diff --git a/ApplicationCode/Adm/LicenseInformation.txt b/ApplicationCode/Adm/LicenseInformation.txt index aef056a504..69a1d1bdea 100644 --- a/ApplicationCode/Adm/LicenseInformation.txt +++ b/ApplicationCode/Adm/LicenseInformation.txt @@ -1,7 +1,7 @@ =============================================================================== Notice for ResInsight: =============================================================================== - Copyright (C) 2011-2012 Statoil ASA, Ceetron AS + Copyright (C) Statoil ASA, Ceetron AS, Ceetron Solutions AS ResInsight is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -19,7 +19,7 @@ Notice for Custom Visualization Core Library: =============================================================================== Custom Visualization Core library - Copyright (C) 2011-2012 Ceetron AS + Copyright (C) Ceetron AS, Ceetron Solutions AS This library is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -36,7 +36,7 @@ =============================================================================== Notice for Ensemble based Reservoir Tool: =============================================================================== - Copyright (C) 2011-2012 Statoil ASA, Norway. + Copyright (C) Statoil ASA, Norway. ERT is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -274,3 +274,51 @@ of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS + +=============================================================================== + Notice for the Qwt libraries +=============================================================================== + Qwt License + Version 1.0, January 1, 2003 + +The Qwt library and included programs are provided under the terms +of the GNU LESSER GENERAL PUBLIC LICENSE (LGPL) with the following +exceptions: + + 1. Widgets that are subclassed from Qwt widgets do not + constitute a derivative work. + + 2. Static linking of applications and widgets to the + Qwt library does not constitute a derivative work + and does not require the author to provide source + code for the application or widget, use the shared + Qwt libraries, or link their applications or + widgets against a user-supplied version of Qwt. + + If you link the application or widget to a modified + version of Qwt, then the changes to Qwt must be + provided under the terms of the LGPL in sections + 1, 2, and 4. + + 3. You do not have to provide a copy of the Qwt license + with programs that are linked to the Qwt library, nor + do you have to identify the Qwt license in your + program or documentation as required by section 6 + of the LGPL. + + + However, programs must still identify their use of Qwt. + The following example statement can be included in user + documentation to satisfy this requirement: + + [program/widget] is based in part on the work of + the Qwt project (http://qwt.sf.net). + + +=============================================================================== + Notice for the NR libraries +=============================================================================== + +CRAVA is a software package for seismic inversion and conditioning of + geological reservoir models. CRAVA is copyrighted by the Norwegian + Computing Center and Statoil and licensed under GPLv3+. diff --git a/ApplicationCode/Adm/RiaBaseDefs.h b/ApplicationCode/Adm/RiaBaseDefs.h index 1bf14ea452..63ceea4ea1 100644 --- a/ApplicationCode/Adm/RiaBaseDefs.h +++ b/ApplicationCode/Adm/RiaBaseDefs.h @@ -21,6 +21,6 @@ // Company and Application name // These two together will become the registry key -const char RI_COMPANY_NAME[] = "Ceetron"; -const char RI_APPLICATION_NAME[] = "ResInsight"; +const char RI_COMPANY_NAME[] = "Ceetron"; +const char RI_APPLICATION_NAME[] = "ResInsight"; diff --git a/ApplicationCode/Application/RiaApplication.cpp b/ApplicationCode/Application/RiaApplication.cpp index 217381860b..6c85decc4b 100644 --- a/ApplicationCode/Application/RiaApplication.cpp +++ b/ApplicationCode/Application/RiaApplication.cpp @@ -18,74 +18,85 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RiaStdInclude.h" - #include "RiaApplication.h" -#include "cafEffectCache.h" -#include "cafUtils.h" -#include "cafAppEnum.h" - -#include "RiaVersionInfo.h" #include "RiaBaseDefs.h" -// -#include "RiuMainWindow.h" -#include "RiuViewer.h" -#include "RiuProcessMonitor.h" -#include "RiaPreferences.h" -// -#include "RimEclipseResultCase.h" -#include "RimEclipseInputCase.h" -#include "RimEclipseView.h" -#include "RimWellPath.h" -#include "RimWellPathCollection.h" -#include "RimOilField.h" -#include "RimEclipseCaseCollection.h" -#include "RimFaultCollection.h" -#include "RimEclipseFaultColors.h" - -#include "RiaSocketServer.h" -#include "cafUiProcess.h" -// -#include "RimUiTreeModelPdm.h" #include "RiaImageCompareReporter.h" #include "RiaImageFileCompare.h" +#include "RiaPreferences.h" #include "RiaProjectModifier.h" -#include "cafProgressInfo.h" -#include "RigGridManager.h" +#include "RiaSocketServer.h" +#include "RiaVersionInfo.h" -#include "RimProject.h" +#include "RigGridManager.h" +#include "Rim3dOverlayInfoConfig.h" +#include "RimCaseCollection.h" +#include "RimCellEdgeColors.h" +#include "RimCellRangeFilterCollection.h" +#include "RimCommandObject.h" +#include "RimDefines.h" +#include "RimEclipseCaseCollection.h" #include "RimEclipseCellColors.h" - -#include "RimIdenticalGridCaseGroup.h" +#include "RimEclipseFaultColors.h" +#include "RimEclipseInputCase.h" #include "RimEclipseInputPropertyCollection.h" - -#include "RimDefines.h" +#include "RimEclipsePropertyFilterCollection.h" +#include "RimEclipseResultCase.h" +#include "RimEclipseStatisticsCase.h" +#include "RimEclipseView.h" +#include "RimEclipseWellCollection.h" +#include "RimFaultCollection.h" +#include "RimGeoMechCase.h" +#include "RimGeoMechCellColors.h" +#include "RimGeoMechModels.h" +#include "RimGeoMechView.h" +#include "RimIdenticalGridCaseGroup.h" +#include "RimMainPlotCollection.h" +#include "RimOilField.h" +#include "RimProject.h" +#include "RimReservoirCellResultsStorage.h" #include "RimScriptCollection.h" -#include "RimCaseCollection.h" +#include "RimViewLinker.h" +#include "RimViewLinkerCollection.h" +#include "RimWellLogPlot.h" +#include "RimWellLogPlotCollection.h" +#include "RimWellPath.h" +#include "RimWellPathCollection.h" -//////////// +#include "RiuMainWindow.h" +#include "RiuProcessMonitor.h" +#include "RiuViewer.h" +#include "cafAppEnum.h" +#include "cafCeetronPlusNavigation.h" +#include "cafEffectCache.h" #include "cafPdmFieldCvfColor.h" #include "cafPdmFieldCvfMat4d.h" -#include "RimReservoirCellResultsStorage.h" -#include "RimCellEdgeColors.h" -#include "RimCellRangeFilterCollection.h" -#include "RimEclipsePropertyFilterCollection.h" -#include "Rim3dOverlayInfoConfig.h" -#include "RimEclipseWellCollection.h" -#include "RimEclipseStatisticsCase.h" -#include "cafCeetronPlusNavigation.h" - +#include "cafPdmSettings.h" +#include "cafPdmUiTreeView.h" +#include "cafProgressInfo.h" +#include "cafUiProcess.h" +#include "cafUtils.h" +#include "cvfFixedAtlasFont.h" #include "cvfProgramOptions.h" #include "cvfqtUtils.h" -#include "RimCommandObject.h" -#include "RimGeoMechCase.h" -#include "RimGeoMechModels.h" -#include "RimGeoMechView.h" -#include "RimGeoMechCellColors.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gtest/gtest.h" + +#ifdef WIN32 +#include +#endif namespace caf { @@ -141,7 +152,7 @@ RiaApplication::RiaApplication(int& argc, char** argv) //cvf::Trace::enable(false); m_preferences = new RiaPreferences; - readFieldsFromApplicationStore(m_preferences); + caf::PdmSettings::readFieldsFromApplicationStore(m_preferences); applyPreferences(); if (useShaders()) @@ -314,7 +325,7 @@ bool RiaApplication::loadProject(const QString& projectFileName, ProjectLoadActi // VL check regarding specific order mentioned in comment above... m_preferences->lastUsedProjectFileName = projectFileName; - writeFieldsToApplicationStore(m_preferences); + caf::PdmSettings::writeFieldsToApplicationStore(m_preferences); for (size_t oilFieldIdx = 0; oilFieldIdx < m_project->oilFields().size(); oilFieldIdx++) { @@ -366,36 +377,56 @@ bool RiaApplication::loadProject(const QString& projectFileName, ProjectLoadActi // Add all "native" cases in the project std::vector casesToLoad; m_project->allCases(casesToLoad); - - caf::ProgressInfo caseProgress(casesToLoad.size() , "Reading Cases"); - - for (size_t cIdx = 0; cIdx < casesToLoad.size(); ++cIdx) { - RimCase* cas = casesToLoad[cIdx]; - CVF_ASSERT(cas); - - caseProgress.setProgressDescription(cas->caseUserDescription()); - std::vector views = cas->views(); - caf::ProgressInfo viewProgress(views.size() , "Creating Views"); + caf::ProgressInfo caseProgress(casesToLoad.size(), "Reading Cases"); - size_t j; - for (j = 0; j < views.size(); j++) + for (size_t cIdx = 0; cIdx < casesToLoad.size(); ++cIdx) { - RimView* riv = views[j]; - CVF_ASSERT(riv); + RimCase* cas = casesToLoad[cIdx]; + CVF_ASSERT(cas); - viewProgress.setProgressDescription(riv->name()); + caseProgress.setProgressDescription(cas->caseUserDescription()); + std::vector views = cas->views(); + caf::ProgressInfo viewProgress(views.size(), "Creating Views"); - riv->loadDataAndUpdate(); - this->setActiveReservoirView(riv); - viewProgress.incrementProgress(); - } + size_t j; + for (j = 0; j < views.size(); j++) + { + RimView* riv = views[j]; + CVF_ASSERT(riv); - caseProgress.incrementProgress(); + viewProgress.setProgressDescription(riv->name()); + + riv->loadDataAndUpdate(); + this->setActiveReservoirView(riv); + + riv->rangeFilterCollection()->updateIconState(); + + viewProgress.incrementProgress(); + } + + caseProgress.incrementProgress(); + } } + if (m_project->viewLinkerCollection() && m_project->viewLinkerCollection()->viewLinker()) + { + m_project->viewLinkerCollection()->viewLinker()->updateOverrides(); + } + { + if (m_project->mainPlotCollection() && m_project->mainPlotCollection()->wellLogPlotCollection()) + { + RimWellLogPlotCollection* wlpColl = m_project->mainPlotCollection()->wellLogPlotCollection(); + caf::ProgressInfo plotProgress(wlpColl->wellLogPlots().size(), "Loading Plot Data"); + for (size_t wlpIdx = 0; wlpIdx < wlpColl->wellLogPlots().size(); ++wlpIdx) + { + wlpColl->wellLogPlots[wlpIdx]->loadDataAndUpdate(); + plotProgress.incrementProgress(); + } + } + } // NB! This function must be called before executing command objects, // because the tree view state is restored from project file and sets // current active view ( see restoreTreeViewState() ) @@ -443,12 +474,36 @@ void RiaApplication::addWellPathsToModel(QList wellPathFilePaths) //printf("Create well path collection.\n"); oilField->wellPathCollection = new RimWellPathCollection(); oilField->wellPathCollection->setProject(m_project); - RiuMainWindow::instance()->uiPdmModel()->updateUiSubTree(m_project); + + m_project->updateConnectedEditors(); } if (oilField->wellPathCollection) oilField->wellPathCollection->addWellPaths(wellPathFilePaths); - RiuMainWindow::instance()->uiPdmModel()->updateUiSubTree(oilField->wellPathCollection); + oilField->wellPathCollection->updateConnectedEditors(); +} + +//-------------------------------------------------------------------------------------------------- +/// Add a list of well log file paths (LAS files) to the well path collection +//-------------------------------------------------------------------------------------------------- +void RiaApplication::addWellLogsToModel(const QList& wellLogFilePaths) +{ + if (m_project == NULL || m_project->oilFields.size() < 1) return; + + RimOilField* oilField = m_project->activeOilField(); + if (oilField == NULL) return; + + if (oilField->wellPathCollection == NULL) + { + oilField->wellPathCollection = new RimWellPathCollection(); + oilField->wellPathCollection->setProject(m_project); + + m_project->updateConnectedEditors(); + } + + if (oilField->wellPathCollection) oilField->wellPathCollection->addWellLogs(wellLogFilePaths); + + oilField->wellPathCollection->updateConnectedEditors(); } @@ -482,16 +537,14 @@ bool RiaApplication::saveProjectPromptForFileName() QString startPath; if (!m_project->fileName().isEmpty()) { - QFileInfo fi(m_project->fileName()); - startPath = fi.absolutePath(); + startPath = m_project->fileName(); } else { startPath = app->defaultFileDialogDirectory("BINARY_GRID"); + startPath += "/ResInsightProject.rsp"; } - startPath += "/ResInsightProject.rsp"; - QString fileName = QFileDialog::getSaveFileName(NULL, tr("Save File"), startPath, tr("Project Files (*.rsp);;All files(*.*)")); if (fileName.isEmpty()) { @@ -518,7 +571,7 @@ bool RiaApplication::saveProjectAs(const QString& fileName) m_project->writeFile(); m_preferences->lastUsedProjectFileName = fileName; - writeFieldsToApplicationStore(m_preferences); + caf::PdmSettings::writeFieldsToApplicationStore(m_preferences); return true; } @@ -531,6 +584,8 @@ bool RiaApplication::closeProject(bool askToSaveIfDirty) { RiuMainWindow* mainWnd = RiuMainWindow::instance(); + clearViewsScheduledForUpdate(); + terminateProcess(); if (false) @@ -562,6 +617,9 @@ bool RiaApplication::closeProject(bool askToSaveIfDirty) onProjectOpenedOrClosed(); + // Make sure all project windows are closed down properly before returning + processEvents(); + return true; } @@ -661,12 +719,11 @@ bool RiaApplication::openEclipseCase(const QString& caseName, const QString& cas riv->cellResult()->setResultVariable(RimDefines::undefinedResultName()); } - RimUiTreeModelPdm* uiModel = RiuMainWindow::instance()->uiPdmModel(); - - uiModel->updateUiSubTree(analysisModels); + analysisModels->updateConnectedEditors(); RiuMainWindow::instance()->setCurrentObjectInTreeView(riv->cellResult()); + return true; } @@ -698,8 +755,7 @@ bool RiaApplication::openInputEclipseCaseFromFileNames(const QStringList& fileNa riv->cellResult()->setResultVariable(RimDefines::undefinedResultName()); } - RimUiTreeModelPdm* uiModel = RiuMainWindow::instance()->uiPdmModel(); - uiModel->updateUiSubTree(analysisModels); + analysisModels->updateConnectedEditors(); RiuMainWindow::instance()->setCurrentObjectInTreeView(riv->cellResult()); @@ -744,9 +800,8 @@ bool RiaApplication::openOdbCaseFromFile(const QString& fileName) //} progress.incrementProgress(); progress.setProgressDescription("Loading results information"); - RimUiTreeModelPdm* uiModel = RiuMainWindow::instance()->uiPdmModel(); - uiModel->updateUiSubTree(m_project); + m_project->updateConnectedEditors(); RiuMainWindow::instance()->setCurrentObjectInTreeView(riv->cellResult()); @@ -821,13 +876,29 @@ void RiaApplication::setActiveReservoirView(RimView* rv) m_activeReservoirView = rv; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiaApplication::setActiveWellLogPlot(RimWellLogPlot* wlp) +{ + m_activeWellLogPlot = wlp; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimWellLogPlot* RiaApplication::activeWellLogPlot() +{ + return m_activeWellLogPlot; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RiaApplication::setUseShaders(bool enable) { m_preferences->useShaders = enable; - writeFieldsToApplicationStore(m_preferences); + caf::PdmSettings::writeFieldsToApplicationStore(m_preferences); } //-------------------------------------------------------------------------------------------------- @@ -859,7 +930,7 @@ RiaApplication::RINavigationPolicy RiaApplication::navigationPolicy() const void RiaApplication::setShowPerformanceInfo(bool enable) { m_preferences->showHud = enable; - writeFieldsToApplicationStore(m_preferences); + caf::PdmSettings::writeFieldsToApplicationStore(m_preferences); } @@ -891,6 +962,7 @@ bool RiaApplication::parseArguments() progOpt.registerOption("?", "", "Displays help text."); progOpt.registerOption("regressiontest", "", "", cvf::ProgramOptions::SINGLE_VALUE); progOpt.registerOption("updateregressiontestbase", "", "", cvf::ProgramOptions::SINGLE_VALUE); + progOpt.registerOption("unittest", "", "Execute unit tests"); progOpt.setOptionPrefix(cvf::ProgramOptions::DOUBLE_DASH); @@ -1068,10 +1140,83 @@ bool RiaApplication::parseArguments() return false; } + // Unit testing + // -------------------------------------------------------- + if (cvf::Option o = progOpt.option("unittest")) + { + launchUnitTests(); + } return true; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiaApplication::launchUnitTests() +{ + cvf::Assert::setReportMode(cvf::Assert::CONSOLE); + + int argc = QCoreApplication::argc(); + testing::InitGoogleTest(&argc, QCoreApplication::argv()); + + //int result = RUN_ALL_TESTS(); + RUN_ALL_TESTS(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiaApplication::launchUnitTestsWithConsole() +{ + // Following code is taken from cvfAssert.cpp +#ifdef WIN32 + { + // Allocate a new console for this app + // Only one console can be associated with an app, so should fail if a console is already present. + AllocConsole(); + + bool redirStdOut = true; + bool redirStdErr = true; + bool redirStdIn = false; + + if (redirStdOut) + { + HANDLE stdHandle = GetStdHandle(STD_OUTPUT_HANDLE); + int fileDescriptor = _open_osfhandle((intptr_t)stdHandle, _O_TEXT); + FILE* fp = _fdopen(fileDescriptor, "w"); + + *stdout = *fp; + setvbuf(stdout, NULL, _IONBF, 0); + } + + if (redirStdErr) + { + HANDLE stdHandle = GetStdHandle(STD_ERROR_HANDLE); + int fileDescriptor = _open_osfhandle((intptr_t)stdHandle, _O_TEXT); + FILE* fp = _fdopen(fileDescriptor, "w"); + + *stderr = *fp; + setvbuf(stderr, NULL, _IONBF, 0); + } + + if (redirStdIn) + { + HANDLE stdHandle = GetStdHandle(STD_INPUT_HANDLE); + int fileDescriptor = _open_osfhandle((intptr_t)stdHandle, _O_TEXT); + FILE* fp = _fdopen(fileDescriptor, "r"); + + *stdin = *fp; + setvbuf(stdin, NULL, _IONBF, 0); + } + + // Make cout, wcout, cin, wcin, wcerr, cerr, wclog and clog point to console as well + std::ios::sync_with_stdio(); + } +#endif + + launchUnitTests(); +} //-------------------------------------------------------------------------------------------------- /// @@ -1288,80 +1433,6 @@ bool RiaApplication::launchProcessForMultipleCases(const QString& program, const return launchProcess(m_currentProgram, m_currentArguments); } -//-------------------------------------------------------------------------------------------------- -/// Read fields of a Pdm object using QSettings -//-------------------------------------------------------------------------------------------------- -void RiaApplication::readFieldsFromApplicationStore(caf::PdmObject* object, const QString context) -{ - QSettings settings; - std::vector fields; - - object->fields(fields); - size_t i; - for (i = 0; i < fields.size(); i++) - { - caf::PdmFieldHandle* fieldHandle = fields[i]; - - std::vector children; - fieldHandle->childObjects(&children); - for (size_t childIdx = 0; childIdx < children.size(); childIdx++) - { - caf::PdmObject* child = children[childIdx]; - QString subContext = context + child->classKeyword() + "/"; - readFieldsFromApplicationStore(child, subContext); - } - - - if (children.size() == 0) - { - QString key = context + fieldHandle->keyword(); - if (settings.contains(key)) - { - QVariant val = settings.value(key); - fieldHandle->setValueFromUi(val); - } - } - } -} - -//-------------------------------------------------------------------------------------------------- -/// Write fields of a Pdm object using QSettings -//-------------------------------------------------------------------------------------------------- -void RiaApplication::writeFieldsToApplicationStore(const caf::PdmObject* object, const QString context) -{ - CVF_ASSERT(object); - - QSettings settings; - - std::vector fields; - object->fields(fields); - - size_t i; - for (i = 0; i < fields.size(); i++) - { - caf::PdmFieldHandle* fieldHandle = fields[i]; - - std::vector children; - fieldHandle->childObjects(&children); - for (size_t childIdx = 0; childIdx < children.size(); childIdx++) - { - caf::PdmObject* child = children[childIdx]; - QString subContext; - if (context.isEmpty()) - { - subContext = context + child->classKeyword() + "/"; - } - - writeFieldsToApplicationStore(child, subContext); - } - - if (children.size() == 0) - { - settings.setValue(context + fieldHandle->keyword(), fieldHandle->uiValue()); - } - } -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -1390,13 +1461,16 @@ void RiaApplication::applyPreferences() caf::EffectGenerator::setRenderingMode(caf::EffectGenerator::FIXED_FUNCTION); } + if (RiuMainWindow::instance() && RiuMainWindow::instance()->projectTreeView()) + { + RiuMainWindow::instance()->projectTreeView()->enableAppendOfClassNameToUiItemText(m_preferences->appendClassNameToUiText()); + } + if (this->project()) { this->project()->setScriptDirectories(m_preferences->scriptDirectories()); - RimUiTreeModelPdm* treeModel = RiuMainWindow::instance()->uiPdmModel(); - if (treeModel) treeModel->updateUiSubTree(this->project()->scriptCollection()); + this->project()->updateConnectedEditors(); } - } //-------------------------------------------------------------------------------------------------- @@ -1541,10 +1615,9 @@ void RiaApplication::saveSnapshotForAllViews(const QString& snapshotFolderName) setActiveReservoirView(riv); RiuViewer* viewer = riv->viewer(); - mainWnd->setActiveViewer(viewer); + mainWnd->setActiveViewer(viewer->layoutWidget()); - // Process all events to avoid a black image when grabbing frame buffer - QCoreApplication::processEvents(); + clearViewsScheduledForUpdate(); QString fileName = cas->caseUserDescription() + "-" + riv->name(); fileName.replace(" ", "_"); @@ -1665,7 +1738,7 @@ void RiaApplication::runRegressionTest(const QString& testRootPath) this->preferences()->fields(fields); for (size_t i = 0; i < fields.size(); i++) { - QVariant v = fields[i]->uiValue(); + QVariant v = fields[i]->uiCapability()->uiValue(); preferencesValues.push_back(v); } } @@ -1721,7 +1794,7 @@ void RiaApplication::runRegressionTest(const QString& testRootPath) for (size_t i = 0; i < preferencesValues.size(); i++) { - fields[i]->setValueFromUi(preferencesValues[i]); + fields[i]->uiCapability()->setValueFromUi(preferencesValues[i]); } } } @@ -1848,9 +1921,7 @@ bool RiaApplication::addEclipseCases(const QStringList& fileNames) gridCaseGroup->loadMainCaseAndActiveCellInfo(); } - RimUiTreeModelPdm* uiModel = RiuMainWindow::instance()->uiPdmModel(); - - uiModel->updateUiSubTree( m_project->activeOilField()->analysisModels()); + m_project->activeOilField()->analysisModels()->updateConnectedEditors(); if (gridCaseGroup->statisticsCaseCollection()->reservoirs.size() > 0) { @@ -1895,6 +1966,21 @@ QImage RiaApplication::grabFrameBufferImage() return image; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiaApplication::clearViewsScheduledForUpdate() +{ + if (m_resViewUpdateTimer) + { + while (m_resViewUpdateTimer->isActive()) + { + QCoreApplication::processEvents(); + } + } + m_resViewsToUpdate.clear(); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -1994,19 +2080,38 @@ void RiaApplication::scheduleDisplayModelUpdateAndRedraw(RimView* resViewToUpdat void RiaApplication::slotUpdateScheduledDisplayModels() { // Compress to remove duplicates - std::set resViewsToUpdate; + // and update dependent views after independent views + + std::set independent3DViewsToUpdate; + std::set dependent3DViewsToUpdate; + for (size_t i = 0; i < m_resViewsToUpdate.size(); ++i) { - resViewsToUpdate.insert(m_resViewsToUpdate[i]); + if (!m_resViewsToUpdate[i]) continue; + + if (m_resViewsToUpdate[i]->viewController()) + dependent3DViewsToUpdate.insert(m_resViewsToUpdate[i]); + else + independent3DViewsToUpdate.insert(m_resViewsToUpdate[i]); + } + + for (std::set::iterator it = independent3DViewsToUpdate.begin(); it != independent3DViewsToUpdate.end(); ++it ) + { + if (*it) + { + (*it)->createDisplayModelAndRedraw(); + } } - for (std::set::iterator it = resViewsToUpdate.begin(); it != resViewsToUpdate.end(); ++it ) + for (std::set::iterator it = dependent3DViewsToUpdate.begin(); it != dependent3DViewsToUpdate.end(); ++it) { if (*it) { (*it)->createDisplayModelAndRedraw(); } } + + m_resViewsToUpdate.clear(); } //-------------------------------------------------------------------------------------------------- @@ -2117,7 +2222,6 @@ void RiaApplication::regressionTestConfigureProject() std::vector projectCases; m_project->allCases(projectCases); - for (size_t i = 0; i < projectCases.size(); i++) { RimCase* cas = projectCases[i]; @@ -2131,6 +2235,13 @@ void RiaApplication::regressionTestConfigureProject() if (riv && riv->viewer()) { + // Make sure all views are maximized for snapshotting + QMdiSubWindow* subWnd = mainWnd->findMdiSubWindow(riv->viewer()->layoutWidget()); + if (subWnd) + { + subWnd->showMaximized(); + } + // This size is set to match the regression test reference images riv->viewer()->setFixedSize(1000, 745); } @@ -2140,7 +2251,12 @@ void RiaApplication::regressionTestConfigureProject() if (resvView) { resvView->faultCollection->setShowFaultsOutsideFilters(false); - resvView->faultResultSettings->showCustomFaultResult.setValueFromUi(false); + + caf::PdmUiFieldHandle* uiFieldHandle = resvView->faultResultSettings->showCustomFaultResult.uiCapability(); + if (uiFieldHandle) + { + uiFieldHandle->setValueFromUi(false); + } } } } diff --git a/ApplicationCode/Application/RiaApplication.h b/ApplicationCode/Application/RiaApplication.h index d2a45b6dab..e453f6514e 100644 --- a/ApplicationCode/Application/RiaApplication.h +++ b/ApplicationCode/Application/RiaApplication.h @@ -42,6 +42,7 @@ class RimView; class RimProject; class RimCommandObject; class RiaProjectModifier; +class RimWellLogPlot; namespace caf { @@ -79,6 +80,9 @@ class RiaApplication : public QApplication RimView* activeReservoirView(); const RimView* activeReservoirView() const; + void setActiveWellLogPlot(RimWellLogPlot*); + RimWellLogPlot* activeWellLogPlot(); + void scheduleDisplayModelUpdateAndRedraw(RimView* resViewToUpdate); RimProject* project(); @@ -107,6 +111,7 @@ class RiaApplication : public QApplication bool saveProjectPromptForFileName(); bool closeProject(bool askToSaveIfDirty); void addWellPathsToModel(QList wellPathFilePaths); + void addWellLogsToModel(const QList& wellLogFilePaths); void copySnapshotToClipboard(); void saveSnapshotPromtpForFilename(); @@ -139,8 +144,6 @@ class RiaApplication : public QApplication void terminateProcess(); RiaPreferences* preferences(); - void readFieldsFromApplicationStore(caf::PdmObject* object, const QString context = ""); - void writeFieldsToApplicationStore(const caf::PdmObject* object, const QString context = ""); void applyPreferences(); cvf::Font* standardFont(); @@ -156,6 +159,9 @@ class RiaApplication : public QApplication bool isRunningRegressionTests() const; + void launchUnitTests(); + void launchUnitTestsWithConsole(); + private: enum ProjectLoadAction { @@ -169,6 +175,7 @@ class RiaApplication : public QApplication void setWindowCaptionFromAppState(); QImage grabFrameBufferImage(); + void clearViewsScheduledForUpdate(); private slots: void slotWorkerProcessFinished(int exitCode, QProcess::ExitStatus exitStatus); @@ -177,6 +184,8 @@ private slots: private: caf::PdmPointer m_activeReservoirView; + caf::PdmPointer m_activeWellLogPlot; + caf::PdmPointer m_project; std::vector > m_resViewsToUpdate; diff --git a/ApplicationCode/Application/RiaPreferences.cpp b/ApplicationCode/Application/RiaPreferences.cpp index 9e3948d5a0..0f5ac014b5 100644 --- a/ApplicationCode/Application/RiaPreferences.cpp +++ b/ApplicationCode/Application/RiaPreferences.cpp @@ -18,13 +18,14 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RiaStdInclude.h" #include "RiaPreferences.h" -#include "cafPdmUiFilePathEditor.h" +#include "RifReaderSettings.h" + #include "cafPdmFieldCvfColor.h" #include "cafPdmUiCheckBoxEditor.h" -#include "RifReaderSettings.h" +#include "cafPdmUiFieldHandle.h" +#include "cafPdmUiFilePathEditor.h" CAF_PDM_SOURCE_INIT(RiaPreferences, "RiaPreferences"); //-------------------------------------------------------------------------------------------------- @@ -35,19 +36,20 @@ RiaPreferences::RiaPreferences(void) CAF_PDM_InitField(&navigationPolicy, "navigationPolicy", caf::AppEnum(RiaApplication::NAVIGATION_POLICY_CEETRON), "Navigation mode", "", "", ""); CAF_PDM_InitFieldNoDefault(&scriptDirectories, "scriptDirectory", "Shared Script Folder(s)", "", "", ""); - scriptDirectories.setUiEditorTypeName(caf::PdmUiFilePathEditor::uiEditorTypeName()); + scriptDirectories.uiCapability()->setUiEditorTypeName(caf::PdmUiFilePathEditor::uiEditorTypeName()); CAF_PDM_InitField(&scriptEditorExecutable, "scriptEditorExecutable", QString("kate"), "Script Editor", "", "", ""); - scriptEditorExecutable.setUiEditorTypeName(caf::PdmUiFilePathEditor::uiEditorTypeName()); + scriptEditorExecutable.uiCapability()->setUiEditorTypeName(caf::PdmUiFilePathEditor::uiEditorTypeName()); CAF_PDM_InitField(&octaveExecutable, "octaveExecutable", QString("octave"), "Octave executable location", "", "", ""); - octaveExecutable.setUiEditorTypeName(caf::PdmUiFilePathEditor::uiEditorTypeName()); - octaveExecutable.setUiLabelPosition(caf::PdmUiItemInfo::TOP); + octaveExecutable.uiCapability()->setUiEditorTypeName(caf::PdmUiFilePathEditor::uiEditorTypeName()); + octaveExecutable.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::TOP); CAF_PDM_InitField(&octaveShowHeaderInfoWhenExecutingScripts, "octaveShowHeaderInfoWhenExecutingScripts", false, "Show text header when executing scripts", "", "", ""); - octaveShowHeaderInfoWhenExecutingScripts.setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN); + octaveShowHeaderInfoWhenExecutingScripts.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN); CAF_PDM_InitField(&ssihubAddress, "ssihubAddress", QString("http://"), "ssihub Address", "", "", ""); + ssihubAddress.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::TOP); CAF_PDM_InitField(&defaultGridLines, "defaultGridLines", true, "Gridlines", "", "", ""); CAF_PDM_InitField(&defaultGridLineColors, "defaultGridLineColors", cvf::Color3f(0.92f, 0.92f, 0.92f), "Mesh color", "", "", ""); @@ -57,18 +59,27 @@ RiaPreferences::RiaPreferences(void) CAF_PDM_InitField(&defaultViewerBackgroundColor, "defaultViewerBackgroundColor", cvf::Color3f(0.69f, 0.77f, 0.87f), "Viewer background", "", "The viewer background color for new views", ""); CAF_PDM_InitField(&defaultScaleFactorZ, "defaultScaleFactorZ", 5, "Z scale factor", "", "", ""); + CAF_PDM_InitField(&showLasCurveWithoutTvdWarning, "showLasCurveWithoutTvdWarning", true, "Show LAS curve without TVD warning", "", "", ""); + showLasCurveWithoutTvdWarning.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN); CAF_PDM_InitField(&useShaders, "useShaders", true, "Use Shaders", "", "", ""); + useShaders.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN); CAF_PDM_InitField(&showHud, "showHud", false, "Show 3D Information", "", "", ""); + showHud.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN); + CAF_PDM_InitField(&appendClassNameToUiText, "appendClassNameToUiText", false, "[System] Show Class Names", "", "", ""); + appendClassNameToUiText.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN); +#ifndef _DEBUG + appendClassNameToUiText.uiCapability()->setUiHidden(true); +#endif CAF_PDM_InitFieldNoDefault(&lastUsedProjectFileName,"lastUsedProjectFileName", "Last Used Project File", "", "", ""); - lastUsedProjectFileName.setUiHidden(true); + lastUsedProjectFileName.uiCapability()->setUiHidden(true); CAF_PDM_InitField(&autocomputeDepthRelatedProperties, "autocomputeDepth", true, "Compute DEPTH related properties", "", "DEPTH, DX, DY, DZ, TOP, BOTTOM", ""); - autocomputeDepthRelatedProperties.setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN); + autocomputeDepthRelatedProperties.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN); CAF_PDM_InitField(&loadAndShowSoil, "loadAndShowSoil", true, "Load and show SOIL", "", "", ""); - loadAndShowSoil.setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN); + loadAndShowSoil.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN); readerSettings = new RifReaderSettings; CAF_PDM_InitFieldNoDefault(&readerSettings, "readerSettings", "Reader settings", "", "", ""); @@ -100,7 +111,11 @@ void RiaPreferences::defineEditorAttribute(const caf::PdmFieldHandle* field, QSt } else if (field == &octaveShowHeaderInfoWhenExecutingScripts || field == &autocomputeDepthRelatedProperties || - field == &loadAndShowSoil ) + field == &loadAndShowSoil || + field == &useShaders || + field == &showHud || + field == &appendClassNameToUiText || + field == &showLasCurveWithoutTvdWarning ) { caf::PdmUiCheckBoxEditorAttribute* myAttr = static_cast(attribute); if (myAttr) @@ -132,6 +147,7 @@ void RiaPreferences::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& defaultSettingsGroup->add(&defaultGridLineColors); defaultSettingsGroup->add(&defaultFaultGridLineColors); defaultSettingsGroup->add(&defaultWellLabelColor); + defaultSettingsGroup->add(&showLasCurveWithoutTvdWarning); caf::PdmUiGroup* autoComputeGroup = uiOrdering.addNewGroup("Behavior when loading new case"); autoComputeGroup->add(&autocomputeDepthRelatedProperties); diff --git a/ApplicationCode/Application/RiaPreferences.h b/ApplicationCode/Application/RiaPreferences.h index 901d1f7d6b..cfce23e567 100644 --- a/ApplicationCode/Application/RiaPreferences.h +++ b/ApplicationCode/Application/RiaPreferences.h @@ -22,9 +22,10 @@ #include "RiaApplication.h" -#include "cafPdmObject.h" -#include "cafPdmField.h" #include "cafAppEnum.h" +#include "cafPdmChildField.h" +#include "cafPdmField.h" +#include "cafPdmObject.h" // Include to make Pdm work for cvf::Color #include "cafPdmFieldCvfColor.h" @@ -58,16 +59,19 @@ class RiaPreferences : public caf::PdmObject caf::PdmField defaultFaultGridLineColors; caf::PdmField defaultViewerBackgroundColor; caf::PdmField defaultWellLabelColor; + caf::PdmField showLasCurveWithoutTvdWarning; + caf::PdmField useShaders; caf::PdmField showHud; + caf::PdmField appendClassNameToUiText; caf::PdmField lastUsedProjectFileName; caf::PdmField autocomputeDepthRelatedProperties; caf::PdmField loadAndShowSoil; - caf::PdmField readerSettings; + caf::PdmChildField readerSettings; protected: virtual void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute); diff --git a/ApplicationCode/Application/RiaProjectModifier.cpp b/ApplicationCode/Application/RiaProjectModifier.cpp index e4e5f16246..5aff5249ab 100644 --- a/ApplicationCode/Application/RiaProjectModifier.cpp +++ b/ApplicationCode/Application/RiaProjectModifier.cpp @@ -17,8 +17,6 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RiaStdInclude.h" - #include "RiaProjectModifier.h" #include "RimProject.h" @@ -40,6 +38,9 @@ #include "RimEclipseWellCollection.h" #include "Rim3dOverlayInfoConfig.h" +#include +#include + diff --git a/ApplicationCode/Application/RiaProjectModifier.h b/ApplicationCode/Application/RiaProjectModifier.h index 3518630b91..da0e0c16db 100644 --- a/ApplicationCode/Application/RiaProjectModifier.h +++ b/ApplicationCode/Application/RiaProjectModifier.h @@ -18,6 +18,14 @@ ///////////////////////////////////////////////////////////////////////////////// #pragma once + +#include "cvfBase.h" +#include "cvfObject.h" + +#include + +#include + class RimProject; diff --git a/ApplicationCode/Application/RiaRegressionTest.cpp b/ApplicationCode/Application/RiaRegressionTest.cpp index 6ca5b5b464..9fb9377b65 100644 --- a/ApplicationCode/Application/RiaRegressionTest.cpp +++ b/ApplicationCode/Application/RiaRegressionTest.cpp @@ -28,10 +28,10 @@ CAF_PDM_SOURCE_INIT(RiaRegressionTest, "RiaRegressionTest"); RiaRegressionTest::RiaRegressionTest(void) { CAF_PDM_InitFieldNoDefault(&applicationWorkingFolder, "workingFolder", "Folder containing compare", "", "Location of compare tool from Image Magic suite", ""); - applicationWorkingFolder.setUiEditorTypeName(caf::PdmUiFilePathEditor::uiEditorTypeName()); + applicationWorkingFolder.uiCapability()->setUiEditorTypeName(caf::PdmUiFilePathEditor::uiEditorTypeName()); CAF_PDM_InitFieldNoDefault(®ressionTestFolder, "regressionTestFolder", "Regression Test Folder", "", "", ""); - regressionTestFolder.setUiEditorTypeName(caf::PdmUiFilePathEditor::uiEditorTypeName()); + regressionTestFolder.uiCapability()->setUiEditorTypeName(caf::PdmUiFilePathEditor::uiEditorTypeName()); } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/CMakeLists.txt b/ApplicationCode/CMakeLists.txt index 8ad8c91b38..46be7f3dce 100644 --- a/ApplicationCode/CMakeLists.txt +++ b/ApplicationCode/CMakeLists.txt @@ -10,15 +10,30 @@ CONFIGURE_FILE( ${CMAKE_SOURCE_DIR}/ApplicationCode/Adm/RiaVersionInfo.h.cmake include_directories( + ${cafPdmCore_SOURCE_DIR} + ${cafPdmUiCore_SOURCE_DIR} + ${cafPdmXml_SOURCE_DIR} + ${cafProjectDataModel_SOURCE_DIR} + + ${cafCommand_SOURCE_DIR} + ${cafViewer_SOURCE_DIR} + ${cafAnimControl_SOURCE_DIR} + ${cafUserInterface_SOURCE_DIR} + ${cafPdmCvf_SOURCE_DIR} + ${CommonCode_SOURCE_DIR} + + ${ResInsight_SOURCE_DIR}/ThirdParty + ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/Adm ${CMAKE_CURRENT_SOURCE_DIR}/Application + ${CMAKE_CURRENT_SOURCE_DIR}/Commands ${CMAKE_CURRENT_SOURCE_DIR}/FileInterface ${CMAKE_CURRENT_SOURCE_DIR}/SocketInterface ${CMAKE_CURRENT_SOURCE_DIR}/ModelVisualization ${CMAKE_CURRENT_SOURCE_DIR}/UserInterface ${CMAKE_CURRENT_SOURCE_DIR}/ProjectDataModel - ${CMAKE_CURRENT_SOURCE_DIR}/ResultStatisticsCache + ${CMAKE_CURRENT_SOURCE_DIR}/ResultStatisticsCache ${CMAKE_CURRENT_SOURCE_DIR}/ReservoirDataModel ${CMAKE_CURRENT_SOURCE_DIR}/WellPathImportSsihub ${CMAKE_CURRENT_SOURCE_DIR}/GeoMech/OdbReader @@ -38,7 +53,6 @@ file( GLOB_RECURSE HEADER_FILES *.h ) set( APPLICATION_FILES RiaMain.cpp - RiaStdInclude.cpp Application/RiaApplication.cpp Application/RiaPreferences.cpp @@ -46,6 +60,8 @@ set( APPLICATION_FILES Application/RiaImageCompareReporter.cpp Application/RiaProjectModifier.cpp Application/RiaRegressionTest.cpp + + ${ResInsight_SOURCE_DIR}/ThirdParty/gtest/gtest-all.cc ) set( USER_INTERFACE_FILES @@ -62,6 +78,18 @@ set( USER_INTERFACE_FILES UserInterface/RiuCadNavigation.cpp UserInterface/RiuRmsNavigation.cpp UserInterface/RiuGeoQuestNavigation.cpp + UserInterface/RiuDragDrop.cpp + UserInterface/RiuDragDrop.h + UserInterface/RiuTreeViewEventFilter.cpp + UserInterface/RiuTreeViewEventFilter.h + UserInterface/RiuWellLogPlot.cpp + UserInterface/RiuWellLogPlot.h + UserInterface/RiuWellLogPlotCurve.cpp + UserInterface/RiuWellLogPlotCurve.h + UserInterface/RiuWellLogTrackPlot.cpp + UserInterface/RiuWellLogTrackPlot.h + UserInterface/RiuProjectPropertyView.h + UserInterface/RiuProjectPropertyView.cpp ) set( SOCKET_INTERFACE_FILES @@ -75,21 +103,35 @@ set( SOCKET_INTERFACE_FILES SocketInterface/RiaSocketDataTransfer.cpp ) +set( UNIT_TEST_FILES + ProjectDataModel/ProjectDataModel_UnitTests/RimWellLogExtractionCurveImpl-Test.cpp + ProjectDataModel/ProjectDataModel_UnitTests/WellPathAsciiFileReader-Test.cpp +) + list( APPEND CPP_SOURCES ${APPLICATION_FILES} ${USER_INTERFACE_FILES} ${SOCKET_INTERFACE_FILES} + ${UNIT_TEST_FILES} ) list( APPEND REFERENCED_CMAKE_FILES ReservoirDataModel/CMakeLists_files.cmake + ReservoirDataModel/CMakeLists_filesNotToUnitTest.cmake FileInterface/CMakeLists_files.cmake ProjectDataModel/CMakeLists_files.cmake ModelVisualization/CMakeLists_files.cmake GeoMech/GeoMechVisualization/CMakeLists_files.cmake + Commands/CMakeLists_files.cmake + Commands/OperationsUsingObjReferences/CMakeLists_files.cmake + Commands/ToggleCommands/CMakeLists_files.cmake + Commands/OctaveScriptCommands/CMakeLists_files.cmake + Commands/ViewLink/CMakeLists_files.cmake + Commands/WellLogCommands/CMakeLists_files.cmake + Commands/WellPathCommands/CMakeLists_files.cmake ) # Include source file lists from *.cmake files @@ -126,10 +168,9 @@ add_subdirectory(GeoMech/GeoMechDataModel) ############################################################################# set ( QT_MOC_HEADERS + ${QT_MOC_HEADERS} Application/RiaApplication.h - ProjectDataModel/RimUiTreeModelPdm.h - ProjectDataModel/RimUiTreeView.h ProjectDataModel/RimMimeData.h UserInterface/RiuMainWindow.h @@ -139,7 +180,9 @@ set ( QT_MOC_HEADERS SocketInterface/RiaSocketServer.h UserInterface/RiuMultiCaseImportDialog.h UserInterface/RiuViewerCommands.h - + UserInterface/RiuTreeViewEventFilter.h + UserInterface/RiuWellLogPlot.h + UserInterface/RiuWellLogTrackPlot.h ) qt4_wrap_cpp( MOC_FILES_CPP ${QT_MOC_HEADERS} ) @@ -233,6 +276,7 @@ source_group( "Application" FILES ${APPLICATION_FILES} ) source_group( "ModelVisualization" FILES ${MODEL_VISUALIZATION_FILES} ) source_group( "UserInterface" FILES ${USER_INTERFACE_FILES} ) source_group( "SocketInterface" FILES ${SOCKET_INTERFACE_FILES} ) +source_group( "UnitTests" FILES ${UNIT_TEST_FILES} ) ############################################################################# @@ -290,13 +334,28 @@ endif () set( LINK_LIBRARIES WellPathImportSsihub - cafPdmCvf +# cafPdmCvf +# cafUserInterface +# cafProjectDataModel +# cafViewer +# cafAnimControl +# cafTensor +# CommonCode + + #cafPdmCore + #cafPdmUiCore + cafPdmXml + #cafProjectDataModel + cafUserInterface - cafProjectDataModel cafViewer cafAnimControl + cafCommand + cafPdmCvf + cafTensor CommonCode + LibGuiQt LibViewing LibRender @@ -311,8 +370,12 @@ set( LINK_LIBRARIES ert_geometry ecl_well + NRLib + ${OPENGL_LIBRARIES} ${QT_LIBRARIES} + + Qwt ) set( EXTERNAL_LINK_LIBRARIES ${ERT_LIBRARY_LIST} ) diff --git a/ApplicationCode/Commands/CMakeLists_files.cmake b/ApplicationCode/Commands/CMakeLists_files.cmake new file mode 100644 index 0000000000..ad862791ef --- /dev/null +++ b/ApplicationCode/Commands/CMakeLists_files.cmake @@ -0,0 +1,107 @@ + +# Use this workaround until we're on 2.8.3 on all platforms and can use CMAKE_CURRENT_LIST_DIR directly +if (${CMAKE_VERSION} VERSION_GREATER "2.8.2") + set(CEE_CURRENT_LIST_DIR ${CMAKE_CURRENT_LIST_DIR}/) +endif() + +set (SOURCE_GROUP_HEADER_FILES +${CEE_CURRENT_LIST_DIR}RicCloseCaseFeature.h +${CEE_CURRENT_LIST_DIR}RicEclipseCaseNewGroupFeature.h +${CEE_CURRENT_LIST_DIR}RicEclipseCaseNewGroupExec.h +${CEE_CURRENT_LIST_DIR}RicGeoMechPropertyFilterFeatureImpl.h +${CEE_CURRENT_LIST_DIR}RicGeoMechPropertyFilterInsertFeature.h +${CEE_CURRENT_LIST_DIR}RicGeoMechPropertyFilterInsertExec.h +${CEE_CURRENT_LIST_DIR}RicGeoMechPropertyFilterNewFeature.h +${CEE_CURRENT_LIST_DIR}RicGeoMechPropertyFilterNewExec.h +${CEE_CURRENT_LIST_DIR}RicEclipsePropertyFilterFeatureImpl.h +${CEE_CURRENT_LIST_DIR}RicEclipsePropertyFilterInsertFeature.h +${CEE_CURRENT_LIST_DIR}RicEclipsePropertyFilterInsertExec.h +${CEE_CURRENT_LIST_DIR}RicEclipsePropertyFilterNewFeature.h +${CEE_CURRENT_LIST_DIR}RicEclipsePropertyFilterNewExec.h +${CEE_CURRENT_LIST_DIR}RicNewViewFeature.h +${CEE_CURRENT_LIST_DIR}RicPropertyFilterNewExec.h +${CEE_CURRENT_LIST_DIR}RicRangeFilterExecImpl.h +${CEE_CURRENT_LIST_DIR}RicRangeFilterInsertExec.h +${CEE_CURRENT_LIST_DIR}RicRangeFilterInsertFeature.h +${CEE_CURRENT_LIST_DIR}RicRangeFilterNewFeature.h +${CEE_CURRENT_LIST_DIR}RicRangeFilterFeatureImpl.h +${CEE_CURRENT_LIST_DIR}RicRangeFilterNewExec.h +${CEE_CURRENT_LIST_DIR}RicRangeFilterNewSliceIFeature.h +${CEE_CURRENT_LIST_DIR}RicRangeFilterNewSliceJFeature.h +${CEE_CURRENT_LIST_DIR}RicRangeFilterNewSliceKFeature.h +${CEE_CURRENT_LIST_DIR}RicAddEclipseInputPropertyFeature.h +${CEE_CURRENT_LIST_DIR}RicSaveEclipseInputPropertyFeature.h +${CEE_CURRENT_LIST_DIR}RicSaveEclipseResultAsInputPropertyFeature.h +${CEE_CURRENT_LIST_DIR}RicSaveEclipseResultAsInputPropertyExec.h +${CEE_CURRENT_LIST_DIR}RicImportEclipseCaseFeature.h +${CEE_CURRENT_LIST_DIR}RicImportInputEclipseCaseFeature.h +${CEE_CURRENT_LIST_DIR}RicCreateGridCaseGroupFeature.h +${CEE_CURRENT_LIST_DIR}RicNewStatisticsCaseFeature.h +${CEE_CURRENT_LIST_DIR}RicComputeStatisticsFeature.h + +${CEE_CURRENT_LIST_DIR}RicWellLogsImportFileFeature.h + +${CEE_CURRENT_LIST_DIR}RicTileWindowsFeature.h +${CEE_CURRENT_LIST_DIR}RicLaunchUnitTestsFeature.h +${CEE_CURRENT_LIST_DIR}RicExportToLasFileFeature.h + +# General delete of any object in a child array field +${CEE_CURRENT_LIST_DIR}RicDeleteItemExec.h +${CEE_CURRENT_LIST_DIR}RicDeleteItemExecData.h +${CEE_CURRENT_LIST_DIR}RicDeleteItemFeature.h +) + +set (SOURCE_GROUP_SOURCE_FILES +${CEE_CURRENT_LIST_DIR}RicCloseCaseFeature.cpp +${CEE_CURRENT_LIST_DIR}RicEclipseCaseNewGroupFeature.cpp +${CEE_CURRENT_LIST_DIR}RicEclipseCaseNewGroupExec.cpp +${CEE_CURRENT_LIST_DIR}RicGeoMechPropertyFilterFeatureImpl.cpp +${CEE_CURRENT_LIST_DIR}RicGeoMechPropertyFilterInsertFeature.cpp +${CEE_CURRENT_LIST_DIR}RicGeoMechPropertyFilterInsertExec.cpp +${CEE_CURRENT_LIST_DIR}RicGeoMechPropertyFilterNewFeature.cpp +${CEE_CURRENT_LIST_DIR}RicGeoMechPropertyFilterNewExec.cpp +${CEE_CURRENT_LIST_DIR}RicEclipsePropertyFilterFeatureImpl.cpp +${CEE_CURRENT_LIST_DIR}RicEclipsePropertyFilterInsertFeature.cpp +${CEE_CURRENT_LIST_DIR}RicEclipsePropertyFilterInsertExec.cpp +${CEE_CURRENT_LIST_DIR}RicEclipsePropertyFilterNewFeature.cpp +${CEE_CURRENT_LIST_DIR}RicEclipsePropertyFilterNewExec.cpp +${CEE_CURRENT_LIST_DIR}RicNewViewFeature.cpp +${CEE_CURRENT_LIST_DIR}RicRangeFilterExecImpl.cpp +${CEE_CURRENT_LIST_DIR}RicRangeFilterInsertExec.cpp +${CEE_CURRENT_LIST_DIR}RicRangeFilterInsertFeature.cpp +${CEE_CURRENT_LIST_DIR}RicRangeFilterNewFeature.cpp +${CEE_CURRENT_LIST_DIR}RicRangeFilterFeatureImpl.cpp +${CEE_CURRENT_LIST_DIR}RicRangeFilterNewExec.cpp +${CEE_CURRENT_LIST_DIR}RicRangeFilterNewSliceIFeature.cpp +${CEE_CURRENT_LIST_DIR}RicRangeFilterNewSliceJFeature.cpp +${CEE_CURRENT_LIST_DIR}RicRangeFilterNewSliceKFeature.cpp +${CEE_CURRENT_LIST_DIR}RicAddEclipseInputPropertyFeature.cpp +${CEE_CURRENT_LIST_DIR}RicSaveEclipseInputPropertyFeature.cpp +${CEE_CURRENT_LIST_DIR}RicSaveEclipseResultAsInputPropertyFeature.cpp +${CEE_CURRENT_LIST_DIR}RicSaveEclipseResultAsInputPropertyExec.cpp +${CEE_CURRENT_LIST_DIR}RicImportEclipseCaseFeature.cpp +${CEE_CURRENT_LIST_DIR}RicImportInputEclipseCaseFeature.cpp +${CEE_CURRENT_LIST_DIR}RicCreateGridCaseGroupFeature.cpp +${CEE_CURRENT_LIST_DIR}RicNewStatisticsCaseFeature.cpp +${CEE_CURRENT_LIST_DIR}RicComputeStatisticsFeature.cpp + +${CEE_CURRENT_LIST_DIR}RicTileWindowsFeature.cpp +${CEE_CURRENT_LIST_DIR}RicLaunchUnitTestsFeature.cpp +${CEE_CURRENT_LIST_DIR}RicExportToLasFileFeature.cpp + + +# General delete of any object in a child array field +${CEE_CURRENT_LIST_DIR}RicDeleteItemExec.cpp +${CEE_CURRENT_LIST_DIR}RicDeleteItemExecData.cpp +${CEE_CURRENT_LIST_DIR}RicDeleteItemFeature.cpp +) + +list(APPEND CODE_HEADER_FILES +${SOURCE_GROUP_HEADER_FILES} +) + +list(APPEND CODE_SOURCE_FILES +${SOURCE_GROUP_SOURCE_FILES} +) + +source_group( "CommandFeature" FILES ${SOURCE_GROUP_HEADER_FILES} ${SOURCE_GROUP_SOURCE_FILES} ${CEE_CURRENT_LIST_DIR}CMakeLists_files.cmake ) diff --git a/ApplicationCode/Commands/OctaveScriptCommands/CMakeLists_files.cmake b/ApplicationCode/Commands/OctaveScriptCommands/CMakeLists_files.cmake new file mode 100644 index 0000000000..e8d3b455dc --- /dev/null +++ b/ApplicationCode/Commands/OctaveScriptCommands/CMakeLists_files.cmake @@ -0,0 +1,40 @@ + +# Use this workaround until we're on 2.8.3 on all platforms and can use CMAKE_CURRENT_LIST_DIR directly +if (${CMAKE_VERSION} VERSION_GREATER "2.8.2") + set(CEE_CURRENT_LIST_DIR ${CMAKE_CURRENT_LIST_DIR}/) +endif() + +set (SOURCE_GROUP_HEADER_FILES +${CEE_CURRENT_LIST_DIR}RicAddScriptPathFeature.h +${CEE_CURRENT_LIST_DIR}RicDeleteScriptPathFeature.h +${CEE_CURRENT_LIST_DIR}RicEditScriptFeature.h +${CEE_CURRENT_LIST_DIR}RicExecuteScriptFeature.h +${CEE_CURRENT_LIST_DIR}RicExecuteScriptForCasesFeature.h +${CEE_CURRENT_LIST_DIR}RicNewScriptFeature.h +${CEE_CURRENT_LIST_DIR}RicScriptFeatureImpl.h +) + +set (SOURCE_GROUP_SOURCE_FILES +${CEE_CURRENT_LIST_DIR}RicAddScriptPathFeature.cpp +${CEE_CURRENT_LIST_DIR}RicDeleteScriptPathFeature.cpp +${CEE_CURRENT_LIST_DIR}RicEditScriptFeature.cpp +${CEE_CURRENT_LIST_DIR}RicExecuteScriptFeature.cpp +${CEE_CURRENT_LIST_DIR}RicExecuteScriptForCasesFeature.cpp +${CEE_CURRENT_LIST_DIR}RicNewScriptFeature.cpp +${CEE_CURRENT_LIST_DIR}RicScriptFeatureImpl.cpp +) + +set (QT_MOC_HEADERS +${QT_MOC_HEADERS} +${CEE_CURRENT_LIST_DIR}RicExecuteScriptForCasesFeature.h +) + +list(APPEND CODE_HEADER_FILES +${SOURCE_GROUP_HEADER_FILES} +) + +list(APPEND CODE_SOURCE_FILES +${SOURCE_GROUP_SOURCE_FILES} +) + +source_group( "CommandFeature\\Script" FILES ${SOURCE_GROUP_HEADER_FILES} ${SOURCE_GROUP_SOURCE_FILES} ${CEE_CURRENT_LIST_DIR}CMakeLists_files.cmake ) diff --git a/ApplicationCode/Commands/OctaveScriptCommands/RicAddScriptPathFeature.cpp b/ApplicationCode/Commands/OctaveScriptCommands/RicAddScriptPathFeature.cpp new file mode 100644 index 0000000000..29c32c25bb --- /dev/null +++ b/ApplicationCode/Commands/OctaveScriptCommands/RicAddScriptPathFeature.cpp @@ -0,0 +1,74 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicAddScriptPathFeature.h" + +#include "RicScriptFeatureImpl.h" + +#include "RimScriptCollection.h" +#include "RiaApplication.h" +#include "RiaPreferences.h" +#include "RiuMainWindow.h" + +#include "cvfAssert.h" + +#include +#include + +CAF_CMD_SOURCE_INIT(RicAddScriptPathFeature, "RicAddScriptPathFeature"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicAddScriptPathFeature::isCommandEnabled() +{ + std::vector selection = RicScriptFeatureImpl::selectedScriptCollections(); + return selection.size() > 0; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicAddScriptPathFeature::onActionTriggered(bool isChecked) +{ + QString selectedFolder = QFileDialog::getExistingDirectory(RiuMainWindow::instance(), "Select script folder"); + if (!selectedFolder.isEmpty()) + { + QString filePathString = RiaApplication::instance()->preferences()->scriptDirectories(); + + QChar separator(';'); + if (!filePathString.isEmpty() && !filePathString.endsWith(separator, Qt::CaseInsensitive)) + { + filePathString += separator; + } + + filePathString += selectedFolder; + + RiaApplication::instance()->preferences()->scriptDirectories = filePathString; + RiaApplication::instance()->applyPreferences(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicAddScriptPathFeature::setupActionLook(QAction* actionToSetup) +{ + actionToSetup->setText("Add Script Path"); +} diff --git a/ApplicationCode/Commands/OctaveScriptCommands/RicAddScriptPathFeature.h b/ApplicationCode/Commands/OctaveScriptCommands/RicAddScriptPathFeature.h new file mode 100644 index 0000000000..e436a7b781 --- /dev/null +++ b/ApplicationCode/Commands/OctaveScriptCommands/RicAddScriptPathFeature.h @@ -0,0 +1,40 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdFeature.h" + +#include + +//================================================================================================== +/// +//================================================================================================== +class RicAddScriptPathFeature : public caf::CmdFeature +{ + CAF_CMD_HEADER_INIT; + +protected: + // Overrides + virtual bool isCommandEnabled(); + virtual void onActionTriggered( bool isChecked ); + virtual void setupActionLook( QAction* actionToSetup ); +}; + + diff --git a/ApplicationCode/Commands/OctaveScriptCommands/RicDeleteScriptPathFeature.cpp b/ApplicationCode/Commands/OctaveScriptCommands/RicDeleteScriptPathFeature.cpp new file mode 100644 index 0000000000..f44a1fadfa --- /dev/null +++ b/ApplicationCode/Commands/OctaveScriptCommands/RicDeleteScriptPathFeature.cpp @@ -0,0 +1,81 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicDeleteScriptPathFeature.h" + +#include "RicScriptFeatureImpl.h" + +#include "RimScriptCollection.h" +#include "RiaApplication.h" +#include "RiaPreferences.h" +#include "RiuMainWindow.h" + +#include "cvfAssert.h" + +#include +#include + +CAF_CMD_SOURCE_INIT(RicDeleteScriptPathFeature, "RicDeleteScriptPathFeature"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicDeleteScriptPathFeature::isCommandEnabled() +{ + std::vector selection = RicScriptFeatureImpl::selectedScriptCollections(); + return selection.size() > 0; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicDeleteScriptPathFeature::onActionTriggered(bool isChecked) +{ + std::vector calcScriptCollections = RicScriptFeatureImpl::selectedScriptCollections(); + RimScriptCollection* scriptCollection = calcScriptCollections.size() > 0 ? calcScriptCollections[0] : NULL; + if (scriptCollection) + { + QString toBeRemoved = scriptCollection->directory; + + QString originalFilePathString = RiaApplication::instance()->preferences()->scriptDirectories(); + QString filePathString = originalFilePathString.remove(toBeRemoved); + + // Remove duplicate separators + QChar separator(';'); + QString regExpString = QString("%1{1,5}").arg(separator); + filePathString.replace(QRegExp(regExpString), separator); + + // Remove separator at end + if (filePathString.endsWith(separator)) + { + filePathString = filePathString.left(filePathString.size() - 1); + } + + RiaApplication::instance()->preferences()->scriptDirectories = filePathString; + RiaApplication::instance()->applyPreferences(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicDeleteScriptPathFeature::setupActionLook(QAction* actionToSetup) +{ + actionToSetup->setText("Delete Script Path"); +} diff --git a/ApplicationCode/Commands/OctaveScriptCommands/RicDeleteScriptPathFeature.h b/ApplicationCode/Commands/OctaveScriptCommands/RicDeleteScriptPathFeature.h new file mode 100644 index 0000000000..236e0de4a6 --- /dev/null +++ b/ApplicationCode/Commands/OctaveScriptCommands/RicDeleteScriptPathFeature.h @@ -0,0 +1,40 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdFeature.h" + +#include + +//================================================================================================== +/// +//================================================================================================== +class RicDeleteScriptPathFeature : public caf::CmdFeature +{ + CAF_CMD_HEADER_INIT; + +protected: + // Overrides + virtual bool isCommandEnabled(); + virtual void onActionTriggered( bool isChecked ); + virtual void setupActionLook( QAction* actionToSetup ); +}; + + diff --git a/ApplicationCode/Commands/OctaveScriptCommands/RicEditScriptFeature.cpp b/ApplicationCode/Commands/OctaveScriptCommands/RicEditScriptFeature.cpp new file mode 100644 index 0000000000..7610e17792 --- /dev/null +++ b/ApplicationCode/Commands/OctaveScriptCommands/RicEditScriptFeature.cpp @@ -0,0 +1,79 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicEditScriptFeature.h" + +#include "RicScriptFeatureImpl.h" + +#include "RimCalcScript.h" +#include "RiaApplication.h" + +#include "RiuMainWindow.h" + +#include "cafSelectionManager.h" +#include "cvfAssert.h" + +#include +#include + +CAF_CMD_SOURCE_INIT(RicEditScriptFeature, "RicEditScriptFeature"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicEditScriptFeature::isCommandEnabled() +{ + std::vector selection = RicScriptFeatureImpl::selectedScripts(); + return selection.size() > 0; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicEditScriptFeature::onActionTriggered(bool isChecked) +{ + std::vector selection = RicScriptFeatureImpl::selectedScripts(); + CVF_ASSERT(selection.size() > 0); + + RimCalcScript* calcScript = selection[0]; + + RiaApplication* app = RiaApplication::instance(); + QString scriptEditor = app->scriptEditorPath(); + if (!scriptEditor.isEmpty()) + { + QStringList arguments; + arguments << calcScript->absolutePath; + + QProcess* myProcess = new QProcess(this); + myProcess->start(scriptEditor, arguments); + + if (!myProcess->waitForStarted(1000)) + { + QMessageBox::warning(RiuMainWindow::instance(), "Script editor", "Failed to start script editor executable\n" + scriptEditor); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicEditScriptFeature::setupActionLook(QAction* actionToSetup) +{ + actionToSetup->setText("Edit"); +} diff --git a/ApplicationCode/Commands/OctaveScriptCommands/RicEditScriptFeature.h b/ApplicationCode/Commands/OctaveScriptCommands/RicEditScriptFeature.h new file mode 100644 index 0000000000..b9ca5599e0 --- /dev/null +++ b/ApplicationCode/Commands/OctaveScriptCommands/RicEditScriptFeature.h @@ -0,0 +1,40 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdFeature.h" + +#include + +//================================================================================================== +/// +//================================================================================================== +class RicEditScriptFeature : public caf::CmdFeature +{ + CAF_CMD_HEADER_INIT; + +protected: + // Overrides + virtual bool isCommandEnabled(); + virtual void onActionTriggered( bool isChecked ); + virtual void setupActionLook( QAction* actionToSetup ); +}; + + diff --git a/ApplicationCode/Commands/OctaveScriptCommands/RicExecuteScriptFeature.cpp b/ApplicationCode/Commands/OctaveScriptCommands/RicExecuteScriptFeature.cpp new file mode 100644 index 0000000000..823c81c140 --- /dev/null +++ b/ApplicationCode/Commands/OctaveScriptCommands/RicExecuteScriptFeature.cpp @@ -0,0 +1,78 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicExecuteScriptFeature.h" + +#include "RicScriptFeatureImpl.h" + +#include "RimCalcScript.h" +#include "RiaApplication.h" + +#include "cafSelectionManager.h" +#include "cvfAssert.h" + +#include +#include + +CAF_CMD_SOURCE_INIT(RicExecuteScriptFeature, "RicExecuteScriptFeature"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicExecuteScriptFeature::isCommandEnabled() +{ + std::vector selection = RicScriptFeatureImpl::selectedScripts(); + return selection.size() > 0; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicExecuteScriptFeature::onActionTriggered(bool isChecked) +{ + std::vector selection = RicScriptFeatureImpl::selectedScripts(); + CVF_ASSERT(selection.size() > 0); + + RimCalcScript* calcScript = selection[0]; + + RiaApplication* app = RiaApplication::instance(); + QString octavePath = app->octavePath(); + if (!octavePath.isEmpty()) + { + // TODO: Must rename RimCalcScript::absolutePath to absoluteFileName, as the code below is confusing + // absolutePath() is a function in QFileInfo + QFileInfo fi(calcScript->absolutePath()); + QString octaveFunctionSearchPath = fi.absolutePath(); + + QStringList arguments = app->octaveArguments(); + arguments.append("--path"); + arguments << octaveFunctionSearchPath; + arguments << calcScript->absolutePath(); + + RiaApplication::instance()->launchProcess(octavePath, arguments); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicExecuteScriptFeature::setupActionLook(QAction* actionToSetup) +{ + actionToSetup->setText("Execute"); +} diff --git a/ApplicationCode/Commands/OctaveScriptCommands/RicExecuteScriptFeature.h b/ApplicationCode/Commands/OctaveScriptCommands/RicExecuteScriptFeature.h new file mode 100644 index 0000000000..82a5d68bed --- /dev/null +++ b/ApplicationCode/Commands/OctaveScriptCommands/RicExecuteScriptFeature.h @@ -0,0 +1,40 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdFeature.h" + +#include + +//================================================================================================== +/// +//================================================================================================== +class RicExecuteScriptFeature : public caf::CmdFeature +{ + CAF_CMD_HEADER_INIT; + +protected: + // Overrides + virtual bool isCommandEnabled(); + virtual void onActionTriggered( bool isChecked ); + virtual void setupActionLook( QAction* actionToSetup ); +}; + + diff --git a/ApplicationCode/Commands/OctaveScriptCommands/RicExecuteScriptForCasesFeature.cpp b/ApplicationCode/Commands/OctaveScriptCommands/RicExecuteScriptForCasesFeature.cpp new file mode 100644 index 0000000000..d2f2be5204 --- /dev/null +++ b/ApplicationCode/Commands/OctaveScriptCommands/RicExecuteScriptForCasesFeature.cpp @@ -0,0 +1,108 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicExecuteScriptForCasesFeature.h" + +#include "RimCase.h" +#include "RiaApplication.h" + +#include "cafSelectionManager.h" + +#include +#include + +CAF_CMD_SOURCE_INIT(RicExecuteScriptForCasesFeature, "RicExecuteScriptForCasesFeature"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicExecuteScriptForCasesFeature::isCommandEnabled() +{ + std::vector selection; + caf::SelectionManager::instance()->objectsByType(&selection); + + if (selection.size() > 0) + { + return true; + } + else + { + return false; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicExecuteScriptForCasesFeature::onActionTriggered(bool isChecked) +{ + // Dummy - handled by slotExecuteScriptForSelectedCases() +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicExecuteScriptForCasesFeature::setupActionLook(QAction* actionToSetup) +{ + actionToSetup->setText("Execute script"); +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicExecuteScriptForCasesFeature::slotExecuteScriptForSelectedCases() +{ + QAction* action = qobject_cast(sender()); + if (!action) return; + + QString scriptAbsolutePath = action->data().toString(); + + RiaApplication* app = RiaApplication::instance(); + QString octavePath = app->octavePath(); + if (!octavePath.isEmpty()) + { + // TODO: Must rename RimCalcScript::absolutePath to absoluteFileName, as the code below is confusing + // absolutePath() is a function in QFileInfo + + QFileInfo fi(scriptAbsolutePath); + QString octaveFunctionSearchPath = fi.absolutePath(); + + QStringList arguments = app->octaveArguments(); + arguments.append("--path"); + arguments << octaveFunctionSearchPath; + arguments << scriptAbsolutePath; + + std::vector selection; + caf::SelectionManager::instance()->objectsByType(&selection); + + // Get case ID from selected cases in selection model + std::vector caseIdsInSelection; + for (size_t i = 0; i < selection.size(); i++) + { + RimCase* casePtr = selection[i]; + caseIdsInSelection.push_back(casePtr->caseId); + } + + if (caseIdsInSelection.size() > 0) + { + RiaApplication::instance()->launchProcessForMultipleCases(octavePath, arguments, caseIdsInSelection); + } + } +} diff --git a/ApplicationCode/Commands/OctaveScriptCommands/RicExecuteScriptForCasesFeature.h b/ApplicationCode/Commands/OctaveScriptCommands/RicExecuteScriptForCasesFeature.h new file mode 100644 index 0000000000..270131ddb0 --- /dev/null +++ b/ApplicationCode/Commands/OctaveScriptCommands/RicExecuteScriptForCasesFeature.h @@ -0,0 +1,43 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdFeature.h" + + +//================================================================================================== +/// +//================================================================================================== +class RicExecuteScriptForCasesFeature : public caf::CmdFeature +{ + Q_OBJECT + CAF_CMD_HEADER_INIT; + +protected: + // Overrides + virtual bool isCommandEnabled(); + virtual void onActionTriggered( bool isChecked ); + virtual void setupActionLook( QAction* actionToSetup ); + +private slots: + void slotExecuteScriptForSelectedCases(); +}; + + diff --git a/ApplicationCode/Commands/OctaveScriptCommands/RicNewScriptFeature.cpp b/ApplicationCode/Commands/OctaveScriptCommands/RicNewScriptFeature.cpp new file mode 100644 index 0000000000..cb1654f7ef --- /dev/null +++ b/ApplicationCode/Commands/OctaveScriptCommands/RicNewScriptFeature.cpp @@ -0,0 +1,105 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicNewScriptFeature.h" + +#include "RicScriptFeatureImpl.h" + +#include "RimCalcScript.h" +#include "RimScriptCollection.h" +#include "RiaApplication.h" + +#include "RiuMainWindow.h" + +#include +#include +#include + +CAF_CMD_SOURCE_INIT(RicNewScriptFeature, "RicNewScriptFeature"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicNewScriptFeature::isCommandEnabled() +{ + std::vector selection = RicScriptFeatureImpl::selectedScripts(); + return selection.size() > 0; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicNewScriptFeature::onActionTriggered(bool isChecked) +{ + std::vector calcScripts = RicScriptFeatureImpl::selectedScripts(); + std::vector calcScriptCollections = RicScriptFeatureImpl::selectedScriptCollections(); + + RimCalcScript* calcScript = calcScripts.size() > 0 ? calcScripts[0] : NULL; + RimScriptCollection* scriptColl = calcScriptCollections.size() > 0 ? calcScriptCollections[0] : NULL; + + QString fullPathNewScript; + + if (calcScript ) + { + QFileInfo existingScriptFileInfo(calcScript->absolutePath()); + fullPathNewScript = existingScriptFileInfo.absolutePath(); + } + else if (scriptColl) + { + fullPathNewScript = scriptColl->directory(); + } + else + { + return; + } + + QString fullPathFilenameNewScript; + + fullPathFilenameNewScript = fullPathNewScript + "/untitled.m"; + int num= 1; + while (QFileInfo(fullPathFilenameNewScript).exists()) + { + fullPathFilenameNewScript = fullPathNewScript + "/untitled" + QString::number(num) + ".m"; + num++; + } + + RiaApplication* app = RiaApplication::instance(); + QString scriptEditor = app->scriptEditorPath(); + if (!scriptEditor.isEmpty()) + { + QStringList arguments; + arguments << fullPathFilenameNewScript; + + QProcess* myProcess = new QProcess(this); + myProcess->start(scriptEditor, arguments); + + if (!myProcess->waitForStarted(1000)) + { + QMessageBox::warning(RiuMainWindow::instance(), "Script editor", "Failed to start script editor executable\n" + scriptEditor); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicNewScriptFeature::setupActionLook(QAction* actionToSetup) +{ + actionToSetup->setText("New"); +} diff --git a/ApplicationCode/Commands/OctaveScriptCommands/RicNewScriptFeature.h b/ApplicationCode/Commands/OctaveScriptCommands/RicNewScriptFeature.h new file mode 100644 index 0000000000..37f7bda90b --- /dev/null +++ b/ApplicationCode/Commands/OctaveScriptCommands/RicNewScriptFeature.h @@ -0,0 +1,40 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdFeature.h" + +#include + +//================================================================================================== +/// +//================================================================================================== +class RicNewScriptFeature : public caf::CmdFeature +{ + CAF_CMD_HEADER_INIT; + +protected: + // Overrides + virtual bool isCommandEnabled(); + virtual void onActionTriggered( bool isChecked ); + virtual void setupActionLook( QAction* actionToSetup ); +}; + + diff --git a/ApplicationCode/Commands/OctaveScriptCommands/RicScriptFeatureImpl.cpp b/ApplicationCode/Commands/OctaveScriptCommands/RicScriptFeatureImpl.cpp new file mode 100644 index 0000000000..ad505cee70 --- /dev/null +++ b/ApplicationCode/Commands/OctaveScriptCommands/RicScriptFeatureImpl.cpp @@ -0,0 +1,46 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicScriptFeatureImpl.h" + +#include "RimCalcScript.h" +#include "RimScriptCollection.h" +#include "cafSelectionManager.h" + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RicScriptFeatureImpl::selectedScripts() +{ + std::vector selection; + caf::SelectionManager::instance()->objectsByType(&selection); + + return selection; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RicScriptFeatureImpl::selectedScriptCollections() +{ + std::vector selection; + caf::SelectionManager::instance()->objectsByType(&selection); + + return selection; +} diff --git a/ApplicationCode/Commands/OctaveScriptCommands/RicScriptFeatureImpl.h b/ApplicationCode/Commands/OctaveScriptCommands/RicScriptFeatureImpl.h new file mode 100644 index 0000000000..bd3dde5a88 --- /dev/null +++ b/ApplicationCode/Commands/OctaveScriptCommands/RicScriptFeatureImpl.h @@ -0,0 +1,39 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdFeature.h" + +#include + +class RimCalcScript; +class RimScriptCollection; + +//================================================================================================== +/// +//================================================================================================== +class RicScriptFeatureImpl +{ +public: + static std::vector selectedScripts(); + static std::vector selectedScriptCollections(); +}; + + diff --git a/ApplicationCode/Commands/OperationsUsingObjReferences/CMakeLists_files.cmake b/ApplicationCode/Commands/OperationsUsingObjReferences/CMakeLists_files.cmake new file mode 100644 index 0000000000..e651d86273 --- /dev/null +++ b/ApplicationCode/Commands/OperationsUsingObjReferences/CMakeLists_files.cmake @@ -0,0 +1,33 @@ + +# Use this workaround until we're on 2.8.3 on all platforms and can use CMAKE_CURRENT_LIST_DIR directly +if (${CMAKE_VERSION} VERSION_GREATER "2.8.2") + set(CEE_CURRENT_LIST_DIR ${CMAKE_CURRENT_LIST_DIR}/) +endif() + +set (SOURCE_GROUP_HEADER_FILES +${CEE_CURRENT_LIST_DIR}RicCopyReferencesToClipboardFeature.h +${CEE_CURRENT_LIST_DIR}RicPasteFeatureImpl.h + +${CEE_CURRENT_LIST_DIR}RicPasteEclipseCasesFeature.h +${CEE_CURRENT_LIST_DIR}RicPasteEclipseViewsFeature.h +${CEE_CURRENT_LIST_DIR}RicPasteGeoMechViewsFeature.h +) + +set (SOURCE_GROUP_SOURCE_FILES +${CEE_CURRENT_LIST_DIR}RicCopyReferencesToClipboardFeature.cpp +${CEE_CURRENT_LIST_DIR}RicPasteFeatureImpl.cpp + +${CEE_CURRENT_LIST_DIR}RicPasteEclipseCasesFeature.cpp +${CEE_CURRENT_LIST_DIR}RicPasteEclipseViewsFeature.cpp +${CEE_CURRENT_LIST_DIR}RicPasteGeoMechViewsFeature.cpp +) + +list(APPEND CODE_HEADER_FILES +${SOURCE_GROUP_HEADER_FILES} +) + +list(APPEND CODE_SOURCE_FILES +${SOURCE_GROUP_SOURCE_FILES} +) + +source_group( "CommandFeature\\ObjReferences" FILES ${SOURCE_GROUP_HEADER_FILES} ${SOURCE_GROUP_SOURCE_FILES} ${CEE_CURRENT_LIST_DIR}CMakeLists_files.cmake ) diff --git a/ApplicationCode/Commands/OperationsUsingObjReferences/RicCopyReferencesToClipboardFeature.cpp b/ApplicationCode/Commands/OperationsUsingObjReferences/RicCopyReferencesToClipboardFeature.cpp new file mode 100644 index 0000000000..8a5892e9c2 --- /dev/null +++ b/ApplicationCode/Commands/OperationsUsingObjReferences/RicCopyReferencesToClipboardFeature.cpp @@ -0,0 +1,72 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicCopyReferencesToClipboardFeature.h" + +#include "RimMimeData.h" + +#include "cafPdmUiItem.h" +#include "cafSelectionManager.h" + +#include +#include +#include + + +namespace caf +{ + +CAF_CMD_SOURCE_INIT(RicCopyReferencesToClipboardFeature, "RicCopyReferencesToClipboardFeature"); + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicCopyReferencesToClipboardFeature::isCommandEnabled() +{ + return true; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicCopyReferencesToClipboardFeature::onActionTriggered(bool isChecked) +{ + std::vector referenceList; + SelectionManager::instance()->selectionAsReferences(referenceList); + + MimeDataWithReferences* myObject = new MimeDataWithReferences; + myObject->setReferences(referenceList); + + QClipboard* clipboard = QApplication::clipboard(); + if (clipboard) + { + clipboard->setMimeData(myObject); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicCopyReferencesToClipboardFeature::setupActionLook(QAction* actionToSetup) +{ + actionToSetup->setText("Copy"); +} + +} // end namespace caf diff --git a/ApplicationCode/Commands/OperationsUsingObjReferences/RicCopyReferencesToClipboardFeature.h b/ApplicationCode/Commands/OperationsUsingObjReferences/RicCopyReferencesToClipboardFeature.h new file mode 100644 index 0000000000..61b7ac77ab --- /dev/null +++ b/ApplicationCode/Commands/OperationsUsingObjReferences/RicCopyReferencesToClipboardFeature.h @@ -0,0 +1,44 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + + +#pragma once + +#include "cafCmdFeature.h" + +namespace caf +{ + +//================================================================================================== +/// +//================================================================================================== +class RicCopyReferencesToClipboardFeature : public CmdFeature +{ + CAF_CMD_HEADER_INIT; +protected: + + // Overrides + virtual bool isCommandEnabled(); + virtual void onActionTriggered( bool isChecked ); + virtual void setupActionLook( QAction* actionToSetup ); +}; + + + +} // end namespace caf diff --git a/ApplicationCode/Commands/OperationsUsingObjReferences/RicPasteEclipseCasesFeature.cpp b/ApplicationCode/Commands/OperationsUsingObjReferences/RicPasteEclipseCasesFeature.cpp new file mode 100644 index 0000000000..b3ba6e2baa --- /dev/null +++ b/ApplicationCode/Commands/OperationsUsingObjReferences/RicPasteEclipseCasesFeature.cpp @@ -0,0 +1,202 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicPasteEclipseCasesFeature.h" + +#include "RiaApplication.h" + +#include "RicPasteFeatureImpl.h" + +#include "RigGridManager.h" + +#include "RimCaseCollection.h" +#include "RimEclipseCaseCollection.h" +#include "RimEclipseResultCase.h" +#include "RimIdenticalGridCaseGroup.h" +#include "RimMimeData.h" +#include "RimOilField.h" +#include "RimProject.h" + +#include "cafPdmObjectGroup.h" +#include "cafPdmObjectHandle.h" +#include "cafPdmReferenceHelper.h" +#include "cafSelectionManager.h" + +#include +#include + +namespace caf +{ + +CAF_CMD_SOURCE_INIT(RicPasteEclipseCasesFeature, "RicPasteEclipseCasesFeature"); + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicPasteEclipseCasesFeature::isCommandEnabled() +{ + PdmObjectGroup objectGroup; + RicPasteFeatureImpl::findObjectsFromClipboardRefs(&objectGroup); + + std::vector > typedObjects; + objectGroup.objectsByType(&typedObjects); + + if (typedObjects.size() == 0) + { + return false; + } + + PdmObjectHandle* destinationObject = dynamic_cast(SelectionManager::instance()->selectedItem()); + + RimIdenticalGridCaseGroup* gridCaseGroup = RicPasteFeatureImpl::findGridCaseGroup(destinationObject); + if (gridCaseGroup) return true; + + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicPasteEclipseCasesFeature::onActionTriggered(bool isChecked) +{ + PdmObjectHandle* destinationObject = dynamic_cast(SelectionManager::instance()->selectedItem()); + + RimIdenticalGridCaseGroup* gridCaseGroup = RicPasteFeatureImpl::findGridCaseGroup(destinationObject); + if (!gridCaseGroup) return; + + PdmObjectGroup objectGroup; + RicPasteFeatureImpl::findObjectsFromClipboardRefs(&objectGroup); + + if (objectGroup.objects.size() == 0) return; + + addCasesToGridCaseGroup(objectGroup, gridCaseGroup); + + return; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicPasteEclipseCasesFeature::setupActionLook(QAction* actionToSetup) +{ + actionToSetup->setText("Paste (Eclipse Cases)"); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicPasteEclipseCasesFeature::addCasesToGridCaseGroup(PdmObjectGroup& objectGroup, RimIdenticalGridCaseGroup* gridCaseGroup) +{ + RimProject* proj = RiaApplication::instance()->project(); + CVF_ASSERT(proj); + + std::vector resultCases; + + for (size_t i = 0; i < objectGroup.objects.size(); i++) + { + RimEclipseResultCase* eclCase = dynamic_cast(objectGroup.objects[i]); + if (eclCase) + { + RimEclipseResultCase* eclCaseCopy = dynamic_cast(eclCase->copyByXmlSerialization(PdmDefaultObjectFactory::instance())); + resultCases.push_back(eclCaseCopy); + } + } + + if (resultCases.size() == 0) + { + return; + } + + RimEclipseResultCase* mainResultCase = NULL; + std::vector< std::vector > mainCaseGridDimensions; + + // Read out main grid and main grid dimensions if present in case group + if (gridCaseGroup->mainCase()) + { + mainResultCase = dynamic_cast(gridCaseGroup->mainCase()); + CVF_ASSERT(mainResultCase); + + mainResultCase->readGridDimensions(mainCaseGridDimensions); + } + + std::vector insertedCases; + + // Add cases to case group + for (size_t i = 0; i < resultCases.size(); i++) + { + RimEclipseResultCase* rimResultReservoir = resultCases[i]; + + proj->assignCaseIdToCase(rimResultReservoir); + + if (gridCaseGroup->contains(rimResultReservoir)) + { + continue; + } + + insertedCases.push_back(rimResultReservoir); + } + + // Load stuff + for (size_t i = 0; i < insertedCases.size(); i++) + { + RimEclipseResultCase* rimResultReservoir = insertedCases[i]; + + if (!mainResultCase) + { + rimResultReservoir->openEclipseGridFile(); + rimResultReservoir->readGridDimensions(mainCaseGridDimensions); + + mainResultCase = rimResultReservoir; + } + else + { + std::vector< std::vector > caseGridDimensions; + rimResultReservoir->readGridDimensions(caseGridDimensions); + + bool identicalGrid = RigGridManager::isGridDimensionsEqual(mainCaseGridDimensions, caseGridDimensions); + if (!identicalGrid) + { + continue; + } + + if (!rimResultReservoir->openAndReadActiveCellData(mainResultCase->reservoirData())) + { + CVF_ASSERT(false); + } + } + + RimOilField* activeOilField = proj ? proj->activeOilField() : NULL; + RimEclipseCaseCollection* analysisModels = (activeOilField) ? activeOilField->analysisModels() : NULL; + if (analysisModels) analysisModels->insertCaseInCaseGroup(gridCaseGroup, rimResultReservoir); + + caf::PdmDocument::updateUiIconStateRecursively(rimResultReservoir); + + gridCaseGroup->updateConnectedEditors(); + + for (size_t rvIdx = 0; rvIdx < rimResultReservoir->reservoirViews.size(); rvIdx++) + { + RimEclipseView* riv = rimResultReservoir->reservoirViews()[rvIdx]; + riv->loadDataAndUpdate(); + } + } +} + + +} // end namespace caf diff --git a/ApplicationCode/Commands/OperationsUsingObjReferences/RicPasteEclipseCasesFeature.h b/ApplicationCode/Commands/OperationsUsingObjReferences/RicPasteEclipseCasesFeature.h new file mode 100644 index 0000000000..648f62c5ed --- /dev/null +++ b/ApplicationCode/Commands/OperationsUsingObjReferences/RicPasteEclipseCasesFeature.h @@ -0,0 +1,51 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + + +#pragma once + +#include "cafCmdFeature.h" + + +class RimIdenticalGridCaseGroup; + +namespace caf +{ + class PdmObjectGroup; + +//================================================================================================== +/// +//================================================================================================== +class RicPasteEclipseCasesFeature : public caf::CmdFeature +{ + CAF_CMD_HEADER_INIT; + +public: + static void addCasesToGridCaseGroup(PdmObjectGroup& objectGroup, RimIdenticalGridCaseGroup* gridCaseGroup); + +protected: + // Overrides + virtual bool isCommandEnabled(); + virtual void onActionTriggered(bool isChecked); + virtual void setupActionLook(QAction* actionToSetup); +}; + + + +} // end namespace caf diff --git a/ApplicationCode/Commands/OperationsUsingObjReferences/RicPasteEclipseViewsFeature.cpp b/ApplicationCode/Commands/OperationsUsingObjReferences/RicPasteEclipseViewsFeature.cpp new file mode 100644 index 0000000000..2d3426ce09 --- /dev/null +++ b/ApplicationCode/Commands/OperationsUsingObjReferences/RicPasteEclipseViewsFeature.cpp @@ -0,0 +1,120 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicPasteEclipseViewsFeature.h" + +#include "RiaApplication.h" + +#include "RicPasteFeatureImpl.h" + +#include "RimEclipseCase.h" +#include "RimEclipseView.h" +#include "RimEclipseWellCollection.h" + +#include "cafPdmDocument.h" +#include "cafPdmObjectGroup.h" +#include "cafSelectionManager.h" + +#include + +namespace caf +{ + +CAF_CMD_SOURCE_INIT(RicPasteEclipseViewsFeature, "RicPasteEclipseViewsFeature"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicPasteEclipseViewsFeature::isCommandEnabled() +{ + PdmObjectGroup objectGroup; + RicPasteFeatureImpl::findObjectsFromClipboardRefs(&objectGroup); + + std::vector > typedObjects; + objectGroup.objectsByType(&typedObjects); + + if (typedObjects.size() == 0) + { + return false; + } + + PdmObjectHandle* destinationObject = dynamic_cast(SelectionManager::instance()->selectedItem()); + + RimIdenticalGridCaseGroup* gridCaseGroup = RicPasteFeatureImpl::findGridCaseGroup(destinationObject); + if (gridCaseGroup) return false; + + RimEclipseCase* eclipseCase = RicPasteFeatureImpl::findEclipseCase(destinationObject); + if (eclipseCase) return true; + + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicPasteEclipseViewsFeature::onActionTriggered(bool isChecked) +{ + PdmObjectHandle* destinationObject = dynamic_cast(SelectionManager::instance()->selectedItem()); + + RimEclipseCase* eclipseCase = RicPasteFeatureImpl::findEclipseCase(destinationObject); + assert(eclipseCase); + + PdmObjectGroup objectGroup; + RicPasteFeatureImpl::findObjectsFromClipboardRefs(&objectGroup); + + if (objectGroup.objects.size() == 0) return; + + std::vector > eclipseViews; + objectGroup.createCopyByType(&eclipseViews, PdmDefaultObjectFactory::instance()); + + if (eclipseViews.size() != 0) + { + // Add cases to case group + for (size_t i = 0; i < eclipseViews.size(); i++) + { + RimEclipseView* rimReservoirView = eclipseViews[i]; + QString nameOfCopy = QString("Copy of ") + rimReservoirView->name; + rimReservoirView->name = nameOfCopy; + eclipseCase->reservoirViews().push_back(rimReservoirView); + + // Delete all wells to be able to copy/paste between cases, as the wells differ between cases + rimReservoirView->wellCollection()->wells().deleteAllChildObjects(); + + rimReservoirView->initAfterReadRecursively(); + rimReservoirView->setEclipseCase(eclipseCase); + + caf::PdmDocument::updateUiIconStateRecursively(rimReservoirView); + + rimReservoirView->loadDataAndUpdate(); + + eclipseCase->updateConnectedEditors(); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicPasteEclipseViewsFeature::setupActionLook(QAction* actionToSetup) +{ + actionToSetup->setText("Paste (Eclipse Views)"); +} + + +} // end namespace caf diff --git a/ApplicationCode/Commands/OperationsUsingObjReferences/RicPasteEclipseViewsFeature.h b/ApplicationCode/Commands/OperationsUsingObjReferences/RicPasteEclipseViewsFeature.h new file mode 100644 index 0000000000..8ddd2ea5f7 --- /dev/null +++ b/ApplicationCode/Commands/OperationsUsingObjReferences/RicPasteEclipseViewsFeature.h @@ -0,0 +1,45 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + + +#pragma once + +#include "cafCmdFeature.h" + + +namespace caf +{ + +//================================================================================================== +/// +//================================================================================================== +class RicPasteEclipseViewsFeature : public caf::CmdFeature +{ +CAF_CMD_HEADER_INIT; + +protected: + // Overrides + virtual bool isCommandEnabled(); + virtual void onActionTriggered(bool isChecked); + virtual void setupActionLook(QAction* actionToSetup); +}; + + + +} // end namespace caf diff --git a/ApplicationCode/Commands/OperationsUsingObjReferences/RicPasteFeatureImpl.cpp b/ApplicationCode/Commands/OperationsUsingObjReferences/RicPasteFeatureImpl.cpp new file mode 100644 index 0000000000..8158773080 --- /dev/null +++ b/ApplicationCode/Commands/OperationsUsingObjReferences/RicPasteFeatureImpl.cpp @@ -0,0 +1,144 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicPasteFeatureImpl.h" + +#include "RiaApplication.h" + +#include "RimCaseCollection.h" +#include "RimEclipseCase.h" +#include "RimGeoMechCase.h" +#include "RimGeoMechView.h" +#include "RimIdenticalGridCaseGroup.h" +#include "RimMimeData.h" +#include "RimProject.h" + +#include "cafPdmObjectGroup.h" +#include "cafPdmObjectHandle.h" + +#include +#include + + + +namespace caf +{ + + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicPasteFeatureImpl::populateObjectGroupFromReferences(const std::vector& referenceList, caf::PdmObjectGroup* objectGroup) +{ + PdmObjectHandle* referenceRoot = RiaApplication::instance()->project(); + + for (size_t i = 0; i < referenceList.size(); i++) + { + QString reference = referenceList[i]; + + PdmObjectHandle* pdmObj = PdmReferenceHelper::objectFromReference(referenceRoot, reference); + if (pdmObj) + { + objectGroup->objects.push_back(pdmObj); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicPasteFeatureImpl::referencesFromClipboard(std::vector& referenceList) +{ + QClipboard* clipboard = QApplication::clipboard(); + if (!clipboard) return; + + const MimeDataWithReferences* mimeDataReferences = dynamic_cast(clipboard->mimeData()); + if (!mimeDataReferences) return; + + referenceList = mimeDataReferences->references(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicPasteFeatureImpl::findObjectsFromClipboardRefs(caf::PdmObjectGroup* objectGroup) +{ + std::vector referenceList; + RicPasteFeatureImpl::referencesFromClipboard(referenceList); + + RicPasteFeatureImpl::populateObjectGroupFromReferences(referenceList, objectGroup); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimIdenticalGridCaseGroup* RicPasteFeatureImpl::findGridCaseGroup(PdmObjectHandle* objectHandle) +{ + if (dynamic_cast(objectHandle)) + { + return dynamic_cast(objectHandle); + } + else if (dynamic_cast(objectHandle) || + dynamic_cast(objectHandle)) + { + RimIdenticalGridCaseGroup* gridCaseGroup = NULL; + objectHandle->firstAnchestorOrThisOfType(gridCaseGroup); + + return gridCaseGroup; + } + + return NULL; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimEclipseCase* RicPasteFeatureImpl::findEclipseCase(PdmObjectHandle* objectHandle) +{ + if (dynamic_cast(objectHandle)) + { + return dynamic_cast(objectHandle); + } + else if (dynamic_cast(objectHandle)) + { + RimEclipseView* reservoirView = dynamic_cast(objectHandle); + + return reservoirView->eclipseCase(); + } + + return NULL; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimGeoMechCase* RicPasteFeatureImpl::findGeoMechCase(PdmObjectHandle* objectHandle) +{ + RimGeoMechCase* geomCase = dynamic_cast(objectHandle); + if (!geomCase) + { + RimGeoMechView* geomView = dynamic_cast(objectHandle); + if (geomView) geomCase = geomView->geoMechCase(); + } + + return geomCase; +} + +} // end namespace caf diff --git a/ApplicationCode/Commands/OperationsUsingObjReferences/RicPasteFeatureImpl.h b/ApplicationCode/Commands/OperationsUsingObjReferences/RicPasteFeatureImpl.h new file mode 100644 index 0000000000..93bd575a63 --- /dev/null +++ b/ApplicationCode/Commands/OperationsUsingObjReferences/RicPasteFeatureImpl.h @@ -0,0 +1,57 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + + +#pragma once + + +#include + +class QString; + +class RimEclipseCase; +class RimGeoMechCase; +class RimIdenticalGridCaseGroup; + +namespace caf +{ + +class PdmObjectGroup; +class PdmObjectHandle; + +//================================================================================================== +/// +//================================================================================================== +class RicPasteFeatureImpl +{ +public: + static void findObjectsFromClipboardRefs(caf::PdmObjectGroup* objectGroup); + + static RimIdenticalGridCaseGroup* findGridCaseGroup(PdmObjectHandle* objectHandle); + static RimEclipseCase* findEclipseCase(PdmObjectHandle* objectHandle); + static RimGeoMechCase* findGeoMechCase(PdmObjectHandle* objectHandle); + +private: + static void populateObjectGroupFromReferences(const std::vector& referenceList, caf::PdmObjectGroup* objectGroup); + static void referencesFromClipboard(std::vector& referenceList); +}; + + + +} // end namespace caf diff --git a/ApplicationCode/Commands/OperationsUsingObjReferences/RicPasteGeoMechViewsFeature.cpp b/ApplicationCode/Commands/OperationsUsingObjReferences/RicPasteGeoMechViewsFeature.cpp new file mode 100644 index 0000000000..879ab427b1 --- /dev/null +++ b/ApplicationCode/Commands/OperationsUsingObjReferences/RicPasteGeoMechViewsFeature.cpp @@ -0,0 +1,111 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicPasteGeoMechViewsFeature.h" + +#include "RicPasteFeatureImpl.h" + +#include "RimGeoMechView.h" +#include "RimGeoMechCase.h" + +#include "cafPdmDocument.h" +#include "cafPdmObjectGroup.h" +#include "cafSelectionManager.h" + +#include + +namespace caf +{ + +CAF_CMD_SOURCE_INIT(RicPasteGeoMechViewsFeature, "RicPasteGeoMechViewsFeature"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicPasteGeoMechViewsFeature::isCommandEnabled() +{ + PdmObjectGroup objectGroup; + RicPasteFeatureImpl::findObjectsFromClipboardRefs(&objectGroup); + + std::vector > typedObjects; + objectGroup.objectsByType(&typedObjects); + + if (typedObjects.size() == 0) + { + return false; + } + + PdmObjectHandle* destinationObject = dynamic_cast(SelectionManager::instance()->selectedItem()); + + RimGeoMechCase* geoMechCase = RicPasteFeatureImpl::findGeoMechCase(destinationObject); + if (geoMechCase) return true; + + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicPasteGeoMechViewsFeature::onActionTriggered(bool isChecked) +{ + PdmObjectHandle* destinationObject = dynamic_cast(SelectionManager::instance()->selectedItem()); + + RimGeoMechCase* geomCase = RicPasteFeatureImpl::findGeoMechCase(destinationObject); + assert(geomCase); + + PdmObjectGroup objectGroup; + RicPasteFeatureImpl::findObjectsFromClipboardRefs(&objectGroup); + + if (objectGroup.objects.size() == 0) return; + + std::vector > geomViews; + objectGroup.createCopyByType(&geomViews, PdmDefaultObjectFactory::instance()); + + if (geomViews.size() != 0) + { + // Add cases to case group + for (size_t i = 0; i < geomViews.size(); i++) + { + RimGeoMechView* rimReservoirView = geomViews[i]; + QString nameOfCopy = QString("Copy of ") + rimReservoirView->name; + rimReservoirView->name = nameOfCopy; + geomCase->geoMechViews().push_back(rimReservoirView); + + rimReservoirView->initAfterReadRecursively(); + rimReservoirView->setGeoMechCase(geomCase); + + caf::PdmDocument::updateUiIconStateRecursively(rimReservoirView); + + rimReservoirView->loadDataAndUpdate(); + + geomCase->updateConnectedEditors(); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicPasteGeoMechViewsFeature::setupActionLook(QAction* actionToSetup) +{ + actionToSetup->setText("Paste (Geo Mech Views)"); +} + + +} // end namespace caf diff --git a/ApplicationCode/Commands/OperationsUsingObjReferences/RicPasteGeoMechViewsFeature.h b/ApplicationCode/Commands/OperationsUsingObjReferences/RicPasteGeoMechViewsFeature.h new file mode 100644 index 0000000000..98c991b722 --- /dev/null +++ b/ApplicationCode/Commands/OperationsUsingObjReferences/RicPasteGeoMechViewsFeature.h @@ -0,0 +1,45 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + + +#pragma once + +#include "cafCmdFeature.h" + + +namespace caf +{ + +//================================================================================================== +/// +//================================================================================================== + class RicPasteGeoMechViewsFeature : public caf::CmdFeature +{ +CAF_CMD_HEADER_INIT; + +protected: + // Overrides + virtual bool isCommandEnabled(); + virtual void onActionTriggered(bool isChecked); + virtual void setupActionLook(QAction* actionToSetup); +}; + + + +} // end namespace caf diff --git a/ApplicationCode/Commands/RicAddEclipseInputPropertyFeature.cpp b/ApplicationCode/Commands/RicAddEclipseInputPropertyFeature.cpp new file mode 100644 index 0000000000..bb7af030e8 --- /dev/null +++ b/ApplicationCode/Commands/RicAddEclipseInputPropertyFeature.cpp @@ -0,0 +1,103 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicAddEclipseInputPropertyFeature.h" + +#include "RimEclipseInputPropertyCollection.h" +#include "RimEclipseInputCase.h" + +#include "RiaApplication.h" +#include "RiuMainWindow.h" + +#include "cafSelectionManager.h" + +#include +#include +#include +#include + +CAF_CMD_SOURCE_INIT(RicAddEclipseInputPropertyFeature, "RicAddEclipseInputPropertyFeature"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicAddEclipseInputPropertyFeature::isCommandEnabled() +{ + return selectedInputPropertyCollection() != NULL; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicAddEclipseInputPropertyFeature::onActionTriggered(bool isChecked) +{ + RiaApplication* app = RiaApplication::instance(); + QString defaultDir = app->defaultFileDialogDirectory("INPUT_FILES"); + QStringList fileNames = QFileDialog::getOpenFileNames(RiuMainWindow::instance(), "Select Eclipse Input Property Files", defaultDir, "All Files (*.* *)"); + + if (fileNames.isEmpty()) return; + + // Remember the directory to next time + defaultDir = QFileInfo(fileNames.last()).absolutePath(); + app->setDefaultFileDialogDirectory("INPUT_FILES", defaultDir); + + RimEclipseInputPropertyCollection* inputPropertyCollection = selectedInputPropertyCollection(); + if (inputPropertyCollection) + { + addEclipseInputProperty(fileNames, inputPropertyCollection); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicAddEclipseInputPropertyFeature::setupActionLook(QAction* actionToSetup) +{ + actionToSetup->setText("Add Input Property"); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimEclipseInputPropertyCollection* RicAddEclipseInputPropertyFeature::selectedInputPropertyCollection() const +{ + std::vector selection; + caf::SelectionManager::instance()->objectsByType(&selection); + + return selection.size() > 0 ? selection[0] : NULL; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicAddEclipseInputPropertyFeature::addEclipseInputProperty(const QStringList& fileNames, RimEclipseInputPropertyCollection* inputPropertyCollection) +{ + CVF_ASSERT(inputPropertyCollection); + + RimEclipseInputCase* inputReservoir = dynamic_cast(inputPropertyCollection->parentField()->ownerObject()); + CVF_ASSERT(inputReservoir); + if (inputReservoir) + { + inputReservoir->openDataFileSet(fileNames); + } + + inputPropertyCollection->updateConnectedEditors(); +} + + diff --git a/ApplicationCode/Commands/RicAddEclipseInputPropertyFeature.h b/ApplicationCode/Commands/RicAddEclipseInputPropertyFeature.h new file mode 100644 index 0000000000..a12c39d407 --- /dev/null +++ b/ApplicationCode/Commands/RicAddEclipseInputPropertyFeature.h @@ -0,0 +1,45 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdFeature.h" + +class RimEclipseInputPropertyCollection; +class QStringList; + +//================================================================================================== +/// +//================================================================================================== +class RicAddEclipseInputPropertyFeature : public caf::CmdFeature +{ + CAF_CMD_HEADER_INIT; + +protected: + // Overrides + virtual bool isCommandEnabled(); + virtual void onActionTriggered( bool isChecked ); + virtual void setupActionLook( QAction* actionToSetup ); + +private: + RimEclipseInputPropertyCollection* selectedInputPropertyCollection() const; + static void addEclipseInputProperty(const QStringList& fileNames, RimEclipseInputPropertyCollection* inputPropertyCollection); +}; + + diff --git a/ApplicationCode/Commands/RicCloseCaseFeature.cpp b/ApplicationCode/Commands/RicCloseCaseFeature.cpp new file mode 100644 index 0000000000..bb22b7bf25 --- /dev/null +++ b/ApplicationCode/Commands/RicCloseCaseFeature.cpp @@ -0,0 +1,263 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicCloseCaseFeature.h" + +#include "RiaApplication.h" + +#include "RimCaseCollection.h" +#include "RimEclipseCase.h" +#include "RimEclipseCaseCollection.h" +#include "RimEclipseStatisticsCase.h" +#include "RimGeoMechCase.h" +#include "RimGeoMechModels.h" +#include "RimIdenticalGridCaseGroup.h" +#include "RimOilField.h" +#include "RimProject.h" +#include "RimMainPlotCollection.h" +#include "RimWellLogPlotCollection.h" + +#include "RiuMainWindow.h" + +#include "cafPdmFieldHandle.h" +#include "cafPdmObjectGroup.h" +#include "cafSelectionManager.h" + +#include +#include + +CAF_CMD_SOURCE_INIT(RicCloseCaseFeature, "RicCloseCaseFeature"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicCloseCaseFeature::isCommandEnabled() +{ + return selectedEclipseCase() != NULL || selectedGeoMechCase() != NULL; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicCloseCaseFeature::onActionTriggered(bool isChecked) +{ + RimEclipseCase* eclipseCase = selectedEclipseCase(); + RimGeoMechCase* geoMechCase = selectedGeoMechCase(); + if (eclipseCase) + { + std::vector casesToBeDeleted; + casesToBeDeleted.push_back(eclipseCase); + + if (userConfirmedGridCaseGroupChange(casesToBeDeleted)) + { + deleteEclipseCase(eclipseCase); + } + } + else if (geoMechCase) + { + deleteGeoMechCase(geoMechCase); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicCloseCaseFeature::setupActionLook(QAction* actionToSetup) +{ + actionToSetup->setText("Close"); +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimEclipseCase* RicCloseCaseFeature::selectedEclipseCase() const +{ + std::vector selection; + caf::SelectionManager::instance()->objectsByType(&selection); + + if (selection.size() > 0) + { + return selection[0]; + } + + return NULL; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimGeoMechCase* RicCloseCaseFeature::selectedGeoMechCase() const +{ + std::vector selection; + caf::SelectionManager::instance()->objectsByType(&selection); + + if (selection.size() > 0) + { + return selection[0]; + } + + return NULL; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicCloseCaseFeature::removeCaseFromAllGroups(RimEclipseCase* eclipseCase) +{ + CVF_ASSERT(eclipseCase); + + RimProject* proj = RiaApplication::instance()->project(); + RimOilField* activeOilField = proj ? proj->activeOilField() : NULL; + RimEclipseCaseCollection* analysisModels = (activeOilField) ? activeOilField->analysisModels() : NULL; + if (analysisModels) + { + analysisModels->removeCaseFromAllGroups(eclipseCase); + analysisModels->updateConnectedEditors(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicCloseCaseFeature::deleteEclipseCase(RimEclipseCase* eclipseCase) +{ + CVF_ASSERT(eclipseCase); + + RimCaseCollection* caseCollection = eclipseCase->parentCaseCollection(); + if (caseCollection) + { + if (RimIdenticalGridCaseGroup::isStatisticsCaseCollection(caseCollection)) + { + RimIdenticalGridCaseGroup* caseGroup = caseCollection->parentCaseGroup(); + CVF_ASSERT(caseGroup); + + caseGroup->statisticsCaseCollection()->reservoirs.removeChildObject(eclipseCase); + caseGroup->updateConnectedEditors(); + } + else + { + removeCaseFromAllGroups(eclipseCase); + } + } + else + { + removeCaseFromAllGroups(eclipseCase); + } + + delete eclipseCase; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicCloseCaseFeature::deleteGeoMechCase(RimGeoMechCase* geoMechCase) +{ + CVF_ASSERT(geoMechCase); + + RimProject* proj = RiaApplication::instance()->project(); + RimOilField* activeOilField = proj ? proj->activeOilField() : NULL; + RimGeoMechModels* models = (activeOilField) ? activeOilField->geoMechModels() : NULL; + if (models) + { + models->cases.removeChildObject(geoMechCase); + models->updateConnectedEditors(); + } + + delete geoMechCase; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicCloseCaseFeature::hasAnyStatisticsResults(RimIdenticalGridCaseGroup* gridCaseGroup) +{ + CVF_ASSERT(gridCaseGroup); + + for (size_t i = 0; i < gridCaseGroup->statisticsCaseCollection()->reservoirs().size(); i++) + { + RimEclipseStatisticsCase* rimStaticsCase = dynamic_cast(gridCaseGroup->statisticsCaseCollection()->reservoirs[i]); + if (rimStaticsCase) + { + if (rimStaticsCase->hasComputedStatistics()) + { + return true; + } + } + } + + return false; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicCloseCaseFeature::userConfirmedGridCaseGroupChange(const std::vector& casesToBeDeleted) +{ + std::vector gridCaseGroups; + + for (size_t i = 0; i < casesToBeDeleted.size(); i++) + { + RimIdenticalGridCaseGroup* gridCaseGroup = NULL; + casesToBeDeleted[i]->firstAnchestorOrThisOfType(gridCaseGroup); + + if (gridCaseGroup && hasAnyStatisticsResults(gridCaseGroup)) + { + gridCaseGroups.push_back(gridCaseGroup); + } + } + + if (gridCaseGroups.size() > 0) + { + RiuMainWindow* mainWnd = RiuMainWindow::instance(); + + QMessageBox msgBox(mainWnd); + msgBox.setIcon(QMessageBox::Question); + + QString questionText; + if (gridCaseGroups.size() == 1) + { + questionText = QString("This operation will invalidate statistics results in grid case group\n\"%1\".\n").arg(gridCaseGroups[0]->name()); + questionText += "Computed results in this group will be deleted if you continue."; + } + else + { + questionText = "This operation will invalidate statistics results in grid case groups\n"; + for (size_t i = 0; i < gridCaseGroups.size(); i++) + { + questionText += QString("\"%1\"\n").arg(gridCaseGroups[i]->name()); + } + + questionText += "Computed results in these groups will be deleted if you continue."; + } + + msgBox.setText(questionText); + msgBox.setInformativeText("Do you want to continue?"); + msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); + + int ret = msgBox.exec(); + if (ret == QMessageBox::No) + { + return false; + } + } + + return true; +} diff --git a/ApplicationCode/Commands/RicCloseCaseFeature.h b/ApplicationCode/Commands/RicCloseCaseFeature.h new file mode 100644 index 0000000000..7e6199f9b1 --- /dev/null +++ b/ApplicationCode/Commands/RicCloseCaseFeature.h @@ -0,0 +1,57 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdFeature.h" + +#include + +class RimEclipseCase; +class RimGeoMechCase; +class RimIdenticalGridCaseGroup; + +//================================================================================================== +/// +//================================================================================================== +class RicCloseCaseFeature : public caf::CmdFeature +{ + CAF_CMD_HEADER_INIT; + +public: + static void deleteEclipseCase(RimEclipseCase* eclipseCase); + static bool userConfirmedGridCaseGroupChange(const std::vector& casesToBeDeleted); + +protected: + // Overrides + virtual bool isCommandEnabled(); + virtual void onActionTriggered( bool isChecked ); + virtual void setupActionLook( QAction* actionToSetup ); + +private: + RimEclipseCase* selectedEclipseCase() const; + RimGeoMechCase* selectedGeoMechCase() const; + + void deleteGeoMechCase(RimGeoMechCase* geoMechCase); + + static bool hasAnyStatisticsResults(RimIdenticalGridCaseGroup* gridCaseGroup); + static void removeCaseFromAllGroups(RimEclipseCase* eclipseCase); +}; + + diff --git a/ApplicationCode/Commands/RicComputeStatisticsFeature.cpp b/ApplicationCode/Commands/RicComputeStatisticsFeature.cpp new file mode 100644 index 0000000000..3f1f21f104 --- /dev/null +++ b/ApplicationCode/Commands/RicComputeStatisticsFeature.cpp @@ -0,0 +1,98 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicComputeStatisticsFeature.h" + +#include "RimEclipseCase.h" +#include "RimEclipseStatisticsCase.h" +#include "RimEclipseStatisticsCaseCollection.h" +#include "RimIdenticalGridCaseGroup.h" +#include "RimCaseCollection.h" + +#include "cafSelectionManager.h" +#include "cafCmdFeatureManager.h" + +#include + +CAF_CMD_SOURCE_INIT(RicComputeStatisticsFeature, "RicComputeStatisticsFeature"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicComputeStatisticsFeature::isCommandEnabled() +{ + std::vector selection = selectedCases(); + if (selection.size() > 0) + { + RimEclipseStatisticsCase* statisticsCase = selection[0]; + if (statisticsCase) + { + RimIdenticalGridCaseGroup* gridCaseGroup = NULL; + statisticsCase->firstAnchestorOrThisOfType(gridCaseGroup); + + RimCaseCollection* caseCollection = gridCaseGroup ? gridCaseGroup->caseCollection() : NULL; + return caseCollection ? caseCollection->reservoirs.size() > 0 : false; + } + } + + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicComputeStatisticsFeature::onActionTriggered(bool isChecked) +{ + std::vector selection = selectedCases(); + if (selection.size() > 0) + { + RimEclipseStatisticsCase* statisticsCase = selection[0]; + + statisticsCase->computeStatistics(); + statisticsCase->scheduleACTIVEGeometryRegenOnReservoirViews(); + statisticsCase->updateConnectedEditorsAndReservoirViews(); + + if (statisticsCase->reservoirViews.size() == 0) + { + QAction* action = caf::CmdFeatureManager::instance()->action("RicNewViewFeature"); + CVF_ASSERT(action); + + action->trigger(); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicComputeStatisticsFeature::setupActionLook(QAction* actionToSetup) +{ + actionToSetup->setText("Compute"); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RicComputeStatisticsFeature::selectedCases() +{ + std::vector selection; + caf::SelectionManager::instance()->objectsByType(&selection); + + return selection; +} diff --git a/ApplicationCode/Commands/RicComputeStatisticsFeature.h b/ApplicationCode/Commands/RicComputeStatisticsFeature.h new file mode 100644 index 0000000000..40311dd00f --- /dev/null +++ b/ApplicationCode/Commands/RicComputeStatisticsFeature.h @@ -0,0 +1,43 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdFeature.h" + +#include + +class RimEclipseStatisticsCase; + +//================================================================================================== +/// +//================================================================================================== +class RicComputeStatisticsFeature : public caf::CmdFeature +{ + CAF_CMD_HEADER_INIT; + +protected: + // Overrides + virtual bool isCommandEnabled(); + virtual void onActionTriggered( bool isChecked ); + virtual void setupActionLook( QAction* actionToSetup ); + +private: + std::vector selectedCases(); +}; diff --git a/ApplicationCode/Commands/RicCreateGridCaseGroupFeature.cpp b/ApplicationCode/Commands/RicCreateGridCaseGroupFeature.cpp new file mode 100644 index 0000000000..6da72f89c2 --- /dev/null +++ b/ApplicationCode/Commands/RicCreateGridCaseGroupFeature.cpp @@ -0,0 +1,65 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicCreateGridCaseGroupFeature.h" + +#include "RimEclipseCaseCollection.h" +#include "RiaApplication.h" +#include "RiuMultiCaseImportDialog.h" + +#include "cafSelectionManager.h" + +#include + +CAF_CMD_SOURCE_INIT(RicCreateGridCaseGroupFeature, "RicCreateGridCaseGroupFeature"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicCreateGridCaseGroupFeature::isCommandEnabled() +{ + std::vector selection; + caf::SelectionManager::instance()->objectsByType(&selection); + + return selection.size() > 0; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicCreateGridCaseGroupFeature::onActionTriggered(bool isChecked) +{ + RiaApplication* app = RiaApplication::instance(); + RiuMultiCaseImportDialog dialog; + int action = dialog.exec(); + if (action == QDialog::Accepted) + { + QStringList gridFileNames = dialog.eclipseCaseFileNames(); + app->addEclipseCases(gridFileNames); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicCreateGridCaseGroupFeature::setupActionLook(QAction* actionToSetup) +{ + actionToSetup->setIcon(QIcon(":/CreateGridCaseGroup16x16.png")); + actionToSetup->setText("&Create Grid Case Group from Files"); +} diff --git a/ApplicationCode/Commands/RicCreateGridCaseGroupFeature.h b/ApplicationCode/Commands/RicCreateGridCaseGroupFeature.h new file mode 100644 index 0000000000..ef7d863655 --- /dev/null +++ b/ApplicationCode/Commands/RicCreateGridCaseGroupFeature.h @@ -0,0 +1,40 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdFeature.h" + +#include + +//================================================================================================== +/// +//================================================================================================== +class RicCreateGridCaseGroupFeature : public caf::CmdFeature +{ + CAF_CMD_HEADER_INIT; + +protected: + // Overrides + virtual bool isCommandEnabled(); + virtual void onActionTriggered( bool isChecked ); + virtual void setupActionLook( QAction* actionToSetup ); +}; + + diff --git a/ApplicationCode/Commands/RicDeleteItemExec.cpp b/ApplicationCode/Commands/RicDeleteItemExec.cpp new file mode 100644 index 0000000000..184c982563 --- /dev/null +++ b/ApplicationCode/Commands/RicDeleteItemExec.cpp @@ -0,0 +1,205 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + + +#include "RicDeleteItemExec.h" +#include "RicDeleteItemExecData.h" + +#include "RimCellRangeFilterCollection.h" +#include "RimEclipsePropertyFilterCollection.h" +#include "RimGeoMechPropertyFilterCollection.h" +#include "RimProject.h" +#include "RimView.h" +#include "RimViewLinkerCollection.h" +#include "RimWellLogPlot.h" +#include "RimWellLogPlotCollection.h" +#include "RimWellLogPlotTrack.h" +#include "RimWellPathCollection.h" + +#include "cafNotificationCenter.h" +#include "cafPdmChildArrayField.h" +#include "cafPdmDocument.h" +#include "cafPdmReferenceHelper.h" +#include "cafPdmUiFieldHandle.h" +#include "cafSelectionManager.h" + + +namespace caf +{ + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RicDeleteItemExec::name() +{ + return m_commandData->classKeyword(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicDeleteItemExec::redo() +{ + PdmFieldHandle* field = PdmReferenceHelper::fieldFromReference(m_commandData->m_rootObject, m_commandData->m_pathToField); + + PdmChildArrayFieldHandle* listField = dynamic_cast(field); + if (listField) + { + std::vector children; + listField->childObjects(&children); + + PdmObjectHandle* obj = children[m_commandData->m_indexToObject]; + caf::SelectionManager::instance()->removeObjectFromAllSelections(obj); + + if (m_commandData->m_deletedObjectAsXml().isEmpty()) + { + m_commandData->m_deletedObjectAsXml = xmlObj(obj)->writeObjectToXmlString(); + } + + delete obj; + + listField->erase(m_commandData->m_indexToObject); + + caf::PdmObjectHandle* parentObj = listField->ownerObject(); + parentObj->uiCapability()->updateConnectedEditors(); + + RimView* view = NULL; + parentObj->firstAnchestorOrThisOfType(view); + + RimCellRangeFilterCollection* rangeFilterColl; + parentObj->firstAnchestorOrThisOfType(rangeFilterColl); + + if (rangeFilterColl) + { + rangeFilterColl->updateDisplayModeNotifyManagedViews(NULL); + } + + RimEclipsePropertyFilterCollection* eclipsePropColl; + parentObj->firstAnchestorOrThisOfType(eclipsePropColl); + + RimGeoMechPropertyFilterCollection* geoMechPropColl; + parentObj->firstAnchestorOrThisOfType(geoMechPropColl); + + if (view && (eclipsePropColl || geoMechPropColl)) + { + view->scheduleGeometryRegen(PROPERTY_FILTERED); + view->scheduleCreateDisplayModelAndRedraw(); + } + + RimWellPathCollection* wellPathColl; + parentObj->firstAnchestorOrThisOfType(wellPathColl); + + if (wellPathColl) + { + wellPathColl->scheduleGeometryRegenAndRedrawViews(); + } + + // Update due to deletion of curves (not tracks, handled separatly) + + RimWellLogPlot* wellLogPlot; + parentObj->firstAnchestorOrThisOfType(wellLogPlot); + if (wellLogPlot) + { + wellLogPlot->calculateAvailableDepthRange(); + wellLogPlot->zoomAllDepth(); + } + + RimWellLogPlotTrack* wellLogPlotTrack; + parentObj->firstAnchestorOrThisOfType(wellLogPlotTrack); + if (wellLogPlotTrack) + { + wellLogPlotTrack->zoomAllXAxis(); + } + + // Update due to delete plots + // Make sure the plot collection disappears with the last plot + + RimWellLogPlotCollection* wellLogPlotCollection = dynamic_cast(parentObj); + if (wellLogPlotCollection) + { + if (wellLogPlotCollection->wellLogPlots.empty()) + { + RimProject* project = NULL; + parentObj->firstAnchestorOrThisOfType(project); + if (project) + { + project->updateConnectedEditors(); + } + } + } + + RimViewLinkerCollection* viewLinkerCollection = NULL; + parentObj->firstAnchestorOrThisOfType(viewLinkerCollection); + if (viewLinkerCollection) + { + viewLinkerCollection->uiCapability()->updateConnectedEditors(); + + RimProject* project = NULL; + parentObj->firstAnchestorOrThisOfType(project); + if (project) + { + // Update visibility of top level Linked Views item in the project tree + // Not visible if no views are linked + project->uiCapability()->updateConnectedEditors(); + } + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicDeleteItemExec::undo() +{ + PdmFieldHandle* field = PdmReferenceHelper::fieldFromReference(m_commandData->m_rootObject, m_commandData->m_pathToField); + + PdmChildArrayFieldHandle* listField = dynamic_cast(field); + if (listField) + { + PdmObjectHandle* obj = PdmXmlObjectHandle::readUnknownObjectFromXmlString(m_commandData->m_deletedObjectAsXml(), PdmDefaultObjectFactory::instance()); + + listField->insertAt(m_commandData->m_indexToObject, obj); + + obj->xmlCapability()->initAfterReadRecursively(); + + listField->uiCapability()->updateConnectedEditors(); + listField->ownerObject()->uiCapability()->updateConnectedEditors(); + + if (m_notificationCenter) m_notificationCenter->notifyObservers(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicDeleteItemExec::RicDeleteItemExec(NotificationCenter* notificationCenter) + : CmdExecuteCommand(notificationCenter) +{ + m_commandData = new RicDeleteItemExecData; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicDeleteItemExecData* RicDeleteItemExec::commandData() +{ + return m_commandData; +} + +} // end namespace caf diff --git a/ApplicationCode/Commands/RicDeleteItemExec.h b/ApplicationCode/Commands/RicDeleteItemExec.h new file mode 100644 index 0000000000..c58817b347 --- /dev/null +++ b/ApplicationCode/Commands/RicDeleteItemExec.h @@ -0,0 +1,50 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + + +#pragma once + +#include "cafCmdExecuteCommand.h" + +namespace caf +{ + +class RicDeleteItemExecData; + +//================================================================================================== +/// +//================================================================================================== +class RicDeleteItemExec : public CmdExecuteCommand +{ +public: + RicDeleteItemExec(NotificationCenter* notificationCenter); + + RicDeleteItemExecData* commandData(); + + virtual QString name(); + virtual void redo(); + virtual void undo(); + +private: + RicDeleteItemExecData* m_commandData; +}; + + + +} // end namespace caf diff --git a/ApplicationCode/Commands/RicDeleteItemExecData.cpp b/ApplicationCode/Commands/RicDeleteItemExecData.cpp new file mode 100644 index 0000000000..6f0a20bb6a --- /dev/null +++ b/ApplicationCode/Commands/RicDeleteItemExecData.cpp @@ -0,0 +1,29 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + + +#include "RicDeleteItemExecData.h" + + +namespace caf +{ + +CAF_PDM_SOURCE_INIT(RicDeleteItemExecData, "RicDeleteItemExecData"); + +} // end namespace caf diff --git a/ApplicationCode/Commands/RicDeleteItemExecData.h b/ApplicationCode/Commands/RicDeleteItemExecData.h new file mode 100644 index 0000000000..e8000233b4 --- /dev/null +++ b/ApplicationCode/Commands/RicDeleteItemExecData.h @@ -0,0 +1,56 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + + +#pragma once + +#include "cafPdmObject.h" +#include "cafPdmField.h" + +namespace caf +{ + + +//================================================================================================== +/// +//================================================================================================== +class RicDeleteItemExecData : public PdmObject +{ + CAF_PDM_HEADER_INIT; + +public: + RicDeleteItemExecData() + { + CAF_PDM_InitObject("CmdDeleteItemExecData uiName", "", "CmdDeleteItemExecData tooltip", "CmdDeleteItemExecData whatsthis"); + + CAF_PDM_InitField(&m_pathToField, "PathToField", QString(), "PathToField", "", "PathToField tooltip", "PathToField whatsthis"); + CAF_PDM_InitField(&m_indexToObject, "indexToObject", -1, "indexToObject", "", "indexToObject tooltip", "indexToObject whatsthis"); + CAF_PDM_InitField(&m_deletedObjectAsXml, "deletedObjectAsXml", QString(), "deletedObjectAsXml", "", "deletedObjectAsXml tooltip", "deletedObjectAsXml whatsthis"); + } + + caf::PdmPointer m_rootObject; + + caf::PdmField m_pathToField; + caf::PdmField m_indexToObject; + caf::PdmField m_deletedObjectAsXml; +}; + + + +} // end namespace caf diff --git a/ApplicationCode/Commands/RicDeleteItemFeature.cpp b/ApplicationCode/Commands/RicDeleteItemFeature.cpp new file mode 100644 index 0000000000..6e9a9fe65b --- /dev/null +++ b/ApplicationCode/Commands/RicDeleteItemFeature.cpp @@ -0,0 +1,104 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicDeleteItemFeature.h" +#include "RicDeleteItemExec.h" +#include "RicDeleteItemExecData.h" + +#include "RimWellLogPlot.h" +#include "RimWellLogPlotTrack.h" + +#include "cafCmdExecCommandManager.h" +#include "cafCmdSelectionHelper.h" +#include "cafPdmChildArrayField.h" +#include "cafPdmField.h" +#include "cafPdmReferenceHelper.h" +#include "cafSelectionManager.h" + +#include + +namespace caf +{ + CAF_CMD_SOURCE_INIT(RicDeleteItemFeature, "RicDeleteItemFeature"); + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicDeleteItemFeature::isCommandEnabled() +{ + caf::PdmObject* currentPdmObject = dynamic_cast(caf::SelectionManager::instance()->selectedItem()); + if (!currentPdmObject) return false; + + caf::PdmChildArrayFieldHandle* childArrayFieldHandle = dynamic_cast(currentPdmObject->parentField()); + if (!childArrayFieldHandle) return false; + + return true; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicDeleteItemFeature::onActionTriggered(bool isChecked) +{ + std::vector items; + SelectionManager::instance()->selectedItems(items); + assert(items.size() > 0); + + caf::PdmObject* currentPdmObject = dynamic_cast(items[0]); + assert(currentPdmObject); + + caf::PdmChildArrayFieldHandle* childArrayFieldHandle = dynamic_cast(currentPdmObject->parentField()); + + int indexAfter = -1; + + std::vector childObjects; + childArrayFieldHandle->childObjects(&childObjects); + + for (size_t i = 0; i < childObjects.size(); i++) + { + if (childObjects[i] == currentPdmObject) + { + indexAfter = static_cast(i); + } + } + + // Did not find currently selected pdm object in the current list field + assert(indexAfter != -1); + + RicDeleteItemExec* executeCmd = new RicDeleteItemExec(SelectionManager::instance()->notificationCenter()); + + RicDeleteItemExecData* data = executeCmd->commandData(); + data->m_rootObject = PdmReferenceHelper::findRoot(childArrayFieldHandle); + data->m_pathToField = PdmReferenceHelper::referenceFromRootToField(data->m_rootObject, childArrayFieldHandle); + data->m_indexToObject = indexAfter; + + + CmdExecCommandManager::instance()->processExecuteCommand(executeCmd); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicDeleteItemFeature::setupActionLook(QAction* actionToSetup) +{ + actionToSetup->setText("Delete"); +} + +} // end namespace caf diff --git a/ApplicationCode/Commands/RicDeleteItemFeature.h b/ApplicationCode/Commands/RicDeleteItemFeature.h new file mode 100644 index 0000000000..5cde0517ef --- /dev/null +++ b/ApplicationCode/Commands/RicDeleteItemFeature.h @@ -0,0 +1,43 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdFeature.h" + +namespace caf +{ + +//================================================================================================== +/// +//================================================================================================== +class RicDeleteItemFeature : public CmdFeature +{ + CAF_CMD_HEADER_INIT; +protected: + + // Overrides + virtual bool isCommandEnabled(); + virtual void onActionTriggered( bool isChecked ); + virtual void setupActionLook( QAction* actionToSetup ); +}; + + + +} // end namespace caf diff --git a/ApplicationCode/Commands/RicEclipseCaseNewGroupExec.cpp b/ApplicationCode/Commands/RicEclipseCaseNewGroupExec.cpp new file mode 100644 index 0000000000..902085ad10 --- /dev/null +++ b/ApplicationCode/Commands/RicEclipseCaseNewGroupExec.cpp @@ -0,0 +1,88 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicEclipseCaseNewGroupExec.h" + +#include "RimProject.h" +#include "RimEclipseCase.h" +#include "RimEclipseCaseCollection.h" +#include "RimEclipseStatisticsCase.h" +#include "RimIdenticalGridCaseGroup.h" +#include "RimOilField.h" + +#include "RiaApplication.h" +#include "RiuMainWindow.h" + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicEclipseCaseNewGroupExec::RicEclipseCaseNewGroupExec() + : CmdExecuteCommand(NULL) +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicEclipseCaseNewGroupExec::~RicEclipseCaseNewGroupExec() +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RicEclipseCaseNewGroupExec::name() +{ + return "New Grid Case Group"; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicEclipseCaseNewGroupExec::redo() +{ + RimProject* proj = RiaApplication::instance()->project(); + CVF_ASSERT(proj); + + RimEclipseCaseCollection* analysisModels = proj->activeOilField() ? proj->activeOilField()->analysisModels() : NULL; + + if (analysisModels) + { + RimIdenticalGridCaseGroup* createdObject = new RimIdenticalGridCaseGroup; + proj->assignIdToCaseGroup(createdObject); + + RimEclipseCase* createdReservoir = createdObject->createAndAppendStatisticsCase(); + proj->assignCaseIdToCase(createdReservoir); + createdObject->name = QString("Grid Case Group %1").arg(analysisModels->caseGroups().size() + 1); + + analysisModels->caseGroups().push_back(createdObject); + analysisModels->updateConnectedEditors(); + RiuMainWindow::instance()->setCurrentObjectInTreeView(createdObject); + RiuMainWindow::instance()->setExpanded(createdObject, true); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicEclipseCaseNewGroupExec::undo() +{ + // TODO + CVF_ASSERT(0); +} diff --git a/ApplicationCode/Commands/RicEclipseCaseNewGroupExec.h b/ApplicationCode/Commands/RicEclipseCaseNewGroupExec.h new file mode 100644 index 0000000000..75e5013341 --- /dev/null +++ b/ApplicationCode/Commands/RicEclipseCaseNewGroupExec.h @@ -0,0 +1,37 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdExecuteCommand.h" + +//================================================================================================== +/// +//================================================================================================== +class RicEclipseCaseNewGroupExec : public caf::CmdExecuteCommand +{ +public: + RicEclipseCaseNewGroupExec(); + virtual ~RicEclipseCaseNewGroupExec(); + + virtual QString name(); + virtual void redo(); + virtual void undo(); +}; + diff --git a/ApplicationCode/Commands/RicEclipseCaseNewGroupFeature.cpp b/ApplicationCode/Commands/RicEclipseCaseNewGroupFeature.cpp new file mode 100644 index 0000000000..b0b1f2a590 --- /dev/null +++ b/ApplicationCode/Commands/RicEclipseCaseNewGroupFeature.cpp @@ -0,0 +1,65 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicEclipseCaseNewGroupFeature.h" + +#include "RicEclipseCaseNewGroupExec.h" + +#include "RimCase.h" +#include "RimEclipseCaseCollection.h" + +#include "cafSelectionManager.h" +#include "cafCmdExecCommandManager.h" + +#include + +CAF_CMD_SOURCE_INIT(RicEclipseCaseNewGroupFeature, "RicEclipseCaseNewGroupFeature"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicEclipseCaseNewGroupFeature::isCommandEnabled() +{ + std::vector caseSelection; + caf::SelectionManager::instance()->objectsByType(&caseSelection); + + std::vector caseCollSelection; + caf::SelectionManager::instance()->objectsByType(&caseCollSelection); + + return caseSelection.size() > 0 || caseCollSelection.size() > 0; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicEclipseCaseNewGroupFeature::onActionTriggered(bool isChecked) +{ + RicEclipseCaseNewGroupExec* cmdExec = new RicEclipseCaseNewGroupExec(); + caf::CmdExecCommandManager::instance()->processExecuteCommand(cmdExec); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicEclipseCaseNewGroupFeature::setupActionLook(QAction* actionToSetup) +{ + actionToSetup->setText("New Grid Case Group"); +} + + diff --git a/ApplicationCode/Commands/RicEclipseCaseNewGroupFeature.h b/ApplicationCode/Commands/RicEclipseCaseNewGroupFeature.h new file mode 100644 index 0000000000..669c92ef5d --- /dev/null +++ b/ApplicationCode/Commands/RicEclipseCaseNewGroupFeature.h @@ -0,0 +1,39 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdFeature.h" + + +//================================================================================================== +/// +//================================================================================================== +class RicEclipseCaseNewGroupFeature : public caf::CmdFeature +{ + CAF_CMD_HEADER_INIT; + +protected: + // Overrides + virtual bool isCommandEnabled(); + virtual void onActionTriggered( bool isChecked ); + virtual void setupActionLook( QAction* actionToSetup ); +}; + + diff --git a/ApplicationCode/Commands/RicEclipsePropertyFilterFeatureImpl.cpp b/ApplicationCode/Commands/RicEclipsePropertyFilterFeatureImpl.cpp new file mode 100644 index 0000000000..8864b9613a --- /dev/null +++ b/ApplicationCode/Commands/RicEclipsePropertyFilterFeatureImpl.cpp @@ -0,0 +1,126 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicEclipsePropertyFilterFeatureImpl.h" + +#include "RimEclipsePropertyFilter.h" +#include "RimEclipsePropertyFilterCollection.h" +#include "RimEclipseView.h" +#include "RimEclipseResultDefinition.h" +#include "RimEclipseCellColors.h" +#include "RimViewController.h" + +#include "cafSelectionManager.h" + +#include "cvfAssert.h" +#include "RiuMainWindow.h" + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RicEclipsePropertyFilterFeatureImpl::selectedPropertyFilters() +{ + std::vector propertyFilters; + caf::SelectionManager::instance()->objectsByType(&propertyFilters); + + return propertyFilters; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RicEclipsePropertyFilterFeatureImpl::selectedPropertyFilterCollections() +{ + std::vector propertyFilterCollections; + caf::SelectionManager::instance()->objectsByType(&propertyFilterCollections); + + return propertyFilterCollections; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicEclipsePropertyFilterFeatureImpl::addPropertyFilter(RimEclipsePropertyFilterCollection* propertyFilterCollection) +{ + RimEclipsePropertyFilter* propertyFilter = new RimEclipsePropertyFilter(); + propertyFilterCollection->propertyFilters.push_back(propertyFilter); + setDefaults(propertyFilter); + + propertyFilterCollection->reservoirView()->scheduleGeometryRegen(PROPERTY_FILTERED); + + propertyFilterCollection->updateConnectedEditors(); + RiuMainWindow::instance()->setCurrentObjectInTreeView(propertyFilter); + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicEclipsePropertyFilterFeatureImpl::insertPropertyFilter(RimEclipsePropertyFilterCollection* propertyFilterCollection, size_t index) +{ + RimEclipsePropertyFilter* propertyFilter = new RimEclipsePropertyFilter(); + propertyFilterCollection->propertyFilters.insertAt(static_cast(index), propertyFilter); + setDefaults(propertyFilter); + + propertyFilterCollection->reservoirView()->scheduleGeometryRegen(PROPERTY_FILTERED); + + propertyFilterCollection->updateConnectedEditors(); + RiuMainWindow::instance()->setCurrentObjectInTreeView(propertyFilter); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicEclipsePropertyFilterFeatureImpl::isPropertyFilterCommandAvailable(caf::PdmObjectHandle* object) +{ + RimView* rimView = NULL; + object->firstAnchestorOrThisOfType(rimView); + if (rimView) + { + RimViewController* vc = rimView->viewController(); + if (vc && vc->isPropertyFilterOveridden()) + { + return false; + } + } + + return true; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicEclipsePropertyFilterFeatureImpl::setDefaults(RimEclipsePropertyFilter* propertyFilter) +{ + CVF_ASSERT(propertyFilter); + + RimEclipsePropertyFilterCollection* propertyFilterCollection = propertyFilter->parentContainer(); + CVF_ASSERT(propertyFilterCollection); + + RimEclipseView* reservoirView = propertyFilterCollection->reservoirView(); + CVF_ASSERT(reservoirView); + + propertyFilter->resultDefinition->setEclipseCase(reservoirView->eclipseCase()); + propertyFilter->resultDefinition->setResultVariable(reservoirView->cellResult->resultVariable()); + propertyFilter->resultDefinition->setPorosityModel(reservoirView->cellResult->porosityModel()); + propertyFilter->resultDefinition->setResultType(reservoirView->cellResult->resultType()); + propertyFilter->resultDefinition->loadResult(); + propertyFilter->setToDefaultValues(); + propertyFilter->updateFilterName(); +} diff --git a/ApplicationCode/Commands/RicEclipsePropertyFilterFeatureImpl.h b/ApplicationCode/Commands/RicEclipsePropertyFilterFeatureImpl.h new file mode 100644 index 0000000000..875adf1ecf --- /dev/null +++ b/ApplicationCode/Commands/RicEclipsePropertyFilterFeatureImpl.h @@ -0,0 +1,51 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include +#include + +class RimEclipsePropertyFilter; +class RimEclipsePropertyFilterCollection; + +namespace caf +{ + class PdmObjectHandle; +} + +//================================================================================================== +/// +//================================================================================================== +class RicEclipsePropertyFilterFeatureImpl +{ +public: + static std::vector selectedPropertyFilters(); + static std::vector selectedPropertyFilterCollections(); + + static void addPropertyFilter(RimEclipsePropertyFilterCollection* propertyFilterCollection); + static void insertPropertyFilter(RimEclipsePropertyFilterCollection* propertyFilterCollection, size_t index); + + static bool isPropertyFilterCommandAvailable(caf::PdmObjectHandle* object); + +private: + static void setDefaults(RimEclipsePropertyFilter* propertyFilter); +}; + + diff --git a/ApplicationCode/Commands/RicEclipsePropertyFilterInsertExec.cpp b/ApplicationCode/Commands/RicEclipsePropertyFilterInsertExec.cpp new file mode 100644 index 0000000000..0eb7f9c956 --- /dev/null +++ b/ApplicationCode/Commands/RicEclipsePropertyFilterInsertExec.cpp @@ -0,0 +1,76 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicEclipsePropertyFilterInsertExec.h" + + +#include "RicEclipsePropertyFilterFeatureImpl.h" + +#include "RimEclipsePropertyFilter.h" +#include "RimEclipsePropertyFilterCollection.h" + +#include "cvfAssert.h" + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicEclipsePropertyFilterInsertExec::RicEclipsePropertyFilterInsertExec(RimEclipsePropertyFilter* propertyFilter) + : CmdExecuteCommand(NULL) +{ + CVF_ASSERT(propertyFilter); + m_propertyFilter = propertyFilter; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicEclipsePropertyFilterInsertExec::~RicEclipsePropertyFilterInsertExec() +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RicEclipsePropertyFilterInsertExec::name() +{ + return "Insert Property Filter"; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicEclipsePropertyFilterInsertExec::redo() +{ + RimEclipsePropertyFilterCollection* propertyFilterCollection = m_propertyFilter->parentContainer(); + CVF_ASSERT(propertyFilterCollection); + + size_t index = propertyFilterCollection->propertyFilters.index(m_propertyFilter); + CVF_ASSERT(index < propertyFilterCollection->propertyFilters.size()); + + RicEclipsePropertyFilterFeatureImpl::insertPropertyFilter(propertyFilterCollection, index); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicEclipsePropertyFilterInsertExec::undo() +{ + // TODO + CVF_ASSERT(0); +} diff --git a/ApplicationCode/Commands/RicEclipsePropertyFilterInsertExec.h b/ApplicationCode/Commands/RicEclipsePropertyFilterInsertExec.h new file mode 100644 index 0000000000..727a30d8fc --- /dev/null +++ b/ApplicationCode/Commands/RicEclipsePropertyFilterInsertExec.h @@ -0,0 +1,43 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdExecuteCommand.h" +#include "cafPdmPointer.h" + +class RimEclipsePropertyFilter; + +//================================================================================================== +/// +//================================================================================================== +class RicEclipsePropertyFilterInsertExec : public caf::CmdExecuteCommand +{ +public: + RicEclipsePropertyFilterInsertExec(RimEclipsePropertyFilter* propertyFilter); + virtual ~RicEclipsePropertyFilterInsertExec(); + + virtual QString name(); + virtual void redo(); + virtual void undo(); + +private: + caf::PdmPointer m_propertyFilter; +}; + diff --git a/ApplicationCode/Commands/RicEclipsePropertyFilterInsertFeature.cpp b/ApplicationCode/Commands/RicEclipsePropertyFilterInsertFeature.cpp new file mode 100644 index 0000000000..cd845f2b9f --- /dev/null +++ b/ApplicationCode/Commands/RicEclipsePropertyFilterInsertFeature.cpp @@ -0,0 +1,68 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicEclipsePropertyFilterInsertFeature.h" + +#include "RicEclipsePropertyFilterInsertExec.h" +#include "RicEclipsePropertyFilterFeatureImpl.h" + +#include "RimEclipsePropertyFilter.h" + +#include "cafCmdExecCommandManager.h" + +#include + +#include + +CAF_CMD_SOURCE_INIT(RicEclipsePropertyFilterInsertFeature, "RicEclipsePropertyFilterInsertFeature"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicEclipsePropertyFilterInsertFeature::isCommandEnabled() +{ + std::vector propertyFilters = RicEclipsePropertyFilterFeatureImpl::selectedPropertyFilters(); + if (propertyFilters.size() == 1) + { + return RicEclipsePropertyFilterFeatureImpl::isPropertyFilterCommandAvailable(propertyFilters[0]); + } + + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicEclipsePropertyFilterInsertFeature::onActionTriggered(bool isChecked) +{ + std::vector propertyFilters = RicEclipsePropertyFilterFeatureImpl::selectedPropertyFilters(); + if (propertyFilters.size() == 1) + { + RicEclipsePropertyFilterInsertExec* filterExec = new RicEclipsePropertyFilterInsertExec(propertyFilters[0]); + caf::CmdExecCommandManager::instance()->processExecuteCommand(filterExec); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicEclipsePropertyFilterInsertFeature::setupActionLook(QAction* actionToSetup) +{ + actionToSetup->setText("Insert Property Filter"); +} diff --git a/ApplicationCode/Commands/RicEclipsePropertyFilterInsertFeature.h b/ApplicationCode/Commands/RicEclipsePropertyFilterInsertFeature.h new file mode 100644 index 0000000000..965ea705b2 --- /dev/null +++ b/ApplicationCode/Commands/RicEclipsePropertyFilterInsertFeature.h @@ -0,0 +1,39 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdFeature.h" + + +//================================================================================================== +/// +//================================================================================================== +class RicEclipsePropertyFilterInsertFeature : public caf::CmdFeature +{ + CAF_CMD_HEADER_INIT; + +protected: + // Overrides + virtual bool isCommandEnabled(); + virtual void onActionTriggered( bool isChecked ); + virtual void setupActionLook( QAction* actionToSetup ); +}; + + diff --git a/ApplicationCode/Commands/RicEclipsePropertyFilterNewExec.cpp b/ApplicationCode/Commands/RicEclipsePropertyFilterNewExec.cpp new file mode 100644 index 0000000000..0038db42f6 --- /dev/null +++ b/ApplicationCode/Commands/RicEclipsePropertyFilterNewExec.cpp @@ -0,0 +1,69 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicEclipsePropertyFilterNewExec.h" + +#include "RicEclipsePropertyFilterFeatureImpl.h" + +#include "RimEclipsePropertyFilter.h" +#include "RimEclipsePropertyFilterCollection.h" + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicEclipsePropertyFilterNewExec::RicEclipsePropertyFilterNewExec(RimEclipsePropertyFilterCollection* propertyFilterCollection) + : CmdExecuteCommand(NULL) +{ + assert(propertyFilterCollection); + m_propertyFilterCollection = propertyFilterCollection; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicEclipsePropertyFilterNewExec::~RicEclipsePropertyFilterNewExec() +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RicEclipsePropertyFilterNewExec::name() +{ + return "New Property Filter"; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicEclipsePropertyFilterNewExec::redo() +{ + RicEclipsePropertyFilterFeatureImpl::addPropertyFilter(m_propertyFilterCollection); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicEclipsePropertyFilterNewExec::undo() +{ + m_propertyFilterCollection->propertyFilters.erase(m_propertyFilterCollection->propertyFilters.size() - 1); + + m_propertyFilterCollection->updateConnectedEditors(); +} diff --git a/ApplicationCode/Commands/RicEclipsePropertyFilterNewExec.h b/ApplicationCode/Commands/RicEclipsePropertyFilterNewExec.h new file mode 100644 index 0000000000..f890ce57e6 --- /dev/null +++ b/ApplicationCode/Commands/RicEclipsePropertyFilterNewExec.h @@ -0,0 +1,44 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdExecuteCommand.h" +#include "cafPdmPointer.h" + +class RimEclipsePropertyFilterCollection; + +//================================================================================================== +/// +//================================================================================================== +class RicEclipsePropertyFilterNewExec : public caf::CmdExecuteCommand +{ +public: + RicEclipsePropertyFilterNewExec(RimEclipsePropertyFilterCollection* propertyFilterCollection); + virtual ~RicEclipsePropertyFilterNewExec(); + + virtual QString name(); + virtual void redo(); + virtual void undo(); + +private: + caf::PdmPointer m_propertyFilterCollection; +}; + + diff --git a/ApplicationCode/Commands/RicEclipsePropertyFilterNewFeature.cpp b/ApplicationCode/Commands/RicEclipsePropertyFilterNewFeature.cpp new file mode 100644 index 0000000000..57366ce3cc --- /dev/null +++ b/ApplicationCode/Commands/RicEclipsePropertyFilterNewFeature.cpp @@ -0,0 +1,68 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicEclipsePropertyFilterNewFeature.h" + +#include "RicEclipsePropertyFilterNewExec.h" +#include "RicEclipsePropertyFilterFeatureImpl.h" + +#include "RimEclipsePropertyFilter.h" +#include "RimEclipsePropertyFilterCollection.h" + +#include "cafCmdExecCommandManager.h" + +#include + +CAF_CMD_SOURCE_INIT(RicEclipsePropertyFilterNewFeature, "RicEclipsePropertyFilterNewFeature"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicEclipsePropertyFilterNewFeature::isCommandEnabled() +{ + std::vector filterCollections = RicEclipsePropertyFilterFeatureImpl::selectedPropertyFilterCollections(); + if (filterCollections.size() == 1) + { + return RicEclipsePropertyFilterFeatureImpl::isPropertyFilterCommandAvailable(filterCollections[0]); + } + + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicEclipsePropertyFilterNewFeature::onActionTriggered(bool isChecked) +{ + std::vector filterCollections = RicEclipsePropertyFilterFeatureImpl::selectedPropertyFilterCollections(); + if (filterCollections.size() == 1) + { + RicEclipsePropertyFilterNewExec* filterExec = new RicEclipsePropertyFilterNewExec(filterCollections[0]); + caf::CmdExecCommandManager::instance()->processExecuteCommand(filterExec); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicEclipsePropertyFilterNewFeature::setupActionLook(QAction* actionToSetup) +{ + actionToSetup->setIcon(QIcon(":/CellFilter_Values.png")); + actionToSetup->setText("New Property Filter"); +} diff --git a/ApplicationCode/Commands/RicEclipsePropertyFilterNewFeature.h b/ApplicationCode/Commands/RicEclipsePropertyFilterNewFeature.h new file mode 100644 index 0000000000..da3ac841c7 --- /dev/null +++ b/ApplicationCode/Commands/RicEclipsePropertyFilterNewFeature.h @@ -0,0 +1,39 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdFeature.h" + + +//================================================================================================== +/// +//================================================================================================== +class RicEclipsePropertyFilterNewFeature : public caf::CmdFeature +{ + CAF_CMD_HEADER_INIT; + +protected: + // Overrides + virtual bool isCommandEnabled(); + virtual void onActionTriggered( bool isChecked ); + virtual void setupActionLook( QAction* actionToSetup ); +}; + + diff --git a/ApplicationCode/Commands/RicExportToLasFileFeature.cpp b/ApplicationCode/Commands/RicExportToLasFileFeature.cpp new file mode 100644 index 0000000000..17c45bf7c0 --- /dev/null +++ b/ApplicationCode/Commands/RicExportToLasFileFeature.cpp @@ -0,0 +1,91 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicExportToLasFileFeature.h" + +#include "RimWellLogPlotCurve.h" +#include "RigWellLogFile.h" + +#include "RiuMainWindow.h" +#include "RiaApplication.h" + +#include "cafSelectionManager.h" + +#include +#include +#include + +CAF_CMD_SOURCE_INIT(RicExportToLasFileFeature, "RicExportToLasFileFeature"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicExportToLasFileFeature::isCommandEnabled() +{ + return selectedWellLogPlotCurve() != NULL; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicExportToLasFileFeature::onActionTriggered(bool isChecked) +{ + RimWellLogPlotCurve* curve = selectedWellLogPlotCurve(); + if (curve) + { + QString defaultDir = RiaApplication::instance()->defaultFileDialogDirectory("WELL_LOGS_DIR"); + + QString defaultFileName = curve->name().trimmed(); + defaultFileName.replace(".", "_"); + defaultFileName.replace(",", "_"); + defaultFileName.replace(" ", "_"); + defaultFileName.replace(QRegExp("_+"), "_"); + defaultFileName.append(".las"); + + QString fileName = QFileDialog::getSaveFileName(RiuMainWindow::instance(), tr("Export Curve Data To LAS File"), QDir(defaultDir).absoluteFilePath(defaultFileName), tr("LAS Files (*.las);;All files(*.*)")); + if (!fileName.isEmpty()) + { + RigWellLogFile::exportToLasFile(curve, fileName); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicExportToLasFileFeature::setupActionLook(QAction* actionToSetup) +{ + actionToSetup->setText("Export To LAS File..."); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimWellLogPlotCurve* RicExportToLasFileFeature::selectedWellLogPlotCurve() const +{ + std::vector selection; + caf::SelectionManager::instance()->objectsByType(&selection); + + if (selection.size() > 0) + { + return selection[0]; + } + + return NULL; +} diff --git a/ApplicationCode/Commands/RicExportToLasFileFeature.h b/ApplicationCode/Commands/RicExportToLasFileFeature.h new file mode 100644 index 0000000000..527fb64169 --- /dev/null +++ b/ApplicationCode/Commands/RicExportToLasFileFeature.h @@ -0,0 +1,45 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdFeature.h" + +#include + +class RimWellLogPlotCurve; + +//================================================================================================== +/// +//================================================================================================== +class RicExportToLasFileFeature : public caf::CmdFeature +{ + CAF_CMD_HEADER_INIT; + +protected: + // Overrides + virtual bool isCommandEnabled(); + virtual void onActionTriggered( bool isChecked ); + virtual void setupActionLook( QAction* actionToSetup ); + +private: + RimWellLogPlotCurve* selectedWellLogPlotCurve() const; +}; + + diff --git a/ApplicationCode/Commands/RicGeoMechPropertyFilterFeatureImpl.cpp b/ApplicationCode/Commands/RicGeoMechPropertyFilterFeatureImpl.cpp new file mode 100644 index 0000000000..312b260336 --- /dev/null +++ b/ApplicationCode/Commands/RicGeoMechPropertyFilterFeatureImpl.cpp @@ -0,0 +1,132 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicGeoMechPropertyFilterFeatureImpl.h" +#include "RicEclipsePropertyFilterFeatureImpl.h" + +#include "RimGeoMechPropertyFilter.h" +#include "RimGeoMechPropertyFilterCollection.h" +#include "RimGeoMechView.h" +#include "RimGeoMechResultDefinition.h" +#include "RimGeoMechCellColors.h" + +#include "cafSelectionManager.h" + +#include "cvfAssert.h" +#include "RiuMainWindow.h" + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RicGeoMechPropertyFilterFeatureImpl::selectedPropertyFilters() +{ + std::vector propertyFilters; + caf::SelectionManager::instance()->objectsByType(&propertyFilters); + + return propertyFilters; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RicGeoMechPropertyFilterFeatureImpl::selectedPropertyFilterCollections() +{ + std::vector propertyFilterCollections; + caf::SelectionManager::instance()->objectsByType(&propertyFilterCollections); + + return propertyFilterCollections; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicGeoMechPropertyFilterFeatureImpl::addPropertyFilter(RimGeoMechPropertyFilterCollection* propertyFilterCollection) +{ + RimGeoMechPropertyFilter* propertyFilter = createPropertyFilter(propertyFilterCollection); + CVF_ASSERT(propertyFilter); + + propertyFilterCollection->propertyFilters.push_back(propertyFilter); + propertyFilterCollection->reservoirView()->scheduleGeometryRegen(PROPERTY_FILTERED); + propertyFilterCollection->reservoirView()->scheduleCreateDisplayModelAndRedraw(); + + propertyFilterCollection->updateConnectedEditors(); + RiuMainWindow::instance()->setCurrentObjectInTreeView(propertyFilter); + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicGeoMechPropertyFilterFeatureImpl::insertPropertyFilter(RimGeoMechPropertyFilterCollection* propertyFilterCollection, size_t index) +{ + RimGeoMechPropertyFilter* propertyFilter = createPropertyFilter(propertyFilterCollection); + CVF_ASSERT(propertyFilter); + + propertyFilterCollection->propertyFilters.insertAt(static_cast(index), propertyFilter); + propertyFilterCollection->reservoirView()->scheduleGeometryRegen(PROPERTY_FILTERED); + propertyFilterCollection->reservoirView()->scheduleCreateDisplayModelAndRedraw(); + + propertyFilterCollection->updateConnectedEditors(); + RiuMainWindow::instance()->setCurrentObjectInTreeView(propertyFilter); + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicGeoMechPropertyFilterFeatureImpl::isPropertyFilterCommandAvailable(caf::PdmObjectHandle* object) +{ + // Reuse code from EclipseProperty filter, as the function is only dependent on RimView + return RicEclipsePropertyFilterFeatureImpl::isPropertyFilterCommandAvailable(object); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimGeoMechPropertyFilter* RicGeoMechPropertyFilterFeatureImpl::createPropertyFilter(RimGeoMechPropertyFilterCollection* propertyFilterCollection) +{ + CVF_ASSERT(propertyFilterCollection); + + RimGeoMechPropertyFilter* propertyFilter = new RimGeoMechPropertyFilter(); + propertyFilter->setParentContainer(propertyFilterCollection); + + setDefaults(propertyFilter); + + return propertyFilter; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicGeoMechPropertyFilterFeatureImpl::setDefaults(RimGeoMechPropertyFilter* propertyFilter) +{ + CVF_ASSERT(propertyFilter); + + RimGeoMechPropertyFilterCollection* propertyFilterCollection = propertyFilter->parentContainer(); + CVF_ASSERT(propertyFilterCollection); + + RimGeoMechView* reservoirView = propertyFilterCollection->reservoirView(); + CVF_ASSERT(reservoirView); + + propertyFilter->resultDefinition->setGeoMechCase(reservoirView->geoMechCase()); + propertyFilter->resultDefinition->setResultAddress(reservoirView->cellResult()->resultAddress()); + propertyFilter->resultDefinition->loadResult(); + propertyFilter->setToDefaultValues(); + propertyFilter->updateFilterName(); +} diff --git a/ApplicationCode/Commands/RicGeoMechPropertyFilterFeatureImpl.h b/ApplicationCode/Commands/RicGeoMechPropertyFilterFeatureImpl.h new file mode 100644 index 0000000000..88ba073ad0 --- /dev/null +++ b/ApplicationCode/Commands/RicGeoMechPropertyFilterFeatureImpl.h @@ -0,0 +1,50 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include +#include + +class RimGeoMechPropertyFilter; +class RimGeoMechPropertyFilterCollection; + +namespace caf +{ + class PdmObjectHandle; +} + +//================================================================================================== +/// +//================================================================================================== +class RicGeoMechPropertyFilterFeatureImpl +{ +public: + static std::vector selectedPropertyFilters(); + static std::vector selectedPropertyFilterCollections(); + + static void addPropertyFilter(RimGeoMechPropertyFilterCollection* propertyFilterCollection); + static void insertPropertyFilter(RimGeoMechPropertyFilterCollection* propertyFilterCollection, size_t index); + + static bool isPropertyFilterCommandAvailable(caf::PdmObjectHandle* object); + +private: + static RimGeoMechPropertyFilter* createPropertyFilter(RimGeoMechPropertyFilterCollection* propertyFilterCollection); + static void setDefaults(RimGeoMechPropertyFilter* propertyFilter); +}; diff --git a/ApplicationCode/Commands/RicGeoMechPropertyFilterInsertExec.cpp b/ApplicationCode/Commands/RicGeoMechPropertyFilterInsertExec.cpp new file mode 100644 index 0000000000..3058d31aa0 --- /dev/null +++ b/ApplicationCode/Commands/RicGeoMechPropertyFilterInsertExec.cpp @@ -0,0 +1,76 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicGeoMechPropertyFilterInsertExec.h" + + +#include "RicGeoMechPropertyFilterFeatureImpl.h" + +#include "RimGeoMechPropertyFilter.h" +#include "RimGeoMechPropertyFilterCollection.h" + +#include "cvfAssert.h" + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicGeoMechPropertyFilterInsertExec::RicGeoMechPropertyFilterInsertExec(RimGeoMechPropertyFilter* propertyFilter) + : CmdExecuteCommand(NULL) +{ + CVF_ASSERT(propertyFilter); + m_propertyFilter = propertyFilter; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicGeoMechPropertyFilterInsertExec::~RicGeoMechPropertyFilterInsertExec() +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RicGeoMechPropertyFilterInsertExec::name() +{ + return "Insert Property Filter"; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicGeoMechPropertyFilterInsertExec::redo() +{ + RimGeoMechPropertyFilterCollection* propertyFilterCollection = m_propertyFilter->parentContainer(); + CVF_ASSERT(propertyFilterCollection); + + size_t index = propertyFilterCollection->propertyFilters.index(m_propertyFilter); + CVF_ASSERT(index < propertyFilterCollection->propertyFilters.size()); + + RicGeoMechPropertyFilterFeatureImpl::insertPropertyFilter(propertyFilterCollection, index); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicGeoMechPropertyFilterInsertExec::undo() +{ + // TODO + CVF_ASSERT(0); +} diff --git a/ApplicationCode/Commands/RicGeoMechPropertyFilterInsertExec.h b/ApplicationCode/Commands/RicGeoMechPropertyFilterInsertExec.h new file mode 100644 index 0000000000..4127c1cf03 --- /dev/null +++ b/ApplicationCode/Commands/RicGeoMechPropertyFilterInsertExec.h @@ -0,0 +1,43 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdExecuteCommand.h" +#include "cafPdmPointer.h" + +class RimGeoMechPropertyFilter; + +//================================================================================================== +/// +//================================================================================================== +class RicGeoMechPropertyFilterInsertExec : public caf::CmdExecuteCommand +{ +public: + RicGeoMechPropertyFilterInsertExec(RimGeoMechPropertyFilter* propertyFilter); + virtual ~RicGeoMechPropertyFilterInsertExec(); + + virtual QString name(); + virtual void redo(); + virtual void undo(); + +private: + caf::PdmPointer m_propertyFilter; +}; + diff --git a/ApplicationCode/Commands/RicGeoMechPropertyFilterInsertFeature.cpp b/ApplicationCode/Commands/RicGeoMechPropertyFilterInsertFeature.cpp new file mode 100644 index 0000000000..030d10b7ff --- /dev/null +++ b/ApplicationCode/Commands/RicGeoMechPropertyFilterInsertFeature.cpp @@ -0,0 +1,68 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicGeoMechPropertyFilterInsertFeature.h" + +#include "RicGeoMechPropertyFilterInsertExec.h" +#include "RicGeoMechPropertyFilterFeatureImpl.h" + +#include "RimGeoMechPropertyFilter.h" + +#include "cafCmdExecCommandManager.h" + +#include + +#include + +CAF_CMD_SOURCE_INIT(RicGeoMechPropertyFilterInsertFeature, "RicGeoMechPropertyFilterInsertFeature"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicGeoMechPropertyFilterInsertFeature::isCommandEnabled() +{ + std::vector propertyFilters = RicGeoMechPropertyFilterFeatureImpl::selectedPropertyFilters(); + if (propertyFilters.size() == 1) + { + return RicGeoMechPropertyFilterFeatureImpl::isPropertyFilterCommandAvailable(propertyFilters[0]); + } + + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicGeoMechPropertyFilterInsertFeature::onActionTriggered(bool isChecked) +{ + std::vector propertyFilters = RicGeoMechPropertyFilterFeatureImpl::selectedPropertyFilters(); + if (propertyFilters.size() == 1) + { + RicGeoMechPropertyFilterInsertExec* filterExec = new RicGeoMechPropertyFilterInsertExec(propertyFilters[0]); + caf::CmdExecCommandManager::instance()->processExecuteCommand(filterExec); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicGeoMechPropertyFilterInsertFeature::setupActionLook(QAction* actionToSetup) +{ + actionToSetup->setText("Insert Property Filter"); +} diff --git a/ApplicationCode/Commands/RicGeoMechPropertyFilterInsertFeature.h b/ApplicationCode/Commands/RicGeoMechPropertyFilterInsertFeature.h new file mode 100644 index 0000000000..fa4730b9cc --- /dev/null +++ b/ApplicationCode/Commands/RicGeoMechPropertyFilterInsertFeature.h @@ -0,0 +1,39 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdFeature.h" + + +//================================================================================================== +/// +//================================================================================================== +class RicGeoMechPropertyFilterInsertFeature : public caf::CmdFeature +{ + CAF_CMD_HEADER_INIT; + +protected: + // Overrides + virtual bool isCommandEnabled(); + virtual void onActionTriggered( bool isChecked ); + virtual void setupActionLook( QAction* actionToSetup ); +}; + + diff --git a/ApplicationCode/Commands/RicGeoMechPropertyFilterNewExec.cpp b/ApplicationCode/Commands/RicGeoMechPropertyFilterNewExec.cpp new file mode 100644 index 0000000000..e63ef16b06 --- /dev/null +++ b/ApplicationCode/Commands/RicGeoMechPropertyFilterNewExec.cpp @@ -0,0 +1,69 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicGeoMechPropertyFilterNewExec.h" + +#include "RicGeoMechPropertyFilterFeatureImpl.h" + +#include "RimGeoMechPropertyFilter.h" +#include "RimGeoMechPropertyFilterCollection.h" + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicGeoMechPropertyFilterNewExec::RicGeoMechPropertyFilterNewExec(RimGeoMechPropertyFilterCollection* propertyFilterCollection) + : CmdExecuteCommand(NULL) +{ + assert(propertyFilterCollection); + m_propertyFilterCollection = propertyFilterCollection; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicGeoMechPropertyFilterNewExec::~RicGeoMechPropertyFilterNewExec() +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RicGeoMechPropertyFilterNewExec::name() +{ + return "New Property Filter"; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicGeoMechPropertyFilterNewExec::redo() +{ + RicGeoMechPropertyFilterFeatureImpl::addPropertyFilter(m_propertyFilterCollection); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicGeoMechPropertyFilterNewExec::undo() +{ + m_propertyFilterCollection->propertyFilters.erase(m_propertyFilterCollection->propertyFilters.size() - 1); + + m_propertyFilterCollection->updateConnectedEditors(); +} diff --git a/ApplicationCode/Commands/RicGeoMechPropertyFilterNewExec.h b/ApplicationCode/Commands/RicGeoMechPropertyFilterNewExec.h new file mode 100644 index 0000000000..da2cebfd95 --- /dev/null +++ b/ApplicationCode/Commands/RicGeoMechPropertyFilterNewExec.h @@ -0,0 +1,44 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdExecuteCommand.h" +#include "cafPdmPointer.h" + +class RimGeoMechPropertyFilterCollection; + +//================================================================================================== +/// +//================================================================================================== +class RicGeoMechPropertyFilterNewExec : public caf::CmdExecuteCommand +{ +public: + RicGeoMechPropertyFilterNewExec(RimGeoMechPropertyFilterCollection* propertyFilterCollection); + virtual ~RicGeoMechPropertyFilterNewExec(); + + virtual QString name(); + virtual void redo(); + virtual void undo(); + +private: + caf::PdmPointer m_propertyFilterCollection; +}; + + diff --git a/ApplicationCode/Commands/RicGeoMechPropertyFilterNewFeature.cpp b/ApplicationCode/Commands/RicGeoMechPropertyFilterNewFeature.cpp new file mode 100644 index 0000000000..e46b3e34e8 --- /dev/null +++ b/ApplicationCode/Commands/RicGeoMechPropertyFilterNewFeature.cpp @@ -0,0 +1,68 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicGeoMechPropertyFilterNewFeature.h" + +#include "RicGeoMechPropertyFilterNewExec.h" +#include "RicGeoMechPropertyFilterFeatureImpl.h" + +#include "RimGeoMechPropertyFilter.h" +#include "RimGeoMechPropertyFilterCollection.h" + +#include "cafCmdExecCommandManager.h" + +#include + +CAF_CMD_SOURCE_INIT(RicGeoMechPropertyFilterNewFeature, "RicGeoMechPropertyFilterNewFeature"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicGeoMechPropertyFilterNewFeature::isCommandEnabled() +{ + std::vector filterCollections = RicGeoMechPropertyFilterFeatureImpl::selectedPropertyFilterCollections(); + if (filterCollections.size() == 1) + { + return RicGeoMechPropertyFilterFeatureImpl::isPropertyFilterCommandAvailable(filterCollections[0]); + } + + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicGeoMechPropertyFilterNewFeature::onActionTriggered(bool isChecked) +{ + std::vector filterCollections = RicGeoMechPropertyFilterFeatureImpl::selectedPropertyFilterCollections(); + if (filterCollections.size() == 1) + { + RicGeoMechPropertyFilterNewExec* filterExec = new RicGeoMechPropertyFilterNewExec(filterCollections[0]); + caf::CmdExecCommandManager::instance()->processExecuteCommand(filterExec); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicGeoMechPropertyFilterNewFeature::setupActionLook(QAction* actionToSetup) +{ + actionToSetup->setIcon(QIcon(":/CellFilter_Values.png")); + actionToSetup->setText("New Property Filter"); +} diff --git a/ApplicationCode/Commands/RicGeoMechPropertyFilterNewFeature.h b/ApplicationCode/Commands/RicGeoMechPropertyFilterNewFeature.h new file mode 100644 index 0000000000..26114b98ec --- /dev/null +++ b/ApplicationCode/Commands/RicGeoMechPropertyFilterNewFeature.h @@ -0,0 +1,39 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdFeature.h" + + +//================================================================================================== +/// +//================================================================================================== +class RicGeoMechPropertyFilterNewFeature : public caf::CmdFeature +{ + CAF_CMD_HEADER_INIT; + +protected: + // Overrides + virtual bool isCommandEnabled(); + virtual void onActionTriggered( bool isChecked ); + virtual void setupActionLook( QAction* actionToSetup ); +}; + + diff --git a/ApplicationCode/Commands/RicImportEclipseCaseFeature.cpp b/ApplicationCode/Commands/RicImportEclipseCaseFeature.cpp new file mode 100644 index 0000000000..3d38aa71b6 --- /dev/null +++ b/ApplicationCode/Commands/RicImportEclipseCaseFeature.cpp @@ -0,0 +1,75 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicImportEclipseCaseFeature.h" + +#include "RimEclipseCaseCollection.h" +#include "RiaApplication.h" +#include "RiuMainWindow.h" + +#include "cafSelectionManager.h" + +#include +#include + +CAF_CMD_SOURCE_INIT(RicImportEclipseCaseFeature, "RicImportEclipseCaseFeature"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicImportEclipseCaseFeature::isCommandEnabled() +{ + return true; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicImportEclipseCaseFeature::onActionTriggered(bool isChecked) +{ + RiaApplication* app = RiaApplication::instance(); + + QString defaultDir = app->defaultFileDialogDirectory("BINARY_GRID"); + QStringList fileNames = QFileDialog::getOpenFileNames(RiuMainWindow::instance(), "Import Eclipse File", defaultDir, "Eclipse Grid Files (*.GRID *.EGRID)"); + if (fileNames.size()) defaultDir = QFileInfo(fileNames.last()).absolutePath(); + app->setDefaultFileDialogDirectory("BINARY_GRID", defaultDir); + + int i; + for (i = 0; i < fileNames.size(); i++) + { + QString fileName = fileNames[i]; + + if (!fileNames.isEmpty()) + { + if (app->openEclipseCaseFromFile(fileName)) + { + RiuMainWindow::instance()->addRecentFiles(fileName); + } + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicImportEclipseCaseFeature::setupActionLook(QAction* actionToSetup) +{ + actionToSetup->setIcon(QIcon(":/Case48x48.png")); + actionToSetup->setText("Import Eclipse Case"); +} diff --git a/ApplicationCode/Commands/RicImportEclipseCaseFeature.h b/ApplicationCode/Commands/RicImportEclipseCaseFeature.h new file mode 100644 index 0000000000..54100a7227 --- /dev/null +++ b/ApplicationCode/Commands/RicImportEclipseCaseFeature.h @@ -0,0 +1,40 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdFeature.h" + +#include + +//================================================================================================== +/// +//================================================================================================== +class RicImportEclipseCaseFeature : public caf::CmdFeature +{ + CAF_CMD_HEADER_INIT; + +protected: + // Overrides + virtual bool isCommandEnabled(); + virtual void onActionTriggered( bool isChecked ); + virtual void setupActionLook( QAction* actionToSetup ); +}; + + diff --git a/ApplicationCode/Commands/RicImportInputEclipseCaseFeature.cpp b/ApplicationCode/Commands/RicImportInputEclipseCaseFeature.cpp new file mode 100644 index 0000000000..7b5a4ff9c2 --- /dev/null +++ b/ApplicationCode/Commands/RicImportInputEclipseCaseFeature.cpp @@ -0,0 +1,66 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicImportInputEclipseCaseFeature.h" + +#include "RimEclipseCaseCollection.h" +#include "RiaApplication.h" +#include "RiuMainWindow.h" + +#include "cafSelectionManager.h" + +#include +#include + +CAF_CMD_SOURCE_INIT(RicImportInputEclipseCaseFeature, "RicImportInputEclipseCaseFeature"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicImportInputEclipseCaseFeature::isCommandEnabled() +{ + return true; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicImportInputEclipseCaseFeature::onActionTriggered(bool isChecked) +{ + RiaApplication* app = RiaApplication::instance(); + QString defaultDir = app->defaultFileDialogDirectory("INPUT_FILES"); + QStringList fileNames = QFileDialog::getOpenFileNames(RiuMainWindow::instance(), "Import Eclipse Input Files", defaultDir, "Eclipse Input Files and Input Properties (*.GRDECL *)"); + + if (fileNames.isEmpty()) return; + + // Remember the path to next time + app->setDefaultFileDialogDirectory("INPUT_FILES", QFileInfo(fileNames.last()).absolutePath()); + + app->openInputEclipseCaseFromFileNames(fileNames); + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicImportInputEclipseCaseFeature::setupActionLook(QAction* actionToSetup) +{ + actionToSetup->setIcon(QIcon(":/EclipseInput48x48.png")); + actionToSetup->setText("Import Input Eclipse Case"); +} diff --git a/ApplicationCode/Commands/RicImportInputEclipseCaseFeature.h b/ApplicationCode/Commands/RicImportInputEclipseCaseFeature.h new file mode 100644 index 0000000000..dcf3d8b27b --- /dev/null +++ b/ApplicationCode/Commands/RicImportInputEclipseCaseFeature.h @@ -0,0 +1,40 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdFeature.h" + +#include + +//================================================================================================== +/// +//================================================================================================== +class RicImportInputEclipseCaseFeature : public caf::CmdFeature +{ + CAF_CMD_HEADER_INIT; + +protected: + // Overrides + virtual bool isCommandEnabled(); + virtual void onActionTriggered( bool isChecked ); + virtual void setupActionLook( QAction* actionToSetup ); +}; + + diff --git a/ApplicationCode/Commands/RicLaunchUnitTestsFeature.cpp b/ApplicationCode/Commands/RicLaunchUnitTestsFeature.cpp new file mode 100644 index 0000000000..1a3079390b --- /dev/null +++ b/ApplicationCode/Commands/RicLaunchUnitTestsFeature.cpp @@ -0,0 +1,53 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicLaunchUnitTestsFeature.h" + +#include "RiaApplication.h" + + +#include + +CAF_CMD_SOURCE_INIT(RicLaunchUnitTestsFeature, "RicLaunchUnitTestsFeature"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicLaunchUnitTestsFeature::isCommandEnabled() +{ + return true; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicLaunchUnitTestsFeature::onActionTriggered(bool isChecked) +{ + RiaApplication::instance()->launchUnitTestsWithConsole(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicLaunchUnitTestsFeature::setupActionLook(QAction* actionToSetup) +{ + actionToSetup->setText("Launch Unit Tests"); +} + + diff --git a/ApplicationCode/Commands/RicLaunchUnitTestsFeature.h b/ApplicationCode/Commands/RicLaunchUnitTestsFeature.h new file mode 100644 index 0000000000..0c411298e9 --- /dev/null +++ b/ApplicationCode/Commands/RicLaunchUnitTestsFeature.h @@ -0,0 +1,38 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdFeature.h" + +//================================================================================================== +/// +//================================================================================================== +class RicLaunchUnitTestsFeature : public caf::CmdFeature +{ + CAF_CMD_HEADER_INIT; + +protected: + // Overrides + virtual bool isCommandEnabled(); + virtual void onActionTriggered( bool isChecked ); + virtual void setupActionLook( QAction* actionToSetup ); +}; + + diff --git a/ApplicationCode/Commands/RicNewStatisticsCaseFeature.cpp b/ApplicationCode/Commands/RicNewStatisticsCaseFeature.cpp new file mode 100644 index 0000000000..abd3d73b37 --- /dev/null +++ b/ApplicationCode/Commands/RicNewStatisticsCaseFeature.cpp @@ -0,0 +1,128 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicNewStatisticsCaseFeature.h" + +#include "RimEclipseStatisticsCase.h" +#include "RimEclipseStatisticsCaseCollection.h" +#include "RimIdenticalGridCaseGroup.h" +#include "RimCaseCollection.h" +#include "RimProject.h" + +#include "RiaApplication.h" +#include "RiuMainWindow.h" + +#include "cafSelectionManager.h" +#include "cafPdmUiTreeView.h" + +#include + +CAF_CMD_SOURCE_INIT(RicNewStatisticsCaseFeature, "RicNewStatisticsCaseFeature"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicNewStatisticsCaseFeature::isCommandEnabled() +{ + return selectedValidUIItem() != NULL; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicNewStatisticsCaseFeature::onActionTriggered(bool isChecked) +{ + caf::PdmUiItem* uiItem = selectedValidUIItem(); + if (uiItem) + { + RimEclipseStatisticsCase* newCase = addStatisticalCalculation(uiItem); + if (newCase) + { + RiuMainWindow::instance()->projectTreeView()->selectAsCurrentItem(newCase); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicNewStatisticsCaseFeature::setupActionLook(QAction* actionToSetup) +{ + actionToSetup->setText("New Statistics Case"); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +caf::PdmUiItem* RicNewStatisticsCaseFeature::selectedValidUIItem() +{ + std::vector statisticsCaseCollections; + caf::SelectionManager::instance()->objectsByType(&statisticsCaseCollections); + + if (statisticsCaseCollections.size() > 0) + { + return statisticsCaseCollections[0]; + } + + std::vector caseCollections; + caf::SelectionManager::instance()->objectsByType(&caseCollections); + + if (caseCollections.size() > 0) + { + if (RimIdenticalGridCaseGroup::isStatisticsCaseCollection(caseCollections[0])) + { + return caseCollections[0]; + } + } + + return NULL; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimEclipseStatisticsCase* RicNewStatisticsCaseFeature::addStatisticalCalculation(caf::PdmUiItem* uiItem) +{ + RimIdenticalGridCaseGroup* caseGroup = NULL; + + if (dynamic_cast(uiItem)) + { + RimEclipseStatisticsCase* currentObject = dynamic_cast(uiItem); + caseGroup = currentObject->parentStatisticsCaseCollection()->parentCaseGroup(); + } + else if (dynamic_cast(uiItem)) + { + RimCaseCollection* statColl = dynamic_cast(uiItem); + caseGroup = statColl->parentCaseGroup(); + } + + if (caseGroup) + { + RimProject* proj = RiaApplication::instance()->project(); + RimEclipseStatisticsCase* createdObject = caseGroup->createAndAppendStatisticsCase(); + proj->assignCaseIdToCase(createdObject); + + caseGroup->updateConnectedEditors(); + return createdObject; + } + else + { + return NULL; + } +} diff --git a/ApplicationCode/Commands/RicNewStatisticsCaseFeature.h b/ApplicationCode/Commands/RicNewStatisticsCaseFeature.h new file mode 100644 index 0000000000..61ddb9baae --- /dev/null +++ b/ApplicationCode/Commands/RicNewStatisticsCaseFeature.h @@ -0,0 +1,49 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdFeature.h" + +#include + +class RimEclipseStatisticsCase; + +namespace caf +{ + class PdmUiItem; +} + +//================================================================================================== +/// +//================================================================================================== +class RicNewStatisticsCaseFeature : public caf::CmdFeature +{ + CAF_CMD_HEADER_INIT; + +protected: + // Overrides + virtual bool isCommandEnabled(); + virtual void onActionTriggered( bool isChecked ); + virtual void setupActionLook( QAction* actionToSetup ); + +private: + caf::PdmUiItem* selectedValidUIItem(); + RimEclipseStatisticsCase* addStatisticalCalculation(caf::PdmUiItem* uiItem); +}; diff --git a/ApplicationCode/Commands/RicNewViewFeature.cpp b/ApplicationCode/Commands/RicNewViewFeature.cpp new file mode 100644 index 0000000000..3543813dff --- /dev/null +++ b/ApplicationCode/Commands/RicNewViewFeature.cpp @@ -0,0 +1,170 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicNewViewFeature.h" + +#include "RimView.h" +#include "RimEclipseView.h" +#include "RimGeoMechView.h" +#include "RimEclipseCase.h" +#include "RimGeoMechCase.h" + +#include "RiuMainWindow.h" + +#include "cafSelectionManager.h" +#include "cafPdmUiTreeView.h" + +#include + +CAF_CMD_SOURCE_INIT(RicNewViewFeature, "RicNewViewFeature"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicNewViewFeature::isCommandEnabled() +{ + return selectedEclipseCase() != NULL + || selectedEclipseView() != NULL + || selectedGeoMechCase() != NULL + || selectedGeoMechView() != NULL; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicNewViewFeature::onActionTriggered(bool isChecked) +{ + RimView* newView = addReservoirView(); + + RiuMainWindow::instance()->projectTreeView()->setExpanded(newView, true); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicNewViewFeature::setupActionLook(QAction* actionToSetup) +{ + actionToSetup->setText("New View"); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimView* RicNewViewFeature::addReservoirView() +{ + // Establish type of selected object + RimEclipseCase* eclipseCase = selectedEclipseCase(); + RimGeoMechCase* geomCase = selectedGeoMechCase(); + RimGeoMechView* geoMechView = selectedGeoMechView(); + RimEclipseView* reservoirView = selectedEclipseView(); + + // Find case to insert into + if (geoMechView) geomCase = geoMechView->geoMechCase(); + if (reservoirView) eclipseCase = reservoirView->eclipseCase(); + + RimView* insertedView = NULL; + + if (eclipseCase) + { + insertedView = eclipseCase->createAndAddReservoirView(); + } + else if (geomCase) + { + insertedView = geomCase->createAndAddReservoirView(); + } + + // Must be run before buildViewItems, as wells are created in this function + insertedView->loadDataAndUpdate(); + + if (eclipseCase) + { + eclipseCase->updateConnectedEditors(); + } + + if (geomCase) + { + geomCase->updateConnectedEditors(); + } + + return insertedView; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimEclipseCase* RicNewViewFeature::selectedEclipseCase() const +{ + std::vector selection; + caf::SelectionManager::instance()->objectsByType(&selection); + + if (selection.size() > 0) + { + return selection[0]; + } + + return NULL; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimGeoMechCase* RicNewViewFeature::selectedGeoMechCase() const +{ + std::vector selection; + caf::SelectionManager::instance()->objectsByType(&selection); + + if (selection.size() > 0) + { + return selection[0]; + } + + return NULL; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimEclipseView* RicNewViewFeature::selectedEclipseView() const +{ + std::vector selection; + caf::SelectionManager::instance()->objectsByType(&selection); + + if (selection.size() > 0) + { + return selection[0]; + } + + return NULL; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimGeoMechView* RicNewViewFeature::selectedGeoMechView() const +{ + std::vector selection; + caf::SelectionManager::instance()->objectsByType(&selection); + + if (selection.size() > 0) + { + return selection[0]; + } + + return NULL; +} diff --git a/ApplicationCode/Commands/RicNewViewFeature.h b/ApplicationCode/Commands/RicNewViewFeature.h new file mode 100644 index 0000000000..1a678c260e --- /dev/null +++ b/ApplicationCode/Commands/RicNewViewFeature.h @@ -0,0 +1,50 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdFeature.h" + +class RimView; +class RimEclipseCase; +class RimEclipseView; +class RimGeoMechCase; +class RimGeoMechView; + +//================================================================================================== +/// +//================================================================================================== +class RicNewViewFeature : public caf::CmdFeature +{ + CAF_CMD_HEADER_INIT; + +protected: + // Overrides + virtual bool isCommandEnabled(); + virtual void onActionTriggered( bool isChecked ); + virtual void setupActionLook( QAction* actionToSetup ); + +private: + RimView* addReservoirView(); + + RimEclipseCase* selectedEclipseCase() const; + RimGeoMechCase* selectedGeoMechCase() const; + RimEclipseView* selectedEclipseView() const; + RimGeoMechView* selectedGeoMechView() const; +}; diff --git a/ApplicationCode/Commands/RicRangeFilterExecImpl.cpp b/ApplicationCode/Commands/RicRangeFilterExecImpl.cpp new file mode 100644 index 0000000000..2816ba408c --- /dev/null +++ b/ApplicationCode/Commands/RicRangeFilterExecImpl.cpp @@ -0,0 +1,109 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicRangeFilterExecImpl.h" + +#include "RimCellRangeFilter.h" +#include "RimCellRangeFilterCollection.h" + +#include "cvfAssert.h" + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicRangeFilterExecImpl::RicRangeFilterExecImpl(RimCellRangeFilterCollection* rangeFilterCollection, RimCellRangeFilter* rangeFilter) + : CmdExecuteCommand(NULL) +{ + CVF_ASSERT(rangeFilterCollection); + m_cellRangeFilterCollection = rangeFilterCollection; + + m_cellRangeFilter = rangeFilter; + + m_iSlice = false; + m_jSlice = false; + m_kSlice = false; + + m_iSliceStart = -1; + m_jSliceStart = -1; + m_kSliceStart = -1; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicRangeFilterExecImpl::~RicRangeFilterExecImpl() +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimCellRangeFilter* RicRangeFilterExecImpl::createRangeFilter() +{ + CVF_ASSERT(m_cellRangeFilterCollection); + + RimCellRangeFilter* rangeFilter = new RimCellRangeFilter(); + + size_t flterIndex = m_cellRangeFilterCollection->rangeFilters().size() + 1; + + rangeFilter->name = QString("New Filter (%1)").arg(flterIndex); + + if (m_iSlice) + { + rangeFilter->name = QString("Slice I (%1)").arg(flterIndex); + } + + if (m_jSlice) + { + rangeFilter->name = QString("Slice J (%1)").arg(flterIndex); + } + + if (m_kSlice) + { + rangeFilter->name = QString("Slice K (%1)").arg(flterIndex); + } + + return rangeFilter; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicRangeFilterExecImpl::applyCommandDataOnFilter(RimCellRangeFilter* rangeFilter) +{ + if (m_iSlice) + { + rangeFilter->cellCountI = 1; + } + + if (m_jSlice) + { + rangeFilter->cellCountJ = 1; + } + + if (m_kSlice) + { + rangeFilter->cellCountK = 1; + } + + if (m_iSliceStart > -1) rangeFilter->startIndexI = m_iSliceStart; + if (m_jSliceStart > -1) rangeFilter->startIndexJ = m_jSliceStart; + if (m_kSliceStart > -1) rangeFilter->startIndexK = m_kSliceStart; +} + diff --git a/ApplicationCode/Commands/RicRangeFilterExecImpl.h b/ApplicationCode/Commands/RicRangeFilterExecImpl.h new file mode 100644 index 0000000000..b7407922ab --- /dev/null +++ b/ApplicationCode/Commands/RicRangeFilterExecImpl.h @@ -0,0 +1,59 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdExecuteCommand.h" +#include "cafPdmPointer.h" + +class RimCellRangeFilter; +class RimCellRangeFilterCollection; + +//================================================================================================== +/// +//================================================================================================== +class RicRangeFilterExecImpl : public caf::CmdExecuteCommand +{ +public: + RicRangeFilterExecImpl(RimCellRangeFilterCollection* rangeFilterCollection, RimCellRangeFilter* rangeFilter = 0); + virtual ~RicRangeFilterExecImpl(); + + virtual QString name() = 0; + virtual void redo() = 0; + virtual void undo() = 0; + +public: + bool m_iSlice; + bool m_jSlice; + bool m_kSlice; + + int m_iSliceStart; + int m_jSliceStart; + int m_kSliceStart; + +protected: + RimCellRangeFilter* createRangeFilter(); + void applyCommandDataOnFilter(RimCellRangeFilter* filter); + +protected: + caf::PdmPointer m_cellRangeFilterCollection; + caf::PdmPointer m_cellRangeFilter; +}; + + diff --git a/ApplicationCode/Commands/RicRangeFilterFeatureImpl.cpp b/ApplicationCode/Commands/RicRangeFilterFeatureImpl.cpp new file mode 100644 index 0000000000..1a5cb04ed7 --- /dev/null +++ b/ApplicationCode/Commands/RicRangeFilterFeatureImpl.cpp @@ -0,0 +1,92 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicRangeFilterFeatureImpl.h" +#include "RicRangeFilterNewExec.h" + +#include "RimCellRangeFilter.h" +#include "RimCellRangeFilterCollection.h" + +#include "cafSelectionManager.h" + +#include +#include "RimView.h" +#include "RimViewController.h" + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicRangeFilterFeatureImpl::isRangeFilterCommandAvailable() +{ + RimCellRangeFilterCollection* rangeFilterCollection = findRangeFilterCollection(); + if (!rangeFilterCollection) return false; + + RimView* view; + rangeFilterCollection->firstAnchestorOrThisOfType(view); + if (view) + { + RimViewController* vc = view->viewController(); + if (!vc) return true; + return (!vc->isRangeFiltersControlled()); + } + + return true; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicRangeFilterNewExec* RicRangeFilterFeatureImpl::createRangeFilterExecCommand() +{ + RimCellRangeFilterCollection* rangeFilterCollection = findRangeFilterCollection(); + + RicRangeFilterNewExec* filterExec = new RicRangeFilterNewExec(rangeFilterCollection); + + return filterExec; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimCellRangeFilterCollection* RicRangeFilterFeatureImpl::findRangeFilterCollection() +{ + RimCellRangeFilterCollection* rangeFilterCollection = NULL; + + std::vector selectedRangeFilter; + caf::SelectionManager::instance()->objectsByType(&selectedRangeFilter); + + std::vector selectedRangeFilterCollection; + caf::SelectionManager::instance()->objectsByType(&selectedRangeFilterCollection); + + if (selectedRangeFilterCollection.size() == 1) + { + rangeFilterCollection = selectedRangeFilterCollection[0]; + } + else if (selectedRangeFilter.size() > 0) + { + selectedRangeFilter[0]->firstAnchestorOrThisOfType(rangeFilterCollection); + } + + assert(rangeFilterCollection); + + // TODO : When a menu is created in the 3D view, add code to find collection based on a RimView + // See RiuViewerCommands + + return rangeFilterCollection; +} diff --git a/ApplicationCode/Commands/RicRangeFilterFeatureImpl.h b/ApplicationCode/Commands/RicRangeFilterFeatureImpl.h new file mode 100644 index 0000000000..f2a93af7af --- /dev/null +++ b/ApplicationCode/Commands/RicRangeFilterFeatureImpl.h @@ -0,0 +1,38 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +class RicRangeFilterNewExec; +class RimCellRangeFilterCollection; + +//================================================================================================== +/// +//================================================================================================== +class RicRangeFilterFeatureImpl +{ +public: + static bool isRangeFilterCommandAvailable(); + static RicRangeFilterNewExec* createRangeFilterExecCommand(); + +public: + static RimCellRangeFilterCollection* findRangeFilterCollection(); +}; + + diff --git a/ApplicationCode/Commands/RicRangeFilterInsertExec.cpp b/ApplicationCode/Commands/RicRangeFilterInsertExec.cpp new file mode 100644 index 0000000000..67b89745e1 --- /dev/null +++ b/ApplicationCode/Commands/RicRangeFilterInsertExec.cpp @@ -0,0 +1,81 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicRangeFilterInsertExec.h" + +#include "RimCellRangeFilter.h" +#include "RimCellRangeFilterCollection.h" +#include "RimView.h" +#include "RiuMainWindow.h" + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicRangeFilterInsertExec::RicRangeFilterInsertExec(RimCellRangeFilterCollection* rangeFilterCollection, RimCellRangeFilter* rangeFilter) + : RicRangeFilterExecImpl(rangeFilterCollection, rangeFilter) +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicRangeFilterInsertExec::~RicRangeFilterInsertExec() +{ + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RicRangeFilterInsertExec::name() +{ + return "Create Range Filter"; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicRangeFilterInsertExec::redo() +{ + RimCellRangeFilter* rangeFilter = createRangeFilter(); + if (rangeFilter) + { + size_t index = m_cellRangeFilterCollection->rangeFilters.index(m_cellRangeFilter); + CVF_ASSERT(index < m_cellRangeFilterCollection->rangeFilters.size()); + + m_cellRangeFilterCollection->rangeFilters.insertAt(static_cast(index), rangeFilter); + + rangeFilter->setDefaultValues(); + applyCommandDataOnFilter(rangeFilter); + + m_cellRangeFilterCollection->updateDisplayModeNotifyManagedViews(NULL); + + m_cellRangeFilterCollection->updateConnectedEditors(); + + RiuMainWindow::instance()->setCurrentObjectInTreeView(rangeFilter); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicRangeFilterInsertExec::undo() +{ +} diff --git a/ApplicationCode/Commands/RicRangeFilterInsertExec.h b/ApplicationCode/Commands/RicRangeFilterInsertExec.h new file mode 100644 index 0000000000..db47dd8890 --- /dev/null +++ b/ApplicationCode/Commands/RicRangeFilterInsertExec.h @@ -0,0 +1,41 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "RicRangeFilterExecImpl.h" + +class RimCellRangeFilter; +class RimCellRangeFilterCollection; + +//================================================================================================== +/// +//================================================================================================== +class RicRangeFilterInsertExec : public RicRangeFilterExecImpl +{ +public: + RicRangeFilterInsertExec(RimCellRangeFilterCollection* rangeFilterCollection, RimCellRangeFilter* rangeFilter = 0); + virtual ~RicRangeFilterInsertExec(); + + virtual QString name(); + virtual void redo(); + virtual void undo(); +}; + + diff --git a/ApplicationCode/Commands/RicRangeFilterInsertFeature.cpp b/ApplicationCode/Commands/RicRangeFilterInsertFeature.cpp new file mode 100644 index 0000000000..e14fe1ff33 --- /dev/null +++ b/ApplicationCode/Commands/RicRangeFilterInsertFeature.cpp @@ -0,0 +1,74 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicRangeFilterInsertFeature.h" + +#include "RicRangeFilterInsertExec.h" +#include "RicRangeFilterFeatureImpl.h" + +#include "RimCellRangeFilter.h" + +#include "cafSelectionManager.h" + +#include "cafCmdFeatureManager.h" +#include "cafCmdExecCommandManager.h" + +#include + +CAF_CMD_SOURCE_INIT(RicRangeFilterInsertFeature, "RicRangeFilterInsertFeature"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicRangeFilterInsertFeature::isCommandEnabled() +{ + return RicRangeFilterFeatureImpl::isRangeFilterCommandAvailable(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicRangeFilterInsertFeature::onActionTriggered(bool isChecked) +{ + std::vector selection = selectedCellRangeFilters(); + RimCellRangeFilterCollection* rangeFilterCollection = RicRangeFilterFeatureImpl::findRangeFilterCollection(); + + RicRangeFilterInsertExec* filterExec = new RicRangeFilterInsertExec(rangeFilterCollection, selection[0]); + caf::CmdExecCommandManager::instance()->processExecuteCommand(filterExec); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicRangeFilterInsertFeature::setupActionLook(QAction* actionToSetup) +{ + actionToSetup->setText("Insert Range Filter"); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RicRangeFilterInsertFeature::selectedCellRangeFilters() +{ + std::vector selection; + caf::SelectionManager::instance()->objectsByType(&selection); + + return selection; +} + diff --git a/ApplicationCode/Commands/RicRangeFilterInsertFeature.h b/ApplicationCode/Commands/RicRangeFilterInsertFeature.h new file mode 100644 index 0000000000..9f47055d74 --- /dev/null +++ b/ApplicationCode/Commands/RicRangeFilterInsertFeature.h @@ -0,0 +1,45 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdFeature.h" + +#include + +class RimCellRangeFilter; + +//================================================================================================== +/// +//================================================================================================== +class RicRangeFilterInsertFeature : public caf::CmdFeature +{ + CAF_CMD_HEADER_INIT; + +protected: + // Overrides + virtual bool isCommandEnabled(); + virtual void onActionTriggered( bool isChecked ); + virtual void setupActionLook( QAction* actionToSetup ); + +private: + static std::vector selectedCellRangeFilters(); +}; + + diff --git a/ApplicationCode/Commands/RicRangeFilterNewExec.cpp b/ApplicationCode/Commands/RicRangeFilterNewExec.cpp new file mode 100644 index 0000000000..a5cd784b73 --- /dev/null +++ b/ApplicationCode/Commands/RicRangeFilterNewExec.cpp @@ -0,0 +1,91 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicRangeFilterNewExec.h" + +#include "RimCellRangeFilter.h" +#include "RimCellRangeFilterCollection.h" +#include "RimView.h" +#include "RiuMainWindow.h" + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicRangeFilterNewExec::RicRangeFilterNewExec(RimCellRangeFilterCollection* rangeFilterCollection, RimCellRangeFilter* rangeFilter) + : RicRangeFilterExecImpl(rangeFilterCollection, rangeFilter) +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicRangeFilterNewExec::~RicRangeFilterNewExec() +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RicRangeFilterNewExec::name() +{ + if (m_iSlice) + return "Create I Slice Filter"; + else if (m_jSlice) + return "Create J Slice Filter"; + else if (m_kSlice) + return "Create K Slice Filter"; + + return "Create Range Filter"; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicRangeFilterNewExec::redo() +{ + RimCellRangeFilter* rangeFilter = createRangeFilter(); + if (rangeFilter) + { + m_cellRangeFilterCollection->rangeFilters.push_back(rangeFilter); + + rangeFilter->setDefaultValues(); + applyCommandDataOnFilter(rangeFilter); + + m_cellRangeFilterCollection->updateDisplayModeNotifyManagedViews(NULL); + + m_cellRangeFilterCollection->updateConnectedEditors(); + + RiuMainWindow::instance()->setCurrentObjectInTreeView(rangeFilter); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicRangeFilterNewExec::undo() +{ + assert(m_cellRangeFilterCollection); + + m_cellRangeFilterCollection->rangeFilters.erase(m_cellRangeFilterCollection->rangeFilters.size() - 1); + + m_cellRangeFilterCollection->updateDisplayModeNotifyManagedViews(NULL); + + m_cellRangeFilterCollection->updateConnectedEditors(); +} diff --git a/ApplicationCode/Commands/RicRangeFilterNewExec.h b/ApplicationCode/Commands/RicRangeFilterNewExec.h new file mode 100644 index 0000000000..111fa81881 --- /dev/null +++ b/ApplicationCode/Commands/RicRangeFilterNewExec.h @@ -0,0 +1,38 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "RicRangeFilterExecImpl.h" + +//================================================================================================== +/// +//================================================================================================== +class RicRangeFilterNewExec : public RicRangeFilterExecImpl +{ +public: + RicRangeFilterNewExec(RimCellRangeFilterCollection* rangeFilterCollection, RimCellRangeFilter* rangeFilter = 0); + virtual ~RicRangeFilterNewExec(); + + virtual QString name(); + virtual void redo(); + virtual void undo(); +}; + + diff --git a/ApplicationCode/Commands/RicRangeFilterNewFeature.cpp b/ApplicationCode/Commands/RicRangeFilterNewFeature.cpp new file mode 100644 index 0000000000..bdec266fa8 --- /dev/null +++ b/ApplicationCode/Commands/RicRangeFilterNewFeature.cpp @@ -0,0 +1,62 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicRangeFilterNewFeature.h" + +#include "RicRangeFilterFeatureImpl.h" +#include "RicRangeFilterNewExec.h" + +#include "RimCellRangeFilter.h" +#include "RimCellRangeFilterCollection.h" + +#include "cafCmdFeatureManager.h" +#include "cafCmdExecCommandManager.h" + +#include + + +CAF_CMD_SOURCE_INIT(RicRangeFilterNewFeature, "RicRangeFilterNewFeature"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicRangeFilterNewFeature::isCommandEnabled() +{ + return RicRangeFilterFeatureImpl::isRangeFilterCommandAvailable(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicRangeFilterNewFeature::onActionTriggered(bool isChecked) +{ + RicRangeFilterNewExec* filterExec = RicRangeFilterFeatureImpl::createRangeFilterExecCommand(); + + caf::CmdExecCommandManager::instance()->processExecuteCommand(filterExec); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicRangeFilterNewFeature::setupActionLook(QAction* actionToSetup) +{ + actionToSetup->setIcon(QIcon(":/CellFilter_Range.png")); + actionToSetup->setText("New Range Filter"); +} + diff --git a/ApplicationCode/Commands/RicRangeFilterNewFeature.h b/ApplicationCode/Commands/RicRangeFilterNewFeature.h new file mode 100644 index 0000000000..e1fb158788 --- /dev/null +++ b/ApplicationCode/Commands/RicRangeFilterNewFeature.h @@ -0,0 +1,38 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// +#pragma once + +#include "cafCmdFeature.h" + + +//================================================================================================== +/// +//================================================================================================== +class RicRangeFilterNewFeature : public caf::CmdFeature +{ + CAF_CMD_HEADER_INIT; + +protected: + // Overrides + virtual bool isCommandEnabled(); + virtual void onActionTriggered( bool isChecked ); + virtual void setupActionLook( QAction* actionToSetup ); +}; + + diff --git a/ApplicationCode/Commands/RicRangeFilterNewSliceIFeature.cpp b/ApplicationCode/Commands/RicRangeFilterNewSliceIFeature.cpp new file mode 100644 index 0000000000..cf7ef24cb3 --- /dev/null +++ b/ApplicationCode/Commands/RicRangeFilterNewSliceIFeature.cpp @@ -0,0 +1,61 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicRangeFilterNewSliceIFeature.h" + +#include "RicRangeFilterNewExec.h" +#include "RicRangeFilterFeatureImpl.h" + +#include "RimCellRangeFilter.h" +#include "RimCellRangeFilterCollection.h" + +#include "cafCmdExecCommandManager.h" + +#include + + +CAF_CMD_SOURCE_INIT(RicRangeFilterNewSliceIFeature, "RicRangeFilterNewSliceIFeature"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicRangeFilterNewSliceIFeature::isCommandEnabled() +{ + return RicRangeFilterFeatureImpl::isRangeFilterCommandAvailable(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicRangeFilterNewSliceIFeature::onActionTriggered(bool isChecked) +{ + RicRangeFilterNewExec* filterExec = RicRangeFilterFeatureImpl::createRangeFilterExecCommand(); + filterExec->m_iSlice = true; + + caf::CmdExecCommandManager::instance()->processExecuteCommand(filterExec); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicRangeFilterNewSliceIFeature::setupActionLook(QAction* actionToSetup) +{ + actionToSetup->setText("New I-slice range filter"); +} + diff --git a/ApplicationCode/Commands/RicRangeFilterNewSliceIFeature.h b/ApplicationCode/Commands/RicRangeFilterNewSliceIFeature.h new file mode 100644 index 0000000000..3d74f5c4a6 --- /dev/null +++ b/ApplicationCode/Commands/RicRangeFilterNewSliceIFeature.h @@ -0,0 +1,39 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdFeature.h" + + +//================================================================================================== +/// +//================================================================================================== +class RicRangeFilterNewSliceIFeature : public caf::CmdFeature +{ + CAF_CMD_HEADER_INIT; + +protected: + // Overrides + virtual bool isCommandEnabled(); + virtual void onActionTriggered( bool isChecked ); + virtual void setupActionLook( QAction* actionToSetup ); +}; + + diff --git a/ApplicationCode/Commands/RicRangeFilterNewSliceJFeature.cpp b/ApplicationCode/Commands/RicRangeFilterNewSliceJFeature.cpp new file mode 100644 index 0000000000..1ceeb5748e --- /dev/null +++ b/ApplicationCode/Commands/RicRangeFilterNewSliceJFeature.cpp @@ -0,0 +1,60 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicRangeFilterNewSliceJFeature.h" + +#include "RicRangeFilterNewExec.h" +#include "RicRangeFilterFeatureImpl.h" + +#include "RimCellRangeFilter.h" +#include "RimCellRangeFilterCollection.h" + +#include "cafCmdExecCommandManager.h" + +#include + +CAF_CMD_SOURCE_INIT(RicRangeFilterNewSliceJFeature, "RicRangeFilterNewSliceJFeature"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicRangeFilterNewSliceJFeature::isCommandEnabled() +{ + return RicRangeFilterFeatureImpl::isRangeFilterCommandAvailable(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicRangeFilterNewSliceJFeature::onActionTriggered(bool isChecked) +{ + RicRangeFilterNewExec* filterExec = RicRangeFilterFeatureImpl::createRangeFilterExecCommand(); + filterExec->m_jSlice = true; + + caf::CmdExecCommandManager::instance()->processExecuteCommand(filterExec); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicRangeFilterNewSliceJFeature::setupActionLook(QAction* actionToSetup) +{ + actionToSetup->setText("New J-slice range filter"); +} + diff --git a/ApplicationCode/Commands/RicRangeFilterNewSliceJFeature.h b/ApplicationCode/Commands/RicRangeFilterNewSliceJFeature.h new file mode 100644 index 0000000000..38c3190a7d --- /dev/null +++ b/ApplicationCode/Commands/RicRangeFilterNewSliceJFeature.h @@ -0,0 +1,39 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdFeature.h" + + +//================================================================================================== +/// +//================================================================================================== +class RicRangeFilterNewSliceJFeature : public caf::CmdFeature +{ + CAF_CMD_HEADER_INIT; + +protected: + // Overrides + virtual bool isCommandEnabled(); + virtual void onActionTriggered( bool isChecked ); + virtual void setupActionLook( QAction* actionToSetup ); +}; + + diff --git a/ApplicationCode/Commands/RicRangeFilterNewSliceKFeature.cpp b/ApplicationCode/Commands/RicRangeFilterNewSliceKFeature.cpp new file mode 100644 index 0000000000..1cacf31df9 --- /dev/null +++ b/ApplicationCode/Commands/RicRangeFilterNewSliceKFeature.cpp @@ -0,0 +1,60 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicRangeFilterNewSliceKFeature.h" + +#include "RicRangeFilterFeatureImpl.h" +#include "RicRangeFilterNewExec.h" + +#include "RimCellRangeFilter.h" +#include "RimCellRangeFilterCollection.h" + +#include "cafCmdExecCommandManager.h" +#include "cafSelectionManager.h" + +#include + +CAF_CMD_SOURCE_INIT(RicRangeFilterNewSliceKFeature, "RicRangeFilterNewSliceKFeature"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicRangeFilterNewSliceKFeature::isCommandEnabled() +{ + return RicRangeFilterFeatureImpl::isRangeFilterCommandAvailable(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicRangeFilterNewSliceKFeature::onActionTriggered(bool isChecked) +{ + RicRangeFilterNewExec* filterExec = RicRangeFilterFeatureImpl::createRangeFilterExecCommand(); + filterExec->m_kSlice = true; + + caf::CmdExecCommandManager::instance()->processExecuteCommand(filterExec); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicRangeFilterNewSliceKFeature::setupActionLook(QAction* actionToSetup) +{ + actionToSetup->setText("New K-slice range filter"); +} diff --git a/ApplicationCode/Commands/RicRangeFilterNewSliceKFeature.h b/ApplicationCode/Commands/RicRangeFilterNewSliceKFeature.h new file mode 100644 index 0000000000..4bcbc28ec2 --- /dev/null +++ b/ApplicationCode/Commands/RicRangeFilterNewSliceKFeature.h @@ -0,0 +1,39 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdFeature.h" + + +//================================================================================================== +/// +//================================================================================================== +class RicRangeFilterNewSliceKFeature : public caf::CmdFeature +{ + CAF_CMD_HEADER_INIT; + +protected: + // Overrides + virtual bool isCommandEnabled(); + virtual void onActionTriggered( bool isChecked ); + virtual void setupActionLook( QAction* actionToSetup ); +}; + + diff --git a/ApplicationCode/Commands/RicSaveEclipseInputPropertyFeature.cpp b/ApplicationCode/Commands/RicSaveEclipseInputPropertyFeature.cpp new file mode 100644 index 0000000000..2fa7600775 --- /dev/null +++ b/ApplicationCode/Commands/RicSaveEclipseInputPropertyFeature.cpp @@ -0,0 +1,140 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicSaveEclipseInputPropertyFeature.h" + +#include "RimEclipseInputProperty.h" +#include "RimEclipseInputPropertyCollection.h" +#include "RimExportInputPropertySettings.h" +#include "RimEclipseInputCase.h" + +#include "RifEclipseInputFileTools.h" + +#include "RiaApplication.h" +#include "RiuMainWindow.h" + +#include "cafSelectionManager.h" +#include "cafPdmUiPropertyViewDialog.h" + +#include +#include +#include + +CAF_CMD_SOURCE_INIT(RicSaveEclipseInputPropertyFeature, "RicSaveEclipseInputPropertyFeature"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicSaveEclipseInputPropertyFeature::isCommandEnabled() +{ + return selectedInputProperty() != NULL; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicSaveEclipseInputPropertyFeature::onActionTriggered(bool isChecked) +{ + RimEclipseInputProperty* inputProperty = selectedInputProperty(); + if (!inputProperty) return; + + { + bool isResolved = false; + if (inputProperty->resolvedState == RimEclipseInputProperty::RESOLVED || inputProperty->resolvedState == RimEclipseInputProperty::RESOLVED_NOT_SAVED) + { + isResolved = true; + } + + if (!isResolved) + { + QMessageBox::warning(RiuMainWindow::instance(), "Export failure", "Property is not resolved, and then it is not possible to export the property."); + + return; + } + } + + RimExportInputSettings exportSettings; + exportSettings.eclipseKeyword = inputProperty->eclipseKeyword; + + // Find input reservoir for this property + RimEclipseInputCase* inputReservoir = NULL; + { + RimEclipseInputPropertyCollection* inputPropertyCollection = dynamic_cast(inputProperty->parentField()->ownerObject()); + if (!inputPropertyCollection) return; + + inputReservoir = dynamic_cast(inputPropertyCollection->parentField()->ownerObject()); + } + + if (!inputReservoir) return; + + { + QString projectFolder; + + RiaApplication* app = RiaApplication::instance(); + QString projectFileName = app->currentProjectFileName(); + if (!projectFileName.isEmpty()) + { + QFileInfo fi(projectFileName); + projectFolder = fi.absolutePath(); + } + else + { + projectFolder = inputReservoir->locationOnDisc(); + } + + QString outputFileName = projectFolder + "/" + inputProperty->eclipseKeyword; + + exportSettings.fileName = outputFileName; + } + + caf::PdmUiPropertyViewDialog propertyDialog(RiuMainWindow::instance(), &exportSettings, "Export Eclipse Property to Text File", ""); + if (propertyDialog.exec() == QDialog::Accepted) + { + bool isOk = RifEclipseInputFileTools::writePropertyToTextFile(exportSettings.fileName, inputReservoir->reservoirData(), 0, inputProperty->resultName, exportSettings.eclipseKeyword); + if (isOk) + { + inputProperty->fileName = exportSettings.fileName; + inputProperty->eclipseKeyword = exportSettings.eclipseKeyword; + inputProperty->resolvedState = RimEclipseInputProperty::RESOLVED; + + inputProperty->updateConnectedEditors(); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicSaveEclipseInputPropertyFeature::setupActionLook(QAction* actionToSetup) +{ + actionToSetup->setText("Save Property To File"); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimEclipseInputProperty* RicSaveEclipseInputPropertyFeature::selectedInputProperty() const +{ + std::vector selection; + caf::SelectionManager::instance()->objectsByType(&selection); + + return selection.size() > 0 ? selection[0] : NULL; +} + + diff --git a/ApplicationCode/Commands/RicSaveEclipseInputPropertyFeature.h b/ApplicationCode/Commands/RicSaveEclipseInputPropertyFeature.h new file mode 100644 index 0000000000..774d95f40c --- /dev/null +++ b/ApplicationCode/Commands/RicSaveEclipseInputPropertyFeature.h @@ -0,0 +1,43 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdFeature.h" + +class RimEclipseInputProperty; + +//================================================================================================== +/// +//================================================================================================== +class RicSaveEclipseInputPropertyFeature : public caf::CmdFeature +{ + CAF_CMD_HEADER_INIT; + +protected: + // Overrides + virtual bool isCommandEnabled(); + virtual void onActionTriggered( bool isChecked ); + virtual void setupActionLook( QAction* actionToSetup ); + +private: + RimEclipseInputProperty* selectedInputProperty() const; +}; + + diff --git a/ApplicationCode/Commands/RicSaveEclipseResultAsInputPropertyExec.cpp b/ApplicationCode/Commands/RicSaveEclipseResultAsInputPropertyExec.cpp new file mode 100644 index 0000000000..9e468d8097 --- /dev/null +++ b/ApplicationCode/Commands/RicSaveEclipseResultAsInputPropertyExec.cpp @@ -0,0 +1,120 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicSaveEclipseResultAsInputPropertyExec.h" + +#include "RimEclipseCellColors.h" +#include "RimBinaryExportSettings.h" +#include "RimEclipseView.h" +#include "RimEclipseCase.h" + +#include "RigCaseData.h" +#include "RigCaseCellResultsData.h" + +#include "RifEclipseInputFileTools.h" +#include "RifReaderInterface.h" + +#include "RiaApplication.h" +#include "RiuMainWindow.h" + +#include "cafPdmUiPropertyViewDialog.h" + +#include +#include + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicSaveEclipseResultAsInputPropertyExec::RicSaveEclipseResultAsInputPropertyExec(RimEclipseCellColors* cellColors) + : CmdExecuteCommand(NULL) +{ + CVF_ASSERT(cellColors); + m_cellColors = cellColors; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicSaveEclipseResultAsInputPropertyExec::~RicSaveEclipseResultAsInputPropertyExec() +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RicSaveEclipseResultAsInputPropertyExec::name() +{ + return "Save Property To File"; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicSaveEclipseResultAsInputPropertyExec::redo() +{ + CVF_ASSERT(m_cellColors); + + if (!m_cellColors->reservoirView()) return; + if (!m_cellColors->reservoirView()->eclipseCase()) return; + if (!m_cellColors->reservoirView()->eclipseCase()->reservoirData()) return; + + RimBinaryExportSettings exportSettings; + exportSettings.eclipseKeyword = m_cellColors->resultVariable(); + { + QString projectFolder; + + RiaApplication* app = RiaApplication::instance(); + QString projectFileName = app->currentProjectFileName(); + if (!projectFileName.isEmpty()) + { + QFileInfo fi(projectFileName); + projectFolder = fi.absolutePath(); + } + else + { + projectFolder = m_cellColors->reservoirView()->eclipseCase()->locationOnDisc(); + } + + QString outputFileName = projectFolder + "/" + m_cellColors->resultVariable(); + + exportSettings.fileName = outputFileName; + } + + caf::PdmUiPropertyViewDialog propertyDialog(RiuMainWindow::instance(), &exportSettings, "Export Binary Eclipse Data to Text File", ""); + if (propertyDialog.exec() == QDialog::Accepted) + { + size_t timeStep = m_cellColors->reservoirView()->currentTimeStep(); + RifReaderInterface::PorosityModelResultType porosityModel = RigCaseCellResultsData::convertFromProjectModelPorosityModel(m_cellColors->porosityModel()); + + bool isOk = RifEclipseInputFileTools::writeBinaryResultToTextFile(exportSettings.fileName, m_cellColors->reservoirView()->eclipseCase()->reservoirData(), porosityModel, timeStep, m_cellColors->resultVariable(), exportSettings.eclipseKeyword, exportSettings.undefinedValue); + if (!isOk) + { + QMessageBox::critical(NULL, "File export", "Failed to exported current result to " + exportSettings.fileName); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicSaveEclipseResultAsInputPropertyExec::undo() +{ + // TODO + CVF_ASSERT(0); +} diff --git a/ApplicationCode/Commands/RicSaveEclipseResultAsInputPropertyExec.h b/ApplicationCode/Commands/RicSaveEclipseResultAsInputPropertyExec.h new file mode 100644 index 0000000000..bfba44995b --- /dev/null +++ b/ApplicationCode/Commands/RicSaveEclipseResultAsInputPropertyExec.h @@ -0,0 +1,43 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdExecuteCommand.h" +#include "cafPdmPointer.h" + +class RimEclipseCellColors; + +//================================================================================================== +/// +//================================================================================================== +class RicSaveEclipseResultAsInputPropertyExec : public caf::CmdExecuteCommand +{ +public: + RicSaveEclipseResultAsInputPropertyExec(RimEclipseCellColors* cellColors); + virtual ~RicSaveEclipseResultAsInputPropertyExec(); + + virtual QString name(); + virtual void redo(); + virtual void undo(); + +private: + caf::PdmPointer m_cellColors; +}; + diff --git a/ApplicationCode/Commands/RicSaveEclipseResultAsInputPropertyFeature.cpp b/ApplicationCode/Commands/RicSaveEclipseResultAsInputPropertyFeature.cpp new file mode 100644 index 0000000000..683bd05075 --- /dev/null +++ b/ApplicationCode/Commands/RicSaveEclipseResultAsInputPropertyFeature.cpp @@ -0,0 +1,67 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicSaveEclipseResultAsInputPropertyFeature.h" + +#include "RicSaveEclipseResultAsInputPropertyExec.h" + +#include "RimEclipseCellColors.h" +#include "RimView.h" + +#include "cafSelectionManager.h" +#include "cafCmdExecCommandManager.h" + +#include + +CAF_CMD_SOURCE_INIT(RicSaveEclipseResultAsInputPropertyFeature, "RicSaveEclipseResultAsInputPropertyFeature"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicSaveEclipseResultAsInputPropertyFeature::isCommandEnabled() +{ + std::vector selection; + caf::SelectionManager::instance()->objectsByType(&selection); + + return selection.size() == 1; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicSaveEclipseResultAsInputPropertyFeature::onActionTriggered(bool isChecked) +{ + std::vector selection; + caf::SelectionManager::instance()->objectsByType(&selection); + if (selection.size() == 1) + { + RicSaveEclipseResultAsInputPropertyExec* cellResultSaveExec = new RicSaveEclipseResultAsInputPropertyExec(selection[0]); + caf::CmdExecCommandManager::instance()->processExecuteCommand(cellResultSaveExec); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicSaveEclipseResultAsInputPropertyFeature::setupActionLook(QAction* actionToSetup) +{ + actionToSetup->setText("Save Property To File"); +} + + diff --git a/ApplicationCode/Commands/RicSaveEclipseResultAsInputPropertyFeature.h b/ApplicationCode/Commands/RicSaveEclipseResultAsInputPropertyFeature.h new file mode 100644 index 0000000000..da7977fb04 --- /dev/null +++ b/ApplicationCode/Commands/RicSaveEclipseResultAsInputPropertyFeature.h @@ -0,0 +1,39 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdFeature.h" + + +//================================================================================================== +/// +//================================================================================================== +class RicSaveEclipseResultAsInputPropertyFeature : public caf::CmdFeature +{ + CAF_CMD_HEADER_INIT; + +protected: + // Overrides + virtual bool isCommandEnabled(); + virtual void onActionTriggered( bool isChecked ); + virtual void setupActionLook( QAction* actionToSetup ); +}; + + diff --git a/ApplicationCode/Commands/RicTileWindowsFeature.cpp b/ApplicationCode/Commands/RicTileWindowsFeature.cpp new file mode 100644 index 0000000000..8669acbf3b --- /dev/null +++ b/ApplicationCode/Commands/RicTileWindowsFeature.cpp @@ -0,0 +1,51 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicTileWindowsFeature.h" + +#include "RiuMainWindow.h" + +#include + +CAF_CMD_SOURCE_INIT(RicTileWindowsFeature, "RicTileWindowsFeature"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicTileWindowsFeature::isCommandEnabled() +{ + return RiuMainWindow::instance()->isAnyMdiSubWindowVisible(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicTileWindowsFeature::onActionTriggered(bool isChecked) +{ + RiuMainWindow::instance()->tileWindows(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicTileWindowsFeature::setupActionLook(QAction* actionToSetup) +{ + actionToSetup->setText("Tile Windows"); + actionToSetup->setIcon(QIcon(":/view-page-multi-24.png")); +} diff --git a/ApplicationCode/Commands/RicTileWindowsFeature.h b/ApplicationCode/Commands/RicTileWindowsFeature.h new file mode 100644 index 0000000000..add1e130db --- /dev/null +++ b/ApplicationCode/Commands/RicTileWindowsFeature.h @@ -0,0 +1,39 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdFeature.h" + + +//================================================================================================== +/// +//================================================================================================== +class RicTileWindowsFeature : public caf::CmdFeature +{ + CAF_CMD_HEADER_INIT; + +protected: + // Overrides + virtual bool isCommandEnabled(); + virtual void onActionTriggered( bool isChecked ); + virtual void setupActionLook( QAction* actionToSetup ); +}; + + diff --git a/ApplicationCode/Commands/ToggleCommands/CMakeLists_files.cmake b/ApplicationCode/Commands/ToggleCommands/CMakeLists_files.cmake new file mode 100644 index 0000000000..c2c336e893 --- /dev/null +++ b/ApplicationCode/Commands/ToggleCommands/CMakeLists_files.cmake @@ -0,0 +1,29 @@ + +# Use this workaround until we're on 2.8.3 on all platforms and can use CMAKE_CURRENT_LIST_DIR directly +if (${CMAKE_VERSION} VERSION_GREATER "2.8.2") + set(CEE_CURRENT_LIST_DIR ${CMAKE_CURRENT_LIST_DIR}/) +endif() + +set (SOURCE_GROUP_HEADER_FILES +${CEE_CURRENT_LIST_DIR}RicToggleItemsFeatureImpl.h +${CEE_CURRENT_LIST_DIR}RicToggleItemsOnFeature.h +${CEE_CURRENT_LIST_DIR}RicToggleItemsOffFeature.h +${CEE_CURRENT_LIST_DIR}RicToggleItemsFeature.h +) + +set (SOURCE_GROUP_SOURCE_FILES +${CEE_CURRENT_LIST_DIR}RicToggleItemsFeatureImpl.cpp +${CEE_CURRENT_LIST_DIR}RicToggleItemsOnFeature.cpp +${CEE_CURRENT_LIST_DIR}RicToggleItemsOffFeature.cpp +${CEE_CURRENT_LIST_DIR}RicToggleItemsFeature.cpp +) + +list(APPEND CODE_HEADER_FILES +${SOURCE_GROUP_HEADER_FILES} +) + +list(APPEND CODE_SOURCE_FILES +${SOURCE_GROUP_SOURCE_FILES} +) + +source_group( "CommandFeature\\ToggleItems" FILES ${SOURCE_GROUP_HEADER_FILES} ${SOURCE_GROUP_SOURCE_FILES} ${CEE_CURRENT_LIST_DIR}CMakeLists_files.cmake ) diff --git a/ApplicationCode/Commands/ToggleCommands/RicToggleItemsFeature.cpp b/ApplicationCode/Commands/ToggleCommands/RicToggleItemsFeature.cpp new file mode 100644 index 0000000000..75e5e7be2f --- /dev/null +++ b/ApplicationCode/Commands/ToggleCommands/RicToggleItemsFeature.cpp @@ -0,0 +1,60 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicToggleItemsFeature.h" + +#include "cafSelectionManager.h" + +#include "RicToggleItemsFeatureImpl.h" + +#include + +namespace caf +{ + +CAF_CMD_SOURCE_INIT(RicToggleItemsFeature, "RicToggleItemsFeature"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicToggleItemsFeature::isCommandEnabled() +{ + return RicToggleItemsFeatureImpl::isToggleCommandsAvailable(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicToggleItemsFeature::onActionTriggered(bool isChecked) +{ + RicToggleItemsFeatureImpl::setObjectToggleStateForSelection(RicToggleItemsFeatureImpl::TOGGLE_SUBITEMS); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicToggleItemsFeature::setupActionLook(QAction* actionToSetup) +{ + if (RicToggleItemsFeatureImpl::isToggleCommandsForSubItems()) + actionToSetup->setText("Toggle Sub Items"); + else + actionToSetup->setText("Toggle"); +} + +} // end namespace caf diff --git a/ApplicationCode/Commands/ToggleCommands/RicToggleItemsFeature.h b/ApplicationCode/Commands/ToggleCommands/RicToggleItemsFeature.h new file mode 100644 index 0000000000..8698dc3237 --- /dev/null +++ b/ApplicationCode/Commands/ToggleCommands/RicToggleItemsFeature.h @@ -0,0 +1,43 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdFeature.h" + +namespace caf +{ + +//================================================================================================== +/// +//================================================================================================== +class RicToggleItemsFeature : public CmdFeature +{ + CAF_CMD_HEADER_INIT; +protected: + + // Overrides + virtual bool isCommandEnabled(); + virtual void onActionTriggered( bool isChecked ); + virtual void setupActionLook( QAction* actionToSetup ); +}; + + + +} // end namespace caf diff --git a/ApplicationCode/Commands/ToggleCommands/RicToggleItemsFeatureImpl.cpp b/ApplicationCode/Commands/ToggleCommands/RicToggleItemsFeatureImpl.cpp new file mode 100644 index 0000000000..dfcb311007 --- /dev/null +++ b/ApplicationCode/Commands/ToggleCommands/RicToggleItemsFeatureImpl.cpp @@ -0,0 +1,150 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicToggleItemsFeatureImpl.h" +#include +#include "cafPdmUiObjectHandle.h" +#include "cafSelectionManager.h" +#include "cafPdmUiItem.h" +#include +#include "RiuMainWindow.h" +#include "cafPdmUiTreeView.h" +#include "cafPdmUiTreeOrdering.h" +#include "cafPdmUiFieldHandle.h" + +bool RicToggleItemsFeatureImpl::isToggleCommandsAvailable() +{ + std::vector selectedItems; + caf::SelectionManager::instance()->selectedItems(selectedItems); + + if (selectedItems.size() == 1) + { + QModelIndex modIndex = RiuMainWindow::instance()->projectTreeView()->findModelIndex(selectedItems[0]); + caf::PdmUiTreeOrdering* treeItem = static_cast(modIndex.internalPointer()); + if (!treeItem) return false; + + for (int cIdx = 0; cIdx < treeItem->childCount(); ++ cIdx) + { + caf::PdmUiTreeOrdering* child = treeItem->child(cIdx); + if (!child) continue; + if (!child->isRepresentingObject()) continue; + + caf::PdmObjectHandle* childObj = child->object(); + caf::PdmUiObjectHandle* uiObjectHandleChild = uiObj(childObj); + + if (uiObjectHandleChild && + uiObjectHandleChild->objectToggleField() && + !uiObjectHandleChild->objectToggleField()->uiCapability()->isUiReadOnly()) + { + return true; + } + } + } + else + { + for (size_t i = 0; i < selectedItems.size(); ++i) + { + caf::PdmUiObjectHandle* uiObjectHandle = dynamic_cast(selectedItems[i]); + + if (uiObjectHandle && uiObjectHandle->objectToggleField()) + { + return true; + } + } + } + + return false; +} + +bool RicToggleItemsFeatureImpl::isToggleCommandsForSubItems() +{ + std::vector selectedItems; + caf::SelectionManager::instance()->selectedItems(selectedItems); + if (isToggleCommandsAvailable() && selectedItems.size() == 1) + { + return true; + } + return false; +} + + +//-------------------------------------------------------------------------------------------------- +/// Set toggle state for list of model indices. +//-------------------------------------------------------------------------------------------------- +void RicToggleItemsFeatureImpl::setObjectToggleStateForSelection(SelectionToggleType state) +{ + std::vector selectedItems; + caf::SelectionManager::instance()->selectedItems(selectedItems); + if (state != TOGGLE && selectedItems.size() == 1) + { + // If only one item is selected, loop over its children, and toggle them instead of the + // selected item directly + + // We need to get the children through the tree view, because that is where the actually shown children is + + QModelIndex modIndex = RiuMainWindow::instance()->projectTreeView()->findModelIndex(selectedItems[0]); + caf::PdmUiTreeOrdering* treeItem = reinterpret_cast(modIndex.internalPointer()); + + for (int cIdx = 0; cIdx < treeItem->childCount(); ++ cIdx) + { + caf::PdmUiTreeOrdering* child = treeItem->child(cIdx); + if (!child) continue; + if (!child->isRepresentingObject()) continue; + + caf::PdmObjectHandle* childObj = child->object(); + caf::PdmUiObjectHandle* uiObjectHandleChild = uiObj(childObj); + + if (uiObjectHandleChild && uiObjectHandleChild->objectToggleField()) + { + caf::PdmField* field = dynamic_cast*>(uiObjectHandleChild->objectToggleField()); + + caf::PdmUiFieldHandle* uiFieldHandle = field->uiCapability(); + if (uiFieldHandle) + { + if (state == TOGGLE_ON) uiFieldHandle->setValueFromUi(true); + if (state == TOGGLE_OFF) uiFieldHandle->setValueFromUi(false); + if (state == TOGGLE_SUBITEMS) uiFieldHandle->setValueFromUi(!(field->v())); + } + } + } + } + else + { + for (size_t i = 0; i < selectedItems.size(); ++i) + { + caf::PdmUiObjectHandle* uiObjectHandle = dynamic_cast< caf::PdmUiObjectHandle*>(selectedItems[i]); + + if (uiObjectHandle && uiObjectHandle->objectToggleField()) + { + caf::PdmField* field = dynamic_cast* >(uiObjectHandle->objectToggleField()); + + caf::PdmUiFieldHandle* uiFieldHandle = field->uiCapability(); + if (uiFieldHandle) + { + if (state == TOGGLE_ON) uiFieldHandle->setValueFromUi(true); + if (state == TOGGLE_OFF) uiFieldHandle->setValueFromUi(false); + if (state == TOGGLE_SUBITEMS || state == TOGGLE) + { + uiFieldHandle->setValueFromUi(!(field->v())); + } + } + } + } + } +} diff --git a/ApplicationCode/Commands/ToggleCommands/RicToggleItemsFeatureImpl.h b/ApplicationCode/Commands/ToggleCommands/RicToggleItemsFeatureImpl.h new file mode 100644 index 0000000000..ed9688d64a --- /dev/null +++ b/ApplicationCode/Commands/ToggleCommands/RicToggleItemsFeatureImpl.h @@ -0,0 +1,42 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +//================================================================================================== +/// +//================================================================================================== +class RicToggleItemsFeatureImpl +{ +public: + enum SelectionToggleType + { + TOGGLE_ON, + TOGGLE_OFF, + TOGGLE_SUBITEMS, + TOGGLE, + TOGGLE_UNDEFINED + }; + + static bool isToggleCommandsAvailable(); + static bool isToggleCommandsForSubItems(); + static void setObjectToggleStateForSelection(SelectionToggleType state); + +}; + diff --git a/ApplicationCode/Commands/ToggleCommands/RicToggleItemsOffFeature.cpp b/ApplicationCode/Commands/ToggleCommands/RicToggleItemsOffFeature.cpp new file mode 100644 index 0000000000..0d61886c90 --- /dev/null +++ b/ApplicationCode/Commands/ToggleCommands/RicToggleItemsOffFeature.cpp @@ -0,0 +1,60 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicToggleItemsOffFeature.h" + +#include "cafSelectionManager.h" + +#include "RicToggleItemsFeatureImpl.h" + +#include + +namespace caf +{ + +CAF_CMD_SOURCE_INIT(RicToggleItemsOffFeature, "RicToggleItemsOffFeature"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicToggleItemsOffFeature::isCommandEnabled() +{ + return RicToggleItemsFeatureImpl::isToggleCommandsAvailable(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicToggleItemsOffFeature::onActionTriggered(bool isChecked) +{ + RicToggleItemsFeatureImpl::setObjectToggleStateForSelection(RicToggleItemsFeatureImpl::TOGGLE_OFF); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicToggleItemsOffFeature::setupActionLook(QAction* actionToSetup) +{ + if (RicToggleItemsFeatureImpl::isToggleCommandsForSubItems()) + actionToSetup->setText("Sub Items Off"); + else + actionToSetup->setText("Off"); +} + +} // end namespace caf diff --git a/ApplicationCode/Commands/ToggleCommands/RicToggleItemsOffFeature.h b/ApplicationCode/Commands/ToggleCommands/RicToggleItemsOffFeature.h new file mode 100644 index 0000000000..2ae4f4a0fe --- /dev/null +++ b/ApplicationCode/Commands/ToggleCommands/RicToggleItemsOffFeature.h @@ -0,0 +1,43 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdFeature.h" + +namespace caf +{ + +//================================================================================================== +/// +//================================================================================================== +class RicToggleItemsOffFeature : public CmdFeature +{ + CAF_CMD_HEADER_INIT; +protected: + + // Overrides + virtual bool isCommandEnabled(); + virtual void onActionTriggered( bool isChecked ); + virtual void setupActionLook( QAction* actionToSetup ); +}; + + + +} // end namespace caf diff --git a/ApplicationCode/Commands/ToggleCommands/RicToggleItemsOnFeature.cpp b/ApplicationCode/Commands/ToggleCommands/RicToggleItemsOnFeature.cpp new file mode 100644 index 0000000000..ecb20cb108 --- /dev/null +++ b/ApplicationCode/Commands/ToggleCommands/RicToggleItemsOnFeature.cpp @@ -0,0 +1,60 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicToggleItemsOnFeature.h" + +#include "cafSelectionManager.h" + +#include "RicToggleItemsFeatureImpl.h" + +#include + +namespace caf +{ + +CAF_CMD_SOURCE_INIT(RicToggleItemsOnFeature, "RicToggleItemsOnFeature"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicToggleItemsOnFeature::isCommandEnabled() +{ + return RicToggleItemsFeatureImpl::isToggleCommandsAvailable(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicToggleItemsOnFeature::onActionTriggered(bool isChecked) +{ + RicToggleItemsFeatureImpl::setObjectToggleStateForSelection(RicToggleItemsFeatureImpl::TOGGLE_ON); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicToggleItemsOnFeature::setupActionLook(QAction* actionToSetup) +{ + if (RicToggleItemsFeatureImpl::isToggleCommandsForSubItems()) + actionToSetup->setText("Sub Items On"); + else + actionToSetup->setText("On"); +} + +} // end namespace caf diff --git a/ApplicationCode/Commands/ToggleCommands/RicToggleItemsOnFeature.h b/ApplicationCode/Commands/ToggleCommands/RicToggleItemsOnFeature.h new file mode 100644 index 0000000000..e92b543e26 --- /dev/null +++ b/ApplicationCode/Commands/ToggleCommands/RicToggleItemsOnFeature.h @@ -0,0 +1,43 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdFeature.h" + +namespace caf +{ + +//================================================================================================== +/// +//================================================================================================== +class RicToggleItemsOnFeature : public CmdFeature +{ + CAF_CMD_HEADER_INIT; +protected: + + // Overrides + virtual bool isCommandEnabled(); + virtual void onActionTriggered( bool isChecked ); + virtual void setupActionLook( QAction* actionToSetup ); +}; + + + +} // end namespace caf diff --git a/ApplicationCode/Commands/ViewLink/CMakeLists_files.cmake b/ApplicationCode/Commands/ViewLink/CMakeLists_files.cmake new file mode 100644 index 0000000000..38cdeccec9 --- /dev/null +++ b/ApplicationCode/Commands/ViewLink/CMakeLists_files.cmake @@ -0,0 +1,37 @@ + +# Use this workaround until we're on 2.8.3 on all platforms and can use CMAKE_CURRENT_LIST_DIR directly +if (${CMAKE_VERSION} VERSION_GREATER "2.8.2") + set(CEE_CURRENT_LIST_DIR ${CMAKE_CURRENT_LIST_DIR}/) +endif() + +set (SOURCE_GROUP_HEADER_FILES +${CEE_CURRENT_LIST_DIR}RicLinkVisibleViewsFeature.h +${CEE_CURRENT_LIST_DIR}RicLinkVisibleViewsFeatureUi.h +${CEE_CURRENT_LIST_DIR}RicShowAllLinkedViewsFeature.h +${CEE_CURRENT_LIST_DIR}RicLinkViewFeature.h +${CEE_CURRENT_LIST_DIR}RicUnLinkViewFeature.h +${CEE_CURRENT_LIST_DIR}RicShowLinkOptionsFeature.h +${CEE_CURRENT_LIST_DIR}RicDeleteAllLinkedViewsFeature.h +${CEE_CURRENT_LIST_DIR}RicSetMasterViewFeature.h +) + +set (SOURCE_GROUP_SOURCE_FILES +${CEE_CURRENT_LIST_DIR}RicLinkVisibleViewsFeature.cpp +${CEE_CURRENT_LIST_DIR}RicLinkVisibleViewsFeatureUi.cpp +${CEE_CURRENT_LIST_DIR}RicShowAllLinkedViewsFeature.cpp +${CEE_CURRENT_LIST_DIR}RicLinkViewFeature.cpp +${CEE_CURRENT_LIST_DIR}RicUnLinkViewFeature.cpp +${CEE_CURRENT_LIST_DIR}RicShowLinkOptionsFeature.cpp +${CEE_CURRENT_LIST_DIR}RicDeleteAllLinkedViewsFeature.cpp +${CEE_CURRENT_LIST_DIR}RicSetMasterViewFeature.cpp +) + +list(APPEND CODE_HEADER_FILES +${SOURCE_GROUP_HEADER_FILES} +) + +list(APPEND CODE_SOURCE_FILES +${SOURCE_GROUP_SOURCE_FILES} +) + +source_group( "CommandFeature\\ViewLink" FILES ${SOURCE_GROUP_HEADER_FILES} ${SOURCE_GROUP_SOURCE_FILES} ${CEE_CURRENT_LIST_DIR}CMakeLists_files.cmake ) diff --git a/ApplicationCode/Commands/ViewLink/RicDeleteAllLinkedViewsFeature.cpp b/ApplicationCode/Commands/ViewLink/RicDeleteAllLinkedViewsFeature.cpp new file mode 100644 index 0000000000..27f7ba8e11 --- /dev/null +++ b/ApplicationCode/Commands/ViewLink/RicDeleteAllLinkedViewsFeature.cpp @@ -0,0 +1,68 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicDeleteAllLinkedViewsFeature.h" + +#include "RiaApplication.h" +#include "RimProject.h" +#include "RimViewLinker.h" +#include "RimViewLinkerCollection.h" + +#include + +CAF_CMD_SOURCE_INIT(RicDeleteAllLinkedViewsFeature, "RicDeleteAllLinkedViewsFeature"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicDeleteAllLinkedViewsFeature::isCommandEnabled() +{ + return true; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicDeleteAllLinkedViewsFeature::onActionTriggered(bool isChecked) +{ + RimProject* proj = RiaApplication::instance()->project(); + + RimViewLinker* viewLinker = proj->viewLinkerCollection()->viewLinker(); + if (viewLinker) + { + // Remove the view linker object from the view linker collection + // viewLinkerCollection->viewLinker is a PdmChildField containing one RimViewLinker child object + proj->viewLinkerCollection->viewLinker.removeChildObject(viewLinker); + + viewLinker->applyRangeFilterCollectionByUserChoice(); + + delete viewLinker; + + proj->uiCapability()->updateConnectedEditors(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicDeleteAllLinkedViewsFeature::setupActionLook(QAction* actionToSetup) +{ + actionToSetup->setText("Delete All Linked Views"); +} + diff --git a/ApplicationCode/Commands/ViewLink/RicDeleteAllLinkedViewsFeature.h b/ApplicationCode/Commands/ViewLink/RicDeleteAllLinkedViewsFeature.h new file mode 100644 index 0000000000..ff16037666 --- /dev/null +++ b/ApplicationCode/Commands/ViewLink/RicDeleteAllLinkedViewsFeature.h @@ -0,0 +1,38 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdFeature.h" + +#include + +//================================================================================================== +/// +//================================================================================================== +class RicDeleteAllLinkedViewsFeature : public caf::CmdFeature +{ + CAF_CMD_HEADER_INIT; + +protected: + // Overrides + virtual bool isCommandEnabled(); + virtual void onActionTriggered( bool isChecked ); + virtual void setupActionLook(QAction* actionToSetup); +}; diff --git a/ApplicationCode/Commands/ViewLink/RicLinkViewFeature.cpp b/ApplicationCode/Commands/ViewLink/RicLinkViewFeature.cpp new file mode 100644 index 0000000000..0157de7d48 --- /dev/null +++ b/ApplicationCode/Commands/ViewLink/RicLinkViewFeature.cpp @@ -0,0 +1,86 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicLinkViewFeature.h" + +#include "RiaApplication.h" + +#include "RicLinkVisibleViewsFeature.h" + +#include "RimProject.h" +#include "RimView.h" +#include "RimViewLinkerCollection.h" +#include "RimViewLinker.h" + +#include "cafSelectionManager.h" + +#include + +CAF_CMD_SOURCE_INIT(RicLinkViewFeature, "RicLinkViewFeature"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicLinkViewFeature::isCommandEnabled() +{ + RimView* activeView = RiaApplication::instance()->activeReservoirView(); + if (!activeView) return false; + + RimViewController* viewController = activeView->viewController(); + + if(viewController) + { + return false; + } + else + { + if (!activeView->isMasterView()) + { + return true; + } + else + { + return false; + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicLinkViewFeature::onActionTriggered(bool isChecked) +{ + RimView* activeView = RiaApplication::instance()->activeReservoirView(); + if (!activeView) return; + + std::vector views; + views.push_back(activeView); + + RicLinkVisibleViewsFeature::linkViews(views); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicLinkViewFeature::setupActionLook(QAction* actionToSetup) +{ + actionToSetup->setText("Link View"); + actionToSetup->setIcon(QIcon(":/chain.png")); +} + diff --git a/ApplicationCode/Commands/ViewLink/RicLinkViewFeature.h b/ApplicationCode/Commands/ViewLink/RicLinkViewFeature.h new file mode 100644 index 0000000000..aa912bbe77 --- /dev/null +++ b/ApplicationCode/Commands/ViewLink/RicLinkViewFeature.h @@ -0,0 +1,38 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdFeature.h" + +#include + +//================================================================================================== +/// +//================================================================================================== +class RicLinkViewFeature : public caf::CmdFeature +{ + CAF_CMD_HEADER_INIT; + +protected: + // Overrides + virtual bool isCommandEnabled(); + virtual void onActionTriggered( bool isChecked ); + virtual void setupActionLook(QAction* actionToSetup); +}; diff --git a/ApplicationCode/Commands/ViewLink/RicLinkVisibleViewsFeature.cpp b/ApplicationCode/Commands/ViewLink/RicLinkVisibleViewsFeature.cpp new file mode 100644 index 0000000000..d4b323fd0a --- /dev/null +++ b/ApplicationCode/Commands/ViewLink/RicLinkVisibleViewsFeature.cpp @@ -0,0 +1,177 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicLinkVisibleViewsFeature.h" + +#include "RiaApplication.h" + +#include "RicLinkVisibleViewsFeatureUi.h" + +#include "RimViewController.h" +#include "RimProject.h" +#include "RimView.h" +#include "RimViewLinker.h" +#include "RimViewLinkerCollection.h" + +#include "RiuMainWindow.h" + +#include "cafPdmUiPropertyViewDialog.h" +#include "cafPdmUiTreeView.h" + +#include +#include +#include + + +CAF_CMD_SOURCE_INIT(RicLinkVisibleViewsFeature, "RicLinkVisibleViewsFeature"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicLinkVisibleViewsFeature::isCommandEnabled() +{ + RimProject* proj = RiaApplication::instance()->project(); + std::vector visibleViews; + std::vector linkedviews; + + proj->allVisibleViews(visibleViews); + if (proj->viewLinkerCollection() && proj->viewLinkerCollection()->viewLinker()) + { + proj->viewLinkerCollection()->viewLinker()->allViews(linkedviews); + } + + + if (visibleViews.size() >= 2 && (linkedviews.size() < visibleViews.size())) return true; + + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicLinkVisibleViewsFeature::onActionTriggered(bool isChecked) +{ + std::vector views; + findNotLinkedVisibleViews(views); + + linkViews(views); + return; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicLinkVisibleViewsFeature::setupActionLook(QAction* actionToSetup) +{ + actionToSetup->setText("Link Visible Views"); + actionToSetup->setIcon(QIcon(":/chain.png")); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicLinkVisibleViewsFeature::allLinkedViews(std::vector& views) +{ + RimProject* proj = RiaApplication::instance()->project(); + if (proj->viewLinkerCollection()->viewLinker()) + { + proj->viewLinkerCollection()->viewLinker()->allViews(views); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicLinkVisibleViewsFeature::findNotLinkedVisibleViews(std::vector &views) +{ + RimProject* proj = RiaApplication::instance()->project(); + + std::vector alreadyLinkedViews; + allLinkedViews(alreadyLinkedViews); + + std::vector visibleViews; + proj->allVisibleViews(visibleViews); + + for (size_t i = 0; i < visibleViews.size(); i++) + { + bool isLinked = false; + for (size_t j = 0; j < alreadyLinkedViews.size(); j++) + { + if (visibleViews[i] == alreadyLinkedViews[j]) + { + isLinked = true; + } + } + + if (!isLinked) + { + views.push_back(visibleViews[i]); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicLinkVisibleViewsFeature::linkViews(std::vector& views) +{ + RimProject* proj = RiaApplication::instance()->project(); + RimViewLinker* viewLinker = proj->viewLinkerCollection->viewLinker(); + + if (!viewLinker) + { + // Create a new view linker + + if (views.size() < 2) + { + return; + } + + RicLinkVisibleViewsFeatureUi featureUi; + featureUi.setViews(views); + + caf::PdmUiPropertyViewDialog propertyDialog(NULL, &featureUi, "Select Master View", ""); + propertyDialog.setWindowIcon(QIcon(":/chain.png")); + if (propertyDialog.exec() != QDialog::Accepted) return; + + RimView* masterView = featureUi.masterView(); + viewLinker = new RimViewLinker; + proj->viewLinkerCollection()->viewLinker = viewLinker; + viewLinker->setMasterView(masterView); + } + + for (size_t i = 0; i < views.size(); i++) + { + RimView* rimView = views[i]; + if (rimView == viewLinker->masterView()) continue; + + viewLinker->addDependentView(rimView); + } + + viewLinker->updateDependentViews(); + + viewLinker->updateUiNameAndIcon(); + + proj->viewLinkerCollection.uiCapability()->updateConnectedEditors(); + proj->updateConnectedEditors(); + + RiuMainWindow::instance()->projectTreeView()->setExpanded(proj->viewLinkerCollection(), true); + +} + diff --git a/ApplicationCode/Commands/ViewLink/RicLinkVisibleViewsFeature.h b/ApplicationCode/Commands/ViewLink/RicLinkVisibleViewsFeature.h new file mode 100644 index 0000000000..07a1a954ff --- /dev/null +++ b/ApplicationCode/Commands/ViewLink/RicLinkVisibleViewsFeature.h @@ -0,0 +1,49 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdFeature.h" + +#include + +class RimView; + +//================================================================================================== +/// +//================================================================================================== +class RicLinkVisibleViewsFeature : public caf::CmdFeature +{ + CAF_CMD_HEADER_INIT; + +public: + static void linkViews(std::vector &views); + +protected: + // Overrides + virtual bool isCommandEnabled(); + virtual void onActionTriggered( bool isChecked ); + + + virtual void setupActionLook(QAction* actionToSetup); + +private: + void findNotLinkedVisibleViews(std::vector &views); + void allLinkedViews(std::vector& views); +}; diff --git a/ApplicationCode/Commands/ViewLink/RicLinkVisibleViewsFeatureUi.cpp b/ApplicationCode/Commands/ViewLink/RicLinkVisibleViewsFeatureUi.cpp new file mode 100644 index 0000000000..424bc34ae6 --- /dev/null +++ b/ApplicationCode/Commands/ViewLink/RicLinkVisibleViewsFeatureUi.cpp @@ -0,0 +1,102 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicLinkVisibleViewsFeatureUi.h" + +#include "RiaApplication.h" + +#include "RimCase.h" +#include "RimView.h" +#include "RimViewLinker.h" + +CAF_PDM_SOURCE_INIT(RicLinkVisibleViewsFeatureUi, "RicLinkVisibleViewsFeatureUi"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicLinkVisibleViewsFeatureUi::RicLinkVisibleViewsFeatureUi(void) +{ + CAF_PDM_InitObject("Link Visible Views Feature UI", ":/chain.png", "", ""); + + CAF_PDM_InitFieldNoDefault(&m_masterView, "MasterView", "Master View", "", "", ""); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicLinkVisibleViewsFeatureUi::setViews(const std::vector& allViews) +{ + m_allViews = allViews; + + RimView* activeView = RiaApplication::instance()->activeReservoirView(); + + // Set Active view as master view + for (size_t i = 0; i < allViews.size(); i++) + { + if (activeView == allViews[i]) + { + m_masterView = allViews[i]; + } + } + + // Fallback to use first view if no active view is present + if (!m_masterView && allViews.size() > 0) + { + m_masterView = allViews[0]; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimView* RicLinkVisibleViewsFeatureUi::masterView() +{ + return m_masterView; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QList RicLinkVisibleViewsFeatureUi::calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly) +{ + QList optionList; + + if (fieldNeedingOptions == &m_masterView) + { + for (size_t i = 0; i < m_allViews.size(); i++) + { + RimCase* rimCase = NULL; + m_allViews[i]->firstAnchestorOrThisOfType(rimCase); + + QIcon icon; + if (rimCase) + { + icon = rimCase->uiCapability()->uiIcon(); + } + + + optionList.push_back(caf::PdmOptionItemInfo(RimViewLinker::displayNameForView(m_allViews[i]), + QVariant::fromValue(caf::PdmPointer(m_allViews[i])), + false, + icon)); + } + } + + return optionList; +} diff --git a/ApplicationCode/Commands/ViewLink/RicLinkVisibleViewsFeatureUi.h b/ApplicationCode/Commands/ViewLink/RicLinkVisibleViewsFeatureUi.h new file mode 100644 index 0000000000..e7b84a20aa --- /dev/null +++ b/ApplicationCode/Commands/ViewLink/RicLinkVisibleViewsFeatureUi.h @@ -0,0 +1,50 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafPdmField.h" +#include "cafPdmObject.h" +#include "cafPdmPtrField.h" + +#include + +class RimView; + +//================================================================================================== +/// +//================================================================================================== +class RicLinkVisibleViewsFeatureUi : public caf::PdmObject +{ + CAF_PDM_HEADER_INIT; + +public: + RicLinkVisibleViewsFeatureUi(void); + + void setViews(const std::vector& allViews); + RimView* masterView(); + +protected: + virtual QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly); + +private: + caf::PdmPtrField m_masterView; + + std::vector m_allViews; +}; diff --git a/ApplicationCode/Commands/ViewLink/RicSetMasterViewFeature.cpp b/ApplicationCode/Commands/ViewLink/RicSetMasterViewFeature.cpp new file mode 100644 index 0000000000..5f5609da7a --- /dev/null +++ b/ApplicationCode/Commands/ViewLink/RicSetMasterViewFeature.cpp @@ -0,0 +1,96 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicSetMasterViewFeature.h" + +#include "RiaApplication.h" +#include "RimProject.h" +#include "RimView.h" +#include "RimViewController.h" +#include "RimViewLinker.h" +#include "RimViewLinkerCollection.h" +#include "RiuMainWindow.h" + +#include "cafPdmUiTreeView.h" + +#include +#include + +CAF_CMD_SOURCE_INIT(RicSetMasterViewFeature, "RicSetMasterViewFeature"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicSetMasterViewFeature::isCommandEnabled() +{ + RimView* activeView = RiaApplication::instance()->activeReservoirView(); + if (!activeView) return false; + + RimProject* proj = RiaApplication::instance()->project(); + RimViewLinker* viewLinker = activeView->assosiatedViewLinker(); + if (viewLinker && viewLinker->masterView() == activeView) + { + return false; + } + + if (!proj->viewLinkerCollection()->viewLinker()) + { + return false; + } + + return true; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicSetMasterViewFeature::onActionTriggered(bool isChecked) +{ + RimView* activeView = RiaApplication::instance()->activeReservoirView(); + if (!activeView) return; + + RimProject* proj = RiaApplication::instance()->project(); + RimViewLinker* viewLinker = proj->viewLinkerCollection()->viewLinker(); + + viewLinker->applyRangeFilterCollectionByUserChoice(); + + RimView* previousMasterView = viewLinker->masterView(); + + viewLinker->setMasterView(activeView); + viewLinker->updateDependentViews(); + + viewLinker->addDependentView(previousMasterView); + + proj->viewLinkerCollection.uiCapability()->updateConnectedEditors(); + proj->updateConnectedEditors(); + + // Set managed view collection to selected and expanded in project tree + caf::PdmUiTreeView* projTreeView = RiuMainWindow::instance()->projectTreeView(); + projTreeView->selectAsCurrentItem(viewLinker); + projTreeView->setExpanded(viewLinker, true); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicSetMasterViewFeature::setupActionLook(QAction* actionToSetup) +{ + actionToSetup->setText("Set As Master View"); +} + diff --git a/ApplicationCode/Commands/ViewLink/RicSetMasterViewFeature.h b/ApplicationCode/Commands/ViewLink/RicSetMasterViewFeature.h new file mode 100644 index 0000000000..0288b94a03 --- /dev/null +++ b/ApplicationCode/Commands/ViewLink/RicSetMasterViewFeature.h @@ -0,0 +1,38 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdFeature.h" + +#include + +//================================================================================================== +/// +//================================================================================================== +class RicSetMasterViewFeature : public caf::CmdFeature +{ + CAF_CMD_HEADER_INIT; + +protected: + // Overrides + virtual bool isCommandEnabled(); + virtual void onActionTriggered( bool isChecked ); + virtual void setupActionLook(QAction* actionToSetup); +}; diff --git a/ApplicationCode/Commands/ViewLink/RicShowAllLinkedViewsFeature.cpp b/ApplicationCode/Commands/ViewLink/RicShowAllLinkedViewsFeature.cpp new file mode 100644 index 0000000000..c7dec0cdda --- /dev/null +++ b/ApplicationCode/Commands/ViewLink/RicShowAllLinkedViewsFeature.cpp @@ -0,0 +1,79 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicShowAllLinkedViewsFeature.h" + +#include "RimViewController.h" +#include "RimView.h" +#include "RimViewLinker.h" + +#include "cafSelectionManager.h" + +#include + +CAF_CMD_SOURCE_INIT(RicShowAllLinkedViewsFeature, "RicShowAllLinkedViewsFeature"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicShowAllLinkedViewsFeature::isCommandEnabled() +{ + return true; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicShowAllLinkedViewsFeature::onActionTriggered(bool isChecked) +{ + std::vector linkedViews; + caf::SelectionManager::instance()->objectsByType(&linkedViews); + + std::vector managedViews; + caf::SelectionManager::instance()->objectsByType(&managedViews); + for (size_t i = 0; i < managedViews.size(); i++) + { + RimViewLinker* rimLinked = NULL; + managedViews[i]->firstAnchestorOrThisOfType(rimLinked); + CVF_ASSERT(rimLinked); + + linkedViews.push_back(rimLinked); + } + + for (size_t i = 0; i < linkedViews.size(); i++) + { + std::vector views; + linkedViews[i]->allViews(views); + + for (size_t j = 0; j < views.size(); j++) + { + views[j]->showWindow.uiCapability()->setValueFromUi(true); + views[j]->uiCapability()->updateUiIconFromToggleField(); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicShowAllLinkedViewsFeature::setupActionLook(QAction* actionToSetup) +{ + actionToSetup->setText("Open All Linked Views"); +} + diff --git a/ApplicationCode/Commands/ViewLink/RicShowAllLinkedViewsFeature.h b/ApplicationCode/Commands/ViewLink/RicShowAllLinkedViewsFeature.h new file mode 100644 index 0000000000..920a8f9596 --- /dev/null +++ b/ApplicationCode/Commands/ViewLink/RicShowAllLinkedViewsFeature.h @@ -0,0 +1,38 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdFeature.h" + +#include + +//================================================================================================== +/// +//================================================================================================== +class RicShowAllLinkedViewsFeature : public caf::CmdFeature +{ + CAF_CMD_HEADER_INIT; + +protected: + // Overrides + virtual bool isCommandEnabled(); + virtual void onActionTriggered( bool isChecked ); + virtual void setupActionLook(QAction* actionToSetup); +}; diff --git a/ApplicationCode/Commands/ViewLink/RicShowLinkOptionsFeature.cpp b/ApplicationCode/Commands/ViewLink/RicShowLinkOptionsFeature.cpp new file mode 100644 index 0000000000..14d8522fb4 --- /dev/null +++ b/ApplicationCode/Commands/ViewLink/RicShowLinkOptionsFeature.cpp @@ -0,0 +1,75 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicShowLinkOptionsFeature.h" + +#include "RiaApplication.h" +#include "RimProject.h" +#include "RimView.h" +#include "RimViewController.h" +#include "RimViewLinker.h" +#include "RiuMainWindow.h" + +#include "cafSelectionManager.h" +#include "cafPdmUiTreeView.h" + +#include + + +CAF_CMD_SOURCE_INIT(RicShowLinkOptionsFeature, "RicShowLinkOptionsFeature"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicShowLinkOptionsFeature::isCommandEnabled() +{ + RimView* activeView = RiaApplication::instance()->activeReservoirView(); + if (!activeView) return false; + + RimViewController* viewController = activeView->viewController(); + + if (viewController) + { + return true; + } + + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicShowLinkOptionsFeature::onActionTriggered(bool isChecked) +{ + RimView* activeView = RiaApplication::instance()->activeReservoirView(); + if (!activeView) return; + + RimViewController* viewController = activeView->viewController(); + + RiuMainWindow::instance()->projectTreeView()->selectAsCurrentItem(viewController); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicShowLinkOptionsFeature::setupActionLook(QAction* actionToSetup) +{ + actionToSetup->setText("Show Link Options"); +} + diff --git a/ApplicationCode/Commands/ViewLink/RicShowLinkOptionsFeature.h b/ApplicationCode/Commands/ViewLink/RicShowLinkOptionsFeature.h new file mode 100644 index 0000000000..e80551dd21 --- /dev/null +++ b/ApplicationCode/Commands/ViewLink/RicShowLinkOptionsFeature.h @@ -0,0 +1,38 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdFeature.h" + +#include + +//================================================================================================== +/// +//================================================================================================== +class RicShowLinkOptionsFeature : public caf::CmdFeature +{ + CAF_CMD_HEADER_INIT; + +protected: + // Overrides + virtual bool isCommandEnabled(); + virtual void onActionTriggered( bool isChecked ); + virtual void setupActionLook(QAction* actionToSetup); +}; diff --git a/ApplicationCode/Commands/ViewLink/RicUnLinkViewFeature.cpp b/ApplicationCode/Commands/ViewLink/RicUnLinkViewFeature.cpp new file mode 100644 index 0000000000..c56ba64971 --- /dev/null +++ b/ApplicationCode/Commands/ViewLink/RicUnLinkViewFeature.cpp @@ -0,0 +1,84 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicUnLinkViewFeature.h" + +#include "RiaApplication.h" + +#include "RimProject.h" +#include "RimView.h" +#include "RimViewController.h" +#include "RimViewLinker.h" + +#include "cafCmdFeatureManager.h" +#include "cafSelectionManager.h" + +#include + + +CAF_CMD_SOURCE_INIT(RicUnLinkViewFeature, "RicUnLinkViewFeature"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicUnLinkViewFeature::isCommandEnabled() +{ + RimView* activeView = RiaApplication::instance()->activeReservoirView(); + if (!activeView) return false; + + RimViewController* viewController = activeView->viewController(); + + if (viewController) + { + return true; + } + + return false; + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicUnLinkViewFeature::onActionTriggered(bool isChecked) +{ + RimView* activeView = RiaApplication::instance()->activeReservoirView(); + if (!activeView) return; + + RimViewController* viewController = activeView->viewController(); + viewController->applyRangeFilterCollectionByUserChoice(); + + caf::SelectionManager::instance()->setSelectedItem(viewController); + caf::CmdFeature* feature = caf::CmdFeatureManager::instance()->getCommandFeature("RicDeleteItemFeature"); + if (feature) + { + feature->action()->trigger(); + + return; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicUnLinkViewFeature::setupActionLook(QAction* actionToSetup) +{ + actionToSetup->setText("Unlink View"); +} + diff --git a/ApplicationCode/Commands/ViewLink/RicUnLinkViewFeature.h b/ApplicationCode/Commands/ViewLink/RicUnLinkViewFeature.h new file mode 100644 index 0000000000..9b01e73473 --- /dev/null +++ b/ApplicationCode/Commands/ViewLink/RicUnLinkViewFeature.h @@ -0,0 +1,38 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdFeature.h" + +#include + +//================================================================================================== +/// +//================================================================================================== +class RicUnLinkViewFeature : public caf::CmdFeature +{ + CAF_CMD_HEADER_INIT; + +protected: + // Overrides + virtual bool isCommandEnabled(); + virtual void onActionTriggered( bool isChecked ); + virtual void setupActionLook(QAction* actionToSetup); +}; diff --git a/ApplicationCode/Commands/WellLogCommands/CMakeLists_files.cmake b/ApplicationCode/Commands/WellLogCommands/CMakeLists_files.cmake new file mode 100644 index 0000000000..0e351d6668 --- /dev/null +++ b/ApplicationCode/Commands/WellLogCommands/CMakeLists_files.cmake @@ -0,0 +1,41 @@ + +# Use this workaround until we're on 2.8.3 on all platforms and can use CMAKE_CURRENT_LIST_DIR directly +if (${CMAKE_VERSION} VERSION_GREATER "2.8.2") + set(CEE_CURRENT_LIST_DIR ${CMAKE_CURRENT_LIST_DIR}/) +endif() + +set (SOURCE_GROUP_HEADER_FILES +${CEE_CURRENT_LIST_DIR}RicAddWellLogToPlotFeature.h +${CEE_CURRENT_LIST_DIR}RicNewWellLogCurveExtractionFeature.h +${CEE_CURRENT_LIST_DIR}RicNewWellLogFileCurveFeature.h +${CEE_CURRENT_LIST_DIR}RicNewWellLogPlotFeature.h +${CEE_CURRENT_LIST_DIR}RicNewWellLogPlotFeatureImpl.h +${CEE_CURRENT_LIST_DIR}RicNewWellLogPlotTrackFeature.h +${CEE_CURRENT_LIST_DIR}RicWellLogPlotCurveFeatureImpl.h +${CEE_CURRENT_LIST_DIR}RicWellLogsImportFileFeature.h +${CEE_CURRENT_LIST_DIR}RicDeleteWellLogPlotTrackFeature.h +${CEE_CURRENT_LIST_DIR}RicWellLogPlotTrackFeatureImpl.h +) + +set (SOURCE_GROUP_SOURCE_FILES +${CEE_CURRENT_LIST_DIR}RicAddWellLogToPlotFeature.cpp +${CEE_CURRENT_LIST_DIR}RicNewWellLogCurveExtractionFeature.cpp +${CEE_CURRENT_LIST_DIR}RicNewWellLogFileCurveFeature.cpp +${CEE_CURRENT_LIST_DIR}RicNewWellLogPlotFeature.cpp +${CEE_CURRENT_LIST_DIR}RicNewWellLogPlotFeatureImpl.cpp +${CEE_CURRENT_LIST_DIR}RicNewWellLogPlotTrackFeature.cpp +${CEE_CURRENT_LIST_DIR}RicWellLogPlotCurveFeatureImpl.cpp +${CEE_CURRENT_LIST_DIR}RicWellLogsImportFileFeature.cpp +${CEE_CURRENT_LIST_DIR}RicDeleteWellLogPlotTrackFeature.cpp +${CEE_CURRENT_LIST_DIR}RicWellLogPlotTrackFeatureImpl.cpp +) + +list(APPEND CODE_HEADER_FILES +${SOURCE_GROUP_HEADER_FILES} +) + +list(APPEND CODE_SOURCE_FILES +${SOURCE_GROUP_SOURCE_FILES} +) + +source_group( "CommandFeature\\WellLog" FILES ${SOURCE_GROUP_HEADER_FILES} ${SOURCE_GROUP_SOURCE_FILES} ${CEE_CURRENT_LIST_DIR}CMakeLists_files.cmake ) diff --git a/ApplicationCode/Commands/WellLogCommands/RicAddWellLogToPlotFeature.cpp b/ApplicationCode/Commands/WellLogCommands/RicAddWellLogToPlotFeature.cpp new file mode 100644 index 0000000000..dd966b8043 --- /dev/null +++ b/ApplicationCode/Commands/WellLogCommands/RicAddWellLogToPlotFeature.cpp @@ -0,0 +1,142 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicAddWellLogToPlotFeature.h" + +#include "RicWellLogPlotCurveFeatureImpl.h" +#include "RicNewWellLogPlotFeatureImpl.h" + +#include "RimWellLogFile.h" +#include "RimWellLogFileChannel.h" +#include "RimWellLogPlot.h" +#include "RimWellLogPlotTrack.h" +#include "RimWellLogFileCurve.h" +#include "RimProject.h" +#include "RimMainPlotCollection.h" +#include "RimWellLogPlotCollection.h" +#include "RimWellPath.h" +#include "RimWellPathCollection.h" + +#include "RigWellLogFile.h" + +#include "RiaApplication.h" +#include "RiuMainWindow.h" +#include "RiuWellLogTrackPlot.h" + +#include "cafSelectionManager.h" +#include "cafPdmUiTreeView.h" + +#include + +namespace caf +{ + CAF_CMD_SOURCE_INIT(RicAddWellLogToPlotFeature, "RicAddWellLogToPlotFeature"); + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicAddWellLogToPlotFeature::isCommandEnabled() +{ + std::vector selection = selectedWellLogs(); + return selection.size() > 0; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicAddWellLogToPlotFeature::onActionTriggered(bool isChecked) +{ + std::vector selection = selectedWellLogs(); + if (selection.size() < 1) return; + + RimWellLogPlot* plot = RicNewWellLogPlotFeatureImpl::createWellLogPlot(); + + RimWellLogPlotTrack* plotTrack = new RimWellLogPlotTrack(); + plot->addTrack(plotTrack); + plotTrack->setDescription(QString("Track %1").arg(plot->trackCount())); + + plot->loadDataAndUpdate(); + + caf::PdmUiItem* uiItem = NULL; + + for (size_t wlIdx = 0; wlIdx < selection.size(); wlIdx++) + { + RimWellLogFileChannel* wellLog = selection[wlIdx]; + + RimWellPath* wellPath = NULL; + wellLog->firstAnchestorOrThisOfType(wellPath); + + RimWellLogFile* wellLogFile = NULL; + wellLog->firstAnchestorOrThisOfType(wellLogFile); + if (wellLogFile) + { + size_t curveIdx = plotTrack->curveCount(); + + RimWellLogFileCurve* curve = new RimWellLogFileCurve; + plotTrack->addCurve(curve); + + RigWellLogFile* wellLogDataFile = wellLogFile->wellLogFile(); + CVF_ASSERT(wellLogDataFile); + + cvf::Color3f curveColor = RicWellLogPlotCurveFeatureImpl::curveColorFromTable(); + curve->setColor(curveColor); + curve->setWellPath(wellPath); + curve->setWellLogChannelName(wellLog->name()); + + curve->updatePlotData(); + + if (wlIdx == selection.size() - 1) + { + uiItem = curve; + } + } + } + + plot->calculateAvailableDepthRange(); + plot->zoomAllDepth(); + plotTrack->viewer()->replot(); + + RiaApplication::instance()->project()->updateConnectedEditors(); + + if (uiItem) + { + RiuMainWindow::instance()->projectTreeView()->selectAsCurrentItem(uiItem); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicAddWellLogToPlotFeature::setupActionLook(QAction* actionToSetup) +{ + actionToSetup->setText("Add To New Plot"); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RicAddWellLogToPlotFeature::selectedWellLogs() +{ + std::vector selection; + caf::SelectionManager::instance()->objectsByType(&selection); + return selection; +} + +} // end namespace caf diff --git a/ApplicationCode/Commands/WellLogCommands/RicAddWellLogToPlotFeature.h b/ApplicationCode/Commands/WellLogCommands/RicAddWellLogToPlotFeature.h new file mode 100644 index 0000000000..987000abb8 --- /dev/null +++ b/ApplicationCode/Commands/WellLogCommands/RicAddWellLogToPlotFeature.h @@ -0,0 +1,53 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdFeature.h" + +#include + +class RimMainPlotCollection; +class RimWellLogPlotCollection; +class RimWellLogPlot; +class RimWellLogFileChannel; + +namespace caf +{ + +//================================================================================================== +/// +//================================================================================================== +class RicAddWellLogToPlotFeature : public CmdFeature +{ + CAF_CMD_HEADER_INIT; +protected: + + // Overrides + virtual bool isCommandEnabled(); + virtual void onActionTriggered( bool isChecked ); + virtual void setupActionLook( QAction* actionToSetup ); + +private: + std::vector selectedWellLogs(); +}; + + + +} // end namespace caf diff --git a/ApplicationCode/Commands/WellLogCommands/RicDeleteWellLogPlotTrackFeature.cpp b/ApplicationCode/Commands/WellLogCommands/RicDeleteWellLogPlotTrackFeature.cpp new file mode 100644 index 0000000000..a6efaedfd5 --- /dev/null +++ b/ApplicationCode/Commands/WellLogCommands/RicDeleteWellLogPlotTrackFeature.cpp @@ -0,0 +1,86 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicDeleteWellLogPlotTrackFeature.h" + +#include "RimWellLogPlotTrack.h" +#include "RimWellLogPlot.h" + +#include "cafSelectionManager.h" + +#include + + +CAF_CMD_SOURCE_INIT(RicDeleteWellLogPlotTrackFeature, "RicDeleteWellLogPlotTrackFeature"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicDeleteWellLogPlotTrackFeature::isCommandEnabled() +{ + std::vector selection; + caf::SelectionManager::instance()->objectsByType(&selection); + + if (selection.size() > 0) + { + RimWellLogPlot* wellLogPlot = NULL; + selection[0]->firstAnchestorOrThisOfType(wellLogPlot); + if (wellLogPlot->trackCount() > 1) + { + return true; + } + } + + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicDeleteWellLogPlotTrackFeature::onActionTriggered(bool isChecked) +{ + std::vector selection; + caf::SelectionManager::instance()->objectsByType(&selection); + + for (size_t i = 0; i < selection.size(); i++) + { + RimWellLogPlotTrack* track = selection[i]; + + RimWellLogPlot* wellLogPlot = NULL; + track->firstAnchestorOrThisOfType(wellLogPlot); + if (wellLogPlot && wellLogPlot->trackCount() > 1) + { + wellLogPlot->removeTrack(track); + caf::SelectionManager::instance()->removeObjectFromAllSelections(track); + delete track; + + wellLogPlot->calculateAvailableDepthRange(); + wellLogPlot->zoomAllDepth(); + wellLogPlot->uiCapability()->updateConnectedEditors(); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicDeleteWellLogPlotTrackFeature::setupActionLook(QAction* actionToSetup) +{ + actionToSetup->setText("Delete Track"); +} diff --git a/ApplicationCode/Commands/WellLogCommands/RicDeleteWellLogPlotTrackFeature.h b/ApplicationCode/Commands/WellLogCommands/RicDeleteWellLogPlotTrackFeature.h new file mode 100644 index 0000000000..cb5ebca9a0 --- /dev/null +++ b/ApplicationCode/Commands/WellLogCommands/RicDeleteWellLogPlotTrackFeature.h @@ -0,0 +1,36 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdFeature.h" + +//================================================================================================== +/// +//================================================================================================== +class RicDeleteWellLogPlotTrackFeature : public caf::CmdFeature +{ + CAF_CMD_HEADER_INIT; + +protected: + // Overrides + virtual bool isCommandEnabled(); + virtual void onActionTriggered( bool isChecked ); + virtual void setupActionLook( QAction* actionToSetup ); +}; diff --git a/ApplicationCode/Commands/WellLogCommands/RicNewWellLogCurveExtractionFeature.cpp b/ApplicationCode/Commands/WellLogCommands/RicNewWellLogCurveExtractionFeature.cpp new file mode 100644 index 0000000000..b862b28307 --- /dev/null +++ b/ApplicationCode/Commands/WellLogCommands/RicNewWellLogCurveExtractionFeature.cpp @@ -0,0 +1,136 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicNewWellLogCurveExtractionFeature.h" + +#include "RicWellLogPlotCurveFeatureImpl.h" +#include "RicNewWellLogPlotFeatureImpl.h" + +#include "RimWellLogPlotTrack.h" +#include "RimWellLogExtractionCurve.h" +#include "RimWellPath.h" +#include "RimWellPathCollection.h" +#include "RimView.h" +#include "RimProject.h" + +#include "RiuMainWindow.h" +#include "RiaApplication.h" + +#include "cafSelectionManager.h" + +#include + +#include + + +CAF_CMD_SOURCE_INIT(RicNewWellLogCurveExtractionFeature, "RicNewWellLogCurveExtractionFeature"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicNewWellLogCurveExtractionFeature::isCommandEnabled() +{ + return (selectedWellLogPlotTrack() != NULL || selectedWellPath() != NULL) && caseAvailable(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicNewWellLogCurveExtractionFeature::onActionTriggered(bool isChecked) +{ + RimWellLogPlotTrack* wellLogPlotTrack = selectedWellLogPlotTrack(); + if (wellLogPlotTrack) + { + addCurve(wellLogPlotTrack, NULL, NULL); + } + else + { + RimWellPath* wellPath = selectedWellPath(); + if (wellPath) + { + RimWellLogPlotTrack* wellLogPlotTrack = RicNewWellLogPlotFeatureImpl::createWellLogPlotTrack(); + RimWellLogExtractionCurve* plotCurve = addCurve(wellLogPlotTrack, RiaApplication::instance()->activeReservoirView(), wellPath); + + plotCurve->updatePlotData(); + plotCurve->updateConnectedEditors(); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicNewWellLogCurveExtractionFeature::setupActionLook(QAction* actionToSetup) +{ + actionToSetup->setText("New Well Log Extraction Curve"); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimWellLogPlotTrack* RicNewWellLogCurveExtractionFeature::selectedWellLogPlotTrack() const +{ + std::vector selection; + caf::SelectionManager::instance()->objectsByType(&selection); + return selection.size() > 0 ? selection[0] : NULL; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimWellPath* RicNewWellLogCurveExtractionFeature::selectedWellPath() const +{ + std::vector selection; + caf::SelectionManager::instance()->objectsByType(&selection); + return selection.size() > 0 ? selection[0] : NULL; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicNewWellLogCurveExtractionFeature::caseAvailable() const +{ + std::vector cases; + RiaApplication::instance()->project()->allCases(cases); + + return cases.size() > 0; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimWellLogExtractionCurve* RicNewWellLogCurveExtractionFeature::addCurve(RimWellLogPlotTrack* plotTrack, RimView* view, RimWellPath* wellPath) +{ + CVF_ASSERT(plotTrack); + + size_t curveIndex = plotTrack->curveCount(); + + RimWellLogExtractionCurve* curve = new RimWellLogExtractionCurve(); + + cvf::Color3f curveColor = RicWellLogPlotCurveFeatureImpl::curveColorFromTable(); + curve->setColor(curveColor); + curve->setWellPath(wellPath); + curve->setPropertiesFromView(view); + plotTrack->addCurve(curve); + + plotTrack->updateConnectedEditors(); + RiuMainWindow::instance()->setCurrentObjectInTreeView(curve); + + return curve; +} diff --git a/ApplicationCode/Commands/WellLogCommands/RicNewWellLogCurveExtractionFeature.h b/ApplicationCode/Commands/WellLogCommands/RicNewWellLogCurveExtractionFeature.h new file mode 100644 index 0000000000..84fe43c76a --- /dev/null +++ b/ApplicationCode/Commands/WellLogCommands/RicNewWellLogCurveExtractionFeature.h @@ -0,0 +1,50 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdFeature.h" + +class RimWellLogExtractionCurve; +class RimWellLogPlotTrack; +class RimWellPath; +class RimView; + +//================================================================================================== +/// +//================================================================================================== +class RicNewWellLogCurveExtractionFeature : public caf::CmdFeature +{ + CAF_CMD_HEADER_INIT; + +public: + static RimWellLogExtractionCurve* addCurve(RimWellLogPlotTrack* plotTrack, RimView* view, RimWellPath* wellPath); + + +protected: + // Overrides + virtual bool isCommandEnabled(); + virtual void onActionTriggered( bool isChecked ); + virtual void setupActionLook( QAction* actionToSetup ); + +private: + RimWellLogPlotTrack* selectedWellLogPlotTrack() const; + RimWellPath* selectedWellPath() const; + bool caseAvailable() const; +}; diff --git a/ApplicationCode/Commands/WellLogCommands/RicNewWellLogFileCurveFeature.cpp b/ApplicationCode/Commands/WellLogCommands/RicNewWellLogFileCurveFeature.cpp new file mode 100644 index 0000000000..2fbcb81055 --- /dev/null +++ b/ApplicationCode/Commands/WellLogCommands/RicNewWellLogFileCurveFeature.cpp @@ -0,0 +1,181 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicNewWellLogFileCurveFeature.h" + +#include "RicWellLogPlotCurveFeatureImpl.h" +#include "RicNewWellLogPlotFeatureImpl.h" + +#include "RimWellLogFileCurve.h" +#include "RimWellLogPlotTrack.h" +#include "RimWellLogFile.h" +#include "RimWellLogFileChannel.h" +#include "RimWellPath.h" +#include "RimWellPathCollection.h" +#include "RimProject.h" +#include "RimOilField.h" + +#include "RiuMainWindow.h" +#include "RiaApplication.h" + +#include "cafSelectionManager.h" + +#include + +#include + + +CAF_CMD_SOURCE_INIT(RicNewWellLogFileCurveFeature, "RicNewWellLogFileCurveFeature"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicNewWellLogFileCurveFeature::isCommandEnabled() +{ + return (selectedWellLogPlotTrack() != NULL && wellLogFilesAvailable()) || selectedWellPathWithLogFile() != NULL; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicNewWellLogFileCurveFeature::onActionTriggered(bool isChecked) +{ + RimWellLogPlotTrack* wellLogPlotTrack = selectedWellLogPlotTrack(); + if (wellLogPlotTrack) + { + addCurve(wellLogPlotTrack); + } + else + { + RimWellPath* wellPath = selectedWellPathWithLogFile(); + if (wellPath) + { + RimWellLogPlotTrack* wellLogPlotTrack = RicNewWellLogPlotFeatureImpl::createWellLogPlotTrack(); + RimWellLogFileCurve* plotCurve = addCurve(wellLogPlotTrack); + plotCurve->setWellPath(wellPath); + plotCurve->updateConnectedEditors(); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicNewWellLogFileCurveFeature::setupActionLook(QAction* actionToSetup) +{ + actionToSetup->setText("New Well Log LAS Curve"); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimWellLogPlotTrack* RicNewWellLogFileCurveFeature::selectedWellLogPlotTrack() const +{ + std::vector selection; + caf::SelectionManager::instance()->objectsByType(&selection); + return selection.size() > 0 ? selection[0] : NULL; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimWellPath* RicNewWellLogFileCurveFeature::selectedWellPathWithLogFile() const +{ + std::vector selection; + caf::SelectionManager::instance()->objectsByType(&selection); + if (selection.size() > 0) + { + RimWellPath* wellPath = selection[0]; + if (wellPath->m_wellLogFile()) + { + return wellPath; + } + } + + return NULL; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicNewWellLogFileCurveFeature::wellLogFilesAvailable() const +{ + RimProject* project = RiaApplication::instance()->project(); + if (project->activeOilField()->wellPathCollection()) + { + caf::PdmChildArrayField& wellPaths = project->activeOilField()->wellPathCollection()->wellPaths; + + for (size_t i = 0; i < wellPaths.size(); i++) + { + if (wellPaths[i]->m_wellLogFile()) + { + if (wellPaths[i]->m_wellLogFile()->wellLogFile()) + { + return true; + } + } + } + } + + return false; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimWellLogFileCurve* RicNewWellLogFileCurveFeature::addCurve(RimWellLogPlotTrack* plotTrack) +{ + CVF_ASSERT(plotTrack); + + size_t curveIndex = plotTrack->curveCount(); + + RimWellLogFileCurve* curve = new RimWellLogFileCurve(); + plotTrack->addCurve(curve); + + cvf::Color3f curveColor = RicWellLogPlotCurveFeatureImpl::curveColorFromTable(); + curve->setColor(curveColor); + + plotTrack->updateConnectedEditors(); + + RiuMainWindow::instance()->setCurrentObjectInTreeView(curve); + + return curve; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicNewWellLogFileCurveFeature::addWellLogChannelsToPlotTrack(RimWellLogPlotTrack* plotTrack, const std::vector& wellLogFileChannels) +{ + for (size_t cIdx = 0; cIdx < wellLogFileChannels.size(); cIdx++) + { + RimWellLogFileCurve* plotCurve = addCurve(plotTrack); + + RimWellPath* wellPath; + wellLogFileChannels[cIdx]->firstAnchestorOrThisOfType(wellPath); + if (wellPath) + { + plotCurve->setWellPath(wellPath); + plotCurve->setWellLogChannelName(wellLogFileChannels[cIdx]->name()); + plotCurve->updatePlotData(); + plotCurve->updateConnectedEditors(); + } + } +} diff --git a/ApplicationCode/Commands/WellLogCommands/RicNewWellLogFileCurveFeature.h b/ApplicationCode/Commands/WellLogCommands/RicNewWellLogFileCurveFeature.h new file mode 100644 index 0000000000..0c42f4a19c --- /dev/null +++ b/ApplicationCode/Commands/WellLogCommands/RicNewWellLogFileCurveFeature.h @@ -0,0 +1,54 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdFeature.h" + +#include + +class RimWellLogPlotTrack; +class RimWellLogFileCurve; +class RimWellPath; +class RimWellLogFileChannel; + + +//================================================================================================== +/// +//================================================================================================== +class RicNewWellLogFileCurveFeature : public caf::CmdFeature +{ + CAF_CMD_HEADER_INIT; + +public: + static RimWellLogFileCurve* addCurve(RimWellLogPlotTrack* plotTrack); + + static void addWellLogChannelsToPlotTrack(RimWellLogPlotTrack* plotTrack, const std::vector& wellLogFileChannels); + +protected: + // Overrides + virtual bool isCommandEnabled(); + virtual void onActionTriggered( bool isChecked ); + virtual void setupActionLook( QAction* actionToSetup ); + +private: + RimWellLogPlotTrack* selectedWellLogPlotTrack() const; + RimWellPath* selectedWellPathWithLogFile() const; + bool wellLogFilesAvailable() const; +}; diff --git a/ApplicationCode/Commands/WellLogCommands/RicNewWellLogPlotFeature.cpp b/ApplicationCode/Commands/WellLogCommands/RicNewWellLogPlotFeature.cpp new file mode 100644 index 0000000000..3f90c9d037 --- /dev/null +++ b/ApplicationCode/Commands/WellLogCommands/RicNewWellLogPlotFeature.cpp @@ -0,0 +1,63 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicNewWellLogPlotFeature.h" + +#include "RicNewWellLogPlotFeatureImpl.h" +#include "RicNewWellLogFileCurveFeature.h" +#include "RicNewWellLogCurveExtractionFeature.h" + +#include "RimProject.h" +#include "RimWellLogPlot.h" +#include "RimWellLogPlotTrack.h" +#include "RimWellLogPlotCurve.h" + +#include "RiaApplication.h" + +#include + +#include "cvfAssert.h" + + +CAF_CMD_SOURCE_INIT(RicNewWellLogPlotFeature, "RicNewWellLogPlotFeature"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicNewWellLogPlotFeature::isCommandEnabled() +{ + return true; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicNewWellLogPlotFeature::onActionTriggered(bool isChecked) +{ + RimWellLogPlotTrack* plotTrack = RicNewWellLogPlotFeatureImpl::createWellLogPlotTrack(); + RicNewWellLogCurveExtractionFeature::addCurve(plotTrack, NULL, NULL); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicNewWellLogPlotFeature::setupActionLook(QAction* actionToSetup) +{ + actionToSetup->setText("New Well Log Plot"); +} diff --git a/ApplicationCode/Commands/WellLogCommands/RicNewWellLogPlotFeature.h b/ApplicationCode/Commands/WellLogCommands/RicNewWellLogPlotFeature.h new file mode 100644 index 0000000000..061c0d99e6 --- /dev/null +++ b/ApplicationCode/Commands/WellLogCommands/RicNewWellLogPlotFeature.h @@ -0,0 +1,36 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdFeature.h" + +//================================================================================================== +/// +//================================================================================================== +class RicNewWellLogPlotFeature : public caf::CmdFeature +{ + CAF_CMD_HEADER_INIT; + +protected: + // Overrides + virtual bool isCommandEnabled(); + virtual void onActionTriggered( bool isChecked ); + virtual void setupActionLook( QAction* actionToSetup ); +}; diff --git a/ApplicationCode/Commands/WellLogCommands/RicNewWellLogPlotFeatureImpl.cpp b/ApplicationCode/Commands/WellLogCommands/RicNewWellLogPlotFeatureImpl.cpp new file mode 100644 index 0000000000..bc5cf34067 --- /dev/null +++ b/ApplicationCode/Commands/WellLogCommands/RicNewWellLogPlotFeatureImpl.cpp @@ -0,0 +1,99 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicNewWellLogPlotFeatureImpl.h" + +#include "RimProject.h" +#include "RimMainPlotCollection.h" +#include "RimWellLogPlotCollection.h" +#include "RimWellLogPlot.h" +#include "RimWellLogPlotTrack.h" + +#include "RiaApplication.h" + +#include "cvfAssert.h" + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimMainPlotCollection* RicNewWellLogPlotFeatureImpl::mainPlotCollection() +{ + RimProject* project = RiaApplication::instance()->project(); + CVF_ASSERT(project); + + RimMainPlotCollection* mainPlotColl = project->mainPlotCollection(); + if (!mainPlotColl) + { + project->recreateMainPlotCollection(); + } + + return project->mainPlotCollection(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimWellLogPlotCollection* RicNewWellLogPlotFeatureImpl::wellLogPlotCollection() +{ + RimMainPlotCollection* mainPlotColl = mainPlotCollection(); + CVF_ASSERT(mainPlotColl); + + RimWellLogPlotCollection* wellLogPlotColl = mainPlotColl->wellLogPlotCollection(); + if (!wellLogPlotColl) + { + mainPlotColl->recreateWellLogPlotCollection(); + } + + return mainPlotColl->wellLogPlotCollection(); +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimWellLogPlot* RicNewWellLogPlotFeatureImpl::createWellLogPlot() +{ + RimWellLogPlotCollection* wellLogPlotColl = wellLogPlotCollection(); + CVF_ASSERT(wellLogPlotColl); + + RimWellLogPlot* plot = new RimWellLogPlot(); + wellLogPlotColl->wellLogPlots().push_back(plot); + + plot->setDescription(QString("Well Log Plot %1").arg(wellLogPlotCollection()->wellLogPlots.size())); + + return plot; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimWellLogPlotTrack* RicNewWellLogPlotFeatureImpl::createWellLogPlotTrack() +{ + RimWellLogPlot* plot = createWellLogPlot(); + + RimWellLogPlotTrack* plotTrack = new RimWellLogPlotTrack(); + plot->addTrack(plotTrack); + plotTrack->setDescription(QString("Track %1").arg(plot->trackCount())); + + plot->loadDataAndUpdate(); + plot->updateConnectedEditors(); + RiaApplication::instance()->project()->updateConnectedEditors(); + + return plotTrack; +} diff --git a/ApplicationCode/Commands/WellLogCommands/RicNewWellLogPlotFeatureImpl.h b/ApplicationCode/Commands/WellLogCommands/RicNewWellLogPlotFeatureImpl.h new file mode 100644 index 0000000000..f681dc1998 --- /dev/null +++ b/ApplicationCode/Commands/WellLogCommands/RicNewWellLogPlotFeatureImpl.h @@ -0,0 +1,38 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +class RimMainPlotCollection; +class RimWellLogPlotCollection; +class RimWellLogPlot; +class RimWellLogPlotTrack; + +//================================================================================================== +/// +//================================================================================================== +class RicNewWellLogPlotFeatureImpl +{ +public: + + static RimMainPlotCollection* mainPlotCollection(); + static RimWellLogPlotCollection* wellLogPlotCollection(); + static RimWellLogPlot* createWellLogPlot(); + static RimWellLogPlotTrack* createWellLogPlotTrack(); +}; diff --git a/ApplicationCode/Commands/WellLogCommands/RicNewWellLogPlotTrackFeature.cpp b/ApplicationCode/Commands/WellLogCommands/RicNewWellLogPlotTrackFeature.cpp new file mode 100644 index 0000000000..f988a934bb --- /dev/null +++ b/ApplicationCode/Commands/WellLogCommands/RicNewWellLogPlotTrackFeature.cpp @@ -0,0 +1,77 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicNewWellLogPlotTrackFeature.h" + +#include "RimWellLogPlot.h" +#include "RimWellLogPlotTrack.h" + +#include "RiuMainWindow.h" + +#include "RicNewWellLogCurveExtractionFeature.h" + +#include "cafSelectionManager.h" + +#include + + +CAF_CMD_SOURCE_INIT(RicNewWellLogPlotTrackFeature, "RicNewWellLogPlotTrackFeature"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicNewWellLogPlotTrackFeature::isCommandEnabled() +{ + return selectedWellLogPlot() != NULL; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicNewWellLogPlotTrackFeature::onActionTriggered(bool isChecked) +{ + RimWellLogPlot* wellLogPlot = selectedWellLogPlot(); + if (wellLogPlot) + { + RimWellLogPlotTrack* plotTrack = new RimWellLogPlotTrack; + wellLogPlot->addTrack(plotTrack); + plotTrack->setDescription(QString("Track %1").arg(wellLogPlot->trackCount())); + + wellLogPlot->updateConnectedEditors(); + RicNewWellLogCurveExtractionFeature::addCurve(plotTrack, NULL, NULL); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicNewWellLogPlotTrackFeature::setupActionLook(QAction* actionToSetup) +{ + actionToSetup->setText("New Track"); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimWellLogPlot* RicNewWellLogPlotTrackFeature::selectedWellLogPlot() +{ + std::vector selection; + caf::SelectionManager::instance()->objectsByType(&selection); + return selection.size() > 0 ? selection[0] : NULL; +} diff --git a/ApplicationCode/Commands/WellLogCommands/RicNewWellLogPlotTrackFeature.h b/ApplicationCode/Commands/WellLogCommands/RicNewWellLogPlotTrackFeature.h new file mode 100644 index 0000000000..92d78de7c2 --- /dev/null +++ b/ApplicationCode/Commands/WellLogCommands/RicNewWellLogPlotTrackFeature.h @@ -0,0 +1,41 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdFeature.h" + +class RimWellLogPlot; + +//================================================================================================== +/// +//================================================================================================== +class RicNewWellLogPlotTrackFeature : public caf::CmdFeature +{ + CAF_CMD_HEADER_INIT; + +protected: + // Overrides + virtual bool isCommandEnabled(); + virtual void onActionTriggered( bool isChecked ); + virtual void setupActionLook( QAction* actionToSetup ); + +private: + RimWellLogPlot* selectedWellLogPlot(); +}; diff --git a/ApplicationCode/Commands/WellLogCommands/RicWellLogPlotCurveFeatureImpl.cpp b/ApplicationCode/Commands/WellLogCommands/RicWellLogPlotCurveFeatureImpl.cpp new file mode 100644 index 0000000000..ae5c4325c7 --- /dev/null +++ b/ApplicationCode/Commands/WellLogCommands/RicWellLogPlotCurveFeatureImpl.cpp @@ -0,0 +1,54 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicWellLogPlotCurveFeatureImpl.h" + +#include + +static const int RI_LOGPLOT_CURVECOLORSCOUNT = 15; +static const int RI_LOGPLOT_CURVECOLORS[] = +{ + Qt::black, + Qt::darkBlue, + Qt::darkRed, + Qt::darkGreen, + Qt::darkYellow, + Qt::darkMagenta, + Qt::darkCyan, + Qt::darkGray, + Qt::blue, + Qt::red, + Qt::green, + Qt::yellow, + Qt::magenta, + Qt::cyan, + Qt::gray +}; + +//-------------------------------------------------------------------------------------------------- +/// Pick default curve color from an index based palette +//-------------------------------------------------------------------------------------------------- +cvf::Color3f RicWellLogPlotCurveFeatureImpl::curveColorFromTable() +{ + static int colorIndex = 0; + QColor color = QColor(Qt::GlobalColor(RI_LOGPLOT_CURVECOLORS[colorIndex % RI_LOGPLOT_CURVECOLORSCOUNT])); + ++colorIndex; + cvf::Color3f cvfColor(color.redF(), color.greenF(), color.blueF()); + return cvfColor; +} diff --git a/ApplicationCode/Commands/WellLogCommands/RicWellLogPlotCurveFeatureImpl.h b/ApplicationCode/Commands/WellLogCommands/RicWellLogPlotCurveFeatureImpl.h new file mode 100644 index 0000000000..5e508d0208 --- /dev/null +++ b/ApplicationCode/Commands/WellLogCommands/RicWellLogPlotCurveFeatureImpl.h @@ -0,0 +1,32 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafPdmFieldCvfColor.h" + +//================================================================================================== +/// +//================================================================================================== +class RicWellLogPlotCurveFeatureImpl +{ + +public: + static cvf::Color3f curveColorFromTable(); +}; diff --git a/ApplicationCode/Commands/WellLogCommands/RicWellLogPlotTrackFeatureImpl.cpp b/ApplicationCode/Commands/WellLogCommands/RicWellLogPlotTrackFeatureImpl.cpp new file mode 100644 index 0000000000..3d69d234ce --- /dev/null +++ b/ApplicationCode/Commands/WellLogCommands/RicWellLogPlotTrackFeatureImpl.cpp @@ -0,0 +1,127 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicWellLogPlotTrackFeatureImpl.h" + +#include "RimWellLogPlot.h" +#include "RimWellLogPlotTrack.h" +#include "RimWellLogPlotCurve.h" + +#include "RiuMainWindow.h" + +#include "cafPdmUiTreeView.h" + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicWellLogPlotTrackFeatureImpl::moveCurvesToWellLogPlotTrack(RimWellLogPlotTrack* destTrack, + const std::vector& curves, + RimWellLogPlotCurve* curveToInsertAfter) +{ + CVF_ASSERT(destTrack ); + + std::set srcTracks; + std::set srcPlots; + + for (size_t cIdx = 0; cIdx < curves.size(); cIdx++) + { + RimWellLogPlotCurve* curve = curves[cIdx]; + + RimWellLogPlotTrack* wellLogPlotTrack; + curve->firstAnchestorOrThisOfType(wellLogPlotTrack); + if (wellLogPlotTrack) + { + wellLogPlotTrack->removeCurve(curve); + wellLogPlotTrack->updateConnectedEditors(); + srcTracks.insert(wellLogPlotTrack); + RimWellLogPlot* plot; + wellLogPlotTrack->firstAnchestorOrThisOfType(plot); + if (plot) srcPlots.insert(plot); + } + } + + size_t insertionStartIndex = 0; + if (curveToInsertAfter) insertionStartIndex = destTrack->curveIndex(curveToInsertAfter) + 1; + + for (size_t cIdx = 0; cIdx < curves.size(); cIdx++) + { + destTrack->insertCurve(curves[cIdx], insertionStartIndex + cIdx); + } + + for (std::set::iterator pIt = srcPlots.begin(); pIt != srcPlots.end(); ++pIt) + { + (*pIt)->calculateAvailableDepthRange(); + } + + for (std::set::iterator tIt = srcTracks.begin(); tIt != srcTracks.end(); ++tIt) + { + (*tIt)->zoomAllXAndZoomAllDepthOnOwnerPlot(); + } + + destTrack->loadDataAndUpdate(); + destTrack->zoomAllXAndZoomAllDepthOnOwnerPlot(); + destTrack->updateConnectedEditors(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicWellLogPlotTrackFeatureImpl::moveTracksToWellLogPlot(RimWellLogPlot* dstWellLogPlot, + const std::vector& tracksToMove, + RimWellLogPlotTrack* trackToInsertAfter) +{ + CVF_ASSERT(dstWellLogPlot); + + std::set srcPlots; + + for (size_t tIdx = 0; tIdx < tracksToMove.size(); tIdx++) + { + RimWellLogPlotTrack* track = tracksToMove[tIdx]; + + RimWellLogPlot* srcPlot; + track->firstAnchestorOrThisOfType(srcPlot); + if (srcPlot) + { + srcPlot->removeTrack(track); + + srcPlots.insert(srcPlot); + } + } + + for (std::set::iterator pIt = srcPlots.begin(); pIt != srcPlots.end(); ++pIt) + { + (*pIt)->calculateAvailableDepthRange(); + (*pIt)->updateTrackNames(); + (*pIt)->zoomAllDepth(); + (*pIt)->updateConnectedEditors(); + } + + + size_t insertionStartIndex = 0; + if (trackToInsertAfter) insertionStartIndex = dstWellLogPlot->trackIndex(trackToInsertAfter) + 1; + + for (size_t tIdx = 0; tIdx < tracksToMove.size(); tIdx++) + { + dstWellLogPlot->insertTrack(tracksToMove[tIdx], insertionStartIndex + tIdx); + } + + dstWellLogPlot->updateTrackNames(); + dstWellLogPlot->updateTracks(); + dstWellLogPlot->updateConnectedEditors(); +} diff --git a/ApplicationCode/Commands/WellLogCommands/RicWellLogPlotTrackFeatureImpl.h b/ApplicationCode/Commands/WellLogCommands/RicWellLogPlotTrackFeatureImpl.h new file mode 100644 index 0000000000..2f4fdaf71d --- /dev/null +++ b/ApplicationCode/Commands/WellLogCommands/RicWellLogPlotTrackFeatureImpl.h @@ -0,0 +1,41 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include + +class RimWellLogPlot; +class RimWellLogPlotTrack; +class RimWellLogPlotCurve; + +//================================================================================================== +/// +//================================================================================================== +class RicWellLogPlotTrackFeatureImpl +{ +public: + + static void moveCurvesToWellLogPlotTrack(RimWellLogPlotTrack* dstTrack, + const std::vector& curves, + RimWellLogPlotCurve* insertAfterCurve); + static void moveTracksToWellLogPlot(RimWellLogPlot* wellLogPlot, + const std::vector& tracks, + RimWellLogPlotTrack* trackToInsertAfter); +}; diff --git a/ApplicationCode/Commands/WellLogCommands/RicWellLogsImportFileFeature.cpp b/ApplicationCode/Commands/WellLogCommands/RicWellLogsImportFileFeature.cpp new file mode 100644 index 0000000000..6accc87f16 --- /dev/null +++ b/ApplicationCode/Commands/WellLogCommands/RicWellLogsImportFileFeature.cpp @@ -0,0 +1,69 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicWellLogsImportFileFeature.h" + +#include "RiaApplication.h" +#include "RimProject.h" +#include "RiuMainWindow.h" + +#include +#include + +namespace caf +{ + CAF_CMD_SOURCE_INIT(RicWellLogsImportFileFeature, "RicWellLogsImportFileFeature"); + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicWellLogsImportFileFeature::isCommandEnabled() +{ + return true; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicWellLogsImportFileFeature::onActionTriggered(bool isChecked) +{ + // Open dialog box to select well path files + RiaApplication* app = RiaApplication::instance(); + QString defaultDir = app->defaultFileDialogDirectory("WELL_LOGS_DIR"); + QStringList wellLogFilePaths = QFileDialog::getOpenFileNames(RiuMainWindow::instance(), "Import Well Logs", defaultDir, "Well Logs (*.las);;All Files (*.*)"); + + if (wellLogFilePaths.size() < 1) return; + + // Remember the path to next time + app->setDefaultFileDialogDirectory("WELL_LOGS_DIR", QFileInfo(wellLogFilePaths.last()).absolutePath()); + + app->addWellLogsToModel(wellLogFilePaths); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicWellLogsImportFileFeature::setupActionLook(QAction* actionToSetup) +{ + actionToSetup->setText("Import Well &Logs from File"); + actionToSetup->setIcon(QIcon(":/LasFile16x16.png")); +} + +} // end namespace caf diff --git a/ApplicationCode/Commands/WellLogCommands/RicWellLogsImportFileFeature.h b/ApplicationCode/Commands/WellLogCommands/RicWellLogsImportFileFeature.h new file mode 100644 index 0000000000..c82e9bf70e --- /dev/null +++ b/ApplicationCode/Commands/WellLogCommands/RicWellLogsImportFileFeature.h @@ -0,0 +1,43 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdFeature.h" + +namespace caf +{ + +//================================================================================================== +/// +//================================================================================================== +class RicWellLogsImportFileFeature : public CmdFeature +{ + CAF_CMD_HEADER_INIT; +protected: + + // Overrides + virtual bool isCommandEnabled(); + virtual void onActionTriggered( bool isChecked ); + virtual void setupActionLook( QAction* actionToSetup ); +}; + + + +} // end namespace caf diff --git a/ApplicationCode/Commands/WellPathCommands/CMakeLists_files.cmake b/ApplicationCode/Commands/WellPathCommands/CMakeLists_files.cmake new file mode 100644 index 0000000000..41ab4db8f8 --- /dev/null +++ b/ApplicationCode/Commands/WellPathCommands/CMakeLists_files.cmake @@ -0,0 +1,29 @@ + +# Use this workaround until we're on 2.8.3 on all platforms and can use CMAKE_CURRENT_LIST_DIR directly +if (${CMAKE_VERSION} VERSION_GREATER "2.8.2") + set(CEE_CURRENT_LIST_DIR ${CMAKE_CURRENT_LIST_DIR}/) +endif() + +set (SOURCE_GROUP_HEADER_FILES +${CEE_CURRENT_LIST_DIR}RicWellPathDeleteFeature.h +${CEE_CURRENT_LIST_DIR}RicWellPathsDeleteAllFeature.h +${CEE_CURRENT_LIST_DIR}RicWellPathsImportFileFeature.h +${CEE_CURRENT_LIST_DIR}RicWellPathsImportSsihubFeature.h +) + +set (SOURCE_GROUP_SOURCE_FILES +${CEE_CURRENT_LIST_DIR}RicWellPathDeleteFeature.cpp +${CEE_CURRENT_LIST_DIR}RicWellPathsDeleteAllFeature.cpp +${CEE_CURRENT_LIST_DIR}RicWellPathsImportFileFeature.cpp +${CEE_CURRENT_LIST_DIR}RicWellPathsImportSsihubFeature.cpp +) + +list(APPEND CODE_HEADER_FILES +${SOURCE_GROUP_HEADER_FILES} +) + +list(APPEND CODE_SOURCE_FILES +${SOURCE_GROUP_SOURCE_FILES} +) + +source_group( "CommandFeature\\WellPath" FILES ${SOURCE_GROUP_HEADER_FILES} ${SOURCE_GROUP_SOURCE_FILES} ${CEE_CURRENT_LIST_DIR}CMakeLists_files.cmake ) diff --git a/ApplicationCode/Commands/WellPathCommands/RicWellPathDeleteFeature.cpp b/ApplicationCode/Commands/WellPathCommands/RicWellPathDeleteFeature.cpp new file mode 100644 index 0000000000..db4035373e --- /dev/null +++ b/ApplicationCode/Commands/WellPathCommands/RicWellPathDeleteFeature.cpp @@ -0,0 +1,81 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicWellPathDeleteFeature.h" + +#include "RimWellPathCollection.h" + +#include "cafSelectionManager.h" + +#include +#include "RimWellPath.h" + +namespace caf +{ + +CAF_CMD_SOURCE_INIT(RicWellPathDeleteFeature, "RicWellPathDeleteFeature"); + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicWellPathDeleteFeature::isCommandEnabled() +{ + std::vector objects; + caf::SelectionManager::instance()->objectsByType(&objects); + + if (objects.size() == 1) + { + return true; + } + + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicWellPathDeleteFeature::onActionTriggered(bool isChecked) +{ + std::vector objects; + caf::SelectionManager::instance()->objectsByType(&objects); + + if (objects.size() == 0) return; + + RimWellPath* wellPath = objects[0]; + + RimWellPathCollection* wellPathCollection = NULL; + wellPath->firstAnchestorOrThisOfType(wellPathCollection); + + wellPathCollection->removeWellPath(wellPath);; + delete wellPath; + + wellPathCollection->uiCapability()->updateConnectedEditors(); + wellPathCollection->scheduleGeometryRegenAndRedrawViews(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicWellPathDeleteFeature::setupActionLook(QAction* actionToSetup) +{ + actionToSetup->setText("Delete Well Path"); +} + +} // end namespace caf diff --git a/ApplicationCode/Commands/WellPathCommands/RicWellPathDeleteFeature.h b/ApplicationCode/Commands/WellPathCommands/RicWellPathDeleteFeature.h new file mode 100644 index 0000000000..7f39370eaa --- /dev/null +++ b/ApplicationCode/Commands/WellPathCommands/RicWellPathDeleteFeature.h @@ -0,0 +1,43 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdFeature.h" + +namespace caf +{ + +//================================================================================================== +/// +//================================================================================================== +class RicWellPathDeleteFeature : public CmdFeature +{ + CAF_CMD_HEADER_INIT; +protected: + + // Overrides + virtual bool isCommandEnabled(); + virtual void onActionTriggered( bool isChecked ); + virtual void setupActionLook( QAction* actionToSetup ); +}; + + + +} // end namespace caf diff --git a/ApplicationCode/Commands/WellPathCommands/RicWellPathsDeleteAllFeature.cpp b/ApplicationCode/Commands/WellPathCommands/RicWellPathsDeleteAllFeature.cpp new file mode 100644 index 0000000000..4459bd0b43 --- /dev/null +++ b/ApplicationCode/Commands/WellPathCommands/RicWellPathsDeleteAllFeature.cpp @@ -0,0 +1,75 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicWellPathsDeleteAllFeature.h" + +#include "RimWellPathCollection.h" + +#include "cafSelectionManager.h" + +#include + +namespace caf +{ + +CAF_CMD_SOURCE_INIT(RicWellPathsDeleteAllFeature, "RicWellPathsDeleteAllFeature"); + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicWellPathsDeleteAllFeature::isCommandEnabled() +{ + std::vector objects; + caf::SelectionManager::instance()->objectsByType(&objects); + + if (objects.size() == 1) + { + return true; + } + + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicWellPathsDeleteAllFeature::onActionTriggered(bool isChecked) +{ + std::vector objects; + caf::SelectionManager::instance()->objectsByType(&objects); + + RimWellPathCollection* wellPathCollection = objects[0]; + + wellPathCollection->deleteAllWellPaths(); + + wellPathCollection->uiCapability()->updateConnectedEditors(); + wellPathCollection->scheduleGeometryRegenAndRedrawViews(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicWellPathsDeleteAllFeature::setupActionLook(QAction* actionToSetup) +{ + actionToSetup->setText("Delete All Well Paths"); + //actionToSetup->setIcon(QIcon(":/WellCollection.png")); +} + +} // end namespace caf diff --git a/ApplicationCode/Commands/WellPathCommands/RicWellPathsDeleteAllFeature.h b/ApplicationCode/Commands/WellPathCommands/RicWellPathsDeleteAllFeature.h new file mode 100644 index 0000000000..3c316ce976 --- /dev/null +++ b/ApplicationCode/Commands/WellPathCommands/RicWellPathsDeleteAllFeature.h @@ -0,0 +1,43 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdFeature.h" + +namespace caf +{ + +//================================================================================================== +/// +//================================================================================================== +class RicWellPathsDeleteAllFeature : public CmdFeature +{ + CAF_CMD_HEADER_INIT; +protected: + + // Overrides + virtual bool isCommandEnabled(); + virtual void onActionTriggered( bool isChecked ); + virtual void setupActionLook( QAction* actionToSetup ); +}; + + + +} // end namespace caf diff --git a/ApplicationCode/Commands/WellPathCommands/RicWellPathsImportFileFeature.cpp b/ApplicationCode/Commands/WellPathCommands/RicWellPathsImportFileFeature.cpp new file mode 100644 index 0000000000..28d13b1ca4 --- /dev/null +++ b/ApplicationCode/Commands/WellPathCommands/RicWellPathsImportFileFeature.cpp @@ -0,0 +1,73 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicWellPathsImportFileFeature.h" + +#include "RiaApplication.h" +#include "RimProject.h" +#include "RiuMainWindow.h" + +#include +#include + +namespace caf +{ + CAF_CMD_SOURCE_INIT(RicWellPathsImportFileFeature, "RicWellPathsImportFileFeature"); + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicWellPathsImportFileFeature::isCommandEnabled() +{ + return true; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicWellPathsImportFileFeature::onActionTriggered(bool isChecked) +{ + // Open dialog box to select well path files + RiaApplication* app = RiaApplication::instance(); + QString defaultDir = app->defaultFileDialogDirectory("WELLPATH_DIR"); + QStringList wellPathFilePaths = QFileDialog::getOpenFileNames(RiuMainWindow::instance(), "Import Well Paths", defaultDir, "Well Paths (*.json *.asc *.asci *.ascii *.dev);;All Files (*.*)"); + + if (wellPathFilePaths.size() < 1) return; + + // Remember the path to next time + app->setDefaultFileDialogDirectory("WELLPATH_DIR", QFileInfo(wellPathFilePaths.last()).absolutePath()); + + app->addWellPathsToModel(wellPathFilePaths); + if (app->project()) + { + app->project()->createDisplayModelAndRedrawAllViews(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicWellPathsImportFileFeature::setupActionLook(QAction* actionToSetup) +{ + actionToSetup->setText("Import &Well Paths from File"); + actionToSetup->setIcon(QIcon(":/Well.png")); +} + +} // end namespace caf diff --git a/ApplicationCode/Commands/WellPathCommands/RicWellPathsImportFileFeature.h b/ApplicationCode/Commands/WellPathCommands/RicWellPathsImportFileFeature.h new file mode 100644 index 0000000000..40bf0afa2f --- /dev/null +++ b/ApplicationCode/Commands/WellPathCommands/RicWellPathsImportFileFeature.h @@ -0,0 +1,43 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdFeature.h" + +namespace caf +{ + +//================================================================================================== +/// +//================================================================================================== +class RicWellPathsImportFileFeature : public CmdFeature +{ + CAF_CMD_HEADER_INIT; +protected: + + // Overrides + virtual bool isCommandEnabled(); + virtual void onActionTriggered( bool isChecked ); + virtual void setupActionLook( QAction* actionToSetup ); +}; + + + +} // end namespace caf diff --git a/ApplicationCode/Commands/WellPathCommands/RicWellPathsImportSsihubFeature.cpp b/ApplicationCode/Commands/WellPathCommands/RicWellPathsImportSsihubFeature.cpp new file mode 100644 index 0000000000..b2800d2364 --- /dev/null +++ b/ApplicationCode/Commands/WellPathCommands/RicWellPathsImportSsihubFeature.cpp @@ -0,0 +1,129 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicWellPathsImportSsihubFeature.h" + +#include "RiaApplication.h" +#include "RiaPreferences.h" +#include "RimProject.h" +#include "RimTools.h" +#include "RimWellPathImport.h" +#include "RiuMainWindow.h" +#include "RiuWellImportWizard.h" + +#include +#include +#include + +namespace caf +{ + CAF_CMD_SOURCE_INIT(RicWellPathsImportSsihubFeature, "RicWellPathsImportSsihubFeature"); + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicWellPathsImportSsihubFeature::isCommandEnabled() +{ + RiaApplication* app = RiaApplication::instance(); + if (!app->project()) + { + return false; + } + + if (!QFile::exists(app->project()->fileName())) + { + return false; + } + + return true; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicWellPathsImportSsihubFeature::onActionTriggered(bool isChecked) +{ + RiaApplication* app = RiaApplication::instance(); + if (!app->project()) + { + return; + } + + if (!QFile::exists(app->project()->fileName())) + { + return; + } + + // Update the UTM bounding box from the reservoir + app->project()->computeUtmAreaOfInterest(); + + QString wellPathsFolderPath = RimTools::getCacheRootDirectoryPathFromProject(); + wellPathsFolderPath += "_wellpaths"; + QDir::root().mkpath(wellPathsFolderPath); + + + // Keep a copy of the import settings, and restore if cancel is pressed in the import wizard + QString copyOfOriginalObject = xmlObj(app->project()->wellPathImport())->writeObjectToXmlString(); + + RiuWellImportWizard wellImportwizard(app->preferences()->ssihubAddress, wellPathsFolderPath, app->project()->wellPathImport(), RiuMainWindow::instance()); + + // Get password/username from application cache + { + QString ssihubUsername = app->cacheDataObject("ssihub_username").toString(); + QString ssihubPassword = app->cacheDataObject("ssihub_password").toString(); + +#ifdef _DEBUG + + // Valid credentials for ssihubfake received in mail from Håkon + ssihubUsername = "admin"; + ssihubPassword = "resinsight"; +#endif + + wellImportwizard.setCredentials(ssihubUsername, ssihubPassword); + } + + if (QDialog::Accepted == wellImportwizard.exec()) + { + QStringList wellPaths = wellImportwizard.absoluteFilePathsToWellPaths(); + if (wellPaths.size() > 0) + { + app->addWellPathsToModel(wellPaths); + app->project()->createDisplayModelAndRedrawAllViews(); + } + + app->setCacheDataObject("ssihub_username", wellImportwizard.field("username")); + app->setCacheDataObject("ssihub_password", wellImportwizard.field("password")); + } + else + { + xmlObj(app->project()->wellPathImport())->readObjectFromXmlString(copyOfOriginalObject, caf::PdmDefaultObjectFactory::instance()); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicWellPathsImportSsihubFeature::setupActionLook(QAction* actionToSetup) +{ + actionToSetup->setText("Import Well Paths from &SSI-hub"); + actionToSetup->setIcon(QIcon(":/WellCollection.png")); +} + +} // end namespace caf diff --git a/ApplicationCode/Commands/WellPathCommands/RicWellPathsImportSsihubFeature.h b/ApplicationCode/Commands/WellPathCommands/RicWellPathsImportSsihubFeature.h new file mode 100644 index 0000000000..46bfc99c33 --- /dev/null +++ b/ApplicationCode/Commands/WellPathCommands/RicWellPathsImportSsihubFeature.h @@ -0,0 +1,43 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdFeature.h" + +namespace caf +{ + +//================================================================================================== +/// +//================================================================================================== +class RicWellPathsImportSsihubFeature : public CmdFeature +{ + CAF_CMD_HEADER_INIT; +protected: + + // Overrides + virtual bool isCommandEnabled(); + virtual void onActionTriggered( bool isChecked ); + virtual void setupActionLook( QAction* actionToSetup ); +}; + + + +} // end namespace caf diff --git a/ApplicationCode/FileInterface/RifEclipseInputFileTools.cpp b/ApplicationCode/FileInterface/RifEclipseInputFileTools.cpp index 7746b8b15d..16665338da 100644 --- a/ApplicationCode/FileInterface/RifEclipseInputFileTools.cpp +++ b/ApplicationCode/FileInterface/RifEclipseInputFileTools.cpp @@ -100,7 +100,6 @@ bool readDoubleValuesForActiveCells(RigCaseData* reservoir, size_t resultIndex, newPropertyData[0].resize(activeCellInfo->reservoirActiveCellCount(), HUGE_VAL); std::vector& valuesActiveCells = newPropertyData[0]; - size_t acIdx = 0; for (size_t gcIdx = 0; gcIdx < activeCellInfo->reservoirCellCount(); gcIdx++) { size_t activeCellResultIndex = activeCellInfo->cellResultIndex(gcIdx); @@ -187,7 +186,6 @@ bool RifEclipseInputFileTools::openGridFile(const QString& fileName, RigCaseData bool allKwReadOk = true; - bool continueReading = true; fseek(gridFilePointer, specgridPos, SEEK_SET); allKwReadOk = allKwReadOk && NULL != (specGridKw = ecl_kw_fscanf_alloc_current_grdecl__(gridFilePointer, false , ECL_INT_TYPE)); @@ -297,7 +295,6 @@ std::map RifEclipseInputFileTools::readProperties(const QStri return std::map(); } - bool isSomethingRead = false; std::map newResults; for (size_t i = 0; i < fileKeywords.size(); ++i) { @@ -503,8 +500,8 @@ bool RifEclipseInputFileTools::writeBinaryResultToTextFile(const QString& fileNa return false; } - cvf::ref resultAccessor = RigResultAccessorFactory::createResultAccessor(eclipseCase, eclipseCase->mainGrid()->gridIndex(), porosityModel, timeStep, resultName); - if (resultAccessor.isNull()) + cvf::ref resultAccessor = RigResultAccessorFactory::createResultAccessor(eclipseCase, eclipseCase->mainGrid()->gridIndex(), porosityModel, timeStep, resultName); + if (resultAccessor.isNull()) { return false; } @@ -517,7 +514,7 @@ bool RifEclipseInputFileTools::writeBinaryResultToTextFile(const QString& fileNa { for (i = 0; i < eclipseCase->mainGrid()->cellCountI(); i++) { - double resultValue = resultAccessor->cellScalar(eclipseCase->mainGrid()->cellIndexFromIJK(i, j, k)); + double resultValue = resultAccessor->cellScalar(eclipseCase->mainGrid()->cellIndexFromIJK(i, j, k)); if (resultValue == HUGE_VAL) { resultValue = undefinedValue; diff --git a/ApplicationCode/FileInterface/RifReaderEclipseOutput.cpp b/ApplicationCode/FileInterface/RifReaderEclipseOutput.cpp index 9f6a02340b..265943faeb 100644 --- a/ApplicationCode/FileInterface/RifReaderEclipseOutput.cpp +++ b/ApplicationCode/FileInterface/RifReaderEclipseOutput.cpp @@ -392,8 +392,6 @@ bool RifReaderEclipseOutput::open(const QString& fileName, RigCaseData* eclipseC cvf::Collection faults; std::vector< RifKeywordAndFilePos > fileKeywords; - std::vector filenamesWithFaults; - for (size_t i = 0; i < this->filenamesWithFaults().size(); i++) { QString faultFilename = this->filenamesWithFaults()[i]; @@ -417,7 +415,9 @@ bool RifReaderEclipseOutput::open(const QString& fileName, RigCaseData* eclipseC RigMainGrid* mainGrid = eclipseCase->mainGrid(); mainGrid->setFaults(faults); - std::unique(filenamesWithFaults.begin(), filenamesWithFaults.end()); + std::sort(filenamesWithFaults.begin(), filenamesWithFaults.end()); + std::vector::iterator last = std::unique(filenamesWithFaults.begin(), filenamesWithFaults.end()); + filenamesWithFaults.erase(last, filenamesWithFaults.end()); this->setFilenamesWithFaults(filenamesWithFaults); } @@ -925,8 +925,6 @@ cvf::Vec3d interpolate3DPosition(const std::vector std::vector filteredPositions; filteredPositions.reserve(positions.size()); - bool hasContibFromBelow = false; - bool hasContribFromAbove = false; double minDistFromContribAbove = HUGE_VAL; double minDistFromContribBelow = HUGE_VAL; std::vector contrFromAbove; @@ -1079,7 +1077,6 @@ void RifReaderEclipseOutput::readWellCells(const ecl_grid_type* mainEclGrid, boo sameCount = true; } - RigMainGrid* mainGrid = m_eclipseCase->mainGrid(); std::vector grids; m_eclipseCase->allGrids(&grids); @@ -1215,8 +1212,6 @@ void RifReaderEclipseOutput::readWellCells(const ecl_grid_type* mainEclGrid, boo double accLengthFromLastConnection = 0; int segmentIdBelow = -1; bool segmentBelowHasConnections = false; - std::set ertSegIdsOfPosContribToRemove; - while (segment && branchId == well_segment_get_branch_id(segment)) { @@ -1493,7 +1488,6 @@ void RifReaderEclipseOutput::readWellCells(const ecl_grid_type* mainEclGrid, boo for (size_t bIdx = 0; bIdx < wellResFrame.m_wellResultBranches.size(); ++bIdx) { RigWellResultBranch& wellResultBranch = wellResFrame.m_wellResultBranches[ bIdx]; - bool previousResultPointWasCell = false; for (size_t rpIdx = 0; rpIdx < wellResultBranch.m_branchResultPoints.size(); ++rpIdx) { RigWellResultPoint & resPoint = wellResultBranch.m_branchResultPoints[rpIdx]; @@ -1612,11 +1606,9 @@ QStringList RifReaderEclipseOutput::validKeywordsForPorosityModel(const QStringL for (int i = 0; i < keywords.size(); i++) { QString keyword = keywords[i]; - size_t keywordDataCount = keywordDataItemCounts[i]; if (activeCellInfo->reservoirActiveCellCount() > 0) { - size_t timeStepsAllCells = keywordDataItemCounts[i] / activeCellInfo->reservoirCellCount(); size_t timeStepsAllCellsRest = keywordDataItemCounts[i] % activeCellInfo->reservoirCellCount(); size_t timeStepsMatrix = keywordDataItemCounts[i] / activeCellInfo->reservoirActiveCellCount(); @@ -1678,7 +1670,6 @@ void RifReaderEclipseOutput::extractResultValuesBasedOnPorosityModel(PorosityMod { RigActiveCellInfo* actCellInfo = m_eclipseCase->activeCellInfo(RifReaderInterface::MATRIX_RESULTS); - size_t dataItemCount = 0; size_t sourceStartPosition = 0; for (size_t i = 0; i < m_eclipseCase->mainGrid()->gridCount(); i++) diff --git a/ApplicationCode/FileInterface/RifReaderMockModel.cpp b/ApplicationCode/FileInterface/RifReaderMockModel.cpp index 0db76f7f25..b12a2281ba 100644 --- a/ApplicationCode/FileInterface/RifReaderMockModel.cpp +++ b/ApplicationCode/FileInterface/RifReaderMockModel.cpp @@ -18,8 +18,6 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RiaStdInclude.h" - #include "RifReaderMockModel.h" #include "RigCaseCellResultsData.h" #include "RifReaderInterface.h" diff --git a/ApplicationCode/FileInterface/RifReaderSettings.cpp b/ApplicationCode/FileInterface/RifReaderSettings.cpp index f221b6fdaa..0e257837bf 100644 --- a/ApplicationCode/FileInterface/RifReaderSettings.cpp +++ b/ApplicationCode/FileInterface/RifReaderSettings.cpp @@ -32,13 +32,13 @@ RifReaderSettings::RifReaderSettings() CAF_PDM_InitObject("RifReaderSettings", "", "", ""); CAF_PDM_InitField(&importFaults, "importFaults", true, "Import faults", "", "", ""); - importFaults.setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN); + importFaults.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN); CAF_PDM_InitField(&importNNCs, "importSimulationNNCs", true, "Import NNCs", "", "", ""); - importNNCs.setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN); + importNNCs.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN); CAF_PDM_InitField(&importAdvancedMswData, "importAdvancedMswData", false, "Import advanced MSW data", "", "", ""); - importAdvancedMswData.setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN); + importAdvancedMswData.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN); } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/GeoMech/GeoMechDataModel/RigFemNativeStatCalc.h b/ApplicationCode/GeoMech/GeoMechDataModel/RigFemNativeStatCalc.h index c351594f0d..269083a74e 100644 --- a/ApplicationCode/GeoMech/GeoMechDataModel/RigFemNativeStatCalc.h +++ b/ApplicationCode/GeoMech/GeoMechDataModel/RigFemNativeStatCalc.h @@ -35,15 +35,15 @@ class RigFemNativeStatCalc : public RigStatisticsCalculator public: RigFemNativeStatCalc(RigFemPartResultsCollection* femResultCollection, const RigFemResultAddress& resVarAddr); - virtual void minMaxCellScalarValues(size_t timeStepIndex, double& min, double& max); - virtual void posNegClosestToZero(size_t timeStepIndex, double& pos, double& neg); - virtual void valueSumAndSampleCount(double& valueSum, size_t& sampleCount); + virtual void minMaxCellScalarValues(size_t timeStepIndex, double& min, double& max); + virtual void posNegClosestToZero(size_t timeStepIndex, double& pos, double& neg); + virtual void valueSumAndSampleCount(double& valueSum, size_t& sampleCount); - virtual void addDataToHistogramCalculator(RigHistogramCalculator& histogramCalculator); + virtual void addDataToHistogramCalculator(RigHistogramCalculator& histogramCalculator); virtual size_t timeStepCount(); private: - RigFemPartResultsCollection* m_resultsData; + RigFemPartResultsCollection* m_resultsData; RigFemResultAddress m_resVarAddr; }; diff --git a/ApplicationCode/GeoMech/GeoMechDataModel/RigFemPart.cpp b/ApplicationCode/GeoMech/GeoMechDataModel/RigFemPart.cpp index 7fdea55199..56c941da84 100644 --- a/ApplicationCode/GeoMech/GeoMechDataModel/RigFemPart.cpp +++ b/ApplicationCode/GeoMech/GeoMechDataModel/RigFemPart.cpp @@ -21,6 +21,7 @@ #include "RigFemPartGrid.h" #include "cvfBoundingBox.h" +#include "cvfBoundingBoxTree.h" //-------------------------------------------------------------------------------------------------- /// @@ -48,7 +49,7 @@ void RigFemPart::preAllocateElementStorage(int elementCount) m_elementTypes.reserve(elementCount); m_elementConnectivityStartIndices.reserve(elementCount); - m_allAlementConnectivities.reserve(elementCount*8); + m_allElementConnectivities.reserve(elementCount*8); } //-------------------------------------------------------------------------------------------------- @@ -58,19 +59,19 @@ void RigFemPart::appendElement(RigElementType elmType, int id, const int* connec { m_elementId.push_back(id); m_elementTypes.push_back(elmType); - m_elementConnectivityStartIndices.push_back(m_allAlementConnectivities.size()); + m_elementConnectivityStartIndices.push_back(m_allElementConnectivities.size()); int nodeCount = RigFemTypes::elmentNodeCount(elmType); for (int lnIdx = 0; lnIdx < nodeCount; ++lnIdx) { - m_allAlementConnectivities.push_back(connectivities[lnIdx]); + m_allElementConnectivities.push_back(connectivities[lnIdx]); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -const RigFemPartGrid* RigFemPart::structGrid() +const RigFemPartGrid* RigFemPart::structGrid() const { if (m_structGrid.isNull()) { @@ -249,7 +250,7 @@ void RigFemPart::calculateElmNeighbors() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -cvf::Vec3f RigFemPart::faceNormal(int elmIdx, int faceIdx) +cvf::Vec3f RigFemPart::faceNormal(int elmIdx, int faceIdx) const { const std::vector& nodeCoordinates = this->nodes().coordinates; @@ -295,7 +296,7 @@ float RigFemPart::characteristicElementSize() { RigElementType eType = this->elementType(elmIdx); - if (eType == HEX8) + if (eType == HEX8 || eType == HEX8P) { const int* elmentConn = this->connectivities(elmIdx); cvf::Vec3f nodePos0 = this->nodes().coordinates[elmentConn[0]]; @@ -338,3 +339,52 @@ cvf::BoundingBox RigFemPart::boundingBox() return m_boundingBox; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigFemPart::findIntersectingCells(const cvf::BoundingBox& inputBB, std::vector* elementIndices) const +{ + if (m_elementSearchTree.isNull()) + { + // build tree + + size_t elmCount = elementCount(); + + std::vector cellBoundingBoxes; + cellBoundingBoxes.resize(elmCount); + + for (size_t elmIdx = 0; elmIdx < elmCount; ++elmIdx) + { + const int* cellIndices = connectivities(elmIdx); + cvf::BoundingBox& cellBB = cellBoundingBoxes[elmIdx]; + cellBB.add(m_nodes.coordinates[cellIndices[0]]); + cellBB.add(m_nodes.coordinates[cellIndices[1]]); + cellBB.add(m_nodes.coordinates[cellIndices[2]]); + cellBB.add(m_nodes.coordinates[cellIndices[3]]); + cellBB.add(m_nodes.coordinates[cellIndices[4]]); + cellBB.add(m_nodes.coordinates[cellIndices[5]]); + cellBB.add(m_nodes.coordinates[cellIndices[6]]); + cellBB.add(m_nodes.coordinates[cellIndices[7]]); + } + + m_elementSearchTree = new cvf::BoundingBoxTree; + m_elementSearchTree->buildTreeFromBoundingBoxes(cellBoundingBoxes, NULL); + } + + m_elementSearchTree->findIntersections(inputBB, elementIndices); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +size_t RigFemPart::elementNodeResultCount() const +{ + int lastElmIdx = this->elementCount() - 1; + if (lastElmIdx < 0) return 0; + RigElementType elmType = this->elementType(lastElmIdx); + int elmNodeCount = RigFemTypes::elmentNodeCount(elmType); + size_t lastElmResultIdx = this->elementNodeResultIdx(lastElmIdx, elmNodeCount -1); + + return lastElmResultIdx + 1; +} + diff --git a/ApplicationCode/GeoMech/GeoMechDataModel/RigFemPart.h b/ApplicationCode/GeoMech/GeoMechDataModel/RigFemPart.h index 1e2763765f..2cf13f7bfc 100644 --- a/ApplicationCode/GeoMech/GeoMechDataModel/RigFemPart.h +++ b/ApplicationCode/GeoMech/GeoMechDataModel/RigFemPart.h @@ -30,13 +30,16 @@ class RigFemPartGrid; +namespace cvf +{ + class BoundingBoxTree; +} + class RigFemPartNodes { public: std::vector nodeIds; std::vector coordinates; - - }; class RigFemPart : public cvf::Object @@ -55,10 +58,11 @@ class RigFemPart : public cvf::Object int elmId(size_t elementIdx) const { return m_elementId[elementIdx]; } RigElementType elementType(size_t elementIdx) const { return m_elementTypes[elementIdx]; } - const int* connectivities(size_t elementIdx) const { return &m_allAlementConnectivities[m_elementConnectivityStartIndices[elementIdx]];} + const int* connectivities(size_t elementIdx) const { return &m_allElementConnectivities[m_elementConnectivityStartIndices[elementIdx]];} size_t elementNodeResultIdx(int elementIdx, int elmLocalNodeIdx) const { return m_elementConnectivityStartIndices[elementIdx] + elmLocalNodeIdx;} - int nodeIdxFromElementNodeResultIdx(size_t elmNodeResultIdx) const { return m_allAlementConnectivities[elmNodeResultIdx]; } + size_t elementNodeResultCount() const; + int nodeIdxFromElementNodeResultIdx(size_t elmNodeResultIdx) const { return m_allElementConnectivities[elmNodeResultIdx]; } RigFemPartNodes& nodes() {return m_nodes;} const RigFemPartNodes& nodes() const {return m_nodes;} @@ -76,10 +80,11 @@ class RigFemPart : public cvf::Object cvf::BoundingBox boundingBox(); float characteristicElementSize(); const std::vector& possibleGridCornerElements() const { return m_possibleGridCornerElements; } + void findIntersectingCells(const cvf::BoundingBox& inputBB, std::vector* elementIndices) const; - cvf::Vec3f faceNormal(int elmentIndex, int faceIndex); + cvf::Vec3f faceNormal(int elmentIndex, int faceIndex) const; - const RigFemPartGrid* structGrid(); + const RigFemPartGrid* structGrid() const; private: int m_elementPartId; @@ -87,11 +92,11 @@ class RigFemPart : public cvf::Object std::vector m_elementId; std::vector m_elementTypes; std::vector m_elementConnectivityStartIndices; - std::vector m_allAlementConnectivities; + std::vector m_allElementConnectivities; RigFemPartNodes m_nodes; - cvf::ref m_structGrid; + mutable cvf::ref m_structGrid; void calculateNodeToElmRefs(); std::vector > m_nodeToElmRefs; // Needs a more memory friendly structure @@ -104,4 +109,6 @@ class RigFemPart : public cvf::Object float m_characteristicElementSize; cvf::BoundingBox m_boundingBox; + mutable cvf::ref m_elementSearchTree; + }; diff --git a/ApplicationCode/GeoMech/GeoMechDataModel/RigFemPartGrid.cpp b/ApplicationCode/GeoMech/GeoMechDataModel/RigFemPartGrid.cpp index 27eddfdb6f..c877f4ada5 100644 --- a/ApplicationCode/GeoMech/GeoMechDataModel/RigFemPartGrid.cpp +++ b/ApplicationCode/GeoMech/GeoMechDataModel/RigFemPartGrid.cpp @@ -26,7 +26,7 @@ //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RigFemPartGrid::RigFemPartGrid(RigFemPart* femPart) +RigFemPartGrid::RigFemPartGrid(const RigFemPart* femPart) { m_femPart = femPart; generateStructGridData(); @@ -172,6 +172,16 @@ void RigFemPartGrid::generateStructGridData() if (kCoord > static_cast(m_elmentIJKCounts[2])) m_elmentIJKCounts[2] = kCoord; } + + + + m_elmIdxPrIJK.resize(m_elmentIJKCounts[0], m_elmentIJKCounts[1],m_elmentIJKCounts[2]); + + for (int elmIdx = 0; elmIdx < m_femPart->elementCount(); ++elmIdx) + { + cvf::Vec3i ijk = m_ijkPrElement[elmIdx]; + m_elmIdxPrIJK.at(ijk[0], ijk[1], ijk[2]) = elmIdx; + } } //-------------------------------------------------------------------------------------------------- @@ -188,8 +198,8 @@ int RigFemPartGrid::findElmIdxForIJK000() cvf::Vec3i ijkMainFaceIndices = findMainIJKFaces(elmIdx); if ( m_femPart->elementNeighbor(elmIdx, ijkMainFaceIndices[0]) != -1 - && m_femPart->elementNeighbor(elmIdx, ijkMainFaceIndices[0]) != -1 - && m_femPart->elementNeighbor(elmIdx, ijkMainFaceIndices[0]) != -1 ) + && m_femPart->elementNeighbor(elmIdx, ijkMainFaceIndices[1]) != -1 + && m_femPart->elementNeighbor(elmIdx, ijkMainFaceIndices[2]) != -1 ) { return elmIdx; } @@ -201,7 +211,7 @@ int RigFemPartGrid::findElmIdxForIJK000() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -cvf::Vec3i RigFemPartGrid::findMainIJKFaces(int elementIndex) +cvf::Vec3i RigFemPartGrid::findMainIJKFaces(int elementIndex) const { cvf::Vec3i ijkMainFaceIndices = cvf::Vec3i(-1, -1, -1); @@ -216,7 +226,7 @@ cvf::Vec3i RigFemPartGrid::findMainIJKFaces(int elementIndex) // Record three independent main direction vectors for the element, and what face they are created from cvf::Vec3f mainElmDirections[3]; int mainElmDirOriginFaces[3]; - if (eType == HEX8) + if (eType == HEX8 || eType == HEX8P) { mainElmDirections[0] = normals[0] - normals[1]; // To get a better "average" direction vector mainElmDirections[1] = normals[2] - normals[3]; @@ -380,8 +390,7 @@ bool RigFemPartGrid::cellIJKNeighbor(size_t i, size_t j, size_t k, FaceType face //-------------------------------------------------------------------------------------------------- size_t RigFemPartGrid::cellIndexFromIJK(size_t i, size_t j, size_t k) const { - CVF_ASSERT(false); - return cvf::UNDEFINED_SIZE_T; + return m_elmIdxPrIJK.at(i,j,k); } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/GeoMech/GeoMechDataModel/RigFemPartGrid.h b/ApplicationCode/GeoMech/GeoMechDataModel/RigFemPartGrid.h index c56422677b..4b775cdaa2 100644 --- a/ApplicationCode/GeoMech/GeoMechDataModel/RigFemPartGrid.h +++ b/ApplicationCode/GeoMech/GeoMechDataModel/RigFemPartGrid.h @@ -27,19 +27,35 @@ class RigFemPart; class RigFemPartGrid : public cvf::StructGridInterface { public: - RigFemPartGrid(RigFemPart* femPart); + RigFemPartGrid(const RigFemPart* femPart); virtual ~RigFemPartGrid(); + virtual bool ijkFromCellIndex(size_t cellIndex, size_t* i, size_t* j, size_t* k) const; + virtual size_t cellIndexFromIJK(size_t i, size_t j, size_t k) const; + virtual size_t gridPointCountI() const; virtual size_t gridPointCountJ() const; virtual size_t gridPointCountK() const; + + cvf::Vec3i findMainIJKFaces(int elementIndex) const; + + private: + void generateStructGridData(); + int findElmIdxForIJK000(); + int perpendicularFaceInDirection(cvf::Vec3f direction, int perpFaceIdx, int elmIdx); + const RigFemPart* m_femPart; + + std::vector m_ijkPrElement; + cvf::Vec3st m_elmentIJKCounts; + +private: // Unused, Not implemented virtual bool isCellValid(size_t i, size_t j, size_t k) const; virtual cvf::Vec3d minCoordinate() const; virtual cvf::Vec3d maxCoordinate() const; virtual bool cellIJKNeighbor(size_t i, size_t j, size_t k, FaceType face, size_t* neighborCellIndex) const; - virtual size_t cellIndexFromIJK(size_t i, size_t j, size_t k) const; - virtual bool ijkFromCellIndex(size_t cellIndex, size_t* i, size_t* j, size_t* k) const; + + virtual bool cellIJKFromCoordinate(const cvf::Vec3d& coord, size_t* i, size_t* j, size_t* k) const; virtual void cellCornerVertices(size_t cellIndex, cvf::Vec3d vertices[8]) const; virtual cvf::Vec3d cellCentroid(size_t cellIndex) const; @@ -47,19 +63,36 @@ class RigFemPartGrid : public cvf::StructGridInterface virtual size_t gridPointIndexFromIJK(size_t i, size_t j, size_t k) const; virtual cvf::Vec3d gridPointCoordinate(size_t i, size_t j, size_t k) const; - - private: - void generateStructGridData(); - - cvf::Vec3i findMainIJKFaces(int elementIndex); - - int findElmIdxForIJK000(); - - int perpendicularFaceInDirection(cvf::Vec3f direction, int perpFaceIdx, int elmIdx); - RigFemPart* m_femPart; - - std::vector m_ijkPrElement; - cvf::Vec3st m_elmentIJKCounts; + class IJKArray + { + public: + IJKArray(): m_iCount(0), m_jCount(0){} + + void resize(size_t iCount, size_t jCount, size_t kCount) + { + data.resize(iCount*jCount*kCount, cvf::UNDEFINED_SIZE_T); + m_iCount = iCount; + m_jCount = jCount; + } + + size_t& at(size_t i, size_t j, size_t k) + { + return data[i + j* m_iCount + k * m_iCount*m_jCount]; + } + + size_t at(size_t i, size_t j, size_t k) const + { + return data[i + j* m_iCount + k * m_iCount*m_jCount]; + } + + private: + size_t m_iCount; + size_t m_jCount; + + std::vector< size_t > data; + }; + + IJKArray m_elmIdxPrIJK; }; diff --git a/ApplicationCode/GeoMech/GeoMechDataModel/RigFemPartResultsCollection.cpp b/ApplicationCode/GeoMech/GeoMechDataModel/RigFemPartResultsCollection.cpp index b56f1793a0..8421d1dcc4 100644 --- a/ApplicationCode/GeoMech/GeoMechDataModel/RigFemPartResultsCollection.cpp +++ b/ApplicationCode/GeoMech/GeoMechDataModel/RigFemPartResultsCollection.cpp @@ -156,6 +156,7 @@ std::map > RigFemPartResultsCollection::sc if (resPos == RIG_NODAL) { fieldCompNames = m_readerInterface->scalarNodeFieldAndComponentNames(); + fieldCompNames["POR-Bar"]; } else if (resPos == RIG_ELEMENT_NODAL) { @@ -193,6 +194,7 @@ std::map > RigFemPartResultsCollection::sc fieldCompNames["NE"].push_back("E12"); fieldCompNames["NE"].push_back("E13"); fieldCompNames["NE"].push_back("E23"); + } else if (resPos == RIG_INTEGRATION_POINT) { @@ -230,17 +232,100 @@ std::map > RigFemPartResultsCollection::sc fieldCompNames["NE"].push_back("E12"); fieldCompNames["NE"].push_back("E13"); fieldCompNames["NE"].push_back("E23"); + } } return fieldCompNames; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigFemScalarResultFrames* RigFemPartResultsCollection::calculateBarConvertedResult(int partIndex, const RigFemResultAddress &convertedResultAddr, const std::string fieldNameToConvert) +{ + RigFemScalarResultFrames * srcDataFrames = this->findOrLoadScalarResult(partIndex, RigFemResultAddress(convertedResultAddr.resultPosType, fieldNameToConvert, convertedResultAddr.componentName)); + RigFemScalarResultFrames * dstDataFrames = m_femPartResults[partIndex]->createScalarResult(convertedResultAddr); + + int frameCount = srcDataFrames->frameCount(); + for (int fIdx = 0; fIdx < frameCount; ++fIdx) + { + const std::vector& srcFrameData = srcDataFrames->frameData(fIdx); + std::vector& dstFrameData = dstDataFrames->frameData(fIdx); + size_t valCount = srcFrameData.size(); + dstFrameData.resize(valCount); + + for (size_t vIdx = 0; vIdx < valCount; ++vIdx) + { + dstFrameData[vIdx] = 1.0e-5*srcFrameData[vIdx]; + } + } + + return dstDataFrames; +} + +//-------------------------------------------------------------------------------------------------- +/// Convert POR NODAL result to POR-Bar Elment Nodal result +//-------------------------------------------------------------------------------------------------- +RigFemScalarResultFrames* RigFemPartResultsCollection::calculateEnIpPorBarResult(int partIndex, const RigFemResultAddress &convertedResultAddr) +{ + RigFemScalarResultFrames * srcDataFrames = this->findOrLoadScalarResult(partIndex, RigFemResultAddress(RIG_NODAL, "POR", "")); + RigFemScalarResultFrames * dstDataFrames = m_femPartResults[partIndex]->createScalarResult(convertedResultAddr); + + const RigFemPart * femPart = m_femParts->part(partIndex); + float inf = std::numeric_limits::infinity(); + + int frameCount = srcDataFrames->frameCount(); + for (int fIdx = 0; fIdx < frameCount; ++fIdx) + { + const std::vector& srcFrameData = srcDataFrames->frameData(fIdx); + std::vector& dstFrameData = dstDataFrames->frameData(fIdx); + + if (!srcFrameData.size()) continue; // Create empty results if we have no POR result. + + size_t valCount = femPart->elementNodeResultCount(); + dstFrameData.resize(valCount, inf); + + int elementCount = femPart->elementCount(); + for (int elmIdx = 0; elmIdx < elementCount; ++elmIdx) + { + RigElementType elmType = femPart->elementType(elmIdx); + + int elmNodeCount = RigFemTypes::elmentNodeCount(elmType); + + if (elmType == HEX8P) + { + for (int elmNodIdx = 0; elmNodIdx < elmNodeCount; ++elmNodIdx) + { + size_t elmNodResIdx = femPart->elementNodeResultIdx(elmIdx, elmNodIdx); + int nodeIdx = femPart->nodeIdxFromElementNodeResultIdx(elmNodResIdx); + dstFrameData[elmNodResIdx] = 1.0e-5*srcFrameData[nodeIdx]; + } + } + } + } + + return dstDataFrames; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RigFemScalarResultFrames* RigFemPartResultsCollection::calculateDerivedResult(int partIndex, const RigFemResultAddress& resVarAddr) { + if (resVarAddr.fieldName == "S-Bar") + { + return calculateBarConvertedResult(partIndex, resVarAddr, "S"); + } + + if (resVarAddr.fieldName == "POR-Bar") + { + if (resVarAddr.resultPosType == RIG_NODAL) + return calculateBarConvertedResult(partIndex, resVarAddr, "POR"); + else + return calculateEnIpPorBarResult(partIndex, resVarAddr); + } + if (resVarAddr.fieldName == "NE") { RigFemScalarResultFrames * srcDataFrames = this->findOrLoadScalarResult(partIndex, RigFemResultAddress(resVarAddr.resultPosType, "E", resVarAddr.componentName)); @@ -264,10 +349,10 @@ RigFemScalarResultFrames* RigFemPartResultsCollection::calculateDerivedResult(in } if ((resVarAddr.fieldName == "SE") - && !(resVarAddr.componentName == "S1" || resVarAddr.componentName == "S2" || resVarAddr.componentName == "S3" )) + && !(resVarAddr.componentName == "S1" || resVarAddr.componentName == "S2" || resVarAddr.componentName == "S3" || resVarAddr.componentName == "")) { - RigFemScalarResultFrames * srcDataFrames = this->findOrLoadScalarResult(partIndex, RigFemResultAddress(resVarAddr.resultPosType, "S", resVarAddr.componentName)); - RigFemScalarResultFrames * srcPORDataFrames = this->findOrLoadScalarResult(partIndex, RigFemResultAddress(RIG_NODAL, "POR", "")); + RigFemScalarResultFrames * srcDataFrames = this->findOrLoadScalarResult(partIndex, RigFemResultAddress(resVarAddr.resultPosType, "S-Bar", resVarAddr.componentName)); + RigFemScalarResultFrames * srcPORDataFrames = this->findOrLoadScalarResult(partIndex, RigFemResultAddress(RIG_NODAL, "POR-Bar", "")); RigFemScalarResultFrames * dstDataFrames = m_femPartResults[partIndex]->createScalarResult(resVarAddr); const RigFemPart * femPart = m_femParts->part(partIndex); @@ -276,23 +361,37 @@ RigFemScalarResultFrames* RigFemPartResultsCollection::calculateDerivedResult(in int frameCount = srcDataFrames->frameCount(); for (int fIdx = 0; fIdx < frameCount; ++fIdx) { - const std::vector& srcFrameData = srcDataFrames->frameData(fIdx); + const std::vector& srcSFrameData = srcDataFrames->frameData(fIdx); std::vector& dstFrameData = dstDataFrames->frameData(fIdx); - size_t valCount = srcFrameData.size(); + size_t valCount = srcSFrameData.size(); dstFrameData.resize(valCount); const std::vector& srcPORFrameData = srcPORDataFrames->frameData(fIdx); - int nodeIdx = 0; - for (size_t vIdx = 0; vIdx < valCount; ++vIdx) + int elementCount = femPart->elementCount(); + for (int elmIdx = 0; elmIdx < elementCount; ++elmIdx) { - nodeIdx = femPart->nodeIdxFromElementNodeResultIdx(vIdx); - float por = srcPORFrameData[nodeIdx]; + RigElementType elmType = femPart->elementType(elmIdx); - if (por == inf) - dstFrameData[vIdx] = inf; - else - dstFrameData[vIdx] = -srcFrameData[vIdx]; + int elmNodeCount = RigFemTypes::elmentNodeCount(femPart->elementType(elmIdx)); + + if (elmType == HEX8P) + { + for (int elmNodIdx = 0; elmNodIdx < elmNodeCount; ++elmNodIdx) + { + size_t elmNodResIdx = femPart->elementNodeResultIdx(elmIdx, elmNodIdx); + dstFrameData[elmNodResIdx] = -srcSFrameData[elmNodResIdx]; + } + } + else + { + for (int elmNodIdx = 0; elmNodIdx < elmNodeCount; ++elmNodIdx) + { + size_t elmNodResIdx = femPart->elementNodeResultIdx(elmIdx, elmNodIdx); + + dstFrameData[elmNodResIdx] = inf; + } + } } } @@ -354,28 +453,53 @@ RigFemScalarResultFrames* RigFemPartResultsCollection::calculateDerivedResult(in || resVarAddr.componentName == "S22" || resVarAddr.componentName == "S33" )) { - RigFemScalarResultFrames * srcNSDataFrames = this->findOrLoadScalarResult(partIndex, RigFemResultAddress(resVarAddr.resultPosType, "S", resVarAddr.componentName)); - RigFemScalarResultFrames * srcPORDataFrames = this->findOrLoadScalarResult(partIndex, RigFemResultAddress(RIG_NODAL, "POR", "")); + RigFemScalarResultFrames * srcSDataFrames = this->findOrLoadScalarResult(partIndex, RigFemResultAddress(resVarAddr.resultPosType, "S-Bar", resVarAddr.componentName)); + RigFemScalarResultFrames * srcPORDataFrames = this->findOrLoadScalarResult(partIndex, RigFemResultAddress(RIG_NODAL, "POR-Bar", "")); RigFemScalarResultFrames * dstDataFrames = m_femPartResults[partIndex]->createScalarResult(resVarAddr); const RigFemPart * femPart = m_femParts->part(partIndex); - int frameCount = srcNSDataFrames->frameCount(); + int frameCount = srcSDataFrames->frameCount(); + + const float inf = std::numeric_limits::infinity(); + for (int fIdx = 0; fIdx < frameCount; ++fIdx) { - const std::vector& srcNSFrameData = srcNSDataFrames->frameData(fIdx); + const std::vector& srcSFrameData = srcSDataFrames->frameData(fIdx); const std::vector& srcPORFrameData = srcPORDataFrames->frameData(fIdx); std::vector& dstFrameData = dstDataFrames->frameData(fIdx); - size_t valCount = srcNSFrameData.size(); + size_t valCount = srcSFrameData.size(); dstFrameData.resize(valCount); - int nodeIdx = 0; - for (size_t vIdx = 0; vIdx < valCount; ++vIdx) + + int elementCount = femPart->elementCount(); + for (int elmIdx = 0; elmIdx < elementCount; ++elmIdx) { - nodeIdx = femPart->nodeIdxFromElementNodeResultIdx(vIdx); - float por = srcPORFrameData[nodeIdx]; - if (por == std::numeric_limits::infinity()) por = 0.0f; - dstFrameData[vIdx] = -srcNSFrameData[vIdx] + por; + RigElementType elmType = femPart->elementType(elmIdx); + + int elmNodeCount = RigFemTypes::elmentNodeCount(femPart->elementType(elmIdx)); + + if (elmType == HEX8P) + { + for (int elmNodIdx = 0; elmNodIdx < elmNodeCount; ++elmNodIdx) + { + size_t elmNodResIdx = femPart->elementNodeResultIdx(elmIdx, elmNodIdx); + int nodeIdx = femPart->nodeIdxFromElementNodeResultIdx(elmNodResIdx); + + float por = srcPORFrameData[nodeIdx]; + if (por == inf) por = 0.0f; + + dstFrameData[elmNodResIdx] = -srcSFrameData[elmNodResIdx] + por; + } + } + else + { + for (int elmNodIdx = 0; elmNodIdx < elmNodeCount; ++elmNodIdx) + { + size_t elmNodResIdx = femPart->elementNodeResultIdx(elmIdx, elmNodIdx); + dstFrameData[elmNodResIdx] = -srcSFrameData[elmNodResIdx]; + } + } } } return dstDataFrames; @@ -386,22 +510,20 @@ RigFemScalarResultFrames* RigFemPartResultsCollection::calculateDerivedResult(in || resVarAddr.componentName == "S13" || resVarAddr.componentName == "S23" )) { - RigFemScalarResultFrames * srcSDataFrames = this->findOrLoadScalarResult(partIndex, RigFemResultAddress(resVarAddr.resultPosType, "S", resVarAddr.componentName)); + RigFemScalarResultFrames * srcSDataFrames = this->findOrLoadScalarResult(partIndex, RigFemResultAddress(resVarAddr.resultPosType, "S-Bar", resVarAddr.componentName)); RigFemScalarResultFrames * dstDataFrames = m_femPartResults[partIndex]->createScalarResult(resVarAddr); - const RigFemPart * femPart = m_femParts->part(partIndex); int frameCount = srcSDataFrames->frameCount(); for (int fIdx = 0; fIdx < frameCount; ++fIdx) { - const std::vector& srcNSFrameData = srcSDataFrames->frameData(fIdx); + const std::vector& srcSFrameData = srcSDataFrames->frameData(fIdx); std::vector& dstFrameData = dstDataFrames->frameData(fIdx); - size_t valCount = srcNSFrameData.size(); + size_t valCount = srcSFrameData.size(); dstFrameData.resize(valCount); - int nodeIdx = 0; for (size_t vIdx = 0; vIdx < valCount; ++vIdx) { - dstFrameData[vIdx] = -srcNSFrameData[vIdx]; + dstFrameData[vIdx] = -srcSFrameData[vIdx]; } } return dstDataFrames; @@ -438,7 +560,7 @@ RigFemScalarResultFrames* RigFemPartResultsCollection::calculateDerivedResult(in srcDataFrames = this->findOrLoadScalarResult(partIndex, RigFemResultAddress(resVarAddr.resultPosType, "ST", "S33")); } - RigFemScalarResultFrames * srcPORDataFrames = this->findOrLoadScalarResult(partIndex, RigFemResultAddress(RIG_NODAL, "POR", "")); + RigFemScalarResultFrames * srcPORDataFrames = this->findOrLoadScalarResult(partIndex, RigFemResultAddress(RIG_NODAL, "POR-Bar", "")); RigFemScalarResultFrames * dstDataFrames = m_femPartResults[partIndex]->createScalarResult(resVarAddr); @@ -455,16 +577,37 @@ RigFemScalarResultFrames* RigFemPartResultsCollection::calculateDerivedResult(in size_t valCount = srcSTFrameData.size(); dstFrameData.resize(valCount); - int nodeIdx = 0; - for (size_t vIdx = 0; vIdx < valCount; ++vIdx) + + int elementCount = femPart->elementCount(); + for (int elmIdx = 0; elmIdx < elementCount; ++elmIdx) { - nodeIdx = femPart->nodeIdxFromElementNodeResultIdx(vIdx); - float por = srcPORFrameData[nodeIdx]; + RigElementType elmType = femPart->elementType(elmIdx); + + int elmNodeCount = RigFemTypes::elmentNodeCount(femPart->elementType(elmIdx)); - if (por == inf || abs(por) < 0.01e6) - dstFrameData[vIdx] = inf; + if (elmType == HEX8P) + { + for (int elmNodIdx = 0; elmNodIdx < elmNodeCount; ++elmNodIdx) + { + size_t elmNodResIdx = femPart->elementNodeResultIdx(elmIdx, elmNodIdx); + int nodeIdx = femPart->nodeIdxFromElementNodeResultIdx(elmNodResIdx); + + float por = srcPORFrameData[nodeIdx]; + + if (por == inf || abs(por) < 0.01e6*1.0e-5) + dstFrameData[elmNodResIdx] = inf; + else + dstFrameData[elmNodResIdx] = srcSTFrameData[elmNodResIdx]/por; + } + } else - dstFrameData[vIdx] = srcSTFrameData[vIdx]/por; + { + for (int elmNodIdx = 0; elmNodIdx < elmNodeCount; ++elmNodIdx) + { + size_t elmNodResIdx = femPart->elementNodeResultIdx(elmIdx, elmNodIdx); + dstFrameData[elmNodResIdx] = inf; + } + } } } return dstDataFrames; diff --git a/ApplicationCode/GeoMech/GeoMechDataModel/RigFemPartResultsCollection.h b/ApplicationCode/GeoMech/GeoMechDataModel/RigFemPartResultsCollection.h index a3daf3db0e..48dd83b91e 100644 --- a/ApplicationCode/GeoMech/GeoMechDataModel/RigFemPartResultsCollection.h +++ b/ApplicationCode/GeoMech/GeoMechDataModel/RigFemPartResultsCollection.h @@ -61,6 +61,9 @@ class RigFemPartResultsCollection: public cvf::Object RigFemScalarResultFrames* calculateDerivedResult(int partIndex, const RigFemResultAddress& resVarAddr); + RigFemScalarResultFrames* calculateBarConvertedResult(int partIndex, const RigFemResultAddress &convertedResultAddr, const std::string fieldNameToConvert); + RigFemScalarResultFrames* calculateEnIpPorBarResult(int partIndex, const RigFemResultAddress &convertedResultAddr); + friend class RigFemNativeStatCalc; cvf::Collection m_femPartResults; cvf::ref m_readerInterface; diff --git a/ApplicationCode/GeoMech/GeoMechDataModel/RigFemTypes.cpp b/ApplicationCode/GeoMech/GeoMechDataModel/RigFemTypes.cpp index a25f66ab9f..566d09f74c 100644 --- a/ApplicationCode/GeoMech/GeoMechDataModel/RigFemTypes.cpp +++ b/ApplicationCode/GeoMech/GeoMechDataModel/RigFemTypes.cpp @@ -27,7 +27,7 @@ //-------------------------------------------------------------------------------------------------- int RigFemTypes::elmentNodeCount(RigElementType elmType) { - static int elementTypeCounts[2] ={ 8, 4 }; + static int elementTypeCounts[3] ={ 8, 8, 4 }; return elementTypeCounts[elmType]; } @@ -37,7 +37,7 @@ int RigFemTypes::elmentNodeCount(RigElementType elmType) //-------------------------------------------------------------------------------------------------- int RigFemTypes::elmentFaceCount(RigElementType elmType) { - const static int elementFaceCounts[2] ={ 6, 1 }; + const static int elementFaceCounts[3] ={ 6, 6, 1 }; return elementFaceCounts[elmType]; } @@ -46,7 +46,7 @@ int RigFemTypes::elmentFaceCount(RigElementType elmType) /// //-------------------------------------------------------------------------------------------------- // HEX8 -// 7---------6 +// 7---------6 Increased k -> Increased depth : 4 5 6 7 is the deepest quad // /| /| |k // / | / | | /j // 4---------5 | |/ @@ -63,6 +63,7 @@ const int* RigFemTypes::localElmNodeIndicesForFace(RigElementType elmType, int f switch (elmType) { case HEX8: + case HEX8P: (*faceNodeCount) = 4; return HEX8_Faces[faceIdx]; break; @@ -85,6 +86,7 @@ int RigFemTypes::oppositeFace(RigElementType elmType, int faceIdx) switch (elmType) { case HEX8: + case HEX8P: return HEX8_OppositeFaces[faceIdx]; break; case CAX4: @@ -97,3 +99,28 @@ int RigFemTypes::oppositeFace(RigElementType elmType, int faceIdx) return faceIdx; } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- + +const int* RigFemTypes::localElmNodeToIntegrationPointMapping(RigElementType elmType) +{ + static const int HEX8_Mapping[8] ={ 0, 1, 3, 2, 4, 5, 7, 6 }; + + switch (elmType) + { + case HEX8: + case HEX8P: + return HEX8_Mapping; + break; + case CAX4: + return HEX8_Mapping; // First four is identical to HEX8 + break; + default: + assert(false); // Element type not supported + break; + } + + return HEX8_Mapping; +} diff --git a/ApplicationCode/GeoMech/GeoMechDataModel/RigFemTypes.h b/ApplicationCode/GeoMech/GeoMechDataModel/RigFemTypes.h index 926af7981f..eb9a70dfcb 100644 --- a/ApplicationCode/GeoMech/GeoMechDataModel/RigFemTypes.h +++ b/ApplicationCode/GeoMech/GeoMechDataModel/RigFemTypes.h @@ -23,6 +23,7 @@ enum RigElementType { HEX8, + HEX8P, CAX4, UNKNOWN_ELM_TYPE }; @@ -34,4 +35,5 @@ class RigFemTypes static int elmentFaceCount(RigElementType elmType); static const int* localElmNodeIndicesForFace(RigElementType elmType, int faceIdx, int* faceNodeCount); static int oppositeFace(RigElementType elmType, int faceIdx); + static const int* localElmNodeToIntegrationPointMapping(RigElementType elmType); }; diff --git a/ApplicationCode/GeoMech/GeoMechVisualization/RivFemElmVisibilityCalculator.cpp b/ApplicationCode/GeoMech/GeoMechVisualization/RivFemElmVisibilityCalculator.cpp index 00694111b3..ba76a26724 100644 --- a/ApplicationCode/GeoMech/GeoMechVisualization/RivFemElmVisibilityCalculator.cpp +++ b/ApplicationCode/GeoMech/GeoMechVisualization/RivFemElmVisibilityCalculator.cpp @@ -32,6 +32,9 @@ #include "RigGeoMechCaseData.h" #include "RigFemPartResultsCollection.h" +#include "RimViewController.h" +#include "RimViewLinker.h" +#include "RigCaseToCaseCellMapper.h" //-------------------------------------------------------------------------------------------------- /// @@ -112,6 +115,9 @@ void RivFemElmVisibilityCalculator::computePropertyVisibility(cvf::UByteArray* c const double upperBound = propertyFilter->upperBound(); RigFemResultAddress resVarAddress = propertyFilter->resultDefinition->resultAddress(); + + // Do a "Hack" to use elm nodal and not nodal POR results + if (resVarAddress.resultPosType == RIG_NODAL && resVarAddress.fieldName == "POR-Bar") resVarAddress.resultPosType = RIG_ELEMENT_NODAL; size_t adjustedTimeStepIndex = timeStepIndex; @@ -166,3 +172,36 @@ void RivFemElmVisibilityCalculator::computePropertyVisibility(cvf::UByteArray* c } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RivFemElmVisibilityCalculator::computeOverriddenCellVisibility(cvf::UByteArray* elmVisibilities, + const RigFemPart* femPart, + RimViewController* masterViewLink) +{ + CVF_ASSERT(elmVisibilities != NULL); + CVF_ASSERT(femPart != NULL); + + RimView* masterView = masterViewLink->ownerViewLinker()->masterView(); + cvf::ref totCellVisibility = masterView->currentTotalCellVisibility(); + + int elmCount = femPart->elementCount(); + elmVisibilities->resize(elmCount); + elmVisibilities->setAll(false); + + const RigCaseToCaseCellMapper* cellMapper = masterViewLink->cellMapper(); + + for (int elmIdx = 0; elmIdx < elmCount; ++elmIdx) + { + // We are assuming that there is only one part. + int cellCount = 0; + const int* cellIndicesInMasterCase = cellMapper->masterCaseCellIndices(elmIdx, &cellCount); + + for (int mcIdx = 0; mcIdx < cellCount; ++mcIdx) + { + (*elmVisibilities)[elmIdx] |= (*totCellVisibility)[cellIndicesInMasterCase[mcIdx]]; // If any is visible, show + } + + } +} + diff --git a/ApplicationCode/GeoMech/GeoMechVisualization/RivFemElmVisibilityCalculator.h b/ApplicationCode/GeoMech/GeoMechVisualization/RivFemElmVisibilityCalculator.h index defd9f4f4f..adda2db74b 100644 --- a/ApplicationCode/GeoMech/GeoMechVisualization/RivFemElmVisibilityCalculator.h +++ b/ApplicationCode/GeoMech/GeoMechVisualization/RivFemElmVisibilityCalculator.h @@ -28,6 +28,7 @@ namespace cvf class RigFemPart; class RimGeoMechPropertyFilterCollection; +class RimViewController; class RivFemElmVisibilityCalculator { @@ -41,6 +42,11 @@ class RivFemElmVisibilityCalculator int timeStepIndex, const cvf::UByteArray* rangeFilterVisibility, RimGeoMechPropertyFilterCollection* propFilterColl); + + static void computeOverriddenCellVisibility(cvf::UByteArray* elmVisibilities, + const RigFemPart* femPart , + RimViewController* masterViewLink); + }; diff --git a/ApplicationCode/GeoMech/GeoMechVisualization/RivFemPartPartMgr.cpp b/ApplicationCode/GeoMech/GeoMechVisualization/RivFemPartPartMgr.cpp index b3dd11a0c1..cd3a140502 100644 --- a/ApplicationCode/GeoMech/GeoMechVisualization/RivFemPartPartMgr.cpp +++ b/ApplicationCode/GeoMech/GeoMechVisualization/RivFemPartPartMgr.cpp @@ -124,7 +124,7 @@ void RivFemPartPartMgr::generatePartGeometry(RivFemPartGeometryGenerator& geoBui // Set default effect caf::SurfaceEffectGenerator geometryEffgen(cvf::Color4f(cvf::Color3f::WHITE), caf::PO_1); - cvf::ref geometryOnlyEffect = geometryEffgen.generateEffect(); + cvf::ref geometryOnlyEffect = geometryEffgen.generateCachedEffect(); part->setEffect(geometryOnlyEffect.p()); part->setEnableMask(surfaceBit); m_surfaceFaces = part; @@ -154,7 +154,7 @@ void RivFemPartPartMgr::generatePartGeometry(RivFemPartGeometryGenerator& geoBui cvf::ref eff; caf::MeshEffectGenerator effGen(prefs->defaultGridLineColors()); - eff = effGen.generateEffect(); + eff = effGen.generateCachedEffect(); // Set priority to make sure fault lines are rendered first part->setPriority(10); @@ -186,7 +186,7 @@ void RivFemPartPartMgr::updateCellColor(cvf::Color4f color) // Set default effect caf::SurfaceEffectGenerator geometryEffgen(color, caf::PO_1); - cvf::ref geometryOnlyEffect = geometryEffgen.generateEffect(); + cvf::ref geometryOnlyEffect = geometryEffgen.generateCachedEffect(); if (m_surfaceFaces.notNull()) m_surfaceFaces->setEffect(geometryOnlyEffect.p()); @@ -206,7 +206,7 @@ void RivFemPartPartMgr::updateCellColor(cvf::Color4f color) if (m_surfaceFaces.notNull()) { caf::MeshEffectGenerator effGen(prefs->defaultGridLineColors()); - eff = effGen.generateEffect(); + eff = effGen.generateCachedEffect(); m_surfaceGridLines->setEffect(eff.p()); } } @@ -234,16 +234,19 @@ void RivFemPartPartMgr::updateCellResultColor(size_t timeStepIndex, RimGeoMechCe RigFemResultAddress resVarAddress = cellResultColors->resultAddress(); + // Do a "Hack" to show elm nodal and not nodal POR results + if (resVarAddress.resultPosType == RIG_NODAL && resVarAddress.fieldName == "POR-Bar") resVarAddress.resultPosType = RIG_ELEMENT_NODAL; + const std::vector& resultValues = caseData->femPartResults()->resultValues(resVarAddress, m_gridIdx, (int)timeStepIndex); const std::vector* vxToResultMapping = NULL; - if (cellResultColors->resultPositionType() == RIG_NODAL) + if (resVarAddress.resultPosType == RIG_NODAL) { vxToResultMapping = &(m_surfaceGenerator.quadVerticesToNodeIdxMapping()); } - else if ( cellResultColors->resultPositionType() == RIG_ELEMENT_NODAL - || cellResultColors->resultPositionType() == RIG_INTEGRATION_POINT) + else if ( resVarAddress.resultPosType == RIG_ELEMENT_NODAL + || resVarAddress.resultPosType == RIG_INTEGRATION_POINT) { vxToResultMapping = &(m_surfaceGenerator.quadVerticesToGlobalElmNodeIdx()); } @@ -288,7 +291,11 @@ void RivFemPartPartMgr::updateCellResultColor(size_t timeStepIndex, RimGeoMechCe } } - RivScalarMapperUtils::applyTextureResultsToPart(m_surfaceFaces.p(), m_surfaceFacesTextureCoords.p(), mapper, m_opacityLevel, caf::FC_NONE, cellResultColors->reservoirView()->isLightingDisabled()); + RimView* view = NULL; + cellResultColors->firstAnchestorOrThisOfType(view); + CVF_ASSERT(view); + + RivScalarMapperUtils::applyTextureResultsToPart(m_surfaceFaces.p(), m_surfaceFacesTextureCoords.p(), mapper, m_opacityLevel, caf::FC_NONE, view->isLightingDisabled()); } } diff --git a/ApplicationCode/GeoMech/GeoMechVisualization/RivGeoMechVizLogic.cpp b/ApplicationCode/GeoMech/GeoMechVisualization/RivGeoMechVizLogic.cpp index 4fef3878e9..e7d9f59231 100644 --- a/ApplicationCode/GeoMech/GeoMechVisualization/RivGeoMechVizLogic.cpp +++ b/ApplicationCode/GeoMech/GeoMechVisualization/RivGeoMechVizLogic.cpp @@ -34,6 +34,8 @@ #include "RivFemElmVisibilityCalculator.h" #include "RigFemPartResultsCollection.h" #include "RimGeoMechPropertyFilterCollection.h" +#include "RimView.h" +#include "RimViewController.h" //-------------------------------------------------------------------------------------------------- /// @@ -111,7 +113,11 @@ void RivGeoMechVizLogic::scheduleGeometryRegen(RivCellSetEnum geometryType) { this->scheduleRegenOfDirectlyDependentGeometry(geometryType); - int frameCount = m_geomechView->geoMechCase()->geoMechData()->femPartResults()->frameCount(); + int frameCount = 0; + if (m_geomechView->geoMechCase()->geoMechData()) + { + frameCount = m_geomechView->geoMechCase()->geoMechData()->femPartResults()->frameCount(); + } for (int fIdx = -1; fIdx < frameCount; ++fIdx) { @@ -134,8 +140,11 @@ void RivGeoMechVizLogic::scheduleRegenOfDirectlyDependentGeometry(RivCellSetEnum std::vector RivGeoMechVizLogic::keysToVisiblePartMgrs(int timeStepIndex) { std::vector visiblePartMgrs; - - if (timeStepIndex >= 0 && m_geomechView->propertyFilterCollection()->hasActiveFilters()) + if (m_geomechView->viewController() && m_geomechView->viewController()->isVisibleCellsOveridden()) + { + visiblePartMgrs.push_back(RivGeoMechPartMgrCache::Key(OVERRIDDEN_CELL_VISIBILITY, -1)); + } + else if (timeStepIndex >= 0 && m_geomechView->propertyFilterCollection()->hasActiveFilters()) { visiblePartMgrs.push_back(RivGeoMechPartMgrCache::Key(PROPERTY_FILTERED, timeStepIndex)); } @@ -203,6 +212,13 @@ RivGeoMechPartMgr* RivGeoMechVizLogic::getUpdatedPartMgr(RivGeoMechPartMgrCache: m_geomechView->propertyFilterCollection() ); } + else if (pMgrKey.geometryType() == OVERRIDDEN_CELL_VISIBILITY) + { + RivFemElmVisibilityCalculator::computeOverriddenCellVisibility(elmVisibility.p(), + caseData->femParts()->part(femPartIdx), + m_geomechView->viewController()); + } + else if (pMgrKey.geometryType() == ALL_CELLS) { RivFemElmVisibilityCalculator::computeAllVisible(elmVisibility.p(), caseData->femParts()->part(femPartIdx)); @@ -220,4 +236,32 @@ RivGeoMechPartMgr* RivGeoMechVizLogic::getUpdatedPartMgr(RivGeoMechPartMgrCache: return partMgrToUpdate; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RivGeoMechVizLogic::calculateCurrentTotalCellVisibility(cvf::UByteArray* totalVisibility, int timeStepIndex) +{ + size_t gridCount = m_geomechView->geoMechCase()->geoMechData()->femParts()->partCount(); + + if (gridCount == 0) return; + + RigFemPart* part = m_geomechView->geoMechCase()->geoMechData()->femParts()->part(0); + int elmCount = part->elementCount(); + + totalVisibility->resize(elmCount); + totalVisibility->setAll(false); + + std::vector visiblePartMgrs = keysToVisiblePartMgrs(timeStepIndex); + for (size_t pmIdx = 0; pmIdx < visiblePartMgrs.size(); ++pmIdx) + { + RivGeoMechPartMgr* partMgr = m_partMgrCache->partMgr(visiblePartMgrs[pmIdx]); + + cvf::ref visibility = partMgr->cellVisibility(0); + for (int elmIdx = 0; elmIdx < elmCount; ++ elmIdx) + { + (*totalVisibility)[elmIdx] |= (*visibility)[elmIdx]; + } + } +} + diff --git a/ApplicationCode/GeoMech/GeoMechVisualization/RivGeoMechVizLogic.h b/ApplicationCode/GeoMech/GeoMechVisualization/RivGeoMechVizLogic.h index 04786ae83e..5c64c3f15a 100644 --- a/ApplicationCode/GeoMech/GeoMechVisualization/RivGeoMechVizLogic.h +++ b/ApplicationCode/GeoMech/GeoMechVisualization/RivGeoMechVizLogic.h @@ -20,6 +20,7 @@ #pragma once #include +#include "cvfArray.h" #include "cvfObject.h" #include "cvfColor4.h" #include "RivGeoMechPartMgrCache.h" @@ -47,6 +48,7 @@ class RivGeoMechVizLogic : public cvf::Object void updateCellResultColor(int timeStepIndex, RimGeoMechCellColors* cellResultColors); void updateStaticCellColors(int timeStepIndex); void scheduleGeometryRegen(RivCellSetEnum geometryType); + void calculateCurrentTotalCellVisibility(cvf::UByteArray* totalVisibility, int timeStepIndex); private: std::vector keysToVisiblePartMgrs(int timeStepIndex); diff --git a/ApplicationCode/GeoMech/OdbReader/RifOdbReader.cpp b/ApplicationCode/GeoMech/OdbReader/RifOdbReader.cpp index 67384d4ba1..e7ddabb22a 100644 --- a/ApplicationCode/GeoMech/OdbReader/RifOdbReader.cpp +++ b/ApplicationCode/GeoMech/OdbReader/RifOdbReader.cpp @@ -104,7 +104,7 @@ std::map initFemTypeMap() std::map typeMap; typeMap["C3D8R"] = HEX8; typeMap["C3D8"] = HEX8; - typeMap["C3D8P"] = HEX8; + typeMap["C3D8P"] = HEX8P; typeMap["CAX4"] = CAX4; return typeMap; @@ -141,6 +141,7 @@ const int* localElmNodeToIntegrationPointMapping(RigElementType elmType) switch (elmType) { case HEX8: + case HEX8P: return HEX8_Mapping; break; case CAX4: @@ -163,7 +164,7 @@ RifOdbReader::RifOdbReader() odb_initializeAPI(); } - m_odb = NULL; + m_odb = NULL; } //-------------------------------------------------------------------------------------------------- @@ -171,7 +172,7 @@ RifOdbReader::RifOdbReader() //-------------------------------------------------------------------------------------------------- RifOdbReader::~RifOdbReader() { - close(); + close(); if (--sm_instanceCount == 0) { @@ -184,11 +185,11 @@ RifOdbReader::~RifOdbReader() //-------------------------------------------------------------------------------------------------- void RifOdbReader::close() { - if (m_odb) - { - m_odb->close(); - m_odb = NULL; - } + if (m_odb) + { + m_odb->close(); + m_odb = NULL; + } } //-------------------------------------------------------------------------------------------------- @@ -196,17 +197,17 @@ void RifOdbReader::close() //-------------------------------------------------------------------------------------------------- bool RifOdbReader::openFile(const std::string& fileName, std::string* errorMessage) { - close(); - CVF_ASSERT(m_odb == NULL); + close(); + CVF_ASSERT(m_odb == NULL); - odb_String path = fileName.c_str(); + odb_String path = fileName.c_str(); - try - { - m_odb = &openOdb(path, true); - } + try + { + m_odb = &openOdb(path, true); + } - catch (const nex_Exception& nex) + catch (const nex_Exception& nex) { if (errorMessage) { @@ -229,7 +230,7 @@ bool RifOdbReader::openFile(const std::string& fileName, std::string* errorMessa return false; } - return true; + return true; } @@ -238,13 +239,13 @@ bool RifOdbReader::openFile(const std::string& fileName, std::string* errorMessa //-------------------------------------------------------------------------------------------------- void RifOdbReader::assertMetaDataLoaded() { - CVF_ASSERT(m_odb != NULL); + CVF_ASSERT(m_odb != NULL); if (m_resultsMetaData.empty()) - { + { m_resultsMetaData = readResultsMetaData(m_odb); } - + } @@ -253,11 +254,11 @@ void RifOdbReader::assertMetaDataLoaded() //-------------------------------------------------------------------------------------------------- std::map< RifOdbReader::RifOdbResultKey, std::vector > RifOdbReader::readResultsMetaData(odb_Odb* odb) { - CVF_ASSERT(odb != NULL); + CVF_ASSERT(odb != NULL); std::map< RifOdbResultKey, std::vector > resultsMap; - const odb_StepRepository& stepRepository = odb->steps(); + const odb_StepRepository& stepRepository = odb->steps(); odb_StepRepositoryIT stepIt(stepRepository); stepIt.first(); @@ -267,56 +268,56 @@ std::map< RifOdbReader::RifOdbResultKey, std::vector > RifOdbReader if (stepFrames.size() > 1) { // Optimization: Get results metadata for the second frame of the first step only - const odb_Frame& frame = stepFrames.constGet(1); - - const odb_FieldOutputRepository& fieldCon = frame.fieldOutputs(); - odb_FieldOutputRepositoryIT fieldConIT(fieldCon); - - for (fieldConIT.first(); !fieldConIT.isDone(); fieldConIT.next()) - { - const odb_FieldOutput& field = fieldCon[fieldConIT.currentKey()]; - - const odb_SequenceFieldLocation& fieldLocations = field.locations(); - for (int loc = 0; loc < fieldLocations.size(); loc++) - { - const odb_FieldLocation& fieldLocation = fieldLocations.constGet(loc); - - std::string fieldName = field.name().CStr(); - odb_SequenceString components = field.componentLabels(); - - std::vector compVec; - - int numComp = components.size(); - for (int comp = 0; comp < numComp; comp++) - { - compVec.push_back(components[comp].CStr()); - } - - switch (fieldLocation.position()) - { - case odb_Enum::NODAL: + const odb_Frame& frame = stepFrames.constGet(1); + + const odb_FieldOutputRepository& fieldCon = frame.fieldOutputs(); + odb_FieldOutputRepositoryIT fieldConIT(fieldCon); + + for (fieldConIT.first(); !fieldConIT.isDone(); fieldConIT.next()) + { + const odb_FieldOutput& field = fieldCon[fieldConIT.currentKey()]; + + const odb_SequenceFieldLocation& fieldLocations = field.locations(); + for (int loc = 0; loc < fieldLocations.size(); loc++) + { + const odb_FieldLocation& fieldLocation = fieldLocations.constGet(loc); + + std::string fieldName = field.name().CStr(); + odb_SequenceString components = field.componentLabels(); + + std::vector compVec; + + int numComp = components.size(); + for (int comp = 0; comp < numComp; comp++) + { + compVec.push_back(components[comp].CStr()); + } + + switch (fieldLocation.position()) + { + case odb_Enum::NODAL: resultsMap[RifOdbResultKey(NODAL, fieldName)] = compVec; - break; + break; case odb_Enum::ELEMENT_NODAL: resultsMap[RifOdbResultKey(ELEMENT_NODAL, fieldName)] = compVec; - break; + break; - case odb_Enum::INTEGRATION_POINT: + case odb_Enum::INTEGRATION_POINT: resultsMap[RifOdbResultKey(INTEGRATION_POINT, fieldName)] = compVec; resultsMap[RifOdbResultKey(ELEMENT_NODAL, fieldName)] = compVec; - break; + break; - default: - break; - } - } + default: + break; + } + } } } stepFrames.release(); - return resultsMap; + return resultsMap; } @@ -326,7 +327,7 @@ std::map< RifOdbReader::RifOdbResultKey, std::vector > RifOdbReader bool RifOdbReader::readFemParts(RigFemPartCollection* femParts) { CVF_ASSERT(femParts); - CVF_ASSERT(m_odb != NULL); + CVF_ASSERT(m_odb != NULL); odb_Assembly& rootAssembly = m_odb->rootAssembly(); @@ -417,7 +418,7 @@ bool RifOdbReader::readFemParts(RigFemPartCollection* femParts) modelProgress.incrementProgress(); } - return true; + return true; } //-------------------------------------------------------------------------------------------------- @@ -425,18 +426,18 @@ bool RifOdbReader::readFemParts(RigFemPartCollection* femParts) //-------------------------------------------------------------------------------------------------- std::vector RifOdbReader::stepNames() { - CVF_ASSERT(m_odb != NULL); + CVF_ASSERT(m_odb != NULL); - std::vector stepNames; + std::vector stepNames; - odb_StepRepository stepRepository = m_odb->steps(); - odb_StepRepositoryIT sIter(stepRepository); - for (sIter.first(); !sIter.isDone(); sIter.next()) - { - stepNames.push_back(stepRepository[sIter.currentKey()].name().CStr()); - } + odb_StepRepository stepRepository = m_odb->steps(); + odb_StepRepositoryIT sIter(stepRepository); + for (sIter.first(); !sIter.isDone(); sIter.next()) + { + stepNames.push_back(stepRepository[sIter.currentKey()].name().CStr()); + } - return stepNames; + return stepNames; } @@ -445,25 +446,25 @@ std::vector RifOdbReader::stepNames() //-------------------------------------------------------------------------------------------------- std::vector RifOdbReader::frameTimes(int stepIndex) { - CVF_ASSERT(m_odb != NULL); + CVF_ASSERT(m_odb != NULL); - odb_StepRepository& stepRepository = m_odb->steps(); + odb_StepRepository& stepRepository = m_odb->steps(); - odb_StepList stepList = stepRepository.stepList(); - odb_Step& step = stepList.Get(stepIndex); - - odb_SequenceFrame& stepFrames = step.frames(); + odb_StepList stepList = stepRepository.stepList(); + odb_Step& step = stepList.Get(stepIndex); + + odb_SequenceFrame& stepFrames = step.frames(); - std::vector frameValues; + std::vector frameValues; - int numFrames = stepFrames.size(); - for (int f = 0; f < numFrames; f++) - { - odb_Frame frame = stepFrames.constGet(f); - frameValues.push_back(frame.frameValue()); - } + int numFrames = stepFrames.size(); + for (int f = 0; f < numFrames; f++) + { + odb_Frame frame = stepFrames.constGet(f); + frameValues.push_back(frame.frameValue()); + } - return frameValues; + return frameValues; } @@ -484,24 +485,24 @@ std::vector RifOdbReader::elementSetNames(int partIndex) int currentInstance = 0; odb_InstanceRepositoryIT instIt(instances); - for (instIt.first(); !instIt.isDone(); instIt.next(), currentInstance++) - { + for (instIt.first(); !instIt.isDone(); instIt.next(), currentInstance++) + { const odb_Instance& instance = instIt.currentValue(); if (currentInstance == partIndex) { const odb_SetRepository& sets = rootAssembly.elementSets(); - - odb_SetRepositoryIT setIt(sets); - for (setIt.first(); !setIt.isDone(); setIt.next()) - { + + odb_SetRepositoryIT setIt(sets); + for (setIt.first(); !setIt.isDone(); setIt.next()) + { const odb_Set& set = setIt.currentValue(); setNames.push_back(set.name().CStr()); - } + } break; } - } + } m_partElementSetNames[partIndex] = setNames; } @@ -523,16 +524,16 @@ std::vector RifOdbReader::elementSet(int partIndex, int setIndex) const odb_Set& set = rootAssembly.elementSets()[odb_String(setNames[setIndex].c_str())]; odb_SequenceString instanceNames = set.instanceNames(); - const odb_SequenceElement& setElements = set.elements(instanceNames[partIndex]); - int elementCount = setElements.size(); + const odb_SequenceElement& setElements = set.elements(instanceNames[partIndex]); + int elementCount = setElements.size(); std::vector elementIndexes; elementIndexes.resize(elementCount); - for (int i = 0; i < elementCount; i++) - { + for (int i = 0; i < elementCount; i++) + { elementIndexes[i] = setElements.element(i).index(); - } + } return elementIndexes; } @@ -570,14 +571,14 @@ std::map > RifOdbReader::scalarIntegration //-------------------------------------------------------------------------------------------------- const odb_Frame& RifOdbReader::stepFrame(int stepIndex, int frameIndex) const { - CVF_ASSERT(m_odb); + CVF_ASSERT(m_odb); - const odb_StepRepository& stepRepository = m_odb->steps(); - const odb_StepList& stepList = stepRepository.stepList(); + const odb_StepRepository& stepRepository = m_odb->steps(); + const odb_StepList& stepList = stepRepository.stepList(); const odb_Step& step = stepList.ConstGet(stepIndex); - const odb_SequenceFrame& stepFrames = step.frames(); + const odb_SequenceFrame& stepFrames = step.frames(); - return stepFrames.constGet(frameIndex); + return stepFrames.constGet(frameIndex); } @@ -615,20 +616,20 @@ size_t RifOdbReader::resultItemCount(const std::string& fieldName, int partIndex odb_Instance* partInstance = instance(partIndex); CVF_ASSERT(partInstance != NULL); - const odb_Frame& frame = stepFrame(stepIndex, frameIndex); - const odb_FieldOutput& instanceFieldOutput = frame.fieldOutputs()[fieldName.c_str()].getSubset(*partInstance); - const odb_SequenceFieldBulkData& seqFieldBulkData = instanceFieldOutput.bulkDataBlocks(); + const odb_Frame& frame = stepFrame(stepIndex, frameIndex); + const odb_FieldOutput& instanceFieldOutput = frame.fieldOutputs()[fieldName.c_str()].getSubset(*partInstance); + const odb_SequenceFieldBulkData& seqFieldBulkData = instanceFieldOutput.bulkDataBlocks(); - size_t resultItemCount = 0; - int numBlocks = seqFieldBulkData.size(); + size_t resultItemCount = 0; + int numBlocks = seqFieldBulkData.size(); - for (int block = 0; block < numBlocks; block++) - { - const odb_FieldBulkData& bulkData = seqFieldBulkData[block]; - resultItemCount += bulkData.length(); - } + for (int block = 0; block < numBlocks; block++) + { + const odb_FieldBulkData& bulkData = seqFieldBulkData[block]; + resultItemCount += bulkData.length(); + } - return resultItemCount; + return resultItemCount; } @@ -647,21 +648,21 @@ size_t RifOdbReader::componentsCount(const std::string& fieldName, ResultPositio //-------------------------------------------------------------------------------------------------- int RifOdbReader::componentIndex(const RifOdbResultKey& result, const std::string& componentName) { - std::vector compNames = componentNames(result); + std::vector compNames = componentNames(result); // If there are no component names, we expect the field to be a pure scalar. // Then an empty string is the valid component name if (!compNames.size() && componentName == "") return 0; - for (size_t i = 0; i < compNames.size(); i++) - { - if (compNames[i] == componentName) - { - return static_cast(i); - } - } + for (size_t i = 0; i < compNames.size(); i++) + { + if (compNames[i] == componentName) + { + return static_cast(i); + } + } - return -1; + return -1; } @@ -673,15 +674,15 @@ std::vector RifOdbReader::componentNames(const RifOdbResultKey& res assertMetaDataLoaded(); std::map< RifOdbResultKey, std::vector >::const_iterator resMapIt = m_resultsMetaData.find(result); - if (resMapIt != m_resultsMetaData.end()) - { + if (resMapIt != m_resultsMetaData.end()) + { std::vector compNames; compNames = resMapIt->second; return compNames; - } - + } + CVF_ASSERT(false); - return std::vector(); + return std::vector(); } @@ -696,12 +697,12 @@ std::map > RifOdbReader::fieldAndComponent std::map< RifOdbResultKey, std::vector >::const_iterator resMapIt; for (resMapIt = m_resultsMetaData.begin(); resMapIt != m_resultsMetaData.end(); resMapIt++) - { + { if (resMapIt->first.resultPostion == position) { fieldsAndComponents[resMapIt->first.fieldName] = resMapIt->second; } - } + } return fieldsAndComponents; } @@ -712,42 +713,42 @@ std::map > RifOdbReader::fieldAndComponent //-------------------------------------------------------------------------------------------------- void RifOdbReader::readDisplacements(int partIndex, int stepIndex, int frameIndex, std::vector* displacements) { - CVF_ASSERT(displacements); + CVF_ASSERT(displacements); odb_Instance* partInstance = instance(partIndex); CVF_ASSERT(partInstance != NULL); - size_t dataSize = resultItemCount("U", partIndex, stepIndex, frameIndex); - if (dataSize > 0) - { - displacements->resize(dataSize); - } - - const odb_Frame& frame = stepFrame(stepIndex, frameIndex); - const odb_FieldOutput& instanceFieldOutput = frame.fieldOutputs()["U"].getSubset(*partInstance); - const odb_SequenceFieldBulkData& seqFieldBulkData = instanceFieldOutput.bulkDataBlocks(); - - size_t dataIndex = 0; - int numBlocks = seqFieldBulkData.size(); - for (int block = 0; block < numBlocks; block++) - { - const odb_FieldBulkData& bulkData = seqFieldBulkData[block]; + size_t dataSize = resultItemCount("U", partIndex, stepIndex, frameIndex); + if (dataSize > 0) + { + displacements->resize(dataSize); + } + + const odb_Frame& frame = stepFrame(stepIndex, frameIndex); + const odb_FieldOutput& instanceFieldOutput = frame.fieldOutputs()["U"].getSubset(*partInstance); + const odb_SequenceFieldBulkData& seqFieldBulkData = instanceFieldOutput.bulkDataBlocks(); + + size_t dataIndex = 0; + int numBlocks = seqFieldBulkData.size(); + for (int block = 0; block < numBlocks; block++) + { + const odb_FieldBulkData& bulkData = seqFieldBulkData[block]; RifOdbBulkDataGetter bulkDataGetter(bulkData); - if (bulkData.numberOfNodes() > 0) - { - int numNodes = bulkData.length(); - int numComp = bulkData.width(); + if (bulkData.numberOfNodes() > 0) + { + int numNodes = bulkData.length(); + int numComp = bulkData.width(); float* data = bulkDataGetter.data(); - for (int i = 0; i < numNodes; i++) - { - (*displacements)[i + dataIndex].set(data[i*numComp], data[i*numComp + 1], data[i*numComp + 2]); - } + for (int i = 0; i < numNodes; i++) + { + (*displacements)[i + dataIndex].set(data[i*numComp], data[i*numComp + 1], data[i*numComp + 2]); + } - dataIndex += numNodes*numComp; - } - } + dataIndex += numNodes*numComp; + } + } } @@ -756,7 +757,7 @@ void RifOdbReader::readDisplacements(int partIndex, int stepIndex, int frameInde //-------------------------------------------------------------------------------------------------- void RifOdbReader::readNodeField(const std::string& fieldName, int partIndex, int stepIndex, int frameIndex, std::vector*>* resultValues) { - CVF_ASSERT(resultValues); + CVF_ASSERT(resultValues); odb_Instance* partInstance = instance(partIndex); CVF_ASSERT(partInstance != NULL); @@ -768,42 +769,42 @@ void RifOdbReader::readNodeField(const std::string& fieldName, int partIndex, in size_t dataSize = nodeIdToIdxMap.size(); - if (dataSize > 0) - { + if (dataSize > 0) + { for (int comp = 0; comp < compCount; comp++) - { + { CVF_ASSERT((*resultValues)[comp]); - (*resultValues)[comp]->resize(dataSize, std::numeric_limits::infinity()); + (*resultValues)[comp]->resize(dataSize, std::numeric_limits::infinity()); } - } + } - const odb_Frame& frame = stepFrame(stepIndex, frameIndex); - const odb_FieldOutput& instanceFieldOutput = frame.fieldOutputs()[fieldName.c_str()].getSubset(*partInstance); + const odb_Frame& frame = stepFrame(stepIndex, frameIndex); + const odb_FieldOutput& instanceFieldOutput = frame.fieldOutputs()[fieldName.c_str()].getSubset(*partInstance); const odb_FieldOutput& fieldOutput = instanceFieldOutput.getSubset(odb_Enum::NODAL); - const odb_SequenceFieldBulkData& seqFieldBulkData = fieldOutput.bulkDataBlocks(); + const odb_SequenceFieldBulkData& seqFieldBulkData = fieldOutput.bulkDataBlocks(); - size_t dataIndex = 0; - int numBlocks = seqFieldBulkData.size(); - for (int block = 0; block < numBlocks; block++) - { - const odb_FieldBulkData& bulkData = seqFieldBulkData[block]; + size_t dataIndex = 0; + int numBlocks = seqFieldBulkData.size(); + for (int block = 0; block < numBlocks; block++) + { + const odb_FieldBulkData& bulkData = seqFieldBulkData[block]; RifOdbBulkDataGetter bulkDataGetter(bulkData); - int numNodes = bulkData.length(); - int numComp = bulkData.width(); + int numNodes = bulkData.length(); + int numComp = bulkData.width(); int* nodeLabels = bulkData.nodeLabels(); float* data = bulkDataGetter.data(); - for (int nIdx = 0; nIdx < numNodes; nIdx++) - { + for (int nIdx = 0; nIdx < numNodes; nIdx++) + { for (int comp = 0; comp < numComp; comp++) { std::vector* singleComponentValues = (*resultValues)[comp]; (*singleComponentValues)[nodeIdToIdxMap[nodeLabels[nIdx]]] = data[nIdx*numComp + comp]; } - } - } + } + } } @@ -823,36 +824,36 @@ void RifOdbReader::readElementNodeField(const std::string& fieldName, CVF_ASSERT(compCount == resultValues->size()); size_t dataSize = resultItemCount(fieldName, partIndex, stepIndex, frameIndex); - if (dataSize > 0) - { + if (dataSize > 0) + { for (int comp = 0; comp < compCount; comp++) - { + { CVF_ASSERT((*resultValues)[comp]); - (*resultValues)[comp]->resize(dataSize, std::numeric_limits::infinity()); + (*resultValues)[comp]->resize(dataSize, std::numeric_limits::infinity()); } - } + } - const odb_Frame& frame = stepFrame(stepIndex, frameIndex); - const odb_FieldOutput& instanceFieldOutput = frame.fieldOutputs()[fieldName.c_str()].getSubset(*partInstance); + const odb_Frame& frame = stepFrame(stepIndex, frameIndex); + const odb_FieldOutput& instanceFieldOutput = frame.fieldOutputs()[fieldName.c_str()].getSubset(*partInstance); const odb_FieldOutput& fieldOutput = instanceFieldOutput.getSubset(odb_Enum::ELEMENT_NODAL); - const odb_SequenceFieldBulkData& seqFieldBulkData = fieldOutput.bulkDataBlocks(); + const odb_SequenceFieldBulkData& seqFieldBulkData = fieldOutput.bulkDataBlocks(); std::map& elementIdToIdxMap = m_elementIdToIdxMaps[partIndex]; CVF_ASSERT(elementIdToIdxMap.size() > 0); - + size_t dataIndex = 0; - int numBlocks = seqFieldBulkData.size(); - for (int block = 0; block < numBlocks; block++) - { - const odb_FieldBulkData& bulkData = seqFieldBulkData[block]; + int numBlocks = seqFieldBulkData.size(); + for (int block = 0; block < numBlocks; block++) + { + const odb_FieldBulkData& bulkData = seqFieldBulkData[block]; RifOdbBulkDataGetter bulkDataGetter(bulkData); - int numValues = bulkData.length(); - int numComp = bulkData.width(); + int numValues = bulkData.length(); + int numComp = bulkData.width(); int elemCount = bulkData.numberOfElements(); - int elemNodeCount = numValues/elemCount; - int* elementLabels = bulkData.elementLabels(); + int elemNodeCount = numValues/elemCount; + int* elementLabels = bulkData.elementLabels(); float* data = bulkDataGetter.data(); for (int elem = 0; elem < elemCount; elem++) @@ -872,7 +873,7 @@ void RifOdbReader::readElementNodeField(const std::string& fieldName, } } } - } + } } @@ -890,40 +891,40 @@ void RifOdbReader::readIntegrationPointField(const std::string& fieldName, int p CVF_ASSERT(compCount == resultValues->size()); size_t dataSize = resultItemCount(fieldName, partIndex, stepIndex, frameIndex); - if (dataSize > 0) - { + if (dataSize > 0) + { for (int comp = 0; comp < compCount; comp++) - { + { CVF_ASSERT((*resultValues)[comp]); - (*resultValues)[comp]->resize(dataSize, std::numeric_limits::infinity()); + (*resultValues)[comp]->resize(dataSize, std::numeric_limits::infinity()); } - } + } - const odb_Frame& frame = stepFrame(stepIndex, frameIndex); - const odb_FieldOutput& instanceFieldOutput = frame.fieldOutputs()[fieldName.c_str()].getSubset(*partInstance); + const odb_Frame& frame = stepFrame(stepIndex, frameIndex); + const odb_FieldOutput& instanceFieldOutput = frame.fieldOutputs()[fieldName.c_str()].getSubset(*partInstance); const odb_FieldOutput& fieldOutput = instanceFieldOutput.getSubset(odb_Enum::INTEGRATION_POINT); - const odb_SequenceFieldBulkData& seqFieldBulkData = fieldOutput.bulkDataBlocks(); + const odb_SequenceFieldBulkData& seqFieldBulkData = fieldOutput.bulkDataBlocks(); std::map& elementIdToIdxMap = m_elementIdToIdxMaps[partIndex]; CVF_ASSERT(elementIdToIdxMap.size() > 0); - + size_t dataIndex = 0; - int numBlocks = seqFieldBulkData.size(); - for (int block = 0; block < numBlocks; block++) - { - const odb_FieldBulkData& bulkData = seqFieldBulkData[block]; + int numBlocks = seqFieldBulkData.size(); + for (int block = 0; block < numBlocks; block++) + { + const odb_FieldBulkData& bulkData = seqFieldBulkData[block]; RifOdbBulkDataGetter bulkDataGetter(bulkData); - int numValues = bulkData.length(); - int numComp = bulkData.width(); + int numValues = bulkData.length(); + int numComp = bulkData.width(); int elemCount = bulkData.numberOfElements(); - int ipCount = numValues/elemCount; - int* elementLabels = bulkData.elementLabels(); + int ipCount = numValues/elemCount; + int* elementLabels = bulkData.elementLabels(); float* data = bulkDataGetter.data(); RigElementType eType = toRigElementType(bulkData.baseElementType()); - const int* elmNodeToIpResultMapping = localElmNodeToIntegrationPointMapping(eType); + const int* elmNodeToIpResultMapping = localElmNodeToIntegrationPointMapping(eType); // Todo: Use the one in RigFemTypes.h, but we need to guard against unknown element types first. if (!elmNodeToIpResultMapping) continue; for (int elem = 0; elem < elemCount; elem++) @@ -944,5 +945,5 @@ void RifOdbReader::readIntegrationPointField(const std::string& fieldName, int p } } } - } + } } diff --git a/ApplicationCode/GeoMech/OdbReader/RifOdbReader.h b/ApplicationCode/GeoMech/OdbReader/RifOdbReader.h index d0b777d4f3..be1004c0c9 100644 --- a/ApplicationCode/GeoMech/OdbReader/RifOdbReader.h +++ b/ApplicationCode/GeoMech/OdbReader/RifOdbReader.h @@ -41,7 +41,7 @@ class RifOdbReader : public RifGeoMechReaderInterface RifOdbReader(); virtual ~RifOdbReader(); - virtual bool openFile(const std::string& fileName, std::string* errorMessage); + virtual bool openFile(const std::string& fileName, std::string* errorMessage); virtual bool readFemParts(RigFemPartCollection* geoMechCase); virtual std::vector stepNames(); @@ -63,9 +63,9 @@ class RifOdbReader : public RifGeoMechReaderInterface private: enum ResultPosition { - NODAL, - ELEMENT_NODAL, - INTEGRATION_POINT + NODAL, + ELEMENT_NODAL, + INTEGRATION_POINT }; class RifOdbResultKey @@ -93,7 +93,7 @@ class RifOdbReader : public RifGeoMechReaderInterface size_t resultItemCount(const std::string& fieldName, int partIndex, int stepIndex, int frameIndex); size_t componentsCount(const std::string& fieldName, ResultPosition position); const odb_Frame& stepFrame(int stepIndex, int frameIndex) const; - odb_Instance* instance(int instanceIndex); + odb_Instance* instance(int instanceIndex); int componentIndex(const RifOdbResultKey& result, const std::string& componentName); std::vector componentNames(const RifOdbResultKey& result); @@ -108,5 +108,5 @@ class RifOdbReader : public RifGeoMechReaderInterface std::vector< std::map > m_nodeIdToIdxMaps; std::vector< std::map > m_elementIdToIdxMaps; - static size_t sm_instanceCount; + static size_t sm_instanceCount; }; diff --git a/ApplicationCode/GeoMech/OdbReader_UnitTests/RifOdbReader-Test.cpp b/ApplicationCode/GeoMech/OdbReader_UnitTests/RifOdbReader-Test.cpp index 5b345d7be2..d6a421f28a 100644 --- a/ApplicationCode/GeoMech/OdbReader_UnitTests/RifOdbReader-Test.cpp +++ b/ApplicationCode/GeoMech/OdbReader_UnitTests/RifOdbReader-Test.cpp @@ -41,84 +41,84 @@ TEST(OdbReaderTest, BasicTests) cvf::DebugTimer timer("DebugTimer"); timer.reportTime(); - reader->openFile(TEST_FILE); + reader->openFile(TEST_FILE); reader->readFemParts(femData.p()); EXPECT_EQ(1, femData->partCount()); EXPECT_EQ(4320, femData->part(0)->elementCount()); EXPECT_EQ(HEX8, femData->part(0)->elementType(0)); - EXPECT_EQ(true, reader->stepNames().size() == 1); + EXPECT_EQ(true, reader->stepNames().size() == 1); - std::vector steps = reader->stepNames(); - EXPECT_EQ(true, steps.at(0).find("Date_20100930") >= 0); - EXPECT_EQ(2, reader->frameTimes(0).size()); - EXPECT_EQ(1.0, reader->frameTimes(0)[1]); + std::vector steps = reader->stepNames(); + EXPECT_EQ(true, steps.at(0).find("Date_20100930") >= 0); + EXPECT_EQ(2, reader->frameTimes(0).size()); + EXPECT_EQ(1.0, reader->frameTimes(0)[1]); - std::map > scalarNodeFieldsMap = reader->scalarNodeFieldAndComponentNames(); - EXPECT_EQ(3, scalarNodeFieldsMap.size()); - - std::map > scalarElementNodeFieldsMap = reader->scalarElementNodeFieldAndComponentNames(); - EXPECT_EQ(0, scalarElementNodeFieldsMap.size()); - - std::map > scalarIntegrationPointFieldsMap = reader->scalarIntegrationPointFieldAndComponentNames(); - EXPECT_EQ(6, scalarIntegrationPointFieldsMap.size()); + std::map > scalarNodeFieldsMap = reader->scalarNodeFieldAndComponentNames(); + EXPECT_EQ(3, scalarNodeFieldsMap.size()); + + std::map > scalarElementNodeFieldsMap = reader->scalarElementNodeFieldAndComponentNames(); + EXPECT_EQ(0, scalarElementNodeFieldsMap.size()); + + std::map > scalarIntegrationPointFieldsMap = reader->scalarIntegrationPointFieldAndComponentNames(); + EXPECT_EQ(6, scalarIntegrationPointFieldsMap.size()); - std::vector displacementValues; - reader->readScalarNodeField("U", "U2", 0, 0, 1, &displacementValues); - EXPECT_EQ(5168, displacementValues.size()); + std::vector displacementValues; + reader->readScalarNodeField("U", "U2", 0, 0, 1, &displacementValues); + EXPECT_EQ(5168, displacementValues.size()); - std::vector integrationPointS22; + std::vector integrationPointS22; timer.restart(); - reader->readScalarIntegrationPointField("S", "S22", 0, 0, 1, &integrationPointS22); + reader->readScalarIntegrationPointField("S", "S22", 0, 0, 1, &integrationPointS22); timer.reportLapTime("Read S/S22"); timer.restart(); - reader->readScalarIntegrationPointField("S", "S22", 0, 0, 1, &integrationPointS22); + reader->readScalarIntegrationPointField("S", "S22", 0, 0, 1, &integrationPointS22); timer.reportLapTime("Read S/S22 2nd time"); timer.restart(); - reader->readScalarIntegrationPointField("S", "S22", 0, 0, 1, &integrationPointS22); + reader->readScalarIntegrationPointField("S", "S22", 0, 0, 1, &integrationPointS22); timer.reportLapTime("Read S/S22 3rd time"); EXPECT_EQ(34560, integrationPointS22.size()); - EXPECT_FLOAT_EQ(-1921117.3, integrationPointS22[0]); - EXPECT_FLOAT_EQ(-1408592.5, integrationPointS22[1]); - EXPECT_FLOAT_EQ(-1345666.9, integrationPointS22[2]); + EXPECT_FLOAT_EQ(-1921117.3, integrationPointS22[0]); + EXPECT_FLOAT_EQ(-1408592.5, integrationPointS22[1]); + EXPECT_FLOAT_EQ(-1345666.9, integrationPointS22[2]); - std::vector elementNodeS11; + std::vector elementNodeS11; reader->readScalarElementNodeField("S", "S11", 0, 0, 1, &elementNodeS11); - EXPECT_EQ(34560, elementNodeS11.size()); - EXPECT_FLOAT_EQ(-2074357.3, elementNodeS11[0]); - EXPECT_FLOAT_EQ(-1353137.5, elementNodeS11[1]); - EXPECT_FLOAT_EQ(-1144559.4, elementNodeS11[2]); - - std::vector integrationPointE33; - reader->readScalarIntegrationPointField("E", "E33", 0, 0, 1, &integrationPointE33); - EXPECT_EQ(34560, integrationPointE33.size()); - - std::vector integrationPointTEMP; - reader->readScalarIntegrationPointField("TEMP", "", 0, 0, 1, &integrationPointTEMP); - EXPECT_EQ(34560, integrationPointTEMP.size()); - - std::vector displacements; - reader->readDisplacements(0, 0, 1, &displacements); - EXPECT_EQ(5168, displacements.size()); - EXPECT_FLOAT_EQ(0.047638997, displacements[1].y()); - EXPECT_FLOAT_EQ(-0.0036307564, displacements[6].x()); - EXPECT_FLOAT_EQ(0.065709047, displacements[6].y()); - EXPECT_FLOAT_EQ(-0.059760433, displacements[6].z()); - - std::vector porValues; - reader->readScalarNodeField("POR", "", 0, 0, 1, &porValues); - EXPECT_EQ(5168, porValues.size()); - - std::vector voidrValues; - reader->readScalarIntegrationPointField("VOIDR", "", 0, 0, 0, &voidrValues); - EXPECT_EQ(34560, voidrValues.size()); - EXPECT_FLOAT_EQ(0.22864963, voidrValues[0]); - EXPECT_FLOAT_EQ(0.23406270, voidrValues[1]); - EXPECT_FLOAT_EQ(0.24549910, voidrValues[2]); + EXPECT_EQ(34560, elementNodeS11.size()); + EXPECT_FLOAT_EQ(-2074357.3, elementNodeS11[0]); + EXPECT_FLOAT_EQ(-1353137.5, elementNodeS11[1]); + EXPECT_FLOAT_EQ(-1144559.4, elementNodeS11[2]); + + std::vector integrationPointE33; + reader->readScalarIntegrationPointField("E", "E33", 0, 0, 1, &integrationPointE33); + EXPECT_EQ(34560, integrationPointE33.size()); + + std::vector integrationPointTEMP; + reader->readScalarIntegrationPointField("TEMP", "", 0, 0, 1, &integrationPointTEMP); + EXPECT_EQ(34560, integrationPointTEMP.size()); + + std::vector displacements; + reader->readDisplacements(0, 0, 1, &displacements); + EXPECT_EQ(5168, displacements.size()); + EXPECT_FLOAT_EQ(0.047638997, displacements[1].y()); + EXPECT_FLOAT_EQ(-0.0036307564, displacements[6].x()); + EXPECT_FLOAT_EQ(0.065709047, displacements[6].y()); + EXPECT_FLOAT_EQ(-0.059760433, displacements[6].z()); + + std::vector porValues; + reader->readScalarNodeField("POR", "", 0, 0, 1, &porValues); + EXPECT_EQ(5168, porValues.size()); + + std::vector voidrValues; + reader->readScalarIntegrationPointField("VOIDR", "", 0, 0, 0, &voidrValues); + EXPECT_EQ(34560, voidrValues.size()); + EXPECT_FLOAT_EQ(0.22864963, voidrValues[0]); + EXPECT_FLOAT_EQ(0.23406270, voidrValues[1]); + EXPECT_FLOAT_EQ(0.24549910, voidrValues[2]); timer.restart(); - reader->readScalarIntegrationPointField("S", "S22", 0, 0, 1, &integrationPointS22); + reader->readScalarIntegrationPointField("S", "S22", 0, 0, 1, &integrationPointS22); timer.reportLapTime("Read S/S22 final time"); } diff --git a/ApplicationCode/ModelVisualization/CMakeLists_files.cmake b/ApplicationCode/ModelVisualization/CMakeLists_files.cmake index 97009bc04c..b17a032cf4 100644 --- a/ApplicationCode/ModelVisualization/CMakeLists_files.cmake +++ b/ApplicationCode/ModelVisualization/CMakeLists_files.cmake @@ -18,6 +18,7 @@ ${CEE_CURRENT_LIST_DIR}RivPipeGeometryGenerator.h ${CEE_CURRENT_LIST_DIR}RivReservoirFaultsPartMgr.h ${CEE_CURRENT_LIST_DIR}RivReservoirPipesPartMgr.h ${CEE_CURRENT_LIST_DIR}RivSourceInfo.h +${CEE_CURRENT_LIST_DIR}RivWellPathSourceInfo.h ${CEE_CURRENT_LIST_DIR}RivWellPathPartMgr.h ${CEE_CURRENT_LIST_DIR}RivWellPathCollectionPartMgr.h ${CEE_CURRENT_LIST_DIR}RivWellPipesPartMgr.h @@ -30,6 +31,7 @@ ${CEE_CURRENT_LIST_DIR}RivTernaryTextureCoordsCreator.h ${CEE_CURRENT_LIST_DIR}RivTernaryScalarMapperEffectGenerator.h ${CEE_CURRENT_LIST_DIR}RivScalarMapperUtils.h ${CEE_CURRENT_LIST_DIR}RivCellEdgeGeometryUtils.h +${CEE_CURRENT_LIST_DIR}RivPipeQuadToSegmentMapper.h ) @@ -48,6 +50,7 @@ ${CEE_CURRENT_LIST_DIR}RivReservoirViewPartMgr.cpp ${CEE_CURRENT_LIST_DIR}RivPipeGeometryGenerator.cpp ${CEE_CURRENT_LIST_DIR}RivReservoirPipesPartMgr.cpp ${CEE_CURRENT_LIST_DIR}RivSourceInfo.cpp +${CEE_CURRENT_LIST_DIR}RivWellPathSourceInfo.cpp ${CEE_CURRENT_LIST_DIR}RivWellPathPartMgr.cpp ${CEE_CURRENT_LIST_DIR}RivWellPathCollectionPartMgr.cpp ${CEE_CURRENT_LIST_DIR}RivWellPipesPartMgr.cpp @@ -58,6 +61,7 @@ ${CEE_CURRENT_LIST_DIR}RivTernaryTextureCoordsCreator.cpp ${CEE_CURRENT_LIST_DIR}RivTernaryScalarMapperEffectGenerator.cpp ${CEE_CURRENT_LIST_DIR}RivScalarMapperUtils.cpp ${CEE_CURRENT_LIST_DIR}RivCellEdgeGeometryUtils.cpp +${CEE_CURRENT_LIST_DIR}RivPipeQuadToSegmentMapper.cpp ) diff --git a/ApplicationCode/ModelVisualization/ModelVisualization_UnitTests/CMakeLists.txt b/ApplicationCode/ModelVisualization/ModelVisualization_UnitTests/CMakeLists.txt index 3f8c05e07e..3d3f29de52 100644 --- a/ApplicationCode/ModelVisualization/ModelVisualization_UnitTests/CMakeLists.txt +++ b/ApplicationCode/ModelVisualization/ModelVisualization_UnitTests/CMakeLists.txt @@ -10,11 +10,10 @@ include_directories( ${LibViewing_SOURCE_DIR} ${ResInsight_SOURCE_DIR}/ThirdParty - ${ResInsight_SOURCE_DIR}/CommonCode - - ${CMAKE_CURRENT_SOURCE_DIR}/.. - + ${ResInsight_SOURCE_DIR}/ApplicationCode/ModelVisualization + + ${CommonCode_SOURCE_DIR} ) set( MODEL_VISUALIZATION_CPP_SOURCES diff --git a/ApplicationCode/ModelVisualization/ModelVisualization_UnitTests/RivTernaryScalarMapper-Test.cpp b/ApplicationCode/ModelVisualization/ModelVisualization_UnitTests/RivTernaryScalarMapper-Test.cpp index 579412857c..cf485ece75 100644 --- a/ApplicationCode/ModelVisualization/ModelVisualization_UnitTests/RivTernaryScalarMapper-Test.cpp +++ b/ApplicationCode/ModelVisualization/ModelVisualization_UnitTests/RivTernaryScalarMapper-Test.cpp @@ -31,14 +31,14 @@ //-------------------------------------------------------------------------------------------------- TEST(TernaryScalarMapperTest, BasicFunctions) { - cvf::ref scalarMapper = new RivTernaryScalarMapper(cvf::Color3f::GRAY); + cvf::ref scalarMapper = new RivTernaryScalarMapper(cvf::Color3f::GRAY); - cvf::ref texImage = new cvf::TextureImage; - scalarMapper->updateTexture(texImage.p(), 1.0); + cvf::ref texImage = new cvf::TextureImage; + scalarMapper->updateTexture(texImage.p(), 1.0); - QImage img = cvfqt::Utils::toQImage(*(texImage.p())); + QImage img = cvfqt::Utils::toQImage(*(texImage.p())); - img.save("c:/tmp/test.png"); + img.save("c:/tmp/test.png"); } //-------------------------------------------------------------------------------------------------- @@ -46,58 +46,58 @@ TEST(TernaryScalarMapperTest, BasicFunctions) //-------------------------------------------------------------------------------------------------- TEST(TernaryScalarMapperTest, TextureMapping) { - cvf::ref scalarMapper = new RivTernaryScalarMapper(cvf::Color3f::GRAY); - - // Without opacity - { - cvf::Vec2f texCoord = scalarMapper->mapToTextureCoord(0.0, 0.0, false); - EXPECT_DOUBLE_EQ(0.0, texCoord.x()); - EXPECT_DOUBLE_EQ(0.0, texCoord.y()); - } - - { - cvf::Vec2f texCoord = scalarMapper->mapToTextureCoord(1.0, 0.0, false); - EXPECT_DOUBLE_EQ(1.0, texCoord.x()); - EXPECT_DOUBLE_EQ(0.0, texCoord.y()); - } - - { - cvf::Vec2f texCoord = scalarMapper->mapToTextureCoord(0.0, 1.0, false); - EXPECT_DOUBLE_EQ(0.0, texCoord.x()); - EXPECT_DOUBLE_EQ(0.5, texCoord.y()); - } - - { - cvf::Vec2f texCoord = scalarMapper->mapToTextureCoord(3.0, 3.0, false); - EXPECT_DOUBLE_EQ(1.0, texCoord.x()); - EXPECT_DOUBLE_EQ(0.0, texCoord.y()); - } - - { - cvf::Vec2f texCoord = scalarMapper->mapToTextureCoord(-1.0, -1.0, false); - EXPECT_DOUBLE_EQ(0.0, texCoord.x()); - EXPECT_DOUBLE_EQ(0.0, texCoord.y()); - } - - { - cvf::Vec2f texCoord = scalarMapper->mapToTextureCoord(0.5, 3.0, false); - EXPECT_DOUBLE_EQ(0.5, texCoord.x()); - EXPECT_DOUBLE_EQ(0.25, texCoord.y()); - } - - - - - // Opacity - { - cvf::Vec2f texCoord = scalarMapper->mapToTextureCoord(0.0, 0.0, true); - EXPECT_DOUBLE_EQ(0.0, texCoord.x()); - EXPECT_DOUBLE_EQ(0.5, texCoord.y()); - } - - { - cvf::Vec2f texCoord = scalarMapper->mapToTextureCoord(0.0, 1.0, true); - EXPECT_DOUBLE_EQ(0.0, texCoord.x()); - EXPECT_DOUBLE_EQ(1.0, texCoord.y()); - } + cvf::ref scalarMapper = new RivTernaryScalarMapper(cvf::Color3f::GRAY); + + // Without opacity + { + cvf::Vec2f texCoord = scalarMapper->mapToTextureCoord(0.0, 0.0, false); + EXPECT_DOUBLE_EQ(0.0, texCoord.x()); + EXPECT_DOUBLE_EQ(0.0, texCoord.y()); + } + + { + cvf::Vec2f texCoord = scalarMapper->mapToTextureCoord(1.0, 0.0, false); + EXPECT_DOUBLE_EQ(1.0, texCoord.x()); + EXPECT_DOUBLE_EQ(0.0, texCoord.y()); + } + + { + cvf::Vec2f texCoord = scalarMapper->mapToTextureCoord(0.0, 1.0, false); + EXPECT_DOUBLE_EQ(0.0, texCoord.x()); + EXPECT_DOUBLE_EQ(0.5, texCoord.y()); + } + + { + cvf::Vec2f texCoord = scalarMapper->mapToTextureCoord(3.0, 3.0, false); + EXPECT_DOUBLE_EQ(1.0, texCoord.x()); + EXPECT_DOUBLE_EQ(0.0, texCoord.y()); + } + + { + cvf::Vec2f texCoord = scalarMapper->mapToTextureCoord(-1.0, -1.0, false); + EXPECT_DOUBLE_EQ(0.0, texCoord.x()); + EXPECT_DOUBLE_EQ(0.0, texCoord.y()); + } + + { + cvf::Vec2f texCoord = scalarMapper->mapToTextureCoord(0.5, 3.0, false); + EXPECT_DOUBLE_EQ(0.5, texCoord.x()); + EXPECT_DOUBLE_EQ(0.25, texCoord.y()); + } + + + + + // Opacity + { + cvf::Vec2f texCoord = scalarMapper->mapToTextureCoord(0.0, 0.0, true); + EXPECT_DOUBLE_EQ(0.0, texCoord.x()); + EXPECT_DOUBLE_EQ(0.5, texCoord.y()); + } + + { + cvf::Vec2f texCoord = scalarMapper->mapToTextureCoord(0.0, 1.0, true); + EXPECT_DOUBLE_EQ(0.0, texCoord.x()); + EXPECT_DOUBLE_EQ(1.0, texCoord.y()); + } } diff --git a/ApplicationCode/ModelVisualization/RivCellEdgeEffectGenerator.cpp b/ApplicationCode/ModelVisualization/RivCellEdgeEffectGenerator.cpp index bcde980d5c..e713ea51d9 100644 --- a/ApplicationCode/ModelVisualization/RivCellEdgeEffectGenerator.cpp +++ b/ApplicationCode/ModelVisualization/RivCellEdgeEffectGenerator.cpp @@ -57,7 +57,7 @@ CellEdgeEffectGenerator::CellEdgeEffectGenerator(const cvf::ScalarMapper* edgeSc //-------------------------------------------------------------------------------------------------- void CellEdgeEffectGenerator::setScalarMapper(const cvf::ScalarMapper* cellScalarMapper) { - m_cellScalarMapper = cellScalarMapper; + m_cellScalarMapper = cellScalarMapper; } //-------------------------------------------------------------------------------------------------- @@ -65,7 +65,7 @@ void CellEdgeEffectGenerator::setScalarMapper(const cvf::ScalarMapper* cellScala //-------------------------------------------------------------------------------------------------- void CellEdgeEffectGenerator::setTernaryScalarMapper(const RivTernaryScalarMapper* ternaryScalarMapper) { - m_ternaryCellScalarMapper = ternaryScalarMapper; + m_ternaryCellScalarMapper = ternaryScalarMapper; } //-------------------------------------------------------------------------------------------------- @@ -78,8 +78,8 @@ bool CellEdgeEffectGenerator::isEqual(const EffectGenerator* other) const if (otherCellFaceEffectGenerator && m_cellScalarMapper.p() == otherCellFaceEffectGenerator->m_cellScalarMapper.p() && m_edgeScalarMapper.p() == otherCellFaceEffectGenerator->m_edgeScalarMapper.p() - && m_ternaryCellScalarMapper.p() == otherCellFaceEffectGenerator->m_ternaryCellScalarMapper.p() - && m_cullBackfaces == otherCellFaceEffectGenerator->m_cullBackfaces + && m_ternaryCellScalarMapper.p() == otherCellFaceEffectGenerator->m_ternaryCellScalarMapper.p() + && m_cullBackfaces == otherCellFaceEffectGenerator->m_cullBackfaces && m_opacityLevel == otherCellFaceEffectGenerator->m_opacityLevel && m_undefinedColor == otherCellFaceEffectGenerator->m_undefinedColor && m_defaultCellColor == otherCellFaceEffectGenerator->m_defaultCellColor @@ -114,8 +114,8 @@ bool CellEdgeEffectGenerator::isEqual(const EffectGenerator* other) const caf::EffectGenerator* CellEdgeEffectGenerator::copy() const { CellEdgeEffectGenerator * newEffect = new CellEdgeEffectGenerator(m_edgeScalarMapper.p()); - newEffect->setScalarMapper(m_cellScalarMapper.p()); - newEffect->setTernaryScalarMapper(m_ternaryCellScalarMapper.p()); + newEffect->setScalarMapper(m_cellScalarMapper.p()); + newEffect->setTernaryScalarMapper(m_ternaryCellScalarMapper.p()); newEffect->m_edgeTextureImage = m_edgeTextureImage; newEffect->m_cellTextureImage = m_cellTextureImage; @@ -133,54 +133,54 @@ caf::EffectGenerator* CellEdgeEffectGenerator::copy() const //-------------------------------------------------------------------------------------------------- void CellEdgeEffectGenerator::updateForShaderBasedRendering(cvf::Effect* effect) const { - cvf::ref eff = effect; - - // Set up shader program - - cvf::ShaderProgramGenerator shaderGen("CellEdgeFaceShaderProgramGenerator", cvf::ShaderSourceProvider::instance()); - { - QFile data(":/Shader/fs_CellFace.glsl"); - if (data.open(QFile::ReadOnly)) - { - QTextStream in(&data); - - QString data = in.readAll(); - cvf::String cvfString = cvfqt::Utils::toString(data); - - shaderGen.addFragmentCode(cvfString); - } - } - - if (m_ternaryCellScalarMapper.notNull()) - { - { - QFile data(":/Shader/vs_2dTextureCellFace.glsl"); - if (data.open(QFile::ReadOnly)) - { - QTextStream in(&data); - - QString data = in.readAll(); - cvf::String cvfString = cvfqt::Utils::toString(data); - - shaderGen.addVertexCode(cvfString); - } - } - } - else - { - { - QFile data(":/Shader/vs_CellFace.glsl"); - if (data.open(QFile::ReadOnly)) - { - QTextStream in(&data); - - QString data = in.readAll(); - cvf::String cvfString = cvfqt::Utils::toString(data); - - shaderGen.addVertexCode(cvfString); - } - } - } + cvf::ref eff = effect; + + // Set up shader program + + cvf::ShaderProgramGenerator shaderGen("CellEdgeFaceShaderProgramGenerator", cvf::ShaderSourceProvider::instance()); + { + QFile data(":/Shader/fs_CellFace.glsl"); + if (data.open(QFile::ReadOnly)) + { + QTextStream in(&data); + + QString data = in.readAll(); + cvf::String cvfString = cvfqt::Utils::toString(data); + + shaderGen.addFragmentCode(cvfString); + } + } + + if (m_ternaryCellScalarMapper.notNull()) + { + { + QFile data(":/Shader/vs_2dTextureCellFace.glsl"); + if (data.open(QFile::ReadOnly)) + { + QTextStream in(&data); + + QString data = in.readAll(); + cvf::String cvfString = cvfqt::Utils::toString(data); + + shaderGen.addVertexCode(cvfString); + } + } + } + else + { + { + QFile data(":/Shader/vs_CellFace.glsl"); + if (data.open(QFile::ReadOnly)) + { + QTextStream in(&data); + + QString data = in.readAll(); + cvf::String cvfString = cvfqt::Utils::toString(data); + + shaderGen.addVertexCode(cvfString); + } + } + } if (m_disableLighting) { @@ -203,11 +203,11 @@ void CellEdgeEffectGenerator::updateForShaderBasedRendering(cvf::Effect* effect) cvf::ref modifiedCellTextImage; m_edgeScalarMapper->updateTexture(m_edgeTextureImage.p()); - if (m_ternaryCellScalarMapper.notNull()) - { - m_ternaryCellScalarMapper->updateTexture(m_cellTextureImage.p(), m_opacityLevel); - modifiedCellTextImage = m_cellTextureImage; - } + if (m_ternaryCellScalarMapper.notNull()) + { + m_ternaryCellScalarMapper->updateTexture(m_cellTextureImage.p(), m_opacityLevel); + modifiedCellTextImage = m_cellTextureImage; + } else if (m_cellScalarMapper.notNull()) { m_cellScalarMapper->updateTexture(m_cellTextureImage.p()); diff --git a/ApplicationCode/ModelVisualization/RivCellEdgeEffectGenerator.h b/ApplicationCode/ModelVisualization/RivCellEdgeEffectGenerator.h index 52f6b1d8e7..3619ee63f9 100644 --- a/ApplicationCode/ModelVisualization/RivCellEdgeEffectGenerator.h +++ b/ApplicationCode/ModelVisualization/RivCellEdgeEffectGenerator.h @@ -101,10 +101,10 @@ class RivTernaryScalarMapper; class CellEdgeEffectGenerator : public caf::EffectGenerator { public: - CellEdgeEffectGenerator(const cvf::ScalarMapper* edgeScalarMapper); + CellEdgeEffectGenerator(const cvf::ScalarMapper* edgeScalarMapper); - void setScalarMapper(const cvf::ScalarMapper* cellScalarMapper); - void setTernaryScalarMapper(const RivTernaryScalarMapper* ternaryScalarMapper); + void setScalarMapper(const cvf::ScalarMapper* cellScalarMapper); + void setTernaryScalarMapper(const RivTernaryScalarMapper* ternaryScalarMapper); void setOpacityLevel(float opacity) { m_opacityLevel = cvf::Math::clamp(opacity, 0.0f , 1.0f ); } void setUndefinedColor(cvf::Color3f color) { m_undefinedColor = color; } @@ -125,9 +125,9 @@ class CellEdgeEffectGenerator : public caf::EffectGenerator cvf::cref m_cellScalarMapper; mutable cvf::ref m_cellTextureImage; - cvf::cref m_ternaryCellScalarMapper; + cvf::cref m_ternaryCellScalarMapper; - float m_opacityLevel; + float m_opacityLevel; caf::FaceCulling m_cullBackfaces; cvf::Color3f m_undefinedColor; cvf::Color3f m_defaultCellColor; diff --git a/ApplicationCode/ModelVisualization/RivCellEdgeGeometryUtils.cpp b/ApplicationCode/ModelVisualization/RivCellEdgeGeometryUtils.cpp index b32a9f8b1b..da0269aec9 100644 --- a/ApplicationCode/ModelVisualization/RivCellEdgeGeometryUtils.cpp +++ b/ApplicationCode/ModelVisualization/RivCellEdgeGeometryUtils.cpp @@ -42,141 +42,141 @@ /// //-------------------------------------------------------------------------------------------------- void RivCellEdgeGeometryUtils::addCellEdgeResultsToDrawableGeo( - size_t timeStepIndex, - RimEclipseCellColors* cellResultColors, - RimCellEdgeColors* cellEdgeResultColors, - const cvf::StructGridQuadToCellFaceMapper* quadToCellFaceMapper, - cvf::DrawableGeo* geo, - size_t gridIndex, - float opacityLevel) + size_t timeStepIndex, + RimEclipseCellColors* cellResultColors, + RimCellEdgeColors* cellEdgeResultColors, + const cvf::StructGridQuadToCellFaceMapper* quadToCellFaceMapper, + cvf::DrawableGeo* geo, + size_t gridIndex, + float opacityLevel) { - RigCaseData* eclipseCase = cellResultColors->reservoirView()->eclipseCase()->reservoirData(); - CVF_ASSERT(eclipseCase != NULL); + RigCaseData* eclipseCase = cellResultColors->reservoirView()->eclipseCase()->reservoirData(); + CVF_ASSERT(eclipseCase != NULL); - // Create result access objects + // Create result access objects - cvf::ref cellCenterDataAccessObject = createCellCenterResultAccessor(cellResultColors, timeStepIndex, eclipseCase, eclipseCase->grid(gridIndex)); - cvf::ref cellEdgeResultAccessor = createCellEdgeCenterResultAccessor(cellResultColors, cellEdgeResultColors, timeStepIndex, eclipseCase, eclipseCase->grid(gridIndex)); + cvf::ref cellCenterDataAccessObject = createCellCenterResultAccessor(cellResultColors, timeStepIndex, eclipseCase, eclipseCase->grid(gridIndex)); + cvf::ref cellEdgeResultAccessor = createCellEdgeCenterResultAccessor(cellResultColors, cellEdgeResultColors, timeStepIndex, eclipseCase, eclipseCase->grid(gridIndex)); - size_t vertexCount = geo->vertexArray()->size(); - size_t quadCount = vertexCount / 4; + size_t vertexCount = geo->vertexArray()->size(); + size_t quadCount = vertexCount / 4; - cvf::ref localCoords = new cvf::Vec2fArray; - localCoords->resize(vertexCount); + cvf::ref localCoords = new cvf::Vec2fArray; + localCoords->resize(vertexCount); - cvf::ref faceIndexArray = new cvf::IntArray; - faceIndexArray->resize(vertexCount); + cvf::ref faceIndexArray = new cvf::IntArray; + faceIndexArray->resize(vertexCount); - cvf::ref cellColorTextureCoordArray = new cvf::FloatArray; - cellColorTextureCoordArray->resize(vertexCount); + cvf::ref cellColorTextureCoordArray = new cvf::FloatArray; + cellColorTextureCoordArray->resize(vertexCount); - // Build six cell face color arrays - cvf::Collection cellEdgeColorTextureCoordsArrays; - size_t idx; - for (idx = 0; idx < 6; idx++) - { - cvf::ref colorArray = new cvf::FloatArray; - colorArray->resize(vertexCount); - cellEdgeColorTextureCoordsArrays.push_back(colorArray.p()); - } + // Build six cell face color arrays + cvf::Collection cellEdgeColorTextureCoordsArrays; + size_t idx; + for (idx = 0; idx < 6; idx++) + { + cvf::ref colorArray = new cvf::FloatArray; + colorArray->resize(vertexCount); + cellEdgeColorTextureCoordsArrays.push_back(colorArray.p()); + } - cvf::ScalarMapper* cellResultScalarMapper = cellResultColors->legendConfig()->scalarMapper(); - cvf::ScalarMapper* edgeResultScalarMapper = cellEdgeResultColors->legendConfig()->scalarMapper(); + cvf::ScalarMapper* cellResultScalarMapper = cellResultColors->legendConfig()->scalarMapper(); + cvf::ScalarMapper* edgeResultScalarMapper = cellEdgeResultColors->legendConfig()->scalarMapper(); - double ignoredScalarValue = cellEdgeResultColors->ignoredScalarValue(); + double ignoredScalarValue = cellEdgeResultColors->ignoredScalarValue(); - const std::vector* isWellPipeVisible = NULL; - cvf::ref gridCellToWellindexMap; + const std::vector* isWellPipeVisible = NULL; + cvf::ref gridCellToWellindexMap; - if (opacityLevel < 1.0f) - { - isWellPipeVisible = &(cellResultColors->reservoirView()->wellCollection()->isWellPipesVisible(timeStepIndex)); - gridCellToWellindexMap = eclipseCase->gridCellToWellIndex(gridIndex); - } + if (opacityLevel < 1.0f) + { + isWellPipeVisible = &(cellResultColors->reservoirView()->wellCollection()->isWellPipesVisible(timeStepIndex)); + gridCellToWellindexMap = eclipseCase->gridCellToWellIndex(gridIndex); + } #pragma omp parallel for - for (int quadIdx = 0; quadIdx < static_cast(quadCount); quadIdx++) - { - localCoords->set(quadIdx * 4 + 0, cvf::Vec2f(0, 0)); - localCoords->set(quadIdx * 4 + 1, cvf::Vec2f(1, 0)); - localCoords->set(quadIdx * 4 + 2, cvf::Vec2f(1, 1)); - localCoords->set(quadIdx * 4 + 3, cvf::Vec2f(0, 1)); - - faceIndexArray->set(quadIdx * 4 + 0, quadToCellFaceMapper->cellFace(quadIdx)); - faceIndexArray->set(quadIdx * 4 + 1, quadToCellFaceMapper->cellFace(quadIdx)); - faceIndexArray->set(quadIdx * 4 + 2, quadToCellFaceMapper->cellFace(quadIdx)); - faceIndexArray->set(quadIdx * 4 + 3, quadToCellFaceMapper->cellFace(quadIdx)); - - size_t cellIndex = quadToCellFaceMapper->cellIndex(quadIdx); - { - cvf::StructGridInterface::FaceType cellFace = quadToCellFaceMapper->cellFace(quadIdx); - double scalarValue = cellCenterDataAccessObject->cellFaceScalar(cellIndex, cellFace); - - { - float cellColorTextureCoord = 0.5f; // If no results exists, the texture will have a special color - if (scalarValue != HUGE_VAL) - { - cellColorTextureCoord = cellResultScalarMapper->mapToTextureCoord(scalarValue)[0]; - // If we are dealing with wellcells, the default is transparent. - // we need to make cells opaque if there are no wellpipe through them. - if (opacityLevel < 1.0f) - { - cvf::uint wellIndex = gridCellToWellindexMap->get(cellIndex); - if (wellIndex != cvf::UNDEFINED_UINT) - { - if (!(*isWellPipeVisible)[wellIndex]) - { - cellColorTextureCoord += 2.0f; // The shader must interpret values in the range 2-3 as "opaque" - } - } - } - } - else - { - cellColorTextureCoord = -1.0f; // Undefined texture coord. Shader handles this. - } - - cellColorTextureCoordArray->set(quadIdx * 4 + 0, cellColorTextureCoord); - cellColorTextureCoordArray->set(quadIdx * 4 + 1, cellColorTextureCoord); - cellColorTextureCoordArray->set(quadIdx * 4 + 2, cellColorTextureCoord); - cellColorTextureCoordArray->set(quadIdx * 4 + 3, cellColorTextureCoord); - } - } - - - float edgeColor; - for (size_t cubeFaceIdx = 0; cubeFaceIdx < 6; cubeFaceIdx++) - { - edgeColor = -1.0f; // Undefined texture coord. Shader handles this. - - double scalarValue = cellEdgeResultAccessor->cellFaceScalar(cellIndex, static_cast(cubeFaceIdx)); + for (int quadIdx = 0; quadIdx < static_cast(quadCount); quadIdx++) + { + localCoords->set(quadIdx * 4 + 0, cvf::Vec2f(0, 0)); + localCoords->set(quadIdx * 4 + 1, cvf::Vec2f(1, 0)); + localCoords->set(quadIdx * 4 + 2, cvf::Vec2f(1, 1)); + localCoords->set(quadIdx * 4 + 3, cvf::Vec2f(0, 1)); + + faceIndexArray->set(quadIdx * 4 + 0, quadToCellFaceMapper->cellFace(quadIdx)); + faceIndexArray->set(quadIdx * 4 + 1, quadToCellFaceMapper->cellFace(quadIdx)); + faceIndexArray->set(quadIdx * 4 + 2, quadToCellFaceMapper->cellFace(quadIdx)); + faceIndexArray->set(quadIdx * 4 + 3, quadToCellFaceMapper->cellFace(quadIdx)); + + size_t cellIndex = quadToCellFaceMapper->cellIndex(quadIdx); + { + cvf::StructGridInterface::FaceType cellFace = quadToCellFaceMapper->cellFace(quadIdx); + double scalarValue = cellCenterDataAccessObject->cellFaceScalar(cellIndex, cellFace); + + { + float cellColorTextureCoord = 0.5f; // If no results exists, the texture will have a special color + if (scalarValue != HUGE_VAL) + { + cellColorTextureCoord = cellResultScalarMapper->mapToTextureCoord(scalarValue)[0]; + // If we are dealing with wellcells, the default is transparent. + // we need to make cells opaque if there are no wellpipe through them. + if (opacityLevel < 1.0f) + { + cvf::uint wellIndex = gridCellToWellindexMap->get(cellIndex); + if (wellIndex != cvf::UNDEFINED_UINT) + { + if (!(*isWellPipeVisible)[wellIndex]) + { + cellColorTextureCoord += 2.0f; // The shader must interpret values in the range 2-3 as "opaque" + } + } + } + } + else + { + cellColorTextureCoord = -1.0f; // Undefined texture coord. Shader handles this. + } + + cellColorTextureCoordArray->set(quadIdx * 4 + 0, cellColorTextureCoord); + cellColorTextureCoordArray->set(quadIdx * 4 + 1, cellColorTextureCoord); + cellColorTextureCoordArray->set(quadIdx * 4 + 2, cellColorTextureCoord); + cellColorTextureCoordArray->set(quadIdx * 4 + 3, cellColorTextureCoord); + } + } + + + float edgeColor; + for (size_t cubeFaceIdx = 0; cubeFaceIdx < 6; cubeFaceIdx++) + { + edgeColor = -1.0f; // Undefined texture coord. Shader handles this. + + double scalarValue = cellEdgeResultAccessor->cellFaceScalar(cellIndex, static_cast(cubeFaceIdx)); if (!hideScalarValue(scalarValue, ignoredScalarValue, 1e-2)) - { - edgeColor = edgeResultScalarMapper->mapToTextureCoord(scalarValue)[0]; - } - - cvf::FloatArray* colArr = cellEdgeColorTextureCoordsArrays.at(cubeFaceIdx); - - colArr->set(quadIdx * 4 + 0, edgeColor); - colArr->set(quadIdx * 4 + 1, edgeColor); - colArr->set(quadIdx * 4 + 2, edgeColor); - colArr->set(quadIdx * 4 + 3, edgeColor); - } - } - - geo->setVertexAttribute(new cvf::Vec2fVertexAttribute("a_localCoord", localCoords.p())); - geo->setVertexAttribute(new cvf::FloatVertexAttribute("a_colorCell", cellColorTextureCoordArray.p())); - - cvf::ref faceIntAttribute = new cvf::IntVertexAttributeDirect("a_face", faceIndexArray.p()); - geo->setVertexAttribute(faceIntAttribute.p()); - - geo->setVertexAttribute(new cvf::FloatVertexAttribute("a_colorPosI", cellEdgeColorTextureCoordsArrays.at(0))); - geo->setVertexAttribute(new cvf::FloatVertexAttribute("a_colorNegI", cellEdgeColorTextureCoordsArrays.at(1))); - geo->setVertexAttribute(new cvf::FloatVertexAttribute("a_colorPosJ", cellEdgeColorTextureCoordsArrays.at(2))); - geo->setVertexAttribute(new cvf::FloatVertexAttribute("a_colorNegJ", cellEdgeColorTextureCoordsArrays.at(3))); - geo->setVertexAttribute(new cvf::FloatVertexAttribute("a_colorPosK", cellEdgeColorTextureCoordsArrays.at(4))); - geo->setVertexAttribute(new cvf::FloatVertexAttribute("a_colorNegK", cellEdgeColorTextureCoordsArrays.at(5))); + { + edgeColor = edgeResultScalarMapper->mapToTextureCoord(scalarValue)[0]; + } + + cvf::FloatArray* colArr = cellEdgeColorTextureCoordsArrays.at(cubeFaceIdx); + + colArr->set(quadIdx * 4 + 0, edgeColor); + colArr->set(quadIdx * 4 + 1, edgeColor); + colArr->set(quadIdx * 4 + 2, edgeColor); + colArr->set(quadIdx * 4 + 3, edgeColor); + } + } + + geo->setVertexAttribute(new cvf::Vec2fVertexAttribute("a_localCoord", localCoords.p())); + geo->setVertexAttribute(new cvf::FloatVertexAttribute("a_colorCell", cellColorTextureCoordArray.p())); + + cvf::ref faceIntAttribute = new cvf::IntVertexAttributeDirect("a_face", faceIndexArray.p()); + geo->setVertexAttribute(faceIntAttribute.p()); + + geo->setVertexAttribute(new cvf::FloatVertexAttribute("a_colorPosI", cellEdgeColorTextureCoordsArrays.at(0))); + geo->setVertexAttribute(new cvf::FloatVertexAttribute("a_colorNegI", cellEdgeColorTextureCoordsArrays.at(1))); + geo->setVertexAttribute(new cvf::FloatVertexAttribute("a_colorPosJ", cellEdgeColorTextureCoordsArrays.at(2))); + geo->setVertexAttribute(new cvf::FloatVertexAttribute("a_colorNegJ", cellEdgeColorTextureCoordsArrays.at(3))); + geo->setVertexAttribute(new cvf::FloatVertexAttribute("a_colorPosK", cellEdgeColorTextureCoordsArrays.at(4))); + geo->setVertexAttribute(new cvf::FloatVertexAttribute("a_colorNegK", cellEdgeColorTextureCoordsArrays.at(5))); } bool RivCellEdgeGeometryUtils::hideScalarValue(double scalarValue, double scalarValueToHide, double tolerance) @@ -188,96 +188,95 @@ bool RivCellEdgeGeometryUtils::hideScalarValue(double scalarValue, double scalar /// //-------------------------------------------------------------------------------------------------- void RivCellEdgeGeometryUtils::addTernaryCellEdgeResultsToDrawableGeo(size_t timeStepIndex, RimEclipseCellColors* cellResultColors, RimCellEdgeColors* cellEdgeResultColors, - const cvf::StructGridQuadToCellFaceMapper* quadToCellFaceMapper, - cvf::DrawableGeo* geo, size_t gridIndex, float opacityLevel) + const cvf::StructGridQuadToCellFaceMapper* quadToCellFaceMapper, + cvf::DrawableGeo* geo, size_t gridIndex, float opacityLevel) { - RigCaseData* eclipseCase = cellResultColors->reservoirView()->eclipseCase()->reservoirData(); - CVF_ASSERT(eclipseCase != NULL); + RigCaseData* eclipseCase = cellResultColors->reservoirView()->eclipseCase()->reservoirData(); + CVF_ASSERT(eclipseCase != NULL); - cvf::ref cellEdgeResultAccessor = createCellEdgeCenterResultAccessor(cellResultColors, cellEdgeResultColors, timeStepIndex, eclipseCase, eclipseCase->grid(gridIndex)); + cvf::ref cellEdgeResultAccessor = createCellEdgeCenterResultAccessor(cellResultColors, cellEdgeResultColors, timeStepIndex, eclipseCase, eclipseCase->grid(gridIndex)); - size_t vertexCount = geo->vertexArray()->size(); - size_t quadCount = vertexCount / 4; + size_t vertexCount = geo->vertexArray()->size(); + size_t quadCount = vertexCount / 4; - cvf::ref localCoords = new cvf::Vec2fArray; - localCoords->resize(vertexCount); + cvf::ref localCoords = new cvf::Vec2fArray; + localCoords->resize(vertexCount); - cvf::ref faceIndexArray = new cvf::IntArray; - faceIndexArray->resize(vertexCount); + cvf::ref faceIndexArray = new cvf::IntArray; + faceIndexArray->resize(vertexCount); - cvf::ref vCellColorTextureCoordArray = new cvf::Vec2fArray; - vCellColorTextureCoordArray->resize(vertexCount); + cvf::ref vCellColorTextureCoordArray = new cvf::Vec2fArray; + vCellColorTextureCoordArray->resize(vertexCount); - // Build six cell face color arrays - cvf::Collection cellEdgeColorTextureCoordsArrays; - size_t idx; - for (idx = 0; idx < 6; idx++) - { - cvf::ref colorArray = new cvf::FloatArray; - colorArray->resize(vertexCount); - cellEdgeColorTextureCoordsArrays.push_back(colorArray.p()); - } + // Build six cell face color arrays + cvf::Collection cellEdgeColorTextureCoordsArrays; + size_t idx; + for (idx = 0; idx < 6; idx++) + { + cvf::ref colorArray = new cvf::FloatArray; + colorArray->resize(vertexCount); + cellEdgeColorTextureCoordsArrays.push_back(colorArray.p()); + } - RivTernaryScalarMapper* ternaryCellResultScalarMapper = cellResultColors->ternaryLegendConfig()->scalarMapper(); - cvf::ScalarMapper* edgeResultScalarMapper = cellEdgeResultColors->legendConfig()->scalarMapper(); + cvf::ScalarMapper* edgeResultScalarMapper = cellEdgeResultColors->legendConfig()->scalarMapper(); - double ignoredScalarValue = cellEdgeResultColors->ignoredScalarValue(); + double ignoredScalarValue = cellEdgeResultColors->ignoredScalarValue(); - RivTernaryTextureCoordsCreator texturer(cellResultColors, cellResultColors->ternaryLegendConfig(), - timeStepIndex, - gridIndex, - quadToCellFaceMapper); + RivTernaryTextureCoordsCreator texturer(cellResultColors, cellResultColors->ternaryLegendConfig(), + timeStepIndex, + gridIndex, + quadToCellFaceMapper); - texturer.createTextureCoords(vCellColorTextureCoordArray.p()); + texturer.createTextureCoords(vCellColorTextureCoordArray.p()); #pragma omp parallel for - for (int quadIdx = 0; quadIdx < static_cast(quadCount); quadIdx++) - { - localCoords->set(quadIdx * 4 + 0, cvf::Vec2f(0, 0)); - localCoords->set(quadIdx * 4 + 1, cvf::Vec2f(1, 0)); - localCoords->set(quadIdx * 4 + 2, cvf::Vec2f(1, 1)); - localCoords->set(quadIdx * 4 + 3, cvf::Vec2f(0, 1)); + for (int quadIdx = 0; quadIdx < static_cast(quadCount); quadIdx++) + { + localCoords->set(quadIdx * 4 + 0, cvf::Vec2f(0, 0)); + localCoords->set(quadIdx * 4 + 1, cvf::Vec2f(1, 0)); + localCoords->set(quadIdx * 4 + 2, cvf::Vec2f(1, 1)); + localCoords->set(quadIdx * 4 + 3, cvf::Vec2f(0, 1)); - faceIndexArray->set(quadIdx * 4 + 0, quadToCellFaceMapper->cellFace(quadIdx)); - faceIndexArray->set(quadIdx * 4 + 1, quadToCellFaceMapper->cellFace(quadIdx)); - faceIndexArray->set(quadIdx * 4 + 2, quadToCellFaceMapper->cellFace(quadIdx)); - faceIndexArray->set(quadIdx * 4 + 3, quadToCellFaceMapper->cellFace(quadIdx)); + faceIndexArray->set(quadIdx * 4 + 0, quadToCellFaceMapper->cellFace(quadIdx)); + faceIndexArray->set(quadIdx * 4 + 1, quadToCellFaceMapper->cellFace(quadIdx)); + faceIndexArray->set(quadIdx * 4 + 2, quadToCellFaceMapper->cellFace(quadIdx)); + faceIndexArray->set(quadIdx * 4 + 3, quadToCellFaceMapper->cellFace(quadIdx)); - size_t cellIndex = quadToCellFaceMapper->cellIndex(quadIdx); + size_t cellIndex = quadToCellFaceMapper->cellIndex(quadIdx); - float edgeColor; - for (size_t cubeFaceIdx = 0; cubeFaceIdx < 6; cubeFaceIdx++) - { - edgeColor = -1.0f; // Undefined texture coord. Shader handles this. + float edgeColor; + for (size_t cubeFaceIdx = 0; cubeFaceIdx < 6; cubeFaceIdx++) + { + edgeColor = -1.0f; // Undefined texture coord. Shader handles this. - double scalarValue = cellEdgeResultAccessor->cellFaceScalar(cellIndex, static_cast(cubeFaceIdx)); + double scalarValue = cellEdgeResultAccessor->cellFaceScalar(cellIndex, static_cast(cubeFaceIdx)); if (!hideScalarValue(scalarValue, ignoredScalarValue, 1e-2)) - { - edgeColor = edgeResultScalarMapper->mapToTextureCoord(scalarValue)[0]; - } + { + edgeColor = edgeResultScalarMapper->mapToTextureCoord(scalarValue)[0]; + } - cvf::FloatArray* colArr = cellEdgeColorTextureCoordsArrays.at(cubeFaceIdx); + cvf::FloatArray* colArr = cellEdgeColorTextureCoordsArrays.at(cubeFaceIdx); - colArr->set(quadIdx * 4 + 0, edgeColor); - colArr->set(quadIdx * 4 + 1, edgeColor); - colArr->set(quadIdx * 4 + 2, edgeColor); - colArr->set(quadIdx * 4 + 3, edgeColor); - } - } + colArr->set(quadIdx * 4 + 0, edgeColor); + colArr->set(quadIdx * 4 + 1, edgeColor); + colArr->set(quadIdx * 4 + 2, edgeColor); + colArr->set(quadIdx * 4 + 3, edgeColor); + } + } - geo->setVertexAttribute(new cvf::Vec2fVertexAttribute("a_localCoord", localCoords.p())); - geo->setVertexAttribute(new cvf::Vec2fVertexAttribute("a_cellTextureCoord", vCellColorTextureCoordArray.p())); + geo->setVertexAttribute(new cvf::Vec2fVertexAttribute("a_localCoord", localCoords.p())); + geo->setVertexAttribute(new cvf::Vec2fVertexAttribute("a_cellTextureCoord", vCellColorTextureCoordArray.p())); - cvf::ref faceIntAttribute = new cvf::IntVertexAttributeDirect("a_face", faceIndexArray.p()); - geo->setVertexAttribute(faceIntAttribute.p()); + cvf::ref faceIntAttribute = new cvf::IntVertexAttributeDirect("a_face", faceIndexArray.p()); + geo->setVertexAttribute(faceIntAttribute.p()); - geo->setVertexAttribute(new cvf::FloatVertexAttribute("a_colorPosI", cellEdgeColorTextureCoordsArrays.at(0))); - geo->setVertexAttribute(new cvf::FloatVertexAttribute("a_colorNegI", cellEdgeColorTextureCoordsArrays.at(1))); - geo->setVertexAttribute(new cvf::FloatVertexAttribute("a_colorPosJ", cellEdgeColorTextureCoordsArrays.at(2))); - geo->setVertexAttribute(new cvf::FloatVertexAttribute("a_colorNegJ", cellEdgeColorTextureCoordsArrays.at(3))); - geo->setVertexAttribute(new cvf::FloatVertexAttribute("a_colorPosK", cellEdgeColorTextureCoordsArrays.at(4))); - geo->setVertexAttribute(new cvf::FloatVertexAttribute("a_colorNegK", cellEdgeColorTextureCoordsArrays.at(5))); + geo->setVertexAttribute(new cvf::FloatVertexAttribute("a_colorPosI", cellEdgeColorTextureCoordsArrays.at(0))); + geo->setVertexAttribute(new cvf::FloatVertexAttribute("a_colorNegI", cellEdgeColorTextureCoordsArrays.at(1))); + geo->setVertexAttribute(new cvf::FloatVertexAttribute("a_colorPosJ", cellEdgeColorTextureCoordsArrays.at(2))); + geo->setVertexAttribute(new cvf::FloatVertexAttribute("a_colorNegJ", cellEdgeColorTextureCoordsArrays.at(3))); + geo->setVertexAttribute(new cvf::FloatVertexAttribute("a_colorPosK", cellEdgeColorTextureCoordsArrays.at(4))); + geo->setVertexAttribute(new cvf::FloatVertexAttribute("a_colorNegK", cellEdgeColorTextureCoordsArrays.at(5))); } @@ -285,28 +284,28 @@ void RivCellEdgeGeometryUtils::addTernaryCellEdgeResultsToDrawableGeo(size_t tim /// //-------------------------------------------------------------------------------------------------- cvf::ref RivCellEdgeGeometryUtils::createCellEdgeCenterResultAccessor( - RimEclipseCellColors* cellResultColors, - RimCellEdgeColors* cellEdgeResultColors, - size_t timeStepIndex, - RigCaseData* eclipseCase, - const RigGridBase* grid) + RimEclipseCellColors* cellResultColors, + RimCellEdgeColors* cellEdgeResultColors, + size_t timeStepIndex, + RigCaseData* eclipseCase, + const RigGridBase* grid) { - cvf::ref cellEdgeResultAccessor = new RigCellEdgeResultAccessor(); - { - size_t resultIndices[6]; - cellEdgeResultColors->gridScalarIndices(resultIndices); - RifReaderInterface::PorosityModelResultType porosityModel = RigCaseCellResultsData::convertFromProjectModelPorosityModel(cellResultColors->porosityModel()); - - size_t cubeFaceIdx; - for (cubeFaceIdx = 0; cubeFaceIdx < 6; cubeFaceIdx++) - { - // Assuming static values to be mapped onto cell edge, always using time step zero - cvf::ref daObj = RigResultAccessorFactory::createResultAccessor(eclipseCase, grid->gridIndex(), porosityModel, 0, resultIndices[cubeFaceIdx]); - cellEdgeResultAccessor->setDataAccessObjectForFace(static_cast(cubeFaceIdx), daObj.p()); - } - } - - return cellEdgeResultAccessor; + cvf::ref cellEdgeResultAccessor = new RigCellEdgeResultAccessor(); + { + size_t resultIndices[6]; + cellEdgeResultColors->gridScalarIndices(resultIndices); + RifReaderInterface::PorosityModelResultType porosityModel = RigCaseCellResultsData::convertFromProjectModelPorosityModel(cellResultColors->porosityModel()); + + size_t cubeFaceIdx; + for (cubeFaceIdx = 0; cubeFaceIdx < 6; cubeFaceIdx++) + { + // Assuming static values to be mapped onto cell edge, always using time step zero + cvf::ref daObj = RigResultAccessorFactory::createResultAccessor(eclipseCase, grid->gridIndex(), porosityModel, 0, resultIndices[cubeFaceIdx]); + cellEdgeResultAccessor->setDataAccessObjectForFace(static_cast(cubeFaceIdx), daObj.p()); + } + } + + return cellEdgeResultAccessor; } //-------------------------------------------------------------------------------------------------- @@ -314,26 +313,26 @@ cvf::ref RivCellEdgeGeometryUtils::createCellEdgeCenterResult //-------------------------------------------------------------------------------------------------- cvf::ref RivCellEdgeGeometryUtils::createCellCenterResultAccessor(RimEclipseCellColors* cellResultColors, size_t timeStepIndex, RigCaseData* eclipseCase, const RigGridBase* grid) { - cvf::ref resultAccessor = NULL; - - if (cellResultColors->hasResult()) - { - if (!cellResultColors->hasDynamicResult()) - { - // Static result values are located at time step 0 - timeStepIndex = 0; - } - - RifReaderInterface::PorosityModelResultType porosityModel = RigCaseCellResultsData::convertFromProjectModelPorosityModel(cellResultColors->porosityModel()); - resultAccessor = RigResultAccessorFactory::createResultAccessor(eclipseCase, grid->gridIndex(), porosityModel, timeStepIndex, cellResultColors->resultVariable()); - } - - if (resultAccessor.isNull()) - { - resultAccessor = new RigHugeValResultAccessor; - } - - return resultAccessor; + cvf::ref resultAccessor = NULL; + + if (cellResultColors->hasResult()) + { + if (!cellResultColors->hasDynamicResult()) + { + // Static result values are located at time step 0 + timeStepIndex = 0; + } + + RifReaderInterface::PorosityModelResultType porosityModel = RigCaseCellResultsData::convertFromProjectModelPorosityModel(cellResultColors->porosityModel()); + resultAccessor = RigResultAccessorFactory::createResultAccessor(eclipseCase, grid->gridIndex(), porosityModel, timeStepIndex, cellResultColors->resultVariable()); + } + + if (resultAccessor.isNull()) + { + resultAccessor = new RigHugeValResultAccessor; + } + + return resultAccessor; } diff --git a/ApplicationCode/ModelVisualization/RivCellEdgeGeometryUtils.h b/ApplicationCode/ModelVisualization/RivCellEdgeGeometryUtils.h index 2bfb42c840..b9c0843a5f 100644 --- a/ApplicationCode/ModelVisualization/RivCellEdgeGeometryUtils.h +++ b/ApplicationCode/ModelVisualization/RivCellEdgeGeometryUtils.h @@ -24,8 +24,8 @@ namespace cvf { - class DrawableGeo; - class StructGridQuadToCellFaceMapper; + class DrawableGeo; + class StructGridQuadToCellFaceMapper; } class RimCellEdgeColors; @@ -38,36 +38,36 @@ class RigCaseData; class RivCellEdgeGeometryUtils { public: - static void addCellEdgeResultsToDrawableGeo(size_t timeStepIndex, - RimEclipseCellColors* cellResultColors, - RimCellEdgeColors* cellEdgeResultColors, - const cvf::StructGridQuadToCellFaceMapper* quadToCellFaceMapper, - cvf::DrawableGeo* geo, - size_t gridIndex, - float opacityLevel); + static void addCellEdgeResultsToDrawableGeo(size_t timeStepIndex, + RimEclipseCellColors* cellResultColors, + RimCellEdgeColors* cellEdgeResultColors, + const cvf::StructGridQuadToCellFaceMapper* quadToCellFaceMapper, + cvf::DrawableGeo* geo, + size_t gridIndex, + float opacityLevel); - static void addTernaryCellEdgeResultsToDrawableGeo(size_t timeStepIndex, - RimEclipseCellColors* cellResultColors, - RimCellEdgeColors* cellEdgeResultColors, - const cvf::StructGridQuadToCellFaceMapper* quadToCellFaceMapper, - cvf::DrawableGeo* geo, - size_t gridIndex, - float opacityLevel); + static void addTernaryCellEdgeResultsToDrawableGeo(size_t timeStepIndex, + RimEclipseCellColors* cellResultColors, + RimCellEdgeColors* cellEdgeResultColors, + const cvf::StructGridQuadToCellFaceMapper* quadToCellFaceMapper, + cvf::DrawableGeo* geo, + size_t gridIndex, + float opacityLevel); private: - static cvf::ref createCellCenterResultAccessor( - RimEclipseCellColors* cellResultColors, - size_t timeStepIndex, - RigCaseData* eclipseCase, - const RigGridBase* grid); + static cvf::ref createCellCenterResultAccessor( + RimEclipseCellColors* cellResultColors, + size_t timeStepIndex, + RigCaseData* eclipseCase, + const RigGridBase* grid); - static cvf::ref createCellEdgeCenterResultAccessor( - RimEclipseCellColors* cellResultColors, - RimCellEdgeColors* cellEdgeResultColors, - size_t timeStepIndex, - RigCaseData* eclipseCase, - const RigGridBase* grid); + static cvf::ref createCellEdgeCenterResultAccessor( + RimEclipseCellColors* cellResultColors, + RimCellEdgeColors* cellEdgeResultColors, + size_t timeStepIndex, + RigCaseData* eclipseCase, + const RigGridBase* grid); static bool hideScalarValue(double scalarValue, double scalarValueToHide, double tolerance); }; diff --git a/ApplicationCode/ModelVisualization/RivCellSetEnum.h b/ApplicationCode/ModelVisualization/RivCellSetEnum.h index 0382ddc23f..7a34fe63d7 100644 --- a/ApplicationCode/ModelVisualization/RivCellSetEnum.h +++ b/ApplicationCode/ModelVisualization/RivCellSetEnum.h @@ -21,6 +21,7 @@ enum RivCellSetEnum { + OVERRIDDEN_CELL_VISIBILITY, ////< Use the total visibility from a different case directly ALL_CELLS, ACTIVE, ///< All Active cells without ALL_WELL_CELLS ALL_WELL_CELLS, ///< All cells ever having a connection to a well (Might be inactive cells as well. Wellhead cells typically) diff --git a/ApplicationCode/ModelVisualization/RivFaultGeometryGenerator.h b/ApplicationCode/ModelVisualization/RivFaultGeometryGenerator.h index a41e75a67f..59e14a4bfd 100644 --- a/ApplicationCode/ModelVisualization/RivFaultGeometryGenerator.h +++ b/ApplicationCode/ModelVisualization/RivFaultGeometryGenerator.h @@ -50,8 +50,8 @@ class RivFaultGeometryGenerator : public cvf::Object // Mapping between cells and geometry - const cvf::StructGridQuadToCellFaceMapper* quadToCellFaceMapper() { return m_quadMapper.p(); } - const cvf::StuctGridTriangleToCellFaceMapper* triangleToCellFaceMapper() { return m_triangleMapper.p(); } + const cvf::StructGridQuadToCellFaceMapper* quadToCellFaceMapper() { return m_quadMapper.p(); } + const cvf::StuctGridTriangleToCellFaceMapper* triangleToCellFaceMapper() { return m_triangleMapper.p(); } // Generated geometry cvf::ref generateSurface(); diff --git a/ApplicationCode/ModelVisualization/RivFaultPartMgr.cpp b/ApplicationCode/ModelVisualization/RivFaultPartMgr.cpp index 9a068e907c..4e5505915c 100644 --- a/ApplicationCode/ModelVisualization/RivFaultPartMgr.cpp +++ b/ApplicationCode/ModelVisualization/RivFaultPartMgr.cpp @@ -100,12 +100,6 @@ void RivFaultPartMgr::updateCellResultColor(size_t timeStepIndex, RimEclipseCell updateNNCColors(cellResultColors); - size_t scalarSetIndex = cellResultColors->scalarResultIndex(); - - // If the result is static, only read that. - size_t resTimeStepIdx = timeStepIndex; - if (cellResultColors->hasStaticResult()) resTimeStepIdx = 0; - RifReaderInterface::PorosityModelResultType porosityModel = RigCaseCellResultsData::convertFromProjectModelPorosityModel(cellResultColors->porosityModel()); RimEclipseView* eclipseView = cellResultColors->reservoirView(); RigCaseData* eclipseCase = eclipseView->eclipseCase()->reservoirData(); @@ -115,16 +109,16 @@ void RivFaultPartMgr::updateCellResultColor(size_t timeStepIndex, RimEclipseCell { if (cellResultColors->isTernarySaturationSelected()) { - RivTernaryTextureCoordsCreator texturer(cellResultColors, cellResultColors->ternaryLegendConfig(), - timeStepIndex, - m_grid->gridIndex(), - m_nativeFaultGenerator->quadToCellFaceMapper()); + RivTernaryTextureCoordsCreator texturer(cellResultColors, cellResultColors->ternaryLegendConfig(), + timeStepIndex, + m_grid->gridIndex(), + m_nativeFaultGenerator->quadToCellFaceMapper()); - texturer.createTextureCoords(m_nativeFaultFacesTextureCoords.p()); + texturer.createTextureCoords(m_nativeFaultFacesTextureCoords.p()); - const RivTernaryScalarMapper* mapper = cellResultColors->ternaryLegendConfig()->scalarMapper(); + const RivTernaryScalarMapper* mapper = cellResultColors->ternaryLegendConfig()->scalarMapper(); RivScalarMapperUtils::applyTernaryTextureResultsToPart(m_nativeFaultFaces.p(), m_nativeFaultFacesTextureCoords.p(), mapper, m_opacityLevel, this->faceCullingMode(), eclipseView->isLightingDisabled()); - } + } else { RivTextureCoordsCreator texturer(cellResultColors, @@ -132,50 +126,50 @@ void RivFaultPartMgr::updateCellResultColor(size_t timeStepIndex, RimEclipseCell m_grid->gridIndex(), m_nativeFaultGenerator->quadToCellFaceMapper()); - if (!texturer.isValid()) - { - return; - } + if (!texturer.isValid()) + { + return; + } texturer.createTextureCoords(m_nativeFaultFacesTextureCoords.p()); - const cvf::ScalarMapper* mapper = cellResultColors->legendConfig()->scalarMapper(); + const cvf::ScalarMapper* mapper = cellResultColors->legendConfig()->scalarMapper(); RivScalarMapperUtils::applyTextureResultsToPart(m_nativeFaultFaces.p(), m_nativeFaultFacesTextureCoords.p(), mapper, m_opacityLevel, this->faceCullingMode(), eclipseView->isLightingDisabled()); } } if (m_oppositeFaultFaces.notNull()) { - if (cellResultColors->isTernarySaturationSelected()) - { - RivTernaryTextureCoordsCreator texturer(cellResultColors, cellResultColors->ternaryLegendConfig(), - timeStepIndex, - m_grid->gridIndex(), - m_oppositeFaultGenerator->quadToCellFaceMapper()); - - texturer.createTextureCoords(m_oppositeFaultFacesTextureCoords.p()); - - const RivTernaryScalarMapper* mapper = cellResultColors->ternaryLegendConfig()->scalarMapper(); - RivScalarMapperUtils::applyTernaryTextureResultsToPart(m_oppositeFaultFaces.p(), m_oppositeFaultFacesTextureCoords.p(), mapper, m_opacityLevel, this->faceCullingMode(), eclipseView->isLightingDisabled()); - } - else - { - RivTextureCoordsCreator texturer(cellResultColors, - timeStepIndex, - m_grid->gridIndex(), - m_oppositeFaultGenerator->quadToCellFaceMapper()); - - if (!texturer.isValid()) - { - return; - } - - texturer.createTextureCoords(m_oppositeFaultFacesTextureCoords.p()); - - const cvf::ScalarMapper* mapper = cellResultColors->legendConfig()->scalarMapper(); + if (cellResultColors->isTernarySaturationSelected()) + { + RivTernaryTextureCoordsCreator texturer(cellResultColors, cellResultColors->ternaryLegendConfig(), + timeStepIndex, + m_grid->gridIndex(), + m_oppositeFaultGenerator->quadToCellFaceMapper()); + + texturer.createTextureCoords(m_oppositeFaultFacesTextureCoords.p()); + + const RivTernaryScalarMapper* mapper = cellResultColors->ternaryLegendConfig()->scalarMapper(); + RivScalarMapperUtils::applyTernaryTextureResultsToPart(m_oppositeFaultFaces.p(), m_oppositeFaultFacesTextureCoords.p(), mapper, m_opacityLevel, this->faceCullingMode(), eclipseView->isLightingDisabled()); + } + else + { + RivTextureCoordsCreator texturer(cellResultColors, + timeStepIndex, + m_grid->gridIndex(), + m_oppositeFaultGenerator->quadToCellFaceMapper()); + + if (!texturer.isValid()) + { + return; + } + + texturer.createTextureCoords(m_oppositeFaultFacesTextureCoords.p()); + + const cvf::ScalarMapper* mapper = cellResultColors->legendConfig()->scalarMapper(); RivScalarMapperUtils::applyTextureResultsToPart(m_oppositeFaultFaces.p(), m_oppositeFaultFacesTextureCoords.p(), mapper, m_opacityLevel, this->faceCullingMode(), eclipseView->isLightingDisabled()); - } - } + } + } } //-------------------------------------------------------------------------------------------------- @@ -185,30 +179,30 @@ void RivFaultPartMgr::updateCellEdgeResultColor(size_t timeStepIndex, RimEclipse { updateNNCColors(cellResultColors); - if (m_nativeFaultFaces.notNull()) - { - cvf::DrawableGeo* dg = dynamic_cast(m_nativeFaultFaces->drawable()); - if (dg) - { - cvf::ref eff = RivScalarMapperUtils::createCellEdgeEffect(dg, m_nativeFaultGenerator->quadToCellFaceMapper(), - m_grid->gridIndex(), + if (m_nativeFaultFaces.notNull()) + { + cvf::DrawableGeo* dg = dynamic_cast(m_nativeFaultFaces->drawable()); + if (dg) + { + cvf::ref eff = RivScalarMapperUtils::createCellEdgeEffect(dg, m_nativeFaultGenerator->quadToCellFaceMapper(), + m_grid->gridIndex(), timeStepIndex, cellResultColors, cellEdgeResultColors, m_opacityLevel, m_defaultColor, this->faceCullingMode(), cellResultColors->reservoirView()->isLightingDisabled()); - m_nativeFaultFaces->setEffect(eff.p()); - } - } + m_nativeFaultFaces->setEffect(eff.p()); + } + } - if (m_oppositeFaultFaces.notNull()) - { - cvf::DrawableGeo* dg = dynamic_cast(m_oppositeFaultFaces->drawable()); - if (dg) - { - cvf::ref eff = RivScalarMapperUtils::createCellEdgeEffect(dg, m_oppositeFaultGenerator->quadToCellFaceMapper(), m_grid->gridIndex(), + if (m_oppositeFaultFaces.notNull()) + { + cvf::DrawableGeo* dg = dynamic_cast(m_oppositeFaultFaces->drawable()); + if (dg) + { + cvf::ref eff = RivScalarMapperUtils::createCellEdgeEffect(dg, m_oppositeFaultGenerator->quadToCellFaceMapper(), m_grid->gridIndex(), timeStepIndex, cellResultColors, cellEdgeResultColors, m_opacityLevel, m_defaultColor, this->faceCullingMode(), cellResultColors->reservoirView()->isLightingDisabled()); - m_oppositeFaultFaces->setEffect(eff.p()); - } - } + m_oppositeFaultFaces->setEffect(eff.p()); + } + } } const int priFaultGeo = 1; @@ -368,7 +362,7 @@ void RivFaultPartMgr::updatePartEffect() caf::SurfaceEffectGenerator geometryEffgen(m_defaultColor, caf::PO_1); geometryEffgen.setCullBackfaces(faceCullingMode()); - cvf::ref geometryOnlyEffect = geometryEffgen.generateEffect(); + cvf::ref geometryOnlyEffect = geometryEffgen.generateCachedEffect(); if (m_nativeFaultFaces.notNull()) { @@ -387,7 +381,7 @@ void RivFaultPartMgr::updatePartEffect() cvf::ref eff; caf::MeshEffectGenerator faultEffGen(prefs->defaultFaultGridLineColors()); - eff = faultEffGen.generateEffect(); + eff = faultEffGen.generateCachedEffect(); if (m_nativeFaultGridLines.notNull()) { @@ -457,12 +451,15 @@ void RivFaultPartMgr::createLabelWithAnchorLine(const cvf::Part* part) cvf::Color3f defWellLabelColor = RiaApplication::instance()->preferences()->defaultWellLabelColor(); { - std::vector parentObjects; - m_rimFault->parentObjectsOfType(parentObjects); - - if (parentObjects.size() > 0) + RimFault* noConstRimFault = const_cast(m_rimFault); + if (noConstRimFault) { - defWellLabelColor = parentObjects[0]->faultLabelColor();; + RimFaultCollection* parentObject; + noConstRimFault->firstAnchestorOrThisOfType(parentObject); + if (parentObject) + { + defWellLabelColor = parentObject->faultLabelColor();; + } } } @@ -511,7 +508,7 @@ void RivFaultPartMgr::createLabelWithAnchorLine(const cvf::Part* part) m_faultLabelLinePart->updateBoundingBox(); caf::MeshEffectGenerator gen(m_rimFault->faultColor()); - cvf::ref eff = gen.generateEffect(); + cvf::ref eff = gen.generateCachedEffect(); m_faultLabelLinePart->setEffect(eff.p()); } @@ -674,13 +671,13 @@ void RivFaultPartMgr::updateNNCColors(RimEclipseCellColors* cellResultColors) { // Move NNC closer to camera to avoid z-fighting with grid surface caf::ScalarMapperEffectGenerator nncEffgen(mapper, caf::PO_NEG_LARGE); - nncEffect = nncEffgen.generateEffect(); + nncEffect = nncEffgen.generateCachedEffect(); } else { // If no grid is present, use same offset as grid geometry to be able to see mesh lines caf::ScalarMapperEffectGenerator nncEffgen(mapper, caf::PO_1); - nncEffect = nncEffgen.generateEffect(); + nncEffect = nncEffgen.generateCachedEffect(); } cvf::DrawableGeo* dg = dynamic_cast(m_NNCFaces->drawable()); @@ -702,13 +699,13 @@ void RivFaultPartMgr::updateNNCColors(RimEclipseCellColors* cellResultColors) { // Move NNC closer to camera to avoid z-fighting with grid surface caf::SurfaceEffectGenerator nncEffgen(nncColor, caf::PO_NEG_LARGE); - nncEffect = nncEffgen.generateEffect(); + nncEffect = nncEffgen.generateCachedEffect(); } else { // If no grid is present, use same offset as grid geometry to be able to see mesh lines caf::SurfaceEffectGenerator nncEffgen(nncColor, caf::PO_1); - nncEffect = nncEffgen.generateEffect(); + nncEffect = nncEffgen.generateCachedEffect(); } m_NNCFaces->setEffect(nncEffect.p()); diff --git a/ApplicationCode/ModelVisualization/RivGridPartMgr.cpp b/ApplicationCode/ModelVisualization/RivGridPartMgr.cpp index 8b4241cbe0..6cec946ce5 100644 --- a/ApplicationCode/ModelVisualization/RivGridPartMgr.cpp +++ b/ApplicationCode/ModelVisualization/RivGridPartMgr.cpp @@ -133,7 +133,7 @@ void RivGridPartMgr::generatePartGeometry(cvf::StructGridGeometryGenerator& geoB // Set default effect caf::SurfaceEffectGenerator geometryEffgen(cvf::Color4f(cvf::Color3f::WHITE), caf::PO_1); - cvf::ref geometryOnlyEffect = geometryEffgen.generateEffect(); + cvf::ref geometryOnlyEffect = geometryEffgen.generateCachedEffect(); part->setEffect(geometryOnlyEffect.p()); part->setEnableMask(surfaceBit); m_surfaceFaces = part; @@ -161,7 +161,7 @@ void RivGridPartMgr::generatePartGeometry(cvf::StructGridGeometryGenerator& geoB cvf::ref eff; caf::MeshEffectGenerator effGen(prefs->defaultGridLineColors()); - eff = effGen.generateEffect(); + eff = effGen.generateCachedEffect(); // Set priority to make sure fault lines are rendered first part->setPriority(10); @@ -193,7 +193,7 @@ void RivGridPartMgr::updateCellColor(cvf::Color4f color) // Set default effect caf::SurfaceEffectGenerator geometryEffgen(color, caf::PO_1); - cvf::ref geometryOnlyEffect = geometryEffgen.generateEffect(); + cvf::ref geometryOnlyEffect = geometryEffgen.generateCachedEffect(); if (m_surfaceFaces.notNull()) m_surfaceFaces->setEffect(geometryOnlyEffect.p()); @@ -213,7 +213,7 @@ void RivGridPartMgr::updateCellColor(cvf::Color4f color) if (m_surfaceFaces.notNull()) { caf::MeshEffectGenerator effGen(prefs->defaultGridLineColors()); - eff = effGen.generateEffect(); + eff = effGen.generateCachedEffect(); m_surfaceGridLines->setEffect(eff.p()); } } @@ -225,42 +225,40 @@ void RivGridPartMgr::updateCellResultColor(size_t timeStepIndex, RimEclipseCellC { CVF_ASSERT(cellResultColors); - RigCaseData* eclipseCase = cellResultColors->reservoirView()->eclipseCase()->reservoirData(); - cvf::ref surfaceFacesColorArray; // Outer surface - if (m_surfaceFaces.notNull()) - { - if (cellResultColors->isTernarySaturationSelected()) - { - RivTernaryTextureCoordsCreator texturer(cellResultColors, cellResultColors->ternaryLegendConfig(), - timeStepIndex, - m_grid->gridIndex(), - m_surfaceGenerator.quadToCellFaceMapper()); - - texturer.createTextureCoords(m_surfaceFacesTextureCoords.p()); - - const RivTernaryScalarMapper* mapper = cellResultColors->ternaryLegendConfig()->scalarMapper(); + if (m_surfaceFaces.notNull()) + { + if (cellResultColors->isTernarySaturationSelected()) + { + RivTernaryTextureCoordsCreator texturer(cellResultColors, cellResultColors->ternaryLegendConfig(), + timeStepIndex, + m_grid->gridIndex(), + m_surfaceGenerator.quadToCellFaceMapper()); + + texturer.createTextureCoords(m_surfaceFacesTextureCoords.p()); + + const RivTernaryScalarMapper* mapper = cellResultColors->ternaryLegendConfig()->scalarMapper(); RivScalarMapperUtils::applyTernaryTextureResultsToPart(m_surfaceFaces.p(), m_surfaceFacesTextureCoords.p(), mapper, m_opacityLevel, caf::FC_NONE, cellResultColors->reservoirView()->isLightingDisabled()); - } - else - { - RivTextureCoordsCreator texturer(cellResultColors, - timeStepIndex, - m_grid->gridIndex(), - m_surfaceGenerator.quadToCellFaceMapper()); - if (!texturer.isValid()) - { - return; - } - - texturer.createTextureCoords(m_surfaceFacesTextureCoords.p()); - - const cvf::ScalarMapper* mapper = cellResultColors->legendConfig()->scalarMapper(); + } + else + { + RivTextureCoordsCreator texturer(cellResultColors, + timeStepIndex, + m_grid->gridIndex(), + m_surfaceGenerator.quadToCellFaceMapper()); + if (!texturer.isValid()) + { + return; + } + + texturer.createTextureCoords(m_surfaceFacesTextureCoords.p()); + + const cvf::ScalarMapper* mapper = cellResultColors->legendConfig()->scalarMapper(); RivScalarMapperUtils::applyTextureResultsToPart(m_surfaceFaces.p(), m_surfaceFacesTextureCoords.p(), mapper, m_opacityLevel, caf::FC_NONE, cellResultColors->reservoirView()->isLightingDisabled()); - } - } + } + } } //-------------------------------------------------------------------------------------------------- @@ -268,17 +266,17 @@ void RivGridPartMgr::updateCellResultColor(size_t timeStepIndex, RimEclipseCellC //-------------------------------------------------------------------------------------------------- void RivGridPartMgr::updateCellEdgeResultColor(size_t timeStepIndex, RimEclipseCellColors* cellResultColors, RimCellEdgeColors* cellEdgeResultColors) { - if (m_surfaceFaces.notNull()) - { - cvf::DrawableGeo* dg = dynamic_cast(m_surfaceFaces->drawable()); - if (dg) - { - cvf::ref eff = RivScalarMapperUtils::createCellEdgeEffect(dg, m_surfaceGenerator.quadToCellFaceMapper(), m_grid->gridIndex(), - timeStepIndex, cellResultColors, cellEdgeResultColors, m_opacityLevel, m_defaultColor, caf::FC_NONE, cellResultColors->reservoirView()->isLightingDisabled()); - - m_surfaceFaces->setEffect(eff.p()); - } - } + if (m_surfaceFaces.notNull()) + { + cvf::DrawableGeo* dg = dynamic_cast(m_surfaceFaces->drawable()); + if (dg) + { + cvf::ref eff = RivScalarMapperUtils::createCellEdgeEffect(dg, m_surfaceGenerator.quadToCellFaceMapper(), m_grid->gridIndex(), + timeStepIndex, cellResultColors, cellEdgeResultColors, m_opacityLevel, m_defaultColor, caf::FC_NONE, cellResultColors->reservoirView()->isLightingDisabled()); + + m_surfaceFaces->setEffect(eff.p()); + } + } } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ModelVisualization/RivPipeGeometryGenerator.cpp b/ApplicationCode/ModelVisualization/RivPipeGeometryGenerator.cpp index 0bdeea610f..19bff35595 100644 --- a/ApplicationCode/ModelVisualization/RivPipeGeometryGenerator.cpp +++ b/ApplicationCode/ModelVisualization/RivPipeGeometryGenerator.cpp @@ -472,9 +472,7 @@ void RivPipeGeometryGenerator::updateFilteredPipeCenterCoords() if (m_originalPipeCenterCoords->size() < 2) return; if (m_filteredPipeCenterCoords.size() > 0) return; - double squareDistanceTolerance = 1e-4*1e-4; - double angleTolerance = 1e-5; size_t firstSegmentWithLength = 0; size_t i; @@ -507,7 +505,6 @@ void RivPipeGeometryGenerator::updateFilteredPipeCenterCoords() cvf::Vec3d directionAB = coordB - coordA; // Skip segment lengths below tolerance - double dirLengthSq = directionAB.lengthSquared(); if (directionAB.lengthSquared() > squareDistanceTolerance) { lastValidDirectionAB = directionAB.getNormalized(); diff --git a/ApplicationCode/ModelVisualization/RivPipeGeometryGenerator.h b/ApplicationCode/ModelVisualization/RivPipeGeometryGenerator.h index d65d910299..40a392ada8 100644 --- a/ApplicationCode/ModelVisualization/RivPipeGeometryGenerator.h +++ b/ApplicationCode/ModelVisualization/RivPipeGeometryGenerator.h @@ -18,6 +18,8 @@ #pragma once +//class RivPipeQuadToSegmentMapper; + class RivPipeGeometryGenerator : public cvf::Object { public: @@ -70,6 +72,9 @@ class RivPipeGeometryGenerator : public cvf::Object // Map from generated cylinder segments to pipe result indices std::vector m_filteredPipeSegmentToResult; + // TODO: implement + //RivPipeQuadToSegmentMapper* m_quadToSegmentMapper; + double m_radius; double m_minimumBendAngle; double m_bendScalingFactor; diff --git a/ApplicationCode/ModelVisualization/RivPipeQuadToSegmentMapper.cpp b/ApplicationCode/ModelVisualization/RivPipeQuadToSegmentMapper.cpp new file mode 100644 index 0000000000..c0f9865ddd --- /dev/null +++ b/ApplicationCode/ModelVisualization/RivPipeQuadToSegmentMapper.cpp @@ -0,0 +1,27 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RivPipeQuadToSegmentMapper.h" + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RivPipeQuadToSegmentMapper::RivPipeQuadToSegmentMapper() +{ +} diff --git a/ApplicationCode/ModelVisualization/RivPipeQuadToSegmentMapper.h b/ApplicationCode/ModelVisualization/RivPipeQuadToSegmentMapper.h new file mode 100644 index 0000000000..8e36942029 --- /dev/null +++ b/ApplicationCode/ModelVisualization/RivPipeQuadToSegmentMapper.h @@ -0,0 +1,37 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include +#include + + +//================================================================================================== +/// +/// TODO: Implement +//================================================================================================== +class RivPipeQuadToSegmentMapper +{ +public: + RivPipeQuadToSegmentMapper(); + +private: + std::vector m_quadsToSegment; +}; diff --git a/ApplicationCode/ModelVisualization/RivReservoirFaultsPartMgr.cpp b/ApplicationCode/ModelVisualization/RivReservoirFaultsPartMgr.cpp index 659de5d5b7..390bf19d25 100644 --- a/ApplicationCode/ModelVisualization/RivReservoirFaultsPartMgr.cpp +++ b/ApplicationCode/ModelVisualization/RivReservoirFaultsPartMgr.cpp @@ -209,8 +209,6 @@ void RivReservoirFaultsPartMgr::updateColors(size_t timeStepIndex, RimEclipseCel for (size_t i = 0; i < faultCollection->faults.size(); i++) { - RimFault* rimFault = faultCollection->faults[i]; - if (cellResultColors && (cellResultColors->hasResult() || cellResultColors->isTernarySaturationSelected()) ) { m_faultParts[i]->updateCellResultColor(timeStepIndex, cellResultColors); diff --git a/ApplicationCode/ModelVisualization/RivReservoirPartMgr.cpp b/ApplicationCode/ModelVisualization/RivReservoirPartMgr.cpp index 3d5c18190e..a99d8c7218 100644 --- a/ApplicationCode/ModelVisualization/RivReservoirPartMgr.cpp +++ b/ApplicationCode/ModelVisualization/RivReservoirPartMgr.cpp @@ -18,7 +18,6 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RiaStdInclude.h" #include "RivReservoirPartMgr.h" #include "cvfStructGrid.h" @@ -204,10 +203,10 @@ void RivReservoirPartMgr::setFaultForceVisibility(bool isGeneratedByFilter) //-------------------------------------------------------------------------------------------------- void RivReservoirPartMgr::updateFaultCellEdgeResultColor(size_t timeStepIndex, RimEclipseCellColors* cellResultColors, RimCellEdgeColors* cellEdgeResultColors) { - if (m_faultsPartMgr.notNull()) - { - m_faultsPartMgr->updateCellEdgeResultColor(timeStepIndex, cellResultColors, cellEdgeResultColors); - } + if (m_faultsPartMgr.notNull()) + { + m_faultsPartMgr->updateCellEdgeResultColor(timeStepIndex, cellResultColors, cellEdgeResultColors); + } } diff --git a/ApplicationCode/ModelVisualization/RivReservoirPartMgr.h b/ApplicationCode/ModelVisualization/RivReservoirPartMgr.h index 5616f7cd25..69cee52abd 100644 --- a/ApplicationCode/ModelVisualization/RivReservoirPartMgr.h +++ b/ApplicationCode/ModelVisualization/RivReservoirPartMgr.h @@ -20,6 +20,7 @@ #pragma once +#include "cvfBase.h" #include "cvfArray.h" #include "cvfCollection.h" @@ -66,9 +67,9 @@ class RivReservoirPartMgr: public cvf::Object // Faults void updateFaultColors(size_t timeStepIndex, RimEclipseCellColors* cellResultColors); - void updateFaultCellEdgeResultColor(size_t timeStepIndex, RimEclipseCellColors* cellResultColors, - RimCellEdgeColors* cellEdgeResultColors); - void appendFaultPartsToModel(cvf::ModelBasicList* model); + void updateFaultCellEdgeResultColor(size_t timeStepIndex, RimEclipseCellColors* cellResultColors, + RimCellEdgeColors* cellEdgeResultColors); + void appendFaultPartsToModel(cvf::ModelBasicList* model); void appendFaultLabelPartsToModel(cvf::ModelBasicList* model); private: diff --git a/ApplicationCode/ModelVisualization/RivReservoirPipesPartMgr.cpp b/ApplicationCode/ModelVisualization/RivReservoirPipesPartMgr.cpp index 7b9d911897..75b18cb451 100644 --- a/ApplicationCode/ModelVisualization/RivReservoirPipesPartMgr.cpp +++ b/ApplicationCode/ModelVisualization/RivReservoirPipesPartMgr.cpp @@ -18,22 +18,22 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RiaStdInclude.h" - #include "RivReservoirPipesPartMgr.h" + +#include "Rim3dOverlayInfoConfig.h" +#include "RimCellEdgeColors.h" +#include "RimCellRangeFilterCollection.h" +#include "RimEclipseCellColors.h" +#include "RimEclipsePropertyFilterCollection.h" #include "RimEclipseView.h" #include "RimEclipseWell.h" #include "RimEclipseWellCollection.h" -#include "RivWellPipesPartMgr.h" + #include "RivWellHeadPartMgr.h" -#include "RimCellEdgeColors.h" +#include "RivWellPipesPartMgr.h" -#include "cafPdmFieldCvfMat4d.h" #include "cafPdmFieldCvfColor.h" -#include "RimEclipseCellColors.h" -#include "RimCellRangeFilterCollection.h" -#include "RimEclipsePropertyFilterCollection.h" -#include "Rim3dOverlayInfoConfig.h" +#include "cafPdmFieldCvfMat4d.h" //-------------------------------------------------------------------------------------------------- /// diff --git a/ApplicationCode/ModelVisualization/RivReservoirPipesPartMgr.h b/ApplicationCode/ModelVisualization/RivReservoirPipesPartMgr.h index 1ba2b7a310..c41daa123e 100644 --- a/ApplicationCode/ModelVisualization/RivReservoirPipesPartMgr.h +++ b/ApplicationCode/ModelVisualization/RivReservoirPipesPartMgr.h @@ -20,9 +20,14 @@ #include "RimEclipseWellCollection.h" - #include "cvfCollection.h" +namespace cvf +{ + class Transform; + class ModelBasicList; +} + class RimEclipseView; class RivWellPipesPartMgr; class RivWellHeadPartMgr; @@ -36,7 +41,7 @@ class RivReservoirPipesPartMgr : public cvf::Object void clearGeometryCache(); void scheduleGeometryRegen(); - void setScaleTransform(cvf::Transform * scaleTransform); + void setScaleTransform(cvf::Transform* scaleTransform); void appendDynamicGeometryPartsToModel(cvf::ModelBasicList* model, size_t frameIndex); void updatePipeResultColor(size_t frameIndex); diff --git a/ApplicationCode/ModelVisualization/RivReservoirViewPartMgr.cpp b/ApplicationCode/ModelVisualization/RivReservoirViewPartMgr.cpp index d49c06c592..c3a99ca95e 100644 --- a/ApplicationCode/ModelVisualization/RivReservoirViewPartMgr.cpp +++ b/ApplicationCode/ModelVisualization/RivReservoirViewPartMgr.cpp @@ -18,8 +18,6 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RiaStdInclude.h" - #include "RivReservoirViewPartMgr.h" #include "RigCaseCellResultsData.h" @@ -40,6 +38,9 @@ #include "RimEclipseWellCollection.h" #include "RivGridPartMgr.h" +#include "RimViewController.h" +#include "RimViewLinker.h" +#include "RigCaseToCaseCellMapper.h" //-------------------------------------------------------------------------------------------------- /// @@ -59,6 +60,8 @@ void RivReservoirViewPartMgr::scheduleGeometryRegen(RivCellSetEnum geometryType) { switch (geometryType) { + case OVERRIDDEN_CELL_VISIBILITY: + clearGeometryCache(OVERRIDDEN_CELL_VISIBILITY); case INACTIVE: clearGeometryCache(INACTIVE); clearGeometryCache(RANGE_FILTERED_INACTIVE); @@ -184,6 +187,7 @@ void RivReservoirViewPartMgr::clearGeometryCache(RivCellSetEnum geomType) //-------------------------------------------------------------------------------------------------- void RivReservoirViewPartMgr::clearGeometryCache() { + clearGeometryCache(OVERRIDDEN_CELL_VISIBILITY); clearGeometryCache(ACTIVE); clearGeometryCache(ALL_WELL_CELLS); clearGeometryCache(VISIBLE_WELL_CELLS); @@ -268,6 +272,9 @@ void RivReservoirViewPartMgr::computeVisibility(cvf::UByteArray* cellVisibility, switch (geometryType) { + case OVERRIDDEN_CELL_VISIBILITY: + computeOverriddenCellVisibility(cellVisibility, grid); + break; case ACTIVE: computeNativeVisibility(cellVisibility, grid, activeCellInfo, eclipseCase->wellCellsInGrid(gridIdx), false, false, true, m_reservoirView->showMainGrid() ); break; @@ -582,6 +589,65 @@ void RivReservoirViewPartMgr::computeNativeVisibility(cvf::UByteArray* cellVisib } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RivReservoirViewPartMgr::computeOverriddenCellVisibility(cvf::UByteArray* cellVisibility, const RigGridBase* grid) +{ + + RimViewController* masterViewLink = m_reservoirView->viewController(); + + CVF_ASSERT(masterViewLink); + + RimView* masterView = masterViewLink->ownerViewLinker()->masterView(); + + // get cell visibility + #if 1 + cvf::ref totCellVisibility = masterView->currentTotalCellVisibility(); + #else + // Could get something more like + std::vector > gridsWithCellSetVisibility = masterView->getAllGridsCurrentCellSetsCellVisibility(); + #endif + + CVF_ASSERT(cellVisibility != NULL); + CVF_ASSERT(grid != NULL); + + size_t gridCellCount = grid->cellCount(); + cellVisibility->resize(gridCellCount); + cellVisibility->setAll(false); + + const RigCaseToCaseCellMapper* cellMapper = masterViewLink->cellMapper(); + + for (size_t lcIdx = 0; lcIdx < gridCellCount; ++lcIdx) + { + #if 1 + int reservoirCellIdx = static_cast(grid->reservoirCellIndex(lcIdx)); + int cellCount = 0; + const int* cellIndicesInMasterCase = cellMapper->masterCaseCellIndices(reservoirCellIdx, &cellCount); + + for (int mcIdx = 0; mcIdx < cellCount; ++mcIdx) + { + (*cellVisibility)[lcIdx] |= (*totCellVisibility)[cellIndicesInMasterCase[mcIdx]]; // If any is visible, show + } + + #else + + const RigGridCells& masterCaseCells = cellMapper->masterCaseGridAndLocalCellIndex(grid->gridIndex, lcIdx); + + for (int mcIdx = 0; mcIdx < masterCaseCells.cellCount(); ++mcIdx) + { + int cellSetCount = gridsWithCellSetVisibility[ masterCaseCells.gridIndex[mcIdx] ].size(); + for (int csIdx = 0; csIdx < cellSetCount; ++csIdx) + { + (*cellVisibility)[lcIdx] |= gridsWithCellSetVisibility[masterCaseCells.gridIndex[mcIdx]][masterCaseCells.cellIndex[mcIdx]]; + } + } + #endif + } +} + + + //-------------------------------------------------------------------------------------------------- /// Copy the data from source into destination. This is not trivial to do using cvf::Array ... @@ -719,8 +785,6 @@ void RivReservoirViewPartMgr::computePropertyVisibility(cvf::UByteArray* cellVis const double lowerBound = propertyFilter->lowerBound(); const double upperBound = propertyFilter->upperBound(); - size_t scalarResultIndex = propertyFilter->resultDefinition->scalarResultIndex(); - size_t adjustedTimeStepIndex = timeStepIndex; // Set time step to zero for static results @@ -734,7 +798,7 @@ void RivReservoirViewPartMgr::computePropertyVisibility(cvf::UByteArray* cellVis RifReaderInterface::PorosityModelResultType porosityModel = RigCaseCellResultsData::convertFromProjectModelPorosityModel(propertyFilter->resultDefinition()->porosityModel()); RigCaseData* eclipseCase = propFilterColl->reservoirView()->eclipseCase()->reservoirData(); - cvf::ref resultAccessor = RigResultAccessorFactory::createResultAccessor(eclipseCase, grid->gridIndex(), porosityModel, adjustedTimeStepIndex, propertyFilter->resultDefinition->resultVariable(), propertyFilter->resultDefinition->resultType()); + cvf::ref resultAccessor = RigResultAccessorFactory::createResultAccessor(eclipseCase, grid->gridIndex(), porosityModel, adjustedTimeStepIndex, propertyFilter->resultDefinition->resultVariable(), propertyFilter->resultDefinition->resultType()); CVF_ASSERT(resultAccessor.notNull()); //#pragma omp parallel for schedule(dynamic) @@ -801,7 +865,7 @@ void RivReservoirViewPartMgr::updateCellResultColor(RivCellSetEnum geometryType, void RivReservoirViewPartMgr::updateCellEdgeResultColor(RivCellSetEnum geometryType, size_t timeStepIndex, RimEclipseCellColors* cellResultColors, RimCellEdgeColors* cellEdgeResultColors) { RivReservoirPartMgr * pmgr = reservoirPartManager( geometryType, timeStepIndex ); - pmgr->updateCellEdgeResultColor(timeStepIndex, cellResultColors, cellEdgeResultColors); + pmgr->updateCellEdgeResultColor(timeStepIndex, cellResultColors, cellEdgeResultColors); } //-------------------------------------------------------------------------------------------------- @@ -809,8 +873,8 @@ void RivReservoirViewPartMgr::updateCellEdgeResultColor(RivCellSetEnum geometryT //-------------------------------------------------------------------------------------------------- void RivReservoirViewPartMgr::updateFaultCellEdgeResultColor(RivCellSetEnum geometryType, size_t timeStepIndex, RimEclipseCellColors* cellResultColors, RimCellEdgeColors* cellEdgeResultColors) { - RivReservoirPartMgr * pmgr = reservoirPartManager(geometryType, timeStepIndex); - pmgr->updateFaultCellEdgeResultColor(timeStepIndex, cellResultColors, cellEdgeResultColors); + RivReservoirPartMgr * pmgr = reservoirPartManager(geometryType, timeStepIndex); + pmgr->updateFaultCellEdgeResultColor(timeStepIndex, cellResultColors, cellEdgeResultColors); } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ModelVisualization/RivReservoirViewPartMgr.h b/ApplicationCode/ModelVisualization/RivReservoirViewPartMgr.h index 737e42742e..87e0e82672 100644 --- a/ApplicationCode/ModelVisualization/RivReservoirViewPartMgr.h +++ b/ApplicationCode/ModelVisualization/RivReservoirViewPartMgr.h @@ -52,16 +52,16 @@ class RivReservoirViewPartMgr: public cvf::Object void updateCellResultColor (RivCellSetEnum geometryType, size_t timeStepIndex, RimEclipseCellColors* cellResultColors); void updateCellEdgeResultColor(RivCellSetEnum geometryType, size_t timeStepIndex, - RimEclipseCellColors* cellResultColors, - RimCellEdgeColors* cellEdgeResultColors); + RimEclipseCellColors* cellResultColors, + RimCellEdgeColors* cellEdgeResultColors); // Faults void appendFaultsStaticGeometryPartsToModel(cvf::ModelBasicList* model, RivCellSetEnum geometryType); void appendFaultsDynamicGeometryPartsToModel(cvf::ModelBasicList* model, RivCellSetEnum geometryType, size_t frameIndex); void updateFaultColors(RivCellSetEnum geometryType, size_t timeStepIndex, RimEclipseCellColors* cellResultColors); - void updateFaultCellEdgeResultColor( RivCellSetEnum geometryType, size_t timeStepIndex, - RimEclipseCellColors* cellResultColors, - RimCellEdgeColors* cellEdgeResultColors); + void updateFaultCellEdgeResultColor( RivCellSetEnum geometryType, size_t timeStepIndex, + RimEclipseCellColors* cellResultColors, + RimCellEdgeColors* cellEdgeResultColors); // Fault labels RivCellSetEnum geometryTypeForFaultLabels(const std::vector& geometryTypes) const; @@ -83,7 +83,10 @@ class RivReservoirViewPartMgr: public cvf::Object static void computeNativeVisibility (cvf::UByteArray* cellVisibilities, const RigGridBase* grid, const RigActiveCellInfo* activeCellInfo, const cvf::UByteArray* cellIsInWellStatuses, bool invalidCellsIsVisible, bool inactiveCellsIsVisible, bool activeCellsIsVisible, bool mainGridIsVisible); void computeRangeVisibility (RivCellSetEnum geometryType, cvf::UByteArray* cellVisibilities, const RigGridBase* grid, const cvf::UByteArray* nativeVisibility, const RimCellRangeFilterCollection* rangeFilterColl); static void computePropertyVisibility(cvf::UByteArray* cellVisibilities, const RigGridBase* grid, size_t timeStepIndex, const cvf::UByteArray* rangeFilterVisibility, RimEclipsePropertyFilterCollection* propFilterColl); - static void copyByteArray(cvf::UByteArray* cellVisibilities, const cvf::UByteArray* cellIsWellStatuses ); + void computeOverriddenCellVisibility(cvf::UByteArray* cellVisibility, const RigGridBase* grid); + + + static void copyByteArray(cvf::UByteArray* dest, const cvf::UByteArray* source ); RivReservoirPartMgr * reservoirPartManager(RivCellSetEnum geometryType, size_t timeStepIndex ); @@ -99,6 +102,6 @@ class RivReservoirViewPartMgr: public cvf::Object std::vector m_propFilteredWellGeometryFramesNeedsRegen; cvf::ref m_scaleTransform; - caf::PdmPointer m_reservoirView; + caf::PdmPointer m_reservoirView; }; diff --git a/ApplicationCode/ModelVisualization/RivScalarMapperUtils.cpp b/ApplicationCode/ModelVisualization/RivScalarMapperUtils.cpp index b66ee7b5c1..1cfbbc3d5a 100644 --- a/ApplicationCode/ModelVisualization/RivScalarMapperUtils.cpp +++ b/ApplicationCode/ModelVisualization/RivScalarMapperUtils.cpp @@ -41,13 +41,13 @@ //-------------------------------------------------------------------------------------------------- void RivScalarMapperUtils::applyTextureResultsToPart(cvf::Part* part, cvf::Vec2fArray* textureCoords, const cvf::ScalarMapper* mapper, float opacityLevel, caf::FaceCulling faceCulling, bool disableLighting) { - CVF_ASSERT(part && textureCoords && mapper); + CVF_ASSERT(part && textureCoords && mapper); - cvf::DrawableGeo* dg = dynamic_cast(part->drawable()); - if (dg) dg->setTextureCoordArray(textureCoords); + cvf::DrawableGeo* dg = dynamic_cast(part->drawable()); + if (dg) dg->setTextureCoordArray(textureCoords); - cvf::ref scalarEffect = RivScalarMapperUtils::createScalarMapperEffect(mapper, opacityLevel, faceCulling, disableLighting); - part->setEffect(scalarEffect.p()); + cvf::ref scalarEffect = RivScalarMapperUtils::createScalarMapperEffect(mapper, opacityLevel, faceCulling, disableLighting); + part->setEffect(scalarEffect.p()); } //-------------------------------------------------------------------------------------------------- @@ -55,55 +55,55 @@ void RivScalarMapperUtils::applyTextureResultsToPart(cvf::Part* part, cvf::Vec2f //-------------------------------------------------------------------------------------------------- void RivScalarMapperUtils::applyTernaryTextureResultsToPart(cvf::Part* part, cvf::Vec2fArray* textureCoords, const RivTernaryScalarMapper* mapper, float opacityLevel, caf::FaceCulling faceCulling, bool disableLighting) { - CVF_ASSERT(part && textureCoords && mapper); + CVF_ASSERT(part && textureCoords && mapper); - cvf::DrawableGeo* dg = dynamic_cast(part->drawable()); - if (dg) dg->setTextureCoordArray(textureCoords); + cvf::DrawableGeo* dg = dynamic_cast(part->drawable()); + if (dg) dg->setTextureCoordArray(textureCoords); cvf::ref scalarEffect = RivScalarMapperUtils::createTernaryScalarMapperEffect(mapper, opacityLevel, faceCulling, disableLighting); - part->setEffect(scalarEffect.p()); + part->setEffect(scalarEffect.p()); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- cvf::ref RivScalarMapperUtils::createCellEdgeEffect(cvf::DrawableGeo* dg, - const cvf::StructGridQuadToCellFaceMapper* quadToCellFaceMapper, - size_t gridIndex, - size_t timeStepIndex, - RimEclipseCellColors* cellResultColors, - RimCellEdgeColors* cellEdgeResultColors, - float opacityLevel, + const cvf::StructGridQuadToCellFaceMapper* quadToCellFaceMapper, + size_t gridIndex, + size_t timeStepIndex, + RimEclipseCellColors* cellResultColors, + RimCellEdgeColors* cellEdgeResultColors, + float opacityLevel, cvf::Color3f defaultColor, caf::FaceCulling faceCulling, bool disableLighting) { - CellEdgeEffectGenerator cellFaceEffectGen(cellEdgeResultColors->legendConfig()->scalarMapper()); - - if (cellResultColors->isTernarySaturationSelected()) - { - RivCellEdgeGeometryUtils::addTernaryCellEdgeResultsToDrawableGeo(timeStepIndex, cellResultColors, cellEdgeResultColors, - quadToCellFaceMapper, dg, gridIndex, opacityLevel); - - RivTernaryScalarMapper* ternaryCellScalarMapper = cellResultColors->ternaryLegendConfig()->scalarMapper(); - cellFaceEffectGen.setTernaryScalarMapper(ternaryCellScalarMapper); - } - else - { - RivCellEdgeGeometryUtils::addCellEdgeResultsToDrawableGeo(timeStepIndex, cellResultColors, cellEdgeResultColors, - quadToCellFaceMapper, dg, gridIndex, opacityLevel); - - cvf::ScalarMapper* cellScalarMapper = cellResultColors->legendConfig()->scalarMapper(); - cellFaceEffectGen.setScalarMapper(cellScalarMapper); - } - - cellFaceEffectGen.setOpacityLevel(opacityLevel); - cellFaceEffectGen.setDefaultCellColor(defaultColor); + CellEdgeEffectGenerator cellFaceEffectGen(cellEdgeResultColors->legendConfig()->scalarMapper()); + + if (cellResultColors->isTernarySaturationSelected()) + { + RivCellEdgeGeometryUtils::addTernaryCellEdgeResultsToDrawableGeo(timeStepIndex, cellResultColors, cellEdgeResultColors, + quadToCellFaceMapper, dg, gridIndex, opacityLevel); + + RivTernaryScalarMapper* ternaryCellScalarMapper = cellResultColors->ternaryLegendConfig()->scalarMapper(); + cellFaceEffectGen.setTernaryScalarMapper(ternaryCellScalarMapper); + } + else + { + RivCellEdgeGeometryUtils::addCellEdgeResultsToDrawableGeo(timeStepIndex, cellResultColors, cellEdgeResultColors, + quadToCellFaceMapper, dg, gridIndex, opacityLevel); + + cvf::ScalarMapper* cellScalarMapper = cellResultColors->legendConfig()->scalarMapper(); + cellFaceEffectGen.setScalarMapper(cellScalarMapper); + } + + cellFaceEffectGen.setOpacityLevel(opacityLevel); + cellFaceEffectGen.setDefaultCellColor(defaultColor); cellFaceEffectGen.setFaceCulling(faceCulling); cellFaceEffectGen.disableLighting(disableLighting); - cvf::ref eff = cellFaceEffectGen.generateEffect(); - return eff; + cvf::ref eff = cellFaceEffectGen.generateCachedEffect(); + return eff; } //-------------------------------------------------------------------------------------------------- @@ -111,17 +111,17 @@ cvf::ref RivScalarMapperUtils::createCellEdgeEffect(cvf::DrawableGe //-------------------------------------------------------------------------------------------------- cvf::ref RivScalarMapperUtils::createScalarMapperEffect(const cvf::ScalarMapper* mapper, float opacityLevel, caf::FaceCulling faceCulling, bool disableLighting) { - CVF_ASSERT(mapper); + CVF_ASSERT(mapper); - caf::PolygonOffset polygonOffset = caf::PO_1; - caf::ScalarMapperEffectGenerator scalarEffgen(mapper, polygonOffset); - scalarEffgen.setOpacityLevel(opacityLevel); + caf::PolygonOffset polygonOffset = caf::PO_1; + caf::ScalarMapperEffectGenerator scalarEffgen(mapper, polygonOffset); + scalarEffgen.setOpacityLevel(opacityLevel); scalarEffgen.setFaceCulling(faceCulling); scalarEffgen.disableLighting(disableLighting); - cvf::ref scalarEffect = scalarEffgen.generateEffect(); + cvf::ref scalarEffect = scalarEffgen.generateCachedEffect(); - return scalarEffect; + return scalarEffect; } //-------------------------------------------------------------------------------------------------- @@ -129,15 +129,15 @@ cvf::ref RivScalarMapperUtils::createScalarMapperEffect(const cvf:: //-------------------------------------------------------------------------------------------------- cvf::ref RivScalarMapperUtils::createTernaryScalarMapperEffect(const RivTernaryScalarMapper* mapper, float opacityLevel, caf::FaceCulling faceCulling, bool disableLighting) { - CVF_ASSERT(mapper); + CVF_ASSERT(mapper); - caf::PolygonOffset polygonOffset = caf::PO_1; - RivTernaryScalarMapperEffectGenerator scalarEffgen(mapper, polygonOffset); - scalarEffgen.setOpacityLevel(opacityLevel); + caf::PolygonOffset polygonOffset = caf::PO_1; + RivTernaryScalarMapperEffectGenerator scalarEffgen(mapper, polygonOffset); + scalarEffgen.setOpacityLevel(opacityLevel); scalarEffgen.setFaceCulling(faceCulling); scalarEffgen.disableLighting(disableLighting); - cvf::ref scalarEffect = scalarEffgen.generateEffect(); + cvf::ref scalarEffect = scalarEffgen.generateCachedEffect(); - return scalarEffect; + return scalarEffect; } diff --git a/ApplicationCode/ModelVisualization/RivScalarMapperUtils.h b/ApplicationCode/ModelVisualization/RivScalarMapperUtils.h index 7ce0585fab..808c9957d2 100644 --- a/ApplicationCode/ModelVisualization/RivScalarMapperUtils.h +++ b/ApplicationCode/ModelVisualization/RivScalarMapperUtils.h @@ -26,11 +26,11 @@ namespace cvf { - class ScalarMapper; - class Part; - class Effect; - class StructGridQuadToCellFaceMapper; - class DrawableGeo; + class ScalarMapper; + class Part; + class Effect; + class StructGridQuadToCellFaceMapper; + class DrawableGeo; } class RivTernaryScalarMapper; @@ -46,13 +46,13 @@ class RivScalarMapperUtils static void applyTextureResultsToPart(cvf::Part* part, cvf::Vec2fArray* textureCoords, const cvf::ScalarMapper* mapper, float opacityLevel, caf::FaceCulling faceCulling, bool disableLighting); static void applyTernaryTextureResultsToPart(cvf::Part* part, cvf::Vec2fArray* textureCoords, const RivTernaryScalarMapper* mapper, float opacityLevel, caf::FaceCulling faceCulling, bool disableLighting); - static cvf::ref createCellEdgeEffect(cvf::DrawableGeo* dg, - const cvf::StructGridQuadToCellFaceMapper* quadToCellFaceMapper, - size_t gridIndex, - size_t timeStepIndex, - RimEclipseCellColors* cellResultColors, - RimCellEdgeColors* cellEdgeResultColors, - float opacityLevel, + static cvf::ref createCellEdgeEffect(cvf::DrawableGeo* dg, + const cvf::StructGridQuadToCellFaceMapper* quadToCellFaceMapper, + size_t gridIndex, + size_t timeStepIndex, + RimEclipseCellColors* cellResultColors, + RimCellEdgeColors* cellEdgeResultColors, + float opacityLevel, cvf::Color3f defaultColor, caf::FaceCulling faceCulling, bool disableLighting); diff --git a/ApplicationCode/ModelVisualization/RivTernaryResultToTextureMapper.h b/ApplicationCode/ModelVisualization/RivTernaryResultToTextureMapper.h index 45c8604585..fb43d44094 100644 --- a/ApplicationCode/ModelVisualization/RivTernaryResultToTextureMapper.h +++ b/ApplicationCode/ModelVisualization/RivTernaryResultToTextureMapper.h @@ -33,15 +33,15 @@ class RivTernaryResultToTextureMapper : public cvf::Object { public: - RivTernaryResultToTextureMapper(const RivTernaryScalarMapper* scalarMapper, const RigPipeInCellEvaluator* pipeInCellEvaluator) + RivTernaryResultToTextureMapper(const RivTernaryScalarMapper* scalarMapper, const RigPipeInCellEvaluator* pipeInCellEvaluator) : m_scalarMapper(scalarMapper), m_pipeInCellEvaluator(pipeInCellEvaluator) {} cvf::Vec2f getTexCoord(double soil, double sgas, size_t cellIndex) const { - bool isTransparent = m_pipeInCellEvaluator->isWellPipeInCell(cellIndex); + bool isTransparent = m_pipeInCellEvaluator->isWellPipeInCell(cellIndex); - return m_scalarMapper->mapToTextureCoord(soil, sgas, isTransparent); + return m_scalarMapper->mapToTextureCoord(soil, sgas, isTransparent); } private: diff --git a/ApplicationCode/ModelVisualization/RivTernaryScalarMapper.cpp b/ApplicationCode/ModelVisualization/RivTernaryScalarMapper.cpp index b0c5debb5e..9975b949f3 100644 --- a/ApplicationCode/ModelVisualization/RivTernaryScalarMapper.cpp +++ b/ApplicationCode/ModelVisualization/RivTernaryScalarMapper.cpp @@ -26,10 +26,10 @@ /// //-------------------------------------------------------------------------------------------------- RivTernaryScalarMapper::RivTernaryScalarMapper(const cvf::Color3f& undefScalarColor) -: m_undefScalarColor(undefScalarColor), - m_textureSize(128, 256) +: m_undefScalarColor(undefScalarColor), + m_textureSize(128, 256) { - setTernaryRanges(0.0, 1.0, 0.0, 1.0); + setTernaryRanges(0.0, 1.0, 0.0, 1.0); } //-------------------------------------------------------------------------------------------------- @@ -61,12 +61,12 @@ cvf::Vec2f RivTernaryScalarMapper::mapToTextureCoord(double soil, double sgas, b /// F * /// * * /// * * -/// * * Texture in this region is assigned the given opacity level +/// * * Texture in this region is assigned the given opacity level /// * * /// D *********** E /// C * SGAS /// * * -/// * * Texture in this region is opaque +/// * * Texture in this region is opaque /// * * /// * * /// A *********** B @@ -74,48 +74,48 @@ cvf::Vec2f RivTernaryScalarMapper::mapToTextureCoord(double soil, double sgas, b //-------------------------------------------------------------------------------------------------- bool RivTernaryScalarMapper::updateTexture(cvf::TextureImage* image, float opacityLevel) const { - CVF_ASSERT(image); - image->allocate(m_textureSize.x(), m_textureSize.y()); + CVF_ASSERT(image); + image->allocate(m_textureSize.x(), m_textureSize.y()); - // For now fill with white so we can see any errors more easily - image->fill(cvf::Color4ub(cvf::Color3::WHITE)); + // For now fill with white so we can see any errors more easily + image->fill(cvf::Color4ub(cvf::Color3::WHITE)); - - - cvf::uint halfTextureHeight = m_textureSize.y() / 2; - - // Create texture + + + cvf::uint halfTextureHeight = m_textureSize.y() / 2; + + // Create texture - float xStride = static_cast(1.0f / m_textureSize.x()); - float yStride = static_cast(1.0f / halfTextureHeight); + float xStride = static_cast(1.0f / m_textureSize.x()); + float yStride = static_cast(1.0f / halfTextureHeight); - float sgas_red = 0.0f; - for (cvf::uint yPos = 0; yPos < halfTextureHeight; yPos++) - { - float soil_green = 0.0f; - for (cvf::uint xPos = 0; xPos < m_textureSize.x() - yPos; xPos++) - { - float swat_blue = 1.0f - sgas_red - soil_green; + float sgas_red = 0.0f; + for (cvf::uint yPos = 0; yPos < halfTextureHeight; yPos++) + { + float soil_green = 0.0f; + for (cvf::uint xPos = 0; xPos < m_textureSize.x() - yPos; xPos++) + { + float swat_blue = 1.0f - sgas_red - soil_green; - cvf::Color3f floatCol(sgas_red, soil_green, swat_blue); + cvf::Color3f floatCol(sgas_red, soil_green, swat_blue); - cvf::ubyte rByteCol = floatCol.rByte(); - cvf::ubyte gByteCol = floatCol.gByte(); - cvf::ubyte bByteCol = floatCol.bByte(); + cvf::ubyte rByteCol = floatCol.rByte(); + cvf::ubyte gByteCol = floatCol.gByte(); + cvf::ubyte bByteCol = floatCol.bByte(); - const cvf::Color4ub clr(rByteCol, gByteCol, bByteCol, 255); - image->setPixel(xPos, yPos, clr); + const cvf::Color4ub clr(rByteCol, gByteCol, bByteCol, 255); + image->setPixel(xPos, yPos, clr); - // Set opacity - const cvf::Color4ub clrOpacity(rByteCol, gByteCol, bByteCol, static_cast(255 * opacityLevel)); - image->setPixel(xPos, yPos + halfTextureHeight, clrOpacity); + // Set opacity + const cvf::Color4ub clrOpacity(rByteCol, gByteCol, bByteCol, static_cast(255 * opacityLevel)); + image->setPixel(xPos, yPos + halfTextureHeight, clrOpacity); - soil_green += xStride; - } - sgas_red += yStride; - } + soil_green += xStride; + } + sgas_red += yStride; + } - return true; + return true; } //-------------------------------------------------------------------------------------------------- @@ -123,12 +123,12 @@ bool RivTernaryScalarMapper::updateTexture(cvf::TextureImage* image, float opaci //-------------------------------------------------------------------------------------------------- void RivTernaryScalarMapper::setTernaryRanges(double soilLower, double soilUpper, double sgasLower, double sgasUpper) { - m_rangeMinSoil = soilLower; - m_rangeMaxSoil = soilUpper; - m_soilFactor = 1.0 / (soilUpper - soilLower); + m_rangeMinSoil = soilLower; + m_rangeMaxSoil = soilUpper; + m_soilFactor = 1.0 / (soilUpper - soilLower); - m_rangeMinSgas = sgasLower; - m_rangeMaxSgas = sgasUpper; - m_sgasFactor = 1.0 / (sgasUpper - sgasLower); + m_rangeMinSgas = sgasLower; + m_rangeMaxSgas = sgasUpper; + m_sgasFactor = 1.0 / (sgasUpper - sgasLower); } diff --git a/ApplicationCode/ModelVisualization/RivTernaryScalarMapper.h b/ApplicationCode/ModelVisualization/RivTernaryScalarMapper.h index 68c17b058e..2503bde2e9 100644 --- a/ApplicationCode/ModelVisualization/RivTernaryScalarMapper.h +++ b/ApplicationCode/ModelVisualization/RivTernaryScalarMapper.h @@ -26,7 +26,7 @@ namespace cvf { - class TextureImage; + class TextureImage; } //================================================================================================== @@ -35,23 +35,23 @@ namespace cvf class RivTernaryScalarMapper : public cvf::Object { public: - RivTernaryScalarMapper(const cvf::Color3f& undefScalarColor); + RivTernaryScalarMapper(const cvf::Color3f& undefScalarColor); - void setTernaryRanges(double soilLower, double soilUpper, double sgasLower, double sgasUpper); + void setTernaryRanges(double soilLower, double soilUpper, double sgasLower, double sgasUpper); - cvf::Vec2f mapToTextureCoord(double soil, double sgas, bool isTransparent) const; - bool updateTexture(cvf::TextureImage* image, float opacityLevel) const; + cvf::Vec2f mapToTextureCoord(double soil, double sgas, bool isTransparent) const; + bool updateTexture(cvf::TextureImage* image, float opacityLevel) const; private: - cvf::Color3f m_undefScalarColor; - cvf::Vec2ui m_textureSize; + cvf::Color3f m_undefScalarColor; + cvf::Vec2ui m_textureSize; - double m_rangeMaxSoil; - double m_rangeMinSoil; - double m_soilFactor; + double m_rangeMaxSoil; + double m_rangeMinSoil; + double m_soilFactor; - double m_rangeMaxSgas; - double m_rangeMinSgas; - double m_sgasFactor; + double m_rangeMaxSgas; + double m_rangeMinSgas; + double m_sgasFactor; }; diff --git a/ApplicationCode/ModelVisualization/RivTernaryScalarMapperEffectGenerator.cpp b/ApplicationCode/ModelVisualization/RivTernaryScalarMapperEffectGenerator.cpp index d80e67bc5b..cf78216d87 100644 --- a/ApplicationCode/ModelVisualization/RivTernaryScalarMapperEffectGenerator.cpp +++ b/ApplicationCode/ModelVisualization/RivTernaryScalarMapperEffectGenerator.cpp @@ -47,13 +47,13 @@ /// //-------------------------------------------------------------------------------------------------- RivTernaryScalarMapperEffectGenerator::RivTernaryScalarMapperEffectGenerator(const RivTernaryScalarMapper* scalarMapper, caf::PolygonOffset polygonOffset) - : m_undefinedColor(cvf::Color3::GRAY) + : m_undefinedColor(cvf::Color3::GRAY) { - m_scalarMapper = scalarMapper; - m_polygonOffset = polygonOffset; - m_opacityLevel = 1.0f; - m_faceCulling = caf::FC_NONE; - m_enableDepthWrite = true; + m_scalarMapper = scalarMapper; + m_polygonOffset = polygonOffset; + m_opacityLevel = 1.0f; + m_faceCulling = caf::FC_NONE; + m_enableDepthWrite = true; m_disableLighting = false; } @@ -62,11 +62,11 @@ RivTernaryScalarMapperEffectGenerator::RivTernaryScalarMapperEffectGenerator(con //-------------------------------------------------------------------------------------------------- void RivTernaryScalarMapperEffectGenerator::updateForShaderBasedRendering(cvf::Effect* effect) const { - cvf::ref eff = effect; + cvf::ref eff = effect; - cvf::ShaderProgramGenerator gen("ScalarMapperMeshEffectGenerator", cvf::ShaderSourceProvider::instance()); - gen.addVertexCode(cvf::ShaderSourceRepository::vs_Standard); - gen.addFragmentCode(cvf::ShaderSourceRepository::src_Texture); + cvf::ShaderProgramGenerator gen("ScalarMapperMeshEffectGenerator", cvf::ShaderSourceProvider::instance()); + gen.addVertexCode(cvf::ShaderSourceRepository::vs_Standard); + gen.addFragmentCode(cvf::ShaderSourceRepository::src_Texture); if (m_disableLighting) { @@ -78,27 +78,27 @@ void RivTernaryScalarMapperEffectGenerator::updateForShaderBasedRendering(cvf::E gen.addFragmentCode(cvf::ShaderSourceRepository::fs_Standard); } - cvf::ref prog = gen.generate(); - eff->setShaderProgram(prog.p()); + cvf::ref prog = gen.generate(); + eff->setShaderProgram(prog.p()); - // Result mapping texture + // Result mapping texture - m_textureImage = new cvf::TextureImage(); - m_scalarMapper->updateTexture(m_textureImage.p(), m_opacityLevel); + m_textureImage = new cvf::TextureImage(); + m_scalarMapper->updateTexture(m_textureImage.p(), m_opacityLevel); - cvf::ref texture = new cvf::Texture(m_textureImage.p()); - cvf::ref sampler = new cvf::Sampler; - sampler->setWrapMode(cvf::Sampler::CLAMP_TO_EDGE); - sampler->setMinFilter(cvf::Sampler::NEAREST); - sampler->setMagFilter(cvf::Sampler::NEAREST); + cvf::ref texture = new cvf::Texture(m_textureImage.p()); + cvf::ref sampler = new cvf::Sampler; + sampler->setWrapMode(cvf::Sampler::CLAMP_TO_EDGE); + sampler->setMinFilter(cvf::Sampler::NEAREST); + sampler->setMagFilter(cvf::Sampler::NEAREST); - cvf::ref texBind = new cvf::RenderStateTextureBindings; - texBind->addBinding(texture.p(), sampler.p(), "u_texture2D"); - eff->setRenderState(texBind.p()); + cvf::ref texBind = new cvf::RenderStateTextureBindings; + texBind->addBinding(texture.p(), sampler.p(), "u_texture2D"); + eff->setRenderState(texBind.p()); - // Hardware independent: + // Hardware independent: - updateCommonEffect(eff.p()); + updateCommonEffect(eff.p()); } //-------------------------------------------------------------------------------------------------- @@ -106,31 +106,31 @@ void RivTernaryScalarMapperEffectGenerator::updateForShaderBasedRendering(cvf::E //-------------------------------------------------------------------------------------------------- void RivTernaryScalarMapperEffectGenerator::updateForFixedFunctionRendering(cvf::Effect* effect) const { - cvf::ref eff = effect; + cvf::ref eff = effect; - cvf::ref mat = new cvf::RenderStateMaterial_FF(cvf::Color3::WHITE); - eff->setRenderState(mat.p()); + cvf::ref mat = new cvf::RenderStateMaterial_FF(cvf::Color3::WHITE); + eff->setRenderState(mat.p()); - cvf::ref lighting = new cvf::RenderStateLighting_FF; - lighting->enableTwoSided(true); + cvf::ref lighting = new cvf::RenderStateLighting_FF; + lighting->enableTwoSided(true); lighting->enable(!m_disableLighting); - eff->setRenderState(lighting.p()); + eff->setRenderState(lighting.p()); - // Result mapping texture + // Result mapping texture - m_textureImage = new cvf::TextureImage; - m_scalarMapper->updateTexture(m_textureImage.p(), m_opacityLevel); + m_textureImage = new cvf::TextureImage; + m_scalarMapper->updateTexture(m_textureImage.p(), m_opacityLevel); - cvf::ref texture = new cvf::Texture2D_FF(m_textureImage.p()); - texture->setWrapMode(cvf::Texture2D_FF::CLAMP); - texture->setMinFilter(cvf::Texture2D_FF::NEAREST); - texture->setMagFilter(cvf::Texture2D_FF::NEAREST); - cvf::ref texMapping = new cvf::RenderStateTextureMapping_FF(texture.p()); - eff->setRenderState(texMapping.p()); + cvf::ref texture = new cvf::Texture2D_FF(m_textureImage.p()); + texture->setWrapMode(cvf::Texture2D_FF::CLAMP); + texture->setMinFilter(cvf::Texture2D_FF::NEAREST); + texture->setMagFilter(cvf::Texture2D_FF::NEAREST); + cvf::ref texMapping = new cvf::RenderStateTextureMapping_FF(texture.p()); + eff->setRenderState(texMapping.p()); - // Hardware independent: + // Hardware independent: - updateCommonEffect(eff.p()); + updateCommonEffect(eff.p()); } @@ -140,48 +140,48 @@ void RivTernaryScalarMapperEffectGenerator::updateForFixedFunctionRendering(cvf: //-------------------------------------------------------------------------------------------------- void RivTernaryScalarMapperEffectGenerator::updateCommonEffect(cvf::Effect* effect) const { - CVF_ASSERT(effect); - - if (m_polygonOffset != caf::PO_NONE) - { - cvf::ref polyOffset = EffectGenerator::createAndConfigurePolygonOffsetRenderState(m_polygonOffset); - effect->setRenderState(polyOffset.p()); - } - - // Simple transparency - if (m_opacityLevel < 1.0f) - { - cvf::ref blender = new cvf::RenderStateBlending; - blender->configureTransparencyBlending(); - effect->setRenderState(blender.p()); - } - - // Backface culling - if (m_faceCulling != caf::FC_NONE) - { - cvf::ref faceCulling = new cvf::RenderStateCullFace; - if (m_faceCulling == caf::FC_BACK) - { - faceCulling->setMode(cvf::RenderStateCullFace::BACK); - } - else if (m_faceCulling == caf::FC_FRONT) - { - faceCulling->setMode(cvf::RenderStateCullFace::FRONT); - } - else if (m_faceCulling == caf::FC_FRONT_AND_BACK) - { - faceCulling->setMode(cvf::RenderStateCullFace::FRONT_AND_BACK); - } - - effect->setRenderState(faceCulling.p()); - } - - if (!m_enableDepthWrite) - { - cvf::ref depth = new cvf::RenderStateDepth; - depth->enableDepthWrite(false); - effect->setRenderState(depth.p()); - } + CVF_ASSERT(effect); + + if (m_polygonOffset != caf::PO_NONE) + { + cvf::ref polyOffset = EffectGenerator::createAndConfigurePolygonOffsetRenderState(m_polygonOffset); + effect->setRenderState(polyOffset.p()); + } + + // Simple transparency + if (m_opacityLevel < 1.0f) + { + cvf::ref blender = new cvf::RenderStateBlending; + blender->configureTransparencyBlending(); + effect->setRenderState(blender.p()); + } + + // Backface culling + if (m_faceCulling != caf::FC_NONE) + { + cvf::ref faceCulling = new cvf::RenderStateCullFace; + if (m_faceCulling == caf::FC_BACK) + { + faceCulling->setMode(cvf::RenderStateCullFace::BACK); + } + else if (m_faceCulling == caf::FC_FRONT) + { + faceCulling->setMode(cvf::RenderStateCullFace::FRONT); + } + else if (m_faceCulling == caf::FC_FRONT_AND_BACK) + { + faceCulling->setMode(cvf::RenderStateCullFace::FRONT_AND_BACK); + } + + effect->setRenderState(faceCulling.p()); + } + + if (!m_enableDepthWrite) + { + cvf::ref depth = new cvf::RenderStateDepth; + depth->enableDepthWrite(false); + effect->setRenderState(depth.p()); + } } @@ -190,26 +190,26 @@ void RivTernaryScalarMapperEffectGenerator::updateCommonEffect(cvf::Effect* effe //-------------------------------------------------------------------------------------------------- bool RivTernaryScalarMapperEffectGenerator::isEqual(const EffectGenerator* other) const { - const RivTernaryScalarMapperEffectGenerator* otherTextureResultEffect = dynamic_cast(other); - - if (otherTextureResultEffect) - { - if (m_scalarMapper.p() == otherTextureResultEffect->m_scalarMapper - && m_polygonOffset == otherTextureResultEffect->m_polygonOffset - && m_opacityLevel == otherTextureResultEffect->m_opacityLevel - && m_undefinedColor == otherTextureResultEffect->m_undefinedColor - && m_faceCulling == otherTextureResultEffect->m_faceCulling - && m_enableDepthWrite == otherTextureResultEffect->m_enableDepthWrite + const RivTernaryScalarMapperEffectGenerator* otherTextureResultEffect = dynamic_cast(other); + + if (otherTextureResultEffect) + { + if (m_scalarMapper.p() == otherTextureResultEffect->m_scalarMapper + && m_polygonOffset == otherTextureResultEffect->m_polygonOffset + && m_opacityLevel == otherTextureResultEffect->m_opacityLevel + && m_undefinedColor == otherTextureResultEffect->m_undefinedColor + && m_faceCulling == otherTextureResultEffect->m_faceCulling + && m_enableDepthWrite == otherTextureResultEffect->m_enableDepthWrite && m_disableLighting == otherTextureResultEffect->m_disableLighting) - { - cvf::ref texImg2 = new cvf::TextureImage; - otherTextureResultEffect->m_scalarMapper->updateTexture(texImg2.p(), m_opacityLevel); + { + cvf::ref texImg2 = new cvf::TextureImage; + otherTextureResultEffect->m_scalarMapper->updateTexture(texImg2.p(), m_opacityLevel); - return RivTernaryScalarMapperEffectGenerator::isImagesEqual(m_textureImage.p(), texImg2.p()); - } - } + return RivTernaryScalarMapperEffectGenerator::isImagesEqual(m_textureImage.p(), texImg2.p()); + } + } - return false; + return false; } //-------------------------------------------------------------------------------------------------- @@ -217,15 +217,15 @@ bool RivTernaryScalarMapperEffectGenerator::isEqual(const EffectGenerator* other //-------------------------------------------------------------------------------------------------- caf::EffectGenerator* RivTernaryScalarMapperEffectGenerator::copy() const { - RivTernaryScalarMapperEffectGenerator* scEffGen = new RivTernaryScalarMapperEffectGenerator(m_scalarMapper.p(), m_polygonOffset); - scEffGen->m_textureImage = m_textureImage; - scEffGen->m_opacityLevel = m_opacityLevel; - scEffGen->m_undefinedColor = m_undefinedColor; - scEffGen->m_faceCulling = m_faceCulling; - scEffGen->m_enableDepthWrite = m_enableDepthWrite; + RivTernaryScalarMapperEffectGenerator* scEffGen = new RivTernaryScalarMapperEffectGenerator(m_scalarMapper.p(), m_polygonOffset); + scEffGen->m_textureImage = m_textureImage; + scEffGen->m_opacityLevel = m_opacityLevel; + scEffGen->m_undefinedColor = m_undefinedColor; + scEffGen->m_faceCulling = m_faceCulling; + scEffGen->m_enableDepthWrite = m_enableDepthWrite; scEffGen->m_disableLighting = m_disableLighting; - return scEffGen; + return scEffGen; } @@ -236,22 +236,22 @@ caf::EffectGenerator* RivTernaryScalarMapperEffectGenerator::copy() const //-------------------------------------------------------------------------------------------------- bool RivTernaryScalarMapperEffectGenerator::isImagesEqual(const cvf::TextureImage* texImg1, const cvf::TextureImage* texImg2) { - if (texImg1 == NULL && texImg2 == NULL) return true; - - if (texImg1 != NULL && texImg2 != NULL - && texImg1->height() == texImg2->height() - && texImg1->width() == texImg2->width() - && texImg1->width() > 0 && texImg1->height() > 0 - && texImg1->pixel(0, 0) == texImg2->pixel(0, 0) - && texImg1->pixel(texImg1->width() - 1, texImg1->height() - 1) == texImg2->pixel(texImg1->width() - 1, texImg1->height() - 1) - && texImg1->pixel(texImg1->width() / 2, texImg1->height() / 2) == texImg2->pixel(texImg1->width() / 2, texImg1->height() / 2) - && texImg1->pixel(texImg1->width() / 4, texImg1->height() / 4) == texImg2->pixel(texImg1->width() / 4, texImg1->height() / 4) - && texImg1->pixel(texImg1->width() / 2 + texImg1->width() / 4, texImg1->height() / 2 + texImg1->height() / 4) == texImg2->pixel(texImg1->width() / 2 + texImg1->width() / 4, texImg1->height() / 2 + texImg1->height() / 4) - ) - { - return true; - } - - return false; + if (texImg1 == NULL && texImg2 == NULL) return true; + + if (texImg1 != NULL && texImg2 != NULL + && texImg1->height() == texImg2->height() + && texImg1->width() == texImg2->width() + && texImg1->width() > 0 && texImg1->height() > 0 + && texImg1->pixel(0, 0) == texImg2->pixel(0, 0) + && texImg1->pixel(texImg1->width() - 1, texImg1->height() - 1) == texImg2->pixel(texImg1->width() - 1, texImg1->height() - 1) + && texImg1->pixel(texImg1->width() / 2, texImg1->height() / 2) == texImg2->pixel(texImg1->width() / 2, texImg1->height() / 2) + && texImg1->pixel(texImg1->width() / 4, texImg1->height() / 4) == texImg2->pixel(texImg1->width() / 4, texImg1->height() / 4) + && texImg1->pixel(texImg1->width() / 2 + texImg1->width() / 4, texImg1->height() / 2 + texImg1->height() / 4) == texImg2->pixel(texImg1->width() / 2 + texImg1->width() / 4, texImg1->height() / 2 + texImg1->height() / 4) + ) + { + return true; + } + + return false; } diff --git a/ApplicationCode/ModelVisualization/RivTernaryScalarMapperEffectGenerator.h b/ApplicationCode/ModelVisualization/RivTernaryScalarMapperEffectGenerator.h index 0e00ea2973..ad6db1ce02 100644 --- a/ApplicationCode/ModelVisualization/RivTernaryScalarMapperEffectGenerator.h +++ b/ApplicationCode/ModelVisualization/RivTernaryScalarMapperEffectGenerator.h @@ -25,7 +25,7 @@ class RivTernaryScalarMapper; namespace cvf { - class TextureImage; + class TextureImage; } //================================================================================================== @@ -36,36 +36,36 @@ namespace cvf class RivTernaryScalarMapperEffectGenerator : public caf::EffectGenerator { public: - RivTernaryScalarMapperEffectGenerator(const RivTernaryScalarMapper* scalarMapper, caf::PolygonOffset polygonOffset); + RivTernaryScalarMapperEffectGenerator(const RivTernaryScalarMapper* scalarMapper, caf::PolygonOffset polygonOffset); - void setOpacityLevel(float opacity) { m_opacityLevel = cvf::Math::clamp(opacity, 0.0f, 1.0f); } - void setUndefinedColor(cvf::Color3f color) { m_undefinedColor = color; } - void setFaceCulling(caf::FaceCulling faceCulling) { m_faceCulling = faceCulling; } - void enableDepthWrite(bool enableWrite) { m_enableDepthWrite = enableWrite; } + void setOpacityLevel(float opacity) { m_opacityLevel = cvf::Math::clamp(opacity, 0.0f, 1.0f); } + void setUndefinedColor(cvf::Color3f color) { m_undefinedColor = color; } + void setFaceCulling(caf::FaceCulling faceCulling) { m_faceCulling = faceCulling; } + void enableDepthWrite(bool enableWrite) { m_enableDepthWrite = enableWrite; } void disableLighting(bool disable) { m_disableLighting = disable; } public: - static bool isImagesEqual(const cvf::TextureImage* texImg1, const cvf::TextureImage* texImg2); + static bool isImagesEqual(const cvf::TextureImage* texImg1, const cvf::TextureImage* texImg2); protected: - virtual bool isEqual(const caf::EffectGenerator* other) const; - virtual caf::EffectGenerator* copy() const; + virtual bool isEqual(const caf::EffectGenerator* other) const; + virtual caf::EffectGenerator* copy() const; - virtual void updateForShaderBasedRendering(cvf::Effect* effect) const; - virtual void updateForFixedFunctionRendering(cvf::Effect* effect) const; + virtual void updateForShaderBasedRendering(cvf::Effect* effect) const; + virtual void updateForFixedFunctionRendering(cvf::Effect* effect) const; private: - void updateCommonEffect(cvf::Effect* effect) const; + void updateCommonEffect(cvf::Effect* effect) const; private: - cvf::cref m_scalarMapper; - mutable cvf::ref m_textureImage; - caf::PolygonOffset m_polygonOffset; - float m_opacityLevel; - cvf::Color3f m_undefinedColor; - caf::FaceCulling m_faceCulling; - bool m_enableDepthWrite; + cvf::cref m_scalarMapper; + mutable cvf::ref m_textureImage; + caf::PolygonOffset m_polygonOffset; + float m_opacityLevel; + cvf::Color3f m_undefinedColor; + caf::FaceCulling m_faceCulling; + bool m_enableDepthWrite; bool m_disableLighting; }; diff --git a/ApplicationCode/ModelVisualization/RivTernaryTextureCoordsCreator.cpp b/ApplicationCode/ModelVisualization/RivTernaryTextureCoordsCreator.cpp index 5bd2243efd..6b6d3b0846 100644 --- a/ApplicationCode/ModelVisualization/RivTernaryTextureCoordsCreator.cpp +++ b/ApplicationCode/ModelVisualization/RivTernaryTextureCoordsCreator.cpp @@ -38,11 +38,11 @@ /// //-------------------------------------------------------------------------------------------------- RivTernaryTextureCoordsCreator::RivTernaryTextureCoordsCreator( - RimEclipseCellColors* cellResultColors, - RimTernaryLegendConfig* ternaryLegendConfig, - size_t timeStepIndex, - size_t gridIndex, - const cvf::StructGridQuadToCellFaceMapper* quadMapper) + RimEclipseCellColors* cellResultColors, + RimTernaryLegendConfig* ternaryLegendConfig, + size_t timeStepIndex, + size_t gridIndex, + const cvf::StructGridQuadToCellFaceMapper* quadMapper) { RigCaseData* eclipseCase = cellResultColors->reservoirView()->eclipseCase()->reservoirData(); @@ -55,12 +55,12 @@ RivTernaryTextureCoordsCreator::RivTernaryTextureCoordsCreator( RifReaderInterface::PorosityModelResultType porosityModel = RigCaseCellResultsData::convertFromProjectModelPorosityModel(cellResultColors->porosityModel()); - cvf::ref soil = RigResultAccessorFactory::createResultAccessor(eclipseCase, gridIndex, porosityModel, resTimeStepIdx, "SOIL"); - cvf::ref sgas = RigResultAccessorFactory::createResultAccessor(eclipseCase, gridIndex, porosityModel, resTimeStepIdx, "SGAS"); - cvf::ref swat = RigResultAccessorFactory::createResultAccessor(eclipseCase, gridIndex, porosityModel, resTimeStepIdx, "SWAT"); - - m_resultAccessor = new RigTernaryResultAccessor(); - m_resultAccessor->setTernaryResultAccessors(soil.p(), sgas.p(), swat.p()); + cvf::ref soil = RigResultAccessorFactory::createResultAccessor(eclipseCase, gridIndex, porosityModel, resTimeStepIdx, "SOIL"); + cvf::ref sgas = RigResultAccessorFactory::createResultAccessor(eclipseCase, gridIndex, porosityModel, resTimeStepIdx, "SGAS"); + cvf::ref swat = RigResultAccessorFactory::createResultAccessor(eclipseCase, gridIndex, porosityModel, resTimeStepIdx, "SWAT"); + + m_resultAccessor = new RigTernaryResultAccessor(); + m_resultAccessor->setTernaryResultAccessors(soil.p(), sgas.p(), swat.p()); cvf::ref pipeInCellEval = new RigPipeInCellEvaluator( cellResultColors->reservoirView()->wellCollection()->isWellPipesVisible(timeStepIndex), eclipseCase->gridCellToWellIndex(gridIndex)); @@ -76,17 +76,17 @@ RivTernaryTextureCoordsCreator::RivTernaryTextureCoordsCreator( //-------------------------------------------------------------------------------------------------- void RivTernaryTextureCoordsCreator::createTextureCoords(cvf::Vec2fArray* quadTextureCoords) { - createTextureCoords(quadTextureCoords, m_quadMapper.p(), m_resultAccessor.p(), m_texMapper.p()); + createTextureCoords(quadTextureCoords, m_quadMapper.p(), m_resultAccessor.p(), m_texMapper.p()); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RivTernaryTextureCoordsCreator::createTextureCoords( - cvf::Vec2fArray* quadTextureCoords, - const cvf::StructGridQuadToCellFaceMapper* quadMapper, - const RigTernaryResultAccessor* resultAccessor, - const RivTernaryResultToTextureMapper* texMapper) + cvf::Vec2fArray* quadTextureCoords, + const cvf::StructGridQuadToCellFaceMapper* quadMapper, + const RigTernaryResultAccessor* resultAccessor, + const RivTernaryResultToTextureMapper* texMapper) { CVF_ASSERT(quadTextureCoords && quadMapper && resultAccessor && texMapper); @@ -94,7 +94,7 @@ void RivTernaryTextureCoordsCreator::createTextureCoords( quadTextureCoords->resize(numVertices); cvf::Vec2f* rawPtr = quadTextureCoords->ptr(); - cvf::Vec2d resultValue; + cvf::Vec2d resultValue; cvf::Vec2f texCoord; #pragma omp parallel for private(texCoord, resultValue) diff --git a/ApplicationCode/ModelVisualization/RivTernaryTextureCoordsCreator.h b/ApplicationCode/ModelVisualization/RivTernaryTextureCoordsCreator.h index d927cf1f9e..c617a34ed2 100644 --- a/ApplicationCode/ModelVisualization/RivTernaryTextureCoordsCreator.h +++ b/ApplicationCode/ModelVisualization/RivTernaryTextureCoordsCreator.h @@ -31,7 +31,7 @@ class RimTernaryLegendConfig; namespace cvf { - class StructGridQuadToCellFaceMapper; + class StructGridQuadToCellFaceMapper; } @@ -41,22 +41,22 @@ namespace cvf class RivTernaryTextureCoordsCreator { public: - RivTernaryTextureCoordsCreator( RimEclipseCellColors* cellResultColors, - RimTernaryLegendConfig* ternaryLegendConfig, - size_t timeStepIndex, - size_t gridIndex, - const cvf::StructGridQuadToCellFaceMapper* quadMapper); + RivTernaryTextureCoordsCreator( RimEclipseCellColors* cellResultColors, + RimTernaryLegendConfig* ternaryLegendConfig, + size_t timeStepIndex, + size_t gridIndex, + const cvf::StructGridQuadToCellFaceMapper* quadMapper); void createTextureCoords(cvf::Vec2fArray* quadTextureCoords); private: static void createTextureCoords(cvf::Vec2fArray* quadTextureCoords, const cvf::StructGridQuadToCellFaceMapper* quadMapper, - const RigTernaryResultAccessor* resultAccessor, + const RigTernaryResultAccessor* resultAccessor, const RivTernaryResultToTextureMapper* texMapper); private: cvf::cref m_quadMapper; - cvf::ref m_resultAccessor; + cvf::ref m_resultAccessor; cvf::ref m_texMapper; }; diff --git a/ApplicationCode/ModelVisualization/RivTextureCoordsCreator.cpp b/ApplicationCode/ModelVisualization/RivTextureCoordsCreator.cpp index 2964ae8090..4683af0e17 100644 --- a/ApplicationCode/ModelVisualization/RivTextureCoordsCreator.cpp +++ b/ApplicationCode/ModelVisualization/RivTextureCoordsCreator.cpp @@ -61,12 +61,12 @@ RivTextureCoordsCreator::RivTextureCoordsCreator(RimEclipseCellColors* cellResul //-------------------------------------------------------------------------------------------------- bool RivTextureCoordsCreator::isValid() { - if (m_quadMapper.isNull() || m_resultAccessor.isNull() || m_texMapper.isNull()) - { - return false; - } + if (m_quadMapper.isNull() || m_resultAccessor.isNull() || m_texMapper.isNull()) + { + return false; + } - return true; + return true; } //-------------------------------------------------------------------------------------------------- @@ -74,17 +74,17 @@ bool RivTextureCoordsCreator::isValid() //-------------------------------------------------------------------------------------------------- void RivTextureCoordsCreator::createTextureCoords(cvf::Vec2fArray* quadTextureCoords) { - createTextureCoords(quadTextureCoords, m_quadMapper.p(), m_resultAccessor.p(), m_texMapper.p()); + createTextureCoords(quadTextureCoords, m_quadMapper.p(), m_resultAccessor.p(), m_texMapper.p()); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RivTextureCoordsCreator::createTextureCoords( - cvf::Vec2fArray* quadTextureCoords, - const cvf::StructGridQuadToCellFaceMapper* quadMapper, - const RigResultAccessor* resultAccessor, - const RivResultToTextureMapper* texMapper) + cvf::Vec2fArray* quadTextureCoords, + const cvf::StructGridQuadToCellFaceMapper* quadMapper, + const RigResultAccessor* resultAccessor, + const RivResultToTextureMapper* texMapper) { CVF_ASSERT(quadTextureCoords && quadMapper && resultAccessor && texMapper); diff --git a/ApplicationCode/ModelVisualization/RivTextureCoordsCreator.h b/ApplicationCode/ModelVisualization/RivTextureCoordsCreator.h index 98f5758df6..9394a8b551 100644 --- a/ApplicationCode/ModelVisualization/RivTextureCoordsCreator.h +++ b/ApplicationCode/ModelVisualization/RivTextureCoordsCreator.h @@ -29,7 +29,7 @@ class RivResultToTextureMapper; namespace cvf { - class StructGridQuadToCellFaceMapper; + class StructGridQuadToCellFaceMapper; } @@ -41,7 +41,7 @@ class RivTextureCoordsCreator size_t gridIndex, const cvf::StructGridQuadToCellFaceMapper* quadMapper); - bool isValid(); + bool isValid(); void createTextureCoords(cvf::Vec2fArray* quadTextureCoords); @@ -51,8 +51,8 @@ class RivTextureCoordsCreator const cvf::StructGridQuadToCellFaceMapper* quadMapper, const RigResultAccessor* resultAccessor, const RivResultToTextureMapper* texMapper); - cvf::cref m_quadMapper; - cvf::ref m_resultAccessor; - cvf::ref m_texMapper; + cvf::cref m_quadMapper; + cvf::ref m_resultAccessor; + cvf::ref m_texMapper; }; diff --git a/ApplicationCode/ModelVisualization/RivWellHeadPartMgr.cpp b/ApplicationCode/ModelVisualization/RivWellHeadPartMgr.cpp index 65f4b8d6c7..0e741a8b50 100644 --- a/ApplicationCode/ModelVisualization/RivWellHeadPartMgr.cpp +++ b/ApplicationCode/ModelVisualization/RivWellHeadPartMgr.cpp @@ -180,7 +180,7 @@ void RivWellHeadPartMgr::buildWellHeadParts(size_t frameIndex) part->setDrawable(pipeSurface.p()); caf::SurfaceEffectGenerator surfaceGen(cvf::Color4f(well->wellPipeColor()), caf::PO_1); - cvf::ref eff = surfaceGen.generateEffect(); + cvf::ref eff = surfaceGen.generateCachedEffect(); part->setEffect(eff.p()); @@ -194,7 +194,7 @@ void RivWellHeadPartMgr::buildWellHeadParts(size_t frameIndex) part->setDrawable(centerLineDrawable.p()); caf::MeshEffectGenerator meshGen(well->wellPipeColor()); - cvf::ref eff = meshGen.generateEffect(); + cvf::ref eff = meshGen.generateCachedEffect(); part->setEffect(eff.p()); @@ -276,7 +276,7 @@ void RivWellHeadPartMgr::buildWellHeadParts(size_t frameIndex) } caf::SurfaceEffectGenerator surfaceGen(headColor, caf::PO_1); - cvf::ref eff = surfaceGen.generateEffect(); + cvf::ref eff = surfaceGen.generateCachedEffect(); part->setEffect(eff.p()); m_wellHeadParts.push_back(part.p()); diff --git a/ApplicationCode/ModelVisualization/RivWellPathPartMgr.cpp b/ApplicationCode/ModelVisualization/RivWellPathPartMgr.cpp index 1093a46780..ae7f0e41e5 100644 --- a/ApplicationCode/ModelVisualization/RivWellPathPartMgr.cpp +++ b/ApplicationCode/ModelVisualization/RivWellPathPartMgr.cpp @@ -39,6 +39,7 @@ #include "RigCaseData.h" #include "RigCell.h" #include "RivWellPathPartMgr.h" +#include "RivWellPathSourceInfo.h" #include "RimWellPath.h" #include "RivPipeGeometryGenerator.h" #include "cvfModelBasicList.h" @@ -78,10 +79,10 @@ RivWellPathPartMgr::RivWellPathPartMgr(RimWellPathCollection* wellPathCollection m_scalarMapper = scalarMapper; caf::ScalarMapperEffectGenerator surfEffGen(scalarMapper.p(), caf::PO_1); - m_scalarMapperSurfaceEffect = surfEffGen.generateEffect(); + m_scalarMapperSurfaceEffect = surfEffGen.generateCachedEffect(); caf::ScalarMapperMeshEffectGenerator meshEffGen(scalarMapper.p()); - m_scalarMapperMeshEffect = meshEffGen.generateEffect(); + m_scalarMapperMeshEffect = meshEffGen.generateCachedEffect(); } //-------------------------------------------------------------------------------------------------- @@ -158,9 +159,12 @@ void RivWellPathPartMgr::buildWellPathParts(cvf::Vec3d displayModelOffset, doubl { pbd.m_surfacePart = new cvf::Part; pbd.m_surfacePart->setDrawable(pbd.m_surfaceDrawable.p()); + + RivWellPathSourceInfo* sourceInfo = new RivWellPathSourceInfo(m_rimWellPath); + pbd.m_surfacePart->setSourceInfo(sourceInfo); caf::SurfaceEffectGenerator surfaceGen(cvf::Color4f(m_rimWellPath->wellPathColor()), caf::PO_1); - cvf::ref eff = surfaceGen.generateEffect(); + cvf::ref eff = surfaceGen.generateCachedEffect(); pbd.m_surfacePart->setEffect(eff.p()); } @@ -171,7 +175,7 @@ void RivWellPathPartMgr::buildWellPathParts(cvf::Vec3d displayModelOffset, doubl pbd.m_centerLinePart->setDrawable(pbd.m_centerLineDrawable.p()); caf::MeshEffectGenerator gen(m_rimWellPath->wellPathColor()); - cvf::ref eff = gen.generateEffect(); + cvf::ref eff = gen.generateCachedEffect(); pbd.m_centerLinePart->setEffect(eff.p()); } diff --git a/ApplicationCode/ModelVisualization/RivWellPathSourceInfo.cpp b/ApplicationCode/ModelVisualization/RivWellPathSourceInfo.cpp new file mode 100644 index 0000000000..3445907400 --- /dev/null +++ b/ApplicationCode/ModelVisualization/RivWellPathSourceInfo.cpp @@ -0,0 +1,42 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RivWellPathSourceInfo.h" + +#include "RimWellPath.h" +#include "RimWellPathCollection.h" + +#include "RivPipeQuadToSegmentMapper.h" + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RivWellPathSourceInfo::RivWellPathSourceInfo(RimWellPath* wellPath/*, RivPipeQuadToSegmentMapper* quadToSegmentMapper*/) +{ + m_wellPath = wellPath; + //m_quadToSegmentMapper = quadToSegmentMapper; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimWellPath* RivWellPathSourceInfo::wellPath() const +{ + return m_wellPath.p(); +} diff --git a/ApplicationCode/ModelVisualization/RivWellPathSourceInfo.h b/ApplicationCode/ModelVisualization/RivWellPathSourceInfo.h new file mode 100644 index 0000000000..4ae7bcf59b --- /dev/null +++ b/ApplicationCode/ModelVisualization/RivWellPathSourceInfo.h @@ -0,0 +1,43 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cvfBase.h" +#include "cvfObject.h" +#include "cafPdmPointer.h" + +class RimWellPath; +//class RivPipeQuadToSegmentMapper; + +//================================================================================================== +/// +/// TODO: Implement and add RivPipeQuadToSegmentMapper +//================================================================================================== +class RivWellPathSourceInfo : public cvf::Object +{ +public: + RivWellPathSourceInfo(RimWellPath* wellPath/*, RivPipeQuadToSegmentMapper* quadToSegmentMapper*/); + + RimWellPath* wellPath() const; + +private: + caf::PdmPointer m_wellPath; + //RivPipeQuadToSegmentMapper* m_quadToSegmentMapper; +}; diff --git a/ApplicationCode/ModelVisualization/RivWellPipesPartMgr.cpp b/ApplicationCode/ModelVisualization/RivWellPipesPartMgr.cpp index ea6713c99b..4dcb02367f 100644 --- a/ApplicationCode/ModelVisualization/RivWellPipesPartMgr.cpp +++ b/ApplicationCode/ModelVisualization/RivWellPipesPartMgr.cpp @@ -74,10 +74,10 @@ RivWellPipesPartMgr::RivWellPipesPartMgr(RimEclipseView* reservoirView, RimEclip m_scalarMapper = scalarMapper; caf::ScalarMapperEffectGenerator surfEffGen(scalarMapper.p(), caf::PO_1); - m_scalarMapperSurfaceEffect = surfEffGen.generateEffect(); + m_scalarMapperSurfaceEffect = surfEffGen.generateCachedEffect(); caf::ScalarMapperMeshEffectGenerator meshEffGen(scalarMapper.p()); - m_scalarMapperMeshEffect = meshEffGen.generateEffect(); + m_scalarMapperMeshEffect = meshEffGen.generateCachedEffect(); } //-------------------------------------------------------------------------------------------------- @@ -97,7 +97,6 @@ void RivWellPipesPartMgr::buildWellPipeParts() m_wellBranches.clear(); - std::vector< size_t > pipeBranchIds; std::vector< std::vector > pipeBranchesCLCoords; std::vector< std::vector > pipeBranchesCellIds; @@ -143,7 +142,7 @@ void RivWellPipesPartMgr::buildWellPipeParts() pbd.m_surfacePart->setDrawable(pbd.m_surfaceDrawable.p()); caf::SurfaceEffectGenerator surfaceGen(cvf::Color4f(m_rimWell->wellPipeColor()), caf::PO_1); - cvf::ref eff = surfaceGen.generateEffect(); + cvf::ref eff = surfaceGen.generateCachedEffect(); pbd.m_surfacePart->setEffect(eff.p()); } @@ -154,7 +153,7 @@ void RivWellPipesPartMgr::buildWellPipeParts() pbd.m_centerLinePart->setDrawable(pbd.m_centerLineDrawable.p()); caf::MeshEffectGenerator gen(m_rimWell->wellPipeColor()); - cvf::ref eff = gen.generateEffect(); + cvf::ref eff = gen.generateCachedEffect(); pbd.m_centerLinePart->setEffect(eff.p()); } @@ -315,7 +314,7 @@ void RivWellPipesPartMgr::calculateWellPipeCenterline( std::vector< std::vector cvf::Vec3d outOfPrevCell(centerPreviousCell); - int intersectionOk = prevCell.firstIntersectionPoint(rayToThisCell, &outOfPrevCell); + //int intersectionOk = prevCell.firstIntersectionPoint(rayToThisCell, &outOfPrevCell); //CVF_ASSERT(intersectionOk); //CVF_ASSERT(intersectionOk); if ((currentPoint - outOfPrevCell).lengthSquared() > 1e-3) @@ -413,7 +412,7 @@ void RivWellPipesPartMgr::calculateWellPipeCenterline( std::vector< std::vector cvf::Vec3d outOfPrevCell(centerPreviousCell); const RigCell& prevCell = rigReservoir->cellFromWellResultCell(*prevWellResPoint); - bool intersectionOk = prevCell.firstIntersectionPoint(rayToThisCell, &outOfPrevCell); + //bool intersectionOk = prevCell.firstIntersectionPoint(rayToThisCell, &outOfPrevCell); //CVF_ASSERT(intersectionOk); //CVF_ASSERT(intersectionOk); if ((intoThisCell - outOfPrevCell).lengthSquared() > 1e-3) diff --git a/ApplicationCode/ProjectDataModel/CMakeLists_files.cmake b/ApplicationCode/ProjectDataModel/CMakeLists_files.cmake index 8c5f2ef7c5..1e61fa84d9 100644 --- a/ApplicationCode/ProjectDataModel/CMakeLists_files.cmake +++ b/ApplicationCode/ProjectDataModel/CMakeLists_files.cmake @@ -37,8 +37,6 @@ ${CEE_CURRENT_LIST_DIR}RimCalcScript.h ${CEE_CURRENT_LIST_DIR}RimExportInputPropertySettings.h ${CEE_CURRENT_LIST_DIR}RimBinaryExportSettings.h ${CEE_CURRENT_LIST_DIR}Rim3dOverlayInfoConfig.h -${CEE_CURRENT_LIST_DIR}RimUiTreeModelPdm.h -${CEE_CURRENT_LIST_DIR}RimUiTreeView.h ${CEE_CURRENT_LIST_DIR}RimReservoirCellResultsStorage.h ${CEE_CURRENT_LIST_DIR}RimEclipseStatisticsCaseEvaluator.h ${CEE_CURRENT_LIST_DIR}RimMimeData.h @@ -60,6 +58,19 @@ ${CEE_CURRENT_LIST_DIR}RimGeoMechResultDefinition.h ${CEE_CURRENT_LIST_DIR}RimGeoMechCellColors.h ${CEE_CURRENT_LIST_DIR}RimView.h ${CEE_CURRENT_LIST_DIR}RimCase.h +${CEE_CURRENT_LIST_DIR}RimTreeViewStateSerializer.h +${CEE_CURRENT_LIST_DIR}RimViewController.h +${CEE_CURRENT_LIST_DIR}RimMainPlotCollection.h +${CEE_CURRENT_LIST_DIR}RimWellLogPlotCollection.h +${CEE_CURRENT_LIST_DIR}RimWellLogPlot.h +${CEE_CURRENT_LIST_DIR}RimWellLogPlotTrack.h +${CEE_CURRENT_LIST_DIR}RimWellLogPlotCurve.h +${CEE_CURRENT_LIST_DIR}RimViewLinker.h +${CEE_CURRENT_LIST_DIR}RimViewLinkerCollection.h +${CEE_CURRENT_LIST_DIR}RimWellLogExtractionCurve.h +${CEE_CURRENT_LIST_DIR}RimWellLogFile.h +${CEE_CURRENT_LIST_DIR}RimWellLogFileChannel.h +${CEE_CURRENT_LIST_DIR}RimWellLogFileCurve.h ) set (SOURCE_GROUP_SOURCE_FILES @@ -95,8 +106,6 @@ ${CEE_CURRENT_LIST_DIR}RimCalcScript.cpp ${CEE_CURRENT_LIST_DIR}RimExportInputPropertySettings.cpp ${CEE_CURRENT_LIST_DIR}RimBinaryExportSettings.cpp ${CEE_CURRENT_LIST_DIR}Rim3dOverlayInfoConfig.cpp -${CEE_CURRENT_LIST_DIR}RimUiTreeModelPdm.cpp -${CEE_CURRENT_LIST_DIR}RimUiTreeView.cpp ${CEE_CURRENT_LIST_DIR}RimReservoirCellResultsStorage.cpp ${CEE_CURRENT_LIST_DIR}RimEclipseStatisticsCaseEvaluator.cpp ${CEE_CURRENT_LIST_DIR}RimMimeData.cpp @@ -118,6 +127,19 @@ ${CEE_CURRENT_LIST_DIR}RimGeoMechResultDefinition.cpp ${CEE_CURRENT_LIST_DIR}RimGeoMechCellColors.cpp ${CEE_CURRENT_LIST_DIR}RimView.cpp ${CEE_CURRENT_LIST_DIR}RimCase.cpp +${CEE_CURRENT_LIST_DIR}RimTreeViewStateSerializer.cpp +${CEE_CURRENT_LIST_DIR}RimViewController.cpp +${CEE_CURRENT_LIST_DIR}RimMainPlotCollection.cpp +${CEE_CURRENT_LIST_DIR}RimWellLogPlotCollection.cpp +${CEE_CURRENT_LIST_DIR}RimWellLogPlot.cpp +${CEE_CURRENT_LIST_DIR}RimWellLogPlotTrack.cpp +${CEE_CURRENT_LIST_DIR}RimWellLogPlotCurve.cpp +${CEE_CURRENT_LIST_DIR}RimViewLinker.cpp +${CEE_CURRENT_LIST_DIR}RimViewLinkerCollection.cpp +${CEE_CURRENT_LIST_DIR}RimWellLogExtractionCurve.cpp +${CEE_CURRENT_LIST_DIR}RimWellLogFile.cpp +${CEE_CURRENT_LIST_DIR}RimWellLogFileChannel.cpp +${CEE_CURRENT_LIST_DIR}RimWellLogFileCurve.cpp ) list(APPEND CODE_HEADER_FILES diff --git a/ApplicationCode/ProjectDataModel/ProjectDataModel_UnitTests/RimWellLogExtractionCurveImpl-Test.cpp b/ApplicationCode/ProjectDataModel/ProjectDataModel_UnitTests/RimWellLogExtractionCurveImpl-Test.cpp new file mode 100644 index 0000000000..1597263404 --- /dev/null +++ b/ApplicationCode/ProjectDataModel/ProjectDataModel_UnitTests/RimWellLogExtractionCurveImpl-Test.cpp @@ -0,0 +1,53 @@ +#include "gtest/gtest.h" + +#include "RigWellLogCurveData.h" + +#include // Needed for HUGE_VAL on Linux + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(RimWellLogExtractionCurveImplTest, StripOffInvalidValAtEndsOfVector) +{ + std::vector values; + values.push_back(HUGE_VAL); + values.push_back(HUGE_VAL); + values.push_back(1.0); + values.push_back(2.0); + values.push_back(3.0); + values.push_back(HUGE_VAL); + + std::vector< std::pair > valuesIntervals; + RigWellLogCurveDataTestInterface::calculateIntervalsOfValidValues(values, &valuesIntervals); + + EXPECT_EQ(1, static_cast(valuesIntervals.size())); + EXPECT_EQ(2, static_cast(valuesIntervals[0].first)); + EXPECT_EQ(4, static_cast(valuesIntervals[0].second)); +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(RimWellLogExtractionCurveImplTest, StripOffHugeValAtEndsAndInteriorOfVector) +{ + std::vector values; + values.push_back(HUGE_VAL); + values.push_back(HUGE_VAL); + values.push_back(1.0); + values.push_back(HUGE_VAL); + values.push_back(HUGE_VAL); + values.push_back(2.0); + values.push_back(3.0); + values.push_back(HUGE_VAL); + + std::vector< std::pair > valuesIntervals; + RigWellLogCurveDataTestInterface::calculateIntervalsOfValidValues(values, &valuesIntervals); + + EXPECT_EQ(2, static_cast(valuesIntervals.size())); + EXPECT_EQ(2, static_cast(valuesIntervals[0].first)); + EXPECT_EQ(2, static_cast(valuesIntervals[0].second)); + EXPECT_EQ(5, static_cast(valuesIntervals[1].first)); + EXPECT_EQ(6, static_cast(valuesIntervals[1].second)); +} diff --git a/ApplicationCode/ProjectDataModel/ProjectDataModel_UnitTests/WellPathAsciiFileReader-Test.cpp b/ApplicationCode/ProjectDataModel/ProjectDataModel_UnitTests/WellPathAsciiFileReader-Test.cpp new file mode 100644 index 0000000000..9c974b49be --- /dev/null +++ b/ApplicationCode/ProjectDataModel/ProjectDataModel_UnitTests/WellPathAsciiFileReader-Test.cpp @@ -0,0 +1,70 @@ +#include "gtest/gtest.h" + +#include "RimWellPathCollection.h" +#include "RigWellPath.h" + +#include +#include + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(RimWellPathAsciiFileReaderTest, TestWellNameNoColon) +{ + QTemporaryFile file; + if (file.open()) + { + QString wellName = "My test Wellname"; + { + QTextStream out(&file); + out << "name " << wellName << "\n"; + out << "1 2 3"; + } + + RifWellPathAsciiFileReader reader; + RifWellPathAsciiFileReader::WellData wpData = reader.readWellData(file.fileName(), 0); + EXPECT_TRUE(wpData.m_name == wellName); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(RimWellPathAsciiFileReaderTest, TestWellNameWithColon) +{ + QTemporaryFile file; + if (file.open()) + { + QString wellName = "My test Wellname"; + { + QTextStream out(&file); + out << "WELLNAME:" << wellName << "\n"; + out << "1 2 3"; + } + + RifWellPathAsciiFileReader reader; + RifWellPathAsciiFileReader::WellData wpData = reader.readWellData(file.fileName(), 0); + EXPECT_TRUE(wpData.m_name == wellName); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(RimWellPathAsciiFileReaderTest, TestWellNameWithColonAndSpace) +{ + QTemporaryFile file; + if (file.open()) + { + QString wellName = "My test Wellname"; + { + QTextStream out(&file); + out << "WELLNAME : " << wellName << "\n"; + out << "1 2 3"; + } + + RifWellPathAsciiFileReader reader; + RifWellPathAsciiFileReader::WellData wpData = reader.readWellData(file.fileName(), 0); + EXPECT_TRUE(wpData.m_name == wellName); + } +} diff --git a/ApplicationCode/ProjectDataModel/Rim3dOverlayInfoConfig.cpp b/ApplicationCode/ProjectDataModel/Rim3dOverlayInfoConfig.cpp index 78ebbeee4f..458a091220 100644 --- a/ApplicationCode/ProjectDataModel/Rim3dOverlayInfoConfig.cpp +++ b/ApplicationCode/ProjectDataModel/Rim3dOverlayInfoConfig.cpp @@ -48,10 +48,10 @@ CAF_PDM_SOURCE_INIT(Rim3dOverlayInfoConfig, "View3dOverlayInfoConfig"); //-------------------------------------------------------------------------------------------------- Rim3dOverlayInfoConfig::Rim3dOverlayInfoConfig() { - CAF_PDM_InitObject("Overlay 3D info", ":/InfoBox16x16.png", "", ""); + CAF_PDM_InitObject("Info Box", ":/InfoBox16x16.png", "", ""); CAF_PDM_InitField(&active, "Active", true, "Active", "", "", ""); - active.setUiHidden(true); + active.uiCapability()->setUiHidden(true); CAF_PDM_InitField(&showInfoText, "ShowInfoText", true, "Info Text", "", "", ""); CAF_PDM_InitField(&showAnimProgress, "ShowAnimProgress", true, "Animation progress", "", "", ""); diff --git a/ApplicationCode/ProjectDataModel/RimBinaryExportSettings.cpp b/ApplicationCode/ProjectDataModel/RimBinaryExportSettings.cpp index 4d22f6ebe6..fb579ce85b 100644 --- a/ApplicationCode/ProjectDataModel/RimBinaryExportSettings.cpp +++ b/ApplicationCode/ProjectDataModel/RimBinaryExportSettings.cpp @@ -16,8 +16,6 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RiaStdInclude.h" - #include "RimBinaryExportSettings.h" #include "cafPdmUiFilePathEditor.h" @@ -32,7 +30,7 @@ RimBinaryExportSettings::RimBinaryExportSettings() CAF_PDM_InitObject("RimBinaryExportSettings", "", "", ""); CAF_PDM_InitFieldNoDefault(&fileName, "Filename", "Export filename", "", "", ""); - fileName.setUiEditorTypeName(caf::PdmUiFilePathEditor::uiEditorTypeName()); + fileName.uiCapability()->setUiEditorTypeName(caf::PdmUiFilePathEditor::uiEditorTypeName()); CAF_PDM_InitFieldNoDefault(&eclipseKeyword, "EclipseKeyword", "Eclipse Keyword", "", "", ""); CAF_PDM_InitField(&undefinedValue, "UndefinedValue", 0.0, "Undefined value", "", "", ""); diff --git a/ApplicationCode/ProjectDataModel/RimCalcScript.cpp b/ApplicationCode/ProjectDataModel/RimCalcScript.cpp index 89bc122aaa..7cc376c539 100644 --- a/ApplicationCode/ProjectDataModel/RimCalcScript.cpp +++ b/ApplicationCode/ProjectDataModel/RimCalcScript.cpp @@ -16,9 +16,6 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RiaStdInclude.h" - - #include "cafPdmField.h" #include "RimCalcScript.h" #include "cafPdmUiFilePathEditor.h" @@ -34,10 +31,10 @@ RimCalcScript::RimCalcScript() CAF_PDM_InitField(&absolutePath, "AbsolutePath", QString(), "Location", "", "" ,""); CAF_PDM_InitField(&content, "Content", QString(), "Directory", "", "" ,""); - content.setUiHidden(true); - content.setIOWritable(false); + content.uiCapability()->setUiHidden(true); + content.xmlCapability()->setIOWritable(false); - absolutePath.setUiEditorTypeName(caf::PdmUiFilePathEditor::uiEditorTypeName()); + absolutePath.uiCapability()->setUiEditorTypeName(caf::PdmUiFilePathEditor::uiEditorTypeName()); } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/RimCase.cpp b/ApplicationCode/ProjectDataModel/RimCase.cpp index 94c0fdfcbb..09e06d6f75 100644 --- a/ApplicationCode/ProjectDataModel/RimCase.cpp +++ b/ApplicationCode/ProjectDataModel/RimCase.cpp @@ -20,14 +20,12 @@ #include "RimCase.h" #include "cafPdmObjectFactory.h" -#include "cafPdmAbstractClassSourceInit.h" - #include #include #include #include -CAF_PDM_ABSTRACT_SOURCE_INIT(RimCase, "RimCase"); +CAF_PDM_XML_ABSTRACT_SOURCE_INIT(RimCase, "RimCase"); //-------------------------------------------------------------------------------------------------- @@ -38,7 +36,7 @@ RimCase::RimCase() CAF_PDM_InitField(&caseUserDescription, "CaseUserDescription", QString(), "Case name", "", "" ,""); CAF_PDM_InitField(&caseId, "CaseId", -1, "Case ID", "", "" ,""); - caseId.setUiReadOnly(true); + caseId.uiCapability()->setUiReadOnly(true); } diff --git a/ApplicationCode/ProjectDataModel/RimCase.h b/ApplicationCode/ProjectDataModel/RimCase.h index 10fd3efc13..c389b97591 100644 --- a/ApplicationCode/ProjectDataModel/RimCase.h +++ b/ApplicationCode/ProjectDataModel/RimCase.h @@ -40,6 +40,9 @@ class RimCase : public caf::PdmObject virtual void updateFilePathsFromProjectPath(const QString& projectPath, const QString& oldProjectPath) = 0; virtual caf::PdmFieldHandle* userDescriptionField() { return &caseUserDescription; } + + virtual QStringList timeStepStrings() { return QStringList(); } + protected: static QString relocateFile(const QString& fileName, const QString& newProjectPath, const QString& oldProjectPath, bool* foundFile, std::vector* searchedPaths); diff --git a/ApplicationCode/ProjectDataModel/RimCaseCollection.cpp b/ApplicationCode/ProjectDataModel/RimCaseCollection.cpp index b3122b9b94..b63de1f8f8 100644 --- a/ApplicationCode/ProjectDataModel/RimCaseCollection.cpp +++ b/ApplicationCode/ProjectDataModel/RimCaseCollection.cpp @@ -33,7 +33,8 @@ RimCaseCollection::RimCaseCollection() { CAF_PDM_InitObject("Derived Statistics", "", "", ""); - CAF_PDM_InitFieldNoDefault(&reservoirs, "Reservoirs", "", "", "", ""); + CAF_PDM_InitFieldNoDefault(&reservoirs, "Reservoirs", "Reservoirs ChildArrayField", "", "", ""); + reservoirs.uiCapability()->setUiHidden(true); } //-------------------------------------------------------------------------------------------------- @@ -49,15 +50,7 @@ RimCaseCollection::~RimCaseCollection() //-------------------------------------------------------------------------------------------------- RimIdenticalGridCaseGroup* RimCaseCollection::parentCaseGroup() { - std::vector parentObjects; - this->parentObjectsOfType(parentObjects); - - if (parentObjects.size() > 0) - { - return parentObjects[0]; - } - - return NULL; + return dynamic_cast(this->parentField()->ownerObject()); } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/RimCaseCollection.h b/ApplicationCode/ProjectDataModel/RimCaseCollection.h index 9208554226..e2bc36ad5c 100644 --- a/ApplicationCode/ProjectDataModel/RimCaseCollection.h +++ b/ApplicationCode/ProjectDataModel/RimCaseCollection.h @@ -20,6 +20,7 @@ #include "cafPdmField.h" #include "cafPdmObject.h" +#include "cafPdmChildArrayField.h" class RimEclipseCase; class RimIdenticalGridCaseGroup; @@ -36,7 +37,7 @@ class RimCaseCollection : public caf::PdmObject public: RimCaseCollection(); virtual ~RimCaseCollection(); - caf::PdmPointersField reservoirs; + caf::PdmChildArrayField reservoirs; RimIdenticalGridCaseGroup* parentCaseGroup(); RimEclipseCase* findByDescription(const QString& caseDescription) const; diff --git a/ApplicationCode/ProjectDataModel/RimCellEdgeColors.cpp b/ApplicationCode/ProjectDataModel/RimCellEdgeColors.cpp index d55ac2b40d..56be7f3f1a 100644 --- a/ApplicationCode/ProjectDataModel/RimCellEdgeColors.cpp +++ b/ApplicationCode/ProjectDataModel/RimCellEdgeColors.cpp @@ -36,10 +36,10 @@ CAF_PDM_SOURCE_INIT(RimCellEdgeColors, "CellEdgeResultSlot"); //-------------------------------------------------------------------------------------------------- RimCellEdgeColors::RimCellEdgeColors() { - CAF_PDM_InitObject("Cell Edge Result", "", "", ""); + CAF_PDM_InitObject("Cell Edge Result", ":/EdgeResult_1.png", "", ""); CAF_PDM_InitField(&enableCellEdgeColors, "EnableCellEdgeColors", true, "Enable cell edge results", "", "", ""); - enableCellEdgeColors.setUiHidden(true); + enableCellEdgeColors.uiCapability()->setUiHidden(true); CAF_PDM_InitFieldNoDefault(&resultVariable, "CellEdgeVariable", "Result property", "", "", ""); CAF_PDM_InitField(&useXVariable, "UseXVariable", true, "Use X values", "", "", ""); @@ -47,8 +47,9 @@ RimCellEdgeColors::RimCellEdgeColors() CAF_PDM_InitField(&useZVariable, "UseZVariable", true, "Use Z values", "", "", ""); CAF_PDM_InitFieldNoDefault(&legendConfig, "LegendDefinition", "Legend Definition", ":/Legend.png", "", ""); + legendConfig.uiCapability()->setUiHidden(true); - resultVariable.setUiEditorTypeName(caf::PdmUiListEditor::uiEditorTypeName()); + resultVariable.uiCapability()->setUiEditorTypeName(caf::PdmUiListEditor::uiEditorTypeName()); legendConfig = new RimLegendConfig(); diff --git a/ApplicationCode/ProjectDataModel/RimCellEdgeColors.h b/ApplicationCode/ProjectDataModel/RimCellEdgeColors.h index 46b5b73a82..6a8e3c8215 100644 --- a/ApplicationCode/ProjectDataModel/RimCellEdgeColors.h +++ b/ApplicationCode/ProjectDataModel/RimCellEdgeColors.h @@ -20,15 +20,17 @@ #pragma once -#include "cafPdmObject.h" -#include "cafPdmField.h" -#include "cafAppEnum.h" #include "RimDefines.h" + +#include "cafAppEnum.h" #include "cafFixedArray.h" +#include "cafPdmChildField.h" +#include "cafPdmField.h" +#include "cafPdmObject.h" class RigCaseCellResultsData; -class RimLegendConfig; class RimEclipseView; +class RimLegendConfig; //================================================================================================== @@ -56,7 +58,7 @@ class RimCellEdgeColors : public caf::PdmObject caf::PdmField resultVariable; caf::PdmField enableCellEdgeColors; - caf::PdmField legendConfig; + caf::PdmChildField legendConfig; double ignoredScalarValue() { return m_ignoredResultScalar; } void gridScalarIndices(size_t resultIndices[6]); void gridScalarResultNames(QStringList* resultNames); diff --git a/ApplicationCode/ProjectDataModel/RimCellFilter.cpp b/ApplicationCode/ProjectDataModel/RimCellFilter.cpp index 4d1bd7266e..6cb52f57f2 100644 --- a/ApplicationCode/ProjectDataModel/RimCellFilter.cpp +++ b/ApplicationCode/ProjectDataModel/RimCellFilter.cpp @@ -16,12 +16,11 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RiaStdInclude.h" - +#include "RimCellFilter.h" #include "cafAppEnum.h" -#include "RimCellFilter.h" +#include namespace caf { @@ -46,7 +45,7 @@ RimCellFilter::RimCellFilter() CAF_PDM_InitField(&name, "UserDescription", QString("Filter Name"), "Name", "", "", ""); CAF_PDM_InitField(&isActive, "Active", true, "Active", "", "", ""); - isActive.setUiHidden(true); + isActive.uiCapability()->setUiHidden(true); CAF_PDM_InitFieldNoDefault(&filterMode, "FilterType", "Filter Type", "", "", ""); } @@ -96,7 +95,7 @@ void RimCellFilter::updateIconState() painter.drawPixmap(0,0, sign); } - if (!isActive) + if (!isActive || isActive.uiCapability()->isUiReadOnly()) { QIcon temp(icPixmap); icPixmap = temp.pixmap(16, 16, QIcon::Disabled); diff --git a/ApplicationCode/ProjectDataModel/RimCellRangeFilter.cpp b/ApplicationCode/ProjectDataModel/RimCellRangeFilter.cpp index 88f79f8a6c..cb5216f40e 100644 --- a/ApplicationCode/ProjectDataModel/RimCellRangeFilter.cpp +++ b/ApplicationCode/ProjectDataModel/RimCellRangeFilter.cpp @@ -25,9 +25,11 @@ #include "RigCaseData.h" #include "RigGridBase.h" #include "RigMainGrid.h" + #include "RimEclipseCase.h" #include "RimCellRangeFilterCollection.h" #include "RimEclipseView.h" +#include "RimViewController.h" #include "cafPdmUiSliderEditor.h" #include "cvfAssert.h" @@ -38,7 +40,6 @@ CAF_PDM_SOURCE_INIT(RimCellRangeFilter, "CellRangeFilter"); /// //-------------------------------------------------------------------------------------------------- RimCellRangeFilter::RimCellRangeFilter() - : m_parentContainer(NULL) { CAF_PDM_InitObject("Cell Range Filter", ":/CellFilter_Range.png", "", ""); @@ -46,22 +47,22 @@ RimCellRangeFilter::RimCellRangeFilter() CAF_PDM_InitField(&propagateToSubGrids, "PropagateToSubGrids", true, "Apply to Subgrids", "", "",""); CAF_PDM_InitField(&startIndexI, "StartIndexI", 1, "Start index I", "", "",""); - startIndexI.setUiEditorTypeName(caf::PdmUiSliderEditor::uiEditorTypeName()); + startIndexI.uiCapability()->setUiEditorTypeName(caf::PdmUiSliderEditor::uiEditorTypeName()); CAF_PDM_InitField(&cellCountI, "CellCountI", 1, "Cell Count I", "", "",""); - cellCountI.setUiEditorTypeName(caf::PdmUiSliderEditor::uiEditorTypeName()); + cellCountI.uiCapability()->setUiEditorTypeName(caf::PdmUiSliderEditor::uiEditorTypeName()); CAF_PDM_InitField(&startIndexJ, "StartIndexJ", 1, "Start index J", "", "",""); - startIndexJ.setUiEditorTypeName(caf::PdmUiSliderEditor::uiEditorTypeName()); + startIndexJ.uiCapability()->setUiEditorTypeName(caf::PdmUiSliderEditor::uiEditorTypeName()); CAF_PDM_InitField(&cellCountJ, "CellCountJ", 1, "Cell Count J", "", "",""); - cellCountJ.setUiEditorTypeName(caf::PdmUiSliderEditor::uiEditorTypeName()); + cellCountJ.uiCapability()->setUiEditorTypeName(caf::PdmUiSliderEditor::uiEditorTypeName()); CAF_PDM_InitField(&startIndexK, "StartIndexK", 1, "Start index K", "", "",""); - startIndexK.setUiEditorTypeName(caf::PdmUiSliderEditor::uiEditorTypeName()); + startIndexK.uiCapability()->setUiEditorTypeName(caf::PdmUiSliderEditor::uiEditorTypeName()); CAF_PDM_InitField(&cellCountK, "CellCountK", 1, "Cell Count K", "", "",""); - cellCountK.setUiEditorTypeName(caf::PdmUiSliderEditor::uiEditorTypeName()); + cellCountK.uiCapability()->setUiEditorTypeName(caf::PdmUiSliderEditor::uiEditorTypeName()); updateIconState(); } @@ -82,25 +83,16 @@ void RimCellRangeFilter::fieldChangedByUi(const caf::PdmFieldHandle* changedFiel { computeAndSetValidValues(); - CVF_ASSERT(m_parentContainer); - m_parentContainer->fieldChangedByUi(changedField, oldValue, newValue); + parentContainer()->updateDisplayModeNotifyManagedViews(this); } } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimCellRangeFilter::setParentContainer(RimCellRangeFilterCollection* parentContainer) -{ - m_parentContainer = parentContainer; -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimCellRangeFilter::computeAndSetValidValues() { - CVF_ASSERT(m_parentContainer); + CVF_ASSERT(parentContainer()); const cvf::StructGridInterface* grid = selectedGrid(); if (grid && grid->cellCountI() > 0 && grid->cellCountJ() > 0 && grid->cellCountK() > 0) @@ -117,17 +109,25 @@ void RimCellRangeFilter::computeAndSetValidValues() this->updateIconState(); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimCellRangeFilter::updateActiveState() +{ + isActive.uiCapability()->setUiReadOnly(isRangeFilterControlled()); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimCellRangeFilter::setDefaultValues() { - CVF_ASSERT(m_parentContainer); + CVF_ASSERT(parentContainer()); const cvf::StructGridInterface* grid = selectedGrid(); - RigActiveCellInfo* actCellInfo = m_parentContainer->activeCellInfo(); - if (grid == m_parentContainer->gridByIndex(0) && actCellInfo) + RigActiveCellInfo* actCellInfo = parentContainer()->activeCellInfo(); + if (grid == parentContainer()->gridByIndex(0) && actCellInfo) { cvf::Vec3st min, max; actCellInfo->IJKBoundingBox(min, max); @@ -164,7 +164,7 @@ void RimCellRangeFilter::setDefaultValues() //-------------------------------------------------------------------------------------------------- RimCellRangeFilterCollection* RimCellRangeFilter::parentContainer() { - return m_parentContainer; + return dynamic_cast(this->parentField()->ownerObject()); } //-------------------------------------------------------------------------------------------------- @@ -173,7 +173,7 @@ RimCellRangeFilterCollection* RimCellRangeFilter::parentContainer() void RimCellRangeFilter::defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute * attribute) { caf::PdmUiSliderEditorAttribute* myAttr = static_cast(attribute); - if (!myAttr || !m_parentContainer) + if (!myAttr || !parentContainer()) { return; } @@ -196,8 +196,8 @@ void RimCellRangeFilter::defineEditorAttribute(const caf::PdmFieldHandle* field, myAttr->m_maximum = static_cast(grid->cellCountK()); } - RigActiveCellInfo* actCellInfo = m_parentContainer->activeCellInfo(); - if (grid == m_parentContainer->gridByIndex(0) && actCellInfo) + RigActiveCellInfo* actCellInfo = parentContainer()->activeCellInfo(); + if (grid == parentContainer()->gridByIndex(0) && actCellInfo) { cvf::Vec3st min, max; actCellInfo->IJKBoundingBox(min, max); @@ -211,24 +211,50 @@ void RimCellRangeFilter::defineEditorAttribute(const caf::PdmFieldHandle* field, max.y() = max.y() + 1; max.z() = max.z() + 1; - startIndexI.setUiName(QString("I Start (%1)").arg(min.x())); - startIndexJ.setUiName(QString("J Start (%1)").arg(min.y())); - startIndexK.setUiName(QString("K Start (%1)").arg(min.z())); - cellCountI.setUiName(QString(" Width (%1)").arg(max.x() - min.x() + 1)); - cellCountJ.setUiName(QString(" Width (%1)").arg(max.y() - min.y() + 1)); - cellCountK.setUiName(QString(" Width (%1)").arg(max.z() - min.z() + 1)); + startIndexI.uiCapability()->setUiName(QString("I Start (%1)").arg(min.x())); + startIndexJ.uiCapability()->setUiName(QString("J Start (%1)").arg(min.y())); + startIndexK.uiCapability()->setUiName(QString("K Start (%1)").arg(min.z())); + cellCountI.uiCapability()->setUiName(QString(" Width (%1)").arg(max.x() - min.x() + 1)); + cellCountJ.uiCapability()->setUiName(QString(" Width (%1)").arg(max.y() - min.y() + 1)); + cellCountK.uiCapability()->setUiName(QString(" Width (%1)").arg(max.z() - min.z() + 1)); } else { - startIndexI.setUiName(QString("I Start")); - startIndexJ.setUiName(QString("J Start")); - startIndexK.setUiName(QString("K Start")); - cellCountI.setUiName(QString(" Width")); - cellCountJ.setUiName(QString(" Width")); - cellCountK.setUiName(QString(" Width")); + startIndexI.uiCapability()->setUiName(QString("I Start")); + startIndexJ.uiCapability()->setUiName(QString("J Start")); + startIndexK.uiCapability()->setUiName(QString("K Start")); + cellCountI.uiCapability()->setUiName(QString(" Width")); + cellCountJ.uiCapability()->setUiName(QString(" Width")); + cellCountK.uiCapability()->setUiName(QString(" Width")); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimCellRangeFilter::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) +{ + bool readOnlyState = isRangeFilterControlled(); + + std::vector objFields; + this->fields(objFields); + for (size_t i = 0; i < objFields.size(); i ++) + { + objFields[i]->uiCapability()->setUiReadOnly(readOnlyState); } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimCellRangeFilter::defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName) +{ + RimCellFilter::defineUiTreeOrdering(uiTreeOrdering, uiConfigName); + + updateActiveState(); + updateIconState(); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -260,17 +286,35 @@ QList RimCellRangeFilter::calculateValueOptions(const ca return options; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimCellRangeFilter::isRangeFilterControlled() +{ + RimView* rimView = NULL; + firstAnchestorOrThisOfType(rimView); + CVF_ASSERT(rimView); + + bool isRangeFilterControlled = false; + if (rimView->viewController() && rimView->viewController()->isRangeFiltersControlled()) + { + isRangeFilterControlled = true; + } + + return isRangeFilterControlled; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- const cvf::StructGridInterface* RimCellRangeFilter::selectedGrid() { - if (gridIndex() >= m_parentContainer->gridCount()) + if (gridIndex() >= parentContainer()->gridCount()) { gridIndex = 0; } - const cvf::StructGridInterface* grid = m_parentContainer->gridByIndex(gridIndex()); + const cvf::StructGridInterface* grid = parentContainer()->gridByIndex(gridIndex()); CVF_ASSERT(grid); diff --git a/ApplicationCode/ProjectDataModel/RimCellRangeFilter.h b/ApplicationCode/ProjectDataModel/RimCellRangeFilter.h index 07164269cd..488cb974a7 100644 --- a/ApplicationCode/ProjectDataModel/RimCellRangeFilter.h +++ b/ApplicationCode/ProjectDataModel/RimCellRangeFilter.h @@ -44,7 +44,6 @@ class RimCellRangeFilter : public RimCellFilter RimCellRangeFilter(); virtual ~RimCellRangeFilter(); - void setParentContainer(RimCellRangeFilterCollection* parentContainer); RimCellRangeFilterCollection* parentContainer(); void setDefaultValues(); @@ -60,17 +59,21 @@ class RimCellRangeFilter : public RimCellFilter void computeAndSetValidValues(); - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue); + void updateActiveState(); protected: + virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue); virtual void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute); + virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) ; + virtual void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName); virtual QList calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly ); private: - const cvf::StructGridInterface* selectedGrid(); + bool isRangeFilterControlled(); - RimCellRangeFilterCollection* m_parentContainer; +private: + const cvf::StructGridInterface* selectedGrid(); }; diff --git a/ApplicationCode/ProjectDataModel/RimCellRangeFilterCollection.cpp b/ApplicationCode/ProjectDataModel/RimCellRangeFilterCollection.cpp index 64623f1f0c..fe47a95e20 100644 --- a/ApplicationCode/ProjectDataModel/RimCellRangeFilterCollection.cpp +++ b/ApplicationCode/ProjectDataModel/RimCellRangeFilterCollection.cpp @@ -20,16 +20,22 @@ #include "RimCellRangeFilterCollection.h" -#include "RimEclipseCase.h" -#include "RigGridBase.h" -#include "RimEclipseView.h" #include "RigCaseData.h" -#include "RigFemPartCollection.h" -#include "RimGeoMechView.h" -#include "RimGeoMechCase.h" -#include "RigGeoMechCaseData.h" #include "RigFemPart.h" +#include "RigFemPartCollection.h" #include "RigFemPartGrid.h" +#include "RigGeoMechCaseData.h" +#include "RigGridBase.h" + +#include "RimEclipseCase.h" +#include "RimEclipseView.h" +#include "RimGeoMechCase.h" +#include "RimGeoMechView.h" +#include "RimViewController.h" +#include "RimViewLinker.h" + +#include "cafPdmUiEditorHandle.h" + CAF_PDM_SOURCE_INIT(RimCellRangeFilterCollection, "CellRangeFilterCollection"); @@ -38,11 +44,13 @@ CAF_PDM_SOURCE_INIT(RimCellRangeFilterCollection, "CellRangeFilterCollection"); //-------------------------------------------------------------------------------------------------- RimCellRangeFilterCollection::RimCellRangeFilterCollection() { - CAF_PDM_InitObject("Cell Range Filters", ":/CellFilter_Range.png", "", ""); + CAF_PDM_InitObject("Range Filters", ":/CellFilter_Range.png", "", ""); CAF_PDM_InitFieldNoDefault(&rangeFilters, "RangeFilters", "Range Filters", "", "", ""); + rangeFilters.uiCapability()->setUiHidden(true); + CAF_PDM_InitField(&isActive, "Active", true, "Active", "", "", ""); - isActive.setUiHidden(true); + isActive.uiCapability()->setUiHidden(true); } //-------------------------------------------------------------------------------------------------- @@ -50,22 +58,9 @@ RimCellRangeFilterCollection::RimCellRangeFilterCollection() //-------------------------------------------------------------------------------------------------- RimCellRangeFilterCollection::~RimCellRangeFilterCollection() { - std::list< caf::PdmPointer< RimCellRangeFilter > >::const_iterator it; - for (it = rangeFilters.v().begin(); it != rangeFilters.v().end(); ++it) - { - delete it->p(); - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimCellRangeFilterCollection::setReservoirView(RimView* reservoirView) -{ - m_reservoirView = reservoirView; + rangeFilters.deleteAllChildObjects(); } - //-------------------------------------------------------------------------------------------------- /// RimCellRangeFilter is using Eclipse 1-based indexing, adjust filter values before // populating cvf::CellRangeFilter (which is 0-based) @@ -74,10 +69,9 @@ void RimCellRangeFilterCollection::compoundCellRangeFilter(cvf::CellRangeFilter* { CVF_ASSERT(cellRangeFilter); - std::list< caf::PdmPointer >::const_iterator it; - for (it = rangeFilters.v().begin(); it != rangeFilters.v().end(); it++) + for (size_t i = 0; i < rangeFilters.size(); i++) { - RimCellRangeFilter* rangeFilter = *it; + RimCellRangeFilter* rangeFilter = rangeFilters[i]; if (rangeFilter && rangeFilter->isActive() && static_cast(rangeFilter->gridIndex()) == gridIndex) { @@ -107,7 +101,6 @@ void RimCellRangeFilterCollection::compoundCellRangeFilter(cvf::CellRangeFilter* } } - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -126,14 +119,13 @@ RigMainGrid* RimCellRangeFilterCollection::mainGrid() const return NULL; } - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RigActiveCellInfo* RimCellRangeFilterCollection::activeCellInfo() const { RimEclipseView* eclipseView = this->eclipseView(); - if (eclipseView ) + if (eclipseView) { return eclipseView->currentActiveCellInfo(); } @@ -141,77 +133,48 @@ RigActiveCellInfo* RimCellRangeFilterCollection::activeCellInfo() const return NULL; } - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimCellRangeFilterCollection::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) { - - this->updateUiIconFromToggleField(); - - CVF_ASSERT(m_reservoirView); - - m_reservoirView->scheduleGeometryRegen(RANGE_FILTERED); - m_reservoirView->scheduleGeometryRegen(RANGE_FILTERED_INACTIVE); - - m_reservoirView->scheduleCreateDisplayModelAndRedraw(); + updateIconState(); + uiCapability()->updateConnectedEditors(); + + updateDisplayModeNotifyManagedViews(NULL); } - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RimCellRangeFilter* RimCellRangeFilterCollection::createAndAppendRangeFilter() +void RimCellRangeFilterCollection::updateDisplayModeNotifyManagedViews(RimCellRangeFilter* changedRangeFilter) { - RimCellRangeFilter* rangeFilter = new RimCellRangeFilter(); - rangeFilter->setParentContainer(this); - rangeFilter->setDefaultValues(); - - rangeFilters.v().push_back(rangeFilter); - - rangeFilter->name = QString("New Filter (%1)").arg(rangeFilters().size()); + RimView* view = NULL; + firstAnchestorOrThisOfType(view); - return rangeFilter; -} -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RimView* RimCellRangeFilterCollection::reservoirView() -{ - return m_reservoirView; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RimEclipseView* RimCellRangeFilterCollection::eclipseView() const -{ - return dynamic_cast(m_reservoirView); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimCellRangeFilterCollection::initAfterRead() -{ - std::list< caf::PdmPointer >::iterator it; - for (it = rangeFilters.v().begin(); it != rangeFilters.v().end(); it++) + if (view->isMasterView()) { - RimCellRangeFilter* rangeFilter = *it; - rangeFilter->setParentContainer(this); - rangeFilter->updateIconState(); + RimViewLinker* viewLinker = view->assosiatedViewLinker(); + if (viewLinker) + { + // Update data for range filter + // Update of display model is handled by view->scheduleGeometryRegen, also for managed views + viewLinker->updateRangeFilters(changedRangeFilter); + } } - this->updateUiIconFromToggleField(); + view->scheduleGeometryRegen(RANGE_FILTERED); + view->scheduleGeometryRegen(RANGE_FILTERED_INACTIVE); + + view->scheduleCreateDisplayModelAndRedraw(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimCellRangeFilterCollection::remove(RimCellRangeFilter* rangeFilter) +RimEclipseView* RimCellRangeFilterCollection::eclipseView() const { - rangeFilters.v().remove(rangeFilter); + return dynamic_cast(baseView()); } //-------------------------------------------------------------------------------------------------- @@ -221,10 +184,9 @@ bool RimCellRangeFilterCollection::hasActiveFilters() const { if (!isActive()) return false; - std::list< caf::PdmPointer< RimCellRangeFilter > >::const_iterator it; - for (it = rangeFilters.v().begin(); it != rangeFilters.v().end(); ++it) + for (size_t i = 0; i < rangeFilters.size(); i++) { - if ((*it)->isActive()) return true; + if (rangeFilters[i]->isActive()) return true; } return false; @@ -245,14 +207,12 @@ bool RimCellRangeFilterCollection::hasActiveIncludeFilters() const { if (!isActive) return false; - std::list< caf::PdmPointer< RimCellRangeFilter > >::const_iterator it; - for (it = rangeFilters.v().begin(); it != rangeFilters.v().end(); ++it) + for (size_t i = 0; i < rangeFilters.size(); i++) { - if ((*it)->isActive() && (*it)->filterMode() == RimCellFilter::INCLUDE) return true; + if (rangeFilters[i]->isActive() && rangeFilters[i]->filterMode() == RimCellFilter::INCLUDE) return true; } return false; - } //-------------------------------------------------------------------------------------------------- @@ -329,16 +289,74 @@ QString RimCellRangeFilterCollection::gridName(int gridIndex) const //-------------------------------------------------------------------------------------------------- RigFemPartCollection* RimCellRangeFilterCollection::femPartColl() const { - RimGeoMechView* eclipseView = dynamic_cast(m_reservoirView); + RimGeoMechView* geoView = dynamic_cast(baseView()); + if (geoView && + geoView->geoMechCase() && + geoView->geoMechCase()->geoMechData() ) + { + return geoView->geoMechCase()->geoMechData()->femParts(); + } - if (eclipseView && - eclipseView->geoMechCase() && - eclipseView->geoMechCase()->geoMechData() ) + return NULL; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimView* RimCellRangeFilterCollection::baseView() const +{ + RimView* rimView = NULL; + firstAnchestorOrThisOfType(rimView); + + return rimView; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimCellRangeFilterCollection::updateIconState() +{ + bool activeIcon = true; + + RimViewController* viewController = baseView()->viewController(); + if (viewController && ( viewController->isRangeFiltersControlled() + || viewController->isVisibleCellsOveridden()) ) { + activeIcon = false; + } - return eclipseView->geoMechCase()->geoMechData()->femParts(); + if (!isActive) + { + activeIcon = false; } - return NULL; + updateUiIconFromState(activeIcon); + + for (size_t i = 0; i < rangeFilters.size(); i++) + { + RimCellRangeFilter* rangeFilter = rangeFilters[i]; + rangeFilter->updateActiveState(); + rangeFilter->updateIconState(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimCellRangeFilterCollection::defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName) +{ + PdmObject::defineUiTreeOrdering(uiTreeOrdering, uiConfigName); + + RimViewController* viewController = baseView()->viewController(); + if (viewController && viewController->isRangeFiltersControlled()) + { + isActive.uiCapability()->setUiReadOnly(true); + } + else + { + isActive.uiCapability()->setUiReadOnly(false); + } + + updateIconState(); } diff --git a/ApplicationCode/ProjectDataModel/RimCellRangeFilterCollection.h b/ApplicationCode/ProjectDataModel/RimCellRangeFilterCollection.h index 56c04cf9fa..5ad20fb37a 100644 --- a/ApplicationCode/ProjectDataModel/RimCellRangeFilterCollection.h +++ b/ApplicationCode/ProjectDataModel/RimCellRangeFilterCollection.h @@ -20,10 +20,12 @@ #include "RimCellRangeFilter.h" +#include "cafPdmChildArrayField.h" + class RigActiveCellInfo; +class RigFemPartCollection; class RigGridBase; class RimView; -class RigFemPartCollection; //================================================================================================== /// @@ -38,38 +40,32 @@ class RimCellRangeFilterCollection : public caf::PdmObject // Fields caf::PdmField isActive; - caf::PdmField< std::list< caf::PdmPointer< RimCellRangeFilter > > > rangeFilters; + caf::PdmChildArrayField rangeFilters; // Methods - RimCellRangeFilter* createAndAppendRangeFilter(); - void remove(RimCellRangeFilter* rangeFilter); - void compoundCellRangeFilter(cvf::CellRangeFilter* cellRangeFilter, size_t gridIndex) const; bool hasActiveFilters() const; bool hasActiveIncludeFilters() const; - void setReservoirView(RimView* reservoirView); - - RimView* reservoirView(); const cvf::StructGridInterface* gridByIndex(int gridIndex) const; int gridCount() const; QString gridName(int gridIndex) const; RigActiveCellInfo* activeCellInfo() const; - // Overridden methods - virtual void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ); - virtual caf::PdmFieldHandle* objectToggleField(); + void updateDisplayModeNotifyManagedViews(RimCellRangeFilter* changedRangeFilter); + void updateIconState(); protected: - // Overridden methods - virtual void initAfterRead(); + virtual void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ); + virtual void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName); + virtual caf::PdmFieldHandle* objectToggleField(); +private: + RimView* baseView() const; private: RimEclipseView* eclipseView() const; RigMainGrid* mainGrid() const; RigFemPartCollection* femPartColl() const; - - RimView* m_reservoirView; }; diff --git a/ApplicationCode/ProjectDataModel/RimCommandObject.cpp b/ApplicationCode/ProjectDataModel/RimCommandObject.cpp index de670e402b..553c79d4ea 100644 --- a/ApplicationCode/ProjectDataModel/RimCommandObject.cpp +++ b/ApplicationCode/ProjectDataModel/RimCommandObject.cpp @@ -25,7 +25,7 @@ #include "RimProject.h" #include "RimEclipseStatisticsCase.h" -#include "cafPdmDocument.h" +#include "cafPdmObjectGroup.h" #include "cafPdmUiPushButtonEditor.h" #include "cafPdmUiTextEditor.h" @@ -60,16 +60,16 @@ RimCommandExecuteScript::RimCommandExecuteScript() CAF_PDM_InitFieldNoDefault(&name, "Name", "Name", "", "", ""); CAF_PDM_InitField(&scriptText, "ScriptText", QString(), "ScriptText", "", "" ,""); - scriptText.setUiEditorTypeName(caf::PdmUiTextEditor::uiEditorTypeName()); + scriptText.uiCapability()->setUiEditorTypeName(caf::PdmUiTextEditor::uiEditorTypeName()); CAF_PDM_InitField(&isEnabled, "IsEnabled", true, "Enabled ", "", "", ""); CAF_PDM_InitField(&execute, "Execute", true, "Execute", "", "", ""); - execute.setIOWritable(false); - execute.setIOReadable(false); - execute.setUiEditorTypeName(caf::PdmUiPushButtonEditor::uiEditorTypeName()); - execute.setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN); + execute.xmlCapability()->setIOWritable(false); + execute.xmlCapability()->setIOReadable(false); + execute.uiCapability()->setUiEditorTypeName(caf::PdmUiPushButtonEditor::uiEditorTypeName()); + execute.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN); } //-------------------------------------------------------------------------------------------------- @@ -159,7 +159,7 @@ void RimCommandFactory::createCommandObjects(const caf::PdmObjectGroup& selected { for (size_t i = 0; i < selectedObjects.objects.size(); i++) { - caf::PdmObject* pdmObject = selectedObjects.objects[i]; + caf::PdmObjectHandle* pdmObject = selectedObjects.objects[i]; if (dynamic_cast(pdmObject)) { @@ -219,16 +219,17 @@ void RimCommandIssueFieldChanged::redo() RiaApplication* app = RiaApplication::instance(); PdmObject* project = app->project(); - caf::PdmObject* pdmObject = findObjectByName(project, this->objectName); + caf::PdmObjectHandle* pdmObject = findObjectByName(project, this->objectName); if (pdmObject) { caf::PdmFieldHandle* fieldHandle = findFieldByKeyword(pdmObject, this->fieldName); - if (fieldHandle) + if (fieldHandle && fieldHandle->uiCapability()) { + caf::PdmUiFieldHandle* uiFieldHandle = fieldHandle->uiCapability(); QVariant variantValue(this->fieldValueToApply); - fieldHandle->setValueFromUi(variantValue); + uiFieldHandle->setValueFromUi(variantValue); } } } @@ -252,7 +253,7 @@ caf::PdmFieldHandle* RimCommandIssueFieldChanged::userDescriptionField() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimCommandIssueFieldChanged::childObjects(caf::PdmObject* pdmObject, std::vector& children) +void RimCommandIssueFieldChanged::childObjects(caf::PdmObject* pdmObject, std::vector& children) { if (!pdmObject) return; @@ -269,27 +270,28 @@ void RimCommandIssueFieldChanged::childObjects(caf::PdmObject* pdmObject, std::v //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -caf::PdmObject* RimCommandIssueFieldChanged::findObjectByName(caf::PdmObject* pdmObject, const QString& objectName) +caf::PdmObjectHandle* RimCommandIssueFieldChanged::findObjectByName(caf::PdmObjectHandle* pdmObject, const QString& objectName) { std::vector fields; pdmObject->fields(fields); - if (pdmObject->uiName() == objectName) + caf::PdmUiObjectHandle* uiObjectHandle = uiObj(pdmObject); + + if (uiObjectHandle && uiObjectHandle->uiName() == objectName) { return pdmObject; } - for (size_t fIdx = 0; fIdx < fields.size(); fIdx++) { if (fields[fIdx]) { - std::vector children; + std::vector children; fields[fIdx]->childObjects(&children); for (size_t cIdx = 0; cIdx < children.size(); cIdx++) { - PdmObject* candidateObj = findObjectByName(children[cIdx], objectName); + PdmObjectHandle* candidateObj = findObjectByName(children[cIdx], objectName); if (candidateObj) { return candidateObj; @@ -305,7 +307,7 @@ caf::PdmObject* RimCommandIssueFieldChanged::findObjectByName(caf::PdmObject* pd //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -caf::PdmFieldHandle* RimCommandIssueFieldChanged::findFieldByKeyword(caf::PdmObject* pdmObject, const QString& keywordName) +caf::PdmFieldHandle* RimCommandIssueFieldChanged::findFieldByKeyword(caf::PdmObjectHandle* pdmObject, const QString& keywordName) { std::vector fields; pdmObject->fields(fields); diff --git a/ApplicationCode/ProjectDataModel/RimCommandObject.h b/ApplicationCode/ProjectDataModel/RimCommandObject.h index 33c596565d..19bb199619 100644 --- a/ApplicationCode/ProjectDataModel/RimCommandObject.h +++ b/ApplicationCode/ProjectDataModel/RimCommandObject.h @@ -20,11 +20,11 @@ #pragma once -#include "cvfBase.h" -#include "cvfObject.h" #include "cafPdmField.h" #include "cafPdmObject.h" -#include "cafPdmDocument.h" +#include "cafPdmObjectGroup.h" +#include "cvfBase.h" +#include "cvfObject.h" //-------------------------------------------------------------------------------------------------- @@ -92,9 +92,9 @@ class RimCommandIssueFieldChanged : public RimCommandObject virtual caf::PdmFieldHandle* userDescriptionField(); private: - void childObjects(caf::PdmObject* pdmObject, std::vector& children); - caf::PdmObject* findObjectByName(caf::PdmObject* root, const QString& objectName); - caf::PdmFieldHandle* findFieldByKeyword(caf::PdmObject* pdmObject, const QString& fieldName); + void childObjects(caf::PdmObject* pdmObject, std::vector& children); + caf::PdmObjectHandle* findObjectByName(caf::PdmObjectHandle* root, const QString& objectName); + caf::PdmFieldHandle* findFieldByKeyword(caf::PdmObjectHandle* pdmObject, const QString& fieldName); }; diff --git a/ApplicationCode/ProjectDataModel/RimDefines.cpp b/ApplicationCode/ProjectDataModel/RimDefines.cpp index ccc6eb4dab..56161163dd 100644 --- a/ApplicationCode/ProjectDataModel/RimDefines.cpp +++ b/ApplicationCode/ProjectDataModel/RimDefines.cpp @@ -18,8 +18,6 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RiaStdInclude.h" - #include "RimDefines.h" #include "cafAppEnum.h" diff --git a/ApplicationCode/ProjectDataModel/RimEclipseCase.cpp b/ApplicationCode/ProjectDataModel/RimEclipseCase.cpp index fa53aa8f05..65f31910fc 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseCase.cpp +++ b/ApplicationCode/ProjectDataModel/RimEclipseCase.cpp @@ -28,11 +28,15 @@ #include "RimCaseCollection.h" #include "RimCellEdgeColors.h" +#include "RimCommandObject.h" +#include "RimEclipseCellColors.h" #include "RimEclipsePropertyFilter.h" #include "RimEclipsePropertyFilterCollection.h" -#include "RimReservoirCellResultsStorage.h" #include "RimEclipseView.h" -#include "RimEclipseCellColors.h" +#include "RimReservoirCellResultsStorage.h" +#include "RimProject.h" +#include "RimMainPlotCollection.h" +#include "RimWellLogPlotCollection.h" #include "cafPdmDocument.h" #include "cafProgressInfo.h" @@ -43,37 +47,39 @@ #include -#include "cafPdmAbstractClassSourceInit.h" - -CAF_PDM_ABSTRACT_SOURCE_INIT(RimEclipseCase, "RimReservoir"); +CAF_PDM_XML_ABSTRACT_SOURCE_INIT(RimEclipseCase, "RimReservoir"); //------------------------------------------------------------------------------------------------ /// //-------------------------------------------------------------------------------------------------- RimEclipseCase::RimEclipseCase() { - - CAF_PDM_InitFieldNoDefault(&reservoirViews, "ReservoirViews", "", "", "", ""); + reservoirViews.uiCapability()->setUiHidden(true); CAF_PDM_InitFieldNoDefault(&m_matrixModelResults, "MatrixModelResults", "", "", "", ""); - m_matrixModelResults.setUiHidden(true); + m_matrixModelResults.uiCapability()->setUiHidden(true); CAF_PDM_InitFieldNoDefault(&m_fractureModelResults, "FractureModelResults", "", "", "", ""); - m_fractureModelResults.setUiHidden(true); + m_fractureModelResults.uiCapability()->setUiHidden(true); CAF_PDM_InitField(&flipXAxis, "FlipXAxis", false, "Flip X Axis", "", "", ""); CAF_PDM_InitField(&flipYAxis, "FlipYAxis", false, "Flip Y Axis", "", "", ""); CAF_PDM_InitFieldNoDefault(&filesContainingFaults, "FilesContainingFaults", "", "", "", ""); - filesContainingFaults.setUiHidden(true); + filesContainingFaults.uiCapability()->setUiHidden(true); // Obsolete field CAF_PDM_InitField(&caseName, "CaseName", QString(), "Obsolete", "", "" ,""); - caseName.setIOWritable(false); - caseName.setUiHidden(true); + caseName.xmlCapability()->setIOWritable(false); + caseName.uiCapability()->setUiHidden(true); m_matrixModelResults = new RimReservoirCellResultsStorage; + m_matrixModelResults.uiCapability()->setUiHidden(true); + m_matrixModelResults.uiCapability()->setUiChildrenHidden(true); + m_fractureModelResults = new RimReservoirCellResultsStorage; + m_fractureModelResults.uiCapability()->setUiHidden(true); + m_fractureModelResults.uiCapability()->setUiChildrenHidden(true); this->setReservoirData( NULL ); } @@ -88,6 +94,19 @@ RimEclipseCase::~RimEclipseCase() delete m_matrixModelResults(); delete m_fractureModelResults(); + RimProject* project = RiaApplication::instance()->project(); + if (project) + { + if (project->mainPlotCollection()) + { + RimWellLogPlotCollection* plotCollection = project->mainPlotCollection()->wellLogPlotCollection(); + if (plotCollection) + { + plotCollection->removeExtractors(this->reservoirData()); + } + } + } + if (this->reservoirData()) { // At this point, we assume that memory should be released @@ -176,9 +195,7 @@ void RimEclipseCase::removeResult(const QString& resultName) rebuildDisplayModel = true; } - std::list< caf::PdmPointer< RimEclipsePropertyFilter > >::iterator it; RimEclipsePropertyFilterCollection* propFilterCollection = reservoirView->propertyFilterCollection(); - for (size_t filter = 0; filter < propFilterCollection->propertyFilters().size(); filter++) { RimEclipsePropertyFilter* propertyFilter = propFilterCollection->propertyFilters()[filter]; @@ -297,15 +314,7 @@ void RimEclipseCase::computeCachedData() //-------------------------------------------------------------------------------------------------- RimCaseCollection* RimEclipseCase::parentCaseCollection() { - std::vector parentObjects; - this->parentObjectsOfType(parentObjects); - - if (parentObjects.size() > 0) - { - return parentObjects[0]; - } - - return NULL; + return dynamic_cast(this->parentField()->ownerObject()); } //-------------------------------------------------------------------------------------------------- @@ -411,3 +420,35 @@ std::vector RimEclipseCase::views() } return views; } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QStringList RimEclipseCase::timeStepStrings() +{ + QStringList stringList; + + std::vector timeStepDates = results(RifReaderInterface::MATRIX_RESULTS)->cellResults()->timeStepDates(0); + + bool showHoursAndMinutes = false; + for (size_t i = 0; i < timeStepDates.size(); i++) + { + if (timeStepDates[i].time().hour() != 0.0 || timeStepDates[i].time().minute() != 0.0) + { + showHoursAndMinutes = true; + } + } + + QString formatString = "dd.MMM yyyy"; + if (showHoursAndMinutes) + { + formatString += " - hh:mm"; + } + + for (size_t i = 0; i < timeStepDates.size(); i++) + { + stringList += timeStepDates[i].toString(formatString); + } + + return stringList; +} diff --git a/ApplicationCode/ProjectDataModel/RimEclipseCase.h b/ApplicationCode/ProjectDataModel/RimEclipseCase.h index e1f42e5ea9..6c1e4d091b 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseCase.h +++ b/ApplicationCode/ProjectDataModel/RimEclipseCase.h @@ -20,18 +20,24 @@ #pragma once -#include "RimCase.h" - #include "cvfBase.h" #include "cvfObject.h" + +#include "RimCase.h" +#include "RimEclipseView.h" + + +#include "cafPdmChildArrayField.h" +#include "cafPdmChildField.h" #include "cafPdmField.h" #include "cafPdmObject.h" + #include "RifReaderInterface.h" + class QString; class RigCaseData; class RigGridBase; -class RimEclipseView; class RimCaseCollection; class RimIdenticalGridCaseGroup; class RimReservoirCellResultsStorage; @@ -52,7 +58,7 @@ class RimEclipseCase : public RimCase // Fields: caf::PdmField releaseResultMemory; - caf::PdmPointersField reservoirViews; + caf::PdmChildArrayField reservoirViews; caf::PdmField flipXAxis; caf::PdmField flipYAxis; @@ -65,7 +71,7 @@ class RimEclipseCase : public RimCase RigCaseData* reservoirData(); const RigCaseData* reservoirData() const; - RimReservoirCellResultsStorage* results(RifReaderInterface::PorosityModelResultType porosityModel); + RimReservoirCellResultsStorage* results(RifReaderInterface::PorosityModelResultType porosityModel); RimEclipseView* createAndAddReservoirView(); @@ -79,7 +85,8 @@ class RimEclipseCase : public RimCase RimIdenticalGridCaseGroup* parentGridCaseGroup(); virtual std::vector views(); - + virtual QStringList timeStepStrings(); + // Overridden methods from PdmObject public: @@ -97,8 +104,8 @@ class RimEclipseCase : public RimCase cvf::ref m_rigEclipseCase; private: - caf::PdmField m_matrixModelResults; - caf::PdmField m_fractureModelResults; + caf::PdmChildField m_matrixModelResults; + caf::PdmChildField m_fractureModelResults; // Obsolete fields protected: diff --git a/ApplicationCode/ProjectDataModel/RimEclipseCaseCollection.cpp b/ApplicationCode/ProjectDataModel/RimEclipseCaseCollection.cpp index faefd53074..d4a36f89d2 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseCaseCollection.cpp +++ b/ApplicationCode/ProjectDataModel/RimEclipseCaseCollection.cpp @@ -39,7 +39,10 @@ RimEclipseCaseCollection::RimEclipseCaseCollection(void) CAF_PDM_InitObject("Grid Models", ":/Cases16x16.png", "", ""); CAF_PDM_InitFieldNoDefault(&cases, "Reservoirs", "", "", "", ""); + cases.uiCapability()->setUiHidden(true); + CAF_PDM_InitFieldNoDefault(&caseGroups, "CaseGroups", "", "", "", ""); + caseGroups.uiCapability()->setUiHidden(true); m_gridCollection = new RigGridManager; } diff --git a/ApplicationCode/ProjectDataModel/RimEclipseCaseCollection.h b/ApplicationCode/ProjectDataModel/RimEclipseCaseCollection.h index 6e8f6e666e..7ec132f3ae 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseCaseCollection.h +++ b/ApplicationCode/ProjectDataModel/RimEclipseCaseCollection.h @@ -20,17 +20,18 @@ #pragma once +#include "cafPdmChildArrayField.h" #include "cafPdmField.h" #include "cafPdmObject.h" #include "cafPdmPointer.h" #include "cvfObject.h" -class RimEclipseCase; +class RigCaseData; class RigGridManager; -class RimIdenticalGridCaseGroup; class RigMainGrid; -class RigCaseData; +class RimEclipseCase; +class RimIdenticalGridCaseGroup; class RimWellPathCollection; //================================================================================================== @@ -45,8 +46,8 @@ class RimEclipseCaseCollection : public caf::PdmObject RimEclipseCaseCollection(void); virtual ~RimEclipseCaseCollection(void); - caf::PdmPointersField cases; - caf::PdmPointersField caseGroups; + caf::PdmChildArrayField cases; + caf::PdmChildArrayField caseGroups; void close(); diff --git a/ApplicationCode/ProjectDataModel/RimEclipseCellColors.cpp b/ApplicationCode/ProjectDataModel/RimEclipseCellColors.cpp index 37b4226d90..09afb218d6 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseCellColors.cpp +++ b/ApplicationCode/ProjectDataModel/RimEclipseCellColors.cpp @@ -20,9 +20,12 @@ #include "RimEclipseCellColors.h" +#include "RimEclipseFaultColors.h" #include "RimEclipseView.h" #include "RimTernaryLegendConfig.h" -#include "RimUiTreeModelPdm.h" +#include "RimViewController.h" +#include "RimViewLinker.h" + #include "RiuMainWindow.h" CAF_PDM_SOURCE_INIT(RimEclipseCellColors, "ResultSlot"); @@ -32,21 +35,28 @@ CAF_PDM_SOURCE_INIT(RimEclipseCellColors, "ResultSlot"); //-------------------------------------------------------------------------------------------------- RimEclipseCellColors::RimEclipseCellColors() { - CAF_PDM_InitObject("Result Slot", "", "", ""); + CAF_PDM_InitObject("Cell Result", ":/CellResult.png", "", ""); - CAF_PDM_InitFieldNoDefault(&legendConfig, "LegendDefinition", "Legend Definition", "", "", ""); - this->legendConfig = new RimLegendConfig(); - this->legendConfig.setUiHidden(true); - this->legendConfig.setUiChildrenHidden(true); + CAF_PDM_InitFieldNoDefault(&obsoleteField_legendConfig, "LegendDefinition", "Legend Definition", "", "", ""); + this->obsoleteField_legendConfig.uiCapability()->setUiHidden(true); + this->obsoleteField_legendConfig.uiCapability()->setUiChildrenHidden(true); + this->obsoleteField_legendConfig.xmlCapability()->setIOWritable(false); CAF_PDM_InitFieldNoDefault(&m_legendConfigData, "ResultVarLegendDefinitionList", "", "", "", ""); - m_legendConfigData.setUiHidden(true); - m_legendConfigData.setUiChildrenHidden(true); + m_legendConfigData.uiCapability()->setUiHidden(true); + m_legendConfigData.uiCapability()->setUiChildrenHidden(true); CAF_PDM_InitFieldNoDefault(&ternaryLegendConfig, "TernaryLegendDefinition", "Ternary Legend Definition", "", "", ""); this->ternaryLegendConfig = new RimTernaryLegendConfig(); - this->ternaryLegendConfig.setUiHidden(true); - this->ternaryLegendConfig.setUiChildrenHidden(true); + this->ternaryLegendConfig.uiCapability()->setUiHidden(true); + this->ternaryLegendConfig.uiCapability()->setUiChildrenHidden(true); + + CAF_PDM_InitFieldNoDefault(&m_legendConfigPtrField, "LegendDefinitionPtrField", "Legend Definition PtrField", "", "", ""); + this->m_legendConfigPtrField.uiCapability()->setUiHidden(true); + this->m_legendConfigPtrField.uiCapability()->setUiChildrenHidden(true); + + // Make sure we have a created legend for the default/undefined result variable + changeLegendConfig(this->resultVariable()); } //-------------------------------------------------------------------------------------------------- @@ -54,7 +64,10 @@ RimEclipseCellColors::RimEclipseCellColors() //-------------------------------------------------------------------------------------------------- RimEclipseCellColors::~RimEclipseCellColors() { - delete legendConfig(); + CVF_ASSERT(obsoleteField_legendConfig() == NULL); + + m_legendConfigData.deleteAllChildObjects(); + delete ternaryLegendConfig(); } @@ -65,7 +78,7 @@ void RimEclipseCellColors::fieldChangedByUi(const caf::PdmFieldHandle* changedFi { RimEclipseResultDefinition::fieldChangedByUi(changedField, oldValue, newValue); - // Update of legend config must happen after RimResultDefinition::fieldChangedByUi(), as this function modifies this->resultVariable() + // Update of legend config must happen after RimEclipseResultDefinition::fieldChangedByUi(), as this function modifies this->resultVariable() if (changedField == &m_resultVariableUiField) { if (oldValue != newValue) @@ -78,7 +91,11 @@ void RimEclipseCellColors::fieldChangedByUi(const caf::PdmFieldHandle* changedFi if (m_reservoirView) m_reservoirView->hasUserRequestedAnimation = true; } - RiuMainWindow::instance()->uiPdmModel()->updateUiSubTree(this); + RimEclipseFaultColors* faultColors = dynamic_cast(this->parentField()->ownerObject()); + if (faultColors) + { + faultColors->updateConnectedEditors(); + } } if (m_reservoirView) m_reservoirView->createDisplayModelAndRedraw(); @@ -91,29 +108,29 @@ void RimEclipseCellColors::changeLegendConfig(QString resultVarNameOfNewLegend) { if (resultVarNameOfNewLegend == RimDefines::ternarySaturationResultName()) { - this->ternaryLegendConfig.setUiHidden(false); - this->ternaryLegendConfig.setUiChildrenHidden(false); - this->legendConfig.setUiHidden(true); - this->legendConfig.setUiChildrenHidden(true); + this->ternaryLegendConfig.uiCapability()->setUiChildrenHidden(false); + this->m_legendConfigPtrField.uiCapability()->setUiChildrenHidden(true); } else { - this->ternaryLegendConfig.setUiHidden(true); - this->ternaryLegendConfig.setUiChildrenHidden(true); + this->ternaryLegendConfig.uiCapability()->setUiChildrenHidden(true); + + bool found = false; + + QString legendResultVariable; + + if (this->m_legendConfigPtrField()) + { + legendResultVariable = this->m_legendConfigPtrField()->resultVariableName(); + } - if (this->legendConfig()->resultVariableName() != resultVarNameOfNewLegend) + if (!this->m_legendConfigPtrField() || legendResultVariable != resultVarNameOfNewLegend) { - std::list >::iterator it; - bool found = false; - for (it = m_legendConfigData.v().begin(); it != m_legendConfigData.v().end(); ++it) + for (size_t i = 0; i < m_legendConfigData.size(); i++) { - if ((*it)->resultVariableName() == resultVarNameOfNewLegend) + if (m_legendConfigData[i]->resultVariableName() == resultVarNameOfNewLegend) { - RimLegendConfig* newLegend = *it; - - m_legendConfigData.v().erase(it); - m_legendConfigData.v().push_back(this->legendConfig()); - this->legendConfig = newLegend; + this->m_legendConfigPtrField = m_legendConfigData[i]; found = true; break; } @@ -122,18 +139,17 @@ void RimEclipseCellColors::changeLegendConfig(QString resultVarNameOfNewLegend) // Not found ? if (!found) { - RimLegendConfig* newLegend = new RimLegendConfig; - newLegend->setReservoirView(m_reservoirView); - newLegend->resultVariableName = resultVarNameOfNewLegend; - m_legendConfigData.v().push_back(this->legendConfig()); - this->legendConfig = newLegend; + RimLegendConfig* newLegend = new RimLegendConfig; + newLegend->setReservoirView(m_reservoirView); + newLegend->resultVariableName = resultVarNameOfNewLegend; + m_legendConfigData.push_back(newLegend); + + this->m_legendConfigPtrField = newLegend; } } - - this->legendConfig.setUiHidden(false); - this->legendConfig.setUiChildrenHidden(false); - } + this->m_legendConfigPtrField.uiCapability()->setUiChildrenHidden(false); + } } //-------------------------------------------------------------------------------------------------- @@ -143,12 +159,26 @@ void RimEclipseCellColors::initAfterRead() { RimEclipseResultDefinition::initAfterRead(); - if (this->legendConfig()->resultVariableName == "") + if (this->m_legendConfigPtrField() && this->m_legendConfigPtrField()->resultVariableName == "") + { + this->m_legendConfigPtrField()->resultVariableName = this->resultVariable(); + } + + if (obsoleteField_legendConfig) { - this->legendConfig()->resultVariableName = this->resultVariable(); + // The current legend config is NOT stored in in ResInsight up to v 1.3.7-dev + RimLegendConfig* obsoleteLegend = obsoleteField_legendConfig(); + + // set to NULL before pushing into container + obsoleteField_legendConfig = NULL; + + m_legendConfigData.push_back(obsoleteLegend); + m_legendConfigPtrField = obsoleteLegend; } changeLegendConfig(this->resultVariable()); + + updateIconState(); } //-------------------------------------------------------------------------------------------------- @@ -156,18 +186,25 @@ void RimEclipseCellColors::initAfterRead() //-------------------------------------------------------------------------------------------------- void RimEclipseCellColors::setReservoirView(RimEclipseView* ownerReservoirView) { - RimEclipseResultDefinition::setReservoirView(ownerReservoirView); + this->setEclipseCase(ownerReservoirView->eclipseCase()); m_reservoirView = ownerReservoirView; - this->legendConfig()->setReservoirView(ownerReservoirView); - std::list >::iterator it; - for (it = m_legendConfigData.v().begin(); it != m_legendConfigData.v().end(); ++it) + + for (size_t i = 0; i < m_legendConfigData.size(); i++) { - (*it)->setReservoirView(ownerReservoirView); + m_legendConfigData[i]->setReservoirView(ownerReservoirView); } this->ternaryLegendConfig()->setReservoirView(ownerReservoirView); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimEclipseView* RimEclipseCellColors::reservoirView() +{ + return m_reservoirView; +} + //-------------------------------------------------------------------------------------------------- /// @@ -179,3 +216,29 @@ void RimEclipseCellColors::setResultVariable(const QString& val) this->changeLegendConfig(val); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimLegendConfig* RimEclipseCellColors::legendConfig() +{ + return m_legendConfigPtrField; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEclipseCellColors::updateIconState() +{ + RimViewController* viewController = m_reservoirView->viewController(); + if (viewController && viewController->isResultColorControlled()) + { + updateUiIconFromState(false); + } + else + { + updateUiIconFromState(true); + } + + uiCapability()->updateConnectedEditors(); +} + diff --git a/ApplicationCode/ProjectDataModel/RimEclipseCellColors.h b/ApplicationCode/ProjectDataModel/RimEclipseCellColors.h index 128afd39b8..e51e44d7d7 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseCellColors.h +++ b/ApplicationCode/ProjectDataModel/RimEclipseCellColors.h @@ -24,34 +24,49 @@ #include "RimLegendConfig.h" #include "RimEclipseResultDefinition.h" +#include "cafPdmChildArrayField.h" +#include "cafPdmChildField.h" +#include "cafPdmPtrField.h" + class RimTernaryLegendConfig; //================================================================================================== /// /// //================================================================================================== -class RimEclipseCellColors : public RimEclipseResultDefinition +class RimEclipseCellColors : public RimEclipseResultDefinition { CAF_PDM_HEADER_INIT; public: RimEclipseCellColors(); virtual ~RimEclipseCellColors(); - virtual void setReservoirView(RimEclipseView* ownerReservoirView); - caf::PdmField legendConfig; - caf::PdmField ternaryLegendConfig; + void setReservoirView(RimEclipseView* ownerReservoirView); + RimEclipseView* reservoirView(); - // Overridden methods - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue); - virtual void setResultVariable(const QString& resultName); + RimLegendConfig* legendConfig(); + caf::PdmChildField ternaryLegendConfig; + + virtual void setResultVariable(const QString& resultName); + + void updateIconState(); protected: + // Overridden methods + virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue); + friend class RimEclipseFaultColors; - virtual void initAfterRead(); + virtual void initAfterRead(); private: - void changeLegendConfig(QString resultVarNameOfNewLegend); + void changeLegendConfig(QString resultVarNameOfNewLegend); + + caf::PdmChildArrayField m_legendConfigData; + caf::PdmPtrField m_legendConfigPtrField; + + caf::PdmPointer m_reservoirView; - caf::PdmField > > m_legendConfigData; + // Obsolete + caf::PdmChildField obsoleteField_legendConfig; }; diff --git a/ApplicationCode/ProjectDataModel/RimEclipseFaultColors.cpp b/ApplicationCode/ProjectDataModel/RimEclipseFaultColors.cpp index 824f468ab0..d72b46d636 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseFaultColors.cpp +++ b/ApplicationCode/ProjectDataModel/RimEclipseFaultColors.cpp @@ -25,9 +25,10 @@ #include "RimEclipseCase.h" #include "RimEclipseView.h" #include "RimEclipseCellColors.h" -#include "RimUiTreeModelPdm.h" #include "RiuMainWindow.h" +#include "cafPdmUiTreeOrdering.h" + CAF_PDM_SOURCE_INIT(RimEclipseFaultColors, "RimFaultResultSlot"); @@ -37,21 +38,15 @@ CAF_PDM_SOURCE_INIT(RimEclipseFaultColors, "RimFaultResultSlot"); //-------------------------------------------------------------------------------------------------- RimEclipseFaultColors::RimEclipseFaultColors() { - CAF_PDM_InitObject("Fault Result Slot", ":/draw_style_faults_24x24.png", "", ""); + CAF_PDM_InitObject("Separate Fault Result", ":/draw_style_faults_24x24.png", "", ""); CAF_PDM_InitField(&showCustomFaultResult, "ShowCustomFaultResult", false, "Show Custom Fault Result", "", "", ""); - showCustomFaultResult.setUiHidden(true); + showCustomFaultResult.uiCapability()->setUiHidden(true); CAF_PDM_InitFieldNoDefault(&m_customFaultResultColors, "CustomResultSlot", "Custom Fault Result", ":/CellResult.png", "", ""); m_customFaultResultColors = new RimEclipseCellColors(); - m_customFaultResultColors.setOwnerObject(this); - m_customFaultResultColors.setUiHidden(true); - - // Take ownership of the fields in RimResultDefinition to be able to trap fieldChangedByUi in this class - m_customFaultResultColors->m_resultTypeUiField.setOwnerObject(this); - m_customFaultResultColors->m_porosityModelUiField.setOwnerObject(this); - m_customFaultResultColors->m_resultVariableUiField.setOwnerObject(this); + m_customFaultResultColors.uiCapability()->setUiHidden(true); updateFieldVisibility(); } @@ -79,13 +74,6 @@ void RimEclipseFaultColors::fieldChangedByUi(const caf::PdmFieldHandle* changedF { this->updateUiIconFromToggleField(); - m_customFaultResultColors->fieldChangedByUi(changedField, oldValue, newValue); - - if (changedField == &m_customFaultResultColors->m_resultVariableUiField) - { - RiuMainWindow::instance()->uiPdmModel()->updateUiSubTree(this); - } - if (m_reservoirView) m_reservoirView->scheduleCreateDisplayModelAndRedraw(); } @@ -158,3 +146,16 @@ bool RimEclipseFaultColors::hasValidCustomResult() return false; } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEclipseFaultColors::defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName /*= ""*/) +{ + if (m_customFaultResultColors()->legendConfig()) + { + uiTreeOrdering.add(m_customFaultResultColors()->legendConfig()); + } + + uiTreeOrdering.setForgetRemainingFields(true); +} diff --git a/ApplicationCode/ProjectDataModel/RimEclipseFaultColors.h b/ApplicationCode/ProjectDataModel/RimEclipseFaultColors.h index 14826cb2ed..96e0c411f0 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseFaultColors.h +++ b/ApplicationCode/ProjectDataModel/RimEclipseFaultColors.h @@ -20,6 +20,7 @@ #pragma once #include "cafAppEnum.h" +#include "cafPdmChildField.h" #include "cafPdmField.h" #include "cafPdmObject.h" @@ -54,9 +55,10 @@ class RimEclipseFaultColors : public caf::PdmObject virtual caf::PdmFieldHandle* objectToggleField(); virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue); virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) ; + virtual void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = ""); private: - caf::PdmField m_customFaultResultColors; + caf::PdmChildField m_customFaultResultColors; caf::PdmPointer m_reservoirView; }; diff --git a/ApplicationCode/ProjectDataModel/RimEclipseInputCase.cpp b/ApplicationCode/ProjectDataModel/RimEclipseInputCase.cpp index d08c8b92ae..3994ceecf7 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseInputCase.cpp +++ b/ApplicationCode/ProjectDataModel/RimEclipseInputCase.cpp @@ -46,12 +46,13 @@ RimEclipseInputCase::RimEclipseInputCase() { CAF_PDM_InitObject("RimInputCase", ":/EclipseInput48x48.png", "", ""); CAF_PDM_InitField(&m_gridFileName, "GridFileName", QString(), "Case grid filename", "", "" ,""); - m_gridFileName.setUiReadOnly(true); + m_gridFileName.uiCapability()->setUiReadOnly(true); CAF_PDM_InitFieldNoDefault(&m_additionalFileNames, "AdditionalFileNames", "Additional files", "", "" ,""); - m_additionalFileNames.setUiReadOnly(true); + m_additionalFileNames.uiCapability()->setUiReadOnly(true); CAF_PDM_InitFieldNoDefault(&m_inputPropertyCollection, "InputPropertyCollection", "", "", "", ""); m_inputPropertyCollection = new RimEclipseInputPropertyCollection; + m_inputPropertyCollection->parentField()->uiCapability()->setUiHidden(true); } @@ -299,9 +300,6 @@ void RimEclipseInputCase::loadAndSyncronizeInputProperties() if (!fileKeywordSet.empty()) { - - - std::vector knownKwsLeft; for_all(knownKeywords, fkIt) { if (fileKeywordSet.count(knownKeywords[fkIt])) @@ -381,14 +379,14 @@ cvf::ref RimEclipseInputCase::createMockModel(QString modelN mockFileInterface->open("", reservoir.p()); { - size_t idx = reservoir->mainGrid()->cellIndexFromIJK(1, 3, 4); + //size_t idx = reservoir->mainGrid()->cellIndexFromIJK(1, 3, 4); //TODO: Rewrite active cell info in mock models //reservoir->mainGrid()->cell(idx).setActiveIndexInMatrixModel(cvf::UNDEFINED_SIZE_T); } { - size_t idx = reservoir->mainGrid()->cellIndexFromIJK(2, 2, 3); + //size_t idx = reservoir->mainGrid()->cellIndexFromIJK(2, 2, 3); //TODO: Rewrite active cell info in mock models //reservoir->mainGrid()->cell(idx).setActiveIndexInMatrixModel(cvf::UNDEFINED_SIZE_T); diff --git a/ApplicationCode/ProjectDataModel/RimEclipseInputCase.h b/ApplicationCode/ProjectDataModel/RimEclipseInputCase.h index d9be00a185..70346a5994 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseInputCase.h +++ b/ApplicationCode/ProjectDataModel/RimEclipseInputCase.h @@ -18,16 +18,18 @@ #pragma once -#include "cvfBase.h" -#include "cvfObject.h" +#include "RimEclipseCase.h" + +#include "cafPdmChildField.h" #include "cafPdmField.h" #include "cafPdmObject.h" -#include "RimEclipseCase.h" +#include "cvfBase.h" +#include "cvfObject.h" class RifReaderInterface; -class RimEclipseInputPropertyCollection; class RimEclipseInputProperty; +class RimEclipseInputPropertyCollection; //================================================================================================== // @@ -43,7 +45,7 @@ class RimEclipseInputCase : public RimEclipseCase virtual ~RimEclipseInputCase(); // Fields - caf::PdmField m_inputPropertyCollection; + caf::PdmChildField m_inputPropertyCollection; // File open methods void openDataFileSet(const QStringList& fileNames); diff --git a/ApplicationCode/ProjectDataModel/RimEclipseInputProperty.cpp b/ApplicationCode/ProjectDataModel/RimEclipseInputProperty.cpp index 11fcb0e71e..14c0c07807 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseInputProperty.cpp +++ b/ApplicationCode/ProjectDataModel/RimEclipseInputProperty.cpp @@ -53,12 +53,12 @@ RimEclipseInputProperty::RimEclipseInputProperty() CAF_PDM_InitField(&fileName, "FileName", QString(), "Filename", "", "" ,""); CAF_PDM_InitField(&resolvedState, "ResolvedState", (ResolveStateEnum)UNKNOWN, "Data state", "", "", ""); - resolvedState.setUiReadOnly(true); - resolvedState.setIOReadable(false); - resolvedState.setIOWritable(false); - resolvedState.setUiEditorTypeName(caf::PdmUiLineEditor::uiEditorTypeName()); + resolvedState.uiCapability()->setUiReadOnly(true); + resolvedState.xmlCapability()->setIOReadable(false); + resolvedState.xmlCapability()->setIOWritable(false); + resolvedState.uiCapability()->setUiEditorTypeName(caf::PdmUiLineEditor::uiEditorTypeName()); - fileName.setUiReadOnly(true); + fileName.uiCapability()->setUiReadOnly(true); } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/RimEclipseInputPropertyCollection.cpp b/ApplicationCode/ProjectDataModel/RimEclipseInputPropertyCollection.cpp index 5be7a25714..7bd75d92ef 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseInputPropertyCollection.cpp +++ b/ApplicationCode/ProjectDataModel/RimEclipseInputPropertyCollection.cpp @@ -34,6 +34,7 @@ RimEclipseInputPropertyCollection::RimEclipseInputPropertyCollection() CAF_PDM_InitObject("Input Properties", ":/EclipseInput48x48.png", "", ""); CAF_PDM_InitFieldNoDefault(&inputProperties, "InputProperties", "", "", "", ""); + inputProperties.uiCapability()->setUiHidden(true); } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/RimEclipseInputPropertyCollection.h b/ApplicationCode/ProjectDataModel/RimEclipseInputPropertyCollection.h index f4467b962f..a9e46a1948 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseInputPropertyCollection.h +++ b/ApplicationCode/ProjectDataModel/RimEclipseInputPropertyCollection.h @@ -20,11 +20,13 @@ #pragma once -#include "cvfBase.h" -#include "cvfObject.h" +#include "cafPdmChildArrayField.h" #include "cafPdmField.h" #include "cafPdmObject.h" +#include "cvfBase.h" +#include "cvfObject.h" + class RimEclipseInputProperty; @@ -47,6 +49,6 @@ class RimEclipseInputPropertyCollection : public caf::PdmObject // Fields: - caf::PdmPointersField inputProperties; + caf::PdmChildArrayField inputProperties; }; diff --git a/ApplicationCode/ProjectDataModel/RimEclipsePropertyFilter.cpp b/ApplicationCode/ProjectDataModel/RimEclipsePropertyFilter.cpp index 68b929a572..d931a141e4 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipsePropertyFilter.cpp +++ b/ApplicationCode/ProjectDataModel/RimEclipsePropertyFilter.cpp @@ -21,14 +21,19 @@ #include "RimEclipsePropertyFilter.h" #include "RigCaseCellResultsData.h" + #include "RimEclipsePropertyFilterCollection.h" -#include "RimReservoirCellResultsStorage.h" #include "RimEclipseResultDefinition.h" +#include "RimEclipseView.h" +#include "RimReservoirCellResultsStorage.h" +#include "RimViewController.h" + +#include "RiuMainWindow.h" #include "cafPdmUiDoubleSliderEditor.h" + #include "cvfAssert.h" #include "cvfMath.h" -#include "RiuMainWindow.h" namespace caf @@ -49,34 +54,26 @@ CAF_PDM_SOURCE_INIT(RimEclipsePropertyFilter, "CellPropertyFilter"); /// //-------------------------------------------------------------------------------------------------- RimEclipsePropertyFilter::RimEclipsePropertyFilter() - : m_parentContainer(NULL) { CAF_PDM_InitObject("Cell Property Filter", ":/CellFilter_Values.png", "", ""); CAF_PDM_InitFieldNoDefault(&obsoleteField_evaluationRegion, "EvaluationRegion", "Evaluation region", "", "", ""); - obsoleteField_evaluationRegion.setUiHidden(true); - obsoleteField_evaluationRegion.setIOWritable(false); + obsoleteField_evaluationRegion.uiCapability()->setUiHidden(true); + obsoleteField_evaluationRegion.xmlCapability()->setIOWritable(false); CAF_PDM_InitFieldNoDefault(&resultDefinition, "ResultDefinition", "Result definition", "", "", ""); resultDefinition = new RimEclipseResultDefinition(); - - // Take ownership of the fields in RimResultDefinition to be able to trap fieldChangedByUi in this class - resultDefinition->m_resultTypeUiField.setOwnerObject(this); - resultDefinition->m_resultTypeUiField.setUiName(""); - resultDefinition->m_porosityModelUiField.setOwnerObject(this); - resultDefinition->m_porosityModelUiField.setUiName(""); - resultDefinition->m_resultVariableUiField.setOwnerObject(this); - resultDefinition->m_resultVariableUiField.setUiName(""); // Set to hidden to avoid this item to been displayed as a child item // Fields in this object are displayed using defineUiOrdering() - resultDefinition.setUiHidden(true); + resultDefinition.uiCapability()->setUiHidden(true); + resultDefinition.uiCapability()->setUiChildrenHidden(true); CAF_PDM_InitField(&lowerBound, "LowerBound", 0.0, "Min", "", "", ""); - lowerBound.setUiEditorTypeName(caf::PdmUiDoubleSliderEditor::uiEditorTypeName()); + lowerBound.uiCapability()->setUiEditorTypeName(caf::PdmUiDoubleSliderEditor::uiEditorTypeName()); CAF_PDM_InitField(&upperBound, "UpperBound", 0.0, "Max", "", "", ""); - upperBound.setUiEditorTypeName(caf::PdmUiDoubleSliderEditor::uiEditorTypeName()); + upperBound.uiCapability()->setUiEditorTypeName(caf::PdmUiDoubleSliderEditor::uiEditorTypeName()); updateIconState(); @@ -100,67 +97,18 @@ void RimEclipsePropertyFilter::fieldChangedByUi(const caf::PdmFieldHandle* chang { } - if ( &(resultDefinition->m_resultTypeUiField) == changedField - || &(resultDefinition->m_porosityModelUiField) == changedField) - { - resultDefinition->fieldChangedByUi(changedField, oldValue, newValue); - } - - if ( &(resultDefinition->m_resultVariableUiField) == changedField ) - { - resultDefinition->fieldChangedByUi(changedField, oldValue, newValue); - setToDefaultValues(); - m_parentContainer->fieldChangedByUi(changedField, oldValue, newValue); - updateFilterName(); - } - if ( &lowerBound == changedField || &upperBound == changedField || &obsoleteField_evaluationRegion == changedField || &isActive == changedField || &filterMode == changedField) { - m_parentContainer->fieldChangedByUi(changedField, oldValue, newValue); updateFilterName(); this->updateIconState(); - } -} + this->uiCapability()->updateConnectedEditors(); -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -QList RimEclipsePropertyFilter::calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly) -{ - QList optionItems = resultDefinition->calculateValueOptions(fieldNeedingOptions, useOptionsOnly); - - std::vector indicesToRemove; - for (int i = 0; i < optionItems.size(); i++) - { - QString text = optionItems[i].optionUiText; - - if (RimDefines::isPerCellFaceResult(text)) - { - indicesToRemove.push_back(i); - } + parentContainer()->updateDisplayModelNotifyManagedViews(); } - - std::sort(indicesToRemove.begin(), indicesToRemove.end()); - - std::vector::reverse_iterator rit; - for (rit = indicesToRemove.rbegin(); rit != indicesToRemove.rend(); ++rit) - { - optionItems.takeAt(*rit); - } - - return optionItems; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimEclipsePropertyFilter::setParentContainer(RimEclipsePropertyFilterCollection* parentContainer) -{ - m_parentContainer = parentContainer; } //-------------------------------------------------------------------------------------------------- @@ -168,7 +116,7 @@ void RimEclipsePropertyFilter::setParentContainer(RimEclipsePropertyFilterCollec //-------------------------------------------------------------------------------------------------- RimEclipsePropertyFilterCollection* RimEclipsePropertyFilter::parentContainer() { - return m_parentContainer; + return dynamic_cast(this->parentField()->ownerObject()); } //-------------------------------------------------------------------------------------------------- @@ -176,7 +124,7 @@ RimEclipsePropertyFilterCollection* RimEclipsePropertyFilter::parentContainer() //-------------------------------------------------------------------------------------------------- void RimEclipsePropertyFilter::setToDefaultValues() { - CVF_ASSERT(m_parentContainer); + CVF_ASSERT(parentContainer()); computeResultValueRange(); @@ -206,6 +154,66 @@ void RimEclipsePropertyFilter::defineUiOrdering(QString uiConfigName, caf::PdmUi uiOrdering.add(&lowerBound); uiOrdering.add(&upperBound); uiOrdering.add(&filterMode); + + updateReadOnlyStateOfAllFields(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEclipsePropertyFilter::defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName) +{ + PdmObject::defineUiTreeOrdering(uiTreeOrdering, uiConfigName); + + updateActiveState(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEclipsePropertyFilter::updateReadOnlyStateOfAllFields() +{ + bool readOnlyState = isPropertyFilterControlled(); + + std::vector objFields; + this->fields(objFields); + + // Include fields declared in RimResultDefinition + objFields.push_back(&(resultDefinition->m_resultTypeUiField)); + objFields.push_back(&(resultDefinition->m_porosityModelUiField)); + objFields.push_back(&(resultDefinition->m_resultVariableUiField)); + + for (size_t i = 0; i < objFields.size(); i++) + { + objFields[i]->uiCapability()->setUiReadOnly(readOnlyState); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimEclipsePropertyFilter::isPropertyFilterControlled() +{ + RimView* rimView = NULL; + firstAnchestorOrThisOfType(rimView); + CVF_ASSERT(rimView); + + bool isPropertyFilterControlled = false; + RimViewController* vc = rimView->viewController(); + if (vc && vc->isPropertyFilterOveridden()) + { + isPropertyFilterControlled = true; + } + + return isPropertyFilterControlled; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEclipsePropertyFilter::updateActiveState() +{ + isActive.uiCapability()->setUiReadOnly(isPropertyFilterControlled()); } //-------------------------------------------------------------------------------------------------- @@ -236,7 +244,7 @@ void RimEclipsePropertyFilter::defineEditorAttribute(const caf::PdmFieldHandle* //-------------------------------------------------------------------------------------------------- void RimEclipsePropertyFilter::computeResultValueRange() { - CVF_ASSERT(m_parentContainer); + CVF_ASSERT(parentContainer()); double min = 0.0; double max = 0.0; @@ -254,8 +262,8 @@ void RimEclipsePropertyFilter::computeResultValueRange() m_maximumResultValue = max; m_minimumResultValue = min; - lowerBound.setUiName(QString("Min (%1)").arg(min)); - upperBound.setUiName(QString("Max (%1)").arg(max)); + lowerBound.uiCapability()->setUiName(QString("Min (%1)").arg(min)); + upperBound.uiCapability()->setUiName(QString("Max (%1)").arg(max)); } //-------------------------------------------------------------------------------------------------- @@ -267,6 +275,20 @@ void RimEclipsePropertyFilter::updateFilterName() newFiltername = resultDefinition->resultVariable() + " (" + QString::number(lowerBound()) + " .. " + QString::number(upperBound) + ")"; this->name = newFiltername; - RiuMainWindow::instance()->forceProjectTreeRepaint(); + + uiCapability()->updateConnectedEditors(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEclipsePropertyFilter::initAfterRead() +{ + resultDefinition->initAfterRead(); + + resultDefinition->setEclipseCase(parentContainer()->reservoirView()->eclipseCase()); + resultDefinition->loadResult(); + updateIconState(); + computeResultValueRange(); } diff --git a/ApplicationCode/ProjectDataModel/RimEclipsePropertyFilter.h b/ApplicationCode/ProjectDataModel/RimEclipsePropertyFilter.h index 1398d03807..b4e45f6cde 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipsePropertyFilter.h +++ b/ApplicationCode/ProjectDataModel/RimEclipsePropertyFilter.h @@ -22,6 +22,8 @@ #include "RimCellFilter.h" +#include "cafPdmChildField.h" + class RimEclipseView; class RimEclipsePropertyFilterCollection; class RimEclipseResultDefinition; @@ -42,26 +44,32 @@ class RimEclipsePropertyFilter : public RimCellFilter RimEclipsePropertyFilter(); virtual ~RimEclipsePropertyFilter(); - caf::PdmField resultDefinition; + caf::PdmChildField resultDefinition; caf::PdmField lowerBound; caf::PdmField upperBound; - void setParentContainer(RimEclipsePropertyFilterCollection* parentContainer); - RimEclipsePropertyFilterCollection* parentContainer(); + RimEclipsePropertyFilterCollection* parentContainer(); void setToDefaultValues(); void updateFilterName(); void computeResultValueRange(); virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue); + virtual void initAfterRead(); + + void updateActiveState(); + protected: - virtual QList calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly ); - virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) ; + virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering); + virtual void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName); + virtual void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute); private: + void updateReadOnlyStateOfAllFields(); + bool isPropertyFilterControlled(); - RimEclipsePropertyFilterCollection* m_parentContainer; +private: double m_minimumResultValue; double m_maximumResultValue; diff --git a/ApplicationCode/ProjectDataModel/RimEclipsePropertyFilterCollection.cpp b/ApplicationCode/ProjectDataModel/RimEclipsePropertyFilterCollection.cpp index 48d7f8423e..a25d0c0f1b 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipsePropertyFilterCollection.cpp +++ b/ApplicationCode/ProjectDataModel/RimEclipsePropertyFilterCollection.cpp @@ -20,9 +20,13 @@ #include "RimEclipsePropertyFilterCollection.h" -#include "RimEclipseView.h" -#include "RimEclipseResultDefinition.h" #include "RimEclipseCellColors.h" +#include "RimEclipseResultDefinition.h" +#include "RimEclipseView.h" +#include "RimViewController.h" +#include "RimViewLinker.h" + +#include "cafPdmUiEditorHandle.h" CAF_PDM_SOURCE_INIT(RimEclipsePropertyFilterCollection, "CellPropertyFilters"); @@ -32,35 +36,21 @@ CAF_PDM_SOURCE_INIT(RimEclipsePropertyFilterCollection, "CellPropertyFilters"); //-------------------------------------------------------------------------------------------------- RimEclipsePropertyFilterCollection::RimEclipsePropertyFilterCollection() { - CAF_PDM_InitObject("Cell Property Filters", ":/CellFilter_Values.png", "", ""); + CAF_PDM_InitObject("Property Filters", ":/CellFilter_Values.png", "", ""); CAF_PDM_InitFieldNoDefault(&propertyFilters, "PropertyFilters", "Property Filters", "", "", ""); - CAF_PDM_InitField(&active, "Active", true, "Active", "", "", ""); - active.setUiHidden(true); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RimEclipsePropertyFilterCollection::~RimEclipsePropertyFilterCollection() -{ + propertyFilters.uiCapability()->setUiHidden(true); + CAF_PDM_InitField(&isActive, "Active", true, "Active", "", "", ""); + isActive.uiCapability()->setUiHidden(true); } - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimEclipsePropertyFilterCollection::setReservoirView(RimEclipseView* reservoirView) +RimEclipsePropertyFilterCollection::~RimEclipsePropertyFilterCollection() { - m_reservoirView = reservoirView; - - for (size_t i = 0; i < propertyFilters.size(); i++) - { - RimEclipsePropertyFilter* propertyFilter = propertyFilters[i]; - propertyFilter->resultDefinition->setReservoirView(m_reservoirView.p()); - } } //-------------------------------------------------------------------------------------------------- @@ -68,44 +58,23 @@ void RimEclipsePropertyFilterCollection::setReservoirView(RimEclipseView* reserv //-------------------------------------------------------------------------------------------------- RimEclipseView* RimEclipsePropertyFilterCollection::reservoirView() { - CVF_ASSERT(!m_reservoirView.isNull()); - return m_reservoirView; -} + RimEclipseView* eclipseView = NULL; + firstAnchestorOrThisOfType(eclipseView); -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimEclipsePropertyFilterCollection::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) -{ - this->updateUiIconFromToggleField(); - - m_reservoirView->fieldChangedByUi(&(m_reservoirView->propertyFilterCollection), oldValue, newValue); + return eclipseView; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RimEclipsePropertyFilter* RimEclipsePropertyFilterCollection::createAndAppendPropertyFilter() +void RimEclipsePropertyFilterCollection::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) { - RimEclipsePropertyFilter* propertyFilter = new RimEclipsePropertyFilter(); - - propertyFilter->resultDefinition->setReservoirView(m_reservoirView.p()); - - propertyFilter->setParentContainer(this); - propertyFilters.push_back(propertyFilter); - - propertyFilter->resultDefinition->setResultVariable(m_reservoirView->cellResult->resultVariable()); - propertyFilter->resultDefinition->setPorosityModel(m_reservoirView->cellResult->porosityModel()); - propertyFilter->resultDefinition->setResultType(m_reservoirView->cellResult->resultType()); - propertyFilter->resultDefinition->loadResult(); - propertyFilter->setToDefaultValues(); - propertyFilter->updateFilterName(); - + updateIconState(); + uiCapability()->updateConnectedEditors(); - return propertyFilter; + updateDisplayModelNotifyManagedViews(); } - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -114,13 +83,7 @@ void RimEclipsePropertyFilterCollection::loadAndInitializePropertyFilters() for (size_t i = 0; i < propertyFilters.size(); i++) { RimEclipsePropertyFilter* propertyFilter = propertyFilters[i]; - - propertyFilter->setParentContainer(this); - - propertyFilter->resultDefinition->setReservoirView(m_reservoirView.p()); - propertyFilter->resultDefinition->loadResult(); - propertyFilter->updateIconState(); - propertyFilter->computeResultValueRange(); + propertyFilter->initAfterRead(); } } @@ -129,17 +92,7 @@ void RimEclipsePropertyFilterCollection::loadAndInitializePropertyFilters() //-------------------------------------------------------------------------------------------------- void RimEclipsePropertyFilterCollection::initAfterRead() { - loadAndInitializePropertyFilters(); - - this->updateUiIconFromToggleField(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimEclipsePropertyFilterCollection::remove(RimEclipsePropertyFilter* propertyFilter) -{ - propertyFilters.removeChildObject(propertyFilter); + updateIconState(); } //-------------------------------------------------------------------------------------------------- @@ -147,7 +100,7 @@ void RimEclipsePropertyFilterCollection::remove(RimEclipsePropertyFilter* proper //-------------------------------------------------------------------------------------------------- bool RimEclipsePropertyFilterCollection::hasActiveFilters() const { - if (!active) return false; + if (!isActive) return false; for (size_t i = 0; i < propertyFilters.size(); i++) { @@ -163,7 +116,7 @@ bool RimEclipsePropertyFilterCollection::hasActiveFilters() const //-------------------------------------------------------------------------------------------------- bool RimEclipsePropertyFilterCollection::hasActiveDynamicFilters() const { - if (!active) return false; + if (!isActive) return false; for (size_t i = 0; i < propertyFilters.size(); i++) { @@ -174,11 +127,77 @@ bool RimEclipsePropertyFilterCollection::hasActiveDynamicFilters() const return false; } - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- caf::PdmFieldHandle* RimEclipsePropertyFilterCollection::objectToggleField() { - return &active; + return &isActive; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEclipsePropertyFilterCollection::updateDisplayModelNotifyManagedViews() +{ + RimEclipseView* view = NULL; + this->firstAnchestorOrThisOfType(view); + CVF_ASSERT(view); + + view->scheduleGeometryRegen(PROPERTY_FILTERED); + view->scheduleCreateDisplayModelAndRedraw(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEclipsePropertyFilterCollection::updateIconState() +{ + bool activeIcon = true; + + RimEclipseView* view = NULL; + this->firstAnchestorOrThisOfType(view); + RimViewController* viewController = view->viewController(); + if (viewController && (viewController->isPropertyFilterOveridden() + || viewController->isVisibleCellsOveridden())) + { + activeIcon = false; + } + + if (!isActive) + { + activeIcon = false; + } + + updateUiIconFromState(activeIcon); + + for (size_t i = 0; i < propertyFilters.size(); i++) + { + RimEclipsePropertyFilter* cellFilter = propertyFilters[i]; + cellFilter->updateActiveState(); + cellFilter->updateIconState(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEclipsePropertyFilterCollection::defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName) +{ + PdmObject::defineUiTreeOrdering(uiTreeOrdering, uiConfigName); + + RimView* rimView = NULL; + this->firstAnchestorOrThisOfType(rimView); + RimViewController* viewController = rimView->viewController(); + if (viewController && (viewController->isPropertyFilterOveridden() + || viewController->isVisibleCellsOveridden())) + { + isActive.uiCapability()->setUiReadOnly(true, uiConfigName); + } + else + { + isActive.uiCapability()->setUiReadOnly(false, uiConfigName); + } + + updateIconState(); } diff --git a/ApplicationCode/ProjectDataModel/RimEclipsePropertyFilterCollection.h b/ApplicationCode/ProjectDataModel/RimEclipsePropertyFilterCollection.h index fcaa65a817..0632f93333 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipsePropertyFilterCollection.h +++ b/ApplicationCode/ProjectDataModel/RimEclipsePropertyFilterCollection.h @@ -20,6 +20,8 @@ #include "RimEclipsePropertyFilter.h" +#include "cafPdmChildArrayField.h" + //================================================================================================== /// /// @@ -31,32 +33,25 @@ class RimEclipsePropertyFilterCollection : public caf::PdmObject RimEclipsePropertyFilterCollection(); virtual ~RimEclipsePropertyFilterCollection(); - // Fields: - caf::PdmField active; - caf::PdmPointersField propertyFilters; + caf::PdmField isActive; + caf::PdmChildArrayField propertyFilters; // Methods - RimEclipsePropertyFilter* createAndAppendPropertyFilter(); - void remove(RimEclipsePropertyFilter* propertyFilter); - bool hasActiveFilters() const; bool hasActiveDynamicFilters() const; - void setReservoirView(RimEclipseView* reservoirView); - RimEclipseView* reservoirView(); + RimEclipseView* reservoirView(); void loadAndInitializePropertyFilters(); + void updateDisplayModelNotifyManagedViews(); + void updateIconState(); +protected: // Overridden methods virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue); + virtual void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName); + virtual void initAfterRead(); virtual caf::PdmFieldHandle* objectToggleField(); - -protected: - // Overridden methods - virtual void initAfterRead(); - -private: - caf::PdmPointer m_reservoirView; }; diff --git a/ApplicationCode/ProjectDataModel/RimEclipseResultCase.cpp b/ApplicationCode/ProjectDataModel/RimEclipseResultCase.cpp index 81444bd5b6..d164a65afd 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseResultCase.cpp +++ b/ApplicationCode/ProjectDataModel/RimEclipseResultCase.cpp @@ -32,7 +32,7 @@ #include "RimReservoirCellResultsStorage.h" #include "cafPdmSettings.h" -#include "cafPdmUiPropertyDialog.h" +#include "cafPdmUiPropertyViewDialog.h" #include "cafProgressInfo.h" #include @@ -49,17 +49,17 @@ RimEclipseResultCase::RimEclipseResultCase() CAF_PDM_InitObject("Eclipse Case", ":/Case48x48.png", "", ""); CAF_PDM_InitField(&caseFileName, "CaseFileName", QString(), "Case file name", "", "" ,""); - caseFileName.setUiReadOnly(true); + caseFileName.uiCapability()->setUiReadOnly(true); // Obsolete, unused field CAF_PDM_InitField(&caseDirectory, "CaseFolder", QString(), "Directory", "", "" ,""); - caseDirectory.setIOWritable(false); - caseDirectory.setUiHidden(true); + caseDirectory.xmlCapability()->setIOWritable(false); + caseDirectory.uiCapability()->setUiHidden(true); - flipXAxis.setIOWritable(true); - //flipXAxis.setUiHidden(true); - flipYAxis.setIOWritable(true); - //flipYAxis.setUiHidden(true); + flipXAxis.xmlCapability()->setIOWritable(true); + //flipXAxis.uiCapability()->setUiHidden(true); + flipYAxis.xmlCapability()->setIOWritable(true); + //flipYAxis.uiCapability()->setUiHidden(true); m_activeCellInfoIsReadFromFile = false; m_gridAndWellDataIsReadFromFile = false; @@ -248,14 +248,14 @@ cvf::ref RimEclipseResultCase::createMockModel(QString model QApplication::setOverrideCursor(QCursor(Qt::ArrowCursor)); RimMockModelSettings rimMockModelSettings; - caf::Settings::readFieldsFromApplicationStore(&rimMockModelSettings); + caf::PdmSettings::readFieldsFromApplicationStore(&rimMockModelSettings); - caf::PdmUiPropertyDialog propertyDialog(NULL, &rimMockModelSettings, "Customize Mock Model"); + caf::PdmUiPropertyViewDialog propertyDialog(NULL, &rimMockModelSettings, "Customize Mock Model", ""); if (propertyDialog.exec() == QDialog::Accepted) { QApplication::restoreOverrideCursor(); - caf::Settings::writeFieldsToApplicationStore(&rimMockModelSettings); + caf::PdmSettings::writeFieldsToApplicationStore(&rimMockModelSettings); double startX = 0; double startY = 0; diff --git a/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.cpp b/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.cpp index c43468d765..8ed6e0aa43 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.cpp +++ b/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.cpp @@ -22,9 +22,16 @@ #include "RigCaseCellResultsData.h" #include "RigCaseData.h" + #include "RimEclipseCase.h" -#include "RimReservoirCellResultsStorage.h" +#include "RimEclipseCellColors.h" +#include "RimEclipseFaultColors.h" +#include "RimEclipsePropertyFilter.h" #include "RimEclipseView.h" +#include "RimReservoirCellResultsStorage.h" +#include "RimView.h" +#include "RimViewLinker.h" +#include "RimWellLogPlotCurve.h" #include "cafPdmUiListEditor.h" @@ -34,29 +41,28 @@ CAF_PDM_SOURCE_INIT(RimEclipseResultDefinition, "ResultDefinition"); /// //-------------------------------------------------------------------------------------------------- RimEclipseResultDefinition::RimEclipseResultDefinition() - //: m_gridScalarResultIndex(cvf::UNDEFINED_SIZE_T) { CAF_PDM_InitObject("Result Definition", "", "", ""); CAF_PDM_InitFieldNoDefault(&m_resultType, "ResultType", "Type", "", "", ""); - m_resultType.setUiHidden(true); + m_resultType.uiCapability()->setUiHidden(true); CAF_PDM_InitFieldNoDefault(&m_porosityModel, "PorosityModelType", "Porosity", "", "", ""); - m_porosityModel.setUiHidden(true); + m_porosityModel.uiCapability()->setUiHidden(true); CAF_PDM_InitField(&m_resultVariable, "ResultVariable", RimDefines::undefinedResultName(), "Variable", "", "", "" ); - m_resultVariable.setUiHidden(true); + m_resultVariable.uiCapability()->setUiHidden(true); CAF_PDM_InitFieldNoDefault(&m_resultTypeUiField, "MResultType", "Type", "", "", ""); - m_resultTypeUiField.setIOReadable(false); - m_resultTypeUiField.setIOWritable(false); + m_resultTypeUiField.xmlCapability()->setIOReadable(false); + m_resultTypeUiField.xmlCapability()->setIOWritable(false); CAF_PDM_InitFieldNoDefault(&m_porosityModelUiField, "MPorosityModelType", "Porosity", "", "", ""); - m_porosityModelUiField.setIOReadable(false); - m_porosityModelUiField.setIOWritable(false); + m_porosityModelUiField.xmlCapability()->setIOReadable(false); + m_porosityModelUiField.xmlCapability()->setIOWritable(false); CAF_PDM_InitField(&m_resultVariableUiField, "MResultVariable", RimDefines::undefinedResultName(), "Result property", "", "", "" ); - m_resultVariableUiField.setIOReadable(false); - m_resultVariableUiField.setIOWritable(false); + m_resultVariableUiField.xmlCapability()->setIOReadable(false); + m_resultVariableUiField.xmlCapability()->setIOWritable(false); - m_resultVariableUiField.setUiEditorTypeName(caf::PdmUiListEditor::uiEditorTypeName()); + m_resultVariableUiField.uiCapability()->setUiEditorTypeName(caf::PdmUiListEditor::uiEditorTypeName()); } //-------------------------------------------------------------------------------------------------- @@ -70,30 +76,29 @@ RimEclipseResultDefinition::~RimEclipseResultDefinition() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimEclipseResultDefinition::setReservoirView(RimEclipseView* ownerReservoirView) +void RimEclipseResultDefinition::setEclipseCase(RimEclipseCase* eclipseCase) { - m_reservoirView = ownerReservoirView; - - updateFieldVisibility(); + m_eclipseCase = eclipseCase; + updateFieldVisibility(); } QStringList RimEclipseResultDefinition::getResultVariableListForCurrentUIFieldSettings() { - if (!m_reservoirView || !m_reservoirView->eclipseCase() ) return QStringList(); + if (!m_eclipseCase ) return QStringList(); RifReaderInterface::PorosityModelResultType porosityModel = RigCaseCellResultsData::convertFromProjectModelPorosityModel(m_porosityModelUiField()); - return m_reservoirView->eclipseCase()->results(porosityModel)->cellResults()->resultNames(m_resultTypeUiField()); + return m_eclipseCase->results(porosityModel)->cellResults()->resultNames(m_resultTypeUiField()); } RimReservoirCellResultsStorage* RimEclipseResultDefinition::currentGridCellResults() const { - if (!m_reservoirView || !m_reservoirView->eclipseCase()) return NULL; + if (!m_eclipseCase ) return NULL; RifReaderInterface::PorosityModelResultType porosityModel = RigCaseCellResultsData::convertFromProjectModelPorosityModel(m_porosityModel()); - return m_reservoirView->eclipseCase()->results(porosityModel); + return m_eclipseCase->results(porosityModel); } //-------------------------------------------------------------------------------------------------- @@ -117,16 +122,69 @@ void RimEclipseResultDefinition::fieldChangedByUi(const caf::PdmFieldHandle* cha { m_resultVariableUiField = ""; } + } - + + RimEclipsePropertyFilter* propFilter = dynamic_cast(this->parentField()->ownerObject()); + RimView* view = NULL; + this->firstAnchestorOrThisOfType(view); + RimWellLogPlotCurve* curve = NULL; + this->firstAnchestorOrThisOfType(curve); + if (&m_resultVariableUiField == changedField) { - m_porosityModel = m_porosityModelUiField; - m_resultType = m_resultTypeUiField; + m_porosityModel = m_porosityModelUiField; + m_resultType = m_resultTypeUiField; m_resultVariable = m_resultVariableUiField; - + loadResult(); + + if (propFilter) + { + propFilter->setToDefaultValues(); + propFilter->updateFilterName(); + + if (view) + { + view->scheduleGeometryRegen(PROPERTY_FILTERED); + view->scheduleCreateDisplayModelAndRedraw(); + } + } + + if (dynamic_cast(this)) + { + if (view) + { + RimViewLinker* viewLinker = view->assosiatedViewLinker(); + if (viewLinker) + { + viewLinker->updateCellResult(); + } + } + } + + if (curve) + { + curve->updatePlotData(); + } + } + + if (propFilter) + { + propFilter->updateConnectedEditors(); + } + + RimEclipseFaultColors* faultColors = dynamic_cast(this->parentField()->ownerObject()); + if (faultColors) + { + faultColors->updateConnectedEditors(); } + + if (curve) + { + curve->updateConnectedEditors(); + } + } //-------------------------------------------------------------------------------------------------- @@ -134,7 +192,18 @@ void RimEclipseResultDefinition::fieldChangedByUi(const caf::PdmFieldHandle* cha //-------------------------------------------------------------------------------------------------- QList RimEclipseResultDefinition::calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) { - return calculateValueOptionsForSpecifiedDerivedListPosition(false, fieldNeedingOptions, useOptionsOnly); + QList optionItems = calculateValueOptionsForSpecifiedDerivedListPosition(false, fieldNeedingOptions, useOptionsOnly); + + RimWellLogPlotCurve* curve = NULL; + this->firstAnchestorOrThisOfType(curve); + + RimEclipsePropertyFilter* propFilter = dynamic_cast(this->parentField()->ownerObject()); + if (propFilter || curve) + { + removePerCellFaceOptionItems(optionItems); + } + + return optionItems; } //-------------------------------------------------------------------------------------------------- @@ -148,8 +217,6 @@ QList RimEclipseResultDefinition::calculateValueOptionsF { QStringList varList = getResultVariableListForCurrentUIFieldSettings(); - bool hasCombinedTransmissibility = false; - QList optionList; QList perCellFaceOptionList; for (int i = 0; i < varList.size(); ++i) @@ -206,7 +273,10 @@ size_t RimEclipseResultDefinition::scalarResultIndex() const size_t gridScalarResultIndex = cvf::UNDEFINED_SIZE_T; const RimReservoirCellResultsStorage* gridCellResults = this->currentGridCellResults(); - if (gridCellResults) gridScalarResultIndex = gridCellResults->cellResults()->findScalarResultIndex(m_resultType(), m_resultVariable()); + if (gridCellResults && gridCellResults->cellResults()) + { + gridScalarResultIndex = gridCellResults->cellResults()->findScalarResultIndex(m_resultType(), m_resultVariable()); + } return gridScalarResultIndex; } @@ -287,13 +357,6 @@ bool RimEclipseResultDefinition::hasDynamicResult() const return false; } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RimEclipseView* RimEclipseResultDefinition::reservoirView() -{ - return m_reservoirView; -} //-------------------------------------------------------------------------------------------------- /// @@ -350,19 +413,43 @@ bool RimEclipseResultDefinition::isTernarySaturationSelected() const //-------------------------------------------------------------------------------------------------- void RimEclipseResultDefinition::updateFieldVisibility() { - if (m_reservoirView && - m_reservoirView->eclipseCase() && - m_reservoirView->eclipseCase()->reservoirData() && - m_reservoirView->eclipseCase()->reservoirData()->activeCellInfo(RifReaderInterface::FRACTURE_RESULTS) ) + if (m_eclipseCase && + m_eclipseCase->reservoirData() && + m_eclipseCase->reservoirData()->activeCellInfo(RifReaderInterface::FRACTURE_RESULTS) ) { - if (m_reservoirView->eclipseCase()->reservoirData()->activeCellInfo(RifReaderInterface::FRACTURE_RESULTS)->reservoirActiveCellCount() == 0) + if (m_eclipseCase->reservoirData()->activeCellInfo(RifReaderInterface::FRACTURE_RESULTS)->reservoirActiveCellCount() == 0) { - m_porosityModelUiField.setUiHidden(true); + m_porosityModelUiField.uiCapability()->setUiHidden(true); } else { - m_porosityModelUiField.setUiHidden(false); + m_porosityModelUiField.uiCapability()->setUiHidden(false); } } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEclipseResultDefinition::removePerCellFaceOptionItems(QList& optionItems) +{ + std::vector indicesToRemove; + for (int i = 0; i < optionItems.size(); i++) + { + QString text = optionItems[i].optionUiText; + + if (RimDefines::isPerCellFaceResult(text)) + { + indicesToRemove.push_back(i); + } + } + + std::sort(indicesToRemove.begin(), indicesToRemove.end()); + + std::vector::reverse_iterator rit; + for (rit = indicesToRemove.rbegin(); rit != indicesToRemove.rend(); ++rit) + { + optionItems.takeAt(*rit); + } +} + diff --git a/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.h b/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.h index 905de6dd12..3e8606fcbd 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.h +++ b/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.h @@ -31,6 +31,7 @@ class RimEclipseView; class RigCaseCellResultsData; class RimReservoirCellResultsStorage; +class RimEclipseCase; //================================================================================================== /// /// @@ -42,8 +43,7 @@ class RimEclipseResultDefinition : public caf::PdmObject RimEclipseResultDefinition(); virtual ~RimEclipseResultDefinition(); - virtual void setReservoirView(RimEclipseView* ownerReservoirView); - RimEclipseView* reservoirView(); + void setEclipseCase(RimEclipseCase* eclipseCase); RimDefines::ResultCatType resultType() const { return m_resultType(); } void setResultType(RimDefines::ResultCatType val); @@ -72,20 +72,25 @@ class RimEclipseResultDefinition : public caf::PdmObject friend class RimEclipsePropertyFilter; friend class RimEclipseFaultColors; + friend class RimWellLogExtractionCurve; // User interface only fields, to support "filtering"-like behaviour etc. caf::PdmField< caf::AppEnum< RimDefines::ResultCatType > > m_resultTypeUiField; caf::PdmField< caf::AppEnum< RimDefines::PorosityModelType > > m_porosityModelUiField; caf::PdmField m_resultVariableUiField; - caf::PdmPointer m_reservoirView; + caf::PdmPointer m_eclipseCase; + protected: void updateFieldVisibility(); QList calculateValueOptionsForSpecifiedDerivedListPosition(bool showDerivedResultsFirstInList, const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly); + + private: QStringList getResultVariableListForCurrentUIFieldSettings(); + static void removePerCellFaceOptionItems(QList& optionItems); }; diff --git a/ApplicationCode/ProjectDataModel/RimEclipseStatisticsCase.cpp b/ApplicationCode/ProjectDataModel/RimEclipseStatisticsCase.cpp index fc6164060d..24aef638ca 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseStatisticsCase.cpp +++ b/ApplicationCode/ProjectDataModel/RimEclipseStatisticsCase.cpp @@ -28,7 +28,6 @@ #include "RimEclipseView.h" #include "RimEclipseCellColors.h" #include "RimEclipseStatisticsCaseEvaluator.h" -#include "RimUiTreeModelPdm.h" #include "RimEclipseWellCollection.h" #include "RiuMainWindow.h" @@ -59,24 +58,24 @@ RimEclipseStatisticsCase::RimEclipseStatisticsCase() CAF_PDM_InitObject("Case Group Statistics", ":/Histogram16x16.png", "", ""); CAF_PDM_InitFieldNoDefault(&m_calculateEditCommand, "m_editingAllowed", "", "", "", ""); - m_calculateEditCommand.setIOWritable(false); - m_calculateEditCommand.setIOReadable(false); - m_calculateEditCommand.setUiEditorTypeName(caf::PdmUiPushButtonEditor::uiEditorTypeName()); - m_calculateEditCommand.setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN); + m_calculateEditCommand.xmlCapability()->setIOWritable(false); + m_calculateEditCommand.xmlCapability()->setIOReadable(false); + m_calculateEditCommand.uiCapability()->setUiEditorTypeName(caf::PdmUiPushButtonEditor::uiEditorTypeName()); + m_calculateEditCommand.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN); m_calculateEditCommand = false; CAF_PDM_InitField(&m_selectionSummary, "SelectionSummary", QString(""), "Summary of calculation setup", "", "", ""); - m_selectionSummary.setIOWritable(false); - m_selectionSummary.setIOReadable(false); - m_selectionSummary.setUiReadOnly(true); - m_selectionSummary.setUiEditorTypeName(caf::PdmUiTextEditor::uiEditorTypeName()); - m_selectionSummary.setUiLabelPosition(caf::PdmUiItemInfo::TOP); + m_selectionSummary.xmlCapability()->setIOWritable(false); + m_selectionSummary.xmlCapability()->setIOReadable(false); + m_selectionSummary.uiCapability()->setUiReadOnly(true); + m_selectionSummary.uiCapability()->setUiEditorTypeName(caf::PdmUiTextEditor::uiEditorTypeName()); + m_selectionSummary.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::TOP); CAF_PDM_InitFieldNoDefault(&m_resultType, "ResultType", "Result Type", "", "", ""); - m_resultType.setIOWritable(false); + m_resultType.xmlCapability()->setIOWritable(false); CAF_PDM_InitFieldNoDefault(&m_porosityModel, "PorosityModel", "Porosity Model", "", "", ""); - m_porosityModel.setIOWritable(false); + m_porosityModel.xmlCapability()->setIOWritable(false); CAF_PDM_InitFieldNoDefault(&m_selectedDynamicProperties, "DynamicPropertiesToCalculate", "Dyn Prop", "", "", ""); CAF_PDM_InitFieldNoDefault(&m_selectedStaticProperties, "StaticPropertiesToCalculate", "Stat Prop", "", "", ""); @@ -88,15 +87,15 @@ RimEclipseStatisticsCase::RimEclipseStatisticsCase() CAF_PDM_InitFieldNoDefault(&m_selectedFractureGeneratedProperties, "FractureGeneratedPropertiesToCalculate", "", "", "", ""); CAF_PDM_InitFieldNoDefault(&m_selectedFractureInputProperties, "FractureInputPropertiesToCalculate", "", "", "", ""); - m_selectedDynamicProperties.setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN); - m_selectedStaticProperties.setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN); - m_selectedGeneratedProperties.setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN); - m_selectedInputProperties.setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN); + m_selectedDynamicProperties.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN); + m_selectedStaticProperties.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN); + m_selectedGeneratedProperties.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN); + m_selectedInputProperties.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN); - m_selectedFractureDynamicProperties.setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN); - m_selectedFractureStaticProperties.setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN); - m_selectedFractureGeneratedProperties.setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN); - m_selectedFractureInputProperties.setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN); + m_selectedFractureDynamicProperties.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN); + m_selectedFractureStaticProperties.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN); + m_selectedFractureGeneratedProperties.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN); + m_selectedFractureInputProperties.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN); CAF_PDM_InitField(&m_calculatePercentiles, "CalculatePercentiles", true, "Calculate Percentiles", "", "", ""); CAF_PDM_InitFieldNoDefault(&m_percentileCalculationType, "PercentileCalculationType", "Method", "", "", ""); @@ -161,15 +160,7 @@ bool RimEclipseStatisticsCase::openEclipseGridFile() //-------------------------------------------------------------------------------------------------- RimCaseCollection* RimEclipseStatisticsCase::parentStatisticsCaseCollection() { - std::vector parentObjects; - this->parentObjectsOfType(parentObjects); - - if (parentObjects.size() > 0) - { - return parentObjects[0]; - } - - return NULL; + return dynamic_cast(this->parentField()->ownerObject()); } //-------------------------------------------------------------------------------------------------- @@ -459,8 +450,6 @@ void RimEclipseStatisticsCase::fieldChangedByUi(const caf::PdmFieldHandle* chang if (&m_wellDataSourceCase == changedField) { - RimUiTreeModelPdm* treeModel = RiuMainWindow::instance()->uiPdmModel(); - // Find or load well data for given case RimEclipseCase* sourceResultCase = caseGroup()->caseCollection()->findByDescription(m_wellDataSourceCase); if (sourceResultCase) @@ -487,8 +476,6 @@ void RimEclipseStatisticsCase::fieldChangedByUi(const caf::PdmFieldHandle* chang //-------------------------------------------------------------------------------------------------- void RimEclipseStatisticsCase::setWellResultsAndUpdateViews(const cvf::Collection& sourceCaseWellResults) { - RimUiTreeModelPdm* treeModel = RiuMainWindow::instance()->uiPdmModel(); - this->reservoirData()->setWellResults(sourceCaseWellResults); caf::ProgressInfo progInfo(reservoirViews().size() + 1, "Updating Well Data for Views"); @@ -501,8 +488,7 @@ void RimEclipseStatisticsCase::setWellResultsAndUpdateViews(const cvf::Collectio reservoirView->wellCollection()->wells.deleteAllChildObjects(); reservoirView->updateDisplayModelForWellResults(); - - treeModel->updateUiSubTree(reservoirView->wellCollection()); + reservoirView->wellCollection()->updateConnectedEditors(); progInfo.incrementProgress(); } @@ -590,18 +576,18 @@ void RimEclipseStatisticsCase::defineEditorAttribute(const caf::PdmFieldHandle* void RimEclipseStatisticsCase::updateSelectionListVisibilities() { bool isLocked = hasComputedStatistics(); - m_resultType.setUiHidden(isLocked); - m_porosityModel.setUiHidden(isLocked ); // || !caseGroup()->mainCase()->reservoirData()->results(RifReaderInterface::FRACTURE_RESULTS)->resultCount() - - m_selectedDynamicProperties.setUiHidden( isLocked || !(m_porosityModel() == RimDefines::MATRIX_MODEL && m_resultType() == RimDefines::DYNAMIC_NATIVE)); - m_selectedStaticProperties.setUiHidden( isLocked || !(m_porosityModel() == RimDefines::MATRIX_MODEL && m_resultType() == RimDefines::STATIC_NATIVE)); - m_selectedGeneratedProperties.setUiHidden( isLocked || !(m_porosityModel() == RimDefines::MATRIX_MODEL && m_resultType() == RimDefines::GENERATED)); - m_selectedInputProperties.setUiHidden( isLocked || !(m_porosityModel() == RimDefines::MATRIX_MODEL && m_resultType() == RimDefines::INPUT_PROPERTY)); - - m_selectedFractureDynamicProperties.setUiHidden( isLocked || !(m_porosityModel() == RimDefines::FRACTURE_MODEL && m_resultType() == RimDefines::DYNAMIC_NATIVE)); - m_selectedFractureStaticProperties.setUiHidden( isLocked || !(m_porosityModel() == RimDefines::FRACTURE_MODEL && m_resultType() == RimDefines::STATIC_NATIVE)); - m_selectedFractureGeneratedProperties.setUiHidden( isLocked || !(m_porosityModel() == RimDefines::FRACTURE_MODEL && m_resultType() == RimDefines::GENERATED)); - m_selectedFractureInputProperties.setUiHidden( isLocked || !(m_porosityModel() == RimDefines::FRACTURE_MODEL && m_resultType() == RimDefines::INPUT_PROPERTY)); + m_resultType.uiCapability()->setUiHidden(isLocked); + m_porosityModel.uiCapability()->setUiHidden(isLocked ); // || !caseGroup()->mainCase()->reservoirData()->results(RifReaderInterface::FRACTURE_RESULTS)->resultCount() + + m_selectedDynamicProperties.uiCapability()->setUiHidden( isLocked || !(m_porosityModel() == RimDefines::MATRIX_MODEL && m_resultType() == RimDefines::DYNAMIC_NATIVE)); + m_selectedStaticProperties.uiCapability()->setUiHidden( isLocked || !(m_porosityModel() == RimDefines::MATRIX_MODEL && m_resultType() == RimDefines::STATIC_NATIVE)); + m_selectedGeneratedProperties.uiCapability()->setUiHidden( isLocked || !(m_porosityModel() == RimDefines::MATRIX_MODEL && m_resultType() == RimDefines::GENERATED)); + m_selectedInputProperties.uiCapability()->setUiHidden( isLocked || !(m_porosityModel() == RimDefines::MATRIX_MODEL && m_resultType() == RimDefines::INPUT_PROPERTY)); + + m_selectedFractureDynamicProperties.uiCapability()->setUiHidden( isLocked || !(m_porosityModel() == RimDefines::FRACTURE_MODEL && m_resultType() == RimDefines::DYNAMIC_NATIVE)); + m_selectedFractureStaticProperties.uiCapability()->setUiHidden( isLocked || !(m_porosityModel() == RimDefines::FRACTURE_MODEL && m_resultType() == RimDefines::STATIC_NATIVE)); + m_selectedFractureGeneratedProperties.uiCapability()->setUiHidden( isLocked || !(m_porosityModel() == RimDefines::FRACTURE_MODEL && m_resultType() == RimDefines::GENERATED)); + m_selectedFractureInputProperties.uiCapability()->setUiHidden( isLocked || !(m_porosityModel() == RimDefines::FRACTURE_MODEL && m_resultType() == RimDefines::INPUT_PROPERTY)); } //-------------------------------------------------------------------------------------------------- @@ -610,11 +596,11 @@ void RimEclipseStatisticsCase::updateSelectionListVisibilities() void RimEclipseStatisticsCase::updatePercentileUiVisibility() { bool isLocked = hasComputedStatistics(); - m_calculatePercentiles.setUiHidden(isLocked); - m_percentileCalculationType.setUiHidden( isLocked || !m_calculatePercentiles()); - m_lowPercentile .setUiHidden(isLocked || !m_calculatePercentiles()); - m_midPercentile .setUiHidden(isLocked || !m_calculatePercentiles()); - m_highPercentile.setUiHidden(isLocked || !m_calculatePercentiles()); + m_calculatePercentiles.uiCapability()->setUiHidden(isLocked); + m_percentileCalculationType.uiCapability()->setUiHidden( isLocked || !m_calculatePercentiles()); + m_lowPercentile .uiCapability()->setUiHidden(isLocked || !m_calculatePercentiles()); + m_midPercentile .uiCapability()->setUiHidden(isLocked || !m_calculatePercentiles()); + m_highPercentile.uiCapability()->setUiHidden(isLocked || !m_calculatePercentiles()); } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/RimEclipseStatisticsCaseCollection.cpp b/ApplicationCode/ProjectDataModel/RimEclipseStatisticsCaseCollection.cpp index 545b4bcc20..cb9d9f77b2 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseStatisticsCaseCollection.cpp +++ b/ApplicationCode/ProjectDataModel/RimEclipseStatisticsCaseCollection.cpp @@ -21,6 +21,7 @@ #include "RimEclipseStatisticsCaseCollection.h" #include "RimIdenticalGridCaseGroup.h" +#include "RimEclipseStatisticsCase.h" CAF_PDM_SOURCE_INIT(RimEclipseStatisticsCaseCollection, "RimStatisticalCollection"); @@ -34,6 +35,7 @@ RimEclipseStatisticsCaseCollection::RimEclipseStatisticsCaseCollection() CAF_PDM_InitObject("Derived Statistics", "", "", ""); CAF_PDM_InitFieldNoDefault(&cases, "Reservoirs", "", "", "", ""); + cases.uiCapability()->setUiHidden(true); } //-------------------------------------------------------------------------------------------------- @@ -49,14 +51,7 @@ RimEclipseStatisticsCaseCollection::~RimEclipseStatisticsCaseCollection() //-------------------------------------------------------------------------------------------------- RimIdenticalGridCaseGroup* RimEclipseStatisticsCaseCollection::parentCaseGroup() { - std::vector parentObjects; - this->parentObjectsOfType(parentObjects); - - if (parentObjects.size() > 0) - { - return parentObjects[0]; - } - - return NULL; + RimIdenticalGridCaseGroup* parentObject = dynamic_cast(this->parentField()->ownerObject()); + return parentObject; } diff --git a/ApplicationCode/ProjectDataModel/RimEclipseStatisticsCaseCollection.h b/ApplicationCode/ProjectDataModel/RimEclipseStatisticsCaseCollection.h index e1f18bfcc3..e6cab8e3be 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseStatisticsCaseCollection.h +++ b/ApplicationCode/ProjectDataModel/RimEclipseStatisticsCaseCollection.h @@ -20,11 +20,13 @@ #pragma once -#include "cvfBase.h" -#include "cvfObject.h" +#include "cafPdmChildArrayField.h" #include "cafPdmField.h" #include "cafPdmObject.h" +#include "cvfBase.h" +#include "cvfObject.h" + class RimEclipseStatisticsCase; class RimIdenticalGridCaseGroup; @@ -42,7 +44,7 @@ class RimEclipseStatisticsCaseCollection : public caf::PdmObject RimEclipseStatisticsCaseCollection(); virtual ~RimEclipseStatisticsCaseCollection(); - caf::PdmPointersField cases; + caf::PdmChildArrayField cases; RimIdenticalGridCaseGroup* parentCaseGroup(); diff --git a/ApplicationCode/ProjectDataModel/RimEclipseStatisticsCaseEvaluator.cpp b/ApplicationCode/ProjectDataModel/RimEclipseStatisticsCaseEvaluator.cpp index 9ec9ac653f..ccaa7261fc 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseStatisticsCaseEvaluator.cpp +++ b/ApplicationCode/ProjectDataModel/RimEclipseStatisticsCaseEvaluator.cpp @@ -150,15 +150,15 @@ void RimEclipseStatisticsCaseEvaluator::evaluateForResults(const QList& // Build data access objects for source scalar results - cvf::Collection sourceDataAccessList; + cvf::Collection sourceDataAccessList; for (size_t caseIdx = 0; caseIdx < m_sourceCases.size(); caseIdx++) { RimEclipseCase* sourceCase = m_sourceCases.at(caseIdx); - // Trigger loading of dataset - sourceCase->results(poroModel)->findOrLoadScalarResultForTimeStep(resultType, resultName, dataAccessTimeStepIndex); + // Trigger loading of dataset + sourceCase->results(poroModel)->findOrLoadScalarResultForTimeStep(resultType, resultName, dataAccessTimeStepIndex); - cvf::ref resultAccessor = RigResultAccessorFactory::createResultAccessor(sourceCase->reservoirData(), gridIdx, poroModel, dataAccessTimeStepIndex, resultName, resultType); + cvf::ref resultAccessor = RigResultAccessorFactory::createResultAccessor(sourceCase->reservoirData(), gridIdx, poroModel, dataAccessTimeStepIndex, resultName, resultType); if (resultAccessor.notNull()) { sourceDataAccessList.push_back(resultAccessor.p()); diff --git a/ApplicationCode/ProjectDataModel/RimEclipseView.cpp b/ApplicationCode/ProjectDataModel/RimEclipseView.cpp index 2871e287f3..268ddd07fc 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseView.cpp +++ b/ApplicationCode/ProjectDataModel/RimEclipseView.cpp @@ -61,6 +61,9 @@ #include #include +#include "RimViewLinker.h" +#include "RimViewController.h" +#include "cafPdmUiTreeOrdering.h" @@ -79,27 +82,27 @@ RimEclipseView::RimEclipseView() CAF_PDM_InitFieldNoDefault(&cellResult, "GridCellResult", "Cell Result", ":/CellResult.png", "", ""); cellResult = new RimEclipseCellColors(); + cellResult.uiCapability()->setUiHidden(true); CAF_PDM_InitFieldNoDefault(&cellEdgeResult, "GridCellEdgeResult", "Cell Edge Result", ":/EdgeResult_1.png", "", ""); cellEdgeResult = new RimCellEdgeColors(); + cellEdgeResult.uiCapability()->setUiHidden(true); CAF_PDM_InitFieldNoDefault(&faultResultSettings, "FaultResultSettings", "Separate Fault Result", "", "", ""); faultResultSettings = new RimEclipseFaultColors(); - + faultResultSettings.uiCapability()->setUiHidden(true); CAF_PDM_InitFieldNoDefault(&wellCollection, "WellCollection", "Simulation Wells", "", "", ""); wellCollection = new RimEclipseWellCollection; + wellCollection.uiCapability()->setUiHidden(true); CAF_PDM_InitFieldNoDefault(&faultCollection, "FaultCollection", "Faults", "", "", ""); faultCollection = new RimFaultCollection; + faultCollection.uiCapability()->setUiHidden(true); - CAF_PDM_InitFieldNoDefault(&rangeFilterCollection, "RangeFilters", "Range Filters", "", "", ""); - rangeFilterCollection = new RimCellRangeFilterCollection(); - rangeFilterCollection->setReservoirView(this); - - CAF_PDM_InitFieldNoDefault(&propertyFilterCollection, "PropertyFilters", "Property Filters", "", "", ""); - propertyFilterCollection = new RimEclipsePropertyFilterCollection(); - propertyFilterCollection->setReservoirView(this); + CAF_PDM_InitFieldNoDefault(&m_propertyFilterCollection, "PropertyFilters", "Property Filters", "", "", ""); + m_propertyFilterCollection = new RimEclipsePropertyFilterCollection(); + m_propertyFilterCollection.uiCapability()->setUiHidden(true); // Visualization fields CAF_PDM_InitField(&showMainGrid, "ShowMainGrid", true, "Show Main Grid", "", "", ""); @@ -107,11 +110,9 @@ RimEclipseView::RimEclipseView() CAF_PDM_InitField(&showInvalidCells, "ShowInvalidCells", false, "Show Invalid Cells", "", "", ""); this->cellResult()->setReservoirView(this); - this->cellResult()->legendConfig()->setPosition(cvf::Vec2ui(10, 120)); this->cellEdgeResult()->setReservoirView(this); this->cellEdgeResult()->legendConfig()->setReservoirView(this); - this->cellEdgeResult()->legendConfig()->setPosition(cvf::Vec2ui(10, 320)); this->cellEdgeResult()->legendConfig()->setColorRangeMode(RimLegendConfig::PINK_WHITE); this->faultResultSettings()->setReservoirView(this); @@ -120,7 +121,6 @@ RimEclipseView::RimEclipseView() m_pipesPartManager = new RivReservoirPipesPartMgr(this); m_reservoir = NULL; - } //-------------------------------------------------------------------------------------------------- @@ -132,8 +132,7 @@ RimEclipseView::~RimEclipseView() delete this->cellResult(); delete this->cellEdgeResult(); - delete rangeFilterCollection(); - delete propertyFilterCollection(); + delete m_propertyFilterCollection; delete wellCollection(); delete faultCollection(); @@ -142,7 +141,6 @@ RimEclipseView::~RimEclipseView() m_reservoir = NULL; } - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -203,7 +201,9 @@ void RimEclipseView::fieldChangedByUi(const caf::PdmFieldHandle* changedField, c { if (m_viewer) { - RiuMainWindow::instance()->removeViewer(m_viewer); + windowGeometry = RiuMainWindow::instance()->windowGeometryForViewer(m_viewer->layoutWidget()); + + RiuMainWindow::instance()->removeViewer(m_viewer->layoutWidget()); delete m_viewer; m_viewer = NULL; } @@ -214,32 +214,32 @@ void RimEclipseView::fieldChangedByUi(const caf::PdmFieldHandle* changedField, c else if (changedField == &showInvalidCells) { - m_reservoirGridPartManager->scheduleGeometryRegen(INACTIVE); - m_reservoirGridPartManager->scheduleGeometryRegen(RANGE_FILTERED_INACTIVE); + this->scheduleGeometryRegen(INACTIVE); + this->scheduleGeometryRegen(RANGE_FILTERED_INACTIVE); - createDisplayModelAndRedraw(); + scheduleCreateDisplayModelAndRedraw(); } else if (changedField == &showInactiveCells) { - m_reservoirGridPartManager->scheduleGeometryRegen(INACTIVE); - m_reservoirGridPartManager->scheduleGeometryRegen(RANGE_FILTERED_INACTIVE); + this->scheduleGeometryRegen(INACTIVE); + this->scheduleGeometryRegen(RANGE_FILTERED_INACTIVE); - createDisplayModelAndRedraw(); + scheduleCreateDisplayModelAndRedraw(); } else if (changedField == &showMainGrid) { - createDisplayModelAndRedraw(); + scheduleCreateDisplayModelAndRedraw(); } - else if (changedField == &rangeFilterCollection) + else if (changedField == &m_rangeFilterCollection) { - m_reservoirGridPartManager->scheduleGeometryRegen(RANGE_FILTERED); - m_reservoirGridPartManager->scheduleGeometryRegen(RANGE_FILTERED_INACTIVE); + this->scheduleGeometryRegen(RANGE_FILTERED); + this->scheduleGeometryRegen(RANGE_FILTERED_INACTIVE); scheduleCreateDisplayModelAndRedraw(); } - else if (changedField == &propertyFilterCollection) + else if (changedField == &m_propertyFilterCollection) { - m_reservoirGridPartManager->scheduleGeometryRegen(PROPERTY_FILTERED); + this->scheduleGeometryRegen(PROPERTY_FILTERED); scheduleCreateDisplayModelAndRedraw(); } @@ -313,8 +313,6 @@ void RimEclipseView::createDisplayModel() // Remove all existing animation frames from the viewer. // The parts are still cached in the RivReservoir geometry and friends - - bool isAnimationActive = m_viewer->isAnimationActive(); m_viewer->removeAllFrames(); wellCollection->scheduleIsWellPipesVisibleRecalculation(); @@ -328,12 +326,18 @@ void RimEclipseView::createDisplayModel() // for the different frames. updateCurrentTimeStep updates the colors etc. // For property filtered geometry : just set all the models as empty scenes // updateCurrentTimeStep requests the actual parts + - if (!this->propertyFilterCollection()->hasActiveFilters()) + if (!this->propertyFilterCollection()->hasActiveFilters() + || this->viewController() && this->viewController()->isVisibleCellsOveridden()) { std::vector geometryTypesToAdd; - if (this->rangeFilterCollection()->hasActiveFilters() && this->wellCollection()->hasVisibleWellCells()) + if (this->viewController() && this->viewController()->isVisibleCellsOveridden()) + { + geometryTypesToAdd.push_back(OVERRIDDEN_CELL_VISIBILITY); + } + else if (this->rangeFilterCollection()->hasActiveFilters() && this->wellCollection()->hasVisibleWellCells()) { geometryTypesToAdd.push_back(RANGE_FILTERED); geometryTypesToAdd.push_back(RANGE_FILTERED_WELL_CELLS); @@ -384,9 +388,9 @@ void RimEclipseView::createDisplayModel() m_visibleGridParts = geometryTypesToAdd; } - if (!this->propertyFilterCollection()->hasActiveFilters() || faultCollection()->showFaultsOutsideFilters()) + if (faultCollection()->showFaultsOutsideFilters() || !this->propertyFilterCollection()->hasActiveFilters() ) { - updateFaultForcedVisibility(); + forceFaultVisibilityOn(); std::vector faultGeometryTypesToAppend = visibleFaultGeometryTypes(); @@ -405,7 +409,7 @@ void RimEclipseView::createDisplayModel() } // Compute triangle count, Debug only - +/* if (false) { size_t totalTriangleCount = 0; @@ -427,6 +431,7 @@ void RimEclipseView::createDisplayModel() } } } +*/ // Create Scenes from the frameModels // Animation frames for results display, starts from frame 1 @@ -461,11 +466,12 @@ void RimEclipseView::createDisplayModel() if (frameModels.size() > 1 && this->hasUserRequestedAnimation()) { - m_viewer->animationControl()->setCurrentFrame(m_currentTimeStep); + m_viewer->animationControl()->setCurrentFrameOnly(m_currentTimeStep); + m_viewer->setCurrentFrame(m_currentTimeStep); } else { - overlayInfoConfig()->update3DInfo(); + m_overlayInfoConfig()->update3DInfo(); updateLegends(); } } @@ -480,7 +486,39 @@ void RimEclipseView::updateCurrentTimeStep() std::vector geometriesToRecolor; - if (this->propertyFilterCollection()->hasActiveFilters()) + if (this->viewController() && this->viewController()->isVisibleCellsOveridden()) + { + geometriesToRecolor.push_back(OVERRIDDEN_CELL_VISIBILITY); +#if 0 // Experimental + cvf::ref frameParts = new cvf::ModelBasicList; + std::vector gridIndices; + this->indicesToVisibleGrids(&gridIndices); + + + m_reservoirGridPartManager->appendStaticGeometryPartsToModel(frameParts.p(), OVERRIDDEN_CELL_VISIBILITY, gridIndices); + std::vector faultGeometryTypesToAppend = visibleFaultGeometryTypes(); + + for (size_t i = 0; i < faultGeometryTypesToAppend.size(); i++) + { + m_reservoirGridPartManager->appendFaultsStaticGeometryPartsToModel(frameParts.p(), faultGeometryTypesToAppend[i]); + } + + RivCellSetEnum faultLabelType = m_reservoirGridPartManager->geometryTypeForFaultLabels(faultGeometryTypesToAppend); + m_reservoirGridPartManager->appendFaultLabelsStaticGeometryPartsToModel(frameParts.p(), faultLabelType); + + if (m_viewer) + { + cvf::Scene* frameScene = m_viewer->frame(m_currentTimeStep); + if (frameScene) + { + frameScene->removeAllModels(); + frameScene->addModel(frameParts.p()); + frameParts->updateBoundingBoxesRecursive(); + } + } +#endif + } + else if (this->propertyFilterCollection()->hasActiveFilters()) { cvf::ref frameParts = new cvf::ModelBasicList; @@ -548,9 +586,9 @@ void RimEclipseView::updateCurrentTimeStep() cvf::Scene* frameScene = m_viewer->frame(m_currentTimeStep); if (frameScene) { - frameParts->updateBoundingBoxesRecursive(); frameScene->removeAllModels(); frameScene->addModel(frameParts.p()); + frameParts->updateBoundingBoxesRecursive(); } } @@ -583,7 +621,7 @@ void RimEclipseView::updateCurrentTimeStep() { if (this->hasUserRequestedAnimation() && this->cellEdgeResult()->hasResult()) { - m_reservoirGridPartManager->updateCellEdgeResultColor(geometriesToRecolor[i], m_currentTimeStep, this->cellResult(), this->cellEdgeResult()); + m_reservoirGridPartManager->updateCellEdgeResultColor(geometriesToRecolor[i], m_currentTimeStep, this->cellResult(), this->cellEdgeResult()); } else if ((this->hasUserRequestedAnimation() && this->cellResult()->hasResult()) || this->cellResult()->isTernarySaturationSelected()) { @@ -645,7 +683,7 @@ void RimEclipseView::updateCurrentTimeStep() } } - overlayInfoConfig()->update3DInfo(); + m_overlayInfoConfig()->update3DInfo(); } //-------------------------------------------------------------------------------------------------- @@ -662,7 +700,7 @@ void RimEclipseView::loadDataAndUpdate() QMessageBox::warning(RiuMainWindow::instance(), "Error when opening project file", "Could not open the Eclipse Grid file: \n"+ m_reservoir->gridFileName()); - m_reservoir = NULL; + this->setEclipseCase( NULL); return; } } @@ -678,7 +716,7 @@ void RimEclipseView::loadDataAndUpdate() updateViewerWidget(); - this->propertyFilterCollection()->loadAndInitializePropertyFilters(); + this->m_propertyFilterCollection()->loadAndInitializePropertyFilters(); this->faultCollection()->setReservoirView(this); this->faultCollection()->syncronizeFaults(); @@ -687,12 +725,8 @@ void RimEclipseView::loadDataAndUpdate() syncronizeWellsWithResults(); - createDisplayModelAndRedraw(); + this->scheduleCreateDisplayModelAndRedraw(); - if (cameraPosition().isIdentity()) - { - setDefaultView(); - } } @@ -705,8 +739,6 @@ void RimEclipseView::initAfterRead() this->faultResultSettings()->setReservoirView(this); this->cellResult()->setReservoirView(this); this->cellEdgeResult()->setReservoirView(this); - this->rangeFilterCollection()->setReservoirView(this); - this->propertyFilterCollection()->setReservoirView(this); this->updateUiIconFromToggleField(); } @@ -717,6 +749,7 @@ void RimEclipseView::initAfterRead() //-------------------------------------------------------------------------------------------------- void RimEclipseView::updateStaticCellColors() { + updateStaticCellColors( OVERRIDDEN_CELL_VISIBILITY); updateStaticCellColors( ACTIVE); updateStaticCellColors( ALL_WELL_CELLS); updateStaticCellColors( VISIBLE_WELL_CELLS); @@ -837,7 +870,18 @@ RigActiveCellInfo* RimEclipseView::currentActiveCellInfo() //-------------------------------------------------------------------------------------------------- void RimEclipseView::scheduleGeometryRegen(RivCellSetEnum geometryType) { - m_reservoirGridPartManager->scheduleGeometryRegen(static_cast(geometryType)); + m_reservoirGridPartManager->scheduleGeometryRegen(geometryType); + + if (this->isMasterView()) + { + RimViewLinker* viewLinker = this->assosiatedViewLinker(); + if (viewLinker) + { + viewLinker->scheduleGeometryRegenForDepViews(geometryType); + } + } + + m_currentReservoirCellVisibility = NULL; } //-------------------------------------------------------------------------------------------------- @@ -957,18 +1001,16 @@ void RimEclipseView::updateMinMaxValuesAndAddLegendToView(QString legendLabel, R localNegClosestToZero = globalNegClosestToZero; } - resultColors->legendConfig->setClosestToZeroValues(globalPosClosestToZero, globalNegClosestToZero, localPosClosestToZero, localNegClosestToZero); - resultColors->legendConfig->setAutomaticRanges(globalMin, globalMax, localMin, localMax); + CVF_ASSERT(resultColors->legendConfig()); - m_viewer->addColorLegendToBottomLeftCorner(resultColors->legendConfig->legend()); - resultColors->legendConfig->legend()->setTitle(cvfqt::Utils::toString(legendLabel + resultColors->resultVariable())); - } - else - { - resultColors->legendConfig->setClosestToZeroValues(0, 0, 0, 0); - resultColors->legendConfig->setAutomaticRanges(cvf::UNDEFINED_DOUBLE, cvf::UNDEFINED_DOUBLE, cvf::UNDEFINED_DOUBLE, cvf::UNDEFINED_DOUBLE); + resultColors->legendConfig()->setClosestToZeroValues(globalPosClosestToZero, globalNegClosestToZero, localPosClosestToZero, localNegClosestToZero); + resultColors->legendConfig()->setAutomaticRanges(globalMin, globalMax, localMin, localMax); + + m_viewer->addColorLegendToBottomLeftCorner(resultColors->legendConfig()->legend()); + resultColors->legendConfig()->legend()->setTitle(cvfqt::Utils::toString(legendLabel + resultColors->resultVariable())); } + size_t maxTimeStepCount = cellResultsData->maxTimeStepCount(); if (resultColors->isTernarySaturationSelected() && maxTimeStepCount > 1) { @@ -1035,6 +1077,9 @@ void RimEclipseView::updateMinMaxValuesAndAddLegendToView(QString legendLabel, R void RimEclipseView::setEclipseCase(RimEclipseCase* reservoir) { m_reservoir = reservoir; + cellResult()->setEclipseCase(reservoir); + faultResultSettings()->customFaultResult()->setEclipseCase(reservoir); + } //-------------------------------------------------------------------------------------------------- @@ -1269,11 +1314,37 @@ void RimEclipseView::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& cellGroup->add(&showInvalidCells); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEclipseView::defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName /*= ""*/) +{ + uiTreeOrdering.add(m_overlayInfoConfig()); + + uiTreeOrdering.add(cellResult()); + uiTreeOrdering.add(cellEdgeResult()); + uiTreeOrdering.add(faultResultSettings()); + + uiTreeOrdering.add(wellCollection()); + uiTreeOrdering.add(faultCollection()); + + uiTreeOrdering.add(m_rangeFilterCollection()); + uiTreeOrdering.add(m_propertyFilterCollection()); + + uiTreeOrdering.setForgetRemainingFields(true); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimEclipseView::updateFaultForcedVisibility() +void RimEclipseView::forceFaultVisibilityOn() { + if (this->viewController() && this->viewController()->isVisibleCellsOveridden()) + { + m_reservoirGridPartManager->setFaultForceVisibilityForGeometryType(OVERRIDDEN_CELL_VISIBILITY, true); + return; + } + // Force visibility of faults based on application state // As fault geometry is visible in grid visualization mode, fault geometry must be forced visible // even if the fault item is disabled in project tree view @@ -1294,8 +1365,24 @@ void RimEclipseView::updateFaultForcedVisibility() std::vector RimEclipseView::visibleFaultGeometryTypes() const { std::vector faultParts; - - if (this->propertyFilterCollection()->hasActiveFilters() && !faultCollection()->showFaultsOutsideFilters()) + if (this->viewController() && this->viewController()->isVisibleCellsOveridden()) + { + if (this->faultCollection()->showFaultsOutsideFilters()) + { + faultParts.push_back(ACTIVE); + faultParts.push_back(ALL_WELL_CELLS); + + if (this->showInactiveCells()) + { + faultParts.push_back(INACTIVE); + } + } + else + { + faultParts.push_back(OVERRIDDEN_CELL_VISIBILITY); + } + } + else if (this->propertyFilterCollection()->hasActiveFilters() && !faultCollection()->showFaultsOutsideFilters()) { faultParts.push_back(PROPERTY_FILTERED); faultParts.push_back(PROPERTY_FILTERED_WELL_CELLS); @@ -1310,15 +1397,19 @@ std::vector RimEclipseView::visibleFaultGeometryTypes() const { faultParts.push_back(ACTIVE); faultParts.push_back(ALL_WELL_CELLS); + /// Why are these added ? JJS --> faultParts.push_back(RANGE_FILTERED); faultParts.push_back(RANGE_FILTERED_WELL_CELLS); faultParts.push_back(VISIBLE_WELL_CELLS_OUTSIDE_RANGE_FILTER); faultParts.push_back(VISIBLE_WELL_FENCE_CELLS_OUTSIDE_RANGE_FILTER); + /// <-- JJS if (this->showInactiveCells()) { faultParts.push_back(INACTIVE); + /// Why is this added ? JJS --> faultParts.push_back(RANGE_FILTERED_INACTIVE); + /// <-- JJS } } else if (this->rangeFilterCollection()->hasActiveFilters() && this->wellCollection()->hasVisibleWellCells()) @@ -1375,14 +1466,14 @@ void RimEclipseView::updateFaultColors() for (size_t i = 0; i < faultGeometriesToRecolor.size(); ++i) { - if (this->hasUserRequestedAnimation() && this->cellEdgeResult()->hasResult()) - { - m_reservoirGridPartManager->updateFaultCellEdgeResultColor(faultGeometriesToRecolor[i], m_currentTimeStep, faultResultColors, this->cellEdgeResult()); - } - else - { - m_reservoirGridPartManager->updateFaultColors(faultGeometriesToRecolor[i], m_currentTimeStep, faultResultColors); - } + if (this->hasUserRequestedAnimation() && this->cellEdgeResult()->hasResult()) + { + m_reservoirGridPartManager->updateFaultCellEdgeResultColor(faultGeometriesToRecolor[i], m_currentTimeStep, faultResultColors, this->cellEdgeResult()); + } + else + { + m_reservoirGridPartManager->updateFaultColors(faultGeometriesToRecolor[i], m_currentTimeStep, faultResultColors); + } } } @@ -1431,12 +1522,16 @@ RimEclipseCellColors* RimEclipseView::currentFaultResultColors() //-------------------------------------------------------------------------------------------------- void RimEclipseView::resetLegendsInViewer() { - this->cellResult()->legendConfig->recreateLegend(); + RimLegendConfig* cellResultNormalLegendConfig = this->cellResult()->legendConfig(); + if (cellResultNormalLegendConfig) cellResultNormalLegendConfig->recreateLegend(); + this->cellResult()->ternaryLegendConfig->recreateLegend(); this->cellEdgeResult()->legendConfig->recreateLegend(); m_viewer->removeAllColorLegends(); - m_viewer->addColorLegendToBottomLeftCorner(this->cellResult()->legendConfig->legend()); + + if (cellResultNormalLegendConfig) m_viewer->addColorLegendToBottomLeftCorner(cellResultNormalLegendConfig->legend()); + m_viewer->addColorLegendToBottomLeftCorner(this->cellEdgeResult()->legendConfig->legend()); } @@ -1496,3 +1591,85 @@ void RimEclipseView::addWellPathsToScene(cvf::Scene* scene, scene->addModel(wellPathModelBasicList.p()); } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimEclipsePropertyFilterCollection* RimEclipseView::propertyFilterCollection() +{ + if (m_overridePropertyFilterCollection) + { + return m_overridePropertyFilterCollection; + } + else + { + return m_propertyFilterCollection; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const RimEclipsePropertyFilterCollection* RimEclipseView::propertyFilterCollection() const +{ + if (m_overridePropertyFilterCollection) + { + return m_overridePropertyFilterCollection; + } + else + { + return m_propertyFilterCollection; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEclipseView::setOverridePropertyFilterCollection(RimEclipsePropertyFilterCollection* pfc) +{ + m_overridePropertyFilterCollection = pfc; + + this->scheduleGeometryRegen(PROPERTY_FILTERED); + this->scheduleCreateDisplayModelAndRedraw(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEclipseView::calculateCurrentTotalCellVisibility(cvf::UByteArray* totalVisibility) +{ + size_t gridCount = this->eclipseCase()->reservoirData()->gridCount(); + size_t cellCount = this->eclipseCase()->reservoirData()->mainGrid()->cells().size(); + + totalVisibility->resize(cellCount); + totalVisibility->setAll(false); + + for (size_t gridIdx = 0; gridIdx < gridCount; ++gridIdx) + { + RigGridBase * grid = this->eclipseCase()->reservoirData()->grid(gridIdx); + int gridCellCount = static_cast(grid->cellCount()); + + for (size_t gpIdx = 0; gpIdx < m_visibleGridParts.size(); ++gpIdx) + { + cvf::cref visibility = m_reservoirGridPartManager->cellVisibility(m_visibleGridParts[gpIdx], gridIdx, m_currentTimeStep); + + for (int lcIdx = 0; lcIdx < gridCellCount; ++ lcIdx) + { + (*totalVisibility)[grid->reservoirCellIndex(lcIdx)] |= (*visibility)[lcIdx]; + } + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEclipseView::updateIconStateForFilterCollections() +{ + m_rangeFilterCollection()->updateIconState(); + m_rangeFilterCollection()->uiCapability()->updateConnectedEditors(); + + // NB - notice that it is the filter collection managed by this view that the icon update applies to + m_propertyFilterCollection()->updateIconState(); + m_propertyFilterCollection()->uiCapability()->updateConnectedEditors(); +} diff --git a/ApplicationCode/ProjectDataModel/RimEclipseView.h b/ApplicationCode/ProjectDataModel/RimEclipseView.h index ec6c17bf1d..4091a424d7 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseView.h +++ b/ApplicationCode/ProjectDataModel/RimEclipseView.h @@ -21,6 +21,7 @@ #pragma once #include "cafAppEnum.h" +#include "cafPdmChildField.h" #include "cafPdmField.h" #include "cafPdmObject.h" @@ -84,14 +85,12 @@ class RimEclipseView : public RimView // Fields containing child objects : - caf::PdmField cellResult; - caf::PdmField cellEdgeResult; - caf::PdmField faultResultSettings; + caf::PdmChildField cellResult; + caf::PdmChildField cellEdgeResult; + caf::PdmChildField faultResultSettings; - caf::PdmField propertyFilterCollection; - - caf::PdmField wellCollection; - caf::PdmField faultCollection; + caf::PdmChildField wellCollection; + caf::PdmChildField faultCollection; // Fields @@ -101,6 +100,10 @@ class RimEclipseView : public RimView // Access internal objects + RimEclipsePropertyFilterCollection* propertyFilterCollection(); + const RimEclipsePropertyFilterCollection* propertyFilterCollection() const; + void setOverridePropertyFilterCollection(RimEclipsePropertyFilterCollection* pfc); + RimReservoirCellResultsStorage* currentGridCellResults(); RigActiveCellInfo* currentActiveCellInfo(); RimEclipseCellColors* currentFaultResultColors(); @@ -126,9 +129,12 @@ class RimEclipseView : public RimView // Overridden PDM methods: virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue); + void updateIconStateForFilterCollections(); + protected: virtual void initAfterRead(); virtual void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ); + virtual void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = ""); private: void createDisplayModel(); @@ -147,7 +153,7 @@ class RimEclipseView : public RimView virtual void updateViewerWidgetWindowTitle(); std::vector visibleFaultGeometryTypes() const; - void updateFaultForcedVisibility(); + void forceFaultVisibilityOn(); void updateFaultColors(); void syncronizeWellsWithResults(); @@ -161,6 +167,11 @@ class RimEclipseView : public RimView virtual RimCase* ownerCase(); + virtual void calculateCurrentTotalCellVisibility(cvf::UByteArray* totalVisibility); + + caf::PdmChildField m_propertyFilterCollection; + caf::PdmPointer m_overridePropertyFilterCollection; + caf::PdmPointer m_reservoir; cvf::ref m_reservoirGridPartManager; diff --git a/ApplicationCode/ProjectDataModel/RimEclipseWell.cpp b/ApplicationCode/ProjectDataModel/RimEclipseWell.cpp index b16ef133f0..f48113e4e4 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseWell.cpp +++ b/ApplicationCode/ProjectDataModel/RimEclipseWell.cpp @@ -37,7 +37,7 @@ RimEclipseWell::RimEclipseWell() CAF_PDM_InitFieldNoDefault(&name, "WellName", "Name", "", "", ""); CAF_PDM_InitField(&showWell, "ShowWell", true, "Show well ", "", "", ""); - showWell.setUiHidden(true); + showWell.uiCapability()->setUiHidden(true); CAF_PDM_InitField(&showWellLabel, "ShowWellLabel", true, "Show well label", "", "", ""); @@ -48,8 +48,8 @@ RimEclipseWell::RimEclipseWell() CAF_PDM_InitField(&showWellCells, "ShowWellCells", true, "Add cells to range filter", "", "", ""); CAF_PDM_InitField(&showWellCellFence, "ShowWellCellFence", false, "Use well fence", "", "", ""); - name.setUiHidden(true); - name.setUiReadOnly(true); + name.uiCapability()->setUiHidden(true); + name.uiCapability()->setUiReadOnly(true); m_wellIndex = cvf::UNDEFINED_SIZE_T; @@ -197,7 +197,7 @@ bool RimEclipseWell::calculateWellPipeVisibility(size_t frameIndex) if (gridIndex != cvf::UNDEFINED_SIZE_T && gridCellIndex != cvf::UNDEFINED_SIZE_T) { cvf::cref cellVisibility = rvMan->cellVisibility(visGridParts[gpIdx], gridIndex, frameIndex); - if ((*cellVisibility)[gridCellIndex]) + if ((*cellVisibility)[gridCellIndex]) { return true; } @@ -217,7 +217,7 @@ bool RimEclipseWell::calculateWellPipeVisibility(size_t frameIndex) gridCellIndex = wsResCells[cIdx].m_gridCellIndex; cvf::cref cellVisibility = rvMan->cellVisibility(visGridParts[gpIdx], gridIndex, frameIndex); - if ((*cellVisibility)[gridCellIndex]) + if ((*cellVisibility)[gridCellIndex]) { return true; } diff --git a/ApplicationCode/ProjectDataModel/RimEclipseWellCollection.cpp b/ApplicationCode/ProjectDataModel/RimEclipseWellCollection.cpp index 297ef704fc..63331d829a 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseWellCollection.cpp +++ b/ApplicationCode/ProjectDataModel/RimEclipseWellCollection.cpp @@ -82,10 +82,10 @@ CAF_PDM_SOURCE_INIT(RimEclipseWellCollection, "Wells"); //-------------------------------------------------------------------------------------------------- RimEclipseWellCollection::RimEclipseWellCollection() { - CAF_PDM_InitObject("Wells", ":/WellCollection.png", "", ""); + CAF_PDM_InitObject("Simulation Wells", ":/WellCollection.png", "", ""); CAF_PDM_InitField(&isActive, "Active", true, "Active", "", "", ""); - isActive.setUiHidden(true); + isActive.uiCapability()->setUiHidden(true); CAF_PDM_InitField(&showWellHead, "ShowWellHead", true, "Show well heads", "", "", ""); CAF_PDM_InitField(&showWellLabel, "ShowWellLabel", true, "Show well labels", "", "", ""); @@ -98,7 +98,7 @@ RimEclipseWellCollection::RimEclipseWellCollection() CAF_PDM_InitField(&pipeRadiusScaleFactor, "WellPipeRadiusScale", 0.1, "Pipe radius scale", "", "", ""); CAF_PDM_InitField(&pipeCrossSectionVertexCount, "WellPipeVertexCount", 12, "Pipe vertex count", "", "", ""); - pipeCrossSectionVertexCount.setUiHidden(true); + pipeCrossSectionVertexCount.uiCapability()->setUiHidden(true); CAF_PDM_InitField(&wellCellsToRangeFilterMode, "GlobalWellCellVisibility", WellCellsRangeFilterEnum(RANGE_ADD_NONE), "Add cells to range filter", "", "", ""); CAF_PDM_InitField(&showWellCellFences, "ShowWellFences", false, "Use well fence", "", "", ""); @@ -109,6 +109,7 @@ RimEclipseWellCollection::RimEclipseWellCollection() CAF_PDM_InitField(&isAutoDetectingBranches, "IsAutoDetectingBranches", true, "Geometry based branch detection", "", "Toggle wether the well pipe visualization will try to detect when a part of the well \nis really a branch, and thus is starting from wellhead", ""); CAF_PDM_InitFieldNoDefault(&wells, "Wells", "Wells", "", "", ""); + wells.uiCapability()->setUiHidden(true); m_reservoirView = NULL; } diff --git a/ApplicationCode/ProjectDataModel/RimEclipseWellCollection.h b/ApplicationCode/ProjectDataModel/RimEclipseWellCollection.h index a9e8a1e29e..dc4b4ca7b9 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseWellCollection.h +++ b/ApplicationCode/ProjectDataModel/RimEclipseWellCollection.h @@ -20,10 +20,11 @@ #pragma once +#include "cafAppEnum.h" +#include "cafPdmChildArrayField.h" #include "cafPdmField.h" #include "cafPdmObject.h" #include "cafPdmPointer.h" -#include "cafAppEnum.h" // Include to make Pdm work for cvf::Color #include "cafPdmFieldCvfColor.h" @@ -101,7 +102,7 @@ class RimEclipseWellCollection : public caf::PdmObject caf::PdmField isAutoDetectingBranches; - caf::PdmPointersField wells; + caf::PdmChildArrayField wells; RimEclipseWell* findWell(QString name); bool hasVisibleWellCells(); diff --git a/ApplicationCode/ProjectDataModel/RimExportInputPropertySettings.cpp b/ApplicationCode/ProjectDataModel/RimExportInputPropertySettings.cpp index 8a2e491420..d0a5ca98a8 100644 --- a/ApplicationCode/ProjectDataModel/RimExportInputPropertySettings.cpp +++ b/ApplicationCode/ProjectDataModel/RimExportInputPropertySettings.cpp @@ -16,8 +16,6 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RiaStdInclude.h" - #include "RimExportInputPropertySettings.h" #include "cafPdmUiFilePathEditor.h" @@ -32,7 +30,7 @@ RimExportInputSettings::RimExportInputSettings() CAF_PDM_InitObject("RimExportInputSettings", "", "", ""); CAF_PDM_InitFieldNoDefault(&fileName, "Filename", "Export filename", "", "", ""); - fileName.setUiEditorTypeName(caf::PdmUiFilePathEditor::uiEditorTypeName()); + fileName.uiCapability()->setUiEditorTypeName(caf::PdmUiFilePathEditor::uiEditorTypeName()); CAF_PDM_InitFieldNoDefault(&eclipseKeyword, "Eclipse Keyword", "Keyword", "", "", ""); } diff --git a/ApplicationCode/ProjectDataModel/RimFault.cpp b/ApplicationCode/ProjectDataModel/RimFault.cpp index 63f01fc646..7fcdfd47dc 100644 --- a/ApplicationCode/ProjectDataModel/RimFault.cpp +++ b/ApplicationCode/ProjectDataModel/RimFault.cpp @@ -33,11 +33,11 @@ RimFault::RimFault() CAF_PDM_InitObject("RimFault", ":/draw_style_faults_24x24.png", "", ""); CAF_PDM_InitFieldNoDefault(&name, "FaultName", "Name", "", "", ""); - name.setUiHidden(true); - name.setUiReadOnly(true); + name.uiCapability()->setUiHidden(true); + name.uiCapability()->setUiReadOnly(true); CAF_PDM_InitField(&showFault, "ShowFault", true, "Show fault", "", "", ""); - showFault.setUiHidden(true); + showFault.uiCapability()->setUiHidden(true); CAF_PDM_InitField(&faultColor, "Color", cvf::Color3f(0.588f, 0.588f, 0.804f), "Fault color", "", "", ""); @@ -69,7 +69,8 @@ void RimFault::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const Q if (&faultColor == changedField || &showFault == changedField) { RimEclipseView* reservoirView = NULL; - this->firstAncestorOfType(reservoirView); + + this->firstAnchestorOrThisOfType(reservoirView); if (reservoirView) { diff --git a/ApplicationCode/ProjectDataModel/RimFaultCollection.cpp b/ApplicationCode/ProjectDataModel/RimFaultCollection.cpp index cdaeecc9a7..37f4e13c57 100644 --- a/ApplicationCode/ProjectDataModel/RimFaultCollection.cpp +++ b/ApplicationCode/ProjectDataModel/RimFaultCollection.cpp @@ -56,27 +56,28 @@ RimFaultCollection::RimFaultCollection() { CAF_PDM_InitObject("Faults", ":/draw_style_faults_24x24.png", "", ""); - RiaPreferences* prefs = RiaApplication::instance()->preferences(); - CAF_PDM_InitField(&showFaultCollection, "Active", true, "Active", "", "", ""); - showFaultCollection.setUiHidden(true); + CAF_PDM_InitField(&showFaultCollection, "Active", true, "Active", "", "", ""); + showFaultCollection.uiCapability()->setUiHidden(true); - CAF_PDM_InitField(&showFaultFaces, "ShowFaultFaces", true, "Show defined faces", "", "", ""); - CAF_PDM_InitField(&showOppositeFaultFaces, "ShowOppositeFaultFaces", true, "Show opposite faces", "", "", ""); - CAF_PDM_InitField(&m_showFaultsOutsideFilters,"ShowFaultsOutsideFilters", true, "Show faults outside filters", "", "", ""); + CAF_PDM_InitField(&showFaultFaces, "ShowFaultFaces", true, "Show defined faces", "", "", ""); + CAF_PDM_InitField(&showOppositeFaultFaces, "ShowOppositeFaultFaces", true, "Show opposite faces", "", "", ""); + CAF_PDM_InitField(&m_showFaultsOutsideFilters, "ShowFaultsOutsideFilters", true, "Show faults outside filters", "", "", ""); - CAF_PDM_InitField(&faultResult, "FaultFaceCulling", caf::AppEnum(RimFaultCollection::FAULT_BACK_FACE_CULLING), "Dynamic Face Selection", "", "", ""); + CAF_PDM_InitField(&faultResult, "FaultFaceCulling", caf::AppEnum(RimFaultCollection::FAULT_BACK_FACE_CULLING), "Dynamic Face Selection", "", "", ""); - CAF_PDM_InitField(&showFaultLabel, "ShowFaultLabel", false, "Show labels", "", "", ""); + CAF_PDM_InitField(&showFaultLabel, "ShowFaultLabel", false, "Show labels", "", "", ""); cvf::Color3f defWellLabelColor = RiaApplication::instance()->preferences()->defaultWellLabelColor(); - CAF_PDM_InitField(&faultLabelColor, "FaultLabelColor", defWellLabelColor, "Label color", "", "", ""); - + CAF_PDM_InitField(&faultLabelColor, "FaultLabelColor", defWellLabelColor, "Label color", "", "", ""); + CAF_PDM_InitField(&showNNCs, "ShowNNCs", true, "Show NNCs", "", "", ""); CAF_PDM_InitField(&hideNncsWhenNoResultIsAvailable, "HideNncsWhenNoResultIsAvailable", true, "Hide NNC geometry if no NNC result is available", "", "", ""); CAF_PDM_InitFieldNoDefault(&noCommonAreaNnncCollection, "NoCommonAreaNnncCollection", "NNCs With No Common Area", "", "", ""); noCommonAreaNnncCollection = new RimNoCommonAreaNncCollection; + noCommonAreaNnncCollection.uiCapability()->setUiHidden(true); CAF_PDM_InitFieldNoDefault(&faults, "Faults", "Faults", "", "", ""); + faults.uiCapability()->setUiHidden(true); m_reservoirView = NULL; } @@ -325,9 +326,9 @@ void RimFaultCollection::defineUiOrdering(QString uiConfigName, caf::PdmUiOrderi { bool isGridVizMode = isGridVisualizationMode(); - faultResult.setUiReadOnly(isGridVizMode); - showFaultFaces.setUiReadOnly(isGridVizMode); - showOppositeFaultFaces.setUiReadOnly(isGridVizMode); + faultResult.uiCapability()->setUiReadOnly(isGridVizMode); + showFaultFaces.uiCapability()->setUiReadOnly(isGridVizMode); + showOppositeFaultFaces.uiCapability()->setUiReadOnly(isGridVizMode); caf::PdmUiGroup* labs = uiOrdering.addNewGroup("Fault Labels"); labs->add(&showFaultLabel); diff --git a/ApplicationCode/ProjectDataModel/RimFaultCollection.h b/ApplicationCode/ProjectDataModel/RimFaultCollection.h index 843882ba66..aab9468473 100644 --- a/ApplicationCode/ProjectDataModel/RimFaultCollection.h +++ b/ApplicationCode/ProjectDataModel/RimFaultCollection.h @@ -19,16 +19,20 @@ #pragma once +#include "RimReservoirCellResultsStorage.h" + #include "cafAppEnum.h" +#include "cafPdmChildArrayField.h" +#include "cafPdmChildField.h" #include "cafPdmField.h" #include "cafPdmObject.h" #include "cafPdmPointer.h" + #include "cvfBase.h" // Include to make Pdm work for cvf::Color #include "cafPdmFieldCvfColor.h" -#include "RimReservoirCellResultsStorage.h" #include @@ -78,10 +82,10 @@ class RimFaultCollection : public caf::PdmObject caf::PdmField showNNCs; caf::PdmField hideNncsWhenNoResultIsAvailable; - caf::PdmPointersField faults; + caf::PdmChildArrayField faults; RimFault* findFaultByName(QString name); - caf::PdmField noCommonAreaNnncCollection; + caf::PdmChildField noCommonAreaNnncCollection; virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue); virtual caf::PdmFieldHandle* objectToggleField(); diff --git a/ApplicationCode/ProjectDataModel/RimGeoMechCase.cpp b/ApplicationCode/ProjectDataModel/RimGeoMechCase.cpp index d8cf7a4680..9dbefc6a3b 100644 --- a/ApplicationCode/ProjectDataModel/RimGeoMechCase.cpp +++ b/ApplicationCode/ProjectDataModel/RimGeoMechCase.cpp @@ -23,6 +23,11 @@ #include "RiaPreferences.h" #include "RifOdbReader.h" #include "RigGeoMechCaseData.h" +#include "RigFemPartResultsCollection.h" +#include "RimProject.h" +#include "RimMainPlotCollection.h" +#include "RimWellLogPlotCollection.h" + #include CAF_PDM_SOURCE_INIT(RimGeoMechCase, "ResInsightGeoMechCase"); @@ -34,9 +39,9 @@ RimGeoMechCase::RimGeoMechCase(void) CAF_PDM_InitObject("Geomechanical Case", ":/GeoMechCase48x48.png", "", ""); CAF_PDM_InitField(&m_caseFileName, "CaseFileName", QString(), "Case file name", "", "", ""); - m_caseFileName.setUiReadOnly(true); + m_caseFileName.uiCapability()->setUiReadOnly(true); CAF_PDM_InitFieldNoDefault(&geoMechViews, "GeoMechViews", "", "", "", ""); - + geoMechViews.uiCapability()->setUiHidden(true); } //-------------------------------------------------------------------------------------------------- @@ -45,6 +50,25 @@ RimGeoMechCase::RimGeoMechCase(void) RimGeoMechCase::~RimGeoMechCase(void) { geoMechViews.deleteAllChildObjects(); + + RimProject* project = RiaApplication::instance()->project(); + if (project) + { + if (project->mainPlotCollection()) + { + RimWellLogPlotCollection* plotCollection = project->mainPlotCollection()->wellLogPlotCollection(); + if (plotCollection) + { + plotCollection->removeExtractors(this->geoMechData()); + } + } + } + + if (this->geoMechData()) + { + // At this point, we assume that memory should be released + CVF_ASSERT(this->geoMechData()->refCount() == 1); + } } //-------------------------------------------------------------------------------------------------- @@ -129,3 +153,19 @@ void RimGeoMechCase::initAfterRead() } } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QStringList RimGeoMechCase::timeStepStrings() +{ + QStringList stringList; + + std::vector stepNames = geoMechData()->femPartResults()->stepNames(); + for (size_t i = 0; i < stepNames.size(); i++) + { + stringList += QString::fromStdString(stepNames[i]); + } + + return stringList; +} diff --git a/ApplicationCode/ProjectDataModel/RimGeoMechCase.h b/ApplicationCode/ProjectDataModel/RimGeoMechCase.h index 0f6a39bfed..49eba64147 100644 --- a/ApplicationCode/ProjectDataModel/RimGeoMechCase.h +++ b/ApplicationCode/ProjectDataModel/RimGeoMechCase.h @@ -18,11 +18,14 @@ ///////////////////////////////////////////////////////////////////////////////// #pragma once + #include "RimCase.h" +#include "cafPdmChildArrayField.h" #include "cafPdmField.h" #include "cafPdmObject.h" #include "cafPdmPointer.h" + #include "cvfObject.h" class RimGeoMechView; @@ -53,8 +56,11 @@ class RimGeoMechCase : public RimCase virtual void updateFilePathsFromProjectPath(const QString& projectPath, const QString& oldProjectPath); virtual std::vector views(); + virtual QStringList timeStepStrings(); + + // Fields: - caf::PdmPointersField geoMechViews; + caf::PdmChildArrayField geoMechViews; private: virtual void initAfterRead(); diff --git a/ApplicationCode/ProjectDataModel/RimGeoMechCellColors.cpp b/ApplicationCode/ProjectDataModel/RimGeoMechCellColors.cpp index f4c3fba9f6..fa1e58a3ab 100644 --- a/ApplicationCode/ProjectDataModel/RimGeoMechCellColors.cpp +++ b/ApplicationCode/ProjectDataModel/RimGeoMechCellColors.cpp @@ -18,8 +18,11 @@ ///////////////////////////////////////////////////////////////////////////////// #include "RimGeoMechCellColors.h" + #include "RimLegendConfig.h" #include "RimView.h" +#include "RimViewController.h" +#include "RimViewLinker.h" CAF_PDM_SOURCE_INIT(RimGeoMechCellColors, "GeoMechResultSlot"); @@ -32,6 +35,7 @@ RimGeoMechCellColors::RimGeoMechCellColors(void) { CAF_PDM_InitFieldNoDefault(&legendConfig, "LegendDefinition", "Legend Definition", "", "", ""); this->legendConfig = new RimLegendConfig(); + legendConfig.uiCapability()->setUiHidden(true); } //-------------------------------------------------------------------------------------------------- @@ -40,3 +44,33 @@ RimGeoMechCellColors::RimGeoMechCellColors(void) RimGeoMechCellColors::~RimGeoMechCellColors(void) { } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimGeoMechCellColors::updateIconState() +{ + RimView* rimView = NULL; + this->firstAnchestorOrThisOfType(rimView); + CVF_ASSERT(rimView); + + RimViewController* viewController = rimView->viewController(); + if (viewController && viewController->isResultColorControlled()) + { + updateUiIconFromState(false); + } + else + { + updateUiIconFromState(true); + } + + uiCapability()->updateConnectedEditors(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimGeoMechCellColors::initAfterRead() +{ + updateIconState(); +} diff --git a/ApplicationCode/ProjectDataModel/RimGeoMechCellColors.h b/ApplicationCode/ProjectDataModel/RimGeoMechCellColors.h index 99d57fa6de..f718382963 100644 --- a/ApplicationCode/ProjectDataModel/RimGeoMechCellColors.h +++ b/ApplicationCode/ProjectDataModel/RimGeoMechCellColors.h @@ -20,6 +20,8 @@ #pragma once #include "RimGeoMechResultDefinition.h" + +#include "cafPdmChildField.h" #include "cafPdmField.h" class RimLegendConfig; @@ -37,5 +39,8 @@ class RimGeoMechCellColors : public RimGeoMechResultDefinition RimGeoMechCellColors(void); virtual ~RimGeoMechCellColors(void); - caf::PdmField legendConfig; + caf::PdmChildField legendConfig; + + void updateIconState(); + virtual void initAfterRead(); }; diff --git a/ApplicationCode/ProjectDataModel/RimGeoMechModels.cpp b/ApplicationCode/ProjectDataModel/RimGeoMechModels.cpp index a24570d0f3..b467e2c393 100644 --- a/ApplicationCode/ProjectDataModel/RimGeoMechModels.cpp +++ b/ApplicationCode/ProjectDataModel/RimGeoMechModels.cpp @@ -31,6 +31,7 @@ RimGeoMechModels::RimGeoMechModels(void) CAF_PDM_InitObject("Geomechanical Models", ":/GeoMechCases48x48.png", "", ""); CAF_PDM_InitFieldNoDefault(&cases, "Cases", "", "", "", ""); + cases.uiCapability()->setUiHidden(true); } diff --git a/ApplicationCode/ProjectDataModel/RimGeoMechModels.h b/ApplicationCode/ProjectDataModel/RimGeoMechModels.h index aa81ca5b0c..e96288bfee 100644 --- a/ApplicationCode/ProjectDataModel/RimGeoMechModels.h +++ b/ApplicationCode/ProjectDataModel/RimGeoMechModels.h @@ -19,6 +19,7 @@ #pragma once +#include "cafPdmChildArrayField.h" #include "cafPdmField.h" #include "cafPdmObject.h" #include "cafPdmPointer.h" @@ -37,7 +38,7 @@ class RimGeoMechModels : public caf::PdmObject RimGeoMechModels(void); virtual ~RimGeoMechModels(void); - caf::PdmPointersField cases; + caf::PdmChildArrayField cases; private: }; diff --git a/ApplicationCode/ProjectDataModel/RimGeoMechPropertyFilter.cpp b/ApplicationCode/ProjectDataModel/RimGeoMechPropertyFilter.cpp index f0f63c4655..74e58f210e 100644 --- a/ApplicationCode/ProjectDataModel/RimGeoMechPropertyFilter.cpp +++ b/ApplicationCode/ProjectDataModel/RimGeoMechPropertyFilter.cpp @@ -18,18 +18,21 @@ ///////////////////////////////////////////////////////////////////////////////// #include "RimGeoMechPropertyFilter.h" -#include "RimGeoMechPropertyFilterCollection.h" -#include "RimGeoMechResultDefinition.h" - -#include "cvfMath.h" -#include "cafPdmUiDoubleSliderEditor.h" -#include "cvfAssert.h" #include "RigFemPartResultsCollection.h" #include "RigGeoMechCaseData.h" + +#include "RimGeoMechPropertyFilterCollection.h" +#include "RimGeoMechResultDefinition.h" #include "RimGeoMechView.h" +#include "RimViewController.h" + #include "RiuMainWindow.h" +#include "cafPdmUiDoubleSliderEditor.h" + +#include "cvfAssert.h" +#include "cvfMath.h" CAF_PDM_SOURCE_INIT(RimGeoMechPropertyFilter, "GeoMechPropertyFilter"); @@ -39,27 +42,26 @@ CAF_PDM_SOURCE_INIT(RimGeoMechPropertyFilter, "GeoMechPropertyFilter"); RimGeoMechPropertyFilter::RimGeoMechPropertyFilter() : m_parentContainer(NULL) { - CAF_PDM_InitObject("GeoMech Property Filter", ":/CellFilter_Values.png", "", ""); + CAF_PDM_InitObject("Property Filter", ":/CellFilter_Values.png", "", ""); CAF_PDM_InitFieldNoDefault(&resultDefinition, "ResultDefinition", "Result definition", "", "", ""); resultDefinition = new RimGeoMechResultDefinition(); - resultDefinition->setOwnerPropertyFilter(this); // Set to hidden to avoid this item to been displayed as a child item // Fields in this object are displayed using defineUiOrdering() - resultDefinition.setUiHidden(true); + resultDefinition.uiCapability()->setUiHidden(true); + resultDefinition.uiCapability()->setUiChildrenHidden(true); CAF_PDM_InitField(&lowerBound, "LowerBound", 0.0, "Min", "", "", ""); - lowerBound.setUiEditorTypeName(caf::PdmUiDoubleSliderEditor::uiEditorTypeName()); + lowerBound.uiCapability()->setUiEditorTypeName(caf::PdmUiDoubleSliderEditor::uiEditorTypeName()); CAF_PDM_InitField(&upperBound, "UpperBound", 0.0, "Max", "", "", ""); - upperBound.setUiEditorTypeName(caf::PdmUiDoubleSliderEditor::uiEditorTypeName()); + upperBound.uiCapability()->setUiEditorTypeName(caf::PdmUiDoubleSliderEditor::uiEditorTypeName()); updateIconState(); m_minimumResultValue = cvf::UNDEFINED_DOUBLE; m_maximumResultValue = cvf::UNDEFINED_DOUBLE; - } //-------------------------------------------------------------------------------------------------- @@ -81,8 +83,9 @@ void RimGeoMechPropertyFilter::fieldChangedByUi(const caf::PdmFieldHandle* chang { this->updateIconState(); this->updateFilterName(); - ((RimView*)resultDefinition->reservoirView())->scheduleGeometryRegen(PROPERTY_FILTERED); - resultDefinition->reservoirView()->scheduleCreateDisplayModelAndRedraw(); + this->uiCapability()->updateConnectedEditors(); + + parentContainer()->updateDisplayModelNotifyManagedViews(); } } @@ -133,6 +136,65 @@ void RimGeoMechPropertyFilter::defineUiOrdering(QString uiConfigName, caf::PdmUi uiOrdering.add(&lowerBound); uiOrdering.add(&upperBound); uiOrdering.add(&filterMode); + + updateReadOnlyStateOfAllFields(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimGeoMechPropertyFilter::defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName) +{ + PdmObject::defineUiTreeOrdering(uiTreeOrdering, uiConfigName); + + updateActiveState(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimGeoMechPropertyFilter::updateReadOnlyStateOfAllFields() +{ + bool readOnlyState = isPropertyFilterControlled(); + + std::vector objFields; + this->fields(objFields); + + // Include fields declared in RimResultDefinition + objFields.push_back(&(resultDefinition->m_resultPositionTypeUiField)); + objFields.push_back(&(resultDefinition->m_resultVariableUiField)); + + for (size_t i = 0; i < objFields.size(); i++) + { + objFields[i]->uiCapability()->setUiReadOnly(readOnlyState); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimGeoMechPropertyFilter::isPropertyFilterControlled() +{ + RimView* rimView = NULL; + firstAnchestorOrThisOfType(rimView); + CVF_ASSERT(rimView); + + bool isPropertyFilterControlled = false; + RimViewController* vc = rimView->viewController(); + if (vc && vc->isPropertyFilterOveridden()) + { + isPropertyFilterControlled = true; + } + + return isPropertyFilterControlled; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimGeoMechPropertyFilter::updateActiveState() +{ + isActive.uiCapability()->setUiReadOnly(isPropertyFilterControlled()); } //-------------------------------------------------------------------------------------------------- @@ -177,8 +239,8 @@ void RimGeoMechPropertyFilter::computeResultValueRange() m_maximumResultValue = max; m_minimumResultValue = min; - lowerBound.setUiName(QString("Min (%1)").arg(min)); - upperBound.setUiName(QString("Max (%1)").arg(max)); + lowerBound.uiCapability()->setUiName(QString("Min (%1)").arg(min)); + upperBound.uiCapability()->setUiName(QString("Max (%1)").arg(max)); } //-------------------------------------------------------------------------------------------------- @@ -197,10 +259,14 @@ void RimGeoMechPropertyFilter::updateFilterName() case RIG_INTEGRATION_POINT: posName = "IP"; break; } - newFiltername = posName + ", " + QString::fromStdString(resultAddress.fieldName + ", " + resultAddress.componentName) + " (" + QString fieldUiName = resultDefinition->resultFieldUiName(); + QString compoUiName = resultDefinition->resultComponentUiName(); + + + newFiltername = posName + ", " + fieldUiName + ", " + compoUiName + " (" + QString::number(lowerBound()) + " .. " + QString::number(upperBound) + ")"; this->name = newFiltername; - RiuMainWindow::instance()->forceProjectTreeRepaint(); + uiCapability()->updateConnectedEditors(); } diff --git a/ApplicationCode/ProjectDataModel/RimGeoMechPropertyFilter.h b/ApplicationCode/ProjectDataModel/RimGeoMechPropertyFilter.h index fe55e097ce..3551a31a6e 100644 --- a/ApplicationCode/ProjectDataModel/RimGeoMechPropertyFilter.h +++ b/ApplicationCode/ProjectDataModel/RimGeoMechPropertyFilter.h @@ -21,6 +21,8 @@ #include "RimCellFilter.h" +#include "cafPdmChildField.h" + class RimGeoMechResultDefinition; class RimGeoMechPropertyFilterCollection; @@ -37,7 +39,7 @@ class RimGeoMechPropertyFilter : public RimCellFilter RimGeoMechPropertyFilter(); virtual ~RimGeoMechPropertyFilter(); - caf::PdmField resultDefinition; + caf::PdmChildField resultDefinition; caf::PdmField lowerBound; caf::PdmField upperBound; @@ -48,11 +50,18 @@ class RimGeoMechPropertyFilter : public RimCellFilter void updateFilterName(); void computeResultValueRange(); - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue); + void updateActiveState(); + protected: + virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue); virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) ; + virtual void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName); virtual void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute); +private: + void updateReadOnlyStateOfAllFields(); + bool isPropertyFilterControlled(); + private: RimGeoMechPropertyFilterCollection* m_parentContainer; double m_minimumResultValue; diff --git a/ApplicationCode/ProjectDataModel/RimGeoMechPropertyFilterCollection.cpp b/ApplicationCode/ProjectDataModel/RimGeoMechPropertyFilterCollection.cpp index 23ef62f21b..97545ce789 100644 --- a/ApplicationCode/ProjectDataModel/RimGeoMechPropertyFilterCollection.cpp +++ b/ApplicationCode/ProjectDataModel/RimGeoMechPropertyFilterCollection.cpp @@ -18,9 +18,12 @@ ///////////////////////////////////////////////////////////////////////////////// #include "RimGeoMechPropertyFilterCollection.h" + +#include "RimGeoMechCellColors.h" #include "RimGeoMechPropertyFilter.h" #include "RimGeoMechView.h" -#include "RimGeoMechCellColors.h" +#include "RimViewController.h" +#include "RimViewLinker.h" #include "cvfAssert.h" @@ -32,34 +35,21 @@ CAF_PDM_SOURCE_INIT(RimGeoMechPropertyFilterCollection, "GeoMechPropertyFilters" //-------------------------------------------------------------------------------------------------- RimGeoMechPropertyFilterCollection::RimGeoMechPropertyFilterCollection() { - CAF_PDM_InitObject("GeoMech Property Filters", ":/CellFilter_Values.png", "", ""); + CAF_PDM_InitObject("Property Filters", ":/CellFilter_Values.png", "", ""); CAF_PDM_InitFieldNoDefault(&propertyFilters, "PropertyFilters", "Property Filters", "", "", ""); - CAF_PDM_InitField(&active, "Active", true, "Active", "", "", ""); - active.setUiHidden(true); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RimGeoMechPropertyFilterCollection::~RimGeoMechPropertyFilterCollection() -{ + propertyFilters.uiCapability()->setUiHidden(true); + CAF_PDM_InitField(&isActive, "Active", true, "Active", "", "", ""); + isActive.uiCapability()->setUiHidden(true); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimGeoMechPropertyFilterCollection::setReservoirView(RimGeoMechView* reservoirView) +RimGeoMechPropertyFilterCollection::~RimGeoMechPropertyFilterCollection() { - m_reservoirView = reservoirView; - for (size_t i = 0; i < propertyFilters.size(); i++) - { - RimGeoMechPropertyFilter* propertyFilter = propertyFilters[i]; - propertyFilter->resultDefinition->setReservoirView(m_reservoirView.p()); - - } } //-------------------------------------------------------------------------------------------------- @@ -67,43 +57,23 @@ void RimGeoMechPropertyFilterCollection::setReservoirView(RimGeoMechView* reserv //-------------------------------------------------------------------------------------------------- RimGeoMechView* RimGeoMechPropertyFilterCollection::reservoirView() { - CVF_ASSERT(!m_reservoirView.isNull()); - return m_reservoirView; + RimGeoMechView* geoMechView = NULL; + firstAnchestorOrThisOfType(geoMechView); + + return geoMechView; } - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimGeoMechPropertyFilterCollection::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) { - this->updateUiIconFromToggleField(); + updateIconState(); + uiCapability()->updateConnectedEditors(); - ((RimView*)m_reservoirView)->scheduleGeometryRegen(PROPERTY_FILTERED); - m_reservoirView->scheduleCreateDisplayModelAndRedraw(); + updateDisplayModelNotifyManagedViews(); } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RimGeoMechPropertyFilter* RimGeoMechPropertyFilterCollection::createAndAppendPropertyFilter() -{ - RimGeoMechPropertyFilter* propertyFilter = new RimGeoMechPropertyFilter(); - - propertyFilter->resultDefinition->setReservoirView(m_reservoirView.p()); - - propertyFilter->setParentContainer(this); - propertyFilters.push_back(propertyFilter); - - propertyFilter->resultDefinition->setResultAddress(m_reservoirView->cellResult()->resultAddress()); - propertyFilter->resultDefinition->loadResult(); - propertyFilter->setToDefaultValues(); - propertyFilter->updateFilterName(); - - return propertyFilter; -} - - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -112,7 +82,7 @@ void RimGeoMechPropertyFilterCollection::loadAndInitializePropertyFilters() for (size_t i = 0; i < propertyFilters.size(); i++) { RimGeoMechPropertyFilter* propertyFilter = propertyFilters[i]; - + propertyFilter->resultDefinition->setGeoMechCase(reservoirView()->geoMechCase()); propertyFilter->resultDefinition->loadResult(); propertyFilter->computeResultValueRange(); } @@ -128,19 +98,11 @@ void RimGeoMechPropertyFilterCollection::initAfterRead() RimGeoMechPropertyFilter* propertyFilter = propertyFilters[i]; propertyFilter->setParentContainer(this); - propertyFilter->resultDefinition->setReservoirView(m_reservoirView.p()); + propertyFilter->resultDefinition->setGeoMechCase(reservoirView()->geoMechCase()); propertyFilter->updateIconState(); } - this->updateUiIconFromToggleField(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimGeoMechPropertyFilterCollection::remove(RimGeoMechPropertyFilter* propertyFilter) -{ - propertyFilters.removeChildObject(propertyFilter); + updateIconState(); } //-------------------------------------------------------------------------------------------------- @@ -148,7 +110,7 @@ void RimGeoMechPropertyFilterCollection::remove(RimGeoMechPropertyFilter* proper //-------------------------------------------------------------------------------------------------- bool RimGeoMechPropertyFilterCollection::hasActiveFilters() const { - if (!active) return false; + if (!isActive) return false; for (size_t i = 0; i < propertyFilters.size(); i++) { @@ -167,11 +129,77 @@ bool RimGeoMechPropertyFilterCollection::hasActiveDynamicFilters() const return hasActiveFilters(); } - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- caf::PdmFieldHandle* RimGeoMechPropertyFilterCollection::objectToggleField() { - return &active; + return &isActive; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimGeoMechPropertyFilterCollection::updateDisplayModelNotifyManagedViews() +{ + RimGeoMechView* view = NULL; + this->firstAnchestorOrThisOfType(view); + CVF_ASSERT(view); + + view->scheduleGeometryRegen(PROPERTY_FILTERED); + view->scheduleCreateDisplayModelAndRedraw(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimGeoMechPropertyFilterCollection::updateIconState() +{ + bool activeIcon = true; + + RimGeoMechView* view = NULL; + this->firstAnchestorOrThisOfType(view); + RimViewController* viewController = view->viewController(); + if (viewController && ( viewController->isPropertyFilterOveridden() + || viewController->isVisibleCellsOveridden())) + { + activeIcon = false; + } + + if (!isActive) + { + activeIcon = false; + } + + updateUiIconFromState(activeIcon); + + for (size_t i = 0; i < propertyFilters.size(); i++) + { + RimGeoMechPropertyFilter* propFilter = propertyFilters[i]; + propFilter->updateActiveState(); + propFilter->updateIconState(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimGeoMechPropertyFilterCollection::defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName) +{ + PdmObject::defineUiTreeOrdering(uiTreeOrdering, uiConfigName); + + RimView* rimView = NULL; + this->firstAnchestorOrThisOfType(rimView); + RimViewController* viewController = rimView->viewController(); + if (viewController && (viewController->isPropertyFilterOveridden() + || viewController->isVisibleCellsOveridden())) + { + isActive.uiCapability()->setUiReadOnly(true, uiConfigName); + } + else + { + isActive.uiCapability()->setUiReadOnly(false, uiConfigName); + } + + updateIconState(); } diff --git a/ApplicationCode/ProjectDataModel/RimGeoMechPropertyFilterCollection.h b/ApplicationCode/ProjectDataModel/RimGeoMechPropertyFilterCollection.h index 521dee9570..f26d9c7d18 100644 --- a/ApplicationCode/ProjectDataModel/RimGeoMechPropertyFilterCollection.h +++ b/ApplicationCode/ProjectDataModel/RimGeoMechPropertyFilterCollection.h @@ -19,8 +19,9 @@ #pragma once -#include "cafPdmObject.h" +#include "cafPdmChildArrayField.h" #include "cafPdmField.h" +#include "cafPdmObject.h" #include "cafPdmPointer.h" class RimGeoMechPropertyFilter; @@ -37,33 +38,24 @@ class RimGeoMechPropertyFilterCollection : public caf::PdmObject RimGeoMechPropertyFilterCollection(); virtual ~RimGeoMechPropertyFilterCollection(); - void setReservoirView(RimGeoMechView* reservoirView); RimGeoMechView* reservoirView(); - // Fields: - caf::PdmField active; - caf::PdmPointersField propertyFilters; + caf::PdmField isActive; + caf::PdmChildArrayField propertyFilters; // Methods - RimGeoMechPropertyFilter* createAndAppendPropertyFilter(); - void remove(RimGeoMechPropertyFilter* propertyFilter); - bool hasActiveFilters() const; bool hasActiveDynamicFilters() const; - void loadAndInitializePropertyFilters(); + void updateDisplayModelNotifyManagedViews(); + void updateIconState(); - +protected: // Overridden methods virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue); + virtual void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName); virtual caf::PdmFieldHandle* objectToggleField(); - -protected: - // Overridden methods - virtual void initAfterRead(); - -private: - caf::PdmPointer m_reservoirView; + virtual void initAfterRead(); }; diff --git a/ApplicationCode/ProjectDataModel/RimGeoMechResultDefinition.cpp b/ApplicationCode/ProjectDataModel/RimGeoMechResultDefinition.cpp index bb9f76ac52..1ea9ba925d 100644 --- a/ApplicationCode/ProjectDataModel/RimGeoMechResultDefinition.cpp +++ b/ApplicationCode/ProjectDataModel/RimGeoMechResultDefinition.cpp @@ -18,16 +18,22 @@ ///////////////////////////////////////////////////////////////////////////////// #include "RimGeoMechResultDefinition.h" -#include "RimGeoMechView.h" -#include "RimDefines.h" -#include "RimGeoMechCase.h" + #include "RifGeoMechReaderInterface.h" -#include "cafPdmUiListEditor.h" -#include "RigGeoMechCaseData.h" + #include "RigFemPartResultsCollection.h" -#include "RiuMainWindow.h" -#include "RimGeoMechPropertyFilter.h" #include "RigFemResultAddress.h" +#include "RigGeoMechCaseData.h" + +#include "RimDefines.h" +#include "RimGeoMechCase.h" +#include "RimGeoMechCellColors.h" +#include "RimGeoMechPropertyFilter.h" +#include "RimGeoMechView.h" +#include "RimViewLinker.h" +#include "RimWellLogPlotCurve.h" + +#include "cafPdmUiListEditor.h" namespace caf { @@ -53,22 +59,22 @@ RimGeoMechResultDefinition::RimGeoMechResultDefinition(void) CAF_PDM_InitObject("Color Result", ":/CellResult.png", "", ""); CAF_PDM_InitFieldNoDefault(&m_resultPositionType, "ResultPositionType" , "Result Position", "", "", ""); - m_resultPositionType.setUiHidden(true); + m_resultPositionType.uiCapability()->setUiHidden(true); CAF_PDM_InitField(&m_resultFieldName, "ResultFieldName", QString(""), "Field Name", "", "", ""); - m_resultFieldName.setUiHidden(true); + m_resultFieldName.uiCapability()->setUiHidden(true); CAF_PDM_InitField(&m_resultComponentName, "ResultComponentName", QString(""), "Component", "", "", ""); - m_resultComponentName.setUiHidden(true); + m_resultComponentName.uiCapability()->setUiHidden(true); CAF_PDM_InitFieldNoDefault(&m_resultPositionTypeUiField, "ResultPositionTypeUi", "Result Position", "", "", ""); - m_resultPositionTypeUiField.setIOWritable(false); - m_resultPositionTypeUiField.setIOReadable(false); + m_resultPositionTypeUiField.xmlCapability()->setIOWritable(false); + m_resultPositionTypeUiField.xmlCapability()->setIOReadable(false); CAF_PDM_InitField(&m_resultVariableUiField, "ResultVariableUI", QString(""), "Value", "", "", ""); - m_resultVariableUiField.setIOWritable(false); - m_resultVariableUiField.setIOReadable(false); + m_resultVariableUiField.xmlCapability()->setIOWritable(false); + m_resultVariableUiField.xmlCapability()->setIOReadable(false); - m_resultVariableUiField.setUiEditorTypeName(caf::PdmUiListEditor::uiEditorTypeName()); - m_resultVariableUiField.setUiLabelPosition(caf::PdmUiItemInfo::TOP); + m_resultVariableUiField.uiCapability()->setUiEditorTypeName(caf::PdmUiListEditor::uiEditorTypeName()); + m_resultVariableUiField.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::TOP); } //-------------------------------------------------------------------------------------------------- @@ -87,11 +93,8 @@ QList RimGeoMechResultDefinition::calculateValueOptions( QList options; *useOptionsOnly = true; - if (m_reservoirView) + if (m_geomCase) { - - - if (&m_resultVariableUiField == fieldNeedingOptions) { std::map > fieldCompNames = getResultMetaDataForUIFieldSetting(); @@ -103,19 +106,6 @@ QList RimGeoMechResultDefinition::calculateValueOptions( { options.push_back(caf::PdmOptionItemInfo(uiVarNames[oIdx], varNames[oIdx])); } - -#if 0 - - for (auto fieldIt = fieldCompNames.begin(); fieldIt != fieldCompNames.end(); ++fieldIt) - { - options.push_back(caf::PdmOptionItemInfo(QString::fromStdString(fieldIt->first), QString::fromStdString(fieldIt->first))); - - for (auto compIt = fieldIt->second.begin(); compIt != fieldIt->second.end(); ++compIt) - { - options.push_back(caf::PdmOptionItemInfo(QString::fromStdString(" " + *compIt), QString::fromStdString(fieldIt->first + " " + *compIt))); - } - } -#endif } } @@ -123,24 +113,15 @@ QList RimGeoMechResultDefinition::calculateValueOptions( } - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimGeoMechResultDefinition::setReservoirView(RimGeoMechView* ownerReservoirView) +void RimGeoMechResultDefinition::setGeoMechCase(RimGeoMechCase* geomCase) { - m_reservoirView = ownerReservoirView; + m_geomCase = geomCase; } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RimGeoMechView* RimGeoMechResultDefinition::reservoirView() -{ - return m_reservoirView; -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -154,9 +135,9 @@ void RimGeoMechResultDefinition::fieldChangedByUi(const caf::PdmFieldHandle* cha getUiAndResultVariableStringList(&uiVarNames, &varNames, fieldCompNames); if (m_resultPositionTypeUiField() == m_resultPositionType() - && varNames.contains(composeUiVarString(m_resultFieldName(), m_resultComponentName()))) + && varNames.contains(composeFieldCompString(m_resultFieldName(), m_resultComponentName()))) { - m_resultVariableUiField = composeUiVarString(m_resultFieldName(), m_resultComponentName()); + m_resultVariableUiField = composeFieldCompString(m_resultFieldName(), m_resultComponentName()); } else { @@ -165,6 +146,14 @@ void RimGeoMechResultDefinition::fieldChangedByUi(const caf::PdmFieldHandle* cha } + // Get the possible property filter owner + RimGeoMechPropertyFilter* propFilter = dynamic_cast(this->parentField()->ownerObject()); + RimView* view = NULL; + this->firstAnchestorOrThisOfType(view); + RimWellLogPlotCurve* curve = NULL; + this->firstAnchestorOrThisOfType(curve); + + if (&m_resultVariableUiField == changedField) { QStringList fieldComponentNames = m_resultVariableUiField().split(QRegExp("\\s+")); @@ -181,27 +170,49 @@ void RimGeoMechResultDefinition::fieldChangedByUi(const caf::PdmFieldHandle* cha m_resultComponentName = ""; } - if (m_reservoirView->geoMechCase()->geoMechData()->femPartResults()->assertResultsLoaded(this->resultAddress())) + + if (m_geomCase->geoMechData()->femPartResults()->assertResultsLoaded(this->resultAddress())) { - m_reservoirView->hasUserRequestedAnimation = true; + if (view) view->hasUserRequestedAnimation = true; } - if (m_propertyFilter) + if (propFilter) { - m_propertyFilter->setToDefaultValues(); + propFilter->setToDefaultValues(); + + if (view) view->scheduleGeometryRegen(PROPERTY_FILTERED); + } + + if (view) view->scheduleCreateDisplayModelAndRedraw(); - ((RimView*)reservoirView())->scheduleGeometryRegen(PROPERTY_FILTERED); + if (dynamic_cast(this)) + { + if (view) + { + RimViewLinker* viewLinker = view->assosiatedViewLinker(); + if (viewLinker) + { + viewLinker->updateCellResult(); + } + } } - reservoirView()->scheduleCreateDisplayModelAndRedraw(); + if (curve) + { + curve->updatePlotData(); + } } } - - if (m_propertyFilter) + + if (propFilter) { - m_propertyFilter->updateConnectedEditors(); + propFilter->updateConnectedEditors(); } + if (curve) + { + curve->updateConnectedEditors(); + } } //-------------------------------------------------------------------------------------------------- @@ -209,7 +220,7 @@ void RimGeoMechResultDefinition::fieldChangedByUi(const caf::PdmFieldHandle* cha //-------------------------------------------------------------------------------------------------- std::map > RimGeoMechResultDefinition::getResultMetaDataForUIFieldSetting() { - RimGeoMechCase* gmCase = m_reservoirView->geoMechCase(); + RimGeoMechCase* gmCase = m_geomCase; if (gmCase && gmCase->geoMechData()) { return gmCase->geoMechData()->femPartResults()->scalarFieldAndComponentNames(m_resultPositionTypeUiField()); @@ -233,7 +244,7 @@ void RimGeoMechResultDefinition::getUiAndResultVariableStringList(QStringList* u { QString resultFieldName = QString::fromStdString(fieldIt->first); - if (resultFieldName == "E" || resultFieldName == "S") continue; // We will not show the native Stress and Strain + if (resultFieldName == "E" || resultFieldName == "S" || resultFieldName == "POR") continue; // We will not show the native POR, Stress and Strain QString resultFieldUiName = convertToUiResultFieldName(resultFieldName); @@ -244,8 +255,8 @@ void RimGeoMechResultDefinition::getUiAndResultVariableStringList(QStringList* u for (compIt = fieldIt->second.begin(); compIt != fieldIt->second.end(); ++compIt) { QString resultCompName = QString::fromStdString(*compIt); - uiNames->push_back(" " + resultCompName); - variableNames->push_back(composeUiVarString(resultFieldName, resultCompName)); + uiNames->push_back(" " + convertToUIComponentName(resultCompName)); + variableNames->push_back(composeFieldCompString(resultFieldName, resultCompName)); } } } @@ -254,9 +265,12 @@ void RimGeoMechResultDefinition::getUiAndResultVariableStringList(QStringList* u //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QString RimGeoMechResultDefinition::composeUiVarString(const QString& resultFieldName, const QString& resultComponentName) +QString RimGeoMechResultDefinition::composeFieldCompString(const QString& resultFieldName, const QString& resultComponentName) { - return resultFieldName + " " + resultComponentName; + if (resultComponentName.isEmpty()) + return resultFieldName; + else + return resultFieldName + " " + resultComponentName; } //-------------------------------------------------------------------------------------------------- @@ -265,7 +279,7 @@ QString RimGeoMechResultDefinition::composeUiVarString(const QString& resultFiel void RimGeoMechResultDefinition::initAfterRead() { m_resultPositionTypeUiField = m_resultPositionType; - m_resultVariableUiField = composeUiVarString(m_resultFieldName(), m_resultComponentName()); + m_resultVariableUiField = composeFieldCompString(m_resultFieldName(), m_resultComponentName()); } @@ -275,9 +289,9 @@ void RimGeoMechResultDefinition::initAfterRead() //-------------------------------------------------------------------------------------------------- void RimGeoMechResultDefinition::loadResult() { - if (m_reservoirView->geoMechCase()) + if (m_geomCase) { - m_reservoirView->geoMechCase()->geoMechData()->femPartResults()->assertResultsLoaded(this->resultAddress()); + m_geomCase->geoMechData()->femPartResults()->assertResultsLoaded(this->resultAddress()); } } @@ -286,11 +300,11 @@ void RimGeoMechResultDefinition::loadResult() //-------------------------------------------------------------------------------------------------- RigGeoMechCaseData* RimGeoMechResultDefinition::ownerCaseData() { - return m_reservoirView->geoMechCase()->geoMechData(); + return m_geomCase->geoMechData(); } //-------------------------------------------------------------------------------------------------- -/// +/// Is the result probably valid and possible to load //-------------------------------------------------------------------------------------------------- bool RimGeoMechResultDefinition::hasResult() { @@ -311,7 +325,7 @@ QString RimGeoMechResultDefinition::resultFieldUiName() //-------------------------------------------------------------------------------------------------- QString RimGeoMechResultDefinition::resultComponentUiName() { - return m_resultComponentName(); + return convertToUIComponentName(m_resultComponentName()); } //-------------------------------------------------------------------------------------------------- @@ -322,6 +336,7 @@ QString RimGeoMechResultDefinition::convertToUiResultFieldName(QString resultFie if (resultFieldName == "E") return "NativeAbaqus Strain"; if (resultFieldName == "S") return "NativeAbaqus Stress"; if (resultFieldName == "NE") return "E"; // Make NE and NS appear as E and SE + if (resultFieldName == "POR-Bar") return "POR"; // POR-Bar appear as POR return resultFieldName; } @@ -329,9 +344,9 @@ QString RimGeoMechResultDefinition::convertToUiResultFieldName(QString resultFie //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimGeoMechResultDefinition::setOwnerPropertyFilter( RimGeoMechPropertyFilter* propertyFilter ) +QString RimGeoMechResultDefinition::convertToUIComponentName(QString resultComponentName) { - m_propertyFilter = propertyFilter; + return resultComponentName; } //-------------------------------------------------------------------------------------------------- @@ -344,5 +359,5 @@ void RimGeoMechResultDefinition::setResultAddress( const RigFemResultAddress& re m_resultComponentName = QString::fromStdString(resultAddress.componentName); m_resultPositionTypeUiField = m_resultPositionType; - m_resultVariableUiField = composeUiVarString(m_resultFieldName(), m_resultComponentName()); + m_resultVariableUiField = composeFieldCompString(m_resultFieldName(), m_resultComponentName()); } diff --git a/ApplicationCode/ProjectDataModel/RimGeoMechResultDefinition.h b/ApplicationCode/ProjectDataModel/RimGeoMechResultDefinition.h index d1d58674ad..f4470dfa3c 100644 --- a/ApplicationCode/ProjectDataModel/RimGeoMechResultDefinition.h +++ b/ApplicationCode/ProjectDataModel/RimGeoMechResultDefinition.h @@ -30,6 +30,7 @@ class RimGeoMechView; class RimGeoMechPropertyFilter; class RifGeoMechReaderInterface; class RigGeoMechCaseData; +class RimGeoMechCase; //================================================================================================== /// @@ -43,8 +44,7 @@ class RimGeoMechResultDefinition : public caf::PdmObject RimGeoMechResultDefinition(void); virtual ~RimGeoMechResultDefinition(void); - void setReservoirView(RimGeoMechView* ownerReservoirView); - RimGeoMechView* reservoirView(); + void setGeoMechCase(RimGeoMechCase* geomCase); RigGeoMechCaseData* ownerCaseData(); bool hasResult(); @@ -57,14 +57,11 @@ class RimGeoMechResultDefinition : public caf::PdmObject QString resultComponentName() { return m_resultComponentName();} void setResultAddress(const RigFemResultAddress& resultAddress); - void setOwnerPropertyFilter(RimGeoMechPropertyFilter* propertyFilter); - QString resultFieldUiName(); QString resultComponentUiName(); protected: - friend class RimGeoMechPropertyFilter; // Property filter needs the ui fields - + private: virtual QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly); @@ -73,7 +70,7 @@ class RimGeoMechResultDefinition : public caf::PdmObject virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue); static void getUiAndResultVariableStringList(QStringList* uiNames, QStringList* variableNames, const std::map >& fieldCompNames); - static QString composeUiVarString(const QString& resultFieldName, const QString& resultComponentName); + static QString composeFieldCompString(const QString& resultFieldName, const QString& resultComponentName); virtual void initAfterRead(); @@ -81,11 +78,14 @@ class RimGeoMechResultDefinition : public caf::PdmObject caf::PdmField m_resultFieldName; caf::PdmField m_resultComponentName; + friend class RimGeoMechPropertyFilter; // Property filter needs the ui fields + friend class RimWellLogExtractionCurve; // Curve needs the ui fields + caf::PdmField > m_resultPositionTypeUiField; caf::PdmField m_resultVariableUiField; - caf::PdmPointer m_reservoirView; - caf::PdmPointer m_propertyFilter; + caf::PdmPointer m_geomCase; static QString convertToUiResultFieldName(QString resultFieldName); + static QString convertToUIComponentName(QString resultComponentName); }; diff --git a/ApplicationCode/ProjectDataModel/RimGeoMechView.cpp b/ApplicationCode/ProjectDataModel/RimGeoMechView.cpp index 1d19853924..2b1482ce44 100644 --- a/ApplicationCode/ProjectDataModel/RimGeoMechView.cpp +++ b/ApplicationCode/ProjectDataModel/RimGeoMechView.cpp @@ -19,38 +19,43 @@ #include "RimGeoMechView.h" -#include "Rim3dOverlayInfoConfig.h" #include "RiaApplication.h" #include "RiaPreferences.h" + +#include "RigFemPartCollection.h" +#include "RigFemPartGrid.h" +#include "RigFemPartResultsCollection.h" +#include "RigGeoMechCaseData.h" + +#include "Rim3dOverlayInfoConfig.h" +#include "RimCellRangeFilterCollection.h" +#include "RimEclipseView.h" +#include "RimGeoMechCase.h" #include "RimGeoMechCellColors.h" +#include "RimGeoMechPropertyFilterCollection.h" +#include "RimLegendConfig.h" #include "RiuMainWindow.h" -#include "cafCeetronPlusNavigation.h" +#include "RiuViewer.h" + +#include "RivGeoMechPartMgr.h" +#include "RivGeoMechPartMgrCache.h" +#include "RivGeoMechVizLogic.h" + #include "cafCadNavigation.h" -#include "RimLegendConfig.h" +#include "cafCeetronPlusNavigation.h" +#include "cafFrameAnimationControl.h" +#include "cafProgressInfo.h" +#include "cvfModelBasicList.h" #include "cvfOverlayScalarMapperLegend.h" - -#include "RimGeoMechCase.h" #include "cvfPart.h" -#include "cvfViewport.h" -#include "cvfModelBasicList.h" #include "cvfScene.h" -#include "RimEclipseView.h" -#include "RiuViewer.h" -#include "RivGeoMechPartMgr.h" -#include "RigGeoMechCaseData.h" +#include "cvfViewport.h" #include "cvfqtUtils.h" -#include "RigFemPartCollection.h" -#include "cafFrameAnimationControl.h" -#include -#include "cafProgressInfo.h" -#include "RimCellRangeFilterCollection.h" -#include "RivGeoMechPartMgrCache.h" -#include "RivGeoMechVizLogic.h" -#include "RigFemPartGrid.h" -#include "RigFemPartResultsCollection.h" -#include "RimGeoMechPropertyFilterCollection.h" +#include +#include "RimViewLinker.h" +#include "cafPdmUiTreeOrdering.h" @@ -68,22 +73,17 @@ RimGeoMechView::RimGeoMechView(void) CAF_PDM_InitFieldNoDefault(&cellResult, "GridCellResult", "Color Result", ":/CellResult.png", "", ""); cellResult = new RimGeoMechCellColors(); + cellResult.uiCapability()->setUiHidden(true); - CAF_PDM_InitFieldNoDefault(&rangeFilterCollection, "RangeFilters", "Range Filters", "", "", ""); - rangeFilterCollection = new RimCellRangeFilterCollection(); - rangeFilterCollection->setReservoirView(this); - - CAF_PDM_InitFieldNoDefault(&propertyFilterCollection, "PropertyFilters", "Property Filters", "", "", ""); - propertyFilterCollection = new RimGeoMechPropertyFilterCollection(); - propertyFilterCollection->setReservoirView(this); + CAF_PDM_InitFieldNoDefault(&m_propertyFilterCollection, "PropertyFilters", "Property Filters", "", "", ""); + m_propertyFilterCollection = new RimGeoMechPropertyFilterCollection(); + m_propertyFilterCollection.uiCapability()->setUiHidden(true); - this->cellResult()->setReservoirView(this); - this->cellResult()->legendConfig()->setPosition(cvf::Vec2ui(10, 120)); + //this->cellResult()->setReservoirView(this); this->cellResult()->legendConfig()->setReservoirView(this); m_scaleTransform = new cvf::Transform(); m_vizLogic = new RivGeoMechVizLogic(this); - } //-------------------------------------------------------------------------------------------------- @@ -154,12 +154,7 @@ void RimGeoMechView::loadDataAndUpdate() updateViewerWidget(); this->propertyFilterCollection()->loadAndInitializePropertyFilters(); - createDisplayModelAndRedraw(); - - if (cameraPosition().isIdentity()) - { - setDefaultView(); - } + this->scheduleCreateDisplayModelAndRedraw(); progress.incrementProgress(); } @@ -244,13 +239,14 @@ void RimGeoMechView::createDisplayModel() if (isTimeStepDependentDataVisible()) { - m_viewer->animationControl()->setCurrentFrame(m_currentTimeStep); + m_viewer->animationControl()->setCurrentFrameOnly(m_currentTimeStep); + m_viewer->setCurrentFrame(m_currentTimeStep); } else { updateLegends(); m_vizLogic->updateStaticCellColors(-1); - overlayInfoConfig()->update3DInfo(); + m_overlayInfoConfig()->update3DInfo(); } } @@ -301,7 +297,7 @@ void RimGeoMechView::updateCurrentTimeStep() m_viewer->animationControl()->slotPause(); // To avoid animation timer spinning in the background } - overlayInfoConfig()->update3DInfo(); + m_overlayInfoConfig()->update3DInfo(); } //-------------------------------------------------------------------------------------------------- @@ -351,7 +347,6 @@ void RimGeoMechView::updateDisplayModelVisibility() m_viewer->setEnableMask(mask); m_viewer->update(); - } //-------------------------------------------------------------------------------------------------- @@ -360,6 +355,8 @@ void RimGeoMechView::updateDisplayModelVisibility() void RimGeoMechView::setGeoMechCase(RimGeoMechCase* gmCase) { m_geomechCase = gmCase; + cellResult()->setGeoMechCase(gmCase); + } //-------------------------------------------------------------------------------------------------- @@ -384,7 +381,8 @@ void RimGeoMechView::updateLegends() } if (!m_geomechCase || !m_viewer || !m_geomechCase->geoMechData() - || !this->isTimeStepDependentDataVisible() ) + || !this->isTimeStepDependentDataVisible() + || !(cellResult()->resultAddress().isValid()) ) { return; } @@ -411,9 +409,21 @@ void RimGeoMechView::updateLegends() m_viewer->addColorLegendToBottomLeftCorner(cellResult()->legendConfig->legend()); - cellResult()->legendConfig->legend()->setTitle(cvfqt::Utils::toString( + cvf::String legendTitle = cvfqt::Utils::toString( caf::AppEnum(cellResult->resultPositionType()).uiText() + "\n" - + cellResult->resultFieldUiName() + ", " + cellResult->resultComponentUiName())); + + cellResult->resultFieldUiName()); + + if (!cellResult->resultComponentUiName().isEmpty()) + { + legendTitle += ", " + cvfqt::Utils::toString(cellResult->resultComponentUiName()); + } + + if (cellResult->resultFieldName() == "SE" || cellResult->resultFieldName() == "ST" || cellResult->resultFieldName() == "POR-Bar") + { + legendTitle += " [Bar]"; + } + + cellResult()->legendConfig->legend()->setTitle(legendTitle); } //-------------------------------------------------------------------------------------------------- @@ -477,7 +487,9 @@ void RimGeoMechView::fieldChangedByUi(const caf::PdmFieldHandle* changedField, c { if (m_viewer) { - RiuMainWindow::instance()->removeViewer(m_viewer); + windowGeometry = RiuMainWindow::instance()->windowGeometryForViewer(m_viewer->layoutWidget()); + + RiuMainWindow::instance()->removeViewer(m_viewer->layoutWidget()); delete m_viewer; m_viewer = NULL; } @@ -492,7 +504,7 @@ void RimGeoMechView::fieldChangedByUi(const caf::PdmFieldHandle* changedField, c //-------------------------------------------------------------------------------------------------- void RimGeoMechView::initAfterRead() { - this->cellResult()->setReservoirView(this); + this->cellResult()->setGeoMechCase(m_geomechCase); this->updateUiIconFromToggleField(); } @@ -511,5 +523,77 @@ RimCase* RimGeoMechView::ownerCase() void RimGeoMechView::scheduleGeometryRegen(RivCellSetEnum geometryType) { m_vizLogic->scheduleGeometryRegen(geometryType); + + if (this->isMasterView()) + { + RimViewLinker* viewLinker = this->assosiatedViewLinker(); + if (viewLinker) + { + viewLinker->scheduleGeometryRegenForDepViews(geometryType); + } + } + m_currentReservoirCellVisibility = NULL; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimGeoMechView::setOverridePropertyFilterCollection(RimGeoMechPropertyFilterCollection* pfc) +{ + m_overridePropertyFilterCollection = pfc; + + this->scheduleGeometryRegen(PROPERTY_FILTERED); + this->scheduleCreateDisplayModelAndRedraw(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimGeoMechPropertyFilterCollection* RimGeoMechView::propertyFilterCollection() +{ + if (m_overridePropertyFilterCollection) + { + return m_overridePropertyFilterCollection; + } + else + { + return m_propertyFilterCollection; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimGeoMechView::calculateCurrentTotalCellVisibility(cvf::UByteArray* totalVisibility) +{ + m_vizLogic->calculateCurrentTotalCellVisibility(totalVisibility, m_currentTimeStep); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimGeoMechView::updateIconStateForFilterCollections() +{ + m_rangeFilterCollection()->updateIconState(); + m_rangeFilterCollection()->uiCapability()->updateConnectedEditors(); + + // NB - notice that it is the filter collection managed by this view that the icon update applies to + m_propertyFilterCollection()->updateIconState(); + m_propertyFilterCollection()->uiCapability()->updateConnectedEditors(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimGeoMechView::defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName /*= ""*/) +{ + uiTreeOrdering.add(m_overlayInfoConfig()); + + uiTreeOrdering.add(cellResult()); + + uiTreeOrdering.add(m_rangeFilterCollection()); + uiTreeOrdering.add(m_propertyFilterCollection()); + + uiTreeOrdering.setForgetRemainingFields(true); } diff --git a/ApplicationCode/ProjectDataModel/RimGeoMechView.h b/ApplicationCode/ProjectDataModel/RimGeoMechView.h index a40e5647df..1e5d7407e0 100644 --- a/ApplicationCode/ProjectDataModel/RimGeoMechView.h +++ b/ApplicationCode/ProjectDataModel/RimGeoMechView.h @@ -19,29 +19,31 @@ #pragma once -#include "cafPdmField.h" -#include "cafPdmObject.h" -#include "cafPdmPointer.h" +#include "RimView.h" + #include "cafAppEnum.h" +#include "cafPdmChildField.h" +#include "cafPdmField.h" #include "cafPdmFieldCvfColor.h" #include "cafPdmFieldCvfMat4d.h" +#include "cafPdmObject.h" +#include "cafPdmPointer.h" #include "cvfObject.h" -#include "RimView.h" -class RimGeoMechCellColors; +class RigFemPart; class Rim3dOverlayInfoConfig; -class RiuViewer; +class RimCellRangeFilterCollection; class RimGeoMechCase; +class RimGeoMechCellColors; +class RimGeoMechPropertyFilterCollection; +class RiuViewer; class RivGeoMechPartMgr; -class RimCellRangeFilterCollection; class RivGeoMechVizLogic; -class RimGeoMechPropertyFilterCollection; -class RigFemPart; namespace cvf { - class Transform; class CellRangeFilter; + class Transform; } //================================================================================================== @@ -61,13 +63,20 @@ class RimGeoMechView : public RimView virtual void loadDataAndUpdate(); - caf::PdmField cellResult; - caf::PdmField propertyFilterCollection; + caf::PdmChildField cellResult; + + RimGeoMechPropertyFilterCollection* propertyFilterCollection(); + void setOverridePropertyFilterCollection(RimGeoMechPropertyFilterCollection* pfc); bool isTimeStepDependentDataVisible(); virtual cvf::Transform* scaleTransform(); virtual void scheduleGeometryRegen(RivCellSetEnum geometryType); + void updateIconStateForFilterCollections(); + +protected: + virtual void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = ""); + private: virtual void createDisplayModel(); @@ -89,6 +98,11 @@ class RimGeoMechView : public RimView virtual RimCase* ownerCase(); + virtual void calculateCurrentTotalCellVisibility(cvf::UByteArray* totalVisibility); + + caf::PdmChildField m_propertyFilterCollection; + caf::PdmPointer m_overridePropertyFilterCollection; + caf::PdmPointer m_geomechCase; cvf::ref m_vizLogic; cvf::ref m_scaleTransform; diff --git a/ApplicationCode/ProjectDataModel/RimIdenticalGridCaseGroup.cpp b/ApplicationCode/ProjectDataModel/RimIdenticalGridCaseGroup.cpp index 8a15d0c822..3519e2cf0f 100644 --- a/ApplicationCode/ProjectDataModel/RimIdenticalGridCaseGroup.cpp +++ b/ApplicationCode/ProjectDataModel/RimIdenticalGridCaseGroup.cpp @@ -51,13 +51,21 @@ RimIdenticalGridCaseGroup::RimIdenticalGridCaseGroup() CAF_PDM_InitField(&name, "UserDescription", QString("Grid Case Group"), "Name", "", "", ""); CAF_PDM_InitField(&groupId, "GroupId", -1, "Case Group ID", "", "" ,""); - groupId.setUiReadOnly(true); + groupId.uiCapability()->setUiReadOnly(true); - CAF_PDM_InitFieldNoDefault(&statisticsCaseCollection, "StatisticsCaseCollection", "Derived Statistics", ":/Histograms16x16.png", "", ""); - CAF_PDM_InitFieldNoDefault(&caseCollection, "CaseCollection", "Source Cases", ":/Cases16x16.png", "", ""); + CAF_PDM_InitFieldNoDefault(&statisticsCaseCollection, "StatisticsCaseCollection", "statisticsCaseCollection ChildArrayField", "", "", ""); + statisticsCaseCollection.uiCapability()->setUiHidden(true); + CAF_PDM_InitFieldNoDefault(&caseCollection, "CaseCollection", "Source Cases ChildArrayField", "", "", ""); + caseCollection.uiCapability()->setUiHidden(true); caseCollection = new RimCaseCollection; + caseCollection->uiCapability()->setUiName("Source Cases"); + caseCollection->uiCapability()->setUiIcon(QIcon(":/Cases16x16.png")); + statisticsCaseCollection = new RimCaseCollection; + statisticsCaseCollection->uiCapability()->setUiName("Derived Statistics"); + statisticsCaseCollection->uiCapability()->setUiIcon(QIcon(":/Histograms16x16.png")); + m_mainGrid = NULL; @@ -377,11 +385,14 @@ void RimIdenticalGridCaseGroup::updateMainGridAndActiveCellsForStatisticsCases() { RimEclipseCase* rimStaticsCase = statisticsCaseCollection->reservoirs[i]; - rimStaticsCase->reservoirData()->setMainGrid(this->mainGrid()); - - if (i == 0) + if (rimStaticsCase->reservoirData()) { - rimStaticsCase->reservoirData()->computeActiveCellBoundingBoxes(); + rimStaticsCase->reservoirData()->setMainGrid(this->mainGrid()); + + if (i == 0) + { + rimStaticsCase->reservoirData()->computeActiveCellBoundingBoxes(); + } } } } @@ -396,8 +407,14 @@ void RimIdenticalGridCaseGroup::clearStatisticsResults() RimEclipseCase* rimStaticsCase = statisticsCaseCollection->reservoirs[i]; if (!rimStaticsCase) continue; - rimStaticsCase->results(RifReaderInterface::MATRIX_RESULTS)->cellResults()->clearAllResults(); - rimStaticsCase->results(RifReaderInterface::FRACTURE_RESULTS)->cellResults()->clearAllResults(); + if (rimStaticsCase->results(RifReaderInterface::MATRIX_RESULTS)->cellResults()) + { + rimStaticsCase->results(RifReaderInterface::MATRIX_RESULTS)->cellResults()->clearAllResults(); + } + if (rimStaticsCase->results(RifReaderInterface::FRACTURE_RESULTS)->cellResults()) + { + rimStaticsCase->results(RifReaderInterface::FRACTURE_RESULTS)->cellResults()->clearAllResults(); + } for (size_t j = 0; j < rimStaticsCase->reservoirViews.size(); j++) { @@ -457,11 +474,10 @@ RigActiveCellInfo* RimIdenticalGridCaseGroup::unionOfActiveCells(RifReaderInterf //-------------------------------------------------------------------------------------------------- bool RimIdenticalGridCaseGroup::isStatisticsCaseCollection(RimCaseCollection* rimCaseCollection) { - std::vector fields; - rimCaseCollection->parentFields(fields); - if (fields.size() == 1) + caf::PdmFieldHandle* parentField = rimCaseCollection->parentField(); + if (parentField) { - if (fields[0]->keyword() == "StatisticsCaseCollection") + if (parentField->keyword() == "StatisticsCaseCollection") { return true; } diff --git a/ApplicationCode/ProjectDataModel/RimIdenticalGridCaseGroup.h b/ApplicationCode/ProjectDataModel/RimIdenticalGridCaseGroup.h index 9e31ef3de6..068ac935de 100644 --- a/ApplicationCode/ProjectDataModel/RimIdenticalGridCaseGroup.h +++ b/ApplicationCode/ProjectDataModel/RimIdenticalGridCaseGroup.h @@ -20,19 +20,21 @@ #pragma once -#include "cvfBase.h" -#include "cvfObject.h" +#include "RifReaderInterface.h" + +#include "cafPdmChildField.h" #include "cafPdmField.h" #include "cafPdmObject.h" -#include "RifReaderInterface.h" +#include "cvfBase.h" +#include "cvfObject.h" -class RimCaseCollection; -class RimEclipseStatisticsCase; +class RigActiveCellInfo; +class RigMainGrid; +class RimCaseCollection; class RimEclipseCase; -class RigMainGrid; -class RigActiveCellInfo; +class RimEclipseStatisticsCase; //================================================================================================== // @@ -49,8 +51,8 @@ class RimIdenticalGridCaseGroup : public caf::PdmObject caf::PdmField name; caf::PdmField groupId; - caf::PdmField caseCollection; - caf::PdmField statisticsCaseCollection; + caf::PdmChildField caseCollection; + caf::PdmChildField statisticsCaseCollection; void addCase(RimEclipseCase* reservoir); void removeCase(RimEclipseCase* reservoir); diff --git a/ApplicationCode/ProjectDataModel/RimLegendConfig.cpp b/ApplicationCode/ProjectDataModel/RimLegendConfig.cpp index 15c28fac82..e6263e212c 100644 --- a/ApplicationCode/ProjectDataModel/RimLegendConfig.cpp +++ b/ApplicationCode/ProjectDataModel/RimLegendConfig.cpp @@ -114,7 +114,7 @@ RimLegendConfig::RimLegendConfig() CAF_PDM_InitField(&m_userDefinedMaxValue, "UserDefinedMax", 1.0, "Max", "", "Min value of the legend", ""); CAF_PDM_InitField(&m_userDefinedMinValue, "UserDefinedMin", 0.0, "Min", "", "Max value of the legend", ""); CAF_PDM_InitField(&resultVariableName, "ResultVariableUsage", QString(""), "", "", "", ""); - resultVariableName.setUiHidden(true); + resultVariableName.uiCapability()->setUiHidden(true); m_linDiscreteScalarMapper = new cvf::ScalarMapperDiscreteLinear; m_logDiscreteScalarMapper = new cvf::ScalarMapperDiscreteLog; @@ -125,7 +125,6 @@ RimLegendConfig::RimLegendConfig() cvf::Font* standardFont = RiaApplication::instance()->standardFont(); m_legend = new cvf::OverlayScalarMapperLegend(standardFont); - m_position = cvf::Vec2ui(20, 50); updateFieldVisibility(); updateLegend(); @@ -392,20 +391,20 @@ void RimLegendConfig::updateLegend() if (m_globalAutoMax != cvf::UNDEFINED_DOUBLE ) { - m_userDefinedMaxValue.setUiName(QString("Max ") + "(" + QString::number(m_globalAutoMax, 'g', m_precision) + ")"); + m_userDefinedMaxValue.uiCapability()->setUiName(QString("Max ") + "(" + QString::number(m_globalAutoMax, 'g', m_precision) + ")"); } else { - m_userDefinedMaxValue.setUiName(QString()); + m_userDefinedMaxValue.uiCapability()->setUiName(QString()); } if (m_globalAutoMin != cvf::UNDEFINED_DOUBLE ) { - m_userDefinedMinValue.setUiName(QString("Min ") + "(" + QString::number(m_globalAutoMin, 'g', m_precision) + ")"); + m_userDefinedMinValue.uiCapability()->setUiName(QString("Min ") + "(" + QString::number(m_globalAutoMin, 'g', m_precision) + ")"); } else { - m_userDefinedMinValue.setUiName(QString()); + m_userDefinedMinValue.uiCapability()->setUiName(QString()); } } @@ -470,13 +469,13 @@ void RimLegendConfig::updateFieldVisibility() { if (m_rangeMode == USER_DEFINED) { - m_userDefinedMaxValue.setUiHidden(false); - m_userDefinedMinValue.setUiHidden(false); + m_userDefinedMaxValue.uiCapability()->setUiHidden(false); + m_userDefinedMinValue.uiCapability()->setUiHidden(false); } else { - m_userDefinedMaxValue.setUiHidden(true); - m_userDefinedMinValue.setUiHidden(true); + m_userDefinedMaxValue.uiCapability()->setUiHidden(true); + m_userDefinedMinValue.uiCapability()->setUiHidden(true); } } @@ -536,14 +535,6 @@ cvf::ref RimLegendConfig::interpolateColorArray(const cvf::C return colors; } */ -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimLegendConfig::setPosition(cvf::Vec2ui position) -{ - m_position = position; - updateLegend(); -} //-------------------------------------------------------------------------------------------------- /// diff --git a/ApplicationCode/ProjectDataModel/RimLegendConfig.h b/ApplicationCode/ProjectDataModel/RimLegendConfig.h index 5de9b90be0..328113a4cc 100644 --- a/ApplicationCode/ProjectDataModel/RimLegendConfig.h +++ b/ApplicationCode/ProjectDataModel/RimLegendConfig.h @@ -93,7 +93,6 @@ class RimLegendConfig: public caf::PdmObject void setColorRangeMode(ColorRangesType colorMode); void setAutomaticRanges(double globalMin, double globalMax, double localMin, double localMax); void setClosestToZeroValues(double globalPosClosestToZero, double globalNegClosestToZero, double localPosClosestToZero, double localNegClosestToZero); - void setPosition(cvf::Vec2ui position); cvf::ScalarMapper* scalarMapper() { return m_currentScalarMapper.p(); } cvf::OverlayScalarMapperLegend* legend() { return m_legend.p(); } @@ -131,8 +130,6 @@ class RimLegendConfig: public caf::PdmObject double m_localAutoPosClosestToZero; double m_localAutoNegClosestToZero; - cvf::Vec2ui m_position; - // Fields caf::PdmField m_numLevels; caf::PdmField m_precision; diff --git a/ApplicationCode/ProjectDataModel/RimMainPlotCollection.cpp b/ApplicationCode/ProjectDataModel/RimMainPlotCollection.cpp new file mode 100644 index 0000000000..1fdaafbb5d --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimMainPlotCollection.cpp @@ -0,0 +1,85 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RimMainPlotCollection.h" +#include "RimWellLogPlotCollection.h" + +#include "RiuMainWindow.h" + +#include "cafPdmUiTreeView.h" + +CAF_PDM_SOURCE_INIT(RimMainPlotCollection, "MainPlotCollection"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimMainPlotCollection::RimMainPlotCollection() +{ + CAF_PDM_InitObject("Plots", "", "", ""); + + CAF_PDM_InitField(&show, "Show", true, "Show plots", "", "", ""); + show.uiCapability()->setUiHidden(true); + + CAF_PDM_InitFieldNoDefault(&m_wellLogPlotCollection, "WellLogPlotCollection", "", "", "", ""); + m_wellLogPlotCollection.uiCapability()->setUiHidden(true); + + m_wellLogPlotCollection = new RimWellLogPlotCollection(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimMainPlotCollection::~RimMainPlotCollection() +{ + if (m_wellLogPlotCollection()) delete m_wellLogPlotCollection(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimMainPlotCollection::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +caf::PdmFieldHandle* RimMainPlotCollection::objectToggleField() +{ + return &show; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimMainPlotCollection::recreateWellLogPlotCollection() +{ + if (!wellLogPlotCollection()) + { + m_wellLogPlotCollection = new RimWellLogPlotCollection(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimWellLogPlotCollection* RimMainPlotCollection::wellLogPlotCollection() +{ + return m_wellLogPlotCollection(); +} diff --git a/ApplicationCode/ProjectDataModel/RimMainPlotCollection.h b/ApplicationCode/ProjectDataModel/RimMainPlotCollection.h new file mode 100644 index 0000000000..23a6b4a890 --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimMainPlotCollection.h @@ -0,0 +1,54 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafPdmObject.h" +#include "cafPdmField.h" +#include "cafPdmChildField.h" + +class RimWellLogPlotCollection; + + +//================================================================================================== +/// +/// +//================================================================================================== +class RimMainPlotCollection : public caf::PdmObject +{ + CAF_PDM_HEADER_INIT; +public: + RimMainPlotCollection(); + virtual ~RimMainPlotCollection(); + + RimWellLogPlotCollection* wellLogPlotCollection(); + void recreateWellLogPlotCollection(); + +protected: + + // Overridden PDM methods + virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue); + +private: + virtual caf::PdmFieldHandle* objectToggleField(); + +private: + caf::PdmChildField m_wellLogPlotCollection; + caf::PdmField show; +}; diff --git a/ApplicationCode/ProjectDataModel/RimMimeData.cpp b/ApplicationCode/ProjectDataModel/RimMimeData.cpp index e16db847d6..773ef20cb2 100644 --- a/ApplicationCode/ProjectDataModel/RimMimeData.cpp +++ b/ApplicationCode/ProjectDataModel/RimMimeData.cpp @@ -16,8 +16,6 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RiaStdInclude.h" - #include "RimMimeData.h" //-------------------------------------------------------------------------------------------------- @@ -79,3 +77,68 @@ QString MimeDataWithIndexes::formatName() return "MimeDataWithIndexes"; } + + + + + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +MimeDataWithReferences::MimeDataWithReferences() +{ + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +MimeDataWithReferences::MimeDataWithReferences(const MimeDataWithReferences& other) + : QMimeData() +{ + setReferences(other.references()); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void MimeDataWithReferences::setReferences(const std::vector& references) +{ + m_references = references; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const std::vector& MimeDataWithReferences::references() const +{ + return m_references; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool MimeDataWithReferences::hasFormat(const QString& mimetype) const +{ + return (mimetype == formatName()); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QStringList MimeDataWithReferences::formats() const +{ + QStringList supportedFormats = QMimeData::formats(); + supportedFormats << formatName(); + + return supportedFormats; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString MimeDataWithReferences::formatName() +{ + return "MimeDataWithReferences"; +} diff --git a/ApplicationCode/ProjectDataModel/RimMimeData.h b/ApplicationCode/ProjectDataModel/RimMimeData.h index 0ff9fa9714..28ad20fa7c 100644 --- a/ApplicationCode/ProjectDataModel/RimMimeData.h +++ b/ApplicationCode/ProjectDataModel/RimMimeData.h @@ -20,6 +20,9 @@ #include #include +#include + +#include //-------------------------------------------------------------------------------------------------- @@ -44,3 +47,27 @@ class MimeDataWithIndexes : public QMimeData }; Q_DECLARE_METATYPE(MimeDataWithIndexes) + + +//-------------------------------------------------------------------------------------------------- +/// MimeData class used to carry string references to pdm objects +//-------------------------------------------------------------------------------------------------- +class MimeDataWithReferences : public QMimeData +{ + Q_OBJECT + +public: + MimeDataWithReferences(); + MimeDataWithReferences(const MimeDataWithReferences& other); + + void setReferences(const std::vector& references); + const std::vector& references() const; + virtual bool hasFormat(const QString& mimetype) const; + virtual QStringList formats() const; + static QString formatName(); + +private: + std::vector m_references; +}; + +Q_DECLARE_METATYPE(MimeDataWithReferences) diff --git a/ApplicationCode/ProjectDataModel/RimMockModelSettings.cpp b/ApplicationCode/ProjectDataModel/RimMockModelSettings.cpp index e7e6fce382..f6905fefd3 100644 --- a/ApplicationCode/ProjectDataModel/RimMockModelSettings.cpp +++ b/ApplicationCode/ProjectDataModel/RimMockModelSettings.cpp @@ -17,8 +17,6 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RiaStdInclude.h" - #include "RimMockModelSettings.h" @@ -39,7 +37,7 @@ RimMockModelSettings::RimMockModelSettings() CAF_PDM_InitField(&cellCountZ, "CellCountZ", quint64(10), "Cell Count Z", "", "", ""); CAF_PDM_InitFieldNoDefault(&totalCellCount, "TotalCellCount", "Total Cell Count", "", "", ""); - totalCellCount.setUiReadOnly(true); + totalCellCount.uiCapability()->setUiReadOnly(true); CAF_PDM_InitField(&resultCount, "ResultCount", quint64(3), "Result Count", "", "", ""); CAF_PDM_InitField(&timeStepCount, "TimeStepCount", quint64(10), "Time Step Count", "", "", ""); @@ -58,7 +56,12 @@ RimMockModelSettings::~RimMockModelSettings() void RimMockModelSettings::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) { totalCellCount = cellCountX * cellCountY * cellCountZ; - totalCellCount.updateConnectedEditors(); + + caf::PdmUiFieldHandle* uiFieldHandle = totalCellCount.uiCapability(); + if (uiFieldHandle) + { + uiFieldHandle->updateConnectedEditors(); + } } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/RimNoCommonAreaNNC.cpp b/ApplicationCode/ProjectDataModel/RimNoCommonAreaNNC.cpp index 7c05ca685b..6c4dc42626 100644 --- a/ApplicationCode/ProjectDataModel/RimNoCommonAreaNNC.cpp +++ b/ApplicationCode/ProjectDataModel/RimNoCommonAreaNNC.cpp @@ -29,7 +29,7 @@ RimNoCommonAreaNNC::RimNoCommonAreaNNC() CAF_PDM_InitObject("RimNoCommonAreaNNC", "", "", ""); CAF_PDM_InitFieldNoDefault(&name, "Name", "Name", "", "", ""); - name.setUiReadOnly(true); + name.uiCapability()->setUiReadOnly(true); } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/RimNoCommonAreaNncCollection.cpp b/ApplicationCode/ProjectDataModel/RimNoCommonAreaNncCollection.cpp index 2da7c58588..7ab3bbdd61 100644 --- a/ApplicationCode/ProjectDataModel/RimNoCommonAreaNncCollection.cpp +++ b/ApplicationCode/ProjectDataModel/RimNoCommonAreaNncCollection.cpp @@ -19,6 +19,8 @@ #include "RimNoCommonAreaNncCollection.h" +#include "RimNoCommonAreaNNC.h" + CAF_PDM_SOURCE_INIT(RimNoCommonAreaNncCollection, "RimNoCommonAreaNncCollection"); //-------------------------------------------------------------------------------------------------- @@ -29,9 +31,13 @@ RimNoCommonAreaNncCollection::RimNoCommonAreaNncCollection() CAF_PDM_InitObject("RimNoCommonAreaNncCollection", "", "", ""); CAF_PDM_InitField(&name, "UserDescription", QString("No Common Area Nncs"), "Name", "", "", ""); - name.setUiHidden(true); + name.uiCapability()->setUiHidden(true); CAF_PDM_InitFieldNoDefault(&noCommonAreaNncs, "NoCommonAreaNncs", "NoCommonAreaNncs", "", "", ""); + noCommonAreaNncs.uiCapability()->setUiHidden(true); + + noCommonAreaNncs.xmlCapability()->setIOReadable(false); + noCommonAreaNncs.xmlCapability()->setIOWritable(false); } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/RimNoCommonAreaNncCollection.h b/ApplicationCode/ProjectDataModel/RimNoCommonAreaNncCollection.h index deb48e53a4..c52c9ae00f 100644 --- a/ApplicationCode/ProjectDataModel/RimNoCommonAreaNncCollection.h +++ b/ApplicationCode/ProjectDataModel/RimNoCommonAreaNncCollection.h @@ -19,6 +19,7 @@ #pragma once +#include "cafPdmChildArrayField.h" #include "cafPdmField.h" #include "cafPdmObject.h" #include "cafPdmPointer.h" @@ -41,5 +42,5 @@ class RimNoCommonAreaNncCollection : public caf::PdmObject virtual caf::PdmFieldHandle* userDescriptionField(); caf::PdmField name; - caf::PdmPointersField noCommonAreaNncs; + caf::PdmChildArrayField noCommonAreaNncs; }; diff --git a/ApplicationCode/ProjectDataModel/RimOilField.h b/ApplicationCode/ProjectDataModel/RimOilField.h index f2704939ff..9240f1793e 100644 --- a/ApplicationCode/ProjectDataModel/RimOilField.h +++ b/ApplicationCode/ProjectDataModel/RimOilField.h @@ -20,13 +20,14 @@ #pragma once +#include "cafPdmChildField.h" #include "cafPdmField.h" #include "cafPdmObject.h" #include "cafPdmPointer.h" -class RimWellPathCollection; class RimEclipseCaseCollection; class RimGeoMechModels; +class RimWellPathCollection; //================================================================================================== /// @@ -40,7 +41,7 @@ class RimOilField : public caf::PdmObject RimOilField(void); virtual ~RimOilField(void); - caf::PdmField analysisModels; - caf::PdmField geoMechModels; - caf::PdmField wellPathCollection; + caf::PdmChildField analysisModels; + caf::PdmChildField geoMechModels; + caf::PdmChildField wellPathCollection; }; diff --git a/ApplicationCode/ProjectDataModel/RimProject.cpp b/ApplicationCode/ProjectDataModel/RimProject.cpp index 01683a007d..f0c24a21ff 100644 --- a/ApplicationCode/ProjectDataModel/RimProject.cpp +++ b/ApplicationCode/ProjectDataModel/RimProject.cpp @@ -20,22 +20,47 @@ #include "RimProject.h" + #include "RiaApplication.h" #include "RiaVersionInfo.h" + #include "RigCaseData.h" -#include "RimEclipseCaseCollection.h" -#include "RimEclipseCase.h" + +#include "RiaApplication.h" +#include "RimCalcScript.h" #include "RimCaseCollection.h" +#include "RimCommandObject.h" +#include "RimEclipseCase.h" +#include "RimEclipseCaseCollection.h" +#include "RimEclipseInputProperty.h" +#include "RimEclipseInputPropertyCollection.h" +#include "RimEclipseStatisticsCase.h" +#include "RimEclipseStatisticsCaseCollection.h" +#include "RimEclipseView.h" +#include "RimGeoMechCase.h" +#include "RimGeoMechModels.h" #include "RimIdenticalGridCaseGroup.h" +#include "RimViewController.h" +#include "RimMainPlotCollection.h" #include "RimOilField.h" -#include "RimEclipseView.h" #include "RimScriptCollection.h" +#include "RimViewLinker.h" +#include "RimViewLinkerCollection.h" +#include "RimWellLogPlot.h" +#include "RimWellLogPlotCollection.h" +#include "RimWellPath.h" #include "RimWellPathCollection.h" #include "RimWellPathImport.h" +#include "RiuMainWindow.h" + +#include "ToggleCommands/RicToggleItemsFeatureImpl.h" +#include "OctaveScriptCommands/RicExecuteScriptForCasesFeature.h" + +#include "cafCmdFeature.h" +#include "cafPdmUiTreeOrdering.h" + #include -#include "RimGeoMechModels.h" -#include "RimGeoMechCase.h" CAF_PDM_SOURCE_INIT(RimProject, "ResInsightProject"); //-------------------------------------------------------------------------------------------------- @@ -44,49 +69,63 @@ CAF_PDM_SOURCE_INIT(RimProject, "ResInsightProject"); RimProject::RimProject(void) { CAF_PDM_InitFieldNoDefault(&m_projectFileVersionString, "ProjectFileVersionString", "", "", "", ""); - m_projectFileVersionString.setUiHidden(true); + m_projectFileVersionString.uiCapability()->setUiHidden(true); CAF_PDM_InitField(&nextValidCaseId, "NextValidCaseId", 0, "Next Valid Case ID", "", "" ,""); - nextValidCaseId.setUiHidden(true); + nextValidCaseId.uiCapability()->setUiHidden(true); CAF_PDM_InitField(&nextValidCaseGroupId, "NextValidCaseGroupId", 0, "Next Valid Case Group ID", "", "" ,""); - nextValidCaseGroupId.setUiHidden(true); + nextValidCaseGroupId.uiCapability()->setUiHidden(true); CAF_PDM_InitFieldNoDefault(&oilFields, "OilFields", "Oil Fields", "", "", ""); - oilFields.setUiHidden(true); + oilFields.uiCapability()->setUiHidden(true); CAF_PDM_InitFieldNoDefault(&scriptCollection, "ScriptCollection", "Scripts", ":/Default.png", "", ""); + scriptCollection.uiCapability()->setUiHidden(true); CAF_PDM_InitFieldNoDefault(&treeViewState, "TreeViewState", "", "", "", ""); - treeViewState.setUiHidden(true); + treeViewState.uiCapability()->setUiHidden(true); CAF_PDM_InitFieldNoDefault(&wellPathImport, "WellPathImport", "WellPathImport", "", "", ""); wellPathImport = new RimWellPathImport(); - wellPathImport.setUiHidden(true); - wellPathImport.setUiChildrenHidden(true); + wellPathImport.uiCapability()->setUiHidden(true); + wellPathImport.uiCapability()->setUiChildrenHidden(true); + + CAF_PDM_InitFieldNoDefault(&mainPlotCollection, "MainPlotCollection", "Plots", "", "", ""); + mainPlotCollection.uiCapability()->setUiHidden(true); + + CAF_PDM_InitFieldNoDefault(&viewLinkerCollection, "LinkedViews", "Linked Views (field in RimProject", ":/chain.png", "", ""); + viewLinkerCollection.uiCapability()->setUiHidden(true); + viewLinkerCollection = new RimViewLinkerCollection; CAF_PDM_InitFieldNoDefault(&commandObjects, "CommandObjects", "CommandObjects", "", "", ""); - //wellPathImport.setUiHidden(true); + //wellPathImport.uiCapability()->setUiHidden(true); CAF_PDM_InitFieldNoDefault(¤tModelIndexPath, "TreeViewCurrentModelIndexPath", "", "", "", ""); - currentModelIndexPath.setUiHidden(true); + currentModelIndexPath.uiCapability()->setUiHidden(true); // Obsolete fields. The content is moved to OilFields and friends CAF_PDM_InitFieldNoDefault(&casesObsolete, "Reservoirs", "", "", "", ""); - casesObsolete.setUiHidden(true); - casesObsolete.setIOWritable(false); // read but not write, they will be moved into RimAnalysisGroups + casesObsolete.uiCapability()->setUiHidden(true); + casesObsolete.xmlCapability()->setIOWritable(false); // read but not write, they will be moved into RimAnalysisGroups CAF_PDM_InitFieldNoDefault(&caseGroupsObsolete, "CaseGroups", "", "", "", ""); - caseGroupsObsolete.setUiHidden(true); - caseGroupsObsolete.setIOWritable(false); // read but not write, they will be moved into RimAnalysisGroups + caseGroupsObsolete.uiCapability()->setUiHidden(true); + caseGroupsObsolete.xmlCapability()->setIOWritable(false); // read but not write, they will be moved into RimAnalysisGroups // Initialization scriptCollection = new RimScriptCollection(); - scriptCollection->directory.setUiHidden(true); + scriptCollection->directory.uiCapability()->setUiHidden(true); + scriptCollection->uiCapability()->setUiName("Scripts"); + scriptCollection->uiCapability()->setUiIcon(QIcon(":/Default.png")); + + mainPlotCollection = new RimMainPlotCollection(); // For now, create a default first oilfield that contains the rest of the project oilFields.push_back(new RimOilField); initScriptDirectories(); + + this->setUiHidden(true); } //-------------------------------------------------------------------------------------------------- @@ -105,6 +144,7 @@ RimProject::~RimProject(void) //-------------------------------------------------------------------------------------------------- void RimProject::close() { + if (mainPlotCollection()) delete mainPlotCollection(); oilFields.deleteAllChildObjects(); oilFields.push_back(new RimOilField); @@ -115,10 +155,15 @@ void RimProject::close() commandObjects.deleteAllChildObjects(); + delete viewLinkerCollection->viewLinker(); + viewLinkerCollection->viewLinker = NULL; + fileName = ""; nextValidCaseId = 0; nextValidCaseGroupId = 0; + currentModelIndexPath = ""; + treeViewState = ""; } @@ -236,9 +281,10 @@ void RimProject::initAfterRead() bool movedOneRimCase = false; for (size_t cIdx = 0; cIdx < casesObsolete().size(); ++cIdx) { - RimEclipseCase* sourceCase = casesObsolete[cIdx]; if (analysisModels) { + RimEclipseCase* sourceCase = casesObsolete[cIdx]; + casesObsolete.set(cIdx, NULL); analysisModels->cases.push_back(sourceCase); //printf("Moved m_project->casesObsolete[%i] to first oil fields analysis models\n", cIdx); movedOneRimCase = true; // moved at least one so assume the others will be moved too... @@ -249,12 +295,12 @@ void RimProject::initAfterRead() { casesObsolete.clear(); } - - if (casesObsolete().size() > 0 || caseGroupsObsolete.size() > 0) - { - //printf("RimProject::initAfterRead: Was not able to move all cases (%i left) or caseGroups (%i left) from Project to analysisModels", - // casesObsolete().size(), caseGroupsObsolete.size()); - } + + if (casesObsolete().size() > 0 || caseGroupsObsolete.size() > 0) + { + //printf("RimProject::initAfterRead: Was not able to move all cases (%i left) or caseGroups (%i left) from Project to analysisModels", + // casesObsolete().size(), caseGroupsObsolete.size()); + } // Set project pointer to each well path for (size_t oilFieldIdx = 0; oilFieldIdx < oilFields().size(); oilFieldIdx++) @@ -421,6 +467,67 @@ void RimProject::allCases(std::vector& cases) } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimProject::allNotLinkedViews(std::vector& views) +{ + std::vector cases; + allCases(cases); + + std::vector alreadyLinkedViews; + if (viewLinkerCollection->viewLinker()) + { + viewLinkerCollection->viewLinker()->allViews(alreadyLinkedViews); + } + + for (size_t caseIdx = 0; caseIdx < cases.size(); caseIdx++) + { + RimCase* rimCase = cases[caseIdx]; + if (!rimCase) continue; + + std::vector caseViews = rimCase->views(); + for (size_t viewIdx = 0; viewIdx < caseViews.size(); viewIdx++) + { + bool isLinked = false; + for (size_t lnIdx = 0; lnIdx < alreadyLinkedViews.size(); lnIdx++) + { + if (caseViews[viewIdx] == alreadyLinkedViews[lnIdx]) + { + isLinked = true; + } + } + if (!isLinked) + { + views.push_back(caseViews[viewIdx]); + } + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimProject::allVisibleViews(std::vector& views) +{ + std::vector cases; + allCases(cases); + + for (size_t caseIdx = 0; caseIdx < cases.size(); caseIdx++) + { + RimCase* rimCase = cases[caseIdx]; + if (!rimCase) continue; + + std::vector caseViews = rimCase->views(); + for (size_t viewIdx = 0; viewIdx < caseViews.size(); viewIdx++) + { + if (caseViews[viewIdx] && caseViews[viewIdx]->viewer()) + { + views.push_back(caseViews[viewIdx]); + } + } + } +} //-------------------------------------------------------------------------------------------------- /// @@ -499,3 +606,383 @@ void RimProject::computeUtmAreaOfInterest() } } + + + + + + +#include "cafCmdFeatureManager.h" +#include "cafSelectionManager.h" + +#include "RimCellRangeFilterCollection.h" +#include "RimCellRangeFilter.h" +#include "RimEclipsePropertyFilterCollection.h" +#include "RimEclipsePropertyFilter.h" +#include "RimGeoMechPropertyFilterCollection.h" +#include "RimGeoMechPropertyFilter.h" +#include "RimGeoMechView.h" +#include "RimEclipseCellColors.h" +#include "RimEclipseFaultColors.h" +#include "RimWellLogPlot.h" +#include "RimWellLogPlotTrack.h" +#include "RimWellLogPlotCurve.h" +#include "RimWellLogFileChannel.h" +#include + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimProject::actionsBasedOnSelection(QMenu& contextMenu) +{ + QStringList commandIds; + + std::vector uiItems; + caf::SelectionManager::instance()->selectedItems(uiItems); + + if (uiItems.size() == 0) + { + commandIds << "RicNewWellLogPlotFeature"; + } + else if (uiItems.size() > 1) + { + caf::PdmUiItem* uiItem = uiItems[0]; + if (dynamic_cast(uiItem)) + { + commandIds << "RicAddWellLogToPlotFeature"; + } + } + else if (uiItems.size() == 1) + { + caf::PdmUiItem* uiItem = uiItems[0]; + CVF_ASSERT(uiItem); + + if (dynamic_cast(uiItem)) + { + commandIds << "RicImportEclipseCaseFeature"; + commandIds << "RicImportInputEclipseCaseFeature"; + commandIds << "RicCreateGridCaseGroupFeature"; + commandIds << "RicEclipseCaseNewGroupFeature"; + } + else if (dynamic_cast(uiItem)) + { + commandIds << "RicNewViewFeature"; + commandIds << "RicCopyReferencesToClipboardFeature"; + commandIds << "RicPasteGeoMechViewsFeature"; + commandIds << "RicDeleteItemFeature"; + commandIds << "Separator"; + } + else if (dynamic_cast(uiItem)) + { + commandIds << "RicNewViewFeature"; + commandIds << "RicCopyReferencesToClipboardFeature"; + commandIds << "RicPasteEclipseViewsFeature"; + commandIds << "RicDeleteItemFeature"; + commandIds << "Separator"; + } + else if (dynamic_cast(uiItem)) + { + commandIds << "RicPasteEclipseCasesFeature"; + commandIds << "RicNewStatisticsCaseFeature"; + } + else if (dynamic_cast(uiItem)) + { + commandIds << "RicNewViewFeature"; + commandIds << "RicComputeStatisticsFeature"; + commandIds << "RicCloseCaseFeature"; + commandIds << "RicExecuteScriptForCasesFeature"; + } + else if (dynamic_cast(uiItem)) + { + commandIds << "RicCopyReferencesToClipboardFeature"; + + commandIds << "RicPasteEclipseCasesFeature"; + commandIds << "RicPasteEclipseViewsFeature"; + + commandIds << "RicCloseCaseFeature"; + commandIds << "RicNewViewFeature"; + commandIds << "RicEclipseCaseNewGroupFeature"; + commandIds << "RicExecuteScriptForCasesFeature"; + } + else if (dynamic_cast(uiItem)) + { + commandIds << "RicPasteGeoMechViewsFeature"; + commandIds << "RicNewViewFeature"; + commandIds << "Separator"; + + commandIds << "RicCloseCaseFeature"; + } + else if (dynamic_cast(uiItem)) + { + commandIds << "RicEclipseCaseNewGroupFeature"; + commandIds << "RicPasteEclipseCasesFeature"; + commandIds << "RicDeleteItemFeature"; + } + else if (dynamic_cast(uiItem)) + { + commandIds << "RicSaveEclipseResultAsInputPropertyFeature"; + } + else if (dynamic_cast(uiItem)) + { + commandIds << "RicAddEclipseInputPropertyFeature"; + } + else if (dynamic_cast(uiItem)) + { + commandIds << "RicDeleteItemFeature"; + commandIds << "RicSaveEclipseInputPropertyFeature"; + } + else if (dynamic_cast(uiItem)) + { + commandIds << "RicRangeFilterNewFeature"; + commandIds << "RicRangeFilterNewSliceIFeature"; + commandIds << "RicRangeFilterNewSliceJFeature"; + commandIds << "RicRangeFilterNewSliceKFeature"; + } + else if (dynamic_cast(uiItem)) + { + commandIds << "RicRangeFilterInsertFeature"; + commandIds << "RicRangeFilterNewSliceIFeature"; + commandIds << "RicRangeFilterNewSliceJFeature"; + commandIds << "RicRangeFilterNewSliceKFeature"; + commandIds << "Separator"; + commandIds << "RicDeleteItemFeature"; + } + else if (dynamic_cast(uiItem)) + { + commandIds << "RicEclipsePropertyFilterNewFeature"; + } + else if (dynamic_cast(uiItem)) + { + commandIds << "RicEclipsePropertyFilterInsertFeature"; + commandIds << "Separator"; + commandIds << "RicDeleteItemFeature"; + } + else if (dynamic_cast(uiItem)) + { + commandIds << "RicGeoMechPropertyFilterNewFeature"; + } + else if (dynamic_cast(uiItem)) + { + commandIds << "RicGeoMechPropertyFilterInsertFeature"; + commandIds << "Separator"; + commandIds << "RicDeleteItemFeature"; + } + else if (dynamic_cast(uiItem)) + { + commandIds << "RicWellPathsDeleteAllFeature"; + commandIds << "RicWellPathsImportFileFeature"; + commandIds << "RicWellPathsImportSsihubFeature"; + commandIds << "RicWellLogsImportFileFeature"; + } + else if (dynamic_cast(uiItem)) + { + commandIds << "RicNewWellLogFileCurveFeature"; + commandIds << "RicNewWellLogCurveExtractionFeature"; + commandIds << "RicWellPathDeleteFeature"; + } + else if (dynamic_cast(uiItem)) + { + commandIds << "RicEditScriptFeature"; + commandIds << "RicNewScriptFeature"; + commandIds << "Separator"; + commandIds << "RicExecuteScriptFeature"; + } + else if (dynamic_cast(uiItem)) + { + commandIds << "RicAddScriptPathFeature"; + commandIds << "RicDeleteScriptPathFeature"; + } + else if (dynamic_cast(uiItem)) + { + commandIds << "RicShowAllLinkedViewsFeature"; + commandIds << "Separator"; + commandIds << "RicDeleteItemFeature"; + } + else if (dynamic_cast(uiItem)) + { + commandIds << "RicShowAllLinkedViewsFeature"; + commandIds << "Separator"; + commandIds << "RicDeleteAllLinkedViewsFeature"; + } + else if (dynamic_cast(uiItem)) + { + commandIds << "RicNewWellLogPlotFeature"; + } + else if (dynamic_cast(uiItem)) + { + commandIds << "RicNewWellLogPlotTrackFeature"; + commandIds << "RicDeleteItemFeature"; + } + else if (dynamic_cast(uiItem)) + { + commandIds << "RicNewWellLogCurveExtractionFeature"; + commandIds << "RicNewWellLogFileCurveFeature"; + commandIds << "RicDeleteWellLogPlotTrackFeature"; + } + else if (dynamic_cast(uiItem)) + { + commandIds << "RicExportToLasFileFeature"; + commandIds << "RicDeleteItemFeature"; + } + else if (dynamic_cast(uiItem)) + { + commandIds << "RicAddWellLogToPlotFeature"; + } + + if (dynamic_cast(uiItem)) + { + commandIds << "RicLinkVisibleViewsFeature"; + commandIds << "RicLinkViewFeature"; + commandIds << "RicUnLinkViewFeature"; + commandIds << "RicShowLinkOptionsFeature"; + commandIds << "RicSetMasterViewFeature"; + } + } + + if (RicToggleItemsFeatureImpl::isToggleCommandsAvailable()) + { + commandIds << "Separator"; + commandIds << "RicToggleItemsOnFeature"; + commandIds << "RicToggleItemsOffFeature"; + commandIds << "RicToggleItemsFeature"; + } + + caf::CmdFeatureManager* commandManager = caf::CmdFeatureManager::instance(); + for (int i = 0; i < commandIds.size(); i++) + { + if (commandIds[i] == "Separator") + { + contextMenu.addSeparator(); + } + else if (commandIds[i] == "RicExecuteScriptForCasesFeature") + { + // Execute script on selection of cases + RiuMainWindow* ruiMainWindow = RiuMainWindow::instance(); + if (ruiMainWindow) + { + std::vector cases; + ruiMainWindow->selectedCases(cases); + + if (cases.size() > 0) + { + QMenu* executeMenu = contextMenu.addMenu("Execute script"); + + RiaApplication* app = RiaApplication::instance(); + RimProject* proj = app->project(); + if (proj && proj->scriptCollection()) + { + RimScriptCollection* rootScriptCollection = proj->scriptCollection(); + + // Root script collection holds a list of subdirectories of user defined script folders + for (size_t i = 0; i < rootScriptCollection->subDirectories.size(); i++) + { + RimScriptCollection* subDir = rootScriptCollection->subDirectories[i]; + + if (subDir) + { + appendScriptItems(executeMenu, subDir); + } + } + } + + contextMenu.addSeparator(); + contextMenu.addMenu(executeMenu); + } + } + } + else + { + caf::CmdFeature* feature = commandManager->getCommandFeature(commandIds[i].toStdString()); + if (feature->canFeatureBeExecuted()) + { + QAction* act = commandManager->action(commandIds[i]); + CVF_ASSERT(act); + + contextMenu.addAction(act); + } + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimProject::appendScriptItems(QMenu* menu, RimScriptCollection* scriptCollection) +{ + CVF_ASSERT(menu); + + QDir dir(scriptCollection->directory); + QMenu* subMenu = menu->addMenu(dir.dirName()); + + caf::CmdFeatureManager* commandManager = caf::CmdFeatureManager::instance(); + CVF_ASSERT(commandManager); + + RicExecuteScriptForCasesFeature* executeScriptFeature = dynamic_cast(commandManager->getCommandFeature("RicExecuteScriptForCasesFeature")); + CVF_ASSERT(executeScriptFeature); + + for (size_t i = 0; i < scriptCollection->calcScripts.size(); i++) + { + RimCalcScript* calcScript = scriptCollection->calcScripts[i]; + QFileInfo fi(calcScript->absolutePath()); + + QString menuText = fi.baseName(); + QAction* scriptAction = subMenu->addAction(menuText, executeScriptFeature, SLOT(slotExecuteScriptForSelectedCases())); + + scriptAction->setData(QVariant(calcScript->absolutePath())); + } + + for (size_t i = 0; i < scriptCollection->subDirectories.size(); i++) + { + RimScriptCollection* subDir = scriptCollection->subDirectories[i]; + + appendScriptItems(subMenu, subDir); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimProject::defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName /*= ""*/) +{ + if (viewLinkerCollection()->viewLinker()) + { + // Use object instead of field to avoid duplicate entries in the tree view + uiTreeOrdering.add(viewLinkerCollection()); + } + + RimOilField* oilField = activeOilField(); + if (oilField) + { + if (oilField->analysisModels()) uiTreeOrdering.add(oilField->analysisModels()); + if (oilField->geoMechModels()) uiTreeOrdering.add(oilField->geoMechModels()); + if (oilField->wellPathCollection()) uiTreeOrdering.add(oilField->wellPathCollection()); + } + + if (mainPlotCollection) + { + if (mainPlotCollection->wellLogPlotCollection()) + { + if (mainPlotCollection->wellLogPlotCollection()->wellLogPlots().size() > 0) + { + uiTreeOrdering.add(mainPlotCollection->wellLogPlotCollection()); + } + } + } + + uiTreeOrdering.add(scriptCollection()); + + uiTreeOrdering.setForgetRemainingFields(true); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimProject::recreateMainPlotCollection() +{ + if (!mainPlotCollection()) + { + mainPlotCollection = new RimMainPlotCollection(); + } +} + diff --git a/ApplicationCode/ProjectDataModel/RimProject.h b/ApplicationCode/ProjectDataModel/RimProject.h index 33cfa8906d..17d54e403e 100644 --- a/ApplicationCode/ProjectDataModel/RimProject.h +++ b/ApplicationCode/ProjectDataModel/RimProject.h @@ -20,18 +20,35 @@ #pragma once +#include "cafPdmChildArrayField.h" +#include "cafPdmChildField.h" #include "cafPdmDocument.h" -class RimOilField; -class RimEclipseCase; -class RimCase; +#include + +class RigCaseData; class RigGridManager; -class RimScriptCollection; -class RimIdenticalGridCaseGroup; class RigMainGrid; -class RigCaseData; -class RimWellPathImport; +class RimCase; class RimCommandObject; +class RimEclipseCase; +class RimIdenticalGridCaseGroup; +class RimViewLinker; +class RimViewLinkerCollection; +class RimMainPlotCollection; +class RimOilField; +class RimScriptCollection; +class RimView; +class RimWellPathImport; + +namespace caf +{ + class PdmUiTreeOrdering; +} + + +class QAction; +class QMenu; //================================================================================================== /// @@ -45,13 +62,16 @@ class RimProject : public caf::PdmDocument RimProject(void); virtual ~RimProject(void); - caf::PdmPointersField oilFields; - caf::PdmField scriptCollection; - caf::PdmField wellPathImport; - caf::PdmPointersField commandObjects; + caf::PdmChildArrayField oilFields; + caf::PdmChildField scriptCollection; + caf::PdmChildField wellPathImport; + caf::PdmChildField mainPlotCollection; + caf::PdmChildField viewLinkerCollection; + caf::PdmChildArrayField commandObjects; caf::PdmField treeViewState; caf::PdmField currentModelIndexPath; + void setScriptDirectories(const QString& scriptDirectories); QString projectFileVersionString() const; void close(); @@ -61,26 +81,37 @@ class RimProject : public caf::PdmDocument void assignCaseIdToCase(RimCase* reservoirCase); void assignIdToCaseGroup(RimIdenticalGridCaseGroup* caseGroup); - void allCases(std::vector& cases); + void allCases(std::vector& cases); + void allNotLinkedViews(std::vector& views); + void allVisibleViews(std::vector& views); + void createDisplayModelAndRedrawAllViews(); void computeUtmAreaOfInterest(); RimOilField* activeOilField(); + void actionsBasedOnSelection(QMenu& contextMenu); + + void recreateMainPlotCollection(); + protected: // Overridden methods void initScriptDirectories(); virtual void initAfterRead(); virtual void setupBeforeSave(); + virtual void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = ""); + +private: + void appendScriptItems(QMenu* menu, RimScriptCollection* scriptCollection); + private: caf::PdmField m_projectFileVersionString; caf::PdmField nextValidCaseId; // Unique case ID within a project, used to identify a case from Octave scripts caf::PdmField nextValidCaseGroupId; // Unique case group ID within a project, used to identify a case group from Octave scripts - caf::PdmPointersField casesObsolete; // obsolete - caf::PdmPointersField caseGroupsObsolete; // obsolete - + caf::PdmChildArrayField casesObsolete; // obsolete + caf::PdmChildArrayField caseGroupsObsolete; // obsolete }; diff --git a/ApplicationCode/ProjectDataModel/RimReservoirCellResultsStorage.cpp b/ApplicationCode/ProjectDataModel/RimReservoirCellResultsStorage.cpp index 1be966dc4b..63a2d10190 100644 --- a/ApplicationCode/ProjectDataModel/RimReservoirCellResultsStorage.cpp +++ b/ApplicationCode/ProjectDataModel/RimReservoirCellResultsStorage.cpp @@ -50,9 +50,9 @@ RimReservoirCellResultsStorage::RimReservoirCellResultsStorage() CAF_PDM_InitObject("Cacher", "", "", ""); CAF_PDM_InitField(&m_resultCacheFileName, "ResultCacheFileName", QString(), "UiDummyname", "", "" ,""); - m_resultCacheFileName.setUiHidden(true); + m_resultCacheFileName.uiCapability()->setUiHidden(true); CAF_PDM_InitFieldNoDefault(&m_resultCacheMetaData, "ResultCacheEntries", "UiDummyname", "", "", ""); - m_resultCacheMetaData.setUiHidden(true); + m_resultCacheMetaData.uiCapability()->setUiHidden(true); } @@ -231,9 +231,7 @@ size_t RimReservoirCellResultsStorage::findOrLoadScalarResult(const QString& res { if (!m_cellResults) return cvf::UNDEFINED_SIZE_T; - size_t scalarResultIndex = cvf::UNDEFINED_SIZE_T; - - scalarResultIndex = this->findOrLoadScalarResult(RimDefines::STATIC_NATIVE, resultName); + size_t scalarResultIndex = this->findOrLoadScalarResult(RimDefines::STATIC_NATIVE, resultName); if (scalarResultIndex == cvf::UNDEFINED_SIZE_T) { @@ -978,16 +976,6 @@ void RimReservoirCellResultsStorage::computeNncCombRiTrans() bool hasNTGResults = ntgResultIdx != cvf::UNDEFINED_SIZE_T; - // Get the result count, to handle that one of them might be globally defined - - size_t permxResultValueCount = m_cellResults->cellScalarResults(permXResultIdx)[0].size(); - size_t resultValueCount = permxResultValueCount; - if (hasNTGResults) - { - size_t ntgResultValueCount = m_cellResults->cellScalarResults(ntgResultIdx)[0].size(); - resultValueCount = CVF_MIN(permxResultValueCount, ntgResultValueCount); - } - // Get all the actual result values std::vector & permXResults = m_cellResults->cellScalarResults(permXResultIdx)[0]; @@ -1028,7 +1016,6 @@ void RimReservoirCellResultsStorage::computeNncCombRiTrans() } const RigActiveCellInfo* activeCellInfo = m_cellResults->activeCellInfo(); - const std::vector& nodes = m_ownerMainGrid->nodes(); bool isFaceNormalsOutwards = m_ownerMainGrid->isFaceNormalsOutwards(); // NNC calculation @@ -1217,8 +1204,6 @@ void RimReservoirCellResultsStorage::computeRiMULTComponent(const QString& riMul // Set up output container to correct number of results riMultResults.resize(resultValueCount); - - const RigActiveCellInfo* activeCellInfo = m_cellResults->activeCellInfo(); for (size_t vIdx = 0; vIdx < transResults.size(); ++vIdx) { @@ -1313,7 +1298,6 @@ void RimReservoirCellResultsStorage::computeRiTRANSbyAreaComponent(const QString const RigActiveCellInfo* activeCellInfo = m_cellResults->activeCellInfo(); const std::vector& nodes = m_ownerMainGrid->nodes(); - bool isFaceNormalsOutwards = m_ownerMainGrid->isFaceNormalsOutwards(); for (size_t nativeResvCellIndex = 0; nativeResvCellIndex < m_ownerMainGrid->cells().size(); nativeResvCellIndex++) { @@ -1528,7 +1512,7 @@ double RimReservoirCellResultsStorage::darchysValue() double darchy = 0.008527; // (ECLIPSE 100) (METRIC) RimEclipseCase* rimCase = NULL; - this->firstAncestorOfType(rimCase); + this->firstAnchestorOrThisOfType(rimCase); if (rimCase && rimCase->reservoirData()) { diff --git a/ApplicationCode/ProjectDataModel/RimReservoirCellResultsStorage.h b/ApplicationCode/ProjectDataModel/RimReservoirCellResultsStorage.h index 4e9fbffe3e..1acdcfd157 100644 --- a/ApplicationCode/ProjectDataModel/RimReservoirCellResultsStorage.h +++ b/ApplicationCode/ProjectDataModel/RimReservoirCellResultsStorage.h @@ -20,13 +20,16 @@ #pragma once +#include "RimDefines.h" + #include "cafAppEnum.h" +#include "cafPdmChildArrayField.h" #include "cafPdmField.h" #include "cafPdmObject.h" + #include "cvfBase.h" #include "cvfObject.h" -#include "RimDefines.h" #include @@ -80,7 +83,7 @@ class RimReservoirCellResultsStorage : public caf::PdmObject QString getCacheDirectoryPath(); // Fields caf::PdmField m_resultCacheFileName; - caf::PdmPointersField + caf::PdmChildArrayField m_resultCacheMetaData; cvf::ref m_readerInterface; diff --git a/ApplicationCode/ProjectDataModel/RimScriptCollection.cpp b/ApplicationCode/ProjectDataModel/RimScriptCollection.cpp index eb26bf7a83..04908c574c 100644 --- a/ApplicationCode/ProjectDataModel/RimScriptCollection.cpp +++ b/ApplicationCode/ProjectDataModel/RimScriptCollection.cpp @@ -21,7 +21,6 @@ #include "RimScriptCollection.h" #include "RimCalcScript.h" -#include "RimUiTreeModelPdm.h" #include "RiuMainWindow.h" #include "cafPdmUiFilePathEditor.h" @@ -40,9 +39,11 @@ RimScriptCollection::RimScriptCollection() CAF_PDM_InitFieldNoDefault(&directory, "ScriptDirectory", "Dir", "", "", ""); CAF_PDM_InitFieldNoDefault(&calcScripts, "CalcScripts", "", "", "", ""); + calcScripts.uiCapability()->setUiHidden(true); CAF_PDM_InitFieldNoDefault(&subDirectories, "SubDirectories", "", "", "", ""); + subDirectories.uiCapability()->setUiHidden(true); - directory.setUiEditorTypeName(caf::PdmUiFilePathEditor::uiEditorTypeName()); + directory.uiCapability()->setUiEditorTypeName(caf::PdmUiFilePathEditor::uiEditorTypeName()); } //-------------------------------------------------------------------------------------------------- @@ -176,8 +177,6 @@ void RimScriptCollection::fieldChangedByUi(const caf::PdmFieldHandle *changedFie QFileInfo fi(directory); this->setUiName(fi.baseName()); this->readContentFromDisc(); - RimUiTreeModelPdm* treeModel = RiuMainWindow::instance()->uiPdmModel(); - if (treeModel) treeModel->updateUiSubTree(this); } } diff --git a/ApplicationCode/ProjectDataModel/RimScriptCollection.h b/ApplicationCode/ProjectDataModel/RimScriptCollection.h index 2562a3c83c..094d89abff 100644 --- a/ApplicationCode/ProjectDataModel/RimScriptCollection.h +++ b/ApplicationCode/ProjectDataModel/RimScriptCollection.h @@ -20,6 +20,7 @@ #pragma once +#include "cafPdmChildArrayField.h" #include "cafPdmField.h" #include "cafPdmObject.h" @@ -43,10 +44,10 @@ class RimScriptCollection : public caf::PdmObject virtual ~RimScriptCollection(); public: // Pdm Fields - caf::PdmField directory; - caf::PdmPointersField calcScripts; + caf::PdmField directory; + caf::PdmChildArrayField calcScripts; - caf::PdmPointersField subDirectories; + caf::PdmChildArrayField subDirectories; public: // Methods void readContentFromDisc(); diff --git a/ApplicationCode/ProjectDataModel/RimTernaryLegendConfig.cpp b/ApplicationCode/ProjectDataModel/RimTernaryLegendConfig.cpp index 8dea112676..0c107d4f2c 100644 --- a/ApplicationCode/ProjectDataModel/RimTernaryLegendConfig.cpp +++ b/ApplicationCode/ProjectDataModel/RimTernaryLegendConfig.cpp @@ -57,29 +57,29 @@ RimTernaryLegendConfig::RimTernaryLegendConfig() CAF_PDM_InitField(&rangeMode, "RangeType", RangeModeEnum(USER_DEFINED), "Range type", "", "Switches between automatic and user defined range on the legend", ""); CAF_PDM_InitFieldNoDefault(&applyLocalMinMax, "m_applyLocalMinMax", "", "", "", ""); - applyLocalMinMax.setIOWritable(false); - applyLocalMinMax.setIOReadable(false); - applyLocalMinMax.setUiEditorTypeName(caf::PdmUiPushButtonEditor::uiEditorTypeName()); - applyLocalMinMax.setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN); + applyLocalMinMax.xmlCapability()->setIOWritable(false); + applyLocalMinMax.xmlCapability()->setIOReadable(false); + applyLocalMinMax.uiCapability()->setUiEditorTypeName(caf::PdmUiPushButtonEditor::uiEditorTypeName()); + applyLocalMinMax.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN); applyLocalMinMax = false; CAF_PDM_InitFieldNoDefault(&applyGlobalMinMax, "m_applyGlobalMinMax", "", "", "", ""); - applyGlobalMinMax.setIOWritable(false); - applyGlobalMinMax.setIOReadable(false); - applyGlobalMinMax.setUiEditorTypeName(caf::PdmUiPushButtonEditor::uiEditorTypeName()); - applyGlobalMinMax.setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN); + applyGlobalMinMax.xmlCapability()->setIOWritable(false); + applyGlobalMinMax.xmlCapability()->setIOReadable(false); + applyGlobalMinMax.uiCapability()->setUiEditorTypeName(caf::PdmUiPushButtonEditor::uiEditorTypeName()); + applyGlobalMinMax.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN); applyGlobalMinMax = false; CAF_PDM_InitFieldNoDefault(&applyFullRangeMinMax, "m_applyFullRangeMinMax", "", "", "", ""); - applyFullRangeMinMax.setIOWritable(false); - applyFullRangeMinMax.setIOReadable(false); - applyFullRangeMinMax.setUiEditorTypeName(caf::PdmUiPushButtonEditor::uiEditorTypeName()); - applyFullRangeMinMax.setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN); + applyFullRangeMinMax.xmlCapability()->setIOWritable(false); + applyFullRangeMinMax.xmlCapability()->setIOReadable(false); + applyFullRangeMinMax.uiCapability()->setUiEditorTypeName(caf::PdmUiPushButtonEditor::uiEditorTypeName()); + applyFullRangeMinMax.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN); applyFullRangeMinMax = false; CAF_PDM_InitFieldNoDefault(&ternaryRangeSummary, "ternaryRangeSummary", "Range summary", "", "", ""); - ternaryRangeSummary.setUiEditorTypeName(caf::PdmUiTextEditor::uiEditorTypeName()); - ternaryRangeSummary.setUiLabelPosition(caf::PdmUiItemInfo::TOP); + ternaryRangeSummary.uiCapability()->setUiEditorTypeName(caf::PdmUiTextEditor::uiEditorTypeName()); + ternaryRangeSummary.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::TOP); CAF_PDM_InitField(&userDefinedMaxValueSoil, "UserDefinedMaxSoil", 1.0, "Max", "", "Min value of the legend", ""); @@ -96,7 +96,7 @@ RimTernaryLegendConfig::RimTernaryLegendConfig() m_localAutoMin.resize(3, 0.0); m_localAutoMax.resize(3, 1.0); - m_scalarMapper = new RivTernaryScalarMapper(cvf::Color3f::GRAY); + m_scalarMapper = new RivTernaryScalarMapper(cvf::Color3f::GRAY); recreateLegend(); updateLegend(); @@ -168,7 +168,7 @@ void RimTernaryLegendConfig::updateLegend() double swatUpper = 1.0; ternaryRanges(soilLower, soilUpper, sgasLower, sgasUpper, swatLower, swatUpper); - m_scalarMapper->setTernaryRanges(soilLower, soilUpper, sgasLower, sgasUpper); + m_scalarMapper->setTernaryRanges(soilLower, soilUpper, sgasLower, sgasUpper); cvf::String soilRange; cvf::String sgasRange; @@ -380,47 +380,47 @@ void RimTernaryLegendConfig::ternaryRanges(double& soilLower, double& soilUpper, void RimTernaryLegendConfig::updateLabelText() { { - userDefinedMinValueSoil.setUiName("Min"); - userDefinedMaxValueSoil.setUiName("Max"); + userDefinedMinValueSoil.uiCapability()->setUiName("Min"); + userDefinedMaxValueSoil.uiCapability()->setUiName("Max"); if (m_globalAutoMin[TERNARY_SOIL_IDX] != cvf::UNDEFINED_DOUBLE ) { - userDefinedMinValueSoil.setUiName(QString("Min ") + "(" + QString::number(m_globalAutoMin[TERNARY_SOIL_IDX], 'g', precision) + ")"); + userDefinedMinValueSoil.uiCapability()->setUiName(QString("Min ") + "(" + QString::number(m_globalAutoMin[TERNARY_SOIL_IDX], 'g', precision) + ")"); } if (m_globalAutoMax[TERNARY_SOIL_IDX] != cvf::UNDEFINED_DOUBLE ) { - userDefinedMaxValueSoil.setUiName(QString("Max ") + "(" + QString::number(m_globalAutoMax[TERNARY_SOIL_IDX], 'g', precision) + ")"); + userDefinedMaxValueSoil.uiCapability()->setUiName(QString("Max ") + "(" + QString::number(m_globalAutoMax[TERNARY_SOIL_IDX], 'g', precision) + ")"); } } { - userDefinedMinValueSgas.setUiName("Min"); - userDefinedMaxValueSgas.setUiName("Max"); + userDefinedMinValueSgas.uiCapability()->setUiName("Min"); + userDefinedMaxValueSgas.uiCapability()->setUiName("Max"); if (m_globalAutoMin[TERNARY_SGAS_IDX] != cvf::UNDEFINED_DOUBLE ) { - userDefinedMinValueSgas.setUiName(QString("Min ") + "(" + QString::number(m_globalAutoMin[TERNARY_SGAS_IDX], 'g', precision) + ")"); + userDefinedMinValueSgas.uiCapability()->setUiName(QString("Min ") + "(" + QString::number(m_globalAutoMin[TERNARY_SGAS_IDX], 'g', precision) + ")"); } if (m_globalAutoMax[TERNARY_SGAS_IDX] != cvf::UNDEFINED_DOUBLE ) { - userDefinedMaxValueSgas.setUiName(QString("Max ") + "(" + QString::number(m_globalAutoMax[TERNARY_SGAS_IDX], 'g', precision) + ")"); + userDefinedMaxValueSgas.uiCapability()->setUiName(QString("Max ") + "(" + QString::number(m_globalAutoMax[TERNARY_SGAS_IDX], 'g', precision) + ")"); } } { - userDefinedMinValueSwat.setUiName("Min"); - userDefinedMaxValueSwat.setUiName("Max"); + userDefinedMinValueSwat.uiCapability()->setUiName("Min"); + userDefinedMaxValueSwat.uiCapability()->setUiName("Max"); if (m_globalAutoMin[TERNARY_SWAT_IDX] != cvf::UNDEFINED_DOUBLE ) { - userDefinedMinValueSwat.setUiName(QString("Min ") + "(" + QString::number(m_globalAutoMin[TERNARY_SWAT_IDX], 'g', precision) + ")"); + userDefinedMinValueSwat.uiCapability()->setUiName(QString("Min ") + "(" + QString::number(m_globalAutoMin[TERNARY_SWAT_IDX], 'g', precision) + ")"); } if (m_globalAutoMax[TERNARY_SWAT_IDX] != cvf::UNDEFINED_DOUBLE ) { - userDefinedMaxValueSwat.setUiName(QString("Max ") + "(" + QString::number(m_globalAutoMax[TERNARY_SWAT_IDX], 'g', precision) + ")"); + userDefinedMaxValueSwat.uiCapability()->setUiName(QString("Max ") + "(" + QString::number(m_globalAutoMax[TERNARY_SWAT_IDX], 'g', precision) + ")"); } } @@ -449,6 +449,6 @@ void RimTernaryLegendConfig::updateLabelText() //-------------------------------------------------------------------------------------------------- RivTernaryScalarMapper* RimTernaryLegendConfig::scalarMapper() { - return m_scalarMapper.p(); + return m_scalarMapper.p(); } diff --git a/ApplicationCode/ProjectDataModel/RimTernaryLegendConfig.h b/ApplicationCode/ProjectDataModel/RimTernaryLegendConfig.h index 4e781bf388..321629cdec 100644 --- a/ApplicationCode/ProjectDataModel/RimTernaryLegendConfig.h +++ b/ApplicationCode/ProjectDataModel/RimTernaryLegendConfig.h @@ -72,8 +72,8 @@ class RimTernaryLegendConfig : public caf::PdmObject void recreateLegend(); - RivTernarySaturationOverlayItem* legend(); - RivTernaryScalarMapper* scalarMapper(); + RivTernarySaturationOverlayItem* legend(); + RivTernaryScalarMapper* scalarMapper(); protected: virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue); @@ -109,5 +109,5 @@ class RimTernaryLegendConfig : public caf::PdmObject caf::PdmPointer m_reservoirView; cvf::ref m_legend; - cvf::ref m_scalarMapper; + cvf::ref m_scalarMapper; }; diff --git a/ApplicationCode/ProjectDataModel/RimTreeViewStateSerializer.cpp b/ApplicationCode/ProjectDataModel/RimTreeViewStateSerializer.cpp new file mode 100644 index 0000000000..04ac193bed --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimTreeViewStateSerializer.cpp @@ -0,0 +1,129 @@ +#include "RimTreeViewStateSerializer.h" +#include + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void setExpandedState(QStringList& nodes, QTreeView* view, QAbstractItemModel* model, + const QModelIndex startIndex, QString path) +{ + path += QString::number(startIndex.row()) + QString::number(startIndex.column()); + for (int i = 0; i < model->rowCount(startIndex); ++i) + { + QModelIndex nextIndex = model->index(i, 0, startIndex); + QString nextPath = path + QString::number(nextIndex.row()) + QString::number(nextIndex.column()); + if(!nodes.contains(nextPath)) + continue; + + setExpandedState(nodes, view, model, model->index(i, 0, startIndex), path); + } + + if (nodes.contains(path)) + { + view->setExpanded( startIndex.sibling(startIndex.row(), 0), true ); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void storeExpandedState(QStringList & nodes, const QTreeView * view, QAbstractItemModel * model, + const QModelIndex startIndex, QString path) +{ + path += QString::number(startIndex.row()) + QString::number(startIndex.column()); + for (int i = 0; i < model->rowCount(startIndex); ++i) + { + if(!view->isExpanded(model->index(i, 0, startIndex))) + continue; + + storeExpandedState(nodes, view, model, model->index(i, 0, startIndex), path); + } + + if (view->isExpanded(startIndex)) + { + nodes << path; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimTreeViewStateSerializer::applyTreeViewStateFromString( QTreeView* treeView, const QString& treeViewState) +{ + if (treeView->model()) + { + treeView->collapseAll(); + + QStringList nodes = treeViewState.split(";"); + + QString path; + setExpandedState(nodes, treeView, treeView->model(), QModelIndex(), path); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimTreeViewStateSerializer::storeTreeViewStateToString(const QTreeView* treeView, QString& treeViewState) +{ + if (treeView->model()) + { + QStringList nodes; + QString path; + + storeExpandedState(nodes, treeView, treeView->model(), QModelIndex(), path); + + treeViewState = nodes.join(";"); + } +} + +//-------------------------------------------------------------------------------------------------- +/// Find index based of an encode QString ; ;...; +/// Set the decoded index as current index in the QAbstractItemView +//-------------------------------------------------------------------------------------------------- +QModelIndex RimTreeViewStateSerializer::getModelIndexFromString(QAbstractItemModel* model, const QString& currentIndexString) +{ + QStringList modelIndexStringList = currentIndexString.split(";"); + + QModelIndex mi; + + foreach (QString modelIndexString, modelIndexStringList) + { + QStringList items = modelIndexString.split(" "); + + if (items.size() != 2) continue; + + int row = items[0].toInt(); + int col = items[1].toInt(); + + mi = model->index(row, col, mi); + } + + return mi; +} + +//-------------------------------------------------------------------------------------------------- +/// Store path to model index in item view using follwoing encoding into a QString ; ;...; +//-------------------------------------------------------------------------------------------------- +void RimTreeViewStateSerializer::encodeStringFromModelIndex(const QModelIndex mi, QString& encodedModelIndex) +{ + if (!mi.isValid()) return; + + QModelIndex localModelIdx = mi; + + while (localModelIdx.isValid()) + { + if (encodedModelIndex.isEmpty()) + { + encodedModelIndex = QString("%1 %2").arg(localModelIdx.row()).arg(localModelIdx.column()) + encodedModelIndex; + } + else + { + encodedModelIndex = QString("%1 %2;").arg(localModelIdx.row()).arg(localModelIdx.column()) + encodedModelIndex; + } + localModelIdx = localModelIdx.parent(); + } +} + + + diff --git a/ApplicationCode/ProjectDataModel/RimTreeViewStateSerializer.h b/ApplicationCode/ProjectDataModel/RimTreeViewStateSerializer.h new file mode 100644 index 0000000000..7fe24ef03f --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimTreeViewStateSerializer.h @@ -0,0 +1,18 @@ +#pragma once + +#include + +class QTreeView; +class QString; +class QAbstractItemModel; + +class RimTreeViewStateSerializer +{ +public: + static void applyTreeViewStateFromString(QTreeView* treeView, const QString& treeViewState); + static void storeTreeViewStateToString (const QTreeView* treeView, QString& treeViewState); + + static QModelIndex getModelIndexFromString(QAbstractItemModel* model, const QString& currentIndexString); + static void encodeStringFromModelIndex(const QModelIndex mi, QString& currentIndexString); +}; + diff --git a/ApplicationCode/ProjectDataModel/RimUiTreeModelPdm.cpp b/ApplicationCode/ProjectDataModel/RimUiTreeModelPdm.cpp deleted file mode 100644 index ccb645ba4a..0000000000 --- a/ApplicationCode/ProjectDataModel/RimUiTreeModelPdm.cpp +++ /dev/null @@ -1,1201 +0,0 @@ -///////////////////////////////////////////////////////////////////////////////// -// -// Copyright (C) 2011- Statoil ASA -// Copyright (C) 2013- Ceetron Solutions AS -// Copyright (C) 2011-2012 Ceetron AS -// -// ResInsight is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. -// -// See the GNU General Public License at -// for more details. -// -///////////////////////////////////////////////////////////////////////////////// - -#include "RimUiTreeModelPdm.h" - -#include "RiaApplication.h" -#include "RigGridManager.h" -#include "RimEclipseCaseCollection.h" -#include "RimEclipseCase.h" -#include "RimCaseCollection.h" -#include "RimEclipsePropertyFilterCollection.h" -#include "RimCellRangeFilterCollection.h" -#include "RimGeoMechPropertyFilterCollection.h" -#include "RimGeoMechPropertyFilter.h" -#include "RimIdenticalGridCaseGroup.h" -#include "RimEclipseInputCase.h" -#include "RimEclipseInputProperty.h" -#include "RimEclipseInputPropertyCollection.h" -#include "RimMimeData.h" -#include "RimOilField.h" -#include "RimProject.h" -#include "RimEclipseView.h" -#include "RimEclipseResultCase.h" -#include "RimScriptCollection.h" -#include "RimEclipseStatisticsCase.h" -#include "RimUiTreeView.h" -#include "RimEclipseWellCollection.h" -#include "RimWellPathCollection.h" -#include "RimGeoMechView.h" - -#include "cvfAssert.h" - -#include -#include -#include "RimGeoMechCase.h" - - - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RimUiTreeModelPdm::RimUiTreeModelPdm(QObject* parent) - : caf::UiTreeModelPdm(parent) -{ - m_scriptChangeDetector = new QFileSystemWatcher(this); - this->updateScriptPaths(); - connect(m_scriptChangeDetector, SIGNAL(directoryChanged(QString)), this, SLOT(slotRefreshScriptTree(QString))); - connect(m_scriptChangeDetector, SIGNAL(fileChanged(QString)), this, SLOT(slotRefreshScriptTree(QString))); -} - - - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool RimUiTreeModelPdm::deletePropertyFilter(const QModelIndex& itemIndex) -{ - CVF_ASSERT(itemIndex.isValid()); - - caf::PdmUiTreeItem* uiItem = getTreeItemFromIndex(itemIndex); - CVF_ASSERT(uiItem); - - RimEclipsePropertyFilter* propertyFilter = dynamic_cast(uiItem->dataObject().p()); - CVF_ASSERT(propertyFilter); - - RimEclipsePropertyFilterCollection* propertyFilterCollection = propertyFilter->parentContainer(); - CVF_ASSERT(propertyFilterCollection); - - bool wasFilterActive = propertyFilter->isActive(); - bool wasSomeFilterActive = propertyFilterCollection->hasActiveFilters(); - - // Remove Ui items pointing at the pdm object to delete - removeRows_special(itemIndex.row(), 1, itemIndex.parent()); // To be deleted - - propertyFilterCollection->remove(propertyFilter); - delete propertyFilter; - - // updateUiSubTree(propertyFilterCollection); // To be enabled - - if (wasFilterActive) - { - propertyFilterCollection->reservoirView()->scheduleGeometryRegen(PROPERTY_FILTERED); - } - - if (wasSomeFilterActive) - { - propertyFilterCollection->reservoirView()->createDisplayModelAndRedraw(); - } - - clearClipboard(); - - return true; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool RimUiTreeModelPdm::deleteGeoMechPropertyFilter(const QModelIndex& itemIndex) -{ - CVF_ASSERT(itemIndex.isValid()); - - caf::PdmUiTreeItem* uiItem = getTreeItemFromIndex(itemIndex); - CVF_ASSERT(uiItem); - - RimGeoMechPropertyFilter* propertyFilter = dynamic_cast(uiItem->dataObject().p()); - CVF_ASSERT(propertyFilter); - - RimGeoMechPropertyFilterCollection* propertyFilterCollection = propertyFilter->parentContainer(); - CVF_ASSERT(propertyFilterCollection); - - bool wasFilterActive = propertyFilter->isActive(); - bool wasSomeFilterActive = propertyFilterCollection->hasActiveFilters(); - - // Remove Ui items pointing at the pdm object to delete - removeRows_special(itemIndex.row(), 1, itemIndex.parent()); // To be deleted - - propertyFilterCollection->remove(propertyFilter); - delete propertyFilter; - - // updateUiSubTree(propertyFilterCollection); // To be enabled - - if (wasFilterActive) - { - propertyFilterCollection->reservoirView()->scheduleGeometryRegen(PROPERTY_FILTERED); - } - - if (wasSomeFilterActive) - { - propertyFilterCollection->reservoirView()->createDisplayModelAndRedraw(); - } - - clearClipboard(); - - return true; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool RimUiTreeModelPdm::deleteRangeFilter(const QModelIndex& itemIndex) -{ - CVF_ASSERT(itemIndex.isValid()); - - caf::PdmUiTreeItem* uiItem = getTreeItemFromIndex(itemIndex); - CVF_ASSERT(uiItem); - - RimCellRangeFilter* rangeFilter = dynamic_cast(uiItem->dataObject().p()); - CVF_ASSERT(rangeFilter); - - RimCellRangeFilterCollection* rangeFilterCollection = rangeFilter->parentContainer(); - CVF_ASSERT(rangeFilterCollection); - - bool wasFilterActive = rangeFilter->isActive(); - bool wasSomeFilterActive = rangeFilterCollection->hasActiveFilters(); - - // Remove Ui items pointing at the pdm object to delete - removeRows_special(itemIndex.row(), 1, itemIndex.parent()); // To be deleted - - rangeFilterCollection->remove(rangeFilter); - delete rangeFilter; - - // updateUiSubTree(rangeFilterCollection); // To be enabled - - if (wasFilterActive) - { - rangeFilterCollection->reservoirView()->scheduleGeometryRegen(PROPERTY_FILTERED); - } - - if (wasSomeFilterActive) - { - rangeFilterCollection->reservoirView()->createDisplayModelAndRedraw(); - } - - clearClipboard(); - - return true; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimUiTreeModelPdm::deleteReservoirViews(const std::vector& treeSelection) -{ - std::set ownerCases; - - for (size_t sIdx = 0; sIdx < treeSelection.size(); ++sIdx) - { - RimView* reservoirView = dynamic_cast(treeSelection[sIdx]); - ownerCases.insert(reservoirView->ownerCase()); - - reservoirView->removeFromParentFields(); - delete reservoirView; - - } - - for (std::set::iterator it = ownerCases.begin(); it != ownerCases.end(); ++it) - { - updateUiSubTree(*it); - } - - clearClipboard(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimUiTreeModelPdm::deleteGeoMechCases(const std::vector& treeSelection) -{ - std::set allParents; - - for (size_t sIdx = 0; sIdx < treeSelection.size(); ++sIdx) - { - RimGeoMechCase* geomCase = dynamic_cast(treeSelection[sIdx]); - if (!geomCase) continue; - - std::vector parents; - geomCase->parentObjects(parents); - for (size_t pIdx = 0; pIdx < treeSelection.size(); ++pIdx) - { - allParents.insert(parents[pIdx]); - } - - geomCase->removeFromParentFields(); - delete geomCase; - } - - for (std::set::iterator it = allParents.begin(); it != allParents.end(); ++it) - { - updateUiSubTree(*it); - } - - clearClipboard(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimUiTreeModelPdm::deleteReservoir(RimEclipseCase* reservoir) -{ - if (reservoir->parentCaseCollection()) - { - RimCaseCollection* caseCollection = reservoir->parentCaseCollection(); - QModelIndex caseCollectionModelIndex = getModelIndexFromPdmObject(caseCollection); - if (!caseCollectionModelIndex.isValid()) return; - - QModelIndex mi = getModelIndexFromPdmObjectRecursive(caseCollectionModelIndex, reservoir); - if (mi.isValid()) - { - caf::PdmUiTreeItem* uiItem = getTreeItemFromIndex(mi); - CVF_ASSERT(uiItem); - - // Remove Ui items pointing at the pdm object to delete - removeRows_special(mi.row(), 1, mi.parent()); - } - - if (RimIdenticalGridCaseGroup::isStatisticsCaseCollection(caseCollection)) - { - RimIdenticalGridCaseGroup* caseGroup = caseCollection->parentCaseGroup(); - CVF_ASSERT(caseGroup); - - caseGroup->statisticsCaseCollection()->reservoirs.removeChildObject(reservoir); - } - else - { - RimProject* proj = RiaApplication::instance()->project(); - RimOilField* activeOilField = proj ? proj->activeOilField() : NULL; - RimEclipseCaseCollection* analysisModels = (activeOilField) ? activeOilField->analysisModels() : NULL; - if (analysisModels) analysisModels->removeCaseFromAllGroups(reservoir); - } - } - else - { - RimProject* proj = RiaApplication::instance()->project(); - QModelIndex mi = getModelIndexFromPdmObject(reservoir); - if (mi.isValid()) - { - caf::PdmUiTreeItem* uiItem = getTreeItemFromIndex(mi); - CVF_ASSERT(uiItem); - - // Remove Ui items pointing at the pdm object to delete - removeRows_special(mi.row(), 1, mi.parent()); - } - - RimOilField* activeOilField = proj ? proj->activeOilField() : NULL; - RimEclipseCaseCollection* analysisModels = (activeOilField) ? activeOilField->analysisModels() : NULL; - if (analysisModels) analysisModels->removeCaseFromAllGroups(reservoir); - } - - delete reservoir; - - clearClipboard(); -} - - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RimEclipsePropertyFilter* RimUiTreeModelPdm::addPropertyFilter(const QModelIndex& itemIndex, QModelIndex& insertedModelIndex) -{ - caf::PdmUiTreeItem* currentItem = getTreeItemFromIndex(itemIndex); - - QModelIndex collectionIndex; - RimEclipsePropertyFilterCollection* propertyFilterCollection = NULL; - caf::PdmUiTreeItem* propertyFilterCollectionItem = NULL; - int position = 0; - - if (dynamic_cast(currentItem->dataObject().p())) - { - RimEclipsePropertyFilter* propertyFilter = dynamic_cast(currentItem->dataObject().p()); - propertyFilterCollection = propertyFilter->parentContainer(); - propertyFilterCollectionItem = currentItem->parent(); - position = itemIndex.row(); - collectionIndex = itemIndex.parent(); - } - else if (dynamic_cast(currentItem->dataObject().p())) - { - propertyFilterCollection = dynamic_cast(currentItem->dataObject().p()); - propertyFilterCollectionItem = currentItem; - position = propertyFilterCollectionItem->childCount(); - collectionIndex = itemIndex; - } - - beginInsertRows(collectionIndex, position, position); - - RimEclipsePropertyFilter* propertyFilter = propertyFilterCollection->createAndAppendPropertyFilter(); - caf::PdmUiTreeItem* childItem = new caf::PdmUiTreeItem(propertyFilterCollectionItem, position, propertyFilter); - - endInsertRows(); - - insertedModelIndex = index(position, 0, collectionIndex); - - if (propertyFilterCollection) - { - propertyFilterCollection->reservoirView()->scheduleGeometryRegen(PROPERTY_FILTERED); - } - - return propertyFilter; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RimGeoMechPropertyFilter* RimUiTreeModelPdm::addGeoMechPropertyFilter(const QModelIndex& itemIndex, QModelIndex& insertedModelIndex) -{ - caf::PdmUiTreeItem* currentItem = getTreeItemFromIndex(itemIndex); - - QModelIndex collectionIndex; - RimGeoMechPropertyFilterCollection* propertyFilterCollection = NULL; - caf::PdmUiTreeItem* propertyFilterCollectionItem = NULL; - int position = 0; - - if (dynamic_cast(currentItem->dataObject().p())) - { - RimGeoMechPropertyFilter* propertyFilter = dynamic_cast(currentItem->dataObject().p()); - propertyFilterCollection = propertyFilter->parentContainer(); - propertyFilterCollectionItem = currentItem->parent(); - position = itemIndex.row(); - collectionIndex = itemIndex.parent(); - } - else if (dynamic_cast(currentItem->dataObject().p())) - { - propertyFilterCollection = dynamic_cast(currentItem->dataObject().p()); - propertyFilterCollectionItem = currentItem; - position = propertyFilterCollectionItem->childCount(); - collectionIndex = itemIndex; - } - - beginInsertRows(collectionIndex, position, position); - - RimGeoMechPropertyFilter* propertyFilter = propertyFilterCollection->createAndAppendPropertyFilter(); - caf::PdmUiTreeItem* childItem = new caf::PdmUiTreeItem(propertyFilterCollectionItem, position, propertyFilter); - - endInsertRows(); - - insertedModelIndex = index(position, 0, collectionIndex); - - if (propertyFilterCollection) - { - static_cast(propertyFilterCollection->reservoirView())->scheduleGeometryRegen(PROPERTY_FILTERED); - } - - return propertyFilter; -} - - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RimCellRangeFilter* RimUiTreeModelPdm::addRangeFilter(const QModelIndex& itemIndex, QModelIndex& insertedModelIndex) -{ - caf::PdmUiTreeItem* currentItem = getTreeItemFromIndex(itemIndex); - - QModelIndex collectionIndex; - RimCellRangeFilterCollection* rangeFilterCollection = NULL; - caf::PdmUiTreeItem* rangeFilterCollectionItem = NULL; - int position = 0; - - if (dynamic_cast(currentItem->dataObject().p())) - { - RimCellRangeFilter* rangeFilter = dynamic_cast(currentItem->dataObject().p()); - rangeFilterCollection = rangeFilter->parentContainer(); - rangeFilterCollectionItem = currentItem->parent(); - position = itemIndex.row(); - collectionIndex = itemIndex.parent(); - } - else if (dynamic_cast(currentItem->dataObject().p())) - { - rangeFilterCollection = dynamic_cast(currentItem->dataObject().p()); - rangeFilterCollectionItem = currentItem; - position = rangeFilterCollectionItem->childCount(); - collectionIndex = itemIndex; - } - - beginInsertRows(collectionIndex, position, position); - - RimCellRangeFilter* rangeFilter = rangeFilterCollection->createAndAppendRangeFilter(); - caf::PdmUiTreeItem* childItem = new caf::PdmUiTreeItem(rangeFilterCollectionItem, position, rangeFilter); - - endInsertRows(); - - insertedModelIndex = index(position, 0, collectionIndex); - if (rangeFilterCollection) - { - rangeFilterCollection->reservoirView()->scheduleGeometryRegen(RANGE_FILTERED); - rangeFilterCollection->reservoirView()->scheduleGeometryRegen(RANGE_FILTERED_INACTIVE); - - } - return rangeFilter; -} - - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RimView* RimUiTreeModelPdm::addReservoirView(const std::vector& treeSelection) -{ - if (!treeSelection.size() || treeSelection[0] == NULL) return NULL; - - caf::PdmUiItem* currentItem = treeSelection[0]; - - // Establish type of selected object - RimEclipseCase* eclipseCase = dynamic_cast(currentItem); - RimGeoMechCase* geomCase = dynamic_cast(currentItem); - RimGeoMechView* geoMechView = dynamic_cast(currentItem); - RimEclipseView* reservoirView = dynamic_cast(currentItem); - - // Find case to insert into - - if (geoMechView) geomCase = geoMechView->geoMechCase(); - if (reservoirView) eclipseCase = reservoirView->eclipseCase(); - - RimView* insertedView = NULL; - - if (eclipseCase) - { - insertedView = eclipseCase->createAndAddReservoirView(); - } - else if (geomCase) - { - insertedView = geomCase->createAndAddReservoirView(); - } - - // Must be run before buildViewItems, as wells are created in this function - - insertedView->loadDataAndUpdate(); - - if (eclipseCase ) this->updateUiSubTree(eclipseCase); - if (geomCase ) this->updateUiSubTree(geomCase); - - return insertedView; -} - - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimUiTreeModelPdm::updateScriptPaths() -{ - RimProject* proj = RiaApplication::instance()->project(); - - if (!proj || !proj->scriptCollection()) return; - - QStringList paths; - - proj->scriptCollection()->pathsAndSubPaths(paths); - - if (m_scriptChangeDetector->directories().size()) m_scriptChangeDetector->removePaths( m_scriptChangeDetector->directories()); - if (m_scriptChangeDetector->files().size()) m_scriptChangeDetector->removePaths( m_scriptChangeDetector->files()); - - if (paths.size()) m_scriptChangeDetector->addPaths(paths); -} - - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimUiTreeModelPdm::slotRefreshScriptTree(QString path) -{ - RimProject* proj = RiaApplication::instance()->project(); - - if (!proj || !proj->scriptCollection()) return; - - RimScriptCollection* changedSColl = proj->scriptCollection()->findScriptCollection(path); - if (changedSColl) - { - changedSColl->readContentFromDisc(); - this->updateUiSubTree(changedSColl); - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimUiTreeModelPdm::addInputProperty(const QModelIndex& itemIndex, const QStringList& fileNames) -{ - caf::PdmUiTreeItem* currentItem = getTreeItemFromIndex(itemIndex); - - RimEclipseInputPropertyCollection* inputPropertyCollection = dynamic_cast(currentItem->dataObject().p()); - CVF_ASSERT(inputPropertyCollection); - - std::vector parentObjects; - inputPropertyCollection->parentObjectsOfType(parentObjects); - CVF_ASSERT(parentObjects.size() == 1); - - RimEclipseInputCase* inputReservoir = parentObjects[0]; - CVF_ASSERT(inputReservoir); - if (inputReservoir) - { - inputReservoir->openDataFileSet(fileNames); - } - - this->updateUiSubTree(inputPropertyCollection); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimUiTreeModelPdm::deleteInputProperty(const QModelIndex& itemIndex) -{ - if (!itemIndex.isValid()) return; - - caf::PdmUiTreeItem* uiItem = getTreeItemFromIndex(itemIndex); - if (!uiItem) return; - - caf::PdmObject* object = uiItem->dataObject().p(); - RimEclipseInputProperty* inputProperty = dynamic_cast(object); - if (!inputProperty) return; - - // Remove item from UI tree model before delete of project data structure - removeRows_special(itemIndex.row(), 1, itemIndex.parent()); - - std::vector parentObjects; - object->parentObjectsOfType(parentObjects); - CVF_ASSERT(parentObjects.size() == 1); - - RimEclipseInputPropertyCollection* inputPropertyCollection = parentObjects[0]; - if (!inputPropertyCollection) return; - - std::vector parentObjects2; - inputPropertyCollection->parentObjectsOfType(parentObjects2); - CVF_ASSERT(parentObjects2.size() == 1); - - RimEclipseInputCase* inputReservoir = parentObjects2[0]; - if (!inputReservoir) return; - - inputReservoir->removeProperty(inputProperty); - - delete inputProperty; - - clearClipboard(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RimEclipseStatisticsCase* RimUiTreeModelPdm::addStatisticalCalculation(const QModelIndex& itemIndex, QModelIndex& insertedModelIndex) -{ - caf::PdmUiTreeItem* currentItem = getTreeItemFromIndex(itemIndex); - - QModelIndex collectionIndex; - RimIdenticalGridCaseGroup* caseGroup = NULL; - caf::PdmUiTreeItem* parentCollectionItem = NULL; - int position = 0; - - if (dynamic_cast(currentItem->dataObject().p())) - { - RimEclipseStatisticsCase* currentObject = dynamic_cast(currentItem->dataObject().p()); - caseGroup = currentObject->parentStatisticsCaseCollection()->parentCaseGroup(); - parentCollectionItem = currentItem->parent(); - position = itemIndex.row(); - collectionIndex = itemIndex.parent(); - } - else if (dynamic_cast(currentItem->dataObject().p())) - { - RimCaseCollection* statColl = dynamic_cast(currentItem->dataObject().p()); - caseGroup = statColl->parentCaseGroup(); - parentCollectionItem = currentItem; - position = parentCollectionItem->childCount(); - collectionIndex = itemIndex; - } - - if (parentCollectionItem && caseGroup) - { - beginInsertRows(collectionIndex, position, position); - - RimProject* proj = RiaApplication::instance()->project(); - RimEclipseStatisticsCase* createdObject = caseGroup->createAndAppendStatisticsCase(); - proj->assignCaseIdToCase(createdObject); - - caf::PdmUiTreeItem* childItem = new caf::PdmUiTreeItem(parentCollectionItem, position, createdObject); - - endInsertRows(); - - insertedModelIndex = index(position, 0, collectionIndex); - - return createdObject; - } - else - { - return NULL; - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RimIdenticalGridCaseGroup* RimUiTreeModelPdm::addCaseGroup(QModelIndex& insertedModelIndex) -{ - RimProject* proj = RiaApplication::instance()->project(); - CVF_ASSERT(proj); - - RimEclipseCaseCollection* analysisModels = proj->activeOilField() ? proj->activeOilField()->analysisModels() : NULL; - - if (analysisModels) - { - RimIdenticalGridCaseGroup* createdObject = new RimIdenticalGridCaseGroup; - proj->assignIdToCaseGroup(createdObject); - - RimEclipseCase* createdReservoir = createdObject->createAndAppendStatisticsCase(); - proj->assignCaseIdToCase(createdReservoir); - createdObject->name = QString("Grid Case Group %1").arg(analysisModels->caseGroups().size() + 1); - - analysisModels->caseGroups().push_back(createdObject); - - this->updateUiSubTree(analysisModels); - insertedModelIndex = getModelIndexFromPdmObject(createdObject); - - return createdObject; - } - else - { - return NULL; - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimUiTreeModelPdm::addObjects(const QModelIndex& itemIndex, const caf::PdmObjectGroup& pdmObjects) -{ - RimProject* proj = RiaApplication::instance()->project(); - CVF_ASSERT(proj); - - RimIdenticalGridCaseGroup* gridCaseGroup = gridCaseGroupFromItemIndex(itemIndex); - if (gridCaseGroup) - { - std::vector > typedObjects; - pdmObjects.createCopyByType(&typedObjects); - - if (typedObjects.size() == 0) - { - return; - } - - RimEclipseResultCase* mainResultCase = NULL; - std::vector< std::vector > mainCaseGridDimensions; - - // Read out main grid and main grid dimensions if present in case group - if (gridCaseGroup->mainCase()) - { - mainResultCase = dynamic_cast(gridCaseGroup->mainCase()); - CVF_ASSERT(mainResultCase); - - mainResultCase->readGridDimensions(mainCaseGridDimensions); - } - - std::vector insertedCases; - - // Add cases to case group - for (size_t i = 0; i < typedObjects.size(); i++) - { - RimEclipseResultCase* rimResultReservoir = typedObjects[i]; - - proj->assignCaseIdToCase(rimResultReservoir); - - if (gridCaseGroup->contains(rimResultReservoir)) - { - continue; - } - - insertedCases.push_back(rimResultReservoir); - } - - // Initialize the new objects - for (size_t i = 0; i < insertedCases.size(); i++) - { - RimEclipseResultCase* rimResultReservoir = insertedCases[i]; - caf::PdmDocument::initAfterReadTraversal(rimResultReservoir); - } - - // Load stuff - for (size_t i = 0; i < insertedCases.size(); i++) - { - RimEclipseResultCase* rimResultReservoir = insertedCases[i]; - - - if (!mainResultCase) - { - rimResultReservoir->openEclipseGridFile(); - rimResultReservoir->readGridDimensions(mainCaseGridDimensions); - - mainResultCase = rimResultReservoir; - } - else - { - std::vector< std::vector > caseGridDimensions; - rimResultReservoir->readGridDimensions(caseGridDimensions); - - bool identicalGrid = RigGridManager::isGridDimensionsEqual(mainCaseGridDimensions, caseGridDimensions); - if (!identicalGrid) - { - continue; - } - - if (!rimResultReservoir->openAndReadActiveCellData(mainResultCase->reservoirData())) - { - CVF_ASSERT(false); - } - } - - RimOilField* activeOilField = proj ? proj->activeOilField() : NULL; - RimEclipseCaseCollection* analysisModels = (activeOilField) ? activeOilField->analysisModels() : NULL; - if (analysisModels) analysisModels->insertCaseInCaseGroup(gridCaseGroup, rimResultReservoir); - - caf::PdmDocument::updateUiIconStateRecursively(rimResultReservoir); - - { - QModelIndex rootIndex = getModelIndexFromPdmObject(gridCaseGroup->caseCollection()); - caf::PdmUiTreeItem* caseCollectionUiItem = getTreeItemFromIndex(rootIndex); - - int position = rowCount(rootIndex); - beginInsertRows(rootIndex, position, position); - caf::PdmUiTreeItem* childItem = caf::UiTreeItemBuilderPdm::buildViewItems(caseCollectionUiItem, -1, rimResultReservoir); - endInsertRows(); - } - - for (size_t rvIdx = 0; rvIdx < rimResultReservoir->reservoirViews.size(); rvIdx++) - { - RimEclipseView* riv = rimResultReservoir->reservoirViews()[rvIdx]; - riv->loadDataAndUpdate(); - } - } - } - else if (caseFromItemIndex(itemIndex)) - { - std::vector > eclipseViews; - pdmObjects.createCopyByType(&eclipseViews); - - if (eclipseViews.size() != 0) - { - RimEclipseCase* rimCase = caseFromItemIndex(itemIndex); - QModelIndex collectionIndex = getModelIndexFromPdmObject(rimCase); - caf::PdmUiTreeItem* collectionItem = getTreeItemFromIndex(collectionIndex); - - // Add cases to case group - for (size_t i = 0; i < eclipseViews.size(); i++) - { - RimEclipseView* rimReservoirView = eclipseViews[i]; - QString nameOfCopy = QString("Copy of ") + rimReservoirView->name; - rimReservoirView->name = nameOfCopy; - rimCase->reservoirViews().push_back(rimReservoirView); - - // Delete all wells to be able to copy/paste between cases, as the wells differ between cases - rimReservoirView->wellCollection()->wells().deleteAllChildObjects(); - - caf::PdmDocument::initAfterReadTraversal(rimReservoirView); - rimReservoirView->setEclipseCase(rimCase); - - caf::PdmDocument::updateUiIconStateRecursively(rimReservoirView); - - rimReservoirView->loadDataAndUpdate(); - - int position = static_cast(rimCase->reservoirViews().size()); - beginInsertRows(collectionIndex, position, position); - - caf::PdmUiTreeItem* childItem = caf::UiTreeItemBuilderPdm::buildViewItems(collectionItem, position, rimReservoirView); - - endInsertRows(); - } - } - } - - caf::PdmObject* selectedObject = getTreeItemFromIndex(itemIndex)->dataObject().p(); - RimGeoMechCase* geomCase = dynamic_cast(selectedObject); - if (!geomCase && selectedObject) - { - RimGeoMechView* geomView = dynamic_cast(selectedObject); - if (geomView) geomCase = geomView->geoMechCase(); - } - - if (geomCase) - { - std::vector > geomViews; - pdmObjects.createCopyByType(&geomViews); - - if (geomViews.size() != 0) - { - // Add cases to case group - for (size_t i = 0; i < geomViews.size(); i++) - { - RimGeoMechView* rimReservoirView = geomViews[i]; - QString nameOfCopy = QString("Copy of ") + rimReservoirView->name; - rimReservoirView->name = nameOfCopy; - geomCase->geoMechViews().push_back(rimReservoirView); - - caf::PdmDocument::initAfterReadTraversal(rimReservoirView); - rimReservoirView->setGeoMechCase(geomCase); - - caf::PdmDocument::updateUiIconStateRecursively(rimReservoirView); - - rimReservoirView->loadDataAndUpdate(); - - this->updateUiSubTree(geomCase); - } - } - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimUiTreeModelPdm::moveObjects(const QModelIndex& itemIndex, caf::PdmObjectGroup& pdmObjects) -{ - addObjects(itemIndex, pdmObjects); - - // Delete objects from original container - std::vector > typedObjects; - pdmObjects.objectsByType(&typedObjects); - - for (size_t i = 0; i < typedObjects.size(); i++) - { - RimEclipseCase* rimReservoir = typedObjects[i]; - deleteReservoir(rimReservoir); - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool RimUiTreeModelPdm::deleteObjectFromPdmPointersField(const QModelIndex& itemIndex) -{ - if (!itemIndex.isValid()) - { - return false; - } - - caf::PdmUiTreeItem* currentItem = getTreeItemFromIndex(itemIndex); - CVF_ASSERT(currentItem); - - caf::PdmObject* currentPdmObject = currentItem->dataObject().p(); - CVF_ASSERT(currentPdmObject); - - std::vector parentFields; - currentPdmObject->parentFields(parentFields); - - if (parentFields.size() == 1) - { - beginRemoveRows(itemIndex.parent(), itemIndex.row(), itemIndex.row()); - if (currentItem->parent()) - { - currentItem->parent()->removeChildren(itemIndex.row(), 1); - } - endRemoveRows(); - - caf::PdmPointersField* caseGroup = dynamic_cast *>(parentFields[0]); - if (caseGroup) - { - caseGroup->removeChildObject(currentPdmObject); - - delete currentPdmObject; - } - } - - clearClipboard(); - - return true; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimUiTreeModelPdm::clearClipboard() -{ - // We use QModelIndex to identify a selection on the clipboard - // When we delete or move an entity, the clipboard data might be invalid - - QClipboard* clipboard = QApplication::clipboard(); - if (clipboard) - { - if (dynamic_cast(clipboard->mimeData())) - { - clipboard->clear(); - } - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -Qt::DropActions RimUiTreeModelPdm::supportedDropActions() const -{ - return Qt::CopyAction | Qt::MoveAction; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -Qt::ItemFlags RimUiTreeModelPdm::flags(const QModelIndex &index) const -{ - Qt::ItemFlags defaultFlags = caf::UiTreeModelPdm::flags(index); - if (index.isValid()) - { - caf::PdmUiTreeItem* currentItem = getTreeItemFromIndex(index); - CVF_ASSERT(currentItem); - - if (dynamic_cast(currentItem->dataObject().p()) || - dynamic_cast(currentItem->dataObject().p())) - { - return Qt::ItemIsDropEnabled | defaultFlags; - } - else if (dynamic_cast(currentItem->dataObject().p())) - { - // TODO: Remember to handle reservoir holding the main grid - return Qt::ItemIsDragEnabled | defaultFlags; - } - } - - return defaultFlags; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool RimUiTreeModelPdm::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) -{ - const MimeDataWithIndexes* myMimeData = qobject_cast(data); - if (myMimeData && parent.isValid()) - { - caf::PdmObjectGroup pog; - - for (int i = 0; i < myMimeData->indexes().size(); i++) - { - QModelIndex mi = myMimeData->indexes().at(i); - caf::PdmUiTreeItem* currentItem = getTreeItemFromIndex(mi); - caf::PdmObject* pdmObj = currentItem->dataObject().p(); - - pog.objects().push_back(pdmObj); - } - - if (action == Qt::CopyAction) - { - addObjects(parent, pog); - } - else if (action == Qt::MoveAction) - { - moveObjects(parent, pog); - } - - return true; - } - - return false; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -QMimeData* RimUiTreeModelPdm::mimeData(const QModelIndexList &indexes) const -{ - MimeDataWithIndexes* myObj = new MimeDataWithIndexes(); - myObj->setIndexes(indexes); - return myObj; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -QStringList RimUiTreeModelPdm::mimeTypes() const -{ - QStringList types; - types << MimeDataWithIndexes::formatName(); - return types; -} - -//-------------------------------------------------------------------------------------------------- -/// Return grid case group when QModelIndex points to grid case group, case collection or case in a grid case group -//-------------------------------------------------------------------------------------------------- -RimIdenticalGridCaseGroup* RimUiTreeModelPdm::gridCaseGroupFromItemIndex(const QModelIndex& itemIndex) -{ - caf::PdmUiTreeItem* currentItem = getTreeItemFromIndex(itemIndex); - - RimIdenticalGridCaseGroup* gridCaseGroup = NULL; - - if (dynamic_cast(currentItem->dataObject().p())) - { - gridCaseGroup = dynamic_cast(currentItem->dataObject().p()); - } - else if (dynamic_cast(currentItem->dataObject().p())) - { - RimCaseCollection* caseCollection = dynamic_cast(currentItem->dataObject().p()); - CVF_ASSERT(caseCollection); - - gridCaseGroup = caseCollection->parentCaseGroup(); - } - else if (dynamic_cast(currentItem->dataObject().p())) - { - RimEclipseCase* rimReservoir = dynamic_cast(currentItem->dataObject().p()); - CVF_ASSERT(rimReservoir); - - RimCaseCollection* caseCollection = rimReservoir->parentCaseCollection(); - if (caseCollection) - { - gridCaseGroup = caseCollection->parentCaseGroup(); - } - } - - return gridCaseGroup; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimUiTreeModelPdm::addToParentAndBuildUiItems(caf::PdmUiTreeItem* parentTreeItem, int position, caf::PdmObject* pdmObject) -{ - QModelIndex parentModelIndex; - - if (parentTreeItem && parentTreeItem->dataObject()) - { - parentModelIndex = getModelIndexFromPdmObject(parentTreeItem->dataObject()); - } - - beginInsertRows(parentModelIndex, position, position); - - caf::PdmUiTreeItem* childItem = caf::UiTreeItemBuilderPdm::buildViewItems(parentTreeItem, position, pdmObject); - - endInsertRows(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RimEclipseCase* RimUiTreeModelPdm::caseFromItemIndex(const QModelIndex& itemIndex) -{ - caf::PdmUiTreeItem* currentItem = getTreeItemFromIndex(itemIndex); - - RimEclipseCase* rimCase = NULL; - - if (dynamic_cast(currentItem->dataObject().p())) - { - rimCase = dynamic_cast(currentItem->dataObject().p()); - } - else if (dynamic_cast(currentItem->dataObject().p())) - { - RimEclipseView* reservoirView = dynamic_cast(currentItem->dataObject().p()); - CVF_ASSERT(reservoirView); - - rimCase = reservoirView->eclipseCase(); - } - - return rimCase; -} - -//-------------------------------------------------------------------------------------------------- -/// Set toggle state for list of model indices. -//-------------------------------------------------------------------------------------------------- -void RimUiTreeModelPdm::setObjectToggleStateForSelection(QModelIndexList selectedIndexes, int state) -{ - bool toggleOn = (state == Qt::Checked); - - std::set resViewsToUpdate; - - foreach (QModelIndex index, selectedIndexes) - { - if (!index.isValid()) - { - continue; - } - - caf::PdmUiTreeItem* treeItem = UiTreeModelPdm::getTreeItemFromIndex(index); - assert(treeItem); - - caf::PdmObject* obj = treeItem->dataObject(); - assert(obj); - - if (selectedIndexes.size() != 1) - { - if (obj && obj->objectToggleField()) - { - caf::PdmField* field = dynamic_cast* >(obj->objectToggleField()); - if (field) - { - if (state == RimUiTreeView::TOGGLE_ON) field->setValueFromUi(true); - if (state == RimUiTreeView::TOGGLE_OFF) field->setValueFromUi(false); - if (state == RimUiTreeView::TOGGLE) field->setValueFromUi(!(field->v())); - } - } - } - else - { - // If only one item is selected, loop over its children, and toggle them instead of the - // selected item directly - - for (int cIdx = 0; cIdx < treeItem->childCount(); ++ cIdx) - { - caf::PdmUiTreeItem* child = treeItem->child(cIdx); - if (!child) continue; - - caf::PdmObject* childObj = child->dataObject(); - - if (childObj && childObj->objectToggleField()) - { - caf::PdmField* field = dynamic_cast* >(childObj->objectToggleField()); - if (field) - { - if (state == RimUiTreeView::TOGGLE_ON) field->setValueFromUi(true); - if (state == RimUiTreeView::TOGGLE_OFF) field->setValueFromUi(false); - if (state == RimUiTreeView::TOGGLE) field->setValueFromUi(!(field->v())); - } - } - } - } - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimUiTreeModelPdm::deleteAllWellPaths(const QModelIndex& itemIndex) -{ - if (!itemIndex.isValid()) return; - - caf::PdmUiTreeItem* uiItem = getTreeItemFromIndex(itemIndex); - if (!uiItem) return; - - caf::PdmObject* object = uiItem->dataObject().p(); - RimWellPathCollection* wellPathCollection = dynamic_cast(object); - if (!wellPathCollection) return; - - // Remove item from UI tree model before delete of project data structure - removeRows_special(0, uiItem->childCount(), itemIndex); - - wellPathCollection->wellPaths.deleteAllChildObjects(); - - clearClipboard(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimUiTreeModelPdm::populateObjectGroupFromModelIndexList(const QModelIndexList& modelIndexList, caf::PdmObjectGroup* objectGroup) -{ - CVF_ASSERT(objectGroup); - - for (int i = 0; i < modelIndexList.size(); i++) - { - caf::PdmUiTreeItem* uiItem = UiTreeModelPdm::getTreeItemFromIndex(modelIndexList.at(i)); - - if (uiItem && uiItem->dataObject() && uiItem->dataObject().p()) - { - objectGroup->addObject(uiItem->dataObject().p()); - } - } -} - diff --git a/ApplicationCode/ProjectDataModel/RimUiTreeModelPdm.h b/ApplicationCode/ProjectDataModel/RimUiTreeModelPdm.h deleted file mode 100644 index 40ebdfec28..0000000000 --- a/ApplicationCode/ProjectDataModel/RimUiTreeModelPdm.h +++ /dev/null @@ -1,103 +0,0 @@ -///////////////////////////////////////////////////////////////////////////////// -// -// Copyright (C) 2011- Statoil ASA -// Copyright (C) 2013- Ceetron Solutions AS -// Copyright (C) 2011-2012 Ceetron AS -// -// ResInsight is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. -// -// See the GNU General Public License at -// for more details. -// -///////////////////////////////////////////////////////////////////////////////// - -#pragma once - -#include "cafPdmObject.h" -#include "cafPdmPointer.h" -#include "cafPdmDocument.h" -#include "cafUiTreeModelPdm.h" - -class QFileSystemWatcher; - -class RimEclipsePropertyFilter; -class RimCellRangeFilter; -class RimGeoMechPropertyFilter; -class RimEclipseCase; -class RimEclipseView; -class RimEclipseInputProperty; -class RimEclipseStatisticsCase; -class RimIdenticalGridCaseGroup; - -class RimView; - - -//================================================================================================== -/// -/// -//================================================================================================== -class RimUiTreeModelPdm : public caf::UiTreeModelPdm -{ - Q_OBJECT; - -public: - RimUiTreeModelPdm(QObject* parent); - - // Special edit methods - bool deleteRangeFilter(const QModelIndex& itemIndex); - bool deletePropertyFilter(const QModelIndex& itemIndex); - bool deleteGeoMechPropertyFilter(const QModelIndex& itemIndex); - - void deleteInputProperty(const QModelIndex& itemIndex); - void deleteReservoir(RimEclipseCase* reservoir); - void deleteAllWellPaths(const QModelIndex& itemIndex); - - RimEclipsePropertyFilter* addPropertyFilter(const QModelIndex& itemIndex, QModelIndex& insertedModelIndex); - RimGeoMechPropertyFilter* addGeoMechPropertyFilter(const QModelIndex& itemIndex, QModelIndex& insertedModelIndex); - RimCellRangeFilter* addRangeFilter(const QModelIndex& itemIndex, QModelIndex& insertedModelIndex); - - RimView* addReservoirView(const std::vector& treeSelection); - void deleteReservoirViews(const std::vector& treeSelection); - void deleteGeoMechCases(const std::vector& treeSelection); - - void addInputProperty(const QModelIndex& itemIndex, const QStringList& fileNames); - - void addToParentAndBuildUiItems(caf::PdmUiTreeItem* parentTreeItem, int position, caf::PdmObject* pdmObject); - - void populateObjectGroupFromModelIndexList(const QModelIndexList& modelIndexList, caf::PdmObjectGroup* objectGroup); - void addObjects(const QModelIndex& itemIndex, const caf::PdmObjectGroup& pdmObjects); - void moveObjects(const QModelIndex& itemIndex, caf::PdmObjectGroup& pdmObjects); - - RimEclipseStatisticsCase* addStatisticalCalculation(const QModelIndex& itemIndex, QModelIndex& insertedModelIndex); - RimIdenticalGridCaseGroup* addCaseGroup(QModelIndex& insertedModelIndex); - - bool deleteObjectFromPdmPointersField(const QModelIndex& itemIndex); - - void updateScriptPaths(); - - virtual Qt::DropActions supportedDropActions() const; - virtual Qt::ItemFlags flags(const QModelIndex &index) const; - virtual bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent); - virtual QMimeData* mimeData(const QModelIndexList &indexes) const; - virtual QStringList mimeTypes() const; - - RimIdenticalGridCaseGroup* gridCaseGroupFromItemIndex(const QModelIndex& itemIndex); - void setObjectToggleStateForSelection(QModelIndexList selectedIndexes, int state); - -private slots: - void slotRefreshScriptTree(QString path); - -private: - void clearClipboard(); - RimEclipseCase* caseFromItemIndex(const QModelIndex& itemIndex); -private: - QFileSystemWatcher* m_scriptChangeDetector; -}; - diff --git a/ApplicationCode/ProjectDataModel/RimUiTreeView.cpp b/ApplicationCode/ProjectDataModel/RimUiTreeView.cpp deleted file mode 100644 index 68a0e411e7..0000000000 --- a/ApplicationCode/ProjectDataModel/RimUiTreeView.cpp +++ /dev/null @@ -1,1676 +0,0 @@ -///////////////////////////////////////////////////////////////////////////////// -// -// Copyright (C) 2011- Statoil ASA -// Copyright (C) 2013- Ceetron Solutions AS -// Copyright (C) 2011-2012 Ceetron AS -// -// ResInsight is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. -// -// See the GNU General Public License at -// for more details. -// -///////////////////////////////////////////////////////////////////////////////// - -//#include "RiaStdInclude.h" - -#include "cafPdmDocument.h" -#include "cafPdmFieldCvfColor.h" -#include "cafPdmFieldCvfMat4d.h" -#include "cafPdmUiPropertyDialog.h" - -#include -#include -#include -#include -#include -#include -#include - -#include "RimUiTreeView.h" -#include "RimUiTreeModelPdm.h" -#include "RimEclipseView.h" -#include "RimCalcScript.h" -#include "RiaApplication.h" -#include "RiuMainWindow.h" -#include "RimEclipseInputPropertyCollection.h" -#include "RimExportInputPropertySettings.h" -#include "RiaPreferences.h" -#include "RifEclipseInputFileTools.h" -#include "RimEclipseInputCase.h" -#include "RimBinaryExportSettings.h" -#include "RigCaseCellResultsData.h" -#include "RimEclipseStatisticsCase.h" -#include "RimEclipseResultCase.h" -#include "RimMimeData.h" - -#include "RimCellRangeFilterCollection.h" -#include "RimEclipsePropertyFilterCollection.h" -#include "RimCellRangeFilterCollection.h" -#include "RimGeoMechPropertyFilter.h" -#include "RimGeoMechPropertyFilterCollection.h" -#include "RimEclipseCellColors.h" -#include "RimEclipseStatisticsCaseCollection.h" -#include "RimIdenticalGridCaseGroup.h" -#include "RimCaseCollection.h" -#include "RimScriptCollection.h" -#include "RimEclipseWell.h" -#include "RimCellEdgeColors.h" -#include "RimEclipseWellCollection.h" -#include "RimWellPathCollection.h" -#include "RimReservoirCellResultsStorage.h" -#include "Rim3dOverlayInfoConfig.h" -#include "RimProject.h" -#include "RimOilField.h" -#include "RimEclipseCaseCollection.h" -#include "RimEclipseInputProperty.h" -#include "RigSingleWellResultsData.h" -#include "RimGeoMechView.h" -#include "RimGeoMechCase.h" - - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RimUiTreeView::RimUiTreeView(QWidget *parent /*= 0*/) - : QTreeView(parent) -{ - setHeaderHidden(true); - - m_pasteAction = new QAction(QString("Paste"), this); - connect(m_pasteAction, SIGNAL(triggered()), SLOT(slotPastePdmObjects())); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RimUiTreeView::~RimUiTreeView() -{ -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimUiTreeView::contextMenuEvent(QContextMenuEvent* event) -{ - m_pasteAction->setEnabled(hasClipboardValidData()); - - if (selectionModel() && selectionModel()->selection().size() == 0) - { - // Clicking in blank space in tree view - QMenu menu; - menu.addAction(QString("New Grid Case Group"), this, SLOT(slotAddCaseGroup())); - menu.exec(event->globalPos()); - - return; - } - - RimUiTreeModelPdm* myModel = dynamic_cast(model()); - if (myModel) - { - caf::PdmUiTreeItem* uiItem = myModel->getTreeItemFromIndex(currentIndex()); - if (uiItem && uiItem->dataObject()) - { - QMenu menu; - - if (dynamic_cast(uiItem->dataObject().p())) - { - menu.addAction(QString("New View"), this, SLOT(slotAddView())); - menu.addAction(QString("Copy View"), this, SLOT(slotCopyPdmObjectToClipboard())); - menu.addAction(m_pasteAction); - menu.addAction(QString("Delete"), this, SLOT(slotDeleteView())); - } - else if (dynamic_cast(uiItem->dataObject().p())) - { - menu.addAction(QString("New View"), this, SLOT(slotAddView())); - menu.addAction(QString("Copy View"), this, SLOT(slotCopyPdmObjectToClipboard())); - menu.addAction(m_pasteAction); - menu.addAction(QString("Delete"), this, SLOT(slotDeleteView())); - } - else if (dynamic_cast(uiItem->dataObject().p())) - { - menu.addAction(QString("New Range Filter"), this, SLOT(slotAddRangeFilter())); - menu.addAction(QString("Slice I Filter"), this, SLOT(slotAddSliceFilterI())); - menu.addAction(QString("Slice J Filter"), this, SLOT(slotAddSliceFilterJ())); - menu.addAction(QString("Slice K Filter"), this, SLOT(slotAddSliceFilterK())); - } - else if (dynamic_cast(uiItem->dataObject().p())) - { - menu.addAction(QString("Insert Range Filter"), this, SLOT(slotAddRangeFilter())); - menu.addAction(QString("Slice I Filter"), this, SLOT(slotAddSliceFilterI())); - menu.addAction(QString("Slice J Filter"), this, SLOT(slotAddSliceFilterJ())); - menu.addAction(QString("Slice K Filter"), this, SLOT(slotAddSliceFilterK())); - menu.addSeparator(); - menu.addAction(QString("Delete"), this, SLOT(slotDeleteRangeFilter())); - } - else if (dynamic_cast(uiItem->dataObject().p())) - { - menu.addAction(QString("New Property Filter"), this, SLOT(slotAddPropertyFilter())); - } - else if (dynamic_cast(uiItem->dataObject().p())) - { - menu.addAction(QString("Insert Property Filter"), this, SLOT(slotAddPropertyFilter())); - menu.addSeparator(); - menu.addAction(QString("Delete"), this, SLOT(slotDeletePropertyFilter())); - } - else if (dynamic_cast(uiItem->dataObject().p())) - { - menu.addAction(QString("New Property Filter"), this, SLOT(slotAddGeoMechPropertyFilter())); - } - else if (dynamic_cast(uiItem->dataObject().p())) - { - menu.addAction(QString("Insert Property Filter"), this, SLOT(slotAddGeoMechPropertyFilter())); - menu.addSeparator(); - menu.addAction(QString("Delete"), this, SLOT(slotDeleteGeoMechPropertyFilter())); - } - else if (dynamic_cast(uiItem->dataObject().p())) - { - RiaApplication* app = RiaApplication::instance(); - - { - QAction* action = menu.addAction(QString("Edit"), this, SLOT(slotEditScript())); - if (app->scriptEditorPath().isEmpty()) - { - action->setEnabled(false); - } - } - menu.addAction(QString("New"), this, SLOT(slotNewScript())); - menu.addSeparator(); - - { - QAction* action = menu.addAction(QString("Execute"), this, SLOT(slotExecuteScript())); - if (app->octavePath().isEmpty()) - { - action->setEnabled(false); - } - } - } - else if (dynamic_cast(uiItem->dataObject().p())) - { - menu.addAction(QString("Add Input Property"), this, SLOT(slotAddInputProperty())); - } - else if (dynamic_cast(uiItem->dataObject().p())) - { - menu.addAction(QString("Delete"), this, SLOT(slotDeleteObjectFromContainer())); - menu.addAction(QString("Save Property To File"), this, SLOT(slotWriteInputProperty())); - } - else if (dynamic_cast(uiItem->dataObject().p())) - { - menu.addAction(QString("Save Property To File"), this, SLOT(slotWriteBinaryResultAsInputProperty())); - } - else if (dynamic_cast(uiItem->dataObject().p())) - { - menu.addAction(QString("New Statistics Case"), this, SLOT(slotNewStatisticsCase())); - } - else if (dynamic_cast(uiItem->dataObject().p())) - { - menu.addAction(QString("New View"), this, SLOT(slotAddView())); - menu.addAction(QString("Compute"), this, SLOT(slotComputeStatistics())); - menu.addAction(QString("Close"), this, SLOT(slotCloseCase())); - } - else if (dynamic_cast(uiItem->dataObject().p())) - { - menu.addAction(QString("New View"), this, SLOT(slotAddView())); - menu.addAction(QString("Close"), this, SLOT(slotCloseGeomechCase())); - menu.addAction(m_pasteAction); - } - else if (dynamic_cast(uiItem->dataObject().p())) - { - menu.addAction(QString("Copy"), this, SLOT(slotCopyPdmObjectToClipboard())); - menu.addAction(m_pasteAction); - menu.addAction(QString("Close"), this, SLOT(slotCloseCase())); - menu.addAction(QString("New View"), this, SLOT(slotAddView())); - menu.addAction(QString("New Grid Case Group"), this, SLOT(slotAddCaseGroup())); - } - else if (dynamic_cast(uiItem->dataObject().p())) - { - menu.addAction(QString("New Grid Case Group"), this, SLOT(slotAddCaseGroup())); - menu.addAction(m_pasteAction); - menu.addAction(QString("Close"), this, SLOT(slotDeleteObjectFromPdmPointersField())); - } - else if (dynamic_cast(uiItem->dataObject().p())) - { - menu.addAction(m_pasteAction); - - // Check if parent field is a StatisticsCaseCollection - RimCaseCollection* rimCaseCollection = dynamic_cast(uiItem->dataObject().p()); - if (RimIdenticalGridCaseGroup::isStatisticsCaseCollection(rimCaseCollection)) - { - menu.addAction(QString("New Statistics Case"), this, SLOT(slotNewStatisticsCase())); - } - } - else if (dynamic_cast(uiItem->dataObject().p()) || dynamic_cast(uiItem->dataObject().p())) - { - menu.addAction(QString("Add Script Path"), this, SLOT(slotAddScriptPath())); - menu.addAction(QString("Delete Script Path"), this, SLOT(slotDeleteScriptPath())); - } - else if (dynamic_cast(uiItem->dataObject().p())) - { - menu.addAction(QString("Delete All Well Paths"), this, SLOT(slotDeleteAllWellPaths())); - - RiuMainWindow* ruiMainWindow = RiuMainWindow::instance(); - ruiMainWindow->appendActionsContextMenuForPdmObject(uiItem->dataObject().p(), &menu); - } - else if (dynamic_cast(uiItem->dataObject().p())) - { - RiuMainWindow* ruiMainWindow = RiuMainWindow::instance(); - ruiMainWindow->appendActionsContextMenuForPdmObject(uiItem->dataObject().p(), &menu); - menu.addAction(QString("New Grid Case Group"), this, SLOT(slotAddCaseGroup())); - } - - // Execute script on selection of cases - RiuMainWindow* ruiMainWindow = RiuMainWindow::instance(); - if (ruiMainWindow) - { - std::vector cases; - ruiMainWindow->selectedCases(cases); - - if (cases.size() > 0) - { - QMenu* executeMenu = menu.addMenu("Execute script"); - - RiaApplication* app = RiaApplication::instance(); - RimProject* proj = app->project(); - if (proj && proj->scriptCollection()) - { - RimScriptCollection* rootScriptCollection = proj->scriptCollection(); - - // Root script collection holds a list of subdirectories of user defined script folders - for (size_t i = 0; i < rootScriptCollection->subDirectories.size(); i++) - { - RimScriptCollection* subDir = rootScriptCollection->subDirectories[i]; - - if (subDir) - { - appendScriptItems(executeMenu, subDir); - } - } - } - - menu.addSeparator(); - menu.addMenu(executeMenu); - } - } - - appendToggleItemActions(menu); - menu.exec(event->globalPos()); - } - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimUiTreeView::slotAddChildItem() -{ - - QModelIndex index = currentIndex(); - QAbstractItemModel* myModel = model(); - - // Insert a single row at the end of the collection of items - int itemCount = myModel->rowCount(index); - if (!myModel->insertRow(itemCount, index)) - return; - - selectionModel()->setCurrentIndex(myModel->index(0, 0, index), QItemSelectionModel::ClearAndSelect); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimUiTreeView::slotDeleteItem() -{ - QModelIndex index = currentIndex(); - QAbstractItemModel* myModel = model(); - - if (!myModel->removeRow(index.row(), index.parent())) - return; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimUiTreeView::slotDeletePropertyFilter() -{ - RimUiTreeModelPdm* myModel = dynamic_cast(model()); - if (myModel) - { - myModel->deletePropertyFilter(currentIndex()); - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimUiTreeView::slotDeleteRangeFilter() -{ - RimUiTreeModelPdm* myModel = dynamic_cast(model()); - if (myModel) - { - myModel->deleteRangeFilter(currentIndex()); - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimUiTreeView::slotAddPropertyFilter() -{ - RimUiTreeModelPdm* myModel = dynamic_cast(model()); - if (myModel) - { - QModelIndex insertedIndex; - RimEclipsePropertyFilter* propFilter = myModel->addPropertyFilter(currentIndex(), insertedIndex); - setCurrentIndex(insertedIndex); - if (propFilter) - { - propFilter->parentContainer()->reservoirView()->createDisplayModelAndRedraw(); - } - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimUiTreeView::slotAddGeoMechPropertyFilter() -{ - RimUiTreeModelPdm* myModel = dynamic_cast(model()); - if (myModel) - { - QModelIndex insertedIndex; - RimGeoMechPropertyFilter* propFilter = myModel->addGeoMechPropertyFilter(currentIndex(), insertedIndex); - setCurrentIndex(insertedIndex); - if (propFilter) - { - propFilter->parentContainer()->reservoirView()->createDisplayModelAndRedraw(); - } - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimUiTreeView::slotDeleteGeoMechPropertyFilter() -{ - RimUiTreeModelPdm* myModel = dynamic_cast(model()); - if (myModel) - { - myModel->deleteGeoMechPropertyFilter(currentIndex()); - } -} - - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimUiTreeView::slotAddRangeFilter() -{ - RimUiTreeModelPdm* myModel = dynamic_cast(model()); - if (myModel) - { - QModelIndex insertedIndex; - RimCellRangeFilter* newFilter = myModel->addRangeFilter(currentIndex(), insertedIndex); - setCurrentIndex(insertedIndex); - - if (newFilter && newFilter->parentContainer()) - { - newFilter->parentContainer()->reservoirView()->createDisplayModelAndRedraw(); - } - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimUiTreeView::slotAddSliceFilterI() -{ - RimUiTreeModelPdm* myModel = dynamic_cast(model()); - if (myModel) - { - QModelIndex insertedIndex; - RimCellRangeFilter* rangeFilter = myModel->addRangeFilter(currentIndex(), insertedIndex); - - RimCellRangeFilterCollection* rangeFilterCollection = rangeFilter->parentContainer(); - rangeFilter->name = QString("Slice I (%1)").arg(rangeFilterCollection->rangeFilters().size()); - rangeFilter->cellCountI = 1; - - rangeFilterCollection->reservoirView()->scheduleGeometryRegen(RANGE_FILTERED); - rangeFilterCollection->reservoirView()->scheduleGeometryRegen(RANGE_FILTERED_INACTIVE); - - rangeFilterCollection->reservoirView()->createDisplayModelAndRedraw(); - - setCurrentIndex(insertedIndex); - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimUiTreeView::slotAddSliceFilterJ() -{ - RimUiTreeModelPdm* myModel = dynamic_cast(model()); - if (myModel) - { - QModelIndex insertedIndex; - RimCellRangeFilter* rangeFilter = myModel->addRangeFilter(currentIndex(), insertedIndex); - - RimCellRangeFilterCollection* rangeFilterCollection = rangeFilter->parentContainer(); - rangeFilter->name = QString("Slice J (%1)").arg(rangeFilterCollection->rangeFilters().size()); - rangeFilter->cellCountJ = 1; - - rangeFilterCollection->reservoirView()->scheduleGeometryRegen(RANGE_FILTERED); - rangeFilterCollection->reservoirView()->scheduleGeometryRegen(RANGE_FILTERED_INACTIVE); - - rangeFilterCollection->reservoirView()->createDisplayModelAndRedraw(); - - setCurrentIndex(insertedIndex); - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimUiTreeView::slotAddSliceFilterK() -{ - RimUiTreeModelPdm* myModel = dynamic_cast(model()); - if (myModel) - { - QModelIndex insertedIndex; - RimCellRangeFilter* rangeFilter = myModel->addRangeFilter(currentIndex(), insertedIndex); - - RimCellRangeFilterCollection* rangeFilterCollection = rangeFilter->parentContainer(); - rangeFilter->name = QString("Slice K (%1)").arg(rangeFilterCollection->rangeFilters().size()); - rangeFilter->cellCountK = 1; - - rangeFilterCollection->reservoirView()->scheduleGeometryRegen(RANGE_FILTERED); - rangeFilterCollection->reservoirView()->scheduleGeometryRegen(RANGE_FILTERED_INACTIVE); - - rangeFilterCollection->reservoirView()->createDisplayModelAndRedraw(); - - setCurrentIndex(insertedIndex); - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimUiTreeView::slotEditScript() -{ - QModelIndex index = currentIndex(); - RimUiTreeModelPdm* myModel = dynamic_cast(model()); - caf::PdmUiTreeItem* uiItem = myModel->getTreeItemFromIndex(currentIndex()); - if (uiItem) - { - RimCalcScript* calcScript = dynamic_cast(uiItem->dataObject().p()); - - RiaApplication* app = RiaApplication::instance(); - QString scriptEditor = app->scriptEditorPath(); - if (!scriptEditor.isEmpty()) - { - QStringList arguments; - arguments << calcScript->absolutePath; - - QProcess* myProcess = new QProcess(this); - myProcess->start(scriptEditor, arguments); - - if (!myProcess->waitForStarted(1000)) - { - QMessageBox::warning(RiuMainWindow::instance(), "Script editor", "Failed to start script editor executable\n" + scriptEditor); - } - } - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimUiTreeView::slotNewScript() -{ - QModelIndex index = currentIndex(); - RimUiTreeModelPdm* myModel = dynamic_cast(model()); - caf::PdmUiTreeItem* uiItem = myModel->getTreeItemFromIndex(currentIndex()); - RimCalcScript* calcScript = NULL; - RimScriptCollection * scriptColl = NULL; - - calcScript = dynamic_cast(uiItem->dataObject().p()); - scriptColl = dynamic_cast(uiItem->dataObject().p()); - QString fullPathNewScript; - - if (calcScript ) - { - QFileInfo existingScriptFileInfo(calcScript->absolutePath()); - fullPathNewScript = existingScriptFileInfo.absolutePath(); - } - else if (scriptColl) - { - fullPathNewScript = scriptColl->directory(); - } - else - { - return; - } - - QString fullPathFilenameNewScript; - - fullPathFilenameNewScript = fullPathNewScript + "/untitled.m"; - int num= 1; - while (QFileInfo(fullPathFilenameNewScript).exists()) - { - fullPathFilenameNewScript = fullPathNewScript + "/untitled" + QString::number(num) + ".m"; - num++; - } - - RiaApplication* app = RiaApplication::instance(); - QString scriptEditor = app->scriptEditorPath(); - if (!scriptEditor.isEmpty()) - { - QStringList arguments; - arguments << fullPathFilenameNewScript; - - QProcess* myProcess = new QProcess(this); - myProcess->start(scriptEditor, arguments); - - if (!myProcess->waitForStarted(1000)) - { - QMessageBox::warning(RiuMainWindow::instance(), "Script editor", "Failed to start script editor executable\n" + scriptEditor); - } - } -} - - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimUiTreeView::slotExecuteScript() -{ - QModelIndex index = currentIndex(); - RimUiTreeModelPdm* myModel = dynamic_cast(model()); - caf::PdmUiTreeItem* uiItem = myModel->getTreeItemFromIndex(currentIndex()); - if (uiItem) - { - RimCalcScript* calcScript = dynamic_cast(uiItem->dataObject().p()); - - RiaApplication* app = RiaApplication::instance(); - QString octavePath = app->octavePath(); - if (!octavePath.isEmpty()) - { - // TODO: Must rename RimCalcScript::absolutePath to absoluteFileName, as the code below is confusing - // absolutePath() is a function in QFileInfo - QFileInfo fi(calcScript->absolutePath()); - QString octaveFunctionSearchPath = fi.absolutePath(); - - QStringList arguments = app->octaveArguments(); - arguments.append("--path"); - arguments << octaveFunctionSearchPath; - arguments << calcScript->absolutePath(); - - RiaApplication::instance()->launchProcess(octavePath, arguments); - } - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimUiTreeView::slotExecuteScriptForSelectedCases() -{ - QAction* action = qobject_cast(sender()); - - if (!action) return; - - QString encodedModelIndex = action->data().toString(); - QModelIndex mi = RimUiTreeView::getModelIndexFromString(model(), encodedModelIndex); - - RimUiTreeModelPdm* myModel = dynamic_cast(model()); - if (!myModel) return; - - caf::PdmUiTreeItem* uiItem = myModel->getTreeItemFromIndex(mi); - if (uiItem) - { - RimCalcScript* calcScript = dynamic_cast(uiItem->dataObject().p()); - if (!calcScript) return; - - RiaApplication* app = RiaApplication::instance(); - QString octavePath = app->octavePath(); - if (!octavePath.isEmpty()) - { - // TODO: Must rename RimCalcScript::absolutePath to absoluteFileName, as the code below is confusing - // absolutePath() is a function in QFileInfo - QFileInfo fi(calcScript->absolutePath()); - QString octaveFunctionSearchPath = fi.absolutePath(); - - QStringList arguments = app->octaveArguments(); - arguments.append("--path"); - arguments << octaveFunctionSearchPath; - arguments << calcScript->absolutePath(); - - // Get case ID from selected cases in selection model - std::vector caseIdsInSelection; - { - QItemSelectionModel* m = selectionModel(); - CVF_ASSERT(m); - - caf::PdmObjectGroup group; - - QModelIndexList mil = m->selectedRows(); - - myModel->populateObjectGroupFromModelIndexList(mil, &group); - - std::vector > typedObjects; - group.objectsByType(&typedObjects); - - for (size_t i = 0; i < typedObjects.size(); i++) - { - RimEclipseCase* rimReservoir = typedObjects[i]; - caseIdsInSelection.push_back(rimReservoir->caseId); - } - } - - if (caseIdsInSelection.size() > 0) - { - RiaApplication::instance()->launchProcessForMultipleCases(octavePath, arguments, caseIdsInSelection); - } - } - } -} - - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimUiTreeView::slotAddView() -{ - RimUiTreeModelPdm* myModel = dynamic_cast(model()); - std::vector selection; - this->selectedUiItems(selection); - - RimView* newView = myModel->addReservoirView(selection); - QModelIndex insertedIndex = myModel->getModelIndexFromPdmObject(newView); - - // Expand parent collection and inserted view item - setExpandedUpToRoot(insertedIndex); - - setCurrentIndex(insertedIndex); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimUiTreeView::slotDeleteView() -{ - RimUiTreeModelPdm* myModel = dynamic_cast(model()); - std::vector selection; - this->selectedUiItems(selection); - myModel->deleteReservoirViews(selection); - - RiaApplication* app = RiaApplication::instance(); - app->setActiveReservoirView(NULL); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimUiTreeView::slotSelectionChanged(const QItemSelection & selected, const QItemSelection & deselected) -{ - caf::PdmObject* pdmObject = NULL; - - if (selected.indexes().size() == 1) - { - QModelIndex mi = selected.indexes()[0]; - if (mi.isValid()) - { - RimUiTreeModelPdm* myModel = dynamic_cast(model()); - if (myModel) - { - caf::PdmUiTreeItem* treeItem = myModel->getTreeItemFromIndex(mi); - if (treeItem && treeItem->dataObject()) - { - pdmObject = treeItem->dataObject(); - } - } - } - } - - emit selectedObjectChanged(pdmObject); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimUiTreeView::setModel(QAbstractItemModel* model) -{ - QTreeView::setModel(model); - - if (selectionModel()) - { - connect(selectionModel(), SIGNAL(selectionChanged( const QItemSelection & , const QItemSelection & )), SLOT(slotSelectionChanged( const QItemSelection & , const QItemSelection & ))); - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimUiTreeView::slotAddInputProperty() -{ - RiaApplication* app = RiaApplication::instance(); - QString defaultDir = app->defaultFileDialogDirectory("INPUT_FILES"); - QStringList fileNames = QFileDialog::getOpenFileNames(this, "Select Eclipse Input Property Files", defaultDir, "All Files (*.* *)"); - - if (fileNames.isEmpty()) return; - - // Remember the directory to next time - defaultDir = QFileInfo(fileNames.last()).absolutePath(); - app->setDefaultFileDialogDirectory("INPUT_FILES", defaultDir); - - - QModelIndex index = currentIndex(); - RimUiTreeModelPdm* myModel = dynamic_cast(model()); - caf::PdmUiTreeItem* uiItem = myModel->getTreeItemFromIndex(currentIndex()); - - RimEclipseInputPropertyCollection* inputPropertyCollection = dynamic_cast(uiItem->dataObject().p()); - if (inputPropertyCollection) - { - myModel->addInputProperty(index, fileNames); - - setCurrentIndex(index); - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimUiTreeView::slotDeleteObjectFromContainer() -{ - QModelIndex index = currentIndex(); - if (!index.isValid()) return; - - RimUiTreeModelPdm* myModel = dynamic_cast(model()); - if (myModel) myModel->deleteInputProperty(index); -} - - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimUiTreeView::slotWriteInputProperty() -{ - QModelIndex index = currentIndex(); - RimUiTreeModelPdm* myModel = dynamic_cast(model()); - caf::PdmUiTreeItem* uiItem = myModel->getTreeItemFromIndex(currentIndex()); - - RimEclipseInputProperty* inputProperty = dynamic_cast(uiItem->dataObject().p()); - if (!inputProperty) return; - - { - bool isResolved = false; - if (inputProperty->resolvedState == RimEclipseInputProperty::RESOLVED || inputProperty->resolvedState == RimEclipseInputProperty::RESOLVED_NOT_SAVED) - { - isResolved = true; - } - - if (!isResolved) - { - QMessageBox::warning(RiuMainWindow::instance(), "Export failure", "Property is not resolved, and then it is not possible to export the property."); - - return; - } - } - - RimExportInputSettings exportSettings; - exportSettings.eclipseKeyword = inputProperty->eclipseKeyword; - - // Find input reservoir for this property - RimEclipseInputCase* inputReservoir = NULL; - { - std::vector parentObjects; - inputProperty->parentObjectsOfType(parentObjects); - CVF_ASSERT(parentObjects.size() == 1); - - RimEclipseInputPropertyCollection* inputPropertyCollection = parentObjects[0]; - if (!inputPropertyCollection) return; - - std::vector parentObjects2; - inputPropertyCollection->parentObjectsOfType(parentObjects2); - CVF_ASSERT(parentObjects2.size() == 1); - - inputReservoir = parentObjects2[0]; - } - - if (!inputReservoir) return; - - { - QString projectFolder; - - RiaApplication* app = RiaApplication::instance(); - QString projectFileName = app->currentProjectFileName(); - if (!projectFileName.isEmpty()) - { - QFileInfo fi(projectFileName); - projectFolder = fi.absolutePath(); - } - else - { - projectFolder = inputReservoir->locationOnDisc(); - } - - QString outputFileName = projectFolder + "/" + inputProperty->eclipseKeyword; - - exportSettings.fileName = outputFileName; - } - - caf::PdmUiPropertyDialog propertyDialog(this, &exportSettings, "Export Eclipse Property to Text File"); - if (propertyDialog.exec() == QDialog::Accepted) - { - bool isOk = RifEclipseInputFileTools::writePropertyToTextFile(exportSettings.fileName, inputReservoir->reservoirData(), 0, inputProperty->resultName, exportSettings.eclipseKeyword); - if (isOk) - { - inputProperty->fileName = exportSettings.fileName; - inputProperty->eclipseKeyword = exportSettings.eclipseKeyword; - inputProperty->resolvedState = RimEclipseInputProperty::RESOLVED; - - inputProperty->updateConnectedEditors(); - } - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimUiTreeView::slotWriteBinaryResultAsInputProperty() -{ - QModelIndex index = currentIndex(); - RimUiTreeModelPdm* myModel = dynamic_cast(model()); - caf::PdmUiTreeItem* uiItem = myModel->getTreeItemFromIndex(currentIndex()); - - RimEclipseCellColors* resultColors = dynamic_cast(uiItem->dataObject().p()); - if (!resultColors) return; - if (!resultColors->reservoirView()) return; - if (!resultColors->reservoirView()->eclipseCase()) return; - if (!resultColors->reservoirView()->eclipseCase()->reservoirData()) return; - - RimBinaryExportSettings exportSettings; - exportSettings.eclipseKeyword = resultColors->resultVariable(); - - { - QString projectFolder; - - RiaApplication* app = RiaApplication::instance(); - QString projectFileName = app->currentProjectFileName(); - if (!projectFileName.isEmpty()) - { - QFileInfo fi(projectFileName); - projectFolder = fi.absolutePath(); - } - else - { - projectFolder = resultColors->reservoirView()->eclipseCase()->locationOnDisc(); - } - - QString outputFileName = projectFolder + "/" + resultColors->resultVariable(); - - exportSettings.fileName = outputFileName; - } - - caf::PdmUiPropertyDialog propertyDialog(this, &exportSettings, "Export Binary Eclipse Data to Text File"); - if (propertyDialog.exec() == QDialog::Accepted) - { - size_t timeStep = resultColors->reservoirView()->currentTimeStep(); - RifReaderInterface::PorosityModelResultType porosityModel = RigCaseCellResultsData::convertFromProjectModelPorosityModel(resultColors->porosityModel()); - - bool isOk = RifEclipseInputFileTools::writeBinaryResultToTextFile(exportSettings.fileName, resultColors->reservoirView()->eclipseCase()->reservoirData(), porosityModel, timeStep, resultColors->resultVariable(), exportSettings.eclipseKeyword, exportSettings.undefinedValue); - if (!isOk) - { - QMessageBox::critical(NULL, "File export", "Failed to exported current result to " + exportSettings.fileName); - } - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimUiTreeView::slotCloseCase() -{ - QModelIndexList miList; - miList << currentIndex(); - - if (userConfirmedGridCaseGroupChange(miList)) - { - RimUiTreeModelPdm* myModel = dynamic_cast(model()); - if (myModel) - { - QItemSelectionModel* m = selectionModel(); - CVF_ASSERT(m); - - caf::PdmObjectGroup group; - - QModelIndexList mil = m->selectedRows(); - myModel->populateObjectGroupFromModelIndexList(mil, &group); - - std::vector > typedObjects; - group.objectsByType(&typedObjects); - - for (size_t i = 0; i < typedObjects.size(); i++) - { - RimEclipseCase* rimReservoir = typedObjects[i]; - myModel->deleteReservoir(rimReservoir); - } - } - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimUiTreeView::slotNewStatisticsCase() -{ - RimUiTreeModelPdm* myModel = dynamic_cast(model()); - if (myModel) - { - QModelIndex insertedIndex; - RimEclipseStatisticsCase* newObject = myModel->addStatisticalCalculation(currentIndex(), insertedIndex); - setCurrentIndex(insertedIndex); - - setExpanded(insertedIndex, true); - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimUiTreeView::slotComputeStatistics() -{ - QModelIndex index = currentIndex(); - RimUiTreeModelPdm* myModel = dynamic_cast(model()); - caf::PdmUiTreeItem* uiItem = myModel->getTreeItemFromIndex(currentIndex()); - - RimEclipseStatisticsCase* statisticsCase = dynamic_cast(uiItem->dataObject().p()); - if (!statisticsCase) return; - - statisticsCase->computeStatistics(); - - statisticsCase->scheduleACTIVEGeometryRegenOnReservoirViews(); - statisticsCase->updateConnectedEditorsAndReservoirViews(); - - if (statisticsCase->reservoirViews.size() == 0) - { - slotAddView(); - } - - - -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimUiTreeView::slotAddCaseGroup() -{ - RimUiTreeModelPdm* myModel = dynamic_cast(model()); - if (myModel) - { - QModelIndex insertedIndex; - myModel->addCaseGroup(insertedIndex); - setCurrentIndex(insertedIndex); - - setExpanded(insertedIndex, true); - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimUiTreeView::slotDeleteObjectFromPdmPointersField() -{ - RimUiTreeModelPdm* myModel = dynamic_cast(model()); - if (myModel) - { - myModel->deleteObjectFromPdmPointersField(currentIndex()); - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimUiTreeView::slotCopyPdmObjectToClipboard() -{ - QItemSelectionModel* m = selectionModel(); - - QModelIndexList mil = m->selectedRows(); - if (mil.size() == 0) - { - return; - } - - MimeDataWithIndexes* myObject = new MimeDataWithIndexes; - myObject->setIndexes(mil); - - QClipboard* clipboard = QApplication::clipboard(); - if (clipboard) - { - clipboard->setMimeData(myObject); - } -} - - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimUiTreeView::slotPastePdmObjects() -{ - if (!currentIndex().isValid()) return; - - RimUiTreeModelPdm* myModel = dynamic_cast(model()); - if (!myModel) return; - - QModelIndexList miList; - miList << currentIndex(); - if (userConfirmedGridCaseGroupChange(miList)) - { - caf::PdmObjectGroup objectGroup; - createPdmObjectsFromClipboard(&objectGroup); - if (objectGroup.objects().size() == 0) return; - - myModel->addObjects(currentIndex(), objectGroup); - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimUiTreeView::createPdmObjectsFromClipboard(caf::PdmObjectGroup* objectGroup) -{ - RimUiTreeModelPdm* myModel = dynamic_cast(model()); - if (!myModel) return; - - QClipboard* clipboard = QApplication::clipboard(); - if (!clipboard) return; - - const MimeDataWithIndexes* mdWithIndexes = dynamic_cast(clipboard->mimeData()); - if (!mdWithIndexes) return; - - QModelIndexList indexList = mdWithIndexes->indexes(); - myModel->populateObjectGroupFromModelIndexList(indexList, objectGroup); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimUiTreeView::keyPressEvent(QKeyEvent* keyEvent) -{ - RimUiTreeModelPdm* myModel = dynamic_cast(model()); - caf::PdmUiTreeItem* uiItem = myModel->getTreeItemFromIndex(currentIndex()); - if (uiItem) - { - if (dynamic_cast(uiItem->dataObject().p()) - || dynamic_cast(uiItem->dataObject().p())) - { - if (keyEvent->matches(QKeySequence::Copy)) - { - slotCopyPdmObjectToClipboard(); - keyEvent->setAccepted(true); - - return; - } - } - - if (dynamic_cast(uiItem->dataObject().p()) - || dynamic_cast(uiItem->dataObject().p()) - || dynamic_cast(uiItem->dataObject().p()) - || dynamic_cast(uiItem->dataObject().p())) - { - if (keyEvent->matches(QKeySequence::Paste)) - { - slotPastePdmObjects(); - keyEvent->setAccepted(true); - - return; - } - } - } - - switch (keyEvent->key()) - { - case Qt::Key_Space: - case Qt::Key_Enter: - case Qt::Key_Return: - case Qt::Key_Select: - { - executeSelectionToggleOperation(TOGGLE); - keyEvent->setAccepted(true); - - return; - } - } - - QTreeView::keyPressEvent(keyEvent); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool RimUiTreeView::hasClipboardValidData() -{ - QClipboard* clipboard = QApplication::clipboard(); - if (clipboard) - { - if (dynamic_cast(clipboard->mimeData())) - { - return true; - } - } - - return false; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimUiTreeView::dropEvent(QDropEvent* dropEvent) -{ - QModelIndexList affectedModels; - - if (dropEvent->dropAction() == Qt::MoveAction) - { - const MimeDataWithIndexes* myMimeData = qobject_cast(dropEvent->mimeData()); - if (myMimeData) - { - affectedModels = myMimeData->indexes(); - } - } - - QModelIndex dropIndex = indexAt(dropEvent->pos()); - if (dropIndex.isValid()) - { - affectedModels.push_back(dropIndex); - } - - if (userConfirmedGridCaseGroupChange(affectedModels)) - { - QTreeView::dropEvent(dropEvent); - } -} - -//-------------------------------------------------------------------------------------------------- -/// Displays a question to the user when a grid case group with statistical results is about to change -//-------------------------------------------------------------------------------------------------- -bool RimUiTreeView::userConfirmedGridCaseGroupChange(const QModelIndexList& itemIndexList) -{ - if (itemIndexList.size() == 0) return true; - - RimUiTreeModelPdm* myModel = dynamic_cast(model()); - if (myModel) - { - caf::PdmObjectGroup pog; - - for (int i = 0; i < itemIndexList.size(); i++) - { - QModelIndex itemIndex = itemIndexList.at(i); - if (!itemIndex.isValid()) continue; - - RimIdenticalGridCaseGroup* gridCaseGroup = myModel->gridCaseGroupFromItemIndex(itemIndex); - if (gridCaseGroup) - { - if (hasAnyStatisticsResults(gridCaseGroup)) - { - if (pog.objects().count(gridCaseGroup) == 0) - { - pog.addObject(gridCaseGroup); - } - } - } - } - - std::vector > typedObjects; - pog.objectsByType(&typedObjects); - - if (typedObjects.size() > 0) - { - RiuMainWindow* mainWnd = RiuMainWindow::instance(); - - QMessageBox msgBox(mainWnd); - msgBox.setIcon(QMessageBox::Question); - - QString questionText; - if (typedObjects.size() == 1) - { - questionText = QString("This operation will invalidate statistics results in grid case group\n\"%1\".\n").arg(typedObjects[0]->name()); - questionText += "Computed results in this group will be deleted if you continue."; - } - else - { - questionText = "This operation will invalidate statistics results in grid case groups\n"; - for (size_t i = 0; i < typedObjects.size(); i++) - { - questionText += QString("\"%1\"\n").arg(typedObjects[i]->name()); - } - - questionText += "Computed results in these groups will be deleted if you continue."; - } - - msgBox.setText(questionText); - msgBox.setInformativeText("Do you want to continue?"); - msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); - - int ret = msgBox.exec(); - if (ret == QMessageBox::No) - { - return false; - } - } - - } - - return true; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool RimUiTreeView::hasAnyStatisticsResults(RimIdenticalGridCaseGroup* gridCaseGroup) -{ - CVF_ASSERT(gridCaseGroup); - - for (size_t i = 0; i < gridCaseGroup->statisticsCaseCollection()->reservoirs().size(); i++) - { - RimEclipseStatisticsCase* rimStaticsCase = dynamic_cast(gridCaseGroup->statisticsCaseCollection()->reservoirs[i]); - if (rimStaticsCase) - { - if (rimStaticsCase->hasComputedStatistics()) - { - return true; - } - } - } - - return false; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimUiTreeView::mousePressEvent(QMouseEvent* mouseEvent) -{ - // TODO: Handle multiple selection and changing state using mouse - // This is a bit tricky due to the fact that there is no obvious way to trap if the check box is pressed - // and not other parts of the check box GUI item - - /* - if (checkAndHandleToggleOfMultipleSelection()) - { - mouseEvent->setAccepted(true); - - return; - } - */ - - QTreeView::mousePressEvent(mouseEvent); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void setExpandedState(QStringList& nodes, QTreeView* view, QAbstractItemModel* model, - const QModelIndex startIndex, QString path) -{ - path += QString::number(startIndex.row()) + QString::number(startIndex.column()); - for (int i = 0; i < model->rowCount(startIndex); ++i) - { - QModelIndex nextIndex = model->index(i, 0, startIndex); - QString nextPath = path + QString::number(nextIndex.row()) + QString::number(nextIndex.column()); - if(!nodes.contains(nextPath)) - continue; - - setExpandedState(nodes, view, model, model->index(i, 0, startIndex), path); - } - - if (nodes.contains(path)) - { - view->setExpanded( startIndex.sibling(startIndex.row(), 0), true ); - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void storeExpandedState(QStringList & nodes, QTreeView * view, QAbstractItemModel * model, - const QModelIndex startIndex, QString path) -{ - path += QString::number(startIndex.row()) + QString::number(startIndex.column()); - for (int i = 0; i < model->rowCount(startIndex); ++i) - { - if(!view->isExpanded(model->index(i, 0, startIndex))) - continue; - - storeExpandedState(nodes, view, model, model->index(i, 0, startIndex), path); - } - - if (view->isExpanded(startIndex)) - { - nodes << path; - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimUiTreeView::applyTreeViewStateFromString(const QString& treeViewState) -{ - if (this->model()) - { - this->collapseAll(); - - QStringList nodes = treeViewState.split(";"); - - QString path; - setExpandedState(nodes, this, this->model(), QModelIndex(), path); - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimUiTreeView::storeTreeViewStateToString(QString& treeViewState) -{ - if (this->model()) - { - QStringList nodes; - QString path; - - storeExpandedState(nodes, this, this->model(), QModelIndex(), path); - - treeViewState = nodes.join(";"); - } -} - -//-------------------------------------------------------------------------------------------------- -/// Find index based of an encode QString ; ;...; -/// Set the decoded index as current index in the QAbstractItemView -//-------------------------------------------------------------------------------------------------- -QModelIndex RimUiTreeView::getModelIndexFromString(QAbstractItemModel* model, const QString& currentIndexString) -{ - QStringList modelIndexStringList = currentIndexString.split(";"); - - QModelIndex mi; - - foreach (QString modelIndexString, modelIndexStringList) - { - QStringList items = modelIndexString.split(" "); - - if (items.size() != 2) continue; - - int row = items[0].toInt(); - int col = items[1].toInt(); - - mi = model->index(row, col, mi); - } - - return mi; -} - -//-------------------------------------------------------------------------------------------------- -/// Store path to model index in item view using follwoing encoding into a QString ; ;...; -//-------------------------------------------------------------------------------------------------- -void RimUiTreeView::encodeStringFromModelIndex(const QModelIndex mi, QString& encodedModelIndex) -{ - if (!mi.isValid()) return; - - QModelIndex localModelIdx = mi; - - while (localModelIdx.isValid()) - { - if (encodedModelIndex.isEmpty()) - { - encodedModelIndex = QString("%1 %2").arg(localModelIdx.row()).arg(localModelIdx.column()) + encodedModelIndex; - } - else - { - encodedModelIndex = QString("%1 %2;").arg(localModelIdx.row()).arg(localModelIdx.column()) + encodedModelIndex; - } - localModelIdx = localModelIdx.parent(); - } -} - - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimUiTreeView::setExpandedUpToRoot(const QModelIndex& itemIndex) -{ - QModelIndex mi = itemIndex; - - while (mi.isValid()) - { - this->setExpanded(mi, true); - mi = mi.parent(); - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimUiTreeView::slotAddScriptPath() -{ - QString selectedFolder = QFileDialog::getExistingDirectory(this, "Select script folder"); - if (!selectedFolder.isEmpty()) - { - QString filePathString = RiaApplication::instance()->preferences()->scriptDirectories(); - - QChar separator(';'); - if (!filePathString.isEmpty() && !filePathString.endsWith(separator, Qt::CaseInsensitive)) - { - filePathString += separator; - } - - filePathString += selectedFolder; - - RiaApplication::instance()->preferences()->scriptDirectories = filePathString; - RiaApplication::instance()->applyPreferences(); - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimUiTreeView::slotDeleteScriptPath() -{ - RimUiTreeModelPdm* myModel = dynamic_cast(model()); - caf::PdmUiTreeItem* uiItem = myModel->getTreeItemFromIndex(currentIndex()); - if (uiItem) - { - if (dynamic_cast(uiItem->dataObject().p())) - { - RimScriptCollection* scriptCollection = dynamic_cast(uiItem->dataObject().p()); - QString toBeRemoved = scriptCollection->directory; - - QString originalFilePathString = RiaApplication::instance()->preferences()->scriptDirectories(); - QString filePathString = originalFilePathString.remove(toBeRemoved); - - // Remove duplicate separators - QChar separator(';'); - QString regExpString = QString("%1{1,5}").arg(separator); - filePathString.replace(QRegExp(regExpString), separator); - - // Remove separator at end - if (filePathString.endsWith(separator)) - { - filePathString = filePathString.left(filePathString.size() - 1); - } - - RiaApplication::instance()->preferences()->scriptDirectories = filePathString; - RiaApplication::instance()->applyPreferences(); - } - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimUiTreeView::appendToggleItemActions(QMenu& contextMenu) -{ - if (selectionModel() && selectionModel()->selectedIndexes().size() > 0) - { - foreach (QModelIndex index, selectionModel()->selectedIndexes()) - { - if (!index.isValid()) return; - - if (!(model()->flags(index) & Qt::ItemIsUserCheckable)) return; - } - - if (contextMenu.actions().size() > 0) - { - contextMenu.addSeparator(); - } - - if (selectionModel()->selectedIndexes().size() > 1) - { - contextMenu.addAction(QString("On"), this, SLOT(slotToggleItemsOn())); - contextMenu.addAction(QString("Off"), this, SLOT(slotToggleItemsOff())); - contextMenu.addAction(QString("Toggle"), this, SLOT(slotToggleItems())); - } - else - { - QModelIndex mIdx = selectionModel()->selectedIndexes()[0]; - caf::PdmUiTreeItem* treeItem = caf::UiTreeModelPdm::getTreeItemFromIndex(mIdx); - if (treeItem && treeItem->childCount()) - { - contextMenu.addAction(QString("Sub Items On"), this, SLOT(slotToggleItemsOn())); - contextMenu.addAction(QString("Sub Items Off"), this, SLOT(slotToggleItemsOff())); - contextMenu.addAction(QString("Toggle Sub items"), this, SLOT(slotToggleItems())); - } - } - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimUiTreeView::slotToggleItems() -{ - executeSelectionToggleOperation(TOGGLE); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimUiTreeView::executeSelectionToggleOperation(SelectionToggleType toggleState) -{ - RimUiTreeModelPdm* myModel = dynamic_cast(model()); - - myModel->setObjectToggleStateForSelection(selectionModel()->selectedIndexes(), toggleState); - - return; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimUiTreeView::slotToggleItemsOn() -{ - executeSelectionToggleOperation(TOGGLE_ON); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimUiTreeView::slotToggleItemsOff() -{ - executeSelectionToggleOperation(TOGGLE_OFF); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimUiTreeView::appendScriptItems(QMenu* menu, RimScriptCollection* scriptCollection) -{ - CVF_ASSERT(menu); - - QDir dir(scriptCollection->directory); - QMenu* subMenu = menu->addMenu(dir.dirName()); - - for (size_t i = 0; i < scriptCollection->calcScripts.size(); i++) - { - RimCalcScript* calcScript = scriptCollection->calcScripts[i]; - QFileInfo fi(calcScript->absolutePath()); - - QString menuText = fi.baseName(); - QAction* scriptAction = subMenu->addAction(menuText, this, SLOT(slotExecuteScriptForSelectedCases())); - - QModelIndex mi; - RimUiTreeModelPdm* myModel = dynamic_cast(model()); - if (myModel) - { - mi = myModel->getModelIndexFromPdmObject(calcScript); - } - - QString encodedModelIndex; - RimUiTreeView::encodeStringFromModelIndex(mi, encodedModelIndex); - - scriptAction->setData(QVariant(encodedModelIndex)); - } - - for (size_t i = 0; i < scriptCollection->subDirectories.size(); i++) - { - RimScriptCollection* subDir = scriptCollection->subDirectories[i]; - - appendScriptItems(subMenu, subDir); - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimUiTreeView::slotDeleteAllWellPaths() -{ - RimUiTreeModelPdm* myModel = dynamic_cast(model()); - if (myModel) - { - myModel->deleteAllWellPaths(currentIndex()); - - caf::PdmUiTreeItem* uiItem = myModel->getTreeItemFromIndex(currentIndex()); - if (uiItem && uiItem->dataObject()) - { - RimWellPathCollection* wellPathCollection = dynamic_cast(uiItem->dataObject().p()); - if (wellPathCollection) - { - wellPathCollection->scheduleGeometryRegenAndRedrawViews(); - } - } - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimUiTreeView::selectedUiItems(std::vector& objects) -{ - RimUiTreeModelPdm* myModel = dynamic_cast(model()); - QModelIndexList idxList = this->selectionModel()->selectedIndexes(); - - for (int i = 0; i < idxList.size(); i++) - { - caf::PdmUiTreeItem* uiItem = myModel->getTreeItemFromIndex(idxList[i]); - if (uiItem) - { - caf::PdmUiItem* item = uiItem->dataObject(); - objects.push_back(item); - } - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimUiTreeView::slotCloseGeomechCase() -{ - RimUiTreeModelPdm* myModel = dynamic_cast(model()); - std::vector selection; - this->selectedUiItems(selection); - myModel->deleteGeoMechCases(selection); - -} diff --git a/ApplicationCode/ProjectDataModel/RimUiTreeView.h b/ApplicationCode/ProjectDataModel/RimUiTreeView.h deleted file mode 100644 index 8475748e70..0000000000 --- a/ApplicationCode/ProjectDataModel/RimUiTreeView.h +++ /dev/null @@ -1,145 +0,0 @@ -///////////////////////////////////////////////////////////////////////////////// -// -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS -// -// ResInsight is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. -// -// See the GNU General Public License at -// for more details. -// -///////////////////////////////////////////////////////////////////////////////// - -#pragma once - -#include "cafPdmObject.h" - -#include - -class QItemSelection; -class RimIdenticalGridCaseGroup; -class RimScriptCollection; - -namespace caf { - class PdmObjectGroup; -} - -//================================================================================================== -/// -/// -//================================================================================================== -class RimUiTreeView : public QTreeView -{ - Q_OBJECT - -public: - RimUiTreeView(QWidget *parent = 0); - ~RimUiTreeView(); - - virtual void setModel(QAbstractItemModel* model); - - void selectedUiItems(std::vector& objects); - - - void applyTreeViewStateFromString(const QString& treeViewState); - void storeTreeViewStateToString(QString& treeViewState); - - static QModelIndex getModelIndexFromString(QAbstractItemModel* model, const QString& currentIndexString); - static void encodeStringFromModelIndex(const QModelIndex mi, QString& currentIndexString); - -protected: - void contextMenuEvent(QContextMenuEvent* event); - -private slots: - void slotAddChildItem(); - void slotDeleteItem(); - - void slotAddRangeFilter(); - void slotAddSliceFilterI(); - void slotAddSliceFilterJ(); - void slotAddSliceFilterK(); - void slotDeleteRangeFilter(); - - void slotAddPropertyFilter(); - void slotDeletePropertyFilter(); - void slotAddGeoMechPropertyFilter(); - void slotDeleteGeoMechPropertyFilter(); - - void slotEditScript(); - void slotNewScript(); - void slotExecuteScript(); - void slotExecuteScriptForSelectedCases(); - - void slotAddView(); - void slotDeleteView(); - - void slotAddInputProperty(); - void slotDeleteObjectFromContainer(); - void slotWriteInputProperty(); - void slotWriteBinaryResultAsInputProperty(); - - void slotCloseCase(); - void slotCloseGeomechCase(); - - void slotNewStatisticsCase(); - void slotComputeStatistics(); - - void slotAddCaseGroup(); - void slotDeleteObjectFromPdmPointersField(); - - void slotAddScriptPath(); - void slotDeleteScriptPath(); - - void slotCopyPdmObjectToClipboard(); - void slotPastePdmObjects(); - - void slotSelectionChanged(const QItemSelection & selected, const QItemSelection & deselected); - - void slotToggleItems(); - void slotToggleItemsOn(); - void slotToggleItemsOff(); - - void slotDeleteAllWellPaths(); - -signals: - void selectedObjectChanged( caf::PdmObject* pdmObject ); - -public: - enum SelectionToggleType - { - TOGGLE_ON, - TOGGLE_OFF, - TOGGLE, - TOGGLE_UNDEFINED - }; - - -private: - bool userConfirmedGridCaseGroupChange(const QModelIndexList& itemIndexList); - bool hasAnyStatisticsResults(RimIdenticalGridCaseGroup* gridCaseGroup); - - void createPdmObjectsFromClipboard(caf::PdmObjectGroup* objectGroup); - bool hasClipboardValidData(); - - virtual void keyPressEvent(QKeyEvent* keyEvent); - virtual void mousePressEvent(QMouseEvent* mouseEvent); - - virtual void dropEvent(QDropEvent* dropEvent); - - void executeSelectionToggleOperation(SelectionToggleType toggleState); - void appendToggleItemActions(QMenu& contextMenu); - - void setExpandedUpToRoot(const QModelIndex& itemIndex); - - void appendScriptItems(QMenu* menu, RimScriptCollection* scriptCollection); -private: - QAction* m_pasteAction; -}; - - diff --git a/ApplicationCode/ProjectDataModel/RimView.cpp b/ApplicationCode/ProjectDataModel/RimView.cpp index 1620ce362e..2bf4d50587 100644 --- a/ApplicationCode/ProjectDataModel/RimView.cpp +++ b/ApplicationCode/ProjectDataModel/RimView.cpp @@ -1,24 +1,36 @@ #include "RimView.h" -#include "cafPdmObjectFactory.h" #include "RiaApplication.h" #include "RiaPreferences.h" + +#include "RigCaseData.h" + #include "Rim3dOverlayInfoConfig.h" -#include "RiuViewer.h" +#include "RimCellRangeFilterCollection.h" +#include "RimEclipseCase.h" +#include "RimEclipseView.h" +#include "RimOilField.h" +#include "RimProject.h" +#include "RimViewController.h" +#include "RimViewLinker.h" +#include "RimViewLinkerCollection.h" +#include "RimWellPathCollection.h" + #include "RiuMainWindow.h" +#include "RiuViewer.h" + +#include "RivWellPathCollectionPartMgr.h" + +#include "cafFrameAnimationControl.h" +#include "cafPdmObjectFactory.h" #include "cvfCamera.h" #include "cvfModel.h" #include "cvfModelBasicList.h" #include "cvfPart.h" #include "cvfScene.h" #include "cvfViewport.h" -#include "cafFrameAnimationControl.h" #include -#include "RimOilField.h" -#include "RimWellPathCollection.h" -#include "RimProject.h" -#include "RivWellPathCollectionPartMgr.h" namespace caf { @@ -44,9 +56,7 @@ void caf::AppEnum< RimView::SurfaceModeType >::setUp() } // End namespace caf -#include "cafPdmAbstractClassSourceInit.h" - -CAF_PDM_ABSTRACT_SOURCE_INIT(RimView, "GenericView"); // Do not use. Abstract class +CAF_PDM_XML_ABSTRACT_SOURCE_INIT(RimView, "GenericView"); // Do not use. Abstract class //-------------------------------------------------------------------------------------------------- /// @@ -61,27 +71,28 @@ RimView::RimView(void) CAF_PDM_InitField(&name, "UserDescription", QString(""), "Name", "", "", ""); CAF_PDM_InitField(&showWindow, "ShowWindow", true, "Show 3D viewer", "", "", ""); - showWindow.setUiHidden(true); + showWindow.uiCapability()->setUiHidden(true); CAF_PDM_InitField(&cameraPosition, "CameraPosition", cvf::Mat4d::IDENTITY, "", "", "", ""); + cameraPosition.uiCapability()->setUiHidden(true); - double defaultScaleFactor = 1.0; - if (preferences) defaultScaleFactor = preferences->defaultScaleFactorZ; + double defaultScaleFactor = preferences->defaultScaleFactorZ; CAF_PDM_InitField(&scaleZ, "GridZScale", defaultScaleFactor, "Z Scale", "", "Scales the scene in the Z direction", ""); cvf::Color3f defBackgColor = preferences->defaultViewerBackgroundColor(); CAF_PDM_InitField(&backgroundColor, "ViewBackgroundColor", defBackgColor, "Background", "", "", ""); CAF_PDM_InitField(&maximumFrameRate, "MaximumFrameRate", 10, "Maximum frame rate", "", "", ""); - maximumFrameRate.setUiHidden(true); + maximumFrameRate.uiCapability()->setUiHidden(true); CAF_PDM_InitField(&hasUserRequestedAnimation, "AnimationMode", false, "Animation Mode", "", "", ""); - hasUserRequestedAnimation.setUiHidden(true); + hasUserRequestedAnimation.uiCapability()->setUiHidden(true); CAF_PDM_InitField(&m_currentTimeStep, "CurrentTimeStep", 0, "Current Time Step", "", "", ""); - m_currentTimeStep.setUiHidden(true); + m_currentTimeStep.uiCapability()->setUiHidden(true); - CAF_PDM_InitFieldNoDefault(&overlayInfoConfig, "OverlayInfoConfig", "Info Box", "", "", ""); - overlayInfoConfig = new Rim3dOverlayInfoConfig(); - overlayInfoConfig->setReservoirView(this); + CAF_PDM_InitFieldNoDefault(&m_overlayInfoConfig, "OverlayInfoConfig", "Info Box", "", "", ""); + m_overlayInfoConfig = new Rim3dOverlayInfoConfig(); + m_overlayInfoConfig->setReservoirView(this); + m_overlayInfoConfig.uiCapability()->setUiHidden(true); caf::AppEnum defaultMeshType = NO_MESH; if (preferences->defaultGridLines) defaultMeshType = FULL_MESH; @@ -90,6 +101,18 @@ RimView::RimView(void) CAF_PDM_InitField(&m_disableLighting, "DisableLighting", false, "Disable Results Lighting", "", "Disable light model for scalar result colors", ""); + CAF_PDM_InitFieldNoDefault(&windowGeometry, "WindowGeometry", "", "", "", ""); + windowGeometry.uiCapability()->setUiHidden(true); + + CAF_PDM_InitFieldNoDefault(&m_rangeFilterCollection, "RangeFilters", "Range Filters", "", "", ""); + m_rangeFilterCollection.uiCapability()->setUiHidden(true); + m_rangeFilterCollection = new RimCellRangeFilterCollection(); + + CAF_PDM_InitFieldNoDefault(&m_overrideRangeFilterCollection, "RangeFiltersControlled", "Range Filters (controlled)", "", "", ""); + m_overrideRangeFilterCollection.uiCapability()->setUiHidden(true); + m_overrideRangeFilterCollection.xmlCapability()->setIOWritable(false); + m_overrideRangeFilterCollection.xmlCapability()->setIOReadable(false); + m_previousGridModeMeshLinesWasFaults = false; } @@ -98,14 +121,37 @@ RimView::RimView(void) //-------------------------------------------------------------------------------------------------- RimView::~RimView(void) { - delete this->overlayInfoConfig(); + RimProject* proj = RiaApplication::instance()->project(); + + if (proj && this->isMasterView()) + { + delete proj->viewLinkerCollection->viewLinker(); + proj->viewLinkerCollection->viewLinker = NULL; + + proj->uiCapability()->updateConnectedEditors(); + } + + RimViewController* vController = this->viewController(); + if (proj && vController) + { + vController->setManagedView(NULL); + vController->ownerViewLinker()->removeViewController(vController); + delete vController; + + proj->uiCapability()->updateConnectedEditors(); + } + + delete this->m_overlayInfoConfig(); if (m_viewer) { - RiuMainWindow::instance()->removeViewer(m_viewer); + RiuMainWindow::instance()->removeViewer(m_viewer->layoutWidget()); } delete m_viewer; + + delete m_rangeFilterCollection; + delete m_overrideRangeFilterCollection; } //-------------------------------------------------------------------------------------------------- @@ -132,7 +178,7 @@ void RimView::updateViewerWidget() m_viewer = new RiuViewer(glFormat, NULL); m_viewer->setOwnerReservoirView(this); - RiuMainWindow::instance()->addViewer(m_viewer); + RiuMainWindow::instance()->addViewer(m_viewer->layoutWidget(), windowGeometry()); m_viewer->setMinNearPlaneDistance(10); this->resetLegendsInViewer(); @@ -143,7 +189,7 @@ void RimView::updateViewerWidget() isViewerCreated = true; } - RiuMainWindow::instance()->setActiveViewer(m_viewer); + RiuMainWindow::instance()->setActiveViewer(m_viewer->layoutWidget()); if (isViewerCreated) m_viewer->mainCamera()->setViewMatrix(cameraPosition); m_viewer->mainCamera()->viewport()->setClearColor(cvf::Color4f(backgroundColor())); @@ -152,7 +198,7 @@ void RimView::updateViewerWidget() } else { - if (m_viewer) + if (m_viewer && m_viewer->layoutWidget()) { if (m_viewer->layoutWidget()->parentWidget()) { @@ -175,6 +221,14 @@ void RimView::updateViewerWidget() void RimView::scheduleCreateDisplayModelAndRedraw() { RiaApplication::instance()->scheduleDisplayModelUpdateAndRedraw(this); + if (this->isMasterView()) + { + RimViewLinker* viewLinker = this->assosiatedViewLinker(); + if (viewLinker) + { + viewLinker->scheduleCreateDisplayModelAndRedrawForDependentViews(); + } + } } //-------------------------------------------------------------------------------------------------- @@ -183,6 +237,8 @@ void RimView::scheduleCreateDisplayModelAndRedraw() void RimView::setCurrentTimeStep(int frameIndex) { m_currentTimeStep = frameIndex; + clampCurrentTimestep(); + this->hasUserRequestedAnimation = true; this->updateCurrentTimeStep(); } @@ -207,6 +263,12 @@ void RimView::createDisplayModelAndRedraw() createDisplayModel(); updateDisplayModelVisibility(); + + if (cameraPosition().isIdentity()) + { + setDefaultView(); + cameraPosition = m_viewer->mainCamera()->viewMatrix(); + } } RiuMainWindow::instance()->refreshAnimationActions(); @@ -244,7 +306,9 @@ void RimView::setupBeforeSave() { hasUserRequestedAnimation = m_viewer->isAnimationActive(); // JJS: This is not conceptually correct. The variable is updated as we go, and store the user intentions. But I guess that in practice... cameraPosition = m_viewer->mainCamera()->viewMatrix(); - } + + windowGeometry = RiuMainWindow::instance()->windowGeometryForViewer(m_viewer->layoutWidget()); + } } //-------------------------------------------------------------------------------------------------- @@ -270,14 +334,14 @@ void RimView::setMeshOnlyDrawstyle() { if (isGridVisualizationMode()) { - meshMode.setValueFromUi(FULL_MESH); + meshMode.uiCapability()->setValueFromUi(FULL_MESH); } else { - meshMode.setValueFromUi(FAULTS_MESH); + meshMode.uiCapability()->setValueFromUi(FAULTS_MESH); } - surfaceMode.setValueFromUi(NO_SURFACE); + surfaceMode.uiCapability()->setValueFromUi(NO_SURFACE); } //-------------------------------------------------------------------------------------------------- @@ -287,13 +351,13 @@ void RimView::setMeshSurfDrawstyle() { if (isGridVisualizationMode()) { - surfaceMode.setValueFromUi(SURFACE); - meshMode.setValueFromUi(FULL_MESH); + surfaceMode.uiCapability()->setValueFromUi(SURFACE); + meshMode.uiCapability()->setValueFromUi(FULL_MESH); } else { - surfaceMode.setValueFromUi(FAULTS); - meshMode.setValueFromUi(FAULTS_MESH); + surfaceMode.uiCapability()->setValueFromUi(FAULTS); + meshMode.uiCapability()->setValueFromUi(FAULTS_MESH); } } @@ -309,14 +373,14 @@ void RimView::setFaultMeshSurfDrawstyle() // Mesh SF SF SF if (this->isGridVisualizationMode()) { - surfaceMode.setValueFromUi(SURFACE); + surfaceMode.uiCapability()->setValueFromUi(SURFACE); } else { - surfaceMode.setValueFromUi(FAULTS); + surfaceMode.uiCapability()->setValueFromUi(FAULTS); } - meshMode.setValueFromUi(FAULTS_MESH); + meshMode.uiCapability()->setValueFromUi(FAULTS_MESH); } //-------------------------------------------------------------------------------------------------- @@ -326,13 +390,14 @@ void RimView::setSurfOnlyDrawstyle() { if (isGridVisualizationMode()) { - surfaceMode.setValueFromUi(SURFACE); + surfaceMode.uiCapability()->setValueFromUi(SURFACE); } else { - surfaceMode.setValueFromUi(FAULTS); + surfaceMode.uiCapability()->setValueFromUi(FAULTS); } - meshMode.setValueFromUi(NO_MESH); + + meshMode.uiCapability()->setValueFromUi(NO_MESH); } //-------------------------------------------------------------------------------------------------- @@ -343,13 +408,13 @@ void RimView::setShowFaultsOnly(bool showFaults) if (showFaults) { m_previousGridModeMeshLinesWasFaults = meshMode() == FAULTS_MESH; - if (surfaceMode() != NO_SURFACE) surfaceMode.setValueFromUi(FAULTS); - if (meshMode() != NO_MESH) meshMode.setValueFromUi(FAULTS_MESH); + if (surfaceMode() != NO_SURFACE) surfaceMode.uiCapability()->setValueFromUi(FAULTS); + if (meshMode() != NO_MESH) meshMode.uiCapability()->setValueFromUi(FAULTS_MESH); } else { - if (surfaceMode() != NO_SURFACE) surfaceMode.setValueFromUi(SURFACE); - if (meshMode() != NO_MESH) meshMode.setValueFromUi(m_previousGridModeMeshLinesWasFaults ? FAULTS_MESH: FULL_MESH); + if (surfaceMode() != NO_SURFACE) surfaceMode.uiCapability()->setValueFromUi(SURFACE); + if (meshMode() != NO_MESH) meshMode.uiCapability()->setValueFromUi(m_previousGridModeMeshLinesWasFaults ? FAULTS_MESH : FULL_MESH); } } @@ -358,7 +423,7 @@ void RimView::setShowFaultsOnly(bool showFaults) //-------------------------------------------------------------------------------------------------- void RimView::setSurfaceDrawstyle() { - if (surfaceMode() != NO_SURFACE) surfaceMode.setValueFromUi(SURFACE); + if (surfaceMode() != NO_SURFACE) surfaceMode.uiCapability()->setValueFromUi(SURFACE); } //-------------------------------------------------------------------------------------------------- @@ -415,7 +480,15 @@ void RimView::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QV updateScaleTransform(); createDisplayModelAndRedraw(); + m_viewer->update(); + + RimViewLinker* viewLinker = this->assosiatedViewLinker(); + if (viewLinker) + { + viewLinker->updateScaleZ(this, scaleZ); + viewLinker->updateCamera(this); + } } RiuMainWindow::instance()->updateScaleValue(); @@ -434,12 +507,32 @@ void RimView::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QV else if (changedField == &name) { updateViewerWidgetWindowTitle(); + + if (viewController()) + { + viewController()->updateDisplayNameAndIcon(); + viewController()->updateConnectedEditors(); + } + else + { + if (isMasterView()) + { + assosiatedViewLinker()->updateUiNameAndIcon(); + assosiatedViewLinker()->updateConnectedEditors(); + } + } } else if (changedField == &m_currentTimeStep) { if (m_viewer) { m_viewer->update(); + + RimViewLinker* viewLinker = this->assosiatedViewLinker(); + if (viewLinker) + { + viewLinker->updateTimeStep(this, m_currentTimeStep); + } } } else if (changedField == &backgroundColor) @@ -484,3 +577,172 @@ void RimView::addWellPathsToModel(cvf::ModelBasicList* wellPathModelBasicList, wellPathModelBasicList->updateBoundingBoxesRecursive(); } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimCellRangeFilterCollection* RimView::rangeFilterCollection() +{ + if (this->viewController() && this->viewController()->isRangeFiltersControlled() && m_overrideRangeFilterCollection) + { + return m_overrideRangeFilterCollection; + } + else + { + return m_rangeFilterCollection; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const RimCellRangeFilterCollection* RimView::rangeFilterCollection() const +{ + if (this->viewController() && this->viewController()->isRangeFiltersControlled() && m_overrideRangeFilterCollection) + { + return m_overrideRangeFilterCollection; + } + else + { + return m_rangeFilterCollection; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimView::setOverrideRangeFilterCollection(RimCellRangeFilterCollection* rfc) +{ + if (m_overrideRangeFilterCollection()) delete m_overrideRangeFilterCollection(); + + m_overrideRangeFilterCollection = rfc; + this->scheduleGeometryRegen(RANGE_FILTERED); + this->scheduleGeometryRegen(RANGE_FILTERED_INACTIVE); + + this->scheduleCreateDisplayModelAndRedraw(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimView::setScaleZAndUpdate(double scaleZ) +{ + this->scaleZ = scaleZ; + updateScaleTransform(); + this->scheduleCreateDisplayModelAndRedraw(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimViewController* RimView::viewController() const +{ + RimViewController* viewController = NULL; + std::vector reffingObjs; + + this->objectsWithReferringPtrFields(reffingObjs); + for (size_t i = 0; i < reffingObjs.size(); ++i) + { + viewController = dynamic_cast(reffingObjs[i]); + if (viewController) break; + } + + return viewController; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimViewLinker* RimView::viewLinkerIfMasterView() const +{ + RimViewLinker* viewLinker = NULL; + std::vector reffingObjs; + + this->objectsWithReferringPtrFields(reffingObjs); + + for (size_t i = 0; i < reffingObjs.size(); ++i) + { + viewLinker = dynamic_cast(reffingObjs[i]); + if (viewLinker) break; + } + + return viewLinker; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimViewLinker* RimView::assosiatedViewLinker() const +{ + RimViewLinker* viewLinker = this->viewLinkerIfMasterView(); + if (!viewLinker) + { + RimViewController* viewController = this->viewController(); + if (viewController) + { + viewLinker = viewController->ownerViewLinker(); + } + } + + return viewLinker; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +cvf::ref RimView::currentTotalCellVisibility() +{ + if (m_currentReservoirCellVisibility.isNull()) + { + m_currentReservoirCellVisibility = new cvf::UByteArray; + this->calculateCurrentTotalCellVisibility(m_currentReservoirCellVisibility.p()); + } + + return m_currentReservoirCellVisibility; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimView::isMasterView() const +{ + RimViewLinker* viewLinker = this->assosiatedViewLinker(); + if (viewLinker && this == viewLinker->masterView()) + { + return true; + } + + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimCellRangeFilterCollection* RimView::overrideRangeFilterCollection() +{ + return m_overrideRangeFilterCollection(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimView::replaceRangeFilterCollectionWithOverride() +{ + RimCellRangeFilterCollection* overrideRfc = m_overrideRangeFilterCollection; + CVF_ASSERT(overrideRfc); + + RimCellRangeFilterCollection* currentRfc = m_rangeFilterCollection; + if (currentRfc) + { + delete currentRfc; + } + + // Must call removeChildObject() to make sure the object has no parent + // No parent is required when assigning a object into a field + m_overrideRangeFilterCollection.removeChildObject(overrideRfc); + + m_rangeFilterCollection = overrideRfc; + + this->uiCapability()->updateConnectedEditors(); +} + diff --git a/ApplicationCode/ProjectDataModel/RimView.h b/ApplicationCode/ProjectDataModel/RimView.h index 5846d1fec2..ec84420a08 100644 --- a/ApplicationCode/ProjectDataModel/RimView.h +++ b/ApplicationCode/ProjectDataModel/RimView.h @@ -19,23 +19,36 @@ #pragma once -#include "cafPdmObject.h" +#include "cafAppEnum.h" +#include "cafPdmChildArrayField.h" +#include "cafPdmChildField.h" #include "cafPdmField.h" #include "cafPdmFieldCvfColor.h" #include "cafPdmFieldCvfMat4d.h" -#include "cafAppEnum.h" +#include "cafPdmObject.h" + #include "RivCellSetEnum.h" -class RiuViewer; +#include "cvfArray.h" +#include "cvfBase.h" +#include "cvfObject.h" + + +#include + class Rim3dOverlayInfoConfig; class RimCase; +class RimCellRangeFilter; class RimCellRangeFilterCollection; +class RiuViewer; +class RimViewLinker; +class RimViewController; namespace cvf { class BoundingBox; - class Scene; class ModelBasicList; + class Scene; class Transform; } @@ -63,7 +76,15 @@ class RimView : public caf::PdmObject caf::PdmField maximumFrameRate; caf::PdmField hasUserRequestedAnimation; - caf::PdmField rangeFilterCollection; + RimCellRangeFilterCollection* rangeFilterCollection(); + const RimCellRangeFilterCollection* rangeFilterCollection() const; + + RimCellRangeFilterCollection* overrideRangeFilterCollection(); + void setOverrideRangeFilterCollection(RimCellRangeFilterCollection* rfc); + void replaceRangeFilterCollectionWithOverride(); + + caf::PdmField< std::vector > windowGeometry; + // Draw style @@ -96,6 +117,8 @@ class RimView : public caf::PdmObject void setShowFaultsOnly(bool showFaults); bool isGridVisualizationMode() const; + void setScaleZAndUpdate(double scaleZ); + // Animation int currentTimeStep() { return m_currentTimeStep;} void setCurrentTimeStep(int frameIdx); @@ -106,6 +129,12 @@ class RimView : public caf::PdmObject void scheduleCreateDisplayModelAndRedraw(); void createDisplayModelAndRedraw(); + RimViewController* viewController() const; + bool isMasterView() const; + RimViewLinker* assosiatedViewLinker() const; + + cvf::ref currentTotalCellVisibility(); + public: virtual void loadDataAndUpdate() = 0; virtual RimCase* ownerCase() = 0; @@ -136,21 +165,29 @@ class RimView : public caf::PdmObject virtual void updateViewerWidgetWindowTitle() = 0; virtual void resetLegendsInViewer() = 0; - + virtual void calculateCurrentTotalCellVisibility(cvf::UByteArray* totalVisibility) = 0; + QPointer m_viewer; - caf::PdmField m_currentTimeStep; - caf::PdmField overlayInfoConfig; + caf::PdmField m_currentTimeStep; + caf::PdmChildField m_overlayInfoConfig; + + caf::PdmChildField m_rangeFilterCollection; + caf::PdmChildField m_overrideRangeFilterCollection; // Overridden PDM methods: virtual void setupBeforeSave(); virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue); + cvf::ref m_currentReservoirCellVisibility; + +private: + RimViewLinker* viewLinkerIfMasterView() const; + private: bool m_previousGridModeMeshLinesWasFaults; caf::PdmField m_disableLighting; - }; diff --git a/ApplicationCode/ProjectDataModel/RimViewController.cpp b/ApplicationCode/ProjectDataModel/RimViewController.cpp new file mode 100644 index 0000000000..4cc5832ba9 --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimViewController.cpp @@ -0,0 +1,987 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RimViewController.h" + +#include "RiaApplication.h" + +#include "RigCaseData.h" +#include "RigCaseToCaseCellMapper.h" +#include "RigFemPartCollection.h" +#include "RigGeoMechCaseData.h" + +#include "RimCase.h" +#include "RimCellRangeFilterCollection.h" +#include "RimEclipseCase.h" +#include "RimEclipseCellColors.h" +#include "RimEclipsePropertyFilterCollection.h" +#include "RimEclipseView.h" +#include "RimGeoMechCase.h" +#include "RimGeoMechCellColors.h" +#include "RimGeoMechPropertyFilterCollection.h" +#include "RimGeoMechView.h" +#include "RimProject.h" +#include "RimView.h" +#include "RimViewLinker.h" +#include "RimViewLinkerCollection.h" + +#include "RiuViewer.h" + +#include "cafPdmUiTreeOrdering.h" +#include "RigCaseToCaseRangeFilterMapper.h" + +#include + +CAF_PDM_SOURCE_INIT(RimViewController, "ViewController"); +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimViewController::RimViewController(void) +{ + CAF_PDM_InitObject("View Link", "", "", ""); + + CAF_PDM_InitField(&m_isActive, "Active", true, "Active", "", "", ""); + m_isActive.uiCapability()->setUiHidden(true); + + QString defaultName = "View Config: Empty view"; + CAF_PDM_InitField(&m_name, "Name", defaultName, "Managed View Name", "", "", ""); + m_name.uiCapability()->setUiHidden(true); + + CAF_PDM_InitFieldNoDefault(&m_managedView, "ManagedView", "Linked View", "", "", ""); + m_managedView.uiCapability()->setUiChildrenHidden(true); + + CAF_PDM_InitField(&m_syncCamera, "SyncCamera", true, "Camera", "", "", ""); + CAF_PDM_InitField(&m_syncTimeStep, "SyncTimeStep", true, "Time Step", "", "", ""); + CAF_PDM_InitField(&m_syncCellResult, "SyncCellResult", false, "Cell Color Result", "", "", ""); + + CAF_PDM_InitField(&m_syncVisibleCells, "SyncVisibleCells", false, "Visible Cells", "", "", ""); + /// We do not support this. Consider to remove sometime + m_syncVisibleCells.uiCapability()->setUiHidden(true); + m_syncVisibleCells.xmlCapability()->setIOWritable(false); + m_syncVisibleCells.xmlCapability()->setIOReadable(false); + + CAF_PDM_InitField(&m_syncRangeFilters, "SyncRangeFilters", false, "Range Filters", "", "", ""); + CAF_PDM_InitField(&m_syncPropertyFilters, "SyncPropertyFilters", false,"Property Filters", "", "", ""); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimViewController::~RimViewController(void) +{ + this->removeOverrides(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QList RimViewController::calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly) +{ + QList optionList; + + if (fieldNeedingOptions == &m_managedView) + { + RimProject* proj = RiaApplication::instance()->project(); + std::vector views; + proj->allNotLinkedViews(views); + + // Add currently linked view to list + if (this->managedView()) + { + views.push_back(this->managedView()); + } + + RimViewLinker* linkedViews = NULL; + this->firstAnchestorOrThisOfType(linkedViews); + + for (size_t i = 0; i< views.size(); i++) + { + if (views[i] != linkedViews->masterView()) + { + RimCase* rimCase = NULL; + views[i]->firstAnchestorOrThisOfType(rimCase); + QIcon icon; + if (rimCase) + { + icon = rimCase->uiCapability()->uiIcon(); + } + + optionList.push_back(caf::PdmOptionItemInfo(RimViewLinker::displayNameForView(views[i]), + QVariant::fromValue(caf::PdmPointer(views[i])), + false, + icon)); + } + } + + if (optionList.size() > 0) + { + optionList.push_front(caf::PdmOptionItemInfo("None", QVariant::fromValue(caf::PdmPointer(NULL)))); + } + } + + return optionList; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimViewController::defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName /*= ""*/) +{ + updateDisplayNameAndIcon(); + uiTreeOrdering.setForgetRemainingFields(true); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimViewController::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) +{ + if (changedField == &m_isActive) + { + if (!m_isActive) + { + applyRangeFilterCollectionByUserChoice(); + } + + updateOverrides(); + updateResultColorsControl(); + updateCameraLink(); + updateDisplayNameAndIcon(); + updateTimeStepLink(); + } + else if (changedField == &m_syncCamera) + { + updateCameraLink(); + } + else if (changedField == &m_syncTimeStep ) + { + updateTimeStepLink(); + } + else if (changedField == &m_syncCellResult) + { + updateResultColorsControl(); + if (managedEclipseView()) + { + managedEclipseView()->cellResult()->updateIconState(); + } + else if (managedGeoView()) + { + managedGeoView()->cellResult()->updateIconState(); + } + } + else if (changedField == &m_syncRangeFilters) + { + if (!m_syncRangeFilters) + { + applyRangeFilterCollectionByUserChoice(); + } + updateOverrides(); + } + else if (changedField == &m_syncPropertyFilters) + { + updateOverrides(); + } + else if (changedField == &m_managedView) + { + PdmObjectHandle* prevValue = oldValue.value >().rawPtr(); + RimView* previousManagedView = dynamic_cast(prevValue); + RimViewController::removeOverrides(previousManagedView); + + setManagedView(m_managedView()); + + m_name.uiCapability()->updateConnectedEditors(); + } + else if (&m_syncVisibleCells == changedField) + { + updateOptionSensitivity(); + updateOverrides(); + } +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimEclipseView* RimViewController::managedEclipseView() +{ + RimView* rimView = m_managedView; + + return dynamic_cast(rimView); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimGeoMechView* RimViewController::managedGeoView() +{ + RimView* rimView = m_managedView; + + return dynamic_cast(rimView); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimViewController::updateOverrides() +{ + RimViewLinker* viewLinker = ownerViewLinker(); + + RimView* masterView = viewLinker->masterView(); + + CVF_ASSERT(masterView); + + if (m_managedView) + { + RimEclipseView* manEclView = managedEclipseView(); + RimGeoMechView* manGeoView = managedGeoView(); + + if (isVisibleCellsOveridden()) + { + if (manEclView) manEclView->setOverridePropertyFilterCollection(NULL); + if (manGeoView) manGeoView->setOverridePropertyFilterCollection(NULL); + m_managedView->scheduleGeometryRegen(OVERRIDDEN_CELL_VISIBILITY); + m_managedView->scheduleCreateDisplayModelAndRedraw(); + } + else + { + RimEclipseView* masterEclipseView = dynamic_cast(masterView); + if (masterEclipseView) + { + + if (manEclView) + { + if (isPropertyFilterOveridden()) + { + manEclView->setOverridePropertyFilterCollection(masterEclipseView->propertyFilterCollection()); + } + else + { + manEclView->setOverridePropertyFilterCollection(NULL); + } + } + } + + RimGeoMechView* masterGeoView = dynamic_cast(masterView); + if (masterGeoView) + { + if (manGeoView) + { + if (isPropertyFilterOveridden()) + { + manGeoView->setOverridePropertyFilterCollection(masterGeoView->propertyFilterCollection()); + } + else + { + manGeoView->setOverridePropertyFilterCollection(NULL); + } + } + } + } + + this->updateRangeFilterOverrides(NULL); + + if (manGeoView) + { + manGeoView->updateIconStateForFilterCollections(); + } + + if (manEclView) + { + manEclView->updateIconStateForFilterCollections(); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimViewController::removeOverrides() +{ + removeOverrides(m_managedView); + + RimEclipseView* manEclView = managedEclipseView(); + RimGeoMechView* manGeoView = managedGeoView(); + + if (manGeoView) + { + manGeoView->updateIconStateForFilterCollections(); + } + + if (manEclView) + { + manEclView->updateIconStateForFilterCollections(); + } +} +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimViewController::removeOverrides(RimView* view) +{ + if (view) + { + RimEclipseView* manEclView = dynamic_cast(view); + RimGeoMechView* manGeoView = dynamic_cast(view); + + if (manEclView) manEclView->setOverridePropertyFilterCollection(NULL); + if (manGeoView) manGeoView->setOverridePropertyFilterCollection(NULL); + + view->setOverrideRangeFilterCollection(NULL); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimViewController::updateOptionSensitivity() +{ + RimViewLinker* linkedViews = NULL; + firstAnchestorOrThisOfType(linkedViews); + CVF_ASSERT(linkedViews); + + RimView* mainView = linkedViews->masterView(); + CVF_ASSERT(mainView); + + RimEclipseView* eclipseMasterView = dynamic_cast(mainView); + RimGeoMechView* geoMasterView = dynamic_cast(mainView); + + bool isMasterAndDependentViewDifferentType = false; + if (eclipseMasterView && !managedEclipseView()) + { + isMasterAndDependentViewDifferentType = true; + } + if (geoMasterView && !managedGeoView()) + { + isMasterAndDependentViewDifferentType = true; + } + + if (isMasterAndDependentViewDifferentType) + { + this->m_syncCellResult.uiCapability()->setUiReadOnly(true); + this->m_syncCellResult = false; + } + else + { + this->m_syncCellResult.uiCapability()->setUiReadOnly(false); + } + + if (isPropertyFilterControlPossible()) + { + this->m_syncPropertyFilters.uiCapability()->setUiReadOnly(false); + } + else + { + this->m_syncPropertyFilters.uiCapability()->setUiReadOnly(true); + this->m_syncPropertyFilters = false; + } + + + if (isRangeFilterControlPossible()) + { + this->m_syncRangeFilters.uiCapability()->setUiReadOnly(false); + } + else + { + this->m_syncRangeFilters.uiCapability()->setUiReadOnly(true); + this->m_syncRangeFilters = false; + } + + m_syncVisibleCells.uiCapability()->setUiReadOnly(!this->isMasterAndDepViewDifferentType()); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimView* RimViewController::managedView() +{ + return m_managedView; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimViewController::setManagedView(RimView* view) +{ + m_managedView = view; + + updateOptionSensitivity(); + updateOverrides(); + updateResultColorsControl(); + updateCameraLink(); + updateDisplayNameAndIcon(); + updateTimeStepLink(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimViewController::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) +{ + updateOptionSensitivity(); + uiOrdering.add(&m_managedView); + + caf::PdmUiGroup* scriptGroup = uiOrdering.addNewGroup("Link Options"); + + scriptGroup->add(&m_syncCamera); + scriptGroup->add(&m_syncTimeStep); + scriptGroup->add(&m_syncCellResult); + + caf::PdmUiGroup* visibleCells = uiOrdering.addNewGroup("Link Cell Filters"); + visibleCells->add(&m_syncVisibleCells); + visibleCells->add(&m_syncRangeFilters); + visibleCells->add(&m_syncPropertyFilters); +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimViewController::updateDisplayNameAndIcon() +{ + RimViewLinker::findNameAndIconFromView(&m_name.v(), &m_originalIcon, managedView()); + RimViewLinker::applyIconEnabledState(this, m_originalIcon, !m_isActive()); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimViewController::updateCameraLink() +{ + if (!this->isCameraLinked()) return; + if (m_managedView) + { + RimViewLinker* viewLinker = this->ownerViewLinker(); + + viewLinker->updateScaleZ(viewLinker->masterView(), viewLinker->masterView()->scaleZ()); + viewLinker->updateCamera(viewLinker->masterView()); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimViewController::updateTimeStepLink() +{ + if (!this->isTimeStepLinked()) return; + + if (m_managedView) + { + RimViewLinker* viewLinker = this->ownerViewLinker(); + + viewLinker->updateTimeStep(viewLinker->masterView(), viewLinker->masterView()->currentTimeStep()); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimViewController::updateResultColorsControl() +{ + if (!this->isResultColorControlled()) return; + + RimViewLinker* viewLinker = ownerViewLinker(); + viewLinker->updateCellResult(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimViewLinker* RimViewController::ownerViewLinker() +{ + RimViewLinker* viewLinker = NULL; + this->firstAnchestorOrThisOfType(viewLinker); + + return viewLinker; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const RigCaseToCaseCellMapper* RimViewController::cellMapper() +{ + RimEclipseView* masterEclipseView = dynamic_cast(masterView()); + RimEclipseView* dependEclipseView = managedEclipseView(); + RimGeoMechView* masterGeomechView = dynamic_cast(masterView()); + RimGeoMechView* dependGeomechView = managedGeoView(); + + RigMainGrid* masterEclGrid = NULL; + RigMainGrid* dependEclGrid = NULL; + RigFemPart* masterFemPart = NULL; + RigFemPart* dependFemPart = NULL; + + if (masterEclipseView && masterEclipseView->eclipseCase()->reservoirData()) + { + masterEclGrid = masterEclipseView->eclipseCase()->reservoirData()->mainGrid(); + } + + if (dependEclipseView && dependEclipseView->eclipseCase()->reservoirData()) + { + dependEclGrid = dependEclipseView->eclipseCase()->reservoirData()->mainGrid(); + } + + if (masterGeomechView && masterGeomechView->geoMechCase()->geoMechData() + && masterGeomechView->geoMechCase()->geoMechData()->femParts()->partCount()) + { + masterFemPart = masterGeomechView->geoMechCase()->geoMechData()->femParts()->part(0); + } + + if (dependGeomechView && dependGeomechView->geoMechCase()->geoMechData() + && dependGeomechView->geoMechCase()->geoMechData()->femParts()->partCount()) + { + dependFemPart = dependGeomechView->geoMechCase()->geoMechData()->femParts()->part(0); + } + + // If we have the correct mapping already, return it. + if (m_caseToCaseCellMapper.notNull()) + { + if ( masterEclGrid == m_caseToCaseCellMapper->masterGrid() + && dependEclGrid == m_caseToCaseCellMapper->dependentGrid() + && masterFemPart == m_caseToCaseCellMapper->masterFemPart() + && dependFemPart == m_caseToCaseCellMapper->dependentFemPart()) + { + return m_caseToCaseCellMapper.p(); + } + else + { + m_caseToCaseCellMapper = NULL; + } + } + + // Create the mapping if needed + + if (m_caseToCaseCellMapper.isNull()) + { + if (masterEclGrid && dependFemPart) + { + m_caseToCaseCellMapper = new RigCaseToCaseCellMapper(masterEclGrid, dependFemPart); + } + else if (masterEclGrid && dependEclGrid) + { + m_caseToCaseCellMapper = new RigCaseToCaseCellMapper(masterEclGrid, dependEclGrid); + } + else if (masterFemPart && dependFemPart) + { + m_caseToCaseCellMapper = new RigCaseToCaseCellMapper(masterFemPart, dependFemPart); + } + else if (masterFemPart && dependEclGrid) + { + m_caseToCaseCellMapper = new RigCaseToCaseCellMapper(masterFemPart, dependEclGrid); + } + } + + return m_caseToCaseCellMapper.p(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimView* RimViewController::masterView() +{ + return ownerViewLinker()->masterView(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimViewController::isMasterAndDepViewDifferentType() +{ + RimEclipseView* eclipseMasterView = dynamic_cast(masterView()); + RimGeoMechView* geoMasterView = dynamic_cast(masterView()); + + bool isMasterAndDependentViewDifferentType = false; + if (eclipseMasterView && !managedEclipseView()) + { + isMasterAndDependentViewDifferentType = true; + } + if (geoMasterView && !managedGeoView()) + { + isMasterAndDependentViewDifferentType = true; + } + + return isMasterAndDependentViewDifferentType; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimViewController::scheduleCreateDisplayModelAndRedrawForDependentView() +{ + if (!this->isActive()) return; + + if (this->isVisibleCellsOveridden() + || this->isRangeFiltersControlled() + || this->isPropertyFilterOveridden() + || this->isResultColorControlled() + ) + { + if (this->managedView()) + { + this->managedView()->scheduleCreateDisplayModelAndRedraw(); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimViewController::scheduleGeometryRegenForDepViews(RivCellSetEnum geometryType) +{ + if (!this->isActive()) return; + + if ( this->isVisibleCellsOveridden() + || this->isRangeFiltersControlled() + || this->isPropertyFilterOveridden() + || this->isResultColorControlled() + ) + { + if (this->managedView()) + { + if (this->isVisibleCellsOveridden()) + { + this->managedView()->scheduleGeometryRegen(OVERRIDDEN_CELL_VISIBILITY); + } + + this->managedView()->scheduleGeometryRegen(geometryType); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimViewController::isActive() +{ + return ownerViewLinker()->isActive() && this->m_isActive(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimViewController::isCameraLinked() +{ + if (ownerViewLinker()->isActive() && this->m_isActive()) + { + return m_syncCamera; + } + else + { + return false; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimViewController::isTimeStepLinked() +{ + if (ownerViewLinker()->isActive() && this->m_isActive()) + { + return m_syncTimeStep; + } + else + { + return false; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimViewController::isResultColorControlled() +{ + if (ownerViewLinker()->isActive() && this->m_isActive()) + { + return m_syncCellResult; + } + else + { + return false; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimViewController::isVisibleCellsOveridden() +{ + if (isMasterAndDepViewDifferentType()) + { + if (ownerViewLinker()->isActive() && this->m_isActive()) + { + return m_syncVisibleCells(); + } + else + { + return false; + } + } + else + { + return false; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimViewController::isRangeFilterControlPossible() +{ + return true; + #if 0 + if (!isMasterAndDepViewDifferentType()) return true; + + // Make sure the cases are in the same domain + RimEclipseView* eclipseView = dynamic_cast(masterView()); + RimGeoMechView* geomView = dynamic_cast(masterView()); + if (!geomView) geomView = managedGeoView(); + if (!eclipseView) eclipseView = managedEclipseView(); + + if (eclipseView && geomView) + { + if (eclipseView->eclipseCase()->reservoirData() && geomView->geoMechCase()->geoMechData()) + { + RigMainGrid* eclGrid = eclipseView->eclipseCase()->reservoirData()->mainGrid(); + RigFemPart* femPart = geomView->geoMechCase()->geoMechData()->femParts()->part(0); + + if (eclGrid && femPart) + { + cvf::BoundingBox fembb = femPart->boundingBox(); + cvf::BoundingBox eclbb = eclGrid->boundingBox(); + return fembb.contains(eclbb.min()) && fembb.contains(eclbb.max()); + } + } + } + return false; + #endif +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimViewController::isRangeFilterMappingApliccable() +{ + if (!isMasterAndDepViewDifferentType()) return false; + + // Make sure the cases are in the same domain + RimEclipseView* eclipseView = dynamic_cast(masterView()); + RimGeoMechView* geomView = dynamic_cast(masterView()); + if (!geomView) geomView = managedGeoView(); + if (!eclipseView) eclipseView = managedEclipseView(); + + if (eclipseView && geomView) + { + if (eclipseView->eclipseCase()->reservoirData() && geomView->geoMechCase()->geoMechData()) + { + RigMainGrid* eclGrid = eclipseView->eclipseCase()->reservoirData()->mainGrid(); + RigFemPart* femPart = geomView->geoMechCase()->geoMechData()->femParts()->part(0); + + if (eclGrid && femPart) + { + cvf::BoundingBox fembb = femPart->boundingBox(); + cvf::BoundingBox eclbb = eclGrid->boundingBox(); + return fembb.contains(eclbb.min()) && fembb.contains(eclbb.max()); + } + } + } + + return false; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimViewController::isRangeFiltersControlled() +{ + if (!isRangeFilterControlPossible()) return false; + + if (ownerViewLinker()->isActive() && this->m_isActive()) + { + return m_syncRangeFilters; + } + else + { + return false; + } +} +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimViewController::isPropertyFilterControlPossible() +{ + // The cases need to be the same + RimGeoMechView* geomView = dynamic_cast(masterView()); + + if (geomView) + { + RimGeoMechView* depGeomView = managedGeoView(); + if (depGeomView && geomView->geoMechCase() == depGeomView->geoMechCase()) + { + return true; + } + } + + RimEclipseView* eclipseView = dynamic_cast(masterView()); + + if (eclipseView) + { + RimEclipseView* depEclipseView = managedEclipseView(); + if (depEclipseView && eclipseView->eclipseCase() == depEclipseView->eclipseCase()) + { + return true; + } + } + + return false; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimViewController::isPropertyFilterOveridden() +{ + if (!isPropertyFilterControlPossible()) return false; + + if (ownerViewLinker()->isActive() && this->m_isActive()) + { + return m_syncPropertyFilters; + } + else + { + return false; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimViewController::updateRangeFilterOverrides(RimCellRangeFilter* changedRangeFilter) +{ + if (!isRangeFiltersControlled()) + { + managedView()->setOverrideRangeFilterCollection(NULL); + + return; + } + + // Todo: Optimize by only mapping the changed range filter, if needed. + + { + // Copy the rangeFilterCollection + + RimCellRangeFilterCollection* sourceFilterCollection = masterView()->rangeFilterCollection(); + QString xmlRangeFilterCollCopy = sourceFilterCollection->writeObjectToXmlString(); + PdmObjectHandle* objectCopy = PdmXmlObjectHandle::readUnknownObjectFromXmlString(xmlRangeFilterCollCopy, caf::PdmDefaultObjectFactory::instance()); + RimCellRangeFilterCollection* overrideRangeFilterColl = dynamic_cast(objectCopy); + + // Convert the range filter to fit in the managed view if needed + if (isRangeFilterMappingApliccable()) + { + RimEclipseView* eclipseMasterView = dynamic_cast(masterView()); + RimGeoMechView* geoMasterView = dynamic_cast(masterView()); + RimEclipseView* depEclView = managedEclipseView(); + RimGeoMechView* depGeomView = managedGeoView(); + + if (eclipseMasterView && depGeomView) + { + if (eclipseMasterView->eclipseCase()->reservoirData()) + { + RigMainGrid* srcEclGrid = eclipseMasterView->eclipseCase()->reservoirData()->mainGrid(); + RigFemPart* dstFemPart = depGeomView->geoMechCase()->geoMechData()->femParts()->part(0); + for (size_t rfIdx = 0; rfIdx < sourceFilterCollection->rangeFilters().size(); ++rfIdx) + { + RimCellRangeFilter* srcRFilter = sourceFilterCollection->rangeFilters[rfIdx]; + RimCellRangeFilter* dstRFilter = overrideRangeFilterColl->rangeFilters[rfIdx]; + RigCaseToCaseRangeFilterMapper::convertRangeFilterEclToFem(srcRFilter, srcEclGrid, + dstRFilter, dstFemPart); + } + } + } + else if (geoMasterView && depEclView) + { + if (depEclView->eclipseCase()->reservoirData()) + { + RigFemPart* srcFemPart = geoMasterView->geoMechCase()->geoMechData()->femParts()->part(0); + RigMainGrid* dstEclGrid = depEclView->eclipseCase()->reservoirData()->mainGrid(); + for (size_t rfIdx = 0; rfIdx < sourceFilterCollection->rangeFilters().size(); ++rfIdx) + { + RimCellRangeFilter* srcRFilter = sourceFilterCollection->rangeFilters[rfIdx]; + RimCellRangeFilter* dstRFilter = overrideRangeFilterColl->rangeFilters[rfIdx]; + RigCaseToCaseRangeFilterMapper::convertRangeFilterFemToEcl(srcRFilter, srcFemPart, + dstRFilter, dstEclGrid); + } + } + } + } + + managedView()->setOverrideRangeFilterCollection(overrideRangeFilterColl); + } + + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimViewController::applyRangeFilterCollectionByUserChoice() +{ + if (!m_managedView->overrideRangeFilterCollection()) + { + return; + } + + bool restoreOriginal = askUserToRestoreOriginalRangeFilterCollection(m_managedView->name); + if (restoreOriginal) + { + m_managedView->setOverrideRangeFilterCollection(NULL); + } + else + { + m_managedView->replaceRangeFilterCollectionWithOverride(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimViewController::askUserToRestoreOriginalRangeFilterCollection(const QString& viewName) +{ + RimView* activeView = RiaApplication::instance()->activeReservoirView(); + + QMessageBox msgBox(activeView->viewer()->layoutWidget()); + msgBox.setIcon(QMessageBox::Question); + + QString questionText; + questionText = QString("The range filters in the view \"%1\" are about to be unlinked.").arg(viewName); + + msgBox.setText(questionText); + msgBox.setInformativeText("Do you want to keep the range filters from the master view?"); + msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); + + int ret = msgBox.exec(); + if (ret == QMessageBox::Yes) + { + return false; + } + else + { + return true; + } +} + diff --git a/ApplicationCode/ProjectDataModel/RimViewController.h b/ApplicationCode/ProjectDataModel/RimViewController.h new file mode 100644 index 0000000000..1f30e228f0 --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimViewController.h @@ -0,0 +1,121 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafPdmField.h" +#include "cafPdmObject.h" +#include "cafPdmPtrField.h" + +#include "cvfBase.h" +#include "cvfObject.h" + +#include "RivCellSetEnum.h" + +class RimView; +class RimEclipseView; +class RimGeoMechView; +class RimViewLinker; +class RigCaseToCaseCellMapper; +class RimCellRangeFilter; + +//================================================================================================== +/// +/// +//================================================================================================== +class RimViewController : public caf::PdmObject +{ + CAF_PDM_HEADER_INIT; + +public: + RimViewController(void); + virtual ~RimViewController(void); + + bool isActive(); + + RimView* managedView(); + void setManagedView(RimView* view); + + RimView* masterView(); + RimViewLinker* ownerViewLinker(); + + const RigCaseToCaseCellMapper* cellMapper(); + + bool isCameraLinked(); + bool isTimeStepLinked(); + + bool isResultColorControlled(); + bool isRangeFiltersControlled(); + + bool isVisibleCellsOveridden(); + bool isPropertyFilterOveridden(); + + void scheduleCreateDisplayModelAndRedrawForDependentView(); + void scheduleGeometryRegenForDepViews(RivCellSetEnum geometryType); + void updateOverrides(); + void updateOptionSensitivity(); + void removeOverrides(); + void updateDisplayNameAndIcon(); + + void updateRangeFilterOverrides(RimCellRangeFilter* changedRangeFilter); + void applyRangeFilterCollectionByUserChoice(); + + +protected: // Pdm overridden methods + virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue); + virtual QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly); + virtual void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = ""); + virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering); + + virtual caf::PdmFieldHandle* userDescriptionField() { return &m_name; } + virtual caf::PdmFieldHandle* objectToggleField() { return &m_isActive; } + +private: + void updateCameraLink(); + void updateTimeStepLink(); + void updateResultColorsControl(); + + bool isMasterAndDepViewDifferentType(); + bool isRangeFilterControlPossible(); + bool isPropertyFilterControlPossible(); + bool isRangeFilterMappingApliccable(); + + RimEclipseView* managedEclipseView(); + RimGeoMechView* managedGeoView(); + static void removeOverrides(RimView* view); + + static bool askUserToRestoreOriginalRangeFilterCollection(const QString& viewName); +private: + caf::PdmField m_name; + caf::PdmPtrField m_managedView; + + caf::PdmField m_isActive; + caf::PdmField m_syncCamera; + caf::PdmField m_syncTimeStep; + + // Overridden properties + caf::PdmField m_syncCellResult; + + caf::PdmField m_syncRangeFilters; + caf::PdmField m_syncVisibleCells; + caf::PdmField m_syncPropertyFilters; + + QIcon m_originalIcon; + cvf::ref m_caseToCaseCellMapper; +}; diff --git a/ApplicationCode/ProjectDataModel/RimViewLinker.cpp b/ApplicationCode/ProjectDataModel/RimViewLinker.cpp new file mode 100644 index 0000000000..b8239c3944 --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimViewLinker.cpp @@ -0,0 +1,643 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RimViewLinker.h" + +#include "RiaApplication.h" + +#include "RigCaseData.h" + +#include "RimCase.h" + +#include "RimEclipseCellColors.h" +#include "RimEclipseInputCase.h" +#include "RimEclipseResultCase.h" +#include "RimEclipseResultDefinition.h" +#include "RimEclipseView.h" +#include "RimGeoMechCase.h" +#include "RimGeoMechCellColors.h" +#include "RimGeoMechResultDefinition.h" +#include "RimGeoMechView.h" +#include "RimViewController.h" +#include "RimProject.h" +#include "RimView.h" +#include "RimViewLinkerCollection.h" + +#include "RiuViewer.h" + +#include "cvfCamera.h" +#include "cvfScene.h" +#include "cafFrameAnimationControl.h" +#include "cvfMatrix4.h" +#include "cafPdmUiTreeOrdering.h" + + + +CAF_PDM_SOURCE_INIT(RimViewLinker, "ViewLinker"); +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimViewLinker::RimViewLinker(void) +{ + CAF_PDM_InitObject("Linked Views", "", "", ""); + + CAF_PDM_InitField(&m_name, "Name", QString("View Group Name"), "View Group Name", "", "", ""); + m_name.uiCapability()->setUiHidden(true); + + CAF_PDM_InitFieldNoDefault(&m_masterView, "MainView", "Main View", "", "", ""); + m_masterView.uiCapability()->setUiChildrenHidden(true); + m_masterView.uiCapability()->setUiHidden(true); + + CAF_PDM_InitFieldNoDefault(&m_viewControllers, "ManagedViews", "Managed Views", "", "", ""); + m_viewControllers.uiCapability()->setUiHidden(true); + m_viewControllers.uiCapability()->setUiChildrenHidden(true); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimViewLinker::~RimViewLinker(void) +{ + removeOverrides(); + + m_viewControllers.deleteAllChildObjects(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimViewLinker::updateTimeStep(RimView* sourceView, int timeStep) +{ + CVF_ASSERT(sourceView); + + if (!isActive()) return; + + if (masterView() != sourceView) + { + RimViewController* sourceViewLink = sourceView->viewController(); + CVF_ASSERT(sourceViewLink); + + if (!sourceViewLink->isTimeStepLinked()) + { + return; + } + } + + if (m_masterView && m_masterView->viewer() && sourceView != m_masterView) + { + m_masterView->viewer()->setCurrentFrame(timeStep); + m_masterView->viewer()->animationControl()->setCurrentFrameOnly(timeStep); + } + + for (size_t i = 0; i < m_viewControllers.size(); i++) + { + RimViewController* viewLink = m_viewControllers[i]; + + if (!viewLink->isTimeStepLinked()) continue; + + if ( viewLink->managedView() + && viewLink->managedView() != sourceView + && viewLink->managedView()->viewer()) + { + viewLink->managedView()->viewer()->setCurrentFrame(timeStep); + viewLink->managedView()->viewer()->animationControl()->setCurrentFrameOnly(timeStep); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimViewLinker::updateCellResult() +{ + RimView* rimView = m_masterView; + RimEclipseView* masterEclipseView = dynamic_cast(rimView); + if (masterEclipseView && masterEclipseView->cellResult()) + { + RimEclipseResultDefinition* eclipseCellResultDefinition = masterEclipseView->cellResult(); + + for (size_t i = 0; i < m_viewControllers.size(); i++) + { + RimViewController* viewLink = m_viewControllers[i]; + + if (viewLink->managedView()) + { + RimView* rimView = viewLink->managedView(); + RimEclipseView* eclipeView = dynamic_cast(rimView); + if (eclipeView) + { + if (viewLink->isResultColorControlled()) + { + eclipeView->cellResult()->setPorosityModel(eclipseCellResultDefinition->porosityModel()); + eclipeView->cellResult()->setResultType(eclipseCellResultDefinition->resultType()); + eclipeView->cellResult()->setResultVariable(eclipseCellResultDefinition->resultVariable()); + eclipeView->scheduleCreateDisplayModelAndRedraw(); + } + + eclipeView->cellResult()->updateIconState(); + } + } + } + } + + RimGeoMechView* masterGeoView = dynamic_cast(rimView); + if (masterGeoView && masterGeoView->cellResult()) + { + RimGeoMechResultDefinition* geoMechResultDefinition = masterGeoView->cellResult(); + + for (size_t i = 0; i < m_viewControllers.size(); i++) + { + RimViewController* viewLink = m_viewControllers[i]; + + if (viewLink->managedView()) + { + RimView* rimView = viewLink->managedView(); + RimGeoMechView* geoView = dynamic_cast(rimView); + if (geoView) + { + if (viewLink->isResultColorControlled()) + { + geoView->cellResult()->setResultAddress(geoMechResultDefinition->resultAddress()); + geoView->scheduleCreateDisplayModelAndRedraw(); + } + + geoView->cellResult()->updateIconState(); + } + } + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimViewLinker::updateRangeFilters(RimCellRangeFilter* changedRangeFilter) +{ + for (size_t i = 0; i < m_viewControllers.size(); i++) + { + RimViewController* viewLink = m_viewControllers[i]; + viewLink->updateRangeFilterOverrides(changedRangeFilter); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimViewLinker::updateOverrides() +{ + for (size_t i = 0; i < m_viewControllers.size(); i++) + { + RimViewController* viewLink = m_viewControllers[i]; + if (viewLink->isActive()) + { + viewLink->updateOverrides(); + } + else + { + viewLink->removeOverrides(); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimViewLinker::removeOverrides() +{ + for (size_t i = 0; i < m_viewControllers.size(); i++) + { + if (m_viewControllers[i]->managedView()) + { + m_viewControllers[i]->removeOverrides(); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimViewLinker::allViewsForCameraSync(RimView* source, std::vector& views) +{ + if (!isActive()) return; + + if (source != m_masterView()) + { + views.push_back(m_masterView()); + } + + for (size_t i = 0; i < m_viewControllers.size(); i++) + { + if (m_viewControllers[i]->managedView() && source != m_viewControllers[i]->managedView()) + { + if (m_viewControllers[i]->isCameraLinked()) + { + views.push_back(m_viewControllers[i]->managedView()); + } + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimViewLinker::updateDependentViews() +{ + updateOverrides(); + updateCellResult(); + updateScaleZ(m_masterView, m_masterView->scaleZ()); + updateCamera(m_masterView); + updateTimeStep(m_masterView, m_masterView->currentTimeStep()); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimViewLinker::displayNameForView(RimView* view) +{ + QString displayName = "None"; + + if (view) + { + RimCase* rimCase = NULL; + view->firstAnchestorOrThisOfType(rimCase); + + displayName = rimCase->caseUserDescription() + ": " + view->name; + } + + return displayName; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimViewLinker::setMasterView(RimView* view) +{ + RimViewController* previousViewController = view->viewController(); + + // Remove the view as dependent view + if (previousViewController) + { + delete previousViewController; + this->m_viewControllers.removeChildObject(NULL); + } + + this->removeOverrides(); + + m_masterView = view; + + updateUiNameAndIcon(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimView* RimViewLinker::masterView() +{ + return m_masterView; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimViewLinker::allViews(std::vector& views) +{ + views.push_back(m_masterView()); + + for (size_t i = 0; i < m_viewControllers.size(); i++) + { + if (m_viewControllers[i]->managedView()) + { + views.push_back(m_viewControllers[i]->managedView()); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimViewLinker::initAfterRead() +{ + updateUiNameAndIcon(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimViewLinker::updateScaleZ(RimView* sourceView, double scaleZ) +{ + if (!isActive()) return; + + if (masterView() != sourceView) + { + RimViewController* sourceViewLink = sourceView->viewController(); + CVF_ASSERT(sourceViewLink); + + if (!sourceViewLink->isCameraLinked()) + { + return; + } + } + + std::vector views; + allViewsForCameraSync(sourceView, views); + + // Make sure scale factors are identical + for (size_t i = 0; i < views.size(); i++) + { + views[i]->setScaleZAndUpdate(scaleZ); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimViewLinker::isActive() +{ + RimViewLinkerCollection* viewLinkerCollection = NULL; + this->firstAnchestorOrThisOfType(viewLinkerCollection); + + if (!viewLinkerCollection) + { + // This will happen when the all linked views are about to be deleted + // The viewLinker is taken out of the viewLinkerCollection, and no parent can be found + // See RicDeleteAllLinkedViewsFeature + return false; + } + + return viewLinkerCollection->isActive(); +} + +//-------------------------------------------------------------------------------------------------- +/// Hande icon update locally as PdmUiItem::updateUiIconFromState works only for static icons +//-------------------------------------------------------------------------------------------------- +void RimViewLinker::applyIconEnabledState(caf::PdmObject* obj, const QIcon& icon, bool disable) +{ + QPixmap icPixmap; + icPixmap = icon.pixmap(16, 16, QIcon::Normal); + + if (disable) + { + QIcon temp(icPixmap); + icPixmap = temp.pixmap(16, 16, QIcon::Disabled); + } + + QIcon newIcon(icPixmap); + obj->setUiIcon(newIcon); +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimViewLinker::updateUiNameAndIcon() +{ + RimViewLinker::findNameAndIconFromView(&m_name.v(), &m_originalIcon, m_masterView); + RimViewLinker::applyIconEnabledState(this, m_originalIcon, false); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimViewLinker::scheduleGeometryRegenForDepViews(RivCellSetEnum geometryType) +{ + for (size_t i = 0; i < m_viewControllers.size(); i++) + { + m_viewControllers[i]->scheduleGeometryRegenForDepViews(geometryType); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimViewLinker::scheduleCreateDisplayModelAndRedrawForDependentViews() +{ + for (size_t i = 0; i < m_viewControllers.size(); i++) + { + m_viewControllers[i]->scheduleCreateDisplayModelAndRedrawForDependentView(); + } +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimViewLinker::findNameAndIconFromView(QString* name, QIcon* icon, RimView* view) +{ + CVF_ASSERT(name && icon); + + *name = displayNameForView(view); + + if (view) + { + RimCase* rimCase = NULL; + view->firstAnchestorOrThisOfType(rimCase); + + if (dynamic_cast(rimCase)) + { + *icon = QIcon(":/GeoMechCase48x48.png"); + } + else if (dynamic_cast(rimCase)) + { + *icon = QIcon(":/Case48x48.png"); + } + else if (dynamic_cast(rimCase)) + { + *icon = QIcon(":/EclipseInput48x48.png"); + } + } + else + { + *icon = QIcon(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimViewLinker::updateCamera(RimView* sourceView) +{ + if (!sourceView->viewer()) return; + + if (!isActive()) return; + + RimViewController* viewLink = sourceView->viewController(); + if (viewLink) + { + if (!viewLink->isCameraLinked()) + { + return; + } + } + + std::vector viewsToUpdate; + allViewsForCameraSync(sourceView, viewsToUpdate); + + cvf::Vec3d sourceCamUp; + cvf::Vec3d sourceCamEye; + cvf::Vec3d sourceCamViewRefPoint; + sourceView->viewer()->mainCamera()->toLookAt(&sourceCamEye, &sourceCamViewRefPoint, &sourceCamUp); + + cvf::Vec3d sourceCamGlobalEye = sourceCamEye; + cvf::Vec3d sourceCamGlobalViewRefPoint = sourceCamViewRefPoint; + + // Source bounding box in global coordinates including scaleZ + cvf::BoundingBox sourceSceneBB = sourceView->viewer()->currentScene()->boundingBox(); + + RimEclipseView* eclipseView = dynamic_cast(sourceView); + if (eclipseView + && eclipseView->eclipseCase() + && eclipseView->eclipseCase()->reservoirData() + && eclipseView->eclipseCase()->reservoirData()->mainGrid()) + { + cvf::Vec3d offset = eclipseView->eclipseCase()->reservoirData()->mainGrid()->displayModelOffset(); + offset.z() *= eclipseView->scaleZ(); + + sourceCamGlobalEye += offset; + sourceCamGlobalViewRefPoint += offset; + + cvf::Mat4d trans; + trans.setTranslation(offset); + sourceSceneBB.transform(trans); + } + + // Propagate view matrix to all relevant views + + const cvf::Mat4d mat = sourceView->viewer()->mainCamera()->viewMatrix(); + for (size_t i = 0; i < viewsToUpdate.size(); i++) + { + if (viewsToUpdate[i] && viewsToUpdate[i]->viewer()) + { + RiuViewer* destinationViewer = viewsToUpdate[i]->viewer(); + + // Destination bounding box in global coordinates including scaleZ + cvf::BoundingBox destSceneBB = destinationViewer->currentScene()->boundingBox(); + + RimEclipseView* destEclipseView = dynamic_cast(viewsToUpdate[i]); + if (destEclipseView + && destEclipseView->eclipseCase() + && destEclipseView->eclipseCase()->reservoirData() + && destEclipseView->eclipseCase()->reservoirData()->mainGrid()) + { + cvf::Vec3d destOffset = destEclipseView->eclipseCase()->reservoirData()->mainGrid()->displayModelOffset(); + destOffset.z() *= destEclipseView->scaleZ(); + + cvf::Vec3d destinationCamEye = sourceCamGlobalEye - destOffset; + cvf::Vec3d destinationCamViewRefPoint = sourceCamGlobalViewRefPoint - destOffset; + + cvf::Mat4d trans; + trans.setTranslation(destOffset); + destSceneBB.transform(trans); + + if (isBoundingBoxesOverlappingOrClose(sourceSceneBB, destSceneBB)) + { + destinationViewer->mainCamera()->setFromLookAt(destinationCamEye, destinationCamViewRefPoint, sourceCamUp); + } + else + { + // Fallback using values from source camera + destinationViewer->mainCamera()->setFromLookAt(sourceCamEye, sourceCamViewRefPoint, sourceCamUp); + } + } + else + { + if (isBoundingBoxesOverlappingOrClose(sourceSceneBB, destSceneBB)) + { + destinationViewer->mainCamera()->setFromLookAt(sourceCamGlobalEye, sourceCamGlobalViewRefPoint, sourceCamUp); + } + else + { + // Fallback using values from source camera + destinationViewer->mainCamera()->setFromLookAt(sourceCamEye, sourceCamViewRefPoint, sourceCamUp); + } + } + + destinationViewer->update(); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimViewLinker::isBoundingBoxesOverlappingOrClose(const cvf::BoundingBox& sourceBB, const cvf::BoundingBox& destBB) +{ + if (!sourceBB.isValid() || !destBB.isValid()) return false; + + if (sourceBB.intersects(destBB)) return true; + + double largestExtent = sourceBB.extent().length(); + if (destBB.extent().length() > largestExtent) + { + largestExtent = destBB.extent().length(); + } + + double centerDist = (sourceBB.center() - destBB.center()).length(); + if (centerDist < largestExtent * 5) + { + return true; + } + + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimViewLinker::addDependentView(RimView* view) +{ + CVF_ASSERT(view && view != m_masterView); + + RimViewController* viewContr = new RimViewController; + this->m_viewControllers.push_back(viewContr); + + viewContr->setManagedView(view); + + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimViewLinker::addViewControllers(caf::PdmUiTreeOrdering& uiTreeOrdering) +{ + for (size_t j = 0; j < m_viewControllers.size(); j++) + { + uiTreeOrdering.add(m_viewControllers()[j]); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimViewLinker::applyRangeFilterCollectionByUserChoice() +{ + for (size_t j = 0; j < m_viewControllers.size(); j++) + { + m_viewControllers[j]->applyRangeFilterCollectionByUserChoice(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimViewLinker::removeViewController(RimViewController* viewController) +{ + m_viewControllers.removeChildObject(viewController); +} + diff --git a/ApplicationCode/ProjectDataModel/RimViewLinker.h b/ApplicationCode/ProjectDataModel/RimViewLinker.h new file mode 100644 index 0000000000..5ea734651d --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimViewLinker.h @@ -0,0 +1,103 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "RimDefines.h" + +#include "RivCellSetEnum.h" + +#include "cafPdmChildArrayField.h" +#include "cafPdmField.h" +#include "cafPdmObject.h" +#include "cafPdmPtrField.h" + +namespace cvf +{ + class BoundingBox; +} + +class RimViewController; +class RiuViewer; +class RimView; +class RimCellRangeFilter; + +//================================================================================================== +/// +/// +//================================================================================================== +class RimViewLinker : public caf::PdmObject +{ + CAF_PDM_HEADER_INIT; + +public: + RimViewLinker(void); + virtual ~RimViewLinker(void); + + bool isActive(); + + void setMasterView(RimView* view); + RimView* masterView(); + + void addDependentView(RimView* view); + void updateDependentViews(); + void removeViewController(RimViewController* viewController); + + void updateOverrides(); + + void updateCamera(RimView* sourceView); + void updateTimeStep(RimView* sourceView, int timeStep); + void updateScaleZ(RimView* sourceView, double scaleZ); + + void updateCellResult(); + void updateRangeFilters(RimCellRangeFilter* changedRangeFilter); + void applyRangeFilterCollectionByUserChoice(); + + void scheduleGeometryRegenForDepViews(RivCellSetEnum geometryType); + void scheduleCreateDisplayModelAndRedrawForDependentViews(); + + void allViews(std::vector& views); + + void updateUiNameAndIcon(); + + void addViewControllers(caf::PdmUiTreeOrdering& uiTreeOrdering); + + static void applyIconEnabledState(caf::PdmObject* obj, const QIcon& icon, bool disable); + static void findNameAndIconFromView(QString* name, QIcon* icon, RimView* view); + +public: + static QString displayNameForView(RimView* view); + +protected: + virtual caf::PdmFieldHandle* userDescriptionField() { return &m_name; } + virtual void initAfterRead(); + +private: + void allViewsForCameraSync(RimView* source, std::vector& views); + + void removeOverrides(); + + static bool isBoundingBoxesOverlappingOrClose(const cvf::BoundingBox& sourceBB, const cvf::BoundingBox& destBB); + +private: + caf::PdmChildArrayField m_viewControllers; + caf::PdmPtrField m_masterView; + caf::PdmField m_name; + QIcon m_originalIcon; +}; diff --git a/ApplicationCode/ProjectDataModel/RimViewLinkerCollection.cpp b/ApplicationCode/ProjectDataModel/RimViewLinkerCollection.cpp new file mode 100644 index 0000000000..ece9c7a518 --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimViewLinkerCollection.cpp @@ -0,0 +1,96 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RimViewLinkerCollection.h" + +#include "RimViewLinker.h" +#include "RimViewController.h" + +#include "cafPdmUiTreeOrdering.h" + + + + +CAF_PDM_SOURCE_INIT(RimViewLinkerCollection, "RimViewLinkerCollection"); +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimViewLinkerCollection::RimViewLinkerCollection(void) +{ + CAF_PDM_InitObject("Linked Views", ":/chain.png", "", ""); + + CAF_PDM_InitField(&isActive, "Active", true, "Active", "", "", ""); + isActive.uiCapability()->setUiHidden(true); + + CAF_PDM_InitFieldNoDefault(&viewLinker, "ViewLinkers", "View Linkers", "", "", ""); + viewLinker.uiCapability()->setUiHidden(true); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimViewLinkerCollection::~RimViewLinkerCollection(void) +{ + if (viewLinker()) delete viewLinker(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimViewLinkerCollection::defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName /*= ""*/) +{ + RimViewLinker* childObject = viewLinker(); + if (childObject) + { + uiTreeOrdering.add(childObject); + childObject->addViewControllers(uiTreeOrdering); + } + + uiTreeOrdering.setForgetRemainingFields(true); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimViewLinkerCollection::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) +{ + if (&isActive == changedField) + { + if (viewLinker()) + { + if (!isActive) + { + viewLinker()->applyRangeFilterCollectionByUserChoice(); + } + + viewLinker()->updateDependentViews(); + } + } + + this->updateUiIconFromToggleField(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimViewLinkerCollection::initAfterRead() +{ + this->updateUiIconFromToggleField(); +} + diff --git a/ApplicationCode/ProjectDataModel/RimViewLinkerCollection.h b/ApplicationCode/ProjectDataModel/RimViewLinkerCollection.h new file mode 100644 index 0000000000..ba60b140b3 --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimViewLinkerCollection.h @@ -0,0 +1,50 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "RimDefines.h" + +#include "cafPdmChildField.h" +#include "cafPdmField.h" +#include "cafPdmObject.h" + +class RimViewLinker; + +//================================================================================================== +/// +/// +//================================================================================================== +class RimViewLinkerCollection : public caf::PdmObject +{ + CAF_PDM_HEADER_INIT; + +public: + RimViewLinkerCollection(void); + virtual ~RimViewLinkerCollection(void); + + caf::PdmField isActive; + caf::PdmChildField viewLinker; + +protected: + virtual caf::PdmFieldHandle* objectToggleField() { return &isActive; } + virtual void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = ""); + virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue); + virtual void initAfterRead(); +}; diff --git a/ApplicationCode/ProjectDataModel/RimWellLogExtractionCurve.cpp b/ApplicationCode/ProjectDataModel/RimWellLogExtractionCurve.cpp new file mode 100644 index 0000000000..647da20dec --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimWellLogExtractionCurve.cpp @@ -0,0 +1,545 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RimWellLogExtractionCurve.h" + +#include "RiaApplication.h" + +#include "RigCaseCellResultsData.h" +#include "RigCaseData.h" +#include "RigEclipseWellLogExtractor.h" +#include "RigFemPartResultsCollection.h" +#include "RigGeoMechCaseData.h" +#include "RigGeoMechWellLogExtractor.h" +#include "RigResultAccessorFactory.h" + +#include "RimEclipseCase.h" +#include "RimEclipseResultDefinition.h" +#include "RimGeoMechCase.h" +#include "RimGeoMechResultDefinition.h" +#include "RimOilField.h" +#include "RimProject.h" +#include "RimWellLogPlot.h" +#include "RimWellLogPlotCollection.h" +#include "RimWellLogPlotCurve.h" +#include "RimWellLogPlotTrack.h" +#include "RimWellPath.h" +#include "RimWellPathCollection.h" +#include "RimEclipseView.h" +#include "RimEclipseCellColors.h" +#include "RimGeoMechView.h" +#include "RimGeoMechCellColors.h" + +#include "RiuWellLogPlotCurve.h" +#include "RiuWellLogTrackPlot.h" + +#include "cafPdmUiTreeOrdering.h" + +//================================================================================================== +/// +/// +//================================================================================================== + +CAF_PDM_SOURCE_INIT(RimWellLogExtractionCurve, "RimWellLogExtractionCurve"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimWellLogExtractionCurve::RimWellLogExtractionCurve() +{ + CAF_PDM_InitObject("Well Log Curve", "", "", ""); + + CAF_PDM_InitFieldNoDefault(&m_wellPath, "CurveWellPath", "Well Path", "", "", ""); + m_wellPath.uiCapability()->setUiChildrenHidden(true); + //m_wellPath.uiCapability()->setUiHidden(true); + + CAF_PDM_InitFieldNoDefault(&m_case, "CurveCase", "Case", "", "", ""); + m_case.uiCapability()->setUiChildrenHidden(true); + //m_case.uiCapability()->setUiHidden(true); + CAF_PDM_InitFieldNoDefault(&m_eclipseResultDefinition, "CurveEclipseResult", "", "", "", ""); + m_eclipseResultDefinition.uiCapability()->setUiHidden(true); + m_eclipseResultDefinition.uiCapability()->setUiChildrenHidden(true); + m_eclipseResultDefinition = new RimEclipseResultDefinition; + + CAF_PDM_InitFieldNoDefault(&m_geomResultDefinition, "CurveGeomechResult", "", "", "", ""); + m_geomResultDefinition.uiCapability()->setUiHidden(true); + m_geomResultDefinition.uiCapability()->setUiChildrenHidden(true); + m_geomResultDefinition = new RimGeoMechResultDefinition; + + CAF_PDM_InitField(&m_timeStep, "CurveTimeStep", 0,"Time Step", "", "", ""); + + // Add some space before name to indicate these belong to the Auto Name field + CAF_PDM_InitField(&m_addCaseNameToCurveName, "AddCaseNameToCurveName", true, " Case Name", "", "", ""); + CAF_PDM_InitField(&m_addPropertyToCurveName, "AddPropertyToCurveName", true, " Property", "", "", ""); + CAF_PDM_InitField(&m_addWellNameToCurveName, "AddWellNameToCurveName", true, " Well Name", "", "", ""); + CAF_PDM_InitField(&m_addTimestepToCurveName, "AddTimestepToCurveName", false, " Timestep", "", "", ""); + CAF_PDM_InitField(&m_addDateToCurveName, "AddDateToCurveName", true, " Date", "", "", ""); + + updateOptionSensitivity(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimWellLogExtractionCurve::~RimWellLogExtractionCurve() +{ + +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogExtractionCurve::setWellPath(RimWellPath* wellPath) +{ + m_wellPath = wellPath; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogExtractionCurve::setPropertiesFromView(RimView* view) +{ + m_case = view ? view->ownerCase() : NULL; + + RimGeoMechCase* geomCase = dynamic_cast(m_case.value()); + RimEclipseCase* eclipseCase = dynamic_cast(m_case.value()); + m_eclipseResultDefinition->setEclipseCase(eclipseCase); + m_geomResultDefinition->setGeoMechCase(geomCase); + + RimEclipseView* eclipseView = dynamic_cast(view); + if (eclipseView) + { + m_eclipseResultDefinition->setResultType(eclipseView->cellResult()->resultType()); + m_eclipseResultDefinition->setResultVariable(eclipseView->cellResult()->resultVariable()); + m_timeStep = eclipseView->currentTimeStep(); + } + + RimGeoMechView* geoMechView = dynamic_cast(view); + if (geoMechView) + { + m_geomResultDefinition->setResultAddress(geoMechView->cellResult()->resultAddress()); + m_timeStep = geoMechView->currentTimeStep(); + } +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogExtractionCurve::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) +{ + RimWellLogPlotCurve::fieldChangedByUi(changedField, oldValue, newValue); + + if (changedField == &m_case) + { + this->updatePlotData(); + } + else if (changedField == &m_wellPath) + { + this->updatePlotData(); + } + else if (changedField == &m_timeStep) + { + this->updatePlotData(); + } + + if (changedField == &m_addCaseNameToCurveName || + changedField == &m_addPropertyToCurveName || + changedField == &m_addWellNameToCurveName || + changedField == &m_addTimestepToCurveName || + changedField == &m_addDateToCurveName) + { + this->uiCapability()->updateConnectedEditors(); + updateCurveName(); + updatePlotTitle(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogExtractionCurve::updatePlotData() +{ + RimWellLogPlotCurve::updatePlotConfiguration(); + + if (isCurveVisible()) + { + // Make sure we have set correct case data into the result definitions. + + RimGeoMechCase* geomCase = dynamic_cast(m_case.value()); + RimEclipseCase* eclipseCase = dynamic_cast(m_case.value()); + m_eclipseResultDefinition->setEclipseCase(eclipseCase); + m_geomResultDefinition->setGeoMechCase(geomCase); + + RimWellLogPlotCollection* wellLogCollection = NULL; + this->firstAnchestorOrThisOfType(wellLogCollection); + CVF_ASSERT(wellLogCollection); + + cvf::ref eclExtractor = wellLogCollection->findOrCreateExtractor(m_wellPath, eclipseCase); + cvf::ref geomExtractor = wellLogCollection->findOrCreateExtractor(m_wellPath, geomCase); + + std::vector values; + std::vector measuredDepthValues; + std::vector tvDepthValues; + + if (eclExtractor.notNull()) + { + RimWellLogPlot* wellLogPlot; + firstAnchestorOrThisOfType(wellLogPlot); + CVF_ASSERT(wellLogPlot); + + measuredDepthValues = eclExtractor->measuredDepth(); + if (wellLogPlot->depthType() == RimWellLogPlot::TRUE_VERTICAL_DEPTH) + { + tvDepthValues = eclExtractor->trueVerticalDepth(); + } + + RifReaderInterface::PorosityModelResultType porosityModel = RigCaseCellResultsData::convertFromProjectModelPorosityModel(m_eclipseResultDefinition->porosityModel()); + m_eclipseResultDefinition->loadResult(); + + cvf::ref resAcc = RigResultAccessorFactory::createResultAccessor( + eclipseCase->reservoirData(), 0, + porosityModel, + m_timeStep, + m_eclipseResultDefinition->resultVariable()); + + if (resAcc.notNull()) + { + eclExtractor->curveData(resAcc.p(), &values); + } + } + else if (geomExtractor.notNull()) // geomExtractor + { + RimWellLogPlot* wellLogPlot; + firstAnchestorOrThisOfType(wellLogPlot); + CVF_ASSERT(wellLogPlot); + + measuredDepthValues = geomExtractor->measuredDepth(); + if (wellLogPlot->depthType() == RimWellLogPlot::TRUE_VERTICAL_DEPTH) + { + tvDepthValues = geomExtractor->trueVerticalDepth(); + } + + m_geomResultDefinition->loadResult(); + + geomExtractor->curveData(m_geomResultDefinition->resultAddress(), m_timeStep, &values); + } + + m_curveData = new RigWellLogCurveData; + if (values.size() && measuredDepthValues.size()) + { + if (!tvDepthValues.size()) + { + m_curveData->setValuesAndMD(values, measuredDepthValues, true); + } + else + { + m_curveData->setValuesWithTVD(values, measuredDepthValues, tvDepthValues); + } + } + + m_qwtPlotCurve->setCurveData(m_curveData.p()); + zoomAllOwnerTrackAndPlot(); + + if (m_ownerQwtTrack) m_ownerQwtTrack->replot(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QList RimWellLogExtractionCurve::calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly) +{ + QList optionList; + + if (fieldNeedingOptions == &m_wellPath) + { + RimProject* proj = RiaApplication::instance()->project(); + if (proj->activeOilField()->wellPathCollection()) + { + caf::PdmChildArrayField& wellPaths = proj->activeOilField()->wellPathCollection()->wellPaths; + + for (size_t i = 0; i< wellPaths.size(); i++) + { + optionList.push_back(caf::PdmOptionItemInfo(wellPaths[i]->name(), QVariant::fromValue(caf::PdmPointer(wellPaths[i])))); + } + + if (optionList.size() > 0) + { + optionList.push_front(caf::PdmOptionItemInfo("None", QVariant::fromValue(caf::PdmPointer(NULL)))); + } + } + } + else if (fieldNeedingOptions == &m_case) + { + RimProject* proj = RiaApplication::instance()->project(); + std::vector cases; + + proj->allCases(cases); + + for (size_t i = 0; i< cases.size(); i++) + { + optionList.push_back(caf::PdmOptionItemInfo(cases[i]->caseUserDescription(), QVariant::fromValue(caf::PdmPointer(cases[i])))); + } + + if (optionList.size() > 0) + { + optionList.push_front(caf::PdmOptionItemInfo("None", QVariant::fromValue(caf::PdmPointer(NULL)))); + } + } + else if (fieldNeedingOptions == &m_timeStep) + { + QStringList timeStepNames; + + if (m_case) + { + timeStepNames = m_case->timeStepStrings(); + } + + for (int i = 0; i < timeStepNames.size(); i++) + { + optionList.push_back(caf::PdmOptionItemInfo(timeStepNames[i], i)); + } + } + + return optionList; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogExtractionCurve::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) +{ + caf::PdmUiGroup* curveDataGroup = uiOrdering.addNewGroup("Curve Data"); + curveDataGroup->add(&m_wellPath); + + RimGeoMechCase* geomCase = dynamic_cast(m_case.value()); + RimEclipseCase* eclipseCase = dynamic_cast(m_case.value()); + + curveDataGroup->add(&m_wellPath); + + curveDataGroup->add(&m_case); + if (eclipseCase) + { + curveDataGroup->add(&(m_eclipseResultDefinition->m_resultTypeUiField)); + curveDataGroup->add(&(m_eclipseResultDefinition->m_porosityModelUiField)); + curveDataGroup->add(&(m_eclipseResultDefinition->m_resultVariableUiField)); + + if (m_eclipseResultDefinition->hasDynamicResult()) + { + curveDataGroup->add(&m_timeStep); + } + } + else if (geomCase) + { + curveDataGroup->add(&(m_geomResultDefinition->m_resultPositionTypeUiField)); + curveDataGroup->add(&(m_geomResultDefinition->m_resultVariableUiField)); + + curveDataGroup->add(&m_timeStep); + } + + caf::PdmUiGroup* appearanceGroup = uiOrdering.addNewGroup("Appearance"); + appearanceGroup->add(&m_curveColor); + appearanceGroup->add(&m_curveName); + appearanceGroup->add(&m_autoName); + if (m_autoName) + { + appearanceGroup->add(&m_addWellNameToCurveName); + appearanceGroup->add(&m_addCaseNameToCurveName); + appearanceGroup->add(&m_addPropertyToCurveName); + appearanceGroup->add(&m_addDateToCurveName); + appearanceGroup->add(&m_addTimestepToCurveName); + } + + + uiOrdering.setForgetRemainingFields(true); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogExtractionCurve::initAfterRead() +{ + RimWellLogPlotCurve::initAfterRead(); + + RimGeoMechCase* geomCase = dynamic_cast(m_case.value()); + RimEclipseCase* eclipseCase = dynamic_cast(m_case.value()); + + m_eclipseResultDefinition->setEclipseCase(eclipseCase); + m_geomResultDefinition->setGeoMechCase(geomCase); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogExtractionCurve::defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName /*= ""*/) +{ + uiTreeOrdering.setForgetRemainingFields(true); +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimWellLogExtractionCurve::createCurveName() +{ + RimGeoMechCase* geomCase = dynamic_cast(m_case.value()); + RimEclipseCase* eclipseCase = dynamic_cast(m_case.value()); + QString generatedCurveName; + + if (m_addWellNameToCurveName && m_wellPath) + { + generatedCurveName += wellName(); + } + + if (m_addCaseNameToCurveName && m_case()) + { + if (!generatedCurveName.isEmpty()) + { + generatedCurveName += ", "; + } + + generatedCurveName += m_case->caseUserDescription(); + } + + if (m_addPropertyToCurveName) + { + if (!generatedCurveName.isEmpty()) + { + generatedCurveName += ","; + } + + generatedCurveName += wellLogChannelName(); + } + + if (m_addTimestepToCurveName || m_addDateToCurveName) + { + size_t maxTimeStep = 0; + + if (eclipseCase) + { + RifReaderInterface::PorosityModelResultType porosityModel = RigCaseCellResultsData::convertFromProjectModelPorosityModel(m_eclipseResultDefinition->porosityModel()); + if (eclipseCase->reservoirData()) + { + maxTimeStep = eclipseCase->reservoirData()->results(porosityModel)->maxTimeStepCount(); + } + } + else if (geomCase) + { + if (geomCase->geoMechData()) + { + maxTimeStep = geomCase->geoMechData()->femPartResults()->frameCount(); + } + } + + if (m_addDateToCurveName) + { + QString dateString = wellDate(); + if (!dateString.isEmpty()) + { + if (!generatedCurveName.isEmpty()) + { + generatedCurveName += ", "; + } + + generatedCurveName += dateString; + } + } + + if (m_addTimestepToCurveName) + { + if (!generatedCurveName.isEmpty()) + { + generatedCurveName += ", "; + } + + generatedCurveName += QString("[%1/%2]").arg(m_timeStep()).arg(maxTimeStep); + } + } + + return generatedCurveName; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimWellLogExtractionCurve::wellLogChannelName() const +{ + RimGeoMechCase* geoMechCase = dynamic_cast(m_case.value()); + RimEclipseCase* eclipseCase = dynamic_cast(m_case.value()); + + QString name; + if (eclipseCase) + { + name = m_eclipseResultDefinition->resultVariable(); + } + else if (geoMechCase) + { + QString resCompName = m_geomResultDefinition->resultComponentUiName(); + if (resCompName.isEmpty()) + { + name = m_geomResultDefinition->resultFieldUiName(); + } + else + { + name = m_geomResultDefinition->resultFieldUiName() + "." + resCompName; + } + } + + return name; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimWellLogExtractionCurve::wellName() const +{ + return m_wellPath->name(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimWellLogExtractionCurve::wellDate() const +{ + RimGeoMechCase* geomCase = dynamic_cast(m_case.value()); + RimEclipseCase* eclipseCase = dynamic_cast(m_case.value()); + + QStringList timeStepNames; + + if (eclipseCase) + { + RifReaderInterface::PorosityModelResultType porosityModel = RigCaseCellResultsData::convertFromProjectModelPorosityModel(m_eclipseResultDefinition->porosityModel()); + if (eclipseCase->reservoirData()) + { + timeStepNames = eclipseCase->timeStepStrings(); + } + } + else if (geomCase) + { + if (geomCase->geoMechData()) + { + timeStepNames = geomCase->timeStepStrings(); + } + } + + return (m_timeStep < timeStepNames.size()) ? timeStepNames[m_timeStep] : ""; +} diff --git a/ApplicationCode/ProjectDataModel/RimWellLogExtractionCurve.h b/ApplicationCode/ProjectDataModel/RimWellLogExtractionCurve.h new file mode 100644 index 0000000000..ae9774523a --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimWellLogExtractionCurve.h @@ -0,0 +1,78 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "RimWellLogPlotCurve.h" + +#include "cafPdmPtrField.h" +#include "cafPdmChildField.h" + +class RimCase; +class RimEclipseResultDefinition; +class RimGeoMechResultDefinition; +class RimWellPath; +class RimView; + +//================================================================================================== +/// +/// +//================================================================================================== +class RimWellLogExtractionCurve : public RimWellLogPlotCurve +{ + CAF_PDM_HEADER_INIT; +public: + RimWellLogExtractionCurve(); + virtual ~RimWellLogExtractionCurve(); + + virtual void updatePlotData(); + + void setWellPath(RimWellPath* wellPath); + void setPropertiesFromView(RimView* view); + + virtual QString wellName() const; + virtual QString wellLogChannelName() const; + virtual QString wellDate() const; + +protected: + virtual QString createCurveName(); + + virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue); + virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering); + + virtual QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly); + + virtual void initAfterRead(); + + virtual void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = ""); + + caf::PdmPtrField m_wellPath; + caf::PdmPtrField m_case; + caf::PdmChildField m_eclipseResultDefinition; + caf::PdmChildField m_geomResultDefinition; + caf::PdmField m_timeStep; + + caf::PdmField m_addCaseNameToCurveName; + caf::PdmField m_addPropertyToCurveName; + caf::PdmField m_addWellNameToCurveName; + caf::PdmField m_addTimestepToCurveName; + caf::PdmField m_addDateToCurveName; +}; + + diff --git a/ApplicationCode/ProjectDataModel/RimWellLogFile.cpp b/ApplicationCode/ProjectDataModel/RimWellLogFile.cpp new file mode 100644 index 0000000000..4fc50b885a --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimWellLogFile.cpp @@ -0,0 +1,163 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RimWellLogFile.h" +#include "RimWellLogFileChannel.h" +#include "RimWellPath.h" +#include "RimWellPathCollection.h" + +#include "RigWellLogFile.h" + +#include "RiuMainWindow.h" + +#include +#include +#include + + +CAF_PDM_SOURCE_INIT(RimWellLogFile, "WellLogFile"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimWellLogFile::RimWellLogFile() +{ + CAF_PDM_InitObject("Well LAS File Info", ":/LasFile16x16.png", "", ""); + + CAF_PDM_InitFieldNoDefault(&m_wellName, "WellName", "", "", "", ""); + m_wellName.uiCapability()->setUiReadOnly(true); + m_wellName.uiCapability()->setUiHidden(true); + m_wellName.xmlCapability()->setIOWritable(false); + + CAF_PDM_InitFieldNoDefault(&m_fileName, "FileName", "Filename", "", "", ""); + m_fileName.uiCapability()->setUiReadOnly(true); + + CAF_PDM_InitFieldNoDefault(&m_name, "Name", "", "", "", ""); + m_name.uiCapability()->setUiReadOnly(true); + m_name.uiCapability()->setUiHidden(true); + m_name.xmlCapability()->setIOWritable(false); + + CAF_PDM_InitFieldNoDefault(&m_wellLogChannelNames, "WellLogFileChannels", "", "", "", ""); + m_wellLogChannelNames.uiCapability()->setUiHidden(true); + m_wellLogChannelNames.xmlCapability()->setIOWritable(false); + + m_wellLogDataFile = NULL; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimWellLogFile::~RimWellLogFile() +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimWellLogFile* RimWellLogFile::readWellLogFile(const QString& logFilePath) +{ + QFileInfo fi(logFilePath); + + RimWellLogFile* wellLogFile = NULL; + + if (fi.suffix().toUpper().compare("LAS") == 0) + { + QString errorMessage; + wellLogFile = new RimWellLogFile(); + wellLogFile->setFileName(logFilePath); + if (!wellLogFile->readFile(&errorMessage)) + { + QString displayMessage = "Could not open the LAS file: \n" + logFilePath; + + if (!errorMessage.isEmpty()) + { + displayMessage += "\n\n"; + displayMessage += errorMessage; + } + + QMessageBox::warning(RiuMainWindow::instance(), + "File open error", + displayMessage); + + delete wellLogFile; + wellLogFile = NULL; + } + } + + return wellLogFile; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogFile::setFileName(const QString& fileName) +{ + m_fileName = fileName; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimWellLogFile::readFile(QString* errorMessage) +{ + if (!m_wellLogDataFile.p()) + { + m_wellLogDataFile = new RigWellLogFile; + } + + m_name = QFileInfo(m_fileName).fileName(); + + if (!m_wellLogDataFile->open(m_fileName, errorMessage)) + { + m_wellLogDataFile = NULL; + return false; + } + + m_wellName = m_wellLogDataFile->wellName(); + + m_wellLogChannelNames.deleteAllChildObjects(); + + QStringList wellLogNames = m_wellLogDataFile->wellLogChannelNames(); + for (int logIdx = 0; logIdx < wellLogNames.size(); logIdx++) + { + RimWellLogFileChannel* wellLog = new RimWellLogFileChannel(); + wellLog->setName(wellLogNames[logIdx]); + m_wellLogChannelNames.push_back(wellLog); + } + + RimWellPath* wellPath; + firstAnchestorOrThisOfType(wellPath); + if (wellPath) + { + if (wellPath->filepath().isEmpty()) + { + wellPath->name = m_wellName; + } + } + + return true; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimWellLogFile::wellName() const +{ + return m_wellName; +} diff --git a/ApplicationCode/ProjectDataModel/RimWellLogFile.h b/ApplicationCode/ProjectDataModel/RimWellLogFile.h new file mode 100644 index 0000000000..6853965401 --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimWellLogFile.h @@ -0,0 +1,69 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafPdmObject.h" +#include "cafPdmField.h" +#include "cafPdmChildArrayField.h" + +#include "RigWellLogFile.h" + +#include "cvfBase.h" + +class RimWellLogFileChannel; + +class QString; + +//================================================================================================== +/// +/// +//================================================================================================== +class RimWellLogFile : public caf::PdmObject +{ + CAF_PDM_HEADER_INIT; + +public: + RimWellLogFile(); + virtual ~RimWellLogFile(); + + static RimWellLogFile* readWellLogFile(const QString& logFilePath); + + + void setFileName(const QString& fileName); + QString fileName() const { return m_fileName; } + + bool readFile(QString* errorMessage); + + QString wellName() const; + virtual caf::PdmFieldHandle* userDescriptionField() { return &m_name; } + + RigWellLogFile* wellLogFile() { return m_wellLogDataFile.p(); } + + const caf::PdmChildArrayField* wellLogChannelNames() const { return &m_wellLogChannelNames; } + +private: + caf::PdmChildArrayField m_wellLogChannelNames; + +private: + cvf::ref m_wellLogDataFile; + caf::PdmField m_wellName; + caf::PdmField m_fileName; + caf::PdmField m_name; +}; diff --git a/ApplicationCode/ProjectDataModel/RimWellLogFileChannel.cpp b/ApplicationCode/ProjectDataModel/RimWellLogFileChannel.cpp new file mode 100644 index 0000000000..5487603496 --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimWellLogFileChannel.cpp @@ -0,0 +1,45 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RimWellLogFileChannel.h" + +#include + + +CAF_PDM_SOURCE_INIT(RimWellLogFileChannel, "WellLogFileChannel"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimWellLogFileChannel::RimWellLogFileChannel() +{ + CAF_PDM_InitObject("Well Log File Channel", "", "", ""); + + CAF_PDM_InitFieldNoDefault(&m_name, "Name", "", "", "", ""); + m_name.uiCapability()->setUiHidden(true); + m_name.xmlCapability()->setIOWritable(false); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogFileChannel::setName(const QString& name) +{ + m_name = name; +} \ No newline at end of file diff --git a/ApplicationCode/ProjectDataModel/RimWellLogFileChannel.h b/ApplicationCode/ProjectDataModel/RimWellLogFileChannel.h new file mode 100644 index 0000000000..796c1a535f --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimWellLogFileChannel.h @@ -0,0 +1,46 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafPdmObject.h" +#include "cafPdmField.h" + +class QString; + +//================================================================================================== +/// +/// +//================================================================================================== +class RimWellLogFileChannel : public caf::PdmObject +{ + CAF_PDM_HEADER_INIT; + +public: + RimWellLogFileChannel(); + + void setName(const QString& name); + QString name() const { return m_name; } + + virtual caf::PdmFieldHandle* userDescriptionField() { return &m_name; } + +private: + caf::PdmField m_name; +}; + diff --git a/ApplicationCode/ProjectDataModel/RimWellLogFileCurve.cpp b/ApplicationCode/ProjectDataModel/RimWellLogFileCurve.cpp new file mode 100644 index 0000000000..b648aa9ba5 --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimWellLogFileCurve.cpp @@ -0,0 +1,282 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RimWellLogFileCurve.h" + +#include "RimProject.h" +#include "RimOilField.h" +#include "RimWellPathCollection.h" +#include "RimWellPath.h" +#include "RimWellLogFileChannel.h" +#include "RimWellLogFile.h" +#include "RimWellLogPlotTrack.h" +#include "RimWellLogPlot.h" + +#include "RiuWellLogTrackPlot.h" +#include "RiuWellLogPlotCurve.h" + +#include "RiaApplication.h" +#include "RiaPreferences.h" + +#include "cafPdmUiTreeOrdering.h" + +#include + + +CAF_PDM_SOURCE_INIT(RimWellLogFileCurve, "WellLogFileCurve"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimWellLogFileCurve::RimWellLogFileCurve() +{ + CAF_PDM_InitObject("Well Log File Curve", "", "", ""); + + CAF_PDM_InitFieldNoDefault(&m_wellPath, "CurveWellPath", "Well Path", "", "", ""); + m_wellPath.uiCapability()->setUiChildrenHidden(true); + + CAF_PDM_InitFieldNoDefault(&m_wellLogChannnelName, "CurveWellLogChannel", "Well Log Channel", "", "", ""); + + m_wellPath = NULL; + + updateOptionSensitivity(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimWellLogFileCurve::~RimWellLogFileCurve() +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogFileCurve::updatePlotData() +{ + RimWellLogPlotCurve::updatePlotConfiguration(); + + if (isCurveVisible()) + { + m_curveData = new RigWellLogCurveData; + + RimWellLogPlot* wellLogPlot; + firstAnchestorOrThisOfType(wellLogPlot); + CVF_ASSERT(wellLogPlot); + + if (wellLogPlot->depthType() == RimWellLogPlot::TRUE_VERTICAL_DEPTH) + { + if (RiaApplication::instance()->preferences()->showLasCurveWithoutTvdWarning()) + { + QString tmp = QString("Display of True Vertical Depth (TVD) for LAS curves in not yet supported, and no LAS curve will be displayed in this mode.\n\n"); + tmp += "Control display of this warning from \"Preferences->Show LAS curve without TVD warning\""; + + QMessageBox::warning(NULL, "LAS curve without TVD", tmp); + } + } + else if (m_wellPath) + { + RimWellLogFile* logFileInfo = m_wellPath->m_wellLogFile; + if (logFileInfo) + { + RigWellLogFile* wellLogFile = logFileInfo->wellLogFile(); + if (wellLogFile) + { + std::vector values = wellLogFile->values(m_wellLogChannnelName); + std::vector depthValues = wellLogFile->depthValues(); + + if (values.size() == depthValues.size()) + { + m_curveData->setValuesAndMD(values, depthValues, false); + } + } + + if (m_autoName) + { + m_qwtPlotCurve->setTitle(createCurveName()); + } + } + } + + m_qwtPlotCurve->setCurveData(m_curveData.p()); + + zoomAllOwnerTrackAndPlot(); + + if (m_ownerQwtTrack) m_ownerQwtTrack->replot(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogFileCurve::setWellPath(RimWellPath* wellPath) +{ + m_wellPath = wellPath; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogFileCurve::setWellLogChannelName(const QString& name) +{ + m_wellLogChannnelName = name; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogFileCurve::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) +{ + RimWellLogPlotCurve::fieldChangedByUi(changedField, oldValue, newValue); + + if (changedField == &m_wellPath) + { + this->updatePlotData(); + } + else if (changedField == &m_wellLogChannnelName) + { + this->updatePlotData(); + } + + if (m_ownerQwtTrack) m_ownerQwtTrack->replot(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogFileCurve::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) +{ + caf::PdmUiGroup* curveDataGroup = uiOrdering.addNewGroup("Curve Data"); + curveDataGroup->add(&m_wellPath); + curveDataGroup->add(&m_wellLogChannnelName); + + caf::PdmUiGroup* appearanceGroup = uiOrdering.addNewGroup("Appearance"); + appearanceGroup->add(&m_curveColor); + appearanceGroup->add(&m_curveName); + appearanceGroup->add(&m_autoName); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogFileCurve::defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName /*= ""*/) +{ + uiTreeOrdering.setForgetRemainingFields(true); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QList RimWellLogFileCurve::calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) +{ + QList optionList; + + if (fieldNeedingOptions == &m_wellPath) + { + RimProject* proj = RiaApplication::instance()->project(); + if (proj->activeOilField()->wellPathCollection()) + { + caf::PdmChildArrayField& wellPaths = proj->activeOilField()->wellPathCollection()->wellPaths; + + for (size_t i = 0; i < wellPaths.size(); i++) + { + if (wellPaths[i]->m_wellLogFile()) + { + optionList.push_back(caf::PdmOptionItemInfo(wellPaths[i]->name(), QVariant::fromValue(caf::PdmPointer(wellPaths[i])))); + } + } + + if (optionList.size() > 0) + { + optionList.push_front(caf::PdmOptionItemInfo("None", QVariant::fromValue(caf::PdmPointer(NULL)))); + } + } + } + + if (fieldNeedingOptions == &m_wellLogChannnelName) + { + if (m_wellPath()) + { + RimWellLogFile* wellLogFile = m_wellPath->m_wellLogFile(); + if (wellLogFile) + { + const caf::PdmChildArrayField* fileLogs = wellLogFile->wellLogChannelNames(); + + for (size_t i = 0; i < fileLogs->size(); i++) + { + QString wellLogChannelName = (*fileLogs)[i]->name(); + optionList.push_back(caf::PdmOptionItemInfo(wellLogChannelName, wellLogChannelName)); + } + } + } + + if (optionList.size() == 0) + { + optionList.push_back(caf::PdmOptionItemInfo("None", "None")); + } + } + + return optionList; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimWellLogFileCurve::createCurveName() +{ + if (m_wellPath) + { + QString txt; + + txt += wellName(); + txt += " : "; + txt += m_wellLogChannnelName; + + RimWellLogFile* logFileInfo = m_wellPath->m_wellLogFile; + RigWellLogFile* wellLogFile = logFileInfo ? logFileInfo->wellLogFile() : NULL; + if (wellLogFile) + { + QString unitName = wellLogFile->wellLogChannelUnit(m_wellLogChannnelName); + if (!unitName.isEmpty()) + { + txt += QString(" [%1]").arg(unitName); + } + } + + return txt; + } + + return "Empty curve"; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimWellLogFileCurve::wellLogChannelName() const +{ + return m_wellLogChannnelName; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimWellLogFileCurve::wellName() const +{ + return m_wellPath->name(); +} diff --git a/ApplicationCode/ProjectDataModel/RimWellLogFileCurve.h b/ApplicationCode/ProjectDataModel/RimWellLogFileCurve.h new file mode 100644 index 0000000000..9b493a8a40 --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimWellLogFileCurve.h @@ -0,0 +1,68 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "RimWellLogPlotCurve.h" + +#include "cafPdmPtrField.h" +#include "cafPdmField.h" + +#include + +class RimWellPath; +class RimWellLogFileChannel; + +//================================================================================================== +/// +/// +//================================================================================================== +class RimWellLogFileCurve : public RimWellLogPlotCurve +{ + CAF_PDM_HEADER_INIT; + +public: + RimWellLogFileCurve(); + virtual ~RimWellLogFileCurve(); + + void setWellPath(RimWellPath* wellPath); + void setWellLogChannelName(const QString& name); + + // Overrides from RimWellLogPlotCurve + virtual void updatePlotData(); + virtual QString wellName() const; + virtual QString wellLogChannelName() const; + +protected: + // Overrides from RimWellLogPlotCurve + virtual QString createCurveName(); + + // Pdm overrrides + virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue); + virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering); + virtual void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = ""); + virtual QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly); + +protected: + caf::PdmPtrField m_wellPath; + caf::PdmField m_wellLogChannnelName; + caf::PdmField m_wellLogChannnelUnit; +}; + + diff --git a/ApplicationCode/ProjectDataModel/RimWellLogPlot.cpp b/ApplicationCode/ProjectDataModel/RimWellLogPlot.cpp new file mode 100644 index 0000000000..cccff5c598 --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimWellLogPlot.cpp @@ -0,0 +1,541 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RimWellLogPlot.h" + +#include "RimWellLogPlotTrack.h" + +#include "RiuWellLogPlot.h" +#include "RiuWellLogTrackPlot.h" +#include "RiuMainWindow.h" + +#include "cafPdmUiTreeView.h" + +#include "cvfAssert.h" + +#include + +#define RI_LOGPLOT_MINDEPTH_DEFAULT 0.0 +#define RI_LOGPLOT_MAXDEPTH_DEFAULT 1000.0 + +namespace caf { + + template<> + void caf::AppEnum< RimWellLogPlot::DepthTypeEnum >::setUp() + { + addItem(RimWellLogPlot::MEASURED_DEPTH, "MEASURED_DEPTH", "Measured Depth"); + addItem(RimWellLogPlot::TRUE_VERTICAL_DEPTH, "TRUE_VERTICAL_DEPTH", "True Vertical Depth"); + setDefault(RimWellLogPlot::MEASURED_DEPTH); + } + +} // End namespace caf + + +CAF_PDM_SOURCE_INIT(RimWellLogPlot, "WellLogPlot"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimWellLogPlot::RimWellLogPlot() +{ + CAF_PDM_InitObject("Well Log Plot", ":/WellLogPlot16x16.png", "", ""); + + m_viewer = NULL; + + CAF_PDM_InitField(&m_showWindow, "ShowWindow", true, "Show well log plot", "", "", ""); + m_showWindow.uiCapability()->setUiHidden(true); + + CAF_PDM_InitField(&m_userName, "PlotDescription", QString("Well Log Plot"),"Name", "", "", ""); + + caf::AppEnum< RimWellLogPlot::DepthTypeEnum > depthType = MEASURED_DEPTH; + CAF_PDM_InitField(&m_depthType, "DepthType", depthType, "Depth type", "", "", ""); + + CAF_PDM_InitField(&m_minVisibleDepth, "MinimumDepth", 0.0, "Min", "", "", ""); + CAF_PDM_InitField(&m_maxVisibleDepth, "MaximumDepth", 1000.0, "Max", "", "", ""); + + CAF_PDM_InitFieldNoDefault(&m_tracks, "Tracks", "", "", "", ""); + m_tracks.uiCapability()->setUiHidden(true); + + CAF_PDM_InitFieldNoDefault(&windowGeometry, "WindowGeometry", "", "", "", ""); + windowGeometry.uiCapability()->setUiHidden(true); + + m_minAvailableDepth = HUGE_VAL; + m_maxAvailableDepth = -HUGE_VAL; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimWellLogPlot::~RimWellLogPlot() +{ + RiuMainWindow::instance()->removeViewer(m_viewer); + detachAllCurves(); + delete m_viewer; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogPlot::updateViewerWidget() +{ + if (m_showWindow()) + { + if (!m_viewer) + { + m_viewer = new RiuWellLogPlot(this, RiuMainWindow::instance()); + + recreateTrackPlots(); + + RiuMainWindow::instance()->addViewer(m_viewer, windowGeometry()); + RiuMainWindow::instance()->setActiveViewer(m_viewer); + } + + updateViewerWidgetWindowTitle(); + } + else + { + if (m_viewer) + { + windowGeometry = RiuMainWindow::instance()->windowGeometryForViewer(m_viewer); + + RiuMainWindow::instance()->removeViewer(m_viewer); + detachAllCurves(); + + delete m_viewer; + m_viewer = NULL; + + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogPlot::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) +{ + if (changedField == &m_showWindow) + { + if (m_showWindow) + { + loadDataAndUpdate(); + } + else + { + updateViewerWidget(); + } + + uiCapability()->updateUiIconFromToggleField(); + } + else if (changedField == &m_minVisibleDepth || changedField == &m_maxVisibleDepth) + { + updateDepthZoomInQwt(); + } + else if (changedField == &m_userName) + { + updateViewerWidgetWindowTitle(); + } + if (changedField == &m_depthType) + { + updateTracks(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +caf::PdmFieldHandle* RimWellLogPlot::objectToggleField() +{ + return &m_showWindow; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogPlot::addTrack(RimWellLogPlotTrack* track) +{ + m_tracks.push_back(track); + if (m_viewer) + { + track->recreateViewer(); + m_viewer->addTrackPlot(track->viewer()); + } + + updateTrackNames(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogPlot::insertTrack(RimWellLogPlotTrack* track, size_t index) +{ + m_tracks.insert(index, track); + + if (m_viewer) + { + track->recreateViewer(); + m_viewer->insertTrackPlot(track->viewer(), index); + } + + updateTrackNames(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogPlot::removeTrack(RimWellLogPlotTrack* track) +{ + if (track) + { + if (m_viewer) m_viewer->removeTrackPlot(track->viewer()); + m_tracks.removeChildObject(track); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogPlot::moveTracks(RimWellLogPlotTrack* insertAfterTrack, const std::vector& tracksToMove) +{ + for (size_t tIdx = 0; tIdx < tracksToMove.size(); tIdx++) + { + RimWellLogPlotTrack* track = tracksToMove[tIdx]; + + RimWellLogPlot* wellLogPlot; + track->firstAnchestorOrThisOfType(wellLogPlot); + if (wellLogPlot) + { + wellLogPlot->removeTrack(track); + wellLogPlot->updateTrackNames(); + wellLogPlot->updateConnectedEditors(); + } + } + + size_t index = m_tracks.index(insertAfterTrack) + 1; + + for (size_t tIdx = 0; tIdx < tracksToMove.size(); tIdx++) + { + insertTrack(tracksToMove[tIdx], index + tIdx); + } + + updateTrackNames(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RiuWellLogPlot* RimWellLogPlot::viewer() +{ + return m_viewer; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogPlot::setDepthZoomByFactorAndCenter(double zoomFactor, double zoomCenter) +{ + double newMinimum = zoomCenter - (zoomCenter - m_minVisibleDepth)*zoomFactor; + double newMaximum = zoomCenter + (m_maxVisibleDepth - zoomCenter)*zoomFactor; + + setDepthZoomMinMax(newMinimum, newMaximum); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogPlot::panDepth(double panFactor) +{ + double delta = panFactor*(m_maxVisibleDepth - m_minVisibleDepth); + setDepthZoomMinMax(m_minVisibleDepth + delta, m_maxVisibleDepth + delta); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogPlot::setDepthZoomMinMax(double minimumDepth, double maximumDepth) +{ + m_minVisibleDepth = minimumDepth; + m_maxVisibleDepth = maximumDepth; + + m_minVisibleDepth.uiCapability()->updateConnectedEditors(); + m_maxVisibleDepth.uiCapability()->updateConnectedEditors(); + + updateDepthZoomInQwt(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogPlot::calculateAvailableDepthRange() +{ + double minDepth = HUGE_VAL; + double maxDepth = -HUGE_VAL; + + for (size_t tIdx = 0; tIdx < m_tracks.size(); tIdx++) + { + double minTrackDepth = HUGE_VAL; + double maxTrackDepth = -HUGE_VAL; + + if (m_tracks[tIdx]->isVisible()) + { + m_tracks[tIdx]->availableDepthRange(&minTrackDepth, &maxTrackDepth); + + if (minTrackDepth < minDepth) + { + minDepth = minTrackDepth; + } + + if (maxTrackDepth > maxDepth) + { + maxDepth = maxTrackDepth; + } + } + } + + m_minAvailableDepth = minDepth; + m_maxAvailableDepth = maxDepth; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogPlot::availableDepthRange(double* minimumDepth, double* maximumDepth) const +{ + if (hasAvailableDepthRange()) + { + *minimumDepth = m_minAvailableDepth; + *maximumDepth = m_maxAvailableDepth; + } + else + { + *minimumDepth = RI_LOGPLOT_MINDEPTH_DEFAULT; + *maximumDepth = RI_LOGPLOT_MAXDEPTH_DEFAULT; + } +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimWellLogPlot::hasAvailableDepthRange() const +{ + return m_minAvailableDepth < HUGE_VAL && m_maxAvailableDepth > -HUGE_VAL; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogPlot::depthZoomMinMax(double* minimumDepth, double* maximumDepth) const +{ + *minimumDepth = m_minVisibleDepth; + *maximumDepth = m_maxVisibleDepth; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogPlot::setupBeforeSave() +{ + if (m_viewer) + { + windowGeometry = RiuMainWindow::instance()->windowGeometryForViewer(m_viewer); + } +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogPlot::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) +{ + uiOrdering.add(&m_userName); + uiOrdering.add(&m_depthType); + + caf::PdmUiGroup* gridGroup = uiOrdering.addNewGroup("Visible Depth Range"); + gridGroup->add(&m_minVisibleDepth); + gridGroup->add(&m_maxVisibleDepth); +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogPlot::loadDataAndUpdate() +{ + updateViewerWidget(); + updateTracks(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogPlot::updateTracks() +{ + if (m_showWindow) + { + for (size_t tIdx = 0; tIdx < m_tracks.size(); ++tIdx) + { + m_tracks[tIdx]->loadDataAndUpdate(); + } + + calculateAvailableDepthRange(); + updateDepthZoomInQwt(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogPlot::updateTrackNames() +{ + for (size_t tIdx = 0; tIdx < m_tracks.size(); tIdx++) + { + m_tracks[tIdx]->setDescription(QString("Track %1").arg(tIdx + 1)); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogPlot::updateDepthZoomInQwt() +{ + if (m_viewer) + { + double minDepth = m_minVisibleDepth < HUGE_VAL ? m_minVisibleDepth : RI_LOGPLOT_MINDEPTH_DEFAULT; + double maxDepth = m_maxVisibleDepth > -HUGE_VAL ? m_maxVisibleDepth : RI_LOGPLOT_MAXDEPTH_DEFAULT; + + m_viewer->setDepthZoomAndReplot(minDepth, maxDepth); + } +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogPlot::zoomAllDepth() +{ + if (hasAvailableDepthRange()) + { + setDepthZoomMinMax(m_minAvailableDepth, m_maxAvailableDepth); + } + else + { + setDepthZoomMinMax(RI_LOGPLOT_MINDEPTH_DEFAULT, RI_LOGPLOT_MAXDEPTH_DEFAULT); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogPlot::recreateTrackPlots() +{ + CVF_ASSERT(m_viewer); + + for (size_t tIdx = 0; tIdx < m_tracks.size(); ++tIdx) + { + m_tracks[tIdx]->recreateViewer(); + m_viewer->addTrackPlot(m_tracks[tIdx]->viewer()); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogPlot::detachAllCurves() +{ + for (size_t tIdx = 0; tIdx < m_tracks.size(); ++tIdx) + { + m_tracks[tIdx]->detachAllCurves(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogPlot::setDescription(const QString& description) +{ + m_userName = description; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogPlot::updateViewerWidgetWindowTitle() +{ + if (m_viewer) + { + m_viewer->setWindowTitle(m_userName); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogPlot::handleViewerDeletion() +{ + m_showWindow = false; + + if (m_viewer) + { + detachAllCurves(); + m_viewer = NULL; + } + + uiCapability()->updateUiIconFromToggleField(); + updateConnectedEditors(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimWellLogPlot::DepthTypeEnum RimWellLogPlot::depthType() const +{ + return m_depthType.value(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimWellLogPlot::depthPlotTitle() const +{ + QString depthTitle = "Depth"; + + switch (m_depthType.value()) + { + case MEASURED_DEPTH: + depthTitle = "MD"; + break; + + case TRUE_VERTICAL_DEPTH: + depthTitle = "TVD"; + break; + } + + depthTitle += " [m]"; + return depthTitle; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +size_t RimWellLogPlot::trackIndex(RimWellLogPlotTrack* track) +{ + return m_tracks.index(track); +} + diff --git a/ApplicationCode/ProjectDataModel/RimWellLogPlot.h b/ApplicationCode/ProjectDataModel/RimWellLogPlot.h new file mode 100644 index 0000000000..3f86ca434a --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimWellLogPlot.h @@ -0,0 +1,115 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafPdmObject.h" +#include "cafPdmField.h" +#include "cafPdmChildArrayField.h" +#include "cafAppEnum.h" + +#include + +class RiuWellLogPlot; +class RimWellLogPlotTrack; + + +//================================================================================================== +/// +/// +//================================================================================================== +class RimWellLogPlot : public caf::PdmObject +{ + CAF_PDM_HEADER_INIT; + +public: + enum DepthTypeEnum + { + MEASURED_DEPTH, + TRUE_VERTICAL_DEPTH + }; + +public: + RimWellLogPlot(); + virtual ~RimWellLogPlot(); + + void setDescription(const QString& description); + + DepthTypeEnum depthType() const; + QString depthPlotTitle() const; + + caf::PdmField< std::vector > windowGeometry; + + void addTrack(RimWellLogPlotTrack* track); + void insertTrack(RimWellLogPlotTrack* track, size_t index); + size_t trackCount() { return m_tracks.size();} + void removeTrack(RimWellLogPlotTrack* track); + size_t trackIndex(RimWellLogPlotTrack* track); + void moveTracks(RimWellLogPlotTrack* insertAfterTrack, const std::vector& tracksToMove); + + void loadDataAndUpdate(); + void updateTracks(); + void updateTrackNames(); + + RiuWellLogPlot* viewer(); + + void zoomAllDepth(); + void setDepthZoomByFactorAndCenter(double zoomFactor, double zoomCenter); + void panDepth(double panFactor); + void setDepthZoomMinMax(double minimumDepth, double maximumDepth); + void depthZoomMinMax(double* minimumDepth, double* maximumDepth) const; + + void calculateAvailableDepthRange(); + void availableDepthRange(double* minimumDepth, double* maximumDepth) const; + bool hasAvailableDepthRange() const; + +protected: + + // Overridden PDM methods + virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue); + virtual void setupBeforeSave(); + virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering); + virtual caf::PdmFieldHandle* objectToggleField(); + virtual caf::PdmFieldHandle* userDescriptionField() { return &m_userName; } + +private: + void updateViewerWidget(); + void updateViewerWidgetWindowTitle(); + void updateDepthZoomInQwt(); + void recreateTrackPlots(); + void detachAllCurves(); + void handleViewerDeletion(); + +private: + + caf::PdmField m_showWindow; + caf::PdmField m_userName; + caf::PdmField< caf::AppEnum< DepthTypeEnum > > m_depthType; + caf::PdmChildArrayField m_tracks; + + caf::PdmField m_minVisibleDepth; + caf::PdmField m_maxVisibleDepth; + + double m_minAvailableDepth; + double m_maxAvailableDepth; + + friend class RiuWellLogPlot; + QPointer m_viewer; + +}; diff --git a/ApplicationCode/ProjectDataModel/RimWellLogPlotCollection.cpp b/ApplicationCode/ProjectDataModel/RimWellLogPlotCollection.cpp new file mode 100644 index 0000000000..2b9d42d520 --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimWellLogPlotCollection.cpp @@ -0,0 +1,159 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RimWellLogPlotCollection.h" + +#include "RimWellLogPlot.h" + +#include "cafPdmUiTreeView.h" +#include "RigCaseData.h" +#include "RigGeoMechCaseData.h" +#include "RimWellPath.h" +#include "RimEclipseCase.h" +#include "RigEclipseWellLogExtractor.h" +#include "RimWellPathCollection.h" +#include "RimGeoMechCase.h" +#include "RigGeoMechWellLogExtractor.h" + +#include "cvfAssert.h" + +CAF_PDM_SOURCE_INIT(RimWellLogPlotCollection, "WellLogPlotCollection"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimWellLogPlotCollection::RimWellLogPlotCollection() +{ + CAF_PDM_InitObject("Well Log Plots", ":/WellLogPlots16x16.png", "", ""); + + CAF_PDM_InitFieldNoDefault(&wellLogPlots, "WellLogPlots", "", "", "", ""); + wellLogPlots.uiCapability()->setUiHidden(true); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimWellLogPlotCollection::~RimWellLogPlotCollection() +{ + wellLogPlots.deleteAllChildObjects(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigEclipseWellLogExtractor* RimWellLogPlotCollection::findOrCreateExtractor(RimWellPath* wellPath, RimEclipseCase* eclCase) +{ + if (!(wellPath && eclCase && wellPath->wellPathGeometry() && eclCase->reservoirData())) + { + return NULL; + } + + RigCaseData* eclCaseData = eclCase->reservoirData(); + RigWellPath* wellPathGeom = wellPath->wellPathGeometry(); + for (size_t exIdx = 0; exIdx < m_extractors.size(); ++exIdx) + { + if (m_extractors[exIdx]->caseData() == eclCaseData && m_extractors[exIdx]->wellPathData() == wellPathGeom) + { + return m_extractors[exIdx].p(); + } + } + + std::string errorIdName = (wellPath->name() + " " + eclCase->caseUserDescription()).toStdString(); + cvf::ref extractor = new RigEclipseWellLogExtractor(eclCaseData, wellPathGeom, errorIdName); + m_extractors.push_back(extractor.p()); + + return extractor.p(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigGeoMechWellLogExtractor* RimWellLogPlotCollection::findOrCreateExtractor(RimWellPath* wellPath, RimGeoMechCase* geomCase) +{ + if (!(wellPath && geomCase && wellPath->wellPathGeometry() && geomCase->geoMechData())) + { + return NULL; + } + + RigGeoMechCaseData* geomCaseData = geomCase->geoMechData(); + RigWellPath* wellPathGeom = wellPath->wellPathGeometry(); + for (size_t exIdx = 0; exIdx < m_geomExtractors.size(); ++exIdx) + { + if (m_geomExtractors[exIdx]->caseData() == geomCaseData && m_geomExtractors[exIdx]->wellPathData() == wellPathGeom) + { + return m_geomExtractors[exIdx].p(); + } + } + + std::string errorIdName = (wellPath->name() + " " + geomCase->caseUserDescription()).toStdString(); + cvf::ref extractor = new RigGeoMechWellLogExtractor(geomCaseData, wellPathGeom, errorIdName); + m_geomExtractors.push_back(extractor.p()); + + return extractor.p(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogPlotCollection::removeExtractors(const RigWellPath* wellPath) +{ + for (int eIdx = (int) m_extractors.size() - 1; eIdx >= 0; eIdx--) + { + if (m_extractors[eIdx]->wellPathData() == wellPath) + { + m_extractors.eraseAt(eIdx); + } + } + + for (int eIdx = (int) m_geomExtractors.size() - 1; eIdx >= 0; eIdx--) + { + if (m_geomExtractors[eIdx]->wellPathData() == wellPath) + { + m_geomExtractors.eraseAt(eIdx); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogPlotCollection::removeExtractors(const RigCaseData* caseData) +{ + for (int eIdx = (int) m_extractors.size() - 1; eIdx >= 0; eIdx--) + { + if (m_extractors[eIdx]->caseData() == caseData) + { + m_extractors.eraseAt(eIdx); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogPlotCollection::removeExtractors(const RigGeoMechCaseData* caseData) +{ + for (int eIdx = (int) m_geomExtractors.size() - 1; eIdx >= 0; eIdx--) + { + if (m_geomExtractors[eIdx]->caseData() == caseData) + { + m_geomExtractors.eraseAt(eIdx); + } + } +} diff --git a/ApplicationCode/ProjectDataModel/RimWellLogPlotCollection.h b/ApplicationCode/ProjectDataModel/RimWellLogPlotCollection.h new file mode 100644 index 0000000000..dbd475c392 --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimWellLogPlotCollection.h @@ -0,0 +1,60 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafPdmObject.h" +#include "cafPdmField.h" +#include "cafPdmChildArrayField.h" +#include "cvfCollection.h" + +class RimWellLogPlot; +class RigEclipseWellLogExtractor; +class RigGeoMechWellLogExtractor; +class RimGeoMechCase; +class RigCaseData; +class RigGeoMechCaseData; +class RigWellPath; +class RimWellPath; +class RimEclipseCase; +class RiuWellLogPlot; + +//================================================================================================== +/// +/// +//================================================================================================== +class RimWellLogPlotCollection : public caf::PdmObject +{ + CAF_PDM_HEADER_INIT; +public: + RimWellLogPlotCollection(); + virtual ~RimWellLogPlotCollection(); + + RigEclipseWellLogExtractor* findOrCreateExtractor(RimWellPath* wellPath, RimEclipseCase* eclCase); + RigGeoMechWellLogExtractor* findOrCreateExtractor(RimWellPath* wellPath, RimGeoMechCase* eclCase); + + void removeExtractors(const RigWellPath* wellPath); + void removeExtractors(const RigCaseData* caseData); + void removeExtractors(const RigGeoMechCaseData* caseData); + + caf::PdmChildArrayField wellLogPlots; +private: + cvf::Collection m_extractors; + cvf::Collection m_geomExtractors; +}; diff --git a/ApplicationCode/ProjectDataModel/RimWellLogPlotCurve.cpp b/ApplicationCode/ProjectDataModel/RimWellLogPlotCurve.cpp new file mode 100644 index 0000000000..04c0895339 --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimWellLogPlotCurve.cpp @@ -0,0 +1,314 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RimWellLogPlotCurve.h" + +#include "RimWellLogPlot.h" + +#include "RimWellLogPlotTrack.h" + +#include "RiuWellLogPlotCurve.h" +#include "RiuWellLogTrackPlot.h" + +#include "cvfAssert.h" + +// NB! Special macro for pure virtual class +CAF_PDM_XML_ABSTRACT_SOURCE_INIT(RimWellLogPlotCurve, "WellLogPlotCurve"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimWellLogPlotCurve::RimWellLogPlotCurve() +{ + CAF_PDM_InitObject("Curve", ":/WellLogCurve16x16.png", "", ""); + + CAF_PDM_InitField(&m_showCurve, "Show", true, "Show curve", "", "", ""); + m_showCurve.uiCapability()->setUiHidden(true); + + CAF_PDM_InitFieldNoDefault(&m_curveName, "CurveName", "Curve Name", "", "", ""); + CAF_PDM_InitFieldNoDefault(&m_customCurveName, "CurveDescription", "Custom Name", "", "", ""); + m_customCurveName.uiCapability()->setUiHidden(true); + + CAF_PDM_InitField(&m_autoName, "AutoName", true, "Auto Name", "", "", ""); + + CAF_PDM_InitField(&m_curveColor, "Color", cvf::Color3f(cvf::Color3::BLACK), "Color", "", "", ""); + + m_qwtPlotCurve = new RiuWellLogPlotCurve; + m_qwtPlotCurve->setXAxis(QwtPlot::xTop); + m_qwtPlotCurve->setYAxis(QwtPlot::yLeft); + + m_ownerQwtTrack = NULL; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimWellLogPlotCurve::~RimWellLogPlotCurve() +{ + m_qwtPlotCurve->detach(); + delete m_qwtPlotCurve; + + if (m_ownerQwtTrack) + { + m_ownerQwtTrack->replot(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogPlotCurve::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) +{ + if (changedField == &m_showCurve) + { + this->updateCurveVisibility(); + } + else if (changedField == &m_curveName) + { + m_customCurveName = m_curveName; + updatePlotTitle(); + } + else if (&m_curveColor == changedField) + { + m_qwtPlotCurve->setPen(QPen(QColor(m_curveColor.value().rByte(), m_curveColor.value().gByte(), m_curveColor.value().bByte()))); + } + else if (changedField == &m_autoName) + { + if (!m_autoName) + { + m_customCurveName = createCurveName(); + } + + updateOptionSensitivity(); + updateCurveName(); + updatePlotTitle(); + } + + if (m_ownerQwtTrack) m_ownerQwtTrack->replot(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +caf::PdmFieldHandle* RimWellLogPlotCurve::objectToggleField() +{ + return &m_showCurve; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogPlotCurve::updateCurveVisibility() +{ + if (m_showCurve() && m_ownerQwtTrack) + { + m_qwtPlotCurve->attach(m_ownerQwtTrack); + } + else + { + m_qwtPlotCurve->detach(); + } + + RimWellLogPlot* wellLogPlot; + this->firstAnchestorOrThisOfType(wellLogPlot); + if (wellLogPlot) + { + wellLogPlot->calculateAvailableDepthRange(); + } + + RimWellLogPlotTrack* wellLogPlotTrack; + this->firstAnchestorOrThisOfType(wellLogPlotTrack); + if (wellLogPlotTrack) + { + wellLogPlotTrack->zoomAllXAndZoomAllDepthOnOwnerPlot(); + } + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogPlotCurve::updatePlotConfiguration() +{ + this->updateCurveVisibility(); + this->updateCurveName(); + this->updatePlotTitle(); + + m_qwtPlotCurve->setPen(QPen(QColor(m_curveColor.value().rByte(), m_curveColor.value().gByte(), m_curveColor.value().bByte()))); + // Todo: Rest of the curve setup controlled from this class +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogPlotCurve::setQwtTrack(RiuWellLogTrackPlot* plot) +{ + m_ownerQwtTrack = plot; + if (m_showCurve) + { + m_qwtPlotCurve->attach(m_ownerQwtTrack); + m_ownerQwtTrack->replot(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +caf::PdmFieldHandle* RimWellLogPlotCurve::userDescriptionField() +{ + return &m_curveName; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimWellLogPlotCurve::depthRange(double* minimumDepth, double* maximumDepth) const +{ + CVF_ASSERT(minimumDepth && maximumDepth); + CVF_ASSERT(m_qwtPlotCurve); + + if (m_qwtPlotCurve->data()->size() < 1) + { + return false; + } + + *minimumDepth = m_qwtPlotCurve->minYValue(); + *maximumDepth = m_qwtPlotCurve->maxYValue(); + + return true; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimWellLogPlotCurve::valueRange(double* minimumValue, double* maximumValue) const +{ + CVF_ASSERT(minimumValue && maximumValue); + CVF_ASSERT(m_qwtPlotCurve); + + if (m_qwtPlotCurve->data()->size() < 1) + { + return false; + } + + *minimumValue = m_qwtPlotCurve->minXValue(); + *maximumValue = m_qwtPlotCurve->maxXValue(); + + return true; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogPlotCurve::setColor(const cvf::Color3f& color) +{ + m_curveColor = color; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogPlotCurve::detachQwtCurve() +{ + m_qwtPlotCurve->detach(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QwtPlotCurve* RimWellLogPlotCurve::plotCurve() const +{ + return m_qwtPlotCurve; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogPlotCurve::updatePlotTitle() +{ + m_qwtPlotCurve->setTitle(m_curveName); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimWellLogPlotCurve::isCurveVisible() const +{ + return m_showCurve; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogPlotCurve::initAfterRead() +{ + updateOptionSensitivity(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogPlotCurve::zoomAllOwnerTrackAndPlot() +{ + RimWellLogPlot* wellLogPlot; + firstAnchestorOrThisOfType(wellLogPlot); + if (wellLogPlot) + { + wellLogPlot->calculateAvailableDepthRange(); + wellLogPlot->zoomAllDepth(); + } + + RimWellLogPlotTrack* plotTrack; + firstAnchestorOrThisOfType(plotTrack); + if (plotTrack) + { + plotTrack->zoomAllXAndZoomAllDepthOnOwnerPlot(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogPlotCurve::updateCurveName() +{ + if (m_autoName) + { + m_curveName = this->createCurveName(); + } + else + { + m_curveName = m_customCurveName; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogPlotCurve::updateOptionSensitivity() +{ + m_curveName.uiCapability()->setUiReadOnly(m_autoName); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const RigWellLogCurveData* RimWellLogPlotCurve::curveData() const +{ + return m_curveData.p(); +} diff --git a/ApplicationCode/ProjectDataModel/RimWellLogPlotCurve.h b/ApplicationCode/ProjectDataModel/RimWellLogPlotCurve.h new file mode 100644 index 0000000000..3ecccc9ba6 --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimWellLogPlotCurve.h @@ -0,0 +1,94 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafPdmField.h" +#include "cafPdmFieldCvfColor.h" +#include "cafPdmObject.h" + +#include "RigWellLogCurveData.h" +#include +#include + +class RigWellLogCurveData; +class RiuWellLogTrackPlot; +class RiuWellLogPlotCurve; +class QwtPlotCurve; +class QString; + +//================================================================================================== +/// +/// +//================================================================================================== +class RimWellLogPlotCurve : public caf::PdmObject +{ + CAF_PDM_HEADER_INIT; +public: + RimWellLogPlotCurve(); + virtual ~RimWellLogPlotCurve(); + + void setColor(const cvf::Color3f& color); + + bool depthRange(double* minimumDepth, double* maximumDepth) const; + bool valueRange(double* minimumValue, double* maximumValue) const; + + void setQwtTrack(RiuWellLogTrackPlot* plot); + void detachQwtCurve(); + + bool isCurveVisible() const; + + QwtPlotCurve* plotCurve() const; + const RigWellLogCurveData* curveData() const; + + QString name() const { return m_curveName; } + void updateCurveName(); + void updatePlotTitle(); + + virtual QString wellName() const = 0; + virtual QString wellLogChannelName() const = 0; + virtual QString wellDate() const { return ""; }; + virtual void updatePlotData() = 0; + +protected: + virtual QString createCurveName() = 0; + + void updatePlotConfiguration(); + void updateCurveVisibility(); + void zoomAllOwnerTrackAndPlot(); + void updateOptionSensitivity(); + + // Overridden PDM methods + virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue); + virtual caf::PdmFieldHandle* objectToggleField(); + virtual caf::PdmFieldHandle* userDescriptionField(); + virtual void initAfterRead(); + + + QPointer m_ownerQwtTrack; + RiuWellLogPlotCurve* m_qwtPlotCurve; + cvf::ref m_curveData; + + caf::PdmField m_showCurve; + caf::PdmField m_curveName; + caf::PdmField m_customCurveName; + + caf::PdmField m_autoName; + caf::PdmField m_curveColor; +}; diff --git a/ApplicationCode/ProjectDataModel/RimWellLogPlotTrack.cpp b/ApplicationCode/ProjectDataModel/RimWellLogPlotTrack.cpp new file mode 100644 index 0000000000..d7b21d941f --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimWellLogPlotTrack.cpp @@ -0,0 +1,375 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RimWellLogPlotTrack.h" + +#include "RimWellLogPlot.h" +#include "RimWellLogPlotCurve.h" + +#include "RiuWellLogTrackPlot.h" +#include "RiuWellLogPlot.h" +#include "RiuMainWindow.h" + +#include "cafPdmUiTreeView.h" +#include "cvfAssert.h" + +#include + +#define RI_LOGPLOTTRACK_MINX_DEFAULT -10.0 +#define RI_LOGPLOTTRACK_MAXX_DEFAULT 100.0 + + +CAF_PDM_SOURCE_INIT(RimWellLogPlotTrack, "WellLogPlotTrack"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimWellLogPlotTrack::RimWellLogPlotTrack() +{ + CAF_PDM_InitObject("Track", ":/WellLogTrack16x16.png", "", ""); + + CAF_PDM_InitFieldNoDefault(&m_userName, "TrackDescription", "Name", "", "", ""); + m_userName.uiCapability()->setUiReadOnly(true); + + CAF_PDM_InitField(&m_show, "Show", true, "Show track", "", "", ""); + m_show.uiCapability()->setUiHidden(true); + + CAF_PDM_InitFieldNoDefault(&curves, "Curves", "", "", "", ""); + curves.uiCapability()->setUiHidden(true); + + CAF_PDM_InitField(&m_visibleXRangeMin, "VisibleXRangeMin", RI_LOGPLOTTRACK_MINX_DEFAULT, "Min", "", "", ""); + CAF_PDM_InitField(&m_visibleXRangeMax, "VisibleXRangeMax", RI_LOGPLOTTRACK_MAXX_DEFAULT, "Max", "", "", ""); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimWellLogPlotTrack::~RimWellLogPlotTrack() +{ + delete m_wellLogTrackPlotWidget; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogPlotTrack::setDescription(const QString& description) +{ + m_userName = description; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogPlotTrack::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) +{ + if (changedField == &m_show) + { + if (m_wellLogTrackPlotWidget) + { + m_wellLogTrackPlotWidget->setVisible(m_show()); + } + + RimWellLogPlot* wellLogPlot; + this->firstAnchestorOrThisOfType(wellLogPlot); + if (wellLogPlot) + { + wellLogPlot->calculateAvailableDepthRange(); + wellLogPlot->zoomAllDepth(); + if (wellLogPlot->viewer()) wellLogPlot->viewer()->updateChildrenLayout(); + } + } + else if (changedField == &m_visibleXRangeMin || changedField == &m_visibleXRangeMax) + { + m_wellLogTrackPlotWidget->setXRange(m_visibleXRangeMin, m_visibleXRangeMax); + m_wellLogTrackPlotWidget->replot(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +caf::PdmFieldHandle* RimWellLogPlotTrack::objectToggleField() +{ + return &m_show; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +caf::PdmFieldHandle* RimWellLogPlotTrack::userDescriptionField() +{ + return &m_userName; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogPlotTrack::addCurve(RimWellLogPlotCurve* curve) +{ + curves.push_back(curve); + + if (m_wellLogTrackPlotWidget) + { + curve->setQwtTrack(m_wellLogTrackPlotWidget); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogPlotTrack::insertCurve(RimWellLogPlotCurve* curve, size_t index) +{ + curves.insert(index, curve); + // Todo: Mark curve data to use either TVD or MD + + if (m_wellLogTrackPlotWidget) + { + curve->setQwtTrack(m_wellLogTrackPlotWidget); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogPlotTrack::removeCurve(RimWellLogPlotCurve* curve) +{ + size_t index = curves.index(curve); + if ( index < curves.size()) + { + curves[index]->detachQwtCurve(); + curves.removeChildObject(curve); + } +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RiuWellLogTrackPlot* RimWellLogPlotTrack::viewer() +{ + return m_wellLogTrackPlotWidget; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogPlotTrack::availableDepthRange(double* minimumDepth, double* maximumDepth) +{ + double minDepth = HUGE_VAL; + double maxDepth = -HUGE_VAL; + + size_t curveCount = curves.size(); + + for (size_t cIdx = 0; cIdx < curveCount; cIdx++) + { + double minCurveDepth = HUGE_VAL; + double maxCurveDepth = -HUGE_VAL; + + if (curves[cIdx]->isCurveVisible() && curves[cIdx]->depthRange(&minCurveDepth, &maxCurveDepth)) + { + if (minCurveDepth < minDepth) + { + minDepth = minCurveDepth; + } + + if (maxCurveDepth > maxDepth) + { + maxDepth = maxCurveDepth; + } + } + } + + *minimumDepth = minDepth; + *maximumDepth = maxDepth; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogPlotTrack::loadDataAndUpdate() +{ + CVF_ASSERT(m_wellLogTrackPlotWidget); + + RimWellLogPlot* wellLogPlot; + firstAnchestorOrThisOfType(wellLogPlot); + if (wellLogPlot) + { + m_wellLogTrackPlotWidget->setDepthTitle(wellLogPlot->depthPlotTitle()); + } + + for (size_t cIdx = 0; cIdx < curves.size(); ++cIdx) + { + curves[cIdx]->updatePlotData(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogPlotTrack::recreateViewer() +{ + if (m_wellLogTrackPlotWidget == NULL) + { + m_wellLogTrackPlotWidget = new RiuWellLogTrackPlot(this); + + for (size_t cIdx = 0; cIdx < curves.size(); ++cIdx) + { + curves[cIdx]->setQwtTrack(this->m_wellLogTrackPlotWidget); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogPlotTrack::detachAllCurves() +{ + for (size_t cIdx = 0; cIdx < curves.size(); ++cIdx) + { + curves[cIdx]->detachQwtCurve(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogPlotTrack::zoomAllXAndZoomAllDepthOnOwnerPlot() +{ + if (m_wellLogTrackPlotWidget) + { + RimWellLogPlot* wellLogPlot; + firstAnchestorOrThisOfType(wellLogPlot); + if (wellLogPlot) + { + wellLogPlot->zoomAllDepth(); + } + + zoomAllXAxis(); + + m_wellLogTrackPlotWidget->replot(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogPlotTrack::alignDepthZoomToPlotAndZoomAllX() +{ + if (m_wellLogTrackPlotWidget) + { + RimWellLogPlot* wellLogPlot; + firstAnchestorOrThisOfType(wellLogPlot); + if (wellLogPlot) + { + double minimumDepth, maximumDepth; + wellLogPlot->depthZoomMinMax(&minimumDepth, &maximumDepth); + + m_wellLogTrackPlotWidget->setDepthZoom(minimumDepth, maximumDepth); + } + + zoomAllXAxis(); + + m_wellLogTrackPlotWidget->replot(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogPlotTrack::zoomAllXAxis() +{ + double minValue = HUGE_VAL; + double maxValue = -HUGE_VAL; + + for (size_t cIdx = 0; cIdx < curves.size(); cIdx++) + { + double minCurveValue = HUGE_VAL; + double maxCurveValue = -HUGE_VAL; + + if (curves[cIdx]->isCurveVisible() && curves[cIdx]->valueRange(&minCurveValue, &maxCurveValue)) + { + if (minCurveValue < minValue) + { + minValue = minCurveValue; + } + + if (maxCurveValue > maxValue) + { + maxValue = maxCurveValue; + } + } + } + + if (minValue == HUGE_VAL) + { + minValue = RI_LOGPLOTTRACK_MINX_DEFAULT; + maxValue = RI_LOGPLOTTRACK_MAXX_DEFAULT; + } + + m_visibleXRangeMin = minValue; + m_visibleXRangeMax = maxValue; + + if (m_wellLogTrackPlotWidget) m_wellLogTrackPlotWidget->setXRange(m_visibleXRangeMin, m_visibleXRangeMax); + + updateConnectedEditors(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimWellLogPlotCurve* RimWellLogPlotTrack::curveDefinitionFromCurve(const QwtPlotCurve* curve) const +{ + for (size_t idx = 0; idx < curves.size(); idx++) + { + if (curves[idx]->plotCurve() == curve) + { + return curves[idx]; + } + } + + return NULL; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogPlotTrack::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) +{ + uiOrdering.add(&m_userName); + + caf::PdmUiGroup* gridGroup = uiOrdering.addNewGroup("Visible X Axis Range"); + gridGroup->add(&m_visibleXRangeMin); + gridGroup->add(&m_visibleXRangeMax); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +size_t RimWellLogPlotTrack::curveIndex(RimWellLogPlotCurve* curve) +{ + return curves.index(curve); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimWellLogPlotTrack::isVisible() +{ + return m_show; +} diff --git a/ApplicationCode/ProjectDataModel/RimWellLogPlotTrack.h b/ApplicationCode/ProjectDataModel/RimWellLogPlotTrack.h new file mode 100644 index 0000000000..d106e0b3c4 --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimWellLogPlotTrack.h @@ -0,0 +1,85 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafPdmObject.h" +#include "cafPdmField.h" +#include "cafPdmChildArrayField.h" + +#include + +#include + +class RimWellLogPlotCurve; +class RiuWellLogTrackPlot; + +class QwtPlotCurve; + +//================================================================================================== +/// +/// +//================================================================================================== +class RimWellLogPlotTrack : public caf::PdmObject +{ + CAF_PDM_HEADER_INIT; +public: + RimWellLogPlotTrack(); + virtual ~RimWellLogPlotTrack(); + + void setDescription(const QString& description); + bool isVisible(); + void addCurve(RimWellLogPlotCurve* curve); + void insertCurve(RimWellLogPlotCurve* curve, size_t index); + void removeCurve(RimWellLogPlotCurve* curve); + size_t curveIndex(RimWellLogPlotCurve* curve); + size_t curveCount() { return curves.size(); } + + void recreateViewer(); + void detachAllCurves(); + + void loadDataAndUpdate(); + + void availableDepthRange(double* minimumDepth, double* maximumDepth); + void zoomAllXAndZoomAllDepthOnOwnerPlot(); + void alignDepthZoomToPlotAndZoomAllX(); + void zoomAllXAxis(); + + RiuWellLogTrackPlot* viewer(); + + RimWellLogPlotCurve* curveDefinitionFromCurve(const QwtPlotCurve* curve) const; + +protected: + + // Overridden PDM methods + virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue); + virtual caf::PdmFieldHandle* objectToggleField(); + virtual caf::PdmFieldHandle* userDescriptionField(); + virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering); + +private: +private: + caf::PdmField m_show; + caf::PdmField m_userName; + caf::PdmChildArrayField curves; + caf::PdmField m_visibleXRangeMin; + caf::PdmField m_visibleXRangeMax; + + QPointer m_wellLogTrackPlotWidget; +}; diff --git a/ApplicationCode/ProjectDataModel/RimWellPath.cpp b/ApplicationCode/ProjectDataModel/RimWellPath.cpp index 598da51516..b50b5c535f 100644 --- a/ApplicationCode/ProjectDataModel/RimWellPath.cpp +++ b/ApplicationCode/ProjectDataModel/RimWellPath.cpp @@ -23,11 +23,18 @@ #include "RifJsonEncodeDecode.h" #include "RimProject.h" #include "RimTools.h" +#include "RimWellLogFile.h" #include "RimWellPathCollection.h" +#include "RimProject.h" +#include "RimMainPlotCollection.h" +#include "RimWellLogPlotCollection.h" #include "RivWellPathPartMgr.h" +#include "RiuMainWindow.h" + #include #include +#include CAF_PDM_SOURCE_INIT(RimWellPath, "WellPath"); @@ -39,48 +46,51 @@ RimWellPath::RimWellPath() CAF_PDM_InitObject("WellPath", ":/Well.png", "", ""); CAF_PDM_InitFieldNoDefault(&name, "WellPathName", "Name", "", "", ""); - name.setUiReadOnly(true); - name.setIOWritable(false); - name.setIOReadable(false); - name.setUiHidden(true); + name.uiCapability()->setUiReadOnly(true); + name.xmlCapability()->setIOWritable(false); + name.xmlCapability()->setIOReadable(false); + name.uiCapability()->setUiHidden(true); CAF_PDM_InitFieldNoDefault(&id, "WellPathId", "Id", "", "", ""); - id.setUiReadOnly(true); - id.setIOWritable(false); - id.setIOReadable(false); + id.uiCapability()->setUiReadOnly(true); + id.xmlCapability()->setIOWritable(false); + id.xmlCapability()->setIOReadable(false); CAF_PDM_InitFieldNoDefault(&sourceSystem, "SourceSystem", "Source System", "", "", ""); - sourceSystem.setUiReadOnly(true); - sourceSystem.setIOWritable(false); - sourceSystem.setIOReadable(false); + sourceSystem.uiCapability()->setUiReadOnly(true); + sourceSystem.xmlCapability()->setIOWritable(false); + sourceSystem.xmlCapability()->setIOReadable(false); CAF_PDM_InitFieldNoDefault(&utmZone, "UTMZone", "UTM Zone", "", "", ""); - utmZone.setUiReadOnly(true); - utmZone.setIOWritable(false); - utmZone.setIOReadable(false); + utmZone.uiCapability()->setUiReadOnly(true); + utmZone.xmlCapability()->setIOWritable(false); + utmZone.xmlCapability()->setIOReadable(false); CAF_PDM_InitFieldNoDefault(&updateDate, "WellPathUpdateDate", "Update Date", "", "", ""); - updateDate.setUiReadOnly(true); - updateDate.setIOWritable(false); - updateDate.setIOReadable(false); + updateDate.uiCapability()->setUiReadOnly(true); + updateDate.xmlCapability()->setIOWritable(false); + updateDate.xmlCapability()->setIOReadable(false); CAF_PDM_InitFieldNoDefault(&updateUser, "WellPathUpdateUser", "Update User", "", "", ""); - updateUser.setUiReadOnly(true); - updateUser.setIOWritable(false); - updateUser.setIOReadable(false); + updateUser.uiCapability()->setUiReadOnly(true); + updateUser.xmlCapability()->setIOWritable(false); + updateUser.xmlCapability()->setIOReadable(false); CAF_PDM_InitFieldNoDefault(&m_surveyType, "WellPathSurveyType", "Survey Type", "", "", ""); - m_surveyType.setUiReadOnly(true); - m_surveyType.setIOWritable(false); - m_surveyType.setIOReadable(false); + m_surveyType.uiCapability()->setUiReadOnly(true); + m_surveyType.xmlCapability()->setIOWritable(false); + m_surveyType.xmlCapability()->setIOReadable(false); CAF_PDM_InitField(&filepath, "WellPathFilepath", QString(""), "Filepath", "", "", ""); - filepath.setUiReadOnly(true); + filepath.uiCapability()->setUiReadOnly(true); CAF_PDM_InitField(&wellPathIndexInFile, "WellPathNumberInFile", -1, "Well Number in file", "", "", ""); - wellPathIndexInFile.setUiReadOnly(true); + wellPathIndexInFile.uiCapability()->setUiReadOnly(true); CAF_PDM_InitField(&showWellPathLabel, "ShowWellPathLabel", true, "Show well path label", "", "", ""); CAF_PDM_InitField(&showWellPath, "ShowWellPath", true, "Show well path", "", "", ""); - showWellPath.setUiHidden(true); + showWellPath.uiCapability()->setUiHidden(true); CAF_PDM_InitField(&wellPathRadiusScaleFactor, "WellPathRadiusScale", 1.0, "Well path radius scale", "", "", ""); CAF_PDM_InitField(&wellPathColor, "WellPathColor", cvf::Color3f(0.999f, 0.333f, 0.999f), "Well path color", "", "", ""); + CAF_PDM_InitFieldNoDefault(&m_wellLogFile, "WellLogFile", "Well Log File", "", "", ""); + m_wellLogFile.uiCapability()->setUiHidden(true); + m_wellPath = NULL; m_project = NULL; } @@ -91,6 +101,25 @@ RimWellPath::RimWellPath() //-------------------------------------------------------------------------------------------------- RimWellPath::~RimWellPath() { + if (m_wellLogFile()) + { + delete m_wellLogFile; + } + + RimProject* project; + firstAnchestorOrThisOfType(project); + if (project) + { + if (project->mainPlotCollection()) + { + RimWellLogPlotCollection* plotCollection = project->mainPlotCollection()->wellLogPlotCollection(); + if (plotCollection) + { + plotCollection->removeExtractors(m_wellPath.p()); + } + } + } + } @@ -147,21 +176,31 @@ caf::PdmFieldHandle* RimWellPath::objectToggleField() //-------------------------------------------------------------------------------------------------- -/// Read JSON file containing well path data +/// Read JSON or ascii file containing well path data //-------------------------------------------------------------------------------------------------- -void RimWellPath::readWellPathFile() +bool RimWellPath::readWellPathFile(QString* errorMessage) { - QFileInfo fi(filepath()); + QFileInfo fileInf(filepath()); - if (fi.suffix().compare("json") == 0) + if (fileInf.isFile() && fileInf.exists()) { - this->readJsonWellPathFile(); + if (fileInf.suffix().compare("json") == 0) + { + this->readJsonWellPathFile(); + } + else + { + this->readAsciiWellPathFile(); + } + + return true; } else { - this->readAsciiWellPathFile(); - } + if (errorMessage) (*errorMessage) = "Could not find the well path file: " + filepath(); + return false; + } } //-------------------------------------------------------------------------------------------------- @@ -204,6 +243,9 @@ void RimWellPath::readJsonWellPathFile() QMap coordinateMap = point.toMap(); cvf::Vec3d vec3d(coordinateMap["east"].toDouble(), coordinateMap["north"].toDouble(), -(coordinateMap["tvd"].toDouble() - datumElevation)); wellPathGeom->m_wellPathPoints.push_back(vec3d); + + double measuredDepth = coordinateMap["md"].toDouble(); + wellPathGeom->m_measuredDepths.push_back(measuredDepth); } //jsonReader.dumpToFile(wellPathGeom->m_wellPathPoints, "c:\\temp\\jsonpoints.txt"); @@ -215,7 +257,7 @@ void RimWellPath::readJsonWellPathFile() //-------------------------------------------------------------------------------------------------- void RimWellPath::readAsciiWellPathFile() { - RimWellPathAsciiFileReader::WellData wpData = m_wellPathCollection->asciiFileReader()->readWellData(filepath(), wellPathIndexInFile()); + RifWellPathAsciiFileReader::WellData wpData = m_wellPathCollection->asciiFileReader()->readWellData(filepath(), wellPathIndexInFile()); this->name = wpData.m_name; setWellPathGeometry(wpData.m_wellPathGeometry.p()); @@ -242,7 +284,6 @@ void RimWellPath::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiO ssihubGroup->add(&updateDate); ssihubGroup->add(&updateUser); ssihubGroup->add(&m_surveyType); - } //-------------------------------------------------------------------------------------------------- @@ -260,12 +301,18 @@ QString RimWellPath::getCacheDirectoryPath() //-------------------------------------------------------------------------------------------------- QString RimWellPath::getCacheFileName() { + if (filepath().isEmpty()) + { + return ""; + } + QString cacheFileName; // Make the path correct related to the possibly new project filename QString newCacheDirPath = getCacheDirectoryPath(); QFileInfo oldCacheFile(filepath); + cacheFileName = newCacheDirPath + "/" + oldCacheFile.fileName(); return cacheFileName; @@ -282,6 +329,11 @@ void RimWellPath::setupBeforeSave() return; } + if (filepath().isEmpty()) + { + return; + } + QDir::root().mkpath(getCacheDirectoryPath()); QString newCacheFileName = getCacheFileName(); @@ -320,3 +372,18 @@ void RimWellPath::updateFilePathsFromProjectPath() } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellPath::setLogFileInfo(RimWellLogFile* logFileInfo) +{ + if (m_wellLogFile()) + { + delete m_wellLogFile; + } + + m_wellLogFile = logFileInfo; + m_wellLogFile->uiCapability()->setUiHidden(true); + + this->name = m_wellLogFile->wellName(); +} diff --git a/ApplicationCode/ProjectDataModel/RimWellPath.h b/ApplicationCode/ProjectDataModel/RimWellPath.h index 928cd2fb17..940b74edb7 100644 --- a/ApplicationCode/ProjectDataModel/RimWellPath.h +++ b/ApplicationCode/ProjectDataModel/RimWellPath.h @@ -23,6 +23,7 @@ #include "cafPdmField.h" #include "cafPdmObject.h" #include "cafPdmPointer.h" +#include "cafPdmChildField.h" #include "cafAppEnum.h" // Include to make Pdm work for cvf::Color @@ -33,6 +34,7 @@ class RimProject; class RivWellPathPartMgr; class RimWellPathCollection; +class RimWellLogFile; //================================================================================================== /// @@ -48,6 +50,7 @@ class RimWellPath : public caf::PdmObject void setProject(RimProject* project) { m_project = project; } void setCollection(RimWellPathCollection* collection) { m_wellPathCollection = collection; } + void setLogFileInfo(RimWellLogFile* logFileInfo); virtual caf::PdmFieldHandle* userDescriptionField(); virtual caf::PdmFieldHandle* objectToggleField(); @@ -65,10 +68,12 @@ class RimWellPath : public caf::PdmObject caf::PdmField wellPathColor; caf::PdmField wellPathRadiusScaleFactor; + caf::PdmChildField m_wellLogFile; + RigWellPath* wellPathGeometry() { return m_wellPath.p(); } RivWellPathPartMgr* partMgr(); - void readWellPathFile(); + bool readWellPathFile(QString * errorMessage); void updateFilePathsFromProjectPath(); @@ -99,5 +104,5 @@ class RimWellPath : public caf::PdmObject cvf::ref m_wellPath; cvf::ref m_wellPathPartMgr; caf::PdmPointer m_wellPathCollection; - RimProject* m_project; + RimProject* m_project; }; diff --git a/ApplicationCode/ProjectDataModel/RimWellPathCollection.cpp b/ApplicationCode/ProjectDataModel/RimWellPathCollection.cpp index 45fd93376c..182d553334 100644 --- a/ApplicationCode/ProjectDataModel/RimWellPathCollection.cpp +++ b/ApplicationCode/ProjectDataModel/RimWellPathCollection.cpp @@ -24,12 +24,17 @@ #include "RiaPreferences.h" #include "RimProject.h" #include "RimWellPath.h" +#include "RimWellLogFile.h" #include "RivWellPathCollectionPartMgr.h" +#include "RiuMainWindow.h" + +#include "cafPdmUiEditorHandle.h" #include "cafProgressInfo.h" #include #include +#include #include #include @@ -56,7 +61,7 @@ RimWellPathCollection::RimWellPathCollection() CAF_PDM_InitObject("Wells", ":/WellCollection.png", "", ""); CAF_PDM_InitField(&isActive, "Active", true, "Active", "", "", ""); - isActive.setUiHidden(true); + isActive.uiCapability()->setUiHidden(true); CAF_PDM_InitField(&showWellPathLabel, "ShowWellPathLabel", true, "Show well path labels", "", "", ""); @@ -67,18 +72,19 @@ RimWellPathCollection::RimWellPathCollection() CAF_PDM_InitField(&wellPathRadiusScaleFactor, "WellPathRadiusScale", 0.1, "Well Path radius scale", "", "", ""); CAF_PDM_InitField(&wellPathCrossSectionVertexCount, "WellPathVertexCount", 12, "Well Path vertex count", "", "", ""); - wellPathCrossSectionVertexCount.setIOWritable(false); - wellPathCrossSectionVertexCount.setIOReadable(false); - wellPathCrossSectionVertexCount.setUiHidden(true); + wellPathCrossSectionVertexCount.xmlCapability()->setIOWritable(false); + wellPathCrossSectionVertexCount.xmlCapability()->setIOReadable(false); + wellPathCrossSectionVertexCount.uiCapability()->setUiHidden(true); CAF_PDM_InitField(&wellPathClip, "WellPathClip", true, "Clip Well Paths", "", "", ""); CAF_PDM_InitField(&wellPathClipZDistance, "WellPathClipZDistance", 100, "Well path clipping depth distance", "", "", ""); CAF_PDM_InitFieldNoDefault(&wellPaths, "WellPaths", "Well Paths", "", "", ""); + wellPaths.uiCapability()->setUiHidden(true); m_wellPathCollectionPartManager = new RivWellPathCollectionPartMgr(this); m_project = NULL; - m_asciiFileReader = new RimWellPathAsciiFileReader; + m_asciiFileReader = new RifWellPathAsciiFileReader; } @@ -124,7 +130,36 @@ void RimWellPathCollection::readWellPathFiles() for (size_t wpIdx = 0; wpIdx < wellPaths.size(); wpIdx++) { - wellPaths[wpIdx]->readWellPathFile(); + if (!wellPaths[wpIdx]->filepath().isEmpty()) + { + QString errorMessage; + if (!wellPaths[wpIdx]->readWellPathFile(&errorMessage)) + { + QMessageBox::warning(RiuMainWindow::instance(), + "File open error", + errorMessage); + } + } + + RimWellLogFile* wellLogFile = wellPaths[wpIdx]->m_wellLogFile; + if (wellLogFile) + { + QString errorMessage; + if (!wellLogFile->readFile(&errorMessage)) + { + QString displayMessage = "Could not open the well log file: \n" + wellLogFile->fileName(); + + if (!errorMessage.isEmpty()) + { + displayMessage += "\n\n"; + displayMessage += errorMessage; + } + + QMessageBox::warning(RiuMainWindow::instance(), + "File open error", + displayMessage); + } + } progress.setProgressDescription(QString("Reading file %1").arg(wellPaths[wpIdx]->name)); progress.incrementProgress(); @@ -137,6 +172,8 @@ void RimWellPathCollection::readWellPathFiles() //-------------------------------------------------------------------------------------------------- void RimWellPathCollection::addWellPaths( QStringList filePaths ) { + std::vector wellPathArray; + foreach (QString filePath, filePaths) { // Check if this file is already open @@ -167,7 +204,7 @@ void RimWellPathCollection::addWellPaths( QStringList filePaths ) wellPath->setProject(m_project); wellPath->setCollection(this); wellPath->filepath = filePath; - wellPaths.push_back(wellPath); + wellPathArray.push_back(wellPath); } else { @@ -180,13 +217,71 @@ void RimWellPathCollection::addWellPaths( QStringList filePaths ) wellPath->setCollection(this); wellPath->filepath = filePath; wellPath->wellPathIndexInFile = static_cast(i); - wellPaths.push_back(wellPath); + wellPathArray.push_back(wellPath); } } } } - readWellPathFiles(); + readAndAddWellPaths(wellPathArray); +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellPathCollection::readAndAddWellPaths(std::vector& wellPathArray) +{ + caf::ProgressInfo progress(wellPathArray.size(), "Reading well paths from file"); + + for (size_t wpIdx = 0; wpIdx < wellPathArray.size(); wpIdx++) + { + RimWellPath* wellPath = wellPathArray[wpIdx]; + wellPath->readWellPathFile(NULL); + + progress.setProgressDescription(QString("Reading file %1").arg(wellPath->name)); + + // If a well path with this name exists already, make it read the well path file + RimWellPath* existingWellPath = wellPathByName(wellPath->name); + if (existingWellPath) + { + existingWellPath->filepath = wellPath->filepath; + existingWellPath->wellPathIndexInFile = wellPath->wellPathIndexInFile; + existingWellPath->readWellPathFile(NULL); + + delete wellPath; + } + else + { + wellPaths.push_back(wellPath); + } + + progress.incrementProgress(); + } +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellPathCollection::addWellLogs(const QStringList& filePaths) +{ + foreach (QString filePath, filePaths) + { + RimWellLogFile* logFileInfo = RimWellLogFile::readWellLogFile(filePath); + if (logFileInfo) + { + RimWellPath* wellPath = wellPathByName(logFileInfo->wellName()); + if (!wellPath) + { + wellPath = new RimWellPath(); + wellPath->setCollection(this); + wellPaths.push_back(wellPath); + } + + wellPath->setLogFileInfo(logFileInfo); + } + } } //-------------------------------------------------------------------------------------------------- @@ -238,7 +333,58 @@ void RimWellPathCollection::updateFilePathsFromProjectPath() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimWellPathAsciiFileReader::readAllWellData(QString filePath) +RimWellPath* RimWellPathCollection::wellPathByName(const QString& wellPathName) const +{ + for (size_t wellPathIdx = 0; wellPathIdx < wellPaths.size(); wellPathIdx++) + { + if (wellPaths[wellPathIdx]->name() == wellPathName) + { + return wellPaths[wellPathIdx]; + } + } + + return NULL; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellPathCollection::deleteAllWellPaths() +{ + wellPaths.deleteAllChildObjects(); + + m_asciiFileReader->clear(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellPathCollection::removeWellPath(RimWellPath* wellPath) +{ + wellPaths.removeChildObject(wellPath); + + bool isFilePathUsed = false; + for (size_t i = 0; i < wellPaths.size(); i++) + { + if (wellPaths[i]->filepath == wellPath->filepath) + { + isFilePathUsed = true; + break; + } + } + + if (!isFilePathUsed) + { + // One file can have multiple well paths + // If no other well paths are referencing the filepath, remove cached data from the file reader + m_asciiFileReader->removeFilePath(wellPath->filepath); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RifWellPathAsciiFileReader::readAllWellData(QString filePath) { std::map >::iterator it = m_fileNameToWellDataGroupMap.find(filePath); @@ -280,6 +426,7 @@ void RimWellPathAsciiFileReader::readAllWellData(QString filePath) cvf::Vec3d wellPoint(x, y, -tvd); fileWellDataArray.back().m_wellPathGeometry->m_wellPathPoints.push_back(wellPoint); + fileWellDataArray.back().m_wellPathGeometry->m_measuredDepths.push_back(md); x = HUGE_VAL; y = HUGE_VAL; @@ -308,15 +455,26 @@ void RimWellPathAsciiFileReader::readAllWellData(QString filePath) else if (quoteStartIdx > line.length() && quoteEndIdx > line.length()) { // Did not find any quotes - // Look for keyword Name + // Supported alternatives are + // name WellNameA + // wellname: WellNameA std::string lineLowerCase = line; transform(lineLowerCase.begin(), lineLowerCase.end(), lineLowerCase.begin(), ::tolower ); - std::string token = "name "; - size_t firstNameIdx = lineLowerCase.find_first_of(token); - if (firstNameIdx < lineLowerCase.length()) + std::string tokenName = "name"; + std::size_t foundNameIdx = lineLowerCase.find(tokenName); + if (foundNameIdx != std::string::npos) { - wellName = line.substr(firstNameIdx + token.length()); + std::string tokenColon = ":"; + std::size_t foundColonIdx = lineLowerCase.find(tokenColon, foundNameIdx); + if (foundColonIdx != std::string::npos) + { + wellName = line.substr(foundColonIdx + tokenColon.length()); + } + else + { + wellName = line.substr(foundNameIdx + tokenName.length()); + } } } @@ -326,7 +484,8 @@ void RimWellPathAsciiFileReader::readAllWellData(QString filePath) fileWellDataArray.push_back(WellData()); fileWellDataArray.back().m_wellPathGeometry = new RigWellPath(); - fileWellDataArray.back().m_name = wellName.c_str(); + QString name = wellName.c_str(); + fileWellDataArray.back().m_name = name.trimmed(); } } } @@ -335,7 +494,7 @@ void RimWellPathAsciiFileReader::readAllWellData(QString filePath) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RimWellPathAsciiFileReader::WellData RimWellPathAsciiFileReader::readWellData(QString filePath, int indexInFile) +RifWellPathAsciiFileReader::WellData RifWellPathAsciiFileReader::readWellData(QString filePath, int indexInFile) { this->readAllWellData(filePath); @@ -349,7 +508,7 @@ RimWellPathAsciiFileReader::WellData RimWellPathAsciiFileReader::readWellData(QS } else { - // Error : The ascii well path file does not contain that many wellpaths + // Error : The ascii well path file does not contain that many well paths return WellData(); } } @@ -357,7 +516,7 @@ RimWellPathAsciiFileReader::WellData RimWellPathAsciiFileReader::readWellData(QS //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -size_t RimWellPathAsciiFileReader::wellDataCount(QString filePath) +size_t RifWellPathAsciiFileReader::wellDataCount(QString filePath) { std::map >::iterator it = m_fileNameToWellDataGroupMap.find(filePath); @@ -373,3 +532,19 @@ size_t RimWellPathAsciiFileReader::wellDataCount(QString filePath) return it->second.size();; } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RifWellPathAsciiFileReader::clear() +{ + m_fileNameToWellDataGroupMap.clear(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RifWellPathAsciiFileReader::removeFilePath(const QString& filePath) +{ + m_fileNameToWellDataGroupMap.erase(filePath); +} diff --git a/ApplicationCode/ProjectDataModel/RimWellPathCollection.h b/ApplicationCode/ProjectDataModel/RimWellPathCollection.h index 4b60c7e535..df00e852a7 100644 --- a/ApplicationCode/ProjectDataModel/RimWellPathCollection.h +++ b/ApplicationCode/ProjectDataModel/RimWellPathCollection.h @@ -20,6 +20,7 @@ #pragma once +#include "cafPdmChildArrayField.h" #include "cafPdmField.h" #include "cafPdmObject.h" #include "cafPdmPointer.h" @@ -33,7 +34,7 @@ #include class RivWellPathCollectionPartMgr; -class RimWellPathAsciiFileReader; +class RifWellPathAsciiFileReader; class RimWellPath; class RimProject; class RigWellPath; @@ -72,14 +73,21 @@ class RimWellPathCollection : public caf::PdmObject caf::PdmField wellPathClip; caf::PdmField wellPathClipZDistance; - caf::PdmPointersField wellPaths; + caf::PdmChildArrayField wellPaths; RivWellPathCollectionPartMgr* wellPathCollectionPartMgr() { return m_wellPathCollectionPartManager.p(); } void readWellPathFiles(); void addWellPaths(QStringList filePaths); - RimWellPathAsciiFileReader* asciiFileReader() {return m_asciiFileReader;} + + void removeWellPath(RimWellPath* wellPath); + void deleteAllWellPaths(); + + RifWellPathAsciiFileReader* asciiFileReader() {return m_asciiFileReader;} + + RimWellPath* wellPathByName(const QString& wellPathName) const; + void addWellLogs(const QStringList& filePaths); virtual void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ); @@ -90,14 +98,20 @@ class RimWellPathCollection : public caf::PdmObject virtual void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ); virtual caf::PdmFieldHandle* objectToggleField(); + void readAndAddWellPaths(std::vector& wellPathArray); + caf::PdmPointer m_project; cvf::ref m_wellPathCollectionPartManager; - RimWellPathAsciiFileReader* m_asciiFileReader; + RifWellPathAsciiFileReader* m_asciiFileReader; }; -class RimWellPathAsciiFileReader +//================================================================================================== +/// +/// +//================================================================================================== +class RifWellPathAsciiFileReader { public: struct WellData @@ -109,8 +123,10 @@ class RimWellPathAsciiFileReader WellData readWellData(QString filePath, int indexInFile); size_t wellDataCount(QString filePath); -private: + void clear(); + void removeFilePath(const QString& filePath); +private: void readAllWellData(QString filePath); std::map > m_fileNameToWellDataGroupMap; diff --git a/ApplicationCode/ProjectDataModel/cafPdmAbstractClassSourceInit.h b/ApplicationCode/ProjectDataModel/cafPdmAbstractClassSourceInit.h deleted file mode 100644 index 896365aa5f..0000000000 --- a/ApplicationCode/ProjectDataModel/cafPdmAbstractClassSourceInit.h +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - - -#define CAF_PDM_ABSTRACT_SOURCE_INIT(ClassName, keyword) \ - bool ClassName::Error_You_forgot_to_add_the_macro_CAF_PDM_HEADER_INIT_and_or_CAF_PDM_SOURCE_INIT_to_your_cpp_file_for_this_class() { return false;} \ - QString ClassName::classKeywordStatic() { assert(PdmObject::isValidXmlElementName(keyword)); return keyword; } - - diff --git a/ApplicationCode/ReservoirDataModel/CMakeLists_files.cmake b/ApplicationCode/ReservoirDataModel/CMakeLists_files.cmake index f1e142c668..21ddac0704 100644 --- a/ApplicationCode/ReservoirDataModel/CMakeLists_files.cmake +++ b/ApplicationCode/ReservoirDataModel/CMakeLists_files.cmake @@ -19,6 +19,8 @@ ${CEE_CURRENT_LIST_DIR}RigCombTransResultAccessor.h ${CEE_CURRENT_LIST_DIR}RigCombMultResultAccessor.h ${CEE_CURRENT_LIST_DIR}RigResultModifier.h ${CEE_CURRENT_LIST_DIR}RigResultModifierFactory.h +${CEE_CURRENT_LIST_DIR}RigWellLogExtractor.h +${CEE_CURRENT_LIST_DIR}RigEclipseWellLogExtractor.h ${CEE_CURRENT_LIST_DIR}RigLocalGrid.h ${CEE_CURRENT_LIST_DIR}RigMainGrid.h ${CEE_CURRENT_LIST_DIR}RigReservoirBuilderMock.h @@ -34,6 +36,7 @@ ${CEE_CURRENT_LIST_DIR}RigResultAccessor2d.h ${CEE_CURRENT_LIST_DIR}RigTernaryResultAccessor2d.h ${CEE_CURRENT_LIST_DIR}RigNativeStatCalc.h ${CEE_CURRENT_LIST_DIR}RigMultipleDatasetStatCalc.h +${CEE_CURRENT_LIST_DIR}RigWellLogCurveData.h ) set (SOURCE_GROUP_SOURCE_FILES @@ -50,6 +53,8 @@ ${CEE_CURRENT_LIST_DIR}RigCellEdgeResultAccessor.cpp ${CEE_CURRENT_LIST_DIR}RigCombTransResultAccessor.cpp ${CEE_CURRENT_LIST_DIR}RigCombMultResultAccessor.cpp ${CEE_CURRENT_LIST_DIR}RigResultModifierFactory.cpp +${CEE_CURRENT_LIST_DIR}RigWellLogExtractor.cpp +${CEE_CURRENT_LIST_DIR}RigEclipseWellLogExtractor.cpp ${CEE_CURRENT_LIST_DIR}RigLocalGrid.cpp ${CEE_CURRENT_LIST_DIR}RigMainGrid.cpp ${CEE_CURRENT_LIST_DIR}RigReservoirBuilderMock.cpp @@ -62,6 +67,7 @@ ${CEE_CURRENT_LIST_DIR}cvfGeometryTools.cpp ${CEE_CURRENT_LIST_DIR}RigTernaryResultAccessor2d.cpp ${CEE_CURRENT_LIST_DIR}RigNativeStatCalc.cpp ${CEE_CURRENT_LIST_DIR}RigMultipleDatasetStatCalc.cpp +${CEE_CURRENT_LIST_DIR}RigWellLogCurveData.cpp ) list(APPEND CODE_HEADER_FILES diff --git a/ApplicationCode/ReservoirDataModel/CMakeLists_filesNotToUnitTest.cmake b/ApplicationCode/ReservoirDataModel/CMakeLists_filesNotToUnitTest.cmake new file mode 100644 index 0000000000..d7ef0c9661 --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/CMakeLists_filesNotToUnitTest.cmake @@ -0,0 +1,31 @@ + +# Use this workaround until we're on 2.8.3 on all platforms and can use CMAKE_CURRENT_LIST_DIR directly +if (${CMAKE_VERSION} VERSION_GREATER "2.8.2") + set(CEE_CURRENT_LIST_DIR ${CMAKE_CURRENT_LIST_DIR}/) +endif() + +set (SOURCE_GROUP_HEADER_FILES + ${CEE_CURRENT_LIST_DIR}RigGeoMechWellLogExtractor.h + ${CEE_CURRENT_LIST_DIR}RigCaseToCaseCellMapper.h + ${CEE_CURRENT_LIST_DIR}RigCaseToCaseCellMapperTools.h + ${CEE_CURRENT_LIST_DIR}RigCaseToCaseRangeFilterMapper.h + ${CEE_CURRENT_LIST_DIR}RigWellLogFile.h +) + +set (SOURCE_GROUP_SOURCE_FILES + ${CEE_CURRENT_LIST_DIR}RigGeoMechWellLogExtractor.cpp + ${CEE_CURRENT_LIST_DIR}RigCaseToCaseCellMapper.cpp + ${CEE_CURRENT_LIST_DIR}RigCaseToCaseCellMapperTools.cpp + ${CEE_CURRENT_LIST_DIR}RigCaseToCaseRangeFilterMapper.cpp + ${CEE_CURRENT_LIST_DIR}RigWellLogFile.cpp +) + +list(APPEND CODE_HEADER_FILES +${SOURCE_GROUP_HEADER_FILES} +) + +list(APPEND CODE_SOURCE_FILES +${SOURCE_GROUP_SOURCE_FILES} +) + +source_group( "ReservoirDataModel2" FILES ${SOURCE_GROUP_HEADER_FILES} ${SOURCE_GROUP_SOURCE_FILES} ${CEE_CURRENT_LIST_DIR}CMakeLists_filesNotToUnitTest.cmake ) diff --git a/ApplicationCode/ReservoirDataModel/ReservoirDataModel_UnitTests/CMakeLists.txt b/ApplicationCode/ReservoirDataModel/ReservoirDataModel_UnitTests/CMakeLists.txt index b066ea1698..80115859bf 100644 --- a/ApplicationCode/ReservoirDataModel/ReservoirDataModel_UnitTests/CMakeLists.txt +++ b/ApplicationCode/ReservoirDataModel/ReservoirDataModel_UnitTests/CMakeLists.txt @@ -19,8 +19,12 @@ include_directories( ${ResInsight_SOURCE_DIR}/ApplicationCode/FileInterface ${ResInsight_SOURCE_DIR}/ApplicationCode/ProjectDataModel ${ResInsight_SOURCE_DIR}/ThirdParty + ${ResInsight_SOURCE_DIR}/ThirdParty/NRLib/nrlib/well - ${ResInsight_SOURCE_DIR}/Fwk/AppFwk/cafProjectDataModel + #${ResInsight_SOURCE_DIR}/Fwk/AppFwk/cafProjectDataModel + + ${cafProjectDataModel_SOURCE_DIR} + ${cafPdmCore_SOURCE_DIR} ${ResInsight_SOURCE_DIR}/Fwk/AppFwk/CommonCode @@ -65,6 +69,8 @@ set( LINK_LIBRARIES ecl_well ert_util + NRLib + ${QT_LIBRARIES} ) diff --git a/ApplicationCode/ReservoirDataModel/ReservoirDataModel_UnitTests/RigReservoir-Test.cpp b/ApplicationCode/ReservoirDataModel/ReservoirDataModel_UnitTests/RigReservoir-Test.cpp index 5fe9cd233b..42df377a7f 100644 --- a/ApplicationCode/ReservoirDataModel/ReservoirDataModel_UnitTests/RigReservoir-Test.cpp +++ b/ApplicationCode/ReservoirDataModel/ReservoirDataModel_UnitTests/RigReservoir-Test.cpp @@ -18,7 +18,6 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RiaStdInclude.h" #include "gtest/gtest.h" #include "RigCaseData.h" diff --git a/ApplicationCode/ReservoirDataModel/ReservoirDataModel_UnitTests/RigStatisticsMath-Test.cpp b/ApplicationCode/ReservoirDataModel/ReservoirDataModel_UnitTests/RigStatisticsMath-Test.cpp index 1be15da9bc..af9bc26f81 100644 --- a/ApplicationCode/ReservoirDataModel/ReservoirDataModel_UnitTests/RigStatisticsMath-Test.cpp +++ b/ApplicationCode/ReservoirDataModel/ReservoirDataModel_UnitTests/RigStatisticsMath-Test.cpp @@ -18,7 +18,6 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RiaStdInclude.h" #include "gtest/gtest.h" #include "RigStatisticsMath.h" diff --git a/ApplicationCode/ReservoirDataModel/ReservoirDataModel_UnitTests/main.cpp b/ApplicationCode/ReservoirDataModel/ReservoirDataModel_UnitTests/main.cpp index 00d12ebca0..543a31bbf5 100644 --- a/ApplicationCode/ReservoirDataModel/ReservoirDataModel_UnitTests/main.cpp +++ b/ApplicationCode/ReservoirDataModel/ReservoirDataModel_UnitTests/main.cpp @@ -16,7 +16,6 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RiaStdInclude.h" #include "cvfBase.h" diff --git a/ApplicationCode/ReservoirDataModel/RigActiveCellsResultAccessor.cpp b/ApplicationCode/ReservoirDataModel/RigActiveCellsResultAccessor.cpp index a2267e84aa..446a95bdfd 100644 --- a/ApplicationCode/ReservoirDataModel/RigActiveCellsResultAccessor.cpp +++ b/ApplicationCode/ReservoirDataModel/RigActiveCellsResultAccessor.cpp @@ -57,3 +57,26 @@ double RigActiveCellsResultAccessor::cellFaceScalar(size_t gridLocalCellIndex, c return cellScalar(gridLocalCellIndex); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RigActiveCellsResultAccessor::cellScalarGlobIdx(size_t reservoirCellIndex) const +{ + if (m_reservoirResultValues == NULL || m_reservoirResultValues->size() == 0) return HUGE_VAL; + + size_t resultValueIndex = m_activeCellInfo->cellResultIndex(reservoirCellIndex); + if (resultValueIndex == cvf::UNDEFINED_SIZE_T) return HUGE_VAL; + + CVF_TIGHT_ASSERT(resultValueIndex < m_reservoirResultValues->size()); + + return m_reservoirResultValues->at(resultValueIndex); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RigActiveCellsResultAccessor::cellFaceScalarGlobIdx(size_t globCellIndex, cvf::StructGridInterface::FaceType faceId) const +{ + return cellScalarGlobIdx(globCellIndex); +} + diff --git a/ApplicationCode/ReservoirDataModel/RigActiveCellsResultAccessor.h b/ApplicationCode/ReservoirDataModel/RigActiveCellsResultAccessor.h index e9fa9b1c0c..2f48e6e682 100644 --- a/ApplicationCode/ReservoirDataModel/RigActiveCellsResultAccessor.h +++ b/ApplicationCode/ReservoirDataModel/RigActiveCellsResultAccessor.h @@ -36,6 +36,9 @@ class RigActiveCellsResultAccessor : public RigResultAccessor virtual double cellScalar(size_t gridLocalCellIndex) const; virtual double cellFaceScalar(size_t gridLocalCellIndex, cvf::StructGridInterface::FaceType faceId) const; + virtual double cellScalarGlobIdx(size_t globCellIndex) const; + virtual double cellFaceScalarGlobIdx(size_t globCellIndex, cvf::StructGridInterface::FaceType faceId) const; + private: const RigActiveCellInfo* m_activeCellInfo; const RigGridBase* m_grid; diff --git a/ApplicationCode/ReservoirDataModel/RigAllGridCellsResultAccessor.cpp b/ApplicationCode/ReservoirDataModel/RigAllGridCellsResultAccessor.cpp index 71e360ceb4..33810175fb 100644 --- a/ApplicationCode/ReservoirDataModel/RigAllGridCellsResultAccessor.cpp +++ b/ApplicationCode/ReservoirDataModel/RigAllGridCellsResultAccessor.cpp @@ -54,3 +54,24 @@ double RigAllGridCellsResultAccessor::cellFaceScalar(size_t gridLocalCellIndex, return cellScalar(gridLocalCellIndex); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RigAllGridCellsResultAccessor::cellScalarGlobIdx(size_t globCellIndex) const +{ + if (m_reservoirResultValues->size() == 0) return HUGE_VAL; + + CVF_TIGHT_ASSERT(globCellIndex < m_reservoirResultValues->size()); + + return m_reservoirResultValues->at(globCellIndex); + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RigAllGridCellsResultAccessor::cellFaceScalarGlobIdx(size_t globCellIndex, cvf::StructGridInterface::FaceType faceId) const +{ + return cellScalarGlobIdx(globCellIndex); +} + diff --git a/ApplicationCode/ReservoirDataModel/RigAllGridCellsResultAccessor.h b/ApplicationCode/ReservoirDataModel/RigAllGridCellsResultAccessor.h index 4c347a555b..57ab007bc7 100644 --- a/ApplicationCode/ReservoirDataModel/RigAllGridCellsResultAccessor.h +++ b/ApplicationCode/ReservoirDataModel/RigAllGridCellsResultAccessor.h @@ -34,6 +34,8 @@ class RigAllGridCellsResultAccessor : public RigResultAccessor virtual double cellScalar(size_t gridLocalCellIndex) const; virtual double cellFaceScalar(size_t gridLocalCellIndex, cvf::StructGridInterface::FaceType faceId) const; + virtual double cellScalarGlobIdx(size_t globCellIndex) const; + virtual double cellFaceScalarGlobIdx(size_t globCellIndex, cvf::StructGridInterface::FaceType faceId) const; private: const RigGridBase* m_grid; diff --git a/ApplicationCode/ReservoirDataModel/RigCaseCellResultsData.cpp b/ApplicationCode/ReservoirDataModel/RigCaseCellResultsData.cpp index 6a1ca42898..10e2a61c47 100644 --- a/ApplicationCode/ReservoirDataModel/RigCaseCellResultsData.cpp +++ b/ApplicationCode/ReservoirDataModel/RigCaseCellResultsData.cpp @@ -108,7 +108,7 @@ void RigCaseCellResultsData::meanCellScalarValues(size_t scalarResultIndex, doub //-------------------------------------------------------------------------------------------------- size_t RigCaseCellResultsData::resultCount() const { - return m_cellScalarResults.size(); + return m_cellScalarResults.size(); } //-------------------------------------------------------------------------------------------------- @@ -136,9 +136,9 @@ const std::vector< std::vector > & RigCaseCellResultsData::cellScalarRes //-------------------------------------------------------------------------------------------------- std::vector< std::vector > & RigCaseCellResultsData::cellScalarResults( size_t scalarResultIndex ) { - CVF_TIGHT_ASSERT(scalarResultIndex < resultCount()); + CVF_TIGHT_ASSERT(scalarResultIndex < resultCount()); - return m_cellScalarResults[scalarResultIndex]; + return m_cellScalarResults[scalarResultIndex]; } //-------------------------------------------------------------------------------------------------- @@ -152,25 +152,6 @@ std::vector& RigCaseCellResultsData::cellScalarResults(size_t scalarResu return m_cellScalarResults[scalarResultIndex][timeStepIndex]; } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -double RigCaseCellResultsData::cellScalarResult( size_t scalarResultIndex, size_t timeStepIndex, size_t resultValueIndex) -{ - if (scalarResultIndex < resultCount() && - timeStepIndex < m_cellScalarResults[scalarResultIndex].size() && - resultValueIndex != cvf::UNDEFINED_SIZE_T && - resultValueIndex < m_cellScalarResults[scalarResultIndex][timeStepIndex].size()) - { - return m_cellScalarResults[scalarResultIndex][timeStepIndex][resultValueIndex]; - } - else - { - return HUGE_VAL; - } -} - - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ReservoirDataModel/RigCaseCellResultsData.h b/ApplicationCode/ReservoirDataModel/RigCaseCellResultsData.h index 461339bc77..a772be7f47 100644 --- a/ApplicationCode/ReservoirDataModel/RigCaseCellResultsData.h +++ b/ApplicationCode/ReservoirDataModel/RigCaseCellResultsData.h @@ -87,7 +87,6 @@ class RigCaseCellResultsData : public cvf::Object const std::vector< std::vector > & cellScalarResults(size_t scalarResultIndex) const; std::vector< std::vector > & cellScalarResults(size_t scalarResultIndex); std::vector& cellScalarResults(size_t scalarResultIndex, size_t timeStepIndex); - double cellScalarResult(size_t scalarResultIndex, size_t timeStepIndex, size_t resultValueIndex); static RifReaderInterface::PorosityModelResultType convertFromProjectModelPorosityModel(RimDefines::PorosityModelType porosityModel); diff --git a/ApplicationCode/ReservoirDataModel/RigCaseData.h b/ApplicationCode/ReservoirDataModel/RigCaseData.h index 8b49fb29ad..220bd5f9a0 100644 --- a/ApplicationCode/ReservoirDataModel/RigCaseData.h +++ b/ApplicationCode/ReservoirDataModel/RigCaseData.h @@ -56,7 +56,7 @@ class RigCaseData : public cvf::Object RigGridBase* grid(size_t index); size_t gridCount() const; - RigCaseCellResultsData* results(RifReaderInterface::PorosityModelResultType porosityModel); + RigCaseCellResultsData* results(RifReaderInterface::PorosityModelResultType porosityModel); const RigCaseCellResultsData* results(RifReaderInterface::PorosityModelResultType porosityModel) const; RigActiveCellInfo* activeCellInfo(RifReaderInterface::PorosityModelResultType porosityModel); diff --git a/ApplicationCode/ReservoirDataModel/RigCaseToCaseCellMapper.cpp b/ApplicationCode/ReservoirDataModel/RigCaseToCaseCellMapper.cpp new file mode 100644 index 0000000000..2bdf14543f --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/RigCaseToCaseCellMapper.cpp @@ -0,0 +1,190 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RigCaseToCaseCellMapper.h" +#include "RigCaseToCaseCellMapperTools.h" + +#include "RigFemPart.h" +#include "RigMainGrid.h" +#include "RigFemPartGrid.h" + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigCaseToCaseCellMapper::RigCaseToCaseCellMapper(RigMainGrid* masterEclGrid, RigMainGrid* dependentEclGrid) + : m_masterGrid(masterEclGrid), + m_dependentGrid(dependentEclGrid), + m_masterFemPart(NULL), + m_dependentFemPart(NULL) +{ + m_masterCellOrIntervalIndex.resize(dependentEclGrid->cells().size(), cvf::UNDEFINED_INT); + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigCaseToCaseCellMapper::RigCaseToCaseCellMapper(RigFemPart* masterFemPart, RigMainGrid* dependentEclGrid) + : m_masterGrid(NULL), + m_dependentGrid(dependentEclGrid), + m_masterFemPart(masterFemPart), + m_dependentFemPart(NULL) +{ + m_masterCellOrIntervalIndex.resize(dependentEclGrid->cells().size(), cvf::UNDEFINED_INT); + this->calculateEclToGeomCellMapping(dependentEclGrid, masterFemPart, false); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigCaseToCaseCellMapper::RigCaseToCaseCellMapper(RigFemPart* masterFemPart, RigFemPart* dependentFemPart) + : m_masterGrid(NULL), + m_dependentGrid(NULL), + m_masterFemPart(masterFemPart), + m_dependentFemPart(dependentFemPart) +{ + m_masterCellOrIntervalIndex.resize(dependentFemPart->elementCount(), cvf::UNDEFINED_INT); +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigCaseToCaseCellMapper::RigCaseToCaseCellMapper(RigMainGrid* masterEclGrid, RigFemPart* dependentFemPart) + : m_masterGrid(masterEclGrid), + m_dependentGrid(NULL), + m_masterFemPart(dependentFemPart), + m_dependentFemPart(NULL) +{ + m_masterCellOrIntervalIndex.resize(dependentFemPart->elementCount(), cvf::UNDEFINED_INT); + this->calculateEclToGeomCellMapping(masterEclGrid, dependentFemPart, true); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const int * RigCaseToCaseCellMapper::masterCaseCellIndices(int dependentCaseReservoirCellIndex, int* masterCaseCellIndexCount) const +{ + int seriesIndex = m_masterCellOrIntervalIndex[dependentCaseReservoirCellIndex]; + + if (seriesIndex == cvf::UNDEFINED_INT) + { + (*masterCaseCellIndexCount) = 0; + return NULL; + } + + if (seriesIndex < 0) + { + (*masterCaseCellIndexCount) = static_cast(m_masterCellIndexSeries[-seriesIndex].size()); + return &(m_masterCellIndexSeries[-seriesIndex][0]); + } + else + { + (*masterCaseCellIndexCount) = 1; + return &(m_masterCellOrIntervalIndex[dependentCaseReservoirCellIndex]); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigCaseToCaseCellMapper::addMapping(int depCaseCellIdx, int masterCaseMatchingCell) +{ + int mcOrSeriesIdx = m_masterCellOrIntervalIndex[depCaseCellIdx]; + if (mcOrSeriesIdx == cvf::UNDEFINED_INT) + { + m_masterCellOrIntervalIndex[depCaseCellIdx] = masterCaseMatchingCell; + } + else if (mcOrSeriesIdx >= 0) + { + int newSeriesIdx = static_cast(m_masterCellIndexSeries.size()); + m_masterCellIndexSeries.push_back(std::vector()); + m_masterCellIndexSeries.back().push_back(mcOrSeriesIdx); + m_masterCellIndexSeries.back().push_back(masterCaseMatchingCell); + m_masterCellOrIntervalIndex[depCaseCellIdx] = -newSeriesIdx; + } + else if (mcOrSeriesIdx < 0) + { + m_masterCellIndexSeries[-mcOrSeriesIdx].push_back(masterCaseMatchingCell); + } + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigCaseToCaseCellMapper::calculateEclToGeomCellMapping(RigMainGrid* masterEclGrid, RigFemPart* dependentFemPart, bool eclipseIsMaster) +{ + // Find tolerance + + double cellSizeI, cellSizeJ, cellSizeK; + masterEclGrid->characteristicCellSizes(&cellSizeI, &cellSizeJ, &cellSizeK); + + double xyTolerance = cellSizeI* 0.4; + double zTolerance = cellSizeK* 0.4; + + bool isEclFaceNormalsOutwards = masterEclGrid->isFaceNormalsOutwards(); + + cvf::Vec3d elmCorners[8]; + + size_t cellCount = masterEclGrid->cellCount(); + + for (size_t cellIdx = 0; cellIdx < cellCount; ++cellIdx) + { + #ifdef _DEBUG + { + // For debugging + size_t i, j, k; + masterEclGrid->ijkFromCellIndex(cellIdx, &i, &j, &k); // Will not work when LGR present + } + #endif + + cvf::Vec3d geoMechConvertedEclCell[8]; + RigCaseToCaseCellMapperTools::estimatedFemCellFromEclCell(masterEclGrid, cellIdx, geoMechConvertedEclCell); + + cvf::BoundingBox elmBBox; + for (int i = 0; i < 8 ; ++i) elmBBox.add(geoMechConvertedEclCell[i]); + + std::vector closeElements; + dependentFemPart->findIntersectingCells(elmBBox, &closeElements); + + for (size_t ccIdx = 0; ccIdx < closeElements.size(); ++ccIdx) + { + int elmIdx = static_cast(closeElements[ccIdx]); + + RigCaseToCaseCellMapperTools::elementCorners(dependentFemPart, elmIdx, elmCorners); + + RigCaseToCaseCellMapperTools::rotateCellTopologicallyToMatchBaseCell(geoMechConvertedEclCell, isEclFaceNormalsOutwards , elmCorners); + + bool isMatching = RigCaseToCaseCellMapperTools::isEclFemCellsMatching(geoMechConvertedEclCell, elmCorners, + xyTolerance, zTolerance); + + if (isMatching) + { + if (eclipseIsMaster) + addMapping(elmIdx, static_cast(cellIdx)); + else + addMapping(static_cast(cellIdx), elmIdx); + + break; + } + } + } +} diff --git a/ApplicationCode/ReservoirDataModel/RigCaseToCaseCellMapper.h b/ApplicationCode/ReservoirDataModel/RigCaseToCaseCellMapper.h new file mode 100644 index 0000000000..b81bc1c03a --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/RigCaseToCaseCellMapper.h @@ -0,0 +1,64 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cvfBase.h" +#include "cvfObject.h" +#include "cvfMath.h" +#include "cvfVector3.h" + +#include + +class RigMainGrid; +class RigFemPart; + + +//================================================================================================== +/// +//================================================================================================== +class RigCaseToCaseCellMapper : public cvf::Object +{ +public: + RigCaseToCaseCellMapper(RigMainGrid* masterEclGrid, RigFemPart* dependentFemPart); + RigCaseToCaseCellMapper(RigMainGrid* masterEclGrid, RigMainGrid* dependentEclGrid); + RigCaseToCaseCellMapper(RigFemPart* masterFemPart, RigMainGrid* dependentEclGrid); + RigCaseToCaseCellMapper(RigFemPart* masterFemPart, RigFemPart* dependentFemPart); + + const int * masterCaseCellIndices(int dependentCaseReservoirCellIndex, int* masterCaseCellIndexCount) const; + + const RigMainGrid* masterGrid() const { return m_masterGrid;} + const RigMainGrid* dependentGrid() const { return m_dependentGrid;} + const RigFemPart* masterFemPart() const { return m_masterFemPart;} + const RigFemPart* dependentFemPart() const { return m_dependentFemPart;} + +private: + + void addMapping(int depCaseCellIdx, int masterCaseMatchingCell); + void calculateEclToGeomCellMapping(RigMainGrid* masterEclGrid, RigFemPart* dependentFemPart, bool eclipseIsMaster); + + std::vector m_masterCellOrIntervalIndex; + std::vector > m_masterCellIndexSeries; + + RigMainGrid* m_masterGrid; + RigMainGrid* m_dependentGrid; + RigFemPart* m_masterFemPart; + RigFemPart* m_dependentFemPart; + +}; diff --git a/ApplicationCode/ReservoirDataModel/RigCaseToCaseCellMapperTools.cpp b/ApplicationCode/ReservoirDataModel/RigCaseToCaseCellMapperTools.cpp new file mode 100644 index 0000000000..2b352274ff --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/RigCaseToCaseCellMapperTools.cpp @@ -0,0 +1,492 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RigCaseToCaseCellMapper.h" +#include "RigCaseToCaseCellMapperTools.h" + +#include "RigFemPart.h" +#include "RigMainGrid.h" +#include "RigFemPartGrid.h" + + +//================================================================================================== +/// +//================================================================================================== + +class RigNeighborCornerFinder +{ +public: + RigNeighborCornerFinder(const RigMainGrid* mainGrid, size_t baseI, size_t baseJ, size_t baseK) + : m_mainGrid(mainGrid), + m_baseI(baseI), + m_baseJ(baseJ), + m_baseK(baseK) + {} + + const caf::SizeTArray8* neighborIndices(int offsetI, int offsetJ, int offsetK) + { + if (offsetI < 0 && m_baseI == 0) return NULL; + if (offsetJ < 0 && m_baseJ == 0) return NULL; + if (offsetK < 0 && m_baseK == 0) return NULL; + if (offsetI > 0 && m_baseI == m_mainGrid->cellCountI()-1) return NULL; + if (offsetJ > 0 && m_baseJ == m_mainGrid->cellCountJ()-1) return NULL; + if (offsetK > 0 && m_baseK == m_mainGrid->cellCountK()-1) return NULL; + + size_t gridLocalCellIndex = m_mainGrid->cellIndexFromIJK(m_baseI + offsetI, m_baseJ + offsetJ, m_baseK + offsetK); + const RigCell& cell = m_mainGrid->cells()[gridLocalCellIndex]; + return &(cell.cornerIndices()); + } + +private: + const RigMainGrid* m_mainGrid; + size_t m_baseI; + size_t m_baseJ; + size_t m_baseK; +}; + +//================================================================================================== +/// +//================================================================================================== + +//-------------------------------------------------------------------------------------------------- +/// Average of neighbor corresponding nodes +//-------------------------------------------------------------------------------------------------- +void RigCaseToCaseCellMapperTools::estimatedFemCellFromEclCell(const RigMainGrid* eclGrid, size_t reservoirCellIndex, cvf::Vec3d estimatedElmCorners[8]) +{ + CVF_TIGHT_ASSERT(reservoirCellIndex < eclGrid->cellCount()); // Assume reservoirCellIdx == localGridCellIdx for maingrid + + const std::vector& eclNodes = eclGrid->nodes(); + + size_t I,J,K; + eclGrid->ijkFromCellIndex(reservoirCellIndex, &I, &J, &K); + RigNeighborCornerFinder nbFinder(eclGrid, I,J,K); + + // Cell corner Averaging mapping: Local cell index in neighbor matching specific corner of this cell + // N - Negative P - positive + // 0 <- NI[1] NINJ[2] NJ[3] NK[4] NINK[5] NINJNK[6] NJNK[7] + // 1 <- NJ[2] PINJ[3] PI[0] NK[5] NJNK[6] PINJNK[7] PINK[4] + // 2 <- PI[3] PIPJ[0] PJ[1] NK[6] PINK[7] PIPJNK[4] PJNK[5] + // 3 <- PJ[0] NIPJ[1] NI[2] NK[7] PJNK[4] NIPJNK[5] NINK[6] + // 4 <- NI[5] NINJ[6] NJ[7] PK[0] NIPK[1] NINJPK[2] NJPK[3] + // 5 <- NJ[6] PINJ[7] PI[4] PK[1] NJPK[2] PINJPK[3] PIPK[0] + // 6 <- PI[7] PIPJ[4] PJ[5] PK[2] PIPK[3] PIPJPK[0] PJPK[1] + // 7 <- PJ[4] NIPJ[5] NI[6] PK[3] PJPK[0] NIPJPK[1] NIPK[2] + + const caf::SizeTArray8* IJK = nbFinder.neighborIndices( 0, 0, 0); + const caf::SizeTArray8* NI = nbFinder.neighborIndices(-1, 0, 0); + const caf::SizeTArray8* NJ = nbFinder.neighborIndices( 0,-1, 0); + const caf::SizeTArray8* PI = nbFinder.neighborIndices( 1, 0, 0); + const caf::SizeTArray8* PJ = nbFinder.neighborIndices( 0, 1, 0); + const caf::SizeTArray8* NK = nbFinder.neighborIndices( 0, 0,-1); + const caf::SizeTArray8* PK = nbFinder.neighborIndices( 0, 0, 1); + const caf::SizeTArray8* NINJ = nbFinder.neighborIndices(-1,-1, 0); + const caf::SizeTArray8* PINJ = nbFinder.neighborIndices( 1,-1, 0); + + const caf::SizeTArray8* PIPJ = nbFinder.neighborIndices( 1, 1, 0); + const caf::SizeTArray8* NIPJ = nbFinder.neighborIndices(-1, 1, 0); + const caf::SizeTArray8* NINK = nbFinder.neighborIndices(-1, 0,-1); + const caf::SizeTArray8* NJNK = nbFinder.neighborIndices( 0,-1,-1); + const caf::SizeTArray8* PINK = nbFinder.neighborIndices( 1, 0,-1); + const caf::SizeTArray8* PJNK = nbFinder.neighborIndices( 0, 1,-1); + const caf::SizeTArray8* NIPK = nbFinder.neighborIndices(-1, 0, 1); + const caf::SizeTArray8* NJPK = nbFinder.neighborIndices( 0,-1, 1); + const caf::SizeTArray8* PIPK = nbFinder.neighborIndices( 1, 0, 1); + + const caf::SizeTArray8* PJPK = nbFinder.neighborIndices( 0, 1, 1); + const caf::SizeTArray8* NINJNK = nbFinder.neighborIndices(-1,-1,-1); + const caf::SizeTArray8* PINJNK = nbFinder.neighborIndices( 1,-1,-1); + const caf::SizeTArray8* PIPJNK = nbFinder.neighborIndices( 1, 1,-1); + const caf::SizeTArray8* NIPJNK = nbFinder.neighborIndices(-1, 1,-1); + const caf::SizeTArray8* NINJPK = nbFinder.neighborIndices(-1,-1, 1); + const caf::SizeTArray8* PINJPK = nbFinder.neighborIndices( 1,-1, 1); + const caf::SizeTArray8* PIPJPK = nbFinder.neighborIndices( 1, 1, 1); + const caf::SizeTArray8* NIPJPK = nbFinder.neighborIndices(-1, 1, 1); + + std::vector contributingNodeIndicesPrCellCorner[8]; + + if (IJK ) contributingNodeIndicesPrCellCorner[0].push_back((*IJK )[0]); + if (NI ) contributingNodeIndicesPrCellCorner[0].push_back((*NI )[1]); + if (NINJ ) contributingNodeIndicesPrCellCorner[0].push_back((*NINJ )[2]); + if (NJ ) contributingNodeIndicesPrCellCorner[0].push_back((*NJ )[3]); + if (NK ) contributingNodeIndicesPrCellCorner[0].push_back((*NK )[4]); + if (NINK ) contributingNodeIndicesPrCellCorner[0].push_back((*NINK )[5]); + if (NINJNK) contributingNodeIndicesPrCellCorner[0].push_back((*NINJNK)[6]); + if (NJNK ) contributingNodeIndicesPrCellCorner[0].push_back((*NJNK )[7]); + + if (IJK ) contributingNodeIndicesPrCellCorner[1].push_back((*IJK )[1]); + if (NJ ) contributingNodeIndicesPrCellCorner[1].push_back((*NJ )[2]); + if (PINJ ) contributingNodeIndicesPrCellCorner[1].push_back((*PINJ )[3]); + if (PI ) contributingNodeIndicesPrCellCorner[1].push_back((*PI )[0]); + if (NK ) contributingNodeIndicesPrCellCorner[1].push_back((*NK )[5]); + if (NJNK ) contributingNodeIndicesPrCellCorner[1].push_back((*NJNK )[6]); + if (PINJNK) contributingNodeIndicesPrCellCorner[1].push_back((*PINJNK)[7]); + if (PINK ) contributingNodeIndicesPrCellCorner[1].push_back((*PINK )[4]); + + if (IJK ) contributingNodeIndicesPrCellCorner[2].push_back((*IJK )[2]); + if (PI ) contributingNodeIndicesPrCellCorner[2].push_back((*PI )[3]); + if (PIPJ ) contributingNodeIndicesPrCellCorner[2].push_back((*PIPJ )[0]); + if (PJ ) contributingNodeIndicesPrCellCorner[2].push_back((*PJ )[1]); + if (NK ) contributingNodeIndicesPrCellCorner[2].push_back((*NK )[6]); + if (PINK ) contributingNodeIndicesPrCellCorner[2].push_back((*PINK )[7]); + if (PIPJNK) contributingNodeIndicesPrCellCorner[2].push_back((*PIPJNK)[4]); + if (PJNK ) contributingNodeIndicesPrCellCorner[2].push_back((*PJNK )[5]); + + if (IJK ) contributingNodeIndicesPrCellCorner[3].push_back((*IJK )[3]); + if (PJ ) contributingNodeIndicesPrCellCorner[3].push_back((*PJ )[0]); + if (NIPJ ) contributingNodeIndicesPrCellCorner[3].push_back((*NIPJ )[1]); + if (NI ) contributingNodeIndicesPrCellCorner[3].push_back((*NI )[2]); + if (NK ) contributingNodeIndicesPrCellCorner[3].push_back((*NK )[7]); + if (PJNK ) contributingNodeIndicesPrCellCorner[3].push_back((*PJNK )[4]); + if (NIPJNK) contributingNodeIndicesPrCellCorner[3].push_back((*NIPJNK)[5]); + if (NINK ) contributingNodeIndicesPrCellCorner[3].push_back((*NINK )[6]); + + // 4 <- NI[5] NINJ[6] NJ[7] PK[0] NIPK[1] NINJPK[2] NJPK[3] + + if (IJK ) contributingNodeIndicesPrCellCorner[4].push_back((*IJK )[4]); + if (NI ) contributingNodeIndicesPrCellCorner[4].push_back((*NI )[5]); + if (NINJ ) contributingNodeIndicesPrCellCorner[4].push_back((*NINJ )[6]); + if (NJ ) contributingNodeIndicesPrCellCorner[4].push_back((*NJ )[7]); + if (PK ) contributingNodeIndicesPrCellCorner[4].push_back((*PK )[0]); + if (NIPK ) contributingNodeIndicesPrCellCorner[4].push_back((*NIPK )[1]); + if (NINJPK) contributingNodeIndicesPrCellCorner[4].push_back((*NINJPK)[2]); + if (NJPK ) contributingNodeIndicesPrCellCorner[4].push_back((*NJPK )[3]); + + if (IJK ) contributingNodeIndicesPrCellCorner[5].push_back((*IJK )[5]); + if (NJ ) contributingNodeIndicesPrCellCorner[5].push_back((*NJ )[6]); + if (PINJ ) contributingNodeIndicesPrCellCorner[5].push_back((*PINJ )[7]); + if (PI ) contributingNodeIndicesPrCellCorner[5].push_back((*PI )[4]); + if (PK ) contributingNodeIndicesPrCellCorner[5].push_back((*PK )[1]); + if (NJPK ) contributingNodeIndicesPrCellCorner[5].push_back((*NJPK )[2]); + if (PINJPK) contributingNodeIndicesPrCellCorner[5].push_back((*PINJPK)[3]); + if (PIPK ) contributingNodeIndicesPrCellCorner[5].push_back((*PIPK )[0]); + + // 6 <- PI[7] PIPJ[4] PJ[5] PK[2] PIPK[3] PIPJPK[0] PJPK[1] + + if (IJK ) contributingNodeIndicesPrCellCorner[6].push_back((*IJK )[6]); + if (PI ) contributingNodeIndicesPrCellCorner[6].push_back((*PI )[7]); + if (PIPJ ) contributingNodeIndicesPrCellCorner[6].push_back((*PIPJ )[4]); + if (PJ ) contributingNodeIndicesPrCellCorner[6].push_back((*PJ )[5]); + if (PK ) contributingNodeIndicesPrCellCorner[6].push_back((*PK )[2]); + if (PIPK ) contributingNodeIndicesPrCellCorner[6].push_back((*PIPK )[3]); + if (PIPJPK) contributingNodeIndicesPrCellCorner[6].push_back((*PIPJPK)[0]); + if (PJPK ) contributingNodeIndicesPrCellCorner[6].push_back((*PJPK )[1]); + + if (IJK ) contributingNodeIndicesPrCellCorner[7].push_back((*IJK )[7]); + if (PJ ) contributingNodeIndicesPrCellCorner[7].push_back((*PJ )[4]); + if (NIPJ ) contributingNodeIndicesPrCellCorner[7].push_back((*NIPJ )[5]); + if (NI ) contributingNodeIndicesPrCellCorner[7].push_back((*NI )[6]); + if (PK ) contributingNodeIndicesPrCellCorner[7].push_back((*PK )[3]); + if (PJPK ) contributingNodeIndicesPrCellCorner[7].push_back((*PJPK )[0]); + if (NIPJPK) contributingNodeIndicesPrCellCorner[7].push_back((*NIPJPK)[1]); + if (NIPK ) contributingNodeIndicesPrCellCorner[7].push_back((*NIPK )[2]); + + // Average the nodes + for (size_t cornIdx = 0; cornIdx < 8; ++cornIdx) + { + estimatedElmCorners[cornIdx] = cvf::Vec3d::ZERO; + size_t contribCount = contributingNodeIndicesPrCellCorner[cornIdx].size(); + for (size_t ctnIdx = 0; ctnIdx < contribCount; ++ctnIdx) + { + estimatedElmCorners[cornIdx] += eclNodes[contributingNodeIndicesPrCellCorner[cornIdx][ctnIdx]]; + } + estimatedElmCorners[cornIdx] /= contribCount; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigCaseToCaseCellMapperTools::rotateQuad(cvf::Vec3d quad[4], int idxToNewStart) +{ + if (idxToNewStart == 0) return; + cvf::Vec3d tmpQuad[4]; + tmpQuad[0] = quad[0]; + tmpQuad[1] = quad[1]; + tmpQuad[2] = quad[2]; + tmpQuad[3] = quad[3]; + + quad[0] = tmpQuad[idxToNewStart]; + ++idxToNewStart; if (idxToNewStart > 3) idxToNewStart = 0; + quad[1] = tmpQuad[idxToNewStart]; + ++idxToNewStart; if (idxToNewStart > 3) idxToNewStart = 0; + quad[2] = tmpQuad[idxToNewStart]; + ++idxToNewStart; if (idxToNewStart > 3) idxToNewStart = 0; + quad[3] = tmpQuad[idxToNewStart]; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigCaseToCaseCellMapperTools::flipQuadWinding(cvf::Vec3d quad[4]) +{ + cvf::Vec3d temp = quad[1]; + quad[1] = quad[3]; + quad[3] = temp; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +int RigCaseToCaseCellMapperTools::quadVxClosestToXYOfPoint( const cvf::Vec3d point, const cvf::Vec3d quad[4]) +{ + double minSqDist = HUGE_VAL; + int quadVxIdxClosestToPoint = cvf::UNDEFINED_INT; + + for (int i = 0; i < 4; ++i) + { + cvf::Vec3d diff = quad[i]- point; + diff[2] = 0.0; + + double sqDist = diff.lengthSquared(); + if (sqDist < minSqDist) + { + minSqDist = sqDist; + quadVxIdxClosestToPoint = i; + } + } + + return quadVxIdxClosestToPoint; +} +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RigCaseToCaseCellMapperTools::elementCorners(const RigFemPart* femPart, int elmIdx, cvf::Vec3d elmCorners[8]) +{ + RigElementType elmType = femPart->elementType(elmIdx); + if (!(elmType == HEX8 || elmType == HEX8P)) return false; + + const std::vector& nodeCoords = femPart->nodes().coordinates; + const int* cornerIndices = femPart->connectivities(elmIdx); + + elmCorners[0] = cvf::Vec3d(nodeCoords[cornerIndices[0]]); + elmCorners[1] = cvf::Vec3d(nodeCoords[cornerIndices[1]]); + elmCorners[2] = cvf::Vec3d(nodeCoords[cornerIndices[2]]); + elmCorners[3] = cvf::Vec3d(nodeCoords[cornerIndices[3]]); + elmCorners[4] = cvf::Vec3d(nodeCoords[cornerIndices[4]]); + elmCorners[5] = cvf::Vec3d(nodeCoords[cornerIndices[5]]); + elmCorners[6] = cvf::Vec3d(nodeCoords[cornerIndices[6]]); + elmCorners[7] = cvf::Vec3d(nodeCoords[cornerIndices[7]]); + + return true; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +int RigCaseToCaseCellMapperTools::findMatchingPOSKFaceIdx(const cvf::Vec3d baseCell[8],bool isBaseCellNormalsOutwards, const cvf::Vec3d c2[8]) +{ + int faceNodeCount; + const int* posKFace = RigFemTypes::localElmNodeIndicesForFace(HEX8, (int)(cvf::StructGridInterface::POS_K), &faceNodeCount); + + double sign = isBaseCellNormalsOutwards ? 1.0 : -1.0; + + cvf::Vec3d posKnormal = sign*(baseCell[posKFace[2]] - baseCell[posKFace[0]]) ^ (baseCell[posKFace[3]] - baseCell[posKFace[1]]); + posKnormal.normalize(); + + double minDiff = HUGE_VAL; + int bestFace = -1; + for (int faceIdx = 5; faceIdx >= 0; --faceIdx) // Backwards. might hit earlier more often + { + const int* face = RigFemTypes::localElmNodeIndicesForFace(HEX8, faceIdx, &faceNodeCount); + cvf::Vec3d normal = (c2[face[2]] - c2[face[0]]) ^ (c2[face[3]] - c2[face[1]]); + normal.normalize(); + double sqDiff = (posKnormal-normal).lengthSquared(); + if (sqDiff < minDiff) + { + minDiff = sqDiff; + bestFace = faceIdx; + if (minDiff < 0.1*0.1) break; // This must be the one. Do not search further + } + } + + return bestFace; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RigCaseToCaseCellMapperTools::isEclFemCellsMatching(const cvf::Vec3d baseCell[8], + cvf::Vec3d cell[8], + double xyTolerance, double zTolerance) +{ + + bool isMatching = true; + + for (int i = 0; i < 4 ; ++i) + { + cvf::Vec3d diff = cell[i] - baseCell[i]; + + if (!(fabs(diff.x()) < xyTolerance && fabs(diff.y()) < xyTolerance && fabs(diff.z()) < zTolerance)) + { + isMatching = false; + break; + } + } + + return isMatching; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigCaseToCaseCellMapperTools::rotateCellTopologicallyToMatchBaseCell(const cvf::Vec3d * baseCell, bool baseCellFaceNormalsIsOutwards, cvf::Vec3d * cell) +{ + int femDeepZFaceIdx = findMatchingPOSKFaceIdx(baseCell, baseCellFaceNormalsIsOutwards, cell); + + { + cvf::Vec3d tmpFemCorners[8]; + tmpFemCorners[0] = cell[0]; + tmpFemCorners[1] = cell[1]; + tmpFemCorners[2] = cell[2]; + tmpFemCorners[3] = cell[3]; + tmpFemCorners[4] = cell[4]; + tmpFemCorners[5] = cell[5]; + tmpFemCorners[6] = cell[6]; + tmpFemCorners[7] = cell[7]; + + int femShallowZFaceIdx = RigFemTypes::oppositeFace(HEX8, femDeepZFaceIdx); + + int faceNodeCount; + const int* localElmNodeIndicesForPOSKFace = RigFemTypes::localElmNodeIndicesForFace(HEX8, femDeepZFaceIdx, &faceNodeCount); + const int* localElmNodeIndicesForNEGKFace = RigFemTypes::localElmNodeIndicesForFace(HEX8, femShallowZFaceIdx, &faceNodeCount); + + cell[0] = tmpFemCorners[localElmNodeIndicesForNEGKFace[0]]; + cell[1] = tmpFemCorners[localElmNodeIndicesForNEGKFace[1]]; + cell[2] = tmpFemCorners[localElmNodeIndicesForNEGKFace[2]]; + cell[3] = tmpFemCorners[localElmNodeIndicesForNEGKFace[3]]; + cell[4] = tmpFemCorners[localElmNodeIndicesForPOSKFace[0]]; + cell[5] = tmpFemCorners[localElmNodeIndicesForPOSKFace[1]]; + cell[6] = tmpFemCorners[localElmNodeIndicesForPOSKFace[2]]; + cell[7] = tmpFemCorners[localElmNodeIndicesForPOSKFace[3]]; + } + + cvf::Vec3d* femDeepestQuad = &(cell[4]); + cvf::Vec3d* femShallowQuad = &(cell[0]); + + // Now the top/bottom have opposite winding. To make the comparisons and index rotations simpler + // flip the winding of the top or bottom face depending on whether the eclipse grid is inside-out + + if (baseCellFaceNormalsIsOutwards) + { + flipQuadWinding(femShallowQuad); + } + else + { + flipQuadWinding(femDeepestQuad); + } + + // We now need to rotate the fem quads to be alligned with the ecl quads + // Since the start point of the quad always is aligned with the opposite face-quad start + // we can find the rotation for the top, and apply it to both top and bottom + + int femQuadStartIdx = quadVxClosestToXYOfPoint(baseCell[0], femShallowQuad); + rotateQuad(femDeepestQuad, femQuadStartIdx); + rotateQuad(femShallowQuad, femQuadStartIdx); + +} + + +#if 0 // Inside Bounding box test +cvf::BoundingBox cellBBox; +for (int i = 0; i < 8 ; ++i) cellBBox.add(cellCorners[i]); + +cvf::Vec3d cs = cellBBox.min(); +cvf::Vec3d cl = cellBBox.max(); +cvf::Vec3d es = elmBBox.min(); +cvf::Vec3d el = elmBBox.max(); + +if ( ( (cs.x() + xyTolerance) >= es.x() && (cl.x() - xyTolerance) <= el.x()) + && ( (cs.y() + xyTolerance) >= es.y() && (cl.y() - xyTolerance) <= el.y()) + && ( (cs.z() + zTolerance ) >= es.z() && (cl.z() - zTolerance ) <= el.z()) ) +{ + // Cell bb equal or inside Elm bb + isMatching = true; +} + +if ( ( (es.x() + xyTolerance) >= cs.x() && (el.x() - xyTolerance) <= cl.x()) + && ( (es.y() + xyTolerance) >= cs.y() && (el.y() - xyTolerance) <= cl.y()) + && ( (es.z() + zTolerance ) >= cs.z() && (el.z() - zTolerance ) <= cl.z()) ) +{ + // Elm bb equal or inside Cell bb + isMatching = true; +} +#endif + +#if 0 + { + const std::vector& eclNodes = eclGrid->nodes(); + const RigCell& cell = eclGrid->cells()[reservoirCellIndex]; + const caf::SizeTArray8& cornerIndices = cell.cornerIndices(); + int faceNodeCount; + const int* localElmNodeIndicesForTopZFace = RigFemTypes::localElmNodeIndicesForFace(HEX8, 4, &faceNodeCount); + const int* localElmNodeIndicesForBotZFace = RigFemTypes::localElmNodeIndicesForFace(HEX8, 5, &faceNodeCount); + + eclDeepestQuad[0] = eclNodes[cornerIndices[localElmNodeIndicesForTopZFace[0]]]; + eclDeepestQuad[1] = eclNodes[cornerIndices[localElmNodeIndicesForTopZFace[1]]]; + eclDeepestQuad[2] = eclNodes[cornerIndices[localElmNodeIndicesForTopZFace[2]]]; + eclDeepestQuad[3] = eclNodes[cornerIndices[localElmNodeIndicesForTopZFace[3]]]; + + eclShallowQuad[0] = eclNodes[cornerIndices[localElmNodeIndicesForBotZFace[0]]]; + eclShallowQuad[1] = eclNodes[cornerIndices[localElmNodeIndicesForBotZFace[1]]]; + eclShallowQuad[2] = eclNodes[cornerIndices[localElmNodeIndicesForBotZFace[2]]]; + eclShallowQuad[3] = eclNodes[cornerIndices[localElmNodeIndicesForBotZFace[3]]]; + } +#endif + +#if 0 +// First search K=1 diagonally for a seed cell; A cell without collapsings, and without faults + +size_t minIJCount = masterEclGrid->cellCountI(); +if (minIJCount > masterEclGrid->cellCountJ()) +minIJCount = masterEclGrid->cellCountJ(); + +for (size_t ij = 0; ij < minIJCount; ++ij ) +{ + size_t localCellIdx = masterEclGrid->cellIndexFromIJK(ij, ij, 0); + size_t reservoirCellIdx = masterEclGrid->reservoirCellIndex(localCellIdx); + + cvf::Vec3d vertices[8]; + masterEclGrid->cellCornerVertices(localCellIdx, vertices); + if (!isCellNormal(vertices)) + continue; + + const RigFault* fault = masterEclGrid->findFaultFromCellIndexAndCellFace(reservoirCellIdx, cvf::StructGridInterface::POS_I); + +} +#endif + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +cvf::Vec3d RigCaseToCaseCellMapperTools::calculateCellCenter(cvf::Vec3d elmCorners[8]) +{ + cvf::Vec3d avg(cvf::Vec3d::ZERO); + + size_t i; + for (i = 0; i < 8; i++) + { + avg += elmCorners[i]; + } + + avg /= 8.0; + + return avg; +} + + diff --git a/ApplicationCode/ReservoirDataModel/RigCaseToCaseCellMapperTools.h b/ApplicationCode/ReservoirDataModel/RigCaseToCaseCellMapperTools.h new file mode 100644 index 0000000000..286a50d2a9 --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/RigCaseToCaseCellMapperTools.h @@ -0,0 +1,54 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cvfBase.h" +#include "cvfObject.h" +#include "cvfMath.h" +#include "cvfVector3.h" + +#include + +class RigMainGrid; +class RigFemPart; + + +//================================================================================================== +/// +//================================================================================================== + +class RigCaseToCaseCellMapperTools +{ +public: + + static void estimatedFemCellFromEclCell(const RigMainGrid* eclGrid, size_t reservoirCellIndex, cvf::Vec3d estimatedElmCorners[8]); + static void rotateCellTopologicallyToMatchBaseCell(const cvf::Vec3d * baseCell, bool baseCellFaceNormalsIsOutwards, cvf::Vec3d * cell); + static cvf::Vec3d calculateCellCenter(cvf::Vec3d elmCorners[8]); + static bool elementCorners(const RigFemPart* femPart, int elmIdx, cvf::Vec3d elmCorners[8]); + static bool isEclFemCellsMatching(const cvf::Vec3d baseCell[8], cvf::Vec3d cell[8], double xyTolerance, double zTolerance); + +private: + static void rotateQuad(cvf::Vec3d quad[4], int idxToNewStart); + static void flipQuadWinding(cvf::Vec3d quad[4]); + static int quadVxClosestToXYOfPoint(const cvf::Vec3d point, const cvf::Vec3d quad[4]); + static int findMatchingPOSKFaceIdx(const cvf::Vec3d baseCell[8], bool isBaseCellNormalsOutwards, const cvf::Vec3d c2[8]); + +}; + diff --git a/ApplicationCode/ReservoirDataModel/RigCaseToCaseRangeFilterMapper.cpp b/ApplicationCode/ReservoirDataModel/RigCaseToCaseRangeFilterMapper.cpp new file mode 100644 index 0000000000..b4f46328ce --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/RigCaseToCaseRangeFilterMapper.cpp @@ -0,0 +1,490 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RigCaseToCaseRangeFilterMapper.h" +#include "RigCaseToCaseCellMapper.h" +#include "RigCaseToCaseCellMapperTools.h" + +#include "RigFemPart.h" +#include "RigMainGrid.h" +#include "RigFemPartGrid.h" + + +#include "RimCellRangeFilter.h" + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigCaseToCaseRangeFilterMapper::convertRangeFilterEclToFem(RimCellRangeFilter* srcFilter, const RigMainGrid* srcEclGrid, + RimCellRangeFilter* dstFilter, const RigFemPart* dstFemPart) +{ + convertRangeFilter(srcFilter, dstFilter, srcEclGrid, dstFemPart, true); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigCaseToCaseRangeFilterMapper::convertRangeFilterFemToEcl(RimCellRangeFilter* srcFilter, const RigFemPart* srcFemPart, + RimCellRangeFilter* dstFilter, const RigMainGrid* dstEclGrid) +{ + convertRangeFilter(srcFilter, dstFilter, dstEclGrid, srcFemPart, false); +} + +struct RigRangeEndPoints +{ + RigRangeEndPoints() + : StartI(cvf::UNDEFINED_SIZE_T), + StartJ(cvf::UNDEFINED_SIZE_T), + StartK(cvf::UNDEFINED_SIZE_T), + EndI(cvf::UNDEFINED_SIZE_T), + EndJ(cvf::UNDEFINED_SIZE_T), + EndK(cvf::UNDEFINED_SIZE_T) + {} + + size_t StartI; + size_t StartJ; + size_t StartK; + size_t EndI ; + size_t EndJ ; + size_t EndK ; +}; + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- + +void RigCaseToCaseRangeFilterMapper::convertRangeFilter(const RimCellRangeFilter* srcFilter, + RimCellRangeFilter* dstFilter, + const RigMainGrid* eclGrid, + const RigFemPart* femPart, + bool femIsDestination) +{ + CVF_ASSERT(srcFilter && eclGrid && dstFilter && femPart); + CVF_ASSERT(srcFilter->gridIndex() == 0); // LGR not supported yet + + + RigRangeEndPoints src; + // Convert the (start, count) range filter vars to end point cell ijk + { + src.StartI = srcFilter->startIndexI() - 1; + src.StartJ = srcFilter->startIndexJ() - 1; + src.StartK = srcFilter->startIndexK() - 1; + + // Needs to subtract one more to have the end idx beeing + // the last cell in the selection, not the first outside + src.EndI = src.StartI + srcFilter->cellCountI() - 1; + src.EndJ = src.StartJ + srcFilter->cellCountJ() - 1; + src.EndK = src.StartK + srcFilter->cellCountK() - 1; + } + + // Clamp the src end points to be inside the src model + { + size_t maxIIndex; + size_t maxJIndex; + size_t maxKIndex; + + // Clamp end + if (femIsDestination) + { + maxIIndex = eclGrid->cellCountI()- 1; + maxJIndex = eclGrid->cellCountJ()- 1; + maxKIndex = eclGrid->cellCountK()- 1; + } + else + { + maxIIndex = femPart->structGrid()->cellCountI()- 1; + maxJIndex = femPart->structGrid()->cellCountJ()- 1; + maxKIndex = femPart->structGrid()->cellCountK()- 1; + + } + src.EndI = CVF_MIN(src.EndI, maxIIndex); + src.EndJ = CVF_MIN(src.EndJ, maxJIndex); + src.EndK = CVF_MIN(src.EndK, maxKIndex); + } + + // When using femPart as source we need to clamp the fem srcRange filter + // to the extents of the ecl grid within the fem part before + // doing the mapping. If not, the range filter corners will most likely be outside + // the ecl grid, resulting in an undefined conversion. + if (!femIsDestination) + { + RigRangeEndPoints eclMaxMin; + eclMaxMin.StartI = 0; + eclMaxMin.StartJ = 0; + eclMaxMin.StartK = 0; + eclMaxMin.EndI = eclGrid->cellCountI() - 1; + eclMaxMin.EndJ = eclGrid->cellCountJ() - 1; + eclMaxMin.EndK = eclGrid->cellCountK() - 1; + RigRangeEndPoints eclExtInFem; + + convertRangeFilterEndPoints(eclMaxMin, eclExtInFem, eclGrid, femPart, true); + + src.StartI = CVF_MAX(src.StartI, eclExtInFem.StartI); + src.StartJ = CVF_MAX(src.StartJ, eclExtInFem.StartJ); + src.StartK = CVF_MAX(src.StartK, eclExtInFem.StartK); + src.EndI = CVF_MIN(src.EndI , eclExtInFem.EndI); + src.EndJ = CVF_MIN(src.EndJ , eclExtInFem.EndJ); + src.EndK = CVF_MIN(src.EndK , eclExtInFem.EndK); + } + + RigRangeEndPoints dst; + + convertRangeFilterEndPoints(src, dst, eclGrid, femPart, femIsDestination); + + // Populate the dst range filter with new data + + if ( dst.StartI != cvf::UNDEFINED_SIZE_T + && dst.StartJ != cvf::UNDEFINED_SIZE_T + && dst.StartK != cvf::UNDEFINED_SIZE_T + && dst.EndI != cvf::UNDEFINED_SIZE_T + && dst.EndJ != cvf::UNDEFINED_SIZE_T + && dst.EndK != cvf::UNDEFINED_SIZE_T) + { + dstFilter->startIndexI = static_cast(dst.StartI + 1); + dstFilter->startIndexJ = static_cast(dst.StartJ + 1); + dstFilter->startIndexK = static_cast(dst.StartK + 1); + + dstFilter->cellCountI = static_cast(dst.EndI - (dst.StartI-1)); + dstFilter->cellCountJ = static_cast(dst.EndJ - (dst.StartJ-1)); + dstFilter->cellCountK = static_cast(dst.EndK - (dst.StartK-1)); + } + else + { + dstFilter->startIndexI = 1; + dstFilter->startIndexJ = 1; + dstFilter->startIndexK = 1; + + dstFilter->cellCountI = 0; + dstFilter->cellCountJ = 0; + dstFilter->cellCountK = 0; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigCaseToCaseRangeFilterMapper::convertRangeFilterEndPoints(const RigRangeEndPoints &src, + RigRangeEndPoints &dst, + const RigMainGrid* eclGrid, + const RigFemPart* femPart, + bool femIsDestination) +{ + { + struct RangeFilterCorner { RangeFilterCorner() : cellMatchType(APPROX_ON_COLLAPSED){} cvf::Vec3st ijk; CellMatchType cellMatchType; }; + + RangeFilterCorner rangeFilterMatches[8]; + + cvf::Vec3st srcRangeCube[8]; + srcRangeCube[0] = cvf::Vec3st(src.StartI, src.StartJ, src.StartK); + srcRangeCube[1] = cvf::Vec3st(src.EndI , src.StartJ, src.StartK); + srcRangeCube[2] = cvf::Vec3st(src.EndI , src.EndJ , src.StartK); + srcRangeCube[3] = cvf::Vec3st(src.StartI, src.EndJ , src.StartK); + srcRangeCube[4] = cvf::Vec3st(src.StartI, src.StartJ, src.EndK); + srcRangeCube[5] = cvf::Vec3st(src.EndI , src.StartJ, src.EndK); + srcRangeCube[6] = cvf::Vec3st(src.EndI , src.EndJ , src.EndK); + srcRangeCube[7] = cvf::Vec3st(src.StartI, src.EndJ , src.EndK); + + bool foundExactMatch = false; + int cornerIdx = 0; + int diagIdx = 6;// Index to diagonal corner + + for (cornerIdx = 0; cornerIdx < 4; ++cornerIdx) + { + diagIdx = (cornerIdx < 2) ? cornerIdx + 6 : cornerIdx + 2; + + if (femIsDestination) + { + rangeFilterMatches[cornerIdx].cellMatchType = findBestFemCellFromEclCell(eclGrid, + srcRangeCube[cornerIdx][0], + srcRangeCube[cornerIdx][1], + srcRangeCube[cornerIdx][2], + femPart, + &(rangeFilterMatches[cornerIdx].ijk[0]), + &(rangeFilterMatches[cornerIdx].ijk[1]), + &(rangeFilterMatches[cornerIdx].ijk[2])); + + rangeFilterMatches[diagIdx].cellMatchType = findBestFemCellFromEclCell(eclGrid, + srcRangeCube[diagIdx][0], + srcRangeCube[diagIdx][1], + srcRangeCube[diagIdx][2], + femPart, + &(rangeFilterMatches[diagIdx].ijk[0]), + &(rangeFilterMatches[diagIdx].ijk[1]), + &(rangeFilterMatches[diagIdx].ijk[2])); + } + else + { + rangeFilterMatches[cornerIdx].cellMatchType = findBestEclCellFromFemCell(femPart, + srcRangeCube[cornerIdx][0], + srcRangeCube[cornerIdx][1], + srcRangeCube[cornerIdx][2], + eclGrid, + &(rangeFilterMatches[cornerIdx].ijk[0]), + &(rangeFilterMatches[cornerIdx].ijk[1]), + &(rangeFilterMatches[cornerIdx].ijk[2])); + + rangeFilterMatches[diagIdx].cellMatchType = findBestEclCellFromFemCell(femPart, + srcRangeCube[diagIdx][0], + srcRangeCube[diagIdx][1], + srcRangeCube[diagIdx][2], + eclGrid, + &(rangeFilterMatches[diagIdx].ijk[0]), + &(rangeFilterMatches[diagIdx].ijk[1]), + &(rangeFilterMatches[diagIdx].ijk[2])); + } + + if (rangeFilterMatches[cornerIdx].cellMatchType == EXACT && rangeFilterMatches[diagIdx].cellMatchType == EXACT) + { + foundExactMatch = true; + break; + } + } + + // Get the start and end IJK from the matched corners + if (foundExactMatch) + { + // Populate dst range filter from the diagonal that matches exact + dst.StartI = CVF_MIN(rangeFilterMatches[cornerIdx].ijk[0], rangeFilterMatches[diagIdx].ijk[0]); + dst.StartJ = CVF_MIN(rangeFilterMatches[cornerIdx].ijk[1], rangeFilterMatches[diagIdx].ijk[1]); + dst.StartK = CVF_MIN(rangeFilterMatches[cornerIdx].ijk[2], rangeFilterMatches[diagIdx].ijk[2]); + dst.EndI = CVF_MAX(rangeFilterMatches[cornerIdx].ijk[0], rangeFilterMatches[diagIdx].ijk[0]); + dst.EndJ = CVF_MAX(rangeFilterMatches[cornerIdx].ijk[1], rangeFilterMatches[diagIdx].ijk[1]); + dst.EndK = CVF_MAX(rangeFilterMatches[cornerIdx].ijk[2], rangeFilterMatches[diagIdx].ijk[2]); + } + else + { + // Look at the matches for each "face" of the range filter cube, + // and use first exact match to determine the position of that "face" + size_t faceIJKs[6] = {cvf::UNDEFINED_SIZE_T, cvf::UNDEFINED_SIZE_T,cvf::UNDEFINED_SIZE_T,cvf::UNDEFINED_SIZE_T,cvf::UNDEFINED_SIZE_T,cvf::UNDEFINED_SIZE_T}; + for (int faceIdx = 0; faceIdx < 6; ++faceIdx) + { + int ijOrk = 0; + if (faceIdx == cvf::StructGridInterface::POS_I || faceIdx == cvf::StructGridInterface::NEG_I) ijOrk = 0; + if (faceIdx == cvf::StructGridInterface::POS_J || faceIdx == cvf::StructGridInterface::NEG_J) ijOrk = 1; + if (faceIdx == cvf::StructGridInterface::POS_K || faceIdx == cvf::StructGridInterface::NEG_K) ijOrk = 2; + + cvf::ubyte surfCorners[4]; + cvf::StructGridInterface::cellFaceVertexIndices((cvf::StructGridInterface::FaceType) faceIdx , surfCorners); + bool foundAcceptedMatch = false; + for (int cIdx = 0; cIdx < 4; ++cIdx) + { + if (rangeFilterMatches[surfCorners[cIdx]].cellMatchType == EXACT) + { + foundAcceptedMatch = true; + + faceIJKs[faceIdx] = rangeFilterMatches[surfCorners[cIdx]].ijk[ijOrk]; + break; + } + } + + if (!foundAcceptedMatch) + { + // Take first match that is not related to a collapsed eclipse cell + for (int cIdx = 0; cIdx < 4; ++cIdx) + { + if (rangeFilterMatches[surfCorners[cIdx]].cellMatchType == APPROX) + { + foundAcceptedMatch = true; + + faceIJKs[faceIdx] = rangeFilterMatches[surfCorners[cIdx]].ijk[ijOrk]; + break; + } + } + + + if (!foundAcceptedMatch) + { + // Only collapsed cell hits in this "face" + // Todo: then use opposite face - range filter thickness + // For now, just select the first + faceIJKs[faceIdx] = rangeFilterMatches[surfCorners[0]].ijk[ijOrk]; + } + } + } + + #ifdef DEBUG + for (int faceIdx = 0; faceIdx <6; ++faceIdx) {CVF_TIGHT_ASSERT(faceIJKs[faceIdx] != cvf::UNDEFINED_SIZE_T);} + #endif + + dst.EndI = faceIJKs[cvf::StructGridInterface::POS_I]; + dst.StartI = faceIJKs[cvf::StructGridInterface::NEG_I]; + dst.EndJ = faceIJKs[cvf::StructGridInterface::POS_J]; + dst.StartJ = faceIJKs[cvf::StructGridInterface::NEG_J]; + dst.EndK = faceIJKs[cvf::StructGridInterface::POS_K]; + dst.StartK = faceIJKs[cvf::StructGridInterface::NEG_K]; + + } + } +} + + +//-------------------------------------------------------------------------------------------------- +/// Return 0 for collapsed cell 1 for +//-------------------------------------------------------------------------------------------------- +RigCaseToCaseRangeFilterMapper::CellMatchType +RigCaseToCaseRangeFilterMapper::findBestFemCellFromEclCell(const RigMainGrid* masterEclGrid, size_t ei, size_t ej, size_t ek, const RigFemPart* dependentFemPart, size_t* fi, size_t * fj, size_t* fk) +{ + // Find tolerance + + double cellSizeI, cellSizeJ, cellSizeK; + masterEclGrid->characteristicCellSizes(&cellSizeI, &cellSizeJ, &cellSizeK); + + double xyTolerance = cellSizeI* 0.01; + double zTolerance = cellSizeK* 0.01; + + bool isEclFaceNormalsOutwards = masterEclGrid->isFaceNormalsOutwards(); + + size_t cellIdx = masterEclGrid->cellIndexFromIJK(ei, ej, ek); + + bool isCollapsedCell = masterEclGrid->cells()[cellIdx].isCollapsedCell(); + + cvf::Vec3d geoMechConvertedEclCell[8]; + RigCaseToCaseCellMapperTools::estimatedFemCellFromEclCell(masterEclGrid, cellIdx, geoMechConvertedEclCell); + + cvf::BoundingBox elmBBox; + for (int i = 0; i < 8 ; ++i) elmBBox.add(geoMechConvertedEclCell[i]); + + std::vector closeElements; + dependentFemPart->findIntersectingCells(elmBBox, &closeElements); + + cvf::Vec3d elmCorners[8]; + int elmIdxToBestMatch = -1; + double sqDistToClosestElmCenter = HUGE_VAL; + cvf::Vec3d convEclCellCenter = RigCaseToCaseCellMapperTools::calculateCellCenter(geoMechConvertedEclCell); + + bool foundExactMatch = false; + + for (size_t ccIdx = 0; ccIdx < closeElements.size(); ++ccIdx) + { + int elmIdx = static_cast(closeElements[ccIdx]); + + RigCaseToCaseCellMapperTools::elementCorners(dependentFemPart, elmIdx, elmCorners); + + cvf::Vec3d cellCenter = RigCaseToCaseCellMapperTools::calculateCellCenter(elmCorners); + double sqDist = (cellCenter - convEclCellCenter).lengthSquared(); + if (sqDist < sqDistToClosestElmCenter) + { + elmIdxToBestMatch = elmIdx; + sqDistToClosestElmCenter = sqDist; + } + + RigCaseToCaseCellMapperTools::rotateCellTopologicallyToMatchBaseCell(geoMechConvertedEclCell, isEclFaceNormalsOutwards, elmCorners); + + foundExactMatch = RigCaseToCaseCellMapperTools::isEclFemCellsMatching(geoMechConvertedEclCell, elmCorners, + xyTolerance, zTolerance); + + if (foundExactMatch) + { + elmIdxToBestMatch = elmIdx; + break; + } + } + + if (elmIdxToBestMatch != -1) + { + dependentFemPart->structGrid()->ijkFromCellIndex(elmIdxToBestMatch, fi, fj, fk); + } + else + { + (*fi) = cvf::UNDEFINED_SIZE_T; + (*fj) = cvf::UNDEFINED_SIZE_T; + (*fk) = cvf::UNDEFINED_SIZE_T; + } + + if (foundExactMatch) return EXACT; + if (isCollapsedCell) return APPROX_ON_COLLAPSED; + return APPROX; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigCaseToCaseRangeFilterMapper::CellMatchType +RigCaseToCaseRangeFilterMapper::findBestEclCellFromFemCell(const RigFemPart* dependentFemPart, size_t fi, size_t fj, size_t fk, const RigMainGrid* masterEclGrid, size_t* ei, size_t* ej, size_t* ek) +{ + // Find tolerance + + double cellSizeI, cellSizeJ, cellSizeK; + masterEclGrid->characteristicCellSizes(&cellSizeI, &cellSizeJ, &cellSizeK); + + double xyTolerance = cellSizeI* 0.4; + double zTolerance = cellSizeK* 0.4; + + bool isEclFaceNormalsOutwards = masterEclGrid->isFaceNormalsOutwards(); + + int elementIdx = static_cast(dependentFemPart->structGrid()->cellIndexFromIJK(fi, fj, fk)); + + cvf::Vec3d elmCorners[8]; + RigCaseToCaseCellMapperTools::elementCorners(dependentFemPart, elementIdx, elmCorners); + + cvf::BoundingBox elmBBox; + for (int i = 0; i < 8 ; ++i) elmBBox.add(elmCorners[i]); + + std::vector closeCells; + masterEclGrid->findIntersectingCells(elmBBox, &closeCells); // This might actually miss the exact one, but we have no other alternative yet. + + size_t globCellIdxToBestMatch = cvf::UNDEFINED_SIZE_T; + double sqDistToClosestCellCenter = HUGE_VAL; + cvf::Vec3d elmCenter = RigCaseToCaseCellMapperTools::calculateCellCenter(elmCorners); + + bool foundExactMatch = false; + + for (size_t ccIdx = 0; ccIdx < closeCells.size(); ++ccIdx) + { + size_t cellIdx = closeCells[ccIdx]; + cvf::Vec3d geoMechConvertedEclCell[8]; + RigCaseToCaseCellMapperTools::estimatedFemCellFromEclCell(masterEclGrid, cellIdx, geoMechConvertedEclCell); + + cvf::Vec3d cellCenter = RigCaseToCaseCellMapperTools::calculateCellCenter(geoMechConvertedEclCell); + double sqDist = (cellCenter - elmCenter).lengthSquared(); + if (sqDist < sqDistToClosestCellCenter) + { + globCellIdxToBestMatch = cellIdx; + sqDistToClosestCellCenter = sqDist; + } + + RigCaseToCaseCellMapperTools::rotateCellTopologicallyToMatchBaseCell(geoMechConvertedEclCell, isEclFaceNormalsOutwards, elmCorners); + + foundExactMatch = RigCaseToCaseCellMapperTools::isEclFemCellsMatching(geoMechConvertedEclCell, elmCorners, + xyTolerance, zTolerance); + + if (foundExactMatch) + { + globCellIdxToBestMatch = cellIdx; + break; + } + } + + bool isCollapsedCell = false; + if (globCellIdxToBestMatch != cvf::UNDEFINED_SIZE_T) + { + masterEclGrid->ijkFromCellIndex(globCellIdxToBestMatch, ei, ej, ek); + isCollapsedCell = masterEclGrid->cells()[globCellIdxToBestMatch].isCollapsedCell(); + } + else + { + (*ei) = cvf::UNDEFINED_SIZE_T; + (*ej) = cvf::UNDEFINED_SIZE_T; + (*ek) = cvf::UNDEFINED_SIZE_T; + } + + if (foundExactMatch) return EXACT; + if (isCollapsedCell) return APPROX_ON_COLLAPSED; + return APPROX; +} diff --git a/ApplicationCode/ReservoirDataModel/RigCaseToCaseRangeFilterMapper.h b/ApplicationCode/ReservoirDataModel/RigCaseToCaseRangeFilterMapper.h new file mode 100644 index 0000000000..1b00489345 --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/RigCaseToCaseRangeFilterMapper.h @@ -0,0 +1,56 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// +#pragma once + +#include + +class RimCellRangeFilter; +class RigMainGrid; +class RigFemPart; +struct RigRangeEndPoints; + +class RigCaseToCaseRangeFilterMapper +{ +public: + static void convertRangeFilterEclToFem(RimCellRangeFilter* srcFilter, const RigMainGrid* srcEclGrid, + RimCellRangeFilter* dstFilter, const RigFemPart* dstFemPart); + static void convertRangeFilterFemToEcl(RimCellRangeFilter* srcFilter, const RigFemPart* srcFemPart, + RimCellRangeFilter* dstFilter, const RigMainGrid* dstEclGrid); + +private: + + static void convertRangeFilter(const RimCellRangeFilter* srcFilter, RimCellRangeFilter* dstFilter, + const RigMainGrid* eclGrid, const RigFemPart* femPart, + bool femIsDestination); + + static void convertRangeFilterEndPoints(const RigRangeEndPoints &src, + RigRangeEndPoints &dst, + const RigMainGrid* eclGrid, + const RigFemPart* femPart, + bool femIsDestination); + + enum CellMatchType {APPROX_ON_COLLAPSED, APPROX, EXACT }; + static CellMatchType findBestFemCellFromEclCell(const RigMainGrid* masterEclGrid, size_t ei, size_t ej, size_t ek, + const RigFemPart* dependentFemPart, size_t* fi, size_t * fj, size_t* fk); + + static CellMatchType findBestEclCellFromFemCell(const RigFemPart* dependentFemPart, size_t fi, size_t fj, size_t fk, + const RigMainGrid* masterEclGrid, size_t* ei, size_t* ej, size_t* ek); +}; + + diff --git a/ApplicationCode/ReservoirDataModel/RigCell.cpp b/ApplicationCode/ReservoirDataModel/RigCell.cpp index a4af1b32a8..2fc2a1a81d 100644 --- a/ApplicationCode/ReservoirDataModel/RigCell.cpp +++ b/ApplicationCode/ReservoirDataModel/RigCell.cpp @@ -106,8 +106,6 @@ bool RigCell::isLongPyramidCell(double maxHeightFactor, double nodeNearTolerance const std::vector& nodes = m_hostGrid->mainGrid()->nodes(); - bool isPyramidCell = false; - int face; for ( face = 0; face < 6 ; ++face) { @@ -221,6 +219,48 @@ bool RigCell::isLongPyramidCell(double maxHeightFactor, double nodeNearTolerance return false; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RigCell::isCollapsedCell(double nodeNearTolerance) const +{ + const std::vector& nodes = m_hostGrid->mainGrid()->nodes(); + + cvf::ubyte faceVertexIndices[4]; + cvf::ubyte oppFaceVertexIndices[4]; + + int face; + for ( face = 0; face < 6 ; face += 2) + { + cvf::StructGridInterface::cellFaceVertexIndices(static_cast(face), faceVertexIndices); + cvf::StructGridInterface::cellFaceVertexIndices(cvf::StructGridInterface::oppositeFace(static_cast(face)), oppFaceVertexIndices); + + cvf::Vec3d c0 = nodes[m_cornerIndices[faceVertexIndices[0]]]; + cvf::Vec3d c1 = nodes[m_cornerIndices[faceVertexIndices[1]]]; + cvf::Vec3d c2 = nodes[m_cornerIndices[faceVertexIndices[2]]]; + cvf::Vec3d c3 = nodes[m_cornerIndices[faceVertexIndices[3]]]; + + cvf::Vec3d oc0 = nodes[m_cornerIndices[oppFaceVertexIndices[0]]]; + cvf::Vec3d oc1 = nodes[m_cornerIndices[oppFaceVertexIndices[1]]]; + cvf::Vec3d oc2 = nodes[m_cornerIndices[oppFaceVertexIndices[2]]]; + cvf::Vec3d oc3 = nodes[m_cornerIndices[oppFaceVertexIndices[3]]]; + + int zeroLengthEdgeCount = 0; + if (isNear(c0, oc0, nodeNearTolerance)) { ++zeroLengthEdgeCount; } + if (isNear(c1, oc3, nodeNearTolerance)) { ++zeroLengthEdgeCount; } + if (isNear(c2, oc2, nodeNearTolerance)) { ++zeroLengthEdgeCount; } + if (isNear(c3, oc1, nodeNearTolerance)) { ++zeroLengthEdgeCount; } + + if (zeroLengthEdgeCount >= 4) + { + return true; + } + } + + return false; +} + + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ReservoirDataModel/RigCell.h b/ApplicationCode/ReservoirDataModel/RigCell.h index 1cda50a286..22887b2c73 100644 --- a/ApplicationCode/ReservoirDataModel/RigCell.h +++ b/ApplicationCode/ReservoirDataModel/RigCell.h @@ -69,6 +69,7 @@ class RigCell int firstIntersectionPoint(const cvf::Ray& ray, cvf::Vec3d* intersectionPoint) const; bool isLongPyramidCell(double maxHeightFactor = 5, double nodeNearTolerance = 1e-3 ) const; + bool isCollapsedCell( double nodeNearTolerance = 1e-3) const; private: caf::SizeTArray8 m_cornerIndices; diff --git a/ApplicationCode/ReservoirDataModel/RigCellEdgeResultAccessor.cpp b/ApplicationCode/ReservoirDataModel/RigCellEdgeResultAccessor.cpp index 6ed6218bb4..ed3f5cc55d 100644 --- a/ApplicationCode/ReservoirDataModel/RigCellEdgeResultAccessor.cpp +++ b/ApplicationCode/ReservoirDataModel/RigCellEdgeResultAccessor.cpp @@ -64,3 +64,29 @@ double RigCellEdgeResultAccessor::cellFaceScalar(size_t gridLocalCellIndex, cvf: return HUGE_VAL; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RigCellEdgeResultAccessor::cellScalarGlobIdx(size_t globCellIndex) const +{ + // TODO: How to handle when we get here? + CVF_ASSERT(false); + + return cvf::UNDEFINED_DOUBLE; + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RigCellEdgeResultAccessor::cellFaceScalarGlobIdx(size_t globCellIndex, cvf::StructGridInterface::FaceType faceId) const +{ + const RigResultAccessor* resultAccessObj = m_resultAccessObjects[faceId].p(); + if (resultAccessObj != NULL) + { + return resultAccessObj->cellFaceScalarGlobIdx(globCellIndex, faceId); + } + + return HUGE_VAL; +} + diff --git a/ApplicationCode/ReservoirDataModel/RigCellEdgeResultAccessor.h b/ApplicationCode/ReservoirDataModel/RigCellEdgeResultAccessor.h index 3ba5e22898..ce21dcb42c 100644 --- a/ApplicationCode/ReservoirDataModel/RigCellEdgeResultAccessor.h +++ b/ApplicationCode/ReservoirDataModel/RigCellEdgeResultAccessor.h @@ -37,6 +37,9 @@ class RigCellEdgeResultAccessor : public RigResultAccessor virtual double cellScalar(size_t gridLocalCellIndex) const; virtual double cellFaceScalar(size_t gridLocalCellIndex, cvf::StructGridInterface::FaceType faceId) const; + virtual double cellScalarGlobIdx(size_t globCellIndex) const; + virtual double cellFaceScalarGlobIdx(size_t globCellIndex, cvf::StructGridInterface::FaceType faceId) const; + private: caf::FixedArray, 6> m_resultAccessObjects; }; diff --git a/ApplicationCode/ReservoirDataModel/RigCombMultResultAccessor.cpp b/ApplicationCode/ReservoirDataModel/RigCombMultResultAccessor.cpp index a06104fbf0..4ef5d409a1 100644 --- a/ApplicationCode/ReservoirDataModel/RigCombMultResultAccessor.cpp +++ b/ApplicationCode/ReservoirDataModel/RigCombMultResultAccessor.cpp @@ -22,6 +22,8 @@ #include "RigGridBase.h" #include +#include "RigCell.h" +#include "RigMainGrid.h" //-------------------------------------------------------------------------------------------------- @@ -147,3 +149,22 @@ double RigCombMultResultAccessor::nativeMultScalar(size_t gridLocalCellIndex, cv return faceScalar; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RigCombMultResultAccessor::cellScalarGlobIdx(size_t globCellIndex) const +{ + CVF_TIGHT_ASSERT(false); + + return HUGE_VAL; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RigCombMultResultAccessor::cellFaceScalarGlobIdx(size_t globCellIndex, cvf::StructGridInterface::FaceType faceId) const +{ + size_t gridLocalCellIndex = m_grid->mainGrid()->cell(globCellIndex).gridLocalCellIndex(); + return this->cellFaceScalar(gridLocalCellIndex, faceId); +} + diff --git a/ApplicationCode/ReservoirDataModel/RigCombMultResultAccessor.h b/ApplicationCode/ReservoirDataModel/RigCombMultResultAccessor.h index 74aa312a9c..174185c101 100644 --- a/ApplicationCode/ReservoirDataModel/RigCombMultResultAccessor.h +++ b/ApplicationCode/ReservoirDataModel/RigCombMultResultAccessor.h @@ -44,6 +44,8 @@ class RigCombMultResultAccessor : public RigResultAccessor virtual double cellScalar(size_t gridLocalCellIndex) const; virtual double cellFaceScalar(size_t gridLocalCellIndex, cvf::StructGridInterface::FaceType faceId) const; + virtual double cellScalarGlobIdx(size_t globCellIndex) const; + virtual double cellFaceScalarGlobIdx(size_t globCellIndex, cvf::StructGridInterface::FaceType faceId) const; private: double nativeMultScalar(size_t gridLocalCellIndex, cvf::StructGridInterface::FaceType faceId) const; diff --git a/ApplicationCode/ReservoirDataModel/RigCombTransResultAccessor.cpp b/ApplicationCode/ReservoirDataModel/RigCombTransResultAccessor.cpp index 8d011f3757..6fc358ae6f 100644 --- a/ApplicationCode/ReservoirDataModel/RigCombTransResultAccessor.cpp +++ b/ApplicationCode/ReservoirDataModel/RigCombTransResultAccessor.cpp @@ -22,6 +22,8 @@ #include "RigGridBase.h" #include +#include "RigCell.h" +#include "RigMainGrid.h" //-------------------------------------------------------------------------------------------------- @@ -137,3 +139,22 @@ double RigCombTransResultAccessor::cellFaceScalar(size_t gridLocalCellIndex, cvf return HUGE_VAL; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RigCombTransResultAccessor::cellScalarGlobIdx(size_t globCellIndex) const +{ + CVF_TIGHT_ASSERT(false); + + return HUGE_VAL; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RigCombTransResultAccessor::cellFaceScalarGlobIdx(size_t globCellIndex, cvf::StructGridInterface::FaceType faceId) const +{ + size_t gridLocalCellIndex = m_grid->mainGrid()->cell(globCellIndex).gridLocalCellIndex(); + return this->cellFaceScalar(gridLocalCellIndex, faceId); +} + diff --git a/ApplicationCode/ReservoirDataModel/RigCombTransResultAccessor.h b/ApplicationCode/ReservoirDataModel/RigCombTransResultAccessor.h index c250f0791a..2687db8000 100644 --- a/ApplicationCode/ReservoirDataModel/RigCombTransResultAccessor.h +++ b/ApplicationCode/ReservoirDataModel/RigCombTransResultAccessor.h @@ -40,9 +40,13 @@ class RigCombTransResultAccessor : public RigResultAccessor virtual double cellScalar(size_t gridLocalCellIndex) const; virtual double cellFaceScalar(size_t gridLocalCellIndex, cvf::StructGridInterface::FaceType faceId) const; + virtual double cellScalarGlobIdx(size_t globCellIndex) const; + virtual double cellFaceScalarGlobIdx(size_t globCellIndex, cvf::StructGridInterface::FaceType faceId) const; + private: double neighborCellTran(size_t gridLocalCellIndex, cvf::StructGridInterface::FaceType faceId, const RigResultAccessor* transAccessor) const; + cvf::ref m_xTransAccessor; cvf::ref m_yTransAccessor; cvf::ref m_zTransAccessor; diff --git a/ApplicationCode/ReservoirDataModel/RigEclipseWellLogExtractor.cpp b/ApplicationCode/ReservoirDataModel/RigEclipseWellLogExtractor.cpp new file mode 100644 index 0000000000..9109e9d2f4 --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/RigEclipseWellLogExtractor.cpp @@ -0,0 +1,141 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RigEclipseWellLogExtractor.h" +#include +#include "RigCaseData.h" +#include "RigWellPath.h" +#include "RigResultAccessor.h" +#include "cvfBoundingBox.h" +#include "cvfGeometryTools.h" + +#include "RigWellLogExtractionTools.h" +#include "RigMainGrid.h" + +//================================================================================================== +/// +//================================================================================================== + +RigEclipseWellLogExtractor::RigEclipseWellLogExtractor(const RigCaseData* aCase, const RigWellPath* wellpath, const std::string& wellCaseErrorMsgName) + : m_caseData(aCase), RigWellLogExtractor(wellpath, wellCaseErrorMsgName) +{ + calculateIntersection(); +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigEclipseWellLogExtractor::calculateIntersection() +{ + std::map uniqueIntersections; + + const std::vector& nodeCoords = m_caseData->mainGrid()->nodes(); + bool isCellFaceNormalsOut = m_caseData->mainGrid()->isFaceNormalsOutwards(); + + if (!m_wellPath->m_wellPathPoints.size()) return ; + + for (size_t wpp = 0; wpp < m_wellPath->m_wellPathPoints.size() - 1; ++wpp) + { + std::vector intersections; + cvf::Vec3d p1 = m_wellPath->m_wellPathPoints[wpp]; + cvf::Vec3d p2 = m_wellPath->m_wellPathPoints[wpp+1]; + + + cvf::BoundingBox bb; + + bb.add(p1); + bb.add(p2); + + std::vector closeCells = findCloseCells(bb); + + + cvf::Vec3d hexCorners[8]; + for (size_t cIdx = 0; cIdx < closeCells.size(); ++cIdx) + { + const RigCell& cell = m_caseData->mainGrid()->cells()[closeCells[cIdx]]; + const caf::SizeTArray8& cornerIndices = cell.cornerIndices(); + + hexCorners[0] = nodeCoords[cornerIndices[0]]; + hexCorners[1] = nodeCoords[cornerIndices[1]]; + hexCorners[2] = nodeCoords[cornerIndices[2]]; + hexCorners[3] = nodeCoords[cornerIndices[3]]; + hexCorners[4] = nodeCoords[cornerIndices[4]]; + hexCorners[5] = nodeCoords[cornerIndices[5]]; + hexCorners[6] = nodeCoords[cornerIndices[6]]; + hexCorners[7] = nodeCoords[cornerIndices[7]]; + + //int intersectionCount = RigHexIntersector::lineHexCellIntersection(p1, p2, hexCorners, closeCells[cIdx], &intersections); + RigHexIntersector::lineHexCellIntersection(p1, p2, hexCorners, closeCells[cIdx], &intersections); + } + + if (!isCellFaceNormalsOut) + { + for (size_t intIdx = 0; intIdx < intersections.size(); ++intIdx) + { + intersections[intIdx].m_isIntersectionEntering = !intersections[intIdx].m_isIntersectionEntering ; + } + } + + // Now, with all the intersections of this piece of line, we need to + // sort them in order, and set the measured depth and corresponding cell index + + // Inserting the intersections in this map will remove identical intersections + // and sort them according to MD, CellIdx, Leave/enter + + double md1 = m_wellPath->m_measuredDepths[wpp]; + double md2 = m_wellPath->m_measuredDepths[wpp+1]; + + insertIntersectionsInMap(intersections, + p1, md1, p2, md2, + &uniqueIntersections); + + } + + this->populateReturnArrays(uniqueIntersections); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigEclipseWellLogExtractor::curveData(const RigResultAccessor* resultAccessor, std::vector* values) +{ + CVF_TIGHT_ASSERT(values); + values->resize(m_intersections.size()); + + for (size_t cpIdx = 0; cpIdx < m_intersections.size(); ++cpIdx) + { + size_t cellIdx = m_intersectedCells[cpIdx]; + cvf::StructGridInterface::FaceType cellFace = m_intersectedCellFaces[cpIdx]; + (*values)[cpIdx] = resultAccessor->cellFaceScalarGlobIdx(cellIdx, cellFace); + } + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RigEclipseWellLogExtractor::findCloseCells(const cvf::BoundingBox& bb) +{ + std::vector closeCells; + m_caseData->mainGrid()->findIntersectingCells(bb, &closeCells); + return closeCells; +} + + diff --git a/ApplicationCode/ReservoirDataModel/RigEclipseWellLogExtractor.h b/ApplicationCode/ReservoirDataModel/RigEclipseWellLogExtractor.h new file mode 100644 index 0000000000..d92a362377 --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/RigEclipseWellLogExtractor.h @@ -0,0 +1,56 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "RigWellLogExtractor.h" + +#include "cvfBase.h" +#include "cvfObject.h" +#include "cvfMath.h" +#include "cvfVector3.h" + +#include +#include "cvfStructGrid.h" + +class RigCaseData; +class RigWellPath; +class RigResultAccessor; + +namespace cvf { + class BoundingBox; +} + +//================================================================================================== +/// +//================================================================================================== +class RigEclipseWellLogExtractor : public RigWellLogExtractor +{ +public: + RigEclipseWellLogExtractor(const RigCaseData* aCase, const RigWellPath* wellpath, const std::string& wellCaseErrorMsgName); + + void curveData(const RigResultAccessor* resultAccessor, std::vector* values ); + const RigCaseData* caseData() { return m_caseData.p();} + +protected: + void calculateIntersection(); + std::vector findCloseCells(const cvf::BoundingBox& bb); + + cvf::cref m_caseData; +}; diff --git a/ApplicationCode/ReservoirDataModel/RigGeoMechWellLogExtractor.cpp b/ApplicationCode/ReservoirDataModel/RigGeoMechWellLogExtractor.cpp new file mode 100644 index 0000000000..b2814d2e0c --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/RigGeoMechWellLogExtractor.cpp @@ -0,0 +1,192 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +//================================================================================================== +/// +//================================================================================================== +#include "RigGeoMechWellLogExtractor.h" +#include "RigFemPart.h" +#include "RigFemPartCollection.h" +#include "RigGeoMechCaseData.h" +#include "RigFemPartResultsCollection.h" + +#include "RigWellLogExtractionTools.h" +#include "RigWellPath.h" +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigGeoMechWellLogExtractor::RigGeoMechWellLogExtractor(RigGeoMechCaseData* aCase, const RigWellPath* wellpath, const std::string& wellCaseErrorMsgName) + :m_caseData(aCase), RigWellLogExtractor(wellpath, wellCaseErrorMsgName) +{ + calculateIntersection(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigGeoMechWellLogExtractor::curveData(const RigFemResultAddress& resAddr, int frameIndex, std::vector* values) +{ + CVF_TIGHT_ASSERT(values); + + if (!resAddr.isValid()) return ; + + RigFemResultAddress convResAddr = resAddr; + + // When showing POR results, always use the element nodal result, + // to get correct handling of elements without POR results + + if (convResAddr.fieldName == "POR-Bar") convResAddr.resultPosType = RIG_ELEMENT_NODAL; + + const RigFemPart* femPart = m_caseData->femParts()->part(0); + const std::vector& nodeCoords = femPart->nodes().coordinates; + const std::vector& resultValues = m_caseData->femPartResults()->resultValues(convResAddr, 0, frameIndex); + + if (!resultValues.size()) return; + + values->resize(m_intersections.size()); + + for (size_t cpIdx = 0; cpIdx < m_intersections.size(); ++cpIdx) + { + size_t elmIdx = m_intersectedCells[cpIdx]; + RigElementType elmType = femPart->elementType(elmIdx); + + if (!(elmType == HEX8 || elmType == HEX8P)) continue; + + cvf::StructGridInterface::FaceType cellFace = m_intersectedCellFaces[cpIdx]; + + int faceNodeCount = 0; + const int* faceLocalIndices = RigFemTypes::localElmNodeIndicesForFace(elmType, cellFace, &faceNodeCount); + const int* elmNodeIndices = femPart->connectivities(elmIdx); + + cvf::Vec3d v0(nodeCoords[elmNodeIndices[faceLocalIndices[0]]]); + cvf::Vec3d v1(nodeCoords[elmNodeIndices[faceLocalIndices[1]]]); + cvf::Vec3d v2(nodeCoords[elmNodeIndices[faceLocalIndices[2]]]); + cvf::Vec3d v3(nodeCoords[elmNodeIndices[faceLocalIndices[3]]]); + + size_t resIdx0 = cvf::UNDEFINED_SIZE_T; + size_t resIdx1 = cvf::UNDEFINED_SIZE_T; + size_t resIdx2 = cvf::UNDEFINED_SIZE_T; + size_t resIdx3 = cvf::UNDEFINED_SIZE_T; + + if (convResAddr.resultPosType == RIG_NODAL) + { + resIdx0 = elmNodeIndices[faceLocalIndices[0]]; + resIdx1 = elmNodeIndices[faceLocalIndices[1]]; + resIdx2 = elmNodeIndices[faceLocalIndices[2]]; + resIdx3 = elmNodeIndices[faceLocalIndices[3]]; + } + else + { + resIdx0 = (size_t)femPart->elementNodeResultIdx((int)elmIdx, faceLocalIndices[0]); + resIdx1 = (size_t)femPart->elementNodeResultIdx((int)elmIdx, faceLocalIndices[1]); + resIdx2 = (size_t)femPart->elementNodeResultIdx((int)elmIdx, faceLocalIndices[2]); + resIdx3 = (size_t)femPart->elementNodeResultIdx((int)elmIdx, faceLocalIndices[3]); + } + + double interpolatedValue = cvf::GeometryTools::interpolateQuad( + v0, resultValues[resIdx0], + v1, resultValues[resIdx1], + v2, resultValues[resIdx2], + v3, resultValues[resIdx3], + m_intersections[cpIdx] + ); + + (*values)[cpIdx] = interpolatedValue; + } + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigGeoMechWellLogExtractor::calculateIntersection() +{ + CVF_ASSERT(m_caseData->femParts()->partCount() == 1); + + std::map uniqueIntersections; + + const RigFemPart* femPart = m_caseData->femParts()->part(0); + const std::vector& nodeCoords = femPart->nodes().coordinates; + + for (size_t wpp = 0; wpp < m_wellPath->m_wellPathPoints.size() - 1; ++wpp) + { + std::vector intersections; + cvf::Vec3d p1 = m_wellPath->m_wellPathPoints[wpp]; + cvf::Vec3d p2 = m_wellPath->m_wellPathPoints[wpp+1]; + + cvf::BoundingBox bb; + + bb.add(p1); + bb.add(p2); + + std::vector closeCells = findCloseCells(bb); + + cvf::Vec3d hexCorners[8]; + for (size_t ccIdx = 0; ccIdx < closeCells.size(); ++ccIdx) + { + RigElementType elmType = femPart->elementType(closeCells[ccIdx]); + if (!(elmType == HEX8 || elmType == HEX8P)) continue; + + const int* cornerIndices = femPart->connectivities(closeCells[ccIdx]); + + hexCorners[0] = cvf::Vec3d(nodeCoords[cornerIndices[0]]); + hexCorners[1] = cvf::Vec3d(nodeCoords[cornerIndices[1]]); + hexCorners[2] = cvf::Vec3d(nodeCoords[cornerIndices[2]]); + hexCorners[3] = cvf::Vec3d(nodeCoords[cornerIndices[3]]); + hexCorners[4] = cvf::Vec3d(nodeCoords[cornerIndices[4]]); + hexCorners[5] = cvf::Vec3d(nodeCoords[cornerIndices[5]]); + hexCorners[6] = cvf::Vec3d(nodeCoords[cornerIndices[6]]); + hexCorners[7] = cvf::Vec3d(nodeCoords[cornerIndices[7]]); + + //int intersectionCount = RigHexIntersector::lineHexCellIntersection(p1, p2, hexCorners, closeCells[ccIdx], &intersections); + RigHexIntersector::lineHexCellIntersection(p1, p2, hexCorners, closeCells[ccIdx], &intersections); + } + + // Now, with all the intersections of this piece of line, we need to + // sort them in order, and set the measured depth and corresponding cell index + + // Inserting the intersections in this map will remove identical intersections + // and sort them according to MD, CellIdx, Leave/enter + + double md1 = m_wellPath->m_measuredDepths[wpp]; + double md2 = m_wellPath->m_measuredDepths[wpp+1]; + + insertIntersectionsInMap(intersections, + p1, md1, p2, md2, + &uniqueIntersections); + } + + this->populateReturnArrays(uniqueIntersections); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RigGeoMechWellLogExtractor::findCloseCells(const cvf::BoundingBox& bb) +{ + std::vector closeCells; + + if (m_caseData->femParts()->partCount()) + { + m_caseData->femParts()->part(0)->findIntersectingCells(bb, &closeCells); + } + return closeCells; +} + + diff --git a/ApplicationCode/ReservoirDataModel/RigGeoMechWellLogExtractor.h b/ApplicationCode/ReservoirDataModel/RigGeoMechWellLogExtractor.h new file mode 100644 index 0000000000..3121913339 --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/RigGeoMechWellLogExtractor.h @@ -0,0 +1,58 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "RigWellLogExtractor.h" + +#include "cvfBase.h" +#include "cvfObject.h" +#include "cvfMath.h" +#include "cvfVector3.h" + +#include +#include "cvfStructGrid.h" + +class RigWellPath; +class RigGeoMechCaseData; +class RigFemResultAddress; + +namespace cvf { + class BoundingBox; +} + +//================================================================================================== +/// +//================================================================================================== +class RigGeoMechWellLogExtractor : public RigWellLogExtractor +{ +public: + RigGeoMechWellLogExtractor(RigGeoMechCaseData* aCase, const RigWellPath* wellpath, const std::string& wellCaseErrorMsgName); + + void curveData(const RigFemResultAddress& resAddr, int frameIndex, std::vector* values ); + const RigGeoMechCaseData* caseData() { return m_caseData.p();} + +private: + void calculateIntersection(); + std::vector findCloseCells(const cvf::BoundingBox& bb); + + cvf::ref m_caseData; +}; + + diff --git a/ApplicationCode/ReservoirDataModel/RigGridManager.cpp b/ApplicationCode/ReservoirDataModel/RigGridManager.cpp index 3a86668846..22e89b82f6 100644 --- a/ApplicationCode/ReservoirDataModel/RigGridManager.cpp +++ b/ApplicationCode/ReservoirDataModel/RigGridManager.cpp @@ -35,8 +35,6 @@ void RigGridManager::addCase(RigCaseData* eclipseCase) //-------------------------------------------------------------------------------------------------- void RigGridManager::removeCase(RigCaseData* eclipseCase) { - size_t indexToErase = cvf::UNDEFINED_SIZE_T; - for (size_t i = 0; i < m_caseToGrid.size(); i++) { if (m_caseToGrid[i]->m_eclipseCase == eclipseCase) diff --git a/ApplicationCode/ReservoirDataModel/RigMainGrid.cpp b/ApplicationCode/ReservoirDataModel/RigMainGrid.cpp index 9d6c271c62..0cd30db889 100644 --- a/ApplicationCode/ReservoirDataModel/RigMainGrid.cpp +++ b/ApplicationCode/ReservoirDataModel/RigMainGrid.cpp @@ -23,6 +23,7 @@ #include "cvfAssert.h" #include "RimDefines.h" #include "RigFault.h" +#include "cvfBoundingBoxTree.h" RigMainGrid::RigMainGrid(void) @@ -441,3 +442,52 @@ const RigFault* RigMainGrid::findFaultFromCellIndexAndCellFace(size_t reservoirC #endif return NULL; } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigMainGrid::findIntersectingCells(const cvf::BoundingBox& inputBB, std::vector* cellIndices) const +{ + if (m_cellSearchTree.isNull()) + { + // build tree + + size_t cellCount = m_cells.size(); + + std::vector cellBoundingBoxes; + cellBoundingBoxes.resize(cellCount); + + for (size_t cIdx = 0; cIdx < cellCount; ++cIdx) + { + const caf::SizeTArray8& cellIndices = m_cells[cIdx].cornerIndices(); + cvf::BoundingBox& cellBB = cellBoundingBoxes[cIdx]; + cellBB.add(m_nodes[cellIndices[0]]); + cellBB.add(m_nodes[cellIndices[1]]); + cellBB.add(m_nodes[cellIndices[2]]); + cellBB.add(m_nodes[cellIndices[3]]); + cellBB.add(m_nodes[cellIndices[4]]); + cellBB.add(m_nodes[cellIndices[5]]); + cellBB.add(m_nodes[cellIndices[6]]); + cellBB.add(m_nodes[cellIndices[7]]); + } + + m_cellSearchTree = new cvf::BoundingBoxTree; + m_cellSearchTree->buildTreeFromBoundingBoxes(cellBoundingBoxes, NULL); + } + + m_cellSearchTree->findIntersections(inputBB, cellIndices); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +cvf::BoundingBox RigMainGrid::boundingBox() const +{ + if (m_boundingBox.isValid()) return m_boundingBox; + + for (size_t i = 0; i < m_nodes.size(); ++i) + { + m_boundingBox.add(m_nodes[i]); + } + return m_boundingBox; +} diff --git a/ApplicationCode/ReservoirDataModel/RigMainGrid.h b/ApplicationCode/ReservoirDataModel/RigMainGrid.h index f208d3f5cb..11ea6639f8 100644 --- a/ApplicationCode/ReservoirDataModel/RigMainGrid.h +++ b/ApplicationCode/ReservoirDataModel/RigMainGrid.h @@ -30,6 +30,11 @@ #include #include "RigNNCData.h" +namespace cvf +{ + class BoundingBoxTree; +} + class RigMainGrid : public RigGridBase { public: @@ -63,7 +68,8 @@ class RigMainGrid : public RigGridBase void setDisplayModelOffset(cvf::Vec3d offset); void setFlipAxis(bool flipXAxis, bool flipYAxis); - + void findIntersectingCells(const cvf::BoundingBox& inputBB, std::vector* cellIndices) const; + cvf::BoundingBox boundingBox() const; private: void initAllSubGridsParentGridPointer(); void initAllSubCellsMainGridCellIndex(); @@ -81,6 +87,8 @@ class RigMainGrid : public RigGridBase cvf::ref m_faultsPrCellAcc; cvf::Vec3d m_displayModelOffset; + mutable cvf::ref m_cellSearchTree; + mutable cvf::BoundingBox m_boundingBox; bool m_flipXAxis; bool m_flipYAxis; diff --git a/ApplicationCode/ReservoirDataModel/RigNativeStatCalc.cpp b/ApplicationCode/ReservoirDataModel/RigNativeStatCalc.cpp index 605537c75f..5008764d42 100644 --- a/ApplicationCode/ReservoirDataModel/RigNativeStatCalc.cpp +++ b/ApplicationCode/ReservoirDataModel/RigNativeStatCalc.cpp @@ -30,7 +30,7 @@ /// //-------------------------------------------------------------------------------------------------- RigNativeStatCalc::RigNativeStatCalc(RigCaseCellResultsData* cellResultsData, size_t scalarResultIndex) - : m_resultsData(cellResultsData), + : m_resultsData(cellResultsData), m_scalarResultIndex(scalarResultIndex) { @@ -41,26 +41,26 @@ RigNativeStatCalc::RigNativeStatCalc(RigCaseCellResultsData* cellResultsData, si //-------------------------------------------------------------------------------------------------- void RigNativeStatCalc::minMaxCellScalarValues(size_t timeStepIndex, double& min, double& max) { - std::vector& values = m_resultsData->cellScalarResults(m_scalarResultIndex, timeStepIndex); - - size_t i; - for (i = 0; i < values.size(); i++) - { - if (values[i] == HUGE_VAL) - { - continue; - } - - if (values[i] < min) - { - min = values[i]; - } - - if (values[i] > max) - { - max = values[i]; - } - } + std::vector& values = m_resultsData->cellScalarResults(m_scalarResultIndex, timeStepIndex); + + size_t i; + for (i = 0; i < values.size(); i++) + { + if (values[i] == HUGE_VAL) + { + continue; + } + + if (values[i] < min) + { + min = values[i]; + } + + if (values[i] > max) + { + max = values[i]; + } + } } //-------------------------------------------------------------------------------------------------- @@ -70,24 +70,24 @@ void RigNativeStatCalc::posNegClosestToZero(size_t timeStepIndex, double& pos, d { std::vector& values = m_resultsData->cellScalarResults(m_scalarResultIndex, timeStepIndex); - size_t i; - for (i = 0; i < values.size(); i++) - { - if (values[i] == HUGE_VAL) - { - continue; - } - - if (values[i] < pos && values[i] > 0) - { - pos = values[i]; - } - - if (values[i] > neg && values[i] < 0) - { - neg = values[i]; - } - } + size_t i; + for (i = 0; i < values.size(); i++) + { + if (values[i] == HUGE_VAL) + { + continue; + } + + if (values[i] < pos && values[i] > 0) + { + pos = values[i]; + } + + if (values[i] > neg && values[i] < 0) + { + neg = values[i]; + } + } } @@ -96,12 +96,12 @@ void RigNativeStatCalc::posNegClosestToZero(size_t timeStepIndex, double& pos, d //-------------------------------------------------------------------------------------------------- void RigNativeStatCalc::addDataToHistogramCalculator(RigHistogramCalculator& histogramCalculator) { - for (size_t tIdx = 0; tIdx < m_resultsData->timeStepCount(m_scalarResultIndex); tIdx++) - { + for (size_t tIdx = 0; tIdx < m_resultsData->timeStepCount(m_scalarResultIndex); tIdx++) + { std::vector& values = m_resultsData->cellScalarResults(m_scalarResultIndex, tIdx); - histogramCalculator.addData(values); - } + histogramCalculator.addData(values); + } } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ReservoirDataModel/RigNativeStatCalc.h b/ApplicationCode/ReservoirDataModel/RigNativeStatCalc.h index 5f506457e4..ece9cf800d 100644 --- a/ApplicationCode/ReservoirDataModel/RigNativeStatCalc.h +++ b/ApplicationCode/ReservoirDataModel/RigNativeStatCalc.h @@ -36,14 +36,14 @@ class RigNativeStatCalc : public RigStatisticsCalculator public: RigNativeStatCalc(RigCaseCellResultsData* cellResultsData, size_t scalarResultIndex); - virtual void minMaxCellScalarValues(size_t timeStepIndex, double& min, double& max); - virtual void posNegClosestToZero(size_t timeStepIndex, double& pos, double& neg); - virtual void valueSumAndSampleCount(double& valueSum, size_t& sampleCount); + virtual void minMaxCellScalarValues(size_t timeStepIndex, double& min, double& max); + virtual void posNegClosestToZero(size_t timeStepIndex, double& pos, double& neg); + virtual void valueSumAndSampleCount(double& valueSum, size_t& sampleCount); - virtual void addDataToHistogramCalculator(RigHistogramCalculator& histogramCalculator); + virtual void addDataToHistogramCalculator(RigHistogramCalculator& histogramCalculator); virtual size_t timeStepCount(); private: - RigCaseCellResultsData* m_resultsData; + RigCaseCellResultsData* m_resultsData; size_t m_scalarResultIndex; }; diff --git a/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.cpp b/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.cpp index c245f4eeff..11f91ba69a 100644 --- a/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.cpp +++ b/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.cpp @@ -136,7 +136,6 @@ void RigReservoirBuilderMock::appendCubeNodes(const cvf::Vec3d& min, const cvf:: //-------------------------------------------------------------------------------------------------- void RigReservoirBuilderMock::appendCells(size_t nodeStartIndex, size_t cellCount, RigGridBase* hostGrid, std::vector& cells) { - size_t activeCellIndex = 0; long long i; size_t cellIndexStart = cells.size(); @@ -347,11 +346,8 @@ bool RigReservoirBuilderMock::dynamicResult(RigCaseData* eclipseCase, const QStr #pragma omp parallel for for (long long k = 0; k < static_cast(eclipseCase->mainGrid()->cells().size()); k++) { - RigCell& cell = eclipseCase->mainGrid()->cells()[k]; - { - double val = offsetValue + scaleValue * ( (stepIndex * 1000 + k) % eclipseCase->mainGrid()->cells().size() ); - values->at(k) = val; - } + double val = offsetValue + scaleValue * ( (stepIndex * 1000 + k) % eclipseCase->mainGrid()->cells().size() ); + values->at(k) = val; } // Set result size to zero for some timesteps diff --git a/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.h b/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.h index 37b1c786ab..3e5f5cc713 100644 --- a/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.h +++ b/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.h @@ -70,7 +70,7 @@ class RigReservoirBuilderMock static void addNnc(RigMainGrid* grid, size_t i1, size_t j1, size_t k1, size_t i2, size_t j2, size_t k2, std::vector &nncConnections); void addWellData(RigCaseData* eclipseCase, RigGridBase* grid); static void appendCells(size_t nodeStartIndex, size_t cellCount, RigGridBase* hostGrid, std::vector& cells); - + static void appendNodes(const cvf::Vec3d& min, const cvf::Vec3d& max, const cvf::Vec3st& cubeDimension, std::vector& nodes); static void appendCubeNodes(const cvf::Vec3d& min, const cvf::Vec3d& max, std::vector& nodes); diff --git a/ApplicationCode/ReservoirDataModel/RigResultAccessor.cpp b/ApplicationCode/ReservoirDataModel/RigResultAccessor.cpp index 7d208c2774..37a9d99100 100644 --- a/ApplicationCode/ReservoirDataModel/RigResultAccessor.cpp +++ b/ApplicationCode/ReservoirDataModel/RigResultAccessor.cpp @@ -26,7 +26,7 @@ //-------------------------------------------------------------------------------------------------- double RigHugeValResultAccessor::cellScalar(size_t gridLocalCellIndex) const { - return HUGE_VAL; + return HUGE_VAL; } //-------------------------------------------------------------------------------------------------- @@ -34,5 +34,21 @@ double RigHugeValResultAccessor::cellScalar(size_t gridLocalCellIndex) const //-------------------------------------------------------------------------------------------------- double RigHugeValResultAccessor::cellFaceScalar(size_t gridLocalCellIndex, cvf::StructGridInterface::FaceType faceId) const { - return cellScalar(gridLocalCellIndex); + return cellScalar(gridLocalCellIndex); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RigHugeValResultAccessor::cellScalarGlobIdx(size_t globCellIndex) const +{ + return HUGE_VAL; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RigHugeValResultAccessor::cellFaceScalarGlobIdx(size_t globCellIndex, cvf::StructGridInterface::FaceType faceId) const +{ + return HUGE_VAL; } diff --git a/ApplicationCode/ReservoirDataModel/RigResultAccessor.h b/ApplicationCode/ReservoirDataModel/RigResultAccessor.h index 19c0037b49..cc416da9a4 100644 --- a/ApplicationCode/ReservoirDataModel/RigResultAccessor.h +++ b/ApplicationCode/ReservoirDataModel/RigResultAccessor.h @@ -34,6 +34,8 @@ class RigResultAccessor : public cvf::Object public: virtual double cellScalar(size_t gridLocalCellIndex) const = 0; virtual double cellFaceScalar(size_t gridLocalCellIndex, cvf::StructGridInterface::FaceType faceId) const = 0; + virtual double cellScalarGlobIdx(size_t globCellIndex) const = 0; + virtual double cellFaceScalarGlobIdx(size_t globCellIndex, cvf::StructGridInterface::FaceType faceId) const = 0; }; //================================================================================================== @@ -42,6 +44,8 @@ class RigResultAccessor : public cvf::Object class RigHugeValResultAccessor : public RigResultAccessor { public: - virtual double cellScalar(size_t gridLocalCellIndex) const; - virtual double cellFaceScalar(size_t gridLocalCellIndex, cvf::StructGridInterface::FaceType faceId) const; + virtual double cellScalar(size_t gridLocalCellIndex) const; + virtual double cellFaceScalar(size_t gridLocalCellIndex, cvf::StructGridInterface::FaceType faceId) const; + virtual double cellScalarGlobIdx(size_t globCellIndex) const; + virtual double cellFaceScalarGlobIdx(size_t globCellIndex, cvf::StructGridInterface::FaceType faceId) const; }; diff --git a/ApplicationCode/ReservoirDataModel/RigResultAccessorFactory.cpp b/ApplicationCode/ReservoirDataModel/RigResultAccessorFactory.cpp index 1986fcc3e0..5377028d91 100644 --- a/ApplicationCode/ReservoirDataModel/RigResultAccessorFactory.cpp +++ b/ApplicationCode/ReservoirDataModel/RigResultAccessorFactory.cpp @@ -41,30 +41,30 @@ /// //-------------------------------------------------------------------------------------------------- cvf::ref RigResultAccessorFactory::createResultAccessor(RigCaseData* eclipseCase, - size_t gridIndex, - RifReaderInterface::PorosityModelResultType porosityModel, - size_t timeStepIndex, - const QString& uiResultName) + size_t gridIndex, + RifReaderInterface::PorosityModelResultType porosityModel, + size_t timeStepIndex, + const QString& uiResultName) { - CVF_ASSERT(gridIndex < eclipseCase->gridCount()); - CVF_ASSERT(eclipseCase); - CVF_ASSERT(eclipseCase->results(porosityModel)); - CVF_ASSERT(eclipseCase->activeCellInfo(porosityModel)); + CVF_ASSERT(gridIndex < eclipseCase->gridCount()); + CVF_ASSERT(eclipseCase); + CVF_ASSERT(eclipseCase->results(porosityModel)); + CVF_ASSERT(eclipseCase->activeCellInfo(porosityModel)); - RigGridBase* grid = eclipseCase->grid(gridIndex); + RigGridBase* grid = eclipseCase->grid(gridIndex); - if (uiResultName == RimDefines::combinedTransmissibilityResultName()) - { - cvf::ref cellFaceAccessObject = new RigCombTransResultAccessor(grid); + if (uiResultName == RimDefines::combinedTransmissibilityResultName()) + { + cvf::ref cellFaceAccessObject = new RigCombTransResultAccessor(grid); - cvf::ref xTransAccessor = RigResultAccessorFactory::createNativeResultAccessor(eclipseCase, gridIndex, porosityModel, timeStepIndex, "TRANX"); - cvf::ref yTransAccessor = RigResultAccessorFactory::createNativeResultAccessor(eclipseCase, gridIndex, porosityModel, timeStepIndex, "TRANY"); - cvf::ref zTransAccessor = RigResultAccessorFactory::createNativeResultAccessor(eclipseCase, gridIndex, porosityModel, timeStepIndex, "TRANZ"); + cvf::ref xTransAccessor = RigResultAccessorFactory::createNativeResultAccessor(eclipseCase, gridIndex, porosityModel, timeStepIndex, "TRANX"); + cvf::ref yTransAccessor = RigResultAccessorFactory::createNativeResultAccessor(eclipseCase, gridIndex, porosityModel, timeStepIndex, "TRANY"); + cvf::ref zTransAccessor = RigResultAccessorFactory::createNativeResultAccessor(eclipseCase, gridIndex, porosityModel, timeStepIndex, "TRANZ"); - cellFaceAccessObject->setTransResultAccessors(xTransAccessor.p(), yTransAccessor.p(), zTransAccessor.p()); + cellFaceAccessObject->setTransResultAccessors(xTransAccessor.p(), yTransAccessor.p(), zTransAccessor.p()); - return cellFaceAccessObject; - } + return cellFaceAccessObject; + } else if (uiResultName == RimDefines::combinedMultResultName()) { cvf::ref cellFaceAccessObject = new RigCombMultResultAccessor(grid); @@ -116,38 +116,36 @@ cvf::ref RigResultAccessorFactory::createResultAccessor(RigCa return cellFaceAccessObject; } - return RigResultAccessorFactory::createNativeResultAccessor(eclipseCase, gridIndex, porosityModel, timeStepIndex, uiResultName); + return RigResultAccessorFactory::createNativeResultAccessor(eclipseCase, gridIndex, porosityModel, timeStepIndex, uiResultName); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- cvf::ref RigResultAccessorFactory::createResultAccessor(RigCaseData* eclipseCase, - size_t gridIndex, - RifReaderInterface::PorosityModelResultType porosityModel, - size_t timeStepIndex, - const QString& uiResultName, - RimDefines::ResultCatType resultType) + size_t gridIndex, + RifReaderInterface::PorosityModelResultType porosityModel, + size_t timeStepIndex, + const QString& uiResultName, + RimDefines::ResultCatType resultType) { - CVF_ASSERT(gridIndex < eclipseCase->gridCount()); - CVF_ASSERT(eclipseCase); - CVF_ASSERT(eclipseCase->results(porosityModel)); - CVF_ASSERT(eclipseCase->activeCellInfo(porosityModel)); - - RigGridBase *grid = eclipseCase->grid(gridIndex); + CVF_ASSERT(gridIndex < eclipseCase->gridCount()); + CVF_ASSERT(eclipseCase); + CVF_ASSERT(eclipseCase->results(porosityModel)); + CVF_ASSERT(eclipseCase->activeCellInfo(porosityModel)); - if (!eclipseCase || !eclipseCase->results(porosityModel) || !eclipseCase->activeCellInfo(porosityModel)) - { - return NULL; - } + if (!eclipseCase || !eclipseCase->results(porosityModel) || !eclipseCase->activeCellInfo(porosityModel)) + { + return NULL; + } - size_t scalarSetIndex = eclipseCase->results(porosityModel)->findScalarResultIndex(resultType, uiResultName); - if (scalarSetIndex == cvf::UNDEFINED_SIZE_T) - { - return NULL; - } + size_t scalarSetIndex = eclipseCase->results(porosityModel)->findScalarResultIndex(resultType, uiResultName); + if (scalarSetIndex == cvf::UNDEFINED_SIZE_T) + { + return NULL; + } - return createResultAccessor(eclipseCase, gridIndex, porosityModel, timeStepIndex, scalarSetIndex); + return createResultAccessor(eclipseCase, gridIndex, porosityModel, timeStepIndex, scalarSetIndex); } //-------------------------------------------------------------------------------------------------- @@ -164,8 +162,6 @@ cvf::ref RigResultAccessorFactory::createNativeResultAccessor CVF_ASSERT(eclipseCase->results(porosityModel)); CVF_ASSERT(eclipseCase->activeCellInfo(porosityModel)); - RigGridBase *grid = eclipseCase->grid(gridIndex); - if (!eclipseCase || !eclipseCase->results(porosityModel) || !eclipseCase->activeCellInfo(porosityModel)) { return NULL; @@ -177,56 +173,56 @@ cvf::ref RigResultAccessorFactory::createNativeResultAccessor return NULL; } - return createResultAccessor(eclipseCase, gridIndex, porosityModel, timeStepIndex, scalarSetIndex); + return createResultAccessor(eclipseCase, gridIndex, porosityModel, timeStepIndex, scalarSetIndex); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- cvf::ref RigResultAccessorFactory::createResultAccessor(RigCaseData* eclipseCase, - size_t gridIndex, - RifReaderInterface::PorosityModelResultType porosityModel, - size_t timeStepIndex, - size_t resultIndex) + size_t gridIndex, + RifReaderInterface::PorosityModelResultType porosityModel, + size_t timeStepIndex, + size_t resultIndex) { - if (resultIndex == cvf::UNDEFINED_SIZE_T) - { - return new RigHugeValResultAccessor; - } - - if (!eclipseCase) return NULL; - - RigGridBase* grid = eclipseCase->grid(gridIndex); - if (!grid) return NULL; - - std::vector< std::vector >& scalarSetResults = eclipseCase->results(porosityModel)->cellScalarResults(resultIndex); - - if (timeStepIndex >= scalarSetResults.size()) - { - return new RigHugeValResultAccessor; - } - - std::vector* resultValues = NULL; - if (timeStepIndex < scalarSetResults.size()) - { - resultValues = &(scalarSetResults[timeStepIndex]); - } - - if (!resultValues || resultValues->size() == 0) - { - return new RigHugeValResultAccessor; - } - - bool useGlobalActiveIndex = eclipseCase->results(porosityModel)->isUsingGlobalActiveIndex(resultIndex); - if (useGlobalActiveIndex) - { - cvf::ref object = new RigActiveCellsResultAccessor(grid, resultValues, eclipseCase->activeCellInfo(porosityModel)); - return object; - } - else - { - cvf::ref object = new RigAllGridCellsResultAccessor(grid, resultValues); - return object; - } + if (resultIndex == cvf::UNDEFINED_SIZE_T) + { + return new RigHugeValResultAccessor; + } + + if (!eclipseCase) return NULL; + + RigGridBase* grid = eclipseCase->grid(gridIndex); + if (!grid) return NULL; + + std::vector< std::vector >& scalarSetResults = eclipseCase->results(porosityModel)->cellScalarResults(resultIndex); + + if (timeStepIndex >= scalarSetResults.size()) + { + return new RigHugeValResultAccessor; + } + + std::vector* resultValues = NULL; + if (timeStepIndex < scalarSetResults.size()) + { + resultValues = &(scalarSetResults[timeStepIndex]); + } + + if (!resultValues || resultValues->size() == 0) + { + return new RigHugeValResultAccessor; + } + + bool useGlobalActiveIndex = eclipseCase->results(porosityModel)->isUsingGlobalActiveIndex(resultIndex); + if (useGlobalActiveIndex) + { + cvf::ref object = new RigActiveCellsResultAccessor(grid, resultValues, eclipseCase->activeCellInfo(porosityModel)); + return object; + } + else + { + cvf::ref object = new RigAllGridCellsResultAccessor(grid, resultValues); + return object; + } } diff --git a/ApplicationCode/ReservoirDataModel/RigResultAccessorFactory.h b/ApplicationCode/ReservoirDataModel/RigResultAccessorFactory.h index 53815e4189..aec039f3fe 100644 --- a/ApplicationCode/ReservoirDataModel/RigResultAccessorFactory.h +++ b/ApplicationCode/ReservoirDataModel/RigResultAccessorFactory.h @@ -36,20 +36,20 @@ class RigResultAccessorFactory size_t timeStepIndex, const QString& uiResultName); - static cvf::ref - createResultAccessor(RigCaseData* eclipseCase, - size_t gridIndex, - RifReaderInterface::PorosityModelResultType porosityModel, - size_t timeStepIndex, - const QString& uiResultName, - RimDefines::ResultCatType resultType); + static cvf::ref + createResultAccessor(RigCaseData* eclipseCase, + size_t gridIndex, + RifReaderInterface::PorosityModelResultType porosityModel, + size_t timeStepIndex, + const QString& uiResultName, + RimDefines::ResultCatType resultType); - static cvf::ref - createResultAccessor(RigCaseData* eclipseCase, - size_t gridIndex, - RifReaderInterface::PorosityModelResultType porosityModel, - size_t timeStepIndex, - size_t resultIndex); + static cvf::ref + createResultAccessor(RigCaseData* eclipseCase, + size_t gridIndex, + RifReaderInterface::PorosityModelResultType porosityModel, + size_t timeStepIndex, + size_t resultIndex); diff --git a/ApplicationCode/ReservoirDataModel/RigResultModifierFactory.cpp b/ApplicationCode/ReservoirDataModel/RigResultModifierFactory.cpp index 30cb443232..bb7746d9d2 100644 --- a/ApplicationCode/ReservoirDataModel/RigResultModifierFactory.cpp +++ b/ApplicationCode/ReservoirDataModel/RigResultModifierFactory.cpp @@ -35,7 +35,7 @@ cvf::ref RigResultModifierFactory::createResultModifier(RigCa size_t timeStepIndex, QString& uiResultName) { - if (!eclipseCase) return NULL; + if (!eclipseCase) return NULL; if (!eclipseCase->results(porosityModel) || !eclipseCase->activeCellInfo(porosityModel)) { @@ -56,12 +56,12 @@ cvf::ref RigResultModifierFactory::createResultModifier(RigCa RifReaderInterface::PorosityModelResultType porosityModel, size_t timeStepIndex, size_t scalarResultIndex) { - if (!eclipseCase) return NULL; + if (!eclipseCase) return NULL; - if (!eclipseCase->results(porosityModel) || !eclipseCase->activeCellInfo(porosityModel)) - { - return NULL; - } + if (!eclipseCase->results(porosityModel) || !eclipseCase->activeCellInfo(porosityModel)) + { + return NULL; + } if (scalarResultIndex == cvf::UNDEFINED_SIZE_T) { @@ -69,10 +69,10 @@ cvf::ref RigResultModifierFactory::createResultModifier(RigCa } RigGridBase* grid = eclipseCase->grid(gridIndex); - if (!grid) - { - return NULL; - } + if (!grid) + { + return NULL; + } std::vector< std::vector >& scalarSetResults = eclipseCase->results(porosityModel)->cellScalarResults(scalarResultIndex); diff --git a/ApplicationCode/ReservoirDataModel/RigSingleWellResultsData.cpp b/ApplicationCode/ReservoirDataModel/RigSingleWellResultsData.cpp index 6e2797af94..d62cacd574 100644 --- a/ApplicationCode/ReservoirDataModel/RigSingleWellResultsData.cpp +++ b/ApplicationCode/ReservoirDataModel/RigSingleWellResultsData.cpp @@ -155,8 +155,6 @@ void RigSingleWellResultsData::computeStaticWellCellPath() std::vector& resBranch = m_wellCellsTimeSteps[tIdx].m_wellResultBranches[bIdx].m_branchResultPoints; std::list< RigWellResultPoint >& stBranch = staticWellBranches[branchId]; - std::list< RigWellResultPoint >::iterator it; - std::list< RigWellResultPoint >::iterator sStartIt; std::list< RigWellResultPoint >::iterator sEndIt; size_t rStartIdx; size_t rEndIdx; @@ -190,7 +188,6 @@ void RigSingleWellResultsData::computeStaticWellCellPath() rEndIdx = 0; } - sStartIt = sEndIt; rStartIdx = rEndIdx; } @@ -227,7 +224,6 @@ void RigSingleWellResultsData::computeStaticWellCellPath() rEndIdx = rStartIdx; } - sStartIt = sEndIt; rStartIdx = rEndIdx; } diff --git a/ApplicationCode/ReservoirDataModel/RigTernaryResultAccessor2d.cpp b/ApplicationCode/ReservoirDataModel/RigTernaryResultAccessor2d.cpp index d3ab6568b8..570a22f799 100644 --- a/ApplicationCode/ReservoirDataModel/RigTernaryResultAccessor2d.cpp +++ b/ApplicationCode/ReservoirDataModel/RigTernaryResultAccessor2d.cpp @@ -35,9 +35,9 @@ RigTernaryResultAccessor::RigTernaryResultAccessor() //-------------------------------------------------------------------------------------------------- void RigTernaryResultAccessor::setTernaryResultAccessors(RigResultAccessor* soil, RigResultAccessor* sgas, RigResultAccessor* swat) { - m_soilAccessor = soil; - m_sgasAccessor = sgas; - m_swatAccessor = swat; + m_soilAccessor = soil; + m_sgasAccessor = sgas; + m_swatAccessor = swat; } //-------------------------------------------------------------------------------------------------- @@ -45,48 +45,48 @@ void RigTernaryResultAccessor::setTernaryResultAccessors(RigResultAccessor* soil //-------------------------------------------------------------------------------------------------- cvf::Vec2d RigTernaryResultAccessor::cellScalar(size_t gridLocalCellIndex) const { - double soil = 0.0; - double sgas = 0.0; + double soil = 0.0; + double sgas = 0.0; - if (m_soilAccessor.notNull()) - { - soil = m_soilAccessor->cellScalar(gridLocalCellIndex); + if (m_soilAccessor.notNull()) + { + soil = m_soilAccessor->cellScalar(gridLocalCellIndex); - if (m_sgasAccessor.notNull()) - { - sgas = m_sgasAccessor->cellScalar(gridLocalCellIndex); - } - else if (m_swatAccessor.notNull()) - { - sgas = 1.0 - soil - m_swatAccessor->cellScalar(gridLocalCellIndex); - } - else - { - sgas = 1.0 - soil; - } - } - else - { - if (m_sgasAccessor.notNull()) - { - sgas = m_sgasAccessor->cellScalar(gridLocalCellIndex); + if (m_sgasAccessor.notNull()) + { + sgas = m_sgasAccessor->cellScalar(gridLocalCellIndex); + } + else if (m_swatAccessor.notNull()) + { + sgas = 1.0 - soil - m_swatAccessor->cellScalar(gridLocalCellIndex); + } + else + { + sgas = 1.0 - soil; + } + } + else + { + if (m_sgasAccessor.notNull()) + { + sgas = m_sgasAccessor->cellScalar(gridLocalCellIndex); - if (m_swatAccessor.notNull()) - { - soil = 1.0 - sgas - m_swatAccessor->cellScalar(gridLocalCellIndex); - } - else - { - soil = 1.0 - sgas; - } - } - else if (m_swatAccessor.notNull()) - { - soil = 1.0 - m_swatAccessor->cellScalar(gridLocalCellIndex); - } - } + if (m_swatAccessor.notNull()) + { + soil = 1.0 - sgas - m_swatAccessor->cellScalar(gridLocalCellIndex); + } + else + { + soil = 1.0 - sgas; + } + } + else if (m_swatAccessor.notNull()) + { + soil = 1.0 - m_swatAccessor->cellScalar(gridLocalCellIndex); + } + } - return cvf::Vec2d(soil, sgas); + return cvf::Vec2d(soil, sgas); } //-------------------------------------------------------------------------------------------------- @@ -94,5 +94,5 @@ cvf::Vec2d RigTernaryResultAccessor::cellScalar(size_t gridLocalCellIndex) const //-------------------------------------------------------------------------------------------------- cvf::Vec2d RigTernaryResultAccessor::cellFaceScalar(size_t gridLocalCellIndex, cvf::StructGridInterface::FaceType faceId) const { - return cellScalar(gridLocalCellIndex); + return cellScalar(gridLocalCellIndex); } diff --git a/ApplicationCode/ReservoirDataModel/RigTernaryResultAccessor2d.h b/ApplicationCode/ReservoirDataModel/RigTernaryResultAccessor2d.h index c081ae3896..a85015e8b7 100644 --- a/ApplicationCode/ReservoirDataModel/RigTernaryResultAccessor2d.h +++ b/ApplicationCode/ReservoirDataModel/RigTernaryResultAccessor2d.h @@ -28,19 +28,19 @@ class RigTernaryResultAccessor : public RigResultAccessor2d { public: - RigTernaryResultAccessor(); + RigTernaryResultAccessor(); - /// Requires two of the arguments to be present - void setTernaryResultAccessors(RigResultAccessor* soil, RigResultAccessor* sgas, RigResultAccessor* swat); + /// Requires two of the arguments to be present + void setTernaryResultAccessors(RigResultAccessor* soil, RigResultAccessor* sgas, RigResultAccessor* swat); - /// Returns [SOIL, SGAS] regardless of which one of the three is missing. if Soil or SWat is missing, it is calculated - /// based on the two others - virtual cvf::Vec2d cellScalar(size_t gridLocalCellIndex) const; - virtual cvf::Vec2d cellFaceScalar(size_t gridLocalCellIndex, cvf::StructGridInterface::FaceType faceId) const; + /// Returns [SOIL, SGAS] regardless of which one of the three is missing. if Soil or SWat is missing, it is calculated + /// based on the two others + virtual cvf::Vec2d cellScalar(size_t gridLocalCellIndex) const; + virtual cvf::Vec2d cellFaceScalar(size_t gridLocalCellIndex, cvf::StructGridInterface::FaceType faceId) const; private: - cvf::ref m_soilAccessor; - cvf::ref m_sgasAccessor; - cvf::ref m_swatAccessor; + cvf::ref m_soilAccessor; + cvf::ref m_sgasAccessor; + cvf::ref m_swatAccessor; }; diff --git a/ApplicationCode/ReservoirDataModel/RigWellLogCurveData.cpp b/ApplicationCode/ReservoirDataModel/RigWellLogCurveData.cpp new file mode 100644 index 0000000000..e11cf920a7 --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/RigWellLogCurveData.cpp @@ -0,0 +1,319 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RigWellLogCurveData.h" + +#include "cvfMath.h" +#include "cvfAssert.h" + +#include + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigWellLogCurveData::RigWellLogCurveData() +{ + m_isExtractionCurve = false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigWellLogCurveData::~RigWellLogCurveData() +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigWellLogCurveData::setValuesAndMD(const std::vector& xValues, + const std::vector& measuredDepths, + bool isExtractionCurve) +{ + CVF_ASSERT(xValues.size() == measuredDepths.size()); + + m_xValues = xValues; + m_measuredDepths = measuredDepths; + m_tvDepths.clear(); + + // Disable depth value filtering is intended to be used for + // extraction curve data + m_isExtractionCurve = isExtractionCurve; + + calculateIntervalsOfContinousValidValues(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigWellLogCurveData::setValuesWithTVD(const std::vector& xValues, + const std::vector& measuredDepths, + const std::vector& tvDepths) +{ + CVF_ASSERT(xValues.size() == measuredDepths.size()); + + m_xValues = xValues; + m_measuredDepths = measuredDepths; + m_tvDepths = tvDepths; + + // Always use value filtering when TVD is present + m_isExtractionCurve = true; + + calculateIntervalsOfContinousValidValues(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const std::vector& RigWellLogCurveData::xValues() const +{ + return m_xValues; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const std::vector& RigWellLogCurveData::measuredDepths() const +{ + return m_measuredDepths; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RigWellLogCurveData::xPlotValues() const +{ + std::vector filteredValues; + getValuesByIntervals(m_xValues, m_intervalsOfContinousValidValues, &filteredValues); + + return filteredValues; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RigWellLogCurveData::depthPlotValues() const +{ + std::vector filteredValues; + if (m_tvDepths.size()) + { + getValuesByIntervals(m_tvDepths, m_intervalsOfContinousValidValues, &filteredValues); + } + else + { + getValuesByIntervals(m_measuredDepths, m_intervalsOfContinousValidValues, &filteredValues); + } + + return filteredValues; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector< std::pair > RigWellLogCurveData::polylineStartStopIndices() const +{ + std::vector< std::pair > lineStartStopIndices; + computePolyLineStartStopIndices(m_intervalsOfContinousValidValues, &lineStartStopIndices); + + return lineStartStopIndices; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigWellLogCurveData::calculateIntervalsOfContinousValidValues() +{ + std::vector< std::pair > intervalsOfValidValues; + calculateIntervalsOfValidValues(m_xValues, &intervalsOfValidValues); + + m_intervalsOfContinousValidValues.clear(); + + if (!m_isExtractionCurve) + { + m_intervalsOfContinousValidValues = intervalsOfValidValues; + } + else + { + size_t intervalsCount = intervalsOfValidValues.size(); + for (size_t intIdx = 0; intIdx < intervalsCount; intIdx++) + { + std::vector< std::pair > depthValuesIntervals; + splitIntervalAtEmptySpace(m_measuredDepths, + intervalsOfValidValues[intIdx].first, intervalsOfValidValues[intIdx].second, + &depthValuesIntervals); + + for (size_t dvintIdx = 0; dvintIdx < depthValuesIntervals.size(); dvintIdx++) + { + m_intervalsOfContinousValidValues.push_back(depthValuesIntervals[dvintIdx]); + } + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigWellLogCurveData::calculateIntervalsOfValidValues(const std::vector& values, std::vector< std::pair >* intervals) +{ + CVF_ASSERT(intervals); + + int startIdx = -1; + size_t vIdx = 0; + + size_t valueCount = values.size(); + while (vIdx < valueCount) + { + double value = values[vIdx]; + if (value == HUGE_VAL || value == -HUGE_VAL || value != value) + { + if (startIdx >= 0) + { + intervals->push_back(std::make_pair(startIdx, vIdx - 1)); + startIdx = -1; + } + } + else if (startIdx < 0) + { + startIdx = (int)vIdx; + } + + vIdx++; + } + + if (startIdx >= 0 && startIdx < ((int)valueCount)) + { + intervals->push_back(std::make_pair(startIdx, valueCount - 1)); + } +} + +//-------------------------------------------------------------------------------------------------- +/// Splits the start stop interval between cells that are not close enough. +/// The depth values are expected to contain pair of depths: Depth at cell enter, and cell leave +//-------------------------------------------------------------------------------------------------- +void RigWellLogCurveData::splitIntervalAtEmptySpace(const std::vector& depthValues, + size_t startIdx, size_t stopIdx, + std::vector< std::pair >* intervals) +{ + CVF_ASSERT(intervals); + + CVF_ASSERT(startIdx < stopIdx); + + if (stopIdx - startIdx == 1) + { + intervals->push_back(std::make_pair(startIdx, stopIdx)); + return; + } + + // !! TODO: Find a reasonable tolerance + const double depthDiffTolerance = 0.1; + + // Find intervals containing depth values that should be connected + size_t intStartIdx = startIdx; + for (size_t vIdx = startIdx + 1; vIdx < stopIdx; vIdx += 2) + { + if (cvf::Math::abs(depthValues[vIdx + 1] - depthValues[vIdx]) > depthDiffTolerance) + { + intervals->push_back(std::make_pair(intStartIdx, vIdx)); + intStartIdx = vIdx + 1; + } + } + + if (intStartIdx <= stopIdx) + { + intervals->push_back(std::make_pair(intStartIdx, stopIdx)); + } +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigWellLogCurveData::getValuesByIntervals(const std::vector& values, + const std::vector< std::pair >& intervals, + std::vector* filteredValues) +{ + CVF_ASSERT(filteredValues); + + for (size_t intIdx = 0; intIdx < intervals.size(); intIdx++) + { + for (size_t vIdx = intervals[intIdx].first; vIdx <= intervals[intIdx].second; vIdx++) + { + filteredValues->push_back(values[vIdx]); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigWellLogCurveData::computePolyLineStartStopIndices(const std::vector< std::pair >& intervals, + std::vector< std::pair >* fltrIntervals) +{ + CVF_ASSERT(fltrIntervals); + + const size_t intervalCount = intervals.size(); + if (intervalCount < 1) return; + + size_t index = 0; + for (size_t intIdx = 0; intIdx < intervalCount; intIdx++) + { + size_t intervalSize = intervals[intIdx].second - intervals[intIdx].first + 1; + fltrIntervals->push_back(std::make_pair(index, index + intervalSize - 1)); + + index += intervalSize; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RigWellLogCurveData::calculateMDRange(double* minimumDepth, double* maximumDepth) const +{ + CVF_ASSERT(minimumDepth && maximumDepth); + + double minValue = HUGE_VAL; + double maxValue = -HUGE_VAL; + + for (size_t vIdx = 0; vIdx < m_measuredDepths.size(); vIdx++) + { + double value = m_measuredDepths[vIdx]; + + if (value < minValue) + { + minValue = value; + } + + if (value > maxValue) + { + maxValue = value; + } + } + + if (maxValue >= minValue) + { + *minimumDepth = minValue; + *maximumDepth = maxValue; + + return true; + } + + return false; +} diff --git a/ApplicationCode/ReservoirDataModel/RigWellLogCurveData.h b/ApplicationCode/ReservoirDataModel/RigWellLogCurveData.h new file mode 100644 index 0000000000..a5025ec98b --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/RigWellLogCurveData.h @@ -0,0 +1,89 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cvfBase.h" +#include "cvfObject.h" + +#include + +class RigWellLogCurveDataTestInterface; + +//================================================================================================== +/// +//================================================================================================== +class RigWellLogCurveData : public cvf::Object +{ +public: + RigWellLogCurveData(); + virtual ~RigWellLogCurveData(); + + void setValuesAndMD(const std::vector& xValues, + const std::vector& measuredDepths, + bool isExtractionCurve); + void setValuesWithTVD(const std::vector& xValues, + const std::vector& measuredDepths, + const std::vector& tvDepths ); + + const std::vector& xValues() const; + const std::vector& measuredDepths() const; + bool calculateMDRange(double* minMD, double* maxMD) const; + + std::vector xPlotValues() const; + std::vector depthPlotValues() const; + std::vector< std::pair > polylineStartStopIndices() const; + +private: + void calculateIntervalsOfContinousValidValues(); + + static void calculateIntervalsOfValidValues(const std::vector& values, + std::vector< std::pair >* intervals); + static void splitIntervalAtEmptySpace(const std::vector& depthValues, + size_t startIdx, size_t stopIdx, + std::vector< std::pair >* intervals); + + static void getValuesByIntervals(const std::vector& values, + const std::vector< std::pair >& intervals, + std::vector* filteredValues); + static void computePolyLineStartStopIndices(const std::vector< std::pair >& intervals, + std::vector< std::pair >* filteredIntervals); + +private: + std::vector m_xValues; + std::vector m_measuredDepths; + std::vector m_tvDepths; + bool m_isExtractionCurve; + + std::vector< std::pair > m_intervalsOfContinousValidValues; + + friend class RigWellLogCurveDataTestInterface; +}; + +//================================================================================================== +/// +//================================================================================================== +class RigWellLogCurveDataTestInterface +{ +public: + static void calculateIntervalsOfValidValues(const std::vector& values, std::vector< std::pair >* intervals) + { + RigWellLogCurveData::calculateIntervalsOfValidValues(values, intervals); + } +}; diff --git a/ApplicationCode/ReservoirDataModel/RigWellLogExtractionTools.h b/ApplicationCode/ReservoirDataModel/RigWellLogExtractionTools.h new file mode 100644 index 0000000000..4232183bf6 --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/RigWellLogExtractionTools.h @@ -0,0 +1,189 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once +#include "cvfBoundingBox.h" +#include "cvfGeometryTools.h" +#include "cvfStructGrid.h" + +//================================================================================================== +/// Internal class for intersection point info +//================================================================================================== + +struct HexIntersectionInfo +{ + +public: + HexIntersectionInfo( cvf::Vec3d intersectionPoint, + bool isIntersectionEntering, + cvf::StructGridInterface::FaceType face, + size_t hexIndex) + : m_intersectionPoint(intersectionPoint), + m_isIntersectionEntering(isIntersectionEntering), + m_face(face), + m_hexIndex(hexIndex) {} + + + cvf::Vec3d m_intersectionPoint; + bool m_isIntersectionEntering; + cvf::StructGridInterface::FaceType m_face; + size_t m_hexIndex; +}; + +//-------------------------------------------------------------------------------------------------- +/// Specialized Line - Hex intersection +//-------------------------------------------------------------------------------------------------- +struct RigHexIntersector +{ + static int lineHexCellIntersection(const cvf::Vec3d p1, const cvf::Vec3d p2, const cvf::Vec3d hexCorners[8], const size_t hexIndex, + std::vector* intersections) + { + CVF_ASSERT(intersections != NULL); + + int intersectionCount = 0; + + for (int face = 0; face < 6 ; ++face) + { + cvf::ubyte faceVertexIndices[4]; + cvf::StructGridInterface::cellFaceVertexIndices(static_cast(face), faceVertexIndices); + + cvf::Vec3d intersection; + bool isEntering = false; + cvf::Vec3d faceCenter = cvf::GeometryTools::computeFaceCenter(hexCorners[faceVertexIndices[0]], hexCorners[faceVertexIndices[1]], hexCorners[faceVertexIndices[2]], hexCorners[faceVertexIndices[3]]); + + for (int i = 0; i < 4; ++i) + { + int next = i < 3 ? i+1 : 0; + + int intsStatus = cvf::GeometryTools::intersectLineSegmentTriangle(p1, p2, + hexCorners[faceVertexIndices[i]], + hexCorners[faceVertexIndices[next]], + faceCenter, + &intersection, + &isEntering); + if (intsStatus == 1) + { + intersectionCount++; + intersections->push_back(HexIntersectionInfo(intersection, + isEntering, + static_cast(face), hexIndex)); + } + } + } + + return intersectionCount; + } + + static bool isEqualDepth(double d1, double d2) + { + double depthDiff = d1 - d2; + + const double tolerance = 0.1;// Meters To handle inaccuracies across faults + + return (fabs(depthDiff) < tolerance); // Equal depth + } +}; + +//================================================================================================== +/// Class used to sort the intersections along the wellpath, +/// Use as key in a map +/// Sorting according to MD first, then Cell Idx, then Leaving before entering cell +//================================================================================================== + +struct RigMDCellIdxEnterLeaveKey +{ + RigMDCellIdxEnterLeaveKey(double md, size_t cellIdx, bool entering): measuredDepth(md), hexIndex(cellIdx), isEnteringCell(entering){} + + double measuredDepth; + size_t hexIndex; + bool isEnteringCell; // As opposed to leaving. + bool isLeavingCell() const { return !isEnteringCell;} + + bool operator < (const RigMDCellIdxEnterLeaveKey& other) const + { + if (RigHexIntersector::isEqualDepth(measuredDepth, other.measuredDepth)) + { + if (hexIndex == other.hexIndex) + { + if (isEnteringCell == other.isEnteringCell) + { + // Completely equal: intersections at cell edges or corners or edges of the face triangles + return false; + } + + return !isEnteringCell; // Sort Leaving cell before (less than) entering cell + } + + return (hexIndex < other.hexIndex); + } + + // The depths are not equal + + return (measuredDepth < other.measuredDepth); + } +}; + + +//================================================================================================== +/// Class used to sort the intersections along the wellpath, +/// Use as key in a map +/// Sorting according to MD first,then Leaving before entering cell, then Cell Idx, +//================================================================================================== + +struct RigMDEnterLeaveCellIdxKey +{ + RigMDEnterLeaveCellIdxKey(double md, bool entering, size_t cellIdx ): measuredDepth(md), hexIndex(cellIdx), isEnteringCell(entering){} + + double measuredDepth; + bool isEnteringCell; // As opposed to leaving. + bool isLeavingCell() const { return !isEnteringCell;} + size_t hexIndex; + + bool operator < (const RigMDEnterLeaveCellIdxKey& other) const + { + if (RigHexIntersector::isEqualDepth(measuredDepth, other.measuredDepth)) + { + if (isEnteringCell == other.isEnteringCell) + { + if (hexIndex == other.hexIndex) + { + // Completely equal: intersections at cell edges or corners or edges of the face triangles + return false; + } + + return (hexIndex < other.hexIndex); + } + + return isLeavingCell(); // Sort Leaving cell before (less than) entering cell + } + + // The depths are not equal + + return (measuredDepth < other.measuredDepth); + } + + static bool isProperCellEnterLeavePair(const RigMDEnterLeaveCellIdxKey& key1, const RigMDEnterLeaveCellIdxKey& key2 ) + { + return ( key1.hexIndex == key2.hexIndex + && key1.isEnteringCell && key2.isLeavingCell() + && !RigHexIntersector::isEqualDepth(key1.measuredDepth, key2.measuredDepth)); + } +}; + + diff --git a/ApplicationCode/ReservoirDataModel/RigWellLogExtractor.cpp b/ApplicationCode/ReservoirDataModel/RigWellLogExtractor.cpp new file mode 100644 index 0000000000..ff3742806d --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/RigWellLogExtractor.cpp @@ -0,0 +1,234 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RigWellLogExtractor.h" +#include "RigWellPath.h" +#include "cvfTrace.h" + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigWellLogExtractor::RigWellLogExtractor(const RigWellPath* wellpath, const std::string& wellCaseErrorMsgName) : m_wellPath(wellpath), m_wellCaseErrorMsgName(wellCaseErrorMsgName) +{ + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigWellLogExtractor::~RigWellLogExtractor() +{ + +} +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigWellLogExtractor::insertIntersectionsInMap(const std::vector &intersections, cvf::Vec3d p1, double md1, cvf::Vec3d p2, double md2, + std::map *uniqueIntersections) +{ + for (size_t intIdx = 0; intIdx < intersections.size(); ++intIdx) + { + double lenghtAlongLineSegment1 = (intersections[intIdx].m_intersectionPoint - p1).length(); + double lenghtAlongLineSegment2 = (p2 - intersections[intIdx].m_intersectionPoint).length(); + double measuredDepthDiff = md2 - md1; + double lineLength = lenghtAlongLineSegment1 + lenghtAlongLineSegment2; + double measuredDepthOfPoint = 0.0; + + if (lineLength > 0.00001) + { + measuredDepthOfPoint = md1 + measuredDepthDiff*lenghtAlongLineSegment1/(lineLength); + } + else + { + measuredDepthOfPoint = md1; + } + + uniqueIntersections->insert(std::make_pair(RigMDCellIdxEnterLeaveKey(measuredDepthOfPoint, + intersections[intIdx].m_hexIndex, + intersections[intIdx].m_isIntersectionEntering), + intersections[intIdx])); + } +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigWellLogExtractor::populateReturnArrays(std::map &uniqueIntersections) +{ + // For same MD and same cell, remove enter/leave pairs, as they only touches the wellpath, and should not contribute. + { + std::map::iterator it1 = uniqueIntersections.begin(); + std::map::iterator it2 = uniqueIntersections.begin(); + + std::vector::iterator> iteratorsToIntersectonsToErase; + + while (it2 != uniqueIntersections.end()) + { + ++it2; + if (it2 != uniqueIntersections.end()) + { + if (RigHexIntersector::isEqualDepth(it1->first.measuredDepth, it2->first.measuredDepth)) + { + if (it1->first.hexIndex == it2->first.hexIndex) + { + // Remove the two from the map, as they just are a touch of the cell surface + CVF_TIGHT_ASSERT(!it1->first.isEnteringCell && it2->first.isEnteringCell); + + iteratorsToIntersectonsToErase.push_back(it1); + iteratorsToIntersectonsToErase.push_back(it2); + } + } + } + ++it1; + } + + // Erase all the intersections that is not needed + for (size_t erItIdx = 0; erItIdx < iteratorsToIntersectonsToErase.size(); ++erItIdx) + { + uniqueIntersections.erase(iteratorsToIntersectonsToErase[erItIdx]); + } + } + + // Copy the map into a different sorting regime, with enter leave more significant than cell index + + std::map sortedUniqueIntersections; + { + std::map::iterator it = uniqueIntersections.begin(); + while (it != uniqueIntersections.end()) + { + sortedUniqueIntersections.insert(std::make_pair(RigMDEnterLeaveCellIdxKey(it->first.measuredDepth, it->first.isEnteringCell, it->first.hexIndex), + it->second)); + ++it; + } + } + + // Add points for the endpoint of the wellpath, if it starts/ends inside a cell + { + // Add an intersection for the well startpoint that is inside the first cell + std::map::iterator it = sortedUniqueIntersections.begin(); + if (it != sortedUniqueIntersections.end() && !it->first.isEnteringCell) // Leaving a cell as first intersection. Well starts inside a cell. + { + // Needs wellpath start point in front + HexIntersectionInfo firstLeavingPoint = it->second; + firstLeavingPoint.m_intersectionPoint = m_wellPath->m_wellPathPoints[0]; + + sortedUniqueIntersections.insert(std::make_pair(RigMDEnterLeaveCellIdxKey(m_wellPath->m_measuredDepths[0], true, firstLeavingPoint.m_hexIndex), + firstLeavingPoint)); + } + + // Add an intersection for the well endpoint possibly inside the last cell. + std::map::reverse_iterator rit = sortedUniqueIntersections.rbegin(); + if (rit != sortedUniqueIntersections.rend() && rit->first.isEnteringCell) // Entering a cell as last intersection. Well ends inside a cell. + { + // Needs wellpath end point at end + HexIntersectionInfo lastEnterPoint = rit->second; + lastEnterPoint.m_intersectionPoint = m_wellPath->m_wellPathPoints.back(); + lastEnterPoint.m_isIntersectionEntering = false; + + sortedUniqueIntersections.insert(std::make_pair(RigMDEnterLeaveCellIdxKey(m_wellPath->m_measuredDepths.back(), false, lastEnterPoint.m_hexIndex), + lastEnterPoint)); + } + } + + // Filter and store the intersections pairwise as cell enter-leave pairs + // Discard points that does not have a match . + { + std::map::iterator it1 = sortedUniqueIntersections.begin(); + std::map::iterator it2; + + while (it1 != sortedUniqueIntersections.end()) + { + it2 = it1; + ++it2; + + if (it2 == sortedUniqueIntersections.end()) break; + + if (RigMDEnterLeaveCellIdxKey::isProperCellEnterLeavePair(it1->first, it2->first)) + { + appendIntersectionToArrays(it1->first.measuredDepth, it1->second); + ++it1; + appendIntersectionToArrays(it1->first.measuredDepth, it1->second); + ++it1; + } + else + { + + // If we haven't a proper pair, try our best to recover these variants: + // 1-2 3 4 5 6 7 8 9 10 11-12 + // +---+ + // +---+ + // +---+ + + std::map::iterator it11 = it1; + std::map::iterator it21 = it2; + + // Check if we have overlapping cells (typically at a fault) + ++it21; + if (it21 != sortedUniqueIntersections.end() + && RigMDEnterLeaveCellIdxKey::isProperCellEnterLeavePair(it11->first, it21->first)) + { + // Found 3 to 5 connection + appendIntersectionToArrays(it11->first.measuredDepth, it11->second); + appendIntersectionToArrays(it21->first.measuredDepth, it21->second); + + ++it11; ++it21; + if (it21 != sortedUniqueIntersections.end() + && RigMDEnterLeaveCellIdxKey::isProperCellEnterLeavePair(it11->first, it21->first)) + { + // Found a 4 to 6 connection + appendIntersectionToArrays(it11->first.measuredDepth, it11->second); + appendIntersectionToArrays(it21->first.measuredDepth, it21->second); + + it1 = it21; + ++it1; + continue; + } + else + { + cvf::Trace::show(cvf::String("Well log from :") + m_wellCaseErrorMsgName + (" Discards a point at MD: ") + cvf::String::number((double)(it1->first.measuredDepth))); + + // Found that 8 to 10 is not connected, after finding 7 to 9 + it1 = it21; // Discard 8 by Jumping to 10 + continue; + } + } + else + { + cvf::Trace::show(cvf::String("Well log from :") + m_wellCaseErrorMsgName + (" Discards a point at MD: ") + cvf::String::number((double)(it1->first.measuredDepth))); + + // Found that 10 to 11 is not connected, and not 10 to 12 either + it1++; // Discard 10 and jump to 11 and hope that recovers us + continue; + } + + CVF_ASSERT(false); // Should never end here + } + } + } +} + +void RigWellLogExtractor::appendIntersectionToArrays(double measuredDepth, const HexIntersectionInfo& intersection) +{ + m_measuredDepth.push_back (measuredDepth); + m_trueVerticalDepth.push_back (fabs(intersection.m_intersectionPoint[2])); + m_intersections.push_back (intersection.m_intersectionPoint); + m_intersectedCells.push_back (intersection.m_hexIndex); + m_intersectedCellFaces.push_back(intersection.m_face); +} diff --git a/ApplicationCode/ReservoirDataModel/RigWellLogExtractor.h b/ApplicationCode/ReservoirDataModel/RigWellLogExtractor.h new file mode 100644 index 0000000000..a06ca717d6 --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/RigWellLogExtractor.h @@ -0,0 +1,70 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cvfBase.h" +#include "cvfObject.h" +#include "cvfMath.h" +#include "cvfVector3.h" + +#include +#include "cvfStructGrid.h" + +#include "RigWellLogExtractionTools.h" + +class RigWellPath; + +//================================================================================================== +/// +//================================================================================================== +class RigWellLogExtractor : public cvf::Object +{ +public: + RigWellLogExtractor(const RigWellPath* wellpath, const std::string& wellCaseErrorMsgName); + virtual ~RigWellLogExtractor(); + + const std::vector& measuredDepth() { return m_measuredDepth; } + const std::vector& trueVerticalDepth() {return m_trueVerticalDepth;} + + const RigWellPath* wellPathData() { return m_wellPath.p();} + +protected: + void insertIntersectionsInMap(const std::vector &intersections, + cvf::Vec3d p1, double md1, cvf::Vec3d p2, double md2, + std::map *uniqueIntersections); + + void populateReturnArrays(std::map &uniqueIntersections); + void appendIntersectionToArrays(double measuredDepth, const HexIntersectionInfo& intersection); + + std::vector m_measuredDepth; + std::vector m_trueVerticalDepth; + + std::vector m_intersections; + std::vector m_intersectedCells; + std::vector + m_intersectedCellFaces; + + cvf::cref m_wellPath; + + std::string m_wellCaseErrorMsgName; +}; + + + diff --git a/ApplicationCode/ReservoirDataModel/RigWellLogFile.cpp b/ApplicationCode/ReservoirDataModel/RigWellLogFile.cpp new file mode 100644 index 0000000000..1e4dc6b751 --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/RigWellLogFile.cpp @@ -0,0 +1,300 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RigWellLogFile.h" + +#include "RimWellLogPlotCurve.h" + +#include "well.hpp" +#include "laswell.hpp" + +#include +#include + +#include +#include // Needed for HUGE_VAL on Linux + +#define RIG_WELL_FOOTPERMETER 3.2808399 + + +//-------------------------------------------------------------------------------------------------- +/// Find the largest possible "ususal" value to use for absent data (-999.25, -9999.25, etc.) +//-------------------------------------------------------------------------------------------------- +static double sg_createAbsentValue(double lowestDataValue) +{ + double absentValue = -999.0; + + while (absentValue > lowestDataValue) + { + absentValue *= 10; + absentValue -= 9; + } + + return absentValue - 0.25; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigWellLogFile::RigWellLogFile() + : cvf::Object() +{ + m_wellLogFile = NULL; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigWellLogFile::~RigWellLogFile() +{ + close(); +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RigWellLogFile::open(const QString& fileName, QString* errorMessage) +{ + close(); + + NRLib::Well* well = NULL; + + try + { + int wellFormat = NRLib::Well::LAS; + well = NRLib::Well::ReadWell(fileName.toStdString(), wellFormat); + if (!well) + { + return false; + } + } + catch (std::exception& e) + { + if (well) + { + delete well; + } + + if (e.what()) + { + CVF_ASSERT(errorMessage); + *errorMessage = e.what(); + } + + return false; + } + + QStringList wellLogNames; + + const std::map >& contLogs = well->GetContLog(); + std::map >::const_iterator itCL; + for (itCL = contLogs.begin(); itCL != contLogs.end(); itCL++) + { + QString logName = QString::fromStdString(itCL->first); + wellLogNames.append(logName); + + if (logName.toUpper() == "DEPT" || logName.toUpper() == "DEPTH") + { + m_depthLogName = logName; + } + } + + m_wellLogChannelNames = wellLogNames; + m_wellLogFile = well; + + return true; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigWellLogFile::close() +{ + if (m_wellLogFile) + { + delete m_wellLogFile; + m_wellLogFile = NULL; + } + + m_wellLogChannelNames.clear(); + m_depthLogName.clear(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RigWellLogFile::wellName() const +{ + CVF_ASSERT(m_wellLogFile); + return QString::fromStdString(m_wellLogFile->GetWellName()); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QStringList RigWellLogFile::wellLogChannelNames() const +{ + return m_wellLogChannelNames; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RigWellLogFile::depthValues() const +{ + return values(m_depthLogName); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RigWellLogFile::values(const QString& name) const +{ + CVF_ASSERT(m_wellLogFile); + + if (m_wellLogFile->HasContLog(name.toStdString())) + { + if (name == m_depthLogName && (depthUnit().toUpper() == "F" || depthUnit().toUpper() == "FT")) + { + std::vector footValues = m_wellLogFile->GetContLog(name.toStdString()); + + std::vector meterValues; + meterValues.reserve(footValues.size()); + + for (size_t vIdx = 0; vIdx < footValues.size(); vIdx++) + { + meterValues.push_back(footValues[vIdx]/RIG_WELL_FOOTPERMETER); + } + + return meterValues; + } + + std::vector values = m_wellLogFile->GetContLog(name.toStdString()); + + for (size_t vIdx = 0; vIdx < values.size(); vIdx++) + { + if (m_wellLogFile->IsMissing(values[vIdx])) + { + // Convert missing ("NULL") values to HUGE_VAL + values[vIdx] = HUGE_VAL; + } + } + + return values; + } + + return std::vector(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RigWellLogFile::depthUnit() const +{ + QString unit; + + NRLib::LasWell* lasWell = dynamic_cast(m_wellLogFile); + if (lasWell) + { + unit = QString::fromStdString(lasWell->depthUnit()); + } + + return unit; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RigWellLogFile::wellLogChannelUnit(const QString& wellLogChannelName) const +{ + QString unit; + + NRLib::LasWell* lasWell = dynamic_cast(m_wellLogFile); + if (lasWell) + { + unit = QString::fromStdString(lasWell->unitName(wellLogChannelName.toStdString())); + } + + // Special handling of depth unit - we convert depth to meter + if (unit == depthUnit()) + { + return "m"; + } + + return unit; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RigWellLogFile::exportToLasFile(const RimWellLogPlotCurve* curve, const QString& fileName) +{ + CVF_ASSERT(curve); + + const RigWellLogCurveData* curveData = curve->curveData(); + if (!curveData) + { + return false; + } + + double minX, maxX; + curve->valueRange(&minX, &maxX); + double absentValue = sg_createAbsentValue(minX); + + std::vector wellLogValues = curveData->xValues(); + for (size_t vIdx = 0; vIdx < wellLogValues.size(); vIdx++) + { + double value = wellLogValues[vIdx]; + if (value == HUGE_VAL || value == -HUGE_VAL || value != value) + { + wellLogValues[vIdx] = absentValue; + } + } + + QString wellLogChannelName = curve->wellLogChannelName().trimmed(); + wellLogChannelName.replace(".", "_"); + + QString wellLogDate = curve->wellDate().trimmed(); + wellLogDate.replace(".", "_"); + wellLogDate.replace(" ", "_"); + + NRLib::LasWell lasFile; + lasFile.addWellInfo("WELL", curve->wellName().trimmed().toStdString()); + lasFile.addWellInfo("DATE", wellLogDate.toStdString()); + lasFile.AddLog("DEPTH", "M", "Depth in meters", curveData->measuredDepths()); + lasFile.AddLog(wellLogChannelName.trimmed().toStdString(), "NO_UNIT", "", wellLogValues); + lasFile.SetMissing(absentValue); + + double minDepth = 0.0; + double maxDepth = 0.0; + curveData->calculateMDRange(&minDepth, &maxDepth); + + lasFile.setStartDepth(minDepth); + lasFile.setStopDepth(maxDepth); + lasFile.setDepthUnit("M"); + + lasFile.setVersionInfo("2.0"); + + std::vector commentHeader; + lasFile.WriteToFile(fileName.toStdString(), commentHeader); + + return true; +} diff --git a/ApplicationCode/ReservoirDataModel/RigWellLogFile.h b/ApplicationCode/ReservoirDataModel/RigWellLogFile.h new file mode 100644 index 0000000000..348e1da03f --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/RigWellLogFile.h @@ -0,0 +1,63 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cvfBase.h" +#include "cvfObject.h" + +#include +#include + +namespace NRLib +{ + class Well; +} + +class RimWellLogPlotCurve; + +//================================================================================================== +/// +//================================================================================================== +class RigWellLogFile : public cvf::Object +{ +public: + RigWellLogFile(); + virtual ~RigWellLogFile(); + + bool open(const QString& fileName, QString* errorMessage); + + QString wellName() const; + QStringList wellLogChannelNames() const; + + std::vector depthValues() const; + std::vector values(const QString& name) const; + + QString depthUnit() const; + QString wellLogChannelUnit(const QString& wellLogChannelName) const; + + static bool exportToLasFile(const RimWellLogPlotCurve* curve, const QString& fileName); + +private: + void close(); + + NRLib::Well* m_wellLogFile; + QStringList m_wellLogChannelNames; + QString m_depthLogName; +}; diff --git a/ApplicationCode/ReservoirDataModel/RigWellPath.h b/ApplicationCode/ReservoirDataModel/RigWellPath.h index 90e3c1d78d..7fce36f533 100644 --- a/ApplicationCode/ReservoirDataModel/RigWellPath.h +++ b/ApplicationCode/ReservoirDataModel/RigWellPath.h @@ -36,4 +36,5 @@ class RigWellPath : public cvf::Object { public: std::vector m_wellPathPoints; + std::vector m_measuredDepths; }; diff --git a/ApplicationCode/ReservoirDataModel/cvfGeometryTools.cpp b/ApplicationCode/ReservoirDataModel/cvfGeometryTools.cpp index b354a71787..17db4bee2c 100644 --- a/ApplicationCode/ReservoirDataModel/cvfGeometryTools.cpp +++ b/ApplicationCode/ReservoirDataModel/cvfGeometryTools.cpp @@ -329,7 +329,7 @@ GeometryTools::inPlaneLineIntersect3D( const cvf::Vec3d& planeNormal, //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -double GeometryTools::linePointSquareDist(const cvf::Vec3d& p1, const cvf::Vec3d& p2, const cvf::Vec3d& p3) +double GeometryTools::linePointSquareDist(const cvf::Vec3d& p1, const cvf::Vec3d& p2, const cvf::Vec3d& p3) { cvf::Vec3d v31 = p3 - p1; cvf::Vec3d v21 = p2 - p1; @@ -374,9 +374,11 @@ double GeometryTools::linePointSquareDist(const cvf::Vec3d& p1, const cvf::Vec3d int GeometryTools::intersectLineSegmentTriangle( const cvf::Vec3d p0, const cvf::Vec3d p1, const cvf::Vec3d t0, const cvf::Vec3d t1, const cvf::Vec3d t2, - cvf::Vec3d* intersectionPoint ) + cvf::Vec3d* intersectionPoint , bool * isLineDirDotNormalNegative) { - CVF_ASSERT(intersectionPoint != NULL); + CVF_TIGHT_ASSERT(intersectionPoint != NULL); + CVF_TIGHT_ASSERT(isLineDirDotNormalNegative != NULL); + cvf::Vec3d u, v, n; // triangle vectors cvf::Vec3d dir, w0, w; // ray vectors double r, a, b; // params to calc ray-plane intersect @@ -392,6 +394,9 @@ int GeometryTools::intersectLineSegmentTriangle( const cvf::Vec3d p0, const cvf: w0 = p0 - t0; a = -dot(n, w0); b = dot(n, dir); + + (*isLineDirDotNormalNegative) = (b < 0.0); + if (fabs(b) < SMALL_NUM) { // ray is parallel to triangle plane if (a == 0) // ray lies in triangle plane return 2; @@ -493,6 +498,58 @@ cvf::Vec3d GeometryTools::barycentricCoords(const cvf::Vec3d& t0, const cvf::Ve return m; } +inline double triArea3D(const cvf::Vec3d& v0, + const cvf::Vec3d& v1, + const cvf::Vec3d& v2) +{ + return 0.5 * ((v1-v0) ^ (v2 - v0)).length(); +} + +//-------------------------------------------------------------------------------------------------- +/// Barycentric coordinates of a Quad +/// See http://geometry.caltech.edu/pubs/MHBD02.pdf for details +/// W_i = a_i / Sum(a_0 ... a_3) +/// a_i = Area(v_(i-1), v_i, v_(i+1))*Area(p, v_(i-2), v_(i-1))*Area(p, v_(i+1), v_(i+2)) + +//-------------------------------------------------------------------------------------------------- +cvf::Vec4d GeometryTools::barycentricCoords(const cvf::Vec3d& v0, + const cvf::Vec3d& v1, + const cvf::Vec3d& v2, + const cvf::Vec3d& v3, + const cvf::Vec3d& p) +{ + cvf::Vec4d w; + cvf::Vec4d a; + + a[0] = triArea3D(v3, v0, v1)*triArea3D(p, v2, v3)*triArea3D(p, v1, v2); + a[1] = triArea3D(v0, v1, v2)*triArea3D(p, v3, v0)*triArea3D(p, v2, v3); + a[2] = triArea3D(v1, v2, v3)*triArea3D(p, v0, v1)*triArea3D(p, v3, v0); + a[3] = triArea3D(v2, v3, v0)*triArea3D(p, v1, v2)*triArea3D(p, v0, v1); + + double sum_a = a[0] + a[1] + a[2] + a[3]; + + w[0] = a[0]/sum_a; + w[1] = a[1]/sum_a; + w[2] = a[2]/sum_a; + w[3] = a[3]/sum_a; + + return w; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double GeometryTools::interpolateQuad(const cvf::Vec3d& v1, double s1, + const cvf::Vec3d& v2, double s2, + const cvf::Vec3d& v3, double s3, + const cvf::Vec3d& v4, double s4, + const cvf::Vec3d& point) +{ + cvf::Vec4d bc = barycentricCoords(v1, v2, v3, v4, point); + + return s1*bc[0] + s2*bc[1] + s3*bc[2] + s4*bc[3]; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -656,9 +713,9 @@ EarClipTesselator::EarClipTesselator(): } //-------------------------------------------------------------------------------------------------- -/// \brief Do the main processing/actual triangulation -/// \param triangleIndices Array that will receive the indices of the triangles resulting from the triangulation -/// \return true when a tesselation was successully created +/// \brief Do the main processing/actual triangulation +/// \param triangleIndices Array that will receive the indices of the triangles resulting from the triangulation +/// \return true when a tesselation was successully created //-------------------------------------------------------------------------------------------------- bool EarClipTesselator::calculateTriangles( std::vector* triangleIndices ) @@ -672,61 +729,61 @@ bool EarClipTesselator::calculateTriangles( std::vector* triangleIndices // We want m_polygonIndices to be a counter-clockwise polygon to make the validation test work - if (calculateProjectedPolygonArea() < 0 ) - { - m_polygonIndices.reverse(); - } + if (calculateProjectedPolygonArea() < 0 ) + { + m_polygonIndices.reverse(); + } std::list::iterator u, v, w; // If we loop two times around polygon without clipping a single triangle we are toast. - size_t count = 2*numVertices; // error detection + size_t count = 2*numVertices; // error detection - v = m_polygonIndices.end(); //nv - 1; + v = m_polygonIndices.end(); //nv - 1; --v; - while (numVertices > 2) - { - // if we loop, it is probably a non-simple polygon - if (count <= 0 ) - { - // Triangulate: ERROR - probable bad polygon! - return false; - } + while (numVertices > 2) + { + // if we loop, it is probably a non-simple polygon + if (count <= 0 ) + { + // Triangulate: ERROR - probable bad polygon! + return false; + } --count; - // Three consecutive vertices in current polygon, - // previous - u = v; - if (u == m_polygonIndices.end()) u = m_polygonIndices.begin(); // if (nv <= u) u = 0; + // Three consecutive vertices in current polygon, + // previous + u = v; + if (u == m_polygonIndices.end()) u = m_polygonIndices.begin(); // if (nv <= u) u = 0; - // new v - v = u; ++v; //u + 1; - if (v == m_polygonIndices.end()) v = m_polygonIndices.begin(); //if (nv <= v) v = 0; + // new v + v = u; ++v; //u + 1; + if (v == m_polygonIndices.end()) v = m_polygonIndices.begin(); //if (nv <= v) v = 0; - // next - w = v; ++w; //v + 1; - if (w == m_polygonIndices.end()) w = m_polygonIndices.begin(); //if (nv <= w) w = 0; + // next + w = v; ++w; //v + 1; + if (w == m_polygonIndices.end()) w = m_polygonIndices.begin(); //if (nv <= w) w = 0; - if ( isTriangleValid(u, v, w) ) - { - // Indices of the vertices - triangleIndices->push_back(*u); - triangleIndices->push_back(*v); - triangleIndices->push_back(*w); + if ( isTriangleValid(u, v, w) ) + { + // Indices of the vertices + triangleIndices->push_back(*u); + triangleIndices->push_back(*v); + triangleIndices->push_back(*w); - // Remove v from remaining polygon + // Remove v from remaining polygon m_polygonIndices.erase(v); v = w; - numVertices--; + numVertices--; - // Resets error detection counter - count = 2*numVertices; - } - } + // Resets error detection counter + count = 2*numVertices; + } + } - return true; + return true; } @@ -744,15 +801,15 @@ bool EarClipTesselator::isTriangleValid( std::list::const_iterator u, st if ( m_areaTolerance > (((B[m_X]-A[m_X])*(C[m_Y]-A[m_Y])) - ((B[m_Y]-A[m_Y])*(C[m_X]-A[m_X]))) ) return false; - std::list::const_iterator c; + std::list::const_iterator c; std::list::const_iterator outside; - for (c = m_polygonIndices.begin(); c != m_polygonIndices.end(); ++c) - { + for (c = m_polygonIndices.begin(); c != m_polygonIndices.end(); ++c) + { // The polygon points that actually make up the triangle candidate does not count // (but the same points on different positions in the polygon does! // Except those one off the triangle, that references the start or end of the triangle) - if ( (c == u) || (c == v) || (c == w)) continue; + if ( (c == u) || (c == v) || (c == w)) continue; // Originally the below tests was not included which resulted in missing triangles sometimes @@ -770,10 +827,10 @@ bool EarClipTesselator::isTriangleValid( std::list::const_iterator u, st cvf::Vec3d P = (*m_nodeCoords)[*c]; - if (isPointInsideTriangle(A, B, C, P)) return false; - } + if (isPointInsideTriangle(A, B, C, P)) return false; + } - return true; + return true; } @@ -786,19 +843,19 @@ bool EarClipTesselator::isPointInsideTriangle(const cvf::Vec3d& A, const cvf::Ve { CVF_ASSERT(m_X > -1 && m_Y > -1); - double ax = C[m_X] - B[m_X]; double ay = C[m_Y] - B[m_Y]; - double bx = A[m_X] - C[m_X]; double by = A[m_Y] - C[m_Y]; - double cx = B[m_X] - A[m_X]; double cy = B[m_Y] - A[m_Y]; + double ax = C[m_X] - B[m_X]; double ay = C[m_Y] - B[m_Y]; + double bx = A[m_X] - C[m_X]; double by = A[m_Y] - C[m_Y]; + double cx = B[m_X] - A[m_X]; double cy = B[m_Y] - A[m_Y]; - double apx= P[m_X] - A[m_X]; double apy= P[m_Y] - A[m_Y]; - double bpx= P[m_X] - B[m_X]; double bpy= P[m_Y] - B[m_Y]; - double cpx= P[m_X] - C[m_X]; double cpy= P[m_Y] - C[m_Y]; + double apx= P[m_X] - A[m_X]; double apy= P[m_Y] - A[m_Y]; + double bpx= P[m_X] - B[m_X]; double bpy= P[m_Y] - B[m_Y]; + double cpx= P[m_X] - C[m_X]; double cpy= P[m_Y] - C[m_Y]; - double aCROSSbp = ax*bpy - ay*bpx; - double cCROSSap = cx*apy - cy*apx; - double bCROSScp = bx*cpy - by*cpx; + double aCROSSbp = ax*bpy - ay*bpx; + double cCROSSap = cx*apy - cy*apx; + double bCROSScp = bx*cpy - by*cpx; double tol = 0; - return ((aCROSSbp >= tol) && (bCROSScp >= tol) && (cCROSSap >= tol)); + return ((aCROSSbp >= tol) && (bCROSScp >= tol) && (cCROSSap >= tol)); }; //-------------------------------------------------------------------------------------------------- @@ -809,21 +866,21 @@ double EarClipTesselator::calculateProjectedPolygonArea() const { CVF_ASSERT(m_X > -1 && m_Y > -1); - double A = 0; + double A = 0; - std::list::const_iterator p = m_polygonIndices.end(); + std::list::const_iterator p = m_polygonIndices.end(); --p; - std::list::const_iterator q = m_polygonIndices.begin(); - while (q != m_polygonIndices.end()) - { - A += (*m_nodeCoords)[*p][m_X] * (*m_nodeCoords)[*q][m_Y] - (*m_nodeCoords)[*q][m_X]*(*m_nodeCoords)[*p][m_Y]; + std::list::const_iterator q = m_polygonIndices.begin(); + while (q != m_polygonIndices.end()) + { + A += (*m_nodeCoords)[*p][m_X] * (*m_nodeCoords)[*q][m_Y] - (*m_nodeCoords)[*q][m_X]*(*m_nodeCoords)[*p][m_Y]; - p = q; - q++; - } + p = q; + q++; + } - return A*0.5; + return A*0.5; } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ReservoirDataModel/cvfGeometryTools.h b/ApplicationCode/ReservoirDataModel/cvfGeometryTools.h index fb11aefddf..2c1478a983 100644 --- a/ApplicationCode/ReservoirDataModel/cvfGeometryTools.h +++ b/ApplicationCode/ReservoirDataModel/cvfGeometryTools.h @@ -39,8 +39,15 @@ class GeometryTools static double linePointSquareDist(const cvf::Vec3d& p1, const cvf::Vec3d& p2, const cvf::Vec3d& p3); static int intersectLineSegmentTriangle( const cvf::Vec3d p0, const cvf::Vec3d p1, const cvf::Vec3d t0, const cvf::Vec3d t1, const cvf::Vec3d t2, - cvf::Vec3d* intersectionPoint ); + cvf::Vec3d* intersectionPoint, + bool * isLineDirDotNormalNegative); static cvf::Vec3d barycentricCoords(const cvf::Vec3d& t0, const cvf::Vec3d& t1, const cvf::Vec3d& t2, const cvf::Vec3d& p); + static cvf::Vec4d barycentricCoords(const cvf::Vec3d& v0, const cvf::Vec3d& v1, const cvf::Vec3d& v2, const cvf::Vec3d& v3, const cvf::Vec3d& p); + static double interpolateQuad(const cvf::Vec3d& v1, double s1, + const cvf::Vec3d& v2, double s2, + const cvf::Vec3d& v3, double s3, + const cvf::Vec3d& v4, double s4, + const cvf::Vec3d& point); static int findClosestAxis(const cvf::Vec3d& vec ); static double getAngle(const cvf::Vec3d& positiveNormalAxis, const cvf::Vec3d& v1, const cvf::Vec3d& v2); diff --git a/ApplicationCode/ReservoirDataModel/cvfGeometryTools.inl b/ApplicationCode/ReservoirDataModel/cvfGeometryTools.inl index 7b9aeed23d..8a27e4ba5d 100644 --- a/ApplicationCode/ReservoirDataModel/cvfGeometryTools.inl +++ b/ApplicationCode/ReservoirDataModel/cvfGeometryTools.inl @@ -104,22 +104,22 @@ bool GeometryTools::insertVertexInPolygon( std::vector * polygon, //-------------------------------------------------------------------------------------------------- -/// \brief Test if a point touches a polygon within the specified tolerance +/// \brief Test if a point touches a polygon within the specified tolerance /// -/// \param polygonNorm Polygon normal -/// \param pPolygonVerts Array of polygon vertice coordinates -/// \param piVertexIndices Array of integer node indices for this polygon -/// \param iNumVerts Number of vertices in polygon -/// \param point The point to be checked +/// \param polygonNorm Polygon normal +/// \param pPolygonVerts Array of polygon vertice coordinates +/// \param piVertexIndices Array of integer node indices for this polygon +/// \param iNumVerts Number of vertices in polygon +/// \param point The point to be checked /// \param tolerance Tolerance in length /// \param touchedEdgeIndex returns -1 if point is inside, and edge index if point touches an edge. -/// \return true if point lies inside or on the border of the polygon. +/// \return true if point lies inside or on the border of the polygon. /// -/// \assumpt Assumes that the polygon is planar -/// \comment First check if point is on an edge, Then check if it is inside by +/// \assumpt Assumes that the polygon is planar +/// \comment First check if point is on an edge, Then check if it is inside by /// counting the number of times a ray from point along positive X axis /// crosses an edge. Odd number says inside. -/// \author SP (really by Eric Haines) and JJS +/// \author SP (really by Eric Haines) and JJS //-------------------------------------------------------------------------------------------------- template bool GeometryTools::isPointTouchingIndexedPolygon( const cvf::Vec3d& polygonNormal, @@ -135,7 +135,7 @@ bool GeometryTools::isPointTouchingIndexedPolygon( const cvf::Vec3d& polygonNor int X = (Z + 1) % 3; int Y = (Z + 2) % 3; - int crossings; + int crossings; int xBelowVx0; int yBelowVx0; @@ -146,7 +146,7 @@ bool GeometryTools::isPointTouchingIndexedPolygon( const cvf::Vec3d& polygonNor double dv0; - cvf::uint j; + cvf::uint j; // Check if point is on an edge or vertex size_t firstIdx; @@ -179,19 +179,19 @@ bool GeometryTools::isPointTouchingIndexedPolygon( const cvf::Vec3d& polygonNor { // cleverness: bobble between filling endpoints of edges, so that the previous edge's shared endpoint is maintained. if (j & 0x1) - { + { vtx0 = vertices[indices[j]].ptr(); yBelowVx0 = (dv0 = vtx0[Y] - point[Y]) >= 0.0; } else - { + { vtx1 = vertices[indices[j]].ptr(); - yBelowVx1 = (vtx1[Y] >= point[Y]); + yBelowVx1 = (vtx1[Y] >= point[Y]); } // check if Y of point is between Y of Vx0 and Vx1 if (yBelowVx0 != yBelowVx1) - { + { // check if X of point is not between X of Vx0 and Vx1 if ( (xBelowVx0 = (vtx0[X] >= point[X])) == (vtx1[X] >= point[X]) ) { @@ -200,9 +200,9 @@ bool GeometryTools::isPointTouchingIndexedPolygon( const cvf::Vec3d& polygonNor else { // compute intersection of polygon segment with X ray, note if > point's X. - crossings += (vtx0[X] - dv0*(vtx1[X] - vtx0[X])/(vtx1[Y] - vtx0[Y])) >= point[X]; - } - } + crossings += (vtx0[X] - dv0*(vtx1[X] - vtx0[X])/(vtx1[Y] - vtx0[Y])) >= point[X]; + } + } } // test if crossings is odd. If we care about its winding number > 0, then just: inside_flag = crossings > 0; diff --git a/ApplicationCode/Resources/LasFile16x16.png b/ApplicationCode/Resources/LasFile16x16.png new file mode 100644 index 0000000000..879923ac91 Binary files /dev/null and b/ApplicationCode/Resources/LasFile16x16.png differ diff --git a/ApplicationCode/Resources/ResInsight.qrc b/ApplicationCode/Resources/ResInsight.qrc index 873569505e..72bf945d1f 100644 --- a/ApplicationCode/Resources/ResInsight.qrc +++ b/ApplicationCode/Resources/ResInsight.qrc @@ -34,8 +34,8 @@ draw_style_meshoutlines_24x24.png draw_style_outlines_24x24.png draw_style_surface_24x24.png - disable_lighting_24x24.png - SnapShot.png + disable_lighting_24x24.png + SnapShot.png SnapShotSave.png SnapShotSaveViews.png draw_style_faults_24x24.png @@ -46,7 +46,14 @@ draw_style_surface_w_fault_mesh_24x24.png InfoBox16x16.png GeoMechCase48x48.png - GeoMechCases48x48.png + GeoMechCases48x48.png + chain.png + view-page-multi-24.png + LasFile16x16.png + WellLogTrack16x16.png + WellLogPlot16x16.png + WellLogPlots16x16.png + WellLogCurve16x16.png fs_CellFace.glsl diff --git a/ApplicationCode/Resources/WellLogCurve16x16.png b/ApplicationCode/Resources/WellLogCurve16x16.png new file mode 100644 index 0000000000..0ad73ebf8d Binary files /dev/null and b/ApplicationCode/Resources/WellLogCurve16x16.png differ diff --git a/ApplicationCode/Resources/WellLogPlot16x16.png b/ApplicationCode/Resources/WellLogPlot16x16.png new file mode 100644 index 0000000000..1214ea851f Binary files /dev/null and b/ApplicationCode/Resources/WellLogPlot16x16.png differ diff --git a/ApplicationCode/Resources/WellLogPlots16x16.png b/ApplicationCode/Resources/WellLogPlots16x16.png new file mode 100644 index 0000000000..71d60aa85c Binary files /dev/null and b/ApplicationCode/Resources/WellLogPlots16x16.png differ diff --git a/ApplicationCode/Resources/WellLogTrack16x16.png b/ApplicationCode/Resources/WellLogTrack16x16.png new file mode 100644 index 0000000000..6f40f7b9da Binary files /dev/null and b/ApplicationCode/Resources/WellLogTrack16x16.png differ diff --git a/ApplicationCode/Resources/chain.png b/ApplicationCode/Resources/chain.png new file mode 100644 index 0000000000..c5205dd598 Binary files /dev/null and b/ApplicationCode/Resources/chain.png differ diff --git a/ApplicationCode/Resources/view-page-multi-24.png b/ApplicationCode/Resources/view-page-multi-24.png new file mode 100644 index 0000000000..87241472ae Binary files /dev/null and b/ApplicationCode/Resources/view-page-multi-24.png differ diff --git a/ApplicationCode/ResultStatisticsCache/RigStatisticsCalculator.h b/ApplicationCode/ResultStatisticsCache/RigStatisticsCalculator.h index c5ee533757..02ff0967ab 100644 --- a/ApplicationCode/ResultStatisticsCache/RigStatisticsCalculator.h +++ b/ApplicationCode/ResultStatisticsCache/RigStatisticsCalculator.h @@ -33,12 +33,12 @@ class RigHistogramCalculator; class RigStatisticsCalculator : public cvf::Object { public: - virtual void minMaxCellScalarValues(size_t timeStepIndex, double& min, double& max) = 0; - virtual void posNegClosestToZero(size_t timeStepIndex, double& pos, double& neg) = 0; - - void meanCellScalarValue(double& meanValue); - virtual void valueSumAndSampleCount(double& valueSum, size_t& sampleCount) = 0; - virtual void addDataToHistogramCalculator(RigHistogramCalculator& histogramCalculator) = 0; + virtual void minMaxCellScalarValues(size_t timeStepIndex, double& min, double& max) = 0; + virtual void posNegClosestToZero(size_t timeStepIndex, double& pos, double& neg) = 0; + + void meanCellScalarValue(double& meanValue); + virtual void valueSumAndSampleCount(double& valueSum, size_t& sampleCount) = 0; + virtual void addDataToHistogramCalculator(RigHistogramCalculator& histogramCalculator) = 0; virtual size_t timeStepCount() = 0; }; diff --git a/ApplicationCode/ResultStatisticsCache/RigStatisticsDataCache.cpp b/ApplicationCode/ResultStatisticsCache/RigStatisticsDataCache.cpp index 4a593bb497..5b4a7182b4 100644 --- a/ApplicationCode/ResultStatisticsCache/RigStatisticsDataCache.cpp +++ b/ApplicationCode/ResultStatisticsCache/RigStatisticsDataCache.cpp @@ -29,7 +29,7 @@ /// //-------------------------------------------------------------------------------------------------- RigStatisticsDataCache::RigStatisticsDataCache(RigStatisticsCalculator* statisticsCalculator) - : m_statisticsCalculator(statisticsCalculator) + : m_statisticsCalculator(statisticsCalculator) { clearAllStatistics(); } @@ -60,27 +60,27 @@ void RigStatisticsDataCache::clearAllStatistics() //-------------------------------------------------------------------------------------------------- void RigStatisticsDataCache::minMaxCellScalarValues(double& min, double& max) { - if (!m_isMaxMinCalculated) - { + if (!m_isMaxMinCalculated) + { min = HUGE_VAL; max = -HUGE_VAL; size_t i; - for (i = 0; i < m_statisticsCalculator->timeStepCount(); i++) - { + for (i = 0; i < m_statisticsCalculator->timeStepCount(); i++) + { double tsmin, tsmax; - this->minMaxCellScalarValues(i, tsmin, tsmax); - if (tsmin < min) min = tsmin; - if (tsmax > max) max = tsmax; - } + this->minMaxCellScalarValues(i, tsmin, tsmax); + if (tsmin < min) min = tsmin; + if (tsmax > max) max = tsmax; + } - m_minValue = min; - m_maxValue = max; + m_minValue = min; + m_maxValue = max; m_isMaxMinCalculated = true; - } + } - min = m_minValue; - max = m_maxValue; + min = m_minValue; + max = m_maxValue; } //-------------------------------------------------------------------------------------------------- @@ -88,9 +88,9 @@ void RigStatisticsDataCache::minMaxCellScalarValues(double& min, double& max) //-------------------------------------------------------------------------------------------------- void RigStatisticsDataCache::minMaxCellScalarValues(size_t timeStepIndex, double& min, double& max) { - if (timeStepIndex >= m_maxMinValuesPrTs.size()) - { - m_maxMinValuesPrTs.resize(timeStepIndex + 1, std::make_pair(HUGE_VAL, -HUGE_VAL)); + if (timeStepIndex >= m_maxMinValuesPrTs.size()) + { + m_maxMinValuesPrTs.resize(timeStepIndex + 1, std::make_pair(HUGE_VAL, -HUGE_VAL)); m_isMaxMinPrTsCalculated.resize(timeStepIndex + 1, false); } @@ -101,14 +101,14 @@ void RigStatisticsDataCache::minMaxCellScalarValues(size_t timeStepIndex, double m_statisticsCalculator->minMaxCellScalarValues(timeStepIndex, tsMin, tsMax); - m_maxMinValuesPrTs[timeStepIndex].first = tsMin; - m_maxMinValuesPrTs[timeStepIndex].second = tsMax; + m_maxMinValuesPrTs[timeStepIndex].first = tsMin; + m_maxMinValuesPrTs[timeStepIndex].second = tsMax; m_isMaxMinPrTsCalculated[timeStepIndex] = true; } - min = m_maxMinValuesPrTs[timeStepIndex].first; - max = m_maxMinValuesPrTs[timeStepIndex].second; + min = m_maxMinValuesPrTs[timeStepIndex].first; + max = m_maxMinValuesPrTs[timeStepIndex].second; } //-------------------------------------------------------------------------------------------------- @@ -116,27 +116,27 @@ void RigStatisticsDataCache::minMaxCellScalarValues(size_t timeStepIndex, double //-------------------------------------------------------------------------------------------------- void RigStatisticsDataCache::posNegClosestToZero(double& pos, double& neg) { - if (!m_isClosestToZeroCalculated) - { + if (!m_isClosestToZeroCalculated) + { pos = HUGE_VAL; neg = -HUGE_VAL; size_t i; for (i = 0; i < m_statisticsCalculator->timeStepCount(); i++) - { - double tsNeg, tsPos; - this->posNegClosestToZero(i, tsPos, tsNeg); - if (tsNeg > neg && tsNeg < 0) neg = tsNeg; - if (tsPos < pos && tsPos > 0) pos = tsPos; - } - - m_posClosestToZero = pos; - m_negClosestToZero = neg; + { + double tsNeg, tsPos; + this->posNegClosestToZero(i, tsPos, tsNeg); + if (tsNeg > neg && tsNeg < 0) neg = tsNeg; + if (tsPos < pos && tsPos > 0) pos = tsPos; + } + + m_posClosestToZero = pos; + m_negClosestToZero = neg; m_isClosestToZeroCalculated = true; - } + } - pos = m_posClosestToZero; - neg = m_negClosestToZero; + pos = m_posClosestToZero; + neg = m_negClosestToZero; } //-------------------------------------------------------------------------------------------------- @@ -144,9 +144,9 @@ void RigStatisticsDataCache::posNegClosestToZero(double& pos, double& neg) //-------------------------------------------------------------------------------------------------- void RigStatisticsDataCache::posNegClosestToZero(size_t timeStepIndex, double& posNearZero, double& negNearZero) { - if (timeStepIndex >= m_posNegClosestToZeroPrTs.size()) - { - m_posNegClosestToZeroPrTs.resize(timeStepIndex + 1, std::make_pair(HUGE_VAL, -HUGE_VAL)); + if (timeStepIndex >= m_posNegClosestToZeroPrTs.size()) + { + m_posNegClosestToZeroPrTs.resize(timeStepIndex + 1, std::make_pair(HUGE_VAL, -HUGE_VAL)); m_isClosestToZeroPrTsCalculated.resize(timeStepIndex + 1, false); } @@ -158,14 +158,14 @@ void RigStatisticsDataCache::posNegClosestToZero(size_t timeStepIndex, double& p m_statisticsCalculator->posNegClosestToZero(timeStepIndex, pos, neg); - m_posNegClosestToZeroPrTs[timeStepIndex].first = pos; - m_posNegClosestToZeroPrTs[timeStepIndex].second = neg; + m_posNegClosestToZeroPrTs[timeStepIndex].first = pos; + m_posNegClosestToZeroPrTs[timeStepIndex].second = neg; m_isClosestToZeroPrTsCalculated[timeStepIndex] = true; } - posNearZero = m_posNegClosestToZeroPrTs[timeStepIndex].first; - negNearZero = m_posNegClosestToZeroPrTs[timeStepIndex].second; + posNearZero = m_posNegClosestToZeroPrTs[timeStepIndex].first; + negNearZero = m_posNegClosestToZeroPrTs[timeStepIndex].second; } //-------------------------------------------------------------------------------------------------- @@ -173,22 +173,9 @@ void RigStatisticsDataCache::posNegClosestToZero(size_t timeStepIndex, double& p //-------------------------------------------------------------------------------------------------- const std::vector& RigStatisticsDataCache::cellScalarValuesHistogram() { - if (m_histogram.size() == 0) - { - double min; - double max; - size_t nBins = 100; - this->minMaxCellScalarValues(min, max); - - RigHistogramCalculator histCalc(min, max, nBins, &m_histogram); - - m_statisticsCalculator->addDataToHistogramCalculator(histCalc); + computeStatisticsIfNeeded(); - m_p10 = histCalc.calculatePercentil(0.1); - m_p90 = histCalc.calculatePercentil(0.9); - } - - return m_histogram; + return m_histogram; } //-------------------------------------------------------------------------------------------------- @@ -196,11 +183,11 @@ const std::vector& RigStatisticsDataCache::cellScalarValuesHistogram() //-------------------------------------------------------------------------------------------------- void RigStatisticsDataCache::p10p90CellScalarValues(double& p10, double& p90) { - // First make sure they are calculated - const std::vector& histogr = this->cellScalarValuesHistogram(); + // First make sure they are calculated + computeStatisticsIfNeeded(); - p10 = m_p10; - p90 = m_p90; + p10 = m_p10; + p90 = m_p90; } //-------------------------------------------------------------------------------------------------- @@ -208,12 +195,33 @@ void RigStatisticsDataCache::p10p90CellScalarValues(double& p10, double& p90) //-------------------------------------------------------------------------------------------------- void RigStatisticsDataCache::meanCellScalarValues(double& meanValue) { - if (!m_isMeanCalculated) - { - m_statisticsCalculator->meanCellScalarValue(m_meanValue); + if (!m_isMeanCalculated) + { + m_statisticsCalculator->meanCellScalarValue(m_meanValue); m_isMeanCalculated = true; - } + } - meanValue = m_meanValue; + meanValue = m_meanValue; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigStatisticsDataCache::computeStatisticsIfNeeded() +{ + if (m_histogram.size() == 0) + { + double min; + double max; + size_t nBins = 100; + this->minMaxCellScalarValues(min, max); + + RigHistogramCalculator histCalc(min, max, nBins, &m_histogram); + + m_statisticsCalculator->addDataToHistogramCalculator(histCalc); + + m_p10 = histCalc.calculatePercentil(0.1); + m_p90 = histCalc.calculatePercentil(0.9); + } } diff --git a/ApplicationCode/ResultStatisticsCache/RigStatisticsDataCache.h b/ApplicationCode/ResultStatisticsCache/RigStatisticsDataCache.h index f1988204c2..ae4c262f35 100644 --- a/ApplicationCode/ResultStatisticsCache/RigStatisticsDataCache.h +++ b/ApplicationCode/ResultStatisticsCache/RigStatisticsDataCache.h @@ -47,26 +47,29 @@ class RigStatisticsDataCache : public cvf::Object const std::vector& cellScalarValuesHistogram(); private: - double m_minValue; - double m_maxValue; + void computeStatisticsIfNeeded(); + +private: + double m_minValue; + double m_maxValue; bool m_isMaxMinCalculated; - double m_posClosestToZero; - double m_negClosestToZero; + double m_posClosestToZero; + double m_negClosestToZero; bool m_isClosestToZeroCalculated; - double m_p10; - double m_p90; + double m_p10; + double m_p90; double m_meanValue; bool m_isMeanCalculated; - std::vector m_histogram; + std::vector m_histogram; - std::vector > m_maxMinValuesPrTs; ///< Max min values for each time step + std::vector > m_maxMinValuesPrTs; ///< Max min values for each time step std::vector m_isMaxMinPrTsCalculated; - std::vector > m_posNegClosestToZeroPrTs; ///< PosNeg values for each time step + std::vector > m_posNegClosestToZeroPrTs; ///< PosNeg values for each time step std::vector m_isClosestToZeroPrTsCalculated; - cvf::ref m_statisticsCalculator; + cvf::ref m_statisticsCalculator; }; diff --git a/ApplicationCode/RiaMain.cpp b/ApplicationCode/RiaMain.cpp index 1fb7745188..5e7d9e6950 100644 --- a/ApplicationCode/RiaMain.cpp +++ b/ApplicationCode/RiaMain.cpp @@ -16,7 +16,6 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RiaStdInclude.h" #include "RiaApplication.h" #include "RiuMainWindow.h" @@ -31,7 +30,8 @@ int main(int argc, char *argv[]) QString platform = cvf::System::is64Bit() ? "(64bit)" : "(32bit)"; window.setWindowTitle("ResInsight " + platform); window.setDefaultWindowSize(); - window.show(); + window.loadWinGeoAndDockToolBarLayout(); + window.showWindow(); if (app.parseArguments()) { diff --git a/ApplicationCode/RiaStdInclude.cpp b/ApplicationCode/RiaStdInclude.cpp deleted file mode 100644 index 2c78f30884..0000000000 --- a/ApplicationCode/RiaStdInclude.cpp +++ /dev/null @@ -1,20 +0,0 @@ -///////////////////////////////////////////////////////////////////////////////// -// -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS -// -// ResInsight is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. -// -// See the GNU General Public License at -// for more details. -// -///////////////////////////////////////////////////////////////////////////////// - -#include "RiaStdInclude.h" - diff --git a/ApplicationCode/RiaStdInclude.h b/ApplicationCode/RiaStdInclude.h deleted file mode 100644 index a4427d82f8..0000000000 --- a/ApplicationCode/RiaStdInclude.h +++ /dev/null @@ -1,36 +0,0 @@ -///////////////////////////////////////////////////////////////////////////////// -// -// Copyright (C) 2011-2012 Statoil ASA, Ceetron AS -// -// ResInsight is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. -// -// See the GNU General Public License at -// for more details. -// -///////////////////////////////////////////////////////////////////////////////// - -#pragma once - -// Compiler warnings in Qt 4.7.0 -#pragma warning (disable : 4311) -#pragma warning (disable : 4312) - -#define USE_PRECOMPILED_HEADERS -#ifdef USE_PRECOMPILED_HEADERS - -#include "cvfLibCore.h" -#include "cvfLibViewing.h" -#include "cvfLibRender.h" -#include "cvfLibGeometry.h" - -#include -#include - -#endif // USE_PRECOMPILED_HEADERS diff --git a/ApplicationCode/SocketInterface/RiaCaseInfoCommands.cpp b/ApplicationCode/SocketInterface/RiaCaseInfoCommands.cpp index 6ee4e99a5f..68b4e41ca5 100644 --- a/ApplicationCode/SocketInterface/RiaCaseInfoCommands.cpp +++ b/ApplicationCode/SocketInterface/RiaCaseInfoCommands.cpp @@ -18,8 +18,6 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RiaStdInclude.h" - #include "RiaSocketCommand.h" #include "RiaSocketServer.h" #include "RiaSocketTools.h" diff --git a/ApplicationCode/SocketInterface/RiaGeometryCommands.cpp b/ApplicationCode/SocketInterface/RiaGeometryCommands.cpp index dd0016180a..1b6b3fe9cb 100644 --- a/ApplicationCode/SocketInterface/RiaGeometryCommands.cpp +++ b/ApplicationCode/SocketInterface/RiaGeometryCommands.cpp @@ -18,7 +18,6 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RiaStdInclude.h" #include "RiaSocketCommand.h" #include "RiaSocketServer.h" #include "RiaSocketTools.h" @@ -90,7 +89,6 @@ class RiaGetCellCenters : public RiaSocketCommand // dv(2) = cellCountK; // dv(3) = 3; - cvf::Vec3d cornerVerts[8]; size_t blockByteCount = cellCount * sizeof(double); std::vector doubleValues(blockByteCount); diff --git a/ApplicationCode/SocketInterface/RiaProjectInfoCommands.cpp b/ApplicationCode/SocketInterface/RiaProjectInfoCommands.cpp index 77737c8ad0..c4ab077840 100644 --- a/ApplicationCode/SocketInterface/RiaProjectInfoCommands.cpp +++ b/ApplicationCode/SocketInterface/RiaProjectInfoCommands.cpp @@ -18,7 +18,6 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RiaStdInclude.h" #include "RiaSocketCommand.h" #include "RiaSocketServer.h" #include "RiaSocketTools.h" @@ -41,9 +40,9 @@ #include "RimIdenticalGridCaseGroup.h" #include "RimCaseCollection.h" #include "RimScriptCollection.h" -#include "RimWellPathCollection.h" #include "RimOilField.h" #include "RimEclipseCaseCollection.h" +#include "cafSelectionManager.h" @@ -122,11 +121,9 @@ class RiaGetSelectedCases: public RiaSocketCommand virtual bool interpretCommand(RiaSocketServer* server, const QList& args, QDataStream& socketStream) { - RiuMainWindow* ruiMainWindow = RiuMainWindow::instance(); - if (ruiMainWindow) { std::vector cases; - ruiMainWindow->selectedCases(cases); + caf::SelectionManager::instance()->objectsByType(&cases); std::vector caseIds; std::vector caseNames; diff --git a/ApplicationCode/SocketInterface/RiaPropertyDataCommands.cpp b/ApplicationCode/SocketInterface/RiaPropertyDataCommands.cpp index f7ca92460a..a5d9f5a760 100644 --- a/ApplicationCode/SocketInterface/RiaPropertyDataCommands.cpp +++ b/ApplicationCode/SocketInterface/RiaPropertyDataCommands.cpp @@ -18,33 +18,30 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RiaStdInclude.h" - #include "RiaSocketCommand.h" #include "RiaSocketDataTransfer.h" #include "RiaSocketServer.h" #include "RiaSocketTools.h" -#include "RifReaderInterface.h" - -#include "RigActiveCellInfo.h" #include "RigCaseCellResultsData.h" #include "RigCaseData.h" +#include "RigResultAccessor.h" +#include "RigResultAccessorFactory.h" #include "RigResultModifier.h" #include "RigResultModifierFactory.h" #include "RimEclipseCase.h" +#include "RimEclipseCase.h" +#include "RimEclipseCellColors.h" #include "RimEclipseInputCase.h" #include "RimEclipseInputProperty.h" #include "RimEclipseInputPropertyCollection.h" #include "RimReservoirCellResultsStorage.h" -#include "RimEclipseView.h" -#include "RimEclipseCellColors.h" -#include "RimUiTreeModelPdm.h" #include "RiuMainWindow.h" #include "RiuProcessMonitor.h" -#include "RigResultAccessorFactory.h" + +#include //-------------------------------------------------------------------------------------------------- @@ -323,7 +320,7 @@ class RiaGetGridProperty: public RiaSocketCommand for (size_t tsIdx = 0; tsIdx < timestepCount; tsIdx++) { - cvf::ref resultAccessor = RigResultAccessorFactory::createResultAccessor(rimCase->reservoirData(), gridIdx, porosityModelEnum, requestedTimesteps[tsIdx], propertyName); + cvf::ref resultAccessor = RigResultAccessorFactory::createResultAccessor(rimCase->reservoirData(), gridIdx, porosityModelEnum, requestedTimesteps[tsIdx], propertyName); if (resultAccessor.isNull()) { @@ -642,8 +639,7 @@ class RiaSetActiveCellProperty: public RiaSocketCommand inputProperty->eclipseKeyword = ""; inputProperty->fileName = ""; inputRes->m_inputPropertyCollection->inputProperties.push_back(inputProperty); - RimUiTreeModelPdm* treeModel = RiuMainWindow::instance()->uiPdmModel(); - treeModel->updateUiSubTree(inputRes->m_inputPropertyCollection()); + inputRes->m_inputPropertyCollection()->updateConnectedEditors(); } inputProperty->resolvedState = RimEclipseInputProperty::RESOLVED_NOT_SAVED; } @@ -1007,8 +1003,7 @@ class RiaSetGridProperty : public RiaSocketCommand inputProperty->eclipseKeyword = ""; inputProperty->fileName = ""; inputRes->m_inputPropertyCollection->inputProperties.push_back(inputProperty); - RimUiTreeModelPdm* treeModel = RiuMainWindow::instance()->uiPdmModel(); - treeModel->updateUiSubTree(inputRes->m_inputPropertyCollection()); + inputRes->m_inputPropertyCollection()->updateConnectedEditors(); } inputProperty->resolvedState = RimEclipseInputProperty::RESOLVED_NOT_SAVED; } diff --git a/ApplicationCode/SocketInterface/RiaSocketCommand.h b/ApplicationCode/SocketInterface/RiaSocketCommand.h index 5a393acc90..efe928725c 100644 --- a/ApplicationCode/SocketInterface/RiaSocketCommand.h +++ b/ApplicationCode/SocketInterface/RiaSocketCommand.h @@ -25,7 +25,12 @@ ////////////////////////////////////////////////////////////////////////// class RiaSocketServer; + class QTcpSocket; +class QDataStream; +class QByteArray; + +#include class RiaSocketCommand { diff --git a/ApplicationCode/SocketInterface/RiaSocketServer.cpp b/ApplicationCode/SocketInterface/RiaSocketServer.cpp index 361cbbf96f..04fac0bcc6 100644 --- a/ApplicationCode/SocketInterface/RiaSocketServer.cpp +++ b/ApplicationCode/SocketInterface/RiaSocketServer.cpp @@ -18,7 +18,6 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RiaStdInclude.h" #include "RiaSocketServer.h" #include "RiaSocketCommand.h" #include "RiaSocketTools.h" @@ -43,7 +42,6 @@ #include "RimIdenticalGridCaseGroup.h" #include "RimScriptCollection.h" #include "RimCaseCollection.h" -#include "RimWellPathCollection.h" #include "RimReservoirCellResultsStorage.h" #include "RigCaseData.h" diff --git a/ApplicationCode/SocketInterface/RiaSocketTools.cpp b/ApplicationCode/SocketInterface/RiaSocketTools.cpp index 510c4d98f3..0378b0f3af 100644 --- a/ApplicationCode/SocketInterface/RiaSocketTools.cpp +++ b/ApplicationCode/SocketInterface/RiaSocketTools.cpp @@ -18,31 +18,28 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RiaStdInclude.h" +#include "RiaSocketTools.h" #include "RiaApplication.h" #include "RiaPreferences.h" - -#include "RiaSocketTools.h" +#include "RiaSocketDataTransfer.h" #include "RiaSocketServer.h" -#include "RimEclipseCase.h" -#include "RimCaseCollection.h" -#include "RimIdenticalGridCaseGroup.h" -#include "RimEclipseInputCase.h" -#include "RimEclipseView.h" -#include "RimEclipseCellColors.h" +#include "Rim3dOverlayInfoConfig.h" +#include "RimCaseCollection.h" #include "RimCellEdgeColors.h" #include "RimCellRangeFilterCollection.h" +#include "RimEclipseCase.h" +#include "RimEclipseCellColors.h" +#include "RimEclipseInputCase.h" +#include "RimEclipseInputPropertyCollection.h" #include "RimEclipsePropertyFilterCollection.h" +#include "RimEclipseView.h" #include "RimEclipseWellCollection.h" -#include "Rim3dOverlayInfoConfig.h" +#include "RimIdenticalGridCaseGroup.h" #include "RimReservoirCellResultsStorage.h" -#include "RimEclipseInputPropertyCollection.h" - -#include "RiaSocketDataTransfer.h" - +#include #include //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/SocketInterface/RiaSocketTools.h b/ApplicationCode/SocketInterface/RiaSocketTools.h index 19c09ace29..1f2ef20bde 100644 --- a/ApplicationCode/SocketInterface/RiaSocketTools.h +++ b/ApplicationCode/SocketInterface/RiaSocketTools.h @@ -20,8 +20,12 @@ class RimCase; class RiaSocketServer; +class RimEclipseCase; class QTcpSocket; +#include +#include + #define PMonLog( MessageString ) RiuMainWindow::instance()->processMonitor()->addStringToLog( MessageString ); class RiaSocketTools diff --git a/ApplicationCode/SocketInterface/RiaWellDataCommands.cpp b/ApplicationCode/SocketInterface/RiaWellDataCommands.cpp index 4ed83781d5..527032e0f7 100644 --- a/ApplicationCode/SocketInterface/RiaWellDataCommands.cpp +++ b/ApplicationCode/SocketInterface/RiaWellDataCommands.cpp @@ -18,29 +18,18 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RiaStdInclude.h" #include "RiaSocketCommand.h" #include "RiaSocketServer.h" #include "RiaSocketTools.h" -#include "RiuMainWindow.h" - #include "RigCaseData.h" -#include "RigCaseCellResultsData.h" +#include "RigSingleWellResultsData.h" -#include "RimReservoirCellResultsStorage.h" #include "RimEclipseCase.h" -#include "RimEclipseInputCase.h" -#include "RimEclipseInputPropertyCollection.h" -#include "RimUiTreeModelPdm.h" -#include "RimEclipseView.h" -#include "RimEclipseCellColors.h" -#include "RimCellEdgeColors.h" -#include "RimCellRangeFilterCollection.h" -#include "RimEclipsePropertyFilterCollection.h" -#include "RimEclipseWellCollection.h" -#include "Rim3dOverlayInfoConfig.h" +#include "cvfCollection.h" + +#include #include diff --git a/ApplicationCode/UserInterface/RiuCadNavigation.cpp b/ApplicationCode/UserInterface/RiuCadNavigation.cpp index 700b1e35f0..09c5e60418 100644 --- a/ApplicationCode/UserInterface/RiuCadNavigation.cpp +++ b/ApplicationCode/UserInterface/RiuCadNavigation.cpp @@ -133,7 +133,7 @@ bool RiuCadNavigation::handleInputEvent(QInputEvent* inputEvent) bool needRedraw = m_trackball->updateNavigation(translatedMousePosX, translatedMousePosY); if (needRedraw) { - m_viewer->update(); + m_viewer->navigationPolicyUpdate(); m_navigationUpdated = true; } isEventHandled = true; @@ -169,7 +169,7 @@ bool RiuCadNavigation::handleInputEvent(QInputEvent* inputEvent) cvf::Vec3d newVrp = vrp + trans; m_viewer->mainCamera()->setFromLookAt(newPos,newVrp, up ); - m_viewer->update(); + m_viewer->navigationPolicyUpdate(); } } isEventHandled = true; diff --git a/ApplicationCode/UserInterface/RiuCursors.cpp b/ApplicationCode/UserInterface/RiuCursors.cpp index bc84b95511..1996c17ccb 100644 --- a/ApplicationCode/UserInterface/RiuCursors.cpp +++ b/ApplicationCode/UserInterface/RiuCursors.cpp @@ -16,7 +16,6 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RiaStdInclude.h" #include "RiuCursors.h" @@ -38,15 +37,15 @@ RiuCursors::RiuCursors() { m_cursors[FILTER_BOX] = cursorFromFile(":/Cursors/curFilterBox.bmp", 10, 10); - m_cursors[NORMAL] = cursorFromFile(":/Cursors/curNormal.bmp", 10, 10); - m_cursors[PAN] = cursorFromFile(":/Cursors/curPan.bmp"); - m_cursors[WALK] = cursorFromFile(":/Cursors/curWalk.bmp"); - m_cursors[ZOOM] = cursorFromFile(":/Cursors/curZoom.bmp"); - m_cursors[ROTATE] = cursorFromFile(":/Cursors/curRotate.bmp"); - - m_cursors[PICK] = cursorFromFile(":/Cursors/curPick.bmp", 10, 10); - m_cursors[PICK_ROTPOINT]= cursorFromFile(":/Cursors/curPickRotPoint.bmp", 10, 10); - m_cursors[PICK_GOTO] = cursorFromFile(":/Cursors/curPickGoto.bmp", 10, 10); + m_cursors[NORMAL] = cursorFromFile(":/Cursors/curNormal.bmp", 10, 10); + m_cursors[PAN] = cursorFromFile(":/Cursors/curPan.bmp"); + m_cursors[WALK] = cursorFromFile(":/Cursors/curWalk.bmp"); + m_cursors[ZOOM] = cursorFromFile(":/Cursors/curZoom.bmp"); + m_cursors[ROTATE] = cursorFromFile(":/Cursors/curRotate.bmp"); + + m_cursors[PICK] = cursorFromFile(":/Cursors/curPick.bmp", 10, 10); + m_cursors[PICK_ROTPOINT]= cursorFromFile(":/Cursors/curPickRotPoint.bmp", 10, 10); + m_cursors[PICK_GOTO] = cursorFromFile(":/Cursors/curPickGoto.bmp", 10, 10); } @@ -55,9 +54,9 @@ RiuCursors::RiuCursors() //-------------------------------------------------------------------------------------------------- QCursor RiuCursors::get(CursorIndex cursorIdx) { - // Create our single instance in a local static variable - static RiuCursors myStaticInstance; - + // Create our single instance in a local static variable + static RiuCursors myStaticInstance; + return myStaticInstance.m_cursors[cursorIdx]; } @@ -65,23 +64,23 @@ QCursor RiuCursors::get(CursorIndex cursorIdx) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QCursor RiuCursors::cursorFromFile(const QString& fileName, int hotspotX, int hotspotY) +QCursor RiuCursors::cursorFromFile(const QString& fileName, int hotspotX, int hotspotY) { - QImage image(fileName); - if (image.width() == 0 || image.height() == 0) - { - return QCursor(); - } + QImage image(fileName); + if (image.width() == 0 || image.height() == 0) + { + return QCursor(); + } - QRgb maskClr = image.pixel(0, 0); - //QImage imgMask = image.createMaskFromColor(maskClr, Qt::MaskInColor); - QImage imgMask = image.createHeuristicMask(true); + QRgb maskClr = image.pixel(0, 0); + //QImage imgMask = image.createMaskFromColor(maskClr, Qt::MaskInColor); + QImage imgMask = image.createHeuristicMask(true); - QBitmap bmMask = QBitmap::fromImage(imgMask, Qt::ThresholdDither | Qt::AvoidDither); + QBitmap bmMask = QBitmap::fromImage(imgMask, Qt::ThresholdDither | Qt::AvoidDither); - QBitmap bitmap = QBitmap::fromImage(image, Qt::ThresholdDither | Qt::AvoidDither); + QBitmap bitmap = QBitmap::fromImage(image, Qt::ThresholdDither | Qt::AvoidDither); - return QCursor(bitmap, bmMask, hotspotX, hotspotY); + return QCursor(bitmap, bmMask, hotspotX, hotspotY); } diff --git a/ApplicationCode/UserInterface/RiuCursors.h b/ApplicationCode/UserInterface/RiuCursors.h index 61fb559a01..bb0dff9b06 100644 --- a/ApplicationCode/UserInterface/RiuCursors.h +++ b/ApplicationCode/UserInterface/RiuCursors.h @@ -41,16 +41,16 @@ class RiuCursors PICK, PICK_GOTO, PICK_ROTPOINT, - NUM_CURSORS + NUM_CURSORS }; public: - static QCursor get(CursorIndex cursorIdx); + static QCursor get(CursorIndex cursorIdx); private: - RiuCursors(); - static QCursor cursorFromFile(const QString& fileName, int hotspotX = -1, int hotspotY = -1); + RiuCursors(); + static QCursor cursorFromFile(const QString& fileName, int hotspotX = -1, int hotspotY = -1); private: - QCursor m_cursors[NUM_CURSORS]; + QCursor m_cursors[NUM_CURSORS]; }; diff --git a/ApplicationCode/UserInterface/RiuDragDrop.cpp b/ApplicationCode/UserInterface/RiuDragDrop.cpp new file mode 100644 index 0000000000..f5aea1513b --- /dev/null +++ b/ApplicationCode/UserInterface/RiuDragDrop.cpp @@ -0,0 +1,457 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RiuDragDrop.h" + +#include "OperationsUsingObjReferences/RicPasteEclipseCasesFeature.h" +#include "RicCloseCaseFeature.h" +#include "WellLogCommands/RicNewWellLogFileCurveFeature.h" +#include "WellLogCommands/RicWellLogPlotTrackFeatureImpl.h" + +#include "RimCaseCollection.h" +#include "RimEclipseCase.h" +#include "RimEclipseResultCase.h" +#include "RimIdenticalGridCaseGroup.h" +#include "RimMimeData.h" +#include "RimWellLogFileChannel.h" +#include "RimWellLogPlotTrack.h" +#include "RimWellLogPlotCurve.h" +#include "RimWellLogPlot.h" + +#include "RimWellLogPlotTrack.h" +#include "RiuMainWindow.h" + +#include "cafPdmUiTreeView.h" +#include "cafSelectionManager.h" +#include "cafPdmUiItem.h" + +#include +#include + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +template +class RiuTypedPdmObjects +{ +public: + RiuTypedPdmObjects(const caf::PdmObjectGroup& objectGroup) + { + objectGroup.objectsByType(&m_typedObjects); + } + + RiuTypedPdmObjects(const std::vector >& objectHandles) + { + for (size_t i = 0; i < objectHandles.size(); i++) + { + T* obj = dynamic_cast(objectHandles[i].p()); + if (obj) m_typedObjects.push_back(obj); + } + } + + static std::vector typedObjectsFromGroup(const caf::PdmObjectGroup& objectGroup) + { + RiuTypedPdmObjects typedObjectsGetter(objectGroup); + return typedObjectsGetter.typedObjects(); + } + + static bool containsTypedObjects(const caf::PdmObjectGroup& objectGroup) + { + RiuTypedPdmObjects typedObjectsGetter(objectGroup); + return typedObjectsGetter.typedObjects().size() > 0; + } + + static bool containsTypedObjects(const std::vector >& objectHandles) + { + RiuTypedPdmObjects typedObjectsGetter(objectHandles); + return typedObjectsGetter.typedObjects().size() > 0; + } + +private: + std::vector typedObjects() + { + std::vector typedObjectsVec; + for (size_t i = 0; i < m_typedObjects.size(); i++) + { + typedObjectsVec.push_back(m_typedObjects[i].p()); + } + + return typedObjectsVec; + } + +private: + std::vector > m_typedObjects; +}; + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RiuDragDrop::RiuDragDrop() +{ + m_proposedDropAction = Qt::MoveAction; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RiuDragDrop::~RiuDragDrop() +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +Qt::DropActions RiuDragDrop::supportedDropActions() const +{ + // Keep drag items so that we can determine allowed actions while dragging + m_dragItems = objectHandlesFromSelection(); + + if (RiuTypedPdmObjects::containsTypedObjects(m_dragItems)) + { + return Qt::CopyAction | Qt::MoveAction; + } + else if (RiuTypedPdmObjects::containsTypedObjects(m_dragItems)) + { + return Qt::CopyAction; + } + + return Qt::MoveAction; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +Qt::ItemFlags RiuDragDrop::flags(const QModelIndex &index) const +{ + Qt::ItemFlags itemflags = 0; + + if (index.isValid()) + { + caf::PdmUiTreeView* uiTreeView = RiuMainWindow::instance()->projectTreeView(); + caf::PdmUiItem* uiItem = uiTreeView->uiItemFromModelIndex(index); + + if (dynamic_cast(uiItem) || + dynamic_cast(uiItem) || + dynamic_cast(uiItem) || + dynamic_cast(uiItem)) + { + // TODO: Remember to handle reservoir holding the main grid + itemflags |= Qt::ItemIsDragEnabled; + } + + if (dynamic_cast(uiItem) || dynamic_cast(uiItem)) + { + if (RiuTypedPdmObjects::containsTypedObjects(m_dragItems)) + { + itemflags |= Qt::ItemIsDropEnabled; + } + } + else if (m_proposedDropAction == Qt::MoveAction) + { + if (dynamic_cast(uiItem)) + { + if (RiuTypedPdmObjects::containsTypedObjects(m_dragItems)) + { + itemflags |= Qt::ItemIsDropEnabled; + } + } + else if (dynamic_cast(uiItem)) + { + if (RiuTypedPdmObjects::containsTypedObjects(m_dragItems)) + { + itemflags |= Qt::ItemIsDropEnabled; + } + else if (RiuTypedPdmObjects::containsTypedObjects(m_dragItems)) + { + itemflags |= Qt::ItemIsDropEnabled; + } + } + else if (dynamic_cast(uiItem)) + { + if (RiuTypedPdmObjects::containsTypedObjects(m_dragItems)) + { + itemflags |= Qt::ItemIsDropEnabled; + } + } + } + else if (m_proposedDropAction == Qt::CopyAction) + { + if (dynamic_cast(uiItem)) + { + if (RiuTypedPdmObjects::containsTypedObjects(m_dragItems)) + { + itemflags |= Qt::ItemIsDropEnabled; + } + } + else if (dynamic_cast(uiItem)) + { + if (RiuTypedPdmObjects::containsTypedObjects(m_dragItems)) + { + itemflags |= Qt::ItemIsDropEnabled; + } + } + } + } + + return itemflags; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RiuDragDrop::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) +{ + caf::PdmUiTreeView* uiTreeView = RiuMainWindow::instance()->projectTreeView(); + caf::PdmUiItem* dropTargetUiItem = uiTreeView->uiItemFromModelIndex(parent); + caf::PdmObjectHandle* dropTarget = dynamic_cast(dropTargetUiItem); + if (dropTarget) + { + caf::PdmObjectGroup draggedObjects; + const MimeDataWithIndexes* myMimeData = qobject_cast(data); + if (myMimeData && parent.isValid()) + { + objectGroupFromModelIndexes(&draggedObjects, myMimeData->indexes()); + } + else + { + return false; + } + + RimIdenticalGridCaseGroup* gridCaseGroup; + dropTarget->firstAnchestorOrThisOfType(gridCaseGroup); + if (gridCaseGroup) + { + return handleGridCaseGroupDrop(action, draggedObjects, gridCaseGroup); + } + + RimWellLogPlotCurve* wellLogPlotCurve; + dropTarget->firstAnchestorOrThisOfType(wellLogPlotCurve); + if (wellLogPlotCurve) + { + return handleWellLogPlotCurveDrop(action, draggedObjects, wellLogPlotCurve); + } + + RimWellLogPlotTrack* wellLogPlotTrack; + dropTarget->firstAnchestorOrThisOfType(wellLogPlotTrack); + if (wellLogPlotTrack) + { + return handleWellLogPlotTrackDrop(action, draggedObjects, wellLogPlotTrack); + } + + RimWellLogPlot* wellLogPlot; + dropTarget->firstAnchestorOrThisOfType(wellLogPlot); + if (wellLogPlot) + { + return handleWellLogPlotDrop(action, draggedObjects, wellLogPlot); + } + } + + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QMimeData* RiuDragDrop::mimeData(const QModelIndexList &indexes) const +{ + MimeDataWithIndexes* myObj = new MimeDataWithIndexes(); + myObj->setIndexes(indexes); + + return myObj; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QStringList RiuDragDrop::mimeTypes() const +{ + QStringList types; + types << MimeDataWithIndexes::formatName(); + return types; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuDragDrop::onDragCanceled() +{ + m_dragItems.clear(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuDragDrop::moveCasesToGridGroup(caf::PdmObjectGroup& objectGroup, RimIdenticalGridCaseGroup* gridCaseGroup) +{ + std::vector casesToBeDeleted = RiuTypedPdmObjects::typedObjectsFromGroup(objectGroup); + + if (RicCloseCaseFeature::userConfirmedGridCaseGroupChange(casesToBeDeleted)) + { + caf::RicPasteEclipseCasesFeature::addCasesToGridCaseGroup(objectGroup, gridCaseGroup); + + for (size_t i = 0; i < casesToBeDeleted.size(); i++) + { + RicCloseCaseFeature::deleteEclipseCase(casesToBeDeleted[i]); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RiuDragDrop::handleGridCaseGroupDrop(Qt::DropAction action, caf::PdmObjectGroup& objectGroup, RimIdenticalGridCaseGroup* gridCaseGroup) +{ + if (action == Qt::CopyAction) + { + caf::RicPasteEclipseCasesFeature::addCasesToGridCaseGroup(objectGroup, gridCaseGroup); + } + else if (action == Qt::MoveAction) + { + moveCasesToGridGroup(objectGroup, gridCaseGroup); + } + + return true; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RiuDragDrop::handleWellLogPlotTrackDrop(Qt::DropAction action, caf::PdmObjectGroup& draggedObjects, RimWellLogPlotTrack* trackTarget) +{ + std::vector wellLogFileChannels = RiuTypedPdmObjects::typedObjectsFromGroup(draggedObjects); + if (wellLogFileChannels.size() > 0) + { + if (action == Qt::CopyAction) + { + RicNewWellLogFileCurveFeature::addWellLogChannelsToPlotTrack(trackTarget, wellLogFileChannels); + return true; + } + } + + std::vector wellLogPlotCurves = RiuTypedPdmObjects::typedObjectsFromGroup(draggedObjects); + if (wellLogPlotCurves.size() > 0) + { + if (action == Qt::MoveAction) + { + RicWellLogPlotTrackFeatureImpl::moveCurvesToWellLogPlotTrack(trackTarget, wellLogPlotCurves, NULL); + return true; + } + } + + std::vector wellLogPlotTracks = RiuTypedPdmObjects::typedObjectsFromGroup(draggedObjects); + if (wellLogPlotTracks.size() > 0) + { + if (action == Qt::MoveAction) + { + RimWellLogPlot* wellLogPlot; + trackTarget->firstAnchestorOrThisOfType(wellLogPlot); + RicWellLogPlotTrackFeatureImpl::moveTracksToWellLogPlot(wellLogPlot, wellLogPlotTracks, trackTarget); + return true; + } + } + + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RiuDragDrop::handleWellLogPlotCurveDrop(Qt::DropAction action, caf::PdmObjectGroup& draggedObjects, RimWellLogPlotCurve* curveDropTarget) +{ + std::vector wellLogPlotCurves = RiuTypedPdmObjects::typedObjectsFromGroup(draggedObjects); + if (wellLogPlotCurves.size() > 0) + { + if (action == Qt::MoveAction) + { + RimWellLogPlotTrack* wellLogPlotTrack; + curveDropTarget->firstAnchestorOrThisOfType(wellLogPlotTrack); + + RicWellLogPlotTrackFeatureImpl::moveCurvesToWellLogPlotTrack(wellLogPlotTrack, wellLogPlotCurves, curveDropTarget); + return true; + } + } + + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RiuDragDrop::handleWellLogPlotDrop(Qt::DropAction action, caf::PdmObjectGroup& draggedObjects, RimWellLogPlot* wellLogPlotTarget) +{ + std::vector wellLogPlotTracks = RiuTypedPdmObjects::typedObjectsFromGroup(draggedObjects); + if (wellLogPlotTracks.size() > 0) + { + if (action == Qt::MoveAction) + { + RicWellLogPlotTrackFeatureImpl::moveTracksToWellLogPlot(wellLogPlotTarget, wellLogPlotTracks, NULL); + return true; + } + } + + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuDragDrop::objectGroupFromModelIndexes(caf::PdmObjectGroup* objectGroup, const QModelIndexList& indexes) +{ + CVF_ASSERT(objectGroup); + + objectGroup->objects.clear(); + caf::PdmUiTreeView* uiTreeView = RiuMainWindow::instance()->projectTreeView(); + + for (int i = 0; i < indexes.size(); i++) + { + caf::PdmUiItem* uiItem = uiTreeView->uiItemFromModelIndex(indexes[i]); + caf::PdmObjectHandle* objHandle = dynamic_cast(uiItem); + if (objHandle) + { + objectGroup->objects.push_back(objHandle); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector > RiuDragDrop::objectHandlesFromSelection() +{ + std::vector selection; + caf::SelectionManager::instance()->objectsByType(&selection); + + std::vector > objectHandles; + + for (size_t sIdx = 0; sIdx < selection.size(); sIdx++) + { + objectHandles.push_back(selection[sIdx]); + } + + return objectHandles; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuDragDrop::onProposedDropActionUpdated(Qt::DropAction action) +{ + m_proposedDropAction = action; +} diff --git a/ApplicationCode/UserInterface/RiuDragDrop.h b/ApplicationCode/UserInterface/RiuDragDrop.h new file mode 100644 index 0000000000..203251dc72 --- /dev/null +++ b/ApplicationCode/UserInterface/RiuDragDrop.h @@ -0,0 +1,71 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafPdmUiDragDropInterface.h" +#include "cafPdmPointer.h" +#include "cafPdmObjectGroup.h" + +#include + +namespace caf +{ + class PdmObjectHandle; +} + +class RimIdenticalGridCaseGroup; +class RimWellLogPlot; +class RimWellLogPlotTrack; +class RimWellLogPlotCurve; + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +class RiuDragDrop : public caf::PdmUiDragDropInterface +{ +public: + RiuDragDrop(); + virtual ~RiuDragDrop(); + +protected: + virtual Qt::DropActions supportedDropActions() const; + virtual Qt::ItemFlags flags(const QModelIndex &index) const; + virtual bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent); + virtual QMimeData* mimeData(const QModelIndexList &indexes) const; + virtual QStringList mimeTypes() const; + + virtual void onDragCanceled(); + virtual void onProposedDropActionUpdated(Qt::DropAction action); + +private: + void moveCasesToGridGroup(caf::PdmObjectGroup& objectGroup, RimIdenticalGridCaseGroup* gridCaseGroup); + bool handleGridCaseGroupDrop(Qt::DropAction action, caf::PdmObjectGroup& objectGroup, RimIdenticalGridCaseGroup* gridCaseGroup); + bool handleWellLogPlotTrackDrop(Qt::DropAction action, caf::PdmObjectGroup& objectGroup, RimWellLogPlotTrack* wellLogPlotTrack); + bool handleWellLogPlotDrop(Qt::DropAction action, caf::PdmObjectGroup& objectGroup, RimWellLogPlot* wellLogPlot); + bool handleWellLogPlotCurveDrop(Qt::DropAction action, caf::PdmObjectGroup& objectGroup, RimWellLogPlotCurve* wellLogPlotCurve); + + static void objectGroupFromModelIndexes(caf::PdmObjectGroup* objectGroup, const QModelIndexList &indexes); + static std::vector > objectHandlesFromSelection(); + +private: + mutable std::vector > m_dragItems; + Qt::DropAction m_proposedDropAction; +}; + diff --git a/ApplicationCode/UserInterface/RiuFemResultTextBuilder.cpp b/ApplicationCode/UserInterface/RiuFemResultTextBuilder.cpp index d0efee33c4..1c14e89877 100644 --- a/ApplicationCode/UserInterface/RiuFemResultTextBuilder.cpp +++ b/ApplicationCode/UserInterface/RiuFemResultTextBuilder.cpp @@ -38,9 +38,9 @@ RiuFemResultTextBuilder::RiuFemResultTextBuilder(RimGeoMechView* reservoirView, CVF_ASSERT(reservoirView); m_reservoirView = reservoirView; - m_gridIndex = gridIndex; - m_cellIndex = cellIndex; - m_timeStepIndex = timeStepIndex; + m_gridIndex = gridIndex; + m_cellIndex = cellIndex; + m_timeStepIndex = timeStepIndex; m_intersectionPoint = cvf::Vec3d::UNDEFINED; m_face = cvf::StructGridInterface::NO_FACE; @@ -79,7 +79,7 @@ QString RiuFemResultTextBuilder::mainResultText() appendDetails(text, gridResultDetails()); - return text; + return text; } //-------------------------------------------------------------------------------------------------- @@ -135,21 +135,21 @@ QString RiuFemResultTextBuilder::topologyText(QString itemSeparator) //-------------------------------------------------------------------------------------------------- QString RiuFemResultTextBuilder::gridResultDetails() { - QString text; + QString text; - if (m_reservoirView->geoMechCase() && m_reservoirView->geoMechCase()->geoMechData()) - { - RigGeoMechCaseData* eclipseCaseData = m_reservoirView->geoMechCase()->geoMechData(); + if (m_reservoirView->geoMechCase() && m_reservoirView->geoMechCase()->geoMechData()) + { + RigGeoMechCaseData* eclipseCaseData = m_reservoirView->geoMechCase()->geoMechData(); - this->appendTextFromResultColors(eclipseCaseData, m_gridIndex, m_cellIndex, m_timeStepIndex, m_reservoirView->cellResult(), &text); + this->appendTextFromResultColors(eclipseCaseData, m_gridIndex, m_cellIndex, m_timeStepIndex, m_reservoirView->cellResult(), &text); if (!text.isEmpty()) { text.prepend("-- Element result details --\n"); } - } + } - return text; + return text; } @@ -158,10 +158,10 @@ QString RiuFemResultTextBuilder::gridResultDetails() //-------------------------------------------------------------------------------------------------- void RiuFemResultTextBuilder::appendTextFromResultColors(RigGeoMechCaseData* geomData, int gridIndex, int cellIndex, int timeStepIndex, RimGeoMechCellColors* resultColors, QString* resultInfoText) { - if (!resultColors) - { - return; - } + if (!resultColors) + { + return; + } if (resultColors->hasResult()) { @@ -178,6 +178,8 @@ void RiuFemResultTextBuilder::appendTextFromResultColors(RigGeoMechCaseData* geo RigElementType elmType = femPart->elementType(cellIndex); const int* elmentConn = femPart->connectivities(cellIndex); int elmNodeCount = RigFemTypes::elmentNodeCount(elmType); + const int* lElmNodeToIpMap = RigFemTypes::localElmNodeToIntegrationPointMapping(elmType); + for (int lNodeIdx = 0; lNodeIdx < elmNodeCount; ++lNodeIdx) { @@ -194,7 +196,18 @@ void RiuFemResultTextBuilder::appendTextFromResultColors(RigGeoMechCaseData* geo scalarValue = scalarResults[resIdx]; } - resultInfoText->append(QString("\tN:%1 \t: %2\n").arg(femPart->nodes().nodeIds[nodeIdx]).arg(scalarValue)); + + if (resultColors->resultPositionType() == RIG_INTEGRATION_POINT) + { + resultInfoText->append(QString("\tIP:%1 \t: %2 \tAss. Node: \t%3").arg(lElmNodeToIpMap[lNodeIdx] + 1 ).arg(scalarValue).arg(femPart->nodes().nodeIds[nodeIdx])); + } + else + { + resultInfoText->append(QString("\tN:%1 \t: %2").arg(femPart->nodes().nodeIds[nodeIdx]).arg(scalarValue)); + } + + cvf::Vec3f nodeCoord = femPart->nodes().coordinates[nodeIdx]; + resultInfoText->append(QString("\t( %3, %4, %5)\n").arg(nodeCoord[0]).arg(nodeCoord[1]).arg(nodeCoord[2])); } } } @@ -218,16 +231,16 @@ void RiuFemResultTextBuilder::appendDetails(QString& text, const QString& detail QString RiuFemResultTextBuilder::closestNodeResultText(RimGeoMechCellColors* resultColors) { QString text; - if (!resultColors) - { - return text; - } + if (!resultColors) + { + return text; + } if (resultColors->hasResult()) { - if (! (m_reservoirView->geoMechCase() && m_reservoirView->geoMechCase()->geoMechData())) return text; - - RigGeoMechCaseData* geomData = m_reservoirView->geoMechCase()->geoMechData(); + if (! (m_reservoirView->geoMechCase() && m_reservoirView->geoMechCase()->geoMechData())) return text; + + RigGeoMechCaseData* geomData = m_reservoirView->geoMechCase()->geoMechData(); const std::vector& scalarResults = geomData->femPartResults()->resultValues(resultColors->resultAddress(), m_gridIndex, m_timeStepIndex); if (scalarResults.size()) diff --git a/ApplicationCode/UserInterface/RiuFemResultTextBuilder.h b/ApplicationCode/UserInterface/RiuFemResultTextBuilder.h index 2d168bc0aa..2cbd88b371 100644 --- a/ApplicationCode/UserInterface/RiuFemResultTextBuilder.h +++ b/ApplicationCode/UserInterface/RiuFemResultTextBuilder.h @@ -30,7 +30,7 @@ class RigGeoMechCaseData; class RimGeoMechCellColors; namespace cvf { - class Part; + class Part; } //================================================================================================== @@ -40,14 +40,14 @@ namespace cvf { class RiuFemResultTextBuilder { public: - RiuFemResultTextBuilder(RimGeoMechView* reservoirView, int gridIndex, int cellIndex, int timeStepIndex); + RiuFemResultTextBuilder(RimGeoMechView* reservoirView, int gridIndex, int cellIndex, int timeStepIndex); void setFace(cvf::StructGridInterface::FaceType face); void setIntersectionPoint(cvf::Vec3d intersectionPoint); QString mainResultText(); - QString topologyText(QString itemSeparator); - + QString topologyText(QString itemSeparator); + private: void appendDetails(QString& text, const QString& details); @@ -55,16 +55,16 @@ class RiuFemResultTextBuilder QString closestNodeResultText(RimGeoMechCellColors* resultColors); - void appendTextFromResultColors(RigGeoMechCaseData* eclipseCase, int gridIndex, int cellIndex, int timeStepIndex, RimGeoMechCellColors* resultColors, QString* resultInfoText); + void appendTextFromResultColors(RigGeoMechCaseData* eclipseCase, int gridIndex, int cellIndex, int timeStepIndex, RimGeoMechCellColors* resultColors, QString* resultInfoText); private: caf::PdmPointer m_reservoirView; - int m_gridIndex; - int m_cellIndex; - int m_timeStepIndex; + int m_gridIndex; + int m_cellIndex; + int m_timeStepIndex; - cvf::StructGridInterface::FaceType m_face; + cvf::StructGridInterface::FaceType m_face; - cvf::Vec3d m_intersectionPoint; + cvf::Vec3d m_intersectionPoint; }; diff --git a/ApplicationCode/UserInterface/RiuGeoQuestNavigation.cpp b/ApplicationCode/UserInterface/RiuGeoQuestNavigation.cpp index ad27fdcedc..84faebc730 100644 --- a/ApplicationCode/UserInterface/RiuGeoQuestNavigation.cpp +++ b/ApplicationCode/UserInterface/RiuGeoQuestNavigation.cpp @@ -134,7 +134,7 @@ bool RiuGeoQuestNavigation::handleInputEvent(QInputEvent* inputEvent) bool needRedraw = m_trackball->updateNavigation(translatedMousePosX, translatedMousePosY); if (needRedraw) { - m_viewer->update(); + m_viewer->navigationPolicyUpdate(); } } isEventHandled = true; @@ -245,6 +245,6 @@ void RiuGeoQuestNavigation::zoomAlongRay(cvf::Ray* ray, int delta) cvf::Vec3d newVrp = vrp + trans; m_viewer->mainCamera()->setFromLookAt(newPos, newVrp, up ); - m_viewer->update(); + m_viewer->navigationPolicyUpdate(); } } diff --git a/ApplicationCode/UserInterface/RiuMainWindow.cpp b/ApplicationCode/UserInterface/RiuMainWindow.cpp index a817cb6606..b57ba4f65d 100644 --- a/ApplicationCode/UserInterface/RiuMainWindow.cpp +++ b/ApplicationCode/UserInterface/RiuMainWindow.cpp @@ -18,54 +18,84 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RiaStdInclude.h" - #include "RiuMainWindow.h" #include "RiaApplication.h" #include "RiaBaseDefs.h" #include "RiaPreferences.h" #include "RiaRegressionTest.h" + #include "RigCaseCellResultsData.h" -#include "RimEclipseCaseCollection.h" -#include "RimEclipseCase.h" +#include "RigFemPartResultsCollection.h" +#include "RigGeoMechCaseData.h" + #include "RimCaseCollection.h" -#include "RimEclipsePropertyFilterCollection.h" #include "RimCommandObject.h" +#include "RimEclipseCase.h" +#include "RimEclipseCaseCollection.h" +#include "RimEclipseCellColors.h" +#include "RimEclipsePropertyFilterCollection.h" +#include "RimEclipseView.h" +#include "RimEclipseWellCollection.h" #include "RimFaultCollection.h" +#include "RimGeoMechCase.h" +#include "RimGeoMechCellColors.h" +#include "RimGeoMechModels.h" +#include "RimGeoMechView.h" +#include "RimGeoMechView.h" +#include "RimMainPlotCollection.h" #include "RimOilField.h" #include "RimProject.h" #include "RimReservoirCellResultsStorage.h" -#include "RimEclipseView.h" -#include "RimGeoMechView.h" -#include "RimGeoMechCase.h" - -#include "RimEclipseCellColors.h" -#include "RimGeoMechCellColors.h" #include "RimTools.h" -#include "RimUiTreeModelPdm.h" -#include "RimUiTreeView.h" -#include "RimEclipseWellCollection.h" -#include "RimWellPathCollection.h" +#include "RimTreeViewStateSerializer.h" +#include "RimWellLogPlot.h" +#include "RimWellLogPlotCollection.h" #include "RimWellPathImport.h" + +#include "RiuDragDrop.h" #include "RiuMultiCaseImportDialog.h" #include "RiuProcessMonitor.h" +#include "RiuProjectPropertyView.h" #include "RiuResultInfoPanel.h" +#include "RiuTreeViewEventFilter.h" #include "RiuViewer.h" #include "RiuWellImportWizard.h" - -#include "RigGeoMechCaseData.h" +#include "RiuWellLogPlot.h" #include "cafAboutDialog.h" #include "cafAnimationToolBar.h" +#include "cafCmdExecCommandManager.h" +#include "cafCmdFeatureManager.h" +#include "cafPdmDefaultObjectFactory.h" #include "cafPdmFieldCvfMat4d.h" -#include "cafPdmUiPropertyDialog.h" +#include "cafPdmObjectGroup.h" +#include "cafPdmSettings.h" #include "cafPdmUiPropertyView.h" - +#include "cafPdmUiPropertyViewDialog.h" +#include "cafPdmUiTreeView.h" +#include "cafSelectionManager.h" #include "cvfTimer.h" -#include "RimGeoMechModels.h" -#include "RimGeoMechView.h" -#include "RigFemPartResultsCollection.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + //================================================================================================== @@ -83,28 +113,20 @@ RiuMainWindow* RiuMainWindow::sm_mainWindowInstance = NULL; /// //-------------------------------------------------------------------------------------------------- RiuMainWindow::RiuMainWindow() -: m_treeView(NULL), - m_pdmRoot(NULL), + : m_pdmRoot(NULL), m_mainViewer(NULL), - m_windowMenu(NULL) + m_windowMenu(NULL), + m_blockSlotSubWindowActivated(false) { CVF_ASSERT(sm_mainWindowInstance == NULL); -#if 0 - m_CentralFrame = new QFrame; - QHBoxLayout* frameLayout = new QHBoxLayout(m_CentralFrame); - setCentralWidget(m_CentralFrame); -#else m_mdiArea = new QMdiArea; - connect(m_mdiArea, SIGNAL(subWindowActivated ( QMdiSubWindow *)), SLOT(slotSubWindowActivated(QMdiSubWindow*))); + m_mdiArea->setOption(QMdiArea::DontMaximizeSubWindowOnActivation, true); + connect(m_mdiArea, SIGNAL(subWindowActivated(QMdiSubWindow *)), SLOT(slotSubWindowActivated(QMdiSubWindow*))); setCentralWidget(m_mdiArea); -#endif //m_mainViewer = createViewer(); - - m_treeModelPdm = new RimUiTreeModelPdm(this); - createActions(); createMenus(); createToolBars(); @@ -112,15 +134,16 @@ RiuMainWindow::RiuMainWindow() // Store the layout so we can offer reset option m_initialDockAndToolbarLayout = saveState(0); - loadWinGeoAndDockToolBarLayout(); sm_mainWindowInstance = this; - - slotRefreshFileActions(); - slotRefreshEditActions(); - // Set pdm root so scripts are displayed - setPdmRoot(RiaApplication::instance()->project()); + m_dragDropInterface = new RiuDragDrop; + + initializeGuiNewProjectLoaded(); + + // Enabling the line below will activate the undo stack + // When enableUndoCommandSystem is set false, all commands are executed and deleted immediately + //caf::CmdExecCommandManager::instance()->enableUndoCommandSystem(true); } @@ -153,6 +176,8 @@ void RiuMainWindow::initializeGuiNewProjectLoaded() //-------------------------------------------------------------------------------------------------- void RiuMainWindow::cleanupGuiBeforeProjectClose() { + caf::CmdExecCommandManager::instance()->undoStack()->clear(); + setPdmRoot(NULL); setResultInfo(""); @@ -161,6 +186,14 @@ void RiuMainWindow::cleanupGuiBeforeProjectClose() m_pdmUiPropertyView->showProperties(NULL); } + for (size_t i = 0; i < additionalProjectViews.size(); i++) + { + RiuProjectAndPropertyView* projPropView = dynamic_cast(additionalProjectViews[i]->widget()); + if (projPropView) + { + projPropView->showProperties(NULL); + } + } m_processMonitor->startMonitorWorkProcess(NULL); } @@ -175,9 +208,9 @@ void RiuMainWindow::closeEvent(QCloseEvent* event) return; } + delete m_dragDropInterface; + saveWinGeoAndDockToolBarLayout(); - - event->accept(); } @@ -191,13 +224,7 @@ void RiuMainWindow::createActions() m_openProjectAction = new QAction(style()->standardIcon(QStyle::SP_DirOpenIcon), "&Open Project", this); m_openLastUsedProjectAction = new QAction("Open &Last Used Project", this); - m_importEclipseCaseAction = new QAction(QIcon(":/Case48x48.png"), "Import &Eclipse Case", this); - m_importInputEclipseFileAction= new QAction(QIcon(":/EclipseInput48x48.png"), "Import &Input Eclipse Case", this); m_importGeoMechCaseAction = new QAction(QIcon(":/GeoMechCase48x48.png"), "Import &Geo Mechanical Model", this); - m_openMultipleEclipseCasesAction = new QAction(QIcon(":/CreateGridCaseGroup16x16.png"), "&Create Grid Case Group from Files", this); - - m_importWellPathsFromFileAction = new QAction(QIcon(":/Well.png"), "Import &Well Paths from File", this); - m_importWellPathsFromSSIHubAction = new QAction(QIcon(":/WellCollection.png"),"Import Well Paths from &SSI-hub", this); m_mockModelAction = new QAction("&Mock Model", this); m_mockResultsModelAction = new QAction("Mock Model With &Results", this); @@ -227,40 +254,35 @@ void RiuMainWindow::createActions() m_exitAction = new QAction("E&xit", this); - connect(m_openProjectAction, SIGNAL(triggered()), SLOT(slotOpenProject())); + connect(m_openProjectAction, SIGNAL(triggered()), SLOT(slotOpenProject())); connect(m_openLastUsedProjectAction, SIGNAL(triggered()), SLOT(slotOpenLastUsedProject())); - connect(m_importEclipseCaseAction, SIGNAL(triggered()), SLOT(slotImportEclipseCase())); - connect(m_importGeoMechCaseAction, SIGNAL(triggered()), SLOT(slotImportGeoMechModel())); - connect(m_importInputEclipseFileAction, SIGNAL(triggered()), SLOT(slotImportInputEclipseFiles())); - connect(m_openMultipleEclipseCasesAction, SIGNAL(triggered()), SLOT(slotOpenMultipleCases())); - connect(m_importWellPathsFromFileAction, SIGNAL(triggered()), SLOT(slotImportWellPathsFromFile())); - connect(m_importWellPathsFromSSIHubAction, SIGNAL(triggered()), SLOT(slotImportWellPathsFromSSIHub())); + connect(m_importGeoMechCaseAction, SIGNAL(triggered()), SLOT(slotImportGeoMechModel())); - connect(m_mockModelAction, SIGNAL(triggered()), SLOT(slotMockModel())); - connect(m_mockResultsModelAction, SIGNAL(triggered()), SLOT(slotMockResultsModel())); - connect(m_mockLargeResultsModelAction, SIGNAL(triggered()), SLOT(slotMockLargeResultsModel())); - connect(m_mockModelCustomizedAction, SIGNAL(triggered()), SLOT(slotMockModelCustomized())); - connect(m_mockInputModelAction, SIGNAL(triggered()), SLOT(slotInputMockModel())); - - connect(m_snapshotToFile, SIGNAL(triggered()), SLOT(slotSnapshotToFile())); - connect(m_snapshotToClipboard, SIGNAL(triggered()), SLOT(slotSnapshotToClipboard())); + connect(m_mockModelAction, SIGNAL(triggered()), SLOT(slotMockModel())); + connect(m_mockResultsModelAction, SIGNAL(triggered()), SLOT(slotMockResultsModel())); + connect(m_mockLargeResultsModelAction, SIGNAL(triggered()), SLOT(slotMockLargeResultsModel())); + connect(m_mockModelCustomizedAction, SIGNAL(triggered()), SLOT(slotMockModelCustomized())); + connect(m_mockInputModelAction, SIGNAL(triggered()), SLOT(slotInputMockModel())); + + connect(m_snapshotToFile, SIGNAL(triggered()), SLOT(slotSnapshotToFile())); + connect(m_snapshotToClipboard, SIGNAL(triggered()), SLOT(slotSnapshotToClipboard())); connect(m_snapshotAllViewsToFile, SIGNAL(triggered()), SLOT(slotSnapshotAllViewsToFile())); connect(m_createCommandObject, SIGNAL(triggered()), SLOT(slotCreateCommandObject())); connect(m_showRegressionTestDialog, SIGNAL(triggered()), SLOT(slotShowRegressionTestDialog())); connect(m_executePaintEventPerformanceTest, SIGNAL(triggered()), SLOT(slotExecutePaintEventPerformanceTest())); - connect(m_saveProjectAction, SIGNAL(triggered()), SLOT(slotSaveProject())); - connect(m_saveProjectAsAction, SIGNAL(triggered()), SLOT(slotSaveProjectAs())); + connect(m_saveProjectAction, SIGNAL(triggered()), SLOT(slotSaveProject())); + connect(m_saveProjectAsAction, SIGNAL(triggered()), SLOT(slotSaveProjectAs())); - connect(m_closeProjectAction, SIGNAL(triggered()), SLOT(slotCloseProject())); + connect(m_closeProjectAction, SIGNAL(triggered()), SLOT(slotCloseProject())); connect(m_exitAction, SIGNAL(triggered()), QApplication::instance(), SLOT(closeAllWindows())); // Edit actions m_editPreferences = new QAction("&Preferences...", this); - connect(m_editPreferences, SIGNAL(triggered()), SLOT(slotEditPreferences())); + connect(m_editPreferences, SIGNAL(triggered()), SLOT(slotEditPreferences())); // View actions m_viewFromNorth = new QAction(QIcon(":/SouthViewArrow.png"), "Look South", this); @@ -279,13 +301,13 @@ void RiuMainWindow::createActions() m_zoomAll = new QAction(QIcon(":/ZoomAll16x16.png"),"Zoom all", this); m_zoomAll->setToolTip("Zoom to view all"); - connect(m_viewFromNorth, SIGNAL(triggered()), SLOT(slotViewFromNorth())); - connect(m_viewFromSouth, SIGNAL(triggered()), SLOT(slotViewFromSouth())); - connect(m_viewFromEast, SIGNAL(triggered()), SLOT(slotViewFromEast())); - connect(m_viewFromWest, SIGNAL(triggered()), SLOT(slotViewFromWest())); - connect(m_viewFromAbove, SIGNAL(triggered()), SLOT(slotViewFromAbove())); - connect(m_viewFromBelow, SIGNAL(triggered()), SLOT(slotViewFromBelow())); - connect(m_zoomAll, SIGNAL(triggered()), SLOT(slotZoomAll())); + connect(m_viewFromNorth, SIGNAL(triggered()), SLOT(slotViewFromNorth())); + connect(m_viewFromSouth, SIGNAL(triggered()), SLOT(slotViewFromSouth())); + connect(m_viewFromEast, SIGNAL(triggered()), SLOT(slotViewFromEast())); + connect(m_viewFromWest, SIGNAL(triggered()), SLOT(slotViewFromWest())); + connect(m_viewFromAbove, SIGNAL(triggered()), SLOT(slotViewFromAbove())); + connect(m_viewFromBelow, SIGNAL(triggered()), SLOT(slotViewFromBelow())); + connect(m_zoomAll, SIGNAL(triggered()), SLOT(slotZoomAll())); // Debug actions m_newPropertyView = new QAction("New Project and Property View", this); @@ -303,18 +325,18 @@ void RiuMainWindow::createActions() m_dsActionGroup = new QActionGroup(this); m_drawStyleLinesAction = new QAction(QIcon(":/draw_style_lines_24x24.png"), "&Mesh Only", this); - //connect(m_drawStyleLinesAction, SIGNAL(triggered()), SLOT(slotDrawStyleLines())); + //connect(m_drawStyleLinesAction, SIGNAL(triggered()), SLOT(slotDrawStyleLines())); m_dsActionGroup->addAction(m_drawStyleLinesAction); m_drawStyleLinesSolidAction = new QAction(QIcon(":/draw_style_meshlines_24x24.png"), "Mesh And Surfaces", this); - //connect(m_drawStyleLinesSolidAction, SIGNAL(triggered()), SLOT(slotDrawStyleLinesSolid())); + //connect(m_drawStyleLinesSolidAction, SIGNAL(triggered()), SLOT(slotDrawStyleLinesSolid())); m_dsActionGroup->addAction(m_drawStyleLinesSolidAction); m_drawStyleFaultLinesSolidAction = new QAction(QIcon(":/draw_style_surface_w_fault_mesh_24x24.png"), "Fault Mesh And Surfaces", this); m_dsActionGroup->addAction(m_drawStyleFaultLinesSolidAction); m_drawStyleSurfOnlyAction = new QAction(QIcon(":/draw_style_surface_24x24.png"), "&Surface Only", this); - //connect(m_drawStyleSurfOnlyAction, SIGNAL(triggered()), SLOT(slotDrawStyleSurfOnly())); + //connect(m_drawStyleSurfOnlyAction, SIGNAL(triggered()), SLOT(slotDrawStyleSurfOnly())); m_dsActionGroup->addAction(m_drawStyleSurfOnlyAction); @@ -322,21 +344,21 @@ void RiuMainWindow::createActions() m_disableLightingAction = new QAction(QIcon(":/disable_lighting_24x24.png"), "&Disable Results Lighting", this); m_disableLightingAction->setCheckable(true); - connect(m_disableLightingAction, SIGNAL(toggled(bool)), SLOT(slotDisableLightingAction(bool))); + connect(m_disableLightingAction, SIGNAL(toggled(bool)), SLOT(slotDisableLightingAction(bool))); m_drawStyleToggleFaultsAction = new QAction( QIcon(":/draw_style_faults_24x24.png"), "&Show Faults Only", this); m_drawStyleToggleFaultsAction->setCheckable(true); - connect(m_drawStyleToggleFaultsAction, SIGNAL(toggled(bool)), SLOT(slotToggleFaultsAction(bool))); + connect(m_drawStyleToggleFaultsAction, SIGNAL(toggled(bool)), SLOT(slotToggleFaultsAction(bool))); m_toggleFaultsLabelAction = new QAction( QIcon(":/draw_style_faults_label_24x24.png"), "&Show Fault Labels", this); m_toggleFaultsLabelAction->setCheckable(true); - connect(m_toggleFaultsLabelAction, SIGNAL(toggled(bool)), SLOT(slotToggleFaultLabelsAction(bool))); + connect(m_toggleFaultsLabelAction, SIGNAL(toggled(bool)), SLOT(slotToggleFaultLabelsAction(bool))); m_addWellCellsToRangeFilterAction = new QAction(QIcon(":/draw_style_WellCellsToRangeFilter_24x24.png"), "&Add Well Cells To Range Filter", this); m_addWellCellsToRangeFilterAction->setCheckable(true); m_addWellCellsToRangeFilterAction->setToolTip("Add Well Cells To Range Filter based on the individual settings"); - connect(m_addWellCellsToRangeFilterAction, SIGNAL(toggled(bool)), SLOT(slotAddWellCellsToRangeFilterAction(bool))); + connect(m_addWellCellsToRangeFilterAction, SIGNAL(toggled(bool)), SLOT(slotAddWellCellsToRangeFilterAction(bool))); } @@ -383,6 +405,9 @@ class ToolTipableMenu : public QMenu //-------------------------------------------------------------------------------------------------- void RiuMainWindow::createMenus() { + caf::CmdFeatureManager* cmdFeatureMgr = caf::CmdFeatureManager::instance(); + CVF_ASSERT(cmdFeatureMgr); + // File menu QMenu* fileMenu = new ToolTipableMenu(menuBar()); fileMenu->setTitle("&File"); @@ -394,16 +419,17 @@ void RiuMainWindow::createMenus() fileMenu->addSeparator(); QMenu* importMenu = fileMenu->addMenu("&Import"); - importMenu->addAction(m_importEclipseCaseAction); - importMenu->addAction(m_importInputEclipseFileAction); - importMenu->addAction(m_openMultipleEclipseCasesAction); + importMenu->addAction(cmdFeatureMgr->action("RicImportEclipseCaseFeature")); + importMenu->addAction(cmdFeatureMgr->action("RicImportInputEclipseCaseFeature")); + importMenu->addAction(cmdFeatureMgr->action("RicCreateGridCaseGroupFeature")); importMenu->addSeparator(); #ifdef USE_ODB_API importMenu->addAction(m_importGeoMechCaseAction); importMenu->addSeparator(); #endif - importMenu->addAction(m_importWellPathsFromFileAction); - importMenu->addAction(m_importWellPathsFromSSIHubAction); + importMenu->addAction(cmdFeatureMgr->action("RicWellPathsImportFileFeature")); + importMenu->addAction(cmdFeatureMgr->action("RicWellPathsImportSsihubFeature")); + importMenu->addAction(cmdFeatureMgr->action("RicWellLogsImportFileFeature")); QMenu* exportMenu = fileMenu->addMenu("&Export"); exportMenu->addAction(m_snapshotToFile); @@ -462,6 +488,7 @@ void RiuMainWindow::createMenus() testMenu->addSeparator(); testMenu->addAction(m_showRegressionTestDialog); testMenu->addAction(m_executePaintEventPerformanceTest); + testMenu->addAction(cmdFeatureMgr->action("RicLaunchUnitTestsFeature")); // Windows menu m_windowMenu = menuBar()->addMenu("&Windows"); @@ -481,12 +508,14 @@ void RiuMainWindow::createMenus() //-------------------------------------------------------------------------------------------------- void RiuMainWindow::createToolBars() { + caf::CmdFeatureManager* cmdFeatureMgr = caf::CmdFeatureManager::instance(); + CVF_ASSERT(cmdFeatureMgr); m_standardToolBar = addToolBar(tr("Standard")); m_standardToolBar->setObjectName(m_standardToolBar->windowTitle()); - m_standardToolBar->addAction(m_importEclipseCaseAction); - m_standardToolBar->addAction(m_importInputEclipseFileAction); + m_standardToolBar->addAction(cmdFeatureMgr->action("RicImportEclipseCaseFeature")); + m_standardToolBar->addAction(cmdFeatureMgr->action("RicImportInputEclipseCaseFeature")); m_standardToolBar->addAction(m_openProjectAction); //m_standardToolBar->addAction(m_openLastUsedProjectAction); m_standardToolBar->addAction(m_saveProjectAction); @@ -509,6 +538,9 @@ void RiuMainWindow::createToolBars() m_viewToolBar->addAction(m_viewFromAbove); m_viewToolBar->addAction(m_viewFromBelow); m_viewToolBar->addSeparator(); + m_viewToolBar->addAction(cmdFeatureMgr->action("RicLinkVisibleViewsFeature")); + m_viewToolBar->addAction(cmdFeatureMgr->action("RicTileWindowsFeature")); + m_viewToolBar->addSeparator(); m_viewToolBar->addAction(m_drawStyleLinesAction); m_viewToolBar->addAction(m_drawStyleLinesSolidAction); m_viewToolBar->addAction(m_drawStyleSurfOnlyAction); @@ -546,22 +578,55 @@ void RiuMainWindow::createDockPanels() { QDockWidget* dockWidget = new QDockWidget("Project Tree", this); dockWidget->setObjectName("dockWidget"); - dockWidget->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea); + dockWidget->setAllowedAreas(Qt::AllDockWidgetAreas); - m_treeView = new RimUiTreeView(dockWidget); - m_treeView->setModel(m_treeModelPdm); - m_treeView->setSelectionMode(QAbstractItemView::ExtendedSelection); + m_projectTreeView = new caf::PdmUiTreeView(this); + m_projectTreeView->enableSelectionManagerUpdating(true); + + RiaApplication* app = RiaApplication::instance(); + m_projectTreeView->enableAppendOfClassNameToUiItemText(app->preferences()->appendClassNameToUiText()); + + dockWidget->setWidget(m_projectTreeView); + + m_projectTreeView->treeView()->setHeaderHidden(true); + m_projectTreeView->treeView()->setSelectionMode(QAbstractItemView::ExtendedSelection); // Drag and drop configuration - m_treeView->setDragEnabled(true); - m_treeView->viewport()->setAcceptDrops(true); - m_treeView->setDropIndicatorShown(true); - m_treeView->setDragDropMode(QAbstractItemView::DragDrop); + m_projectTreeView->treeView()->setDragEnabled(true); + m_projectTreeView->treeView()->viewport()->setAcceptDrops(true); + m_projectTreeView->treeView()->setDropIndicatorShown(true); + m_projectTreeView->treeView()->setDragDropMode(QAbstractItemView::DragDrop); - dockWidget->setWidget(m_treeView); + // Install event filter used to handle key press events + RiuTreeViewEventFilter* treeViewEventFilter = new RiuTreeViewEventFilter(this); + m_projectTreeView->treeView()->installEventFilter(treeViewEventFilter); - addDockWidget(Qt::LeftDockWidgetArea, dockWidget); + addDockWidget(Qt::RightDockWidgetArea, dockWidget); + + connect(m_projectTreeView, SIGNAL(selectionChanged()), this, SLOT(selectedObjectsChanged())); + m_projectTreeView->treeView()->setContextMenuPolicy(Qt::CustomContextMenu); + connect(m_projectTreeView->treeView(), SIGNAL(customContextMenuRequested(const QPoint&)), SLOT(customMenuRequested(const QPoint&))); } + +/* + { + QDockWidget* dockWidget = new QDockWidget("Undo stack", this); + dockWidget->setObjectName("dockWidget"); + dockWidget->setAllowedAreas(Qt::AllDockWidgetAreas); + + m_undoView = new QUndoView(this); + m_undoView->setStack(caf::CmdExecCommandManager::instance()->undoStack()); + //connect(caf::CmdExecCommandManager::instance()->undoStack(), SIGNAL(indexChanged(int)), SLOT(slotIndexChanged())); + + dockWidget->setWidget(m_undoView); + + addDockWidget(Qt::RightDockWidgetArea, dockWidget); + + dockWidget->hide(); + + //m_windowsMenu->addAction(dockWidget->toggleViewAction()); + } +*/ { QDockWidget* dockWidget = new QDockWidget("Property Editor", this); @@ -572,7 +637,6 @@ void RiuMainWindow::createDockPanels() dockWidget->setWidget(m_pdmUiPropertyView); m_pdmUiPropertyView->layout()->setContentsMargins(5,0,0,0); - connect(m_treeView, SIGNAL(selectedObjectChanged( caf::PdmObject* )), m_pdmUiPropertyView, SLOT(showProperties( caf::PdmObject* ))); addDockWidget(Qt::LeftDockWidgetArea, dockWidget); } @@ -597,8 +661,21 @@ void RiuMainWindow::createDockPanels() addDockWidget(Qt::BottomDockWidgetArea, dockPanel); } + // Test - create well log viewer in a dock widget + // TODO: remove after making MDI widgets for well log viewers +// { +// QDockWidget* dockPanel = new QDockWidget("TEST - Well Log Viewer", this); +// dockPanel->setObjectName("dockWellLogViewer"); +// dockPanel->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea | Qt::BottomDockWidgetArea); +// +// RiuWellLogViewer* wellLogViewer = new RiuWellLogViewer(dockPanel); +// dockPanel->setWidget(wellLogViewer); +// +// addDockWidget(Qt::BottomDockWidgetArea, dockPanel); +// } + - setCorner(Qt::BottomLeftCorner, Qt::LeftDockWidgetArea); + setCorner(Qt::BottomLeftCorner, Qt::LeftDockWidgetArea); setCorner(Qt::BottomRightCorner, Qt::BottomDockWidgetArea); } @@ -616,8 +693,9 @@ void RiuMainWindow::saveWinGeoAndDockToolBarLayout() QByteArray layout = saveState(0); settings.setValue("dockAndToolBarLayout", layout); -} + settings.setValue("isMaximized", isMaximized()); +} //-------------------------------------------------------------------------------------------------- /// @@ -642,6 +720,23 @@ void RiuMainWindow::loadWinGeoAndDockToolBarLayout() } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuMainWindow::showWindow() +{ + // Company and appname set through QCoreApplication + QSettings settings; + + showNormal(); + + QVariant isMax = settings.value("isMaximized", false); + if (isMax.toBool()) + { + showMaximized(); + } +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -672,7 +767,10 @@ void RiuMainWindow::slotRefreshFileActions() bool projectFileExists = QFile::exists(app->project()->fileName()); - m_importWellPathsFromSSIHubAction->setEnabled(projectFileExists); + caf::CmdFeatureManager* cmdFeatureMgr = caf::CmdFeatureManager::instance(); + CVF_ASSERT(cmdFeatureMgr); + + cmdFeatureMgr->action("RicWellPathsImportSsihubFeature")->setEnabled(projectFileExists); } @@ -700,6 +798,8 @@ void RiuMainWindow::slotRefreshViewActions() m_viewFromBelow->setEnabled(enabled); updateScaleValue(); + + caf::CmdFeatureManager::instance()->refreshEnabledState(QStringList() << "RicLinkVisibleViewsFeature" << "RicTileWindowsFeature"); } //-------------------------------------------------------------------------------------------------- @@ -716,12 +816,11 @@ void RiuMainWindow::refreshAnimationActions() m_animationToolBar->connectAnimationControl(animationControl); QStringList timeStepStrings; - int currentTimeStepIndex = 0; - RiaApplication* app = RiaApplication::instance(); + int currentTimeStepIndex = 0; bool enableAnimControls = false; - RimView * activeView = app->activeReservoirView(); + RimView * activeView = RiaApplication::instance()->activeReservoirView(); if (activeView && activeView->viewer() && activeView->viewer()->frameCount()) @@ -735,27 +834,7 @@ void RiuMainWindow::refreshAnimationActions() { if (activeRiv->isTimeStepDependentDataVisible()) { - std::vector timeStepDates = activeRiv->currentGridCellResults()->cellResults()->timeStepDates(0); - bool showHoursAndMinutes = false; - for (size_t i = 0; i < timeStepDates.size(); i++) - { - if (timeStepDates[i].time().hour() != 0.0 || timeStepDates[i].time().minute() != 0.0) - { - showHoursAndMinutes = true; - } - } - - QString formatString = "dd.MMM yyyy"; - if (showHoursAndMinutes) - { - formatString += " - hh:mm"; - } - - for (size_t i = 0; i < timeStepDates.size(); i++) - { - timeStepStrings += timeStepDates[i].toString(formatString); - } - currentTimeStepIndex = RiaApplication::instance()->activeReservoirView()->currentTimeStep(); + timeStepStrings = activeRiv->eclipseCase()->timeStepStrings(); } else { @@ -770,16 +849,13 @@ void RiuMainWindow::refreshAnimationActions() { if (activeGmv->isTimeStepDependentDataVisible()) { - std::vector stepNames = activeGmv->geoMechCase()->geoMechData()->femPartResults()->stepNames(); - for (size_t i = 0; i < stepNames.size(); i++) - { - timeStepStrings += QString::fromStdString(stepNames[i]); - } - currentTimeStepIndex = RiaApplication::instance()->activeReservoirView()->currentTimeStep(); + timeStepStrings = activeGmv->geoMechCase()->timeStepStrings(); } } } + currentTimeStepIndex = activeView->currentTimeStep(); + // Animation control is only relevant for more than one time step if (timeStepStrings.size() < 2) @@ -787,7 +863,7 @@ void RiuMainWindow::refreshAnimationActions() enableAnimControls = false; } - m_animationToolBar->setFrameRate(app->activeReservoirView()->maximumFrameRate()); + m_animationToolBar->setFrameRate(activeView->maximumFrameRate()); } m_animationToolBar->setTimeStepStrings(timeStepStrings); @@ -828,58 +904,6 @@ void RiuMainWindow::slotAbout() } - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RiuMainWindow::slotImportEclipseCase() -{ - if (checkForDocumentModifications()) - { - RiaApplication* app = RiaApplication::instance(); - - QString defaultDir = app->defaultFileDialogDirectory("BINARY_GRID"); - QStringList fileNames = QFileDialog::getOpenFileNames(this, "Import Eclipse File", defaultDir, "Eclipse Grid Files (*.GRID *.EGRID)"); - if (fileNames.size()) defaultDir = QFileInfo(fileNames.last()).absolutePath(); - app->setDefaultFileDialogDirectory("BINARY_GRID", defaultDir); - - int i; - for (i = 0; i < fileNames.size(); i++) - { - QString fileName = fileNames[i]; - - if (!fileNames.isEmpty()) - { - if (app->openEclipseCaseFromFile(fileName)) - { - addRecentFiles(fileName); - } - } - } - } -} - - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RiuMainWindow::slotImportInputEclipseFiles() -{ - if (checkForDocumentModifications()) - { - RiaApplication* app = RiaApplication::instance(); - QString defaultDir = app->defaultFileDialogDirectory("INPUT_FILES"); - QStringList fileNames = QFileDialog::getOpenFileNames(this, "Import Eclipse Input Files", defaultDir, "Eclipse Input Files and Input Properties (*.GRDECL *)"); - - if (fileNames.isEmpty()) return; - - // Remember the path to next time - app->setDefaultFileDialogDirectory("INPUT_FILES", QFileInfo(fileNames.last()).absolutePath()); - - app->openInputEclipseCaseFromFileNames(fileNames); - } -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -949,24 +973,6 @@ void RiuMainWindow::slotOpenLastUsedProject() } } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RiuMainWindow::slotImportWellPathsFromFile() -{ - // Open dialog box to select well path files - RiaApplication* app = RiaApplication::instance(); - QString defaultDir = app->defaultFileDialogDirectory("WELLPATH_DIR"); - QStringList wellPathFilePaths = QFileDialog::getOpenFileNames(this, "Import Well Paths", defaultDir, "Well Paths (*.json *.asc *.asci *.ascii *.dev);;All Files (*.*)"); - - if (wellPathFilePaths.size() < 1) return; - - // Remember the path to next time - app->setDefaultFileDialogDirectory("WELLPATH_DIR", QFileInfo(wellPathFilePaths.last()).absolutePath()); - - app->addWellPathsToModel(wellPathFilePaths); - if (app->project()) app->project()->createDisplayModelAndRedrawAllViews(); -} //-------------------------------------------------------------------------------------------------- /// @@ -1014,16 +1020,6 @@ void RiuMainWindow::slotInputMockModel() app->createInputMockModel(); } - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RiuMainWindow::slotSetCurrentFrame(int frameIndex) -{ - RiaApplication* app = RiaApplication::instance(); - // app->setTimeStep(frameIndex); -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -1060,7 +1056,7 @@ bool RiuMainWindow::checkForDocumentModifications() void RiuMainWindow::slotCloseProject() { RiaApplication* app = RiaApplication::instance(); - bool ret = app->closeProject(true); + app->closeProject(true); } //-------------------------------------------------------------------------------------------------- @@ -1157,13 +1153,13 @@ void RiuMainWindow::removeRecentFiles(const QString& file) /// //-------------------------------------------------------------------------------------------------- -QMdiSubWindow* RiuMainWindow::findMdiSubWindow(RiuViewer* viewer) +QMdiSubWindow* RiuMainWindow::findMdiSubWindow(QWidget* viewer) { QList subws = m_mdiArea->subWindowList(); int i; for (i = 0; i < subws.size(); ++i) { - if (subws[i]->widget() == viewer->layoutWidget()) + if (subws[i]->widget() == viewer) { return subws[i]; } @@ -1172,40 +1168,120 @@ QMdiSubWindow* RiuMainWindow::findMdiSubWindow(RiuViewer* viewer) return NULL; } - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RiuMainWindow::removeViewer(RiuViewer* viewer) +void RiuMainWindow::removeViewer(QWidget* viewer) { -#if 0 - m_CentralFrame->layout()->removeWidget(viewer->layoutWidget()); -#else - m_mdiArea->removeSubWindow( findMdiSubWindow(viewer)); -#endif + m_blockSlotSubWindowActivated = true; + m_mdiArea->removeSubWindow(findMdiSubWindow(viewer)); + m_blockSlotSubWindowActivated = false; + + slotRefreshViewActions(); } + +// Helper class used to trap the close event of an QMdiSubWindow +class RiuMdiSubWindow : public QMdiSubWindow +{ +public: + RiuMdiSubWindow(QWidget* parent = 0, Qt::WindowFlags flags = 0) + : QMdiSubWindow(parent, flags) + { + } + + ~RiuMdiSubWindow() + { + RiuMainWindow::instance()->slotRefreshViewActions(); + } + +protected: + virtual void closeEvent(QCloseEvent* event) + { + QWidget* mainWidget = widget(); + + RiuWellLogPlot* wellLogPlot = dynamic_cast(mainWidget); + if (wellLogPlot) + { + wellLogPlot->ownerPlotDefinition()->windowGeometry = RiuMainWindow::instance()->windowGeometryForWidget(this); + } + else + { + RiuViewer* viewer = mainWidget->findChild(); + if (viewer) + { + viewer->ownerReservoirView()->windowGeometry = RiuMainWindow::instance()->windowGeometryForWidget(this); + } + } + + QMdiSubWindow::closeEvent(event); + } +}; + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RiuMainWindow::addViewer(RiuViewer* viewer) +void RiuMainWindow::addViewer(QWidget* viewer, const std::vector& windowsGeometry) { -#if 0 - m_CentralFrame->layout()->addWidget(viewer->layoutWidget()); -#else - QMdiSubWindow * subWin = m_mdiArea->addSubWindow(viewer->layoutWidget()); - subWin->resize(400, 400); + RiuMdiSubWindow* subWin = new RiuMdiSubWindow(m_mdiArea); + subWin->setAttribute(Qt::WA_DeleteOnClose); // Make sure the contained widget is destroyed when the MDI window is closed + subWin->setWidget(viewer); + + QSize subWindowSize; + QPoint subWindowPos(-1, -1); + bool initialStateMaximized = false; - if (m_mdiArea->subWindowList().size() == 1) + if (windowsGeometry.size() == 5) { - // Show first view maximized - subWin->showMaximized(); + subWindowPos = QPoint(windowsGeometry[0], windowsGeometry[1]); + subWindowSize = QSize(windowsGeometry[2], windowsGeometry[3]); + + if (windowsGeometry[4] > 0) + { + initialStateMaximized = true; + } } else { - subWin->show(); + RiuWellLogPlot* wellLogPlot = dynamic_cast(subWin->widget()); + if (wellLogPlot) + { + subWindowSize = QSize(275, m_mdiArea->height()); + } + else + { + subWindowSize = QSize(400, 400); + + if (m_mdiArea->subWindowList().size() < 1) + { + // Show first 3D view maximized + initialStateMaximized = true; + } + } } -#endif + + if (m_mdiArea->currentSubWindow() && m_mdiArea->currentSubWindow()->isMaximized()) + { + initialStateMaximized = true; + } + + subWin->show(); + + // Move and resize must be done after window is visible + // If not, the position and size of the window is different to specification (Windows 7) + // Might be a Qt bug, must be tested on Linux + if (subWindowPos.x() > -1) + { + subWin->move(subWindowPos); + } + subWin->resize(subWindowSize); + + if (initialStateMaximized) + { + subWin->showMaximized(); + } + + slotRefreshViewActions(); } //-------------------------------------------------------------------------------------------------- @@ -1240,13 +1316,22 @@ void RiuMainWindow::setPdmRoot(caf::PdmObject* pdmRoot) { m_pdmRoot = pdmRoot; - caf::PdmUiTreeItem* treeItemRoot = caf::UiTreeItemBuilderPdm::buildViewItems(NULL, -1, m_pdmRoot); - m_treeModelPdm->setTreeItemRoot(treeItemRoot); + m_projectTreeView->setPdmItem(pdmRoot); + // For debug only : m_projectTreeView->treeView()->expandAll(); + m_projectTreeView->setDragDropInterface(m_dragDropInterface); - if (treeItemRoot && m_treeView->selectionModel()) + for (size_t i = 0; i < additionalProjectViews.size(); i++) { - connect(m_treeView->selectionModel(), SIGNAL(currentChanged ( const QModelIndex & , const QModelIndex & )), SLOT(slotCurrentChanged( const QModelIndex & , const QModelIndex & ))); + if (!additionalProjectViews[i]) continue; + + RiuProjectAndPropertyView* projPropView = dynamic_cast(additionalProjectViews[i]->widget()); + if (projPropView) + { + projPropView->setPdmItem(pdmRoot); + } } + + caf::SelectionManager::instance()->setPdmRootObject(pdmRoot); } //-------------------------------------------------------------------------------------------------- @@ -1331,11 +1416,35 @@ void RiuMainWindow::slotZoomAll() //-------------------------------------------------------------------------------------------------- void RiuMainWindow::slotSubWindowActivated(QMdiSubWindow* subWindow) { + if (!subWindow) return; + if (m_blockSlotSubWindowActivated) return; + RimProject * proj = RiaApplication::instance()->project(); if (!proj) return; - if (!subWindow) return; - // Iterate all cases in each oil field + RiuWellLogPlot* wellLogPlotViewer = dynamic_cast(subWindow->widget()); + + if (wellLogPlotViewer) + { + RimWellLogPlot* wellLogPlot = wellLogPlotViewer->ownerPlotDefinition(); + + if (wellLogPlot != RiaApplication::instance()->activeWellLogPlot()) + { + RiaApplication::instance()->setActiveWellLogPlot(wellLogPlot); + if (wellLogPlot) + { + projectTreeView()->selectAsCurrentItem(wellLogPlot); + } + } + return; + } + + RiaApplication::instance()->setActiveWellLogPlot(NULL); + + // Find the activated 3D view + + RimView* activatedView = NULL; + std::vector allCases; proj->allCases(allCases); @@ -1343,7 +1452,7 @@ void RiuMainWindow::slotSubWindowActivated(QMdiSubWindow* subWindow) { RimCase* reservoirCase = allCases[caseIdx]; if (reservoirCase == NULL) continue; - + std::vector views = reservoirCase->views(); size_t viewIdx; @@ -1356,62 +1465,73 @@ void RiuMainWindow::slotSubWindowActivated(QMdiSubWindow* subWindow) riv->viewer()->layoutWidget() && riv->viewer()->layoutWidget()->parent() == subWindow) { - RimView* previousActiveReservoirView = RiaApplication::instance()->activeReservoirView(); - RiaApplication::instance()->setActiveReservoirView(riv); - if (previousActiveReservoirView && previousActiveReservoirView != riv) - { - QModelIndex previousViewModelIndex = m_treeModelPdm->getModelIndexFromPdmObject(previousActiveReservoirView); - QModelIndex newViewModelIndex = m_treeModelPdm->getModelIndexFromPdmObject(riv); + activatedView = riv; + break; + } + } + } - QModelIndex newSelectionIndex = newViewModelIndex; - QModelIndex currentSelectionIndex = m_treeView->selectionModel()->currentIndex(); + { + RimView* previousActiveReservoirView = RiaApplication::instance()->activeReservoirView(); + RiaApplication::instance()->setActiveReservoirView(activatedView); - if (currentSelectionIndex != newViewModelIndex && - currentSelectionIndex.isValid()) - { - QVector route; // Contains all model indices from current selection up to previous view + if (previousActiveReservoirView != activatedView) + { + QModelIndex newViewModelIndex = m_projectTreeView->findModelIndex(activatedView); + QModelIndex newSelectionIndex = newViewModelIndex; - QModelIndex tmpModelIndex = currentSelectionIndex; + if (previousActiveReservoirView) + { + // Try to select the same entry in the new View, as was selected in the previous - while (tmpModelIndex.isValid() && tmpModelIndex != previousViewModelIndex) - { - // NB! Add model index to front of vector to be able to do a for-loop with correct ordering - route.push_front(tmpModelIndex); + QModelIndex previousViewModelIndex = m_projectTreeView->findModelIndex(previousActiveReservoirView); + QModelIndex currentSelectionIndex = m_projectTreeView->treeView()->selectionModel()->currentIndex(); - tmpModelIndex = tmpModelIndex.parent(); - } + if (currentSelectionIndex != newViewModelIndex && + currentSelectionIndex.isValid()) + { + QVector route; // Contains all model indices from current selection up to previous view - // Traverse model indices from new view index to currently selected item - int i; - for (i = 0; i < route.size(); i++) - { - QModelIndex tmp = route[i]; - if (newSelectionIndex.isValid()) - { - newSelectionIndex = m_treeModelPdm->index(tmp.row(), tmp.column(), newSelectionIndex); - } - } + QModelIndex tmpModelIndex = currentSelectionIndex; + + while (tmpModelIndex.isValid() && tmpModelIndex != previousViewModelIndex) + { + // NB! Add model index to front of vector to be able to do a for-loop with correct ordering + route.push_front(tmpModelIndex); - // Use view model index if anything goes wrong - if (!newSelectionIndex.isValid()) + tmpModelIndex = tmpModelIndex.parent(); + } + + // Traverse model indices from new view index to currently selected item + int i; + for (i = 0; i < route.size(); i++) + { + QModelIndex tmp = route[i]; + if (newSelectionIndex.isValid()) { - newSelectionIndex = newViewModelIndex; + newSelectionIndex = m_projectTreeView->treeView()->model()->index(tmp.row(), tmp.column(), newSelectionIndex); } } - m_treeView->setCurrentIndex(newSelectionIndex); - if (newSelectionIndex != newViewModelIndex) + // Use view model index if anything goes wrong + if (!newSelectionIndex.isValid()) { - m_treeView->setExpanded(newViewModelIndex, true); + newSelectionIndex = newViewModelIndex; } } + } - slotRefreshViewActions(); - refreshAnimationActions(); - refreshDrawStyleActions(); - break; + m_projectTreeView->treeView()->setCurrentIndex(newSelectionIndex); + if (newSelectionIndex != newViewModelIndex) + { + m_projectTreeView->treeView()->setExpanded(newViewModelIndex, true); } + } + + slotRefreshViewActions(); + refreshAnimationActions(); + refreshDrawStyleActions(); } } @@ -1439,27 +1559,31 @@ void RiuMainWindow::slotShowPerformanceInfo(bool enable) void RiuMainWindow::slotEditPreferences() { RiaApplication* app = RiaApplication::instance(); - caf::PdmUiPropertyDialog propertyDialog(this, app->preferences(), "Preferences"); + caf::PdmUiPropertyViewDialog propertyDialog(this, app->preferences(), "Preferences", ""); if (propertyDialog.exec() == QDialog::Accepted) { // Write preferences using QSettings and apply them to the application - app->writeFieldsToApplicationStore(app->preferences()); + caf::PdmSettings::writeFieldsToApplicationStore(app->preferences()); app->applyPreferences(); } else { // Read back currently stored values using QSettings - app->readFieldsFromApplicationStore(app->preferences()); + caf::PdmSettings::readFieldsFromApplicationStore(app->preferences()); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RiuMainWindow::setActiveViewer(RiuViewer* viewer) +void RiuMainWindow::setActiveViewer(QWidget* viewer) { - QMdiSubWindow * swin = findMdiSubWindow(viewer); + m_blockSlotSubWindowActivated = true; + + QMdiSubWindow * swin = findMdiSubWindow(viewer); if (swin) m_mdiArea->setActiveSubWindow(swin); + + m_blockSlotSubWindowActivated = false; } //-------------------------------------------------------------------------------------------------- @@ -1469,7 +1593,8 @@ void RiuMainWindow::slotFramerateChanged(double frameRate) { if (RiaApplication::instance()->activeReservoirView() != NULL) { - RiaApplication::instance()->activeReservoirView()->maximumFrameRate.setValueFromUi(QVariant(frameRate)); + caf::PdmUiFieldHandle* uiFieldHandle = RiaApplication::instance()->activeReservoirView()->maximumFrameRate.uiCapability(); + uiFieldHandle->setValueFromUi(QVariant(frameRate)); } } @@ -1502,103 +1627,121 @@ void RiuMainWindow::slotBuildWindowActions() ++i; } } + + m_windowMenu->addSeparator(); + QAction* cascadeWindowsAction = new QAction("Cascade Windows", this); + connect(cascadeWindowsAction, SIGNAL(triggered()), m_mdiArea, SLOT(cascadeSubWindows())); + + QAction* closeAllSubWindowsAction = new QAction("Close All Windows", this); + connect(closeAllSubWindowsAction, SIGNAL(triggered()), m_mdiArea, SLOT(closeAllSubWindows())); + + m_windowMenu->addAction(caf::CmdFeatureManager::instance()->action("RicTileWindowsFeature")); + m_windowMenu->addAction(cascadeWindowsAction); + m_windowMenu->addAction(closeAllSubWindowsAction); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RiuMainWindow::slotCurrentChanged(const QModelIndex & current, const QModelIndex & previous) +void RiuMainWindow::selectedObjectsChanged() { - RimView* activeReservoirView = RiaApplication::instance()->activeReservoirView(); - QModelIndex activeViewModelIndex = m_treeModelPdm->getModelIndexFromPdmObject(activeReservoirView); + std::vector uiItems; + m_projectTreeView->selectedUiItems(uiItems); - QModelIndex tmp = current; + caf::PdmObjectHandle* firstSelectedObject = NULL; - // Traverse parents until a reservoir view is found - while (tmp.isValid()) + if (uiItems.size() == 1) { - caf::PdmUiTreeItem* treeItem = m_treeModelPdm->getTreeItemFromIndex(tmp); - caf::PdmObject* pdmObject = treeItem->dataObject(); + firstSelectedObject = dynamic_cast(uiItems[0]); + } + m_pdmUiPropertyView->showProperties(firstSelectedObject); + + if (uiItems.size() == 1) + { + // Find the reservoir view or the Plot that the selected item is within + + if (!firstSelectedObject) + { + caf::PdmFieldHandle* selectedField = dynamic_cast(uiItems[0]); + if (selectedField) firstSelectedObject = selectedField->ownerObject(); + } - RimView* rimReservoirView = dynamic_cast(pdmObject); - if (rimReservoirView) + if (!firstSelectedObject) return; + + // First check if we are within a RimView + RimView* selectedReservoirView = dynamic_cast(firstSelectedObject); + if (!selectedReservoirView) { - // If current selection is an item within a different reservoir view than active, - // show new reservoir view and set this as activate view - if (rimReservoirView != activeReservoirView) + firstSelectedObject->firstAnchestorOrThisOfType(selectedReservoirView); + } + + bool isActiveViewChanged = false; + + RimWellLogPlot* selectedWellLogPlot = NULL; + + if (selectedReservoirView) + { + // Set focus in MDI area to this window if it exists + if (selectedReservoirView->viewer()) + { + setActiveViewer(selectedReservoirView->viewer()->layoutWidget()); + } + isActiveViewChanged = true; + } + else // Check if we are winthin a Well Log plot + { + selectedWellLogPlot = dynamic_cast(firstSelectedObject); + if (!selectedWellLogPlot) + { + firstSelectedObject->firstAnchestorOrThisOfType(selectedWellLogPlot); + } + + if (selectedWellLogPlot) { - RiaApplication::instance()->setActiveReservoirView(rimReservoirView); - // Set focus in MDI area to this window if it exists - if (rimReservoirView->viewer()) + if (selectedWellLogPlot->viewer()) { - setActiveViewer(rimReservoirView->viewer()); + setActiveViewer(selectedWellLogPlot->viewer()); + } - m_treeView->setCurrentIndex(current); - refreshDrawStyleActions(); - refreshAnimationActions(); - slotRefreshFileActions(); - slotRefreshEditActions(); - slotRefreshViewActions(); - - // The only way to get to this code is by selection change initiated from the project tree view - // As we are activating an MDI-window, the focus is given to this MDI-window - // Set focus back to the tree view to be able to continue keyboard tree view navigation - m_treeView->setFocus(); + isActiveViewChanged = true; } } - // Traverse parents until a reservoir view is found - tmp = tmp.parent(); + if (isActiveViewChanged) + { + RiaApplication::instance()->setActiveReservoirView(selectedReservoirView); + RiaApplication::instance()->setActiveWellLogPlot(selectedWellLogPlot); + refreshDrawStyleActions(); + refreshAnimationActions(); + slotRefreshFileActions(); + slotRefreshEditActions(); + slotRefreshViewActions(); + + // The only way to get to this code is by selection change initiated from the project tree view + // As we are activating an MDI-window, the focus is given to this MDI-window + // Set focus back to the tree view to be able to continue keyboard tree view navigation + m_projectTreeView->treeView()->setFocus(); + } } } - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RiuMainWindow::slotNewObjectPropertyView() { - if (!m_treeModelPdm) return; - - RimUiTreeView* treeView = NULL; - - { - QDockWidget* dockWidget = new QDockWidget("Additional Project Tree " + QString::number(additionalProjectTrees.size() + 1), this); - dockWidget->setObjectName("dockWidget"); - dockWidget->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea); - - treeView = new RimUiTreeView(dockWidget); - treeView->setSelectionMode(QAbstractItemView::ExtendedSelection); - - // Drag and drop configuration - m_treeView->setDragEnabled(true); - m_treeView->viewport()->setAcceptDrops(true); - m_treeView->setDropIndicatorShown(true); - m_treeView->setDragDropMode(QAbstractItemView::DragDrop); + QDockWidget* dockWidget = new QDockWidget(QString("Additional Project Tree (%1)").arg(additionalProjectViews.size() + 1), this); + dockWidget->setObjectName("dockWidget"); + dockWidget->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea); - dockWidget->setWidget(treeView); - - addDockWidget(Qt::RightDockWidgetArea, dockWidget); - additionalProjectTrees.push_back(dockWidget); - } - - treeView->setModel(m_treeModelPdm); + RiuProjectAndPropertyView* projPropView = new RiuProjectAndPropertyView(dockWidget); + dockWidget->setWidget(projPropView); + projPropView->setPdmItem(m_pdmRoot); + addDockWidget(Qt::RightDockWidgetArea, dockWidget); - { - QDockWidget* dockWidget = new QDockWidget("Additional Property Editor " + QString::number(additionalPropertyEditors.size() + 1), this); - dockWidget->setObjectName("dockWidget"); - dockWidget->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea); - - caf::PdmUiPropertyView* propView = new caf::PdmUiPropertyView(dockWidget); - dockWidget->setWidget(propView); - - addDockWidget(Qt::RightDockWidgetArea, dockWidget); - - connect(treeView, SIGNAL(selectedObjectChanged( caf::PdmObject* )), propView, SLOT(showProperties( caf::PdmObject* ))); - additionalPropertyEditors.push_back(dockWidget); - } + additionalProjectViews.push_back(dockWidget); } //-------------------------------------------------------------------------------------------------- @@ -1650,17 +1793,13 @@ void RiuMainWindow::hideAllDockWindows() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RiuMainWindow::slotOpenMultipleCases() +/*void RiuMainWindow::slotOpenMultipleCases() { #if 1 - RiaApplication* app = RiaApplication::instance(); - RiuMultiCaseImportDialog dialog; - int action = dialog.exec(); - if (action == QDialog::Accepted) - { - QStringList gridFileNames = dialog.eclipseCaseFileNames(); - app->addEclipseCases(gridFileNames); - } + QAction* action = caf::CmdFeatureManager::instance()->action("RicCreateGridCaseGroupFeature"); + CVF_ASSERT(action); + + action->trigger(); #else // Code to fast generate a test project RiaApplication* app = RiaApplication::instance(); @@ -1685,7 +1824,7 @@ void RiuMainWindow::slotOpenMultipleCases() #endif } - +*/ //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -1731,7 +1870,8 @@ void RiuMainWindow::slotToggleFaultLabelsAction(bool showLabels) RimEclipseView* activeRiv = dynamic_cast(RiaApplication::instance()->activeReservoirView()); if (!activeRiv) return; - activeRiv->faultCollection->showFaultLabel.setValueFromUi(showLabels); + caf::PdmUiFieldHandle* uiFieldHandle = activeRiv->faultCollection->showFaultLabel.uiCapability(); + uiFieldHandle->setValueFromUi(showLabels); refreshDrawStyleActions(); } @@ -1800,15 +1940,15 @@ void RiuMainWindow::slotDisableLightingAction(bool disable) //-------------------------------------------------------------------------------------------------- void RiuMainWindow::storeTreeViewState() { - if (m_treeView) + if (m_projectTreeView) { QString treeViewState; - m_treeView->storeTreeViewStateToString(treeViewState); + RimTreeViewStateSerializer::storeTreeViewStateToString(m_projectTreeView->treeView(), treeViewState); - QModelIndex mi = m_treeView->currentIndex(); + QModelIndex mi = m_projectTreeView->treeView()->currentIndex(); QString encodedModelIndexString; - RimUiTreeView::encodeStringFromModelIndex(mi, encodedModelIndexString); + RimTreeViewStateSerializer::encodeStringFromModelIndex(mi, encodedModelIndexString); RiaApplication::instance()->project()->treeViewState = treeViewState; RiaApplication::instance()->project()->currentModelIndexPath = encodedModelIndexString; @@ -1820,20 +1960,20 @@ void RiuMainWindow::storeTreeViewState() //-------------------------------------------------------------------------------------------------- void RiuMainWindow::restoreTreeViewState() { - if (m_treeView) + if (m_projectTreeView) { QString stateString = RiaApplication::instance()->project()->treeViewState; if (!stateString.isEmpty()) { - m_treeView->collapseAll(); - m_treeView->applyTreeViewStateFromString(stateString); + m_projectTreeView->treeView()->collapseAll(); + RimTreeViewStateSerializer::applyTreeViewStateFromString(m_projectTreeView->treeView(), stateString); } QString currentIndexString = RiaApplication::instance()->project()->currentModelIndexPath; if (!currentIndexString.isEmpty()) { - QModelIndex mi = RimUiTreeView::getModelIndexFromString(m_treeView->model(), currentIndexString); - m_treeView->setCurrentIndex(mi); + QModelIndex mi = RimTreeViewStateSerializer::getModelIndexFromString(m_projectTreeView->treeView()->model(), currentIndexString); + m_projectTreeView->treeView()->setCurrentIndex(mi); } } } @@ -1843,15 +1983,7 @@ void RiuMainWindow::restoreTreeViewState() //-------------------------------------------------------------------------------------------------- void RiuMainWindow::setCurrentObjectInTreeView(caf::PdmObject* object) { - if (m_treeView && m_treeModelPdm) - { - QModelIndex mi = m_treeModelPdm->getModelIndexFromPdmObject(object); - - if (mi.isValid()) - { - m_treeView->setCurrentIndex(mi); - } - } + m_projectTreeView->selectAsCurrentItem(object); } //-------------------------------------------------------------------------------------------------- @@ -1861,7 +1993,8 @@ void RiuMainWindow::slotScaleChanged(int scaleValue) { if (RiaApplication::instance()->activeReservoirView()) { - RiaApplication::instance()->activeReservoirView()->scaleZ.setValueFromUi(scaleValue); + caf::PdmUiFieldHandle* uiFieldHandle = RiaApplication::instance()->activeReservoirView()->scaleZ.uiCapability(); + uiFieldHandle->setValueFromUi(scaleValue); } } @@ -1890,80 +2023,7 @@ void RiuMainWindow::updateScaleValue() //-------------------------------------------------------------------------------------------------- void RiuMainWindow::selectedCases(std::vector& cases) { - if (m_treeView && m_treeView->selectionModel()) - { - QModelIndexList selectedModelIndexes = m_treeView->selectionModel()->selectedIndexes(); - - caf::PdmObjectGroup group; - m_treeModelPdm->populateObjectGroupFromModelIndexList(selectedModelIndexes, &group); - - std::vector > typedObjects; - group.objectsByType(&typedObjects); - - for (size_t i = 0; i < typedObjects.size(); i++) - { - cases.push_back(typedObjects[i]); - } - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RiuMainWindow::slotImportWellPathsFromSSIHub() -{ - RiaApplication* app = RiaApplication::instance(); - if (!app->project()) - { - return; - } - - if (!QFile::exists(app->project()->fileName())) - { - return; - } - - // Update the UTM bounding box from the reservoir - app->project()->computeUtmAreaOfInterest(); - - QString wellPathsFolderPath = RimTools::getCacheRootDirectoryPathFromProject(); - wellPathsFolderPath += "_wellpaths"; - QDir::root().mkpath(wellPathsFolderPath); - - RimWellPathImport* copyOfWellPathImport = dynamic_cast(app->project()->wellPathImport->deepCopy()); - RiuWellImportWizard wellImportwizard(app->preferences()->ssihubAddress, wellPathsFolderPath, copyOfWellPathImport, this); - - RimWellPathImport* wellPathObjectToBeDeleted = NULL; - - // Get password/username from application cache - { - QString ssihubUsername = app->cacheDataObject("ssihub_username").toString(); - QString ssihubPassword = app->cacheDataObject("ssihub_password").toString(); - - wellImportwizard.setCredentials(ssihubUsername, ssihubPassword); - } - - if (QDialog::Accepted == wellImportwizard.exec()) - { - QStringList wellPaths = wellImportwizard.absoluteFilePathsToWellPaths(); - if (wellPaths.size() > 0) - { - app->addWellPathsToModel(wellPaths); - app->project()->createDisplayModelAndRedrawAllViews(); - } - - wellPathObjectToBeDeleted = app->project()->wellPathImport; - app->project()->wellPathImport = copyOfWellPathImport; - - app->setCacheDataObject("ssihub_username", wellImportwizard.field("username")); - app->setCacheDataObject("ssihub_password", wellImportwizard.field("password")); - } - else - { - wellPathObjectToBeDeleted = copyOfWellPathImport; - } - - delete wellPathObjectToBeDeleted; + caf::SelectionManager::instance()->objectsByType(&cases); } //-------------------------------------------------------------------------------------------------- @@ -1984,14 +2044,21 @@ void RiuMainWindow::slotCreateCommandObject() RiaApplication* app = RiaApplication::instance(); if (!app->project()) return; - QItemSelectionModel* selectionModel = m_treeView->selectionModel(); - if (selectionModel) + std::vector selectedUiItems; + m_projectTreeView->selectedUiItems(selectedUiItems); + + caf::PdmObjectGroup selectedObjects; + for (size_t i = 0; i < selectedUiItems.size(); ++i) { - QModelIndexList selectedModelIndices = selectionModel->selectedIndexes(); - - caf::PdmObjectGroup selectedObjects; - m_treeModelPdm->populateObjectGroupFromModelIndexList(selectedModelIndices, &selectedObjects); + caf::PdmUiObjectHandle* uiObj = dynamic_cast(selectedUiItems[i]); + if (uiObj) + { + selectedObjects.addObject(uiObj->objectHandle()); + } + } + if (selectedObjects.objects.size()) + { std::vector commandObjects; RimCommandFactory::createCommandObjects(selectedObjects, &commandObjects); @@ -2012,13 +2079,13 @@ void RiuMainWindow::slotShowRegressionTestDialog() RiaRegressionTest regTestConfig; RiaApplication* app = RiaApplication::instance(); - app->readFieldsFromApplicationStore(®TestConfig); + caf::PdmSettings::readFieldsFromApplicationStore(®TestConfig); - caf::PdmUiPropertyDialog regressionTestDialog(this, ®TestConfig, "Regression Test"); + caf::PdmUiPropertyViewDialog regressionTestDialog(this, ®TestConfig, "Regression Test", ""); if (regressionTestDialog.exec() == QDialog::Accepted) { // Write preferences using QSettings and apply them to the application - app->writeFieldsToApplicationStore(®TestConfig); + caf::PdmSettings::writeFieldsToApplicationStore(®TestConfig); QString currentApplicationPath = QDir::currentPath(); @@ -2074,7 +2141,12 @@ void RiuMainWindow::slotAddWellCellsToRangeFilterAction(bool doAdd) { caf::AppEnum rangeAddType; rangeAddType = doAdd ? RimEclipseWellCollection::RANGE_ADD_INDIVIDUAL : RimEclipseWellCollection::RANGE_ADD_NONE; - riv->wellCollection()->wellCellsToRangeFilterMode.setValueFromUi(static_cast(rangeAddType.index())); + + caf::PdmUiFieldHandle* pdmUiFieldHandle = riv->wellCollection()->wellCellsToRangeFilterMode.uiCapability(); + if (pdmUiFieldHandle) + { + pdmUiFieldHandle->setValueFromUi(static_cast(rangeAddType.index())); + } } } @@ -2095,51 +2167,91 @@ void RiuMainWindow::slotOpenUsersGuideInBrowserAction() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RiuMainWindow::appendActionsContextMenuForPdmObject(caf::PdmObject* pdmObject, QMenu* menu) +void RiuMainWindow::setExpanded(const caf::PdmUiItem* uiItem, bool expanded) { - if (!menu) - { - return; - } + + m_projectTreeView->setExpanded(uiItem, expanded); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuMainWindow::customMenuRequested(const QPoint& pos) +{ + QMenu menu; - if (dynamic_cast(pdmObject)) + RiaApplication* app = RiaApplication::instance(); + app->project()->actionsBasedOnSelection(menu); + + // Qt doc: QAbstractScrollArea and its subclasses that map the context menu event to coordinates of the viewport(). + // Since we might get this signal from different treeViews, we need to map the position accordingly. + QObject* senderObj = this->sender(); + QTreeView* treeView = dynamic_cast(senderObj); + if (treeView) { - menu->addAction(m_importWellPathsFromFileAction); - menu->addAction(m_importWellPathsFromSSIHubAction); + QPoint globalPos = treeView->viewport()->mapToGlobal(pos); + menu.exec(globalPos); } - else if (dynamic_cast(pdmObject)) +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RiuMainWindow::windowGeometryForViewer(QWidget* viewer) +{ + QMdiSubWindow* mdiWindow = findMdiSubWindow(viewer); + if (mdiWindow) { - menu->addAction(m_importEclipseCaseAction); - menu->addAction(m_importInputEclipseFileAction); - menu->addAction(m_openMultipleEclipseCasesAction); + return windowGeometryForWidget(mdiWindow); } - else if (dynamic_cast(pdmObject)) + + std::vector geo; + return geo; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RiuMainWindow::windowGeometryForWidget(QWidget* widget) +{ + std::vector geo; + + if (widget) { - #ifdef USE_ODB_API - menu->addAction(m_importGeoMechCaseAction); - #endif + geo.push_back(widget->pos().x()); + geo.push_back(widget->pos().y()); + geo.push_back(widget->size().width()); + geo.push_back(widget->size().height()); + geo.push_back(widget->isMaximized()); } + + return geo; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RiuMainWindow::setExpanded(const caf::PdmObject* pdmObject, bool expanded) +void RiuMainWindow::tileWindows() { - QModelIndex mi = m_treeModelPdm->getModelIndexFromPdmObject(pdmObject); - if (m_treeView && mi.isValid()) + // Based on workaround described here + // https://forum.qt.io/topic/50053/qmdiarea-tilesubwindows-always-places-widgets-in-activationhistoryorder-in-subwindowview-mode + + QMdiSubWindow *a = m_mdiArea->activeSubWindow(); + QList list = m_mdiArea->subWindowList(m_mdiArea->activationOrder()); + for (int i = 0; i < list.count(); i++) { - m_treeView->setExpanded(mi, expanded); + m_mdiArea->setActiveSubWindow(list[i]); } + + m_mdiArea->tileSubWindows(); + m_mdiArea->setActiveSubWindow(a); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RiuMainWindow::forceProjectTreeRepaint() +bool RiuMainWindow::isAnyMdiSubWindowVisible() { - // This is a hack to force the treeview redraw. - // Needed for some reason when changing names and icons in the model - m_treeView->scroll(0,1); - m_treeView->scroll(0,-1); + return m_mdiArea->subWindowList().size() > 0; } + diff --git a/ApplicationCode/UserInterface/RiuMainWindow.h b/ApplicationCode/UserInterface/RiuMainWindow.h index 04bc6ac9cb..a6db88f08b 100644 --- a/ApplicationCode/UserInterface/RiuMainWindow.h +++ b/ApplicationCode/UserInterface/RiuMainWindow.h @@ -20,39 +20,39 @@ #pragma once -#include "cafUiTreeModelPdm.h" - -#include #include +#include #include -class QTreeView; -class QMdiArea; -class QFrame; -class QMdiSubWindow; +class QActionGroup; class QComboBox; +class QFrame; +class QItemSelection; class QLabel; class QLineEdit; -class QItemSelection; -class QActionGroup; +class QMdiArea; +class QMdiSubWindow; class QSpinBox; +class QTreeView; +class QUndoView; -class RiuViewer; -class RiuResultInfoPanel; -class RiuProcessMonitor; -class RimUiTreeModelPdm; -class RimUiTreeView; -class RimEclipseCase; class RimCase; +class RimEclipseCase; +class RiuProcessMonitor; +class RiuResultInfoPanel; +class RiuViewer; +class RiuWellLogPlot; namespace caf { - class UiPropertyCreatorPdm; - class UiTreeModelPdm; - class PdmObject; - class FrameAnimationControl; + class PdmUiTreeView; class AnimationToolBar; + class FrameAnimationControl; + class PdmObject; class PdmUiPropertyView; + class UiPropertyCreatorPdm; + class PdmUiItem; + class PdmUiDragDropInterface; } namespace ssihub @@ -73,25 +73,24 @@ class RiuMainWindow : public QMainWindow RiuMainWindow(); static RiuMainWindow* instance(); - void initializeGuiNewProjectLoaded(); - void cleanupGuiBeforeProjectClose(); + void initializeGuiNewProjectLoaded(); + void cleanupGuiBeforeProjectClose(); - void removeViewer( RiuViewer* viewer ); - void addViewer(RiuViewer* viewer); - void setActiveViewer(RiuViewer* subWindow); + void removeViewer( QWidget* viewer ); + void addViewer(QWidget* viewer, const std::vector& windowsGeometry); + void setActiveViewer(QWidget* subWindow); void setResultInfo(const QString& info) const; void refreshAnimationActions(); void updateScaleValue(); - void forceProjectTreeRepaint(); - - RimUiTreeModelPdm* uiPdmModel() { return m_treeModelPdm;} + caf::PdmUiTreeView* projectTreeView() { return m_projectTreeView;} RiuProcessMonitor* processMonitor(); void hideAllDockWindows(); - void loadWinGeoAndDockToolBarLayout(); + void loadWinGeoAndDockToolBarLayout(); + void showWindow(); void setCurrentObjectInTreeView(caf::PdmObject* object); @@ -99,28 +98,33 @@ class RiuMainWindow : public QMainWindow void setDefaultWindowSize(); - void appendActionsContextMenuForPdmObject(caf::PdmObject* pdmObject, QMenu* menu); void refreshDrawStyleActions(); - void setExpanded(const caf::PdmObject* pdmObject, bool expanded); + void setExpanded(const caf::PdmUiItem* uiItem, bool expanded); + + void addRecentFiles(const QString& file); + void removeRecentFiles(const QString& file); + + std::vector windowGeometryForViewer(QWidget* viewer); + std::vector windowGeometryForWidget(QWidget* widget); + + void tileWindows(); + bool isAnyMdiSubWindowVisible(); + QMdiSubWindow* findMdiSubWindow(QWidget* viewer); protected: - virtual void closeEvent(QCloseEvent* event); + virtual void closeEvent(QCloseEvent* event); private: void createActions(); void createMenus(); void createToolBars(); void createDockPanels(); - void saveWinGeoAndDockToolBarLayout(); + void saveWinGeoAndDockToolBarLayout(); bool checkForDocumentModifications(); void updateRecentFileActions(); - void addRecentFiles(const QString& file); - void removeRecentFiles(const QString& file); - - QMdiSubWindow* findMdiSubWindow(RiuViewer* viewer); void storeTreeViewState(); void restoreTreeViewState(); @@ -128,22 +132,17 @@ class RiuMainWindow : public QMainWindow private: static RiuMainWindow* sm_mainWindowInstance; - QByteArray m_initialDockAndToolbarLayout; // Initial dock window and toolbar layout, used to reset GUI + QByteArray m_initialDockAndToolbarLayout; // Initial dock window and toolbar layout, used to reset GUI private: // File actions - QAction* m_importEclipseCaseAction; - QAction* m_importInputEclipseFileAction; QAction* m_importGeoMechCaseAction; - QAction* m_openMultipleEclipseCasesAction; - QAction* m_openProjectAction; - QAction* m_openLastUsedProjectAction; - QAction* m_importWellPathsFromFileAction; - QAction* m_importWellPathsFromSSIHubAction; - QAction* m_saveProjectAction; - QAction* m_saveProjectAsAction; + QAction* m_openProjectAction; + QAction* m_openLastUsedProjectAction; + QAction* m_saveProjectAction; + QAction* m_saveProjectAsAction; QAction* m_closeProjectAction; - QAction* m_exitAction; + QAction* m_exitAction; // Recent files enum { MaxRecentFiles = 5 }; @@ -153,28 +152,28 @@ class RiuMainWindow : public QMainWindow // Edit actions - QAction* m_editPreferences; - QAction* m_newPropertyView; + QAction* m_editPreferences; + QAction* m_newPropertyView; // View actions - QAction* m_viewFromNorth; - QAction* m_viewFromSouth; - QAction* m_viewFromEast; - QAction* m_viewFromWest; - QAction* m_viewFromAbove; - QAction* m_viewFromBelow; - QAction* m_zoomAll; + QAction* m_viewFromNorth; + QAction* m_viewFromSouth; + QAction* m_viewFromEast; + QAction* m_viewFromWest; + QAction* m_viewFromAbove; + QAction* m_viewFromBelow; + QAction* m_zoomAll; // Mock actions - QAction* m_mockModelAction; - QAction* m_mockResultsModelAction; - QAction* m_mockLargeResultsModelAction; - QAction* m_mockModelCustomizedAction; - QAction* m_mockInputModelAction; + QAction* m_mockModelAction; + QAction* m_mockResultsModelAction; + QAction* m_mockLargeResultsModelAction; + QAction* m_mockModelCustomizedAction; + QAction* m_mockInputModelAction; - QAction* m_snapshotToFile; - QAction* m_snapshotToClipboard; - QAction* m_snapshotAllViewsToFile; + QAction* m_snapshotToFile; + QAction* m_snapshotToClipboard; + QAction* m_snapshotAllViewsToFile; QAction* m_createCommandObject; QAction* m_showRegressionTestDialog; @@ -194,11 +193,10 @@ class RiuMainWindow : public QMainWindow QToolBar* m_snapshotToolbar; - QFrame* m_CentralFrame; QMdiArea* m_mdiArea; - RiuViewer* m_mainViewer; - RiuResultInfoPanel* m_resultInfoPanel; - RiuProcessMonitor* m_processMonitor; + RiuViewer* m_mainViewer; + RiuResultInfoPanel* m_resultInfoPanel; + RiuProcessMonitor* m_processMonitor; QMenu* m_windowMenu; @@ -206,15 +204,12 @@ class RiuMainWindow : public QMainWindow // Menu and action slots private slots: + friend class RiuMdiSubWindow; + // File slots - void slotImportEclipseCase(); - void slotImportInputEclipseFiles(); void slotImportGeoMechModel(); - void slotOpenMultipleCases(); void slotOpenProject(); void slotOpenLastUsedProject(); - void slotImportWellPathsFromFile(); - void slotImportWellPathsFromSSIHub(); void slotSaveProject(); void slotSaveProjectAs(); void slotCloseProject(); @@ -275,18 +270,24 @@ private slots: void slotOpenUsersGuideInBrowserAction(); void slotSubWindowActivated(QMdiSubWindow* subWindow); - void slotCurrentChanged(const QModelIndex & current, const QModelIndex & previous); + + void selectedObjectsChanged(); + void customMenuRequested(const QPoint& pos); + // Animation slots - void slotSetCurrentFrame(int frameIndex); void slotFramerateChanged(double frameRate); // Pdm System : public: void setPdmRoot(caf::PdmObject* pdmRoot); private: - RimUiTreeView* m_treeView; - RimUiTreeModelPdm* m_treeModelPdm; + caf::PdmUiTreeView* m_projectTreeView; + + caf::PdmUiDragDropInterface* m_dragDropInterface; + + QUndoView* m_undoView; + caf::PdmObject* m_pdmRoot; caf::PdmUiPropertyView* m_pdmUiPropertyView; @@ -302,6 +303,7 @@ private slots: QAction* m_drawStyleSurfOnlyAction; QAction* m_addWellCellsToRangeFilterAction; - std::vector > additionalProjectTrees; - std::vector > additionalPropertyEditors; + std::vector > additionalProjectViews; + + bool m_blockSlotSubWindowActivated; }; diff --git a/ApplicationCode/UserInterface/RiuProcessMonitor.cpp b/ApplicationCode/UserInterface/RiuProcessMonitor.cpp index 489050a2d5..96f49ca269 100644 --- a/ApplicationCode/UserInterface/RiuProcessMonitor.cpp +++ b/ApplicationCode/UserInterface/RiuProcessMonitor.cpp @@ -16,11 +16,18 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RiaStdInclude.h" +#include "RiaApplication.h" #include "RiuProcessMonitor.h" + #include "cafUiProcess.h" -#include "RiaApplication.h" + +#include +#include +#include +#include +#include +#include //-------------------------------------------------------------------------------------------------- /// diff --git a/ApplicationCode/UserInterface/RiuProjectPropertyView.cpp b/ApplicationCode/UserInterface/RiuProjectPropertyView.cpp new file mode 100644 index 0000000000..9efd302e85 --- /dev/null +++ b/ApplicationCode/UserInterface/RiuProjectPropertyView.cpp @@ -0,0 +1,105 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RiuProjectPropertyView.h" + +#include "RiuMainWindow.h" +#include "RiuTreeViewEventFilter.h" + +#include "cafPdmUiPropertyView.h" +#include "cafPdmUiTreeView.h" + +#include +#include +#include +#include + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RiuProjectAndPropertyView::RiuProjectAndPropertyView(QWidget* parent, Qt::WindowFlags f) + : QWidget(parent, f) +{ + // Tree View + m_projectTreeView = new caf::PdmUiTreeView; + m_projectTreeView->treeView()->setHeaderHidden(true); + m_projectTreeView->treeView()->setSelectionMode(QAbstractItemView::ExtendedSelection); + m_projectTreeView->enableSelectionManagerUpdating(true); + + // Install event filter used to handle key press events + RiuTreeViewEventFilter* treeViewEventFilter = new RiuTreeViewEventFilter(this); + m_projectTreeView->treeView()->installEventFilter(treeViewEventFilter); + + // Drag and drop configuration + m_projectTreeView->treeView()->setDragEnabled(true); + m_projectTreeView->treeView()->viewport()->setAcceptDrops(true); + m_projectTreeView->treeView()->setDropIndicatorShown(true); + m_projectTreeView->treeView()->setDragDropMode(QAbstractItemView::DragDrop); + + m_projectTreeView->treeView()->setContextMenuPolicy(Qt::CustomContextMenu); + connect(m_projectTreeView->treeView(), SIGNAL(customContextMenuRequested(const QPoint&)), RiuMainWindow::instance(), SLOT(customMenuRequested(const QPoint&))); + + // Property view + m_propertyView = new caf::PdmUiPropertyView; + + connect(m_projectTreeView, SIGNAL(selectedObjectChanged(caf::PdmObjectHandle*)), m_propertyView, SLOT(showProperties(caf::PdmObjectHandle*))); + + QWidget* propertyEditorWithHeader = new QWidget; + { + QLabel* propertyHeader = new QLabel; + propertyHeader->setText("Property Editor"); + propertyHeader->setStyleSheet("QLabel { background-color: #CCCCCC }"); + propertyHeader->setFixedHeight(20); + + QVBoxLayout* layout = new QVBoxLayout; + layout->setMargin(0); + layout->addWidget(propertyHeader); + layout->addWidget(m_propertyView); + + propertyEditorWithHeader->setLayout(layout); + propertyEditorWithHeader->setMinimumHeight(150); + } + + QSplitter* splitter = new QSplitter(Qt::Vertical); + splitter->addWidget(m_projectTreeView); + splitter->addWidget(propertyEditorWithHeader); + + QVBoxLayout* layout = new QVBoxLayout; + layout->setMargin(0); + layout->addWidget(splitter); + + setLayout(layout); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuProjectAndPropertyView::setPdmItem(caf::PdmUiItem* object) +{ + m_propertyView->showProperties(NULL); + m_projectTreeView->setPdmItem(object); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuProjectAndPropertyView::showProperties(caf::PdmObjectHandle* object) +{ + m_propertyView->showProperties(object); +} diff --git a/ApplicationCode/UserInterface/RiuProjectPropertyView.h b/ApplicationCode/UserInterface/RiuProjectPropertyView.h new file mode 100644 index 0000000000..eb2b2ea501 --- /dev/null +++ b/ApplicationCode/UserInterface/RiuProjectPropertyView.h @@ -0,0 +1,44 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + + +#include + +namespace caf { + class PdmUiItem; + class PdmUiTreeView; + class PdmUiPropertyView; + class PdmObjectHandle; +} + +//-------------------------------------------------------------------------------------------------- +class RiuProjectAndPropertyView : public QWidget +{ +public: + RiuProjectAndPropertyView(QWidget* parent = 0, Qt::WindowFlags f = 0); + + void setPdmItem(caf::PdmUiItem* object); + void showProperties(caf::PdmObjectHandle* object); + +private: + caf::PdmUiTreeView* m_projectTreeView; + caf::PdmUiPropertyView* m_propertyView; +}; \ No newline at end of file diff --git a/ApplicationCode/UserInterface/RiuResultInfoPanel.cpp b/ApplicationCode/UserInterface/RiuResultInfoPanel.cpp index 9ac0ae118b..b49341938d 100644 --- a/ApplicationCode/UserInterface/RiuResultInfoPanel.cpp +++ b/ApplicationCode/UserInterface/RiuResultInfoPanel.cpp @@ -16,10 +16,12 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RiaStdInclude.h" #include "RiuResultInfoPanel.h" - +#include +#include +#include +#include //================================================================================================== /// @@ -36,16 +38,16 @@ RiuResultInfoPanel::RiuResultInfoPanel(QDockWidget* parent) : QWidget(parent) { - m_textEdit = new QTextEdit(this); - m_textEdit->setReadOnly(true); - m_textEdit->setLineWrapMode(QTextEdit::NoWrap); + m_textEdit = new QTextEdit(this); + m_textEdit->setReadOnly(true); + m_textEdit->setLineWrapMode(QTextEdit::NoWrap); - QVBoxLayout* layout = new QVBoxLayout(); - layout->addWidget(m_textEdit); + QVBoxLayout* layout = new QVBoxLayout(); + layout->addWidget(m_textEdit); layout->setContentsMargins(0, 0, 0, 0); - setLayout(layout); + setLayout(layout); } @@ -56,9 +58,9 @@ void RiuResultInfoPanel::setInfo(const QString& info) { QString tmp(info); - convertStringToHTML(&tmp); + convertStringToHTML(&tmp); - m_textEdit->setText(info); + m_textEdit->setText(info); } @@ -67,8 +69,8 @@ void RiuResultInfoPanel::setInfo(const QString& info) //-------------------------------------------------------------------------------------------------- void RiuResultInfoPanel::convertStringToHTML(QString* str) { - str->replace("\n", "
"); - str->replace(" ", " "); + str->replace("\n", "
"); + str->replace(" ", " "); } diff --git a/ApplicationCode/UserInterface/RiuResultInfoPanel.h b/ApplicationCode/UserInterface/RiuResultInfoPanel.h index 9ee0ba1b24..dad1b39dca 100644 --- a/ApplicationCode/UserInterface/RiuResultInfoPanel.h +++ b/ApplicationCode/UserInterface/RiuResultInfoPanel.h @@ -32,19 +32,19 @@ class QTextEdit; //================================================================================================== class RiuResultInfoPanel : public QWidget { - Q_OBJECT + Q_OBJECT public: - RiuResultInfoPanel(QDockWidget* parent); + RiuResultInfoPanel(QDockWidget* parent); - void setInfo(const QString& info); + void setInfo(const QString& info); - virtual QSize sizeHint () const; + virtual QSize sizeHint () const; private: - static void convertStringToHTML(QString* str); + static void convertStringToHTML(QString* str); private: - QTextEdit* m_textEdit; + QTextEdit* m_textEdit; }; diff --git a/ApplicationCode/UserInterface/RiuResultTextBuilder.cpp b/ApplicationCode/UserInterface/RiuResultTextBuilder.cpp index b798cdc4f9..3b837cd870 100644 --- a/ApplicationCode/UserInterface/RiuResultTextBuilder.cpp +++ b/ApplicationCode/UserInterface/RiuResultTextBuilder.cpp @@ -42,9 +42,9 @@ RiuResultTextBuilder::RiuResultTextBuilder(RimEclipseView* reservoirView, size_t CVF_ASSERT(reservoirView); m_reservoirView = reservoirView; - m_gridIndex = gridIndex; - m_cellIndex = cellIndex; - m_timeStepIndex = timeStepIndex; + m_gridIndex = gridIndex; + m_cellIndex = cellIndex; + m_timeStepIndex = timeStepIndex; m_nncIndex = cvf::UNDEFINED_SIZE_T; m_intersectionPoint = cvf::Vec3d::UNDEFINED; @@ -122,7 +122,7 @@ QString RiuResultTextBuilder::mainResultText() appendDetails(text, wellResultText()); } - return text; + return text; } //-------------------------------------------------------------------------------------------------- @@ -176,22 +176,22 @@ QString RiuResultTextBuilder::topologyText(QString itemSeparator) //-------------------------------------------------------------------------------------------------- QString RiuResultTextBuilder::gridResultDetails() { - QString text; + QString text; - if (m_reservoirView->eclipseCase() && m_reservoirView->eclipseCase()->reservoirData()) - { - RigCaseData* eclipseCaseData = m_reservoirView->eclipseCase()->reservoirData(); - RigGridBase* grid = eclipseCaseData->grid(m_gridIndex); + if (m_reservoirView->eclipseCase() && m_reservoirView->eclipseCase()->reservoirData()) + { + RigCaseData* eclipseCaseData = m_reservoirView->eclipseCase()->reservoirData(); + RigGridBase* grid = eclipseCaseData->grid(m_gridIndex); - this->appendTextFromResultColors(eclipseCaseData, m_gridIndex, m_cellIndex, m_timeStepIndex, m_reservoirView->cellResult(), &text); + this->appendTextFromResultColors(eclipseCaseData, m_gridIndex, m_cellIndex, m_timeStepIndex, m_reservoirView->cellResult(), &text); if (!text.isEmpty()) { text.prepend("-- Grid cell result details --\n"); } - } + } - return text; + return text; } //-------------------------------------------------------------------------------------------------- @@ -199,33 +199,33 @@ QString RiuResultTextBuilder::gridResultDetails() //-------------------------------------------------------------------------------------------------- QString RiuResultTextBuilder::faultResultDetails() { - QString text; + QString text; - if (m_reservoirView->eclipseCase() && m_reservoirView->eclipseCase()->reservoirData()) - { - RigCaseData* eclipseCaseData = m_reservoirView->eclipseCase()->reservoirData(); - RigGridBase* grid = eclipseCaseData->grid(m_gridIndex); - RigMainGrid* mainGrid = grid->mainGrid(); + if (m_reservoirView->eclipseCase() && m_reservoirView->eclipseCase()->reservoirData()) + { + RigCaseData* eclipseCaseData = m_reservoirView->eclipseCase()->reservoirData(); + RigGridBase* grid = eclipseCaseData->grid(m_gridIndex); + RigMainGrid* mainGrid = grid->mainGrid(); - const RigFault* fault = mainGrid->findFaultFromCellIndexAndCellFace(m_cellIndex, m_face); - if (fault) - { + const RigFault* fault = mainGrid->findFaultFromCellIndexAndCellFace(m_cellIndex, m_face); + if (fault) + { text += "-- Fault result details --\n"; text += QString("Fault Name: %1\n").arg(fault->name()); - cvf::StructGridInterface::FaceEnum faceHelper(m_face); - text += "Fault Face : " + faceHelper.text() + "\n"; + cvf::StructGridInterface::FaceEnum faceHelper(m_face); + text += "Fault Face : " + faceHelper.text() + "\n"; - if (m_reservoirView->faultResultSettings()->hasValidCustomResult()) - { - text += "Fault result data:\n"; - this->appendTextFromResultColors(eclipseCaseData, m_gridIndex, m_cellIndex, m_timeStepIndex, m_reservoirView->currentFaultResultColors(), &text); - } - } - } + if (m_reservoirView->faultResultSettings()->hasValidCustomResult()) + { + text += "Fault result data:\n"; + this->appendTextFromResultColors(eclipseCaseData, m_gridIndex, m_cellIndex, m_timeStepIndex, m_reservoirView->currentFaultResultColors(), &text); + } + } + } - return text; + return text; } @@ -236,7 +236,7 @@ QString RiuResultTextBuilder::gridResultText() { QString text = cellResultText(m_reservoirView->cellResult()); - return text; + return text; } @@ -273,7 +273,7 @@ QString RiuResultTextBuilder::faultResultText() //-------------------------------------------------------------------------------------------------- QString RiuResultTextBuilder::nncResultText() { - QString text; + QString text; if (m_nncIndex != cvf::UNDEFINED_SIZE_T) { @@ -308,7 +308,7 @@ QString RiuResultTextBuilder::nncResultText() } } - return text; + return text; } //-------------------------------------------------------------------------------------------------- @@ -316,143 +316,143 @@ QString RiuResultTextBuilder::nncResultText() //-------------------------------------------------------------------------------------------------- void RiuResultTextBuilder::appendTextFromResultColors(RigCaseData* eclipseCase, size_t gridIndex, size_t cellIndex, size_t timeStepIndex, RimEclipseCellColors* resultColors, QString* resultInfoText) { - if (!resultColors) - { - return; - } - - RifReaderInterface::PorosityModelResultType porosityModel = RigCaseCellResultsData::convertFromProjectModelPorosityModel(resultColors->porosityModel()); - if (resultColors->isTernarySaturationSelected()) - { - RimReservoirCellResultsStorage* gridCellResults = resultColors->currentGridCellResults(); - if (gridCellResults) - { - size_t soilScalarSetIndex = gridCellResults->findOrLoadScalarResult(RimDefines::DYNAMIC_NATIVE, "SOIL"); - size_t sgasScalarSetIndex = gridCellResults->findOrLoadScalarResult(RimDefines::DYNAMIC_NATIVE, "SGAS"); - size_t swatScalarSetIndex = gridCellResults->findOrLoadScalarResult(RimDefines::DYNAMIC_NATIVE, "SWAT"); - - cvf::ref dataAccessObjectX = RigResultAccessorFactory::createResultAccessor(eclipseCase, gridIndex, porosityModel, timeStepIndex, soilScalarSetIndex); - cvf::ref dataAccessObjectY = RigResultAccessorFactory::createResultAccessor(eclipseCase, gridIndex, porosityModel, timeStepIndex, sgasScalarSetIndex); - cvf::ref dataAccessObjectZ = RigResultAccessorFactory::createResultAccessor(eclipseCase, gridIndex, porosityModel, timeStepIndex, swatScalarSetIndex); - - double scalarValue = 0.0; - - if (dataAccessObjectX.notNull()) scalarValue = dataAccessObjectX->cellScalar(cellIndex); - else scalarValue = 0.0; - resultInfoText->append(QString("SOIL : %1\n").arg(scalarValue)); - - if (dataAccessObjectY.notNull()) scalarValue = dataAccessObjectY->cellScalar(cellIndex); - else scalarValue = 0.0; - resultInfoText->append(QString("SGAS : %1\n").arg(scalarValue)); - - if (dataAccessObjectZ.notNull()) scalarValue = dataAccessObjectZ->cellScalar(cellIndex); - else scalarValue = 0.0; - resultInfoText->append(QString("SWAT : %1\n").arg(scalarValue)); - } - } - else if (resultColors->hasResult()) - { - RifReaderInterface::PorosityModelResultType porosityModel = RigCaseCellResultsData::convertFromProjectModelPorosityModel(resultColors->porosityModel()); - cvf::ref resultAccessor; - - if (resultColors->hasStaticResult()) - { - if (resultColors->resultVariable().compare(RimDefines::combinedTransmissibilityResultName(), Qt::CaseInsensitive) == 0) - { - cvf::ref transResultAccessor = RigResultAccessorFactory::createResultAccessor(eclipseCase, gridIndex, porosityModel, 0, RimDefines::combinedTransmissibilityResultName()); - { - double scalarValue = transResultAccessor->cellFaceScalar(cellIndex, cvf::StructGridInterface::POS_I); - resultInfoText->append(QString("Tran X : %1\n").arg(scalarValue)); - - scalarValue = transResultAccessor->cellFaceScalar(cellIndex, cvf::StructGridInterface::POS_J); - resultInfoText->append(QString("Tran Y : %1\n").arg(scalarValue)); - - scalarValue = transResultAccessor->cellFaceScalar(cellIndex, cvf::StructGridInterface::POS_K); - resultInfoText->append(QString("Tran Z : %1\n").arg(scalarValue)); - } - } - else if (resultColors->resultVariable().compare(RimDefines::combinedMultResultName(), Qt::CaseInsensitive) == 0) - { - cvf::ref multResultAccessor = RigResultAccessorFactory::createResultAccessor(eclipseCase, gridIndex, porosityModel, 0, RimDefines::combinedMultResultName()); - { - double scalarValue = 0.0; - - scalarValue = multResultAccessor->cellFaceScalar(cellIndex, cvf::StructGridInterface::POS_I); - resultInfoText->append(QString("MULTX : %1\n").arg(scalarValue)); - scalarValue = multResultAccessor->cellFaceScalar(cellIndex, cvf::StructGridInterface::NEG_I); - resultInfoText->append(QString("MULTX- : %1\n").arg(scalarValue)); - - scalarValue = multResultAccessor->cellFaceScalar(cellIndex, cvf::StructGridInterface::POS_J); - resultInfoText->append(QString("MULTY : %1\n").arg(scalarValue)); - scalarValue = multResultAccessor->cellFaceScalar(cellIndex, cvf::StructGridInterface::NEG_J); - resultInfoText->append(QString("MULTY- : %1\n").arg(scalarValue)); - - scalarValue = multResultAccessor->cellFaceScalar(cellIndex, cvf::StructGridInterface::POS_K); - resultInfoText->append(QString("MULTZ : %1\n").arg(scalarValue)); - scalarValue = multResultAccessor->cellFaceScalar(cellIndex, cvf::StructGridInterface::NEG_K); - resultInfoText->append(QString("MULTZ- : %1\n").arg(scalarValue)); - } - } - else if (resultColors->resultVariable().compare(RimDefines::combinedRiTranResultName(), Qt::CaseInsensitive) == 0) - { - cvf::ref transResultAccessor = RigResultAccessorFactory::createResultAccessor(eclipseCase, gridIndex, porosityModel, 0, RimDefines::combinedRiTranResultName()); - { - double scalarValue = transResultAccessor->cellFaceScalar(cellIndex, cvf::StructGridInterface::POS_I); - resultInfoText->append(QString("riTran X : %1\n").arg(scalarValue)); - - scalarValue = transResultAccessor->cellFaceScalar(cellIndex, cvf::StructGridInterface::POS_J); - resultInfoText->append(QString("riTran Y : %1\n").arg(scalarValue)); - - scalarValue = transResultAccessor->cellFaceScalar(cellIndex, cvf::StructGridInterface::POS_K); - resultInfoText->append(QString("riTran Z : %1\n").arg(scalarValue)); - } - } - else if (resultColors->resultVariable().compare(RimDefines::combinedRiMultResultName(), Qt::CaseInsensitive) == 0) - { - cvf::ref resultAccessor = RigResultAccessorFactory::createResultAccessor(eclipseCase, gridIndex, porosityModel, 0, RimDefines::combinedRiMultResultName()); - { - double scalarValue = resultAccessor->cellFaceScalar(cellIndex, cvf::StructGridInterface::POS_I); - resultInfoText->append(QString("riMult X : %1\n").arg(scalarValue)); - - scalarValue = resultAccessor->cellFaceScalar(cellIndex, cvf::StructGridInterface::POS_J); - resultInfoText->append(QString("riMult Y : %1\n").arg(scalarValue)); - - scalarValue = resultAccessor->cellFaceScalar(cellIndex, cvf::StructGridInterface::POS_K); - resultInfoText->append(QString("riMult Z : %1\n").arg(scalarValue)); - } - } - else if (resultColors->resultVariable().compare(RimDefines::combinedRiAreaNormTranResultName(), Qt::CaseInsensitive) == 0) - { - cvf::ref resultAccessor = RigResultAccessorFactory::createResultAccessor(eclipseCase, gridIndex, porosityModel, 0, RimDefines::combinedRiAreaNormTranResultName()); - { - double scalarValue = resultAccessor->cellFaceScalar(cellIndex, cvf::StructGridInterface::POS_I); - resultInfoText->append(QString("riTransByArea X : %1\n").arg(scalarValue)); - - scalarValue = resultAccessor->cellFaceScalar(cellIndex, cvf::StructGridInterface::POS_J); - resultInfoText->append(QString("riTransByArea Y : %1\n").arg(scalarValue)); - - scalarValue = resultAccessor->cellFaceScalar(cellIndex, cvf::StructGridInterface::POS_K); - resultInfoText->append(QString("riTransByArea Z : %1\n").arg(scalarValue)); - } - } - else - { - resultAccessor = RigResultAccessorFactory::createResultAccessor(eclipseCase, gridIndex, porosityModel, 0, resultColors->scalarResultIndex()); - } - } - else - { - resultAccessor = RigResultAccessorFactory::createResultAccessor(eclipseCase, gridIndex, porosityModel, timeStepIndex, resultColors->scalarResultIndex()); - } - - if (resultAccessor.notNull()) - { - double scalarValue = resultAccessor->cellScalar(cellIndex); + if (!resultColors) + { + return; + } + + RifReaderInterface::PorosityModelResultType porosityModel = RigCaseCellResultsData::convertFromProjectModelPorosityModel(resultColors->porosityModel()); + if (resultColors->isTernarySaturationSelected()) + { + RimReservoirCellResultsStorage* gridCellResults = resultColors->currentGridCellResults(); + if (gridCellResults) + { + size_t soilScalarSetIndex = gridCellResults->findOrLoadScalarResult(RimDefines::DYNAMIC_NATIVE, "SOIL"); + size_t sgasScalarSetIndex = gridCellResults->findOrLoadScalarResult(RimDefines::DYNAMIC_NATIVE, "SGAS"); + size_t swatScalarSetIndex = gridCellResults->findOrLoadScalarResult(RimDefines::DYNAMIC_NATIVE, "SWAT"); + + cvf::ref dataAccessObjectX = RigResultAccessorFactory::createResultAccessor(eclipseCase, gridIndex, porosityModel, timeStepIndex, soilScalarSetIndex); + cvf::ref dataAccessObjectY = RigResultAccessorFactory::createResultAccessor(eclipseCase, gridIndex, porosityModel, timeStepIndex, sgasScalarSetIndex); + cvf::ref dataAccessObjectZ = RigResultAccessorFactory::createResultAccessor(eclipseCase, gridIndex, porosityModel, timeStepIndex, swatScalarSetIndex); + + double scalarValue = 0.0; + + if (dataAccessObjectX.notNull()) scalarValue = dataAccessObjectX->cellScalar(cellIndex); + else scalarValue = 0.0; + resultInfoText->append(QString("SOIL : %1\n").arg(scalarValue)); + + if (dataAccessObjectY.notNull()) scalarValue = dataAccessObjectY->cellScalar(cellIndex); + else scalarValue = 0.0; + resultInfoText->append(QString("SGAS : %1\n").arg(scalarValue)); + + if (dataAccessObjectZ.notNull()) scalarValue = dataAccessObjectZ->cellScalar(cellIndex); + else scalarValue = 0.0; + resultInfoText->append(QString("SWAT : %1\n").arg(scalarValue)); + } + } + else if (resultColors->hasResult()) + { + RifReaderInterface::PorosityModelResultType porosityModel = RigCaseCellResultsData::convertFromProjectModelPorosityModel(resultColors->porosityModel()); + cvf::ref resultAccessor; + + if (resultColors->hasStaticResult()) + { + if (resultColors->resultVariable().compare(RimDefines::combinedTransmissibilityResultName(), Qt::CaseInsensitive) == 0) + { + cvf::ref transResultAccessor = RigResultAccessorFactory::createResultAccessor(eclipseCase, gridIndex, porosityModel, 0, RimDefines::combinedTransmissibilityResultName()); + { + double scalarValue = transResultAccessor->cellFaceScalar(cellIndex, cvf::StructGridInterface::POS_I); + resultInfoText->append(QString("Tran X : %1\n").arg(scalarValue)); + + scalarValue = transResultAccessor->cellFaceScalar(cellIndex, cvf::StructGridInterface::POS_J); + resultInfoText->append(QString("Tran Y : %1\n").arg(scalarValue)); + + scalarValue = transResultAccessor->cellFaceScalar(cellIndex, cvf::StructGridInterface::POS_K); + resultInfoText->append(QString("Tran Z : %1\n").arg(scalarValue)); + } + } + else if (resultColors->resultVariable().compare(RimDefines::combinedMultResultName(), Qt::CaseInsensitive) == 0) + { + cvf::ref multResultAccessor = RigResultAccessorFactory::createResultAccessor(eclipseCase, gridIndex, porosityModel, 0, RimDefines::combinedMultResultName()); + { + double scalarValue = 0.0; + + scalarValue = multResultAccessor->cellFaceScalar(cellIndex, cvf::StructGridInterface::POS_I); + resultInfoText->append(QString("MULTX : %1\n").arg(scalarValue)); + scalarValue = multResultAccessor->cellFaceScalar(cellIndex, cvf::StructGridInterface::NEG_I); + resultInfoText->append(QString("MULTX- : %1\n").arg(scalarValue)); + + scalarValue = multResultAccessor->cellFaceScalar(cellIndex, cvf::StructGridInterface::POS_J); + resultInfoText->append(QString("MULTY : %1\n").arg(scalarValue)); + scalarValue = multResultAccessor->cellFaceScalar(cellIndex, cvf::StructGridInterface::NEG_J); + resultInfoText->append(QString("MULTY- : %1\n").arg(scalarValue)); + + scalarValue = multResultAccessor->cellFaceScalar(cellIndex, cvf::StructGridInterface::POS_K); + resultInfoText->append(QString("MULTZ : %1\n").arg(scalarValue)); + scalarValue = multResultAccessor->cellFaceScalar(cellIndex, cvf::StructGridInterface::NEG_K); + resultInfoText->append(QString("MULTZ- : %1\n").arg(scalarValue)); + } + } + else if (resultColors->resultVariable().compare(RimDefines::combinedRiTranResultName(), Qt::CaseInsensitive) == 0) + { + cvf::ref transResultAccessor = RigResultAccessorFactory::createResultAccessor(eclipseCase, gridIndex, porosityModel, 0, RimDefines::combinedRiTranResultName()); + { + double scalarValue = transResultAccessor->cellFaceScalar(cellIndex, cvf::StructGridInterface::POS_I); + resultInfoText->append(QString("riTran X : %1\n").arg(scalarValue)); + + scalarValue = transResultAccessor->cellFaceScalar(cellIndex, cvf::StructGridInterface::POS_J); + resultInfoText->append(QString("riTran Y : %1\n").arg(scalarValue)); + + scalarValue = transResultAccessor->cellFaceScalar(cellIndex, cvf::StructGridInterface::POS_K); + resultInfoText->append(QString("riTran Z : %1\n").arg(scalarValue)); + } + } + else if (resultColors->resultVariable().compare(RimDefines::combinedRiMultResultName(), Qt::CaseInsensitive) == 0) + { + cvf::ref resultAccessor = RigResultAccessorFactory::createResultAccessor(eclipseCase, gridIndex, porosityModel, 0, RimDefines::combinedRiMultResultName()); + { + double scalarValue = resultAccessor->cellFaceScalar(cellIndex, cvf::StructGridInterface::POS_I); + resultInfoText->append(QString("riMult X : %1\n").arg(scalarValue)); + + scalarValue = resultAccessor->cellFaceScalar(cellIndex, cvf::StructGridInterface::POS_J); + resultInfoText->append(QString("riMult Y : %1\n").arg(scalarValue)); + + scalarValue = resultAccessor->cellFaceScalar(cellIndex, cvf::StructGridInterface::POS_K); + resultInfoText->append(QString("riMult Z : %1\n").arg(scalarValue)); + } + } + else if (resultColors->resultVariable().compare(RimDefines::combinedRiAreaNormTranResultName(), Qt::CaseInsensitive) == 0) + { + cvf::ref resultAccessor = RigResultAccessorFactory::createResultAccessor(eclipseCase, gridIndex, porosityModel, 0, RimDefines::combinedRiAreaNormTranResultName()); + { + double scalarValue = resultAccessor->cellFaceScalar(cellIndex, cvf::StructGridInterface::POS_I); + resultInfoText->append(QString("riTransByArea X : %1\n").arg(scalarValue)); + + scalarValue = resultAccessor->cellFaceScalar(cellIndex, cvf::StructGridInterface::POS_J); + resultInfoText->append(QString("riTransByArea Y : %1\n").arg(scalarValue)); + + scalarValue = resultAccessor->cellFaceScalar(cellIndex, cvf::StructGridInterface::POS_K); + resultInfoText->append(QString("riTransByArea Z : %1\n").arg(scalarValue)); + } + } + else + { + resultAccessor = RigResultAccessorFactory::createResultAccessor(eclipseCase, gridIndex, porosityModel, 0, resultColors->scalarResultIndex()); + } + } + else + { + resultAccessor = RigResultAccessorFactory::createResultAccessor(eclipseCase, gridIndex, porosityModel, timeStepIndex, resultColors->scalarResultIndex()); + } + + if (resultAccessor.notNull()) + { + double scalarValue = resultAccessor->cellScalar(cellIndex); resultInfoText->append("Cell result : "); resultInfoText->append(resultColors->resultVariable()); - resultInfoText->append(QString(" : %1\n").arg(scalarValue)); - } - } + resultInfoText->append(QString(" : %1\n").arg(scalarValue)); + } + } } //-------------------------------------------------------------------------------------------------- @@ -460,32 +460,32 @@ void RiuResultTextBuilder::appendTextFromResultColors(RigCaseData* eclipseCase, //-------------------------------------------------------------------------------------------------- QString RiuResultTextBuilder::cellEdgeResultDetails() { - QString text; - - if (m_reservoirView->cellEdgeResult()->hasResult()) - { - size_t resultIndices[6]; - QStringList resultNames; - m_reservoirView->cellEdgeResult()->gridScalarIndices(resultIndices); - m_reservoirView->cellEdgeResult()->gridScalarResultNames(&resultNames); - - text += "-- Cell edge result data --\n"; - for (int idx = 0; idx < 6; idx++) - { - if (resultIndices[idx] == cvf::UNDEFINED_SIZE_T) continue; - - // Cell edge results are static, results are loaded for first time step only - RifReaderInterface::PorosityModelResultType porosityModel = RigCaseCellResultsData::convertFromProjectModelPorosityModel(m_reservoirView->cellResult()->porosityModel()); - cvf::ref resultAccessor = RigResultAccessorFactory::createResultAccessor(m_reservoirView->eclipseCase()->reservoirData(), m_gridIndex, porosityModel, 0, resultIndices[idx]); - if (resultAccessor.notNull()) - { - double scalarValue = resultAccessor->cellScalar(m_cellIndex); - text.append(QString("%1 : %2\n").arg(resultNames[idx]).arg(scalarValue)); - } - } - } - - return text; + QString text; + + if (m_reservoirView->cellEdgeResult()->hasResult()) + { + size_t resultIndices[6]; + QStringList resultNames; + m_reservoirView->cellEdgeResult()->gridScalarIndices(resultIndices); + m_reservoirView->cellEdgeResult()->gridScalarResultNames(&resultNames); + + text += "-- Cell edge result data --\n"; + for (int idx = 0; idx < 6; idx++) + { + if (resultIndices[idx] == cvf::UNDEFINED_SIZE_T) continue; + + // Cell edge results are static, results are loaded for first time step only + RifReaderInterface::PorosityModelResultType porosityModel = RigCaseCellResultsData::convertFromProjectModelPorosityModel(m_reservoirView->cellResult()->porosityModel()); + cvf::ref resultAccessor = RigResultAccessorFactory::createResultAccessor(m_reservoirView->eclipseCase()->reservoirData(), m_gridIndex, porosityModel, 0, resultIndices[idx]); + if (resultAccessor.notNull()) + { + double scalarValue = resultAccessor->cellScalar(m_cellIndex); + text.append(QString("%1 : %2\n").arg(resultNames[idx]).arg(scalarValue)); + } + } + } + + return text; } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/UserInterface/RiuResultTextBuilder.h b/ApplicationCode/UserInterface/RiuResultTextBuilder.h index c02beeddd6..25f1b6a7cf 100644 --- a/ApplicationCode/UserInterface/RiuResultTextBuilder.h +++ b/ApplicationCode/UserInterface/RiuResultTextBuilder.h @@ -30,7 +30,7 @@ class QString; class RigCaseData; namespace cvf { - class Part; + class Part; } //================================================================================================== @@ -40,15 +40,15 @@ namespace cvf { class RiuResultTextBuilder { public: - RiuResultTextBuilder(RimEclipseView* reservoirView, size_t gridIndex, size_t cellIndex, size_t timeStepIndex); + RiuResultTextBuilder(RimEclipseView* reservoirView, size_t gridIndex, size_t cellIndex, size_t timeStepIndex); void setFace(cvf::StructGridInterface::FaceType face); void setNncIndex(size_t nncIndex); void setIntersectionPoint(cvf::Vec3d intersectionPoint); QString mainResultText(); - QString topologyText(QString itemSeparator); - + QString topologyText(QString itemSeparator); + private: void appendDetails(QString& text, const QString& details); @@ -64,18 +64,18 @@ class RiuResultTextBuilder QString cellResultText(RimEclipseCellColors* resultColors); - void appendTextFromResultColors(RigCaseData* eclipseCase, size_t gridIndex, size_t cellIndex, size_t timeStepIndex, RimEclipseCellColors* resultColors, QString* resultInfoText); + void appendTextFromResultColors(RigCaseData* eclipseCase, size_t gridIndex, size_t cellIndex, size_t timeStepIndex, RimEclipseCellColors* resultColors, QString* resultInfoText); private: caf::PdmPointer m_reservoirView; - size_t m_gridIndex; - size_t m_cellIndex; - size_t m_timeStepIndex; + size_t m_gridIndex; + size_t m_cellIndex; + size_t m_timeStepIndex; - cvf::StructGridInterface::FaceType m_face; + cvf::StructGridInterface::FaceType m_face; size_t m_nncIndex; - cvf::Vec3d m_intersectionPoint; + cvf::Vec3d m_intersectionPoint; }; diff --git a/ApplicationCode/UserInterface/RiuRmsNavigation.cpp b/ApplicationCode/UserInterface/RiuRmsNavigation.cpp index 74b7db7c60..70afb005b4 100644 --- a/ApplicationCode/UserInterface/RiuRmsNavigation.cpp +++ b/ApplicationCode/UserInterface/RiuRmsNavigation.cpp @@ -158,7 +158,7 @@ bool RiuRmsNavigation::handleInputEvent(QInputEvent* inputEvent) bool needRedraw = m_trackball->updateNavigation(translatedMousePosX, translatedMousePosY); if (needRedraw) { - m_viewer->update(); + m_viewer->navigationPolicyUpdate(); } } isEventHandled = true; @@ -269,6 +269,6 @@ void RiuRmsNavigation::zoomAlongRay(cvf::Ray* ray, int delta) cvf::Vec3d newVrp = vrp + trans; m_viewer->mainCamera()->setFromLookAt(newPos, newVrp, up ); - m_viewer->update(); + m_viewer->navigationPolicyUpdate(); } } diff --git a/ApplicationCode/UserInterface/RiuTreeViewEventFilter.cpp b/ApplicationCode/UserInterface/RiuTreeViewEventFilter.cpp new file mode 100644 index 0000000000..5b33d7662e --- /dev/null +++ b/ApplicationCode/UserInterface/RiuTreeViewEventFilter.cpp @@ -0,0 +1,122 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RiuTreeViewEventFilter.h" + +#include "ToggleCommands/RicToggleItemsFeatureImpl.h" + +#include "RimCaseCollection.h" +#include "RimEclipseCase.h" +#include "RimGeoMechCase.h" +#include "RimGeoMechView.h" +#include "RimIdenticalGridCaseGroup.h" +#include "RiuMainWindow.h" + +#include "cafCmdFeatureManager.h" +#include "cafPdmUiTreeView.h" +#include "cafSelectionManager.h" + +#include +#include +#include + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RiuTreeViewEventFilter::RiuTreeViewEventFilter(QObject* parent) + : QObject(parent) +{ +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RiuTreeViewEventFilter::eventFilter(QObject *obj, QEvent *event) +{ + if (event->type() == QEvent::KeyPress) + { + QKeyEvent* keyEvent = static_cast(event); + + QString featureToActivate; + + caf::PdmUiItem* uiItem = caf::SelectionManager::instance()->selectedItem(); + if (uiItem) + { + if (dynamic_cast(uiItem) + || dynamic_cast(uiItem) + || dynamic_cast(uiItem) + || dynamic_cast(uiItem)) + { + if (keyEvent->matches(QKeySequence::Copy)) + { + featureToActivate = "RicCopyReferencesToClipboardFeature"; + } + } + + if (keyEvent->matches(QKeySequence::Paste)) + { + if (dynamic_cast(uiItem) + || dynamic_cast(uiItem)) + { + featureToActivate = "RicPasteEclipseCasesFeature"; + } + else if (dynamic_cast(uiItem) + || dynamic_cast(uiItem)) + { + featureToActivate = "RicPasteEclipseViewsFeature"; + } + else if (dynamic_cast(uiItem) + || dynamic_cast(uiItem)) + { + featureToActivate = "RicPasteGeoMechViewsFeature"; + } + } + } + + if (!featureToActivate.isEmpty()) + { + QAction* actionToTrigger = caf::CmdFeatureManager::instance()->action(featureToActivate); + assert(actionToTrigger); + + actionToTrigger->trigger(); + + keyEvent->setAccepted(true); + return true; + } + + switch (keyEvent->key()) + { + case Qt::Key_Space: + case Qt::Key_Enter: + case Qt::Key_Return: + case Qt::Key_Select: + { + RicToggleItemsFeatureImpl::setObjectToggleStateForSelection(RicToggleItemsFeatureImpl::TOGGLE); + + keyEvent->setAccepted(true); + return true; + } + } + } + + // standard event processing + return QObject::eventFilter(obj, event); +} + diff --git a/ApplicationCode/UserInterface/RiuTreeViewEventFilter.h b/ApplicationCode/UserInterface/RiuTreeViewEventFilter.h new file mode 100644 index 0000000000..fd065b8018 --- /dev/null +++ b/ApplicationCode/UserInterface/RiuTreeViewEventFilter.h @@ -0,0 +1,36 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + + +#include + +class QEvent; + +//-------------------------------------------------------------------------------------------------- +class RiuTreeViewEventFilter : public QObject +{ + Q_OBJECT +public: + RiuTreeViewEventFilter(QObject* parent); + +protected: + bool eventFilter(QObject *obj, QEvent *event); +}; \ No newline at end of file diff --git a/ApplicationCode/UserInterface/RiuViewer.cpp b/ApplicationCode/UserInterface/RiuViewer.cpp index 68ea3b4a1f..73d8aa347e 100644 --- a/ApplicationCode/UserInterface/RiuViewer.cpp +++ b/ApplicationCode/UserInterface/RiuViewer.cpp @@ -18,54 +18,35 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RiaStdInclude.h" - #include "RiuViewer.h" -#include "RiuViewerCommands.h" #include "RiaApplication.h" -#include "RiuMainWindow.h" +#include "RiaBaseDefs.h" + +#include "RimProject.h" +#include "RimView.h" +#include "RimViewController.h" +#include "RimViewLinker.h" -#include "cafCeetronPlusNavigation.h" #include "RiuCadNavigation.h" -#include "RiuRmsNavigation.h" #include "RiuGeoQuestNavigation.h" - -#include "RimEclipseView.h" - -#include "Rim3dOverlayInfoConfig.h" -#include "RimEclipseCase.h" -#include "RimCellEdgeColors.h" -#include "RimEclipsePropertyFilterCollection.h" -#include "RimCellRangeFilterCollection.h" -#include "RimFaultCollection.h" -#include "RimEclipseCellColors.h" -#include "RimEclipseWellCollection.h" - -#include "RimUiTreeModelPdm.h" - -#include "RimReservoirCellResultsStorage.h" - -#include "RigCaseData.h" - +#include "RiuRmsNavigation.h" #include "RiuSimpleHistogramWidget.h" +#include "RiuViewerCommands.h" -#include "cafNavigationPolicy.h" +#include "cafCeetronPlusNavigation.h" #include "cafEffectGenerator.h" - -#include "cafPdmFieldCvfColor.h" -#include "cafPdmFieldCvfMat4d.h" -#include "RivSourceInfo.h" -#include "RivFemPickSourceInfo.h" - -#include "RiuResultTextBuilder.h" -#include "RivFemPartGeometryGenerator.h" -#include "RimGeoMechView.h" -#include "RimGeoMechCase.h" -#include "RigGeoMechCaseData.h" -#include "RigFemPartCollection.h" -#include "RigFemPart.h" -#include "RigFemPartGrid.h" +#include "cvfCamera.h" +#include "cvfFont.h" +#include "cvfOverlayAxisCross.h" +#include "cvfRenderSequence.h" +#include "cvfRendering.h" +#include "cvfScene.h" + +#include +#include +#include +#include using cvf::ManipulatorTrackball; @@ -81,7 +62,6 @@ const double RI_MIN_NEARPLANE_DISTANCE = 0.1; /// //================================================================================================== -#include "RiaBaseDefs.h" //-------------------------------------------------------------------------------------------------- /// @@ -172,6 +152,12 @@ RiuViewer::RiuViewer(const QGLFormat& format, QWidget* parent) m_animationProgress->setFont(regTestFont); m_histogramWidget->setFont(regTestFont); } + + // When a context menu is created in the viewer is, and the action triggered is displaying a dialog, + // the context menu of QMainWindow is displayed after the action has finished + // Setting this policy will make sure the handling is not deferred to the widget's parent, + // which solves the problem + setContextMenuPolicy(Qt::PreventContextMenu); } @@ -183,6 +169,8 @@ RiuViewer::~RiuViewer() if (m_reservoirView) { m_reservoirView->showWindow = false; + m_reservoirView->uiCapability()->updateUiIconFromToggleField(); + m_reservoirView->cameraPosition = m_mainCamera->viewMatrix(); } delete m_InfoLabel; @@ -274,12 +262,16 @@ void RiuViewer::slotEndAnimation() //-------------------------------------------------------------------------------------------------- void RiuViewer::slotSetCurrentFrame(int frameIndex) { - cvf::Rendering* firstRendering = m_renderingSequence->firstRendering(); - CVF_ASSERT(firstRendering); + setCurrentFrame(frameIndex); - if (m_reservoirView) m_reservoirView->setCurrentTimeStep(frameIndex); - - caf::Viewer::slotSetCurrentFrame(frameIndex); + if (m_reservoirView) + { + RimViewLinker* viewLinker = m_reservoirView->assosiatedViewLinker(); + if (viewLinker) + { + viewLinker->updateTimeStep(m_reservoirView, frameIndex); + } + } } //-------------------------------------------------------------------------------------------------- @@ -491,3 +483,41 @@ void RiuViewer::updateNavigationPolicy() break; } } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuViewer::navigationPolicyUpdate() +{ + caf::Viewer::navigationPolicyUpdate(); + + if (m_reservoirView) + { + RimViewLinker* viewLinker = m_reservoirView->assosiatedViewLinker(); + if (viewLinker) + { + viewLinker->updateCamera(m_reservoirView); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuViewer::setCurrentFrame(int frameIndex) +{ + cvf::Rendering* firstRendering = m_renderingSequence->firstRendering(); + CVF_ASSERT(firstRendering); + + if (m_reservoirView) m_reservoirView->setCurrentTimeStep(frameIndex); + + caf::Viewer::slotSetCurrentFrame(frameIndex); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimView* RiuViewer::ownerReservoirView() +{ + return m_reservoirView; +} diff --git a/ApplicationCode/UserInterface/RiuViewer.h b/ApplicationCode/UserInterface/RiuViewer.h index 4374af1d8d..bdfe58dc98 100644 --- a/ApplicationCode/UserInterface/RiuViewer.h +++ b/ApplicationCode/UserInterface/RiuViewer.h @@ -58,6 +58,7 @@ class RiuViewer : public caf::Viewer cvf::Vec3d pointOfInterest(); void setPointOfInterest(cvf::Vec3d poi); void setOwnerReservoirView(RimView * owner); + RimView* ownerReservoirView(); void setEnableMask(unsigned int mask); void showInfoText(bool enable); @@ -72,7 +73,11 @@ class RiuViewer : public caf::Viewer void addColorLegendToBottomLeftCorner(cvf::OverlayItem* legend); void updateNavigationPolicy(); - + + virtual void navigationPolicyUpdate(); // Override of caf::Viewer::navigationPolicyUpdate() + + void setCurrentFrame(int frameIndex); + public slots: virtual void slotSetCurrentFrame(int frameIndex); virtual void slotEndAnimation(); @@ -83,6 +88,7 @@ public slots: void mouseReleaseEvent(QMouseEvent* event); void mousePressEvent(QMouseEvent* event); + QLabel* m_InfoLabel; QLabel* m_versionInfoLabel; bool m_showInfoText;; diff --git a/ApplicationCode/UserInterface/RiuViewerCommands.cpp b/ApplicationCode/UserInterface/RiuViewerCommands.cpp index e12a06f719..6a9735e731 100644 --- a/ApplicationCode/UserInterface/RiuViewerCommands.cpp +++ b/ApplicationCode/UserInterface/RiuViewerCommands.cpp @@ -18,44 +18,62 @@ ///////////////////////////////////////////////////////////////////////////////// #include "RiuViewerCommands.h" -#include "RiuViewer.h" -#include "RimUiTreeModelPdm.h" + +#include "RicEclipsePropertyFilterNewExec.h" +#include "RicGeoMechPropertyFilterNewExec.h" +#include "RicRangeFilterNewExec.h" +#include "Commands/WellLogCommands/RicNewWellLogFileCurveFeature.h" +#include "Commands/WellLogCommands/RicNewWellLogCurveExtractionFeature.h" + +#include "RigCaseData.h" +#include "RigFemPartCollection.h" +#include "RigFemPartGrid.h" +#include "RigGeoMechCaseData.h" + #include "RimCellRangeFilter.h" -#include "RimView.h" #include "RimCellRangeFilterCollection.h" #include "RimEclipseCase.h" -#include "RimEclipseView.h" -#include "RimGeoMechView.h" -#include "RimFaultCollection.h" #include "RimEclipseCellColors.h" #include "RimEclipsePropertyFilter.h" #include "RimEclipsePropertyFilterCollection.h" -#include "RimGeoMechView.h" +#include "RimEclipseView.h" +#include "RimFaultCollection.h" +#include "RimGeoMechCase.h" +#include "RimGeoMechCellColors.h" #include "RimGeoMechPropertyFilter.h" #include "RimGeoMechPropertyFilterCollection.h" -#include "RimGeoMechCellColors.h" +#include "RimGeoMechView.h" +#include "RimGeoMechView.h" +#include "RimOilField.h" +#include "RimProject.h" +#include "RimView.h" +#include "RimViewController.h" +#include "RimWellPath.h" +#include "RimWellPathCollection.h" +#include "RimWellLogFile.h" -#include "RivSourceInfo.h" -#include "RivFemPickSourceInfo.h" -#include "RivFemPartGeometryGenerator.h" -#include "RigCaseData.h" +#include "RiuFemResultTextBuilder.h" #include "RiuMainWindow.h" -#include "RiaApplication.h" #include "RiuResultTextBuilder.h" -#include "RigGeoMechCaseData.h" -#include "RimGeoMechCase.h" -#include "RigFemPartCollection.h" -#include "RigFemPartGrid.h" +#include "RiuViewer.h" + +#include "RivFemPartGeometryGenerator.h" +#include "RivFemPickSourceInfo.h" +#include "RivSourceInfo.h" +#include "RivWellPathSourceInfo.h" + +#include "cafCmdExecCommandManager.h" +#include "cafCmdFeature.h" +#include "cafCmdFeatureManager.h" +#include "cafPdmUiTreeView.h" #include "cvfDrawableGeo.h" -#include "cvfPart.h" #include "cvfHitItemCollection.h" +#include "cvfPart.h" #include #include - #include -#include "RiuFemResultTextBuilder.h" //================================================================================================== // @@ -99,6 +117,8 @@ void RiuViewerCommands::displayContextMenu(QMouseEvent* event) int winPosX = event->x(); int winPosY = event->y(); + QMenu menu; + uint faceIndex = cvf::UNDEFINED_UINT; cvf::Vec3d localIntersectionPoint(cvf::Vec3d::ZERO); @@ -110,75 +130,157 @@ void RiuViewerCommands::displayContextMenu(QMouseEvent* event) if (m_viewer->rayPick(winPosX, winPosY, &hitItems)) { extractIntersectionData(hitItems, &localIntersectionPoint, &firstHitPart, &faceIndex, &nncFirstHitPart, NULL); + updateSelectionFromPickedPart(firstHitPart); } - if (!firstHitPart) return; - - if (faceIndex == cvf::UNDEFINED_UINT) return; + if (firstHitPart && faceIndex != cvf::UNDEFINED_UINT) + { + const RivSourceInfo* rivSourceInfo = dynamic_cast(firstHitPart->sourceInfo()); + const RivFemPickSourceInfo* femSourceInfo = dynamic_cast(firstHitPart->sourceInfo()); - if (!firstHitPart->sourceInfo()) return; - - const RivSourceInfo* rivSourceInfo = dynamic_cast(firstHitPart->sourceInfo()); - const RivFemPickSourceInfo* femSourceInfo = dynamic_cast(firstHitPart->sourceInfo()); + if (rivSourceInfo || femSourceInfo) + { + if (rivSourceInfo) + { + if (!rivSourceInfo->hasCellFaceMapping()) return; - if (!(rivSourceInfo || femSourceInfo) ) return; - - if (rivSourceInfo) - { - if (!rivSourceInfo->hasCellFaceMapping()) return; + // Set the data regarding what was hit - // Set the data regarding what was hit + m_currentGridIdx = rivSourceInfo->gridIndex(); + m_currentCellIndex = rivSourceInfo->m_cellFaceFromTriangleMapper->cellIndex(faceIndex); + m_currentFaceIndex = rivSourceInfo->m_cellFaceFromTriangleMapper->cellFace(faceIndex); + } + else + { + m_currentGridIdx = femSourceInfo->femPartIndex(); + m_currentCellIndex = femSourceInfo->triangleToElmMapper()->elementIndex(faceIndex); + } - m_currentGridIdx = rivSourceInfo->gridIndex(); - m_currentCellIndex = rivSourceInfo->m_cellFaceFromTriangleMapper->cellIndex(faceIndex); - m_currentFaceIndex = rivSourceInfo->m_cellFaceFromTriangleMapper->cellFace(faceIndex); - } - else - { - m_currentGridIdx = femSourceInfo->femPartIndex(); - m_currentCellIndex = femSourceInfo->triangleToElmMapper()->elementIndex(faceIndex); - } + // IJK -slice commands - // IJK -slice commands + RimViewController* viewController = NULL; + if (m_reservoirView) viewController = m_reservoirView->viewController(); - QMenu menu; + if (!viewController || !viewController->isRangeFiltersControlled()) + { + menu.addAction(QIcon(":/CellFilter_Range.png"), QString("I-slice range filter"), this, SLOT(slotRangeFilterI())); + menu.addAction(QIcon(":/CellFilter_Range.png"), QString("J-slice range filter"), this, SLOT(slotRangeFilterJ())); + menu.addAction(QIcon(":/CellFilter_Range.png"), QString("K-slice range filter"), this, SLOT(slotRangeFilterK())); + } - menu.addAction(QString("I-slice range filter"), this, SLOT(slotRangeFilterI())); - menu.addAction(QString("J-slice range filter"), this, SLOT(slotRangeFilterJ())); - menu.addAction(QString("K-slice range filter"), this, SLOT(slotRangeFilterK())); + RimEclipseView* eclipseView = dynamic_cast(m_reservoirView.p()); + if (eclipseView) + { + RimEclipseCellColors* cellColors = eclipseView->cellResult().p(); + if (cellColors) + { + QAction* propertyAction = new QAction(QIcon(":/CellFilter_Values.png"), QString("Add property filter"), this); + connect(propertyAction, SIGNAL(triggered()), SLOT(slotAddEclipsePropertyFilter())); - RimEclipseView* eclipseView = dynamic_cast(m_reservoirView.p()); - if (eclipseView) - { - RimEclipseCellColors* cellColors = eclipseView->cellResult().p(); - if (cellColors) - { - menu.addAction(QString("Add property filter"), this, SLOT(slotAddEclipsePropertyFilter())); + bool isPerCellFaceResult = RimDefines::isPerCellFaceResult(cellColors->resultVariable()); + if (isPerCellFaceResult) + { + propertyAction->setEnabled(false); + } + + if (!viewController || !viewController->isPropertyFilterOveridden()) + { + menu.addAction(propertyAction); + } + } + + // Hide faults command + const RigCaseData* reservoir = eclipseView->eclipseCase()->reservoirData(); + const RigFault* fault = reservoir->mainGrid()->findFaultFromCellIndexAndCellFace(m_currentCellIndex, m_currentFaceIndex); + if (fault) + { + menu.addSeparator(); + + QString faultName = fault->name(); + menu.addAction(QString("Hide ") + faultName, this, SLOT(slotHideFault())); + } + } + + RimGeoMechView* geoMechView = dynamic_cast(m_reservoirView.p()); + if (geoMechView) + { + RimGeoMechCellColors* cellColors = geoMechView->cellResult().p(); + if (cellColors) + { + if (!viewController || !viewController->isPropertyFilterOveridden()) + { + menu.addAction(QIcon(":/CellFilter_Values.png"), QString("Add property filter"), this, SLOT(slotAddGeoMechPropertyFilter())); + } + } + } } + } - // Hide faults command - const RigCaseData* reservoir = eclipseView->eclipseCase()->reservoirData(); - const RigFault* fault = reservoir->mainGrid()->findFaultFromCellIndexAndCellFace(m_currentCellIndex, m_currentFaceIndex); - if (fault) + // Well log curve creation commands + if (firstHitPart && firstHitPart->sourceInfo()) + { + const RivWellPathSourceInfo* wellPathSourceInfo = dynamic_cast(firstHitPart->sourceInfo()); + if (wellPathSourceInfo) { - menu.addSeparator(); + RimWellPath* wellPath = wellPathSourceInfo->wellPath(); + if (wellPath) + { + caf::CmdFeatureManager* commandManager = caf::CmdFeatureManager::instance(); - QString faultName = fault->name(); - menu.addAction(QString("Hide ") + faultName, this, SLOT(slotHideFault())); + RicNewWellLogFileCurveFeature* newWellLogFileCurveFeature = dynamic_cast(commandManager->getCommandFeature("RicNewWellLogFileCurveFeature")); + if (newWellLogFileCurveFeature && newWellLogFileCurveFeature->canFeatureBeExecuted()) + { + menu.addAction(newWellLogFileCurveFeature->action()); + } + + RicNewWellLogCurveExtractionFeature* newExtractionCurveFeature = dynamic_cast(commandManager->getCommandFeature("RicNewWellLogCurveExtractionFeature")); + if (newExtractionCurveFeature && newExtractionCurveFeature->canFeatureBeExecuted()) + { + menu.addAction(newExtractionCurveFeature->action()); + } + } } } - RimGeoMechView* geoMechView = dynamic_cast(m_reservoirView.p()); - if (geoMechView) + // View Link commands + if (!firstHitPart) { - RimGeoMechCellColors* cellColors = geoMechView->cellResult().p(); - if (cellColors) + QStringList commandIds; + + commandIds << "RicLinkViewFeature"; + commandIds << "RicUnLinkViewFeature"; + commandIds << "RicShowLinkOptionsFeature"; + commandIds << "RicSetMasterViewFeature"; + + bool firstLinkAction = true; + + caf::CmdFeatureManager* commandManager = caf::CmdFeatureManager::instance(); + for (int i = 0; i < commandIds.size(); i++) { - menu.addAction(QString("Add property filter"), this, SLOT(slotAddGeoMechPropertyFilter())); + caf::CmdFeature* feature = commandManager->getCommandFeature(commandIds[i].toStdString()); + if (feature->canFeatureBeExecuted()) + { + QAction* act = commandManager->action(commandIds[i]); + CVF_ASSERT(act); + + if (firstLinkAction) + { + if (menu.actions().size() > 0) + { + menu.addSeparator(); + } + firstLinkAction = false; + } + + menu.addAction(act); + } } } - menu.exec(event->globalPos()); + if (menu.actions().size() > 0) + { + menu.exec(event->globalPos()); + } } //-------------------------------------------------------------------------------------------------- @@ -205,6 +307,9 @@ void RiuViewerCommands::slotRangeFilterK() createSliceRangeFilter(2); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- void RiuViewerCommands::createSliceRangeFilter(int ijOrk) { RimView* eclipseView = m_reservoirView.p(); @@ -213,46 +318,26 @@ void RiuViewerCommands::createSliceRangeFilter(int ijOrk) size_t i, j, k; ijkFromCellIndex(m_currentGridIdx, m_currentCellIndex, &i, &j, &k); - RiuMainWindow* mainWindow = RiuMainWindow::instance(); - RimUiTreeModelPdm* myModel = mainWindow->uiPdmModel(); - if (myModel) - { - RimCellRangeFilterCollection* rangeFilterCollection = eclipseView->rangeFilterCollection(); - - QModelIndex collectionModelIndex = myModel->getModelIndexFromPdmObject(rangeFilterCollection); - - QModelIndex insertedIndex; - RimCellRangeFilter* rangeFilter = myModel->addRangeFilter(collectionModelIndex, insertedIndex); + RimCellRangeFilterCollection* rangeFilterCollection = eclipseView->rangeFilterCollection(); - if (ijOrk == 0){ - rangeFilter->name = QString("Slice I (%1)").arg(rangeFilterCollection->rangeFilters().size()); - rangeFilter->cellCountI = 1; - int startIndex = CVF_MAX(static_cast(i + 1), 1); - rangeFilter->startIndexI = startIndex; + RicRangeFilterNewExec* filterExec = new RicRangeFilterNewExec(rangeFilterCollection); - } - else if (ijOrk == 1){ - rangeFilter->name = QString("Slice J (%1)").arg(rangeFilterCollection->rangeFilters().size()); - rangeFilter->cellCountJ = 1; - int startIndex = CVF_MAX(static_cast(j + 1), 1); - rangeFilter->startIndexJ = startIndex; - - } - else if (ijOrk == 2){ - rangeFilter->name = QString("Slice K (%1)").arg(rangeFilterCollection->rangeFilters().size()); - rangeFilter->cellCountK = 1; - int startIndex = CVF_MAX(static_cast(k + 1), 1); - rangeFilter->startIndexK = startIndex; - } - - rangeFilterCollection->reservoirView()->scheduleGeometryRegen(RANGE_FILTERED); - rangeFilterCollection->reservoirView()->scheduleGeometryRegen(RANGE_FILTERED_INACTIVE); - - rangeFilterCollection->reservoirView()->createDisplayModelAndRedraw(); + if (ijOrk == 0){ + filterExec->m_iSlice = true; + filterExec->m_iSliceStart = CVF_MAX(static_cast(i + 1), 1); + } + else if (ijOrk == 1){ + filterExec->m_jSlice = true; + filterExec->m_jSliceStart = CVF_MAX(static_cast(j + 1), 1); - mainWindow->setCurrentObjectInTreeView(rangeFilter); + } + else if (ijOrk == 2){ + filterExec->m_kSlice = true; + filterExec->m_kSliceStart = CVF_MAX(static_cast(k + 1), 1); } + caf::CmdExecCommandManager::instance()->processExecuteCommand(filterExec); + eclipseView->setSurfaceDrawstyle(); } @@ -275,7 +360,11 @@ void RiuViewerCommands::slotHideFault() RimFault* rimFault = eclipseView->faultCollection()->findFaultByName(faultName); if (rimFault) { - rimFault->showFault.setValueFromUi(!rimFault->showFault); + caf::PdmUiFieldHandle* uiFieldHandle = rimFault->showFault.uiCapability(); + if (uiFieldHandle) + { + uiFieldHandle->setValueFromUi(!rimFault->showFault); + } } } } @@ -288,19 +377,9 @@ void RiuViewerCommands::slotAddEclipsePropertyFilter() RimEclipseView* eclipseView = dynamic_cast(m_reservoirView.p()); if (eclipseView) { - RiuMainWindow* mainWindow = RiuMainWindow::instance(); - RimUiTreeModelPdm* myModel = mainWindow->uiPdmModel(); - if (myModel) - { - RimEclipsePropertyFilterCollection* filterCollection = eclipseView->propertyFilterCollection(); - - QModelIndex collectionModelIndex = myModel->getModelIndexFromPdmObject(filterCollection); - - QModelIndex insertedIndex; - RimEclipsePropertyFilter* propertyFilter = myModel->addPropertyFilter(collectionModelIndex, insertedIndex); - - mainWindow->setCurrentObjectInTreeView(propertyFilter); - } + RimEclipsePropertyFilterCollection* filterCollection = eclipseView->propertyFilterCollection(); + RicEclipsePropertyFilterNewExec* propCmdExe = new RicEclipsePropertyFilterNewExec(filterCollection); + caf::CmdExecCommandManager::instance()->processExecuteCommand(propCmdExe); } } @@ -312,19 +391,9 @@ void RiuViewerCommands::slotAddGeoMechPropertyFilter() RimGeoMechView* geoMechView = dynamic_cast(m_reservoirView.p()); if (geoMechView) { - RiuMainWindow* mainWindow = RiuMainWindow::instance(); - RimUiTreeModelPdm* myModel = mainWindow->uiPdmModel(); - if (myModel) - { - RimGeoMechPropertyFilterCollection* filterCollection = geoMechView->propertyFilterCollection(); - - QModelIndex collectionModelIndex = myModel->getModelIndexFromPdmObject(filterCollection); - - QModelIndex insertedIndex; - RimGeoMechPropertyFilter* propertyFilter = myModel->addGeoMechPropertyFilter(collectionModelIndex, insertedIndex); - - mainWindow->setCurrentObjectInTreeView(propertyFilter); - } + RimGeoMechPropertyFilterCollection* filterCollection = geoMechView->propertyFilterCollection(); + RicGeoMechPropertyFilterNewExec* propCmdExe = new RicGeoMechPropertyFilterNewExec(filterCollection); + caf::CmdExecCommandManager::instance()->processExecuteCommand(propCmdExe); } } @@ -337,6 +406,7 @@ void RiuViewerCommands::handlePickAction(int winPosX, int winPosY) size_t gridIndex = cvf::UNDEFINED_SIZE_T; size_t cellIndex = cvf::UNDEFINED_SIZE_T; size_t nncIndex = cvf::UNDEFINED_SIZE_T; + RimWellPath* wellPath = NULL; cvf::StructGridInterface::FaceType face = cvf::StructGridInterface::NO_FACE; cvf::Vec3d localIntersectionPoint(cvf::Vec3d::ZERO); @@ -353,12 +423,14 @@ void RiuViewerCommands::handlePickAction(int winPosX, int winPosY) if (m_viewer->rayPick(winPosX, winPosY, &hitItems)) { extractIntersectionData(hitItems, &localIntersectionPoint, &firstHitPart, &firstPartTriangleIndex, &firstNncHitPart, &nncPartTriangleIndex); + updateSelectionFromPickedPart(firstHitPart); } if (firstHitPart && firstHitPart->sourceInfo()) { const RivSourceInfo* rivSourceInfo = dynamic_cast(firstHitPart->sourceInfo()); const RivFemPickSourceInfo* femSourceInfo = dynamic_cast(firstHitPart->sourceInfo()); + const RivWellPathSourceInfo* wellPathSourceInfo = dynamic_cast(firstHitPart->sourceInfo()); if (rivSourceInfo) { @@ -376,6 +448,10 @@ void RiuViewerCommands::handlePickAction(int winPosX, int winPosY) gridIndex = femSourceInfo->femPartIndex(); cellIndex = femSourceInfo->triangleToElmMapper()->elementIndex(firstPartTriangleIndex); } + else if (wellPathSourceInfo) + { + wellPath = wellPathSourceInfo->wellPath(); + } } @@ -427,6 +503,11 @@ void RiuViewerCommands::handlePickAction(int winPosX, int winPosY) } } + if (wellPath) + { + pickInfo = QString("Well path hit: %1").arg(wellPath->name()); + } + // Display the text RiuMainWindow* mainWnd = RiuMainWindow::instance(); @@ -573,4 +654,21 @@ void RiuViewerCommands::ijkFromCellIndex(size_t gridIdx, size_t cellIndex, size } } - +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuViewerCommands::updateSelectionFromPickedPart(cvf::Part* part) +{ + if (part && part->sourceInfo()) + { + const RivWellPathSourceInfo* wellPathSourceInfo = dynamic_cast(part->sourceInfo()); + if (wellPathSourceInfo) + { + RimWellPath* wellPath = wellPathSourceInfo->wellPath(); + if (wellPath) + { + RiuMainWindow::instance()->projectTreeView()->selectAsCurrentItem(wellPath); + } + } + } +} diff --git a/ApplicationCode/UserInterface/RiuViewerCommands.h b/ApplicationCode/UserInterface/RiuViewerCommands.h index 7495394079..edb0bff949 100644 --- a/ApplicationCode/UserInterface/RiuViewerCommands.h +++ b/ApplicationCode/UserInterface/RiuViewerCommands.h @@ -61,6 +61,7 @@ private slots: void ijkFromCellIndex(size_t gridIdx, size_t cellIndex, size_t* i, size_t* j, size_t* k); void createSliceRangeFilter(int ijOrk); void extractIntersectionData(const cvf::HitItemCollection& hitItems, cvf::Vec3d* localIntersectionPoint, cvf::Part** firstPart, uint* firstPartFaceHit, cvf::Part** nncPart, uint* nncPartFaceHit); + void updateSelectionFromPickedPart(cvf::Part* part); size_t m_currentGridIdx; size_t m_currentCellIndex; diff --git a/ApplicationCode/UserInterface/RiuWellLogPlot.cpp b/ApplicationCode/UserInterface/RiuWellLogPlot.cpp new file mode 100644 index 0000000000..8fff877713 --- /dev/null +++ b/ApplicationCode/UserInterface/RiuWellLogPlot.cpp @@ -0,0 +1,360 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RiuWellLogPlot.h" + +#include "RiuWellLogTrackPlot.h" +#include "RiuMainWindow.h" + +#include "RimWellLogPlot.h" +#include "RimWellLogPlotTrack.h" + +#include "cafPdmUiTreeView.h" +#include "cvfAssert.h" + +#include +#include +#include +#include +#include + +#include +#include "qwt_legend.h" + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RiuWellLogPlot::RiuWellLogPlot(RimWellLogPlot* plotDefinition, QWidget* parent) + : QWidget(parent), m_scheduleUpdateChildrenLayoutTimer(NULL) +{ + Q_ASSERT(plotDefinition); + m_plotDefinition = plotDefinition; + + QPalette newPalette(palette()); + newPalette.setColor(QPalette::Background, Qt::white); + setPalette(newPalette); + + setAutoFillBackground(true); + + m_scrollBar = new QScrollBar(this); + m_scrollBar->setOrientation(Qt::Vertical); + m_scrollBar->setVisible(true); + + connect(m_scrollBar, SIGNAL(valueChanged(int)), this, SLOT(slotSetMinDepth(int))); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RiuWellLogPlot::~RiuWellLogPlot() +{ + if (m_plotDefinition) + { + m_plotDefinition->handleViewerDeletion(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuWellLogPlot::addTrackPlot(RiuWellLogTrackPlot* trackPlot) +{ + // Insert the plot to the left of the scroll bar + insertTrackPlot(trackPlot, m_trackPlots.size()); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuWellLogPlot::insertTrackPlot(RiuWellLogTrackPlot* trackPlot, size_t index) +{ + trackPlot->setParent(this); + + m_trackPlots.insert(static_cast(index), trackPlot); + + QwtLegend* legend = new QwtLegend(this); + legend->setMaxColumns(1); + legend->connect(trackPlot, SIGNAL(legendDataChanged(const QVariant &, const QList< QwtLegendData > &)), SLOT(updateLegend(const QVariant &, const QList< QwtLegendData > &))); + legend->contentsWidget()->layout()->setAlignment(Qt::AlignBottom | Qt::AlignHCenter); + m_legends.insert(static_cast(index), legend); + + this->connect(trackPlot, SIGNAL(legendDataChanged(const QVariant &, const QList< QwtLegendData > &)), SLOT(scheduleUpdateChildrenLayout())); + + trackPlot->updateLegend(); + + if (trackPlot->isRimTrackVisible()) + { + trackPlot->show(); + } + else + { + trackPlot->hide(); + } + + modifyWidthOfContainingMdiWindow(trackPlot->width()); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuWellLogPlot::removeTrackPlot(RiuWellLogTrackPlot* trackPlot) +{ + if (!trackPlot) return; + + int windowWidthChange = - trackPlot->width(); + + int trackIdx = m_trackPlots.indexOf(trackPlot); + CVF_ASSERT(trackIdx >= 0); + + m_trackPlots.removeAt(trackIdx); + trackPlot->setParent(NULL); + + QwtLegend* legend = m_legends[trackIdx]; + m_legends.removeAt(trackIdx); + delete legend; + + modifyWidthOfContainingMdiWindow(windowWidthChange); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuWellLogPlot::modifyWidthOfContainingMdiWindow(int widthChange) +{ + QMdiSubWindow* mdiWindow = RiuMainWindow::instance()->findMdiSubWindow(this); + if (mdiWindow) + { + if (m_trackPlots.size() == 0 && widthChange <= 0) return; // Last track removed. Leave be + + QSize subWindowSize = mdiWindow->size(); + int newWidth = 0; + + if (m_trackPlots.size() == 1 && widthChange > 0) // First track added + { + newWidth = widthChange; + } + else + { + newWidth = subWindowSize.width() + widthChange; + } + + if (newWidth < 0) newWidth = 100; + + subWindowSize.setWidth(newWidth); + mdiWindow->resize(subWindowSize); + + if (mdiWindow->isMaximized()) + { + // Set window temporarily to normal state and back to maximized + // to redo layout so the whole window canvas is filled + // Tried to activate layout, did not work as expected + // Tested code: + // m_layout->activate(); + // mdiWindow->layout()->activate(); + + mdiWindow->showNormal(); + mdiWindow->showMaximized(); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuWellLogPlot::setDepthZoomAndReplot(double minDepth, double maxDepth) +{ + for (int tpIdx = 0; tpIdx < m_trackPlots.count(); tpIdx++) + { + m_trackPlots[tpIdx]->setDepthZoom(minDepth, maxDepth); + m_trackPlots[tpIdx]->replot(); + } + + updateScrollBar(minDepth, maxDepth); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuWellLogPlot::updateScrollBar(double minDepth, double maxDepth) +{ + double availableMinDepth; + double availableMaxDepth; + m_plotDefinition->availableDepthRange(&availableMinDepth, &availableMaxDepth); + + double visibleDepth = maxDepth - minDepth; + + m_scrollBar->setRange((int) availableMinDepth, (int) (ceil(availableMaxDepth - visibleDepth))); + m_scrollBar->setPageStep((int) visibleDepth); + m_scrollBar->setValue((int) minDepth); + + m_scrollBar->setVisible(true); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuWellLogPlot::slotSetMinDepth(int value) +{ + double minimumDepth; + double maximumDepth; + m_plotDefinition->depthZoomMinMax(&minimumDepth, &maximumDepth); + + double delta = value - minimumDepth; + m_plotDefinition->setDepthZoomMinMax(minimumDepth + delta, maximumDepth + delta); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimWellLogPlot* RiuWellLogPlot::ownerPlotDefinition() +{ + return m_plotDefinition; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuWellLogPlot::resizeEvent(QResizeEvent *event) +{ + int height = event->size().height(); + int width = event->size().width(); + + placeChildWidgets(height, width); + QWidget::resizeEvent(event); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuWellLogPlot::placeChildWidgets(int height, int width) +{ + int trackCount = m_trackPlots.size(); + CVF_ASSERT(m_legends.size() == trackCount); + + int visibleTrackCount = 0; + for (int tIdx = 0; tIdx < trackCount; ++tIdx) + { + if (m_trackPlots[tIdx]->isVisible()) ++visibleTrackCount; + } + + int scrollBarWidth = 0; + if (m_scrollBar->isVisible()) scrollBarWidth = m_scrollBar->sizeHint().width(); + + int maxLegendHeight = 0; + + for (int tIdx = 0; tIdx < trackCount; ++tIdx) + { + if (m_trackPlots[tIdx]->isVisible()) + { + int legendHeight = m_legends[tIdx]->sizeHint().height(); + if (legendHeight > maxLegendHeight) maxLegendHeight = legendHeight; + } + } + + int trackHeight = height - maxLegendHeight; + int trackX = 0; + + + if (visibleTrackCount) + { + int trackWidth = (width - scrollBarWidth)/visibleTrackCount; + int trackWidthExtra = (width-scrollBarWidth)%visibleTrackCount; + + for (int tIdx = 0; tIdx < trackCount; ++tIdx) + { + if (m_trackPlots[tIdx]->isVisible()) + { + int realTrackWidth = trackWidth; + if (trackWidthExtra > 0) + { + realTrackWidth += 1; + --trackWidthExtra; + } + + m_legends[tIdx]->setGeometry(trackX, 0, realTrackWidth, maxLegendHeight); + m_trackPlots[tIdx]->setGeometry(trackX, maxLegendHeight, realTrackWidth, trackHeight); + + trackX += realTrackWidth; + } + } + } + + if (m_scrollBar->isVisible()) m_scrollBar->setGeometry(trackX, maxLegendHeight, scrollBarWidth, trackHeight); + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuWellLogPlot::updateChildrenLayout() +{ + int trackCount = m_trackPlots.size(); + for (int tIdx = 0; tIdx < trackCount; ++tIdx) + { + if (m_trackPlots[tIdx]->isVisible()) + { + m_legends[tIdx]->show(); + } + else + { + m_legends[tIdx]->hide(); + } + } + + placeChildWidgets(this->height(), this->width()); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuWellLogPlot::showEvent(QShowEvent *) +{ + updateChildrenLayout(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuWellLogPlot::changeEvent(QEvent *event) +{ + if (event->type() == QEvent::WindowStateChange) + { + updateChildrenLayout(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// Schedule an update of the widget positions +/// Will happen just a bit after the event loop is entered +/// Used to delay the positioning to after the legend widgets is actually updated. +//-------------------------------------------------------------------------------------------------- +void RiuWellLogPlot::scheduleUpdateChildrenLayout() +{ + if (!m_scheduleUpdateChildrenLayoutTimer) + { + m_scheduleUpdateChildrenLayoutTimer = new QTimer(this); + connect(m_scheduleUpdateChildrenLayoutTimer, SIGNAL(timeout()), this, SLOT(updateChildrenLayout())); + } + + if (!m_scheduleUpdateChildrenLayoutTimer->isActive()) + { + m_scheduleUpdateChildrenLayoutTimer->setSingleShot(true); + m_scheduleUpdateChildrenLayoutTimer->start(10); + } +} diff --git a/ApplicationCode/UserInterface/RiuWellLogPlot.h b/ApplicationCode/UserInterface/RiuWellLogPlot.h new file mode 100644 index 0000000000..749fb1b1c5 --- /dev/null +++ b/ApplicationCode/UserInterface/RiuWellLogPlot.h @@ -0,0 +1,80 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include +#include +#include "cafPdmPointer.h" + +class RimWellLogPlot; +class RiuWellLogTrackPlot; + +class QHBoxLayout; +class QScrollBar; +class QFocusEvent; +class QwtLegend; + +//================================================================================================== +// +// RiuWellLogPlot +// +//================================================================================================== +class RiuWellLogPlot : public QWidget +{ + Q_OBJECT + +public: + RiuWellLogPlot(RimWellLogPlot* plotDefinition, QWidget* parent = NULL); + virtual ~RiuWellLogPlot(); + + RimWellLogPlot* ownerPlotDefinition(); + + void addTrackPlot(RiuWellLogTrackPlot* trackPlot); + void insertTrackPlot(RiuWellLogTrackPlot* trackPlot, size_t index); + void removeTrackPlot(RiuWellLogTrackPlot* trackPlot); + + void setDepthZoomAndReplot(double minDepth, double maxDepth); + +public slots: + void updateChildrenLayout(); + +protected: + virtual void resizeEvent(QResizeEvent *event); + virtual void showEvent(QShowEvent *); + virtual void changeEvent(QEvent *); + +private: + void updateScrollBar(double minDepth, double maxDepth); + void modifyWidthOfContainingMdiWindow(int widthChange); + void placeChildWidgets(int height, int width); + +private slots: + void slotSetMinDepth(int value); + void scheduleUpdateChildrenLayout(); + +private: + QHBoxLayout* m_layout; + QScrollBar* m_scrollBar; + QList m_legends; + QList m_trackPlots; + caf::PdmPointer m_plotDefinition; + QTimer* m_scheduleUpdateChildrenLayoutTimer; +}; + diff --git a/ApplicationCode/UserInterface/RiuWellLogPlotCurve.cpp b/ApplicationCode/UserInterface/RiuWellLogPlotCurve.cpp new file mode 100644 index 0000000000..5c2a2e116c --- /dev/null +++ b/ApplicationCode/UserInterface/RiuWellLogPlotCurve.cpp @@ -0,0 +1,69 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RiuWellLogPlotCurve.h" + +#include "RigWellLogCurveData.h" + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RiuWellLogPlotCurve::RiuWellLogPlotCurve() +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RiuWellLogPlotCurve::~RiuWellLogPlotCurve() +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuWellLogPlotCurve::drawCurve(QPainter* p, int style, + const QwtScaleMap& xMap, const QwtScaleMap& yMap, + const QRectF& canvasRect, int from, int to) const +{ + size_t intervalCount = m_polyLineStartStopIndices.size(); + if (intervalCount > 0) + { + for (size_t intIdx = 0; intIdx < intervalCount; intIdx++) + { + QwtPlotCurve::drawCurve(p, style, xMap, yMap, canvasRect, (int) m_polyLineStartStopIndices[intIdx].first, (int) m_polyLineStartStopIndices[intIdx].second); + } + } + else QwtPlotCurve::drawCurve(p, style, xMap, yMap, canvasRect, from, to); +}; + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuWellLogPlotCurve::setCurveData(const RigWellLogCurveData* curveData) +{ + CVF_ASSERT(curveData); + + std::vector validXValues = curveData->xPlotValues(); + std::vector validYValues = curveData->depthPlotValues(); + + setSamples(validXValues.data(), validYValues.data(), (int) validXValues.size()); + m_polyLineStartStopIndices = curveData->polylineStartStopIndices(); +} diff --git a/ApplicationCode/UserInterface/RiuWellLogPlotCurve.h b/ApplicationCode/UserInterface/RiuWellLogPlotCurve.h new file mode 100644 index 0000000000..d7b5b25dd6 --- /dev/null +++ b/ApplicationCode/UserInterface/RiuWellLogPlotCurve.h @@ -0,0 +1,49 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "qwt_plot_curve.h" + +#include + +class RigWellLogCurveData; + +//================================================================================================== +/// +/// +//================================================================================================== +class RiuWellLogPlotCurve : public QwtPlotCurve +{ +public: + + RiuWellLogPlotCurve(); + virtual ~RiuWellLogPlotCurve(); + + void setCurveData(const RigWellLogCurveData* curveData); + +protected: + + virtual void drawCurve(QPainter* p, int style, + const QwtScaleMap& xMap, const QwtScaleMap& yMap, + const QRectF& canvasRect, int from, int to) const; + +private: + std::vector< std::pair > m_polyLineStartStopIndices; +}; diff --git a/ApplicationCode/UserInterface/RiuWellLogTrackPlot.cpp b/ApplicationCode/UserInterface/RiuWellLogTrackPlot.cpp new file mode 100644 index 0000000000..170e74ce57 --- /dev/null +++ b/ApplicationCode/UserInterface/RiuWellLogTrackPlot.cpp @@ -0,0 +1,292 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RiuWellLogTrackPlot.h" + +#include "RimWellLogPlot.h" +#include "RimWellLogPlotTrack.h" +#include "RimWellLogPlotCurve.h" + +#include "RiuMainWindow.h" + +#include "cafPdmUiTreeView.h" + +#include "qwt_plot_grid.h" +#include "qwt_legend.h" +#include "qwt_scale_engine.h" +#include "qwt_plot_layout.h" +#include "qwt_scale_draw.h" +#include "qwt_text.h" +#include "qwt_plot_curve.h" + +#include +#include +#include + +#include +#include + +#define RIU_SCROLLWHEEL_ZOOMFACTOR 1.1 +#define RIU_SCROLLWHEEL_PANFACTOR 0.1 + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RiuWellLogTrackPlot::RiuWellLogTrackPlot(RimWellLogPlotTrack* plotTrackDefinition, QWidget* parent) + : QwtPlot(parent) +{ + Q_ASSERT(plotTrackDefinition); + m_plotTrackDefinition = plotTrackDefinition; + + m_grid = new QwtPlotGrid(); + m_grid->attach(this); + + setFocusPolicy(Qt::ClickFocus); + setDefaults(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RiuWellLogTrackPlot::~RiuWellLogTrackPlot() +{ + m_grid->detach(); + delete m_grid; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuWellLogTrackPlot::setDefaults() +{ + QPalette newPalette(palette()); + newPalette.setColor(QPalette::Background, Qt::white); + setPalette(newPalette); + + setAutoFillBackground(true); + setCanvasBackground(Qt::white); + + QFrame* canvasFrame = dynamic_cast(canvas()); + if (canvasFrame) + { + canvasFrame->setFrameShape(QFrame::NoFrame); + } + + canvas()->setMouseTracking(true); + canvas()->installEventFilter(this); + + QPen gridPen(Qt::SolidLine); + gridPen.setColor(Qt::lightGray); + m_grid->setPen(gridPen); + + enableAxis(QwtPlot::xTop, true); + enableAxis(QwtPlot::yLeft, true); + enableAxis(QwtPlot::xBottom, false); + enableAxis(QwtPlot::yRight, false); + + plotLayout()->setAlignCanvasToScales(true); + + axisScaleEngine(QwtPlot::yLeft)->setAttribute(QwtScaleEngine::Inverted, true); + + // Align the canvas with the actual min and max values of the curves + axisScaleEngine(QwtPlot::xTop)->setAttribute(QwtScaleEngine::Floating, true); + axisScaleEngine(QwtPlot::yLeft)->setAttribute(QwtScaleEngine::Floating, true); + setAxisScale(QwtPlot::yLeft, 1000, 0); + setAxisScale(QwtPlot::xTop, -10, 100); + + QFont xAxisFont = axisFont(QwtPlot::xTop); + xAxisFont.setPixelSize(9); + setAxisFont(QwtPlot::xTop, xAxisFont); + + QFont yAxisFont = axisFont(QwtPlot::yLeft); + yAxisFont.setPixelSize(9); + setAxisFont(QwtPlot::yLeft, yAxisFont); + + QwtText axisTitleY = axisTitle(QwtPlot::yLeft); + QFont yAxisTitleFont = axisTitleY.font(); + yAxisTitleFont.setPixelSize(9); + yAxisTitleFont.setBold(false); + axisTitleY.setFont(yAxisTitleFont); + axisTitleY.setRenderFlags(Qt::AlignRight); + setAxisTitle(QwtPlot::yLeft, axisTitleY); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuWellLogTrackPlot::setDepthZoom(double minDepth, double maxDepth) +{ + // Note: Y-axis is inverted + setAxisScale(QwtPlot::yLeft, maxDepth, minDepth); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuWellLogTrackPlot::setXRange(double min, double max) +{ + setAxisScale(QwtPlot::xTop, min, max); + setAxisScale(QwtPlot::xBottom, min, max); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuWellLogTrackPlot::setDepthTitle(const QString& title) +{ + QwtText axisTitleY = axisTitle(QwtPlot::yLeft); + axisTitleY.setText(title); + setAxisTitle(QwtPlot::yLeft, axisTitleY); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RiuWellLogTrackPlot::eventFilter(QObject* watched, QEvent* event) +{ + if (watched == canvas()) + { + QWheelEvent* wheelEvent = dynamic_cast(event); + if (wheelEvent) + { + if (!m_plotTrackDefinition) + { + return QwtPlot::eventFilter(watched, event); + } + + RimWellLogPlot* plotDefinition; + m_plotTrackDefinition->firstAnchestorOrThisOfType(plotDefinition); + if (!plotDefinition) + { + return QwtPlot::eventFilter(watched, event); + } + + if (wheelEvent->modifiers() & Qt::ControlModifier) + { + QwtScaleMap scaleMap = canvasMap(QwtPlot::yLeft); + double zoomCenter = scaleMap.invTransform(wheelEvent->pos().y()); + + if (wheelEvent->delta() > 0) + { + plotDefinition->setDepthZoomByFactorAndCenter(RIU_SCROLLWHEEL_ZOOMFACTOR, zoomCenter); + } + else + { + plotDefinition->setDepthZoomByFactorAndCenter(1.0/RIU_SCROLLWHEEL_ZOOMFACTOR, zoomCenter); + } + } + else + { + plotDefinition->panDepth(wheelEvent->delta() < 0 ? RIU_SCROLLWHEEL_PANFACTOR : -RIU_SCROLLWHEEL_PANFACTOR); + } + + event->accept(); + return true; + } + else + { + QMouseEvent* mouseEvent = dynamic_cast(event); + if (mouseEvent) + { + if (mouseEvent->button() == Qt::LeftButton && mouseEvent->type() == QMouseEvent::MouseButtonRelease) + { + selectClosestCurve(mouseEvent->pos()); + } + } + } + } + + return QwtPlot::eventFilter(watched, event); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuWellLogTrackPlot::focusInEvent(QFocusEvent* event) +{ + if (m_plotTrackDefinition) + { + RiuMainWindow::instance()->projectTreeView()->selectAsCurrentItem(m_plotTrackDefinition); + clearFocus(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuWellLogTrackPlot::selectClosestCurve(const QPoint& pos) +{ + QwtPlotCurve* closestCurve = NULL; + double distMin = DBL_MAX; + + const QwtPlotItemList& itmList = itemList(); + for (QwtPlotItemIterator it = itmList.begin(); it != itmList.end(); it++) + { + if ((*it )->rtti() == QwtPlotItem::Rtti_PlotCurve ) + { + QwtPlotCurve* candidateCurve = static_cast(*it); + double dist; + candidateCurve->closestPoint(pos, &dist); + if (dist < distMin) + { + closestCurve = candidateCurve; + distMin = dist; + } + } + } + + if (closestCurve && distMin < 20) + { + RimWellLogPlotCurve* selectedCurve = m_plotTrackDefinition->curveDefinitionFromCurve(closestCurve); + if (selectedCurve) + { + RiuMainWindow::instance()->projectTreeView()->selectAsCurrentItem(selectedCurve); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QSize RiuWellLogTrackPlot::sizeHint() const +{ + return QSize(0, 0); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QSize RiuWellLogTrackPlot::minimumSizeHint() const +{ + return QSize(0, 0); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RiuWellLogTrackPlot::isRimTrackVisible() +{ + if (m_plotTrackDefinition) + { + return m_plotTrackDefinition->isVisible(); + } + + return false; +} + diff --git a/ApplicationCode/UserInterface/RiuWellLogTrackPlot.h b/ApplicationCode/UserInterface/RiuWellLogTrackPlot.h new file mode 100644 index 0000000000..a32e35afa6 --- /dev/null +++ b/ApplicationCode/UserInterface/RiuWellLogTrackPlot.h @@ -0,0 +1,65 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "qwt_plot.h" +#include "cafPdmPointer.h" + +class RimWellLogPlotTrack; +class QwtPlotGrid; +class QwtLegend; + +class QEvent; + +//================================================================================================== +// +// +// +//================================================================================================== +class RiuWellLogTrackPlot : public QwtPlot +{ + Q_OBJECT + +public: + RiuWellLogTrackPlot(RimWellLogPlotTrack* plotTrackDefinition, QWidget* parent = NULL); + virtual ~RiuWellLogTrackPlot(); + + void setDepthZoom(double minDepth, double maxDepth); + void setDepthTitle(const QString& title); + + void setXRange(double min, double max); + + bool isRimTrackVisible(); + +protected: + virtual bool eventFilter(QObject* watched, QEvent* event); + virtual void focusInEvent(QFocusEvent* event); + virtual QSize sizeHint() const; + virtual QSize minimumSizeHint() const; + +private: + void setDefaults(); + void selectClosestCurve(const QPoint& pos); + +private: + caf::PdmPointer m_plotTrackDefinition; + QwtPlotGrid* m_grid; +}; + diff --git a/ApplicationCode/WellPathImportSsihub/RimOilFieldEntry.cpp b/ApplicationCode/WellPathImportSsihub/RimOilFieldEntry.cpp index 53646b15aa..287646e8b6 100644 --- a/ApplicationCode/WellPathImportSsihub/RimOilFieldEntry.cpp +++ b/ApplicationCode/WellPathImportSsihub/RimOilFieldEntry.cpp @@ -48,6 +48,8 @@ RimOilFieldEntry::RimOilFieldEntry() CAF_PDM_InitFieldNoDefault(&wellsFilePath, "wellsFilePath", "wellsFilePath", "", "", ""); CAF_PDM_InitFieldNoDefault(&wells, "Wells", "", "", "", ""); + wells.uiCapability()->setUiHidden(true); + wells.uiCapability()->setUiChildrenHidden(true); } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/WellPathImportSsihub/RimOilFieldEntry.h b/ApplicationCode/WellPathImportSsihub/RimOilFieldEntry.h index b15770391a..bbe2bdac45 100644 --- a/ApplicationCode/WellPathImportSsihub/RimOilFieldEntry.h +++ b/ApplicationCode/WellPathImportSsihub/RimOilFieldEntry.h @@ -20,6 +20,7 @@ #include "cafPdmObject.h" #include "cafPdmField.h" +#include "cafPdmChildArrayField.h" #include "RimWellsEntry.h" @@ -39,7 +40,7 @@ class RimOilFieldEntry : public caf::PdmObject caf::PdmField selected; caf::PdmField wellsFilePath; // Location of the response file from request "/wells" - caf::PdmPointersField wells; + caf::PdmChildArrayField wells; RimWellPathEntry* find(const QString& name, RimWellPathEntry::WellTypeEnum wellPathType); diff --git a/ApplicationCode/WellPathImportSsihub/RimOilRegionEntry.cpp b/ApplicationCode/WellPathImportSsihub/RimOilRegionEntry.cpp index 23482ddc9c..93c3af9f54 100644 --- a/ApplicationCode/WellPathImportSsihub/RimOilRegionEntry.cpp +++ b/ApplicationCode/WellPathImportSsihub/RimOilRegionEntry.cpp @@ -33,9 +33,9 @@ RimOilRegionEntry::RimOilRegionEntry() CAF_PDM_InitFieldNoDefault(&name, "OilRegionEntry", "OilRegionEntry", "", "", ""); CAF_PDM_InitFieldNoDefault(&fields, "Fields", "", "", "", ""); + fields.uiCapability()->setUiHidden(true); CAF_PDM_InitField(&selected, "Selected", false, "Selected", "", "", ""); - } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/WellPathImportSsihub/RimOilRegionEntry.h b/ApplicationCode/WellPathImportSsihub/RimOilRegionEntry.h index da0db5d294..0af69eb858 100644 --- a/ApplicationCode/WellPathImportSsihub/RimOilRegionEntry.h +++ b/ApplicationCode/WellPathImportSsihub/RimOilRegionEntry.h @@ -43,7 +43,7 @@ class RimOilRegionEntry : public caf::PdmObject caf::PdmField name; caf::PdmField selected; - caf::PdmPointersField fields; + caf::PdmChildArrayField fields; }; diff --git a/ApplicationCode/WellPathImportSsihub/RimWellPathImport.cpp b/ApplicationCode/WellPathImportSsihub/RimWellPathImport.cpp index 779e6cdf1e..32b0a33c68 100644 --- a/ApplicationCode/WellPathImportSsihub/RimWellPathImport.cpp +++ b/ApplicationCode/WellPathImportSsihub/RimWellPathImport.cpp @@ -62,6 +62,7 @@ RimWellPathImport::RimWellPathImport() CAF_PDM_InitField(&west, "UtmWest", 0.0, "West", "", "", ""); CAF_PDM_InitFieldNoDefault(®ions, "Regions", "", "", "", ""); + regions.uiCapability()->setUiHidden(true); } //-------------------------------------------------------------------------------------------------- @@ -168,17 +169,17 @@ void RimWellPathImport::updateFieldVisibility() { if (utmFilterMode == UTM_FILTER_CUSTOM) { - north.setUiReadOnly(false); - south.setUiReadOnly(false); - east.setUiReadOnly(false); - west.setUiReadOnly(false); + north.uiCapability()->setUiReadOnly(false); + south.uiCapability()->setUiReadOnly(false); + east.uiCapability()->setUiReadOnly(false); + west.uiCapability()->setUiReadOnly(false); } else { - north.setUiReadOnly(true); - south.setUiReadOnly(true); - east.setUiReadOnly(true); - west.setUiReadOnly(true); + north.uiCapability()->setUiReadOnly(true); + south.uiCapability()->setUiReadOnly(true); + east.uiCapability()->setUiReadOnly(true); + west.uiCapability()->setUiReadOnly(true); } } diff --git a/ApplicationCode/WellPathImportSsihub/RimWellPathImport.h b/ApplicationCode/WellPathImportSsihub/RimWellPathImport.h index cec2ba95d4..491664f051 100644 --- a/ApplicationCode/WellPathImportSsihub/RimWellPathImport.h +++ b/ApplicationCode/WellPathImportSsihub/RimWellPathImport.h @@ -52,7 +52,7 @@ class RimWellPathImport : public caf::PdmObject caf::PdmField east; caf::PdmField west; - caf::PdmPointersField regions; + caf::PdmChildArrayField regions; void updateRegions(const QStringList& regions, const QStringList& fields, const QStringList& edmIds); diff --git a/ApplicationCode/WellPathImportSsihub/RiuWellImportWizard.cpp b/ApplicationCode/WellPathImportSsihub/RiuWellImportWizard.cpp index 4376f52b36..4a47a0aab9 100644 --- a/ApplicationCode/WellPathImportSsihub/RiuWellImportWizard.cpp +++ b/ApplicationCode/WellPathImportSsihub/RiuWellImportWizard.cpp @@ -18,22 +18,22 @@ #include "RiuWellImportWizard.h" -#include -#include -#include +#include "RifJsonEncodeDecode.h" +#include "RimWellPathImport.h" -#include "cafPdmUiPropertyView.h" -#include "cafPdmUiTreeView.h" #include "cafPdmDocument.h" -#include "cafPdmUiListViewEditor.h" +#include "cafPdmObject.h" +#include "cafPdmObjectGroup.h" #include "cafPdmUiListView.h" -#include "cafUiTreeModelPdm.h" - -#include "RimWellPathImport.h" - -#include "RifJsonEncodeDecode.h" +#include "cafPdmUiListViewEditor.h" +#include "cafPdmUiPropertyView.h" +#include "cafPdmUiTreeView.h" #include "cafPdmUiTreeViewEditor.h" +#include +#include +#include + //-------------------------------------------------------------------------------------------------- /// @@ -66,6 +66,13 @@ RiuWellImportWizard::RiuWellImportWizard(const QString& webServiceAddress, const } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RiuWellImportWizard::~RiuWellImportWizard() +{ +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -427,38 +434,18 @@ void RiuWellImportWizard::downloadWells() checkDownloadQueueAndIssueRequests(); } - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RiuWellImportWizard::downloadWellPaths() { - for (size_t rIdx = 0; rIdx < m_wellPathImportObject->regions.size(); rIdx++) - { - RimOilRegionEntry* oilRegion = m_wellPathImportObject->regions[rIdx]; - if (oilRegion->selected) - { - for (size_t fIdx = 0; fIdx < oilRegion->fields.size(); fIdx++) - { - RimOilFieldEntry* oilField = oilRegion->fields[fIdx]; - if (oilField->selected) - { - for (size_t wIdx = 0; wIdx < oilField->wells.size(); wIdx++) - { - RimWellPathEntry* wellPathEntry = oilField->wells[wIdx]; - if (wellPathEntry->selected && wellPathEntry->isWellPathValid()) - { - DownloadEntity urlToFile; - - urlToFile.requestUrl = wellPathEntry->requestUrl; - urlToFile.responseFilename = wellPathEntry->wellPathFilePath; + WellSelectionPage* wellSelectionPage = dynamic_cast(page(m_wellSelectionPageId)); + std::vector downloadEntities; + wellSelectionPage->selectedWellPathEntries(downloadEntities, NULL); - m_wellRequestQueue.push_back(urlToFile); - } - } - } - } - } + for (size_t i = 0; i < downloadEntities.size(); i++) + { + m_wellRequestQueue.push_back(downloadEntities[i]); } m_currentDownloadState = DOWNLOAD_WELL_PATH; @@ -543,31 +530,15 @@ QStringList RiuWellImportWizard::absoluteFilePathsToWellPaths() const { QStringList filePaths; - for (size_t rIdx = 0; rIdx < m_wellPathImportObject->regions.size(); rIdx++) + WellSelectionPage* wellSelectionPage = dynamic_cast(page(m_wellSelectionPageId)); + std::vector downloadEntities; + wellSelectionPage->selectedWellPathEntries(downloadEntities, NULL); + + for (size_t i = 0; i < downloadEntities.size(); i++) { - RimOilRegionEntry* oilRegion = m_wellPathImportObject->regions[rIdx]; - if (oilRegion->selected) + if (QFile::exists(downloadEntities[i].responseFilename)) { - for (size_t fIdx = 0; fIdx < oilRegion->fields.size(); fIdx++) - { - RimOilFieldEntry* oilField = oilRegion->fields[fIdx]; - if (oilField->selected) - { - for (size_t wIdx = 0; wIdx < oilField->wells.size(); wIdx++) - { - RimWellPathEntry* wellPathEntry = oilField->wells[wIdx]; - - QString wellStatus; - if (wellPathEntry->selected) - { - if (QFile::exists(oilField->wells[wIdx]->wellPathFilePath)) - { - filePaths += oilField->wells[wIdx]->wellPathFilePath; - } - } - } - } - } + filePaths.push_back(downloadEntities[i].responseFilename); } } @@ -590,7 +561,7 @@ void RiuWellImportWizard::slotCurrentIdChanged(int currentId) for (size_t fIdx = 0; fIdx < oilRegion->fields.size(); fIdx++) { RimOilFieldEntry* oilField = oilRegion->fields[fIdx]; - oilField->wells.setUiHidden(hideWells); + oilField->wells.uiCapability()->setUiHidden(hideWells); } } } @@ -708,6 +679,15 @@ void RiuWellImportWizard::setCredentials(const QString& username, const QString& setField("password", password); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +int RiuWellImportWizard::wellSelectionPageId() +{ + return m_wellSelectionPageId; +} + + @@ -775,15 +755,15 @@ FieldSelectionPage::FieldSelectionPage(RimWellPathImport* wellPathImport, QWidge // Tree view caf::PdmUiTreeView* treeView = new caf::PdmUiTreeView(this); - treeView->setPdmObject(wellPathImport); + treeView->setPdmItem(wellPathImport); layout->addWidget(treeView); layout->setStretchFactor(treeView, 10); // Property view - caf::PdmUiPropertyView* propertyView = new caf::PdmUiPropertyView(this); - layout->addWidget(propertyView); - propertyView->showProperties(wellPathImport); + m_propertyView = new caf::PdmUiPropertyView(this); + layout->addWidget(m_propertyView); + m_propertyView->showProperties(wellPathImport); setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding)); } @@ -797,36 +777,19 @@ void FieldSelectionPage::initializePage() wiz->downloadFields(); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +FieldSelectionPage::~FieldSelectionPage() +{ + m_propertyView->showProperties(NULL); +} -//-------------------------------------------------------------------------------------------------- -/// Helper class used to define column headers -//-------------------------------------------------------------------------------------------------- -class ObjectGroupWithHeaders : public caf::PdmObjectGroup -{ -public: - ObjectGroupWithHeaders() : caf::PdmObjectGroup() - { - } - - //-------------------------------------------------------------------------------------------------- - /// - //-------------------------------------------------------------------------------------------------- - virtual void defineObjectEditorAttribute(QString uiConfigName, caf::PdmUiEditorAttribute * attribute) - { - caf::PdmUiTreeViewEditorAttribute* myAttr = dynamic_cast(attribute); - if (myAttr) - { - QStringList colHeaders; - colHeaders << "Wells"; - myAttr->columnHeaders = colHeaders; - } - } -}; @@ -849,6 +812,7 @@ WellSelectionPage::WellSelectionPage(RimWellPathImport* wellPathImport, QWidget* m_wellPathImportObject = wellPathImport; m_regionsWithVisibleWells = new ObjectGroupWithHeaders; + m_regionsWithVisibleWells->objects.uiCapability()->setUiHidden(true); } //-------------------------------------------------------------------------------------------------- @@ -888,15 +852,17 @@ void WellSelectionPage::buildWellTreeView() } // Delete all temporary pdm object groups - m_regionsWithVisibleWells->deleteObjects(); + m_regionsWithVisibleWells->objects.deleteAllChildObjects(); for (size_t rIdx = 0; rIdx < m_wellPathImportObject->regions.size(); rIdx++) { RimOilRegionEntry* oilRegion = m_wellPathImportObject->regions[rIdx]; if (oilRegion->selected) { - caf::PdmObjectGroup* regGroup = new caf::PdmObjectGroup; - regGroup->setUiName(oilRegion->userDescriptionField()->uiValue().toString()); + caf::PdmObjectCollection* regGroup = new caf::PdmObjectCollection; + regGroup->objects.uiCapability()->setUiHidden(true); + + regGroup->setUiName(oilRegion->userDescriptionField()->uiCapability()->uiValue().toString()); m_regionsWithVisibleWells->objects.push_back(regGroup); @@ -905,22 +871,31 @@ void WellSelectionPage::buildWellTreeView() RimOilFieldEntry* oilField = oilRegion->fields[fIdx]; if (oilField->selected) { - caf::PdmObjectGroup* fieldGroup = new caf::PdmObjectGroup; - fieldGroup->setUiName(oilField->userDescriptionField()->uiValue().toString()); + caf::PdmObjectCollection* fieldGroup = new caf::PdmObjectCollection; + fieldGroup->objects.uiCapability()->setUiHidden(true); + + fieldGroup->setUiName(oilField->userDescriptionField()->uiCapability()->uiValue().toString()); regGroup->objects.push_back(fieldGroup); for (size_t wIdx = 0; wIdx < oilField->wells.size(); wIdx++) { RimWellPathEntry* wellPathEntry = oilField->wells[wIdx]; - fieldGroup->objects.push_back(wellPathEntry); + + // Create a copy of the PdmObject, as it is not supported to have multiple parents of any objects + QString objStr = xmlObj(wellPathEntry)->writeObjectToXmlString(); + + RimWellPathEntry* wellPathCopy = new RimWellPathEntry; + xmlObj(wellPathCopy)->readObjectFromXmlString(objStr, caf::PdmDefaultObjectFactory::instance()); + + fieldGroup->objects.push_back(wellPathCopy); } } } } } - m_wellSelectionTreeView->setPdmObject(m_regionsWithVisibleWells); + m_wellSelectionTreeView->setPdmItem(m_regionsWithVisibleWells); m_regionsWithVisibleWells->updateConnectedEditors(); m_wellSelectionTreeView->treeView()->expandAll(); @@ -931,10 +906,56 @@ void WellSelectionPage::buildWellTreeView() //-------------------------------------------------------------------------------------------------- WellSelectionPage::~WellSelectionPage() { + if (m_wellSelectionTreeView) + { + m_wellSelectionTreeView->setPdmItem(NULL); + } delete m_regionsWithVisibleWells; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void WellSelectionPage::selectedWellPathEntries(std::vector& downloadEntities, caf::PdmObjectHandle* objHandle) +{ + if (objHandle == NULL) + { + objHandle = m_regionsWithVisibleWells; + } + + std::vector childFields; + objHandle->fields(childFields); + for (size_t i = 0; i < childFields.size(); i++) + { + std::vector childObjects; + childFields[i]->childObjects(&childObjects); + + for (size_t j = 0; j < childObjects.size(); j++) + { + RimWellPathEntry* wellPathEntry = (dynamic_cast(childObjects[j])); + if (wellPathEntry) + { + if (wellPathEntry->selected && wellPathEntry->isWellPathValid()) + { + DownloadEntity urlToFile; + + urlToFile.name = wellPathEntry->name; + urlToFile.requestUrl = wellPathEntry->requestUrl; + urlToFile.responseFilename = wellPathEntry->wellPathFilePath; + + downloadEntities.push_back(urlToFile); + } + } + else + { + selectedWellPathEntries(downloadEntities, childObjects[j]); + } + } + } +} + + //-------------------------------------------------------------------------------------------------- @@ -961,7 +982,7 @@ WellSummaryPage::WellSummaryPage(RimWellPathImport* wellPathImport, QWidget* par layout->addWidget(m_listView); m_listView->hide(); - m_objectGroup = new caf::PdmObjectGroup; + m_objectGroup = new caf::PdmObjectCollection; setButtonText(QWizard::FinishButton, "Import"); } @@ -987,41 +1008,30 @@ void WellSummaryPage::updateSummaryPage() size_t wellPathCount = 0; QString errorString; - for (size_t rIdx = 0; rIdx < m_wellPathImportObject->regions.size(); rIdx++) + RiuWellImportWizard* wiz = dynamic_cast(wizard()); + WellSelectionPage* wellSelectionPage = dynamic_cast(wiz->page(wiz->wellSelectionPageId())); + std::vector downloadEntities; + wellSelectionPage->selectedWellPathEntries(downloadEntities, NULL); + + for (size_t i = 0; i < downloadEntities.size(); i++) { - RimOilRegionEntry* oilRegion = m_wellPathImportObject->regions[rIdx]; - if (oilRegion->selected) + if (QFile::exists(downloadEntities[i].responseFilename)) { - for (size_t fIdx = 0; fIdx < oilRegion->fields.size(); fIdx++) - { - RimOilFieldEntry* oilField = oilRegion->fields[fIdx]; - if (oilField->selected) - { - QString oilFieldText = QString("\nRegion : %1 - Field : %2").arg(oilRegion->name).arg(oilField->name); - m_textEdit->append(oilFieldText); - - for (size_t wIdx = 0; wIdx < oilField->wells.size(); wIdx++) - { - RimWellPathEntry* wellPathEntry = oilField->wells[wIdx]; - if (wellPathEntry->selected) - { - if (QFile::exists(oilField->wells[wIdx]->wellPathFilePath)) - { - wellPathCount++; - } - else - { - errorString += QString("Failed to get file '%1' from well '%2'\n").arg(oilField->wells[wIdx]->wellPathFilePath).arg(oilField->wells[wIdx]->name); - } - - m_objectGroup->objects.push_back(wellPathEntry); - } - } - } - } + wellPathCount++; } - } + else + { + errorString += QString("Failed to get file '%1' from well '%2'\n").arg(downloadEntities[i].responseFilename).arg(downloadEntities[i].name); + } + + SummaryPageDownloadEntity* sumPageEntity = new SummaryPageDownloadEntity; + sumPageEntity->name = downloadEntities[i].name; + sumPageEntity->responseFilename = downloadEntities[i].responseFilename; + sumPageEntity->requestUrl = downloadEntities[i].requestUrl; + + m_objectGroup->objects().push_back(sumPageEntity); + } m_textEdit->setText(QString("Downloaded successfully %1 well paths.\nPlease push 'Import' button to import well paths into ResInsight.\n\n").arg(wellPathCount)); if (!errorString.isEmpty()) @@ -1050,3 +1060,34 @@ void WellSummaryPage::slotShowDetails() } } + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void ObjectGroupWithHeaders::defineObjectEditorAttribute(QString uiConfigName, caf::PdmUiEditorAttribute * attribute) +{ + caf::PdmUiTreeViewEditorAttribute* myAttr = dynamic_cast(attribute); + if (myAttr) + { + QStringList colHeaders; + colHeaders << "Wells"; + myAttr->columnHeaders = colHeaders; + } +} + + + +CAF_PDM_SOURCE_INIT(SummaryPageDownloadEntity, "SummaryPageDownloadEntity"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +SummaryPageDownloadEntity::SummaryPageDownloadEntity() +{ + CAF_PDM_InitObject("SummaryPageDownloadEntity", "", "", ""); + + CAF_PDM_InitFieldNoDefault(&name, "Name", "", "", "", ""); + CAF_PDM_InitFieldNoDefault(&requestUrl, "RequestUrl", "", "", "", ""); + CAF_PDM_InitFieldNoDefault(&responseFilename, "ResponseFilename", "", "", "", ""); +} diff --git a/ApplicationCode/WellPathImportSsihub/RiuWellImportWizard.h b/ApplicationCode/WellPathImportSsihub/RiuWellImportWizard.h index aea5bee92e..75ff77487d 100644 --- a/ApplicationCode/WellPathImportSsihub/RiuWellImportWizard.h +++ b/ApplicationCode/WellPathImportSsihub/RiuWellImportWizard.h @@ -18,29 +18,34 @@ #pragma once -#include -#include -#include -#include +#include "cafPdmChildArrayField.h" +#include "cafPdmField.h" +#include "cafPdmObject.h" +#include "cafPdmObjectGroup.h" + #include +#include #include +#include +#include +#include class QFile; class QProgressDialog; class QLabel; class QTextEdit; - class RimWellPathImport; class RimOilFieldEntry; +class RimWellPathEntry; namespace caf { - class UiTreeModelPdm; class PdmUiTreeView; class PdmUiListView; - class PdmObjectGroup; + class PdmUiPropertyView; + class PdmObjectCollection; } @@ -67,14 +72,52 @@ class FieldSelectionPage : public QWizardPage public: FieldSelectionPage(RimWellPathImport* wellPathImport, QWidget* parent = 0); + ~FieldSelectionPage(); virtual void initializePage(); + +private: + caf::PdmUiPropertyView* m_propertyView; }; -class ObjectGroupWithHeaders; +//-------------------------------------------------------------------------------------------------- +/// Container class used to define column headers +//-------------------------------------------------------------------------------------------------- +class ObjectGroupWithHeaders : public caf::PdmObjectCollection +{ +public: + ObjectGroupWithHeaders() {}; + + virtual void defineObjectEditorAttribute(QString uiConfigName, caf::PdmUiEditorAttribute * attribute); +}; + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +class DownloadEntity +{ +public: + QString name; + QString requestUrl; + QString responseFilename; +}; + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +class SummaryPageDownloadEntity : public caf::PdmObject +{ + CAF_PDM_HEADER_INIT; + +public: + SummaryPageDownloadEntity(); + caf::PdmField name; + caf::PdmField requestUrl; + caf::PdmField responseFilename; +}; //-------------------------------------------------------------------------------------------------- /// @@ -90,6 +133,9 @@ class WellSelectionPage : public QWizardPage virtual void initializePage(); void buildWellTreeView(); + + void selectedWellPathEntries(std::vector& downloadEntities, caf::PdmObjectHandle* objHandle); + private: ObjectGroupWithHeaders* m_regionsWithVisibleWells; RimWellPathImport* m_wellPathImportObject; @@ -119,20 +165,10 @@ private slots: RimWellPathImport* m_wellPathImportObject; QTextEdit* m_textEdit; caf::PdmUiListView* m_listView; - caf::PdmObjectGroup*m_objectGroup; + caf::PdmObjectCollection* m_objectGroup; }; -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -class DownloadEntity -{ -public: - QString requestUrl; - QString responseFilename; -}; - //-------------------------------------------------------------------------------------------------- /// @@ -146,12 +182,12 @@ class RiuWellImportWizard : public QWizard public: RiuWellImportWizard(const QString& webServiceAddress, const QString& downloadFolder, RimWellPathImport* wellPathImportObject, QWidget *parent = 0); + ~RiuWellImportWizard(); void setCredentials(const QString& username, const QString& password); QStringList absoluteFilePathsToWellPaths() const; // Methods used from the wizard pages - caf::PdmObjectGroup* wellCollection(); void resetAuthenticationCount(); public slots: @@ -169,6 +205,7 @@ public slots: void slotAuthenticationRequired(QNetworkReply* networkReply, QAuthenticator* authenticator); + int wellSelectionPageId(); #ifndef QT_NO_OPENSSL void sslErrors(QNetworkReply*,const QList &errors); diff --git a/CMakeLists.txt b/CMakeLists.txt index faced5354d..85a8a82a38 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -55,6 +55,7 @@ include (ResInsightVersion.cmake) # Disable install of ERT libs and headers, as Ert code is compiled and linked directly SET(INSTALL_ERT OFF CACHE BOOL "ERT: Install library") +SET(BUILD_PYTHON OFF CACHE BOOL "ERT: Run py_compile on the python wrappers") SET(BUILD_SHARED_LIBS OFF CACHE BOOL "ERT: Build shared libraries") SET(ERT_USE_OPENMP ${OPENMP_FOUND} CACHE BOOL "ERT: Compile using OpenMP") @@ -107,6 +108,15 @@ set_property(TARGET PROPERTY FOLDER "ERT" ) + +################################################################################ +# NRLib +################################################################################ + +add_subdirectory(ThirdParty/NRLib) +include_directories(ThirdParty/NRLib/nrlib/well) + + ################################################################################ # Qt ################################################################################ @@ -125,6 +135,13 @@ include (${QT_USE_FILE}) # Open GL find_package( OpenGL ) +################################################################################ +# Qwt +################################################################################ + +add_subdirectory(ThirdParty/Qwt/src) +include_directories(ThirdParty/Qwt/src) + ################################################################################ # Vizualization Framework ################################################################################ @@ -178,31 +195,35 @@ set_property(TARGET # Application Framework ################################################################################ -add_subdirectory(Fwk/AppFwk/cafProjectDataModel) -add_subdirectory(Fwk/AppFwk/CommonCode) add_subdirectory(Fwk/AppFwk/cafAnimControl) add_subdirectory(Fwk/AppFwk/cafViewer) + +add_subdirectory(Fwk/AppFwk/cafProjectDataModel/cafPdmCore) +add_subdirectory(Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore) +add_subdirectory(Fwk/AppFwk/cafProjectDataModel/cafPdmXml) +add_subdirectory(Fwk/AppFwk/cafProjectDataModel) + +add_subdirectory(Fwk/AppFwk/cafCommand) add_subdirectory(Fwk/AppFwk/cafUserInterface) add_subdirectory(Fwk/AppFwk/cafPdmCvf) -add_subdirectory(Fwk/AppFwk/cafTensor) +add_subdirectory(Fwk/AppFwk/CommonCode) -include_directories( - ${cafUserInterface_SOURCE_DIR} - ${cafProjectDataModel_SOURCE_DIR} - ${cafPdmCvf_SOURCE_DIR} - ${CommonCode_SOURCE_DIR} - ${cafAnimControl_SOURCE_DIR} - ${cafViewer_SOURCE_DIR} - ${cafTensor_SOURCE_DIR} -) + +add_subdirectory(Fwk/AppFwk/cafTensor) set_property(TARGET - cafAnimControl - cafPdmCvf + cafAnimControl + cafViewer + + cafPdmCore + cafPdmUiCore + cafPdmXml cafProjectDataModel + + cafCommand cafUserInterface - cafViewer cafTensor + cafPdmCvf CommonCode PROPERTY FOLDER "AppFwk" ) @@ -237,12 +258,12 @@ add_subdirectory(OctavePlugin) # Unit tests ################################################################################ add_subdirectory(ApplicationCode/ReservoirDataModel/ReservoirDataModel_UnitTests) -add_subdirectory(ApplicationCode/FileInterface/FileInterface_UnitTests) +#add_subdirectory(ApplicationCode/FileInterface/FileInterface_UnitTests) add_subdirectory(ApplicationCode/ModelVisualization/ModelVisualization_UnitTests) set_property(TARGET ModelVisualization_UnitTests - FileInterface_UnitTests +# FileInterface_UnitTests RigReservoirDataModel_UnitTests PROPERTY FOLDER "UnitTests" ) diff --git a/Fwk/AppFwk/CMakeLists.txt b/Fwk/AppFwk/CMakeLists.txt index 9c13882f33..4aaad1afe9 100644 --- a/Fwk/AppFwk/CMakeLists.txt +++ b/Fwk/AppFwk/CMakeLists.txt @@ -6,11 +6,26 @@ project (CeeApp) find_package (Qt4 COMPONENTS QtCore QtGui QtMain QtOpenGl REQUIRED) include (${QT_USE_FILE}) + #libraries +add_subdirectory (cafProjectDataModel/cafPdmCore) +add_subdirectory (cafProjectDataModel/cafPdmUiCore) +add_subdirectory (cafProjectDataModel/cafPdmXml) + add_subdirectory(cafProjectDataModel) +add_subdirectory(cafCommand) add_subdirectory(cafUserInterface) #executables add_subdirectory(cafTests/cafProjectDataModel_UnitTests) add_subdirectory(cafTests/cafTestApplication) +add_subdirectory (cafProjectDataModel/cafPdmCore/cafPdmCore_UnitTests) +add_subdirectory (cafProjectDataModel/cafPdmXml/cafPdmXml_UnitTests) + +# Organize sub-projects into folders on Visual Studio +# Turn on using solution folders +set_property(GLOBAL PROPERTY USE_FOLDERS ON) + +set_property(TARGET cafPdmCore cafPdmCore_UnitTests cafPdmXml cafPdmXml_UnitTests cafPdmUiCore PROPERTY FOLDER "PdmCore") + diff --git a/Fwk/AppFwk/CommonCode/CMakeLists.txt b/Fwk/AppFwk/CommonCode/CMakeLists.txt index 0cb5f05752..855306a200 100644 --- a/Fwk/AppFwk/CommonCode/CMakeLists.txt +++ b/Fwk/AppFwk/CommonCode/CMakeLists.txt @@ -2,6 +2,23 @@ cmake_minimum_required (VERSION 2.8) project (CommonCode) +# Qt +find_package ( Qt4 COMPONENTS QtCore QtGui QtMain QtOpenGl ) +include (${QT_USE_FILE}) + +# Open GL +find_package( OpenGL ) + +include_directories( + ${LibCore_SOURCE_DIR} + ${LibGeometry_SOURCE_DIR} + ${LibGuiQt_SOURCE_DIR} + ${LibRender_SOURCE_DIR} + ${LibViewing_SOURCE_DIR} + + ${cafPdmCore_SOURCE_DIR} +) + # These headers need to go through Qt's MOC compiler set( QOBJECT_HEADERS cafMessagePanel.h diff --git a/Fwk/AppFwk/CommonCode/cafEffectGenerator.cpp b/Fwk/AppFwk/CommonCode/cafEffectGenerator.cpp index 642c24b4e1..920c923b31 100644 --- a/Fwk/AppFwk/CommonCode/cafEffectGenerator.cpp +++ b/Fwk/AppFwk/CommonCode/cafEffectGenerator.cpp @@ -155,17 +155,27 @@ EffectGenerator::RenderingModeType EffectGenerator::renderingMode() } //-------------------------------------------------------------------------------------------------- -/// Creates a new effect using the settings in the inherited generator. -/// Creates a new effect and calls the correct update-Effect method dep. on the effect type (software/shader) +/// //-------------------------------------------------------------------------------------------------- -cvf::ref EffectGenerator::generateEffect() const +cvf::ref EffectGenerator::generateCachedEffect() const { - cvf::ref eff = caf::EffectCache::instance()->findEffect(this); - if (eff.notNull()) return eff.p(); + if (eff.notNull()) return eff.p(); - eff = new cvf::Effect; + eff = generateUnCachedEffect(); + caf::EffectCache::instance()->addEffect(this, eff.p()); + + return eff; +} + +//-------------------------------------------------------------------------------------------------- +/// Creates a new effect using the settings in the inherited generator. +/// Creates a new effect and calls the correct update-Effect method dep. on the effect type (software/shader) +//-------------------------------------------------------------------------------------------------- +cvf::ref EffectGenerator::generateUnCachedEffect() const +{ + cvf::ref eff = new cvf::Effect; if (sm_renderingMode == SHADER_BASED) { @@ -176,11 +186,11 @@ cvf::ref EffectGenerator::generateEffect() const updateForFixedFunctionRendering(eff.p()); } - caf::EffectCache::instance()->addEffect(this, eff.p()); - return eff; } + + //-------------------------------------------------------------------------------------------------- /// Updates the effect to the state defined by the inherited effect generator. /// This can be used to update an effect used several places in the scene. @@ -237,6 +247,7 @@ SurfaceEffectGenerator::SurfaceEffectGenerator(const cvf::Color4f& color, Polygo m_polygonOffset = polygonOffset; m_cullBackfaces = FC_NONE; m_enableDepthWrite = true; + m_enableLighting = true; } //-------------------------------------------------------------------------------------------------- @@ -248,6 +259,7 @@ SurfaceEffectGenerator::SurfaceEffectGenerator(const cvf::Color3f& color, Polygo m_polygonOffset = polygonOffset; m_cullBackfaces = FC_NONE; m_enableDepthWrite = true; + m_enableLighting = true; } @@ -259,8 +271,16 @@ void SurfaceEffectGenerator::updateForShaderBasedRendering(cvf::Effect* effect) cvf::ShaderProgramGenerator gen("SurfaceEffectGenerator", cvf::ShaderSourceProvider::instance()); gen.addVertexCode(cvf::ShaderSourceRepository::vs_Standard); gen.addFragmentCode(cvf::ShaderSourceRepository::src_Color); - gen.addFragmentCode(CommonShaderSources::light_AmbientDiffuse()); - gen.addFragmentCode(cvf::ShaderSourceRepository::fs_Standard); + + if (m_enableLighting) + { + gen.addFragmentCode(CommonShaderSources::light_AmbientDiffuse()); + gen.addFragmentCode(cvf::ShaderSourceRepository::fs_Standard); + } + else + { + gen.addFragmentCode(cvf::ShaderSourceRepository::fs_Unlit); + } cvf::ref shaderProg = gen.generate(); @@ -286,6 +306,7 @@ void SurfaceEffectGenerator::updateForFixedFunctionRendering(cvf::Effect* effect cvf::ref lighting = new cvf::RenderStateLighting_FF; lighting->enableTwoSided(true); + lighting->enable(m_enableLighting); eff->setRenderState(lighting.p()); this->updateCommonEffect(effect); @@ -351,6 +372,7 @@ bool SurfaceEffectGenerator::isEqual(const EffectGenerator* other) const if (m_color == otherSurfaceEffect->m_color && m_polygonOffset == otherSurfaceEffect->m_polygonOffset && m_enableDepthWrite == otherSurfaceEffect->m_enableDepthWrite + && m_enableLighting == otherSurfaceEffect->m_enableLighting && m_cullBackfaces == otherSurfaceEffect->m_cullBackfaces) { return true; @@ -368,6 +390,7 @@ EffectGenerator* SurfaceEffectGenerator::copy() const SurfaceEffectGenerator* effGen = new SurfaceEffectGenerator(m_color, m_polygonOffset); effGen->m_cullBackfaces = m_cullBackfaces; effGen->m_enableDepthWrite = m_enableDepthWrite; + effGen->m_enableLighting = m_enableLighting; return effGen; } @@ -781,6 +804,7 @@ EffectGenerator* ScalarMapperMeshEffectGenerator::copy() const MeshEffectGenerator::MeshEffectGenerator(const cvf::Color3f& color) { m_color = color; + m_lineStipple = false; } //-------------------------------------------------------------------------------------------------- @@ -798,7 +822,12 @@ void MeshEffectGenerator::updateForShaderBasedRendering(cvf::Effect* effect) con cvf::ref eff = effect; eff->setShaderProgram(shaderProg.p()); eff->setUniform(new cvf::UniformFloat("u_color", cvf::Color4f(m_color, 1.0))); - + + if (m_lineStipple) + { + // TODO: Use when VizFwk is updated + //eff->setRenderState(new cvf::RenderStateLineStipple_FF); + } } //-------------------------------------------------------------------------------------------------- @@ -813,6 +842,11 @@ void MeshEffectGenerator::updateForFixedFunctionRendering(cvf::Effect* effect) c eff->setRenderState(new cvf::RenderStateDepth(true, cvf::RenderStateDepth::LEQUAL)); eff->setRenderState(new cvf::RenderStateLighting_FF(false)); + if (m_lineStipple) + { + // TODO: Use when VizFwk is updated + //eff->setRenderState(new cvf::RenderStateLineStipple_FF); + } } //-------------------------------------------------------------------------------------------------- @@ -824,10 +858,17 @@ bool MeshEffectGenerator::isEqual(const EffectGenerator* other) const if (otherMesh) { - if (m_color == otherMesh->m_color) + if (m_color != otherMesh->m_color) { - return true; + return false; + } + + if (m_lineStipple != otherMesh->m_lineStipple) + { + return false; } + + return true; } return false; @@ -838,7 +879,10 @@ bool MeshEffectGenerator::isEqual(const EffectGenerator* other) const //-------------------------------------------------------------------------------------------------- EffectGenerator* MeshEffectGenerator::copy() const { - return new MeshEffectGenerator(m_color); + MeshEffectGenerator* effGen = new MeshEffectGenerator(m_color); + effGen->setLineStipple(m_lineStipple); + + return effGen; } diff --git a/Fwk/AppFwk/CommonCode/cafEffectGenerator.h b/Fwk/AppFwk/CommonCode/cafEffectGenerator.h index 56adcf3849..9483f255a2 100644 --- a/Fwk/AppFwk/CommonCode/cafEffectGenerator.h +++ b/Fwk/AppFwk/CommonCode/cafEffectGenerator.h @@ -46,6 +46,11 @@ #include "cvfString.h" #include "cvfRenderStatePolygonOffset.h" +namespace cvf +{ + class RenderStatePolygonOffset; +} + namespace caf { class CommonShaderSources @@ -88,7 +93,8 @@ class EffectGenerator EffectGenerator() {} virtual ~EffectGenerator() {} - cvf::ref generateEffect() const; + cvf::ref generateUnCachedEffect() const; + cvf::ref generateCachedEffect() const; void updateEffect(cvf::Effect* effect) const; static void setRenderingMode(RenderingModeType effectType); @@ -129,6 +135,7 @@ class SurfaceEffectGenerator : public EffectGenerator void setCullBackfaces(FaceCulling cullBackFaces) { m_cullBackfaces = cullBackFaces; } void enableDepthWrite(bool enableWrite) { m_enableDepthWrite = enableWrite; } + void enableLighting(bool enableLighting) { m_enableLighting = enableLighting; } protected: virtual bool isEqual(const EffectGenerator* other) const; @@ -145,6 +152,7 @@ class SurfaceEffectGenerator : public EffectGenerator PolygonOffset m_polygonOffset; FaceCulling m_cullBackfaces; bool m_enableDepthWrite; + bool m_enableLighting; }; @@ -230,6 +238,7 @@ class MeshEffectGenerator : public EffectGenerator { public: MeshEffectGenerator(const cvf::Color3f& color); + void setLineStipple(bool enable) { m_lineStipple = enable; } protected: virtual bool isEqual(const EffectGenerator* other) const; @@ -240,6 +249,7 @@ class MeshEffectGenerator : public EffectGenerator private: cvf::Color3f m_color; + bool m_lineStipple; }; diff --git a/Fwk/AppFwk/CommonCode/cafLog.cpp b/Fwk/AppFwk/CommonCode/cafLog.cpp index aab270bd36..523a80e40b 100644 --- a/Fwk/AppFwk/CommonCode/cafLog.cpp +++ b/Fwk/AppFwk/CommonCode/cafLog.cpp @@ -50,7 +50,7 @@ namespace caf { //-------------------------------------------------------------------------------------------------- void Log::info(const QString& msg) { - infoMultiLine(msg, ""); + infoMultiLine(msg, ""); } @@ -59,7 +59,7 @@ void Log::info(const QString& msg) //-------------------------------------------------------------------------------------------------- void Log::warning(const QString& msg) { - warningMultiLine(msg, ""); + warningMultiLine(msg, ""); } @@ -68,7 +68,7 @@ void Log::warning(const QString& msg) //-------------------------------------------------------------------------------------------------- bool Log::error(const QString& err) { - return errorMultiLine(err, ""); + return errorMultiLine(err, ""); } @@ -77,30 +77,30 @@ bool Log::error(const QString& err) //-------------------------------------------------------------------------------------------------- void Log::infoMultiLine(const QString& line1, const QString& line2Etc) { - MessagePanel* messagePanel = MessagePanel::instance(); + MessagePanel* messagePanel = MessagePanel::instance(); - bool generateTrace = true; + bool generateTrace = true; - if (messagePanel) - { - QString msg = line1; - if (!line2Etc.isEmpty()) - { - msg += "\n"; + if (messagePanel) + { + QString msg = line1; + if (!line2Etc.isEmpty()) + { + msg += "\n"; msg += Utils::indentString(2, line2Etc); - } + } - messagePanel->showInfo(msg); - } + messagePanel->showInfo(msg); + } - if (generateTrace) - { + if (generateTrace) + { cvf::Trace::show("INF: %s", (const char*)line1.toAscii()); - if (!line2Etc.isEmpty()) - { + if (!line2Etc.isEmpty()) + { cvf::Trace::show((const char*)Utils::indentString(5, line2Etc).toAscii()); - } - } + } + } } @@ -146,7 +146,7 @@ bool Log::errorMultiLine(const QString& line1, const QString& line2Etc) bool generateTrace = true; if (messagePanel) - { + { QString msg = line1; if (!line2Etc.isEmpty()) { @@ -155,43 +155,43 @@ bool Log::errorMultiLine(const QString& line1, const QString& line2Etc) } messagePanel->showError(msg); - } - - bool messagePanelVisible = messagePanel ? messagePanel->isVisibleToUser() : false; - if (!messagePanelVisible) - { -// if (mainWindow) -// { -// QString capt = QString(PD_APPLICATION_NAME) + " Error"; + } + + bool messagePanelVisible = messagePanel ? messagePanel->isVisibleToUser() : false; + if (!messagePanelVisible) + { +// if (mainWindow) +// { +// QString capt = QString(PD_APPLICATION_NAME) + " Error"; // -// QString msg = line1; -// if (!line2Etc.isEmpty()) -// { -// msg += "\n"; -// msg += line2Etc; -// } +// QString msg = line1; +// if (!line2Etc.isEmpty()) +// { +// msg += "\n"; +// msg += line2Etc; +// } // -// QMessageBox msgBox(mainWindow); -// msgBox.setIcon(QMessageBox::Critical); -// msgBox.setWindowTitle(capt); -// msgBox.setText(msg); +// QMessageBox msgBox(mainWindow); +// msgBox.setIcon(QMessageBox::Critical); +// msgBox.setWindowTitle(capt); +// msgBox.setText(msg); // -// msgBox.exec(); -// } -// else -// { -// generateTrace = true; -// } - } - - if (generateTrace) - { +// msgBox.exec(); +// } +// else +// { +// generateTrace = true; +// } + } + + if (generateTrace) + { cvf::Trace::show("\nERR: %s", (const char*)line1.toAscii()); if (!line2Etc.isEmpty()) { cvf::Trace::show((const char*)Utils::indentString(5, line2Etc).toAscii()); } - } + } return false; } diff --git a/Fwk/AppFwk/CommonCode/cafLog.h b/Fwk/AppFwk/CommonCode/cafLog.h index 00fb26c2d1..e24fcd8575 100644 --- a/Fwk/AppFwk/CommonCode/cafLog.h +++ b/Fwk/AppFwk/CommonCode/cafLog.h @@ -59,7 +59,7 @@ class Log static void warningMultiLine(const QString& line1, const QString& line2Etc); static bool errorMultiLine(const QString& line1, const QString& line2Etc); - static void pumpMessages(); + static void pumpMessages(); }; diff --git a/Fwk/AppFwk/CommonCode/cafMessagePanel.cpp b/Fwk/AppFwk/CommonCode/cafMessagePanel.cpp index 88714f07f1..53a8ea9725 100644 --- a/Fwk/AppFwk/CommonCode/cafMessagePanel.cpp +++ b/Fwk/AppFwk/CommonCode/cafMessagePanel.cpp @@ -61,13 +61,13 @@ MessagePanel* MessagePanel::sm_messagePanelInstance = NULL; MessagePanel::MessagePanel(QDockWidget* parent) : QWidget(parent) { - m_textEdit = new QTextEdit(this); - m_textEdit->setReadOnly(true); - m_textEdit->setLineWrapMode(QTextEdit::NoWrap); + m_textEdit = new QTextEdit(this); + m_textEdit->setReadOnly(true); + m_textEdit->setLineWrapMode(QTextEdit::NoWrap); - QVBoxLayout* layout = new QVBoxLayout(); - layout->addWidget(m_textEdit); - setLayout(layout); + QVBoxLayout* layout = new QVBoxLayout(); + layout->addWidget(m_textEdit); + setLayout(layout); sm_messagePanelInstance = this; } @@ -78,13 +78,13 @@ MessagePanel::MessagePanel(QDockWidget* parent) //-------------------------------------------------------------------------------------------------- void MessagePanel::showInfo(QString info) { - convertStringToHTML(&info); + convertStringToHTML(&info); - QString str = ""; - str += info; - str += ""; + QString str = ""; + str += info; + str += ""; - m_textEdit->append(str); + m_textEdit->append(str); } @@ -93,13 +93,13 @@ void MessagePanel::showInfo(QString info) //-------------------------------------------------------------------------------------------------- void MessagePanel::showWarning(QString warn) { - convertStringToHTML(&warn); + convertStringToHTML(&warn); - QString str = ""; - str += warn; - str += ""; - - m_textEdit->append(str); + QString str = ""; + str += warn; + str += ""; + + m_textEdit->append(str); } @@ -108,13 +108,13 @@ void MessagePanel::showWarning(QString warn) //-------------------------------------------------------------------------------------------------- void MessagePanel::showError(QString error) { - convertStringToHTML(&error); + convertStringToHTML(&error); - QString str = ""; - str += error; - str += ""; + QString str = ""; + str += error; + str += ""; - m_textEdit->append(str); + m_textEdit->append(str); } @@ -123,8 +123,8 @@ void MessagePanel::showError(QString error) //-------------------------------------------------------------------------------------------------- void MessagePanel::convertStringToHTML(QString* str) { - str->replace("\n", "
"); - str->replace(" ", " "); + str->replace("\n", "
"); + str->replace(" ", " "); } @@ -143,15 +143,15 @@ QSize MessagePanel::sizeHint () const //-------------------------------------------------------------------------------------------------- bool MessagePanel::isVisibleToUser() { - if (!isVisible()) return false; + if (!isVisible()) return false; - if (!m_textEdit) return false; - if (!m_textEdit->isVisible()) return false; + if (!m_textEdit) return false; + if (!m_textEdit->isVisible()) return false; - QRegion rgn = m_textEdit->visibleRegion(); - if (rgn.isEmpty()) return false; + QRegion rgn = m_textEdit->visibleRegion(); + if (rgn.isEmpty()) return false; - return true; + return true; } //-------------------------------------------------------------------------------------------------- diff --git a/Fwk/AppFwk/CommonCode/cafMessagePanel.h b/Fwk/AppFwk/CommonCode/cafMessagePanel.h index 65ab380145..cbc084eeae 100644 --- a/Fwk/AppFwk/CommonCode/cafMessagePanel.h +++ b/Fwk/AppFwk/CommonCode/cafMessagePanel.h @@ -52,27 +52,27 @@ namespace caf { //================================================================================================== class MessagePanel : public QWidget { - Q_OBJECT + Q_OBJECT public: - MessagePanel(QDockWidget* parent); + MessagePanel(QDockWidget* parent); static MessagePanel* instance(); - void showInfo(QString info); - void showWarning(QString warn); - void showError(QString error); + void showInfo(QString info); + void showWarning(QString warn); + void showError(QString error); - virtual QSize sizeHint () const; - bool isVisibleToUser(); + virtual QSize sizeHint () const; + bool isVisibleToUser(); private: - static void convertStringToHTML(QString* str); + static void convertStringToHTML(QString* str); private: static MessagePanel* sm_messagePanelInstance; - QTextEdit* m_textEdit; + QTextEdit* m_textEdit; }; } diff --git a/Fwk/AppFwk/CommonCode/cafMouseState.cpp b/Fwk/AppFwk/CommonCode/cafMouseState.cpp index a14040b23d..da4f6ccf64 100644 --- a/Fwk/AppFwk/CommonCode/cafMouseState.cpp +++ b/Fwk/AppFwk/CommonCode/cafMouseState.cpp @@ -63,7 +63,7 @@ namespace caf { //-------------------------------------------------------------------------------------------------- QtMouseState::QtMouseState() { - m_cleanButtonClickTolerance = 3; + m_cleanButtonClickTolerance = 3; reset(); } @@ -200,12 +200,12 @@ void QtMouseState::updateFromMouseEvent(QGraphicsSceneMouseEvent* event) //-------------------------------------------------------------------------------------------------- void QtMouseState::reset() { - m_mouseButtonState = Qt::NoButton; + m_mouseButtonState = Qt::NoButton; - m_cleanButtonPressButton = Qt::NoButton; - m_cleanButtonPressPosX = cvf::UNDEFINED_INT; + m_cleanButtonPressButton = Qt::NoButton; + m_cleanButtonPressPosX = cvf::UNDEFINED_INT; m_cleanButtonPressPosY = cvf::UNDEFINED_INT; - m_cleanButtonClickButton = Qt::NoButton; + m_cleanButtonClickButton = Qt::NoButton; } @@ -214,7 +214,7 @@ void QtMouseState::reset() //-------------------------------------------------------------------------------------------------- Qt::MouseButtons QtMouseState::mouseButtonState() const { - return m_mouseButtonState; + return m_mouseButtonState; } @@ -223,7 +223,7 @@ Qt::MouseButtons QtMouseState::mouseButtonState() const //-------------------------------------------------------------------------------------------------- Qt::KeyboardModifiers QtMouseState::keyboardModifierFlags() const { - return m_keyboardModifierFlags; + return m_keyboardModifierFlags; } @@ -232,7 +232,7 @@ Qt::KeyboardModifiers QtMouseState::keyboardModifierFlags() const //-------------------------------------------------------------------------------------------------- Qt::MouseButton QtMouseState::cleanButtonClickButton() const { - return m_cleanButtonClickButton; + return m_cleanButtonClickButton; } @@ -241,13 +241,13 @@ Qt::MouseButton QtMouseState::cleanButtonClickButton() const //-------------------------------------------------------------------------------------------------- int QtMouseState::numMouseButtonsInState(Qt::MouseButtons buttonState) { - int iNum = 0; + int iNum = 0; - if (buttonState & Qt::LeftButton) iNum++; - if (buttonState & Qt::RightButton) iNum++; - if (buttonState & Qt::MidButton) iNum++; + if (buttonState & Qt::LeftButton) iNum++; + if (buttonState & Qt::RightButton) iNum++; + if (buttonState & Qt::MidButton) iNum++; - return iNum; + return iNum; } diff --git a/Fwk/AppFwk/CommonCode/cafUtils.cpp b/Fwk/AppFwk/CommonCode/cafUtils.cpp index 53a25f9c74..1b29cd721d 100644 --- a/Fwk/AppFwk/CommonCode/cafUtils.cpp +++ b/Fwk/AppFwk/CommonCode/cafUtils.cpp @@ -126,12 +126,12 @@ QString Utils::constructFullFileName(const QString& folder, const QString& baseF //-------------------------------------------------------------------------------------------------- QString Utils::indentString(int numSpacesToIndent, const QString& str) { - QString indentString; - indentString.fill(' ', numSpacesToIndent); + QString indentString; + indentString.fill(' ', numSpacesToIndent); - QStringList strList = str.split("\n"); + QStringList strList = str.split("\n"); - QString retStr = indentString + strList.join("\n" + indentString); + QString retStr = indentString + strList.join("\n" + indentString); return retStr; } diff --git a/Fwk/AppFwk/CommonCode/cvfStructGrid.h b/Fwk/AppFwk/CommonCode/cvfStructGrid.h index 2291415d11..9c2df1d7da 100644 --- a/Fwk/AppFwk/CommonCode/cvfStructGrid.h +++ b/Fwk/AppFwk/CommonCode/cvfStructGrid.h @@ -41,7 +41,7 @@ #include "cvfObject.h" #include "cvfVector3.h" -#include "../cafProjectDataModel/cafAppEnum.h" +#include "cafAppEnum.h" diff --git a/Fwk/AppFwk/cafAnimControl/CMakeLists.txt b/Fwk/AppFwk/cafAnimControl/CMakeLists.txt index fd29f60e11..fa400a77e2 100644 --- a/Fwk/AppFwk/cafAnimControl/CMakeLists.txt +++ b/Fwk/AppFwk/cafAnimControl/CMakeLists.txt @@ -2,6 +2,10 @@ cmake_minimum_required (VERSION 2.8) project (cafAnimControl) +# Qt +find_package ( Qt4 COMPONENTS QtCore QtGui QtMain ) +include (${QT_USE_FILE}) + set( QOBJECT_HEADERS cafFrameAnimationControl.h cafAnimationToolBar.h diff --git a/Fwk/AppFwk/cafAnimControl/cafFrameAnimationControl.cpp b/Fwk/AppFwk/cafAnimControl/cafFrameAnimationControl.cpp index e834d9d241..71ec537a8c 100644 --- a/Fwk/AppFwk/cafAnimControl/cafFrameAnimationControl.cpp +++ b/Fwk/AppFwk/cafAnimControl/cafFrameAnimationControl.cpp @@ -157,6 +157,19 @@ int FrameAnimationControl::currentFrame() const return m_currentFrame; } +//-------------------------------------------------------------------------------------------------- +/// Set current frame without emitting signal +/// Used when views are linked and need to update current frame without emitting a signal +/// Emitting a signal will cause infinite recursion +//-------------------------------------------------------------------------------------------------- +void FrameAnimationControl::setCurrentFrameOnly(int frameIndex) +{ + if (frameIndex >= 0) + { + m_currentFrame = frameIndex; + } +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/Fwk/AppFwk/cafAnimControl/cafFrameAnimationControl.h b/Fwk/AppFwk/cafAnimControl/cafFrameAnimationControl.h index 89023c76e6..f24ad7dba7 100644 --- a/Fwk/AppFwk/cafAnimControl/cafFrameAnimationControl.h +++ b/Fwk/AppFwk/cafAnimControl/cafFrameAnimationControl.h @@ -58,6 +58,7 @@ class FrameAnimationControl : public QObject void setNumFrames(int numFrames); int numFrames() const; int currentFrame() const; + void setCurrentFrameOnly(int frameIndex); bool isActive() const; diff --git a/Fwk/AppFwk/cafCommand/CMakeLists.txt b/Fwk/AppFwk/cafCommand/CMakeLists.txt new file mode 100644 index 0000000000..21131db0fa --- /dev/null +++ b/Fwk/AppFwk/cafCommand/CMakeLists.txt @@ -0,0 +1,72 @@ +cmake_minimum_required (VERSION 2.8) + +# Qt +find_package ( Qt4 COMPONENTS QtCore QtGui QtMain ) +include (${QT_USE_FILE}) + +project (cafCommand) + +include_directories( + ${cafProjectDataModel_SOURCE_DIR} +) + +include_directories ( + ${cafPdmCore_SOURCE_DIR} + ${cafPdmUiCore_SOURCE_DIR} + ${cafPdmXml_SOURCE_DIR} + . +) + +# These headers need to go through Qt's MOC compiler +set( QOBJECT_HEADERS + cafCmdFeature.h + cafCmdFeatureManager.h +) + +if ( (${CMAKE_VERSION} VERSION_LESS 2.8.6) OR (NOT CMAKE_AUTOMOC) ) + qt4_wrap_cpp( MOC_FILES_CPP ${QOBJECT_HEADERS} ) +endif() + +set( PROJECT_FILES + + cafCmdExecCommandManager.cpp + cafCmdExecCommandManager.h + cafCmdExecuteCommand.h + cafCmdUiCommandSystemImpl.h + cafCmdUiCommandSystemImpl.cpp + + # Default features + defaultfeatures/cafCmdAddItemExec.cpp + defaultfeatures/cafCmdAddItemExec.h + defaultfeatures/cafCmdAddItemExecData.cpp + defaultfeatures/cafCmdAddItemExecData.h + defaultfeatures/cafCmdAddItemFeature.cpp + defaultfeatures/cafCmdAddItemFeature.h + defaultfeatures/cafCmdDeleteItemExec.cpp + defaultfeatures/cafCmdDeleteItemExec.h + defaultfeatures/cafCmdDeleteItemExecData.cpp + defaultfeatures/cafCmdDeleteItemExecData.h + defaultfeatures/cafCmdDeleteItemFeature.cpp + defaultfeatures/cafCmdDeleteItemFeature.h + + cafCmdFieldChangeExec.cpp + cafCmdFieldChangeExec.h + + cafCmdSelectionHelper.cpp + cafCmdSelectionHelper.h + cafCmdSelectionChangeExec.cpp + cafCmdSelectionChangeExec.h + + cafCmdFeature.cpp + cafCmdFeature.h + cafCmdFeatureManager.cpp + cafCmdFeatureManager.h +) + + +add_library( ${PROJECT_NAME} + ${PROJECT_FILES} + ${MOC_FILES_CPP} +) + +source_group("" FILES ${PROJECT_FILES}) \ No newline at end of file diff --git a/Fwk/AppFwk/cafCommand/CafCommandSystemSpecification.plantuml b/Fwk/AppFwk/cafCommand/CafCommandSystemSpecification.plantuml new file mode 100644 index 0000000000..ef10b5254e --- /dev/null +++ b/Fwk/AppFwk/cafCommand/CafCommandSystemSpecification.plantuml @@ -0,0 +1,165 @@ +@startuml +scale 1200 width + +class PdmUiTableEditor{ + + QMenu * buildDefaultContextMenu() + enableDefaultContextMenu(bool ); + +} + +PdmUiTableEditor ---> CmdFeatureManager :"GetQAction(id)" +PdmUiTableEditor --* QTableView + +QTableView --> NodeTableMenuCreator : signal CustomContextMenu(QMenu*) + + +NodeTableMenuCreator .. SelectionManager +NodeTableMenuCreator ---> CmdFeatureManager :"GetQAction(id)" + +class MainWindow{ + refreshAllVisibleToolbars() +} + +MainWindow --> CmdFeatureManager: refreshEnabledState() + +class SelectionManager{ + SelectionStack + CurrentTempSelection + --- + CurrentItem ? + PreHighlightSelection ? + --- + activePdmCommandFeature + +} + + +class CmdFeatureManager{ + QAction* action(commandId) + + void refreshEnabledState([commandIdList]) + void refreshCheckedState([commandIdList]) + void refreshStates([commandIdList]) + + CmdFeature* getCommandFeature(const std::string& commandId) +} + +CmdFeatureManager ----* "n" CmdFeature +CmdFeatureManager --> "get new" CmdFeatureFactory + +class CmdFeature{ + QAction* action() + QAction* action(QString customText); + + void refreshEnabledState(); + void refreshCheckedState(); +-- + slot: + void actionTriggered(bool isChecked) +} + + + +CmdFeature <|-- CmdAddItemFeature + +SelectionManager <----> CmdAddItemFeature +CmdAddItemFeature --> "create" CmdAddItemExec +CmdAddItemFeature -l-> "processExecuteCommand()" CmdExecCommandManager + + +CmdFeature -l-> CmdFeatureFactory :"register" + +CmdFeature ..> "create" CmdExecuteCommand +CmdFeature ..> "processExecuteCommand()" CmdExecCommandManager + +CmdFeature .> "Thought" CommandUserProcess +CommandUserProcess .> "Thought" CommandUi + + + + +class CmdExecuteCommand{ + virtual redo() + virtual undo() +} + +CmdExecuteCommand <|--- CmdFieldChangeExec +CmdFieldChangeExec --* CmdFieldChangeExecData +PdmObject <|- CmdFieldChangeExecData + +CmdExecuteCommand <|--- CmdAddItemExec +CmdAddItemExec --* CmdAddItemExecData +PdmObject <|- CmdAddItemExecData + + +class CmdExecCommandManager{ + void activateCommandSystem(); + + + void enableUndoCommandSystem(bool enable); + QUndoStack* undoStack(); + + void processExecuteCommand( CmdExecuteCommand* cmd) + void processExecuteCommandsAsMacro(const QString& macroName, + std::vector& commands); +} + + +CmdExecCommandManager --* "n" CmdExecuteCommand + +package "Project Data Model UI" { +class PdmUiFieldEditorHandle + +PdmUiFieldEditorHandle -> PdmUiCommandSystemProxy : setUiValueToField() + + +class PdmUiCommandSystemProxy +note right +If the commandinterface object is set, +delegate handling of field changed events to this object +If no commandinterface, +perform basic field change on a single field +end note + +class PdmUiCommandSystemProxy{ + void setCommandInterface(PdmUiCommandFeatureInterface* undoCommandInterface); + + void setUiValueToField(PdmUiFieldHandle* uiFieldHandle, const QVariant& newUiValue); + void populateMenu(const QString& uiConfigName, QMenu* menu); +} + +PdmUiCommandSystemProxy "Process Ui requests" ..> PdmUiCommandFeatureInterface + +} + +class PdmUiCommandFeatureInterface{ + virtual void fieldChangedCommand(PdmFieldHandle* field, const QVariant& newUiValue) = 0; + virtual void populateMenu(const QString& uiConfigName, QMenu* menu) = 0; +} + +CmdFieldChangeExec --> CmdExecCommandManager +CmdExecCommandManager "Registers command interface" .> PdmUiCommandSystemProxy + +PdmUiCommandFeatureInterface <|- CmdUiCommandSystemImpl + +class CmdUiCommandSystemImpl +note bottom +fieldChangedCommand interacts with selection system +to find all selected fields with same keyword as being edited +creates N CmdFieldChangeExec commands, and insert into undo stack if needed + +populateMenu creates the UI menu for default commands (add item/delete item) +end note + +class CmdUiCommandSystemImpl{ + virtual void fieldChangedCommand(PdmFieldHandle* field, const QVariant& newUiValue); + virtual void populateMenu(const QString& uiConfigName, QMenu* menu); + virtual bool isUndoEnabled(); +} + +CmdUiCommandSystemImpl ----* "n" CmdFieldChangeExec + + +@enduml + \ No newline at end of file diff --git a/Fwk/AppFwk/cafCommand/cafCmdExecCommandManager.cpp b/Fwk/AppFwk/cafCommand/cafCmdExecCommandManager.cpp new file mode 100644 index 0000000000..b307849681 --- /dev/null +++ b/Fwk/AppFwk/cafCommand/cafCmdExecCommandManager.cpp @@ -0,0 +1,206 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2013 Ceetron AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + + +#include "cafCmdExecCommandManager.h" + +#include "cafCmdExecuteCommand.h" +#include "cafCmdFieldChangeExec.h" +#include "cafCmdUiCommandSystemImpl.h" +#include "cafPdmUiCommandSystemProxy.h" + +#include + +//-------------------------------------------------------------------------------------------------- +/// Classed used to take over ownership of an execute command and wrap it in a QUndoCommand +//-------------------------------------------------------------------------------------------------- +class UndoRedoWrapper : public QUndoCommand +{ +public: + UndoRedoWrapper(caf::CmdExecuteCommand* executeCommand) + { + m_executeCommand = executeCommand; + + setText(m_executeCommand->name()); + } + + ~UndoRedoWrapper() + { + delete m_executeCommand; + } + + //-------------------------------------------------------------------------------------------------- + /// + //-------------------------------------------------------------------------------------------------- + virtual void undo() + { + m_executeCommand->undo(); + } + + //-------------------------------------------------------------------------------------------------- + /// + //-------------------------------------------------------------------------------------------------- + virtual void redo() + { + m_executeCommand->redo(); + } + + +private: + caf::CmdExecuteCommand* m_executeCommand; +}; + + +namespace caf +{ + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +CmdExecCommandManager::CmdExecCommandManager() +{ + m_commandFeatureInterface = NULL; + + m_undoStack = new QUndoStack(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +CmdExecCommandManager* CmdExecCommandManager::instance() +{ + static CmdExecCommandManager* singleton = new CmdExecCommandManager; + return singleton; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void CmdExecCommandManager::activateCommandSystem() +{ + if (!m_commandFeatureInterface) + { + m_commandFeatureInterface = new CmdUiCommandSystemImpl; + PdmUiCommandSystemProxy::instance()->setCommandInterface(m_commandFeatureInterface); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void CmdExecCommandManager::enableUndoCommandSystem(bool enable) +{ + this->activateCommandSystem(); + + m_commandFeatureInterface->enableUndoFeature(enable); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QUndoStack* CmdExecCommandManager::undoStack() +{ + return m_undoStack; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void CmdExecCommandManager::processExecuteCommand(CmdExecuteCommand* executeCommand) +{ + bool useUndo = false; + + if (dynamic_cast(executeCommand) && m_commandFeatureInterface->disableUndoForFieldChange()) + { + useUndo = false; + } + else if (m_commandFeatureInterface && m_commandFeatureInterface->isUndoEnabled()) + { + useUndo = true; + } + + if (useUndo) + { + // Transfer ownership of execute command to wrapper object + UndoRedoWrapper* undoRedoWrapper = new UndoRedoWrapper(executeCommand); + + m_undoStack->push(undoRedoWrapper); + } + else + { + // Execute command and delete the execute command + + executeCommand->redo(); + delete executeCommand; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void CmdExecCommandManager::processExecuteCommandsAsMacro(const QString& macroName, std::vector& commands) +{ + if (commands.size() == 0) + { + return; + } + + if (m_commandFeatureInterface && m_commandFeatureInterface->isUndoEnabled()) + { + m_undoStack->beginMacro(macroName); + for (size_t i = 0; i < commands.size(); i++) + { + UndoRedoWrapper* undoRedoWrapper = new UndoRedoWrapper(commands[i]); + m_undoStack->push(undoRedoWrapper); + } + m_undoStack->endMacro(); + } + else + { + for (size_t i = 0; i < commands.size(); i++) + { + CmdExecuteCommand* executeCommand = commands[i]; + if (executeCommand) + { + executeCommand->redo(); + delete executeCommand; + } + } + } +} + + +} // end namespace caf diff --git a/Fwk/AppFwk/cafCommand/cafCmdExecCommandManager.h b/Fwk/AppFwk/cafCommand/cafCmdExecCommandManager.h new file mode 100644 index 0000000000..649e554c89 --- /dev/null +++ b/Fwk/AppFwk/cafCommand/cafCmdExecCommandManager.h @@ -0,0 +1,86 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2013 Ceetron AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + + +#pragma once +#include + +class QUndoStack; +class QString; + +namespace caf +{ + +class CmdExecuteCommand; +class CmdUiCommandSystemImpl; + +//================================================================================================== +/// +//================================================================================================== +class CmdExecCommandManager +{ +public: + static CmdExecCommandManager* instance(); + + // Creates the object (CmdUiCommandSystemImpl) used to communicate from UI editors to advanced parts of the command system + // This includes support for undo system and default command features for add/delete of items in PdmChildArrayFieldHandle + // and creation of field changed commands so a change in an editor can be put into undo/redo + // CmdUiCommandSystemImpl is a requirement for using the undo system + void activateCommandSystem(); + + // When the undoFeature is enabled, execute commands are inserted in the undo stack + // The application can use the QUndoStack to display/modify execute commands wrapped in QUndoCommand objects + void enableUndoCommandSystem(bool enable); + QUndoStack* undoStack(); + + // If undo system is enabled, the PdmExecuteCommand is wrapped in a QUndoCommand and inserted in the QUndoStack. + // If undo is not possible (undo system not enabled, or pdm object has disabled undo), + // the PdmExecuteCommand is executed and deleted + void processExecuteCommand(CmdExecuteCommand* executeCommand); + void processExecuteCommandsAsMacro(const QString& macroName, std::vector& commands); + +private: + CmdExecCommandManager(); + +private: + QUndoStack* m_undoStack; + + CmdUiCommandSystemImpl* m_commandFeatureInterface; +}; + + + +} // end namespace caf diff --git a/Fwk/AppFwk/cafCommand/cafCmdExecuteCommand.h b/Fwk/AppFwk/cafCommand/cafCmdExecuteCommand.h new file mode 100644 index 0000000000..6fe6e4b420 --- /dev/null +++ b/Fwk/AppFwk/cafCommand/cafCmdExecuteCommand.h @@ -0,0 +1,72 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2013 Ceetron AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + + +#pragma once + +#include +#include + +namespace caf +{ + +class NotificationCenter; +class PdmObjectHandle; + +//================================================================================================== +/// +//================================================================================================== +class CmdExecuteCommand +{ +public: + CmdExecuteCommand(NotificationCenter* notificationCenter) + { + m_notificationCenter = notificationCenter; + } + + virtual ~CmdExecuteCommand() { }; + + virtual QString name() = 0; + virtual void redo() = 0; + virtual void undo() = 0; + +protected: + NotificationCenter* m_notificationCenter; +}; + + + +} // end namespace caf diff --git a/Fwk/AppFwk/cafCommand/cafCmdFeature.cpp b/Fwk/AppFwk/cafCommand/cafCmdFeature.cpp new file mode 100644 index 0000000000..a7fa7f18e1 --- /dev/null +++ b/Fwk/AppFwk/cafCommand/cafCmdFeature.cpp @@ -0,0 +1,121 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2014 Ceetron Solutions AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + +#include "cafCmdFeature.h" + +#include "cafCmdExecCommandManager.h" +#include "cafCmdFeatureManager.h" + +#include + +#include + + +namespace caf +{ + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QAction* CmdFeature::action() +{ + return this->action(QString("")); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QAction* CmdFeature::action(QString customText) +{ + QAction* action = NULL; + + std::map::iterator it; + it = m_customTextToActionMap.find(customText); + + if (it != m_customTextToActionMap.end() && it->second != NULL) + { + action = it->second; + } + else + { + action = new QAction(this); + connect(action, SIGNAL(triggered(bool)), SLOT(actionTriggered(bool))); + m_customTextToActionMap[customText]= action; + } + + this->setupActionLook(action); + if (!customText.isEmpty()) + { + action->setText(customText); + } + + return action; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void CmdFeature::refreshEnabledState() +{ + std::map::iterator it; + bool isEnabled = this->isCommandEnabled(); + + for (it = m_customTextToActionMap.begin(); it != m_customTextToActionMap.end(); ++it) + { + it->second->setEnabled(isEnabled); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void CmdFeature::refreshCheckedState() +{ + std::map::iterator it; + bool isChecked = this->isCommandChecked(); + + for (it = m_customTextToActionMap.begin(); it != m_customTextToActionMap.end(); ++it) + { + QAction* act = it->second; + if (act->isCheckable()) + { + it->second->setChecked(isChecked); + } + } +} + +} // end namespace caf diff --git a/Fwk/AppFwk/cafCommand/cafCmdFeature.h b/Fwk/AppFwk/cafCommand/cafCmdFeature.h new file mode 100644 index 0000000000..155fe1dedb --- /dev/null +++ b/Fwk/AppFwk/cafCommand/cafCmdFeature.h @@ -0,0 +1,101 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2014 Ceetron Solution AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + + +#pragma once + +#include "cafFactory.h" + +#include +#include + +#include + +class QAction; +class QIcon; +class QString; + +#define CAF_CMD_HEADER_INIT \ + public: \ + static const std::string& idNameStatic() + +#define CAF_CMD_SOURCE_INIT(ClassName, CommandIdName)\ + const std::string& ClassName::idNameStatic() { static std::string id = CommandIdName; return id;} \ + CAF_FACTORY_REGISTER(caf::CmdFeature, ClassName, std::string, ClassName::idNameStatic()) + + +namespace caf +{ + +class CmdExecuteCommand; + +//================================================================================================== +/// 1. If a direct command with no UI is requested, create an ExecuteCommand object and execute command +/// 2. If UI is required, create a CommandUI object and display to user. When user accepts data input, +/// create an ExecuteCommand object and fill in the data provided by the user +/// 3. If a user process is required, create start an CommandUserProcess. When the process is complete, +/// create an ExecuteCommand object and fill in the data provided by the user +//================================================================================================== +class CmdFeature : public QObject +{ + Q_OBJECT +public: + CmdFeature() {} + virtual ~CmdFeature() {} + + QAction* action(); + QAction* action(QString customText); + void refreshEnabledState(); + void refreshCheckedState(); + + bool canFeatureBeExecuted() { return this->isCommandEnabled(); } + +public slots: + void actionTriggered(bool isChecked) { this->onActionTriggered(isChecked); } + +protected: + virtual void onActionTriggered(bool isChecked) = 0; + virtual void setupActionLook(QAction* actionToSetup) = 0; + virtual bool isCommandEnabled() = 0; + virtual bool isCommandChecked() { return false; } + +private: + std::map m_customTextToActionMap; +}; + + + +} // end namespace caf diff --git a/Fwk/AppFwk/cafCommand/cafCmdFeatureManager.cpp b/Fwk/AppFwk/cafCommand/cafCmdFeatureManager.cpp new file mode 100644 index 0000000000..adeb24134c --- /dev/null +++ b/Fwk/AppFwk/cafCommand/cafCmdFeatureManager.cpp @@ -0,0 +1,252 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2013 Ceetron AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + + +#include "cafCmdFeatureManager.h" + +#include "cafCmdFeature.h" +#include "cafCmdSelectionHelper.h" +#include "cafFactory.h" + +#include "defaultfeatures/cafCmdDeleteItemFeature.h" +#include "defaultfeatures/cafCmdAddItemFeature.h" + +#include + +#include + +namespace caf +{ + + typedef Factory CommandFeatureFactory; +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +CmdFeatureManager::CmdFeatureManager() +{ + CmdDeleteItemFeature::idNameStatic(); + CmdAddItemFeature::idNameStatic(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +CmdFeatureManager::~CmdFeatureManager() +{ + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +CmdFeatureManager* CmdFeatureManager::instance() +{ + static CmdFeatureManager* singleton = new CmdFeatureManager; + return singleton; +} + +//-------------------------------------------------------------------------------------------------- +/// Get action for the specified command. +/// The action is owned by the PdmCommandItemManager +//-------------------------------------------------------------------------------------------------- +QAction* CmdFeatureManager::action(const QString& commandId) +{ + std::pair featurePair = createFeature(commandId.toStdString()); + + QAction* act = featurePair.first->action(); + m_actionToFeatureIdxMap[act] = featurePair.second; + + return act; +} + +//-------------------------------------------------------------------------------------------------- +/// Get action for the specified command, with custom action text +/// The action is owned by the PdmCommandItemManager +//-------------------------------------------------------------------------------------------------- +QAction* CmdFeatureManager::action(const QString& commandId, const QString& customActionText) +{ + std::pair featurePair = createFeature(commandId.toStdString()); + + QAction* act = featurePair.first->action(customActionText); + m_actionToFeatureIdxMap[act] = featurePair.second; + + return act; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::pair CmdFeatureManager::createFeature(const std::string& commandId) +{ + std::pair featurePair = this->findExistingCmdFeature(commandId); + + if (featurePair.first) + { + return featurePair; + } + + CmdFeature* feature = CommandFeatureFactory::instance()->create(commandId); + assert(feature); // The command ID is not known in the factory + + feature->setParent(this); + size_t index = m_commandFeatures.size(); + m_commandFeatures.push_back(feature); + m_commandIdToFeatureIdxMap[commandId] = index; + + return std::make_pair(feature, index); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::pair CmdFeatureManager::findExistingCmdFeature(const std::string& commandId) +{ + std::map::const_iterator it; + it = m_commandIdToFeatureIdxMap.find(commandId); + + if (it != m_commandIdToFeatureIdxMap.end()) + { + size_t itemIndex = it->second; + + CmdFeature* item = m_commandFeatures[itemIndex]; + item->refreshEnabledState(); + + return std::make_pair(item, itemIndex); + } + else + { + return std::make_pair(static_cast(NULL), -1); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void CmdFeatureManager::refreshStates(const QStringList& commandIdList) +{ + if (commandIdList.size() == 0) + { + for (size_t i = 0; i < m_commandFeatures.size(); i++) + { + CmdFeature* cmdFeature = m_commandFeatures[i]; + + if (cmdFeature) + { + cmdFeature->refreshEnabledState(); + cmdFeature->refreshCheckedState(); + } + } + } + else + { + for (int i = 0; i < commandIdList.size(); i++) + { + std::pair featurePair = findExistingCmdFeature(commandIdList.at(i).toStdString()); + + if (featurePair.first) + { + featurePair.first->refreshEnabledState(); + featurePair.first->refreshCheckedState(); + } + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void CmdFeatureManager::refreshEnabledState(const QStringList& commandIdList) +{ + if (commandIdList.size() == 0) + { + for (size_t i = 0; i < m_commandFeatures.size(); i++) + { + m_commandFeatures[i]->refreshEnabledState(); + } + } + else + { + for (int i = 0; i < commandIdList.size(); i++) + { + std::pair featurePair = findExistingCmdFeature(commandIdList.at(i).toStdString()); + + if (featurePair.first) + { + featurePair.first->refreshEnabledState(); + } + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void CmdFeatureManager::refreshCheckedState(const QStringList& commandIdList) +{ + if (commandIdList.size() == 0) + { + for (size_t i = 0; i < m_commandFeatures.size(); i++) + { + m_commandFeatures[i]->refreshCheckedState(); + } + } + else + { + for (int i = 0; i < commandIdList.size(); i++) + { + std::pair featurePair = findExistingCmdFeature(commandIdList.at(i).toStdString()); + + if (featurePair.first) + { + featurePair.first->refreshCheckedState(); + } + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +CmdFeature* CmdFeatureManager::getCommandFeature(const std::string& commandId) +{ + std::pair featurePair = createFeature(commandId); + + return featurePair.first; + +} + + +} // end namespace caf diff --git a/Fwk/AppFwk/cafCommand/cafCmdFeatureManager.h b/Fwk/AppFwk/cafCommand/cafCmdFeatureManager.h new file mode 100644 index 0000000000..9dbdf51118 --- /dev/null +++ b/Fwk/AppFwk/cafCommand/cafCmdFeatureManager.h @@ -0,0 +1,88 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2013 Ceetron AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + + +#pragma once + +#include +#include +#include + +#include +#include + +class QAction; + +namespace caf +{ + +class CmdFeature; + +//================================================================================================== +/// +//================================================================================================== +class CmdFeatureManager : public QObject +{ + Q_OBJECT + +public: + static CmdFeatureManager* instance(); + virtual ~CmdFeatureManager(); + + QAction* action(const QString& commandId); + QAction* action(const QString& commandId, const QString& actionText); + + void refreshStates(const QStringList& commandIdList = QStringList()); + void refreshEnabledState(const QStringList& commandIdList = QStringList()); + void refreshCheckedState(const QStringList& commandIdList = QStringList()); + + CmdFeature* getCommandFeature(const std::string& commandId); + +private: + CmdFeatureManager(); + + std::pair createFeature(const std::string& commandId); + std::pair findExistingCmdFeature(const std::string& commandId); + + std::vector m_commandFeatures; + std::map m_commandIdToFeatureIdxMap; + std::map m_actionToFeatureIdxMap; + +}; + + + +} // end namespace caf diff --git a/Fwk/AppFwk/cafCommand/cafCmdFieldChangeExec.cpp b/Fwk/AppFwk/cafCommand/cafCmdFieldChangeExec.cpp new file mode 100644 index 0000000000..6b23801183 --- /dev/null +++ b/Fwk/AppFwk/cafCommand/cafCmdFieldChangeExec.cpp @@ -0,0 +1,216 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2013 Ceetron AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + + +#include "cafCmdFieldChangeExec.h" + +#include "cafPdmReferenceHelper.h" +#include "cafNotificationCenter.h" + + +namespace caf +{ + +CAF_PDM_SOURCE_INIT(CmdFieldChangeExecData, "CmdFieldChangeExecData"); + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString CmdFieldChangeExec::name() +{ + PdmFieldHandle* field = PdmReferenceHelper::fieldFromReference(m_commandData->m_rootObject, m_commandData->m_pathToField); + if (field) + { + QString fieldText; + + PdmUiFieldHandle* uiFieldHandle = field->uiCapability(); + if (uiFieldHandle) + { + fieldText = QString("Change field '%1'").arg(uiFieldHandle->uiName()); + } + + if (field->ownerObject()) + { + PdmUiObjectHandle* uiObjHandle = uiObj(field->ownerObject()); + if (uiObjHandle) + { + fieldText += QString(" in '%1'").arg(uiObjHandle->uiName()); + } + } + return fieldText; + } + else + { + return m_commandData->classKeyword(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void CmdFieldChangeExec::redo() +{ + PdmFieldHandle* field = PdmReferenceHelper::fieldFromReference(m_commandData->m_rootObject, m_commandData->m_pathToField); + if (!field) + { + assert(false); + return; + } + + PdmUiFieldHandle* uiFieldHandle = field->uiCapability(); + PdmXmlFieldHandle* xmlFieldHandle = field->xmlCapability(); + if (uiFieldHandle && xmlFieldHandle) + { + if (m_commandData->m_redoFieldValueSerialized.isEmpty()) + { + { + QXmlStreamWriter xmlStream(&m_commandData->m_undoFieldValueSerialized); + writeFieldDataToValidXmlDocument(xmlStream, xmlFieldHandle); + } + + // This function will notify field change, no need to explicitly call notification + uiFieldHandle->setValueFromUi(m_commandData->m_newUiValue); + + { + QXmlStreamWriter xmlStream(&m_commandData->m_redoFieldValueSerialized); + writeFieldDataToValidXmlDocument(xmlStream, xmlFieldHandle); + } + } + else + { + QVariant oldFieldData = uiFieldHandle->toUiBasedQVariant(); + + QXmlStreamReader xmlStream(m_commandData->m_redoFieldValueSerialized); + + readFieldValueFromValidXmlDocument(xmlStream, xmlFieldHandle); + + QVariant newFieldData = uiFieldHandle->toUiBasedQVariant(); + + // New data is present in field, notify data changed + uiFieldHandle->notifyFieldChanged(oldFieldData, newFieldData); + } + } + + if (m_notificationCenter) m_notificationCenter->notifyObserversOfDataChange(field->ownerObject()); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void CmdFieldChangeExec::undo() +{ + PdmFieldHandle* field = PdmReferenceHelper::fieldFromReference(m_commandData->m_rootObject, m_commandData->m_pathToField); + if (!field) + { + assert(false); + return; + } + + PdmUiFieldHandle* uiFieldHandle = field->uiCapability(); + PdmXmlFieldHandle* xmlFieldHandle = field->xmlCapability(); + if (uiFieldHandle && xmlFieldHandle) + { + QXmlStreamReader xmlStream(m_commandData->m_undoFieldValueSerialized); + QVariant oldFieldData = uiFieldHandle->toUiBasedQVariant(); + + readFieldValueFromValidXmlDocument(xmlStream, xmlFieldHandle); + + QVariant newFieldData = uiFieldHandle->toUiBasedQVariant(); + + // New data is present in field, notify data changed + uiFieldHandle->notifyFieldChanged(oldFieldData, newFieldData); + } + + if (m_notificationCenter) m_notificationCenter->notifyObserversOfDataChange(field->ownerObject()); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +CmdFieldChangeExec::CmdFieldChangeExec(NotificationCenter* notificationCenter) + : CmdExecuteCommand(notificationCenter) +{ + m_commandData = new CmdFieldChangeExecData; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +CmdFieldChangeExec::~CmdFieldChangeExec() +{ + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +CmdFieldChangeExecData* CmdFieldChangeExec::commandData() +{ + return m_commandData; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void CmdFieldChangeExec::writeFieldDataToValidXmlDocument(QXmlStreamWriter &xmlStream, PdmXmlFieldHandle* xmlFieldHandle) +{ + xmlStream.setAutoFormatting(true); + xmlStream.writeStartDocument(); + xmlStream.writeStartElement("", "d"); + xmlFieldHandle->writeFieldData(xmlStream); + xmlStream.writeEndElement(); + xmlStream.writeEndDocument(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void CmdFieldChangeExec::readFieldValueFromValidXmlDocument(QXmlStreamReader &xmlStream, PdmXmlFieldHandle* xmlFieldHandle) +{ + // See PdmObject::readFields and friends to match token count for reading field values + // The stream is supposed to be pointing at the first token of field content when calling readFieldData() + QXmlStreamReader::TokenType tt; + int tokenCount = 3; + for (int i = 0; i < tokenCount; i++) + { + tt = xmlStream.readNext(); + } + xmlFieldHandle->readFieldData(xmlStream, PdmDefaultObjectFactory::instance()); +} + +} // end namespace caf diff --git a/Fwk/AppFwk/cafCommand/cafCmdFieldChangeExec.h b/Fwk/AppFwk/cafCommand/cafCmdFieldChangeExec.h new file mode 100644 index 0000000000..3a503ec0aa --- /dev/null +++ b/Fwk/AppFwk/cafCommand/cafCmdFieldChangeExec.h @@ -0,0 +1,99 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2013 Ceetron AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + +#pragma once + +#include "cafCmdExecuteCommand.h" +#include "cafPdmField.h" +#include "cafPdmObject.h" + +namespace caf +{ + +class PdmChildArrayFieldHandle; + +//================================================================================================== +/// +//================================================================================================== +class CmdFieldChangeExecData : public PdmObject +{ + CAF_PDM_HEADER_INIT; + +public: + CmdFieldChangeExecData() + { + CAF_PDM_InitObject("CmdFieldChangeExecData uiName", "", "CmdFieldChangeExecData tooltip", "CmdFieldChangeExecData whatsthis"); + + CAF_PDM_InitField(&m_pathToField, "PathToField", QString(), "PathToField", "", "PathToField tooltip", "PathToField whatsthis"); + } + + caf::PdmPointer m_rootObject; + + PdmField m_pathToField; + QVariant m_newUiValue; // QVariant coming from the UI + + QString m_undoFieldValueSerialized; + QString m_redoFieldValueSerialized; +}; + + +//================================================================================================== +/// +//================================================================================================== +class CmdFieldChangeExec : public CmdExecuteCommand +{ +public: + CmdFieldChangeExec(NotificationCenter* notificationCenter); + virtual ~CmdFieldChangeExec(); + + + CmdFieldChangeExecData* commandData(); + + virtual QString name(); + virtual void redo(); + virtual void undo(); + +private: + void readFieldValueFromValidXmlDocument(QXmlStreamReader& xmlStream, PdmXmlFieldHandle* xmlFieldHandle); + void writeFieldDataToValidXmlDocument(QXmlStreamWriter& xmlStream, PdmXmlFieldHandle* xmlFieldHandle); + +private: + CmdFieldChangeExecData* m_commandData; +}; + + + +} // end namespace caf diff --git a/Fwk/AppFwk/cafCommand/cafCmdSelectionChangeExec.cpp b/Fwk/AppFwk/cafCommand/cafCmdSelectionChangeExec.cpp new file mode 100644 index 0000000000..c7f6636047 --- /dev/null +++ b/Fwk/AppFwk/cafCommand/cafCmdSelectionChangeExec.cpp @@ -0,0 +1,109 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2013 Ceetron AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + + +#include "cafCmdSelectionChangeExec.h" +#include "cafPdmReferenceHelper.h" + + +namespace caf +{ + + + template<> + void AppEnum::setUp() + { + addItem(SelectionManager::APPLICATION_GLOBAL, "APPLICATION_GLOBAL", "APPLICATION_GLOBAL"); + addItem(SelectionManager::CURRENT, "CURRENT", "CURRENT"); + addItem(SelectionManager::UNDEFINED, "UNDEFINED", "UNDEFINED"); + setDefault(SelectionManager::UNDEFINED); + } + +CAF_PDM_SOURCE_INIT(CmdSelectionChangeExecData, "CmdSelectionChangeExecData"); + + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString CmdSelectionChangeExec::name() +{ + return m_commandData->classKeyword(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void CmdSelectionChangeExec::redo() +{ + SelectionManager::instance()->setSelectionFromReferences(m_commandData->m_newSelection.v(), m_commandData->m_selectionRole.v()); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void CmdSelectionChangeExec::undo() +{ + SelectionManager::instance()->setSelectionFromReferences(m_commandData->m_previousSelection.v(), m_commandData->m_selectionRole.v()); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +CmdSelectionChangeExec::CmdSelectionChangeExec(NotificationCenter* notificationCenter) + : CmdExecuteCommand(notificationCenter) +{ + m_commandData = new CmdSelectionChangeExecData; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +CmdSelectionChangeExec::~CmdSelectionChangeExec() +{ + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +CmdSelectionChangeExecData* CmdSelectionChangeExec::commandData() +{ + return m_commandData; +} + +} // end namespace caf diff --git a/Fwk/AppFwk/cafCommand/cafCmdSelectionChangeExec.h b/Fwk/AppFwk/cafCommand/cafCmdSelectionChangeExec.h new file mode 100644 index 0000000000..c485a09402 --- /dev/null +++ b/Fwk/AppFwk/cafCommand/cafCmdSelectionChangeExec.h @@ -0,0 +1,96 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2013 Ceetron AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + +#pragma once + +#include "cafCmdExecuteCommand.h" + +#include "cafPdmField.h" +#include "cafPdmObject.h" +#include "cafSelectionManager.h" +#include "cafAppEnum.h" + + +namespace caf +{ + + + +//================================================================================================== +/// +//================================================================================================== +class CmdSelectionChangeExecData : public PdmObject +{ + CAF_PDM_HEADER_INIT; + +public: + CmdSelectionChangeExecData() + { + CAF_PDM_InitObject("CmdSelectionChangeExecData uiName", "", "CmdSelectionChangeExecData tooltip", "CmdSelectionChangeExecData whatsthis"); + + CAF_PDM_InitFieldNoDefault(&m_selectionRole, "selectionRole", "selectionRole", "", "", ""); + CAF_PDM_InitField(&m_previousSelection, "previousSelection", std::vector(), "previousSelection", "", "", ""); + CAF_PDM_InitField(&m_newSelection, "newSelection", std::vector(), "newSelection", "", "", ""); + } + + PdmField< AppEnum > m_selectionRole; + PdmField< std::vector > m_previousSelection; + PdmField< std::vector > m_newSelection; +}; + + +//================================================================================================== +/// +//================================================================================================== +class CmdSelectionChangeExec : public CmdExecuteCommand +{ +public: + CmdSelectionChangeExec(NotificationCenter* notificationCenter); + virtual ~CmdSelectionChangeExec();; + + CmdSelectionChangeExecData* commandData(); + + virtual QString name(); + virtual void redo(); + virtual void undo(); + +private: + CmdSelectionChangeExecData* m_commandData; +}; + + + +} // end namespace caf diff --git a/Fwk/AppFwk/cafCommand/cafCmdSelectionHelper.cpp b/Fwk/AppFwk/cafCommand/cafCmdSelectionHelper.cpp new file mode 100644 index 0000000000..da4496fd50 --- /dev/null +++ b/Fwk/AppFwk/cafCommand/cafCmdSelectionHelper.cpp @@ -0,0 +1,76 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2013 Ceetron AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + + +#include "cafCmdSelectionHelper.h" + +#include "cafCmdExecCommandManager.h" +#include "cafCmdSelectionChangeExec.h" + + +namespace caf +{ + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void CmdSelectionHelper::executeSelectionCommand(std::vector selection, SelectionManager::SelectionRole role) +{ + CmdSelectionChangeExec* selectionChangeExec = createSelectionCommand(selection, role); + + CmdExecCommandManager::instance()->processExecuteCommand(selectionChangeExec); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +CmdSelectionChangeExec* CmdSelectionHelper::createSelectionCommand(const std::vector& selection, SelectionManager::SelectionRole role) +{ + CmdSelectionChangeExec* selectionChangeExec = new CmdSelectionChangeExec(SelectionManager::instance()->notificationCenter()); + selectionChangeExec->commandData()->m_selectionRole.v() = role; + SelectionManager::instance()->selectionAsReferences(selectionChangeExec->commandData()->m_previousSelection.v(), role); + + for (size_t i = 0; i < selection.size(); i++) + { + QString itemRef = PdmReferenceHelper::referenceFromRootToObject(PdmReferenceHelper::findRoot(selection[i]), selection[i]); + selectionChangeExec->commandData()->m_newSelection.v().push_back(itemRef); + } + + return selectionChangeExec; +} + + +} // end namespace caf diff --git a/Fwk/AppFwk/cafCommand/cafCmdSelectionHelper.h b/Fwk/AppFwk/cafCommand/cafCmdSelectionHelper.h new file mode 100644 index 0000000000..eb8698a0e1 --- /dev/null +++ b/Fwk/AppFwk/cafCommand/cafCmdSelectionHelper.h @@ -0,0 +1,58 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2013 Ceetron AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + + +#pragma once + +#include "cafSelectionManager.h" + +#include + + +namespace caf +{ +class CmdSelectionChangeExec; + +class CmdSelectionHelper +{ +public: + static void executeSelectionCommand(std::vector selection, SelectionManager::SelectionRole role); + static CmdSelectionChangeExec* createSelectionCommand(const std::vector& selection, SelectionManager::SelectionRole role); +}; + + + +} // end namespace caf diff --git a/Fwk/AppFwk/cafCommand/cafCmdUiCommandSystemImpl.cpp b/Fwk/AppFwk/cafCommand/cafCmdUiCommandSystemImpl.cpp new file mode 100644 index 0000000000..b61080db31 --- /dev/null +++ b/Fwk/AppFwk/cafCommand/cafCmdUiCommandSystemImpl.cpp @@ -0,0 +1,205 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2013 Ceetron AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + + +#include "cafCmdUiCommandSystemImpl.h" + +#include "cafCmdExecCommandManager.h" +#include "cafCmdExecuteCommand.h" +#include "cafCmdFieldChangeExec.h" +#include "cafCmdFeatureManager.h" + +#include "cafPdmFieldHandle.h" +#include "cafPdmUiObjectHandle.h" + +#include "cafSelectionManager.h" + +#include + +#include + +namespace caf +{ + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +CmdUiCommandSystemImpl::CmdUiCommandSystemImpl() +{ + m_undoFeatureEnabled = false; + m_disableUndoForFieldChange = false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void CmdUiCommandSystemImpl::fieldChangedCommand(PdmFieldHandle* editorField, const QVariant& newUiValue) +{ + std::vector fieldsToUpdate; + fieldsToUpdate.push_back(editorField); + + // For current selection, find all fields with same keyword + { + std::vector items; + SelectionManager::instance()->selectedItems(items, SelectionManager::CURRENT); + + for (size_t i = 0; i < items.size(); i++) + { + PdmObjectHandle* objectHandle = dynamic_cast(items[i]); + if (objectHandle) + { + // An object is selected, find field with same keyword as the current field being edited + PdmFieldHandle* fieldHandle = objectHandle->findField(editorField->keyword()); + if (fieldHandle && fieldHandle != editorField) + { + fieldsToUpdate.push_back(fieldHandle); + } + } + else + { + // A field is selected, check if keywords are identical + PdmUiFieldHandle* uiFieldHandle = dynamic_cast(items[i]); + if (uiFieldHandle) + { + PdmFieldHandle* field = uiFieldHandle->fieldHandle(); + if (field && field != editorField && field->keyword() == editorField->keyword()) + { + fieldsToUpdate.push_back(field); + } + } + } + } + } + + std::vector commands; + + for (size_t i = 0; i < fieldsToUpdate.size(); i++) + { + PdmFieldHandle* field = fieldsToUpdate[i]; + PdmUiFieldHandle* uiFieldHandle = field->uiCapability(); + if (uiFieldHandle) + { + QVariant fieldCurrentUiValue = uiFieldHandle->uiValue(); + + if (fieldCurrentUiValue != newUiValue) + { + PdmObjectHandle* rootObjHandle = PdmReferenceHelper::findRoot(field); + + QString reference = PdmReferenceHelper::referenceFromRootToField(rootObjHandle, field); + if (reference.isEmpty()) + { + assert(false); + return; + } + + CmdFieldChangeExec* fieldChangeExec = new CmdFieldChangeExec(SelectionManager::instance()->notificationCenter()); + + fieldChangeExec->commandData()->m_newUiValue = newUiValue; + fieldChangeExec->commandData()->m_pathToField = reference; + fieldChangeExec->commandData()->m_rootObject = rootObjHandle; + + commands.push_back(fieldChangeExec); + } + } + } + + caf::PdmUiObjectHandle* uiOwnerObjectHandle = uiObj(editorField->ownerObject()); + if (uiOwnerObjectHandle && !uiOwnerObjectHandle->useUndoRedoForFieldChanged()) + { + // Temporarily disable undo framework as requested by the PdmUiObjectHandle + m_disableUndoForFieldChange = true; + } + + if (commands.size() == 1) + { + CmdExecCommandManager::instance()->processExecuteCommand(commands[0]); + } + else + { + CmdExecCommandManager::instance()->processExecuteCommandsAsMacro("Multiple Field Change", commands); + } + + if (uiOwnerObjectHandle && !uiOwnerObjectHandle->useUndoRedoForFieldChanged()) + { + // Restore undo feature to normal operation + m_disableUndoForFieldChange = false; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void CmdUiCommandSystemImpl::populateMenuWithDefaultCommands(const QString& uiConfigName, QMenu* menu) +{ + if (uiConfigName == "PdmUiTreeViewEditor" || + uiConfigName == "PdmUiTableViewEditor") + { + caf::CmdFeatureManager* commandManager = caf::CmdFeatureManager::instance(); + + menu->addAction(commandManager->action("PdmListField_AddItem")); + menu->addAction(commandManager->action("PdmListField_DeleteItem")); + + QStringList commandIdList; + commandIdList << "PdmListField_AddItem" << "PdmListField_DeleteItem"; + commandManager->refreshStates(commandIdList); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool CmdUiCommandSystemImpl::isUndoEnabled() +{ + return m_undoFeatureEnabled; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void CmdUiCommandSystemImpl::enableUndoFeature(bool enable) +{ + m_undoFeatureEnabled = enable; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool CmdUiCommandSystemImpl::disableUndoForFieldChange() +{ + return m_disableUndoForFieldChange; +} + +} // end namespace caf diff --git a/Fwk/AppFwk/cafCommand/cafCmdUiCommandSystemImpl.h b/Fwk/AppFwk/cafCommand/cafCmdUiCommandSystemImpl.h new file mode 100644 index 0000000000..40fb1c787d --- /dev/null +++ b/Fwk/AppFwk/cafCommand/cafCmdUiCommandSystemImpl.h @@ -0,0 +1,67 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2013 Ceetron AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + + +#pragma once + +#include "cafInternalPdmUiCommandSystemInterface.h" + + +namespace caf +{ + +class PdmFieldHandle; + +class CmdUiCommandSystemImpl : public PdmUiCommandSystemInterface +{ +public: + CmdUiCommandSystemImpl(); + + virtual void fieldChangedCommand(PdmFieldHandle* field, const QVariant& newUiValue); + virtual void populateMenuWithDefaultCommands(const QString& uiConfigName, QMenu* menu); + + bool isUndoEnabled(); + void enableUndoFeature(bool enable); + + bool disableUndoForFieldChange(); + +private: + bool m_undoFeatureEnabled; + bool m_disableUndoForFieldChange; +}; + + +} // end namespace caf diff --git a/Fwk/AppFwk/cafCommand/defaultfeatures/cafCmdAddItemExec.cpp b/Fwk/AppFwk/cafCommand/defaultfeatures/cafCmdAddItemExec.cpp new file mode 100644 index 0000000000..242aba4898 --- /dev/null +++ b/Fwk/AppFwk/cafCommand/defaultfeatures/cafCmdAddItemExec.cpp @@ -0,0 +1,178 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2013 Ceetron AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + + +#include "cafCmdAddItemExec.h" + +#include "cafCmdAddItemExecData.h" + +#include "cafNotificationCenter.h" +#include "cafPdmReferenceHelper.h" +#include "cafSelectionManager.h" + +#include "cafPdmChildArrayField.h" + + + +namespace caf +{ + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString CmdAddItemExec::name() +{ + PdmFieldHandle* field = PdmReferenceHelper::fieldFromReference(m_commandData->m_rootObject, m_commandData->m_pathToField); + + QString containedObjectType = "object"; + + PdmChildArrayFieldHandle* listField = dynamic_cast(field); + if (listField) + { + PdmXmlFieldHandle* xfh = listField->xmlCapability(); + containedObjectType = xfh->childClassKeyword(); + } + + return QString("Create new '%1'").arg(containedObjectType); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void CmdAddItemExec::redo() +{ + PdmFieldHandle* field = PdmReferenceHelper::fieldFromReference(m_commandData->m_rootObject, m_commandData->m_pathToField); + + PdmChildArrayFieldHandle* listField = dynamic_cast(field); + if (listField && field->xmlCapability()) + { + QString classKeyword = field->xmlCapability()->childClassKeyword(); + + if (classKeyword.isEmpty()) return; + + caf::PdmObjectHandle* obj = PdmDefaultObjectFactory::instance()->create(classKeyword); + + if (!obj) return; + + listField->insertAt(m_commandData->m_indexAfter, obj); + caf::PdmUiObjectHandle* uiObject = uiObj(obj); + + if (m_commandData->m_indexAfter == -1) + { + m_commandData->m_createdItemIndex = static_cast(listField->size() - 1); + } + else + { + m_commandData->m_createdItemIndex = m_commandData->m_indexAfter; + } + + if (m_notificationCenter) m_notificationCenter->notifyObserversOfDataChange(obj); + + listField->uiCapability()->updateConnectedEditors(); + + if (listField->ownerObject()) + { + caf::PdmUiObjectHandle* ownerUiObject = uiObj(listField->ownerObject()); + if (ownerUiObject) + { + ownerUiObject->fieldChangedByUi(listField, QVariant(), QVariant()); + } + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void CmdAddItemExec::undo() +{ + PdmFieldHandle* field = PdmReferenceHelper::fieldFromReference(m_commandData->m_rootObject, m_commandData->m_pathToField); + + PdmChildArrayFieldHandle* listField = dynamic_cast(field); + if (listField && m_commandData->m_createdItemIndex >= 0) + { + std::vector children; + listField->childObjects(&children); + + caf::PdmObjectHandle* obj = children[m_commandData->m_createdItemIndex]; + + caf::SelectionManager::instance()->removeObjectFromAllSelections(obj); + + listField->erase(m_commandData->m_createdItemIndex); + listField->uiCapability()->updateConnectedEditors(); + + if (m_notificationCenter) m_notificationCenter->notifyObservers(); + + if (listField->ownerObject()) + { + caf::PdmUiObjectHandle* ownerUiObject = uiObj(listField->ownerObject()); + if (ownerUiObject) + { + ownerUiObject->fieldChangedByUi(listField, QVariant(), QVariant()); + } + } + + delete obj; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +CmdAddItemExec::CmdAddItemExec(NotificationCenter* notificationCenter) + : CmdExecuteCommand(notificationCenter) +{ + m_commandData = new CmdAddItemExecData; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +CmdAddItemExec::~CmdAddItemExec() +{ + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +CmdAddItemExecData* CmdAddItemExec::commandData() +{ + return m_commandData; +} + +} // end namespace caf diff --git a/Fwk/AppFwk/cafCommand/defaultfeatures/cafCmdAddItemExec.h b/Fwk/AppFwk/cafCommand/defaultfeatures/cafCmdAddItemExec.h new file mode 100644 index 0000000000..aaf23ab4a1 --- /dev/null +++ b/Fwk/AppFwk/cafCommand/defaultfeatures/cafCmdAddItemExec.h @@ -0,0 +1,69 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2013 Ceetron AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + + +#pragma once + +#include "cafCmdExecuteCommand.h" + +namespace caf +{ + +class PdmChildArrayFieldHandle; +class CmdAddItemExecData; + +//================================================================================================== +/// +//================================================================================================== +class CmdAddItemExec : public CmdExecuteCommand +{ +public: + CmdAddItemExec(NotificationCenter* notificationCenter); + virtual ~CmdAddItemExec();; + + CmdAddItemExecData* commandData(); + + virtual QString name(); + virtual void redo(); + virtual void undo(); + +private: + CmdAddItemExecData* m_commandData; +}; + + + +} // end namespace caf diff --git a/Fwk/AppFwk/cafCommand/defaultfeatures/cafCmdAddItemExecData.cpp b/Fwk/AppFwk/cafCommand/defaultfeatures/cafCmdAddItemExecData.cpp new file mode 100644 index 0000000000..2c1b99c8a0 --- /dev/null +++ b/Fwk/AppFwk/cafCommand/defaultfeatures/cafCmdAddItemExecData.cpp @@ -0,0 +1,46 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2013 Ceetron AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + + +#include "cafCmdAddItemExecData.h" + + +namespace caf +{ + +CAF_PDM_SOURCE_INIT(CmdAddItemExecData, "CmdAddItemExecData"); + +} // end namespace caf diff --git a/Fwk/AppFwk/cafCommand/defaultfeatures/cafCmdAddItemExecData.h b/Fwk/AppFwk/cafCommand/defaultfeatures/cafCmdAddItemExecData.h new file mode 100644 index 0000000000..e25baa5e5d --- /dev/null +++ b/Fwk/AppFwk/cafCommand/defaultfeatures/cafCmdAddItemExecData.h @@ -0,0 +1,73 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2013 Ceetron AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + + +#pragma once + +#include "cafPdmObject.h" +#include "cafPdmField.h" + +namespace caf +{ + + +//================================================================================================== +/// +//================================================================================================== +class CmdAddItemExecData : public PdmObject +{ + CAF_PDM_HEADER_INIT; + +public: + CmdAddItemExecData() + { + CAF_PDM_InitObject("CmdAddItemExecData uiName", "", "CmdAddItemExecData tooltip", "CmdAddItemExecData whatsthis"); + + CAF_PDM_InitField(&m_pathToField, "PathToField", QString(), "PathToField", "", "PathToField tooltip", "PathToField whatsthis"); + CAF_PDM_InitField(&m_indexAfter, "indexAfter", -1, "indexAfter", "", "indexAfter tooltip", "indexAfter whatsthis"); + CAF_PDM_InitField(&m_createdItemIndex, "createdItemIndex", -1, "createdItemIndex", "", "createdItemIndex tooltip", "createdItemIndex whatsthis"); + } + + caf::PdmPointer m_rootObject; + + caf::PdmField m_pathToField; + caf::PdmField m_indexAfter; + caf::PdmField m_createdItemIndex; +}; + + + +} // end namespace caf diff --git a/Fwk/AppFwk/cafCommand/defaultfeatures/cafCmdAddItemFeature.cpp b/Fwk/AppFwk/cafCommand/defaultfeatures/cafCmdAddItemFeature.cpp new file mode 100644 index 0000000000..861f8573ce --- /dev/null +++ b/Fwk/AppFwk/cafCommand/defaultfeatures/cafCmdAddItemFeature.cpp @@ -0,0 +1,123 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2013 Ceetron AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + + +#include "cafCmdAddItemFeature.h" + +#include "cafCmdAddItemExec.h" +#include "cafCmdAddItemExecData.h" +#include "cafCmdFeatureManager.h" +#include "cafCmdSelectionHelper.h" +#include "cafPdmReferenceHelper.h" +#include "cafSelectionManager.h" + +#include "cafCmdExecCommandManager.h" +#include "cafPdmChildArrayField.h" +#include "cafPdmField.h" + +#include + + + +namespace caf +{ + + CAF_CMD_SOURCE_INIT(CmdAddItemFeature, "PdmListField_AddItem"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +CmdExecuteCommand* CmdAddItemFeature::createExecuteCommand() +{ + caf::PdmChildArrayFieldHandle* childArrayFieldHandle = SelectionManager::instance()->activeChildArrayFieldHandle(); + if (!childArrayFieldHandle) return NULL; + + int indexAfter = -1; + CmdAddItemExec* addItemExec = new CmdAddItemExec(SelectionManager::instance()->notificationCenter()); + + CmdAddItemExecData* data = addItemExec->commandData(); + data->m_rootObject = PdmReferenceHelper::findRoot(childArrayFieldHandle); + data->m_pathToField = PdmReferenceHelper::referenceFromRootToField(data->m_rootObject, childArrayFieldHandle); + data->m_indexAfter = indexAfter; + + return addItemExec; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool CmdAddItemFeature::isCommandEnabled() +{ + caf::PdmChildArrayFieldHandle* childArrayFieldHandle = SelectionManager::instance()->activeChildArrayFieldHandle(); + + if (childArrayFieldHandle) + { + return true; + } + else + { + return false; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void CmdAddItemFeature::onActionTriggered(bool isChecked) +{ + if (isCommandEnabled()) + { + CmdExecuteCommand* exeCmd = createExecuteCommand(); + if (exeCmd) + { + CmdExecCommandManager::instance()->processExecuteCommand(exeCmd); + } + else + { + assert(0); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void CmdAddItemFeature::setupActionLook(QAction* actionToSetup) +{ + actionToSetup->setText("Add new object"); +} + +} // end namespace caf diff --git a/Fwk/AppFwk/cafCommand/defaultfeatures/cafCmdAddItemFeature.h b/Fwk/AppFwk/cafCommand/defaultfeatures/cafCmdAddItemFeature.h new file mode 100644 index 0000000000..576f291288 --- /dev/null +++ b/Fwk/AppFwk/cafCommand/defaultfeatures/cafCmdAddItemFeature.h @@ -0,0 +1,64 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2013 Ceetron AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + + +#pragma once + +#include "cafCmdFeature.h" + +namespace caf +{ + +class CmdExecuteCommand; + +//================================================================================================== +/// +//================================================================================================== +class CmdAddItemFeature : public CmdFeature +{ + CAF_CMD_HEADER_INIT; +protected: + CmdExecuteCommand* createExecuteCommand(); + + virtual bool isCommandEnabled(); + virtual void onActionTriggered( bool isChecked ); + virtual void setupActionLook( QAction* actionToSetup ); + +}; + + + +} // end namespace caf diff --git a/Fwk/AppFwk/cafCommand/defaultfeatures/cafCmdDeleteItemExec.cpp b/Fwk/AppFwk/cafCommand/defaultfeatures/cafCmdDeleteItemExec.cpp new file mode 100644 index 0000000000..a0107d0bc4 --- /dev/null +++ b/Fwk/AppFwk/cafCommand/defaultfeatures/cafCmdDeleteItemExec.cpp @@ -0,0 +1,150 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2013 Ceetron AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + + +#include "cafCmdDeleteItemExec.h" +#include "cafCmdDeleteItemExecData.h" + +#include "cafPdmChildArrayField.h" +#include "cafPdmReferenceHelper.h" +#include "cafPdmUiFieldHandle.h" + +#include "cafNotificationCenter.h" +#include "cafSelectionManager.h" + + +namespace caf +{ + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString CmdDeleteItemExec::name() +{ + return m_commandData->classKeyword(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void CmdDeleteItemExec::redo() +{ + PdmFieldHandle* field = PdmReferenceHelper::fieldFromReference(m_commandData->m_rootObject, m_commandData->m_pathToField); + + PdmChildArrayFieldHandle* listField = dynamic_cast(field); + if (listField) + { + std::vector children; + listField->childObjects(&children); + + PdmObjectHandle* obj = children[m_commandData->m_indexToObject]; + caf::SelectionManager::instance()->removeObjectFromAllSelections(obj); + + if (m_commandData->m_deletedObjectAsXml().isEmpty()) + { + QString encodedXml; + { + m_commandData->m_deletedObjectAsXml = xmlObj(obj)->writeObjectToXmlString(); + } + } + + listField->erase(m_commandData->m_indexToObject); + + + // TODO: The notification here could possibly be changed to + // PdmUiFieldHandle::notifyDataChange() similar to void CmdFieldChangeExec::redo() + + caf::PdmUiObjectHandle* ownerUiObject = uiObj(listField->ownerObject()); + if (ownerUiObject) + { + ownerUiObject->fieldChangedByUi(field, QVariant(), QVariant()); + } + + listField->uiCapability()->updateConnectedEditors(); + + if (m_notificationCenter) m_notificationCenter->notifyObservers(); + + delete obj; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void CmdDeleteItemExec::undo() +{ + PdmFieldHandle* field = PdmReferenceHelper::fieldFromReference(m_commandData->m_rootObject, m_commandData->m_pathToField); + + PdmChildArrayFieldHandle* listField = dynamic_cast(field); + if (listField) + { + PdmObjectHandle* obj = PdmXmlObjectHandle::readUnknownObjectFromXmlString(m_commandData->m_deletedObjectAsXml(), PdmDefaultObjectFactory::instance()); + + listField->insertAt(m_commandData->m_indexToObject, obj); + + // TODO: The notification here could possibly be changed to + // PdmUiFieldHandle::notifyDataChange() similar to void CmdFieldChangeExec::redo() + + caf::PdmUiObjectHandle* ownerUiObject = uiObj(listField->ownerObject()); + if (ownerUiObject) + { + ownerUiObject->fieldChangedByUi(field, QVariant(), QVariant()); + } + + listField->uiCapability()->updateConnectedEditors(); + + if (m_notificationCenter) m_notificationCenter->notifyObservers(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +CmdDeleteItemExec::CmdDeleteItemExec(NotificationCenter* notificationCenter) + : CmdExecuteCommand(notificationCenter) +{ + m_commandData = new CmdDeleteItemExecData; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +CmdDeleteItemExecData* CmdDeleteItemExec::commandData() +{ + return m_commandData; +} + +} // end namespace caf diff --git a/Fwk/AppFwk/cafCommand/defaultfeatures/cafCmdDeleteItemExec.h b/Fwk/AppFwk/cafCommand/defaultfeatures/cafCmdDeleteItemExec.h new file mode 100644 index 0000000000..14f3d39965 --- /dev/null +++ b/Fwk/AppFwk/cafCommand/defaultfeatures/cafCmdDeleteItemExec.h @@ -0,0 +1,70 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2013 Ceetron AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + + +#pragma once + +#include "cafCmdExecuteCommand.h" + +namespace caf +{ + +class PdmChildArrayFieldHandle; +class CmdDeleteItemExecData; + +//================================================================================================== +/// +//================================================================================================== +class CmdDeleteItemExec : public CmdExecuteCommand +{ +public: + CmdDeleteItemExec(NotificationCenter* notificationCenter); + virtual ~CmdDeleteItemExec() {}; + + + CmdDeleteItemExecData* commandData(); + + virtual QString name(); + virtual void redo(); + virtual void undo(); + +private: + CmdDeleteItemExecData* m_commandData; +}; + + + +} // end namespace caf diff --git a/Fwk/AppFwk/cafCommand/defaultfeatures/cafCmdDeleteItemExecData.cpp b/Fwk/AppFwk/cafCommand/defaultfeatures/cafCmdDeleteItemExecData.cpp new file mode 100644 index 0000000000..474a430a3a --- /dev/null +++ b/Fwk/AppFwk/cafCommand/defaultfeatures/cafCmdDeleteItemExecData.cpp @@ -0,0 +1,46 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2013 Ceetron AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + + +#include "cafCmdDeleteItemExecData.h" + + +namespace caf +{ + +CAF_PDM_SOURCE_INIT(CmdDeleteItemExecData, "CmdDeleteItemExecData"); + +} // end namespace caf diff --git a/Fwk/AppFwk/cafCommand/defaultfeatures/cafCmdDeleteItemExecData.h b/Fwk/AppFwk/cafCommand/defaultfeatures/cafCmdDeleteItemExecData.h new file mode 100644 index 0000000000..774fd2ba05 --- /dev/null +++ b/Fwk/AppFwk/cafCommand/defaultfeatures/cafCmdDeleteItemExecData.h @@ -0,0 +1,73 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2013 Ceetron AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + + +#pragma once + +#include "cafPdmObject.h" +#include "cafPdmField.h" + +namespace caf +{ + + +//================================================================================================== +/// +//================================================================================================== +class CmdDeleteItemExecData : public PdmObject +{ + CAF_PDM_HEADER_INIT; + +public: + CmdDeleteItemExecData() + { + CAF_PDM_InitObject("CmdDeleteItemExecData uiName", "", "CmdDeleteItemExecData tooltip", "CmdDeleteItemExecData whatsthis"); + + CAF_PDM_InitField(&m_pathToField, "PathToField", QString(), "PathToField", "", "PathToField tooltip", "PathToField whatsthis"); + CAF_PDM_InitField(&m_indexToObject, "indexToObject", -1, "indexToObject", "", "indexToObject tooltip", "indexToObject whatsthis"); + CAF_PDM_InitField(&m_deletedObjectAsXml, "deletedObjectAsXml", QString(), "deletedObjectAsXml", "", "deletedObjectAsXml tooltip", "deletedObjectAsXml whatsthis"); + } + + caf::PdmPointer m_rootObject; + + caf::PdmField m_pathToField; + caf::PdmField m_indexToObject; + caf::PdmField m_deletedObjectAsXml; +}; + + + +} // end namespace caf diff --git a/Fwk/AppFwk/cafCommand/defaultfeatures/cafCmdDeleteItemFeature.cpp b/Fwk/AppFwk/cafCommand/defaultfeatures/cafCmdDeleteItemFeature.cpp new file mode 100644 index 0000000000..cf26a3edf8 --- /dev/null +++ b/Fwk/AppFwk/cafCommand/defaultfeatures/cafCmdDeleteItemFeature.cpp @@ -0,0 +1,145 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2013 Ceetron AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + +#include "cafCmdDeleteItemFeature.h" + +#include "cafCmdExecCommandManager.h" +#include "cafCmdDeleteItemExec.h" +#include "cafCmdDeleteItemExecData.h" +#include "cafCmdSelectionHelper.h" +#include "cafPdmReferenceHelper.h" +#include "cafSelectionManager.h" + +#include "cafPdmChildArrayField.h" +#include "cafPdmField.h" + +#include + +namespace caf +{ + CAF_CMD_SOURCE_INIT(CmdDeleteItemFeature, "PdmListField_DeleteItem"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +CmdExecuteCommand* CmdDeleteItemFeature::createExecuteCommand() +{ + std::vector items; + SelectionManager::instance()->selectedItems(items, SelectionManager::CURRENT); + + caf::PdmChildArrayFieldHandle* childArrayFieldHandle = caf::SelectionManager::instance()->activeChildArrayFieldHandle(); + if (!childArrayFieldHandle) return NULL; + + caf::PdmObjectHandle* currentPdmObject = NULL; + + for (size_t i = 0; i < items.size(); i++) + { + if (dynamic_cast(items[i])) + { + currentPdmObject = dynamic_cast(items[i])->objectHandle(); + } + } + + if (!currentPdmObject) return NULL; + + int indexAfter = -1; + + std::vector childObjects; + childArrayFieldHandle->childObjects(&childObjects); + + for (size_t i = 0; i < childObjects.size(); i++) + { + if (childObjects[i] == currentPdmObject) + { + indexAfter = static_cast(i); + } + } + + // Did not find currently selected pdm object in the current list field + assert(indexAfter != -1); + + CmdDeleteItemExec* executeCmd = new CmdDeleteItemExec(SelectionManager::instance()->notificationCenter()); + + CmdDeleteItemExecData* data = executeCmd->commandData(); + data->m_rootObject = PdmReferenceHelper::findRoot(childArrayFieldHandle); + data->m_pathToField = PdmReferenceHelper::referenceFromRootToField(data->m_rootObject, childArrayFieldHandle); + data->m_indexToObject = indexAfter; + + return executeCmd; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool CmdDeleteItemFeature::isCommandEnabled() +{ + caf::PdmObject* currentPdmObject = dynamic_cast(caf::SelectionManager::instance()->selectedItem(caf::SelectionManager::CURRENT)); + if (!currentPdmObject) return false; + + caf::PdmChildArrayFieldHandle* childArrayFieldHandle = caf::SelectionManager::instance()->activeChildArrayFieldHandle(); + if (!childArrayFieldHandle) return false; + + return true; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void CmdDeleteItemFeature::onActionTriggered(bool isChecked) +{ + if (isCommandEnabled()) + { + CmdExecuteCommand* exeCmd = createExecuteCommand(); + if (exeCmd) + { + CmdExecCommandManager::instance()->processExecuteCommand(exeCmd); + } + else + { + assert(0); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void CmdDeleteItemFeature::setupActionLook(QAction* actionToSetup) +{ + actionToSetup->setText("Delete object"); +} + +} // end namespace caf diff --git a/Fwk/AppFwk/cafCommand/defaultfeatures/cafCmdDeleteItemFeature.h b/Fwk/AppFwk/cafCommand/defaultfeatures/cafCmdDeleteItemFeature.h new file mode 100644 index 0000000000..d98288614c --- /dev/null +++ b/Fwk/AppFwk/cafCommand/defaultfeatures/cafCmdDeleteItemFeature.h @@ -0,0 +1,62 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2013 Ceetron AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + + +#pragma once + +#include "cafCmdFeature.h" + +namespace caf +{ + +//================================================================================================== +/// +//================================================================================================== +class CmdDeleteItemFeature : public CmdFeature +{ + CAF_CMD_HEADER_INIT; +protected: + CmdExecuteCommand* createExecuteCommand(); + + // Overrides + virtual bool isCommandEnabled(); + virtual void onActionTriggered( bool isChecked ); + virtual void setupActionLook( QAction* actionToSetup ); +}; + + + +} // end namespace caf diff --git a/Fwk/AppFwk/cafPdmCvf/CMakeLists.txt b/Fwk/AppFwk/cafPdmCvf/CMakeLists.txt index 20a9a15d2a..6be4d2ef14 100644 --- a/Fwk/AppFwk/cafPdmCvf/CMakeLists.txt +++ b/Fwk/AppFwk/cafPdmCvf/CMakeLists.txt @@ -2,15 +2,48 @@ cmake_minimum_required (VERSION 2.8) project (cafPdmCvf) +# Qt +find_package ( Qt4 COMPONENTS QtCore QtGui QtMain ) +include (${QT_USE_FILE}) + include_directories( + ${LibCore_SOURCE_DIR} ${cafProjectDataModel_SOURCE_DIR} ${cafUserInterface_SOURCE_DIR} + + ${cafPdmCore_SOURCE_DIR} + ${cafPdmUiCore_SOURCE_DIR} ) add_library( ${PROJECT_NAME} - cafPdmFieldCvfColor.cpp - cafPdmFieldCvfColor.h - cafPdmFieldCvfMat4d.cpp - cafPdmFieldCvfMat4d.h + cafPdmCoreColor3f.h + cafPdmUiCoreColor3f.cpp + cafPdmUiCoreColor3f.h + cafPdmXmlColor3f.cpp + cafPdmXmlColor3f.h + cafPdmFieldCvfColor.h + + cafPdmCoreVec3d.h + cafPdmUiCoreVec3d.cpp + cafPdmUiCoreVec3d.h + cafPdmXmlVec3d.cpp + cafPdmXmlVec3d.h + cafPdmFieldCvfVec3d.h + + cafPdmCoreMat4d.h + # cafPdmUiCoreVec3d.cpp no special editor for matrix is created yet + cafPdmUiCoreMat4d.h + cafPdmXmlMat4d.cpp + cafPdmXmlMat4d.h + cafPdmFieldCvfMat4d.h +) + +target_link_libraries ( ${PROJECT_NAME} + cafPdmCore + cafPdmUiCore + cafUserInterface + cafProjectDataModel + LibCore + ${QT_LIBRARIES} ) diff --git a/Fwk/AppFwk/cafPdmCvf/cafPdmCoreColor3f.h b/Fwk/AppFwk/cafPdmCvf/cafPdmCoreColor3f.h new file mode 100644 index 0000000000..d77a0b4a1c --- /dev/null +++ b/Fwk/AppFwk/cafPdmCvf/cafPdmCoreColor3f.h @@ -0,0 +1,82 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2013 Ceetron AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + + +#pragma once + +#include "cvfBase.h" +#include "cvfColor3.h" + +#include "cafInternalPdmValueFieldSpecializations.h" + +#include + + +namespace caf +{ + +//================================================================================================== +/// Partial specialization for PdmValueFieldSpecialization< cvf::Color3f > +//================================================================================================== + +template <> +class PdmValueFieldSpecialization +{ +public: + static QVariant convert(const cvf::Color3f& value) + { + QColor col; + col.setRgbF(value.r(), value.g(), value.b()); + + return col; + } + + static void setFromVariant(const QVariant& variantValue, cvf::Color3f& value) + { + QColor col = variantValue.value(); + + value.set(col.redF(), col.greenF(), col.blueF()); + } + + static bool isEqual(const QVariant& variantValue, const QVariant& variantValue2) + { + return variantValue == variantValue2; + } + +}; + + +} // end namespace caf diff --git a/Fwk/AppFwk/cafPdmCvf/cafPdmCoreMat4d.h b/Fwk/AppFwk/cafPdmCvf/cafPdmCoreMat4d.h new file mode 100644 index 0000000000..6eb4289b94 --- /dev/null +++ b/Fwk/AppFwk/cafPdmCvf/cafPdmCoreMat4d.h @@ -0,0 +1,83 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2013 Ceetron AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + + +#pragma once + +#include "cvfBase.h" +#include "cvfMatrix4.h" + +#include "cafInternalPdmValueFieldSpecializations.h" + +#include "cafPdmXmlMat4d.h" + + +namespace caf +{ + +template <> +class PdmValueFieldSpecialization < cvf::Mat4d > +{ +public: + /// Convert the field value into a QVariant + static QVariant convert(const cvf::Mat4d& value) + { + QString str; + + QTextStream textStream(&str); + textStream << value; + + return QVariant(str); + } + + /// Set the field value from a QVariant + static void setFromVariant(const QVariant& variantValue, cvf::Mat4d& value) + { + QString str = variantValue.toString(); + + QTextStream textStream(&str); + + textStream >> value; + } + + static bool isEqual(const QVariant& variantValue, const QVariant& variantValue2) + { + return variantValue == variantValue2; + } +}; + + +} // end namespace caf diff --git a/Fwk/AppFwk/cafPdmCvf/cafPdmCoreVec3d.h b/Fwk/AppFwk/cafPdmCvf/cafPdmCoreVec3d.h new file mode 100644 index 0000000000..bd044460de --- /dev/null +++ b/Fwk/AppFwk/cafPdmCvf/cafPdmCoreVec3d.h @@ -0,0 +1,84 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2013 Ceetron AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + + +#pragma once + +#include "cvfBase.h" +#include "cvfVector3.h" + +#include "cafInternalPdmValueFieldSpecializations.h" + +#include "cafPdmXmlVec3d.h" + + +namespace caf +{ + +template <> +class PdmValueFieldSpecialization < cvf::Vec3d > +{ +public: + /// Convert the field value into a QVariant + static QVariant convert(const cvf::Vec3d& value) + { + QString str; + + QTextStream textStream(&str); + textStream << value; + + return QVariant(str); + } + + /// Set the field value from a QVariant + static void setFromVariant(const QVariant& variantValue, cvf::Vec3d& value) + { + QString str = variantValue.toString(); + + QTextStream textStream(&str); + + textStream >> value; + } + + static bool isEqual(const QVariant& variantValue, const QVariant& variantValue2) + { + return variantValue == variantValue2; + } + +}; + + +} // end namespace caf diff --git a/Fwk/AppFwk/cafPdmCvf/cafPdmFieldCvfColor.cpp b/Fwk/AppFwk/cafPdmCvf/cafPdmFieldCvfColor.cpp deleted file mode 100644 index 17bafcf76f..0000000000 --- a/Fwk/AppFwk/cafPdmCvf/cafPdmFieldCvfColor.cpp +++ /dev/null @@ -1,66 +0,0 @@ -//################################################################################################## -// -// Custom Visualization Core library -// Copyright (C) 2011-2013 Ceetron AS -// -// This library may be used under the terms of either the GNU General Public License or -// the GNU Lesser General Public License as follows: -// -// GNU General Public License Usage -// This library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. -// -// See the GNU General Public License at <> -// for more details. -// -// GNU Lesser General Public License Usage -// This library is free software; you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation; either version 2.1 of the License, or -// (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. -// -// See the GNU Lesser General Public License at <> -// for more details. -// -//################################################################################################## - - -#include - -#include "cvfBase.h" - -// Includes needed for field editor registration -#include "cvfColor3.h" -#include "cafPdmUiColorEditor.h" -#include "cafPdmField.h" - -CAF_PDM_UI_REGISTER_DEFAULT_FIELD_EDITOR(caf::PdmUiColorEditor, cvf::Color3f); - -void operator >> (QTextStream& str, cvf::Color3f& value) -{ - QString text; - - double r, g, b; - str >> r; - str >> g; - str >> b; - - value.set(r, g, b); -} - -void operator << (QTextStream& str, const cvf::Color3f& value) -{ - str << value.r() << " " << value.g() << " " << value.b(); -} - - diff --git a/Fwk/AppFwk/cafPdmCvf/cafPdmFieldCvfColor.h b/Fwk/AppFwk/cafPdmCvf/cafPdmFieldCvfColor.h index d8f7a5c777..810a8320fa 100644 --- a/Fwk/AppFwk/cafPdmCvf/cafPdmFieldCvfColor.h +++ b/Fwk/AppFwk/cafPdmCvf/cafPdmFieldCvfColor.h @@ -36,63 +36,8 @@ #pragma once -#include -#include -#include -#include "cafPdmFieldImpl.h" -#include "cvfBase.h" -#include "cvfColor3.h" +#include "cafPdmCoreColor3f.h" +#include "cafPdmXmlColor3f.h" +#include "cafPdmUiCoreColor3f.h" -namespace caf -{ - - // Forward declarations - template class PdmField; - - -//================================================================================================== -/// Partial specialization for PdmField< cvf::Color3f > -//================================================================================================== - -template <> -class PdmFieldTypeSpecialization < cvf::Color3f > -{ -public: - /// Convert the field value into a QVariant - static QVariant convert(const cvf::Color3f& value) - { - QColor col; - col.setRgbF(value.r(), value.g(), value.b()); - - return col; - } - - /// Set the field value from a QVariant - static void setFromVariant(const QVariant& variantValue, cvf::Color3f& value) - { - QColor col = variantValue.value(); - - value.set(col.redF(), col.greenF(), col.blueF()); - } - - /// Methods to get a list of options for a field - static QList valueOptions( bool* useOptionsOnly, const cvf::Color3f& ) - { - return QList(); - } - - /// Methods to retrieve the possible PdmObject pointed to by a field - static void childObjects(const PdmField< cvf::Color3f >& field, std::vector* objects) - { } - -}; - -} - -//================================================================================================== -/// QTextStream Stream operator for cvf::Color3f -//================================================================================================== - -void operator >> (QTextStream& str, cvf::Color3f& value); -void operator << (QTextStream& str, const cvf::Color3f& value); diff --git a/Fwk/AppFwk/cafPdmCvf/cafPdmFieldCvfMat4d.cpp b/Fwk/AppFwk/cafPdmCvf/cafPdmFieldCvfMat4d.cpp deleted file mode 100644 index ea16aafe1e..0000000000 --- a/Fwk/AppFwk/cafPdmCvf/cafPdmFieldCvfMat4d.cpp +++ /dev/null @@ -1,71 +0,0 @@ -//################################################################################################## -// -// Custom Visualization Core library -// Copyright (C) 2011-2013 Ceetron AS -// -// This library may be used under the terms of either the GNU General Public License or -// the GNU Lesser General Public License as follows: -// -// GNU General Public License Usage -// This library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. -// -// See the GNU General Public License at <> -// for more details. -// -// GNU Lesser General Public License Usage -// This library is free software; you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation; either version 2.1 of the License, or -// (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. -// -// See the GNU Lesser General Public License at <> -// for more details. -// -//################################################################################################## - - -#include - -// Includes needed for field editor registration -#include "cvfAssert.h" -#include "cvfMatrix4.h" - -//#include "cafPdmUiMatrixEditor.h" -//#include "cafPdmField.h" - -//CAF_PDM_UI_REGISTER_DEFAULT_FIELD_EDITOR(caf::PdmUiMatrixEditor, cvf::Mat4d); - -void operator >> (QTextStream& str, cvf::Mat4d& value) -{ - for (int r = 0; r < 4 ; ++r) - { - for (int c = 0; c < 4 ; ++c) - { - str >> value(r, c); - } - } -} - -void operator << (QTextStream& str, const cvf::Mat4d& value) -{ - for (int r = 0; r < 4 ; ++r) - { - for (int c = 0; c < 4 ; ++c) - { - str << value(r, c) << " " ; - } - } -} - - diff --git a/Fwk/AppFwk/cafPdmCvf/cafPdmFieldCvfMat4d.h b/Fwk/AppFwk/cafPdmCvf/cafPdmFieldCvfMat4d.h index 7afa2f1f3d..a6293a251d 100644 --- a/Fwk/AppFwk/cafPdmCvf/cafPdmFieldCvfMat4d.h +++ b/Fwk/AppFwk/cafPdmCvf/cafPdmFieldCvfMat4d.h @@ -34,66 +34,8 @@ // //################################################################################################## - #pragma once -#include -#include -//#include -//#include -//#include -#include - -//#include "cafPdmUiItem.h" -//#include "cafPdmObjectFactory.h" - -#include "cafPdmFieldImpl.h" -#include "cvfAssert.h" -#include "cvfMatrix4.h" - -namespace caf -{ - - // Forward declarations - template class PdmField; - - -//================================================================================================== -/// Partial specialization for PdmField< cvf::Mat4d > -//================================================================================================== - -template <> -class PdmFieldTypeSpecialization < cvf::Mat4d > -{ -public: - /// Convert the field value into a QVariant - static QVariant convert(const cvf::Mat4d& value) - { - return QVariant(); - } - - /// Set the field value from a QVariant - static void setFromVariant(const QVariant& variantValue, cvf::Mat4d& value) - { - - } - - /// Methods to get a list of options for a field - static QList valueOptions( bool* useOptionsOnly, const cvf::Mat4d& ) - { - return QList(); - } - - /// Methods to retrieve the possible PdmObject pointed to by a field - static void childObjects(const PdmField< cvf::Mat4d >& field, std::vector* objects) - { } - -}; - -} - -//================================================================================================== -/// QTextStream Stream operator for cvf::Color3f -//================================================================================================== -void operator >> (QTextStream& str, cvf::Mat4d& value); -void operator << (QTextStream& str, const cvf::Mat4d& value); +#include "cafPdmCoreMat4d.h" +#include "cafPdmXmlMat4d.h" +#include "cafPdmUiCoreMat4d.h" diff --git a/Fwk/AppFwk/cafPdmCvf/cafPdmFieldCvfVec3d.h b/Fwk/AppFwk/cafPdmCvf/cafPdmFieldCvfVec3d.h new file mode 100644 index 0000000000..4948fee8d2 --- /dev/null +++ b/Fwk/AppFwk/cafPdmCvf/cafPdmFieldCvfVec3d.h @@ -0,0 +1,42 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2014 Ceetron Solutions AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + + +#pragma once + +#include "cafPdmCoreVec3d.h" +#include "cafPdmXmlVec3d.h" +#include "cafPdmUiCoreVec3d.h" diff --git a/Fwk/AppFwk/cafPdmCvf/cafPdmUiCoreColor3f.cpp b/Fwk/AppFwk/cafPdmCvf/cafPdmUiCoreColor3f.cpp new file mode 100644 index 0000000000..4506c24939 --- /dev/null +++ b/Fwk/AppFwk/cafPdmCvf/cafPdmUiCoreColor3f.cpp @@ -0,0 +1,53 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2013 Ceetron AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + +#include "cafPdmUiCoreColor3f.h" + +#include "cafPdmField.h" +#include "cafPdmProxyValueField.h" +#include "cafPdmUiColorEditor.h" + +CAF_PDM_UI_REGISTER_DEFAULT_FIELD_EDITOR(caf::PdmUiColorEditor, cvf::Color3f); + +//-------------------------------------------------------------------------------------------------- +// If the macro for registering the editor is put as the single statement +// in a cpp file, a dummy static class must be used to make sure the compile unit +// is included +//-------------------------------------------------------------------------------------------------- +Color3fDummy::Color3fDummy() +{ + +} diff --git a/Fwk/AppFwk/cafPdmCvf/cafPdmUiCoreColor3f.h b/Fwk/AppFwk/cafPdmCvf/cafPdmUiCoreColor3f.h new file mode 100644 index 0000000000..395c886d14 --- /dev/null +++ b/Fwk/AppFwk/cafPdmCvf/cafPdmUiCoreColor3f.h @@ -0,0 +1,95 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2013 Ceetron AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + + +#pragma once + +#include "cvfBase.h" +#include "cvfColor3.h" + +#include "cafInternalPdmValueFieldSpecializations.h" +#include "cafPdmUiFieldSpecialization.h" +#include "cafPdmUiItem.h" + +#include "cafPdmCoreColor3f.h" + +class Color3fDummy +{ +public: + Color3fDummy(); +}; + +namespace caf +{ + +template <> +class PdmUiFieldSpecialization < cvf::Color3f > +{ +public: + /// Convert the field value into a QVariant + static QVariant convert(const cvf::Color3f& value) + { + static Color3fDummy dummy; + + return PdmValueFieldSpecialization< cvf::Color3f >::convert(value); + } + + + /// Set the field value from a QVariant + static void setFromVariant(const QVariant& variantValue, cvf::Color3f& value) + { + PdmValueFieldSpecialization< cvf::Color3f >::setFromVariant(variantValue, value); + } + + static bool isEqual(const QVariant& variantValue, const QVariant& variantValue2) + { + return PdmValueFieldSpecialization< cvf::Color3f >::isEqual(variantValue, variantValue2); + } + + /// Methods to get a list of options for a field, specialized for AppEnum + static QList valueOptions(bool* useOptionsOnly, const cvf::Color3f&) + { + return QList(); + } + + /// Methods to retrieve the possible PdmObject pointed to by a field + static void childObjects(const PdmDataValueField< cvf::Color3f >&, std::vector*) + { } + +}; + +} // end namespace caf + diff --git a/Fwk/AppFwk/cafPdmCvf/cafPdmUiCoreMat4d.h b/Fwk/AppFwk/cafPdmCvf/cafPdmUiCoreMat4d.h new file mode 100644 index 0000000000..9adf5b38ef --- /dev/null +++ b/Fwk/AppFwk/cafPdmCvf/cafPdmUiCoreMat4d.h @@ -0,0 +1,87 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2013 Ceetron AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + + +#pragma once + +#include "cvfBase.h" +#include "cvfMatrix4.h" + +#include "cafInternalPdmValueFieldSpecializations.h" +#include "cafPdmUiFieldSpecialization.h" +#include "cafPdmUiItem.h" + +#include "cafPdmCoreMat4d.h" + +namespace caf +{ + +template <> +class PdmUiFieldSpecialization < cvf::Mat4d > +{ +public: + /// Convert the field value into a QVariant + static QVariant convert(const cvf::Mat4d& value) + { + return PdmValueFieldSpecialization< cvf::Mat4d >::convert(value); + } + + + /// Set the field value from a QVariant + static void setFromVariant(const QVariant& variantValue, cvf::Mat4d& value) + { + PdmValueFieldSpecialization< cvf::Mat4d >::setFromVariant(variantValue, value); + } + + static bool isEqual(const QVariant& variantValue, const QVariant& variantValue2) + { + return PdmValueFieldSpecialization< cvf::Mat4d >::isEqual(variantValue, variantValue2); + } + + /// Methods to get a list of options for a field, specialized for AppEnum + static QList valueOptions(bool* useOptionsOnly, const cvf::Mat4d&) + { + return QList(); + } + + /// Methods to retrieve the possible PdmObject pointed to by a field + static void childObjects(const PdmDataValueField< cvf::Mat4d >&, std::vector*) + { } + +}; + +} // end namespace caf + diff --git a/Fwk/AppFwk/cafPdmCvf/cafPdmUiCoreVec3d.cpp b/Fwk/AppFwk/cafPdmCvf/cafPdmUiCoreVec3d.cpp new file mode 100644 index 0000000000..c5cd968f37 --- /dev/null +++ b/Fwk/AppFwk/cafPdmCvf/cafPdmUiCoreVec3d.cpp @@ -0,0 +1,53 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2013 Ceetron AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + +#include "cafPdmUiCoreVec3d.h" + +#include "cafPdmField.h" +#include "cafPdmProxyValueField.h" +#include "cafPdmUiLineEditor.h" + +CAF_PDM_UI_REGISTER_DEFAULT_FIELD_EDITOR(caf::PdmUiLineEditor, cvf::Vec3d); + +//-------------------------------------------------------------------------------------------------- +// If the macro for registering the editor is put as the single statement +// in a cpp file, a dummy static class must be used to make sure the compile unit +// is included +//-------------------------------------------------------------------------------------------------- +Vec3dDummy::Vec3dDummy() +{ + +} diff --git a/Fwk/AppFwk/cafPdmCvf/cafPdmUiCoreVec3d.h b/Fwk/AppFwk/cafPdmCvf/cafPdmUiCoreVec3d.h new file mode 100644 index 0000000000..2fd75fea97 --- /dev/null +++ b/Fwk/AppFwk/cafPdmCvf/cafPdmUiCoreVec3d.h @@ -0,0 +1,96 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2013 Ceetron AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + + +#pragma once + +#include "cvfBase.h" +#include "cvfVector3.h" + +#include "cafInternalPdmValueFieldSpecializations.h" +#include "cafPdmUiFieldSpecialization.h" +#include "cafPdmUiItem.h" + +#include "cafPdmCoreVec3d.h" + +class Vec3dDummy +{ +public: + Vec3dDummy(); +}; + + +namespace caf +{ + +template <> +class PdmUiFieldSpecialization < cvf::Vec3d > +{ +public: + /// Convert the field value into a QVariant + static QVariant convert(const cvf::Vec3d& value) + { + static Vec3dDummy dummy; + + return PdmValueFieldSpecialization< cvf::Vec3d >::convert(value); + } + + + /// Set the field value from a QVariant + static void setFromVariant(const QVariant& variantValue, cvf::Vec3d& value) + { + PdmValueFieldSpecialization< cvf::Vec3d >::setFromVariant(variantValue, value); + } + + static bool isEqual(const QVariant& variantValue, const QVariant& variantValue2) + { + return PdmValueFieldSpecialization< cvf::Vec3d >::isEqual(variantValue, variantValue2); + } + + /// Methods to get a list of options for a field, specialized for AppEnum + static QList valueOptions(bool* useOptionsOnly, const cvf::Vec3d&) + { + return QList(); + } + + /// Methods to retrieve the possible PdmObject pointed to by a field + static void childObjects(const PdmDataValueField< cvf::Vec3d >&, std::vector*) + { } + +}; + +} // end namespace caf + diff --git a/Fwk/AppFwk/cafPdmCvf/cafPdmXmlColor3f.cpp b/Fwk/AppFwk/cafPdmCvf/cafPdmXmlColor3f.cpp new file mode 100644 index 0000000000..23b27d1b0a --- /dev/null +++ b/Fwk/AppFwk/cafPdmCvf/cafPdmXmlColor3f.cpp @@ -0,0 +1,59 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2013 Ceetron AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + +#include "cafPdmXmlColor3f.h" + + +#include + +void operator >> (QTextStream& str, cvf::Color3f& value) +{ + QString text; + + double r, g, b; + str >> r; + str >> g; + str >> b; + + value.set(r, g, b); +} + +void operator << (QTextStream& str, const cvf::Color3f& value) +{ + str << value.r() << " " << value.g() << " " << value.b(); +} + + diff --git a/Fwk/AppFwk/cafPdmCvf/cafPdmXmlColor3f.h b/Fwk/AppFwk/cafPdmCvf/cafPdmXmlColor3f.h new file mode 100644 index 0000000000..36d19809ec --- /dev/null +++ b/Fwk/AppFwk/cafPdmCvf/cafPdmXmlColor3f.h @@ -0,0 +1,50 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2013 Ceetron AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + + +#pragma once + +#include "cvfBase.h" +#include "cvfColor3.h" + +class QTextStream; + +//================================================================================================== +/// QTextStream Stream operator for cvf::Color3f +//================================================================================================== + +void operator >> (QTextStream& str, cvf::Color3f& value); +void operator << (QTextStream& str, const cvf::Color3f& value); diff --git a/Fwk/AppFwk/cafPdmCvf/cafPdmXmlMat4d.cpp b/Fwk/AppFwk/cafPdmCvf/cafPdmXmlMat4d.cpp new file mode 100644 index 0000000000..89dc738c41 --- /dev/null +++ b/Fwk/AppFwk/cafPdmCvf/cafPdmXmlMat4d.cpp @@ -0,0 +1,62 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2013 Ceetron AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + +#include "cafPdmXmlMat4d.h" + + +#include + +void operator >> (QTextStream& str, cvf::Mat4d& value) +{ + for (int r = 0; r < 4; ++r) + { + for (int c = 0; c < 4; ++c) + { + str >> value(r, c); + } + } +} + +void operator << (QTextStream& str, const cvf::Mat4d& value) +{ + for (int r = 0; r < 4; ++r) + { + for (int c = 0; c < 4; ++c) + { + str << value(r, c) << " "; + } + } +} diff --git a/Fwk/AppFwk/cafPdmCvf/cafPdmXmlMat4d.h b/Fwk/AppFwk/cafPdmCvf/cafPdmXmlMat4d.h new file mode 100644 index 0000000000..51fd8a5737 --- /dev/null +++ b/Fwk/AppFwk/cafPdmCvf/cafPdmXmlMat4d.h @@ -0,0 +1,46 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2013 Ceetron AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + + +#pragma once + +#include "cvfBase.h" +#include "cvfMatrix4.h" + +class QTextStream; + +void operator >> (QTextStream& str, cvf::Mat4d& value); +void operator << (QTextStream& str, const cvf::Mat4d& value); diff --git a/Fwk/AppFwk/cafPdmCvf/cafPdmXmlVec3d.cpp b/Fwk/AppFwk/cafPdmCvf/cafPdmXmlVec3d.cpp new file mode 100644 index 0000000000..63f645936a --- /dev/null +++ b/Fwk/AppFwk/cafPdmCvf/cafPdmXmlVec3d.cpp @@ -0,0 +1,71 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2013 Ceetron AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + +#include "cafPdmXmlVec3d.h" + + +#include + +void operator >> (QTextStream& str, cvf::Vec3d& value) +{ + bool streamStatusOk = true; + + cvf::Vec3d tmp; + for (int r = 0; r < 3; ++r) + { + str >> tmp[r]; + + if (str.status() != QTextStream::Ok) + { + streamStatusOk = false; + } + } + + if (streamStatusOk) + { + value = tmp; + } +} + +void operator << (QTextStream& str, const cvf::Vec3d& value) +{ + for (int r = 0; r < 3; ++r) + { + str << value[r]; + if (r < 2) str << " "; + } +} + diff --git a/Fwk/AppFwk/cafPdmCvf/cafPdmXmlVec3d.h b/Fwk/AppFwk/cafPdmCvf/cafPdmXmlVec3d.h new file mode 100644 index 0000000000..a3af7fa539 --- /dev/null +++ b/Fwk/AppFwk/cafPdmCvf/cafPdmXmlVec3d.h @@ -0,0 +1,46 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2013 Ceetron AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + + +#pragma once + +#include "cvfBase.h" +#include "cvfVector3.h" + +class QTextStream; + +void operator >> (QTextStream& str, cvf::Vec3d& value); +void operator << (QTextStream& str, const cvf::Vec3d& value); diff --git a/Fwk/AppFwk/cafProjectDataModel/CMakeLists.txt b/Fwk/AppFwk/cafProjectDataModel/CMakeLists.txt index 24bc987236..7e451984f4 100644 --- a/Fwk/AppFwk/cafProjectDataModel/CMakeLists.txt +++ b/Fwk/AppFwk/cafProjectDataModel/CMakeLists.txt @@ -2,35 +2,30 @@ cmake_minimum_required (VERSION 2.8) project (cafProjectDataModel) -add_library( ${PROJECT_NAME} - cafAppEnum.h +# Qt +find_package ( Qt4 COMPONENTS QtCore QtGui ) +include (${QT_USE_FILE}) + +include_directories ( + ${cafPdmCore_SOURCE_DIR} + ${cafPdmUiCore_SOURCE_DIR} + ${cafPdmXml_SOURCE_DIR} +) + +set( PROJECT_FILES cafFactory.h cafFixedArray.h cafOmpMutex.h - cafUiTreeItem.h cafPdmDocument.cpp cafPdmDocument.h - cafPdmField.cpp - cafPdmField.h - cafPdmField.inl - cafPdmFieldImpl.h - cafPdmObject.cpp + cafPdmObjectGroup.cpp + cafPdmObjectGroup.h cafPdmObject.h - cafPdmObjectFactory.h - cafPdmPointer.cpp - cafPdmPointer.h - cafPdmUiEditorHandle.cpp - cafPdmUiEditorHandle.h - cafPdmUiFieldEditorHandle.cpp - cafPdmUiFieldEditorHandle.h - cafPdmUiItem.cpp - cafPdmUiItem.h - cafPdmUiObjectEditorHandle.cpp - cafPdmUiObjectEditorHandle.h - cafPdmUiOrdering.cpp - cafPdmUiOrdering.h - cafPdmUiTreeOrdering.cpp - cafPdmUiTreeOrdering.h - cafPdmUiTreeEditorHandle.h - cafPdmUiTreeEditorHandle.cpp + cafPdmField.h ) + +add_library( ${PROJECT_NAME} + ${PROJECT_FILES} +) + +source_group("" FILES ${PROJECT_FILES}) \ No newline at end of file diff --git a/Fwk/AppFwk/cafProjectDataModel/PdmCore.plantuml b/Fwk/AppFwk/cafProjectDataModel/PdmCore.plantuml new file mode 100644 index 0000000000..2cf0221beb --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/PdmCore.plantuml @@ -0,0 +1,166 @@ +@startuml + +class PdmObject { + name() + fields(); + referencingFields(); + parentField(); + template capability() + void addCapability() + +--- + std::vector m_fields; + std::vector m_capabilities; +} + + +PdmObject --* "n" PdmObjectCapability + +class PdmUiItem{ + +} + +PdmObjectCapability <|- PdmUiObject +PdmUiItem <|- PdmUiObject + +class PdmUiObject{ + uiOrdering() = ?; + uiTreeOrdering() = ? ; + editorAttribute() = ?; + + objectEditorAttribute() = ? ; + + userDescriptionField(); + objectToggleField() + + calculateValueOptions() = ?; + + fieldChangedByUi() = 0; + --- + m_descriptionField; + m_objectToggleField; +} + +PdmUiObject <|-- PdmCompleteObject +PdmObject <|-- PdmCompleteObject +PdmXmlSerializable <|-- PdmCompleteObject + + +class PdmXmlSerializable { + classKeyword() = 0; + readFields (); + writeFields(); +} + +PdmObjectCapability <|- PdmXmlSerializable + + + +package FieldHandle{ + +PdmObject --> "n" PdmFieldHandle + +class PdmFieldHandle{ + name() + + setOwnerObject(); + ownerObject(); + + hasChildObjects() = 0; + childObjects( ) = 0; + --- + std::vector m_attributes; +} + + +PdmFieldHandle --* "n" PdmFieldCapability + +class PdmUiFieldHandle{ + + uiValue() + setValueFromUi() + + valueOptions( ) = 0; + +} + +PdmFieldCapability <|- PdmUiFieldHandle +PdmUiItem <|- PdmUiFieldHandle + + +class PdmXmlFieldHandle { + setKeyword(); + keyword(); + + readFieldData() = 0; + writeFieldData() = 0; + + isIOReadable() + isIOWritable() + setIOWritable() + setIOReadable() +--- + bool m_isReadable; + bool m_isWritable; +} + +PdmFieldCapability <|- PdmXmlFieldHandle + + +PdmFieldHandle <|-- PdmCompleteFieldHandle +PdmUiFieldHandle <|-- PdmCompleteFieldHandle +PdmXmlFieldHandle <|-- PdmCompleteFieldHandle + +} + +package ToDoFields{ +class "PdmFieldXmlCap>"{ +} +} + +package SplittedFields{ + +PdmFieldHandle <|--- "PdmField" +"PdmField" --> "PdmFieldUiCap" +"PdmField" --> "PdmFieldXmlCap" + +PdmFieldHandle <|--- "PdmProxyField" +"PdmProxyField" --> "PdmFieldUiCap" +"PdmProxyField" --> "PdmFieldXmlCap" + +PdmUiFieldHandle <|--- "PdmFieldUiCap" +PdmXmlFieldHandle <|--- "PdmFieldXmlCap" + +PdmFieldHandle <|--- "PdmPtrField" +"PdmPtrField" --> "PdmFieldUiCap" +"PdmPtrField" --> "PdmFieldXmlCap" +"PdmPtrField" ..> "Todo" "PdmFieldXmlCap>" + +PdmFieldHandle <|--- "PdmChildField" +"PdmChildField"--> "PdmFieldUiCap>" +"PdmChildField"--> "PdmFieldXmlCap>" +PdmFieldHandle <|--- "PdmChildArrayField" +"PdmChildArrayField"--> "PdmFieldUiCap>" +"PdmChildArrayField"--> "PdmFieldXmlCap>" + +} + + +package ToDoFields{ +PdmFieldHandle <|-- "PdmProxyPtrField" +"PdmProxyPtrField" --> "PdmFieldUiCap" +"PdmProxyPtrField" ..> "Todo" "PdmFieldXmlCap>" + +PdmFieldHandle <|-- "PdmProxyChildField" +"PdmProxyChildField"--> "PdmFieldUiCap>" +"PdmProxyChildField"--> "PdmFieldXmlCap>" +PdmFieldHandle <|-- "PdmProxyChildArrayField" +"PdmProxyChildArrayField"--> "PdmFieldUiCap>" +"PdmProxyChildArrayField"--> "PdmFieldXmlCap>" + +} + + + +@enduml + \ No newline at end of file diff --git a/Fwk/AppFwk/cafProjectDataModel/PdmCoreNewNames.plantuml b/Fwk/AppFwk/cafProjectDataModel/PdmCoreNewNames.plantuml new file mode 100644 index 0000000000..aef25defb0 --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/PdmCoreNewNames.plantuml @@ -0,0 +1,163 @@ +@startuml + +class PdmObjectHandle { + name() + fields(); + referencingFields(); + parentField(); + template capability() + void addCapability() + +--- + std::vector m_fields; + std::vector m_capabilities; +} + + +PdmObjectHandle --* "n" PdmObjectCapability + +class PdmUiItem{ + +} + +PdmObjectCapability <|- PdmUiObjectHandle +PdmUiItem <|- PdmUiObjectHandle + +class PdmUiObjectHandle { + uiOrdering() = ?; + uiTreeOrdering() = ? ; + editorAttribute() = ?; + + objectEditorAttribute() = ? ; + + userDescriptionField(); + objectToggleField() + + calculateValueOptions() = ?; + + fieldChangedByUi() = 0; + --- + m_descriptionField; + m_objectToggleField; +} + +PdmUiObjectHandle <|-- PdmObject +PdmObjectHandle <|-- PdmObject +PdmXmlObjectHandle <|-- PdmObject + + +class PdmXmlObjectHandle { + classKeyword() = 0; + readFields (); + writeFields(); +} + +PdmObjectCapability <|- PdmXmlObjectHandle + + + +package FieldHandle{ + +PdmObjectHandle --> "n" PdmFieldHandle + +class PdmFieldHandle{ + name() + + setOwnerObject(); + ownerObject(); + + hasChildObjects() = 0; + childObjects( ) = 0; + --- + std::vector m_attributes; +} + + +PdmFieldHandle --* "n" PdmFieldCapability + +class PdmUiFieldHandle{ + + uiValue() + setValueFromUi() + + valueOptions( ) = 0; + +} + +PdmFieldCapability <|- PdmUiFieldHandle +PdmUiItem <|- PdmUiFieldHandle + + +class PdmXmlFieldHandle { + setKeyword(); + keyword(); + + readFieldData() = 0; + writeFieldData() = 0; + + isIOReadable() + isIOWritable() + setIOWritable() + setIOReadable() +--- + bool m_isReadable; + bool m_isWritable; +} + +PdmFieldCapability <|- PdmXmlFieldHandle + + + +} + +package ToDoFields{ +class "InternalPdmXmlFieldCapability>"{ +} +} + +package SplittedFields{ + +PdmFieldHandle <|--- "PdmField" +"PdmField" --> "InternalPdmUiFieldCapability" +"PdmField" --> "InternalPdmXmlFieldCapability" + +PdmFieldHandle <|--- "PdmProxyField" +"PdmProxyField" --> "InternalPdmUiFieldCapability" +"PdmProxyField" --> "InternalPdmXmlFieldCapability" + +PdmUiFieldHandle <|--- "InternalPdmUiFieldCapability" +PdmXmlFieldHandle <|--- "InternalPdmXmlFieldCapability" + +PdmFieldHandle <|--- "PdmPtrField" +"PdmPtrField" --> "InternalPdmUiFieldCapability" +"PdmPtrField" --> "InternalPdmXmlFieldCapability" +"PdmPtrField" ..> "Todo" "InternalPdmXmlFieldCapability>" + +PdmFieldHandle <|--- "PdmChildField" +"PdmChildField"--> "InternalPdmUiFieldCapability>" +"PdmChildField"--> "InternalPdmXmlFieldCapability>" +PdmFieldHandle <|--- "PdmChildArrayField" +"PdmChildArrayField"--> "InternalPdmUiFieldCapability>" +"PdmChildArrayField"--> "InternalPdmXmlFieldCapability>" + +} + + +package ToDoFields{ +PdmFieldHandle <|-- "PdmProxyPtrField" +"PdmProxyPtrField" --> "InternalPdmUiFieldCapability" +"PdmProxyPtrField" ..> "Todo" "InternalPdmXmlFieldCapability>" + +PdmFieldHandle <|-- "PdmProxyChildField" +"PdmProxyChildField"--> "InternalPdmUiFieldCapability>" +"PdmProxyChildField"--> "InternalPdmXmlFieldCapability>" +PdmFieldHandle <|-- "PdmProxyChildArrayField" +"PdmProxyChildArrayField"--> "InternalPdmUiFieldCapability>" +"PdmProxyChildArrayField"--> "InternalPdmXmlFieldCapability>" + +} + + + +@enduml + \ No newline at end of file diff --git a/Fwk/AppFwk/cafProjectDataModel/PdmModularization.plantuml b/Fwk/AppFwk/cafProjectDataModel/PdmModularization.plantuml new file mode 100644 index 0000000000..af982b8471 --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/PdmModularization.plantuml @@ -0,0 +1,135 @@ +@startuml + +class PdmObjectHandle { + name() + fields(); + referencingFields(); + parentField(); + template capability() + void addCapability() + +--- + std::vector m_fields; + std::vector m_capabilities; +} + + +PdmObjectHandle --* "n" PdmObjectCapability + +class PdmUiItem{ + +} + +PdmObjectCapability <|- PdmUiObjectHandle +PdmUiItem <|- PdmUiObjectHandle + +class PdmUiObjectHandle { + uiOrdering() = ?; + uiTreeOrdering() = ? ; + editorAttribute() = ?; + + objectEditorAttribute() = ? ; + + userDescriptionField(); + objectToggleField() + + calculateValueOptions() = ?; + + fieldChangedByUi() = 0; + --- + m_descriptionField; + m_objectToggleField; +} + +PdmUiObjectHandle <|-- PdmObject +PdmObjectHandle <|-- PdmObject +PdmXmlObjectHandle <|-- PdmObject + + +class PdmXmlObjectHandle { + classKeyword() = 0; + readFields (); + writeFields(); +} + +PdmObjectCapability <|- PdmXmlObjectHandle + + + +package FieldHandle{ + +PdmObjectHandle --> "n" PdmFieldHandle + +class PdmFieldHandle{ + name() + + setOwnerObject(); + ownerObject(); + + hasChildObjects() = 0; + childObjects( ) = 0; + --- + std::vector m_attributes; +} + + +PdmFieldHandle --* "n" PdmFieldCapability + +class PdmUiFieldHandle{ + + uiValue() + setValueFromUi() + + valueOptions( ) = 0; + +} + +PdmFieldCapability <|- PdmUiFieldHandle +PdmUiItem <|- PdmUiFieldHandle + + +class PdmXmlFieldHandle { + setKeyword(); + keyword(); + + readFieldData() = 0; + writeFieldData() = 0; + + isIOReadable() + isIOWritable() + setIOWritable() + setIOReadable() +--- + bool m_isReadable; + bool m_isWritable; +} + +PdmFieldCapability <|- PdmXmlFieldHandle + + + +} + + + +PdmFieldHandle <|- "PdmPtrField" +PdmFieldHandle <|- "PdmChildField" + +PdmFieldHandle <|- PdmValueField +PdmValueField <|-- "PdmDataValueField" +PdmValueField <|-- "PdmProxyValueField" + +PdmFieldHandle <|- PdmChildArrayFieldHandle +PdmChildArrayFieldHandle <|-- "PdmChildArrayField" + +PdmField ..u.. PdmValueField + +class PdmField { + Macro used to replace + PdmField with PdmValueField (used in ResInsight) +} + + + +@enduml + \ No newline at end of file diff --git a/Fwk/AppFwk/cafProjectDataModel/PdmOverview.plantuml b/Fwk/AppFwk/cafProjectDataModel/PdmOverview.plantuml new file mode 100644 index 0000000000..fac1502557 --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/PdmOverview.plantuml @@ -0,0 +1,76 @@ +@startuml +left to right direction + +component cafProjectDataModel +note right of [cafProjectDataModel] + Templated factory class + Multithreaded mutex + Aggreagated class PdmObject, inherits Core, Ui, Xml + Helper macro to be able to use PdmField(macro for replacing with PdmValueField) + PdmObjectGroup - collection of PdmObjects +end note + + +component cafPdmCore +note right of [cafPdmCore] + cafAppEnum + Classes derived from cafPdmFieldHandle + cafPdmPointer +end note + +component cafPdmUiCore +note right of [cafPdmUiCore] + Object editor handle + Field editor handle + Ui ordering for properties + Ui ordering for tree view + Selection manager +end note + +component cafPdmXml +note right of [cafPdmXml] + Default object factory + Serialization of objects to Xml +end note + +component cafUserInterface +note right of [cafUserInterface] + Default object property editor + Property view contained in a dialog (used to display preferences) + + Table editor + Progress info + + PdmField editors (line, checkbox, list view, ...) +end note + +component cafCommand +note right of [cafCommand] + Feature manager + Base class for features + Base class for feature commands + Management of undo/redo +end note + +component cafAnimControl +component cafTensor + +component cafViewer +note right of [cafViewer] + Viewer widget used to display 3D models + Mouse navigation policies +end note + +component cafPdmCvf +note right of [cafPdmCvf] + Definition of default Ui editors for CVF classes + Color3f + Vec3d + Mat4d +end note + + + + +@enduml + \ No newline at end of file diff --git a/Fwk/AppFwk/cafProjectDataModel/cafFactory.h b/Fwk/AppFwk/cafProjectDataModel/cafFactory.h index e4712b3cd5..9080e3fb4e 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafFactory.h +++ b/Fwk/AppFwk/cafProjectDataModel/cafFactory.h @@ -39,6 +39,25 @@ #include #include +#include + +// Taken from gtest.h +// +// Due to C++ preprocessor weirdness, we need double indirection to +// concatenate two tokens when one of them is __LINE__. Writing +// +// foo ## __LINE__ +// +// will result in the token foo__LINE__, instead of foo followed by +// the current line number. For more details, see +// http://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.6 +#define CAF_FACTORY_CONCATENATE_STRINGS(foo, bar) CAF_FACTORY_CONCATENATE_STRINGS_IMPL_(foo, bar) +#define CAF_FACTORY_CONCATENATE_STRINGS_IMPL_(foo, bar) foo ## bar + +#define CAF_UNIQUE_COMPILE_UNIT_VAR_NAME CAF_FACTORY_CONCATENATE_STRINGS(caf_factory_init_, __LINE__) + +#define CAF_FACTORY_REGISTER(BaseType, TypeToCreate, KeyType, key) \ +static bool CAF_UNIQUE_COMPILE_UNIT_VAR_NAME = caf::Factory::instance()->registerCreator(key) namespace caf { @@ -56,6 +75,8 @@ namespace caf /// /// static bool uniqueVarname = caf::Factory::instance()->registerCreator(key); /// + /// You can also use the macro CAF_FACTORY_REGISTER(BaseType, TypeToCreate, KeyType, key) + /// /// See also cafPdmUiFieldEditorHandle.h for an advanced example. /// /// When you need an object: diff --git a/Fwk/AppFwk/cafProjectDataModel/cafFixedArray.h b/Fwk/AppFwk/cafProjectDataModel/cafFixedArray.h index 6602c333cb..eab0ac9247 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafFixedArray.h +++ b/Fwk/AppFwk/cafProjectDataModel/cafFixedArray.h @@ -37,6 +37,8 @@ #pragma once +#include "cvfAssert.h" + namespace caf { @@ -55,8 +57,8 @@ class FixedArray FixedArray& operator=(const T* ptr) { for (size_t i = 0; i < size ; ++i) m_array[i] = ptr[i]; return *this;} - template T& operator[](const IndexType& index) { return m_array[index]; } - template const T& operator[](const IndexType& index) const { return m_array[index]; } + template T& operator[](const IndexType& index) { CVF_TIGHT_ASSERT(static_cast(index) < size); return m_array[index]; } + template const T& operator[](const IndexType& index) const { CVF_TIGHT_ASSERT(static_cast(index) < size); return m_array[index]; } }; typedef FixedArray IntArray3; diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/CMakeLists.txt b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/CMakeLists.txt new file mode 100644 index 0000000000..d3f5be1d5c --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/CMakeLists.txt @@ -0,0 +1,47 @@ +cmake_minimum_required (VERSION 2.8) + +project (cafPdmCore) + +# Qt +find_package ( Qt4 COMPONENTS QtCore ) +include (${QT_USE_FILE}) + +include_directories ( +) + +set( PROJECT_FILES + + cafAppEnum.h + cafClassTypeName.h + cafPdmBase.h + cafPdmChildArrayField.h + cafPdmChildArrayField.inl + cafPdmChildArrayFieldHandle.cpp + cafPdmChildField.h + cafPdmChildField.inl + cafPdmDataValueField.h + cafPdmFieldCapability.h + cafPdmFieldHandle.cpp + cafPdmFieldHandle.h + cafPdmObjectCapability.h + cafPdmObjectHandle.cpp + cafPdmObjectHandle.h + cafPdmPointer.cpp + cafPdmPointer.h + cafPdmProxyValueField.h + cafPdmPtrField.h + cafPdmPtrField.inl + cafPdmReferenceHelper.cpp + cafPdmReferenceHelper.h + cafPdmValueField.h + + cafNotificationCenter.cpp + cafNotificationCenter.h +) + + +add_library( ${PROJECT_NAME} + ${PROJECT_FILES} +) + +source_group("" FILES ${PROJECT_FILES}) \ No newline at end of file diff --git a/Fwk/AppFwk/cafProjectDataModel/cafAppEnum.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafAppEnum.h similarity index 98% rename from Fwk/AppFwk/cafProjectDataModel/cafAppEnum.h rename to Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafAppEnum.h index 23035c7edb..287e0e5b21 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafAppEnum.h +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafAppEnum.h @@ -170,13 +170,14 @@ class AppEnum static EnumMapper * instance() { - static EnumMapper * storedInstance = 0; - if (!storedInstance) + static EnumMapper storedInstance; + static bool isInitialized = false; + if (!isInitialized) { - storedInstance = new EnumMapper; + isInitialized = true; AppEnum::setUp(); } - return storedInstance; + return &storedInstance; } void setDefault(T defaultEnumValue) diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafClassTypeName.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafClassTypeName.h new file mode 100644 index 0000000000..d82a762730 --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafClassTypeName.h @@ -0,0 +1,43 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) Ceetron Solutions AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + + +#pragma once + +#include + +/// Create a QString based on a typename +#define qStringTypeName(TypeName) QString(typeid(TypeName).name()) diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafInternalPdmValueFieldSpecializations.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafInternalPdmValueFieldSpecializations.h new file mode 100644 index 0000000000..50112cc5cd --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafInternalPdmValueFieldSpecializations.h @@ -0,0 +1,118 @@ +#pragma once + +#include + +namespace caf +{ + +//================================================================================================== +/// A proxy class that implements the generic QVariant interface for a field +/// +/// This class collects methods that need specialization when introducing a new type in a PdmField. +/// Having those methods in a separate class makes it possible to "partially specialize" the methods +/// for container classes etc. since partial specialization of template functions is not C++ as of yet. +/// +/// When introducing a new type in a PdmField, you might need to implement a (partial)specialization +/// of this class. +//================================================================================================== + +template +class PdmValueFieldSpecialization +{ +public: + /// Convert the field value into a QVariant + static QVariant convert(const T& value) + { + return QVariant::fromValue(value); + } + + /// Set the field value from a QVariant + static void setFromVariant(const QVariant& variantValue, T& value) + { + value = variantValue.value(); + } + + /// Check equality between QVariants that carries a Field Value. + /// The == operator will normally work, but does not support custom types in the QVariant + /// See http://qt-project.org/doc/qt-4.8/qvariant.html#operator-eq-eq-64 + static bool isEqual(const QVariant& variantValue, const QVariant& variantValue2) + { + return variantValue == variantValue2; + } + +}; +} // End of namespace caf + +#include "cafAppEnum.h" + +namespace caf +{ + +template +class PdmValueFieldSpecialization > +{ +public: + static QVariant convert(const caf::AppEnum& value) + { + T enumValue = value; + return QVariant(enumValue); + } + + static void setFromVariant(const QVariant& variantValue, caf::AppEnum& value) + { + value = (T)variantValue.toInt(); + } + + static bool isEqual(const QVariant& variantValue, const QVariant& variantValue2) + { + return variantValue == variantValue2; + } + +}; + +} // End of namespace caf + + + +#include + +namespace caf +{ + +template +class PdmValueFieldSpecialization > +{ +public: + static QVariant convert(const std::vector& value) + { + QList returnList; + typename std::vector::const_iterator it; + for (it = value.begin(); it != value.end() ; ++it) + { + returnList.push_back(QVariant::fromValue(*it)); + } + return returnList; + + } + + static void setFromVariant(const QVariant& variantValue, std::vector& value) + { + if (variantValue.canConvert< QList >()) + { + value.clear(); + QList lst = variantValue.toList(); + for (int i = 0; i < lst.size(); ++i) + { + value.push_back(lst[i].value()); + } + } + } + + static bool isEqual(const QVariant& variantValue, const QVariant& variantValue2) + { + return variantValue == variantValue2; + } + +}; + +} // End of namespace caf diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafNotificationCenter.cpp b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafNotificationCenter.cpp new file mode 100644 index 0000000000..0ba8c85e64 --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafNotificationCenter.cpp @@ -0,0 +1,116 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2014 Ceetron Solutions AS +// +// is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "cafNotificationCenter.h" + +#include + +#include +#include + + +namespace caf +{ + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +NotificationCenter::NotificationCenter() +{ +} + + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +NotificationCenter::~NotificationCenter() +{ + assert(m_observers.size() == 0); +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void NotificationCenter::registerObserver(DataModelObserver* observer) +{ + std::vector::iterator it = std::find(m_observers.begin(), m_observers.end(), observer); + if (it == m_observers.end()) + { + m_observers.push_back(observer); + } +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void NotificationCenter::removeObserver(DataModelObserver* observer) +{ + std::vector::iterator it = std::find(m_observers.begin(), m_observers.end(), observer); + if (it != m_observers.end()) + { + m_observers.erase(it); + } +} + + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void NotificationCenter::notifyObserversOfDataChange(caf::PdmObjectHandle* itemThatChanged) +{ + assert(itemThatChanged); + + foreach(DataModelObserver* o, m_observers) + { + o->handleModelNotification(itemThatChanged); + } + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void NotificationCenter::notifyObservers() +{ + foreach(DataModelObserver* o, m_observers) + { + o->handleModelNotification(NULL); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void NotificationCenter::notifyObserversOfSelectionChange() +{ + foreach(DataModelObserver* o, m_observers) + { + o->handleModelSelectionChange(); + } +} + + + + + +} // end namespace caf diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafNotificationCenter.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafNotificationCenter.h new file mode 100644 index 0000000000..2d99b88288 --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafNotificationCenter.h @@ -0,0 +1,66 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2014 Ceetron Solutions AS +// +// is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include + + +namespace caf +{ + class PdmObjectHandle; + + +//================================================================================================== +// +// +// +//================================================================================================== +class DataModelObserver +{ +public: + virtual void handleModelNotification(caf::PdmObjectHandle* itemThatChanged) = 0; + virtual void handleModelSelectionChange() = 0; +}; + + +//================================================================================================== +// +// +// +//================================================================================================== +class NotificationCenter +{ +public: + NotificationCenter(); + ~NotificationCenter(); + + void registerObserver(DataModelObserver* observer); + void removeObserver(DataModelObserver* observer); + + void notifyObservers(); + void notifyObserversOfDataChange(caf::PdmObjectHandle* itemThatChanged); + void notifyObserversOfSelectionChange(); + +private: + std::vector m_observers; +}; + + + +} // end namespace caf diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmBase.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmBase.h new file mode 100644 index 0000000000..d608d5b477 --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmBase.h @@ -0,0 +1,12 @@ +#pragma once + + +// Brings in size_t and definition of NULL +#include + +// Macro to disable the copy constructor and assignment operator +// Should be used in the private section of a class +#define PDM_DISABLE_COPY_AND_ASSIGN(CLASS_NAME) \ + CLASS_NAME(const CLASS_NAME&); \ + void operator=(const CLASS_NAME&) + diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmChildArrayField.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmChildArrayField.h new file mode 100644 index 0000000000..043206a5ff --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmChildArrayField.h @@ -0,0 +1,109 @@ +#pragma once + +#include "cafPdmFieldHandle.h" +#include "cafPdmPointer.h" +#include + +namespace caf +{ + +template class PdmFieldXmlCap; + +//================================================================================================== +/// +/// +/// +//================================================================================================== +class PdmChildArrayFieldHandle : public PdmFieldHandle +{ +public: + PdmChildArrayFieldHandle() {} + virtual ~PdmChildArrayFieldHandle() {} + + virtual size_t size() const = 0; + virtual bool empty() const = 0; + virtual void clear() = 0; + virtual void insertAt(int indexAfter, PdmObjectHandle* obj) = 0; + virtual void erase(size_t index) = 0; + virtual void deleteAllChildObjects() = 0; + + virtual PdmObjectHandle* at(size_t index) = 0; + + bool hasSameFieldCountForAllObjects(); +}; + +//================================================================================================== +/// PdmFieldClass to handle a collection of PdmObject derived pointers +/// The reasons for this class is to add itself as parentField into the objects being pointed to. +/// The interface is made similar to std::vector<>, and the complexity of the methods is similar too. +//================================================================================================== + +template +class PdmChildArrayField : public PdmFieldHandle +{ +public: + PdmChildArrayField() + { + bool doNotUsePdmPointersFieldForAnythingButPointersToPdmObject = false; assert(doNotUsePdmPointersFieldForAnythingButPointersToPdmObject); + } +}; + + +template +class PdmChildArrayField : public PdmChildArrayFieldHandle +{ + typedef DataType* DataTypePtr; +public: + PdmChildArrayField() { } + virtual ~PdmChildArrayField(); + + PdmChildArrayField& operator() () { return *this; } + + // Reimplementation of PdmPointersFieldHandle methods + + virtual size_t size() const { return m_pointers.size(); } + virtual bool empty() const { return m_pointers.empty(); } + virtual void clear(); + virtual void deleteAllChildObjects(); + virtual void insertAt(int indexAfter, PdmObjectHandle* obj); + virtual PdmObjectHandle* at(size_t index); + + // std::vector-like access + + DataType* operator[] (size_t index) const; + + void push_back(DataType* pointer); + void set(size_t index, DataType* pointer); + void insert(size_t indexAfter, DataType* pointer); + void insert(size_t indexAfter, const std::vector >& objects); + size_t count(const DataType* pointer) const; + + void erase(size_t index); + size_t index(DataType* pointer); + + typename std::vector< PdmPointer >::iterator begin() { return m_pointers.begin(); }; + typename std::vector< PdmPointer >::iterator end() { return m_pointers.end(); }; + + typename std::vector< PdmPointer >::const_iterator begin() const { return m_pointers.begin(); }; + typename std::vector< PdmPointer >::const_iterator end() const { return m_pointers.end(); }; + + // Child objects + + virtual void childObjects(std::vector* objects); + virtual void removeChildObject(PdmObjectHandle* object); + +private: //To be disabled + PDM_DISABLE_COPY_AND_ASSIGN(PdmChildArrayField); + +private: + void removeThisAsParentField(); + void addThisAsParentField(); + +private: + friend class PdmFieldXmlCap< PdmChildArrayField >; + std::vector< PdmPointer > m_pointers; +}; + +} // End of namespace caf + +#include "cafPdmChildArrayField.inl" diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmChildArrayField.inl b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmChildArrayField.inl new file mode 100644 index 0000000000..a5b06a0ec7 --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmChildArrayField.inl @@ -0,0 +1,273 @@ +#include "cafClassTypeName.h" +#include "cafPdmObjectHandle.h" + +namespace caf +{ + +//================================================================================================== +/// Implementation of PdmPointersField<> +//================================================================================================== + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +template +PdmChildArrayField::~PdmChildArrayField() +{ + this->removeThisAsParentField(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +template +DataType* PdmChildArrayField::operator[](size_t index) const +{ + return m_pointers[index]; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +template +void PdmChildArrayField::push_back(DataType* pointer) +{ + m_pointers.push_back(pointer); + if (pointer) pointer->setAsParentField(this); +} + +//-------------------------------------------------------------------------------------------------- +/// Set the value at position index to pointer, overwriting any pointer already present at that +/// position without deleting the object pointed to. +//-------------------------------------------------------------------------------------------------- +template +void PdmChildArrayField::set(size_t index, DataType* pointer) +{ + if (m_pointers[index]) m_pointers[index]->removeAsParentField(this); + m_pointers[index] = pointer; + if (m_pointers[index]) pointer->setAsParentField(this); +} + +//-------------------------------------------------------------------------------------------------- +/// Insert pointer at position index, pushing the value previously at that position and all +/// the preceding values backwards +//-------------------------------------------------------------------------------------------------- +template +void PdmChildArrayField::insert(size_t index, DataType* pointer) +{ + m_pointers.insert(m_pointers.begin()+index, pointer); + + if (pointer) pointer->setAsParentField(this); +} + + +//-------------------------------------------------------------------------------------------------- +/// Insert the pointers at position index, pushing the value previously at that position and all +/// the preceding values backwards +//-------------------------------------------------------------------------------------------------- +template +void PdmChildArrayField::insert(size_t index, const std::vector >& objects) +{ + m_pointers.insert(m_pointers.begin()+index, objects.begin(), objects.end()); + + typename std::vector< PdmPointer< DataType > >::iterator it; + for (it = m_pointers.begin()+index; it != m_pointers.end(); ++it) + { + if (!it->isNull()) + { + (*it)->setAsParentField(this); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// Returns the number of times pointer is referenced from the container. +//-------------------------------------------------------------------------------------------------- +template +size_t PdmChildArrayField::count(const DataType* pointer) const +{ + size_t itemCount = 0; + + typename std::vector< PdmPointer< DataType > >::const_iterator it; + for (it = m_pointers.begin(); it != m_pointers.end(); ++it) + { + if (*it == pointer) + { + itemCount++; + } + } + + return itemCount; +} + +//-------------------------------------------------------------------------------------------------- +/// Empty the container without deleting the objects pointed to. +//-------------------------------------------------------------------------------------------------- +template +void PdmChildArrayField::clear() +{ + this->removeThisAsParentField(); + m_pointers.clear(); +} + +//-------------------------------------------------------------------------------------------------- +/// Deletes all the objects pointed to by the field, then clears the container. +//-------------------------------------------------------------------------------------------------- +template +void PdmChildArrayField::deleteAllChildObjects() +{ + size_t index; + for (index = 0; index < m_pointers.size(); ++index) + { + delete(m_pointers[index].rawPtr()); + } + + m_pointers.clear(); +} + +//-------------------------------------------------------------------------------------------------- +/// Removes the pointer at index from the container. Does not delete the object pointed to. +/// Todo: This implementation can't be necessary in the new regime. Should be to just remove +/// the item at index (shrinking the array) +//-------------------------------------------------------------------------------------------------- +template +void PdmChildArrayField::erase(size_t index) +{ + if (m_pointers[index].rawPtr()) + { + m_pointers[index].rawPtr()->removeAsParentField(this); + } + + m_pointers.erase(m_pointers.begin() + index); +} + + +//-------------------------------------------------------------------------------------------------- +/// Get the index of the given object pointer +//-------------------------------------------------------------------------------------------------- +template +size_t PdmChildArrayField::index(DataType* pointer) +{ + for (size_t i = 0; i < m_pointers.size(); ++i) + { + if (pointer == m_pointers[i].p()) + { + return i; + } + } + + return (size_t)(-1); // Undefined size_t > m_pointers.size(); +} + + +//-------------------------------------------------------------------------------------------------- +/// Removes all instances of object pointer from the container without deleting the object. +//-------------------------------------------------------------------------------------------------- +template +void PdmChildArrayField::removeChildObject(PdmObjectHandle* object) +{ + std::vector< PdmPointer > tempPointers; + + tempPointers = m_pointers; + m_pointers.clear(); + + for (size_t index = 0; index < tempPointers.size(); ++index) + { + if (tempPointers[index].rawPtr() != object) + { + m_pointers.push_back(tempPointers[index]); + } + else + { + if (tempPointers[index].rawPtr()) + { + tempPointers[index].rawPtr()->removeAsParentField(this); + } + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +template +void PdmChildArrayField::childObjects(std::vector* objects) +{ + if (!objects) return; + size_t i; + for (i = 0; i < m_pointers.size(); ++i) + { + objects->push_back(m_pointers[i].rawPtr()); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +template +void PdmChildArrayField::insertAt(int indexAfter, PdmObjectHandle* obj) +{ + // This method should assert if obj to insert is not castable to the container type, but since this + // is a virtual method, its implementation is always created and that makes a dyn_cast add the need for + // #include of the header file "everywhere" + typename std::vector< PdmPointer >::iterator it; + + if (indexAfter == -1) + { + m_pointers.push_back(PdmPointer()); + it = m_pointers.end() - 1; + } + else + { + m_pointers.insert(m_pointers.begin() + indexAfter, PdmPointer()); + it = m_pointers.begin() + indexAfter; + } + + it->setRawPtr(obj); + obj->setAsParentField(this); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +template +PdmObjectHandle* PdmChildArrayField::at(size_t index) +{ + return m_pointers[index].rawPtr(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +template +void PdmChildArrayField::removeThisAsParentField() +{ + typename std::vector< PdmPointer< DataType > >::iterator it; + for (it = m_pointers.begin(); it != m_pointers.end(); ++it) + { + if (!it->isNull()) + { + it->rawPtr()->removeAsParentField(this); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +template +void PdmChildArrayField::addThisAsParentField() +{ + typename std::vector< PdmPointer< DataType > >::iterator it; + for (it = m_pointers.begin(); it != m_pointers.end(); ++it) + { + if (!it->isNull()) + { + (*it)->setAsParentField(this); + } + } +} + +} //End of namespace caf + diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmChildArrayFieldHandle.cpp b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmChildArrayFieldHandle.cpp new file mode 100644 index 0000000000..cceac6102b --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmChildArrayFieldHandle.cpp @@ -0,0 +1,40 @@ +#include "cafPdmChildArrayField.h" + +#include "cafPdmFieldHandle.h" +#include "cafPdmObjectHandle.h" + +namespace caf +{ +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool PdmChildArrayFieldHandle::hasSameFieldCountForAllObjects() +{ + std::vector listObjects; + this->childObjects(&listObjects); + + if (listObjects.size() == 0) + { + return true; + } + + size_t fieldCount = 0; + for (size_t i = 0; i < listObjects.size(); i++) + { + std::vector fields; + listObjects[i]->fields(fields); + + if (i == 0) + { + fieldCount = fields.size(); + } + else if (fieldCount != fields.size()) + { + return false; + } + } + + return true; +} + +} // End of namespace caf diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmChildField.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmChildField.h new file mode 100644 index 0000000000..cd91f7e359 --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmChildField.h @@ -0,0 +1,69 @@ +#pragma once + +#include "cafPdmPointer.h" + +#include "cafPdmFieldHandle.h" +#include + +namespace caf +{ + +template< typename T> class PdmFieldXmlCap; +//================================================================================================== +/// Specialization for pointers, but only applicable to PdmObject derived objects. +/// The pointer is guarded, meaning that it will be set to NULL if the object pointed to +/// is deleted. The referenced object will be printed in place in the xml-file +/// This is supposed to be renamed to PdmChildField +//================================================================================================== + +template +class PdmChildField : public PdmFieldHandle +{ +public: + PdmChildField() + { + bool doNotUsePdmPtrFieldForAnythingButPointersToPdmObject = false; assert(doNotUsePdmPtrFieldForAnythingButPointersToPdmObject); + } +}; + +template +class PdmChildField : public PdmFieldHandle +{ + typedef DataType* DataTypePtr; +public: + PdmChildField() { } + explicit PdmChildField(const DataTypePtr& fieldValue); + virtual ~PdmChildField(); + + // Assignment + + PdmChildField& operator= (const DataTypePtr & fieldValue); + + // Basic access + + DataType* value() const { return m_fieldValue; } + void setValue(const DataTypePtr& fieldValue); + + // Access operators + + /*Conversion*/ operator DataType* () const { return m_fieldValue; } + DataType* operator->() const { return m_fieldValue; } + + const PdmPointer& operator()() const { return m_fieldValue; } + const PdmPointer& v() const { return m_fieldValue; } + + // Child objects + + virtual void childObjects(std::vector* objects); + virtual void removeChildObject(PdmObjectHandle* object); + +private: + PDM_DISABLE_COPY_AND_ASSIGN(PdmChildField); + + friend class PdmFieldXmlCap< PdmChildField >; + PdmPointer m_fieldValue; +}; + +} // End of namespace caf + +#include "cafPdmChildField.inl" diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmChildField.inl b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmChildField.inl new file mode 100644 index 0000000000..d23c6c6a83 --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmChildField.inl @@ -0,0 +1,73 @@ + +#include +#include +#include +namespace caf +{ + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +template +void caf::PdmChildField::childObjects(std::vector* objects) +{ + assert(objects); + PdmObjectHandle* obj = m_fieldValue.rawPtr(); + if (obj) + { + objects->push_back(obj); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +template +void caf::PdmChildField::removeChildObject(PdmObjectHandle* object) +{ + if (m_fieldValue.rawPtr() != NULL && m_fieldValue.rawPtr() == object) + { + m_fieldValue.rawPtr()->removeAsParentField(this); + m_fieldValue.setRawPtr(NULL); + } +} + + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +template +caf::PdmChildField::PdmChildField(const DataTypePtr& fieldValue) +{ + if (m_fieldValue) m_fieldValue->removeAsParentField(this); + m_fieldValue = fieldValue; + if (m_fieldValue != NULL) m_fieldValue->setAsParentField(this); +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +template +caf::PdmChildField::~PdmChildField() +{ + if (!m_fieldValue.isNull()) m_fieldValue.rawPtr()->removeAsParentField(this); + m_fieldValue.setRawPtr(NULL); +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +template +caf::PdmChildField& PdmChildField::operator=(const DataTypePtr & fieldValue) +{ + if (m_fieldValue) m_fieldValue->removeAsParentField(this); + m_fieldValue = fieldValue; + if (m_fieldValue != NULL) m_fieldValue->setAsParentField(this); + return *this; +} + +} //End of namespace caf + diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmCore_UnitTests/CMakeLists.txt b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmCore_UnitTests/CMakeLists.txt new file mode 100644 index 0000000000..6040797dd5 --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmCore_UnitTests/CMakeLists.txt @@ -0,0 +1,56 @@ +cmake_minimum_required (VERSION 2.8) + +find_package ( Qt4 COMPONENTS QtCore ) +include (${QT_USE_FILE}) + +project ( cafPdmCore_UnitTests ) + +include_directories ( + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/.. +) + + +set( PROJECT_FILES + + cafPdmCore_UnitTests.cpp + gtest/gtest-all.cpp + + cafPdmCoreBasicTest.cpp + cafPdmReferenceHelperTest.cpp + cafPdmChildArrayFieldHandleTest.cpp + + Child.cpp + Child.h + Parent.cpp + Parent.h + TestObj.cpp + TestObj.h +) + +# add the executable +add_executable (${PROJECT_NAME} + ${PROJECT_FILES} +) + +source_group("" FILES ${PROJECT_FILES}) + +message(STATUS ${PROJECT_NAME}" - Qt includes : " ${QT_LIBRARIES}) + +target_link_libraries ( ${PROJECT_NAME} + cafPdmCore + ${QT_LIBRARIES} +) + +# Copy Qt Dlls +if (MSVC) + set (QTLIBLIST QtCore ) + foreach (qtlib ${QTLIBLIST}) + + # Debug + execute_process(COMMAND cmake -E copy_if_different ${QT_BINARY_DIR}/${qtlib}d4.dll ${CMAKE_CURRENT_BINARY_DIR}/Debug/${qtlib}d4.dll) + + # Release + execute_process(COMMAND cmake -E copy_if_different ${QT_BINARY_DIR}/${qtlib}4.dll ${CMAKE_CURRENT_BINARY_DIR}/Release/${qtlib}4.dll) + endforeach( qtlib ) +endif(MSVC) diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmCore_UnitTests/Child.cpp b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmCore_UnitTests/Child.cpp new file mode 100644 index 0000000000..9dd5e981fd --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmCore_UnitTests/Child.cpp @@ -0,0 +1,11 @@ +#include "Child.h" +#include "TestObj.h" + +Child::Child() +{ + this->addField(&m_testObj, "Numbers"); +} + +Child::~Child() +{ +} diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmCore_UnitTests/Child.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmCore_UnitTests/Child.h new file mode 100644 index 0000000000..13a9dfe0f9 --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmCore_UnitTests/Child.h @@ -0,0 +1,19 @@ +#pragma once + +#include "cafPdmChildField.h" +#include "cafPdmPointer.h" +#include "cafPdmObjectHandle.h" + +class TestObj; + +class Child: public caf::PdmObjectHandle +{ + +public: + Child(); + ~Child(); + + caf::PdmChildField m_testObj; +}; + + diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmCore_UnitTests/Parent.cpp b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmCore_UnitTests/Parent.cpp new file mode 100644 index 0000000000..7f1d6fd2d1 --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmCore_UnitTests/Parent.cpp @@ -0,0 +1,31 @@ +#include "Parent.h" +#include "Child.h" + + + +Parent::Parent() +{ + this->addField(&m_simpleObjectsField, "SimpleObjects"); + this->addField(&m_simpleObjectF, "SimpleObject"); +} + +Parent::~Parent() +{ +} + + void Parent::doSome() +{ + size_t i = m_simpleObjectsField.size(); + if (i){ + //Child* c = m_simpleObjectsField[0]; + //TestObj* to = c->m_testObj(); + } +} + +#include + + TEST(IncludeTest, Basic) + { + Parent* p = new Parent; + delete(p); + } diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmCore_UnitTests/Parent.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmCore_UnitTests/Parent.h new file mode 100644 index 0000000000..2337885a1d --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmCore_UnitTests/Parent.h @@ -0,0 +1,19 @@ +#pragma once + +#include "cafPdmObjectHandle.h" +#include "cafPdmChildArrayField.h" +#include "cafPdmChildField.h" + +class Child; + +class Parent : public caf::PdmObjectHandle +{ +public: + Parent(); + ~Parent(); + + void doSome(); + + caf::PdmChildArrayField m_simpleObjectsField; + caf::PdmChildField m_simpleObjectF; +}; diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmCore_UnitTests/TestObj.cpp b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmCore_UnitTests/TestObj.cpp new file mode 100644 index 0000000000..1a17980348 --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmCore_UnitTests/TestObj.cpp @@ -0,0 +1,9 @@ +#include "TestObj.h" + + +TestObj::TestObj() +{ + this->addField(&m_position, "Position"); +} + +TestObj::~TestObj() {} diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmCore_UnitTests/TestObj.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmCore_UnitTests/TestObj.h new file mode 100644 index 0000000000..5064facab6 --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmCore_UnitTests/TestObj.h @@ -0,0 +1,14 @@ +#pragma once + +#include "cafPdmPointer.h" +#include "cafPdmDataValueField.h" +#include "cafPdmObjectHandle.h" + +class TestObj : public caf::PdmObjectHandle +{ +public: + TestObj(); + ~TestObj(); + + caf::PdmDataValueField m_position; +}; diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmCore_UnitTests/cafPdmChildArrayFieldHandleTest.cpp b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmCore_UnitTests/cafPdmChildArrayFieldHandleTest.cpp new file mode 100644 index 0000000000..0a85d52856 --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmCore_UnitTests/cafPdmChildArrayFieldHandleTest.cpp @@ -0,0 +1,130 @@ + +#include "gtest/gtest.h" + +#include "cafAppEnum.h" + +#include "cafPdmObjectHandle.h" +#include "cafPdmProxyValueField.h" +#include "cafPdmPtrField.h" +#include "cafPdmReferenceHelper.h" +#include "cafPdmDataValueField.h" +#include "cafPdmChildArrayField.h" +#include "cafPdmChildField.h" + +#include + +class MsjSimpleObj : public caf::PdmObjectHandle +{ +public: + MsjSimpleObj() : PdmObjectHandle() + { + this->addField(&name, "Name"); + this->addField(&id, "ID"); + + static int a = 0; + + id = a++; + name = QString("Name %1").arg(id); + } + + caf::PdmDataValueField name; + caf::PdmDataValueField id; +}; + +class SimpleObjDerived : public MsjSimpleObj +{ +public: + SimpleObjDerived() : MsjSimpleObj() + { + this->addField(&valueA, "valueA"); + } + + caf::PdmDataValueField valueA; +}; + +class SimpleObjDerivedOther : public MsjSimpleObj +{ +public: + SimpleObjDerivedOther() : MsjSimpleObj() + { + this->addField(&valueDouble, "valueDouble"); + } + + caf::PdmDataValueField valueDouble; +}; + +class ContainerObj : public caf::PdmObjectHandle +{ +public: + ContainerObj() : PdmObjectHandle() + { + this->addField(&derivedObjs, "derivedObjs"); + } + + ~ContainerObj() + { + derivedObjs.deleteAllChildObjects(); + } + + caf::PdmChildArrayField derivedObjs; + caf::PdmChildArrayField derivedOtherObjs; +}; + +template +U findObjectById(T start, T end, int id) +{ + for (T it = start; it != end; it++) + { + if (id == it->p()->id()) + { + return it->p(); + } + } + + return NULL; +} + +TEST(ChildArrayFieldHandle, DerivedObjects) +{ + ContainerObj* containerObj = new ContainerObj; + + SimpleObjDerived* s0 = new SimpleObjDerived; + SimpleObjDerived* s1 = new SimpleObjDerived; + SimpleObjDerived* s2 = new SimpleObjDerived; + containerObj->derivedObjs.push_back(s0); + containerObj->derivedObjs.push_back(s1); + containerObj->derivedObjs.push_back(s2); + + SimpleObjDerived* myObj = NULL; + myObj = findObjectById(containerObj->derivedObjs.begin(), containerObj->derivedObjs.end(), 2); + EXPECT_EQ(s2, myObj); + + myObj = findObjectById(containerObj->derivedObjs.begin(), containerObj->derivedObjs.end(), -1); + EXPECT_EQ(NULL, myObj); + + delete containerObj; +} + +TEST(ChildArrayFieldHandle, DerivedOtherObjects) +{ + ContainerObj* containerObj = new ContainerObj; + + SimpleObjDerivedOther* s0 = new SimpleObjDerivedOther; + SimpleObjDerivedOther* s1 = new SimpleObjDerivedOther; + SimpleObjDerivedOther* s2 = new SimpleObjDerivedOther; + + int s2Id = s2->id; + + containerObj->derivedOtherObjs.push_back(s0); + containerObj->derivedOtherObjs.push_back(s1); + containerObj->derivedOtherObjs.push_back(s2); + + SimpleObjDerivedOther* myObj = NULL; + myObj = findObjectById(containerObj->derivedOtherObjs.begin(), containerObj->derivedOtherObjs.end(), s2Id); + EXPECT_EQ(s2, myObj); + + myObj = findObjectById(containerObj->derivedOtherObjs.begin(), containerObj->derivedOtherObjs.end(), -1); + EXPECT_EQ(NULL, myObj); + + delete containerObj; +} diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmCore_UnitTests/cafPdmCoreBasicTest.cpp b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmCore_UnitTests/cafPdmCoreBasicTest.cpp new file mode 100644 index 0000000000..6306af2b72 --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmCore_UnitTests/cafPdmCoreBasicTest.cpp @@ -0,0 +1,576 @@ + +#include "gtest/gtest.h" + +#include "Parent.h" + +#include "cafPdmChildArrayField.h" +#include "cafPdmChildField.h" +#include "cafPdmDataValueField.h" +#include "cafPdmObjectHandle.h" +#include "cafPdmProxyValueField.h" +#include "cafPdmPtrField.h" +#include "cafPdmReferenceHelper.h" +#include "cafPdmValueField.h" + + +class DemoPdmObject: public caf::PdmObjectHandle +{ +public: + + DemoPdmObject() + { + this->addField(&m_proxyDoubleField, "m_proxyDoubleField"); + m_proxyDoubleField.registerSetMethod(this, &DemoPdmObject::setDoubleMember); + m_proxyDoubleField.registerGetMethod(this, &DemoPdmObject::doubleMember); + + this->addField(&m_proxyIntField, "m_proxyIntField"); + m_proxyIntField.registerSetMethod(this, &DemoPdmObject::setIntMember); + m_proxyIntField.registerGetMethod(this, &DemoPdmObject::intMember); + + this->addField(&m_proxyStringField, "m_proxyStringField"); + m_proxyStringField.registerSetMethod(this, &DemoPdmObject::setStringMember); + m_proxyStringField.registerGetMethod(this, &DemoPdmObject::stringMember); + + this->addField(&m_memberDoubleField, "m_memberDoubleField"); + this->addField(&m_memberIntField, "m_memberIntField"); + this->addField(&m_memberStringField, "m_memberStringField"); + + + // Default values + m_doubleMember = 2.1; + m_intMember = 7; + m_stringMember = "abba"; + + m_memberDoubleField = 0.0; + m_memberIntField = 0; + m_memberStringField = ""; + + } + + ~DemoPdmObject() + { + } + + // Fields + caf::PdmProxyValueField m_proxyDoubleField; + caf::PdmProxyValueField m_proxyIntField; + caf::PdmProxyValueField m_proxyStringField; + + caf::PdmDataValueField m_memberDoubleField; + caf::PdmDataValueField m_memberIntField; + caf::PdmDataValueField m_memberStringField; + + + // Internal class members accessed by proxy fields + double doubleMember() const { std::cout << "doubleMember" << std::endl; return m_doubleMember; } + void setDoubleMember(const double& d) { m_doubleMember = d; std::cout << "setDoubleMember" << std::endl; } + + int intMember() const { return m_intMember; } + void setIntMember(const int& val) { m_intMember = val; } + + QString stringMember() const { return m_stringMember; } + void setStringMember(const QString& val) { m_stringMember = val; } + +private: + double m_doubleMember; + int m_intMember; + QString m_stringMember; +}; + + +class InheritedDemoObj : public DemoPdmObject +{ +public: + + InheritedDemoObj() + { + this->addField(&m_texts, "Texts"); + this->addField(&m_childArrayField, "DemoPdmObjectects"); + this->addField(&m_ptrField, "m_ptrField"); + + } + + caf::PdmDataValueField m_texts; + caf::PdmChildArrayField m_childArrayField; + caf::PdmPtrField m_ptrField; +}; + + +TEST(BaseTest, Delete) +{ + DemoPdmObject* s2 = new DemoPdmObject; + delete s2; +} + + +//-------------------------------------------------------------------------------------------------- +/// TestPdmDataValueField +//-------------------------------------------------------------------------------------------------- +TEST(BaseTest, TestPdmDataValueField) +{ + DemoPdmObject* a = new DemoPdmObject; + + + ASSERT_DOUBLE_EQ(0.0, a->m_memberDoubleField.value()); + a->m_memberDoubleField.setValue(1.2); + ASSERT_DOUBLE_EQ(1.2, a->m_memberDoubleField.value()); + + ASSERT_EQ(0, a->m_memberIntField.value()); + a->m_memberIntField.setValue(11); + ASSERT_EQ(11, a->m_memberIntField.value()); + + ASSERT_TRUE(a->m_memberStringField.value().isEmpty()); + a->m_memberStringField.setValue("123"); + ASSERT_TRUE(a->m_memberStringField.value() == "123"); + + +} + +//-------------------------------------------------------------------------------------------------- +/// TestPdmProxyValueField +//-------------------------------------------------------------------------------------------------- +TEST(BaseTest, TestPdmProxyValueField) +{ + DemoPdmObject* a = new DemoPdmObject; + + ASSERT_DOUBLE_EQ(2.1, a->m_proxyDoubleField.value()); + a->m_proxyDoubleField.setValue(1.2); + ASSERT_DOUBLE_EQ(1.2, a->m_proxyDoubleField.value()); + + ASSERT_EQ(7, a->m_proxyIntField.value()); + a->m_proxyIntField.setValue(11); + ASSERT_EQ(11, a->m_proxyIntField.value()); + + ASSERT_TRUE(a->m_proxyStringField.value() == "abba"); + a->m_proxyStringField.setValue("123"); + ASSERT_TRUE(a->m_proxyStringField.value() == "123"); + +} + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +TEST(BaseTest, TestPdmValueFieldInterface) +{ + DemoPdmObject* a = new DemoPdmObject; + + { + caf::PdmValueField* valField = dynamic_cast(a->findField("m_proxyDoubleField")); + QVariant newVal = 3.4; + valField->setFromQVariant(newVal); + QVariant var = valField->toQVariant(); + ASSERT_TRUE(newVal == var); + } + + { + caf::PdmValueField* valField = dynamic_cast(a->findField("m_proxyIntField")); + QVariant newVal = 3; + valField->setFromQVariant(newVal); + QVariant var = valField->toQVariant(); + ASSERT_TRUE(newVal == var); + } + + { + caf::PdmValueField* valField = dynamic_cast(a->findField("m_proxyStringField")); + QVariant newVal = "test"; + valField->setFromQVariant(newVal); + QVariant var = valField->toQVariant(); + ASSERT_TRUE(newVal == var); + } + + { + caf::PdmValueField* valField = dynamic_cast(a->findField("m_memberDoubleField")); + QVariant newVal = 3.4; + valField->setFromQVariant(newVal); + QVariant var = valField->toQVariant(); + ASSERT_TRUE(newVal == var); + } + + { + caf::PdmValueField* valField = dynamic_cast(a->findField("m_memberIntField")); + QVariant newVal = 3; + valField->setFromQVariant(newVal); + QVariant var = valField->toQVariant(); + ASSERT_TRUE(newVal == var); + } + + { + caf::PdmValueField* valField = dynamic_cast(a->findField("m_memberStringField")); + QVariant newVal = "test"; + valField->setFromQVariant(newVal); + QVariant var = valField->toQVariant(); + ASSERT_TRUE(newVal == var); + } + +} + + +//-------------------------------------------------------------------------------------------------- +/// Test of PdmDataValueField operations +//-------------------------------------------------------------------------------------------------- +TEST(BaseTest, NormalPdmField) +{ + class A + { + public: + A(const std::vector& testValue) : field2(testValue), field3(field2) {} + + caf::PdmDataValueField > field1; + caf::PdmDataValueField > field2; + caf::PdmDataValueField > field3; + }; + + + std::vector testValue; + testValue.push_back(1.1); + testValue.push_back(1.2); + testValue.push_back(1.3); + + std::vector testValue2; + testValue2.push_back(2.1); + testValue2.push_back(2.2); + testValue2.push_back(2.3); + + // Constructors + + A a(testValue); + + EXPECT_EQ(1.3, a.field2.v()[2]); + EXPECT_EQ(1.3, a.field3.v()[2]); + EXPECT_EQ(size_t(0), a.field1().size()); + + // Operators + // == + EXPECT_FALSE(a.field1 == a.field3); + // = field to field + a.field1 = a.field2; + // () + EXPECT_EQ(1.3, a.field1()[2]); + // = value to field + a.field1 = testValue2; + // v() + EXPECT_EQ(2.3, a.field1.v()[2]); + // == + a.field3 = a.field1; + EXPECT_TRUE(a.field1 == a.field3); +} + +//-------------------------------------------------------------------------------------------------- +/// Test of PdmChildArrayField operations +//-------------------------------------------------------------------------------------------------- + +TEST(BaseTest, PdmChildArrayField) +{ + InheritedDemoObj* ihd1 = new InheritedDemoObj; + + caf::PdmPointer s1 = new DemoPdmObject; + caf::PdmPointer s2 = new DemoPdmObject; + caf::PdmPointer s3 = new DemoPdmObject; + + // empty() number 1 + EXPECT_TRUE(ihd1->m_childArrayField.empty()); + EXPECT_EQ(size_t(0), ihd1->m_childArrayField.size()); + + // push_back() + ihd1->m_childArrayField.push_back(s1); + ihd1->m_childArrayField.push_back(s2); + ihd1->m_childArrayField.push_back(s3); + + // Parent field + EXPECT_EQ(s1->parentField(), &(ihd1->m_childArrayField)); + + // size() + EXPECT_EQ(size_t(3), ihd1->m_childArrayField.size()); + EXPECT_EQ(size_t(3), ihd1->m_childArrayField.size()); + + // operator[] + EXPECT_EQ(s2, ihd1->m_childArrayField[1]); + EXPECT_EQ(s3, ihd1->m_childArrayField[2]); + + // childObjects + std::vector objects; + ihd1->m_childArrayField.childObjects(&objects); + EXPECT_EQ(size_t(3), objects.size()); + + // set() + ihd1->m_childArrayField.set(1, NULL); + EXPECT_TRUE(NULL == ihd1->m_childArrayField[1]); + EXPECT_TRUE(s2->parentField() == NULL); + + ihd1->m_childArrayField.removeChildObject(NULL); + EXPECT_EQ(size_t(2), ihd1->m_childArrayField.size()); + EXPECT_EQ(s3, ihd1->m_childArrayField[1]); + EXPECT_EQ(s1, ihd1->m_childArrayField[0]); + + // insert() + ihd1->m_childArrayField.insert(1, s2); + EXPECT_EQ(s1, ihd1->m_childArrayField[0]); + EXPECT_EQ(s2, ihd1->m_childArrayField[1]); + EXPECT_EQ(s3, ihd1->m_childArrayField[2]); + + EXPECT_TRUE(s2->parentField() == &(ihd1->m_childArrayField)); + + // erase (index) + ihd1->m_childArrayField.erase(1); + EXPECT_EQ(size_t(2), ihd1->m_childArrayField.size()); + EXPECT_EQ(s3, ihd1->m_childArrayField[1]); + EXPECT_EQ(s1, ihd1->m_childArrayField[0]); + + EXPECT_TRUE(s2->parentField() == NULL); + + // clear() + ihd1->m_childArrayField.clear(); + EXPECT_EQ(size_t(0), ihd1->m_childArrayField.size()); + + EXPECT_TRUE(s1->parentField() == NULL); + + ihd1->m_childArrayField.push_back(s1); + ihd1->m_childArrayField.push_back(s2); + ihd1->m_childArrayField.push_back(s3); + + ihd1->m_childArrayField.deleteAllChildObjects(); + EXPECT_EQ(size_t(0), ihd1->m_childArrayField.size()); + EXPECT_TRUE(s1 == NULL); + EXPECT_TRUE(s2 == NULL); + EXPECT_TRUE(s3 == NULL); +} + + +TEST(BaseTest, PdmChildArrayParentField) +{ + // Test of instanciating a class with forward declare of object used in PdmChildArrayField and PdmChildField + Parent* parentObj = new Parent; + + delete parentObj; + +} + +#include "Child.h" + +TEST(BaseTest, PdmPointersFieldInsertVector) +{ + Parent* ihd1 = new Parent; + + Child* s1 = new Child; + Child* s2 = new Child; + Child* s3 = new Child; + + std::vector > typedObjects; + typedObjects.push_back(s1); + typedObjects.push_back(s2); + typedObjects.push_back(s3); + + ihd1->m_simpleObjectsField.push_back(new Child); + ihd1->m_simpleObjectsField.insert(ihd1->m_simpleObjectsField.size(), typedObjects); + EXPECT_EQ(size_t(4), ihd1->m_simpleObjectsField.size()); + EXPECT_EQ(ihd1->m_simpleObjectsField[3], s3); + + delete ihd1; +} + +//-------------------------------------------------------------------------------------------------- +/// PdmChildArrayFieldHandle +//-------------------------------------------------------------------------------------------------- +TEST(BaseTest, PdmChildArrayFieldHandle) +{ + + // virtual size_t size() const = 0; + // virtual bool empty() const = 0; + // virtual void clear() = 0; + // virtual PdmObject* createAppendObject(int indexAfter) = 0; + // virtual void erase(size_t index) = 0; + // virtual void deleteAllChildObjects() = 0; + // + // virtual PdmObject* at(size_t index) = 0; + // + // bool hasSameFieldCountForAllObjects(); + DemoPdmObject* s0 = new DemoPdmObject; + s0->m_memberDoubleField = 1000; + + DemoPdmObject* s1 = new DemoPdmObject; + s1->m_memberDoubleField = 1000; + + DemoPdmObject* s2 = new DemoPdmObject; + s2->m_memberDoubleField = 2000; + + DemoPdmObject* s3 = new DemoPdmObject; + s3->m_memberDoubleField = 3000; + + InheritedDemoObj* ihd1 = new InheritedDemoObj; + caf::PdmChildArrayFieldHandle* listField = &(ihd1->m_childArrayField); + + EXPECT_EQ(0, listField->size()); + EXPECT_TRUE(listField->hasSameFieldCountForAllObjects()); + EXPECT_TRUE(listField->empty()); + + listField->insertAt(0, s0); + EXPECT_EQ(1, listField->size()); + EXPECT_TRUE(listField->hasSameFieldCountForAllObjects()); + EXPECT_FALSE(listField->empty()); + + ihd1->m_childArrayField.push_back(s1); + ihd1->m_childArrayField.push_back(s2); + ihd1->m_childArrayField.push_back(s3); + + EXPECT_EQ(4, listField->size()); + EXPECT_TRUE(listField->hasSameFieldCountForAllObjects()); + EXPECT_FALSE(listField->empty()); + + listField->erase(0); + EXPECT_EQ(3, listField->size()); + EXPECT_TRUE(listField->hasSameFieldCountForAllObjects()); + EXPECT_FALSE(listField->empty()); + + listField->deleteAllChildObjects(); + EXPECT_EQ(0, listField->size()); + EXPECT_TRUE(listField->hasSameFieldCountForAllObjects()); + EXPECT_TRUE(listField->empty()); + +} +//-------------------------------------------------------------------------------------------------- +/// Test of PdmChildField +//-------------------------------------------------------------------------------------------------- + +TEST(BaseTest, PdmChildField) +{ + class A { + public: + A(Child* a) :field2(a) {} + + caf::PdmChildField field2; + int b; + }; + + { + Parent* parent = new Parent; + Child* testValue = new Child; + + // Constructor assignment + A a(testValue); + EXPECT_EQ(testValue, a.field2.v()); + + // Guarded + delete testValue; + EXPECT_EQ((Child*)0, a.field2); + } + { + A a(NULL); + Child* c2 = new Child; + // Assign + a.field2 = c2; + // Access + EXPECT_EQ(c2, a.field2.v()); + EXPECT_EQ(c2, a.field2); + EXPECT_EQ(c2, a.field2.value()); + EXPECT_TRUE(c2 == a.field2); + + + std::vector objects; + a.field2.childObjects(&objects); + EXPECT_EQ((size_t)1, objects.size()); + EXPECT_EQ(c2, objects[0]); + } +} + + +TEST(BaseTest, PdmPtrField) +{ + InheritedDemoObj* ihd1 = new InheritedDemoObj; + InheritedDemoObj* ihd2 = new InheritedDemoObj; + + // Direct access + EXPECT_EQ((InheritedDemoObj*)NULL, ihd1->m_ptrField); + + InheritedDemoObj* accessedIhd = NULL; + + // Assignment + ihd1->m_ptrField = ihd1; + accessedIhd = ihd1->m_ptrField; + EXPECT_EQ(ihd1, accessedIhd); + + ihd1->m_ptrField = caf::PdmPointer(ihd2); + accessedIhd = ihd1->m_ptrField; + EXPECT_EQ(ihd2, accessedIhd); + + // Access + accessedIhd = ihd1->m_ptrField; // Conversion + EXPECT_EQ(ihd2, accessedIhd); + accessedIhd = ihd1->m_ptrField.value(); + EXPECT_EQ(ihd2, accessedIhd); + accessedIhd = ihd1->m_ptrField.v(); + + caf::PdmPointer accessedPdmPtr; + EXPECT_EQ(ihd2, accessedIhd); + accessedPdmPtr = ihd1->m_ptrField.v(); + EXPECT_EQ(ihd2, accessedPdmPtr.p()); + accessedPdmPtr = ihd1->m_ptrField(); + EXPECT_EQ(ihd2, accessedPdmPtr.p()); + + // Operator == + EXPECT_TRUE(ihd1->m_ptrField == ihd2); + EXPECT_FALSE(ihd1->m_ptrField == ihd1); + + EXPECT_TRUE(ihd1->m_ptrField == caf::PdmPointer(ihd2)); + + // Generic access + std::vector objects; + ihd1->m_ptrField.ptrReferencedObjects(&objects); + EXPECT_EQ(1, objects.size()); + EXPECT_EQ(ihd2, objects[0]); + + // Operator -> + ihd1->m_ptrField->m_texts = "Hei PtrField"; + EXPECT_TRUE(ihd1->m_ptrField->m_texts == "Hei PtrField"); + + // Refrencing system + std::vector ptrFields; + ihd2->referringPtrFields(ptrFields); + EXPECT_EQ(1, ptrFields.size()); + EXPECT_EQ(&(ihd1->m_ptrField), ptrFields[0]); + + objects.clear(); + ihd2->objectsWithReferringPtrFields(objects); + EXPECT_EQ(1, objects.size()); + EXPECT_EQ(ihd1, objects[0]); + + + delete ihd1; + delete ihd2; + +} + + +//-------------------------------------------------------------------------------------------------- +/// Tests the features of PdmPointer +//-------------------------------------------------------------------------------------------------- +TEST(BaseTest, PdmPointer) +{ + InheritedDemoObj * d = new InheritedDemoObj; + + { + caf::PdmPointer p; + EXPECT_TRUE(p == NULL); + } + + { + caf::PdmPointer p(d); + caf::PdmPointer p2(p); + + EXPECT_TRUE(p == d && p2 == d); + EXPECT_TRUE(p.p() == d); + p = 0; + EXPECT_TRUE(p == NULL); + EXPECT_TRUE(p.isNull()); + EXPECT_TRUE(p2 == d); + p = p2; + EXPECT_TRUE(p == d); + delete d; + EXPECT_TRUE(p.isNull() && p2.isNull()); + } + + caf::PdmPointer p3(new DemoPdmObject()); + + delete p3; + +} + + diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmCore_UnitTests/cafPdmCore_UnitTests.cpp b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmCore_UnitTests/cafPdmCore_UnitTests.cpp new file mode 100644 index 0000000000..e50441cd76 --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmCore_UnitTests/cafPdmCore_UnitTests.cpp @@ -0,0 +1,56 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2013 Ceetron AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + + +#include "gtest/gtest.h" +#include +#include +#include + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +int main(int argc, char **argv) +{ + + testing::InitGoogleTest(&argc, argv); + int result = RUN_ALL_TESTS(); + + char text[5]; + std::cin.getline(text, 5); + + return result; +} diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmCore_UnitTests/cafPdmReferenceHelperTest.cpp b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmCore_UnitTests/cafPdmReferenceHelperTest.cpp new file mode 100644 index 0000000000..f8bed80aa1 --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmCore_UnitTests/cafPdmReferenceHelperTest.cpp @@ -0,0 +1,287 @@ + +#include "gtest/gtest.h" + +#include "cafAppEnum.h" + +#include "cafPdmObjectHandle.h" +#include "cafPdmProxyValueField.h" +#include "cafPdmPtrField.h" +#include "cafPdmReferenceHelper.h" +#include "cafPdmDataValueField.h" +#include "cafPdmChildArrayField.h" +#include "cafPdmChildField.h" + + + +class SimpleObj : public caf::PdmObjectHandle +{ +public: + SimpleObj() : PdmObjectHandle() + { + this->addField(&m_position, "m_position"); + this->addField(&m_dir, "m_dir"); + this->addField(&m_up, "m_up"); + this->addField(&m_proxyDouble, "m_proxyDouble"); + } + + caf::PdmDataValueField m_position; + caf::PdmDataValueField m_dir; + caf::PdmDataValueField m_up; + caf::PdmProxyValueField m_proxyDouble; + + void setDoubleMember(const double& d) { m_doubleMember = d; std::cout << "setDoubleMember" << std::endl; } + double doubleMember() const { std::cout << "doubleMember" << std::endl; return m_doubleMember; } + + double m_doubleMember; +}; + + +class ReferenceSimpleObj : public caf::PdmObjectHandle +{ +public: + + ReferenceSimpleObj() : PdmObjectHandle() + { + this->addField(&m_pointersField, "m_pointersField"); + this->addField(&m_simpleObjPtrField, "m_simpleObjPtrField"); + } + + ~ReferenceSimpleObj() + { + delete m_pointersField(); + m_simpleObjPtrField.deleteAllChildObjects(); + } + + // Fields + caf::PdmChildField m_pointersField; + caf::PdmChildArrayField m_simpleObjPtrField; +}; + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(PdmReferenceHelperTest, FindRootFromObject) +{ + { + caf::PdmObjectHandle* obj = NULL; + EXPECT_EQ(NULL, caf::PdmReferenceHelper::findRoot(obj)); + } + + { + caf::PdmObjectHandle* obj = new SimpleObj; + EXPECT_EQ(obj, caf::PdmReferenceHelper::findRoot(obj)); + delete obj; + } + + { + SimpleObj* s1 = new SimpleObj; + ReferenceSimpleObj* ihd1 = new ReferenceSimpleObj; + ihd1->m_simpleObjPtrField.push_back(s1); + + EXPECT_EQ(ihd1, caf::PdmReferenceHelper::findRoot(s1)); + delete ihd1; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(PdmReferenceHelperTest, FindRootFromField) +{ + { + caf::PdmFieldHandle* fieldHandle = NULL; + EXPECT_EQ(NULL, caf::PdmReferenceHelper::findRoot(fieldHandle)); + } + + { + SimpleObj* s1 = new SimpleObj; + ReferenceSimpleObj* ihd1 = new ReferenceSimpleObj; + ihd1->m_simpleObjPtrField.push_back(s1); + + EXPECT_EQ(ihd1, caf::PdmReferenceHelper::findRoot(&s1->m_dir)); + delete ihd1; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(PdmReferenceHelperTest, ReferenceFrommRootToField) +{ + { + caf::PdmObjectHandle* obj = NULL; + caf::PdmFieldHandle* fieldHandle = NULL; + EXPECT_TRUE(caf::PdmReferenceHelper::referenceFromRootToField(obj, fieldHandle).isEmpty()); + } + + { + SimpleObj* s1 = new SimpleObj; + SimpleObj* s2 = new SimpleObj; + SimpleObj* s3 = new SimpleObj; + ReferenceSimpleObj* ihd1 = new ReferenceSimpleObj; + ihd1->m_simpleObjPtrField.push_back(s1); + ihd1->m_simpleObjPtrField.push_back(s2); + ihd1->m_simpleObjPtrField.push_back(s3); + + EXPECT_TRUE(caf::PdmReferenceHelper::referenceFromRootToField(NULL, &s3->m_dir).isEmpty()); + EXPECT_TRUE(caf::PdmReferenceHelper::referenceFromRootToField(ihd1, NULL).isEmpty()); + + QString refString = caf::PdmReferenceHelper::referenceFromRootToField(ihd1, &s3->m_dir); + QString expectedString = "m_dir m_simpleObjPtrField 2"; + EXPECT_STREQ(expectedString.toAscii(), refString.toAscii()); + + delete ihd1; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(PdmReferenceHelperTest, ReferenceFrommRootToObject) +{ + { + caf::PdmObjectHandle* root = NULL; + caf::PdmObjectHandle* obj = NULL; + EXPECT_TRUE(caf::PdmReferenceHelper::referenceFromRootToObject(root, obj).isEmpty()); + } + + { + SimpleObj* s1 = new SimpleObj; + SimpleObj* s2 = new SimpleObj; + SimpleObj* s3 = new SimpleObj; + ReferenceSimpleObj* ihd1 = new ReferenceSimpleObj; + ihd1->m_simpleObjPtrField.push_back(s1); + ihd1->m_simpleObjPtrField.push_back(s2); + ihd1->m_simpleObjPtrField.push_back(s3); + + EXPECT_TRUE(caf::PdmReferenceHelper::referenceFromRootToObject(NULL, s3).isEmpty()); + EXPECT_TRUE(caf::PdmReferenceHelper::referenceFromRootToObject(ihd1, NULL).isEmpty()); + + QString refString = caf::PdmReferenceHelper::referenceFromRootToObject(ihd1, s3); + QString expectedString = "m_simpleObjPtrField 2"; + EXPECT_STREQ(expectedString.toAscii(), refString.toAscii()); + + ReferenceSimpleObj* ihd2 = new ReferenceSimpleObj; + SimpleObj* s4 = new SimpleObj; + ihd2->m_simpleObjPtrField.push_back(s4); + + EXPECT_TRUE(caf::PdmReferenceHelper::referenceFromRootToObject(ihd1, s4).isEmpty()); + + delete ihd1; + delete ihd2; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(PdmReferenceHelperTest, ObjectFromReference) +{ + { + caf::PdmObjectHandle* root = NULL; + EXPECT_EQ(NULL, caf::PdmReferenceHelper::objectFromReference(root, "")); + EXPECT_EQ(NULL, caf::PdmReferenceHelper::objectFromReference(root, "a 2 b 4")); + } + + { + SimpleObj* s1 = new SimpleObj; + SimpleObj* s2 = new SimpleObj; + ReferenceSimpleObj* ihd1 = new ReferenceSimpleObj; + ihd1->m_simpleObjPtrField.push_back(s1); + ihd1->m_simpleObjPtrField.push_back(s2); + + EXPECT_EQ(NULL, caf::PdmReferenceHelper::objectFromReference(ihd1, "")); + EXPECT_EQ(NULL, caf::PdmReferenceHelper::objectFromReference(ihd1, "a 2 b 4")); + + QString refString = caf::PdmReferenceHelper::referenceFromRootToObject(ihd1, s2); + EXPECT_EQ(s2, caf::PdmReferenceHelper::objectFromReference(ihd1, refString)); + + ihd1->m_simpleObjPtrField.removeChildObject(s2); + EXPECT_EQ(NULL, caf::PdmReferenceHelper::objectFromReference(ihd1, refString)); + + ihd1->m_simpleObjPtrField.deleteAllChildObjects(); + + EXPECT_EQ(NULL, caf::PdmReferenceHelper::objectFromReference(ihd1, refString)); + + delete s2; + delete ihd1; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(PdmReferenceHelperTest, FieldFromReference) +{ + { + caf::PdmObjectHandle* root = NULL; + EXPECT_EQ(NULL, caf::PdmReferenceHelper::fieldFromReference(root, "")); + EXPECT_EQ(NULL, caf::PdmReferenceHelper::fieldFromReference(root, "a 2 b 4")); + } + + { + SimpleObj* s1 = new SimpleObj; + SimpleObj* s2 = new SimpleObj; + ReferenceSimpleObj* ihd1 = new ReferenceSimpleObj; + ihd1->m_simpleObjPtrField.push_back(s1); + ihd1->m_simpleObjPtrField.push_back(s2); + + EXPECT_EQ(NULL, caf::PdmReferenceHelper::fieldFromReference(ihd1, "")); + EXPECT_EQ(NULL, caf::PdmReferenceHelper::fieldFromReference(ihd1, "a 2 b 4")); + + caf::PdmFieldHandle* fHandle = &s2->m_position; + + QString refString = caf::PdmReferenceHelper::referenceFromRootToField(ihd1, fHandle); + EXPECT_EQ(fHandle, caf::PdmReferenceHelper::fieldFromReference(ihd1, refString)); + + ihd1->m_simpleObjPtrField.removeChildObject(s2); + EXPECT_EQ(NULL, caf::PdmReferenceHelper::fieldFromReference(ihd1, refString)); + + ihd1->m_simpleObjPtrField.deleteAllChildObjects(); + + EXPECT_EQ(NULL, caf::PdmReferenceHelper::fieldFromReference(ihd1, refString)); + + delete s2; + delete ihd1; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(PdmReferenceHelperTest, ReferenceFromFieldToObject) +{ + { + caf::PdmObjectHandle* root = NULL; + caf::PdmFieldHandle* fieldHandle = NULL; + + EXPECT_TRUE(caf::PdmReferenceHelper::referenceFromFieldToObject(fieldHandle, root).isEmpty()); + } + + { + SimpleObj* s1 = new SimpleObj; + SimpleObj* s2 = new SimpleObj; + + caf::PdmFieldHandle* s2FieldHandle = &s2->m_dir; + + // Unrelated objects + EXPECT_TRUE(caf::PdmReferenceHelper::referenceFromFieldToObject(s2FieldHandle, s1).isEmpty()); + + ReferenceSimpleObj* root = new ReferenceSimpleObj; + SimpleObj* root_s1 = new SimpleObj; + root->m_simpleObjPtrField.push_back(root_s1); + + ReferenceSimpleObj* ihd1 = new ReferenceSimpleObj; + root->m_pointersField = ihd1; + + ihd1->m_simpleObjPtrField.push_back(s1); + ihd1->m_simpleObjPtrField.push_back(s2); + + QString refString = caf::PdmReferenceHelper::referenceFromFieldToObject(s2FieldHandle, root_s1); + caf::PdmObjectHandle* obj = caf::PdmReferenceHelper::objectFromFieldReference(s2FieldHandle, refString); + EXPECT_EQ(root_s1, obj); + + delete root; + } +} + diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmCore_UnitTests/gtest/gtest-all.cpp b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmCore_UnitTests/gtest/gtest-all.cpp new file mode 100644 index 0000000000..644479a63c --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmCore_UnitTests/gtest/gtest-all.cpp @@ -0,0 +1,8510 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: mheule@google.com (Markus Heule) +// +// Google C++ Testing Framework (Google Test) +// +// Sometimes it's desirable to build Google Test by compiling a single file. +// This file serves this purpose. + +// This line ensures that gtest.h can be compiled on its own, even +// when it's fused. +#include + +// The following lines pull in the real gtest *.cc files. +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: wan@google.com (Zhanyong Wan) +// +// The Google C++ Testing Framework (Google Test) + +// Copyright 2007, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: wan@google.com (Zhanyong Wan) +// +// Utilities for testing Google Test itself and code that uses Google Test +// (e.g. frameworks built on top of Google Test). + +#ifndef GTEST_INCLUDE_GTEST_GTEST_SPI_H_ +#define GTEST_INCLUDE_GTEST_GTEST_SPI_H_ + + +namespace testing { + +// This helper class can be used to mock out Google Test failure reporting +// so that we can test Google Test or code that builds on Google Test. +// +// An object of this class appends a TestPartResult object to the +// TestPartResultArray object given in the constructor whenever a Google Test +// failure is reported. It can either intercept only failures that are +// generated in the same thread that created this object or it can intercept +// all generated failures. The scope of this mock object can be controlled with +// the second argument to the two arguments constructor. +class GTEST_API_ ScopedFakeTestPartResultReporter + : public TestPartResultReporterInterface { + public: + // The two possible mocking modes of this object. + enum InterceptMode { + INTERCEPT_ONLY_CURRENT_THREAD, // Intercepts only thread local failures. + INTERCEPT_ALL_THREADS // Intercepts all failures. + }; + + // The c'tor sets this object as the test part result reporter used + // by Google Test. The 'result' parameter specifies where to report the + // results. This reporter will only catch failures generated in the current + // thread. DEPRECATED + explicit ScopedFakeTestPartResultReporter(TestPartResultArray* result); + + // Same as above, but you can choose the interception scope of this object. + ScopedFakeTestPartResultReporter(InterceptMode intercept_mode, + TestPartResultArray* result); + + // The d'tor restores the previous test part result reporter. + virtual ~ScopedFakeTestPartResultReporter(); + + // Appends the TestPartResult object to the TestPartResultArray + // received in the constructor. + // + // This method is from the TestPartResultReporterInterface + // interface. + virtual void ReportTestPartResult(const TestPartResult& result); + private: + void Init(); + + const InterceptMode intercept_mode_; + TestPartResultReporterInterface* old_reporter_; + TestPartResultArray* const result_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedFakeTestPartResultReporter); +}; + +namespace internal { + +// A helper class for implementing EXPECT_FATAL_FAILURE() and +// EXPECT_NONFATAL_FAILURE(). Its destructor verifies that the given +// TestPartResultArray contains exactly one failure that has the given +// type and contains the given substring. If that's not the case, a +// non-fatal failure will be generated. +class GTEST_API_ SingleFailureChecker { + public: + // The constructor remembers the arguments. + SingleFailureChecker(const TestPartResultArray* results, + TestPartResult::Type type, + const char* substr); + ~SingleFailureChecker(); + private: + const TestPartResultArray* const results_; + const TestPartResult::Type type_; + const String substr_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(SingleFailureChecker); +}; + +} // namespace internal + +} // namespace testing + +// A set of macros for testing Google Test assertions or code that's expected +// to generate Google Test fatal failures. It verifies that the given +// statement will cause exactly one fatal Google Test failure with 'substr' +// being part of the failure message. +// +// There are two different versions of this macro. EXPECT_FATAL_FAILURE only +// affects and considers failures generated in the current thread and +// EXPECT_FATAL_FAILURE_ON_ALL_THREADS does the same but for all threads. +// +// The verification of the assertion is done correctly even when the statement +// throws an exception or aborts the current function. +// +// Known restrictions: +// - 'statement' cannot reference local non-static variables or +// non-static members of the current object. +// - 'statement' cannot return a value. +// - You cannot stream a failure message to this macro. +// +// Note that even though the implementations of the following two +// macros are much alike, we cannot refactor them to use a common +// helper macro, due to some peculiarity in how the preprocessor +// works. The AcceptsMacroThatExpandsToUnprotectedComma test in +// gtest_unittest.cc will fail to compile if we do that. +#define EXPECT_FATAL_FAILURE(statement, substr) \ + do { \ + class GTestExpectFatalFailureHelper {\ + public:\ + static void Execute() { statement; }\ + };\ + ::testing::TestPartResultArray gtest_failures;\ + ::testing::internal::SingleFailureChecker gtest_checker(\ + >est_failures, ::testing::TestPartResult::kFatalFailure, (substr));\ + {\ + ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ + ::testing::ScopedFakeTestPartResultReporter:: \ + INTERCEPT_ONLY_CURRENT_THREAD, >est_failures);\ + GTestExpectFatalFailureHelper::Execute();\ + }\ + } while (::testing::internal::AlwaysFalse()) + +#define EXPECT_FATAL_FAILURE_ON_ALL_THREADS(statement, substr) \ + do { \ + class GTestExpectFatalFailureHelper {\ + public:\ + static void Execute() { statement; }\ + };\ + ::testing::TestPartResultArray gtest_failures;\ + ::testing::internal::SingleFailureChecker gtest_checker(\ + >est_failures, ::testing::TestPartResult::kFatalFailure, (substr));\ + {\ + ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ + ::testing::ScopedFakeTestPartResultReporter:: \ + INTERCEPT_ALL_THREADS, >est_failures);\ + GTestExpectFatalFailureHelper::Execute();\ + }\ + } while (::testing::internal::AlwaysFalse()) + +// A macro for testing Google Test assertions or code that's expected to +// generate Google Test non-fatal failures. It asserts that the given +// statement will cause exactly one non-fatal Google Test failure with 'substr' +// being part of the failure message. +// +// There are two different versions of this macro. EXPECT_NONFATAL_FAILURE only +// affects and considers failures generated in the current thread and +// EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS does the same but for all threads. +// +// 'statement' is allowed to reference local variables and members of +// the current object. +// +// The verification of the assertion is done correctly even when the statement +// throws an exception or aborts the current function. +// +// Known restrictions: +// - You cannot stream a failure message to this macro. +// +// Note that even though the implementations of the following two +// macros are much alike, we cannot refactor them to use a common +// helper macro, due to some peculiarity in how the preprocessor +// works. If we do that, the code won't compile when the user gives +// EXPECT_NONFATAL_FAILURE() a statement that contains a macro that +// expands to code containing an unprotected comma. The +// AcceptsMacroThatExpandsToUnprotectedComma test in gtest_unittest.cc +// catches that. +// +// For the same reason, we have to write +// if (::testing::internal::AlwaysTrue()) { statement; } +// instead of +// GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement) +// to avoid an MSVC warning on unreachable code. +#define EXPECT_NONFATAL_FAILURE(statement, substr) \ + do {\ + ::testing::TestPartResultArray gtest_failures;\ + ::testing::internal::SingleFailureChecker gtest_checker(\ + >est_failures, ::testing::TestPartResult::kNonFatalFailure, \ + (substr));\ + {\ + ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ + ::testing::ScopedFakeTestPartResultReporter:: \ + INTERCEPT_ONLY_CURRENT_THREAD, >est_failures);\ + if (::testing::internal::AlwaysTrue()) { statement; }\ + }\ + } while (::testing::internal::AlwaysFalse()) + +#define EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(statement, substr) \ + do {\ + ::testing::TestPartResultArray gtest_failures;\ + ::testing::internal::SingleFailureChecker gtest_checker(\ + >est_failures, ::testing::TestPartResult::kNonFatalFailure, \ + (substr));\ + {\ + ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ + ::testing::ScopedFakeTestPartResultReporter::INTERCEPT_ALL_THREADS,\ + >est_failures);\ + if (::testing::internal::AlwaysTrue()) { statement; }\ + }\ + } while (::testing::internal::AlwaysFalse()) + +#endif // GTEST_INCLUDE_GTEST_GTEST_SPI_H_ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#if GTEST_OS_LINUX + +// TODO(kenton@google.com): Use autoconf to detect availability of +// gettimeofday(). +#define GTEST_HAS_GETTIMEOFDAY_ 1 + +#include +#include +#include +// Declares vsnprintf(). This header is not available on Windows. +#include +#include +#include +#include +#include +#include + +#elif GTEST_OS_SYMBIAN +#define GTEST_HAS_GETTIMEOFDAY_ 1 +#include // NOLINT + +#elif GTEST_OS_ZOS +#define GTEST_HAS_GETTIMEOFDAY_ 1 +#include // NOLINT + +// On z/OS we additionally need strings.h for strcasecmp. +#include // NOLINT + +#elif GTEST_OS_WINDOWS_MOBILE // We are on Windows CE. + +#include // NOLINT + +#elif GTEST_OS_WINDOWS // We are on Windows proper. + +#include // NOLINT +#include // NOLINT +#include // NOLINT +#include // NOLINT + +#if GTEST_OS_WINDOWS_MINGW +// MinGW has gettimeofday() but not _ftime64(). +// TODO(kenton@google.com): Use autoconf to detect availability of +// gettimeofday(). +// TODO(kenton@google.com): There are other ways to get the time on +// Windows, like GetTickCount() or GetSystemTimeAsFileTime(). MinGW +// supports these. consider using them instead. +#define GTEST_HAS_GETTIMEOFDAY_ 1 +#include // NOLINT +#endif // GTEST_OS_WINDOWS_MINGW + +// cpplint thinks that the header is already included, so we want to +// silence it. +#include // NOLINT + +#else + +// Assume other platforms have gettimeofday(). +// TODO(kenton@google.com): Use autoconf to detect availability of +// gettimeofday(). +#define GTEST_HAS_GETTIMEOFDAY_ 1 + +// cpplint thinks that the header is already included, so we want to +// silence it. +#include // NOLINT +#include // NOLINT + +#endif // GTEST_OS_LINUX + +#if GTEST_HAS_EXCEPTIONS +#include +#endif + +// Indicates that this translation unit is part of Google Test's +// implementation. It must come before gtest-internal-inl.h is +// included, or there will be a compiler error. This trick is to +// prevent a user from accidentally including gtest-internal-inl.h in +// his code. +#define GTEST_IMPLEMENTATION_ 1 +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Utility functions and classes used by the Google C++ testing framework. +// +// Author: wan@google.com (Zhanyong Wan) +// +// This file contains purely Google Test's internal implementation. Please +// DO NOT #INCLUDE IT IN A USER PROGRAM. + +#ifndef GTEST_SRC_GTEST_INTERNAL_INL_H_ +#define GTEST_SRC_GTEST_INTERNAL_INL_H_ + +// GTEST_IMPLEMENTATION_ is defined to 1 iff the current translation unit is +// part of Google Test's implementation; otherwise it's undefined. +#if !GTEST_IMPLEMENTATION_ +// A user is trying to include this from his code - just say no. +#error "gtest-internal-inl.h is part of Google Test's internal implementation." +#error "It must not be included except by Google Test itself." +#endif // GTEST_IMPLEMENTATION_ + +#ifndef _WIN32_WCE +#include +#endif // !_WIN32_WCE +#include +#include // For strtoll/_strtoul64/malloc/free. +#include // For memmove. + +#include +#include +#include + + +#if GTEST_OS_WINDOWS +#include // For DWORD. +#endif // GTEST_OS_WINDOWS + + +namespace testing { + +// Declares the flags. +// +// We don't want the users to modify this flag in the code, but want +// Google Test's own unit tests to be able to access it. Therefore we +// declare it here as opposed to in gtest.h. +GTEST_DECLARE_bool_(death_test_use_fork); + +namespace internal { + +// The value of GetTestTypeId() as seen from within the Google Test +// library. This is solely for testing GetTestTypeId(). +GTEST_API_ extern const TypeId kTestTypeIdInGoogleTest; + +// Names of the flags (needed for parsing Google Test flags). +const char kAlsoRunDisabledTestsFlag[] = "also_run_disabled_tests"; +const char kBreakOnFailureFlag[] = "break_on_failure"; +const char kCatchExceptionsFlag[] = "catch_exceptions"; +const char kColorFlag[] = "color"; +const char kFilterFlag[] = "filter"; +const char kListTestsFlag[] = "list_tests"; +const char kOutputFlag[] = "output"; +const char kPrintTimeFlag[] = "print_time"; +const char kRandomSeedFlag[] = "random_seed"; +const char kRepeatFlag[] = "repeat"; +const char kShuffleFlag[] = "shuffle"; +const char kStackTraceDepthFlag[] = "stack_trace_depth"; +const char kThrowOnFailureFlag[] = "throw_on_failure"; + +// A valid random seed must be in [1, kMaxRandomSeed]. +const int kMaxRandomSeed = 99999; + +// g_help_flag is true iff the --help flag or an equivalent form is +// specified on the command line. +GTEST_API_ extern bool g_help_flag; + +// Returns the current time in milliseconds. +GTEST_API_ TimeInMillis GetTimeInMillis(); + +// Returns true iff Google Test should use colors in the output. +GTEST_API_ bool ShouldUseColor(bool stdout_is_tty); + +// Formats the given time in milliseconds as seconds. +GTEST_API_ std::string FormatTimeInMillisAsSeconds(TimeInMillis ms); + +// Parses a string for an Int32 flag, in the form of "--flag=value". +// +// On success, stores the value of the flag in *value, and returns +// true. On failure, returns false without changing *value. +GTEST_API_ bool ParseInt32Flag( + const char* str, const char* flag, Int32* value); + +// Returns a random seed in range [1, kMaxRandomSeed] based on the +// given --gtest_random_seed flag value. +inline int GetRandomSeedFromFlag(Int32 random_seed_flag) { + const unsigned int raw_seed = (random_seed_flag == 0) ? + static_cast(GetTimeInMillis()) : + static_cast(random_seed_flag); + + // Normalizes the actual seed to range [1, kMaxRandomSeed] such that + // it's easy to type. + const int normalized_seed = + static_cast((raw_seed - 1U) % + static_cast(kMaxRandomSeed)) + 1; + return normalized_seed; +} + +// Returns the first valid random seed after 'seed'. The behavior is +// undefined if 'seed' is invalid. The seed after kMaxRandomSeed is +// considered to be 1. +inline int GetNextRandomSeed(int seed) { + GTEST_CHECK_(1 <= seed && seed <= kMaxRandomSeed) + << "Invalid random seed " << seed << " - must be in [1, " + << kMaxRandomSeed << "]."; + const int next_seed = seed + 1; + return (next_seed > kMaxRandomSeed) ? 1 : next_seed; +} + +// This class saves the values of all Google Test flags in its c'tor, and +// restores them in its d'tor. +class GTestFlagSaver { + public: + // The c'tor. + GTestFlagSaver() { + also_run_disabled_tests_ = GTEST_FLAG(also_run_disabled_tests); + break_on_failure_ = GTEST_FLAG(break_on_failure); + catch_exceptions_ = GTEST_FLAG(catch_exceptions); + color_ = GTEST_FLAG(color); + death_test_style_ = GTEST_FLAG(death_test_style); + death_test_use_fork_ = GTEST_FLAG(death_test_use_fork); + filter_ = GTEST_FLAG(filter); + internal_run_death_test_ = GTEST_FLAG(internal_run_death_test); + list_tests_ = GTEST_FLAG(list_tests); + output_ = GTEST_FLAG(output); + print_time_ = GTEST_FLAG(print_time); + random_seed_ = GTEST_FLAG(random_seed); + repeat_ = GTEST_FLAG(repeat); + shuffle_ = GTEST_FLAG(shuffle); + stack_trace_depth_ = GTEST_FLAG(stack_trace_depth); + throw_on_failure_ = GTEST_FLAG(throw_on_failure); + } + + // The d'tor is not virtual. DO NOT INHERIT FROM THIS CLASS. + ~GTestFlagSaver() { + GTEST_FLAG(also_run_disabled_tests) = also_run_disabled_tests_; + GTEST_FLAG(break_on_failure) = break_on_failure_; + GTEST_FLAG(catch_exceptions) = catch_exceptions_; + GTEST_FLAG(color) = color_; + GTEST_FLAG(death_test_style) = death_test_style_; + GTEST_FLAG(death_test_use_fork) = death_test_use_fork_; + GTEST_FLAG(filter) = filter_; + GTEST_FLAG(internal_run_death_test) = internal_run_death_test_; + GTEST_FLAG(list_tests) = list_tests_; + GTEST_FLAG(output) = output_; + GTEST_FLAG(print_time) = print_time_; + GTEST_FLAG(random_seed) = random_seed_; + GTEST_FLAG(repeat) = repeat_; + GTEST_FLAG(shuffle) = shuffle_; + GTEST_FLAG(stack_trace_depth) = stack_trace_depth_; + GTEST_FLAG(throw_on_failure) = throw_on_failure_; + } + private: + // Fields for saving the original values of flags. + bool also_run_disabled_tests_; + bool break_on_failure_; + bool catch_exceptions_; + String color_; + String death_test_style_; + bool death_test_use_fork_; + String filter_; + String internal_run_death_test_; + bool list_tests_; + String output_; + bool print_time_; + bool pretty_; + internal::Int32 random_seed_; + internal::Int32 repeat_; + bool shuffle_; + internal::Int32 stack_trace_depth_; + bool throw_on_failure_; +} GTEST_ATTRIBUTE_UNUSED_; + +// Converts a Unicode code point to a narrow string in UTF-8 encoding. +// code_point parameter is of type UInt32 because wchar_t may not be +// wide enough to contain a code point. +// The output buffer str must containt at least 32 characters. +// The function returns the address of the output buffer. +// If the code_point is not a valid Unicode code point +// (i.e. outside of Unicode range U+0 to U+10FFFF) it will be output +// as '(Invalid Unicode 0xXXXXXXXX)'. +GTEST_API_ char* CodePointToUtf8(UInt32 code_point, char* str); + +// Converts a wide string to a narrow string in UTF-8 encoding. +// The wide string is assumed to have the following encoding: +// UTF-16 if sizeof(wchar_t) == 2 (on Windows, Cygwin, Symbian OS) +// UTF-32 if sizeof(wchar_t) == 4 (on Linux) +// Parameter str points to a null-terminated wide string. +// Parameter num_chars may additionally limit the number +// of wchar_t characters processed. -1 is used when the entire string +// should be processed. +// If the string contains code points that are not valid Unicode code points +// (i.e. outside of Unicode range U+0 to U+10FFFF) they will be output +// as '(Invalid Unicode 0xXXXXXXXX)'. If the string is in UTF16 encoding +// and contains invalid UTF-16 surrogate pairs, values in those pairs +// will be encoded as individual Unicode characters from Basic Normal Plane. +GTEST_API_ String WideStringToUtf8(const wchar_t* str, int num_chars); + +// Reads the GTEST_SHARD_STATUS_FILE environment variable, and creates the file +// if the variable is present. If a file already exists at this location, this +// function will write over it. If the variable is present, but the file cannot +// be created, prints an error and exits. +void WriteToShardStatusFileIfNeeded(); + +// Checks whether sharding is enabled by examining the relevant +// environment variable values. If the variables are present, +// but inconsistent (e.g., shard_index >= total_shards), prints +// an error and exits. If in_subprocess_for_death_test, sharding is +// disabled because it must only be applied to the original test +// process. Otherwise, we could filter out death tests we intended to execute. +GTEST_API_ bool ShouldShard(const char* total_shards_str, + const char* shard_index_str, + bool in_subprocess_for_death_test); + +// Parses the environment variable var as an Int32. If it is unset, +// returns default_val. If it is not an Int32, prints an error and +// and aborts. +GTEST_API_ Int32 Int32FromEnvOrDie(const char* env_var, Int32 default_val); + +// Given the total number of shards, the shard index, and the test id, +// returns true iff the test should be run on this shard. The test id is +// some arbitrary but unique non-negative integer assigned to each test +// method. Assumes that 0 <= shard_index < total_shards. +GTEST_API_ bool ShouldRunTestOnShard( + int total_shards, int shard_index, int test_id); + +// STL container utilities. + +// Returns the number of elements in the given container that satisfy +// the given predicate. +template +inline int CountIf(const Container& c, Predicate predicate) { + return static_cast(std::count_if(c.begin(), c.end(), predicate)); +} + +// Applies a function/functor to each element in the container. +template +void ForEach(const Container& c, Functor functor) { + std::for_each(c.begin(), c.end(), functor); +} + +// Returns the i-th element of the vector, or default_value if i is not +// in range [0, v.size()). +template +inline E GetElementOr(const std::vector& v, int i, E default_value) { + return (i < 0 || i >= static_cast(v.size())) ? default_value : v[i]; +} + +// Performs an in-place shuffle of a range of the vector's elements. +// 'begin' and 'end' are element indices as an STL-style range; +// i.e. [begin, end) are shuffled, where 'end' == size() means to +// shuffle to the end of the vector. +template +void ShuffleRange(internal::Random* random, int begin, int end, + std::vector* v) { + const int size = static_cast(v->size()); + GTEST_CHECK_(0 <= begin && begin <= size) + << "Invalid shuffle range start " << begin << ": must be in range [0, " + << size << "]."; + GTEST_CHECK_(begin <= end && end <= size) + << "Invalid shuffle range finish " << end << ": must be in range [" + << begin << ", " << size << "]."; + + // Fisher-Yates shuffle, from + // http://en.wikipedia.org/wiki/Fisher-Yates_shuffle + for (int range_width = end - begin; range_width >= 2; range_width--) { + const int last_in_range = begin + range_width - 1; + const int selected = begin + random->Generate(range_width); + std::swap((*v)[selected], (*v)[last_in_range]); + } +} + +// Performs an in-place shuffle of the vector's elements. +template +inline void Shuffle(internal::Random* random, std::vector* v) { + ShuffleRange(random, 0, static_cast(v->size()), v); +} + +// A function for deleting an object. Handy for being used as a +// functor. +template +static void Delete(T* x) { + delete x; +} + +// A predicate that checks the key of a TestProperty against a known key. +// +// TestPropertyKeyIs is copyable. +class TestPropertyKeyIs { + public: + // Constructor. + // + // TestPropertyKeyIs has NO default constructor. + explicit TestPropertyKeyIs(const char* key) + : key_(key) {} + + // Returns true iff the test name of test property matches on key_. + bool operator()(const TestProperty& test_property) const { + return String(test_property.key()).Compare(key_) == 0; + } + + private: + String key_; +}; + +class TestInfoImpl { + public: + TestInfoImpl(TestInfo* parent, const char* test_case_name, + const char* name, const char* test_case_comment, + const char* comment, TypeId fixture_class_id, + internal::TestFactoryBase* factory); + ~TestInfoImpl(); + + // Returns true if this test should run. + bool should_run() const { return should_run_; } + + // Sets the should_run member. + void set_should_run(bool should) { should_run_ = should; } + + // Returns true if this test is disabled. Disabled tests are not run. + bool is_disabled() const { return is_disabled_; } + + // Sets the is_disabled member. + void set_is_disabled(bool is) { is_disabled_ = is; } + + // Returns true if this test matches the filter specified by the user. + bool matches_filter() const { return matches_filter_; } + + // Sets the matches_filter member. + void set_matches_filter(bool matches) { matches_filter_ = matches; } + + // Returns the test case name. + const char* test_case_name() const { return test_case_name_.c_str(); } + + // Returns the test name. + const char* name() const { return name_.c_str(); } + + // Returns the test case comment. + const char* test_case_comment() const { return test_case_comment_.c_str(); } + + // Returns the test comment. + const char* comment() const { return comment_.c_str(); } + + // Returns the ID of the test fixture class. + TypeId fixture_class_id() const { return fixture_class_id_; } + + // Returns the test result. + TestResult* result() { return &result_; } + const TestResult* result() const { return &result_; } + + // Creates the test object, runs it, records its result, and then + // deletes it. + void Run(); + + // Clears the test result. + void ClearResult() { result_.Clear(); } + + // Clears the test result in the given TestInfo object. + static void ClearTestResult(TestInfo * test_info) { + test_info->impl()->ClearResult(); + } + + private: + // These fields are immutable properties of the test. + TestInfo* const parent_; // The owner of this object + const String test_case_name_; // Test case name + const String name_; // Test name + const String test_case_comment_; // Test case comment + const String comment_; // Test comment + const TypeId fixture_class_id_; // ID of the test fixture class + bool should_run_; // True iff this test should run + bool is_disabled_; // True iff this test is disabled + bool matches_filter_; // True if this test matches the + // user-specified filter. + internal::TestFactoryBase* const factory_; // The factory that creates + // the test object + + // This field is mutable and needs to be reset before running the + // test for the second time. + TestResult result_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestInfoImpl); +}; + +// Class UnitTestOptions. +// +// This class contains functions for processing options the user +// specifies when running the tests. It has only static members. +// +// In most cases, the user can specify an option using either an +// environment variable or a command line flag. E.g. you can set the +// test filter using either GTEST_FILTER or --gtest_filter. If both +// the variable and the flag are present, the latter overrides the +// former. +class GTEST_API_ UnitTestOptions { + public: + // Functions for processing the gtest_output flag. + + // Returns the output format, or "" for normal printed output. + static String GetOutputFormat(); + + // Returns the absolute path of the requested output file, or the + // default (test_detail.xml in the original working directory) if + // none was explicitly specified. + static String GetAbsolutePathToOutputFile(); + + // Functions for processing the gtest_filter flag. + + // Returns true iff the wildcard pattern matches the string. The + // first ':' or '\0' character in pattern marks the end of it. + // + // This recursive algorithm isn't very efficient, but is clear and + // works well enough for matching test names, which are short. + static bool PatternMatchesString(const char *pattern, const char *str); + + // Returns true iff the user-specified filter matches the test case + // name and the test name. + static bool FilterMatchesTest(const String &test_case_name, + const String &test_name); + +#if GTEST_OS_WINDOWS + // Function for supporting the gtest_catch_exception flag. + + // Returns EXCEPTION_EXECUTE_HANDLER if Google Test should handle the + // given SEH exception, or EXCEPTION_CONTINUE_SEARCH otherwise. + // This function is useful as an __except condition. + static int GTestShouldProcessSEH(DWORD exception_code); +#endif // GTEST_OS_WINDOWS + + // Returns true if "name" matches the ':' separated list of glob-style + // filters in "filter". + static bool MatchesFilter(const String& name, const char* filter); +}; + +// Returns the current application's name, removing directory path if that +// is present. Used by UnitTestOptions::GetOutputFile. +GTEST_API_ FilePath GetCurrentExecutableName(); + +// The role interface for getting the OS stack trace as a string. +class OsStackTraceGetterInterface { + public: + OsStackTraceGetterInterface() {} + virtual ~OsStackTraceGetterInterface() {} + + // Returns the current OS stack trace as a String. Parameters: + // + // max_depth - the maximum number of stack frames to be included + // in the trace. + // skip_count - the number of top frames to be skipped; doesn't count + // against max_depth. + virtual String CurrentStackTrace(int max_depth, int skip_count) = 0; + + // UponLeavingGTest() should be called immediately before Google Test calls + // user code. It saves some information about the current stack that + // CurrentStackTrace() will use to find and hide Google Test stack frames. + virtual void UponLeavingGTest() = 0; + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(OsStackTraceGetterInterface); +}; + +// A working implementation of the OsStackTraceGetterInterface interface. +class OsStackTraceGetter : public OsStackTraceGetterInterface { + public: + OsStackTraceGetter() : caller_frame_(NULL) {} + virtual String CurrentStackTrace(int max_depth, int skip_count); + virtual void UponLeavingGTest(); + + // This string is inserted in place of stack frames that are part of + // Google Test's implementation. + static const char* const kElidedFramesMarker; + + private: + Mutex mutex_; // protects all internal state + + // We save the stack frame below the frame that calls user code. + // We do this because the address of the frame immediately below + // the user code changes between the call to UponLeavingGTest() + // and any calls to CurrentStackTrace() from within the user code. + void* caller_frame_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(OsStackTraceGetter); +}; + +// Information about a Google Test trace point. +struct TraceInfo { + const char* file; + int line; + String message; +}; + +// This is the default global test part result reporter used in UnitTestImpl. +// This class should only be used by UnitTestImpl. +class DefaultGlobalTestPartResultReporter + : public TestPartResultReporterInterface { + public: + explicit DefaultGlobalTestPartResultReporter(UnitTestImpl* unit_test); + // Implements the TestPartResultReporterInterface. Reports the test part + // result in the current test. + virtual void ReportTestPartResult(const TestPartResult& result); + + private: + UnitTestImpl* const unit_test_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultGlobalTestPartResultReporter); +}; + +// This is the default per thread test part result reporter used in +// UnitTestImpl. This class should only be used by UnitTestImpl. +class DefaultPerThreadTestPartResultReporter + : public TestPartResultReporterInterface { + public: + explicit DefaultPerThreadTestPartResultReporter(UnitTestImpl* unit_test); + // Implements the TestPartResultReporterInterface. The implementation just + // delegates to the current global test part result reporter of *unit_test_. + virtual void ReportTestPartResult(const TestPartResult& result); + + private: + UnitTestImpl* const unit_test_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultPerThreadTestPartResultReporter); +}; + +// The private implementation of the UnitTest class. We don't protect +// the methods under a mutex, as this class is not accessible by a +// user and the UnitTest class that delegates work to this class does +// proper locking. +class GTEST_API_ UnitTestImpl { + public: + explicit UnitTestImpl(UnitTest* parent); + virtual ~UnitTestImpl(); + + // There are two different ways to register your own TestPartResultReporter. + // You can register your own repoter to listen either only for test results + // from the current thread or for results from all threads. + // By default, each per-thread test result repoter just passes a new + // TestPartResult to the global test result reporter, which registers the + // test part result for the currently running test. + + // Returns the global test part result reporter. + TestPartResultReporterInterface* GetGlobalTestPartResultReporter(); + + // Sets the global test part result reporter. + void SetGlobalTestPartResultReporter( + TestPartResultReporterInterface* reporter); + + // Returns the test part result reporter for the current thread. + TestPartResultReporterInterface* GetTestPartResultReporterForCurrentThread(); + + // Sets the test part result reporter for the current thread. + void SetTestPartResultReporterForCurrentThread( + TestPartResultReporterInterface* reporter); + + // Gets the number of successful test cases. + int successful_test_case_count() const; + + // Gets the number of failed test cases. + int failed_test_case_count() const; + + // Gets the number of all test cases. + int total_test_case_count() const; + + // Gets the number of all test cases that contain at least one test + // that should run. + int test_case_to_run_count() const; + + // Gets the number of successful tests. + int successful_test_count() const; + + // Gets the number of failed tests. + int failed_test_count() const; + + // Gets the number of disabled tests. + int disabled_test_count() const; + + // Gets the number of all tests. + int total_test_count() const; + + // Gets the number of tests that should run. + int test_to_run_count() const; + + // Gets the elapsed time, in milliseconds. + TimeInMillis elapsed_time() const { return elapsed_time_; } + + // Returns true iff the unit test passed (i.e. all test cases passed). + bool Passed() const { return !Failed(); } + + // Returns true iff the unit test failed (i.e. some test case failed + // or something outside of all tests failed). + bool Failed() const { + return failed_test_case_count() > 0 || ad_hoc_test_result()->Failed(); + } + + // Gets the i-th test case among all the test cases. i can range from 0 to + // total_test_case_count() - 1. If i is not in that range, returns NULL. + const TestCase* GetTestCase(int i) const { + const int index = GetElementOr(test_case_indices_, i, -1); + return index < 0 ? NULL : test_cases_[i]; + } + + // Gets the i-th test case among all the test cases. i can range from 0 to + // total_test_case_count() - 1. If i is not in that range, returns NULL. + TestCase* GetMutableTestCase(int i) { + const int index = GetElementOr(test_case_indices_, i, -1); + return index < 0 ? NULL : test_cases_[index]; + } + + // Provides access to the event listener list. + TestEventListeners* listeners() { return &listeners_; } + + // Returns the TestResult for the test that's currently running, or + // the TestResult for the ad hoc test if no test is running. + TestResult* current_test_result(); + + // Returns the TestResult for the ad hoc test. + const TestResult* ad_hoc_test_result() const { return &ad_hoc_test_result_; } + + // Sets the OS stack trace getter. + // + // Does nothing if the input and the current OS stack trace getter + // are the same; otherwise, deletes the old getter and makes the + // input the current getter. + void set_os_stack_trace_getter(OsStackTraceGetterInterface* getter); + + // Returns the current OS stack trace getter if it is not NULL; + // otherwise, creates an OsStackTraceGetter, makes it the current + // getter, and returns it. + OsStackTraceGetterInterface* os_stack_trace_getter(); + + // Returns the current OS stack trace as a String. + // + // The maximum number of stack frames to be included is specified by + // the gtest_stack_trace_depth flag. The skip_count parameter + // specifies the number of top frames to be skipped, which doesn't + // count against the number of frames to be included. + // + // For example, if Foo() calls Bar(), which in turn calls + // CurrentOsStackTraceExceptTop(1), Foo() will be included in the + // trace but Bar() and CurrentOsStackTraceExceptTop() won't. + String CurrentOsStackTraceExceptTop(int skip_count); + + // Finds and returns a TestCase with the given name. If one doesn't + // exist, creates one and returns it. + // + // Arguments: + // + // test_case_name: name of the test case + // set_up_tc: pointer to the function that sets up the test case + // tear_down_tc: pointer to the function that tears down the test case + TestCase* GetTestCase(const char* test_case_name, + const char* comment, + Test::SetUpTestCaseFunc set_up_tc, + Test::TearDownTestCaseFunc tear_down_tc); + + // Adds a TestInfo to the unit test. + // + // Arguments: + // + // set_up_tc: pointer to the function that sets up the test case + // tear_down_tc: pointer to the function that tears down the test case + // test_info: the TestInfo object + void AddTestInfo(Test::SetUpTestCaseFunc set_up_tc, + Test::TearDownTestCaseFunc tear_down_tc, + TestInfo * test_info) { + // In order to support thread-safe death tests, we need to + // remember the original working directory when the test program + // was first invoked. We cannot do this in RUN_ALL_TESTS(), as + // the user may have changed the current directory before calling + // RUN_ALL_TESTS(). Therefore we capture the current directory in + // AddTestInfo(), which is called to register a TEST or TEST_F + // before main() is reached. + if (original_working_dir_.IsEmpty()) { + original_working_dir_.Set(FilePath::GetCurrentDir()); + GTEST_CHECK_(!original_working_dir_.IsEmpty()) + << "Failed to get the current working directory."; + } + + GetTestCase(test_info->test_case_name(), + test_info->test_case_comment(), + set_up_tc, + tear_down_tc)->AddTestInfo(test_info); + } + +#if GTEST_HAS_PARAM_TEST + // Returns ParameterizedTestCaseRegistry object used to keep track of + // value-parameterized tests and instantiate and register them. + internal::ParameterizedTestCaseRegistry& parameterized_test_registry() { + return parameterized_test_registry_; + } +#endif // GTEST_HAS_PARAM_TEST + + // Sets the TestCase object for the test that's currently running. + void set_current_test_case(TestCase* a_current_test_case) { + current_test_case_ = a_current_test_case; + } + + // Sets the TestInfo object for the test that's currently running. If + // current_test_info is NULL, the assertion results will be stored in + // ad_hoc_test_result_. + void set_current_test_info(TestInfo* a_current_test_info) { + current_test_info_ = a_current_test_info; + } + + // Registers all parameterized tests defined using TEST_P and + // INSTANTIATE_TEST_P, creating regular tests for each test/parameter + // combination. This method can be called more then once; it has + // guards protecting from registering the tests more then once. + // If value-parameterized tests are disabled, RegisterParameterizedTests + // is present but does nothing. + void RegisterParameterizedTests(); + + // Runs all tests in this UnitTest object, prints the result, and + // returns 0 if all tests are successful, or 1 otherwise. If any + // exception is thrown during a test on Windows, this test is + // considered to be failed, but the rest of the tests will still be + // run. (We disable exceptions on Linux and Mac OS X, so the issue + // doesn't apply there.) + int RunAllTests(); + + // Clears the results of all tests, including the ad hoc test. + void ClearResult() { + ForEach(test_cases_, TestCase::ClearTestCaseResult); + ad_hoc_test_result_.Clear(); + } + + enum ReactionToSharding { + HONOR_SHARDING_PROTOCOL, + IGNORE_SHARDING_PROTOCOL + }; + + // Matches the full name of each test against the user-specified + // filter to decide whether the test should run, then records the + // result in each TestCase and TestInfo object. + // If shard_tests == HONOR_SHARDING_PROTOCOL, further filters tests + // based on sharding variables in the environment. + // Returns the number of tests that should run. + int FilterTests(ReactionToSharding shard_tests); + + // Prints the names of the tests matching the user-specified filter flag. + void ListTestsMatchingFilter(); + + const TestCase* current_test_case() const { return current_test_case_; } + TestInfo* current_test_info() { return current_test_info_; } + const TestInfo* current_test_info() const { return current_test_info_; } + + // Returns the vector of environments that need to be set-up/torn-down + // before/after the tests are run. + std::vector& environments() { return environments_; } + + // Getters for the per-thread Google Test trace stack. + std::vector& gtest_trace_stack() { + return *(gtest_trace_stack_.pointer()); + } + const std::vector& gtest_trace_stack() const { + return gtest_trace_stack_.get(); + } + +#if GTEST_HAS_DEATH_TEST + void InitDeathTestSubprocessControlInfo() { + internal_run_death_test_flag_.reset(ParseInternalRunDeathTestFlag()); + } + // Returns a pointer to the parsed --gtest_internal_run_death_test + // flag, or NULL if that flag was not specified. + // This information is useful only in a death test child process. + // Must not be called before a call to InitGoogleTest. + const InternalRunDeathTestFlag* internal_run_death_test_flag() const { + return internal_run_death_test_flag_.get(); + } + + // Returns a pointer to the current death test factory. + internal::DeathTestFactory* death_test_factory() { + return death_test_factory_.get(); + } + + void SuppressTestEventsIfInSubprocess(); + + friend class ReplaceDeathTestFactory; +#endif // GTEST_HAS_DEATH_TEST + + // Initializes the event listener performing XML output as specified by + // UnitTestOptions. Must not be called before InitGoogleTest. + void ConfigureXmlOutput(); + + // Performs initialization dependent upon flag values obtained in + // ParseGoogleTestFlagsOnly. Is called from InitGoogleTest after the call to + // ParseGoogleTestFlagsOnly. In case a user neglects to call InitGoogleTest + // this function is also called from RunAllTests. Since this function can be + // called more than once, it has to be idempotent. + void PostFlagParsingInit(); + + // Gets the random seed used at the start of the current test iteration. + int random_seed() const { return random_seed_; } + + // Gets the random number generator. + internal::Random* random() { return &random_; } + + // Shuffles all test cases, and the tests within each test case, + // making sure that death tests are still run first. + void ShuffleTests(); + + // Restores the test cases and tests to their order before the first shuffle. + void UnshuffleTests(); + + private: + friend class ::testing::UnitTest; + + // The UnitTest object that owns this implementation object. + UnitTest* const parent_; + + // The working directory when the first TEST() or TEST_F() was + // executed. + internal::FilePath original_working_dir_; + + // The default test part result reporters. + DefaultGlobalTestPartResultReporter default_global_test_part_result_reporter_; + DefaultPerThreadTestPartResultReporter + default_per_thread_test_part_result_reporter_; + + // Points to (but doesn't own) the global test part result reporter. + TestPartResultReporterInterface* global_test_part_result_repoter_; + + // Protects read and write access to global_test_part_result_reporter_. + internal::Mutex global_test_part_result_reporter_mutex_; + + // Points to (but doesn't own) the per-thread test part result reporter. + internal::ThreadLocal + per_thread_test_part_result_reporter_; + + // The vector of environments that need to be set-up/torn-down + // before/after the tests are run. + std::vector environments_; + + // The vector of TestCases in their original order. It owns the + // elements in the vector. + std::vector test_cases_; + + // Provides a level of indirection for the test case list to allow + // easy shuffling and restoring the test case order. The i-th + // element of this vector is the index of the i-th test case in the + // shuffled order. + std::vector test_case_indices_; + +#if GTEST_HAS_PARAM_TEST + // ParameterizedTestRegistry object used to register value-parameterized + // tests. + internal::ParameterizedTestCaseRegistry parameterized_test_registry_; + + // Indicates whether RegisterParameterizedTests() has been called already. + bool parameterized_tests_registered_; +#endif // GTEST_HAS_PARAM_TEST + + // Index of the last death test case registered. Initially -1. + int last_death_test_case_; + + // This points to the TestCase for the currently running test. It + // changes as Google Test goes through one test case after another. + // When no test is running, this is set to NULL and Google Test + // stores assertion results in ad_hoc_test_result_. Initially NULL. + TestCase* current_test_case_; + + // This points to the TestInfo for the currently running test. It + // changes as Google Test goes through one test after another. When + // no test is running, this is set to NULL and Google Test stores + // assertion results in ad_hoc_test_result_. Initially NULL. + TestInfo* current_test_info_; + + // Normally, a user only writes assertions inside a TEST or TEST_F, + // or inside a function called by a TEST or TEST_F. Since Google + // Test keeps track of which test is current running, it can + // associate such an assertion with the test it belongs to. + // + // If an assertion is encountered when no TEST or TEST_F is running, + // Google Test attributes the assertion result to an imaginary "ad hoc" + // test, and records the result in ad_hoc_test_result_. + TestResult ad_hoc_test_result_; + + // The list of event listeners that can be used to track events inside + // Google Test. + TestEventListeners listeners_; + + // The OS stack trace getter. Will be deleted when the UnitTest + // object is destructed. By default, an OsStackTraceGetter is used, + // but the user can set this field to use a custom getter if that is + // desired. + OsStackTraceGetterInterface* os_stack_trace_getter_; + + // True iff PostFlagParsingInit() has been called. + bool post_flag_parse_init_performed_; + + // The random number seed used at the beginning of the test run. + int random_seed_; + + // Our random number generator. + internal::Random random_; + + // How long the test took to run, in milliseconds. + TimeInMillis elapsed_time_; + +#if GTEST_HAS_DEATH_TEST + // The decomposed components of the gtest_internal_run_death_test flag, + // parsed when RUN_ALL_TESTS is called. + internal::scoped_ptr internal_run_death_test_flag_; + internal::scoped_ptr death_test_factory_; +#endif // GTEST_HAS_DEATH_TEST + + // A per-thread stack of traces created by the SCOPED_TRACE() macro. + internal::ThreadLocal > gtest_trace_stack_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(UnitTestImpl); +}; // class UnitTestImpl + +// Convenience function for accessing the global UnitTest +// implementation object. +inline UnitTestImpl* GetUnitTestImpl() { + return UnitTest::GetInstance()->impl(); +} + +// Internal helper functions for implementing the simple regular +// expression matcher. +GTEST_API_ bool IsInSet(char ch, const char* str); +GTEST_API_ bool IsDigit(char ch); +GTEST_API_ bool IsPunct(char ch); +GTEST_API_ bool IsRepeat(char ch); +GTEST_API_ bool IsWhiteSpace(char ch); +GTEST_API_ bool IsWordChar(char ch); +GTEST_API_ bool IsValidEscape(char ch); +GTEST_API_ bool AtomMatchesChar(bool escaped, char pattern, char ch); +GTEST_API_ bool ValidateRegex(const char* regex); +GTEST_API_ bool MatchRegexAtHead(const char* regex, const char* str); +GTEST_API_ bool MatchRepetitionAndRegexAtHead( + bool escaped, char ch, char repeat, const char* regex, const char* str); +GTEST_API_ bool MatchRegexAnywhere(const char* regex, const char* str); + +// Parses the command line for Google Test flags, without initializing +// other parts of Google Test. +GTEST_API_ void ParseGoogleTestFlagsOnly(int* argc, char** argv); +GTEST_API_ void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv); + +#if GTEST_HAS_DEATH_TEST + +// Returns the message describing the last system error, regardless of the +// platform. +String GetLastErrnoDescription(); + +#if GTEST_OS_WINDOWS +// Provides leak-safe Windows kernel handle ownership. +class AutoHandle { + public: + AutoHandle() : handle_(INVALID_HANDLE_VALUE) {} + explicit AutoHandle(HANDLE handle) : handle_(handle) {} + + ~AutoHandle() { Reset(); } + + HANDLE Get() const { return handle_; } + void Reset() { Reset(INVALID_HANDLE_VALUE); } + void Reset(HANDLE handle) { + if (handle != handle_) { + if (handle_ != INVALID_HANDLE_VALUE) + ::CloseHandle(handle_); + handle_ = handle; + } + } + + private: + HANDLE handle_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(AutoHandle); +}; +#endif // GTEST_OS_WINDOWS + +// Attempts to parse a string into a positive integer pointed to by the +// number parameter. Returns true if that is possible. +// GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we can use +// it here. +template +bool ParseNaturalNumber(const ::std::string& str, Integer* number) { + // Fail fast if the given string does not begin with a digit; + // this bypasses strtoXXX's "optional leading whitespace and plus + // or minus sign" semantics, which are undesirable here. + if (str.empty() || !isdigit(str[0])) { + return false; + } + errno = 0; + + char* end; + // BiggestConvertible is the largest integer type that system-provided + // string-to-number conversion routines can return. +#if GTEST_OS_WINDOWS && !defined(__GNUC__) + // MSVC and C++ Builder define __int64 instead of the standard long long. + typedef unsigned __int64 BiggestConvertible; + const BiggestConvertible parsed = _strtoui64(str.c_str(), &end, 10); +#else + typedef unsigned long long BiggestConvertible; // NOLINT + const BiggestConvertible parsed = strtoull(str.c_str(), &end, 10); +#endif // GTEST_OS_WINDOWS && !defined(__GNUC__) + const bool parse_success = *end == '\0' && errno == 0; + + // TODO(vladl@google.com): Convert this to compile time assertion when it is + // available. + GTEST_CHECK_(sizeof(Integer) <= sizeof(parsed)); + + const Integer result = static_cast(parsed); + if (parse_success && static_cast(result) == parsed) { + *number = result; + return true; + } + return false; +} +#endif // GTEST_HAS_DEATH_TEST + +// TestResult contains some private methods that should be hidden from +// Google Test user but are required for testing. This class allow our tests +// to access them. +// +// This class is supplied only for the purpose of testing Google Test's own +// constructs. Do not use it in user tests, either directly or indirectly. +class TestResultAccessor { + public: + static void RecordProperty(TestResult* test_result, + const TestProperty& property) { + test_result->RecordProperty(property); + } + + static void ClearTestPartResults(TestResult* test_result) { + test_result->ClearTestPartResults(); + } + + static const std::vector& test_part_results( + const TestResult& test_result) { + return test_result.test_part_results(); + } +}; + +} // namespace internal +} // namespace testing + +#endif // GTEST_SRC_GTEST_INTERNAL_INL_H_ +#undef GTEST_IMPLEMENTATION_ + +#if GTEST_OS_WINDOWS +#define vsnprintf _vsnprintf +#endif // GTEST_OS_WINDOWS + +namespace testing { + +using internal::CountIf; +using internal::ForEach; +using internal::GetElementOr; +using internal::Shuffle; + +// Constants. + +// A test whose test case name or test name matches this filter is +// disabled and not run. +static const char kDisableTestFilter[] = "DISABLED_*:*/DISABLED_*"; + +// A test case whose name matches this filter is considered a death +// test case and will be run before test cases whose name doesn't +// match this filter. +static const char kDeathTestCaseFilter[] = "*DeathTest:*DeathTest/*"; + +// A test filter that matches everything. +static const char kUniversalFilter[] = "*"; + +// The default output file for XML output. +static const char kDefaultOutputFile[] = "test_detail.xml"; + +// The environment variable name for the test shard index. +static const char kTestShardIndex[] = "GTEST_SHARD_INDEX"; +// The environment variable name for the total number of test shards. +static const char kTestTotalShards[] = "GTEST_TOTAL_SHARDS"; +// The environment variable name for the test shard status file. +static const char kTestShardStatusFile[] = "GTEST_SHARD_STATUS_FILE"; + +namespace internal { + +// The text used in failure messages to indicate the start of the +// stack trace. +const char kStackTraceMarker[] = "\nStack trace:\n"; + +// g_help_flag is true iff the --help flag or an equivalent form is +// specified on the command line. +bool g_help_flag = false; + +} // namespace internal + +GTEST_DEFINE_bool_( + also_run_disabled_tests, + internal::BoolFromGTestEnv("also_run_disabled_tests", false), + "Run disabled tests too, in addition to the tests normally being run."); + +GTEST_DEFINE_bool_( + break_on_failure, + internal::BoolFromGTestEnv("break_on_failure", false), + "True iff a failed assertion should be a debugger break-point."); + +GTEST_DEFINE_bool_( + catch_exceptions, + internal::BoolFromGTestEnv("catch_exceptions", false), + "True iff " GTEST_NAME_ + " should catch exceptions and treat them as test failures."); + +GTEST_DEFINE_string_( + color, + internal::StringFromGTestEnv("color", "auto"), + "Whether to use colors in the output. Valid values: yes, no, " + "and auto. 'auto' means to use colors if the output is " + "being sent to a terminal and the TERM environment variable " + "is set to xterm, xterm-color, xterm-256color, linux or cygwin."); + +GTEST_DEFINE_string_( + filter, + internal::StringFromGTestEnv("filter", kUniversalFilter), + "A colon-separated list of glob (not regex) patterns " + "for filtering the tests to run, optionally followed by a " + "'-' and a : separated list of negative patterns (tests to " + "exclude). A test is run if it matches one of the positive " + "patterns and does not match any of the negative patterns."); + +GTEST_DEFINE_bool_(list_tests, false, + "List all tests without running them."); + +GTEST_DEFINE_string_( + output, + internal::StringFromGTestEnv("output", ""), + "A format (currently must be \"xml\"), optionally followed " + "by a colon and an output file name or directory. A directory " + "is indicated by a trailing pathname separator. " + "Examples: \"xml:filename.xml\", \"xml::directoryname/\". " + "If a directory is specified, output files will be created " + "within that directory, with file-names based on the test " + "executable's name and, if necessary, made unique by adding " + "digits."); + +GTEST_DEFINE_bool_( + print_time, + internal::BoolFromGTestEnv("print_time", true), + "True iff " GTEST_NAME_ + " should display elapsed time in text output."); + +GTEST_DEFINE_int32_( + random_seed, + internal::Int32FromGTestEnv("random_seed", 0), + "Random number seed to use when shuffling test orders. Must be in range " + "[1, 99999], or 0 to use a seed based on the current time."); + +GTEST_DEFINE_int32_( + repeat, + internal::Int32FromGTestEnv("repeat", 1), + "How many times to repeat each test. Specify a negative number " + "for repeating forever. Useful for shaking out flaky tests."); + +GTEST_DEFINE_bool_( + show_internal_stack_frames, false, + "True iff " GTEST_NAME_ " should include internal stack frames when " + "printing test failure stack traces."); + +GTEST_DEFINE_bool_( + shuffle, + internal::BoolFromGTestEnv("shuffle", false), + "True iff " GTEST_NAME_ + " should randomize tests' order on every run."); + +GTEST_DEFINE_int32_( + stack_trace_depth, + internal::Int32FromGTestEnv("stack_trace_depth", kMaxStackTraceDepth), + "The maximum number of stack frames to print when an " + "assertion fails. The valid range is 0 through 100, inclusive."); + +GTEST_DEFINE_bool_( + throw_on_failure, + internal::BoolFromGTestEnv("throw_on_failure", false), + "When this flag is specified, a failed assertion will throw an exception " + "if exceptions are enabled or exit the program with a non-zero code " + "otherwise."); + +namespace internal { + +// Generates a random number from [0, range), using a Linear +// Congruential Generator (LCG). Crashes if 'range' is 0 or greater +// than kMaxRange. +UInt32 Random::Generate(UInt32 range) { + // These constants are the same as are used in glibc's rand(3). + state_ = (1103515245U*state_ + 12345U) % kMaxRange; + + GTEST_CHECK_(range > 0) + << "Cannot generate a number in the range [0, 0)."; + GTEST_CHECK_(range <= kMaxRange) + << "Generation of a number in [0, " << range << ") was requested, " + << "but this can only generate numbers in [0, " << kMaxRange << ")."; + + // Converting via modulus introduces a bit of downward bias, but + // it's simple, and a linear congruential generator isn't too good + // to begin with. + return state_ % range; +} + +// GTestIsInitialized() returns true iff the user has initialized +// Google Test. Useful for catching the user mistake of not initializing +// Google Test before calling RUN_ALL_TESTS(). +// +// A user must call testing::InitGoogleTest() to initialize Google +// Test. g_init_gtest_count is set to the number of times +// InitGoogleTest() has been called. We don't protect this variable +// under a mutex as it is only accessed in the main thread. +int g_init_gtest_count = 0; +static bool GTestIsInitialized() { return g_init_gtest_count != 0; } + +// Iterates over a vector of TestCases, keeping a running sum of the +// results of calling a given int-returning method on each. +// Returns the sum. +static int SumOverTestCaseList(const std::vector& case_list, + int (TestCase::*method)() const) { + int sum = 0; + for (size_t i = 0; i < case_list.size(); i++) { + sum += (case_list[i]->*method)(); + } + return sum; +} + +// Returns true iff the test case passed. +static bool TestCasePassed(const TestCase* test_case) { + return test_case->should_run() && test_case->Passed(); +} + +// Returns true iff the test case failed. +static bool TestCaseFailed(const TestCase* test_case) { + return test_case->should_run() && test_case->Failed(); +} + +// Returns true iff test_case contains at least one test that should +// run. +static bool ShouldRunTestCase(const TestCase* test_case) { + return test_case->should_run(); +} + +// AssertHelper constructor. +AssertHelper::AssertHelper(TestPartResult::Type type, + const char* file, + int line, + const char* message) + : data_(new AssertHelperData(type, file, line, message)) { +} + +AssertHelper::~AssertHelper() { + delete data_; +} + +// Message assignment, for assertion streaming support. +void AssertHelper::operator=(const Message& message) const { + UnitTest::GetInstance()-> + AddTestPartResult(data_->type, data_->file, data_->line, + AppendUserMessage(data_->message, message), + UnitTest::GetInstance()->impl() + ->CurrentOsStackTraceExceptTop(1) + // Skips the stack frame for this function itself. + ); // NOLINT +} + +// Mutex for linked pointers. +GTEST_DEFINE_STATIC_MUTEX_(g_linked_ptr_mutex); + +// Application pathname gotten in InitGoogleTest. +String g_executable_path; + +// Returns the current application's name, removing directory path if that +// is present. +FilePath GetCurrentExecutableName() { + FilePath result; + +#if GTEST_OS_WINDOWS + result.Set(FilePath(g_executable_path).RemoveExtension("exe")); +#else + result.Set(FilePath(g_executable_path)); +#endif // GTEST_OS_WINDOWS + + return result.RemoveDirectoryName(); +} + +// Functions for processing the gtest_output flag. + +// Returns the output format, or "" for normal printed output. +String UnitTestOptions::GetOutputFormat() { + const char* const gtest_output_flag = GTEST_FLAG(output).c_str(); + if (gtest_output_flag == NULL) return String(""); + + const char* const colon = strchr(gtest_output_flag, ':'); + return (colon == NULL) ? + String(gtest_output_flag) : + String(gtest_output_flag, colon - gtest_output_flag); +} + +// Returns the name of the requested output file, or the default if none +// was explicitly specified. +String UnitTestOptions::GetAbsolutePathToOutputFile() { + const char* const gtest_output_flag = GTEST_FLAG(output).c_str(); + if (gtest_output_flag == NULL) + return String(""); + + const char* const colon = strchr(gtest_output_flag, ':'); + if (colon == NULL) + return String(internal::FilePath::ConcatPaths( + internal::FilePath( + UnitTest::GetInstance()->original_working_dir()), + internal::FilePath(kDefaultOutputFile)).ToString() ); + + internal::FilePath output_name(colon + 1); + if (!output_name.IsAbsolutePath()) + // TODO(wan@google.com): on Windows \some\path is not an absolute + // path (as its meaning depends on the current drive), yet the + // following logic for turning it into an absolute path is wrong. + // Fix it. + output_name = internal::FilePath::ConcatPaths( + internal::FilePath(UnitTest::GetInstance()->original_working_dir()), + internal::FilePath(colon + 1)); + + if (!output_name.IsDirectory()) + return output_name.ToString(); + + internal::FilePath result(internal::FilePath::GenerateUniqueFileName( + output_name, internal::GetCurrentExecutableName(), + GetOutputFormat().c_str())); + return result.ToString(); +} + +// Returns true iff the wildcard pattern matches the string. The +// first ':' or '\0' character in pattern marks the end of it. +// +// This recursive algorithm isn't very efficient, but is clear and +// works well enough for matching test names, which are short. +bool UnitTestOptions::PatternMatchesString(const char *pattern, + const char *str) { + switch (*pattern) { + case '\0': + case ':': // Either ':' or '\0' marks the end of the pattern. + return *str == '\0'; + case '?': // Matches any single character. + return *str != '\0' && PatternMatchesString(pattern + 1, str + 1); + case '*': // Matches any string (possibly empty) of characters. + return (*str != '\0' && PatternMatchesString(pattern, str + 1)) || + PatternMatchesString(pattern + 1, str); + default: // Non-special character. Matches itself. + return *pattern == *str && + PatternMatchesString(pattern + 1, str + 1); + } +} + +bool UnitTestOptions::MatchesFilter(const String& name, const char* filter) { + const char *cur_pattern = filter; + for (;;) { + if (PatternMatchesString(cur_pattern, name.c_str())) { + return true; + } + + // Finds the next pattern in the filter. + cur_pattern = strchr(cur_pattern, ':'); + + // Returns if no more pattern can be found. + if (cur_pattern == NULL) { + return false; + } + + // Skips the pattern separater (the ':' character). + cur_pattern++; + } +} + +// TODO(keithray): move String function implementations to gtest-string.cc. + +// Returns true iff the user-specified filter matches the test case +// name and the test name. +bool UnitTestOptions::FilterMatchesTest(const String &test_case_name, + const String &test_name) { + const String& full_name = String::Format("%s.%s", + test_case_name.c_str(), + test_name.c_str()); + + // Split --gtest_filter at '-', if there is one, to separate into + // positive filter and negative filter portions + const char* const p = GTEST_FLAG(filter).c_str(); + const char* const dash = strchr(p, '-'); + String positive; + String negative; + if (dash == NULL) { + positive = GTEST_FLAG(filter).c_str(); // Whole string is a positive filter + negative = String(""); + } else { + positive = String(p, dash - p); // Everything up to the dash + negative = String(dash+1); // Everything after the dash + if (positive.empty()) { + // Treat '-test1' as the same as '*-test1' + positive = kUniversalFilter; + } + } + + // A filter is a colon-separated list of patterns. It matches a + // test if any pattern in it matches the test. + return (MatchesFilter(full_name, positive.c_str()) && + !MatchesFilter(full_name, negative.c_str())); +} + +#if GTEST_OS_WINDOWS +// Returns EXCEPTION_EXECUTE_HANDLER if Google Test should handle the +// given SEH exception, or EXCEPTION_CONTINUE_SEARCH otherwise. +// This function is useful as an __except condition. +int UnitTestOptions::GTestShouldProcessSEH(DWORD exception_code) { + // Google Test should handle an exception if: + // 1. the user wants it to, AND + // 2. this is not a breakpoint exception. + return (GTEST_FLAG(catch_exceptions) && + exception_code != EXCEPTION_BREAKPOINT) ? + EXCEPTION_EXECUTE_HANDLER : + EXCEPTION_CONTINUE_SEARCH; +} +#endif // GTEST_OS_WINDOWS + +} // namespace internal + +// The c'tor sets this object as the test part result reporter used by +// Google Test. The 'result' parameter specifies where to report the +// results. Intercepts only failures from the current thread. +ScopedFakeTestPartResultReporter::ScopedFakeTestPartResultReporter( + TestPartResultArray* result) + : intercept_mode_(INTERCEPT_ONLY_CURRENT_THREAD), + result_(result) { + Init(); +} + +// The c'tor sets this object as the test part result reporter used by +// Google Test. The 'result' parameter specifies where to report the +// results. +ScopedFakeTestPartResultReporter::ScopedFakeTestPartResultReporter( + InterceptMode intercept_mode, TestPartResultArray* result) + : intercept_mode_(intercept_mode), + result_(result) { + Init(); +} + +void ScopedFakeTestPartResultReporter::Init() { + internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); + if (intercept_mode_ == INTERCEPT_ALL_THREADS) { + old_reporter_ = impl->GetGlobalTestPartResultReporter(); + impl->SetGlobalTestPartResultReporter(this); + } else { + old_reporter_ = impl->GetTestPartResultReporterForCurrentThread(); + impl->SetTestPartResultReporterForCurrentThread(this); + } +} + +// The d'tor restores the test part result reporter used by Google Test +// before. +ScopedFakeTestPartResultReporter::~ScopedFakeTestPartResultReporter() { + internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); + if (intercept_mode_ == INTERCEPT_ALL_THREADS) { + impl->SetGlobalTestPartResultReporter(old_reporter_); + } else { + impl->SetTestPartResultReporterForCurrentThread(old_reporter_); + } +} + +// Increments the test part result count and remembers the result. +// This method is from the TestPartResultReporterInterface interface. +void ScopedFakeTestPartResultReporter::ReportTestPartResult( + const TestPartResult& result) { + result_->Append(result); +} + +namespace internal { + +// Returns the type ID of ::testing::Test. We should always call this +// instead of GetTypeId< ::testing::Test>() to get the type ID of +// testing::Test. This is to work around a suspected linker bug when +// using Google Test as a framework on Mac OS X. The bug causes +// GetTypeId< ::testing::Test>() to return different values depending +// on whether the call is from the Google Test framework itself or +// from user test code. GetTestTypeId() is guaranteed to always +// return the same value, as it always calls GetTypeId<>() from the +// gtest.cc, which is within the Google Test framework. +TypeId GetTestTypeId() { + return GetTypeId(); +} + +// The value of GetTestTypeId() as seen from within the Google Test +// library. This is solely for testing GetTestTypeId(). +extern const TypeId kTestTypeIdInGoogleTest = GetTestTypeId(); + +// This predicate-formatter checks that 'results' contains a test part +// failure of the given type and that the failure message contains the +// given substring. +AssertionResult HasOneFailure(const char* /* results_expr */, + const char* /* type_expr */, + const char* /* substr_expr */, + const TestPartResultArray& results, + TestPartResult::Type type, + const char* substr) { + const String expected(type == TestPartResult::kFatalFailure ? + "1 fatal failure" : + "1 non-fatal failure"); + Message msg; + if (results.size() != 1) { + msg << "Expected: " << expected << "\n" + << " Actual: " << results.size() << " failures"; + for (int i = 0; i < results.size(); i++) { + msg << "\n" << results.GetTestPartResult(i); + } + return AssertionFailure(msg); + } + + const TestPartResult& r = results.GetTestPartResult(0); + if (r.type() != type) { + msg << "Expected: " << expected << "\n" + << " Actual:\n" + << r; + return AssertionFailure(msg); + } + + if (strstr(r.message(), substr) == NULL) { + msg << "Expected: " << expected << " containing \"" + << substr << "\"\n" + << " Actual:\n" + << r; + return AssertionFailure(msg); + } + + return AssertionSuccess(); +} + +// The constructor of SingleFailureChecker remembers where to look up +// test part results, what type of failure we expect, and what +// substring the failure message should contain. +SingleFailureChecker:: SingleFailureChecker( + const TestPartResultArray* results, + TestPartResult::Type type, + const char* substr) + : results_(results), + type_(type), + substr_(substr) {} + +// The destructor of SingleFailureChecker verifies that the given +// TestPartResultArray contains exactly one failure that has the given +// type and contains the given substring. If that's not the case, a +// non-fatal failure will be generated. +SingleFailureChecker::~SingleFailureChecker() { + EXPECT_PRED_FORMAT3(HasOneFailure, *results_, type_, substr_.c_str()); +} + +DefaultGlobalTestPartResultReporter::DefaultGlobalTestPartResultReporter( + UnitTestImpl* unit_test) : unit_test_(unit_test) {} + +void DefaultGlobalTestPartResultReporter::ReportTestPartResult( + const TestPartResult& result) { + unit_test_->current_test_result()->AddTestPartResult(result); + unit_test_->listeners()->repeater()->OnTestPartResult(result); +} + +DefaultPerThreadTestPartResultReporter::DefaultPerThreadTestPartResultReporter( + UnitTestImpl* unit_test) : unit_test_(unit_test) {} + +void DefaultPerThreadTestPartResultReporter::ReportTestPartResult( + const TestPartResult& result) { + unit_test_->GetGlobalTestPartResultReporter()->ReportTestPartResult(result); +} + +// Returns the global test part result reporter. +TestPartResultReporterInterface* +UnitTestImpl::GetGlobalTestPartResultReporter() { + internal::MutexLock lock(&global_test_part_result_reporter_mutex_); + return global_test_part_result_repoter_; +} + +// Sets the global test part result reporter. +void UnitTestImpl::SetGlobalTestPartResultReporter( + TestPartResultReporterInterface* reporter) { + internal::MutexLock lock(&global_test_part_result_reporter_mutex_); + global_test_part_result_repoter_ = reporter; +} + +// Returns the test part result reporter for the current thread. +TestPartResultReporterInterface* +UnitTestImpl::GetTestPartResultReporterForCurrentThread() { + return per_thread_test_part_result_reporter_.get(); +} + +// Sets the test part result reporter for the current thread. +void UnitTestImpl::SetTestPartResultReporterForCurrentThread( + TestPartResultReporterInterface* reporter) { + per_thread_test_part_result_reporter_.set(reporter); +} + +// Gets the number of successful test cases. +int UnitTestImpl::successful_test_case_count() const { + return CountIf(test_cases_, TestCasePassed); +} + +// Gets the number of failed test cases. +int UnitTestImpl::failed_test_case_count() const { + return CountIf(test_cases_, TestCaseFailed); +} + +// Gets the number of all test cases. +int UnitTestImpl::total_test_case_count() const { + return static_cast(test_cases_.size()); +} + +// Gets the number of all test cases that contain at least one test +// that should run. +int UnitTestImpl::test_case_to_run_count() const { + return CountIf(test_cases_, ShouldRunTestCase); +} + +// Gets the number of successful tests. +int UnitTestImpl::successful_test_count() const { + return SumOverTestCaseList(test_cases_, &TestCase::successful_test_count); +} + +// Gets the number of failed tests. +int UnitTestImpl::failed_test_count() const { + return SumOverTestCaseList(test_cases_, &TestCase::failed_test_count); +} + +// Gets the number of disabled tests. +int UnitTestImpl::disabled_test_count() const { + return SumOverTestCaseList(test_cases_, &TestCase::disabled_test_count); +} + +// Gets the number of all tests. +int UnitTestImpl::total_test_count() const { + return SumOverTestCaseList(test_cases_, &TestCase::total_test_count); +} + +// Gets the number of tests that should run. +int UnitTestImpl::test_to_run_count() const { + return SumOverTestCaseList(test_cases_, &TestCase::test_to_run_count); +} + +// Returns the current OS stack trace as a String. +// +// The maximum number of stack frames to be included is specified by +// the gtest_stack_trace_depth flag. The skip_count parameter +// specifies the number of top frames to be skipped, which doesn't +// count against the number of frames to be included. +// +// For example, if Foo() calls Bar(), which in turn calls +// CurrentOsStackTraceExceptTop(1), Foo() will be included in the +// trace but Bar() and CurrentOsStackTraceExceptTop() won't. +String UnitTestImpl::CurrentOsStackTraceExceptTop(int skip_count) { + (void)skip_count; + return String(""); +} + +// Returns the current time in milliseconds. +TimeInMillis GetTimeInMillis() { +#if GTEST_OS_WINDOWS_MOBILE || defined(__BORLANDC__) + // Difference between 1970-01-01 and 1601-01-01 in milliseconds. + // http://analogous.blogspot.com/2005/04/epoch.html + const TimeInMillis kJavaEpochToWinFileTimeDelta = + static_cast(116444736UL) * 100000UL; + const DWORD kTenthMicrosInMilliSecond = 10000; + + SYSTEMTIME now_systime; + FILETIME now_filetime; + ULARGE_INTEGER now_int64; + // TODO(kenton@google.com): Shouldn't this just use + // GetSystemTimeAsFileTime()? + GetSystemTime(&now_systime); + if (SystemTimeToFileTime(&now_systime, &now_filetime)) { + now_int64.LowPart = now_filetime.dwLowDateTime; + now_int64.HighPart = now_filetime.dwHighDateTime; + now_int64.QuadPart = (now_int64.QuadPart / kTenthMicrosInMilliSecond) - + kJavaEpochToWinFileTimeDelta; + return now_int64.QuadPart; + } + return 0; +#elif GTEST_OS_WINDOWS && !GTEST_HAS_GETTIMEOFDAY_ + __timeb64 now; +#ifdef _MSC_VER + // MSVC 8 deprecates _ftime64(), so we want to suppress warning 4996 + // (deprecated function) there. + // TODO(kenton@google.com): Use GetTickCount()? Or use + // SystemTimeToFileTime() +#pragma warning(push) // Saves the current warning state. +#pragma warning(disable:4996) // Temporarily disables warning 4996. + _ftime64(&now); +#pragma warning(pop) // Restores the warning state. +#else + _ftime64(&now); +#endif // _MSC_VER + return static_cast(now.time) * 1000 + now.millitm; +#elif GTEST_HAS_GETTIMEOFDAY_ + struct timeval now; + gettimeofday(&now, NULL); + return static_cast(now.tv_sec) * 1000 + now.tv_usec / 1000; +#else +#error "Don't know how to get the current time on your system." +#endif +} + +// Utilities + +// class String + +// Returns the input enclosed in double quotes if it's not NULL; +// otherwise returns "(null)". For example, "\"Hello\"" is returned +// for input "Hello". +// +// This is useful for printing a C string in the syntax of a literal. +// +// Known issue: escape sequences are not handled yet. +String String::ShowCStringQuoted(const char* c_str) { + return c_str ? String::Format("\"%s\"", c_str) : String("(null)"); +} + +// Copies at most length characters from str into a newly-allocated +// piece of memory of size length+1. The memory is allocated with new[]. +// A terminating null byte is written to the memory, and a pointer to it +// is returned. If str is NULL, NULL is returned. +static char* CloneString(const char* str, size_t length) { + if (str == NULL) { + return NULL; + } else { + char* const clone = new char[length + 1]; + posix::StrNCpy(clone, str, length); + clone[length] = '\0'; + return clone; + } +} + +// Clones a 0-terminated C string, allocating memory using new. The +// caller is responsible for deleting[] the return value. Returns the +// cloned string, or NULL if the input is NULL. +const char * String::CloneCString(const char* c_str) { + return (c_str == NULL) ? + NULL : CloneString(c_str, strlen(c_str)); +} + +#if GTEST_OS_WINDOWS_MOBILE +// Creates a UTF-16 wide string from the given ANSI string, allocating +// memory using new. The caller is responsible for deleting the return +// value using delete[]. Returns the wide string, or NULL if the +// input is NULL. +LPCWSTR String::AnsiToUtf16(const char* ansi) { + if (!ansi) return NULL; + const int length = strlen(ansi); + const int unicode_length = + MultiByteToWideChar(CP_ACP, 0, ansi, length, + NULL, 0); + WCHAR* unicode = new WCHAR[unicode_length + 1]; + MultiByteToWideChar(CP_ACP, 0, ansi, length, + unicode, unicode_length); + unicode[unicode_length] = 0; + return unicode; +} + +// Creates an ANSI string from the given wide string, allocating +// memory using new. The caller is responsible for deleting the return +// value using delete[]. Returns the ANSI string, or NULL if the +// input is NULL. +const char* String::Utf16ToAnsi(LPCWSTR utf16_str) { + if (!utf16_str) return NULL; + const int ansi_length = + WideCharToMultiByte(CP_ACP, 0, utf16_str, -1, + NULL, 0, NULL, NULL); + char* ansi = new char[ansi_length + 1]; + WideCharToMultiByte(CP_ACP, 0, utf16_str, -1, + ansi, ansi_length, NULL, NULL); + ansi[ansi_length] = 0; + return ansi; +} + +#endif // GTEST_OS_WINDOWS_MOBILE + +// Compares two C strings. Returns true iff they have the same content. +// +// Unlike strcmp(), this function can handle NULL argument(s). A NULL +// C string is considered different to any non-NULL C string, +// including the empty string. +bool String::CStringEquals(const char * lhs, const char * rhs) { + if ( lhs == NULL ) return rhs == NULL; + + if ( rhs == NULL ) return false; + + return strcmp(lhs, rhs) == 0; +} + +#if GTEST_HAS_STD_WSTRING || GTEST_HAS_GLOBAL_WSTRING + +// Converts an array of wide chars to a narrow string using the UTF-8 +// encoding, and streams the result to the given Message object. +static void StreamWideCharsToMessage(const wchar_t* wstr, size_t length, + Message* msg) { + // TODO(wan): consider allowing a testing::String object to + // contain '\0'. This will make it behave more like std::string, + // and will allow ToUtf8String() to return the correct encoding + // for '\0' s.t. we can get rid of the conditional here (and in + // several other places). + for (size_t i = 0; i != length; ) { // NOLINT + if (wstr[i] != L'\0') { + *msg << WideStringToUtf8(wstr + i, static_cast(length - i)); + while (i != length && wstr[i] != L'\0') + i++; + } else { + *msg << '\0'; + i++; + } + } +} + +#endif // GTEST_HAS_STD_WSTRING || GTEST_HAS_GLOBAL_WSTRING + +} // namespace internal + +#if GTEST_HAS_STD_WSTRING +// Converts the given wide string to a narrow string using the UTF-8 +// encoding, and streams the result to this Message object. +Message& Message::operator <<(const ::std::wstring& wstr) { + internal::StreamWideCharsToMessage(wstr.c_str(), wstr.length(), this); + return *this; +} +#endif // GTEST_HAS_STD_WSTRING + +#if GTEST_HAS_GLOBAL_WSTRING +// Converts the given wide string to a narrow string using the UTF-8 +// encoding, and streams the result to this Message object. +Message& Message::operator <<(const ::wstring& wstr) { + internal::StreamWideCharsToMessage(wstr.c_str(), wstr.length(), this); + return *this; +} +#endif // GTEST_HAS_GLOBAL_WSTRING + +namespace internal { + +// Formats a value to be used in a failure message. + +// For a char value, we print it as a C++ char literal and as an +// unsigned integer (both in decimal and in hexadecimal). +String FormatForFailureMessage(char ch) { + const unsigned int ch_as_uint = ch; + // A String object cannot contain '\0', so we print "\\0" when ch is + // '\0'. + return String::Format("'%s' (%u, 0x%X)", + ch ? String::Format("%c", ch).c_str() : "\\0", + ch_as_uint, ch_as_uint); +} + +// For a wchar_t value, we print it as a C++ wchar_t literal and as an +// unsigned integer (both in decimal and in hexidecimal). +String FormatForFailureMessage(wchar_t wchar) { + // The C++ standard doesn't specify the exact size of the wchar_t + // type. It just says that it shall have the same size as another + // integral type, called its underlying type. + // + // Therefore, in order to print a wchar_t value in the numeric form, + // we first convert it to the largest integral type (UInt64) and + // then print the converted value. + // + // We use streaming to print the value as "%llu" doesn't work + // correctly with MSVC 7.1. + const UInt64 wchar_as_uint64 = wchar; + Message msg; + // A String object cannot contain '\0', so we print "\\0" when wchar is + // L'\0'. + char buffer[32]; // CodePointToUtf8 requires a buffer that big. + msg << "L'" + << (wchar ? CodePointToUtf8(static_cast(wchar), buffer) : "\\0") + << "' (" << wchar_as_uint64 << ", 0x" << ::std::setbase(16) + << wchar_as_uint64 << ")"; + return msg.GetString(); +} + +} // namespace internal + +// AssertionResult constructors. +// Used in EXPECT_TRUE/FALSE(assertion_result). +AssertionResult::AssertionResult(const AssertionResult& other) + : success_(other.success_), + message_(other.message_.get() != NULL ? + new internal::String(*other.message_) : + static_cast(NULL)) { +} + +// Returns the assertion's negation. Used with EXPECT/ASSERT_FALSE. +AssertionResult AssertionResult::operator!() const { + AssertionResult negation(!success_); + if (message_.get() != NULL) + negation << *message_; + return negation; +} + +// Makes a successful assertion result. +AssertionResult AssertionSuccess() { + return AssertionResult(true); +} + +// Makes a failed assertion result. +AssertionResult AssertionFailure() { + return AssertionResult(false); +} + +// Makes a failed assertion result with the given failure message. +// Deprecated; use AssertionFailure() << message. +AssertionResult AssertionFailure(const Message& message) { + return AssertionFailure() << message; +} + +namespace internal { + +// Constructs and returns the message for an equality assertion +// (e.g. ASSERT_EQ, EXPECT_STREQ, etc) failure. +// +// The first four parameters are the expressions used in the assertion +// and their values, as strings. For example, for ASSERT_EQ(foo, bar) +// where foo is 5 and bar is 6, we have: +// +// expected_expression: "foo" +// actual_expression: "bar" +// expected_value: "5" +// actual_value: "6" +// +// The ignoring_case parameter is true iff the assertion is a +// *_STRCASEEQ*. When it's true, the string " (ignoring case)" will +// be inserted into the message. +AssertionResult EqFailure(const char* expected_expression, + const char* actual_expression, + const String& expected_value, + const String& actual_value, + bool ignoring_case) { + Message msg; + msg << "Value of: " << actual_expression; + if (actual_value != actual_expression) { + msg << "\n Actual: " << actual_value; + } + + msg << "\nExpected: " << expected_expression; + if (ignoring_case) { + msg << " (ignoring case)"; + } + if (expected_value != expected_expression) { + msg << "\nWhich is: " << expected_value; + } + + return AssertionFailure(msg); +} + +// Constructs a failure message for Boolean assertions such as EXPECT_TRUE. +String GetBoolAssertionFailureMessage(const AssertionResult& assertion_result, + const char* expression_text, + const char* actual_predicate_value, + const char* expected_predicate_value) { + const char* actual_message = assertion_result.message(); + Message msg; + msg << "Value of: " << expression_text + << "\n Actual: " << actual_predicate_value; + if (actual_message[0] != '\0') + msg << " (" << actual_message << ")"; + msg << "\nExpected: " << expected_predicate_value; + return msg.GetString(); +} + +// Helper function for implementing ASSERT_NEAR. +AssertionResult DoubleNearPredFormat(const char* expr1, + const char* expr2, + const char* abs_error_expr, + double val1, + double val2, + double abs_error) { + const double diff = fabs(val1 - val2); + if (diff <= abs_error) return AssertionSuccess(); + + // TODO(wan): do not print the value of an expression if it's + // already a literal. + Message msg; + msg << "The difference between " << expr1 << " and " << expr2 + << " is " << diff << ", which exceeds " << abs_error_expr << ", where\n" + << expr1 << " evaluates to " << val1 << ",\n" + << expr2 << " evaluates to " << val2 << ", and\n" + << abs_error_expr << " evaluates to " << abs_error << "."; + return AssertionFailure(msg); +} + + +// Helper template for implementing FloatLE() and DoubleLE(). +template +AssertionResult FloatingPointLE(const char* expr1, + const char* expr2, + RawType val1, + RawType val2) { + // Returns success if val1 is less than val2, + if (val1 < val2) { + return AssertionSuccess(); + } + + // or if val1 is almost equal to val2. + const FloatingPoint lhs(val1), rhs(val2); + if (lhs.AlmostEquals(rhs)) { + return AssertionSuccess(); + } + + // Note that the above two checks will both fail if either val1 or + // val2 is NaN, as the IEEE floating-point standard requires that + // any predicate involving a NaN must return false. + + StrStream val1_ss; + val1_ss << std::setprecision(std::numeric_limits::digits10 + 2) + << val1; + + StrStream val2_ss; + val2_ss << std::setprecision(std::numeric_limits::digits10 + 2) + << val2; + + Message msg; + msg << "Expected: (" << expr1 << ") <= (" << expr2 << ")\n" + << " Actual: " << StrStreamToString(&val1_ss) << " vs " + << StrStreamToString(&val2_ss); + + return AssertionFailure(msg); +} + +} // namespace internal + +// Asserts that val1 is less than, or almost equal to, val2. Fails +// otherwise. In particular, it fails if either val1 or val2 is NaN. +AssertionResult FloatLE(const char* expr1, const char* expr2, + float val1, float val2) { + return internal::FloatingPointLE(expr1, expr2, val1, val2); +} + +// Asserts that val1 is less than, or almost equal to, val2. Fails +// otherwise. In particular, it fails if either val1 or val2 is NaN. +AssertionResult DoubleLE(const char* expr1, const char* expr2, + double val1, double val2) { + return internal::FloatingPointLE(expr1, expr2, val1, val2); +} + +namespace internal { + +// The helper function for {ASSERT|EXPECT}_EQ with int or enum +// arguments. +AssertionResult CmpHelperEQ(const char* expected_expression, + const char* actual_expression, + BiggestInt expected, + BiggestInt actual) { + if (expected == actual) { + return AssertionSuccess(); + } + + return EqFailure(expected_expression, + actual_expression, + FormatForComparisonFailureMessage(expected, actual), + FormatForComparisonFailureMessage(actual, expected), + false); +} + +// A macro for implementing the helper functions needed to implement +// ASSERT_?? and EXPECT_?? with integer or enum arguments. It is here +// just to avoid copy-and-paste of similar code. +#define GTEST_IMPL_CMP_HELPER_(op_name, op)\ +AssertionResult CmpHelper##op_name(const char* expr1, const char* expr2, \ + BiggestInt val1, BiggestInt val2) {\ + if (val1 op val2) {\ + return AssertionSuccess();\ + } else {\ + Message msg;\ + msg << "Expected: (" << expr1 << ") " #op " (" << expr2\ + << "), actual: " << FormatForComparisonFailureMessage(val1, val2)\ + << " vs " << FormatForComparisonFailureMessage(val2, val1);\ + return AssertionFailure(msg);\ + }\ +} + +// Implements the helper function for {ASSERT|EXPECT}_NE with int or +// enum arguments. +GTEST_IMPL_CMP_HELPER_(NE, !=) +// Implements the helper function for {ASSERT|EXPECT}_LE with int or +// enum arguments. +GTEST_IMPL_CMP_HELPER_(LE, <=) +// Implements the helper function for {ASSERT|EXPECT}_LT with int or +// enum arguments. +GTEST_IMPL_CMP_HELPER_(LT, < ) +// Implements the helper function for {ASSERT|EXPECT}_GE with int or +// enum arguments. +GTEST_IMPL_CMP_HELPER_(GE, >=) +// Implements the helper function for {ASSERT|EXPECT}_GT with int or +// enum arguments. +GTEST_IMPL_CMP_HELPER_(GT, > ) + +#undef GTEST_IMPL_CMP_HELPER_ + +// The helper function for {ASSERT|EXPECT}_STREQ. +AssertionResult CmpHelperSTREQ(const char* expected_expression, + const char* actual_expression, + const char* expected, + const char* actual) { + if (String::CStringEquals(expected, actual)) { + return AssertionSuccess(); + } + + return EqFailure(expected_expression, + actual_expression, + String::ShowCStringQuoted(expected), + String::ShowCStringQuoted(actual), + false); +} + +// The helper function for {ASSERT|EXPECT}_STRCASEEQ. +AssertionResult CmpHelperSTRCASEEQ(const char* expected_expression, + const char* actual_expression, + const char* expected, + const char* actual) { + if (String::CaseInsensitiveCStringEquals(expected, actual)) { + return AssertionSuccess(); + } + + return EqFailure(expected_expression, + actual_expression, + String::ShowCStringQuoted(expected), + String::ShowCStringQuoted(actual), + true); +} + +// The helper function for {ASSERT|EXPECT}_STRNE. +AssertionResult CmpHelperSTRNE(const char* s1_expression, + const char* s2_expression, + const char* s1, + const char* s2) { + if (!String::CStringEquals(s1, s2)) { + return AssertionSuccess(); + } else { + Message msg; + msg << "Expected: (" << s1_expression << ") != (" + << s2_expression << "), actual: \"" + << s1 << "\" vs \"" << s2 << "\""; + return AssertionFailure(msg); + } +} + +// The helper function for {ASSERT|EXPECT}_STRCASENE. +AssertionResult CmpHelperSTRCASENE(const char* s1_expression, + const char* s2_expression, + const char* s1, + const char* s2) { + if (!String::CaseInsensitiveCStringEquals(s1, s2)) { + return AssertionSuccess(); + } else { + Message msg; + msg << "Expected: (" << s1_expression << ") != (" + << s2_expression << ") (ignoring case), actual: \"" + << s1 << "\" vs \"" << s2 << "\""; + return AssertionFailure(msg); + } +} + +} // namespace internal + +namespace { + +// Helper functions for implementing IsSubString() and IsNotSubstring(). + +// This group of overloaded functions return true iff needle is a +// substring of haystack. NULL is considered a substring of itself +// only. + +bool IsSubstringPred(const char* needle, const char* haystack) { + if (needle == NULL || haystack == NULL) + return needle == haystack; + + return strstr(haystack, needle) != NULL; +} + +bool IsSubstringPred(const wchar_t* needle, const wchar_t* haystack) { + if (needle == NULL || haystack == NULL) + return needle == haystack; + + return wcsstr(haystack, needle) != NULL; +} + +// StringType here can be either ::std::string or ::std::wstring. +template +bool IsSubstringPred(const StringType& needle, + const StringType& haystack) { + return haystack.find(needle) != StringType::npos; +} + +// This function implements either IsSubstring() or IsNotSubstring(), +// depending on the value of the expected_to_be_substring parameter. +// StringType here can be const char*, const wchar_t*, ::std::string, +// or ::std::wstring. +template +AssertionResult IsSubstringImpl( + bool expected_to_be_substring, + const char* needle_expr, const char* haystack_expr, + const StringType& needle, const StringType& haystack) { + if (IsSubstringPred(needle, haystack) == expected_to_be_substring) + return AssertionSuccess(); + + const bool is_wide_string = sizeof(needle[0]) > 1; + const char* const begin_string_quote = is_wide_string ? "L\"" : "\""; + return AssertionFailure( + Message() + << "Value of: " << needle_expr << "\n" + << " Actual: " << begin_string_quote << needle << "\"\n" + << "Expected: " << (expected_to_be_substring ? "" : "not ") + << "a substring of " << haystack_expr << "\n" + << "Which is: " << begin_string_quote << haystack << "\""); +} + +} // namespace + +// IsSubstring() and IsNotSubstring() check whether needle is a +// substring of haystack (NULL is considered a substring of itself +// only), and return an appropriate error message when they fail. + +AssertionResult IsSubstring( + const char* needle_expr, const char* haystack_expr, + const char* needle, const char* haystack) { + return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); +} + +AssertionResult IsSubstring( + const char* needle_expr, const char* haystack_expr, + const wchar_t* needle, const wchar_t* haystack) { + return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); +} + +AssertionResult IsNotSubstring( + const char* needle_expr, const char* haystack_expr, + const char* needle, const char* haystack) { + return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); +} + +AssertionResult IsNotSubstring( + const char* needle_expr, const char* haystack_expr, + const wchar_t* needle, const wchar_t* haystack) { + return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); +} + +AssertionResult IsSubstring( + const char* needle_expr, const char* haystack_expr, + const ::std::string& needle, const ::std::string& haystack) { + return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); +} + +AssertionResult IsNotSubstring( + const char* needle_expr, const char* haystack_expr, + const ::std::string& needle, const ::std::string& haystack) { + return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); +} + +#if GTEST_HAS_STD_WSTRING +AssertionResult IsSubstring( + const char* needle_expr, const char* haystack_expr, + const ::std::wstring& needle, const ::std::wstring& haystack) { + return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); +} + +AssertionResult IsNotSubstring( + const char* needle_expr, const char* haystack_expr, + const ::std::wstring& needle, const ::std::wstring& haystack) { + return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); +} +#endif // GTEST_HAS_STD_WSTRING + +namespace internal { + +#if GTEST_OS_WINDOWS + +namespace { + +// Helper function for IsHRESULT{SuccessFailure} predicates +AssertionResult HRESULTFailureHelper(const char* expr, + const char* expected, + long hr) { // NOLINT +#if GTEST_OS_WINDOWS_MOBILE + // Windows CE doesn't support FormatMessage. + const char error_text[] = ""; +#else + // Looks up the human-readable system message for the HRESULT code + // and since we're not passing any params to FormatMessage, we don't + // want inserts expanded. + const DWORD kFlags = FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS; + const DWORD kBufSize = 4096; // String::Format can't exceed this length. + // Gets the system's human readable message string for this HRESULT. + char error_text[kBufSize] = { '\0' }; + DWORD message_length = ::FormatMessageA(kFlags, + 0, // no source, we're asking system + hr, // the error + 0, // no line width restrictions + error_text, // output buffer + kBufSize, // buf size + NULL); // no arguments for inserts + // Trims tailing white space (FormatMessage leaves a trailing cr-lf) + for (; message_length && isspace(error_text[message_length - 1]); + --message_length) { + error_text[message_length - 1] = '\0'; + } +#endif // GTEST_OS_WINDOWS_MOBILE + + const String error_hex(String::Format("0x%08X ", hr)); + Message msg; + msg << "Expected: " << expr << " " << expected << ".\n" + << " Actual: " << error_hex << error_text << "\n"; + + return ::testing::AssertionFailure(msg); +} + +} // namespace + +AssertionResult IsHRESULTSuccess(const char* expr, long hr) { // NOLINT + if (SUCCEEDED(hr)) { + return AssertionSuccess(); + } + return HRESULTFailureHelper(expr, "succeeds", hr); +} + +AssertionResult IsHRESULTFailure(const char* expr, long hr) { // NOLINT + if (FAILED(hr)) { + return AssertionSuccess(); + } + return HRESULTFailureHelper(expr, "fails", hr); +} + +#endif // GTEST_OS_WINDOWS + +// Utility functions for encoding Unicode text (wide strings) in +// UTF-8. + +// A Unicode code-point can have upto 21 bits, and is encoded in UTF-8 +// like this: +// +// Code-point length Encoding +// 0 - 7 bits 0xxxxxxx +// 8 - 11 bits 110xxxxx 10xxxxxx +// 12 - 16 bits 1110xxxx 10xxxxxx 10xxxxxx +// 17 - 21 bits 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx + +// The maximum code-point a one-byte UTF-8 sequence can represent. +const UInt32 kMaxCodePoint1 = (static_cast(1) << 7) - 1; + +// The maximum code-point a two-byte UTF-8 sequence can represent. +const UInt32 kMaxCodePoint2 = (static_cast(1) << (5 + 6)) - 1; + +// The maximum code-point a three-byte UTF-8 sequence can represent. +const UInt32 kMaxCodePoint3 = (static_cast(1) << (4 + 2*6)) - 1; + +// The maximum code-point a four-byte UTF-8 sequence can represent. +const UInt32 kMaxCodePoint4 = (static_cast(1) << (3 + 3*6)) - 1; + +// Chops off the n lowest bits from a bit pattern. Returns the n +// lowest bits. As a side effect, the original bit pattern will be +// shifted to the right by n bits. +inline UInt32 ChopLowBits(UInt32* bits, int n) { + const UInt32 low_bits = *bits & ((static_cast(1) << n) - 1); + *bits >>= n; + return low_bits; +} + +// Converts a Unicode code point to a narrow string in UTF-8 encoding. +// code_point parameter is of type UInt32 because wchar_t may not be +// wide enough to contain a code point. +// The output buffer str must containt at least 32 characters. +// The function returns the address of the output buffer. +// If the code_point is not a valid Unicode code point +// (i.e. outside of Unicode range U+0 to U+10FFFF) it will be output +// as '(Invalid Unicode 0xXXXXXXXX)'. +char* CodePointToUtf8(UInt32 code_point, char* str) { + if (code_point <= kMaxCodePoint1) { + str[1] = '\0'; + str[0] = static_cast(code_point); // 0xxxxxxx + } else if (code_point <= kMaxCodePoint2) { + str[2] = '\0'; + str[1] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx + str[0] = static_cast(0xC0 | code_point); // 110xxxxx + } else if (code_point <= kMaxCodePoint3) { + str[3] = '\0'; + str[2] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx + str[1] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx + str[0] = static_cast(0xE0 | code_point); // 1110xxxx + } else if (code_point <= kMaxCodePoint4) { + str[4] = '\0'; + str[3] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx + str[2] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx + str[1] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx + str[0] = static_cast(0xF0 | code_point); // 11110xxx + } else { + // The longest string String::Format can produce when invoked + // with these parameters is 28 character long (not including + // the terminating nul character). We are asking for 32 character + // buffer just in case. This is also enough for strncpy to + // null-terminate the destination string. + posix::StrNCpy( + str, String::Format("(Invalid Unicode 0x%X)", code_point).c_str(), 32); + str[31] = '\0'; // Makes sure no change in the format to strncpy leaves + // the result unterminated. + } + return str; +} + +// The following two functions only make sense if the the system +// uses UTF-16 for wide string encoding. All supported systems +// with 16 bit wchar_t (Windows, Cygwin, Symbian OS) do use UTF-16. + +// Determines if the arguments constitute UTF-16 surrogate pair +// and thus should be combined into a single Unicode code point +// using CreateCodePointFromUtf16SurrogatePair. +inline bool IsUtf16SurrogatePair(wchar_t first, wchar_t second) { + return sizeof(wchar_t) == 2 && + (first & 0xFC00) == 0xD800 && (second & 0xFC00) == 0xDC00; +} + +// Creates a Unicode code point from UTF16 surrogate pair. +inline UInt32 CreateCodePointFromUtf16SurrogatePair(wchar_t first, + wchar_t second) { + const UInt32 mask = (1 << 10) - 1; + return (sizeof(wchar_t) == 2) ? + (((first & mask) << 10) | (second & mask)) + 0x10000 : + // This function should not be called when the condition is + // false, but we provide a sensible default in case it is. + static_cast(first); +} + +// Converts a wide string to a narrow string in UTF-8 encoding. +// The wide string is assumed to have the following encoding: +// UTF-16 if sizeof(wchar_t) == 2 (on Windows, Cygwin, Symbian OS) +// UTF-32 if sizeof(wchar_t) == 4 (on Linux) +// Parameter str points to a null-terminated wide string. +// Parameter num_chars may additionally limit the number +// of wchar_t characters processed. -1 is used when the entire string +// should be processed. +// If the string contains code points that are not valid Unicode code points +// (i.e. outside of Unicode range U+0 to U+10FFFF) they will be output +// as '(Invalid Unicode 0xXXXXXXXX)'. If the string is in UTF16 encoding +// and contains invalid UTF-16 surrogate pairs, values in those pairs +// will be encoded as individual Unicode characters from Basic Normal Plane. +String WideStringToUtf8(const wchar_t* str, int num_chars) { + if (num_chars == -1) + num_chars = static_cast(wcslen(str)); + + StrStream stream; + for (int i = 0; i < num_chars; ++i) { + UInt32 unicode_code_point; + + if (str[i] == L'\0') { + break; + } else if (i + 1 < num_chars && IsUtf16SurrogatePair(str[i], str[i + 1])) { + unicode_code_point = CreateCodePointFromUtf16SurrogatePair(str[i], + str[i + 1]); + i++; + } else { + unicode_code_point = static_cast(str[i]); + } + + char buffer[32]; // CodePointToUtf8 requires a buffer this big. + stream << CodePointToUtf8(unicode_code_point, buffer); + } + return StrStreamToString(&stream); +} + +// Converts a wide C string to a String using the UTF-8 encoding. +// NULL will be converted to "(null)". +String String::ShowWideCString(const wchar_t * wide_c_str) { + if (wide_c_str == NULL) return String("(null)"); + + return String(internal::WideStringToUtf8(wide_c_str, -1).c_str()); +} + +// Similar to ShowWideCString(), except that this function encloses +// the converted string in double quotes. +String String::ShowWideCStringQuoted(const wchar_t* wide_c_str) { + if (wide_c_str == NULL) return String("(null)"); + + return String::Format("L\"%s\"", + String::ShowWideCString(wide_c_str).c_str()); +} + +// Compares two wide C strings. Returns true iff they have the same +// content. +// +// Unlike wcscmp(), this function can handle NULL argument(s). A NULL +// C string is considered different to any non-NULL C string, +// including the empty string. +bool String::WideCStringEquals(const wchar_t * lhs, const wchar_t * rhs) { + if (lhs == NULL) return rhs == NULL; + + if (rhs == NULL) return false; + + return wcscmp(lhs, rhs) == 0; +} + +// Helper function for *_STREQ on wide strings. +AssertionResult CmpHelperSTREQ(const char* expected_expression, + const char* actual_expression, + const wchar_t* expected, + const wchar_t* actual) { + if (String::WideCStringEquals(expected, actual)) { + return AssertionSuccess(); + } + + return EqFailure(expected_expression, + actual_expression, + String::ShowWideCStringQuoted(expected), + String::ShowWideCStringQuoted(actual), + false); +} + +// Helper function for *_STRNE on wide strings. +AssertionResult CmpHelperSTRNE(const char* s1_expression, + const char* s2_expression, + const wchar_t* s1, + const wchar_t* s2) { + if (!String::WideCStringEquals(s1, s2)) { + return AssertionSuccess(); + } + + Message msg; + msg << "Expected: (" << s1_expression << ") != (" + << s2_expression << "), actual: " + << String::ShowWideCStringQuoted(s1) + << " vs " << String::ShowWideCStringQuoted(s2); + return AssertionFailure(msg); +} + +// Compares two C strings, ignoring case. Returns true iff they have +// the same content. +// +// Unlike strcasecmp(), this function can handle NULL argument(s). A +// NULL C string is considered different to any non-NULL C string, +// including the empty string. +bool String::CaseInsensitiveCStringEquals(const char * lhs, const char * rhs) { + if (lhs == NULL) + return rhs == NULL; + if (rhs == NULL) + return false; + return posix::StrCaseCmp(lhs, rhs) == 0; +} + + // Compares two wide C strings, ignoring case. Returns true iff they + // have the same content. + // + // Unlike wcscasecmp(), this function can handle NULL argument(s). + // A NULL C string is considered different to any non-NULL wide C string, + // including the empty string. + // NB: The implementations on different platforms slightly differ. + // On windows, this method uses _wcsicmp which compares according to LC_CTYPE + // environment variable. On GNU platform this method uses wcscasecmp + // which compares according to LC_CTYPE category of the current locale. + // On MacOS X, it uses towlower, which also uses LC_CTYPE category of the + // current locale. +bool String::CaseInsensitiveWideCStringEquals(const wchar_t* lhs, + const wchar_t* rhs) { + if ( lhs == NULL ) return rhs == NULL; + + if ( rhs == NULL ) return false; + +#if GTEST_OS_WINDOWS + return _wcsicmp(lhs, rhs) == 0; +#elif GTEST_OS_LINUX + return wcscasecmp(lhs, rhs) == 0; +#else + // Mac OS X and Cygwin don't define wcscasecmp. Other unknown OSes + // may not define it either. + wint_t left, right; + do { + left = towlower(*lhs++); + right = towlower(*rhs++); + } while (left && left == right); + return left == right; +#endif // OS selector +} + +// Compares this with another String. +// Returns < 0 if this is less than rhs, 0 if this is equal to rhs, or > 0 +// if this is greater than rhs. +int String::Compare(const String & rhs) const { + const char* const lhs_c_str = c_str(); + const char* const rhs_c_str = rhs.c_str(); + + if (lhs_c_str == NULL) { + return rhs_c_str == NULL ? 0 : -1; // NULL < anything except NULL + } else if (rhs_c_str == NULL) { + return 1; + } + + const size_t shorter_str_len = + length() <= rhs.length() ? length() : rhs.length(); + for (size_t i = 0; i != shorter_str_len; i++) { + if (lhs_c_str[i] < rhs_c_str[i]) { + return -1; + } else if (lhs_c_str[i] > rhs_c_str[i]) { + return 1; + } + } + return (length() < rhs.length()) ? -1 : + (length() > rhs.length()) ? 1 : 0; +} + +// Returns true iff this String ends with the given suffix. *Any* +// String is considered to end with a NULL or empty suffix. +bool String::EndsWith(const char* suffix) const { + if (suffix == NULL || CStringEquals(suffix, "")) return true; + + if (c_str() == NULL) return false; + + const size_t this_len = strlen(c_str()); + const size_t suffix_len = strlen(suffix); + return (this_len >= suffix_len) && + CStringEquals(c_str() + this_len - suffix_len, suffix); +} + +// Returns true iff this String ends with the given suffix, ignoring case. +// Any String is considered to end with a NULL or empty suffix. +bool String::EndsWithCaseInsensitive(const char* suffix) const { + if (suffix == NULL || CStringEquals(suffix, "")) return true; + + if (c_str() == NULL) return false; + + const size_t this_len = strlen(c_str()); + const size_t suffix_len = strlen(suffix); + return (this_len >= suffix_len) && + CaseInsensitiveCStringEquals(c_str() + this_len - suffix_len, suffix); +} + +// Formats a list of arguments to a String, using the same format +// spec string as for printf. +// +// We do not use the StringPrintf class as it is not universally +// available. +// +// The result is limited to 4096 characters (including the tailing 0). +// If 4096 characters are not enough to format the input, or if +// there's an error, "" is +// returned. +String String::Format(const char * format, ...) { + va_list args; + va_start(args, format); + + char buffer[4096]; + const int kBufferSize = sizeof(buffer)/sizeof(buffer[0]); + + // MSVC 8 deprecates vsnprintf(), so we want to suppress warning + // 4996 (deprecated function) there. +#ifdef _MSC_VER // We are using MSVC. +#pragma warning(push) // Saves the current warning state. +#pragma warning(disable:4996) // Temporarily disables warning 4996. + const int size = vsnprintf(buffer, kBufferSize, format, args); +#pragma warning(pop) // Restores the warning state. +#else // We are not using MSVC. + const int size = vsnprintf(buffer, kBufferSize, format, args); +#endif // _MSC_VER + va_end(args); + + // vsnprintf()'s behavior is not portable. When the buffer is not + // big enough, it returns a negative value in MSVC, and returns the + // needed buffer size on Linux. When there is an output error, it + // always returns a negative value. For simplicity, we lump the two + // error cases together. + if (size < 0 || size >= kBufferSize) { + return String(""); + } else { + return String(buffer, size); + } +} + +// Converts the buffer in a StrStream to a String, converting NUL +// bytes to "\\0" along the way. +String StrStreamToString(StrStream* ss) { + const ::std::string& str = ss->str(); + const char* const start = str.c_str(); + const char* const end = start + str.length(); + + // We need to use a helper StrStream to do this transformation + // because String doesn't support push_back(). + StrStream helper; + for (const char* ch = start; ch != end; ++ch) { + if (*ch == '\0') { + helper << "\\0"; // Replaces NUL with "\\0"; + } else { + helper.put(*ch); + } + } + + return String(helper.str().c_str()); +} + +// Appends the user-supplied message to the Google-Test-generated message. +String AppendUserMessage(const String& gtest_msg, + const Message& user_msg) { + // Appends the user message if it's non-empty. + const String user_msg_string = user_msg.GetString(); + if (user_msg_string.empty()) { + return gtest_msg; + } + + Message msg; + msg << gtest_msg << "\n" << user_msg_string; + + return msg.GetString(); +} + +} // namespace internal + +// class TestResult + +// Creates an empty TestResult. +TestResult::TestResult() + : death_test_count_(0), + elapsed_time_(0) { +} + +// D'tor. +TestResult::~TestResult() { +} + +// Returns the i-th test part result among all the results. i can +// range from 0 to total_part_count() - 1. If i is not in that range, +// aborts the program. +const TestPartResult& TestResult::GetTestPartResult(int i) const { + if (i < 0 || i >= total_part_count()) + internal::posix::Abort(); + return test_part_results_.at(i); +} + +// Returns the i-th test property. i can range from 0 to +// test_property_count() - 1. If i is not in that range, aborts the +// program. +const TestProperty& TestResult::GetTestProperty(int i) const { + if (i < 0 || i >= test_property_count()) + internal::posix::Abort(); + return test_properties_.at(i); +} + +// Clears the test part results. +void TestResult::ClearTestPartResults() { + test_part_results_.clear(); +} + +// Adds a test part result to the list. +void TestResult::AddTestPartResult(const TestPartResult& test_part_result) { + test_part_results_.push_back(test_part_result); +} + +// Adds a test property to the list. If a property with the same key as the +// supplied property is already represented, the value of this test_property +// replaces the old value for that key. +void TestResult::RecordProperty(const TestProperty& test_property) { + if (!ValidateTestProperty(test_property)) { + return; + } + internal::MutexLock lock(&test_properites_mutex_); + const std::vector::iterator property_with_matching_key = + std::find_if(test_properties_.begin(), test_properties_.end(), + internal::TestPropertyKeyIs(test_property.key())); + if (property_with_matching_key == test_properties_.end()) { + test_properties_.push_back(test_property); + return; + } + property_with_matching_key->SetValue(test_property.value()); +} + +// Adds a failure if the key is a reserved attribute of Google Test +// testcase tags. Returns true if the property is valid. +bool TestResult::ValidateTestProperty(const TestProperty& test_property) { + internal::String key(test_property.key()); + if (key == "name" || key == "status" || key == "time" || key == "classname") { + ADD_FAILURE() + << "Reserved key used in RecordProperty(): " + << key + << " ('name', 'status', 'time', and 'classname' are reserved by " + << GTEST_NAME_ << ")"; + return false; + } + return true; +} + +// Clears the object. +void TestResult::Clear() { + test_part_results_.clear(); + test_properties_.clear(); + death_test_count_ = 0; + elapsed_time_ = 0; +} + +// Returns true iff the test failed. +bool TestResult::Failed() const { + for (int i = 0; i < total_part_count(); ++i) { + if (GetTestPartResult(i).failed()) + return true; + } + return false; +} + +// Returns true iff the test part fatally failed. +static bool TestPartFatallyFailed(const TestPartResult& result) { + return result.fatally_failed(); +} + +// Returns true iff the test fatally failed. +bool TestResult::HasFatalFailure() const { + return CountIf(test_part_results_, TestPartFatallyFailed) > 0; +} + +// Returns true iff the test part non-fatally failed. +static bool TestPartNonfatallyFailed(const TestPartResult& result) { + return result.nonfatally_failed(); +} + +// Returns true iff the test has a non-fatal failure. +bool TestResult::HasNonfatalFailure() const { + return CountIf(test_part_results_, TestPartNonfatallyFailed) > 0; +} + +// Gets the number of all test parts. This is the sum of the number +// of successful test parts and the number of failed test parts. +int TestResult::total_part_count() const { + return static_cast(test_part_results_.size()); +} + +// Returns the number of the test properties. +int TestResult::test_property_count() const { + return static_cast(test_properties_.size()); +} + +// class Test + +// Creates a Test object. + +// The c'tor saves the values of all Google Test flags. +Test::Test() + : gtest_flag_saver_(new internal::GTestFlagSaver) { +} + +// The d'tor restores the values of all Google Test flags. +Test::~Test() { + delete gtest_flag_saver_; +} + +// Sets up the test fixture. +// +// A sub-class may override this. +void Test::SetUp() { +} + +// Tears down the test fixture. +// +// A sub-class may override this. +void Test::TearDown() { +} + +// Allows user supplied key value pairs to be recorded for later output. +void Test::RecordProperty(const char* key, const char* value) { + UnitTest::GetInstance()->RecordPropertyForCurrentTest(key, value); +} + +// Allows user supplied key value pairs to be recorded for later output. +void Test::RecordProperty(const char* key, int value) { + Message value_message; + value_message << value; + RecordProperty(key, value_message.GetString().c_str()); +} + +namespace internal { + +void ReportFailureInUnknownLocation(TestPartResult::Type result_type, + const String& message) { + // This function is a friend of UnitTest and as such has access to + // AddTestPartResult. + UnitTest::GetInstance()->AddTestPartResult( + result_type, + NULL, // No info about the source file where the exception occurred. + -1, // We have no info on which line caused the exception. + message, + String()); // No stack trace, either. +} + +} // namespace internal + +#if GTEST_OS_WINDOWS +// We are on Windows. + +// Adds an "exception thrown" fatal failure to the current test. +static void AddExceptionThrownFailure(DWORD exception_code, + const char* location) { + Message message; + message << "Exception thrown with code 0x" << std::setbase(16) << + exception_code << std::setbase(10) << " in " << location << "."; + + internal::ReportFailureInUnknownLocation(TestPartResult::kFatalFailure, + message.GetString()); +} + +#endif // GTEST_OS_WINDOWS + +// Google Test requires all tests in the same test case to use the same test +// fixture class. This function checks if the current test has the +// same fixture class as the first test in the current test case. If +// yes, it returns true; otherwise it generates a Google Test failure and +// returns false. +bool Test::HasSameFixtureClass() { + internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); + const TestCase* const test_case = impl->current_test_case(); + + // Info about the first test in the current test case. + const internal::TestInfoImpl* const first_test_info = + test_case->test_info_list()[0]->impl(); + const internal::TypeId first_fixture_id = first_test_info->fixture_class_id(); + const char* const first_test_name = first_test_info->name(); + + // Info about the current test. + const internal::TestInfoImpl* const this_test_info = + impl->current_test_info()->impl(); + const internal::TypeId this_fixture_id = this_test_info->fixture_class_id(); + const char* const this_test_name = this_test_info->name(); + + if (this_fixture_id != first_fixture_id) { + // Is the first test defined using TEST? + const bool first_is_TEST = first_fixture_id == internal::GetTestTypeId(); + // Is this test defined using TEST? + const bool this_is_TEST = this_fixture_id == internal::GetTestTypeId(); + + if (first_is_TEST || this_is_TEST) { + // The user mixed TEST and TEST_F in this test case - we'll tell + // him/her how to fix it. + + // Gets the name of the TEST and the name of the TEST_F. Note + // that first_is_TEST and this_is_TEST cannot both be true, as + // the fixture IDs are different for the two tests. + const char* const TEST_name = + first_is_TEST ? first_test_name : this_test_name; + const char* const TEST_F_name = + first_is_TEST ? this_test_name : first_test_name; + + ADD_FAILURE() + << "All tests in the same test case must use the same test fixture\n" + << "class, so mixing TEST_F and TEST in the same test case is\n" + << "illegal. In test case " << this_test_info->test_case_name() + << ",\n" + << "test " << TEST_F_name << " is defined using TEST_F but\n" + << "test " << TEST_name << " is defined using TEST. You probably\n" + << "want to change the TEST to TEST_F or move it to another test\n" + << "case."; + } else { + // The user defined two fixture classes with the same name in + // two namespaces - we'll tell him/her how to fix it. + ADD_FAILURE() + << "All tests in the same test case must use the same test fixture\n" + << "class. However, in test case " + << this_test_info->test_case_name() << ",\n" + << "you defined test " << first_test_name + << " and test " << this_test_name << "\n" + << "using two different test fixture classes. This can happen if\n" + << "the two classes are from different namespaces or translation\n" + << "units and have the same name. You should probably rename one\n" + << "of the classes to put the tests into different test cases."; + } + return false; + } + + return true; +} + +// Runs the test and updates the test result. +void Test::Run() { + if (!HasSameFixtureClass()) return; + + internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); +#if GTEST_HAS_SEH + // Catch SEH-style exceptions. + impl->os_stack_trace_getter()->UponLeavingGTest(); + __try { + SetUp(); + } __except(internal::UnitTestOptions::GTestShouldProcessSEH( + GetExceptionCode())) { + AddExceptionThrownFailure(GetExceptionCode(), "SetUp()"); + } + + // We will run the test only if SetUp() had no fatal failure. + if (!HasFatalFailure()) { + impl->os_stack_trace_getter()->UponLeavingGTest(); + __try { + TestBody(); + } __except(internal::UnitTestOptions::GTestShouldProcessSEH( + GetExceptionCode())) { + AddExceptionThrownFailure(GetExceptionCode(), "the test body"); + } + } + + // However, we want to clean up as much as possible. Hence we will + // always call TearDown(), even if SetUp() or the test body has + // failed. + impl->os_stack_trace_getter()->UponLeavingGTest(); + __try { + TearDown(); + } __except(internal::UnitTestOptions::GTestShouldProcessSEH( + GetExceptionCode())) { + AddExceptionThrownFailure(GetExceptionCode(), "TearDown()"); + } + +#else // We are on a compiler or platform that doesn't support SEH. + impl->os_stack_trace_getter()->UponLeavingGTest(); + SetUp(); + + // We will run the test only if SetUp() was successful. + if (!HasFatalFailure()) { + impl->os_stack_trace_getter()->UponLeavingGTest(); + TestBody(); + } + + // However, we want to clean up as much as possible. Hence we will + // always call TearDown(), even if SetUp() or the test body has + // failed. + impl->os_stack_trace_getter()->UponLeavingGTest(); + TearDown(); +#endif // GTEST_HAS_SEH +} + + +// Returns true iff the current test has a fatal failure. +bool Test::HasFatalFailure() { + return internal::GetUnitTestImpl()->current_test_result()->HasFatalFailure(); +} + +// Returns true iff the current test has a non-fatal failure. +bool Test::HasNonfatalFailure() { + return internal::GetUnitTestImpl()->current_test_result()-> + HasNonfatalFailure(); +} + +// class TestInfo + +// Constructs a TestInfo object. It assumes ownership of the test factory +// object via impl_. +TestInfo::TestInfo(const char* a_test_case_name, + const char* a_name, + const char* a_test_case_comment, + const char* a_comment, + internal::TypeId fixture_class_id, + internal::TestFactoryBase* factory) { + impl_ = new internal::TestInfoImpl(this, a_test_case_name, a_name, + a_test_case_comment, a_comment, + fixture_class_id, factory); +} + +// Destructs a TestInfo object. +TestInfo::~TestInfo() { + delete impl_; +} + +namespace internal { + +// Creates a new TestInfo object and registers it with Google Test; +// returns the created object. +// +// Arguments: +// +// test_case_name: name of the test case +// name: name of the test +// test_case_comment: a comment on the test case that will be included in +// the test output +// comment: a comment on the test that will be included in the +// test output +// fixture_class_id: ID of the test fixture class +// set_up_tc: pointer to the function that sets up the test case +// tear_down_tc: pointer to the function that tears down the test case +// factory: pointer to the factory that creates a test object. +// The newly created TestInfo instance will assume +// ownership of the factory object. +TestInfo* MakeAndRegisterTestInfo( + const char* test_case_name, const char* name, + const char* test_case_comment, const char* comment, + TypeId fixture_class_id, + SetUpTestCaseFunc set_up_tc, + TearDownTestCaseFunc tear_down_tc, + TestFactoryBase* factory) { + TestInfo* const test_info = + new TestInfo(test_case_name, name, test_case_comment, comment, + fixture_class_id, factory); + GetUnitTestImpl()->AddTestInfo(set_up_tc, tear_down_tc, test_info); + return test_info; +} + +#if GTEST_HAS_PARAM_TEST +void ReportInvalidTestCaseType(const char* test_case_name, + const char* file, int line) { + Message errors; + errors + << "Attempted redefinition of test case " << test_case_name << ".\n" + << "All tests in the same test case must use the same test fixture\n" + << "class. However, in test case " << test_case_name << ", you tried\n" + << "to define a test using a fixture class different from the one\n" + << "used earlier. This can happen if the two fixture classes are\n" + << "from different namespaces and have the same name. You should\n" + << "probably rename one of the classes to put the tests into different\n" + << "test cases."; + + fprintf(stderr, "%s %s", FormatFileLocation(file, line).c_str(), + errors.GetString().c_str()); +} +#endif // GTEST_HAS_PARAM_TEST + +} // namespace internal + +// Returns the test case name. +const char* TestInfo::test_case_name() const { + return impl_->test_case_name(); +} + +// Returns the test name. +const char* TestInfo::name() const { + return impl_->name(); +} + +// Returns the test case comment. +const char* TestInfo::test_case_comment() const { + return impl_->test_case_comment(); +} + +// Returns the test comment. +const char* TestInfo::comment() const { + return impl_->comment(); +} + +// Returns true if this test should run. +bool TestInfo::should_run() const { return impl_->should_run(); } + +// Returns true if this test matches the user-specified filter. +bool TestInfo::matches_filter() const { return impl_->matches_filter(); } + +// Returns the result of the test. +const TestResult* TestInfo::result() const { return impl_->result(); } + +// Increments the number of death tests encountered in this test so +// far. +int TestInfo::increment_death_test_count() { + return impl_->result()->increment_death_test_count(); +} + +namespace { + +// A predicate that checks the test name of a TestInfo against a known +// value. +// +// This is used for implementation of the TestCase class only. We put +// it in the anonymous namespace to prevent polluting the outer +// namespace. +// +// TestNameIs is copyable. +class TestNameIs { + public: + // Constructor. + // + // TestNameIs has NO default constructor. + explicit TestNameIs(const char* name) + : name_(name) {} + + // Returns true iff the test name of test_info matches name_. + bool operator()(const TestInfo * test_info) const { + return test_info && internal::String(test_info->name()).Compare(name_) == 0; + } + + private: + internal::String name_; +}; + +} // namespace + +namespace internal { + +// This method expands all parameterized tests registered with macros TEST_P +// and INSTANTIATE_TEST_CASE_P into regular tests and registers those. +// This will be done just once during the program runtime. +void UnitTestImpl::RegisterParameterizedTests() { +#if GTEST_HAS_PARAM_TEST + if (!parameterized_tests_registered_) { + parameterized_test_registry_.RegisterTests(); + parameterized_tests_registered_ = true; + } +#endif +} + +// Creates the test object, runs it, records its result, and then +// deletes it. +void TestInfoImpl::Run() { + if (!should_run_) return; + + // Tells UnitTest where to store test result. + UnitTestImpl* const impl = internal::GetUnitTestImpl(); + impl->set_current_test_info(parent_); + + TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater(); + + // Notifies the unit test event listeners that a test is about to start. + repeater->OnTestStart(*parent_); + + const TimeInMillis start = GetTimeInMillis(); + + impl->os_stack_trace_getter()->UponLeavingGTest(); +#if GTEST_HAS_SEH + // Catch SEH-style exceptions. + Test* test = NULL; + + __try { + // Creates the test object. + test = factory_->CreateTest(); + } __except(internal::UnitTestOptions::GTestShouldProcessSEH( + GetExceptionCode())) { + AddExceptionThrownFailure(GetExceptionCode(), + "the test fixture's constructor"); + return; + } +#else // We are on a compiler or platform that doesn't support SEH. + + // TODO(wan): If test->Run() throws, test won't be deleted. This is + // not a problem now as we don't use exceptions. If we were to + // enable exceptions, we should revise the following to be + // exception-safe. + + // Creates the test object. + Test* test = factory_->CreateTest(); +#endif // GTEST_HAS_SEH + + // Runs the test only if the constructor of the test fixture didn't + // generate a fatal failure. + if (!Test::HasFatalFailure()) { + test->Run(); + } + + // Deletes the test object. + impl->os_stack_trace_getter()->UponLeavingGTest(); + delete test; + test = NULL; + + result_.set_elapsed_time(GetTimeInMillis() - start); + + // Notifies the unit test event listener that a test has just finished. + repeater->OnTestEnd(*parent_); + + // Tells UnitTest to stop associating assertion results to this + // test. + impl->set_current_test_info(NULL); +} + +} // namespace internal + +// class TestCase + +// Gets the number of successful tests in this test case. +int TestCase::successful_test_count() const { + return CountIf(test_info_list_, TestPassed); +} + +// Gets the number of failed tests in this test case. +int TestCase::failed_test_count() const { + return CountIf(test_info_list_, TestFailed); +} + +int TestCase::disabled_test_count() const { + return CountIf(test_info_list_, TestDisabled); +} + +// Get the number of tests in this test case that should run. +int TestCase::test_to_run_count() const { + return CountIf(test_info_list_, ShouldRunTest); +} + +// Gets the number of all tests. +int TestCase::total_test_count() const { + return static_cast(test_info_list_.size()); +} + +// Creates a TestCase with the given name. +// +// Arguments: +// +// name: name of the test case +// set_up_tc: pointer to the function that sets up the test case +// tear_down_tc: pointer to the function that tears down the test case +TestCase::TestCase(const char* a_name, const char* a_comment, + Test::SetUpTestCaseFunc set_up_tc, + Test::TearDownTestCaseFunc tear_down_tc) + : name_(a_name), + comment_(a_comment), + set_up_tc_(set_up_tc), + tear_down_tc_(tear_down_tc), + should_run_(false), + elapsed_time_(0) { +} + +// Destructor of TestCase. +TestCase::~TestCase() { + // Deletes every Test in the collection. + ForEach(test_info_list_, internal::Delete); +} + +// Returns the i-th test among all the tests. i can range from 0 to +// total_test_count() - 1. If i is not in that range, returns NULL. +const TestInfo* TestCase::GetTestInfo(int i) const { + const int index = GetElementOr(test_indices_, i, -1); + return index < 0 ? NULL : test_info_list_[index]; +} + +// Returns the i-th test among all the tests. i can range from 0 to +// total_test_count() - 1. If i is not in that range, returns NULL. +TestInfo* TestCase::GetMutableTestInfo(int i) { + const int index = GetElementOr(test_indices_, i, -1); + return index < 0 ? NULL : test_info_list_[index]; +} + +// Adds a test to this test case. Will delete the test upon +// destruction of the TestCase object. +void TestCase::AddTestInfo(TestInfo * test_info) { + test_info_list_.push_back(test_info); + test_indices_.push_back(static_cast(test_indices_.size())); +} + +// Runs every test in this TestCase. +void TestCase::Run() { + if (!should_run_) return; + + internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); + impl->set_current_test_case(this); + + TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater(); + + repeater->OnTestCaseStart(*this); + impl->os_stack_trace_getter()->UponLeavingGTest(); + set_up_tc_(); + + const internal::TimeInMillis start = internal::GetTimeInMillis(); + for (int i = 0; i < total_test_count(); i++) { + GetMutableTestInfo(i)->impl()->Run(); + } + elapsed_time_ = internal::GetTimeInMillis() - start; + + impl->os_stack_trace_getter()->UponLeavingGTest(); + tear_down_tc_(); + repeater->OnTestCaseEnd(*this); + impl->set_current_test_case(NULL); +} + +// Clears the results of all tests in this test case. +void TestCase::ClearResult() { + ForEach(test_info_list_, internal::TestInfoImpl::ClearTestResult); +} + +// Returns true iff test passed. +bool TestCase::TestPassed(const TestInfo * test_info) { + const internal::TestInfoImpl* const impl = test_info->impl(); + return impl->should_run() && impl->result()->Passed(); +} + +// Returns true iff test failed. +bool TestCase::TestFailed(const TestInfo * test_info) { + const internal::TestInfoImpl* const impl = test_info->impl(); + return impl->should_run() && impl->result()->Failed(); +} + +// Returns true iff test is disabled. +bool TestCase::TestDisabled(const TestInfo * test_info) { + return test_info->impl()->is_disabled(); +} + +// Returns true if the given test should run. +bool TestCase::ShouldRunTest(const TestInfo *test_info) { + return test_info->impl()->should_run(); +} + +// Shuffles the tests in this test case. +void TestCase::ShuffleTests(internal::Random* random) { + Shuffle(random, &test_indices_); +} + +// Restores the test order to before the first shuffle. +void TestCase::UnshuffleTests() { + for (size_t i = 0; i < test_indices_.size(); i++) { + test_indices_[i] = static_cast(i); + } +} + +// Formats a countable noun. Depending on its quantity, either the +// singular form or the plural form is used. e.g. +// +// FormatCountableNoun(1, "formula", "formuli") returns "1 formula". +// FormatCountableNoun(5, "book", "books") returns "5 books". +static internal::String FormatCountableNoun(int count, + const char * singular_form, + const char * plural_form) { + return internal::String::Format("%d %s", count, + count == 1 ? singular_form : plural_form); +} + +// Formats the count of tests. +static internal::String FormatTestCount(int test_count) { + return FormatCountableNoun(test_count, "test", "tests"); +} + +// Formats the count of test cases. +static internal::String FormatTestCaseCount(int test_case_count) { + return FormatCountableNoun(test_case_count, "test case", "test cases"); +} + +// Converts a TestPartResult::Type enum to human-friendly string +// representation. Both kNonFatalFailure and kFatalFailure are translated +// to "Failure", as the user usually doesn't care about the difference +// between the two when viewing the test result. +static const char * TestPartResultTypeToString(TestPartResult::Type type) { + switch (type) { + case TestPartResult::kSuccess: + return "Success"; + + case TestPartResult::kNonFatalFailure: + case TestPartResult::kFatalFailure: +#ifdef _MSC_VER + return "error: "; +#else + return "Failure\n"; +#endif + } + + return "Unknown result type"; +} + +// Prints a TestPartResult to a String. +static internal::String PrintTestPartResultToString( + const TestPartResult& test_part_result) { + return (Message() + << internal::FormatFileLocation(test_part_result.file_name(), + test_part_result.line_number()) + << " " << TestPartResultTypeToString(test_part_result.type()) + << test_part_result.message()).GetString(); +} + +// Prints a TestPartResult. +static void PrintTestPartResult(const TestPartResult& test_part_result) { + const internal::String& result = + PrintTestPartResultToString(test_part_result); + printf("%s\n", result.c_str()); + fflush(stdout); + // If the test program runs in Visual Studio or a debugger, the + // following statements add the test part result message to the Output + // window such that the user can double-click on it to jump to the + // corresponding source code location; otherwise they do nothing. +#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE + // We don't call OutputDebugString*() on Windows Mobile, as printing + // to stdout is done by OutputDebugString() there already - we don't + // want the same message printed twice. + ::OutputDebugStringA(result.c_str()); + ::OutputDebugStringA("\n"); +#endif +} + +// class PrettyUnitTestResultPrinter + +namespace internal { + +enum GTestColor { + COLOR_DEFAULT, + COLOR_RED, + COLOR_GREEN, + COLOR_YELLOW +}; + +#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE + +// Returns the character attribute for the given color. +WORD GetColorAttribute(GTestColor color) { + switch (color) { + case COLOR_RED: return FOREGROUND_RED; + case COLOR_GREEN: return FOREGROUND_GREEN; + case COLOR_YELLOW: return FOREGROUND_RED | FOREGROUND_GREEN; + default: return 0; + } +} + +#else + +// Returns the ANSI color code for the given color. COLOR_DEFAULT is +// an invalid input. +const char* GetAnsiColorCode(GTestColor color) { + switch (color) { + case COLOR_RED: return "1"; + case COLOR_GREEN: return "2"; + case COLOR_YELLOW: return "3"; + default: return NULL; + }; +} + +#endif // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE + +// Returns true iff Google Test should use colors in the output. +bool ShouldUseColor(bool stdout_is_tty) { + const char* const gtest_color = GTEST_FLAG(color).c_str(); + + if (String::CaseInsensitiveCStringEquals(gtest_color, "auto")) { +#if GTEST_OS_WINDOWS + // On Windows the TERM variable is usually not set, but the + // console there does support colors. + return stdout_is_tty; +#else + // On non-Windows platforms, we rely on the TERM variable. + const char* const term = posix::GetEnv("TERM"); + const bool term_supports_color = + String::CStringEquals(term, "xterm") || + String::CStringEquals(term, "xterm-color") || + String::CStringEquals(term, "xterm-256color") || + String::CStringEquals(term, "linux") || + String::CStringEquals(term, "cygwin"); + return stdout_is_tty && term_supports_color; +#endif // GTEST_OS_WINDOWS + } + + return String::CaseInsensitiveCStringEquals(gtest_color, "yes") || + String::CaseInsensitiveCStringEquals(gtest_color, "true") || + String::CaseInsensitiveCStringEquals(gtest_color, "t") || + String::CStringEquals(gtest_color, "1"); + // We take "yes", "true", "t", and "1" as meaning "yes". If the + // value is neither one of these nor "auto", we treat it as "no" to + // be conservative. +} + +// Helpers for printing colored strings to stdout. Note that on Windows, we +// cannot simply emit special characters and have the terminal change colors. +// This routine must actually emit the characters rather than return a string +// that would be colored when printed, as can be done on Linux. +void ColoredPrintf(GTestColor color, const char* fmt, ...) { + va_list args; + va_start(args, fmt); + +#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_SYMBIAN || GTEST_OS_ZOS + const bool use_color = false; +#else + static const bool in_color_mode = + ShouldUseColor(posix::IsATTY(posix::FileNo(stdout)) != 0); + const bool use_color = in_color_mode && (color != COLOR_DEFAULT); +#endif // GTEST_OS_WINDOWS_MOBILE || GTEST_OS_SYMBIAN || GTEST_OS_ZOS + // The '!= 0' comparison is necessary to satisfy MSVC 7.1. + + if (!use_color) { + vprintf(fmt, args); + va_end(args); + return; + } + +#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE + const HANDLE stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE); + + // Gets the current text color. + CONSOLE_SCREEN_BUFFER_INFO buffer_info; + GetConsoleScreenBufferInfo(stdout_handle, &buffer_info); + const WORD old_color_attrs = buffer_info.wAttributes; + + // We need to flush the stream buffers into the console before each + // SetConsoleTextAttribute call lest it affect the text that is already + // printed but has not yet reached the console. + fflush(stdout); + SetConsoleTextAttribute(stdout_handle, + GetColorAttribute(color) | FOREGROUND_INTENSITY); + vprintf(fmt, args); + + fflush(stdout); + // Restores the text color. + SetConsoleTextAttribute(stdout_handle, old_color_attrs); +#else + printf("\033[0;3%sm", GetAnsiColorCode(color)); + vprintf(fmt, args); + printf("\033[m"); // Resets the terminal to default. +#endif // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE + va_end(args); +} + +// This class implements the TestEventListener interface. +// +// Class PrettyUnitTestResultPrinter is copyable. +class PrettyUnitTestResultPrinter : public TestEventListener { + public: + PrettyUnitTestResultPrinter() {} + static void PrintTestName(const char * test_case, const char * test) { + printf("%s.%s", test_case, test); + } + + // The following methods override what's in the TestEventListener class. + virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) {} + virtual void OnTestIterationStart(const UnitTest& unit_test, int iteration); + virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test); + virtual void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) {} + virtual void OnTestCaseStart(const TestCase& test_case); + virtual void OnTestStart(const TestInfo& test_info); + virtual void OnTestPartResult(const TestPartResult& result); + virtual void OnTestEnd(const TestInfo& test_info); + virtual void OnTestCaseEnd(const TestCase& test_case); + virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test); + virtual void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) {} + virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration); + virtual void OnTestProgramEnd(const UnitTest& /*unit_test*/) {} + + private: + static void PrintFailedTests(const UnitTest& unit_test); + + internal::String test_case_name_; +}; + + // Fired before each iteration of tests starts. +void PrettyUnitTestResultPrinter::OnTestIterationStart( + const UnitTest& unit_test, int iteration) { + if (GTEST_FLAG(repeat) != 1) + printf("\nRepeating all tests (iteration %d) . . .\n\n", iteration + 1); + + const char* const filter = GTEST_FLAG(filter).c_str(); + + // Prints the filter if it's not *. This reminds the user that some + // tests may be skipped. + if (!internal::String::CStringEquals(filter, kUniversalFilter)) { + ColoredPrintf(COLOR_YELLOW, + "Note: %s filter = %s\n", GTEST_NAME_, filter); + } + + if (internal::ShouldShard(kTestTotalShards, kTestShardIndex, false)) { + ColoredPrintf(COLOR_YELLOW, + "Note: This is test shard %s of %s.\n", + internal::posix::GetEnv(kTestShardIndex), + internal::posix::GetEnv(kTestTotalShards)); + } + + if (GTEST_FLAG(shuffle)) { + ColoredPrintf(COLOR_YELLOW, + "Note: Randomizing tests' orders with a seed of %d .\n", + unit_test.random_seed()); + } + + ColoredPrintf(COLOR_GREEN, "[==========] "); + printf("Running %s from %s.\n", + FormatTestCount(unit_test.test_to_run_count()).c_str(), + FormatTestCaseCount(unit_test.test_case_to_run_count()).c_str()); + fflush(stdout); +} + +void PrettyUnitTestResultPrinter::OnEnvironmentsSetUpStart( + const UnitTest& /*unit_test*/) { + ColoredPrintf(COLOR_GREEN, "[----------] "); + printf("Global test environment set-up.\n"); + fflush(stdout); +} + +void PrettyUnitTestResultPrinter::OnTestCaseStart(const TestCase& test_case) { + test_case_name_ = test_case.name(); + const internal::String counts = + FormatCountableNoun(test_case.test_to_run_count(), "test", "tests"); + ColoredPrintf(COLOR_GREEN, "[----------] "); + printf("%s from %s", counts.c_str(), test_case_name_.c_str()); + if (test_case.comment()[0] == '\0') { + printf("\n"); + } else { + printf(", where %s\n", test_case.comment()); + } + fflush(stdout); +} + +void PrettyUnitTestResultPrinter::OnTestStart(const TestInfo& test_info) { + ColoredPrintf(COLOR_GREEN, "[ RUN ] "); + PrintTestName(test_case_name_.c_str(), test_info.name()); + if (test_info.comment()[0] == '\0') { + printf("\n"); + } else { + printf(", where %s\n", test_info.comment()); + } + fflush(stdout); +} + +// Called after an assertion failure. +void PrettyUnitTestResultPrinter::OnTestPartResult( + const TestPartResult& result) { + // If the test part succeeded, we don't need to do anything. + if (result.type() == TestPartResult::kSuccess) + return; + + // Print failure message from the assertion (e.g. expected this and got that). + PrintTestPartResult(result); + fflush(stdout); +} + +void PrettyUnitTestResultPrinter::OnTestEnd(const TestInfo& test_info) { + if (test_info.result()->Passed()) { + ColoredPrintf(COLOR_GREEN, "[ OK ] "); + } else { + ColoredPrintf(COLOR_RED, "[ FAILED ] "); + } + PrintTestName(test_case_name_.c_str(), test_info.name()); + if (GTEST_FLAG(print_time)) { + printf(" (%s ms)\n", internal::StreamableToString( + test_info.result()->elapsed_time()).c_str()); + } else { + printf("\n"); + } + fflush(stdout); +} + +void PrettyUnitTestResultPrinter::OnTestCaseEnd(const TestCase& test_case) { + if (!GTEST_FLAG(print_time)) return; + + test_case_name_ = test_case.name(); + const internal::String counts = + FormatCountableNoun(test_case.test_to_run_count(), "test", "tests"); + ColoredPrintf(COLOR_GREEN, "[----------] "); + printf("%s from %s (%s ms total)\n\n", + counts.c_str(), test_case_name_.c_str(), + internal::StreamableToString(test_case.elapsed_time()).c_str()); + fflush(stdout); +} + +void PrettyUnitTestResultPrinter::OnEnvironmentsTearDownStart( + const UnitTest& /*unit_test*/) { + ColoredPrintf(COLOR_GREEN, "[----------] "); + printf("Global test environment tear-down\n"); + fflush(stdout); +} + +// Internal helper for printing the list of failed tests. +void PrettyUnitTestResultPrinter::PrintFailedTests(const UnitTest& unit_test) { + const int failed_test_count = unit_test.failed_test_count(); + if (failed_test_count == 0) { + return; + } + + for (int i = 0; i < unit_test.total_test_case_count(); ++i) { + const TestCase& test_case = *unit_test.GetTestCase(i); + if (!test_case.should_run() || (test_case.failed_test_count() == 0)) { + continue; + } + for (int j = 0; j < test_case.total_test_count(); ++j) { + const TestInfo& test_info = *test_case.GetTestInfo(j); + if (!test_info.should_run() || test_info.result()->Passed()) { + continue; + } + ColoredPrintf(COLOR_RED, "[ FAILED ] "); + printf("%s.%s", test_case.name(), test_info.name()); + if (test_case.comment()[0] != '\0' || + test_info.comment()[0] != '\0') { + printf(", where %s", test_case.comment()); + if (test_case.comment()[0] != '\0' && + test_info.comment()[0] != '\0') { + printf(" and "); + } + } + printf("%s\n", test_info.comment()); + } + } +} + + void PrettyUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test, + int /*iteration*/) { + ColoredPrintf(COLOR_GREEN, "[==========] "); + printf("%s from %s ran.", + FormatTestCount(unit_test.test_to_run_count()).c_str(), + FormatTestCaseCount(unit_test.test_case_to_run_count()).c_str()); + if (GTEST_FLAG(print_time)) { + printf(" (%s ms total)", + internal::StreamableToString(unit_test.elapsed_time()).c_str()); + } + printf("\n"); + ColoredPrintf(COLOR_GREEN, "[ PASSED ] "); + printf("%s.\n", FormatTestCount(unit_test.successful_test_count()).c_str()); + + int num_failures = unit_test.failed_test_count(); + if (!unit_test.Passed()) { + const int failed_test_count = unit_test.failed_test_count(); + ColoredPrintf(COLOR_RED, "[ FAILED ] "); + printf("%s, listed below:\n", FormatTestCount(failed_test_count).c_str()); + PrintFailedTests(unit_test); + printf("\n%2d FAILED %s\n", num_failures, + num_failures == 1 ? "TEST" : "TESTS"); + } + + int num_disabled = unit_test.disabled_test_count(); + if (num_disabled && !GTEST_FLAG(also_run_disabled_tests)) { + if (!num_failures) { + printf("\n"); // Add a spacer if no FAILURE banner is displayed. + } + ColoredPrintf(COLOR_YELLOW, + " YOU HAVE %d DISABLED %s\n\n", + num_disabled, + num_disabled == 1 ? "TEST" : "TESTS"); + } + // Ensure that Google Test output is printed before, e.g., heapchecker output. + fflush(stdout); +} + +// End PrettyUnitTestResultPrinter + +// class TestEventRepeater +// +// This class forwards events to other event listeners. +class TestEventRepeater : public TestEventListener { + public: + TestEventRepeater() : forwarding_enabled_(true) {} + virtual ~TestEventRepeater(); + void Append(TestEventListener *listener); + TestEventListener* Release(TestEventListener* listener); + + // Controls whether events will be forwarded to listeners_. Set to false + // in death test child processes. + bool forwarding_enabled() const { return forwarding_enabled_; } + void set_forwarding_enabled(bool enable) { forwarding_enabled_ = enable; } + + virtual void OnTestProgramStart(const UnitTest& unit_test); + virtual void OnTestIterationStart(const UnitTest& unit_test, int iteration); + virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test); + virtual void OnEnvironmentsSetUpEnd(const UnitTest& unit_test); + virtual void OnTestCaseStart(const TestCase& test_case); + virtual void OnTestStart(const TestInfo& test_info); + virtual void OnTestPartResult(const TestPartResult& result); + virtual void OnTestEnd(const TestInfo& test_info); + virtual void OnTestCaseEnd(const TestCase& test_case); + virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test); + virtual void OnEnvironmentsTearDownEnd(const UnitTest& unit_test); + virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration); + virtual void OnTestProgramEnd(const UnitTest& unit_test); + + private: + // Controls whether events will be forwarded to listeners_. Set to false + // in death test child processes. + bool forwarding_enabled_; + // The list of listeners that receive events. + std::vector listeners_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestEventRepeater); +}; + +TestEventRepeater::~TestEventRepeater() { + ForEach(listeners_, Delete); +} + +void TestEventRepeater::Append(TestEventListener *listener) { + listeners_.push_back(listener); +} + +// TODO(vladl@google.com): Factor the search functionality into Vector::Find. +TestEventListener* TestEventRepeater::Release(TestEventListener *listener) { + for (size_t i = 0; i < listeners_.size(); ++i) { + if (listeners_[i] == listener) { + listeners_.erase(listeners_.begin() + i); + return listener; + } + } + + return NULL; +} + +// Since most methods are very similar, use macros to reduce boilerplate. +// This defines a member that forwards the call to all listeners. +#define GTEST_REPEATER_METHOD_(Name, Type) \ +void TestEventRepeater::Name(const Type& parameter) { \ + if (forwarding_enabled_) { \ + for (size_t i = 0; i < listeners_.size(); i++) { \ + listeners_[i]->Name(parameter); \ + } \ + } \ +} +// This defines a member that forwards the call to all listeners in reverse +// order. +#define GTEST_REVERSE_REPEATER_METHOD_(Name, Type) \ +void TestEventRepeater::Name(const Type& parameter) { \ + if (forwarding_enabled_) { \ + for (int i = static_cast(listeners_.size()) - 1; i >= 0; i--) { \ + listeners_[i]->Name(parameter); \ + } \ + } \ +} + +GTEST_REPEATER_METHOD_(OnTestProgramStart, UnitTest) +GTEST_REPEATER_METHOD_(OnEnvironmentsSetUpStart, UnitTest) +GTEST_REPEATER_METHOD_(OnTestCaseStart, TestCase) +GTEST_REPEATER_METHOD_(OnTestStart, TestInfo) +GTEST_REPEATER_METHOD_(OnTestPartResult, TestPartResult) +GTEST_REPEATER_METHOD_(OnEnvironmentsTearDownStart, UnitTest) +GTEST_REVERSE_REPEATER_METHOD_(OnEnvironmentsSetUpEnd, UnitTest) +GTEST_REVERSE_REPEATER_METHOD_(OnEnvironmentsTearDownEnd, UnitTest) +GTEST_REVERSE_REPEATER_METHOD_(OnTestEnd, TestInfo) +GTEST_REVERSE_REPEATER_METHOD_(OnTestCaseEnd, TestCase) +GTEST_REVERSE_REPEATER_METHOD_(OnTestProgramEnd, UnitTest) + +#undef GTEST_REPEATER_METHOD_ +#undef GTEST_REVERSE_REPEATER_METHOD_ + +void TestEventRepeater::OnTestIterationStart(const UnitTest& unit_test, + int iteration) { + if (forwarding_enabled_) { + for (size_t i = 0; i < listeners_.size(); i++) { + listeners_[i]->OnTestIterationStart(unit_test, iteration); + } + } +} + +void TestEventRepeater::OnTestIterationEnd(const UnitTest& unit_test, + int iteration) { + if (forwarding_enabled_) { + for (int i = static_cast(listeners_.size()) - 1; i >= 0; i--) { + listeners_[i]->OnTestIterationEnd(unit_test, iteration); + } + } +} + +// End TestEventRepeater + +// This class generates an XML output file. +class XmlUnitTestResultPrinter : public EmptyTestEventListener { + public: + explicit XmlUnitTestResultPrinter(const char* output_file); + + virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration); + + private: + // Is c a whitespace character that is normalized to a space character + // when it appears in an XML attribute value? + static bool IsNormalizableWhitespace(char c) { + return c == 0x9 || c == 0xA || c == 0xD; + } + + // May c appear in a well-formed XML document? + static bool IsValidXmlCharacter(char c) { + return IsNormalizableWhitespace(c) || c >= 0x20; + } + + // Returns an XML-escaped copy of the input string str. If + // is_attribute is true, the text is meant to appear as an attribute + // value, and normalizable whitespace is preserved by replacing it + // with character references. + static String EscapeXml(const char* str, bool is_attribute); + + // Returns the given string with all characters invalid in XML removed. + static String RemoveInvalidXmlCharacters(const char* str); + + // Convenience wrapper around EscapeXml when str is an attribute value. + static String EscapeXmlAttribute(const char* str) { + return EscapeXml(str, true); + } + + // Convenience wrapper around EscapeXml when str is not an attribute value. + static String EscapeXmlText(const char* str) { return EscapeXml(str, false); } + + // Streams an XML CDATA section, escaping invalid CDATA sequences as needed. + static void OutputXmlCDataSection(::std::ostream* stream, const char* data); + + // Streams an XML representation of a TestInfo object. + static void OutputXmlTestInfo(::std::ostream* stream, + const char* test_case_name, + const TestInfo& test_info); + + // Prints an XML representation of a TestCase object + static void PrintXmlTestCase(FILE* out, const TestCase& test_case); + + // Prints an XML summary of unit_test to output stream out. + static void PrintXmlUnitTest(FILE* out, const UnitTest& unit_test); + + // Produces a string representing the test properties in a result as space + // delimited XML attributes based on the property key="value" pairs. + // When the String is not empty, it includes a space at the beginning, + // to delimit this attribute from prior attributes. + static String TestPropertiesAsXmlAttributes(const TestResult& result); + + // The output file. + const String output_file_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(XmlUnitTestResultPrinter); +}; + +// Creates a new XmlUnitTestResultPrinter. +XmlUnitTestResultPrinter::XmlUnitTestResultPrinter(const char* output_file) + : output_file_(output_file) { + if (output_file_.c_str() == NULL || output_file_.empty()) { + fprintf(stderr, "XML output file may not be null\n"); + fflush(stderr); + exit(EXIT_FAILURE); + } +} + +// Called after the unit test ends. +void XmlUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test, + int /*iteration*/) { + FILE* xmlout = NULL; + FilePath output_file(output_file_); + FilePath output_dir(output_file.RemoveFileName()); + + if (output_dir.CreateDirectoriesRecursively()) { + xmlout = posix::FOpen(output_file_.c_str(), "w"); + } + if (xmlout == NULL) { + // TODO(wan): report the reason of the failure. + // + // We don't do it for now as: + // + // 1. There is no urgent need for it. + // 2. It's a bit involved to make the errno variable thread-safe on + // all three operating systems (Linux, Windows, and Mac OS). + // 3. To interpret the meaning of errno in a thread-safe way, + // we need the strerror_r() function, which is not available on + // Windows. + fprintf(stderr, + "Unable to open file \"%s\"\n", + output_file_.c_str()); + fflush(stderr); + exit(EXIT_FAILURE); + } + PrintXmlUnitTest(xmlout, unit_test); + fclose(xmlout); +} + +// Returns an XML-escaped copy of the input string str. If is_attribute +// is true, the text is meant to appear as an attribute value, and +// normalizable whitespace is preserved by replacing it with character +// references. +// +// Invalid XML characters in str, if any, are stripped from the output. +// It is expected that most, if not all, of the text processed by this +// module will consist of ordinary English text. +// If this module is ever modified to produce version 1.1 XML output, +// most invalid characters can be retained using character references. +// TODO(wan): It might be nice to have a minimally invasive, human-readable +// escaping scheme for invalid characters, rather than dropping them. +String XmlUnitTestResultPrinter::EscapeXml(const char* str, bool is_attribute) { + Message m; + + if (str != NULL) { + for (const char* src = str; *src; ++src) { + switch (*src) { + case '<': + m << "<"; + break; + case '>': + m << ">"; + break; + case '&': + m << "&"; + break; + case '\'': + if (is_attribute) + m << "'"; + else + m << '\''; + break; + case '"': + if (is_attribute) + m << """; + else + m << '"'; + break; + default: + if (IsValidXmlCharacter(*src)) { + if (is_attribute && IsNormalizableWhitespace(*src)) + m << String::Format("&#x%02X;", unsigned(*src)); + else + m << *src; + } + break; + } + } + } + + return m.GetString(); +} + +// Returns the given string with all characters invalid in XML removed. +// Currently invalid characters are dropped from the string. An +// alternative is to replace them with certain characters such as . or ?. +String XmlUnitTestResultPrinter::RemoveInvalidXmlCharacters(const char* str) { + char* const output = new char[strlen(str) + 1]; + char* appender = output; + for (char ch = *str; ch != '\0'; ch = *++str) + if (IsValidXmlCharacter(ch)) + *appender++ = ch; + *appender = '\0'; + + String ret_value(output); + delete[] output; + return ret_value; +} + +// The following routines generate an XML representation of a UnitTest +// object. +// +// This is how Google Test concepts map to the DTD: +// +// <-- corresponds to a UnitTest object +// <-- corresponds to a TestCase object +// <-- corresponds to a TestInfo object +// ... +// ... +// ... +// <-- individual assertion failures +// +// +// + +// Formats the given time in milliseconds as seconds. +std::string FormatTimeInMillisAsSeconds(TimeInMillis ms) { + ::std::stringstream ss; + ss << ms/1000.0; + return ss.str(); +} + +// Streams an XML CDATA section, escaping invalid CDATA sequences as needed. +void XmlUnitTestResultPrinter::OutputXmlCDataSection(::std::ostream* stream, + const char* data) { + const char* segment = data; + *stream << ""); + if (next_segment != NULL) { + stream->write( + segment, static_cast(next_segment - segment)); + *stream << "]]>]]>"); + } else { + *stream << segment; + break; + } + } + *stream << "]]>"; +} + +// Prints an XML representation of a TestInfo object. +// TODO(wan): There is also value in printing properties with the plain printer. +void XmlUnitTestResultPrinter::OutputXmlTestInfo(::std::ostream* stream, + const char* test_case_name, + const TestInfo& test_info) { + const TestResult& result = *test_info.result(); + *stream << " \n"; + *stream << " "; + const String message = RemoveInvalidXmlCharacters(String::Format( + "%s:%d\n%s", + part.file_name(), part.line_number(), + part.message()).c_str()); + OutputXmlCDataSection(stream, message.c_str()); + *stream << "\n"; + } + } + + if (failures == 0) + *stream << " />\n"; + else + *stream << " \n"; +} + +// Prints an XML representation of a TestCase object +void XmlUnitTestResultPrinter::PrintXmlTestCase(FILE* out, + const TestCase& test_case) { + fprintf(out, + " \n", + FormatTimeInMillisAsSeconds(test_case.elapsed_time()).c_str()); + for (int i = 0; i < test_case.total_test_count(); ++i) { + StrStream stream; + OutputXmlTestInfo(&stream, test_case.name(), *test_case.GetTestInfo(i)); + fprintf(out, "%s", StrStreamToString(&stream).c_str()); + } + fprintf(out, " \n"); +} + +// Prints an XML summary of unit_test to output stream out. +void XmlUnitTestResultPrinter::PrintXmlUnitTest(FILE* out, + const UnitTest& unit_test) { + fprintf(out, "\n"); + fprintf(out, + "\n"); + for (int i = 0; i < unit_test.total_test_case_count(); ++i) + PrintXmlTestCase(out, *unit_test.GetTestCase(i)); + fprintf(out, "\n"); +} + +// Produces a string representing the test properties in a result as space +// delimited XML attributes based on the property key="value" pairs. +String XmlUnitTestResultPrinter::TestPropertiesAsXmlAttributes( + const TestResult& result) { + Message attributes; + for (int i = 0; i < result.test_property_count(); ++i) { + const TestProperty& property = result.GetTestProperty(i); + attributes << " " << property.key() << "=" + << "\"" << EscapeXmlAttribute(property.value()) << "\""; + } + return attributes.GetString(); +} + +// End XmlUnitTestResultPrinter + +// Class ScopedTrace + +// Pushes the given source file location and message onto a per-thread +// trace stack maintained by Google Test. +// L < UnitTest::mutex_ +ScopedTrace::ScopedTrace(const char* file, int line, const Message& message) { + TraceInfo trace; + trace.file = file; + trace.line = line; + trace.message = message.GetString(); + + UnitTest::GetInstance()->PushGTestTrace(trace); +} + +// Pops the info pushed by the c'tor. +// L < UnitTest::mutex_ +ScopedTrace::~ScopedTrace() { + UnitTest::GetInstance()->PopGTestTrace(); +} + + +// class OsStackTraceGetter + +// Returns the current OS stack trace as a String. Parameters: +// +// max_depth - the maximum number of stack frames to be included +// in the trace. +// skip_count - the number of top frames to be skipped; doesn't count +// against max_depth. +// +// L < mutex_ +// We use "L < mutex_" to denote that the function may acquire mutex_. +String OsStackTraceGetter::CurrentStackTrace(int, int) { + return String(""); +} + +// L < mutex_ +void OsStackTraceGetter::UponLeavingGTest() { +} + +const char* const +OsStackTraceGetter::kElidedFramesMarker = + "... " GTEST_NAME_ " internal frames ..."; + +} // namespace internal + +// class TestEventListeners + +TestEventListeners::TestEventListeners() + : repeater_(new internal::TestEventRepeater()), + default_result_printer_(NULL), + default_xml_generator_(NULL) { +} + +TestEventListeners::~TestEventListeners() { delete repeater_; } + +// Returns the standard listener responsible for the default console +// output. Can be removed from the listeners list to shut down default +// console output. Note that removing this object from the listener list +// with Release transfers its ownership to the user. +void TestEventListeners::Append(TestEventListener* listener) { + repeater_->Append(listener); +} + +// Removes the given event listener from the list and returns it. It then +// becomes the caller's responsibility to delete the listener. Returns +// NULL if the listener is not found in the list. +TestEventListener* TestEventListeners::Release(TestEventListener* listener) { + if (listener == default_result_printer_) + default_result_printer_ = NULL; + else if (listener == default_xml_generator_) + default_xml_generator_ = NULL; + return repeater_->Release(listener); +} + +// Returns repeater that broadcasts the TestEventListener events to all +// subscribers. +TestEventListener* TestEventListeners::repeater() { return repeater_; } + +// Sets the default_result_printer attribute to the provided listener. +// The listener is also added to the listener list and previous +// default_result_printer is removed from it and deleted. The listener can +// also be NULL in which case it will not be added to the list. Does +// nothing if the previous and the current listener objects are the same. +void TestEventListeners::SetDefaultResultPrinter(TestEventListener* listener) { + if (default_result_printer_ != listener) { + // It is an error to pass this method a listener that is already in the + // list. + delete Release(default_result_printer_); + default_result_printer_ = listener; + if (listener != NULL) + Append(listener); + } +} + +// Sets the default_xml_generator attribute to the provided listener. The +// listener is also added to the listener list and previous +// default_xml_generator is removed from it and deleted. The listener can +// also be NULL in which case it will not be added to the list. Does +// nothing if the previous and the current listener objects are the same. +void TestEventListeners::SetDefaultXmlGenerator(TestEventListener* listener) { + if (default_xml_generator_ != listener) { + // It is an error to pass this method a listener that is already in the + // list. + delete Release(default_xml_generator_); + default_xml_generator_ = listener; + if (listener != NULL) + Append(listener); + } +} + +// Controls whether events will be forwarded by the repeater to the +// listeners in the list. +bool TestEventListeners::EventForwardingEnabled() const { + return repeater_->forwarding_enabled(); +} + +void TestEventListeners::SuppressEventForwarding() { + repeater_->set_forwarding_enabled(false); +} + +// class UnitTest + +// Gets the singleton UnitTest object. The first time this method is +// called, a UnitTest object is constructed and returned. Consecutive +// calls will return the same object. +// +// We don't protect this under mutex_ as a user is not supposed to +// call this before main() starts, from which point on the return +// value will never change. +UnitTest * UnitTest::GetInstance() { + // When compiled with MSVC 7.1 in optimized mode, destroying the + // UnitTest object upon exiting the program messes up the exit code, + // causing successful tests to appear failed. We have to use a + // different implementation in this case to bypass the compiler bug. + // This implementation makes the compiler happy, at the cost of + // leaking the UnitTest object. + + // CodeGear C++Builder insists on a public destructor for the + // default implementation. Use this implementation to keep good OO + // design with private destructor. + +#if (_MSC_VER == 1310 && !defined(_DEBUG)) || defined(__BORLANDC__) + static UnitTest* const instance = new UnitTest; + return instance; +#else + static UnitTest instance; + return &instance; +#endif // (_MSC_VER == 1310 && !defined(_DEBUG)) || defined(__BORLANDC__) +} + +// Gets the number of successful test cases. +int UnitTest::successful_test_case_count() const { + return impl()->successful_test_case_count(); +} + +// Gets the number of failed test cases. +int UnitTest::failed_test_case_count() const { + return impl()->failed_test_case_count(); +} + +// Gets the number of all test cases. +int UnitTest::total_test_case_count() const { + return impl()->total_test_case_count(); +} + +// Gets the number of all test cases that contain at least one test +// that should run. +int UnitTest::test_case_to_run_count() const { + return impl()->test_case_to_run_count(); +} + +// Gets the number of successful tests. +int UnitTest::successful_test_count() const { + return impl()->successful_test_count(); +} + +// Gets the number of failed tests. +int UnitTest::failed_test_count() const { return impl()->failed_test_count(); } + +// Gets the number of disabled tests. +int UnitTest::disabled_test_count() const { + return impl()->disabled_test_count(); +} + +// Gets the number of all tests. +int UnitTest::total_test_count() const { return impl()->total_test_count(); } + +// Gets the number of tests that should run. +int UnitTest::test_to_run_count() const { return impl()->test_to_run_count(); } + +// Gets the elapsed time, in milliseconds. +internal::TimeInMillis UnitTest::elapsed_time() const { + return impl()->elapsed_time(); +} + +// Returns true iff the unit test passed (i.e. all test cases passed). +bool UnitTest::Passed() const { return impl()->Passed(); } + +// Returns true iff the unit test failed (i.e. some test case failed +// or something outside of all tests failed). +bool UnitTest::Failed() const { return impl()->Failed(); } + +// Gets the i-th test case among all the test cases. i can range from 0 to +// total_test_case_count() - 1. If i is not in that range, returns NULL. +const TestCase* UnitTest::GetTestCase(int i) const { + return impl()->GetTestCase(i); +} + +// Gets the i-th test case among all the test cases. i can range from 0 to +// total_test_case_count() - 1. If i is not in that range, returns NULL. +TestCase* UnitTest::GetMutableTestCase(int i) { + return impl()->GetMutableTestCase(i); +} + +// Returns the list of event listeners that can be used to track events +// inside Google Test. +TestEventListeners& UnitTest::listeners() { + return *impl()->listeners(); +} + +// Registers and returns a global test environment. When a test +// program is run, all global test environments will be set-up in the +// order they were registered. After all tests in the program have +// finished, all global test environments will be torn-down in the +// *reverse* order they were registered. +// +// The UnitTest object takes ownership of the given environment. +// +// We don't protect this under mutex_, as we only support calling it +// from the main thread. +Environment* UnitTest::AddEnvironment(Environment* env) { + if (env == NULL) { + return NULL; + } + + impl_->environments().push_back(env); + return env; +} + +#if GTEST_HAS_EXCEPTIONS +// A failed Google Test assertion will throw an exception of this type +// when exceptions are enabled. We derive it from std::runtime_error, +// which is for errors presumably detectable only at run time. Since +// std::runtime_error inherits from std::exception, many testing +// frameworks know how to extract and print the message inside it. +class GoogleTestFailureException : public ::std::runtime_error { + public: + explicit GoogleTestFailureException(const TestPartResult& failure) + : ::std::runtime_error(PrintTestPartResultToString(failure).c_str()) {} +}; +#endif + +// Adds a TestPartResult to the current TestResult object. All Google Test +// assertion macros (e.g. ASSERT_TRUE, EXPECT_EQ, etc) eventually call +// this to report their results. The user code should use the +// assertion macros instead of calling this directly. +// L < mutex_ +void UnitTest::AddTestPartResult(TestPartResult::Type result_type, + const char* file_name, + int line_number, + const internal::String& message, + const internal::String& os_stack_trace) { + Message msg; + msg << message; + + internal::MutexLock lock(&mutex_); + if (impl_->gtest_trace_stack().size() > 0) { + msg << "\n" << GTEST_NAME_ << " trace:"; + + for (int i = static_cast(impl_->gtest_trace_stack().size()); + i > 0; --i) { + const internal::TraceInfo& trace = impl_->gtest_trace_stack()[i - 1]; + msg << "\n" << internal::FormatFileLocation(trace.file, trace.line) + << " " << trace.message; + } + } + + if (os_stack_trace.c_str() != NULL && !os_stack_trace.empty()) { + msg << internal::kStackTraceMarker << os_stack_trace; + } + + const TestPartResult result = + TestPartResult(result_type, file_name, line_number, + msg.GetString().c_str()); + impl_->GetTestPartResultReporterForCurrentThread()-> + ReportTestPartResult(result); + + if (result_type != TestPartResult::kSuccess) { + // gtest_break_on_failure takes precedence over + // gtest_throw_on_failure. This allows a user to set the latter + // in the code (perhaps in order to use Google Test assertions + // with another testing framework) and specify the former on the + // command line for debugging. + if (GTEST_FLAG(break_on_failure)) { +#if GTEST_OS_WINDOWS + // Using DebugBreak on Windows allows gtest to still break into a debugger + // when a failure happens and both the --gtest_break_on_failure and + // the --gtest_catch_exceptions flags are specified. + DebugBreak(); +#else + *static_cast(NULL) = 1; +#endif // GTEST_OS_WINDOWS + } else if (GTEST_FLAG(throw_on_failure)) { +#if GTEST_HAS_EXCEPTIONS + throw GoogleTestFailureException(result); +#else + // We cannot call abort() as it generates a pop-up in debug mode + // that cannot be suppressed in VC 7.1 or below. + exit(1); +#endif + } + } +} + +// Creates and adds a property to the current TestResult. If a property matching +// the supplied value already exists, updates its value instead. +void UnitTest::RecordPropertyForCurrentTest(const char* key, + const char* value) { + const TestProperty test_property(key, value); + impl_->current_test_result()->RecordProperty(test_property); +} + +// Runs all tests in this UnitTest object and prints the result. +// Returns 0 if successful, or 1 otherwise. +// +// We don't protect this under mutex_, as we only support calling it +// from the main thread. +int UnitTest::Run() { +#if GTEST_HAS_SEH + // Catch SEH-style exceptions. + + const bool in_death_test_child_process = + internal::GTEST_FLAG(internal_run_death_test).length() > 0; + + // Either the user wants Google Test to catch exceptions thrown by the + // tests or this is executing in the context of death test child + // process. In either case the user does not want to see pop-up dialogs + // about crashes - they are expected.. + if (GTEST_FLAG(catch_exceptions) || in_death_test_child_process) { +#if !GTEST_OS_WINDOWS_MOBILE + // SetErrorMode doesn't exist on CE. + SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOALIGNMENTFAULTEXCEPT | + SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX); +#endif // !GTEST_OS_WINDOWS_MOBILE + +#if (defined(_MSC_VER) || GTEST_OS_WINDOWS_MINGW) && !GTEST_OS_WINDOWS_MOBILE + // Death test children can be terminated with _abort(). On Windows, + // _abort() can show a dialog with a warning message. This forces the + // abort message to go to stderr instead. + _set_error_mode(_OUT_TO_STDERR); +#endif + +#if _MSC_VER >= 1400 && !GTEST_OS_WINDOWS_MOBILE + // In the debug version, Visual Studio pops up a separate dialog + // offering a choice to debug the aborted program. We need to suppress + // this dialog or it will pop up for every EXPECT/ASSERT_DEATH statement + // executed. Google Test will notify the user of any unexpected + // failure via stderr. + // + // VC++ doesn't define _set_abort_behavior() prior to the version 8.0. + // Users of prior VC versions shall suffer the agony and pain of + // clicking through the countless debug dialogs. + // TODO(vladl@google.com): find a way to suppress the abort dialog() in the + // debug mode when compiled with VC 7.1 or lower. + if (!GTEST_FLAG(break_on_failure)) + _set_abort_behavior( + 0x0, // Clear the following flags: + _WRITE_ABORT_MSG | _CALL_REPORTFAULT); // pop-up window, core dump. +#endif + } + + __try { + return impl_->RunAllTests(); + } __except(internal::UnitTestOptions::GTestShouldProcessSEH( + GetExceptionCode())) { + printf("Exception thrown with code 0x%x.\nFAIL\n", GetExceptionCode()); + fflush(stdout); + return 1; + } + +#else // We are on a compiler or platform that doesn't support SEH. + + return impl_->RunAllTests(); +#endif // GTEST_HAS_SEH +} + +// Returns the working directory when the first TEST() or TEST_F() was +// executed. +const char* UnitTest::original_working_dir() const { + return impl_->original_working_dir_.c_str(); +} + +// Returns the TestCase object for the test that's currently running, +// or NULL if no test is running. +// L < mutex_ +const TestCase* UnitTest::current_test_case() const { + internal::MutexLock lock(&mutex_); + return impl_->current_test_case(); +} + +// Returns the TestInfo object for the test that's currently running, +// or NULL if no test is running. +// L < mutex_ +const TestInfo* UnitTest::current_test_info() const { + internal::MutexLock lock(&mutex_); + return impl_->current_test_info(); +} + +// Returns the random seed used at the start of the current test run. +int UnitTest::random_seed() const { return impl_->random_seed(); } + +#if GTEST_HAS_PARAM_TEST +// Returns ParameterizedTestCaseRegistry object used to keep track of +// value-parameterized tests and instantiate and register them. +// L < mutex_ +internal::ParameterizedTestCaseRegistry& + UnitTest::parameterized_test_registry() { + return impl_->parameterized_test_registry(); +} +#endif // GTEST_HAS_PARAM_TEST + +// Creates an empty UnitTest. +UnitTest::UnitTest() { + impl_ = new internal::UnitTestImpl(this); +} + +// Destructor of UnitTest. +UnitTest::~UnitTest() { + delete impl_; +} + +// Pushes a trace defined by SCOPED_TRACE() on to the per-thread +// Google Test trace stack. +// L < mutex_ +void UnitTest::PushGTestTrace(const internal::TraceInfo& trace) { + internal::MutexLock lock(&mutex_); + impl_->gtest_trace_stack().push_back(trace); +} + +// Pops a trace from the per-thread Google Test trace stack. +// L < mutex_ +void UnitTest::PopGTestTrace() { + internal::MutexLock lock(&mutex_); + impl_->gtest_trace_stack().pop_back(); +} + +namespace internal { + +UnitTestImpl::UnitTestImpl(UnitTest* parent) + : parent_(parent), +#ifdef _MSC_VER +#pragma warning(push) // Saves the current warning state. +#pragma warning(disable:4355) // Temporarily disables warning 4355 + // (using this in initializer). + default_global_test_part_result_reporter_(this), + default_per_thread_test_part_result_reporter_(this), +#pragma warning(pop) // Restores the warning state again. +#else + default_global_test_part_result_reporter_(this), + default_per_thread_test_part_result_reporter_(this), +#endif // _MSC_VER + global_test_part_result_repoter_( + &default_global_test_part_result_reporter_), + per_thread_test_part_result_reporter_( + &default_per_thread_test_part_result_reporter_), +#if GTEST_HAS_PARAM_TEST + parameterized_test_registry_(), + parameterized_tests_registered_(false), +#endif // GTEST_HAS_PARAM_TEST + last_death_test_case_(-1), + current_test_case_(NULL), + current_test_info_(NULL), + ad_hoc_test_result_(), + os_stack_trace_getter_(NULL), + post_flag_parse_init_performed_(false), + random_seed_(0), // Will be overridden by the flag before first use. + random_(0), // Will be reseeded before first use. +#if GTEST_HAS_DEATH_TEST + elapsed_time_(0), + internal_run_death_test_flag_(NULL), + death_test_factory_(new DefaultDeathTestFactory) { +#else + elapsed_time_(0) { +#endif // GTEST_HAS_DEATH_TEST + listeners()->SetDefaultResultPrinter(new PrettyUnitTestResultPrinter); +} + +UnitTestImpl::~UnitTestImpl() { + // Deletes every TestCase. + ForEach(test_cases_, internal::Delete); + + // Deletes every Environment. + ForEach(environments_, internal::Delete); + + delete os_stack_trace_getter_; +} + +#if GTEST_HAS_DEATH_TEST +// Disables event forwarding if the control is currently in a death test +// subprocess. Must not be called before InitGoogleTest. +void UnitTestImpl::SuppressTestEventsIfInSubprocess() { + if (internal_run_death_test_flag_.get() != NULL) + listeners()->SuppressEventForwarding(); +} +#endif // GTEST_HAS_DEATH_TEST + +// Initializes event listeners performing XML output as specified by +// UnitTestOptions. Must not be called before InitGoogleTest. +void UnitTestImpl::ConfigureXmlOutput() { + const String& output_format = UnitTestOptions::GetOutputFormat(); + if (output_format == "xml") { + listeners()->SetDefaultXmlGenerator(new XmlUnitTestResultPrinter( + UnitTestOptions::GetAbsolutePathToOutputFile().c_str())); + } else if (output_format != "") { + printf("WARNING: unrecognized output format \"%s\" ignored.\n", + output_format.c_str()); + fflush(stdout); + } +} + +// Performs initialization dependent upon flag values obtained in +// ParseGoogleTestFlagsOnly. Is called from InitGoogleTest after the call to +// ParseGoogleTestFlagsOnly. In case a user neglects to call InitGoogleTest +// this function is also called from RunAllTests. Since this function can be +// called more than once, it has to be idempotent. +void UnitTestImpl::PostFlagParsingInit() { + // Ensures that this function does not execute more than once. + if (!post_flag_parse_init_performed_) { + post_flag_parse_init_performed_ = true; + +#if GTEST_HAS_DEATH_TEST + InitDeathTestSubprocessControlInfo(); + SuppressTestEventsIfInSubprocess(); +#endif // GTEST_HAS_DEATH_TEST + + // Registers parameterized tests. This makes parameterized tests + // available to the UnitTest reflection API without running + // RUN_ALL_TESTS. + RegisterParameterizedTests(); + + // Configures listeners for XML output. This makes it possible for users + // to shut down the default XML output before invoking RUN_ALL_TESTS. + ConfigureXmlOutput(); + } +} + +// A predicate that checks the name of a TestCase against a known +// value. +// +// This is used for implementation of the UnitTest class only. We put +// it in the anonymous namespace to prevent polluting the outer +// namespace. +// +// TestCaseNameIs is copyable. +class TestCaseNameIs { + public: + // Constructor. + explicit TestCaseNameIs(const String& name) + : name_(name) {} + + // Returns true iff the name of test_case matches name_. + bool operator()(const TestCase* test_case) const { + return test_case != NULL && strcmp(test_case->name(), name_.c_str()) == 0; + } + + private: + String name_; +}; + +// Finds and returns a TestCase with the given name. If one doesn't +// exist, creates one and returns it. It's the CALLER'S +// RESPONSIBILITY to ensure that this function is only called WHEN THE +// TESTS ARE NOT SHUFFLED. +// +// Arguments: +// +// test_case_name: name of the test case +// set_up_tc: pointer to the function that sets up the test case +// tear_down_tc: pointer to the function that tears down the test case +TestCase* UnitTestImpl::GetTestCase(const char* test_case_name, + const char* comment, + Test::SetUpTestCaseFunc set_up_tc, + Test::TearDownTestCaseFunc tear_down_tc) { + // Can we find a TestCase with the given name? + const std::vector::const_iterator test_case = + std::find_if(test_cases_.begin(), test_cases_.end(), + TestCaseNameIs(test_case_name)); + + if (test_case != test_cases_.end()) + return *test_case; + + // No. Let's create one. + TestCase* const new_test_case = + new TestCase(test_case_name, comment, set_up_tc, tear_down_tc); + + // Is this a death test case? + if (internal::UnitTestOptions::MatchesFilter(String(test_case_name), + kDeathTestCaseFilter)) { + // Yes. Inserts the test case after the last death test case + // defined so far. This only works when the test cases haven't + // been shuffled. Otherwise we may end up running a death test + // after a non-death test. + ++last_death_test_case_; + test_cases_.insert(test_cases_.begin() + last_death_test_case_, + new_test_case); + } else { + // No. Appends to the end of the list. + test_cases_.push_back(new_test_case); + } + + test_case_indices_.push_back(static_cast(test_case_indices_.size())); + return new_test_case; +} + +// Helpers for setting up / tearing down the given environment. They +// are for use in the ForEach() function. +static void SetUpEnvironment(Environment* env) { env->SetUp(); } +static void TearDownEnvironment(Environment* env) { env->TearDown(); } + +// Runs all tests in this UnitTest object, prints the result, and +// returns 0 if all tests are successful, or 1 otherwise. If any +// exception is thrown during a test on Windows, this test is +// considered to be failed, but the rest of the tests will still be +// run. (We disable exceptions on Linux and Mac OS X, so the issue +// doesn't apply there.) +// When parameterized tests are enabled, it expands and registers +// parameterized tests first in RegisterParameterizedTests(). +// All other functions called from RunAllTests() may safely assume that +// parameterized tests are ready to be counted and run. +int UnitTestImpl::RunAllTests() { + // Makes sure InitGoogleTest() was called. + if (!GTestIsInitialized()) { + printf("%s", + "\nThis test program did NOT call ::testing::InitGoogleTest " + "before calling RUN_ALL_TESTS(). Please fix it.\n"); + return 1; + } + + // Do not run any test if the --help flag was specified. + if (g_help_flag) + return 0; + + // Repeats the call to the post-flag parsing initialization in case the + // user didn't call InitGoogleTest. + PostFlagParsingInit(); + + // Even if sharding is not on, test runners may want to use the + // GTEST_SHARD_STATUS_FILE to query whether the test supports the sharding + // protocol. + internal::WriteToShardStatusFileIfNeeded(); + + // True iff we are in a subprocess for running a thread-safe-style + // death test. + bool in_subprocess_for_death_test = false; + +#if GTEST_HAS_DEATH_TEST + in_subprocess_for_death_test = (internal_run_death_test_flag_.get() != NULL); +#endif // GTEST_HAS_DEATH_TEST + + const bool should_shard = ShouldShard(kTestTotalShards, kTestShardIndex, + in_subprocess_for_death_test); + + // Compares the full test names with the filter to decide which + // tests to run. + const bool has_tests_to_run = FilterTests(should_shard + ? HONOR_SHARDING_PROTOCOL + : IGNORE_SHARDING_PROTOCOL) > 0; + + // Lists the tests and exits if the --gtest_list_tests flag was specified. + if (GTEST_FLAG(list_tests)) { + // This must be called *after* FilterTests() has been called. + ListTestsMatchingFilter(); + return 0; + } + + random_seed_ = GTEST_FLAG(shuffle) ? + GetRandomSeedFromFlag(GTEST_FLAG(random_seed)) : 0; + + // True iff at least one test has failed. + bool failed = false; + + TestEventListener* repeater = listeners()->repeater(); + + repeater->OnTestProgramStart(*parent_); + + // How many times to repeat the tests? We don't want to repeat them + // when we are inside the subprocess of a death test. + const int repeat = in_subprocess_for_death_test ? 1 : GTEST_FLAG(repeat); + // Repeats forever if the repeat count is negative. + const bool forever = repeat < 0; + for (int i = 0; forever || i != repeat; i++) { + ClearResult(); + + const TimeInMillis start = GetTimeInMillis(); + + // Shuffles test cases and tests if requested. + if (has_tests_to_run && GTEST_FLAG(shuffle)) { + random()->Reseed(random_seed_); + // This should be done before calling OnTestIterationStart(), + // such that a test event listener can see the actual test order + // in the event. + ShuffleTests(); + } + + // Tells the unit test event listeners that the tests are about to start. + repeater->OnTestIterationStart(*parent_, i); + + // Runs each test case if there is at least one test to run. + if (has_tests_to_run) { + // Sets up all environments beforehand. + repeater->OnEnvironmentsSetUpStart(*parent_); + ForEach(environments_, SetUpEnvironment); + repeater->OnEnvironmentsSetUpEnd(*parent_); + + // Runs the tests only if there was no fatal failure during global + // set-up. + if (!Test::HasFatalFailure()) { + for (int test_index = 0; test_index < total_test_case_count(); + test_index++) { + GetMutableTestCase(test_index)->Run(); + } + } + + // Tears down all environments in reverse order afterwards. + repeater->OnEnvironmentsTearDownStart(*parent_); + std::for_each(environments_.rbegin(), environments_.rend(), + TearDownEnvironment); + repeater->OnEnvironmentsTearDownEnd(*parent_); + } + + elapsed_time_ = GetTimeInMillis() - start; + + // Tells the unit test event listener that the tests have just finished. + repeater->OnTestIterationEnd(*parent_, i); + + // Gets the result and clears it. + if (!Passed()) { + failed = true; + } + + // Restores the original test order after the iteration. This + // allows the user to quickly repro a failure that happens in the + // N-th iteration without repeating the first (N - 1) iterations. + // This is not enclosed in "if (GTEST_FLAG(shuffle)) { ... }", in + // case the user somehow changes the value of the flag somewhere + // (it's always safe to unshuffle the tests). + UnshuffleTests(); + + if (GTEST_FLAG(shuffle)) { + // Picks a new random seed for each iteration. + random_seed_ = GetNextRandomSeed(random_seed_); + } + } + + repeater->OnTestProgramEnd(*parent_); + + // Returns 0 if all tests passed, or 1 other wise. + return failed ? 1 : 0; +} + +// Reads the GTEST_SHARD_STATUS_FILE environment variable, and creates the file +// if the variable is present. If a file already exists at this location, this +// function will write over it. If the variable is present, but the file cannot +// be created, prints an error and exits. +void WriteToShardStatusFileIfNeeded() { + const char* const test_shard_file = posix::GetEnv(kTestShardStatusFile); + if (test_shard_file != NULL) { + FILE* const file = posix::FOpen(test_shard_file, "w"); + if (file == NULL) { + ColoredPrintf(COLOR_RED, + "Could not write to the test shard status file \"%s\" " + "specified by the %s environment variable.\n", + test_shard_file, kTestShardStatusFile); + fflush(stdout); + exit(EXIT_FAILURE); + } + fclose(file); + } +} + +// Checks whether sharding is enabled by examining the relevant +// environment variable values. If the variables are present, +// but inconsistent (i.e., shard_index >= total_shards), prints +// an error and exits. If in_subprocess_for_death_test, sharding is +// disabled because it must only be applied to the original test +// process. Otherwise, we could filter out death tests we intended to execute. +bool ShouldShard(const char* total_shards_env, + const char* shard_index_env, + bool in_subprocess_for_death_test) { + if (in_subprocess_for_death_test) { + return false; + } + + const Int32 total_shards = Int32FromEnvOrDie(total_shards_env, -1); + const Int32 shard_index = Int32FromEnvOrDie(shard_index_env, -1); + + if (total_shards == -1 && shard_index == -1) { + return false; + } else if (total_shards == -1 && shard_index != -1) { + const Message msg = Message() + << "Invalid environment variables: you have " + << kTestShardIndex << " = " << shard_index + << ", but have left " << kTestTotalShards << " unset.\n"; + ColoredPrintf(COLOR_RED, msg.GetString().c_str()); + fflush(stdout); + exit(EXIT_FAILURE); + } else if (total_shards != -1 && shard_index == -1) { + const Message msg = Message() + << "Invalid environment variables: you have " + << kTestTotalShards << " = " << total_shards + << ", but have left " << kTestShardIndex << " unset.\n"; + ColoredPrintf(COLOR_RED, msg.GetString().c_str()); + fflush(stdout); + exit(EXIT_FAILURE); + } else if (shard_index < 0 || shard_index >= total_shards) { + const Message msg = Message() + << "Invalid environment variables: we require 0 <= " + << kTestShardIndex << " < " << kTestTotalShards + << ", but you have " << kTestShardIndex << "=" << shard_index + << ", " << kTestTotalShards << "=" << total_shards << ".\n"; + ColoredPrintf(COLOR_RED, msg.GetString().c_str()); + fflush(stdout); + exit(EXIT_FAILURE); + } + + return total_shards > 1; +} + +// Parses the environment variable var as an Int32. If it is unset, +// returns default_val. If it is not an Int32, prints an error +// and aborts. +Int32 Int32FromEnvOrDie(const char* const var, Int32 default_val) { + const char* str_val = posix::GetEnv(var); + if (str_val == NULL) { + return default_val; + } + + Int32 result; + if (!ParseInt32(Message() << "The value of environment variable " << var, + str_val, &result)) { + exit(EXIT_FAILURE); + } + return result; +} + +// Given the total number of shards, the shard index, and the test id, +// returns true iff the test should be run on this shard. The test id is +// some arbitrary but unique non-negative integer assigned to each test +// method. Assumes that 0 <= shard_index < total_shards. +bool ShouldRunTestOnShard(int total_shards, int shard_index, int test_id) { + return (test_id % total_shards) == shard_index; +} + +// Compares the name of each test with the user-specified filter to +// decide whether the test should be run, then records the result in +// each TestCase and TestInfo object. +// If shard_tests == true, further filters tests based on sharding +// variables in the environment - see +// http://code.google.com/p/googletest/wiki/GoogleTestAdvancedGuide. +// Returns the number of tests that should run. +int UnitTestImpl::FilterTests(ReactionToSharding shard_tests) { + const Int32 total_shards = shard_tests == HONOR_SHARDING_PROTOCOL ? + Int32FromEnvOrDie(kTestTotalShards, -1) : -1; + const Int32 shard_index = shard_tests == HONOR_SHARDING_PROTOCOL ? + Int32FromEnvOrDie(kTestShardIndex, -1) : -1; + + // num_runnable_tests are the number of tests that will + // run across all shards (i.e., match filter and are not disabled). + // num_selected_tests are the number of tests to be run on + // this shard. + int num_runnable_tests = 0; + int num_selected_tests = 0; + for (size_t i = 0; i < test_cases_.size(); i++) { + TestCase* const test_case = test_cases_[i]; + const String &test_case_name = test_case->name(); + test_case->set_should_run(false); + + for (size_t j = 0; j < test_case->test_info_list().size(); j++) { + TestInfo* const test_info = test_case->test_info_list()[j]; + const String test_name(test_info->name()); + // A test is disabled if test case name or test name matches + // kDisableTestFilter. + const bool is_disabled = + internal::UnitTestOptions::MatchesFilter(test_case_name, + kDisableTestFilter) || + internal::UnitTestOptions::MatchesFilter(test_name, + kDisableTestFilter); + test_info->impl()->set_is_disabled(is_disabled); + + const bool matches_filter = + internal::UnitTestOptions::FilterMatchesTest(test_case_name, + test_name); + test_info->impl()->set_matches_filter(matches_filter); + + const bool is_runnable = + (GTEST_FLAG(also_run_disabled_tests) || !is_disabled) && + matches_filter; + + const bool is_selected = is_runnable && + (shard_tests == IGNORE_SHARDING_PROTOCOL || + ShouldRunTestOnShard(total_shards, shard_index, + num_runnable_tests)); + + num_runnable_tests += is_runnable; + num_selected_tests += is_selected; + + test_info->impl()->set_should_run(is_selected); + test_case->set_should_run(test_case->should_run() || is_selected); + } + } + return num_selected_tests; +} + +// Prints the names of the tests matching the user-specified filter flag. +void UnitTestImpl::ListTestsMatchingFilter() { + for (size_t i = 0; i < test_cases_.size(); i++) { + const TestCase* const test_case = test_cases_[i]; + bool printed_test_case_name = false; + + for (size_t j = 0; j < test_case->test_info_list().size(); j++) { + const TestInfo* const test_info = + test_case->test_info_list()[j]; + if (test_info->matches_filter()) { + if (!printed_test_case_name) { + printed_test_case_name = true; + printf("%s.\n", test_case->name()); + } + printf(" %s\n", test_info->name()); + } + } + } + fflush(stdout); +} + +// Sets the OS stack trace getter. +// +// Does nothing if the input and the current OS stack trace getter are +// the same; otherwise, deletes the old getter and makes the input the +// current getter. +void UnitTestImpl::set_os_stack_trace_getter( + OsStackTraceGetterInterface* getter) { + if (os_stack_trace_getter_ != getter) { + delete os_stack_trace_getter_; + os_stack_trace_getter_ = getter; + } +} + +// Returns the current OS stack trace getter if it is not NULL; +// otherwise, creates an OsStackTraceGetter, makes it the current +// getter, and returns it. +OsStackTraceGetterInterface* UnitTestImpl::os_stack_trace_getter() { + if (os_stack_trace_getter_ == NULL) { + os_stack_trace_getter_ = new OsStackTraceGetter; + } + + return os_stack_trace_getter_; +} + +// Returns the TestResult for the test that's currently running, or +// the TestResult for the ad hoc test if no test is running. +TestResult* UnitTestImpl::current_test_result() { + return current_test_info_ ? + current_test_info_->impl()->result() : &ad_hoc_test_result_; +} + +// Shuffles all test cases, and the tests within each test case, +// making sure that death tests are still run first. +void UnitTestImpl::ShuffleTests() { + // Shuffles the death test cases. + ShuffleRange(random(), 0, last_death_test_case_ + 1, &test_case_indices_); + + // Shuffles the non-death test cases. + ShuffleRange(random(), last_death_test_case_ + 1, + static_cast(test_cases_.size()), &test_case_indices_); + + // Shuffles the tests inside each test case. + for (size_t i = 0; i < test_cases_.size(); i++) { + test_cases_[i]->ShuffleTests(random()); + } +} + +// Restores the test cases and tests to their order before the first shuffle. +void UnitTestImpl::UnshuffleTests() { + for (size_t i = 0; i < test_cases_.size(); i++) { + // Unshuffles the tests in each test case. + test_cases_[i]->UnshuffleTests(); + // Resets the index of each test case. + test_case_indices_[i] = static_cast(i); + } +} + +// TestInfoImpl constructor. The new instance assumes ownership of the test +// factory object. +TestInfoImpl::TestInfoImpl(TestInfo* parent, + const char* a_test_case_name, + const char* a_name, + const char* a_test_case_comment, + const char* a_comment, + TypeId a_fixture_class_id, + internal::TestFactoryBase* factory) : + parent_(parent), + test_case_name_(String(a_test_case_name)), + name_(String(a_name)), + test_case_comment_(String(a_test_case_comment)), + comment_(String(a_comment)), + fixture_class_id_(a_fixture_class_id), + should_run_(false), + is_disabled_(false), + matches_filter_(false), + factory_(factory) { +} + +// TestInfoImpl destructor. +TestInfoImpl::~TestInfoImpl() { + delete factory_; +} + +// Returns the current OS stack trace as a String. +// +// The maximum number of stack frames to be included is specified by +// the gtest_stack_trace_depth flag. The skip_count parameter +// specifies the number of top frames to be skipped, which doesn't +// count against the number of frames to be included. +// +// For example, if Foo() calls Bar(), which in turn calls +// GetCurrentOsStackTraceExceptTop(..., 1), Foo() will be included in +// the trace but Bar() and GetCurrentOsStackTraceExceptTop() won't. +String GetCurrentOsStackTraceExceptTop(UnitTest* /*unit_test*/, + int skip_count) { + // We pass skip_count + 1 to skip this wrapper function in addition + // to what the user really wants to skip. + return GetUnitTestImpl()->CurrentOsStackTraceExceptTop(skip_count + 1); +} + +// Used by the GTEST_HIDE_UNREACHABLE_CODE_ macro to suppress unreachable +// code warnings. +namespace { +class ClassUniqueToAlwaysTrue {}; +} + +bool IsTrue(bool condition) { return condition; } + +bool AlwaysTrue() { +#if GTEST_HAS_EXCEPTIONS + // This condition is always false so AlwaysTrue() never actually throws, + // but it makes the compiler think that it may throw. + if (IsTrue(false)) + throw ClassUniqueToAlwaysTrue(); +#endif // GTEST_HAS_EXCEPTIONS + return true; +} + +// If *pstr starts with the given prefix, modifies *pstr to be right +// past the prefix and returns true; otherwise leaves *pstr unchanged +// and returns false. None of pstr, *pstr, and prefix can be NULL. +bool SkipPrefix(const char* prefix, const char** pstr) { + const size_t prefix_len = strlen(prefix); + if (strncmp(*pstr, prefix, prefix_len) == 0) { + *pstr += prefix_len; + return true; + } + return false; +} + +// Parses a string as a command line flag. The string should have +// the format "--flag=value". When def_optional is true, the "=value" +// part can be omitted. +// +// Returns the value of the flag, or NULL if the parsing failed. +const char* ParseFlagValue(const char* str, + const char* flag, + bool def_optional) { + // str and flag must not be NULL. + if (str == NULL || flag == NULL) return NULL; + + // The flag must start with "--" followed by GTEST_FLAG_PREFIX_. + const String flag_str = String::Format("--%s%s", GTEST_FLAG_PREFIX_, flag); + const size_t flag_len = flag_str.length(); + if (strncmp(str, flag_str.c_str(), flag_len) != 0) return NULL; + + // Skips the flag name. + const char* flag_end = str + flag_len; + + // When def_optional is true, it's OK to not have a "=value" part. + if (def_optional && (flag_end[0] == '\0')) { + return flag_end; + } + + // If def_optional is true and there are more characters after the + // flag name, or if def_optional is false, there must be a '=' after + // the flag name. + if (flag_end[0] != '=') return NULL; + + // Returns the string after "=". + return flag_end + 1; +} + +// Parses a string for a bool flag, in the form of either +// "--flag=value" or "--flag". +// +// In the former case, the value is taken as true as long as it does +// not start with '0', 'f', or 'F'. +// +// In the latter case, the value is taken as true. +// +// On success, stores the value of the flag in *value, and returns +// true. On failure, returns false without changing *value. +bool ParseBoolFlag(const char* str, const char* flag, bool* value) { + // Gets the value of the flag as a string. + const char* const value_str = ParseFlagValue(str, flag, true); + + // Aborts if the parsing failed. + if (value_str == NULL) return false; + + // Converts the string value to a bool. + *value = !(*value_str == '0' || *value_str == 'f' || *value_str == 'F'); + return true; +} + +// Parses a string for an Int32 flag, in the form of +// "--flag=value". +// +// On success, stores the value of the flag in *value, and returns +// true. On failure, returns false without changing *value. +bool ParseInt32Flag(const char* str, const char* flag, Int32* value) { + // Gets the value of the flag as a string. + const char* const value_str = ParseFlagValue(str, flag, false); + + // Aborts if the parsing failed. + if (value_str == NULL) return false; + + // Sets *value to the value of the flag. + return ParseInt32(Message() << "The value of flag --" << flag, + value_str, value); +} + +// Parses a string for a string flag, in the form of +// "--flag=value". +// +// On success, stores the value of the flag in *value, and returns +// true. On failure, returns false without changing *value. +bool ParseStringFlag(const char* str, const char* flag, String* value) { + // Gets the value of the flag as a string. + const char* const value_str = ParseFlagValue(str, flag, false); + + // Aborts if the parsing failed. + if (value_str == NULL) return false; + + // Sets *value to the value of the flag. + *value = value_str; + return true; +} + +// Determines whether a string has a prefix that Google Test uses for its +// flags, i.e., starts with GTEST_FLAG_PREFIX_ or GTEST_FLAG_PREFIX_DASH_. +// If Google Test detects that a command line flag has its prefix but is not +// recognized, it will print its help message. Flags starting with +// GTEST_INTERNAL_PREFIX_ followed by "internal_" are considered Google Test +// internal flags and do not trigger the help message. +static bool HasGoogleTestFlagPrefix(const char* str) { + return (SkipPrefix("--", &str) || + SkipPrefix("-", &str) || + SkipPrefix("/", &str)) && + !SkipPrefix(GTEST_FLAG_PREFIX_ "internal_", &str) && + (SkipPrefix(GTEST_FLAG_PREFIX_, &str) || + SkipPrefix(GTEST_FLAG_PREFIX_DASH_, &str)); +} + +// Prints a string containing code-encoded text. The following escape +// sequences can be used in the string to control the text color: +// +// @@ prints a single '@' character. +// @R changes the color to red. +// @G changes the color to green. +// @Y changes the color to yellow. +// @D changes to the default terminal text color. +// +// TODO(wan@google.com): Write tests for this once we add stdout +// capturing to Google Test. +static void PrintColorEncoded(const char* str) { + GTestColor color = COLOR_DEFAULT; // The current color. + + // Conceptually, we split the string into segments divided by escape + // sequences. Then we print one segment at a time. At the end of + // each iteration, the str pointer advances to the beginning of the + // next segment. + for (;;) { + const char* p = strchr(str, '@'); + if (p == NULL) { + ColoredPrintf(color, "%s", str); + return; + } + + ColoredPrintf(color, "%s", String(str, p - str).c_str()); + + const char ch = p[1]; + str = p + 2; + if (ch == '@') { + ColoredPrintf(color, "@"); + } else if (ch == 'D') { + color = COLOR_DEFAULT; + } else if (ch == 'R') { + color = COLOR_RED; + } else if (ch == 'G') { + color = COLOR_GREEN; + } else if (ch == 'Y') { + color = COLOR_YELLOW; + } else { + --str; + } + } +} + +static const char kColorEncodedHelpMessage[] = +"This program contains tests written using " GTEST_NAME_ ". You can use the\n" +"following command line flags to control its behavior:\n" +"\n" +"Test Selection:\n" +" @G--" GTEST_FLAG_PREFIX_ "list_tests@D\n" +" List the names of all tests instead of running them. The name of\n" +" TEST(Foo, Bar) is \"Foo.Bar\".\n" +" @G--" GTEST_FLAG_PREFIX_ "filter=@YPOSTIVE_PATTERNS" + "[@G-@YNEGATIVE_PATTERNS]@D\n" +" Run only the tests whose name matches one of the positive patterns but\n" +" none of the negative patterns. '?' matches any single character; '*'\n" +" matches any substring; ':' separates two patterns.\n" +" @G--" GTEST_FLAG_PREFIX_ "also_run_disabled_tests@D\n" +" Run all disabled tests too.\n" +"\n" +"Test Execution:\n" +" @G--" GTEST_FLAG_PREFIX_ "repeat=@Y[COUNT]@D\n" +" Run the tests repeatedly; use a negative count to repeat forever.\n" +" @G--" GTEST_FLAG_PREFIX_ "shuffle@D\n" +" Randomize tests' orders on every iteration.\n" +" @G--" GTEST_FLAG_PREFIX_ "random_seed=@Y[NUMBER]@D\n" +" Random number seed to use for shuffling test orders (between 1 and\n" +" 99999, or 0 to use a seed based on the current time).\n" +"\n" +"Test Output:\n" +" @G--" GTEST_FLAG_PREFIX_ "color=@Y(@Gyes@Y|@Gno@Y|@Gauto@Y)@D\n" +" Enable/disable colored output. The default is @Gauto@D.\n" +" -@G-" GTEST_FLAG_PREFIX_ "print_time=0@D\n" +" Don't print the elapsed time of each test.\n" +" @G--" GTEST_FLAG_PREFIX_ "output=xml@Y[@G:@YDIRECTORY_PATH@G" + GTEST_PATH_SEP_ "@Y|@G:@YFILE_PATH]@D\n" +" Generate an XML report in the given directory or with the given file\n" +" name. @YFILE_PATH@D defaults to @Gtest_details.xml@D.\n" +"\n" +"Assertion Behavior:\n" +#if GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS +" @G--" GTEST_FLAG_PREFIX_ "death_test_style=@Y(@Gfast@Y|@Gthreadsafe@Y)@D\n" +" Set the default death test style.\n" +#endif // GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS +" @G--" GTEST_FLAG_PREFIX_ "break_on_failure@D\n" +" Turn assertion failures into debugger break-points.\n" +" @G--" GTEST_FLAG_PREFIX_ "throw_on_failure@D\n" +" Turn assertion failures into C++ exceptions.\n" +#if GTEST_OS_WINDOWS +" @G--" GTEST_FLAG_PREFIX_ "catch_exceptions@D\n" +" Suppress pop-ups caused by exceptions.\n" +#endif // GTEST_OS_WINDOWS +"\n" +"Except for @G--" GTEST_FLAG_PREFIX_ "list_tests@D, you can alternatively set " + "the corresponding\n" +"environment variable of a flag (all letters in upper-case). For example, to\n" +"disable colored text output, you can either specify @G--" GTEST_FLAG_PREFIX_ + "color=no@D or set\n" +"the @G" GTEST_FLAG_PREFIX_UPPER_ "COLOR@D environment variable to @Gno@D.\n" +"\n" +"For more information, please read the " GTEST_NAME_ " documentation at\n" +"@G" GTEST_PROJECT_URL_ "@D. If you find a bug in " GTEST_NAME_ "\n" +"(not one in your own code or tests), please report it to\n" +"@G<" GTEST_DEV_EMAIL_ ">@D.\n"; + +// Parses the command line for Google Test flags, without initializing +// other parts of Google Test. The type parameter CharType can be +// instantiated to either char or wchar_t. +template +void ParseGoogleTestFlagsOnlyImpl(int* argc, CharType** argv) { + for (int i = 1; i < *argc; i++) { + const String arg_string = StreamableToString(argv[i]); + const char* const arg = arg_string.c_str(); + + using internal::ParseBoolFlag; + using internal::ParseInt32Flag; + using internal::ParseStringFlag; + + // Do we see a Google Test flag? + if (ParseBoolFlag(arg, kAlsoRunDisabledTestsFlag, + >EST_FLAG(also_run_disabled_tests)) || + ParseBoolFlag(arg, kBreakOnFailureFlag, + >EST_FLAG(break_on_failure)) || + ParseBoolFlag(arg, kCatchExceptionsFlag, + >EST_FLAG(catch_exceptions)) || + ParseStringFlag(arg, kColorFlag, >EST_FLAG(color)) || + ParseStringFlag(arg, kDeathTestStyleFlag, + >EST_FLAG(death_test_style)) || + ParseBoolFlag(arg, kDeathTestUseFork, + >EST_FLAG(death_test_use_fork)) || + ParseStringFlag(arg, kFilterFlag, >EST_FLAG(filter)) || + ParseStringFlag(arg, kInternalRunDeathTestFlag, + >EST_FLAG(internal_run_death_test)) || + ParseBoolFlag(arg, kListTestsFlag, >EST_FLAG(list_tests)) || + ParseStringFlag(arg, kOutputFlag, >EST_FLAG(output)) || + ParseBoolFlag(arg, kPrintTimeFlag, >EST_FLAG(print_time)) || + ParseInt32Flag(arg, kRandomSeedFlag, >EST_FLAG(random_seed)) || + ParseInt32Flag(arg, kRepeatFlag, >EST_FLAG(repeat)) || + ParseBoolFlag(arg, kShuffleFlag, >EST_FLAG(shuffle)) || + ParseInt32Flag(arg, kStackTraceDepthFlag, + >EST_FLAG(stack_trace_depth)) || + ParseBoolFlag(arg, kThrowOnFailureFlag, >EST_FLAG(throw_on_failure)) + ) { + // Yes. Shift the remainder of the argv list left by one. Note + // that argv has (*argc + 1) elements, the last one always being + // NULL. The following loop moves the trailing NULL element as + // well. + for (int j = i; j != *argc; j++) { + argv[j] = argv[j + 1]; + } + + // Decrements the argument count. + (*argc)--; + + // We also need to decrement the iterator as we just removed + // an element. + i--; + } else if (arg_string == "--help" || arg_string == "-h" || + arg_string == "-?" || arg_string == "/?" || + HasGoogleTestFlagPrefix(arg)) { + // Both help flag and unrecognized Google Test flags (excluding + // internal ones) trigger help display. + g_help_flag = true; + } + } + + if (g_help_flag) { + // We print the help here instead of in RUN_ALL_TESTS(), as the + // latter may not be called at all if the user is using Google + // Test with another testing framework. + PrintColorEncoded(kColorEncodedHelpMessage); + } +} + +// Parses the command line for Google Test flags, without initializing +// other parts of Google Test. +void ParseGoogleTestFlagsOnly(int* argc, char** argv) { + ParseGoogleTestFlagsOnlyImpl(argc, argv); +} +void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv) { + ParseGoogleTestFlagsOnlyImpl(argc, argv); +} + +// The internal implementation of InitGoogleTest(). +// +// The type parameter CharType can be instantiated to either char or +// wchar_t. +template +void InitGoogleTestImpl(int* argc, CharType** argv) { + g_init_gtest_count++; + + // We don't want to run the initialization code twice. + if (g_init_gtest_count != 1) return; + + if (*argc <= 0) return; + + internal::g_executable_path = internal::StreamableToString(argv[0]); + +#if GTEST_HAS_DEATH_TEST + g_argvs.clear(); + for (int i = 0; i != *argc; i++) { + g_argvs.push_back(StreamableToString(argv[i])); + } +#endif // GTEST_HAS_DEATH_TEST + + ParseGoogleTestFlagsOnly(argc, argv); + GetUnitTestImpl()->PostFlagParsingInit(); +} + +} // namespace internal + +// Initializes Google Test. This must be called before calling +// RUN_ALL_TESTS(). In particular, it parses a command line for the +// flags that Google Test recognizes. Whenever a Google Test flag is +// seen, it is removed from argv, and *argc is decremented. +// +// No value is returned. Instead, the Google Test flag variables are +// updated. +// +// Calling the function for the second time has no user-visible effect. +void InitGoogleTest(int* argc, char** argv) { + internal::InitGoogleTestImpl(argc, argv); +} + +// This overloaded version can be used in Windows programs compiled in +// UNICODE mode. +void InitGoogleTest(int* argc, wchar_t** argv) { + internal::InitGoogleTestImpl(argc, argv); +} + +} // namespace testing +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: wan@google.com (Zhanyong Wan), vladl@google.com (Vlad Losev) +// +// This file implements death tests. + + +#if GTEST_HAS_DEATH_TEST + +#if GTEST_OS_MAC +#include +#endif // GTEST_OS_MAC + +#include +#include +#include +#include + +#if GTEST_OS_WINDOWS +#include +#else +#include +#include +#endif // GTEST_OS_WINDOWS + +#endif // GTEST_HAS_DEATH_TEST + + +// Indicates that this translation unit is part of Google Test's +// implementation. It must come before gtest-internal-inl.h is +// included, or there will be a compiler error. This trick is to +// prevent a user from accidentally including gtest-internal-inl.h in +// his code. +#define GTEST_IMPLEMENTATION_ 1 +#undef GTEST_IMPLEMENTATION_ + +namespace testing { + +// Constants. + +// The default death test style. +static const char kDefaultDeathTestStyle[] = "fast"; + +GTEST_DEFINE_string_( + death_test_style, + internal::StringFromGTestEnv("death_test_style", kDefaultDeathTestStyle), + "Indicates how to run a death test in a forked child process: " + "\"threadsafe\" (child process re-executes the test binary " + "from the beginning, running only the specific death test) or " + "\"fast\" (child process runs the death test immediately " + "after forking)."); + +GTEST_DEFINE_bool_( + death_test_use_fork, + internal::BoolFromGTestEnv("death_test_use_fork", false), + "Instructs to use fork()/_exit() instead of clone() in death tests. " + "Ignored and always uses fork() on POSIX systems where clone() is not " + "implemented. Useful when running under valgrind or similar tools if " + "those do not support clone(). Valgrind 3.3.1 will just fail if " + "it sees an unsupported combination of clone() flags. " + "It is not recommended to use this flag w/o valgrind though it will " + "work in 99% of the cases. Once valgrind is fixed, this flag will " + "most likely be removed."); + +namespace internal { +GTEST_DEFINE_string_( + internal_run_death_test, "", + "Indicates the file, line number, temporal index of " + "the single death test to run, and a file descriptor to " + "which a success code may be sent, all separated by " + "colons. This flag is specified if and only if the current " + "process is a sub-process launched for running a thread-safe " + "death test. FOR INTERNAL USE ONLY."); +} // namespace internal + +#if GTEST_HAS_DEATH_TEST + +// ExitedWithCode constructor. +ExitedWithCode::ExitedWithCode(int exit_code) : exit_code_(exit_code) { +} + +// ExitedWithCode function-call operator. +bool ExitedWithCode::operator()(int exit_status) const { +#if GTEST_OS_WINDOWS + return exit_status == exit_code_; +#else + return WIFEXITED(exit_status) && WEXITSTATUS(exit_status) == exit_code_; +#endif // GTEST_OS_WINDOWS +} + +#if !GTEST_OS_WINDOWS +// KilledBySignal constructor. +KilledBySignal::KilledBySignal(int signum) : signum_(signum) { +} + +// KilledBySignal function-call operator. +bool KilledBySignal::operator()(int exit_status) const { + return WIFSIGNALED(exit_status) && WTERMSIG(exit_status) == signum_; +} +#endif // !GTEST_OS_WINDOWS + +namespace internal { + +// Utilities needed for death tests. + +// Generates a textual description of a given exit code, in the format +// specified by wait(2). +static String ExitSummary(int exit_code) { + Message m; +#if GTEST_OS_WINDOWS + m << "Exited with exit status " << exit_code; +#else + if (WIFEXITED(exit_code)) { + m << "Exited with exit status " << WEXITSTATUS(exit_code); + } else if (WIFSIGNALED(exit_code)) { + m << "Terminated by signal " << WTERMSIG(exit_code); + } +#ifdef WCOREDUMP + if (WCOREDUMP(exit_code)) { + m << " (core dumped)"; + } +#endif +#endif // GTEST_OS_WINDOWS + return m.GetString(); +} + +// Returns true if exit_status describes a process that was terminated +// by a signal, or exited normally with a nonzero exit code. +bool ExitedUnsuccessfully(int exit_status) { + return !ExitedWithCode(0)(exit_status); +} + +#if !GTEST_OS_WINDOWS +// Generates a textual failure message when a death test finds more than +// one thread running, or cannot determine the number of threads, prior +// to executing the given statement. It is the responsibility of the +// caller not to pass a thread_count of 1. +static String DeathTestThreadWarning(size_t thread_count) { + Message msg; + msg << "Death tests use fork(), which is unsafe particularly" + << " in a threaded context. For this test, " << GTEST_NAME_ << " "; + if (thread_count == 0) + msg << "couldn't detect the number of threads."; + else + msg << "detected " << thread_count << " threads."; + return msg.GetString(); +} +#endif // !GTEST_OS_WINDOWS + +// Flag characters for reporting a death test that did not die. +static const char kDeathTestLived = 'L'; +static const char kDeathTestReturned = 'R'; +static const char kDeathTestInternalError = 'I'; + +// An enumeration describing all of the possible ways that a death test +// can conclude. DIED means that the process died while executing the +// test code; LIVED means that process lived beyond the end of the test +// code; and RETURNED means that the test statement attempted a "return," +// which is not allowed. IN_PROGRESS means the test has not yet +// concluded. +enum DeathTestOutcome { IN_PROGRESS, DIED, LIVED, RETURNED }; + +// Routine for aborting the program which is safe to call from an +// exec-style death test child process, in which case the error +// message is propagated back to the parent process. Otherwise, the +// message is simply printed to stderr. In either case, the program +// then exits with status 1. +void DeathTestAbort(const String& message) { + // On a POSIX system, this function may be called from a threadsafe-style + // death test child process, which operates on a very small stack. Use + // the heap for any additional non-minuscule memory requirements. + const InternalRunDeathTestFlag* const flag = + GetUnitTestImpl()->internal_run_death_test_flag(); + if (flag != NULL) { + FILE* parent = posix::FDOpen(flag->write_fd(), "w"); + fputc(kDeathTestInternalError, parent); + fprintf(parent, "%s", message.c_str()); + fflush(parent); + _exit(1); + } else { + fprintf(stderr, "%s", message.c_str()); + fflush(stderr); + abort(); + } +} + +// A replacement for CHECK that calls DeathTestAbort if the assertion +// fails. +#define GTEST_DEATH_TEST_CHECK_(expression) \ + do { \ + if (!::testing::internal::IsTrue(expression)) { \ + DeathTestAbort(::testing::internal::String::Format( \ + "CHECK failed: File %s, line %d: %s", \ + __FILE__, __LINE__, #expression)); \ + } \ + } while (::testing::internal::AlwaysFalse()) + +// This macro is similar to GTEST_DEATH_TEST_CHECK_, but it is meant for +// evaluating any system call that fulfills two conditions: it must return +// -1 on failure, and set errno to EINTR when it is interrupted and +// should be tried again. The macro expands to a loop that repeatedly +// evaluates the expression as long as it evaluates to -1 and sets +// errno to EINTR. If the expression evaluates to -1 but errno is +// something other than EINTR, DeathTestAbort is called. +#define GTEST_DEATH_TEST_CHECK_SYSCALL_(expression) \ + do { \ + int gtest_retval; \ + do { \ + gtest_retval = (expression); \ + } while (gtest_retval == -1 && errno == EINTR); \ + if (gtest_retval == -1) { \ + DeathTestAbort(::testing::internal::String::Format( \ + "CHECK failed: File %s, line %d: %s != -1", \ + __FILE__, __LINE__, #expression)); \ + } \ + } while (::testing::internal::AlwaysFalse()) + +// Returns the message describing the last system error in errno. +String GetLastErrnoDescription() { + return String(errno == 0 ? "" : posix::StrError(errno)); +} + +// This is called from a death test parent process to read a failure +// message from the death test child process and log it with the FATAL +// severity. On Windows, the message is read from a pipe handle. On other +// platforms, it is read from a file descriptor. +static void FailFromInternalError(int fd) { + Message error; + char buffer[256]; + int num_read; + + do { + while ((num_read = posix::Read(fd, buffer, 255)) > 0) { + buffer[num_read] = '\0'; + error << buffer; + } + } while (num_read == -1 && errno == EINTR); + + if (num_read == 0) { + GTEST_LOG_(FATAL) << error.GetString(); + } else { + const int last_error = errno; + GTEST_LOG_(FATAL) << "Error while reading death test internal: " + << GetLastErrnoDescription() << " [" << last_error << "]"; + } +} + +// Death test constructor. Increments the running death test count +// for the current test. +DeathTest::DeathTest() { + TestInfo* const info = GetUnitTestImpl()->current_test_info(); + if (info == NULL) { + DeathTestAbort("Cannot run a death test outside of a TEST or " + "TEST_F construct"); + } +} + +// Creates and returns a death test by dispatching to the current +// death test factory. +bool DeathTest::Create(const char* statement, const RE* regex, + const char* file, int line, DeathTest** test) { + return GetUnitTestImpl()->death_test_factory()->Create( + statement, regex, file, line, test); +} + +const char* DeathTest::LastMessage() { + return last_death_test_message_.c_str(); +} + +void DeathTest::set_last_death_test_message(const String& message) { + last_death_test_message_ = message; +} + +String DeathTest::last_death_test_message_; + +// Provides cross platform implementation for some death functionality. +class DeathTestImpl : public DeathTest { + protected: + DeathTestImpl(const char* a_statement, const RE* a_regex) + : statement_(a_statement), + regex_(a_regex), + spawned_(false), + status_(-1), + outcome_(IN_PROGRESS), + read_fd_(-1), + write_fd_(-1) {} + + // read_fd_ is expected to be closed and cleared by a derived class. + ~DeathTestImpl() { GTEST_DEATH_TEST_CHECK_(read_fd_ == -1); } + + void Abort(AbortReason reason); + virtual bool Passed(bool status_ok); + + const char* statement() const { return statement_; } + const RE* regex() const { return regex_; } + bool spawned() const { return spawned_; } + void set_spawned(bool is_spawned) { spawned_ = is_spawned; } + int status() const { return status_; } + void set_status(int a_status) { status_ = a_status; } + DeathTestOutcome outcome() const { return outcome_; } + void set_outcome(DeathTestOutcome an_outcome) { outcome_ = an_outcome; } + int read_fd() const { return read_fd_; } + void set_read_fd(int fd) { read_fd_ = fd; } + int write_fd() const { return write_fd_; } + void set_write_fd(int fd) { write_fd_ = fd; } + + // Called in the parent process only. Reads the result code of the death + // test child process via a pipe, interprets it to set the outcome_ + // member, and closes read_fd_. Outputs diagnostics and terminates in + // case of unexpected codes. + void ReadAndInterpretStatusByte(); + + private: + // The textual content of the code this object is testing. This class + // doesn't own this string and should not attempt to delete it. + const char* const statement_; + // The regular expression which test output must match. DeathTestImpl + // doesn't own this object and should not attempt to delete it. + const RE* const regex_; + // True if the death test child process has been successfully spawned. + bool spawned_; + // The exit status of the child process. + int status_; + // How the death test concluded. + DeathTestOutcome outcome_; + // Descriptor to the read end of the pipe to the child process. It is + // always -1 in the child process. The child keeps its write end of the + // pipe in write_fd_. + int read_fd_; + // Descriptor to the child's write end of the pipe to the parent process. + // It is always -1 in the parent process. The parent keeps its end of the + // pipe in read_fd_. + int write_fd_; +}; + +// Called in the parent process only. Reads the result code of the death +// test child process via a pipe, interprets it to set the outcome_ +// member, and closes read_fd_. Outputs diagnostics and terminates in +// case of unexpected codes. +void DeathTestImpl::ReadAndInterpretStatusByte() { + char flag; + int bytes_read; + + // The read() here blocks until data is available (signifying the + // failure of the death test) or until the pipe is closed (signifying + // its success), so it's okay to call this in the parent before + // the child process has exited. + do { + bytes_read = posix::Read(read_fd(), &flag, 1); + } while (bytes_read == -1 && errno == EINTR); + + if (bytes_read == 0) { + set_outcome(DIED); + } else if (bytes_read == 1) { + switch (flag) { + case kDeathTestReturned: + set_outcome(RETURNED); + break; + case kDeathTestLived: + set_outcome(LIVED); + break; + case kDeathTestInternalError: + FailFromInternalError(read_fd()); // Does not return. + break; + default: + GTEST_LOG_(FATAL) << "Death test child process reported " + << "unexpected status byte (" + << static_cast(flag) << ")"; + } + } else { + GTEST_LOG_(FATAL) << "Read from death test child process failed: " + << GetLastErrnoDescription(); + } + GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Close(read_fd())); + set_read_fd(-1); +} + +// Signals that the death test code which should have exited, didn't. +// Should be called only in a death test child process. +// Writes a status byte to the child's status file descriptor, then +// calls _exit(1). +void DeathTestImpl::Abort(AbortReason reason) { + // The parent process considers the death test to be a failure if + // it finds any data in our pipe. So, here we write a single flag byte + // to the pipe, then exit. + const char status_ch = + reason == TEST_DID_NOT_DIE ? kDeathTestLived : kDeathTestReturned; + GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Write(write_fd(), &status_ch, 1)); + GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Close(write_fd())); + _exit(1); // Exits w/o any normal exit hooks (we were supposed to crash) +} + +// Assesses the success or failure of a death test, using both private +// members which have previously been set, and one argument: +// +// Private data members: +// outcome: An enumeration describing how the death test +// concluded: DIED, LIVED, or RETURNED. The death test fails +// in the latter two cases. +// status: The exit status of the child process. On *nix, it is in the +// in the format specified by wait(2). On Windows, this is the +// value supplied to the ExitProcess() API or a numeric code +// of the exception that terminated the program. +// regex: A regular expression object to be applied to +// the test's captured standard error output; the death test +// fails if it does not match. +// +// Argument: +// status_ok: true if exit_status is acceptable in the context of +// this particular death test, which fails if it is false +// +// Returns true iff all of the above conditions are met. Otherwise, the +// first failing condition, in the order given above, is the one that is +// reported. Also sets the last death test message string. +bool DeathTestImpl::Passed(bool status_ok) { + if (!spawned()) + return false; + + const String error_message = GetCapturedStderr(); + + bool success = false; + Message buffer; + + buffer << "Death test: " << statement() << "\n"; + switch (outcome()) { + case LIVED: + buffer << " Result: failed to die.\n" + << " Error msg: " << error_message; + break; + case RETURNED: + buffer << " Result: illegal return in test statement.\n" + << " Error msg: " << error_message; + break; + case DIED: + if (status_ok) { + const bool matched = RE::PartialMatch(error_message.c_str(), *regex()); + if (matched) { + success = true; + } else { + buffer << " Result: died but not with expected error.\n" + << " Expected: " << regex()->pattern() << "\n" + << "Actual msg: " << error_message; + } + } else { + buffer << " Result: died but not with expected exit code:\n" + << " " << ExitSummary(status()) << "\n"; + } + break; + case IN_PROGRESS: + default: + GTEST_LOG_(FATAL) + << "DeathTest::Passed somehow called before conclusion of test"; + } + + DeathTest::set_last_death_test_message(buffer.GetString()); + return success; +} + +#if GTEST_OS_WINDOWS +// WindowsDeathTest implements death tests on Windows. Due to the +// specifics of starting new processes on Windows, death tests there are +// always threadsafe, and Google Test considers the +// --gtest_death_test_style=fast setting to be equivalent to +// --gtest_death_test_style=threadsafe there. +// +// A few implementation notes: Like the Linux version, the Windows +// implementation uses pipes for child-to-parent communication. But due to +// the specifics of pipes on Windows, some extra steps are required: +// +// 1. The parent creates a communication pipe and stores handles to both +// ends of it. +// 2. The parent starts the child and provides it with the information +// necessary to acquire the handle to the write end of the pipe. +// 3. The child acquires the write end of the pipe and signals the parent +// using a Windows event. +// 4. Now the parent can release the write end of the pipe on its side. If +// this is done before step 3, the object's reference count goes down to +// 0 and it is destroyed, preventing the child from acquiring it. The +// parent now has to release it, or read operations on the read end of +// the pipe will not return when the child terminates. +// 5. The parent reads child's output through the pipe (outcome code and +// any possible error messages) from the pipe, and its stderr and then +// determines whether to fail the test. +// +// Note: to distinguish Win32 API calls from the local method and function +// calls, the former are explicitly resolved in the global namespace. +// +class WindowsDeathTest : public DeathTestImpl { + public: + WindowsDeathTest(const char* statement, + const RE* regex, + const char* file, + int line) + : DeathTestImpl(statement, regex), file_(file), line_(line) {} + + // All of these virtual functions are inherited from DeathTest. + virtual int Wait(); + virtual TestRole AssumeRole(); + + private: + // The name of the file in which the death test is located. + const char* const file_; + // The line number on which the death test is located. + const int line_; + // Handle to the write end of the pipe to the child process. + AutoHandle write_handle_; + // Child process handle. + AutoHandle child_handle_; + // Event the child process uses to signal the parent that it has + // acquired the handle to the write end of the pipe. After seeing this + // event the parent can release its own handles to make sure its + // ReadFile() calls return when the child terminates. + AutoHandle event_handle_; +}; + +// Waits for the child in a death test to exit, returning its exit +// status, or 0 if no child process exists. As a side effect, sets the +// outcome data member. +int WindowsDeathTest::Wait() { + if (!spawned()) + return 0; + + // Wait until the child either signals that it has acquired the write end + // of the pipe or it dies. + const HANDLE wait_handles[2] = { child_handle_.Get(), event_handle_.Get() }; + switch (::WaitForMultipleObjects(2, + wait_handles, + FALSE, // Waits for any of the handles. + INFINITE)) { + case WAIT_OBJECT_0: + case WAIT_OBJECT_0 + 1: + break; + default: + GTEST_DEATH_TEST_CHECK_(false); // Should not get here. + } + + // The child has acquired the write end of the pipe or exited. + // We release the handle on our side and continue. + write_handle_.Reset(); + event_handle_.Reset(); + + ReadAndInterpretStatusByte(); + + // Waits for the child process to exit if it haven't already. This + // returns immediately if the child has already exited, regardless of + // whether previous calls to WaitForMultipleObjects synchronized on this + // handle or not. + GTEST_DEATH_TEST_CHECK_( + WAIT_OBJECT_0 == ::WaitForSingleObject(child_handle_.Get(), + INFINITE)); + DWORD status; + GTEST_DEATH_TEST_CHECK_(::GetExitCodeProcess(child_handle_.Get(), &status) + != FALSE); + child_handle_.Reset(); + set_status(static_cast(status)); + return this->status(); +} + +// The AssumeRole process for a Windows death test. It creates a child +// process with the same executable as the current process to run the +// death test. The child process is given the --gtest_filter and +// --gtest_internal_run_death_test flags such that it knows to run the +// current death test only. +DeathTest::TestRole WindowsDeathTest::AssumeRole() { + const UnitTestImpl* const impl = GetUnitTestImpl(); + const InternalRunDeathTestFlag* const flag = + impl->internal_run_death_test_flag(); + const TestInfo* const info = impl->current_test_info(); + const int death_test_index = info->result()->death_test_count(); + + if (flag != NULL) { + // ParseInternalRunDeathTestFlag() has performed all the necessary + // processing. + set_write_fd(flag->write_fd()); + return EXECUTE_TEST; + } + + // WindowsDeathTest uses an anonymous pipe to communicate results of + // a death test. + SECURITY_ATTRIBUTES handles_are_inheritable = { + sizeof(SECURITY_ATTRIBUTES), NULL, TRUE }; + HANDLE read_handle, write_handle; + GTEST_DEATH_TEST_CHECK_( + ::CreatePipe(&read_handle, &write_handle, &handles_are_inheritable, + 0) // Default buffer size. + != FALSE); + set_read_fd(::_open_osfhandle(reinterpret_cast(read_handle), + O_RDONLY)); + write_handle_.Reset(write_handle); + event_handle_.Reset(::CreateEvent( + &handles_are_inheritable, + TRUE, // The event will automatically reset to non-signaled state. + FALSE, // The initial state is non-signalled. + NULL)); // The even is unnamed. + GTEST_DEATH_TEST_CHECK_(event_handle_.Get() != NULL); + const String filter_flag = String::Format("--%s%s=%s.%s", + GTEST_FLAG_PREFIX_, kFilterFlag, + info->test_case_name(), + info->name()); + const String internal_flag = String::Format( + "--%s%s=%s|%d|%d|%u|%Iu|%Iu", + GTEST_FLAG_PREFIX_, + kInternalRunDeathTestFlag, + file_, line_, + death_test_index, + static_cast(::GetCurrentProcessId()), + // size_t has the same with as pointers on both 32-bit and 64-bit + // Windows platforms. + // See http://msdn.microsoft.com/en-us/library/tcxf1dw6.aspx. + reinterpret_cast(write_handle), + reinterpret_cast(event_handle_.Get())); + + char executable_path[_MAX_PATH + 1]; // NOLINT + GTEST_DEATH_TEST_CHECK_( + _MAX_PATH + 1 != ::GetModuleFileNameA(NULL, + executable_path, + _MAX_PATH)); + + String command_line = String::Format("%s %s \"%s\"", + ::GetCommandLineA(), + filter_flag.c_str(), + internal_flag.c_str()); + + DeathTest::set_last_death_test_message(""); + + CaptureStderr(); + // Flush the log buffers since the log streams are shared with the child. + FlushInfoLog(); + + // The child process will share the standard handles with the parent. + STARTUPINFOA startup_info; + memset(&startup_info, 0, sizeof(STARTUPINFO)); + startup_info.dwFlags = STARTF_USESTDHANDLES; + startup_info.hStdInput = ::GetStdHandle(STD_INPUT_HANDLE); + startup_info.hStdOutput = ::GetStdHandle(STD_OUTPUT_HANDLE); + startup_info.hStdError = ::GetStdHandle(STD_ERROR_HANDLE); + + PROCESS_INFORMATION process_info; + GTEST_DEATH_TEST_CHECK_(::CreateProcessA( + executable_path, + const_cast(command_line.c_str()), + NULL, // Retuned process handle is not inheritable. + NULL, // Retuned thread handle is not inheritable. + TRUE, // Child inherits all inheritable handles (for write_handle_). + 0x0, // Default creation flags. + NULL, // Inherit the parent's environment. + UnitTest::GetInstance()->original_working_dir(), + &startup_info, + &process_info) != FALSE); + child_handle_.Reset(process_info.hProcess); + ::CloseHandle(process_info.hThread); + set_spawned(true); + return OVERSEE_TEST; +} +#else // We are not on Windows. + +// ForkingDeathTest provides implementations for most of the abstract +// methods of the DeathTest interface. Only the AssumeRole method is +// left undefined. +class ForkingDeathTest : public DeathTestImpl { + public: + ForkingDeathTest(const char* statement, const RE* regex); + + // All of these virtual functions are inherited from DeathTest. + virtual int Wait(); + + protected: + void set_child_pid(pid_t child_pid) { child_pid_ = child_pid; } + + private: + // PID of child process during death test; 0 in the child process itself. + pid_t child_pid_; +}; + +// Constructs a ForkingDeathTest. +ForkingDeathTest::ForkingDeathTest(const char* a_statement, const RE* a_regex) + : DeathTestImpl(a_statement, a_regex), + child_pid_(-1) {} + +// Waits for the child in a death test to exit, returning its exit +// status, or 0 if no child process exists. As a side effect, sets the +// outcome data member. +int ForkingDeathTest::Wait() { + if (!spawned()) + return 0; + + ReadAndInterpretStatusByte(); + + int status_value; + GTEST_DEATH_TEST_CHECK_SYSCALL_(waitpid(child_pid_, &status_value, 0)); + set_status(status_value); + return status_value; +} + +// A concrete death test class that forks, then immediately runs the test +// in the child process. +class NoExecDeathTest : public ForkingDeathTest { + public: + NoExecDeathTest(const char* a_statement, const RE* a_regex) : + ForkingDeathTest(a_statement, a_regex) { } + virtual TestRole AssumeRole(); +}; + +// The AssumeRole process for a fork-and-run death test. It implements a +// straightforward fork, with a simple pipe to transmit the status byte. +DeathTest::TestRole NoExecDeathTest::AssumeRole() { + const size_t thread_count = GetThreadCount(); + if (thread_count != 1) { + GTEST_LOG_(WARNING) << DeathTestThreadWarning(thread_count); + } + + int pipe_fd[2]; + GTEST_DEATH_TEST_CHECK_(pipe(pipe_fd) != -1); + + DeathTest::set_last_death_test_message(""); + CaptureStderr(); + // When we fork the process below, the log file buffers are copied, but the + // file descriptors are shared. We flush all log files here so that closing + // the file descriptors in the child process doesn't throw off the + // synchronization between descriptors and buffers in the parent process. + // This is as close to the fork as possible to avoid a race condition in case + // there are multiple threads running before the death test, and another + // thread writes to the log file. + FlushInfoLog(); + + const pid_t child_pid = fork(); + GTEST_DEATH_TEST_CHECK_(child_pid != -1); + set_child_pid(child_pid); + if (child_pid == 0) { + GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[0])); + set_write_fd(pipe_fd[1]); + // Redirects all logging to stderr in the child process to prevent + // concurrent writes to the log files. We capture stderr in the parent + // process and append the child process' output to a log. + LogToStderr(); + // Event forwarding to the listeners of event listener API mush be shut + // down in death test subprocesses. + GetUnitTestImpl()->listeners()->SuppressEventForwarding(); + return EXECUTE_TEST; + } else { + GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1])); + set_read_fd(pipe_fd[0]); + set_spawned(true); + return OVERSEE_TEST; + } +} + +// A concrete death test class that forks and re-executes the main +// program from the beginning, with command-line flags set that cause +// only this specific death test to be run. +class ExecDeathTest : public ForkingDeathTest { + public: + ExecDeathTest(const char* a_statement, const RE* a_regex, + const char* file, int line) : + ForkingDeathTest(a_statement, a_regex), file_(file), line_(line) { } + virtual TestRole AssumeRole(); + private: + // The name of the file in which the death test is located. + const char* const file_; + // The line number on which the death test is located. + const int line_; +}; + +// Utility class for accumulating command-line arguments. +class Arguments { + public: + Arguments() { + args_.push_back(NULL); + } + + ~Arguments() { + for (std::vector::iterator i = args_.begin(); i != args_.end(); + ++i) { + free(*i); + } + } + void AddArgument(const char* argument) { + args_.insert(args_.end() - 1, posix::StrDup(argument)); + } + + template + void AddArguments(const ::std::vector& arguments) { + for (typename ::std::vector::const_iterator i = arguments.begin(); + i != arguments.end(); + ++i) { + args_.insert(args_.end() - 1, posix::StrDup(i->c_str())); + } + } + char* const* Argv() { + return &args_[0]; + } + private: + std::vector args_; +}; + +// A struct that encompasses the arguments to the child process of a +// threadsafe-style death test process. +struct ExecDeathTestArgs { + char* const* argv; // Command-line arguments for the child's call to exec + int close_fd; // File descriptor to close; the read end of a pipe +}; + +#if GTEST_OS_MAC +inline char** GetEnviron() { + // When Google Test is built as a framework on MacOS X, the environ variable + // is unavailable. Apple's documentation (man environ) recommends using + // _NSGetEnviron() instead. + return *_NSGetEnviron(); +} +#else +// Some POSIX platforms expect you to declare environ. extern "C" makes +// it reside in the global namespace. +extern "C" char** environ; +inline char** GetEnviron() { return environ; } +#endif // GTEST_OS_MAC + +// The main function for a threadsafe-style death test child process. +// This function is called in a clone()-ed process and thus must avoid +// any potentially unsafe operations like malloc or libc functions. +static int ExecDeathTestChildMain(void* child_arg) { + ExecDeathTestArgs* const args = static_cast(child_arg); + GTEST_DEATH_TEST_CHECK_SYSCALL_(close(args->close_fd)); + + // We need to execute the test program in the same environment where + // it was originally invoked. Therefore we change to the original + // working directory first. + const char* const original_dir = + UnitTest::GetInstance()->original_working_dir(); + // We can safely call chdir() as it's a direct system call. + if (chdir(original_dir) != 0) { + DeathTestAbort(String::Format("chdir(\"%s\") failed: %s", + original_dir, + GetLastErrnoDescription().c_str())); + return EXIT_FAILURE; + } + + // We can safely call execve() as it's a direct system call. We + // cannot use execvp() as it's a libc function and thus potentially + // unsafe. Since execve() doesn't search the PATH, the user must + // invoke the test program via a valid path that contains at least + // one path separator. + execve(args->argv[0], args->argv, GetEnviron()); + DeathTestAbort(String::Format("execve(%s, ...) in %s failed: %s", + args->argv[0], + original_dir, + GetLastErrnoDescription().c_str())); + return EXIT_FAILURE; +} + +// Two utility routines that together determine the direction the stack +// grows. +// This could be accomplished more elegantly by a single recursive +// function, but we want to guard against the unlikely possibility of +// a smart compiler optimizing the recursion away. +bool StackLowerThanAddress(const void* ptr) { + int dummy; + return &dummy < ptr; +} + +bool StackGrowsDown() { + int dummy; + return StackLowerThanAddress(&dummy); +} + +// A threadsafe implementation of fork(2) for threadsafe-style death tests +// that uses clone(2). It dies with an error message if anything goes +// wrong. +static pid_t ExecDeathTestFork(char* const* argv, int close_fd) { + ExecDeathTestArgs args = { argv, close_fd }; + pid_t child_pid = -1; + +#if GTEST_HAS_CLONE + const bool use_fork = GTEST_FLAG(death_test_use_fork); + + if (!use_fork) { + static const bool stack_grows_down = StackGrowsDown(); + const size_t stack_size = getpagesize(); + // MMAP_ANONYMOUS is not defined on Mac, so we use MAP_ANON instead. + void* const stack = mmap(NULL, stack_size, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_PRIVATE, -1, 0); + GTEST_DEATH_TEST_CHECK_(stack != MAP_FAILED); + void* const stack_top = + static_cast(stack) + (stack_grows_down ? stack_size : 0); + + child_pid = clone(&ExecDeathTestChildMain, stack_top, SIGCHLD, &args); + + GTEST_DEATH_TEST_CHECK_(munmap(stack, stack_size) != -1); + } +#else + const bool use_fork = true; +#endif // GTEST_HAS_CLONE + + if (use_fork && (child_pid = fork()) == 0) { + ExecDeathTestChildMain(&args); + _exit(0); + } + + GTEST_DEATH_TEST_CHECK_(child_pid != -1); + return child_pid; +} + +// The AssumeRole process for a fork-and-exec death test. It re-executes the +// main program from the beginning, setting the --gtest_filter +// and --gtest_internal_run_death_test flags to cause only the current +// death test to be re-run. +DeathTest::TestRole ExecDeathTest::AssumeRole() { + const UnitTestImpl* const impl = GetUnitTestImpl(); + const InternalRunDeathTestFlag* const flag = + impl->internal_run_death_test_flag(); + const TestInfo* const info = impl->current_test_info(); + const int death_test_index = info->result()->death_test_count(); + + if (flag != NULL) { + set_write_fd(flag->write_fd()); + return EXECUTE_TEST; + } + + int pipe_fd[2]; + GTEST_DEATH_TEST_CHECK_(pipe(pipe_fd) != -1); + // Clear the close-on-exec flag on the write end of the pipe, lest + // it be closed when the child process does an exec: + GTEST_DEATH_TEST_CHECK_(fcntl(pipe_fd[1], F_SETFD, 0) != -1); + + const String filter_flag = + String::Format("--%s%s=%s.%s", + GTEST_FLAG_PREFIX_, kFilterFlag, + info->test_case_name(), info->name()); + const String internal_flag = + String::Format("--%s%s=%s|%d|%d|%d", + GTEST_FLAG_PREFIX_, kInternalRunDeathTestFlag, + file_, line_, death_test_index, pipe_fd[1]); + Arguments args; + args.AddArguments(GetArgvs()); + args.AddArgument(filter_flag.c_str()); + args.AddArgument(internal_flag.c_str()); + + DeathTest::set_last_death_test_message(""); + + CaptureStderr(); + // See the comment in NoExecDeathTest::AssumeRole for why the next line + // is necessary. + FlushInfoLog(); + + const pid_t child_pid = ExecDeathTestFork(args.Argv(), pipe_fd[0]); + GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1])); + set_child_pid(child_pid); + set_read_fd(pipe_fd[0]); + set_spawned(true); + return OVERSEE_TEST; +} + +#endif // !GTEST_OS_WINDOWS + +// Creates a concrete DeathTest-derived class that depends on the +// --gtest_death_test_style flag, and sets the pointer pointed to +// by the "test" argument to its address. If the test should be +// skipped, sets that pointer to NULL. Returns true, unless the +// flag is set to an invalid value. +bool DefaultDeathTestFactory::Create(const char* statement, const RE* regex, + const char* file, int line, + DeathTest** test) { + UnitTestImpl* const impl = GetUnitTestImpl(); + const InternalRunDeathTestFlag* const flag = + impl->internal_run_death_test_flag(); + const int death_test_index = impl->current_test_info() + ->increment_death_test_count(); + + if (flag != NULL) { + if (death_test_index > flag->index()) { + DeathTest::set_last_death_test_message(String::Format( + "Death test count (%d) somehow exceeded expected maximum (%d)", + death_test_index, flag->index())); + return false; + } + + if (!(flag->file() == file && flag->line() == line && + flag->index() == death_test_index)) { + *test = NULL; + return true; + } + } + +#if GTEST_OS_WINDOWS + if (GTEST_FLAG(death_test_style) == "threadsafe" || + GTEST_FLAG(death_test_style) == "fast") { + *test = new WindowsDeathTest(statement, regex, file, line); + } +#else + if (GTEST_FLAG(death_test_style) == "threadsafe") { + *test = new ExecDeathTest(statement, regex, file, line); + } else if (GTEST_FLAG(death_test_style) == "fast") { + *test = new NoExecDeathTest(statement, regex); + } +#endif // GTEST_OS_WINDOWS + else { // NOLINT - this is more readable than unbalanced brackets inside #if. + DeathTest::set_last_death_test_message(String::Format( + "Unknown death test style \"%s\" encountered", + GTEST_FLAG(death_test_style).c_str())); + return false; + } + + return true; +} + +// Splits a given string on a given delimiter, populating a given +// vector with the fields. GTEST_HAS_DEATH_TEST implies that we have +// ::std::string, so we can use it here. +static void SplitString(const ::std::string& str, char delimiter, + ::std::vector< ::std::string>* dest) { + ::std::vector< ::std::string> parsed; + ::std::string::size_type pos = 0; + while (::testing::internal::AlwaysTrue()) { + const ::std::string::size_type colon = str.find(delimiter, pos); + if (colon == ::std::string::npos) { + parsed.push_back(str.substr(pos)); + break; + } else { + parsed.push_back(str.substr(pos, colon - pos)); + pos = colon + 1; + } + } + dest->swap(parsed); +} + +#if GTEST_OS_WINDOWS +// Recreates the pipe and event handles from the provided parameters, +// signals the event, and returns a file descriptor wrapped around the pipe +// handle. This function is called in the child process only. +int GetStatusFileDescriptor(unsigned int parent_process_id, + size_t write_handle_as_size_t, + size_t event_handle_as_size_t) { + AutoHandle parent_process_handle(::OpenProcess(PROCESS_DUP_HANDLE, + FALSE, // Non-inheritable. + parent_process_id)); + if (parent_process_handle.Get() == INVALID_HANDLE_VALUE) { + DeathTestAbort(String::Format("Unable to open parent process %u", + parent_process_id)); + } + + // TODO(vladl@google.com): Replace the following check with a + // compile-time assertion when available. + GTEST_CHECK_(sizeof(HANDLE) <= sizeof(size_t)); + + const HANDLE write_handle = + reinterpret_cast(write_handle_as_size_t); + HANDLE dup_write_handle; + + // The newly initialized handle is accessible only in in the parent + // process. To obtain one accessible within the child, we need to use + // DuplicateHandle. + if (!::DuplicateHandle(parent_process_handle.Get(), write_handle, + ::GetCurrentProcess(), &dup_write_handle, + 0x0, // Requested privileges ignored since + // DUPLICATE_SAME_ACCESS is used. + FALSE, // Request non-inheritable handler. + DUPLICATE_SAME_ACCESS)) { + DeathTestAbort(String::Format( + "Unable to duplicate the pipe handle %Iu from the parent process %u", + write_handle_as_size_t, parent_process_id)); + } + + const HANDLE event_handle = reinterpret_cast(event_handle_as_size_t); + HANDLE dup_event_handle; + + if (!::DuplicateHandle(parent_process_handle.Get(), event_handle, + ::GetCurrentProcess(), &dup_event_handle, + 0x0, + FALSE, + DUPLICATE_SAME_ACCESS)) { + DeathTestAbort(String::Format( + "Unable to duplicate the event handle %Iu from the parent process %u", + event_handle_as_size_t, parent_process_id)); + } + + const int write_fd = + ::_open_osfhandle(reinterpret_cast(dup_write_handle), O_APPEND); + if (write_fd == -1) { + DeathTestAbort(String::Format( + "Unable to convert pipe handle %Iu to a file descriptor", + write_handle_as_size_t)); + } + + // Signals the parent that the write end of the pipe has been acquired + // so the parent can release its own write end. + ::SetEvent(dup_event_handle); + + return write_fd; +} +#endif // GTEST_OS_WINDOWS + +// Returns a newly created InternalRunDeathTestFlag object with fields +// initialized from the GTEST_FLAG(internal_run_death_test) flag if +// the flag is specified; otherwise returns NULL. +InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag() { + if (GTEST_FLAG(internal_run_death_test) == "") return NULL; + + // GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we + // can use it here. + int line = -1; + int index = -1; + ::std::vector< ::std::string> fields; + SplitString(GTEST_FLAG(internal_run_death_test).c_str(), '|', &fields); + int write_fd = -1; + +#if GTEST_OS_WINDOWS + unsigned int parent_process_id = 0; + size_t write_handle_as_size_t = 0; + size_t event_handle_as_size_t = 0; + + if (fields.size() != 6 + || !ParseNaturalNumber(fields[1], &line) + || !ParseNaturalNumber(fields[2], &index) + || !ParseNaturalNumber(fields[3], &parent_process_id) + || !ParseNaturalNumber(fields[4], &write_handle_as_size_t) + || !ParseNaturalNumber(fields[5], &event_handle_as_size_t)) { + DeathTestAbort(String::Format( + "Bad --gtest_internal_run_death_test flag: %s", + GTEST_FLAG(internal_run_death_test).c_str())); + } + write_fd = GetStatusFileDescriptor(parent_process_id, + write_handle_as_size_t, + event_handle_as_size_t); +#else + if (fields.size() != 4 + || !ParseNaturalNumber(fields[1], &line) + || !ParseNaturalNumber(fields[2], &index) + || !ParseNaturalNumber(fields[3], &write_fd)) { + DeathTestAbort(String::Format( + "Bad --gtest_internal_run_death_test flag: %s", + GTEST_FLAG(internal_run_death_test).c_str())); + } +#endif // GTEST_OS_WINDOWS + return new InternalRunDeathTestFlag(fields[0], line, index, write_fd); +} + +} // namespace internal + +#endif // GTEST_HAS_DEATH_TEST + +} // namespace testing +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: keith.ray@gmail.com (Keith Ray) + + +#include + +#if GTEST_OS_WINDOWS_MOBILE +#include +#elif GTEST_OS_WINDOWS +#include +#include +#elif GTEST_OS_SYMBIAN +// Symbian OpenC has PATH_MAX in sys/syslimits.h +#include +#else +#include +#include // Some Linux distributions define PATH_MAX here. +#endif // GTEST_OS_WINDOWS_MOBILE + +#if GTEST_OS_WINDOWS +#define GTEST_PATH_MAX_ _MAX_PATH +#elif defined(PATH_MAX) +#define GTEST_PATH_MAX_ PATH_MAX +#elif defined(_XOPEN_PATH_MAX) +#define GTEST_PATH_MAX_ _XOPEN_PATH_MAX +#else +#define GTEST_PATH_MAX_ _POSIX_PATH_MAX +#endif // GTEST_OS_WINDOWS + + +namespace testing { +namespace internal { + +#if GTEST_OS_WINDOWS +// On Windows, '\\' is the standard path separator, but many tools and the +// Windows API also accept '/' as an alternate path separator. Unless otherwise +// noted, a file path can contain either kind of path separators, or a mixture +// of them. +const char kPathSeparator = '\\'; +const char kAlternatePathSeparator = '/'; +const char kPathSeparatorString[] = "\\"; +const char kAlternatePathSeparatorString[] = "/"; +#if GTEST_OS_WINDOWS_MOBILE +// Windows CE doesn't have a current directory. You should not use +// the current directory in tests on Windows CE, but this at least +// provides a reasonable fallback. +const char kCurrentDirectoryString[] = "\\"; +// Windows CE doesn't define INVALID_FILE_ATTRIBUTES +const DWORD kInvalidFileAttributes = 0xffffffff; +#else +const char kCurrentDirectoryString[] = ".\\"; +#endif // GTEST_OS_WINDOWS_MOBILE +#else +const char kPathSeparator = '/'; +const char kPathSeparatorString[] = "/"; +const char kCurrentDirectoryString[] = "./"; +#endif // GTEST_OS_WINDOWS + +// Returns whether the given character is a valid path separator. +static bool IsPathSeparator(char c) { +#if GTEST_HAS_ALT_PATH_SEP_ + return (c == kPathSeparator) || (c == kAlternatePathSeparator); +#else + return c == kPathSeparator; +#endif +} + +// Returns the current working directory, or "" if unsuccessful. +FilePath FilePath::GetCurrentDir() { +#if GTEST_OS_WINDOWS_MOBILE + // Windows CE doesn't have a current directory, so we just return + // something reasonable. + return FilePath(kCurrentDirectoryString); +#elif GTEST_OS_WINDOWS + char cwd[GTEST_PATH_MAX_ + 1] = { '\0' }; + return FilePath(_getcwd(cwd, sizeof(cwd)) == NULL ? "" : cwd); +#else + char cwd[GTEST_PATH_MAX_ + 1] = { '\0' }; + return FilePath(getcwd(cwd, sizeof(cwd)) == NULL ? "" : cwd); +#endif // GTEST_OS_WINDOWS_MOBILE +} + +// Returns a copy of the FilePath with the case-insensitive extension removed. +// Example: FilePath("dir/file.exe").RemoveExtension("EXE") returns +// FilePath("dir/file"). If a case-insensitive extension is not +// found, returns a copy of the original FilePath. +FilePath FilePath::RemoveExtension(const char* extension) const { + String dot_extension(String::Format(".%s", extension)); + if (pathname_.EndsWithCaseInsensitive(dot_extension.c_str())) { + return FilePath(String(pathname_.c_str(), pathname_.length() - 4)); + } + return *this; +} + +// Returns a pointer to the last occurence of a valid path separator in +// the FilePath. On Windows, for example, both '/' and '\' are valid path +// separators. Returns NULL if no path separator was found. +const char* FilePath::FindLastPathSeparator() const { + const char* const last_sep = strrchr(c_str(), kPathSeparator); +#if GTEST_HAS_ALT_PATH_SEP_ + const char* const last_alt_sep = strrchr(c_str(), kAlternatePathSeparator); + // Comparing two pointers of which only one is NULL is undefined. + if (last_alt_sep != NULL && + (last_sep == NULL || last_alt_sep > last_sep)) { + return last_alt_sep; + } +#endif + return last_sep; +} + +// Returns a copy of the FilePath with the directory part removed. +// Example: FilePath("path/to/file").RemoveDirectoryName() returns +// FilePath("file"). If there is no directory part ("just_a_file"), it returns +// the FilePath unmodified. If there is no file part ("just_a_dir/") it +// returns an empty FilePath (""). +// On Windows platform, '\' is the path separator, otherwise it is '/'. +FilePath FilePath::RemoveDirectoryName() const { + const char* const last_sep = FindLastPathSeparator(); + return last_sep ? FilePath(String(last_sep + 1)) : *this; +} + +// RemoveFileName returns the directory path with the filename removed. +// Example: FilePath("path/to/file").RemoveFileName() returns "path/to/". +// If the FilePath is "a_file" or "/a_file", RemoveFileName returns +// FilePath("./") or, on Windows, FilePath(".\\"). If the filepath does +// not have a file, like "just/a/dir/", it returns the FilePath unmodified. +// On Windows platform, '\' is the path separator, otherwise it is '/'. +FilePath FilePath::RemoveFileName() const { + const char* const last_sep = FindLastPathSeparator(); + String dir; + if (last_sep) { + dir = String(c_str(), last_sep + 1 - c_str()); + } else { + dir = kCurrentDirectoryString; + } + return FilePath(dir); +} + +// Helper functions for naming files in a directory for xml output. + +// Given directory = "dir", base_name = "test", number = 0, +// extension = "xml", returns "dir/test.xml". If number is greater +// than zero (e.g., 12), returns "dir/test_12.xml". +// On Windows platform, uses \ as the separator rather than /. +FilePath FilePath::MakeFileName(const FilePath& directory, + const FilePath& base_name, + int number, + const char* extension) { + String file; + if (number == 0) { + file = String::Format("%s.%s", base_name.c_str(), extension); + } else { + file = String::Format("%s_%d.%s", base_name.c_str(), number, extension); + } + return ConcatPaths(directory, FilePath(file)); +} + +// Given directory = "dir", relative_path = "test.xml", returns "dir/test.xml". +// On Windows, uses \ as the separator rather than /. +FilePath FilePath::ConcatPaths(const FilePath& directory, + const FilePath& relative_path) { + if (directory.IsEmpty()) + return relative_path; + const FilePath dir(directory.RemoveTrailingPathSeparator()); + return FilePath(String::Format("%s%c%s", dir.c_str(), kPathSeparator, + relative_path.c_str())); +} + +// Returns true if pathname describes something findable in the file-system, +// either a file, directory, or whatever. +bool FilePath::FileOrDirectoryExists() const { +#if GTEST_OS_WINDOWS_MOBILE + LPCWSTR unicode = String::AnsiToUtf16(pathname_.c_str()); + const DWORD attributes = GetFileAttributes(unicode); + delete [] unicode; + return attributes != kInvalidFileAttributes; +#else + posix::StatStruct file_stat; + return posix::Stat(pathname_.c_str(), &file_stat) == 0; +#endif // GTEST_OS_WINDOWS_MOBILE +} + +// Returns true if pathname describes a directory in the file-system +// that exists. +bool FilePath::DirectoryExists() const { + bool result = false; +#if GTEST_OS_WINDOWS + // Don't strip off trailing separator if path is a root directory on + // Windows (like "C:\\"). + const FilePath& path(IsRootDirectory() ? *this : + RemoveTrailingPathSeparator()); +#else + const FilePath& path(*this); +#endif + +#if GTEST_OS_WINDOWS_MOBILE + LPCWSTR unicode = String::AnsiToUtf16(path.c_str()); + const DWORD attributes = GetFileAttributes(unicode); + delete [] unicode; + if ((attributes != kInvalidFileAttributes) && + (attributes & FILE_ATTRIBUTE_DIRECTORY)) { + result = true; + } +#else + posix::StatStruct file_stat; + result = posix::Stat(path.c_str(), &file_stat) == 0 && + posix::IsDir(file_stat); +#endif // GTEST_OS_WINDOWS_MOBILE + + return result; +} + +// Returns true if pathname describes a root directory. (Windows has one +// root directory per disk drive.) +bool FilePath::IsRootDirectory() const { +#if GTEST_OS_WINDOWS + // TODO(wan@google.com): on Windows a network share like + // \\server\share can be a root directory, although it cannot be the + // current directory. Handle this properly. + return pathname_.length() == 3 && IsAbsolutePath(); +#else + return pathname_.length() == 1 && IsPathSeparator(pathname_.c_str()[0]); +#endif +} + +// Returns true if pathname describes an absolute path. +bool FilePath::IsAbsolutePath() const { + const char* const name = pathname_.c_str(); +#if GTEST_OS_WINDOWS + return pathname_.length() >= 3 && + ((name[0] >= 'a' && name[0] <= 'z') || + (name[0] >= 'A' && name[0] <= 'Z')) && + name[1] == ':' && + IsPathSeparator(name[2]); +#else + return IsPathSeparator(name[0]); +#endif +} + +// Returns a pathname for a file that does not currently exist. The pathname +// will be directory/base_name.extension or +// directory/base_name_.extension if directory/base_name.extension +// already exists. The number will be incremented until a pathname is found +// that does not already exist. +// Examples: 'dir/foo_test.xml' or 'dir/foo_test_1.xml'. +// There could be a race condition if two or more processes are calling this +// function at the same time -- they could both pick the same filename. +FilePath FilePath::GenerateUniqueFileName(const FilePath& directory, + const FilePath& base_name, + const char* extension) { + FilePath full_pathname; + int number = 0; + do { + full_pathname.Set(MakeFileName(directory, base_name, number++, extension)); + } while (full_pathname.FileOrDirectoryExists()); + return full_pathname; +} + +// Returns true if FilePath ends with a path separator, which indicates that +// it is intended to represent a directory. Returns false otherwise. +// This does NOT check that a directory (or file) actually exists. +bool FilePath::IsDirectory() const { + return !pathname_.empty() && + IsPathSeparator(pathname_.c_str()[pathname_.length() - 1]); +} + +// Create directories so that path exists. Returns true if successful or if +// the directories already exist; returns false if unable to create directories +// for any reason. +bool FilePath::CreateDirectoriesRecursively() const { + if (!this->IsDirectory()) { + return false; + } + + if (pathname_.length() == 0 || this->DirectoryExists()) { + return true; + } + + const FilePath parent(this->RemoveTrailingPathSeparator().RemoveFileName()); + return parent.CreateDirectoriesRecursively() && this->CreateFolder(); +} + +// Create the directory so that path exists. Returns true if successful or +// if the directory already exists; returns false if unable to create the +// directory for any reason, including if the parent directory does not +// exist. Not named "CreateDirectory" because that's a macro on Windows. +bool FilePath::CreateFolder() const { +#if GTEST_OS_WINDOWS_MOBILE + FilePath removed_sep(this->RemoveTrailingPathSeparator()); + LPCWSTR unicode = String::AnsiToUtf16(removed_sep.c_str()); + int result = CreateDirectory(unicode, NULL) ? 0 : -1; + delete [] unicode; +#elif GTEST_OS_WINDOWS + int result = _mkdir(pathname_.c_str()); +#else + int result = mkdir(pathname_.c_str(), 0777); +#endif // GTEST_OS_WINDOWS_MOBILE + + if (result == -1) { + return this->DirectoryExists(); // An error is OK if the directory exists. + } + return true; // No error. +} + +// If input name has a trailing separator character, remove it and return the +// name, otherwise return the name string unmodified. +// On Windows platform, uses \ as the separator, other platforms use /. +FilePath FilePath::RemoveTrailingPathSeparator() const { + return IsDirectory() + ? FilePath(String(pathname_.c_str(), pathname_.length() - 1)) + : *this; +} + +// Removes any redundant separators that might be in the pathname. +// For example, "bar///foo" becomes "bar/foo". Does not eliminate other +// redundancies that might be in a pathname involving "." or "..". +// TODO(wan@google.com): handle Windows network shares (e.g. \\server\share). +void FilePath::Normalize() { + if (pathname_.c_str() == NULL) { + pathname_ = ""; + return; + } + const char* src = pathname_.c_str(); + char* const dest = new char[pathname_.length() + 1]; + char* dest_ptr = dest; + memset(dest_ptr, 0, pathname_.length() + 1); + + while (*src != '\0') { + *dest_ptr = *src; + if (!IsPathSeparator(*src)) { + src++; + } else { +#if GTEST_HAS_ALT_PATH_SEP_ + if (*dest_ptr == kAlternatePathSeparator) { + *dest_ptr = kPathSeparator; + } +#endif + while (IsPathSeparator(*src)) + src++; + } + dest_ptr++; + } + *dest_ptr = '\0'; + pathname_ = dest; + delete[] dest; +} + +} // namespace internal +} // namespace testing +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: wan@google.com (Zhanyong Wan) + + +#include +#include +#include + +#if GTEST_OS_WINDOWS_MOBILE +#include // For TerminateProcess() +#elif GTEST_OS_WINDOWS +#include +#include +#else +#include +#endif // GTEST_OS_WINDOWS_MOBILE + +#if GTEST_OS_MAC +#include +#include +#include +#endif // GTEST_OS_MAC + + +// Indicates that this translation unit is part of Google Test's +// implementation. It must come before gtest-internal-inl.h is +// included, or there will be a compiler error. This trick is to +// prevent a user from accidentally including gtest-internal-inl.h in +// his code. +#define GTEST_IMPLEMENTATION_ 1 +#undef GTEST_IMPLEMENTATION_ + +namespace testing { +namespace internal { + +#if defined(_MSC_VER) || defined(__BORLANDC__) +// MSVC and C++Builder do not provide a definition of STDERR_FILENO. +const int kStdOutFileno = 1; +const int kStdErrFileno = 2; +#else +const int kStdOutFileno = STDOUT_FILENO; +const int kStdErrFileno = STDERR_FILENO; +#endif // _MSC_VER + +#if GTEST_OS_MAC + +// Returns the number of threads running in the process, or 0 to indicate that +// we cannot detect it. +size_t GetThreadCount() { + const task_t task = mach_task_self(); + mach_msg_type_number_t thread_count; + thread_act_array_t thread_list; + const kern_return_t status = task_threads(task, &thread_list, &thread_count); + if (status == KERN_SUCCESS) { + // task_threads allocates resources in thread_list and we need to free them + // to avoid leaks. + vm_deallocate(task, + reinterpret_cast(thread_list), + sizeof(thread_t) * thread_count); + return static_cast(thread_count); + } else { + return 0; + } +} + +#else + +size_t GetThreadCount() { + // There's no portable way to detect the number of threads, so we just + // return 0 to indicate that we cannot detect it. + return 0; +} + +#endif // GTEST_OS_MAC + +#if GTEST_USES_POSIX_RE + +// Implements RE. Currently only needed for death tests. + +RE::~RE() { + if (is_valid_) { + // regfree'ing an invalid regex might crash because the content + // of the regex is undefined. Since the regex's are essentially + // the same, one cannot be valid (or invalid) without the other + // being so too. + regfree(&partial_regex_); + regfree(&full_regex_); + } + free(const_cast(pattern_)); +} + +// Returns true iff regular expression re matches the entire str. +bool RE::FullMatch(const char* str, const RE& re) { + if (!re.is_valid_) return false; + + regmatch_t match; + return regexec(&re.full_regex_, str, 1, &match, 0) == 0; +} + +// Returns true iff regular expression re matches a substring of str +// (including str itself). +bool RE::PartialMatch(const char* str, const RE& re) { + if (!re.is_valid_) return false; + + regmatch_t match; + return regexec(&re.partial_regex_, str, 1, &match, 0) == 0; +} + +// Initializes an RE from its string representation. +void RE::Init(const char* regex) { + pattern_ = posix::StrDup(regex); + + // Reserves enough bytes to hold the regular expression used for a + // full match. + const size_t full_regex_len = strlen(regex) + 10; + char* const full_pattern = new char[full_regex_len]; + + snprintf(full_pattern, full_regex_len, "^(%s)$", regex); + is_valid_ = regcomp(&full_regex_, full_pattern, REG_EXTENDED) == 0; + // We want to call regcomp(&partial_regex_, ...) even if the + // previous expression returns false. Otherwise partial_regex_ may + // not be properly initialized can may cause trouble when it's + // freed. + // + // Some implementation of POSIX regex (e.g. on at least some + // versions of Cygwin) doesn't accept the empty string as a valid + // regex. We change it to an equivalent form "()" to be safe. + if (is_valid_) { + const char* const partial_regex = (*regex == '\0') ? "()" : regex; + is_valid_ = regcomp(&partial_regex_, partial_regex, REG_EXTENDED) == 0; + } + EXPECT_TRUE(is_valid_) + << "Regular expression \"" << regex + << "\" is not a valid POSIX Extended regular expression."; + + delete[] full_pattern; +} + +#elif GTEST_USES_SIMPLE_RE + +// Returns true iff ch appears anywhere in str (excluding the +// terminating '\0' character). +bool IsInSet(char ch, const char* str) { + return ch != '\0' && strchr(str, ch) != NULL; +} + +// Returns true iff ch belongs to the given classification. Unlike +// similar functions in , these aren't affected by the +// current locale. +bool IsDigit(char ch) { return '0' <= ch && ch <= '9'; } +bool IsPunct(char ch) { + return IsInSet(ch, "^-!\"#$%&'()*+,./:;<=>?@[\\]_`{|}~"); +} +bool IsRepeat(char ch) { return IsInSet(ch, "?*+"); } +bool IsWhiteSpace(char ch) { return IsInSet(ch, " \f\n\r\t\v"); } +bool IsWordChar(char ch) { + return ('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z') || + ('0' <= ch && ch <= '9') || ch == '_'; +} + +// Returns true iff "\\c" is a supported escape sequence. +bool IsValidEscape(char c) { + return (IsPunct(c) || IsInSet(c, "dDfnrsStvwW")); +} + +// Returns true iff the given atom (specified by escaped and pattern) +// matches ch. The result is undefined if the atom is invalid. +bool AtomMatchesChar(bool escaped, char pattern_char, char ch) { + if (escaped) { // "\\p" where p is pattern_char. + switch (pattern_char) { + case 'd': return IsDigit(ch); + case 'D': return !IsDigit(ch); + case 'f': return ch == '\f'; + case 'n': return ch == '\n'; + case 'r': return ch == '\r'; + case 's': return IsWhiteSpace(ch); + case 'S': return !IsWhiteSpace(ch); + case 't': return ch == '\t'; + case 'v': return ch == '\v'; + case 'w': return IsWordChar(ch); + case 'W': return !IsWordChar(ch); + } + return IsPunct(pattern_char) && pattern_char == ch; + } + + return (pattern_char == '.' && ch != '\n') || pattern_char == ch; +} + +// Helper function used by ValidateRegex() to format error messages. +String FormatRegexSyntaxError(const char* regex, int index) { + return (Message() << "Syntax error at index " << index + << " in simple regular expression \"" << regex << "\": ").GetString(); +} + +// Generates non-fatal failures and returns false if regex is invalid; +// otherwise returns true. +bool ValidateRegex(const char* regex) { + if (regex == NULL) { + // TODO(wan@google.com): fix the source file location in the + // assertion failures to match where the regex is used in user + // code. + ADD_FAILURE() << "NULL is not a valid simple regular expression."; + return false; + } + + bool is_valid = true; + + // True iff ?, *, or + can follow the previous atom. + bool prev_repeatable = false; + for (int i = 0; regex[i]; i++) { + if (regex[i] == '\\') { // An escape sequence + i++; + if (regex[i] == '\0') { + ADD_FAILURE() << FormatRegexSyntaxError(regex, i - 1) + << "'\\' cannot appear at the end."; + return false; + } + + if (!IsValidEscape(regex[i])) { + ADD_FAILURE() << FormatRegexSyntaxError(regex, i - 1) + << "invalid escape sequence \"\\" << regex[i] << "\"."; + is_valid = false; + } + prev_repeatable = true; + } else { // Not an escape sequence. + const char ch = regex[i]; + + if (ch == '^' && i > 0) { + ADD_FAILURE() << FormatRegexSyntaxError(regex, i) + << "'^' can only appear at the beginning."; + is_valid = false; + } else if (ch == '$' && regex[i + 1] != '\0') { + ADD_FAILURE() << FormatRegexSyntaxError(regex, i) + << "'$' can only appear at the end."; + is_valid = false; + } else if (IsInSet(ch, "()[]{}|")) { + ADD_FAILURE() << FormatRegexSyntaxError(regex, i) + << "'" << ch << "' is unsupported."; + is_valid = false; + } else if (IsRepeat(ch) && !prev_repeatable) { + ADD_FAILURE() << FormatRegexSyntaxError(regex, i) + << "'" << ch << "' can only follow a repeatable token."; + is_valid = false; + } + + prev_repeatable = !IsInSet(ch, "^$?*+"); + } + } + + return is_valid; +} + +// Matches a repeated regex atom followed by a valid simple regular +// expression. The regex atom is defined as c if escaped is false, +// or \c otherwise. repeat is the repetition meta character (?, *, +// or +). The behavior is undefined if str contains too many +// characters to be indexable by size_t, in which case the test will +// probably time out anyway. We are fine with this limitation as +// std::string has it too. +bool MatchRepetitionAndRegexAtHead( + bool escaped, char c, char repeat, const char* regex, + const char* str) { + const size_t min_count = (repeat == '+') ? 1 : 0; + const size_t max_count = (repeat == '?') ? 1 : + static_cast(-1) - 1; + // We cannot call numeric_limits::max() as it conflicts with the + // max() macro on Windows. + + for (size_t i = 0; i <= max_count; ++i) { + // We know that the atom matches each of the first i characters in str. + if (i >= min_count && MatchRegexAtHead(regex, str + i)) { + // We have enough matches at the head, and the tail matches too. + // Since we only care about *whether* the pattern matches str + // (as opposed to *how* it matches), there is no need to find a + // greedy match. + return true; + } + if (str[i] == '\0' || !AtomMatchesChar(escaped, c, str[i])) + return false; + } + return false; +} + +// Returns true iff regex matches a prefix of str. regex must be a +// valid simple regular expression and not start with "^", or the +// result is undefined. +bool MatchRegexAtHead(const char* regex, const char* str) { + if (*regex == '\0') // An empty regex matches a prefix of anything. + return true; + + // "$" only matches the end of a string. Note that regex being + // valid guarantees that there's nothing after "$" in it. + if (*regex == '$') + return *str == '\0'; + + // Is the first thing in regex an escape sequence? + const bool escaped = *regex == '\\'; + if (escaped) + ++regex; + if (IsRepeat(regex[1])) { + // MatchRepetitionAndRegexAtHead() calls MatchRegexAtHead(), so + // here's an indirect recursion. It terminates as the regex gets + // shorter in each recursion. + return MatchRepetitionAndRegexAtHead( + escaped, regex[0], regex[1], regex + 2, str); + } else { + // regex isn't empty, isn't "$", and doesn't start with a + // repetition. We match the first atom of regex with the first + // character of str and recurse. + return (*str != '\0') && AtomMatchesChar(escaped, *regex, *str) && + MatchRegexAtHead(regex + 1, str + 1); + } +} + +// Returns true iff regex matches any substring of str. regex must be +// a valid simple regular expression, or the result is undefined. +// +// The algorithm is recursive, but the recursion depth doesn't exceed +// the regex length, so we won't need to worry about running out of +// stack space normally. In rare cases the time complexity can be +// exponential with respect to the regex length + the string length, +// but usually it's must faster (often close to linear). +bool MatchRegexAnywhere(const char* regex, const char* str) { + if (regex == NULL || str == NULL) + return false; + + if (*regex == '^') + return MatchRegexAtHead(regex + 1, str); + + // A successful match can be anywhere in str. + do { + if (MatchRegexAtHead(regex, str)) + return true; + } while (*str++ != '\0'); + return false; +} + +// Implements the RE class. + +RE::~RE() { + free(const_cast(pattern_)); + free(const_cast(full_pattern_)); +} + +// Returns true iff regular expression re matches the entire str. +bool RE::FullMatch(const char* str, const RE& re) { + return re.is_valid_ && MatchRegexAnywhere(re.full_pattern_, str); +} + +// Returns true iff regular expression re matches a substring of str +// (including str itself). +bool RE::PartialMatch(const char* str, const RE& re) { + return re.is_valid_ && MatchRegexAnywhere(re.pattern_, str); +} + +// Initializes an RE from its string representation. +void RE::Init(const char* regex) { + pattern_ = full_pattern_ = NULL; + if (regex != NULL) { + pattern_ = posix::StrDup(regex); + } + + is_valid_ = ValidateRegex(regex); + if (!is_valid_) { + // No need to calculate the full pattern when the regex is invalid. + return; + } + + const size_t len = strlen(regex); + // Reserves enough bytes to hold the regular expression used for a + // full match: we need space to prepend a '^', append a '$', and + // terminate the string with '\0'. + char* buffer = static_cast(malloc(len + 3)); + full_pattern_ = buffer; + + if (*regex != '^') + *buffer++ = '^'; // Makes sure full_pattern_ starts with '^'. + + // We don't use snprintf or strncpy, as they trigger a warning when + // compiled with VC++ 8.0. + memcpy(buffer, regex, len); + buffer += len; + + if (len == 0 || regex[len - 1] != '$') + *buffer++ = '$'; // Makes sure full_pattern_ ends with '$'. + + *buffer = '\0'; +} + +#endif // GTEST_USES_POSIX_RE + + +GTestLog::GTestLog(GTestLogSeverity severity, const char* file, int line) + : severity_(severity) { + const char* const marker = + severity == GTEST_INFO ? "[ INFO ]" : + severity == GTEST_WARNING ? "[WARNING]" : + severity == GTEST_ERROR ? "[ ERROR ]" : "[ FATAL ]"; + GetStream() << ::std::endl << marker << " " + << FormatFileLocation(file, line).c_str() << ": "; +} + +// Flushes the buffers and, if severity is GTEST_FATAL, aborts the program. +GTestLog::~GTestLog() { + GetStream() << ::std::endl; + if (severity_ == GTEST_FATAL) { + fflush(stderr); + posix::Abort(); + } +} +// Disable Microsoft deprecation warnings for POSIX functions called from +// this class (creat, dup, dup2, and close) +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable: 4996) +#endif // _MSC_VER + +#if GTEST_HAS_STREAM_REDIRECTION_ + +// Object that captures an output stream (stdout/stderr). +class CapturedStream { + public: + // The ctor redirects the stream to a temporary file. + CapturedStream(int fd) : fd_(fd), uncaptured_fd_(dup(fd)) { +#if GTEST_OS_WINDOWS + char temp_dir_path[MAX_PATH + 1] = { '\0' }; // NOLINT + char temp_file_path[MAX_PATH + 1] = { '\0' }; // NOLINT + + ::GetTempPathA(sizeof(temp_dir_path), temp_dir_path); + const UINT success = ::GetTempFileNameA(temp_dir_path, + "gtest_redir", + 0, // Generate unique file name. + temp_file_path); + GTEST_CHECK_(success != 0) + << "Unable to create a temporary file in " << temp_dir_path; + const int captured_fd = creat(temp_file_path, _S_IREAD | _S_IWRITE); + GTEST_CHECK_(captured_fd != -1) << "Unable to open temporary file " + << temp_file_path; + filename_ = temp_file_path; +#else + // There's no guarantee that a test has write access to the + // current directory, so we create the temporary file in the /tmp + // directory instead. + char name_template[] = "/tmp/captured_stream.XXXXXX"; + const int captured_fd = mkstemp(name_template); + filename_ = name_template; +#endif // GTEST_OS_WINDOWS + fflush(NULL); + dup2(captured_fd, fd_); + close(captured_fd); + } + + ~CapturedStream() { + remove(filename_.c_str()); + } + + String GetCapturedString() { + if (uncaptured_fd_ != -1) { + // Restores the original stream. + fflush(NULL); + dup2(uncaptured_fd_, fd_); + close(uncaptured_fd_); + uncaptured_fd_ = -1; + } + + FILE* const file = posix::FOpen(filename_.c_str(), "r"); + const String content = ReadEntireFile(file); + posix::FClose(file); + return content; + } + + private: + // Reads the entire content of a file as a String. + static String ReadEntireFile(FILE* file); + + // Returns the size (in bytes) of a file. + static size_t GetFileSize(FILE* file); + + const int fd_; // A stream to capture. + int uncaptured_fd_; + // Name of the temporary file holding the stderr output. + ::std::string filename_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(CapturedStream); +}; + +// Returns the size (in bytes) of a file. +size_t CapturedStream::GetFileSize(FILE* file) { + fseek(file, 0, SEEK_END); + return static_cast(ftell(file)); +} + +// Reads the entire content of a file as a string. +String CapturedStream::ReadEntireFile(FILE* file) { + const size_t file_size = GetFileSize(file); + char* const buffer = new char[file_size]; + + size_t bytes_last_read = 0; // # of bytes read in the last fread() + size_t bytes_read = 0; // # of bytes read so far + + fseek(file, 0, SEEK_SET); + + // Keeps reading the file until we cannot read further or the + // pre-determined file size is reached. + do { + bytes_last_read = fread(buffer+bytes_read, 1, file_size-bytes_read, file); + bytes_read += bytes_last_read; + } while (bytes_last_read > 0 && bytes_read < file_size); + + const String content(buffer, bytes_read); + delete[] buffer; + + return content; +} + +#ifdef _MSC_VER +#pragma warning(pop) +#endif // _MSC_VER + +static CapturedStream* g_captured_stderr = NULL; +static CapturedStream* g_captured_stdout = NULL; + +// Starts capturing an output stream (stdout/stderr). +void CaptureStream(int fd, const char* stream_name, CapturedStream** stream) { + if (*stream != NULL) { + GTEST_LOG_(FATAL) << "Only one " << stream_name + << " capturer can exist at a time."; + } + *stream = new CapturedStream(fd); +} + +// Stops capturing the output stream and returns the captured string. +String GetCapturedStream(CapturedStream** captured_stream) { + const String content = (*captured_stream)->GetCapturedString(); + + delete *captured_stream; + *captured_stream = NULL; + + return content; +} + +// Starts capturing stdout. +void CaptureStdout() { + CaptureStream(kStdOutFileno, "stdout", &g_captured_stdout); +} + +// Starts capturing stderr. +void CaptureStderr() { + CaptureStream(kStdErrFileno, "stderr", &g_captured_stderr); +} + +// Stops capturing stdout and returns the captured string. +String GetCapturedStdout() { return GetCapturedStream(&g_captured_stdout); } + +// Stops capturing stderr and returns the captured string. +String GetCapturedStderr() { return GetCapturedStream(&g_captured_stderr); } + +#endif // GTEST_HAS_STREAM_REDIRECTION_ + +#if GTEST_HAS_DEATH_TEST + +// A copy of all command line arguments. Set by InitGoogleTest(). +::std::vector g_argvs; + +// Returns the command line as a vector of strings. +const ::std::vector& GetArgvs() { return g_argvs; } + +#endif // GTEST_HAS_DEATH_TEST + +#if GTEST_OS_WINDOWS_MOBILE +namespace posix { +void Abort() { + DebugBreak(); + TerminateProcess(GetCurrentProcess(), 1); +} +} // namespace posix +#endif // GTEST_OS_WINDOWS_MOBILE + +// Returns the name of the environment variable corresponding to the +// given flag. For example, FlagToEnvVar("foo") will return +// "GTEST_FOO" in the open-source version. +static String FlagToEnvVar(const char* flag) { + const String full_flag = + (Message() << GTEST_FLAG_PREFIX_ << flag).GetString(); + + Message env_var; + for (size_t i = 0; i != full_flag.length(); i++) { + env_var << static_cast(toupper(full_flag.c_str()[i])); + } + + return env_var.GetString(); +} + +// Parses 'str' for a 32-bit signed integer. If successful, writes +// the result to *value and returns true; otherwise leaves *value +// unchanged and returns false. +bool ParseInt32(const Message& src_text, const char* str, Int32* value) { + // Parses the environment variable as a decimal integer. + char* end = NULL; + const long long_value = strtol(str, &end, 10); // NOLINT + + // Has strtol() consumed all characters in the string? + if (*end != '\0') { + // No - an invalid character was encountered. + Message msg; + msg << "WARNING: " << src_text + << " is expected to be a 32-bit integer, but actually" + << " has value \"" << str << "\".\n"; + printf("%s", msg.GetString().c_str()); + fflush(stdout); + return false; + } + + // Is the parsed value in the range of an Int32? + const Int32 result = static_cast(long_value); + if (long_value == LONG_MAX || long_value == LONG_MIN || + // The parsed value overflows as a long. (strtol() returns + // LONG_MAX or LONG_MIN when the input overflows.) + result != long_value + // The parsed value overflows as an Int32. + ) { + Message msg; + msg << "WARNING: " << src_text + << " is expected to be a 32-bit integer, but actually" + << " has value " << str << ", which overflows.\n"; + printf("%s", msg.GetString().c_str()); + fflush(stdout); + return false; + } + + *value = result; + return true; +} + +// Reads and returns the Boolean environment variable corresponding to +// the given flag; if it's not set, returns default_value. +// +// The value is considered true iff it's not "0". +bool BoolFromGTestEnv(const char* flag, bool default_value) { + const String env_var = FlagToEnvVar(flag); + const char* const string_value = posix::GetEnv(env_var.c_str()); + return string_value == NULL ? + default_value : strcmp(string_value, "0") != 0; +} + +// Reads and returns a 32-bit integer stored in the environment +// variable corresponding to the given flag; if it isn't set or +// doesn't represent a valid 32-bit integer, returns default_value. +Int32 Int32FromGTestEnv(const char* flag, Int32 default_value) { + const String env_var = FlagToEnvVar(flag); + const char* const string_value = posix::GetEnv(env_var.c_str()); + if (string_value == NULL) { + // The environment variable is not set. + return default_value; + } + + Int32 result = default_value; + if (!ParseInt32(Message() << "Environment variable " << env_var, + string_value, &result)) { + printf("The default value %s is used.\n", + (Message() << default_value).GetString().c_str()); + fflush(stdout); + return default_value; + } + + return result; +} + +// Reads and returns the string environment variable corresponding to +// the given flag; if it's not set, returns default_value. +const char* StringFromGTestEnv(const char* flag, const char* default_value) { + const String env_var = FlagToEnvVar(flag); + const char* const value = posix::GetEnv(env_var.c_str()); + return value == NULL ? default_value : value; +} + +} // namespace internal +} // namespace testing +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: mheule@google.com (Markus Heule) +// +// The Google C++ Testing Framework (Google Test) + + +// Indicates that this translation unit is part of Google Test's +// implementation. It must come before gtest-internal-inl.h is +// included, or there will be a compiler error. This trick is to +// prevent a user from accidentally including gtest-internal-inl.h in +// his code. +#define GTEST_IMPLEMENTATION_ 1 +#undef GTEST_IMPLEMENTATION_ + +namespace testing { + +using internal::GetUnitTestImpl; + +// Gets the summary of the failure message by omitting the stack trace +// in it. +internal::String TestPartResult::ExtractSummary(const char* message) { + const char* const stack_trace = strstr(message, internal::kStackTraceMarker); + return stack_trace == NULL ? internal::String(message) : + internal::String(message, stack_trace - message); +} + +// Prints a TestPartResult object. +std::ostream& operator<<(std::ostream& os, const TestPartResult& result) { + return os + << result.file_name() << ":" << result.line_number() << ": " + << (result.type() == TestPartResult::kSuccess ? "Success" : + result.type() == TestPartResult::kFatalFailure ? "Fatal failure" : + "Non-fatal failure") << ":\n" + << result.message() << std::endl; +} + +// Appends a TestPartResult to the array. +void TestPartResultArray::Append(const TestPartResult& result) { + array_.push_back(result); +} + +// Returns the TestPartResult at the given index (0-based). +const TestPartResult& TestPartResultArray::GetTestPartResult(int index) const { + if (index < 0 || index >= size()) { + printf("\nInvalid index (%d) into TestPartResultArray.\n", index); + internal::posix::Abort(); + } + + return array_[index]; +} + +// Returns the number of TestPartResult objects in the array. +int TestPartResultArray::size() const { + return static_cast(array_.size()); +} + +namespace internal { + +HasNewFatalFailureHelper::HasNewFatalFailureHelper() + : has_new_fatal_failure_(false), + original_reporter_(GetUnitTestImpl()-> + GetTestPartResultReporterForCurrentThread()) { + GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread(this); +} + +HasNewFatalFailureHelper::~HasNewFatalFailureHelper() { + GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread( + original_reporter_); +} + +void HasNewFatalFailureHelper::ReportTestPartResult( + const TestPartResult& result) { + if (result.fatally_failed()) + has_new_fatal_failure_ = true; + original_reporter_->ReportTestPartResult(result); +} + +} // namespace internal + +} // namespace testing +// Copyright 2008 Google Inc. +// All Rights Reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: wan@google.com (Zhanyong Wan) + + +namespace testing { +namespace internal { + +#if GTEST_HAS_TYPED_TEST_P + +// Skips to the first non-space char in str. Returns an empty string if str +// contains only whitespace characters. +static const char* SkipSpaces(const char* str) { + while (isspace(*str)) + str++; + return str; +} + +// Verifies that registered_tests match the test names in +// defined_test_names_; returns registered_tests if successful, or +// aborts the program otherwise. +const char* TypedTestCasePState::VerifyRegisteredTestNames( + const char* file, int line, const char* registered_tests) { + typedef ::std::set::const_iterator DefinedTestIter; + registered_ = true; + + // Skip initial whitespace in registered_tests since some + // preprocessors prefix stringizied literals with whitespace. + registered_tests = SkipSpaces(registered_tests); + + Message errors; + ::std::set tests; + for (const char* names = registered_tests; names != NULL; + names = SkipComma(names)) { + const String name = GetPrefixUntilComma(names); + if (tests.count(name) != 0) { + errors << "Test " << name << " is listed more than once.\n"; + continue; + } + + bool found = false; + for (DefinedTestIter it = defined_test_names_.begin(); + it != defined_test_names_.end(); + ++it) { + if (name == *it) { + found = true; + break; + } + } + + if (found) { + tests.insert(name); + } else { + errors << "No test named " << name + << " can be found in this test case.\n"; + } + } + + for (DefinedTestIter it = defined_test_names_.begin(); + it != defined_test_names_.end(); + ++it) { + if (tests.count(*it) == 0) { + errors << "You forgot to list test " << *it << ".\n"; + } + } + + const String& errors_str = errors.GetString(); + if (errors_str != "") { + fprintf(stderr, "%s %s", FormatFileLocation(file, line).c_str(), + errors_str.c_str()); + fflush(stderr); + posix::Abort(); + } + + return registered_tests; +} + +#endif // GTEST_HAS_TYPED_TEST_P + +} // namespace internal +} // namespace testing diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmCore_UnitTests/gtest/gtest.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmCore_UnitTests/gtest/gtest.h new file mode 100644 index 0000000000..c0a1902e25 --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmCore_UnitTests/gtest/gtest.h @@ -0,0 +1,18007 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: wan@google.com (Zhanyong Wan) +// +// The Google C++ Testing Framework (Google Test) +// +// This header file defines the public API for Google Test. It should be +// included by any test program that uses Google Test. +// +// IMPORTANT NOTE: Due to limitation of the C++ language, we have to +// leave some internal implementation details in this header file. +// They are clearly marked by comments like this: +// +// // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +// +// Such code is NOT meant to be used by a user directly, and is subject +// to CHANGE WITHOUT NOTICE. Therefore DO NOT DEPEND ON IT in a user +// program! +// +// Acknowledgment: Google Test borrowed the idea of automatic test +// registration from Barthelemy Dagenais' (barthelemy@prologique.com) +// easyUnit framework. + +#ifndef GTEST_INCLUDE_GTEST_GTEST_H_ +#define GTEST_INCLUDE_GTEST_GTEST_H_ + +#include +#include + +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee) +// +// The Google C++ Testing Framework (Google Test) +// +// This header file declares functions and macros used internally by +// Google Test. They are subject to change without notice. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_ + +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: wan@google.com (Zhanyong Wan) +// +// Low-level types and utilities for porting Google Test to various +// platforms. They are subject to change without notice. DO NOT USE +// THEM IN USER CODE. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_ + +// The user can define the following macros in the build script to +// control Google Test's behavior. If the user doesn't define a macro +// in this list, Google Test will define it. +// +// GTEST_HAS_CLONE - Define it to 1/0 to indicate that clone(2) +// is/isn't available. +// GTEST_HAS_EXCEPTIONS - Define it to 1/0 to indicate that exceptions +// are enabled. +// GTEST_HAS_GLOBAL_STRING - Define it to 1/0 to indicate that ::string +// is/isn't available (some systems define +// ::string, which is different to std::string). +// GTEST_HAS_GLOBAL_WSTRING - Define it to 1/0 to indicate that ::string +// is/isn't available (some systems define +// ::wstring, which is different to std::wstring). +// GTEST_HAS_PTHREAD - Define it to 1/0 to indicate that +// is/isn't available. +// GTEST_HAS_RTTI - Define it to 1/0 to indicate that RTTI is/isn't +// enabled. +// GTEST_HAS_STD_WSTRING - Define it to 1/0 to indicate that +// std::wstring does/doesn't work (Google Test can +// be used where std::wstring is unavailable). +// GTEST_HAS_TR1_TUPLE - Define it to 1/0 to indicate tr1::tuple +// is/isn't available. +// GTEST_HAS_SEH - Define it to 1/0 to indicate whether the +// compiler supports Microsoft's "Structured +// Exception Handling". +// GTEST_USE_OWN_TR1_TUPLE - Define it to 1/0 to indicate whether Google +// Test's own tr1 tuple implementation should be +// used. Unused when the user sets +// GTEST_HAS_TR1_TUPLE to 0. +// GTEST_LINKED_AS_SHARED_LIBRARY +// - Define to 1 when compiling tests that use +// Google Test as a shared library (known as +// DLL on Windows). +// GTEST_CREATE_SHARED_LIBRARY +// - Define to 1 when compiling Google Test itself +// as a shared library. + +// This header defines the following utilities: +// +// Macros indicating the current platform (defined to 1 if compiled on +// the given platform; otherwise undefined): +// GTEST_OS_AIX - IBM AIX +// GTEST_OS_CYGWIN - Cygwin +// GTEST_OS_LINUX - Linux +// GTEST_OS_MAC - Mac OS X +// GTEST_OS_SOLARIS - Sun Solaris +// GTEST_OS_SYMBIAN - Symbian +// GTEST_OS_WINDOWS - Windows (Desktop, MinGW, or Mobile) +// GTEST_OS_WINDOWS_DESKTOP - Windows Desktop +// GTEST_OS_WINDOWS_MINGW - MinGW +// GTEST_OS_WINDOWS_MOBILE - Windows Mobile +// GTEST_OS_ZOS - z/OS +// +// Among the platforms, Cygwin, Linux, Max OS X, and Windows have the +// most stable support. Since core members of the Google Test project +// don't have access to other platforms, support for them may be less +// stable. If you notice any problems on your platform, please notify +// googletestframework@googlegroups.com (patches for fixing them are +// even more welcome!). +// +// Note that it is possible that none of the GTEST_OS_* macros are defined. +// +// Macros indicating available Google Test features (defined to 1 if +// the corresponding feature is supported; otherwise undefined): +// GTEST_HAS_COMBINE - the Combine() function (for value-parameterized +// tests) +// GTEST_HAS_DEATH_TEST - death tests +// GTEST_HAS_PARAM_TEST - value-parameterized tests +// GTEST_HAS_TYPED_TEST - typed tests +// GTEST_HAS_TYPED_TEST_P - type-parameterized tests +// GTEST_USES_POSIX_RE - enhanced POSIX regex is used. +// GTEST_USES_SIMPLE_RE - our own simple regex is used; +// the above two are mutually exclusive. +// GTEST_CAN_COMPARE_NULL - accepts untyped NULL in EXPECT_EQ(). +// +// Macros for basic C++ coding: +// GTEST_AMBIGUOUS_ELSE_BLOCKER_ - for disabling a gcc warning. +// GTEST_ATTRIBUTE_UNUSED_ - declares that a class' instances or a +// variable don't have to be used. +// GTEST_DISALLOW_ASSIGN_ - disables operator=. +// GTEST_DISALLOW_COPY_AND_ASSIGN_ - disables copy ctor and operator=. +// GTEST_MUST_USE_RESULT_ - declares that a function's result must be used. +// +// Synchronization: +// Mutex, MutexLock, ThreadLocal, GetThreadCount() +// - synchronization primitives. +// GTEST_IS_THREADSAFE - defined to 1 to indicate that the above +// synchronization primitives have real implementations +// and Google Test is thread-safe; or 0 otherwise. +// +// Template meta programming: +// is_pointer - as in TR1; needed on Symbian and IBM XL C/C++ only. +// +// Smart pointers: +// scoped_ptr - as in TR2. +// +// Regular expressions: +// RE - a simple regular expression class using the POSIX +// Extended Regular Expression syntax. Not available on +// Windows. +// +// Logging: +// GTEST_LOG_() - logs messages at the specified severity level. +// LogToStderr() - directs all log messages to stderr. +// FlushInfoLog() - flushes informational log messages. +// +// Stdout and stderr capturing: +// CaptureStdout() - starts capturing stdout. +// GetCapturedStdout() - stops capturing stdout and returns the captured +// string. +// CaptureStderr() - starts capturing stderr. +// GetCapturedStderr() - stops capturing stderr and returns the captured +// string. +// +// Integer types: +// TypeWithSize - maps an integer to a int type. +// Int32, UInt32, Int64, UInt64, TimeInMillis +// - integers of known sizes. +// BiggestInt - the biggest signed integer type. +// +// Command-line utilities: +// GTEST_FLAG() - references a flag. +// GTEST_DECLARE_*() - declares a flag. +// GTEST_DEFINE_*() - defines a flag. +// GetArgvs() - returns the command line as a vector of strings. +// +// Environment variable utilities: +// GetEnv() - gets the value of an environment variable. +// BoolFromGTestEnv() - parses a bool environment variable. +// Int32FromGTestEnv() - parses an Int32 environment variable. +// StringFromGTestEnv() - parses a string environment variable. + +#include // For ptrdiff_t +#include +#include +#include +#ifndef _WIN32_WCE +#include +#endif // !_WIN32_WCE + +#include // NOLINT +#include // NOLINT +#include // NOLINT + +#define GTEST_DEV_EMAIL_ "googletestframework@@googlegroups.com" +#define GTEST_FLAG_PREFIX_ "gtest_" +#define GTEST_FLAG_PREFIX_DASH_ "gtest-" +#define GTEST_FLAG_PREFIX_UPPER_ "GTEST_" +#define GTEST_NAME_ "Google Test" +#define GTEST_PROJECT_URL_ "http://code.google.com/p/googletest/" + +// Determines the version of gcc that is used to compile this. +#ifdef __GNUC__ +// 40302 means version 4.3.2. +#define GTEST_GCC_VER_ \ + (__GNUC__*10000 + __GNUC_MINOR__*100 + __GNUC_PATCHLEVEL__) +#endif // __GNUC__ + +// Determines the platform on which Google Test is compiled. +#ifdef __CYGWIN__ +#define GTEST_OS_CYGWIN 1 +#elif defined __SYMBIAN32__ +#define GTEST_OS_SYMBIAN 1 +#elif defined _WIN32 +#define GTEST_OS_WINDOWS 1 +#ifdef _WIN32_WCE +#define GTEST_OS_WINDOWS_MOBILE 1 +#elif defined(__MINGW__) || defined(__MINGW32__) +#define GTEST_OS_WINDOWS_MINGW 1 +#else +#define GTEST_OS_WINDOWS_DESKTOP 1 +#endif // _WIN32_WCE +#elif defined __APPLE__ +#define GTEST_OS_MAC 1 +#elif defined __linux__ +#define GTEST_OS_LINUX 1 +#elif defined __MVS__ +#define GTEST_OS_ZOS 1 +#elif defined(__sun) && defined(__SVR4) +#define GTEST_OS_SOLARIS 1 +#elif defined(_AIX) +#define GTEST_OS_AIX 1 +#endif // __CYGWIN__ + +#if GTEST_OS_CYGWIN || GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_SYMBIAN || \ + GTEST_OS_SOLARIS || GTEST_OS_AIX + +// On some platforms, needs someone to define size_t, and +// won't compile otherwise. We can #include it here as we already +// included , which is guaranteed to define size_t through +// . +#include // NOLINT +#include // NOLINT +#include // NOLINT +#include // NOLINT +#include // NOLINT + +#define GTEST_USES_POSIX_RE 1 + +#elif GTEST_OS_WINDOWS + +#if !GTEST_OS_WINDOWS_MOBILE +#include // NOLINT +#include // NOLINT +#endif + +// is not available on Windows. Use our own simple regex +// implementation instead. +#define GTEST_USES_SIMPLE_RE 1 + +#else + +// may not be available on this platform. Use our own +// simple regex implementation instead. +#define GTEST_USES_SIMPLE_RE 1 + +#endif // GTEST_OS_CYGWIN || GTEST_OS_LINUX || GTEST_OS_MAC || + // GTEST_OS_SYMBIAN || GTEST_OS_SOLARIS || GTEST_OS_AIX + +#ifndef GTEST_HAS_EXCEPTIONS +// The user didn't tell us whether exceptions are enabled, so we need +// to figure it out. +#if defined(_MSC_VER) || defined(__BORLANDC__) +// MSVC's and C++Builder's implementations of the STL use the _HAS_EXCEPTIONS +// macro to enable exceptions, so we'll do the same. +// Assumes that exceptions are enabled by default. +#ifndef _HAS_EXCEPTIONS +#define _HAS_EXCEPTIONS 1 +#endif // _HAS_EXCEPTIONS +#define GTEST_HAS_EXCEPTIONS _HAS_EXCEPTIONS +#elif defined(__GNUC__) && __EXCEPTIONS +// gcc defines __EXCEPTIONS to 1 iff exceptions are enabled. +#define GTEST_HAS_EXCEPTIONS 1 +#elif defined(__SUNPRO_CC) +// Sun Pro CC supports exceptions. However, there is no compile-time way of +// detecting whether they are enabled or not. Therefore, we assume that +// they are enabled unless the user tells us otherwise. +#define GTEST_HAS_EXCEPTIONS 1 +#elif defined(__IBMCPP__) && __EXCEPTIONS +// xlC defines __EXCEPTIONS to 1 iff exceptions are enabled. +#define GTEST_HAS_EXCEPTIONS 1 +#else +// For other compilers, we assume exceptions are disabled to be +// conservative. +#define GTEST_HAS_EXCEPTIONS 0 +#endif // defined(_MSC_VER) || defined(__BORLANDC__) +#endif // GTEST_HAS_EXCEPTIONS + +#if !defined(GTEST_HAS_STD_STRING) +// Even though we don't use this macro any longer, we keep it in case +// some clients still depend on it. +#define GTEST_HAS_STD_STRING 1 +#elif !GTEST_HAS_STD_STRING +// The user told us that ::std::string isn't available. +#error "Google Test cannot be used where ::std::string isn't available." +#endif // !defined(GTEST_HAS_STD_STRING) + +#ifndef GTEST_HAS_GLOBAL_STRING +// The user didn't tell us whether ::string is available, so we need +// to figure it out. + +#define GTEST_HAS_GLOBAL_STRING 0 + +#endif // GTEST_HAS_GLOBAL_STRING + +#ifndef GTEST_HAS_STD_WSTRING +// The user didn't tell us whether ::std::wstring is available, so we need +// to figure it out. +// TODO(wan@google.com): uses autoconf to detect whether ::std::wstring +// is available. + +// Cygwin 1.5 and below doesn't support ::std::wstring. +// Cygwin 1.7 might add wstring support; this should be updated when clear. +// Solaris' libc++ doesn't support it either. +#define GTEST_HAS_STD_WSTRING (!(GTEST_OS_CYGWIN || GTEST_OS_SOLARIS)) + +#endif // GTEST_HAS_STD_WSTRING + +#ifndef GTEST_HAS_GLOBAL_WSTRING +// The user didn't tell us whether ::wstring is available, so we need +// to figure it out. +#define GTEST_HAS_GLOBAL_WSTRING \ + (GTEST_HAS_STD_WSTRING && GTEST_HAS_GLOBAL_STRING) +#endif // GTEST_HAS_GLOBAL_WSTRING + +// Determines whether RTTI is available. +#ifndef GTEST_HAS_RTTI +// The user didn't tell us whether RTTI is enabled, so we need to +// figure it out. + +#ifdef _MSC_VER + +#ifdef _CPPRTTI // MSVC defines this macro iff RTTI is enabled. +#define GTEST_HAS_RTTI 1 +#else +#define GTEST_HAS_RTTI 0 +#endif + +// Starting with version 4.3.2, gcc defines __GXX_RTTI iff RTTI is enabled. +#elif defined(__GNUC__) && (GTEST_GCC_VER_ >= 40302) + +#ifdef __GXX_RTTI +#define GTEST_HAS_RTTI 1 +#else +#define GTEST_HAS_RTTI 0 +#endif // __GXX_RTTI + +// Starting with version 9.0 IBM Visual Age defines __RTTI_ALL__ to 1 if +// both the typeid and dynamic_cast features are present. +#elif defined(__IBMCPP__) && (__IBMCPP__ >= 900) + +#ifdef __RTTI_ALL__ +#define GTEST_HAS_RTTI 1 +#else +#define GTEST_HAS_RTTI 0 +#endif + +#else + +// For all other compilers, we assume RTTI is enabled. +#define GTEST_HAS_RTTI 1 + +#endif // _MSC_VER + +#endif // GTEST_HAS_RTTI + +// It's this header's responsibility to #include when RTTI +// is enabled. +#if GTEST_HAS_RTTI +#include +#endif + +// Determines whether Google Test can use the pthreads library. +#ifndef GTEST_HAS_PTHREAD +// The user didn't tell us explicitly, so we assume pthreads support is +// available on Linux and Mac. +// +// To disable threading support in Google Test, add -DGTEST_HAS_PTHREAD=0 +// to your compiler flags. +#define GTEST_HAS_PTHREAD (GTEST_OS_LINUX || GTEST_OS_MAC) +#endif // GTEST_HAS_PTHREAD + +// Determines whether Google Test can use tr1/tuple. You can define +// this macro to 0 to prevent Google Test from using tuple (any +// feature depending on tuple with be disabled in this mode). +#ifndef GTEST_HAS_TR1_TUPLE +// The user didn't tell us not to do it, so we assume it's OK. +#define GTEST_HAS_TR1_TUPLE 1 +#endif // GTEST_HAS_TR1_TUPLE + +// Determines whether Google Test's own tr1 tuple implementation +// should be used. +#ifndef GTEST_USE_OWN_TR1_TUPLE +// The user didn't tell us, so we need to figure it out. + +// We use our own TR1 tuple if we aren't sure the user has an +// implementation of it already. At this time, GCC 4.0.0+ and MSVC +// 2010 are the only mainstream compilers that come with a TR1 tuple +// implementation. NVIDIA's CUDA NVCC compiler pretends to be GCC by +// defining __GNUC__ and friends, but cannot compile GCC's tuple +// implementation. MSVC 2008 (9.0) provides TR1 tuple in a 323 MB +// Feature Pack download, which we cannot assume the user has. +#if (defined(__GNUC__) && !defined(__CUDACC__) && (GTEST_GCC_VER_ >= 40000)) \ + || _MSC_VER >= 1600 +#define GTEST_USE_OWN_TR1_TUPLE 0 +#else +#define GTEST_USE_OWN_TR1_TUPLE 1 +#endif + +#endif // GTEST_USE_OWN_TR1_TUPLE + +// To avoid conditional compilation everywhere, we make it +// gtest-port.h's responsibility to #include the header implementing +// tr1/tuple. +#if GTEST_HAS_TR1_TUPLE + +#if GTEST_USE_OWN_TR1_TUPLE +// This file was GENERATED by a script. DO NOT EDIT BY HAND!!! + +// Copyright 2009 Google Inc. +// All Rights Reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: wan@google.com (Zhanyong Wan) + +// Implements a subset of TR1 tuple needed by Google Test and Google Mock. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_ + +#include // For ::std::pair. + +// The compiler used in Symbian has a bug that prevents us from declaring the +// tuple template as a friend (it complains that tuple is redefined). This +// hack bypasses the bug by declaring the members that should otherwise be +// private as public. +// Sun Studio versions < 12 also have the above bug. +#if defined(__SYMBIAN32__) || (defined(__SUNPRO_CC) && __SUNPRO_CC < 0x590) +#define GTEST_DECLARE_TUPLE_AS_FRIEND_ public: +#else +#define GTEST_DECLARE_TUPLE_AS_FRIEND_ \ + template friend class tuple; \ + private: +#endif + +// GTEST_n_TUPLE_(T) is the type of an n-tuple. +#define GTEST_0_TUPLE_(T) tuple<> +#define GTEST_1_TUPLE_(T) tuple +#define GTEST_2_TUPLE_(T) tuple +#define GTEST_3_TUPLE_(T) tuple +#define GTEST_4_TUPLE_(T) tuple +#define GTEST_5_TUPLE_(T) tuple +#define GTEST_6_TUPLE_(T) tuple +#define GTEST_7_TUPLE_(T) tuple +#define GTEST_8_TUPLE_(T) tuple +#define GTEST_9_TUPLE_(T) tuple +#define GTEST_10_TUPLE_(T) tuple + +// GTEST_n_TYPENAMES_(T) declares a list of n typenames. +#define GTEST_0_TYPENAMES_(T) +#define GTEST_1_TYPENAMES_(T) typename T##0 +#define GTEST_2_TYPENAMES_(T) typename T##0, typename T##1 +#define GTEST_3_TYPENAMES_(T) typename T##0, typename T##1, typename T##2 +#define GTEST_4_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ + typename T##3 +#define GTEST_5_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ + typename T##3, typename T##4 +#define GTEST_6_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ + typename T##3, typename T##4, typename T##5 +#define GTEST_7_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ + typename T##3, typename T##4, typename T##5, typename T##6 +#define GTEST_8_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ + typename T##3, typename T##4, typename T##5, typename T##6, typename T##7 +#define GTEST_9_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ + typename T##3, typename T##4, typename T##5, typename T##6, \ + typename T##7, typename T##8 +#define GTEST_10_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ + typename T##3, typename T##4, typename T##5, typename T##6, \ + typename T##7, typename T##8, typename T##9 + +// In theory, defining stuff in the ::std namespace is undefined +// behavior. We can do this as we are playing the role of a standard +// library vendor. +namespace std { +namespace tr1 { + +template +class tuple; + +// Anything in namespace gtest_internal is Google Test's INTERNAL +// IMPLEMENTATION DETAIL and MUST NOT BE USED DIRECTLY in user code. +namespace gtest_internal { + +// ByRef::type is T if T is a reference; otherwise it's const T&. +template +struct ByRef { typedef const T& type; }; // NOLINT +template +struct ByRef { typedef T& type; }; // NOLINT + +// A handy wrapper for ByRef. +#define GTEST_BY_REF_(T) typename ::std::tr1::gtest_internal::ByRef::type + +// AddRef::type is T if T is a reference; otherwise it's T&. This +// is the same as tr1::add_reference::type. +template +struct AddRef { typedef T& type; }; // NOLINT +template +struct AddRef { typedef T& type; }; // NOLINT + +// A handy wrapper for AddRef. +#define GTEST_ADD_REF_(T) typename ::std::tr1::gtest_internal::AddRef::type + +// A helper for implementing get(). +template class Get; + +// A helper for implementing tuple_element. kIndexValid is true +// iff k < the number of fields in tuple type T. +template +struct TupleElement; + +template +struct TupleElement { typedef T0 type; }; + +template +struct TupleElement { typedef T1 type; }; + +template +struct TupleElement { typedef T2 type; }; + +template +struct TupleElement { typedef T3 type; }; + +template +struct TupleElement { typedef T4 type; }; + +template +struct TupleElement { typedef T5 type; }; + +template +struct TupleElement { typedef T6 type; }; + +template +struct TupleElement { typedef T7 type; }; + +template +struct TupleElement { typedef T8 type; }; + +template +struct TupleElement { typedef T9 type; }; + +} // namespace gtest_internal + +template <> +class tuple<> { + public: + tuple() {} + tuple(const tuple& /* t */) {} + tuple& operator=(const tuple& /* t */) { return *this; } +}; + +template +class GTEST_1_TUPLE_(T) { + public: + template friend class gtest_internal::Get; + + tuple() : f0_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0) : f0_(f0) {} + + tuple(const tuple& t) : f0_(t.f0_) {} + + template + tuple(const GTEST_1_TUPLE_(U)& t) : f0_(t.f0_) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template + tuple& operator=(const GTEST_1_TUPLE_(U)& t) { + return CopyFrom(t); + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template + tuple& CopyFrom(const GTEST_1_TUPLE_(U)& t) { + f0_ = t.f0_; + return *this; + } + + T0 f0_; +}; + +template +class GTEST_2_TUPLE_(T) { + public: + template friend class gtest_internal::Get; + + tuple() : f0_(), f1_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1) : f0_(f0), + f1_(f1) {} + + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_) {} + + template + tuple(const GTEST_2_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_) {} + template + tuple(const ::std::pair& p) : f0_(p.first), f1_(p.second) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template + tuple& operator=(const GTEST_2_TUPLE_(U)& t) { + return CopyFrom(t); + } + template + tuple& operator=(const ::std::pair& p) { + f0_ = p.first; + f1_ = p.second; + return *this; + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template + tuple& CopyFrom(const GTEST_2_TUPLE_(U)& t) { + f0_ = t.f0_; + f1_ = t.f1_; + return *this; + } + + T0 f0_; + T1 f1_; +}; + +template +class GTEST_3_TUPLE_(T) { + public: + template friend class gtest_internal::Get; + + tuple() : f0_(), f1_(), f2_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, + GTEST_BY_REF_(T2) f2) : f0_(f0), f1_(f1), f2_(f2) {} + + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_) {} + + template + tuple(const GTEST_3_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template + tuple& operator=(const GTEST_3_TUPLE_(U)& t) { + return CopyFrom(t); + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template + tuple& CopyFrom(const GTEST_3_TUPLE_(U)& t) { + f0_ = t.f0_; + f1_ = t.f1_; + f2_ = t.f2_; + return *this; + } + + T0 f0_; + T1 f1_; + T2 f2_; +}; + +template +class GTEST_4_TUPLE_(T) { + public: + template friend class gtest_internal::Get; + + tuple() : f0_(), f1_(), f2_(), f3_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, + GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3) : f0_(f0), f1_(f1), f2_(f2), + f3_(f3) {} + + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_) {} + + template + tuple(const GTEST_4_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), + f3_(t.f3_) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template + tuple& operator=(const GTEST_4_TUPLE_(U)& t) { + return CopyFrom(t); + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template + tuple& CopyFrom(const GTEST_4_TUPLE_(U)& t) { + f0_ = t.f0_; + f1_ = t.f1_; + f2_ = t.f2_; + f3_ = t.f3_; + return *this; + } + + T0 f0_; + T1 f1_; + T2 f2_; + T3 f3_; +}; + +template +class GTEST_5_TUPLE_(T) { + public: + template friend class gtest_internal::Get; + + tuple() : f0_(), f1_(), f2_(), f3_(), f4_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, + GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, + GTEST_BY_REF_(T4) f4) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4) {} + + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), + f4_(t.f4_) {} + + template + tuple(const GTEST_5_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), + f3_(t.f3_), f4_(t.f4_) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template + tuple& operator=(const GTEST_5_TUPLE_(U)& t) { + return CopyFrom(t); + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template + tuple& CopyFrom(const GTEST_5_TUPLE_(U)& t) { + f0_ = t.f0_; + f1_ = t.f1_; + f2_ = t.f2_; + f3_ = t.f3_; + f4_ = t.f4_; + return *this; + } + + T0 f0_; + T1 f1_; + T2 f2_; + T3 f3_; + T4 f4_; +}; + +template +class GTEST_6_TUPLE_(T) { + public: + template friend class gtest_internal::Get; + + tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, + GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4, + GTEST_BY_REF_(T5) f5) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4), + f5_(f5) {} + + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), + f4_(t.f4_), f5_(t.f5_) {} + + template + tuple(const GTEST_6_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), + f3_(t.f3_), f4_(t.f4_), f5_(t.f5_) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template + tuple& operator=(const GTEST_6_TUPLE_(U)& t) { + return CopyFrom(t); + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template + tuple& CopyFrom(const GTEST_6_TUPLE_(U)& t) { + f0_ = t.f0_; + f1_ = t.f1_; + f2_ = t.f2_; + f3_ = t.f3_; + f4_ = t.f4_; + f5_ = t.f5_; + return *this; + } + + T0 f0_; + T1 f1_; + T2 f2_; + T3 f3_; + T4 f4_; + T5 f5_; +}; + +template +class GTEST_7_TUPLE_(T) { + public: + template friend class gtest_internal::Get; + + tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, + GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4, + GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6) : f0_(f0), f1_(f1), f2_(f2), + f3_(f3), f4_(f4), f5_(f5), f6_(f6) {} + + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), + f4_(t.f4_), f5_(t.f5_), f6_(t.f6_) {} + + template + tuple(const GTEST_7_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), + f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template + tuple& operator=(const GTEST_7_TUPLE_(U)& t) { + return CopyFrom(t); + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template + tuple& CopyFrom(const GTEST_7_TUPLE_(U)& t) { + f0_ = t.f0_; + f1_ = t.f1_; + f2_ = t.f2_; + f3_ = t.f3_; + f4_ = t.f4_; + f5_ = t.f5_; + f6_ = t.f6_; + return *this; + } + + T0 f0_; + T1 f1_; + T2 f2_; + T3 f3_; + T4 f4_; + T5 f5_; + T6 f6_; +}; + +template +class GTEST_8_TUPLE_(T) { + public: + template friend class gtest_internal::Get; + + tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_(), f7_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, + GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4, + GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6, + GTEST_BY_REF_(T7) f7) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4), + f5_(f5), f6_(f6), f7_(f7) {} + + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), + f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_) {} + + template + tuple(const GTEST_8_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), + f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template + tuple& operator=(const GTEST_8_TUPLE_(U)& t) { + return CopyFrom(t); + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template + tuple& CopyFrom(const GTEST_8_TUPLE_(U)& t) { + f0_ = t.f0_; + f1_ = t.f1_; + f2_ = t.f2_; + f3_ = t.f3_; + f4_ = t.f4_; + f5_ = t.f5_; + f6_ = t.f6_; + f7_ = t.f7_; + return *this; + } + + T0 f0_; + T1 f1_; + T2 f2_; + T3 f3_; + T4 f4_; + T5 f5_; + T6 f6_; + T7 f7_; +}; + +template +class GTEST_9_TUPLE_(T) { + public: + template friend class gtest_internal::Get; + + tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_(), f7_(), f8_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, + GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4, + GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6, GTEST_BY_REF_(T7) f7, + GTEST_BY_REF_(T8) f8) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4), + f5_(f5), f6_(f6), f7_(f7), f8_(f8) {} + + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), + f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_) {} + + template + tuple(const GTEST_9_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), + f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template + tuple& operator=(const GTEST_9_TUPLE_(U)& t) { + return CopyFrom(t); + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template + tuple& CopyFrom(const GTEST_9_TUPLE_(U)& t) { + f0_ = t.f0_; + f1_ = t.f1_; + f2_ = t.f2_; + f3_ = t.f3_; + f4_ = t.f4_; + f5_ = t.f5_; + f6_ = t.f6_; + f7_ = t.f7_; + f8_ = t.f8_; + return *this; + } + + T0 f0_; + T1 f1_; + T2 f2_; + T3 f3_; + T4 f4_; + T5 f5_; + T6 f6_; + T7 f7_; + T8 f8_; +}; + +template +class tuple { + public: + template friend class gtest_internal::Get; + + tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_(), f7_(), f8_(), + f9_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, + GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4, + GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6, GTEST_BY_REF_(T7) f7, + GTEST_BY_REF_(T8) f8, GTEST_BY_REF_(T9) f9) : f0_(f0), f1_(f1), f2_(f2), + f3_(f3), f4_(f4), f5_(f5), f6_(f6), f7_(f7), f8_(f8), f9_(f9) {} + + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), + f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_), f9_(t.f9_) {} + + template + tuple(const GTEST_10_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), + f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_), + f9_(t.f9_) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template + tuple& operator=(const GTEST_10_TUPLE_(U)& t) { + return CopyFrom(t); + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template + tuple& CopyFrom(const GTEST_10_TUPLE_(U)& t) { + f0_ = t.f0_; + f1_ = t.f1_; + f2_ = t.f2_; + f3_ = t.f3_; + f4_ = t.f4_; + f5_ = t.f5_; + f6_ = t.f6_; + f7_ = t.f7_; + f8_ = t.f8_; + f9_ = t.f9_; + return *this; + } + + T0 f0_; + T1 f1_; + T2 f2_; + T3 f3_; + T4 f4_; + T5 f5_; + T6 f6_; + T7 f7_; + T8 f8_; + T9 f9_; +}; + +// 6.1.3.2 Tuple creation functions. + +// Known limitations: we don't support passing an +// std::tr1::reference_wrapper to make_tuple(). And we don't +// implement tie(). + +inline tuple<> make_tuple() { return tuple<>(); } + +template +inline GTEST_1_TUPLE_(T) make_tuple(const T0& f0) { + return GTEST_1_TUPLE_(T)(f0); +} + +template +inline GTEST_2_TUPLE_(T) make_tuple(const T0& f0, const T1& f1) { + return GTEST_2_TUPLE_(T)(f0, f1); +} + +template +inline GTEST_3_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2) { + return GTEST_3_TUPLE_(T)(f0, f1, f2); +} + +template +inline GTEST_4_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, + const T3& f3) { + return GTEST_4_TUPLE_(T)(f0, f1, f2, f3); +} + +template +inline GTEST_5_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, + const T3& f3, const T4& f4) { + return GTEST_5_TUPLE_(T)(f0, f1, f2, f3, f4); +} + +template +inline GTEST_6_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, + const T3& f3, const T4& f4, const T5& f5) { + return GTEST_6_TUPLE_(T)(f0, f1, f2, f3, f4, f5); +} + +template +inline GTEST_7_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, + const T3& f3, const T4& f4, const T5& f5, const T6& f6) { + return GTEST_7_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6); +} + +template +inline GTEST_8_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, + const T3& f3, const T4& f4, const T5& f5, const T6& f6, const T7& f7) { + return GTEST_8_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6, f7); +} + +template +inline GTEST_9_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, + const T3& f3, const T4& f4, const T5& f5, const T6& f6, const T7& f7, + const T8& f8) { + return GTEST_9_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6, f7, f8); +} + +template +inline GTEST_10_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, + const T3& f3, const T4& f4, const T5& f5, const T6& f6, const T7& f7, + const T8& f8, const T9& f9) { + return GTEST_10_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6, f7, f8, f9); +} + +// 6.1.3.3 Tuple helper classes. + +template struct tuple_size; + +template +struct tuple_size { static const int value = 0; }; + +template +struct tuple_size { static const int value = 1; }; + +template +struct tuple_size { static const int value = 2; }; + +template +struct tuple_size { static const int value = 3; }; + +template +struct tuple_size { static const int value = 4; }; + +template +struct tuple_size { static const int value = 5; }; + +template +struct tuple_size { static const int value = 6; }; + +template +struct tuple_size { static const int value = 7; }; + +template +struct tuple_size { static const int value = 8; }; + +template +struct tuple_size { static const int value = 9; }; + +template +struct tuple_size { static const int value = 10; }; + +template +struct tuple_element { + typedef typename gtest_internal::TupleElement< + k < (tuple_size::value), k, Tuple>::type type; +}; + +#define GTEST_TUPLE_ELEMENT_(k, Tuple) typename tuple_element::type + +// 6.1.3.4 Element access. + +namespace gtest_internal { + +template <> +class Get<0> { + public: + template + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(0, Tuple)) + Field(Tuple& t) { return t.f0_; } // NOLINT + + template + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(0, Tuple)) + ConstField(const Tuple& t) { return t.f0_; } +}; + +template <> +class Get<1> { + public: + template + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(1, Tuple)) + Field(Tuple& t) { return t.f1_; } // NOLINT + + template + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(1, Tuple)) + ConstField(const Tuple& t) { return t.f1_; } +}; + +template <> +class Get<2> { + public: + template + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(2, Tuple)) + Field(Tuple& t) { return t.f2_; } // NOLINT + + template + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(2, Tuple)) + ConstField(const Tuple& t) { return t.f2_; } +}; + +template <> +class Get<3> { + public: + template + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(3, Tuple)) + Field(Tuple& t) { return t.f3_; } // NOLINT + + template + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(3, Tuple)) + ConstField(const Tuple& t) { return t.f3_; } +}; + +template <> +class Get<4> { + public: + template + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(4, Tuple)) + Field(Tuple& t) { return t.f4_; } // NOLINT + + template + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(4, Tuple)) + ConstField(const Tuple& t) { return t.f4_; } +}; + +template <> +class Get<5> { + public: + template + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(5, Tuple)) + Field(Tuple& t) { return t.f5_; } // NOLINT + + template + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(5, Tuple)) + ConstField(const Tuple& t) { return t.f5_; } +}; + +template <> +class Get<6> { + public: + template + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(6, Tuple)) + Field(Tuple& t) { return t.f6_; } // NOLINT + + template + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(6, Tuple)) + ConstField(const Tuple& t) { return t.f6_; } +}; + +template <> +class Get<7> { + public: + template + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(7, Tuple)) + Field(Tuple& t) { return t.f7_; } // NOLINT + + template + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(7, Tuple)) + ConstField(const Tuple& t) { return t.f7_; } +}; + +template <> +class Get<8> { + public: + template + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(8, Tuple)) + Field(Tuple& t) { return t.f8_; } // NOLINT + + template + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(8, Tuple)) + ConstField(const Tuple& t) { return t.f8_; } +}; + +template <> +class Get<9> { + public: + template + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(9, Tuple)) + Field(Tuple& t) { return t.f9_; } // NOLINT + + template + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(9, Tuple)) + ConstField(const Tuple& t) { return t.f9_; } +}; + +} // namespace gtest_internal + +template +GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_10_TUPLE_(T))) +get(GTEST_10_TUPLE_(T)& t) { + return gtest_internal::Get::Field(t); +} + +template +GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_10_TUPLE_(T))) +get(const GTEST_10_TUPLE_(T)& t) { + return gtest_internal::Get::ConstField(t); +} + +// 6.1.3.5 Relational operators + +// We only implement == and !=, as we don't have a need for the rest yet. + +namespace gtest_internal { + +// SameSizeTuplePrefixComparator::Eq(t1, t2) returns true if the +// first k fields of t1 equals the first k fields of t2. +// SameSizeTuplePrefixComparator(k1, k2) would be a compiler error if +// k1 != k2. +template +struct SameSizeTuplePrefixComparator; + +template <> +struct SameSizeTuplePrefixComparator<0, 0> { + template + static bool Eq(const Tuple1& /* t1 */, const Tuple2& /* t2 */) { + return true; + } +}; + +template +struct SameSizeTuplePrefixComparator { + template + static bool Eq(const Tuple1& t1, const Tuple2& t2) { + return SameSizeTuplePrefixComparator::Eq(t1, t2) && + ::std::tr1::get(t1) == ::std::tr1::get(t2); + } +}; + +} // namespace gtest_internal + +template +inline bool operator==(const GTEST_10_TUPLE_(T)& t, + const GTEST_10_TUPLE_(U)& u) { + return gtest_internal::SameSizeTuplePrefixComparator< + tuple_size::value, + tuple_size::value>::Eq(t, u); +} + +template +inline bool operator!=(const GTEST_10_TUPLE_(T)& t, + const GTEST_10_TUPLE_(U)& u) { return !(t == u); } + +// 6.1.4 Pairs. +// Unimplemented. + +} // namespace tr1 +} // namespace std + +#undef GTEST_0_TUPLE_ +#undef GTEST_1_TUPLE_ +#undef GTEST_2_TUPLE_ +#undef GTEST_3_TUPLE_ +#undef GTEST_4_TUPLE_ +#undef GTEST_5_TUPLE_ +#undef GTEST_6_TUPLE_ +#undef GTEST_7_TUPLE_ +#undef GTEST_8_TUPLE_ +#undef GTEST_9_TUPLE_ +#undef GTEST_10_TUPLE_ + +#undef GTEST_0_TYPENAMES_ +#undef GTEST_1_TYPENAMES_ +#undef GTEST_2_TYPENAMES_ +#undef GTEST_3_TYPENAMES_ +#undef GTEST_4_TYPENAMES_ +#undef GTEST_5_TYPENAMES_ +#undef GTEST_6_TYPENAMES_ +#undef GTEST_7_TYPENAMES_ +#undef GTEST_8_TYPENAMES_ +#undef GTEST_9_TYPENAMES_ +#undef GTEST_10_TYPENAMES_ + +#undef GTEST_DECLARE_TUPLE_AS_FRIEND_ +#undef GTEST_BY_REF_ +#undef GTEST_ADD_REF_ +#undef GTEST_TUPLE_ELEMENT_ + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_ +#elif GTEST_OS_SYMBIAN + +// On Symbian, BOOST_HAS_TR1_TUPLE causes Boost's TR1 tuple library to +// use STLport's tuple implementation, which unfortunately doesn't +// work as the copy of STLport distributed with Symbian is incomplete. +// By making sure BOOST_HAS_TR1_TUPLE is undefined, we force Boost to +// use its own tuple implementation. +#ifdef BOOST_HAS_TR1_TUPLE +#undef BOOST_HAS_TR1_TUPLE +#endif // BOOST_HAS_TR1_TUPLE + +// This prevents , which defines +// BOOST_HAS_TR1_TUPLE, from being #included by Boost's . +#define BOOST_TR1_DETAIL_CONFIG_HPP_INCLUDED +#include + +#elif defined(__GNUC__) && (GTEST_GCC_VER_ >= 40000) +// GCC 4.0+ implements tr1/tuple in the header. This does +// not conform to the TR1 spec, which requires the header to be . + +#if !GTEST_HAS_RTTI && GTEST_GCC_VER_ < 40302 +// Until version 4.3.2, gcc has a bug that causes , +// which is #included by , to not compile when RTTI is +// disabled. _TR1_FUNCTIONAL is the header guard for +// . Hence the following #define is a hack to prevent +// from being included. +#define _TR1_FUNCTIONAL 1 +#include +#undef _TR1_FUNCTIONAL // Allows the user to #include + // if he chooses to. +#else +#include // NOLINT +#endif // !GTEST_HAS_RTTI && GTEST_GCC_VER_ < 40302 + +#else +// If the compiler is not GCC 4.0+, we assume the user is using a +// spec-conforming TR1 implementation. +#include // NOLINT +#endif // GTEST_USE_OWN_TR1_TUPLE + +#endif // GTEST_HAS_TR1_TUPLE + +// Determines whether clone(2) is supported. +// Usually it will only be available on Linux, excluding +// Linux on the Itanium architecture. +// Also see http://linux.die.net/man/2/clone. +#ifndef GTEST_HAS_CLONE +// The user didn't tell us, so we need to figure it out. + +#if GTEST_OS_LINUX && !defined(__ia64__) +#define GTEST_HAS_CLONE 1 +#else +#define GTEST_HAS_CLONE 0 +#endif // GTEST_OS_LINUX && !defined(__ia64__) + +#endif // GTEST_HAS_CLONE + +// Determines whether to support stream redirection. This is used to test +// output correctness and to implement death tests. +#if !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_SYMBIAN +#define GTEST_HAS_STREAM_REDIRECTION_ 1 +#endif // !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_SYMBIAN + +// Determines whether to support death tests. +// Google Test does not support death tests for VC 7.1 and earlier as +// abort() in a VC 7.1 application compiled as GUI in debug config +// pops up a dialog window that cannot be suppressed programmatically. +#if (GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_CYGWIN || GTEST_OS_SOLARIS || \ + (GTEST_OS_WINDOWS_DESKTOP && _MSC_VER >= 1400) || \ + GTEST_OS_WINDOWS_MINGW || GTEST_OS_AIX) +#define GTEST_HAS_DEATH_TEST 1 +#include // NOLINT +#endif + +// We don't support MSVC 7.1 with exceptions disabled now. Therefore +// all the compilers we care about are adequate for supporting +// value-parameterized tests. +#define GTEST_HAS_PARAM_TEST 1 + +// Determines whether to support type-driven tests. + +// Typed tests need and variadic macros, which GCC, VC++ 8.0, +// Sun Pro CC, and IBM Visual Age support. +#if defined(__GNUC__) || (_MSC_VER >= 1400) || defined(__SUNPRO_CC) || \ + defined(__IBMCPP__) +#define GTEST_HAS_TYPED_TEST 1 +#define GTEST_HAS_TYPED_TEST_P 1 +#endif + +// Determines whether to support Combine(). This only makes sense when +// value-parameterized tests are enabled. The implementation doesn't +// work on Sun Studio since it doesn't understand templated conversion +// operators. +#if GTEST_HAS_PARAM_TEST && GTEST_HAS_TR1_TUPLE && !defined(__SUNPRO_CC) +#define GTEST_HAS_COMBINE 1 +#endif + +// Determines whether the system compiler uses UTF-16 for encoding wide strings. +#define GTEST_WIDE_STRING_USES_UTF16_ \ + (GTEST_OS_WINDOWS || GTEST_OS_CYGWIN || GTEST_OS_SYMBIAN || GTEST_OS_AIX) + +// Defines some utility macros. + +// The GNU compiler emits a warning if nested "if" statements are followed by +// an "else" statement and braces are not used to explicitly disambiguate the +// "else" binding. This leads to problems with code like: +// +// if (gate) +// ASSERT_*(condition) << "Some message"; +// +// The "switch (0) case 0:" idiom is used to suppress this. +#ifdef __INTEL_COMPILER +#define GTEST_AMBIGUOUS_ELSE_BLOCKER_ +#else +#define GTEST_AMBIGUOUS_ELSE_BLOCKER_ switch (0) case 0: // NOLINT +#endif + +// Use this annotation at the end of a struct/class definition to +// prevent the compiler from optimizing away instances that are never +// used. This is useful when all interesting logic happens inside the +// c'tor and / or d'tor. Example: +// +// struct Foo { +// Foo() { ... } +// } GTEST_ATTRIBUTE_UNUSED_; +// +// Also use it after a variable or parameter declaration to tell the +// compiler the variable/parameter does not have to be used. +#if defined(__GNUC__) && !defined(COMPILER_ICC) +#define GTEST_ATTRIBUTE_UNUSED_ __attribute__ ((unused)) +#else +#define GTEST_ATTRIBUTE_UNUSED_ +#endif + +// A macro to disallow operator= +// This should be used in the private: declarations for a class. +#define GTEST_DISALLOW_ASSIGN_(type)\ + void operator=(type const &) + +// A macro to disallow copy constructor and operator= +// This should be used in the private: declarations for a class. +#define GTEST_DISALLOW_COPY_AND_ASSIGN_(type)\ + type(type const &);\ + GTEST_DISALLOW_ASSIGN_(type) + +// Tell the compiler to warn about unused return values for functions declared +// with this macro. The macro should be used on function declarations +// following the argument list: +// +// Sprocket* AllocateSprocket() GTEST_MUST_USE_RESULT_; +#if defined(__GNUC__) && (GTEST_GCC_VER_ >= 30400) && !defined(COMPILER_ICC) +#define GTEST_MUST_USE_RESULT_ __attribute__ ((warn_unused_result)) +#else +#define GTEST_MUST_USE_RESULT_ +#endif // __GNUC__ && (GTEST_GCC_VER_ >= 30400) && !COMPILER_ICC + +// Determine whether the compiler supports Microsoft's Structured Exception +// Handling. This is supported by several Windows compilers but generally +// does not exist on any other system. +#ifndef GTEST_HAS_SEH +// The user didn't tell us, so we need to figure it out. + +#if defined(_MSC_VER) || defined(__BORLANDC__) +// These two compilers are known to support SEH. +#define GTEST_HAS_SEH 1 +#else +// Assume no SEH. +#define GTEST_HAS_SEH 0 +#endif + +#endif // GTEST_HAS_SEH + +#ifdef _MSC_VER + +#if GTEST_LINKED_AS_SHARED_LIBRARY +#define GTEST_API_ __declspec(dllimport) +#elif GTEST_CREATE_SHARED_LIBRARY +#define GTEST_API_ __declspec(dllexport) +#endif + +#endif // _MSC_VER + +#ifndef GTEST_API_ +#define GTEST_API_ +#endif + +namespace testing { + +class Message; + +namespace internal { + +class String; + +typedef ::std::stringstream StrStream; + +// A helper for suppressing warnings on constant condition. It just +// returns 'condition'. +GTEST_API_ bool IsTrue(bool condition); + +// Defines scoped_ptr. + +// This implementation of scoped_ptr is PARTIAL - it only contains +// enough stuff to satisfy Google Test's need. +template +class scoped_ptr { + public: + typedef T element_type; + + explicit scoped_ptr(T* p = NULL) : ptr_(p) {} + ~scoped_ptr() { reset(); } + + T& operator*() const { return *ptr_; } + T* operator->() const { return ptr_; } + T* get() const { return ptr_; } + + T* release() { + T* const ptr = ptr_; + ptr_ = NULL; + return ptr; + } + + void reset(T* p = NULL) { + if (p != ptr_) { + if (IsTrue(sizeof(T) > 0)) { // Makes sure T is a complete type. + delete ptr_; + } + ptr_ = p; + } + } + private: + T* ptr_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(scoped_ptr); +}; + +// Defines RE. + +// A simple C++ wrapper for . It uses the POSIX Extended +// Regular Expression syntax. +class GTEST_API_ RE { + public: + // A copy constructor is required by the Standard to initialize object + // references from r-values. + RE(const RE& other) { Init(other.pattern()); } + + // Constructs an RE from a string. + RE(const ::std::string& regex) { Init(regex.c_str()); } // NOLINT + +#if GTEST_HAS_GLOBAL_STRING + RE(const ::string& regex) { Init(regex.c_str()); } // NOLINT +#endif // GTEST_HAS_GLOBAL_STRING + + RE(const char* regex) { Init(regex); } // NOLINT + ~RE(); + + // Returns the string representation of the regex. + const char* pattern() const { return pattern_; } + + // FullMatch(str, re) returns true iff regular expression re matches + // the entire str. + // PartialMatch(str, re) returns true iff regular expression re + // matches a substring of str (including str itself). + // + // TODO(wan@google.com): make FullMatch() and PartialMatch() work + // when str contains NUL characters. + static bool FullMatch(const ::std::string& str, const RE& re) { + return FullMatch(str.c_str(), re); + } + static bool PartialMatch(const ::std::string& str, const RE& re) { + return PartialMatch(str.c_str(), re); + } + +#if GTEST_HAS_GLOBAL_STRING + static bool FullMatch(const ::string& str, const RE& re) { + return FullMatch(str.c_str(), re); + } + static bool PartialMatch(const ::string& str, const RE& re) { + return PartialMatch(str.c_str(), re); + } +#endif // GTEST_HAS_GLOBAL_STRING + + static bool FullMatch(const char* str, const RE& re); + static bool PartialMatch(const char* str, const RE& re); + + private: + void Init(const char* regex); + + // We use a const char* instead of a string, as Google Test may be used + // where string is not available. We also do not use Google Test's own + // String type here, in order to simplify dependencies between the + // files. + const char* pattern_; + bool is_valid_; +#if GTEST_USES_POSIX_RE + regex_t full_regex_; // For FullMatch(). + regex_t partial_regex_; // For PartialMatch(). +#else // GTEST_USES_SIMPLE_RE + const char* full_pattern_; // For FullMatch(); +#endif + + GTEST_DISALLOW_ASSIGN_(RE); +}; + +// Defines logging utilities: +// GTEST_LOG_(severity) - logs messages at the specified severity level. The +// message itself is streamed into the macro. +// LogToStderr() - directs all log messages to stderr. +// FlushInfoLog() - flushes informational log messages. + +enum GTestLogSeverity { + GTEST_INFO, + GTEST_WARNING, + GTEST_ERROR, + GTEST_FATAL +}; + +// Formats log entry severity, provides a stream object for streaming the +// log message, and terminates the message with a newline when going out of +// scope. +class GTEST_API_ GTestLog { + public: + GTestLog(GTestLogSeverity severity, const char* file, int line); + + // Flushes the buffers and, if severity is GTEST_FATAL, aborts the program. + ~GTestLog(); + + ::std::ostream& GetStream() { return ::std::cerr; } + + private: + const GTestLogSeverity severity_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(GTestLog); +}; + +#define GTEST_LOG_(severity) \ + ::testing::internal::GTestLog(::testing::internal::GTEST_##severity, \ + __FILE__, __LINE__).GetStream() + +inline void LogToStderr() {} +inline void FlushInfoLog() { fflush(NULL); } + +// INTERNAL IMPLEMENTATION - DO NOT USE. +// +// GTEST_CHECK_ is an all-mode assert. It aborts the program if the condition +// is not satisfied. +// Synopsys: +// GTEST_CHECK_(boolean_condition); +// or +// GTEST_CHECK_(boolean_condition) << "Additional message"; +// +// This checks the condition and if the condition is not satisfied +// it prints message about the condition violation, including the +// condition itself, plus additional message streamed into it, if any, +// and then it aborts the program. It aborts the program irrespective of +// whether it is built in the debug mode or not. +#define GTEST_CHECK_(condition) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (::testing::internal::IsTrue(condition)) \ + ; \ + else \ + GTEST_LOG_(FATAL) << "Condition " #condition " failed. " + +// An all-mode assert to verify that the given POSIX-style function +// call returns 0 (indicating success). Known limitation: this +// doesn't expand to a balanced 'if' statement, so enclose the macro +// in {} if you need to use it as the only statement in an 'if' +// branch. +#define GTEST_CHECK_POSIX_SUCCESS_(posix_call) \ + if (const int gtest_error = (posix_call)) \ + GTEST_LOG_(FATAL) << #posix_call << "failed with error " \ + << gtest_error + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// Downcasts the pointer of type Base to Derived. +// Derived must be a subclass of Base. The parameter MUST +// point to a class of type Derived, not any subclass of it. +// When RTTI is available, the function performs a runtime +// check to enforce this. +template +Derived* CheckedDowncastToActualType(Base* base) { +#if GTEST_HAS_RTTI + GTEST_CHECK_(typeid(*base) == typeid(Derived)); + return dynamic_cast(base); // NOLINT +#else + return static_cast(base); // Poor man's downcast. +#endif +} + +#if GTEST_HAS_STREAM_REDIRECTION_ + +// Defines the stderr capturer: +// CaptureStdout - starts capturing stdout. +// GetCapturedStdout - stops capturing stdout and returns the captured string. +// CaptureStderr - starts capturing stderr. +// GetCapturedStderr - stops capturing stderr and returns the captured string. +// +GTEST_API_ void CaptureStdout(); +GTEST_API_ String GetCapturedStdout(); +GTEST_API_ void CaptureStderr(); +GTEST_API_ String GetCapturedStderr(); + +#endif // GTEST_HAS_STREAM_REDIRECTION_ + + +#if GTEST_HAS_DEATH_TEST + +// A copy of all command line arguments. Set by InitGoogleTest(). +extern ::std::vector g_argvs; + +// GTEST_HAS_DEATH_TEST implies we have ::std::string. +const ::std::vector& GetArgvs(); + +#endif // GTEST_HAS_DEATH_TEST + +// Defines synchronization primitives. + +#if GTEST_HAS_PTHREAD + +// Sleeps for (roughly) n milli-seconds. This function is only for +// testing Google Test's own constructs. Don't use it in user tests, +// either directly or indirectly. +inline void SleepMilliseconds(int n) { + const timespec time = { + 0, // 0 seconds. + n * 1000L * 1000L, // And n ms. + }; + nanosleep(&time, NULL); +} + +// Allows a controller thread to pause execution of newly created +// threads until notified. Instances of this class must be created +// and destroyed in the controller thread. +// +// This class is only for testing Google Test's own constructs. Do not +// use it in user tests, either directly or indirectly. +class Notification { + public: + Notification() : notified_(false) {} + + // Notifies all threads created with this notification to start. Must + // be called from the controller thread. + void Notify() { notified_ = true; } + + // Blocks until the controller thread notifies. Must be called from a test + // thread. + void WaitForNotification() { + while(!notified_) { + SleepMilliseconds(10); + } + } + + private: + volatile bool notified_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(Notification); +}; + +// As a C-function, ThreadFuncWithCLinkage cannot be templated itself. +// Consequently, it cannot select a correct instantiation of ThreadWithParam +// in order to call its Run(). Introducing ThreadWithParamBase as a +// non-templated base class for ThreadWithParam allows us to bypass this +// problem. +class ThreadWithParamBase { + public: + virtual ~ThreadWithParamBase() {} + virtual void Run() = 0; +}; + +// pthread_create() accepts a pointer to a function type with the C linkage. +// According to the Standard (7.5/1), function types with different linkages +// are different even if they are otherwise identical. Some compilers (for +// example, SunStudio) treat them as different types. Since class methods +// cannot be defined with C-linkage we need to define a free C-function to +// pass into pthread_create(). +extern "C" inline void* ThreadFuncWithCLinkage(void* thread) { + static_cast(thread)->Run(); + return NULL; +} + +// Helper class for testing Google Test's multi-threading constructs. +// To use it, write: +// +// void ThreadFunc(int param) { /* Do things with param */ } +// Notification thread_can_start; +// ... +// // The thread_can_start parameter is optional; you can supply NULL. +// ThreadWithParam thread(&ThreadFunc, 5, &thread_can_start); +// thread_can_start.Notify(); +// +// These classes are only for testing Google Test's own constructs. Do +// not use them in user tests, either directly or indirectly. +template +class ThreadWithParam : public ThreadWithParamBase { + public: + typedef void (*UserThreadFunc)(T); + + ThreadWithParam( + UserThreadFunc func, T param, Notification* thread_can_start) + : func_(func), + param_(param), + thread_can_start_(thread_can_start), + finished_(false) { + ThreadWithParamBase* const base = this; + // The thread can be created only after all fields except thread_ + // have been initialized. + GTEST_CHECK_POSIX_SUCCESS_( + pthread_create(&thread_, 0, &ThreadFuncWithCLinkage, base)); + } + ~ThreadWithParam() { Join(); } + + void Join() { + if (!finished_) { + GTEST_CHECK_POSIX_SUCCESS_(pthread_join(thread_, 0)); + finished_ = true; + } + } + + virtual void Run() { + if (thread_can_start_ != NULL) + thread_can_start_->WaitForNotification(); + func_(param_); + } + + private: + const UserThreadFunc func_; // User-supplied thread function. + const T param_; // User-supplied parameter to the thread function. + // When non-NULL, used to block execution until the controller thread + // notifies. + Notification* const thread_can_start_; + bool finished_; // true iff we know that the thread function has finished. + pthread_t thread_; // The native thread object. + + GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadWithParam); +}; + +// gtest-port.h guarantees to #include when GTEST_HAS_PTHREAD is +// true. +#include + +// MutexBase and Mutex implement mutex on pthreads-based platforms. They +// are used in conjunction with class MutexLock: +// +// Mutex mutex; +// ... +// MutexLock lock(&mutex); // Acquires the mutex and releases it at the end +// // of the current scope. +// +// MutexBase implements behavior for both statically and dynamically +// allocated mutexes. Do not use MutexBase directly. Instead, write +// the following to define a static mutex: +// +// GTEST_DEFINE_STATIC_MUTEX_(g_some_mutex); +// +// You can forward declare a static mutex like this: +// +// GTEST_DECLARE_STATIC_MUTEX_(g_some_mutex); +// +// To create a dynamic mutex, just define an object of type Mutex. +class MutexBase { + public: + // Acquires this mutex. + void Lock() { + GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_lock(&mutex_)); + owner_ = pthread_self(); + } + + // Releases this mutex. + void Unlock() { + // We don't protect writing to owner_ here, as it's the caller's + // responsibility to ensure that the current thread holds the + // mutex when this is called. + owner_ = 0; + GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_unlock(&mutex_)); + } + + // Does nothing if the current thread holds the mutex. Otherwise, crashes + // with high probability. + void AssertHeld() const { + GTEST_CHECK_(owner_ == pthread_self()) + << "The current thread is not holding the mutex @" << this; + } + + // A static mutex may be used before main() is entered. It may even + // be used before the dynamic initialization stage. Therefore we + // must be able to initialize a static mutex object at link time. + // This means MutexBase has to be a POD and its member variables + // have to be public. + public: + pthread_mutex_t mutex_; // The underlying pthread mutex. + pthread_t owner_; // The thread holding the mutex; 0 means no one holds it. +}; + +// Forward-declares a static mutex. +#define GTEST_DECLARE_STATIC_MUTEX_(mutex) \ + extern ::testing::internal::MutexBase mutex + +// Defines and statically (i.e. at link time) initializes a static mutex. +#define GTEST_DEFINE_STATIC_MUTEX_(mutex) \ + ::testing::internal::MutexBase mutex = { PTHREAD_MUTEX_INITIALIZER, 0 } + +// The Mutex class can only be used for mutexes created at runtime. It +// shares its API with MutexBase otherwise. +class Mutex : public MutexBase { + public: + Mutex() { + GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_init(&mutex_, NULL)); + owner_ = 0; + } + ~Mutex() { + GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_destroy(&mutex_)); + } + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(Mutex); +}; + +// We cannot name this class MutexLock as the ctor declaration would +// conflict with a macro named MutexLock, which is defined on some +// platforms. Hence the typedef trick below. +class GTestMutexLock { + public: + explicit GTestMutexLock(MutexBase* mutex) + : mutex_(mutex) { mutex_->Lock(); } + + ~GTestMutexLock() { mutex_->Unlock(); } + + private: + MutexBase* const mutex_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(GTestMutexLock); +}; + +typedef GTestMutexLock MutexLock; + +// Helpers for ThreadLocal. + +// pthread_key_create() requires DeleteThreadLocalValue() to have +// C-linkage. Therefore it cannot be templatized to access +// ThreadLocal. Hence the need for class +// ThreadLocalValueHolderBase. +class ThreadLocalValueHolderBase { + public: + virtual ~ThreadLocalValueHolderBase() {} +}; + +// Called by pthread to delete thread-local data stored by +// pthread_setspecific(). +extern "C" inline void DeleteThreadLocalValue(void* value_holder) { + delete static_cast(value_holder); +} + +// Implements thread-local storage on pthreads-based systems. +// +// // Thread 1 +// ThreadLocal tl(100); // 100 is the default value for each thread. +// +// // Thread 2 +// tl.set(150); // Changes the value for thread 2 only. +// EXPECT_EQ(150, tl.get()); +// +// // Thread 1 +// EXPECT_EQ(100, tl.get()); // In thread 1, tl has the original value. +// tl.set(200); +// EXPECT_EQ(200, tl.get()); +// +// The template type argument T must have a public copy constructor. +// In addition, the default ThreadLocal constructor requires T to have +// a public default constructor. +// +// An object managed for a thread by a ThreadLocal instance is deleted +// when the thread exits. Or, if the ThreadLocal instance dies in +// that thread, when the ThreadLocal dies. It's the user's +// responsibility to ensure that all other threads using a ThreadLocal +// have exited when it dies, or the per-thread objects for those +// threads will not be deleted. +// +// Google Test only uses global ThreadLocal objects. That means they +// will die after main() has returned. Therefore, no per-thread +// object managed by Google Test will be leaked as long as all threads +// using Google Test have exited when main() returns. +template +class ThreadLocal { + public: + ThreadLocal() : key_(CreateKey()), + default_() {} + explicit ThreadLocal(const T& value) : key_(CreateKey()), + default_(value) {} + + ~ThreadLocal() { + // Destroys the managed object for the current thread, if any. + DeleteThreadLocalValue(pthread_getspecific(key_)); + + // Releases resources associated with the key. This will *not* + // delete managed objects for other threads. + GTEST_CHECK_POSIX_SUCCESS_(pthread_key_delete(key_)); + } + + T* pointer() { return GetOrCreateValue(); } + const T* pointer() const { return GetOrCreateValue(); } + const T& get() const { return *pointer(); } + void set(const T& value) { *pointer() = value; } + + private: + // Holds a value of type T. + class ValueHolder : public ThreadLocalValueHolderBase { + public: + explicit ValueHolder(const T& value) : value_(value) {} + + T* pointer() { return &value_; } + + private: + T value_; + GTEST_DISALLOW_COPY_AND_ASSIGN_(ValueHolder); + }; + + static pthread_key_t CreateKey() { + pthread_key_t key; + // When a thread exits, DeleteThreadLocalValue() will be called on + // the object managed for that thread. + GTEST_CHECK_POSIX_SUCCESS_( + pthread_key_create(&key, &DeleteThreadLocalValue)); + return key; + } + + T* GetOrCreateValue() const { + ThreadLocalValueHolderBase* const holder = + static_cast(pthread_getspecific(key_)); + if (holder != NULL) { + return CheckedDowncastToActualType(holder)->pointer(); + } + + ValueHolder* const new_holder = new ValueHolder(default_); + ThreadLocalValueHolderBase* const holder_base = new_holder; + GTEST_CHECK_POSIX_SUCCESS_(pthread_setspecific(key_, holder_base)); + return new_holder->pointer(); + } + + // A key pthreads uses for looking up per-thread values. + const pthread_key_t key_; + const T default_; // The default value for each thread. + + GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadLocal); +}; + +#define GTEST_IS_THREADSAFE 1 + +#else // GTEST_HAS_PTHREAD + +// A dummy implementation of synchronization primitives (mutex, lock, +// and thread-local variable). Necessary for compiling Google Test where +// mutex is not supported - using Google Test in multiple threads is not +// supported on such platforms. + +class Mutex { + public: + Mutex() {} + void AssertHeld() const {} +}; + +#define GTEST_DECLARE_STATIC_MUTEX_(mutex) \ + extern ::testing::internal::Mutex mutex + +#define GTEST_DEFINE_STATIC_MUTEX_(mutex) ::testing::internal::Mutex mutex + +class GTestMutexLock { + public: + explicit GTestMutexLock(Mutex*) {} // NOLINT +}; + +typedef GTestMutexLock MutexLock; + +template +class ThreadLocal { + public: + ThreadLocal() : value_() {} + explicit ThreadLocal(const T& value) : value_(value) {} + T* pointer() { return &value_; } + const T* pointer() const { return &value_; } + const T& get() const { return value_; } + void set(const T& value) { value_ = value; } + private: + T value_; +}; + +// The above synchronization primitives have dummy implementations. +// Therefore Google Test is not thread-safe. +#define GTEST_IS_THREADSAFE 0 + +#endif // GTEST_HAS_PTHREAD + +// Returns the number of threads running in the process, or 0 to indicate that +// we cannot detect it. +GTEST_API_ size_t GetThreadCount(); + +// Passing non-POD classes through ellipsis (...) crashes the ARM +// compiler and generates a warning in Sun Studio. The Nokia Symbian +// and the IBM XL C/C++ compiler try to instantiate a copy constructor +// for objects passed through ellipsis (...), failing for uncopyable +// objects. We define this to ensure that only POD is passed through +// ellipsis on these systems. +#if defined(__SYMBIAN32__) || defined(__IBMCPP__) || defined(__SUNPRO_CC) +// We lose support for NULL detection where the compiler doesn't like +// passing non-POD classes through ellipsis (...). +#define GTEST_ELLIPSIS_NEEDS_POD_ 1 +#else +#define GTEST_CAN_COMPARE_NULL 1 +#endif + +// The Nokia Symbian and IBM XL C/C++ compilers cannot decide between +// const T& and const T* in a function template. These compilers +// _can_ decide between class template specializations for T and T*, +// so a tr1::type_traits-like is_pointer works. +#if defined(__SYMBIAN32__) || defined(__IBMCPP__) +#define GTEST_NEEDS_IS_POINTER_ 1 +#endif + +template +struct bool_constant { + typedef bool_constant type; + static const bool value = bool_value; +}; +template const bool bool_constant::value; + +typedef bool_constant false_type; +typedef bool_constant true_type; + +template +struct is_pointer : public false_type {}; + +template +struct is_pointer : public true_type {}; + +#if GTEST_OS_WINDOWS +#define GTEST_PATH_SEP_ "\\" +#define GTEST_HAS_ALT_PATH_SEP_ 1 +// The biggest signed integer type the compiler supports. +typedef __int64 BiggestInt; +#else +#define GTEST_PATH_SEP_ "/" +#define GTEST_HAS_ALT_PATH_SEP_ 0 +typedef long long BiggestInt; // NOLINT +#endif // GTEST_OS_WINDOWS + +// The testing::internal::posix namespace holds wrappers for common +// POSIX functions. These wrappers hide the differences between +// Windows/MSVC and POSIX systems. Since some compilers define these +// standard functions as macros, the wrapper cannot have the same name +// as the wrapped function. + +namespace posix { + +// Functions with a different name on Windows. + +#if GTEST_OS_WINDOWS + +typedef struct _stat StatStruct; + +#ifdef __BORLANDC__ +inline int IsATTY(int fd) { return isatty(fd); } +inline int StrCaseCmp(const char* s1, const char* s2) { + return stricmp(s1, s2); +} +inline char* StrDup(const char* src) { return strdup(src); } +#else // !__BORLANDC__ +#if GTEST_OS_WINDOWS_MOBILE +inline int IsATTY(int /* fd */) { return 0; } +#else +inline int IsATTY(int fd) { return _isatty(fd); } +#endif // GTEST_OS_WINDOWS_MOBILE +inline int StrCaseCmp(const char* s1, const char* s2) { + return _stricmp(s1, s2); +} +inline char* StrDup(const char* src) { return _strdup(src); } +#endif // __BORLANDC__ + +#if GTEST_OS_WINDOWS_MOBILE +inline int FileNo(FILE* file) { return reinterpret_cast(_fileno(file)); } +// Stat(), RmDir(), and IsDir() are not needed on Windows CE at this +// time and thus not defined there. +#else +inline int FileNo(FILE* file) { return _fileno(file); } +inline int Stat(const char* path, StatStruct* buf) { return _stat(path, buf); } +inline int RmDir(const char* dir) { return _rmdir(dir); } +inline bool IsDir(const StatStruct& st) { + return (_S_IFDIR & st.st_mode) != 0; +} +#endif // GTEST_OS_WINDOWS_MOBILE + +#else + +typedef struct stat StatStruct; + +inline int FileNo(FILE* file) { return fileno(file); } +inline int IsATTY(int fd) { return isatty(fd); } +inline int Stat(const char* path, StatStruct* buf) { return stat(path, buf); } +inline int StrCaseCmp(const char* s1, const char* s2) { + return strcasecmp(s1, s2); +} +inline char* StrDup(const char* src) { return strdup(src); } +inline int RmDir(const char* dir) { return rmdir(dir); } +inline bool IsDir(const StatStruct& st) { return S_ISDIR(st.st_mode); } + +#endif // GTEST_OS_WINDOWS + +// Functions deprecated by MSVC 8.0. + +#ifdef _MSC_VER +// Temporarily disable warning 4996 (deprecated function). +#pragma warning(push) +#pragma warning(disable:4996) +#endif + +inline const char* StrNCpy(char* dest, const char* src, size_t n) { + return strncpy(dest, src, n); +} + +// ChDir(), FReopen(), FDOpen(), Read(), Write(), Close(), and +// StrError() aren't needed on Windows CE at this time and thus not +// defined there. + +#if !GTEST_OS_WINDOWS_MOBILE +inline int ChDir(const char* dir) { return chdir(dir); } +#endif +inline FILE* FOpen(const char* path, const char* mode) { + return fopen(path, mode); +} +#if !GTEST_OS_WINDOWS_MOBILE +inline FILE *FReopen(const char* path, const char* mode, FILE* stream) { + return freopen(path, mode, stream); +} +inline FILE* FDOpen(int fd, const char* mode) { return fdopen(fd, mode); } +#endif +inline int FClose(FILE* fp) { return fclose(fp); } +#if !GTEST_OS_WINDOWS_MOBILE +inline int Read(int fd, void* buf, unsigned int count) { + return static_cast(read(fd, buf, count)); +} +inline int Write(int fd, const void* buf, unsigned int count) { + return static_cast(write(fd, buf, count)); +} +inline int Close(int fd) { return close(fd); } +inline const char* StrError(int errnum) { return strerror(errnum); } +#endif +inline const char* GetEnv(const char* name) { +#if GTEST_OS_WINDOWS_MOBILE + // We are on Windows CE, which has no environment variables. + return NULL; +#elif defined(__BORLANDC__) || defined(__SunOS_5_8) || defined(__SunOS_5_9) + // Environment variables which we programmatically clear will be set to the + // empty string rather than unset (NULL). Handle that case. + const char* const env = getenv(name); + return (env != NULL && env[0] != '\0') ? env : NULL; +#else + return getenv(name); +#endif +} + +#ifdef _MSC_VER +#pragma warning(pop) // Restores the warning state. +#endif + +#if GTEST_OS_WINDOWS_MOBILE +// Windows CE has no C library. The abort() function is used in +// several places in Google Test. This implementation provides a reasonable +// imitation of standard behaviour. +void Abort(); +#else +inline void Abort() { abort(); } +#endif // GTEST_OS_WINDOWS_MOBILE + +} // namespace posix + +// The maximum number a BiggestInt can represent. This definition +// works no matter BiggestInt is represented in one's complement or +// two's complement. +// +// We cannot rely on numeric_limits in STL, as __int64 and long long +// are not part of standard C++ and numeric_limits doesn't need to be +// defined for them. +const BiggestInt kMaxBiggestInt = + ~(static_cast(1) << (8*sizeof(BiggestInt) - 1)); + +// This template class serves as a compile-time function from size to +// type. It maps a size in bytes to a primitive type with that +// size. e.g. +// +// TypeWithSize<4>::UInt +// +// is typedef-ed to be unsigned int (unsigned integer made up of 4 +// bytes). +// +// Such functionality should belong to STL, but I cannot find it +// there. +// +// Google Test uses this class in the implementation of floating-point +// comparison. +// +// For now it only handles UInt (unsigned int) as that's all Google Test +// needs. Other types can be easily added in the future if need +// arises. +template +class TypeWithSize { + public: + // This prevents the user from using TypeWithSize with incorrect + // values of N. + typedef void UInt; +}; + +// The specialization for size 4. +template <> +class TypeWithSize<4> { + public: + // unsigned int has size 4 in both gcc and MSVC. + // + // As base/basictypes.h doesn't compile on Windows, we cannot use + // uint32, uint64, and etc here. + typedef int Int; + typedef unsigned int UInt; +}; + +// The specialization for size 8. +template <> +class TypeWithSize<8> { + public: +#if GTEST_OS_WINDOWS + typedef __int64 Int; + typedef unsigned __int64 UInt; +#else + typedef long long Int; // NOLINT + typedef unsigned long long UInt; // NOLINT +#endif // GTEST_OS_WINDOWS +}; + +// Integer types of known sizes. +typedef TypeWithSize<4>::Int Int32; +typedef TypeWithSize<4>::UInt UInt32; +typedef TypeWithSize<8>::Int Int64; +typedef TypeWithSize<8>::UInt UInt64; +typedef TypeWithSize<8>::Int TimeInMillis; // Represents time in milliseconds. + +// Utilities for command line flags and environment variables. + +// Macro for referencing flags. +#define GTEST_FLAG(name) FLAGS_gtest_##name + +// Macros for declaring flags. +#define GTEST_DECLARE_bool_(name) GTEST_API_ extern bool GTEST_FLAG(name) +#define GTEST_DECLARE_int32_(name) \ + GTEST_API_ extern ::testing::internal::Int32 GTEST_FLAG(name) +#define GTEST_DECLARE_string_(name) \ + GTEST_API_ extern ::testing::internal::String GTEST_FLAG(name) + +// Macros for defining flags. +#define GTEST_DEFINE_bool_(name, default_val, doc) \ + GTEST_API_ bool GTEST_FLAG(name) = (default_val) +#define GTEST_DEFINE_int32_(name, default_val, doc) \ + GTEST_API_ ::testing::internal::Int32 GTEST_FLAG(name) = (default_val) +#define GTEST_DEFINE_string_(name, default_val, doc) \ + GTEST_API_ ::testing::internal::String GTEST_FLAG(name) = (default_val) + +// Parses 'str' for a 32-bit signed integer. If successful, writes the result +// to *value and returns true; otherwise leaves *value unchanged and returns +// false. +// TODO(chandlerc): Find a better way to refactor flag and environment parsing +// out of both gtest-port.cc and gtest.cc to avoid exporting this utility +// function. +bool ParseInt32(const Message& src_text, const char* str, Int32* value); + +// Parses a bool/Int32/string from the environment variable +// corresponding to the given Google Test flag. +bool BoolFromGTestEnv(const char* flag, bool default_val); +GTEST_API_ Int32 Int32FromGTestEnv(const char* flag, Int32 default_val); +const char* StringFromGTestEnv(const char* flag, const char* default_val); + +} // namespace internal +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_ + +#if GTEST_OS_LINUX +#include +#include +#include +#include +#endif // GTEST_OS_LINUX + +#include +#include +#include +#include +#include + +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee) +// +// The Google C++ Testing Framework (Google Test) +// +// This header file declares the String class and functions used internally by +// Google Test. They are subject to change without notice. They should not used +// by code external to Google Test. +// +// This header file is #included by . +// It should not be #included by other files. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_ + +#ifdef __BORLANDC__ +// string.h is not guaranteed to provide strcpy on C++ Builder. +#include +#endif + +#include + +#include + +namespace testing { +namespace internal { + +// String - a UTF-8 string class. +// +// For historic reasons, we don't use std::string. +// +// TODO(wan@google.com): replace this class with std::string or +// implement it in terms of the latter. +// +// Note that String can represent both NULL and the empty string, +// while std::string cannot represent NULL. +// +// NULL and the empty string are considered different. NULL is less +// than anything (including the empty string) except itself. +// +// This class only provides minimum functionality necessary for +// implementing Google Test. We do not intend to implement a full-fledged +// string class here. +// +// Since the purpose of this class is to provide a substitute for +// std::string on platforms where it cannot be used, we define a copy +// constructor and assignment operators such that we don't need +// conditional compilation in a lot of places. +// +// In order to make the representation efficient, the d'tor of String +// is not virtual. Therefore DO NOT INHERIT FROM String. +class GTEST_API_ String { + public: + // Static utility methods + + // Returns the input enclosed in double quotes if it's not NULL; + // otherwise returns "(null)". For example, "\"Hello\"" is returned + // for input "Hello". + // + // This is useful for printing a C string in the syntax of a literal. + // + // Known issue: escape sequences are not handled yet. + static String ShowCStringQuoted(const char* c_str); + + // Clones a 0-terminated C string, allocating memory using new. The + // caller is responsible for deleting the return value using + // delete[]. Returns the cloned string, or NULL if the input is + // NULL. + // + // This is different from strdup() in string.h, which allocates + // memory using malloc(). + static const char* CloneCString(const char* c_str); + +#if GTEST_OS_WINDOWS_MOBILE + // Windows CE does not have the 'ANSI' versions of Win32 APIs. To be + // able to pass strings to Win32 APIs on CE we need to convert them + // to 'Unicode', UTF-16. + + // Creates a UTF-16 wide string from the given ANSI string, allocating + // memory using new. The caller is responsible for deleting the return + // value using delete[]. Returns the wide string, or NULL if the + // input is NULL. + // + // The wide string is created using the ANSI codepage (CP_ACP) to + // match the behaviour of the ANSI versions of Win32 calls and the + // C runtime. + static LPCWSTR AnsiToUtf16(const char* c_str); + + // Creates an ANSI string from the given wide string, allocating + // memory using new. The caller is responsible for deleting the return + // value using delete[]. Returns the ANSI string, or NULL if the + // input is NULL. + // + // The returned string is created using the ANSI codepage (CP_ACP) to + // match the behaviour of the ANSI versions of Win32 calls and the + // C runtime. + static const char* Utf16ToAnsi(LPCWSTR utf16_str); +#endif + + // Compares two C strings. Returns true iff they have the same content. + // + // Unlike strcmp(), this function can handle NULL argument(s). A + // NULL C string is considered different to any non-NULL C string, + // including the empty string. + static bool CStringEquals(const char* lhs, const char* rhs); + + // Converts a wide C string to a String using the UTF-8 encoding. + // NULL will be converted to "(null)". If an error occurred during + // the conversion, "(failed to convert from wide string)" is + // returned. + static String ShowWideCString(const wchar_t* wide_c_str); + + // Similar to ShowWideCString(), except that this function encloses + // the converted string in double quotes. + static String ShowWideCStringQuoted(const wchar_t* wide_c_str); + + // Compares two wide C strings. Returns true iff they have the same + // content. + // + // Unlike wcscmp(), this function can handle NULL argument(s). A + // NULL C string is considered different to any non-NULL C string, + // including the empty string. + static bool WideCStringEquals(const wchar_t* lhs, const wchar_t* rhs); + + // Compares two C strings, ignoring case. Returns true iff they + // have the same content. + // + // Unlike strcasecmp(), this function can handle NULL argument(s). + // A NULL C string is considered different to any non-NULL C string, + // including the empty string. + static bool CaseInsensitiveCStringEquals(const char* lhs, + const char* rhs); + + // Compares two wide C strings, ignoring case. Returns true iff they + // have the same content. + // + // Unlike wcscasecmp(), this function can handle NULL argument(s). + // A NULL C string is considered different to any non-NULL wide C string, + // including the empty string. + // NB: The implementations on different platforms slightly differ. + // On windows, this method uses _wcsicmp which compares according to LC_CTYPE + // environment variable. On GNU platform this method uses wcscasecmp + // which compares according to LC_CTYPE category of the current locale. + // On MacOS X, it uses towlower, which also uses LC_CTYPE category of the + // current locale. + static bool CaseInsensitiveWideCStringEquals(const wchar_t* lhs, + const wchar_t* rhs); + + // Formats a list of arguments to a String, using the same format + // spec string as for printf. + // + // We do not use the StringPrintf class as it is not universally + // available. + // + // The result is limited to 4096 characters (including the tailing + // 0). If 4096 characters are not enough to format the input, + // "" is returned. + static String Format(const char* format, ...); + + // C'tors + + // The default c'tor constructs a NULL string. + String() : c_str_(NULL), length_(0) {} + + // Constructs a String by cloning a 0-terminated C string. + String(const char* a_c_str) { // NOLINT + if (a_c_str == NULL) { + c_str_ = NULL; + length_ = 0; + } else { + ConstructNonNull(a_c_str, strlen(a_c_str)); + } + } + + // Constructs a String by copying a given number of chars from a + // buffer. E.g. String("hello", 3) creates the string "hel", + // String("a\0bcd", 4) creates "a\0bc", String(NULL, 0) creates "", + // and String(NULL, 1) results in access violation. + String(const char* buffer, size_t a_length) { + ConstructNonNull(buffer, a_length); + } + + // The copy c'tor creates a new copy of the string. The two + // String objects do not share content. + String(const String& str) : c_str_(NULL), length_(0) { *this = str; } + + // D'tor. String is intended to be a final class, so the d'tor + // doesn't need to be virtual. + ~String() { delete[] c_str_; } + + // Allows a String to be implicitly converted to an ::std::string or + // ::string, and vice versa. Converting a String containing a NULL + // pointer to ::std::string or ::string is undefined behavior. + // Converting a ::std::string or ::string containing an embedded NUL + // character to a String will result in the prefix up to the first + // NUL character. + String(const ::std::string& str) { + ConstructNonNull(str.c_str(), str.length()); + } + + operator ::std::string() const { return ::std::string(c_str(), length()); } + +#if GTEST_HAS_GLOBAL_STRING + String(const ::string& str) { + ConstructNonNull(str.c_str(), str.length()); + } + + operator ::string() const { return ::string(c_str(), length()); } +#endif // GTEST_HAS_GLOBAL_STRING + + // Returns true iff this is an empty string (i.e. ""). + bool empty() const { return (c_str() != NULL) && (length() == 0); } + + // Compares this with another String. + // Returns < 0 if this is less than rhs, 0 if this is equal to rhs, or > 0 + // if this is greater than rhs. + int Compare(const String& rhs) const; + + // Returns true iff this String equals the given C string. A NULL + // string and a non-NULL string are considered not equal. + bool operator==(const char* a_c_str) const { return Compare(a_c_str) == 0; } + + // Returns true iff this String is less than the given String. A + // NULL string is considered less than "". + bool operator<(const String& rhs) const { return Compare(rhs) < 0; } + + // Returns true iff this String doesn't equal the given C string. A NULL + // string and a non-NULL string are considered not equal. + bool operator!=(const char* a_c_str) const { return !(*this == a_c_str); } + + // Returns true iff this String ends with the given suffix. *Any* + // String is considered to end with a NULL or empty suffix. + bool EndsWith(const char* suffix) const; + + // Returns true iff this String ends with the given suffix, not considering + // case. Any String is considered to end with a NULL or empty suffix. + bool EndsWithCaseInsensitive(const char* suffix) const; + + // Returns the length of the encapsulated string, or 0 if the + // string is NULL. + size_t length() const { return length_; } + + // Gets the 0-terminated C string this String object represents. + // The String object still owns the string. Therefore the caller + // should NOT delete the return value. + const char* c_str() const { return c_str_; } + + // Assigns a C string to this object. Self-assignment works. + const String& operator=(const char* a_c_str) { + return *this = String(a_c_str); + } + + // Assigns a String object to this object. Self-assignment works. + const String& operator=(const String& rhs) { + if (this != &rhs) { + delete[] c_str_; + if (rhs.c_str() == NULL) { + c_str_ = NULL; + length_ = 0; + } else { + ConstructNonNull(rhs.c_str(), rhs.length()); + } + } + + return *this; + } + + private: + // Constructs a non-NULL String from the given content. This + // function can only be called when data_ has not been allocated. + // ConstructNonNull(NULL, 0) results in an empty string (""). + // ConstructNonNull(NULL, non_zero) is undefined behavior. + void ConstructNonNull(const char* buffer, size_t a_length) { + char* const str = new char[a_length + 1]; + memcpy(str, buffer, a_length); + str[a_length] = '\0'; + c_str_ = str; + length_ = a_length; + } + + const char* c_str_; + size_t length_; +}; // class String + +// Streams a String to an ostream. Each '\0' character in the String +// is replaced with "\\0". +inline ::std::ostream& operator<<(::std::ostream& os, const String& str) { + if (str.c_str() == NULL) { + os << "(null)"; + } else { + const char* const c_str = str.c_str(); + for (size_t i = 0; i != str.length(); i++) { + if (c_str[i] == '\0') { + os << "\\0"; + } else { + os << c_str[i]; + } + } + } + return os; +} + +// Gets the content of the StrStream's buffer as a String. Each '\0' +// character in the buffer is replaced with "\\0". +GTEST_API_ String StrStreamToString(StrStream* stream); + +// Converts a streamable value to a String. A NULL pointer is +// converted to "(null)". When the input value is a ::string, +// ::std::string, ::wstring, or ::std::wstring object, each NUL +// character in it is replaced with "\\0". + +// Declared here but defined in gtest.h, so that it has access +// to the definition of the Message class, required by the ARM +// compiler. +template +String StreamableToString(const T& streamable); + +} // namespace internal +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: keith.ray@gmail.com (Keith Ray) +// +// Google Test filepath utilities +// +// This header file declares classes and functions used internally by +// Google Test. They are subject to change without notice. +// +// This file is #included in . +// Do not include this header file separately! + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_ + + +namespace testing { +namespace internal { + +// FilePath - a class for file and directory pathname manipulation which +// handles platform-specific conventions (like the pathname separator). +// Used for helper functions for naming files in a directory for xml output. +// Except for Set methods, all methods are const or static, which provides an +// "immutable value object" -- useful for peace of mind. +// A FilePath with a value ending in a path separator ("like/this/") represents +// a directory, otherwise it is assumed to represent a file. In either case, +// it may or may not represent an actual file or directory in the file system. +// Names are NOT checked for syntax correctness -- no checking for illegal +// characters, malformed paths, etc. + +class GTEST_API_ FilePath { + public: + FilePath() : pathname_("") { } + FilePath(const FilePath& rhs) : pathname_(rhs.pathname_) { } + + explicit FilePath(const char* pathname) : pathname_(pathname) { + Normalize(); + } + + explicit FilePath(const String& pathname) : pathname_(pathname) { + Normalize(); + } + + FilePath& operator=(const FilePath& rhs) { + Set(rhs); + return *this; + } + + void Set(const FilePath& rhs) { + pathname_ = rhs.pathname_; + } + + String ToString() const { return pathname_; } + const char* c_str() const { return pathname_.c_str(); } + + // Returns the current working directory, or "" if unsuccessful. + static FilePath GetCurrentDir(); + + // Given directory = "dir", base_name = "test", number = 0, + // extension = "xml", returns "dir/test.xml". If number is greater + // than zero (e.g., 12), returns "dir/test_12.xml". + // On Windows platform, uses \ as the separator rather than /. + static FilePath MakeFileName(const FilePath& directory, + const FilePath& base_name, + int number, + const char* extension); + + // Given directory = "dir", relative_path = "test.xml", + // returns "dir/test.xml". + // On Windows, uses \ as the separator rather than /. + static FilePath ConcatPaths(const FilePath& directory, + const FilePath& relative_path); + + // Returns a pathname for a file that does not currently exist. The pathname + // will be directory/base_name.extension or + // directory/base_name_.extension if directory/base_name.extension + // already exists. The number will be incremented until a pathname is found + // that does not already exist. + // Examples: 'dir/foo_test.xml' or 'dir/foo_test_1.xml'. + // There could be a race condition if two or more processes are calling this + // function at the same time -- they could both pick the same filename. + static FilePath GenerateUniqueFileName(const FilePath& directory, + const FilePath& base_name, + const char* extension); + + // Returns true iff the path is NULL or "". + bool IsEmpty() const { return c_str() == NULL || *c_str() == '\0'; } + + // If input name has a trailing separator character, removes it and returns + // the name, otherwise return the name string unmodified. + // On Windows platform, uses \ as the separator, other platforms use /. + FilePath RemoveTrailingPathSeparator() const; + + // Returns a copy of the FilePath with the directory part removed. + // Example: FilePath("path/to/file").RemoveDirectoryName() returns + // FilePath("file"). If there is no directory part ("just_a_file"), it returns + // the FilePath unmodified. If there is no file part ("just_a_dir/") it + // returns an empty FilePath (""). + // On Windows platform, '\' is the path separator, otherwise it is '/'. + FilePath RemoveDirectoryName() const; + + // RemoveFileName returns the directory path with the filename removed. + // Example: FilePath("path/to/file").RemoveFileName() returns "path/to/". + // If the FilePath is "a_file" or "/a_file", RemoveFileName returns + // FilePath("./") or, on Windows, FilePath(".\\"). If the filepath does + // not have a file, like "just/a/dir/", it returns the FilePath unmodified. + // On Windows platform, '\' is the path separator, otherwise it is '/'. + FilePath RemoveFileName() const; + + // Returns a copy of the FilePath with the case-insensitive extension removed. + // Example: FilePath("dir/file.exe").RemoveExtension("EXE") returns + // FilePath("dir/file"). If a case-insensitive extension is not + // found, returns a copy of the original FilePath. + FilePath RemoveExtension(const char* extension) const; + + // Creates directories so that path exists. Returns true if successful or if + // the directories already exist; returns false if unable to create + // directories for any reason. Will also return false if the FilePath does + // not represent a directory (that is, it doesn't end with a path separator). + bool CreateDirectoriesRecursively() const; + + // Create the directory so that path exists. Returns true if successful or + // if the directory already exists; returns false if unable to create the + // directory for any reason, including if the parent directory does not + // exist. Not named "CreateDirectory" because that's a macro on Windows. + bool CreateFolder() const; + + // Returns true if FilePath describes something in the file-system, + // either a file, directory, or whatever, and that something exists. + bool FileOrDirectoryExists() const; + + // Returns true if pathname describes a directory in the file-system + // that exists. + bool DirectoryExists() const; + + // Returns true if FilePath ends with a path separator, which indicates that + // it is intended to represent a directory. Returns false otherwise. + // This does NOT check that a directory (or file) actually exists. + bool IsDirectory() const; + + // Returns true if pathname describes a root directory. (Windows has one + // root directory per disk drive.) + bool IsRootDirectory() const; + + // Returns true if pathname describes an absolute path. + bool IsAbsolutePath() const; + + private: + // Replaces multiple consecutive separators with a single separator. + // For example, "bar///foo" becomes "bar/foo". Does not eliminate other + // redundancies that might be in a pathname involving "." or "..". + // + // A pathname with multiple consecutive separators may occur either through + // user error or as a result of some scripts or APIs that generate a pathname + // with a trailing separator. On other platforms the same API or script + // may NOT generate a pathname with a trailing "/". Then elsewhere that + // pathname may have another "/" and pathname components added to it, + // without checking for the separator already being there. + // The script language and operating system may allow paths like "foo//bar" + // but some of the functions in FilePath will not handle that correctly. In + // particular, RemoveTrailingPathSeparator() only removes one separator, and + // it is called in CreateDirectoriesRecursively() assuming that it will change + // a pathname from directory syntax (trailing separator) to filename syntax. + // + // On Windows this method also replaces the alternate path separator '/' with + // the primary path separator '\\', so that for example "bar\\/\\foo" becomes + // "bar\\foo". + + void Normalize(); + + // Returns a pointer to the last occurence of a valid path separator in + // the FilePath. On Windows, for example, both '/' and '\' are valid path + // separators. Returns NULL if no path separator was found. + const char* FindLastPathSeparator() const; + + String pathname_; +}; // class FilePath + +} // namespace internal +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_ +// This file was GENERATED by command: +// pump.py gtest-type-util.h.pump +// DO NOT EDIT BY HAND!!! + +// Copyright 2008 Google Inc. +// All Rights Reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: wan@google.com (Zhanyong Wan) + +// Type utilities needed for implementing typed and type-parameterized +// tests. This file is generated by a SCRIPT. DO NOT EDIT BY HAND! +// +// Currently we support at most 50 types in a list, and at most 50 +// type-parameterized tests in one type-parameterized test case. +// Please contact googletestframework@googlegroups.com if you need +// more. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ + + +#if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P + +// #ifdef __GNUC__ is too general here. It is possible to use gcc without using +// libstdc++ (which is where cxxabi.h comes from). +#ifdef __GLIBCXX__ +#include +#endif // __GLIBCXX__ + +namespace testing { +namespace internal { + +// AssertyTypeEq::type is defined iff T1 and T2 are the same +// type. This can be used as a compile-time assertion to ensure that +// two types are equal. + +template +struct AssertTypeEq; + +template +struct AssertTypeEq { + typedef bool type; +}; + +// GetTypeName() returns a human-readable name of type T. +template +String GetTypeName() { +#if GTEST_HAS_RTTI + + const char* const name = typeid(T).name(); +#ifdef __GLIBCXX__ + int status = 0; + // gcc's implementation of typeid(T).name() mangles the type name, + // so we have to demangle it. + char* const readable_name = abi::__cxa_demangle(name, 0, 0, &status); + const String name_str(status == 0 ? readable_name : name); + free(readable_name); + return name_str; +#else + return name; +#endif // __GLIBCXX__ + +#else + return ""; +#endif // GTEST_HAS_RTTI +} + +// A unique type used as the default value for the arguments of class +// template Types. This allows us to simulate variadic templates +// (e.g. Types, Type, and etc), which C++ doesn't +// support directly. +struct None {}; + +// The following family of struct and struct templates are used to +// represent type lists. In particular, TypesN +// represents a type list with N types (T1, T2, ..., and TN) in it. +// Except for Types0, every struct in the family has two member types: +// Head for the first type in the list, and Tail for the rest of the +// list. + +// The empty type list. +struct Types0 {}; + +// Type lists of length 1, 2, 3, and so on. + +template +struct Types1 { + typedef T1 Head; + typedef Types0 Tail; +}; +template +struct Types2 { + typedef T1 Head; + typedef Types1 Tail; +}; + +template +struct Types3 { + typedef T1 Head; + typedef Types2 Tail; +}; + +template +struct Types4 { + typedef T1 Head; + typedef Types3 Tail; +}; + +template +struct Types5 { + typedef T1 Head; + typedef Types4 Tail; +}; + +template +struct Types6 { + typedef T1 Head; + typedef Types5 Tail; +}; + +template +struct Types7 { + typedef T1 Head; + typedef Types6 Tail; +}; + +template +struct Types8 { + typedef T1 Head; + typedef Types7 Tail; +}; + +template +struct Types9 { + typedef T1 Head; + typedef Types8 Tail; +}; + +template +struct Types10 { + typedef T1 Head; + typedef Types9 Tail; +}; + +template +struct Types11 { + typedef T1 Head; + typedef Types10 Tail; +}; + +template +struct Types12 { + typedef T1 Head; + typedef Types11 Tail; +}; + +template +struct Types13 { + typedef T1 Head; + typedef Types12 Tail; +}; + +template +struct Types14 { + typedef T1 Head; + typedef Types13 Tail; +}; + +template +struct Types15 { + typedef T1 Head; + typedef Types14 Tail; +}; + +template +struct Types16 { + typedef T1 Head; + typedef Types15 Tail; +}; + +template +struct Types17 { + typedef T1 Head; + typedef Types16 Tail; +}; + +template +struct Types18 { + typedef T1 Head; + typedef Types17 Tail; +}; + +template +struct Types19 { + typedef T1 Head; + typedef Types18 Tail; +}; + +template +struct Types20 { + typedef T1 Head; + typedef Types19 Tail; +}; + +template +struct Types21 { + typedef T1 Head; + typedef Types20 Tail; +}; + +template +struct Types22 { + typedef T1 Head; + typedef Types21 Tail; +}; + +template +struct Types23 { + typedef T1 Head; + typedef Types22 Tail; +}; + +template +struct Types24 { + typedef T1 Head; + typedef Types23 Tail; +}; + +template +struct Types25 { + typedef T1 Head; + typedef Types24 Tail; +}; + +template +struct Types26 { + typedef T1 Head; + typedef Types25 Tail; +}; + +template +struct Types27 { + typedef T1 Head; + typedef Types26 Tail; +}; + +template +struct Types28 { + typedef T1 Head; + typedef Types27 Tail; +}; + +template +struct Types29 { + typedef T1 Head; + typedef Types28 Tail; +}; + +template +struct Types30 { + typedef T1 Head; + typedef Types29 Tail; +}; + +template +struct Types31 { + typedef T1 Head; + typedef Types30 Tail; +}; + +template +struct Types32 { + typedef T1 Head; + typedef Types31 Tail; +}; + +template +struct Types33 { + typedef T1 Head; + typedef Types32 Tail; +}; + +template +struct Types34 { + typedef T1 Head; + typedef Types33 Tail; +}; + +template +struct Types35 { + typedef T1 Head; + typedef Types34 Tail; +}; + +template +struct Types36 { + typedef T1 Head; + typedef Types35 Tail; +}; + +template +struct Types37 { + typedef T1 Head; + typedef Types36 Tail; +}; + +template +struct Types38 { + typedef T1 Head; + typedef Types37 Tail; +}; + +template +struct Types39 { + typedef T1 Head; + typedef Types38 Tail; +}; + +template +struct Types40 { + typedef T1 Head; + typedef Types39 Tail; +}; + +template +struct Types41 { + typedef T1 Head; + typedef Types40 Tail; +}; + +template +struct Types42 { + typedef T1 Head; + typedef Types41 Tail; +}; + +template +struct Types43 { + typedef T1 Head; + typedef Types42 Tail; +}; + +template +struct Types44 { + typedef T1 Head; + typedef Types43 Tail; +}; + +template +struct Types45 { + typedef T1 Head; + typedef Types44 Tail; +}; + +template +struct Types46 { + typedef T1 Head; + typedef Types45 Tail; +}; + +template +struct Types47 { + typedef T1 Head; + typedef Types46 Tail; +}; + +template +struct Types48 { + typedef T1 Head; + typedef Types47 Tail; +}; + +template +struct Types49 { + typedef T1 Head; + typedef Types48 Tail; +}; + +template +struct Types50 { + typedef T1 Head; + typedef Types49 Tail; +}; + + +} // namespace internal + +// We don't want to require the users to write TypesN<...> directly, +// as that would require them to count the length. Types<...> is much +// easier to write, but generates horrible messages when there is a +// compiler error, as gcc insists on printing out each template +// argument, even if it has the default value (this means Types +// will appear as Types in the compiler +// errors). +// +// Our solution is to combine the best part of the two approaches: a +// user would write Types, and Google Test will translate +// that to TypesN internally to make error messages +// readable. The translation is done by the 'type' member of the +// Types template. +template +struct Types { + typedef internal::Types50 type; +}; + +template <> +struct Types { + typedef internal::Types0 type; +}; +template +struct Types { + typedef internal::Types1 type; +}; +template +struct Types { + typedef internal::Types2 type; +}; +template +struct Types { + typedef internal::Types3 type; +}; +template +struct Types { + typedef internal::Types4 type; +}; +template +struct Types { + typedef internal::Types5 type; +}; +template +struct Types { + typedef internal::Types6 type; +}; +template +struct Types { + typedef internal::Types7 type; +}; +template +struct Types { + typedef internal::Types8 type; +}; +template +struct Types { + typedef internal::Types9 type; +}; +template +struct Types { + typedef internal::Types10 type; +}; +template +struct Types { + typedef internal::Types11 type; +}; +template +struct Types { + typedef internal::Types12 type; +}; +template +struct Types { + typedef internal::Types13 type; +}; +template +struct Types { + typedef internal::Types14 type; +}; +template +struct Types { + typedef internal::Types15 type; +}; +template +struct Types { + typedef internal::Types16 type; +}; +template +struct Types { + typedef internal::Types17 type; +}; +template +struct Types { + typedef internal::Types18 type; +}; +template +struct Types { + typedef internal::Types19 type; +}; +template +struct Types { + typedef internal::Types20 type; +}; +template +struct Types { + typedef internal::Types21 type; +}; +template +struct Types { + typedef internal::Types22 type; +}; +template +struct Types { + typedef internal::Types23 type; +}; +template +struct Types { + typedef internal::Types24 type; +}; +template +struct Types { + typedef internal::Types25 type; +}; +template +struct Types { + typedef internal::Types26 type; +}; +template +struct Types { + typedef internal::Types27 type; +}; +template +struct Types { + typedef internal::Types28 type; +}; +template +struct Types { + typedef internal::Types29 type; +}; +template +struct Types { + typedef internal::Types30 type; +}; +template +struct Types { + typedef internal::Types31 type; +}; +template +struct Types { + typedef internal::Types32 type; +}; +template +struct Types { + typedef internal::Types33 type; +}; +template +struct Types { + typedef internal::Types34 type; +}; +template +struct Types { + typedef internal::Types35 type; +}; +template +struct Types { + typedef internal::Types36 type; +}; +template +struct Types { + typedef internal::Types37 type; +}; +template +struct Types { + typedef internal::Types38 type; +}; +template +struct Types { + typedef internal::Types39 type; +}; +template +struct Types { + typedef internal::Types40 type; +}; +template +struct Types { + typedef internal::Types41 type; +}; +template +struct Types { + typedef internal::Types42 type; +}; +template +struct Types { + typedef internal::Types43 type; +}; +template +struct Types { + typedef internal::Types44 type; +}; +template +struct Types { + typedef internal::Types45 type; +}; +template +struct Types { + typedef internal::Types46 type; +}; +template +struct Types { + typedef internal::Types47 type; +}; +template +struct Types { + typedef internal::Types48 type; +}; +template +struct Types { + typedef internal::Types49 type; +}; + +namespace internal { + +#define GTEST_TEMPLATE_ template class + +// The template "selector" struct TemplateSel is used to +// represent Tmpl, which must be a class template with one type +// parameter, as a type. TemplateSel::Bind::type is defined +// as the type Tmpl. This allows us to actually instantiate the +// template "selected" by TemplateSel. +// +// This trick is necessary for simulating typedef for class templates, +// which C++ doesn't support directly. +template +struct TemplateSel { + template + struct Bind { + typedef Tmpl type; + }; +}; + +#define GTEST_BIND_(TmplSel, T) \ + TmplSel::template Bind::type + +// A unique struct template used as the default value for the +// arguments of class template Templates. This allows us to simulate +// variadic templates (e.g. Templates, Templates, +// and etc), which C++ doesn't support directly. +template +struct NoneT {}; + +// The following family of struct and struct templates are used to +// represent template lists. In particular, TemplatesN represents a list of N templates (T1, T2, ..., and TN). Except +// for Templates0, every struct in the family has two member types: +// Head for the selector of the first template in the list, and Tail +// for the rest of the list. + +// The empty template list. +struct Templates0 {}; + +// Template lists of length 1, 2, 3, and so on. + +template +struct Templates1 { + typedef TemplateSel Head; + typedef Templates0 Tail; +}; +template +struct Templates2 { + typedef TemplateSel Head; + typedef Templates1 Tail; +}; + +template +struct Templates3 { + typedef TemplateSel Head; + typedef Templates2 Tail; +}; + +template +struct Templates4 { + typedef TemplateSel Head; + typedef Templates3 Tail; +}; + +template +struct Templates5 { + typedef TemplateSel Head; + typedef Templates4 Tail; +}; + +template +struct Templates6 { + typedef TemplateSel Head; + typedef Templates5 Tail; +}; + +template +struct Templates7 { + typedef TemplateSel Head; + typedef Templates6 Tail; +}; + +template +struct Templates8 { + typedef TemplateSel Head; + typedef Templates7 Tail; +}; + +template +struct Templates9 { + typedef TemplateSel Head; + typedef Templates8 Tail; +}; + +template +struct Templates10 { + typedef TemplateSel Head; + typedef Templates9 Tail; +}; + +template +struct Templates11 { + typedef TemplateSel Head; + typedef Templates10 Tail; +}; + +template +struct Templates12 { + typedef TemplateSel Head; + typedef Templates11 Tail; +}; + +template +struct Templates13 { + typedef TemplateSel Head; + typedef Templates12 Tail; +}; + +template +struct Templates14 { + typedef TemplateSel Head; + typedef Templates13 Tail; +}; + +template +struct Templates15 { + typedef TemplateSel Head; + typedef Templates14 Tail; +}; + +template +struct Templates16 { + typedef TemplateSel Head; + typedef Templates15 Tail; +}; + +template +struct Templates17 { + typedef TemplateSel Head; + typedef Templates16 Tail; +}; + +template +struct Templates18 { + typedef TemplateSel Head; + typedef Templates17 Tail; +}; + +template +struct Templates19 { + typedef TemplateSel Head; + typedef Templates18 Tail; +}; + +template +struct Templates20 { + typedef TemplateSel Head; + typedef Templates19 Tail; +}; + +template +struct Templates21 { + typedef TemplateSel Head; + typedef Templates20 Tail; +}; + +template +struct Templates22 { + typedef TemplateSel Head; + typedef Templates21 Tail; +}; + +template +struct Templates23 { + typedef TemplateSel Head; + typedef Templates22 Tail; +}; + +template +struct Templates24 { + typedef TemplateSel Head; + typedef Templates23 Tail; +}; + +template +struct Templates25 { + typedef TemplateSel Head; + typedef Templates24 Tail; +}; + +template +struct Templates26 { + typedef TemplateSel Head; + typedef Templates25 Tail; +}; + +template +struct Templates27 { + typedef TemplateSel Head; + typedef Templates26 Tail; +}; + +template +struct Templates28 { + typedef TemplateSel Head; + typedef Templates27 Tail; +}; + +template +struct Templates29 { + typedef TemplateSel Head; + typedef Templates28 Tail; +}; + +template +struct Templates30 { + typedef TemplateSel Head; + typedef Templates29 Tail; +}; + +template +struct Templates31 { + typedef TemplateSel Head; + typedef Templates30 Tail; +}; + +template +struct Templates32 { + typedef TemplateSel Head; + typedef Templates31 Tail; +}; + +template +struct Templates33 { + typedef TemplateSel Head; + typedef Templates32 Tail; +}; + +template +struct Templates34 { + typedef TemplateSel Head; + typedef Templates33 Tail; +}; + +template +struct Templates35 { + typedef TemplateSel Head; + typedef Templates34 Tail; +}; + +template +struct Templates36 { + typedef TemplateSel Head; + typedef Templates35 Tail; +}; + +template +struct Templates37 { + typedef TemplateSel Head; + typedef Templates36 Tail; +}; + +template +struct Templates38 { + typedef TemplateSel Head; + typedef Templates37 Tail; +}; + +template +struct Templates39 { + typedef TemplateSel Head; + typedef Templates38 Tail; +}; + +template +struct Templates40 { + typedef TemplateSel Head; + typedef Templates39 Tail; +}; + +template +struct Templates41 { + typedef TemplateSel Head; + typedef Templates40 Tail; +}; + +template +struct Templates42 { + typedef TemplateSel Head; + typedef Templates41 Tail; +}; + +template +struct Templates43 { + typedef TemplateSel Head; + typedef Templates42 Tail; +}; + +template +struct Templates44 { + typedef TemplateSel Head; + typedef Templates43 Tail; +}; + +template +struct Templates45 { + typedef TemplateSel Head; + typedef Templates44 Tail; +}; + +template +struct Templates46 { + typedef TemplateSel Head; + typedef Templates45 Tail; +}; + +template +struct Templates47 { + typedef TemplateSel Head; + typedef Templates46 Tail; +}; + +template +struct Templates48 { + typedef TemplateSel Head; + typedef Templates47 Tail; +}; + +template +struct Templates49 { + typedef TemplateSel Head; + typedef Templates48 Tail; +}; + +template +struct Templates50 { + typedef TemplateSel Head; + typedef Templates49 Tail; +}; + + +// We don't want to require the users to write TemplatesN<...> directly, +// as that would require them to count the length. Templates<...> is much +// easier to write, but generates horrible messages when there is a +// compiler error, as gcc insists on printing out each template +// argument, even if it has the default value (this means Templates +// will appear as Templates in the compiler +// errors). +// +// Our solution is to combine the best part of the two approaches: a +// user would write Templates, and Google Test will translate +// that to TemplatesN internally to make error messages +// readable. The translation is done by the 'type' member of the +// Templates template. +template +struct Templates { + typedef Templates50 type; +}; + +template <> +struct Templates { + typedef Templates0 type; +}; +template +struct Templates { + typedef Templates1 type; +}; +template +struct Templates { + typedef Templates2 type; +}; +template +struct Templates { + typedef Templates3 type; +}; +template +struct Templates { + typedef Templates4 type; +}; +template +struct Templates { + typedef Templates5 type; +}; +template +struct Templates { + typedef Templates6 type; +}; +template +struct Templates { + typedef Templates7 type; +}; +template +struct Templates { + typedef Templates8 type; +}; +template +struct Templates { + typedef Templates9 type; +}; +template +struct Templates { + typedef Templates10 type; +}; +template +struct Templates { + typedef Templates11 type; +}; +template +struct Templates { + typedef Templates12 type; +}; +template +struct Templates { + typedef Templates13 type; +}; +template +struct Templates { + typedef Templates14 type; +}; +template +struct Templates { + typedef Templates15 type; +}; +template +struct Templates { + typedef Templates16 type; +}; +template +struct Templates { + typedef Templates17 type; +}; +template +struct Templates { + typedef Templates18 type; +}; +template +struct Templates { + typedef Templates19 type; +}; +template +struct Templates { + typedef Templates20 type; +}; +template +struct Templates { + typedef Templates21 type; +}; +template +struct Templates { + typedef Templates22 type; +}; +template +struct Templates { + typedef Templates23 type; +}; +template +struct Templates { + typedef Templates24 type; +}; +template +struct Templates { + typedef Templates25 type; +}; +template +struct Templates { + typedef Templates26 type; +}; +template +struct Templates { + typedef Templates27 type; +}; +template +struct Templates { + typedef Templates28 type; +}; +template +struct Templates { + typedef Templates29 type; +}; +template +struct Templates { + typedef Templates30 type; +}; +template +struct Templates { + typedef Templates31 type; +}; +template +struct Templates { + typedef Templates32 type; +}; +template +struct Templates { + typedef Templates33 type; +}; +template +struct Templates { + typedef Templates34 type; +}; +template +struct Templates { + typedef Templates35 type; +}; +template +struct Templates { + typedef Templates36 type; +}; +template +struct Templates { + typedef Templates37 type; +}; +template +struct Templates { + typedef Templates38 type; +}; +template +struct Templates { + typedef Templates39 type; +}; +template +struct Templates { + typedef Templates40 type; +}; +template +struct Templates { + typedef Templates41 type; +}; +template +struct Templates { + typedef Templates42 type; +}; +template +struct Templates { + typedef Templates43 type; +}; +template +struct Templates { + typedef Templates44 type; +}; +template +struct Templates { + typedef Templates45 type; +}; +template +struct Templates { + typedef Templates46 type; +}; +template +struct Templates { + typedef Templates47 type; +}; +template +struct Templates { + typedef Templates48 type; +}; +template +struct Templates { + typedef Templates49 type; +}; + +// The TypeList template makes it possible to use either a single type +// or a Types<...> list in TYPED_TEST_CASE() and +// INSTANTIATE_TYPED_TEST_CASE_P(). + +template +struct TypeList { typedef Types1 type; }; + +template +struct TypeList > { + typedef typename Types::type type; +}; + +} // namespace internal +} // namespace testing + +#endif // GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ + +// Due to C++ preprocessor weirdness, we need double indirection to +// concatenate two tokens when one of them is __LINE__. Writing +// +// foo ## __LINE__ +// +// will result in the token foo__LINE__, instead of foo followed by +// the current line number. For more details, see +// http://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.6 +#define GTEST_CONCAT_TOKEN_(foo, bar) GTEST_CONCAT_TOKEN_IMPL_(foo, bar) +#define GTEST_CONCAT_TOKEN_IMPL_(foo, bar) foo ## bar + +// Google Test defines the testing::Message class to allow construction of +// test messages via the << operator. The idea is that anything +// streamable to std::ostream can be streamed to a testing::Message. +// This allows a user to use his own types in Google Test assertions by +// overloading the << operator. +// +// util/gtl/stl_logging-inl.h overloads << for STL containers. These +// overloads cannot be defined in the std namespace, as that will be +// undefined behavior. Therefore, they are defined in the global +// namespace instead. +// +// C++'s symbol lookup rule (i.e. Koenig lookup) says that these +// overloads are visible in either the std namespace or the global +// namespace, but not other namespaces, including the testing +// namespace which Google Test's Message class is in. +// +// To allow STL containers (and other types that has a << operator +// defined in the global namespace) to be used in Google Test assertions, +// testing::Message must access the custom << operator from the global +// namespace. Hence this helper function. +// +// Note: Jeffrey Yasskin suggested an alternative fix by "using +// ::operator<<;" in the definition of Message's operator<<. That fix +// doesn't require a helper function, but unfortunately doesn't +// compile with MSVC. +template +inline void GTestStreamToHelper(std::ostream* os, const T& val) { + *os << val; +} + +namespace testing { + +// Forward declaration of classes. + +class AssertionResult; // Result of an assertion. +class Message; // Represents a failure message. +class Test; // Represents a test. +class TestInfo; // Information about a test. +class TestPartResult; // Result of a test part. +class UnitTest; // A collection of test cases. + +namespace internal { + +struct TraceInfo; // Information about a trace point. +class ScopedTrace; // Implements scoped trace. +class TestInfoImpl; // Opaque implementation of TestInfo +class UnitTestImpl; // Opaque implementation of UnitTest + +// How many times InitGoogleTest() has been called. +extern int g_init_gtest_count; + +// The text used in failure messages to indicate the start of the +// stack trace. +GTEST_API_ extern const char kStackTraceMarker[]; + +// A secret type that Google Test users don't know about. It has no +// definition on purpose. Therefore it's impossible to create a +// Secret object, which is what we want. +class Secret; + +// Two overloaded helpers for checking at compile time whether an +// expression is a null pointer literal (i.e. NULL or any 0-valued +// compile-time integral constant). Their return values have +// different sizes, so we can use sizeof() to test which version is +// picked by the compiler. These helpers have no implementations, as +// we only need their signatures. +// +// Given IsNullLiteralHelper(x), the compiler will pick the first +// version if x can be implicitly converted to Secret*, and pick the +// second version otherwise. Since Secret is a secret and incomplete +// type, the only expression a user can write that has type Secret* is +// a null pointer literal. Therefore, we know that x is a null +// pointer literal if and only if the first version is picked by the +// compiler. +char IsNullLiteralHelper(Secret* p); +char (&IsNullLiteralHelper(...))[2]; // NOLINT + +// A compile-time bool constant that is true if and only if x is a +// null pointer literal (i.e. NULL or any 0-valued compile-time +// integral constant). +#ifdef GTEST_ELLIPSIS_NEEDS_POD_ +// We lose support for NULL detection where the compiler doesn't like +// passing non-POD classes through ellipsis (...). +#define GTEST_IS_NULL_LITERAL_(x) false +#else +#define GTEST_IS_NULL_LITERAL_(x) \ + (sizeof(::testing::internal::IsNullLiteralHelper(x)) == 1) +#endif // GTEST_ELLIPSIS_NEEDS_POD_ + +// Appends the user-supplied message to the Google-Test-generated message. +GTEST_API_ String AppendUserMessage(const String& gtest_msg, + const Message& user_msg); + +// A helper class for creating scoped traces in user programs. +class GTEST_API_ ScopedTrace { + public: + // The c'tor pushes the given source file location and message onto + // a trace stack maintained by Google Test. + ScopedTrace(const char* file, int line, const Message& message); + + // The d'tor pops the info pushed by the c'tor. + // + // Note that the d'tor is not virtual in order to be efficient. + // Don't inherit from ScopedTrace! + ~ScopedTrace(); + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedTrace); +} GTEST_ATTRIBUTE_UNUSED_; // A ScopedTrace object does its job in its + // c'tor and d'tor. Therefore it doesn't + // need to be used otherwise. + +// Converts a streamable value to a String. A NULL pointer is +// converted to "(null)". When the input value is a ::string, +// ::std::string, ::wstring, or ::std::wstring object, each NUL +// character in it is replaced with "\\0". +// Declared here but defined in gtest.h, so that it has access +// to the definition of the Message class, required by the ARM +// compiler. +template +String StreamableToString(const T& streamable); + +// Formats a value to be used in a failure message. + +#ifdef GTEST_NEEDS_IS_POINTER_ + +// These are needed as the Nokia Symbian and IBM XL C/C++ compilers +// cannot decide between const T& and const T* in a function template. +// These compilers _can_ decide between class template specializations +// for T and T*, so a tr1::type_traits-like is_pointer works, and we +// can overload on that. + +// This overload makes sure that all pointers (including +// those to char or wchar_t) are printed as raw pointers. +template +inline String FormatValueForFailureMessage(internal::true_type /*dummy*/, + T* pointer) { + return StreamableToString(static_cast(pointer)); +} + +template +inline String FormatValueForFailureMessage(internal::false_type /*dummy*/, + const T& value) { + return StreamableToString(value); +} + +template +inline String FormatForFailureMessage(const T& value) { + return FormatValueForFailureMessage( + typename internal::is_pointer::type(), value); +} + +#else + +// These are needed as the above solution using is_pointer has the +// limitation that T cannot be a type without external linkage, when +// compiled using MSVC. + +template +inline String FormatForFailureMessage(const T& value) { + return StreamableToString(value); +} + +// This overload makes sure that all pointers (including +// those to char or wchar_t) are printed as raw pointers. +template +inline String FormatForFailureMessage(T* pointer) { + return StreamableToString(static_cast(pointer)); +} + +#endif // GTEST_NEEDS_IS_POINTER_ + +// These overloaded versions handle narrow and wide characters. +GTEST_API_ String FormatForFailureMessage(char ch); +GTEST_API_ String FormatForFailureMessage(wchar_t wchar); + +// When this operand is a const char* or char*, and the other operand +// is a ::std::string or ::string, we print this operand as a C string +// rather than a pointer. We do the same for wide strings. + +// This internal macro is used to avoid duplicated code. +#define GTEST_FORMAT_IMPL_(operand2_type, operand1_printer)\ +inline String FormatForComparisonFailureMessage(\ + operand2_type::value_type* str, const operand2_type& /*operand2*/) {\ + return operand1_printer(str);\ +}\ +inline String FormatForComparisonFailureMessage(\ + const operand2_type::value_type* str, const operand2_type& /*operand2*/) {\ + return operand1_printer(str);\ +} + +GTEST_FORMAT_IMPL_(::std::string, String::ShowCStringQuoted) +#if GTEST_HAS_STD_WSTRING +GTEST_FORMAT_IMPL_(::std::wstring, String::ShowWideCStringQuoted) +#endif // GTEST_HAS_STD_WSTRING + +#if GTEST_HAS_GLOBAL_STRING +GTEST_FORMAT_IMPL_(::string, String::ShowCStringQuoted) +#endif // GTEST_HAS_GLOBAL_STRING +#if GTEST_HAS_GLOBAL_WSTRING +GTEST_FORMAT_IMPL_(::wstring, String::ShowWideCStringQuoted) +#endif // GTEST_HAS_GLOBAL_WSTRING + +#undef GTEST_FORMAT_IMPL_ + +// Constructs and returns the message for an equality assertion +// (e.g. ASSERT_EQ, EXPECT_STREQ, etc) failure. +// +// The first four parameters are the expressions used in the assertion +// and their values, as strings. For example, for ASSERT_EQ(foo, bar) +// where foo is 5 and bar is 6, we have: +// +// expected_expression: "foo" +// actual_expression: "bar" +// expected_value: "5" +// actual_value: "6" +// +// The ignoring_case parameter is true iff the assertion is a +// *_STRCASEEQ*. When it's true, the string " (ignoring case)" will +// be inserted into the message. +GTEST_API_ AssertionResult EqFailure(const char* expected_expression, + const char* actual_expression, + const String& expected_value, + const String& actual_value, + bool ignoring_case); + +// Constructs a failure message for Boolean assertions such as EXPECT_TRUE. +GTEST_API_ String GetBoolAssertionFailureMessage( + const AssertionResult& assertion_result, + const char* expression_text, + const char* actual_predicate_value, + const char* expected_predicate_value); + +// This template class represents an IEEE floating-point number +// (either single-precision or double-precision, depending on the +// template parameters). +// +// The purpose of this class is to do more sophisticated number +// comparison. (Due to round-off error, etc, it's very unlikely that +// two floating-points will be equal exactly. Hence a naive +// comparison by the == operation often doesn't work.) +// +// Format of IEEE floating-point: +// +// The most-significant bit being the leftmost, an IEEE +// floating-point looks like +// +// sign_bit exponent_bits fraction_bits +// +// Here, sign_bit is a single bit that designates the sign of the +// number. +// +// For float, there are 8 exponent bits and 23 fraction bits. +// +// For double, there are 11 exponent bits and 52 fraction bits. +// +// More details can be found at +// http://en.wikipedia.org/wiki/IEEE_floating-point_standard. +// +// Template parameter: +// +// RawType: the raw floating-point type (either float or double) +template +class FloatingPoint { + public: + // Defines the unsigned integer type that has the same size as the + // floating point number. + typedef typename TypeWithSize::UInt Bits; + + // Constants. + + // # of bits in a number. + static const size_t kBitCount = 8*sizeof(RawType); + + // # of fraction bits in a number. + static const size_t kFractionBitCount = + std::numeric_limits::digits - 1; + + // # of exponent bits in a number. + static const size_t kExponentBitCount = kBitCount - 1 - kFractionBitCount; + + // The mask for the sign bit. + static const Bits kSignBitMask = static_cast(1) << (kBitCount - 1); + + // The mask for the fraction bits. + static const Bits kFractionBitMask = + ~static_cast(0) >> (kExponentBitCount + 1); + + // The mask for the exponent bits. + static const Bits kExponentBitMask = ~(kSignBitMask | kFractionBitMask); + + // How many ULP's (Units in the Last Place) we want to tolerate when + // comparing two numbers. The larger the value, the more error we + // allow. A 0 value means that two numbers must be exactly the same + // to be considered equal. + // + // The maximum error of a single floating-point operation is 0.5 + // units in the last place. On Intel CPU's, all floating-point + // calculations are done with 80-bit precision, while double has 64 + // bits. Therefore, 4 should be enough for ordinary use. + // + // See the following article for more details on ULP: + // http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm. + static const size_t kMaxUlps = 4; + + // Constructs a FloatingPoint from a raw floating-point number. + // + // On an Intel CPU, passing a non-normalized NAN (Not a Number) + // around may change its bits, although the new value is guaranteed + // to be also a NAN. Therefore, don't expect this constructor to + // preserve the bits in x when x is a NAN. + explicit FloatingPoint(const RawType& x) { u_.value_ = x; } + + // Static methods + + // Reinterprets a bit pattern as a floating-point number. + // + // This function is needed to test the AlmostEquals() method. + static RawType ReinterpretBits(const Bits bits) { + FloatingPoint fp(0); + fp.u_.bits_ = bits; + return fp.u_.value_; + } + + // Returns the floating-point number that represent positive infinity. + static RawType Infinity() { + return ReinterpretBits(kExponentBitMask); + } + + // Non-static methods + + // Returns the bits that represents this number. + const Bits &bits() const { return u_.bits_; } + + // Returns the exponent bits of this number. + Bits exponent_bits() const { return kExponentBitMask & u_.bits_; } + + // Returns the fraction bits of this number. + Bits fraction_bits() const { return kFractionBitMask & u_.bits_; } + + // Returns the sign bit of this number. + Bits sign_bit() const { return kSignBitMask & u_.bits_; } + + // Returns true iff this is NAN (not a number). + bool is_nan() const { + // It's a NAN if the exponent bits are all ones and the fraction + // bits are not entirely zeros. + return (exponent_bits() == kExponentBitMask) && (fraction_bits() != 0); + } + + // Returns true iff this number is at most kMaxUlps ULP's away from + // rhs. In particular, this function: + // + // - returns false if either number is (or both are) NAN. + // - treats really large numbers as almost equal to infinity. + // - thinks +0.0 and -0.0 are 0 DLP's apart. + bool AlmostEquals(const FloatingPoint& rhs) const { + // The IEEE standard says that any comparison operation involving + // a NAN must return false. + if (is_nan() || rhs.is_nan()) return false; + + return DistanceBetweenSignAndMagnitudeNumbers(u_.bits_, rhs.u_.bits_) + <= kMaxUlps; + } + + private: + // The data type used to store the actual floating-point number. + union FloatingPointUnion { + RawType value_; // The raw floating-point number. + Bits bits_; // The bits that represent the number. + }; + + // Converts an integer from the sign-and-magnitude representation to + // the biased representation. More precisely, let N be 2 to the + // power of (kBitCount - 1), an integer x is represented by the + // unsigned number x + N. + // + // For instance, + // + // -N + 1 (the most negative number representable using + // sign-and-magnitude) is represented by 1; + // 0 is represented by N; and + // N - 1 (the biggest number representable using + // sign-and-magnitude) is represented by 2N - 1. + // + // Read http://en.wikipedia.org/wiki/Signed_number_representations + // for more details on signed number representations. + static Bits SignAndMagnitudeToBiased(const Bits &sam) { + if (kSignBitMask & sam) { + // sam represents a negative number. + return ~sam + 1; + } else { + // sam represents a positive number. + return kSignBitMask | sam; + } + } + + // Given two numbers in the sign-and-magnitude representation, + // returns the distance between them as an unsigned number. + static Bits DistanceBetweenSignAndMagnitudeNumbers(const Bits &sam1, + const Bits &sam2) { + const Bits biased1 = SignAndMagnitudeToBiased(sam1); + const Bits biased2 = SignAndMagnitudeToBiased(sam2); + return (biased1 >= biased2) ? (biased1 - biased2) : (biased2 - biased1); + } + + FloatingPointUnion u_; +}; + +// Typedefs the instances of the FloatingPoint template class that we +// care to use. +typedef FloatingPoint Float; +typedef FloatingPoint Double; + +// In order to catch the mistake of putting tests that use different +// test fixture classes in the same test case, we need to assign +// unique IDs to fixture classes and compare them. The TypeId type is +// used to hold such IDs. The user should treat TypeId as an opaque +// type: the only operation allowed on TypeId values is to compare +// them for equality using the == operator. +typedef const void* TypeId; + +template +class TypeIdHelper { + public: + // dummy_ must not have a const type. Otherwise an overly eager + // compiler (e.g. MSVC 7.1 & 8.0) may try to merge + // TypeIdHelper::dummy_ for different Ts as an "optimization". + static bool dummy_; +}; + +template +bool TypeIdHelper::dummy_ = false; + +// GetTypeId() returns the ID of type T. Different values will be +// returned for different types. Calling the function twice with the +// same type argument is guaranteed to return the same ID. +template +TypeId GetTypeId() { + // The compiler is required to allocate a different + // TypeIdHelper::dummy_ variable for each T used to instantiate + // the template. Therefore, the address of dummy_ is guaranteed to + // be unique. + return &(TypeIdHelper::dummy_); +} + +// Returns the type ID of ::testing::Test. Always call this instead +// of GetTypeId< ::testing::Test>() to get the type ID of +// ::testing::Test, as the latter may give the wrong result due to a +// suspected linker bug when compiling Google Test as a Mac OS X +// framework. +GTEST_API_ TypeId GetTestTypeId(); + +// Defines the abstract factory interface that creates instances +// of a Test object. +class TestFactoryBase { + public: + virtual ~TestFactoryBase() {} + + // Creates a test instance to run. The instance is both created and destroyed + // within TestInfoImpl::Run() + virtual Test* CreateTest() = 0; + + protected: + TestFactoryBase() {} + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestFactoryBase); +}; + +// This class provides implementation of TeastFactoryBase interface. +// It is used in TEST and TEST_F macros. +template +class TestFactoryImpl : public TestFactoryBase { + public: + virtual Test* CreateTest() { return new TestClass; } +}; + +#if GTEST_OS_WINDOWS + +// Predicate-formatters for implementing the HRESULT checking macros +// {ASSERT|EXPECT}_HRESULT_{SUCCEEDED|FAILED} +// We pass a long instead of HRESULT to avoid causing an +// include dependency for the HRESULT type. +GTEST_API_ AssertionResult IsHRESULTSuccess(const char* expr, + long hr); // NOLINT +GTEST_API_ AssertionResult IsHRESULTFailure(const char* expr, + long hr); // NOLINT + +#endif // GTEST_OS_WINDOWS + +// Formats a source file path and a line number as they would appear +// in a compiler error message. +inline String FormatFileLocation(const char* file, int line) { + const char* const file_name = file == NULL ? "unknown file" : file; + if (line < 0) { + return String::Format("%s:", file_name); + } +#ifdef _MSC_VER + return String::Format("%s(%d):", file_name, line); +#else + return String::Format("%s:%d:", file_name, line); +#endif // _MSC_VER +} + +// Types of SetUpTestCase() and TearDownTestCase() functions. +typedef void (*SetUpTestCaseFunc)(); +typedef void (*TearDownTestCaseFunc)(); + +// Creates a new TestInfo object and registers it with Google Test; +// returns the created object. +// +// Arguments: +// +// test_case_name: name of the test case +// name: name of the test +// test_case_comment: a comment on the test case that will be included in +// the test output +// comment: a comment on the test that will be included in the +// test output +// fixture_class_id: ID of the test fixture class +// set_up_tc: pointer to the function that sets up the test case +// tear_down_tc: pointer to the function that tears down the test case +// factory: pointer to the factory that creates a test object. +// The newly created TestInfo instance will assume +// ownership of the factory object. +GTEST_API_ TestInfo* MakeAndRegisterTestInfo( + const char* test_case_name, const char* name, + const char* test_case_comment, const char* comment, + TypeId fixture_class_id, + SetUpTestCaseFunc set_up_tc, + TearDownTestCaseFunc tear_down_tc, + TestFactoryBase* factory); + +// If *pstr starts with the given prefix, modifies *pstr to be right +// past the prefix and returns true; otherwise leaves *pstr unchanged +// and returns false. None of pstr, *pstr, and prefix can be NULL. +bool SkipPrefix(const char* prefix, const char** pstr); + +#if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P + +// State of the definition of a type-parameterized test case. +class GTEST_API_ TypedTestCasePState { + public: + TypedTestCasePState() : registered_(false) {} + + // Adds the given test name to defined_test_names_ and return true + // if the test case hasn't been registered; otherwise aborts the + // program. + bool AddTestName(const char* file, int line, const char* case_name, + const char* test_name) { + if (registered_) { + fprintf(stderr, "%s Test %s must be defined before " + "REGISTER_TYPED_TEST_CASE_P(%s, ...).\n", + FormatFileLocation(file, line).c_str(), test_name, case_name); + fflush(stderr); + posix::Abort(); + } + defined_test_names_.insert(test_name); + return true; + } + + // Verifies that registered_tests match the test names in + // defined_test_names_; returns registered_tests if successful, or + // aborts the program otherwise. + const char* VerifyRegisteredTestNames( + const char* file, int line, const char* registered_tests); + + private: + bool registered_; + ::std::set defined_test_names_; +}; + +// Skips to the first non-space char after the first comma in 'str'; +// returns NULL if no comma is found in 'str'. +inline const char* SkipComma(const char* str) { + const char* comma = strchr(str, ','); + if (comma == NULL) { + return NULL; + } + while (isspace(*(++comma))) {} + return comma; +} + +// Returns the prefix of 'str' before the first comma in it; returns +// the entire string if it contains no comma. +inline String GetPrefixUntilComma(const char* str) { + const char* comma = strchr(str, ','); + return comma == NULL ? String(str) : String(str, comma - str); +} + +// TypeParameterizedTest::Register() +// registers a list of type-parameterized tests with Google Test. The +// return value is insignificant - we just need to return something +// such that we can call this function in a namespace scope. +// +// Implementation note: The GTEST_TEMPLATE_ macro declares a template +// template parameter. It's defined in gtest-type-util.h. +template +class TypeParameterizedTest { + public: + // 'index' is the index of the test in the type list 'Types' + // specified in INSTANTIATE_TYPED_TEST_CASE_P(Prefix, TestCase, + // Types). Valid values for 'index' are [0, N - 1] where N is the + // length of Types. + static bool Register(const char* prefix, const char* case_name, + const char* test_names, int index) { + typedef typename Types::Head Type; + typedef Fixture FixtureClass; + typedef typename GTEST_BIND_(TestSel, Type) TestClass; + + // First, registers the first type-parameterized test in the type + // list. + MakeAndRegisterTestInfo( + String::Format("%s%s%s/%d", prefix, prefix[0] == '\0' ? "" : "/", + case_name, index).c_str(), + GetPrefixUntilComma(test_names).c_str(), + String::Format("TypeParam = %s", GetTypeName().c_str()).c_str(), + "", + GetTypeId(), + TestClass::SetUpTestCase, + TestClass::TearDownTestCase, + new TestFactoryImpl); + + // Next, recurses (at compile time) with the tail of the type list. + return TypeParameterizedTest + ::Register(prefix, case_name, test_names, index + 1); + } +}; + +// The base case for the compile time recursion. +template +class TypeParameterizedTest { + public: + static bool Register(const char* /*prefix*/, const char* /*case_name*/, + const char* /*test_names*/, int /*index*/) { + return true; + } +}; + +// TypeParameterizedTestCase::Register() +// registers *all combinations* of 'Tests' and 'Types' with Google +// Test. The return value is insignificant - we just need to return +// something such that we can call this function in a namespace scope. +template +class TypeParameterizedTestCase { + public: + static bool Register(const char* prefix, const char* case_name, + const char* test_names) { + typedef typename Tests::Head Head; + + // First, register the first test in 'Test' for each type in 'Types'. + TypeParameterizedTest::Register( + prefix, case_name, test_names, 0); + + // Next, recurses (at compile time) with the tail of the test list. + return TypeParameterizedTestCase + ::Register(prefix, case_name, SkipComma(test_names)); + } +}; + +// The base case for the compile time recursion. +template +class TypeParameterizedTestCase { + public: + static bool Register(const char* /*prefix*/, const char* /*case_name*/, + const char* /*test_names*/) { + return true; + } +}; + +#endif // GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P + +// Returns the current OS stack trace as a String. +// +// The maximum number of stack frames to be included is specified by +// the gtest_stack_trace_depth flag. The skip_count parameter +// specifies the number of top frames to be skipped, which doesn't +// count against the number of frames to be included. +// +// For example, if Foo() calls Bar(), which in turn calls +// GetCurrentOsStackTraceExceptTop(..., 1), Foo() will be included in +// the trace but Bar() and GetCurrentOsStackTraceExceptTop() won't. +GTEST_API_ String GetCurrentOsStackTraceExceptTop(UnitTest* unit_test, + int skip_count); + +// Helpers for suppressing warnings on unreachable code or constant +// condition. + +// Always returns true. +GTEST_API_ bool AlwaysTrue(); + +// Always returns false. +inline bool AlwaysFalse() { return !AlwaysTrue(); } + +// A simple Linear Congruential Generator for generating random +// numbers with a uniform distribution. Unlike rand() and srand(), it +// doesn't use global state (and therefore can't interfere with user +// code). Unlike rand_r(), it's portable. An LCG isn't very random, +// but it's good enough for our purposes. +class GTEST_API_ Random { + public: + static const UInt32 kMaxRange = 1u << 31; + + explicit Random(UInt32 seed) : state_(seed) {} + + void Reseed(UInt32 seed) { state_ = seed; } + + // Generates a random number from [0, range). Crashes if 'range' is + // 0 or greater than kMaxRange. + UInt32 Generate(UInt32 range); + + private: + UInt32 state_; + GTEST_DISALLOW_COPY_AND_ASSIGN_(Random); +}; + +} // namespace internal +} // namespace testing + +#define GTEST_MESSAGE_(message, result_type) \ + ::testing::internal::AssertHelper(result_type, __FILE__, __LINE__, message) \ + = ::testing::Message() + +#define GTEST_FATAL_FAILURE_(message) \ + return GTEST_MESSAGE_(message, ::testing::TestPartResult::kFatalFailure) + +#define GTEST_NONFATAL_FAILURE_(message) \ + GTEST_MESSAGE_(message, ::testing::TestPartResult::kNonFatalFailure) + +#define GTEST_SUCCESS_(message) \ + GTEST_MESSAGE_(message, ::testing::TestPartResult::kSuccess) + +// Suppresses MSVC warnings 4072 (unreachable code) for the code following +// statement if it returns or throws (or doesn't return or throw in some +// situations). +#define GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement) \ + if (::testing::internal::AlwaysTrue()) { statement; } + +#define GTEST_TEST_THROW_(statement, expected_exception, fail) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (const char* gtest_msg = "") { \ + bool gtest_caught_expected = false; \ + try { \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ + } \ + catch (expected_exception const&) { \ + gtest_caught_expected = true; \ + } \ + catch (...) { \ + gtest_msg = "Expected: " #statement " throws an exception of type " \ + #expected_exception ".\n Actual: it throws a different " \ + "type."; \ + goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \ + } \ + if (!gtest_caught_expected) { \ + gtest_msg = "Expected: " #statement " throws an exception of type " \ + #expected_exception ".\n Actual: it throws nothing."; \ + goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \ + } \ + } else \ + GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__): \ + fail(gtest_msg) + +#define GTEST_TEST_NO_THROW_(statement, fail) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (const char* gtest_msg = "") { \ + try { \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ + } \ + catch (...) { \ + gtest_msg = "Expected: " #statement " doesn't throw an exception.\n" \ + " Actual: it throws."; \ + goto GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__); \ + } \ + } else \ + GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__): \ + fail(gtest_msg) + +#define GTEST_TEST_ANY_THROW_(statement, fail) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (const char* gtest_msg = "") { \ + bool gtest_caught_any = false; \ + try { \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ + } \ + catch (...) { \ + gtest_caught_any = true; \ + } \ + if (!gtest_caught_any) { \ + gtest_msg = "Expected: " #statement " throws an exception.\n" \ + " Actual: it doesn't."; \ + goto GTEST_CONCAT_TOKEN_(gtest_label_testanythrow_, __LINE__); \ + } \ + } else \ + GTEST_CONCAT_TOKEN_(gtest_label_testanythrow_, __LINE__): \ + fail(gtest_msg) + + +// Implements Boolean test assertions such as EXPECT_TRUE. expression can be +// either a boolean expression or an AssertionResult. text is a textual +// represenation of expression as it was passed into the EXPECT_TRUE. +#define GTEST_TEST_BOOLEAN_(expression, text, actual, expected, fail) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (const ::testing::AssertionResult gtest_ar_ = \ + ::testing::AssertionResult(expression)) \ + ; \ + else \ + fail(::testing::internal::GetBoolAssertionFailureMessage(\ + gtest_ar_, text, #actual, #expected).c_str()) + +#define GTEST_TEST_NO_FATAL_FAILURE_(statement, fail) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (const char* gtest_msg = "") { \ + ::testing::internal::HasNewFatalFailureHelper gtest_fatal_failure_checker; \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ + if (gtest_fatal_failure_checker.has_new_fatal_failure()) { \ + gtest_msg = "Expected: " #statement " doesn't generate new fatal " \ + "failures in the current thread.\n" \ + " Actual: it does."; \ + goto GTEST_CONCAT_TOKEN_(gtest_label_testnofatal_, __LINE__); \ + } \ + } else \ + GTEST_CONCAT_TOKEN_(gtest_label_testnofatal_, __LINE__): \ + fail(gtest_msg) + +// Expands to the name of the class that implements the given test. +#define GTEST_TEST_CLASS_NAME_(test_case_name, test_name) \ + test_case_name##_##test_name##_Test + +// Helper macro for defining tests. +#define GTEST_TEST_(test_case_name, test_name, parent_class, parent_id)\ +class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) : public parent_class {\ + public:\ + GTEST_TEST_CLASS_NAME_(test_case_name, test_name)() {}\ + private:\ + virtual void TestBody();\ + static ::testing::TestInfo* const test_info_;\ + GTEST_DISALLOW_COPY_AND_ASSIGN_(\ + GTEST_TEST_CLASS_NAME_(test_case_name, test_name));\ +};\ +\ +::testing::TestInfo* const GTEST_TEST_CLASS_NAME_(test_case_name, test_name)\ + ::test_info_ =\ + ::testing::internal::MakeAndRegisterTestInfo(\ + #test_case_name, #test_name, "", "", \ + (parent_id), \ + parent_class::SetUpTestCase, \ + parent_class::TearDownTestCase, \ + new ::testing::internal::TestFactoryImpl<\ + GTEST_TEST_CLASS_NAME_(test_case_name, test_name)>);\ +void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody() + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: wan@google.com (Zhanyong Wan) +// +// The Google C++ Testing Framework (Google Test) +// +// This header file defines the public API for death tests. It is +// #included by gtest.h so a user doesn't need to include this +// directly. + +#ifndef GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_ +#define GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_ + +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee) +// +// The Google C++ Testing Framework (Google Test) +// +// This header file defines internal utilities needed for implementing +// death tests. They are subject to change without notice. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_ + + +namespace testing { +namespace internal { + +GTEST_DECLARE_string_(internal_run_death_test); + +// Names of the flags (needed for parsing Google Test flags). +const char kDeathTestStyleFlag[] = "death_test_style"; +const char kDeathTestUseFork[] = "death_test_use_fork"; +const char kInternalRunDeathTestFlag[] = "internal_run_death_test"; + +#if GTEST_HAS_DEATH_TEST + +// DeathTest is a class that hides much of the complexity of the +// GTEST_DEATH_TEST_ macro. It is abstract; its static Create method +// returns a concrete class that depends on the prevailing death test +// style, as defined by the --gtest_death_test_style and/or +// --gtest_internal_run_death_test flags. + +// In describing the results of death tests, these terms are used with +// the corresponding definitions: +// +// exit status: The integer exit information in the format specified +// by wait(2) +// exit code: The integer code passed to exit(3), _exit(2), or +// returned from main() +class GTEST_API_ DeathTest { + public: + // Create returns false if there was an error determining the + // appropriate action to take for the current death test; for example, + // if the gtest_death_test_style flag is set to an invalid value. + // The LastMessage method will return a more detailed message in that + // case. Otherwise, the DeathTest pointer pointed to by the "test" + // argument is set. If the death test should be skipped, the pointer + // is set to NULL; otherwise, it is set to the address of a new concrete + // DeathTest object that controls the execution of the current test. + static bool Create(const char* statement, const RE* regex, + const char* file, int line, DeathTest** test); + DeathTest(); + virtual ~DeathTest() { } + + // A helper class that aborts a death test when it's deleted. + class ReturnSentinel { + public: + explicit ReturnSentinel(DeathTest* test) : test_(test) { } + ~ReturnSentinel() { test_->Abort(TEST_ENCOUNTERED_RETURN_STATEMENT); } + private: + DeathTest* const test_; + GTEST_DISALLOW_COPY_AND_ASSIGN_(ReturnSentinel); + } GTEST_ATTRIBUTE_UNUSED_; + + // An enumeration of possible roles that may be taken when a death + // test is encountered. EXECUTE means that the death test logic should + // be executed immediately. OVERSEE means that the program should prepare + // the appropriate environment for a child process to execute the death + // test, then wait for it to complete. + enum TestRole { OVERSEE_TEST, EXECUTE_TEST }; + + // An enumeration of the two reasons that a test might be aborted. + enum AbortReason { TEST_ENCOUNTERED_RETURN_STATEMENT, TEST_DID_NOT_DIE }; + + // Assumes one of the above roles. + virtual TestRole AssumeRole() = 0; + + // Waits for the death test to finish and returns its status. + virtual int Wait() = 0; + + // Returns true if the death test passed; that is, the test process + // exited during the test, its exit status matches a user-supplied + // predicate, and its stderr output matches a user-supplied regular + // expression. + // The user-supplied predicate may be a macro expression rather + // than a function pointer or functor, or else Wait and Passed could + // be combined. + virtual bool Passed(bool exit_status_ok) = 0; + + // Signals that the death test did not die as expected. + virtual void Abort(AbortReason reason) = 0; + + // Returns a human-readable outcome message regarding the outcome of + // the last death test. + static const char* LastMessage(); + + static void set_last_death_test_message(const String& message); + + private: + // A string containing a description of the outcome of the last death test. + static String last_death_test_message_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(DeathTest); +}; + +// Factory interface for death tests. May be mocked out for testing. +class DeathTestFactory { + public: + virtual ~DeathTestFactory() { } + virtual bool Create(const char* statement, const RE* regex, + const char* file, int line, DeathTest** test) = 0; +}; + +// A concrete DeathTestFactory implementation for normal use. +class DefaultDeathTestFactory : public DeathTestFactory { + public: + virtual bool Create(const char* statement, const RE* regex, + const char* file, int line, DeathTest** test); +}; + +// Returns true if exit_status describes a process that was terminated +// by a signal, or exited normally with a nonzero exit code. +GTEST_API_ bool ExitedUnsuccessfully(int exit_status); + +// This macro is for implementing ASSERT_DEATH*, EXPECT_DEATH*, +// ASSERT_EXIT*, and EXPECT_EXIT*. +#define GTEST_DEATH_TEST_(statement, predicate, regex, fail) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (::testing::internal::AlwaysTrue()) { \ + const ::testing::internal::RE& gtest_regex = (regex); \ + ::testing::internal::DeathTest* gtest_dt; \ + if (!::testing::internal::DeathTest::Create(#statement, >est_regex, \ + __FILE__, __LINE__, >est_dt)) { \ + goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \ + } \ + if (gtest_dt != NULL) { \ + ::testing::internal::scoped_ptr< ::testing::internal::DeathTest> \ + gtest_dt_ptr(gtest_dt); \ + switch (gtest_dt->AssumeRole()) { \ + case ::testing::internal::DeathTest::OVERSEE_TEST: \ + if (!gtest_dt->Passed(predicate(gtest_dt->Wait()))) { \ + goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \ + } \ + break; \ + case ::testing::internal::DeathTest::EXECUTE_TEST: { \ + ::testing::internal::DeathTest::ReturnSentinel \ + gtest_sentinel(gtest_dt); \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ + gtest_dt->Abort(::testing::internal::DeathTest::TEST_DID_NOT_DIE); \ + break; \ + } \ + } \ + } \ + } else \ + GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__): \ + fail(::testing::internal::DeathTest::LastMessage()) +// The symbol "fail" here expands to something into which a message +// can be streamed. + +// A class representing the parsed contents of the +// --gtest_internal_run_death_test flag, as it existed when +// RUN_ALL_TESTS was called. +class InternalRunDeathTestFlag { + public: + InternalRunDeathTestFlag(const String& a_file, + int a_line, + int an_index, + int a_write_fd) + : file_(a_file), line_(a_line), index_(an_index), + write_fd_(a_write_fd) {} + + ~InternalRunDeathTestFlag() { + if (write_fd_ >= 0) + posix::Close(write_fd_); + } + + String file() const { return file_; } + int line() const { return line_; } + int index() const { return index_; } + int write_fd() const { return write_fd_; } + + private: + String file_; + int line_; + int index_; + int write_fd_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(InternalRunDeathTestFlag); +}; + +// Returns a newly created InternalRunDeathTestFlag object with fields +// initialized from the GTEST_FLAG(internal_run_death_test) flag if +// the flag is specified; otherwise returns NULL. +InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag(); + +#else // GTEST_HAS_DEATH_TEST + +// This macro is used for implementing macros such as +// EXPECT_DEATH_IF_SUPPORTED and ASSERT_DEATH_IF_SUPPORTED on systems where +// death tests are not supported. Those macros must compile on such systems +// iff EXPECT_DEATH and ASSERT_DEATH compile with the same parameters on +// systems that support death tests. This allows one to write such a macro +// on a system that does not support death tests and be sure that it will +// compile on a death-test supporting system. +// +// Parameters: +// statement - A statement that a macro such as EXPECT_DEATH would test +// for program termination. This macro has to make sure this +// statement is compiled but not executed, to ensure that +// EXPECT_DEATH_IF_SUPPORTED compiles with a certain +// parameter iff EXPECT_DEATH compiles with it. +// regex - A regex that a macro such as EXPECT_DEATH would use to test +// the output of statement. This parameter has to be +// compiled but not evaluated by this macro, to ensure that +// this macro only accepts expressions that a macro such as +// EXPECT_DEATH would accept. +// terminator - Must be an empty statement for EXPECT_DEATH_IF_SUPPORTED +// and a return statement for ASSERT_DEATH_IF_SUPPORTED. +// This ensures that ASSERT_DEATH_IF_SUPPORTED will not +// compile inside functions where ASSERT_DEATH doesn't +// compile. +// +// The branch that has an always false condition is used to ensure that +// statement and regex are compiled (and thus syntactically correct) but +// never executed. The unreachable code macro protects the terminator +// statement from generating an 'unreachable code' warning in case +// statement unconditionally returns or throws. The Message constructor at +// the end allows the syntax of streaming additional messages into the +// macro, for compilational compatibility with EXPECT_DEATH/ASSERT_DEATH. +#define GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, terminator) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (::testing::internal::AlwaysTrue()) { \ + GTEST_LOG_(WARNING) \ + << "Death tests are not supported on this platform.\n" \ + << "Statement '" #statement "' cannot be verified."; \ + } else if (::testing::internal::AlwaysFalse()) { \ + ::testing::internal::RE::PartialMatch(".*", (regex)); \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ + terminator; \ + } else \ + ::testing::Message() + +#endif // GTEST_HAS_DEATH_TEST + +} // namespace internal +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_ + +namespace testing { + +// This flag controls the style of death tests. Valid values are "threadsafe", +// meaning that the death test child process will re-execute the test binary +// from the start, running only a single death test, or "fast", +// meaning that the child process will execute the test logic immediately +// after forking. +GTEST_DECLARE_string_(death_test_style); + +#if GTEST_HAS_DEATH_TEST + +// The following macros are useful for writing death tests. + +// Here's what happens when an ASSERT_DEATH* or EXPECT_DEATH* is +// executed: +// +// 1. It generates a warning if there is more than one active +// thread. This is because it's safe to fork() or clone() only +// when there is a single thread. +// +// 2. The parent process clone()s a sub-process and runs the death +// test in it; the sub-process exits with code 0 at the end of the +// death test, if it hasn't exited already. +// +// 3. The parent process waits for the sub-process to terminate. +// +// 4. The parent process checks the exit code and error message of +// the sub-process. +// +// Examples: +// +// ASSERT_DEATH(server.SendMessage(56, "Hello"), "Invalid port number"); +// for (int i = 0; i < 5; i++) { +// EXPECT_DEATH(server.ProcessRequest(i), +// "Invalid request .* in ProcessRequest()") +// << "Failed to die on request " << i); +// } +// +// ASSERT_EXIT(server.ExitNow(), ::testing::ExitedWithCode(0), "Exiting"); +// +// bool KilledBySIGHUP(int exit_code) { +// return WIFSIGNALED(exit_code) && WTERMSIG(exit_code) == SIGHUP; +// } +// +// ASSERT_EXIT(client.HangUpServer(), KilledBySIGHUP, "Hanging up!"); +// +// On the regular expressions used in death tests: +// +// On POSIX-compliant systems (*nix), we use the library, +// which uses the POSIX extended regex syntax. +// +// On other platforms (e.g. Windows), we only support a simple regex +// syntax implemented as part of Google Test. This limited +// implementation should be enough most of the time when writing +// death tests; though it lacks many features you can find in PCRE +// or POSIX extended regex syntax. For example, we don't support +// union ("x|y"), grouping ("(xy)"), brackets ("[xy]"), and +// repetition count ("x{5,7}"), among others. +// +// Below is the syntax that we do support. We chose it to be a +// subset of both PCRE and POSIX extended regex, so it's easy to +// learn wherever you come from. In the following: 'A' denotes a +// literal character, period (.), or a single \\ escape sequence; +// 'x' and 'y' denote regular expressions; 'm' and 'n' are for +// natural numbers. +// +// c matches any literal character c +// \\d matches any decimal digit +// \\D matches any character that's not a decimal digit +// \\f matches \f +// \\n matches \n +// \\r matches \r +// \\s matches any ASCII whitespace, including \n +// \\S matches any character that's not a whitespace +// \\t matches \t +// \\v matches \v +// \\w matches any letter, _, or decimal digit +// \\W matches any character that \\w doesn't match +// \\c matches any literal character c, which must be a punctuation +// . matches any single character except \n +// A? matches 0 or 1 occurrences of A +// A* matches 0 or many occurrences of A +// A+ matches 1 or many occurrences of A +// ^ matches the beginning of a string (not that of each line) +// $ matches the end of a string (not that of each line) +// xy matches x followed by y +// +// If you accidentally use PCRE or POSIX extended regex features +// not implemented by us, you will get a run-time failure. In that +// case, please try to rewrite your regular expression within the +// above syntax. +// +// This implementation is *not* meant to be as highly tuned or robust +// as a compiled regex library, but should perform well enough for a +// death test, which already incurs significant overhead by launching +// a child process. +// +// Known caveats: +// +// A "threadsafe" style death test obtains the path to the test +// program from argv[0] and re-executes it in the sub-process. For +// simplicity, the current implementation doesn't search the PATH +// when launching the sub-process. This means that the user must +// invoke the test program via a path that contains at least one +// path separator (e.g. path/to/foo_test and +// /absolute/path/to/bar_test are fine, but foo_test is not). This +// is rarely a problem as people usually don't put the test binary +// directory in PATH. +// +// TODO(wan@google.com): make thread-safe death tests search the PATH. + +// Asserts that a given statement causes the program to exit, with an +// integer exit status that satisfies predicate, and emitting error output +// that matches regex. +#define ASSERT_EXIT(statement, predicate, regex) \ + GTEST_DEATH_TEST_(statement, predicate, regex, GTEST_FATAL_FAILURE_) + +// Like ASSERT_EXIT, but continues on to successive tests in the +// test case, if any: +#define EXPECT_EXIT(statement, predicate, regex) \ + GTEST_DEATH_TEST_(statement, predicate, regex, GTEST_NONFATAL_FAILURE_) + +// Asserts that a given statement causes the program to exit, either by +// explicitly exiting with a nonzero exit code or being killed by a +// signal, and emitting error output that matches regex. +#define ASSERT_DEATH(statement, regex) \ + ASSERT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex) + +// Like ASSERT_DEATH, but continues on to successive tests in the +// test case, if any: +#define EXPECT_DEATH(statement, regex) \ + EXPECT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex) + +// Two predicate classes that can be used in {ASSERT,EXPECT}_EXIT*: + +// Tests that an exit code describes a normal exit with a given exit code. +class GTEST_API_ ExitedWithCode { + public: + explicit ExitedWithCode(int exit_code); + bool operator()(int exit_status) const; + private: + // No implementation - assignment is unsupported. + void operator=(const ExitedWithCode& other); + + const int exit_code_; +}; + +#if !GTEST_OS_WINDOWS +// Tests that an exit code describes an exit due to termination by a +// given signal. +class GTEST_API_ KilledBySignal { + public: + explicit KilledBySignal(int signum); + bool operator()(int exit_status) const; + private: + const int signum_; +}; +#endif // !GTEST_OS_WINDOWS + +// EXPECT_DEBUG_DEATH asserts that the given statements die in debug mode. +// The death testing framework causes this to have interesting semantics, +// since the sideeffects of the call are only visible in opt mode, and not +// in debug mode. +// +// In practice, this can be used to test functions that utilize the +// LOG(DFATAL) macro using the following style: +// +// int DieInDebugOr12(int* sideeffect) { +// if (sideeffect) { +// *sideeffect = 12; +// } +// LOG(DFATAL) << "death"; +// return 12; +// } +// +// TEST(TestCase, TestDieOr12WorksInDgbAndOpt) { +// int sideeffect = 0; +// // Only asserts in dbg. +// EXPECT_DEBUG_DEATH(DieInDebugOr12(&sideeffect), "death"); +// +// #ifdef NDEBUG +// // opt-mode has sideeffect visible. +// EXPECT_EQ(12, sideeffect); +// #else +// // dbg-mode no visible sideeffect. +// EXPECT_EQ(0, sideeffect); +// #endif +// } +// +// This will assert that DieInDebugReturn12InOpt() crashes in debug +// mode, usually due to a DCHECK or LOG(DFATAL), but returns the +// appropriate fallback value (12 in this case) in opt mode. If you +// need to test that a function has appropriate side-effects in opt +// mode, include assertions against the side-effects. A general +// pattern for this is: +// +// EXPECT_DEBUG_DEATH({ +// // Side-effects here will have an effect after this statement in +// // opt mode, but none in debug mode. +// EXPECT_EQ(12, DieInDebugOr12(&sideeffect)); +// }, "death"); +// +#ifdef NDEBUG + +#define EXPECT_DEBUG_DEATH(statement, regex) \ + do { statement; } while (::testing::internal::AlwaysFalse()) + +#define ASSERT_DEBUG_DEATH(statement, regex) \ + do { statement; } while (::testing::internal::AlwaysFalse()) + +#else + +#define EXPECT_DEBUG_DEATH(statement, regex) \ + EXPECT_DEATH(statement, regex) + +#define ASSERT_DEBUG_DEATH(statement, regex) \ + ASSERT_DEATH(statement, regex) + +#endif // NDEBUG for EXPECT_DEBUG_DEATH +#endif // GTEST_HAS_DEATH_TEST + +// EXPECT_DEATH_IF_SUPPORTED(statement, regex) and +// ASSERT_DEATH_IF_SUPPORTED(statement, regex) expand to real death tests if +// death tests are supported; otherwise they just issue a warning. This is +// useful when you are combining death test assertions with normal test +// assertions in one test. +#if GTEST_HAS_DEATH_TEST +#define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \ + EXPECT_DEATH(statement, regex) +#define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \ + ASSERT_DEATH(statement, regex) +#else +#define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \ + GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, ) +#define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \ + GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, return) +#endif + +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: wan@google.com (Zhanyong Wan) +// +// The Google C++ Testing Framework (Google Test) +// +// This header file defines the Message class. +// +// IMPORTANT NOTE: Due to limitation of the C++ language, we have to +// leave some internal implementation details in this header file. +// They are clearly marked by comments like this: +// +// // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +// +// Such code is NOT meant to be used by a user directly, and is subject +// to CHANGE WITHOUT NOTICE. Therefore DO NOT DEPEND ON IT in a user +// program! + +#ifndef GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_ +#define GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_ + +#include + + +namespace testing { + +// The Message class works like an ostream repeater. +// +// Typical usage: +// +// 1. You stream a bunch of values to a Message object. +// It will remember the text in a StrStream. +// 2. Then you stream the Message object to an ostream. +// This causes the text in the Message to be streamed +// to the ostream. +// +// For example; +// +// testing::Message foo; +// foo << 1 << " != " << 2; +// std::cout << foo; +// +// will print "1 != 2". +// +// Message is not intended to be inherited from. In particular, its +// destructor is not virtual. +// +// Note that StrStream behaves differently in gcc and in MSVC. You +// can stream a NULL char pointer to it in the former, but not in the +// latter (it causes an access violation if you do). The Message +// class hides this difference by treating a NULL char pointer as +// "(null)". +class GTEST_API_ Message { + private: + // The type of basic IO manipulators (endl, ends, and flush) for + // narrow streams. + typedef std::ostream& (*BasicNarrowIoManip)(std::ostream&); + + public: + // Constructs an empty Message. + // We allocate the StrStream separately because it otherwise each use of + // ASSERT/EXPECT in a procedure adds over 200 bytes to the procedure's + // stack frame leading to huge stack frames in some cases; gcc does not reuse + // the stack space. + Message() : ss_(new internal::StrStream) { + // By default, we want there to be enough precision when printing + // a double to a Message. + *ss_ << std::setprecision(std::numeric_limits::digits10 + 2); + } + + // Copy constructor. + Message(const Message& msg) : ss_(new internal::StrStream) { // NOLINT + *ss_ << msg.GetString(); + } + + // Constructs a Message from a C-string. + explicit Message(const char* str) : ss_(new internal::StrStream) { + *ss_ << str; + } + + ~Message() { delete ss_; } +#if GTEST_OS_SYMBIAN + // Streams a value (either a pointer or not) to this object. + template + inline Message& operator <<(const T& value) { + StreamHelper(typename internal::is_pointer::type(), value); + return *this; + } +#else + // Streams a non-pointer value to this object. + template + inline Message& operator <<(const T& val) { + ::GTestStreamToHelper(ss_, val); + return *this; + } + + // Streams a pointer value to this object. + // + // This function is an overload of the previous one. When you + // stream a pointer to a Message, this definition will be used as it + // is more specialized. (The C++ Standard, section + // [temp.func.order].) If you stream a non-pointer, then the + // previous definition will be used. + // + // The reason for this overload is that streaming a NULL pointer to + // ostream is undefined behavior. Depending on the compiler, you + // may get "0", "(nil)", "(null)", or an access violation. To + // ensure consistent result across compilers, we always treat NULL + // as "(null)". + template + inline Message& operator <<(T* const& pointer) { // NOLINT + if (pointer == NULL) { + *ss_ << "(null)"; + } else { + ::GTestStreamToHelper(ss_, pointer); + } + return *this; + } +#endif // GTEST_OS_SYMBIAN + + // Since the basic IO manipulators are overloaded for both narrow + // and wide streams, we have to provide this specialized definition + // of operator <<, even though its body is the same as the + // templatized version above. Without this definition, streaming + // endl or other basic IO manipulators to Message will confuse the + // compiler. + Message& operator <<(BasicNarrowIoManip val) { + *ss_ << val; + return *this; + } + + // Instead of 1/0, we want to see true/false for bool values. + Message& operator <<(bool b) { + return *this << (b ? "true" : "false"); + } + + // These two overloads allow streaming a wide C string to a Message + // using the UTF-8 encoding. + Message& operator <<(const wchar_t* wide_c_str) { + return *this << internal::String::ShowWideCString(wide_c_str); + } + Message& operator <<(wchar_t* wide_c_str) { + return *this << internal::String::ShowWideCString(wide_c_str); + } + +#if GTEST_HAS_STD_WSTRING + // Converts the given wide string to a narrow string using the UTF-8 + // encoding, and streams the result to this Message object. + Message& operator <<(const ::std::wstring& wstr); +#endif // GTEST_HAS_STD_WSTRING + +#if GTEST_HAS_GLOBAL_WSTRING + // Converts the given wide string to a narrow string using the UTF-8 + // encoding, and streams the result to this Message object. + Message& operator <<(const ::wstring& wstr); +#endif // GTEST_HAS_GLOBAL_WSTRING + + // Gets the text streamed to this object so far as a String. + // Each '\0' character in the buffer is replaced with "\\0". + // + // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. + internal::String GetString() const { + return internal::StrStreamToString(ss_); + } + + private: +#if GTEST_OS_SYMBIAN + // These are needed as the Nokia Symbian Compiler cannot decide between + // const T& and const T* in a function template. The Nokia compiler _can_ + // decide between class template specializations for T and T*, so a + // tr1::type_traits-like is_pointer works, and we can overload on that. + template + inline void StreamHelper(internal::true_type /*dummy*/, T* pointer) { + if (pointer == NULL) { + *ss_ << "(null)"; + } else { + ::GTestStreamToHelper(ss_, pointer); + } + } + template + inline void StreamHelper(internal::false_type /*dummy*/, const T& value) { + ::GTestStreamToHelper(ss_, value); + } +#endif // GTEST_OS_SYMBIAN + + // We'll hold the text streamed to this object here. + internal::StrStream* const ss_; + + // We declare (but don't implement) this to prevent the compiler + // from implementing the assignment operator. + void operator=(const Message&); +}; + +// Streams a Message to an ostream. +inline std::ostream& operator <<(std::ostream& os, const Message& sb) { + return os << sb.GetString(); +} + +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_ +// This file was GENERATED by a script. DO NOT EDIT BY HAND!!! + +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: vladl@google.com (Vlad Losev) +// +// Macros and functions for implementing parameterized tests +// in Google C++ Testing Framework (Google Test) +// +// This file is generated by a SCRIPT. DO NOT EDIT BY HAND! +// +#ifndef GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_ +#define GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_ + + +// Value-parameterized tests allow you to test your code with different +// parameters without writing multiple copies of the same test. +// +// Here is how you use value-parameterized tests: + +#if 0 + +// To write value-parameterized tests, first you should define a fixture +// class. It must be derived from testing::TestWithParam, where T is +// the type of your parameter values. TestWithParam is itself derived +// from testing::Test. T can be any copyable type. If it's a raw pointer, +// you are responsible for managing the lifespan of the pointed values. + +class FooTest : public ::testing::TestWithParam { + // You can implement all the usual class fixture members here. +}; + +// Then, use the TEST_P macro to define as many parameterized tests +// for this fixture as you want. The _P suffix is for "parameterized" +// or "pattern", whichever you prefer to think. + +TEST_P(FooTest, DoesBlah) { + // Inside a test, access the test parameter with the GetParam() method + // of the TestWithParam class: + EXPECT_TRUE(foo.Blah(GetParam())); + ... +} + +TEST_P(FooTest, HasBlahBlah) { + ... +} + +// Finally, you can use INSTANTIATE_TEST_CASE_P to instantiate the test +// case with any set of parameters you want. Google Test defines a number +// of functions for generating test parameters. They return what we call +// (surprise!) parameter generators. Here is a summary of them, which +// are all in the testing namespace: +// +// +// Range(begin, end [, step]) - Yields values {begin, begin+step, +// begin+step+step, ...}. The values do not +// include end. step defaults to 1. +// Values(v1, v2, ..., vN) - Yields values {v1, v2, ..., vN}. +// ValuesIn(container) - Yields values from a C-style array, an STL +// ValuesIn(begin,end) container, or an iterator range [begin, end). +// Bool() - Yields sequence {false, true}. +// Combine(g1, g2, ..., gN) - Yields all combinations (the Cartesian product +// for the math savvy) of the values generated +// by the N generators. +// +// For more details, see comments at the definitions of these functions below +// in this file. +// +// The following statement will instantiate tests from the FooTest test case +// each with parameter values "meeny", "miny", and "moe". + +INSTANTIATE_TEST_CASE_P(InstantiationName, + FooTest, + Values("meeny", "miny", "moe")); + +// To distinguish different instances of the pattern, (yes, you +// can instantiate it more then once) the first argument to the +// INSTANTIATE_TEST_CASE_P macro is a prefix that will be added to the +// actual test case name. Remember to pick unique prefixes for different +// instantiations. The tests from the instantiation above will have +// these names: +// +// * InstantiationName/FooTest.DoesBlah/0 for "meeny" +// * InstantiationName/FooTest.DoesBlah/1 for "miny" +// * InstantiationName/FooTest.DoesBlah/2 for "moe" +// * InstantiationName/FooTest.HasBlahBlah/0 for "meeny" +// * InstantiationName/FooTest.HasBlahBlah/1 for "miny" +// * InstantiationName/FooTest.HasBlahBlah/2 for "moe" +// +// You can use these names in --gtest_filter. +// +// This statement will instantiate all tests from FooTest again, each +// with parameter values "cat" and "dog": + +const char* pets[] = {"cat", "dog"}; +INSTANTIATE_TEST_CASE_P(AnotherInstantiationName, FooTest, ValuesIn(pets)); + +// The tests from the instantiation above will have these names: +// +// * AnotherInstantiationName/FooTest.DoesBlah/0 for "cat" +// * AnotherInstantiationName/FooTest.DoesBlah/1 for "dog" +// * AnotherInstantiationName/FooTest.HasBlahBlah/0 for "cat" +// * AnotherInstantiationName/FooTest.HasBlahBlah/1 for "dog" +// +// Please note that INSTANTIATE_TEST_CASE_P will instantiate all tests +// in the given test case, whether their definitions come before or +// AFTER the INSTANTIATE_TEST_CASE_P statement. +// +// Please also note that generator expressions (including parameters to the +// generators) are evaluated in InitGoogleTest(), after main() has started. +// This allows the user on one hand, to adjust generator parameters in order +// to dynamically determine a set of tests to run and on the other hand, +// give the user a chance to inspect the generated tests with Google Test +// reflection API before RUN_ALL_TESTS() is executed. +// +// You can see samples/sample7_unittest.cc and samples/sample8_unittest.cc +// for more examples. +// +// In the future, we plan to publish the API for defining new parameter +// generators. But for now this interface remains part of the internal +// implementation and is subject to change. + +#endif // 0 + + +#if !GTEST_OS_SYMBIAN +#include +#endif + +// scripts/fuse_gtest.py depends on gtest's own header being #included +// *unconditionally*. Therefore these #includes cannot be moved +// inside #if GTEST_HAS_PARAM_TEST. +// Copyright 2008 Google Inc. +// All Rights Reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: vladl@google.com (Vlad Losev) + +// Type and function utilities for implementing parameterized tests. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_ + +#include +#include +#include + +// scripts/fuse_gtest.py depends on gtest's own header being #included +// *unconditionally*. Therefore these #includes cannot be moved +// inside #if GTEST_HAS_PARAM_TEST. +// Copyright 2003 Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: Dan Egnor (egnor@google.com) +// +// A "smart" pointer type with reference tracking. Every pointer to a +// particular object is kept on a circular linked list. When the last pointer +// to an object is destroyed or reassigned, the object is deleted. +// +// Used properly, this deletes the object when the last reference goes away. +// There are several caveats: +// - Like all reference counting schemes, cycles lead to leaks. +// - Each smart pointer is actually two pointers (8 bytes instead of 4). +// - Every time a pointer is assigned, the entire list of pointers to that +// object is traversed. This class is therefore NOT SUITABLE when there +// will often be more than two or three pointers to a particular object. +// - References are only tracked as long as linked_ptr<> objects are copied. +// If a linked_ptr<> is converted to a raw pointer and back, BAD THINGS +// will happen (double deletion). +// +// A good use of this class is storing object references in STL containers. +// You can safely put linked_ptr<> in a vector<>. +// Other uses may not be as good. +// +// Note: If you use an incomplete type with linked_ptr<>, the class +// *containing* linked_ptr<> must have a constructor and destructor (even +// if they do nothing!). +// +// Bill Gibbons suggested we use something like this. +// +// Thread Safety: +// Unlike other linked_ptr implementations, in this implementation +// a linked_ptr object is thread-safe in the sense that: +// - it's safe to copy linked_ptr objects concurrently, +// - it's safe to copy *from* a linked_ptr and read its underlying +// raw pointer (e.g. via get()) concurrently, and +// - it's safe to write to two linked_ptrs that point to the same +// shared object concurrently. +// TODO(wan@google.com): rename this to safe_linked_ptr to avoid +// confusion with normal linked_ptr. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_ + +#include +#include + + +namespace testing { +namespace internal { + +// Protects copying of all linked_ptr objects. +GTEST_API_ GTEST_DECLARE_STATIC_MUTEX_(g_linked_ptr_mutex); + +// This is used internally by all instances of linked_ptr<>. It needs to be +// a non-template class because different types of linked_ptr<> can refer to +// the same object (linked_ptr(obj) vs linked_ptr(obj)). +// So, it needs to be possible for different types of linked_ptr to participate +// in the same circular linked list, so we need a single class type here. +// +// DO NOT USE THIS CLASS DIRECTLY YOURSELF. Use linked_ptr. +class linked_ptr_internal { + public: + // Create a new circle that includes only this instance. + void join_new() { + next_ = this; + } + + // Many linked_ptr operations may change p.link_ for some linked_ptr + // variable p in the same circle as this object. Therefore we need + // to prevent two such operations from occurring concurrently. + // + // Note that different types of linked_ptr objects can coexist in a + // circle (e.g. linked_ptr, linked_ptr, and + // linked_ptr). Therefore we must use a single mutex to + // protect all linked_ptr objects. This can create serious + // contention in production code, but is acceptable in a testing + // framework. + + // Join an existing circle. + // L < g_linked_ptr_mutex + void join(linked_ptr_internal const* ptr) { + MutexLock lock(&g_linked_ptr_mutex); + + linked_ptr_internal const* p = ptr; + while (p->next_ != ptr) p = p->next_; + p->next_ = this; + next_ = ptr; + } + + // Leave whatever circle we're part of. Returns true if we were the + // last member of the circle. Once this is done, you can join() another. + // L < g_linked_ptr_mutex + bool depart() { + MutexLock lock(&g_linked_ptr_mutex); + + if (next_ == this) return true; + linked_ptr_internal const* p = next_; + while (p->next_ != this) p = p->next_; + p->next_ = next_; + return false; + } + + private: + mutable linked_ptr_internal const* next_; +}; + +template +class linked_ptr { + public: + typedef T element_type; + + // Take over ownership of a raw pointer. This should happen as soon as + // possible after the object is created. + explicit linked_ptr(T* ptr = NULL) { capture(ptr); } + ~linked_ptr() { depart(); } + + // Copy an existing linked_ptr<>, adding ourselves to the list of references. + template linked_ptr(linked_ptr const& ptr) { copy(&ptr); } + linked_ptr(linked_ptr const& ptr) { // NOLINT + assert(&ptr != this); + copy(&ptr); + } + + // Assignment releases the old value and acquires the new. + template linked_ptr& operator=(linked_ptr const& ptr) { + depart(); + copy(&ptr); + return *this; + } + + linked_ptr& operator=(linked_ptr const& ptr) { + if (&ptr != this) { + depart(); + copy(&ptr); + } + return *this; + } + + // Smart pointer members. + void reset(T* ptr = NULL) { + depart(); + capture(ptr); + } + T* get() const { return value_; } + T* operator->() const { return value_; } + T& operator*() const { return *value_; } + // Release ownership of the pointed object and returns it. + // Sole ownership by this linked_ptr object is required. + T* release() { + bool last = link_.depart(); + assert(last); + T* v = value_; + value_ = NULL; + return v; + } + + bool operator==(T* p) const { return value_ == p; } + bool operator!=(T* p) const { return value_ != p; } + template + bool operator==(linked_ptr const& ptr) const { + return value_ == ptr.get(); + } + template + bool operator!=(linked_ptr const& ptr) const { + return value_ != ptr.get(); + } + + private: + template + friend class linked_ptr; + + T* value_; + linked_ptr_internal link_; + + void depart() { + if (link_.depart()) delete value_; + } + + void capture(T* ptr) { + value_ = ptr; + link_.join_new(); + } + + template void copy(linked_ptr const* ptr) { + value_ = ptr->get(); + if (value_) + link_.join(&ptr->link_); + else + link_.join_new(); + } +}; + +template inline +bool operator==(T* ptr, const linked_ptr& x) { + return ptr == x.get(); +} + +template inline +bool operator!=(T* ptr, const linked_ptr& x) { + return ptr != x.get(); +} + +// A function to convert T* into linked_ptr +// Doing e.g. make_linked_ptr(new FooBarBaz(arg)) is a shorter notation +// for linked_ptr >(new FooBarBaz(arg)) +template +linked_ptr make_linked_ptr(T* ptr) { + return linked_ptr(ptr); +} + +} // namespace internal +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_ + +#if GTEST_HAS_PARAM_TEST + +namespace testing { +namespace internal { + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// Outputs a message explaining invalid registration of different +// fixture class for the same test case. This may happen when +// TEST_P macro is used to define two tests with the same name +// but in different namespaces. +GTEST_API_ void ReportInvalidTestCaseType(const char* test_case_name, + const char* file, int line); + +template class ParamGeneratorInterface; +template class ParamGenerator; + +// Interface for iterating over elements provided by an implementation +// of ParamGeneratorInterface. +template +class ParamIteratorInterface { + public: + virtual ~ParamIteratorInterface() {} + // A pointer to the base generator instance. + // Used only for the purposes of iterator comparison + // to make sure that two iterators belong to the same generator. + virtual const ParamGeneratorInterface* BaseGenerator() const = 0; + // Advances iterator to point to the next element + // provided by the generator. The caller is responsible + // for not calling Advance() on an iterator equal to + // BaseGenerator()->End(). + virtual void Advance() = 0; + // Clones the iterator object. Used for implementing copy semantics + // of ParamIterator. + virtual ParamIteratorInterface* Clone() const = 0; + // Dereferences the current iterator and provides (read-only) access + // to the pointed value. It is the caller's responsibility not to call + // Current() on an iterator equal to BaseGenerator()->End(). + // Used for implementing ParamGenerator::operator*(). + virtual const T* Current() const = 0; + // Determines whether the given iterator and other point to the same + // element in the sequence generated by the generator. + // Used for implementing ParamGenerator::operator==(). + virtual bool Equals(const ParamIteratorInterface& other) const = 0; +}; + +// Class iterating over elements provided by an implementation of +// ParamGeneratorInterface. It wraps ParamIteratorInterface +// and implements the const forward iterator concept. +template +class ParamIterator { + public: + typedef T value_type; + typedef const T& reference; + typedef ptrdiff_t difference_type; + + // ParamIterator assumes ownership of the impl_ pointer. + ParamIterator(const ParamIterator& other) : impl_(other.impl_->Clone()) {} + ParamIterator& operator=(const ParamIterator& other) { + if (this != &other) + impl_.reset(other.impl_->Clone()); + return *this; + } + + const T& operator*() const { return *impl_->Current(); } + const T* operator->() const { return impl_->Current(); } + // Prefix version of operator++. + ParamIterator& operator++() { + impl_->Advance(); + return *this; + } + // Postfix version of operator++. + ParamIterator operator++(int /*unused*/) { + ParamIteratorInterface* clone = impl_->Clone(); + impl_->Advance(); + return ParamIterator(clone); + } + bool operator==(const ParamIterator& other) const { + return impl_.get() == other.impl_.get() || impl_->Equals(*other.impl_); + } + bool operator!=(const ParamIterator& other) const { + return !(*this == other); + } + + private: + friend class ParamGenerator; + explicit ParamIterator(ParamIteratorInterface* impl) : impl_(impl) {} + scoped_ptr > impl_; +}; + +// ParamGeneratorInterface is the binary interface to access generators +// defined in other translation units. +template +class ParamGeneratorInterface { + public: + typedef T ParamType; + + virtual ~ParamGeneratorInterface() {} + + // Generator interface definition + virtual ParamIteratorInterface* Begin() const = 0; + virtual ParamIteratorInterface* End() const = 0; +}; + +// Wraps ParamGeneratorInterface and provides general generator syntax +// compatible with the STL Container concept. +// This class implements copy initialization semantics and the contained +// ParamGeneratorInterface instance is shared among all copies +// of the original object. This is possible because that instance is immutable. +template +class ParamGenerator { + public: + typedef ParamIterator iterator; + + explicit ParamGenerator(ParamGeneratorInterface* impl) : impl_(impl) {} + ParamGenerator(const ParamGenerator& other) : impl_(other.impl_) {} + + ParamGenerator& operator=(const ParamGenerator& other) { + impl_ = other.impl_; + return *this; + } + + iterator begin() const { return iterator(impl_->Begin()); } + iterator end() const { return iterator(impl_->End()); } + + private: + ::testing::internal::linked_ptr > impl_; +}; + +// Generates values from a range of two comparable values. Can be used to +// generate sequences of user-defined types that implement operator+() and +// operator<(). +// This class is used in the Range() function. +template +class RangeGenerator : public ParamGeneratorInterface { + public: + RangeGenerator(T begin, T end, IncrementT step) + : begin_(begin), end_(end), + step_(step), end_index_(CalculateEndIndex(begin, end, step)) {} + virtual ~RangeGenerator() {} + + virtual ParamIteratorInterface* Begin() const { + return new Iterator(this, begin_, 0, step_); + } + virtual ParamIteratorInterface* End() const { + return new Iterator(this, end_, end_index_, step_); + } + + private: + class Iterator : public ParamIteratorInterface { + public: + Iterator(const ParamGeneratorInterface* base, T value, int index, + IncrementT step) + : base_(base), value_(value), index_(index), step_(step) {} + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface* BaseGenerator() const { + return base_; + } + virtual void Advance() { + value_ = value_ + step_; + index_++; + } + virtual ParamIteratorInterface* Clone() const { + return new Iterator(*this); + } + virtual const T* Current() const { return &value_; } + virtual bool Equals(const ParamIteratorInterface& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const int other_index = + CheckedDowncastToActualType(&other)->index_; + return index_ == other_index; + } + + private: + Iterator(const Iterator& other) + : ParamIteratorInterface(), + base_(other.base_), value_(other.value_), index_(other.index_), + step_(other.step_) {} + + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + + const ParamGeneratorInterface* const base_; + T value_; + int index_; + const IncrementT step_; + }; // class RangeGenerator::Iterator + + static int CalculateEndIndex(const T& begin, + const T& end, + const IncrementT& step) { + int end_index = 0; + for (T i = begin; i < end; i = i + step) + end_index++; + return end_index; + } + + // No implementation - assignment is unsupported. + void operator=(const RangeGenerator& other); + + const T begin_; + const T end_; + const IncrementT step_; + // The index for the end() iterator. All the elements in the generated + // sequence are indexed (0-based) to aid iterator comparison. + const int end_index_; +}; // class RangeGenerator + + +// Generates values from a pair of STL-style iterators. Used in the +// ValuesIn() function. The elements are copied from the source range +// since the source can be located on the stack, and the generator +// is likely to persist beyond that stack frame. +template +class ValuesInIteratorRangeGenerator : public ParamGeneratorInterface { + public: + template + ValuesInIteratorRangeGenerator(ForwardIterator begin, ForwardIterator end) + : container_(begin, end) {} + virtual ~ValuesInIteratorRangeGenerator() {} + + virtual ParamIteratorInterface* Begin() const { + return new Iterator(this, container_.begin()); + } + virtual ParamIteratorInterface* End() const { + return new Iterator(this, container_.end()); + } + + private: + typedef typename ::std::vector ContainerType; + + class Iterator : public ParamIteratorInterface { + public: + Iterator(const ParamGeneratorInterface* base, + typename ContainerType::const_iterator iterator) + : base_(base), iterator_(iterator) {} + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface* BaseGenerator() const { + return base_; + } + virtual void Advance() { + ++iterator_; + value_.reset(); + } + virtual ParamIteratorInterface* Clone() const { + return new Iterator(*this); + } + // We need to use cached value referenced by iterator_ because *iterator_ + // can return a temporary object (and of type other then T), so just + // having "return &*iterator_;" doesn't work. + // value_ is updated here and not in Advance() because Advance() + // can advance iterator_ beyond the end of the range, and we cannot + // detect that fact. The client code, on the other hand, is + // responsible for not calling Current() on an out-of-range iterator. + virtual const T* Current() const { + if (value_.get() == NULL) + value_.reset(new T(*iterator_)); + return value_.get(); + } + virtual bool Equals(const ParamIteratorInterface& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + return iterator_ == + CheckedDowncastToActualType(&other)->iterator_; + } + + private: + Iterator(const Iterator& other) + // The explicit constructor call suppresses a false warning + // emitted by gcc when supplied with the -Wextra option. + : ParamIteratorInterface(), + base_(other.base_), + iterator_(other.iterator_) {} + + const ParamGeneratorInterface* const base_; + typename ContainerType::const_iterator iterator_; + // A cached value of *iterator_. We keep it here to allow access by + // pointer in the wrapping iterator's operator->(). + // value_ needs to be mutable to be accessed in Current(). + // Use of scoped_ptr helps manage cached value's lifetime, + // which is bound by the lifespan of the iterator itself. + mutable scoped_ptr value_; + }; // class ValuesInIteratorRangeGenerator::Iterator + + // No implementation - assignment is unsupported. + void operator=(const ValuesInIteratorRangeGenerator& other); + + const ContainerType container_; +}; // class ValuesInIteratorRangeGenerator + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// Stores a parameter value and later creates tests parameterized with that +// value. +template +class ParameterizedTestFactory : public TestFactoryBase { + public: + typedef typename TestClass::ParamType ParamType; + explicit ParameterizedTestFactory(ParamType parameter) : + parameter_(parameter) {} + virtual Test* CreateTest() { + TestClass::SetParam(¶meter_); + return new TestClass(); + } + + private: + const ParamType parameter_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestFactory); +}; + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// TestMetaFactoryBase is a base class for meta-factories that create +// test factories for passing into MakeAndRegisterTestInfo function. +template +class TestMetaFactoryBase { + public: + virtual ~TestMetaFactoryBase() {} + + virtual TestFactoryBase* CreateTestFactory(ParamType parameter) = 0; +}; + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// TestMetaFactory creates test factories for passing into +// MakeAndRegisterTestInfo function. Since MakeAndRegisterTestInfo receives +// ownership of test factory pointer, same factory object cannot be passed +// into that method twice. But ParameterizedTestCaseInfo is going to call +// it for each Test/Parameter value combination. Thus it needs meta factory +// creator class. +template +class TestMetaFactory + : public TestMetaFactoryBase { + public: + typedef typename TestCase::ParamType ParamType; + + TestMetaFactory() {} + + virtual TestFactoryBase* CreateTestFactory(ParamType parameter) { + return new ParameterizedTestFactory(parameter); + } + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestMetaFactory); +}; + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// ParameterizedTestCaseInfoBase is a generic interface +// to ParameterizedTestCaseInfo classes. ParameterizedTestCaseInfoBase +// accumulates test information provided by TEST_P macro invocations +// and generators provided by INSTANTIATE_TEST_CASE_P macro invocations +// and uses that information to register all resulting test instances +// in RegisterTests method. The ParameterizeTestCaseRegistry class holds +// a collection of pointers to the ParameterizedTestCaseInfo objects +// and calls RegisterTests() on each of them when asked. +class ParameterizedTestCaseInfoBase { + public: + virtual ~ParameterizedTestCaseInfoBase() {} + + // Base part of test case name for display purposes. + virtual const String& GetTestCaseName() const = 0; + // Test case id to verify identity. + virtual TypeId GetTestCaseTypeId() const = 0; + // UnitTest class invokes this method to register tests in this + // test case right before running them in RUN_ALL_TESTS macro. + // This method should not be called more then once on any single + // instance of a ParameterizedTestCaseInfoBase derived class. + virtual void RegisterTests() = 0; + + protected: + ParameterizedTestCaseInfoBase() {} + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseInfoBase); +}; + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// ParameterizedTestCaseInfo accumulates tests obtained from TEST_P +// macro invocations for a particular test case and generators +// obtained from INSTANTIATE_TEST_CASE_P macro invocations for that +// test case. It registers tests with all values generated by all +// generators when asked. +template +class ParameterizedTestCaseInfo : public ParameterizedTestCaseInfoBase { + public: + // ParamType and GeneratorCreationFunc are private types but are required + // for declarations of public methods AddTestPattern() and + // AddTestCaseInstantiation(). + typedef typename TestCase::ParamType ParamType; + // A function that returns an instance of appropriate generator type. + typedef ParamGenerator(GeneratorCreationFunc)(); + + explicit ParameterizedTestCaseInfo(const char* name) + : test_case_name_(name) {} + + // Test case base name for display purposes. + virtual const String& GetTestCaseName() const { return test_case_name_; } + // Test case id to verify identity. + virtual TypeId GetTestCaseTypeId() const { return GetTypeId(); } + // TEST_P macro uses AddTestPattern() to record information + // about a single test in a LocalTestInfo structure. + // test_case_name is the base name of the test case (without invocation + // prefix). test_base_name is the name of an individual test without + // parameter index. For the test SequenceA/FooTest.DoBar/1 FooTest is + // test case base name and DoBar is test base name. + void AddTestPattern(const char* test_case_name, + const char* test_base_name, + TestMetaFactoryBase* meta_factory) { + tests_.push_back(linked_ptr(new TestInfo(test_case_name, + test_base_name, + meta_factory))); + } + // INSTANTIATE_TEST_CASE_P macro uses AddGenerator() to record information + // about a generator. + int AddTestCaseInstantiation(const char* instantiation_name, + GeneratorCreationFunc* func, + const char* /* file */, + int /* line */) { + instantiations_.push_back(::std::make_pair(instantiation_name, func)); + return 0; // Return value used only to run this method in namespace scope. + } + // UnitTest class invokes this method to register tests in this test case + // test cases right before running tests in RUN_ALL_TESTS macro. + // This method should not be called more then once on any single + // instance of a ParameterizedTestCaseInfoBase derived class. + // UnitTest has a guard to prevent from calling this method more then once. + virtual void RegisterTests() { + for (typename TestInfoContainer::iterator test_it = tests_.begin(); + test_it != tests_.end(); ++test_it) { + linked_ptr test_info = *test_it; + for (typename InstantiationContainer::iterator gen_it = + instantiations_.begin(); gen_it != instantiations_.end(); + ++gen_it) { + const String& instantiation_name = gen_it->first; + ParamGenerator generator((*gen_it->second)()); + + Message test_case_name_stream; + if ( !instantiation_name.empty() ) + test_case_name_stream << instantiation_name.c_str() << "/"; + test_case_name_stream << test_info->test_case_base_name.c_str(); + + int i = 0; + for (typename ParamGenerator::iterator param_it = + generator.begin(); + param_it != generator.end(); ++param_it, ++i) { + Message test_name_stream; + test_name_stream << test_info->test_base_name.c_str() << "/" << i; + ::testing::internal::MakeAndRegisterTestInfo( + test_case_name_stream.GetString().c_str(), + test_name_stream.GetString().c_str(), + "", // test_case_comment + "", // comment; TODO(vladl@google.com): provide parameter value + // representation. + GetTestCaseTypeId(), + TestCase::SetUpTestCase, + TestCase::TearDownTestCase, + test_info->test_meta_factory->CreateTestFactory(*param_it)); + } // for param_it + } // for gen_it + } // for test_it + } // RegisterTests + + private: + // LocalTestInfo structure keeps information about a single test registered + // with TEST_P macro. + struct TestInfo { + TestInfo(const char* a_test_case_base_name, + const char* a_test_base_name, + TestMetaFactoryBase* a_test_meta_factory) : + test_case_base_name(a_test_case_base_name), + test_base_name(a_test_base_name), + test_meta_factory(a_test_meta_factory) {} + + const String test_case_base_name; + const String test_base_name; + const scoped_ptr > test_meta_factory; + }; + typedef ::std::vector > TestInfoContainer; + // Keeps pairs of + // received from INSTANTIATE_TEST_CASE_P macros. + typedef ::std::vector > + InstantiationContainer; + + const String test_case_name_; + TestInfoContainer tests_; + InstantiationContainer instantiations_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseInfo); +}; // class ParameterizedTestCaseInfo + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// ParameterizedTestCaseRegistry contains a map of ParameterizedTestCaseInfoBase +// classes accessed by test case names. TEST_P and INSTANTIATE_TEST_CASE_P +// macros use it to locate their corresponding ParameterizedTestCaseInfo +// descriptors. +class ParameterizedTestCaseRegistry { + public: + ParameterizedTestCaseRegistry() {} + ~ParameterizedTestCaseRegistry() { + for (TestCaseInfoContainer::iterator it = test_case_infos_.begin(); + it != test_case_infos_.end(); ++it) { + delete *it; + } + } + + // Looks up or creates and returns a structure containing information about + // tests and instantiations of a particular test case. + template + ParameterizedTestCaseInfo* GetTestCasePatternHolder( + const char* test_case_name, + const char* file, + int line) { + ParameterizedTestCaseInfo* typed_test_info = NULL; + for (TestCaseInfoContainer::iterator it = test_case_infos_.begin(); + it != test_case_infos_.end(); ++it) { + if ((*it)->GetTestCaseName() == test_case_name) { + if ((*it)->GetTestCaseTypeId() != GetTypeId()) { + // Complain about incorrect usage of Google Test facilities + // and terminate the program since we cannot guaranty correct + // test case setup and tear-down in this case. + ReportInvalidTestCaseType(test_case_name, file, line); + abort(); + } else { + // At this point we are sure that the object we found is of the same + // type we are looking for, so we downcast it to that type + // without further checks. + typed_test_info = CheckedDowncastToActualType< + ParameterizedTestCaseInfo >(*it); + } + break; + } + } + if (typed_test_info == NULL) { + typed_test_info = new ParameterizedTestCaseInfo(test_case_name); + test_case_infos_.push_back(typed_test_info); + } + return typed_test_info; + } + void RegisterTests() { + for (TestCaseInfoContainer::iterator it = test_case_infos_.begin(); + it != test_case_infos_.end(); ++it) { + (*it)->RegisterTests(); + } + } + + private: + typedef ::std::vector TestCaseInfoContainer; + + TestCaseInfoContainer test_case_infos_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseRegistry); +}; + +} // namespace internal +} // namespace testing + +#endif // GTEST_HAS_PARAM_TEST + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_ +// This file was GENERATED by a script. DO NOT EDIT BY HAND!!! + +// Copyright 2008 Google Inc. +// All Rights Reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: vladl@google.com (Vlad Losev) + +// Type and function utilities for implementing parameterized tests. +// This file is generated by a SCRIPT. DO NOT EDIT BY HAND! +// +// Currently Google Test supports at most 50 arguments in Values, +// and at most 10 arguments in Combine. Please contact +// googletestframework@googlegroups.com if you need more. +// Please note that the number of arguments to Combine is limited +// by the maximum arity of the implementation of tr1::tuple which is +// currently set at 10. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_ + +// scripts/fuse_gtest.py depends on gtest's own header being #included +// *unconditionally*. Therefore these #includes cannot be moved +// inside #if GTEST_HAS_PARAM_TEST. + +#if GTEST_HAS_PARAM_TEST + +namespace testing { + +// Forward declarations of ValuesIn(), which is implemented in +// include/gtest/gtest-param-test.h. +template +internal::ParamGenerator< + typename ::std::iterator_traits::value_type> ValuesIn( + ForwardIterator begin, ForwardIterator end); + +template +internal::ParamGenerator ValuesIn(const T (&array)[N]); + +template +internal::ParamGenerator ValuesIn( + const Container& container); + +namespace internal { + +// Used in the Values() function to provide polymorphic capabilities. +template +class ValueArray1 { + public: + explicit ValueArray1(T1 v1) : v1_(v1) {} + + template + operator ParamGenerator() const { return ValuesIn(&v1_, &v1_ + 1); } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray1& other); + + const T1 v1_; +}; + +template +class ValueArray2 { + public: + ValueArray2(T1 v1, T2 v2) : v1_(v1), v2_(v2) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray2& other); + + const T1 v1_; + const T2 v2_; +}; + +template +class ValueArray3 { + public: + ValueArray3(T1 v1, T2 v2, T3 v3) : v1_(v1), v2_(v2), v3_(v3) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray3& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; +}; + +template +class ValueArray4 { + public: + ValueArray4(T1 v1, T2 v2, T3 v3, T4 v4) : v1_(v1), v2_(v2), v3_(v3), + v4_(v4) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray4& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; +}; + +template +class ValueArray5 { + public: + ValueArray5(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5) : v1_(v1), v2_(v2), v3_(v3), + v4_(v4), v5_(v5) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray5& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; +}; + +template +class ValueArray6 { + public: + ValueArray6(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6) : v1_(v1), v2_(v2), + v3_(v3), v4_(v4), v5_(v5), v6_(v6) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray6& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; +}; + +template +class ValueArray7 { + public: + ValueArray7(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7) : v1_(v1), + v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray7& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; +}; + +template +class ValueArray8 { + public: + ValueArray8(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, + T8 v8) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray8& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; +}; + +template +class ValueArray9 { + public: + ValueArray9(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, + T9 v9) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray9& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; +}; + +template +class ValueArray10 { + public: + ValueArray10(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray10& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; +}; + +template +class ValueArray11 { + public: + ValueArray11(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), + v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray11& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; +}; + +template +class ValueArray12 { + public: + ValueArray12(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), + v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray12& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; +}; + +template +class ValueArray13 { + public: + ValueArray13(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), + v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), + v12_(v12), v13_(v13) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray13& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; +}; + +template +class ValueArray14 { + public: + ValueArray14(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14) : v1_(v1), v2_(v2), v3_(v3), + v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), + v11_(v11), v12_(v12), v13_(v13), v14_(v14) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray14& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; +}; + +template +class ValueArray15 { + public: + ValueArray15(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15) : v1_(v1), v2_(v2), + v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), + v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray15& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; +}; + +template +class ValueArray16 { + public: + ValueArray16(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16) : v1_(v1), + v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), + v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), + v16_(v16) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray16& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; +}; + +template +class ValueArray17 { + public: + ValueArray17(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, + T17 v17) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), + v15_(v15), v16_(v16), v17_(v17) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray17& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; +}; + +template +class ValueArray18 { + public: + ValueArray18(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), + v15_(v15), v16_(v16), v17_(v17), v18_(v18) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray18& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; +}; + +template +class ValueArray19 { + public: + ValueArray19(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), + v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), + v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray19& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; +}; + +template +class ValueArray20 { + public: + ValueArray20(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), + v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), + v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), + v19_(v19), v20_(v20) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray20& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; +}; + +template +class ValueArray21 { + public: + ValueArray21(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), + v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), + v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), + v18_(v18), v19_(v19), v20_(v20), v21_(v21) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray21& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; +}; + +template +class ValueArray22 { + public: + ValueArray22(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22) : v1_(v1), v2_(v2), v3_(v3), + v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), + v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), + v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray22& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; +}; + +template +class ValueArray23 { + public: + ValueArray23(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23) : v1_(v1), v2_(v2), + v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), + v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), + v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), + v23_(v23) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, + v23_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray23& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; +}; + +template +class ValueArray24 { + public: + ValueArray24(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24) : v1_(v1), + v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), + v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), + v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), + v22_(v22), v23_(v23), v24_(v24) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray24& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; +}; + +template +class ValueArray25 { + public: + ValueArray25(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, + T25 v25) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), + v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), + v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray25& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; +}; + +template +class ValueArray26 { + public: + ValueArray26(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), + v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), + v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray26& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; +}; + +template +class ValueArray27 { + public: + ValueArray27(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), + v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), + v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), + v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), + v26_(v26), v27_(v27) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray27& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; +}; + +template +class ValueArray28 { + public: + ValueArray28(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), + v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), + v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), + v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), + v25_(v25), v26_(v26), v27_(v27), v28_(v28) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray28& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; +}; + +template +class ValueArray29 { + public: + ValueArray29(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), + v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), + v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), + v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), + v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray29& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; +}; + +template +class ValueArray30 { + public: + ValueArray30(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30) : v1_(v1), v2_(v2), v3_(v3), + v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), + v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), + v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), + v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), + v29_(v29), v30_(v30) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_, v30_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray30& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; +}; + +template +class ValueArray31 { + public: + ValueArray31(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31) : v1_(v1), v2_(v2), + v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), + v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), + v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), + v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), + v29_(v29), v30_(v30), v31_(v31) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray31& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; +}; + +template +class ValueArray32 { + public: + ValueArray32(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32) : v1_(v1), + v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), + v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), + v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), + v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), + v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray32& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; +}; + +template +class ValueArray33 { + public: + ValueArray33(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, + T33 v33) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), + v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), + v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), + v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), + v33_(v33) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray33& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; +}; + +template +class ValueArray34 { + public: + ValueArray34(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), + v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), + v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), + v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), + v33_(v33), v34_(v34) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray34& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; +}; + +template +class ValueArray35 { + public: + ValueArray35(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), + v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), + v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), + v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), + v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), + v32_(v32), v33_(v33), v34_(v34), v35_(v35) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, + v35_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray35& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; +}; + +template +class ValueArray36 { + public: + ValueArray36(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), + v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), + v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), + v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), + v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), + v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, + v36_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray36& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; +}; + +template +class ValueArray37 { + public: + ValueArray37(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), + v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), + v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), + v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), + v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), + v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), + v36_(v36), v37_(v37) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, + v36_, v37_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray37& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; +}; + +template +class ValueArray38 { + public: + ValueArray38(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38) : v1_(v1), v2_(v2), v3_(v3), + v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), + v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), + v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), + v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), + v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), + v35_(v35), v36_(v36), v37_(v37), v38_(v38) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, + v36_, v37_, v38_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray38& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; +}; + +template +class ValueArray39 { + public: + ValueArray39(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39) : v1_(v1), v2_(v2), + v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), + v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), + v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), + v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), + v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), + v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, + v36_, v37_, v38_, v39_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray39& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; +}; + +template +class ValueArray40 { + public: + ValueArray40(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40) : v1_(v1), + v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), + v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), + v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), + v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), + v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), + v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), + v40_(v40) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, + v36_, v37_, v38_, v39_, v40_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray40& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; +}; + +template +class ValueArray41 { + public: + ValueArray41(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, + T41 v41) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), + v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), + v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), + v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), + v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), + v39_(v39), v40_(v40), v41_(v41) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, + v36_, v37_, v38_, v39_, v40_, v41_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray41& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; +}; + +template +class ValueArray42 { + public: + ValueArray42(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), + v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), + v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), + v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), + v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), + v39_(v39), v40_(v40), v41_(v41), v42_(v42) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, + v36_, v37_, v38_, v39_, v40_, v41_, v42_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray42& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; + const T42 v42_; +}; + +template +class ValueArray43 { + public: + ValueArray43(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), + v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), + v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), + v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), + v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), + v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), + v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, + v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray43& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; + const T42 v42_; + const T43 v43_; +}; + +template +class ValueArray44 { + public: + ValueArray44(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43, T44 v44) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), + v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), + v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), + v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), + v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), + v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), + v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42), + v43_(v43), v44_(v44) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, + v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray44& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; + const T42 v42_; + const T43 v43_; + const T44 v44_; +}; + +template +class ValueArray45 { + public: + ValueArray45(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43, T44 v44, T45 v45) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), + v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), + v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), + v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), + v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), + v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), + v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41), + v42_(v42), v43_(v43), v44_(v44), v45_(v45) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, + v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_, v45_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray45& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; + const T42 v42_; + const T43 v43_; + const T44 v44_; + const T45 v45_; +}; + +template +class ValueArray46 { + public: + ValueArray46(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43, T44 v44, T45 v45, T46 v46) : v1_(v1), v2_(v2), v3_(v3), + v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), + v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), + v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), + v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), + v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), + v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), + v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45), v46_(v46) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, + v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_, v45_, v46_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray46& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; + const T42 v42_; + const T43 v43_; + const T44 v44_; + const T45 v45_; + const T46 v46_; +}; + +template +class ValueArray47 { + public: + ValueArray47(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47) : v1_(v1), v2_(v2), + v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), + v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), + v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), + v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), + v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), + v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), + v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45), v46_(v46), + v47_(v47) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, + v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_, v45_, v46_, + v47_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray47& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; + const T42 v42_; + const T43 v43_; + const T44 v44_; + const T45 v45_; + const T46 v46_; + const T47 v47_; +}; + +template +class ValueArray48 { + public: + ValueArray48(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48) : v1_(v1), + v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), + v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), + v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), + v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), + v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), + v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), + v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45), + v46_(v46), v47_(v47), v48_(v48) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, + v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_, v45_, v46_, v47_, + v48_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray48& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; + const T42 v42_; + const T43 v43_; + const T44 v44_; + const T45 v45_; + const T46 v46_; + const T47 v47_; + const T48 v48_; +}; + +template +class ValueArray49 { + public: + ValueArray49(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48, + T49 v49) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), + v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), + v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), + v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), + v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), + v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44), + v45_(v45), v46_(v46), v47_(v47), v48_(v48), v49_(v49) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, + v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_, v45_, v46_, v47_, + v48_, v49_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray49& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; + const T42 v42_; + const T43 v43_; + const T44 v44_; + const T45 v45_; + const T46 v46_; + const T47 v47_; + const T48 v48_; + const T49 v49_; +}; + +template +class ValueArray50 { + public: + ValueArray50(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48, T49 v49, + T50 v50) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), + v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), + v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), + v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), + v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), + v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44), + v45_(v45), v46_(v46), v47_(v47), v48_(v48), v49_(v49), v50_(v50) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, + v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_, v45_, v46_, v47_, + v48_, v49_, v50_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray50& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; + const T42 v42_; + const T43 v43_; + const T44 v44_; + const T45 v45_; + const T46 v46_; + const T47 v47_; + const T48 v48_; + const T49 v49_; + const T50 v50_; +}; + +#if GTEST_HAS_COMBINE +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// Generates values from the Cartesian product of values produced +// by the argument generators. +// +template +class CartesianProductGenerator2 + : public ParamGeneratorInterface< ::std::tr1::tuple > { + public: + typedef ::std::tr1::tuple ParamType; + + CartesianProductGenerator2(const ParamGenerator& g1, + const ParamGenerator& g2) + : g1_(g1), g2_(g2) {} + virtual ~CartesianProductGenerator2() {} + + virtual ParamIteratorInterface* Begin() const { + return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin()); + } + virtual ParamIteratorInterface* End() const { + return new Iterator(this, g1_, g1_.end(), g2_, g2_.end()); + } + + private: + class Iterator : public ParamIteratorInterface { + public: + Iterator(const ParamGeneratorInterface* base, + const ParamGenerator& g1, + const typename ParamGenerator::iterator& current1, + const ParamGenerator& g2, + const typename ParamGenerator::iterator& current2) + : base_(base), + begin1_(g1.begin()), end1_(g1.end()), current1_(current1), + begin2_(g2.begin()), end2_(g2.end()), current2_(current2) { + ComputeCurrentValue(); + } + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface* BaseGenerator() const { + return base_; + } + // Advance should not be called on beyond-of-range iterators + // so no component iterators must be beyond end of range, either. + virtual void Advance() { + assert(!AtEnd()); + ++current2_; + if (current2_ == end2_) { + current2_ = begin2_; + ++current1_; + } + ComputeCurrentValue(); + } + virtual ParamIteratorInterface* Clone() const { + return new Iterator(*this); + } + virtual const ParamType* Current() const { return ¤t_value_; } + virtual bool Equals(const ParamIteratorInterface& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const Iterator* typed_other = + CheckedDowncastToActualType(&other); + // We must report iterators equal if they both point beyond their + // respective ranges. That can happen in a variety of fashions, + // so we have to consult AtEnd(). + return (AtEnd() && typed_other->AtEnd()) || + ( + current1_ == typed_other->current1_ && + current2_ == typed_other->current2_); + } + + private: + Iterator(const Iterator& other) + : base_(other.base_), + begin1_(other.begin1_), + end1_(other.end1_), + current1_(other.current1_), + begin2_(other.begin2_), + end2_(other.end2_), + current2_(other.current2_) { + ComputeCurrentValue(); + } + + void ComputeCurrentValue() { + if (!AtEnd()) + current_value_ = ParamType(*current1_, *current2_); + } + bool AtEnd() const { + // We must report iterator past the end of the range when either of the + // component iterators has reached the end of its range. + return + current1_ == end1_ || + current2_ == end2_; + } + + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + + const ParamGeneratorInterface* const base_; + // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. + // current[i]_ is the actual traversing iterator. + const typename ParamGenerator::iterator begin1_; + const typename ParamGenerator::iterator end1_; + typename ParamGenerator::iterator current1_; + const typename ParamGenerator::iterator begin2_; + const typename ParamGenerator::iterator end2_; + typename ParamGenerator::iterator current2_; + ParamType current_value_; + }; // class CartesianProductGenerator2::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator2& other); + + const ParamGenerator g1_; + const ParamGenerator g2_; +}; // class CartesianProductGenerator2 + + +template +class CartesianProductGenerator3 + : public ParamGeneratorInterface< ::std::tr1::tuple > { + public: + typedef ::std::tr1::tuple ParamType; + + CartesianProductGenerator3(const ParamGenerator& g1, + const ParamGenerator& g2, const ParamGenerator& g3) + : g1_(g1), g2_(g2), g3_(g3) {} + virtual ~CartesianProductGenerator3() {} + + virtual ParamIteratorInterface* Begin() const { + return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, + g3_.begin()); + } + virtual ParamIteratorInterface* End() const { + return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end()); + } + + private: + class Iterator : public ParamIteratorInterface { + public: + Iterator(const ParamGeneratorInterface* base, + const ParamGenerator& g1, + const typename ParamGenerator::iterator& current1, + const ParamGenerator& g2, + const typename ParamGenerator::iterator& current2, + const ParamGenerator& g3, + const typename ParamGenerator::iterator& current3) + : base_(base), + begin1_(g1.begin()), end1_(g1.end()), current1_(current1), + begin2_(g2.begin()), end2_(g2.end()), current2_(current2), + begin3_(g3.begin()), end3_(g3.end()), current3_(current3) { + ComputeCurrentValue(); + } + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface* BaseGenerator() const { + return base_; + } + // Advance should not be called on beyond-of-range iterators + // so no component iterators must be beyond end of range, either. + virtual void Advance() { + assert(!AtEnd()); + ++current3_; + if (current3_ == end3_) { + current3_ = begin3_; + ++current2_; + } + if (current2_ == end2_) { + current2_ = begin2_; + ++current1_; + } + ComputeCurrentValue(); + } + virtual ParamIteratorInterface* Clone() const { + return new Iterator(*this); + } + virtual const ParamType* Current() const { return ¤t_value_; } + virtual bool Equals(const ParamIteratorInterface& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const Iterator* typed_other = + CheckedDowncastToActualType(&other); + // We must report iterators equal if they both point beyond their + // respective ranges. That can happen in a variety of fashions, + // so we have to consult AtEnd(). + return (AtEnd() && typed_other->AtEnd()) || + ( + current1_ == typed_other->current1_ && + current2_ == typed_other->current2_ && + current3_ == typed_other->current3_); + } + + private: + Iterator(const Iterator& other) + : base_(other.base_), + begin1_(other.begin1_), + end1_(other.end1_), + current1_(other.current1_), + begin2_(other.begin2_), + end2_(other.end2_), + current2_(other.current2_), + begin3_(other.begin3_), + end3_(other.end3_), + current3_(other.current3_) { + ComputeCurrentValue(); + } + + void ComputeCurrentValue() { + if (!AtEnd()) + current_value_ = ParamType(*current1_, *current2_, *current3_); + } + bool AtEnd() const { + // We must report iterator past the end of the range when either of the + // component iterators has reached the end of its range. + return + current1_ == end1_ || + current2_ == end2_ || + current3_ == end3_; + } + + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + + const ParamGeneratorInterface* const base_; + // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. + // current[i]_ is the actual traversing iterator. + const typename ParamGenerator::iterator begin1_; + const typename ParamGenerator::iterator end1_; + typename ParamGenerator::iterator current1_; + const typename ParamGenerator::iterator begin2_; + const typename ParamGenerator::iterator end2_; + typename ParamGenerator::iterator current2_; + const typename ParamGenerator::iterator begin3_; + const typename ParamGenerator::iterator end3_; + typename ParamGenerator::iterator current3_; + ParamType current_value_; + }; // class CartesianProductGenerator3::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator3& other); + + const ParamGenerator g1_; + const ParamGenerator g2_; + const ParamGenerator g3_; +}; // class CartesianProductGenerator3 + + +template +class CartesianProductGenerator4 + : public ParamGeneratorInterface< ::std::tr1::tuple > { + public: + typedef ::std::tr1::tuple ParamType; + + CartesianProductGenerator4(const ParamGenerator& g1, + const ParamGenerator& g2, const ParamGenerator& g3, + const ParamGenerator& g4) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4) {} + virtual ~CartesianProductGenerator4() {} + + virtual ParamIteratorInterface* Begin() const { + return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, + g3_.begin(), g4_, g4_.begin()); + } + virtual ParamIteratorInterface* End() const { + return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), + g4_, g4_.end()); + } + + private: + class Iterator : public ParamIteratorInterface { + public: + Iterator(const ParamGeneratorInterface* base, + const ParamGenerator& g1, + const typename ParamGenerator::iterator& current1, + const ParamGenerator& g2, + const typename ParamGenerator::iterator& current2, + const ParamGenerator& g3, + const typename ParamGenerator::iterator& current3, + const ParamGenerator& g4, + const typename ParamGenerator::iterator& current4) + : base_(base), + begin1_(g1.begin()), end1_(g1.end()), current1_(current1), + begin2_(g2.begin()), end2_(g2.end()), current2_(current2), + begin3_(g3.begin()), end3_(g3.end()), current3_(current3), + begin4_(g4.begin()), end4_(g4.end()), current4_(current4) { + ComputeCurrentValue(); + } + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface* BaseGenerator() const { + return base_; + } + // Advance should not be called on beyond-of-range iterators + // so no component iterators must be beyond end of range, either. + virtual void Advance() { + assert(!AtEnd()); + ++current4_; + if (current4_ == end4_) { + current4_ = begin4_; + ++current3_; + } + if (current3_ == end3_) { + current3_ = begin3_; + ++current2_; + } + if (current2_ == end2_) { + current2_ = begin2_; + ++current1_; + } + ComputeCurrentValue(); + } + virtual ParamIteratorInterface* Clone() const { + return new Iterator(*this); + } + virtual const ParamType* Current() const { return ¤t_value_; } + virtual bool Equals(const ParamIteratorInterface& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const Iterator* typed_other = + CheckedDowncastToActualType(&other); + // We must report iterators equal if they both point beyond their + // respective ranges. That can happen in a variety of fashions, + // so we have to consult AtEnd(). + return (AtEnd() && typed_other->AtEnd()) || + ( + current1_ == typed_other->current1_ && + current2_ == typed_other->current2_ && + current3_ == typed_other->current3_ && + current4_ == typed_other->current4_); + } + + private: + Iterator(const Iterator& other) + : base_(other.base_), + begin1_(other.begin1_), + end1_(other.end1_), + current1_(other.current1_), + begin2_(other.begin2_), + end2_(other.end2_), + current2_(other.current2_), + begin3_(other.begin3_), + end3_(other.end3_), + current3_(other.current3_), + begin4_(other.begin4_), + end4_(other.end4_), + current4_(other.current4_) { + ComputeCurrentValue(); + } + + void ComputeCurrentValue() { + if (!AtEnd()) + current_value_ = ParamType(*current1_, *current2_, *current3_, + *current4_); + } + bool AtEnd() const { + // We must report iterator past the end of the range when either of the + // component iterators has reached the end of its range. + return + current1_ == end1_ || + current2_ == end2_ || + current3_ == end3_ || + current4_ == end4_; + } + + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + + const ParamGeneratorInterface* const base_; + // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. + // current[i]_ is the actual traversing iterator. + const typename ParamGenerator::iterator begin1_; + const typename ParamGenerator::iterator end1_; + typename ParamGenerator::iterator current1_; + const typename ParamGenerator::iterator begin2_; + const typename ParamGenerator::iterator end2_; + typename ParamGenerator::iterator current2_; + const typename ParamGenerator::iterator begin3_; + const typename ParamGenerator::iterator end3_; + typename ParamGenerator::iterator current3_; + const typename ParamGenerator::iterator begin4_; + const typename ParamGenerator::iterator end4_; + typename ParamGenerator::iterator current4_; + ParamType current_value_; + }; // class CartesianProductGenerator4::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator4& other); + + const ParamGenerator g1_; + const ParamGenerator g2_; + const ParamGenerator g3_; + const ParamGenerator g4_; +}; // class CartesianProductGenerator4 + + +template +class CartesianProductGenerator5 + : public ParamGeneratorInterface< ::std::tr1::tuple > { + public: + typedef ::std::tr1::tuple ParamType; + + CartesianProductGenerator5(const ParamGenerator& g1, + const ParamGenerator& g2, const ParamGenerator& g3, + const ParamGenerator& g4, const ParamGenerator& g5) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5) {} + virtual ~CartesianProductGenerator5() {} + + virtual ParamIteratorInterface* Begin() const { + return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, + g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin()); + } + virtual ParamIteratorInterface* End() const { + return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), + g4_, g4_.end(), g5_, g5_.end()); + } + + private: + class Iterator : public ParamIteratorInterface { + public: + Iterator(const ParamGeneratorInterface* base, + const ParamGenerator& g1, + const typename ParamGenerator::iterator& current1, + const ParamGenerator& g2, + const typename ParamGenerator::iterator& current2, + const ParamGenerator& g3, + const typename ParamGenerator::iterator& current3, + const ParamGenerator& g4, + const typename ParamGenerator::iterator& current4, + const ParamGenerator& g5, + const typename ParamGenerator::iterator& current5) + : base_(base), + begin1_(g1.begin()), end1_(g1.end()), current1_(current1), + begin2_(g2.begin()), end2_(g2.end()), current2_(current2), + begin3_(g3.begin()), end3_(g3.end()), current3_(current3), + begin4_(g4.begin()), end4_(g4.end()), current4_(current4), + begin5_(g5.begin()), end5_(g5.end()), current5_(current5) { + ComputeCurrentValue(); + } + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface* BaseGenerator() const { + return base_; + } + // Advance should not be called on beyond-of-range iterators + // so no component iterators must be beyond end of range, either. + virtual void Advance() { + assert(!AtEnd()); + ++current5_; + if (current5_ == end5_) { + current5_ = begin5_; + ++current4_; + } + if (current4_ == end4_) { + current4_ = begin4_; + ++current3_; + } + if (current3_ == end3_) { + current3_ = begin3_; + ++current2_; + } + if (current2_ == end2_) { + current2_ = begin2_; + ++current1_; + } + ComputeCurrentValue(); + } + virtual ParamIteratorInterface* Clone() const { + return new Iterator(*this); + } + virtual const ParamType* Current() const { return ¤t_value_; } + virtual bool Equals(const ParamIteratorInterface& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const Iterator* typed_other = + CheckedDowncastToActualType(&other); + // We must report iterators equal if they both point beyond their + // respective ranges. That can happen in a variety of fashions, + // so we have to consult AtEnd(). + return (AtEnd() && typed_other->AtEnd()) || + ( + current1_ == typed_other->current1_ && + current2_ == typed_other->current2_ && + current3_ == typed_other->current3_ && + current4_ == typed_other->current4_ && + current5_ == typed_other->current5_); + } + + private: + Iterator(const Iterator& other) + : base_(other.base_), + begin1_(other.begin1_), + end1_(other.end1_), + current1_(other.current1_), + begin2_(other.begin2_), + end2_(other.end2_), + current2_(other.current2_), + begin3_(other.begin3_), + end3_(other.end3_), + current3_(other.current3_), + begin4_(other.begin4_), + end4_(other.end4_), + current4_(other.current4_), + begin5_(other.begin5_), + end5_(other.end5_), + current5_(other.current5_) { + ComputeCurrentValue(); + } + + void ComputeCurrentValue() { + if (!AtEnd()) + current_value_ = ParamType(*current1_, *current2_, *current3_, + *current4_, *current5_); + } + bool AtEnd() const { + // We must report iterator past the end of the range when either of the + // component iterators has reached the end of its range. + return + current1_ == end1_ || + current2_ == end2_ || + current3_ == end3_ || + current4_ == end4_ || + current5_ == end5_; + } + + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + + const ParamGeneratorInterface* const base_; + // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. + // current[i]_ is the actual traversing iterator. + const typename ParamGenerator::iterator begin1_; + const typename ParamGenerator::iterator end1_; + typename ParamGenerator::iterator current1_; + const typename ParamGenerator::iterator begin2_; + const typename ParamGenerator::iterator end2_; + typename ParamGenerator::iterator current2_; + const typename ParamGenerator::iterator begin3_; + const typename ParamGenerator::iterator end3_; + typename ParamGenerator::iterator current3_; + const typename ParamGenerator::iterator begin4_; + const typename ParamGenerator::iterator end4_; + typename ParamGenerator::iterator current4_; + const typename ParamGenerator::iterator begin5_; + const typename ParamGenerator::iterator end5_; + typename ParamGenerator::iterator current5_; + ParamType current_value_; + }; // class CartesianProductGenerator5::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator5& other); + + const ParamGenerator g1_; + const ParamGenerator g2_; + const ParamGenerator g3_; + const ParamGenerator g4_; + const ParamGenerator g5_; +}; // class CartesianProductGenerator5 + + +template +class CartesianProductGenerator6 + : public ParamGeneratorInterface< ::std::tr1::tuple > { + public: + typedef ::std::tr1::tuple ParamType; + + CartesianProductGenerator6(const ParamGenerator& g1, + const ParamGenerator& g2, const ParamGenerator& g3, + const ParamGenerator& g4, const ParamGenerator& g5, + const ParamGenerator& g6) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6) {} + virtual ~CartesianProductGenerator6() {} + + virtual ParamIteratorInterface* Begin() const { + return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, + g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin()); + } + virtual ParamIteratorInterface* End() const { + return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), + g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end()); + } + + private: + class Iterator : public ParamIteratorInterface { + public: + Iterator(const ParamGeneratorInterface* base, + const ParamGenerator& g1, + const typename ParamGenerator::iterator& current1, + const ParamGenerator& g2, + const typename ParamGenerator::iterator& current2, + const ParamGenerator& g3, + const typename ParamGenerator::iterator& current3, + const ParamGenerator& g4, + const typename ParamGenerator::iterator& current4, + const ParamGenerator& g5, + const typename ParamGenerator::iterator& current5, + const ParamGenerator& g6, + const typename ParamGenerator::iterator& current6) + : base_(base), + begin1_(g1.begin()), end1_(g1.end()), current1_(current1), + begin2_(g2.begin()), end2_(g2.end()), current2_(current2), + begin3_(g3.begin()), end3_(g3.end()), current3_(current3), + begin4_(g4.begin()), end4_(g4.end()), current4_(current4), + begin5_(g5.begin()), end5_(g5.end()), current5_(current5), + begin6_(g6.begin()), end6_(g6.end()), current6_(current6) { + ComputeCurrentValue(); + } + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface* BaseGenerator() const { + return base_; + } + // Advance should not be called on beyond-of-range iterators + // so no component iterators must be beyond end of range, either. + virtual void Advance() { + assert(!AtEnd()); + ++current6_; + if (current6_ == end6_) { + current6_ = begin6_; + ++current5_; + } + if (current5_ == end5_) { + current5_ = begin5_; + ++current4_; + } + if (current4_ == end4_) { + current4_ = begin4_; + ++current3_; + } + if (current3_ == end3_) { + current3_ = begin3_; + ++current2_; + } + if (current2_ == end2_) { + current2_ = begin2_; + ++current1_; + } + ComputeCurrentValue(); + } + virtual ParamIteratorInterface* Clone() const { + return new Iterator(*this); + } + virtual const ParamType* Current() const { return ¤t_value_; } + virtual bool Equals(const ParamIteratorInterface& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const Iterator* typed_other = + CheckedDowncastToActualType(&other); + // We must report iterators equal if they both point beyond their + // respective ranges. That can happen in a variety of fashions, + // so we have to consult AtEnd(). + return (AtEnd() && typed_other->AtEnd()) || + ( + current1_ == typed_other->current1_ && + current2_ == typed_other->current2_ && + current3_ == typed_other->current3_ && + current4_ == typed_other->current4_ && + current5_ == typed_other->current5_ && + current6_ == typed_other->current6_); + } + + private: + Iterator(const Iterator& other) + : base_(other.base_), + begin1_(other.begin1_), + end1_(other.end1_), + current1_(other.current1_), + begin2_(other.begin2_), + end2_(other.end2_), + current2_(other.current2_), + begin3_(other.begin3_), + end3_(other.end3_), + current3_(other.current3_), + begin4_(other.begin4_), + end4_(other.end4_), + current4_(other.current4_), + begin5_(other.begin5_), + end5_(other.end5_), + current5_(other.current5_), + begin6_(other.begin6_), + end6_(other.end6_), + current6_(other.current6_) { + ComputeCurrentValue(); + } + + void ComputeCurrentValue() { + if (!AtEnd()) + current_value_ = ParamType(*current1_, *current2_, *current3_, + *current4_, *current5_, *current6_); + } + bool AtEnd() const { + // We must report iterator past the end of the range when either of the + // component iterators has reached the end of its range. + return + current1_ == end1_ || + current2_ == end2_ || + current3_ == end3_ || + current4_ == end4_ || + current5_ == end5_ || + current6_ == end6_; + } + + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + + const ParamGeneratorInterface* const base_; + // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. + // current[i]_ is the actual traversing iterator. + const typename ParamGenerator::iterator begin1_; + const typename ParamGenerator::iterator end1_; + typename ParamGenerator::iterator current1_; + const typename ParamGenerator::iterator begin2_; + const typename ParamGenerator::iterator end2_; + typename ParamGenerator::iterator current2_; + const typename ParamGenerator::iterator begin3_; + const typename ParamGenerator::iterator end3_; + typename ParamGenerator::iterator current3_; + const typename ParamGenerator::iterator begin4_; + const typename ParamGenerator::iterator end4_; + typename ParamGenerator::iterator current4_; + const typename ParamGenerator::iterator begin5_; + const typename ParamGenerator::iterator end5_; + typename ParamGenerator::iterator current5_; + const typename ParamGenerator::iterator begin6_; + const typename ParamGenerator::iterator end6_; + typename ParamGenerator::iterator current6_; + ParamType current_value_; + }; // class CartesianProductGenerator6::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator6& other); + + const ParamGenerator g1_; + const ParamGenerator g2_; + const ParamGenerator g3_; + const ParamGenerator g4_; + const ParamGenerator g5_; + const ParamGenerator g6_; +}; // class CartesianProductGenerator6 + + +template +class CartesianProductGenerator7 + : public ParamGeneratorInterface< ::std::tr1::tuple > { + public: + typedef ::std::tr1::tuple ParamType; + + CartesianProductGenerator7(const ParamGenerator& g1, + const ParamGenerator& g2, const ParamGenerator& g3, + const ParamGenerator& g4, const ParamGenerator& g5, + const ParamGenerator& g6, const ParamGenerator& g7) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7) {} + virtual ~CartesianProductGenerator7() {} + + virtual ParamIteratorInterface* Begin() const { + return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, + g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_, + g7_.begin()); + } + virtual ParamIteratorInterface* End() const { + return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), + g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end()); + } + + private: + class Iterator : public ParamIteratorInterface { + public: + Iterator(const ParamGeneratorInterface* base, + const ParamGenerator& g1, + const typename ParamGenerator::iterator& current1, + const ParamGenerator& g2, + const typename ParamGenerator::iterator& current2, + const ParamGenerator& g3, + const typename ParamGenerator::iterator& current3, + const ParamGenerator& g4, + const typename ParamGenerator::iterator& current4, + const ParamGenerator& g5, + const typename ParamGenerator::iterator& current5, + const ParamGenerator& g6, + const typename ParamGenerator::iterator& current6, + const ParamGenerator& g7, + const typename ParamGenerator::iterator& current7) + : base_(base), + begin1_(g1.begin()), end1_(g1.end()), current1_(current1), + begin2_(g2.begin()), end2_(g2.end()), current2_(current2), + begin3_(g3.begin()), end3_(g3.end()), current3_(current3), + begin4_(g4.begin()), end4_(g4.end()), current4_(current4), + begin5_(g5.begin()), end5_(g5.end()), current5_(current5), + begin6_(g6.begin()), end6_(g6.end()), current6_(current6), + begin7_(g7.begin()), end7_(g7.end()), current7_(current7) { + ComputeCurrentValue(); + } + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface* BaseGenerator() const { + return base_; + } + // Advance should not be called on beyond-of-range iterators + // so no component iterators must be beyond end of range, either. + virtual void Advance() { + assert(!AtEnd()); + ++current7_; + if (current7_ == end7_) { + current7_ = begin7_; + ++current6_; + } + if (current6_ == end6_) { + current6_ = begin6_; + ++current5_; + } + if (current5_ == end5_) { + current5_ = begin5_; + ++current4_; + } + if (current4_ == end4_) { + current4_ = begin4_; + ++current3_; + } + if (current3_ == end3_) { + current3_ = begin3_; + ++current2_; + } + if (current2_ == end2_) { + current2_ = begin2_; + ++current1_; + } + ComputeCurrentValue(); + } + virtual ParamIteratorInterface* Clone() const { + return new Iterator(*this); + } + virtual const ParamType* Current() const { return ¤t_value_; } + virtual bool Equals(const ParamIteratorInterface& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const Iterator* typed_other = + CheckedDowncastToActualType(&other); + // We must report iterators equal if they both point beyond their + // respective ranges. That can happen in a variety of fashions, + // so we have to consult AtEnd(). + return (AtEnd() && typed_other->AtEnd()) || + ( + current1_ == typed_other->current1_ && + current2_ == typed_other->current2_ && + current3_ == typed_other->current3_ && + current4_ == typed_other->current4_ && + current5_ == typed_other->current5_ && + current6_ == typed_other->current6_ && + current7_ == typed_other->current7_); + } + + private: + Iterator(const Iterator& other) + : base_(other.base_), + begin1_(other.begin1_), + end1_(other.end1_), + current1_(other.current1_), + begin2_(other.begin2_), + end2_(other.end2_), + current2_(other.current2_), + begin3_(other.begin3_), + end3_(other.end3_), + current3_(other.current3_), + begin4_(other.begin4_), + end4_(other.end4_), + current4_(other.current4_), + begin5_(other.begin5_), + end5_(other.end5_), + current5_(other.current5_), + begin6_(other.begin6_), + end6_(other.end6_), + current6_(other.current6_), + begin7_(other.begin7_), + end7_(other.end7_), + current7_(other.current7_) { + ComputeCurrentValue(); + } + + void ComputeCurrentValue() { + if (!AtEnd()) + current_value_ = ParamType(*current1_, *current2_, *current3_, + *current4_, *current5_, *current6_, *current7_); + } + bool AtEnd() const { + // We must report iterator past the end of the range when either of the + // component iterators has reached the end of its range. + return + current1_ == end1_ || + current2_ == end2_ || + current3_ == end3_ || + current4_ == end4_ || + current5_ == end5_ || + current6_ == end6_ || + current7_ == end7_; + } + + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + + const ParamGeneratorInterface* const base_; + // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. + // current[i]_ is the actual traversing iterator. + const typename ParamGenerator::iterator begin1_; + const typename ParamGenerator::iterator end1_; + typename ParamGenerator::iterator current1_; + const typename ParamGenerator::iterator begin2_; + const typename ParamGenerator::iterator end2_; + typename ParamGenerator::iterator current2_; + const typename ParamGenerator::iterator begin3_; + const typename ParamGenerator::iterator end3_; + typename ParamGenerator::iterator current3_; + const typename ParamGenerator::iterator begin4_; + const typename ParamGenerator::iterator end4_; + typename ParamGenerator::iterator current4_; + const typename ParamGenerator::iterator begin5_; + const typename ParamGenerator::iterator end5_; + typename ParamGenerator::iterator current5_; + const typename ParamGenerator::iterator begin6_; + const typename ParamGenerator::iterator end6_; + typename ParamGenerator::iterator current6_; + const typename ParamGenerator::iterator begin7_; + const typename ParamGenerator::iterator end7_; + typename ParamGenerator::iterator current7_; + ParamType current_value_; + }; // class CartesianProductGenerator7::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator7& other); + + const ParamGenerator g1_; + const ParamGenerator g2_; + const ParamGenerator g3_; + const ParamGenerator g4_; + const ParamGenerator g5_; + const ParamGenerator g6_; + const ParamGenerator g7_; +}; // class CartesianProductGenerator7 + + +template +class CartesianProductGenerator8 + : public ParamGeneratorInterface< ::std::tr1::tuple > { + public: + typedef ::std::tr1::tuple ParamType; + + CartesianProductGenerator8(const ParamGenerator& g1, + const ParamGenerator& g2, const ParamGenerator& g3, + const ParamGenerator& g4, const ParamGenerator& g5, + const ParamGenerator& g6, const ParamGenerator& g7, + const ParamGenerator& g8) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), + g8_(g8) {} + virtual ~CartesianProductGenerator8() {} + + virtual ParamIteratorInterface* Begin() const { + return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, + g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_, + g7_.begin(), g8_, g8_.begin()); + } + virtual ParamIteratorInterface* End() const { + return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), + g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end(), g8_, + g8_.end()); + } + + private: + class Iterator : public ParamIteratorInterface { + public: + Iterator(const ParamGeneratorInterface* base, + const ParamGenerator& g1, + const typename ParamGenerator::iterator& current1, + const ParamGenerator& g2, + const typename ParamGenerator::iterator& current2, + const ParamGenerator& g3, + const typename ParamGenerator::iterator& current3, + const ParamGenerator& g4, + const typename ParamGenerator::iterator& current4, + const ParamGenerator& g5, + const typename ParamGenerator::iterator& current5, + const ParamGenerator& g6, + const typename ParamGenerator::iterator& current6, + const ParamGenerator& g7, + const typename ParamGenerator::iterator& current7, + const ParamGenerator& g8, + const typename ParamGenerator::iterator& current8) + : base_(base), + begin1_(g1.begin()), end1_(g1.end()), current1_(current1), + begin2_(g2.begin()), end2_(g2.end()), current2_(current2), + begin3_(g3.begin()), end3_(g3.end()), current3_(current3), + begin4_(g4.begin()), end4_(g4.end()), current4_(current4), + begin5_(g5.begin()), end5_(g5.end()), current5_(current5), + begin6_(g6.begin()), end6_(g6.end()), current6_(current6), + begin7_(g7.begin()), end7_(g7.end()), current7_(current7), + begin8_(g8.begin()), end8_(g8.end()), current8_(current8) { + ComputeCurrentValue(); + } + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface* BaseGenerator() const { + return base_; + } + // Advance should not be called on beyond-of-range iterators + // so no component iterators must be beyond end of range, either. + virtual void Advance() { + assert(!AtEnd()); + ++current8_; + if (current8_ == end8_) { + current8_ = begin8_; + ++current7_; + } + if (current7_ == end7_) { + current7_ = begin7_; + ++current6_; + } + if (current6_ == end6_) { + current6_ = begin6_; + ++current5_; + } + if (current5_ == end5_) { + current5_ = begin5_; + ++current4_; + } + if (current4_ == end4_) { + current4_ = begin4_; + ++current3_; + } + if (current3_ == end3_) { + current3_ = begin3_; + ++current2_; + } + if (current2_ == end2_) { + current2_ = begin2_; + ++current1_; + } + ComputeCurrentValue(); + } + virtual ParamIteratorInterface* Clone() const { + return new Iterator(*this); + } + virtual const ParamType* Current() const { return ¤t_value_; } + virtual bool Equals(const ParamIteratorInterface& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const Iterator* typed_other = + CheckedDowncastToActualType(&other); + // We must report iterators equal if they both point beyond their + // respective ranges. That can happen in a variety of fashions, + // so we have to consult AtEnd(). + return (AtEnd() && typed_other->AtEnd()) || + ( + current1_ == typed_other->current1_ && + current2_ == typed_other->current2_ && + current3_ == typed_other->current3_ && + current4_ == typed_other->current4_ && + current5_ == typed_other->current5_ && + current6_ == typed_other->current6_ && + current7_ == typed_other->current7_ && + current8_ == typed_other->current8_); + } + + private: + Iterator(const Iterator& other) + : base_(other.base_), + begin1_(other.begin1_), + end1_(other.end1_), + current1_(other.current1_), + begin2_(other.begin2_), + end2_(other.end2_), + current2_(other.current2_), + begin3_(other.begin3_), + end3_(other.end3_), + current3_(other.current3_), + begin4_(other.begin4_), + end4_(other.end4_), + current4_(other.current4_), + begin5_(other.begin5_), + end5_(other.end5_), + current5_(other.current5_), + begin6_(other.begin6_), + end6_(other.end6_), + current6_(other.current6_), + begin7_(other.begin7_), + end7_(other.end7_), + current7_(other.current7_), + begin8_(other.begin8_), + end8_(other.end8_), + current8_(other.current8_) { + ComputeCurrentValue(); + } + + void ComputeCurrentValue() { + if (!AtEnd()) + current_value_ = ParamType(*current1_, *current2_, *current3_, + *current4_, *current5_, *current6_, *current7_, *current8_); + } + bool AtEnd() const { + // We must report iterator past the end of the range when either of the + // component iterators has reached the end of its range. + return + current1_ == end1_ || + current2_ == end2_ || + current3_ == end3_ || + current4_ == end4_ || + current5_ == end5_ || + current6_ == end6_ || + current7_ == end7_ || + current8_ == end8_; + } + + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + + const ParamGeneratorInterface* const base_; + // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. + // current[i]_ is the actual traversing iterator. + const typename ParamGenerator::iterator begin1_; + const typename ParamGenerator::iterator end1_; + typename ParamGenerator::iterator current1_; + const typename ParamGenerator::iterator begin2_; + const typename ParamGenerator::iterator end2_; + typename ParamGenerator::iterator current2_; + const typename ParamGenerator::iterator begin3_; + const typename ParamGenerator::iterator end3_; + typename ParamGenerator::iterator current3_; + const typename ParamGenerator::iterator begin4_; + const typename ParamGenerator::iterator end4_; + typename ParamGenerator::iterator current4_; + const typename ParamGenerator::iterator begin5_; + const typename ParamGenerator::iterator end5_; + typename ParamGenerator::iterator current5_; + const typename ParamGenerator::iterator begin6_; + const typename ParamGenerator::iterator end6_; + typename ParamGenerator::iterator current6_; + const typename ParamGenerator::iterator begin7_; + const typename ParamGenerator::iterator end7_; + typename ParamGenerator::iterator current7_; + const typename ParamGenerator::iterator begin8_; + const typename ParamGenerator::iterator end8_; + typename ParamGenerator::iterator current8_; + ParamType current_value_; + }; // class CartesianProductGenerator8::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator8& other); + + const ParamGenerator g1_; + const ParamGenerator g2_; + const ParamGenerator g3_; + const ParamGenerator g4_; + const ParamGenerator g5_; + const ParamGenerator g6_; + const ParamGenerator g7_; + const ParamGenerator g8_; +}; // class CartesianProductGenerator8 + + +template +class CartesianProductGenerator9 + : public ParamGeneratorInterface< ::std::tr1::tuple > { + public: + typedef ::std::tr1::tuple ParamType; + + CartesianProductGenerator9(const ParamGenerator& g1, + const ParamGenerator& g2, const ParamGenerator& g3, + const ParamGenerator& g4, const ParamGenerator& g5, + const ParamGenerator& g6, const ParamGenerator& g7, + const ParamGenerator& g8, const ParamGenerator& g9) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8), + g9_(g9) {} + virtual ~CartesianProductGenerator9() {} + + virtual ParamIteratorInterface* Begin() const { + return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, + g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_, + g7_.begin(), g8_, g8_.begin(), g9_, g9_.begin()); + } + virtual ParamIteratorInterface* End() const { + return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), + g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end(), g8_, + g8_.end(), g9_, g9_.end()); + } + + private: + class Iterator : public ParamIteratorInterface { + public: + Iterator(const ParamGeneratorInterface* base, + const ParamGenerator& g1, + const typename ParamGenerator::iterator& current1, + const ParamGenerator& g2, + const typename ParamGenerator::iterator& current2, + const ParamGenerator& g3, + const typename ParamGenerator::iterator& current3, + const ParamGenerator& g4, + const typename ParamGenerator::iterator& current4, + const ParamGenerator& g5, + const typename ParamGenerator::iterator& current5, + const ParamGenerator& g6, + const typename ParamGenerator::iterator& current6, + const ParamGenerator& g7, + const typename ParamGenerator::iterator& current7, + const ParamGenerator& g8, + const typename ParamGenerator::iterator& current8, + const ParamGenerator& g9, + const typename ParamGenerator::iterator& current9) + : base_(base), + begin1_(g1.begin()), end1_(g1.end()), current1_(current1), + begin2_(g2.begin()), end2_(g2.end()), current2_(current2), + begin3_(g3.begin()), end3_(g3.end()), current3_(current3), + begin4_(g4.begin()), end4_(g4.end()), current4_(current4), + begin5_(g5.begin()), end5_(g5.end()), current5_(current5), + begin6_(g6.begin()), end6_(g6.end()), current6_(current6), + begin7_(g7.begin()), end7_(g7.end()), current7_(current7), + begin8_(g8.begin()), end8_(g8.end()), current8_(current8), + begin9_(g9.begin()), end9_(g9.end()), current9_(current9) { + ComputeCurrentValue(); + } + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface* BaseGenerator() const { + return base_; + } + // Advance should not be called on beyond-of-range iterators + // so no component iterators must be beyond end of range, either. + virtual void Advance() { + assert(!AtEnd()); + ++current9_; + if (current9_ == end9_) { + current9_ = begin9_; + ++current8_; + } + if (current8_ == end8_) { + current8_ = begin8_; + ++current7_; + } + if (current7_ == end7_) { + current7_ = begin7_; + ++current6_; + } + if (current6_ == end6_) { + current6_ = begin6_; + ++current5_; + } + if (current5_ == end5_) { + current5_ = begin5_; + ++current4_; + } + if (current4_ == end4_) { + current4_ = begin4_; + ++current3_; + } + if (current3_ == end3_) { + current3_ = begin3_; + ++current2_; + } + if (current2_ == end2_) { + current2_ = begin2_; + ++current1_; + } + ComputeCurrentValue(); + } + virtual ParamIteratorInterface* Clone() const { + return new Iterator(*this); + } + virtual const ParamType* Current() const { return ¤t_value_; } + virtual bool Equals(const ParamIteratorInterface& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const Iterator* typed_other = + CheckedDowncastToActualType(&other); + // We must report iterators equal if they both point beyond their + // respective ranges. That can happen in a variety of fashions, + // so we have to consult AtEnd(). + return (AtEnd() && typed_other->AtEnd()) || + ( + current1_ == typed_other->current1_ && + current2_ == typed_other->current2_ && + current3_ == typed_other->current3_ && + current4_ == typed_other->current4_ && + current5_ == typed_other->current5_ && + current6_ == typed_other->current6_ && + current7_ == typed_other->current7_ && + current8_ == typed_other->current8_ && + current9_ == typed_other->current9_); + } + + private: + Iterator(const Iterator& other) + : base_(other.base_), + begin1_(other.begin1_), + end1_(other.end1_), + current1_(other.current1_), + begin2_(other.begin2_), + end2_(other.end2_), + current2_(other.current2_), + begin3_(other.begin3_), + end3_(other.end3_), + current3_(other.current3_), + begin4_(other.begin4_), + end4_(other.end4_), + current4_(other.current4_), + begin5_(other.begin5_), + end5_(other.end5_), + current5_(other.current5_), + begin6_(other.begin6_), + end6_(other.end6_), + current6_(other.current6_), + begin7_(other.begin7_), + end7_(other.end7_), + current7_(other.current7_), + begin8_(other.begin8_), + end8_(other.end8_), + current8_(other.current8_), + begin9_(other.begin9_), + end9_(other.end9_), + current9_(other.current9_) { + ComputeCurrentValue(); + } + + void ComputeCurrentValue() { + if (!AtEnd()) + current_value_ = ParamType(*current1_, *current2_, *current3_, + *current4_, *current5_, *current6_, *current7_, *current8_, + *current9_); + } + bool AtEnd() const { + // We must report iterator past the end of the range when either of the + // component iterators has reached the end of its range. + return + current1_ == end1_ || + current2_ == end2_ || + current3_ == end3_ || + current4_ == end4_ || + current5_ == end5_ || + current6_ == end6_ || + current7_ == end7_ || + current8_ == end8_ || + current9_ == end9_; + } + + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + + const ParamGeneratorInterface* const base_; + // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. + // current[i]_ is the actual traversing iterator. + const typename ParamGenerator::iterator begin1_; + const typename ParamGenerator::iterator end1_; + typename ParamGenerator::iterator current1_; + const typename ParamGenerator::iterator begin2_; + const typename ParamGenerator::iterator end2_; + typename ParamGenerator::iterator current2_; + const typename ParamGenerator::iterator begin3_; + const typename ParamGenerator::iterator end3_; + typename ParamGenerator::iterator current3_; + const typename ParamGenerator::iterator begin4_; + const typename ParamGenerator::iterator end4_; + typename ParamGenerator::iterator current4_; + const typename ParamGenerator::iterator begin5_; + const typename ParamGenerator::iterator end5_; + typename ParamGenerator::iterator current5_; + const typename ParamGenerator::iterator begin6_; + const typename ParamGenerator::iterator end6_; + typename ParamGenerator::iterator current6_; + const typename ParamGenerator::iterator begin7_; + const typename ParamGenerator::iterator end7_; + typename ParamGenerator::iterator current7_; + const typename ParamGenerator::iterator begin8_; + const typename ParamGenerator::iterator end8_; + typename ParamGenerator::iterator current8_; + const typename ParamGenerator::iterator begin9_; + const typename ParamGenerator::iterator end9_; + typename ParamGenerator::iterator current9_; + ParamType current_value_; + }; // class CartesianProductGenerator9::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator9& other); + + const ParamGenerator g1_; + const ParamGenerator g2_; + const ParamGenerator g3_; + const ParamGenerator g4_; + const ParamGenerator g5_; + const ParamGenerator g6_; + const ParamGenerator g7_; + const ParamGenerator g8_; + const ParamGenerator g9_; +}; // class CartesianProductGenerator9 + + +template +class CartesianProductGenerator10 + : public ParamGeneratorInterface< ::std::tr1::tuple > { + public: + typedef ::std::tr1::tuple ParamType; + + CartesianProductGenerator10(const ParamGenerator& g1, + const ParamGenerator& g2, const ParamGenerator& g3, + const ParamGenerator& g4, const ParamGenerator& g5, + const ParamGenerator& g6, const ParamGenerator& g7, + const ParamGenerator& g8, const ParamGenerator& g9, + const ParamGenerator& g10) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8), + g9_(g9), g10_(g10) {} + virtual ~CartesianProductGenerator10() {} + + virtual ParamIteratorInterface* Begin() const { + return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, + g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_, + g7_.begin(), g8_, g8_.begin(), g9_, g9_.begin(), g10_, g10_.begin()); + } + virtual ParamIteratorInterface* End() const { + return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), + g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end(), g8_, + g8_.end(), g9_, g9_.end(), g10_, g10_.end()); + } + + private: + class Iterator : public ParamIteratorInterface { + public: + Iterator(const ParamGeneratorInterface* base, + const ParamGenerator& g1, + const typename ParamGenerator::iterator& current1, + const ParamGenerator& g2, + const typename ParamGenerator::iterator& current2, + const ParamGenerator& g3, + const typename ParamGenerator::iterator& current3, + const ParamGenerator& g4, + const typename ParamGenerator::iterator& current4, + const ParamGenerator& g5, + const typename ParamGenerator::iterator& current5, + const ParamGenerator& g6, + const typename ParamGenerator::iterator& current6, + const ParamGenerator& g7, + const typename ParamGenerator::iterator& current7, + const ParamGenerator& g8, + const typename ParamGenerator::iterator& current8, + const ParamGenerator& g9, + const typename ParamGenerator::iterator& current9, + const ParamGenerator& g10, + const typename ParamGenerator::iterator& current10) + : base_(base), + begin1_(g1.begin()), end1_(g1.end()), current1_(current1), + begin2_(g2.begin()), end2_(g2.end()), current2_(current2), + begin3_(g3.begin()), end3_(g3.end()), current3_(current3), + begin4_(g4.begin()), end4_(g4.end()), current4_(current4), + begin5_(g5.begin()), end5_(g5.end()), current5_(current5), + begin6_(g6.begin()), end6_(g6.end()), current6_(current6), + begin7_(g7.begin()), end7_(g7.end()), current7_(current7), + begin8_(g8.begin()), end8_(g8.end()), current8_(current8), + begin9_(g9.begin()), end9_(g9.end()), current9_(current9), + begin10_(g10.begin()), end10_(g10.end()), current10_(current10) { + ComputeCurrentValue(); + } + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface* BaseGenerator() const { + return base_; + } + // Advance should not be called on beyond-of-range iterators + // so no component iterators must be beyond end of range, either. + virtual void Advance() { + assert(!AtEnd()); + ++current10_; + if (current10_ == end10_) { + current10_ = begin10_; + ++current9_; + } + if (current9_ == end9_) { + current9_ = begin9_; + ++current8_; + } + if (current8_ == end8_) { + current8_ = begin8_; + ++current7_; + } + if (current7_ == end7_) { + current7_ = begin7_; + ++current6_; + } + if (current6_ == end6_) { + current6_ = begin6_; + ++current5_; + } + if (current5_ == end5_) { + current5_ = begin5_; + ++current4_; + } + if (current4_ == end4_) { + current4_ = begin4_; + ++current3_; + } + if (current3_ == end3_) { + current3_ = begin3_; + ++current2_; + } + if (current2_ == end2_) { + current2_ = begin2_; + ++current1_; + } + ComputeCurrentValue(); + } + virtual ParamIteratorInterface* Clone() const { + return new Iterator(*this); + } + virtual const ParamType* Current() const { return ¤t_value_; } + virtual bool Equals(const ParamIteratorInterface& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const Iterator* typed_other = + CheckedDowncastToActualType(&other); + // We must report iterators equal if they both point beyond their + // respective ranges. That can happen in a variety of fashions, + // so we have to consult AtEnd(). + return (AtEnd() && typed_other->AtEnd()) || + ( + current1_ == typed_other->current1_ && + current2_ == typed_other->current2_ && + current3_ == typed_other->current3_ && + current4_ == typed_other->current4_ && + current5_ == typed_other->current5_ && + current6_ == typed_other->current6_ && + current7_ == typed_other->current7_ && + current8_ == typed_other->current8_ && + current9_ == typed_other->current9_ && + current10_ == typed_other->current10_); + } + + private: + Iterator(const Iterator& other) + : base_(other.base_), + begin1_(other.begin1_), + end1_(other.end1_), + current1_(other.current1_), + begin2_(other.begin2_), + end2_(other.end2_), + current2_(other.current2_), + begin3_(other.begin3_), + end3_(other.end3_), + current3_(other.current3_), + begin4_(other.begin4_), + end4_(other.end4_), + current4_(other.current4_), + begin5_(other.begin5_), + end5_(other.end5_), + current5_(other.current5_), + begin6_(other.begin6_), + end6_(other.end6_), + current6_(other.current6_), + begin7_(other.begin7_), + end7_(other.end7_), + current7_(other.current7_), + begin8_(other.begin8_), + end8_(other.end8_), + current8_(other.current8_), + begin9_(other.begin9_), + end9_(other.end9_), + current9_(other.current9_), + begin10_(other.begin10_), + end10_(other.end10_), + current10_(other.current10_) { + ComputeCurrentValue(); + } + + void ComputeCurrentValue() { + if (!AtEnd()) + current_value_ = ParamType(*current1_, *current2_, *current3_, + *current4_, *current5_, *current6_, *current7_, *current8_, + *current9_, *current10_); + } + bool AtEnd() const { + // We must report iterator past the end of the range when either of the + // component iterators has reached the end of its range. + return + current1_ == end1_ || + current2_ == end2_ || + current3_ == end3_ || + current4_ == end4_ || + current5_ == end5_ || + current6_ == end6_ || + current7_ == end7_ || + current8_ == end8_ || + current9_ == end9_ || + current10_ == end10_; + } + + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + + const ParamGeneratorInterface* const base_; + // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. + // current[i]_ is the actual traversing iterator. + const typename ParamGenerator::iterator begin1_; + const typename ParamGenerator::iterator end1_; + typename ParamGenerator::iterator current1_; + const typename ParamGenerator::iterator begin2_; + const typename ParamGenerator::iterator end2_; + typename ParamGenerator::iterator current2_; + const typename ParamGenerator::iterator begin3_; + const typename ParamGenerator::iterator end3_; + typename ParamGenerator::iterator current3_; + const typename ParamGenerator::iterator begin4_; + const typename ParamGenerator::iterator end4_; + typename ParamGenerator::iterator current4_; + const typename ParamGenerator::iterator begin5_; + const typename ParamGenerator::iterator end5_; + typename ParamGenerator::iterator current5_; + const typename ParamGenerator::iterator begin6_; + const typename ParamGenerator::iterator end6_; + typename ParamGenerator::iterator current6_; + const typename ParamGenerator::iterator begin7_; + const typename ParamGenerator::iterator end7_; + typename ParamGenerator::iterator current7_; + const typename ParamGenerator::iterator begin8_; + const typename ParamGenerator::iterator end8_; + typename ParamGenerator::iterator current8_; + const typename ParamGenerator::iterator begin9_; + const typename ParamGenerator::iterator end9_; + typename ParamGenerator::iterator current9_; + const typename ParamGenerator::iterator begin10_; + const typename ParamGenerator::iterator end10_; + typename ParamGenerator::iterator current10_; + ParamType current_value_; + }; // class CartesianProductGenerator10::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator10& other); + + const ParamGenerator g1_; + const ParamGenerator g2_; + const ParamGenerator g3_; + const ParamGenerator g4_; + const ParamGenerator g5_; + const ParamGenerator g6_; + const ParamGenerator g7_; + const ParamGenerator g8_; + const ParamGenerator g9_; + const ParamGenerator g10_; +}; // class CartesianProductGenerator10 + + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// Helper classes providing Combine() with polymorphic features. They allow +// casting CartesianProductGeneratorN to ParamGenerator if T is +// convertible to U. +// +template +class CartesianProductHolder2 { + public: +CartesianProductHolder2(const Generator1& g1, const Generator2& g2) + : g1_(g1), g2_(g2) {} + template + operator ParamGenerator< ::std::tr1::tuple >() const { + return ParamGenerator< ::std::tr1::tuple >( + new CartesianProductGenerator2( + static_cast >(g1_), + static_cast >(g2_))); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder2& other); + + const Generator1 g1_; + const Generator2 g2_; +}; // class CartesianProductHolder2 + +template +class CartesianProductHolder3 { + public: +CartesianProductHolder3(const Generator1& g1, const Generator2& g2, + const Generator3& g3) + : g1_(g1), g2_(g2), g3_(g3) {} + template + operator ParamGenerator< ::std::tr1::tuple >() const { + return ParamGenerator< ::std::tr1::tuple >( + new CartesianProductGenerator3( + static_cast >(g1_), + static_cast >(g2_), + static_cast >(g3_))); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder3& other); + + const Generator1 g1_; + const Generator2 g2_; + const Generator3 g3_; +}; // class CartesianProductHolder3 + +template +class CartesianProductHolder4 { + public: +CartesianProductHolder4(const Generator1& g1, const Generator2& g2, + const Generator3& g3, const Generator4& g4) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4) {} + template + operator ParamGenerator< ::std::tr1::tuple >() const { + return ParamGenerator< ::std::tr1::tuple >( + new CartesianProductGenerator4( + static_cast >(g1_), + static_cast >(g2_), + static_cast >(g3_), + static_cast >(g4_))); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder4& other); + + const Generator1 g1_; + const Generator2 g2_; + const Generator3 g3_; + const Generator4 g4_; +}; // class CartesianProductHolder4 + +template +class CartesianProductHolder5 { + public: +CartesianProductHolder5(const Generator1& g1, const Generator2& g2, + const Generator3& g3, const Generator4& g4, const Generator5& g5) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5) {} + template + operator ParamGenerator< ::std::tr1::tuple >() const { + return ParamGenerator< ::std::tr1::tuple >( + new CartesianProductGenerator5( + static_cast >(g1_), + static_cast >(g2_), + static_cast >(g3_), + static_cast >(g4_), + static_cast >(g5_))); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder5& other); + + const Generator1 g1_; + const Generator2 g2_; + const Generator3 g3_; + const Generator4 g4_; + const Generator5 g5_; +}; // class CartesianProductHolder5 + +template +class CartesianProductHolder6 { + public: +CartesianProductHolder6(const Generator1& g1, const Generator2& g2, + const Generator3& g3, const Generator4& g4, const Generator5& g5, + const Generator6& g6) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6) {} + template + operator ParamGenerator< ::std::tr1::tuple >() const { + return ParamGenerator< ::std::tr1::tuple >( + new CartesianProductGenerator6( + static_cast >(g1_), + static_cast >(g2_), + static_cast >(g3_), + static_cast >(g4_), + static_cast >(g5_), + static_cast >(g6_))); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder6& other); + + const Generator1 g1_; + const Generator2 g2_; + const Generator3 g3_; + const Generator4 g4_; + const Generator5 g5_; + const Generator6 g6_; +}; // class CartesianProductHolder6 + +template +class CartesianProductHolder7 { + public: +CartesianProductHolder7(const Generator1& g1, const Generator2& g2, + const Generator3& g3, const Generator4& g4, const Generator5& g5, + const Generator6& g6, const Generator7& g7) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7) {} + template + operator ParamGenerator< ::std::tr1::tuple >() const { + return ParamGenerator< ::std::tr1::tuple >( + new CartesianProductGenerator7( + static_cast >(g1_), + static_cast >(g2_), + static_cast >(g3_), + static_cast >(g4_), + static_cast >(g5_), + static_cast >(g6_), + static_cast >(g7_))); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder7& other); + + const Generator1 g1_; + const Generator2 g2_; + const Generator3 g3_; + const Generator4 g4_; + const Generator5 g5_; + const Generator6 g6_; + const Generator7 g7_; +}; // class CartesianProductHolder7 + +template +class CartesianProductHolder8 { + public: +CartesianProductHolder8(const Generator1& g1, const Generator2& g2, + const Generator3& g3, const Generator4& g4, const Generator5& g5, + const Generator6& g6, const Generator7& g7, const Generator8& g8) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), + g8_(g8) {} + template + operator ParamGenerator< ::std::tr1::tuple >() const { + return ParamGenerator< ::std::tr1::tuple >( + new CartesianProductGenerator8( + static_cast >(g1_), + static_cast >(g2_), + static_cast >(g3_), + static_cast >(g4_), + static_cast >(g5_), + static_cast >(g6_), + static_cast >(g7_), + static_cast >(g8_))); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder8& other); + + const Generator1 g1_; + const Generator2 g2_; + const Generator3 g3_; + const Generator4 g4_; + const Generator5 g5_; + const Generator6 g6_; + const Generator7 g7_; + const Generator8 g8_; +}; // class CartesianProductHolder8 + +template +class CartesianProductHolder9 { + public: +CartesianProductHolder9(const Generator1& g1, const Generator2& g2, + const Generator3& g3, const Generator4& g4, const Generator5& g5, + const Generator6& g6, const Generator7& g7, const Generator8& g8, + const Generator9& g9) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8), + g9_(g9) {} + template + operator ParamGenerator< ::std::tr1::tuple >() const { + return ParamGenerator< ::std::tr1::tuple >( + new CartesianProductGenerator9( + static_cast >(g1_), + static_cast >(g2_), + static_cast >(g3_), + static_cast >(g4_), + static_cast >(g5_), + static_cast >(g6_), + static_cast >(g7_), + static_cast >(g8_), + static_cast >(g9_))); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder9& other); + + const Generator1 g1_; + const Generator2 g2_; + const Generator3 g3_; + const Generator4 g4_; + const Generator5 g5_; + const Generator6 g6_; + const Generator7 g7_; + const Generator8 g8_; + const Generator9 g9_; +}; // class CartesianProductHolder9 + +template +class CartesianProductHolder10 { + public: +CartesianProductHolder10(const Generator1& g1, const Generator2& g2, + const Generator3& g3, const Generator4& g4, const Generator5& g5, + const Generator6& g6, const Generator7& g7, const Generator8& g8, + const Generator9& g9, const Generator10& g10) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8), + g9_(g9), g10_(g10) {} + template + operator ParamGenerator< ::std::tr1::tuple >() const { + return ParamGenerator< ::std::tr1::tuple >( + new CartesianProductGenerator10( + static_cast >(g1_), + static_cast >(g2_), + static_cast >(g3_), + static_cast >(g4_), + static_cast >(g5_), + static_cast >(g6_), + static_cast >(g7_), + static_cast >(g8_), + static_cast >(g9_), + static_cast >(g10_))); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder10& other); + + const Generator1 g1_; + const Generator2 g2_; + const Generator3 g3_; + const Generator4 g4_; + const Generator5 g5_; + const Generator6 g6_; + const Generator7 g7_; + const Generator8 g8_; + const Generator9 g9_; + const Generator10 g10_; +}; // class CartesianProductHolder10 + +#endif // GTEST_HAS_COMBINE + +} // namespace internal +} // namespace testing + +#endif // GTEST_HAS_PARAM_TEST + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_ + +#if GTEST_HAS_PARAM_TEST + +namespace testing { + +// Functions producing parameter generators. +// +// Google Test uses these generators to produce parameters for value- +// parameterized tests. When a parameterized test case is instantiated +// with a particular generator, Google Test creates and runs tests +// for each element in the sequence produced by the generator. +// +// In the following sample, tests from test case FooTest are instantiated +// each three times with parameter values 3, 5, and 8: +// +// class FooTest : public TestWithParam { ... }; +// +// TEST_P(FooTest, TestThis) { +// } +// TEST_P(FooTest, TestThat) { +// } +// INSTANTIATE_TEST_CASE_P(TestSequence, FooTest, Values(3, 5, 8)); +// + +// Range() returns generators providing sequences of values in a range. +// +// Synopsis: +// Range(start, end) +// - returns a generator producing a sequence of values {start, start+1, +// start+2, ..., }. +// Range(start, end, step) +// - returns a generator producing a sequence of values {start, start+step, +// start+step+step, ..., }. +// Notes: +// * The generated sequences never include end. For example, Range(1, 5) +// returns a generator producing a sequence {1, 2, 3, 4}. Range(1, 9, 2) +// returns a generator producing {1, 3, 5, 7}. +// * start and end must have the same type. That type may be any integral or +// floating-point type or a user defined type satisfying these conditions: +// * It must be assignable (have operator=() defined). +// * It must have operator+() (operator+(int-compatible type) for +// two-operand version). +// * It must have operator<() defined. +// Elements in the resulting sequences will also have that type. +// * Condition start < end must be satisfied in order for resulting sequences +// to contain any elements. +// +template +internal::ParamGenerator Range(T start, T end, IncrementT step) { + return internal::ParamGenerator( + new internal::RangeGenerator(start, end, step)); +} + +template +internal::ParamGenerator Range(T start, T end) { + return Range(start, end, 1); +} + +// ValuesIn() function allows generation of tests with parameters coming from +// a container. +// +// Synopsis: +// ValuesIn(const T (&array)[N]) +// - returns a generator producing sequences with elements from +// a C-style array. +// ValuesIn(const Container& container) +// - returns a generator producing sequences with elements from +// an STL-style container. +// ValuesIn(Iterator begin, Iterator end) +// - returns a generator producing sequences with elements from +// a range [begin, end) defined by a pair of STL-style iterators. These +// iterators can also be plain C pointers. +// +// Please note that ValuesIn copies the values from the containers +// passed in and keeps them to generate tests in RUN_ALL_TESTS(). +// +// Examples: +// +// This instantiates tests from test case StringTest +// each with C-string values of "foo", "bar", and "baz": +// +// const char* strings[] = {"foo", "bar", "baz"}; +// INSTANTIATE_TEST_CASE_P(StringSequence, SrtingTest, ValuesIn(strings)); +// +// This instantiates tests from test case StlStringTest +// each with STL strings with values "a" and "b": +// +// ::std::vector< ::std::string> GetParameterStrings() { +// ::std::vector< ::std::string> v; +// v.push_back("a"); +// v.push_back("b"); +// return v; +// } +// +// INSTANTIATE_TEST_CASE_P(CharSequence, +// StlStringTest, +// ValuesIn(GetParameterStrings())); +// +// +// This will also instantiate tests from CharTest +// each with parameter values 'a' and 'b': +// +// ::std::list GetParameterChars() { +// ::std::list list; +// list.push_back('a'); +// list.push_back('b'); +// return list; +// } +// ::std::list l = GetParameterChars(); +// INSTANTIATE_TEST_CASE_P(CharSequence2, +// CharTest, +// ValuesIn(l.begin(), l.end())); +// +template +internal::ParamGenerator< + typename ::std::iterator_traits::value_type> ValuesIn( + ForwardIterator begin, + ForwardIterator end) { + typedef typename ::std::iterator_traits::value_type + ParamType; + return internal::ParamGenerator( + new internal::ValuesInIteratorRangeGenerator(begin, end)); +} + +template +internal::ParamGenerator ValuesIn(const T (&array)[N]) { + return ValuesIn(array, array + N); +} + +template +internal::ParamGenerator ValuesIn( + const Container& container) { + return ValuesIn(container.begin(), container.end()); +} + +// Values() allows generating tests from explicitly specified list of +// parameters. +// +// Synopsis: +// Values(T v1, T v2, ..., T vN) +// - returns a generator producing sequences with elements v1, v2, ..., vN. +// +// For example, this instantiates tests from test case BarTest each +// with values "one", "two", and "three": +// +// INSTANTIATE_TEST_CASE_P(NumSequence, BarTest, Values("one", "two", "three")); +// +// This instantiates tests from test case BazTest each with values 1, 2, 3.5. +// The exact type of values will depend on the type of parameter in BazTest. +// +// INSTANTIATE_TEST_CASE_P(FloatingNumbers, BazTest, Values(1, 2, 3.5)); +// +// Currently, Values() supports from 1 to 50 parameters. +// +template +internal::ValueArray1 Values(T1 v1) { + return internal::ValueArray1(v1); +} + +template +internal::ValueArray2 Values(T1 v1, T2 v2) { + return internal::ValueArray2(v1, v2); +} + +template +internal::ValueArray3 Values(T1 v1, T2 v2, T3 v3) { + return internal::ValueArray3(v1, v2, v3); +} + +template +internal::ValueArray4 Values(T1 v1, T2 v2, T3 v3, T4 v4) { + return internal::ValueArray4(v1, v2, v3, v4); +} + +template +internal::ValueArray5 Values(T1 v1, T2 v2, T3 v3, T4 v4, + T5 v5) { + return internal::ValueArray5(v1, v2, v3, v4, v5); +} + +template +internal::ValueArray6 Values(T1 v1, T2 v2, T3 v3, + T4 v4, T5 v5, T6 v6) { + return internal::ValueArray6(v1, v2, v3, v4, v5, v6); +} + +template +internal::ValueArray7 Values(T1 v1, T2 v2, T3 v3, + T4 v4, T5 v5, T6 v6, T7 v7) { + return internal::ValueArray7(v1, v2, v3, v4, v5, + v6, v7); +} + +template +internal::ValueArray8 Values(T1 v1, T2 v2, + T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8) { + return internal::ValueArray8(v1, v2, v3, v4, + v5, v6, v7, v8); +} + +template +internal::ValueArray9 Values(T1 v1, T2 v2, + T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9) { + return internal::ValueArray9(v1, v2, v3, + v4, v5, v6, v7, v8, v9); +} + +template +internal::ValueArray10 Values(T1 v1, + T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10) { + return internal::ValueArray10(v1, + v2, v3, v4, v5, v6, v7, v8, v9, v10); +} + +template +internal::ValueArray11 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11) { + return internal::ValueArray11(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11); +} + +template +internal::ValueArray12 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12) { + return internal::ValueArray12(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12); +} + +template +internal::ValueArray13 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13) { + return internal::ValueArray13(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13); +} + +template +internal::ValueArray14 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14) { + return internal::ValueArray14(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, + v14); +} + +template +internal::ValueArray15 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, + T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15) { + return internal::ValueArray15(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, + v13, v14, v15); +} + +template +internal::ValueArray16 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, + T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, + T16 v16) { + return internal::ValueArray16(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, + v12, v13, v14, v15, v16); +} + +template +internal::ValueArray17 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, + T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, + T16 v16, T17 v17) { + return internal::ValueArray17(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, + v11, v12, v13, v14, v15, v16, v17); +} + +template +internal::ValueArray18 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, + T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, + T16 v16, T17 v17, T18 v18) { + return internal::ValueArray18(v1, v2, v3, v4, v5, v6, v7, v8, v9, + v10, v11, v12, v13, v14, v15, v16, v17, v18); +} + +template +internal::ValueArray19 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, + T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, + T15 v15, T16 v16, T17 v17, T18 v18, T19 v19) { + return internal::ValueArray19(v1, v2, v3, v4, v5, v6, v7, v8, + v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19); +} + +template +internal::ValueArray20 Values(T1 v1, T2 v2, T3 v3, T4 v4, + T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, + T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20) { + return internal::ValueArray20(v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20); +} + +template +internal::ValueArray21 Values(T1 v1, T2 v2, T3 v3, T4 v4, + T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, + T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21) { + return internal::ValueArray21(v1, v2, v3, v4, v5, v6, + v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21); +} + +template +internal::ValueArray22 Values(T1 v1, T2 v2, T3 v3, + T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, + T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, + T21 v21, T22 v22) { + return internal::ValueArray22(v1, v2, v3, v4, + v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, + v20, v21, v22); +} + +template +internal::ValueArray23 Values(T1 v1, T2 v2, + T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, + T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, + T21 v21, T22 v22, T23 v23) { + return internal::ValueArray23(v1, v2, v3, + v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, + v20, v21, v22, v23); +} + +template +internal::ValueArray24 Values(T1 v1, T2 v2, + T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, + T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, + T21 v21, T22 v22, T23 v23, T24 v24) { + return internal::ValueArray24(v1, v2, + v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, + v19, v20, v21, v22, v23, v24); +} + +template +internal::ValueArray25 Values(T1 v1, + T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, + T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, + T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25) { + return internal::ValueArray25(v1, + v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, + v18, v19, v20, v21, v22, v23, v24, v25); +} + +template +internal::ValueArray26 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26) { + return internal::ValueArray26(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, + v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26); +} + +template +internal::ValueArray27 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27) { + return internal::ValueArray27(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, + v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27); +} + +template +internal::ValueArray28 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28) { + return internal::ValueArray28(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, + v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, + v28); +} + +template +internal::ValueArray29 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29) { + return internal::ValueArray29(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, + v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, + v27, v28, v29); +} + +template +internal::ValueArray30 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, + T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, + T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, + T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30) { + return internal::ValueArray30(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, + v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, + v26, v27, v28, v29, v30); +} + +template +internal::ValueArray31 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, + T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, + T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, + T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31) { + return internal::ValueArray31(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, + v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, + v25, v26, v27, v28, v29, v30, v31); +} + +template +internal::ValueArray32 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, + T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, + T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, + T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, + T32 v32) { + return internal::ValueArray32(v1, v2, v3, v4, v5, v6, v7, v8, v9, + v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, + v24, v25, v26, v27, v28, v29, v30, v31, v32); +} + +template +internal::ValueArray33 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, + T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, + T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, + T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, + T32 v32, T33 v33) { + return internal::ValueArray33(v1, v2, v3, v4, v5, v6, v7, v8, + v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, + v24, v25, v26, v27, v28, v29, v30, v31, v32, v33); +} + +template +internal::ValueArray34 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, + T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, + T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, + T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, + T31 v31, T32 v32, T33 v33, T34 v34) { + return internal::ValueArray34(v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, + v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34); +} + +template +internal::ValueArray35 Values(T1 v1, T2 v2, T3 v3, T4 v4, + T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, + T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, + T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, + T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35) { + return internal::ValueArray35(v1, v2, v3, v4, v5, v6, + v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, + v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35); +} + +template +internal::ValueArray36 Values(T1 v1, T2 v2, T3 v3, T4 v4, + T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, + T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, + T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, + T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36) { + return internal::ValueArray36(v1, v2, v3, v4, + v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, + v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, + v34, v35, v36); +} + +template +internal::ValueArray37 Values(T1 v1, T2 v2, T3 v3, + T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, + T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, + T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, + T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, + T37 v37) { + return internal::ValueArray37(v1, v2, v3, + v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, + v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, + v34, v35, v36, v37); +} + +template +internal::ValueArray38 Values(T1 v1, T2 v2, + T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, + T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, + T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, + T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, + T37 v37, T38 v38) { + return internal::ValueArray38(v1, v2, + v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, + v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, + v33, v34, v35, v36, v37, v38); +} + +template +internal::ValueArray39 Values(T1 v1, T2 v2, + T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, + T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, + T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, + T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, + T37 v37, T38 v38, T39 v39) { + return internal::ValueArray39(v1, + v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, + v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, + v32, v33, v34, v35, v36, v37, v38, v39); +} + +template +internal::ValueArray40 Values(T1 v1, + T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, + T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, + T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, + T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, + T36 v36, T37 v37, T38 v38, T39 v39, T40 v40) { + return internal::ValueArray40(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, + v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, + v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40); +} + +template +internal::ValueArray41 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41) { + return internal::ValueArray41(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, + v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, + v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41); +} + +template +internal::ValueArray42 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42) { + return internal::ValueArray42(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, + v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, + v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, + v42); +} + +template +internal::ValueArray43 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43) { + return internal::ValueArray43(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, + v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, + v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, + v41, v42, v43); +} + +template +internal::ValueArray44 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43, T44 v44) { + return internal::ValueArray44(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, + v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, + v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, + v40, v41, v42, v43, v44); +} + +template +internal::ValueArray45 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, + T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, + T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, + T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, + T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, + T41 v41, T42 v42, T43 v43, T44 v44, T45 v45) { + return internal::ValueArray45(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, + v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, + v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, + v39, v40, v41, v42, v43, v44, v45); +} + +template +internal::ValueArray46 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, + T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, + T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, + T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, + T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, + T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46) { + return internal::ValueArray46(v1, v2, v3, v4, v5, v6, v7, v8, v9, + v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, + v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, + v38, v39, v40, v41, v42, v43, v44, v45, v46); +} + +template +internal::ValueArray47 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, + T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, + T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, + T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, + T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, + T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47) { + return internal::ValueArray47(v1, v2, v3, v4, v5, v6, v7, v8, + v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, + v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, + v38, v39, v40, v41, v42, v43, v44, v45, v46, v47); +} + +template +internal::ValueArray48 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, + T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, + T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, + T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, + T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, + T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, + T48 v48) { + return internal::ValueArray48(v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, + v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, + v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48); +} + +template +internal::ValueArray49 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, + T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, + T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, + T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, + T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, + T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, + T47 v47, T48 v48, T49 v49) { + return internal::ValueArray49(v1, v2, v3, v4, v5, v6, + v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, + v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, + v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49); +} + +template +internal::ValueArray50 Values(T1 v1, T2 v2, T3 v3, T4 v4, + T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, + T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, + T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, + T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, + T38 v38, T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, + T46 v46, T47 v47, T48 v48, T49 v49, T50 v50) { + return internal::ValueArray50(v1, v2, v3, v4, + v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, + v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, + v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, + v48, v49, v50); +} + +// Bool() allows generating tests with parameters in a set of (false, true). +// +// Synopsis: +// Bool() +// - returns a generator producing sequences with elements {false, true}. +// +// It is useful when testing code that depends on Boolean flags. Combinations +// of multiple flags can be tested when several Bool()'s are combined using +// Combine() function. +// +// In the following example all tests in the test case FlagDependentTest +// will be instantiated twice with parameters false and true. +// +// class FlagDependentTest : public testing::TestWithParam { +// virtual void SetUp() { +// external_flag = GetParam(); +// } +// } +// INSTANTIATE_TEST_CASE_P(BoolSequence, FlagDependentTest, Bool()); +// +inline internal::ParamGenerator Bool() { + return Values(false, true); +} + +#if GTEST_HAS_COMBINE +// Combine() allows the user to combine two or more sequences to produce +// values of a Cartesian product of those sequences' elements. +// +// Synopsis: +// Combine(gen1, gen2, ..., genN) +// - returns a generator producing sequences with elements coming from +// the Cartesian product of elements from the sequences generated by +// gen1, gen2, ..., genN. The sequence elements will have a type of +// tuple where T1, T2, ..., TN are the types +// of elements from sequences produces by gen1, gen2, ..., genN. +// +// Combine can have up to 10 arguments. This number is currently limited +// by the maximum number of elements in the tuple implementation used by Google +// Test. +// +// Example: +// +// This will instantiate tests in test case AnimalTest each one with +// the parameter values tuple("cat", BLACK), tuple("cat", WHITE), +// tuple("dog", BLACK), and tuple("dog", WHITE): +// +// enum Color { BLACK, GRAY, WHITE }; +// class AnimalTest +// : public testing::TestWithParam > {...}; +// +// TEST_P(AnimalTest, AnimalLooksNice) {...} +// +// INSTANTIATE_TEST_CASE_P(AnimalVariations, AnimalTest, +// Combine(Values("cat", "dog"), +// Values(BLACK, WHITE))); +// +// This will instantiate tests in FlagDependentTest with all variations of two +// Boolean flags: +// +// class FlagDependentTest +// : public testing::TestWithParam > { +// virtual void SetUp() { +// // Assigns external_flag_1 and external_flag_2 values from the tuple. +// tie(external_flag_1, external_flag_2) = GetParam(); +// } +// }; +// +// TEST_P(FlagDependentTest, TestFeature1) { +// // Test your code using external_flag_1 and external_flag_2 here. +// } +// INSTANTIATE_TEST_CASE_P(TwoBoolSequence, FlagDependentTest, +// Combine(Bool(), Bool())); +// +template +internal::CartesianProductHolder2 Combine( + const Generator1& g1, const Generator2& g2) { + return internal::CartesianProductHolder2( + g1, g2); +} + +template +internal::CartesianProductHolder3 Combine( + const Generator1& g1, const Generator2& g2, const Generator3& g3) { + return internal::CartesianProductHolder3( + g1, g2, g3); +} + +template +internal::CartesianProductHolder4 Combine( + const Generator1& g1, const Generator2& g2, const Generator3& g3, + const Generator4& g4) { + return internal::CartesianProductHolder4( + g1, g2, g3, g4); +} + +template +internal::CartesianProductHolder5 Combine( + const Generator1& g1, const Generator2& g2, const Generator3& g3, + const Generator4& g4, const Generator5& g5) { + return internal::CartesianProductHolder5( + g1, g2, g3, g4, g5); +} + +template +internal::CartesianProductHolder6 Combine( + const Generator1& g1, const Generator2& g2, const Generator3& g3, + const Generator4& g4, const Generator5& g5, const Generator6& g6) { + return internal::CartesianProductHolder6( + g1, g2, g3, g4, g5, g6); +} + +template +internal::CartesianProductHolder7 Combine( + const Generator1& g1, const Generator2& g2, const Generator3& g3, + const Generator4& g4, const Generator5& g5, const Generator6& g6, + const Generator7& g7) { + return internal::CartesianProductHolder7( + g1, g2, g3, g4, g5, g6, g7); +} + +template +internal::CartesianProductHolder8 Combine( + const Generator1& g1, const Generator2& g2, const Generator3& g3, + const Generator4& g4, const Generator5& g5, const Generator6& g6, + const Generator7& g7, const Generator8& g8) { + return internal::CartesianProductHolder8( + g1, g2, g3, g4, g5, g6, g7, g8); +} + +template +internal::CartesianProductHolder9 Combine( + const Generator1& g1, const Generator2& g2, const Generator3& g3, + const Generator4& g4, const Generator5& g5, const Generator6& g6, + const Generator7& g7, const Generator8& g8, const Generator9& g9) { + return internal::CartesianProductHolder9( + g1, g2, g3, g4, g5, g6, g7, g8, g9); +} + +template +internal::CartesianProductHolder10 Combine( + const Generator1& g1, const Generator2& g2, const Generator3& g3, + const Generator4& g4, const Generator5& g5, const Generator6& g6, + const Generator7& g7, const Generator8& g8, const Generator9& g9, + const Generator10& g10) { + return internal::CartesianProductHolder10( + g1, g2, g3, g4, g5, g6, g7, g8, g9, g10); +} +#endif // GTEST_HAS_COMBINE + + + +#define TEST_P(test_case_name, test_name) \ + class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) \ + : public test_case_name { \ + public: \ + GTEST_TEST_CLASS_NAME_(test_case_name, test_name)() {} \ + virtual void TestBody(); \ + private: \ + static int AddToRegistry() { \ + ::testing::UnitTest::GetInstance()->parameterized_test_registry(). \ + GetTestCasePatternHolder(\ + #test_case_name, __FILE__, __LINE__)->AddTestPattern(\ + #test_case_name, \ + #test_name, \ + new ::testing::internal::TestMetaFactory< \ + GTEST_TEST_CLASS_NAME_(test_case_name, test_name)>()); \ + return 0; \ + } \ + static int gtest_registering_dummy_; \ + GTEST_DISALLOW_COPY_AND_ASSIGN_(\ + GTEST_TEST_CLASS_NAME_(test_case_name, test_name)); \ + }; \ + int GTEST_TEST_CLASS_NAME_(test_case_name, \ + test_name)::gtest_registering_dummy_ = \ + GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::AddToRegistry(); \ + void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody() + +#define INSTANTIATE_TEST_CASE_P(prefix, test_case_name, generator) \ + ::testing::internal::ParamGenerator \ + gtest_##prefix##test_case_name##_EvalGenerator_() { return generator; } \ + int gtest_##prefix##test_case_name##_dummy_ = \ + ::testing::UnitTest::GetInstance()->parameterized_test_registry(). \ + GetTestCasePatternHolder(\ + #test_case_name, __FILE__, __LINE__)->AddTestCaseInstantiation(\ + #prefix, \ + >est_##prefix##test_case_name##_EvalGenerator_, \ + __FILE__, __LINE__) + +} // namespace testing + +#endif // GTEST_HAS_PARAM_TEST + +#endif // GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_ +// Copyright 2006, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: wan@google.com (Zhanyong Wan) +// +// Google C++ Testing Framework definitions useful in production code. + +#ifndef GTEST_INCLUDE_GTEST_GTEST_PROD_H_ +#define GTEST_INCLUDE_GTEST_GTEST_PROD_H_ + +// When you need to test the private or protected members of a class, +// use the FRIEND_TEST macro to declare your tests as friends of the +// class. For example: +// +// class MyClass { +// private: +// void MyMethod(); +// FRIEND_TEST(MyClassTest, MyMethod); +// }; +// +// class MyClassTest : public testing::Test { +// // ... +// }; +// +// TEST_F(MyClassTest, MyMethod) { +// // Can call MyClass::MyMethod() here. +// } + +#define FRIEND_TEST(test_case_name, test_name)\ +friend class test_case_name##_##test_name##_Test + +#endif // GTEST_INCLUDE_GTEST_GTEST_PROD_H_ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: mheule@google.com (Markus Heule) +// + +#ifndef GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_ +#define GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_ + +#include +#include + +namespace testing { + +// A copyable object representing the result of a test part (i.e. an +// assertion or an explicit FAIL(), ADD_FAILURE(), or SUCCESS()). +// +// Don't inherit from TestPartResult as its destructor is not virtual. +class GTEST_API_ TestPartResult { + public: + // The possible outcomes of a test part (i.e. an assertion or an + // explicit SUCCEED(), FAIL(), or ADD_FAILURE()). + enum Type { + kSuccess, // Succeeded. + kNonFatalFailure, // Failed but the test can continue. + kFatalFailure // Failed and the test should be terminated. + }; + + // C'tor. TestPartResult does NOT have a default constructor. + // Always use this constructor (with parameters) to create a + // TestPartResult object. + TestPartResult(Type a_type, + const char* a_file_name, + int a_line_number, + const char* a_message) + : type_(a_type), + file_name_(a_file_name), + line_number_(a_line_number), + summary_(ExtractSummary(a_message)), + message_(a_message) { + } + + // Gets the outcome of the test part. + Type type() const { return type_; } + + // Gets the name of the source file where the test part took place, or + // NULL if it's unknown. + const char* file_name() const { return file_name_.c_str(); } + + // Gets the line in the source file where the test part took place, + // or -1 if it's unknown. + int line_number() const { return line_number_; } + + // Gets the summary of the failure message. + const char* summary() const { return summary_.c_str(); } + + // Gets the message associated with the test part. + const char* message() const { return message_.c_str(); } + + // Returns true iff the test part passed. + bool passed() const { return type_ == kSuccess; } + + // Returns true iff the test part failed. + bool failed() const { return type_ != kSuccess; } + + // Returns true iff the test part non-fatally failed. + bool nonfatally_failed() const { return type_ == kNonFatalFailure; } + + // Returns true iff the test part fatally failed. + bool fatally_failed() const { return type_ == kFatalFailure; } + private: + Type type_; + + // Gets the summary of the failure message by omitting the stack + // trace in it. + static internal::String ExtractSummary(const char* message); + + // The name of the source file where the test part took place, or + // NULL if the source file is unknown. + internal::String file_name_; + // The line in the source file where the test part took place, or -1 + // if the line number is unknown. + int line_number_; + internal::String summary_; // The test failure summary. + internal::String message_; // The test failure message. +}; + +// Prints a TestPartResult object. +std::ostream& operator<<(std::ostream& os, const TestPartResult& result); + +// An array of TestPartResult objects. +// +// Don't inherit from TestPartResultArray as its destructor is not +// virtual. +class GTEST_API_ TestPartResultArray { + public: + TestPartResultArray() {} + + // Appends the given TestPartResult to the array. + void Append(const TestPartResult& result); + + // Returns the TestPartResult at the given index (0-based). + const TestPartResult& GetTestPartResult(int index) const; + + // Returns the number of TestPartResult objects in the array. + int size() const; + + private: + std::vector array_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestPartResultArray); +}; + +// This interface knows how to report a test part result. +class TestPartResultReporterInterface { + public: + virtual ~TestPartResultReporterInterface() {} + + virtual void ReportTestPartResult(const TestPartResult& result) = 0; +}; + +namespace internal { + +// This helper class is used by {ASSERT|EXPECT}_NO_FATAL_FAILURE to check if a +// statement generates new fatal failures. To do so it registers itself as the +// current test part result reporter. Besides checking if fatal failures were +// reported, it only delegates the reporting to the former result reporter. +// The original result reporter is restored in the destructor. +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +class GTEST_API_ HasNewFatalFailureHelper + : public TestPartResultReporterInterface { + public: + HasNewFatalFailureHelper(); + virtual ~HasNewFatalFailureHelper(); + virtual void ReportTestPartResult(const TestPartResult& result); + bool has_new_fatal_failure() const { return has_new_fatal_failure_; } + private: + bool has_new_fatal_failure_; + TestPartResultReporterInterface* original_reporter_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(HasNewFatalFailureHelper); +}; + +} // namespace internal + +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_ +// Copyright 2008 Google Inc. +// All Rights Reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: wan@google.com (Zhanyong Wan) + +#ifndef GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_ +#define GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_ + +// This header implements typed tests and type-parameterized tests. + +// Typed (aka type-driven) tests repeat the same test for types in a +// list. You must know which types you want to test with when writing +// typed tests. Here's how you do it: + +#if 0 + +// First, define a fixture class template. It should be parameterized +// by a type. Remember to derive it from testing::Test. +template +class FooTest : public testing::Test { + public: + ... + typedef std::list List; + static T shared_; + T value_; +}; + +// Next, associate a list of types with the test case, which will be +// repeated for each type in the list. The typedef is necessary for +// the macro to parse correctly. +typedef testing::Types MyTypes; +TYPED_TEST_CASE(FooTest, MyTypes); + +// If the type list contains only one type, you can write that type +// directly without Types<...>: +// TYPED_TEST_CASE(FooTest, int); + +// Then, use TYPED_TEST() instead of TEST_F() to define as many typed +// tests for this test case as you want. +TYPED_TEST(FooTest, DoesBlah) { + // Inside a test, refer to TypeParam to get the type parameter. + // Since we are inside a derived class template, C++ requires use to + // visit the members of FooTest via 'this'. + TypeParam n = this->value_; + + // To visit static members of the fixture, add the TestFixture:: + // prefix. + n += TestFixture::shared_; + + // To refer to typedefs in the fixture, add the "typename + // TestFixture::" prefix. + typename TestFixture::List values; + values.push_back(n); + ... +} + +TYPED_TEST(FooTest, HasPropertyA) { ... } + +#endif // 0 + +// Type-parameterized tests are abstract test patterns parameterized +// by a type. Compared with typed tests, type-parameterized tests +// allow you to define the test pattern without knowing what the type +// parameters are. The defined pattern can be instantiated with +// different types any number of times, in any number of translation +// units. +// +// If you are designing an interface or concept, you can define a +// suite of type-parameterized tests to verify properties that any +// valid implementation of the interface/concept should have. Then, +// each implementation can easily instantiate the test suite to verify +// that it conforms to the requirements, without having to write +// similar tests repeatedly. Here's an example: + +#if 0 + +// First, define a fixture class template. It should be parameterized +// by a type. Remember to derive it from testing::Test. +template +class FooTest : public testing::Test { + ... +}; + +// Next, declare that you will define a type-parameterized test case +// (the _P suffix is for "parameterized" or "pattern", whichever you +// prefer): +TYPED_TEST_CASE_P(FooTest); + +// Then, use TYPED_TEST_P() to define as many type-parameterized tests +// for this type-parameterized test case as you want. +TYPED_TEST_P(FooTest, DoesBlah) { + // Inside a test, refer to TypeParam to get the type parameter. + TypeParam n = 0; + ... +} + +TYPED_TEST_P(FooTest, HasPropertyA) { ... } + +// Now the tricky part: you need to register all test patterns before +// you can instantiate them. The first argument of the macro is the +// test case name; the rest are the names of the tests in this test +// case. +REGISTER_TYPED_TEST_CASE_P(FooTest, + DoesBlah, HasPropertyA); + +// Finally, you are free to instantiate the pattern with the types you +// want. If you put the above code in a header file, you can #include +// it in multiple C++ source files and instantiate it multiple times. +// +// To distinguish different instances of the pattern, the first +// argument to the INSTANTIATE_* macro is a prefix that will be added +// to the actual test case name. Remember to pick unique prefixes for +// different instances. +typedef testing::Types MyTypes; +INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, MyTypes); + +// If the type list contains only one type, you can write that type +// directly without Types<...>: +// INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, int); + +#endif // 0 + + +// Implements typed tests. + +#if GTEST_HAS_TYPED_TEST + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// Expands to the name of the typedef for the type parameters of the +// given test case. +#define GTEST_TYPE_PARAMS_(TestCaseName) gtest_type_params_##TestCaseName##_ + +// The 'Types' template argument below must have spaces around it +// since some compilers may choke on '>>' when passing a template +// instance (e.g. Types) +#define TYPED_TEST_CASE(CaseName, Types) \ + typedef ::testing::internal::TypeList< Types >::type \ + GTEST_TYPE_PARAMS_(CaseName) + +#define TYPED_TEST(CaseName, TestName) \ + template \ + class GTEST_TEST_CLASS_NAME_(CaseName, TestName) \ + : public CaseName { \ + private: \ + typedef CaseName TestFixture; \ + typedef gtest_TypeParam_ TypeParam; \ + virtual void TestBody(); \ + }; \ + bool gtest_##CaseName##_##TestName##_registered_ = \ + ::testing::internal::TypeParameterizedTest< \ + CaseName, \ + ::testing::internal::TemplateSel< \ + GTEST_TEST_CLASS_NAME_(CaseName, TestName)>, \ + GTEST_TYPE_PARAMS_(CaseName)>::Register(\ + "", #CaseName, #TestName, 0); \ + template \ + void GTEST_TEST_CLASS_NAME_(CaseName, TestName)::TestBody() + +#endif // GTEST_HAS_TYPED_TEST + +// Implements type-parameterized tests. + +#if GTEST_HAS_TYPED_TEST_P + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// Expands to the namespace name that the type-parameterized tests for +// the given type-parameterized test case are defined in. The exact +// name of the namespace is subject to change without notice. +#define GTEST_CASE_NAMESPACE_(TestCaseName) \ + gtest_case_##TestCaseName##_ + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// Expands to the name of the variable used to remember the names of +// the defined tests in the given test case. +#define GTEST_TYPED_TEST_CASE_P_STATE_(TestCaseName) \ + gtest_typed_test_case_p_state_##TestCaseName##_ + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE DIRECTLY. +// +// Expands to the name of the variable used to remember the names of +// the registered tests in the given test case. +#define GTEST_REGISTERED_TEST_NAMES_(TestCaseName) \ + gtest_registered_test_names_##TestCaseName##_ + +// The variables defined in the type-parameterized test macros are +// static as typically these macros are used in a .h file that can be +// #included in multiple translation units linked together. +#define TYPED_TEST_CASE_P(CaseName) \ + static ::testing::internal::TypedTestCasePState \ + GTEST_TYPED_TEST_CASE_P_STATE_(CaseName) + +#define TYPED_TEST_P(CaseName, TestName) \ + namespace GTEST_CASE_NAMESPACE_(CaseName) { \ + template \ + class TestName : public CaseName { \ + private: \ + typedef CaseName TestFixture; \ + typedef gtest_TypeParam_ TypeParam; \ + virtual void TestBody(); \ + }; \ + static bool gtest_##TestName##_defined_ = \ + GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).AddTestName(\ + __FILE__, __LINE__, #CaseName, #TestName); \ + } \ + template \ + void GTEST_CASE_NAMESPACE_(CaseName)::TestName::TestBody() + +#define REGISTER_TYPED_TEST_CASE_P(CaseName, ...) \ + namespace GTEST_CASE_NAMESPACE_(CaseName) { \ + typedef ::testing::internal::Templates<__VA_ARGS__>::type gtest_AllTests_; \ + } \ + static const char* const GTEST_REGISTERED_TEST_NAMES_(CaseName) = \ + GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).VerifyRegisteredTestNames(\ + __FILE__, __LINE__, #__VA_ARGS__) + +// The 'Types' template argument below must have spaces around it +// since some compilers may choke on '>>' when passing a template +// instance (e.g. Types) +#define INSTANTIATE_TYPED_TEST_CASE_P(Prefix, CaseName, Types) \ + bool gtest_##Prefix##_##CaseName = \ + ::testing::internal::TypeParameterizedTestCase::type>::Register(\ + #Prefix, #CaseName, GTEST_REGISTERED_TEST_NAMES_(CaseName)) + +#endif // GTEST_HAS_TYPED_TEST_P + +#endif // GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_ + +// Depending on the platform, different string classes are available. +// On Linux, in addition to ::std::string, Google also makes use of +// class ::string, which has the same interface as ::std::string, but +// has a different implementation. +// +// The user can define GTEST_HAS_GLOBAL_STRING to 1 to indicate that +// ::string is available AND is a distinct type to ::std::string, or +// define it to 0 to indicate otherwise. +// +// If the user's ::std::string and ::string are the same class due to +// aliasing, he should define GTEST_HAS_GLOBAL_STRING to 0. +// +// If the user doesn't define GTEST_HAS_GLOBAL_STRING, it is defined +// heuristically. + +namespace testing { + +// Declares the flags. + +// This flag temporary enables the disabled tests. +GTEST_DECLARE_bool_(also_run_disabled_tests); + +// This flag brings the debugger on an assertion failure. +GTEST_DECLARE_bool_(break_on_failure); + +// This flag controls whether Google Test catches all test-thrown exceptions +// and logs them as failures. +GTEST_DECLARE_bool_(catch_exceptions); + +// This flag enables using colors in terminal output. Available values are +// "yes" to enable colors, "no" (disable colors), or "auto" (the default) +// to let Google Test decide. +GTEST_DECLARE_string_(color); + +// This flag sets up the filter to select by name using a glob pattern +// the tests to run. If the filter is not given all tests are executed. +GTEST_DECLARE_string_(filter); + +// This flag causes the Google Test to list tests. None of the tests listed +// are actually run if the flag is provided. +GTEST_DECLARE_bool_(list_tests); + +// This flag controls whether Google Test emits a detailed XML report to a file +// in addition to its normal textual output. +GTEST_DECLARE_string_(output); + +// This flags control whether Google Test prints the elapsed time for each +// test. +GTEST_DECLARE_bool_(print_time); + +// This flag specifies the random number seed. +GTEST_DECLARE_int32_(random_seed); + +// This flag sets how many times the tests are repeated. The default value +// is 1. If the value is -1 the tests are repeating forever. +GTEST_DECLARE_int32_(repeat); + +// This flag controls whether Google Test includes Google Test internal +// stack frames in failure stack traces. +GTEST_DECLARE_bool_(show_internal_stack_frames); + +// When this flag is specified, tests' order is randomized on every iteration. +GTEST_DECLARE_bool_(shuffle); + +// This flag specifies the maximum number of stack frames to be +// printed in a failure message. +GTEST_DECLARE_int32_(stack_trace_depth); + +// When this flag is specified, a failed assertion will throw an +// exception if exceptions are enabled, or exit the program with a +// non-zero code otherwise. +GTEST_DECLARE_bool_(throw_on_failure); + +// The upper limit for valid stack trace depths. +const int kMaxStackTraceDepth = 100; + +namespace internal { + +class AssertHelper; +class DefaultGlobalTestPartResultReporter; +class ExecDeathTest; +class NoExecDeathTest; +class FinalSuccessChecker; +class GTestFlagSaver; +class TestInfoImpl; +class TestResultAccessor; +class TestEventListenersAccessor; +class TestEventRepeater; +class WindowsDeathTest; +class UnitTestImpl* GetUnitTestImpl(); +void ReportFailureInUnknownLocation(TestPartResult::Type result_type, + const String& message); +class PrettyUnitTestResultPrinter; +class XmlUnitTestResultPrinter; + +// Converts a streamable value to a String. A NULL pointer is +// converted to "(null)". When the input value is a ::string, +// ::std::string, ::wstring, or ::std::wstring object, each NUL +// character in it is replaced with "\\0". +// Declared in gtest-internal.h but defined here, so that it has access +// to the definition of the Message class, required by the ARM +// compiler. +template +String StreamableToString(const T& streamable) { + return (Message() << streamable).GetString(); +} + +} // namespace internal + +// A class for indicating whether an assertion was successful. When +// the assertion wasn't successful, the AssertionResult object +// remembers a non-empty message that describes how it failed. +// +// To create an instance of this class, use one of the factory functions +// (AssertionSuccess() and AssertionFailure()). +// +// This class is useful for two purposes: +// 1. Defining predicate functions to be used with Boolean test assertions +// EXPECT_TRUE/EXPECT_FALSE and their ASSERT_ counterparts +// 2. Defining predicate-format functions to be +// used with predicate assertions (ASSERT_PRED_FORMAT*, etc). +// +// For example, if you define IsEven predicate: +// +// testing::AssertionResult IsEven(int n) { +// if ((n % 2) == 0) +// return testing::AssertionSuccess(); +// else +// return testing::AssertionFailure() << n << " is odd"; +// } +// +// Then the failed expectation EXPECT_TRUE(IsEven(Fib(5))) +// will print the message +// +// Value of: IsEven(Fib(5)) +// Actual: false (5 is odd) +// Expected: true +// +// instead of a more opaque +// +// Value of: IsEven(Fib(5)) +// Actual: false +// Expected: true +// +// in case IsEven is a simple Boolean predicate. +// +// If you expect your predicate to be reused and want to support informative +// messages in EXPECT_FALSE and ASSERT_FALSE (negative assertions show up +// about half as often as positive ones in our tests), supply messages for +// both success and failure cases: +// +// testing::AssertionResult IsEven(int n) { +// if ((n % 2) == 0) +// return testing::AssertionSuccess() << n << " is even"; +// else +// return testing::AssertionFailure() << n << " is odd"; +// } +// +// Then a statement EXPECT_FALSE(IsEven(Fib(6))) will print +// +// Value of: IsEven(Fib(6)) +// Actual: true (8 is even) +// Expected: false +// +// NB: Predicates that support negative Boolean assertions have reduced +// performance in positive ones so be careful not to use them in tests +// that have lots (tens of thousands) of positive Boolean assertions. +// +// To use this class with EXPECT_PRED_FORMAT assertions such as: +// +// // Verifies that Foo() returns an even number. +// EXPECT_PRED_FORMAT1(IsEven, Foo()); +// +// you need to define: +// +// testing::AssertionResult IsEven(const char* expr, int n) { +// if ((n % 2) == 0) +// return testing::AssertionSuccess(); +// else +// return testing::AssertionFailure() +// << "Expected: " << expr << " is even\n Actual: it's " << n; +// } +// +// If Foo() returns 5, you will see the following message: +// +// Expected: Foo() is even +// Actual: it's 5 +// +class GTEST_API_ AssertionResult { + public: + // Copy constructor. + // Used in EXPECT_TRUE/FALSE(assertion_result). + AssertionResult(const AssertionResult& other); + // Used in the EXPECT_TRUE/FALSE(bool_expression). + explicit AssertionResult(bool success) : success_(success) {} + + // Returns true iff the assertion succeeded. + operator bool() const { return success_; } // NOLINT + + // Returns the assertion's negation. Used with EXPECT/ASSERT_FALSE. + AssertionResult operator!() const; + + // Returns the text streamed into this AssertionResult. Test assertions + // use it when they fail (i.e., the predicate's outcome doesn't match the + // assertion's expectation). When nothing has been streamed into the + // object, returns an empty string. + const char* message() const { + return message_.get() != NULL && message_->c_str() != NULL ? + message_->c_str() : ""; + } + // TODO(vladl@google.com): Remove this after making sure no clients use it. + // Deprecated; please use message() instead. + const char* failure_message() const { return message(); } + + // Streams a custom failure message into this object. + template AssertionResult& operator<<(const T& value); + + private: + // No implementation - we want AssertionResult to be + // copy-constructible but not assignable. + void operator=(const AssertionResult& other); + + // Stores result of the assertion predicate. + bool success_; + // Stores the message describing the condition in case the expectation + // construct is not satisfied with the predicate's outcome. + // Referenced via a pointer to avoid taking too much stack frame space + // with test assertions. + internal::scoped_ptr message_; +}; // class AssertionResult + +// Streams a custom failure message into this object. +template +AssertionResult& AssertionResult::operator<<(const T& value) { + Message msg; + if (message_.get() != NULL) + msg << *message_; + msg << value; + message_.reset(new internal::String(msg.GetString())); + return *this; +} + +// Makes a successful assertion result. +GTEST_API_ AssertionResult AssertionSuccess(); + +// Makes a failed assertion result. +GTEST_API_ AssertionResult AssertionFailure(); + +// Makes a failed assertion result with the given failure message. +// Deprecated; use AssertionFailure() << msg. +GTEST_API_ AssertionResult AssertionFailure(const Message& msg); + +// The abstract class that all tests inherit from. +// +// In Google Test, a unit test program contains one or many TestCases, and +// each TestCase contains one or many Tests. +// +// When you define a test using the TEST macro, you don't need to +// explicitly derive from Test - the TEST macro automatically does +// this for you. +// +// The only time you derive from Test is when defining a test fixture +// to be used a TEST_F. For example: +// +// class FooTest : public testing::Test { +// protected: +// virtual void SetUp() { ... } +// virtual void TearDown() { ... } +// ... +// }; +// +// TEST_F(FooTest, Bar) { ... } +// TEST_F(FooTest, Baz) { ... } +// +// Test is not copyable. +class GTEST_API_ Test { + public: + friend class internal::TestInfoImpl; + + // Defines types for pointers to functions that set up and tear down + // a test case. + typedef internal::SetUpTestCaseFunc SetUpTestCaseFunc; + typedef internal::TearDownTestCaseFunc TearDownTestCaseFunc; + + // The d'tor is virtual as we intend to inherit from Test. + virtual ~Test(); + + // Sets up the stuff shared by all tests in this test case. + // + // Google Test will call Foo::SetUpTestCase() before running the first + // test in test case Foo. Hence a sub-class can define its own + // SetUpTestCase() method to shadow the one defined in the super + // class. + static void SetUpTestCase() {} + + // Tears down the stuff shared by all tests in this test case. + // + // Google Test will call Foo::TearDownTestCase() after running the last + // test in test case Foo. Hence a sub-class can define its own + // TearDownTestCase() method to shadow the one defined in the super + // class. + static void TearDownTestCase() {} + + // Returns true iff the current test has a fatal failure. + static bool HasFatalFailure(); + + // Returns true iff the current test has a non-fatal failure. + static bool HasNonfatalFailure(); + + // Returns true iff the current test has a (either fatal or + // non-fatal) failure. + static bool HasFailure() { return HasFatalFailure() || HasNonfatalFailure(); } + + // Logs a property for the current test. Only the last value for a given + // key is remembered. + // These are public static so they can be called from utility functions + // that are not members of the test fixture. + // The arguments are const char* instead strings, as Google Test is used + // on platforms where string doesn't compile. + // + // Note that a driving consideration for these RecordProperty methods + // was to produce xml output suited to the Greenspan charting utility, + // which at present will only chart values that fit in a 32-bit int. It + // is the user's responsibility to restrict their values to 32-bit ints + // if they intend them to be used with Greenspan. + static void RecordProperty(const char* key, const char* value); + static void RecordProperty(const char* key, int value); + + protected: + // Creates a Test object. + Test(); + + // Sets up the test fixture. + virtual void SetUp(); + + // Tears down the test fixture. + virtual void TearDown(); + + private: + // Returns true iff the current test has the same fixture class as + // the first test in the current test case. + static bool HasSameFixtureClass(); + + // Runs the test after the test fixture has been set up. + // + // A sub-class must implement this to define the test logic. + // + // DO NOT OVERRIDE THIS FUNCTION DIRECTLY IN A USER PROGRAM. + // Instead, use the TEST or TEST_F macro. + virtual void TestBody() = 0; + + // Sets up, executes, and tears down the test. + void Run(); + + // Uses a GTestFlagSaver to save and restore all Google Test flags. + const internal::GTestFlagSaver* const gtest_flag_saver_; + + // Often a user mis-spells SetUp() as Setup() and spends a long time + // wondering why it is never called by Google Test. The declaration of + // the following method is solely for catching such an error at + // compile time: + // + // - The return type is deliberately chosen to be not void, so it + // will be a conflict if a user declares void Setup() in his test + // fixture. + // + // - This method is private, so it will be another compiler error + // if a user calls it from his test fixture. + // + // DO NOT OVERRIDE THIS FUNCTION. + // + // If you see an error about overriding the following function or + // about it being private, you have mis-spelled SetUp() as Setup(). + struct Setup_should_be_spelled_SetUp {}; + virtual Setup_should_be_spelled_SetUp* Setup() { return NULL; } + + // We disallow copying Tests. + GTEST_DISALLOW_COPY_AND_ASSIGN_(Test); +}; + +typedef internal::TimeInMillis TimeInMillis; + +// A copyable object representing a user specified test property which can be +// output as a key/value string pair. +// +// Don't inherit from TestProperty as its destructor is not virtual. +class TestProperty { + public: + // C'tor. TestProperty does NOT have a default constructor. + // Always use this constructor (with parameters) to create a + // TestProperty object. + TestProperty(const char* a_key, const char* a_value) : + key_(a_key), value_(a_value) { + } + + // Gets the user supplied key. + const char* key() const { + return key_.c_str(); + } + + // Gets the user supplied value. + const char* value() const { + return value_.c_str(); + } + + // Sets a new value, overriding the one supplied in the constructor. + void SetValue(const char* new_value) { + value_ = new_value; + } + + private: + // The key supplied by the user. + internal::String key_; + // The value supplied by the user. + internal::String value_; +}; + +// The result of a single Test. This includes a list of +// TestPartResults, a list of TestProperties, a count of how many +// death tests there are in the Test, and how much time it took to run +// the Test. +// +// TestResult is not copyable. +class GTEST_API_ TestResult { + public: + // Creates an empty TestResult. + TestResult(); + + // D'tor. Do not inherit from TestResult. + ~TestResult(); + + // Gets the number of all test parts. This is the sum of the number + // of successful test parts and the number of failed test parts. + int total_part_count() const; + + // Returns the number of the test properties. + int test_property_count() const; + + // Returns true iff the test passed (i.e. no test part failed). + bool Passed() const { return !Failed(); } + + // Returns true iff the test failed. + bool Failed() const; + + // Returns true iff the test fatally failed. + bool HasFatalFailure() const; + + // Returns true iff the test has a non-fatal failure. + bool HasNonfatalFailure() const; + + // Returns the elapsed time, in milliseconds. + TimeInMillis elapsed_time() const { return elapsed_time_; } + + // Returns the i-th test part result among all the results. i can range + // from 0 to test_property_count() - 1. If i is not in that range, aborts + // the program. + const TestPartResult& GetTestPartResult(int i) const; + + // Returns the i-th test property. i can range from 0 to + // test_property_count() - 1. If i is not in that range, aborts the + // program. + const TestProperty& GetTestProperty(int i) const; + + private: + friend class TestInfo; + friend class UnitTest; + friend class internal::DefaultGlobalTestPartResultReporter; + friend class internal::ExecDeathTest; + friend class internal::TestInfoImpl; + friend class internal::TestResultAccessor; + friend class internal::UnitTestImpl; + friend class internal::WindowsDeathTest; + + // Gets the vector of TestPartResults. + const std::vector& test_part_results() const { + return test_part_results_; + } + + // Gets the vector of TestProperties. + const std::vector& test_properties() const { + return test_properties_; + } + + // Sets the elapsed time. + void set_elapsed_time(TimeInMillis elapsed) { elapsed_time_ = elapsed; } + + // Adds a test property to the list. The property is validated and may add + // a non-fatal failure if invalid (e.g., if it conflicts with reserved + // key names). If a property is already recorded for the same key, the + // value will be updated, rather than storing multiple values for the same + // key. + void RecordProperty(const TestProperty& test_property); + + // Adds a failure if the key is a reserved attribute of Google Test + // testcase tags. Returns true if the property is valid. + // TODO(russr): Validate attribute names are legal and human readable. + static bool ValidateTestProperty(const TestProperty& test_property); + + // Adds a test part result to the list. + void AddTestPartResult(const TestPartResult& test_part_result); + + // Returns the death test count. + int death_test_count() const { return death_test_count_; } + + // Increments the death test count, returning the new count. + int increment_death_test_count() { return ++death_test_count_; } + + // Clears the test part results. + void ClearTestPartResults(); + + // Clears the object. + void Clear(); + + // Protects mutable state of the property vector and of owned + // properties, whose values may be updated. + internal::Mutex test_properites_mutex_; + + // The vector of TestPartResults + std::vector test_part_results_; + // The vector of TestProperties + std::vector test_properties_; + // Running count of death tests. + int death_test_count_; + // The elapsed time, in milliseconds. + TimeInMillis elapsed_time_; + + // We disallow copying TestResult. + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestResult); +}; // class TestResult + +// A TestInfo object stores the following information about a test: +// +// Test case name +// Test name +// Whether the test should be run +// A function pointer that creates the test object when invoked +// Test result +// +// The constructor of TestInfo registers itself with the UnitTest +// singleton such that the RUN_ALL_TESTS() macro knows which tests to +// run. +class GTEST_API_ TestInfo { + public: + // Destructs a TestInfo object. This function is not virtual, so + // don't inherit from TestInfo. + ~TestInfo(); + + // Returns the test case name. + const char* test_case_name() const; + + // Returns the test name. + const char* name() const; + + // Returns the test case comment. + const char* test_case_comment() const; + + // Returns the test comment. + const char* comment() const; + + // Returns true if this test should run, that is if the test is not disabled + // (or it is disabled but the also_run_disabled_tests flag has been specified) + // and its full name matches the user-specified filter. + // + // Google Test allows the user to filter the tests by their full names. + // The full name of a test Bar in test case Foo is defined as + // "Foo.Bar". Only the tests that match the filter will run. + // + // A filter is a colon-separated list of glob (not regex) patterns, + // optionally followed by a '-' and a colon-separated list of + // negative patterns (tests to exclude). A test is run if it + // matches one of the positive patterns and does not match any of + // the negative patterns. + // + // For example, *A*:Foo.* is a filter that matches any string that + // contains the character 'A' or starts with "Foo.". + bool should_run() const; + + // Returns the result of the test. + const TestResult* result() const; + + private: +#if GTEST_HAS_DEATH_TEST + friend class internal::DefaultDeathTestFactory; +#endif // GTEST_HAS_DEATH_TEST + friend class Test; + friend class TestCase; + friend class internal::TestInfoImpl; + friend class internal::UnitTestImpl; + friend TestInfo* internal::MakeAndRegisterTestInfo( + const char* test_case_name, const char* name, + const char* test_case_comment, const char* comment, + internal::TypeId fixture_class_id, + Test::SetUpTestCaseFunc set_up_tc, + Test::TearDownTestCaseFunc tear_down_tc, + internal::TestFactoryBase* factory); + + // Returns true if this test matches the user-specified filter. + bool matches_filter() const; + + // Increments the number of death tests encountered in this test so + // far. + int increment_death_test_count(); + + // Accessors for the implementation object. + internal::TestInfoImpl* impl() { return impl_; } + const internal::TestInfoImpl* impl() const { return impl_; } + + // Constructs a TestInfo object. The newly constructed instance assumes + // ownership of the factory object. + TestInfo(const char* test_case_name, const char* name, + const char* test_case_comment, const char* comment, + internal::TypeId fixture_class_id, + internal::TestFactoryBase* factory); + + // An opaque implementation object. + internal::TestInfoImpl* impl_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestInfo); +}; + +// A test case, which consists of a vector of TestInfos. +// +// TestCase is not copyable. +class GTEST_API_ TestCase { + public: + // Creates a TestCase with the given name. + // + // TestCase does NOT have a default constructor. Always use this + // constructor to create a TestCase object. + // + // Arguments: + // + // name: name of the test case + // set_up_tc: pointer to the function that sets up the test case + // tear_down_tc: pointer to the function that tears down the test case + TestCase(const char* name, const char* comment, + Test::SetUpTestCaseFunc set_up_tc, + Test::TearDownTestCaseFunc tear_down_tc); + + // Destructor of TestCase. + virtual ~TestCase(); + + // Gets the name of the TestCase. + const char* name() const { return name_.c_str(); } + + // Returns the test case comment. + const char* comment() const { return comment_.c_str(); } + + // Returns true if any test in this test case should run. + bool should_run() const { return should_run_; } + + // Gets the number of successful tests in this test case. + int successful_test_count() const; + + // Gets the number of failed tests in this test case. + int failed_test_count() const; + + // Gets the number of disabled tests in this test case. + int disabled_test_count() const; + + // Get the number of tests in this test case that should run. + int test_to_run_count() const; + + // Gets the number of all tests in this test case. + int total_test_count() const; + + // Returns true iff the test case passed. + bool Passed() const { return !Failed(); } + + // Returns true iff the test case failed. + bool Failed() const { return failed_test_count() > 0; } + + // Returns the elapsed time, in milliseconds. + TimeInMillis elapsed_time() const { return elapsed_time_; } + + // Returns the i-th test among all the tests. i can range from 0 to + // total_test_count() - 1. If i is not in that range, returns NULL. + const TestInfo* GetTestInfo(int i) const; + + private: + friend class Test; + friend class internal::UnitTestImpl; + + // Gets the (mutable) vector of TestInfos in this TestCase. + std::vector& test_info_list() { return test_info_list_; } + + // Gets the (immutable) vector of TestInfos in this TestCase. + const std::vector& test_info_list() const { + return test_info_list_; + } + + // Returns the i-th test among all the tests. i can range from 0 to + // total_test_count() - 1. If i is not in that range, returns NULL. + TestInfo* GetMutableTestInfo(int i); + + // Sets the should_run member. + void set_should_run(bool should) { should_run_ = should; } + + // Adds a TestInfo to this test case. Will delete the TestInfo upon + // destruction of the TestCase object. + void AddTestInfo(TestInfo * test_info); + + // Clears the results of all tests in this test case. + void ClearResult(); + + // Clears the results of all tests in the given test case. + static void ClearTestCaseResult(TestCase* test_case) { + test_case->ClearResult(); + } + + // Runs every test in this TestCase. + void Run(); + + // Returns true iff test passed. + static bool TestPassed(const TestInfo * test_info); + + // Returns true iff test failed. + static bool TestFailed(const TestInfo * test_info); + + // Returns true iff test is disabled. + static bool TestDisabled(const TestInfo * test_info); + + // Returns true if the given test should run. + static bool ShouldRunTest(const TestInfo *test_info); + + // Shuffles the tests in this test case. + void ShuffleTests(internal::Random* random); + + // Restores the test order to before the first shuffle. + void UnshuffleTests(); + + // Name of the test case. + internal::String name_; + // Comment on the test case. + internal::String comment_; + // The vector of TestInfos in their original order. It owns the + // elements in the vector. + std::vector test_info_list_; + // Provides a level of indirection for the test list to allow easy + // shuffling and restoring the test order. The i-th element in this + // vector is the index of the i-th test in the shuffled test list. + std::vector test_indices_; + // Pointer to the function that sets up the test case. + Test::SetUpTestCaseFunc set_up_tc_; + // Pointer to the function that tears down the test case. + Test::TearDownTestCaseFunc tear_down_tc_; + // True iff any test in this test case should run. + bool should_run_; + // Elapsed time, in milliseconds. + TimeInMillis elapsed_time_; + + // We disallow copying TestCases. + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestCase); +}; + +// An Environment object is capable of setting up and tearing down an +// environment. The user should subclass this to define his own +// environment(s). +// +// An Environment object does the set-up and tear-down in virtual +// methods SetUp() and TearDown() instead of the constructor and the +// destructor, as: +// +// 1. You cannot safely throw from a destructor. This is a problem +// as in some cases Google Test is used where exceptions are enabled, and +// we may want to implement ASSERT_* using exceptions where they are +// available. +// 2. You cannot use ASSERT_* directly in a constructor or +// destructor. +class Environment { + public: + // The d'tor is virtual as we need to subclass Environment. + virtual ~Environment() {} + + // Override this to define how to set up the environment. + virtual void SetUp() {} + + // Override this to define how to tear down the environment. + virtual void TearDown() {} + private: + // If you see an error about overriding the following function or + // about it being private, you have mis-spelled SetUp() as Setup(). + struct Setup_should_be_spelled_SetUp {}; + virtual Setup_should_be_spelled_SetUp* Setup() { return NULL; } +}; + +// The interface for tracing execution of tests. The methods are organized in +// the order the corresponding events are fired. +class TestEventListener { + public: + virtual ~TestEventListener() {} + + // Fired before any test activity starts. + virtual void OnTestProgramStart(const UnitTest& unit_test) = 0; + + // Fired before each iteration of tests starts. There may be more than + // one iteration if GTEST_FLAG(repeat) is set. iteration is the iteration + // index, starting from 0. + virtual void OnTestIterationStart(const UnitTest& unit_test, + int iteration) = 0; + + // Fired before environment set-up for each iteration of tests starts. + virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test) = 0; + + // Fired after environment set-up for each iteration of tests ends. + virtual void OnEnvironmentsSetUpEnd(const UnitTest& unit_test) = 0; + + // Fired before the test case starts. + virtual void OnTestCaseStart(const TestCase& test_case) = 0; + + // Fired before the test starts. + virtual void OnTestStart(const TestInfo& test_info) = 0; + + // Fired after a failed assertion or a SUCCESS(). + virtual void OnTestPartResult(const TestPartResult& test_part_result) = 0; + + // Fired after the test ends. + virtual void OnTestEnd(const TestInfo& test_info) = 0; + + // Fired after the test case ends. + virtual void OnTestCaseEnd(const TestCase& test_case) = 0; + + // Fired before environment tear-down for each iteration of tests starts. + virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test) = 0; + + // Fired after environment tear-down for each iteration of tests ends. + virtual void OnEnvironmentsTearDownEnd(const UnitTest& unit_test) = 0; + + // Fired after each iteration of tests finishes. + virtual void OnTestIterationEnd(const UnitTest& unit_test, + int iteration) = 0; + + // Fired after all test activities have ended. + virtual void OnTestProgramEnd(const UnitTest& unit_test) = 0; +}; + +// The convenience class for users who need to override just one or two +// methods and are not concerned that a possible change to a signature of +// the methods they override will not be caught during the build. For +// comments about each method please see the definition of TestEventListener +// above. +class EmptyTestEventListener : public TestEventListener { + public: + virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) {} + virtual void OnTestIterationStart(const UnitTest& /*unit_test*/, + int /*iteration*/) {} + virtual void OnEnvironmentsSetUpStart(const UnitTest& /*unit_test*/) {} + virtual void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) {} + virtual void OnTestCaseStart(const TestCase& /*test_case*/) {} + virtual void OnTestStart(const TestInfo& /*test_info*/) {} + virtual void OnTestPartResult(const TestPartResult& /*test_part_result*/) {} + virtual void OnTestEnd(const TestInfo& /*test_info*/) {} + virtual void OnTestCaseEnd(const TestCase& /*test_case*/) {} + virtual void OnEnvironmentsTearDownStart(const UnitTest& /*unit_test*/) {} + virtual void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) {} + virtual void OnTestIterationEnd(const UnitTest& /*unit_test*/, + int /*iteration*/) {} + virtual void OnTestProgramEnd(const UnitTest& /*unit_test*/) {} +}; + +// TestEventListeners lets users add listeners to track events in Google Test. +class GTEST_API_ TestEventListeners { + public: + TestEventListeners(); + ~TestEventListeners(); + + // Appends an event listener to the end of the list. Google Test assumes + // the ownership of the listener (i.e. it will delete the listener when + // the test program finishes). + void Append(TestEventListener* listener); + + // Removes the given event listener from the list and returns it. It then + // becomes the caller's responsibility to delete the listener. Returns + // NULL if the listener is not found in the list. + TestEventListener* Release(TestEventListener* listener); + + // Returns the standard listener responsible for the default console + // output. Can be removed from the listeners list to shut down default + // console output. Note that removing this object from the listener list + // with Release transfers its ownership to the caller and makes this + // function return NULL the next time. + TestEventListener* default_result_printer() const { + return default_result_printer_; + } + + // Returns the standard listener responsible for the default XML output + // controlled by the --gtest_output=xml flag. Can be removed from the + // listeners list by users who want to shut down the default XML output + // controlled by this flag and substitute it with custom one. Note that + // removing this object from the listener list with Release transfers its + // ownership to the caller and makes this function return NULL the next + // time. + TestEventListener* default_xml_generator() const { + return default_xml_generator_; + } + + private: + friend class TestCase; + friend class internal::DefaultGlobalTestPartResultReporter; + friend class internal::NoExecDeathTest; + friend class internal::TestEventListenersAccessor; + friend class internal::TestInfoImpl; + friend class internal::UnitTestImpl; + + // Returns repeater that broadcasts the TestEventListener events to all + // subscribers. + TestEventListener* repeater(); + + // Sets the default_result_printer attribute to the provided listener. + // The listener is also added to the listener list and previous + // default_result_printer is removed from it and deleted. The listener can + // also be NULL in which case it will not be added to the list. Does + // nothing if the previous and the current listener objects are the same. + void SetDefaultResultPrinter(TestEventListener* listener); + + // Sets the default_xml_generator attribute to the provided listener. The + // listener is also added to the listener list and previous + // default_xml_generator is removed from it and deleted. The listener can + // also be NULL in which case it will not be added to the list. Does + // nothing if the previous and the current listener objects are the same. + void SetDefaultXmlGenerator(TestEventListener* listener); + + // Controls whether events will be forwarded by the repeater to the + // listeners in the list. + bool EventForwardingEnabled() const; + void SuppressEventForwarding(); + + // The actual list of listeners. + internal::TestEventRepeater* repeater_; + // Listener responsible for the standard result output. + TestEventListener* default_result_printer_; + // Listener responsible for the creation of the XML output file. + TestEventListener* default_xml_generator_; + + // We disallow copying TestEventListeners. + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestEventListeners); +}; + +// A UnitTest consists of a vector of TestCases. +// +// This is a singleton class. The only instance of UnitTest is +// created when UnitTest::GetInstance() is first called. This +// instance is never deleted. +// +// UnitTest is not copyable. +// +// This class is thread-safe as long as the methods are called +// according to their specification. +class GTEST_API_ UnitTest { + public: + // Gets the singleton UnitTest object. The first time this method + // is called, a UnitTest object is constructed and returned. + // Consecutive calls will return the same object. + static UnitTest* GetInstance(); + + // Runs all tests in this UnitTest object and prints the result. + // Returns 0 if successful, or 1 otherwise. + // + // This method can only be called from the main thread. + // + // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. + int Run() GTEST_MUST_USE_RESULT_; + + // Returns the working directory when the first TEST() or TEST_F() + // was executed. The UnitTest object owns the string. + const char* original_working_dir() const; + + // Returns the TestCase object for the test that's currently running, + // or NULL if no test is running. + const TestCase* current_test_case() const; + + // Returns the TestInfo object for the test that's currently running, + // or NULL if no test is running. + const TestInfo* current_test_info() const; + + // Returns the random seed used at the start of the current test run. + int random_seed() const; + +#if GTEST_HAS_PARAM_TEST + // Returns the ParameterizedTestCaseRegistry object used to keep track of + // value-parameterized tests and instantiate and register them. + // + // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. + internal::ParameterizedTestCaseRegistry& parameterized_test_registry(); +#endif // GTEST_HAS_PARAM_TEST + + // Gets the number of successful test cases. + int successful_test_case_count() const; + + // Gets the number of failed test cases. + int failed_test_case_count() const; + + // Gets the number of all test cases. + int total_test_case_count() const; + + // Gets the number of all test cases that contain at least one test + // that should run. + int test_case_to_run_count() const; + + // Gets the number of successful tests. + int successful_test_count() const; + + // Gets the number of failed tests. + int failed_test_count() const; + + // Gets the number of disabled tests. + int disabled_test_count() const; + + // Gets the number of all tests. + int total_test_count() const; + + // Gets the number of tests that should run. + int test_to_run_count() const; + + // Gets the elapsed time, in milliseconds. + TimeInMillis elapsed_time() const; + + // Returns true iff the unit test passed (i.e. all test cases passed). + bool Passed() const; + + // Returns true iff the unit test failed (i.e. some test case failed + // or something outside of all tests failed). + bool Failed() const; + + // Gets the i-th test case among all the test cases. i can range from 0 to + // total_test_case_count() - 1. If i is not in that range, returns NULL. + const TestCase* GetTestCase(int i) const; + + // Returns the list of event listeners that can be used to track events + // inside Google Test. + TestEventListeners& listeners(); + + private: + // Registers and returns a global test environment. When a test + // program is run, all global test environments will be set-up in + // the order they were registered. After all tests in the program + // have finished, all global test environments will be torn-down in + // the *reverse* order they were registered. + // + // The UnitTest object takes ownership of the given environment. + // + // This method can only be called from the main thread. + Environment* AddEnvironment(Environment* env); + + // Adds a TestPartResult to the current TestResult object. All + // Google Test assertion macros (e.g. ASSERT_TRUE, EXPECT_EQ, etc) + // eventually call this to report their results. The user code + // should use the assertion macros instead of calling this directly. + void AddTestPartResult(TestPartResult::Type result_type, + const char* file_name, + int line_number, + const internal::String& message, + const internal::String& os_stack_trace); + + // Adds a TestProperty to the current TestResult object. If the result already + // contains a property with the same key, the value will be updated. + void RecordPropertyForCurrentTest(const char* key, const char* value); + + // Gets the i-th test case among all the test cases. i can range from 0 to + // total_test_case_count() - 1. If i is not in that range, returns NULL. + TestCase* GetMutableTestCase(int i); + + // Accessors for the implementation object. + internal::UnitTestImpl* impl() { return impl_; } + const internal::UnitTestImpl* impl() const { return impl_; } + + // These classes and funcions are friends as they need to access private + // members of UnitTest. + friend class Test; + friend class internal::AssertHelper; + friend class internal::ScopedTrace; + friend Environment* AddGlobalTestEnvironment(Environment* env); + friend internal::UnitTestImpl* internal::GetUnitTestImpl(); + friend void internal::ReportFailureInUnknownLocation( + TestPartResult::Type result_type, + const internal::String& message); + + // Creates an empty UnitTest. + UnitTest(); + + // D'tor + virtual ~UnitTest(); + + // Pushes a trace defined by SCOPED_TRACE() on to the per-thread + // Google Test trace stack. + void PushGTestTrace(const internal::TraceInfo& trace); + + // Pops a trace from the per-thread Google Test trace stack. + void PopGTestTrace(); + + // Protects mutable state in *impl_. This is mutable as some const + // methods need to lock it too. + mutable internal::Mutex mutex_; + + // Opaque implementation object. This field is never changed once + // the object is constructed. We don't mark it as const here, as + // doing so will cause a warning in the constructor of UnitTest. + // Mutable state in *impl_ is protected by mutex_. + internal::UnitTestImpl* impl_; + + // We disallow copying UnitTest. + GTEST_DISALLOW_COPY_AND_ASSIGN_(UnitTest); +}; + +// A convenient wrapper for adding an environment for the test +// program. +// +// You should call this before RUN_ALL_TESTS() is called, probably in +// main(). If you use gtest_main, you need to call this before main() +// starts for it to take effect. For example, you can define a global +// variable like this: +// +// testing::Environment* const foo_env = +// testing::AddGlobalTestEnvironment(new FooEnvironment); +// +// However, we strongly recommend you to write your own main() and +// call AddGlobalTestEnvironment() there, as relying on initialization +// of global variables makes the code harder to read and may cause +// problems when you register multiple environments from different +// translation units and the environments have dependencies among them +// (remember that the compiler doesn't guarantee the order in which +// global variables from different translation units are initialized). +inline Environment* AddGlobalTestEnvironment(Environment* env) { + return UnitTest::GetInstance()->AddEnvironment(env); +} + +// Initializes Google Test. This must be called before calling +// RUN_ALL_TESTS(). In particular, it parses a command line for the +// flags that Google Test recognizes. Whenever a Google Test flag is +// seen, it is removed from argv, and *argc is decremented. +// +// No value is returned. Instead, the Google Test flag variables are +// updated. +// +// Calling the function for the second time has no user-visible effect. +GTEST_API_ void InitGoogleTest(int* argc, char** argv); + +// This overloaded version can be used in Windows programs compiled in +// UNICODE mode. +GTEST_API_ void InitGoogleTest(int* argc, wchar_t** argv); + +namespace internal { + +// These overloaded versions handle ::std::string and ::std::wstring. +GTEST_API_ inline String FormatForFailureMessage(const ::std::string& str) { + return (Message() << '"' << str << '"').GetString(); +} + +#if GTEST_HAS_STD_WSTRING +GTEST_API_ inline String FormatForFailureMessage(const ::std::wstring& wstr) { + return (Message() << "L\"" << wstr << '"').GetString(); +} +#endif // GTEST_HAS_STD_WSTRING + +// These overloaded versions handle ::string and ::wstring. +#if GTEST_HAS_GLOBAL_STRING +GTEST_API_ inline String FormatForFailureMessage(const ::string& str) { + return (Message() << '"' << str << '"').GetString(); +} +#endif // GTEST_HAS_GLOBAL_STRING + +#if GTEST_HAS_GLOBAL_WSTRING +GTEST_API_ inline String FormatForFailureMessage(const ::wstring& wstr) { + return (Message() << "L\"" << wstr << '"').GetString(); +} +#endif // GTEST_HAS_GLOBAL_WSTRING + +// Formats a comparison assertion (e.g. ASSERT_EQ, EXPECT_LT, and etc) +// operand to be used in a failure message. The type (but not value) +// of the other operand may affect the format. This allows us to +// print a char* as a raw pointer when it is compared against another +// char*, and print it as a C string when it is compared against an +// std::string object, for example. +// +// The default implementation ignores the type of the other operand. +// Some specialized versions are used to handle formatting wide or +// narrow C strings. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +template +String FormatForComparisonFailureMessage(const T1& value, + const T2& /* other_operand */) { + return FormatForFailureMessage(value); +} + +// The helper function for {ASSERT|EXPECT}_EQ. +template +AssertionResult CmpHelperEQ(const char* expected_expression, + const char* actual_expression, + const T1& expected, + const T2& actual) { +#ifdef _MSC_VER +#pragma warning(push) // Saves the current warning state. +#pragma warning(disable:4389) // Temporarily disables warning on + // signed/unsigned mismatch. +#endif + + if (expected == actual) { + return AssertionSuccess(); + } + +#ifdef _MSC_VER +#pragma warning(pop) // Restores the warning state. +#endif + + return EqFailure(expected_expression, + actual_expression, + FormatForComparisonFailureMessage(expected, actual), + FormatForComparisonFailureMessage(actual, expected), + false); +} + +// With this overloaded version, we allow anonymous enums to be used +// in {ASSERT|EXPECT}_EQ when compiled with gcc 4, as anonymous enums +// can be implicitly cast to BiggestInt. +GTEST_API_ AssertionResult CmpHelperEQ(const char* expected_expression, + const char* actual_expression, + BiggestInt expected, + BiggestInt actual); + +// The helper class for {ASSERT|EXPECT}_EQ. The template argument +// lhs_is_null_literal is true iff the first argument to ASSERT_EQ() +// is a null pointer literal. The following default implementation is +// for lhs_is_null_literal being false. +template +class EqHelper { + public: + // This templatized version is for the general case. + template + static AssertionResult Compare(const char* expected_expression, + const char* actual_expression, + const T1& expected, + const T2& actual) { + return CmpHelperEQ(expected_expression, actual_expression, expected, + actual); + } + + // With this overloaded version, we allow anonymous enums to be used + // in {ASSERT|EXPECT}_EQ when compiled with gcc 4, as anonymous + // enums can be implicitly cast to BiggestInt. + // + // Even though its body looks the same as the above version, we + // cannot merge the two, as it will make anonymous enums unhappy. + static AssertionResult Compare(const char* expected_expression, + const char* actual_expression, + BiggestInt expected, + BiggestInt actual) { + return CmpHelperEQ(expected_expression, actual_expression, expected, + actual); + } +}; + +// This specialization is used when the first argument to ASSERT_EQ() +// is a null pointer literal. +template <> +class EqHelper { + public: + // We define two overloaded versions of Compare(). The first + // version will be picked when the second argument to ASSERT_EQ() is + // NOT a pointer, e.g. ASSERT_EQ(0, AnIntFunction()) or + // EXPECT_EQ(false, a_bool). + template + static AssertionResult Compare(const char* expected_expression, + const char* actual_expression, + const T1& expected, + const T2& actual) { + return CmpHelperEQ(expected_expression, actual_expression, expected, + actual); + } + + // This version will be picked when the second argument to + // ASSERT_EQ() is a pointer, e.g. ASSERT_EQ(NULL, a_pointer). + template + static AssertionResult Compare(const char* expected_expression, + const char* actual_expression, + const T1& /* expected */, + T2* actual) { + // We already know that 'expected' is a null pointer. + return CmpHelperEQ(expected_expression, actual_expression, + static_cast(NULL), actual); + } +}; + +// A macro for implementing the helper functions needed to implement +// ASSERT_?? and EXPECT_??. It is here just to avoid copy-and-paste +// of similar code. +// +// For each templatized helper function, we also define an overloaded +// version for BiggestInt in order to reduce code bloat and allow +// anonymous enums to be used with {ASSERT|EXPECT}_?? when compiled +// with gcc 4. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +#define GTEST_IMPL_CMP_HELPER_(op_name, op)\ +template \ +AssertionResult CmpHelper##op_name(const char* expr1, const char* expr2, \ + const T1& val1, const T2& val2) {\ + if (val1 op val2) {\ + return AssertionSuccess();\ + } else {\ + Message msg;\ + msg << "Expected: (" << expr1 << ") " #op " (" << expr2\ + << "), actual: " << FormatForComparisonFailureMessage(val1, val2)\ + << " vs " << FormatForComparisonFailureMessage(val2, val1);\ + return AssertionFailure(msg);\ + }\ +}\ +GTEST_API_ AssertionResult CmpHelper##op_name(\ + const char* expr1, const char* expr2, BiggestInt val1, BiggestInt val2) + +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. + +// Implements the helper function for {ASSERT|EXPECT}_NE +GTEST_IMPL_CMP_HELPER_(NE, !=); +// Implements the helper function for {ASSERT|EXPECT}_LE +GTEST_IMPL_CMP_HELPER_(LE, <=); +// Implements the helper function for {ASSERT|EXPECT}_LT +GTEST_IMPL_CMP_HELPER_(LT, < ); +// Implements the helper function for {ASSERT|EXPECT}_GE +GTEST_IMPL_CMP_HELPER_(GE, >=); +// Implements the helper function for {ASSERT|EXPECT}_GT +GTEST_IMPL_CMP_HELPER_(GT, > ); + +#undef GTEST_IMPL_CMP_HELPER_ + +// The helper function for {ASSERT|EXPECT}_STREQ. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +GTEST_API_ AssertionResult CmpHelperSTREQ(const char* expected_expression, + const char* actual_expression, + const char* expected, + const char* actual); + +// The helper function for {ASSERT|EXPECT}_STRCASEEQ. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +GTEST_API_ AssertionResult CmpHelperSTRCASEEQ(const char* expected_expression, + const char* actual_expression, + const char* expected, + const char* actual); + +// The helper function for {ASSERT|EXPECT}_STRNE. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +GTEST_API_ AssertionResult CmpHelperSTRNE(const char* s1_expression, + const char* s2_expression, + const char* s1, + const char* s2); + +// The helper function for {ASSERT|EXPECT}_STRCASENE. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +GTEST_API_ AssertionResult CmpHelperSTRCASENE(const char* s1_expression, + const char* s2_expression, + const char* s1, + const char* s2); + + +// Helper function for *_STREQ on wide strings. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +GTEST_API_ AssertionResult CmpHelperSTREQ(const char* expected_expression, + const char* actual_expression, + const wchar_t* expected, + const wchar_t* actual); + +// Helper function for *_STRNE on wide strings. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +GTEST_API_ AssertionResult CmpHelperSTRNE(const char* s1_expression, + const char* s2_expression, + const wchar_t* s1, + const wchar_t* s2); + +} // namespace internal + +// IsSubstring() and IsNotSubstring() are intended to be used as the +// first argument to {EXPECT,ASSERT}_PRED_FORMAT2(), not by +// themselves. They check whether needle is a substring of haystack +// (NULL is considered a substring of itself only), and return an +// appropriate error message when they fail. +// +// The {needle,haystack}_expr arguments are the stringified +// expressions that generated the two real arguments. +GTEST_API_ AssertionResult IsSubstring( + const char* needle_expr, const char* haystack_expr, + const char* needle, const char* haystack); +GTEST_API_ AssertionResult IsSubstring( + const char* needle_expr, const char* haystack_expr, + const wchar_t* needle, const wchar_t* haystack); +GTEST_API_ AssertionResult IsNotSubstring( + const char* needle_expr, const char* haystack_expr, + const char* needle, const char* haystack); +GTEST_API_ AssertionResult IsNotSubstring( + const char* needle_expr, const char* haystack_expr, + const wchar_t* needle, const wchar_t* haystack); +GTEST_API_ AssertionResult IsSubstring( + const char* needle_expr, const char* haystack_expr, + const ::std::string& needle, const ::std::string& haystack); +GTEST_API_ AssertionResult IsNotSubstring( + const char* needle_expr, const char* haystack_expr, + const ::std::string& needle, const ::std::string& haystack); + +#if GTEST_HAS_STD_WSTRING +GTEST_API_ AssertionResult IsSubstring( + const char* needle_expr, const char* haystack_expr, + const ::std::wstring& needle, const ::std::wstring& haystack); +GTEST_API_ AssertionResult IsNotSubstring( + const char* needle_expr, const char* haystack_expr, + const ::std::wstring& needle, const ::std::wstring& haystack); +#endif // GTEST_HAS_STD_WSTRING + +namespace internal { + +// Helper template function for comparing floating-points. +// +// Template parameter: +// +// RawType: the raw floating-point type (either float or double) +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +template +AssertionResult CmpHelperFloatingPointEQ(const char* expected_expression, + const char* actual_expression, + RawType expected, + RawType actual) { + const FloatingPoint lhs(expected), rhs(actual); + + if (lhs.AlmostEquals(rhs)) { + return AssertionSuccess(); + } + + StrStream expected_ss; + expected_ss << std::setprecision(std::numeric_limits::digits10 + 2) + << expected; + + StrStream actual_ss; + actual_ss << std::setprecision(std::numeric_limits::digits10 + 2) + << actual; + + return EqFailure(expected_expression, + actual_expression, + StrStreamToString(&expected_ss), + StrStreamToString(&actual_ss), + false); +} + +// Helper function for implementing ASSERT_NEAR. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +GTEST_API_ AssertionResult DoubleNearPredFormat(const char* expr1, + const char* expr2, + const char* abs_error_expr, + double val1, + double val2, + double abs_error); + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// A class that enables one to stream messages to assertion macros +class GTEST_API_ AssertHelper { + public: + // Constructor. + AssertHelper(TestPartResult::Type type, + const char* file, + int line, + const char* message); + ~AssertHelper(); + + // Message assignment is a semantic trick to enable assertion + // streaming; see the GTEST_MESSAGE_ macro below. + void operator=(const Message& message) const; + + private: + // We put our data in a struct so that the size of the AssertHelper class can + // be as small as possible. This is important because gcc is incapable of + // re-using stack space even for temporary variables, so every EXPECT_EQ + // reserves stack space for another AssertHelper. + struct AssertHelperData { + AssertHelperData(TestPartResult::Type t, + const char* srcfile, + int line_num, + const char* msg) + : type(t), file(srcfile), line(line_num), message(msg) { } + + TestPartResult::Type const type; + const char* const file; + int const line; + String const message; + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(AssertHelperData); + }; + + AssertHelperData* const data_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(AssertHelper); +}; + +} // namespace internal + +#if GTEST_HAS_PARAM_TEST +// The abstract base class that all value-parameterized tests inherit from. +// +// This class adds support for accessing the test parameter value via +// the GetParam() method. +// +// Use it with one of the parameter generator defining functions, like Range(), +// Values(), ValuesIn(), Bool(), and Combine(). +// +// class FooTest : public ::testing::TestWithParam { +// protected: +// FooTest() { +// // Can use GetParam() here. +// } +// virtual ~FooTest() { +// // Can use GetParam() here. +// } +// virtual void SetUp() { +// // Can use GetParam() here. +// } +// virtual void TearDown { +// // Can use GetParam() here. +// } +// }; +// TEST_P(FooTest, DoesBar) { +// // Can use GetParam() method here. +// Foo foo; +// ASSERT_TRUE(foo.DoesBar(GetParam())); +// } +// INSTANTIATE_TEST_CASE_P(OneToTenRange, FooTest, ::testing::Range(1, 10)); + +template +class TestWithParam : public Test { + public: + typedef T ParamType; + + // The current parameter value. Is also available in the test fixture's + // constructor. + const ParamType& GetParam() const { return *parameter_; } + + private: + // Sets parameter value. The caller is responsible for making sure the value + // remains alive and unchanged throughout the current test. + static void SetParam(const ParamType* parameter) { + parameter_ = parameter; + } + + // Static value used for accessing parameter during a test lifetime. + static const ParamType* parameter_; + + // TestClass must be a subclass of TestWithParam. + template friend class internal::ParameterizedTestFactory; +}; + +template +const T* TestWithParam::parameter_ = NULL; + +#endif // GTEST_HAS_PARAM_TEST + +// Macros for indicating success/failure in test code. + +// ADD_FAILURE unconditionally adds a failure to the current test. +// SUCCEED generates a success - it doesn't automatically make the +// current test successful, as a test is only successful when it has +// no failure. +// +// EXPECT_* verifies that a certain condition is satisfied. If not, +// it behaves like ADD_FAILURE. In particular: +// +// EXPECT_TRUE verifies that a Boolean condition is true. +// EXPECT_FALSE verifies that a Boolean condition is false. +// +// FAIL and ASSERT_* are similar to ADD_FAILURE and EXPECT_*, except +// that they will also abort the current function on failure. People +// usually want the fail-fast behavior of FAIL and ASSERT_*, but those +// writing data-driven tests often find themselves using ADD_FAILURE +// and EXPECT_* more. +// +// Examples: +// +// EXPECT_TRUE(server.StatusIsOK()); +// ASSERT_FALSE(server.HasPendingRequest(port)) +// << "There are still pending requests " << "on port " << port; + +// Generates a nonfatal failure with a generic message. +#define ADD_FAILURE() GTEST_NONFATAL_FAILURE_("Failed") + +// Generates a fatal failure with a generic message. +#define GTEST_FAIL() GTEST_FATAL_FAILURE_("Failed") + +// Define this macro to 1 to omit the definition of FAIL(), which is a +// generic name and clashes with some other libraries. +#if !GTEST_DONT_DEFINE_FAIL +#define FAIL() GTEST_FAIL() +#endif + +// Generates a success with a generic message. +#define GTEST_SUCCEED() GTEST_SUCCESS_("Succeeded") + +// Define this macro to 1 to omit the definition of SUCCEED(), which +// is a generic name and clashes with some other libraries. +#if !GTEST_DONT_DEFINE_SUCCEED +#define SUCCEED() GTEST_SUCCEED() +#endif + +// Macros for testing exceptions. +// +// * {ASSERT|EXPECT}_THROW(statement, expected_exception): +// Tests that the statement throws the expected exception. +// * {ASSERT|EXPECT}_NO_THROW(statement): +// Tests that the statement doesn't throw any exception. +// * {ASSERT|EXPECT}_ANY_THROW(statement): +// Tests that the statement throws an exception. + +#define EXPECT_THROW(statement, expected_exception) \ + GTEST_TEST_THROW_(statement, expected_exception, GTEST_NONFATAL_FAILURE_) +#define EXPECT_NO_THROW(statement) \ + GTEST_TEST_NO_THROW_(statement, GTEST_NONFATAL_FAILURE_) +#define EXPECT_ANY_THROW(statement) \ + GTEST_TEST_ANY_THROW_(statement, GTEST_NONFATAL_FAILURE_) +#define ASSERT_THROW(statement, expected_exception) \ + GTEST_TEST_THROW_(statement, expected_exception, GTEST_FATAL_FAILURE_) +#define ASSERT_NO_THROW(statement) \ + GTEST_TEST_NO_THROW_(statement, GTEST_FATAL_FAILURE_) +#define ASSERT_ANY_THROW(statement) \ + GTEST_TEST_ANY_THROW_(statement, GTEST_FATAL_FAILURE_) + +// Boolean assertions. Condition can be either a Boolean expression or an +// AssertionResult. For more information on how to use AssertionResult with +// these macros see comments on that class. +#define EXPECT_TRUE(condition) \ + GTEST_TEST_BOOLEAN_(condition, #condition, false, true, \ + GTEST_NONFATAL_FAILURE_) +#define EXPECT_FALSE(condition) \ + GTEST_TEST_BOOLEAN_(!(condition), #condition, true, false, \ + GTEST_NONFATAL_FAILURE_) +#define ASSERT_TRUE(condition) \ + GTEST_TEST_BOOLEAN_(condition, #condition, false, true, \ + GTEST_FATAL_FAILURE_) +#define ASSERT_FALSE(condition) \ + GTEST_TEST_BOOLEAN_(!(condition), #condition, true, false, \ + GTEST_FATAL_FAILURE_) + +// Includes the auto-generated header that implements a family of +// generic predicate assertion macros. +// Copyright 2006, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// This file is AUTOMATICALLY GENERATED on 10/02/2008 by command +// 'gen_gtest_pred_impl.py 5'. DO NOT EDIT BY HAND! +// +// Implements a family of generic predicate assertion macros. + +#ifndef GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ +#define GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ + +// Makes sure this header is not included before gtest.h. +#ifndef GTEST_INCLUDE_GTEST_GTEST_H_ +#error Do not include gtest_pred_impl.h directly. Include gtest.h instead. +#endif // GTEST_INCLUDE_GTEST_GTEST_H_ + +// This header implements a family of generic predicate assertion +// macros: +// +// ASSERT_PRED_FORMAT1(pred_format, v1) +// ASSERT_PRED_FORMAT2(pred_format, v1, v2) +// ... +// +// where pred_format is a function or functor that takes n (in the +// case of ASSERT_PRED_FORMATn) values and their source expression +// text, and returns a testing::AssertionResult. See the definition +// of ASSERT_EQ in gtest.h for an example. +// +// If you don't care about formatting, you can use the more +// restrictive version: +// +// ASSERT_PRED1(pred, v1) +// ASSERT_PRED2(pred, v1, v2) +// ... +// +// where pred is an n-ary function or functor that returns bool, +// and the values v1, v2, ..., must support the << operator for +// streaming to std::ostream. +// +// We also define the EXPECT_* variations. +// +// For now we only support predicates whose arity is at most 5. +// Please email googletestframework@googlegroups.com if you need +// support for higher arities. + +// GTEST_ASSERT_ is the basic statement to which all of the assertions +// in this file reduce. Don't use this in your code. + +#define GTEST_ASSERT_(expression, on_failure) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (const ::testing::AssertionResult gtest_ar = (expression)) \ + ; \ + else \ + on_failure(gtest_ar.failure_message()) + + +// Helper function for implementing {EXPECT|ASSERT}_PRED1. Don't use +// this in your code. +template +AssertionResult AssertPred1Helper(const char* pred_text, + const char* e1, + Pred pred, + const T1& v1) { + if (pred(v1)) return AssertionSuccess(); + + Message msg; + msg << pred_text << "(" + << e1 << ") evaluates to false, where" + << "\n" << e1 << " evaluates to " << v1; + return AssertionFailure(msg); +} + +// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT1. +// Don't use this in your code. +#define GTEST_PRED_FORMAT1_(pred_format, v1, on_failure)\ + GTEST_ASSERT_(pred_format(#v1, v1),\ + on_failure) + +// Internal macro for implementing {EXPECT|ASSERT}_PRED1. Don't use +// this in your code. +#define GTEST_PRED1_(pred, v1, on_failure)\ + GTEST_ASSERT_(::testing::AssertPred1Helper(#pred, \ + #v1, \ + pred, \ + v1), on_failure) + +// Unary predicate assertion macros. +#define EXPECT_PRED_FORMAT1(pred_format, v1) \ + GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_NONFATAL_FAILURE_) +#define EXPECT_PRED1(pred, v1) \ + GTEST_PRED1_(pred, v1, GTEST_NONFATAL_FAILURE_) +#define ASSERT_PRED_FORMAT1(pred_format, v1) \ + GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_FATAL_FAILURE_) +#define ASSERT_PRED1(pred, v1) \ + GTEST_PRED1_(pred, v1, GTEST_FATAL_FAILURE_) + + + +// Helper function for implementing {EXPECT|ASSERT}_PRED2. Don't use +// this in your code. +template +AssertionResult AssertPred2Helper(const char* pred_text, + const char* e1, + const char* e2, + Pred pred, + const T1& v1, + const T2& v2) { + if (pred(v1, v2)) return AssertionSuccess(); + + Message msg; + msg << pred_text << "(" + << e1 << ", " + << e2 << ") evaluates to false, where" + << "\n" << e1 << " evaluates to " << v1 + << "\n" << e2 << " evaluates to " << v2; + return AssertionFailure(msg); +} + +// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT2. +// Don't use this in your code. +#define GTEST_PRED_FORMAT2_(pred_format, v1, v2, on_failure)\ + GTEST_ASSERT_(pred_format(#v1, #v2, v1, v2),\ + on_failure) + +// Internal macro for implementing {EXPECT|ASSERT}_PRED2. Don't use +// this in your code. +#define GTEST_PRED2_(pred, v1, v2, on_failure)\ + GTEST_ASSERT_(::testing::AssertPred2Helper(#pred, \ + #v1, \ + #v2, \ + pred, \ + v1, \ + v2), on_failure) + +// Binary predicate assertion macros. +#define EXPECT_PRED_FORMAT2(pred_format, v1, v2) \ + GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_NONFATAL_FAILURE_) +#define EXPECT_PRED2(pred, v1, v2) \ + GTEST_PRED2_(pred, v1, v2, GTEST_NONFATAL_FAILURE_) +#define ASSERT_PRED_FORMAT2(pred_format, v1, v2) \ + GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_FATAL_FAILURE_) +#define ASSERT_PRED2(pred, v1, v2) \ + GTEST_PRED2_(pred, v1, v2, GTEST_FATAL_FAILURE_) + + + +// Helper function for implementing {EXPECT|ASSERT}_PRED3. Don't use +// this in your code. +template +AssertionResult AssertPred3Helper(const char* pred_text, + const char* e1, + const char* e2, + const char* e3, + Pred pred, + const T1& v1, + const T2& v2, + const T3& v3) { + if (pred(v1, v2, v3)) return AssertionSuccess(); + + Message msg; + msg << pred_text << "(" + << e1 << ", " + << e2 << ", " + << e3 << ") evaluates to false, where" + << "\n" << e1 << " evaluates to " << v1 + << "\n" << e2 << " evaluates to " << v2 + << "\n" << e3 << " evaluates to " << v3; + return AssertionFailure(msg); +} + +// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT3. +// Don't use this in your code. +#define GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, on_failure)\ + GTEST_ASSERT_(pred_format(#v1, #v2, #v3, v1, v2, v3),\ + on_failure) + +// Internal macro for implementing {EXPECT|ASSERT}_PRED3. Don't use +// this in your code. +#define GTEST_PRED3_(pred, v1, v2, v3, on_failure)\ + GTEST_ASSERT_(::testing::AssertPred3Helper(#pred, \ + #v1, \ + #v2, \ + #v3, \ + pred, \ + v1, \ + v2, \ + v3), on_failure) + +// Ternary predicate assertion macros. +#define EXPECT_PRED_FORMAT3(pred_format, v1, v2, v3) \ + GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, GTEST_NONFATAL_FAILURE_) +#define EXPECT_PRED3(pred, v1, v2, v3) \ + GTEST_PRED3_(pred, v1, v2, v3, GTEST_NONFATAL_FAILURE_) +#define ASSERT_PRED_FORMAT3(pred_format, v1, v2, v3) \ + GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, GTEST_FATAL_FAILURE_) +#define ASSERT_PRED3(pred, v1, v2, v3) \ + GTEST_PRED3_(pred, v1, v2, v3, GTEST_FATAL_FAILURE_) + + + +// Helper function for implementing {EXPECT|ASSERT}_PRED4. Don't use +// this in your code. +template +AssertionResult AssertPred4Helper(const char* pred_text, + const char* e1, + const char* e2, + const char* e3, + const char* e4, + Pred pred, + const T1& v1, + const T2& v2, + const T3& v3, + const T4& v4) { + if (pred(v1, v2, v3, v4)) return AssertionSuccess(); + + Message msg; + msg << pred_text << "(" + << e1 << ", " + << e2 << ", " + << e3 << ", " + << e4 << ") evaluates to false, where" + << "\n" << e1 << " evaluates to " << v1 + << "\n" << e2 << " evaluates to " << v2 + << "\n" << e3 << " evaluates to " << v3 + << "\n" << e4 << " evaluates to " << v4; + return AssertionFailure(msg); +} + +// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT4. +// Don't use this in your code. +#define GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, on_failure)\ + GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, v1, v2, v3, v4),\ + on_failure) + +// Internal macro for implementing {EXPECT|ASSERT}_PRED4. Don't use +// this in your code. +#define GTEST_PRED4_(pred, v1, v2, v3, v4, on_failure)\ + GTEST_ASSERT_(::testing::AssertPred4Helper(#pred, \ + #v1, \ + #v2, \ + #v3, \ + #v4, \ + pred, \ + v1, \ + v2, \ + v3, \ + v4), on_failure) + +// 4-ary predicate assertion macros. +#define EXPECT_PRED_FORMAT4(pred_format, v1, v2, v3, v4) \ + GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, GTEST_NONFATAL_FAILURE_) +#define EXPECT_PRED4(pred, v1, v2, v3, v4) \ + GTEST_PRED4_(pred, v1, v2, v3, v4, GTEST_NONFATAL_FAILURE_) +#define ASSERT_PRED_FORMAT4(pred_format, v1, v2, v3, v4) \ + GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, GTEST_FATAL_FAILURE_) +#define ASSERT_PRED4(pred, v1, v2, v3, v4) \ + GTEST_PRED4_(pred, v1, v2, v3, v4, GTEST_FATAL_FAILURE_) + + + +// Helper function for implementing {EXPECT|ASSERT}_PRED5. Don't use +// this in your code. +template +AssertionResult AssertPred5Helper(const char* pred_text, + const char* e1, + const char* e2, + const char* e3, + const char* e4, + const char* e5, + Pred pred, + const T1& v1, + const T2& v2, + const T3& v3, + const T4& v4, + const T5& v5) { + if (pred(v1, v2, v3, v4, v5)) return AssertionSuccess(); + + Message msg; + msg << pred_text << "(" + << e1 << ", " + << e2 << ", " + << e3 << ", " + << e4 << ", " + << e5 << ") evaluates to false, where" + << "\n" << e1 << " evaluates to " << v1 + << "\n" << e2 << " evaluates to " << v2 + << "\n" << e3 << " evaluates to " << v3 + << "\n" << e4 << " evaluates to " << v4 + << "\n" << e5 << " evaluates to " << v5; + return AssertionFailure(msg); +} + +// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT5. +// Don't use this in your code. +#define GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, on_failure)\ + GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, #v5, v1, v2, v3, v4, v5),\ + on_failure) + +// Internal macro for implementing {EXPECT|ASSERT}_PRED5. Don't use +// this in your code. +#define GTEST_PRED5_(pred, v1, v2, v3, v4, v5, on_failure)\ + GTEST_ASSERT_(::testing::AssertPred5Helper(#pred, \ + #v1, \ + #v2, \ + #v3, \ + #v4, \ + #v5, \ + pred, \ + v1, \ + v2, \ + v3, \ + v4, \ + v5), on_failure) + +// 5-ary predicate assertion macros. +#define EXPECT_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5) \ + GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, GTEST_NONFATAL_FAILURE_) +#define EXPECT_PRED5(pred, v1, v2, v3, v4, v5) \ + GTEST_PRED5_(pred, v1, v2, v3, v4, v5, GTEST_NONFATAL_FAILURE_) +#define ASSERT_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5) \ + GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, GTEST_FATAL_FAILURE_) +#define ASSERT_PRED5(pred, v1, v2, v3, v4, v5) \ + GTEST_PRED5_(pred, v1, v2, v3, v4, v5, GTEST_FATAL_FAILURE_) + + + +#endif // GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ + +// Macros for testing equalities and inequalities. +// +// * {ASSERT|EXPECT}_EQ(expected, actual): Tests that expected == actual +// * {ASSERT|EXPECT}_NE(v1, v2): Tests that v1 != v2 +// * {ASSERT|EXPECT}_LT(v1, v2): Tests that v1 < v2 +// * {ASSERT|EXPECT}_LE(v1, v2): Tests that v1 <= v2 +// * {ASSERT|EXPECT}_GT(v1, v2): Tests that v1 > v2 +// * {ASSERT|EXPECT}_GE(v1, v2): Tests that v1 >= v2 +// +// When they are not, Google Test prints both the tested expressions and +// their actual values. The values must be compatible built-in types, +// or you will get a compiler error. By "compatible" we mean that the +// values can be compared by the respective operator. +// +// Note: +// +// 1. It is possible to make a user-defined type work with +// {ASSERT|EXPECT}_??(), but that requires overloading the +// comparison operators and is thus discouraged by the Google C++ +// Usage Guide. Therefore, you are advised to use the +// {ASSERT|EXPECT}_TRUE() macro to assert that two objects are +// equal. +// +// 2. The {ASSERT|EXPECT}_??() macros do pointer comparisons on +// pointers (in particular, C strings). Therefore, if you use it +// with two C strings, you are testing how their locations in memory +// are related, not how their content is related. To compare two C +// strings by content, use {ASSERT|EXPECT}_STR*(). +// +// 3. {ASSERT|EXPECT}_EQ(expected, actual) is preferred to +// {ASSERT|EXPECT}_TRUE(expected == actual), as the former tells you +// what the actual value is when it fails, and similarly for the +// other comparisons. +// +// 4. Do not depend on the order in which {ASSERT|EXPECT}_??() +// evaluate their arguments, which is undefined. +// +// 5. These macros evaluate their arguments exactly once. +// +// Examples: +// +// EXPECT_NE(5, Foo()); +// EXPECT_EQ(NULL, a_pointer); +// ASSERT_LT(i, array_size); +// ASSERT_GT(records.size(), 0) << "There is no record left."; + +#define EXPECT_EQ(expected, actual) \ + EXPECT_PRED_FORMAT2(::testing::internal:: \ + EqHelper::Compare, \ + expected, actual) +#define EXPECT_NE(expected, actual) \ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperNE, expected, actual) +#define EXPECT_LE(val1, val2) \ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperLE, val1, val2) +#define EXPECT_LT(val1, val2) \ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperLT, val1, val2) +#define EXPECT_GE(val1, val2) \ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperGE, val1, val2) +#define EXPECT_GT(val1, val2) \ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperGT, val1, val2) + +#define ASSERT_EQ(expected, actual) \ + ASSERT_PRED_FORMAT2(::testing::internal:: \ + EqHelper::Compare, \ + expected, actual) +#define ASSERT_NE(val1, val2) \ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperNE, val1, val2) +#define ASSERT_LE(val1, val2) \ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperLE, val1, val2) +#define ASSERT_LT(val1, val2) \ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperLT, val1, val2) +#define ASSERT_GE(val1, val2) \ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperGE, val1, val2) +#define ASSERT_GT(val1, val2) \ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperGT, val1, val2) + +// C String Comparisons. All tests treat NULL and any non-NULL string +// as different. Two NULLs are equal. +// +// * {ASSERT|EXPECT}_STREQ(s1, s2): Tests that s1 == s2 +// * {ASSERT|EXPECT}_STRNE(s1, s2): Tests that s1 != s2 +// * {ASSERT|EXPECT}_STRCASEEQ(s1, s2): Tests that s1 == s2, ignoring case +// * {ASSERT|EXPECT}_STRCASENE(s1, s2): Tests that s1 != s2, ignoring case +// +// For wide or narrow string objects, you can use the +// {ASSERT|EXPECT}_??() macros. +// +// Don't depend on the order in which the arguments are evaluated, +// which is undefined. +// +// These macros evaluate their arguments exactly once. + +#define EXPECT_STREQ(expected, actual) \ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTREQ, expected, actual) +#define EXPECT_STRNE(s1, s2) \ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRNE, s1, s2) +#define EXPECT_STRCASEEQ(expected, actual) \ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASEEQ, expected, actual) +#define EXPECT_STRCASENE(s1, s2)\ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASENE, s1, s2) + +#define ASSERT_STREQ(expected, actual) \ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTREQ, expected, actual) +#define ASSERT_STRNE(s1, s2) \ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRNE, s1, s2) +#define ASSERT_STRCASEEQ(expected, actual) \ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASEEQ, expected, actual) +#define ASSERT_STRCASENE(s1, s2)\ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASENE, s1, s2) + +// Macros for comparing floating-point numbers. +// +// * {ASSERT|EXPECT}_FLOAT_EQ(expected, actual): +// Tests that two float values are almost equal. +// * {ASSERT|EXPECT}_DOUBLE_EQ(expected, actual): +// Tests that two double values are almost equal. +// * {ASSERT|EXPECT}_NEAR(v1, v2, abs_error): +// Tests that v1 and v2 are within the given distance to each other. +// +// Google Test uses ULP-based comparison to automatically pick a default +// error bound that is appropriate for the operands. See the +// FloatingPoint template class in gtest-internal.h if you are +// interested in the implementation details. + +#define EXPECT_FLOAT_EQ(expected, actual)\ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ, \ + expected, actual) + +#define EXPECT_DOUBLE_EQ(expected, actual)\ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ, \ + expected, actual) + +#define ASSERT_FLOAT_EQ(expected, actual)\ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ, \ + expected, actual) + +#define ASSERT_DOUBLE_EQ(expected, actual)\ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ, \ + expected, actual) + +#define EXPECT_NEAR(val1, val2, abs_error)\ + EXPECT_PRED_FORMAT3(::testing::internal::DoubleNearPredFormat, \ + val1, val2, abs_error) + +#define ASSERT_NEAR(val1, val2, abs_error)\ + ASSERT_PRED_FORMAT3(::testing::internal::DoubleNearPredFormat, \ + val1, val2, abs_error) + +// These predicate format functions work on floating-point values, and +// can be used in {ASSERT|EXPECT}_PRED_FORMAT2*(), e.g. +// +// EXPECT_PRED_FORMAT2(testing::DoubleLE, Foo(), 5.0); + +// Asserts that val1 is less than, or almost equal to, val2. Fails +// otherwise. In particular, it fails if either val1 or val2 is NaN. +GTEST_API_ AssertionResult FloatLE(const char* expr1, const char* expr2, + float val1, float val2); +GTEST_API_ AssertionResult DoubleLE(const char* expr1, const char* expr2, + double val1, double val2); + + +#if GTEST_OS_WINDOWS + +// Macros that test for HRESULT failure and success, these are only useful +// on Windows, and rely on Windows SDK macros and APIs to compile. +// +// * {ASSERT|EXPECT}_HRESULT_{SUCCEEDED|FAILED}(expr) +// +// When expr unexpectedly fails or succeeds, Google Test prints the +// expected result and the actual result with both a human-readable +// string representation of the error, if available, as well as the +// hex result code. +#define EXPECT_HRESULT_SUCCEEDED(expr) \ + EXPECT_PRED_FORMAT1(::testing::internal::IsHRESULTSuccess, (expr)) + +#define ASSERT_HRESULT_SUCCEEDED(expr) \ + ASSERT_PRED_FORMAT1(::testing::internal::IsHRESULTSuccess, (expr)) + +#define EXPECT_HRESULT_FAILED(expr) \ + EXPECT_PRED_FORMAT1(::testing::internal::IsHRESULTFailure, (expr)) + +#define ASSERT_HRESULT_FAILED(expr) \ + ASSERT_PRED_FORMAT1(::testing::internal::IsHRESULTFailure, (expr)) + +#endif // GTEST_OS_WINDOWS + +// Macros that execute statement and check that it doesn't generate new fatal +// failures in the current thread. +// +// * {ASSERT|EXPECT}_NO_FATAL_FAILURE(statement); +// +// Examples: +// +// EXPECT_NO_FATAL_FAILURE(Process()); +// ASSERT_NO_FATAL_FAILURE(Process()) << "Process() failed"; +// +#define ASSERT_NO_FATAL_FAILURE(statement) \ + GTEST_TEST_NO_FATAL_FAILURE_(statement, GTEST_FATAL_FAILURE_) +#define EXPECT_NO_FATAL_FAILURE(statement) \ + GTEST_TEST_NO_FATAL_FAILURE_(statement, GTEST_NONFATAL_FAILURE_) + +// Causes a trace (including the source file path, the current line +// number, and the given message) to be included in every test failure +// message generated by code in the current scope. The effect is +// undone when the control leaves the current scope. +// +// The message argument can be anything streamable to std::ostream. +// +// In the implementation, we include the current line number as part +// of the dummy variable name, thus allowing multiple SCOPED_TRACE()s +// to appear in the same block - as long as they are on different +// lines. +#define SCOPED_TRACE(message) \ + ::testing::internal::ScopedTrace GTEST_CONCAT_TOKEN_(gtest_trace_, __LINE__)(\ + __FILE__, __LINE__, ::testing::Message() << (message)) + +namespace internal { + +// This template is declared, but intentionally undefined. +template +struct StaticAssertTypeEqHelper; + +template +struct StaticAssertTypeEqHelper {}; + +} // namespace internal + +// Compile-time assertion for type equality. +// StaticAssertTypeEq() compiles iff type1 and type2 are +// the same type. The value it returns is not interesting. +// +// Instead of making StaticAssertTypeEq a class template, we make it a +// function template that invokes a helper class template. This +// prevents a user from misusing StaticAssertTypeEq by +// defining objects of that type. +// +// CAVEAT: +// +// When used inside a method of a class template, +// StaticAssertTypeEq() is effective ONLY IF the method is +// instantiated. For example, given: +// +// template class Foo { +// public: +// void Bar() { testing::StaticAssertTypeEq(); } +// }; +// +// the code: +// +// void Test1() { Foo foo; } +// +// will NOT generate a compiler error, as Foo::Bar() is never +// actually instantiated. Instead, you need: +// +// void Test2() { Foo foo; foo.Bar(); } +// +// to cause a compiler error. +template +bool StaticAssertTypeEq() { + internal::StaticAssertTypeEqHelper(); + return true; +} + +// Defines a test. +// +// The first parameter is the name of the test case, and the second +// parameter is the name of the test within the test case. +// +// The convention is to end the test case name with "Test". For +// example, a test case for the Foo class can be named FooTest. +// +// The user should put his test code between braces after using this +// macro. Example: +// +// TEST(FooTest, InitializesCorrectly) { +// Foo foo; +// EXPECT_TRUE(foo.StatusIsOK()); +// } + +// Note that we call GetTestTypeId() instead of GetTypeId< +// ::testing::Test>() here to get the type ID of testing::Test. This +// is to work around a suspected linker bug when using Google Test as +// a framework on Mac OS X. The bug causes GetTypeId< +// ::testing::Test>() to return different values depending on whether +// the call is from the Google Test framework itself or from user test +// code. GetTestTypeId() is guaranteed to always return the same +// value, as it always calls GetTypeId<>() from the Google Test +// framework. +#define GTEST_TEST(test_case_name, test_name)\ + GTEST_TEST_(test_case_name, test_name, \ + ::testing::Test, ::testing::internal::GetTestTypeId()) + +// Define this macro to 1 to omit the definition of TEST(), which +// is a generic name and clashes with some other libraries. +#if !GTEST_DONT_DEFINE_TEST +#define TEST(test_case_name, test_name) GTEST_TEST(test_case_name, test_name) +#endif + +// Defines a test that uses a test fixture. +// +// The first parameter is the name of the test fixture class, which +// also doubles as the test case name. The second parameter is the +// name of the test within the test case. +// +// A test fixture class must be declared earlier. The user should put +// his test code between braces after using this macro. Example: +// +// class FooTest : public testing::Test { +// protected: +// virtual void SetUp() { b_.AddElement(3); } +// +// Foo a_; +// Foo b_; +// }; +// +// TEST_F(FooTest, InitializesCorrectly) { +// EXPECT_TRUE(a_.StatusIsOK()); +// } +// +// TEST_F(FooTest, ReturnsElementCountCorrectly) { +// EXPECT_EQ(0, a_.size()); +// EXPECT_EQ(1, b_.size()); +// } + +#define TEST_F(test_fixture, test_name)\ + GTEST_TEST_(test_fixture, test_name, test_fixture, \ + ::testing::internal::GetTypeId()) + +// Use this macro in main() to run all tests. It returns 0 if all +// tests are successful, or 1 otherwise. +// +// RUN_ALL_TESTS() should be invoked after the command line has been +// parsed by InitGoogleTest(). + +#define RUN_ALL_TESTS()\ + (::testing::UnitTest::GetInstance()->Run()) + +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_GTEST_H_ diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmDataValueField.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmDataValueField.h new file mode 100644 index 0000000000..160ca98a70 --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmDataValueField.h @@ -0,0 +1,108 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2013 Ceetron AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## +#ifndef CAF_IS_DEFINING_PDM_FIELD +#pragma once +#endif + +#include "cafPdmValueField.h" +#include "cafInternalPdmValueFieldSpecializations.h" + +#include +#include + + +namespace caf +{ + +class PdmObjectHandle; + +//================================================================================================== +/// Field class encapsulating data with input and output of this data to/from a QXmlStream +/// read/write-FieldData is supposed to be specialized for types needing specialization +//================================================================================================== + +template +class PdmDataValueField : public PdmValueField +{ +public: + typedef DataType FieldDataType; + PdmDataValueField() {} + PdmDataValueField(const PdmDataValueField& other) { m_fieldValue = other.m_fieldValue; } + explicit PdmDataValueField(const DataType& fieldValue) { m_fieldValue = fieldValue; } + virtual ~PdmDataValueField() {} + + // Assignment + + PdmDataValueField& operator= (const PdmDataValueField& other) { m_fieldValue = other.m_fieldValue; return *this; } + PdmDataValueField& operator= (const DataType& fieldValue) { m_fieldValue = fieldValue; return *this; } + + // Basic access + + DataType value() const { return m_fieldValue; } + void setValue(const DataType& fieldValue) { m_fieldValue = fieldValue; } + + // Implementation of PdmValueField interface + + virtual QVariant toQVariant() const { return PdmValueFieldSpecialization::convert(m_fieldValue); } + virtual void setFromQVariant(const QVariant& variant) { PdmValueFieldSpecialization::setFromVariant(variant, m_fieldValue); } + virtual bool isReadOnly() const { return false; } + + // Access operators + + /*Conversion */ operator DataType () const { return m_fieldValue; } + const DataType& operator()() const { return m_fieldValue; } + + DataType& v() { return m_fieldValue; } // This one breaches encapsulation. Remove ? + const DataType& v() const { return m_fieldValue; } + + bool operator== (const DataType& fieldValue) const { return m_fieldValue == fieldValue; } + +protected: + DataType m_fieldValue; + + // Default value stuff. + // + // This is not used enough. Remove when dust has settled. + // ResInsight uses at one point to find whether the value is changed by the user +public: + const DataType& defaultValue() const { return m_defaultFieldValue; } + void setDefaultValue(const DataType& val) { m_defaultFieldValue = val; } +protected: + DataType m_defaultFieldValue; + +}; + +} // End of namespace caf diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmFieldCapability.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmFieldCapability.h new file mode 100644 index 0000000000..9272a62325 --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmFieldCapability.h @@ -0,0 +1,14 @@ +#pragma once + +namespace caf +{ + +class PdmFieldCapability +{ +public: + PdmFieldCapability() {} + virtual ~PdmFieldCapability() {} + +}; + +} // End of namespace caf diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmFieldHandle.cpp b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmFieldHandle.cpp new file mode 100644 index 0000000000..55c0f727d8 --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmFieldHandle.cpp @@ -0,0 +1,84 @@ +#include "cafPdmFieldHandle.h" + +#include "cafPdmFieldCapability.h" + +#include + +namespace caf +{ + +#if 0 +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool PdmFieldHandle::assertValid() const +{ + if (m_keyword == "UNDEFINED") + { + std::cout << "PdmField: Detected use of non-initialized field. Did you forget to do CAF_PDM_InitField() on this field ?\n"; + return false; + } + + if (!PdmXmlSerializable::isValidXmlElementName(m_keyword)) + { + std::cout << "PdmField: The supplied keyword: \"" << m_keyword.toStdString() << "\" is an invalid XML element name, and will break your file format!\n"; + return false; + } + + return true; +} +#endif + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmFieldHandle::setKeyword(const QString& keyword) +{ + m_keyword = keyword; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool PdmFieldHandle::hasChildObjects() +{ + std::vector children; + this->childObjects(&children); + return (children.size() > 0); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +PdmFieldHandle::~PdmFieldHandle() +{ + for (size_t i = 0; i < m_capabilities.size(); ++i) + { + if (m_capabilities[i].second) delete m_capabilities[i].first; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool PdmFieldHandle::hasPtrReferencedObjects() +{ + std::vector ptrReffedObjs; + this->ptrReferencedObjects(&ptrReffedObjs); + return (ptrReffedObjs.size() > 0); +} + +// These two functions can be used when PdmCore is used standalone without PdmUi/PdmXml +/* +PdmUiFieldHandle* PdmFieldHandle::uiCapability() +{ + return NULL; +} + +PdmXmlFieldHandle* PdmFieldHandle::xmlCapability() +{ + return NULL; +} +*/ + +} // End of namespace caf diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmFieldHandle.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmFieldHandle.h new file mode 100644 index 0000000000..c6cc4cea1c --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmFieldHandle.h @@ -0,0 +1,74 @@ +#pragma once + +#include "cafPdmBase.h" +#include +#include + +namespace caf +{ + +class PdmObjectHandle; +class PdmUiFieldHandle; +class PdmXmlFieldHandle; + +//================================================================================================== +/// Base class for all fields, making it possible to handle them generically +//================================================================================================== +class PdmFieldCapability; + +class PdmFieldHandle +{ +public: + PdmFieldHandle() { m_ownerObject = NULL; } + virtual ~PdmFieldHandle(); + + QString keyword() const { return m_keyword; } + + PdmObjectHandle* ownerObject() { return m_ownerObject; } + + // Child objects + bool hasChildObjects(); + virtual void childObjects(std::vector*) { } + virtual void removeChildObject(PdmObjectHandle*) { } + + // Ptr referenced objects + bool hasPtrReferencedObjects(); + virtual void ptrReferencedObjects(std::vector*) { } + + // Capabilities + void addCapability(PdmFieldCapability* capability, bool takeOwnership) { m_capabilities.push_back(std::make_pair(capability, takeOwnership)); } + + template + CapabilityType* capability(); + + PdmUiFieldHandle* uiCapability(); + PdmXmlFieldHandle* xmlCapability(); + +private: + PDM_DISABLE_COPY_AND_ASSIGN(PdmFieldHandle); + + friend class PdmObjectHandle; // Give access to m_ownerObject and set Keyword + void setKeyword(const QString& keyword); + PdmObjectHandle* m_ownerObject; + + QString m_keyword; + + std::vector > m_capabilities; +}; + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +template +CapabilityType* PdmFieldHandle::capability() +{ + for (size_t i = 0; i < m_capabilities.size(); ++i) + { + CapabilityType* capability = dynamic_cast(m_capabilities[i].first); + if (capability) return capability; + } + return NULL; +} + +} // End of namespace caf diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmObjectCapability.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmObjectCapability.h new file mode 100644 index 0000000000..e8c81c5117 --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmObjectCapability.h @@ -0,0 +1,14 @@ +#pragma once + +namespace caf +{ + +class PdmObjectCapability +{ +public: + PdmObjectCapability() {} + virtual ~PdmObjectCapability() {} + +}; + +} // End namespace caf diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmObjectHandle.cpp b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmObjectHandle.cpp new file mode 100644 index 0000000000..2124871255 --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmObjectHandle.cpp @@ -0,0 +1,163 @@ + +#include "cafPdmObjectHandle.h" + +#include "cafPdmFieldHandle.h" +#include "cafPdmObjectCapability.h" + +#include + + +namespace caf +{ + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +PdmObjectHandle::~PdmObjectHandle() +{ + for (size_t i = 0; i < m_capabilities.size(); ++i) + { + if (m_capabilities[i].second) delete m_capabilities[i].first; + } + + // Set all guarded pointers pointing to this to NULL + + std::set::iterator it; + for (it = m_pointersReferencingMe.begin(); it != m_pointersReferencingMe.end() ; ++it) + { + (**it) = NULL; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmObjectHandle::fields(std::vector& fields) const +{ + fields = m_fields; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmObjectHandle::setAsParentField(PdmFieldHandle* parentField) +{ + assert(m_parentField == NULL); + + m_parentField = parentField; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmObjectHandle::removeAsParentField(PdmFieldHandle* parentField) +{ + assert(m_parentField == parentField); + + m_parentField = NULL; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmObjectHandle::addReferencingPtrField(PdmFieldHandle* fieldReferringToMe) +{ + if (fieldReferringToMe != NULL) m_referencingPtrFields.insert(fieldReferringToMe); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmObjectHandle::removeReferencingPtrField(PdmFieldHandle* fieldReferringToMe) +{ + if (fieldReferringToMe != NULL) m_referencingPtrFields.erase(fieldReferringToMe); +} + +//-------------------------------------------------------------------------------------------------- +/// Appends pointers to all the PdmPtrFields containing a pointer to this object. +/// As the PdmPtrArrayFields can hold several pointers to the same object, the returned vector can +/// contain multiple pointers to the same field. +//-------------------------------------------------------------------------------------------------- +void PdmObjectHandle::referringPtrFields(std::vector& fieldsReferringToMe) const +{ + std::multiset::const_iterator it; + + for (it = m_referencingPtrFields.begin(); it != m_referencingPtrFields.end(); ++it) + { + fieldsReferringToMe.push_back(*it); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmObjectHandle::objectsWithReferringPtrFields(std::vector& objects) const +{ + std::vector parentFields; + this->referringPtrFields(parentFields); + size_t i; + for (i = 0; i < parentFields.size(); i++) + { + objects.push_back(parentFields[i]->ownerObject()); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmObjectHandle::addField(PdmFieldHandle* field, const QString& keyword) +{ + field->m_ownerObject = this; + + assert(!keyword.isEmpty()); + assert(this->findField(keyword) == NULL); + + field->setKeyword(keyword); + m_fields.push_back(field); +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +PdmFieldHandle* PdmObjectHandle::findField(const QString& keyword) +{ + std::vector fields; + this->fields(fields); + + for (size_t it = 0; it < fields.size(); it++) + { + PdmFieldHandle* field = fields[it]; + if (field->keyword() == keyword) + { + return field; + } + } + + return NULL; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +PdmFieldHandle* PdmObjectHandle::parentField() const +{ + return m_parentField; +} + +// These two functions can be used when PdmCore is used standalone without PdmUi/PdmXml +/* +PdmUiObjectHandle* PdmObjectHandle::uiCapability() +{ +return NULL; +} + +PdmXmlObjectHandle* PdmObjectHandle::xmlCapability() +{ +return NULL; +} +*/ + + +} // End namespace caf diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmObjectHandle.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmObjectHandle.h new file mode 100644 index 0000000000..1536ba1c80 --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmObjectHandle.h @@ -0,0 +1,152 @@ +#pragma once + +#include "cafPdmBase.h" + +class QString; + +#include +#include + + +namespace caf +{ + +class PdmObjectCapability; +class PdmFieldHandle; +class PdmUiObjectHandle; +class PdmXmlObjectHandle; + +//================================================================================================== +/// The base class of all objects +//================================================================================================== +class PdmObjectHandle +{ +public: + PdmObjectHandle() { m_parentField = NULL; } + virtual ~PdmObjectHandle(); + + /// The registered fields contained in this PdmObject. + void fields(std::vector& fields) const; + PdmFieldHandle* findField(const QString& keyword); + + /// The field referencing this object as a child + PdmFieldHandle* parentField() const; + /// Convenience function. Traverses from parent to parents parent to find first object of the requested type. + template + void firstAnchestorOrThisOfType(T*& ancestor) const; + + // PtrReferences + /// The PdmPtrField's containing pointers to this PdmObjecthandle + /// Use ownerObject() on the fieldHandle to get the PdmObjectHandle + void referringPtrFields(std::vector& fieldsReferringToMe) const; + /// Convenience method to get the objects pointing to this field + void objectsWithReferringPtrFields(std::vector& objects) const; + + // Object capabilities + void addCapability(PdmObjectCapability* capability, bool takeOwnership) { m_capabilities.push_back(std::make_pair(capability, takeOwnership)); } + + template + CapabilityType* capability() + { + for (size_t i = 0; i < m_capabilities.size(); ++i) + { + CapabilityType* capability = dynamic_cast(m_capabilities[i].first); + if (capability) return capability; + } + return NULL; + } + + PdmUiObjectHandle* uiCapability(); // Implementation is in cafPdmUiObjectHandle.cpp + PdmXmlObjectHandle* xmlCapability(); // Implementation is in cafPdmXmlObjectHandle.cpp + +protected: + void addField(PdmFieldHandle* field, const QString& keyword); + +private: + PDM_DISABLE_COPY_AND_ASSIGN(PdmObjectHandle); + + // Fields + std::vector m_fields; + + // Capabilities + std::vector > m_capabilities; + + // Child/Parent Relationships + void setAsParentField(PdmFieldHandle* parentField); + void removeAsParentField(PdmFieldHandle* parentField); + PdmFieldHandle* m_parentField; + + // PtrReferences + void addReferencingPtrField(PdmFieldHandle* fieldReferringToMe); + void removeReferencingPtrField(PdmFieldHandle* fieldReferringToMe); + std::multiset m_referencingPtrFields; + + // Give access to set/removeAsParentField + template < class T > friend class PdmChildArrayField; + template < class T > friend class PdmChildField; + template < class T > friend class PdmPtrField; + template < class T > friend class PdmField; // For backwards compatibility layer + + template < class T > friend class PdmFieldXmlCap; + + static const char* classKeywordStatic() { return "PdmObjectHandle";} // For PdmXmlFieldCap to be able to handle fields of PdmObjectHandle directly + + // Support system for PdmPointer + friend class PdmPointerImpl; + std::set m_pointersReferencingMe; +}; +} + +#include "cafPdmFieldHandle.h" + +namespace caf +{ +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +template +void PdmObjectHandle::firstAnchestorOrThisOfType(T*& ancestor) const +{ + ancestor = NULL; + + // Check if this matches the type + + const T* objectOfType = dynamic_cast(this); + if (objectOfType) + { + ancestor = const_cast(objectOfType); + return; + } + + // Search anchestors + + PdmObjectHandle* parent = NULL; + PdmFieldHandle* parentField = this->parentField(); + if (parentField) parent = parentField->ownerObject(); + + while (parent != NULL) + { + T* objectOfType = dynamic_cast(parent); + if (objectOfType) + { + ancestor = objectOfType; + return; + } + + // Get next level parent + + PdmFieldHandle* nextParentField = parent->parentField(); + + if (nextParentField) + { + parent = nextParentField->ownerObject(); + } + else + { + parent = NULL; + } + } +} + +} // End of namespace caf + diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmPointer.cpp b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmPointer.cpp similarity index 92% rename from Fwk/AppFwk/cafProjectDataModel/cafPdmPointer.cpp rename to Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmPointer.cpp index 1ab0948343..0976eb4991 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmPointer.cpp +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmPointer.cpp @@ -34,7 +34,7 @@ // //################################################################################################## -#include "cafPdmObject.h" +#include "cafPdmObjectHandle.h" #include "cafPdmPointer.h" namespace caf @@ -44,7 +44,7 @@ namespace caf //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void PdmPointerImpl::addReference(PdmObject ** addressToObjectPointer) +void PdmPointerImpl::addReference(PdmObjectHandle ** addressToObjectPointer) { if (*addressToObjectPointer) (*addressToObjectPointer)->m_pointersReferencingMe.insert(addressToObjectPointer); } @@ -52,7 +52,7 @@ void PdmPointerImpl::addReference(PdmObject ** addressToObjectPointer) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void PdmPointerImpl::removeReference(PdmObject ** addressToObjectPointer) +void PdmPointerImpl::removeReference(PdmObjectHandle ** addressToObjectPointer) { if (*addressToObjectPointer) (*addressToObjectPointer)->m_pointersReferencingMe.erase(addressToObjectPointer); } diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmPointer.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmPointer.h similarity index 78% rename from Fwk/AppFwk/cafProjectDataModel/cafPdmPointer.h rename to Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmPointer.h index c9ca2359fd..b9caaf2d58 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmPointer.h +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmPointer.h @@ -37,11 +37,13 @@ #pragma once +#include + namespace caf { -class PdmObject; +class PdmObjectHandle; //================================================================================================== /// Helper class for the PdmPointer class @@ -58,8 +60,8 @@ class PdmPointerImpl { private: template < class T > friend class PdmPointer; - static void addReference(PdmObject ** addressToObjectPointer); - static void removeReference(PdmObject ** addressToObjectPointer); + static void addReference(PdmObjectHandle ** addressToObjectPointer); + static void removeReference(PdmObjectHandle ** addressToObjectPointer); }; //================================================================================================== @@ -74,7 +76,7 @@ class PdmPointerImpl template < class T > class PdmPointer { - PdmObject* m_object; + PdmObjectHandle* m_object; public : inline PdmPointer () : m_object(NULL) { } inline PdmPointer ( T * p ) : m_object(p) { PdmPointerImpl::addReference(&m_object); } @@ -82,18 +84,21 @@ public : { PdmPointerImpl::addReference(&m_object); } inline ~PdmPointer () { PdmPointerImpl::removeReference(&m_object); } - T* p() const { return static_cast(const_cast(m_object)); } - bool isNull() const { return !m_object; } - bool notNull() const { return !isNull(); } - operator T* () const { return static_cast(const_cast(m_object)); } - T& operator* () const { return *static_cast(const_cast(m_object)); } - T* operator->() const { return static_cast(const_cast(m_object)); } + T* p() const { return static_cast(const_cast(m_object)); } + bool isNull() const { return !m_object; } + bool notNull() const { return !isNull(); } + operator T* () const { return static_cast(const_cast(m_object)); } + T& operator* () const { return *static_cast(const_cast(m_object)); } + T* operator->() const { return static_cast(const_cast(m_object)); } PdmPointer & operator= ( const PdmPointer& p ) { if (this != &p) PdmPointerImpl::removeReference(&m_object); m_object = p.m_object; PdmPointerImpl::addReference(&m_object); return *this; } PdmPointer & operator= ( T* p ) { if (m_object != p) PdmPointerImpl::removeReference(&m_object); m_object = p; PdmPointerImpl::addReference(&m_object); return *this; } // Private methods used by PdmField and PdmPointersField. Do not use unless you mean it ! - PdmObject* rawPtr() const { return m_object; } - void setRawPtr( PdmObject* p) { if (m_object != p) PdmPointerImpl::removeReference(&m_object); m_object = p; PdmPointerImpl::addReference(&m_object); } + PdmObjectHandle* rawPtr() const { return m_object; } + void setRawPtr( PdmObjectHandle* p) { if (m_object != p) PdmPointerImpl::removeReference(&m_object); m_object = p; PdmPointerImpl::addReference(&m_object); } }; + + } // End of namespace caf + diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmProxyValueField.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmProxyValueField.h new file mode 100644 index 0000000000..af9bfa8703 --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmProxyValueField.h @@ -0,0 +1,137 @@ +#pragma once + +#include "cafPdmFieldHandle.h" +#include "cafPdmPointer.h" + +#include "cafPdmValueField.h" +#include "cafInternalPdmValueFieldSpecializations.h" + +#include + +#include + +namespace caf +{ +//================================================================================================== +/// Field class encapsulating data access through object setter/getter with input and output of this +/// data to/from a QXmlStream +/// read/write-FieldData is supposed to be specialized for types needing specialization +//================================================================================================== + +template +class PdmProxyValueField : public PdmValueField +{ +public: + typedef DataType FieldDataType; + PdmProxyValueField() { m_valueSetter = NULL; m_valueGetter = NULL; } + virtual ~PdmProxyValueField() { if (m_valueSetter) delete m_valueSetter; if (m_valueGetter) delete m_valueGetter; } + + // Assignment + + PdmProxyValueField& operator= (const DataType& newFieldValue) { setValue(newFieldValue); return *this; } + + // Basic access + + void setValue(const DataType& fieldValue) { if (m_valueSetter) m_valueSetter->setValue(fieldValue); } + DataType value() const { assert(m_valueGetter); return m_valueGetter->getValue(); } + + // Implementation of PdmValueField interface + + virtual QVariant toQVariant() const { DataType val = value(); return PdmValueFieldSpecialization::convert(val); } + virtual void setFromQVariant(const QVariant& variant) { DataType val; PdmValueFieldSpecialization::setFromVariant(variant, val); setValue(val); } + virtual bool isReadOnly() const { if (!m_valueSetter) { return true; } else { return false; } } + + // Access operators + + DataType operator()() const { return value(); } + DataType v() const { return value(); } + bool operator== (const DataType& otherValue) const { return value() == otherValue; } + +private: + PDM_DISABLE_COPY_AND_ASSIGN(PdmProxyValueField); + + // Proxy Field stuff to handle the method pointers + // The public registering methods must be written below the private classes + // For some reason. Forward declaration did some weirdness. +private: + class SetValueInterface + { + public: + virtual ~SetValueInterface() {} + virtual void setValue(const DataType& value) = 0; + }; + + template + class SetterMethodCB : public SetValueInterface + { + public: + typedef void (ObjectType::*SetterMethodType)(const DataType& value); + + SetterMethodCB(ObjectType* obj, SetterMethodType setterMethod) + { + m_setterMethod = setterMethod; + m_obj = obj; + } + + void setValue(const DataType& value) + { + (m_obj->*m_setterMethod)(value); + } + + private: + SetterMethodType m_setterMethod; + PdmPointer m_obj; + }; + + class GetValueInterface + { + public: + virtual ~GetValueInterface() {} + virtual DataType getValue() const = 0; + }; + + template + class GetterMethodCB : public GetValueInterface + { + public: + typedef DataType (ObjectType::*GetterMethodType)() const; + + GetterMethodCB(ObjectType* obj, GetterMethodType setterMethod) + { + m_getterMethod = setterMethod; + m_obj = obj; + } + + DataType getValue() const + { + return (m_obj->*m_getterMethod)(); + } + + private: + GetterMethodType m_getterMethod; + PdmPointer< ObjectType> m_obj; + }; + +public: + template + void registerSetMethod(OwnerObjectType* obj, typename SetterMethodCB< OwnerObjectType>::SetterMethodType setterMethod) + { + if (m_valueSetter) delete m_valueSetter; + m_valueSetter = new SetterMethodCB(obj, setterMethod); + } + + template + void registerGetMethod(OwnerObjectType* obj, typename GetterMethodCB< OwnerObjectType>::GetterMethodType getterMethod) + { + if (m_valueGetter) delete m_valueGetter; + m_valueGetter = new GetterMethodCB(obj, getterMethod); + } + +private: + + SetValueInterface* m_valueSetter; + GetValueInterface* m_valueGetter; +}; + +} // End of namespace caf + diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmPtrField.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmPtrField.h new file mode 100644 index 0000000000..dd840645d2 --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmPtrField.h @@ -0,0 +1,91 @@ +#pragma once + +#include "cafPdmPointer.h" + +#include "cafPdmFieldHandle.h" +#include + +namespace caf +{ + +template< typename T> class PdmFieldXmlCap; + +//================================================================================================== +/// A field that contains a pointer to a PdmObjectHandle derived object. +/// The referenced object will not be printed in the XML-output yet, but +/// it is intended to be written as a reference (by path from common root) +/// This field has nothing to do with ownership at all, and is not a part of the +/// parent-child relations induced by the other PdmChildField PdmChildArrayField +/// The pointer is guarded, meaning that it will be set to NULL if the object pointed to +/// is deleted. +//================================================================================================== + +template +class PdmPtrField : public PdmFieldHandle +{ +public: + PdmPtrField() + { + bool doNotUsePdmPtrFieldForAnythingButPointersToPdmObject = false; assert(doNotUsePdmPtrFieldForAnythingButPointersToPdmObject); + } +}; + +template +class PdmPtrField : public PdmFieldHandle +{ + typedef DataType* DataTypePtr; +public: + typedef PdmPointer FieldDataType; + + PdmPtrField() { m_referenceString = ""; m_isResolved = false; } + explicit PdmPtrField(const DataTypePtr& fieldValue); + virtual ~PdmPtrField(); + + // Assignment + + PdmPtrField& operator= (const DataTypePtr & fieldValue); + PdmPtrField& operator= (const FieldDataType & fieldValue); + + // Basic access + + DataType* value() const { return m_fieldValue; } + void setValue(const DataTypePtr& fieldValue); + + // Access operators + + /*Conversion*/ operator DataType* () const { return m_fieldValue; } + DataType* operator->() const { return m_fieldValue; } + + const PdmPointer& operator()() const { return m_fieldValue; } + const PdmPointer& v() const { return m_fieldValue; } + + bool operator==(const DataTypePtr& fieldValue) { return m_fieldValue == fieldValue; } + + // Child objects + + virtual void childObjects(std::vector*); + + // Ptr referenced objects + + virtual void ptrReferencedObjects(std::vector* objectsToFill); + + +private: + PDM_DISABLE_COPY_AND_ASSIGN(PdmPtrField); + + friend class PdmFieldXmlCap< PdmPtrField >; + void setRawPtr(PdmObjectHandle* obj); + + PdmPointer m_fieldValue; + + // Resolving + QString m_referenceString; + bool m_isResolved; +}; + +} // End of namespace caf + +#include "cafPdmPtrField.inl" + +#include +Q_DECLARE_METATYPE(caf::PdmPointer); diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmPtrField.inl b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmPtrField.inl new file mode 100644 index 0000000000..55ce13265b --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmPtrField.inl @@ -0,0 +1,104 @@ +namespace caf +{ + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +template +caf::PdmPtrField::PdmPtrField(const DataTypePtr& fieldValue) +{ + m_fieldValue = fieldValue; + if (m_fieldValue != NULL) m_fieldValue->addReferencingPtrField(this); +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +template +caf::PdmPtrField::~PdmPtrField() +{ + if (!m_fieldValue.isNull()) m_fieldValue.rawPtr()->removeReferencingPtrField(this); + m_fieldValue.setRawPtr(NULL); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +template +void PdmPtrField::setValue(const DataTypePtr& fieldValue) +{ + if (m_fieldValue) m_fieldValue->removeReferencingPtrField(this); + m_fieldValue = fieldValue; + if (m_fieldValue != NULL) m_fieldValue->addReferencingPtrField(this); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +template +void PdmPtrField::setRawPtr(PdmObjectHandle* obj) +{ + if (m_fieldValue.notNull()) m_fieldValue.rawPtr()->removeReferencingPtrField(this); + m_fieldValue.setRawPtr(obj); + if (m_fieldValue.notNull()) m_fieldValue.rawPtr()->addReferencingPtrField(this); +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +template +caf::PdmPtrField& PdmPtrField::operator=(const DataTypePtr & fieldValue) +{ + if (m_fieldValue) m_fieldValue->removeReferencingPtrField(this); + m_fieldValue = fieldValue; + if (m_fieldValue != NULL) m_fieldValue->addReferencingPtrField(this); + + return *this; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +template +caf::PdmPtrField& PdmPtrField::operator=(const FieldDataType & fieldValue) +{ + if (m_fieldValue) m_fieldValue->removeReferencingPtrField(this); + m_fieldValue = fieldValue; + if (m_fieldValue != NULL) m_fieldValue->addReferencingPtrField(this); + + return *this; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +template +void caf::PdmPtrField::childObjects(std::vector* objects) +{ + assert(objects); + PdmObjectHandle* obj = m_fieldValue.rawPtr(); + if (obj) + { + objects->push_back(obj); + } +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +template +void PdmPtrField::ptrReferencedObjects(std::vector* objectsToFill) +{ + if (m_fieldValue.rawPtr()) + { + objectsToFill->push_back(m_fieldValue.rawPtr()); + } +} + +} // End of namespace caf + diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmReferenceHelper.cpp b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmReferenceHelper.cpp new file mode 100644 index 0000000000..1427e59c1a --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmReferenceHelper.cpp @@ -0,0 +1,371 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2013 Ceetron AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + + +#include "cafPdmReferenceHelper.h" + +#include "cafPdmFieldHandle.h" + +#include + +#include +#include + + +namespace caf +{ + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString PdmReferenceHelper::referenceFromRootToObject(PdmObjectHandle* root, PdmObjectHandle* obj) +{ + if (obj == NULL || root == NULL) return QString(); + + QStringList objectNames = referenceFromRootToObjectAsStringList(root, obj); + + QString completeReference = objectNames.join(" "); + return completeReference; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString PdmReferenceHelper::referenceFromRootToField(PdmObjectHandle* root, PdmFieldHandle* field) +{ + if (field == NULL || root == NULL) return QString(); + + PdmObjectHandle* owner = field->ownerObject(); + if (!owner) return QString(); // Should be assert ? + + QStringList refFromRootToField; + + refFromRootToField = referenceFromRootToObjectAsStringList(root, owner); + + refFromRootToField.push_front(field->keyword()); + + QString completeReference = refFromRootToField.join(" "); + return completeReference; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +PdmObjectHandle* PdmReferenceHelper::objectFromReference(PdmObjectHandle* root, const QString& reference) +{ + QStringList decodedReference = reference.split(" "); + + return objectFromReferenceStringList(root, decodedReference); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +PdmFieldHandle* PdmReferenceHelper::findField(PdmObjectHandle* object, const QString& fieldKeyword) +{ + if (object == NULL) return NULL; + + std::vector fields; + object->fields(fields); + + for (size_t i = 0; i < fields.size(); i++) + { + if (fields[i]->keyword() == fieldKeyword) + { + return fields[i]; + } + } + + return NULL; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QStringList PdmReferenceHelper::referenceFromRootToObjectAsStringList(PdmObjectHandle* root, PdmObjectHandle* obj) +{ + QStringList objectNames; + + if (obj != NULL && root) + { + if (obj == root) return objectNames; + + PdmObjectHandle* currentObject = obj; + + bool continueParsing = true; + while (continueParsing) + { + caf::PdmFieldHandle* parentField = currentObject->parentField(); + if (!parentField) + { + // Could not find a path from obj to root, obj and root are unrelated objects + return QStringList(); + } + + std::vector childObjects; + parentField->childObjects(&childObjects); + + if (childObjects.size() > 0) + { + int index = -1; + + for (size_t i = 0; i < childObjects.size(); i++) + { + if (childObjects[i] == currentObject) + { + index = static_cast(i); + } + } + + objectNames.push_front(QString::number(index)); + objectNames.push_front(parentField->keyword()); + } + else + { + continueParsing = false; + continue; + } + + PdmObjectHandle* ownerObject = parentField->ownerObject(); + if (!ownerObject) + { + // Could not find a path from obj to root, obj and root are unrelated objects + return QStringList(); + } + + if (ownerObject == root) + { + continueParsing = false; + continue; + } + + currentObject = ownerObject; + } + } + + return objectNames; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +PdmFieldHandle* PdmReferenceHelper::fieldFromReference(PdmObjectHandle* root, const QString& reference) +{ + QStringList decodedReference = reference.split(" "); + if (decodedReference.size() == 0) return NULL; + + QString fieldKeyword = decodedReference[0]; + decodedReference.pop_front(); + + PdmObjectHandle* parentObject = objectFromReferenceStringList(root, decodedReference); + return findField(parentObject, fieldKeyword); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +PdmObjectHandle* PdmReferenceHelper::objectFromReferenceStringList(PdmObjectHandle* root, const QStringList& reference) +{ + if (!root) return NULL; + + PdmObjectHandle* currentObject = root; + + int i = 0; + while (i < reference.size()) + { + QString fieldKeyword = reference.at(i++); + + PdmFieldHandle* fieldHandle = findField(currentObject, fieldKeyword); + if (!fieldHandle) + { + return NULL; + } + + std::vector childObjects; + fieldHandle->childObjects(&childObjects); + + if (childObjects.size() == 0) + { + return NULL; + } + + QString fieldIndex = reference.at(i++); + bool conversionOk = true; + int index = fieldIndex.toInt(&conversionOk); + if (!conversionOk) + { + return NULL; + } + + if (index < 0 || index > ((int)childObjects.size()) - 1) + { + return NULL; + } + + currentObject = childObjects[index]; + } + + return currentObject; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector findPathToObjectFromRoot(PdmObjectHandle* obj) +{ + std::vector objPath; + PdmObjectHandle* currentObj = obj; + while (currentObj) + { + objPath.push_back(currentObj); + if (currentObj->parentField()) + { + currentObj = currentObj->parentField()->ownerObject(); + } + else + { + currentObj = NULL; + } + } + + std::reverse(objPath.begin(), objPath.end()); + + return objPath; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString PdmReferenceHelper::referenceFromFieldToObject(PdmFieldHandle* fromField, PdmObjectHandle* toObj) +{ + if (!fromField || !toObj) return ""; + + PdmObjectHandle* fromObj = fromField->ownerObject(); + if (!fromObj) return ""; + + std::vector fromObjPath = findPathToObjectFromRoot(fromObj); + std::vector toObjPath = findPathToObjectFromRoot(toObj); + + // Make sure the objects actually have at least one common ancestor + if (fromObjPath.front() != toObjPath.front()) return NULL; + + bool anchestorIsEqual = true; + size_t idxToLastCommonAnchestor = 0; + while (anchestorIsEqual) + { + ++idxToLastCommonAnchestor; + if ( idxToLastCommonAnchestor >= fromObjPath.size() + || idxToLastCommonAnchestor >= toObjPath.size() + || fromObjPath[idxToLastCommonAnchestor] != toObjPath[idxToLastCommonAnchestor]) + { + anchestorIsEqual = false; + idxToLastCommonAnchestor -= 1; + } + } + + size_t levelCountToCommonAnchestor = (fromObjPath.size() - 1) - idxToLastCommonAnchestor; + + PdmObjectHandle* lastCommonAnchestor = fromObjPath[idxToLastCommonAnchestor]; + + QStringList referenceList = referenceFromRootToObjectAsStringList(lastCommonAnchestor, toObj); + + for (size_t i = 0; i < levelCountToCommonAnchestor; ++i) + { + referenceList.push_front(".."); + } + + QString completeReference = referenceList.join(" "); + + return completeReference; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +PdmObjectHandle* PdmReferenceHelper::objectFromFieldReference(PdmFieldHandle* fromField, const QString& reference) +{ + if (!fromField) return NULL; + if (reference.isEmpty()) return NULL; + + QStringList decodedReference = reference.split(" "); + PdmObjectHandle* lastCommonAnchestor = fromField->ownerObject(); + assert(lastCommonAnchestor); + assert(decodedReference.size()); + + while (decodedReference.front() == "..") + { + PdmFieldHandle* parentField = lastCommonAnchestor->parentField(); + if (!parentField) + { + // Error: Relative object reference has an invalid number of parent levels + return NULL; + } + + lastCommonAnchestor = parentField->ownerObject(); + assert(lastCommonAnchestor); + decodedReference.pop_front(); + } + + return objectFromReferenceStringList(lastCommonAnchestor, decodedReference); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +PdmObjectHandle* PdmReferenceHelper::findRoot(PdmObjectHandle* obj) +{ + std::vector path = findPathToObjectFromRoot(obj); + + if (path.size()) return path[0]; + else return NULL; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +PdmObjectHandle* PdmReferenceHelper::findRoot(PdmFieldHandle* field) +{ + if (field) + { + PdmObjectHandle* ownerObject = field->ownerObject(); + return findRoot(ownerObject); + } + + return NULL; +} + +} // end namespace caf diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmReferenceHelper.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmReferenceHelper.h new file mode 100644 index 0000000000..c68f6f460b --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmReferenceHelper.h @@ -0,0 +1,75 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2013 Ceetron AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + + +#pragma once + +#include "cafPdmObjectHandle.h" +#include "cafPdmPointer.h" + +class QStringList; + +namespace caf +{ + +//================================================================================================== +/// +//================================================================================================== +class PdmReferenceHelper +{ +public: + static PdmObjectHandle* findRoot(PdmObjectHandle* obj); + static PdmObjectHandle* findRoot(PdmFieldHandle* field); + + static QString referenceFromRootToField(PdmObjectHandle* root, PdmFieldHandle* field); + static QString referenceFromRootToObject(PdmObjectHandle* root, PdmObjectHandle* obj); + static PdmObjectHandle* objectFromReference(PdmObjectHandle* root, const QString& reference); + static PdmFieldHandle* fieldFromReference(PdmObjectHandle* root, const QString& reference); + + static QString referenceFromFieldToObject(PdmFieldHandle* fromField, PdmObjectHandle* toObj); + static PdmObjectHandle* objectFromFieldReference(PdmFieldHandle* fromField, const QString& reference); + +private: + static QStringList referenceFromRootToObjectAsStringList(PdmObjectHandle* root, PdmObjectHandle* obj); + static PdmObjectHandle* objectFromReferenceStringList(PdmObjectHandle* root, const QStringList& reference); + + static PdmFieldHandle* findField(PdmObjectHandle* object, const QString& fieldKeyword); + +}; + + + +} // end namespace caf diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmValueField.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmValueField.h new file mode 100644 index 0000000000..1de3c13714 --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmValueField.h @@ -0,0 +1,66 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2013 Ceetron AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## +#pragma once + + +#include "cafPdmFieldHandle.h" + +class QVariant; + +namespace caf +{ + + + +class PdmValueField : public PdmFieldHandle +{ +public: + virtual QVariant toQVariant() const = 0; + virtual void setFromQVariant(const QVariant& variant) = 0; + virtual bool isReadOnly() const = 0; +}; + + + +// class PdmProxyValueField : public PdmValueField +// { +// DataType value() const { assert(m_valueGetter); return m_valueGetter->getValue(); } +// void setValue(const DataType& fieldValue) { if (m_valueSetter) m_valueSetter->setValue(fieldValue); } +// } + + + +} // End of namespace caf diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmDocument.cpp b/Fwk/AppFwk/cafProjectDataModel/cafPdmDocument.cpp index 0dec597148..baa4fff955 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmDocument.cpp +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmDocument.cpp @@ -38,69 +38,20 @@ #include "cafPdmDocument.h" #include +#include namespace caf { -CAF_PDM_SOURCE_INIT(PdmObjectGroup, "PdmObjectGroup"); - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -PdmObjectGroup::PdmObjectGroup() -{ - CAF_PDM_InitObject("Object Group", "", "", ""); - CAF_PDM_InitFieldNoDefault(&objects, "PdmObjects","", "", "", "") -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -PdmObjectGroup::~PdmObjectGroup() -{ -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void PdmObjectGroup::deleteObjects() -{ - size_t it; - for (it = 0; it != objects.size(); ++it) - { - delete objects[it]; - } - removeNullPtrs(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void PdmObjectGroup::removeNullPtrs() -{ - objects.removeChildObject(NULL); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void PdmObjectGroup::addObject(PdmObject * obj) -{ - objects.push_back(obj); -} - - - - CAF_PDM_SOURCE_INIT(PdmDocument, "PdmDocument"); //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -PdmDocument::PdmDocument() +PdmDocument::PdmDocument() { - CAF_PDM_InitObject("File", "", "", ""); - CAF_PDM_InitField(&fileName, "DocumentFileName", QString(""), "File Name", "", "", ""); + CAF_PDM_InitFieldNoDefault(&fileName, "DocumentFileName", "File Name", "", "", ""); + } //-------------------------------------------------------------------------------------------------- @@ -133,15 +84,15 @@ void PdmDocument::readFile(QIODevice* xmlFile) // Error: This is not a Ceetron Pdm based xml document return; } - readFields(xmlStream); + readFields(xmlStream, PdmDefaultObjectFactory::instance()); } } // Ask all objects to initialize and set up internal datastructure and pointers // after everything is read from file - PdmDocument::initAfterReadTraversal(this); - PdmDocument::updateUiIconStateRecursively(this); + resolveReferencesRecursively(); + initAfterReadRecursively(); } //-------------------------------------------------------------------------------------------------- @@ -162,7 +113,7 @@ void PdmDocument::writeFile() void PdmDocument::writeFile(QIODevice* xmlFile) { // Ask all objects to make them ready to write themselves to file - PdmDocument::setupBeforeSaveTraversal(this); + setupBeforeSaveRecursively(); QXmlStreamWriter xmlStream(xmlFile); xmlStream.setAutoFormatting(true); @@ -180,14 +131,13 @@ void PdmDocument::writeFile(QIODevice* xmlFile) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void PdmDocument::setupBeforeSaveTraversal(PdmObject * object) +void PdmDocument::updateUiIconStateRecursively(PdmObjectHandle* object) { if (object == NULL) return; - std::vector fields; object->fields(fields); - - std::vector children; + + std::vector children; size_t fIdx; for (fIdx = 0; fIdx < fields.size(); ++fIdx) { @@ -197,63 +147,16 @@ void PdmDocument::setupBeforeSaveTraversal(PdmObject * object) size_t cIdx; for (cIdx = 0; cIdx < children.size(); ++cIdx) { - PdmDocument::setupBeforeSaveTraversal(children[cIdx]); - } - - object->setupBeforeSave(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void PdmDocument::initAfterReadTraversal(PdmObject* object) -{ - if (object == NULL) return; - - std::vector fields; - object->fields(fields); - - std::vector children; - size_t fIdx; - for (fIdx = 0; fIdx < fields.size(); ++fIdx) - { - if (fields[fIdx]) fields[fIdx]->childObjects(&children); + PdmDocument::updateUiIconStateRecursively(children[cIdx]); } - size_t cIdx; - for (cIdx = 0; cIdx < children.size(); ++cIdx) + PdmUiObjectHandle* uiObjectHandle = uiObj(object); + if (uiObjectHandle) { - PdmDocument::initAfterReadTraversal(children[cIdx]); + uiObjectHandle->updateUiIconFromToggleField(); } - - object->initAfterRead(); } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void PdmDocument::updateUiIconStateRecursively(PdmObject* object) -{ - if (object == NULL) return; - - std::vector fields; - object->fields(fields); - - std::vector children; - size_t fIdx; - for (fIdx = 0; fIdx < fields.size(); ++fIdx) - { - if (fields[fIdx]) fields[fIdx]->childObjects(&children); - } - - size_t cIdx; - for (cIdx = 0; cIdx < children.size(); ++cIdx) - { - PdmDocument::updateUiIconStateRecursively(children[cIdx]); - } - - object->updateUiIconFromToggleField(); -} } //End of namespace caf diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmDocument.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmDocument.h index 4fb204edd1..17dafdab4b 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmDocument.h +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmDocument.h @@ -43,46 +43,11 @@ namespace caf { -//================================================================================================== -/// The PdmObjectGroup serves as a container of unknown PdmObjects, and is inherited by -/// PdmDocument. Can be used to create sub assemblies. -/// This class should possibly be merged with PdmDocument. It is not clear whether it really has -/// a reusable value on its own. -//================================================================================================== -class PdmObjectGroup : public PdmObject -{ - CAF_PDM_HEADER_INIT; -public: - PdmObjectGroup(); - ~PdmObjectGroup(); - - PdmPointersField objects; - - void deleteObjects(); - void removeNullPtrs(); - void addObject(PdmObject * obj); - - template - void objectsByType(std::vector >* typedObjects ) const - { - if (!typedObjects) return; - size_t it; - for (it = 0; it != objects.size(); ++it) - { - T* obj = dynamic_cast(objects[it]); - if (obj) typedObjects->push_back(obj); - } - } - - template - void createCopyByType(std::vector >* copyOfTypedObjects) const; -}; - //================================================================================================== /// The PdmDocument class is the main class to do file based IO, /// and is also supposed to act as the overall container of the objects read. //================================================================================================== -class PdmDocument: public PdmObjectGroup +class PdmDocument: public PdmObject { CAF_PDM_HEADER_INIT; public: @@ -96,52 +61,10 @@ class PdmDocument: public PdmObjectGroup void readFile(QIODevice* device); void writeFile(QIODevice* device); - static void updateUiIconStateRecursively(PdmObject * root); - static void initAfterReadTraversal(PdmObject * root); - - static void setupBeforeSaveTraversal(PdmObject * root); - + static void updateUiIconStateRecursively(PdmObjectHandle* root); }; -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -template -void PdmObjectGroup::createCopyByType(std::vector >* copyOfTypedObjects) const -{ - std::vector > sourceTypedObjects; - objectsByType(&sourceTypedObjects); - - QString encodedXml; - { - // Write original objects to XML file - PdmObjectGroup typedObjectGroup; - for (size_t i = 0; i < sourceTypedObjects.size(); i++) - { - typedObjectGroup.addObject(sourceTypedObjects[i]); - PdmDocument::setupBeforeSaveTraversal(sourceTypedObjects[i]); - } - - QXmlStreamWriter xmlStream(&encodedXml); - xmlStream.setAutoFormatting(true); - - typedObjectGroup.writeFields(xmlStream); - } - - // Read back XML into object group, factory methods will be called that will create new objects - PdmObjectGroup destinationObjectGroup; - QXmlStreamReader xmlStream(encodedXml); - destinationObjectGroup.readFields(xmlStream); - - for (size_t it = 0; it < destinationObjectGroup.objects.size(); it++) - { - T* obj = dynamic_cast(destinationObjectGroup.objects[it]); - if (obj) copyOfTypedObjects->push_back(obj); - } -} - - } // End of namespace caf diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmField.cpp b/Fwk/AppFwk/cafProjectDataModel/cafPdmField.cpp deleted file mode 100644 index a266bb290b..0000000000 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmField.cpp +++ /dev/null @@ -1,203 +0,0 @@ -//################################################################################################## -// -// Custom Visualization Core library -// Copyright (C) 2011-2013 Ceetron AS -// -// This library may be used under the terms of either the GNU General Public License or -// the GNU Lesser General Public License as follows: -// -// GNU General Public License Usage -// This library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. -// -// See the GNU General Public License at <> -// for more details. -// -// GNU Lesser General Public License Usage -// This library is free software; you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation; either version 2.1 of the License, or -// (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. -// -// See the GNU Lesser General Public License at <> -// for more details. -// -//################################################################################################## - - -#include "cafPdmField.h" -#include "cafPdmObject.h" - -#include - -namespace caf -{ - -//-------------------------------------------------------------------------------------------------- -/// PdmFieldHandle implementations -//-------------------------------------------------------------------------------------------------- -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void PdmFieldIOHelper::skipCharactersAndComments(QXmlStreamReader& xmlStream) -{ - QXmlStreamReader::TokenType type; - while (!xmlStream.atEnd() && xmlStream.isCharacters() || xmlStream.isComment()) - { - type = xmlStream.readNext(); - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void PdmFieldIOHelper::skipComments(QXmlStreamReader& xmlStream) -{ - QXmlStreamReader::TokenType type; - while (!xmlStream.atEnd() && xmlStream.isComment()) - { - type = xmlStream.readNext(); - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool PdmFieldHandle::assertValid() const -{ - if (m_keyword == "UNDEFINED") - { - std::cout << "PdmField: Detected use of non-initialized field. Did you forget to do CAF_PDM_InitField() on this field ?\n"; - return false; - } - - if (!PdmObject::isValidXmlElementName(m_keyword)) - { - std::cout << "PdmField: The supplied keyword: \"" << m_keyword.toStdString() << "\" is an invalid XML element name, and will break your file format!\n"; - return false; - } - - return true; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void PdmFieldHandle::setKeyword(const QString& keyword) -{ - assert(PdmObject::isValidXmlElementName(keyword)); - - m_keyword = keyword; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool PdmFieldHandle::hasChildObjects() -{ - std::vector children; - this->childObjects(&children); - return (children.size() > 0); -} - -//-------------------------------------------------------------------------------------------------- -/// PdmObjectFactory implementations -//-------------------------------------------------------------------------------------------------- - - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -PdmObject * PdmObjectFactory::create(const QString& classNameKeyword) -{ - std::map::iterator entryIt; - entryIt = m_factoryMap.find(classNameKeyword); - if (entryIt != m_factoryMap.end()) - { - return entryIt->second->create(); - } - else - { - return NULL; - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -PdmObjectFactory * PdmObjectFactory::instance() -{ - static PdmObjectFactory* fact = new PdmObjectFactory; - return fact; -} - -//-------------------------------------------------------------------------------------------------- -/// Specialized read function for QStrings, because the >> operator only can read word by word -//-------------------------------------------------------------------------------------------------- -template<> -void PdmFieldReader::readFieldData(PdmField & field, QXmlStreamReader& xmlStream) -{ - PdmFieldIOHelper::skipComments(xmlStream); - if (!xmlStream.isCharacters()) return; - - field = xmlStream.text().toString(); - - // Make stream point to end of element - QXmlStreamReader::TokenType type; - type = xmlStream.readNext(); - PdmFieldIOHelper::skipCharactersAndComments(xmlStream); -} - - -} //End of namespace caf - -//-------------------------------------------------------------------------------------------------- -/// Specialized read operation for Bool`s -//-------------------------------------------------------------------------------------------------- -QTextStream& operator >> (QTextStream& str, bool& value) -{ - QString text; - str >> text; - if (text == "True" || text == "true" || text == "1" || text == "Yes" || text == "yes") value = true; - else value = false; - - return str; -} - -QTextStream& operator << (QTextStream& str, const bool& value) -{ - if (value) str << "True "; - else str << "False "; - - return str; -} - - -//-------------------------------------------------------------------------------------------------- -/// Specialized read operation for QDateTimes`s -//-------------------------------------------------------------------------------------------------- -#include -QTextStream& operator >> (QTextStream& str, QDateTime& value) -{ - QString text; - str >> text; - value = QDateTime::fromString(text, "yyyy_MM_dd-HH:mm:ss"); - return str; -} - -QTextStream& operator << (QTextStream& str, const QDateTime& value) -{ - QString text = value.toString("yyyy_MM_dd-HH:mm:ss"); - str << text; - return str; -} diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmField.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmField.h index d8066b7ad9..f74aa9f72e 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmField.h +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmField.h @@ -1,267 +1,23 @@ -//################################################################################################## -// -// Custom Visualization Core library -// Copyright (C) 2011-2013 Ceetron AS -// -// This library may be used under the terms of either the GNU General Public License or -// the GNU Lesser General Public License as follows: -// -// GNU General Public License Usage -// This library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. -// -// See the GNU General Public License at <> -// for more details. -// -// GNU Lesser General Public License Usage -// This library is free software; you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation; either version 2.1 of the License, or -// (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. -// -// See the GNU Lesser General Public License at <> -// for more details. -// -//################################################################################################## +#pragma once +#define CAF_IS_DEFINING_PDM_FIELD +#define PdmDataValueField PdmField +#include "cafPdmDataValueField.h" +#undef PdmDataValueField +#undef CAF_IS_DEFINING_PDM_FIELD -#pragma once - -#include "cafPdmUiItem.h" -#include "cafPdmFieldImpl.h" - -#include -#include - -#include -#include -#include - -namespace caf -{ - -class PdmObject; -template class PdmPointer; -class PdmUiFieldEditorHandle; - -//================================================================================================== -/// Base class for all fields, making it possible to handle them generically -//================================================================================================== - -class PdmFieldHandle : public PdmUiItem -{ -public: - PdmFieldHandle() : m_isIOReadable(true), m_isIOWritable(true) { m_ownerObject = NULL; m_keyword = "UNDEFINED"; } - virtual ~PdmFieldHandle() { } - - virtual void resetToDefaultValue() { }; - - virtual void readFieldData(QXmlStreamReader& xmlStream) = 0; - virtual void writeFieldData(QXmlStreamWriter& xmlStream) = 0; - - bool isIOReadable() { return m_isIOReadable; } - bool isIOWritable() { return m_isIOWritable; } - void setIOWritable(bool isWritable) { m_isIOWritable = isWritable; } - void setIOReadable(bool isReadable) { m_isIOReadable = isReadable; } - - void setKeyword(const QString& keyword); - QString keyword() const { return m_keyword; } - - void setOwnerObject(PdmObject * owner) { m_ownerObject = owner; } - PdmObject* ownerObject() { return m_ownerObject; } - - // Generalized access methods for User interface - // The QVariant encapsulates the real value, or an index into the valueOptions - // - - virtual QVariant uiValue() const { return QVariant(); } - virtual void setValueFromUi(const QVariant& ) { } - - virtual bool hasChildObjects(); - virtual void childObjects(std::vector* ) { } - virtual void removeChildObject(PdmObject* ) { } - - virtual QList - valueOptions( bool* useOptionsOnly) { return QList(); } - -protected: - bool assertValid() const; -protected: - PdmObject* m_ownerObject; -private: - QString m_keyword; - bool m_isIOReadable; - bool m_isIOWritable; - -}; - - -//================================================================================================== -/// Field class encapsulating data with input and output of this data to/from a QXmlStream -/// read/write-FieldData is supposed to be specialized for types needing specialization -//================================================================================================== -template struct PdmFieldWriter; -template struct PdmFieldReader; - -template -class PdmField : public PdmFieldHandle +namespace caf { -public: - PdmField() {} - virtual ~PdmField() {} - - // Copy and assignment must ignore the default value. - PdmField(const PdmField& other) : PdmFieldHandle() { assertValid(); m_fieldValue = other.m_fieldValue; } - PdmField(const DataType& fieldValue) : PdmFieldHandle() { assertValid(); m_fieldValue = fieldValue; } - PdmField& operator= (const PdmField& other) { assertValid(); m_fieldValue = other.m_fieldValue; return *this; } - PdmField& operator= (const DataType& fieldValue) { assertValid(); m_fieldValue = fieldValue; return *this; } - - operator DataType () const { return m_fieldValue; } - - // DataType& operator()() { assertValid(); return m_fieldValue; } - const DataType& operator()() const { return m_fieldValue; } - DataType& v() { assertValid(); return m_fieldValue; } - const DataType& v() const { return m_fieldValue; } - - bool operator== (const DataType& fieldValue) const { return m_fieldValue == fieldValue; } - - // readFieldData assumes that the xmlStream points to first token of field content. - // After reading, the xmlStream is supposed to point to the first token after the field content. - // (typically an "endElement") - - virtual void readFieldData(QXmlStreamReader& xmlStream) { PdmFieldReader::readFieldData(*this, xmlStream); } - virtual void writeFieldData(QXmlStreamWriter& xmlStream) { PdmFieldWriter::writeFieldData(*this, xmlStream);} - - const DataType& defaultValue() const { return m_defaultFieldValue; } - void setDefaultValue(const DataType& val) { m_defaultFieldValue = val; } - virtual void resetToDefaultValue() { m_fieldValue = m_defaultFieldValue; } - - // Gui generalized interface - virtual QVariant uiValue() const; - virtual void setValueFromUi(const QVariant& uiValue); - - virtual QList valueOptions( bool* useOptionsOnly); - virtual void childObjects(std::vector* objects) { PdmFieldTypeSpecialization::childObjects(*this, objects); } - -protected: - DataType m_fieldValue; - DataType m_defaultFieldValue; - QList m_optionEntryCache; -}; - - -//================================================================================================== -/// Specialization for pointers, but only applicable to PdmObject derived objects. -/// The pointer is guarded, meaning that it will be set to NULL if the object pointed to -/// is deleted. The referenced object will be printed in place in the xml-file -//================================================================================================== - -template -class PdmField : public PdmFieldHandle -{ - typedef DataType* DataTypePtr; -public: - PdmField() : PdmFieldHandle() { } - PdmField(const PdmField& other); - PdmField(const DataTypePtr& fieldValue); - virtual ~PdmField(); - - PdmField& operator= (const PdmField& other); - PdmField& operator= (const DataTypePtr & fieldValue); - - operator DataType* () const { return m_fieldValue; } - DataType* operator->() const { return m_fieldValue; } - - const PdmPointer& operator()() const { return m_fieldValue; } - const PdmPointer& v() const { return m_fieldValue; } - - bool operator==(const DataTypePtr& fieldValue) { return m_fieldValue == fieldValue; } - - // readFieldData assumes that the xmlStream points to first token of field content. - // After reading, the xmlStream is supposed to point to the first token after the field content. - // (typically an "endElement") - virtual void readFieldData(QXmlStreamReader& xmlStream); - virtual void writeFieldData(QXmlStreamWriter& xmlStream); - - const DataTypePtr& defaultValue() const { return NULL; } - void setDefaultValue(const DataTypePtr& ) { } - - // Gui generalized methods - virtual QVariant uiValue() const { return QVariant();} - virtual void childObjects(std::vector* objects); - -protected: - PdmPointer m_fieldValue; -}; - -//================================================================================================== -/// PdmFieldClass to handle a collection of PdmObject derived pointers -/// The reasons for this class is to add itself as parentField into the objects being pointed to. -/// The interface is made similar to std::vector<>, and the complexity of the methods is similar too. -//================================================================================================== - -template -class PdmPointersField : public PdmFieldHandle -{ -public: - PdmPointersField() - { bool doNotUsePdmPointersFieldForAnythingButPointersToPdmObject = false; assert(doNotUsePdmPointersFieldForAnythingButPointersToPdmObject); } -}; - -template -class PdmPointersField : public PdmFieldHandle -{ - typedef DataType* DataTypePtr; -public: - PdmPointersField() { } - PdmPointersField(const PdmPointersField& other); - virtual ~PdmPointersField(); - - PdmPointersField& operator= (const PdmPointersField& other); - bool operator==(const PdmPointersField& other) { return m_pointers == other.m_pointers; } - PdmPointersField& operator() () { return *this; } - - size_t size() const { return m_pointers.size(); } - bool empty() const { return m_pointers.empty(); } - DataType* operator[] (size_t index) const; - - void push_back(DataType* pointer); - void set(size_t index, DataType* pointer); - void insert(size_t indexAfter, DataType* pointer); - void insert(size_t indexAfter, const std::vector >& objects); - size_t count(const DataType* pointer) const; - - void clear(); - void erase(size_t index); - void deleteAllChildObjects(); - - // Reimplementation of PdmFieldhandle methods - virtual void readFieldData(QXmlStreamReader& xmlStream); - virtual void writeFieldData(QXmlStreamWriter& xmlStream); - - // Gui generalized methods - virtual void childObjects(std::vector* objects); - virtual void removeChildObject(PdmObject* object); -private: - void removeThisAsParentField(); - void addThisAsParentField(); +// Specialization to create compiler errors to help finding the PdmField's to rename -private: - std::vector< PdmPointer > m_pointers; -}; +#ifdef WIN32 + template + class PdmField : public Rename_PdmField_of_pointer_to_PdmChildField // You must rename PdmField to PdmChildField + { + }; -} // End of namespace caf +#endif -#include "cafPdmField.inl" +} diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmField.inl b/Fwk/AppFwk/cafProjectDataModel/cafPdmField.inl deleted file mode 100644 index 5d60952b13..0000000000 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmField.inl +++ /dev/null @@ -1,746 +0,0 @@ -//################################################################################################## -// -// Custom Visualization Core library -// Copyright (C) 2011-2013 Ceetron AS -// -// This library may be used under the terms of either the GNU General Public License or -// the GNU Lesser General Public License as follows: -// -// GNU General Public License Usage -// This library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. -// -// See the GNU General Public License at <> -// for more details. -// -// GNU Lesser General Public License Usage -// This library is free software; you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation; either version 2.1 of the License, or -// (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. -// -// See the GNU Lesser General Public License at <> -// for more details. -// -//################################################################################################## - - -#include "cafPdmObject.h" -#include -#include -#include "cafPdmUiFieldEditorHandle.h" - -namespace caf -{ - -//================================================================================================== -/// Implementation of PdmField methods -//================================================================================================== - -//-------------------------------------------------------------------------------------------------- -/// This method is supposed to be the interface for the implementation of UI editors to set values into -/// the field. The data to set must be encapsulated in a QVariant. -/// This method triggers PdmObject::fieldChangedByUi() and PdmObject::updateConnectedEditors(), an thus -/// makes the application and the UI aware of the change. -/// -/// Note : If the field has optionValues the interface is _index-based_. The QVariant must contain -/// an UInt representing the index to the option selected by the user interface. -/// -//-------------------------------------------------------------------------------------------------- -template -void caf::PdmField::setValueFromUi(const QVariant& uiValue) -{ - QVariant oldValue = PdmFieldTypeSpecialization::convert(m_fieldValue); - - // Check whether we are handling selections of values or actual values - if (m_optionEntryCache.size()) - { - // This has an option based GUI, the uiValue is only indexes into the m_optionEntryCache - if (uiValue.type() == QVariant::UInt) - { - assert(uiValue.toUInt() < static_cast(m_optionEntryCache.size())); - PdmFieldTypeSpecialization::setFromVariant(m_optionEntryCache[uiValue.toUInt()].value, m_fieldValue); - } - else if (uiValue.type() == QVariant::List) - { - QList selectedIndexes = uiValue.toList(); - QList valuesToSetInField; - - if (selectedIndexes.isEmpty()) - { - PdmFieldTypeSpecialization::setFromVariant(valuesToSetInField, m_fieldValue); - } - else - { - if (selectedIndexes.front().type() == QVariant::UInt) - { - for (int i = 0; i < selectedIndexes.size(); ++i) - { - unsigned int opIdx = selectedIndexes[i].toUInt(); - if (opIdx < static_cast(m_optionEntryCache.size())) - { - valuesToSetInField.push_back(m_optionEntryCache[opIdx].value); - } - } - - PdmFieldTypeSpecialization::setFromVariant(valuesToSetInField, m_fieldValue); - } - else - { - // We are not getting indexes as expected from the UI. For now assert, to catch this condition - // but it should possibly be handled as setting the values explicitly. The code for that is below the assert - assert(false); - PdmFieldTypeSpecialization::setFromVariant(uiValue, m_fieldValue); - m_optionEntryCache.clear(); - } - } - - } - else - { - // We are not getting indexes as expected from the UI. For now assert, to catch this condition - // but it should possibly be handled as setting the values explicitly. The code for that is below the assert - assert(false); - PdmFieldTypeSpecialization::setFromVariant(uiValue, m_fieldValue); - m_optionEntryCache.clear(); - } - } - else - { // Not an option based GUI, the uiValue is a real field value - PdmFieldTypeSpecialization::setFromVariant(uiValue, m_fieldValue); - } - - QVariant newValue = PdmFieldTypeSpecialization::convert(m_fieldValue); - - // Call changed methods if field value has changed - if (newValue != oldValue) - { - assert(m_ownerObject != NULL); - m_ownerObject->fieldChangedByUi(this, oldValue, newValue); - - // This assumes that all field editors are updated by an instance of PdmUiObjectEditorHandle - m_ownerObject->updateConnectedEditors(); - } -} - -//-------------------------------------------------------------------------------------------------- -/// Returns the option values that is to be displayed in the UI for this field. -/// This method calls the virtual PdmObject::calculateValueOptions to get the list provided from the -/// application, then possibly adds the current field value(s) to the list, to -/// make sure the actual values are shown -/// -/// Note: This method is missing the uiConfigName concept. This is a Todo. The m_optionEntryCache -/// then needs to be stored pr. uiConfigName. -//-------------------------------------------------------------------------------------------------- -template -QList caf::PdmField::valueOptions(bool* useOptionsOnly) -{ - // First check if the owner PdmObject has a value options specification. - // if it has, use it. - if (m_ownerObject) - { - m_optionEntryCache = m_ownerObject->calculateValueOptions(this, useOptionsOnly); - if (m_optionEntryCache.size()) - { - // Make sure the options contain the field values, event though they not necessarily - // is supplied as possible options by the application. This is a convenience making sure - // the actual data in the pdmObject is shown correctly in the UI, and to prevent accidental - // changes of the field values - - // Find the field value(s) in the list if present - - QVariant convertedFieldValue = PdmFieldTypeSpecialization::convert(m_fieldValue); - - std::vector foundIndexes; - bool foundAllFieldValues = PdmOptionItemInfo::findValues(m_optionEntryCache, convertedFieldValue, foundIndexes); - - // If not all are found, we have to add the missing to the list, to be able to show it - - if (!foundAllFieldValues) - { - if (convertedFieldValue.type() != QVariant::List) // Single value field - { - if (!convertedFieldValue.toString().isEmpty()) - { - m_optionEntryCache.push_front(PdmOptionItemInfo(convertedFieldValue.toString(), convertedFieldValue, true, QIcon())); - } - } - else // The field value is a list of values - { - QList valuesSelectedInField = convertedFieldValue.toList(); - for (int i= 0 ; i < valuesSelectedInField.size(); ++i) - { - bool isFound = false; - for (unsigned int opIdx = 0; opIdx < static_cast(m_optionEntryCache.size()); ++opIdx) - { - if (valuesSelectedInField[i] == m_optionEntryCache[opIdx].value) isFound = true; - } - - if (!isFound && !valuesSelectedInField[i].toString().isEmpty()) - { - m_optionEntryCache.push_front(PdmOptionItemInfo(valuesSelectedInField[i].toString(), valuesSelectedInField[i], true, QIcon())); - } - } - } - } - - return m_optionEntryCache; - } - } - - // If we have no options, use the options defined by the type. Normally only caf::AppEnum type - -#if 0 - m_optionEntryCache = PdmFieldTypeSpecialization::valueOptions(useOptionsOnly, m_fieldValue); - return m_optionEntryCache; -#else - return PdmFieldTypeSpecialization::valueOptions(useOptionsOnly, m_fieldValue); -#endif - -} - -//-------------------------------------------------------------------------------------------------- -/// Extracts a QVariant representation of the data in the field to be used in the UI. -/// -/// Note : For fields with a none-empty valueOptions list, the returned QVariant contains the -/// _indexes_ to the selected options rather than the actual values, if they can be found. -/// -/// If this is a multivalue field, and we cant find all of the field values among the options, -/// the method asserts (For now), forcing the valueOptions to always contain the field values. -/// Single value fields will return -1 if the option is not found, allowing the concept of "nothing selected" -//-------------------------------------------------------------------------------------------------- -template -QVariant caf::PdmField::uiValue() const -{ - if (m_optionEntryCache.size()) - { - QVariant convertedFieldValue = PdmFieldTypeSpecialization::convert(m_fieldValue); - std::vector indexesToFoundOptions; - PdmOptionItemInfo::findValues(m_optionEntryCache, convertedFieldValue, indexesToFoundOptions); - if (convertedFieldValue.type() == QVariant::List) - { - if (indexesToFoundOptions.size() == static_cast(convertedFieldValue.toList().size())) - { - QList returnList; - for(size_t i = 0; i < indexesToFoundOptions.size(); ++i) - { - returnList.push_back(QVariant(indexesToFoundOptions[i])); - } - return QVariant(returnList); - } - assert(false); // Did not find all the field values among the options available. - } - else - { - if (indexesToFoundOptions.size() == 1) return QVariant(indexesToFoundOptions.front()); - else return QVariant(-1); // Return -1 if not found instead of assert. Should result in clearing the selection - } - - assert(false); - return convertedFieldValue; - } - else - { - return PdmFieldTypeSpecialization::convert(m_fieldValue); - } - -} - -//================================================================================================== -/// Implementation of PdmField methods -/// (Partial specialization for pointers) -//================================================================================================== - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- - -template -void caf::PdmField::readFieldData(QXmlStreamReader& xmlStream) -{ - PdmFieldIOHelper::skipCharactersAndComments(xmlStream); - if (!xmlStream.isStartElement()) - { - return; // This happens when the field is "shortcut" empty (written like: ) - } - - QString className = xmlStream.name().toString(); - PdmObject* obj = NULL; - - // Create an object if needed - if (m_fieldValue.isNull()) - { - obj = caf::PdmObjectFactory::instance()->create(className); - - if (obj == NULL) - { - std::cout << "Line " << xmlStream.lineNumber() << ": Warning: Unknown object type with class name: " << className.toLatin1().data() << " found while reading the field : " << this->keyword().toLatin1().data() << std::endl; - - xmlStream.skipCurrentElement(); // Skip to the endelement of the object we was supposed to read - xmlStream.skipCurrentElement(); // Skip to the endelement of this field - return; - } - else - { - if (obj->classKeyword() != className) - { - assert(false); // Inconsistency in the factory. It creates objects of wrong type from the ClassKeyword - - xmlStream.skipCurrentElement(); // Skip to the endelement of the object we was supposed to read - xmlStream.skipCurrentElement(); // Skip to the endelement of this field - - return; - } - - m_fieldValue.setRawPtr(obj); - obj->addParentField(this); - } - } - else - { - obj = m_fieldValue.rawPtr(); - } - - if (className != obj->classKeyword()) - { - // Error: Field contains different class type than on file - std::cout << "Line " << xmlStream.lineNumber() << ": Warning: Unknown object type with class name: " << className.toLatin1().data() << " found while reading the field : " << this->keyword().toLatin1().data() << std::endl; - std::cout << " Expected class name: " << obj->classKeyword().toLatin1().data() << std::endl; - - xmlStream.skipCurrentElement(); // Skip to the endelement of the object we was supposed to read - xmlStream.skipCurrentElement(); // Skip to the endelement of this field - - return; - } - - // Everything seems ok, so read the contents of the object: - - obj->readFields(xmlStream); - - // Make stream point to endElement of this field - - QXmlStreamReader::TokenType type; - type = xmlStream.readNext(); - PdmFieldIOHelper::skipCharactersAndComments(xmlStream); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- - -template -void caf::PdmField::writeFieldData(QXmlStreamWriter& xmlStream) -{ - if (m_fieldValue.rawPtr() == NULL) return; - - QString className = m_fieldValue.rawPtr()->classKeyword(); - - xmlStream.writeStartElement("", className); - m_fieldValue.rawPtr()->writeFields(xmlStream); - xmlStream.writeEndElement(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -template -void caf::PdmField::childObjects(std::vector* objects) -{ - assert (objects); - PdmObject* obj = m_fieldValue.rawPtr(); - if (obj) - { - objects->push_back(obj); - } -} - - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -template -caf::PdmField::PdmField(const PdmField& other) - : PdmFieldHandle() -{ - if (m_fieldValue) m_fieldValue.rawPtr()->removeParentField(this); - m_fieldValue = other.m_fieldValue; - if (m_fieldValue != NULL) m_fieldValue.rawPtr()->addParentField(this); -} - - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -template -caf::PdmField::PdmField(const DataTypePtr& fieldValue) -{ - if (m_fieldValue) m_fieldValue->removeParentField(this); - m_fieldValue = fieldValue; - if (m_fieldValue != NULL) m_fieldValue->addParentField(this); -} - - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -template -caf::PdmField::~PdmField() -{ - if (!m_fieldValue.isNull()) m_fieldValue.rawPtr()->removeParentField(this); - m_fieldValue.setRawPtr(NULL); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -template -caf::PdmField& PdmField::operator=(const PdmField& other) -{ - if (m_fieldValue) m_fieldValue->removeParentField(this); - m_fieldValue = other.m_fieldValue; - if (m_fieldValue != NULL) m_fieldValue->addParentField(this); - - return *this; -} - - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -template -caf::PdmField& PdmField::operator=(const DataTypePtr & fieldValue) -{ - if (m_fieldValue) m_fieldValue->removeParentField(this); - m_fieldValue = fieldValue; - if (m_fieldValue != NULL) m_fieldValue->addParentField(this); - return *this; -} - - -//================================================================================================== -/// Implementation of PdmPointersField<> -//================================================================================================== - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -template -PdmPointersField::PdmPointersField(const PdmPointersField& other) -{ - this->removeThisAsParentField(); - m_pointers = other.m_pointers; - this->addThisAsParentField(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -template -PdmPointersField::~PdmPointersField() -{ - this->removeThisAsParentField(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -template -caf::PdmPointersField& PdmPointersField::operator=(const PdmPointersField& other) -{ - this->removeThisAsParentField(); - m_pointers = other.m_pointers; - this->addThisAsParentField(); - - return *this; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -template -DataType* PdmPointersField::operator[](size_t index) const -{ - return m_pointers[index]; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -template -void PdmPointersField::push_back(DataType* pointer) -{ - m_pointers.push_back(pointer); - if (pointer) pointer->addParentField(this); -} - -//-------------------------------------------------------------------------------------------------- -/// Set the value at position index to pointer, overwriting any pointer already present at that -/// position without deleting the object pointed to. -//-------------------------------------------------------------------------------------------------- -template -void PdmPointersField::set(size_t index, DataType* pointer) -{ - if (m_pointers[index]) m_pointers[index]->removeParentField(this); - m_pointers[index] = pointer; - if (m_pointers[index]) pointer->addParentField(this); -} - -//-------------------------------------------------------------------------------------------------- -/// Insert pointer at position index, pushing the value previously at that position and all -/// the preceding values backwards -//-------------------------------------------------------------------------------------------------- -template -void PdmPointersField::insert(size_t index, DataType* pointer) -{ - m_pointers.insert(m_pointers.begin()+index, pointer); - - if (pointer) pointer->addParentField(this); -} - - -//-------------------------------------------------------------------------------------------------- -/// Insert the pointers at position index, pushing the value previously at that position and all -/// the preceding values backwards -//-------------------------------------------------------------------------------------------------- -template -void PdmPointersField::insert(size_t index, const std::vector >& objects) -{ - m_pointers.insert(m_pointers.begin()+index, objects.begin(), objects.end()); - - typename std::vector< PdmPointer< DataType > >::iterator it; - for (it = m_pointers.begin()+index; it != m_pointers.end(); ++it) - { - if (!it->isNull()) - { - (*it)->addParentField(this); - } - } -} - -//-------------------------------------------------------------------------------------------------- -/// Returns the number of times pointer is referenced from the container. -//-------------------------------------------------------------------------------------------------- -template -size_t PdmPointersField::count(const DataType* pointer) const -{ - size_t itemCount = 0; - - typename std::vector< PdmPointer< DataType > >::const_iterator it; - for (it = m_pointers.begin(); it != m_pointers.end(); ++it) - { - if (*it == pointer) - { - itemCount++; - } - } - - return itemCount; -} - -//-------------------------------------------------------------------------------------------------- -/// Empty the container without deleting the objects pointed to. -//-------------------------------------------------------------------------------------------------- -template -void PdmPointersField::clear() -{ - this->removeThisAsParentField(); - m_pointers.clear(); -} - -//-------------------------------------------------------------------------------------------------- -/// Deletes all the objects pointed to by the field, then clears the container. -//-------------------------------------------------------------------------------------------------- -template -void PdmPointersField::deleteAllChildObjects() -{ - size_t index; - for (index = 0; index < m_pointers.size(); ++index) - { - delete(m_pointers[index].rawPtr()); - } - - m_pointers.clear(); -} - -//-------------------------------------------------------------------------------------------------- -/// Removes the pointer at index from the container. Does not delete the object pointed to. -//-------------------------------------------------------------------------------------------------- -template -void PdmPointersField::erase(size_t index) -{ - if (m_pointers[index]) - { - m_pointers[index]->removeParentField(this); - } - - m_pointers.erase(m_pointers.begin() + index); -} - -//-------------------------------------------------------------------------------------------------- -/// Removes all instances of object pointer from the container without deleting the object. -//-------------------------------------------------------------------------------------------------- -template -void PdmPointersField::removeChildObject(PdmObject* object) -{ - std::vector< PdmPointer > tempPointers; - - tempPointers = m_pointers; - m_pointers.clear(); - - for (size_t index = 0; index < tempPointers.size(); ++index) - { - if (tempPointers[index].rawPtr() != object) - { - m_pointers.push_back(tempPointers[index]); - } - else - { - if (tempPointers[index].rawPtr()) - { - tempPointers[index].rawPtr()->removeParentField(this); - } - } - } -} - - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -template - void PdmPointersField::writeFieldData( QXmlStreamWriter& xmlStream) -{ - typename std::vector< PdmPointer >::iterator it; - for (it = m_pointers.begin(); it != m_pointers.end(); ++it) - { - if (it->rawPtr() == NULL) continue; - - QString className = it->rawPtr()->classKeyword(); - - xmlStream.writeStartElement("", className); - it->rawPtr()->writeFields(xmlStream); - xmlStream.writeEndElement(); - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- - template - void PdmPointersField::readFieldData(QXmlStreamReader& xmlStream) -{ - DataType * currentObject = NULL; - this->deleteAllChildObjects(); - PdmFieldIOHelper::skipCharactersAndComments(xmlStream); - while (xmlStream.isStartElement()) - { - QString className = xmlStream.name().toString(); - - PdmObject * obj = PdmObjectFactory::instance()->create(className); - - if (obj == NULL) - { - // Warning: Unknown className read - // Skip to corresponding end element - - std::cout << "Line " << xmlStream.lineNumber() << ": Warning: Unknown object type with class name: " << className.toLatin1().data() << " found while reading the field : " << this->keyword().toLatin1().data() << std::endl; - - // Skip to EndElement of the object - xmlStream.skipCurrentElement(); - - // Jump off the end element, and head for next start element (or the final EndElement of the field) - QXmlStreamReader::TokenType type; - type = xmlStream.readNext(); - PdmFieldIOHelper::skipCharactersAndComments(xmlStream); - - continue; - } - - if (obj->classKeyword() != className) - { - assert(false); // There is an inconsistency in the factory. It creates objects of type not matching the ClassKeyword - - // Skip to EndElement of the object - xmlStream.skipCurrentElement(); - - // Jump off the end element, and head for next start element (or the final EndElement of the field) - QXmlStreamReader::TokenType type; - type = xmlStream.readNext(); - PdmFieldIOHelper::skipCharactersAndComments(xmlStream); - - continue; - } - - obj->readFields(xmlStream); - - m_pointers.push_back(PdmPointer()); - m_pointers.back().setRawPtr(obj); - obj->addParentField(this); - - // Jump off the end element, and head for next start element (or the final EndElement of the field) - // Qt reports a character token between EndElements and StartElements so skip it - - QXmlStreamReader::TokenType type; - type = xmlStream.readNext(); - PdmFieldIOHelper::skipCharactersAndComments(xmlStream); - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -template -void PdmPointersField::childObjects(std::vector* objects) -{ - if (!objects) return; - size_t i; - for (i = 0; i < m_pointers.size(); ++i) - { - objects->push_back(m_pointers[i].rawPtr()); - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -template -void PdmPointersField::removeThisAsParentField() -{ - typename std::vector< PdmPointer< DataType > >::iterator it; - for (it = m_pointers.begin(); it != m_pointers.end(); ++it) - { - if (!it->isNull()) - { - it->rawPtr()->removeParentField(this); - } - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -template -void PdmPointersField::addThisAsParentField() -{ - typename std::vector< PdmPointer< DataType > >::iterator it; - for (it = m_pointers.begin(); it != m_pointers.end(); ++it) - { - if (!it->isNull()) - { - (*it)->addParentField(this); - } - } -} - - -} //End of namespace caf diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmFieldImpl.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmFieldImpl.h deleted file mode 100644 index 3c15cb91f8..0000000000 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmFieldImpl.h +++ /dev/null @@ -1,497 +0,0 @@ -//################################################################################################## -// -// Custom Visualization Core library -// Copyright (C) 2011-2013 Ceetron AS -// -// This library may be used under the terms of either the GNU General Public License or -// the GNU Lesser General Public License as follows: -// -// GNU General Public License Usage -// This library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. -// -// See the GNU General Public License at <> -// for more details. -// -// GNU Lesser General Public License Usage -// This library is free software; you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation; either version 2.1 of the License, or -// (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. -// -// See the GNU Lesser General Public License at <> -// for more details. -// -//################################################################################################## - - -#pragma once -#include -#include -#include -#include -#include -#include - -#include "cafPdmUiItem.h" -#include "cafPdmObjectFactory.h" - -namespace caf -{ - -// Forward declarations -template class PdmField; -template class PdmPointer; -template class AppEnum; - -//================================================================================================== -/// A proxy class that implements the Gui interface of fields -/// -/// This class collects methods that need specialization when introducing a new type in a PdmField. -/// Having those methods in a separate class makes it possible to "partially specialize" the methods -/// for container classes etc. since partial specialization of template functions is not C++ as of yet. -/// -/// When introducing a new type in a PdmField, you might need to implement a (partial)specialization -/// of this class. -//================================================================================================== - -template -class PdmFieldTypeSpecialization -{ -public: - /// Convert the field value into a QVariant - static QVariant convert(const T& value) - { - return QVariant(value); - } - - /// Set the field value from a QVariant - static void setFromVariant(const QVariant& variantValue, T& value) - { - value = variantValue.value(); - } - - /// Methods to get a list of options for a field, specialized for AppEnum - static QList valueOptions( bool* useOptionsOnly, const T& ) - { - return QList(); - } - - /// Methods to retrieve the possible PdmObject pointed to by a field - static void childObjects(const PdmField& , std::vector* ) - { } - /* - static void writeFieldData(PdmField & field, QXmlStreamWriter& xmlStream) - { - QString dataString; - QTextStream data(&dataString, QIODevice::WriteOnly); - data << field.v(); - xmlStream.writeCharacters(dataString); - } - - static void readFieldData(PdmField & field, QXmlStreamReader& xmlStream) - { - PdmFieldHandle::skipComments(xmlStream); - if (!xmlStream.isCharacters()) return; - - QString dataString = xmlStream.text().toString(); - QTextStream data(&dataString, QIODevice::ReadOnly); - data >> field.v(); - - // Make stream point to end of element - QXmlStreamReader::TokenType type; - type = xmlStream.readNext(); - PdmFieldHandle::skipCharactersAndComments(xmlStream); - } - */ -}; - -//================================================================================================== -/// Partial specialization for PdmField< std::list > -//================================================================================================== - -template -class PdmFieldTypeSpecialization < std::list > -{ -public: - /// Convert the field value into a QVariant - static QVariant convert(const std::list& value) - { - QList returnList; - typename std::list::const_iterator it; - for (it = value.begin(); it != value.end() ; ++it) - { - returnList.push_back(QVariant(*it)); - } - return returnList; - } - - - /// Set the field value from a QVariant - static void setFromVariant(const QVariant& variantValue, std::list& value) - { - if (variantValue.canConvert< QList >()) - { - value.clear(); - QList lst = variantValue.toList(); - int i; - for (i = 0; i < lst.size(); ++i) - { - value.push_back(lst[i].value()); - } - } - } - - /// Methods to get a list of options for a field, specialized for AppEnum - static QList valueOptions( bool* useOptionsOnly, const std::list& ) - { - return QList(); - } - - /// Methods to retrieve the possible PdmObject pointed to by a field - static void childObjects(const PdmField< std::list >& , std::vector* ) - { } - -}; - -//================================================================================================== -/// Partial specialization for PdmField< std::list< PdmPointer > > -//================================================================================================== - -template -class PdmFieldTypeSpecialization < std::list > > -{ -public: - /// Convert the field value into a QVariant - static QVariant convert(const std::list >& ) - { - return QVariant(); // Do nothing. The members are "children" - } - - /// Set the field value from a QVariant - // Overloaded to do nothing because this is supposed to be handled as children - static void setFromVariant(const QVariant& , std::list >& ) - { } - - /// Methods to get a list of options for a field, specialized for AppEnum - static QList valueOptions( bool* useOptionsOnly, const std::list >& ) - { - return QList(); - } - - /// Methods to retrieve the possible PdmObject pointed to by a field - static void childObjects(const PdmField > >& field, std::vector* objects) - { - if (!objects) return; - - typename std::list >::const_iterator it; - for (it = field.v().begin() ; it != field.v().end(); ++it) - { - objects->push_back(*it); - } - } - -}; - -//================================================================================================== -/// Partial specialization for PdmField< std::vector > -//================================================================================================== - -template -class PdmFieldTypeSpecialization < std::vector > -{ -public: - /// Convert the field value into a QVariant - static QVariant convert(const std::vector& value) - { - QList returnList; - typename std::vector::const_iterator it; - for (it = value.begin(); it != value.end() ; ++it) - { - returnList.push_back(QVariant(*it)); - } - return returnList; - } - - /// Set the field value from a QVariant - static void setFromVariant(const QVariant& variantValue, std::vector& value) - { - if (variantValue.canConvert< QList >()) - { - value.clear(); - QList lst = variantValue.toList(); - int i; - for (i = 0; i < lst.size(); ++i) - { - value.push_back(lst[i].value()); - } - } - } - - /// Methods to get a list of options for a field, specialized for AppEnum - static QList valueOptions( bool* useOptionsOnly, const std::vector& ) - { - return QList(); - } - - /// Methods to retrieve the possible PdmObject pointed to by a field - static void childObjects(const PdmField< std::vector > & field, std::vector* objects) - { } - -}; - -//================================================================================================== -/// Partial specialization for PdmField< caf::AppEnum > -/// -/// Note : Makes the setUiValue() and uiValue() interface index based, and NOT based on real enum values. -/// The valueOptions() interface is thus also index based (the value in the PdmOptionItemInfo is index NOT enum) -/// This is probably going to change, ans it is strange. -/// This conversion should really be done in the editors we think (now) -//================================================================================================== - -#define PDMFIELDAPPENUM_USE_INDEX_BASED_INTERFACE 1 - -template -class PdmFieldTypeSpecialization < caf::AppEnum > -{ -public: - /// Convert the field value into a QVariant - static QVariant convert(const caf::AppEnum& value) - { -#if PDMFIELDAPPENUM_USE_INDEX_BASED_INTERFACE - return QVariant(static_cast(caf::AppEnum::index(value))); -#else - unsigned int enumVal = value; - return QVariant(enumVal); -#endif - } - - /// Set the field value from a QVariant - static void setFromVariant(const QVariant& variantValue, caf::AppEnum& value) - { -#if PDMFIELDAPPENUM_USE_INDEX_BASED_INTERFACE - value.setFromIndex(variantValue.toInt()); -#else - value = static_cast (variantValue.toInt()); -#endif - } - - /// Methods to get a list of options for a field, specialized for AppEnum - static QList valueOptions( bool* useOptionsOnly, const caf::AppEnum& ) - { - if (useOptionsOnly) *useOptionsOnly = true; - - QStringList optionTexts = caf::AppEnum::uiTexts(); - QList optionList; - int i; - for (i = 0; i < optionTexts.size(); ++i) - { -#if PDMFIELDAPPENUM_USE_INDEX_BASED_INTERFACE - optionList.push_back(PdmOptionItemInfo(optionTexts[i], static_cast(i))); -#else - optionList.push_back(PdmOptionItemInfo(optionTexts[i], caf::AppEnum::fromIndex(i))); -#endif - } - - return optionList; - } - - /// Methods to retrieve the possible PdmObject pointed to by a field - static void childObjects(const PdmField< caf::AppEnum >& field, std::vector* objects) - { } - -}; - -class PdmFieldIOHelper -{ -public: - // Utility functions for reading from QXmlStreamReader - static void skipCharactersAndComments(QXmlStreamReader& xmlStream); - static void skipComments(QXmlStreamReader& xmlStream); - -}; - -//-------------------------------------------------------------------------------------------------- -/// Generic write method for fields. Will work as long as DataType supports the stream operator -/// towards a QTextStream. Some special datatype should not specialize this method unless it is -/// impossible/awkward to implement the stream operator -/// Implemented in a proxy class to allow partial specialization -//-------------------------------------------------------------------------------------------------- -template -struct PdmFieldWriter -{ - static void writeFieldData(PdmField & field, QXmlStreamWriter& xmlStream) - { - QString dataString; - QTextStream data(&dataString, QIODevice::WriteOnly); - data << field.v(); - xmlStream.writeCharacters(dataString); - } -}; - -template -struct PdmFieldReader -{ - static void readFieldData(PdmField & field, QXmlStreamReader& xmlStream); -}; - -//-------------------------------------------------------------------------------------------------- -/// Generic read method for fields. Will work as long as DataType supports the stream operator -/// towards a QTextStream. Some special datatype should not specialize this method unless it is -/// impossible/awkward to implement the stream operator -//-------------------------------------------------------------------------------------------------- -template -void PdmFieldReader::readFieldData(PdmField & field, QXmlStreamReader& xmlStream) -{ - PdmFieldIOHelper::skipComments(xmlStream); - if (!xmlStream.isCharacters()) return; - - QString dataString = xmlStream.text().toString(); - QTextStream data(&dataString, QIODevice::ReadOnly); - data >> field.v(); - - // Make stream point to end of element - QXmlStreamReader::TokenType type; - type = xmlStream.readNext(); - PdmFieldIOHelper::skipCharactersAndComments(xmlStream); -} - -//-------------------------------------------------------------------------------------------------- -/// Specialized read function for QStrings, because the >> operator only can read word by word -//-------------------------------------------------------------------------------------------------- -template<> -void PdmFieldReader::readFieldData(PdmField & field, QXmlStreamReader& xmlStream); - -//================================================================================================== -/// Read and write method specializations for containers of pointers -/// std::list is the main one -//================================================================================================== - -template -struct PdmFieldWriter > > -{ - static void writeFieldData(PdmField > > & field, QXmlStreamWriter& xmlStream) - { - typename std::list< PdmPointer >::iterator it; - for (it = field.v().begin(); it != field.v().end(); ++it) - { - if (*it == NULL) continue; - - QString className = (*it)->classKeyword(); - - xmlStream.writeStartElement("", className); - (*it)->writeFields(xmlStream); - xmlStream.writeEndElement(); - } - } -}; - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -template -struct PdmFieldReader > > -{ - static void readFieldData(PdmField > > & field, QXmlStreamReader& xmlStream) - { - T * currentObject = NULL; - PdmFieldIOHelper::skipCharactersAndComments(xmlStream); - while (xmlStream.isStartElement()) - { - QString className = xmlStream.name().toString(); - - PdmObject * obj = PdmObjectFactory::instance()->create(className); - - if (obj == NULL) - { - // Warning: Unknown className read - // Skip to corresponding end element - xmlStream.skipCurrentElement(); - PdmFieldIOHelper::skipCharactersAndComments(xmlStream); - continue; - } - - currentObject = dynamic_cast (obj); - - if (currentObject == NULL) - { - // Warning: Inconsistency in factory !! Assert ? - // Skip to corresponding end element - xmlStream.skipCurrentElement(); - PdmFieldIOHelper::skipCharactersAndComments(xmlStream); - continue; - } - - currentObject->readFields(xmlStream); - field.v().push_back(currentObject); - - // Skip comments and for some reason: Characters. The last bit should not be correct, - // but Qt reports a character token between EndElement and StartElement - - QXmlStreamReader::TokenType type; - type = xmlStream.readNext(); - PdmFieldIOHelper::skipCharactersAndComments(xmlStream); - } - } -}; - - -} // End of namespace caf - - -//================================================================================================== -/// QTextStream Stream operator overloading for bool`s -/// Prints bool`s as "True"/"False", and reads them too -//================================================================================================== - -QTextStream& operator >> (QTextStream& str, bool& value); -QTextStream& operator << (QTextStream& str, const bool& value); - - -//================================================================================================== -/// QTextStream Stream operator overloading for QDateTimes`s -/// -//================================================================================================== -//class QDateTime; -QTextStream& operator >> (QTextStream& str, QDateTime& value); -QTextStream& operator << (QTextStream& str, const QDateTime& value); - - -//================================================================================================== -/// QTextStream Stream operator overloading for std::vector of things. -/// Makes automated IO of PdmField< std::vector< Whatever > possible as long as -/// the type will print as one single word -//================================================================================================== - -template < typename T > -QTextStream& operator << (QTextStream& str, const std::vector& sobj) -{ - size_t i; - for (i = 0; i < sobj.size(); ++i) - { - str << sobj[i] << " "; - } - return str; -} - -template < typename T > -QTextStream& operator >> (QTextStream& str, std::vector& sobj) -{ - while (str.status() == QTextStream::Ok ) - { - T d; - str >> d; - if (str.status() == QTextStream::Ok ) sobj.push_back(d); - } - return str; -} diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmObject.cpp b/Fwk/AppFwk/cafProjectDataModel/cafPdmObject.cpp deleted file mode 100644 index d32c20c4fa..0000000000 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmObject.cpp +++ /dev/null @@ -1,480 +0,0 @@ -//################################################################################################## -// -// Custom Visualization Core library -// Copyright (C) 2011-2013 Ceetron AS -// -// This library may be used under the terms of either the GNU General Public License or -// the GNU Lesser General Public License as follows: -// -// GNU General Public License Usage -// This library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. -// -// See the GNU General Public License at <> -// for more details. -// -// GNU Lesser General Public License Usage -// This library is free software; you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation; either version 2.1 of the License, or -// (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. -// -// See the GNU Lesser General Public License at <> -// for more details. -// -//################################################################################################## - - -#include "cafPdmField.h" -#include "cafPdmObject.h" - -#include - -#include -#include -#include "cafPdmObjectFactory.h" -#include "cafPdmDocument.h" -#include "cafPdmUiTreeOrdering.h" - -namespace caf -{ - -//-------------------------------------------------------------------------------------------------- -/// Reads all the fields into this PdmObject -/// Assumes xmlStream points to the start element token of the PdmObject for which to read fields. -/// ( and not first token of object content) -/// This makes attribute based field storage possible. -/// Leaves the xmlStream pointing to the EndElement of the PdmObject. -//-------------------------------------------------------------------------------------------------- -void PdmObject::readFields (QXmlStreamReader& xmlStream ) -{ - bool isObjectFinished = false; - QXmlStreamReader::TokenType type; - while(!isObjectFinished) - { - type = xmlStream.readNext(); - - switch (type) - { - case QXmlStreamReader::StartElement: - { - QString name = xmlStream.name().toString(); - if (name == QString("SimpleObjPtrField")) - { - int a; - a = 2 + 7; - } - PdmFieldHandle* currentField = findField(name); - if (currentField) - { - if (currentField->isIOReadable()) - { - // readFieldData assumes that the xmlStream points to first token of field content. - // After reading, the xmlStream is supposed to point to the first token after the field content. - // (typically an "endElement") - QXmlStreamReader::TokenType tt; - tt = xmlStream.readNext(); - currentField->readFieldData( xmlStream ); - } - else - { - xmlStream.skipCurrentElement(); - } - } - else - { - std::cout << "Line "<< xmlStream.lineNumber() << ": Warning: Could not find a field with name " << name.toLatin1().data() << " in the current object : " << classKeyword().toLatin1().data() << std::endl; - xmlStream.skipCurrentElement(); - } - break; - } - break; - case QXmlStreamReader::EndElement: - { - // End of object. - QString name = xmlStream.name().toString(); // For debugging - isObjectFinished = true; - } - break; - case QXmlStreamReader::EndDocument: - { - // End of object. - isObjectFinished = true; - } - break; - default: - { - // Just read on - // Todo: Error handling - } - break; - } - } - -} -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void PdmObject::writeFields(QXmlStreamWriter& xmlStream) -{ - std::vector::iterator it; - for (it = m_fields.begin(); it != m_fields.end(); ++it) - { - PdmFieldHandle* field = *it; - if (field->isIOWritable()) - { - QString keyword = field->keyword(); - assert(PdmObject::isValidXmlElementName(keyword)); - - xmlStream.writeStartElement("", keyword); - field->writeFieldData(xmlStream); - xmlStream.writeEndElement(); - } - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -PdmFieldHandle* PdmObject::findField(const QString& keyword) -{ - std::vector::iterator it; - for (it = m_fields.begin(); it != m_fields.end(); it++) - { - PdmFieldHandle* obj = *it; - if (obj->keyword() == keyword) - { - return obj; - } - } - - return NULL; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -PdmObject::~PdmObject() -{ - // Set all guarded pointers pointing to this to NULL - - std::set::iterator it; - for (it = m_pointersReferencingMe.begin(); it != m_pointersReferencingMe.end() ; ++it) - { - (**it) = NULL; - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void PdmObject::fields(std::vector& fields) const -{ - fields = m_fields; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void PdmObject::addParentField(PdmFieldHandle* parentField) -{ - if (parentField != NULL) m_parentFields.insert(parentField); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void PdmObject::removeParentField(PdmFieldHandle* parentField) -{ - if (parentField != NULL) m_parentFields.erase(parentField); -} - -//-------------------------------------------------------------------------------------------------- -/// Appends pointers to all the PdmFields/PdmPointerFields containing a pointer to this object. -/// As the PdmPointersField can hold several pointers to the same object, the returned vector can -/// contain multiple pointers to the same field. -//-------------------------------------------------------------------------------------------------- -void PdmObject::parentFields(std::vector& parentFields) const -{ - std::multiset::const_iterator it; - - for (it = m_parentFields.begin(); it != m_parentFields.end(); ++it) - { - parentFields.push_back(*it); - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void PdmObject::parentObjects(std::vector& objects) const -{ - std::vector parentFields; - this->parentFields(parentFields); - size_t i; - for (i = 0; i < parentFields.size(); i++) - { - objects.push_back(parentFields[i]->ownerObject()); - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void PdmObject::removeFromParentFields() -{ - std::vector parentFields; - this->parentFields(parentFields); - size_t i; - for (i = 0; i < parentFields.size(); i++) - { - parentFields[i]->removeChildObject(this); - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void PdmObject::addFieldNoDefault(PdmFieldHandle* field, const QString& keyword, PdmUiItemInfo * fieldDescription) -{ - field->setUiItemInfo(fieldDescription); - field->setKeyword(keyword); - field->setOwnerObject(this); - - assert(findField(keyword) == NULL); - m_fields.push_back(field); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void PdmObject::uiOrdering(QString uiConfigName, PdmUiOrdering& uiOrdering) -{ - this->defineUiOrdering(uiConfigName, uiOrdering); - if (!uiOrdering.forgetRemainingFields()) - { - // Add the remaining Fields To UiConfig - - for (size_t i = 0; i < m_fields.size(); ++i) - { - if (!uiOrdering.contains(m_fields[i])) - { - uiOrdering.add( m_fields[i]); - } - } - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void PdmObject::editorAttribute(const PdmFieldHandle* field, QString uiConfigName, PdmUiEditorAttribute * attribute) -{ - this->defineEditorAttribute(field, uiConfigName, attribute); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void PdmObject::objectEditorAttribute(QString uiConfigName, PdmUiEditorAttribute* attribute) -{ - this->defineObjectEditorAttribute(uiConfigName, attribute); -} - - -//-------------------------------------------------------------------------------------------------- -/// Check if a string is a valid Xml element name -// -/// http://www.w3schools.com/xml/xml_elements.asp -/// -/// XML elements must follow these naming rules: -/// Names can contain letters, numbers, and other characters -/// Names cannot start with a number or punctuation character -/// Names cannot start with the letters xml (or XML, or Xml, etc) -/// Names cannot contain spaces -//-------------------------------------------------------------------------------------------------- -bool PdmObject::isValidXmlElementName(const QString& name) -{ - if (name.size() > 0) - { - QChar firstChar = name[0]; - if (firstChar.isDigit() || firstChar == '.') - { - return false; - } - } - - if (name.size() >= 3) - { - if (name.left(3).compare("xml", Qt::CaseInsensitive) == 0) - { - return false; - } - } - - if (name.contains(' ')) - { - return false; - } - - return true; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -PdmObject* PdmObject::deepCopy() -{ - QString encodedXml; - - { - PdmObjectGroup typedObjectGroup; - typedObjectGroup.addObject(this); - - QXmlStreamWriter xmlStream(&encodedXml); - xmlStream.setAutoFormatting(true); - - typedObjectGroup.writeFields(xmlStream); - } - - PdmObject* pdmCopy = NULL; - { - // Read back XML into object group, factory methods will be called that will create new objects - PdmObjectGroup destinationObjectGroup; - QXmlStreamReader xmlStream(encodedXml); - destinationObjectGroup.readFields(xmlStream); - - if (destinationObjectGroup.objects.size() == 1) - { - pdmCopy = destinationObjectGroup.objects[0]; - } - } - - return pdmCopy; - - /* - PdmObject* cloneRoot = PdmObjectFactory::instance()->create(this->classKeyword()); - - - - QString encodedXml; - { - QXmlStreamWriter xmlStream(&encodedXml); - xmlStream.setAutoFormatting(true); - - this->writeFields(xmlStream); - } - - QXmlStreamReader xmlStream(encodedXml); - cloneRoot->readFields(xmlStream); - - return cloneRoot; - */ -} - -//-------------------------------------------------------------------------------------------------- -/// This method is to be used to create a tree-representation of the object hierarchy starting at this -/// object. The caller is responsible to delete the returned PdmUiTreeOrdering -//-------------------------------------------------------------------------------------------------- -PdmUiTreeOrdering* PdmObject::uiTreeOrdering(QString uiConfigName /*= ""*/) -{ - PdmUiTreeOrdering* uiTreeOrdering = new PdmUiTreeOrdering(NULL, -1, this); - - this->defineUiTreeOrdering(*uiTreeOrdering, uiConfigName); - - if (!uiTreeOrdering->forgetRemainingFields()) - { - // Add the remaining Fields To UiConfig - - for (size_t fIdx = 0; fIdx < m_fields.size(); ++fIdx) - { - if (m_fields[fIdx]->hasChildObjects() && !uiTreeOrdering->containsField(m_fields[fIdx])) - { - if (m_fields[fIdx]->isUiHidden() && !m_fields[fIdx]->isUiChildrenHidden()) - { - std::vector children; - m_fields[fIdx]->childObjects(&children); - - for (size_t cIdx = 0; cIdx < children.size(); cIdx++) - { - if (!uiTreeOrdering->containsObject(children[cIdx])) - { - uiTreeOrdering->add(children[cIdx]); - } - } - } - else if ( !m_fields[fIdx]->isUiHidden()) - { - uiTreeOrdering->add(m_fields[fIdx]); - } - } - } - } - - addUiTreeChildren(uiTreeOrdering, uiConfigName); - return uiTreeOrdering; -} - - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void PdmObject::addUiTreeChildren(PdmUiTreeOrdering* root, QString uiConfigName /*= "" */) -{ - if (!root) return; - - if ( root->childCount() == 0) // This means that no one has tried to expand it. - { - if (!root->ignoreSubTree() && root->dataObject()) - { - - if (root->m_field && !root->m_field->isUiChildrenHidden(uiConfigName)) - { - std::vector fieldsChildObjects; - root->m_field->childObjects(&fieldsChildObjects); - for (size_t cIdx = 0; cIdx < fieldsChildObjects.size(); ++cIdx) - { - root->add(fieldsChildObjects[cIdx]); - } - } - else - { - root->object()->defineUiTreeOrdering(*root, uiConfigName); - } - } - } - - for (int cIdx = 0; cIdx < root->childCount(); ++cIdx) - { - PdmUiTreeOrdering* child = dynamic_cast(root->child(cIdx)); - if (!child->ignoreSubTree()) - { - addUiTreeChildren(child); - } - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void PdmObject::updateUiIconFromToggleField() -{ - if (objectToggleField()) - { - bool active = objectToggleField()->uiValue().toBool(); - updateUiIconFromState(active); - } -} - - -} //End of namespace caf diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmObject.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmObject.h index 8bb9410b87..30ee78520a 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmObject.h +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmObject.h @@ -37,7 +37,9 @@ #pragma once -#include "cafPdmUiItem.h" + +#include "cafPdmObjectHandle.h" + #include "cafPdmUiOrdering.h" #include "cafPdmPointer.h" @@ -48,18 +50,18 @@ class QXmlStreamReader; class QXmlStreamWriter; -// Taken from gtest.h -// -// Due to C++ preprocessor weirdness, we need double indirection to -// concatenate two tokens when one of them is __LINE__. Writing -// -// foo ## __LINE__ -// -// will result in the token foo__LINE__, instead of foo followed by -// the current line number. For more details, see -// http://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.6 -#define PDM_OBJECT_STRING_CONCATENATE(foo, bar) PDM_OBJECT_STRING_CONCATENATE_IMPL_(foo, bar) -#define PDM_OBJECT_STRING_CONCATENATE_IMPL_(foo, bar) foo ## bar + +#include "cafPdmObjectCapability.h" + +#include "cafPdmUiObjectHandle.h" +#include "cafPdmXmlObjectHandle.h" +#include "cafPdmXmlObjectHandleMacros.h" + +#include "cafPdmFieldHandle.h" +#include "cafInternalPdmUiFieldCapability.h" +#include "cafInternalPdmXmlFieldCapability.h" + +#include "cafPdmUiFieldSpecialization.h" namespace caf @@ -69,34 +71,22 @@ class PdmFieldHandle; template < class FieldDataType > class PdmField; class PdmUiEditorAttribute; class PdmUiTreeOrdering; -//================================================================================================== -/// Macros helping in development of PDM objects -//================================================================================================== +class PdmObjectCapability; -/// CAF_PDM_HEADER_INIT assists the factory used when reading objects from file -/// Place this in the header file inside the class definition of your PdmObject +#define CAF_PDM_HEADER_INIT CAF_PDM_XML_HEADER_INIT +#define CAF_PDM_SOURCE_INIT CAF_PDM_XML_SOURCE_INIT -#define CAF_PDM_HEADER_INIT \ -public: \ - virtual QString classKeyword() { return classKeywordStatic(); } \ - static QString classKeywordStatic(); \ - static bool Error_You_forgot_to_add_the_macro_CAF_PDM_HEADER_INIT_and_or_CAF_PDM_SOURCE_INIT_to_your_cpp_file_for_this_class() - -/// CAF_PDM_SOURCE_INIT associates the file keyword used for storage with the class and initializes the factory -/// Place this in the cpp file, preferably above the constructor - -#define CAF_PDM_SOURCE_INIT(ClassName, keyword) \ - bool ClassName::Error_You_forgot_to_add_the_macro_CAF_PDM_HEADER_INIT_and_or_CAF_PDM_SOURCE_INIT_to_your_cpp_file_for_this_class() { return false;} \ - QString ClassName::classKeywordStatic() { assert(PdmObject::isValidXmlElementName(keyword)); return keyword; } \ - static bool PDM_OBJECT_STRING_CONCATENATE(pdm_object_factory_init_, __LINE__) = caf::PdmObjectFactory::instance()->registerCreator() /// InitObject sets up the user interface related information for the object /// Placed in the constructor of your PdmObject #define CAF_PDM_InitObject(uiName, iconResourceName, toolTip, whatsThis) \ { \ + this->isInheritedFromPdmUiObject(); \ + this->isInheritedFromPdmXmlSerializable(); \ + \ static caf::PdmUiItemInfo objDescr(uiName, QIcon(QString(iconResourceName)), toolTip, whatsThis); \ - setUiItemInfo(&objDescr); \ + this->setUiItemInfo(&objDescr); \ } /// InitField sets the file keyword for the field, @@ -106,216 +96,71 @@ public: \ #define CAF_PDM_InitField(field, keyword, default, uiName, iconResourceName, toolTip, whatsThis) \ { \ - static bool chekingThePresenceOfHeaderAndSourceInitMacros = Error_You_forgot_to_add_the_macro_CAF_PDM_HEADER_INIT_and_or_CAF_PDM_SOURCE_INIT_to_your_cpp_file_for_this_class(); \ - \ + static bool chekingThePresenceOfHeaderAndSourceInitMacros = \ + Error_You_forgot_to_add_the_macro_CAF_PDM_XML_HEADER_INIT_and_or_CAF_PDM_XML_SOURCE_INIT_to_your_cpp_file_for_this_class(); \ + this->isInheritedFromPdmUiObject(); \ + this->isInheritedFromPdmXmlSerializable(); \ + \ + AddXmlCapabilityToField(field); \ + AddUiCapabilityToField(field); \ + \ static caf::PdmUiItemInfo objDescr(uiName, QIcon(QString(iconResourceName)), toolTip, whatsThis); \ - addField(field, keyword, default, &objDescr); \ + addFieldUi(field, keyword, default, &objDescr); \ } /// InitFieldNoDefault does the same as InitField but omits the default value. #define CAF_PDM_InitFieldNoDefault(field, keyword, uiName, iconResourceName, toolTip, whatsThis) \ { \ - static bool chekingThePresenceOfHeaderAndSourceInitMacros = Error_You_forgot_to_add_the_macro_CAF_PDM_HEADER_INIT_and_or_CAF_PDM_SOURCE_INIT_to_your_cpp_file_for_this_class(); \ + static bool chekingThePresenceOfHeaderAndSourceInitMacros = \ + Error_You_forgot_to_add_the_macro_CAF_PDM_XML_HEADER_INIT_and_or_CAF_PDM_XML_SOURCE_INIT_to_your_cpp_file_for_this_class(); \ + this->isInheritedFromPdmUiObject(); \ + this->isInheritedFromPdmXmlSerializable(); \ + \ + AddXmlCapabilityToField(field); \ + AddUiCapabilityToField(field); \ \ static caf::PdmUiItemInfo objDescr(uiName, QIcon(QString(iconResourceName)), toolTip, whatsThis); \ - addFieldNoDefault(field, keyword, &objDescr); \ + addFieldUiNoDefault(field, keyword, &objDescr); \ } -//================================================================================================== -/// The base class of all objects that will use the features of the field based IO -/// Inherit this class to make your Pdm-based data structure -//================================================================================================== - -class PdmObject : public PdmUiItem -{ -public: - PdmObject() { } - virtual ~PdmObject(); - - /// The classKeyword method is overridden in subclasses by the CAF_PDM_HEADER_INIT macro - virtual QString classKeyword() = 0; - - void readFields (QXmlStreamReader& inputStream ); - void writeFields(QXmlStreamWriter& outputStream); - - PdmObject* deepCopy(); - - /// The registered fields contained in this PdmObject. Registered by subclasses. - void fields(std::vector& fields) const; - /// The fields containing pointers to this PdmObject. Use ownerObject() on the fieldHandle to get the PdmObject parent. - void parentFields(std::vector& fields) const; - /// Remove pointer to this from all parent fields - void removeFromParentFields(); - - /// - void parentObjects(std::vector& objects) const; - - /// - template - void parentObjectsOfType(std::vector& objects) const; - - /// - template - void firstAncestorOfType(T*& ancestor) const; - - /// Method to be called from the Ui classes creating Auto Gui to get the group information - /// supplied by the \sa defineUiOrdering method that can be reimplemented - void uiOrdering(QString uiConfigName, PdmUiOrdering& uiOrdering) ; - - /// Method to be called by Ui displaying a tree representation of the object hierarchy - /// Caller must delete the returned object. - PdmUiTreeOrdering* uiTreeOrdering( QString uiConfigName = ""); - - /// For a specific field, return editor specific parameters used to customize the editor behavior. - void editorAttribute(const PdmFieldHandle* field, QString uiConfigName, PdmUiEditorAttribute * attribute); - - /// Return object editor specific parameters used to customize the editor behavior. - void objectEditorAttribute(QString uiConfigName, PdmUiEditorAttribute* attribute); - - void updateUiIconFromToggleField(); - - // Virtual interface to override in subclasses to support special behaviour if needed -public: // Virtual - virtual PdmFieldHandle* userDescriptionField() { return NULL; } - - /// Field used to toggle object on/off in UI-related uses of the object (ie checkbox in treeview) - virtual PdmFieldHandle* objectToggleField() { return NULL; } - - /// Method to reimplement to catch when the field has changed due to setUiValue() - virtual void fieldChangedByUi(const PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) {} - /// Method to re-implement to supply option values for a specific field - virtual QList - calculateValueOptions(const PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly) { return QList(); } - // For later // virtual void editorAttributeChangedByUI(const PdmFieldHandle* field, QString uiConfigName, const PdmUiAttributeHandle * attributes); +} // End of namespace caf -public: - /// Check if a string is a valid Xml element name - static bool isValidXmlElementName(const QString& name); - -protected: // Virtual - /// Method gets called from PdmDocument after all objects are read. - /// Re-implement to set up internal pointers etc. in your data structure - virtual void initAfterRead() {}; - - /// Method gets called from PdmDocument before saving document. - /// Re-implement to make sure your fields have correct data before saving - virtual void setupBeforeSave() {}; - - /// Override to customize the order and grouping of the Gui. - /// Fill up the uiOrdering object with groups and field references to create the gui structure - /// If the uiOrdering is empty, it is interpreted as meaning all fields w/o grouping. - virtual void defineUiOrdering(QString uiConfigName, PdmUiOrdering& uiOrdering) {} - - /// Override to customize the tree representations of the object hierarchy. - /// If the PdmUiTreeOrdering is empty, it is interpreted as meaning all fields containing child objects in order - virtual void defineUiTreeOrdering(PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = "" ) { } - - /// Override to provide editor specific data for the field and uiConfigName - virtual void defineEditorAttribute(const PdmFieldHandle* field, QString uiConfigName, PdmUiEditorAttribute * attribute) {} - /// Override to provide editor specific data for the uiConfigName for the object - virtual void defineObjectEditorAttribute(QString uiConfigName, PdmUiEditorAttribute * attribute) {} +namespace caf +{ +class PdmObject : public PdmObjectHandle, public PdmXmlObjectHandle, public PdmUiObjectHandle +{ public: - /// operator= implemented to avoid copying the internal m_fields - PdmObject& operator=(const PdmObject& ) { return *this; } + PdmObject() : PdmObjectHandle(), PdmUiObjectHandle(this, false), PdmXmlObjectHandle(this, false) {} + virtual ~PdmObject() {} -protected: /// Adds field to the internal data structure and sets the file keyword and Ui information /// Consider this method private. Please use the CAF_PDM_InitField() macro instead template< typename FieldDataType > - void addField(PdmField* field, const QString& keyword, const FieldDataType& defaultValue, PdmUiItemInfo * fieldDescription) + void addFieldUi(PdmField* field, const QString& keyword, const FieldDataType& defaultValue, PdmUiItemInfo * fieldDescription) { - addFieldNoDefault(field, keyword, fieldDescription); + addFieldUiNoDefault(field, keyword, fieldDescription); field->setDefaultValue(defaultValue); *field = defaultValue; } /// Does the same as the above method, but omits the default value. /// Consider this method private. Please use the CAF_PDM_InitFieldNoDefault() macro instead. - void addFieldNoDefault(PdmFieldHandle* field, const QString& keyword, PdmUiItemInfo * fieldDescription); - -private: - // Copy and assignment operators are implemented to avoid copying the internal management data structures. - - // If you use copy constructor in your application code, the compiler reports - // "error C2248: 'caf::PdmObjectBase::PdmObjectBase' : cannot access private member declared in ..." - // To fix this issue, implement a public copy constructor in your derived class. - PdmObject(const PdmObject& ): PdmUiItem() { } - PdmFieldHandle* findField(const QString& keyword); - - template < class T > friend class PdmField; - template < class T > friend class PdmPointersField; - - friend class PdmDocument; - friend class PdmObjectGroup; - - void addParentField(PdmFieldHandle* parentField); - void removeParentField(PdmFieldHandle* parentField); - -private: - /// Recursive function to traverse and create a Ui tree representation of the object hierarchy - static void addUiTreeChildren( PdmUiTreeOrdering* root, QString uiConfigName = "" ); - -private: - std::multiset m_parentFields; - std::vector m_fields; - - // Support system for PdmPointer - friend class PdmPointerImpl; - std::set m_pointersReferencingMe; -}; - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -template -void PdmObject::parentObjectsOfType(std::vector& objects) const -{ - std::vector parents; - this->parentObjects(parents); - - for (size_t i = 0; i < parents.size(); i++) - { - T* objectOfType = dynamic_cast(parents[i]); - if (objectOfType) - { - objects.push_back(objectOfType); - } - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -template -void PdmObject::firstAncestorOfType(T*& ancestor) const -{ - std::vector parents; - this->parentObjects(parents); - - while (parents.size() > 0) + void addFieldUiNoDefault(PdmFieldHandle* field, const QString& keyword, PdmUiItemInfo * fieldDescription) { - assert(parents.size() == 1); + addField(field, keyword); - PdmObject* firstParent = parents[0]; - assert(firstParent); - - T* objectOfType = dynamic_cast(firstParent); - if (objectOfType) + PdmUiFieldHandle* uiFieldHandle = field->uiCapability(); + if (uiFieldHandle) { - ancestor = objectOfType; - return; + uiFieldHandle->setUiItemInfo(fieldDescription); } - - // Get next level parents - parents.clear(); - firstParent->parentObjects(parents); } -} +}; } // End of namespace caf diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmObjectFactory.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmObjectFactory.h deleted file mode 100644 index 76e6348655..0000000000 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmObjectFactory.h +++ /dev/null @@ -1,106 +0,0 @@ -//################################################################################################## -// -// Custom Visualization Core library -// Copyright (C) 2011-2013 Ceetron AS -// -// This library may be used under the terms of either the GNU General Public License or -// the GNU Lesser General Public License as follows: -// -// GNU General Public License Usage -// This library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. -// -// See the GNU General Public License at <> -// for more details. -// -// GNU Lesser General Public License Usage -// This library is free software; you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation; either version 2.1 of the License, or -// (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. -// -// See the GNU Lesser General Public License at <> -// for more details. -// -//################################################################################################## - - -#pragma once - -#include - -namespace caf -{ - -class PdmObject; - -//================================================================================================== -/// "Private" class for implementation of a factory for PdmObjectBase derived objects -/// Every PdmObject must register with this factory to be readable -/// This class can be considered private in the Pdm system -//================================================================================================== - -class PdmObjectFactory -{ -public: - static PdmObjectFactory * instance(); - PdmObject * create(const QString& classNameKeyword); - - template< typename PdmObjectBaseDerivative > - bool registerCreator() - { - std::map::iterator entryIt; - - QString classNameKeyword = PdmObjectBaseDerivative::classKeywordStatic(); - - entryIt = m_factoryMap.find(classNameKeyword); - if (entryIt == m_factoryMap.end()) - { - m_factoryMap[classNameKeyword] = new PdmObjectCreator(); - return true; - } - else - { - assert(classNameKeyword != entryIt->first); // classNameKeyword has already been used - assert(false); // To be sure .. - return false; // never hit; - } - } - -private: - PdmObjectFactory() {} - ~PdmObjectFactory() { /* Could clean up, but ... */ } - - // Internal helper classes - - class PdmObjectCreatorBase - { - public: - PdmObjectCreatorBase() {} - virtual ~PdmObjectCreatorBase() {} - virtual PdmObject * create() = 0; - }; - - template< typename PdmObjectBaseDerivative > - class PdmObjectCreator : public PdmObjectCreatorBase - { - public: - virtual PdmObject * create() { return new PdmObjectBaseDerivative(); } - }; - - // Map to store factory - std::map m_factoryMap; -}; - - -} //End of namespace caf diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmObjectGroup.cpp b/Fwk/AppFwk/cafProjectDataModel/cafPdmObjectGroup.cpp new file mode 100644 index 0000000000..c021c3ab5f --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmObjectGroup.cpp @@ -0,0 +1,70 @@ + + +#include "cafPdmObjectGroup.h" +#include "cafInternalPdmXmlFieldCapability.h" + +#include + +namespace caf +{ + +CAF_PDM_SOURCE_INIT(PdmObjectGroup, "PdmObjectGroup"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +PdmObjectGroup::PdmObjectGroup() +{ + CAF_PDM_InitObject("Object Group", "", "", ""); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +PdmObjectGroup::~PdmObjectGroup() +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmObjectGroup::deleteObjects() +{ + size_t it; + for (it = 0; it != objects.size(); ++it) + { + delete objects[it]; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmObjectGroup::addObject(PdmObjectHandle * obj) +{ + objects.push_back(obj); +} + + + +CAF_PDM_SOURCE_INIT(PdmObjectCollection, "PdmObjectCollection"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +PdmObjectCollection::PdmObjectCollection() +{ + CAF_PDM_InitObject("PdmObjectCollection", "", "", ""); + CAF_PDM_InitFieldNoDefault(&objects, "PdmObjects", "", "", "", "") +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +PdmObjectCollection::~PdmObjectCollection() +{ + +} + +} //End of namespace caf + diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmObjectGroup.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmObjectGroup.h new file mode 100644 index 0000000000..d7e19fc3cc --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmObjectGroup.h @@ -0,0 +1,84 @@ +#pragma once + +#include "cafPdmObject.h" +#include "cafPdmChildArrayField.h" + +#include + +namespace caf +{ + +class PdmReferenceHelper; + +//================================================================================================== +/// The PdmObjectGroup serves as a container of unknown PdmObjects +//================================================================================================== +class PdmObjectGroup : public PdmObject +{ + CAF_PDM_HEADER_INIT; +public: + PdmObjectGroup(); + ~PdmObjectGroup(); + + std::vector objects; + + void deleteObjects(); + void addObject(PdmObjectHandle * obj); + + template + void objectsByType(std::vector >* typedObjects ) const + { + if (!typedObjects) return; + size_t it; + for (it = 0; it != objects.size(); ++it) + { + T* obj = dynamic_cast(objects[it]); + if (obj) typedObjects->push_back(obj); + } + } + + template + void createCopyByType(std::vector >* copyOfTypedObjects, PdmObjectFactory* objectFactory) const; +}; + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +template +void PdmObjectGroup::createCopyByType(std::vector >* copyOfTypedObjects, PdmObjectFactory* objectFactory) const +{ + std::vector > sourceTypedObjects; + objectsByType(&sourceTypedObjects); + + for (size_t i = 0; i < sourceTypedObjects.size(); i++) + { + QString xml = xmlObj(sourceTypedObjects[i])->writeObjectToXmlString(); + + PdmObjectHandle* objectCopy = PdmXmlObjectHandle::readUnknownObjectFromXmlString(xml, PdmDefaultObjectFactory::instance()); + + T* typedObject = dynamic_cast(objectCopy); + assert(typedObject); + + copyOfTypedObjects->push_back(typedObject); + } +} + + +//================================================================================================== +/// The PdmObjectCollection serves as a container of unknown PdmObjects stored in a PdmChildArrayField +//================================================================================================== +class PdmObjectCollection : public PdmObject +{ + CAF_PDM_HEADER_INIT; +public: + PdmObjectCollection(); + ~PdmObjectCollection(); + + caf::PdmChildArrayField objects; +}; + + +} // End of namespace caf + + diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/CMakeLists.txt b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/CMakeLists.txt new file mode 100644 index 0000000000..49361d5ef5 --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/CMakeLists.txt @@ -0,0 +1,54 @@ +cmake_minimum_required (VERSION 2.8) + +project (cafPdmUiCore) + +# Qt +find_package ( Qt4 COMPONENTS QtCore QtGui ) +include (${QT_USE_FILE}) + +include_directories ( + + ${cafPdmCore_SOURCE_DIR} + .. +) + +set( PROJECT_FILES + + cafInternalPdmFieldTypeSpecializations.h + cafInternalPdmUiFieldCapability.h + cafInternalPdmUiFieldCapability.inl + cafInternalPdmUiCommandSystemInterface.h + + cafPdmUiEditorHandle.cpp + cafPdmUiEditorHandle.h + cafPdmUiFieldEditorHandle.cpp + cafPdmUiFieldEditorHandle.h + cafPdmUiFieldHandle.cpp + cafPdmUiFieldHandle.h + cafPdmUiFieldSpecialization.h + cafPdmUiItem.cpp + cafPdmUiItem.h + cafPdmUiObjectEditorHandle.cpp + cafPdmUiObjectEditorHandle.h + cafPdmUiObjectHandle.cpp + cafPdmUiObjectHandle.h + cafPdmUiOrdering.cpp + cafPdmUiOrdering.h + cafPdmUiCommandSystemProxy.cpp + cafPdmUiCommandSystemProxy.h + cafPdmUiTreeOrdering.cpp + cafPdmUiTreeOrdering.h + cafUiTreeItem.h + + cafSelectionManager.cpp + cafSelectionManager.h + + +) + + +add_library( ${PROJECT_NAME} + ${PROJECT_FILES} +) + +source_group("" FILES ${PROJECT_FILES}) \ No newline at end of file diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafInternalPdmFieldTypeSpecializations.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafInternalPdmFieldTypeSpecializations.h new file mode 100644 index 0000000000..749c956410 --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafInternalPdmFieldTypeSpecializations.h @@ -0,0 +1,222 @@ +#pragma once + +#include "cafPdmObjectHandle.h" +#include "cafPdmPointer.h" + +#include + +namespace caf +{ + +template class PdmDataValueField; +template class PdmPointer; +template class AppEnum; + +//================================================================================================== +/// Partial specialization for PdmField< PdmPointer > +/// +/// Will package the PdmPointer into QVariant as PdmPointer +/// Needed to support arbitrary types in PdmPointer without +/// havning to declare everything Q_DECLARE_METATYPE() +/// Also introduces the need for a isEqual() method, as this was the first +/// custom type embedded in QVariant +//================================================================================================== + +template +class PdmUiFieldSpecialization < PdmPointer > +{ +public: + static QVariant convert(const PdmPointer& value) + { + return QVariant::fromValue(PdmPointer(value.rawPtr())); + } + + static void setFromVariant(const QVariant& variantValue, PdmPointer& value) + { + value.setRawPtr(variantValue.value >().rawPtr()); + } + + static bool isEqual(const QVariant& variantValue, const QVariant& variantValue2) + { + return variantValue.value >() == variantValue2.value >() ; + } + + static QList valueOptions(bool* useOptionsOnly, const PdmPointer&) + { + return QList(); + } +}; + +//================================================================================================== +/// Partial specialization for PdmField< std::list > +//================================================================================================== + +template +class PdmUiFieldSpecialization < std::list > +{ +public: + /// Convert the field value into a QVariant + static QVariant convert(const std::list& value) + { + QList returnList; + typename std::list::const_iterator it; + for (it = value.begin(); it != value.end() ; ++it) + { + returnList.push_back(QVariant(*it)); + } + return returnList; + } + + + /// Set the field value from a QVariant + static void setFromVariant(const QVariant& variantValue, std::list& value) + { + if (variantValue.canConvert< QList >()) + { + value.clear(); + QList lst = variantValue.toList(); + int i; + for (i = 0; i < lst.size(); ++i) + { + value.push_back(lst[i].value()); + } + } + } + + static bool isEqual(const QVariant& variantValue, const QVariant& variantValue2) + { + return variantValue == variantValue2; + } + + /// Methods to get a list of options for a field, specialized for AppEnum + static QList valueOptions( bool* useOptionsOnly, const std::list& ) + { + return QList(); + } + + /// Methods to retrieve the possible PdmObject pointed to by a field + static void childObjects(const PdmDataValueField< std::list >& , std::vector* ) + { } + +}; + +//================================================================================================== +/// Partial specialization for PdmField< std::vector > +//================================================================================================== + +template +class PdmUiFieldSpecialization < std::vector > +{ +public: + /// Convert the field value into a QVariant + static QVariant convert(const std::vector& value) + { + QList returnList; + typename std::vector::const_iterator it; + for (it = value.begin(); it != value.end() ; ++it) + { + returnList.push_back(QVariant(*it)); + } + return returnList; + } + + /// Set the field value from a QVariant + static void setFromVariant(const QVariant& variantValue, std::vector& value) + { + if (variantValue.canConvert< QList >()) + { + value.clear(); + QList lst = variantValue.toList(); + int i; + for (i = 0; i < lst.size(); ++i) + { + value.push_back(lst[i].value()); + } + } + } + + static bool isEqual(const QVariant& variantValue, const QVariant& variantValue2) + { + return variantValue == variantValue2; + } + + /// Methods to get a list of options for a field, specialized for AppEnum + static QList valueOptions( bool* useOptionsOnly, const std::vector& ) + { + return QList(); + } + + /// Methods to retrieve the possible PdmObject pointed to by a field + static void childObjects(const PdmDataValueField< std::vector > & field, std::vector* objects) + { } + +}; + +//================================================================================================== +/// Partial specialization for PdmField< caf::AppEnum > +/// +/// Note : Makes the setUiValue() and uiValue() interface index based, and NOT based on real enum values. +/// The valueOptions() interface is thus also index based (the value in the PdmOptionItemInfo is index NOT enum) +/// This is probably going to change, ans it is strange. +/// This conversion should really be done in the editors we think (now) +//================================================================================================== + +#define PDMFIELDAPPENUM_USE_INDEX_BASED_INTERFACE 1 + +template +class PdmUiFieldSpecialization < caf::AppEnum > +{ +public: + /// Convert the field value into a QVariant + static QVariant convert(const caf::AppEnum& value) + { +#if PDMFIELDAPPENUM_USE_INDEX_BASED_INTERFACE + return QVariant(static_cast(caf::AppEnum::index(value))); +#else + unsigned int enumVal = value; + return QVariant(enumVal); +#endif + } + + /// Set the field value from a QVariant + static void setFromVariant(const QVariant& variantValue, caf::AppEnum& value) + { +#if PDMFIELDAPPENUM_USE_INDEX_BASED_INTERFACE + value.setFromIndex(variantValue.toInt()); +#else + value = static_cast (variantValue.toInt()); +#endif + } + + static bool isEqual(const QVariant& variantValue, const QVariant& variantValue2) + { + return variantValue == variantValue2; + } + + /// Methods to get a list of options for a field, specialized for AppEnum + static QList valueOptions( bool* useOptionsOnly, const caf::AppEnum& ) + { + if (useOptionsOnly) *useOptionsOnly = true; + + QStringList optionTexts = caf::AppEnum::uiTexts(); + QList optionList; + int i; + for (i = 0; i < optionTexts.size(); ++i) + { +#if PDMFIELDAPPENUM_USE_INDEX_BASED_INTERFACE + optionList.push_back(PdmOptionItemInfo(optionTexts[i], static_cast(i))); +#else + optionList.push_back(PdmOptionItemInfo(optionTexts[i], caf::AppEnum::fromIndex(i))); +#endif + } + + return optionList; + } + + /// Methods to retrieve the possible PdmObject pointed to by a field + static void childObjects(const PdmDataValueField< caf::AppEnum >& field, std::vector* objects) + { } + +}; + +} // End namespace caf diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafInternalPdmUiCommandSystemInterface.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafInternalPdmUiCommandSystemInterface.h new file mode 100644 index 0000000000..07f247fef7 --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafInternalPdmUiCommandSystemInterface.h @@ -0,0 +1,60 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) Ceetron Solutions AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + +#pragma once + +class QVariant; +class QMenu; +class QString; + +namespace caf +{ + +class PdmFieldHandle; +class PdmUiFieldHandle; + + +class PdmUiCommandSystemInterface +{ +public: + virtual void fieldChangedCommand(PdmFieldHandle* field, const QVariant& newUiValue) = 0; + virtual void populateMenuWithDefaultCommands(const QString& uiConfigName, QMenu* menu) = 0; +}; + + + +} // End of namespace caf + diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafInternalPdmUiFieldCapability.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafInternalPdmUiFieldCapability.h new file mode 100644 index 0000000000..ffa429089a --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafInternalPdmUiFieldCapability.h @@ -0,0 +1,83 @@ +#pragma once + +#include "cafPdmUiFieldHandle.h" + +namespace caf +{ + + + +template < typename FieldType> +class PdmFieldUiCap : public PdmUiFieldHandle +{ +public: + PdmFieldUiCap(FieldType* field, bool giveOwnership) : PdmUiFieldHandle(field, giveOwnership) { m_field = field; } + + // Gui generalized interface +public: + virtual QVariant uiValue() const; + virtual void setValueFromUi(const QVariant& uiValue); + virtual QList valueOptions(bool* useOptionsOnly); + + virtual QVariant toUiBasedQVariant() const; + +private: + QList m_optionEntryCache; + +private: + FieldType* m_field; +}; + + + +// +// Specialization for ChildFields to do nothing towards GUI +// +template < typename DataType> +class PdmFieldUiCap< PdmChildField > : public PdmUiFieldHandle +{ + typedef PdmChildField FieldType; +public: + PdmFieldUiCap(FieldType* field, bool giveOwnership) : PdmUiFieldHandle(field, giveOwnership) { } + + // Gui generalized interface +public: + virtual QVariant uiValue() const { return QVariant();} + virtual void setValueFromUi(const QVariant& uiValue) { } + virtual QList valueOptions(bool* useOptionsOnly) { return QList(); } + + virtual QVariant toUiBasedQVariant() const { return QVariant(); } +}; + +// +// Specialization for ChildArrayFields to do nothing towards GUI +// +template < typename DataType> +class PdmFieldUiCap< PdmChildArrayField > : public PdmUiFieldHandle +{ + typedef PdmChildArrayField FieldType; +public: + PdmFieldUiCap(FieldType* field, bool giveOwnership) : PdmUiFieldHandle(field, giveOwnership) { } + + // Gui generalized interface +public: + virtual QVariant uiValue() const { return QVariant(); } + virtual void setValueFromUi(const QVariant& uiValue) { } + virtual QList valueOptions(bool* useOptionsOnly) { return QList(); } + + virtual QVariant toUiBasedQVariant() const { return QVariant(); } +}; + +template +void AddUiCapabilityToField(FieldType* field) +{ + if(field->template capability< PdmFieldUiCap >() == NULL) + { + new PdmFieldUiCap(field, true); + } +} + + +} // End of namespace caf + +#include "cafInternalPdmUiFieldCapability.inl" diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafInternalPdmUiFieldCapability.inl b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafInternalPdmUiFieldCapability.inl new file mode 100644 index 0000000000..02cdb66ba1 --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafInternalPdmUiFieldCapability.inl @@ -0,0 +1,233 @@ +#pragma once + + +namespace caf +{ + +//-------------------------------------------------------------------------------------------------- +/// This method is supposed to be the interface for the implementation of UI editors to set values into +/// the field. The data to set must be encapsulated in a QVariant. +/// This method triggers PdmObject::fieldChangedByUi() and PdmObject::updateConnectedEditors(), an thus +/// makes the application and the UI aware of the change. +/// +/// Note : If the field has optionValues the interface is _index-based_. The QVariant must contain +/// an UInt representing the index to the option selected by the user interface. +/// +//-------------------------------------------------------------------------------------------------- + +template +void caf::PdmFieldUiCap::setValueFromUi(const QVariant& uiValue) +{ + QVariant oldUiBasedQVariant = toUiBasedQVariant(); + + // Check whether we are handling selections of values or actual values + if (m_optionEntryCache.size()) + { + // This has an option based GUI, the uiValue is only indexes into the m_optionEntryCache + if (uiValue.type() == QVariant::UInt) + { + assert(uiValue.toUInt() < static_cast(m_optionEntryCache.size())); + typename FieldType::FieldDataType value; + PdmUiFieldSpecialization::setFromVariant(m_optionEntryCache[uiValue.toUInt()].value, value); + m_field->setValue(value); + } + else if (uiValue.type() == QVariant::List) + { + QList selectedIndexes = uiValue.toList(); + QList valuesToSetInField; + + if (selectedIndexes.isEmpty()) + { + typename FieldType::FieldDataType value; + PdmUiFieldSpecialization::setFromVariant(valuesToSetInField, value); + m_field->setValue(value); + } + else + { + if (selectedIndexes.front().type() == QVariant::UInt) + { + for (int i = 0; i < selectedIndexes.size(); ++i) + { + unsigned int opIdx = selectedIndexes[i].toUInt(); + if (opIdx < static_cast(m_optionEntryCache.size())) + { + valuesToSetInField.push_back(m_optionEntryCache[opIdx].value); + } + } + typename FieldType::FieldDataType value; + PdmUiFieldSpecialization::setFromVariant(valuesToSetInField, value); + m_field->setValue(value); + } + else + { + // We are not getting indexes as expected from the UI. For now assert, to catch this condition + // but it should possibly be handled as setting the values explicitly. The code for that is below the assert + assert(false); + typename FieldType::FieldDataType value; + PdmUiFieldSpecialization::setFromVariant(uiValue, value); + m_field->setValue(value); + m_optionEntryCache.clear(); + } + } + + } + else + { + // We are not getting indexes as expected from the UI. For now assert, to catch this condition + // but it should possibly be handled as setting the values explicitly. The code for that is below the assert + assert(false); + typename FieldType::FieldDataType value; + PdmUiFieldSpecialization::setFromVariant(uiValue, value); + m_field->setValue(value); + m_optionEntryCache.clear(); + } + } + else + { // Not an option based GUI, the uiValue is a real field value + typename FieldType::FieldDataType value; + PdmUiFieldSpecialization::setFromVariant(uiValue, value); + m_field->setValue(value); + } + + QVariant newUiBasedQVariant = toUiBasedQVariant(); + + this->notifyFieldChanged(oldUiBasedQVariant, newUiBasedQVariant); +} + + +//-------------------------------------------------------------------------------------------------- +/// Extracts a QVariant representation of the data in the field to be used in the UI. +/// +/// Note : For fields with a none-empty valueOptions list, the returned QVariant contains the +/// _indexes_ to the selected options rather than the actual values, if they can be found. +/// +/// If this is a multivalue field, and we cant find all of the field values among the options, +/// the method asserts (For now), forcing the valueOptions to always contain the field values. +/// Single value fields will return -1 if the option is not found, allowing the concept of "nothing selected" +//-------------------------------------------------------------------------------------------------- + +template +QVariant caf::PdmFieldUiCap::uiValue() const +{ + if (m_optionEntryCache.size()) + { + QVariant uiBasedQVariant = toUiBasedQVariant(); + std::vector indexesToFoundOptions; + PdmOptionItemInfo::findValues(m_optionEntryCache, uiBasedQVariant, indexesToFoundOptions); + if (uiBasedQVariant.type() == QVariant::List) + { + if (indexesToFoundOptions.size() == static_cast(uiBasedQVariant.toList().size())) + { + QList returnList; + for (size_t i = 0; i < indexesToFoundOptions.size(); ++i) + { + returnList.push_back(QVariant(indexesToFoundOptions[i])); + } + return QVariant(returnList); + } + assert(false); // Did not find all the field values among the options available. + } + else + { + if (indexesToFoundOptions.size() == 1) return QVariant(indexesToFoundOptions.front()); + else return QVariant(-1); // Return -1 if not found instead of assert. Should result in clearing the selection + } + + assert(false); + return uiBasedQVariant; + } + else + { + return toUiBasedQVariant(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// Returns the option values that is to be displayed in the UI for this field. +/// This method calls the virtual PdmObject::calculateValueOptions to get the list provided from the +/// application, then possibly adds the current field value(s) to the list, to +/// make sure the actual values are shown +/// +/// Note: This method is missing the uiConfigName concept. This is a Todo. The m_optionEntryCache +/// then needs to be stored pr. uiConfigName. +//-------------------------------------------------------------------------------------------------- + +template +QList caf::PdmFieldUiCap::valueOptions(bool* useOptionsOnly) +{ + // First check if the owner PdmObject has a value options specification. + // if it has, use it. + if (m_field->ownerObject()) + { + m_optionEntryCache = uiObj(m_field->ownerObject())->calculateValueOptions(this->m_field, useOptionsOnly); + if (m_optionEntryCache.size()) + { + // Make sure the options contain the field values, event though they not necessarily + // is supplied as possible options by the application. This is a convenience making sure + // the actual data in the pdmObject is shown correctly in the UI, and to prevent accidental + // changes of the field values + + // Find the field value(s) in the list if present + + QVariant uiBasedQVariant = toUiBasedQVariant(); + + std::vector foundIndexes; + bool foundAllFieldValues = PdmOptionItemInfo::findValues(m_optionEntryCache, uiBasedQVariant, foundIndexes); + + // If not all are found, we have to add the missing to the list, to be able to show it + + if (!foundAllFieldValues) + { + if (uiBasedQVariant.type() != QVariant::List) // Single value field + { + if (!uiBasedQVariant.toString().isEmpty()) + { + m_optionEntryCache.push_front(PdmOptionItemInfo(uiBasedQVariant.toString(), uiBasedQVariant, true, QIcon())); + } + } + else // The field value is a list of values + { + QList valuesSelectedInField = uiBasedQVariant.toList(); + for (int i= 0 ; i < valuesSelectedInField.size(); ++i) + { + bool isFound = false; + for (unsigned int opIdx = 0; opIdx < static_cast(m_optionEntryCache.size()); ++opIdx) + { + if (valuesSelectedInField[i] == m_optionEntryCache[opIdx].value) isFound = true; + } + + if (!isFound && !valuesSelectedInField[i].toString().isEmpty()) + { + m_optionEntryCache.push_front(PdmOptionItemInfo(valuesSelectedInField[i].toString(), valuesSelectedInField[i], true, QIcon())); + } + } + } + } + + return m_optionEntryCache; + } + } + + // If we have no options, use the options defined by the type. Normally only caf::AppEnum type + +#if 0 + m_optionEntryCache = PdmFieldTypeSpecialization::valueOptions(useOptionsOnly, m_fieldValue); + return m_optionEntryCache; +#else + return PdmUiFieldSpecialization::valueOptions(useOptionsOnly, m_field->value()); +#endif + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +template +QVariant caf::PdmFieldUiCap::toUiBasedQVariant() const +{ + return PdmUiFieldSpecialization::convert(m_field->value()); +} + + +} // End of namespace caf + diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiCommandSystemProxy.cpp b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiCommandSystemProxy.cpp new file mode 100644 index 0000000000..c6cf9c1f4d --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiCommandSystemProxy.cpp @@ -0,0 +1,108 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) Ceetron Solutions AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + +#include "cafPdmUiCommandSystemProxy.h" + +#include "cafInternalPdmUiCommandSystemInterface.h" + +#include "cafPdmFieldHandle.h" +#include "cafPdmObjectHandle.h" +#include "cafPdmUiFieldHandle.h" +#include "cafPdmUiObjectHandle.h" + +#include + + +namespace caf { + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +PdmUiCommandSystemProxy* PdmUiCommandSystemProxy::instance() +{ + static PdmUiCommandSystemProxy staticInstance; + + return &staticInstance; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +PdmUiCommandSystemProxy::PdmUiCommandSystemProxy() +{ + m_commandInterface = NULL; + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiCommandSystemProxy::setCommandInterface(PdmUiCommandSystemInterface* commandInterface) +{ + m_commandInterface = commandInterface; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiCommandSystemProxy::setUiValueToField(PdmUiFieldHandle* uiFieldHandle, const QVariant& newUiValue) +{ + if (uiFieldHandle) + { + if (m_commandInterface) + { + m_commandInterface->fieldChangedCommand(uiFieldHandle->fieldHandle(), newUiValue); + } + else + { + uiFieldHandle->setValueFromUi(newUiValue); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiCommandSystemProxy::populateMenuWithDefaultCommands(const QString& uiConfigName, QMenu* menu) +{ + if (m_commandInterface) + { + m_commandInterface->populateMenuWithDefaultCommands(uiConfigName, menu); + } +} + +} // end namespace caf diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiCommandSystemProxy.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiCommandSystemProxy.h new file mode 100644 index 0000000000..8d04ddb63e --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiCommandSystemProxy.h @@ -0,0 +1,67 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) Ceetron Solutions AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + +#pragma once + +class QVariant; +class QMenu; +class QString; + +namespace caf +{ + +class PdmFieldHandle; +class PdmUiFieldHandle; +class PdmUiCommandSystemInterface; + + +class PdmUiCommandSystemProxy +{ +public: + PdmUiCommandSystemProxy(); + + static PdmUiCommandSystemProxy* instance(); + void setCommandInterface(PdmUiCommandSystemInterface* undoCommandInterface); + + void setUiValueToField(PdmUiFieldHandle* uiFieldHandle, const QVariant& newUiValue); + void populateMenuWithDefaultCommands(const QString& uiConfigName, QMenu* menu); + +private: + PdmUiCommandSystemInterface* m_commandInterface; +}; + +} // End of namespace caf + diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiEditorHandle.cpp b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiEditorHandle.cpp similarity index 90% rename from Fwk/AppFwk/cafProjectDataModel/cafPdmUiEditorHandle.cpp rename to Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiEditorHandle.cpp index b59abf0564..2b7bf1c3d2 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiEditorHandle.cpp +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiEditorHandle.cpp @@ -36,11 +36,18 @@ #include "cafPdmUiEditorHandle.h" -#include "cafPdmUiItem.h" namespace caf { +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +PdmUiEditorHandle::PdmUiEditorHandle() : m_pdmItem(NULL) +{ + +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -59,5 +66,6 @@ void PdmUiEditorHandle::bindToPdmItem(PdmUiItem* item) if (m_pdmItem) m_pdmItem->addFieldEditor(this); } + } //End of namespace caf diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiEditorHandle.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiEditorHandle.h similarity index 97% rename from Fwk/AppFwk/cafProjectDataModel/cafPdmUiEditorHandle.h rename to Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiEditorHandle.h index c03dc8a66e..5e699b152e 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiEditorHandle.h +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiEditorHandle.h @@ -36,24 +36,24 @@ #pragma once -#include -#include -#include + #include "cafPdmUiItem.h" +#include + namespace caf { class PdmUiItem; //================================================================================================== -/// Abstract class to handle editors +/// Abstract class to handle editors. Inherits QObject to be able to use signals and slots //================================================================================================== class PdmUiEditorHandle: public QObject { public: - PdmUiEditorHandle() : m_pdmItem(NULL) {} + PdmUiEditorHandle(); virtual ~PdmUiEditorHandle(); public: diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiFieldEditorHandle.cpp b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiFieldEditorHandle.cpp similarity index 81% rename from Fwk/AppFwk/cafProjectDataModel/cafPdmUiFieldEditorHandle.cpp rename to Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiFieldEditorHandle.cpp index 2d0ecdc277..87588d2fa6 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiFieldEditorHandle.cpp +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiFieldEditorHandle.cpp @@ -36,7 +36,11 @@ #include "cafPdmUiFieldEditorHandle.h" -#include "cafPdmField.h" + +#include "cafPdmUiFieldHandle.h" +#include "cafPdmUiCommandSystemProxy.h" + +#include namespace caf { @@ -57,15 +61,15 @@ PdmUiFieldEditorHandle::PdmUiFieldEditorHandle() //-------------------------------------------------------------------------------------------------- PdmUiFieldEditorHandle::~PdmUiFieldEditorHandle() { - if (!m_combinedWidget.isNull()) delete m_combinedWidget; - if (!m_editorWidget.isNull()) delete m_editorWidget ; - if (!m_labelWidget.isNull()) delete m_labelWidget; + if (!m_combinedWidget.isNull()) m_combinedWidget->deleteLater(); + if (!m_editorWidget.isNull()) m_editorWidget->deleteLater(); + if (!m_labelWidget.isNull()) m_labelWidget->deleteLater(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void PdmUiFieldEditorHandle::setField(PdmFieldHandle * field) +void PdmUiFieldEditorHandle::setField(PdmUiFieldHandle * field) { this->bindToPdmItem(field); } @@ -73,9 +77,9 @@ void PdmUiFieldEditorHandle::setField(PdmFieldHandle * field) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -PdmFieldHandle* PdmUiFieldEditorHandle::field() +PdmUiFieldHandle* PdmUiFieldEditorHandle::field() { - return dynamic_cast(pdmItem()); + return dynamic_cast(pdmItem()); } //-------------------------------------------------------------------------------------------------- @@ -89,11 +93,13 @@ void PdmUiFieldEditorHandle::createWidgets(QWidget * parent) } //-------------------------------------------------------------------------------------------------- -/// +/// Well this is food for thought. How do we spawn commands, without making us +/// dependent on the command system. It should be optional to use, and not depending on the command "library" +/// JJS //-------------------------------------------------------------------------------------------------- -void PdmUiFieldEditorHandle::setValueToField(const QVariant& value) +void PdmUiFieldEditorHandle::setValueToField(const QVariant& newUiValue) { - if (field()) field()->setValueFromUi(value); + PdmUiCommandSystemProxy::instance()->setUiValueToField(field(), newUiValue); } diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiFieldEditorHandle.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiFieldEditorHandle.h similarity index 92% rename from Fwk/AppFwk/cafProjectDataModel/cafPdmUiFieldEditorHandle.h rename to Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiFieldEditorHandle.h index b685d1fa5a..09120b2456 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiFieldEditorHandle.h +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiFieldEditorHandle.h @@ -36,17 +36,17 @@ #pragma once + +#include "cafFactory.h" +#include "cafPdmUiEditorHandle.h" +#include "cafClassTypeName.h" + #include -#include -#include "cafPdmUiItem.h" #include +#include #include -#include "cafFactory.h" - -#include "cafPdmUiEditorHandle.h" -#include // Taken from gtest.h // @@ -68,9 +68,6 @@ namespace caf /// Macros helping in development of PDM UI editors //================================================================================================== -/// Create a QString based on a typename -#define qStringTypeName(TypeName) QString(typeid(TypeName).name()) - /// CAF_PDM_UI_EDITOR_HEADER_INIT assists the factory used when creating editors /// Place this in the header file inside the class definition of your PdmUiEditor @@ -86,10 +83,11 @@ public: \ static bool PDM_FIELD_EDITOR_STRING_CONCATENATE(pdm_field_editor_registrate_, __LINE__) = caf::Factory::instance()->registerCreator(EditorClassName::uiEditorTypeName()) #define CAF_PDM_UI_REGISTER_DEFAULT_FIELD_EDITOR(EditorClassName, TypeName) \ - static bool PDM_FIELD_EDITOR_STRING_CONCATENATE(pdm_field_register_default_editor_, __LINE__) = caf::Factory::instance()->registerCreator(qStringTypeName(caf::PdmField)) + static bool PDM_FIELD_EDITOR_STRING_CONCATENATE(pdm_field_register_default_editor_, __LINE__) = caf::Factory::instance()->registerCreator(qStringTypeName(caf::PdmField)); \ + static bool PDM_FIELD_EDITOR_STRING_CONCATENATE(pdm_Proxy_field_register_default_editor_, __LINE__) = caf::Factory::instance()->registerCreator(qStringTypeName(caf::PdmProxyValueField)) class PdmUiGroup; -class PdmFieldHandle; +class PdmUiFieldHandle; //================================================================================================== /// Abstract class to handle editors of PdmFields @@ -102,8 +100,8 @@ class PdmUiFieldEditorHandle : public PdmUiEditorHandle PdmUiFieldEditorHandle(); ~PdmUiFieldEditorHandle(); - PdmFieldHandle* field(); - void setField(PdmFieldHandle * field); + PdmUiFieldHandle* field(); + void setField(PdmUiFieldHandle * field); void createWidgets(QWidget * parent); QWidget* combinedWidget() { return m_combinedWidget; } diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiFieldHandle.cpp b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiFieldHandle.cpp new file mode 100644 index 0000000000..485a0064a5 --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiFieldHandle.cpp @@ -0,0 +1,54 @@ +#include "cafPdmUiFieldHandle.h" +#include "cafPdmFieldHandle.h" + +#include "cafPdmUiObjectHandle.h" + +#include + +namespace caf +{ + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +PdmUiFieldHandle::PdmUiFieldHandle(PdmFieldHandle* owner, bool giveOwnership) +{ + m_owner = owner; + owner->addCapability(this, giveOwnership); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiFieldHandle::notifyFieldChanged(const QVariant& oldFieldValue, const QVariant& newFieldValue) +{ + if (oldFieldValue != newFieldValue) + { + PdmFieldHandle* fieldHandle = this->fieldHandle(); + assert(fieldHandle && fieldHandle->ownerObject()); + + PdmUiObjectHandle* uiObjHandle = uiObj(fieldHandle->ownerObject()); + if (uiObjHandle) + { + uiObjHandle->fieldChangedByUi(fieldHandle, oldFieldValue, newFieldValue); + uiObjHandle->updateConnectedEditors(); + } + + // Update field editors + this->updateConnectedEditors(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// Implementation of uiCapability() defined in cafPdmFieldHandle.h +//-------------------------------------------------------------------------------------------------- +PdmUiFieldHandle* PdmFieldHandle::uiCapability() +{ + PdmUiFieldHandle* uiField = capability(); + assert(uiField); + + return uiField; +} + +} // End of namespace caf diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiFieldHandle.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiFieldHandle.h new file mode 100644 index 0000000000..8b8c0c8f11 --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiFieldHandle.h @@ -0,0 +1,35 @@ +#pragma once + +#include "cafPdmUiItem.h" +#include "cafPdmFieldCapability.h" + +namespace caf +{ + +class PdmFieldHandle; + +class PdmUiFieldHandle : public PdmUiItem, public PdmFieldCapability +{ +public: + PdmUiFieldHandle(PdmFieldHandle* owner, bool giveOwnership); + virtual ~PdmUiFieldHandle() { } + + PdmFieldHandle* fieldHandle() { return m_owner; } + + // Generalized access methods for User interface + // The QVariant encapsulates the real value, or an index into the valueOptions + + virtual QVariant uiValue() const { return QVariant(); } + virtual void setValueFromUi(const QVariant& uiValue) { } + virtual QList + valueOptions(bool* useOptionsOnly) { return QList(); } + + virtual QVariant toUiBasedQVariant() const { return QVariant(); } + void notifyFieldChanged(const QVariant& oldUiBasedQVariant, const QVariant& newUiBasedQVariant); + +private: + PdmFieldHandle* m_owner; +}; + + +} // End of namespace caf diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiFieldSpecialization.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiFieldSpecialization.h new file mode 100644 index 0000000000..99c38d331b --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiFieldSpecialization.h @@ -0,0 +1,65 @@ +#pragma once + +#include +#include + +#include + +namespace caf +{ + +template class PdmDataValueField; +class PdmOptionItemInfo; +class PdmObjectHandle; + +//================================================================================================== +/// A proxy class that implements the Gui interface of fields +/// +/// This class collects methods that need specialization when introducing a new type in a PdmField. +/// Having those methods in a separate class makes it possible to "partially specialize" the methods +/// for container classes etc. since partial specialization of template functions is not C++ as of yet. +/// +/// When introducing a new type in a PdmField, you might need to implement a (partial)specialization +/// of this class. +//================================================================================================== + +template +class PdmUiFieldSpecialization +{ +public: + /// Convert the field value into a QVariant + static QVariant convert(const T& value) + { + return QVariant::fromValue(value); + } + + /// Set the field value from a QVariant + static void setFromVariant(const QVariant& variantValue, T& value) + { + value = variantValue.value(); + } + + /// Check equality between QVariants that carries a Field Value. + /// The == operator will normally work, but does not support custom types in the QVariant + /// See http://qt-project.org/doc/qt-4.8/qvariant.html#operator-eq-eq-64 + /// This is needed for the lookup regarding OptionValues + static bool isEqual(const QVariant& variantValue, const QVariant& variantValue2) + { + return variantValue == variantValue2; + } + + /// Methods to get a list of options for a field, specialized for AppEnum + static QList valueOptions( bool* useOptionsOnly, const T& ) + { + return QList(); + } + + /// Methods to retrieve the possible PdmObject pointed to by a field + static void childObjects(const PdmDataValueField& , std::vector* ) + { } + +}; +} // End of namespace caf + +#include "cafInternalPdmFieldTypeSpecializations.h" + diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiItem.cpp b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiItem.cpp similarity index 86% rename from Fwk/AppFwk/cafProjectDataModel/cafPdmUiItem.cpp rename to Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiItem.cpp index 8ecc7533c4..d6e385ac9a 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiItem.cpp +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiItem.cpp @@ -55,51 +55,6 @@ QStringList PdmOptionItemInfo::extractUiTexts(const QList& op return texts; } -//-------------------------------------------------------------------------------------------------- -/// Finds the indexes into the optionList that the field value(s) corresponds to. -/// In the case where the field is some kind of array, several indexes might be returned -/// The returned bool is true if all the fieldValues were found. -//-------------------------------------------------------------------------------------------------- -bool PdmOptionItemInfo::findValues(const QList& optionList , QVariant fieldValue, std::vector& foundIndexes) -{ - foundIndexes.clear(); - - // Find this fieldvalue in the optionlist if present - - // First handle lists/arrays of values - if (fieldValue.type() == QVariant::List) - { - QList valuesSelectedInField = fieldValue.toList(); - - if (valuesSelectedInField.size()) - { - for (int i= 0 ; i < valuesSelectedInField.size(); ++i) - { - for (unsigned int opIdx = 0; opIdx < static_cast(optionList.size()); ++opIdx) - { - if (valuesSelectedInField[i] == optionList[opIdx].value) - { - foundIndexes.push_back(opIdx); - } - } - } - } - - return (static_cast(valuesSelectedInField.size()) <= foundIndexes.size()); - } - else // Then handle single value fields - { - for(unsigned int opIdx = 0; opIdx < static_cast(optionList.size()); ++opIdx) - { - if (optionList[opIdx].value == fieldValue) - { - foundIndexes.push_back(opIdx); - break; - } - } - return (foundIndexes.size() > 0); - } -} //-------------------------------------------------------------------------------------------------- diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiItem.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiItem.h similarity index 81% rename from Fwk/AppFwk/cafProjectDataModel/cafPdmUiItem.h rename to Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiItem.h index 00de8915e3..cf0104d443 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiItem.h +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiItem.h @@ -36,6 +36,9 @@ #pragma once + +#include "cafPdmUiFieldSpecialization.h" + #include #include #include @@ -96,11 +99,58 @@ class PdmOptionItemInfo // Please regard as private to the PDM system static QStringList extractUiTexts(const QList& optionList ); + template static bool findValues (const QList& optionList , QVariant fieldValue, std::vector& foundIndexes); }; class PdmUiEditorHandle; +//-------------------------------------------------------------------------------------------------- +/// Finds the indexes into the optionList that the field value(s) corresponds to. +/// In the case where the field is some kind of array, several indexes might be returned +/// The returned bool is true if all the fieldValues were found. +//-------------------------------------------------------------------------------------------------- +template +bool PdmOptionItemInfo::findValues(const QList& optionList, QVariant fieldValue, std::vector& foundIndexes) +{ + foundIndexes.clear(); + + // Find this fieldvalue in the optionlist if present + + // First handle lists/arrays of values + if (fieldValue.type() == QVariant::List) + { + QList valuesSelectedInField = fieldValue.toList(); + + if (valuesSelectedInField.size()) + { + for (int i= 0 ; i < valuesSelectedInField.size(); ++i) + { + for (unsigned int opIdx = 0; opIdx < static_cast(optionList.size()); ++opIdx) + { + if (PdmUiFieldSpecialization::isEqual(valuesSelectedInField[i], optionList[opIdx].value)) + { + foundIndexes.push_back(opIdx); + } + } + } + } + + return (static_cast(valuesSelectedInField.size()) <= foundIndexes.size()); + } + else // Then handle single value fields + { + for (unsigned int opIdx = 0; opIdx < static_cast(optionList.size()); ++opIdx) + { + if (PdmUiFieldSpecialization::isEqual(optionList[opIdx].value, fieldValue)) + { + foundIndexes.push_back(opIdx); + break; + } + } + return (foundIndexes.size() > 0); + } +} //================================================================================================== /// Base class for all datastructure items (fields or objects) to make them have information on diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiObjectEditorHandle.cpp b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiObjectEditorHandle.cpp similarity index 84% rename from Fwk/AppFwk/cafProjectDataModel/cafPdmUiObjectEditorHandle.cpp rename to Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiObjectEditorHandle.cpp index be166acb83..944df284d6 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiObjectEditorHandle.cpp +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiObjectEditorHandle.cpp @@ -36,7 +36,9 @@ #include "cafPdmUiObjectEditorHandle.h" -#include "cafPdmObject.h" + +#include "cafPdmObjectHandle.h" +#include "cafPdmUiObjectHandle.h" namespace caf { @@ -57,19 +59,28 @@ QWidget* PdmUiObjectEditorHandle::getOrCreateWidget(QWidget* parent) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void PdmUiObjectEditorHandle::setPdmObject(PdmObject* object) +void PdmUiObjectEditorHandle::setPdmObject(PdmObjectHandle* object) { cleanupBeforeSettingPdmObject(); - this->bindToPdmItem(object); + caf::PdmUiObjectHandle* uiObject = uiObj(object); + this->bindToPdmItem(uiObject); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -PdmObject* PdmUiObjectEditorHandle::pdmObject() +PdmObjectHandle* PdmUiObjectEditorHandle::pdmObject() { - return dynamic_cast(pdmItem()); + PdmUiObjectHandle* uiObject = dynamic_cast(pdmItem()); + if (uiObject) + { + return uiObject->objectHandle(); + } + else + { + return NULL; + } } } //End of namespace caf diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiObjectEditorHandle.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiObjectEditorHandle.h similarity index 94% rename from Fwk/AppFwk/cafProjectDataModel/cafPdmUiObjectEditorHandle.h rename to Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiObjectEditorHandle.h index f7bcb41bfd..eee58affd0 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiObjectEditorHandle.h +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiObjectEditorHandle.h @@ -36,17 +36,20 @@ #pragma once -#include -#include -#include -#include + #include "cafPdmUiEditorHandle.h" #include "cafPdmPointer.h" +#include +#include +#include + +#include + namespace caf { -class PdmObject; +class PdmObjectHandle; //================================================================================================== /// Abstract class to handle editors for complete PdmObjects @@ -61,15 +64,15 @@ class PdmUiObjectEditorHandle: public PdmUiEditorHandle QWidget* getOrCreateWidget(QWidget* parent); QWidget* widget() { return m_widget; } - void setPdmObject(PdmObject* object); - PdmObject* pdmObject(); + void setPdmObject(PdmObjectHandle* object); + PdmObjectHandle* pdmObject(); protected: virtual QWidget* createWidget(QWidget* parent) = 0; virtual void cleanupBeforeSettingPdmObject() {}; protected: - QPointer m_widget; + QPointer m_widget; }; diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiObjectHandle.cpp b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiObjectHandle.cpp new file mode 100644 index 0000000000..63e692b0ec --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiObjectHandle.cpp @@ -0,0 +1,239 @@ +#include "cafPdmUiObjectHandle.h" + +#include "cafPdmFieldHandle.h" +#include "cafPdmObjectHandle.h" +#include "cafPdmUiFieldHandle.h" +#include "cafPdmUiOrdering.h" +#include "cafPdmUiTreeOrdering.h" + +#include + + +namespace caf +{ + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +PdmUiObjectHandle::PdmUiObjectHandle(PdmObjectHandle* owner, bool giveOwnership) +{ + m_owner = owner; + m_owner->addCapability(this, giveOwnership); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +PdmUiObjectHandle* uiObj(PdmObjectHandle* obj) +{ + if (!obj) return NULL; + PdmUiObjectHandle* uiObject = obj->capability(); + assert(uiObject); + return uiObject; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiObjectHandle::uiOrdering(QString uiConfigName, PdmUiOrdering& uiOrdering) +{ +#if 1 + this->defineUiOrdering(uiConfigName, uiOrdering); + if (!uiOrdering.forgetRemainingFields()) + { + // Add the remaining Fields To UiConfig + std::vector fields; + m_owner->fields(fields); + for (size_t i = 0; i < fields.size(); ++i) + { + PdmUiFieldHandle * field = fields[i]->uiCapability(); + if (!uiOrdering.contains(field)) + { + uiOrdering.add(field->fieldHandle()); + } + } + } +#endif +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiObjectHandle::editorAttribute(const PdmFieldHandle* field, QString uiConfigName, PdmUiEditorAttribute * attribute) +{ + this->defineEditorAttribute(field, uiConfigName, attribute); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiObjectHandle::objectEditorAttribute(QString uiConfigName, PdmUiEditorAttribute* attribute) +{ + this->defineObjectEditorAttribute(uiConfigName, attribute); +} + +//-------------------------------------------------------------------------------------------------- +/// This method creates a tree-representation of the object hierarchy starting at this +/// object to be used for a tree view. +/// This method calls the optional virtual user defined method "defineUiTreeOrdering" to customize the +/// order and content of the children directly below each object. If this method does nothing, +/// the default behavior applies: Add all fields that contains objects, and their objects. +/// +/// The caller is responsible to delete the returned PdmUiTreeOrdering +//-------------------------------------------------------------------------------------------------- +PdmUiTreeOrdering* PdmUiObjectHandle::uiTreeOrdering(QString uiConfigName /*= ""*/) +{ + assert(this); // This method actually is possible to call on a NULL ptr without getting a crash, so we assert instead. + + PdmUiTreeOrdering* uiTreeOrdering = new PdmUiTreeOrdering(NULL, m_owner); + + expandUiTree(uiTreeOrdering, uiConfigName); + + return uiTreeOrdering; +} + +//-------------------------------------------------------------------------------------------------- +/// Adds the direct children of this PdmObject to the PdmUiTree according to +/// the default rules. Add all fields that contains objects, and their objects. +/// Takes into account the control variables regarding this: +/// PdmField::isUiHidden +/// PdmField::isUiChildrenHidden +/// And whether the fields and objects are already added by the user. +//-------------------------------------------------------------------------------------------------- +void PdmUiObjectHandle::addDefaultUiTreeChildren(PdmUiTreeOrdering* uiTreeOrdering) +{ +#if 1 + if (!uiTreeOrdering->forgetRemainingFields()) + { + // Add the remaining Fields To UiConfig + std::vector fields; + m_owner->fields(fields); + + for (size_t fIdx = 0; fIdx < fields.size(); ++fIdx) + { + if (fields[fIdx]->hasChildObjects() && !uiTreeOrdering->containsField(fields[fIdx])) + { + if (fields[fIdx]->uiCapability()->isUiHidden() && !fields[fIdx]->uiCapability()->isUiChildrenHidden()) + { + std::vector children; + fields[fIdx]->childObjects(&children); + + std::set objectsAddedByApplication; + for (int i = 0; i < uiTreeOrdering->childCount(); i++) + { + if (uiTreeOrdering->child(i)->isRepresentingObject()) + { + objectsAddedByApplication.insert(uiTreeOrdering->child(i)->object()); + } + } + + for (size_t cIdx = 0; cIdx < children.size(); cIdx++) + { + if (children[cIdx]) + { + bool isAlreadyAdded = false; + std::set::iterator it = objectsAddedByApplication.find(children[cIdx]); + if (it != objectsAddedByApplication.end()) + { + isAlreadyAdded = true; + break; + } + + if (!isAlreadyAdded) + { + uiTreeOrdering->add(children[cIdx]); + } + } + } + } + else if (!fields[fIdx]->uiCapability()->isUiHidden()) + { + uiTreeOrdering->add(fields[fIdx]); + } + } + } + } +#endif +} + + +//-------------------------------------------------------------------------------------------------- +/// Builds the sPdmUiTree for all the children of @param root recursively, and stores the result +/// in root +//-------------------------------------------------------------------------------------------------- +void PdmUiObjectHandle::expandUiTree(PdmUiTreeOrdering* root, QString uiConfigName /*= "" */) +{ +#if 1 + if (!root || !root->isValid()) return; + + if (root->childCount() > 0) + { + for (int cIdx = 0; cIdx < root->childCount(); ++cIdx) + { + PdmUiTreeOrdering* child = root->child(cIdx); + if (child->isValid() && !child->ignoreSubTree()) + { + expandUiTree(child); + } + } + } + else //( root->childCount() == 0) // This means that no one has tried to expand it. + { + if (!root->ignoreSubTree()) + { + if (root->isRepresentingField() && !root->field()->uiCapability()->isUiChildrenHidden(uiConfigName)) + { + std::vector fieldsChildObjects; + root->field()->childObjects(&fieldsChildObjects); + for (size_t cIdx = 0; cIdx < fieldsChildObjects.size(); ++cIdx) + { + PdmObjectHandle* childObject = fieldsChildObjects[cIdx]; + if (childObject) + { + root->appendChild(uiObj(childObject)->uiTreeOrdering(uiConfigName)); + } + } + } + else if (root->isRepresentingObject()) + { + uiObj(root->object())->defineUiTreeOrdering(*root, uiConfigName); + uiObj(root->object())->addDefaultUiTreeChildren(root); + if (root->childCount()) + { + expandUiTree(root); + } + } + } + } +#endif +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiObjectHandle::updateUiIconFromToggleField() +{ + if (objectToggleField()) + { + PdmUiFieldHandle* uiFieldHandle = objectToggleField()->uiCapability(); + if (uiFieldHandle) + { + bool active = uiFieldHandle->uiValue().toBool(); + updateUiIconFromState(active); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// Implementation of uiCapability() defined in cafPdmObjectHandle.h +//-------------------------------------------------------------------------------------------------- +PdmUiObjectHandle* PdmObjectHandle::uiCapability() +{ + PdmUiObjectHandle* uiField = capability(); + assert(uiField); + + return uiField; +} + +} // End namespace caf diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiObjectHandle.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiObjectHandle.h new file mode 100644 index 0000000000..3b67ad45ba --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiObjectHandle.h @@ -0,0 +1,92 @@ +#pragma once + +#include "cafPdmUiItem.h" +#include "cafPdmObjectCapability.h" + + +namespace caf +{ + +class PdmUiEditorAttribute; +class PdmUiTreeOrdering; +class PdmObjectHandle; +class PdmUiOrdering; +class PdmFieldHandle; +class PdmUiEditorAttribute; + +class PdmUiObjectHandle : public PdmUiItem, public PdmObjectCapability +{ +public: + PdmUiObjectHandle(PdmObjectHandle* owner, bool giveOwnership); + virtual ~PdmUiObjectHandle() { } + + PdmObjectHandle* objectHandle() { return m_owner; } + + /// Method to be called from the Ui classes creating Auto Gui to get the group information + /// supplied by the \sa defineUiOrdering method that can be reimplemented + void uiOrdering(QString uiConfigName, PdmUiOrdering& uiOrdering) ; + + /// Method to be called by Ui displaying a tree representation of the object hierarchy + /// Caller must delete the returned object. + PdmUiTreeOrdering* uiTreeOrdering(QString uiConfigName = ""); + /// Helper function to expand a pre-defined tree start + static void expandUiTree(PdmUiTreeOrdering* root, QString uiConfigName = ""); + + + /// For a specific field, return editor specific parameters used to customize the editor behavior. + void editorAttribute(const PdmFieldHandle* field, QString uiConfigName, PdmUiEditorAttribute * attribute); + + /// Return object editor specific parameters used to customize the editor behavior. + void objectEditorAttribute(QString uiConfigName, PdmUiEditorAttribute* attribute); + + /// Field used to control if field change of and object should be covered by undo/redo framework + virtual bool useUndoRedoForFieldChanged() { return true; } + + void updateUiIconFromToggleField(); + + + // Virtual interface to override in subclasses to support special behaviour if needed +public: // Virtual + virtual PdmFieldHandle* userDescriptionField() { return NULL; } + + /// Field used to toggle object on/off in UI-related uses of the object (ie checkbox in treeview) + virtual PdmFieldHandle* objectToggleField() { return NULL; } + + /// Method to reimplement to catch when the field has changed due to setUiValue() + virtual void fieldChangedByUi(const PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) {} + /// Method to re-implement to supply option values for a specific field + virtual QList + calculateValueOptions(const PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly) { return QList(); } + +protected: + /// Override to customize the order and grouping of the Gui. + /// Fill up the uiOrdering object with groups and field references to create the gui structure + /// If the uiOrdering is empty, it is interpreted as meaning all fields w/o grouping. + virtual void defineUiOrdering(QString uiConfigName, PdmUiOrdering& uiOrdering) {} + + /// Override to customize the tree representations of the object hierarchy. + /// If the PdmUiTreeOrdering is empty, it is interpreted as meaning all fields containing child objects in order + virtual void defineUiTreeOrdering(PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = "") { } + + /// Override to provide editor specific data for the field and uiConfigName + virtual void defineEditorAttribute(const PdmFieldHandle* field, QString uiConfigName, PdmUiEditorAttribute * attribute) {} + + /// Override to provide editor specific data for the uiConfigName for the object + virtual void defineObjectEditorAttribute(QString uiConfigName, PdmUiEditorAttribute * attribute) {} + + /// This method is intended to be used in macros to make compile time errors + // if user uses them on wrong type of objects + bool isInheritedFromPdmUiObject() { return true; } + +private: + /// Helper method for the TreeItem generation stuff + void addDefaultUiTreeChildren(PdmUiTreeOrdering* uiTreeOrdering); + + PdmObjectHandle* m_owner; + +}; + +PdmUiObjectHandle* uiObj(PdmObjectHandle* obj); + + +} // End of namespace caf diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiOrdering.cpp b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiOrdering.cpp similarity index 76% rename from Fwk/AppFwk/cafProjectDataModel/cafPdmUiOrdering.cpp rename to Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiOrdering.cpp index b2891ddb45..5b94960a72 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiOrdering.cpp +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiOrdering.cpp @@ -34,14 +34,18 @@ // //################################################################################################## - #include "cafPdmUiOrdering.h" +#include "cafPdmDataValueField.h" +#include "cafPdmObjectHandle.h" +#include "cafPdmUiFieldHandle.h" +#include "cafPdmUiObjectHandle.h" + +#include namespace caf { - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -84,5 +88,25 @@ bool PdmUiOrdering::contains(const PdmUiItem* item) return false; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiOrdering::add(const PdmFieldHandle* field) +{ + PdmUiFieldHandle* uiItem = const_cast(field)->uiCapability(); + assert(uiItem); + m_ordering.push_back(uiItem); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiOrdering::add(const PdmObjectHandle* obj) +{ + PdmUiObjectHandle* uiItem = uiObj(const_cast(obj)); + assert(uiItem); + m_ordering.push_back(uiItem); +} + } //End of namespace caf diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiOrdering.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiOrdering.h new file mode 100644 index 0000000000..58f4c03e47 --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiOrdering.h @@ -0,0 +1,97 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2013 Ceetron AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + +#pragma once + +#include "cafPdmUiItem.h" + +#include +#include + +namespace caf +{ + +class PdmUiGroup; +class PdmFieldHandle; +class PdmObjectHandle; + +//================================================================================================== +/// Class storing the order and grouping of fields and groups of fields etc. to be used in the Gui +//================================================================================================== + +class PdmUiOrdering +{ +public: + PdmUiOrdering(): m_forgetRemainingFields(false) { }; + virtual ~PdmUiOrdering(); + + PdmUiGroup* addNewGroup(QString displayName); + //void add(PdmUiItem* item) { m_ordering.push_back(item); } + + /// HACK constness of this class and functions must be revisited + //void add(const PdmUiItem* item) { m_ordering.push_back(const_cast(item)); } + void add(const PdmFieldHandle* field); + void add(const PdmObjectHandle* obj); + + bool forgetRemainingFields() const { return m_forgetRemainingFields; } + void setForgetRemainingFields(bool val) { m_forgetRemainingFields = val; } + + const std::vector& uiItems() const { return m_ordering; } + bool contains(const PdmUiItem* item); + +private: + // Private copy constructor and assignment to prevent this. (The vectors below will make trouble) + PdmUiOrdering(const PdmUiOrdering& other) { } + PdmUiOrdering& operator= (const PdmUiOrdering& other) { } + + std::vector m_ordering; ///< The order of groups and fields + std::vector m_createdGroups; ///< Owned PdmUiGroups, for mem management + bool m_forgetRemainingFields; +}; + +//================================================================================================== +/// Class representing a group of fields +//================================================================================================== + +class PdmUiGroup : public PdmUiItem, public PdmUiOrdering +{ + virtual bool isUiGroup() { return true; } +}; + + + +} // End of namespace caf + diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiTreeOrdering.cpp b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiTreeOrdering.cpp new file mode 100644 index 0000000000..05d23c1db8 --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiTreeOrdering.cpp @@ -0,0 +1,401 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2013 Ceetron AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + + +#include "cafPdmUiTreeOrdering.h" + +#include "cafPdmDataValueField.h" +#include "cafPdmObjectHandle.h" +#include "cafPdmUiEditorHandle.h" +#include "cafPdmUiFieldHandle.h" +#include "cafPdmUiObjectHandle.h" + +#include +#include + +namespace caf +{ + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiTreeOrdering::add(PdmFieldHandle * field) +{ + assert(field); + + PdmUiTreeOrdering* child = new PdmUiTreeOrdering(this, field); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiTreeOrdering::add(PdmObjectHandle* object) +{ + assert(object); + + PdmUiTreeOrdering* child = new PdmUiTreeOrdering(this, object); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +PdmUiTreeOrdering* PdmUiTreeOrdering::add(const QString & title, const QString& iconResourceName) +{ + PdmUiTreeOrdering* child = new PdmUiTreeOrdering(title, iconResourceName); + assert(child->isValid()); + + this->appendChild(child); + return child; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool PdmUiTreeOrdering::containsField(const PdmFieldHandle* field) +{ + assert (field); + for (int cIdx = 0; cIdx < this->childCount(); ++cIdx) + { + PdmUiTreeOrdering* child = dynamic_cast(this->child(cIdx)); // What ??? + + if (child->m_field == field) + { + return true; + } + } + + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool PdmUiTreeOrdering::containsObject(const PdmObjectHandle* object) +{ + assert (object); + for (int cIdx = 0; cIdx < this->childCount(); ++cIdx) + { + PdmUiTreeOrdering* child = this->child(cIdx); + + if (child->isRepresentingObject() && child->object() == object) + { + return true; + } + } + + return false; +} + + +//-------------------------------------------------------------------------------------------------- +/// Creates an new root PdmUiTreeOrdering item, pointing at a PdmObject +//-------------------------------------------------------------------------------------------------- +PdmUiTreeOrdering::PdmUiTreeOrdering(PdmObjectHandle* pdmObject) : + m_parentItem(NULL), + m_field(NULL), + m_forgetRemainingFields(false), + m_isToIgnoreSubTree(false), + m_uiItem(NULL), + m_object(pdmObject), + m_treeItemEditor(NULL) +{ +} + +//-------------------------------------------------------------------------------------------------- +/// Creates an new root PdmUiTreeOrdering item, pointing at a field +//-------------------------------------------------------------------------------------------------- +PdmUiTreeOrdering::PdmUiTreeOrdering( PdmFieldHandle* pdmField ) : + m_parentItem(NULL), + m_field(pdmField), + m_forgetRemainingFields(false), + m_isToIgnoreSubTree(false), + m_uiItem(NULL), + m_object(NULL), + m_treeItemEditor(NULL) +{ + if (pdmField) m_object = pdmField->ownerObject(); +} + +//-------------------------------------------------------------------------------------------------- +/// Creates an new root PdmUiTreeOrdering item, as a display item only +//-------------------------------------------------------------------------------------------------- +PdmUiTreeOrdering::PdmUiTreeOrdering(const QString & title, const QString& iconResourceName) : + m_parentItem(NULL), + m_field(NULL), + m_forgetRemainingFields(false), + m_isToIgnoreSubTree(false), + m_uiItem(NULL), + m_object(NULL), + m_treeItemEditor(NULL) +{ + m_uiItem = new PdmUiItem(); + m_uiItem->setUiName(title); + m_uiItem->setUiIcon(QIcon(iconResourceName)); +} + +//-------------------------------------------------------------------------------------------------- +/// Creates an new PdmUiTreeOrdering item, and adds it to parent. If position is -1, it is added +/// at the end of parents existing child list. +//-------------------------------------------------------------------------------------------------- +PdmUiTreeOrdering::PdmUiTreeOrdering(PdmUiTreeOrdering* parent, PdmObjectHandle* pdmObject) : + m_parentItem(parent), + m_field(NULL), + m_forgetRemainingFields(false), + m_isToIgnoreSubTree(false), + m_uiItem(NULL), + m_object(pdmObject), + m_treeItemEditor(NULL) +{ + if (m_parentItem) + { + m_parentItem->m_childItems.push_back( this); + } +} + +//-------------------------------------------------------------------------------------------------- +/// Creates an new PdmUiTreeOrdering item, and adds it to parent. If position is -1, it is added +/// at the end of parents existing child list. +//-------------------------------------------------------------------------------------------------- +PdmUiTreeOrdering::PdmUiTreeOrdering(PdmUiTreeOrdering* parent , PdmFieldHandle* pdmField ) : + m_parentItem(parent), + m_field(pdmField), + m_forgetRemainingFields(false), + m_isToIgnoreSubTree(false), + m_uiItem(NULL), + m_object(NULL), + m_treeItemEditor(NULL) +{ + if (m_parentItem) + { + m_parentItem->m_childItems.push_back( this); + } + + if (pdmField) m_object = pdmField->ownerObject(); +} + + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +PdmUiTreeOrdering::~PdmUiTreeOrdering() +{ + if (m_uiItem) + { + delete m_uiItem; + } + + if (m_treeItemEditor) + { + delete m_treeItemEditor; + } + + qDeleteAll(m_childItems); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +PdmObjectHandle* PdmUiTreeOrdering::object() const +{ + assert(isRepresentingObject()); return m_object; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +PdmFieldHandle* PdmUiTreeOrdering::field() const +{ + assert(isRepresentingField()); return m_field; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +PdmUiItem* PdmUiTreeOrdering::uiItem() const +{ + assert(isDisplayItemOnly()); return m_uiItem; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +PdmUiItem* PdmUiTreeOrdering::activeItem() const +{ + if (isRepresentingObject()) return uiObj(m_object); + if (isRepresentingField()) return m_field->uiCapability(); + if (isDisplayItemOnly()) return m_uiItem; + return NULL; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiTreeOrdering::setEditor(PdmUiEditorHandle* editor) +{ + m_treeItemEditor = editor; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +PdmUiEditorHandle* PdmUiTreeOrdering::editor() +{ + return m_treeItemEditor; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiTreeOrdering::debugDump(int level) const +{ + for (int i = 0; i < level; ++i) + { + std::cout << " "; + } + + if (isValid()) + { + char type = 'I'; + if (isRepresentingObject()) type = 'O'; + if (isRepresentingField()) type = 'F'; + if (isDisplayItemOnly()) type = 'D'; + + std::cout << type << ": " << activeItem()->uiName().toLatin1().data() << std::endl; + } + else + { + std::cout << "NULL" << std::endl; + } + + for (int i = 0; i < childCount(); ++i) + { + child(i)->debugDump(level+1); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +PdmUiTreeOrdering* PdmUiTreeOrdering::child(int index) const +{ + assert(index < m_childItems.size()); + return m_childItems.value(index); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +int PdmUiTreeOrdering::childCount() const +{ + return m_childItems.count(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +PdmUiTreeOrdering* PdmUiTreeOrdering::parent() const +{ + return m_parentItem; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +int PdmUiTreeOrdering::indexInParent() const +{ + if (m_parentItem) + { + return m_parentItem->m_childItems.indexOf(const_cast(this)); + } + + return 0; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiTreeOrdering::appendChild(PdmUiTreeOrdering* child) +{ + m_childItems.append(child); + child->m_parentItem = this; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiTreeOrdering::insertChild(int position, PdmUiTreeOrdering* child) +{ + m_childItems.insert(position, child); + child->m_parentItem = this; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool PdmUiTreeOrdering::removeChildren(int position, int count) +{ + if (position < 0 || position + count > m_childItems.size()) + return false; + + for (int row = 0; row < count; ++row) + { + PdmUiTreeOrdering* uiItem = m_childItems.takeAt(position); + + delete uiItem; + } + + return true; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool PdmUiTreeOrdering::removeChildrenNoDelete(int position, int count) +{ + if (position < 0 || position + count > m_childItems.size()) + return false; + + for (int row = 0; row < count; ++row) + { + m_childItems.removeAt(position); + } + return true; +} + + +} //End of namespace caf + diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiTreeOrdering.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiTreeOrdering.h new file mode 100644 index 0000000000..3fa34ac695 --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiTreeOrdering.h @@ -0,0 +1,142 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2013 Ceetron AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + + +#pragma once + +#include "cafPdmPointer.h" + +#include +#include + +#include + + +namespace caf +{ + +class PdmFieldHandle; +class PdmObjectHandle; +class PdmUiEditorHandle; +class PdmUiItem; +class PdmUiTreeItemEditor; +class PdmUiTreeOrdering; + + +//================================================================================================== +/// Class storing a tree structure representation of some PdmObject hierarchy to be used for tree views in the Gui +//================================================================================================== + +class PdmUiTreeOrdering +{ +public: + PdmUiTreeOrdering(PdmObjectHandle* pdmItem ); + PdmUiTreeOrdering(PdmFieldHandle* pdmField ); + PdmUiTreeOrdering(const QString & title, const QString& iconResourceName ); + + ~PdmUiTreeOrdering(); + + void add(PdmFieldHandle * field); + void add(PdmObjectHandle* object); + PdmUiTreeOrdering* add(const QString & title, const QString& iconResourceName ); + + /// If the rest of the fields containing children is supposed to be omitted, setForgetRemainingFileds to true. + void setForgetRemainingFields(bool val) { m_forgetRemainingFields = val; } + /// To stop the tree generation at this level, doIgnoreSubTree to true + void setIgnoreSubTree(bool doIgnoreSubTree ) { m_isToIgnoreSubTree = doIgnoreSubTree; } + + // Testing for the PdmItem being represented + bool isRepresentingObject() const { return !isRepresentingField() && (m_object != NULL); } + bool isRepresentingField() const { return (m_object != NULL) && (m_field != NULL);} + bool isDisplayItemOnly() const { return (m_uiItem != NULL); } + bool isValid() const { return (this->activeItem() != NULL); } + + // Access to the PdmItem being represented + PdmUiItem* activeItem() const; + PdmObjectHandle* object() const; + PdmFieldHandle* field() const; + PdmUiItem* uiItem() const; + + // Tree structure traversal access + PdmUiTreeOrdering* child(int index) const; + int childCount() const; + PdmUiTreeOrdering* parent() const; + int indexInParent() const; + + // Debug helper + void debugDump(int level) const; + +private: + friend class PdmObjectHandle; friend class PdmUiObjectHandle; + bool forgetRemainingFields() const { return m_forgetRemainingFields; } + bool ignoreSubTree() const { return m_isToIgnoreSubTree; } + bool containsField(const PdmFieldHandle* field); + bool containsObject(const PdmObjectHandle* object); + void appendChild( PdmUiTreeOrdering* child); + + friend class PdmUiTreeViewModel; + PdmUiEditorHandle* editor(); + void setEditor(PdmUiEditorHandle* editor); + void insertChild( int position, PdmUiTreeOrdering* child); + bool removeChildren(int position, int count); + bool removeChildrenNoDelete(int position, int count); + +private: + PdmUiTreeOrdering(PdmUiTreeOrdering* parent, PdmObjectHandle* pdmItem ); + PdmUiTreeOrdering(PdmUiTreeOrdering* parent, PdmFieldHandle* pdmField ); + + // Item that we represent + PdmPointer m_object; // We keep both pointer to object and pointer to field when representing a field + PdmFieldHandle* m_field; // because m_object is guarded while PdmFieldHandle::ownerObject() is not guarded + PdmUiItem* m_uiItem; + + // Tree generation control + bool m_forgetRemainingFields; + bool m_isToIgnoreSubTree; + + // Editor propagating changes from PdmItem to TreeViewEditor + PdmUiEditorHandle* m_treeItemEditor; + + // Tree data + QList m_childItems; + PdmUiTreeOrdering* m_parentItem; + +}; + + + +} // End of namespace caf + diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafSelectionManager.cpp b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafSelectionManager.cpp new file mode 100644 index 0000000000..9233b71ac7 --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafSelectionManager.cpp @@ -0,0 +1,308 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2013 Ceetron AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + + +#include "cafSelectionManager.h" + +#include "cafNotificationCenter.h" +#include "cafPdmReferenceHelper.h" +#include "cafPdmUiFieldHandle.h" +#include "cafPdmUiObjectHandle.h" + + + +namespace caf +{ + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +SelectionManager* SelectionManager::instance() +{ + static SelectionManager* singleton = new SelectionManager; + return singleton; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void SelectionManager::selectedItems(std::vector& items, int role /*= SelectionManager::APPLICATION_GLOBAL*/) +{ + std::vector< std::pair, PdmUiItem*> >& selection = m_selectionForRole[role]; + + for (size_t i = 0; i < selection.size(); i++) + { + if (selection[i].first.notNull()) + { + items.push_back(selection[i].second); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void SelectionManager::setSelectedItems(const std::vector& items, int role /*= SelectionManager::APPLICATION_GLOBAL*/) +{ + std::vector< std::pair, PdmUiItem*> >& selection = m_selectionForRole[role]; + + selection.clear(); + + for (size_t i = 0; i < items.size(); i++) + { + PdmUiFieldHandle* fieldHandle = dynamic_cast(items[i]); + if (fieldHandle) + { + PdmObjectHandle* obj = fieldHandle->fieldHandle()->ownerObject(); + + selection.push_back(std::make_pair(obj, fieldHandle)); + } + else + { + PdmUiObjectHandle* obj = dynamic_cast(items[i]); + if (obj) + { + selection.push_back(std::make_pair(obj->objectHandle(), obj)); + } + } + } + + notifySelectionChanged(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +PdmUiItem* SelectionManager::selectedItem(int role /*= SelectionManager::APPLICATION_GLOBAL*/) +{ + std::vector< std::pair, PdmUiItem*> >& selection = m_selectionForRole[role]; + + if (selection.size() == 1) + { + if (selection[0].first.notNull()) + { + return selection[0].second; + } + } + + return NULL; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void SelectionManager::setSelectedItem(PdmUiItem* item, int role /*= SelectionManager::APPLICATION_GLOBAL*/) +{ + std::vector singleSelection; + singleSelection.push_back(item); + + setSelectedItems(singleSelection, role); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +SelectionManager::SelectionManager() +{ + m_selectionForRole.resize(UNDEFINED); + + m_notificationCenter = NULL; + m_activeChildArrayFieldHandle = NULL; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void SelectionManager::selectionAsReferences(std::vector& referenceList, int role) const +{ +// const std::vector& selection = m_selectionForRole[role]; + const std::vector< std::pair, PdmUiItem*> >& selection = m_selectionForRole[role]; + + for (size_t i = 0; i < selection.size(); i++) + { + if (!selection[i].first.isNull()) + { + PdmUiObjectHandle* pdmObj = dynamic_cast(selection[i].second); + if (pdmObj) + { + QString itemRef = PdmReferenceHelper::referenceFromRootToObject(m_rootObject, pdmObj->objectHandle()); + + referenceList.push_back(itemRef); + } + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void SelectionManager::setSelectionFromReferences(const std::vector& referenceList, int role) +{ + std::vector uiItems; + + for (size_t i = 0; i < referenceList.size(); i++) + { + QString reference = referenceList[i]; + + PdmObjectHandle* pdmObj = PdmReferenceHelper::objectFromReference(m_rootObject, reference); + if (pdmObj) + { + caf::PdmUiObjectHandle* uiObject = uiObj(pdmObj); + if (uiObject) + { + uiItems.push_back(uiObject); + } + } + } + + setSelectedItems(uiItems, role); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void SelectionManager::clearAll() +{ + for (size_t i = 0; i < m_selectionForRole.size(); i++) + { + m_selectionForRole[i].clear(); + } + + notifySelectionChanged(); +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void SelectionManager::clear(int role) +{ + m_selectionForRole[role].clear(); + + notifySelectionChanged(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void SelectionManager::notifySelectionChanged() +{ + if (m_notificationCenter) + { + m_notificationCenter->notifyObserversOfSelectionChange(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void SelectionManager::setNotificationCenter(NotificationCenter* notificationCenter) +{ + m_notificationCenter = notificationCenter; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +NotificationCenter* SelectionManager::notificationCenter() +{ + return m_notificationCenter; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void SelectionManager::removeObjectFromAllSelections(PdmObjectHandle* pdmObject) +{ + bool doNotifySelectionChanged = false; + + for (size_t role = 0; role < m_selectionForRole.size(); role++) + { + std::vector< std::pair, PdmUiItem*> >& selection = m_selectionForRole[role]; + + std::vector< std::pair, PdmUiItem*> >::iterator iter = selection.begin(); + while (iter != selection.end()) + { + if (iter->first.notNull()) + { + PdmObjectHandle* selectionObj = dynamic_cast(iter->second); + if (selectionObj == pdmObject) + { + iter = selection.erase(iter); + + doNotifySelectionChanged = true; + } + else + { + ++iter; + } + } + else + { + ++iter; + } + } + } + + if (doNotifySelectionChanged) + { + notifySelectionChanged(); + } +} + +void SelectionManager::setPdmRootObject(PdmObjectHandle* root) +{ + m_rootObject = root; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void SelectionManager::setActiveChildArrayFieldHandle(PdmChildArrayFieldHandle* childArray) +{ + m_activeChildArrayFieldHandle = childArray; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +PdmChildArrayFieldHandle* SelectionManager::activeChildArrayFieldHandle() +{ + return m_activeChildArrayFieldHandle; +} + +} // end namespace caf diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafSelectionManager.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafSelectionManager.h new file mode 100644 index 0000000000..09adab873b --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafSelectionManager.h @@ -0,0 +1,121 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2013 Ceetron AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + + +#pragma once + +#include "cafPdmPointer.h" + +#include "cafPdmField.h" + +#include + +#include + + +namespace caf +{ + +class PdmUiItem; +class NotificationCenter; +class PdmChildArrayFieldHandle; + +//================================================================================================== +/// +//================================================================================================== +class SelectionManager +{ +public: + enum SelectionRole + { + APPLICATION_GLOBAL, + CURRENT, + UNDEFINED + }; + +public: + static SelectionManager* instance(); + + void setNotificationCenter(NotificationCenter* notificationCenter); + NotificationCenter* notificationCenter(); + + void setActiveChildArrayFieldHandle(PdmChildArrayFieldHandle* childArray); + PdmChildArrayFieldHandle* activeChildArrayFieldHandle(); + + void setPdmRootObject(PdmObjectHandle* root); + PdmObjectHandle* pdmRootObject() { return m_rootObject; } + + PdmUiItem* selectedItem(int role = SelectionManager::APPLICATION_GLOBAL); + void setSelectedItem(PdmUiItem* item, int role = SelectionManager::APPLICATION_GLOBAL); + + void selectedItems(std::vector& items, int role = SelectionManager::APPLICATION_GLOBAL); + void setSelectedItems(const std::vector& items, int role = SelectionManager::APPLICATION_GLOBAL); + + void selectionAsReferences(std::vector& referenceList, int role = SelectionManager::APPLICATION_GLOBAL) const; + void setSelectionFromReferences(const std::vector& referenceList, int role = SelectionManager::APPLICATION_GLOBAL); + + void clearAll(); + void clear(int role); + void removeObjectFromAllSelections(PdmObjectHandle* pdmObject); + + template + void objectsByType(std::vector* typedObjects, int role = SelectionManager::APPLICATION_GLOBAL) + { + std::vector items; + this->selectedItems(items, role); + for (size_t i = 0; i < items.size(); i++) + { + T* obj = dynamic_cast(items[i]); + if (obj) typedObjects->push_back(obj); + } + } + + +private: + SelectionManager(); + void notifySelectionChanged(); + +private: + std::vector < std::vector< std::pair, PdmUiItem*> > > m_selectionForRole; + + NotificationCenter* m_notificationCenter; + PdmChildArrayFieldHandle* m_activeChildArrayFieldHandle; + PdmPointer m_rootObject; +}; + + + +} // end namespace caf diff --git a/Fwk/AppFwk/cafProjectDataModel/cafUiTreeItem.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafUiTreeItem.h similarity index 98% rename from Fwk/AppFwk/cafProjectDataModel/cafUiTreeItem.h rename to Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafUiTreeItem.h index af5bd24def..f118cbbef1 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafUiTreeItem.h +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafUiTreeItem.h @@ -40,7 +40,7 @@ //#include #include #include - +#include namespace caf { @@ -71,7 +71,7 @@ class UiTreeItem qDeleteAll(m_childItems); } - UiTreeItem* child(int row) + UiTreeItem* child(int row) const { assert(row < m_childItems.size()); return m_childItems.value(row); @@ -100,7 +100,7 @@ class UiTreeItem return m_parentItem; } - T dataObject() + T dataObject() const { return m_dataObject; } @@ -167,6 +167,8 @@ class UiTreeItem return -1; } + + private: QList m_childItems; UiTreeItem* m_parentItem; diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiOrdering.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiOrdering.h deleted file mode 100644 index ba952cbb72..0000000000 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiOrdering.h +++ /dev/null @@ -1,93 +0,0 @@ -//################################################################################################## -// -// Custom Visualization Core library -// Copyright (C) 2011-2013 Ceetron AS -// -// This library may be used under the terms of either the GNU General Public License or -// the GNU Lesser General Public License as follows: -// -// GNU General Public License Usage -// This library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. -// -// See the GNU General Public License at <> -// for more details. -// -// GNU Lesser General Public License Usage -// This library is free software; you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation; either version 2.1 of the License, or -// (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. -// -// See the GNU Lesser General Public License at <> -// for more details. -// -//################################################################################################## - - -#pragma once -#include -#include - -#include "cafPdmUiItem.h" - -namespace caf -{ - -class PdmUiGroup; - -//================================================================================================== -/// Class storing the order and grouping of fields and groups of fields etc. to be used in the Gui -//================================================================================================== - -class PdmUiOrdering -{ -public: - PdmUiOrdering(): m_forgetRemainingFields(false) { }; - virtual ~PdmUiOrdering(); - - PdmUiGroup* addNewGroup(QString displayName); - void add(PdmUiItem* item) { m_ordering.push_back(item); } - - /// HACK constness of this class and functions must be revisited - void add(const PdmUiItem* item) { m_ordering.push_back(const_cast(item)); } - - bool forgetRemainingFields() const { return m_forgetRemainingFields; } - void setForgetRemainingFields(bool val) { m_forgetRemainingFields = val; } - - const std::vector& uiItems() const { return m_ordering; } - bool contains(const PdmUiItem* item); - -private: - // Private copy constructor and assignment to prevent this. (The vectors below will make trouble) - PdmUiOrdering(const PdmUiOrdering& other) { } - PdmUiOrdering& operator= (const PdmUiOrdering& other) { } - - std::vector m_ordering; ///< The order of groups and fields - std::vector m_createdGroups; ///< Owned PdmUiGroups, for mem management - bool m_forgetRemainingFields; -}; - -//================================================================================================== -/// Class representing a group of fields -//================================================================================================== - -class PdmUiGroup : public PdmUiItem, public PdmUiOrdering -{ - virtual bool isUiGroup() { return true; } -}; - - - -} // End of namespace caf - diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiTreeOrdering.cpp b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiTreeOrdering.cpp deleted file mode 100644 index bea9b8a19a..0000000000 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiTreeOrdering.cpp +++ /dev/null @@ -1,143 +0,0 @@ -//################################################################################################## -// -// Custom Visualization Core library -// Copyright (C) 2011-2013 Ceetron AS -// -// This library may be used under the terms of either the GNU General Public License or -// the GNU Lesser General Public License as follows: -// -// GNU General Public License Usage -// This library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. -// -// See the GNU General Public License at <> -// for more details. -// -// GNU Lesser General Public License Usage -// This library is free software; you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation; either version 2.1 of the License, or -// (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. -// -// See the GNU Lesser General Public License at <> -// for more details. -// -//################################################################################################## - - -#include "cafPdmUiTreeOrdering.h" -#include "cafPdmField.h" - -namespace caf -{ - - - //-------------------------------------------------------------------------------------------------- - /// - //-------------------------------------------------------------------------------------------------- - void PdmUiTreeOrdering::add(PdmFieldHandle * field) - { - PdmUiTreeOrdering* to = new PdmUiTreeOrdering(this, -1, field->ownerObject()); - to->m_field = field; - } - - //-------------------------------------------------------------------------------------------------- - /// - //-------------------------------------------------------------------------------------------------- - void PdmUiTreeOrdering::add(PdmObject* object) - { - PdmUiTreeOrdering* to = new PdmUiTreeOrdering(this, -1, object); - } - - //-------------------------------------------------------------------------------------------------- - /// - //-------------------------------------------------------------------------------------------------- - PdmUiTreeOrdering* PdmUiTreeOrdering::add(const QString & title, const QString& iconResourceName) - { - PdmUiTreeOrdering* to = new PdmUiTreeOrdering(this, -1, NULL); - - to->m_uiItem = new PdmUiItem(); - to->m_uiItem->setUiName(title); - to->m_uiItem->setUiIcon(QIcon(iconResourceName)); - - return to; - } - - //-------------------------------------------------------------------------------------------------- - /// - //-------------------------------------------------------------------------------------------------- - bool PdmUiTreeOrdering::containsField(const PdmFieldHandle* field) - { - assert (field); - for (int cIdx = 0; cIdx < this->childCount(); ++cIdx) - { - PdmUiTreeOrdering* child = dynamic_cast(this->child(cIdx)); - - if (child->m_field == field) - { - return true; - } - } - - return false; - } - - //-------------------------------------------------------------------------------------------------- - /// - //-------------------------------------------------------------------------------------------------- - bool PdmUiTreeOrdering::containsObject(const PdmObject* object) - { - assert (object); - for (int cIdx = 0; cIdx < this->childCount(); ++cIdx) - { - PdmUiTreeOrdering* child = dynamic_cast(this->child(cIdx)); - - if (child->object() == object) - { - return true; - } - } - - return false; - } - - - //-------------------------------------------------------------------------------------------------- - /// Creates an new PdmUiTreeOrdering item, and adds it to parent. If position is -1, it is added - /// at the end of parents existing child list. - //-------------------------------------------------------------------------------------------------- - PdmUiTreeOrdering::PdmUiTreeOrdering(PdmUiTreeOrdering* parent /*= NULL*/, int position /*= -1*/, PdmObject* dataObject /*= NULL*/) : PdmUiTreeItem(parent, position, this), - m_field(NULL), - m_forgetRemainingFields(false), - m_isToIgnoreSubTree(false), - m_uiItem(NULL), - m_object(dataObject) - { - - } - - //-------------------------------------------------------------------------------------------------- - /// - //-------------------------------------------------------------------------------------------------- - PdmUiTreeOrdering::~PdmUiTreeOrdering() - { - if (m_uiItem) - { - delete m_uiItem; - } - } - - - -} //End of namespace caf - diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiTreeOrdering.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiTreeOrdering.h deleted file mode 100644 index e43b74191d..0000000000 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiTreeOrdering.h +++ /dev/null @@ -1,98 +0,0 @@ -//################################################################################################## -// -// Custom Visualization Core library -// Copyright (C) 2011-2013 Ceetron AS -// -// This library may be used under the terms of either the GNU General Public License or -// the GNU Lesser General Public License as follows: -// -// GNU General Public License Usage -// This library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. -// -// See the GNU General Public License at <> -// for more details. -// -// GNU Lesser General Public License Usage -// This library is free software; you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation; either version 2.1 of the License, or -// (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. -// -// See the GNU Lesser General Public License at <> -// for more details. -// -//################################################################################################## - - -#pragma once -#include -#include - -#include "cafPdmUiItem.h" -#include "cafUiTreeItem.h" -#include "cafPdmPointer.h" - -namespace caf -{ - -class PdmObject; -class PdmFieldHandle; - -class PdmUiTreeOrdering; - -typedef UiTreeItem PdmUiTreeItem; - -//================================================================================================== -/// Class storing a tree structure representation of some PdmObject hierarchy to be used for tree views in the Gui -//================================================================================================== - -class PdmUiTreeOrdering : public UiTreeItem< PdmUiTreeOrdering* > -{ -public: - PdmUiTreeOrdering(PdmUiTreeOrdering* parent = NULL, int position = -1, PdmObject* dataObject = NULL); - ~PdmUiTreeOrdering(); - - void add(PdmFieldHandle * field); - void add(PdmObject* object); - PdmUiTreeOrdering* add(const QString & title, const QString& iconResourceName ); - - /// If the rest of the fields containing children is supposed to be omitted, setForgetRemainingFileds to true. - void setForgetRemainingFields(bool val) { m_forgetRemainingFields = val; } - /// To stop the tree generation at this level, setSubTreeDefined to true - void setIgnoreSubTree(bool doIgnoreSubTree ) { m_isToIgnoreSubTree = doIgnoreSubTree; } - - PdmObject* object() const { return m_object; } - PdmFieldHandle* field() const { return m_field; } - PdmUiItem* uiItem() const { return m_uiItem; } - -private: - friend class PdmObject; - bool forgetRemainingFields() const { return m_forgetRemainingFields; } - bool ignoreSubTree() const { return m_isToIgnoreSubTree; } - bool containsField(const PdmFieldHandle* field); - bool containsObject(const PdmObject* object); - -private: - PdmPointer m_object; - PdmFieldHandle* m_field; - PdmUiItem* m_uiItem; - - bool m_forgetRemainingFields; - bool m_isToIgnoreSubTree; -}; - - - -} // End of namespace caf - diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/CMakeLists.txt b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/CMakeLists.txt new file mode 100644 index 0000000000..c42cab52c4 --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/CMakeLists.txt @@ -0,0 +1,43 @@ +cmake_minimum_required (VERSION 2.8) + +project (cafPdmXml) + +# Qt +find_package ( Qt4 COMPONENTS QtCore ) +include (${QT_USE_FILE}) + +include_directories ( + .. + ${cafPdmCore_SOURCE_DIR} +) + +set( PROJECT_FILES + cafInternalPdmFieldIoHelper.cpp + cafInternalPdmFieldIoHelper.h + cafInternalPdmStreamOperators.cpp + cafInternalPdmStreamOperators.h + cafInternalPdmXmlFieldCapability.h + cafInternalPdmXmlFieldCapability.inl + cafInternalPdmXmlFieldReaderWriter.cpp + cafInternalPdmXmlFieldReaderWriter.h + cafPdmXmlFieldHandle.cpp + cafPdmXmlFieldHandle.h + cafPdmXmlObjectHandle.cpp + cafPdmXmlObjectHandle.h + + cafPdmXmlObjectHandleMacros.h + + cafPdmDefaultObjectFactory.cpp + cafPdmDefaultObjectFactory.h + cafPdmObjectFactory.h + + cafPdmSettings.h + cafPdmSettings.cpp +) + + +add_library( ${PROJECT_NAME} + ${PROJECT_FILES} +) + +source_group("" FILES ${PROJECT_FILES}) \ No newline at end of file diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafInternalPdmFieldIoHelper.cpp b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafInternalPdmFieldIoHelper.cpp new file mode 100644 index 0000000000..33f7729749 --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafInternalPdmFieldIoHelper.cpp @@ -0,0 +1,32 @@ +#include "cafInternalPdmFieldIoHelper.h" + +#include + +namespace caf +{ + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmFieldIOHelper::skipCharactersAndComments(QXmlStreamReader& xmlStream) +{ + QXmlStreamReader::TokenType type; + while (!xmlStream.atEnd() && xmlStream.isCharacters() || xmlStream.isComment()) + { + type = xmlStream.readNext(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmFieldIOHelper::skipComments(QXmlStreamReader& xmlStream) +{ + QXmlStreamReader::TokenType type; + while (!xmlStream.atEnd() && xmlStream.isComment()) + { + type = xmlStream.readNext(); + } +} + +} // End of namespace caf diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafInternalPdmFieldIoHelper.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafInternalPdmFieldIoHelper.h new file mode 100644 index 0000000000..4d8e94a525 --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafInternalPdmFieldIoHelper.h @@ -0,0 +1,17 @@ +#pragma once + +class QXmlStreamReader; + +namespace caf +{ + +class PdmFieldIOHelper +{ +public: + // Utility functions for reading from QXmlStreamReader + static void skipCharactersAndComments(QXmlStreamReader& xmlStream); + static void skipComments(QXmlStreamReader& xmlStream); + +}; + +} // End of namespace caf diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafInternalPdmStreamOperators.cpp b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafInternalPdmStreamOperators.cpp new file mode 100644 index 0000000000..cd236ad01f --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafInternalPdmStreamOperators.cpp @@ -0,0 +1,42 @@ +#include + +//-------------------------------------------------------------------------------------------------- +/// Specialized read operation for Bool`s +//-------------------------------------------------------------------------------------------------- +QTextStream& operator >> (QTextStream& str, bool& value) +{ + QString text; + str >> text; + if (text == "True" || text == "true" || text == "1" || text == "Yes" || text == "yes") value = true; + else value = false; + + return str; +} + +QTextStream& operator << (QTextStream& str, const bool& value) +{ + if (value) str << "True "; + else str << "False "; + + return str; +} + + +//-------------------------------------------------------------------------------------------------- +/// Specialized read operation for QDateTimes`s +//-------------------------------------------------------------------------------------------------- +#include +QTextStream& operator >> (QTextStream& str, QDateTime& value) +{ + QString text; + str >> text; + value = QDateTime::fromString(text, "yyyy_MM_dd-HH:mm:ss"); + return str; +} + +QTextStream& operator << (QTextStream& str, const QDateTime& value) +{ + QString text = value.toString("yyyy_MM_dd-HH:mm:ss"); + str << text; + return str; +} diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafInternalPdmStreamOperators.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafInternalPdmStreamOperators.h new file mode 100644 index 0000000000..7d211ee841 --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafInternalPdmStreamOperators.h @@ -0,0 +1,50 @@ +#pragma once + +#include + +//================================================================================================== +/// QTextStream Stream operator overloading for bool`s +/// Prints bool`s as "True"/"False", and reads them too +//================================================================================================== + +QTextStream& operator >> (QTextStream& str, bool& value); +QTextStream& operator << (QTextStream& str, const bool& value); + + +//================================================================================================== +/// QTextStream Stream operator overloading for QDateTimes`s +/// +//================================================================================================== +//class QDateTime; +QTextStream& operator >> (QTextStream& str, QDateTime& value); +QTextStream& operator << (QTextStream& str, const QDateTime& value); + + +//================================================================================================== +/// QTextStream Stream operator overloading for std::vector of things. +/// Makes automated IO of PdmField< std::vector< Whatever > possible as long as +/// the type will print as one single word +//================================================================================================== + +template < typename T > +QTextStream& operator << (QTextStream& str, const std::vector& sobj) +{ + size_t i; + for (i = 0; i < sobj.size(); ++i) + { + str << sobj[i] << " "; + } + return str; +} + +template < typename T > +QTextStream& operator >> (QTextStream& str, std::vector& sobj) +{ + while (str.status() == QTextStream::Ok) + { + T d; + str >> d; + if (str.status() == QTextStream::Ok) sobj.push_back(d); + } + return str; +} diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafInternalPdmXmlFieldCapability.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafInternalPdmXmlFieldCapability.h new file mode 100644 index 0000000000..f14cd1914b --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafInternalPdmXmlFieldCapability.h @@ -0,0 +1,105 @@ +#pragma once + +#include "cafInternalPdmXmlFieldReaderWriter.h" +#include "cafPdmXmlFieldHandle.h" + +namespace caf +{ + +template < typename FieldType> +class PdmFieldXmlCap : public PdmXmlFieldHandle +{ +public: + PdmFieldXmlCap(FieldType* field, bool giveOwnership) : PdmXmlFieldHandle(field, giveOwnership) { m_field = field; } + + // Xml Serializing +public: + virtual void readFieldData(QXmlStreamReader& xmlStream, PdmObjectFactory* objectFactory); + virtual void writeFieldData(QXmlStreamWriter& xmlStream); +private: + FieldType* m_field; +}; + + +template class PdmPtrField; + +template < typename DataType> +class PdmFieldXmlCap< PdmPtrField > : public PdmXmlFieldHandle +{ + typedef PdmPtrField FieldType; +public: + PdmFieldXmlCap(FieldType* field, bool giveOwnership) : PdmXmlFieldHandle(field, giveOwnership) + { + m_field = field; + m_childClassKeyword = DataType::classKeywordStatic(); + m_isResolved = false; + m_referenceString = ""; + } + + // Xml Serializing +public: + virtual void readFieldData(QXmlStreamReader& xmlStream, PdmObjectFactory* objectFactory); + virtual void writeFieldData(QXmlStreamWriter& xmlStream); + virtual void resolveReferences(); + +private: + FieldType* m_field; + + // Resolving + QString m_referenceString; + bool m_isResolved; +}; + + + +template class PdmChildField; + +template < typename DataType> +class PdmFieldXmlCap< PdmChildField > : public PdmXmlFieldHandle +{ + typedef PdmChildField FieldType; +public: + PdmFieldXmlCap(FieldType* field, bool giveOwnership) : PdmXmlFieldHandle(field, giveOwnership) { m_field = field; m_childClassKeyword = DataType::classKeywordStatic(); } + + // Xml Serializing +public: + virtual void readFieldData(QXmlStreamReader& xmlStream, PdmObjectFactory* objectFactory); + virtual void writeFieldData(QXmlStreamWriter& xmlStream); +private: + FieldType* m_field; +}; + + +template class PdmChildArrayField; + +template < typename DataType> +class PdmFieldXmlCap< PdmChildArrayField > : public PdmXmlFieldHandle +{ + typedef PdmChildArrayField FieldType; +public: + PdmFieldXmlCap(FieldType* field, bool giveOwnership) : PdmXmlFieldHandle(field, giveOwnership) { m_field = field; m_childClassKeyword = DataType::classKeywordStatic();} + + // Xml Serializing +public: + virtual void readFieldData(QXmlStreamReader& xmlStream, PdmObjectFactory* objectFactory); + virtual void writeFieldData(QXmlStreamWriter& xmlStream); +private: + FieldType* m_field; +}; + + + + +template +void AddXmlCapabilityToField(FieldType* field) +{ + if(field->template capability< PdmFieldXmlCap >() == NULL) + { + new PdmFieldXmlCap(field, true); + } +} + + +} // End of namespace caf + +#include "cafInternalPdmXmlFieldCapability.inl" diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafInternalPdmXmlFieldCapability.inl b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafInternalPdmXmlFieldCapability.inl new file mode 100644 index 0000000000..5842df0414 --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafInternalPdmXmlFieldCapability.inl @@ -0,0 +1,300 @@ +#include "cafInternalPdmFieldIoHelper.h" +#include "cafPdmObjectFactory.h" +#include "cafPdmXmlObjectHandle.h" + +#include + +namespace caf +{ +//================================================================================================== +/// XML Implementation for PdmFieldXmlCap<> methods +/// +//================================================================================================== + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +template + void caf::PdmFieldXmlCap::readFieldData(QXmlStreamReader& xmlStream, + PdmObjectFactory* objectFactory) + { + this->assertValid(); + typename FieldType::FieldDataType value; + PdmFieldReader::readFieldData(value, xmlStream, objectFactory); + m_field->setValue(value); + } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +template + void caf::PdmFieldXmlCap::writeFieldData(QXmlStreamWriter& xmlStream) + { + this->assertValid(); + PdmFieldWriter::writeFieldData(m_field->value(), xmlStream); + } + +//================================================================================================== +/// XML Implementation for PdmPtrField<> +//================================================================================================== + + //-------------------------------------------------------------------------------------------------- + /// + //-------------------------------------------------------------------------------------------------- + + template + void caf::PdmFieldXmlCap< caf::PdmPtrField >::readFieldData(QXmlStreamReader& xmlStream, PdmObjectFactory*) + { + this->assertValid(); + + PdmFieldIOHelper::skipComments(xmlStream); + if (!xmlStream.isCharacters()) return; + + QString dataString = xmlStream.text().toString(); + + // Make stream point to end of element + QXmlStreamReader::TokenType type; + type = xmlStream.readNext(); + PdmFieldIOHelper::skipCharactersAndComments(xmlStream); + + // This resolving can NOT be done here. + // It must be done when we know that the complete hierarchy is read and created, + // The object pointed to is not always read and created at this point in time. + // We rather need to do something like : + // m_refenceString = dataString; + // m_isResolved = false; + // m_field->setRawPtr(NULL); + // + // and then we need a traversal of the object hierarchy to resolve all references before initAfterRead. + + m_isResolved = false; + m_referenceString = dataString; + m_field->setRawPtr(NULL); +} + + //-------------------------------------------------------------------------------------------------- + /// + //-------------------------------------------------------------------------------------------------- + + template + void caf::PdmFieldXmlCap< caf::PdmPtrField >::writeFieldData(QXmlStreamWriter& xmlStream) + { + this->assertValid(); + + QString dataString; + + dataString = PdmReferenceHelper::referenceFromFieldToObject(m_field, m_field->m_fieldValue.rawPtr()); + + xmlStream.writeCharacters(dataString); + } + + + //-------------------------------------------------------------------------------------------------- + /// + //-------------------------------------------------------------------------------------------------- + template < typename DataType> + void caf::PdmFieldXmlCap< PdmPtrField >::resolveReferences() + { + if (m_isResolved) return; + if (m_referenceString.isEmpty()) return; + + PdmObjectHandle* objHandle = PdmReferenceHelper::objectFromFieldReference(this->fieldHandle(), m_referenceString); + m_field->setRawPtr(objHandle); + m_isResolved = true; + } + + +//================================================================================================== +/// XML Implementation for PdmChildField<> +//================================================================================================== + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- + +template +void caf::PdmFieldXmlCap< caf::PdmChildField >::readFieldData(QXmlStreamReader& xmlStream, PdmObjectFactory* objectFactory) +{ + PdmFieldIOHelper::skipCharactersAndComments(xmlStream); + if (!xmlStream.isStartElement()) + { + return; // This happens when the field is "shortcut" empty (written like: ) + } + + QString className = xmlStream.name().toString(); + PdmObjectHandle* obj = NULL; + + // Create an object if needed + if (m_field->value() == NULL) + { + assert(objectFactory); + obj = objectFactory->create(className); + + if (obj == NULL) + { + std::cout << "Line " << xmlStream.lineNumber() << ": Warning: Unknown object type with class name: " << className.toLatin1().data() << " found while reading the field : " << m_field->keyword().toLatin1().data() << std::endl; + + xmlStream.skipCurrentElement(); // Skip to the endelement of the object we was supposed to read + xmlStream.skipCurrentElement(); // Skip to the endelement of this field + return; + } + else + { + PdmXmlObjectHandle* xmlObject = xmlObj(obj); + if (!xmlObject || xmlObject->classKeyword() != className) + { + assert(false); // Inconsistency in the factory. It creates objects of wrong type from the ClassKeyword + + xmlStream.skipCurrentElement(); // Skip to the endelement of the object we was supposed to read + xmlStream.skipCurrentElement(); // Skip to the endelement of this field + + return; + } + + m_field->m_fieldValue.setRawPtr(obj); + obj->setAsParentField(m_field); + } + } + else + { + obj = m_field->m_fieldValue.rawPtr(); + } + + PdmXmlObjectHandle* xmlObject = xmlObj(obj); + if (!xmlObject || xmlObject->classKeyword() != className) + { + // Error: Field contains different class type than on file + std::cout << "Line " << xmlStream.lineNumber() << ": Warning: Unknown object type with class name: " << className.toLatin1().data() << " found while reading the field : " << m_field->keyword().toLatin1().data() << std::endl; + std::cout << " Expected class name: " << xmlObject->classKeyword().toLatin1().data() << std::endl; + + xmlStream.skipCurrentElement(); // Skip to the endelement of the object we was supposed to read + xmlStream.skipCurrentElement(); // Skip to the endelement of this field + + return; + } + + // Everything seems ok, so read the contents of the object: + + xmlObject->readFields(xmlStream, objectFactory); + + // Make stream point to endElement of this field + + QXmlStreamReader::TokenType type; + type = xmlStream.readNext(); + PdmFieldIOHelper::skipCharactersAndComments(xmlStream); +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- + +template +void caf::PdmFieldXmlCap< caf::PdmChildField >::writeFieldData(QXmlStreamWriter& xmlStream) +{ + if (m_field->m_fieldValue.rawPtr() == NULL) return; + + PdmXmlObjectHandle* xmlObject = xmlObj(m_field->m_fieldValue.rawPtr()); + if (xmlObject) + { + QString className = xmlObject->classKeyword(); + + xmlStream.writeStartElement("", className); + xmlObject->writeFields(xmlStream); + xmlStream.writeEndElement(); + } +} + +//================================================================================================== +/// XML Implementation for PdmChildArrayField<> +//================================================================================================== + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +template +void caf::PdmFieldXmlCap< caf::PdmChildArrayField >::writeFieldData(QXmlStreamWriter& xmlStream) +{ + typename std::vector< PdmPointer >::iterator it; + for (it = m_field->m_pointers.begin(); it != m_field->m_pointers.end(); ++it) + { + if (it->rawPtr() == NULL) continue; + + PdmXmlObjectHandle* xmlObject = xmlObj(it->rawPtr()); + if (xmlObject) + { + QString className = xmlObject->classKeyword(); + + xmlStream.writeStartElement("", className); + xmlObject->writeFields(xmlStream); + xmlStream.writeEndElement(); + } + } +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +template +void caf::PdmFieldXmlCap< caf::PdmChildArrayField >::readFieldData(QXmlStreamReader& xmlStream, PdmObjectFactory* objectFactory) +{ + m_field->deleteAllChildObjects(); + PdmFieldIOHelper::skipCharactersAndComments(xmlStream); + while (xmlStream.isStartElement()) + { + QString className = xmlStream.name().toString(); + + assert(objectFactory); + PdmObjectHandle * obj = objectFactory->create(className); + + if (obj == NULL) + { + // Warning: Unknown className read + // Skip to corresponding end element + + std::cout << "Line " << xmlStream.lineNumber() << ": Warning: Unknown object type with class name: " << className.toLatin1().data() << " found while reading the field : " << m_field->keyword().toLatin1().data() << std::endl; + + // Skip to EndElement of the object + xmlStream.skipCurrentElement(); + + // Jump off the end element, and head for next start element (or the final EndElement of the field) + QXmlStreamReader::TokenType type; + type = xmlStream.readNext(); + PdmFieldIOHelper::skipCharactersAndComments(xmlStream); + + continue; + } + + PdmXmlObjectHandle* xmlObject = xmlObj(obj); + if (!xmlObject || xmlObject->classKeyword() != className) + { + assert(false); // There is an inconsistency in the factory. It creates objects of type not matching the ClassKeyword + + // Skip to EndElement of the object + xmlStream.skipCurrentElement(); + + // Jump off the end element, and head for next start element (or the final EndElement of the field) + QXmlStreamReader::TokenType type; + type = xmlStream.readNext(); + PdmFieldIOHelper::skipCharactersAndComments(xmlStream); + + continue; + } + + xmlObject->readFields(xmlStream, objectFactory); + + m_field->m_pointers.push_back(PdmPointer()); + m_field->m_pointers.back().setRawPtr(obj); + obj->setAsParentField(m_field); + + // Jump off the end element, and head for next start element (or the final EndElement of the field) + // Qt reports a character token between EndElements and StartElements so skip it + + QXmlStreamReader::TokenType type; + type = xmlStream.readNext(); + PdmFieldIOHelper::skipCharactersAndComments(xmlStream); + } +} + +} // End namespace caf diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafInternalPdmXmlFieldReaderWriter.cpp b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafInternalPdmXmlFieldReaderWriter.cpp new file mode 100644 index 0000000000..dc8373ff21 --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafInternalPdmXmlFieldReaderWriter.cpp @@ -0,0 +1,25 @@ +#include "cafInternalPdmXmlFieldReaderWriter.h" + +#include "cafInternalPdmFieldIoHelper.h" + +namespace caf +{ + +//-------------------------------------------------------------------------------------------------- +/// Specialized read function for QStrings, because the >> operator only can read word by word +//-------------------------------------------------------------------------------------------------- +template<> +void PdmFieldReader::readFieldData(QString & field, QXmlStreamReader& xmlStream, PdmObjectFactory*) +{ + PdmFieldIOHelper::skipComments(xmlStream); + if (!xmlStream.isCharacters()) return; + + field = xmlStream.text().toString(); + + // Make stream point to end of element + QXmlStreamReader::TokenType type; + type = xmlStream.readNext(); + PdmFieldIOHelper::skipCharactersAndComments(xmlStream); +} + +} // End of namespace caf diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafInternalPdmXmlFieldReaderWriter.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafInternalPdmXmlFieldReaderWriter.h new file mode 100644 index 0000000000..3263c14379 --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafInternalPdmXmlFieldReaderWriter.h @@ -0,0 +1,124 @@ +#pragma once + +#include +#include +#include + +#include "cafInternalPdmStreamOperators.h" +#include "cafPdmReferenceHelper.h" +#include "cafInternalPdmFieldIoHelper.h" + +#include + + +namespace caf +{ + class PdmObjectFactory; + template class PdmPointer; + + +//-------------------------------------------------------------------------------------------------- +/// Generic write method for fields. Will work as long as DataType supports the stream operator +/// towards a QTextStream. Some special datatype should not specialize this method unless it is +/// impossible/awkward to implement the stream operator +/// Implemented in a proxy class to allow partial specialization +//-------------------------------------------------------------------------------------------------- +template +struct PdmFieldWriter +{ + static void writeFieldData(const DataType & fieldValue, QXmlStreamWriter& xmlStream) + { + QString dataString; + QTextStream data(&dataString, QIODevice::WriteOnly); + data << fieldValue; + xmlStream.writeCharacters(dataString); + } +}; + +template +struct PdmFieldReader +{ + static void readFieldData(DataType & fieldValue, QXmlStreamReader& xmlStream, PdmObjectFactory* objectFactory); +}; + +//-------------------------------------------------------------------------------------------------- +/// Generic read method for fields. Will work as long as DataType supports the stream operator +/// towards a QTextStream. Some special datatype should not specialize this method unless it is +/// impossible/awkward to implement the stream operator +//-------------------------------------------------------------------------------------------------- +template +void PdmFieldReader::readFieldData(DataType & fieldValue, QXmlStreamReader& xmlStream, PdmObjectFactory* objectFactory) +{ + PdmFieldIOHelper::skipComments(xmlStream); + if (!xmlStream.isCharacters()) return; + + QString dataString = xmlStream.text().toString(); + QTextStream data(&dataString, QIODevice::ReadOnly); + data >> fieldValue; + + // Make stream point to end of element + QXmlStreamReader::TokenType type; + type = xmlStream.readNext(); + PdmFieldIOHelper::skipCharactersAndComments(xmlStream); +} + +//-------------------------------------------------------------------------------------------------- +/// Specialized read function for QStrings, because the >> operator only can read word by word +//-------------------------------------------------------------------------------------------------- +template<> +void PdmFieldReader::readFieldData(QString & field, QXmlStreamReader& xmlStream, PdmObjectFactory* objectFactory); + +#if 0 +//-------------------------------------------------------------------------------------------------- +/// Specialized IO for PdmPointer +//-------------------------------------------------------------------------------------------------- +template +struct PdmFieldWriter< PdmPointer > +{ + static void writeFieldData(const PdmPointer & fieldValue, QXmlStreamWriter& xmlStream, PdmReferenceHelper* referenceHelper) + { + QString dataString; + + assert(referenceHelper); + + if (fieldValue.isNull()) + { + dataString = "NULL"; + } + else + { + dataString = referenceHelper->referenceFromRootToObject(fieldValue.p()); + } + + xmlStream.writeCharacters(dataString); + } +}; + +template +struct PdmFieldReader< PdmPointer > +{ + static void readFieldData(PdmPointer & fieldValue, QXmlStreamReader& xmlStream, PdmObjectFactory*, PdmReferenceHelper* referenceHelper) + { + PdmFieldIOHelper::skipComments(xmlStream); + if (!xmlStream.isCharacters()) return; + + QString dataString = xmlStream.text().toString(); + + // Make stream point to end of element + QXmlStreamReader::TokenType type; + type = xmlStream.readNext(); + PdmFieldIOHelper::skipCharactersAndComments(xmlStream); + + if (dataString != "NULL") + { + assert(referenceHelper); + + PdmObjectHandle* objHandle = referenceHelper->objectFromReference(dataString); + fieldValue.setRawPtr(objHandle); + } + } +}; + +#endif +} // End of namespace caf + diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmDefaultObjectFactory.cpp b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmDefaultObjectFactory.cpp new file mode 100644 index 0000000000..21191d418b --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmDefaultObjectFactory.cpp @@ -0,0 +1,36 @@ +#include "cafPdmDefaultObjectFactory.h" + +namespace caf +{ +//-------------------------------------------------------------------------------------------------- +/// PdmObjectFactory implementations +//-------------------------------------------------------------------------------------------------- + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +PdmObjectHandle * PdmDefaultObjectFactory::create(const QString& classNameKeyword) +{ + std::map::iterator entryIt; + entryIt = m_factoryMap.find(classNameKeyword); + if (entryIt != m_factoryMap.end()) + { + return entryIt->second->create(); + } + else + { + return NULL; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +PdmDefaultObjectFactory * PdmDefaultObjectFactory::instance() +{ + static PdmDefaultObjectFactory* fact = new PdmDefaultObjectFactory; + return fact; +} + +} // End of namespace caf diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmDefaultObjectFactory.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmDefaultObjectFactory.h new file mode 100644 index 0000000000..a23be61d4a --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmDefaultObjectFactory.h @@ -0,0 +1,112 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2013 Ceetron AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + + +#pragma once + +#include "cafPdmObjectFactory.h" + +#include + +#include +#include + +namespace caf +{ + + + +//================================================================================================== +/// "Private" class for implementation of a factory for PdmObjectBase derived objects +/// Every PdmObject must register with this factory to be readable +/// This class can be considered private in the Pdm system +//================================================================================================== + +class PdmDefaultObjectFactory : public PdmObjectFactory +{ +public: + static PdmDefaultObjectFactory * instance(); + + virtual PdmObjectHandle* create(const QString& classNameKeyword); + + template< typename PdmObjectBaseDerivative > + bool registerCreator() + { + std::map::iterator entryIt; + + QString classNameKeyword = PdmObjectBaseDerivative::classKeywordStatic(); + + entryIt = m_factoryMap.find(classNameKeyword); + if (entryIt == m_factoryMap.end()) + { + m_factoryMap[classNameKeyword] = new PdmObjectCreator(); + return true; + } + else + { + assert(classNameKeyword != entryIt->first); // classNameKeyword has already been used + assert(false); // To be sure .. + return false; // never hit; + } + } + +private: + PdmDefaultObjectFactory() {} + ~PdmDefaultObjectFactory() { /* Could clean up, but ... */ } + + // Internal helper classes + + class PdmObjectCreatorBase + { + public: + PdmObjectCreatorBase() {} + virtual ~PdmObjectCreatorBase() {} + virtual PdmObjectHandle * create() = 0; + }; + + template< typename PdmObjectBaseDerivative > + class PdmObjectCreator : public PdmObjectCreatorBase + { + public: + virtual PdmObjectHandle * create() { return new PdmObjectBaseDerivative(); } + }; + + // Map to store factory + std::map m_factoryMap; +}; + + +} //End of namespace caf diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmObjectFactory.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmObjectFactory.h new file mode 100644 index 0000000000..d758c4bbcb --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmObjectFactory.h @@ -0,0 +1,66 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2013 Ceetron AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + + +#pragma once + +class QString; + +namespace caf +{ + +class PdmObjectHandle; + + + +//================================================================================================== +// +// Factory interface for creating PDM objects derived from PdmObjectHandle based on class name keyword +// +//================================================================================================== +class PdmObjectFactory +{ +public: + + virtual PdmObjectHandle* create(const QString& classNameKeyword) = 0; + +protected: + PdmObjectFactory() {} + virtual ~PdmObjectFactory() {} +}; + + +} //End of namespace caf diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmSettings.cpp b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmSettings.cpp new file mode 100644 index 0000000000..c324694325 --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmSettings.cpp @@ -0,0 +1,143 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2015 Ceetron Solutions AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + + +#include "cafPdmSettings.h" + +#include "cafPdmField.h" +#include "cafPdmXmlObjectHandle.h" + +#include + + +namespace caf +{ + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmSettings::readFieldsFromApplicationStore(caf::PdmObjectHandle* object, const QString context) +{ + // Qt doc : + // + // Constructs a QSettings object for accessing settings of the application and organization + // set previously with a call to QCoreApplication::setOrganizationName(), + // QCoreApplication::setOrganizationDomain(), and QCoreApplication::setApplicationName(). + QSettings settings; + std::vector fields; + + object->fields(fields); + size_t i; + for (i = 0; i < fields.size(); i++) + { + caf::PdmFieldHandle* fieldHandle = fields[i]; + + std::vector children; + fieldHandle->childObjects(&children); + for (size_t childIdx = 0; childIdx < children.size(); childIdx++) + { + caf::PdmObjectHandle* child = children[childIdx]; + caf::PdmXmlObjectHandle* xmlObjHandle = xmlObj(child); + + QString subContext = context + xmlObjHandle->classKeyword() + "/"; + readFieldsFromApplicationStore(child, subContext); + } + + if (children.size() == 0) + { + QString key = context + fieldHandle->keyword(); + if (settings.contains(key)) + { + QVariant val = settings.value(key); + + caf::PdmValueField* valueField = dynamic_cast(fieldHandle); + assert(valueField); + valueField->setFromQVariant(val); + } + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmSettings::writeFieldsToApplicationStore(caf::PdmObjectHandle* object, const QString context) +{ + assert(object); + + // Qt doc : + // + // Constructs a QSettings object for accessing settings of the application and organization + // set previously with a call to QCoreApplication::setOrganizationName(), + // QCoreApplication::setOrganizationDomain(), and QCoreApplication::setApplicationName(). + QSettings settings; + + std::vector fields; + object->fields(fields); + + size_t i; + for (i = 0; i < fields.size(); i++) + { + caf::PdmFieldHandle* fieldHandle = fields[i]; + + std::vector children; + fieldHandle->childObjects(&children); + for (size_t childIdx = 0; childIdx < children.size(); childIdx++) + { + caf::PdmObjectHandle* child = children[childIdx]; + QString subContext; + if (context.isEmpty()) + { + caf::PdmXmlObjectHandle* xmlObjHandle = xmlObj(child); + + subContext = xmlObjHandle->classKeyword() + "/"; + } + + writeFieldsToApplicationStore(child, subContext); + } + + if (children.size() == 0) + { + caf::PdmValueField* valueField = dynamic_cast(fieldHandle); + assert(valueField); + settings.setValue(context + fieldHandle->keyword(), valueField->toQVariant()); + } + } +} + + +} // namespace caf diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmSettings.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmSettings.h similarity index 85% rename from Fwk/AppFwk/cafUserInterface/cafPdmSettings.h rename to Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmSettings.h index 2342eacd71..22bf3eb47a 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmSettings.h +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmSettings.h @@ -1,7 +1,7 @@ //################################################################################################## // // Custom Visualization Core library -// Copyright (C) 2011-2013 Ceetron AS +// Copyright (C) 2015 Ceetron Solutions AS // // This library may be used under the terms of either the GNU General Public License or // the GNU Lesser General Public License as follows: @@ -42,13 +42,13 @@ namespace caf { - class PdmObject; + class PdmObjectHandle; -class Settings +class PdmSettings { public: - static void readFieldsFromApplicationStore(caf::PdmObject* object); - static void writeFieldsToApplicationStore(caf::PdmObject* object); + static void readFieldsFromApplicationStore(caf::PdmObjectHandle* object, const QString context = ""); + static void writeFieldsToApplicationStore(caf::PdmObjectHandle* object, const QString context = ""); }; diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmXmlFieldHandle.cpp b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmXmlFieldHandle.cpp new file mode 100644 index 0000000000..e6bd532bd3 --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmXmlFieldHandle.cpp @@ -0,0 +1,63 @@ +#include "cafPdmXmlFieldHandle.h" + +#include "cafPdmFieldHandle.h" +#include "cafPdmXmlObjectHandle.h" + +#include + +namespace caf +{ + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool PdmXmlFieldHandle::assertValid() const +{ + + if (m_owner->keyword().isEmpty()) + { + std::cout << "PdmField: Detected use of non-initialized field. Did you forget to do CAF_PDM_InitField() on this field ?\n"; + return false; + } + + if (!PdmXmlObjectHandle::isValidXmlElementName(m_owner->keyword())) + { + std::cout << "PdmField: The supplied keyword: \"" << m_owner->keyword().toStdString() << "\" is an invalid XML element name, and will break your file format!\n"; + return false; + } + + return true; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +PdmXmlFieldHandle::PdmXmlFieldHandle(PdmFieldHandle* owner, bool giveOwnership) : m_isIOReadable(true), m_isIOWritable(true) +{ + m_owner = owner; + owner->addCapability(this, giveOwnership); +} + +//-------------------------------------------------------------------------------------------------- +/// Returns the classKeyword of the child class type, if this field is supposed to contain pointers +/// to PdmObjectHandle derived onbjects. +/// Returns empty string if the field is not containig some PdmObjectHandle type +//-------------------------------------------------------------------------------------------------- +QString PdmXmlFieldHandle::childClassKeyword() +{ + return m_childClassKeyword; +} + +//-------------------------------------------------------------------------------------------------- +/// Implementation of uiCapability() defined in cafPdmFieldHandle.h +//-------------------------------------------------------------------------------------------------- +PdmXmlFieldHandle* PdmFieldHandle::xmlCapability() +{ + PdmXmlFieldHandle* xmlField = capability(); + assert(xmlField); + + return xmlField; +} + +} // End of namespace caf diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmXmlFieldHandle.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmXmlFieldHandle.h new file mode 100644 index 0000000000..bf426be4a1 --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmXmlFieldHandle.h @@ -0,0 +1,55 @@ +#pragma once + +#include "cafPdmFieldCapability.h" +#include + +class QXmlStreamReader; +class QXmlStreamWriter; + +namespace caf +{ + +class PdmFieldHandle; +class PdmObjectFactory; +class PdmReferenceHelper; + + +//================================================================================================== +// +// +// +//================================================================================================== +class PdmXmlFieldHandle : public PdmFieldCapability +{ +public: + PdmXmlFieldHandle(PdmFieldHandle* owner , bool giveOwnership); + virtual ~PdmXmlFieldHandle() { } + + PdmFieldHandle* fieldHandle() { return m_owner; } + + bool isIOReadable() { return m_isIOReadable; } + bool isIOWritable() { return m_isIOWritable; } + void setIOWritable(bool isWritable) { m_isIOWritable = isWritable; } + void setIOReadable(bool isReadable) { m_isIOReadable = isReadable; } + + QString childClassKeyword(); + + virtual void readFieldData(QXmlStreamReader& xmlStream, PdmObjectFactory* objectFactory) = 0; + virtual void writeFieldData(QXmlStreamWriter& xmlStream) = 0; + + virtual void resolveReferences() { }; + +protected: + bool assertValid() const; + QString m_childClassKeyword; ///< Must be set in constructor of derived XmlFieldHandle + +private: + bool m_isIOReadable; + bool m_isIOWritable; + + PdmFieldHandle* m_owner; +}; + +} // End of namespace caf + +#include "cafInternalPdmXmlFieldCapability.h" diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmXmlObjectHandle.cpp b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmXmlObjectHandle.cpp new file mode 100644 index 0000000000..b5fb344fc5 --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmXmlObjectHandle.cpp @@ -0,0 +1,349 @@ +#include "cafPdmXmlObjectHandle.h" + +#include "cafPdmObjectHandle.h" +#include "cafPdmXmlFieldHandle.h" + +#include "cafPdmFieldHandle.h" + +#include +#include + +#include +#include + +namespace caf +{ + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +PdmXmlObjectHandle::PdmXmlObjectHandle(PdmObjectHandle* owner, bool giveOwnership) +{ + m_owner = owner; + m_owner->addCapability(this, giveOwnership); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +PdmXmlObjectHandle* xmlObj(PdmObjectHandle* obj) +{ + if (!obj) return NULL; + PdmXmlObjectHandle* xmlObject = obj->capability(); + assert(xmlObject); + return xmlObject; +} + + +//-------------------------------------------------------------------------------------------------- +/// Reads all the fields into this PdmObject +/// Assumes xmlStream points to the start element token of the PdmObject for which to read fields. +/// ( and not first token of object content) +/// This makes attribute based field storage possible. +/// Leaves the xmlStream pointing to the EndElement of the PdmObject. +//-------------------------------------------------------------------------------------------------- +void PdmXmlObjectHandle::readFields(QXmlStreamReader& xmlStream, PdmObjectFactory* objectFactory) +{ + bool isObjectFinished = false; + QXmlStreamReader::TokenType type; + while (!isObjectFinished) + { + type = xmlStream.readNext(); + + switch (type) + { + case QXmlStreamReader::StartElement: + { + QString name = xmlStream.name().toString(); + + PdmFieldHandle* fieldHandle = m_owner->findField(name); + if (fieldHandle && fieldHandle->xmlCapability()) + { + PdmXmlFieldHandle* xmlFieldHandle = fieldHandle->xmlCapability(); + if (xmlFieldHandle->isIOReadable()) + { + // readFieldData assumes that the xmlStream points to first token of field content. + // After reading, the xmlStream is supposed to point to the first token after the field content. + // (typically an "endElement") + QXmlStreamReader::TokenType tt; + tt = xmlStream.readNext(); + xmlFieldHandle->readFieldData(xmlStream, objectFactory); + } + else + { + xmlStream.skipCurrentElement(); + } + } + else + { + std::cout << "Line " << xmlStream.lineNumber() << ": Warning: Could not find a field with name " << name.toLatin1().data() << " in the current object : " << classKeyword().toLatin1().data() << std::endl; + xmlStream.skipCurrentElement(); + } + break; + } + break; + case QXmlStreamReader::EndElement: + { + // End of object. + QString name = xmlStream.name().toString(); // For debugging + isObjectFinished = true; + } + break; + case QXmlStreamReader::EndDocument: + { + // End of object. + isObjectFinished = true; + } + break; + default: + { + // Just read on + // Todo: Error handling + } + break; + } + } + +} +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmXmlObjectHandle::writeFields(QXmlStreamWriter& xmlStream) +{ + std::vector fields; + m_owner->fields(fields); + for (size_t it = 0; it < fields.size(); ++it) + { + PdmXmlFieldHandle* field = fields[it]->xmlCapability(); + if (field && field->isIOWritable()) + { + QString keyword = field->fieldHandle()->keyword(); + assert(PdmXmlObjectHandle::isValidXmlElementName(keyword)); + + xmlStream.writeStartElement("", keyword); + field->writeFieldData(xmlStream); + xmlStream.writeEndElement(); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmXmlObjectHandle::readObjectFromXmlString(const QString& xmlString, PdmObjectFactory* objectFactory) +{ + // A valid XML is used to store field data of the object. The format of the XML is like this + + /* + + value + value + + */ + + QXmlStreamReader inputStream(xmlString); + + QXmlStreamReader::TokenType tt; + tt = inputStream.readNext(); // Start of document + tt = inputStream.readNext(); + QString classKeyword = inputStream.name().toString(); + assert(classKeyword == this->classKeyword()); + + this->readFields(inputStream, objectFactory); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +PdmObjectHandle* PdmXmlObjectHandle::readUnknownObjectFromXmlString(const QString& xmlString, PdmObjectFactory* objectFactory) +{ + QXmlStreamReader inputStream(xmlString); + + QXmlStreamReader::TokenType tt; + tt = inputStream.readNext(); // Start of document + tt = inputStream.readNext(); + QString classKeyword = inputStream.name().toString(); + PdmObjectHandle* newObject = objectFactory->create(classKeyword); + + xmlObj(newObject)->readFields(inputStream, objectFactory); + + return newObject; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +PdmObjectHandle* PdmXmlObjectHandle::copyByXmlSerialization(PdmObjectFactory* objectFactory) +{ + this->setupBeforeSaveRecursively(); + + QString xmlString = this->writeObjectToXmlString(); + + PdmObjectHandle* objectCopy = PdmXmlObjectHandle::readUnknownObjectFromXmlString(xmlString, objectFactory); + objectCopy->xmlCapability()->initAfterReadRecursively(); + + return objectCopy; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString PdmXmlObjectHandle::writeObjectToXmlString() +{ + QString xmlString; + QXmlStreamWriter outputStream(&xmlString); + outputStream.setAutoFormatting(true); + + outputStream.writeStartElement("", this->classKeyword()); + this->writeFields(outputStream); + outputStream.writeEndElement(); + return xmlString; +} + +//-------------------------------------------------------------------------------------------------- +/// Check if a string is a valid Xml element name +// +/// http://www.w3schools.com/xml/xml_elements.asp +/// +/// XML elements must follow these naming rules: +/// Names can contain letters, numbers, and other characters +/// Names cannot start with a number or punctuation character +/// Names cannot start with the letters xml (or XML, or Xml, etc) +/// Names cannot contain spaces +//-------------------------------------------------------------------------------------------------- +bool PdmXmlObjectHandle::isValidXmlElementName(const QString& name) +{ + if (name.isEmpty()) + { + return false; + } + + if (name.size() > 0) + { + QChar firstChar = name[0]; + if (firstChar.isDigit() || firstChar == '.') + { + return false; + } + } + + if (name.size() >= 3) + { + if (name.left(3).compare("xml", Qt::CaseInsensitive) == 0) + { + return false; + } + } + + if (name.contains(' ')) + { + return false; + } + + return true; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmXmlObjectHandle::initAfterReadRecursively(PdmObjectHandle* object) +{ + if (object == NULL) return; + + std::vector fields; + object->fields(fields); + + std::vector children; + size_t fIdx; + for (fIdx = 0; fIdx < fields.size(); ++fIdx) + { + if (fields[fIdx]) fields[fIdx]->childObjects(&children); + } + + size_t cIdx; + for (cIdx = 0; cIdx < children.size(); ++cIdx) + { + initAfterReadRecursively(children[cIdx]); + } + + PdmXmlObjectHandle* xmlObject = xmlObj(object); + if (xmlObject) + { + xmlObject->initAfterRead(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmXmlObjectHandle::resolveReferencesRecursively(PdmObjectHandle* object) +{ + if (object == NULL) return; + + std::vector fields; + object->fields(fields); + + std::vector children; + size_t fIdx; + for (fIdx = 0; fIdx < fields.size(); ++fIdx) + { + PdmFieldHandle* field = fields[fIdx]; + if (field) + { + field->childObjects(&children); + + field->xmlCapability()->resolveReferences(); + } + } + + size_t cIdx; + for (cIdx = 0; cIdx < children.size(); ++cIdx) + { + resolveReferencesRecursively(children[cIdx]); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmXmlObjectHandle::setupBeforeSaveRecursively(PdmObjectHandle* object) +{ + if (object == NULL) return; + + std::vector fields; + object->fields(fields); + + std::vector children; + size_t fIdx; + for (fIdx = 0; fIdx < fields.size(); ++fIdx) + { + if (fields[fIdx]) fields[fIdx]->childObjects(&children); + } + + size_t cIdx; + for (cIdx = 0; cIdx < children.size(); ++cIdx) + { + setupBeforeSaveRecursively(children[cIdx]); + } + + PdmXmlObjectHandle* xmlObject = xmlObj(object); + if (xmlObject) + { + xmlObject->setupBeforeSave(); + } +} + + +//-------------------------------------------------------------------------------------------------- +/// Implementation of xmlCapability() defined in cafPdmObjectHandle.h +//-------------------------------------------------------------------------------------------------- +PdmXmlObjectHandle* PdmObjectHandle::xmlCapability() + { + PdmXmlObjectHandle* xmlField = capability(); + assert(xmlField); + + return xmlField; +} + + +} // end namespace caf diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmXmlObjectHandle.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmXmlObjectHandle.h new file mode 100644 index 0000000000..0759889f52 --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmXmlObjectHandle.h @@ -0,0 +1,80 @@ +#pragma once + +#include "cafPdmObjectCapability.h" + +#include + +class QXmlStreamReader; +class QXmlStreamWriter; + + +namespace caf +{ + +class PdmXmlFieldHandle; +class PdmObjectHandle; +class PdmObjectFactory; +class PdmReferenceHelper; + + +//================================================================================================== +// +// +// +//================================================================================================== +class PdmXmlObjectHandle : public PdmObjectCapability +{ +public: + + PdmXmlObjectHandle(PdmObjectHandle* owner, bool giveOwnership); + virtual ~PdmXmlObjectHandle() { } + + /// The classKeyword method is overridden in subclasses by the CAF_PDM_XML_HEADER_INIT macro + virtual QString classKeyword() = 0; + + /// Convenience methods to serialize/de-serialize this particular object (with children) + void readObjectFromXmlString(const QString& xmlString, PdmObjectFactory* objectFactory); + QString writeObjectToXmlString(); + static PdmObjectHandle* readUnknownObjectFromXmlString(const QString& xmlString, PdmObjectFactory* objectFactory); + PdmObjectHandle* copyByXmlSerialization(PdmObjectFactory* objectFactory); + + // Main XML serialization methods that is used internally by the document serialization system + // Not supposed to be used directly. + void readFields(QXmlStreamReader& inputStream, PdmObjectFactory* objectFactory); + void writeFields(QXmlStreamWriter& outputStream); + + /// Check if a string is a valid Xml element name + static bool isValidXmlElementName(const QString& name); + + void initAfterReadRecursively() { initAfterReadRecursively(this->m_owner); }; + void setupBeforeSaveRecursively() { setupBeforeSaveRecursively(this->m_owner); }; + void resolveReferencesRecursively() { resolveReferencesRecursively(this->m_owner); }; + +protected: // Virtual + /// Method gets called from PdmDocument after all objects are read. + /// Re-implement to set up internal pointers etc. in your data structure + virtual void initAfterRead() {}; + /// Method gets called from PdmDocument before saving document. + /// Re-implement to make sure your fields have correct data before saving + virtual void setupBeforeSave() {}; + + /// This method is intended to be used in macros to make compile time errors + // if user uses them on wrong type of objects + bool isInheritedFromPdmXmlSerializable() { return true; } + +private: + void initAfterReadRecursively(PdmObjectHandle* object); + void setupBeforeSaveRecursively(PdmObjectHandle * object); + void resolveReferencesRecursively(PdmObjectHandle* object); + +private: + friend class PdmObjectHandle ; // Only temporary for void PdmObject::addFieldNoDefault( ) accessing findField + + PdmObjectHandle* m_owner; +}; + +PdmXmlObjectHandle* xmlObj(PdmObjectHandle* obj); + +} // End of namespace caf + +#include "cafPdmXmlFieldHandle.h" diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmXmlObjectHandleMacros.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmXmlObjectHandleMacros.h new file mode 100644 index 0000000000..339dc96070 --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmXmlObjectHandleMacros.h @@ -0,0 +1,54 @@ +#pragma once + +#include "cafPdmDefaultObjectFactory.h" + +// Taken from gtest.h +// +// Due to C++ preprocessor weirdness, we need double indirection to +// concatenate two tokens when one of them is __LINE__. Writing +// +// foo ## __LINE__ +// +// will result in the token foo__LINE__, instead of foo followed by +// the current line number. For more details, see +// http://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.6 +#define PDM_OBJECT_STRING_CONCATENATE(foo, bar) PDM_OBJECT_STRING_CONCATENATE_IMPL_(foo, bar) +#define PDM_OBJECT_STRING_CONCATENATE_IMPL_(foo, bar) foo ## bar + + +/// CAF_PDM_HEADER_INIT assists the factory used when reading objects from file +/// Place this in the header file inside the class definition of your PdmObject + +// To be renamed CAF_PDM_XML_HEADER_INIT +#define CAF_PDM_XML_HEADER_INIT \ +public: \ + virtual QString classKeyword() { return classKeywordStatic(); } \ + static QString classKeywordStatic(); \ + \ + static bool Error_You_forgot_to_add_the_macro_CAF_PDM_XML_HEADER_INIT_and_or_CAF_PDM_XML_SOURCE_INIT_to_your_cpp_file_for_this_class() + + +/// CAF_PDM_XML_SOURCE_INIT associates the file keyword used for storage with the class and +// initializes the factory +/// Place this in the cpp file, preferably above the constructor + +#define CAF_PDM_XML_SOURCE_INIT(ClassName, keyword) \ + bool ClassName::Error_You_forgot_to_add_the_macro_CAF_PDM_XML_HEADER_INIT_and_or_CAF_PDM_XML_SOURCE_INIT_to_your_cpp_file_for_this_class() { return false;} \ + \ + QString ClassName::classKeywordStatic() { return keyword; } \ + static bool PDM_OBJECT_STRING_CONCATENATE(pdm_object_factory_init_, __LINE__) = caf::PdmDefaultObjectFactory::instance()->registerCreator() + +#define CAF_PDM_XML_ABSTRACT_SOURCE_INIT(ClassName, keyword) \ + bool ClassName::Error_You_forgot_to_add_the_macro_CAF_PDM_XML_HEADER_INIT_and_or_CAF_PDM_XML_SOURCE_INIT_to_your_cpp_file_for_this_class() { return false;} \ + \ + QString ClassName::classKeywordStatic() { return keyword; } \ + +#define CAF_PDM_XML_InitField(field, keyword) \ +{ \ + static bool chekingThePresenceOfHeaderAndSourceInitMacros = \ + Error_You_forgot_to_add_the_macro_CAF_PDM_XML_HEADER_INIT_and_or_CAF_PDM_XML_SOURCE_INIT_to_your_cpp_file_for_this_class(); \ + this->isInheritedFromPdmXmlSerializable(); \ + \ + AddXmlCapabilityToField((field)); \ + addField((field), (keyword)); \ +} diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmXml_UnitTests/CMakeLists.txt b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmXml_UnitTests/CMakeLists.txt new file mode 100644 index 0000000000..e2fe8ba28d --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmXml_UnitTests/CMakeLists.txt @@ -0,0 +1,42 @@ +cmake_minimum_required (VERSION 2.8) + +find_package ( Qt4 COMPONENTS QtCore ) +include (${QT_USE_FILE}) + +project ( cafPdmXml_UnitTests ) + +include_directories ( + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/.. + ${cafPdmCore_SOURCE_DIR} +) + + +# add the executable +add_executable (${PROJECT_NAME} + cafPdmXml_UnitTests.cpp + gtest/gtest-all.cpp + + cafPdmXmlBasicTest.cpp + cafPdmAdvancedTemplateTest.cpp +) +message(STATUS ${PROJECT_NAME}" - Qt includes : " ${QT_LIBRARIES}) + +target_link_libraries ( ${PROJECT_NAME} + cafPdmCore + cafPdmXml + ${QT_LIBRARIES} +) + +# Copy Qt Dlls +if (MSVC) + set (QTLIBLIST QtCore ) + foreach (qtlib ${QTLIBLIST}) + + # Debug + execute_process(COMMAND cmake -E copy_if_different ${QT_BINARY_DIR}/${qtlib}d4.dll ${CMAKE_CURRENT_BINARY_DIR}/Debug/${qtlib}d4.dll) + + # Release + execute_process(COMMAND cmake -E copy_if_different ${QT_BINARY_DIR}/${qtlib}4.dll ${CMAKE_CURRENT_BINARY_DIR}/Release/${qtlib}4.dll) + endforeach( qtlib ) +endif(MSVC) diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmXml_UnitTests/cafPdmAdvancedTemplateTest.cpp b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmXml_UnitTests/cafPdmAdvancedTemplateTest.cpp new file mode 100644 index 0000000000..7c8000f8c9 --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmXml_UnitTests/cafPdmAdvancedTemplateTest.cpp @@ -0,0 +1,203 @@ + +#include "gtest/gtest.h" + + +#include "cafAppEnum.h" +#include "cafPdmChildArrayField.h" +#include "cafPdmDataValueField.h" +#include "cafPdmObjectHandle.h" +#include "cafPdmProxyValueField.h" +#include "cafPdmPtrField.h" +#include "cafPdmReferenceHelper.h" +#include "cafPdmXmlObjectHandle.h" +#include "cafPdmXmlObjectHandleMacros.h" + +#include + + + + + +class ItemPdmObject : public caf::PdmObjectHandle, public caf::PdmXmlObjectHandle +{ + CAF_PDM_XML_HEADER_INIT; +public: + + ItemPdmObject() : PdmObjectHandle(), PdmXmlObjectHandle(this, false) + { + CAF_PDM_XML_InitField(&m_name, "Name"); + } + + ItemPdmObject(QString name) : PdmObjectHandle(), PdmXmlObjectHandle(this, false) + { + CAF_PDM_XML_InitField(&m_name, "Name"); + m_name = name; + } + + ~ItemPdmObject() + { + } + + // Fields + caf::PdmDataValueField m_name; +}; +CAF_PDM_XML_SOURCE_INIT(ItemPdmObject, "ItemPdmObject"); + +class DemoPdmObjectA; + +class ContainerPdmObject : public caf::PdmObjectHandle, public caf::PdmXmlObjectHandle +{ + CAF_PDM_XML_HEADER_INIT; +public: + + ContainerPdmObject() : PdmObjectHandle(), PdmXmlObjectHandle(this, false) + { + CAF_PDM_XML_InitField(&m_items, "Items"); + CAF_PDM_XML_InitField(&m_containers, "Containers"); + CAF_PDM_XML_InitField(&m_demoObjs, "DemoObjs"); + + } + + ~ContainerPdmObject() + { + } + + // Fields + caf::PdmChildArrayField m_items; + caf::PdmChildArrayField m_containers; + caf::PdmChildArrayField m_demoObjs; + +}; +CAF_PDM_XML_SOURCE_INIT(ContainerPdmObject, "ContainerPdmObject"); + +class DemoPdmObjectA : public caf::PdmObjectHandle, public caf::PdmXmlObjectHandle +{ + CAF_PDM_XML_HEADER_INIT; +public: + enum TestEnumType + { + T1, T2, T3 + }; + + DemoPdmObjectA() : PdmObjectHandle(), PdmXmlObjectHandle(this, false) + { + + CAF_PDM_XML_InitField(&m_doubleField, "BigNumber"); + m_doubleField.registerSetMethod(this, &DemoPdmObjectA::setDoubleMember); + m_doubleField.registerGetMethod(this, &DemoPdmObjectA::doubleMember); + + CAF_PDM_XML_InitField(&m_pointerToItem, "TestPointerToItem"); + CAF_PDM_XML_InitField(&m_pointerToDemoObj, "TestPointerToDemo"); + + } + + ~DemoPdmObjectA() + { + } + + // Fields + caf::PdmProxyValueField m_doubleField; + caf::PdmPtrField< caf::PdmObjectHandle* > m_pointerToItem; + caf::PdmPtrField< caf::PdmObjectHandle* > m_pointerToDemoObj; + + void setDoubleMember(const double& d) { m_doubleMember = d; std::cout << "setDoubleMember" << std::endl; } + double doubleMember() const { std::cout << "doubleMember" << std::endl; return m_doubleMember; } + double m_doubleMember; +}; + +CAF_PDM_XML_SOURCE_INIT(DemoPdmObjectA, "DemoPdmObjectA"); + +namespace caf +{ + +template<> +void AppEnum::setUp() +{ + addItem(DemoPdmObjectA::T1, "T1", "An A letter"); + addItem(DemoPdmObjectA::T2, "T2", "A B letter"); + addItem(DemoPdmObjectA::T3, "T3", "A B letter"); + setDefault(DemoPdmObjectA::T1); +} + +} + + +//-------------------------------------------------------------------------------------------------- +/// Read/write fields to a valid Xml document encoded in a QString +//-------------------------------------------------------------------------------------------------- +TEST(AdvancedObjectTest, FieldWrite) +{ + ContainerPdmObject* root = new ContainerPdmObject; + ContainerPdmObject* container = new ContainerPdmObject; + ContainerPdmObject* sibling = new ContainerPdmObject; + root->m_containers.push_back(container); + root->m_containers.push_back(sibling); + + { + ItemPdmObject* item = new ItemPdmObject(); + item->m_name = "Obj A"; + + container->m_items.push_back(item); + } + { + ItemPdmObject* item = new ItemPdmObject(); + item->m_name = "Obj B"; + + container->m_items.push_back(item); + } + + { + ItemPdmObject* item = new ItemPdmObject(); + item->m_name = "Obj C"; + + container->m_items.push_back(item); + } + + + // Test with empty ptr field + { + QString serializedString; + { + DemoPdmObjectA* a = new DemoPdmObjectA; + sibling->m_demoObjs.push_back(a); + serializedString = a->writeObjectToXmlString(); + delete a; + } + + + { + DemoPdmObjectA* a = new DemoPdmObjectA; + sibling->m_demoObjs.push_back(a); + + a->readObjectFromXmlString(serializedString, caf::PdmDefaultObjectFactory::instance()); + + ASSERT_TRUE(a->m_pointerToItem() == NULL); + } + } + + { + QString serializedString; + { + DemoPdmObjectA* a = new DemoPdmObjectA; + sibling->m_demoObjs.push_back(a); + + a->m_pointerToItem = container->m_items[1]; + + serializedString = a->writeObjectToXmlString(); + std::cout << serializedString.toStdString() << std::endl; + delete a; + } + + + { + DemoPdmObjectA* a = new DemoPdmObjectA; + sibling->m_demoObjs.push_back(a); + + a->readObjectFromXmlString(serializedString, caf::PdmDefaultObjectFactory::instance()); + a->xmlCapability()->resolveReferencesRecursively(); + + ASSERT_TRUE(a->m_pointerToItem() == container->m_items[1]); + } + } +} + diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmXml_UnitTests/cafPdmXmlBasicTest.cpp b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmXml_UnitTests/cafPdmXmlBasicTest.cpp new file mode 100644 index 0000000000..9763036182 --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmXml_UnitTests/cafPdmXmlBasicTest.cpp @@ -0,0 +1,342 @@ + +#include "gtest/gtest.h" + +#include "cafAppEnum.h" + +#include "cafPdmObjectHandle.h" +#include "cafPdmProxyValueField.h" +#include "cafPdmPtrField.h" +#include "cafPdmReferenceHelper.h" +#include "cafPdmXmlObjectHandle.h" +#include "cafPdmXmlObjectHandleMacros.h" +#include "cafPdmDataValueField.h" +#include "cafPdmChildArrayField.h" +#include "cafPdmChildField.h" + +#include + + +class DemoPdmObject : public caf::PdmObjectHandle, public caf::PdmXmlObjectHandle +{ + CAF_PDM_XML_HEADER_INIT; +public: + enum TestEnumType + { + T1, T2, T3 + }; + + DemoPdmObject() : PdmObjectHandle(), PdmXmlObjectHandle(this, false) + { + CAF_PDM_XML_InitField(&m_proxyDoubleField, "BigNumber"); + m_proxyDoubleField.registerSetMethod(this, &DemoPdmObject::setDoubleMember); + m_proxyDoubleField.registerGetMethod(this, &DemoPdmObject::doubleMember); + + CAF_PDM_XML_InitField(&m_proxyEnumField, "AppEnum"); + m_proxyEnumField.registerSetMethod(this, &DemoPdmObject::setEnumMember); + m_proxyEnumField.registerGetMethod(this, &DemoPdmObject::enumMember); + m_enumMember = T1; + } + + ~DemoPdmObject() + { + } + + // Fields + + caf::PdmProxyValueField m_proxyDoubleField; + caf::PdmProxyValueField > m_proxyEnumField; + +private: + void setDoubleMember(const double& d) { m_doubleMember = d; std::cout << "setDoubleMember" << std::endl; } + double doubleMember() const { std::cout << "doubleMember" << std::endl; return m_doubleMember; } + + void setEnumMember(const caf::AppEnum& val) { m_enumMember = val; } + caf::AppEnum enumMember() const { return m_enumMember; } + + double m_doubleMember; + TestEnumType m_enumMember; +}; + +CAF_PDM_XML_SOURCE_INIT(DemoPdmObject, "DemoPdmObject"); + + + +namespace caf +{ + +template<> +void AppEnum::setUp() +{ + addItem(DemoPdmObject::T1, "T1", "An A letter"); + addItem(DemoPdmObject::T2, "T2", "A B letter"); + addItem(DemoPdmObject::T3, "T3", "A B letter"); + setDefault(DemoPdmObject::T1); +} + +} + +TEST(BaseTest, Delete) +{ + DemoPdmObject* s2 = new DemoPdmObject; + delete s2; +} + +#if 0 +//-------------------------------------------------------------------------------------------------- +/// Read/write Xml using PdmObjectGroup +//-------------------------------------------------------------------------------------------------- +TEST(BaseTest, Start) +{ + QString serializedString; + { + DemoPdmObject* a = new DemoPdmObject; + + a->m_proxyDoubleField.setValue(2.5); + a->m_proxyEnumField.setValue(DemoPdmObject::T3); + + ASSERT_DOUBLE_EQ(2.5, a->m_proxyDoubleField.value()); + + caf::PdmObjectGroup objGroup; + objGroup.addObject(a); + + QXmlStreamWriter xmlStream(&serializedString); + xmlStream.setAutoFormatting(true); + objGroup.writeFields(xmlStream, NULL); + + std::cout << serializedString.toStdString() << std::endl; + + delete a; + } + + /* + + + 2.5 + T3 + + + */ + + { + caf::PdmObjectGroup destinationObjectGroup; + QXmlStreamReader xmlStream(serializedString); + destinationObjectGroup.readFields(xmlStream, caf::PdmDefaultObjectFactory::instance(), NULL); + + DemoPdmObject* a = dynamic_cast(destinationObjectGroup.objects[0]); + + ASSERT_DOUBLE_EQ(2.5, a->m_proxyDoubleField.value()); + ASSERT_EQ(DemoPdmObject::T3, a->m_proxyEnumField()); + + } +} +#endif +//-------------------------------------------------------------------------------------------------- +/// Read/write fields to a valid Xml document encoded in a QString +//-------------------------------------------------------------------------------------------------- +TEST(BaseTest, FieldWrite) +{ + QString serializedString; + { + DemoPdmObject* a = new DemoPdmObject; + + a->m_proxyDoubleField.setValue(2.5); + ASSERT_DOUBLE_EQ(2.5, a->m_proxyDoubleField.value()); + + serializedString = a->writeObjectToXmlString(); + + std::cout << serializedString.toStdString() << std::endl; + + delete a; + } + + /* + + 2.5 + T3 + + */ + + { + DemoPdmObject* a = new DemoPdmObject; + + a->readObjectFromXmlString(serializedString, caf::PdmDefaultObjectFactory::instance()); + + } + +} + +class InheritedDemoObj : public DemoPdmObject +{ + CAF_PDM_XML_HEADER_INIT; +public: + + InheritedDemoObj() + { + CAF_PDM_XML_InitField(&m_texts, "Texts"); + CAF_PDM_XML_InitField(&m_childArrayField, "DemoPdmObjectects"); + } + + caf::PdmDataValueField m_texts; + caf::PdmChildArrayField m_childArrayField; + +}; +CAF_PDM_XML_SOURCE_INIT(InheritedDemoObj, "InheritedDemoObj"); + + +class SimpleObj : public caf::PdmObjectHandle, public caf::PdmXmlObjectHandle +{ + CAF_PDM_XML_HEADER_INIT; +public: + SimpleObj() : PdmObjectHandle(), PdmXmlObjectHandle(this, false) + { + CAF_PDM_XML_InitField(&m_position, "Position"); + CAF_PDM_XML_InitField(&m_dir, "Dir"); + CAF_PDM_XML_InitField(&m_up, "Up"); + } + + caf::PdmDataValueField m_position; + caf::PdmDataValueField m_dir; + caf::PdmDataValueField m_up; + caf::PdmProxyValueField m_proxyDouble; + + void setDoubleMember(const double& d) { m_doubleMember = d; std::cout << "setDoubleMember" << std::endl; } + double doubleMember() const { std::cout << "doubleMember" << std::endl; return m_doubleMember; } + + double m_doubleMember; + + +}; +CAF_PDM_XML_SOURCE_INIT(SimpleObj, "SimpleObj"); + + +class ReferenceDemoPdmObject : public caf::PdmObjectHandle, public caf::PdmXmlObjectHandle +{ + CAF_PDM_XML_HEADER_INIT; +public: + + ReferenceDemoPdmObject() : PdmObjectHandle(), PdmXmlObjectHandle(this, false) + { + CAF_PDM_XML_InitField(&m_pointersField, "SimpleObjPtrField"); + CAF_PDM_XML_InitField(&m_simpleObjPtrField2, "SimpleObjPtrField2"); + } + + // Fields + caf::PdmChildField m_pointersField; + caf::PdmChildArrayField m_simpleObjPtrField2; +}; + +CAF_PDM_XML_SOURCE_INIT(ReferenceDemoPdmObject, "ReferenceDemoPdmObject"); + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(BaseTest, PdmReferenceHelper) +{ + DemoPdmObject* s1 = new DemoPdmObject; + DemoPdmObject* s2 = new DemoPdmObject; + DemoPdmObject* s3 = new DemoPdmObject; + + InheritedDemoObj* ihd1 = new InheritedDemoObj; + ihd1->m_childArrayField.push_back(new DemoPdmObject); + + ihd1->m_childArrayField.push_back(s1); + ihd1->m_childArrayField.push_back(s2); + ihd1->m_childArrayField.push_back(s3); + + { + QString refString = caf::PdmReferenceHelper::referenceFromRootToObject(ihd1, s3); + QString expectedString = ihd1->m_childArrayField.keyword() + " 3"; + EXPECT_STREQ(refString.toAscii(), expectedString.toAscii()); + + caf::PdmObjectHandle* fromRef = caf::PdmReferenceHelper::objectFromReference(ihd1, refString); + EXPECT_TRUE(fromRef == s3); + } + + ReferenceDemoPdmObject* objA = new ReferenceDemoPdmObject; + objA->m_pointersField = ihd1; + + { + QString refString = caf::PdmReferenceHelper::referenceFromRootToObject(objA, s3); + + caf::PdmObjectHandle* fromRef = caf::PdmReferenceHelper::objectFromReference(objA, refString); + EXPECT_TRUE(fromRef == s3); + } + + + // Test reference to field + { + QString refString = caf::PdmReferenceHelper::referenceFromRootToField(objA, &(ihd1->m_childArrayField)); + + caf::PdmFieldHandle* fromRef = caf::PdmReferenceHelper::fieldFromReference(objA, refString); + EXPECT_TRUE(fromRef == &(ihd1->m_childArrayField)); + } + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(BaseTest, ChildArrayFieldSerializing) +{ + DemoPdmObject* s1 = new DemoPdmObject; + s1->m_proxyDoubleField.setValue(10); + + DemoPdmObject* s2 = new DemoPdmObject; + s2->m_proxyDoubleField.setValue(20); + + DemoPdmObject* s3 = new DemoPdmObject; + s3->m_proxyDoubleField.setValue(30); + + InheritedDemoObj* ihd1 = new InheritedDemoObj; + ihd1->m_childArrayField.push_back(s1); + ihd1->m_childArrayField.push_back(s2); + ihd1->m_childArrayField.push_back(s3); + + QString serializedString; + { + serializedString = ihd1->writeObjectToXmlString(); + + std::cout << serializedString.toStdString() << std::endl; + + delete ihd1; + } + + { + InheritedDemoObj* ihd1 = new InheritedDemoObj; + ASSERT_EQ(0, ihd1->m_childArrayField.size()); + + QXmlStreamReader xmlStream(serializedString); + + ihd1->readObjectFromXmlString(serializedString, caf::PdmDefaultObjectFactory::instance()); + + ASSERT_DOUBLE_EQ(10, ihd1->m_childArrayField[0]->m_proxyDoubleField.value()); + ASSERT_DOUBLE_EQ(20, ihd1->m_childArrayField[1]->m_proxyDoubleField.value()); + ASSERT_DOUBLE_EQ(30, ihd1->m_childArrayField[2]->m_proxyDoubleField.value()); + } +} + +//-------------------------------------------------------------------------------------------------- +/// Testing that the QXmlStreamReader actually can not just read a list of fields. +//-------------------------------------------------------------------------------------------------- +TEST(BaseTest, QXMLStreamTest) +{ + QString xmlText = + //"" + "2.5" + "T3" + "T3" + //"" + ; + + QXmlStreamReader inputStream(xmlText); + + QXmlStreamReader::TokenType tt; + while (!inputStream.atEnd()) + { + tt = inputStream.readNext(); + std::cout << inputStream.name().toString().toStdString() << std::endl; + } + + +} \ No newline at end of file diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmXml_UnitTests/cafPdmXml_UnitTests.cpp b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmXml_UnitTests/cafPdmXml_UnitTests.cpp new file mode 100644 index 0000000000..e50441cd76 --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmXml_UnitTests/cafPdmXml_UnitTests.cpp @@ -0,0 +1,56 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2013 Ceetron AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + + +#include "gtest/gtest.h" +#include +#include +#include + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +int main(int argc, char **argv) +{ + + testing::InitGoogleTest(&argc, argv); + int result = RUN_ALL_TESTS(); + + char text[5]; + std::cin.getline(text, 5); + + return result; +} diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmXml_UnitTests/gtest/gtest-all.cpp b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmXml_UnitTests/gtest/gtest-all.cpp new file mode 100644 index 0000000000..644479a63c --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmXml_UnitTests/gtest/gtest-all.cpp @@ -0,0 +1,8510 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: mheule@google.com (Markus Heule) +// +// Google C++ Testing Framework (Google Test) +// +// Sometimes it's desirable to build Google Test by compiling a single file. +// This file serves this purpose. + +// This line ensures that gtest.h can be compiled on its own, even +// when it's fused. +#include + +// The following lines pull in the real gtest *.cc files. +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: wan@google.com (Zhanyong Wan) +// +// The Google C++ Testing Framework (Google Test) + +// Copyright 2007, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: wan@google.com (Zhanyong Wan) +// +// Utilities for testing Google Test itself and code that uses Google Test +// (e.g. frameworks built on top of Google Test). + +#ifndef GTEST_INCLUDE_GTEST_GTEST_SPI_H_ +#define GTEST_INCLUDE_GTEST_GTEST_SPI_H_ + + +namespace testing { + +// This helper class can be used to mock out Google Test failure reporting +// so that we can test Google Test or code that builds on Google Test. +// +// An object of this class appends a TestPartResult object to the +// TestPartResultArray object given in the constructor whenever a Google Test +// failure is reported. It can either intercept only failures that are +// generated in the same thread that created this object or it can intercept +// all generated failures. The scope of this mock object can be controlled with +// the second argument to the two arguments constructor. +class GTEST_API_ ScopedFakeTestPartResultReporter + : public TestPartResultReporterInterface { + public: + // The two possible mocking modes of this object. + enum InterceptMode { + INTERCEPT_ONLY_CURRENT_THREAD, // Intercepts only thread local failures. + INTERCEPT_ALL_THREADS // Intercepts all failures. + }; + + // The c'tor sets this object as the test part result reporter used + // by Google Test. The 'result' parameter specifies where to report the + // results. This reporter will only catch failures generated in the current + // thread. DEPRECATED + explicit ScopedFakeTestPartResultReporter(TestPartResultArray* result); + + // Same as above, but you can choose the interception scope of this object. + ScopedFakeTestPartResultReporter(InterceptMode intercept_mode, + TestPartResultArray* result); + + // The d'tor restores the previous test part result reporter. + virtual ~ScopedFakeTestPartResultReporter(); + + // Appends the TestPartResult object to the TestPartResultArray + // received in the constructor. + // + // This method is from the TestPartResultReporterInterface + // interface. + virtual void ReportTestPartResult(const TestPartResult& result); + private: + void Init(); + + const InterceptMode intercept_mode_; + TestPartResultReporterInterface* old_reporter_; + TestPartResultArray* const result_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedFakeTestPartResultReporter); +}; + +namespace internal { + +// A helper class for implementing EXPECT_FATAL_FAILURE() and +// EXPECT_NONFATAL_FAILURE(). Its destructor verifies that the given +// TestPartResultArray contains exactly one failure that has the given +// type and contains the given substring. If that's not the case, a +// non-fatal failure will be generated. +class GTEST_API_ SingleFailureChecker { + public: + // The constructor remembers the arguments. + SingleFailureChecker(const TestPartResultArray* results, + TestPartResult::Type type, + const char* substr); + ~SingleFailureChecker(); + private: + const TestPartResultArray* const results_; + const TestPartResult::Type type_; + const String substr_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(SingleFailureChecker); +}; + +} // namespace internal + +} // namespace testing + +// A set of macros for testing Google Test assertions or code that's expected +// to generate Google Test fatal failures. It verifies that the given +// statement will cause exactly one fatal Google Test failure with 'substr' +// being part of the failure message. +// +// There are two different versions of this macro. EXPECT_FATAL_FAILURE only +// affects and considers failures generated in the current thread and +// EXPECT_FATAL_FAILURE_ON_ALL_THREADS does the same but for all threads. +// +// The verification of the assertion is done correctly even when the statement +// throws an exception or aborts the current function. +// +// Known restrictions: +// - 'statement' cannot reference local non-static variables or +// non-static members of the current object. +// - 'statement' cannot return a value. +// - You cannot stream a failure message to this macro. +// +// Note that even though the implementations of the following two +// macros are much alike, we cannot refactor them to use a common +// helper macro, due to some peculiarity in how the preprocessor +// works. The AcceptsMacroThatExpandsToUnprotectedComma test in +// gtest_unittest.cc will fail to compile if we do that. +#define EXPECT_FATAL_FAILURE(statement, substr) \ + do { \ + class GTestExpectFatalFailureHelper {\ + public:\ + static void Execute() { statement; }\ + };\ + ::testing::TestPartResultArray gtest_failures;\ + ::testing::internal::SingleFailureChecker gtest_checker(\ + >est_failures, ::testing::TestPartResult::kFatalFailure, (substr));\ + {\ + ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ + ::testing::ScopedFakeTestPartResultReporter:: \ + INTERCEPT_ONLY_CURRENT_THREAD, >est_failures);\ + GTestExpectFatalFailureHelper::Execute();\ + }\ + } while (::testing::internal::AlwaysFalse()) + +#define EXPECT_FATAL_FAILURE_ON_ALL_THREADS(statement, substr) \ + do { \ + class GTestExpectFatalFailureHelper {\ + public:\ + static void Execute() { statement; }\ + };\ + ::testing::TestPartResultArray gtest_failures;\ + ::testing::internal::SingleFailureChecker gtest_checker(\ + >est_failures, ::testing::TestPartResult::kFatalFailure, (substr));\ + {\ + ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ + ::testing::ScopedFakeTestPartResultReporter:: \ + INTERCEPT_ALL_THREADS, >est_failures);\ + GTestExpectFatalFailureHelper::Execute();\ + }\ + } while (::testing::internal::AlwaysFalse()) + +// A macro for testing Google Test assertions or code that's expected to +// generate Google Test non-fatal failures. It asserts that the given +// statement will cause exactly one non-fatal Google Test failure with 'substr' +// being part of the failure message. +// +// There are two different versions of this macro. EXPECT_NONFATAL_FAILURE only +// affects and considers failures generated in the current thread and +// EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS does the same but for all threads. +// +// 'statement' is allowed to reference local variables and members of +// the current object. +// +// The verification of the assertion is done correctly even when the statement +// throws an exception or aborts the current function. +// +// Known restrictions: +// - You cannot stream a failure message to this macro. +// +// Note that even though the implementations of the following two +// macros are much alike, we cannot refactor them to use a common +// helper macro, due to some peculiarity in how the preprocessor +// works. If we do that, the code won't compile when the user gives +// EXPECT_NONFATAL_FAILURE() a statement that contains a macro that +// expands to code containing an unprotected comma. The +// AcceptsMacroThatExpandsToUnprotectedComma test in gtest_unittest.cc +// catches that. +// +// For the same reason, we have to write +// if (::testing::internal::AlwaysTrue()) { statement; } +// instead of +// GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement) +// to avoid an MSVC warning on unreachable code. +#define EXPECT_NONFATAL_FAILURE(statement, substr) \ + do {\ + ::testing::TestPartResultArray gtest_failures;\ + ::testing::internal::SingleFailureChecker gtest_checker(\ + >est_failures, ::testing::TestPartResult::kNonFatalFailure, \ + (substr));\ + {\ + ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ + ::testing::ScopedFakeTestPartResultReporter:: \ + INTERCEPT_ONLY_CURRENT_THREAD, >est_failures);\ + if (::testing::internal::AlwaysTrue()) { statement; }\ + }\ + } while (::testing::internal::AlwaysFalse()) + +#define EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(statement, substr) \ + do {\ + ::testing::TestPartResultArray gtest_failures;\ + ::testing::internal::SingleFailureChecker gtest_checker(\ + >est_failures, ::testing::TestPartResult::kNonFatalFailure, \ + (substr));\ + {\ + ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ + ::testing::ScopedFakeTestPartResultReporter::INTERCEPT_ALL_THREADS,\ + >est_failures);\ + if (::testing::internal::AlwaysTrue()) { statement; }\ + }\ + } while (::testing::internal::AlwaysFalse()) + +#endif // GTEST_INCLUDE_GTEST_GTEST_SPI_H_ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#if GTEST_OS_LINUX + +// TODO(kenton@google.com): Use autoconf to detect availability of +// gettimeofday(). +#define GTEST_HAS_GETTIMEOFDAY_ 1 + +#include +#include +#include +// Declares vsnprintf(). This header is not available on Windows. +#include +#include +#include +#include +#include +#include + +#elif GTEST_OS_SYMBIAN +#define GTEST_HAS_GETTIMEOFDAY_ 1 +#include // NOLINT + +#elif GTEST_OS_ZOS +#define GTEST_HAS_GETTIMEOFDAY_ 1 +#include // NOLINT + +// On z/OS we additionally need strings.h for strcasecmp. +#include // NOLINT + +#elif GTEST_OS_WINDOWS_MOBILE // We are on Windows CE. + +#include // NOLINT + +#elif GTEST_OS_WINDOWS // We are on Windows proper. + +#include // NOLINT +#include // NOLINT +#include // NOLINT +#include // NOLINT + +#if GTEST_OS_WINDOWS_MINGW +// MinGW has gettimeofday() but not _ftime64(). +// TODO(kenton@google.com): Use autoconf to detect availability of +// gettimeofday(). +// TODO(kenton@google.com): There are other ways to get the time on +// Windows, like GetTickCount() or GetSystemTimeAsFileTime(). MinGW +// supports these. consider using them instead. +#define GTEST_HAS_GETTIMEOFDAY_ 1 +#include // NOLINT +#endif // GTEST_OS_WINDOWS_MINGW + +// cpplint thinks that the header is already included, so we want to +// silence it. +#include // NOLINT + +#else + +// Assume other platforms have gettimeofday(). +// TODO(kenton@google.com): Use autoconf to detect availability of +// gettimeofday(). +#define GTEST_HAS_GETTIMEOFDAY_ 1 + +// cpplint thinks that the header is already included, so we want to +// silence it. +#include // NOLINT +#include // NOLINT + +#endif // GTEST_OS_LINUX + +#if GTEST_HAS_EXCEPTIONS +#include +#endif + +// Indicates that this translation unit is part of Google Test's +// implementation. It must come before gtest-internal-inl.h is +// included, or there will be a compiler error. This trick is to +// prevent a user from accidentally including gtest-internal-inl.h in +// his code. +#define GTEST_IMPLEMENTATION_ 1 +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Utility functions and classes used by the Google C++ testing framework. +// +// Author: wan@google.com (Zhanyong Wan) +// +// This file contains purely Google Test's internal implementation. Please +// DO NOT #INCLUDE IT IN A USER PROGRAM. + +#ifndef GTEST_SRC_GTEST_INTERNAL_INL_H_ +#define GTEST_SRC_GTEST_INTERNAL_INL_H_ + +// GTEST_IMPLEMENTATION_ is defined to 1 iff the current translation unit is +// part of Google Test's implementation; otherwise it's undefined. +#if !GTEST_IMPLEMENTATION_ +// A user is trying to include this from his code - just say no. +#error "gtest-internal-inl.h is part of Google Test's internal implementation." +#error "It must not be included except by Google Test itself." +#endif // GTEST_IMPLEMENTATION_ + +#ifndef _WIN32_WCE +#include +#endif // !_WIN32_WCE +#include +#include // For strtoll/_strtoul64/malloc/free. +#include // For memmove. + +#include +#include +#include + + +#if GTEST_OS_WINDOWS +#include // For DWORD. +#endif // GTEST_OS_WINDOWS + + +namespace testing { + +// Declares the flags. +// +// We don't want the users to modify this flag in the code, but want +// Google Test's own unit tests to be able to access it. Therefore we +// declare it here as opposed to in gtest.h. +GTEST_DECLARE_bool_(death_test_use_fork); + +namespace internal { + +// The value of GetTestTypeId() as seen from within the Google Test +// library. This is solely for testing GetTestTypeId(). +GTEST_API_ extern const TypeId kTestTypeIdInGoogleTest; + +// Names of the flags (needed for parsing Google Test flags). +const char kAlsoRunDisabledTestsFlag[] = "also_run_disabled_tests"; +const char kBreakOnFailureFlag[] = "break_on_failure"; +const char kCatchExceptionsFlag[] = "catch_exceptions"; +const char kColorFlag[] = "color"; +const char kFilterFlag[] = "filter"; +const char kListTestsFlag[] = "list_tests"; +const char kOutputFlag[] = "output"; +const char kPrintTimeFlag[] = "print_time"; +const char kRandomSeedFlag[] = "random_seed"; +const char kRepeatFlag[] = "repeat"; +const char kShuffleFlag[] = "shuffle"; +const char kStackTraceDepthFlag[] = "stack_trace_depth"; +const char kThrowOnFailureFlag[] = "throw_on_failure"; + +// A valid random seed must be in [1, kMaxRandomSeed]. +const int kMaxRandomSeed = 99999; + +// g_help_flag is true iff the --help flag or an equivalent form is +// specified on the command line. +GTEST_API_ extern bool g_help_flag; + +// Returns the current time in milliseconds. +GTEST_API_ TimeInMillis GetTimeInMillis(); + +// Returns true iff Google Test should use colors in the output. +GTEST_API_ bool ShouldUseColor(bool stdout_is_tty); + +// Formats the given time in milliseconds as seconds. +GTEST_API_ std::string FormatTimeInMillisAsSeconds(TimeInMillis ms); + +// Parses a string for an Int32 flag, in the form of "--flag=value". +// +// On success, stores the value of the flag in *value, and returns +// true. On failure, returns false without changing *value. +GTEST_API_ bool ParseInt32Flag( + const char* str, const char* flag, Int32* value); + +// Returns a random seed in range [1, kMaxRandomSeed] based on the +// given --gtest_random_seed flag value. +inline int GetRandomSeedFromFlag(Int32 random_seed_flag) { + const unsigned int raw_seed = (random_seed_flag == 0) ? + static_cast(GetTimeInMillis()) : + static_cast(random_seed_flag); + + // Normalizes the actual seed to range [1, kMaxRandomSeed] such that + // it's easy to type. + const int normalized_seed = + static_cast((raw_seed - 1U) % + static_cast(kMaxRandomSeed)) + 1; + return normalized_seed; +} + +// Returns the first valid random seed after 'seed'. The behavior is +// undefined if 'seed' is invalid. The seed after kMaxRandomSeed is +// considered to be 1. +inline int GetNextRandomSeed(int seed) { + GTEST_CHECK_(1 <= seed && seed <= kMaxRandomSeed) + << "Invalid random seed " << seed << " - must be in [1, " + << kMaxRandomSeed << "]."; + const int next_seed = seed + 1; + return (next_seed > kMaxRandomSeed) ? 1 : next_seed; +} + +// This class saves the values of all Google Test flags in its c'tor, and +// restores them in its d'tor. +class GTestFlagSaver { + public: + // The c'tor. + GTestFlagSaver() { + also_run_disabled_tests_ = GTEST_FLAG(also_run_disabled_tests); + break_on_failure_ = GTEST_FLAG(break_on_failure); + catch_exceptions_ = GTEST_FLAG(catch_exceptions); + color_ = GTEST_FLAG(color); + death_test_style_ = GTEST_FLAG(death_test_style); + death_test_use_fork_ = GTEST_FLAG(death_test_use_fork); + filter_ = GTEST_FLAG(filter); + internal_run_death_test_ = GTEST_FLAG(internal_run_death_test); + list_tests_ = GTEST_FLAG(list_tests); + output_ = GTEST_FLAG(output); + print_time_ = GTEST_FLAG(print_time); + random_seed_ = GTEST_FLAG(random_seed); + repeat_ = GTEST_FLAG(repeat); + shuffle_ = GTEST_FLAG(shuffle); + stack_trace_depth_ = GTEST_FLAG(stack_trace_depth); + throw_on_failure_ = GTEST_FLAG(throw_on_failure); + } + + // The d'tor is not virtual. DO NOT INHERIT FROM THIS CLASS. + ~GTestFlagSaver() { + GTEST_FLAG(also_run_disabled_tests) = also_run_disabled_tests_; + GTEST_FLAG(break_on_failure) = break_on_failure_; + GTEST_FLAG(catch_exceptions) = catch_exceptions_; + GTEST_FLAG(color) = color_; + GTEST_FLAG(death_test_style) = death_test_style_; + GTEST_FLAG(death_test_use_fork) = death_test_use_fork_; + GTEST_FLAG(filter) = filter_; + GTEST_FLAG(internal_run_death_test) = internal_run_death_test_; + GTEST_FLAG(list_tests) = list_tests_; + GTEST_FLAG(output) = output_; + GTEST_FLAG(print_time) = print_time_; + GTEST_FLAG(random_seed) = random_seed_; + GTEST_FLAG(repeat) = repeat_; + GTEST_FLAG(shuffle) = shuffle_; + GTEST_FLAG(stack_trace_depth) = stack_trace_depth_; + GTEST_FLAG(throw_on_failure) = throw_on_failure_; + } + private: + // Fields for saving the original values of flags. + bool also_run_disabled_tests_; + bool break_on_failure_; + bool catch_exceptions_; + String color_; + String death_test_style_; + bool death_test_use_fork_; + String filter_; + String internal_run_death_test_; + bool list_tests_; + String output_; + bool print_time_; + bool pretty_; + internal::Int32 random_seed_; + internal::Int32 repeat_; + bool shuffle_; + internal::Int32 stack_trace_depth_; + bool throw_on_failure_; +} GTEST_ATTRIBUTE_UNUSED_; + +// Converts a Unicode code point to a narrow string in UTF-8 encoding. +// code_point parameter is of type UInt32 because wchar_t may not be +// wide enough to contain a code point. +// The output buffer str must containt at least 32 characters. +// The function returns the address of the output buffer. +// If the code_point is not a valid Unicode code point +// (i.e. outside of Unicode range U+0 to U+10FFFF) it will be output +// as '(Invalid Unicode 0xXXXXXXXX)'. +GTEST_API_ char* CodePointToUtf8(UInt32 code_point, char* str); + +// Converts a wide string to a narrow string in UTF-8 encoding. +// The wide string is assumed to have the following encoding: +// UTF-16 if sizeof(wchar_t) == 2 (on Windows, Cygwin, Symbian OS) +// UTF-32 if sizeof(wchar_t) == 4 (on Linux) +// Parameter str points to a null-terminated wide string. +// Parameter num_chars may additionally limit the number +// of wchar_t characters processed. -1 is used when the entire string +// should be processed. +// If the string contains code points that are not valid Unicode code points +// (i.e. outside of Unicode range U+0 to U+10FFFF) they will be output +// as '(Invalid Unicode 0xXXXXXXXX)'. If the string is in UTF16 encoding +// and contains invalid UTF-16 surrogate pairs, values in those pairs +// will be encoded as individual Unicode characters from Basic Normal Plane. +GTEST_API_ String WideStringToUtf8(const wchar_t* str, int num_chars); + +// Reads the GTEST_SHARD_STATUS_FILE environment variable, and creates the file +// if the variable is present. If a file already exists at this location, this +// function will write over it. If the variable is present, but the file cannot +// be created, prints an error and exits. +void WriteToShardStatusFileIfNeeded(); + +// Checks whether sharding is enabled by examining the relevant +// environment variable values. If the variables are present, +// but inconsistent (e.g., shard_index >= total_shards), prints +// an error and exits. If in_subprocess_for_death_test, sharding is +// disabled because it must only be applied to the original test +// process. Otherwise, we could filter out death tests we intended to execute. +GTEST_API_ bool ShouldShard(const char* total_shards_str, + const char* shard_index_str, + bool in_subprocess_for_death_test); + +// Parses the environment variable var as an Int32. If it is unset, +// returns default_val. If it is not an Int32, prints an error and +// and aborts. +GTEST_API_ Int32 Int32FromEnvOrDie(const char* env_var, Int32 default_val); + +// Given the total number of shards, the shard index, and the test id, +// returns true iff the test should be run on this shard. The test id is +// some arbitrary but unique non-negative integer assigned to each test +// method. Assumes that 0 <= shard_index < total_shards. +GTEST_API_ bool ShouldRunTestOnShard( + int total_shards, int shard_index, int test_id); + +// STL container utilities. + +// Returns the number of elements in the given container that satisfy +// the given predicate. +template +inline int CountIf(const Container& c, Predicate predicate) { + return static_cast(std::count_if(c.begin(), c.end(), predicate)); +} + +// Applies a function/functor to each element in the container. +template +void ForEach(const Container& c, Functor functor) { + std::for_each(c.begin(), c.end(), functor); +} + +// Returns the i-th element of the vector, or default_value if i is not +// in range [0, v.size()). +template +inline E GetElementOr(const std::vector& v, int i, E default_value) { + return (i < 0 || i >= static_cast(v.size())) ? default_value : v[i]; +} + +// Performs an in-place shuffle of a range of the vector's elements. +// 'begin' and 'end' are element indices as an STL-style range; +// i.e. [begin, end) are shuffled, where 'end' == size() means to +// shuffle to the end of the vector. +template +void ShuffleRange(internal::Random* random, int begin, int end, + std::vector* v) { + const int size = static_cast(v->size()); + GTEST_CHECK_(0 <= begin && begin <= size) + << "Invalid shuffle range start " << begin << ": must be in range [0, " + << size << "]."; + GTEST_CHECK_(begin <= end && end <= size) + << "Invalid shuffle range finish " << end << ": must be in range [" + << begin << ", " << size << "]."; + + // Fisher-Yates shuffle, from + // http://en.wikipedia.org/wiki/Fisher-Yates_shuffle + for (int range_width = end - begin; range_width >= 2; range_width--) { + const int last_in_range = begin + range_width - 1; + const int selected = begin + random->Generate(range_width); + std::swap((*v)[selected], (*v)[last_in_range]); + } +} + +// Performs an in-place shuffle of the vector's elements. +template +inline void Shuffle(internal::Random* random, std::vector* v) { + ShuffleRange(random, 0, static_cast(v->size()), v); +} + +// A function for deleting an object. Handy for being used as a +// functor. +template +static void Delete(T* x) { + delete x; +} + +// A predicate that checks the key of a TestProperty against a known key. +// +// TestPropertyKeyIs is copyable. +class TestPropertyKeyIs { + public: + // Constructor. + // + // TestPropertyKeyIs has NO default constructor. + explicit TestPropertyKeyIs(const char* key) + : key_(key) {} + + // Returns true iff the test name of test property matches on key_. + bool operator()(const TestProperty& test_property) const { + return String(test_property.key()).Compare(key_) == 0; + } + + private: + String key_; +}; + +class TestInfoImpl { + public: + TestInfoImpl(TestInfo* parent, const char* test_case_name, + const char* name, const char* test_case_comment, + const char* comment, TypeId fixture_class_id, + internal::TestFactoryBase* factory); + ~TestInfoImpl(); + + // Returns true if this test should run. + bool should_run() const { return should_run_; } + + // Sets the should_run member. + void set_should_run(bool should) { should_run_ = should; } + + // Returns true if this test is disabled. Disabled tests are not run. + bool is_disabled() const { return is_disabled_; } + + // Sets the is_disabled member. + void set_is_disabled(bool is) { is_disabled_ = is; } + + // Returns true if this test matches the filter specified by the user. + bool matches_filter() const { return matches_filter_; } + + // Sets the matches_filter member. + void set_matches_filter(bool matches) { matches_filter_ = matches; } + + // Returns the test case name. + const char* test_case_name() const { return test_case_name_.c_str(); } + + // Returns the test name. + const char* name() const { return name_.c_str(); } + + // Returns the test case comment. + const char* test_case_comment() const { return test_case_comment_.c_str(); } + + // Returns the test comment. + const char* comment() const { return comment_.c_str(); } + + // Returns the ID of the test fixture class. + TypeId fixture_class_id() const { return fixture_class_id_; } + + // Returns the test result. + TestResult* result() { return &result_; } + const TestResult* result() const { return &result_; } + + // Creates the test object, runs it, records its result, and then + // deletes it. + void Run(); + + // Clears the test result. + void ClearResult() { result_.Clear(); } + + // Clears the test result in the given TestInfo object. + static void ClearTestResult(TestInfo * test_info) { + test_info->impl()->ClearResult(); + } + + private: + // These fields are immutable properties of the test. + TestInfo* const parent_; // The owner of this object + const String test_case_name_; // Test case name + const String name_; // Test name + const String test_case_comment_; // Test case comment + const String comment_; // Test comment + const TypeId fixture_class_id_; // ID of the test fixture class + bool should_run_; // True iff this test should run + bool is_disabled_; // True iff this test is disabled + bool matches_filter_; // True if this test matches the + // user-specified filter. + internal::TestFactoryBase* const factory_; // The factory that creates + // the test object + + // This field is mutable and needs to be reset before running the + // test for the second time. + TestResult result_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestInfoImpl); +}; + +// Class UnitTestOptions. +// +// This class contains functions for processing options the user +// specifies when running the tests. It has only static members. +// +// In most cases, the user can specify an option using either an +// environment variable or a command line flag. E.g. you can set the +// test filter using either GTEST_FILTER or --gtest_filter. If both +// the variable and the flag are present, the latter overrides the +// former. +class GTEST_API_ UnitTestOptions { + public: + // Functions for processing the gtest_output flag. + + // Returns the output format, or "" for normal printed output. + static String GetOutputFormat(); + + // Returns the absolute path of the requested output file, or the + // default (test_detail.xml in the original working directory) if + // none was explicitly specified. + static String GetAbsolutePathToOutputFile(); + + // Functions for processing the gtest_filter flag. + + // Returns true iff the wildcard pattern matches the string. The + // first ':' or '\0' character in pattern marks the end of it. + // + // This recursive algorithm isn't very efficient, but is clear and + // works well enough for matching test names, which are short. + static bool PatternMatchesString(const char *pattern, const char *str); + + // Returns true iff the user-specified filter matches the test case + // name and the test name. + static bool FilterMatchesTest(const String &test_case_name, + const String &test_name); + +#if GTEST_OS_WINDOWS + // Function for supporting the gtest_catch_exception flag. + + // Returns EXCEPTION_EXECUTE_HANDLER if Google Test should handle the + // given SEH exception, or EXCEPTION_CONTINUE_SEARCH otherwise. + // This function is useful as an __except condition. + static int GTestShouldProcessSEH(DWORD exception_code); +#endif // GTEST_OS_WINDOWS + + // Returns true if "name" matches the ':' separated list of glob-style + // filters in "filter". + static bool MatchesFilter(const String& name, const char* filter); +}; + +// Returns the current application's name, removing directory path if that +// is present. Used by UnitTestOptions::GetOutputFile. +GTEST_API_ FilePath GetCurrentExecutableName(); + +// The role interface for getting the OS stack trace as a string. +class OsStackTraceGetterInterface { + public: + OsStackTraceGetterInterface() {} + virtual ~OsStackTraceGetterInterface() {} + + // Returns the current OS stack trace as a String. Parameters: + // + // max_depth - the maximum number of stack frames to be included + // in the trace. + // skip_count - the number of top frames to be skipped; doesn't count + // against max_depth. + virtual String CurrentStackTrace(int max_depth, int skip_count) = 0; + + // UponLeavingGTest() should be called immediately before Google Test calls + // user code. It saves some information about the current stack that + // CurrentStackTrace() will use to find and hide Google Test stack frames. + virtual void UponLeavingGTest() = 0; + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(OsStackTraceGetterInterface); +}; + +// A working implementation of the OsStackTraceGetterInterface interface. +class OsStackTraceGetter : public OsStackTraceGetterInterface { + public: + OsStackTraceGetter() : caller_frame_(NULL) {} + virtual String CurrentStackTrace(int max_depth, int skip_count); + virtual void UponLeavingGTest(); + + // This string is inserted in place of stack frames that are part of + // Google Test's implementation. + static const char* const kElidedFramesMarker; + + private: + Mutex mutex_; // protects all internal state + + // We save the stack frame below the frame that calls user code. + // We do this because the address of the frame immediately below + // the user code changes between the call to UponLeavingGTest() + // and any calls to CurrentStackTrace() from within the user code. + void* caller_frame_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(OsStackTraceGetter); +}; + +// Information about a Google Test trace point. +struct TraceInfo { + const char* file; + int line; + String message; +}; + +// This is the default global test part result reporter used in UnitTestImpl. +// This class should only be used by UnitTestImpl. +class DefaultGlobalTestPartResultReporter + : public TestPartResultReporterInterface { + public: + explicit DefaultGlobalTestPartResultReporter(UnitTestImpl* unit_test); + // Implements the TestPartResultReporterInterface. Reports the test part + // result in the current test. + virtual void ReportTestPartResult(const TestPartResult& result); + + private: + UnitTestImpl* const unit_test_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultGlobalTestPartResultReporter); +}; + +// This is the default per thread test part result reporter used in +// UnitTestImpl. This class should only be used by UnitTestImpl. +class DefaultPerThreadTestPartResultReporter + : public TestPartResultReporterInterface { + public: + explicit DefaultPerThreadTestPartResultReporter(UnitTestImpl* unit_test); + // Implements the TestPartResultReporterInterface. The implementation just + // delegates to the current global test part result reporter of *unit_test_. + virtual void ReportTestPartResult(const TestPartResult& result); + + private: + UnitTestImpl* const unit_test_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultPerThreadTestPartResultReporter); +}; + +// The private implementation of the UnitTest class. We don't protect +// the methods under a mutex, as this class is not accessible by a +// user and the UnitTest class that delegates work to this class does +// proper locking. +class GTEST_API_ UnitTestImpl { + public: + explicit UnitTestImpl(UnitTest* parent); + virtual ~UnitTestImpl(); + + // There are two different ways to register your own TestPartResultReporter. + // You can register your own repoter to listen either only for test results + // from the current thread or for results from all threads. + // By default, each per-thread test result repoter just passes a new + // TestPartResult to the global test result reporter, which registers the + // test part result for the currently running test. + + // Returns the global test part result reporter. + TestPartResultReporterInterface* GetGlobalTestPartResultReporter(); + + // Sets the global test part result reporter. + void SetGlobalTestPartResultReporter( + TestPartResultReporterInterface* reporter); + + // Returns the test part result reporter for the current thread. + TestPartResultReporterInterface* GetTestPartResultReporterForCurrentThread(); + + // Sets the test part result reporter for the current thread. + void SetTestPartResultReporterForCurrentThread( + TestPartResultReporterInterface* reporter); + + // Gets the number of successful test cases. + int successful_test_case_count() const; + + // Gets the number of failed test cases. + int failed_test_case_count() const; + + // Gets the number of all test cases. + int total_test_case_count() const; + + // Gets the number of all test cases that contain at least one test + // that should run. + int test_case_to_run_count() const; + + // Gets the number of successful tests. + int successful_test_count() const; + + // Gets the number of failed tests. + int failed_test_count() const; + + // Gets the number of disabled tests. + int disabled_test_count() const; + + // Gets the number of all tests. + int total_test_count() const; + + // Gets the number of tests that should run. + int test_to_run_count() const; + + // Gets the elapsed time, in milliseconds. + TimeInMillis elapsed_time() const { return elapsed_time_; } + + // Returns true iff the unit test passed (i.e. all test cases passed). + bool Passed() const { return !Failed(); } + + // Returns true iff the unit test failed (i.e. some test case failed + // or something outside of all tests failed). + bool Failed() const { + return failed_test_case_count() > 0 || ad_hoc_test_result()->Failed(); + } + + // Gets the i-th test case among all the test cases. i can range from 0 to + // total_test_case_count() - 1. If i is not in that range, returns NULL. + const TestCase* GetTestCase(int i) const { + const int index = GetElementOr(test_case_indices_, i, -1); + return index < 0 ? NULL : test_cases_[i]; + } + + // Gets the i-th test case among all the test cases. i can range from 0 to + // total_test_case_count() - 1. If i is not in that range, returns NULL. + TestCase* GetMutableTestCase(int i) { + const int index = GetElementOr(test_case_indices_, i, -1); + return index < 0 ? NULL : test_cases_[index]; + } + + // Provides access to the event listener list. + TestEventListeners* listeners() { return &listeners_; } + + // Returns the TestResult for the test that's currently running, or + // the TestResult for the ad hoc test if no test is running. + TestResult* current_test_result(); + + // Returns the TestResult for the ad hoc test. + const TestResult* ad_hoc_test_result() const { return &ad_hoc_test_result_; } + + // Sets the OS stack trace getter. + // + // Does nothing if the input and the current OS stack trace getter + // are the same; otherwise, deletes the old getter and makes the + // input the current getter. + void set_os_stack_trace_getter(OsStackTraceGetterInterface* getter); + + // Returns the current OS stack trace getter if it is not NULL; + // otherwise, creates an OsStackTraceGetter, makes it the current + // getter, and returns it. + OsStackTraceGetterInterface* os_stack_trace_getter(); + + // Returns the current OS stack trace as a String. + // + // The maximum number of stack frames to be included is specified by + // the gtest_stack_trace_depth flag. The skip_count parameter + // specifies the number of top frames to be skipped, which doesn't + // count against the number of frames to be included. + // + // For example, if Foo() calls Bar(), which in turn calls + // CurrentOsStackTraceExceptTop(1), Foo() will be included in the + // trace but Bar() and CurrentOsStackTraceExceptTop() won't. + String CurrentOsStackTraceExceptTop(int skip_count); + + // Finds and returns a TestCase with the given name. If one doesn't + // exist, creates one and returns it. + // + // Arguments: + // + // test_case_name: name of the test case + // set_up_tc: pointer to the function that sets up the test case + // tear_down_tc: pointer to the function that tears down the test case + TestCase* GetTestCase(const char* test_case_name, + const char* comment, + Test::SetUpTestCaseFunc set_up_tc, + Test::TearDownTestCaseFunc tear_down_tc); + + // Adds a TestInfo to the unit test. + // + // Arguments: + // + // set_up_tc: pointer to the function that sets up the test case + // tear_down_tc: pointer to the function that tears down the test case + // test_info: the TestInfo object + void AddTestInfo(Test::SetUpTestCaseFunc set_up_tc, + Test::TearDownTestCaseFunc tear_down_tc, + TestInfo * test_info) { + // In order to support thread-safe death tests, we need to + // remember the original working directory when the test program + // was first invoked. We cannot do this in RUN_ALL_TESTS(), as + // the user may have changed the current directory before calling + // RUN_ALL_TESTS(). Therefore we capture the current directory in + // AddTestInfo(), which is called to register a TEST or TEST_F + // before main() is reached. + if (original_working_dir_.IsEmpty()) { + original_working_dir_.Set(FilePath::GetCurrentDir()); + GTEST_CHECK_(!original_working_dir_.IsEmpty()) + << "Failed to get the current working directory."; + } + + GetTestCase(test_info->test_case_name(), + test_info->test_case_comment(), + set_up_tc, + tear_down_tc)->AddTestInfo(test_info); + } + +#if GTEST_HAS_PARAM_TEST + // Returns ParameterizedTestCaseRegistry object used to keep track of + // value-parameterized tests and instantiate and register them. + internal::ParameterizedTestCaseRegistry& parameterized_test_registry() { + return parameterized_test_registry_; + } +#endif // GTEST_HAS_PARAM_TEST + + // Sets the TestCase object for the test that's currently running. + void set_current_test_case(TestCase* a_current_test_case) { + current_test_case_ = a_current_test_case; + } + + // Sets the TestInfo object for the test that's currently running. If + // current_test_info is NULL, the assertion results will be stored in + // ad_hoc_test_result_. + void set_current_test_info(TestInfo* a_current_test_info) { + current_test_info_ = a_current_test_info; + } + + // Registers all parameterized tests defined using TEST_P and + // INSTANTIATE_TEST_P, creating regular tests for each test/parameter + // combination. This method can be called more then once; it has + // guards protecting from registering the tests more then once. + // If value-parameterized tests are disabled, RegisterParameterizedTests + // is present but does nothing. + void RegisterParameterizedTests(); + + // Runs all tests in this UnitTest object, prints the result, and + // returns 0 if all tests are successful, or 1 otherwise. If any + // exception is thrown during a test on Windows, this test is + // considered to be failed, but the rest of the tests will still be + // run. (We disable exceptions on Linux and Mac OS X, so the issue + // doesn't apply there.) + int RunAllTests(); + + // Clears the results of all tests, including the ad hoc test. + void ClearResult() { + ForEach(test_cases_, TestCase::ClearTestCaseResult); + ad_hoc_test_result_.Clear(); + } + + enum ReactionToSharding { + HONOR_SHARDING_PROTOCOL, + IGNORE_SHARDING_PROTOCOL + }; + + // Matches the full name of each test against the user-specified + // filter to decide whether the test should run, then records the + // result in each TestCase and TestInfo object. + // If shard_tests == HONOR_SHARDING_PROTOCOL, further filters tests + // based on sharding variables in the environment. + // Returns the number of tests that should run. + int FilterTests(ReactionToSharding shard_tests); + + // Prints the names of the tests matching the user-specified filter flag. + void ListTestsMatchingFilter(); + + const TestCase* current_test_case() const { return current_test_case_; } + TestInfo* current_test_info() { return current_test_info_; } + const TestInfo* current_test_info() const { return current_test_info_; } + + // Returns the vector of environments that need to be set-up/torn-down + // before/after the tests are run. + std::vector& environments() { return environments_; } + + // Getters for the per-thread Google Test trace stack. + std::vector& gtest_trace_stack() { + return *(gtest_trace_stack_.pointer()); + } + const std::vector& gtest_trace_stack() const { + return gtest_trace_stack_.get(); + } + +#if GTEST_HAS_DEATH_TEST + void InitDeathTestSubprocessControlInfo() { + internal_run_death_test_flag_.reset(ParseInternalRunDeathTestFlag()); + } + // Returns a pointer to the parsed --gtest_internal_run_death_test + // flag, or NULL if that flag was not specified. + // This information is useful only in a death test child process. + // Must not be called before a call to InitGoogleTest. + const InternalRunDeathTestFlag* internal_run_death_test_flag() const { + return internal_run_death_test_flag_.get(); + } + + // Returns a pointer to the current death test factory. + internal::DeathTestFactory* death_test_factory() { + return death_test_factory_.get(); + } + + void SuppressTestEventsIfInSubprocess(); + + friend class ReplaceDeathTestFactory; +#endif // GTEST_HAS_DEATH_TEST + + // Initializes the event listener performing XML output as specified by + // UnitTestOptions. Must not be called before InitGoogleTest. + void ConfigureXmlOutput(); + + // Performs initialization dependent upon flag values obtained in + // ParseGoogleTestFlagsOnly. Is called from InitGoogleTest after the call to + // ParseGoogleTestFlagsOnly. In case a user neglects to call InitGoogleTest + // this function is also called from RunAllTests. Since this function can be + // called more than once, it has to be idempotent. + void PostFlagParsingInit(); + + // Gets the random seed used at the start of the current test iteration. + int random_seed() const { return random_seed_; } + + // Gets the random number generator. + internal::Random* random() { return &random_; } + + // Shuffles all test cases, and the tests within each test case, + // making sure that death tests are still run first. + void ShuffleTests(); + + // Restores the test cases and tests to their order before the first shuffle. + void UnshuffleTests(); + + private: + friend class ::testing::UnitTest; + + // The UnitTest object that owns this implementation object. + UnitTest* const parent_; + + // The working directory when the first TEST() or TEST_F() was + // executed. + internal::FilePath original_working_dir_; + + // The default test part result reporters. + DefaultGlobalTestPartResultReporter default_global_test_part_result_reporter_; + DefaultPerThreadTestPartResultReporter + default_per_thread_test_part_result_reporter_; + + // Points to (but doesn't own) the global test part result reporter. + TestPartResultReporterInterface* global_test_part_result_repoter_; + + // Protects read and write access to global_test_part_result_reporter_. + internal::Mutex global_test_part_result_reporter_mutex_; + + // Points to (but doesn't own) the per-thread test part result reporter. + internal::ThreadLocal + per_thread_test_part_result_reporter_; + + // The vector of environments that need to be set-up/torn-down + // before/after the tests are run. + std::vector environments_; + + // The vector of TestCases in their original order. It owns the + // elements in the vector. + std::vector test_cases_; + + // Provides a level of indirection for the test case list to allow + // easy shuffling and restoring the test case order. The i-th + // element of this vector is the index of the i-th test case in the + // shuffled order. + std::vector test_case_indices_; + +#if GTEST_HAS_PARAM_TEST + // ParameterizedTestRegistry object used to register value-parameterized + // tests. + internal::ParameterizedTestCaseRegistry parameterized_test_registry_; + + // Indicates whether RegisterParameterizedTests() has been called already. + bool parameterized_tests_registered_; +#endif // GTEST_HAS_PARAM_TEST + + // Index of the last death test case registered. Initially -1. + int last_death_test_case_; + + // This points to the TestCase for the currently running test. It + // changes as Google Test goes through one test case after another. + // When no test is running, this is set to NULL and Google Test + // stores assertion results in ad_hoc_test_result_. Initially NULL. + TestCase* current_test_case_; + + // This points to the TestInfo for the currently running test. It + // changes as Google Test goes through one test after another. When + // no test is running, this is set to NULL and Google Test stores + // assertion results in ad_hoc_test_result_. Initially NULL. + TestInfo* current_test_info_; + + // Normally, a user only writes assertions inside a TEST or TEST_F, + // or inside a function called by a TEST or TEST_F. Since Google + // Test keeps track of which test is current running, it can + // associate such an assertion with the test it belongs to. + // + // If an assertion is encountered when no TEST or TEST_F is running, + // Google Test attributes the assertion result to an imaginary "ad hoc" + // test, and records the result in ad_hoc_test_result_. + TestResult ad_hoc_test_result_; + + // The list of event listeners that can be used to track events inside + // Google Test. + TestEventListeners listeners_; + + // The OS stack trace getter. Will be deleted when the UnitTest + // object is destructed. By default, an OsStackTraceGetter is used, + // but the user can set this field to use a custom getter if that is + // desired. + OsStackTraceGetterInterface* os_stack_trace_getter_; + + // True iff PostFlagParsingInit() has been called. + bool post_flag_parse_init_performed_; + + // The random number seed used at the beginning of the test run. + int random_seed_; + + // Our random number generator. + internal::Random random_; + + // How long the test took to run, in milliseconds. + TimeInMillis elapsed_time_; + +#if GTEST_HAS_DEATH_TEST + // The decomposed components of the gtest_internal_run_death_test flag, + // parsed when RUN_ALL_TESTS is called. + internal::scoped_ptr internal_run_death_test_flag_; + internal::scoped_ptr death_test_factory_; +#endif // GTEST_HAS_DEATH_TEST + + // A per-thread stack of traces created by the SCOPED_TRACE() macro. + internal::ThreadLocal > gtest_trace_stack_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(UnitTestImpl); +}; // class UnitTestImpl + +// Convenience function for accessing the global UnitTest +// implementation object. +inline UnitTestImpl* GetUnitTestImpl() { + return UnitTest::GetInstance()->impl(); +} + +// Internal helper functions for implementing the simple regular +// expression matcher. +GTEST_API_ bool IsInSet(char ch, const char* str); +GTEST_API_ bool IsDigit(char ch); +GTEST_API_ bool IsPunct(char ch); +GTEST_API_ bool IsRepeat(char ch); +GTEST_API_ bool IsWhiteSpace(char ch); +GTEST_API_ bool IsWordChar(char ch); +GTEST_API_ bool IsValidEscape(char ch); +GTEST_API_ bool AtomMatchesChar(bool escaped, char pattern, char ch); +GTEST_API_ bool ValidateRegex(const char* regex); +GTEST_API_ bool MatchRegexAtHead(const char* regex, const char* str); +GTEST_API_ bool MatchRepetitionAndRegexAtHead( + bool escaped, char ch, char repeat, const char* regex, const char* str); +GTEST_API_ bool MatchRegexAnywhere(const char* regex, const char* str); + +// Parses the command line for Google Test flags, without initializing +// other parts of Google Test. +GTEST_API_ void ParseGoogleTestFlagsOnly(int* argc, char** argv); +GTEST_API_ void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv); + +#if GTEST_HAS_DEATH_TEST + +// Returns the message describing the last system error, regardless of the +// platform. +String GetLastErrnoDescription(); + +#if GTEST_OS_WINDOWS +// Provides leak-safe Windows kernel handle ownership. +class AutoHandle { + public: + AutoHandle() : handle_(INVALID_HANDLE_VALUE) {} + explicit AutoHandle(HANDLE handle) : handle_(handle) {} + + ~AutoHandle() { Reset(); } + + HANDLE Get() const { return handle_; } + void Reset() { Reset(INVALID_HANDLE_VALUE); } + void Reset(HANDLE handle) { + if (handle != handle_) { + if (handle_ != INVALID_HANDLE_VALUE) + ::CloseHandle(handle_); + handle_ = handle; + } + } + + private: + HANDLE handle_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(AutoHandle); +}; +#endif // GTEST_OS_WINDOWS + +// Attempts to parse a string into a positive integer pointed to by the +// number parameter. Returns true if that is possible. +// GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we can use +// it here. +template +bool ParseNaturalNumber(const ::std::string& str, Integer* number) { + // Fail fast if the given string does not begin with a digit; + // this bypasses strtoXXX's "optional leading whitespace and plus + // or minus sign" semantics, which are undesirable here. + if (str.empty() || !isdigit(str[0])) { + return false; + } + errno = 0; + + char* end; + // BiggestConvertible is the largest integer type that system-provided + // string-to-number conversion routines can return. +#if GTEST_OS_WINDOWS && !defined(__GNUC__) + // MSVC and C++ Builder define __int64 instead of the standard long long. + typedef unsigned __int64 BiggestConvertible; + const BiggestConvertible parsed = _strtoui64(str.c_str(), &end, 10); +#else + typedef unsigned long long BiggestConvertible; // NOLINT + const BiggestConvertible parsed = strtoull(str.c_str(), &end, 10); +#endif // GTEST_OS_WINDOWS && !defined(__GNUC__) + const bool parse_success = *end == '\0' && errno == 0; + + // TODO(vladl@google.com): Convert this to compile time assertion when it is + // available. + GTEST_CHECK_(sizeof(Integer) <= sizeof(parsed)); + + const Integer result = static_cast(parsed); + if (parse_success && static_cast(result) == parsed) { + *number = result; + return true; + } + return false; +} +#endif // GTEST_HAS_DEATH_TEST + +// TestResult contains some private methods that should be hidden from +// Google Test user but are required for testing. This class allow our tests +// to access them. +// +// This class is supplied only for the purpose of testing Google Test's own +// constructs. Do not use it in user tests, either directly or indirectly. +class TestResultAccessor { + public: + static void RecordProperty(TestResult* test_result, + const TestProperty& property) { + test_result->RecordProperty(property); + } + + static void ClearTestPartResults(TestResult* test_result) { + test_result->ClearTestPartResults(); + } + + static const std::vector& test_part_results( + const TestResult& test_result) { + return test_result.test_part_results(); + } +}; + +} // namespace internal +} // namespace testing + +#endif // GTEST_SRC_GTEST_INTERNAL_INL_H_ +#undef GTEST_IMPLEMENTATION_ + +#if GTEST_OS_WINDOWS +#define vsnprintf _vsnprintf +#endif // GTEST_OS_WINDOWS + +namespace testing { + +using internal::CountIf; +using internal::ForEach; +using internal::GetElementOr; +using internal::Shuffle; + +// Constants. + +// A test whose test case name or test name matches this filter is +// disabled and not run. +static const char kDisableTestFilter[] = "DISABLED_*:*/DISABLED_*"; + +// A test case whose name matches this filter is considered a death +// test case and will be run before test cases whose name doesn't +// match this filter. +static const char kDeathTestCaseFilter[] = "*DeathTest:*DeathTest/*"; + +// A test filter that matches everything. +static const char kUniversalFilter[] = "*"; + +// The default output file for XML output. +static const char kDefaultOutputFile[] = "test_detail.xml"; + +// The environment variable name for the test shard index. +static const char kTestShardIndex[] = "GTEST_SHARD_INDEX"; +// The environment variable name for the total number of test shards. +static const char kTestTotalShards[] = "GTEST_TOTAL_SHARDS"; +// The environment variable name for the test shard status file. +static const char kTestShardStatusFile[] = "GTEST_SHARD_STATUS_FILE"; + +namespace internal { + +// The text used in failure messages to indicate the start of the +// stack trace. +const char kStackTraceMarker[] = "\nStack trace:\n"; + +// g_help_flag is true iff the --help flag or an equivalent form is +// specified on the command line. +bool g_help_flag = false; + +} // namespace internal + +GTEST_DEFINE_bool_( + also_run_disabled_tests, + internal::BoolFromGTestEnv("also_run_disabled_tests", false), + "Run disabled tests too, in addition to the tests normally being run."); + +GTEST_DEFINE_bool_( + break_on_failure, + internal::BoolFromGTestEnv("break_on_failure", false), + "True iff a failed assertion should be a debugger break-point."); + +GTEST_DEFINE_bool_( + catch_exceptions, + internal::BoolFromGTestEnv("catch_exceptions", false), + "True iff " GTEST_NAME_ + " should catch exceptions and treat them as test failures."); + +GTEST_DEFINE_string_( + color, + internal::StringFromGTestEnv("color", "auto"), + "Whether to use colors in the output. Valid values: yes, no, " + "and auto. 'auto' means to use colors if the output is " + "being sent to a terminal and the TERM environment variable " + "is set to xterm, xterm-color, xterm-256color, linux or cygwin."); + +GTEST_DEFINE_string_( + filter, + internal::StringFromGTestEnv("filter", kUniversalFilter), + "A colon-separated list of glob (not regex) patterns " + "for filtering the tests to run, optionally followed by a " + "'-' and a : separated list of negative patterns (tests to " + "exclude). A test is run if it matches one of the positive " + "patterns and does not match any of the negative patterns."); + +GTEST_DEFINE_bool_(list_tests, false, + "List all tests without running them."); + +GTEST_DEFINE_string_( + output, + internal::StringFromGTestEnv("output", ""), + "A format (currently must be \"xml\"), optionally followed " + "by a colon and an output file name or directory. A directory " + "is indicated by a trailing pathname separator. " + "Examples: \"xml:filename.xml\", \"xml::directoryname/\". " + "If a directory is specified, output files will be created " + "within that directory, with file-names based on the test " + "executable's name and, if necessary, made unique by adding " + "digits."); + +GTEST_DEFINE_bool_( + print_time, + internal::BoolFromGTestEnv("print_time", true), + "True iff " GTEST_NAME_ + " should display elapsed time in text output."); + +GTEST_DEFINE_int32_( + random_seed, + internal::Int32FromGTestEnv("random_seed", 0), + "Random number seed to use when shuffling test orders. Must be in range " + "[1, 99999], or 0 to use a seed based on the current time."); + +GTEST_DEFINE_int32_( + repeat, + internal::Int32FromGTestEnv("repeat", 1), + "How many times to repeat each test. Specify a negative number " + "for repeating forever. Useful for shaking out flaky tests."); + +GTEST_DEFINE_bool_( + show_internal_stack_frames, false, + "True iff " GTEST_NAME_ " should include internal stack frames when " + "printing test failure stack traces."); + +GTEST_DEFINE_bool_( + shuffle, + internal::BoolFromGTestEnv("shuffle", false), + "True iff " GTEST_NAME_ + " should randomize tests' order on every run."); + +GTEST_DEFINE_int32_( + stack_trace_depth, + internal::Int32FromGTestEnv("stack_trace_depth", kMaxStackTraceDepth), + "The maximum number of stack frames to print when an " + "assertion fails. The valid range is 0 through 100, inclusive."); + +GTEST_DEFINE_bool_( + throw_on_failure, + internal::BoolFromGTestEnv("throw_on_failure", false), + "When this flag is specified, a failed assertion will throw an exception " + "if exceptions are enabled or exit the program with a non-zero code " + "otherwise."); + +namespace internal { + +// Generates a random number from [0, range), using a Linear +// Congruential Generator (LCG). Crashes if 'range' is 0 or greater +// than kMaxRange. +UInt32 Random::Generate(UInt32 range) { + // These constants are the same as are used in glibc's rand(3). + state_ = (1103515245U*state_ + 12345U) % kMaxRange; + + GTEST_CHECK_(range > 0) + << "Cannot generate a number in the range [0, 0)."; + GTEST_CHECK_(range <= kMaxRange) + << "Generation of a number in [0, " << range << ") was requested, " + << "but this can only generate numbers in [0, " << kMaxRange << ")."; + + // Converting via modulus introduces a bit of downward bias, but + // it's simple, and a linear congruential generator isn't too good + // to begin with. + return state_ % range; +} + +// GTestIsInitialized() returns true iff the user has initialized +// Google Test. Useful for catching the user mistake of not initializing +// Google Test before calling RUN_ALL_TESTS(). +// +// A user must call testing::InitGoogleTest() to initialize Google +// Test. g_init_gtest_count is set to the number of times +// InitGoogleTest() has been called. We don't protect this variable +// under a mutex as it is only accessed in the main thread. +int g_init_gtest_count = 0; +static bool GTestIsInitialized() { return g_init_gtest_count != 0; } + +// Iterates over a vector of TestCases, keeping a running sum of the +// results of calling a given int-returning method on each. +// Returns the sum. +static int SumOverTestCaseList(const std::vector& case_list, + int (TestCase::*method)() const) { + int sum = 0; + for (size_t i = 0; i < case_list.size(); i++) { + sum += (case_list[i]->*method)(); + } + return sum; +} + +// Returns true iff the test case passed. +static bool TestCasePassed(const TestCase* test_case) { + return test_case->should_run() && test_case->Passed(); +} + +// Returns true iff the test case failed. +static bool TestCaseFailed(const TestCase* test_case) { + return test_case->should_run() && test_case->Failed(); +} + +// Returns true iff test_case contains at least one test that should +// run. +static bool ShouldRunTestCase(const TestCase* test_case) { + return test_case->should_run(); +} + +// AssertHelper constructor. +AssertHelper::AssertHelper(TestPartResult::Type type, + const char* file, + int line, + const char* message) + : data_(new AssertHelperData(type, file, line, message)) { +} + +AssertHelper::~AssertHelper() { + delete data_; +} + +// Message assignment, for assertion streaming support. +void AssertHelper::operator=(const Message& message) const { + UnitTest::GetInstance()-> + AddTestPartResult(data_->type, data_->file, data_->line, + AppendUserMessage(data_->message, message), + UnitTest::GetInstance()->impl() + ->CurrentOsStackTraceExceptTop(1) + // Skips the stack frame for this function itself. + ); // NOLINT +} + +// Mutex for linked pointers. +GTEST_DEFINE_STATIC_MUTEX_(g_linked_ptr_mutex); + +// Application pathname gotten in InitGoogleTest. +String g_executable_path; + +// Returns the current application's name, removing directory path if that +// is present. +FilePath GetCurrentExecutableName() { + FilePath result; + +#if GTEST_OS_WINDOWS + result.Set(FilePath(g_executable_path).RemoveExtension("exe")); +#else + result.Set(FilePath(g_executable_path)); +#endif // GTEST_OS_WINDOWS + + return result.RemoveDirectoryName(); +} + +// Functions for processing the gtest_output flag. + +// Returns the output format, or "" for normal printed output. +String UnitTestOptions::GetOutputFormat() { + const char* const gtest_output_flag = GTEST_FLAG(output).c_str(); + if (gtest_output_flag == NULL) return String(""); + + const char* const colon = strchr(gtest_output_flag, ':'); + return (colon == NULL) ? + String(gtest_output_flag) : + String(gtest_output_flag, colon - gtest_output_flag); +} + +// Returns the name of the requested output file, or the default if none +// was explicitly specified. +String UnitTestOptions::GetAbsolutePathToOutputFile() { + const char* const gtest_output_flag = GTEST_FLAG(output).c_str(); + if (gtest_output_flag == NULL) + return String(""); + + const char* const colon = strchr(gtest_output_flag, ':'); + if (colon == NULL) + return String(internal::FilePath::ConcatPaths( + internal::FilePath( + UnitTest::GetInstance()->original_working_dir()), + internal::FilePath(kDefaultOutputFile)).ToString() ); + + internal::FilePath output_name(colon + 1); + if (!output_name.IsAbsolutePath()) + // TODO(wan@google.com): on Windows \some\path is not an absolute + // path (as its meaning depends on the current drive), yet the + // following logic for turning it into an absolute path is wrong. + // Fix it. + output_name = internal::FilePath::ConcatPaths( + internal::FilePath(UnitTest::GetInstance()->original_working_dir()), + internal::FilePath(colon + 1)); + + if (!output_name.IsDirectory()) + return output_name.ToString(); + + internal::FilePath result(internal::FilePath::GenerateUniqueFileName( + output_name, internal::GetCurrentExecutableName(), + GetOutputFormat().c_str())); + return result.ToString(); +} + +// Returns true iff the wildcard pattern matches the string. The +// first ':' or '\0' character in pattern marks the end of it. +// +// This recursive algorithm isn't very efficient, but is clear and +// works well enough for matching test names, which are short. +bool UnitTestOptions::PatternMatchesString(const char *pattern, + const char *str) { + switch (*pattern) { + case '\0': + case ':': // Either ':' or '\0' marks the end of the pattern. + return *str == '\0'; + case '?': // Matches any single character. + return *str != '\0' && PatternMatchesString(pattern + 1, str + 1); + case '*': // Matches any string (possibly empty) of characters. + return (*str != '\0' && PatternMatchesString(pattern, str + 1)) || + PatternMatchesString(pattern + 1, str); + default: // Non-special character. Matches itself. + return *pattern == *str && + PatternMatchesString(pattern + 1, str + 1); + } +} + +bool UnitTestOptions::MatchesFilter(const String& name, const char* filter) { + const char *cur_pattern = filter; + for (;;) { + if (PatternMatchesString(cur_pattern, name.c_str())) { + return true; + } + + // Finds the next pattern in the filter. + cur_pattern = strchr(cur_pattern, ':'); + + // Returns if no more pattern can be found. + if (cur_pattern == NULL) { + return false; + } + + // Skips the pattern separater (the ':' character). + cur_pattern++; + } +} + +// TODO(keithray): move String function implementations to gtest-string.cc. + +// Returns true iff the user-specified filter matches the test case +// name and the test name. +bool UnitTestOptions::FilterMatchesTest(const String &test_case_name, + const String &test_name) { + const String& full_name = String::Format("%s.%s", + test_case_name.c_str(), + test_name.c_str()); + + // Split --gtest_filter at '-', if there is one, to separate into + // positive filter and negative filter portions + const char* const p = GTEST_FLAG(filter).c_str(); + const char* const dash = strchr(p, '-'); + String positive; + String negative; + if (dash == NULL) { + positive = GTEST_FLAG(filter).c_str(); // Whole string is a positive filter + negative = String(""); + } else { + positive = String(p, dash - p); // Everything up to the dash + negative = String(dash+1); // Everything after the dash + if (positive.empty()) { + // Treat '-test1' as the same as '*-test1' + positive = kUniversalFilter; + } + } + + // A filter is a colon-separated list of patterns. It matches a + // test if any pattern in it matches the test. + return (MatchesFilter(full_name, positive.c_str()) && + !MatchesFilter(full_name, negative.c_str())); +} + +#if GTEST_OS_WINDOWS +// Returns EXCEPTION_EXECUTE_HANDLER if Google Test should handle the +// given SEH exception, or EXCEPTION_CONTINUE_SEARCH otherwise. +// This function is useful as an __except condition. +int UnitTestOptions::GTestShouldProcessSEH(DWORD exception_code) { + // Google Test should handle an exception if: + // 1. the user wants it to, AND + // 2. this is not a breakpoint exception. + return (GTEST_FLAG(catch_exceptions) && + exception_code != EXCEPTION_BREAKPOINT) ? + EXCEPTION_EXECUTE_HANDLER : + EXCEPTION_CONTINUE_SEARCH; +} +#endif // GTEST_OS_WINDOWS + +} // namespace internal + +// The c'tor sets this object as the test part result reporter used by +// Google Test. The 'result' parameter specifies where to report the +// results. Intercepts only failures from the current thread. +ScopedFakeTestPartResultReporter::ScopedFakeTestPartResultReporter( + TestPartResultArray* result) + : intercept_mode_(INTERCEPT_ONLY_CURRENT_THREAD), + result_(result) { + Init(); +} + +// The c'tor sets this object as the test part result reporter used by +// Google Test. The 'result' parameter specifies where to report the +// results. +ScopedFakeTestPartResultReporter::ScopedFakeTestPartResultReporter( + InterceptMode intercept_mode, TestPartResultArray* result) + : intercept_mode_(intercept_mode), + result_(result) { + Init(); +} + +void ScopedFakeTestPartResultReporter::Init() { + internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); + if (intercept_mode_ == INTERCEPT_ALL_THREADS) { + old_reporter_ = impl->GetGlobalTestPartResultReporter(); + impl->SetGlobalTestPartResultReporter(this); + } else { + old_reporter_ = impl->GetTestPartResultReporterForCurrentThread(); + impl->SetTestPartResultReporterForCurrentThread(this); + } +} + +// The d'tor restores the test part result reporter used by Google Test +// before. +ScopedFakeTestPartResultReporter::~ScopedFakeTestPartResultReporter() { + internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); + if (intercept_mode_ == INTERCEPT_ALL_THREADS) { + impl->SetGlobalTestPartResultReporter(old_reporter_); + } else { + impl->SetTestPartResultReporterForCurrentThread(old_reporter_); + } +} + +// Increments the test part result count and remembers the result. +// This method is from the TestPartResultReporterInterface interface. +void ScopedFakeTestPartResultReporter::ReportTestPartResult( + const TestPartResult& result) { + result_->Append(result); +} + +namespace internal { + +// Returns the type ID of ::testing::Test. We should always call this +// instead of GetTypeId< ::testing::Test>() to get the type ID of +// testing::Test. This is to work around a suspected linker bug when +// using Google Test as a framework on Mac OS X. The bug causes +// GetTypeId< ::testing::Test>() to return different values depending +// on whether the call is from the Google Test framework itself or +// from user test code. GetTestTypeId() is guaranteed to always +// return the same value, as it always calls GetTypeId<>() from the +// gtest.cc, which is within the Google Test framework. +TypeId GetTestTypeId() { + return GetTypeId(); +} + +// The value of GetTestTypeId() as seen from within the Google Test +// library. This is solely for testing GetTestTypeId(). +extern const TypeId kTestTypeIdInGoogleTest = GetTestTypeId(); + +// This predicate-formatter checks that 'results' contains a test part +// failure of the given type and that the failure message contains the +// given substring. +AssertionResult HasOneFailure(const char* /* results_expr */, + const char* /* type_expr */, + const char* /* substr_expr */, + const TestPartResultArray& results, + TestPartResult::Type type, + const char* substr) { + const String expected(type == TestPartResult::kFatalFailure ? + "1 fatal failure" : + "1 non-fatal failure"); + Message msg; + if (results.size() != 1) { + msg << "Expected: " << expected << "\n" + << " Actual: " << results.size() << " failures"; + for (int i = 0; i < results.size(); i++) { + msg << "\n" << results.GetTestPartResult(i); + } + return AssertionFailure(msg); + } + + const TestPartResult& r = results.GetTestPartResult(0); + if (r.type() != type) { + msg << "Expected: " << expected << "\n" + << " Actual:\n" + << r; + return AssertionFailure(msg); + } + + if (strstr(r.message(), substr) == NULL) { + msg << "Expected: " << expected << " containing \"" + << substr << "\"\n" + << " Actual:\n" + << r; + return AssertionFailure(msg); + } + + return AssertionSuccess(); +} + +// The constructor of SingleFailureChecker remembers where to look up +// test part results, what type of failure we expect, and what +// substring the failure message should contain. +SingleFailureChecker:: SingleFailureChecker( + const TestPartResultArray* results, + TestPartResult::Type type, + const char* substr) + : results_(results), + type_(type), + substr_(substr) {} + +// The destructor of SingleFailureChecker verifies that the given +// TestPartResultArray contains exactly one failure that has the given +// type and contains the given substring. If that's not the case, a +// non-fatal failure will be generated. +SingleFailureChecker::~SingleFailureChecker() { + EXPECT_PRED_FORMAT3(HasOneFailure, *results_, type_, substr_.c_str()); +} + +DefaultGlobalTestPartResultReporter::DefaultGlobalTestPartResultReporter( + UnitTestImpl* unit_test) : unit_test_(unit_test) {} + +void DefaultGlobalTestPartResultReporter::ReportTestPartResult( + const TestPartResult& result) { + unit_test_->current_test_result()->AddTestPartResult(result); + unit_test_->listeners()->repeater()->OnTestPartResult(result); +} + +DefaultPerThreadTestPartResultReporter::DefaultPerThreadTestPartResultReporter( + UnitTestImpl* unit_test) : unit_test_(unit_test) {} + +void DefaultPerThreadTestPartResultReporter::ReportTestPartResult( + const TestPartResult& result) { + unit_test_->GetGlobalTestPartResultReporter()->ReportTestPartResult(result); +} + +// Returns the global test part result reporter. +TestPartResultReporterInterface* +UnitTestImpl::GetGlobalTestPartResultReporter() { + internal::MutexLock lock(&global_test_part_result_reporter_mutex_); + return global_test_part_result_repoter_; +} + +// Sets the global test part result reporter. +void UnitTestImpl::SetGlobalTestPartResultReporter( + TestPartResultReporterInterface* reporter) { + internal::MutexLock lock(&global_test_part_result_reporter_mutex_); + global_test_part_result_repoter_ = reporter; +} + +// Returns the test part result reporter for the current thread. +TestPartResultReporterInterface* +UnitTestImpl::GetTestPartResultReporterForCurrentThread() { + return per_thread_test_part_result_reporter_.get(); +} + +// Sets the test part result reporter for the current thread. +void UnitTestImpl::SetTestPartResultReporterForCurrentThread( + TestPartResultReporterInterface* reporter) { + per_thread_test_part_result_reporter_.set(reporter); +} + +// Gets the number of successful test cases. +int UnitTestImpl::successful_test_case_count() const { + return CountIf(test_cases_, TestCasePassed); +} + +// Gets the number of failed test cases. +int UnitTestImpl::failed_test_case_count() const { + return CountIf(test_cases_, TestCaseFailed); +} + +// Gets the number of all test cases. +int UnitTestImpl::total_test_case_count() const { + return static_cast(test_cases_.size()); +} + +// Gets the number of all test cases that contain at least one test +// that should run. +int UnitTestImpl::test_case_to_run_count() const { + return CountIf(test_cases_, ShouldRunTestCase); +} + +// Gets the number of successful tests. +int UnitTestImpl::successful_test_count() const { + return SumOverTestCaseList(test_cases_, &TestCase::successful_test_count); +} + +// Gets the number of failed tests. +int UnitTestImpl::failed_test_count() const { + return SumOverTestCaseList(test_cases_, &TestCase::failed_test_count); +} + +// Gets the number of disabled tests. +int UnitTestImpl::disabled_test_count() const { + return SumOverTestCaseList(test_cases_, &TestCase::disabled_test_count); +} + +// Gets the number of all tests. +int UnitTestImpl::total_test_count() const { + return SumOverTestCaseList(test_cases_, &TestCase::total_test_count); +} + +// Gets the number of tests that should run. +int UnitTestImpl::test_to_run_count() const { + return SumOverTestCaseList(test_cases_, &TestCase::test_to_run_count); +} + +// Returns the current OS stack trace as a String. +// +// The maximum number of stack frames to be included is specified by +// the gtest_stack_trace_depth flag. The skip_count parameter +// specifies the number of top frames to be skipped, which doesn't +// count against the number of frames to be included. +// +// For example, if Foo() calls Bar(), which in turn calls +// CurrentOsStackTraceExceptTop(1), Foo() will be included in the +// trace but Bar() and CurrentOsStackTraceExceptTop() won't. +String UnitTestImpl::CurrentOsStackTraceExceptTop(int skip_count) { + (void)skip_count; + return String(""); +} + +// Returns the current time in milliseconds. +TimeInMillis GetTimeInMillis() { +#if GTEST_OS_WINDOWS_MOBILE || defined(__BORLANDC__) + // Difference between 1970-01-01 and 1601-01-01 in milliseconds. + // http://analogous.blogspot.com/2005/04/epoch.html + const TimeInMillis kJavaEpochToWinFileTimeDelta = + static_cast(116444736UL) * 100000UL; + const DWORD kTenthMicrosInMilliSecond = 10000; + + SYSTEMTIME now_systime; + FILETIME now_filetime; + ULARGE_INTEGER now_int64; + // TODO(kenton@google.com): Shouldn't this just use + // GetSystemTimeAsFileTime()? + GetSystemTime(&now_systime); + if (SystemTimeToFileTime(&now_systime, &now_filetime)) { + now_int64.LowPart = now_filetime.dwLowDateTime; + now_int64.HighPart = now_filetime.dwHighDateTime; + now_int64.QuadPart = (now_int64.QuadPart / kTenthMicrosInMilliSecond) - + kJavaEpochToWinFileTimeDelta; + return now_int64.QuadPart; + } + return 0; +#elif GTEST_OS_WINDOWS && !GTEST_HAS_GETTIMEOFDAY_ + __timeb64 now; +#ifdef _MSC_VER + // MSVC 8 deprecates _ftime64(), so we want to suppress warning 4996 + // (deprecated function) there. + // TODO(kenton@google.com): Use GetTickCount()? Or use + // SystemTimeToFileTime() +#pragma warning(push) // Saves the current warning state. +#pragma warning(disable:4996) // Temporarily disables warning 4996. + _ftime64(&now); +#pragma warning(pop) // Restores the warning state. +#else + _ftime64(&now); +#endif // _MSC_VER + return static_cast(now.time) * 1000 + now.millitm; +#elif GTEST_HAS_GETTIMEOFDAY_ + struct timeval now; + gettimeofday(&now, NULL); + return static_cast(now.tv_sec) * 1000 + now.tv_usec / 1000; +#else +#error "Don't know how to get the current time on your system." +#endif +} + +// Utilities + +// class String + +// Returns the input enclosed in double quotes if it's not NULL; +// otherwise returns "(null)". For example, "\"Hello\"" is returned +// for input "Hello". +// +// This is useful for printing a C string in the syntax of a literal. +// +// Known issue: escape sequences are not handled yet. +String String::ShowCStringQuoted(const char* c_str) { + return c_str ? String::Format("\"%s\"", c_str) : String("(null)"); +} + +// Copies at most length characters from str into a newly-allocated +// piece of memory of size length+1. The memory is allocated with new[]. +// A terminating null byte is written to the memory, and a pointer to it +// is returned. If str is NULL, NULL is returned. +static char* CloneString(const char* str, size_t length) { + if (str == NULL) { + return NULL; + } else { + char* const clone = new char[length + 1]; + posix::StrNCpy(clone, str, length); + clone[length] = '\0'; + return clone; + } +} + +// Clones a 0-terminated C string, allocating memory using new. The +// caller is responsible for deleting[] the return value. Returns the +// cloned string, or NULL if the input is NULL. +const char * String::CloneCString(const char* c_str) { + return (c_str == NULL) ? + NULL : CloneString(c_str, strlen(c_str)); +} + +#if GTEST_OS_WINDOWS_MOBILE +// Creates a UTF-16 wide string from the given ANSI string, allocating +// memory using new. The caller is responsible for deleting the return +// value using delete[]. Returns the wide string, or NULL if the +// input is NULL. +LPCWSTR String::AnsiToUtf16(const char* ansi) { + if (!ansi) return NULL; + const int length = strlen(ansi); + const int unicode_length = + MultiByteToWideChar(CP_ACP, 0, ansi, length, + NULL, 0); + WCHAR* unicode = new WCHAR[unicode_length + 1]; + MultiByteToWideChar(CP_ACP, 0, ansi, length, + unicode, unicode_length); + unicode[unicode_length] = 0; + return unicode; +} + +// Creates an ANSI string from the given wide string, allocating +// memory using new. The caller is responsible for deleting the return +// value using delete[]. Returns the ANSI string, or NULL if the +// input is NULL. +const char* String::Utf16ToAnsi(LPCWSTR utf16_str) { + if (!utf16_str) return NULL; + const int ansi_length = + WideCharToMultiByte(CP_ACP, 0, utf16_str, -1, + NULL, 0, NULL, NULL); + char* ansi = new char[ansi_length + 1]; + WideCharToMultiByte(CP_ACP, 0, utf16_str, -1, + ansi, ansi_length, NULL, NULL); + ansi[ansi_length] = 0; + return ansi; +} + +#endif // GTEST_OS_WINDOWS_MOBILE + +// Compares two C strings. Returns true iff they have the same content. +// +// Unlike strcmp(), this function can handle NULL argument(s). A NULL +// C string is considered different to any non-NULL C string, +// including the empty string. +bool String::CStringEquals(const char * lhs, const char * rhs) { + if ( lhs == NULL ) return rhs == NULL; + + if ( rhs == NULL ) return false; + + return strcmp(lhs, rhs) == 0; +} + +#if GTEST_HAS_STD_WSTRING || GTEST_HAS_GLOBAL_WSTRING + +// Converts an array of wide chars to a narrow string using the UTF-8 +// encoding, and streams the result to the given Message object. +static void StreamWideCharsToMessage(const wchar_t* wstr, size_t length, + Message* msg) { + // TODO(wan): consider allowing a testing::String object to + // contain '\0'. This will make it behave more like std::string, + // and will allow ToUtf8String() to return the correct encoding + // for '\0' s.t. we can get rid of the conditional here (and in + // several other places). + for (size_t i = 0; i != length; ) { // NOLINT + if (wstr[i] != L'\0') { + *msg << WideStringToUtf8(wstr + i, static_cast(length - i)); + while (i != length && wstr[i] != L'\0') + i++; + } else { + *msg << '\0'; + i++; + } + } +} + +#endif // GTEST_HAS_STD_WSTRING || GTEST_HAS_GLOBAL_WSTRING + +} // namespace internal + +#if GTEST_HAS_STD_WSTRING +// Converts the given wide string to a narrow string using the UTF-8 +// encoding, and streams the result to this Message object. +Message& Message::operator <<(const ::std::wstring& wstr) { + internal::StreamWideCharsToMessage(wstr.c_str(), wstr.length(), this); + return *this; +} +#endif // GTEST_HAS_STD_WSTRING + +#if GTEST_HAS_GLOBAL_WSTRING +// Converts the given wide string to a narrow string using the UTF-8 +// encoding, and streams the result to this Message object. +Message& Message::operator <<(const ::wstring& wstr) { + internal::StreamWideCharsToMessage(wstr.c_str(), wstr.length(), this); + return *this; +} +#endif // GTEST_HAS_GLOBAL_WSTRING + +namespace internal { + +// Formats a value to be used in a failure message. + +// For a char value, we print it as a C++ char literal and as an +// unsigned integer (both in decimal and in hexadecimal). +String FormatForFailureMessage(char ch) { + const unsigned int ch_as_uint = ch; + // A String object cannot contain '\0', so we print "\\0" when ch is + // '\0'. + return String::Format("'%s' (%u, 0x%X)", + ch ? String::Format("%c", ch).c_str() : "\\0", + ch_as_uint, ch_as_uint); +} + +// For a wchar_t value, we print it as a C++ wchar_t literal and as an +// unsigned integer (both in decimal and in hexidecimal). +String FormatForFailureMessage(wchar_t wchar) { + // The C++ standard doesn't specify the exact size of the wchar_t + // type. It just says that it shall have the same size as another + // integral type, called its underlying type. + // + // Therefore, in order to print a wchar_t value in the numeric form, + // we first convert it to the largest integral type (UInt64) and + // then print the converted value. + // + // We use streaming to print the value as "%llu" doesn't work + // correctly with MSVC 7.1. + const UInt64 wchar_as_uint64 = wchar; + Message msg; + // A String object cannot contain '\0', so we print "\\0" when wchar is + // L'\0'. + char buffer[32]; // CodePointToUtf8 requires a buffer that big. + msg << "L'" + << (wchar ? CodePointToUtf8(static_cast(wchar), buffer) : "\\0") + << "' (" << wchar_as_uint64 << ", 0x" << ::std::setbase(16) + << wchar_as_uint64 << ")"; + return msg.GetString(); +} + +} // namespace internal + +// AssertionResult constructors. +// Used in EXPECT_TRUE/FALSE(assertion_result). +AssertionResult::AssertionResult(const AssertionResult& other) + : success_(other.success_), + message_(other.message_.get() != NULL ? + new internal::String(*other.message_) : + static_cast(NULL)) { +} + +// Returns the assertion's negation. Used with EXPECT/ASSERT_FALSE. +AssertionResult AssertionResult::operator!() const { + AssertionResult negation(!success_); + if (message_.get() != NULL) + negation << *message_; + return negation; +} + +// Makes a successful assertion result. +AssertionResult AssertionSuccess() { + return AssertionResult(true); +} + +// Makes a failed assertion result. +AssertionResult AssertionFailure() { + return AssertionResult(false); +} + +// Makes a failed assertion result with the given failure message. +// Deprecated; use AssertionFailure() << message. +AssertionResult AssertionFailure(const Message& message) { + return AssertionFailure() << message; +} + +namespace internal { + +// Constructs and returns the message for an equality assertion +// (e.g. ASSERT_EQ, EXPECT_STREQ, etc) failure. +// +// The first four parameters are the expressions used in the assertion +// and their values, as strings. For example, for ASSERT_EQ(foo, bar) +// where foo is 5 and bar is 6, we have: +// +// expected_expression: "foo" +// actual_expression: "bar" +// expected_value: "5" +// actual_value: "6" +// +// The ignoring_case parameter is true iff the assertion is a +// *_STRCASEEQ*. When it's true, the string " (ignoring case)" will +// be inserted into the message. +AssertionResult EqFailure(const char* expected_expression, + const char* actual_expression, + const String& expected_value, + const String& actual_value, + bool ignoring_case) { + Message msg; + msg << "Value of: " << actual_expression; + if (actual_value != actual_expression) { + msg << "\n Actual: " << actual_value; + } + + msg << "\nExpected: " << expected_expression; + if (ignoring_case) { + msg << " (ignoring case)"; + } + if (expected_value != expected_expression) { + msg << "\nWhich is: " << expected_value; + } + + return AssertionFailure(msg); +} + +// Constructs a failure message for Boolean assertions such as EXPECT_TRUE. +String GetBoolAssertionFailureMessage(const AssertionResult& assertion_result, + const char* expression_text, + const char* actual_predicate_value, + const char* expected_predicate_value) { + const char* actual_message = assertion_result.message(); + Message msg; + msg << "Value of: " << expression_text + << "\n Actual: " << actual_predicate_value; + if (actual_message[0] != '\0') + msg << " (" << actual_message << ")"; + msg << "\nExpected: " << expected_predicate_value; + return msg.GetString(); +} + +// Helper function for implementing ASSERT_NEAR. +AssertionResult DoubleNearPredFormat(const char* expr1, + const char* expr2, + const char* abs_error_expr, + double val1, + double val2, + double abs_error) { + const double diff = fabs(val1 - val2); + if (diff <= abs_error) return AssertionSuccess(); + + // TODO(wan): do not print the value of an expression if it's + // already a literal. + Message msg; + msg << "The difference between " << expr1 << " and " << expr2 + << " is " << diff << ", which exceeds " << abs_error_expr << ", where\n" + << expr1 << " evaluates to " << val1 << ",\n" + << expr2 << " evaluates to " << val2 << ", and\n" + << abs_error_expr << " evaluates to " << abs_error << "."; + return AssertionFailure(msg); +} + + +// Helper template for implementing FloatLE() and DoubleLE(). +template +AssertionResult FloatingPointLE(const char* expr1, + const char* expr2, + RawType val1, + RawType val2) { + // Returns success if val1 is less than val2, + if (val1 < val2) { + return AssertionSuccess(); + } + + // or if val1 is almost equal to val2. + const FloatingPoint lhs(val1), rhs(val2); + if (lhs.AlmostEquals(rhs)) { + return AssertionSuccess(); + } + + // Note that the above two checks will both fail if either val1 or + // val2 is NaN, as the IEEE floating-point standard requires that + // any predicate involving a NaN must return false. + + StrStream val1_ss; + val1_ss << std::setprecision(std::numeric_limits::digits10 + 2) + << val1; + + StrStream val2_ss; + val2_ss << std::setprecision(std::numeric_limits::digits10 + 2) + << val2; + + Message msg; + msg << "Expected: (" << expr1 << ") <= (" << expr2 << ")\n" + << " Actual: " << StrStreamToString(&val1_ss) << " vs " + << StrStreamToString(&val2_ss); + + return AssertionFailure(msg); +} + +} // namespace internal + +// Asserts that val1 is less than, or almost equal to, val2. Fails +// otherwise. In particular, it fails if either val1 or val2 is NaN. +AssertionResult FloatLE(const char* expr1, const char* expr2, + float val1, float val2) { + return internal::FloatingPointLE(expr1, expr2, val1, val2); +} + +// Asserts that val1 is less than, or almost equal to, val2. Fails +// otherwise. In particular, it fails if either val1 or val2 is NaN. +AssertionResult DoubleLE(const char* expr1, const char* expr2, + double val1, double val2) { + return internal::FloatingPointLE(expr1, expr2, val1, val2); +} + +namespace internal { + +// The helper function for {ASSERT|EXPECT}_EQ with int or enum +// arguments. +AssertionResult CmpHelperEQ(const char* expected_expression, + const char* actual_expression, + BiggestInt expected, + BiggestInt actual) { + if (expected == actual) { + return AssertionSuccess(); + } + + return EqFailure(expected_expression, + actual_expression, + FormatForComparisonFailureMessage(expected, actual), + FormatForComparisonFailureMessage(actual, expected), + false); +} + +// A macro for implementing the helper functions needed to implement +// ASSERT_?? and EXPECT_?? with integer or enum arguments. It is here +// just to avoid copy-and-paste of similar code. +#define GTEST_IMPL_CMP_HELPER_(op_name, op)\ +AssertionResult CmpHelper##op_name(const char* expr1, const char* expr2, \ + BiggestInt val1, BiggestInt val2) {\ + if (val1 op val2) {\ + return AssertionSuccess();\ + } else {\ + Message msg;\ + msg << "Expected: (" << expr1 << ") " #op " (" << expr2\ + << "), actual: " << FormatForComparisonFailureMessage(val1, val2)\ + << " vs " << FormatForComparisonFailureMessage(val2, val1);\ + return AssertionFailure(msg);\ + }\ +} + +// Implements the helper function for {ASSERT|EXPECT}_NE with int or +// enum arguments. +GTEST_IMPL_CMP_HELPER_(NE, !=) +// Implements the helper function for {ASSERT|EXPECT}_LE with int or +// enum arguments. +GTEST_IMPL_CMP_HELPER_(LE, <=) +// Implements the helper function for {ASSERT|EXPECT}_LT with int or +// enum arguments. +GTEST_IMPL_CMP_HELPER_(LT, < ) +// Implements the helper function for {ASSERT|EXPECT}_GE with int or +// enum arguments. +GTEST_IMPL_CMP_HELPER_(GE, >=) +// Implements the helper function for {ASSERT|EXPECT}_GT with int or +// enum arguments. +GTEST_IMPL_CMP_HELPER_(GT, > ) + +#undef GTEST_IMPL_CMP_HELPER_ + +// The helper function for {ASSERT|EXPECT}_STREQ. +AssertionResult CmpHelperSTREQ(const char* expected_expression, + const char* actual_expression, + const char* expected, + const char* actual) { + if (String::CStringEquals(expected, actual)) { + return AssertionSuccess(); + } + + return EqFailure(expected_expression, + actual_expression, + String::ShowCStringQuoted(expected), + String::ShowCStringQuoted(actual), + false); +} + +// The helper function for {ASSERT|EXPECT}_STRCASEEQ. +AssertionResult CmpHelperSTRCASEEQ(const char* expected_expression, + const char* actual_expression, + const char* expected, + const char* actual) { + if (String::CaseInsensitiveCStringEquals(expected, actual)) { + return AssertionSuccess(); + } + + return EqFailure(expected_expression, + actual_expression, + String::ShowCStringQuoted(expected), + String::ShowCStringQuoted(actual), + true); +} + +// The helper function for {ASSERT|EXPECT}_STRNE. +AssertionResult CmpHelperSTRNE(const char* s1_expression, + const char* s2_expression, + const char* s1, + const char* s2) { + if (!String::CStringEquals(s1, s2)) { + return AssertionSuccess(); + } else { + Message msg; + msg << "Expected: (" << s1_expression << ") != (" + << s2_expression << "), actual: \"" + << s1 << "\" vs \"" << s2 << "\""; + return AssertionFailure(msg); + } +} + +// The helper function for {ASSERT|EXPECT}_STRCASENE. +AssertionResult CmpHelperSTRCASENE(const char* s1_expression, + const char* s2_expression, + const char* s1, + const char* s2) { + if (!String::CaseInsensitiveCStringEquals(s1, s2)) { + return AssertionSuccess(); + } else { + Message msg; + msg << "Expected: (" << s1_expression << ") != (" + << s2_expression << ") (ignoring case), actual: \"" + << s1 << "\" vs \"" << s2 << "\""; + return AssertionFailure(msg); + } +} + +} // namespace internal + +namespace { + +// Helper functions for implementing IsSubString() and IsNotSubstring(). + +// This group of overloaded functions return true iff needle is a +// substring of haystack. NULL is considered a substring of itself +// only. + +bool IsSubstringPred(const char* needle, const char* haystack) { + if (needle == NULL || haystack == NULL) + return needle == haystack; + + return strstr(haystack, needle) != NULL; +} + +bool IsSubstringPred(const wchar_t* needle, const wchar_t* haystack) { + if (needle == NULL || haystack == NULL) + return needle == haystack; + + return wcsstr(haystack, needle) != NULL; +} + +// StringType here can be either ::std::string or ::std::wstring. +template +bool IsSubstringPred(const StringType& needle, + const StringType& haystack) { + return haystack.find(needle) != StringType::npos; +} + +// This function implements either IsSubstring() or IsNotSubstring(), +// depending on the value of the expected_to_be_substring parameter. +// StringType here can be const char*, const wchar_t*, ::std::string, +// or ::std::wstring. +template +AssertionResult IsSubstringImpl( + bool expected_to_be_substring, + const char* needle_expr, const char* haystack_expr, + const StringType& needle, const StringType& haystack) { + if (IsSubstringPred(needle, haystack) == expected_to_be_substring) + return AssertionSuccess(); + + const bool is_wide_string = sizeof(needle[0]) > 1; + const char* const begin_string_quote = is_wide_string ? "L\"" : "\""; + return AssertionFailure( + Message() + << "Value of: " << needle_expr << "\n" + << " Actual: " << begin_string_quote << needle << "\"\n" + << "Expected: " << (expected_to_be_substring ? "" : "not ") + << "a substring of " << haystack_expr << "\n" + << "Which is: " << begin_string_quote << haystack << "\""); +} + +} // namespace + +// IsSubstring() and IsNotSubstring() check whether needle is a +// substring of haystack (NULL is considered a substring of itself +// only), and return an appropriate error message when they fail. + +AssertionResult IsSubstring( + const char* needle_expr, const char* haystack_expr, + const char* needle, const char* haystack) { + return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); +} + +AssertionResult IsSubstring( + const char* needle_expr, const char* haystack_expr, + const wchar_t* needle, const wchar_t* haystack) { + return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); +} + +AssertionResult IsNotSubstring( + const char* needle_expr, const char* haystack_expr, + const char* needle, const char* haystack) { + return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); +} + +AssertionResult IsNotSubstring( + const char* needle_expr, const char* haystack_expr, + const wchar_t* needle, const wchar_t* haystack) { + return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); +} + +AssertionResult IsSubstring( + const char* needle_expr, const char* haystack_expr, + const ::std::string& needle, const ::std::string& haystack) { + return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); +} + +AssertionResult IsNotSubstring( + const char* needle_expr, const char* haystack_expr, + const ::std::string& needle, const ::std::string& haystack) { + return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); +} + +#if GTEST_HAS_STD_WSTRING +AssertionResult IsSubstring( + const char* needle_expr, const char* haystack_expr, + const ::std::wstring& needle, const ::std::wstring& haystack) { + return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); +} + +AssertionResult IsNotSubstring( + const char* needle_expr, const char* haystack_expr, + const ::std::wstring& needle, const ::std::wstring& haystack) { + return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); +} +#endif // GTEST_HAS_STD_WSTRING + +namespace internal { + +#if GTEST_OS_WINDOWS + +namespace { + +// Helper function for IsHRESULT{SuccessFailure} predicates +AssertionResult HRESULTFailureHelper(const char* expr, + const char* expected, + long hr) { // NOLINT +#if GTEST_OS_WINDOWS_MOBILE + // Windows CE doesn't support FormatMessage. + const char error_text[] = ""; +#else + // Looks up the human-readable system message for the HRESULT code + // and since we're not passing any params to FormatMessage, we don't + // want inserts expanded. + const DWORD kFlags = FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS; + const DWORD kBufSize = 4096; // String::Format can't exceed this length. + // Gets the system's human readable message string for this HRESULT. + char error_text[kBufSize] = { '\0' }; + DWORD message_length = ::FormatMessageA(kFlags, + 0, // no source, we're asking system + hr, // the error + 0, // no line width restrictions + error_text, // output buffer + kBufSize, // buf size + NULL); // no arguments for inserts + // Trims tailing white space (FormatMessage leaves a trailing cr-lf) + for (; message_length && isspace(error_text[message_length - 1]); + --message_length) { + error_text[message_length - 1] = '\0'; + } +#endif // GTEST_OS_WINDOWS_MOBILE + + const String error_hex(String::Format("0x%08X ", hr)); + Message msg; + msg << "Expected: " << expr << " " << expected << ".\n" + << " Actual: " << error_hex << error_text << "\n"; + + return ::testing::AssertionFailure(msg); +} + +} // namespace + +AssertionResult IsHRESULTSuccess(const char* expr, long hr) { // NOLINT + if (SUCCEEDED(hr)) { + return AssertionSuccess(); + } + return HRESULTFailureHelper(expr, "succeeds", hr); +} + +AssertionResult IsHRESULTFailure(const char* expr, long hr) { // NOLINT + if (FAILED(hr)) { + return AssertionSuccess(); + } + return HRESULTFailureHelper(expr, "fails", hr); +} + +#endif // GTEST_OS_WINDOWS + +// Utility functions for encoding Unicode text (wide strings) in +// UTF-8. + +// A Unicode code-point can have upto 21 bits, and is encoded in UTF-8 +// like this: +// +// Code-point length Encoding +// 0 - 7 bits 0xxxxxxx +// 8 - 11 bits 110xxxxx 10xxxxxx +// 12 - 16 bits 1110xxxx 10xxxxxx 10xxxxxx +// 17 - 21 bits 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx + +// The maximum code-point a one-byte UTF-8 sequence can represent. +const UInt32 kMaxCodePoint1 = (static_cast(1) << 7) - 1; + +// The maximum code-point a two-byte UTF-8 sequence can represent. +const UInt32 kMaxCodePoint2 = (static_cast(1) << (5 + 6)) - 1; + +// The maximum code-point a three-byte UTF-8 sequence can represent. +const UInt32 kMaxCodePoint3 = (static_cast(1) << (4 + 2*6)) - 1; + +// The maximum code-point a four-byte UTF-8 sequence can represent. +const UInt32 kMaxCodePoint4 = (static_cast(1) << (3 + 3*6)) - 1; + +// Chops off the n lowest bits from a bit pattern. Returns the n +// lowest bits. As a side effect, the original bit pattern will be +// shifted to the right by n bits. +inline UInt32 ChopLowBits(UInt32* bits, int n) { + const UInt32 low_bits = *bits & ((static_cast(1) << n) - 1); + *bits >>= n; + return low_bits; +} + +// Converts a Unicode code point to a narrow string in UTF-8 encoding. +// code_point parameter is of type UInt32 because wchar_t may not be +// wide enough to contain a code point. +// The output buffer str must containt at least 32 characters. +// The function returns the address of the output buffer. +// If the code_point is not a valid Unicode code point +// (i.e. outside of Unicode range U+0 to U+10FFFF) it will be output +// as '(Invalid Unicode 0xXXXXXXXX)'. +char* CodePointToUtf8(UInt32 code_point, char* str) { + if (code_point <= kMaxCodePoint1) { + str[1] = '\0'; + str[0] = static_cast(code_point); // 0xxxxxxx + } else if (code_point <= kMaxCodePoint2) { + str[2] = '\0'; + str[1] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx + str[0] = static_cast(0xC0 | code_point); // 110xxxxx + } else if (code_point <= kMaxCodePoint3) { + str[3] = '\0'; + str[2] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx + str[1] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx + str[0] = static_cast(0xE0 | code_point); // 1110xxxx + } else if (code_point <= kMaxCodePoint4) { + str[4] = '\0'; + str[3] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx + str[2] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx + str[1] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx + str[0] = static_cast(0xF0 | code_point); // 11110xxx + } else { + // The longest string String::Format can produce when invoked + // with these parameters is 28 character long (not including + // the terminating nul character). We are asking for 32 character + // buffer just in case. This is also enough for strncpy to + // null-terminate the destination string. + posix::StrNCpy( + str, String::Format("(Invalid Unicode 0x%X)", code_point).c_str(), 32); + str[31] = '\0'; // Makes sure no change in the format to strncpy leaves + // the result unterminated. + } + return str; +} + +// The following two functions only make sense if the the system +// uses UTF-16 for wide string encoding. All supported systems +// with 16 bit wchar_t (Windows, Cygwin, Symbian OS) do use UTF-16. + +// Determines if the arguments constitute UTF-16 surrogate pair +// and thus should be combined into a single Unicode code point +// using CreateCodePointFromUtf16SurrogatePair. +inline bool IsUtf16SurrogatePair(wchar_t first, wchar_t second) { + return sizeof(wchar_t) == 2 && + (first & 0xFC00) == 0xD800 && (second & 0xFC00) == 0xDC00; +} + +// Creates a Unicode code point from UTF16 surrogate pair. +inline UInt32 CreateCodePointFromUtf16SurrogatePair(wchar_t first, + wchar_t second) { + const UInt32 mask = (1 << 10) - 1; + return (sizeof(wchar_t) == 2) ? + (((first & mask) << 10) | (second & mask)) + 0x10000 : + // This function should not be called when the condition is + // false, but we provide a sensible default in case it is. + static_cast(first); +} + +// Converts a wide string to a narrow string in UTF-8 encoding. +// The wide string is assumed to have the following encoding: +// UTF-16 if sizeof(wchar_t) == 2 (on Windows, Cygwin, Symbian OS) +// UTF-32 if sizeof(wchar_t) == 4 (on Linux) +// Parameter str points to a null-terminated wide string. +// Parameter num_chars may additionally limit the number +// of wchar_t characters processed. -1 is used when the entire string +// should be processed. +// If the string contains code points that are not valid Unicode code points +// (i.e. outside of Unicode range U+0 to U+10FFFF) they will be output +// as '(Invalid Unicode 0xXXXXXXXX)'. If the string is in UTF16 encoding +// and contains invalid UTF-16 surrogate pairs, values in those pairs +// will be encoded as individual Unicode characters from Basic Normal Plane. +String WideStringToUtf8(const wchar_t* str, int num_chars) { + if (num_chars == -1) + num_chars = static_cast(wcslen(str)); + + StrStream stream; + for (int i = 0; i < num_chars; ++i) { + UInt32 unicode_code_point; + + if (str[i] == L'\0') { + break; + } else if (i + 1 < num_chars && IsUtf16SurrogatePair(str[i], str[i + 1])) { + unicode_code_point = CreateCodePointFromUtf16SurrogatePair(str[i], + str[i + 1]); + i++; + } else { + unicode_code_point = static_cast(str[i]); + } + + char buffer[32]; // CodePointToUtf8 requires a buffer this big. + stream << CodePointToUtf8(unicode_code_point, buffer); + } + return StrStreamToString(&stream); +} + +// Converts a wide C string to a String using the UTF-8 encoding. +// NULL will be converted to "(null)". +String String::ShowWideCString(const wchar_t * wide_c_str) { + if (wide_c_str == NULL) return String("(null)"); + + return String(internal::WideStringToUtf8(wide_c_str, -1).c_str()); +} + +// Similar to ShowWideCString(), except that this function encloses +// the converted string in double quotes. +String String::ShowWideCStringQuoted(const wchar_t* wide_c_str) { + if (wide_c_str == NULL) return String("(null)"); + + return String::Format("L\"%s\"", + String::ShowWideCString(wide_c_str).c_str()); +} + +// Compares two wide C strings. Returns true iff they have the same +// content. +// +// Unlike wcscmp(), this function can handle NULL argument(s). A NULL +// C string is considered different to any non-NULL C string, +// including the empty string. +bool String::WideCStringEquals(const wchar_t * lhs, const wchar_t * rhs) { + if (lhs == NULL) return rhs == NULL; + + if (rhs == NULL) return false; + + return wcscmp(lhs, rhs) == 0; +} + +// Helper function for *_STREQ on wide strings. +AssertionResult CmpHelperSTREQ(const char* expected_expression, + const char* actual_expression, + const wchar_t* expected, + const wchar_t* actual) { + if (String::WideCStringEquals(expected, actual)) { + return AssertionSuccess(); + } + + return EqFailure(expected_expression, + actual_expression, + String::ShowWideCStringQuoted(expected), + String::ShowWideCStringQuoted(actual), + false); +} + +// Helper function for *_STRNE on wide strings. +AssertionResult CmpHelperSTRNE(const char* s1_expression, + const char* s2_expression, + const wchar_t* s1, + const wchar_t* s2) { + if (!String::WideCStringEquals(s1, s2)) { + return AssertionSuccess(); + } + + Message msg; + msg << "Expected: (" << s1_expression << ") != (" + << s2_expression << "), actual: " + << String::ShowWideCStringQuoted(s1) + << " vs " << String::ShowWideCStringQuoted(s2); + return AssertionFailure(msg); +} + +// Compares two C strings, ignoring case. Returns true iff they have +// the same content. +// +// Unlike strcasecmp(), this function can handle NULL argument(s). A +// NULL C string is considered different to any non-NULL C string, +// including the empty string. +bool String::CaseInsensitiveCStringEquals(const char * lhs, const char * rhs) { + if (lhs == NULL) + return rhs == NULL; + if (rhs == NULL) + return false; + return posix::StrCaseCmp(lhs, rhs) == 0; +} + + // Compares two wide C strings, ignoring case. Returns true iff they + // have the same content. + // + // Unlike wcscasecmp(), this function can handle NULL argument(s). + // A NULL C string is considered different to any non-NULL wide C string, + // including the empty string. + // NB: The implementations on different platforms slightly differ. + // On windows, this method uses _wcsicmp which compares according to LC_CTYPE + // environment variable. On GNU platform this method uses wcscasecmp + // which compares according to LC_CTYPE category of the current locale. + // On MacOS X, it uses towlower, which also uses LC_CTYPE category of the + // current locale. +bool String::CaseInsensitiveWideCStringEquals(const wchar_t* lhs, + const wchar_t* rhs) { + if ( lhs == NULL ) return rhs == NULL; + + if ( rhs == NULL ) return false; + +#if GTEST_OS_WINDOWS + return _wcsicmp(lhs, rhs) == 0; +#elif GTEST_OS_LINUX + return wcscasecmp(lhs, rhs) == 0; +#else + // Mac OS X and Cygwin don't define wcscasecmp. Other unknown OSes + // may not define it either. + wint_t left, right; + do { + left = towlower(*lhs++); + right = towlower(*rhs++); + } while (left && left == right); + return left == right; +#endif // OS selector +} + +// Compares this with another String. +// Returns < 0 if this is less than rhs, 0 if this is equal to rhs, or > 0 +// if this is greater than rhs. +int String::Compare(const String & rhs) const { + const char* const lhs_c_str = c_str(); + const char* const rhs_c_str = rhs.c_str(); + + if (lhs_c_str == NULL) { + return rhs_c_str == NULL ? 0 : -1; // NULL < anything except NULL + } else if (rhs_c_str == NULL) { + return 1; + } + + const size_t shorter_str_len = + length() <= rhs.length() ? length() : rhs.length(); + for (size_t i = 0; i != shorter_str_len; i++) { + if (lhs_c_str[i] < rhs_c_str[i]) { + return -1; + } else if (lhs_c_str[i] > rhs_c_str[i]) { + return 1; + } + } + return (length() < rhs.length()) ? -1 : + (length() > rhs.length()) ? 1 : 0; +} + +// Returns true iff this String ends with the given suffix. *Any* +// String is considered to end with a NULL or empty suffix. +bool String::EndsWith(const char* suffix) const { + if (suffix == NULL || CStringEquals(suffix, "")) return true; + + if (c_str() == NULL) return false; + + const size_t this_len = strlen(c_str()); + const size_t suffix_len = strlen(suffix); + return (this_len >= suffix_len) && + CStringEquals(c_str() + this_len - suffix_len, suffix); +} + +// Returns true iff this String ends with the given suffix, ignoring case. +// Any String is considered to end with a NULL or empty suffix. +bool String::EndsWithCaseInsensitive(const char* suffix) const { + if (suffix == NULL || CStringEquals(suffix, "")) return true; + + if (c_str() == NULL) return false; + + const size_t this_len = strlen(c_str()); + const size_t suffix_len = strlen(suffix); + return (this_len >= suffix_len) && + CaseInsensitiveCStringEquals(c_str() + this_len - suffix_len, suffix); +} + +// Formats a list of arguments to a String, using the same format +// spec string as for printf. +// +// We do not use the StringPrintf class as it is not universally +// available. +// +// The result is limited to 4096 characters (including the tailing 0). +// If 4096 characters are not enough to format the input, or if +// there's an error, "" is +// returned. +String String::Format(const char * format, ...) { + va_list args; + va_start(args, format); + + char buffer[4096]; + const int kBufferSize = sizeof(buffer)/sizeof(buffer[0]); + + // MSVC 8 deprecates vsnprintf(), so we want to suppress warning + // 4996 (deprecated function) there. +#ifdef _MSC_VER // We are using MSVC. +#pragma warning(push) // Saves the current warning state. +#pragma warning(disable:4996) // Temporarily disables warning 4996. + const int size = vsnprintf(buffer, kBufferSize, format, args); +#pragma warning(pop) // Restores the warning state. +#else // We are not using MSVC. + const int size = vsnprintf(buffer, kBufferSize, format, args); +#endif // _MSC_VER + va_end(args); + + // vsnprintf()'s behavior is not portable. When the buffer is not + // big enough, it returns a negative value in MSVC, and returns the + // needed buffer size on Linux. When there is an output error, it + // always returns a negative value. For simplicity, we lump the two + // error cases together. + if (size < 0 || size >= kBufferSize) { + return String(""); + } else { + return String(buffer, size); + } +} + +// Converts the buffer in a StrStream to a String, converting NUL +// bytes to "\\0" along the way. +String StrStreamToString(StrStream* ss) { + const ::std::string& str = ss->str(); + const char* const start = str.c_str(); + const char* const end = start + str.length(); + + // We need to use a helper StrStream to do this transformation + // because String doesn't support push_back(). + StrStream helper; + for (const char* ch = start; ch != end; ++ch) { + if (*ch == '\0') { + helper << "\\0"; // Replaces NUL with "\\0"; + } else { + helper.put(*ch); + } + } + + return String(helper.str().c_str()); +} + +// Appends the user-supplied message to the Google-Test-generated message. +String AppendUserMessage(const String& gtest_msg, + const Message& user_msg) { + // Appends the user message if it's non-empty. + const String user_msg_string = user_msg.GetString(); + if (user_msg_string.empty()) { + return gtest_msg; + } + + Message msg; + msg << gtest_msg << "\n" << user_msg_string; + + return msg.GetString(); +} + +} // namespace internal + +// class TestResult + +// Creates an empty TestResult. +TestResult::TestResult() + : death_test_count_(0), + elapsed_time_(0) { +} + +// D'tor. +TestResult::~TestResult() { +} + +// Returns the i-th test part result among all the results. i can +// range from 0 to total_part_count() - 1. If i is not in that range, +// aborts the program. +const TestPartResult& TestResult::GetTestPartResult(int i) const { + if (i < 0 || i >= total_part_count()) + internal::posix::Abort(); + return test_part_results_.at(i); +} + +// Returns the i-th test property. i can range from 0 to +// test_property_count() - 1. If i is not in that range, aborts the +// program. +const TestProperty& TestResult::GetTestProperty(int i) const { + if (i < 0 || i >= test_property_count()) + internal::posix::Abort(); + return test_properties_.at(i); +} + +// Clears the test part results. +void TestResult::ClearTestPartResults() { + test_part_results_.clear(); +} + +// Adds a test part result to the list. +void TestResult::AddTestPartResult(const TestPartResult& test_part_result) { + test_part_results_.push_back(test_part_result); +} + +// Adds a test property to the list. If a property with the same key as the +// supplied property is already represented, the value of this test_property +// replaces the old value for that key. +void TestResult::RecordProperty(const TestProperty& test_property) { + if (!ValidateTestProperty(test_property)) { + return; + } + internal::MutexLock lock(&test_properites_mutex_); + const std::vector::iterator property_with_matching_key = + std::find_if(test_properties_.begin(), test_properties_.end(), + internal::TestPropertyKeyIs(test_property.key())); + if (property_with_matching_key == test_properties_.end()) { + test_properties_.push_back(test_property); + return; + } + property_with_matching_key->SetValue(test_property.value()); +} + +// Adds a failure if the key is a reserved attribute of Google Test +// testcase tags. Returns true if the property is valid. +bool TestResult::ValidateTestProperty(const TestProperty& test_property) { + internal::String key(test_property.key()); + if (key == "name" || key == "status" || key == "time" || key == "classname") { + ADD_FAILURE() + << "Reserved key used in RecordProperty(): " + << key + << " ('name', 'status', 'time', and 'classname' are reserved by " + << GTEST_NAME_ << ")"; + return false; + } + return true; +} + +// Clears the object. +void TestResult::Clear() { + test_part_results_.clear(); + test_properties_.clear(); + death_test_count_ = 0; + elapsed_time_ = 0; +} + +// Returns true iff the test failed. +bool TestResult::Failed() const { + for (int i = 0; i < total_part_count(); ++i) { + if (GetTestPartResult(i).failed()) + return true; + } + return false; +} + +// Returns true iff the test part fatally failed. +static bool TestPartFatallyFailed(const TestPartResult& result) { + return result.fatally_failed(); +} + +// Returns true iff the test fatally failed. +bool TestResult::HasFatalFailure() const { + return CountIf(test_part_results_, TestPartFatallyFailed) > 0; +} + +// Returns true iff the test part non-fatally failed. +static bool TestPartNonfatallyFailed(const TestPartResult& result) { + return result.nonfatally_failed(); +} + +// Returns true iff the test has a non-fatal failure. +bool TestResult::HasNonfatalFailure() const { + return CountIf(test_part_results_, TestPartNonfatallyFailed) > 0; +} + +// Gets the number of all test parts. This is the sum of the number +// of successful test parts and the number of failed test parts. +int TestResult::total_part_count() const { + return static_cast(test_part_results_.size()); +} + +// Returns the number of the test properties. +int TestResult::test_property_count() const { + return static_cast(test_properties_.size()); +} + +// class Test + +// Creates a Test object. + +// The c'tor saves the values of all Google Test flags. +Test::Test() + : gtest_flag_saver_(new internal::GTestFlagSaver) { +} + +// The d'tor restores the values of all Google Test flags. +Test::~Test() { + delete gtest_flag_saver_; +} + +// Sets up the test fixture. +// +// A sub-class may override this. +void Test::SetUp() { +} + +// Tears down the test fixture. +// +// A sub-class may override this. +void Test::TearDown() { +} + +// Allows user supplied key value pairs to be recorded for later output. +void Test::RecordProperty(const char* key, const char* value) { + UnitTest::GetInstance()->RecordPropertyForCurrentTest(key, value); +} + +// Allows user supplied key value pairs to be recorded for later output. +void Test::RecordProperty(const char* key, int value) { + Message value_message; + value_message << value; + RecordProperty(key, value_message.GetString().c_str()); +} + +namespace internal { + +void ReportFailureInUnknownLocation(TestPartResult::Type result_type, + const String& message) { + // This function is a friend of UnitTest and as such has access to + // AddTestPartResult. + UnitTest::GetInstance()->AddTestPartResult( + result_type, + NULL, // No info about the source file where the exception occurred. + -1, // We have no info on which line caused the exception. + message, + String()); // No stack trace, either. +} + +} // namespace internal + +#if GTEST_OS_WINDOWS +// We are on Windows. + +// Adds an "exception thrown" fatal failure to the current test. +static void AddExceptionThrownFailure(DWORD exception_code, + const char* location) { + Message message; + message << "Exception thrown with code 0x" << std::setbase(16) << + exception_code << std::setbase(10) << " in " << location << "."; + + internal::ReportFailureInUnknownLocation(TestPartResult::kFatalFailure, + message.GetString()); +} + +#endif // GTEST_OS_WINDOWS + +// Google Test requires all tests in the same test case to use the same test +// fixture class. This function checks if the current test has the +// same fixture class as the first test in the current test case. If +// yes, it returns true; otherwise it generates a Google Test failure and +// returns false. +bool Test::HasSameFixtureClass() { + internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); + const TestCase* const test_case = impl->current_test_case(); + + // Info about the first test in the current test case. + const internal::TestInfoImpl* const first_test_info = + test_case->test_info_list()[0]->impl(); + const internal::TypeId first_fixture_id = first_test_info->fixture_class_id(); + const char* const first_test_name = first_test_info->name(); + + // Info about the current test. + const internal::TestInfoImpl* const this_test_info = + impl->current_test_info()->impl(); + const internal::TypeId this_fixture_id = this_test_info->fixture_class_id(); + const char* const this_test_name = this_test_info->name(); + + if (this_fixture_id != first_fixture_id) { + // Is the first test defined using TEST? + const bool first_is_TEST = first_fixture_id == internal::GetTestTypeId(); + // Is this test defined using TEST? + const bool this_is_TEST = this_fixture_id == internal::GetTestTypeId(); + + if (first_is_TEST || this_is_TEST) { + // The user mixed TEST and TEST_F in this test case - we'll tell + // him/her how to fix it. + + // Gets the name of the TEST and the name of the TEST_F. Note + // that first_is_TEST and this_is_TEST cannot both be true, as + // the fixture IDs are different for the two tests. + const char* const TEST_name = + first_is_TEST ? first_test_name : this_test_name; + const char* const TEST_F_name = + first_is_TEST ? this_test_name : first_test_name; + + ADD_FAILURE() + << "All tests in the same test case must use the same test fixture\n" + << "class, so mixing TEST_F and TEST in the same test case is\n" + << "illegal. In test case " << this_test_info->test_case_name() + << ",\n" + << "test " << TEST_F_name << " is defined using TEST_F but\n" + << "test " << TEST_name << " is defined using TEST. You probably\n" + << "want to change the TEST to TEST_F or move it to another test\n" + << "case."; + } else { + // The user defined two fixture classes with the same name in + // two namespaces - we'll tell him/her how to fix it. + ADD_FAILURE() + << "All tests in the same test case must use the same test fixture\n" + << "class. However, in test case " + << this_test_info->test_case_name() << ",\n" + << "you defined test " << first_test_name + << " and test " << this_test_name << "\n" + << "using two different test fixture classes. This can happen if\n" + << "the two classes are from different namespaces or translation\n" + << "units and have the same name. You should probably rename one\n" + << "of the classes to put the tests into different test cases."; + } + return false; + } + + return true; +} + +// Runs the test and updates the test result. +void Test::Run() { + if (!HasSameFixtureClass()) return; + + internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); +#if GTEST_HAS_SEH + // Catch SEH-style exceptions. + impl->os_stack_trace_getter()->UponLeavingGTest(); + __try { + SetUp(); + } __except(internal::UnitTestOptions::GTestShouldProcessSEH( + GetExceptionCode())) { + AddExceptionThrownFailure(GetExceptionCode(), "SetUp()"); + } + + // We will run the test only if SetUp() had no fatal failure. + if (!HasFatalFailure()) { + impl->os_stack_trace_getter()->UponLeavingGTest(); + __try { + TestBody(); + } __except(internal::UnitTestOptions::GTestShouldProcessSEH( + GetExceptionCode())) { + AddExceptionThrownFailure(GetExceptionCode(), "the test body"); + } + } + + // However, we want to clean up as much as possible. Hence we will + // always call TearDown(), even if SetUp() or the test body has + // failed. + impl->os_stack_trace_getter()->UponLeavingGTest(); + __try { + TearDown(); + } __except(internal::UnitTestOptions::GTestShouldProcessSEH( + GetExceptionCode())) { + AddExceptionThrownFailure(GetExceptionCode(), "TearDown()"); + } + +#else // We are on a compiler or platform that doesn't support SEH. + impl->os_stack_trace_getter()->UponLeavingGTest(); + SetUp(); + + // We will run the test only if SetUp() was successful. + if (!HasFatalFailure()) { + impl->os_stack_trace_getter()->UponLeavingGTest(); + TestBody(); + } + + // However, we want to clean up as much as possible. Hence we will + // always call TearDown(), even if SetUp() or the test body has + // failed. + impl->os_stack_trace_getter()->UponLeavingGTest(); + TearDown(); +#endif // GTEST_HAS_SEH +} + + +// Returns true iff the current test has a fatal failure. +bool Test::HasFatalFailure() { + return internal::GetUnitTestImpl()->current_test_result()->HasFatalFailure(); +} + +// Returns true iff the current test has a non-fatal failure. +bool Test::HasNonfatalFailure() { + return internal::GetUnitTestImpl()->current_test_result()-> + HasNonfatalFailure(); +} + +// class TestInfo + +// Constructs a TestInfo object. It assumes ownership of the test factory +// object via impl_. +TestInfo::TestInfo(const char* a_test_case_name, + const char* a_name, + const char* a_test_case_comment, + const char* a_comment, + internal::TypeId fixture_class_id, + internal::TestFactoryBase* factory) { + impl_ = new internal::TestInfoImpl(this, a_test_case_name, a_name, + a_test_case_comment, a_comment, + fixture_class_id, factory); +} + +// Destructs a TestInfo object. +TestInfo::~TestInfo() { + delete impl_; +} + +namespace internal { + +// Creates a new TestInfo object and registers it with Google Test; +// returns the created object. +// +// Arguments: +// +// test_case_name: name of the test case +// name: name of the test +// test_case_comment: a comment on the test case that will be included in +// the test output +// comment: a comment on the test that will be included in the +// test output +// fixture_class_id: ID of the test fixture class +// set_up_tc: pointer to the function that sets up the test case +// tear_down_tc: pointer to the function that tears down the test case +// factory: pointer to the factory that creates a test object. +// The newly created TestInfo instance will assume +// ownership of the factory object. +TestInfo* MakeAndRegisterTestInfo( + const char* test_case_name, const char* name, + const char* test_case_comment, const char* comment, + TypeId fixture_class_id, + SetUpTestCaseFunc set_up_tc, + TearDownTestCaseFunc tear_down_tc, + TestFactoryBase* factory) { + TestInfo* const test_info = + new TestInfo(test_case_name, name, test_case_comment, comment, + fixture_class_id, factory); + GetUnitTestImpl()->AddTestInfo(set_up_tc, tear_down_tc, test_info); + return test_info; +} + +#if GTEST_HAS_PARAM_TEST +void ReportInvalidTestCaseType(const char* test_case_name, + const char* file, int line) { + Message errors; + errors + << "Attempted redefinition of test case " << test_case_name << ".\n" + << "All tests in the same test case must use the same test fixture\n" + << "class. However, in test case " << test_case_name << ", you tried\n" + << "to define a test using a fixture class different from the one\n" + << "used earlier. This can happen if the two fixture classes are\n" + << "from different namespaces and have the same name. You should\n" + << "probably rename one of the classes to put the tests into different\n" + << "test cases."; + + fprintf(stderr, "%s %s", FormatFileLocation(file, line).c_str(), + errors.GetString().c_str()); +} +#endif // GTEST_HAS_PARAM_TEST + +} // namespace internal + +// Returns the test case name. +const char* TestInfo::test_case_name() const { + return impl_->test_case_name(); +} + +// Returns the test name. +const char* TestInfo::name() const { + return impl_->name(); +} + +// Returns the test case comment. +const char* TestInfo::test_case_comment() const { + return impl_->test_case_comment(); +} + +// Returns the test comment. +const char* TestInfo::comment() const { + return impl_->comment(); +} + +// Returns true if this test should run. +bool TestInfo::should_run() const { return impl_->should_run(); } + +// Returns true if this test matches the user-specified filter. +bool TestInfo::matches_filter() const { return impl_->matches_filter(); } + +// Returns the result of the test. +const TestResult* TestInfo::result() const { return impl_->result(); } + +// Increments the number of death tests encountered in this test so +// far. +int TestInfo::increment_death_test_count() { + return impl_->result()->increment_death_test_count(); +} + +namespace { + +// A predicate that checks the test name of a TestInfo against a known +// value. +// +// This is used for implementation of the TestCase class only. We put +// it in the anonymous namespace to prevent polluting the outer +// namespace. +// +// TestNameIs is copyable. +class TestNameIs { + public: + // Constructor. + // + // TestNameIs has NO default constructor. + explicit TestNameIs(const char* name) + : name_(name) {} + + // Returns true iff the test name of test_info matches name_. + bool operator()(const TestInfo * test_info) const { + return test_info && internal::String(test_info->name()).Compare(name_) == 0; + } + + private: + internal::String name_; +}; + +} // namespace + +namespace internal { + +// This method expands all parameterized tests registered with macros TEST_P +// and INSTANTIATE_TEST_CASE_P into regular tests and registers those. +// This will be done just once during the program runtime. +void UnitTestImpl::RegisterParameterizedTests() { +#if GTEST_HAS_PARAM_TEST + if (!parameterized_tests_registered_) { + parameterized_test_registry_.RegisterTests(); + parameterized_tests_registered_ = true; + } +#endif +} + +// Creates the test object, runs it, records its result, and then +// deletes it. +void TestInfoImpl::Run() { + if (!should_run_) return; + + // Tells UnitTest where to store test result. + UnitTestImpl* const impl = internal::GetUnitTestImpl(); + impl->set_current_test_info(parent_); + + TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater(); + + // Notifies the unit test event listeners that a test is about to start. + repeater->OnTestStart(*parent_); + + const TimeInMillis start = GetTimeInMillis(); + + impl->os_stack_trace_getter()->UponLeavingGTest(); +#if GTEST_HAS_SEH + // Catch SEH-style exceptions. + Test* test = NULL; + + __try { + // Creates the test object. + test = factory_->CreateTest(); + } __except(internal::UnitTestOptions::GTestShouldProcessSEH( + GetExceptionCode())) { + AddExceptionThrownFailure(GetExceptionCode(), + "the test fixture's constructor"); + return; + } +#else // We are on a compiler or platform that doesn't support SEH. + + // TODO(wan): If test->Run() throws, test won't be deleted. This is + // not a problem now as we don't use exceptions. If we were to + // enable exceptions, we should revise the following to be + // exception-safe. + + // Creates the test object. + Test* test = factory_->CreateTest(); +#endif // GTEST_HAS_SEH + + // Runs the test only if the constructor of the test fixture didn't + // generate a fatal failure. + if (!Test::HasFatalFailure()) { + test->Run(); + } + + // Deletes the test object. + impl->os_stack_trace_getter()->UponLeavingGTest(); + delete test; + test = NULL; + + result_.set_elapsed_time(GetTimeInMillis() - start); + + // Notifies the unit test event listener that a test has just finished. + repeater->OnTestEnd(*parent_); + + // Tells UnitTest to stop associating assertion results to this + // test. + impl->set_current_test_info(NULL); +} + +} // namespace internal + +// class TestCase + +// Gets the number of successful tests in this test case. +int TestCase::successful_test_count() const { + return CountIf(test_info_list_, TestPassed); +} + +// Gets the number of failed tests in this test case. +int TestCase::failed_test_count() const { + return CountIf(test_info_list_, TestFailed); +} + +int TestCase::disabled_test_count() const { + return CountIf(test_info_list_, TestDisabled); +} + +// Get the number of tests in this test case that should run. +int TestCase::test_to_run_count() const { + return CountIf(test_info_list_, ShouldRunTest); +} + +// Gets the number of all tests. +int TestCase::total_test_count() const { + return static_cast(test_info_list_.size()); +} + +// Creates a TestCase with the given name. +// +// Arguments: +// +// name: name of the test case +// set_up_tc: pointer to the function that sets up the test case +// tear_down_tc: pointer to the function that tears down the test case +TestCase::TestCase(const char* a_name, const char* a_comment, + Test::SetUpTestCaseFunc set_up_tc, + Test::TearDownTestCaseFunc tear_down_tc) + : name_(a_name), + comment_(a_comment), + set_up_tc_(set_up_tc), + tear_down_tc_(tear_down_tc), + should_run_(false), + elapsed_time_(0) { +} + +// Destructor of TestCase. +TestCase::~TestCase() { + // Deletes every Test in the collection. + ForEach(test_info_list_, internal::Delete); +} + +// Returns the i-th test among all the tests. i can range from 0 to +// total_test_count() - 1. If i is not in that range, returns NULL. +const TestInfo* TestCase::GetTestInfo(int i) const { + const int index = GetElementOr(test_indices_, i, -1); + return index < 0 ? NULL : test_info_list_[index]; +} + +// Returns the i-th test among all the tests. i can range from 0 to +// total_test_count() - 1. If i is not in that range, returns NULL. +TestInfo* TestCase::GetMutableTestInfo(int i) { + const int index = GetElementOr(test_indices_, i, -1); + return index < 0 ? NULL : test_info_list_[index]; +} + +// Adds a test to this test case. Will delete the test upon +// destruction of the TestCase object. +void TestCase::AddTestInfo(TestInfo * test_info) { + test_info_list_.push_back(test_info); + test_indices_.push_back(static_cast(test_indices_.size())); +} + +// Runs every test in this TestCase. +void TestCase::Run() { + if (!should_run_) return; + + internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); + impl->set_current_test_case(this); + + TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater(); + + repeater->OnTestCaseStart(*this); + impl->os_stack_trace_getter()->UponLeavingGTest(); + set_up_tc_(); + + const internal::TimeInMillis start = internal::GetTimeInMillis(); + for (int i = 0; i < total_test_count(); i++) { + GetMutableTestInfo(i)->impl()->Run(); + } + elapsed_time_ = internal::GetTimeInMillis() - start; + + impl->os_stack_trace_getter()->UponLeavingGTest(); + tear_down_tc_(); + repeater->OnTestCaseEnd(*this); + impl->set_current_test_case(NULL); +} + +// Clears the results of all tests in this test case. +void TestCase::ClearResult() { + ForEach(test_info_list_, internal::TestInfoImpl::ClearTestResult); +} + +// Returns true iff test passed. +bool TestCase::TestPassed(const TestInfo * test_info) { + const internal::TestInfoImpl* const impl = test_info->impl(); + return impl->should_run() && impl->result()->Passed(); +} + +// Returns true iff test failed. +bool TestCase::TestFailed(const TestInfo * test_info) { + const internal::TestInfoImpl* const impl = test_info->impl(); + return impl->should_run() && impl->result()->Failed(); +} + +// Returns true iff test is disabled. +bool TestCase::TestDisabled(const TestInfo * test_info) { + return test_info->impl()->is_disabled(); +} + +// Returns true if the given test should run. +bool TestCase::ShouldRunTest(const TestInfo *test_info) { + return test_info->impl()->should_run(); +} + +// Shuffles the tests in this test case. +void TestCase::ShuffleTests(internal::Random* random) { + Shuffle(random, &test_indices_); +} + +// Restores the test order to before the first shuffle. +void TestCase::UnshuffleTests() { + for (size_t i = 0; i < test_indices_.size(); i++) { + test_indices_[i] = static_cast(i); + } +} + +// Formats a countable noun. Depending on its quantity, either the +// singular form or the plural form is used. e.g. +// +// FormatCountableNoun(1, "formula", "formuli") returns "1 formula". +// FormatCountableNoun(5, "book", "books") returns "5 books". +static internal::String FormatCountableNoun(int count, + const char * singular_form, + const char * plural_form) { + return internal::String::Format("%d %s", count, + count == 1 ? singular_form : plural_form); +} + +// Formats the count of tests. +static internal::String FormatTestCount(int test_count) { + return FormatCountableNoun(test_count, "test", "tests"); +} + +// Formats the count of test cases. +static internal::String FormatTestCaseCount(int test_case_count) { + return FormatCountableNoun(test_case_count, "test case", "test cases"); +} + +// Converts a TestPartResult::Type enum to human-friendly string +// representation. Both kNonFatalFailure and kFatalFailure are translated +// to "Failure", as the user usually doesn't care about the difference +// between the two when viewing the test result. +static const char * TestPartResultTypeToString(TestPartResult::Type type) { + switch (type) { + case TestPartResult::kSuccess: + return "Success"; + + case TestPartResult::kNonFatalFailure: + case TestPartResult::kFatalFailure: +#ifdef _MSC_VER + return "error: "; +#else + return "Failure\n"; +#endif + } + + return "Unknown result type"; +} + +// Prints a TestPartResult to a String. +static internal::String PrintTestPartResultToString( + const TestPartResult& test_part_result) { + return (Message() + << internal::FormatFileLocation(test_part_result.file_name(), + test_part_result.line_number()) + << " " << TestPartResultTypeToString(test_part_result.type()) + << test_part_result.message()).GetString(); +} + +// Prints a TestPartResult. +static void PrintTestPartResult(const TestPartResult& test_part_result) { + const internal::String& result = + PrintTestPartResultToString(test_part_result); + printf("%s\n", result.c_str()); + fflush(stdout); + // If the test program runs in Visual Studio or a debugger, the + // following statements add the test part result message to the Output + // window such that the user can double-click on it to jump to the + // corresponding source code location; otherwise they do nothing. +#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE + // We don't call OutputDebugString*() on Windows Mobile, as printing + // to stdout is done by OutputDebugString() there already - we don't + // want the same message printed twice. + ::OutputDebugStringA(result.c_str()); + ::OutputDebugStringA("\n"); +#endif +} + +// class PrettyUnitTestResultPrinter + +namespace internal { + +enum GTestColor { + COLOR_DEFAULT, + COLOR_RED, + COLOR_GREEN, + COLOR_YELLOW +}; + +#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE + +// Returns the character attribute for the given color. +WORD GetColorAttribute(GTestColor color) { + switch (color) { + case COLOR_RED: return FOREGROUND_RED; + case COLOR_GREEN: return FOREGROUND_GREEN; + case COLOR_YELLOW: return FOREGROUND_RED | FOREGROUND_GREEN; + default: return 0; + } +} + +#else + +// Returns the ANSI color code for the given color. COLOR_DEFAULT is +// an invalid input. +const char* GetAnsiColorCode(GTestColor color) { + switch (color) { + case COLOR_RED: return "1"; + case COLOR_GREEN: return "2"; + case COLOR_YELLOW: return "3"; + default: return NULL; + }; +} + +#endif // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE + +// Returns true iff Google Test should use colors in the output. +bool ShouldUseColor(bool stdout_is_tty) { + const char* const gtest_color = GTEST_FLAG(color).c_str(); + + if (String::CaseInsensitiveCStringEquals(gtest_color, "auto")) { +#if GTEST_OS_WINDOWS + // On Windows the TERM variable is usually not set, but the + // console there does support colors. + return stdout_is_tty; +#else + // On non-Windows platforms, we rely on the TERM variable. + const char* const term = posix::GetEnv("TERM"); + const bool term_supports_color = + String::CStringEquals(term, "xterm") || + String::CStringEquals(term, "xterm-color") || + String::CStringEquals(term, "xterm-256color") || + String::CStringEquals(term, "linux") || + String::CStringEquals(term, "cygwin"); + return stdout_is_tty && term_supports_color; +#endif // GTEST_OS_WINDOWS + } + + return String::CaseInsensitiveCStringEquals(gtest_color, "yes") || + String::CaseInsensitiveCStringEquals(gtest_color, "true") || + String::CaseInsensitiveCStringEquals(gtest_color, "t") || + String::CStringEquals(gtest_color, "1"); + // We take "yes", "true", "t", and "1" as meaning "yes". If the + // value is neither one of these nor "auto", we treat it as "no" to + // be conservative. +} + +// Helpers for printing colored strings to stdout. Note that on Windows, we +// cannot simply emit special characters and have the terminal change colors. +// This routine must actually emit the characters rather than return a string +// that would be colored when printed, as can be done on Linux. +void ColoredPrintf(GTestColor color, const char* fmt, ...) { + va_list args; + va_start(args, fmt); + +#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_SYMBIAN || GTEST_OS_ZOS + const bool use_color = false; +#else + static const bool in_color_mode = + ShouldUseColor(posix::IsATTY(posix::FileNo(stdout)) != 0); + const bool use_color = in_color_mode && (color != COLOR_DEFAULT); +#endif // GTEST_OS_WINDOWS_MOBILE || GTEST_OS_SYMBIAN || GTEST_OS_ZOS + // The '!= 0' comparison is necessary to satisfy MSVC 7.1. + + if (!use_color) { + vprintf(fmt, args); + va_end(args); + return; + } + +#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE + const HANDLE stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE); + + // Gets the current text color. + CONSOLE_SCREEN_BUFFER_INFO buffer_info; + GetConsoleScreenBufferInfo(stdout_handle, &buffer_info); + const WORD old_color_attrs = buffer_info.wAttributes; + + // We need to flush the stream buffers into the console before each + // SetConsoleTextAttribute call lest it affect the text that is already + // printed but has not yet reached the console. + fflush(stdout); + SetConsoleTextAttribute(stdout_handle, + GetColorAttribute(color) | FOREGROUND_INTENSITY); + vprintf(fmt, args); + + fflush(stdout); + // Restores the text color. + SetConsoleTextAttribute(stdout_handle, old_color_attrs); +#else + printf("\033[0;3%sm", GetAnsiColorCode(color)); + vprintf(fmt, args); + printf("\033[m"); // Resets the terminal to default. +#endif // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE + va_end(args); +} + +// This class implements the TestEventListener interface. +// +// Class PrettyUnitTestResultPrinter is copyable. +class PrettyUnitTestResultPrinter : public TestEventListener { + public: + PrettyUnitTestResultPrinter() {} + static void PrintTestName(const char * test_case, const char * test) { + printf("%s.%s", test_case, test); + } + + // The following methods override what's in the TestEventListener class. + virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) {} + virtual void OnTestIterationStart(const UnitTest& unit_test, int iteration); + virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test); + virtual void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) {} + virtual void OnTestCaseStart(const TestCase& test_case); + virtual void OnTestStart(const TestInfo& test_info); + virtual void OnTestPartResult(const TestPartResult& result); + virtual void OnTestEnd(const TestInfo& test_info); + virtual void OnTestCaseEnd(const TestCase& test_case); + virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test); + virtual void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) {} + virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration); + virtual void OnTestProgramEnd(const UnitTest& /*unit_test*/) {} + + private: + static void PrintFailedTests(const UnitTest& unit_test); + + internal::String test_case_name_; +}; + + // Fired before each iteration of tests starts. +void PrettyUnitTestResultPrinter::OnTestIterationStart( + const UnitTest& unit_test, int iteration) { + if (GTEST_FLAG(repeat) != 1) + printf("\nRepeating all tests (iteration %d) . . .\n\n", iteration + 1); + + const char* const filter = GTEST_FLAG(filter).c_str(); + + // Prints the filter if it's not *. This reminds the user that some + // tests may be skipped. + if (!internal::String::CStringEquals(filter, kUniversalFilter)) { + ColoredPrintf(COLOR_YELLOW, + "Note: %s filter = %s\n", GTEST_NAME_, filter); + } + + if (internal::ShouldShard(kTestTotalShards, kTestShardIndex, false)) { + ColoredPrintf(COLOR_YELLOW, + "Note: This is test shard %s of %s.\n", + internal::posix::GetEnv(kTestShardIndex), + internal::posix::GetEnv(kTestTotalShards)); + } + + if (GTEST_FLAG(shuffle)) { + ColoredPrintf(COLOR_YELLOW, + "Note: Randomizing tests' orders with a seed of %d .\n", + unit_test.random_seed()); + } + + ColoredPrintf(COLOR_GREEN, "[==========] "); + printf("Running %s from %s.\n", + FormatTestCount(unit_test.test_to_run_count()).c_str(), + FormatTestCaseCount(unit_test.test_case_to_run_count()).c_str()); + fflush(stdout); +} + +void PrettyUnitTestResultPrinter::OnEnvironmentsSetUpStart( + const UnitTest& /*unit_test*/) { + ColoredPrintf(COLOR_GREEN, "[----------] "); + printf("Global test environment set-up.\n"); + fflush(stdout); +} + +void PrettyUnitTestResultPrinter::OnTestCaseStart(const TestCase& test_case) { + test_case_name_ = test_case.name(); + const internal::String counts = + FormatCountableNoun(test_case.test_to_run_count(), "test", "tests"); + ColoredPrintf(COLOR_GREEN, "[----------] "); + printf("%s from %s", counts.c_str(), test_case_name_.c_str()); + if (test_case.comment()[0] == '\0') { + printf("\n"); + } else { + printf(", where %s\n", test_case.comment()); + } + fflush(stdout); +} + +void PrettyUnitTestResultPrinter::OnTestStart(const TestInfo& test_info) { + ColoredPrintf(COLOR_GREEN, "[ RUN ] "); + PrintTestName(test_case_name_.c_str(), test_info.name()); + if (test_info.comment()[0] == '\0') { + printf("\n"); + } else { + printf(", where %s\n", test_info.comment()); + } + fflush(stdout); +} + +// Called after an assertion failure. +void PrettyUnitTestResultPrinter::OnTestPartResult( + const TestPartResult& result) { + // If the test part succeeded, we don't need to do anything. + if (result.type() == TestPartResult::kSuccess) + return; + + // Print failure message from the assertion (e.g. expected this and got that). + PrintTestPartResult(result); + fflush(stdout); +} + +void PrettyUnitTestResultPrinter::OnTestEnd(const TestInfo& test_info) { + if (test_info.result()->Passed()) { + ColoredPrintf(COLOR_GREEN, "[ OK ] "); + } else { + ColoredPrintf(COLOR_RED, "[ FAILED ] "); + } + PrintTestName(test_case_name_.c_str(), test_info.name()); + if (GTEST_FLAG(print_time)) { + printf(" (%s ms)\n", internal::StreamableToString( + test_info.result()->elapsed_time()).c_str()); + } else { + printf("\n"); + } + fflush(stdout); +} + +void PrettyUnitTestResultPrinter::OnTestCaseEnd(const TestCase& test_case) { + if (!GTEST_FLAG(print_time)) return; + + test_case_name_ = test_case.name(); + const internal::String counts = + FormatCountableNoun(test_case.test_to_run_count(), "test", "tests"); + ColoredPrintf(COLOR_GREEN, "[----------] "); + printf("%s from %s (%s ms total)\n\n", + counts.c_str(), test_case_name_.c_str(), + internal::StreamableToString(test_case.elapsed_time()).c_str()); + fflush(stdout); +} + +void PrettyUnitTestResultPrinter::OnEnvironmentsTearDownStart( + const UnitTest& /*unit_test*/) { + ColoredPrintf(COLOR_GREEN, "[----------] "); + printf("Global test environment tear-down\n"); + fflush(stdout); +} + +// Internal helper for printing the list of failed tests. +void PrettyUnitTestResultPrinter::PrintFailedTests(const UnitTest& unit_test) { + const int failed_test_count = unit_test.failed_test_count(); + if (failed_test_count == 0) { + return; + } + + for (int i = 0; i < unit_test.total_test_case_count(); ++i) { + const TestCase& test_case = *unit_test.GetTestCase(i); + if (!test_case.should_run() || (test_case.failed_test_count() == 0)) { + continue; + } + for (int j = 0; j < test_case.total_test_count(); ++j) { + const TestInfo& test_info = *test_case.GetTestInfo(j); + if (!test_info.should_run() || test_info.result()->Passed()) { + continue; + } + ColoredPrintf(COLOR_RED, "[ FAILED ] "); + printf("%s.%s", test_case.name(), test_info.name()); + if (test_case.comment()[0] != '\0' || + test_info.comment()[0] != '\0') { + printf(", where %s", test_case.comment()); + if (test_case.comment()[0] != '\0' && + test_info.comment()[0] != '\0') { + printf(" and "); + } + } + printf("%s\n", test_info.comment()); + } + } +} + + void PrettyUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test, + int /*iteration*/) { + ColoredPrintf(COLOR_GREEN, "[==========] "); + printf("%s from %s ran.", + FormatTestCount(unit_test.test_to_run_count()).c_str(), + FormatTestCaseCount(unit_test.test_case_to_run_count()).c_str()); + if (GTEST_FLAG(print_time)) { + printf(" (%s ms total)", + internal::StreamableToString(unit_test.elapsed_time()).c_str()); + } + printf("\n"); + ColoredPrintf(COLOR_GREEN, "[ PASSED ] "); + printf("%s.\n", FormatTestCount(unit_test.successful_test_count()).c_str()); + + int num_failures = unit_test.failed_test_count(); + if (!unit_test.Passed()) { + const int failed_test_count = unit_test.failed_test_count(); + ColoredPrintf(COLOR_RED, "[ FAILED ] "); + printf("%s, listed below:\n", FormatTestCount(failed_test_count).c_str()); + PrintFailedTests(unit_test); + printf("\n%2d FAILED %s\n", num_failures, + num_failures == 1 ? "TEST" : "TESTS"); + } + + int num_disabled = unit_test.disabled_test_count(); + if (num_disabled && !GTEST_FLAG(also_run_disabled_tests)) { + if (!num_failures) { + printf("\n"); // Add a spacer if no FAILURE banner is displayed. + } + ColoredPrintf(COLOR_YELLOW, + " YOU HAVE %d DISABLED %s\n\n", + num_disabled, + num_disabled == 1 ? "TEST" : "TESTS"); + } + // Ensure that Google Test output is printed before, e.g., heapchecker output. + fflush(stdout); +} + +// End PrettyUnitTestResultPrinter + +// class TestEventRepeater +// +// This class forwards events to other event listeners. +class TestEventRepeater : public TestEventListener { + public: + TestEventRepeater() : forwarding_enabled_(true) {} + virtual ~TestEventRepeater(); + void Append(TestEventListener *listener); + TestEventListener* Release(TestEventListener* listener); + + // Controls whether events will be forwarded to listeners_. Set to false + // in death test child processes. + bool forwarding_enabled() const { return forwarding_enabled_; } + void set_forwarding_enabled(bool enable) { forwarding_enabled_ = enable; } + + virtual void OnTestProgramStart(const UnitTest& unit_test); + virtual void OnTestIterationStart(const UnitTest& unit_test, int iteration); + virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test); + virtual void OnEnvironmentsSetUpEnd(const UnitTest& unit_test); + virtual void OnTestCaseStart(const TestCase& test_case); + virtual void OnTestStart(const TestInfo& test_info); + virtual void OnTestPartResult(const TestPartResult& result); + virtual void OnTestEnd(const TestInfo& test_info); + virtual void OnTestCaseEnd(const TestCase& test_case); + virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test); + virtual void OnEnvironmentsTearDownEnd(const UnitTest& unit_test); + virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration); + virtual void OnTestProgramEnd(const UnitTest& unit_test); + + private: + // Controls whether events will be forwarded to listeners_. Set to false + // in death test child processes. + bool forwarding_enabled_; + // The list of listeners that receive events. + std::vector listeners_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestEventRepeater); +}; + +TestEventRepeater::~TestEventRepeater() { + ForEach(listeners_, Delete); +} + +void TestEventRepeater::Append(TestEventListener *listener) { + listeners_.push_back(listener); +} + +// TODO(vladl@google.com): Factor the search functionality into Vector::Find. +TestEventListener* TestEventRepeater::Release(TestEventListener *listener) { + for (size_t i = 0; i < listeners_.size(); ++i) { + if (listeners_[i] == listener) { + listeners_.erase(listeners_.begin() + i); + return listener; + } + } + + return NULL; +} + +// Since most methods are very similar, use macros to reduce boilerplate. +// This defines a member that forwards the call to all listeners. +#define GTEST_REPEATER_METHOD_(Name, Type) \ +void TestEventRepeater::Name(const Type& parameter) { \ + if (forwarding_enabled_) { \ + for (size_t i = 0; i < listeners_.size(); i++) { \ + listeners_[i]->Name(parameter); \ + } \ + } \ +} +// This defines a member that forwards the call to all listeners in reverse +// order. +#define GTEST_REVERSE_REPEATER_METHOD_(Name, Type) \ +void TestEventRepeater::Name(const Type& parameter) { \ + if (forwarding_enabled_) { \ + for (int i = static_cast(listeners_.size()) - 1; i >= 0; i--) { \ + listeners_[i]->Name(parameter); \ + } \ + } \ +} + +GTEST_REPEATER_METHOD_(OnTestProgramStart, UnitTest) +GTEST_REPEATER_METHOD_(OnEnvironmentsSetUpStart, UnitTest) +GTEST_REPEATER_METHOD_(OnTestCaseStart, TestCase) +GTEST_REPEATER_METHOD_(OnTestStart, TestInfo) +GTEST_REPEATER_METHOD_(OnTestPartResult, TestPartResult) +GTEST_REPEATER_METHOD_(OnEnvironmentsTearDownStart, UnitTest) +GTEST_REVERSE_REPEATER_METHOD_(OnEnvironmentsSetUpEnd, UnitTest) +GTEST_REVERSE_REPEATER_METHOD_(OnEnvironmentsTearDownEnd, UnitTest) +GTEST_REVERSE_REPEATER_METHOD_(OnTestEnd, TestInfo) +GTEST_REVERSE_REPEATER_METHOD_(OnTestCaseEnd, TestCase) +GTEST_REVERSE_REPEATER_METHOD_(OnTestProgramEnd, UnitTest) + +#undef GTEST_REPEATER_METHOD_ +#undef GTEST_REVERSE_REPEATER_METHOD_ + +void TestEventRepeater::OnTestIterationStart(const UnitTest& unit_test, + int iteration) { + if (forwarding_enabled_) { + for (size_t i = 0; i < listeners_.size(); i++) { + listeners_[i]->OnTestIterationStart(unit_test, iteration); + } + } +} + +void TestEventRepeater::OnTestIterationEnd(const UnitTest& unit_test, + int iteration) { + if (forwarding_enabled_) { + for (int i = static_cast(listeners_.size()) - 1; i >= 0; i--) { + listeners_[i]->OnTestIterationEnd(unit_test, iteration); + } + } +} + +// End TestEventRepeater + +// This class generates an XML output file. +class XmlUnitTestResultPrinter : public EmptyTestEventListener { + public: + explicit XmlUnitTestResultPrinter(const char* output_file); + + virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration); + + private: + // Is c a whitespace character that is normalized to a space character + // when it appears in an XML attribute value? + static bool IsNormalizableWhitespace(char c) { + return c == 0x9 || c == 0xA || c == 0xD; + } + + // May c appear in a well-formed XML document? + static bool IsValidXmlCharacter(char c) { + return IsNormalizableWhitespace(c) || c >= 0x20; + } + + // Returns an XML-escaped copy of the input string str. If + // is_attribute is true, the text is meant to appear as an attribute + // value, and normalizable whitespace is preserved by replacing it + // with character references. + static String EscapeXml(const char* str, bool is_attribute); + + // Returns the given string with all characters invalid in XML removed. + static String RemoveInvalidXmlCharacters(const char* str); + + // Convenience wrapper around EscapeXml when str is an attribute value. + static String EscapeXmlAttribute(const char* str) { + return EscapeXml(str, true); + } + + // Convenience wrapper around EscapeXml when str is not an attribute value. + static String EscapeXmlText(const char* str) { return EscapeXml(str, false); } + + // Streams an XML CDATA section, escaping invalid CDATA sequences as needed. + static void OutputXmlCDataSection(::std::ostream* stream, const char* data); + + // Streams an XML representation of a TestInfo object. + static void OutputXmlTestInfo(::std::ostream* stream, + const char* test_case_name, + const TestInfo& test_info); + + // Prints an XML representation of a TestCase object + static void PrintXmlTestCase(FILE* out, const TestCase& test_case); + + // Prints an XML summary of unit_test to output stream out. + static void PrintXmlUnitTest(FILE* out, const UnitTest& unit_test); + + // Produces a string representing the test properties in a result as space + // delimited XML attributes based on the property key="value" pairs. + // When the String is not empty, it includes a space at the beginning, + // to delimit this attribute from prior attributes. + static String TestPropertiesAsXmlAttributes(const TestResult& result); + + // The output file. + const String output_file_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(XmlUnitTestResultPrinter); +}; + +// Creates a new XmlUnitTestResultPrinter. +XmlUnitTestResultPrinter::XmlUnitTestResultPrinter(const char* output_file) + : output_file_(output_file) { + if (output_file_.c_str() == NULL || output_file_.empty()) { + fprintf(stderr, "XML output file may not be null\n"); + fflush(stderr); + exit(EXIT_FAILURE); + } +} + +// Called after the unit test ends. +void XmlUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test, + int /*iteration*/) { + FILE* xmlout = NULL; + FilePath output_file(output_file_); + FilePath output_dir(output_file.RemoveFileName()); + + if (output_dir.CreateDirectoriesRecursively()) { + xmlout = posix::FOpen(output_file_.c_str(), "w"); + } + if (xmlout == NULL) { + // TODO(wan): report the reason of the failure. + // + // We don't do it for now as: + // + // 1. There is no urgent need for it. + // 2. It's a bit involved to make the errno variable thread-safe on + // all three operating systems (Linux, Windows, and Mac OS). + // 3. To interpret the meaning of errno in a thread-safe way, + // we need the strerror_r() function, which is not available on + // Windows. + fprintf(stderr, + "Unable to open file \"%s\"\n", + output_file_.c_str()); + fflush(stderr); + exit(EXIT_FAILURE); + } + PrintXmlUnitTest(xmlout, unit_test); + fclose(xmlout); +} + +// Returns an XML-escaped copy of the input string str. If is_attribute +// is true, the text is meant to appear as an attribute value, and +// normalizable whitespace is preserved by replacing it with character +// references. +// +// Invalid XML characters in str, if any, are stripped from the output. +// It is expected that most, if not all, of the text processed by this +// module will consist of ordinary English text. +// If this module is ever modified to produce version 1.1 XML output, +// most invalid characters can be retained using character references. +// TODO(wan): It might be nice to have a minimally invasive, human-readable +// escaping scheme for invalid characters, rather than dropping them. +String XmlUnitTestResultPrinter::EscapeXml(const char* str, bool is_attribute) { + Message m; + + if (str != NULL) { + for (const char* src = str; *src; ++src) { + switch (*src) { + case '<': + m << "<"; + break; + case '>': + m << ">"; + break; + case '&': + m << "&"; + break; + case '\'': + if (is_attribute) + m << "'"; + else + m << '\''; + break; + case '"': + if (is_attribute) + m << """; + else + m << '"'; + break; + default: + if (IsValidXmlCharacter(*src)) { + if (is_attribute && IsNormalizableWhitespace(*src)) + m << String::Format("&#x%02X;", unsigned(*src)); + else + m << *src; + } + break; + } + } + } + + return m.GetString(); +} + +// Returns the given string with all characters invalid in XML removed. +// Currently invalid characters are dropped from the string. An +// alternative is to replace them with certain characters such as . or ?. +String XmlUnitTestResultPrinter::RemoveInvalidXmlCharacters(const char* str) { + char* const output = new char[strlen(str) + 1]; + char* appender = output; + for (char ch = *str; ch != '\0'; ch = *++str) + if (IsValidXmlCharacter(ch)) + *appender++ = ch; + *appender = '\0'; + + String ret_value(output); + delete[] output; + return ret_value; +} + +// The following routines generate an XML representation of a UnitTest +// object. +// +// This is how Google Test concepts map to the DTD: +// +// <-- corresponds to a UnitTest object +// <-- corresponds to a TestCase object +// <-- corresponds to a TestInfo object +// ... +// ... +// ... +// <-- individual assertion failures +// +// +// + +// Formats the given time in milliseconds as seconds. +std::string FormatTimeInMillisAsSeconds(TimeInMillis ms) { + ::std::stringstream ss; + ss << ms/1000.0; + return ss.str(); +} + +// Streams an XML CDATA section, escaping invalid CDATA sequences as needed. +void XmlUnitTestResultPrinter::OutputXmlCDataSection(::std::ostream* stream, + const char* data) { + const char* segment = data; + *stream << ""); + if (next_segment != NULL) { + stream->write( + segment, static_cast(next_segment - segment)); + *stream << "]]>]]>"); + } else { + *stream << segment; + break; + } + } + *stream << "]]>"; +} + +// Prints an XML representation of a TestInfo object. +// TODO(wan): There is also value in printing properties with the plain printer. +void XmlUnitTestResultPrinter::OutputXmlTestInfo(::std::ostream* stream, + const char* test_case_name, + const TestInfo& test_info) { + const TestResult& result = *test_info.result(); + *stream << " \n"; + *stream << " "; + const String message = RemoveInvalidXmlCharacters(String::Format( + "%s:%d\n%s", + part.file_name(), part.line_number(), + part.message()).c_str()); + OutputXmlCDataSection(stream, message.c_str()); + *stream << "\n"; + } + } + + if (failures == 0) + *stream << " />\n"; + else + *stream << " \n"; +} + +// Prints an XML representation of a TestCase object +void XmlUnitTestResultPrinter::PrintXmlTestCase(FILE* out, + const TestCase& test_case) { + fprintf(out, + " \n", + FormatTimeInMillisAsSeconds(test_case.elapsed_time()).c_str()); + for (int i = 0; i < test_case.total_test_count(); ++i) { + StrStream stream; + OutputXmlTestInfo(&stream, test_case.name(), *test_case.GetTestInfo(i)); + fprintf(out, "%s", StrStreamToString(&stream).c_str()); + } + fprintf(out, " \n"); +} + +// Prints an XML summary of unit_test to output stream out. +void XmlUnitTestResultPrinter::PrintXmlUnitTest(FILE* out, + const UnitTest& unit_test) { + fprintf(out, "\n"); + fprintf(out, + "\n"); + for (int i = 0; i < unit_test.total_test_case_count(); ++i) + PrintXmlTestCase(out, *unit_test.GetTestCase(i)); + fprintf(out, "\n"); +} + +// Produces a string representing the test properties in a result as space +// delimited XML attributes based on the property key="value" pairs. +String XmlUnitTestResultPrinter::TestPropertiesAsXmlAttributes( + const TestResult& result) { + Message attributes; + for (int i = 0; i < result.test_property_count(); ++i) { + const TestProperty& property = result.GetTestProperty(i); + attributes << " " << property.key() << "=" + << "\"" << EscapeXmlAttribute(property.value()) << "\""; + } + return attributes.GetString(); +} + +// End XmlUnitTestResultPrinter + +// Class ScopedTrace + +// Pushes the given source file location and message onto a per-thread +// trace stack maintained by Google Test. +// L < UnitTest::mutex_ +ScopedTrace::ScopedTrace(const char* file, int line, const Message& message) { + TraceInfo trace; + trace.file = file; + trace.line = line; + trace.message = message.GetString(); + + UnitTest::GetInstance()->PushGTestTrace(trace); +} + +// Pops the info pushed by the c'tor. +// L < UnitTest::mutex_ +ScopedTrace::~ScopedTrace() { + UnitTest::GetInstance()->PopGTestTrace(); +} + + +// class OsStackTraceGetter + +// Returns the current OS stack trace as a String. Parameters: +// +// max_depth - the maximum number of stack frames to be included +// in the trace. +// skip_count - the number of top frames to be skipped; doesn't count +// against max_depth. +// +// L < mutex_ +// We use "L < mutex_" to denote that the function may acquire mutex_. +String OsStackTraceGetter::CurrentStackTrace(int, int) { + return String(""); +} + +// L < mutex_ +void OsStackTraceGetter::UponLeavingGTest() { +} + +const char* const +OsStackTraceGetter::kElidedFramesMarker = + "... " GTEST_NAME_ " internal frames ..."; + +} // namespace internal + +// class TestEventListeners + +TestEventListeners::TestEventListeners() + : repeater_(new internal::TestEventRepeater()), + default_result_printer_(NULL), + default_xml_generator_(NULL) { +} + +TestEventListeners::~TestEventListeners() { delete repeater_; } + +// Returns the standard listener responsible for the default console +// output. Can be removed from the listeners list to shut down default +// console output. Note that removing this object from the listener list +// with Release transfers its ownership to the user. +void TestEventListeners::Append(TestEventListener* listener) { + repeater_->Append(listener); +} + +// Removes the given event listener from the list and returns it. It then +// becomes the caller's responsibility to delete the listener. Returns +// NULL if the listener is not found in the list. +TestEventListener* TestEventListeners::Release(TestEventListener* listener) { + if (listener == default_result_printer_) + default_result_printer_ = NULL; + else if (listener == default_xml_generator_) + default_xml_generator_ = NULL; + return repeater_->Release(listener); +} + +// Returns repeater that broadcasts the TestEventListener events to all +// subscribers. +TestEventListener* TestEventListeners::repeater() { return repeater_; } + +// Sets the default_result_printer attribute to the provided listener. +// The listener is also added to the listener list and previous +// default_result_printer is removed from it and deleted. The listener can +// also be NULL in which case it will not be added to the list. Does +// nothing if the previous and the current listener objects are the same. +void TestEventListeners::SetDefaultResultPrinter(TestEventListener* listener) { + if (default_result_printer_ != listener) { + // It is an error to pass this method a listener that is already in the + // list. + delete Release(default_result_printer_); + default_result_printer_ = listener; + if (listener != NULL) + Append(listener); + } +} + +// Sets the default_xml_generator attribute to the provided listener. The +// listener is also added to the listener list and previous +// default_xml_generator is removed from it and deleted. The listener can +// also be NULL in which case it will not be added to the list. Does +// nothing if the previous and the current listener objects are the same. +void TestEventListeners::SetDefaultXmlGenerator(TestEventListener* listener) { + if (default_xml_generator_ != listener) { + // It is an error to pass this method a listener that is already in the + // list. + delete Release(default_xml_generator_); + default_xml_generator_ = listener; + if (listener != NULL) + Append(listener); + } +} + +// Controls whether events will be forwarded by the repeater to the +// listeners in the list. +bool TestEventListeners::EventForwardingEnabled() const { + return repeater_->forwarding_enabled(); +} + +void TestEventListeners::SuppressEventForwarding() { + repeater_->set_forwarding_enabled(false); +} + +// class UnitTest + +// Gets the singleton UnitTest object. The first time this method is +// called, a UnitTest object is constructed and returned. Consecutive +// calls will return the same object. +// +// We don't protect this under mutex_ as a user is not supposed to +// call this before main() starts, from which point on the return +// value will never change. +UnitTest * UnitTest::GetInstance() { + // When compiled with MSVC 7.1 in optimized mode, destroying the + // UnitTest object upon exiting the program messes up the exit code, + // causing successful tests to appear failed. We have to use a + // different implementation in this case to bypass the compiler bug. + // This implementation makes the compiler happy, at the cost of + // leaking the UnitTest object. + + // CodeGear C++Builder insists on a public destructor for the + // default implementation. Use this implementation to keep good OO + // design with private destructor. + +#if (_MSC_VER == 1310 && !defined(_DEBUG)) || defined(__BORLANDC__) + static UnitTest* const instance = new UnitTest; + return instance; +#else + static UnitTest instance; + return &instance; +#endif // (_MSC_VER == 1310 && !defined(_DEBUG)) || defined(__BORLANDC__) +} + +// Gets the number of successful test cases. +int UnitTest::successful_test_case_count() const { + return impl()->successful_test_case_count(); +} + +// Gets the number of failed test cases. +int UnitTest::failed_test_case_count() const { + return impl()->failed_test_case_count(); +} + +// Gets the number of all test cases. +int UnitTest::total_test_case_count() const { + return impl()->total_test_case_count(); +} + +// Gets the number of all test cases that contain at least one test +// that should run. +int UnitTest::test_case_to_run_count() const { + return impl()->test_case_to_run_count(); +} + +// Gets the number of successful tests. +int UnitTest::successful_test_count() const { + return impl()->successful_test_count(); +} + +// Gets the number of failed tests. +int UnitTest::failed_test_count() const { return impl()->failed_test_count(); } + +// Gets the number of disabled tests. +int UnitTest::disabled_test_count() const { + return impl()->disabled_test_count(); +} + +// Gets the number of all tests. +int UnitTest::total_test_count() const { return impl()->total_test_count(); } + +// Gets the number of tests that should run. +int UnitTest::test_to_run_count() const { return impl()->test_to_run_count(); } + +// Gets the elapsed time, in milliseconds. +internal::TimeInMillis UnitTest::elapsed_time() const { + return impl()->elapsed_time(); +} + +// Returns true iff the unit test passed (i.e. all test cases passed). +bool UnitTest::Passed() const { return impl()->Passed(); } + +// Returns true iff the unit test failed (i.e. some test case failed +// or something outside of all tests failed). +bool UnitTest::Failed() const { return impl()->Failed(); } + +// Gets the i-th test case among all the test cases. i can range from 0 to +// total_test_case_count() - 1. If i is not in that range, returns NULL. +const TestCase* UnitTest::GetTestCase(int i) const { + return impl()->GetTestCase(i); +} + +// Gets the i-th test case among all the test cases. i can range from 0 to +// total_test_case_count() - 1. If i is not in that range, returns NULL. +TestCase* UnitTest::GetMutableTestCase(int i) { + return impl()->GetMutableTestCase(i); +} + +// Returns the list of event listeners that can be used to track events +// inside Google Test. +TestEventListeners& UnitTest::listeners() { + return *impl()->listeners(); +} + +// Registers and returns a global test environment. When a test +// program is run, all global test environments will be set-up in the +// order they were registered. After all tests in the program have +// finished, all global test environments will be torn-down in the +// *reverse* order they were registered. +// +// The UnitTest object takes ownership of the given environment. +// +// We don't protect this under mutex_, as we only support calling it +// from the main thread. +Environment* UnitTest::AddEnvironment(Environment* env) { + if (env == NULL) { + return NULL; + } + + impl_->environments().push_back(env); + return env; +} + +#if GTEST_HAS_EXCEPTIONS +// A failed Google Test assertion will throw an exception of this type +// when exceptions are enabled. We derive it from std::runtime_error, +// which is for errors presumably detectable only at run time. Since +// std::runtime_error inherits from std::exception, many testing +// frameworks know how to extract and print the message inside it. +class GoogleTestFailureException : public ::std::runtime_error { + public: + explicit GoogleTestFailureException(const TestPartResult& failure) + : ::std::runtime_error(PrintTestPartResultToString(failure).c_str()) {} +}; +#endif + +// Adds a TestPartResult to the current TestResult object. All Google Test +// assertion macros (e.g. ASSERT_TRUE, EXPECT_EQ, etc) eventually call +// this to report their results. The user code should use the +// assertion macros instead of calling this directly. +// L < mutex_ +void UnitTest::AddTestPartResult(TestPartResult::Type result_type, + const char* file_name, + int line_number, + const internal::String& message, + const internal::String& os_stack_trace) { + Message msg; + msg << message; + + internal::MutexLock lock(&mutex_); + if (impl_->gtest_trace_stack().size() > 0) { + msg << "\n" << GTEST_NAME_ << " trace:"; + + for (int i = static_cast(impl_->gtest_trace_stack().size()); + i > 0; --i) { + const internal::TraceInfo& trace = impl_->gtest_trace_stack()[i - 1]; + msg << "\n" << internal::FormatFileLocation(trace.file, trace.line) + << " " << trace.message; + } + } + + if (os_stack_trace.c_str() != NULL && !os_stack_trace.empty()) { + msg << internal::kStackTraceMarker << os_stack_trace; + } + + const TestPartResult result = + TestPartResult(result_type, file_name, line_number, + msg.GetString().c_str()); + impl_->GetTestPartResultReporterForCurrentThread()-> + ReportTestPartResult(result); + + if (result_type != TestPartResult::kSuccess) { + // gtest_break_on_failure takes precedence over + // gtest_throw_on_failure. This allows a user to set the latter + // in the code (perhaps in order to use Google Test assertions + // with another testing framework) and specify the former on the + // command line for debugging. + if (GTEST_FLAG(break_on_failure)) { +#if GTEST_OS_WINDOWS + // Using DebugBreak on Windows allows gtest to still break into a debugger + // when a failure happens and both the --gtest_break_on_failure and + // the --gtest_catch_exceptions flags are specified. + DebugBreak(); +#else + *static_cast(NULL) = 1; +#endif // GTEST_OS_WINDOWS + } else if (GTEST_FLAG(throw_on_failure)) { +#if GTEST_HAS_EXCEPTIONS + throw GoogleTestFailureException(result); +#else + // We cannot call abort() as it generates a pop-up in debug mode + // that cannot be suppressed in VC 7.1 or below. + exit(1); +#endif + } + } +} + +// Creates and adds a property to the current TestResult. If a property matching +// the supplied value already exists, updates its value instead. +void UnitTest::RecordPropertyForCurrentTest(const char* key, + const char* value) { + const TestProperty test_property(key, value); + impl_->current_test_result()->RecordProperty(test_property); +} + +// Runs all tests in this UnitTest object and prints the result. +// Returns 0 if successful, or 1 otherwise. +// +// We don't protect this under mutex_, as we only support calling it +// from the main thread. +int UnitTest::Run() { +#if GTEST_HAS_SEH + // Catch SEH-style exceptions. + + const bool in_death_test_child_process = + internal::GTEST_FLAG(internal_run_death_test).length() > 0; + + // Either the user wants Google Test to catch exceptions thrown by the + // tests or this is executing in the context of death test child + // process. In either case the user does not want to see pop-up dialogs + // about crashes - they are expected.. + if (GTEST_FLAG(catch_exceptions) || in_death_test_child_process) { +#if !GTEST_OS_WINDOWS_MOBILE + // SetErrorMode doesn't exist on CE. + SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOALIGNMENTFAULTEXCEPT | + SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX); +#endif // !GTEST_OS_WINDOWS_MOBILE + +#if (defined(_MSC_VER) || GTEST_OS_WINDOWS_MINGW) && !GTEST_OS_WINDOWS_MOBILE + // Death test children can be terminated with _abort(). On Windows, + // _abort() can show a dialog with a warning message. This forces the + // abort message to go to stderr instead. + _set_error_mode(_OUT_TO_STDERR); +#endif + +#if _MSC_VER >= 1400 && !GTEST_OS_WINDOWS_MOBILE + // In the debug version, Visual Studio pops up a separate dialog + // offering a choice to debug the aborted program. We need to suppress + // this dialog or it will pop up for every EXPECT/ASSERT_DEATH statement + // executed. Google Test will notify the user of any unexpected + // failure via stderr. + // + // VC++ doesn't define _set_abort_behavior() prior to the version 8.0. + // Users of prior VC versions shall suffer the agony and pain of + // clicking through the countless debug dialogs. + // TODO(vladl@google.com): find a way to suppress the abort dialog() in the + // debug mode when compiled with VC 7.1 or lower. + if (!GTEST_FLAG(break_on_failure)) + _set_abort_behavior( + 0x0, // Clear the following flags: + _WRITE_ABORT_MSG | _CALL_REPORTFAULT); // pop-up window, core dump. +#endif + } + + __try { + return impl_->RunAllTests(); + } __except(internal::UnitTestOptions::GTestShouldProcessSEH( + GetExceptionCode())) { + printf("Exception thrown with code 0x%x.\nFAIL\n", GetExceptionCode()); + fflush(stdout); + return 1; + } + +#else // We are on a compiler or platform that doesn't support SEH. + + return impl_->RunAllTests(); +#endif // GTEST_HAS_SEH +} + +// Returns the working directory when the first TEST() or TEST_F() was +// executed. +const char* UnitTest::original_working_dir() const { + return impl_->original_working_dir_.c_str(); +} + +// Returns the TestCase object for the test that's currently running, +// or NULL if no test is running. +// L < mutex_ +const TestCase* UnitTest::current_test_case() const { + internal::MutexLock lock(&mutex_); + return impl_->current_test_case(); +} + +// Returns the TestInfo object for the test that's currently running, +// or NULL if no test is running. +// L < mutex_ +const TestInfo* UnitTest::current_test_info() const { + internal::MutexLock lock(&mutex_); + return impl_->current_test_info(); +} + +// Returns the random seed used at the start of the current test run. +int UnitTest::random_seed() const { return impl_->random_seed(); } + +#if GTEST_HAS_PARAM_TEST +// Returns ParameterizedTestCaseRegistry object used to keep track of +// value-parameterized tests and instantiate and register them. +// L < mutex_ +internal::ParameterizedTestCaseRegistry& + UnitTest::parameterized_test_registry() { + return impl_->parameterized_test_registry(); +} +#endif // GTEST_HAS_PARAM_TEST + +// Creates an empty UnitTest. +UnitTest::UnitTest() { + impl_ = new internal::UnitTestImpl(this); +} + +// Destructor of UnitTest. +UnitTest::~UnitTest() { + delete impl_; +} + +// Pushes a trace defined by SCOPED_TRACE() on to the per-thread +// Google Test trace stack. +// L < mutex_ +void UnitTest::PushGTestTrace(const internal::TraceInfo& trace) { + internal::MutexLock lock(&mutex_); + impl_->gtest_trace_stack().push_back(trace); +} + +// Pops a trace from the per-thread Google Test trace stack. +// L < mutex_ +void UnitTest::PopGTestTrace() { + internal::MutexLock lock(&mutex_); + impl_->gtest_trace_stack().pop_back(); +} + +namespace internal { + +UnitTestImpl::UnitTestImpl(UnitTest* parent) + : parent_(parent), +#ifdef _MSC_VER +#pragma warning(push) // Saves the current warning state. +#pragma warning(disable:4355) // Temporarily disables warning 4355 + // (using this in initializer). + default_global_test_part_result_reporter_(this), + default_per_thread_test_part_result_reporter_(this), +#pragma warning(pop) // Restores the warning state again. +#else + default_global_test_part_result_reporter_(this), + default_per_thread_test_part_result_reporter_(this), +#endif // _MSC_VER + global_test_part_result_repoter_( + &default_global_test_part_result_reporter_), + per_thread_test_part_result_reporter_( + &default_per_thread_test_part_result_reporter_), +#if GTEST_HAS_PARAM_TEST + parameterized_test_registry_(), + parameterized_tests_registered_(false), +#endif // GTEST_HAS_PARAM_TEST + last_death_test_case_(-1), + current_test_case_(NULL), + current_test_info_(NULL), + ad_hoc_test_result_(), + os_stack_trace_getter_(NULL), + post_flag_parse_init_performed_(false), + random_seed_(0), // Will be overridden by the flag before first use. + random_(0), // Will be reseeded before first use. +#if GTEST_HAS_DEATH_TEST + elapsed_time_(0), + internal_run_death_test_flag_(NULL), + death_test_factory_(new DefaultDeathTestFactory) { +#else + elapsed_time_(0) { +#endif // GTEST_HAS_DEATH_TEST + listeners()->SetDefaultResultPrinter(new PrettyUnitTestResultPrinter); +} + +UnitTestImpl::~UnitTestImpl() { + // Deletes every TestCase. + ForEach(test_cases_, internal::Delete); + + // Deletes every Environment. + ForEach(environments_, internal::Delete); + + delete os_stack_trace_getter_; +} + +#if GTEST_HAS_DEATH_TEST +// Disables event forwarding if the control is currently in a death test +// subprocess. Must not be called before InitGoogleTest. +void UnitTestImpl::SuppressTestEventsIfInSubprocess() { + if (internal_run_death_test_flag_.get() != NULL) + listeners()->SuppressEventForwarding(); +} +#endif // GTEST_HAS_DEATH_TEST + +// Initializes event listeners performing XML output as specified by +// UnitTestOptions. Must not be called before InitGoogleTest. +void UnitTestImpl::ConfigureXmlOutput() { + const String& output_format = UnitTestOptions::GetOutputFormat(); + if (output_format == "xml") { + listeners()->SetDefaultXmlGenerator(new XmlUnitTestResultPrinter( + UnitTestOptions::GetAbsolutePathToOutputFile().c_str())); + } else if (output_format != "") { + printf("WARNING: unrecognized output format \"%s\" ignored.\n", + output_format.c_str()); + fflush(stdout); + } +} + +// Performs initialization dependent upon flag values obtained in +// ParseGoogleTestFlagsOnly. Is called from InitGoogleTest after the call to +// ParseGoogleTestFlagsOnly. In case a user neglects to call InitGoogleTest +// this function is also called from RunAllTests. Since this function can be +// called more than once, it has to be idempotent. +void UnitTestImpl::PostFlagParsingInit() { + // Ensures that this function does not execute more than once. + if (!post_flag_parse_init_performed_) { + post_flag_parse_init_performed_ = true; + +#if GTEST_HAS_DEATH_TEST + InitDeathTestSubprocessControlInfo(); + SuppressTestEventsIfInSubprocess(); +#endif // GTEST_HAS_DEATH_TEST + + // Registers parameterized tests. This makes parameterized tests + // available to the UnitTest reflection API without running + // RUN_ALL_TESTS. + RegisterParameterizedTests(); + + // Configures listeners for XML output. This makes it possible for users + // to shut down the default XML output before invoking RUN_ALL_TESTS. + ConfigureXmlOutput(); + } +} + +// A predicate that checks the name of a TestCase against a known +// value. +// +// This is used for implementation of the UnitTest class only. We put +// it in the anonymous namespace to prevent polluting the outer +// namespace. +// +// TestCaseNameIs is copyable. +class TestCaseNameIs { + public: + // Constructor. + explicit TestCaseNameIs(const String& name) + : name_(name) {} + + // Returns true iff the name of test_case matches name_. + bool operator()(const TestCase* test_case) const { + return test_case != NULL && strcmp(test_case->name(), name_.c_str()) == 0; + } + + private: + String name_; +}; + +// Finds and returns a TestCase with the given name. If one doesn't +// exist, creates one and returns it. It's the CALLER'S +// RESPONSIBILITY to ensure that this function is only called WHEN THE +// TESTS ARE NOT SHUFFLED. +// +// Arguments: +// +// test_case_name: name of the test case +// set_up_tc: pointer to the function that sets up the test case +// tear_down_tc: pointer to the function that tears down the test case +TestCase* UnitTestImpl::GetTestCase(const char* test_case_name, + const char* comment, + Test::SetUpTestCaseFunc set_up_tc, + Test::TearDownTestCaseFunc tear_down_tc) { + // Can we find a TestCase with the given name? + const std::vector::const_iterator test_case = + std::find_if(test_cases_.begin(), test_cases_.end(), + TestCaseNameIs(test_case_name)); + + if (test_case != test_cases_.end()) + return *test_case; + + // No. Let's create one. + TestCase* const new_test_case = + new TestCase(test_case_name, comment, set_up_tc, tear_down_tc); + + // Is this a death test case? + if (internal::UnitTestOptions::MatchesFilter(String(test_case_name), + kDeathTestCaseFilter)) { + // Yes. Inserts the test case after the last death test case + // defined so far. This only works when the test cases haven't + // been shuffled. Otherwise we may end up running a death test + // after a non-death test. + ++last_death_test_case_; + test_cases_.insert(test_cases_.begin() + last_death_test_case_, + new_test_case); + } else { + // No. Appends to the end of the list. + test_cases_.push_back(new_test_case); + } + + test_case_indices_.push_back(static_cast(test_case_indices_.size())); + return new_test_case; +} + +// Helpers for setting up / tearing down the given environment. They +// are for use in the ForEach() function. +static void SetUpEnvironment(Environment* env) { env->SetUp(); } +static void TearDownEnvironment(Environment* env) { env->TearDown(); } + +// Runs all tests in this UnitTest object, prints the result, and +// returns 0 if all tests are successful, or 1 otherwise. If any +// exception is thrown during a test on Windows, this test is +// considered to be failed, but the rest of the tests will still be +// run. (We disable exceptions on Linux and Mac OS X, so the issue +// doesn't apply there.) +// When parameterized tests are enabled, it expands and registers +// parameterized tests first in RegisterParameterizedTests(). +// All other functions called from RunAllTests() may safely assume that +// parameterized tests are ready to be counted and run. +int UnitTestImpl::RunAllTests() { + // Makes sure InitGoogleTest() was called. + if (!GTestIsInitialized()) { + printf("%s", + "\nThis test program did NOT call ::testing::InitGoogleTest " + "before calling RUN_ALL_TESTS(). Please fix it.\n"); + return 1; + } + + // Do not run any test if the --help flag was specified. + if (g_help_flag) + return 0; + + // Repeats the call to the post-flag parsing initialization in case the + // user didn't call InitGoogleTest. + PostFlagParsingInit(); + + // Even if sharding is not on, test runners may want to use the + // GTEST_SHARD_STATUS_FILE to query whether the test supports the sharding + // protocol. + internal::WriteToShardStatusFileIfNeeded(); + + // True iff we are in a subprocess for running a thread-safe-style + // death test. + bool in_subprocess_for_death_test = false; + +#if GTEST_HAS_DEATH_TEST + in_subprocess_for_death_test = (internal_run_death_test_flag_.get() != NULL); +#endif // GTEST_HAS_DEATH_TEST + + const bool should_shard = ShouldShard(kTestTotalShards, kTestShardIndex, + in_subprocess_for_death_test); + + // Compares the full test names with the filter to decide which + // tests to run. + const bool has_tests_to_run = FilterTests(should_shard + ? HONOR_SHARDING_PROTOCOL + : IGNORE_SHARDING_PROTOCOL) > 0; + + // Lists the tests and exits if the --gtest_list_tests flag was specified. + if (GTEST_FLAG(list_tests)) { + // This must be called *after* FilterTests() has been called. + ListTestsMatchingFilter(); + return 0; + } + + random_seed_ = GTEST_FLAG(shuffle) ? + GetRandomSeedFromFlag(GTEST_FLAG(random_seed)) : 0; + + // True iff at least one test has failed. + bool failed = false; + + TestEventListener* repeater = listeners()->repeater(); + + repeater->OnTestProgramStart(*parent_); + + // How many times to repeat the tests? We don't want to repeat them + // when we are inside the subprocess of a death test. + const int repeat = in_subprocess_for_death_test ? 1 : GTEST_FLAG(repeat); + // Repeats forever if the repeat count is negative. + const bool forever = repeat < 0; + for (int i = 0; forever || i != repeat; i++) { + ClearResult(); + + const TimeInMillis start = GetTimeInMillis(); + + // Shuffles test cases and tests if requested. + if (has_tests_to_run && GTEST_FLAG(shuffle)) { + random()->Reseed(random_seed_); + // This should be done before calling OnTestIterationStart(), + // such that a test event listener can see the actual test order + // in the event. + ShuffleTests(); + } + + // Tells the unit test event listeners that the tests are about to start. + repeater->OnTestIterationStart(*parent_, i); + + // Runs each test case if there is at least one test to run. + if (has_tests_to_run) { + // Sets up all environments beforehand. + repeater->OnEnvironmentsSetUpStart(*parent_); + ForEach(environments_, SetUpEnvironment); + repeater->OnEnvironmentsSetUpEnd(*parent_); + + // Runs the tests only if there was no fatal failure during global + // set-up. + if (!Test::HasFatalFailure()) { + for (int test_index = 0; test_index < total_test_case_count(); + test_index++) { + GetMutableTestCase(test_index)->Run(); + } + } + + // Tears down all environments in reverse order afterwards. + repeater->OnEnvironmentsTearDownStart(*parent_); + std::for_each(environments_.rbegin(), environments_.rend(), + TearDownEnvironment); + repeater->OnEnvironmentsTearDownEnd(*parent_); + } + + elapsed_time_ = GetTimeInMillis() - start; + + // Tells the unit test event listener that the tests have just finished. + repeater->OnTestIterationEnd(*parent_, i); + + // Gets the result and clears it. + if (!Passed()) { + failed = true; + } + + // Restores the original test order after the iteration. This + // allows the user to quickly repro a failure that happens in the + // N-th iteration without repeating the first (N - 1) iterations. + // This is not enclosed in "if (GTEST_FLAG(shuffle)) { ... }", in + // case the user somehow changes the value of the flag somewhere + // (it's always safe to unshuffle the tests). + UnshuffleTests(); + + if (GTEST_FLAG(shuffle)) { + // Picks a new random seed for each iteration. + random_seed_ = GetNextRandomSeed(random_seed_); + } + } + + repeater->OnTestProgramEnd(*parent_); + + // Returns 0 if all tests passed, or 1 other wise. + return failed ? 1 : 0; +} + +// Reads the GTEST_SHARD_STATUS_FILE environment variable, and creates the file +// if the variable is present. If a file already exists at this location, this +// function will write over it. If the variable is present, but the file cannot +// be created, prints an error and exits. +void WriteToShardStatusFileIfNeeded() { + const char* const test_shard_file = posix::GetEnv(kTestShardStatusFile); + if (test_shard_file != NULL) { + FILE* const file = posix::FOpen(test_shard_file, "w"); + if (file == NULL) { + ColoredPrintf(COLOR_RED, + "Could not write to the test shard status file \"%s\" " + "specified by the %s environment variable.\n", + test_shard_file, kTestShardStatusFile); + fflush(stdout); + exit(EXIT_FAILURE); + } + fclose(file); + } +} + +// Checks whether sharding is enabled by examining the relevant +// environment variable values. If the variables are present, +// but inconsistent (i.e., shard_index >= total_shards), prints +// an error and exits. If in_subprocess_for_death_test, sharding is +// disabled because it must only be applied to the original test +// process. Otherwise, we could filter out death tests we intended to execute. +bool ShouldShard(const char* total_shards_env, + const char* shard_index_env, + bool in_subprocess_for_death_test) { + if (in_subprocess_for_death_test) { + return false; + } + + const Int32 total_shards = Int32FromEnvOrDie(total_shards_env, -1); + const Int32 shard_index = Int32FromEnvOrDie(shard_index_env, -1); + + if (total_shards == -1 && shard_index == -1) { + return false; + } else if (total_shards == -1 && shard_index != -1) { + const Message msg = Message() + << "Invalid environment variables: you have " + << kTestShardIndex << " = " << shard_index + << ", but have left " << kTestTotalShards << " unset.\n"; + ColoredPrintf(COLOR_RED, msg.GetString().c_str()); + fflush(stdout); + exit(EXIT_FAILURE); + } else if (total_shards != -1 && shard_index == -1) { + const Message msg = Message() + << "Invalid environment variables: you have " + << kTestTotalShards << " = " << total_shards + << ", but have left " << kTestShardIndex << " unset.\n"; + ColoredPrintf(COLOR_RED, msg.GetString().c_str()); + fflush(stdout); + exit(EXIT_FAILURE); + } else if (shard_index < 0 || shard_index >= total_shards) { + const Message msg = Message() + << "Invalid environment variables: we require 0 <= " + << kTestShardIndex << " < " << kTestTotalShards + << ", but you have " << kTestShardIndex << "=" << shard_index + << ", " << kTestTotalShards << "=" << total_shards << ".\n"; + ColoredPrintf(COLOR_RED, msg.GetString().c_str()); + fflush(stdout); + exit(EXIT_FAILURE); + } + + return total_shards > 1; +} + +// Parses the environment variable var as an Int32. If it is unset, +// returns default_val. If it is not an Int32, prints an error +// and aborts. +Int32 Int32FromEnvOrDie(const char* const var, Int32 default_val) { + const char* str_val = posix::GetEnv(var); + if (str_val == NULL) { + return default_val; + } + + Int32 result; + if (!ParseInt32(Message() << "The value of environment variable " << var, + str_val, &result)) { + exit(EXIT_FAILURE); + } + return result; +} + +// Given the total number of shards, the shard index, and the test id, +// returns true iff the test should be run on this shard. The test id is +// some arbitrary but unique non-negative integer assigned to each test +// method. Assumes that 0 <= shard_index < total_shards. +bool ShouldRunTestOnShard(int total_shards, int shard_index, int test_id) { + return (test_id % total_shards) == shard_index; +} + +// Compares the name of each test with the user-specified filter to +// decide whether the test should be run, then records the result in +// each TestCase and TestInfo object. +// If shard_tests == true, further filters tests based on sharding +// variables in the environment - see +// http://code.google.com/p/googletest/wiki/GoogleTestAdvancedGuide. +// Returns the number of tests that should run. +int UnitTestImpl::FilterTests(ReactionToSharding shard_tests) { + const Int32 total_shards = shard_tests == HONOR_SHARDING_PROTOCOL ? + Int32FromEnvOrDie(kTestTotalShards, -1) : -1; + const Int32 shard_index = shard_tests == HONOR_SHARDING_PROTOCOL ? + Int32FromEnvOrDie(kTestShardIndex, -1) : -1; + + // num_runnable_tests are the number of tests that will + // run across all shards (i.e., match filter and are not disabled). + // num_selected_tests are the number of tests to be run on + // this shard. + int num_runnable_tests = 0; + int num_selected_tests = 0; + for (size_t i = 0; i < test_cases_.size(); i++) { + TestCase* const test_case = test_cases_[i]; + const String &test_case_name = test_case->name(); + test_case->set_should_run(false); + + for (size_t j = 0; j < test_case->test_info_list().size(); j++) { + TestInfo* const test_info = test_case->test_info_list()[j]; + const String test_name(test_info->name()); + // A test is disabled if test case name or test name matches + // kDisableTestFilter. + const bool is_disabled = + internal::UnitTestOptions::MatchesFilter(test_case_name, + kDisableTestFilter) || + internal::UnitTestOptions::MatchesFilter(test_name, + kDisableTestFilter); + test_info->impl()->set_is_disabled(is_disabled); + + const bool matches_filter = + internal::UnitTestOptions::FilterMatchesTest(test_case_name, + test_name); + test_info->impl()->set_matches_filter(matches_filter); + + const bool is_runnable = + (GTEST_FLAG(also_run_disabled_tests) || !is_disabled) && + matches_filter; + + const bool is_selected = is_runnable && + (shard_tests == IGNORE_SHARDING_PROTOCOL || + ShouldRunTestOnShard(total_shards, shard_index, + num_runnable_tests)); + + num_runnable_tests += is_runnable; + num_selected_tests += is_selected; + + test_info->impl()->set_should_run(is_selected); + test_case->set_should_run(test_case->should_run() || is_selected); + } + } + return num_selected_tests; +} + +// Prints the names of the tests matching the user-specified filter flag. +void UnitTestImpl::ListTestsMatchingFilter() { + for (size_t i = 0; i < test_cases_.size(); i++) { + const TestCase* const test_case = test_cases_[i]; + bool printed_test_case_name = false; + + for (size_t j = 0; j < test_case->test_info_list().size(); j++) { + const TestInfo* const test_info = + test_case->test_info_list()[j]; + if (test_info->matches_filter()) { + if (!printed_test_case_name) { + printed_test_case_name = true; + printf("%s.\n", test_case->name()); + } + printf(" %s\n", test_info->name()); + } + } + } + fflush(stdout); +} + +// Sets the OS stack trace getter. +// +// Does nothing if the input and the current OS stack trace getter are +// the same; otherwise, deletes the old getter and makes the input the +// current getter. +void UnitTestImpl::set_os_stack_trace_getter( + OsStackTraceGetterInterface* getter) { + if (os_stack_trace_getter_ != getter) { + delete os_stack_trace_getter_; + os_stack_trace_getter_ = getter; + } +} + +// Returns the current OS stack trace getter if it is not NULL; +// otherwise, creates an OsStackTraceGetter, makes it the current +// getter, and returns it. +OsStackTraceGetterInterface* UnitTestImpl::os_stack_trace_getter() { + if (os_stack_trace_getter_ == NULL) { + os_stack_trace_getter_ = new OsStackTraceGetter; + } + + return os_stack_trace_getter_; +} + +// Returns the TestResult for the test that's currently running, or +// the TestResult for the ad hoc test if no test is running. +TestResult* UnitTestImpl::current_test_result() { + return current_test_info_ ? + current_test_info_->impl()->result() : &ad_hoc_test_result_; +} + +// Shuffles all test cases, and the tests within each test case, +// making sure that death tests are still run first. +void UnitTestImpl::ShuffleTests() { + // Shuffles the death test cases. + ShuffleRange(random(), 0, last_death_test_case_ + 1, &test_case_indices_); + + // Shuffles the non-death test cases. + ShuffleRange(random(), last_death_test_case_ + 1, + static_cast(test_cases_.size()), &test_case_indices_); + + // Shuffles the tests inside each test case. + for (size_t i = 0; i < test_cases_.size(); i++) { + test_cases_[i]->ShuffleTests(random()); + } +} + +// Restores the test cases and tests to their order before the first shuffle. +void UnitTestImpl::UnshuffleTests() { + for (size_t i = 0; i < test_cases_.size(); i++) { + // Unshuffles the tests in each test case. + test_cases_[i]->UnshuffleTests(); + // Resets the index of each test case. + test_case_indices_[i] = static_cast(i); + } +} + +// TestInfoImpl constructor. The new instance assumes ownership of the test +// factory object. +TestInfoImpl::TestInfoImpl(TestInfo* parent, + const char* a_test_case_name, + const char* a_name, + const char* a_test_case_comment, + const char* a_comment, + TypeId a_fixture_class_id, + internal::TestFactoryBase* factory) : + parent_(parent), + test_case_name_(String(a_test_case_name)), + name_(String(a_name)), + test_case_comment_(String(a_test_case_comment)), + comment_(String(a_comment)), + fixture_class_id_(a_fixture_class_id), + should_run_(false), + is_disabled_(false), + matches_filter_(false), + factory_(factory) { +} + +// TestInfoImpl destructor. +TestInfoImpl::~TestInfoImpl() { + delete factory_; +} + +// Returns the current OS stack trace as a String. +// +// The maximum number of stack frames to be included is specified by +// the gtest_stack_trace_depth flag. The skip_count parameter +// specifies the number of top frames to be skipped, which doesn't +// count against the number of frames to be included. +// +// For example, if Foo() calls Bar(), which in turn calls +// GetCurrentOsStackTraceExceptTop(..., 1), Foo() will be included in +// the trace but Bar() and GetCurrentOsStackTraceExceptTop() won't. +String GetCurrentOsStackTraceExceptTop(UnitTest* /*unit_test*/, + int skip_count) { + // We pass skip_count + 1 to skip this wrapper function in addition + // to what the user really wants to skip. + return GetUnitTestImpl()->CurrentOsStackTraceExceptTop(skip_count + 1); +} + +// Used by the GTEST_HIDE_UNREACHABLE_CODE_ macro to suppress unreachable +// code warnings. +namespace { +class ClassUniqueToAlwaysTrue {}; +} + +bool IsTrue(bool condition) { return condition; } + +bool AlwaysTrue() { +#if GTEST_HAS_EXCEPTIONS + // This condition is always false so AlwaysTrue() never actually throws, + // but it makes the compiler think that it may throw. + if (IsTrue(false)) + throw ClassUniqueToAlwaysTrue(); +#endif // GTEST_HAS_EXCEPTIONS + return true; +} + +// If *pstr starts with the given prefix, modifies *pstr to be right +// past the prefix and returns true; otherwise leaves *pstr unchanged +// and returns false. None of pstr, *pstr, and prefix can be NULL. +bool SkipPrefix(const char* prefix, const char** pstr) { + const size_t prefix_len = strlen(prefix); + if (strncmp(*pstr, prefix, prefix_len) == 0) { + *pstr += prefix_len; + return true; + } + return false; +} + +// Parses a string as a command line flag. The string should have +// the format "--flag=value". When def_optional is true, the "=value" +// part can be omitted. +// +// Returns the value of the flag, or NULL if the parsing failed. +const char* ParseFlagValue(const char* str, + const char* flag, + bool def_optional) { + // str and flag must not be NULL. + if (str == NULL || flag == NULL) return NULL; + + // The flag must start with "--" followed by GTEST_FLAG_PREFIX_. + const String flag_str = String::Format("--%s%s", GTEST_FLAG_PREFIX_, flag); + const size_t flag_len = flag_str.length(); + if (strncmp(str, flag_str.c_str(), flag_len) != 0) return NULL; + + // Skips the flag name. + const char* flag_end = str + flag_len; + + // When def_optional is true, it's OK to not have a "=value" part. + if (def_optional && (flag_end[0] == '\0')) { + return flag_end; + } + + // If def_optional is true and there are more characters after the + // flag name, or if def_optional is false, there must be a '=' after + // the flag name. + if (flag_end[0] != '=') return NULL; + + // Returns the string after "=". + return flag_end + 1; +} + +// Parses a string for a bool flag, in the form of either +// "--flag=value" or "--flag". +// +// In the former case, the value is taken as true as long as it does +// not start with '0', 'f', or 'F'. +// +// In the latter case, the value is taken as true. +// +// On success, stores the value of the flag in *value, and returns +// true. On failure, returns false without changing *value. +bool ParseBoolFlag(const char* str, const char* flag, bool* value) { + // Gets the value of the flag as a string. + const char* const value_str = ParseFlagValue(str, flag, true); + + // Aborts if the parsing failed. + if (value_str == NULL) return false; + + // Converts the string value to a bool. + *value = !(*value_str == '0' || *value_str == 'f' || *value_str == 'F'); + return true; +} + +// Parses a string for an Int32 flag, in the form of +// "--flag=value". +// +// On success, stores the value of the flag in *value, and returns +// true. On failure, returns false without changing *value. +bool ParseInt32Flag(const char* str, const char* flag, Int32* value) { + // Gets the value of the flag as a string. + const char* const value_str = ParseFlagValue(str, flag, false); + + // Aborts if the parsing failed. + if (value_str == NULL) return false; + + // Sets *value to the value of the flag. + return ParseInt32(Message() << "The value of flag --" << flag, + value_str, value); +} + +// Parses a string for a string flag, in the form of +// "--flag=value". +// +// On success, stores the value of the flag in *value, and returns +// true. On failure, returns false without changing *value. +bool ParseStringFlag(const char* str, const char* flag, String* value) { + // Gets the value of the flag as a string. + const char* const value_str = ParseFlagValue(str, flag, false); + + // Aborts if the parsing failed. + if (value_str == NULL) return false; + + // Sets *value to the value of the flag. + *value = value_str; + return true; +} + +// Determines whether a string has a prefix that Google Test uses for its +// flags, i.e., starts with GTEST_FLAG_PREFIX_ or GTEST_FLAG_PREFIX_DASH_. +// If Google Test detects that a command line flag has its prefix but is not +// recognized, it will print its help message. Flags starting with +// GTEST_INTERNAL_PREFIX_ followed by "internal_" are considered Google Test +// internal flags and do not trigger the help message. +static bool HasGoogleTestFlagPrefix(const char* str) { + return (SkipPrefix("--", &str) || + SkipPrefix("-", &str) || + SkipPrefix("/", &str)) && + !SkipPrefix(GTEST_FLAG_PREFIX_ "internal_", &str) && + (SkipPrefix(GTEST_FLAG_PREFIX_, &str) || + SkipPrefix(GTEST_FLAG_PREFIX_DASH_, &str)); +} + +// Prints a string containing code-encoded text. The following escape +// sequences can be used in the string to control the text color: +// +// @@ prints a single '@' character. +// @R changes the color to red. +// @G changes the color to green. +// @Y changes the color to yellow. +// @D changes to the default terminal text color. +// +// TODO(wan@google.com): Write tests for this once we add stdout +// capturing to Google Test. +static void PrintColorEncoded(const char* str) { + GTestColor color = COLOR_DEFAULT; // The current color. + + // Conceptually, we split the string into segments divided by escape + // sequences. Then we print one segment at a time. At the end of + // each iteration, the str pointer advances to the beginning of the + // next segment. + for (;;) { + const char* p = strchr(str, '@'); + if (p == NULL) { + ColoredPrintf(color, "%s", str); + return; + } + + ColoredPrintf(color, "%s", String(str, p - str).c_str()); + + const char ch = p[1]; + str = p + 2; + if (ch == '@') { + ColoredPrintf(color, "@"); + } else if (ch == 'D') { + color = COLOR_DEFAULT; + } else if (ch == 'R') { + color = COLOR_RED; + } else if (ch == 'G') { + color = COLOR_GREEN; + } else if (ch == 'Y') { + color = COLOR_YELLOW; + } else { + --str; + } + } +} + +static const char kColorEncodedHelpMessage[] = +"This program contains tests written using " GTEST_NAME_ ". You can use the\n" +"following command line flags to control its behavior:\n" +"\n" +"Test Selection:\n" +" @G--" GTEST_FLAG_PREFIX_ "list_tests@D\n" +" List the names of all tests instead of running them. The name of\n" +" TEST(Foo, Bar) is \"Foo.Bar\".\n" +" @G--" GTEST_FLAG_PREFIX_ "filter=@YPOSTIVE_PATTERNS" + "[@G-@YNEGATIVE_PATTERNS]@D\n" +" Run only the tests whose name matches one of the positive patterns but\n" +" none of the negative patterns. '?' matches any single character; '*'\n" +" matches any substring; ':' separates two patterns.\n" +" @G--" GTEST_FLAG_PREFIX_ "also_run_disabled_tests@D\n" +" Run all disabled tests too.\n" +"\n" +"Test Execution:\n" +" @G--" GTEST_FLAG_PREFIX_ "repeat=@Y[COUNT]@D\n" +" Run the tests repeatedly; use a negative count to repeat forever.\n" +" @G--" GTEST_FLAG_PREFIX_ "shuffle@D\n" +" Randomize tests' orders on every iteration.\n" +" @G--" GTEST_FLAG_PREFIX_ "random_seed=@Y[NUMBER]@D\n" +" Random number seed to use for shuffling test orders (between 1 and\n" +" 99999, or 0 to use a seed based on the current time).\n" +"\n" +"Test Output:\n" +" @G--" GTEST_FLAG_PREFIX_ "color=@Y(@Gyes@Y|@Gno@Y|@Gauto@Y)@D\n" +" Enable/disable colored output. The default is @Gauto@D.\n" +" -@G-" GTEST_FLAG_PREFIX_ "print_time=0@D\n" +" Don't print the elapsed time of each test.\n" +" @G--" GTEST_FLAG_PREFIX_ "output=xml@Y[@G:@YDIRECTORY_PATH@G" + GTEST_PATH_SEP_ "@Y|@G:@YFILE_PATH]@D\n" +" Generate an XML report in the given directory or with the given file\n" +" name. @YFILE_PATH@D defaults to @Gtest_details.xml@D.\n" +"\n" +"Assertion Behavior:\n" +#if GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS +" @G--" GTEST_FLAG_PREFIX_ "death_test_style=@Y(@Gfast@Y|@Gthreadsafe@Y)@D\n" +" Set the default death test style.\n" +#endif // GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS +" @G--" GTEST_FLAG_PREFIX_ "break_on_failure@D\n" +" Turn assertion failures into debugger break-points.\n" +" @G--" GTEST_FLAG_PREFIX_ "throw_on_failure@D\n" +" Turn assertion failures into C++ exceptions.\n" +#if GTEST_OS_WINDOWS +" @G--" GTEST_FLAG_PREFIX_ "catch_exceptions@D\n" +" Suppress pop-ups caused by exceptions.\n" +#endif // GTEST_OS_WINDOWS +"\n" +"Except for @G--" GTEST_FLAG_PREFIX_ "list_tests@D, you can alternatively set " + "the corresponding\n" +"environment variable of a flag (all letters in upper-case). For example, to\n" +"disable colored text output, you can either specify @G--" GTEST_FLAG_PREFIX_ + "color=no@D or set\n" +"the @G" GTEST_FLAG_PREFIX_UPPER_ "COLOR@D environment variable to @Gno@D.\n" +"\n" +"For more information, please read the " GTEST_NAME_ " documentation at\n" +"@G" GTEST_PROJECT_URL_ "@D. If you find a bug in " GTEST_NAME_ "\n" +"(not one in your own code or tests), please report it to\n" +"@G<" GTEST_DEV_EMAIL_ ">@D.\n"; + +// Parses the command line for Google Test flags, without initializing +// other parts of Google Test. The type parameter CharType can be +// instantiated to either char or wchar_t. +template +void ParseGoogleTestFlagsOnlyImpl(int* argc, CharType** argv) { + for (int i = 1; i < *argc; i++) { + const String arg_string = StreamableToString(argv[i]); + const char* const arg = arg_string.c_str(); + + using internal::ParseBoolFlag; + using internal::ParseInt32Flag; + using internal::ParseStringFlag; + + // Do we see a Google Test flag? + if (ParseBoolFlag(arg, kAlsoRunDisabledTestsFlag, + >EST_FLAG(also_run_disabled_tests)) || + ParseBoolFlag(arg, kBreakOnFailureFlag, + >EST_FLAG(break_on_failure)) || + ParseBoolFlag(arg, kCatchExceptionsFlag, + >EST_FLAG(catch_exceptions)) || + ParseStringFlag(arg, kColorFlag, >EST_FLAG(color)) || + ParseStringFlag(arg, kDeathTestStyleFlag, + >EST_FLAG(death_test_style)) || + ParseBoolFlag(arg, kDeathTestUseFork, + >EST_FLAG(death_test_use_fork)) || + ParseStringFlag(arg, kFilterFlag, >EST_FLAG(filter)) || + ParseStringFlag(arg, kInternalRunDeathTestFlag, + >EST_FLAG(internal_run_death_test)) || + ParseBoolFlag(arg, kListTestsFlag, >EST_FLAG(list_tests)) || + ParseStringFlag(arg, kOutputFlag, >EST_FLAG(output)) || + ParseBoolFlag(arg, kPrintTimeFlag, >EST_FLAG(print_time)) || + ParseInt32Flag(arg, kRandomSeedFlag, >EST_FLAG(random_seed)) || + ParseInt32Flag(arg, kRepeatFlag, >EST_FLAG(repeat)) || + ParseBoolFlag(arg, kShuffleFlag, >EST_FLAG(shuffle)) || + ParseInt32Flag(arg, kStackTraceDepthFlag, + >EST_FLAG(stack_trace_depth)) || + ParseBoolFlag(arg, kThrowOnFailureFlag, >EST_FLAG(throw_on_failure)) + ) { + // Yes. Shift the remainder of the argv list left by one. Note + // that argv has (*argc + 1) elements, the last one always being + // NULL. The following loop moves the trailing NULL element as + // well. + for (int j = i; j != *argc; j++) { + argv[j] = argv[j + 1]; + } + + // Decrements the argument count. + (*argc)--; + + // We also need to decrement the iterator as we just removed + // an element. + i--; + } else if (arg_string == "--help" || arg_string == "-h" || + arg_string == "-?" || arg_string == "/?" || + HasGoogleTestFlagPrefix(arg)) { + // Both help flag and unrecognized Google Test flags (excluding + // internal ones) trigger help display. + g_help_flag = true; + } + } + + if (g_help_flag) { + // We print the help here instead of in RUN_ALL_TESTS(), as the + // latter may not be called at all if the user is using Google + // Test with another testing framework. + PrintColorEncoded(kColorEncodedHelpMessage); + } +} + +// Parses the command line for Google Test flags, without initializing +// other parts of Google Test. +void ParseGoogleTestFlagsOnly(int* argc, char** argv) { + ParseGoogleTestFlagsOnlyImpl(argc, argv); +} +void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv) { + ParseGoogleTestFlagsOnlyImpl(argc, argv); +} + +// The internal implementation of InitGoogleTest(). +// +// The type parameter CharType can be instantiated to either char or +// wchar_t. +template +void InitGoogleTestImpl(int* argc, CharType** argv) { + g_init_gtest_count++; + + // We don't want to run the initialization code twice. + if (g_init_gtest_count != 1) return; + + if (*argc <= 0) return; + + internal::g_executable_path = internal::StreamableToString(argv[0]); + +#if GTEST_HAS_DEATH_TEST + g_argvs.clear(); + for (int i = 0; i != *argc; i++) { + g_argvs.push_back(StreamableToString(argv[i])); + } +#endif // GTEST_HAS_DEATH_TEST + + ParseGoogleTestFlagsOnly(argc, argv); + GetUnitTestImpl()->PostFlagParsingInit(); +} + +} // namespace internal + +// Initializes Google Test. This must be called before calling +// RUN_ALL_TESTS(). In particular, it parses a command line for the +// flags that Google Test recognizes. Whenever a Google Test flag is +// seen, it is removed from argv, and *argc is decremented. +// +// No value is returned. Instead, the Google Test flag variables are +// updated. +// +// Calling the function for the second time has no user-visible effect. +void InitGoogleTest(int* argc, char** argv) { + internal::InitGoogleTestImpl(argc, argv); +} + +// This overloaded version can be used in Windows programs compiled in +// UNICODE mode. +void InitGoogleTest(int* argc, wchar_t** argv) { + internal::InitGoogleTestImpl(argc, argv); +} + +} // namespace testing +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: wan@google.com (Zhanyong Wan), vladl@google.com (Vlad Losev) +// +// This file implements death tests. + + +#if GTEST_HAS_DEATH_TEST + +#if GTEST_OS_MAC +#include +#endif // GTEST_OS_MAC + +#include +#include +#include +#include + +#if GTEST_OS_WINDOWS +#include +#else +#include +#include +#endif // GTEST_OS_WINDOWS + +#endif // GTEST_HAS_DEATH_TEST + + +// Indicates that this translation unit is part of Google Test's +// implementation. It must come before gtest-internal-inl.h is +// included, or there will be a compiler error. This trick is to +// prevent a user from accidentally including gtest-internal-inl.h in +// his code. +#define GTEST_IMPLEMENTATION_ 1 +#undef GTEST_IMPLEMENTATION_ + +namespace testing { + +// Constants. + +// The default death test style. +static const char kDefaultDeathTestStyle[] = "fast"; + +GTEST_DEFINE_string_( + death_test_style, + internal::StringFromGTestEnv("death_test_style", kDefaultDeathTestStyle), + "Indicates how to run a death test in a forked child process: " + "\"threadsafe\" (child process re-executes the test binary " + "from the beginning, running only the specific death test) or " + "\"fast\" (child process runs the death test immediately " + "after forking)."); + +GTEST_DEFINE_bool_( + death_test_use_fork, + internal::BoolFromGTestEnv("death_test_use_fork", false), + "Instructs to use fork()/_exit() instead of clone() in death tests. " + "Ignored and always uses fork() on POSIX systems where clone() is not " + "implemented. Useful when running under valgrind or similar tools if " + "those do not support clone(). Valgrind 3.3.1 will just fail if " + "it sees an unsupported combination of clone() flags. " + "It is not recommended to use this flag w/o valgrind though it will " + "work in 99% of the cases. Once valgrind is fixed, this flag will " + "most likely be removed."); + +namespace internal { +GTEST_DEFINE_string_( + internal_run_death_test, "", + "Indicates the file, line number, temporal index of " + "the single death test to run, and a file descriptor to " + "which a success code may be sent, all separated by " + "colons. This flag is specified if and only if the current " + "process is a sub-process launched for running a thread-safe " + "death test. FOR INTERNAL USE ONLY."); +} // namespace internal + +#if GTEST_HAS_DEATH_TEST + +// ExitedWithCode constructor. +ExitedWithCode::ExitedWithCode(int exit_code) : exit_code_(exit_code) { +} + +// ExitedWithCode function-call operator. +bool ExitedWithCode::operator()(int exit_status) const { +#if GTEST_OS_WINDOWS + return exit_status == exit_code_; +#else + return WIFEXITED(exit_status) && WEXITSTATUS(exit_status) == exit_code_; +#endif // GTEST_OS_WINDOWS +} + +#if !GTEST_OS_WINDOWS +// KilledBySignal constructor. +KilledBySignal::KilledBySignal(int signum) : signum_(signum) { +} + +// KilledBySignal function-call operator. +bool KilledBySignal::operator()(int exit_status) const { + return WIFSIGNALED(exit_status) && WTERMSIG(exit_status) == signum_; +} +#endif // !GTEST_OS_WINDOWS + +namespace internal { + +// Utilities needed for death tests. + +// Generates a textual description of a given exit code, in the format +// specified by wait(2). +static String ExitSummary(int exit_code) { + Message m; +#if GTEST_OS_WINDOWS + m << "Exited with exit status " << exit_code; +#else + if (WIFEXITED(exit_code)) { + m << "Exited with exit status " << WEXITSTATUS(exit_code); + } else if (WIFSIGNALED(exit_code)) { + m << "Terminated by signal " << WTERMSIG(exit_code); + } +#ifdef WCOREDUMP + if (WCOREDUMP(exit_code)) { + m << " (core dumped)"; + } +#endif +#endif // GTEST_OS_WINDOWS + return m.GetString(); +} + +// Returns true if exit_status describes a process that was terminated +// by a signal, or exited normally with a nonzero exit code. +bool ExitedUnsuccessfully(int exit_status) { + return !ExitedWithCode(0)(exit_status); +} + +#if !GTEST_OS_WINDOWS +// Generates a textual failure message when a death test finds more than +// one thread running, or cannot determine the number of threads, prior +// to executing the given statement. It is the responsibility of the +// caller not to pass a thread_count of 1. +static String DeathTestThreadWarning(size_t thread_count) { + Message msg; + msg << "Death tests use fork(), which is unsafe particularly" + << " in a threaded context. For this test, " << GTEST_NAME_ << " "; + if (thread_count == 0) + msg << "couldn't detect the number of threads."; + else + msg << "detected " << thread_count << " threads."; + return msg.GetString(); +} +#endif // !GTEST_OS_WINDOWS + +// Flag characters for reporting a death test that did not die. +static const char kDeathTestLived = 'L'; +static const char kDeathTestReturned = 'R'; +static const char kDeathTestInternalError = 'I'; + +// An enumeration describing all of the possible ways that a death test +// can conclude. DIED means that the process died while executing the +// test code; LIVED means that process lived beyond the end of the test +// code; and RETURNED means that the test statement attempted a "return," +// which is not allowed. IN_PROGRESS means the test has not yet +// concluded. +enum DeathTestOutcome { IN_PROGRESS, DIED, LIVED, RETURNED }; + +// Routine for aborting the program which is safe to call from an +// exec-style death test child process, in which case the error +// message is propagated back to the parent process. Otherwise, the +// message is simply printed to stderr. In either case, the program +// then exits with status 1. +void DeathTestAbort(const String& message) { + // On a POSIX system, this function may be called from a threadsafe-style + // death test child process, which operates on a very small stack. Use + // the heap for any additional non-minuscule memory requirements. + const InternalRunDeathTestFlag* const flag = + GetUnitTestImpl()->internal_run_death_test_flag(); + if (flag != NULL) { + FILE* parent = posix::FDOpen(flag->write_fd(), "w"); + fputc(kDeathTestInternalError, parent); + fprintf(parent, "%s", message.c_str()); + fflush(parent); + _exit(1); + } else { + fprintf(stderr, "%s", message.c_str()); + fflush(stderr); + abort(); + } +} + +// A replacement for CHECK that calls DeathTestAbort if the assertion +// fails. +#define GTEST_DEATH_TEST_CHECK_(expression) \ + do { \ + if (!::testing::internal::IsTrue(expression)) { \ + DeathTestAbort(::testing::internal::String::Format( \ + "CHECK failed: File %s, line %d: %s", \ + __FILE__, __LINE__, #expression)); \ + } \ + } while (::testing::internal::AlwaysFalse()) + +// This macro is similar to GTEST_DEATH_TEST_CHECK_, but it is meant for +// evaluating any system call that fulfills two conditions: it must return +// -1 on failure, and set errno to EINTR when it is interrupted and +// should be tried again. The macro expands to a loop that repeatedly +// evaluates the expression as long as it evaluates to -1 and sets +// errno to EINTR. If the expression evaluates to -1 but errno is +// something other than EINTR, DeathTestAbort is called. +#define GTEST_DEATH_TEST_CHECK_SYSCALL_(expression) \ + do { \ + int gtest_retval; \ + do { \ + gtest_retval = (expression); \ + } while (gtest_retval == -1 && errno == EINTR); \ + if (gtest_retval == -1) { \ + DeathTestAbort(::testing::internal::String::Format( \ + "CHECK failed: File %s, line %d: %s != -1", \ + __FILE__, __LINE__, #expression)); \ + } \ + } while (::testing::internal::AlwaysFalse()) + +// Returns the message describing the last system error in errno. +String GetLastErrnoDescription() { + return String(errno == 0 ? "" : posix::StrError(errno)); +} + +// This is called from a death test parent process to read a failure +// message from the death test child process and log it with the FATAL +// severity. On Windows, the message is read from a pipe handle. On other +// platforms, it is read from a file descriptor. +static void FailFromInternalError(int fd) { + Message error; + char buffer[256]; + int num_read; + + do { + while ((num_read = posix::Read(fd, buffer, 255)) > 0) { + buffer[num_read] = '\0'; + error << buffer; + } + } while (num_read == -1 && errno == EINTR); + + if (num_read == 0) { + GTEST_LOG_(FATAL) << error.GetString(); + } else { + const int last_error = errno; + GTEST_LOG_(FATAL) << "Error while reading death test internal: " + << GetLastErrnoDescription() << " [" << last_error << "]"; + } +} + +// Death test constructor. Increments the running death test count +// for the current test. +DeathTest::DeathTest() { + TestInfo* const info = GetUnitTestImpl()->current_test_info(); + if (info == NULL) { + DeathTestAbort("Cannot run a death test outside of a TEST or " + "TEST_F construct"); + } +} + +// Creates and returns a death test by dispatching to the current +// death test factory. +bool DeathTest::Create(const char* statement, const RE* regex, + const char* file, int line, DeathTest** test) { + return GetUnitTestImpl()->death_test_factory()->Create( + statement, regex, file, line, test); +} + +const char* DeathTest::LastMessage() { + return last_death_test_message_.c_str(); +} + +void DeathTest::set_last_death_test_message(const String& message) { + last_death_test_message_ = message; +} + +String DeathTest::last_death_test_message_; + +// Provides cross platform implementation for some death functionality. +class DeathTestImpl : public DeathTest { + protected: + DeathTestImpl(const char* a_statement, const RE* a_regex) + : statement_(a_statement), + regex_(a_regex), + spawned_(false), + status_(-1), + outcome_(IN_PROGRESS), + read_fd_(-1), + write_fd_(-1) {} + + // read_fd_ is expected to be closed and cleared by a derived class. + ~DeathTestImpl() { GTEST_DEATH_TEST_CHECK_(read_fd_ == -1); } + + void Abort(AbortReason reason); + virtual bool Passed(bool status_ok); + + const char* statement() const { return statement_; } + const RE* regex() const { return regex_; } + bool spawned() const { return spawned_; } + void set_spawned(bool is_spawned) { spawned_ = is_spawned; } + int status() const { return status_; } + void set_status(int a_status) { status_ = a_status; } + DeathTestOutcome outcome() const { return outcome_; } + void set_outcome(DeathTestOutcome an_outcome) { outcome_ = an_outcome; } + int read_fd() const { return read_fd_; } + void set_read_fd(int fd) { read_fd_ = fd; } + int write_fd() const { return write_fd_; } + void set_write_fd(int fd) { write_fd_ = fd; } + + // Called in the parent process only. Reads the result code of the death + // test child process via a pipe, interprets it to set the outcome_ + // member, and closes read_fd_. Outputs diagnostics and terminates in + // case of unexpected codes. + void ReadAndInterpretStatusByte(); + + private: + // The textual content of the code this object is testing. This class + // doesn't own this string and should not attempt to delete it. + const char* const statement_; + // The regular expression which test output must match. DeathTestImpl + // doesn't own this object and should not attempt to delete it. + const RE* const regex_; + // True if the death test child process has been successfully spawned. + bool spawned_; + // The exit status of the child process. + int status_; + // How the death test concluded. + DeathTestOutcome outcome_; + // Descriptor to the read end of the pipe to the child process. It is + // always -1 in the child process. The child keeps its write end of the + // pipe in write_fd_. + int read_fd_; + // Descriptor to the child's write end of the pipe to the parent process. + // It is always -1 in the parent process. The parent keeps its end of the + // pipe in read_fd_. + int write_fd_; +}; + +// Called in the parent process only. Reads the result code of the death +// test child process via a pipe, interprets it to set the outcome_ +// member, and closes read_fd_. Outputs diagnostics and terminates in +// case of unexpected codes. +void DeathTestImpl::ReadAndInterpretStatusByte() { + char flag; + int bytes_read; + + // The read() here blocks until data is available (signifying the + // failure of the death test) or until the pipe is closed (signifying + // its success), so it's okay to call this in the parent before + // the child process has exited. + do { + bytes_read = posix::Read(read_fd(), &flag, 1); + } while (bytes_read == -1 && errno == EINTR); + + if (bytes_read == 0) { + set_outcome(DIED); + } else if (bytes_read == 1) { + switch (flag) { + case kDeathTestReturned: + set_outcome(RETURNED); + break; + case kDeathTestLived: + set_outcome(LIVED); + break; + case kDeathTestInternalError: + FailFromInternalError(read_fd()); // Does not return. + break; + default: + GTEST_LOG_(FATAL) << "Death test child process reported " + << "unexpected status byte (" + << static_cast(flag) << ")"; + } + } else { + GTEST_LOG_(FATAL) << "Read from death test child process failed: " + << GetLastErrnoDescription(); + } + GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Close(read_fd())); + set_read_fd(-1); +} + +// Signals that the death test code which should have exited, didn't. +// Should be called only in a death test child process. +// Writes a status byte to the child's status file descriptor, then +// calls _exit(1). +void DeathTestImpl::Abort(AbortReason reason) { + // The parent process considers the death test to be a failure if + // it finds any data in our pipe. So, here we write a single flag byte + // to the pipe, then exit. + const char status_ch = + reason == TEST_DID_NOT_DIE ? kDeathTestLived : kDeathTestReturned; + GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Write(write_fd(), &status_ch, 1)); + GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Close(write_fd())); + _exit(1); // Exits w/o any normal exit hooks (we were supposed to crash) +} + +// Assesses the success or failure of a death test, using both private +// members which have previously been set, and one argument: +// +// Private data members: +// outcome: An enumeration describing how the death test +// concluded: DIED, LIVED, or RETURNED. The death test fails +// in the latter two cases. +// status: The exit status of the child process. On *nix, it is in the +// in the format specified by wait(2). On Windows, this is the +// value supplied to the ExitProcess() API or a numeric code +// of the exception that terminated the program. +// regex: A regular expression object to be applied to +// the test's captured standard error output; the death test +// fails if it does not match. +// +// Argument: +// status_ok: true if exit_status is acceptable in the context of +// this particular death test, which fails if it is false +// +// Returns true iff all of the above conditions are met. Otherwise, the +// first failing condition, in the order given above, is the one that is +// reported. Also sets the last death test message string. +bool DeathTestImpl::Passed(bool status_ok) { + if (!spawned()) + return false; + + const String error_message = GetCapturedStderr(); + + bool success = false; + Message buffer; + + buffer << "Death test: " << statement() << "\n"; + switch (outcome()) { + case LIVED: + buffer << " Result: failed to die.\n" + << " Error msg: " << error_message; + break; + case RETURNED: + buffer << " Result: illegal return in test statement.\n" + << " Error msg: " << error_message; + break; + case DIED: + if (status_ok) { + const bool matched = RE::PartialMatch(error_message.c_str(), *regex()); + if (matched) { + success = true; + } else { + buffer << " Result: died but not with expected error.\n" + << " Expected: " << regex()->pattern() << "\n" + << "Actual msg: " << error_message; + } + } else { + buffer << " Result: died but not with expected exit code:\n" + << " " << ExitSummary(status()) << "\n"; + } + break; + case IN_PROGRESS: + default: + GTEST_LOG_(FATAL) + << "DeathTest::Passed somehow called before conclusion of test"; + } + + DeathTest::set_last_death_test_message(buffer.GetString()); + return success; +} + +#if GTEST_OS_WINDOWS +// WindowsDeathTest implements death tests on Windows. Due to the +// specifics of starting new processes on Windows, death tests there are +// always threadsafe, and Google Test considers the +// --gtest_death_test_style=fast setting to be equivalent to +// --gtest_death_test_style=threadsafe there. +// +// A few implementation notes: Like the Linux version, the Windows +// implementation uses pipes for child-to-parent communication. But due to +// the specifics of pipes on Windows, some extra steps are required: +// +// 1. The parent creates a communication pipe and stores handles to both +// ends of it. +// 2. The parent starts the child and provides it with the information +// necessary to acquire the handle to the write end of the pipe. +// 3. The child acquires the write end of the pipe and signals the parent +// using a Windows event. +// 4. Now the parent can release the write end of the pipe on its side. If +// this is done before step 3, the object's reference count goes down to +// 0 and it is destroyed, preventing the child from acquiring it. The +// parent now has to release it, or read operations on the read end of +// the pipe will not return when the child terminates. +// 5. The parent reads child's output through the pipe (outcome code and +// any possible error messages) from the pipe, and its stderr and then +// determines whether to fail the test. +// +// Note: to distinguish Win32 API calls from the local method and function +// calls, the former are explicitly resolved in the global namespace. +// +class WindowsDeathTest : public DeathTestImpl { + public: + WindowsDeathTest(const char* statement, + const RE* regex, + const char* file, + int line) + : DeathTestImpl(statement, regex), file_(file), line_(line) {} + + // All of these virtual functions are inherited from DeathTest. + virtual int Wait(); + virtual TestRole AssumeRole(); + + private: + // The name of the file in which the death test is located. + const char* const file_; + // The line number on which the death test is located. + const int line_; + // Handle to the write end of the pipe to the child process. + AutoHandle write_handle_; + // Child process handle. + AutoHandle child_handle_; + // Event the child process uses to signal the parent that it has + // acquired the handle to the write end of the pipe. After seeing this + // event the parent can release its own handles to make sure its + // ReadFile() calls return when the child terminates. + AutoHandle event_handle_; +}; + +// Waits for the child in a death test to exit, returning its exit +// status, or 0 if no child process exists. As a side effect, sets the +// outcome data member. +int WindowsDeathTest::Wait() { + if (!spawned()) + return 0; + + // Wait until the child either signals that it has acquired the write end + // of the pipe or it dies. + const HANDLE wait_handles[2] = { child_handle_.Get(), event_handle_.Get() }; + switch (::WaitForMultipleObjects(2, + wait_handles, + FALSE, // Waits for any of the handles. + INFINITE)) { + case WAIT_OBJECT_0: + case WAIT_OBJECT_0 + 1: + break; + default: + GTEST_DEATH_TEST_CHECK_(false); // Should not get here. + } + + // The child has acquired the write end of the pipe or exited. + // We release the handle on our side and continue. + write_handle_.Reset(); + event_handle_.Reset(); + + ReadAndInterpretStatusByte(); + + // Waits for the child process to exit if it haven't already. This + // returns immediately if the child has already exited, regardless of + // whether previous calls to WaitForMultipleObjects synchronized on this + // handle or not. + GTEST_DEATH_TEST_CHECK_( + WAIT_OBJECT_0 == ::WaitForSingleObject(child_handle_.Get(), + INFINITE)); + DWORD status; + GTEST_DEATH_TEST_CHECK_(::GetExitCodeProcess(child_handle_.Get(), &status) + != FALSE); + child_handle_.Reset(); + set_status(static_cast(status)); + return this->status(); +} + +// The AssumeRole process for a Windows death test. It creates a child +// process with the same executable as the current process to run the +// death test. The child process is given the --gtest_filter and +// --gtest_internal_run_death_test flags such that it knows to run the +// current death test only. +DeathTest::TestRole WindowsDeathTest::AssumeRole() { + const UnitTestImpl* const impl = GetUnitTestImpl(); + const InternalRunDeathTestFlag* const flag = + impl->internal_run_death_test_flag(); + const TestInfo* const info = impl->current_test_info(); + const int death_test_index = info->result()->death_test_count(); + + if (flag != NULL) { + // ParseInternalRunDeathTestFlag() has performed all the necessary + // processing. + set_write_fd(flag->write_fd()); + return EXECUTE_TEST; + } + + // WindowsDeathTest uses an anonymous pipe to communicate results of + // a death test. + SECURITY_ATTRIBUTES handles_are_inheritable = { + sizeof(SECURITY_ATTRIBUTES), NULL, TRUE }; + HANDLE read_handle, write_handle; + GTEST_DEATH_TEST_CHECK_( + ::CreatePipe(&read_handle, &write_handle, &handles_are_inheritable, + 0) // Default buffer size. + != FALSE); + set_read_fd(::_open_osfhandle(reinterpret_cast(read_handle), + O_RDONLY)); + write_handle_.Reset(write_handle); + event_handle_.Reset(::CreateEvent( + &handles_are_inheritable, + TRUE, // The event will automatically reset to non-signaled state. + FALSE, // The initial state is non-signalled. + NULL)); // The even is unnamed. + GTEST_DEATH_TEST_CHECK_(event_handle_.Get() != NULL); + const String filter_flag = String::Format("--%s%s=%s.%s", + GTEST_FLAG_PREFIX_, kFilterFlag, + info->test_case_name(), + info->name()); + const String internal_flag = String::Format( + "--%s%s=%s|%d|%d|%u|%Iu|%Iu", + GTEST_FLAG_PREFIX_, + kInternalRunDeathTestFlag, + file_, line_, + death_test_index, + static_cast(::GetCurrentProcessId()), + // size_t has the same with as pointers on both 32-bit and 64-bit + // Windows platforms. + // See http://msdn.microsoft.com/en-us/library/tcxf1dw6.aspx. + reinterpret_cast(write_handle), + reinterpret_cast(event_handle_.Get())); + + char executable_path[_MAX_PATH + 1]; // NOLINT + GTEST_DEATH_TEST_CHECK_( + _MAX_PATH + 1 != ::GetModuleFileNameA(NULL, + executable_path, + _MAX_PATH)); + + String command_line = String::Format("%s %s \"%s\"", + ::GetCommandLineA(), + filter_flag.c_str(), + internal_flag.c_str()); + + DeathTest::set_last_death_test_message(""); + + CaptureStderr(); + // Flush the log buffers since the log streams are shared with the child. + FlushInfoLog(); + + // The child process will share the standard handles with the parent. + STARTUPINFOA startup_info; + memset(&startup_info, 0, sizeof(STARTUPINFO)); + startup_info.dwFlags = STARTF_USESTDHANDLES; + startup_info.hStdInput = ::GetStdHandle(STD_INPUT_HANDLE); + startup_info.hStdOutput = ::GetStdHandle(STD_OUTPUT_HANDLE); + startup_info.hStdError = ::GetStdHandle(STD_ERROR_HANDLE); + + PROCESS_INFORMATION process_info; + GTEST_DEATH_TEST_CHECK_(::CreateProcessA( + executable_path, + const_cast(command_line.c_str()), + NULL, // Retuned process handle is not inheritable. + NULL, // Retuned thread handle is not inheritable. + TRUE, // Child inherits all inheritable handles (for write_handle_). + 0x0, // Default creation flags. + NULL, // Inherit the parent's environment. + UnitTest::GetInstance()->original_working_dir(), + &startup_info, + &process_info) != FALSE); + child_handle_.Reset(process_info.hProcess); + ::CloseHandle(process_info.hThread); + set_spawned(true); + return OVERSEE_TEST; +} +#else // We are not on Windows. + +// ForkingDeathTest provides implementations for most of the abstract +// methods of the DeathTest interface. Only the AssumeRole method is +// left undefined. +class ForkingDeathTest : public DeathTestImpl { + public: + ForkingDeathTest(const char* statement, const RE* regex); + + // All of these virtual functions are inherited from DeathTest. + virtual int Wait(); + + protected: + void set_child_pid(pid_t child_pid) { child_pid_ = child_pid; } + + private: + // PID of child process during death test; 0 in the child process itself. + pid_t child_pid_; +}; + +// Constructs a ForkingDeathTest. +ForkingDeathTest::ForkingDeathTest(const char* a_statement, const RE* a_regex) + : DeathTestImpl(a_statement, a_regex), + child_pid_(-1) {} + +// Waits for the child in a death test to exit, returning its exit +// status, or 0 if no child process exists. As a side effect, sets the +// outcome data member. +int ForkingDeathTest::Wait() { + if (!spawned()) + return 0; + + ReadAndInterpretStatusByte(); + + int status_value; + GTEST_DEATH_TEST_CHECK_SYSCALL_(waitpid(child_pid_, &status_value, 0)); + set_status(status_value); + return status_value; +} + +// A concrete death test class that forks, then immediately runs the test +// in the child process. +class NoExecDeathTest : public ForkingDeathTest { + public: + NoExecDeathTest(const char* a_statement, const RE* a_regex) : + ForkingDeathTest(a_statement, a_regex) { } + virtual TestRole AssumeRole(); +}; + +// The AssumeRole process for a fork-and-run death test. It implements a +// straightforward fork, with a simple pipe to transmit the status byte. +DeathTest::TestRole NoExecDeathTest::AssumeRole() { + const size_t thread_count = GetThreadCount(); + if (thread_count != 1) { + GTEST_LOG_(WARNING) << DeathTestThreadWarning(thread_count); + } + + int pipe_fd[2]; + GTEST_DEATH_TEST_CHECK_(pipe(pipe_fd) != -1); + + DeathTest::set_last_death_test_message(""); + CaptureStderr(); + // When we fork the process below, the log file buffers are copied, but the + // file descriptors are shared. We flush all log files here so that closing + // the file descriptors in the child process doesn't throw off the + // synchronization between descriptors and buffers in the parent process. + // This is as close to the fork as possible to avoid a race condition in case + // there are multiple threads running before the death test, and another + // thread writes to the log file. + FlushInfoLog(); + + const pid_t child_pid = fork(); + GTEST_DEATH_TEST_CHECK_(child_pid != -1); + set_child_pid(child_pid); + if (child_pid == 0) { + GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[0])); + set_write_fd(pipe_fd[1]); + // Redirects all logging to stderr in the child process to prevent + // concurrent writes to the log files. We capture stderr in the parent + // process and append the child process' output to a log. + LogToStderr(); + // Event forwarding to the listeners of event listener API mush be shut + // down in death test subprocesses. + GetUnitTestImpl()->listeners()->SuppressEventForwarding(); + return EXECUTE_TEST; + } else { + GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1])); + set_read_fd(pipe_fd[0]); + set_spawned(true); + return OVERSEE_TEST; + } +} + +// A concrete death test class that forks and re-executes the main +// program from the beginning, with command-line flags set that cause +// only this specific death test to be run. +class ExecDeathTest : public ForkingDeathTest { + public: + ExecDeathTest(const char* a_statement, const RE* a_regex, + const char* file, int line) : + ForkingDeathTest(a_statement, a_regex), file_(file), line_(line) { } + virtual TestRole AssumeRole(); + private: + // The name of the file in which the death test is located. + const char* const file_; + // The line number on which the death test is located. + const int line_; +}; + +// Utility class for accumulating command-line arguments. +class Arguments { + public: + Arguments() { + args_.push_back(NULL); + } + + ~Arguments() { + for (std::vector::iterator i = args_.begin(); i != args_.end(); + ++i) { + free(*i); + } + } + void AddArgument(const char* argument) { + args_.insert(args_.end() - 1, posix::StrDup(argument)); + } + + template + void AddArguments(const ::std::vector& arguments) { + for (typename ::std::vector::const_iterator i = arguments.begin(); + i != arguments.end(); + ++i) { + args_.insert(args_.end() - 1, posix::StrDup(i->c_str())); + } + } + char* const* Argv() { + return &args_[0]; + } + private: + std::vector args_; +}; + +// A struct that encompasses the arguments to the child process of a +// threadsafe-style death test process. +struct ExecDeathTestArgs { + char* const* argv; // Command-line arguments for the child's call to exec + int close_fd; // File descriptor to close; the read end of a pipe +}; + +#if GTEST_OS_MAC +inline char** GetEnviron() { + // When Google Test is built as a framework on MacOS X, the environ variable + // is unavailable. Apple's documentation (man environ) recommends using + // _NSGetEnviron() instead. + return *_NSGetEnviron(); +} +#else +// Some POSIX platforms expect you to declare environ. extern "C" makes +// it reside in the global namespace. +extern "C" char** environ; +inline char** GetEnviron() { return environ; } +#endif // GTEST_OS_MAC + +// The main function for a threadsafe-style death test child process. +// This function is called in a clone()-ed process and thus must avoid +// any potentially unsafe operations like malloc or libc functions. +static int ExecDeathTestChildMain(void* child_arg) { + ExecDeathTestArgs* const args = static_cast(child_arg); + GTEST_DEATH_TEST_CHECK_SYSCALL_(close(args->close_fd)); + + // We need to execute the test program in the same environment where + // it was originally invoked. Therefore we change to the original + // working directory first. + const char* const original_dir = + UnitTest::GetInstance()->original_working_dir(); + // We can safely call chdir() as it's a direct system call. + if (chdir(original_dir) != 0) { + DeathTestAbort(String::Format("chdir(\"%s\") failed: %s", + original_dir, + GetLastErrnoDescription().c_str())); + return EXIT_FAILURE; + } + + // We can safely call execve() as it's a direct system call. We + // cannot use execvp() as it's a libc function and thus potentially + // unsafe. Since execve() doesn't search the PATH, the user must + // invoke the test program via a valid path that contains at least + // one path separator. + execve(args->argv[0], args->argv, GetEnviron()); + DeathTestAbort(String::Format("execve(%s, ...) in %s failed: %s", + args->argv[0], + original_dir, + GetLastErrnoDescription().c_str())); + return EXIT_FAILURE; +} + +// Two utility routines that together determine the direction the stack +// grows. +// This could be accomplished more elegantly by a single recursive +// function, but we want to guard against the unlikely possibility of +// a smart compiler optimizing the recursion away. +bool StackLowerThanAddress(const void* ptr) { + int dummy; + return &dummy < ptr; +} + +bool StackGrowsDown() { + int dummy; + return StackLowerThanAddress(&dummy); +} + +// A threadsafe implementation of fork(2) for threadsafe-style death tests +// that uses clone(2). It dies with an error message if anything goes +// wrong. +static pid_t ExecDeathTestFork(char* const* argv, int close_fd) { + ExecDeathTestArgs args = { argv, close_fd }; + pid_t child_pid = -1; + +#if GTEST_HAS_CLONE + const bool use_fork = GTEST_FLAG(death_test_use_fork); + + if (!use_fork) { + static const bool stack_grows_down = StackGrowsDown(); + const size_t stack_size = getpagesize(); + // MMAP_ANONYMOUS is not defined on Mac, so we use MAP_ANON instead. + void* const stack = mmap(NULL, stack_size, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_PRIVATE, -1, 0); + GTEST_DEATH_TEST_CHECK_(stack != MAP_FAILED); + void* const stack_top = + static_cast(stack) + (stack_grows_down ? stack_size : 0); + + child_pid = clone(&ExecDeathTestChildMain, stack_top, SIGCHLD, &args); + + GTEST_DEATH_TEST_CHECK_(munmap(stack, stack_size) != -1); + } +#else + const bool use_fork = true; +#endif // GTEST_HAS_CLONE + + if (use_fork && (child_pid = fork()) == 0) { + ExecDeathTestChildMain(&args); + _exit(0); + } + + GTEST_DEATH_TEST_CHECK_(child_pid != -1); + return child_pid; +} + +// The AssumeRole process for a fork-and-exec death test. It re-executes the +// main program from the beginning, setting the --gtest_filter +// and --gtest_internal_run_death_test flags to cause only the current +// death test to be re-run. +DeathTest::TestRole ExecDeathTest::AssumeRole() { + const UnitTestImpl* const impl = GetUnitTestImpl(); + const InternalRunDeathTestFlag* const flag = + impl->internal_run_death_test_flag(); + const TestInfo* const info = impl->current_test_info(); + const int death_test_index = info->result()->death_test_count(); + + if (flag != NULL) { + set_write_fd(flag->write_fd()); + return EXECUTE_TEST; + } + + int pipe_fd[2]; + GTEST_DEATH_TEST_CHECK_(pipe(pipe_fd) != -1); + // Clear the close-on-exec flag on the write end of the pipe, lest + // it be closed when the child process does an exec: + GTEST_DEATH_TEST_CHECK_(fcntl(pipe_fd[1], F_SETFD, 0) != -1); + + const String filter_flag = + String::Format("--%s%s=%s.%s", + GTEST_FLAG_PREFIX_, kFilterFlag, + info->test_case_name(), info->name()); + const String internal_flag = + String::Format("--%s%s=%s|%d|%d|%d", + GTEST_FLAG_PREFIX_, kInternalRunDeathTestFlag, + file_, line_, death_test_index, pipe_fd[1]); + Arguments args; + args.AddArguments(GetArgvs()); + args.AddArgument(filter_flag.c_str()); + args.AddArgument(internal_flag.c_str()); + + DeathTest::set_last_death_test_message(""); + + CaptureStderr(); + // See the comment in NoExecDeathTest::AssumeRole for why the next line + // is necessary. + FlushInfoLog(); + + const pid_t child_pid = ExecDeathTestFork(args.Argv(), pipe_fd[0]); + GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1])); + set_child_pid(child_pid); + set_read_fd(pipe_fd[0]); + set_spawned(true); + return OVERSEE_TEST; +} + +#endif // !GTEST_OS_WINDOWS + +// Creates a concrete DeathTest-derived class that depends on the +// --gtest_death_test_style flag, and sets the pointer pointed to +// by the "test" argument to its address. If the test should be +// skipped, sets that pointer to NULL. Returns true, unless the +// flag is set to an invalid value. +bool DefaultDeathTestFactory::Create(const char* statement, const RE* regex, + const char* file, int line, + DeathTest** test) { + UnitTestImpl* const impl = GetUnitTestImpl(); + const InternalRunDeathTestFlag* const flag = + impl->internal_run_death_test_flag(); + const int death_test_index = impl->current_test_info() + ->increment_death_test_count(); + + if (flag != NULL) { + if (death_test_index > flag->index()) { + DeathTest::set_last_death_test_message(String::Format( + "Death test count (%d) somehow exceeded expected maximum (%d)", + death_test_index, flag->index())); + return false; + } + + if (!(flag->file() == file && flag->line() == line && + flag->index() == death_test_index)) { + *test = NULL; + return true; + } + } + +#if GTEST_OS_WINDOWS + if (GTEST_FLAG(death_test_style) == "threadsafe" || + GTEST_FLAG(death_test_style) == "fast") { + *test = new WindowsDeathTest(statement, regex, file, line); + } +#else + if (GTEST_FLAG(death_test_style) == "threadsafe") { + *test = new ExecDeathTest(statement, regex, file, line); + } else if (GTEST_FLAG(death_test_style) == "fast") { + *test = new NoExecDeathTest(statement, regex); + } +#endif // GTEST_OS_WINDOWS + else { // NOLINT - this is more readable than unbalanced brackets inside #if. + DeathTest::set_last_death_test_message(String::Format( + "Unknown death test style \"%s\" encountered", + GTEST_FLAG(death_test_style).c_str())); + return false; + } + + return true; +} + +// Splits a given string on a given delimiter, populating a given +// vector with the fields. GTEST_HAS_DEATH_TEST implies that we have +// ::std::string, so we can use it here. +static void SplitString(const ::std::string& str, char delimiter, + ::std::vector< ::std::string>* dest) { + ::std::vector< ::std::string> parsed; + ::std::string::size_type pos = 0; + while (::testing::internal::AlwaysTrue()) { + const ::std::string::size_type colon = str.find(delimiter, pos); + if (colon == ::std::string::npos) { + parsed.push_back(str.substr(pos)); + break; + } else { + parsed.push_back(str.substr(pos, colon - pos)); + pos = colon + 1; + } + } + dest->swap(parsed); +} + +#if GTEST_OS_WINDOWS +// Recreates the pipe and event handles from the provided parameters, +// signals the event, and returns a file descriptor wrapped around the pipe +// handle. This function is called in the child process only. +int GetStatusFileDescriptor(unsigned int parent_process_id, + size_t write_handle_as_size_t, + size_t event_handle_as_size_t) { + AutoHandle parent_process_handle(::OpenProcess(PROCESS_DUP_HANDLE, + FALSE, // Non-inheritable. + parent_process_id)); + if (parent_process_handle.Get() == INVALID_HANDLE_VALUE) { + DeathTestAbort(String::Format("Unable to open parent process %u", + parent_process_id)); + } + + // TODO(vladl@google.com): Replace the following check with a + // compile-time assertion when available. + GTEST_CHECK_(sizeof(HANDLE) <= sizeof(size_t)); + + const HANDLE write_handle = + reinterpret_cast(write_handle_as_size_t); + HANDLE dup_write_handle; + + // The newly initialized handle is accessible only in in the parent + // process. To obtain one accessible within the child, we need to use + // DuplicateHandle. + if (!::DuplicateHandle(parent_process_handle.Get(), write_handle, + ::GetCurrentProcess(), &dup_write_handle, + 0x0, // Requested privileges ignored since + // DUPLICATE_SAME_ACCESS is used. + FALSE, // Request non-inheritable handler. + DUPLICATE_SAME_ACCESS)) { + DeathTestAbort(String::Format( + "Unable to duplicate the pipe handle %Iu from the parent process %u", + write_handle_as_size_t, parent_process_id)); + } + + const HANDLE event_handle = reinterpret_cast(event_handle_as_size_t); + HANDLE dup_event_handle; + + if (!::DuplicateHandle(parent_process_handle.Get(), event_handle, + ::GetCurrentProcess(), &dup_event_handle, + 0x0, + FALSE, + DUPLICATE_SAME_ACCESS)) { + DeathTestAbort(String::Format( + "Unable to duplicate the event handle %Iu from the parent process %u", + event_handle_as_size_t, parent_process_id)); + } + + const int write_fd = + ::_open_osfhandle(reinterpret_cast(dup_write_handle), O_APPEND); + if (write_fd == -1) { + DeathTestAbort(String::Format( + "Unable to convert pipe handle %Iu to a file descriptor", + write_handle_as_size_t)); + } + + // Signals the parent that the write end of the pipe has been acquired + // so the parent can release its own write end. + ::SetEvent(dup_event_handle); + + return write_fd; +} +#endif // GTEST_OS_WINDOWS + +// Returns a newly created InternalRunDeathTestFlag object with fields +// initialized from the GTEST_FLAG(internal_run_death_test) flag if +// the flag is specified; otherwise returns NULL. +InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag() { + if (GTEST_FLAG(internal_run_death_test) == "") return NULL; + + // GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we + // can use it here. + int line = -1; + int index = -1; + ::std::vector< ::std::string> fields; + SplitString(GTEST_FLAG(internal_run_death_test).c_str(), '|', &fields); + int write_fd = -1; + +#if GTEST_OS_WINDOWS + unsigned int parent_process_id = 0; + size_t write_handle_as_size_t = 0; + size_t event_handle_as_size_t = 0; + + if (fields.size() != 6 + || !ParseNaturalNumber(fields[1], &line) + || !ParseNaturalNumber(fields[2], &index) + || !ParseNaturalNumber(fields[3], &parent_process_id) + || !ParseNaturalNumber(fields[4], &write_handle_as_size_t) + || !ParseNaturalNumber(fields[5], &event_handle_as_size_t)) { + DeathTestAbort(String::Format( + "Bad --gtest_internal_run_death_test flag: %s", + GTEST_FLAG(internal_run_death_test).c_str())); + } + write_fd = GetStatusFileDescriptor(parent_process_id, + write_handle_as_size_t, + event_handle_as_size_t); +#else + if (fields.size() != 4 + || !ParseNaturalNumber(fields[1], &line) + || !ParseNaturalNumber(fields[2], &index) + || !ParseNaturalNumber(fields[3], &write_fd)) { + DeathTestAbort(String::Format( + "Bad --gtest_internal_run_death_test flag: %s", + GTEST_FLAG(internal_run_death_test).c_str())); + } +#endif // GTEST_OS_WINDOWS + return new InternalRunDeathTestFlag(fields[0], line, index, write_fd); +} + +} // namespace internal + +#endif // GTEST_HAS_DEATH_TEST + +} // namespace testing +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: keith.ray@gmail.com (Keith Ray) + + +#include + +#if GTEST_OS_WINDOWS_MOBILE +#include +#elif GTEST_OS_WINDOWS +#include +#include +#elif GTEST_OS_SYMBIAN +// Symbian OpenC has PATH_MAX in sys/syslimits.h +#include +#else +#include +#include // Some Linux distributions define PATH_MAX here. +#endif // GTEST_OS_WINDOWS_MOBILE + +#if GTEST_OS_WINDOWS +#define GTEST_PATH_MAX_ _MAX_PATH +#elif defined(PATH_MAX) +#define GTEST_PATH_MAX_ PATH_MAX +#elif defined(_XOPEN_PATH_MAX) +#define GTEST_PATH_MAX_ _XOPEN_PATH_MAX +#else +#define GTEST_PATH_MAX_ _POSIX_PATH_MAX +#endif // GTEST_OS_WINDOWS + + +namespace testing { +namespace internal { + +#if GTEST_OS_WINDOWS +// On Windows, '\\' is the standard path separator, but many tools and the +// Windows API also accept '/' as an alternate path separator. Unless otherwise +// noted, a file path can contain either kind of path separators, or a mixture +// of them. +const char kPathSeparator = '\\'; +const char kAlternatePathSeparator = '/'; +const char kPathSeparatorString[] = "\\"; +const char kAlternatePathSeparatorString[] = "/"; +#if GTEST_OS_WINDOWS_MOBILE +// Windows CE doesn't have a current directory. You should not use +// the current directory in tests on Windows CE, but this at least +// provides a reasonable fallback. +const char kCurrentDirectoryString[] = "\\"; +// Windows CE doesn't define INVALID_FILE_ATTRIBUTES +const DWORD kInvalidFileAttributes = 0xffffffff; +#else +const char kCurrentDirectoryString[] = ".\\"; +#endif // GTEST_OS_WINDOWS_MOBILE +#else +const char kPathSeparator = '/'; +const char kPathSeparatorString[] = "/"; +const char kCurrentDirectoryString[] = "./"; +#endif // GTEST_OS_WINDOWS + +// Returns whether the given character is a valid path separator. +static bool IsPathSeparator(char c) { +#if GTEST_HAS_ALT_PATH_SEP_ + return (c == kPathSeparator) || (c == kAlternatePathSeparator); +#else + return c == kPathSeparator; +#endif +} + +// Returns the current working directory, or "" if unsuccessful. +FilePath FilePath::GetCurrentDir() { +#if GTEST_OS_WINDOWS_MOBILE + // Windows CE doesn't have a current directory, so we just return + // something reasonable. + return FilePath(kCurrentDirectoryString); +#elif GTEST_OS_WINDOWS + char cwd[GTEST_PATH_MAX_ + 1] = { '\0' }; + return FilePath(_getcwd(cwd, sizeof(cwd)) == NULL ? "" : cwd); +#else + char cwd[GTEST_PATH_MAX_ + 1] = { '\0' }; + return FilePath(getcwd(cwd, sizeof(cwd)) == NULL ? "" : cwd); +#endif // GTEST_OS_WINDOWS_MOBILE +} + +// Returns a copy of the FilePath with the case-insensitive extension removed. +// Example: FilePath("dir/file.exe").RemoveExtension("EXE") returns +// FilePath("dir/file"). If a case-insensitive extension is not +// found, returns a copy of the original FilePath. +FilePath FilePath::RemoveExtension(const char* extension) const { + String dot_extension(String::Format(".%s", extension)); + if (pathname_.EndsWithCaseInsensitive(dot_extension.c_str())) { + return FilePath(String(pathname_.c_str(), pathname_.length() - 4)); + } + return *this; +} + +// Returns a pointer to the last occurence of a valid path separator in +// the FilePath. On Windows, for example, both '/' and '\' are valid path +// separators. Returns NULL if no path separator was found. +const char* FilePath::FindLastPathSeparator() const { + const char* const last_sep = strrchr(c_str(), kPathSeparator); +#if GTEST_HAS_ALT_PATH_SEP_ + const char* const last_alt_sep = strrchr(c_str(), kAlternatePathSeparator); + // Comparing two pointers of which only one is NULL is undefined. + if (last_alt_sep != NULL && + (last_sep == NULL || last_alt_sep > last_sep)) { + return last_alt_sep; + } +#endif + return last_sep; +} + +// Returns a copy of the FilePath with the directory part removed. +// Example: FilePath("path/to/file").RemoveDirectoryName() returns +// FilePath("file"). If there is no directory part ("just_a_file"), it returns +// the FilePath unmodified. If there is no file part ("just_a_dir/") it +// returns an empty FilePath (""). +// On Windows platform, '\' is the path separator, otherwise it is '/'. +FilePath FilePath::RemoveDirectoryName() const { + const char* const last_sep = FindLastPathSeparator(); + return last_sep ? FilePath(String(last_sep + 1)) : *this; +} + +// RemoveFileName returns the directory path with the filename removed. +// Example: FilePath("path/to/file").RemoveFileName() returns "path/to/". +// If the FilePath is "a_file" or "/a_file", RemoveFileName returns +// FilePath("./") or, on Windows, FilePath(".\\"). If the filepath does +// not have a file, like "just/a/dir/", it returns the FilePath unmodified. +// On Windows platform, '\' is the path separator, otherwise it is '/'. +FilePath FilePath::RemoveFileName() const { + const char* const last_sep = FindLastPathSeparator(); + String dir; + if (last_sep) { + dir = String(c_str(), last_sep + 1 - c_str()); + } else { + dir = kCurrentDirectoryString; + } + return FilePath(dir); +} + +// Helper functions for naming files in a directory for xml output. + +// Given directory = "dir", base_name = "test", number = 0, +// extension = "xml", returns "dir/test.xml". If number is greater +// than zero (e.g., 12), returns "dir/test_12.xml". +// On Windows platform, uses \ as the separator rather than /. +FilePath FilePath::MakeFileName(const FilePath& directory, + const FilePath& base_name, + int number, + const char* extension) { + String file; + if (number == 0) { + file = String::Format("%s.%s", base_name.c_str(), extension); + } else { + file = String::Format("%s_%d.%s", base_name.c_str(), number, extension); + } + return ConcatPaths(directory, FilePath(file)); +} + +// Given directory = "dir", relative_path = "test.xml", returns "dir/test.xml". +// On Windows, uses \ as the separator rather than /. +FilePath FilePath::ConcatPaths(const FilePath& directory, + const FilePath& relative_path) { + if (directory.IsEmpty()) + return relative_path; + const FilePath dir(directory.RemoveTrailingPathSeparator()); + return FilePath(String::Format("%s%c%s", dir.c_str(), kPathSeparator, + relative_path.c_str())); +} + +// Returns true if pathname describes something findable in the file-system, +// either a file, directory, or whatever. +bool FilePath::FileOrDirectoryExists() const { +#if GTEST_OS_WINDOWS_MOBILE + LPCWSTR unicode = String::AnsiToUtf16(pathname_.c_str()); + const DWORD attributes = GetFileAttributes(unicode); + delete [] unicode; + return attributes != kInvalidFileAttributes; +#else + posix::StatStruct file_stat; + return posix::Stat(pathname_.c_str(), &file_stat) == 0; +#endif // GTEST_OS_WINDOWS_MOBILE +} + +// Returns true if pathname describes a directory in the file-system +// that exists. +bool FilePath::DirectoryExists() const { + bool result = false; +#if GTEST_OS_WINDOWS + // Don't strip off trailing separator if path is a root directory on + // Windows (like "C:\\"). + const FilePath& path(IsRootDirectory() ? *this : + RemoveTrailingPathSeparator()); +#else + const FilePath& path(*this); +#endif + +#if GTEST_OS_WINDOWS_MOBILE + LPCWSTR unicode = String::AnsiToUtf16(path.c_str()); + const DWORD attributes = GetFileAttributes(unicode); + delete [] unicode; + if ((attributes != kInvalidFileAttributes) && + (attributes & FILE_ATTRIBUTE_DIRECTORY)) { + result = true; + } +#else + posix::StatStruct file_stat; + result = posix::Stat(path.c_str(), &file_stat) == 0 && + posix::IsDir(file_stat); +#endif // GTEST_OS_WINDOWS_MOBILE + + return result; +} + +// Returns true if pathname describes a root directory. (Windows has one +// root directory per disk drive.) +bool FilePath::IsRootDirectory() const { +#if GTEST_OS_WINDOWS + // TODO(wan@google.com): on Windows a network share like + // \\server\share can be a root directory, although it cannot be the + // current directory. Handle this properly. + return pathname_.length() == 3 && IsAbsolutePath(); +#else + return pathname_.length() == 1 && IsPathSeparator(pathname_.c_str()[0]); +#endif +} + +// Returns true if pathname describes an absolute path. +bool FilePath::IsAbsolutePath() const { + const char* const name = pathname_.c_str(); +#if GTEST_OS_WINDOWS + return pathname_.length() >= 3 && + ((name[0] >= 'a' && name[0] <= 'z') || + (name[0] >= 'A' && name[0] <= 'Z')) && + name[1] == ':' && + IsPathSeparator(name[2]); +#else + return IsPathSeparator(name[0]); +#endif +} + +// Returns a pathname for a file that does not currently exist. The pathname +// will be directory/base_name.extension or +// directory/base_name_.extension if directory/base_name.extension +// already exists. The number will be incremented until a pathname is found +// that does not already exist. +// Examples: 'dir/foo_test.xml' or 'dir/foo_test_1.xml'. +// There could be a race condition if two or more processes are calling this +// function at the same time -- they could both pick the same filename. +FilePath FilePath::GenerateUniqueFileName(const FilePath& directory, + const FilePath& base_name, + const char* extension) { + FilePath full_pathname; + int number = 0; + do { + full_pathname.Set(MakeFileName(directory, base_name, number++, extension)); + } while (full_pathname.FileOrDirectoryExists()); + return full_pathname; +} + +// Returns true if FilePath ends with a path separator, which indicates that +// it is intended to represent a directory. Returns false otherwise. +// This does NOT check that a directory (or file) actually exists. +bool FilePath::IsDirectory() const { + return !pathname_.empty() && + IsPathSeparator(pathname_.c_str()[pathname_.length() - 1]); +} + +// Create directories so that path exists. Returns true if successful or if +// the directories already exist; returns false if unable to create directories +// for any reason. +bool FilePath::CreateDirectoriesRecursively() const { + if (!this->IsDirectory()) { + return false; + } + + if (pathname_.length() == 0 || this->DirectoryExists()) { + return true; + } + + const FilePath parent(this->RemoveTrailingPathSeparator().RemoveFileName()); + return parent.CreateDirectoriesRecursively() && this->CreateFolder(); +} + +// Create the directory so that path exists. Returns true if successful or +// if the directory already exists; returns false if unable to create the +// directory for any reason, including if the parent directory does not +// exist. Not named "CreateDirectory" because that's a macro on Windows. +bool FilePath::CreateFolder() const { +#if GTEST_OS_WINDOWS_MOBILE + FilePath removed_sep(this->RemoveTrailingPathSeparator()); + LPCWSTR unicode = String::AnsiToUtf16(removed_sep.c_str()); + int result = CreateDirectory(unicode, NULL) ? 0 : -1; + delete [] unicode; +#elif GTEST_OS_WINDOWS + int result = _mkdir(pathname_.c_str()); +#else + int result = mkdir(pathname_.c_str(), 0777); +#endif // GTEST_OS_WINDOWS_MOBILE + + if (result == -1) { + return this->DirectoryExists(); // An error is OK if the directory exists. + } + return true; // No error. +} + +// If input name has a trailing separator character, remove it and return the +// name, otherwise return the name string unmodified. +// On Windows platform, uses \ as the separator, other platforms use /. +FilePath FilePath::RemoveTrailingPathSeparator() const { + return IsDirectory() + ? FilePath(String(pathname_.c_str(), pathname_.length() - 1)) + : *this; +} + +// Removes any redundant separators that might be in the pathname. +// For example, "bar///foo" becomes "bar/foo". Does not eliminate other +// redundancies that might be in a pathname involving "." or "..". +// TODO(wan@google.com): handle Windows network shares (e.g. \\server\share). +void FilePath::Normalize() { + if (pathname_.c_str() == NULL) { + pathname_ = ""; + return; + } + const char* src = pathname_.c_str(); + char* const dest = new char[pathname_.length() + 1]; + char* dest_ptr = dest; + memset(dest_ptr, 0, pathname_.length() + 1); + + while (*src != '\0') { + *dest_ptr = *src; + if (!IsPathSeparator(*src)) { + src++; + } else { +#if GTEST_HAS_ALT_PATH_SEP_ + if (*dest_ptr == kAlternatePathSeparator) { + *dest_ptr = kPathSeparator; + } +#endif + while (IsPathSeparator(*src)) + src++; + } + dest_ptr++; + } + *dest_ptr = '\0'; + pathname_ = dest; + delete[] dest; +} + +} // namespace internal +} // namespace testing +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: wan@google.com (Zhanyong Wan) + + +#include +#include +#include + +#if GTEST_OS_WINDOWS_MOBILE +#include // For TerminateProcess() +#elif GTEST_OS_WINDOWS +#include +#include +#else +#include +#endif // GTEST_OS_WINDOWS_MOBILE + +#if GTEST_OS_MAC +#include +#include +#include +#endif // GTEST_OS_MAC + + +// Indicates that this translation unit is part of Google Test's +// implementation. It must come before gtest-internal-inl.h is +// included, or there will be a compiler error. This trick is to +// prevent a user from accidentally including gtest-internal-inl.h in +// his code. +#define GTEST_IMPLEMENTATION_ 1 +#undef GTEST_IMPLEMENTATION_ + +namespace testing { +namespace internal { + +#if defined(_MSC_VER) || defined(__BORLANDC__) +// MSVC and C++Builder do not provide a definition of STDERR_FILENO. +const int kStdOutFileno = 1; +const int kStdErrFileno = 2; +#else +const int kStdOutFileno = STDOUT_FILENO; +const int kStdErrFileno = STDERR_FILENO; +#endif // _MSC_VER + +#if GTEST_OS_MAC + +// Returns the number of threads running in the process, or 0 to indicate that +// we cannot detect it. +size_t GetThreadCount() { + const task_t task = mach_task_self(); + mach_msg_type_number_t thread_count; + thread_act_array_t thread_list; + const kern_return_t status = task_threads(task, &thread_list, &thread_count); + if (status == KERN_SUCCESS) { + // task_threads allocates resources in thread_list and we need to free them + // to avoid leaks. + vm_deallocate(task, + reinterpret_cast(thread_list), + sizeof(thread_t) * thread_count); + return static_cast(thread_count); + } else { + return 0; + } +} + +#else + +size_t GetThreadCount() { + // There's no portable way to detect the number of threads, so we just + // return 0 to indicate that we cannot detect it. + return 0; +} + +#endif // GTEST_OS_MAC + +#if GTEST_USES_POSIX_RE + +// Implements RE. Currently only needed for death tests. + +RE::~RE() { + if (is_valid_) { + // regfree'ing an invalid regex might crash because the content + // of the regex is undefined. Since the regex's are essentially + // the same, one cannot be valid (or invalid) without the other + // being so too. + regfree(&partial_regex_); + regfree(&full_regex_); + } + free(const_cast(pattern_)); +} + +// Returns true iff regular expression re matches the entire str. +bool RE::FullMatch(const char* str, const RE& re) { + if (!re.is_valid_) return false; + + regmatch_t match; + return regexec(&re.full_regex_, str, 1, &match, 0) == 0; +} + +// Returns true iff regular expression re matches a substring of str +// (including str itself). +bool RE::PartialMatch(const char* str, const RE& re) { + if (!re.is_valid_) return false; + + regmatch_t match; + return regexec(&re.partial_regex_, str, 1, &match, 0) == 0; +} + +// Initializes an RE from its string representation. +void RE::Init(const char* regex) { + pattern_ = posix::StrDup(regex); + + // Reserves enough bytes to hold the regular expression used for a + // full match. + const size_t full_regex_len = strlen(regex) + 10; + char* const full_pattern = new char[full_regex_len]; + + snprintf(full_pattern, full_regex_len, "^(%s)$", regex); + is_valid_ = regcomp(&full_regex_, full_pattern, REG_EXTENDED) == 0; + // We want to call regcomp(&partial_regex_, ...) even if the + // previous expression returns false. Otherwise partial_regex_ may + // not be properly initialized can may cause trouble when it's + // freed. + // + // Some implementation of POSIX regex (e.g. on at least some + // versions of Cygwin) doesn't accept the empty string as a valid + // regex. We change it to an equivalent form "()" to be safe. + if (is_valid_) { + const char* const partial_regex = (*regex == '\0') ? "()" : regex; + is_valid_ = regcomp(&partial_regex_, partial_regex, REG_EXTENDED) == 0; + } + EXPECT_TRUE(is_valid_) + << "Regular expression \"" << regex + << "\" is not a valid POSIX Extended regular expression."; + + delete[] full_pattern; +} + +#elif GTEST_USES_SIMPLE_RE + +// Returns true iff ch appears anywhere in str (excluding the +// terminating '\0' character). +bool IsInSet(char ch, const char* str) { + return ch != '\0' && strchr(str, ch) != NULL; +} + +// Returns true iff ch belongs to the given classification. Unlike +// similar functions in , these aren't affected by the +// current locale. +bool IsDigit(char ch) { return '0' <= ch && ch <= '9'; } +bool IsPunct(char ch) { + return IsInSet(ch, "^-!\"#$%&'()*+,./:;<=>?@[\\]_`{|}~"); +} +bool IsRepeat(char ch) { return IsInSet(ch, "?*+"); } +bool IsWhiteSpace(char ch) { return IsInSet(ch, " \f\n\r\t\v"); } +bool IsWordChar(char ch) { + return ('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z') || + ('0' <= ch && ch <= '9') || ch == '_'; +} + +// Returns true iff "\\c" is a supported escape sequence. +bool IsValidEscape(char c) { + return (IsPunct(c) || IsInSet(c, "dDfnrsStvwW")); +} + +// Returns true iff the given atom (specified by escaped and pattern) +// matches ch. The result is undefined if the atom is invalid. +bool AtomMatchesChar(bool escaped, char pattern_char, char ch) { + if (escaped) { // "\\p" where p is pattern_char. + switch (pattern_char) { + case 'd': return IsDigit(ch); + case 'D': return !IsDigit(ch); + case 'f': return ch == '\f'; + case 'n': return ch == '\n'; + case 'r': return ch == '\r'; + case 's': return IsWhiteSpace(ch); + case 'S': return !IsWhiteSpace(ch); + case 't': return ch == '\t'; + case 'v': return ch == '\v'; + case 'w': return IsWordChar(ch); + case 'W': return !IsWordChar(ch); + } + return IsPunct(pattern_char) && pattern_char == ch; + } + + return (pattern_char == '.' && ch != '\n') || pattern_char == ch; +} + +// Helper function used by ValidateRegex() to format error messages. +String FormatRegexSyntaxError(const char* regex, int index) { + return (Message() << "Syntax error at index " << index + << " in simple regular expression \"" << regex << "\": ").GetString(); +} + +// Generates non-fatal failures and returns false if regex is invalid; +// otherwise returns true. +bool ValidateRegex(const char* regex) { + if (regex == NULL) { + // TODO(wan@google.com): fix the source file location in the + // assertion failures to match where the regex is used in user + // code. + ADD_FAILURE() << "NULL is not a valid simple regular expression."; + return false; + } + + bool is_valid = true; + + // True iff ?, *, or + can follow the previous atom. + bool prev_repeatable = false; + for (int i = 0; regex[i]; i++) { + if (regex[i] == '\\') { // An escape sequence + i++; + if (regex[i] == '\0') { + ADD_FAILURE() << FormatRegexSyntaxError(regex, i - 1) + << "'\\' cannot appear at the end."; + return false; + } + + if (!IsValidEscape(regex[i])) { + ADD_FAILURE() << FormatRegexSyntaxError(regex, i - 1) + << "invalid escape sequence \"\\" << regex[i] << "\"."; + is_valid = false; + } + prev_repeatable = true; + } else { // Not an escape sequence. + const char ch = regex[i]; + + if (ch == '^' && i > 0) { + ADD_FAILURE() << FormatRegexSyntaxError(regex, i) + << "'^' can only appear at the beginning."; + is_valid = false; + } else if (ch == '$' && regex[i + 1] != '\0') { + ADD_FAILURE() << FormatRegexSyntaxError(regex, i) + << "'$' can only appear at the end."; + is_valid = false; + } else if (IsInSet(ch, "()[]{}|")) { + ADD_FAILURE() << FormatRegexSyntaxError(regex, i) + << "'" << ch << "' is unsupported."; + is_valid = false; + } else if (IsRepeat(ch) && !prev_repeatable) { + ADD_FAILURE() << FormatRegexSyntaxError(regex, i) + << "'" << ch << "' can only follow a repeatable token."; + is_valid = false; + } + + prev_repeatable = !IsInSet(ch, "^$?*+"); + } + } + + return is_valid; +} + +// Matches a repeated regex atom followed by a valid simple regular +// expression. The regex atom is defined as c if escaped is false, +// or \c otherwise. repeat is the repetition meta character (?, *, +// or +). The behavior is undefined if str contains too many +// characters to be indexable by size_t, in which case the test will +// probably time out anyway. We are fine with this limitation as +// std::string has it too. +bool MatchRepetitionAndRegexAtHead( + bool escaped, char c, char repeat, const char* regex, + const char* str) { + const size_t min_count = (repeat == '+') ? 1 : 0; + const size_t max_count = (repeat == '?') ? 1 : + static_cast(-1) - 1; + // We cannot call numeric_limits::max() as it conflicts with the + // max() macro on Windows. + + for (size_t i = 0; i <= max_count; ++i) { + // We know that the atom matches each of the first i characters in str. + if (i >= min_count && MatchRegexAtHead(regex, str + i)) { + // We have enough matches at the head, and the tail matches too. + // Since we only care about *whether* the pattern matches str + // (as opposed to *how* it matches), there is no need to find a + // greedy match. + return true; + } + if (str[i] == '\0' || !AtomMatchesChar(escaped, c, str[i])) + return false; + } + return false; +} + +// Returns true iff regex matches a prefix of str. regex must be a +// valid simple regular expression and not start with "^", or the +// result is undefined. +bool MatchRegexAtHead(const char* regex, const char* str) { + if (*regex == '\0') // An empty regex matches a prefix of anything. + return true; + + // "$" only matches the end of a string. Note that regex being + // valid guarantees that there's nothing after "$" in it. + if (*regex == '$') + return *str == '\0'; + + // Is the first thing in regex an escape sequence? + const bool escaped = *regex == '\\'; + if (escaped) + ++regex; + if (IsRepeat(regex[1])) { + // MatchRepetitionAndRegexAtHead() calls MatchRegexAtHead(), so + // here's an indirect recursion. It terminates as the regex gets + // shorter in each recursion. + return MatchRepetitionAndRegexAtHead( + escaped, regex[0], regex[1], regex + 2, str); + } else { + // regex isn't empty, isn't "$", and doesn't start with a + // repetition. We match the first atom of regex with the first + // character of str and recurse. + return (*str != '\0') && AtomMatchesChar(escaped, *regex, *str) && + MatchRegexAtHead(regex + 1, str + 1); + } +} + +// Returns true iff regex matches any substring of str. regex must be +// a valid simple regular expression, or the result is undefined. +// +// The algorithm is recursive, but the recursion depth doesn't exceed +// the regex length, so we won't need to worry about running out of +// stack space normally. In rare cases the time complexity can be +// exponential with respect to the regex length + the string length, +// but usually it's must faster (often close to linear). +bool MatchRegexAnywhere(const char* regex, const char* str) { + if (regex == NULL || str == NULL) + return false; + + if (*regex == '^') + return MatchRegexAtHead(regex + 1, str); + + // A successful match can be anywhere in str. + do { + if (MatchRegexAtHead(regex, str)) + return true; + } while (*str++ != '\0'); + return false; +} + +// Implements the RE class. + +RE::~RE() { + free(const_cast(pattern_)); + free(const_cast(full_pattern_)); +} + +// Returns true iff regular expression re matches the entire str. +bool RE::FullMatch(const char* str, const RE& re) { + return re.is_valid_ && MatchRegexAnywhere(re.full_pattern_, str); +} + +// Returns true iff regular expression re matches a substring of str +// (including str itself). +bool RE::PartialMatch(const char* str, const RE& re) { + return re.is_valid_ && MatchRegexAnywhere(re.pattern_, str); +} + +// Initializes an RE from its string representation. +void RE::Init(const char* regex) { + pattern_ = full_pattern_ = NULL; + if (regex != NULL) { + pattern_ = posix::StrDup(regex); + } + + is_valid_ = ValidateRegex(regex); + if (!is_valid_) { + // No need to calculate the full pattern when the regex is invalid. + return; + } + + const size_t len = strlen(regex); + // Reserves enough bytes to hold the regular expression used for a + // full match: we need space to prepend a '^', append a '$', and + // terminate the string with '\0'. + char* buffer = static_cast(malloc(len + 3)); + full_pattern_ = buffer; + + if (*regex != '^') + *buffer++ = '^'; // Makes sure full_pattern_ starts with '^'. + + // We don't use snprintf or strncpy, as they trigger a warning when + // compiled with VC++ 8.0. + memcpy(buffer, regex, len); + buffer += len; + + if (len == 0 || regex[len - 1] != '$') + *buffer++ = '$'; // Makes sure full_pattern_ ends with '$'. + + *buffer = '\0'; +} + +#endif // GTEST_USES_POSIX_RE + + +GTestLog::GTestLog(GTestLogSeverity severity, const char* file, int line) + : severity_(severity) { + const char* const marker = + severity == GTEST_INFO ? "[ INFO ]" : + severity == GTEST_WARNING ? "[WARNING]" : + severity == GTEST_ERROR ? "[ ERROR ]" : "[ FATAL ]"; + GetStream() << ::std::endl << marker << " " + << FormatFileLocation(file, line).c_str() << ": "; +} + +// Flushes the buffers and, if severity is GTEST_FATAL, aborts the program. +GTestLog::~GTestLog() { + GetStream() << ::std::endl; + if (severity_ == GTEST_FATAL) { + fflush(stderr); + posix::Abort(); + } +} +// Disable Microsoft deprecation warnings for POSIX functions called from +// this class (creat, dup, dup2, and close) +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable: 4996) +#endif // _MSC_VER + +#if GTEST_HAS_STREAM_REDIRECTION_ + +// Object that captures an output stream (stdout/stderr). +class CapturedStream { + public: + // The ctor redirects the stream to a temporary file. + CapturedStream(int fd) : fd_(fd), uncaptured_fd_(dup(fd)) { +#if GTEST_OS_WINDOWS + char temp_dir_path[MAX_PATH + 1] = { '\0' }; // NOLINT + char temp_file_path[MAX_PATH + 1] = { '\0' }; // NOLINT + + ::GetTempPathA(sizeof(temp_dir_path), temp_dir_path); + const UINT success = ::GetTempFileNameA(temp_dir_path, + "gtest_redir", + 0, // Generate unique file name. + temp_file_path); + GTEST_CHECK_(success != 0) + << "Unable to create a temporary file in " << temp_dir_path; + const int captured_fd = creat(temp_file_path, _S_IREAD | _S_IWRITE); + GTEST_CHECK_(captured_fd != -1) << "Unable to open temporary file " + << temp_file_path; + filename_ = temp_file_path; +#else + // There's no guarantee that a test has write access to the + // current directory, so we create the temporary file in the /tmp + // directory instead. + char name_template[] = "/tmp/captured_stream.XXXXXX"; + const int captured_fd = mkstemp(name_template); + filename_ = name_template; +#endif // GTEST_OS_WINDOWS + fflush(NULL); + dup2(captured_fd, fd_); + close(captured_fd); + } + + ~CapturedStream() { + remove(filename_.c_str()); + } + + String GetCapturedString() { + if (uncaptured_fd_ != -1) { + // Restores the original stream. + fflush(NULL); + dup2(uncaptured_fd_, fd_); + close(uncaptured_fd_); + uncaptured_fd_ = -1; + } + + FILE* const file = posix::FOpen(filename_.c_str(), "r"); + const String content = ReadEntireFile(file); + posix::FClose(file); + return content; + } + + private: + // Reads the entire content of a file as a String. + static String ReadEntireFile(FILE* file); + + // Returns the size (in bytes) of a file. + static size_t GetFileSize(FILE* file); + + const int fd_; // A stream to capture. + int uncaptured_fd_; + // Name of the temporary file holding the stderr output. + ::std::string filename_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(CapturedStream); +}; + +// Returns the size (in bytes) of a file. +size_t CapturedStream::GetFileSize(FILE* file) { + fseek(file, 0, SEEK_END); + return static_cast(ftell(file)); +} + +// Reads the entire content of a file as a string. +String CapturedStream::ReadEntireFile(FILE* file) { + const size_t file_size = GetFileSize(file); + char* const buffer = new char[file_size]; + + size_t bytes_last_read = 0; // # of bytes read in the last fread() + size_t bytes_read = 0; // # of bytes read so far + + fseek(file, 0, SEEK_SET); + + // Keeps reading the file until we cannot read further or the + // pre-determined file size is reached. + do { + bytes_last_read = fread(buffer+bytes_read, 1, file_size-bytes_read, file); + bytes_read += bytes_last_read; + } while (bytes_last_read > 0 && bytes_read < file_size); + + const String content(buffer, bytes_read); + delete[] buffer; + + return content; +} + +#ifdef _MSC_VER +#pragma warning(pop) +#endif // _MSC_VER + +static CapturedStream* g_captured_stderr = NULL; +static CapturedStream* g_captured_stdout = NULL; + +// Starts capturing an output stream (stdout/stderr). +void CaptureStream(int fd, const char* stream_name, CapturedStream** stream) { + if (*stream != NULL) { + GTEST_LOG_(FATAL) << "Only one " << stream_name + << " capturer can exist at a time."; + } + *stream = new CapturedStream(fd); +} + +// Stops capturing the output stream and returns the captured string. +String GetCapturedStream(CapturedStream** captured_stream) { + const String content = (*captured_stream)->GetCapturedString(); + + delete *captured_stream; + *captured_stream = NULL; + + return content; +} + +// Starts capturing stdout. +void CaptureStdout() { + CaptureStream(kStdOutFileno, "stdout", &g_captured_stdout); +} + +// Starts capturing stderr. +void CaptureStderr() { + CaptureStream(kStdErrFileno, "stderr", &g_captured_stderr); +} + +// Stops capturing stdout and returns the captured string. +String GetCapturedStdout() { return GetCapturedStream(&g_captured_stdout); } + +// Stops capturing stderr and returns the captured string. +String GetCapturedStderr() { return GetCapturedStream(&g_captured_stderr); } + +#endif // GTEST_HAS_STREAM_REDIRECTION_ + +#if GTEST_HAS_DEATH_TEST + +// A copy of all command line arguments. Set by InitGoogleTest(). +::std::vector g_argvs; + +// Returns the command line as a vector of strings. +const ::std::vector& GetArgvs() { return g_argvs; } + +#endif // GTEST_HAS_DEATH_TEST + +#if GTEST_OS_WINDOWS_MOBILE +namespace posix { +void Abort() { + DebugBreak(); + TerminateProcess(GetCurrentProcess(), 1); +} +} // namespace posix +#endif // GTEST_OS_WINDOWS_MOBILE + +// Returns the name of the environment variable corresponding to the +// given flag. For example, FlagToEnvVar("foo") will return +// "GTEST_FOO" in the open-source version. +static String FlagToEnvVar(const char* flag) { + const String full_flag = + (Message() << GTEST_FLAG_PREFIX_ << flag).GetString(); + + Message env_var; + for (size_t i = 0; i != full_flag.length(); i++) { + env_var << static_cast(toupper(full_flag.c_str()[i])); + } + + return env_var.GetString(); +} + +// Parses 'str' for a 32-bit signed integer. If successful, writes +// the result to *value and returns true; otherwise leaves *value +// unchanged and returns false. +bool ParseInt32(const Message& src_text, const char* str, Int32* value) { + // Parses the environment variable as a decimal integer. + char* end = NULL; + const long long_value = strtol(str, &end, 10); // NOLINT + + // Has strtol() consumed all characters in the string? + if (*end != '\0') { + // No - an invalid character was encountered. + Message msg; + msg << "WARNING: " << src_text + << " is expected to be a 32-bit integer, but actually" + << " has value \"" << str << "\".\n"; + printf("%s", msg.GetString().c_str()); + fflush(stdout); + return false; + } + + // Is the parsed value in the range of an Int32? + const Int32 result = static_cast(long_value); + if (long_value == LONG_MAX || long_value == LONG_MIN || + // The parsed value overflows as a long. (strtol() returns + // LONG_MAX or LONG_MIN when the input overflows.) + result != long_value + // The parsed value overflows as an Int32. + ) { + Message msg; + msg << "WARNING: " << src_text + << " is expected to be a 32-bit integer, but actually" + << " has value " << str << ", which overflows.\n"; + printf("%s", msg.GetString().c_str()); + fflush(stdout); + return false; + } + + *value = result; + return true; +} + +// Reads and returns the Boolean environment variable corresponding to +// the given flag; if it's not set, returns default_value. +// +// The value is considered true iff it's not "0". +bool BoolFromGTestEnv(const char* flag, bool default_value) { + const String env_var = FlagToEnvVar(flag); + const char* const string_value = posix::GetEnv(env_var.c_str()); + return string_value == NULL ? + default_value : strcmp(string_value, "0") != 0; +} + +// Reads and returns a 32-bit integer stored in the environment +// variable corresponding to the given flag; if it isn't set or +// doesn't represent a valid 32-bit integer, returns default_value. +Int32 Int32FromGTestEnv(const char* flag, Int32 default_value) { + const String env_var = FlagToEnvVar(flag); + const char* const string_value = posix::GetEnv(env_var.c_str()); + if (string_value == NULL) { + // The environment variable is not set. + return default_value; + } + + Int32 result = default_value; + if (!ParseInt32(Message() << "Environment variable " << env_var, + string_value, &result)) { + printf("The default value %s is used.\n", + (Message() << default_value).GetString().c_str()); + fflush(stdout); + return default_value; + } + + return result; +} + +// Reads and returns the string environment variable corresponding to +// the given flag; if it's not set, returns default_value. +const char* StringFromGTestEnv(const char* flag, const char* default_value) { + const String env_var = FlagToEnvVar(flag); + const char* const value = posix::GetEnv(env_var.c_str()); + return value == NULL ? default_value : value; +} + +} // namespace internal +} // namespace testing +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: mheule@google.com (Markus Heule) +// +// The Google C++ Testing Framework (Google Test) + + +// Indicates that this translation unit is part of Google Test's +// implementation. It must come before gtest-internal-inl.h is +// included, or there will be a compiler error. This trick is to +// prevent a user from accidentally including gtest-internal-inl.h in +// his code. +#define GTEST_IMPLEMENTATION_ 1 +#undef GTEST_IMPLEMENTATION_ + +namespace testing { + +using internal::GetUnitTestImpl; + +// Gets the summary of the failure message by omitting the stack trace +// in it. +internal::String TestPartResult::ExtractSummary(const char* message) { + const char* const stack_trace = strstr(message, internal::kStackTraceMarker); + return stack_trace == NULL ? internal::String(message) : + internal::String(message, stack_trace - message); +} + +// Prints a TestPartResult object. +std::ostream& operator<<(std::ostream& os, const TestPartResult& result) { + return os + << result.file_name() << ":" << result.line_number() << ": " + << (result.type() == TestPartResult::kSuccess ? "Success" : + result.type() == TestPartResult::kFatalFailure ? "Fatal failure" : + "Non-fatal failure") << ":\n" + << result.message() << std::endl; +} + +// Appends a TestPartResult to the array. +void TestPartResultArray::Append(const TestPartResult& result) { + array_.push_back(result); +} + +// Returns the TestPartResult at the given index (0-based). +const TestPartResult& TestPartResultArray::GetTestPartResult(int index) const { + if (index < 0 || index >= size()) { + printf("\nInvalid index (%d) into TestPartResultArray.\n", index); + internal::posix::Abort(); + } + + return array_[index]; +} + +// Returns the number of TestPartResult objects in the array. +int TestPartResultArray::size() const { + return static_cast(array_.size()); +} + +namespace internal { + +HasNewFatalFailureHelper::HasNewFatalFailureHelper() + : has_new_fatal_failure_(false), + original_reporter_(GetUnitTestImpl()-> + GetTestPartResultReporterForCurrentThread()) { + GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread(this); +} + +HasNewFatalFailureHelper::~HasNewFatalFailureHelper() { + GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread( + original_reporter_); +} + +void HasNewFatalFailureHelper::ReportTestPartResult( + const TestPartResult& result) { + if (result.fatally_failed()) + has_new_fatal_failure_ = true; + original_reporter_->ReportTestPartResult(result); +} + +} // namespace internal + +} // namespace testing +// Copyright 2008 Google Inc. +// All Rights Reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: wan@google.com (Zhanyong Wan) + + +namespace testing { +namespace internal { + +#if GTEST_HAS_TYPED_TEST_P + +// Skips to the first non-space char in str. Returns an empty string if str +// contains only whitespace characters. +static const char* SkipSpaces(const char* str) { + while (isspace(*str)) + str++; + return str; +} + +// Verifies that registered_tests match the test names in +// defined_test_names_; returns registered_tests if successful, or +// aborts the program otherwise. +const char* TypedTestCasePState::VerifyRegisteredTestNames( + const char* file, int line, const char* registered_tests) { + typedef ::std::set::const_iterator DefinedTestIter; + registered_ = true; + + // Skip initial whitespace in registered_tests since some + // preprocessors prefix stringizied literals with whitespace. + registered_tests = SkipSpaces(registered_tests); + + Message errors; + ::std::set tests; + for (const char* names = registered_tests; names != NULL; + names = SkipComma(names)) { + const String name = GetPrefixUntilComma(names); + if (tests.count(name) != 0) { + errors << "Test " << name << " is listed more than once.\n"; + continue; + } + + bool found = false; + for (DefinedTestIter it = defined_test_names_.begin(); + it != defined_test_names_.end(); + ++it) { + if (name == *it) { + found = true; + break; + } + } + + if (found) { + tests.insert(name); + } else { + errors << "No test named " << name + << " can be found in this test case.\n"; + } + } + + for (DefinedTestIter it = defined_test_names_.begin(); + it != defined_test_names_.end(); + ++it) { + if (tests.count(*it) == 0) { + errors << "You forgot to list test " << *it << ".\n"; + } + } + + const String& errors_str = errors.GetString(); + if (errors_str != "") { + fprintf(stderr, "%s %s", FormatFileLocation(file, line).c_str(), + errors_str.c_str()); + fflush(stderr); + posix::Abort(); + } + + return registered_tests; +} + +#endif // GTEST_HAS_TYPED_TEST_P + +} // namespace internal +} // namespace testing diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmXml_UnitTests/gtest/gtest.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmXml_UnitTests/gtest/gtest.h new file mode 100644 index 0000000000..c0a1902e25 --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmXml_UnitTests/gtest/gtest.h @@ -0,0 +1,18007 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: wan@google.com (Zhanyong Wan) +// +// The Google C++ Testing Framework (Google Test) +// +// This header file defines the public API for Google Test. It should be +// included by any test program that uses Google Test. +// +// IMPORTANT NOTE: Due to limitation of the C++ language, we have to +// leave some internal implementation details in this header file. +// They are clearly marked by comments like this: +// +// // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +// +// Such code is NOT meant to be used by a user directly, and is subject +// to CHANGE WITHOUT NOTICE. Therefore DO NOT DEPEND ON IT in a user +// program! +// +// Acknowledgment: Google Test borrowed the idea of automatic test +// registration from Barthelemy Dagenais' (barthelemy@prologique.com) +// easyUnit framework. + +#ifndef GTEST_INCLUDE_GTEST_GTEST_H_ +#define GTEST_INCLUDE_GTEST_GTEST_H_ + +#include +#include + +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee) +// +// The Google C++ Testing Framework (Google Test) +// +// This header file declares functions and macros used internally by +// Google Test. They are subject to change without notice. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_ + +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: wan@google.com (Zhanyong Wan) +// +// Low-level types and utilities for porting Google Test to various +// platforms. They are subject to change without notice. DO NOT USE +// THEM IN USER CODE. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_ + +// The user can define the following macros in the build script to +// control Google Test's behavior. If the user doesn't define a macro +// in this list, Google Test will define it. +// +// GTEST_HAS_CLONE - Define it to 1/0 to indicate that clone(2) +// is/isn't available. +// GTEST_HAS_EXCEPTIONS - Define it to 1/0 to indicate that exceptions +// are enabled. +// GTEST_HAS_GLOBAL_STRING - Define it to 1/0 to indicate that ::string +// is/isn't available (some systems define +// ::string, which is different to std::string). +// GTEST_HAS_GLOBAL_WSTRING - Define it to 1/0 to indicate that ::string +// is/isn't available (some systems define +// ::wstring, which is different to std::wstring). +// GTEST_HAS_PTHREAD - Define it to 1/0 to indicate that +// is/isn't available. +// GTEST_HAS_RTTI - Define it to 1/0 to indicate that RTTI is/isn't +// enabled. +// GTEST_HAS_STD_WSTRING - Define it to 1/0 to indicate that +// std::wstring does/doesn't work (Google Test can +// be used where std::wstring is unavailable). +// GTEST_HAS_TR1_TUPLE - Define it to 1/0 to indicate tr1::tuple +// is/isn't available. +// GTEST_HAS_SEH - Define it to 1/0 to indicate whether the +// compiler supports Microsoft's "Structured +// Exception Handling". +// GTEST_USE_OWN_TR1_TUPLE - Define it to 1/0 to indicate whether Google +// Test's own tr1 tuple implementation should be +// used. Unused when the user sets +// GTEST_HAS_TR1_TUPLE to 0. +// GTEST_LINKED_AS_SHARED_LIBRARY +// - Define to 1 when compiling tests that use +// Google Test as a shared library (known as +// DLL on Windows). +// GTEST_CREATE_SHARED_LIBRARY +// - Define to 1 when compiling Google Test itself +// as a shared library. + +// This header defines the following utilities: +// +// Macros indicating the current platform (defined to 1 if compiled on +// the given platform; otherwise undefined): +// GTEST_OS_AIX - IBM AIX +// GTEST_OS_CYGWIN - Cygwin +// GTEST_OS_LINUX - Linux +// GTEST_OS_MAC - Mac OS X +// GTEST_OS_SOLARIS - Sun Solaris +// GTEST_OS_SYMBIAN - Symbian +// GTEST_OS_WINDOWS - Windows (Desktop, MinGW, or Mobile) +// GTEST_OS_WINDOWS_DESKTOP - Windows Desktop +// GTEST_OS_WINDOWS_MINGW - MinGW +// GTEST_OS_WINDOWS_MOBILE - Windows Mobile +// GTEST_OS_ZOS - z/OS +// +// Among the platforms, Cygwin, Linux, Max OS X, and Windows have the +// most stable support. Since core members of the Google Test project +// don't have access to other platforms, support for them may be less +// stable. If you notice any problems on your platform, please notify +// googletestframework@googlegroups.com (patches for fixing them are +// even more welcome!). +// +// Note that it is possible that none of the GTEST_OS_* macros are defined. +// +// Macros indicating available Google Test features (defined to 1 if +// the corresponding feature is supported; otherwise undefined): +// GTEST_HAS_COMBINE - the Combine() function (for value-parameterized +// tests) +// GTEST_HAS_DEATH_TEST - death tests +// GTEST_HAS_PARAM_TEST - value-parameterized tests +// GTEST_HAS_TYPED_TEST - typed tests +// GTEST_HAS_TYPED_TEST_P - type-parameterized tests +// GTEST_USES_POSIX_RE - enhanced POSIX regex is used. +// GTEST_USES_SIMPLE_RE - our own simple regex is used; +// the above two are mutually exclusive. +// GTEST_CAN_COMPARE_NULL - accepts untyped NULL in EXPECT_EQ(). +// +// Macros for basic C++ coding: +// GTEST_AMBIGUOUS_ELSE_BLOCKER_ - for disabling a gcc warning. +// GTEST_ATTRIBUTE_UNUSED_ - declares that a class' instances or a +// variable don't have to be used. +// GTEST_DISALLOW_ASSIGN_ - disables operator=. +// GTEST_DISALLOW_COPY_AND_ASSIGN_ - disables copy ctor and operator=. +// GTEST_MUST_USE_RESULT_ - declares that a function's result must be used. +// +// Synchronization: +// Mutex, MutexLock, ThreadLocal, GetThreadCount() +// - synchronization primitives. +// GTEST_IS_THREADSAFE - defined to 1 to indicate that the above +// synchronization primitives have real implementations +// and Google Test is thread-safe; or 0 otherwise. +// +// Template meta programming: +// is_pointer - as in TR1; needed on Symbian and IBM XL C/C++ only. +// +// Smart pointers: +// scoped_ptr - as in TR2. +// +// Regular expressions: +// RE - a simple regular expression class using the POSIX +// Extended Regular Expression syntax. Not available on +// Windows. +// +// Logging: +// GTEST_LOG_() - logs messages at the specified severity level. +// LogToStderr() - directs all log messages to stderr. +// FlushInfoLog() - flushes informational log messages. +// +// Stdout and stderr capturing: +// CaptureStdout() - starts capturing stdout. +// GetCapturedStdout() - stops capturing stdout and returns the captured +// string. +// CaptureStderr() - starts capturing stderr. +// GetCapturedStderr() - stops capturing stderr and returns the captured +// string. +// +// Integer types: +// TypeWithSize - maps an integer to a int type. +// Int32, UInt32, Int64, UInt64, TimeInMillis +// - integers of known sizes. +// BiggestInt - the biggest signed integer type. +// +// Command-line utilities: +// GTEST_FLAG() - references a flag. +// GTEST_DECLARE_*() - declares a flag. +// GTEST_DEFINE_*() - defines a flag. +// GetArgvs() - returns the command line as a vector of strings. +// +// Environment variable utilities: +// GetEnv() - gets the value of an environment variable. +// BoolFromGTestEnv() - parses a bool environment variable. +// Int32FromGTestEnv() - parses an Int32 environment variable. +// StringFromGTestEnv() - parses a string environment variable. + +#include // For ptrdiff_t +#include +#include +#include +#ifndef _WIN32_WCE +#include +#endif // !_WIN32_WCE + +#include // NOLINT +#include // NOLINT +#include // NOLINT + +#define GTEST_DEV_EMAIL_ "googletestframework@@googlegroups.com" +#define GTEST_FLAG_PREFIX_ "gtest_" +#define GTEST_FLAG_PREFIX_DASH_ "gtest-" +#define GTEST_FLAG_PREFIX_UPPER_ "GTEST_" +#define GTEST_NAME_ "Google Test" +#define GTEST_PROJECT_URL_ "http://code.google.com/p/googletest/" + +// Determines the version of gcc that is used to compile this. +#ifdef __GNUC__ +// 40302 means version 4.3.2. +#define GTEST_GCC_VER_ \ + (__GNUC__*10000 + __GNUC_MINOR__*100 + __GNUC_PATCHLEVEL__) +#endif // __GNUC__ + +// Determines the platform on which Google Test is compiled. +#ifdef __CYGWIN__ +#define GTEST_OS_CYGWIN 1 +#elif defined __SYMBIAN32__ +#define GTEST_OS_SYMBIAN 1 +#elif defined _WIN32 +#define GTEST_OS_WINDOWS 1 +#ifdef _WIN32_WCE +#define GTEST_OS_WINDOWS_MOBILE 1 +#elif defined(__MINGW__) || defined(__MINGW32__) +#define GTEST_OS_WINDOWS_MINGW 1 +#else +#define GTEST_OS_WINDOWS_DESKTOP 1 +#endif // _WIN32_WCE +#elif defined __APPLE__ +#define GTEST_OS_MAC 1 +#elif defined __linux__ +#define GTEST_OS_LINUX 1 +#elif defined __MVS__ +#define GTEST_OS_ZOS 1 +#elif defined(__sun) && defined(__SVR4) +#define GTEST_OS_SOLARIS 1 +#elif defined(_AIX) +#define GTEST_OS_AIX 1 +#endif // __CYGWIN__ + +#if GTEST_OS_CYGWIN || GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_SYMBIAN || \ + GTEST_OS_SOLARIS || GTEST_OS_AIX + +// On some platforms, needs someone to define size_t, and +// won't compile otherwise. We can #include it here as we already +// included , which is guaranteed to define size_t through +// . +#include // NOLINT +#include // NOLINT +#include // NOLINT +#include // NOLINT +#include // NOLINT + +#define GTEST_USES_POSIX_RE 1 + +#elif GTEST_OS_WINDOWS + +#if !GTEST_OS_WINDOWS_MOBILE +#include // NOLINT +#include // NOLINT +#endif + +// is not available on Windows. Use our own simple regex +// implementation instead. +#define GTEST_USES_SIMPLE_RE 1 + +#else + +// may not be available on this platform. Use our own +// simple regex implementation instead. +#define GTEST_USES_SIMPLE_RE 1 + +#endif // GTEST_OS_CYGWIN || GTEST_OS_LINUX || GTEST_OS_MAC || + // GTEST_OS_SYMBIAN || GTEST_OS_SOLARIS || GTEST_OS_AIX + +#ifndef GTEST_HAS_EXCEPTIONS +// The user didn't tell us whether exceptions are enabled, so we need +// to figure it out. +#if defined(_MSC_VER) || defined(__BORLANDC__) +// MSVC's and C++Builder's implementations of the STL use the _HAS_EXCEPTIONS +// macro to enable exceptions, so we'll do the same. +// Assumes that exceptions are enabled by default. +#ifndef _HAS_EXCEPTIONS +#define _HAS_EXCEPTIONS 1 +#endif // _HAS_EXCEPTIONS +#define GTEST_HAS_EXCEPTIONS _HAS_EXCEPTIONS +#elif defined(__GNUC__) && __EXCEPTIONS +// gcc defines __EXCEPTIONS to 1 iff exceptions are enabled. +#define GTEST_HAS_EXCEPTIONS 1 +#elif defined(__SUNPRO_CC) +// Sun Pro CC supports exceptions. However, there is no compile-time way of +// detecting whether they are enabled or not. Therefore, we assume that +// they are enabled unless the user tells us otherwise. +#define GTEST_HAS_EXCEPTIONS 1 +#elif defined(__IBMCPP__) && __EXCEPTIONS +// xlC defines __EXCEPTIONS to 1 iff exceptions are enabled. +#define GTEST_HAS_EXCEPTIONS 1 +#else +// For other compilers, we assume exceptions are disabled to be +// conservative. +#define GTEST_HAS_EXCEPTIONS 0 +#endif // defined(_MSC_VER) || defined(__BORLANDC__) +#endif // GTEST_HAS_EXCEPTIONS + +#if !defined(GTEST_HAS_STD_STRING) +// Even though we don't use this macro any longer, we keep it in case +// some clients still depend on it. +#define GTEST_HAS_STD_STRING 1 +#elif !GTEST_HAS_STD_STRING +// The user told us that ::std::string isn't available. +#error "Google Test cannot be used where ::std::string isn't available." +#endif // !defined(GTEST_HAS_STD_STRING) + +#ifndef GTEST_HAS_GLOBAL_STRING +// The user didn't tell us whether ::string is available, so we need +// to figure it out. + +#define GTEST_HAS_GLOBAL_STRING 0 + +#endif // GTEST_HAS_GLOBAL_STRING + +#ifndef GTEST_HAS_STD_WSTRING +// The user didn't tell us whether ::std::wstring is available, so we need +// to figure it out. +// TODO(wan@google.com): uses autoconf to detect whether ::std::wstring +// is available. + +// Cygwin 1.5 and below doesn't support ::std::wstring. +// Cygwin 1.7 might add wstring support; this should be updated when clear. +// Solaris' libc++ doesn't support it either. +#define GTEST_HAS_STD_WSTRING (!(GTEST_OS_CYGWIN || GTEST_OS_SOLARIS)) + +#endif // GTEST_HAS_STD_WSTRING + +#ifndef GTEST_HAS_GLOBAL_WSTRING +// The user didn't tell us whether ::wstring is available, so we need +// to figure it out. +#define GTEST_HAS_GLOBAL_WSTRING \ + (GTEST_HAS_STD_WSTRING && GTEST_HAS_GLOBAL_STRING) +#endif // GTEST_HAS_GLOBAL_WSTRING + +// Determines whether RTTI is available. +#ifndef GTEST_HAS_RTTI +// The user didn't tell us whether RTTI is enabled, so we need to +// figure it out. + +#ifdef _MSC_VER + +#ifdef _CPPRTTI // MSVC defines this macro iff RTTI is enabled. +#define GTEST_HAS_RTTI 1 +#else +#define GTEST_HAS_RTTI 0 +#endif + +// Starting with version 4.3.2, gcc defines __GXX_RTTI iff RTTI is enabled. +#elif defined(__GNUC__) && (GTEST_GCC_VER_ >= 40302) + +#ifdef __GXX_RTTI +#define GTEST_HAS_RTTI 1 +#else +#define GTEST_HAS_RTTI 0 +#endif // __GXX_RTTI + +// Starting with version 9.0 IBM Visual Age defines __RTTI_ALL__ to 1 if +// both the typeid and dynamic_cast features are present. +#elif defined(__IBMCPP__) && (__IBMCPP__ >= 900) + +#ifdef __RTTI_ALL__ +#define GTEST_HAS_RTTI 1 +#else +#define GTEST_HAS_RTTI 0 +#endif + +#else + +// For all other compilers, we assume RTTI is enabled. +#define GTEST_HAS_RTTI 1 + +#endif // _MSC_VER + +#endif // GTEST_HAS_RTTI + +// It's this header's responsibility to #include when RTTI +// is enabled. +#if GTEST_HAS_RTTI +#include +#endif + +// Determines whether Google Test can use the pthreads library. +#ifndef GTEST_HAS_PTHREAD +// The user didn't tell us explicitly, so we assume pthreads support is +// available on Linux and Mac. +// +// To disable threading support in Google Test, add -DGTEST_HAS_PTHREAD=0 +// to your compiler flags. +#define GTEST_HAS_PTHREAD (GTEST_OS_LINUX || GTEST_OS_MAC) +#endif // GTEST_HAS_PTHREAD + +// Determines whether Google Test can use tr1/tuple. You can define +// this macro to 0 to prevent Google Test from using tuple (any +// feature depending on tuple with be disabled in this mode). +#ifndef GTEST_HAS_TR1_TUPLE +// The user didn't tell us not to do it, so we assume it's OK. +#define GTEST_HAS_TR1_TUPLE 1 +#endif // GTEST_HAS_TR1_TUPLE + +// Determines whether Google Test's own tr1 tuple implementation +// should be used. +#ifndef GTEST_USE_OWN_TR1_TUPLE +// The user didn't tell us, so we need to figure it out. + +// We use our own TR1 tuple if we aren't sure the user has an +// implementation of it already. At this time, GCC 4.0.0+ and MSVC +// 2010 are the only mainstream compilers that come with a TR1 tuple +// implementation. NVIDIA's CUDA NVCC compiler pretends to be GCC by +// defining __GNUC__ and friends, but cannot compile GCC's tuple +// implementation. MSVC 2008 (9.0) provides TR1 tuple in a 323 MB +// Feature Pack download, which we cannot assume the user has. +#if (defined(__GNUC__) && !defined(__CUDACC__) && (GTEST_GCC_VER_ >= 40000)) \ + || _MSC_VER >= 1600 +#define GTEST_USE_OWN_TR1_TUPLE 0 +#else +#define GTEST_USE_OWN_TR1_TUPLE 1 +#endif + +#endif // GTEST_USE_OWN_TR1_TUPLE + +// To avoid conditional compilation everywhere, we make it +// gtest-port.h's responsibility to #include the header implementing +// tr1/tuple. +#if GTEST_HAS_TR1_TUPLE + +#if GTEST_USE_OWN_TR1_TUPLE +// This file was GENERATED by a script. DO NOT EDIT BY HAND!!! + +// Copyright 2009 Google Inc. +// All Rights Reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: wan@google.com (Zhanyong Wan) + +// Implements a subset of TR1 tuple needed by Google Test and Google Mock. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_ + +#include // For ::std::pair. + +// The compiler used in Symbian has a bug that prevents us from declaring the +// tuple template as a friend (it complains that tuple is redefined). This +// hack bypasses the bug by declaring the members that should otherwise be +// private as public. +// Sun Studio versions < 12 also have the above bug. +#if defined(__SYMBIAN32__) || (defined(__SUNPRO_CC) && __SUNPRO_CC < 0x590) +#define GTEST_DECLARE_TUPLE_AS_FRIEND_ public: +#else +#define GTEST_DECLARE_TUPLE_AS_FRIEND_ \ + template friend class tuple; \ + private: +#endif + +// GTEST_n_TUPLE_(T) is the type of an n-tuple. +#define GTEST_0_TUPLE_(T) tuple<> +#define GTEST_1_TUPLE_(T) tuple +#define GTEST_2_TUPLE_(T) tuple +#define GTEST_3_TUPLE_(T) tuple +#define GTEST_4_TUPLE_(T) tuple +#define GTEST_5_TUPLE_(T) tuple +#define GTEST_6_TUPLE_(T) tuple +#define GTEST_7_TUPLE_(T) tuple +#define GTEST_8_TUPLE_(T) tuple +#define GTEST_9_TUPLE_(T) tuple +#define GTEST_10_TUPLE_(T) tuple + +// GTEST_n_TYPENAMES_(T) declares a list of n typenames. +#define GTEST_0_TYPENAMES_(T) +#define GTEST_1_TYPENAMES_(T) typename T##0 +#define GTEST_2_TYPENAMES_(T) typename T##0, typename T##1 +#define GTEST_3_TYPENAMES_(T) typename T##0, typename T##1, typename T##2 +#define GTEST_4_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ + typename T##3 +#define GTEST_5_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ + typename T##3, typename T##4 +#define GTEST_6_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ + typename T##3, typename T##4, typename T##5 +#define GTEST_7_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ + typename T##3, typename T##4, typename T##5, typename T##6 +#define GTEST_8_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ + typename T##3, typename T##4, typename T##5, typename T##6, typename T##7 +#define GTEST_9_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ + typename T##3, typename T##4, typename T##5, typename T##6, \ + typename T##7, typename T##8 +#define GTEST_10_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ + typename T##3, typename T##4, typename T##5, typename T##6, \ + typename T##7, typename T##8, typename T##9 + +// In theory, defining stuff in the ::std namespace is undefined +// behavior. We can do this as we are playing the role of a standard +// library vendor. +namespace std { +namespace tr1 { + +template +class tuple; + +// Anything in namespace gtest_internal is Google Test's INTERNAL +// IMPLEMENTATION DETAIL and MUST NOT BE USED DIRECTLY in user code. +namespace gtest_internal { + +// ByRef::type is T if T is a reference; otherwise it's const T&. +template +struct ByRef { typedef const T& type; }; // NOLINT +template +struct ByRef { typedef T& type; }; // NOLINT + +// A handy wrapper for ByRef. +#define GTEST_BY_REF_(T) typename ::std::tr1::gtest_internal::ByRef::type + +// AddRef::type is T if T is a reference; otherwise it's T&. This +// is the same as tr1::add_reference::type. +template +struct AddRef { typedef T& type; }; // NOLINT +template +struct AddRef { typedef T& type; }; // NOLINT + +// A handy wrapper for AddRef. +#define GTEST_ADD_REF_(T) typename ::std::tr1::gtest_internal::AddRef::type + +// A helper for implementing get(). +template class Get; + +// A helper for implementing tuple_element. kIndexValid is true +// iff k < the number of fields in tuple type T. +template +struct TupleElement; + +template +struct TupleElement { typedef T0 type; }; + +template +struct TupleElement { typedef T1 type; }; + +template +struct TupleElement { typedef T2 type; }; + +template +struct TupleElement { typedef T3 type; }; + +template +struct TupleElement { typedef T4 type; }; + +template +struct TupleElement { typedef T5 type; }; + +template +struct TupleElement { typedef T6 type; }; + +template +struct TupleElement { typedef T7 type; }; + +template +struct TupleElement { typedef T8 type; }; + +template +struct TupleElement { typedef T9 type; }; + +} // namespace gtest_internal + +template <> +class tuple<> { + public: + tuple() {} + tuple(const tuple& /* t */) {} + tuple& operator=(const tuple& /* t */) { return *this; } +}; + +template +class GTEST_1_TUPLE_(T) { + public: + template friend class gtest_internal::Get; + + tuple() : f0_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0) : f0_(f0) {} + + tuple(const tuple& t) : f0_(t.f0_) {} + + template + tuple(const GTEST_1_TUPLE_(U)& t) : f0_(t.f0_) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template + tuple& operator=(const GTEST_1_TUPLE_(U)& t) { + return CopyFrom(t); + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template + tuple& CopyFrom(const GTEST_1_TUPLE_(U)& t) { + f0_ = t.f0_; + return *this; + } + + T0 f0_; +}; + +template +class GTEST_2_TUPLE_(T) { + public: + template friend class gtest_internal::Get; + + tuple() : f0_(), f1_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1) : f0_(f0), + f1_(f1) {} + + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_) {} + + template + tuple(const GTEST_2_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_) {} + template + tuple(const ::std::pair& p) : f0_(p.first), f1_(p.second) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template + tuple& operator=(const GTEST_2_TUPLE_(U)& t) { + return CopyFrom(t); + } + template + tuple& operator=(const ::std::pair& p) { + f0_ = p.first; + f1_ = p.second; + return *this; + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template + tuple& CopyFrom(const GTEST_2_TUPLE_(U)& t) { + f0_ = t.f0_; + f1_ = t.f1_; + return *this; + } + + T0 f0_; + T1 f1_; +}; + +template +class GTEST_3_TUPLE_(T) { + public: + template friend class gtest_internal::Get; + + tuple() : f0_(), f1_(), f2_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, + GTEST_BY_REF_(T2) f2) : f0_(f0), f1_(f1), f2_(f2) {} + + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_) {} + + template + tuple(const GTEST_3_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template + tuple& operator=(const GTEST_3_TUPLE_(U)& t) { + return CopyFrom(t); + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template + tuple& CopyFrom(const GTEST_3_TUPLE_(U)& t) { + f0_ = t.f0_; + f1_ = t.f1_; + f2_ = t.f2_; + return *this; + } + + T0 f0_; + T1 f1_; + T2 f2_; +}; + +template +class GTEST_4_TUPLE_(T) { + public: + template friend class gtest_internal::Get; + + tuple() : f0_(), f1_(), f2_(), f3_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, + GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3) : f0_(f0), f1_(f1), f2_(f2), + f3_(f3) {} + + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_) {} + + template + tuple(const GTEST_4_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), + f3_(t.f3_) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template + tuple& operator=(const GTEST_4_TUPLE_(U)& t) { + return CopyFrom(t); + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template + tuple& CopyFrom(const GTEST_4_TUPLE_(U)& t) { + f0_ = t.f0_; + f1_ = t.f1_; + f2_ = t.f2_; + f3_ = t.f3_; + return *this; + } + + T0 f0_; + T1 f1_; + T2 f2_; + T3 f3_; +}; + +template +class GTEST_5_TUPLE_(T) { + public: + template friend class gtest_internal::Get; + + tuple() : f0_(), f1_(), f2_(), f3_(), f4_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, + GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, + GTEST_BY_REF_(T4) f4) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4) {} + + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), + f4_(t.f4_) {} + + template + tuple(const GTEST_5_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), + f3_(t.f3_), f4_(t.f4_) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template + tuple& operator=(const GTEST_5_TUPLE_(U)& t) { + return CopyFrom(t); + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template + tuple& CopyFrom(const GTEST_5_TUPLE_(U)& t) { + f0_ = t.f0_; + f1_ = t.f1_; + f2_ = t.f2_; + f3_ = t.f3_; + f4_ = t.f4_; + return *this; + } + + T0 f0_; + T1 f1_; + T2 f2_; + T3 f3_; + T4 f4_; +}; + +template +class GTEST_6_TUPLE_(T) { + public: + template friend class gtest_internal::Get; + + tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, + GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4, + GTEST_BY_REF_(T5) f5) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4), + f5_(f5) {} + + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), + f4_(t.f4_), f5_(t.f5_) {} + + template + tuple(const GTEST_6_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), + f3_(t.f3_), f4_(t.f4_), f5_(t.f5_) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template + tuple& operator=(const GTEST_6_TUPLE_(U)& t) { + return CopyFrom(t); + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template + tuple& CopyFrom(const GTEST_6_TUPLE_(U)& t) { + f0_ = t.f0_; + f1_ = t.f1_; + f2_ = t.f2_; + f3_ = t.f3_; + f4_ = t.f4_; + f5_ = t.f5_; + return *this; + } + + T0 f0_; + T1 f1_; + T2 f2_; + T3 f3_; + T4 f4_; + T5 f5_; +}; + +template +class GTEST_7_TUPLE_(T) { + public: + template friend class gtest_internal::Get; + + tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, + GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4, + GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6) : f0_(f0), f1_(f1), f2_(f2), + f3_(f3), f4_(f4), f5_(f5), f6_(f6) {} + + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), + f4_(t.f4_), f5_(t.f5_), f6_(t.f6_) {} + + template + tuple(const GTEST_7_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), + f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template + tuple& operator=(const GTEST_7_TUPLE_(U)& t) { + return CopyFrom(t); + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template + tuple& CopyFrom(const GTEST_7_TUPLE_(U)& t) { + f0_ = t.f0_; + f1_ = t.f1_; + f2_ = t.f2_; + f3_ = t.f3_; + f4_ = t.f4_; + f5_ = t.f5_; + f6_ = t.f6_; + return *this; + } + + T0 f0_; + T1 f1_; + T2 f2_; + T3 f3_; + T4 f4_; + T5 f5_; + T6 f6_; +}; + +template +class GTEST_8_TUPLE_(T) { + public: + template friend class gtest_internal::Get; + + tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_(), f7_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, + GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4, + GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6, + GTEST_BY_REF_(T7) f7) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4), + f5_(f5), f6_(f6), f7_(f7) {} + + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), + f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_) {} + + template + tuple(const GTEST_8_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), + f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template + tuple& operator=(const GTEST_8_TUPLE_(U)& t) { + return CopyFrom(t); + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template + tuple& CopyFrom(const GTEST_8_TUPLE_(U)& t) { + f0_ = t.f0_; + f1_ = t.f1_; + f2_ = t.f2_; + f3_ = t.f3_; + f4_ = t.f4_; + f5_ = t.f5_; + f6_ = t.f6_; + f7_ = t.f7_; + return *this; + } + + T0 f0_; + T1 f1_; + T2 f2_; + T3 f3_; + T4 f4_; + T5 f5_; + T6 f6_; + T7 f7_; +}; + +template +class GTEST_9_TUPLE_(T) { + public: + template friend class gtest_internal::Get; + + tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_(), f7_(), f8_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, + GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4, + GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6, GTEST_BY_REF_(T7) f7, + GTEST_BY_REF_(T8) f8) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4), + f5_(f5), f6_(f6), f7_(f7), f8_(f8) {} + + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), + f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_) {} + + template + tuple(const GTEST_9_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), + f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template + tuple& operator=(const GTEST_9_TUPLE_(U)& t) { + return CopyFrom(t); + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template + tuple& CopyFrom(const GTEST_9_TUPLE_(U)& t) { + f0_ = t.f0_; + f1_ = t.f1_; + f2_ = t.f2_; + f3_ = t.f3_; + f4_ = t.f4_; + f5_ = t.f5_; + f6_ = t.f6_; + f7_ = t.f7_; + f8_ = t.f8_; + return *this; + } + + T0 f0_; + T1 f1_; + T2 f2_; + T3 f3_; + T4 f4_; + T5 f5_; + T6 f6_; + T7 f7_; + T8 f8_; +}; + +template +class tuple { + public: + template friend class gtest_internal::Get; + + tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_(), f7_(), f8_(), + f9_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, + GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4, + GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6, GTEST_BY_REF_(T7) f7, + GTEST_BY_REF_(T8) f8, GTEST_BY_REF_(T9) f9) : f0_(f0), f1_(f1), f2_(f2), + f3_(f3), f4_(f4), f5_(f5), f6_(f6), f7_(f7), f8_(f8), f9_(f9) {} + + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), + f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_), f9_(t.f9_) {} + + template + tuple(const GTEST_10_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), + f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_), + f9_(t.f9_) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template + tuple& operator=(const GTEST_10_TUPLE_(U)& t) { + return CopyFrom(t); + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template + tuple& CopyFrom(const GTEST_10_TUPLE_(U)& t) { + f0_ = t.f0_; + f1_ = t.f1_; + f2_ = t.f2_; + f3_ = t.f3_; + f4_ = t.f4_; + f5_ = t.f5_; + f6_ = t.f6_; + f7_ = t.f7_; + f8_ = t.f8_; + f9_ = t.f9_; + return *this; + } + + T0 f0_; + T1 f1_; + T2 f2_; + T3 f3_; + T4 f4_; + T5 f5_; + T6 f6_; + T7 f7_; + T8 f8_; + T9 f9_; +}; + +// 6.1.3.2 Tuple creation functions. + +// Known limitations: we don't support passing an +// std::tr1::reference_wrapper to make_tuple(). And we don't +// implement tie(). + +inline tuple<> make_tuple() { return tuple<>(); } + +template +inline GTEST_1_TUPLE_(T) make_tuple(const T0& f0) { + return GTEST_1_TUPLE_(T)(f0); +} + +template +inline GTEST_2_TUPLE_(T) make_tuple(const T0& f0, const T1& f1) { + return GTEST_2_TUPLE_(T)(f0, f1); +} + +template +inline GTEST_3_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2) { + return GTEST_3_TUPLE_(T)(f0, f1, f2); +} + +template +inline GTEST_4_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, + const T3& f3) { + return GTEST_4_TUPLE_(T)(f0, f1, f2, f3); +} + +template +inline GTEST_5_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, + const T3& f3, const T4& f4) { + return GTEST_5_TUPLE_(T)(f0, f1, f2, f3, f4); +} + +template +inline GTEST_6_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, + const T3& f3, const T4& f4, const T5& f5) { + return GTEST_6_TUPLE_(T)(f0, f1, f2, f3, f4, f5); +} + +template +inline GTEST_7_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, + const T3& f3, const T4& f4, const T5& f5, const T6& f6) { + return GTEST_7_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6); +} + +template +inline GTEST_8_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, + const T3& f3, const T4& f4, const T5& f5, const T6& f6, const T7& f7) { + return GTEST_8_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6, f7); +} + +template +inline GTEST_9_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, + const T3& f3, const T4& f4, const T5& f5, const T6& f6, const T7& f7, + const T8& f8) { + return GTEST_9_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6, f7, f8); +} + +template +inline GTEST_10_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, + const T3& f3, const T4& f4, const T5& f5, const T6& f6, const T7& f7, + const T8& f8, const T9& f9) { + return GTEST_10_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6, f7, f8, f9); +} + +// 6.1.3.3 Tuple helper classes. + +template struct tuple_size; + +template +struct tuple_size { static const int value = 0; }; + +template +struct tuple_size { static const int value = 1; }; + +template +struct tuple_size { static const int value = 2; }; + +template +struct tuple_size { static const int value = 3; }; + +template +struct tuple_size { static const int value = 4; }; + +template +struct tuple_size { static const int value = 5; }; + +template +struct tuple_size { static const int value = 6; }; + +template +struct tuple_size { static const int value = 7; }; + +template +struct tuple_size { static const int value = 8; }; + +template +struct tuple_size { static const int value = 9; }; + +template +struct tuple_size { static const int value = 10; }; + +template +struct tuple_element { + typedef typename gtest_internal::TupleElement< + k < (tuple_size::value), k, Tuple>::type type; +}; + +#define GTEST_TUPLE_ELEMENT_(k, Tuple) typename tuple_element::type + +// 6.1.3.4 Element access. + +namespace gtest_internal { + +template <> +class Get<0> { + public: + template + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(0, Tuple)) + Field(Tuple& t) { return t.f0_; } // NOLINT + + template + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(0, Tuple)) + ConstField(const Tuple& t) { return t.f0_; } +}; + +template <> +class Get<1> { + public: + template + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(1, Tuple)) + Field(Tuple& t) { return t.f1_; } // NOLINT + + template + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(1, Tuple)) + ConstField(const Tuple& t) { return t.f1_; } +}; + +template <> +class Get<2> { + public: + template + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(2, Tuple)) + Field(Tuple& t) { return t.f2_; } // NOLINT + + template + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(2, Tuple)) + ConstField(const Tuple& t) { return t.f2_; } +}; + +template <> +class Get<3> { + public: + template + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(3, Tuple)) + Field(Tuple& t) { return t.f3_; } // NOLINT + + template + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(3, Tuple)) + ConstField(const Tuple& t) { return t.f3_; } +}; + +template <> +class Get<4> { + public: + template + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(4, Tuple)) + Field(Tuple& t) { return t.f4_; } // NOLINT + + template + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(4, Tuple)) + ConstField(const Tuple& t) { return t.f4_; } +}; + +template <> +class Get<5> { + public: + template + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(5, Tuple)) + Field(Tuple& t) { return t.f5_; } // NOLINT + + template + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(5, Tuple)) + ConstField(const Tuple& t) { return t.f5_; } +}; + +template <> +class Get<6> { + public: + template + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(6, Tuple)) + Field(Tuple& t) { return t.f6_; } // NOLINT + + template + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(6, Tuple)) + ConstField(const Tuple& t) { return t.f6_; } +}; + +template <> +class Get<7> { + public: + template + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(7, Tuple)) + Field(Tuple& t) { return t.f7_; } // NOLINT + + template + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(7, Tuple)) + ConstField(const Tuple& t) { return t.f7_; } +}; + +template <> +class Get<8> { + public: + template + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(8, Tuple)) + Field(Tuple& t) { return t.f8_; } // NOLINT + + template + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(8, Tuple)) + ConstField(const Tuple& t) { return t.f8_; } +}; + +template <> +class Get<9> { + public: + template + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(9, Tuple)) + Field(Tuple& t) { return t.f9_; } // NOLINT + + template + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(9, Tuple)) + ConstField(const Tuple& t) { return t.f9_; } +}; + +} // namespace gtest_internal + +template +GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_10_TUPLE_(T))) +get(GTEST_10_TUPLE_(T)& t) { + return gtest_internal::Get::Field(t); +} + +template +GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_10_TUPLE_(T))) +get(const GTEST_10_TUPLE_(T)& t) { + return gtest_internal::Get::ConstField(t); +} + +// 6.1.3.5 Relational operators + +// We only implement == and !=, as we don't have a need for the rest yet. + +namespace gtest_internal { + +// SameSizeTuplePrefixComparator::Eq(t1, t2) returns true if the +// first k fields of t1 equals the first k fields of t2. +// SameSizeTuplePrefixComparator(k1, k2) would be a compiler error if +// k1 != k2. +template +struct SameSizeTuplePrefixComparator; + +template <> +struct SameSizeTuplePrefixComparator<0, 0> { + template + static bool Eq(const Tuple1& /* t1 */, const Tuple2& /* t2 */) { + return true; + } +}; + +template +struct SameSizeTuplePrefixComparator { + template + static bool Eq(const Tuple1& t1, const Tuple2& t2) { + return SameSizeTuplePrefixComparator::Eq(t1, t2) && + ::std::tr1::get(t1) == ::std::tr1::get(t2); + } +}; + +} // namespace gtest_internal + +template +inline bool operator==(const GTEST_10_TUPLE_(T)& t, + const GTEST_10_TUPLE_(U)& u) { + return gtest_internal::SameSizeTuplePrefixComparator< + tuple_size::value, + tuple_size::value>::Eq(t, u); +} + +template +inline bool operator!=(const GTEST_10_TUPLE_(T)& t, + const GTEST_10_TUPLE_(U)& u) { return !(t == u); } + +// 6.1.4 Pairs. +// Unimplemented. + +} // namespace tr1 +} // namespace std + +#undef GTEST_0_TUPLE_ +#undef GTEST_1_TUPLE_ +#undef GTEST_2_TUPLE_ +#undef GTEST_3_TUPLE_ +#undef GTEST_4_TUPLE_ +#undef GTEST_5_TUPLE_ +#undef GTEST_6_TUPLE_ +#undef GTEST_7_TUPLE_ +#undef GTEST_8_TUPLE_ +#undef GTEST_9_TUPLE_ +#undef GTEST_10_TUPLE_ + +#undef GTEST_0_TYPENAMES_ +#undef GTEST_1_TYPENAMES_ +#undef GTEST_2_TYPENAMES_ +#undef GTEST_3_TYPENAMES_ +#undef GTEST_4_TYPENAMES_ +#undef GTEST_5_TYPENAMES_ +#undef GTEST_6_TYPENAMES_ +#undef GTEST_7_TYPENAMES_ +#undef GTEST_8_TYPENAMES_ +#undef GTEST_9_TYPENAMES_ +#undef GTEST_10_TYPENAMES_ + +#undef GTEST_DECLARE_TUPLE_AS_FRIEND_ +#undef GTEST_BY_REF_ +#undef GTEST_ADD_REF_ +#undef GTEST_TUPLE_ELEMENT_ + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_ +#elif GTEST_OS_SYMBIAN + +// On Symbian, BOOST_HAS_TR1_TUPLE causes Boost's TR1 tuple library to +// use STLport's tuple implementation, which unfortunately doesn't +// work as the copy of STLport distributed with Symbian is incomplete. +// By making sure BOOST_HAS_TR1_TUPLE is undefined, we force Boost to +// use its own tuple implementation. +#ifdef BOOST_HAS_TR1_TUPLE +#undef BOOST_HAS_TR1_TUPLE +#endif // BOOST_HAS_TR1_TUPLE + +// This prevents , which defines +// BOOST_HAS_TR1_TUPLE, from being #included by Boost's . +#define BOOST_TR1_DETAIL_CONFIG_HPP_INCLUDED +#include + +#elif defined(__GNUC__) && (GTEST_GCC_VER_ >= 40000) +// GCC 4.0+ implements tr1/tuple in the header. This does +// not conform to the TR1 spec, which requires the header to be . + +#if !GTEST_HAS_RTTI && GTEST_GCC_VER_ < 40302 +// Until version 4.3.2, gcc has a bug that causes , +// which is #included by , to not compile when RTTI is +// disabled. _TR1_FUNCTIONAL is the header guard for +// . Hence the following #define is a hack to prevent +// from being included. +#define _TR1_FUNCTIONAL 1 +#include +#undef _TR1_FUNCTIONAL // Allows the user to #include + // if he chooses to. +#else +#include // NOLINT +#endif // !GTEST_HAS_RTTI && GTEST_GCC_VER_ < 40302 + +#else +// If the compiler is not GCC 4.0+, we assume the user is using a +// spec-conforming TR1 implementation. +#include // NOLINT +#endif // GTEST_USE_OWN_TR1_TUPLE + +#endif // GTEST_HAS_TR1_TUPLE + +// Determines whether clone(2) is supported. +// Usually it will only be available on Linux, excluding +// Linux on the Itanium architecture. +// Also see http://linux.die.net/man/2/clone. +#ifndef GTEST_HAS_CLONE +// The user didn't tell us, so we need to figure it out. + +#if GTEST_OS_LINUX && !defined(__ia64__) +#define GTEST_HAS_CLONE 1 +#else +#define GTEST_HAS_CLONE 0 +#endif // GTEST_OS_LINUX && !defined(__ia64__) + +#endif // GTEST_HAS_CLONE + +// Determines whether to support stream redirection. This is used to test +// output correctness and to implement death tests. +#if !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_SYMBIAN +#define GTEST_HAS_STREAM_REDIRECTION_ 1 +#endif // !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_SYMBIAN + +// Determines whether to support death tests. +// Google Test does not support death tests for VC 7.1 and earlier as +// abort() in a VC 7.1 application compiled as GUI in debug config +// pops up a dialog window that cannot be suppressed programmatically. +#if (GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_CYGWIN || GTEST_OS_SOLARIS || \ + (GTEST_OS_WINDOWS_DESKTOP && _MSC_VER >= 1400) || \ + GTEST_OS_WINDOWS_MINGW || GTEST_OS_AIX) +#define GTEST_HAS_DEATH_TEST 1 +#include // NOLINT +#endif + +// We don't support MSVC 7.1 with exceptions disabled now. Therefore +// all the compilers we care about are adequate for supporting +// value-parameterized tests. +#define GTEST_HAS_PARAM_TEST 1 + +// Determines whether to support type-driven tests. + +// Typed tests need and variadic macros, which GCC, VC++ 8.0, +// Sun Pro CC, and IBM Visual Age support. +#if defined(__GNUC__) || (_MSC_VER >= 1400) || defined(__SUNPRO_CC) || \ + defined(__IBMCPP__) +#define GTEST_HAS_TYPED_TEST 1 +#define GTEST_HAS_TYPED_TEST_P 1 +#endif + +// Determines whether to support Combine(). This only makes sense when +// value-parameterized tests are enabled. The implementation doesn't +// work on Sun Studio since it doesn't understand templated conversion +// operators. +#if GTEST_HAS_PARAM_TEST && GTEST_HAS_TR1_TUPLE && !defined(__SUNPRO_CC) +#define GTEST_HAS_COMBINE 1 +#endif + +// Determines whether the system compiler uses UTF-16 for encoding wide strings. +#define GTEST_WIDE_STRING_USES_UTF16_ \ + (GTEST_OS_WINDOWS || GTEST_OS_CYGWIN || GTEST_OS_SYMBIAN || GTEST_OS_AIX) + +// Defines some utility macros. + +// The GNU compiler emits a warning if nested "if" statements are followed by +// an "else" statement and braces are not used to explicitly disambiguate the +// "else" binding. This leads to problems with code like: +// +// if (gate) +// ASSERT_*(condition) << "Some message"; +// +// The "switch (0) case 0:" idiom is used to suppress this. +#ifdef __INTEL_COMPILER +#define GTEST_AMBIGUOUS_ELSE_BLOCKER_ +#else +#define GTEST_AMBIGUOUS_ELSE_BLOCKER_ switch (0) case 0: // NOLINT +#endif + +// Use this annotation at the end of a struct/class definition to +// prevent the compiler from optimizing away instances that are never +// used. This is useful when all interesting logic happens inside the +// c'tor and / or d'tor. Example: +// +// struct Foo { +// Foo() { ... } +// } GTEST_ATTRIBUTE_UNUSED_; +// +// Also use it after a variable or parameter declaration to tell the +// compiler the variable/parameter does not have to be used. +#if defined(__GNUC__) && !defined(COMPILER_ICC) +#define GTEST_ATTRIBUTE_UNUSED_ __attribute__ ((unused)) +#else +#define GTEST_ATTRIBUTE_UNUSED_ +#endif + +// A macro to disallow operator= +// This should be used in the private: declarations for a class. +#define GTEST_DISALLOW_ASSIGN_(type)\ + void operator=(type const &) + +// A macro to disallow copy constructor and operator= +// This should be used in the private: declarations for a class. +#define GTEST_DISALLOW_COPY_AND_ASSIGN_(type)\ + type(type const &);\ + GTEST_DISALLOW_ASSIGN_(type) + +// Tell the compiler to warn about unused return values for functions declared +// with this macro. The macro should be used on function declarations +// following the argument list: +// +// Sprocket* AllocateSprocket() GTEST_MUST_USE_RESULT_; +#if defined(__GNUC__) && (GTEST_GCC_VER_ >= 30400) && !defined(COMPILER_ICC) +#define GTEST_MUST_USE_RESULT_ __attribute__ ((warn_unused_result)) +#else +#define GTEST_MUST_USE_RESULT_ +#endif // __GNUC__ && (GTEST_GCC_VER_ >= 30400) && !COMPILER_ICC + +// Determine whether the compiler supports Microsoft's Structured Exception +// Handling. This is supported by several Windows compilers but generally +// does not exist on any other system. +#ifndef GTEST_HAS_SEH +// The user didn't tell us, so we need to figure it out. + +#if defined(_MSC_VER) || defined(__BORLANDC__) +// These two compilers are known to support SEH. +#define GTEST_HAS_SEH 1 +#else +// Assume no SEH. +#define GTEST_HAS_SEH 0 +#endif + +#endif // GTEST_HAS_SEH + +#ifdef _MSC_VER + +#if GTEST_LINKED_AS_SHARED_LIBRARY +#define GTEST_API_ __declspec(dllimport) +#elif GTEST_CREATE_SHARED_LIBRARY +#define GTEST_API_ __declspec(dllexport) +#endif + +#endif // _MSC_VER + +#ifndef GTEST_API_ +#define GTEST_API_ +#endif + +namespace testing { + +class Message; + +namespace internal { + +class String; + +typedef ::std::stringstream StrStream; + +// A helper for suppressing warnings on constant condition. It just +// returns 'condition'. +GTEST_API_ bool IsTrue(bool condition); + +// Defines scoped_ptr. + +// This implementation of scoped_ptr is PARTIAL - it only contains +// enough stuff to satisfy Google Test's need. +template +class scoped_ptr { + public: + typedef T element_type; + + explicit scoped_ptr(T* p = NULL) : ptr_(p) {} + ~scoped_ptr() { reset(); } + + T& operator*() const { return *ptr_; } + T* operator->() const { return ptr_; } + T* get() const { return ptr_; } + + T* release() { + T* const ptr = ptr_; + ptr_ = NULL; + return ptr; + } + + void reset(T* p = NULL) { + if (p != ptr_) { + if (IsTrue(sizeof(T) > 0)) { // Makes sure T is a complete type. + delete ptr_; + } + ptr_ = p; + } + } + private: + T* ptr_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(scoped_ptr); +}; + +// Defines RE. + +// A simple C++ wrapper for . It uses the POSIX Extended +// Regular Expression syntax. +class GTEST_API_ RE { + public: + // A copy constructor is required by the Standard to initialize object + // references from r-values. + RE(const RE& other) { Init(other.pattern()); } + + // Constructs an RE from a string. + RE(const ::std::string& regex) { Init(regex.c_str()); } // NOLINT + +#if GTEST_HAS_GLOBAL_STRING + RE(const ::string& regex) { Init(regex.c_str()); } // NOLINT +#endif // GTEST_HAS_GLOBAL_STRING + + RE(const char* regex) { Init(regex); } // NOLINT + ~RE(); + + // Returns the string representation of the regex. + const char* pattern() const { return pattern_; } + + // FullMatch(str, re) returns true iff regular expression re matches + // the entire str. + // PartialMatch(str, re) returns true iff regular expression re + // matches a substring of str (including str itself). + // + // TODO(wan@google.com): make FullMatch() and PartialMatch() work + // when str contains NUL characters. + static bool FullMatch(const ::std::string& str, const RE& re) { + return FullMatch(str.c_str(), re); + } + static bool PartialMatch(const ::std::string& str, const RE& re) { + return PartialMatch(str.c_str(), re); + } + +#if GTEST_HAS_GLOBAL_STRING + static bool FullMatch(const ::string& str, const RE& re) { + return FullMatch(str.c_str(), re); + } + static bool PartialMatch(const ::string& str, const RE& re) { + return PartialMatch(str.c_str(), re); + } +#endif // GTEST_HAS_GLOBAL_STRING + + static bool FullMatch(const char* str, const RE& re); + static bool PartialMatch(const char* str, const RE& re); + + private: + void Init(const char* regex); + + // We use a const char* instead of a string, as Google Test may be used + // where string is not available. We also do not use Google Test's own + // String type here, in order to simplify dependencies between the + // files. + const char* pattern_; + bool is_valid_; +#if GTEST_USES_POSIX_RE + regex_t full_regex_; // For FullMatch(). + regex_t partial_regex_; // For PartialMatch(). +#else // GTEST_USES_SIMPLE_RE + const char* full_pattern_; // For FullMatch(); +#endif + + GTEST_DISALLOW_ASSIGN_(RE); +}; + +// Defines logging utilities: +// GTEST_LOG_(severity) - logs messages at the specified severity level. The +// message itself is streamed into the macro. +// LogToStderr() - directs all log messages to stderr. +// FlushInfoLog() - flushes informational log messages. + +enum GTestLogSeverity { + GTEST_INFO, + GTEST_WARNING, + GTEST_ERROR, + GTEST_FATAL +}; + +// Formats log entry severity, provides a stream object for streaming the +// log message, and terminates the message with a newline when going out of +// scope. +class GTEST_API_ GTestLog { + public: + GTestLog(GTestLogSeverity severity, const char* file, int line); + + // Flushes the buffers and, if severity is GTEST_FATAL, aborts the program. + ~GTestLog(); + + ::std::ostream& GetStream() { return ::std::cerr; } + + private: + const GTestLogSeverity severity_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(GTestLog); +}; + +#define GTEST_LOG_(severity) \ + ::testing::internal::GTestLog(::testing::internal::GTEST_##severity, \ + __FILE__, __LINE__).GetStream() + +inline void LogToStderr() {} +inline void FlushInfoLog() { fflush(NULL); } + +// INTERNAL IMPLEMENTATION - DO NOT USE. +// +// GTEST_CHECK_ is an all-mode assert. It aborts the program if the condition +// is not satisfied. +// Synopsys: +// GTEST_CHECK_(boolean_condition); +// or +// GTEST_CHECK_(boolean_condition) << "Additional message"; +// +// This checks the condition and if the condition is not satisfied +// it prints message about the condition violation, including the +// condition itself, plus additional message streamed into it, if any, +// and then it aborts the program. It aborts the program irrespective of +// whether it is built in the debug mode or not. +#define GTEST_CHECK_(condition) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (::testing::internal::IsTrue(condition)) \ + ; \ + else \ + GTEST_LOG_(FATAL) << "Condition " #condition " failed. " + +// An all-mode assert to verify that the given POSIX-style function +// call returns 0 (indicating success). Known limitation: this +// doesn't expand to a balanced 'if' statement, so enclose the macro +// in {} if you need to use it as the only statement in an 'if' +// branch. +#define GTEST_CHECK_POSIX_SUCCESS_(posix_call) \ + if (const int gtest_error = (posix_call)) \ + GTEST_LOG_(FATAL) << #posix_call << "failed with error " \ + << gtest_error + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// Downcasts the pointer of type Base to Derived. +// Derived must be a subclass of Base. The parameter MUST +// point to a class of type Derived, not any subclass of it. +// When RTTI is available, the function performs a runtime +// check to enforce this. +template +Derived* CheckedDowncastToActualType(Base* base) { +#if GTEST_HAS_RTTI + GTEST_CHECK_(typeid(*base) == typeid(Derived)); + return dynamic_cast(base); // NOLINT +#else + return static_cast(base); // Poor man's downcast. +#endif +} + +#if GTEST_HAS_STREAM_REDIRECTION_ + +// Defines the stderr capturer: +// CaptureStdout - starts capturing stdout. +// GetCapturedStdout - stops capturing stdout and returns the captured string. +// CaptureStderr - starts capturing stderr. +// GetCapturedStderr - stops capturing stderr and returns the captured string. +// +GTEST_API_ void CaptureStdout(); +GTEST_API_ String GetCapturedStdout(); +GTEST_API_ void CaptureStderr(); +GTEST_API_ String GetCapturedStderr(); + +#endif // GTEST_HAS_STREAM_REDIRECTION_ + + +#if GTEST_HAS_DEATH_TEST + +// A copy of all command line arguments. Set by InitGoogleTest(). +extern ::std::vector g_argvs; + +// GTEST_HAS_DEATH_TEST implies we have ::std::string. +const ::std::vector& GetArgvs(); + +#endif // GTEST_HAS_DEATH_TEST + +// Defines synchronization primitives. + +#if GTEST_HAS_PTHREAD + +// Sleeps for (roughly) n milli-seconds. This function is only for +// testing Google Test's own constructs. Don't use it in user tests, +// either directly or indirectly. +inline void SleepMilliseconds(int n) { + const timespec time = { + 0, // 0 seconds. + n * 1000L * 1000L, // And n ms. + }; + nanosleep(&time, NULL); +} + +// Allows a controller thread to pause execution of newly created +// threads until notified. Instances of this class must be created +// and destroyed in the controller thread. +// +// This class is only for testing Google Test's own constructs. Do not +// use it in user tests, either directly or indirectly. +class Notification { + public: + Notification() : notified_(false) {} + + // Notifies all threads created with this notification to start. Must + // be called from the controller thread. + void Notify() { notified_ = true; } + + // Blocks until the controller thread notifies. Must be called from a test + // thread. + void WaitForNotification() { + while(!notified_) { + SleepMilliseconds(10); + } + } + + private: + volatile bool notified_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(Notification); +}; + +// As a C-function, ThreadFuncWithCLinkage cannot be templated itself. +// Consequently, it cannot select a correct instantiation of ThreadWithParam +// in order to call its Run(). Introducing ThreadWithParamBase as a +// non-templated base class for ThreadWithParam allows us to bypass this +// problem. +class ThreadWithParamBase { + public: + virtual ~ThreadWithParamBase() {} + virtual void Run() = 0; +}; + +// pthread_create() accepts a pointer to a function type with the C linkage. +// According to the Standard (7.5/1), function types with different linkages +// are different even if they are otherwise identical. Some compilers (for +// example, SunStudio) treat them as different types. Since class methods +// cannot be defined with C-linkage we need to define a free C-function to +// pass into pthread_create(). +extern "C" inline void* ThreadFuncWithCLinkage(void* thread) { + static_cast(thread)->Run(); + return NULL; +} + +// Helper class for testing Google Test's multi-threading constructs. +// To use it, write: +// +// void ThreadFunc(int param) { /* Do things with param */ } +// Notification thread_can_start; +// ... +// // The thread_can_start parameter is optional; you can supply NULL. +// ThreadWithParam thread(&ThreadFunc, 5, &thread_can_start); +// thread_can_start.Notify(); +// +// These classes are only for testing Google Test's own constructs. Do +// not use them in user tests, either directly or indirectly. +template +class ThreadWithParam : public ThreadWithParamBase { + public: + typedef void (*UserThreadFunc)(T); + + ThreadWithParam( + UserThreadFunc func, T param, Notification* thread_can_start) + : func_(func), + param_(param), + thread_can_start_(thread_can_start), + finished_(false) { + ThreadWithParamBase* const base = this; + // The thread can be created only after all fields except thread_ + // have been initialized. + GTEST_CHECK_POSIX_SUCCESS_( + pthread_create(&thread_, 0, &ThreadFuncWithCLinkage, base)); + } + ~ThreadWithParam() { Join(); } + + void Join() { + if (!finished_) { + GTEST_CHECK_POSIX_SUCCESS_(pthread_join(thread_, 0)); + finished_ = true; + } + } + + virtual void Run() { + if (thread_can_start_ != NULL) + thread_can_start_->WaitForNotification(); + func_(param_); + } + + private: + const UserThreadFunc func_; // User-supplied thread function. + const T param_; // User-supplied parameter to the thread function. + // When non-NULL, used to block execution until the controller thread + // notifies. + Notification* const thread_can_start_; + bool finished_; // true iff we know that the thread function has finished. + pthread_t thread_; // The native thread object. + + GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadWithParam); +}; + +// gtest-port.h guarantees to #include when GTEST_HAS_PTHREAD is +// true. +#include + +// MutexBase and Mutex implement mutex on pthreads-based platforms. They +// are used in conjunction with class MutexLock: +// +// Mutex mutex; +// ... +// MutexLock lock(&mutex); // Acquires the mutex and releases it at the end +// // of the current scope. +// +// MutexBase implements behavior for both statically and dynamically +// allocated mutexes. Do not use MutexBase directly. Instead, write +// the following to define a static mutex: +// +// GTEST_DEFINE_STATIC_MUTEX_(g_some_mutex); +// +// You can forward declare a static mutex like this: +// +// GTEST_DECLARE_STATIC_MUTEX_(g_some_mutex); +// +// To create a dynamic mutex, just define an object of type Mutex. +class MutexBase { + public: + // Acquires this mutex. + void Lock() { + GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_lock(&mutex_)); + owner_ = pthread_self(); + } + + // Releases this mutex. + void Unlock() { + // We don't protect writing to owner_ here, as it's the caller's + // responsibility to ensure that the current thread holds the + // mutex when this is called. + owner_ = 0; + GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_unlock(&mutex_)); + } + + // Does nothing if the current thread holds the mutex. Otherwise, crashes + // with high probability. + void AssertHeld() const { + GTEST_CHECK_(owner_ == pthread_self()) + << "The current thread is not holding the mutex @" << this; + } + + // A static mutex may be used before main() is entered. It may even + // be used before the dynamic initialization stage. Therefore we + // must be able to initialize a static mutex object at link time. + // This means MutexBase has to be a POD and its member variables + // have to be public. + public: + pthread_mutex_t mutex_; // The underlying pthread mutex. + pthread_t owner_; // The thread holding the mutex; 0 means no one holds it. +}; + +// Forward-declares a static mutex. +#define GTEST_DECLARE_STATIC_MUTEX_(mutex) \ + extern ::testing::internal::MutexBase mutex + +// Defines and statically (i.e. at link time) initializes a static mutex. +#define GTEST_DEFINE_STATIC_MUTEX_(mutex) \ + ::testing::internal::MutexBase mutex = { PTHREAD_MUTEX_INITIALIZER, 0 } + +// The Mutex class can only be used for mutexes created at runtime. It +// shares its API with MutexBase otherwise. +class Mutex : public MutexBase { + public: + Mutex() { + GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_init(&mutex_, NULL)); + owner_ = 0; + } + ~Mutex() { + GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_destroy(&mutex_)); + } + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(Mutex); +}; + +// We cannot name this class MutexLock as the ctor declaration would +// conflict with a macro named MutexLock, which is defined on some +// platforms. Hence the typedef trick below. +class GTestMutexLock { + public: + explicit GTestMutexLock(MutexBase* mutex) + : mutex_(mutex) { mutex_->Lock(); } + + ~GTestMutexLock() { mutex_->Unlock(); } + + private: + MutexBase* const mutex_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(GTestMutexLock); +}; + +typedef GTestMutexLock MutexLock; + +// Helpers for ThreadLocal. + +// pthread_key_create() requires DeleteThreadLocalValue() to have +// C-linkage. Therefore it cannot be templatized to access +// ThreadLocal. Hence the need for class +// ThreadLocalValueHolderBase. +class ThreadLocalValueHolderBase { + public: + virtual ~ThreadLocalValueHolderBase() {} +}; + +// Called by pthread to delete thread-local data stored by +// pthread_setspecific(). +extern "C" inline void DeleteThreadLocalValue(void* value_holder) { + delete static_cast(value_holder); +} + +// Implements thread-local storage on pthreads-based systems. +// +// // Thread 1 +// ThreadLocal tl(100); // 100 is the default value for each thread. +// +// // Thread 2 +// tl.set(150); // Changes the value for thread 2 only. +// EXPECT_EQ(150, tl.get()); +// +// // Thread 1 +// EXPECT_EQ(100, tl.get()); // In thread 1, tl has the original value. +// tl.set(200); +// EXPECT_EQ(200, tl.get()); +// +// The template type argument T must have a public copy constructor. +// In addition, the default ThreadLocal constructor requires T to have +// a public default constructor. +// +// An object managed for a thread by a ThreadLocal instance is deleted +// when the thread exits. Or, if the ThreadLocal instance dies in +// that thread, when the ThreadLocal dies. It's the user's +// responsibility to ensure that all other threads using a ThreadLocal +// have exited when it dies, or the per-thread objects for those +// threads will not be deleted. +// +// Google Test only uses global ThreadLocal objects. That means they +// will die after main() has returned. Therefore, no per-thread +// object managed by Google Test will be leaked as long as all threads +// using Google Test have exited when main() returns. +template +class ThreadLocal { + public: + ThreadLocal() : key_(CreateKey()), + default_() {} + explicit ThreadLocal(const T& value) : key_(CreateKey()), + default_(value) {} + + ~ThreadLocal() { + // Destroys the managed object for the current thread, if any. + DeleteThreadLocalValue(pthread_getspecific(key_)); + + // Releases resources associated with the key. This will *not* + // delete managed objects for other threads. + GTEST_CHECK_POSIX_SUCCESS_(pthread_key_delete(key_)); + } + + T* pointer() { return GetOrCreateValue(); } + const T* pointer() const { return GetOrCreateValue(); } + const T& get() const { return *pointer(); } + void set(const T& value) { *pointer() = value; } + + private: + // Holds a value of type T. + class ValueHolder : public ThreadLocalValueHolderBase { + public: + explicit ValueHolder(const T& value) : value_(value) {} + + T* pointer() { return &value_; } + + private: + T value_; + GTEST_DISALLOW_COPY_AND_ASSIGN_(ValueHolder); + }; + + static pthread_key_t CreateKey() { + pthread_key_t key; + // When a thread exits, DeleteThreadLocalValue() will be called on + // the object managed for that thread. + GTEST_CHECK_POSIX_SUCCESS_( + pthread_key_create(&key, &DeleteThreadLocalValue)); + return key; + } + + T* GetOrCreateValue() const { + ThreadLocalValueHolderBase* const holder = + static_cast(pthread_getspecific(key_)); + if (holder != NULL) { + return CheckedDowncastToActualType(holder)->pointer(); + } + + ValueHolder* const new_holder = new ValueHolder(default_); + ThreadLocalValueHolderBase* const holder_base = new_holder; + GTEST_CHECK_POSIX_SUCCESS_(pthread_setspecific(key_, holder_base)); + return new_holder->pointer(); + } + + // A key pthreads uses for looking up per-thread values. + const pthread_key_t key_; + const T default_; // The default value for each thread. + + GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadLocal); +}; + +#define GTEST_IS_THREADSAFE 1 + +#else // GTEST_HAS_PTHREAD + +// A dummy implementation of synchronization primitives (mutex, lock, +// and thread-local variable). Necessary for compiling Google Test where +// mutex is not supported - using Google Test in multiple threads is not +// supported on such platforms. + +class Mutex { + public: + Mutex() {} + void AssertHeld() const {} +}; + +#define GTEST_DECLARE_STATIC_MUTEX_(mutex) \ + extern ::testing::internal::Mutex mutex + +#define GTEST_DEFINE_STATIC_MUTEX_(mutex) ::testing::internal::Mutex mutex + +class GTestMutexLock { + public: + explicit GTestMutexLock(Mutex*) {} // NOLINT +}; + +typedef GTestMutexLock MutexLock; + +template +class ThreadLocal { + public: + ThreadLocal() : value_() {} + explicit ThreadLocal(const T& value) : value_(value) {} + T* pointer() { return &value_; } + const T* pointer() const { return &value_; } + const T& get() const { return value_; } + void set(const T& value) { value_ = value; } + private: + T value_; +}; + +// The above synchronization primitives have dummy implementations. +// Therefore Google Test is not thread-safe. +#define GTEST_IS_THREADSAFE 0 + +#endif // GTEST_HAS_PTHREAD + +// Returns the number of threads running in the process, or 0 to indicate that +// we cannot detect it. +GTEST_API_ size_t GetThreadCount(); + +// Passing non-POD classes through ellipsis (...) crashes the ARM +// compiler and generates a warning in Sun Studio. The Nokia Symbian +// and the IBM XL C/C++ compiler try to instantiate a copy constructor +// for objects passed through ellipsis (...), failing for uncopyable +// objects. We define this to ensure that only POD is passed through +// ellipsis on these systems. +#if defined(__SYMBIAN32__) || defined(__IBMCPP__) || defined(__SUNPRO_CC) +// We lose support for NULL detection where the compiler doesn't like +// passing non-POD classes through ellipsis (...). +#define GTEST_ELLIPSIS_NEEDS_POD_ 1 +#else +#define GTEST_CAN_COMPARE_NULL 1 +#endif + +// The Nokia Symbian and IBM XL C/C++ compilers cannot decide between +// const T& and const T* in a function template. These compilers +// _can_ decide between class template specializations for T and T*, +// so a tr1::type_traits-like is_pointer works. +#if defined(__SYMBIAN32__) || defined(__IBMCPP__) +#define GTEST_NEEDS_IS_POINTER_ 1 +#endif + +template +struct bool_constant { + typedef bool_constant type; + static const bool value = bool_value; +}; +template const bool bool_constant::value; + +typedef bool_constant false_type; +typedef bool_constant true_type; + +template +struct is_pointer : public false_type {}; + +template +struct is_pointer : public true_type {}; + +#if GTEST_OS_WINDOWS +#define GTEST_PATH_SEP_ "\\" +#define GTEST_HAS_ALT_PATH_SEP_ 1 +// The biggest signed integer type the compiler supports. +typedef __int64 BiggestInt; +#else +#define GTEST_PATH_SEP_ "/" +#define GTEST_HAS_ALT_PATH_SEP_ 0 +typedef long long BiggestInt; // NOLINT +#endif // GTEST_OS_WINDOWS + +// The testing::internal::posix namespace holds wrappers for common +// POSIX functions. These wrappers hide the differences between +// Windows/MSVC and POSIX systems. Since some compilers define these +// standard functions as macros, the wrapper cannot have the same name +// as the wrapped function. + +namespace posix { + +// Functions with a different name on Windows. + +#if GTEST_OS_WINDOWS + +typedef struct _stat StatStruct; + +#ifdef __BORLANDC__ +inline int IsATTY(int fd) { return isatty(fd); } +inline int StrCaseCmp(const char* s1, const char* s2) { + return stricmp(s1, s2); +} +inline char* StrDup(const char* src) { return strdup(src); } +#else // !__BORLANDC__ +#if GTEST_OS_WINDOWS_MOBILE +inline int IsATTY(int /* fd */) { return 0; } +#else +inline int IsATTY(int fd) { return _isatty(fd); } +#endif // GTEST_OS_WINDOWS_MOBILE +inline int StrCaseCmp(const char* s1, const char* s2) { + return _stricmp(s1, s2); +} +inline char* StrDup(const char* src) { return _strdup(src); } +#endif // __BORLANDC__ + +#if GTEST_OS_WINDOWS_MOBILE +inline int FileNo(FILE* file) { return reinterpret_cast(_fileno(file)); } +// Stat(), RmDir(), and IsDir() are not needed on Windows CE at this +// time and thus not defined there. +#else +inline int FileNo(FILE* file) { return _fileno(file); } +inline int Stat(const char* path, StatStruct* buf) { return _stat(path, buf); } +inline int RmDir(const char* dir) { return _rmdir(dir); } +inline bool IsDir(const StatStruct& st) { + return (_S_IFDIR & st.st_mode) != 0; +} +#endif // GTEST_OS_WINDOWS_MOBILE + +#else + +typedef struct stat StatStruct; + +inline int FileNo(FILE* file) { return fileno(file); } +inline int IsATTY(int fd) { return isatty(fd); } +inline int Stat(const char* path, StatStruct* buf) { return stat(path, buf); } +inline int StrCaseCmp(const char* s1, const char* s2) { + return strcasecmp(s1, s2); +} +inline char* StrDup(const char* src) { return strdup(src); } +inline int RmDir(const char* dir) { return rmdir(dir); } +inline bool IsDir(const StatStruct& st) { return S_ISDIR(st.st_mode); } + +#endif // GTEST_OS_WINDOWS + +// Functions deprecated by MSVC 8.0. + +#ifdef _MSC_VER +// Temporarily disable warning 4996 (deprecated function). +#pragma warning(push) +#pragma warning(disable:4996) +#endif + +inline const char* StrNCpy(char* dest, const char* src, size_t n) { + return strncpy(dest, src, n); +} + +// ChDir(), FReopen(), FDOpen(), Read(), Write(), Close(), and +// StrError() aren't needed on Windows CE at this time and thus not +// defined there. + +#if !GTEST_OS_WINDOWS_MOBILE +inline int ChDir(const char* dir) { return chdir(dir); } +#endif +inline FILE* FOpen(const char* path, const char* mode) { + return fopen(path, mode); +} +#if !GTEST_OS_WINDOWS_MOBILE +inline FILE *FReopen(const char* path, const char* mode, FILE* stream) { + return freopen(path, mode, stream); +} +inline FILE* FDOpen(int fd, const char* mode) { return fdopen(fd, mode); } +#endif +inline int FClose(FILE* fp) { return fclose(fp); } +#if !GTEST_OS_WINDOWS_MOBILE +inline int Read(int fd, void* buf, unsigned int count) { + return static_cast(read(fd, buf, count)); +} +inline int Write(int fd, const void* buf, unsigned int count) { + return static_cast(write(fd, buf, count)); +} +inline int Close(int fd) { return close(fd); } +inline const char* StrError(int errnum) { return strerror(errnum); } +#endif +inline const char* GetEnv(const char* name) { +#if GTEST_OS_WINDOWS_MOBILE + // We are on Windows CE, which has no environment variables. + return NULL; +#elif defined(__BORLANDC__) || defined(__SunOS_5_8) || defined(__SunOS_5_9) + // Environment variables which we programmatically clear will be set to the + // empty string rather than unset (NULL). Handle that case. + const char* const env = getenv(name); + return (env != NULL && env[0] != '\0') ? env : NULL; +#else + return getenv(name); +#endif +} + +#ifdef _MSC_VER +#pragma warning(pop) // Restores the warning state. +#endif + +#if GTEST_OS_WINDOWS_MOBILE +// Windows CE has no C library. The abort() function is used in +// several places in Google Test. This implementation provides a reasonable +// imitation of standard behaviour. +void Abort(); +#else +inline void Abort() { abort(); } +#endif // GTEST_OS_WINDOWS_MOBILE + +} // namespace posix + +// The maximum number a BiggestInt can represent. This definition +// works no matter BiggestInt is represented in one's complement or +// two's complement. +// +// We cannot rely on numeric_limits in STL, as __int64 and long long +// are not part of standard C++ and numeric_limits doesn't need to be +// defined for them. +const BiggestInt kMaxBiggestInt = + ~(static_cast(1) << (8*sizeof(BiggestInt) - 1)); + +// This template class serves as a compile-time function from size to +// type. It maps a size in bytes to a primitive type with that +// size. e.g. +// +// TypeWithSize<4>::UInt +// +// is typedef-ed to be unsigned int (unsigned integer made up of 4 +// bytes). +// +// Such functionality should belong to STL, but I cannot find it +// there. +// +// Google Test uses this class in the implementation of floating-point +// comparison. +// +// For now it only handles UInt (unsigned int) as that's all Google Test +// needs. Other types can be easily added in the future if need +// arises. +template +class TypeWithSize { + public: + // This prevents the user from using TypeWithSize with incorrect + // values of N. + typedef void UInt; +}; + +// The specialization for size 4. +template <> +class TypeWithSize<4> { + public: + // unsigned int has size 4 in both gcc and MSVC. + // + // As base/basictypes.h doesn't compile on Windows, we cannot use + // uint32, uint64, and etc here. + typedef int Int; + typedef unsigned int UInt; +}; + +// The specialization for size 8. +template <> +class TypeWithSize<8> { + public: +#if GTEST_OS_WINDOWS + typedef __int64 Int; + typedef unsigned __int64 UInt; +#else + typedef long long Int; // NOLINT + typedef unsigned long long UInt; // NOLINT +#endif // GTEST_OS_WINDOWS +}; + +// Integer types of known sizes. +typedef TypeWithSize<4>::Int Int32; +typedef TypeWithSize<4>::UInt UInt32; +typedef TypeWithSize<8>::Int Int64; +typedef TypeWithSize<8>::UInt UInt64; +typedef TypeWithSize<8>::Int TimeInMillis; // Represents time in milliseconds. + +// Utilities for command line flags and environment variables. + +// Macro for referencing flags. +#define GTEST_FLAG(name) FLAGS_gtest_##name + +// Macros for declaring flags. +#define GTEST_DECLARE_bool_(name) GTEST_API_ extern bool GTEST_FLAG(name) +#define GTEST_DECLARE_int32_(name) \ + GTEST_API_ extern ::testing::internal::Int32 GTEST_FLAG(name) +#define GTEST_DECLARE_string_(name) \ + GTEST_API_ extern ::testing::internal::String GTEST_FLAG(name) + +// Macros for defining flags. +#define GTEST_DEFINE_bool_(name, default_val, doc) \ + GTEST_API_ bool GTEST_FLAG(name) = (default_val) +#define GTEST_DEFINE_int32_(name, default_val, doc) \ + GTEST_API_ ::testing::internal::Int32 GTEST_FLAG(name) = (default_val) +#define GTEST_DEFINE_string_(name, default_val, doc) \ + GTEST_API_ ::testing::internal::String GTEST_FLAG(name) = (default_val) + +// Parses 'str' for a 32-bit signed integer. If successful, writes the result +// to *value and returns true; otherwise leaves *value unchanged and returns +// false. +// TODO(chandlerc): Find a better way to refactor flag and environment parsing +// out of both gtest-port.cc and gtest.cc to avoid exporting this utility +// function. +bool ParseInt32(const Message& src_text, const char* str, Int32* value); + +// Parses a bool/Int32/string from the environment variable +// corresponding to the given Google Test flag. +bool BoolFromGTestEnv(const char* flag, bool default_val); +GTEST_API_ Int32 Int32FromGTestEnv(const char* flag, Int32 default_val); +const char* StringFromGTestEnv(const char* flag, const char* default_val); + +} // namespace internal +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_ + +#if GTEST_OS_LINUX +#include +#include +#include +#include +#endif // GTEST_OS_LINUX + +#include +#include +#include +#include +#include + +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee) +// +// The Google C++ Testing Framework (Google Test) +// +// This header file declares the String class and functions used internally by +// Google Test. They are subject to change without notice. They should not used +// by code external to Google Test. +// +// This header file is #included by . +// It should not be #included by other files. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_ + +#ifdef __BORLANDC__ +// string.h is not guaranteed to provide strcpy on C++ Builder. +#include +#endif + +#include + +#include + +namespace testing { +namespace internal { + +// String - a UTF-8 string class. +// +// For historic reasons, we don't use std::string. +// +// TODO(wan@google.com): replace this class with std::string or +// implement it in terms of the latter. +// +// Note that String can represent both NULL and the empty string, +// while std::string cannot represent NULL. +// +// NULL and the empty string are considered different. NULL is less +// than anything (including the empty string) except itself. +// +// This class only provides minimum functionality necessary for +// implementing Google Test. We do not intend to implement a full-fledged +// string class here. +// +// Since the purpose of this class is to provide a substitute for +// std::string on platforms where it cannot be used, we define a copy +// constructor and assignment operators such that we don't need +// conditional compilation in a lot of places. +// +// In order to make the representation efficient, the d'tor of String +// is not virtual. Therefore DO NOT INHERIT FROM String. +class GTEST_API_ String { + public: + // Static utility methods + + // Returns the input enclosed in double quotes if it's not NULL; + // otherwise returns "(null)". For example, "\"Hello\"" is returned + // for input "Hello". + // + // This is useful for printing a C string in the syntax of a literal. + // + // Known issue: escape sequences are not handled yet. + static String ShowCStringQuoted(const char* c_str); + + // Clones a 0-terminated C string, allocating memory using new. The + // caller is responsible for deleting the return value using + // delete[]. Returns the cloned string, or NULL if the input is + // NULL. + // + // This is different from strdup() in string.h, which allocates + // memory using malloc(). + static const char* CloneCString(const char* c_str); + +#if GTEST_OS_WINDOWS_MOBILE + // Windows CE does not have the 'ANSI' versions of Win32 APIs. To be + // able to pass strings to Win32 APIs on CE we need to convert them + // to 'Unicode', UTF-16. + + // Creates a UTF-16 wide string from the given ANSI string, allocating + // memory using new. The caller is responsible for deleting the return + // value using delete[]. Returns the wide string, or NULL if the + // input is NULL. + // + // The wide string is created using the ANSI codepage (CP_ACP) to + // match the behaviour of the ANSI versions of Win32 calls and the + // C runtime. + static LPCWSTR AnsiToUtf16(const char* c_str); + + // Creates an ANSI string from the given wide string, allocating + // memory using new. The caller is responsible for deleting the return + // value using delete[]. Returns the ANSI string, or NULL if the + // input is NULL. + // + // The returned string is created using the ANSI codepage (CP_ACP) to + // match the behaviour of the ANSI versions of Win32 calls and the + // C runtime. + static const char* Utf16ToAnsi(LPCWSTR utf16_str); +#endif + + // Compares two C strings. Returns true iff they have the same content. + // + // Unlike strcmp(), this function can handle NULL argument(s). A + // NULL C string is considered different to any non-NULL C string, + // including the empty string. + static bool CStringEquals(const char* lhs, const char* rhs); + + // Converts a wide C string to a String using the UTF-8 encoding. + // NULL will be converted to "(null)". If an error occurred during + // the conversion, "(failed to convert from wide string)" is + // returned. + static String ShowWideCString(const wchar_t* wide_c_str); + + // Similar to ShowWideCString(), except that this function encloses + // the converted string in double quotes. + static String ShowWideCStringQuoted(const wchar_t* wide_c_str); + + // Compares two wide C strings. Returns true iff they have the same + // content. + // + // Unlike wcscmp(), this function can handle NULL argument(s). A + // NULL C string is considered different to any non-NULL C string, + // including the empty string. + static bool WideCStringEquals(const wchar_t* lhs, const wchar_t* rhs); + + // Compares two C strings, ignoring case. Returns true iff they + // have the same content. + // + // Unlike strcasecmp(), this function can handle NULL argument(s). + // A NULL C string is considered different to any non-NULL C string, + // including the empty string. + static bool CaseInsensitiveCStringEquals(const char* lhs, + const char* rhs); + + // Compares two wide C strings, ignoring case. Returns true iff they + // have the same content. + // + // Unlike wcscasecmp(), this function can handle NULL argument(s). + // A NULL C string is considered different to any non-NULL wide C string, + // including the empty string. + // NB: The implementations on different platforms slightly differ. + // On windows, this method uses _wcsicmp which compares according to LC_CTYPE + // environment variable. On GNU platform this method uses wcscasecmp + // which compares according to LC_CTYPE category of the current locale. + // On MacOS X, it uses towlower, which also uses LC_CTYPE category of the + // current locale. + static bool CaseInsensitiveWideCStringEquals(const wchar_t* lhs, + const wchar_t* rhs); + + // Formats a list of arguments to a String, using the same format + // spec string as for printf. + // + // We do not use the StringPrintf class as it is not universally + // available. + // + // The result is limited to 4096 characters (including the tailing + // 0). If 4096 characters are not enough to format the input, + // "" is returned. + static String Format(const char* format, ...); + + // C'tors + + // The default c'tor constructs a NULL string. + String() : c_str_(NULL), length_(0) {} + + // Constructs a String by cloning a 0-terminated C string. + String(const char* a_c_str) { // NOLINT + if (a_c_str == NULL) { + c_str_ = NULL; + length_ = 0; + } else { + ConstructNonNull(a_c_str, strlen(a_c_str)); + } + } + + // Constructs a String by copying a given number of chars from a + // buffer. E.g. String("hello", 3) creates the string "hel", + // String("a\0bcd", 4) creates "a\0bc", String(NULL, 0) creates "", + // and String(NULL, 1) results in access violation. + String(const char* buffer, size_t a_length) { + ConstructNonNull(buffer, a_length); + } + + // The copy c'tor creates a new copy of the string. The two + // String objects do not share content. + String(const String& str) : c_str_(NULL), length_(0) { *this = str; } + + // D'tor. String is intended to be a final class, so the d'tor + // doesn't need to be virtual. + ~String() { delete[] c_str_; } + + // Allows a String to be implicitly converted to an ::std::string or + // ::string, and vice versa. Converting a String containing a NULL + // pointer to ::std::string or ::string is undefined behavior. + // Converting a ::std::string or ::string containing an embedded NUL + // character to a String will result in the prefix up to the first + // NUL character. + String(const ::std::string& str) { + ConstructNonNull(str.c_str(), str.length()); + } + + operator ::std::string() const { return ::std::string(c_str(), length()); } + +#if GTEST_HAS_GLOBAL_STRING + String(const ::string& str) { + ConstructNonNull(str.c_str(), str.length()); + } + + operator ::string() const { return ::string(c_str(), length()); } +#endif // GTEST_HAS_GLOBAL_STRING + + // Returns true iff this is an empty string (i.e. ""). + bool empty() const { return (c_str() != NULL) && (length() == 0); } + + // Compares this with another String. + // Returns < 0 if this is less than rhs, 0 if this is equal to rhs, or > 0 + // if this is greater than rhs. + int Compare(const String& rhs) const; + + // Returns true iff this String equals the given C string. A NULL + // string and a non-NULL string are considered not equal. + bool operator==(const char* a_c_str) const { return Compare(a_c_str) == 0; } + + // Returns true iff this String is less than the given String. A + // NULL string is considered less than "". + bool operator<(const String& rhs) const { return Compare(rhs) < 0; } + + // Returns true iff this String doesn't equal the given C string. A NULL + // string and a non-NULL string are considered not equal. + bool operator!=(const char* a_c_str) const { return !(*this == a_c_str); } + + // Returns true iff this String ends with the given suffix. *Any* + // String is considered to end with a NULL or empty suffix. + bool EndsWith(const char* suffix) const; + + // Returns true iff this String ends with the given suffix, not considering + // case. Any String is considered to end with a NULL or empty suffix. + bool EndsWithCaseInsensitive(const char* suffix) const; + + // Returns the length of the encapsulated string, or 0 if the + // string is NULL. + size_t length() const { return length_; } + + // Gets the 0-terminated C string this String object represents. + // The String object still owns the string. Therefore the caller + // should NOT delete the return value. + const char* c_str() const { return c_str_; } + + // Assigns a C string to this object. Self-assignment works. + const String& operator=(const char* a_c_str) { + return *this = String(a_c_str); + } + + // Assigns a String object to this object. Self-assignment works. + const String& operator=(const String& rhs) { + if (this != &rhs) { + delete[] c_str_; + if (rhs.c_str() == NULL) { + c_str_ = NULL; + length_ = 0; + } else { + ConstructNonNull(rhs.c_str(), rhs.length()); + } + } + + return *this; + } + + private: + // Constructs a non-NULL String from the given content. This + // function can only be called when data_ has not been allocated. + // ConstructNonNull(NULL, 0) results in an empty string (""). + // ConstructNonNull(NULL, non_zero) is undefined behavior. + void ConstructNonNull(const char* buffer, size_t a_length) { + char* const str = new char[a_length + 1]; + memcpy(str, buffer, a_length); + str[a_length] = '\0'; + c_str_ = str; + length_ = a_length; + } + + const char* c_str_; + size_t length_; +}; // class String + +// Streams a String to an ostream. Each '\0' character in the String +// is replaced with "\\0". +inline ::std::ostream& operator<<(::std::ostream& os, const String& str) { + if (str.c_str() == NULL) { + os << "(null)"; + } else { + const char* const c_str = str.c_str(); + for (size_t i = 0; i != str.length(); i++) { + if (c_str[i] == '\0') { + os << "\\0"; + } else { + os << c_str[i]; + } + } + } + return os; +} + +// Gets the content of the StrStream's buffer as a String. Each '\0' +// character in the buffer is replaced with "\\0". +GTEST_API_ String StrStreamToString(StrStream* stream); + +// Converts a streamable value to a String. A NULL pointer is +// converted to "(null)". When the input value is a ::string, +// ::std::string, ::wstring, or ::std::wstring object, each NUL +// character in it is replaced with "\\0". + +// Declared here but defined in gtest.h, so that it has access +// to the definition of the Message class, required by the ARM +// compiler. +template +String StreamableToString(const T& streamable); + +} // namespace internal +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: keith.ray@gmail.com (Keith Ray) +// +// Google Test filepath utilities +// +// This header file declares classes and functions used internally by +// Google Test. They are subject to change without notice. +// +// This file is #included in . +// Do not include this header file separately! + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_ + + +namespace testing { +namespace internal { + +// FilePath - a class for file and directory pathname manipulation which +// handles platform-specific conventions (like the pathname separator). +// Used for helper functions for naming files in a directory for xml output. +// Except for Set methods, all methods are const or static, which provides an +// "immutable value object" -- useful for peace of mind. +// A FilePath with a value ending in a path separator ("like/this/") represents +// a directory, otherwise it is assumed to represent a file. In either case, +// it may or may not represent an actual file or directory in the file system. +// Names are NOT checked for syntax correctness -- no checking for illegal +// characters, malformed paths, etc. + +class GTEST_API_ FilePath { + public: + FilePath() : pathname_("") { } + FilePath(const FilePath& rhs) : pathname_(rhs.pathname_) { } + + explicit FilePath(const char* pathname) : pathname_(pathname) { + Normalize(); + } + + explicit FilePath(const String& pathname) : pathname_(pathname) { + Normalize(); + } + + FilePath& operator=(const FilePath& rhs) { + Set(rhs); + return *this; + } + + void Set(const FilePath& rhs) { + pathname_ = rhs.pathname_; + } + + String ToString() const { return pathname_; } + const char* c_str() const { return pathname_.c_str(); } + + // Returns the current working directory, or "" if unsuccessful. + static FilePath GetCurrentDir(); + + // Given directory = "dir", base_name = "test", number = 0, + // extension = "xml", returns "dir/test.xml". If number is greater + // than zero (e.g., 12), returns "dir/test_12.xml". + // On Windows platform, uses \ as the separator rather than /. + static FilePath MakeFileName(const FilePath& directory, + const FilePath& base_name, + int number, + const char* extension); + + // Given directory = "dir", relative_path = "test.xml", + // returns "dir/test.xml". + // On Windows, uses \ as the separator rather than /. + static FilePath ConcatPaths(const FilePath& directory, + const FilePath& relative_path); + + // Returns a pathname for a file that does not currently exist. The pathname + // will be directory/base_name.extension or + // directory/base_name_.extension if directory/base_name.extension + // already exists. The number will be incremented until a pathname is found + // that does not already exist. + // Examples: 'dir/foo_test.xml' or 'dir/foo_test_1.xml'. + // There could be a race condition if two or more processes are calling this + // function at the same time -- they could both pick the same filename. + static FilePath GenerateUniqueFileName(const FilePath& directory, + const FilePath& base_name, + const char* extension); + + // Returns true iff the path is NULL or "". + bool IsEmpty() const { return c_str() == NULL || *c_str() == '\0'; } + + // If input name has a trailing separator character, removes it and returns + // the name, otherwise return the name string unmodified. + // On Windows platform, uses \ as the separator, other platforms use /. + FilePath RemoveTrailingPathSeparator() const; + + // Returns a copy of the FilePath with the directory part removed. + // Example: FilePath("path/to/file").RemoveDirectoryName() returns + // FilePath("file"). If there is no directory part ("just_a_file"), it returns + // the FilePath unmodified. If there is no file part ("just_a_dir/") it + // returns an empty FilePath (""). + // On Windows platform, '\' is the path separator, otherwise it is '/'. + FilePath RemoveDirectoryName() const; + + // RemoveFileName returns the directory path with the filename removed. + // Example: FilePath("path/to/file").RemoveFileName() returns "path/to/". + // If the FilePath is "a_file" or "/a_file", RemoveFileName returns + // FilePath("./") or, on Windows, FilePath(".\\"). If the filepath does + // not have a file, like "just/a/dir/", it returns the FilePath unmodified. + // On Windows platform, '\' is the path separator, otherwise it is '/'. + FilePath RemoveFileName() const; + + // Returns a copy of the FilePath with the case-insensitive extension removed. + // Example: FilePath("dir/file.exe").RemoveExtension("EXE") returns + // FilePath("dir/file"). If a case-insensitive extension is not + // found, returns a copy of the original FilePath. + FilePath RemoveExtension(const char* extension) const; + + // Creates directories so that path exists. Returns true if successful or if + // the directories already exist; returns false if unable to create + // directories for any reason. Will also return false if the FilePath does + // not represent a directory (that is, it doesn't end with a path separator). + bool CreateDirectoriesRecursively() const; + + // Create the directory so that path exists. Returns true if successful or + // if the directory already exists; returns false if unable to create the + // directory for any reason, including if the parent directory does not + // exist. Not named "CreateDirectory" because that's a macro on Windows. + bool CreateFolder() const; + + // Returns true if FilePath describes something in the file-system, + // either a file, directory, or whatever, and that something exists. + bool FileOrDirectoryExists() const; + + // Returns true if pathname describes a directory in the file-system + // that exists. + bool DirectoryExists() const; + + // Returns true if FilePath ends with a path separator, which indicates that + // it is intended to represent a directory. Returns false otherwise. + // This does NOT check that a directory (or file) actually exists. + bool IsDirectory() const; + + // Returns true if pathname describes a root directory. (Windows has one + // root directory per disk drive.) + bool IsRootDirectory() const; + + // Returns true if pathname describes an absolute path. + bool IsAbsolutePath() const; + + private: + // Replaces multiple consecutive separators with a single separator. + // For example, "bar///foo" becomes "bar/foo". Does not eliminate other + // redundancies that might be in a pathname involving "." or "..". + // + // A pathname with multiple consecutive separators may occur either through + // user error or as a result of some scripts or APIs that generate a pathname + // with a trailing separator. On other platforms the same API or script + // may NOT generate a pathname with a trailing "/". Then elsewhere that + // pathname may have another "/" and pathname components added to it, + // without checking for the separator already being there. + // The script language and operating system may allow paths like "foo//bar" + // but some of the functions in FilePath will not handle that correctly. In + // particular, RemoveTrailingPathSeparator() only removes one separator, and + // it is called in CreateDirectoriesRecursively() assuming that it will change + // a pathname from directory syntax (trailing separator) to filename syntax. + // + // On Windows this method also replaces the alternate path separator '/' with + // the primary path separator '\\', so that for example "bar\\/\\foo" becomes + // "bar\\foo". + + void Normalize(); + + // Returns a pointer to the last occurence of a valid path separator in + // the FilePath. On Windows, for example, both '/' and '\' are valid path + // separators. Returns NULL if no path separator was found. + const char* FindLastPathSeparator() const; + + String pathname_; +}; // class FilePath + +} // namespace internal +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_ +// This file was GENERATED by command: +// pump.py gtest-type-util.h.pump +// DO NOT EDIT BY HAND!!! + +// Copyright 2008 Google Inc. +// All Rights Reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: wan@google.com (Zhanyong Wan) + +// Type utilities needed for implementing typed and type-parameterized +// tests. This file is generated by a SCRIPT. DO NOT EDIT BY HAND! +// +// Currently we support at most 50 types in a list, and at most 50 +// type-parameterized tests in one type-parameterized test case. +// Please contact googletestframework@googlegroups.com if you need +// more. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ + + +#if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P + +// #ifdef __GNUC__ is too general here. It is possible to use gcc without using +// libstdc++ (which is where cxxabi.h comes from). +#ifdef __GLIBCXX__ +#include +#endif // __GLIBCXX__ + +namespace testing { +namespace internal { + +// AssertyTypeEq::type is defined iff T1 and T2 are the same +// type. This can be used as a compile-time assertion to ensure that +// two types are equal. + +template +struct AssertTypeEq; + +template +struct AssertTypeEq { + typedef bool type; +}; + +// GetTypeName() returns a human-readable name of type T. +template +String GetTypeName() { +#if GTEST_HAS_RTTI + + const char* const name = typeid(T).name(); +#ifdef __GLIBCXX__ + int status = 0; + // gcc's implementation of typeid(T).name() mangles the type name, + // so we have to demangle it. + char* const readable_name = abi::__cxa_demangle(name, 0, 0, &status); + const String name_str(status == 0 ? readable_name : name); + free(readable_name); + return name_str; +#else + return name; +#endif // __GLIBCXX__ + +#else + return ""; +#endif // GTEST_HAS_RTTI +} + +// A unique type used as the default value for the arguments of class +// template Types. This allows us to simulate variadic templates +// (e.g. Types, Type, and etc), which C++ doesn't +// support directly. +struct None {}; + +// The following family of struct and struct templates are used to +// represent type lists. In particular, TypesN +// represents a type list with N types (T1, T2, ..., and TN) in it. +// Except for Types0, every struct in the family has two member types: +// Head for the first type in the list, and Tail for the rest of the +// list. + +// The empty type list. +struct Types0 {}; + +// Type lists of length 1, 2, 3, and so on. + +template +struct Types1 { + typedef T1 Head; + typedef Types0 Tail; +}; +template +struct Types2 { + typedef T1 Head; + typedef Types1 Tail; +}; + +template +struct Types3 { + typedef T1 Head; + typedef Types2 Tail; +}; + +template +struct Types4 { + typedef T1 Head; + typedef Types3 Tail; +}; + +template +struct Types5 { + typedef T1 Head; + typedef Types4 Tail; +}; + +template +struct Types6 { + typedef T1 Head; + typedef Types5 Tail; +}; + +template +struct Types7 { + typedef T1 Head; + typedef Types6 Tail; +}; + +template +struct Types8 { + typedef T1 Head; + typedef Types7 Tail; +}; + +template +struct Types9 { + typedef T1 Head; + typedef Types8 Tail; +}; + +template +struct Types10 { + typedef T1 Head; + typedef Types9 Tail; +}; + +template +struct Types11 { + typedef T1 Head; + typedef Types10 Tail; +}; + +template +struct Types12 { + typedef T1 Head; + typedef Types11 Tail; +}; + +template +struct Types13 { + typedef T1 Head; + typedef Types12 Tail; +}; + +template +struct Types14 { + typedef T1 Head; + typedef Types13 Tail; +}; + +template +struct Types15 { + typedef T1 Head; + typedef Types14 Tail; +}; + +template +struct Types16 { + typedef T1 Head; + typedef Types15 Tail; +}; + +template +struct Types17 { + typedef T1 Head; + typedef Types16 Tail; +}; + +template +struct Types18 { + typedef T1 Head; + typedef Types17 Tail; +}; + +template +struct Types19 { + typedef T1 Head; + typedef Types18 Tail; +}; + +template +struct Types20 { + typedef T1 Head; + typedef Types19 Tail; +}; + +template +struct Types21 { + typedef T1 Head; + typedef Types20 Tail; +}; + +template +struct Types22 { + typedef T1 Head; + typedef Types21 Tail; +}; + +template +struct Types23 { + typedef T1 Head; + typedef Types22 Tail; +}; + +template +struct Types24 { + typedef T1 Head; + typedef Types23 Tail; +}; + +template +struct Types25 { + typedef T1 Head; + typedef Types24 Tail; +}; + +template +struct Types26 { + typedef T1 Head; + typedef Types25 Tail; +}; + +template +struct Types27 { + typedef T1 Head; + typedef Types26 Tail; +}; + +template +struct Types28 { + typedef T1 Head; + typedef Types27 Tail; +}; + +template +struct Types29 { + typedef T1 Head; + typedef Types28 Tail; +}; + +template +struct Types30 { + typedef T1 Head; + typedef Types29 Tail; +}; + +template +struct Types31 { + typedef T1 Head; + typedef Types30 Tail; +}; + +template +struct Types32 { + typedef T1 Head; + typedef Types31 Tail; +}; + +template +struct Types33 { + typedef T1 Head; + typedef Types32 Tail; +}; + +template +struct Types34 { + typedef T1 Head; + typedef Types33 Tail; +}; + +template +struct Types35 { + typedef T1 Head; + typedef Types34 Tail; +}; + +template +struct Types36 { + typedef T1 Head; + typedef Types35 Tail; +}; + +template +struct Types37 { + typedef T1 Head; + typedef Types36 Tail; +}; + +template +struct Types38 { + typedef T1 Head; + typedef Types37 Tail; +}; + +template +struct Types39 { + typedef T1 Head; + typedef Types38 Tail; +}; + +template +struct Types40 { + typedef T1 Head; + typedef Types39 Tail; +}; + +template +struct Types41 { + typedef T1 Head; + typedef Types40 Tail; +}; + +template +struct Types42 { + typedef T1 Head; + typedef Types41 Tail; +}; + +template +struct Types43 { + typedef T1 Head; + typedef Types42 Tail; +}; + +template +struct Types44 { + typedef T1 Head; + typedef Types43 Tail; +}; + +template +struct Types45 { + typedef T1 Head; + typedef Types44 Tail; +}; + +template +struct Types46 { + typedef T1 Head; + typedef Types45 Tail; +}; + +template +struct Types47 { + typedef T1 Head; + typedef Types46 Tail; +}; + +template +struct Types48 { + typedef T1 Head; + typedef Types47 Tail; +}; + +template +struct Types49 { + typedef T1 Head; + typedef Types48 Tail; +}; + +template +struct Types50 { + typedef T1 Head; + typedef Types49 Tail; +}; + + +} // namespace internal + +// We don't want to require the users to write TypesN<...> directly, +// as that would require them to count the length. Types<...> is much +// easier to write, but generates horrible messages when there is a +// compiler error, as gcc insists on printing out each template +// argument, even if it has the default value (this means Types +// will appear as Types in the compiler +// errors). +// +// Our solution is to combine the best part of the two approaches: a +// user would write Types, and Google Test will translate +// that to TypesN internally to make error messages +// readable. The translation is done by the 'type' member of the +// Types template. +template +struct Types { + typedef internal::Types50 type; +}; + +template <> +struct Types { + typedef internal::Types0 type; +}; +template +struct Types { + typedef internal::Types1 type; +}; +template +struct Types { + typedef internal::Types2 type; +}; +template +struct Types { + typedef internal::Types3 type; +}; +template +struct Types { + typedef internal::Types4 type; +}; +template +struct Types { + typedef internal::Types5 type; +}; +template +struct Types { + typedef internal::Types6 type; +}; +template +struct Types { + typedef internal::Types7 type; +}; +template +struct Types { + typedef internal::Types8 type; +}; +template +struct Types { + typedef internal::Types9 type; +}; +template +struct Types { + typedef internal::Types10 type; +}; +template +struct Types { + typedef internal::Types11 type; +}; +template +struct Types { + typedef internal::Types12 type; +}; +template +struct Types { + typedef internal::Types13 type; +}; +template +struct Types { + typedef internal::Types14 type; +}; +template +struct Types { + typedef internal::Types15 type; +}; +template +struct Types { + typedef internal::Types16 type; +}; +template +struct Types { + typedef internal::Types17 type; +}; +template +struct Types { + typedef internal::Types18 type; +}; +template +struct Types { + typedef internal::Types19 type; +}; +template +struct Types { + typedef internal::Types20 type; +}; +template +struct Types { + typedef internal::Types21 type; +}; +template +struct Types { + typedef internal::Types22 type; +}; +template +struct Types { + typedef internal::Types23 type; +}; +template +struct Types { + typedef internal::Types24 type; +}; +template +struct Types { + typedef internal::Types25 type; +}; +template +struct Types { + typedef internal::Types26 type; +}; +template +struct Types { + typedef internal::Types27 type; +}; +template +struct Types { + typedef internal::Types28 type; +}; +template +struct Types { + typedef internal::Types29 type; +}; +template +struct Types { + typedef internal::Types30 type; +}; +template +struct Types { + typedef internal::Types31 type; +}; +template +struct Types { + typedef internal::Types32 type; +}; +template +struct Types { + typedef internal::Types33 type; +}; +template +struct Types { + typedef internal::Types34 type; +}; +template +struct Types { + typedef internal::Types35 type; +}; +template +struct Types { + typedef internal::Types36 type; +}; +template +struct Types { + typedef internal::Types37 type; +}; +template +struct Types { + typedef internal::Types38 type; +}; +template +struct Types { + typedef internal::Types39 type; +}; +template +struct Types { + typedef internal::Types40 type; +}; +template +struct Types { + typedef internal::Types41 type; +}; +template +struct Types { + typedef internal::Types42 type; +}; +template +struct Types { + typedef internal::Types43 type; +}; +template +struct Types { + typedef internal::Types44 type; +}; +template +struct Types { + typedef internal::Types45 type; +}; +template +struct Types { + typedef internal::Types46 type; +}; +template +struct Types { + typedef internal::Types47 type; +}; +template +struct Types { + typedef internal::Types48 type; +}; +template +struct Types { + typedef internal::Types49 type; +}; + +namespace internal { + +#define GTEST_TEMPLATE_ template class + +// The template "selector" struct TemplateSel is used to +// represent Tmpl, which must be a class template with one type +// parameter, as a type. TemplateSel::Bind::type is defined +// as the type Tmpl. This allows us to actually instantiate the +// template "selected" by TemplateSel. +// +// This trick is necessary for simulating typedef for class templates, +// which C++ doesn't support directly. +template +struct TemplateSel { + template + struct Bind { + typedef Tmpl type; + }; +}; + +#define GTEST_BIND_(TmplSel, T) \ + TmplSel::template Bind::type + +// A unique struct template used as the default value for the +// arguments of class template Templates. This allows us to simulate +// variadic templates (e.g. Templates, Templates, +// and etc), which C++ doesn't support directly. +template +struct NoneT {}; + +// The following family of struct and struct templates are used to +// represent template lists. In particular, TemplatesN represents a list of N templates (T1, T2, ..., and TN). Except +// for Templates0, every struct in the family has two member types: +// Head for the selector of the first template in the list, and Tail +// for the rest of the list. + +// The empty template list. +struct Templates0 {}; + +// Template lists of length 1, 2, 3, and so on. + +template +struct Templates1 { + typedef TemplateSel Head; + typedef Templates0 Tail; +}; +template +struct Templates2 { + typedef TemplateSel Head; + typedef Templates1 Tail; +}; + +template +struct Templates3 { + typedef TemplateSel Head; + typedef Templates2 Tail; +}; + +template +struct Templates4 { + typedef TemplateSel Head; + typedef Templates3 Tail; +}; + +template +struct Templates5 { + typedef TemplateSel Head; + typedef Templates4 Tail; +}; + +template +struct Templates6 { + typedef TemplateSel Head; + typedef Templates5 Tail; +}; + +template +struct Templates7 { + typedef TemplateSel Head; + typedef Templates6 Tail; +}; + +template +struct Templates8 { + typedef TemplateSel Head; + typedef Templates7 Tail; +}; + +template +struct Templates9 { + typedef TemplateSel Head; + typedef Templates8 Tail; +}; + +template +struct Templates10 { + typedef TemplateSel Head; + typedef Templates9 Tail; +}; + +template +struct Templates11 { + typedef TemplateSel Head; + typedef Templates10 Tail; +}; + +template +struct Templates12 { + typedef TemplateSel Head; + typedef Templates11 Tail; +}; + +template +struct Templates13 { + typedef TemplateSel Head; + typedef Templates12 Tail; +}; + +template +struct Templates14 { + typedef TemplateSel Head; + typedef Templates13 Tail; +}; + +template +struct Templates15 { + typedef TemplateSel Head; + typedef Templates14 Tail; +}; + +template +struct Templates16 { + typedef TemplateSel Head; + typedef Templates15 Tail; +}; + +template +struct Templates17 { + typedef TemplateSel Head; + typedef Templates16 Tail; +}; + +template +struct Templates18 { + typedef TemplateSel Head; + typedef Templates17 Tail; +}; + +template +struct Templates19 { + typedef TemplateSel Head; + typedef Templates18 Tail; +}; + +template +struct Templates20 { + typedef TemplateSel Head; + typedef Templates19 Tail; +}; + +template +struct Templates21 { + typedef TemplateSel Head; + typedef Templates20 Tail; +}; + +template +struct Templates22 { + typedef TemplateSel Head; + typedef Templates21 Tail; +}; + +template +struct Templates23 { + typedef TemplateSel Head; + typedef Templates22 Tail; +}; + +template +struct Templates24 { + typedef TemplateSel Head; + typedef Templates23 Tail; +}; + +template +struct Templates25 { + typedef TemplateSel Head; + typedef Templates24 Tail; +}; + +template +struct Templates26 { + typedef TemplateSel Head; + typedef Templates25 Tail; +}; + +template +struct Templates27 { + typedef TemplateSel Head; + typedef Templates26 Tail; +}; + +template +struct Templates28 { + typedef TemplateSel Head; + typedef Templates27 Tail; +}; + +template +struct Templates29 { + typedef TemplateSel Head; + typedef Templates28 Tail; +}; + +template +struct Templates30 { + typedef TemplateSel Head; + typedef Templates29 Tail; +}; + +template +struct Templates31 { + typedef TemplateSel Head; + typedef Templates30 Tail; +}; + +template +struct Templates32 { + typedef TemplateSel Head; + typedef Templates31 Tail; +}; + +template +struct Templates33 { + typedef TemplateSel Head; + typedef Templates32 Tail; +}; + +template +struct Templates34 { + typedef TemplateSel Head; + typedef Templates33 Tail; +}; + +template +struct Templates35 { + typedef TemplateSel Head; + typedef Templates34 Tail; +}; + +template +struct Templates36 { + typedef TemplateSel Head; + typedef Templates35 Tail; +}; + +template +struct Templates37 { + typedef TemplateSel Head; + typedef Templates36 Tail; +}; + +template +struct Templates38 { + typedef TemplateSel Head; + typedef Templates37 Tail; +}; + +template +struct Templates39 { + typedef TemplateSel Head; + typedef Templates38 Tail; +}; + +template +struct Templates40 { + typedef TemplateSel Head; + typedef Templates39 Tail; +}; + +template +struct Templates41 { + typedef TemplateSel Head; + typedef Templates40 Tail; +}; + +template +struct Templates42 { + typedef TemplateSel Head; + typedef Templates41 Tail; +}; + +template +struct Templates43 { + typedef TemplateSel Head; + typedef Templates42 Tail; +}; + +template +struct Templates44 { + typedef TemplateSel Head; + typedef Templates43 Tail; +}; + +template +struct Templates45 { + typedef TemplateSel Head; + typedef Templates44 Tail; +}; + +template +struct Templates46 { + typedef TemplateSel Head; + typedef Templates45 Tail; +}; + +template +struct Templates47 { + typedef TemplateSel Head; + typedef Templates46 Tail; +}; + +template +struct Templates48 { + typedef TemplateSel Head; + typedef Templates47 Tail; +}; + +template +struct Templates49 { + typedef TemplateSel Head; + typedef Templates48 Tail; +}; + +template +struct Templates50 { + typedef TemplateSel Head; + typedef Templates49 Tail; +}; + + +// We don't want to require the users to write TemplatesN<...> directly, +// as that would require them to count the length. Templates<...> is much +// easier to write, but generates horrible messages when there is a +// compiler error, as gcc insists on printing out each template +// argument, even if it has the default value (this means Templates +// will appear as Templates in the compiler +// errors). +// +// Our solution is to combine the best part of the two approaches: a +// user would write Templates, and Google Test will translate +// that to TemplatesN internally to make error messages +// readable. The translation is done by the 'type' member of the +// Templates template. +template +struct Templates { + typedef Templates50 type; +}; + +template <> +struct Templates { + typedef Templates0 type; +}; +template +struct Templates { + typedef Templates1 type; +}; +template +struct Templates { + typedef Templates2 type; +}; +template +struct Templates { + typedef Templates3 type; +}; +template +struct Templates { + typedef Templates4 type; +}; +template +struct Templates { + typedef Templates5 type; +}; +template +struct Templates { + typedef Templates6 type; +}; +template +struct Templates { + typedef Templates7 type; +}; +template +struct Templates { + typedef Templates8 type; +}; +template +struct Templates { + typedef Templates9 type; +}; +template +struct Templates { + typedef Templates10 type; +}; +template +struct Templates { + typedef Templates11 type; +}; +template +struct Templates { + typedef Templates12 type; +}; +template +struct Templates { + typedef Templates13 type; +}; +template +struct Templates { + typedef Templates14 type; +}; +template +struct Templates { + typedef Templates15 type; +}; +template +struct Templates { + typedef Templates16 type; +}; +template +struct Templates { + typedef Templates17 type; +}; +template +struct Templates { + typedef Templates18 type; +}; +template +struct Templates { + typedef Templates19 type; +}; +template +struct Templates { + typedef Templates20 type; +}; +template +struct Templates { + typedef Templates21 type; +}; +template +struct Templates { + typedef Templates22 type; +}; +template +struct Templates { + typedef Templates23 type; +}; +template +struct Templates { + typedef Templates24 type; +}; +template +struct Templates { + typedef Templates25 type; +}; +template +struct Templates { + typedef Templates26 type; +}; +template +struct Templates { + typedef Templates27 type; +}; +template +struct Templates { + typedef Templates28 type; +}; +template +struct Templates { + typedef Templates29 type; +}; +template +struct Templates { + typedef Templates30 type; +}; +template +struct Templates { + typedef Templates31 type; +}; +template +struct Templates { + typedef Templates32 type; +}; +template +struct Templates { + typedef Templates33 type; +}; +template +struct Templates { + typedef Templates34 type; +}; +template +struct Templates { + typedef Templates35 type; +}; +template +struct Templates { + typedef Templates36 type; +}; +template +struct Templates { + typedef Templates37 type; +}; +template +struct Templates { + typedef Templates38 type; +}; +template +struct Templates { + typedef Templates39 type; +}; +template +struct Templates { + typedef Templates40 type; +}; +template +struct Templates { + typedef Templates41 type; +}; +template +struct Templates { + typedef Templates42 type; +}; +template +struct Templates { + typedef Templates43 type; +}; +template +struct Templates { + typedef Templates44 type; +}; +template +struct Templates { + typedef Templates45 type; +}; +template +struct Templates { + typedef Templates46 type; +}; +template +struct Templates { + typedef Templates47 type; +}; +template +struct Templates { + typedef Templates48 type; +}; +template +struct Templates { + typedef Templates49 type; +}; + +// The TypeList template makes it possible to use either a single type +// or a Types<...> list in TYPED_TEST_CASE() and +// INSTANTIATE_TYPED_TEST_CASE_P(). + +template +struct TypeList { typedef Types1 type; }; + +template +struct TypeList > { + typedef typename Types::type type; +}; + +} // namespace internal +} // namespace testing + +#endif // GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ + +// Due to C++ preprocessor weirdness, we need double indirection to +// concatenate two tokens when one of them is __LINE__. Writing +// +// foo ## __LINE__ +// +// will result in the token foo__LINE__, instead of foo followed by +// the current line number. For more details, see +// http://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.6 +#define GTEST_CONCAT_TOKEN_(foo, bar) GTEST_CONCAT_TOKEN_IMPL_(foo, bar) +#define GTEST_CONCAT_TOKEN_IMPL_(foo, bar) foo ## bar + +// Google Test defines the testing::Message class to allow construction of +// test messages via the << operator. The idea is that anything +// streamable to std::ostream can be streamed to a testing::Message. +// This allows a user to use his own types in Google Test assertions by +// overloading the << operator. +// +// util/gtl/stl_logging-inl.h overloads << for STL containers. These +// overloads cannot be defined in the std namespace, as that will be +// undefined behavior. Therefore, they are defined in the global +// namespace instead. +// +// C++'s symbol lookup rule (i.e. Koenig lookup) says that these +// overloads are visible in either the std namespace or the global +// namespace, but not other namespaces, including the testing +// namespace which Google Test's Message class is in. +// +// To allow STL containers (and other types that has a << operator +// defined in the global namespace) to be used in Google Test assertions, +// testing::Message must access the custom << operator from the global +// namespace. Hence this helper function. +// +// Note: Jeffrey Yasskin suggested an alternative fix by "using +// ::operator<<;" in the definition of Message's operator<<. That fix +// doesn't require a helper function, but unfortunately doesn't +// compile with MSVC. +template +inline void GTestStreamToHelper(std::ostream* os, const T& val) { + *os << val; +} + +namespace testing { + +// Forward declaration of classes. + +class AssertionResult; // Result of an assertion. +class Message; // Represents a failure message. +class Test; // Represents a test. +class TestInfo; // Information about a test. +class TestPartResult; // Result of a test part. +class UnitTest; // A collection of test cases. + +namespace internal { + +struct TraceInfo; // Information about a trace point. +class ScopedTrace; // Implements scoped trace. +class TestInfoImpl; // Opaque implementation of TestInfo +class UnitTestImpl; // Opaque implementation of UnitTest + +// How many times InitGoogleTest() has been called. +extern int g_init_gtest_count; + +// The text used in failure messages to indicate the start of the +// stack trace. +GTEST_API_ extern const char kStackTraceMarker[]; + +// A secret type that Google Test users don't know about. It has no +// definition on purpose. Therefore it's impossible to create a +// Secret object, which is what we want. +class Secret; + +// Two overloaded helpers for checking at compile time whether an +// expression is a null pointer literal (i.e. NULL or any 0-valued +// compile-time integral constant). Their return values have +// different sizes, so we can use sizeof() to test which version is +// picked by the compiler. These helpers have no implementations, as +// we only need their signatures. +// +// Given IsNullLiteralHelper(x), the compiler will pick the first +// version if x can be implicitly converted to Secret*, and pick the +// second version otherwise. Since Secret is a secret and incomplete +// type, the only expression a user can write that has type Secret* is +// a null pointer literal. Therefore, we know that x is a null +// pointer literal if and only if the first version is picked by the +// compiler. +char IsNullLiteralHelper(Secret* p); +char (&IsNullLiteralHelper(...))[2]; // NOLINT + +// A compile-time bool constant that is true if and only if x is a +// null pointer literal (i.e. NULL or any 0-valued compile-time +// integral constant). +#ifdef GTEST_ELLIPSIS_NEEDS_POD_ +// We lose support for NULL detection where the compiler doesn't like +// passing non-POD classes through ellipsis (...). +#define GTEST_IS_NULL_LITERAL_(x) false +#else +#define GTEST_IS_NULL_LITERAL_(x) \ + (sizeof(::testing::internal::IsNullLiteralHelper(x)) == 1) +#endif // GTEST_ELLIPSIS_NEEDS_POD_ + +// Appends the user-supplied message to the Google-Test-generated message. +GTEST_API_ String AppendUserMessage(const String& gtest_msg, + const Message& user_msg); + +// A helper class for creating scoped traces in user programs. +class GTEST_API_ ScopedTrace { + public: + // The c'tor pushes the given source file location and message onto + // a trace stack maintained by Google Test. + ScopedTrace(const char* file, int line, const Message& message); + + // The d'tor pops the info pushed by the c'tor. + // + // Note that the d'tor is not virtual in order to be efficient. + // Don't inherit from ScopedTrace! + ~ScopedTrace(); + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedTrace); +} GTEST_ATTRIBUTE_UNUSED_; // A ScopedTrace object does its job in its + // c'tor and d'tor. Therefore it doesn't + // need to be used otherwise. + +// Converts a streamable value to a String. A NULL pointer is +// converted to "(null)". When the input value is a ::string, +// ::std::string, ::wstring, or ::std::wstring object, each NUL +// character in it is replaced with "\\0". +// Declared here but defined in gtest.h, so that it has access +// to the definition of the Message class, required by the ARM +// compiler. +template +String StreamableToString(const T& streamable); + +// Formats a value to be used in a failure message. + +#ifdef GTEST_NEEDS_IS_POINTER_ + +// These are needed as the Nokia Symbian and IBM XL C/C++ compilers +// cannot decide between const T& and const T* in a function template. +// These compilers _can_ decide between class template specializations +// for T and T*, so a tr1::type_traits-like is_pointer works, and we +// can overload on that. + +// This overload makes sure that all pointers (including +// those to char or wchar_t) are printed as raw pointers. +template +inline String FormatValueForFailureMessage(internal::true_type /*dummy*/, + T* pointer) { + return StreamableToString(static_cast(pointer)); +} + +template +inline String FormatValueForFailureMessage(internal::false_type /*dummy*/, + const T& value) { + return StreamableToString(value); +} + +template +inline String FormatForFailureMessage(const T& value) { + return FormatValueForFailureMessage( + typename internal::is_pointer::type(), value); +} + +#else + +// These are needed as the above solution using is_pointer has the +// limitation that T cannot be a type without external linkage, when +// compiled using MSVC. + +template +inline String FormatForFailureMessage(const T& value) { + return StreamableToString(value); +} + +// This overload makes sure that all pointers (including +// those to char or wchar_t) are printed as raw pointers. +template +inline String FormatForFailureMessage(T* pointer) { + return StreamableToString(static_cast(pointer)); +} + +#endif // GTEST_NEEDS_IS_POINTER_ + +// These overloaded versions handle narrow and wide characters. +GTEST_API_ String FormatForFailureMessage(char ch); +GTEST_API_ String FormatForFailureMessage(wchar_t wchar); + +// When this operand is a const char* or char*, and the other operand +// is a ::std::string or ::string, we print this operand as a C string +// rather than a pointer. We do the same for wide strings. + +// This internal macro is used to avoid duplicated code. +#define GTEST_FORMAT_IMPL_(operand2_type, operand1_printer)\ +inline String FormatForComparisonFailureMessage(\ + operand2_type::value_type* str, const operand2_type& /*operand2*/) {\ + return operand1_printer(str);\ +}\ +inline String FormatForComparisonFailureMessage(\ + const operand2_type::value_type* str, const operand2_type& /*operand2*/) {\ + return operand1_printer(str);\ +} + +GTEST_FORMAT_IMPL_(::std::string, String::ShowCStringQuoted) +#if GTEST_HAS_STD_WSTRING +GTEST_FORMAT_IMPL_(::std::wstring, String::ShowWideCStringQuoted) +#endif // GTEST_HAS_STD_WSTRING + +#if GTEST_HAS_GLOBAL_STRING +GTEST_FORMAT_IMPL_(::string, String::ShowCStringQuoted) +#endif // GTEST_HAS_GLOBAL_STRING +#if GTEST_HAS_GLOBAL_WSTRING +GTEST_FORMAT_IMPL_(::wstring, String::ShowWideCStringQuoted) +#endif // GTEST_HAS_GLOBAL_WSTRING + +#undef GTEST_FORMAT_IMPL_ + +// Constructs and returns the message for an equality assertion +// (e.g. ASSERT_EQ, EXPECT_STREQ, etc) failure. +// +// The first four parameters are the expressions used in the assertion +// and their values, as strings. For example, for ASSERT_EQ(foo, bar) +// where foo is 5 and bar is 6, we have: +// +// expected_expression: "foo" +// actual_expression: "bar" +// expected_value: "5" +// actual_value: "6" +// +// The ignoring_case parameter is true iff the assertion is a +// *_STRCASEEQ*. When it's true, the string " (ignoring case)" will +// be inserted into the message. +GTEST_API_ AssertionResult EqFailure(const char* expected_expression, + const char* actual_expression, + const String& expected_value, + const String& actual_value, + bool ignoring_case); + +// Constructs a failure message for Boolean assertions such as EXPECT_TRUE. +GTEST_API_ String GetBoolAssertionFailureMessage( + const AssertionResult& assertion_result, + const char* expression_text, + const char* actual_predicate_value, + const char* expected_predicate_value); + +// This template class represents an IEEE floating-point number +// (either single-precision or double-precision, depending on the +// template parameters). +// +// The purpose of this class is to do more sophisticated number +// comparison. (Due to round-off error, etc, it's very unlikely that +// two floating-points will be equal exactly. Hence a naive +// comparison by the == operation often doesn't work.) +// +// Format of IEEE floating-point: +// +// The most-significant bit being the leftmost, an IEEE +// floating-point looks like +// +// sign_bit exponent_bits fraction_bits +// +// Here, sign_bit is a single bit that designates the sign of the +// number. +// +// For float, there are 8 exponent bits and 23 fraction bits. +// +// For double, there are 11 exponent bits and 52 fraction bits. +// +// More details can be found at +// http://en.wikipedia.org/wiki/IEEE_floating-point_standard. +// +// Template parameter: +// +// RawType: the raw floating-point type (either float or double) +template +class FloatingPoint { + public: + // Defines the unsigned integer type that has the same size as the + // floating point number. + typedef typename TypeWithSize::UInt Bits; + + // Constants. + + // # of bits in a number. + static const size_t kBitCount = 8*sizeof(RawType); + + // # of fraction bits in a number. + static const size_t kFractionBitCount = + std::numeric_limits::digits - 1; + + // # of exponent bits in a number. + static const size_t kExponentBitCount = kBitCount - 1 - kFractionBitCount; + + // The mask for the sign bit. + static const Bits kSignBitMask = static_cast(1) << (kBitCount - 1); + + // The mask for the fraction bits. + static const Bits kFractionBitMask = + ~static_cast(0) >> (kExponentBitCount + 1); + + // The mask for the exponent bits. + static const Bits kExponentBitMask = ~(kSignBitMask | kFractionBitMask); + + // How many ULP's (Units in the Last Place) we want to tolerate when + // comparing two numbers. The larger the value, the more error we + // allow. A 0 value means that two numbers must be exactly the same + // to be considered equal. + // + // The maximum error of a single floating-point operation is 0.5 + // units in the last place. On Intel CPU's, all floating-point + // calculations are done with 80-bit precision, while double has 64 + // bits. Therefore, 4 should be enough for ordinary use. + // + // See the following article for more details on ULP: + // http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm. + static const size_t kMaxUlps = 4; + + // Constructs a FloatingPoint from a raw floating-point number. + // + // On an Intel CPU, passing a non-normalized NAN (Not a Number) + // around may change its bits, although the new value is guaranteed + // to be also a NAN. Therefore, don't expect this constructor to + // preserve the bits in x when x is a NAN. + explicit FloatingPoint(const RawType& x) { u_.value_ = x; } + + // Static methods + + // Reinterprets a bit pattern as a floating-point number. + // + // This function is needed to test the AlmostEquals() method. + static RawType ReinterpretBits(const Bits bits) { + FloatingPoint fp(0); + fp.u_.bits_ = bits; + return fp.u_.value_; + } + + // Returns the floating-point number that represent positive infinity. + static RawType Infinity() { + return ReinterpretBits(kExponentBitMask); + } + + // Non-static methods + + // Returns the bits that represents this number. + const Bits &bits() const { return u_.bits_; } + + // Returns the exponent bits of this number. + Bits exponent_bits() const { return kExponentBitMask & u_.bits_; } + + // Returns the fraction bits of this number. + Bits fraction_bits() const { return kFractionBitMask & u_.bits_; } + + // Returns the sign bit of this number. + Bits sign_bit() const { return kSignBitMask & u_.bits_; } + + // Returns true iff this is NAN (not a number). + bool is_nan() const { + // It's a NAN if the exponent bits are all ones and the fraction + // bits are not entirely zeros. + return (exponent_bits() == kExponentBitMask) && (fraction_bits() != 0); + } + + // Returns true iff this number is at most kMaxUlps ULP's away from + // rhs. In particular, this function: + // + // - returns false if either number is (or both are) NAN. + // - treats really large numbers as almost equal to infinity. + // - thinks +0.0 and -0.0 are 0 DLP's apart. + bool AlmostEquals(const FloatingPoint& rhs) const { + // The IEEE standard says that any comparison operation involving + // a NAN must return false. + if (is_nan() || rhs.is_nan()) return false; + + return DistanceBetweenSignAndMagnitudeNumbers(u_.bits_, rhs.u_.bits_) + <= kMaxUlps; + } + + private: + // The data type used to store the actual floating-point number. + union FloatingPointUnion { + RawType value_; // The raw floating-point number. + Bits bits_; // The bits that represent the number. + }; + + // Converts an integer from the sign-and-magnitude representation to + // the biased representation. More precisely, let N be 2 to the + // power of (kBitCount - 1), an integer x is represented by the + // unsigned number x + N. + // + // For instance, + // + // -N + 1 (the most negative number representable using + // sign-and-magnitude) is represented by 1; + // 0 is represented by N; and + // N - 1 (the biggest number representable using + // sign-and-magnitude) is represented by 2N - 1. + // + // Read http://en.wikipedia.org/wiki/Signed_number_representations + // for more details on signed number representations. + static Bits SignAndMagnitudeToBiased(const Bits &sam) { + if (kSignBitMask & sam) { + // sam represents a negative number. + return ~sam + 1; + } else { + // sam represents a positive number. + return kSignBitMask | sam; + } + } + + // Given two numbers in the sign-and-magnitude representation, + // returns the distance between them as an unsigned number. + static Bits DistanceBetweenSignAndMagnitudeNumbers(const Bits &sam1, + const Bits &sam2) { + const Bits biased1 = SignAndMagnitudeToBiased(sam1); + const Bits biased2 = SignAndMagnitudeToBiased(sam2); + return (biased1 >= biased2) ? (biased1 - biased2) : (biased2 - biased1); + } + + FloatingPointUnion u_; +}; + +// Typedefs the instances of the FloatingPoint template class that we +// care to use. +typedef FloatingPoint Float; +typedef FloatingPoint Double; + +// In order to catch the mistake of putting tests that use different +// test fixture classes in the same test case, we need to assign +// unique IDs to fixture classes and compare them. The TypeId type is +// used to hold such IDs. The user should treat TypeId as an opaque +// type: the only operation allowed on TypeId values is to compare +// them for equality using the == operator. +typedef const void* TypeId; + +template +class TypeIdHelper { + public: + // dummy_ must not have a const type. Otherwise an overly eager + // compiler (e.g. MSVC 7.1 & 8.0) may try to merge + // TypeIdHelper::dummy_ for different Ts as an "optimization". + static bool dummy_; +}; + +template +bool TypeIdHelper::dummy_ = false; + +// GetTypeId() returns the ID of type T. Different values will be +// returned for different types. Calling the function twice with the +// same type argument is guaranteed to return the same ID. +template +TypeId GetTypeId() { + // The compiler is required to allocate a different + // TypeIdHelper::dummy_ variable for each T used to instantiate + // the template. Therefore, the address of dummy_ is guaranteed to + // be unique. + return &(TypeIdHelper::dummy_); +} + +// Returns the type ID of ::testing::Test. Always call this instead +// of GetTypeId< ::testing::Test>() to get the type ID of +// ::testing::Test, as the latter may give the wrong result due to a +// suspected linker bug when compiling Google Test as a Mac OS X +// framework. +GTEST_API_ TypeId GetTestTypeId(); + +// Defines the abstract factory interface that creates instances +// of a Test object. +class TestFactoryBase { + public: + virtual ~TestFactoryBase() {} + + // Creates a test instance to run. The instance is both created and destroyed + // within TestInfoImpl::Run() + virtual Test* CreateTest() = 0; + + protected: + TestFactoryBase() {} + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestFactoryBase); +}; + +// This class provides implementation of TeastFactoryBase interface. +// It is used in TEST and TEST_F macros. +template +class TestFactoryImpl : public TestFactoryBase { + public: + virtual Test* CreateTest() { return new TestClass; } +}; + +#if GTEST_OS_WINDOWS + +// Predicate-formatters for implementing the HRESULT checking macros +// {ASSERT|EXPECT}_HRESULT_{SUCCEEDED|FAILED} +// We pass a long instead of HRESULT to avoid causing an +// include dependency for the HRESULT type. +GTEST_API_ AssertionResult IsHRESULTSuccess(const char* expr, + long hr); // NOLINT +GTEST_API_ AssertionResult IsHRESULTFailure(const char* expr, + long hr); // NOLINT + +#endif // GTEST_OS_WINDOWS + +// Formats a source file path and a line number as they would appear +// in a compiler error message. +inline String FormatFileLocation(const char* file, int line) { + const char* const file_name = file == NULL ? "unknown file" : file; + if (line < 0) { + return String::Format("%s:", file_name); + } +#ifdef _MSC_VER + return String::Format("%s(%d):", file_name, line); +#else + return String::Format("%s:%d:", file_name, line); +#endif // _MSC_VER +} + +// Types of SetUpTestCase() and TearDownTestCase() functions. +typedef void (*SetUpTestCaseFunc)(); +typedef void (*TearDownTestCaseFunc)(); + +// Creates a new TestInfo object and registers it with Google Test; +// returns the created object. +// +// Arguments: +// +// test_case_name: name of the test case +// name: name of the test +// test_case_comment: a comment on the test case that will be included in +// the test output +// comment: a comment on the test that will be included in the +// test output +// fixture_class_id: ID of the test fixture class +// set_up_tc: pointer to the function that sets up the test case +// tear_down_tc: pointer to the function that tears down the test case +// factory: pointer to the factory that creates a test object. +// The newly created TestInfo instance will assume +// ownership of the factory object. +GTEST_API_ TestInfo* MakeAndRegisterTestInfo( + const char* test_case_name, const char* name, + const char* test_case_comment, const char* comment, + TypeId fixture_class_id, + SetUpTestCaseFunc set_up_tc, + TearDownTestCaseFunc tear_down_tc, + TestFactoryBase* factory); + +// If *pstr starts with the given prefix, modifies *pstr to be right +// past the prefix and returns true; otherwise leaves *pstr unchanged +// and returns false. None of pstr, *pstr, and prefix can be NULL. +bool SkipPrefix(const char* prefix, const char** pstr); + +#if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P + +// State of the definition of a type-parameterized test case. +class GTEST_API_ TypedTestCasePState { + public: + TypedTestCasePState() : registered_(false) {} + + // Adds the given test name to defined_test_names_ and return true + // if the test case hasn't been registered; otherwise aborts the + // program. + bool AddTestName(const char* file, int line, const char* case_name, + const char* test_name) { + if (registered_) { + fprintf(stderr, "%s Test %s must be defined before " + "REGISTER_TYPED_TEST_CASE_P(%s, ...).\n", + FormatFileLocation(file, line).c_str(), test_name, case_name); + fflush(stderr); + posix::Abort(); + } + defined_test_names_.insert(test_name); + return true; + } + + // Verifies that registered_tests match the test names in + // defined_test_names_; returns registered_tests if successful, or + // aborts the program otherwise. + const char* VerifyRegisteredTestNames( + const char* file, int line, const char* registered_tests); + + private: + bool registered_; + ::std::set defined_test_names_; +}; + +// Skips to the first non-space char after the first comma in 'str'; +// returns NULL if no comma is found in 'str'. +inline const char* SkipComma(const char* str) { + const char* comma = strchr(str, ','); + if (comma == NULL) { + return NULL; + } + while (isspace(*(++comma))) {} + return comma; +} + +// Returns the prefix of 'str' before the first comma in it; returns +// the entire string if it contains no comma. +inline String GetPrefixUntilComma(const char* str) { + const char* comma = strchr(str, ','); + return comma == NULL ? String(str) : String(str, comma - str); +} + +// TypeParameterizedTest::Register() +// registers a list of type-parameterized tests with Google Test. The +// return value is insignificant - we just need to return something +// such that we can call this function in a namespace scope. +// +// Implementation note: The GTEST_TEMPLATE_ macro declares a template +// template parameter. It's defined in gtest-type-util.h. +template +class TypeParameterizedTest { + public: + // 'index' is the index of the test in the type list 'Types' + // specified in INSTANTIATE_TYPED_TEST_CASE_P(Prefix, TestCase, + // Types). Valid values for 'index' are [0, N - 1] where N is the + // length of Types. + static bool Register(const char* prefix, const char* case_name, + const char* test_names, int index) { + typedef typename Types::Head Type; + typedef Fixture FixtureClass; + typedef typename GTEST_BIND_(TestSel, Type) TestClass; + + // First, registers the first type-parameterized test in the type + // list. + MakeAndRegisterTestInfo( + String::Format("%s%s%s/%d", prefix, prefix[0] == '\0' ? "" : "/", + case_name, index).c_str(), + GetPrefixUntilComma(test_names).c_str(), + String::Format("TypeParam = %s", GetTypeName().c_str()).c_str(), + "", + GetTypeId(), + TestClass::SetUpTestCase, + TestClass::TearDownTestCase, + new TestFactoryImpl); + + // Next, recurses (at compile time) with the tail of the type list. + return TypeParameterizedTest + ::Register(prefix, case_name, test_names, index + 1); + } +}; + +// The base case for the compile time recursion. +template +class TypeParameterizedTest { + public: + static bool Register(const char* /*prefix*/, const char* /*case_name*/, + const char* /*test_names*/, int /*index*/) { + return true; + } +}; + +// TypeParameterizedTestCase::Register() +// registers *all combinations* of 'Tests' and 'Types' with Google +// Test. The return value is insignificant - we just need to return +// something such that we can call this function in a namespace scope. +template +class TypeParameterizedTestCase { + public: + static bool Register(const char* prefix, const char* case_name, + const char* test_names) { + typedef typename Tests::Head Head; + + // First, register the first test in 'Test' for each type in 'Types'. + TypeParameterizedTest::Register( + prefix, case_name, test_names, 0); + + // Next, recurses (at compile time) with the tail of the test list. + return TypeParameterizedTestCase + ::Register(prefix, case_name, SkipComma(test_names)); + } +}; + +// The base case for the compile time recursion. +template +class TypeParameterizedTestCase { + public: + static bool Register(const char* /*prefix*/, const char* /*case_name*/, + const char* /*test_names*/) { + return true; + } +}; + +#endif // GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P + +// Returns the current OS stack trace as a String. +// +// The maximum number of stack frames to be included is specified by +// the gtest_stack_trace_depth flag. The skip_count parameter +// specifies the number of top frames to be skipped, which doesn't +// count against the number of frames to be included. +// +// For example, if Foo() calls Bar(), which in turn calls +// GetCurrentOsStackTraceExceptTop(..., 1), Foo() will be included in +// the trace but Bar() and GetCurrentOsStackTraceExceptTop() won't. +GTEST_API_ String GetCurrentOsStackTraceExceptTop(UnitTest* unit_test, + int skip_count); + +// Helpers for suppressing warnings on unreachable code or constant +// condition. + +// Always returns true. +GTEST_API_ bool AlwaysTrue(); + +// Always returns false. +inline bool AlwaysFalse() { return !AlwaysTrue(); } + +// A simple Linear Congruential Generator for generating random +// numbers with a uniform distribution. Unlike rand() and srand(), it +// doesn't use global state (and therefore can't interfere with user +// code). Unlike rand_r(), it's portable. An LCG isn't very random, +// but it's good enough for our purposes. +class GTEST_API_ Random { + public: + static const UInt32 kMaxRange = 1u << 31; + + explicit Random(UInt32 seed) : state_(seed) {} + + void Reseed(UInt32 seed) { state_ = seed; } + + // Generates a random number from [0, range). Crashes if 'range' is + // 0 or greater than kMaxRange. + UInt32 Generate(UInt32 range); + + private: + UInt32 state_; + GTEST_DISALLOW_COPY_AND_ASSIGN_(Random); +}; + +} // namespace internal +} // namespace testing + +#define GTEST_MESSAGE_(message, result_type) \ + ::testing::internal::AssertHelper(result_type, __FILE__, __LINE__, message) \ + = ::testing::Message() + +#define GTEST_FATAL_FAILURE_(message) \ + return GTEST_MESSAGE_(message, ::testing::TestPartResult::kFatalFailure) + +#define GTEST_NONFATAL_FAILURE_(message) \ + GTEST_MESSAGE_(message, ::testing::TestPartResult::kNonFatalFailure) + +#define GTEST_SUCCESS_(message) \ + GTEST_MESSAGE_(message, ::testing::TestPartResult::kSuccess) + +// Suppresses MSVC warnings 4072 (unreachable code) for the code following +// statement if it returns or throws (or doesn't return or throw in some +// situations). +#define GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement) \ + if (::testing::internal::AlwaysTrue()) { statement; } + +#define GTEST_TEST_THROW_(statement, expected_exception, fail) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (const char* gtest_msg = "") { \ + bool gtest_caught_expected = false; \ + try { \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ + } \ + catch (expected_exception const&) { \ + gtest_caught_expected = true; \ + } \ + catch (...) { \ + gtest_msg = "Expected: " #statement " throws an exception of type " \ + #expected_exception ".\n Actual: it throws a different " \ + "type."; \ + goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \ + } \ + if (!gtest_caught_expected) { \ + gtest_msg = "Expected: " #statement " throws an exception of type " \ + #expected_exception ".\n Actual: it throws nothing."; \ + goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \ + } \ + } else \ + GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__): \ + fail(gtest_msg) + +#define GTEST_TEST_NO_THROW_(statement, fail) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (const char* gtest_msg = "") { \ + try { \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ + } \ + catch (...) { \ + gtest_msg = "Expected: " #statement " doesn't throw an exception.\n" \ + " Actual: it throws."; \ + goto GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__); \ + } \ + } else \ + GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__): \ + fail(gtest_msg) + +#define GTEST_TEST_ANY_THROW_(statement, fail) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (const char* gtest_msg = "") { \ + bool gtest_caught_any = false; \ + try { \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ + } \ + catch (...) { \ + gtest_caught_any = true; \ + } \ + if (!gtest_caught_any) { \ + gtest_msg = "Expected: " #statement " throws an exception.\n" \ + " Actual: it doesn't."; \ + goto GTEST_CONCAT_TOKEN_(gtest_label_testanythrow_, __LINE__); \ + } \ + } else \ + GTEST_CONCAT_TOKEN_(gtest_label_testanythrow_, __LINE__): \ + fail(gtest_msg) + + +// Implements Boolean test assertions such as EXPECT_TRUE. expression can be +// either a boolean expression or an AssertionResult. text is a textual +// represenation of expression as it was passed into the EXPECT_TRUE. +#define GTEST_TEST_BOOLEAN_(expression, text, actual, expected, fail) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (const ::testing::AssertionResult gtest_ar_ = \ + ::testing::AssertionResult(expression)) \ + ; \ + else \ + fail(::testing::internal::GetBoolAssertionFailureMessage(\ + gtest_ar_, text, #actual, #expected).c_str()) + +#define GTEST_TEST_NO_FATAL_FAILURE_(statement, fail) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (const char* gtest_msg = "") { \ + ::testing::internal::HasNewFatalFailureHelper gtest_fatal_failure_checker; \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ + if (gtest_fatal_failure_checker.has_new_fatal_failure()) { \ + gtest_msg = "Expected: " #statement " doesn't generate new fatal " \ + "failures in the current thread.\n" \ + " Actual: it does."; \ + goto GTEST_CONCAT_TOKEN_(gtest_label_testnofatal_, __LINE__); \ + } \ + } else \ + GTEST_CONCAT_TOKEN_(gtest_label_testnofatal_, __LINE__): \ + fail(gtest_msg) + +// Expands to the name of the class that implements the given test. +#define GTEST_TEST_CLASS_NAME_(test_case_name, test_name) \ + test_case_name##_##test_name##_Test + +// Helper macro for defining tests. +#define GTEST_TEST_(test_case_name, test_name, parent_class, parent_id)\ +class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) : public parent_class {\ + public:\ + GTEST_TEST_CLASS_NAME_(test_case_name, test_name)() {}\ + private:\ + virtual void TestBody();\ + static ::testing::TestInfo* const test_info_;\ + GTEST_DISALLOW_COPY_AND_ASSIGN_(\ + GTEST_TEST_CLASS_NAME_(test_case_name, test_name));\ +};\ +\ +::testing::TestInfo* const GTEST_TEST_CLASS_NAME_(test_case_name, test_name)\ + ::test_info_ =\ + ::testing::internal::MakeAndRegisterTestInfo(\ + #test_case_name, #test_name, "", "", \ + (parent_id), \ + parent_class::SetUpTestCase, \ + parent_class::TearDownTestCase, \ + new ::testing::internal::TestFactoryImpl<\ + GTEST_TEST_CLASS_NAME_(test_case_name, test_name)>);\ +void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody() + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: wan@google.com (Zhanyong Wan) +// +// The Google C++ Testing Framework (Google Test) +// +// This header file defines the public API for death tests. It is +// #included by gtest.h so a user doesn't need to include this +// directly. + +#ifndef GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_ +#define GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_ + +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee) +// +// The Google C++ Testing Framework (Google Test) +// +// This header file defines internal utilities needed for implementing +// death tests. They are subject to change without notice. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_ + + +namespace testing { +namespace internal { + +GTEST_DECLARE_string_(internal_run_death_test); + +// Names of the flags (needed for parsing Google Test flags). +const char kDeathTestStyleFlag[] = "death_test_style"; +const char kDeathTestUseFork[] = "death_test_use_fork"; +const char kInternalRunDeathTestFlag[] = "internal_run_death_test"; + +#if GTEST_HAS_DEATH_TEST + +// DeathTest is a class that hides much of the complexity of the +// GTEST_DEATH_TEST_ macro. It is abstract; its static Create method +// returns a concrete class that depends on the prevailing death test +// style, as defined by the --gtest_death_test_style and/or +// --gtest_internal_run_death_test flags. + +// In describing the results of death tests, these terms are used with +// the corresponding definitions: +// +// exit status: The integer exit information in the format specified +// by wait(2) +// exit code: The integer code passed to exit(3), _exit(2), or +// returned from main() +class GTEST_API_ DeathTest { + public: + // Create returns false if there was an error determining the + // appropriate action to take for the current death test; for example, + // if the gtest_death_test_style flag is set to an invalid value. + // The LastMessage method will return a more detailed message in that + // case. Otherwise, the DeathTest pointer pointed to by the "test" + // argument is set. If the death test should be skipped, the pointer + // is set to NULL; otherwise, it is set to the address of a new concrete + // DeathTest object that controls the execution of the current test. + static bool Create(const char* statement, const RE* regex, + const char* file, int line, DeathTest** test); + DeathTest(); + virtual ~DeathTest() { } + + // A helper class that aborts a death test when it's deleted. + class ReturnSentinel { + public: + explicit ReturnSentinel(DeathTest* test) : test_(test) { } + ~ReturnSentinel() { test_->Abort(TEST_ENCOUNTERED_RETURN_STATEMENT); } + private: + DeathTest* const test_; + GTEST_DISALLOW_COPY_AND_ASSIGN_(ReturnSentinel); + } GTEST_ATTRIBUTE_UNUSED_; + + // An enumeration of possible roles that may be taken when a death + // test is encountered. EXECUTE means that the death test logic should + // be executed immediately. OVERSEE means that the program should prepare + // the appropriate environment for a child process to execute the death + // test, then wait for it to complete. + enum TestRole { OVERSEE_TEST, EXECUTE_TEST }; + + // An enumeration of the two reasons that a test might be aborted. + enum AbortReason { TEST_ENCOUNTERED_RETURN_STATEMENT, TEST_DID_NOT_DIE }; + + // Assumes one of the above roles. + virtual TestRole AssumeRole() = 0; + + // Waits for the death test to finish and returns its status. + virtual int Wait() = 0; + + // Returns true if the death test passed; that is, the test process + // exited during the test, its exit status matches a user-supplied + // predicate, and its stderr output matches a user-supplied regular + // expression. + // The user-supplied predicate may be a macro expression rather + // than a function pointer or functor, or else Wait and Passed could + // be combined. + virtual bool Passed(bool exit_status_ok) = 0; + + // Signals that the death test did not die as expected. + virtual void Abort(AbortReason reason) = 0; + + // Returns a human-readable outcome message regarding the outcome of + // the last death test. + static const char* LastMessage(); + + static void set_last_death_test_message(const String& message); + + private: + // A string containing a description of the outcome of the last death test. + static String last_death_test_message_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(DeathTest); +}; + +// Factory interface for death tests. May be mocked out for testing. +class DeathTestFactory { + public: + virtual ~DeathTestFactory() { } + virtual bool Create(const char* statement, const RE* regex, + const char* file, int line, DeathTest** test) = 0; +}; + +// A concrete DeathTestFactory implementation for normal use. +class DefaultDeathTestFactory : public DeathTestFactory { + public: + virtual bool Create(const char* statement, const RE* regex, + const char* file, int line, DeathTest** test); +}; + +// Returns true if exit_status describes a process that was terminated +// by a signal, or exited normally with a nonzero exit code. +GTEST_API_ bool ExitedUnsuccessfully(int exit_status); + +// This macro is for implementing ASSERT_DEATH*, EXPECT_DEATH*, +// ASSERT_EXIT*, and EXPECT_EXIT*. +#define GTEST_DEATH_TEST_(statement, predicate, regex, fail) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (::testing::internal::AlwaysTrue()) { \ + const ::testing::internal::RE& gtest_regex = (regex); \ + ::testing::internal::DeathTest* gtest_dt; \ + if (!::testing::internal::DeathTest::Create(#statement, >est_regex, \ + __FILE__, __LINE__, >est_dt)) { \ + goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \ + } \ + if (gtest_dt != NULL) { \ + ::testing::internal::scoped_ptr< ::testing::internal::DeathTest> \ + gtest_dt_ptr(gtest_dt); \ + switch (gtest_dt->AssumeRole()) { \ + case ::testing::internal::DeathTest::OVERSEE_TEST: \ + if (!gtest_dt->Passed(predicate(gtest_dt->Wait()))) { \ + goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \ + } \ + break; \ + case ::testing::internal::DeathTest::EXECUTE_TEST: { \ + ::testing::internal::DeathTest::ReturnSentinel \ + gtest_sentinel(gtest_dt); \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ + gtest_dt->Abort(::testing::internal::DeathTest::TEST_DID_NOT_DIE); \ + break; \ + } \ + } \ + } \ + } else \ + GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__): \ + fail(::testing::internal::DeathTest::LastMessage()) +// The symbol "fail" here expands to something into which a message +// can be streamed. + +// A class representing the parsed contents of the +// --gtest_internal_run_death_test flag, as it existed when +// RUN_ALL_TESTS was called. +class InternalRunDeathTestFlag { + public: + InternalRunDeathTestFlag(const String& a_file, + int a_line, + int an_index, + int a_write_fd) + : file_(a_file), line_(a_line), index_(an_index), + write_fd_(a_write_fd) {} + + ~InternalRunDeathTestFlag() { + if (write_fd_ >= 0) + posix::Close(write_fd_); + } + + String file() const { return file_; } + int line() const { return line_; } + int index() const { return index_; } + int write_fd() const { return write_fd_; } + + private: + String file_; + int line_; + int index_; + int write_fd_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(InternalRunDeathTestFlag); +}; + +// Returns a newly created InternalRunDeathTestFlag object with fields +// initialized from the GTEST_FLAG(internal_run_death_test) flag if +// the flag is specified; otherwise returns NULL. +InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag(); + +#else // GTEST_HAS_DEATH_TEST + +// This macro is used for implementing macros such as +// EXPECT_DEATH_IF_SUPPORTED and ASSERT_DEATH_IF_SUPPORTED on systems where +// death tests are not supported. Those macros must compile on such systems +// iff EXPECT_DEATH and ASSERT_DEATH compile with the same parameters on +// systems that support death tests. This allows one to write such a macro +// on a system that does not support death tests and be sure that it will +// compile on a death-test supporting system. +// +// Parameters: +// statement - A statement that a macro such as EXPECT_DEATH would test +// for program termination. This macro has to make sure this +// statement is compiled but not executed, to ensure that +// EXPECT_DEATH_IF_SUPPORTED compiles with a certain +// parameter iff EXPECT_DEATH compiles with it. +// regex - A regex that a macro such as EXPECT_DEATH would use to test +// the output of statement. This parameter has to be +// compiled but not evaluated by this macro, to ensure that +// this macro only accepts expressions that a macro such as +// EXPECT_DEATH would accept. +// terminator - Must be an empty statement for EXPECT_DEATH_IF_SUPPORTED +// and a return statement for ASSERT_DEATH_IF_SUPPORTED. +// This ensures that ASSERT_DEATH_IF_SUPPORTED will not +// compile inside functions where ASSERT_DEATH doesn't +// compile. +// +// The branch that has an always false condition is used to ensure that +// statement and regex are compiled (and thus syntactically correct) but +// never executed. The unreachable code macro protects the terminator +// statement from generating an 'unreachable code' warning in case +// statement unconditionally returns or throws. The Message constructor at +// the end allows the syntax of streaming additional messages into the +// macro, for compilational compatibility with EXPECT_DEATH/ASSERT_DEATH. +#define GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, terminator) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (::testing::internal::AlwaysTrue()) { \ + GTEST_LOG_(WARNING) \ + << "Death tests are not supported on this platform.\n" \ + << "Statement '" #statement "' cannot be verified."; \ + } else if (::testing::internal::AlwaysFalse()) { \ + ::testing::internal::RE::PartialMatch(".*", (regex)); \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ + terminator; \ + } else \ + ::testing::Message() + +#endif // GTEST_HAS_DEATH_TEST + +} // namespace internal +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_ + +namespace testing { + +// This flag controls the style of death tests. Valid values are "threadsafe", +// meaning that the death test child process will re-execute the test binary +// from the start, running only a single death test, or "fast", +// meaning that the child process will execute the test logic immediately +// after forking. +GTEST_DECLARE_string_(death_test_style); + +#if GTEST_HAS_DEATH_TEST + +// The following macros are useful for writing death tests. + +// Here's what happens when an ASSERT_DEATH* or EXPECT_DEATH* is +// executed: +// +// 1. It generates a warning if there is more than one active +// thread. This is because it's safe to fork() or clone() only +// when there is a single thread. +// +// 2. The parent process clone()s a sub-process and runs the death +// test in it; the sub-process exits with code 0 at the end of the +// death test, if it hasn't exited already. +// +// 3. The parent process waits for the sub-process to terminate. +// +// 4. The parent process checks the exit code and error message of +// the sub-process. +// +// Examples: +// +// ASSERT_DEATH(server.SendMessage(56, "Hello"), "Invalid port number"); +// for (int i = 0; i < 5; i++) { +// EXPECT_DEATH(server.ProcessRequest(i), +// "Invalid request .* in ProcessRequest()") +// << "Failed to die on request " << i); +// } +// +// ASSERT_EXIT(server.ExitNow(), ::testing::ExitedWithCode(0), "Exiting"); +// +// bool KilledBySIGHUP(int exit_code) { +// return WIFSIGNALED(exit_code) && WTERMSIG(exit_code) == SIGHUP; +// } +// +// ASSERT_EXIT(client.HangUpServer(), KilledBySIGHUP, "Hanging up!"); +// +// On the regular expressions used in death tests: +// +// On POSIX-compliant systems (*nix), we use the library, +// which uses the POSIX extended regex syntax. +// +// On other platforms (e.g. Windows), we only support a simple regex +// syntax implemented as part of Google Test. This limited +// implementation should be enough most of the time when writing +// death tests; though it lacks many features you can find in PCRE +// or POSIX extended regex syntax. For example, we don't support +// union ("x|y"), grouping ("(xy)"), brackets ("[xy]"), and +// repetition count ("x{5,7}"), among others. +// +// Below is the syntax that we do support. We chose it to be a +// subset of both PCRE and POSIX extended regex, so it's easy to +// learn wherever you come from. In the following: 'A' denotes a +// literal character, period (.), or a single \\ escape sequence; +// 'x' and 'y' denote regular expressions; 'm' and 'n' are for +// natural numbers. +// +// c matches any literal character c +// \\d matches any decimal digit +// \\D matches any character that's not a decimal digit +// \\f matches \f +// \\n matches \n +// \\r matches \r +// \\s matches any ASCII whitespace, including \n +// \\S matches any character that's not a whitespace +// \\t matches \t +// \\v matches \v +// \\w matches any letter, _, or decimal digit +// \\W matches any character that \\w doesn't match +// \\c matches any literal character c, which must be a punctuation +// . matches any single character except \n +// A? matches 0 or 1 occurrences of A +// A* matches 0 or many occurrences of A +// A+ matches 1 or many occurrences of A +// ^ matches the beginning of a string (not that of each line) +// $ matches the end of a string (not that of each line) +// xy matches x followed by y +// +// If you accidentally use PCRE or POSIX extended regex features +// not implemented by us, you will get a run-time failure. In that +// case, please try to rewrite your regular expression within the +// above syntax. +// +// This implementation is *not* meant to be as highly tuned or robust +// as a compiled regex library, but should perform well enough for a +// death test, which already incurs significant overhead by launching +// a child process. +// +// Known caveats: +// +// A "threadsafe" style death test obtains the path to the test +// program from argv[0] and re-executes it in the sub-process. For +// simplicity, the current implementation doesn't search the PATH +// when launching the sub-process. This means that the user must +// invoke the test program via a path that contains at least one +// path separator (e.g. path/to/foo_test and +// /absolute/path/to/bar_test are fine, but foo_test is not). This +// is rarely a problem as people usually don't put the test binary +// directory in PATH. +// +// TODO(wan@google.com): make thread-safe death tests search the PATH. + +// Asserts that a given statement causes the program to exit, with an +// integer exit status that satisfies predicate, and emitting error output +// that matches regex. +#define ASSERT_EXIT(statement, predicate, regex) \ + GTEST_DEATH_TEST_(statement, predicate, regex, GTEST_FATAL_FAILURE_) + +// Like ASSERT_EXIT, but continues on to successive tests in the +// test case, if any: +#define EXPECT_EXIT(statement, predicate, regex) \ + GTEST_DEATH_TEST_(statement, predicate, regex, GTEST_NONFATAL_FAILURE_) + +// Asserts that a given statement causes the program to exit, either by +// explicitly exiting with a nonzero exit code or being killed by a +// signal, and emitting error output that matches regex. +#define ASSERT_DEATH(statement, regex) \ + ASSERT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex) + +// Like ASSERT_DEATH, but continues on to successive tests in the +// test case, if any: +#define EXPECT_DEATH(statement, regex) \ + EXPECT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex) + +// Two predicate classes that can be used in {ASSERT,EXPECT}_EXIT*: + +// Tests that an exit code describes a normal exit with a given exit code. +class GTEST_API_ ExitedWithCode { + public: + explicit ExitedWithCode(int exit_code); + bool operator()(int exit_status) const; + private: + // No implementation - assignment is unsupported. + void operator=(const ExitedWithCode& other); + + const int exit_code_; +}; + +#if !GTEST_OS_WINDOWS +// Tests that an exit code describes an exit due to termination by a +// given signal. +class GTEST_API_ KilledBySignal { + public: + explicit KilledBySignal(int signum); + bool operator()(int exit_status) const; + private: + const int signum_; +}; +#endif // !GTEST_OS_WINDOWS + +// EXPECT_DEBUG_DEATH asserts that the given statements die in debug mode. +// The death testing framework causes this to have interesting semantics, +// since the sideeffects of the call are only visible in opt mode, and not +// in debug mode. +// +// In practice, this can be used to test functions that utilize the +// LOG(DFATAL) macro using the following style: +// +// int DieInDebugOr12(int* sideeffect) { +// if (sideeffect) { +// *sideeffect = 12; +// } +// LOG(DFATAL) << "death"; +// return 12; +// } +// +// TEST(TestCase, TestDieOr12WorksInDgbAndOpt) { +// int sideeffect = 0; +// // Only asserts in dbg. +// EXPECT_DEBUG_DEATH(DieInDebugOr12(&sideeffect), "death"); +// +// #ifdef NDEBUG +// // opt-mode has sideeffect visible. +// EXPECT_EQ(12, sideeffect); +// #else +// // dbg-mode no visible sideeffect. +// EXPECT_EQ(0, sideeffect); +// #endif +// } +// +// This will assert that DieInDebugReturn12InOpt() crashes in debug +// mode, usually due to a DCHECK or LOG(DFATAL), but returns the +// appropriate fallback value (12 in this case) in opt mode. If you +// need to test that a function has appropriate side-effects in opt +// mode, include assertions against the side-effects. A general +// pattern for this is: +// +// EXPECT_DEBUG_DEATH({ +// // Side-effects here will have an effect after this statement in +// // opt mode, but none in debug mode. +// EXPECT_EQ(12, DieInDebugOr12(&sideeffect)); +// }, "death"); +// +#ifdef NDEBUG + +#define EXPECT_DEBUG_DEATH(statement, regex) \ + do { statement; } while (::testing::internal::AlwaysFalse()) + +#define ASSERT_DEBUG_DEATH(statement, regex) \ + do { statement; } while (::testing::internal::AlwaysFalse()) + +#else + +#define EXPECT_DEBUG_DEATH(statement, regex) \ + EXPECT_DEATH(statement, regex) + +#define ASSERT_DEBUG_DEATH(statement, regex) \ + ASSERT_DEATH(statement, regex) + +#endif // NDEBUG for EXPECT_DEBUG_DEATH +#endif // GTEST_HAS_DEATH_TEST + +// EXPECT_DEATH_IF_SUPPORTED(statement, regex) and +// ASSERT_DEATH_IF_SUPPORTED(statement, regex) expand to real death tests if +// death tests are supported; otherwise they just issue a warning. This is +// useful when you are combining death test assertions with normal test +// assertions in one test. +#if GTEST_HAS_DEATH_TEST +#define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \ + EXPECT_DEATH(statement, regex) +#define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \ + ASSERT_DEATH(statement, regex) +#else +#define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \ + GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, ) +#define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \ + GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, return) +#endif + +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: wan@google.com (Zhanyong Wan) +// +// The Google C++ Testing Framework (Google Test) +// +// This header file defines the Message class. +// +// IMPORTANT NOTE: Due to limitation of the C++ language, we have to +// leave some internal implementation details in this header file. +// They are clearly marked by comments like this: +// +// // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +// +// Such code is NOT meant to be used by a user directly, and is subject +// to CHANGE WITHOUT NOTICE. Therefore DO NOT DEPEND ON IT in a user +// program! + +#ifndef GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_ +#define GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_ + +#include + + +namespace testing { + +// The Message class works like an ostream repeater. +// +// Typical usage: +// +// 1. You stream a bunch of values to a Message object. +// It will remember the text in a StrStream. +// 2. Then you stream the Message object to an ostream. +// This causes the text in the Message to be streamed +// to the ostream. +// +// For example; +// +// testing::Message foo; +// foo << 1 << " != " << 2; +// std::cout << foo; +// +// will print "1 != 2". +// +// Message is not intended to be inherited from. In particular, its +// destructor is not virtual. +// +// Note that StrStream behaves differently in gcc and in MSVC. You +// can stream a NULL char pointer to it in the former, but not in the +// latter (it causes an access violation if you do). The Message +// class hides this difference by treating a NULL char pointer as +// "(null)". +class GTEST_API_ Message { + private: + // The type of basic IO manipulators (endl, ends, and flush) for + // narrow streams. + typedef std::ostream& (*BasicNarrowIoManip)(std::ostream&); + + public: + // Constructs an empty Message. + // We allocate the StrStream separately because it otherwise each use of + // ASSERT/EXPECT in a procedure adds over 200 bytes to the procedure's + // stack frame leading to huge stack frames in some cases; gcc does not reuse + // the stack space. + Message() : ss_(new internal::StrStream) { + // By default, we want there to be enough precision when printing + // a double to a Message. + *ss_ << std::setprecision(std::numeric_limits::digits10 + 2); + } + + // Copy constructor. + Message(const Message& msg) : ss_(new internal::StrStream) { // NOLINT + *ss_ << msg.GetString(); + } + + // Constructs a Message from a C-string. + explicit Message(const char* str) : ss_(new internal::StrStream) { + *ss_ << str; + } + + ~Message() { delete ss_; } +#if GTEST_OS_SYMBIAN + // Streams a value (either a pointer or not) to this object. + template + inline Message& operator <<(const T& value) { + StreamHelper(typename internal::is_pointer::type(), value); + return *this; + } +#else + // Streams a non-pointer value to this object. + template + inline Message& operator <<(const T& val) { + ::GTestStreamToHelper(ss_, val); + return *this; + } + + // Streams a pointer value to this object. + // + // This function is an overload of the previous one. When you + // stream a pointer to a Message, this definition will be used as it + // is more specialized. (The C++ Standard, section + // [temp.func.order].) If you stream a non-pointer, then the + // previous definition will be used. + // + // The reason for this overload is that streaming a NULL pointer to + // ostream is undefined behavior. Depending on the compiler, you + // may get "0", "(nil)", "(null)", or an access violation. To + // ensure consistent result across compilers, we always treat NULL + // as "(null)". + template + inline Message& operator <<(T* const& pointer) { // NOLINT + if (pointer == NULL) { + *ss_ << "(null)"; + } else { + ::GTestStreamToHelper(ss_, pointer); + } + return *this; + } +#endif // GTEST_OS_SYMBIAN + + // Since the basic IO manipulators are overloaded for both narrow + // and wide streams, we have to provide this specialized definition + // of operator <<, even though its body is the same as the + // templatized version above. Without this definition, streaming + // endl or other basic IO manipulators to Message will confuse the + // compiler. + Message& operator <<(BasicNarrowIoManip val) { + *ss_ << val; + return *this; + } + + // Instead of 1/0, we want to see true/false for bool values. + Message& operator <<(bool b) { + return *this << (b ? "true" : "false"); + } + + // These two overloads allow streaming a wide C string to a Message + // using the UTF-8 encoding. + Message& operator <<(const wchar_t* wide_c_str) { + return *this << internal::String::ShowWideCString(wide_c_str); + } + Message& operator <<(wchar_t* wide_c_str) { + return *this << internal::String::ShowWideCString(wide_c_str); + } + +#if GTEST_HAS_STD_WSTRING + // Converts the given wide string to a narrow string using the UTF-8 + // encoding, and streams the result to this Message object. + Message& operator <<(const ::std::wstring& wstr); +#endif // GTEST_HAS_STD_WSTRING + +#if GTEST_HAS_GLOBAL_WSTRING + // Converts the given wide string to a narrow string using the UTF-8 + // encoding, and streams the result to this Message object. + Message& operator <<(const ::wstring& wstr); +#endif // GTEST_HAS_GLOBAL_WSTRING + + // Gets the text streamed to this object so far as a String. + // Each '\0' character in the buffer is replaced with "\\0". + // + // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. + internal::String GetString() const { + return internal::StrStreamToString(ss_); + } + + private: +#if GTEST_OS_SYMBIAN + // These are needed as the Nokia Symbian Compiler cannot decide between + // const T& and const T* in a function template. The Nokia compiler _can_ + // decide between class template specializations for T and T*, so a + // tr1::type_traits-like is_pointer works, and we can overload on that. + template + inline void StreamHelper(internal::true_type /*dummy*/, T* pointer) { + if (pointer == NULL) { + *ss_ << "(null)"; + } else { + ::GTestStreamToHelper(ss_, pointer); + } + } + template + inline void StreamHelper(internal::false_type /*dummy*/, const T& value) { + ::GTestStreamToHelper(ss_, value); + } +#endif // GTEST_OS_SYMBIAN + + // We'll hold the text streamed to this object here. + internal::StrStream* const ss_; + + // We declare (but don't implement) this to prevent the compiler + // from implementing the assignment operator. + void operator=(const Message&); +}; + +// Streams a Message to an ostream. +inline std::ostream& operator <<(std::ostream& os, const Message& sb) { + return os << sb.GetString(); +} + +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_ +// This file was GENERATED by a script. DO NOT EDIT BY HAND!!! + +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: vladl@google.com (Vlad Losev) +// +// Macros and functions for implementing parameterized tests +// in Google C++ Testing Framework (Google Test) +// +// This file is generated by a SCRIPT. DO NOT EDIT BY HAND! +// +#ifndef GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_ +#define GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_ + + +// Value-parameterized tests allow you to test your code with different +// parameters without writing multiple copies of the same test. +// +// Here is how you use value-parameterized tests: + +#if 0 + +// To write value-parameterized tests, first you should define a fixture +// class. It must be derived from testing::TestWithParam, where T is +// the type of your parameter values. TestWithParam is itself derived +// from testing::Test. T can be any copyable type. If it's a raw pointer, +// you are responsible for managing the lifespan of the pointed values. + +class FooTest : public ::testing::TestWithParam { + // You can implement all the usual class fixture members here. +}; + +// Then, use the TEST_P macro to define as many parameterized tests +// for this fixture as you want. The _P suffix is for "parameterized" +// or "pattern", whichever you prefer to think. + +TEST_P(FooTest, DoesBlah) { + // Inside a test, access the test parameter with the GetParam() method + // of the TestWithParam class: + EXPECT_TRUE(foo.Blah(GetParam())); + ... +} + +TEST_P(FooTest, HasBlahBlah) { + ... +} + +// Finally, you can use INSTANTIATE_TEST_CASE_P to instantiate the test +// case with any set of parameters you want. Google Test defines a number +// of functions for generating test parameters. They return what we call +// (surprise!) parameter generators. Here is a summary of them, which +// are all in the testing namespace: +// +// +// Range(begin, end [, step]) - Yields values {begin, begin+step, +// begin+step+step, ...}. The values do not +// include end. step defaults to 1. +// Values(v1, v2, ..., vN) - Yields values {v1, v2, ..., vN}. +// ValuesIn(container) - Yields values from a C-style array, an STL +// ValuesIn(begin,end) container, or an iterator range [begin, end). +// Bool() - Yields sequence {false, true}. +// Combine(g1, g2, ..., gN) - Yields all combinations (the Cartesian product +// for the math savvy) of the values generated +// by the N generators. +// +// For more details, see comments at the definitions of these functions below +// in this file. +// +// The following statement will instantiate tests from the FooTest test case +// each with parameter values "meeny", "miny", and "moe". + +INSTANTIATE_TEST_CASE_P(InstantiationName, + FooTest, + Values("meeny", "miny", "moe")); + +// To distinguish different instances of the pattern, (yes, you +// can instantiate it more then once) the first argument to the +// INSTANTIATE_TEST_CASE_P macro is a prefix that will be added to the +// actual test case name. Remember to pick unique prefixes for different +// instantiations. The tests from the instantiation above will have +// these names: +// +// * InstantiationName/FooTest.DoesBlah/0 for "meeny" +// * InstantiationName/FooTest.DoesBlah/1 for "miny" +// * InstantiationName/FooTest.DoesBlah/2 for "moe" +// * InstantiationName/FooTest.HasBlahBlah/0 for "meeny" +// * InstantiationName/FooTest.HasBlahBlah/1 for "miny" +// * InstantiationName/FooTest.HasBlahBlah/2 for "moe" +// +// You can use these names in --gtest_filter. +// +// This statement will instantiate all tests from FooTest again, each +// with parameter values "cat" and "dog": + +const char* pets[] = {"cat", "dog"}; +INSTANTIATE_TEST_CASE_P(AnotherInstantiationName, FooTest, ValuesIn(pets)); + +// The tests from the instantiation above will have these names: +// +// * AnotherInstantiationName/FooTest.DoesBlah/0 for "cat" +// * AnotherInstantiationName/FooTest.DoesBlah/1 for "dog" +// * AnotherInstantiationName/FooTest.HasBlahBlah/0 for "cat" +// * AnotherInstantiationName/FooTest.HasBlahBlah/1 for "dog" +// +// Please note that INSTANTIATE_TEST_CASE_P will instantiate all tests +// in the given test case, whether their definitions come before or +// AFTER the INSTANTIATE_TEST_CASE_P statement. +// +// Please also note that generator expressions (including parameters to the +// generators) are evaluated in InitGoogleTest(), after main() has started. +// This allows the user on one hand, to adjust generator parameters in order +// to dynamically determine a set of tests to run and on the other hand, +// give the user a chance to inspect the generated tests with Google Test +// reflection API before RUN_ALL_TESTS() is executed. +// +// You can see samples/sample7_unittest.cc and samples/sample8_unittest.cc +// for more examples. +// +// In the future, we plan to publish the API for defining new parameter +// generators. But for now this interface remains part of the internal +// implementation and is subject to change. + +#endif // 0 + + +#if !GTEST_OS_SYMBIAN +#include +#endif + +// scripts/fuse_gtest.py depends on gtest's own header being #included +// *unconditionally*. Therefore these #includes cannot be moved +// inside #if GTEST_HAS_PARAM_TEST. +// Copyright 2008 Google Inc. +// All Rights Reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: vladl@google.com (Vlad Losev) + +// Type and function utilities for implementing parameterized tests. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_ + +#include +#include +#include + +// scripts/fuse_gtest.py depends on gtest's own header being #included +// *unconditionally*. Therefore these #includes cannot be moved +// inside #if GTEST_HAS_PARAM_TEST. +// Copyright 2003 Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: Dan Egnor (egnor@google.com) +// +// A "smart" pointer type with reference tracking. Every pointer to a +// particular object is kept on a circular linked list. When the last pointer +// to an object is destroyed or reassigned, the object is deleted. +// +// Used properly, this deletes the object when the last reference goes away. +// There are several caveats: +// - Like all reference counting schemes, cycles lead to leaks. +// - Each smart pointer is actually two pointers (8 bytes instead of 4). +// - Every time a pointer is assigned, the entire list of pointers to that +// object is traversed. This class is therefore NOT SUITABLE when there +// will often be more than two or three pointers to a particular object. +// - References are only tracked as long as linked_ptr<> objects are copied. +// If a linked_ptr<> is converted to a raw pointer and back, BAD THINGS +// will happen (double deletion). +// +// A good use of this class is storing object references in STL containers. +// You can safely put linked_ptr<> in a vector<>. +// Other uses may not be as good. +// +// Note: If you use an incomplete type with linked_ptr<>, the class +// *containing* linked_ptr<> must have a constructor and destructor (even +// if they do nothing!). +// +// Bill Gibbons suggested we use something like this. +// +// Thread Safety: +// Unlike other linked_ptr implementations, in this implementation +// a linked_ptr object is thread-safe in the sense that: +// - it's safe to copy linked_ptr objects concurrently, +// - it's safe to copy *from* a linked_ptr and read its underlying +// raw pointer (e.g. via get()) concurrently, and +// - it's safe to write to two linked_ptrs that point to the same +// shared object concurrently. +// TODO(wan@google.com): rename this to safe_linked_ptr to avoid +// confusion with normal linked_ptr. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_ + +#include +#include + + +namespace testing { +namespace internal { + +// Protects copying of all linked_ptr objects. +GTEST_API_ GTEST_DECLARE_STATIC_MUTEX_(g_linked_ptr_mutex); + +// This is used internally by all instances of linked_ptr<>. It needs to be +// a non-template class because different types of linked_ptr<> can refer to +// the same object (linked_ptr(obj) vs linked_ptr(obj)). +// So, it needs to be possible for different types of linked_ptr to participate +// in the same circular linked list, so we need a single class type here. +// +// DO NOT USE THIS CLASS DIRECTLY YOURSELF. Use linked_ptr. +class linked_ptr_internal { + public: + // Create a new circle that includes only this instance. + void join_new() { + next_ = this; + } + + // Many linked_ptr operations may change p.link_ for some linked_ptr + // variable p in the same circle as this object. Therefore we need + // to prevent two such operations from occurring concurrently. + // + // Note that different types of linked_ptr objects can coexist in a + // circle (e.g. linked_ptr, linked_ptr, and + // linked_ptr). Therefore we must use a single mutex to + // protect all linked_ptr objects. This can create serious + // contention in production code, but is acceptable in a testing + // framework. + + // Join an existing circle. + // L < g_linked_ptr_mutex + void join(linked_ptr_internal const* ptr) { + MutexLock lock(&g_linked_ptr_mutex); + + linked_ptr_internal const* p = ptr; + while (p->next_ != ptr) p = p->next_; + p->next_ = this; + next_ = ptr; + } + + // Leave whatever circle we're part of. Returns true if we were the + // last member of the circle. Once this is done, you can join() another. + // L < g_linked_ptr_mutex + bool depart() { + MutexLock lock(&g_linked_ptr_mutex); + + if (next_ == this) return true; + linked_ptr_internal const* p = next_; + while (p->next_ != this) p = p->next_; + p->next_ = next_; + return false; + } + + private: + mutable linked_ptr_internal const* next_; +}; + +template +class linked_ptr { + public: + typedef T element_type; + + // Take over ownership of a raw pointer. This should happen as soon as + // possible after the object is created. + explicit linked_ptr(T* ptr = NULL) { capture(ptr); } + ~linked_ptr() { depart(); } + + // Copy an existing linked_ptr<>, adding ourselves to the list of references. + template linked_ptr(linked_ptr const& ptr) { copy(&ptr); } + linked_ptr(linked_ptr const& ptr) { // NOLINT + assert(&ptr != this); + copy(&ptr); + } + + // Assignment releases the old value and acquires the new. + template linked_ptr& operator=(linked_ptr const& ptr) { + depart(); + copy(&ptr); + return *this; + } + + linked_ptr& operator=(linked_ptr const& ptr) { + if (&ptr != this) { + depart(); + copy(&ptr); + } + return *this; + } + + // Smart pointer members. + void reset(T* ptr = NULL) { + depart(); + capture(ptr); + } + T* get() const { return value_; } + T* operator->() const { return value_; } + T& operator*() const { return *value_; } + // Release ownership of the pointed object and returns it. + // Sole ownership by this linked_ptr object is required. + T* release() { + bool last = link_.depart(); + assert(last); + T* v = value_; + value_ = NULL; + return v; + } + + bool operator==(T* p) const { return value_ == p; } + bool operator!=(T* p) const { return value_ != p; } + template + bool operator==(linked_ptr const& ptr) const { + return value_ == ptr.get(); + } + template + bool operator!=(linked_ptr const& ptr) const { + return value_ != ptr.get(); + } + + private: + template + friend class linked_ptr; + + T* value_; + linked_ptr_internal link_; + + void depart() { + if (link_.depart()) delete value_; + } + + void capture(T* ptr) { + value_ = ptr; + link_.join_new(); + } + + template void copy(linked_ptr const* ptr) { + value_ = ptr->get(); + if (value_) + link_.join(&ptr->link_); + else + link_.join_new(); + } +}; + +template inline +bool operator==(T* ptr, const linked_ptr& x) { + return ptr == x.get(); +} + +template inline +bool operator!=(T* ptr, const linked_ptr& x) { + return ptr != x.get(); +} + +// A function to convert T* into linked_ptr +// Doing e.g. make_linked_ptr(new FooBarBaz(arg)) is a shorter notation +// for linked_ptr >(new FooBarBaz(arg)) +template +linked_ptr make_linked_ptr(T* ptr) { + return linked_ptr(ptr); +} + +} // namespace internal +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_ + +#if GTEST_HAS_PARAM_TEST + +namespace testing { +namespace internal { + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// Outputs a message explaining invalid registration of different +// fixture class for the same test case. This may happen when +// TEST_P macro is used to define two tests with the same name +// but in different namespaces. +GTEST_API_ void ReportInvalidTestCaseType(const char* test_case_name, + const char* file, int line); + +template class ParamGeneratorInterface; +template class ParamGenerator; + +// Interface for iterating over elements provided by an implementation +// of ParamGeneratorInterface. +template +class ParamIteratorInterface { + public: + virtual ~ParamIteratorInterface() {} + // A pointer to the base generator instance. + // Used only for the purposes of iterator comparison + // to make sure that two iterators belong to the same generator. + virtual const ParamGeneratorInterface* BaseGenerator() const = 0; + // Advances iterator to point to the next element + // provided by the generator. The caller is responsible + // for not calling Advance() on an iterator equal to + // BaseGenerator()->End(). + virtual void Advance() = 0; + // Clones the iterator object. Used for implementing copy semantics + // of ParamIterator. + virtual ParamIteratorInterface* Clone() const = 0; + // Dereferences the current iterator and provides (read-only) access + // to the pointed value. It is the caller's responsibility not to call + // Current() on an iterator equal to BaseGenerator()->End(). + // Used for implementing ParamGenerator::operator*(). + virtual const T* Current() const = 0; + // Determines whether the given iterator and other point to the same + // element in the sequence generated by the generator. + // Used for implementing ParamGenerator::operator==(). + virtual bool Equals(const ParamIteratorInterface& other) const = 0; +}; + +// Class iterating over elements provided by an implementation of +// ParamGeneratorInterface. It wraps ParamIteratorInterface +// and implements the const forward iterator concept. +template +class ParamIterator { + public: + typedef T value_type; + typedef const T& reference; + typedef ptrdiff_t difference_type; + + // ParamIterator assumes ownership of the impl_ pointer. + ParamIterator(const ParamIterator& other) : impl_(other.impl_->Clone()) {} + ParamIterator& operator=(const ParamIterator& other) { + if (this != &other) + impl_.reset(other.impl_->Clone()); + return *this; + } + + const T& operator*() const { return *impl_->Current(); } + const T* operator->() const { return impl_->Current(); } + // Prefix version of operator++. + ParamIterator& operator++() { + impl_->Advance(); + return *this; + } + // Postfix version of operator++. + ParamIterator operator++(int /*unused*/) { + ParamIteratorInterface* clone = impl_->Clone(); + impl_->Advance(); + return ParamIterator(clone); + } + bool operator==(const ParamIterator& other) const { + return impl_.get() == other.impl_.get() || impl_->Equals(*other.impl_); + } + bool operator!=(const ParamIterator& other) const { + return !(*this == other); + } + + private: + friend class ParamGenerator; + explicit ParamIterator(ParamIteratorInterface* impl) : impl_(impl) {} + scoped_ptr > impl_; +}; + +// ParamGeneratorInterface is the binary interface to access generators +// defined in other translation units. +template +class ParamGeneratorInterface { + public: + typedef T ParamType; + + virtual ~ParamGeneratorInterface() {} + + // Generator interface definition + virtual ParamIteratorInterface* Begin() const = 0; + virtual ParamIteratorInterface* End() const = 0; +}; + +// Wraps ParamGeneratorInterface and provides general generator syntax +// compatible with the STL Container concept. +// This class implements copy initialization semantics and the contained +// ParamGeneratorInterface instance is shared among all copies +// of the original object. This is possible because that instance is immutable. +template +class ParamGenerator { + public: + typedef ParamIterator iterator; + + explicit ParamGenerator(ParamGeneratorInterface* impl) : impl_(impl) {} + ParamGenerator(const ParamGenerator& other) : impl_(other.impl_) {} + + ParamGenerator& operator=(const ParamGenerator& other) { + impl_ = other.impl_; + return *this; + } + + iterator begin() const { return iterator(impl_->Begin()); } + iterator end() const { return iterator(impl_->End()); } + + private: + ::testing::internal::linked_ptr > impl_; +}; + +// Generates values from a range of two comparable values. Can be used to +// generate sequences of user-defined types that implement operator+() and +// operator<(). +// This class is used in the Range() function. +template +class RangeGenerator : public ParamGeneratorInterface { + public: + RangeGenerator(T begin, T end, IncrementT step) + : begin_(begin), end_(end), + step_(step), end_index_(CalculateEndIndex(begin, end, step)) {} + virtual ~RangeGenerator() {} + + virtual ParamIteratorInterface* Begin() const { + return new Iterator(this, begin_, 0, step_); + } + virtual ParamIteratorInterface* End() const { + return new Iterator(this, end_, end_index_, step_); + } + + private: + class Iterator : public ParamIteratorInterface { + public: + Iterator(const ParamGeneratorInterface* base, T value, int index, + IncrementT step) + : base_(base), value_(value), index_(index), step_(step) {} + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface* BaseGenerator() const { + return base_; + } + virtual void Advance() { + value_ = value_ + step_; + index_++; + } + virtual ParamIteratorInterface* Clone() const { + return new Iterator(*this); + } + virtual const T* Current() const { return &value_; } + virtual bool Equals(const ParamIteratorInterface& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const int other_index = + CheckedDowncastToActualType(&other)->index_; + return index_ == other_index; + } + + private: + Iterator(const Iterator& other) + : ParamIteratorInterface(), + base_(other.base_), value_(other.value_), index_(other.index_), + step_(other.step_) {} + + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + + const ParamGeneratorInterface* const base_; + T value_; + int index_; + const IncrementT step_; + }; // class RangeGenerator::Iterator + + static int CalculateEndIndex(const T& begin, + const T& end, + const IncrementT& step) { + int end_index = 0; + for (T i = begin; i < end; i = i + step) + end_index++; + return end_index; + } + + // No implementation - assignment is unsupported. + void operator=(const RangeGenerator& other); + + const T begin_; + const T end_; + const IncrementT step_; + // The index for the end() iterator. All the elements in the generated + // sequence are indexed (0-based) to aid iterator comparison. + const int end_index_; +}; // class RangeGenerator + + +// Generates values from a pair of STL-style iterators. Used in the +// ValuesIn() function. The elements are copied from the source range +// since the source can be located on the stack, and the generator +// is likely to persist beyond that stack frame. +template +class ValuesInIteratorRangeGenerator : public ParamGeneratorInterface { + public: + template + ValuesInIteratorRangeGenerator(ForwardIterator begin, ForwardIterator end) + : container_(begin, end) {} + virtual ~ValuesInIteratorRangeGenerator() {} + + virtual ParamIteratorInterface* Begin() const { + return new Iterator(this, container_.begin()); + } + virtual ParamIteratorInterface* End() const { + return new Iterator(this, container_.end()); + } + + private: + typedef typename ::std::vector ContainerType; + + class Iterator : public ParamIteratorInterface { + public: + Iterator(const ParamGeneratorInterface* base, + typename ContainerType::const_iterator iterator) + : base_(base), iterator_(iterator) {} + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface* BaseGenerator() const { + return base_; + } + virtual void Advance() { + ++iterator_; + value_.reset(); + } + virtual ParamIteratorInterface* Clone() const { + return new Iterator(*this); + } + // We need to use cached value referenced by iterator_ because *iterator_ + // can return a temporary object (and of type other then T), so just + // having "return &*iterator_;" doesn't work. + // value_ is updated here and not in Advance() because Advance() + // can advance iterator_ beyond the end of the range, and we cannot + // detect that fact. The client code, on the other hand, is + // responsible for not calling Current() on an out-of-range iterator. + virtual const T* Current() const { + if (value_.get() == NULL) + value_.reset(new T(*iterator_)); + return value_.get(); + } + virtual bool Equals(const ParamIteratorInterface& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + return iterator_ == + CheckedDowncastToActualType(&other)->iterator_; + } + + private: + Iterator(const Iterator& other) + // The explicit constructor call suppresses a false warning + // emitted by gcc when supplied with the -Wextra option. + : ParamIteratorInterface(), + base_(other.base_), + iterator_(other.iterator_) {} + + const ParamGeneratorInterface* const base_; + typename ContainerType::const_iterator iterator_; + // A cached value of *iterator_. We keep it here to allow access by + // pointer in the wrapping iterator's operator->(). + // value_ needs to be mutable to be accessed in Current(). + // Use of scoped_ptr helps manage cached value's lifetime, + // which is bound by the lifespan of the iterator itself. + mutable scoped_ptr value_; + }; // class ValuesInIteratorRangeGenerator::Iterator + + // No implementation - assignment is unsupported. + void operator=(const ValuesInIteratorRangeGenerator& other); + + const ContainerType container_; +}; // class ValuesInIteratorRangeGenerator + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// Stores a parameter value and later creates tests parameterized with that +// value. +template +class ParameterizedTestFactory : public TestFactoryBase { + public: + typedef typename TestClass::ParamType ParamType; + explicit ParameterizedTestFactory(ParamType parameter) : + parameter_(parameter) {} + virtual Test* CreateTest() { + TestClass::SetParam(¶meter_); + return new TestClass(); + } + + private: + const ParamType parameter_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestFactory); +}; + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// TestMetaFactoryBase is a base class for meta-factories that create +// test factories for passing into MakeAndRegisterTestInfo function. +template +class TestMetaFactoryBase { + public: + virtual ~TestMetaFactoryBase() {} + + virtual TestFactoryBase* CreateTestFactory(ParamType parameter) = 0; +}; + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// TestMetaFactory creates test factories for passing into +// MakeAndRegisterTestInfo function. Since MakeAndRegisterTestInfo receives +// ownership of test factory pointer, same factory object cannot be passed +// into that method twice. But ParameterizedTestCaseInfo is going to call +// it for each Test/Parameter value combination. Thus it needs meta factory +// creator class. +template +class TestMetaFactory + : public TestMetaFactoryBase { + public: + typedef typename TestCase::ParamType ParamType; + + TestMetaFactory() {} + + virtual TestFactoryBase* CreateTestFactory(ParamType parameter) { + return new ParameterizedTestFactory(parameter); + } + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestMetaFactory); +}; + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// ParameterizedTestCaseInfoBase is a generic interface +// to ParameterizedTestCaseInfo classes. ParameterizedTestCaseInfoBase +// accumulates test information provided by TEST_P macro invocations +// and generators provided by INSTANTIATE_TEST_CASE_P macro invocations +// and uses that information to register all resulting test instances +// in RegisterTests method. The ParameterizeTestCaseRegistry class holds +// a collection of pointers to the ParameterizedTestCaseInfo objects +// and calls RegisterTests() on each of them when asked. +class ParameterizedTestCaseInfoBase { + public: + virtual ~ParameterizedTestCaseInfoBase() {} + + // Base part of test case name for display purposes. + virtual const String& GetTestCaseName() const = 0; + // Test case id to verify identity. + virtual TypeId GetTestCaseTypeId() const = 0; + // UnitTest class invokes this method to register tests in this + // test case right before running them in RUN_ALL_TESTS macro. + // This method should not be called more then once on any single + // instance of a ParameterizedTestCaseInfoBase derived class. + virtual void RegisterTests() = 0; + + protected: + ParameterizedTestCaseInfoBase() {} + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseInfoBase); +}; + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// ParameterizedTestCaseInfo accumulates tests obtained from TEST_P +// macro invocations for a particular test case and generators +// obtained from INSTANTIATE_TEST_CASE_P macro invocations for that +// test case. It registers tests with all values generated by all +// generators when asked. +template +class ParameterizedTestCaseInfo : public ParameterizedTestCaseInfoBase { + public: + // ParamType and GeneratorCreationFunc are private types but are required + // for declarations of public methods AddTestPattern() and + // AddTestCaseInstantiation(). + typedef typename TestCase::ParamType ParamType; + // A function that returns an instance of appropriate generator type. + typedef ParamGenerator(GeneratorCreationFunc)(); + + explicit ParameterizedTestCaseInfo(const char* name) + : test_case_name_(name) {} + + // Test case base name for display purposes. + virtual const String& GetTestCaseName() const { return test_case_name_; } + // Test case id to verify identity. + virtual TypeId GetTestCaseTypeId() const { return GetTypeId(); } + // TEST_P macro uses AddTestPattern() to record information + // about a single test in a LocalTestInfo structure. + // test_case_name is the base name of the test case (without invocation + // prefix). test_base_name is the name of an individual test without + // parameter index. For the test SequenceA/FooTest.DoBar/1 FooTest is + // test case base name and DoBar is test base name. + void AddTestPattern(const char* test_case_name, + const char* test_base_name, + TestMetaFactoryBase* meta_factory) { + tests_.push_back(linked_ptr(new TestInfo(test_case_name, + test_base_name, + meta_factory))); + } + // INSTANTIATE_TEST_CASE_P macro uses AddGenerator() to record information + // about a generator. + int AddTestCaseInstantiation(const char* instantiation_name, + GeneratorCreationFunc* func, + const char* /* file */, + int /* line */) { + instantiations_.push_back(::std::make_pair(instantiation_name, func)); + return 0; // Return value used only to run this method in namespace scope. + } + // UnitTest class invokes this method to register tests in this test case + // test cases right before running tests in RUN_ALL_TESTS macro. + // This method should not be called more then once on any single + // instance of a ParameterizedTestCaseInfoBase derived class. + // UnitTest has a guard to prevent from calling this method more then once. + virtual void RegisterTests() { + for (typename TestInfoContainer::iterator test_it = tests_.begin(); + test_it != tests_.end(); ++test_it) { + linked_ptr test_info = *test_it; + for (typename InstantiationContainer::iterator gen_it = + instantiations_.begin(); gen_it != instantiations_.end(); + ++gen_it) { + const String& instantiation_name = gen_it->first; + ParamGenerator generator((*gen_it->second)()); + + Message test_case_name_stream; + if ( !instantiation_name.empty() ) + test_case_name_stream << instantiation_name.c_str() << "/"; + test_case_name_stream << test_info->test_case_base_name.c_str(); + + int i = 0; + for (typename ParamGenerator::iterator param_it = + generator.begin(); + param_it != generator.end(); ++param_it, ++i) { + Message test_name_stream; + test_name_stream << test_info->test_base_name.c_str() << "/" << i; + ::testing::internal::MakeAndRegisterTestInfo( + test_case_name_stream.GetString().c_str(), + test_name_stream.GetString().c_str(), + "", // test_case_comment + "", // comment; TODO(vladl@google.com): provide parameter value + // representation. + GetTestCaseTypeId(), + TestCase::SetUpTestCase, + TestCase::TearDownTestCase, + test_info->test_meta_factory->CreateTestFactory(*param_it)); + } // for param_it + } // for gen_it + } // for test_it + } // RegisterTests + + private: + // LocalTestInfo structure keeps information about a single test registered + // with TEST_P macro. + struct TestInfo { + TestInfo(const char* a_test_case_base_name, + const char* a_test_base_name, + TestMetaFactoryBase* a_test_meta_factory) : + test_case_base_name(a_test_case_base_name), + test_base_name(a_test_base_name), + test_meta_factory(a_test_meta_factory) {} + + const String test_case_base_name; + const String test_base_name; + const scoped_ptr > test_meta_factory; + }; + typedef ::std::vector > TestInfoContainer; + // Keeps pairs of + // received from INSTANTIATE_TEST_CASE_P macros. + typedef ::std::vector > + InstantiationContainer; + + const String test_case_name_; + TestInfoContainer tests_; + InstantiationContainer instantiations_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseInfo); +}; // class ParameterizedTestCaseInfo + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// ParameterizedTestCaseRegistry contains a map of ParameterizedTestCaseInfoBase +// classes accessed by test case names. TEST_P and INSTANTIATE_TEST_CASE_P +// macros use it to locate their corresponding ParameterizedTestCaseInfo +// descriptors. +class ParameterizedTestCaseRegistry { + public: + ParameterizedTestCaseRegistry() {} + ~ParameterizedTestCaseRegistry() { + for (TestCaseInfoContainer::iterator it = test_case_infos_.begin(); + it != test_case_infos_.end(); ++it) { + delete *it; + } + } + + // Looks up or creates and returns a structure containing information about + // tests and instantiations of a particular test case. + template + ParameterizedTestCaseInfo* GetTestCasePatternHolder( + const char* test_case_name, + const char* file, + int line) { + ParameterizedTestCaseInfo* typed_test_info = NULL; + for (TestCaseInfoContainer::iterator it = test_case_infos_.begin(); + it != test_case_infos_.end(); ++it) { + if ((*it)->GetTestCaseName() == test_case_name) { + if ((*it)->GetTestCaseTypeId() != GetTypeId()) { + // Complain about incorrect usage of Google Test facilities + // and terminate the program since we cannot guaranty correct + // test case setup and tear-down in this case. + ReportInvalidTestCaseType(test_case_name, file, line); + abort(); + } else { + // At this point we are sure that the object we found is of the same + // type we are looking for, so we downcast it to that type + // without further checks. + typed_test_info = CheckedDowncastToActualType< + ParameterizedTestCaseInfo >(*it); + } + break; + } + } + if (typed_test_info == NULL) { + typed_test_info = new ParameterizedTestCaseInfo(test_case_name); + test_case_infos_.push_back(typed_test_info); + } + return typed_test_info; + } + void RegisterTests() { + for (TestCaseInfoContainer::iterator it = test_case_infos_.begin(); + it != test_case_infos_.end(); ++it) { + (*it)->RegisterTests(); + } + } + + private: + typedef ::std::vector TestCaseInfoContainer; + + TestCaseInfoContainer test_case_infos_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseRegistry); +}; + +} // namespace internal +} // namespace testing + +#endif // GTEST_HAS_PARAM_TEST + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_ +// This file was GENERATED by a script. DO NOT EDIT BY HAND!!! + +// Copyright 2008 Google Inc. +// All Rights Reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: vladl@google.com (Vlad Losev) + +// Type and function utilities for implementing parameterized tests. +// This file is generated by a SCRIPT. DO NOT EDIT BY HAND! +// +// Currently Google Test supports at most 50 arguments in Values, +// and at most 10 arguments in Combine. Please contact +// googletestframework@googlegroups.com if you need more. +// Please note that the number of arguments to Combine is limited +// by the maximum arity of the implementation of tr1::tuple which is +// currently set at 10. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_ + +// scripts/fuse_gtest.py depends on gtest's own header being #included +// *unconditionally*. Therefore these #includes cannot be moved +// inside #if GTEST_HAS_PARAM_TEST. + +#if GTEST_HAS_PARAM_TEST + +namespace testing { + +// Forward declarations of ValuesIn(), which is implemented in +// include/gtest/gtest-param-test.h. +template +internal::ParamGenerator< + typename ::std::iterator_traits::value_type> ValuesIn( + ForwardIterator begin, ForwardIterator end); + +template +internal::ParamGenerator ValuesIn(const T (&array)[N]); + +template +internal::ParamGenerator ValuesIn( + const Container& container); + +namespace internal { + +// Used in the Values() function to provide polymorphic capabilities. +template +class ValueArray1 { + public: + explicit ValueArray1(T1 v1) : v1_(v1) {} + + template + operator ParamGenerator() const { return ValuesIn(&v1_, &v1_ + 1); } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray1& other); + + const T1 v1_; +}; + +template +class ValueArray2 { + public: + ValueArray2(T1 v1, T2 v2) : v1_(v1), v2_(v2) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray2& other); + + const T1 v1_; + const T2 v2_; +}; + +template +class ValueArray3 { + public: + ValueArray3(T1 v1, T2 v2, T3 v3) : v1_(v1), v2_(v2), v3_(v3) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray3& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; +}; + +template +class ValueArray4 { + public: + ValueArray4(T1 v1, T2 v2, T3 v3, T4 v4) : v1_(v1), v2_(v2), v3_(v3), + v4_(v4) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray4& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; +}; + +template +class ValueArray5 { + public: + ValueArray5(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5) : v1_(v1), v2_(v2), v3_(v3), + v4_(v4), v5_(v5) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray5& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; +}; + +template +class ValueArray6 { + public: + ValueArray6(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6) : v1_(v1), v2_(v2), + v3_(v3), v4_(v4), v5_(v5), v6_(v6) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray6& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; +}; + +template +class ValueArray7 { + public: + ValueArray7(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7) : v1_(v1), + v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray7& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; +}; + +template +class ValueArray8 { + public: + ValueArray8(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, + T8 v8) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray8& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; +}; + +template +class ValueArray9 { + public: + ValueArray9(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, + T9 v9) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray9& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; +}; + +template +class ValueArray10 { + public: + ValueArray10(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray10& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; +}; + +template +class ValueArray11 { + public: + ValueArray11(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), + v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray11& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; +}; + +template +class ValueArray12 { + public: + ValueArray12(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), + v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray12& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; +}; + +template +class ValueArray13 { + public: + ValueArray13(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), + v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), + v12_(v12), v13_(v13) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray13& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; +}; + +template +class ValueArray14 { + public: + ValueArray14(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14) : v1_(v1), v2_(v2), v3_(v3), + v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), + v11_(v11), v12_(v12), v13_(v13), v14_(v14) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray14& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; +}; + +template +class ValueArray15 { + public: + ValueArray15(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15) : v1_(v1), v2_(v2), + v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), + v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray15& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; +}; + +template +class ValueArray16 { + public: + ValueArray16(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16) : v1_(v1), + v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), + v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), + v16_(v16) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray16& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; +}; + +template +class ValueArray17 { + public: + ValueArray17(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, + T17 v17) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), + v15_(v15), v16_(v16), v17_(v17) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray17& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; +}; + +template +class ValueArray18 { + public: + ValueArray18(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), + v15_(v15), v16_(v16), v17_(v17), v18_(v18) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray18& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; +}; + +template +class ValueArray19 { + public: + ValueArray19(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), + v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), + v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray19& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; +}; + +template +class ValueArray20 { + public: + ValueArray20(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), + v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), + v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), + v19_(v19), v20_(v20) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray20& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; +}; + +template +class ValueArray21 { + public: + ValueArray21(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), + v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), + v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), + v18_(v18), v19_(v19), v20_(v20), v21_(v21) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray21& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; +}; + +template +class ValueArray22 { + public: + ValueArray22(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22) : v1_(v1), v2_(v2), v3_(v3), + v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), + v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), + v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray22& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; +}; + +template +class ValueArray23 { + public: + ValueArray23(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23) : v1_(v1), v2_(v2), + v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), + v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), + v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), + v23_(v23) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, + v23_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray23& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; +}; + +template +class ValueArray24 { + public: + ValueArray24(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24) : v1_(v1), + v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), + v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), + v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), + v22_(v22), v23_(v23), v24_(v24) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray24& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; +}; + +template +class ValueArray25 { + public: + ValueArray25(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, + T25 v25) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), + v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), + v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray25& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; +}; + +template +class ValueArray26 { + public: + ValueArray26(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), + v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), + v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray26& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; +}; + +template +class ValueArray27 { + public: + ValueArray27(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), + v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), + v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), + v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), + v26_(v26), v27_(v27) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray27& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; +}; + +template +class ValueArray28 { + public: + ValueArray28(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), + v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), + v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), + v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), + v25_(v25), v26_(v26), v27_(v27), v28_(v28) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray28& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; +}; + +template +class ValueArray29 { + public: + ValueArray29(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), + v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), + v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), + v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), + v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray29& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; +}; + +template +class ValueArray30 { + public: + ValueArray30(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30) : v1_(v1), v2_(v2), v3_(v3), + v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), + v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), + v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), + v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), + v29_(v29), v30_(v30) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_, v30_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray30& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; +}; + +template +class ValueArray31 { + public: + ValueArray31(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31) : v1_(v1), v2_(v2), + v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), + v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), + v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), + v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), + v29_(v29), v30_(v30), v31_(v31) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray31& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; +}; + +template +class ValueArray32 { + public: + ValueArray32(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32) : v1_(v1), + v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), + v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), + v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), + v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), + v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray32& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; +}; + +template +class ValueArray33 { + public: + ValueArray33(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, + T33 v33) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), + v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), + v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), + v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), + v33_(v33) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray33& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; +}; + +template +class ValueArray34 { + public: + ValueArray34(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), + v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), + v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), + v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), + v33_(v33), v34_(v34) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray34& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; +}; + +template +class ValueArray35 { + public: + ValueArray35(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), + v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), + v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), + v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), + v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), + v32_(v32), v33_(v33), v34_(v34), v35_(v35) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, + v35_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray35& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; +}; + +template +class ValueArray36 { + public: + ValueArray36(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), + v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), + v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), + v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), + v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), + v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, + v36_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray36& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; +}; + +template +class ValueArray37 { + public: + ValueArray37(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), + v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), + v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), + v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), + v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), + v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), + v36_(v36), v37_(v37) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, + v36_, v37_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray37& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; +}; + +template +class ValueArray38 { + public: + ValueArray38(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38) : v1_(v1), v2_(v2), v3_(v3), + v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), + v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), + v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), + v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), + v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), + v35_(v35), v36_(v36), v37_(v37), v38_(v38) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, + v36_, v37_, v38_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray38& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; +}; + +template +class ValueArray39 { + public: + ValueArray39(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39) : v1_(v1), v2_(v2), + v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), + v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), + v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), + v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), + v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), + v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, + v36_, v37_, v38_, v39_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray39& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; +}; + +template +class ValueArray40 { + public: + ValueArray40(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40) : v1_(v1), + v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), + v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), + v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), + v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), + v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), + v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), + v40_(v40) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, + v36_, v37_, v38_, v39_, v40_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray40& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; +}; + +template +class ValueArray41 { + public: + ValueArray41(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, + T41 v41) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), + v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), + v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), + v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), + v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), + v39_(v39), v40_(v40), v41_(v41) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, + v36_, v37_, v38_, v39_, v40_, v41_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray41& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; +}; + +template +class ValueArray42 { + public: + ValueArray42(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), + v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), + v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), + v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), + v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), + v39_(v39), v40_(v40), v41_(v41), v42_(v42) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, + v36_, v37_, v38_, v39_, v40_, v41_, v42_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray42& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; + const T42 v42_; +}; + +template +class ValueArray43 { + public: + ValueArray43(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), + v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), + v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), + v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), + v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), + v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), + v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, + v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray43& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; + const T42 v42_; + const T43 v43_; +}; + +template +class ValueArray44 { + public: + ValueArray44(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43, T44 v44) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), + v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), + v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), + v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), + v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), + v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), + v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42), + v43_(v43), v44_(v44) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, + v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray44& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; + const T42 v42_; + const T43 v43_; + const T44 v44_; +}; + +template +class ValueArray45 { + public: + ValueArray45(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43, T44 v44, T45 v45) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), + v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), + v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), + v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), + v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), + v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), + v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41), + v42_(v42), v43_(v43), v44_(v44), v45_(v45) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, + v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_, v45_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray45& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; + const T42 v42_; + const T43 v43_; + const T44 v44_; + const T45 v45_; +}; + +template +class ValueArray46 { + public: + ValueArray46(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43, T44 v44, T45 v45, T46 v46) : v1_(v1), v2_(v2), v3_(v3), + v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), + v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), + v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), + v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), + v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), + v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), + v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45), v46_(v46) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, + v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_, v45_, v46_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray46& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; + const T42 v42_; + const T43 v43_; + const T44 v44_; + const T45 v45_; + const T46 v46_; +}; + +template +class ValueArray47 { + public: + ValueArray47(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47) : v1_(v1), v2_(v2), + v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), + v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), + v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), + v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), + v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), + v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), + v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45), v46_(v46), + v47_(v47) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, + v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_, v45_, v46_, + v47_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray47& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; + const T42 v42_; + const T43 v43_; + const T44 v44_; + const T45 v45_; + const T46 v46_; + const T47 v47_; +}; + +template +class ValueArray48 { + public: + ValueArray48(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48) : v1_(v1), + v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), + v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), + v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), + v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), + v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), + v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), + v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45), + v46_(v46), v47_(v47), v48_(v48) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, + v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_, v45_, v46_, v47_, + v48_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray48& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; + const T42 v42_; + const T43 v43_; + const T44 v44_; + const T45 v45_; + const T46 v46_; + const T47 v47_; + const T48 v48_; +}; + +template +class ValueArray49 { + public: + ValueArray49(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48, + T49 v49) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), + v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), + v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), + v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), + v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), + v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44), + v45_(v45), v46_(v46), v47_(v47), v48_(v48), v49_(v49) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, + v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_, v45_, v46_, v47_, + v48_, v49_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray49& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; + const T42 v42_; + const T43 v43_; + const T44 v44_; + const T45 v45_; + const T46 v46_; + const T47 v47_; + const T48 v48_; + const T49 v49_; +}; + +template +class ValueArray50 { + public: + ValueArray50(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48, T49 v49, + T50 v50) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), + v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), + v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), + v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), + v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), + v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44), + v45_(v45), v46_(v46), v47_(v47), v48_(v48), v49_(v49), v50_(v50) {} + + template + operator ParamGenerator() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, + v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_, v45_, v46_, v47_, + v48_, v49_, v50_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray50& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; + const T42 v42_; + const T43 v43_; + const T44 v44_; + const T45 v45_; + const T46 v46_; + const T47 v47_; + const T48 v48_; + const T49 v49_; + const T50 v50_; +}; + +#if GTEST_HAS_COMBINE +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// Generates values from the Cartesian product of values produced +// by the argument generators. +// +template +class CartesianProductGenerator2 + : public ParamGeneratorInterface< ::std::tr1::tuple > { + public: + typedef ::std::tr1::tuple ParamType; + + CartesianProductGenerator2(const ParamGenerator& g1, + const ParamGenerator& g2) + : g1_(g1), g2_(g2) {} + virtual ~CartesianProductGenerator2() {} + + virtual ParamIteratorInterface* Begin() const { + return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin()); + } + virtual ParamIteratorInterface* End() const { + return new Iterator(this, g1_, g1_.end(), g2_, g2_.end()); + } + + private: + class Iterator : public ParamIteratorInterface { + public: + Iterator(const ParamGeneratorInterface* base, + const ParamGenerator& g1, + const typename ParamGenerator::iterator& current1, + const ParamGenerator& g2, + const typename ParamGenerator::iterator& current2) + : base_(base), + begin1_(g1.begin()), end1_(g1.end()), current1_(current1), + begin2_(g2.begin()), end2_(g2.end()), current2_(current2) { + ComputeCurrentValue(); + } + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface* BaseGenerator() const { + return base_; + } + // Advance should not be called on beyond-of-range iterators + // so no component iterators must be beyond end of range, either. + virtual void Advance() { + assert(!AtEnd()); + ++current2_; + if (current2_ == end2_) { + current2_ = begin2_; + ++current1_; + } + ComputeCurrentValue(); + } + virtual ParamIteratorInterface* Clone() const { + return new Iterator(*this); + } + virtual const ParamType* Current() const { return ¤t_value_; } + virtual bool Equals(const ParamIteratorInterface& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const Iterator* typed_other = + CheckedDowncastToActualType(&other); + // We must report iterators equal if they both point beyond their + // respective ranges. That can happen in a variety of fashions, + // so we have to consult AtEnd(). + return (AtEnd() && typed_other->AtEnd()) || + ( + current1_ == typed_other->current1_ && + current2_ == typed_other->current2_); + } + + private: + Iterator(const Iterator& other) + : base_(other.base_), + begin1_(other.begin1_), + end1_(other.end1_), + current1_(other.current1_), + begin2_(other.begin2_), + end2_(other.end2_), + current2_(other.current2_) { + ComputeCurrentValue(); + } + + void ComputeCurrentValue() { + if (!AtEnd()) + current_value_ = ParamType(*current1_, *current2_); + } + bool AtEnd() const { + // We must report iterator past the end of the range when either of the + // component iterators has reached the end of its range. + return + current1_ == end1_ || + current2_ == end2_; + } + + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + + const ParamGeneratorInterface* const base_; + // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. + // current[i]_ is the actual traversing iterator. + const typename ParamGenerator::iterator begin1_; + const typename ParamGenerator::iterator end1_; + typename ParamGenerator::iterator current1_; + const typename ParamGenerator::iterator begin2_; + const typename ParamGenerator::iterator end2_; + typename ParamGenerator::iterator current2_; + ParamType current_value_; + }; // class CartesianProductGenerator2::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator2& other); + + const ParamGenerator g1_; + const ParamGenerator g2_; +}; // class CartesianProductGenerator2 + + +template +class CartesianProductGenerator3 + : public ParamGeneratorInterface< ::std::tr1::tuple > { + public: + typedef ::std::tr1::tuple ParamType; + + CartesianProductGenerator3(const ParamGenerator& g1, + const ParamGenerator& g2, const ParamGenerator& g3) + : g1_(g1), g2_(g2), g3_(g3) {} + virtual ~CartesianProductGenerator3() {} + + virtual ParamIteratorInterface* Begin() const { + return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, + g3_.begin()); + } + virtual ParamIteratorInterface* End() const { + return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end()); + } + + private: + class Iterator : public ParamIteratorInterface { + public: + Iterator(const ParamGeneratorInterface* base, + const ParamGenerator& g1, + const typename ParamGenerator::iterator& current1, + const ParamGenerator& g2, + const typename ParamGenerator::iterator& current2, + const ParamGenerator& g3, + const typename ParamGenerator::iterator& current3) + : base_(base), + begin1_(g1.begin()), end1_(g1.end()), current1_(current1), + begin2_(g2.begin()), end2_(g2.end()), current2_(current2), + begin3_(g3.begin()), end3_(g3.end()), current3_(current3) { + ComputeCurrentValue(); + } + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface* BaseGenerator() const { + return base_; + } + // Advance should not be called on beyond-of-range iterators + // so no component iterators must be beyond end of range, either. + virtual void Advance() { + assert(!AtEnd()); + ++current3_; + if (current3_ == end3_) { + current3_ = begin3_; + ++current2_; + } + if (current2_ == end2_) { + current2_ = begin2_; + ++current1_; + } + ComputeCurrentValue(); + } + virtual ParamIteratorInterface* Clone() const { + return new Iterator(*this); + } + virtual const ParamType* Current() const { return ¤t_value_; } + virtual bool Equals(const ParamIteratorInterface& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const Iterator* typed_other = + CheckedDowncastToActualType(&other); + // We must report iterators equal if they both point beyond their + // respective ranges. That can happen in a variety of fashions, + // so we have to consult AtEnd(). + return (AtEnd() && typed_other->AtEnd()) || + ( + current1_ == typed_other->current1_ && + current2_ == typed_other->current2_ && + current3_ == typed_other->current3_); + } + + private: + Iterator(const Iterator& other) + : base_(other.base_), + begin1_(other.begin1_), + end1_(other.end1_), + current1_(other.current1_), + begin2_(other.begin2_), + end2_(other.end2_), + current2_(other.current2_), + begin3_(other.begin3_), + end3_(other.end3_), + current3_(other.current3_) { + ComputeCurrentValue(); + } + + void ComputeCurrentValue() { + if (!AtEnd()) + current_value_ = ParamType(*current1_, *current2_, *current3_); + } + bool AtEnd() const { + // We must report iterator past the end of the range when either of the + // component iterators has reached the end of its range. + return + current1_ == end1_ || + current2_ == end2_ || + current3_ == end3_; + } + + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + + const ParamGeneratorInterface* const base_; + // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. + // current[i]_ is the actual traversing iterator. + const typename ParamGenerator::iterator begin1_; + const typename ParamGenerator::iterator end1_; + typename ParamGenerator::iterator current1_; + const typename ParamGenerator::iterator begin2_; + const typename ParamGenerator::iterator end2_; + typename ParamGenerator::iterator current2_; + const typename ParamGenerator::iterator begin3_; + const typename ParamGenerator::iterator end3_; + typename ParamGenerator::iterator current3_; + ParamType current_value_; + }; // class CartesianProductGenerator3::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator3& other); + + const ParamGenerator g1_; + const ParamGenerator g2_; + const ParamGenerator g3_; +}; // class CartesianProductGenerator3 + + +template +class CartesianProductGenerator4 + : public ParamGeneratorInterface< ::std::tr1::tuple > { + public: + typedef ::std::tr1::tuple ParamType; + + CartesianProductGenerator4(const ParamGenerator& g1, + const ParamGenerator& g2, const ParamGenerator& g3, + const ParamGenerator& g4) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4) {} + virtual ~CartesianProductGenerator4() {} + + virtual ParamIteratorInterface* Begin() const { + return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, + g3_.begin(), g4_, g4_.begin()); + } + virtual ParamIteratorInterface* End() const { + return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), + g4_, g4_.end()); + } + + private: + class Iterator : public ParamIteratorInterface { + public: + Iterator(const ParamGeneratorInterface* base, + const ParamGenerator& g1, + const typename ParamGenerator::iterator& current1, + const ParamGenerator& g2, + const typename ParamGenerator::iterator& current2, + const ParamGenerator& g3, + const typename ParamGenerator::iterator& current3, + const ParamGenerator& g4, + const typename ParamGenerator::iterator& current4) + : base_(base), + begin1_(g1.begin()), end1_(g1.end()), current1_(current1), + begin2_(g2.begin()), end2_(g2.end()), current2_(current2), + begin3_(g3.begin()), end3_(g3.end()), current3_(current3), + begin4_(g4.begin()), end4_(g4.end()), current4_(current4) { + ComputeCurrentValue(); + } + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface* BaseGenerator() const { + return base_; + } + // Advance should not be called on beyond-of-range iterators + // so no component iterators must be beyond end of range, either. + virtual void Advance() { + assert(!AtEnd()); + ++current4_; + if (current4_ == end4_) { + current4_ = begin4_; + ++current3_; + } + if (current3_ == end3_) { + current3_ = begin3_; + ++current2_; + } + if (current2_ == end2_) { + current2_ = begin2_; + ++current1_; + } + ComputeCurrentValue(); + } + virtual ParamIteratorInterface* Clone() const { + return new Iterator(*this); + } + virtual const ParamType* Current() const { return ¤t_value_; } + virtual bool Equals(const ParamIteratorInterface& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const Iterator* typed_other = + CheckedDowncastToActualType(&other); + // We must report iterators equal if they both point beyond their + // respective ranges. That can happen in a variety of fashions, + // so we have to consult AtEnd(). + return (AtEnd() && typed_other->AtEnd()) || + ( + current1_ == typed_other->current1_ && + current2_ == typed_other->current2_ && + current3_ == typed_other->current3_ && + current4_ == typed_other->current4_); + } + + private: + Iterator(const Iterator& other) + : base_(other.base_), + begin1_(other.begin1_), + end1_(other.end1_), + current1_(other.current1_), + begin2_(other.begin2_), + end2_(other.end2_), + current2_(other.current2_), + begin3_(other.begin3_), + end3_(other.end3_), + current3_(other.current3_), + begin4_(other.begin4_), + end4_(other.end4_), + current4_(other.current4_) { + ComputeCurrentValue(); + } + + void ComputeCurrentValue() { + if (!AtEnd()) + current_value_ = ParamType(*current1_, *current2_, *current3_, + *current4_); + } + bool AtEnd() const { + // We must report iterator past the end of the range when either of the + // component iterators has reached the end of its range. + return + current1_ == end1_ || + current2_ == end2_ || + current3_ == end3_ || + current4_ == end4_; + } + + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + + const ParamGeneratorInterface* const base_; + // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. + // current[i]_ is the actual traversing iterator. + const typename ParamGenerator::iterator begin1_; + const typename ParamGenerator::iterator end1_; + typename ParamGenerator::iterator current1_; + const typename ParamGenerator::iterator begin2_; + const typename ParamGenerator::iterator end2_; + typename ParamGenerator::iterator current2_; + const typename ParamGenerator::iterator begin3_; + const typename ParamGenerator::iterator end3_; + typename ParamGenerator::iterator current3_; + const typename ParamGenerator::iterator begin4_; + const typename ParamGenerator::iterator end4_; + typename ParamGenerator::iterator current4_; + ParamType current_value_; + }; // class CartesianProductGenerator4::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator4& other); + + const ParamGenerator g1_; + const ParamGenerator g2_; + const ParamGenerator g3_; + const ParamGenerator g4_; +}; // class CartesianProductGenerator4 + + +template +class CartesianProductGenerator5 + : public ParamGeneratorInterface< ::std::tr1::tuple > { + public: + typedef ::std::tr1::tuple ParamType; + + CartesianProductGenerator5(const ParamGenerator& g1, + const ParamGenerator& g2, const ParamGenerator& g3, + const ParamGenerator& g4, const ParamGenerator& g5) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5) {} + virtual ~CartesianProductGenerator5() {} + + virtual ParamIteratorInterface* Begin() const { + return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, + g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin()); + } + virtual ParamIteratorInterface* End() const { + return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), + g4_, g4_.end(), g5_, g5_.end()); + } + + private: + class Iterator : public ParamIteratorInterface { + public: + Iterator(const ParamGeneratorInterface* base, + const ParamGenerator& g1, + const typename ParamGenerator::iterator& current1, + const ParamGenerator& g2, + const typename ParamGenerator::iterator& current2, + const ParamGenerator& g3, + const typename ParamGenerator::iterator& current3, + const ParamGenerator& g4, + const typename ParamGenerator::iterator& current4, + const ParamGenerator& g5, + const typename ParamGenerator::iterator& current5) + : base_(base), + begin1_(g1.begin()), end1_(g1.end()), current1_(current1), + begin2_(g2.begin()), end2_(g2.end()), current2_(current2), + begin3_(g3.begin()), end3_(g3.end()), current3_(current3), + begin4_(g4.begin()), end4_(g4.end()), current4_(current4), + begin5_(g5.begin()), end5_(g5.end()), current5_(current5) { + ComputeCurrentValue(); + } + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface* BaseGenerator() const { + return base_; + } + // Advance should not be called on beyond-of-range iterators + // so no component iterators must be beyond end of range, either. + virtual void Advance() { + assert(!AtEnd()); + ++current5_; + if (current5_ == end5_) { + current5_ = begin5_; + ++current4_; + } + if (current4_ == end4_) { + current4_ = begin4_; + ++current3_; + } + if (current3_ == end3_) { + current3_ = begin3_; + ++current2_; + } + if (current2_ == end2_) { + current2_ = begin2_; + ++current1_; + } + ComputeCurrentValue(); + } + virtual ParamIteratorInterface* Clone() const { + return new Iterator(*this); + } + virtual const ParamType* Current() const { return ¤t_value_; } + virtual bool Equals(const ParamIteratorInterface& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const Iterator* typed_other = + CheckedDowncastToActualType(&other); + // We must report iterators equal if they both point beyond their + // respective ranges. That can happen in a variety of fashions, + // so we have to consult AtEnd(). + return (AtEnd() && typed_other->AtEnd()) || + ( + current1_ == typed_other->current1_ && + current2_ == typed_other->current2_ && + current3_ == typed_other->current3_ && + current4_ == typed_other->current4_ && + current5_ == typed_other->current5_); + } + + private: + Iterator(const Iterator& other) + : base_(other.base_), + begin1_(other.begin1_), + end1_(other.end1_), + current1_(other.current1_), + begin2_(other.begin2_), + end2_(other.end2_), + current2_(other.current2_), + begin3_(other.begin3_), + end3_(other.end3_), + current3_(other.current3_), + begin4_(other.begin4_), + end4_(other.end4_), + current4_(other.current4_), + begin5_(other.begin5_), + end5_(other.end5_), + current5_(other.current5_) { + ComputeCurrentValue(); + } + + void ComputeCurrentValue() { + if (!AtEnd()) + current_value_ = ParamType(*current1_, *current2_, *current3_, + *current4_, *current5_); + } + bool AtEnd() const { + // We must report iterator past the end of the range when either of the + // component iterators has reached the end of its range. + return + current1_ == end1_ || + current2_ == end2_ || + current3_ == end3_ || + current4_ == end4_ || + current5_ == end5_; + } + + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + + const ParamGeneratorInterface* const base_; + // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. + // current[i]_ is the actual traversing iterator. + const typename ParamGenerator::iterator begin1_; + const typename ParamGenerator::iterator end1_; + typename ParamGenerator::iterator current1_; + const typename ParamGenerator::iterator begin2_; + const typename ParamGenerator::iterator end2_; + typename ParamGenerator::iterator current2_; + const typename ParamGenerator::iterator begin3_; + const typename ParamGenerator::iterator end3_; + typename ParamGenerator::iterator current3_; + const typename ParamGenerator::iterator begin4_; + const typename ParamGenerator::iterator end4_; + typename ParamGenerator::iterator current4_; + const typename ParamGenerator::iterator begin5_; + const typename ParamGenerator::iterator end5_; + typename ParamGenerator::iterator current5_; + ParamType current_value_; + }; // class CartesianProductGenerator5::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator5& other); + + const ParamGenerator g1_; + const ParamGenerator g2_; + const ParamGenerator g3_; + const ParamGenerator g4_; + const ParamGenerator g5_; +}; // class CartesianProductGenerator5 + + +template +class CartesianProductGenerator6 + : public ParamGeneratorInterface< ::std::tr1::tuple > { + public: + typedef ::std::tr1::tuple ParamType; + + CartesianProductGenerator6(const ParamGenerator& g1, + const ParamGenerator& g2, const ParamGenerator& g3, + const ParamGenerator& g4, const ParamGenerator& g5, + const ParamGenerator& g6) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6) {} + virtual ~CartesianProductGenerator6() {} + + virtual ParamIteratorInterface* Begin() const { + return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, + g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin()); + } + virtual ParamIteratorInterface* End() const { + return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), + g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end()); + } + + private: + class Iterator : public ParamIteratorInterface { + public: + Iterator(const ParamGeneratorInterface* base, + const ParamGenerator& g1, + const typename ParamGenerator::iterator& current1, + const ParamGenerator& g2, + const typename ParamGenerator::iterator& current2, + const ParamGenerator& g3, + const typename ParamGenerator::iterator& current3, + const ParamGenerator& g4, + const typename ParamGenerator::iterator& current4, + const ParamGenerator& g5, + const typename ParamGenerator::iterator& current5, + const ParamGenerator& g6, + const typename ParamGenerator::iterator& current6) + : base_(base), + begin1_(g1.begin()), end1_(g1.end()), current1_(current1), + begin2_(g2.begin()), end2_(g2.end()), current2_(current2), + begin3_(g3.begin()), end3_(g3.end()), current3_(current3), + begin4_(g4.begin()), end4_(g4.end()), current4_(current4), + begin5_(g5.begin()), end5_(g5.end()), current5_(current5), + begin6_(g6.begin()), end6_(g6.end()), current6_(current6) { + ComputeCurrentValue(); + } + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface* BaseGenerator() const { + return base_; + } + // Advance should not be called on beyond-of-range iterators + // so no component iterators must be beyond end of range, either. + virtual void Advance() { + assert(!AtEnd()); + ++current6_; + if (current6_ == end6_) { + current6_ = begin6_; + ++current5_; + } + if (current5_ == end5_) { + current5_ = begin5_; + ++current4_; + } + if (current4_ == end4_) { + current4_ = begin4_; + ++current3_; + } + if (current3_ == end3_) { + current3_ = begin3_; + ++current2_; + } + if (current2_ == end2_) { + current2_ = begin2_; + ++current1_; + } + ComputeCurrentValue(); + } + virtual ParamIteratorInterface* Clone() const { + return new Iterator(*this); + } + virtual const ParamType* Current() const { return ¤t_value_; } + virtual bool Equals(const ParamIteratorInterface& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const Iterator* typed_other = + CheckedDowncastToActualType(&other); + // We must report iterators equal if they both point beyond their + // respective ranges. That can happen in a variety of fashions, + // so we have to consult AtEnd(). + return (AtEnd() && typed_other->AtEnd()) || + ( + current1_ == typed_other->current1_ && + current2_ == typed_other->current2_ && + current3_ == typed_other->current3_ && + current4_ == typed_other->current4_ && + current5_ == typed_other->current5_ && + current6_ == typed_other->current6_); + } + + private: + Iterator(const Iterator& other) + : base_(other.base_), + begin1_(other.begin1_), + end1_(other.end1_), + current1_(other.current1_), + begin2_(other.begin2_), + end2_(other.end2_), + current2_(other.current2_), + begin3_(other.begin3_), + end3_(other.end3_), + current3_(other.current3_), + begin4_(other.begin4_), + end4_(other.end4_), + current4_(other.current4_), + begin5_(other.begin5_), + end5_(other.end5_), + current5_(other.current5_), + begin6_(other.begin6_), + end6_(other.end6_), + current6_(other.current6_) { + ComputeCurrentValue(); + } + + void ComputeCurrentValue() { + if (!AtEnd()) + current_value_ = ParamType(*current1_, *current2_, *current3_, + *current4_, *current5_, *current6_); + } + bool AtEnd() const { + // We must report iterator past the end of the range when either of the + // component iterators has reached the end of its range. + return + current1_ == end1_ || + current2_ == end2_ || + current3_ == end3_ || + current4_ == end4_ || + current5_ == end5_ || + current6_ == end6_; + } + + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + + const ParamGeneratorInterface* const base_; + // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. + // current[i]_ is the actual traversing iterator. + const typename ParamGenerator::iterator begin1_; + const typename ParamGenerator::iterator end1_; + typename ParamGenerator::iterator current1_; + const typename ParamGenerator::iterator begin2_; + const typename ParamGenerator::iterator end2_; + typename ParamGenerator::iterator current2_; + const typename ParamGenerator::iterator begin3_; + const typename ParamGenerator::iterator end3_; + typename ParamGenerator::iterator current3_; + const typename ParamGenerator::iterator begin4_; + const typename ParamGenerator::iterator end4_; + typename ParamGenerator::iterator current4_; + const typename ParamGenerator::iterator begin5_; + const typename ParamGenerator::iterator end5_; + typename ParamGenerator::iterator current5_; + const typename ParamGenerator::iterator begin6_; + const typename ParamGenerator::iterator end6_; + typename ParamGenerator::iterator current6_; + ParamType current_value_; + }; // class CartesianProductGenerator6::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator6& other); + + const ParamGenerator g1_; + const ParamGenerator g2_; + const ParamGenerator g3_; + const ParamGenerator g4_; + const ParamGenerator g5_; + const ParamGenerator g6_; +}; // class CartesianProductGenerator6 + + +template +class CartesianProductGenerator7 + : public ParamGeneratorInterface< ::std::tr1::tuple > { + public: + typedef ::std::tr1::tuple ParamType; + + CartesianProductGenerator7(const ParamGenerator& g1, + const ParamGenerator& g2, const ParamGenerator& g3, + const ParamGenerator& g4, const ParamGenerator& g5, + const ParamGenerator& g6, const ParamGenerator& g7) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7) {} + virtual ~CartesianProductGenerator7() {} + + virtual ParamIteratorInterface* Begin() const { + return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, + g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_, + g7_.begin()); + } + virtual ParamIteratorInterface* End() const { + return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), + g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end()); + } + + private: + class Iterator : public ParamIteratorInterface { + public: + Iterator(const ParamGeneratorInterface* base, + const ParamGenerator& g1, + const typename ParamGenerator::iterator& current1, + const ParamGenerator& g2, + const typename ParamGenerator::iterator& current2, + const ParamGenerator& g3, + const typename ParamGenerator::iterator& current3, + const ParamGenerator& g4, + const typename ParamGenerator::iterator& current4, + const ParamGenerator& g5, + const typename ParamGenerator::iterator& current5, + const ParamGenerator& g6, + const typename ParamGenerator::iterator& current6, + const ParamGenerator& g7, + const typename ParamGenerator::iterator& current7) + : base_(base), + begin1_(g1.begin()), end1_(g1.end()), current1_(current1), + begin2_(g2.begin()), end2_(g2.end()), current2_(current2), + begin3_(g3.begin()), end3_(g3.end()), current3_(current3), + begin4_(g4.begin()), end4_(g4.end()), current4_(current4), + begin5_(g5.begin()), end5_(g5.end()), current5_(current5), + begin6_(g6.begin()), end6_(g6.end()), current6_(current6), + begin7_(g7.begin()), end7_(g7.end()), current7_(current7) { + ComputeCurrentValue(); + } + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface* BaseGenerator() const { + return base_; + } + // Advance should not be called on beyond-of-range iterators + // so no component iterators must be beyond end of range, either. + virtual void Advance() { + assert(!AtEnd()); + ++current7_; + if (current7_ == end7_) { + current7_ = begin7_; + ++current6_; + } + if (current6_ == end6_) { + current6_ = begin6_; + ++current5_; + } + if (current5_ == end5_) { + current5_ = begin5_; + ++current4_; + } + if (current4_ == end4_) { + current4_ = begin4_; + ++current3_; + } + if (current3_ == end3_) { + current3_ = begin3_; + ++current2_; + } + if (current2_ == end2_) { + current2_ = begin2_; + ++current1_; + } + ComputeCurrentValue(); + } + virtual ParamIteratorInterface* Clone() const { + return new Iterator(*this); + } + virtual const ParamType* Current() const { return ¤t_value_; } + virtual bool Equals(const ParamIteratorInterface& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const Iterator* typed_other = + CheckedDowncastToActualType(&other); + // We must report iterators equal if they both point beyond their + // respective ranges. That can happen in a variety of fashions, + // so we have to consult AtEnd(). + return (AtEnd() && typed_other->AtEnd()) || + ( + current1_ == typed_other->current1_ && + current2_ == typed_other->current2_ && + current3_ == typed_other->current3_ && + current4_ == typed_other->current4_ && + current5_ == typed_other->current5_ && + current6_ == typed_other->current6_ && + current7_ == typed_other->current7_); + } + + private: + Iterator(const Iterator& other) + : base_(other.base_), + begin1_(other.begin1_), + end1_(other.end1_), + current1_(other.current1_), + begin2_(other.begin2_), + end2_(other.end2_), + current2_(other.current2_), + begin3_(other.begin3_), + end3_(other.end3_), + current3_(other.current3_), + begin4_(other.begin4_), + end4_(other.end4_), + current4_(other.current4_), + begin5_(other.begin5_), + end5_(other.end5_), + current5_(other.current5_), + begin6_(other.begin6_), + end6_(other.end6_), + current6_(other.current6_), + begin7_(other.begin7_), + end7_(other.end7_), + current7_(other.current7_) { + ComputeCurrentValue(); + } + + void ComputeCurrentValue() { + if (!AtEnd()) + current_value_ = ParamType(*current1_, *current2_, *current3_, + *current4_, *current5_, *current6_, *current7_); + } + bool AtEnd() const { + // We must report iterator past the end of the range when either of the + // component iterators has reached the end of its range. + return + current1_ == end1_ || + current2_ == end2_ || + current3_ == end3_ || + current4_ == end4_ || + current5_ == end5_ || + current6_ == end6_ || + current7_ == end7_; + } + + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + + const ParamGeneratorInterface* const base_; + // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. + // current[i]_ is the actual traversing iterator. + const typename ParamGenerator::iterator begin1_; + const typename ParamGenerator::iterator end1_; + typename ParamGenerator::iterator current1_; + const typename ParamGenerator::iterator begin2_; + const typename ParamGenerator::iterator end2_; + typename ParamGenerator::iterator current2_; + const typename ParamGenerator::iterator begin3_; + const typename ParamGenerator::iterator end3_; + typename ParamGenerator::iterator current3_; + const typename ParamGenerator::iterator begin4_; + const typename ParamGenerator::iterator end4_; + typename ParamGenerator::iterator current4_; + const typename ParamGenerator::iterator begin5_; + const typename ParamGenerator::iterator end5_; + typename ParamGenerator::iterator current5_; + const typename ParamGenerator::iterator begin6_; + const typename ParamGenerator::iterator end6_; + typename ParamGenerator::iterator current6_; + const typename ParamGenerator::iterator begin7_; + const typename ParamGenerator::iterator end7_; + typename ParamGenerator::iterator current7_; + ParamType current_value_; + }; // class CartesianProductGenerator7::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator7& other); + + const ParamGenerator g1_; + const ParamGenerator g2_; + const ParamGenerator g3_; + const ParamGenerator g4_; + const ParamGenerator g5_; + const ParamGenerator g6_; + const ParamGenerator g7_; +}; // class CartesianProductGenerator7 + + +template +class CartesianProductGenerator8 + : public ParamGeneratorInterface< ::std::tr1::tuple > { + public: + typedef ::std::tr1::tuple ParamType; + + CartesianProductGenerator8(const ParamGenerator& g1, + const ParamGenerator& g2, const ParamGenerator& g3, + const ParamGenerator& g4, const ParamGenerator& g5, + const ParamGenerator& g6, const ParamGenerator& g7, + const ParamGenerator& g8) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), + g8_(g8) {} + virtual ~CartesianProductGenerator8() {} + + virtual ParamIteratorInterface* Begin() const { + return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, + g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_, + g7_.begin(), g8_, g8_.begin()); + } + virtual ParamIteratorInterface* End() const { + return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), + g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end(), g8_, + g8_.end()); + } + + private: + class Iterator : public ParamIteratorInterface { + public: + Iterator(const ParamGeneratorInterface* base, + const ParamGenerator& g1, + const typename ParamGenerator::iterator& current1, + const ParamGenerator& g2, + const typename ParamGenerator::iterator& current2, + const ParamGenerator& g3, + const typename ParamGenerator::iterator& current3, + const ParamGenerator& g4, + const typename ParamGenerator::iterator& current4, + const ParamGenerator& g5, + const typename ParamGenerator::iterator& current5, + const ParamGenerator& g6, + const typename ParamGenerator::iterator& current6, + const ParamGenerator& g7, + const typename ParamGenerator::iterator& current7, + const ParamGenerator& g8, + const typename ParamGenerator::iterator& current8) + : base_(base), + begin1_(g1.begin()), end1_(g1.end()), current1_(current1), + begin2_(g2.begin()), end2_(g2.end()), current2_(current2), + begin3_(g3.begin()), end3_(g3.end()), current3_(current3), + begin4_(g4.begin()), end4_(g4.end()), current4_(current4), + begin5_(g5.begin()), end5_(g5.end()), current5_(current5), + begin6_(g6.begin()), end6_(g6.end()), current6_(current6), + begin7_(g7.begin()), end7_(g7.end()), current7_(current7), + begin8_(g8.begin()), end8_(g8.end()), current8_(current8) { + ComputeCurrentValue(); + } + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface* BaseGenerator() const { + return base_; + } + // Advance should not be called on beyond-of-range iterators + // so no component iterators must be beyond end of range, either. + virtual void Advance() { + assert(!AtEnd()); + ++current8_; + if (current8_ == end8_) { + current8_ = begin8_; + ++current7_; + } + if (current7_ == end7_) { + current7_ = begin7_; + ++current6_; + } + if (current6_ == end6_) { + current6_ = begin6_; + ++current5_; + } + if (current5_ == end5_) { + current5_ = begin5_; + ++current4_; + } + if (current4_ == end4_) { + current4_ = begin4_; + ++current3_; + } + if (current3_ == end3_) { + current3_ = begin3_; + ++current2_; + } + if (current2_ == end2_) { + current2_ = begin2_; + ++current1_; + } + ComputeCurrentValue(); + } + virtual ParamIteratorInterface* Clone() const { + return new Iterator(*this); + } + virtual const ParamType* Current() const { return ¤t_value_; } + virtual bool Equals(const ParamIteratorInterface& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const Iterator* typed_other = + CheckedDowncastToActualType(&other); + // We must report iterators equal if they both point beyond their + // respective ranges. That can happen in a variety of fashions, + // so we have to consult AtEnd(). + return (AtEnd() && typed_other->AtEnd()) || + ( + current1_ == typed_other->current1_ && + current2_ == typed_other->current2_ && + current3_ == typed_other->current3_ && + current4_ == typed_other->current4_ && + current5_ == typed_other->current5_ && + current6_ == typed_other->current6_ && + current7_ == typed_other->current7_ && + current8_ == typed_other->current8_); + } + + private: + Iterator(const Iterator& other) + : base_(other.base_), + begin1_(other.begin1_), + end1_(other.end1_), + current1_(other.current1_), + begin2_(other.begin2_), + end2_(other.end2_), + current2_(other.current2_), + begin3_(other.begin3_), + end3_(other.end3_), + current3_(other.current3_), + begin4_(other.begin4_), + end4_(other.end4_), + current4_(other.current4_), + begin5_(other.begin5_), + end5_(other.end5_), + current5_(other.current5_), + begin6_(other.begin6_), + end6_(other.end6_), + current6_(other.current6_), + begin7_(other.begin7_), + end7_(other.end7_), + current7_(other.current7_), + begin8_(other.begin8_), + end8_(other.end8_), + current8_(other.current8_) { + ComputeCurrentValue(); + } + + void ComputeCurrentValue() { + if (!AtEnd()) + current_value_ = ParamType(*current1_, *current2_, *current3_, + *current4_, *current5_, *current6_, *current7_, *current8_); + } + bool AtEnd() const { + // We must report iterator past the end of the range when either of the + // component iterators has reached the end of its range. + return + current1_ == end1_ || + current2_ == end2_ || + current3_ == end3_ || + current4_ == end4_ || + current5_ == end5_ || + current6_ == end6_ || + current7_ == end7_ || + current8_ == end8_; + } + + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + + const ParamGeneratorInterface* const base_; + // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. + // current[i]_ is the actual traversing iterator. + const typename ParamGenerator::iterator begin1_; + const typename ParamGenerator::iterator end1_; + typename ParamGenerator::iterator current1_; + const typename ParamGenerator::iterator begin2_; + const typename ParamGenerator::iterator end2_; + typename ParamGenerator::iterator current2_; + const typename ParamGenerator::iterator begin3_; + const typename ParamGenerator::iterator end3_; + typename ParamGenerator::iterator current3_; + const typename ParamGenerator::iterator begin4_; + const typename ParamGenerator::iterator end4_; + typename ParamGenerator::iterator current4_; + const typename ParamGenerator::iterator begin5_; + const typename ParamGenerator::iterator end5_; + typename ParamGenerator::iterator current5_; + const typename ParamGenerator::iterator begin6_; + const typename ParamGenerator::iterator end6_; + typename ParamGenerator::iterator current6_; + const typename ParamGenerator::iterator begin7_; + const typename ParamGenerator::iterator end7_; + typename ParamGenerator::iterator current7_; + const typename ParamGenerator::iterator begin8_; + const typename ParamGenerator::iterator end8_; + typename ParamGenerator::iterator current8_; + ParamType current_value_; + }; // class CartesianProductGenerator8::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator8& other); + + const ParamGenerator g1_; + const ParamGenerator g2_; + const ParamGenerator g3_; + const ParamGenerator g4_; + const ParamGenerator g5_; + const ParamGenerator g6_; + const ParamGenerator g7_; + const ParamGenerator g8_; +}; // class CartesianProductGenerator8 + + +template +class CartesianProductGenerator9 + : public ParamGeneratorInterface< ::std::tr1::tuple > { + public: + typedef ::std::tr1::tuple ParamType; + + CartesianProductGenerator9(const ParamGenerator& g1, + const ParamGenerator& g2, const ParamGenerator& g3, + const ParamGenerator& g4, const ParamGenerator& g5, + const ParamGenerator& g6, const ParamGenerator& g7, + const ParamGenerator& g8, const ParamGenerator& g9) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8), + g9_(g9) {} + virtual ~CartesianProductGenerator9() {} + + virtual ParamIteratorInterface* Begin() const { + return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, + g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_, + g7_.begin(), g8_, g8_.begin(), g9_, g9_.begin()); + } + virtual ParamIteratorInterface* End() const { + return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), + g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end(), g8_, + g8_.end(), g9_, g9_.end()); + } + + private: + class Iterator : public ParamIteratorInterface { + public: + Iterator(const ParamGeneratorInterface* base, + const ParamGenerator& g1, + const typename ParamGenerator::iterator& current1, + const ParamGenerator& g2, + const typename ParamGenerator::iterator& current2, + const ParamGenerator& g3, + const typename ParamGenerator::iterator& current3, + const ParamGenerator& g4, + const typename ParamGenerator::iterator& current4, + const ParamGenerator& g5, + const typename ParamGenerator::iterator& current5, + const ParamGenerator& g6, + const typename ParamGenerator::iterator& current6, + const ParamGenerator& g7, + const typename ParamGenerator::iterator& current7, + const ParamGenerator& g8, + const typename ParamGenerator::iterator& current8, + const ParamGenerator& g9, + const typename ParamGenerator::iterator& current9) + : base_(base), + begin1_(g1.begin()), end1_(g1.end()), current1_(current1), + begin2_(g2.begin()), end2_(g2.end()), current2_(current2), + begin3_(g3.begin()), end3_(g3.end()), current3_(current3), + begin4_(g4.begin()), end4_(g4.end()), current4_(current4), + begin5_(g5.begin()), end5_(g5.end()), current5_(current5), + begin6_(g6.begin()), end6_(g6.end()), current6_(current6), + begin7_(g7.begin()), end7_(g7.end()), current7_(current7), + begin8_(g8.begin()), end8_(g8.end()), current8_(current8), + begin9_(g9.begin()), end9_(g9.end()), current9_(current9) { + ComputeCurrentValue(); + } + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface* BaseGenerator() const { + return base_; + } + // Advance should not be called on beyond-of-range iterators + // so no component iterators must be beyond end of range, either. + virtual void Advance() { + assert(!AtEnd()); + ++current9_; + if (current9_ == end9_) { + current9_ = begin9_; + ++current8_; + } + if (current8_ == end8_) { + current8_ = begin8_; + ++current7_; + } + if (current7_ == end7_) { + current7_ = begin7_; + ++current6_; + } + if (current6_ == end6_) { + current6_ = begin6_; + ++current5_; + } + if (current5_ == end5_) { + current5_ = begin5_; + ++current4_; + } + if (current4_ == end4_) { + current4_ = begin4_; + ++current3_; + } + if (current3_ == end3_) { + current3_ = begin3_; + ++current2_; + } + if (current2_ == end2_) { + current2_ = begin2_; + ++current1_; + } + ComputeCurrentValue(); + } + virtual ParamIteratorInterface* Clone() const { + return new Iterator(*this); + } + virtual const ParamType* Current() const { return ¤t_value_; } + virtual bool Equals(const ParamIteratorInterface& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const Iterator* typed_other = + CheckedDowncastToActualType(&other); + // We must report iterators equal if they both point beyond their + // respective ranges. That can happen in a variety of fashions, + // so we have to consult AtEnd(). + return (AtEnd() && typed_other->AtEnd()) || + ( + current1_ == typed_other->current1_ && + current2_ == typed_other->current2_ && + current3_ == typed_other->current3_ && + current4_ == typed_other->current4_ && + current5_ == typed_other->current5_ && + current6_ == typed_other->current6_ && + current7_ == typed_other->current7_ && + current8_ == typed_other->current8_ && + current9_ == typed_other->current9_); + } + + private: + Iterator(const Iterator& other) + : base_(other.base_), + begin1_(other.begin1_), + end1_(other.end1_), + current1_(other.current1_), + begin2_(other.begin2_), + end2_(other.end2_), + current2_(other.current2_), + begin3_(other.begin3_), + end3_(other.end3_), + current3_(other.current3_), + begin4_(other.begin4_), + end4_(other.end4_), + current4_(other.current4_), + begin5_(other.begin5_), + end5_(other.end5_), + current5_(other.current5_), + begin6_(other.begin6_), + end6_(other.end6_), + current6_(other.current6_), + begin7_(other.begin7_), + end7_(other.end7_), + current7_(other.current7_), + begin8_(other.begin8_), + end8_(other.end8_), + current8_(other.current8_), + begin9_(other.begin9_), + end9_(other.end9_), + current9_(other.current9_) { + ComputeCurrentValue(); + } + + void ComputeCurrentValue() { + if (!AtEnd()) + current_value_ = ParamType(*current1_, *current2_, *current3_, + *current4_, *current5_, *current6_, *current7_, *current8_, + *current9_); + } + bool AtEnd() const { + // We must report iterator past the end of the range when either of the + // component iterators has reached the end of its range. + return + current1_ == end1_ || + current2_ == end2_ || + current3_ == end3_ || + current4_ == end4_ || + current5_ == end5_ || + current6_ == end6_ || + current7_ == end7_ || + current8_ == end8_ || + current9_ == end9_; + } + + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + + const ParamGeneratorInterface* const base_; + // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. + // current[i]_ is the actual traversing iterator. + const typename ParamGenerator::iterator begin1_; + const typename ParamGenerator::iterator end1_; + typename ParamGenerator::iterator current1_; + const typename ParamGenerator::iterator begin2_; + const typename ParamGenerator::iterator end2_; + typename ParamGenerator::iterator current2_; + const typename ParamGenerator::iterator begin3_; + const typename ParamGenerator::iterator end3_; + typename ParamGenerator::iterator current3_; + const typename ParamGenerator::iterator begin4_; + const typename ParamGenerator::iterator end4_; + typename ParamGenerator::iterator current4_; + const typename ParamGenerator::iterator begin5_; + const typename ParamGenerator::iterator end5_; + typename ParamGenerator::iterator current5_; + const typename ParamGenerator::iterator begin6_; + const typename ParamGenerator::iterator end6_; + typename ParamGenerator::iterator current6_; + const typename ParamGenerator::iterator begin7_; + const typename ParamGenerator::iterator end7_; + typename ParamGenerator::iterator current7_; + const typename ParamGenerator::iterator begin8_; + const typename ParamGenerator::iterator end8_; + typename ParamGenerator::iterator current8_; + const typename ParamGenerator::iterator begin9_; + const typename ParamGenerator::iterator end9_; + typename ParamGenerator::iterator current9_; + ParamType current_value_; + }; // class CartesianProductGenerator9::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator9& other); + + const ParamGenerator g1_; + const ParamGenerator g2_; + const ParamGenerator g3_; + const ParamGenerator g4_; + const ParamGenerator g5_; + const ParamGenerator g6_; + const ParamGenerator g7_; + const ParamGenerator g8_; + const ParamGenerator g9_; +}; // class CartesianProductGenerator9 + + +template +class CartesianProductGenerator10 + : public ParamGeneratorInterface< ::std::tr1::tuple > { + public: + typedef ::std::tr1::tuple ParamType; + + CartesianProductGenerator10(const ParamGenerator& g1, + const ParamGenerator& g2, const ParamGenerator& g3, + const ParamGenerator& g4, const ParamGenerator& g5, + const ParamGenerator& g6, const ParamGenerator& g7, + const ParamGenerator& g8, const ParamGenerator& g9, + const ParamGenerator& g10) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8), + g9_(g9), g10_(g10) {} + virtual ~CartesianProductGenerator10() {} + + virtual ParamIteratorInterface* Begin() const { + return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, + g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_, + g7_.begin(), g8_, g8_.begin(), g9_, g9_.begin(), g10_, g10_.begin()); + } + virtual ParamIteratorInterface* End() const { + return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), + g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end(), g8_, + g8_.end(), g9_, g9_.end(), g10_, g10_.end()); + } + + private: + class Iterator : public ParamIteratorInterface { + public: + Iterator(const ParamGeneratorInterface* base, + const ParamGenerator& g1, + const typename ParamGenerator::iterator& current1, + const ParamGenerator& g2, + const typename ParamGenerator::iterator& current2, + const ParamGenerator& g3, + const typename ParamGenerator::iterator& current3, + const ParamGenerator& g4, + const typename ParamGenerator::iterator& current4, + const ParamGenerator& g5, + const typename ParamGenerator::iterator& current5, + const ParamGenerator& g6, + const typename ParamGenerator::iterator& current6, + const ParamGenerator& g7, + const typename ParamGenerator::iterator& current7, + const ParamGenerator& g8, + const typename ParamGenerator::iterator& current8, + const ParamGenerator& g9, + const typename ParamGenerator::iterator& current9, + const ParamGenerator& g10, + const typename ParamGenerator::iterator& current10) + : base_(base), + begin1_(g1.begin()), end1_(g1.end()), current1_(current1), + begin2_(g2.begin()), end2_(g2.end()), current2_(current2), + begin3_(g3.begin()), end3_(g3.end()), current3_(current3), + begin4_(g4.begin()), end4_(g4.end()), current4_(current4), + begin5_(g5.begin()), end5_(g5.end()), current5_(current5), + begin6_(g6.begin()), end6_(g6.end()), current6_(current6), + begin7_(g7.begin()), end7_(g7.end()), current7_(current7), + begin8_(g8.begin()), end8_(g8.end()), current8_(current8), + begin9_(g9.begin()), end9_(g9.end()), current9_(current9), + begin10_(g10.begin()), end10_(g10.end()), current10_(current10) { + ComputeCurrentValue(); + } + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface* BaseGenerator() const { + return base_; + } + // Advance should not be called on beyond-of-range iterators + // so no component iterators must be beyond end of range, either. + virtual void Advance() { + assert(!AtEnd()); + ++current10_; + if (current10_ == end10_) { + current10_ = begin10_; + ++current9_; + } + if (current9_ == end9_) { + current9_ = begin9_; + ++current8_; + } + if (current8_ == end8_) { + current8_ = begin8_; + ++current7_; + } + if (current7_ == end7_) { + current7_ = begin7_; + ++current6_; + } + if (current6_ == end6_) { + current6_ = begin6_; + ++current5_; + } + if (current5_ == end5_) { + current5_ = begin5_; + ++current4_; + } + if (current4_ == end4_) { + current4_ = begin4_; + ++current3_; + } + if (current3_ == end3_) { + current3_ = begin3_; + ++current2_; + } + if (current2_ == end2_) { + current2_ = begin2_; + ++current1_; + } + ComputeCurrentValue(); + } + virtual ParamIteratorInterface* Clone() const { + return new Iterator(*this); + } + virtual const ParamType* Current() const { return ¤t_value_; } + virtual bool Equals(const ParamIteratorInterface& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const Iterator* typed_other = + CheckedDowncastToActualType(&other); + // We must report iterators equal if they both point beyond their + // respective ranges. That can happen in a variety of fashions, + // so we have to consult AtEnd(). + return (AtEnd() && typed_other->AtEnd()) || + ( + current1_ == typed_other->current1_ && + current2_ == typed_other->current2_ && + current3_ == typed_other->current3_ && + current4_ == typed_other->current4_ && + current5_ == typed_other->current5_ && + current6_ == typed_other->current6_ && + current7_ == typed_other->current7_ && + current8_ == typed_other->current8_ && + current9_ == typed_other->current9_ && + current10_ == typed_other->current10_); + } + + private: + Iterator(const Iterator& other) + : base_(other.base_), + begin1_(other.begin1_), + end1_(other.end1_), + current1_(other.current1_), + begin2_(other.begin2_), + end2_(other.end2_), + current2_(other.current2_), + begin3_(other.begin3_), + end3_(other.end3_), + current3_(other.current3_), + begin4_(other.begin4_), + end4_(other.end4_), + current4_(other.current4_), + begin5_(other.begin5_), + end5_(other.end5_), + current5_(other.current5_), + begin6_(other.begin6_), + end6_(other.end6_), + current6_(other.current6_), + begin7_(other.begin7_), + end7_(other.end7_), + current7_(other.current7_), + begin8_(other.begin8_), + end8_(other.end8_), + current8_(other.current8_), + begin9_(other.begin9_), + end9_(other.end9_), + current9_(other.current9_), + begin10_(other.begin10_), + end10_(other.end10_), + current10_(other.current10_) { + ComputeCurrentValue(); + } + + void ComputeCurrentValue() { + if (!AtEnd()) + current_value_ = ParamType(*current1_, *current2_, *current3_, + *current4_, *current5_, *current6_, *current7_, *current8_, + *current9_, *current10_); + } + bool AtEnd() const { + // We must report iterator past the end of the range when either of the + // component iterators has reached the end of its range. + return + current1_ == end1_ || + current2_ == end2_ || + current3_ == end3_ || + current4_ == end4_ || + current5_ == end5_ || + current6_ == end6_ || + current7_ == end7_ || + current8_ == end8_ || + current9_ == end9_ || + current10_ == end10_; + } + + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + + const ParamGeneratorInterface* const base_; + // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. + // current[i]_ is the actual traversing iterator. + const typename ParamGenerator::iterator begin1_; + const typename ParamGenerator::iterator end1_; + typename ParamGenerator::iterator current1_; + const typename ParamGenerator::iterator begin2_; + const typename ParamGenerator::iterator end2_; + typename ParamGenerator::iterator current2_; + const typename ParamGenerator::iterator begin3_; + const typename ParamGenerator::iterator end3_; + typename ParamGenerator::iterator current3_; + const typename ParamGenerator::iterator begin4_; + const typename ParamGenerator::iterator end4_; + typename ParamGenerator::iterator current4_; + const typename ParamGenerator::iterator begin5_; + const typename ParamGenerator::iterator end5_; + typename ParamGenerator::iterator current5_; + const typename ParamGenerator::iterator begin6_; + const typename ParamGenerator::iterator end6_; + typename ParamGenerator::iterator current6_; + const typename ParamGenerator::iterator begin7_; + const typename ParamGenerator::iterator end7_; + typename ParamGenerator::iterator current7_; + const typename ParamGenerator::iterator begin8_; + const typename ParamGenerator::iterator end8_; + typename ParamGenerator::iterator current8_; + const typename ParamGenerator::iterator begin9_; + const typename ParamGenerator::iterator end9_; + typename ParamGenerator::iterator current9_; + const typename ParamGenerator::iterator begin10_; + const typename ParamGenerator::iterator end10_; + typename ParamGenerator::iterator current10_; + ParamType current_value_; + }; // class CartesianProductGenerator10::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator10& other); + + const ParamGenerator g1_; + const ParamGenerator g2_; + const ParamGenerator g3_; + const ParamGenerator g4_; + const ParamGenerator g5_; + const ParamGenerator g6_; + const ParamGenerator g7_; + const ParamGenerator g8_; + const ParamGenerator g9_; + const ParamGenerator g10_; +}; // class CartesianProductGenerator10 + + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// Helper classes providing Combine() with polymorphic features. They allow +// casting CartesianProductGeneratorN to ParamGenerator if T is +// convertible to U. +// +template +class CartesianProductHolder2 { + public: +CartesianProductHolder2(const Generator1& g1, const Generator2& g2) + : g1_(g1), g2_(g2) {} + template + operator ParamGenerator< ::std::tr1::tuple >() const { + return ParamGenerator< ::std::tr1::tuple >( + new CartesianProductGenerator2( + static_cast >(g1_), + static_cast >(g2_))); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder2& other); + + const Generator1 g1_; + const Generator2 g2_; +}; // class CartesianProductHolder2 + +template +class CartesianProductHolder3 { + public: +CartesianProductHolder3(const Generator1& g1, const Generator2& g2, + const Generator3& g3) + : g1_(g1), g2_(g2), g3_(g3) {} + template + operator ParamGenerator< ::std::tr1::tuple >() const { + return ParamGenerator< ::std::tr1::tuple >( + new CartesianProductGenerator3( + static_cast >(g1_), + static_cast >(g2_), + static_cast >(g3_))); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder3& other); + + const Generator1 g1_; + const Generator2 g2_; + const Generator3 g3_; +}; // class CartesianProductHolder3 + +template +class CartesianProductHolder4 { + public: +CartesianProductHolder4(const Generator1& g1, const Generator2& g2, + const Generator3& g3, const Generator4& g4) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4) {} + template + operator ParamGenerator< ::std::tr1::tuple >() const { + return ParamGenerator< ::std::tr1::tuple >( + new CartesianProductGenerator4( + static_cast >(g1_), + static_cast >(g2_), + static_cast >(g3_), + static_cast >(g4_))); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder4& other); + + const Generator1 g1_; + const Generator2 g2_; + const Generator3 g3_; + const Generator4 g4_; +}; // class CartesianProductHolder4 + +template +class CartesianProductHolder5 { + public: +CartesianProductHolder5(const Generator1& g1, const Generator2& g2, + const Generator3& g3, const Generator4& g4, const Generator5& g5) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5) {} + template + operator ParamGenerator< ::std::tr1::tuple >() const { + return ParamGenerator< ::std::tr1::tuple >( + new CartesianProductGenerator5( + static_cast >(g1_), + static_cast >(g2_), + static_cast >(g3_), + static_cast >(g4_), + static_cast >(g5_))); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder5& other); + + const Generator1 g1_; + const Generator2 g2_; + const Generator3 g3_; + const Generator4 g4_; + const Generator5 g5_; +}; // class CartesianProductHolder5 + +template +class CartesianProductHolder6 { + public: +CartesianProductHolder6(const Generator1& g1, const Generator2& g2, + const Generator3& g3, const Generator4& g4, const Generator5& g5, + const Generator6& g6) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6) {} + template + operator ParamGenerator< ::std::tr1::tuple >() const { + return ParamGenerator< ::std::tr1::tuple >( + new CartesianProductGenerator6( + static_cast >(g1_), + static_cast >(g2_), + static_cast >(g3_), + static_cast >(g4_), + static_cast >(g5_), + static_cast >(g6_))); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder6& other); + + const Generator1 g1_; + const Generator2 g2_; + const Generator3 g3_; + const Generator4 g4_; + const Generator5 g5_; + const Generator6 g6_; +}; // class CartesianProductHolder6 + +template +class CartesianProductHolder7 { + public: +CartesianProductHolder7(const Generator1& g1, const Generator2& g2, + const Generator3& g3, const Generator4& g4, const Generator5& g5, + const Generator6& g6, const Generator7& g7) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7) {} + template + operator ParamGenerator< ::std::tr1::tuple >() const { + return ParamGenerator< ::std::tr1::tuple >( + new CartesianProductGenerator7( + static_cast >(g1_), + static_cast >(g2_), + static_cast >(g3_), + static_cast >(g4_), + static_cast >(g5_), + static_cast >(g6_), + static_cast >(g7_))); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder7& other); + + const Generator1 g1_; + const Generator2 g2_; + const Generator3 g3_; + const Generator4 g4_; + const Generator5 g5_; + const Generator6 g6_; + const Generator7 g7_; +}; // class CartesianProductHolder7 + +template +class CartesianProductHolder8 { + public: +CartesianProductHolder8(const Generator1& g1, const Generator2& g2, + const Generator3& g3, const Generator4& g4, const Generator5& g5, + const Generator6& g6, const Generator7& g7, const Generator8& g8) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), + g8_(g8) {} + template + operator ParamGenerator< ::std::tr1::tuple >() const { + return ParamGenerator< ::std::tr1::tuple >( + new CartesianProductGenerator8( + static_cast >(g1_), + static_cast >(g2_), + static_cast >(g3_), + static_cast >(g4_), + static_cast >(g5_), + static_cast >(g6_), + static_cast >(g7_), + static_cast >(g8_))); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder8& other); + + const Generator1 g1_; + const Generator2 g2_; + const Generator3 g3_; + const Generator4 g4_; + const Generator5 g5_; + const Generator6 g6_; + const Generator7 g7_; + const Generator8 g8_; +}; // class CartesianProductHolder8 + +template +class CartesianProductHolder9 { + public: +CartesianProductHolder9(const Generator1& g1, const Generator2& g2, + const Generator3& g3, const Generator4& g4, const Generator5& g5, + const Generator6& g6, const Generator7& g7, const Generator8& g8, + const Generator9& g9) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8), + g9_(g9) {} + template + operator ParamGenerator< ::std::tr1::tuple >() const { + return ParamGenerator< ::std::tr1::tuple >( + new CartesianProductGenerator9( + static_cast >(g1_), + static_cast >(g2_), + static_cast >(g3_), + static_cast >(g4_), + static_cast >(g5_), + static_cast >(g6_), + static_cast >(g7_), + static_cast >(g8_), + static_cast >(g9_))); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder9& other); + + const Generator1 g1_; + const Generator2 g2_; + const Generator3 g3_; + const Generator4 g4_; + const Generator5 g5_; + const Generator6 g6_; + const Generator7 g7_; + const Generator8 g8_; + const Generator9 g9_; +}; // class CartesianProductHolder9 + +template +class CartesianProductHolder10 { + public: +CartesianProductHolder10(const Generator1& g1, const Generator2& g2, + const Generator3& g3, const Generator4& g4, const Generator5& g5, + const Generator6& g6, const Generator7& g7, const Generator8& g8, + const Generator9& g9, const Generator10& g10) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8), + g9_(g9), g10_(g10) {} + template + operator ParamGenerator< ::std::tr1::tuple >() const { + return ParamGenerator< ::std::tr1::tuple >( + new CartesianProductGenerator10( + static_cast >(g1_), + static_cast >(g2_), + static_cast >(g3_), + static_cast >(g4_), + static_cast >(g5_), + static_cast >(g6_), + static_cast >(g7_), + static_cast >(g8_), + static_cast >(g9_), + static_cast >(g10_))); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder10& other); + + const Generator1 g1_; + const Generator2 g2_; + const Generator3 g3_; + const Generator4 g4_; + const Generator5 g5_; + const Generator6 g6_; + const Generator7 g7_; + const Generator8 g8_; + const Generator9 g9_; + const Generator10 g10_; +}; // class CartesianProductHolder10 + +#endif // GTEST_HAS_COMBINE + +} // namespace internal +} // namespace testing + +#endif // GTEST_HAS_PARAM_TEST + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_ + +#if GTEST_HAS_PARAM_TEST + +namespace testing { + +// Functions producing parameter generators. +// +// Google Test uses these generators to produce parameters for value- +// parameterized tests. When a parameterized test case is instantiated +// with a particular generator, Google Test creates and runs tests +// for each element in the sequence produced by the generator. +// +// In the following sample, tests from test case FooTest are instantiated +// each three times with parameter values 3, 5, and 8: +// +// class FooTest : public TestWithParam { ... }; +// +// TEST_P(FooTest, TestThis) { +// } +// TEST_P(FooTest, TestThat) { +// } +// INSTANTIATE_TEST_CASE_P(TestSequence, FooTest, Values(3, 5, 8)); +// + +// Range() returns generators providing sequences of values in a range. +// +// Synopsis: +// Range(start, end) +// - returns a generator producing a sequence of values {start, start+1, +// start+2, ..., }. +// Range(start, end, step) +// - returns a generator producing a sequence of values {start, start+step, +// start+step+step, ..., }. +// Notes: +// * The generated sequences never include end. For example, Range(1, 5) +// returns a generator producing a sequence {1, 2, 3, 4}. Range(1, 9, 2) +// returns a generator producing {1, 3, 5, 7}. +// * start and end must have the same type. That type may be any integral or +// floating-point type or a user defined type satisfying these conditions: +// * It must be assignable (have operator=() defined). +// * It must have operator+() (operator+(int-compatible type) for +// two-operand version). +// * It must have operator<() defined. +// Elements in the resulting sequences will also have that type. +// * Condition start < end must be satisfied in order for resulting sequences +// to contain any elements. +// +template +internal::ParamGenerator Range(T start, T end, IncrementT step) { + return internal::ParamGenerator( + new internal::RangeGenerator(start, end, step)); +} + +template +internal::ParamGenerator Range(T start, T end) { + return Range(start, end, 1); +} + +// ValuesIn() function allows generation of tests with parameters coming from +// a container. +// +// Synopsis: +// ValuesIn(const T (&array)[N]) +// - returns a generator producing sequences with elements from +// a C-style array. +// ValuesIn(const Container& container) +// - returns a generator producing sequences with elements from +// an STL-style container. +// ValuesIn(Iterator begin, Iterator end) +// - returns a generator producing sequences with elements from +// a range [begin, end) defined by a pair of STL-style iterators. These +// iterators can also be plain C pointers. +// +// Please note that ValuesIn copies the values from the containers +// passed in and keeps them to generate tests in RUN_ALL_TESTS(). +// +// Examples: +// +// This instantiates tests from test case StringTest +// each with C-string values of "foo", "bar", and "baz": +// +// const char* strings[] = {"foo", "bar", "baz"}; +// INSTANTIATE_TEST_CASE_P(StringSequence, SrtingTest, ValuesIn(strings)); +// +// This instantiates tests from test case StlStringTest +// each with STL strings with values "a" and "b": +// +// ::std::vector< ::std::string> GetParameterStrings() { +// ::std::vector< ::std::string> v; +// v.push_back("a"); +// v.push_back("b"); +// return v; +// } +// +// INSTANTIATE_TEST_CASE_P(CharSequence, +// StlStringTest, +// ValuesIn(GetParameterStrings())); +// +// +// This will also instantiate tests from CharTest +// each with parameter values 'a' and 'b': +// +// ::std::list GetParameterChars() { +// ::std::list list; +// list.push_back('a'); +// list.push_back('b'); +// return list; +// } +// ::std::list l = GetParameterChars(); +// INSTANTIATE_TEST_CASE_P(CharSequence2, +// CharTest, +// ValuesIn(l.begin(), l.end())); +// +template +internal::ParamGenerator< + typename ::std::iterator_traits::value_type> ValuesIn( + ForwardIterator begin, + ForwardIterator end) { + typedef typename ::std::iterator_traits::value_type + ParamType; + return internal::ParamGenerator( + new internal::ValuesInIteratorRangeGenerator(begin, end)); +} + +template +internal::ParamGenerator ValuesIn(const T (&array)[N]) { + return ValuesIn(array, array + N); +} + +template +internal::ParamGenerator ValuesIn( + const Container& container) { + return ValuesIn(container.begin(), container.end()); +} + +// Values() allows generating tests from explicitly specified list of +// parameters. +// +// Synopsis: +// Values(T v1, T v2, ..., T vN) +// - returns a generator producing sequences with elements v1, v2, ..., vN. +// +// For example, this instantiates tests from test case BarTest each +// with values "one", "two", and "three": +// +// INSTANTIATE_TEST_CASE_P(NumSequence, BarTest, Values("one", "two", "three")); +// +// This instantiates tests from test case BazTest each with values 1, 2, 3.5. +// The exact type of values will depend on the type of parameter in BazTest. +// +// INSTANTIATE_TEST_CASE_P(FloatingNumbers, BazTest, Values(1, 2, 3.5)); +// +// Currently, Values() supports from 1 to 50 parameters. +// +template +internal::ValueArray1 Values(T1 v1) { + return internal::ValueArray1(v1); +} + +template +internal::ValueArray2 Values(T1 v1, T2 v2) { + return internal::ValueArray2(v1, v2); +} + +template +internal::ValueArray3 Values(T1 v1, T2 v2, T3 v3) { + return internal::ValueArray3(v1, v2, v3); +} + +template +internal::ValueArray4 Values(T1 v1, T2 v2, T3 v3, T4 v4) { + return internal::ValueArray4(v1, v2, v3, v4); +} + +template +internal::ValueArray5 Values(T1 v1, T2 v2, T3 v3, T4 v4, + T5 v5) { + return internal::ValueArray5(v1, v2, v3, v4, v5); +} + +template +internal::ValueArray6 Values(T1 v1, T2 v2, T3 v3, + T4 v4, T5 v5, T6 v6) { + return internal::ValueArray6(v1, v2, v3, v4, v5, v6); +} + +template +internal::ValueArray7 Values(T1 v1, T2 v2, T3 v3, + T4 v4, T5 v5, T6 v6, T7 v7) { + return internal::ValueArray7(v1, v2, v3, v4, v5, + v6, v7); +} + +template +internal::ValueArray8 Values(T1 v1, T2 v2, + T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8) { + return internal::ValueArray8(v1, v2, v3, v4, + v5, v6, v7, v8); +} + +template +internal::ValueArray9 Values(T1 v1, T2 v2, + T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9) { + return internal::ValueArray9(v1, v2, v3, + v4, v5, v6, v7, v8, v9); +} + +template +internal::ValueArray10 Values(T1 v1, + T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10) { + return internal::ValueArray10(v1, + v2, v3, v4, v5, v6, v7, v8, v9, v10); +} + +template +internal::ValueArray11 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11) { + return internal::ValueArray11(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11); +} + +template +internal::ValueArray12 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12) { + return internal::ValueArray12(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12); +} + +template +internal::ValueArray13 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13) { + return internal::ValueArray13(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13); +} + +template +internal::ValueArray14 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14) { + return internal::ValueArray14(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, + v14); +} + +template +internal::ValueArray15 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, + T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15) { + return internal::ValueArray15(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, + v13, v14, v15); +} + +template +internal::ValueArray16 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, + T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, + T16 v16) { + return internal::ValueArray16(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, + v12, v13, v14, v15, v16); +} + +template +internal::ValueArray17 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, + T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, + T16 v16, T17 v17) { + return internal::ValueArray17(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, + v11, v12, v13, v14, v15, v16, v17); +} + +template +internal::ValueArray18 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, + T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, + T16 v16, T17 v17, T18 v18) { + return internal::ValueArray18(v1, v2, v3, v4, v5, v6, v7, v8, v9, + v10, v11, v12, v13, v14, v15, v16, v17, v18); +} + +template +internal::ValueArray19 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, + T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, + T15 v15, T16 v16, T17 v17, T18 v18, T19 v19) { + return internal::ValueArray19(v1, v2, v3, v4, v5, v6, v7, v8, + v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19); +} + +template +internal::ValueArray20 Values(T1 v1, T2 v2, T3 v3, T4 v4, + T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, + T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20) { + return internal::ValueArray20(v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20); +} + +template +internal::ValueArray21 Values(T1 v1, T2 v2, T3 v3, T4 v4, + T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, + T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21) { + return internal::ValueArray21(v1, v2, v3, v4, v5, v6, + v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21); +} + +template +internal::ValueArray22 Values(T1 v1, T2 v2, T3 v3, + T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, + T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, + T21 v21, T22 v22) { + return internal::ValueArray22(v1, v2, v3, v4, + v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, + v20, v21, v22); +} + +template +internal::ValueArray23 Values(T1 v1, T2 v2, + T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, + T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, + T21 v21, T22 v22, T23 v23) { + return internal::ValueArray23(v1, v2, v3, + v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, + v20, v21, v22, v23); +} + +template +internal::ValueArray24 Values(T1 v1, T2 v2, + T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, + T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, + T21 v21, T22 v22, T23 v23, T24 v24) { + return internal::ValueArray24(v1, v2, + v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, + v19, v20, v21, v22, v23, v24); +} + +template +internal::ValueArray25 Values(T1 v1, + T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, + T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, + T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25) { + return internal::ValueArray25(v1, + v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, + v18, v19, v20, v21, v22, v23, v24, v25); +} + +template +internal::ValueArray26 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26) { + return internal::ValueArray26(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, + v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26); +} + +template +internal::ValueArray27 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27) { + return internal::ValueArray27(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, + v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27); +} + +template +internal::ValueArray28 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28) { + return internal::ValueArray28(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, + v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, + v28); +} + +template +internal::ValueArray29 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29) { + return internal::ValueArray29(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, + v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, + v27, v28, v29); +} + +template +internal::ValueArray30 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, + T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, + T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, + T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30) { + return internal::ValueArray30(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, + v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, + v26, v27, v28, v29, v30); +} + +template +internal::ValueArray31 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, + T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, + T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, + T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31) { + return internal::ValueArray31(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, + v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, + v25, v26, v27, v28, v29, v30, v31); +} + +template +internal::ValueArray32 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, + T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, + T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, + T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, + T32 v32) { + return internal::ValueArray32(v1, v2, v3, v4, v5, v6, v7, v8, v9, + v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, + v24, v25, v26, v27, v28, v29, v30, v31, v32); +} + +template +internal::ValueArray33 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, + T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, + T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, + T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, + T32 v32, T33 v33) { + return internal::ValueArray33(v1, v2, v3, v4, v5, v6, v7, v8, + v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, + v24, v25, v26, v27, v28, v29, v30, v31, v32, v33); +} + +template +internal::ValueArray34 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, + T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, + T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, + T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, + T31 v31, T32 v32, T33 v33, T34 v34) { + return internal::ValueArray34(v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, + v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34); +} + +template +internal::ValueArray35 Values(T1 v1, T2 v2, T3 v3, T4 v4, + T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, + T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, + T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, + T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35) { + return internal::ValueArray35(v1, v2, v3, v4, v5, v6, + v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, + v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35); +} + +template +internal::ValueArray36 Values(T1 v1, T2 v2, T3 v3, T4 v4, + T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, + T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, + T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, + T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36) { + return internal::ValueArray36(v1, v2, v3, v4, + v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, + v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, + v34, v35, v36); +} + +template +internal::ValueArray37 Values(T1 v1, T2 v2, T3 v3, + T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, + T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, + T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, + T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, + T37 v37) { + return internal::ValueArray37(v1, v2, v3, + v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, + v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, + v34, v35, v36, v37); +} + +template +internal::ValueArray38 Values(T1 v1, T2 v2, + T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, + T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, + T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, + T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, + T37 v37, T38 v38) { + return internal::ValueArray38(v1, v2, + v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, + v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, + v33, v34, v35, v36, v37, v38); +} + +template +internal::ValueArray39 Values(T1 v1, T2 v2, + T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, + T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, + T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, + T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, + T37 v37, T38 v38, T39 v39) { + return internal::ValueArray39(v1, + v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, + v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, + v32, v33, v34, v35, v36, v37, v38, v39); +} + +template +internal::ValueArray40 Values(T1 v1, + T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, + T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, + T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, + T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, + T36 v36, T37 v37, T38 v38, T39 v39, T40 v40) { + return internal::ValueArray40(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, + v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, + v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40); +} + +template +internal::ValueArray41 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41) { + return internal::ValueArray41(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, + v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, + v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41); +} + +template +internal::ValueArray42 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42) { + return internal::ValueArray42(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, + v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, + v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, + v42); +} + +template +internal::ValueArray43 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43) { + return internal::ValueArray43(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, + v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, + v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, + v41, v42, v43); +} + +template +internal::ValueArray44 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43, T44 v44) { + return internal::ValueArray44(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, + v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, + v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, + v40, v41, v42, v43, v44); +} + +template +internal::ValueArray45 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, + T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, + T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, + T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, + T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, + T41 v41, T42 v42, T43 v43, T44 v44, T45 v45) { + return internal::ValueArray45(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, + v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, + v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, + v39, v40, v41, v42, v43, v44, v45); +} + +template +internal::ValueArray46 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, + T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, + T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, + T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, + T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, + T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46) { + return internal::ValueArray46(v1, v2, v3, v4, v5, v6, v7, v8, v9, + v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, + v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, + v38, v39, v40, v41, v42, v43, v44, v45, v46); +} + +template +internal::ValueArray47 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, + T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, + T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, + T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, + T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, + T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47) { + return internal::ValueArray47(v1, v2, v3, v4, v5, v6, v7, v8, + v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, + v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, + v38, v39, v40, v41, v42, v43, v44, v45, v46, v47); +} + +template +internal::ValueArray48 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, + T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, + T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, + T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, + T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, + T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, + T48 v48) { + return internal::ValueArray48(v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, + v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, + v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48); +} + +template +internal::ValueArray49 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, + T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, + T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, + T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, + T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, + T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, + T47 v47, T48 v48, T49 v49) { + return internal::ValueArray49(v1, v2, v3, v4, v5, v6, + v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, + v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, + v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49); +} + +template +internal::ValueArray50 Values(T1 v1, T2 v2, T3 v3, T4 v4, + T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, + T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, + T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, + T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, + T38 v38, T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, + T46 v46, T47 v47, T48 v48, T49 v49, T50 v50) { + return internal::ValueArray50(v1, v2, v3, v4, + v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, + v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, + v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, + v48, v49, v50); +} + +// Bool() allows generating tests with parameters in a set of (false, true). +// +// Synopsis: +// Bool() +// - returns a generator producing sequences with elements {false, true}. +// +// It is useful when testing code that depends on Boolean flags. Combinations +// of multiple flags can be tested when several Bool()'s are combined using +// Combine() function. +// +// In the following example all tests in the test case FlagDependentTest +// will be instantiated twice with parameters false and true. +// +// class FlagDependentTest : public testing::TestWithParam { +// virtual void SetUp() { +// external_flag = GetParam(); +// } +// } +// INSTANTIATE_TEST_CASE_P(BoolSequence, FlagDependentTest, Bool()); +// +inline internal::ParamGenerator Bool() { + return Values(false, true); +} + +#if GTEST_HAS_COMBINE +// Combine() allows the user to combine two or more sequences to produce +// values of a Cartesian product of those sequences' elements. +// +// Synopsis: +// Combine(gen1, gen2, ..., genN) +// - returns a generator producing sequences with elements coming from +// the Cartesian product of elements from the sequences generated by +// gen1, gen2, ..., genN. The sequence elements will have a type of +// tuple where T1, T2, ..., TN are the types +// of elements from sequences produces by gen1, gen2, ..., genN. +// +// Combine can have up to 10 arguments. This number is currently limited +// by the maximum number of elements in the tuple implementation used by Google +// Test. +// +// Example: +// +// This will instantiate tests in test case AnimalTest each one with +// the parameter values tuple("cat", BLACK), tuple("cat", WHITE), +// tuple("dog", BLACK), and tuple("dog", WHITE): +// +// enum Color { BLACK, GRAY, WHITE }; +// class AnimalTest +// : public testing::TestWithParam > {...}; +// +// TEST_P(AnimalTest, AnimalLooksNice) {...} +// +// INSTANTIATE_TEST_CASE_P(AnimalVariations, AnimalTest, +// Combine(Values("cat", "dog"), +// Values(BLACK, WHITE))); +// +// This will instantiate tests in FlagDependentTest with all variations of two +// Boolean flags: +// +// class FlagDependentTest +// : public testing::TestWithParam > { +// virtual void SetUp() { +// // Assigns external_flag_1 and external_flag_2 values from the tuple. +// tie(external_flag_1, external_flag_2) = GetParam(); +// } +// }; +// +// TEST_P(FlagDependentTest, TestFeature1) { +// // Test your code using external_flag_1 and external_flag_2 here. +// } +// INSTANTIATE_TEST_CASE_P(TwoBoolSequence, FlagDependentTest, +// Combine(Bool(), Bool())); +// +template +internal::CartesianProductHolder2 Combine( + const Generator1& g1, const Generator2& g2) { + return internal::CartesianProductHolder2( + g1, g2); +} + +template +internal::CartesianProductHolder3 Combine( + const Generator1& g1, const Generator2& g2, const Generator3& g3) { + return internal::CartesianProductHolder3( + g1, g2, g3); +} + +template +internal::CartesianProductHolder4 Combine( + const Generator1& g1, const Generator2& g2, const Generator3& g3, + const Generator4& g4) { + return internal::CartesianProductHolder4( + g1, g2, g3, g4); +} + +template +internal::CartesianProductHolder5 Combine( + const Generator1& g1, const Generator2& g2, const Generator3& g3, + const Generator4& g4, const Generator5& g5) { + return internal::CartesianProductHolder5( + g1, g2, g3, g4, g5); +} + +template +internal::CartesianProductHolder6 Combine( + const Generator1& g1, const Generator2& g2, const Generator3& g3, + const Generator4& g4, const Generator5& g5, const Generator6& g6) { + return internal::CartesianProductHolder6( + g1, g2, g3, g4, g5, g6); +} + +template +internal::CartesianProductHolder7 Combine( + const Generator1& g1, const Generator2& g2, const Generator3& g3, + const Generator4& g4, const Generator5& g5, const Generator6& g6, + const Generator7& g7) { + return internal::CartesianProductHolder7( + g1, g2, g3, g4, g5, g6, g7); +} + +template +internal::CartesianProductHolder8 Combine( + const Generator1& g1, const Generator2& g2, const Generator3& g3, + const Generator4& g4, const Generator5& g5, const Generator6& g6, + const Generator7& g7, const Generator8& g8) { + return internal::CartesianProductHolder8( + g1, g2, g3, g4, g5, g6, g7, g8); +} + +template +internal::CartesianProductHolder9 Combine( + const Generator1& g1, const Generator2& g2, const Generator3& g3, + const Generator4& g4, const Generator5& g5, const Generator6& g6, + const Generator7& g7, const Generator8& g8, const Generator9& g9) { + return internal::CartesianProductHolder9( + g1, g2, g3, g4, g5, g6, g7, g8, g9); +} + +template +internal::CartesianProductHolder10 Combine( + const Generator1& g1, const Generator2& g2, const Generator3& g3, + const Generator4& g4, const Generator5& g5, const Generator6& g6, + const Generator7& g7, const Generator8& g8, const Generator9& g9, + const Generator10& g10) { + return internal::CartesianProductHolder10( + g1, g2, g3, g4, g5, g6, g7, g8, g9, g10); +} +#endif // GTEST_HAS_COMBINE + + + +#define TEST_P(test_case_name, test_name) \ + class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) \ + : public test_case_name { \ + public: \ + GTEST_TEST_CLASS_NAME_(test_case_name, test_name)() {} \ + virtual void TestBody(); \ + private: \ + static int AddToRegistry() { \ + ::testing::UnitTest::GetInstance()->parameterized_test_registry(). \ + GetTestCasePatternHolder(\ + #test_case_name, __FILE__, __LINE__)->AddTestPattern(\ + #test_case_name, \ + #test_name, \ + new ::testing::internal::TestMetaFactory< \ + GTEST_TEST_CLASS_NAME_(test_case_name, test_name)>()); \ + return 0; \ + } \ + static int gtest_registering_dummy_; \ + GTEST_DISALLOW_COPY_AND_ASSIGN_(\ + GTEST_TEST_CLASS_NAME_(test_case_name, test_name)); \ + }; \ + int GTEST_TEST_CLASS_NAME_(test_case_name, \ + test_name)::gtest_registering_dummy_ = \ + GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::AddToRegistry(); \ + void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody() + +#define INSTANTIATE_TEST_CASE_P(prefix, test_case_name, generator) \ + ::testing::internal::ParamGenerator \ + gtest_##prefix##test_case_name##_EvalGenerator_() { return generator; } \ + int gtest_##prefix##test_case_name##_dummy_ = \ + ::testing::UnitTest::GetInstance()->parameterized_test_registry(). \ + GetTestCasePatternHolder(\ + #test_case_name, __FILE__, __LINE__)->AddTestCaseInstantiation(\ + #prefix, \ + >est_##prefix##test_case_name##_EvalGenerator_, \ + __FILE__, __LINE__) + +} // namespace testing + +#endif // GTEST_HAS_PARAM_TEST + +#endif // GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_ +// Copyright 2006, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: wan@google.com (Zhanyong Wan) +// +// Google C++ Testing Framework definitions useful in production code. + +#ifndef GTEST_INCLUDE_GTEST_GTEST_PROD_H_ +#define GTEST_INCLUDE_GTEST_GTEST_PROD_H_ + +// When you need to test the private or protected members of a class, +// use the FRIEND_TEST macro to declare your tests as friends of the +// class. For example: +// +// class MyClass { +// private: +// void MyMethod(); +// FRIEND_TEST(MyClassTest, MyMethod); +// }; +// +// class MyClassTest : public testing::Test { +// // ... +// }; +// +// TEST_F(MyClassTest, MyMethod) { +// // Can call MyClass::MyMethod() here. +// } + +#define FRIEND_TEST(test_case_name, test_name)\ +friend class test_case_name##_##test_name##_Test + +#endif // GTEST_INCLUDE_GTEST_GTEST_PROD_H_ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: mheule@google.com (Markus Heule) +// + +#ifndef GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_ +#define GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_ + +#include +#include + +namespace testing { + +// A copyable object representing the result of a test part (i.e. an +// assertion or an explicit FAIL(), ADD_FAILURE(), or SUCCESS()). +// +// Don't inherit from TestPartResult as its destructor is not virtual. +class GTEST_API_ TestPartResult { + public: + // The possible outcomes of a test part (i.e. an assertion or an + // explicit SUCCEED(), FAIL(), or ADD_FAILURE()). + enum Type { + kSuccess, // Succeeded. + kNonFatalFailure, // Failed but the test can continue. + kFatalFailure // Failed and the test should be terminated. + }; + + // C'tor. TestPartResult does NOT have a default constructor. + // Always use this constructor (with parameters) to create a + // TestPartResult object. + TestPartResult(Type a_type, + const char* a_file_name, + int a_line_number, + const char* a_message) + : type_(a_type), + file_name_(a_file_name), + line_number_(a_line_number), + summary_(ExtractSummary(a_message)), + message_(a_message) { + } + + // Gets the outcome of the test part. + Type type() const { return type_; } + + // Gets the name of the source file where the test part took place, or + // NULL if it's unknown. + const char* file_name() const { return file_name_.c_str(); } + + // Gets the line in the source file where the test part took place, + // or -1 if it's unknown. + int line_number() const { return line_number_; } + + // Gets the summary of the failure message. + const char* summary() const { return summary_.c_str(); } + + // Gets the message associated with the test part. + const char* message() const { return message_.c_str(); } + + // Returns true iff the test part passed. + bool passed() const { return type_ == kSuccess; } + + // Returns true iff the test part failed. + bool failed() const { return type_ != kSuccess; } + + // Returns true iff the test part non-fatally failed. + bool nonfatally_failed() const { return type_ == kNonFatalFailure; } + + // Returns true iff the test part fatally failed. + bool fatally_failed() const { return type_ == kFatalFailure; } + private: + Type type_; + + // Gets the summary of the failure message by omitting the stack + // trace in it. + static internal::String ExtractSummary(const char* message); + + // The name of the source file where the test part took place, or + // NULL if the source file is unknown. + internal::String file_name_; + // The line in the source file where the test part took place, or -1 + // if the line number is unknown. + int line_number_; + internal::String summary_; // The test failure summary. + internal::String message_; // The test failure message. +}; + +// Prints a TestPartResult object. +std::ostream& operator<<(std::ostream& os, const TestPartResult& result); + +// An array of TestPartResult objects. +// +// Don't inherit from TestPartResultArray as its destructor is not +// virtual. +class GTEST_API_ TestPartResultArray { + public: + TestPartResultArray() {} + + // Appends the given TestPartResult to the array. + void Append(const TestPartResult& result); + + // Returns the TestPartResult at the given index (0-based). + const TestPartResult& GetTestPartResult(int index) const; + + // Returns the number of TestPartResult objects in the array. + int size() const; + + private: + std::vector array_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestPartResultArray); +}; + +// This interface knows how to report a test part result. +class TestPartResultReporterInterface { + public: + virtual ~TestPartResultReporterInterface() {} + + virtual void ReportTestPartResult(const TestPartResult& result) = 0; +}; + +namespace internal { + +// This helper class is used by {ASSERT|EXPECT}_NO_FATAL_FAILURE to check if a +// statement generates new fatal failures. To do so it registers itself as the +// current test part result reporter. Besides checking if fatal failures were +// reported, it only delegates the reporting to the former result reporter. +// The original result reporter is restored in the destructor. +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +class GTEST_API_ HasNewFatalFailureHelper + : public TestPartResultReporterInterface { + public: + HasNewFatalFailureHelper(); + virtual ~HasNewFatalFailureHelper(); + virtual void ReportTestPartResult(const TestPartResult& result); + bool has_new_fatal_failure() const { return has_new_fatal_failure_; } + private: + bool has_new_fatal_failure_; + TestPartResultReporterInterface* original_reporter_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(HasNewFatalFailureHelper); +}; + +} // namespace internal + +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_ +// Copyright 2008 Google Inc. +// All Rights Reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: wan@google.com (Zhanyong Wan) + +#ifndef GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_ +#define GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_ + +// This header implements typed tests and type-parameterized tests. + +// Typed (aka type-driven) tests repeat the same test for types in a +// list. You must know which types you want to test with when writing +// typed tests. Here's how you do it: + +#if 0 + +// First, define a fixture class template. It should be parameterized +// by a type. Remember to derive it from testing::Test. +template +class FooTest : public testing::Test { + public: + ... + typedef std::list List; + static T shared_; + T value_; +}; + +// Next, associate a list of types with the test case, which will be +// repeated for each type in the list. The typedef is necessary for +// the macro to parse correctly. +typedef testing::Types MyTypes; +TYPED_TEST_CASE(FooTest, MyTypes); + +// If the type list contains only one type, you can write that type +// directly without Types<...>: +// TYPED_TEST_CASE(FooTest, int); + +// Then, use TYPED_TEST() instead of TEST_F() to define as many typed +// tests for this test case as you want. +TYPED_TEST(FooTest, DoesBlah) { + // Inside a test, refer to TypeParam to get the type parameter. + // Since we are inside a derived class template, C++ requires use to + // visit the members of FooTest via 'this'. + TypeParam n = this->value_; + + // To visit static members of the fixture, add the TestFixture:: + // prefix. + n += TestFixture::shared_; + + // To refer to typedefs in the fixture, add the "typename + // TestFixture::" prefix. + typename TestFixture::List values; + values.push_back(n); + ... +} + +TYPED_TEST(FooTest, HasPropertyA) { ... } + +#endif // 0 + +// Type-parameterized tests are abstract test patterns parameterized +// by a type. Compared with typed tests, type-parameterized tests +// allow you to define the test pattern without knowing what the type +// parameters are. The defined pattern can be instantiated with +// different types any number of times, in any number of translation +// units. +// +// If you are designing an interface or concept, you can define a +// suite of type-parameterized tests to verify properties that any +// valid implementation of the interface/concept should have. Then, +// each implementation can easily instantiate the test suite to verify +// that it conforms to the requirements, without having to write +// similar tests repeatedly. Here's an example: + +#if 0 + +// First, define a fixture class template. It should be parameterized +// by a type. Remember to derive it from testing::Test. +template +class FooTest : public testing::Test { + ... +}; + +// Next, declare that you will define a type-parameterized test case +// (the _P suffix is for "parameterized" or "pattern", whichever you +// prefer): +TYPED_TEST_CASE_P(FooTest); + +// Then, use TYPED_TEST_P() to define as many type-parameterized tests +// for this type-parameterized test case as you want. +TYPED_TEST_P(FooTest, DoesBlah) { + // Inside a test, refer to TypeParam to get the type parameter. + TypeParam n = 0; + ... +} + +TYPED_TEST_P(FooTest, HasPropertyA) { ... } + +// Now the tricky part: you need to register all test patterns before +// you can instantiate them. The first argument of the macro is the +// test case name; the rest are the names of the tests in this test +// case. +REGISTER_TYPED_TEST_CASE_P(FooTest, + DoesBlah, HasPropertyA); + +// Finally, you are free to instantiate the pattern with the types you +// want. If you put the above code in a header file, you can #include +// it in multiple C++ source files and instantiate it multiple times. +// +// To distinguish different instances of the pattern, the first +// argument to the INSTANTIATE_* macro is a prefix that will be added +// to the actual test case name. Remember to pick unique prefixes for +// different instances. +typedef testing::Types MyTypes; +INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, MyTypes); + +// If the type list contains only one type, you can write that type +// directly without Types<...>: +// INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, int); + +#endif // 0 + + +// Implements typed tests. + +#if GTEST_HAS_TYPED_TEST + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// Expands to the name of the typedef for the type parameters of the +// given test case. +#define GTEST_TYPE_PARAMS_(TestCaseName) gtest_type_params_##TestCaseName##_ + +// The 'Types' template argument below must have spaces around it +// since some compilers may choke on '>>' when passing a template +// instance (e.g. Types) +#define TYPED_TEST_CASE(CaseName, Types) \ + typedef ::testing::internal::TypeList< Types >::type \ + GTEST_TYPE_PARAMS_(CaseName) + +#define TYPED_TEST(CaseName, TestName) \ + template \ + class GTEST_TEST_CLASS_NAME_(CaseName, TestName) \ + : public CaseName { \ + private: \ + typedef CaseName TestFixture; \ + typedef gtest_TypeParam_ TypeParam; \ + virtual void TestBody(); \ + }; \ + bool gtest_##CaseName##_##TestName##_registered_ = \ + ::testing::internal::TypeParameterizedTest< \ + CaseName, \ + ::testing::internal::TemplateSel< \ + GTEST_TEST_CLASS_NAME_(CaseName, TestName)>, \ + GTEST_TYPE_PARAMS_(CaseName)>::Register(\ + "", #CaseName, #TestName, 0); \ + template \ + void GTEST_TEST_CLASS_NAME_(CaseName, TestName)::TestBody() + +#endif // GTEST_HAS_TYPED_TEST + +// Implements type-parameterized tests. + +#if GTEST_HAS_TYPED_TEST_P + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// Expands to the namespace name that the type-parameterized tests for +// the given type-parameterized test case are defined in. The exact +// name of the namespace is subject to change without notice. +#define GTEST_CASE_NAMESPACE_(TestCaseName) \ + gtest_case_##TestCaseName##_ + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// Expands to the name of the variable used to remember the names of +// the defined tests in the given test case. +#define GTEST_TYPED_TEST_CASE_P_STATE_(TestCaseName) \ + gtest_typed_test_case_p_state_##TestCaseName##_ + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE DIRECTLY. +// +// Expands to the name of the variable used to remember the names of +// the registered tests in the given test case. +#define GTEST_REGISTERED_TEST_NAMES_(TestCaseName) \ + gtest_registered_test_names_##TestCaseName##_ + +// The variables defined in the type-parameterized test macros are +// static as typically these macros are used in a .h file that can be +// #included in multiple translation units linked together. +#define TYPED_TEST_CASE_P(CaseName) \ + static ::testing::internal::TypedTestCasePState \ + GTEST_TYPED_TEST_CASE_P_STATE_(CaseName) + +#define TYPED_TEST_P(CaseName, TestName) \ + namespace GTEST_CASE_NAMESPACE_(CaseName) { \ + template \ + class TestName : public CaseName { \ + private: \ + typedef CaseName TestFixture; \ + typedef gtest_TypeParam_ TypeParam; \ + virtual void TestBody(); \ + }; \ + static bool gtest_##TestName##_defined_ = \ + GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).AddTestName(\ + __FILE__, __LINE__, #CaseName, #TestName); \ + } \ + template \ + void GTEST_CASE_NAMESPACE_(CaseName)::TestName::TestBody() + +#define REGISTER_TYPED_TEST_CASE_P(CaseName, ...) \ + namespace GTEST_CASE_NAMESPACE_(CaseName) { \ + typedef ::testing::internal::Templates<__VA_ARGS__>::type gtest_AllTests_; \ + } \ + static const char* const GTEST_REGISTERED_TEST_NAMES_(CaseName) = \ + GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).VerifyRegisteredTestNames(\ + __FILE__, __LINE__, #__VA_ARGS__) + +// The 'Types' template argument below must have spaces around it +// since some compilers may choke on '>>' when passing a template +// instance (e.g. Types) +#define INSTANTIATE_TYPED_TEST_CASE_P(Prefix, CaseName, Types) \ + bool gtest_##Prefix##_##CaseName = \ + ::testing::internal::TypeParameterizedTestCase::type>::Register(\ + #Prefix, #CaseName, GTEST_REGISTERED_TEST_NAMES_(CaseName)) + +#endif // GTEST_HAS_TYPED_TEST_P + +#endif // GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_ + +// Depending on the platform, different string classes are available. +// On Linux, in addition to ::std::string, Google also makes use of +// class ::string, which has the same interface as ::std::string, but +// has a different implementation. +// +// The user can define GTEST_HAS_GLOBAL_STRING to 1 to indicate that +// ::string is available AND is a distinct type to ::std::string, or +// define it to 0 to indicate otherwise. +// +// If the user's ::std::string and ::string are the same class due to +// aliasing, he should define GTEST_HAS_GLOBAL_STRING to 0. +// +// If the user doesn't define GTEST_HAS_GLOBAL_STRING, it is defined +// heuristically. + +namespace testing { + +// Declares the flags. + +// This flag temporary enables the disabled tests. +GTEST_DECLARE_bool_(also_run_disabled_tests); + +// This flag brings the debugger on an assertion failure. +GTEST_DECLARE_bool_(break_on_failure); + +// This flag controls whether Google Test catches all test-thrown exceptions +// and logs them as failures. +GTEST_DECLARE_bool_(catch_exceptions); + +// This flag enables using colors in terminal output. Available values are +// "yes" to enable colors, "no" (disable colors), or "auto" (the default) +// to let Google Test decide. +GTEST_DECLARE_string_(color); + +// This flag sets up the filter to select by name using a glob pattern +// the tests to run. If the filter is not given all tests are executed. +GTEST_DECLARE_string_(filter); + +// This flag causes the Google Test to list tests. None of the tests listed +// are actually run if the flag is provided. +GTEST_DECLARE_bool_(list_tests); + +// This flag controls whether Google Test emits a detailed XML report to a file +// in addition to its normal textual output. +GTEST_DECLARE_string_(output); + +// This flags control whether Google Test prints the elapsed time for each +// test. +GTEST_DECLARE_bool_(print_time); + +// This flag specifies the random number seed. +GTEST_DECLARE_int32_(random_seed); + +// This flag sets how many times the tests are repeated. The default value +// is 1. If the value is -1 the tests are repeating forever. +GTEST_DECLARE_int32_(repeat); + +// This flag controls whether Google Test includes Google Test internal +// stack frames in failure stack traces. +GTEST_DECLARE_bool_(show_internal_stack_frames); + +// When this flag is specified, tests' order is randomized on every iteration. +GTEST_DECLARE_bool_(shuffle); + +// This flag specifies the maximum number of stack frames to be +// printed in a failure message. +GTEST_DECLARE_int32_(stack_trace_depth); + +// When this flag is specified, a failed assertion will throw an +// exception if exceptions are enabled, or exit the program with a +// non-zero code otherwise. +GTEST_DECLARE_bool_(throw_on_failure); + +// The upper limit for valid stack trace depths. +const int kMaxStackTraceDepth = 100; + +namespace internal { + +class AssertHelper; +class DefaultGlobalTestPartResultReporter; +class ExecDeathTest; +class NoExecDeathTest; +class FinalSuccessChecker; +class GTestFlagSaver; +class TestInfoImpl; +class TestResultAccessor; +class TestEventListenersAccessor; +class TestEventRepeater; +class WindowsDeathTest; +class UnitTestImpl* GetUnitTestImpl(); +void ReportFailureInUnknownLocation(TestPartResult::Type result_type, + const String& message); +class PrettyUnitTestResultPrinter; +class XmlUnitTestResultPrinter; + +// Converts a streamable value to a String. A NULL pointer is +// converted to "(null)". When the input value is a ::string, +// ::std::string, ::wstring, or ::std::wstring object, each NUL +// character in it is replaced with "\\0". +// Declared in gtest-internal.h but defined here, so that it has access +// to the definition of the Message class, required by the ARM +// compiler. +template +String StreamableToString(const T& streamable) { + return (Message() << streamable).GetString(); +} + +} // namespace internal + +// A class for indicating whether an assertion was successful. When +// the assertion wasn't successful, the AssertionResult object +// remembers a non-empty message that describes how it failed. +// +// To create an instance of this class, use one of the factory functions +// (AssertionSuccess() and AssertionFailure()). +// +// This class is useful for two purposes: +// 1. Defining predicate functions to be used with Boolean test assertions +// EXPECT_TRUE/EXPECT_FALSE and their ASSERT_ counterparts +// 2. Defining predicate-format functions to be +// used with predicate assertions (ASSERT_PRED_FORMAT*, etc). +// +// For example, if you define IsEven predicate: +// +// testing::AssertionResult IsEven(int n) { +// if ((n % 2) == 0) +// return testing::AssertionSuccess(); +// else +// return testing::AssertionFailure() << n << " is odd"; +// } +// +// Then the failed expectation EXPECT_TRUE(IsEven(Fib(5))) +// will print the message +// +// Value of: IsEven(Fib(5)) +// Actual: false (5 is odd) +// Expected: true +// +// instead of a more opaque +// +// Value of: IsEven(Fib(5)) +// Actual: false +// Expected: true +// +// in case IsEven is a simple Boolean predicate. +// +// If you expect your predicate to be reused and want to support informative +// messages in EXPECT_FALSE and ASSERT_FALSE (negative assertions show up +// about half as often as positive ones in our tests), supply messages for +// both success and failure cases: +// +// testing::AssertionResult IsEven(int n) { +// if ((n % 2) == 0) +// return testing::AssertionSuccess() << n << " is even"; +// else +// return testing::AssertionFailure() << n << " is odd"; +// } +// +// Then a statement EXPECT_FALSE(IsEven(Fib(6))) will print +// +// Value of: IsEven(Fib(6)) +// Actual: true (8 is even) +// Expected: false +// +// NB: Predicates that support negative Boolean assertions have reduced +// performance in positive ones so be careful not to use them in tests +// that have lots (tens of thousands) of positive Boolean assertions. +// +// To use this class with EXPECT_PRED_FORMAT assertions such as: +// +// // Verifies that Foo() returns an even number. +// EXPECT_PRED_FORMAT1(IsEven, Foo()); +// +// you need to define: +// +// testing::AssertionResult IsEven(const char* expr, int n) { +// if ((n % 2) == 0) +// return testing::AssertionSuccess(); +// else +// return testing::AssertionFailure() +// << "Expected: " << expr << " is even\n Actual: it's " << n; +// } +// +// If Foo() returns 5, you will see the following message: +// +// Expected: Foo() is even +// Actual: it's 5 +// +class GTEST_API_ AssertionResult { + public: + // Copy constructor. + // Used in EXPECT_TRUE/FALSE(assertion_result). + AssertionResult(const AssertionResult& other); + // Used in the EXPECT_TRUE/FALSE(bool_expression). + explicit AssertionResult(bool success) : success_(success) {} + + // Returns true iff the assertion succeeded. + operator bool() const { return success_; } // NOLINT + + // Returns the assertion's negation. Used with EXPECT/ASSERT_FALSE. + AssertionResult operator!() const; + + // Returns the text streamed into this AssertionResult. Test assertions + // use it when they fail (i.e., the predicate's outcome doesn't match the + // assertion's expectation). When nothing has been streamed into the + // object, returns an empty string. + const char* message() const { + return message_.get() != NULL && message_->c_str() != NULL ? + message_->c_str() : ""; + } + // TODO(vladl@google.com): Remove this after making sure no clients use it. + // Deprecated; please use message() instead. + const char* failure_message() const { return message(); } + + // Streams a custom failure message into this object. + template AssertionResult& operator<<(const T& value); + + private: + // No implementation - we want AssertionResult to be + // copy-constructible but not assignable. + void operator=(const AssertionResult& other); + + // Stores result of the assertion predicate. + bool success_; + // Stores the message describing the condition in case the expectation + // construct is not satisfied with the predicate's outcome. + // Referenced via a pointer to avoid taking too much stack frame space + // with test assertions. + internal::scoped_ptr message_; +}; // class AssertionResult + +// Streams a custom failure message into this object. +template +AssertionResult& AssertionResult::operator<<(const T& value) { + Message msg; + if (message_.get() != NULL) + msg << *message_; + msg << value; + message_.reset(new internal::String(msg.GetString())); + return *this; +} + +// Makes a successful assertion result. +GTEST_API_ AssertionResult AssertionSuccess(); + +// Makes a failed assertion result. +GTEST_API_ AssertionResult AssertionFailure(); + +// Makes a failed assertion result with the given failure message. +// Deprecated; use AssertionFailure() << msg. +GTEST_API_ AssertionResult AssertionFailure(const Message& msg); + +// The abstract class that all tests inherit from. +// +// In Google Test, a unit test program contains one or many TestCases, and +// each TestCase contains one or many Tests. +// +// When you define a test using the TEST macro, you don't need to +// explicitly derive from Test - the TEST macro automatically does +// this for you. +// +// The only time you derive from Test is when defining a test fixture +// to be used a TEST_F. For example: +// +// class FooTest : public testing::Test { +// protected: +// virtual void SetUp() { ... } +// virtual void TearDown() { ... } +// ... +// }; +// +// TEST_F(FooTest, Bar) { ... } +// TEST_F(FooTest, Baz) { ... } +// +// Test is not copyable. +class GTEST_API_ Test { + public: + friend class internal::TestInfoImpl; + + // Defines types for pointers to functions that set up and tear down + // a test case. + typedef internal::SetUpTestCaseFunc SetUpTestCaseFunc; + typedef internal::TearDownTestCaseFunc TearDownTestCaseFunc; + + // The d'tor is virtual as we intend to inherit from Test. + virtual ~Test(); + + // Sets up the stuff shared by all tests in this test case. + // + // Google Test will call Foo::SetUpTestCase() before running the first + // test in test case Foo. Hence a sub-class can define its own + // SetUpTestCase() method to shadow the one defined in the super + // class. + static void SetUpTestCase() {} + + // Tears down the stuff shared by all tests in this test case. + // + // Google Test will call Foo::TearDownTestCase() after running the last + // test in test case Foo. Hence a sub-class can define its own + // TearDownTestCase() method to shadow the one defined in the super + // class. + static void TearDownTestCase() {} + + // Returns true iff the current test has a fatal failure. + static bool HasFatalFailure(); + + // Returns true iff the current test has a non-fatal failure. + static bool HasNonfatalFailure(); + + // Returns true iff the current test has a (either fatal or + // non-fatal) failure. + static bool HasFailure() { return HasFatalFailure() || HasNonfatalFailure(); } + + // Logs a property for the current test. Only the last value for a given + // key is remembered. + // These are public static so they can be called from utility functions + // that are not members of the test fixture. + // The arguments are const char* instead strings, as Google Test is used + // on platforms where string doesn't compile. + // + // Note that a driving consideration for these RecordProperty methods + // was to produce xml output suited to the Greenspan charting utility, + // which at present will only chart values that fit in a 32-bit int. It + // is the user's responsibility to restrict their values to 32-bit ints + // if they intend them to be used with Greenspan. + static void RecordProperty(const char* key, const char* value); + static void RecordProperty(const char* key, int value); + + protected: + // Creates a Test object. + Test(); + + // Sets up the test fixture. + virtual void SetUp(); + + // Tears down the test fixture. + virtual void TearDown(); + + private: + // Returns true iff the current test has the same fixture class as + // the first test in the current test case. + static bool HasSameFixtureClass(); + + // Runs the test after the test fixture has been set up. + // + // A sub-class must implement this to define the test logic. + // + // DO NOT OVERRIDE THIS FUNCTION DIRECTLY IN A USER PROGRAM. + // Instead, use the TEST or TEST_F macro. + virtual void TestBody() = 0; + + // Sets up, executes, and tears down the test. + void Run(); + + // Uses a GTestFlagSaver to save and restore all Google Test flags. + const internal::GTestFlagSaver* const gtest_flag_saver_; + + // Often a user mis-spells SetUp() as Setup() and spends a long time + // wondering why it is never called by Google Test. The declaration of + // the following method is solely for catching such an error at + // compile time: + // + // - The return type is deliberately chosen to be not void, so it + // will be a conflict if a user declares void Setup() in his test + // fixture. + // + // - This method is private, so it will be another compiler error + // if a user calls it from his test fixture. + // + // DO NOT OVERRIDE THIS FUNCTION. + // + // If you see an error about overriding the following function or + // about it being private, you have mis-spelled SetUp() as Setup(). + struct Setup_should_be_spelled_SetUp {}; + virtual Setup_should_be_spelled_SetUp* Setup() { return NULL; } + + // We disallow copying Tests. + GTEST_DISALLOW_COPY_AND_ASSIGN_(Test); +}; + +typedef internal::TimeInMillis TimeInMillis; + +// A copyable object representing a user specified test property which can be +// output as a key/value string pair. +// +// Don't inherit from TestProperty as its destructor is not virtual. +class TestProperty { + public: + // C'tor. TestProperty does NOT have a default constructor. + // Always use this constructor (with parameters) to create a + // TestProperty object. + TestProperty(const char* a_key, const char* a_value) : + key_(a_key), value_(a_value) { + } + + // Gets the user supplied key. + const char* key() const { + return key_.c_str(); + } + + // Gets the user supplied value. + const char* value() const { + return value_.c_str(); + } + + // Sets a new value, overriding the one supplied in the constructor. + void SetValue(const char* new_value) { + value_ = new_value; + } + + private: + // The key supplied by the user. + internal::String key_; + // The value supplied by the user. + internal::String value_; +}; + +// The result of a single Test. This includes a list of +// TestPartResults, a list of TestProperties, a count of how many +// death tests there are in the Test, and how much time it took to run +// the Test. +// +// TestResult is not copyable. +class GTEST_API_ TestResult { + public: + // Creates an empty TestResult. + TestResult(); + + // D'tor. Do not inherit from TestResult. + ~TestResult(); + + // Gets the number of all test parts. This is the sum of the number + // of successful test parts and the number of failed test parts. + int total_part_count() const; + + // Returns the number of the test properties. + int test_property_count() const; + + // Returns true iff the test passed (i.e. no test part failed). + bool Passed() const { return !Failed(); } + + // Returns true iff the test failed. + bool Failed() const; + + // Returns true iff the test fatally failed. + bool HasFatalFailure() const; + + // Returns true iff the test has a non-fatal failure. + bool HasNonfatalFailure() const; + + // Returns the elapsed time, in milliseconds. + TimeInMillis elapsed_time() const { return elapsed_time_; } + + // Returns the i-th test part result among all the results. i can range + // from 0 to test_property_count() - 1. If i is not in that range, aborts + // the program. + const TestPartResult& GetTestPartResult(int i) const; + + // Returns the i-th test property. i can range from 0 to + // test_property_count() - 1. If i is not in that range, aborts the + // program. + const TestProperty& GetTestProperty(int i) const; + + private: + friend class TestInfo; + friend class UnitTest; + friend class internal::DefaultGlobalTestPartResultReporter; + friend class internal::ExecDeathTest; + friend class internal::TestInfoImpl; + friend class internal::TestResultAccessor; + friend class internal::UnitTestImpl; + friend class internal::WindowsDeathTest; + + // Gets the vector of TestPartResults. + const std::vector& test_part_results() const { + return test_part_results_; + } + + // Gets the vector of TestProperties. + const std::vector& test_properties() const { + return test_properties_; + } + + // Sets the elapsed time. + void set_elapsed_time(TimeInMillis elapsed) { elapsed_time_ = elapsed; } + + // Adds a test property to the list. The property is validated and may add + // a non-fatal failure if invalid (e.g., if it conflicts with reserved + // key names). If a property is already recorded for the same key, the + // value will be updated, rather than storing multiple values for the same + // key. + void RecordProperty(const TestProperty& test_property); + + // Adds a failure if the key is a reserved attribute of Google Test + // testcase tags. Returns true if the property is valid. + // TODO(russr): Validate attribute names are legal and human readable. + static bool ValidateTestProperty(const TestProperty& test_property); + + // Adds a test part result to the list. + void AddTestPartResult(const TestPartResult& test_part_result); + + // Returns the death test count. + int death_test_count() const { return death_test_count_; } + + // Increments the death test count, returning the new count. + int increment_death_test_count() { return ++death_test_count_; } + + // Clears the test part results. + void ClearTestPartResults(); + + // Clears the object. + void Clear(); + + // Protects mutable state of the property vector and of owned + // properties, whose values may be updated. + internal::Mutex test_properites_mutex_; + + // The vector of TestPartResults + std::vector test_part_results_; + // The vector of TestProperties + std::vector test_properties_; + // Running count of death tests. + int death_test_count_; + // The elapsed time, in milliseconds. + TimeInMillis elapsed_time_; + + // We disallow copying TestResult. + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestResult); +}; // class TestResult + +// A TestInfo object stores the following information about a test: +// +// Test case name +// Test name +// Whether the test should be run +// A function pointer that creates the test object when invoked +// Test result +// +// The constructor of TestInfo registers itself with the UnitTest +// singleton such that the RUN_ALL_TESTS() macro knows which tests to +// run. +class GTEST_API_ TestInfo { + public: + // Destructs a TestInfo object. This function is not virtual, so + // don't inherit from TestInfo. + ~TestInfo(); + + // Returns the test case name. + const char* test_case_name() const; + + // Returns the test name. + const char* name() const; + + // Returns the test case comment. + const char* test_case_comment() const; + + // Returns the test comment. + const char* comment() const; + + // Returns true if this test should run, that is if the test is not disabled + // (or it is disabled but the also_run_disabled_tests flag has been specified) + // and its full name matches the user-specified filter. + // + // Google Test allows the user to filter the tests by their full names. + // The full name of a test Bar in test case Foo is defined as + // "Foo.Bar". Only the tests that match the filter will run. + // + // A filter is a colon-separated list of glob (not regex) patterns, + // optionally followed by a '-' and a colon-separated list of + // negative patterns (tests to exclude). A test is run if it + // matches one of the positive patterns and does not match any of + // the negative patterns. + // + // For example, *A*:Foo.* is a filter that matches any string that + // contains the character 'A' or starts with "Foo.". + bool should_run() const; + + // Returns the result of the test. + const TestResult* result() const; + + private: +#if GTEST_HAS_DEATH_TEST + friend class internal::DefaultDeathTestFactory; +#endif // GTEST_HAS_DEATH_TEST + friend class Test; + friend class TestCase; + friend class internal::TestInfoImpl; + friend class internal::UnitTestImpl; + friend TestInfo* internal::MakeAndRegisterTestInfo( + const char* test_case_name, const char* name, + const char* test_case_comment, const char* comment, + internal::TypeId fixture_class_id, + Test::SetUpTestCaseFunc set_up_tc, + Test::TearDownTestCaseFunc tear_down_tc, + internal::TestFactoryBase* factory); + + // Returns true if this test matches the user-specified filter. + bool matches_filter() const; + + // Increments the number of death tests encountered in this test so + // far. + int increment_death_test_count(); + + // Accessors for the implementation object. + internal::TestInfoImpl* impl() { return impl_; } + const internal::TestInfoImpl* impl() const { return impl_; } + + // Constructs a TestInfo object. The newly constructed instance assumes + // ownership of the factory object. + TestInfo(const char* test_case_name, const char* name, + const char* test_case_comment, const char* comment, + internal::TypeId fixture_class_id, + internal::TestFactoryBase* factory); + + // An opaque implementation object. + internal::TestInfoImpl* impl_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestInfo); +}; + +// A test case, which consists of a vector of TestInfos. +// +// TestCase is not copyable. +class GTEST_API_ TestCase { + public: + // Creates a TestCase with the given name. + // + // TestCase does NOT have a default constructor. Always use this + // constructor to create a TestCase object. + // + // Arguments: + // + // name: name of the test case + // set_up_tc: pointer to the function that sets up the test case + // tear_down_tc: pointer to the function that tears down the test case + TestCase(const char* name, const char* comment, + Test::SetUpTestCaseFunc set_up_tc, + Test::TearDownTestCaseFunc tear_down_tc); + + // Destructor of TestCase. + virtual ~TestCase(); + + // Gets the name of the TestCase. + const char* name() const { return name_.c_str(); } + + // Returns the test case comment. + const char* comment() const { return comment_.c_str(); } + + // Returns true if any test in this test case should run. + bool should_run() const { return should_run_; } + + // Gets the number of successful tests in this test case. + int successful_test_count() const; + + // Gets the number of failed tests in this test case. + int failed_test_count() const; + + // Gets the number of disabled tests in this test case. + int disabled_test_count() const; + + // Get the number of tests in this test case that should run. + int test_to_run_count() const; + + // Gets the number of all tests in this test case. + int total_test_count() const; + + // Returns true iff the test case passed. + bool Passed() const { return !Failed(); } + + // Returns true iff the test case failed. + bool Failed() const { return failed_test_count() > 0; } + + // Returns the elapsed time, in milliseconds. + TimeInMillis elapsed_time() const { return elapsed_time_; } + + // Returns the i-th test among all the tests. i can range from 0 to + // total_test_count() - 1. If i is not in that range, returns NULL. + const TestInfo* GetTestInfo(int i) const; + + private: + friend class Test; + friend class internal::UnitTestImpl; + + // Gets the (mutable) vector of TestInfos in this TestCase. + std::vector& test_info_list() { return test_info_list_; } + + // Gets the (immutable) vector of TestInfos in this TestCase. + const std::vector& test_info_list() const { + return test_info_list_; + } + + // Returns the i-th test among all the tests. i can range from 0 to + // total_test_count() - 1. If i is not in that range, returns NULL. + TestInfo* GetMutableTestInfo(int i); + + // Sets the should_run member. + void set_should_run(bool should) { should_run_ = should; } + + // Adds a TestInfo to this test case. Will delete the TestInfo upon + // destruction of the TestCase object. + void AddTestInfo(TestInfo * test_info); + + // Clears the results of all tests in this test case. + void ClearResult(); + + // Clears the results of all tests in the given test case. + static void ClearTestCaseResult(TestCase* test_case) { + test_case->ClearResult(); + } + + // Runs every test in this TestCase. + void Run(); + + // Returns true iff test passed. + static bool TestPassed(const TestInfo * test_info); + + // Returns true iff test failed. + static bool TestFailed(const TestInfo * test_info); + + // Returns true iff test is disabled. + static bool TestDisabled(const TestInfo * test_info); + + // Returns true if the given test should run. + static bool ShouldRunTest(const TestInfo *test_info); + + // Shuffles the tests in this test case. + void ShuffleTests(internal::Random* random); + + // Restores the test order to before the first shuffle. + void UnshuffleTests(); + + // Name of the test case. + internal::String name_; + // Comment on the test case. + internal::String comment_; + // The vector of TestInfos in their original order. It owns the + // elements in the vector. + std::vector test_info_list_; + // Provides a level of indirection for the test list to allow easy + // shuffling and restoring the test order. The i-th element in this + // vector is the index of the i-th test in the shuffled test list. + std::vector test_indices_; + // Pointer to the function that sets up the test case. + Test::SetUpTestCaseFunc set_up_tc_; + // Pointer to the function that tears down the test case. + Test::TearDownTestCaseFunc tear_down_tc_; + // True iff any test in this test case should run. + bool should_run_; + // Elapsed time, in milliseconds. + TimeInMillis elapsed_time_; + + // We disallow copying TestCases. + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestCase); +}; + +// An Environment object is capable of setting up and tearing down an +// environment. The user should subclass this to define his own +// environment(s). +// +// An Environment object does the set-up and tear-down in virtual +// methods SetUp() and TearDown() instead of the constructor and the +// destructor, as: +// +// 1. You cannot safely throw from a destructor. This is a problem +// as in some cases Google Test is used where exceptions are enabled, and +// we may want to implement ASSERT_* using exceptions where they are +// available. +// 2. You cannot use ASSERT_* directly in a constructor or +// destructor. +class Environment { + public: + // The d'tor is virtual as we need to subclass Environment. + virtual ~Environment() {} + + // Override this to define how to set up the environment. + virtual void SetUp() {} + + // Override this to define how to tear down the environment. + virtual void TearDown() {} + private: + // If you see an error about overriding the following function or + // about it being private, you have mis-spelled SetUp() as Setup(). + struct Setup_should_be_spelled_SetUp {}; + virtual Setup_should_be_spelled_SetUp* Setup() { return NULL; } +}; + +// The interface for tracing execution of tests. The methods are organized in +// the order the corresponding events are fired. +class TestEventListener { + public: + virtual ~TestEventListener() {} + + // Fired before any test activity starts. + virtual void OnTestProgramStart(const UnitTest& unit_test) = 0; + + // Fired before each iteration of tests starts. There may be more than + // one iteration if GTEST_FLAG(repeat) is set. iteration is the iteration + // index, starting from 0. + virtual void OnTestIterationStart(const UnitTest& unit_test, + int iteration) = 0; + + // Fired before environment set-up for each iteration of tests starts. + virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test) = 0; + + // Fired after environment set-up for each iteration of tests ends. + virtual void OnEnvironmentsSetUpEnd(const UnitTest& unit_test) = 0; + + // Fired before the test case starts. + virtual void OnTestCaseStart(const TestCase& test_case) = 0; + + // Fired before the test starts. + virtual void OnTestStart(const TestInfo& test_info) = 0; + + // Fired after a failed assertion or a SUCCESS(). + virtual void OnTestPartResult(const TestPartResult& test_part_result) = 0; + + // Fired after the test ends. + virtual void OnTestEnd(const TestInfo& test_info) = 0; + + // Fired after the test case ends. + virtual void OnTestCaseEnd(const TestCase& test_case) = 0; + + // Fired before environment tear-down for each iteration of tests starts. + virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test) = 0; + + // Fired after environment tear-down for each iteration of tests ends. + virtual void OnEnvironmentsTearDownEnd(const UnitTest& unit_test) = 0; + + // Fired after each iteration of tests finishes. + virtual void OnTestIterationEnd(const UnitTest& unit_test, + int iteration) = 0; + + // Fired after all test activities have ended. + virtual void OnTestProgramEnd(const UnitTest& unit_test) = 0; +}; + +// The convenience class for users who need to override just one or two +// methods and are not concerned that a possible change to a signature of +// the methods they override will not be caught during the build. For +// comments about each method please see the definition of TestEventListener +// above. +class EmptyTestEventListener : public TestEventListener { + public: + virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) {} + virtual void OnTestIterationStart(const UnitTest& /*unit_test*/, + int /*iteration*/) {} + virtual void OnEnvironmentsSetUpStart(const UnitTest& /*unit_test*/) {} + virtual void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) {} + virtual void OnTestCaseStart(const TestCase& /*test_case*/) {} + virtual void OnTestStart(const TestInfo& /*test_info*/) {} + virtual void OnTestPartResult(const TestPartResult& /*test_part_result*/) {} + virtual void OnTestEnd(const TestInfo& /*test_info*/) {} + virtual void OnTestCaseEnd(const TestCase& /*test_case*/) {} + virtual void OnEnvironmentsTearDownStart(const UnitTest& /*unit_test*/) {} + virtual void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) {} + virtual void OnTestIterationEnd(const UnitTest& /*unit_test*/, + int /*iteration*/) {} + virtual void OnTestProgramEnd(const UnitTest& /*unit_test*/) {} +}; + +// TestEventListeners lets users add listeners to track events in Google Test. +class GTEST_API_ TestEventListeners { + public: + TestEventListeners(); + ~TestEventListeners(); + + // Appends an event listener to the end of the list. Google Test assumes + // the ownership of the listener (i.e. it will delete the listener when + // the test program finishes). + void Append(TestEventListener* listener); + + // Removes the given event listener from the list and returns it. It then + // becomes the caller's responsibility to delete the listener. Returns + // NULL if the listener is not found in the list. + TestEventListener* Release(TestEventListener* listener); + + // Returns the standard listener responsible for the default console + // output. Can be removed from the listeners list to shut down default + // console output. Note that removing this object from the listener list + // with Release transfers its ownership to the caller and makes this + // function return NULL the next time. + TestEventListener* default_result_printer() const { + return default_result_printer_; + } + + // Returns the standard listener responsible for the default XML output + // controlled by the --gtest_output=xml flag. Can be removed from the + // listeners list by users who want to shut down the default XML output + // controlled by this flag and substitute it with custom one. Note that + // removing this object from the listener list with Release transfers its + // ownership to the caller and makes this function return NULL the next + // time. + TestEventListener* default_xml_generator() const { + return default_xml_generator_; + } + + private: + friend class TestCase; + friend class internal::DefaultGlobalTestPartResultReporter; + friend class internal::NoExecDeathTest; + friend class internal::TestEventListenersAccessor; + friend class internal::TestInfoImpl; + friend class internal::UnitTestImpl; + + // Returns repeater that broadcasts the TestEventListener events to all + // subscribers. + TestEventListener* repeater(); + + // Sets the default_result_printer attribute to the provided listener. + // The listener is also added to the listener list and previous + // default_result_printer is removed from it and deleted. The listener can + // also be NULL in which case it will not be added to the list. Does + // nothing if the previous and the current listener objects are the same. + void SetDefaultResultPrinter(TestEventListener* listener); + + // Sets the default_xml_generator attribute to the provided listener. The + // listener is also added to the listener list and previous + // default_xml_generator is removed from it and deleted. The listener can + // also be NULL in which case it will not be added to the list. Does + // nothing if the previous and the current listener objects are the same. + void SetDefaultXmlGenerator(TestEventListener* listener); + + // Controls whether events will be forwarded by the repeater to the + // listeners in the list. + bool EventForwardingEnabled() const; + void SuppressEventForwarding(); + + // The actual list of listeners. + internal::TestEventRepeater* repeater_; + // Listener responsible for the standard result output. + TestEventListener* default_result_printer_; + // Listener responsible for the creation of the XML output file. + TestEventListener* default_xml_generator_; + + // We disallow copying TestEventListeners. + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestEventListeners); +}; + +// A UnitTest consists of a vector of TestCases. +// +// This is a singleton class. The only instance of UnitTest is +// created when UnitTest::GetInstance() is first called. This +// instance is never deleted. +// +// UnitTest is not copyable. +// +// This class is thread-safe as long as the methods are called +// according to their specification. +class GTEST_API_ UnitTest { + public: + // Gets the singleton UnitTest object. The first time this method + // is called, a UnitTest object is constructed and returned. + // Consecutive calls will return the same object. + static UnitTest* GetInstance(); + + // Runs all tests in this UnitTest object and prints the result. + // Returns 0 if successful, or 1 otherwise. + // + // This method can only be called from the main thread. + // + // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. + int Run() GTEST_MUST_USE_RESULT_; + + // Returns the working directory when the first TEST() or TEST_F() + // was executed. The UnitTest object owns the string. + const char* original_working_dir() const; + + // Returns the TestCase object for the test that's currently running, + // or NULL if no test is running. + const TestCase* current_test_case() const; + + // Returns the TestInfo object for the test that's currently running, + // or NULL if no test is running. + const TestInfo* current_test_info() const; + + // Returns the random seed used at the start of the current test run. + int random_seed() const; + +#if GTEST_HAS_PARAM_TEST + // Returns the ParameterizedTestCaseRegistry object used to keep track of + // value-parameterized tests and instantiate and register them. + // + // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. + internal::ParameterizedTestCaseRegistry& parameterized_test_registry(); +#endif // GTEST_HAS_PARAM_TEST + + // Gets the number of successful test cases. + int successful_test_case_count() const; + + // Gets the number of failed test cases. + int failed_test_case_count() const; + + // Gets the number of all test cases. + int total_test_case_count() const; + + // Gets the number of all test cases that contain at least one test + // that should run. + int test_case_to_run_count() const; + + // Gets the number of successful tests. + int successful_test_count() const; + + // Gets the number of failed tests. + int failed_test_count() const; + + // Gets the number of disabled tests. + int disabled_test_count() const; + + // Gets the number of all tests. + int total_test_count() const; + + // Gets the number of tests that should run. + int test_to_run_count() const; + + // Gets the elapsed time, in milliseconds. + TimeInMillis elapsed_time() const; + + // Returns true iff the unit test passed (i.e. all test cases passed). + bool Passed() const; + + // Returns true iff the unit test failed (i.e. some test case failed + // or something outside of all tests failed). + bool Failed() const; + + // Gets the i-th test case among all the test cases. i can range from 0 to + // total_test_case_count() - 1. If i is not in that range, returns NULL. + const TestCase* GetTestCase(int i) const; + + // Returns the list of event listeners that can be used to track events + // inside Google Test. + TestEventListeners& listeners(); + + private: + // Registers and returns a global test environment. When a test + // program is run, all global test environments will be set-up in + // the order they were registered. After all tests in the program + // have finished, all global test environments will be torn-down in + // the *reverse* order they were registered. + // + // The UnitTest object takes ownership of the given environment. + // + // This method can only be called from the main thread. + Environment* AddEnvironment(Environment* env); + + // Adds a TestPartResult to the current TestResult object. All + // Google Test assertion macros (e.g. ASSERT_TRUE, EXPECT_EQ, etc) + // eventually call this to report their results. The user code + // should use the assertion macros instead of calling this directly. + void AddTestPartResult(TestPartResult::Type result_type, + const char* file_name, + int line_number, + const internal::String& message, + const internal::String& os_stack_trace); + + // Adds a TestProperty to the current TestResult object. If the result already + // contains a property with the same key, the value will be updated. + void RecordPropertyForCurrentTest(const char* key, const char* value); + + // Gets the i-th test case among all the test cases. i can range from 0 to + // total_test_case_count() - 1. If i is not in that range, returns NULL. + TestCase* GetMutableTestCase(int i); + + // Accessors for the implementation object. + internal::UnitTestImpl* impl() { return impl_; } + const internal::UnitTestImpl* impl() const { return impl_; } + + // These classes and funcions are friends as they need to access private + // members of UnitTest. + friend class Test; + friend class internal::AssertHelper; + friend class internal::ScopedTrace; + friend Environment* AddGlobalTestEnvironment(Environment* env); + friend internal::UnitTestImpl* internal::GetUnitTestImpl(); + friend void internal::ReportFailureInUnknownLocation( + TestPartResult::Type result_type, + const internal::String& message); + + // Creates an empty UnitTest. + UnitTest(); + + // D'tor + virtual ~UnitTest(); + + // Pushes a trace defined by SCOPED_TRACE() on to the per-thread + // Google Test trace stack. + void PushGTestTrace(const internal::TraceInfo& trace); + + // Pops a trace from the per-thread Google Test trace stack. + void PopGTestTrace(); + + // Protects mutable state in *impl_. This is mutable as some const + // methods need to lock it too. + mutable internal::Mutex mutex_; + + // Opaque implementation object. This field is never changed once + // the object is constructed. We don't mark it as const here, as + // doing so will cause a warning in the constructor of UnitTest. + // Mutable state in *impl_ is protected by mutex_. + internal::UnitTestImpl* impl_; + + // We disallow copying UnitTest. + GTEST_DISALLOW_COPY_AND_ASSIGN_(UnitTest); +}; + +// A convenient wrapper for adding an environment for the test +// program. +// +// You should call this before RUN_ALL_TESTS() is called, probably in +// main(). If you use gtest_main, you need to call this before main() +// starts for it to take effect. For example, you can define a global +// variable like this: +// +// testing::Environment* const foo_env = +// testing::AddGlobalTestEnvironment(new FooEnvironment); +// +// However, we strongly recommend you to write your own main() and +// call AddGlobalTestEnvironment() there, as relying on initialization +// of global variables makes the code harder to read and may cause +// problems when you register multiple environments from different +// translation units and the environments have dependencies among them +// (remember that the compiler doesn't guarantee the order in which +// global variables from different translation units are initialized). +inline Environment* AddGlobalTestEnvironment(Environment* env) { + return UnitTest::GetInstance()->AddEnvironment(env); +} + +// Initializes Google Test. This must be called before calling +// RUN_ALL_TESTS(). In particular, it parses a command line for the +// flags that Google Test recognizes. Whenever a Google Test flag is +// seen, it is removed from argv, and *argc is decremented. +// +// No value is returned. Instead, the Google Test flag variables are +// updated. +// +// Calling the function for the second time has no user-visible effect. +GTEST_API_ void InitGoogleTest(int* argc, char** argv); + +// This overloaded version can be used in Windows programs compiled in +// UNICODE mode. +GTEST_API_ void InitGoogleTest(int* argc, wchar_t** argv); + +namespace internal { + +// These overloaded versions handle ::std::string and ::std::wstring. +GTEST_API_ inline String FormatForFailureMessage(const ::std::string& str) { + return (Message() << '"' << str << '"').GetString(); +} + +#if GTEST_HAS_STD_WSTRING +GTEST_API_ inline String FormatForFailureMessage(const ::std::wstring& wstr) { + return (Message() << "L\"" << wstr << '"').GetString(); +} +#endif // GTEST_HAS_STD_WSTRING + +// These overloaded versions handle ::string and ::wstring. +#if GTEST_HAS_GLOBAL_STRING +GTEST_API_ inline String FormatForFailureMessage(const ::string& str) { + return (Message() << '"' << str << '"').GetString(); +} +#endif // GTEST_HAS_GLOBAL_STRING + +#if GTEST_HAS_GLOBAL_WSTRING +GTEST_API_ inline String FormatForFailureMessage(const ::wstring& wstr) { + return (Message() << "L\"" << wstr << '"').GetString(); +} +#endif // GTEST_HAS_GLOBAL_WSTRING + +// Formats a comparison assertion (e.g. ASSERT_EQ, EXPECT_LT, and etc) +// operand to be used in a failure message. The type (but not value) +// of the other operand may affect the format. This allows us to +// print a char* as a raw pointer when it is compared against another +// char*, and print it as a C string when it is compared against an +// std::string object, for example. +// +// The default implementation ignores the type of the other operand. +// Some specialized versions are used to handle formatting wide or +// narrow C strings. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +template +String FormatForComparisonFailureMessage(const T1& value, + const T2& /* other_operand */) { + return FormatForFailureMessage(value); +} + +// The helper function for {ASSERT|EXPECT}_EQ. +template +AssertionResult CmpHelperEQ(const char* expected_expression, + const char* actual_expression, + const T1& expected, + const T2& actual) { +#ifdef _MSC_VER +#pragma warning(push) // Saves the current warning state. +#pragma warning(disable:4389) // Temporarily disables warning on + // signed/unsigned mismatch. +#endif + + if (expected == actual) { + return AssertionSuccess(); + } + +#ifdef _MSC_VER +#pragma warning(pop) // Restores the warning state. +#endif + + return EqFailure(expected_expression, + actual_expression, + FormatForComparisonFailureMessage(expected, actual), + FormatForComparisonFailureMessage(actual, expected), + false); +} + +// With this overloaded version, we allow anonymous enums to be used +// in {ASSERT|EXPECT}_EQ when compiled with gcc 4, as anonymous enums +// can be implicitly cast to BiggestInt. +GTEST_API_ AssertionResult CmpHelperEQ(const char* expected_expression, + const char* actual_expression, + BiggestInt expected, + BiggestInt actual); + +// The helper class for {ASSERT|EXPECT}_EQ. The template argument +// lhs_is_null_literal is true iff the first argument to ASSERT_EQ() +// is a null pointer literal. The following default implementation is +// for lhs_is_null_literal being false. +template +class EqHelper { + public: + // This templatized version is for the general case. + template + static AssertionResult Compare(const char* expected_expression, + const char* actual_expression, + const T1& expected, + const T2& actual) { + return CmpHelperEQ(expected_expression, actual_expression, expected, + actual); + } + + // With this overloaded version, we allow anonymous enums to be used + // in {ASSERT|EXPECT}_EQ when compiled with gcc 4, as anonymous + // enums can be implicitly cast to BiggestInt. + // + // Even though its body looks the same as the above version, we + // cannot merge the two, as it will make anonymous enums unhappy. + static AssertionResult Compare(const char* expected_expression, + const char* actual_expression, + BiggestInt expected, + BiggestInt actual) { + return CmpHelperEQ(expected_expression, actual_expression, expected, + actual); + } +}; + +// This specialization is used when the first argument to ASSERT_EQ() +// is a null pointer literal. +template <> +class EqHelper { + public: + // We define two overloaded versions of Compare(). The first + // version will be picked when the second argument to ASSERT_EQ() is + // NOT a pointer, e.g. ASSERT_EQ(0, AnIntFunction()) or + // EXPECT_EQ(false, a_bool). + template + static AssertionResult Compare(const char* expected_expression, + const char* actual_expression, + const T1& expected, + const T2& actual) { + return CmpHelperEQ(expected_expression, actual_expression, expected, + actual); + } + + // This version will be picked when the second argument to + // ASSERT_EQ() is a pointer, e.g. ASSERT_EQ(NULL, a_pointer). + template + static AssertionResult Compare(const char* expected_expression, + const char* actual_expression, + const T1& /* expected */, + T2* actual) { + // We already know that 'expected' is a null pointer. + return CmpHelperEQ(expected_expression, actual_expression, + static_cast(NULL), actual); + } +}; + +// A macro for implementing the helper functions needed to implement +// ASSERT_?? and EXPECT_??. It is here just to avoid copy-and-paste +// of similar code. +// +// For each templatized helper function, we also define an overloaded +// version for BiggestInt in order to reduce code bloat and allow +// anonymous enums to be used with {ASSERT|EXPECT}_?? when compiled +// with gcc 4. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +#define GTEST_IMPL_CMP_HELPER_(op_name, op)\ +template \ +AssertionResult CmpHelper##op_name(const char* expr1, const char* expr2, \ + const T1& val1, const T2& val2) {\ + if (val1 op val2) {\ + return AssertionSuccess();\ + } else {\ + Message msg;\ + msg << "Expected: (" << expr1 << ") " #op " (" << expr2\ + << "), actual: " << FormatForComparisonFailureMessage(val1, val2)\ + << " vs " << FormatForComparisonFailureMessage(val2, val1);\ + return AssertionFailure(msg);\ + }\ +}\ +GTEST_API_ AssertionResult CmpHelper##op_name(\ + const char* expr1, const char* expr2, BiggestInt val1, BiggestInt val2) + +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. + +// Implements the helper function for {ASSERT|EXPECT}_NE +GTEST_IMPL_CMP_HELPER_(NE, !=); +// Implements the helper function for {ASSERT|EXPECT}_LE +GTEST_IMPL_CMP_HELPER_(LE, <=); +// Implements the helper function for {ASSERT|EXPECT}_LT +GTEST_IMPL_CMP_HELPER_(LT, < ); +// Implements the helper function for {ASSERT|EXPECT}_GE +GTEST_IMPL_CMP_HELPER_(GE, >=); +// Implements the helper function for {ASSERT|EXPECT}_GT +GTEST_IMPL_CMP_HELPER_(GT, > ); + +#undef GTEST_IMPL_CMP_HELPER_ + +// The helper function for {ASSERT|EXPECT}_STREQ. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +GTEST_API_ AssertionResult CmpHelperSTREQ(const char* expected_expression, + const char* actual_expression, + const char* expected, + const char* actual); + +// The helper function for {ASSERT|EXPECT}_STRCASEEQ. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +GTEST_API_ AssertionResult CmpHelperSTRCASEEQ(const char* expected_expression, + const char* actual_expression, + const char* expected, + const char* actual); + +// The helper function for {ASSERT|EXPECT}_STRNE. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +GTEST_API_ AssertionResult CmpHelperSTRNE(const char* s1_expression, + const char* s2_expression, + const char* s1, + const char* s2); + +// The helper function for {ASSERT|EXPECT}_STRCASENE. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +GTEST_API_ AssertionResult CmpHelperSTRCASENE(const char* s1_expression, + const char* s2_expression, + const char* s1, + const char* s2); + + +// Helper function for *_STREQ on wide strings. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +GTEST_API_ AssertionResult CmpHelperSTREQ(const char* expected_expression, + const char* actual_expression, + const wchar_t* expected, + const wchar_t* actual); + +// Helper function for *_STRNE on wide strings. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +GTEST_API_ AssertionResult CmpHelperSTRNE(const char* s1_expression, + const char* s2_expression, + const wchar_t* s1, + const wchar_t* s2); + +} // namespace internal + +// IsSubstring() and IsNotSubstring() are intended to be used as the +// first argument to {EXPECT,ASSERT}_PRED_FORMAT2(), not by +// themselves. They check whether needle is a substring of haystack +// (NULL is considered a substring of itself only), and return an +// appropriate error message when they fail. +// +// The {needle,haystack}_expr arguments are the stringified +// expressions that generated the two real arguments. +GTEST_API_ AssertionResult IsSubstring( + const char* needle_expr, const char* haystack_expr, + const char* needle, const char* haystack); +GTEST_API_ AssertionResult IsSubstring( + const char* needle_expr, const char* haystack_expr, + const wchar_t* needle, const wchar_t* haystack); +GTEST_API_ AssertionResult IsNotSubstring( + const char* needle_expr, const char* haystack_expr, + const char* needle, const char* haystack); +GTEST_API_ AssertionResult IsNotSubstring( + const char* needle_expr, const char* haystack_expr, + const wchar_t* needle, const wchar_t* haystack); +GTEST_API_ AssertionResult IsSubstring( + const char* needle_expr, const char* haystack_expr, + const ::std::string& needle, const ::std::string& haystack); +GTEST_API_ AssertionResult IsNotSubstring( + const char* needle_expr, const char* haystack_expr, + const ::std::string& needle, const ::std::string& haystack); + +#if GTEST_HAS_STD_WSTRING +GTEST_API_ AssertionResult IsSubstring( + const char* needle_expr, const char* haystack_expr, + const ::std::wstring& needle, const ::std::wstring& haystack); +GTEST_API_ AssertionResult IsNotSubstring( + const char* needle_expr, const char* haystack_expr, + const ::std::wstring& needle, const ::std::wstring& haystack); +#endif // GTEST_HAS_STD_WSTRING + +namespace internal { + +// Helper template function for comparing floating-points. +// +// Template parameter: +// +// RawType: the raw floating-point type (either float or double) +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +template +AssertionResult CmpHelperFloatingPointEQ(const char* expected_expression, + const char* actual_expression, + RawType expected, + RawType actual) { + const FloatingPoint lhs(expected), rhs(actual); + + if (lhs.AlmostEquals(rhs)) { + return AssertionSuccess(); + } + + StrStream expected_ss; + expected_ss << std::setprecision(std::numeric_limits::digits10 + 2) + << expected; + + StrStream actual_ss; + actual_ss << std::setprecision(std::numeric_limits::digits10 + 2) + << actual; + + return EqFailure(expected_expression, + actual_expression, + StrStreamToString(&expected_ss), + StrStreamToString(&actual_ss), + false); +} + +// Helper function for implementing ASSERT_NEAR. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +GTEST_API_ AssertionResult DoubleNearPredFormat(const char* expr1, + const char* expr2, + const char* abs_error_expr, + double val1, + double val2, + double abs_error); + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// A class that enables one to stream messages to assertion macros +class GTEST_API_ AssertHelper { + public: + // Constructor. + AssertHelper(TestPartResult::Type type, + const char* file, + int line, + const char* message); + ~AssertHelper(); + + // Message assignment is a semantic trick to enable assertion + // streaming; see the GTEST_MESSAGE_ macro below. + void operator=(const Message& message) const; + + private: + // We put our data in a struct so that the size of the AssertHelper class can + // be as small as possible. This is important because gcc is incapable of + // re-using stack space even for temporary variables, so every EXPECT_EQ + // reserves stack space for another AssertHelper. + struct AssertHelperData { + AssertHelperData(TestPartResult::Type t, + const char* srcfile, + int line_num, + const char* msg) + : type(t), file(srcfile), line(line_num), message(msg) { } + + TestPartResult::Type const type; + const char* const file; + int const line; + String const message; + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(AssertHelperData); + }; + + AssertHelperData* const data_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(AssertHelper); +}; + +} // namespace internal + +#if GTEST_HAS_PARAM_TEST +// The abstract base class that all value-parameterized tests inherit from. +// +// This class adds support for accessing the test parameter value via +// the GetParam() method. +// +// Use it with one of the parameter generator defining functions, like Range(), +// Values(), ValuesIn(), Bool(), and Combine(). +// +// class FooTest : public ::testing::TestWithParam { +// protected: +// FooTest() { +// // Can use GetParam() here. +// } +// virtual ~FooTest() { +// // Can use GetParam() here. +// } +// virtual void SetUp() { +// // Can use GetParam() here. +// } +// virtual void TearDown { +// // Can use GetParam() here. +// } +// }; +// TEST_P(FooTest, DoesBar) { +// // Can use GetParam() method here. +// Foo foo; +// ASSERT_TRUE(foo.DoesBar(GetParam())); +// } +// INSTANTIATE_TEST_CASE_P(OneToTenRange, FooTest, ::testing::Range(1, 10)); + +template +class TestWithParam : public Test { + public: + typedef T ParamType; + + // The current parameter value. Is also available in the test fixture's + // constructor. + const ParamType& GetParam() const { return *parameter_; } + + private: + // Sets parameter value. The caller is responsible for making sure the value + // remains alive and unchanged throughout the current test. + static void SetParam(const ParamType* parameter) { + parameter_ = parameter; + } + + // Static value used for accessing parameter during a test lifetime. + static const ParamType* parameter_; + + // TestClass must be a subclass of TestWithParam. + template friend class internal::ParameterizedTestFactory; +}; + +template +const T* TestWithParam::parameter_ = NULL; + +#endif // GTEST_HAS_PARAM_TEST + +// Macros for indicating success/failure in test code. + +// ADD_FAILURE unconditionally adds a failure to the current test. +// SUCCEED generates a success - it doesn't automatically make the +// current test successful, as a test is only successful when it has +// no failure. +// +// EXPECT_* verifies that a certain condition is satisfied. If not, +// it behaves like ADD_FAILURE. In particular: +// +// EXPECT_TRUE verifies that a Boolean condition is true. +// EXPECT_FALSE verifies that a Boolean condition is false. +// +// FAIL and ASSERT_* are similar to ADD_FAILURE and EXPECT_*, except +// that they will also abort the current function on failure. People +// usually want the fail-fast behavior of FAIL and ASSERT_*, but those +// writing data-driven tests often find themselves using ADD_FAILURE +// and EXPECT_* more. +// +// Examples: +// +// EXPECT_TRUE(server.StatusIsOK()); +// ASSERT_FALSE(server.HasPendingRequest(port)) +// << "There are still pending requests " << "on port " << port; + +// Generates a nonfatal failure with a generic message. +#define ADD_FAILURE() GTEST_NONFATAL_FAILURE_("Failed") + +// Generates a fatal failure with a generic message. +#define GTEST_FAIL() GTEST_FATAL_FAILURE_("Failed") + +// Define this macro to 1 to omit the definition of FAIL(), which is a +// generic name and clashes with some other libraries. +#if !GTEST_DONT_DEFINE_FAIL +#define FAIL() GTEST_FAIL() +#endif + +// Generates a success with a generic message. +#define GTEST_SUCCEED() GTEST_SUCCESS_("Succeeded") + +// Define this macro to 1 to omit the definition of SUCCEED(), which +// is a generic name and clashes with some other libraries. +#if !GTEST_DONT_DEFINE_SUCCEED +#define SUCCEED() GTEST_SUCCEED() +#endif + +// Macros for testing exceptions. +// +// * {ASSERT|EXPECT}_THROW(statement, expected_exception): +// Tests that the statement throws the expected exception. +// * {ASSERT|EXPECT}_NO_THROW(statement): +// Tests that the statement doesn't throw any exception. +// * {ASSERT|EXPECT}_ANY_THROW(statement): +// Tests that the statement throws an exception. + +#define EXPECT_THROW(statement, expected_exception) \ + GTEST_TEST_THROW_(statement, expected_exception, GTEST_NONFATAL_FAILURE_) +#define EXPECT_NO_THROW(statement) \ + GTEST_TEST_NO_THROW_(statement, GTEST_NONFATAL_FAILURE_) +#define EXPECT_ANY_THROW(statement) \ + GTEST_TEST_ANY_THROW_(statement, GTEST_NONFATAL_FAILURE_) +#define ASSERT_THROW(statement, expected_exception) \ + GTEST_TEST_THROW_(statement, expected_exception, GTEST_FATAL_FAILURE_) +#define ASSERT_NO_THROW(statement) \ + GTEST_TEST_NO_THROW_(statement, GTEST_FATAL_FAILURE_) +#define ASSERT_ANY_THROW(statement) \ + GTEST_TEST_ANY_THROW_(statement, GTEST_FATAL_FAILURE_) + +// Boolean assertions. Condition can be either a Boolean expression or an +// AssertionResult. For more information on how to use AssertionResult with +// these macros see comments on that class. +#define EXPECT_TRUE(condition) \ + GTEST_TEST_BOOLEAN_(condition, #condition, false, true, \ + GTEST_NONFATAL_FAILURE_) +#define EXPECT_FALSE(condition) \ + GTEST_TEST_BOOLEAN_(!(condition), #condition, true, false, \ + GTEST_NONFATAL_FAILURE_) +#define ASSERT_TRUE(condition) \ + GTEST_TEST_BOOLEAN_(condition, #condition, false, true, \ + GTEST_FATAL_FAILURE_) +#define ASSERT_FALSE(condition) \ + GTEST_TEST_BOOLEAN_(!(condition), #condition, true, false, \ + GTEST_FATAL_FAILURE_) + +// Includes the auto-generated header that implements a family of +// generic predicate assertion macros. +// Copyright 2006, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// This file is AUTOMATICALLY GENERATED on 10/02/2008 by command +// 'gen_gtest_pred_impl.py 5'. DO NOT EDIT BY HAND! +// +// Implements a family of generic predicate assertion macros. + +#ifndef GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ +#define GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ + +// Makes sure this header is not included before gtest.h. +#ifndef GTEST_INCLUDE_GTEST_GTEST_H_ +#error Do not include gtest_pred_impl.h directly. Include gtest.h instead. +#endif // GTEST_INCLUDE_GTEST_GTEST_H_ + +// This header implements a family of generic predicate assertion +// macros: +// +// ASSERT_PRED_FORMAT1(pred_format, v1) +// ASSERT_PRED_FORMAT2(pred_format, v1, v2) +// ... +// +// where pred_format is a function or functor that takes n (in the +// case of ASSERT_PRED_FORMATn) values and their source expression +// text, and returns a testing::AssertionResult. See the definition +// of ASSERT_EQ in gtest.h for an example. +// +// If you don't care about formatting, you can use the more +// restrictive version: +// +// ASSERT_PRED1(pred, v1) +// ASSERT_PRED2(pred, v1, v2) +// ... +// +// where pred is an n-ary function or functor that returns bool, +// and the values v1, v2, ..., must support the << operator for +// streaming to std::ostream. +// +// We also define the EXPECT_* variations. +// +// For now we only support predicates whose arity is at most 5. +// Please email googletestframework@googlegroups.com if you need +// support for higher arities. + +// GTEST_ASSERT_ is the basic statement to which all of the assertions +// in this file reduce. Don't use this in your code. + +#define GTEST_ASSERT_(expression, on_failure) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (const ::testing::AssertionResult gtest_ar = (expression)) \ + ; \ + else \ + on_failure(gtest_ar.failure_message()) + + +// Helper function for implementing {EXPECT|ASSERT}_PRED1. Don't use +// this in your code. +template +AssertionResult AssertPred1Helper(const char* pred_text, + const char* e1, + Pred pred, + const T1& v1) { + if (pred(v1)) return AssertionSuccess(); + + Message msg; + msg << pred_text << "(" + << e1 << ") evaluates to false, where" + << "\n" << e1 << " evaluates to " << v1; + return AssertionFailure(msg); +} + +// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT1. +// Don't use this in your code. +#define GTEST_PRED_FORMAT1_(pred_format, v1, on_failure)\ + GTEST_ASSERT_(pred_format(#v1, v1),\ + on_failure) + +// Internal macro for implementing {EXPECT|ASSERT}_PRED1. Don't use +// this in your code. +#define GTEST_PRED1_(pred, v1, on_failure)\ + GTEST_ASSERT_(::testing::AssertPred1Helper(#pred, \ + #v1, \ + pred, \ + v1), on_failure) + +// Unary predicate assertion macros. +#define EXPECT_PRED_FORMAT1(pred_format, v1) \ + GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_NONFATAL_FAILURE_) +#define EXPECT_PRED1(pred, v1) \ + GTEST_PRED1_(pred, v1, GTEST_NONFATAL_FAILURE_) +#define ASSERT_PRED_FORMAT1(pred_format, v1) \ + GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_FATAL_FAILURE_) +#define ASSERT_PRED1(pred, v1) \ + GTEST_PRED1_(pred, v1, GTEST_FATAL_FAILURE_) + + + +// Helper function for implementing {EXPECT|ASSERT}_PRED2. Don't use +// this in your code. +template +AssertionResult AssertPred2Helper(const char* pred_text, + const char* e1, + const char* e2, + Pred pred, + const T1& v1, + const T2& v2) { + if (pred(v1, v2)) return AssertionSuccess(); + + Message msg; + msg << pred_text << "(" + << e1 << ", " + << e2 << ") evaluates to false, where" + << "\n" << e1 << " evaluates to " << v1 + << "\n" << e2 << " evaluates to " << v2; + return AssertionFailure(msg); +} + +// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT2. +// Don't use this in your code. +#define GTEST_PRED_FORMAT2_(pred_format, v1, v2, on_failure)\ + GTEST_ASSERT_(pred_format(#v1, #v2, v1, v2),\ + on_failure) + +// Internal macro for implementing {EXPECT|ASSERT}_PRED2. Don't use +// this in your code. +#define GTEST_PRED2_(pred, v1, v2, on_failure)\ + GTEST_ASSERT_(::testing::AssertPred2Helper(#pred, \ + #v1, \ + #v2, \ + pred, \ + v1, \ + v2), on_failure) + +// Binary predicate assertion macros. +#define EXPECT_PRED_FORMAT2(pred_format, v1, v2) \ + GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_NONFATAL_FAILURE_) +#define EXPECT_PRED2(pred, v1, v2) \ + GTEST_PRED2_(pred, v1, v2, GTEST_NONFATAL_FAILURE_) +#define ASSERT_PRED_FORMAT2(pred_format, v1, v2) \ + GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_FATAL_FAILURE_) +#define ASSERT_PRED2(pred, v1, v2) \ + GTEST_PRED2_(pred, v1, v2, GTEST_FATAL_FAILURE_) + + + +// Helper function for implementing {EXPECT|ASSERT}_PRED3. Don't use +// this in your code. +template +AssertionResult AssertPred3Helper(const char* pred_text, + const char* e1, + const char* e2, + const char* e3, + Pred pred, + const T1& v1, + const T2& v2, + const T3& v3) { + if (pred(v1, v2, v3)) return AssertionSuccess(); + + Message msg; + msg << pred_text << "(" + << e1 << ", " + << e2 << ", " + << e3 << ") evaluates to false, where" + << "\n" << e1 << " evaluates to " << v1 + << "\n" << e2 << " evaluates to " << v2 + << "\n" << e3 << " evaluates to " << v3; + return AssertionFailure(msg); +} + +// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT3. +// Don't use this in your code. +#define GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, on_failure)\ + GTEST_ASSERT_(pred_format(#v1, #v2, #v3, v1, v2, v3),\ + on_failure) + +// Internal macro for implementing {EXPECT|ASSERT}_PRED3. Don't use +// this in your code. +#define GTEST_PRED3_(pred, v1, v2, v3, on_failure)\ + GTEST_ASSERT_(::testing::AssertPred3Helper(#pred, \ + #v1, \ + #v2, \ + #v3, \ + pred, \ + v1, \ + v2, \ + v3), on_failure) + +// Ternary predicate assertion macros. +#define EXPECT_PRED_FORMAT3(pred_format, v1, v2, v3) \ + GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, GTEST_NONFATAL_FAILURE_) +#define EXPECT_PRED3(pred, v1, v2, v3) \ + GTEST_PRED3_(pred, v1, v2, v3, GTEST_NONFATAL_FAILURE_) +#define ASSERT_PRED_FORMAT3(pred_format, v1, v2, v3) \ + GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, GTEST_FATAL_FAILURE_) +#define ASSERT_PRED3(pred, v1, v2, v3) \ + GTEST_PRED3_(pred, v1, v2, v3, GTEST_FATAL_FAILURE_) + + + +// Helper function for implementing {EXPECT|ASSERT}_PRED4. Don't use +// this in your code. +template +AssertionResult AssertPred4Helper(const char* pred_text, + const char* e1, + const char* e2, + const char* e3, + const char* e4, + Pred pred, + const T1& v1, + const T2& v2, + const T3& v3, + const T4& v4) { + if (pred(v1, v2, v3, v4)) return AssertionSuccess(); + + Message msg; + msg << pred_text << "(" + << e1 << ", " + << e2 << ", " + << e3 << ", " + << e4 << ") evaluates to false, where" + << "\n" << e1 << " evaluates to " << v1 + << "\n" << e2 << " evaluates to " << v2 + << "\n" << e3 << " evaluates to " << v3 + << "\n" << e4 << " evaluates to " << v4; + return AssertionFailure(msg); +} + +// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT4. +// Don't use this in your code. +#define GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, on_failure)\ + GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, v1, v2, v3, v4),\ + on_failure) + +// Internal macro for implementing {EXPECT|ASSERT}_PRED4. Don't use +// this in your code. +#define GTEST_PRED4_(pred, v1, v2, v3, v4, on_failure)\ + GTEST_ASSERT_(::testing::AssertPred4Helper(#pred, \ + #v1, \ + #v2, \ + #v3, \ + #v4, \ + pred, \ + v1, \ + v2, \ + v3, \ + v4), on_failure) + +// 4-ary predicate assertion macros. +#define EXPECT_PRED_FORMAT4(pred_format, v1, v2, v3, v4) \ + GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, GTEST_NONFATAL_FAILURE_) +#define EXPECT_PRED4(pred, v1, v2, v3, v4) \ + GTEST_PRED4_(pred, v1, v2, v3, v4, GTEST_NONFATAL_FAILURE_) +#define ASSERT_PRED_FORMAT4(pred_format, v1, v2, v3, v4) \ + GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, GTEST_FATAL_FAILURE_) +#define ASSERT_PRED4(pred, v1, v2, v3, v4) \ + GTEST_PRED4_(pred, v1, v2, v3, v4, GTEST_FATAL_FAILURE_) + + + +// Helper function for implementing {EXPECT|ASSERT}_PRED5. Don't use +// this in your code. +template +AssertionResult AssertPred5Helper(const char* pred_text, + const char* e1, + const char* e2, + const char* e3, + const char* e4, + const char* e5, + Pred pred, + const T1& v1, + const T2& v2, + const T3& v3, + const T4& v4, + const T5& v5) { + if (pred(v1, v2, v3, v4, v5)) return AssertionSuccess(); + + Message msg; + msg << pred_text << "(" + << e1 << ", " + << e2 << ", " + << e3 << ", " + << e4 << ", " + << e5 << ") evaluates to false, where" + << "\n" << e1 << " evaluates to " << v1 + << "\n" << e2 << " evaluates to " << v2 + << "\n" << e3 << " evaluates to " << v3 + << "\n" << e4 << " evaluates to " << v4 + << "\n" << e5 << " evaluates to " << v5; + return AssertionFailure(msg); +} + +// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT5. +// Don't use this in your code. +#define GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, on_failure)\ + GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, #v5, v1, v2, v3, v4, v5),\ + on_failure) + +// Internal macro for implementing {EXPECT|ASSERT}_PRED5. Don't use +// this in your code. +#define GTEST_PRED5_(pred, v1, v2, v3, v4, v5, on_failure)\ + GTEST_ASSERT_(::testing::AssertPred5Helper(#pred, \ + #v1, \ + #v2, \ + #v3, \ + #v4, \ + #v5, \ + pred, \ + v1, \ + v2, \ + v3, \ + v4, \ + v5), on_failure) + +// 5-ary predicate assertion macros. +#define EXPECT_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5) \ + GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, GTEST_NONFATAL_FAILURE_) +#define EXPECT_PRED5(pred, v1, v2, v3, v4, v5) \ + GTEST_PRED5_(pred, v1, v2, v3, v4, v5, GTEST_NONFATAL_FAILURE_) +#define ASSERT_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5) \ + GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, GTEST_FATAL_FAILURE_) +#define ASSERT_PRED5(pred, v1, v2, v3, v4, v5) \ + GTEST_PRED5_(pred, v1, v2, v3, v4, v5, GTEST_FATAL_FAILURE_) + + + +#endif // GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ + +// Macros for testing equalities and inequalities. +// +// * {ASSERT|EXPECT}_EQ(expected, actual): Tests that expected == actual +// * {ASSERT|EXPECT}_NE(v1, v2): Tests that v1 != v2 +// * {ASSERT|EXPECT}_LT(v1, v2): Tests that v1 < v2 +// * {ASSERT|EXPECT}_LE(v1, v2): Tests that v1 <= v2 +// * {ASSERT|EXPECT}_GT(v1, v2): Tests that v1 > v2 +// * {ASSERT|EXPECT}_GE(v1, v2): Tests that v1 >= v2 +// +// When they are not, Google Test prints both the tested expressions and +// their actual values. The values must be compatible built-in types, +// or you will get a compiler error. By "compatible" we mean that the +// values can be compared by the respective operator. +// +// Note: +// +// 1. It is possible to make a user-defined type work with +// {ASSERT|EXPECT}_??(), but that requires overloading the +// comparison operators and is thus discouraged by the Google C++ +// Usage Guide. Therefore, you are advised to use the +// {ASSERT|EXPECT}_TRUE() macro to assert that two objects are +// equal. +// +// 2. The {ASSERT|EXPECT}_??() macros do pointer comparisons on +// pointers (in particular, C strings). Therefore, if you use it +// with two C strings, you are testing how their locations in memory +// are related, not how their content is related. To compare two C +// strings by content, use {ASSERT|EXPECT}_STR*(). +// +// 3. {ASSERT|EXPECT}_EQ(expected, actual) is preferred to +// {ASSERT|EXPECT}_TRUE(expected == actual), as the former tells you +// what the actual value is when it fails, and similarly for the +// other comparisons. +// +// 4. Do not depend on the order in which {ASSERT|EXPECT}_??() +// evaluate their arguments, which is undefined. +// +// 5. These macros evaluate their arguments exactly once. +// +// Examples: +// +// EXPECT_NE(5, Foo()); +// EXPECT_EQ(NULL, a_pointer); +// ASSERT_LT(i, array_size); +// ASSERT_GT(records.size(), 0) << "There is no record left."; + +#define EXPECT_EQ(expected, actual) \ + EXPECT_PRED_FORMAT2(::testing::internal:: \ + EqHelper::Compare, \ + expected, actual) +#define EXPECT_NE(expected, actual) \ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperNE, expected, actual) +#define EXPECT_LE(val1, val2) \ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperLE, val1, val2) +#define EXPECT_LT(val1, val2) \ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperLT, val1, val2) +#define EXPECT_GE(val1, val2) \ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperGE, val1, val2) +#define EXPECT_GT(val1, val2) \ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperGT, val1, val2) + +#define ASSERT_EQ(expected, actual) \ + ASSERT_PRED_FORMAT2(::testing::internal:: \ + EqHelper::Compare, \ + expected, actual) +#define ASSERT_NE(val1, val2) \ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperNE, val1, val2) +#define ASSERT_LE(val1, val2) \ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperLE, val1, val2) +#define ASSERT_LT(val1, val2) \ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperLT, val1, val2) +#define ASSERT_GE(val1, val2) \ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperGE, val1, val2) +#define ASSERT_GT(val1, val2) \ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperGT, val1, val2) + +// C String Comparisons. All tests treat NULL and any non-NULL string +// as different. Two NULLs are equal. +// +// * {ASSERT|EXPECT}_STREQ(s1, s2): Tests that s1 == s2 +// * {ASSERT|EXPECT}_STRNE(s1, s2): Tests that s1 != s2 +// * {ASSERT|EXPECT}_STRCASEEQ(s1, s2): Tests that s1 == s2, ignoring case +// * {ASSERT|EXPECT}_STRCASENE(s1, s2): Tests that s1 != s2, ignoring case +// +// For wide or narrow string objects, you can use the +// {ASSERT|EXPECT}_??() macros. +// +// Don't depend on the order in which the arguments are evaluated, +// which is undefined. +// +// These macros evaluate their arguments exactly once. + +#define EXPECT_STREQ(expected, actual) \ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTREQ, expected, actual) +#define EXPECT_STRNE(s1, s2) \ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRNE, s1, s2) +#define EXPECT_STRCASEEQ(expected, actual) \ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASEEQ, expected, actual) +#define EXPECT_STRCASENE(s1, s2)\ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASENE, s1, s2) + +#define ASSERT_STREQ(expected, actual) \ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTREQ, expected, actual) +#define ASSERT_STRNE(s1, s2) \ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRNE, s1, s2) +#define ASSERT_STRCASEEQ(expected, actual) \ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASEEQ, expected, actual) +#define ASSERT_STRCASENE(s1, s2)\ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASENE, s1, s2) + +// Macros for comparing floating-point numbers. +// +// * {ASSERT|EXPECT}_FLOAT_EQ(expected, actual): +// Tests that two float values are almost equal. +// * {ASSERT|EXPECT}_DOUBLE_EQ(expected, actual): +// Tests that two double values are almost equal. +// * {ASSERT|EXPECT}_NEAR(v1, v2, abs_error): +// Tests that v1 and v2 are within the given distance to each other. +// +// Google Test uses ULP-based comparison to automatically pick a default +// error bound that is appropriate for the operands. See the +// FloatingPoint template class in gtest-internal.h if you are +// interested in the implementation details. + +#define EXPECT_FLOAT_EQ(expected, actual)\ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ, \ + expected, actual) + +#define EXPECT_DOUBLE_EQ(expected, actual)\ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ, \ + expected, actual) + +#define ASSERT_FLOAT_EQ(expected, actual)\ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ, \ + expected, actual) + +#define ASSERT_DOUBLE_EQ(expected, actual)\ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ, \ + expected, actual) + +#define EXPECT_NEAR(val1, val2, abs_error)\ + EXPECT_PRED_FORMAT3(::testing::internal::DoubleNearPredFormat, \ + val1, val2, abs_error) + +#define ASSERT_NEAR(val1, val2, abs_error)\ + ASSERT_PRED_FORMAT3(::testing::internal::DoubleNearPredFormat, \ + val1, val2, abs_error) + +// These predicate format functions work on floating-point values, and +// can be used in {ASSERT|EXPECT}_PRED_FORMAT2*(), e.g. +// +// EXPECT_PRED_FORMAT2(testing::DoubleLE, Foo(), 5.0); + +// Asserts that val1 is less than, or almost equal to, val2. Fails +// otherwise. In particular, it fails if either val1 or val2 is NaN. +GTEST_API_ AssertionResult FloatLE(const char* expr1, const char* expr2, + float val1, float val2); +GTEST_API_ AssertionResult DoubleLE(const char* expr1, const char* expr2, + double val1, double val2); + + +#if GTEST_OS_WINDOWS + +// Macros that test for HRESULT failure and success, these are only useful +// on Windows, and rely on Windows SDK macros and APIs to compile. +// +// * {ASSERT|EXPECT}_HRESULT_{SUCCEEDED|FAILED}(expr) +// +// When expr unexpectedly fails or succeeds, Google Test prints the +// expected result and the actual result with both a human-readable +// string representation of the error, if available, as well as the +// hex result code. +#define EXPECT_HRESULT_SUCCEEDED(expr) \ + EXPECT_PRED_FORMAT1(::testing::internal::IsHRESULTSuccess, (expr)) + +#define ASSERT_HRESULT_SUCCEEDED(expr) \ + ASSERT_PRED_FORMAT1(::testing::internal::IsHRESULTSuccess, (expr)) + +#define EXPECT_HRESULT_FAILED(expr) \ + EXPECT_PRED_FORMAT1(::testing::internal::IsHRESULTFailure, (expr)) + +#define ASSERT_HRESULT_FAILED(expr) \ + ASSERT_PRED_FORMAT1(::testing::internal::IsHRESULTFailure, (expr)) + +#endif // GTEST_OS_WINDOWS + +// Macros that execute statement and check that it doesn't generate new fatal +// failures in the current thread. +// +// * {ASSERT|EXPECT}_NO_FATAL_FAILURE(statement); +// +// Examples: +// +// EXPECT_NO_FATAL_FAILURE(Process()); +// ASSERT_NO_FATAL_FAILURE(Process()) << "Process() failed"; +// +#define ASSERT_NO_FATAL_FAILURE(statement) \ + GTEST_TEST_NO_FATAL_FAILURE_(statement, GTEST_FATAL_FAILURE_) +#define EXPECT_NO_FATAL_FAILURE(statement) \ + GTEST_TEST_NO_FATAL_FAILURE_(statement, GTEST_NONFATAL_FAILURE_) + +// Causes a trace (including the source file path, the current line +// number, and the given message) to be included in every test failure +// message generated by code in the current scope. The effect is +// undone when the control leaves the current scope. +// +// The message argument can be anything streamable to std::ostream. +// +// In the implementation, we include the current line number as part +// of the dummy variable name, thus allowing multiple SCOPED_TRACE()s +// to appear in the same block - as long as they are on different +// lines. +#define SCOPED_TRACE(message) \ + ::testing::internal::ScopedTrace GTEST_CONCAT_TOKEN_(gtest_trace_, __LINE__)(\ + __FILE__, __LINE__, ::testing::Message() << (message)) + +namespace internal { + +// This template is declared, but intentionally undefined. +template +struct StaticAssertTypeEqHelper; + +template +struct StaticAssertTypeEqHelper {}; + +} // namespace internal + +// Compile-time assertion for type equality. +// StaticAssertTypeEq() compiles iff type1 and type2 are +// the same type. The value it returns is not interesting. +// +// Instead of making StaticAssertTypeEq a class template, we make it a +// function template that invokes a helper class template. This +// prevents a user from misusing StaticAssertTypeEq by +// defining objects of that type. +// +// CAVEAT: +// +// When used inside a method of a class template, +// StaticAssertTypeEq() is effective ONLY IF the method is +// instantiated. For example, given: +// +// template class Foo { +// public: +// void Bar() { testing::StaticAssertTypeEq(); } +// }; +// +// the code: +// +// void Test1() { Foo foo; } +// +// will NOT generate a compiler error, as Foo::Bar() is never +// actually instantiated. Instead, you need: +// +// void Test2() { Foo foo; foo.Bar(); } +// +// to cause a compiler error. +template +bool StaticAssertTypeEq() { + internal::StaticAssertTypeEqHelper(); + return true; +} + +// Defines a test. +// +// The first parameter is the name of the test case, and the second +// parameter is the name of the test within the test case. +// +// The convention is to end the test case name with "Test". For +// example, a test case for the Foo class can be named FooTest. +// +// The user should put his test code between braces after using this +// macro. Example: +// +// TEST(FooTest, InitializesCorrectly) { +// Foo foo; +// EXPECT_TRUE(foo.StatusIsOK()); +// } + +// Note that we call GetTestTypeId() instead of GetTypeId< +// ::testing::Test>() here to get the type ID of testing::Test. This +// is to work around a suspected linker bug when using Google Test as +// a framework on Mac OS X. The bug causes GetTypeId< +// ::testing::Test>() to return different values depending on whether +// the call is from the Google Test framework itself or from user test +// code. GetTestTypeId() is guaranteed to always return the same +// value, as it always calls GetTypeId<>() from the Google Test +// framework. +#define GTEST_TEST(test_case_name, test_name)\ + GTEST_TEST_(test_case_name, test_name, \ + ::testing::Test, ::testing::internal::GetTestTypeId()) + +// Define this macro to 1 to omit the definition of TEST(), which +// is a generic name and clashes with some other libraries. +#if !GTEST_DONT_DEFINE_TEST +#define TEST(test_case_name, test_name) GTEST_TEST(test_case_name, test_name) +#endif + +// Defines a test that uses a test fixture. +// +// The first parameter is the name of the test fixture class, which +// also doubles as the test case name. The second parameter is the +// name of the test within the test case. +// +// A test fixture class must be declared earlier. The user should put +// his test code between braces after using this macro. Example: +// +// class FooTest : public testing::Test { +// protected: +// virtual void SetUp() { b_.AddElement(3); } +// +// Foo a_; +// Foo b_; +// }; +// +// TEST_F(FooTest, InitializesCorrectly) { +// EXPECT_TRUE(a_.StatusIsOK()); +// } +// +// TEST_F(FooTest, ReturnsElementCountCorrectly) { +// EXPECT_EQ(0, a_.size()); +// EXPECT_EQ(1, b_.size()); +// } + +#define TEST_F(test_fixture, test_name)\ + GTEST_TEST_(test_fixture, test_name, test_fixture, \ + ::testing::internal::GetTypeId()) + +// Use this macro in main() to run all tests. It returns 0 if all +// tests are successful, or 1 otherwise. +// +// RUN_ALL_TESTS() should be invoked after the command line has been +// parsed by InitGoogleTest(). + +#define RUN_ALL_TESTS()\ + (::testing::UnitTest::GetInstance()->Run()) + +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_GTEST_H_ diff --git a/Fwk/AppFwk/cafTensor/cafTensor3.cpp b/Fwk/AppFwk/cafTensor/cafTensor3.cpp index e10b924a83..56c26270fd 100644 --- a/Fwk/AppFwk/cafTensor/cafTensor3.cpp +++ b/Fwk/AppFwk/cafTensor/cafTensor3.cpp @@ -68,82 +68,82 @@ cvf::Vec3d eigenVector3(const cvf::Mat3d& mx, double eigenValue, bool* computedO { const double doubleThreshold = 1.0e-60; if (computedOk) (*computedOk) = false; - cvf::Mat3d mxMinusEigv = mx; + cvf::Mat3d mxMinusEigv = mx; - for (int i = 0; i < 3; i++) + for (int i = 0; i < 3; i++) { mxMinusEigv(i, i) -= eigenValue; } - cvf::Mat3d cof = cofactor3(mxMinusEigv); + cvf::Mat3d cof = cofactor3(mxMinusEigv); - // Find largest absolute cofactor + // Find largest absolute cofactor - int largestCof_i = -1; + int largestCof_i = -1; int largestCof_j = -1; - double largestCof = 0.0; - for (int i = 0; i < 3; i++) - { - for (int j = 0; j < 3; j++) - { - double absCof = fabs(cof(i,j)); - - if (absCof > largestCof) - { - largestCof = absCof; - largestCof_i = i; - largestCof_j = j; - } - } - } - - if (fabs(largestCof) < doubleThreshold) return cvf::Vec3d::ZERO; - - // Find largest matrix element not in the max cofactor row/col - - int largestMxElm_i = -1; + double largestCof = 0.0; + for (int i = 0; i < 3; i++) + { + for (int j = 0; j < 3; j++) + { + double absCof = fabs(cof(i,j)); + + if (absCof > largestCof) + { + largestCof = absCof; + largestCof_i = i; + largestCof_j = j; + } + } + } + + if (fabs(largestCof) < doubleThreshold) return cvf::Vec3d::ZERO; + + // Find largest matrix element not in the max cofactor row/col + + int largestMxElm_i = -1; int largestMxElm_j = -1; - double largestMxElm = 0.0; - for (int i = 0; i < 3; i++) - { - if (i != largestCof_i) - { - for (int j = 0; j < 3; j++) - { - if (j != largestCof_j) - { - double absMxElm = fabs(mxMinusEigv(i,j)); - - if (absMxElm > largestMxElm) - { - largestMxElm = absMxElm; - largestMxElm_i = i; - largestMxElm_j = j; - } - } - } - } - } - - // Check if largest coefficient is zero - if (fabs(largestMxElm) < doubleThreshold) return cvf::Vec3d::ZERO; - - // Find last component index - int lastComp_j = 0; - for (int i = 0; i < 3; i++) - { - if ((i != largestCof_j) && (i != largestMxElm_j)) lastComp_j = i; - } + double largestMxElm = 0.0; + for (int i = 0; i < 3; i++) + { + if (i != largestCof_i) + { + for (int j = 0; j < 3; j++) + { + if (j != largestCof_j) + { + double absMxElm = fabs(mxMinusEigv(i,j)); + + if (absMxElm > largestMxElm) + { + largestMxElm = absMxElm; + largestMxElm_i = i; + largestMxElm_j = j; + } + } + } + } + } + + // Check if largest coefficient is zero + if (fabs(largestMxElm) < doubleThreshold) return cvf::Vec3d::ZERO; + + // Find last component index + int lastComp_j = 0; + for (int i = 0; i < 3; i++) + { + if ((i != largestCof_j) && (i != largestMxElm_j)) lastComp_j = i; + } cvf::Vec3d eigenVector; - eigenVector[largestCof_j] = 1.0; - eigenVector[lastComp_j] = cof(largestCof_i, lastComp_j) / cof(largestCof_i, largestCof_j); - eigenVector[largestMxElm_j] = (-mxMinusEigv(largestMxElm_i, largestCof_j) - mxMinusEigv(largestMxElm_i, lastComp_j)*eigenVector[lastComp_j] ) + eigenVector[largestCof_j] = 1.0; + eigenVector[lastComp_j] = cof(largestCof_i, lastComp_j) / cof(largestCof_i, largestCof_j); + eigenVector[largestMxElm_j] = (-mxMinusEigv(largestMxElm_i, largestCof_j) - mxMinusEigv(largestMxElm_i, lastComp_j)*eigenVector[lastComp_j] ) / mxMinusEigv(largestMxElm_i, largestMxElm_j); if (computedOk) (*computedOk) = true; - return eigenVector; + return eigenVector; } diff --git a/Fwk/AppFwk/cafTensor/cafTensor3.inl b/Fwk/AppFwk/cafTensor/cafTensor3.inl index 1b21b9a545..a7b107d26f 100644 --- a/Fwk/AppFwk/cafTensor/cafTensor3.inl +++ b/Fwk/AppFwk/cafTensor/cafTensor3.inl @@ -170,111 +170,111 @@ cvf::Vec3d eigenVector3(const cvf::Mat3d& mx, double eigenValue, bool* computedO template cvf::Vec3f Tensor3::calculatePrincipals( cvf::Vec3f principalDirections[3]) { - CVF_TIGHT_ASSERT(m_tensor); + CVF_TIGHT_ASSERT(m_tensor); const float floatThreshold = 1.0e-30f; const double doubleThreshold = 1.0e-60; cvf::Vec3f principalValues; - - // Init return arrays to invalid + + // Init return arrays to invalid principalValues[0] = std::numeric_limits::infinity(); principalValues[1] = std::numeric_limits::infinity(); principalValues[2] = std::numeric_limits::infinity(); if (principalDirections) - { - principalDirections[0] = cvf::Vec3f::ZERO; - principalDirections[1] = cvf::Vec3f::ZERO; - principalDirections[2] = cvf::Vec3f::ZERO; - } + { + principalDirections[0] = cvf::Vec3f::ZERO; + principalDirections[1] = cvf::Vec3f::ZERO; + principalDirections[2] = cvf::Vec3f::ZERO; + } // Return if we have an undefined component - int i; - for (i = 0; i < 6; i++) - { - if (m_tensor[i] == std::numeric_limits::infinity()) + int i; + for (i = 0; i < 6; i++) + { + if (m_tensor[i] == std::numeric_limits::infinity()) { return principalValues; } - } + } - // Return 0, 0, 0 if all components are zero - - bool isAllTensCompsZero = true; - for (i = 0; i < 6; i++) - { - if (!(abs(m_tensor[i]) < floatThreshold)) - { - isAllTensCompsZero = false; - break; - } - } - - if (isAllTensCompsZero) + // Return 0, 0, 0 if all components are zero + + bool isAllTensCompsZero = true; + for (i = 0; i < 6; i++) + { + if (!(abs(m_tensor[i]) < floatThreshold)) + { + isAllTensCompsZero = false; + break; + } + } + + if (isAllTensCompsZero) { return cvf::Vec3f::ZERO; } - double SXX = m_tensor[0], SYY = m_tensor[1], SZZ = m_tensor[2]; - double SXY = m_tensor[3], SYZ = m_tensor[4], SZX = m_tensor[5]; + double SXX = m_tensor[0], SYY = m_tensor[1], SZZ = m_tensor[2]; + double SXY = m_tensor[3], SYZ = m_tensor[4], SZX = m_tensor[5]; - double pressure = -(SXX + SYY + SZZ)/3.0; + double pressure = -(SXX + SYY + SZZ)/3.0; - // Normally we would solve the eigenvalues by solving the 3'rd degree equation: + // Normally we would solve the eigenvalues by solving the 3'rd degree equation: // -sigma^3 + A*sigma^2 - B*sigma + C = 0 - // in which A, B, and C are the invariants of the stress tensor. + // in which A, B, and C are the invariants of the stress tensor. // http://www.engapplets.vt.edu/Mohr/java/nsfapplets/MohrCircles2-3D/Theory/theory.htm - // But the roots(eigenvalues) are calculated by transforming the above equation into - // s**3 + aa*s + b = 0 and using the trignometric solution. - // See crc standard mathematical tables 19th edition pp. 103-104. + // But the roots(eigenvalues) are calculated by transforming the above equation into + // s**3 + aa*s + b = 0 and using the trignometric solution. + // See crc standard mathematical tables 19th edition pp. 103-104. - SXX += pressure; - SYY += pressure; - SZZ += pressure; + SXX += pressure; + SYY += pressure; + SZZ += pressure; double S1, S2, S3; - double AA, BB, CC, DD, angleP; + double AA, BB, CC, DD, angleP; - AA = SXY*SXY + SYZ*SYZ + SZX*SZX - SXX*SYY - SYY*SZZ - SXX*SZZ; + AA = SXY*SXY + SYZ*SYZ + SZX*SZX - SXX*SYY - SYY*SZZ - SXX*SZZ; - BB = SXX * SYZ * SYZ + BB = SXX * SYZ * SYZ + SYY * SZX * SZX + SZZ * SXY * SXY - SXX * SYY * SZZ - 2.0 * SXY * SYZ * SZX; - if (fabs(AA) < doubleThreshold) - { - S1 = 0.0; - S2 = 0.0; - S3 = 0.0; - } - else - { - CC = -sqrt(27.0/AA) * BB * 0.5 / AA; - - if (CC > 1.0) CC = 1.0; - else if (CC < -1.0) CC = -1.0; - - angleP = acos(CC)/3.0; - DD = 2.0*sqrt(AA/3.0); - S1 = DD*cos(angleP); - S2 = DD*cos(angleP + 4.0*cvf::PI_D/3.0); - S3 = DD*cos(angleP + 2.0*cvf::PI_D/3.0); - } - - int idxPMin = 2; + if (fabs(AA) < doubleThreshold) + { + S1 = 0.0; + S2 = 0.0; + S3 = 0.0; + } + else + { + CC = -sqrt(27.0/AA) * BB * 0.5 / AA; + + if (CC > 1.0) CC = 1.0; + else if (CC < -1.0) CC = -1.0; + + angleP = acos(CC)/3.0; + DD = 2.0*sqrt(AA/3.0); + S1 = DD*cos(angleP); + S2 = DD*cos(angleP + 4.0*cvf::PI_D/3.0); + S3 = DD*cos(angleP + 2.0*cvf::PI_D/3.0); + } + + int idxPMin = 2; int idxPMid = 1; int idxPMax = 0; - double principalsd[3]; - principalsd[idxPMax] = (S1 - pressure); - principalsd[idxPMid] = (S2 - pressure); - principalsd[idxPMin] = (S3 - pressure); + double principalsd[3]; + principalsd[idxPMax] = (S1 - pressure); + principalsd[idxPMid] = (S2 - pressure); + principalsd[idxPMin] = (S3 - pressure); // Sort the principals if we have no Z component in the tensor at all if ((m_tensor[2] == 0.0f) && (m_tensor[4] == 0.0f) && (m_tensor[5] == 0.0f)) @@ -317,8 +317,8 @@ template< typename S> float caf::Tensor3::calculateVonMises() { return (float) sqrt( ( (m_tensor[0]*m_tensor[0] + m_tensor[1]*m_tensor[1] + m_tensor[2]*m_tensor[2]) ) + - ( -(m_tensor[0]*m_tensor[1] + m_tensor[1]*m_tensor[2] + m_tensor[0]*m_tensor[2]) ) + - ( 3*(m_tensor[3]*m_tensor[3] + m_tensor[4]*m_tensor[4] + m_tensor[5]*m_tensor[5]) ) ); + ( -(m_tensor[0]*m_tensor[1] + m_tensor[1]*m_tensor[2] + m_tensor[0]*m_tensor[2]) ) + + ( 3*(m_tensor[3]*m_tensor[3] + m_tensor[4]*m_tensor[4] + m_tensor[5]*m_tensor[5]) ) ); } } diff --git a/Fwk/AppFwk/cafTests/cafProjectDataModel_UnitTests/CMakeLists.txt b/Fwk/AppFwk/cafTests/cafProjectDataModel_UnitTests/CMakeLists.txt index 2f531891ab..e6034e0d79 100644 --- a/Fwk/AppFwk/cafTests/cafProjectDataModel_UnitTests/CMakeLists.txt +++ b/Fwk/AppFwk/cafTests/cafProjectDataModel_UnitTests/CMakeLists.txt @@ -1,30 +1,46 @@ cmake_minimum_required (VERSION 2.8) +find_package ( Qt4 COMPONENTS QtCore QtGui ) +include (${QT_USE_FILE}) + project ( cafProjectDataModel_UnitTests ) include_directories ( ${CMAKE_SOURCE_DIR}/cafProjectDataModel ${CMAKE_SOURCE_DIR}/cafTests +) - #Remove when RigStatistics is out - ${ResInsight_SOURCE_DIR}/ApplicationCode/ModelVisualization +include_directories ( + ${cafPdmCore_SOURCE_DIR} + ${cafPdmUiCore_SOURCE_DIR} + ${cafPdmXml_SOURCE_DIR} ) -# add the executable -add_executable (${PROJECT_NAME} +set( PROJECT_FILES cafPdmBasicTest.cpp cafProjectDataModel_UnitTests.cpp Child.cpp Parent.cpp TestObj.cpp + +) + +# add the executable +add_executable (${PROJECT_NAME} + ${PROJECT_FILES} ${CMAKE_SOURCE_DIR}/cafTests/gtest/gtest-all.cpp ) +message(${PROJECT_NAME}" - Qt includes : " ${QT_LIBRARIES}) target_link_libraries ( ${PROJECT_NAME} + cafPdmCore + cafPdmUiCore + cafPdmXml cafProjectDataModel - ${QT_LIBRARIES} + ${QT_LIBRARIES} ) +source_group("" FILES ${PROJECT_FILES}) # Copy Qt Dlls if (MSVC) diff --git a/Fwk/AppFwk/cafTests/cafProjectDataModel_UnitTests/Child.h b/Fwk/AppFwk/cafTests/cafProjectDataModel_UnitTests/Child.h index 82e91dfd4f..61b78e3c18 100644 --- a/Fwk/AppFwk/cafTests/cafProjectDataModel_UnitTests/Child.h +++ b/Fwk/AppFwk/cafTests/cafProjectDataModel_UnitTests/Child.h @@ -1,6 +1,6 @@ #pragma once -#include "cafPdmField.h" +#include "cafPdmChildField.h" #include "cafPdmObject.h" #include "cafPdmPointer.h" @@ -16,7 +16,7 @@ class Child: public caf::PdmObject ~Child(); - caf::PdmField m_testObj; + caf::PdmChildField m_testObj; }; diff --git a/Fwk/AppFwk/cafTests/cafProjectDataModel_UnitTests/Parent.cpp b/Fwk/AppFwk/cafTests/cafProjectDataModel_UnitTests/Parent.cpp index 26d3f4fd01..16892e55ff 100644 --- a/Fwk/AppFwk/cafTests/cafProjectDataModel_UnitTests/Parent.cpp +++ b/Fwk/AppFwk/cafTests/cafProjectDataModel_UnitTests/Parent.cpp @@ -1,11 +1,12 @@ +#include "Child.h" #include "Parent.h" -//#include "Child.h" CAF_PDM_SOURCE_INIT(Parent, "Parent"); Parent::Parent() { + CAF_PDM_InitObject("Parent", "", "", ""); CAF_PDM_InitFieldNoDefault(&m_simpleObjectsField, "SimpleObjects", "A child object", "", "", ""); CAF_PDM_InitFieldNoDefault(&m_simpleObjectF, "SimpleObject", "A child object", "", "", ""); } diff --git a/Fwk/AppFwk/cafTests/cafProjectDataModel_UnitTests/Parent.h b/Fwk/AppFwk/cafTests/cafProjectDataModel_UnitTests/Parent.h index bb4ec86f43..5a4b911417 100644 --- a/Fwk/AppFwk/cafTests/cafProjectDataModel_UnitTests/Parent.h +++ b/Fwk/AppFwk/cafTests/cafProjectDataModel_UnitTests/Parent.h @@ -1,8 +1,9 @@ #pragma once -#include "cafPdmField.h" +#include "cafPdmChildField.h" #include "cafPdmObject.h" #include "cafPdmPointer.h" +#include "cafPdmChildArrayField.h" #if 0 class PdmPointerTarget @@ -47,6 +48,6 @@ class Parent: public caf::PdmObject void doSome(); - caf::PdmPointersField m_simpleObjectsField; - caf::PdmField m_simpleObjectF; + caf::PdmChildArrayField m_simpleObjectsField; + caf::PdmChildField m_simpleObjectF; }; diff --git a/Fwk/AppFwk/cafTests/cafProjectDataModel_UnitTests/cafPdmBasicTest.cpp b/Fwk/AppFwk/cafTests/cafProjectDataModel_UnitTests/cafPdmBasicTest.cpp index c9c0b07576..e28b2f6b5b 100644 --- a/Fwk/AppFwk/cafTests/cafProjectDataModel_UnitTests/cafPdmBasicTest.cpp +++ b/Fwk/AppFwk/cafTests/cafProjectDataModel_UnitTests/cafPdmBasicTest.cpp @@ -37,15 +37,22 @@ #include #include "gtest/gtest.h" + +#include "cafAppEnum.h" +#include "cafPdmChildArrayField.h" +#include "cafPdmChildField.h" +#include "cafPdmDocument.h" #include "cafPdmField.h" #include "cafPdmObject.h" +#include "cafPdmObjectGroup.h" #include "cafPdmPointer.h" -#include "cafPdmDocument.h" +#include "cafPdmProxyValueField.h" +#include "cafPdmReferenceHelper.h" -#include "cafAppEnum.h" -#include #include +#include + /// Demo objects to show the usage of the Pdm system @@ -54,25 +61,33 @@ class SimpleObj: public caf::PdmObject { CAF_PDM_HEADER_INIT; public: - SimpleObj() + SimpleObj() : PdmObject() { - CAF_PDM_InitObject("Simple Object", "", "", ""); - - CAF_PDM_InitField(&m_position, "Position", 8765.2, "Position", "", "", ""); - CAF_PDM_InitField(&m_dir, "Dir", 123.56, "Direction", "", "", ""); - CAF_PDM_InitField(&m_up, "Up", 0.0, "Up value", "", "", "" ); - CAF_PDM_InitFieldNoDefault(&m_numbers, "Numbers", "Important Numbers", "", "", ""); - } + CAF_PDM_InitObject("SimpleObj", "", "Tooltip SimpleObj", "WhatsThis SimpleObj"); + + CAF_PDM_InitField(&m_position, "Position", 8765.2, "Position", "", "Tooltip", "WhatsThis"); + CAF_PDM_InitField(&m_dir, "Dir", 123.56, "Direction", "", "Tooltip", "WhatsThis"); + CAF_PDM_InitField(&m_up, "Up", 0.0, "Up value", "", "Tooltip", "WhatsThis" ); + CAF_PDM_InitFieldNoDefault(&m_numbers, "Numbers", "Important Numbers", "", "Tooltip", "WhatsThis"); +#if 1 + m_proxyDouble.registerSetMethod(this, &SimpleObj::setDoubleMember); + m_proxyDouble.registerGetMethod(this, &SimpleObj::doubleMember); + AddUiCapabilityToField(&m_proxyDouble); + AddXmlCapabilityToField(&m_proxyDouble); + CAF_PDM_InitFieldNoDefault(&m_proxyDouble, "ProxyDouble", "ProxyDouble", "", "", ""); +#endif + } /// Assignment and copying of PDM objects is not focus for the features. This is only a /// "would it work" test SimpleObj(const SimpleObj& other) : PdmObject() { - CAF_PDM_InitField(&m_position, "Position", 8765.2, "Position", "", "", ""); - CAF_PDM_InitField(&m_dir, "Dir", 123.56, "Direction", "", "", ""); - CAF_PDM_InitField(&m_up, "Up", 0.0, "Up value", "", "", "" ); - CAF_PDM_InitFieldNoDefault(&m_numbers, "Numbers", "Important Numbers", "", "", ""); + CAF_PDM_InitField(&m_position, "Position", 8765.2, "Position", "", "", "WhatsThis"); + CAF_PDM_InitField(&m_dir, "Dir", 123.56, "Direction", "", "", "WhatsThis"); + CAF_PDM_InitField(&m_up, "Up", 0.0, "Up value", "", "", "WhatsThis" ); + + CAF_PDM_InitFieldNoDefault(&m_numbers, "Numbers", "Important Numbers", "", "", "WhatsThis"); m_position = other.m_position; m_dir = other.m_dir; @@ -87,6 +102,14 @@ class SimpleObj: public caf::PdmObject caf::PdmField m_dir; caf::PdmField m_up; caf::PdmField > m_numbers; + caf::PdmProxyValueField m_proxyDouble; + + void setDoubleMember(const double& d) { m_doubleMember = d; std::cout << "setDoubleMember" << std::endl; } + double doubleMember() const { std::cout << "doubleMember" << std::endl; return m_doubleMember; } + + double m_doubleMember; + + }; CAF_PDM_SOURCE_INIT(SimpleObj, "SimpleObj"); @@ -99,19 +122,19 @@ class DemoPdmObject: public caf::PdmObject DemoPdmObject() { - CAF_PDM_InitObject("Demo Object", "", "This object is a demo of the CAF framework", "This object is a demo of the CAF framework"); + CAF_PDM_InitObject("DemoPdmObject", "", "Tooltip DemoPdmObject", "WhatsThis DemoPdmObject"); - CAF_PDM_InitField(&m_doubleField, "BigNumber", 0.0, "Big Number", "", + CAF_PDM_InitField(&m_doubleField, "BigNumber", 0.0, "", "", "Enter a big number here", "This is a place you can enter a big real value if you want" ); - CAF_PDM_InitField(&m_intField, "IntNumber", 0, "Small Number","", + CAF_PDM_InitField(&m_intField, "IntNumber", 0, "","", "Enter some small number here", "This is a place you can enter a small integer value if you want"); - CAF_PDM_InitField(&m_textField, "TextField", QString("ÆØÅ Test text end"), "", "", "", ""); - CAF_PDM_InitFieldNoDefault(&m_simpleObjPtrField, "SimpleObjPtrField", "", "", "", ""); - CAF_PDM_InitFieldNoDefault(&m_simpleObjPtrField2, "SimpleObjPtrField2", "", "", "", ""); + CAF_PDM_InitField(&m_textField, "TextField", QString("ÆØÅ Test text end"), "TextField", "", "Tooltip", "WhatsThis"); + CAF_PDM_InitFieldNoDefault(&m_simpleObjPtrField, "SimpleObjPtrField", "SimpleObjPtrField", "", "Tooltip", "WhatsThis"); + CAF_PDM_InitFieldNoDefault(&m_simpleObjPtrField2, "SimpleObjPtrField2", "SimpleObjPtrField2", "", "Tooltip", "WhatsThis"); m_simpleObjPtrField2 = new SimpleObj; } @@ -125,8 +148,8 @@ class DemoPdmObject: public caf::PdmObject caf::PdmField m_intField; caf::PdmField m_textField; - caf::PdmField m_simpleObjPtrField; - caf::PdmField m_simpleObjPtrField2; + caf::PdmChildField m_simpleObjPtrField; + caf::PdmChildField m_simpleObjPtrField2; }; CAF_PDM_SOURCE_INIT(DemoPdmObject, "DemoPdmObject"); @@ -143,20 +166,39 @@ class InheritedDemoObj : public DemoPdmObject InheritedDemoObj() { + CAF_PDM_InitObject("InheritedDemoObj", "", "ToolTip InheritedDemoObj", "Whatsthis InheritedDemoObj"); + CAF_PDM_InitFieldNoDefault(&m_texts, "Texts", "Some words", "", "", ""); CAF_PDM_InitFieldNoDefault(&m_testEnumField, "TestEnumValue", "An Enum", "", "", ""); - CAF_PDM_InitFieldNoDefault(&m_simpleObjectsField, "SimpleObjects", "A child object", "", "", ""); + CAF_PDM_InitFieldNoDefault(&m_simpleObjectsField, "SimpleObjects", "SimpleObjectsField", "", "ToolTip SimpleObjectsField", "Whatsthis SimpleObjectsField"); } caf::PdmField > m_texts; caf::PdmField< caf::AppEnum > m_testEnumField; - caf::PdmPointersField m_simpleObjectsField; + caf::PdmChildArrayField m_simpleObjectsField; }; CAF_PDM_SOURCE_INIT(InheritedDemoObj, "InheritedDemoObj"); +class MyPdmDocument : public caf::PdmDocument +{ + CAF_PDM_HEADER_INIT; +public: + MyPdmDocument() + { + CAF_PDM_InitObject("PdmObjectCollection", "", "", ""); + CAF_PDM_InitFieldNoDefault(&objects, "PdmObjects", "", "", "", "") + } + + caf::PdmChildArrayField objects; + +}; +CAF_PDM_SOURCE_INIT(MyPdmDocument, "MyPdmDocument"); + + + namespace caf { @@ -171,6 +213,13 @@ void AppEnum::setUp() } +TEST(BaseTest, Delete) +{ + SimpleObj* s2 = new SimpleObj; + delete s2; +} + + //-------------------------------------------------------------------------------------------------- /// This is a testbed to try out different aspects, instead of having a main in a prototype program /// To be disabled when everything gets more mature. @@ -179,7 +228,7 @@ TEST(BaseTest, Start) { DemoPdmObject* a = new DemoPdmObject; - caf::PdmObject* demo = caf::PdmObjectFactory::instance()->create("DemoPdmObject"); + caf::PdmObjectHandle* demo = caf::PdmDefaultObjectFactory::instance()->create("DemoPdmObject"); EXPECT_TRUE(demo != NULL); QString xml; @@ -196,15 +245,16 @@ TEST(BaseTest, Start) s.m_dir = 10000; sp = &s; a->m_textField = "Hei og hå"; - *s2 = s; + //*s2 = s; a->m_simpleObjPtrField = s2; s.writeFields(xmlStream); } a->writeFields(xmlStream); + caf::PdmObjectGroup og; og.objects.push_back(a); - og.objects.push_back(s2); + og.objects.push_back(new SimpleObj); og.writeFields(xmlStream); std::cout << sp.p() << std::endl, @@ -246,6 +296,7 @@ TEST(BaseTest, NormalPdmField) EXPECT_TRUE(field1 == field3); } +#if 0 //-------------------------------------------------------------------------------------------------- /// Test of PdmField of pointer operations //-------------------------------------------------------------------------------------------------- @@ -284,12 +335,13 @@ TEST(BaseTest, PointerPdmField) EXPECT_EQ((SimpleObj*)0, field2); EXPECT_EQ((SimpleObj*)0, field3); } +#endif //-------------------------------------------------------------------------------------------------- /// Test of PdmPointersField operations //-------------------------------------------------------------------------------------------------- - -TEST(BaseTest, PdmPointersField) +#if 0 +TEST(BaseTest, PdmChildArrayField) { std::vector parentFields; @@ -308,7 +360,7 @@ TEST(BaseTest, PdmPointersField) ihd1->m_simpleObjectsField.push_back(s2); ihd1->m_simpleObjectsField.push_back(s3); - s1->parentFields(parentFields); + s1->parentField(parentFields); EXPECT_EQ(size_t(1), parentFields.size()); parentFields.clear(); @@ -321,7 +373,7 @@ TEST(BaseTest, PdmPointersField) EXPECT_EQ(s3, ihd1->m_simpleObjectsField[2]); // childObjects - std::vector objects; + std::vector objects; ihd1->m_simpleObjectsField.childObjects(&objects); EXPECT_EQ(size_t(3), objects.size()); @@ -378,11 +430,14 @@ TEST(BaseTest, PdmPointersField) } +#endif + template <> inline void GTestStreamToHelper(std::ostream* os, const QString& val) { *os << val.toLatin1().data(); } + //-------------------------------------------------------------------------------------------------- /// Tests the roundtrip: Create, write, read, write and checks that the first and second file are identical //-------------------------------------------------------------------------------------------------- @@ -391,7 +446,7 @@ TEST(BaseTest, ReadWrite) QString xmlDocumentContentWithErrors; { - caf::PdmDocument xmlDoc; + MyPdmDocument xmlDoc; // Create objects DemoPdmObject* d1 = new DemoPdmObject; @@ -417,60 +472,76 @@ TEST(BaseTest, ReadWrite) d2->m_simpleObjPtrField = &s2; d2->m_simpleObjPtrField2 = s1; - id1->m_simpleObjectsField.push_back(s1); - id1->m_simpleObjectsField.push_back(&s2); - id1->m_simpleObjectsField.push_back(&s2); - id1->m_simpleObjectsField.push_back(&s2); + id1->m_simpleObjectsField.push_back(new SimpleObj); + id1->m_simpleObjectsField[0]->m_numbers.v().push_back(3.0); + id1->m_simpleObjectsField.push_back(new SimpleObj); + id1->m_simpleObjectsField[1]->m_numbers.v().push_back(3.1); + id1->m_simpleObjectsField[1]->m_numbers.v().push_back(3.11); + id1->m_simpleObjectsField[1]->m_numbers.v().push_back(3.12); + id1->m_simpleObjectsField[1]->m_numbers.v().push_back(3.13); + id1->m_simpleObjectsField.push_back(new SimpleObj); + id1->m_simpleObjectsField[2]->m_numbers.v().push_back(3.2); + id1->m_simpleObjectsField.push_back(new SimpleObj); + id1->m_simpleObjectsField[3]->m_numbers.v().push_back(3.3); // Add to document - xmlDoc.addObject(d1); - xmlDoc.addObject(d2); - xmlDoc.addObject(s1); - xmlDoc.addObject(id1); - xmlDoc.addObject(id2); + xmlDoc.objects.push_back(d1); + xmlDoc.objects.push_back(d2); + xmlDoc.objects.push_back(new SimpleObj); + xmlDoc.objects.push_back(id1); + xmlDoc.objects.push_back(id2); // Write file xmlDoc.fileName = "PdmTestFil.xml"; xmlDoc.writeFile(); + caf::PdmObjectGroup pog; + for (size_t i = 0; i < xmlDoc.objects.size(); i++) + { + pog.addObject(xmlDoc.objects[i]); + } { std::vector > demoObjs; - xmlDoc.objectsByType(&demoObjs); + pog.objectsByType(&demoObjs); EXPECT_EQ(size_t(4), demoObjs.size()); } { std::vector > demoObjs; - xmlDoc.objectsByType(&demoObjs); + pog.objectsByType(&demoObjs); EXPECT_EQ(size_t(2), demoObjs.size()); } { std::vector > demoObjs; - xmlDoc.objectsByType(&demoObjs); + pog.objectsByType(&demoObjs); EXPECT_EQ(size_t(1), demoObjs.size()); } - xmlDoc.deleteObjects(); - EXPECT_EQ(size_t(0), xmlDoc.objects().size()); } { - caf::PdmDocument xmlDoc; + MyPdmDocument xmlDoc; // Read file xmlDoc.fileName = "PdmTestFil.xml"; xmlDoc.readFile(); + caf::PdmObjectGroup pog; + for (size_t i = 0; i < xmlDoc.objects.size(); i++) + { + pog.addObject(xmlDoc.objects[i]); + } + // Test sample of that writing actually took place std::vector > ihDObjs; - xmlDoc.objectsByType(&ihDObjs); + pog.objectsByType(&ihDObjs); EXPECT_EQ(size_t(2),ihDObjs.size() ); ASSERT_EQ(size_t(4), ihDObjs[0]->m_simpleObjectsField.size()); ASSERT_EQ(size_t(4), ihDObjs[0]->m_simpleObjectsField[1]->m_numbers().size()); - EXPECT_EQ(2.7, ihDObjs[0]->m_simpleObjectsField[1]->m_numbers()[3]); + EXPECT_EQ(3.13, ihDObjs[0]->m_simpleObjectsField[1]->m_numbers()[3]); EXPECT_EQ(QString("ÆØÅ Test text end"), ihDObjs[0]->m_textField()); @@ -573,20 +644,27 @@ TEST(BaseTest, ReadWrite) f3.close(); // Read the document containing errors - caf::PdmDocument xmlErrorDoc; + + MyPdmDocument xmlErrorDoc; xmlErrorDoc.fileName = "PdmTestFilWithError.xml"; xmlErrorDoc.readFile(); + caf::PdmObjectGroup pog; + for (size_t i = 0; i < xmlErrorDoc.objects.size(); i++) + { + pog.addObject(xmlErrorDoc.objects[i]); + } + // Check the pointersfield std::vector > ihDObjs; - xmlErrorDoc.objectsByType(&ihDObjs); + pog.objectsByType(&ihDObjs); EXPECT_EQ(size_t(2), ihDObjs.size() ); ASSERT_EQ(size_t(3), ihDObjs[0]->m_simpleObjectsField.size()); // check single pointer field std::vector > demoObjs; - xmlErrorDoc.objectsByType(&demoObjs); + pog.objectsByType(&demoObjs); EXPECT_EQ(size_t(4), demoObjs.size() ); EXPECT_TRUE(demoObjs[0]->m_simpleObjPtrField == NULL ); @@ -594,10 +672,9 @@ TEST(BaseTest, ReadWrite) // check single pointer field std::vector > simpleObjs; - xmlErrorDoc.objectsByType(&simpleObjs); + pog.objectsByType(&simpleObjs); EXPECT_EQ(size_t(1), simpleObjs.size() ); EXPECT_EQ(size_t(0), simpleObjs[0]->m_numbers().size()); - } } @@ -619,8 +696,6 @@ TEST(BaseTest, PdmPointer) EXPECT_TRUE(p == d && p2 == d); EXPECT_TRUE(p.p() == d); - EXPECT_TRUE((*p).uiName() == (*d).uiName()); - EXPECT_TRUE(p->uiName() == "File"); p = 0; EXPECT_TRUE(p == NULL); EXPECT_TRUE(p.isNull()); @@ -646,30 +721,30 @@ TEST(BaseTest, PdmObjectFactory) { { SimpleObj* s = NULL; - s = dynamic_cast (caf::PdmObjectFactory::instance()->create("SimpleObj")); + s = dynamic_cast (caf::PdmDefaultObjectFactory::instance()->create("SimpleObj")); EXPECT_TRUE(s != NULL); } { DemoPdmObject* s = NULL; - s = dynamic_cast (caf::PdmObjectFactory::instance()->create("DemoPdmObject")); + s = dynamic_cast (caf::PdmDefaultObjectFactory::instance()->create("DemoPdmObject")); EXPECT_TRUE(s != NULL); delete s; } { InheritedDemoObj* s = NULL; - s = dynamic_cast (caf::PdmObjectFactory::instance()->create("InheritedDemoObj")); + s = dynamic_cast (caf::PdmDefaultObjectFactory::instance()->create("InheritedDemoObj")); EXPECT_TRUE(s != NULL); } { caf::PdmDocument* s = NULL; - s = dynamic_cast (caf::PdmObjectFactory::instance()->create("PdmDocument")); + s = dynamic_cast (caf::PdmDefaultObjectFactory::instance()->create("PdmDocument")); EXPECT_TRUE(s != NULL); } { caf::PdmObjectGroup* s = NULL; - s = dynamic_cast (caf::PdmObjectFactory::instance()->create("PdmObjectGroup")); + s = dynamic_cast (caf::PdmDefaultObjectFactory::instance()->create("PdmObjectGroup")); EXPECT_TRUE(s != NULL); } @@ -680,12 +755,12 @@ TEST(BaseTest, PdmObjectFactory) //-------------------------------------------------------------------------------------------------- TEST(BaseTest, ValidXmlKeywords) { - EXPECT_TRUE(caf::PdmObject::isValidXmlElementName("Valid_name")); + EXPECT_TRUE(caf::PdmXmlObjectHandle::isValidXmlElementName("Valid_name")); - EXPECT_FALSE(caf::PdmObject::isValidXmlElementName("2Valid_name")); - EXPECT_FALSE(caf::PdmObject::isValidXmlElementName(".Valid_name")); - EXPECT_FALSE(caf::PdmObject::isValidXmlElementName("xml_Valid_name")); - EXPECT_FALSE(caf::PdmObject::isValidXmlElementName("Valid_name_with_space ")); + EXPECT_FALSE(caf::PdmXmlObjectHandle::isValidXmlElementName("2Valid_name")); + EXPECT_FALSE(caf::PdmXmlObjectHandle::isValidXmlElementName(".Valid_name")); + EXPECT_FALSE(caf::PdmXmlObjectHandle::isValidXmlElementName("xml_Valid_name")); + EXPECT_FALSE(caf::PdmXmlObjectHandle::isValidXmlElementName("Valid_name_with_space ")); } TEST(BaseTest, PdmPointersFieldInsertVector) @@ -703,8 +778,14 @@ TEST(BaseTest, PdmPointersFieldInsertVector) std::vector > typedObjects; pdmGroup.objectsByType(&typedObjects); - - ihd1->m_simpleObjectsField.insert(ihd1->m_simpleObjectsField.size(), typedObjects); + EXPECT_EQ(size_t(3), typedObjects.size()); + + std::vector > objs; + objs.push_back(new SimpleObj); + objs.push_back(new SimpleObj); + objs.push_back(new SimpleObj); + + ihd1->m_simpleObjectsField.insert(ihd1->m_simpleObjectsField.size(), objs); EXPECT_EQ(size_t(3), ihd1->m_simpleObjectsField.size()); delete ihd1; @@ -731,14 +812,159 @@ TEST(BaseTest, PdmObjectGroupCopyOfTypedObjects) og.objects.push_back(ihd1); std::vector > simpleObjList; - og.createCopyByType(&simpleObjList); + og.createCopyByType(&simpleObjList, caf::PdmDefaultObjectFactory::instance()); EXPECT_EQ(size_t(3), simpleObjList.size()); + EXPECT_EQ(1000, simpleObjList[0]->m_position); + EXPECT_EQ(size_t(1), simpleObjList[0]->m_numbers.v().size()); + EXPECT_EQ(10, simpleObjList[0]->m_numbers.v()[0]); + + EXPECT_EQ(2000, simpleObjList[1]->m_position); + EXPECT_EQ(3000, simpleObjList[2]->m_position); + std::vector > inheritObjList; - og.createCopyByType(&inheritObjList); + og.createCopyByType(&inheritObjList, caf::PdmDefaultObjectFactory::instance()); EXPECT_EQ(size_t(1), inheritObjList.size()); og.deleteObjects(); EXPECT_EQ(size_t(3), simpleObjList.size()); EXPECT_EQ(size_t(1), inheritObjList.size()); } + +//-------------------------------------------------------------------------------------------------- +/// PdmChildArrayFieldHandle +//-------------------------------------------------------------------------------------------------- +TEST(BaseTest, PdmChildArrayFieldHandle) +{ + +// virtual size_t size() const = 0; +// virtual bool empty() const = 0; +// virtual void clear() = 0; +// virtual PdmObject* createAppendObject(int indexAfter) = 0; +// virtual void erase(size_t index) = 0; +// virtual void deleteAllChildObjects() = 0; +// +// virtual PdmObject* at(size_t index) = 0; +// +// bool hasSameFieldCountForAllObjects(); + + SimpleObj* s1 = new SimpleObj; + s1->m_position = 1000; + s1->m_numbers.v().push_back(10); + + SimpleObj* s2 = new SimpleObj; + s2->m_position = 2000; + + SimpleObj* s3 = new SimpleObj; + s3->m_position = 3000; + + InheritedDemoObj* ihd1 = new InheritedDemoObj; + caf::PdmChildArrayFieldHandle* listField = &(ihd1->m_simpleObjectsField); + + EXPECT_EQ(0, listField->size()); + EXPECT_TRUE(listField->hasSameFieldCountForAllObjects()); + EXPECT_TRUE(listField->empty()); + + ihd1->m_simpleObjectsField.push_back(new SimpleObj); + EXPECT_EQ(1, listField->size()); + EXPECT_TRUE(listField->hasSameFieldCountForAllObjects()); + EXPECT_FALSE(listField->empty()); + + ihd1->m_simpleObjectsField.push_back(s1); + ihd1->m_simpleObjectsField.push_back(s2); + ihd1->m_simpleObjectsField.push_back(s3); + + EXPECT_EQ(4, listField->size()); + EXPECT_TRUE(listField->hasSameFieldCountForAllObjects()); + EXPECT_FALSE(listField->empty()); + + listField->erase(0); + EXPECT_EQ(3, listField->size()); + EXPECT_TRUE(listField->hasSameFieldCountForAllObjects()); + EXPECT_FALSE(listField->empty()); + + listField->deleteAllChildObjects(); + EXPECT_EQ(0, listField->size()); + EXPECT_TRUE(listField->hasSameFieldCountForAllObjects()); + EXPECT_TRUE(listField->empty()); + +} + + + +class ReferenceDemoPdmObject: public caf::PdmObject +{ + CAF_PDM_HEADER_INIT; +public: + + ReferenceDemoPdmObject() + { + CAF_PDM_InitObject("ReferenceDemoPdmObject", "", "Tooltip DemoPdmObject", "WhatsThis DemoPdmObject"); + + CAF_PDM_InitFieldNoDefault(&m_pointersField, "SimpleObjPtrField", "SimpleObjPtrField", "", "Tooltip", "WhatsThis"); + CAF_PDM_InitFieldNoDefault(&m_simpleObjPtrField2, "SimpleObjPtrField2", "SimpleObjPtrField2", "", "Tooltip", "WhatsThis"); + } + + // Fields + caf::PdmChildField m_pointersField; + caf::PdmChildArrayField m_simpleObjPtrField2; +}; + +CAF_PDM_SOURCE_INIT(ReferenceDemoPdmObject, "ReferenceDemoPdmObject"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(BaseTest, PdmReferenceHelper) +{ + SimpleObj* s1 = new SimpleObj; + s1->m_position = 1000; + s1->m_numbers.v().push_back(10); + + SimpleObj* s2 = new SimpleObj; + s2->m_position = 2000; + + SimpleObj* s3 = new SimpleObj; + s3->m_position = 3000; + + InheritedDemoObj* ihd1 = new InheritedDemoObj; + caf::PdmChildArrayFieldHandle* listField = &(ihd1->m_simpleObjectsField); + ihd1->m_simpleObjectsField.push_back(new SimpleObj); + + ihd1->m_simpleObjectsField.push_back(s1); + ihd1->m_simpleObjectsField.push_back(s2); + ihd1->m_simpleObjectsField.push_back(s3); + + { + QString refString = caf::PdmReferenceHelper::referenceFromRootToObject(NULL, s3); + EXPECT_TRUE(refString.isEmpty()); + + refString = caf::PdmReferenceHelper::referenceFromRootToObject(ihd1, s3); + QString expectedString = ihd1->m_simpleObjectsField.keyword() + " 3"; + EXPECT_STREQ(refString.toAscii(), expectedString.toAscii()); + + caf::PdmObjectHandle* fromRef = caf::PdmReferenceHelper::objectFromReference(ihd1, refString); + EXPECT_TRUE(fromRef == s3); + } + + ReferenceDemoPdmObject* objA = new ReferenceDemoPdmObject; + objA->m_pointersField = ihd1; + + { + QString refString = caf::PdmReferenceHelper::referenceFromRootToObject(objA, s3); + + caf::PdmObjectHandle* fromRef = caf::PdmReferenceHelper::objectFromReference(objA, refString); + EXPECT_TRUE(fromRef == s3); + } + + + // Test reference to field + { + QString refString = caf::PdmReferenceHelper::referenceFromRootToField(objA, &(ihd1->m_simpleObjectsField)); + + caf::PdmFieldHandle* fromRef = caf::PdmReferenceHelper::fieldFromReference(objA, refString); + EXPECT_TRUE(fromRef == &(ihd1->m_simpleObjectsField)); + } + +} + diff --git a/Fwk/AppFwk/cafTests/cafTensor_UnitTest/CMakeLists.txt b/Fwk/AppFwk/cafTests/cafTensor_UnitTest/CMakeLists.txt deleted file mode 100644 index a1df15fe93..0000000000 --- a/Fwk/AppFwk/cafTests/cafTensor_UnitTest/CMakeLists.txt +++ /dev/null @@ -1,32 +0,0 @@ -cmake_minimum_required (VERSION 2.8) - -project ( cafTensor_UnitTests ) - -set(RI_VIZ_FWK_ROOT ../../../Fwk/VizFwk CACHE PATH "Path to VizFwk") -set(RI_GTEST_ROOT .. CACHE PATH "Path to folder containing gtest folder") -set(RI_SRC_ROOT ../../cafTensor CACHE PATH "Path to the code to test") -set(RI_TEST_FILE "" CACHE FILEPATH "Path to test file") - -include(${RI_VIZ_FWK_ROOT}/CMake/Utils/ceeDetermineCompilerFlags.cmake) - -add_subdirectory(${RI_VIZ_FWK_ROOT}/LibCore buildVizFwk) - -add_definitions( -DTEST_FILE="${RI_TEST_FILE}") - -include_directories(${RI_VIZ_FWK_ROOT}/LibCore) -include_directories(${RI_GTEST_ROOT}) -include_directories(${RI_SRC_ROOT}) - -set( UNIT_TEST_CPP_SOURCES - main.cpp - cafTensor_UnitTests.cpp - ${RI_SRC_ROOT}/cafTensor3.cpp - ${RI_SRC_ROOT}/cafTensor3.h - ${RI_SRC_ROOT}/cafTensor3.inl - - ${RI_GTEST_ROOT}/gtest/gtest-all.cpp -) - -add_executable( ${PROJECT_NAME} ${UNIT_TEST_CPP_SOURCES} ) -target_link_libraries( ${PROJECT_NAME} LibCore) - diff --git a/Fwk/AppFwk/cafTests/cafTensor_UnitTest/cafTensor_UnitTests.cpp b/Fwk/AppFwk/cafTests/cafTensor_UnitTest/cafTensor_UnitTests.cpp deleted file mode 100644 index f6b43a695b..0000000000 --- a/Fwk/AppFwk/cafTests/cafTensor_UnitTest/cafTensor_UnitTests.cpp +++ /dev/null @@ -1,194 +0,0 @@ -///////////////////////////////////////////////////////////////////////////////// -// -// Copyright (C) 2015- Statoil ASA -// Copyright (C) 2015- Ceetron Solutions AS -// -// ResInsight is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. -// -// See the GNU General Public License at -// for more details. -// -///////////////////////////////////////////////////////////////////////////////// -#include "cafTensor3.h" - -#include "gtest/gtest.h" - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -TEST(cafTensor3Test, BasicTests) -{ - caf::Ten3f T1; - caf::Ten3f T2(1, 2, 3, 4, 5, 6); - caf::Ten3f T3(T2); - - EXPECT_EQ(1, T2[caf::Ten3f::SXX]); - EXPECT_EQ(2, T2[caf::Ten3f::SYY]); - EXPECT_EQ(3, T2[caf::Ten3f::SZZ]); - EXPECT_EQ(4, T2[caf::Ten3f::SXY]); - EXPECT_EQ(5, T2[caf::Ten3f::SYZ]); - EXPECT_EQ(6, T2[caf::Ten3f::SZX]); - - T1 = T2; - EXPECT_EQ(1, T1[caf::Ten3f::SXX]); - EXPECT_EQ(2, T1[caf::Ten3f::SYY]); - EXPECT_EQ(3, T1[caf::Ten3f::SZZ]); - EXPECT_EQ(4, T1[caf::Ten3f::SXY]); - EXPECT_EQ(5, T1[caf::Ten3f::SYZ]); - EXPECT_EQ(6, T1[caf::Ten3f::SZX]); - - EXPECT_TRUE(T2 == T3); - - EXPECT_TRUE(T1 == T2); - EXPECT_TRUE(T1.equals(T2)); - EXPECT_FALSE(T1 != T2); - - T1[caf::Ten3f::SXX] = 7; - - EXPECT_TRUE(T1 != T2); - EXPECT_FALSE(T1 == T2); - EXPECT_FALSE(T1.equals(T2)); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -TEST(cafTensor3Test, setFromNativeArray) -{ - float tensData[6] = {11,12,13,14,15,16}; - caf::Ten3f T1; - - T1.setFromAbaqusLayout(tensData); - EXPECT_EQ(11, T1[caf::Ten3f::SXX]); - EXPECT_EQ(12, T1[caf::Ten3f::SYY]); - EXPECT_EQ(13, T1[caf::Ten3f::SZZ]); - EXPECT_EQ(14, T1[caf::Ten3f::SXY]); - EXPECT_EQ(15, T1[caf::Ten3f::SZX]); - EXPECT_EQ(16, T1[caf::Ten3f::SYZ]); - - caf::Ten3f T2; - T2.setFromInternalLayout(tensData); - EXPECT_EQ(11, T2[caf::Ten3f::SXX]); - EXPECT_EQ(12, T2[caf::Ten3f::SYY]); - EXPECT_EQ(13, T2[caf::Ten3f::SZZ]); - EXPECT_EQ(14, T2[caf::Ten3f::SXY]); - EXPECT_EQ(15, T2[caf::Ten3f::SYZ]); - EXPECT_EQ(16, T2[caf::Ten3f::SZX]); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -TEST(cafTensor3Test, zero) -{ - caf::Ten3f T0(0,0,0,0,0,0); - - cvf::Vec3f pDirs[3]; - cvf::Vec3f p0 = T0.calculatePrincipals(pDirs); - - EXPECT_TRUE(p0 == cvf::Vec3f::ZERO); - EXPECT_TRUE(pDirs[0] == cvf::Vec3f::ZERO); - EXPECT_TRUE(pDirs[1] == cvf::Vec3f::ZERO); - EXPECT_TRUE(pDirs[2] == cvf::Vec3f::ZERO); - - float vm = T0.calculateVonMises(); - EXPECT_EQ(0.0f, vm ); -} -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -TEST(cafTensor3Test, undef) -{ - float inf = std::numeric_limits::infinity(); - caf::Ten3f T0(0,0,0,0,0,inf); - - cvf::Vec3f pDirs[3]; - cvf::Vec3f p0 = T0.calculatePrincipals(pDirs); - - EXPECT_TRUE(p0 == cvf::Vec3f(inf, inf, inf)); - EXPECT_TRUE(pDirs[0] == cvf::Vec3f::ZERO); - EXPECT_TRUE(pDirs[1] == cvf::Vec3f::ZERO); - EXPECT_TRUE(pDirs[2] == cvf::Vec3f::ZERO); - - float vm = T0.calculateVonMises(); - EXPECT_EQ(inf, vm ); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -TEST(cafTensor3Test, realTensors1) -{ - caf::Ten3f T0(80,50,20,40,45,50); - - cvf::Vec3f pDirs[3]; - cvf::Vec3f p0 = T0.calculatePrincipals(pDirs); - - EXPECT_NEAR( 143.8f, p0[0], 0.1 ); - EXPECT_NEAR( 23.6f, p0[1], 0.1 ); - EXPECT_NEAR( -17.4f, p0[2], 0.1 ); - - float vm = T0.calculateVonMises(); - EXPECT_NEAR(145.2f, vm, 0.1 ); -} - - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -TEST(cafTensor3Test, realTensors2) -{ - caf::Ten3f T0(20,50,80,50,45,40); - - cvf::Vec3f pDirs[3]; - cvf::Vec3f p0 = T0.calculatePrincipals(pDirs); - - EXPECT_NEAR( 143.8f, p0[0], 0.1 ); - EXPECT_NEAR( 23.9f, p0[1], 0.1 ); - EXPECT_NEAR( -17.6f, p0[2], 0.1 ); - - float vm = T0.calculateVonMises(); - EXPECT_NEAR(145.2f, vm, 0.1 ); -} - - - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -TEST(cafTensor3Test, realTensors3) -{ - caf::Ten3f T0(10,20,30,0,0,0); - - cvf::Vec3f pDirs[3]; - cvf::Vec3f p0 = T0.calculatePrincipals(pDirs); - - EXPECT_NEAR( 30.0f, p0[0], 0.1 ); - EXPECT_NEAR( 20.0f, p0[1], 0.1 ); - EXPECT_NEAR( 10.0f, p0[2], 0.1 ); - - EXPECT_NEAR( 0.0f, pDirs[0][0], 0.1 ); - EXPECT_NEAR( 0.0f, pDirs[0][1], 0.1 ); - EXPECT_NEAR( 1.0f, pDirs[0][2], 0.1 ); - - EXPECT_NEAR( 0.0f, pDirs[1][0], 0.1); - EXPECT_NEAR( 1.0f, pDirs[1][1], 0.1 ); - EXPECT_NEAR( 0.0f, pDirs[1][2], 0.1 ); - - EXPECT_NEAR( 1.0f, pDirs[2][0], 0.1 ); - EXPECT_NEAR( 0.0f, pDirs[2][1], 0.1 ); - EXPECT_NEAR( 0.0f, pDirs[2][2], 0.1 ); - - - float vm = T0.calculateVonMises(); - EXPECT_NEAR(17.3f, vm, 0.1 ); -} - - diff --git a/Fwk/AppFwk/cafTests/cafTensor_UnitTest/main.cpp b/Fwk/AppFwk/cafTests/cafTensor_UnitTest/main.cpp deleted file mode 100644 index 143593e6c0..0000000000 --- a/Fwk/AppFwk/cafTests/cafTensor_UnitTest/main.cpp +++ /dev/null @@ -1,42 +0,0 @@ -///////////////////////////////////////////////////////////////////////////////// -// -// Copyright (C) 2015 - Statoil ASA -// Copyright (C) 2015 - Ceetron Solutions AS -// -// ResInsight is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. -// -// See the GNU General Public License at -// for more details. -// -///////////////////////////////////////////////////////////////////////////////// - -#include "cvfBase.h" - -#include "gtest/gtest.h" -#include - -#include "cvfTrace.h" - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -int main(int argc, char **argv) -{ - cvf::Assert::setReportMode(cvf::Assert::CONSOLE); - - testing::InitGoogleTest(&argc, argv); - - int result = RUN_ALL_TESTS(); - - std::cout << "Please press to close the window."; - std::cin.get(); - - return result; -} diff --git a/Fwk/AppFwk/cafTests/cafTestApplication/CMakeLists.txt b/Fwk/AppFwk/cafTests/cafTestApplication/CMakeLists.txt index 9f12dcd8c3..71145da54c 100644 --- a/Fwk/AppFwk/cafTests/cafTestApplication/CMakeLists.txt +++ b/Fwk/AppFwk/cafTests/cafTestApplication/CMakeLists.txt @@ -1,7 +1,14 @@ cmake_minimum_required (VERSION 2.8) +# Qt +find_package ( Qt4 COMPONENTS QtCore QtGui QtMain QtOpenGl ) +include (${QT_USE_FILE}) + project ( cafTestApplication ) + +option(USE_COMMAND_FRAMEWORK "Use Caf Command Framework" ON) + # Qt MOC set ( QT_MOC_HEADERS MainWindow.h @@ -23,25 +30,58 @@ qt4_add_resources( QRC_FILES_CPP ) include_directories ( - ${CMAKE_SOURCE_DIR}/cafProjectDataModel - ${CMAKE_SOURCE_DIR}/cafUserInterface + ${cafProjectDataModel_SOURCE_DIR} + ${cafUserInterface_SOURCE_DIR} ) -# add the executable -add_executable ( ${PROJECT_NAME} +if (USE_COMMAND_FRAMEWORK) + include_directories ( + ${cafCommand_SOURCE_DIR} + ) + ADD_DEFINITIONS(-DTAP_USE_COMMAND_FRAMEWORK) +endif(USE_COMMAND_FRAMEWORK) + + +include_directories ( + ${cafPdmCore_SOURCE_DIR} + ${cafPdmUiCore_SOURCE_DIR} + ${cafPdmXml_SOURCE_DIR} +) + +set( PROJECT_FILES Main.cpp MainWindow.cpp WidgetLayoutTest.cpp +) + + +# add the executable +add_executable ( ${PROJECT_NAME} + ${PROJECT_FILES} ${MOC_FILES_CPP} ${QRC_FILES_CPP} ) -target_link_libraries ( ${PROJECT_NAME} +set (TAP_LINK_LIBRARIES cafUserInterface - cafProjectDataModel + cafPdmXml ${QT_LIBRARIES} + ) + +if (USE_COMMAND_FRAMEWORK) + set (TAP_LINK_LIBRARIES + ${TAP_LINK_LIBRARIES} + cafCommand + ) +endif(USE_COMMAND_FRAMEWORK) + + +target_link_libraries ( ${PROJECT_NAME} + ${TAP_LINK_LIBRARIES} ) +source_group("" FILES ${PROJECT_FILES}) + # Copy Qt Dlls if (MSVC) set (QTLIBLIST QtCore QtGui QtOpenGl) diff --git a/Fwk/AppFwk/cafTests/cafTestApplication/MainWindow.cpp b/Fwk/AppFwk/cafTests/cafTestApplication/MainWindow.cpp index 596821fa30..1070ca1279 100644 --- a/Fwk/AppFwk/cafTests/cafTestApplication/MainWindow.cpp +++ b/Fwk/AppFwk/cafTests/cafTestApplication/MainWindow.cpp @@ -1,4 +1,6 @@ +#include "cafPdmField.h" + #include "MainWindow.h" #include "WidgetLayoutTest.h" @@ -6,27 +8,41 @@ #include #include #include +#include + -#include "cafPdmField.h" -#include "cafPdmObject.h" -#include "cafPdmDocument.h" #include "cafAppEnum.h" -#include "cafUiTreeModelPdm.h" -#include "cafPdmUiPropertyView.h" + +#ifdef TAP_USE_COMMAND_FRAMEWORK +#include "cafCmdExecCommandManager.h" +#include "cafCmdSelectionHelper.h" +#include "cafCmdFeatureManager.h" +#endif + +#include "cafPdmObject.h" +#include "cafPdmObjectGroup.h" +#include "cafPdmProxyValueField.h" +#include "cafPdmPtrField.h" +#include "cafPdmReferenceHelper.h" #include "cafPdmUiFilePathEditor.h" #include "cafPdmUiListEditor.h" +#include "cafPdmUiPropertyView.h" +#include "cafPdmUiTableView.h" #include "cafPdmUiTextEditor.h" +#include "cafPdmUiTreeView.h" +#include "cafSelectionManager.h" -class DemoPdmObjectGroup: public caf::PdmObjectGroup +class DemoPdmObjectGroup : public caf::PdmObjectCollection { CAF_PDM_HEADER_INIT; public: DemoPdmObjectGroup() { - CAF_PDM_InitObject("Demo Object Group", "", "This group object is a demo of the CAF framework", "This group object is a demo of the CAF framework") + objects.uiCapability()->setUiHidden(true); + } }; @@ -41,14 +57,46 @@ class SmallDemoPdmObject: public caf::PdmObject { CAF_PDM_InitObject("Small Demo Object", ":/images/win/filenew.png", "This object is a demo of the CAF framework", "This object is a demo of the CAF framework"); + CAF_PDM_InitField(&m_toggleField, "Toggle", false, "Toggle Field", "", "Toggle Field tooltip", " Toggle Field whatsthis"); CAF_PDM_InitField(&m_doubleField, "BigNumber", 0.0, "Big Number", "", "Enter a big number here", "This is a place you can enter a big real value if you want" ); CAF_PDM_InitField(&m_intField, "IntNumber", 0, "Small Number", "", "Enter some small number here", "This is a place you can enter a small integer value if you want"); CAF_PDM_InitField(&m_textField, "TextField", QString(""), "Text", "", "Text tooltip", "This is a place you can enter a small integer value if you want"); + + m_proxyDoubleField.registerSetMethod(this, &SmallDemoPdmObject::setDoubleMember); + m_proxyDoubleField.registerGetMethod(this, &SmallDemoPdmObject::doubleMember); + CAF_PDM_InitFieldNoDefault(&m_proxyDoubleField, "ProxyDouble", "Proxy Double", "", "", ""); + + m_proxyDoubleField = 0; + if (!(m_proxyDoubleField == 3)) { std::cout << "Double is not 3 " << std::endl; } + } + caf::PdmField m_doubleField; caf::PdmField m_intField; caf::PdmField m_textField; + caf::PdmProxyValueField m_proxyDoubleField; + + caf::PdmField m_toggleField; + virtual caf::PdmFieldHandle* objectToggleField() + { + return &m_toggleField; + } + + virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) + { + if (changedField == &m_toggleField) + { + std::cout << "Toggle Field changed" << std::endl; + } + } + + void setDoubleMember(const double& d) { m_doubleMember = d; std::cout << "setDoubleMember" << std::endl; } + double doubleMember() const { std::cout << "doubleMember" << std::endl; return m_doubleMember; } + +private: + double m_doubleMember; + }; CAF_PDM_SOURCE_INIT(SmallDemoPdmObject, "SmallDemoPdmObject"); @@ -69,18 +117,94 @@ class SmallDemoPdmObjectA: public caf::PdmObject { CAF_PDM_InitObject("Small Demo Object A", "", "This object is a demo of the CAF framework", "This object is a demo of the CAF framework"); + CAF_PDM_InitField(&m_toggleField, "Toggle", false, "Toggle Field", "", "Toggle Field tooltip", " Toggle Field whatsthis"); CAF_PDM_InitField(&m_doubleField, "BigNumber", 0.0, "Big Number", "", "Enter a big number here", "This is a place you can enter a big real value if you want"); CAF_PDM_InitField(&m_intField, "IntNumber", 0, "Small Number", "", "Enter some small number here","This is a place you can enter a small integer value if you want"); - CAF_PDM_InitField(&m_textField, "TextField", QString(""), "Small Number", "", "Enter some small number here", "This is a place you can enter a small integer value if you want"); - CAF_PDM_InitField(&m_testEnumField, "TestEnumValue", caf::AppEnum(T1), "Small Number", "", "Enter some small number here", "This is a place you can enter a small integer value if you want"); + CAF_PDM_InitField(&m_textField, "TextField", QString("Small Demo Object A"), "Name Text Field", "", "", ""); + CAF_PDM_InitField(&m_testEnumField, "TestEnumValue", caf::AppEnum(T1), "EnumField", "", "", ""); + CAF_PDM_InitFieldNoDefault(&m_ptrField, "m_ptrField", "PtrField", "", "", ""); + + CAF_PDM_InitFieldNoDefault(&m_proxyEnumField, "ProxyEnumValue", "ProxyEnum", "", "", ""); + m_proxyEnumField.registerSetMethod(this, &SmallDemoPdmObjectA::setEnumMember); + m_proxyEnumField.registerGetMethod(this, &SmallDemoPdmObjectA::enumMember); + m_proxyEnumMember = T2; - m_testEnumField.setUiEditorTypeName(caf::PdmUiListEditor::uiEditorTypeName()); + m_testEnumField.capability()->setUiEditorTypeName(caf::PdmUiListEditor::uiEditorTypeName()); } caf::PdmField m_doubleField; caf::PdmField m_intField; caf::PdmField m_textField; caf::PdmField< caf::AppEnum > m_testEnumField; + caf::PdmPtrField m_ptrField; + + caf::PdmProxyValueField< caf::AppEnum > m_proxyEnumField; + void setEnumMember(const caf::AppEnum& val) { m_proxyEnumMember = val; } + caf::AppEnum enumMember() const { return m_proxyEnumMember; } + TestEnumType m_proxyEnumMember; + + + + caf::PdmField m_toggleField; + virtual caf::PdmFieldHandle* objectToggleField() + { + return &m_toggleField; + } + + virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) + { + if (changedField == &m_toggleField) + { + std::cout << "Toggle Field changed" << std::endl; + } + } + + virtual QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly) + { + QList options; + + + if (&m_ptrField == fieldNeedingOptions) + { + caf::PdmFieldHandle* field; + std::vector objects; + field = this->parentField(); + + field->childObjects(&objects); + + for (size_t i = 0; i < objects.size(); ++i) + { + QString userDesc; + + caf::PdmUiObjectHandle* uiObject = caf::uiObj(objects[i]); + if (uiObject) + { + if (uiObject->userDescriptionField()) + { + caf::PdmUiFieldHandle* uiFieldHandle = uiObject->userDescriptionField()->uiCapability(); + if (uiFieldHandle) + { + userDesc = uiFieldHandle->uiValue().toString(); + } + } + + options.push_back(caf::PdmOptionItemInfo(uiObject->uiName() + "(" + userDesc + ")", QVariant::fromValue(caf::PdmPointer(objects[i])))); + } + } + } + + if (useOptionsOnly) *useOptionsOnly = true; + + return options; + } + + //-------------------------------------------------------------------------------------------------- + /// + //-------------------------------------------------------------------------------------------------- + virtual caf::PdmFieldHandle* userDescriptionField() + { + return &m_textField; + } }; @@ -113,21 +237,23 @@ class DemoPdmObject: public caf::PdmObject { CAF_PDM_InitObject( "Demo Object", "", "This object is a demo of the CAF framework", "This object is a demo of the CAF framework"); + CAF_PDM_InitField(&m_toggleField, "Toggle", false, "Toggle Field", "", "Toggle Field tooltip", " Toggle Field whatsthis"); CAF_PDM_InitField(&m_doubleField, "BigNumber", 0.0, "Big Number", "", "Enter a big number here", "This is a place you can enter a big real value if you want"); CAF_PDM_InitField(&m_intField, "IntNumber", 0, "Small Number", "", "Enter some small number here", "This is a place you can enter a small integer value if you want" ); CAF_PDM_InitField(&m_boolField, "BooleanValue", false, "Boolean:" , "", "Boolean:Enter some small number here", "Boolean:This is a place you can enter a small integer value if you want"); - CAF_PDM_InitField(&m_textField, "TextField", QString(""), "", "", "", ""); + CAF_PDM_InitField(&m_textField, "TextField", QString("Demo Object Description Field"), "", "", "", ""); CAF_PDM_InitField(&m_filePath, "FilePath", QString(""), "Filename", "", "", ""); CAF_PDM_InitField(&m_longText, "LongText", QString("Test text"), "Long Text", "", "", ""); CAF_PDM_InitFieldNoDefault(&m_multiSelectList, "MultiSelect", "Selection List", "", "List" , "This is a multi selection list" ); + CAF_PDM_InitFieldNoDefault(&m_objectList, "ObjectList", "Objects list Field", "", "List" , "This is a list of PdmObjects" ); + CAF_PDM_InitFieldNoDefault(&m_objectListOfSameType, "m_objectListOfSameType", "Same type Objects list Field", "", "Same type List" , "Same type list of PdmObjects" ); + CAF_PDM_InitFieldNoDefault(&m_ptrField, "m_ptrField", "PtrField", "", "Same type List", "Same type list of PdmObjects"); - CAF_PDM_InitFieldNoDefault(&m_objectList, "ObjectList", "Objects list", "", "List" , "This is a list of PdmObjects" ); - - m_filePath.setUiEditorTypeName(caf::PdmUiFilePathEditor::uiEditorTypeName()); - m_filePath.setUiLabelPosition(caf::PdmUiItemInfo::TOP); - m_longText.setUiEditorTypeName(caf::PdmUiTextEditor::uiEditorTypeName()); - m_longText.setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN); + m_filePath.capability()->setUiEditorTypeName(caf::PdmUiFilePathEditor::uiEditorTypeName()); + m_filePath.capability()->setUiLabelPosition(caf::PdmUiItemInfo::TOP); + m_longText.capability()->setUiEditorTypeName(caf::PdmUiTextEditor::uiEditorTypeName()); + m_longText.capability()->setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN); } @@ -136,6 +262,7 @@ class DemoPdmObject: public caf::PdmObject //-------------------------------------------------------------------------------------------------- virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) { + uiOrdering.add(&m_ptrField); uiOrdering.add(&m_boolField); caf::PdmUiGroup* group1 = uiOrdering.addNewGroup("Name1"); group1->add(&m_doubleField); @@ -165,11 +292,34 @@ class DemoPdmObject: public caf::PdmObject options.push_back(caf::PdmOptionItemInfo("Choice 6", "Choice6")); } + + if (&m_ptrField == fieldNeedingOptions) + { + for (size_t i = 0; i < m_objectListOfSameType.size(); ++i) + { + caf::PdmUiObjectHandle* uiObject = caf::uiObj(m_objectListOfSameType[i]); + if (uiObject) + { + options.push_back(caf::PdmOptionItemInfo(uiObject->uiName(), QVariant::fromValue(caf::PdmPointer(m_objectListOfSameType[i])))); + } + } + } + if (useOptionsOnly) *useOptionsOnly = true; return options; } + //-------------------------------------------------------------------------------------------------- + /// + //-------------------------------------------------------------------------------------------------- + virtual caf::PdmFieldHandle* userDescriptionField() + { + return &m_textField; + } + + + // Fields caf::PdmField m_boolField; caf::PdmField m_doubleField; @@ -182,7 +332,25 @@ class DemoPdmObject: public caf::PdmObject caf::PdmField > m_multiSelectList; - caf::PdmPointersField< caf::PdmObject* > m_objectList; + caf::PdmChildArrayField< caf::PdmObjectHandle* > m_objectList; + caf::PdmChildArrayField< SmallDemoPdmObjectA* > m_objectListOfSameType; + caf::PdmPtrField m_ptrField; + + + caf::PdmField m_toggleField; + virtual caf::PdmFieldHandle* objectToggleField() + { + return &m_toggleField; + } + + virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) + { + if (changedField == &m_toggleField) + { + std::cout << "Toggle Field changed" << std::endl; + } + } + }; CAF_PDM_SOURCE_INIT(DemoPdmObject, "DemoPdmObject"); @@ -196,9 +364,10 @@ MainWindow* MainWindow::sm_mainWindowInstance = NULL; //-------------------------------------------------------------------------------------------------- MainWindow::MainWindow() { - m_treeView = NULL; - m_treeModelPdm = NULL; + // Initialize command framework + // Register default command features (add/delete item in list) + createActions(); createDockPanels(); @@ -206,6 +375,13 @@ MainWindow::MainWindow() setPdmRoot(m_testRoot); sm_mainWindowInstance = this; + caf::SelectionManager::instance()->setPdmRootObject(m_testRoot); + +#ifdef TAP_USE_COMMAND_FRAMEWORK + caf::CmdExecCommandManager::instance()->enableUndoCommandSystem(true); + undoView->setStack(caf::CmdExecCommandManager::instance()->undoStack()); +#endif + } //-------------------------------------------------------------------------------------------------- @@ -214,38 +390,66 @@ MainWindow::MainWindow() void MainWindow::createDockPanels() { { - QDockWidget* dockWidget = new QDockWidget("Workspace", this); + QDockWidget* dockWidget = new QDockWidget("PdmTreeView - controls property view", this); dockWidget->setObjectName("dockWidget"); dockWidget->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea); - m_treeView = new QTreeView(dockWidget); - dockWidget->setWidget(m_treeView); + m_pdmUiTreeView = new caf::PdmUiTreeView(dockWidget); + dockWidget->setWidget(m_pdmUiTreeView); addDockWidget(Qt::LeftDockWidgetArea, dockWidget); } - /* + { - QDockWidget* dockWidget = new QDockWidget("WidgetLayoutTest", this); + QDockWidget* dockWidget = new QDockWidget("cafPropertyView", this); dockWidget->setObjectName("dockWidget"); dockWidget->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea); - WidgetLayoutTest* widgetLayoutTest = new WidgetLayoutTest(dockWidget); - dockWidget->setWidget(widgetLayoutTest); + m_pdmUiPropertyView = new caf::PdmUiPropertyView(dockWidget); + dockWidget->setWidget(m_pdmUiPropertyView); addDockWidget(Qt::LeftDockWidgetArea, dockWidget); } - */ { - QDockWidget* dockWidget = new QDockWidget("cafPropertyView", this); + QDockWidget* dockWidget = new QDockWidget("PdmTreeView2 - controls table view", this); dockWidget->setObjectName("dockWidget"); dockWidget->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea); - m_pdmUiPropertyView = new caf::PdmUiPropertyView(dockWidget); - dockWidget->setWidget(m_pdmUiPropertyView); + m_pdmUiTreeView2 = new caf::PdmUiTreeView(dockWidget); + m_pdmUiTreeView2->enableDefaultContextMenu(true); + m_pdmUiTreeView2->enableSelectionManagerUpdating(true); + dockWidget->setWidget(m_pdmUiTreeView2); - addDockWidget(Qt::LeftDockWidgetArea, dockWidget); + addDockWidget(Qt::RightDockWidgetArea, dockWidget); + } + + { + QDockWidget* dockWidget = new QDockWidget("cafTableView", this); + dockWidget->setObjectName("dockWidget"); + dockWidget->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea); + + m_pdmUiTableView = new caf::PdmUiTableView(dockWidget); + m_pdmUiTableView->setSelectionRole(caf::SelectionManager::CURRENT); + m_pdmUiTableView->enableDefaultContextMenu(true); + + dockWidget->setWidget(m_pdmUiTableView); + + addDockWidget(Qt::RightDockWidgetArea, dockWidget); + } + + + { + QDockWidget* dockWidget = new QDockWidget("Undo stack", this); + dockWidget->setObjectName("dockWidget"); + dockWidget->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea); + + undoView = new QUndoView(this); + dockWidget->setWidget(undoView); + + addDockWidget(Qt::RightDockWidgetArea, dockWidget); } + } //-------------------------------------------------------------------------------------------------- @@ -256,44 +460,72 @@ void MainWindow::buildTestModel() m_testRoot = new DemoPdmObjectGroup; DemoPdmObject* demoObject = new DemoPdmObject; - m_testRoot->addObject(demoObject); + m_testRoot->objects.push_back(demoObject); SmallDemoPdmObject* smallObj1 = new SmallDemoPdmObject; - m_testRoot->addObject(smallObj1); + m_testRoot->objects.push_back(smallObj1); SmallDemoPdmObjectA* smallObj2 = new SmallDemoPdmObjectA; - m_testRoot->addObject(smallObj2); + m_testRoot->objects.push_back(smallObj2); - demoObject->m_objectList.push_back(new DemoPdmObject); + DemoPdmObject* demoObj2 = new DemoPdmObject; + + demoObject->m_textField = "Mitt Demo Obj"; + demoObject->m_objectList.push_back(demoObj2); demoObject->m_objectList.push_back(new SmallDemoPdmObjectA()); + SmallDemoPdmObject* smallObj3 = new SmallDemoPdmObject(); + demoObject->m_objectList.push_back(smallObj3); demoObject->m_objectList.push_back(new SmallDemoPdmObject()); + + demoObject->m_objectListOfSameType.push_back(new SmallDemoPdmObjectA()); + demoObject->m_objectListOfSameType.push_back(new SmallDemoPdmObjectA()); + demoObject->m_objectListOfSameType.push_back(new SmallDemoPdmObjectA()); + demoObject->m_objectListOfSameType.push_back(new SmallDemoPdmObjectA()); + + + demoObj2->m_objectList.push_back(new SmallDemoPdmObjectA()); + demoObj2->m_objectList.push_back(new SmallDemoPdmObjectA()); + demoObj2->m_objectList.push_back(new SmallDemoPdmObject()); + + delete smallObj3; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void MainWindow::setPdmRoot(caf::PdmObject* pdmRoot) +void MainWindow::setPdmRoot(caf::PdmObjectHandle* pdmRoot) { - caf::PdmUiTreeItem* treeItemRoot = caf::UiTreeItemBuilderPdm::buildViewItems(NULL, 0, pdmRoot); - - if (!m_treeModelPdm) + caf::PdmUiObjectHandle* uiObject = uiObj(pdmRoot); + if (uiObject) { - m_treeModelPdm = new caf::UiTreeModelPdm(this); + m_pdmUiTreeView->setPdmItem(uiObject); } - m_treeModelPdm->setTreeItemRoot(treeItemRoot); + connect(m_pdmUiTreeView, SIGNAL(selectionChanged()), SLOT(slotSimpleSelectionChanged())); - assert(m_treeView); - m_treeView->setModel(m_treeModelPdm); + // Set up test of using a field as a root item + // Hack, because we know that pdmRoot is a PdmObjectGroup ... - if (treeItemRoot) + std::vector fields; + pdmRoot->fields(fields); + if (fields.size()) { - if (m_treeView->selectionModel()) + caf::PdmFieldHandle* field = fields[0]; + caf::PdmUiFieldHandle* uiFieldHandle = field->uiCapability(); + if (uiFieldHandle) { - connect(m_treeView->selectionModel(), SIGNAL(selectionChanged( const QItemSelection & , const QItemSelection & )), SLOT(slotSelectionChanged( const QItemSelection & , const QItemSelection & ))); + m_pdmUiTreeView2->setPdmItem(uiFieldHandle); + uiFieldHandle->updateConnectedEditors(); } } + + if (uiObject) + { + m_pdmUiTreeView2->setPdmItem(uiObject); + } + + connect(m_pdmUiTreeView2, SIGNAL(selectionChanged()), SLOT(slotShowTableView())); } //-------------------------------------------------------------------------------------------------- @@ -301,6 +533,10 @@ void MainWindow::setPdmRoot(caf::PdmObject* pdmRoot) //-------------------------------------------------------------------------------------------------- MainWindow::~MainWindow() { + m_pdmUiTreeView->setPdmItem(NULL); + m_pdmUiTreeView2->setPdmItem(NULL); + m_pdmUiPropertyView->showProperties(NULL); + m_pdmUiTableView->setListField(NULL); } //-------------------------------------------------------------------------------------------------- @@ -308,15 +544,9 @@ MainWindow::~MainWindow() //-------------------------------------------------------------------------------------------------- void MainWindow::releaseTestData() { - m_treeView->setModel(NULL); - if (m_treeModelPdm) - { - delete m_treeModelPdm; - } - if (m_testRoot) { - m_testRoot->deleteObjects(); + m_testRoot->objects.deleteAllChildObjects(); delete m_testRoot; } } @@ -356,27 +586,35 @@ void MainWindow::createActions() //-------------------------------------------------------------------------------------------------- void MainWindow::slotInsert() { - QModelIndex index = m_treeView->selectionModel()->currentIndex(); - QAbstractItemModel *model = m_treeView->model(); + std::vector selection; + m_pdmUiTreeView->selectedUiItems(selection); - if (!model->insertRow(0, index)) - return; + for (size_t i = 0; i < selection.size(); ++i) + { + caf::PdmUiFieldHandle* uiFh = dynamic_cast(selection[i]); + caf::PdmChildArrayField< caf::PdmObjectHandle*> * field = NULL; - QModelIndex child = model->index(0, 0, index); + if (uiFh) field = dynamic_cast *>(uiFh->fieldHandle()); + + if (field) + { + field->push_back(new DemoPdmObject); + field->capability()->updateConnectedEditors(); + return; + } + #if 0 + caf::PdmChildArrayFieldHandle* listField = NULL; -// ( -// for (int column = 0; column < model->columnCount(index); ++column) -// { -// QModelIndex child = model->index(0, column, index); -// model->setData(child, QVariant("[No data]"), Qt::EditRole); -// if (!model->headerData(column, Qt::Horizontal).isValid()) -// model->setHeaderData(column, Qt::Horizontal, QVariant("[No header]"), -// Qt::EditRole); -// } -// ) + if (uiFh) listField = dynamic_cast(uiFh->fieldHandle()); - m_treeView->selectionModel()->setCurrentIndex(model->index(0, 0, index), QItemSelectionModel::ClearAndSelect); + if (listField) + { + caf::PdmObjectHandle* obj = listField->createAppendObject(); + listField->capability()->updateConnectedEditors(); + } + #endif + } } //-------------------------------------------------------------------------------------------------- @@ -384,9 +622,29 @@ void MainWindow::slotInsert() //-------------------------------------------------------------------------------------------------- void MainWindow::slotRemove() { - QModelIndex index = m_treeView->selectionModel()->currentIndex(); - QAbstractItemModel *model = m_treeView->model(); - model->removeRow(index.row(), index.parent()); + std::vector selection; + m_pdmUiTreeView->selectedUiItems(selection); + + for (size_t i = 0; i < selection.size(); ++i) + { + caf::PdmObjectHandle* obj = dynamic_cast< caf::PdmObjectHandle*>(selection[i]); + if (obj) + { + caf::PdmFieldHandle* field = obj->parentField(); + + // Ordering is important + + field->removeChildObject(obj); + + // Delete object + delete obj; + + // Update editors + field->uiCapability()->updateConnectedEditors(); + + break; + } + } } //-------------------------------------------------------------------------------------------------- @@ -400,19 +658,53 @@ void MainWindow::slotRemoveAll() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void MainWindow::slotSelectionChanged(const QItemSelection & selected, const QItemSelection & deselected ) +void MainWindow::slotSimpleSelectionChanged() +{ + std::vector selection; + m_pdmUiTreeView->selectedUiItems(selection); + caf::PdmObjectHandle* obj = NULL; + caf::PdmChildArrayFieldHandle* listField = NULL; + + if (selection.size()) + { + caf::PdmUiObjectHandle* pdmUiObj = dynamic_cast( selection[0] ); + if (pdmUiObj) obj = pdmUiObj->objectHandle(); + } + + m_pdmUiPropertyView->showProperties(obj); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void MainWindow::slotShowTableView() { - if (selected.indexes().size() == 1) + std::vector selection; + m_pdmUiTreeView2->selectedUiItems(selection); + caf::PdmObjectHandle* obj = NULL; + caf::PdmChildArrayFieldHandle* listField = NULL; + + if (selection.size()) { - QModelIndex mi = selected.indexes()[0]; - caf::PdmUiTreeItem* treeItem = m_treeModelPdm->getTreeItemFromIndex(mi); - if (treeItem && treeItem->dataObject()) + caf::PdmUiItem* pdmUiItem = selection[0]; + + caf::PdmUiFieldHandle* guiField = dynamic_cast(pdmUiItem); + + if (guiField) listField = dynamic_cast(guiField->fieldHandle()); + + if (listField) { - m_pdmUiPropertyView->showProperties(treeItem->dataObject()); + if (!listField->hasSameFieldCountForAllObjects()) + { + listField = NULL; + } } } - else + + m_pdmUiTableView->setListField(listField); + + if (listField) { - m_pdmUiPropertyView->showProperties(NULL); + listField->uiCapability()->updateConnectedEditors(); } } diff --git a/Fwk/AppFwk/cafTests/cafTestApplication/MainWindow.h b/Fwk/AppFwk/cafTests/cafTestApplication/MainWindow.h index d95234afb8..b9728a6824 100644 --- a/Fwk/AppFwk/cafTests/cafTestApplication/MainWindow.h +++ b/Fwk/AppFwk/cafTests/cafTestApplication/MainWindow.h @@ -6,13 +6,16 @@ class DemoPdmObject; class QTreeView; +class QUndoView; namespace caf { - class PdmObjectGroup; - class PdmObject; + class PdmObjectCollection; + class PdmObjectHandle; class UiTreeModelPdm; class PdmUiPropertyView; + class PdmUiTreeView; + class PdmUiTableView; } class MainWindow : public QMainWindow @@ -24,7 +27,7 @@ class MainWindow : public QMainWindow ~MainWindow(); static MainWindow* instance(); - void setPdmRoot(caf::PdmObject* pdmRoot); + void setPdmRoot(caf::PdmObjectHandle* pdmRoot); private: void createActions(); @@ -40,17 +43,21 @@ private slots: void slotInsert(); void slotRemove(); void slotRemoveAll(); - void slotSelectionChanged(const QItemSelection &, const QItemSelection & ); + + void slotSimpleSelectionChanged(); + void slotShowTableView(); private: static MainWindow* sm_mainWindowInstance; private: - QTreeView* m_treeView; - caf::UiTreeModelPdm* m_treeModelPdm; - caf::PdmUiPropertyView* m_pdmUiPropertyView; - caf::PdmObjectGroup* m_testRoot; + QUndoView* undoView; + caf::PdmUiTreeView* m_pdmUiTreeView; + caf::PdmUiTreeView* m_pdmUiTreeView2; + caf::PdmUiPropertyView* m_pdmUiPropertyView; + caf::PdmUiTableView* m_pdmUiTableView; + caf::PdmObjectCollection* m_testRoot; }; diff --git a/Fwk/AppFwk/cafTests/cafTestApplication/TapCvfSpecialization.cpp b/Fwk/AppFwk/cafTests/cafTestApplication/TapCvfSpecialization.cpp new file mode 100644 index 0000000000..4b12fea0a1 --- /dev/null +++ b/Fwk/AppFwk/cafTests/cafTestApplication/TapCvfSpecialization.cpp @@ -0,0 +1,56 @@ +#include "TapCvfSpecialization.h" +/* + +#include "MainWindow.h" +#include "WidgetLayoutTest.h" + +#include +#include +#include +#include +#include + + +#include "cafAppEnum.h" +#include "cafAppExecCommandManager.h" +#include "cafCommandFeaturesCore.h" +#include "cafCommandFeatureManager.h" +#include "cafPdmDocument.h" +#include "cafPdmObject.h" +#include "cafPdmUiFilePathEditor.h" +#include "cafPdmUiListEditor.h" +#include "cafPdmUiPropertyView.h" +#include "cafPdmUiTableView.h" +#include "cafPdmUiTextEditor.h" +#include "cafPdmUiTreeView.h" +#include "cafPdmReferenceHelper.h" +#include "cafSelectionManager.h" +#include "cafUiTreeModelPdm.h" +#include "cafPdmProxyValueField.h" +#include "cafPdmPtrField.h" +*/ + +CAF_PDM_SOURCE_INIT(TapCvfSpecialization, "TapCvfSpecialization"); + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TapCvfSpecialization::TapCvfSpecialization() +{ + CAF_PDM_InitObject("Test Object for type specializations", "", "", ""); + +/* + CAF_PDM_InitField(&m_toggleField, "Toggle", false, "Toggle Field", "", "Toggle Field tooltip", " Toggle Field whatsthis"); + CAF_PDM_InitField(&m_doubleField, "BigNumber", 0.0, "Big Number", "", "Enter a big number here", "This is a place you can enter a big real value if you want"); + CAF_PDM_InitField(&m_intField, "IntNumber", 0, "Small Number", "", "Enter some small number here", "This is a place you can enter a small integer value if you want"); + CAF_PDM_InitField(&m_textField, "TextField", QString(""), "Text", "", "Text tooltip", "This is a place you can enter a small integer value if you want"); + + m_proxyDoubleField.registerSetMethod(this, &SmallDemoPdmObject::setDoubleMember); + m_proxyDoubleField.registerGetMethod(this, &SmallDemoPdmObject::doubleMember); + CAF_PDM_InitFieldNoDefault(&m_proxyDoubleField, "ProxyDouble", "Proxy Double", "", "", ""); + + m_proxyDoubleField = 0; + if (!(m_proxyDoubleField == 3)) { std::cout << "Double is not 3 " << std::endl; } +*/ +} diff --git a/Fwk/AppFwk/cafTests/cafTestApplication/TapCvfSpecialization.h b/Fwk/AppFwk/cafTests/cafTestApplication/TapCvfSpecialization.h new file mode 100644 index 0000000000..c2c7bc9cbe --- /dev/null +++ b/Fwk/AppFwk/cafTests/cafTestApplication/TapCvfSpecialization.h @@ -0,0 +1,41 @@ +#pragma once + + +#include "..\LibCore\cvfBase.h" +#include "..\LibCore\cvfColor3.h" +#include "..\LibCore\cvfVector3.h" +#include "..\LibCore\cvfMatrix4.h" + +#include "cafPdmObject.h" +#include "cafPdmField.h" + + + +class TapCvfSpecialization : public caf::PdmObject +{ + CAF_PDM_HEADER_INIT; +public: + + TapCvfSpecialization(); + + caf::PdmField m_colorField; + caf::PdmField m_vectorField; + caf::PdmField m_matrixField; + +/* + virtual caf::PdmFieldHandle* objectToggleField() + { + return &m_toggleField; + } + + virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) + { + if (changedField == &m_toggleField) + { + std::cout << "Toggle Field changed" << std::endl; + } + } +*/ + +}; + diff --git a/Fwk/AppFwk/cafTests/cafTestCvfApplication/CMakeLists.txt b/Fwk/AppFwk/cafTests/cafTestCvfApplication/CMakeLists.txt new file mode 100644 index 0000000000..2497678191 --- /dev/null +++ b/Fwk/AppFwk/cafTests/cafTestCvfApplication/CMakeLists.txt @@ -0,0 +1,96 @@ +cmake_minimum_required (VERSION 2.8) + +# Qt +find_package ( Qt4 COMPONENTS QtCore QtGui QtMain QtOpenGl ) +include (${QT_USE_FILE}) + +project ( cafTestCvfApplication ) + +# Qt MOC +set ( QT_MOC_HEADERS + MainWindow.h + WidgetLayoutTest.h +) + +qt4_wrap_cpp( MOC_FILES_CPP + ${QT_MOC_HEADERS} +) + +# Resource file +set( QRC_FILES + textedit.qrc +) + +# Runs RCC on specified files +qt4_add_resources( QRC_FILES_CPP + ${QRC_FILES} +) + +include_directories ( + ${LibCore_SOURCE_DIR} + ${LibGeometry_SOURCE_DIR} + ${LibGuiQt_SOURCE_DIR} + ${LibRender_SOURCE_DIR} + ${LibViewing_SOURCE_DIR} + + ${cafPdmCore_SOURCE_DIR} + ${cafPdmUiCore_SOURCE_DIR} + ${cafPdmXml_SOURCE_DIR} + ${cafProjectDataModel_SOURCE_DIR} + + ${cafCommand_SOURCE_DIR} +# ${cafViewer_SOURCE_DIR} + ${cafUserInterface_SOURCE_DIR} + ${cafPdmCvf_SOURCE_DIR} +# ${CommonCode_SOURCE_DIR} + +) + +set( PROJECT_FILES + Main.cpp + MainWindow.cpp + WidgetLayoutTest.cpp + + TapCvfSpecialization.cpp + TapProject.cpp +) + + +# add the executable +add_executable ( ${PROJECT_NAME} + ${PROJECT_FILES} + ${MOC_FILES_CPP} + ${QRC_FILES_CPP} +) + +target_link_libraries ( ${PROJECT_NAME} + + LibCore + + cafPdmCore + cafPdmUiCore + cafPdmXml + cafProjectDataModel + + cafCommand + cafUserInterface + + cafPdmCvf + + ${QT_LIBRARIES} +) + +source_group("" FILES ${PROJECT_FILES}) + +# Copy Qt Dlls +if (MSVC) + set (QTLIBLIST QtCore QtGui QtOpenGl) + foreach (qtlib ${QTLIBLIST}) + + # Debug + execute_process(COMMAND cmake -E copy_if_different ${QT_BINARY_DIR}/${qtlib}d4.dll ${CMAKE_CURRENT_BINARY_DIR}/Debug/${qtlib}d4.dll) + + # Release + execute_process(COMMAND cmake -E copy_if_different ${QT_BINARY_DIR}/${qtlib}4.dll ${CMAKE_CURRENT_BINARY_DIR}/Release/${qtlib}4.dll) + endforeach( qtlib ) +endif(MSVC) diff --git a/Fwk/AppFwk/cafTests/cafTestCvfApplication/Main.cpp b/Fwk/AppFwk/cafTests/cafTestCvfApplication/Main.cpp new file mode 100644 index 0000000000..8151364084 --- /dev/null +++ b/Fwk/AppFwk/cafTests/cafTestCvfApplication/Main.cpp @@ -0,0 +1,17 @@ + +#include "MainWindow.h" + +#include + +#include "cafPdmFieldCvfColor.h" + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + + MainWindow window; + window.setWindowTitle("Ceetron Application Framework Test Application"); + window.show(); + + return app.exec(); +} diff --git a/Fwk/AppFwk/cafTests/cafTestCvfApplication/MainWindow.cpp b/Fwk/AppFwk/cafTests/cafTestCvfApplication/MainWindow.cpp new file mode 100644 index 0000000000..e249c45eee --- /dev/null +++ b/Fwk/AppFwk/cafTests/cafTestCvfApplication/MainWindow.cpp @@ -0,0 +1,771 @@ + +#include "cafPdmField.h" + +#include "MainWindow.h" +#include "WidgetLayoutTest.h" + +#include +#include +#include +#include +#include + + +#include "cafAppEnum.h" +#include "cafAppExecCommandManager.h" +#include "cafCommandFeaturesCore.h" +#include "cafCommandFeatureManager.h" +#include "cafPdmDocument.h" +#include "cafPdmObject.h" +#include "cafPdmUiFilePathEditor.h" +#include "cafPdmUiListEditor.h" +#include "cafPdmUiPropertyView.h" +#include "cafPdmUiTableView.h" +#include "cafPdmUiTextEditor.h" +#include "cafPdmUiTreeView.h" +#include "cafPdmReferenceHelper.h" +#include "cafSelectionManager.h" +#include "cafUiTreeModelPdm.h" +#include "cafPdmProxyValueField.h" +#include "cafPdmPtrField.h" + + +class DemoPdmObjectGroup: public caf::PdmObjectGroup +{ + CAF_PDM_HEADER_INIT; +public: + + DemoPdmObjectGroup() + { + + } +}; + +CAF_PDM_SOURCE_INIT(DemoPdmObjectGroup, "DemoPdmObjectGroup"); + +class SmallDemoPdmObject: public caf::PdmObject +{ + CAF_PDM_HEADER_INIT; +public: + + SmallDemoPdmObject() + { + CAF_PDM_InitObject("Small Demo Object", ":/images/win/filenew.png", "This object is a demo of the CAF framework", "This object is a demo of the CAF framework"); + + CAF_PDM_InitField(&m_toggleField, "Toggle", false, "Toggle Field", "", "Toggle Field tooltip", " Toggle Field whatsthis"); + CAF_PDM_InitField(&m_doubleField, "BigNumber", 0.0, "Big Number", "", "Enter a big number here", "This is a place you can enter a big real value if you want" ); + CAF_PDM_InitField(&m_intField, "IntNumber", 0, "Small Number", "", "Enter some small number here", "This is a place you can enter a small integer value if you want"); + CAF_PDM_InitField(&m_textField, "TextField", QString(""), "Text", "", "Text tooltip", "This is a place you can enter a small integer value if you want"); + + m_proxyDoubleField.registerSetMethod(this, &SmallDemoPdmObject::setDoubleMember); + m_proxyDoubleField.registerGetMethod(this, &SmallDemoPdmObject::doubleMember); + CAF_PDM_InitFieldNoDefault(&m_proxyDoubleField, "ProxyDouble", "Proxy Double", "", "", ""); + + m_proxyDoubleField = 0; + if (!(m_proxyDoubleField == 3)) { std::cout << "Double is not 3 " << std::endl; } + + } + + + caf::PdmField m_doubleField; + caf::PdmField m_intField; + caf::PdmField m_textField; + caf::PdmProxyValueField m_proxyDoubleField; + + caf::PdmField m_toggleField; + virtual caf::PdmFieldHandle* objectToggleField() + { + return &m_toggleField; + } + + virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) + { + if (changedField == &m_toggleField) + { + std::cout << "Toggle Field changed" << std::endl; + } + } + + void setDoubleMember(const double& d) { m_doubleMember = d; std::cout << "setDoubleMember" << std::endl; } + double doubleMember() const { std::cout << "doubleMember" << std::endl; return m_doubleMember; } + +private: + double m_doubleMember; + +}; + +CAF_PDM_SOURCE_INIT(SmallDemoPdmObject, "SmallDemoPdmObject"); + + +class SmallDemoPdmObjectA: public caf::PdmObject +{ + CAF_PDM_HEADER_INIT; +public: + + enum TestEnumType + { + T1, T2, T3 + }; + + + SmallDemoPdmObjectA() + { + CAF_PDM_InitObject("Small Demo Object A", "", "This object is a demo of the CAF framework", "This object is a demo of the CAF framework"); + + CAF_PDM_InitField(&m_toggleField, "Toggle", false, "Toggle Field", "", "Toggle Field tooltip", " Toggle Field whatsthis"); + CAF_PDM_InitField(&m_doubleField, "BigNumber", 0.0, "Big Number", "", "Enter a big number here", "This is a place you can enter a big real value if you want"); + CAF_PDM_InitField(&m_intField, "IntNumber", 0, "Small Number", "", "Enter some small number here","This is a place you can enter a small integer value if you want"); + CAF_PDM_InitField(&m_textField, "TextField", QString("Small Demo Object A"), "Name Text Field", "", "", ""); + CAF_PDM_InitField(&m_testEnumField, "TestEnumValue", caf::AppEnum(T1), "EnumField", "", "", ""); + CAF_PDM_InitFieldNoDefault(&m_ptrField, "m_ptrField", "PtrField", "", "", ""); + + CAF_PDM_InitFieldNoDefault(&m_proxyEnumField, "ProxyEnumValue", "ProxyEnum", "", "", ""); + m_proxyEnumField.registerSetMethod(this, &SmallDemoPdmObjectA::setEnumMember); + m_proxyEnumField.registerGetMethod(this, &SmallDemoPdmObjectA::enumMember); + m_proxyEnumMember = T2; + + m_testEnumField.capability()->setUiEditorTypeName(caf::PdmUiListEditor::uiEditorTypeName()); + } + + caf::PdmField m_doubleField; + caf::PdmField m_intField; + caf::PdmField m_textField; + caf::PdmField< caf::AppEnum > m_testEnumField; + caf::PdmPtrField m_ptrField; + + caf::PdmProxyValueField< caf::AppEnum > m_proxyEnumField; + void setEnumMember(const caf::AppEnum& val) { m_proxyEnumMember = val; } + caf::AppEnum enumMember() const { return m_proxyEnumMember; } + TestEnumType m_proxyEnumMember; + + + + caf::PdmField m_toggleField; + virtual caf::PdmFieldHandle* objectToggleField() + { + return &m_toggleField; + } + + virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) + { + if (changedField == &m_toggleField) + { + std::cout << "Toggle Field changed" << std::endl; + } + } + + virtual QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly) + { + QList options; + + + if (&m_ptrField == fieldNeedingOptions) + { + caf::PdmFieldHandle* field; + std::vector objects; + field = this->parentField(); + + field->childObjects(&objects); + + for (size_t i = 0; i < objects.size(); ++i) + { + QString userDesc; + + caf::PdmUiObjectHandle* uiObject = caf::uiObj(objects[i]); + if (uiObject) + { + if (uiObject->userDescriptionField()) + { + caf::PdmUiFieldHandle* uiFieldHandle = caf::uiField(uiObject->userDescriptionField()); + if (uiFieldHandle) + { + userDesc = uiFieldHandle->uiValue().toString(); + } + } + + options.push_back(caf::PdmOptionItemInfo(uiObject->uiName() + "(" + userDesc + ")", QVariant::fromValue(caf::PdmPointer(objects[i])))); + } + } + } + + if (useOptionsOnly) *useOptionsOnly = true; + + return options; + } + + //-------------------------------------------------------------------------------------------------- + /// + //-------------------------------------------------------------------------------------------------- + virtual caf::PdmFieldHandle* userDescriptionField() + { + return &m_textField; + } + +}; + +CAF_PDM_SOURCE_INIT(SmallDemoPdmObjectA, "SmallDemoPdmObjectA"); + +namespace caf +{ + template<> + void AppEnum::setUp() + { + addItem(SmallDemoPdmObjectA::T1, "T1", "An A letter"); + addItem(SmallDemoPdmObjectA::T2, "T2", "A B letter"); + addItem(SmallDemoPdmObjectA::T3, "T3", "A B C letter"); + setDefault(SmallDemoPdmObjectA::T1); + + } + +} +Q_DECLARE_METATYPE(caf::AppEnum); + + + + +class DemoPdmObject: public caf::PdmObject +{ + CAF_PDM_HEADER_INIT; +public: + + DemoPdmObject() + { + CAF_PDM_InitObject( "Demo Object", "", "This object is a demo of the CAF framework", "This object is a demo of the CAF framework"); + + CAF_PDM_InitField(&m_toggleField, "Toggle", false, "Toggle Field", "", "Toggle Field tooltip", " Toggle Field whatsthis"); + CAF_PDM_InitField(&m_doubleField, "BigNumber", 0.0, "Big Number", "", "Enter a big number here", "This is a place you can enter a big real value if you want"); + CAF_PDM_InitField(&m_intField, "IntNumber", 0, "Small Number", "", "Enter some small number here", "This is a place you can enter a small integer value if you want" ); + CAF_PDM_InitField(&m_boolField, "BooleanValue", false, "Boolean:" , "", "Boolean:Enter some small number here", "Boolean:This is a place you can enter a small integer value if you want"); + CAF_PDM_InitField(&m_textField, "TextField", QString("Demo Object Description Field"), "", "", "", ""); + CAF_PDM_InitField(&m_filePath, "FilePath", QString(""), "Filename", "", "", ""); + CAF_PDM_InitField(&m_longText, "LongText", QString("Test text"), "Long Text", "", "", ""); + + CAF_PDM_InitFieldNoDefault(&m_multiSelectList, "MultiSelect", "Selection List", "", "List" , "This is a multi selection list" ); + CAF_PDM_InitFieldNoDefault(&m_objectList, "ObjectList", "Objects list Field", "", "List" , "This is a list of PdmObjects" ); + CAF_PDM_InitFieldNoDefault(&m_objectListOfSameType, "m_objectListOfSameType", "Same type Objects list Field", "", "Same type List" , "Same type list of PdmObjects" ); + CAF_PDM_InitFieldNoDefault(&m_ptrField, "m_ptrField", "PtrField", "", "Same type List", "Same type list of PdmObjects"); + + m_filePath.capability()->setUiEditorTypeName(caf::PdmUiFilePathEditor::uiEditorTypeName()); + m_filePath.capability()->setUiLabelPosition(caf::PdmUiItemInfo::TOP); + m_longText.capability()->setUiEditorTypeName(caf::PdmUiTextEditor::uiEditorTypeName()); + m_longText.capability()->setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN); + + } + + //-------------------------------------------------------------------------------------------------- + /// + //-------------------------------------------------------------------------------------------------- + virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) + { + uiOrdering.add(&m_ptrField); + uiOrdering.add(&m_boolField); + caf::PdmUiGroup* group1 = uiOrdering.addNewGroup("Name1"); + group1->add(&m_doubleField); + caf::PdmUiGroup* group2 = uiOrdering.addNewGroup("Name2"); + group2->add(&m_intField); + caf::PdmUiGroup* group3 = group2->addNewGroup("Name3"); + group3->add(&m_textField); + + //uiConfig->add(&f3); + //uiConfig->forgetRemainingFields(); + } + + //-------------------------------------------------------------------------------------------------- + /// + //-------------------------------------------------------------------------------------------------- + virtual QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly) + { + QList options; + if (&m_multiSelectList == fieldNeedingOptions) + { + + options.push_back(caf::PdmOptionItemInfo("Choice 1", "Choice1")); + options.push_back(caf::PdmOptionItemInfo("Choice 2", "Choice2")); + options.push_back(caf::PdmOptionItemInfo("Choice 3", "Choice3")); + options.push_back(caf::PdmOptionItemInfo("Choice 4", "Choice4")); + options.push_back(caf::PdmOptionItemInfo("Choice 5", "Choice5")); + options.push_back(caf::PdmOptionItemInfo("Choice 6", "Choice6")); + + } + + if (&m_ptrField == fieldNeedingOptions) + { + for (size_t i = 0; i < m_objectListOfSameType.size(); ++i) + { + caf::PdmUiObjectHandle* uiObject = caf::uiObj(m_objectListOfSameType[i]); + if (uiObject) + { + options.push_back(caf::PdmOptionItemInfo(uiObject->uiName(), QVariant::fromValue(caf::PdmPointer(m_objectListOfSameType[i])))); + } + } + } + + if (useOptionsOnly) *useOptionsOnly = true; + + return options; + } + + //-------------------------------------------------------------------------------------------------- + /// + //-------------------------------------------------------------------------------------------------- + virtual caf::PdmFieldHandle* userDescriptionField() + { + return &m_textField; + } + + + + // Fields + caf::PdmField m_boolField; + caf::PdmField m_doubleField; + caf::PdmField m_intField; + caf::PdmField m_textField; + + caf::PdmField m_filePath; + + caf::PdmField m_longText; + caf::PdmField > m_multiSelectList; + + + caf::PdmChildArrayField< caf::PdmObjectHandle* > m_objectList; + caf::PdmChildArrayField< SmallDemoPdmObjectA* > m_objectListOfSameType; + caf::PdmPtrField m_ptrField; + + + caf::PdmField m_toggleField; + virtual caf::PdmFieldHandle* objectToggleField() + { + return &m_toggleField; + } + + virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) + { + if (changedField == &m_toggleField) + { + std::cout << "Toggle Field changed" << std::endl; + } + } + +}; + +CAF_PDM_SOURCE_INIT(DemoPdmObject, "DemoPdmObject"); + + + +MainWindow* MainWindow::sm_mainWindowInstance = NULL; + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +MainWindow::MainWindow() +{ + // Initialize command framework + + // Register default command features (add/delete item in list) + + caf::AppExecCommandManager::instance()->enableUndoStack(true); + + m_treeView = NULL; + m_treeModelPdm = NULL; + + createActions(); + createDockPanels(); + + buildTestModel(); + setPdmRoot(m_testRoot); + + sm_mainWindowInstance = this; + caf::SelectionManager::instance()->setPdmRootObject(m_testRoot); + + undoView->setStack(caf::AppExecCommandManager::instance()->undoStack()); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void MainWindow::createDockPanels() +{ + { + QDockWidget* dockWidget = new QDockWidget("Workspace", this); + dockWidget->setObjectName("dockWidget"); + dockWidget->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea); + + m_treeView = new QTreeView(dockWidget); + dockWidget->setWidget(m_treeView); + + addDockWidget(Qt::LeftDockWidgetArea, dockWidget); + } + { + QDockWidget* dockWidget = new QDockWidget("PdmTreeView", this); + dockWidget->setObjectName("dockWidget"); + dockWidget->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea); + + m_pdmUiTreeView = new caf::PdmUiTreeView(dockWidget); + dockWidget->setWidget(m_pdmUiTreeView); + + addDockWidget(Qt::LeftDockWidgetArea, dockWidget); + } + /* + { + QDockWidget* dockWidget = new QDockWidget("WidgetLayoutTest", this); + dockWidget->setObjectName("dockWidget"); + dockWidget->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea); + + WidgetLayoutTest* widgetLayoutTest = new WidgetLayoutTest(dockWidget); + dockWidget->setWidget(widgetLayoutTest); + + addDockWidget(Qt::LeftDockWidgetArea, dockWidget); + } + */ + + { + QDockWidget* dockWidget = new QDockWidget("cafPropertyView", this); + dockWidget->setObjectName("dockWidget"); + dockWidget->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea); + + m_pdmUiPropertyView = new caf::PdmUiPropertyView(dockWidget); + dockWidget->setWidget(m_pdmUiPropertyView); + + addDockWidget(Qt::LeftDockWidgetArea, dockWidget); + } + + { + QDockWidget* dockWidget = new QDockWidget("cafTableView", this); + dockWidget->setObjectName("dockWidget"); + dockWidget->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea); + + m_pdmUiTableView = new caf::PdmUiTableView(dockWidget); + m_pdmUiTableView->setSelectionRole(caf::SelectionManager::CURRENT); + m_pdmUiTableView->enableDefaultContextMenu(true); + + dockWidget->setWidget(m_pdmUiTableView); + + addDockWidget(Qt::LeftDockWidgetArea, dockWidget); + } + + { + QDockWidget* dockWidget = new QDockWidget("PdmTreeView2", this); + dockWidget->setObjectName("dockWidget"); + dockWidget->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea); + + m_pdmUiTreeView2 = new caf::PdmUiTreeView(dockWidget); + m_pdmUiTreeView2->enableDefaultContextMenu(true); + dockWidget->setWidget(m_pdmUiTreeView2); + + addDockWidget(Qt::LeftDockWidgetArea, dockWidget); + } + + { + QDockWidget* dockWidget = new QDockWidget("Undo stack", this); + dockWidget->setObjectName("dockWidget"); + dockWidget->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea); + + undoView = new QUndoView(this); + dockWidget->setWidget(undoView); + + addDockWidget(Qt::LeftDockWidgetArea, dockWidget); + } + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void MainWindow::buildTestModel() +{ + m_testRoot = new DemoPdmObjectGroup; + + DemoPdmObject* demoObject = new DemoPdmObject; + m_testRoot->addObject(demoObject); + + SmallDemoPdmObject* smallObj1 = new SmallDemoPdmObject; + m_testRoot->addObject(smallObj1); + + SmallDemoPdmObjectA* smallObj2 = new SmallDemoPdmObjectA; + m_testRoot->addObject(smallObj2); + + DemoPdmObject* demoObj2 = new DemoPdmObject; + + demoObject->m_textField = "Mitt Demo Obj"; + demoObject->m_objectList.push_back(demoObj2); + demoObject->m_objectList.push_back(new SmallDemoPdmObjectA()); + SmallDemoPdmObject* smallObj3 = new SmallDemoPdmObject(); + demoObject->m_objectList.push_back(smallObj3); + demoObject->m_objectList.push_back(new SmallDemoPdmObject()); + + demoObject->m_objectListOfSameType.push_back(new SmallDemoPdmObjectA()); + demoObject->m_objectListOfSameType.push_back(new SmallDemoPdmObjectA()); + demoObject->m_objectListOfSameType.push_back(new SmallDemoPdmObjectA()); + demoObject->m_objectListOfSameType.push_back(new SmallDemoPdmObjectA()); + + + demoObj2->m_objectList.push_back(new SmallDemoPdmObjectA()); + demoObj2->m_objectList.push_back(new SmallDemoPdmObjectA()); + demoObj2->m_objectList.push_back(new SmallDemoPdmObject()); + + delete smallObj3; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void MainWindow::setPdmRoot(caf::PdmObjectHandle* pdmRoot) +{ + caf::PdmUiTreeItem* treeItemRoot = caf::UiTreeItemBuilderPdm::buildViewItems(NULL, 0, pdmRoot); + + if (!m_treeModelPdm) + { + m_treeModelPdm = new caf::UiTreeModelPdm(this); + } + + m_treeModelPdm->setTreeItemRoot(treeItemRoot); + + assert(m_treeView); + m_treeView->setModel(m_treeModelPdm); + + if (treeItemRoot) + { + if (m_treeView->selectionModel()) + { + connect(m_treeView->selectionModel(), SIGNAL(selectionChanged( const QItemSelection & , const QItemSelection & )), SLOT(slotSelectionChanged( const QItemSelection & , const QItemSelection & ))); + } + } + + caf::PdmUiObjectHandle* uiObject = uiObj(pdmRoot); + if (uiObject) + { + m_pdmUiTreeView->setPdmItem(uiObject); + } + + connect(m_pdmUiTreeView, SIGNAL(selectionChanged()), SLOT(slotSimpleSelectionChanged())); + + // Set up test of using a field as a root item + // Hack, because we know that pdmRoot is a PdmObjectGroup ... + + std::vector fields; + pdmRoot->fields(fields); + if (fields.size()) + { + caf::PdmFieldHandle* field = fields[0]; + caf::PdmUiFieldHandle* uiFieldHandle = uiField(field); + if (uiFieldHandle) + { + m_pdmUiTreeView2->setPdmItem(uiFieldHandle); + uiFieldHandle->updateConnectedEditors(); + } + } + + if (uiObject) + { + m_pdmUiTreeView2->setPdmItem(uiObject); + } + + connect(m_pdmUiTreeView2, SIGNAL(selectionChanged()), SLOT(slotShowTableView())); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +MainWindow::~MainWindow() +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void MainWindow::releaseTestData() +{ + m_treeView->setModel(NULL); + if (m_treeModelPdm) + { + delete m_treeModelPdm; + } + + if (m_testRoot) + { + m_testRoot->deleteObjects(); + delete m_testRoot; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +MainWindow* MainWindow::instance() +{ + return sm_mainWindowInstance; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void MainWindow::createActions() +{ + // Create actions + QAction* editInsert = new QAction("&Insert", this); + QAction* editRemove = new QAction("&Remove", this); + QAction* editRemoveAll = new QAction("Remove all", this); + + connect(editInsert, SIGNAL(triggered()), SLOT(slotInsert())); + connect(editRemove, SIGNAL(triggered()), SLOT(slotRemove())); + connect(editRemoveAll, SIGNAL(triggered()), SLOT(slotRemoveAll())); + + + // Create menus + QMenu* editMenu = menuBar()->addMenu("&Edit"); + editMenu->addAction(editInsert); + editMenu->addAction(editRemove); + editMenu->addAction(editRemoveAll); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void MainWindow::slotInsert() +{ + std::vector selection; + m_pdmUiTreeView->selectedObjects(selection); + + for (size_t i = 0; i < selection.size(); ++i) + { + caf::PdmUiFieldHandle* uiFh = dynamic_cast(selection[i]); + caf::PdmChildArrayField< caf::PdmObjectHandle*> * field = NULL; + + if (uiFh) field = dynamic_cast *>(uiFh->fieldHandle()); + + if (field) + { + field->push_back(new DemoPdmObject); + field->capability()->updateConnectedEditors(); + + return; + } + #if 0 + caf::PdmChildArrayFieldHandle* listField = NULL; + + if (uiFh) listField = dynamic_cast(uiFh->fieldHandle()); + + if (listField) + { + caf::PdmObjectHandle* obj = listField->createAppendObject(); + listField->capability()->updateConnectedEditors(); + } + #endif + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void MainWindow::slotRemove() +{ + std::vector selection; + m_pdmUiTreeView->selectedObjects(selection); + + for (size_t i = 0; i < selection.size(); ++i) + { + caf::PdmObjectHandle* obj = dynamic_cast< caf::PdmObjectHandle*>(selection[i]); + if (obj) + { + caf::PdmFieldHandle* field = obj->parentField(); + + // Ordering is important + + field->removeChildObject(obj); + + // Delete object + delete obj; + + // Update editors + caf::PdmUiFieldHandle* uiFieldHandle = uiField(field); + if (uiFieldHandle) + { + uiFieldHandle->updateConnectedEditors(); + } + + break; + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void MainWindow::slotRemoveAll() +{ + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void MainWindow::slotSelectionChanged(const QItemSelection & selected, const QItemSelection & deselected ) +{ + if (selected.indexes().size() == 1) + { + QModelIndex mi = selected.indexes()[0]; + caf::PdmUiTreeItem* treeItem = m_treeModelPdm->getTreeItemFromIndex(mi); + if (treeItem && treeItem->dataObject()) + { + m_pdmUiPropertyView->showProperties(treeItem->dataObject()); + } + } + else + { + m_pdmUiPropertyView->showProperties(NULL); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void MainWindow::slotSimpleSelectionChanged() +{ + std::vector selection; + m_pdmUiTreeView->selectedObjects(selection); + caf::PdmObjectHandle* obj = NULL; + caf::PdmChildArrayFieldHandle* listField = NULL; + + if (selection.size()) + { + caf::PdmUiObjectHandle* pdmUiObj = dynamic_cast( selection[0] ); + if (pdmUiObj) obj = pdmUiObj->owner(); + } + + m_pdmUiPropertyView->showProperties(obj); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void MainWindow::slotShowTableView() +{ + std::vector selection; + m_pdmUiTreeView2->selectedObjects(selection); + caf::PdmObjectHandle* obj = NULL; + caf::PdmChildArrayFieldHandle* listField = NULL; + + if (selection.size()) + { + caf::PdmUiItem* pdmUiItem = selection[0]; + + caf::PdmUiFieldHandle* guiField = dynamic_cast(pdmUiItem); + + if (guiField) listField = dynamic_cast(guiField->fieldHandle()); + + if (listField) + { + if (!listField->hasSameFieldCountForAllObjects()) + { + listField = NULL; + } + } + } + + m_pdmUiTableView->setListField(listField); + if (listField) + { + listField->capability()->updateConnectedEditors(); + } +} diff --git a/Fwk/AppFwk/cafTests/cafTestCvfApplication/MainWindow.h b/Fwk/AppFwk/cafTests/cafTestCvfApplication/MainWindow.h new file mode 100644 index 0000000000..f1512ec64d --- /dev/null +++ b/Fwk/AppFwk/cafTests/cafTestCvfApplication/MainWindow.h @@ -0,0 +1,66 @@ +#pragma once + +#include +#include +#include + +class DemoPdmObject; +class QTreeView; +class QUndoView; + +namespace caf +{ + class PdmObjectGroup; + class PdmObjectHandle; + class UiTreeModelPdm; + class PdmUiPropertyView; + class PdmUiTreeView; + class PdmUiTableView; +} + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + MainWindow(); + ~MainWindow(); + + static MainWindow* instance(); + void setPdmRoot(caf::PdmObjectHandle* pdmRoot); + +private: + void createActions(); + void createMenus(); + void createToolBars(); + void createDockPanels(); + + + void buildTestModel(); + void releaseTestData(); + +private slots: + void slotInsert(); + void slotRemove(); + void slotRemoveAll(); + void slotSelectionChanged(const QItemSelection &, const QItemSelection & ); + void slotSimpleSelectionChanged(); + void slotShowTableView(); + + +private: + static MainWindow* sm_mainWindowInstance; + +private: + QTreeView* m_treeView; + QUndoView* undoView; + + caf::UiTreeModelPdm* m_treeModelPdm; + caf::PdmUiTreeView* m_pdmUiTreeView; + caf::PdmUiTreeView* m_pdmUiTreeView2; + caf::PdmUiPropertyView* m_pdmUiPropertyView; + caf::PdmUiTableView* m_pdmUiTableView; + caf::PdmObjectGroup* m_testRoot; + +}; + diff --git a/Fwk/AppFwk/cafTests/cafTestCvfApplication/TapCvfSpecialization.cpp b/Fwk/AppFwk/cafTests/cafTestCvfApplication/TapCvfSpecialization.cpp new file mode 100644 index 0000000000..b3fe87f5cf --- /dev/null +++ b/Fwk/AppFwk/cafTests/cafTestCvfApplication/TapCvfSpecialization.cpp @@ -0,0 +1,60 @@ +#include "TapCvfSpecialization.h" +/* + +#include "MainWindow.h" +#include "WidgetLayoutTest.h" + +#include +#include +#include +#include +#include + + +#include "cafAppEnum.h" +#include "cafAppExecCommandManager.h" +#include "cafCommandFeaturesCore.h" +#include "cafCommandFeatureManager.h" +#include "cafPdmDocument.h" +#include "cafPdmObject.h" +#include "cafPdmUiFilePathEditor.h" +#include "cafPdmUiListEditor.h" +#include "cafPdmUiPropertyView.h" +#include "cafPdmUiTableView.h" +#include "cafPdmUiTextEditor.h" +#include "cafPdmUiTreeView.h" +#include "cafPdmReferenceHelper.h" +#include "cafSelectionManager.h" +#include "cafUiTreeModelPdm.h" +#include "cafPdmProxyValueField.h" +#include "cafPdmPtrField.h" +*/ + +CAF_PDM_SOURCE_INIT(TapCvfSpecialization, "TapCvfSpecialization"); + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TapCvfSpecialization::TapCvfSpecialization() +{ + CAF_PDM_InitObject("Test Object for type specializations", "", "", ""); + + CAF_PDM_InitField(&m_vectorField, "m_vectorField", cvf::Vec3d::ZERO, "Start Point", "", "", ""); + CAF_PDM_InitField(&m_matrixField, "m_matrixField", cvf::Mat4d::ZERO, "Zero matrix", "", "", ""); + CAF_PDM_InitField(&m_colorField, "m_colorField", cvf::Color3f(cvf::Color3::GREEN), "Color3f", "", "", ""); + +/* + CAF_PDM_InitField(&m_toggleField, "Toggle", false, "Toggle Field", "", "Toggle Field tooltip", " Toggle Field whatsthis"); + CAF_PDM_InitField(&m_doubleField, "BigNumber", 0.0, "Big Number", "", "Enter a big number here", "This is a place you can enter a big real value if you want"); + CAF_PDM_InitField(&m_intField, "IntNumber", 0, "Small Number", "", "Enter some small number here", "This is a place you can enter a small integer value if you want"); + CAF_PDM_InitField(&m_textField, "TextField", QString(""), "Text", "", "Text tooltip", "This is a place you can enter a small integer value if you want"); + + m_proxyDoubleField.registerSetMethod(this, &SmallDemoPdmObject::setDoubleMember); + m_proxyDoubleField.registerGetMethod(this, &SmallDemoPdmObject::doubleMember); + CAF_PDM_InitFieldNoDefault(&m_proxyDoubleField, "ProxyDouble", "Proxy Double", "", "", ""); + + m_proxyDoubleField = 0; + if (!(m_proxyDoubleField == 3)) { std::cout << "Double is not 3 " << std::endl; } +*/ +} diff --git a/Fwk/AppFwk/cafTests/cafTestCvfApplication/TapCvfSpecialization.h b/Fwk/AppFwk/cafTests/cafTestCvfApplication/TapCvfSpecialization.h new file mode 100644 index 0000000000..7114b7c361 --- /dev/null +++ b/Fwk/AppFwk/cafTests/cafTestCvfApplication/TapCvfSpecialization.h @@ -0,0 +1,33 @@ +#pragma once + + +#include "cvfBase.h" +#include "cvfColor3.h" +#include "cvfVector3.h" +#include "cvfMatrix4.h" + +#include "cafPdmObject.h" +#include "cafPdmField.h" + +#include "cafPdmFieldCvfColor.h" +#include "cafPdmFieldCvfVec3d.h" +#include "cafPdmFieldCvfMat4d.h" + + + + +class TapCvfSpecialization : public caf::PdmObject +{ + CAF_PDM_HEADER_INIT; +public: + + TapCvfSpecialization(); + + caf::PdmField m_testField; + + caf::PdmField m_colorField; + caf::PdmField m_vectorField; + caf::PdmField m_matrixField; + +}; + diff --git a/Fwk/AppFwk/cafTests/cafTestCvfApplication/TapProject.cpp b/Fwk/AppFwk/cafTests/cafTestCvfApplication/TapProject.cpp new file mode 100644 index 0000000000..39df038a32 --- /dev/null +++ b/Fwk/AppFwk/cafTests/cafTestCvfApplication/TapProject.cpp @@ -0,0 +1,20 @@ +#include "TapProject.h" + +CAF_PDM_SOURCE_INIT(TapProject, "RPMProject"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TapProject::TapProject(void) +{ + CAF_PDM_InitFieldNoDefault(&m_objectList, "ObjectList", "Objects list Field", "", "List", "This is a list of PdmObjects"); + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TapProject::~TapProject(void) +{ + +} diff --git a/Fwk/AppFwk/cafTests/cafTestCvfApplication/TapProject.h b/Fwk/AppFwk/cafTests/cafTestCvfApplication/TapProject.h new file mode 100644 index 0000000000..4116f343ee --- /dev/null +++ b/Fwk/AppFwk/cafTests/cafTestCvfApplication/TapProject.h @@ -0,0 +1,17 @@ +#pragma once + +#include "cafPdmDocument.h" + + + +class TapProject : public caf::PdmDocument +{ + CAF_PDM_HEADER_INIT; + +public: + TapProject(void); + virtual ~TapProject(void); + + caf::PdmChildArrayField< caf::PdmObjectHandle* > m_objectList; + +}; \ No newline at end of file diff --git a/Fwk/AppFwk/cafTests/cafTestCvfApplication/WidgetLayoutTest.cpp b/Fwk/AppFwk/cafTests/cafTestCvfApplication/WidgetLayoutTest.cpp new file mode 100644 index 0000000000..ce5e33eca1 --- /dev/null +++ b/Fwk/AppFwk/cafTests/cafTestCvfApplication/WidgetLayoutTest.cpp @@ -0,0 +1,108 @@ + +#include "WidgetLayoutTest.h" + +#include +#include +#include +#include +#include + + + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +WidgetLayoutTest::WidgetLayoutTest(QWidget* parent /*= 0*/, Qt::WindowFlags f /*= 0*/) + : QWidget(parent, f) +{ + QVBoxLayout* l = new QVBoxLayout; + setLayout(l); + + { + QPushButton* b1 = new QPushButton("Original config", this); + connect(b1, SIGNAL(clicked()), SLOT(setUpInitialConfiguration())); + l->addWidget(b1); + } + + { + QPushButton* b1 = new QPushButton("Config A", this); + connect(b1, SIGNAL(clicked()), SLOT(setUpInitialConfigurationA())); + l->addWidget(b1); + } + + { + QPushButton* b1 = new QPushButton("Config B", this); + connect(b1, SIGNAL(clicked()), SLOT(setUpInitialConfigurationB())); + l->addWidget(b1); + } + + m_mainLayout = new QGridLayout(); + l->addLayout(m_mainLayout); + + // Create widgets + m_widget1 = new QLineEdit("1", this); + m_widget2 = new QLineEdit("2", this); + m_widget3 = new QLineEdit("3", this); + m_widget4 = new QLineEdit("4", this); + m_widget5 = new QLineEdit("5", this); + + m_groupBoxA = new QGroupBox("Groupbox A", this); + m_groupBoxALayout = new QGridLayout(); + m_groupBoxA->setLayout(m_groupBoxALayout); + + m_groupBoxB = new QGroupBox("Groupbox B", this); + m_groupBoxBLayout = new QGridLayout(); + m_groupBoxB->setLayout(m_groupBoxBLayout); + + setUpInitialConfiguration(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +WidgetLayoutTest::~WidgetLayoutTest() +{ + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void WidgetLayoutTest::setUpInitialConfiguration() +{ + m_mainLayout->addWidget(m_widget1); + + m_mainLayout->addWidget(m_groupBoxA); + + m_groupBoxALayout->addWidget(m_widget2, 0, 0); + if (!m_widget3) + { + m_widget3 = new QLabel("Test label", this); + } + m_groupBoxALayout->addWidget(m_widget3, 1, 0); + m_groupBoxALayout->addWidget(m_groupBoxB, 2, 0); + + m_groupBoxBLayout->addWidget(m_widget4); + + m_mainLayout->addWidget(m_widget5); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void WidgetLayoutTest::setUpInitialConfigurationA() +{ + m_mainLayout->addWidget(m_widget2); + + delete m_widget3; + m_widget3 = NULL; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void WidgetLayoutTest::setUpInitialConfigurationB() +{ + m_mainLayout->addWidget(m_widget4); +} diff --git a/Fwk/AppFwk/cafTests/cafTestCvfApplication/WidgetLayoutTest.h b/Fwk/AppFwk/cafTests/cafTestCvfApplication/WidgetLayoutTest.h new file mode 100644 index 0000000000..662765c544 --- /dev/null +++ b/Fwk/AppFwk/cafTests/cafTestCvfApplication/WidgetLayoutTest.h @@ -0,0 +1,41 @@ +#pragma once + +#include + + +class QGridLayout; +class QGroupBox; + + + +class WidgetLayoutTest : public QWidget +{ + Q_OBJECT + +public: + WidgetLayoutTest(QWidget* parent = 0, Qt::WindowFlags f = 0); + ~WidgetLayoutTest(); + +private: + QGridLayout* m_mainLayout; + + QGroupBox* m_groupBoxA; + QGridLayout* m_groupBoxALayout; + + QGroupBox* m_groupBoxB; + QGridLayout* m_groupBoxBLayout; + + QWidget* m_widget1; + QWidget* m_widget2; + QWidget* m_widget3; + QWidget* m_widget4; + QWidget* m_widget5; + +private slots: + void setUpInitialConfiguration(); + + void setUpInitialConfigurationA(); + void setUpInitialConfigurationB(); + +}; + diff --git a/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/logo32.png b/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/logo32.png new file mode 100644 index 0000000000..5f91e9873b Binary files /dev/null and b/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/logo32.png differ diff --git a/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/mac/editcopy.png b/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/mac/editcopy.png new file mode 100644 index 0000000000..f551364464 Binary files /dev/null and b/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/mac/editcopy.png differ diff --git a/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/mac/editcut.png b/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/mac/editcut.png new file mode 100644 index 0000000000..a784fd5709 Binary files /dev/null and b/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/mac/editcut.png differ diff --git a/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/mac/editpaste.png b/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/mac/editpaste.png new file mode 100644 index 0000000000..64c0b2d6ab Binary files /dev/null and b/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/mac/editpaste.png differ diff --git a/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/mac/editredo.png b/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/mac/editredo.png new file mode 100644 index 0000000000..8875bf246c Binary files /dev/null and b/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/mac/editredo.png differ diff --git a/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/mac/editundo.png b/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/mac/editundo.png new file mode 100644 index 0000000000..a3bd5e0bf2 Binary files /dev/null and b/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/mac/editundo.png differ diff --git a/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/mac/exportpdf.png b/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/mac/exportpdf.png new file mode 100644 index 0000000000..ebb44e6b88 Binary files /dev/null and b/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/mac/exportpdf.png differ diff --git a/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/mac/filenew.png b/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/mac/filenew.png new file mode 100644 index 0000000000..d3882c7b3f Binary files /dev/null and b/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/mac/filenew.png differ diff --git a/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/mac/fileopen.png b/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/mac/fileopen.png new file mode 100644 index 0000000000..fc06c5ec63 Binary files /dev/null and b/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/mac/fileopen.png differ diff --git a/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/mac/fileprint.png b/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/mac/fileprint.png new file mode 100644 index 0000000000..10ca56c82a Binary files /dev/null and b/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/mac/fileprint.png differ diff --git a/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/mac/filesave.png b/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/mac/filesave.png new file mode 100644 index 0000000000..b41ecf5319 Binary files /dev/null and b/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/mac/filesave.png differ diff --git a/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/mac/textbold.png b/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/mac/textbold.png new file mode 100644 index 0000000000..38400bd1f6 Binary files /dev/null and b/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/mac/textbold.png differ diff --git a/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/mac/textcenter.png b/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/mac/textcenter.png new file mode 100644 index 0000000000..2ef5b2ee6f Binary files /dev/null and b/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/mac/textcenter.png differ diff --git a/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/mac/textitalic.png b/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/mac/textitalic.png new file mode 100644 index 0000000000..0170ee26a6 Binary files /dev/null and b/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/mac/textitalic.png differ diff --git a/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/mac/textjustify.png b/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/mac/textjustify.png new file mode 100644 index 0000000000..39cd6c1a9d Binary files /dev/null and b/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/mac/textjustify.png differ diff --git a/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/mac/textleft.png b/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/mac/textleft.png new file mode 100644 index 0000000000..83a66d5535 Binary files /dev/null and b/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/mac/textleft.png differ diff --git a/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/mac/textright.png b/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/mac/textright.png new file mode 100644 index 0000000000..e7c04645cf Binary files /dev/null and b/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/mac/textright.png differ diff --git a/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/mac/textunder.png b/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/mac/textunder.png new file mode 100644 index 0000000000..968bac5e90 Binary files /dev/null and b/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/mac/textunder.png differ diff --git a/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/mac/zoomin.png b/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/mac/zoomin.png new file mode 100644 index 0000000000..d46f5aff0d Binary files /dev/null and b/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/mac/zoomin.png differ diff --git a/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/mac/zoomout.png b/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/mac/zoomout.png new file mode 100644 index 0000000000..46326566d1 Binary files /dev/null and b/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/mac/zoomout.png differ diff --git a/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/win/editcopy.png b/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/win/editcopy.png new file mode 100644 index 0000000000..1121b47d8b Binary files /dev/null and b/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/win/editcopy.png differ diff --git a/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/win/editcut.png b/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/win/editcut.png new file mode 100644 index 0000000000..38e55f7420 Binary files /dev/null and b/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/win/editcut.png differ diff --git a/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/win/editpaste.png b/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/win/editpaste.png new file mode 100644 index 0000000000..ffab15aaf8 Binary files /dev/null and b/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/win/editpaste.png differ diff --git a/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/win/editredo.png b/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/win/editredo.png new file mode 100644 index 0000000000..9d679fe6fc Binary files /dev/null and b/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/win/editredo.png differ diff --git a/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/win/editundo.png b/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/win/editundo.png new file mode 100644 index 0000000000..eee23d24a3 Binary files /dev/null and b/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/win/editundo.png differ diff --git a/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/win/exportpdf.png b/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/win/exportpdf.png new file mode 100644 index 0000000000..eef5132928 Binary files /dev/null and b/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/win/exportpdf.png differ diff --git a/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/win/filenew.png b/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/win/filenew.png new file mode 100644 index 0000000000..af5d122141 Binary files /dev/null and b/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/win/filenew.png differ diff --git a/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/win/fileopen.png b/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/win/fileopen.png new file mode 100644 index 0000000000..fc6f17e977 Binary files /dev/null and b/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/win/fileopen.png differ diff --git a/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/win/fileprint.png b/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/win/fileprint.png new file mode 100644 index 0000000000..ba7c02dc18 Binary files /dev/null and b/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/win/fileprint.png differ diff --git a/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/win/filesave.png b/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/win/filesave.png new file mode 100644 index 0000000000..8feec99bee Binary files /dev/null and b/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/win/filesave.png differ diff --git a/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/win/textbold.png b/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/win/textbold.png new file mode 100644 index 0000000000..9cbc7138b9 Binary files /dev/null and b/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/win/textbold.png differ diff --git a/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/win/textcenter.png b/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/win/textcenter.png new file mode 100644 index 0000000000..11efb4b852 Binary files /dev/null and b/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/win/textcenter.png differ diff --git a/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/win/textitalic.png b/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/win/textitalic.png new file mode 100644 index 0000000000..b30ce14c14 Binary files /dev/null and b/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/win/textitalic.png differ diff --git a/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/win/textjustify.png b/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/win/textjustify.png new file mode 100644 index 0000000000..9de0c88085 Binary files /dev/null and b/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/win/textjustify.png differ diff --git a/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/win/textleft.png b/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/win/textleft.png new file mode 100644 index 0000000000..16f80bc325 Binary files /dev/null and b/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/win/textleft.png differ diff --git a/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/win/textright.png b/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/win/textright.png new file mode 100644 index 0000000000..16872df62a Binary files /dev/null and b/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/win/textright.png differ diff --git a/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/win/textunder.png b/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/win/textunder.png new file mode 100644 index 0000000000..c72eff53fb Binary files /dev/null and b/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/win/textunder.png differ diff --git a/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/win/zoomin.png b/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/win/zoomin.png new file mode 100644 index 0000000000..2e586fc7bf Binary files /dev/null and b/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/win/zoomin.png differ diff --git a/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/win/zoomout.png b/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/win/zoomout.png new file mode 100644 index 0000000000..a736d39343 Binary files /dev/null and b/Fwk/AppFwk/cafTests/cafTestCvfApplication/images/win/zoomout.png differ diff --git a/Fwk/AppFwk/cafTests/cafTestCvfApplication/textedit.qrc b/Fwk/AppFwk/cafTests/cafTestCvfApplication/textedit.qrc new file mode 100644 index 0000000000..1df9e53b89 --- /dev/null +++ b/Fwk/AppFwk/cafTests/cafTestCvfApplication/textedit.qrc @@ -0,0 +1,43 @@ + + + images/logo32.png + images/mac/editcopy.png + images/mac/editcut.png + images/mac/editpaste.png + images/mac/editredo.png + images/mac/editundo.png + images/mac/exportpdf.png + images/mac/filenew.png + images/mac/fileopen.png + images/mac/fileprint.png + images/mac/filesave.png + images/mac/textbold.png + images/mac/textcenter.png + images/mac/textitalic.png + images/mac/textjustify.png + images/mac/textleft.png + images/mac/textright.png + images/mac/textunder.png + images/mac/zoomin.png + images/mac/zoomout.png + images/win/editcopy.png + images/win/editcut.png + images/win/editpaste.png + images/win/editredo.png + images/win/editundo.png + images/win/exportpdf.png + images/win/filenew.png + images/win/fileopen.png + images/win/fileprint.png + images/win/filesave.png + images/win/textbold.png + images/win/textcenter.png + images/win/textitalic.png + images/win/textjustify.png + images/win/textleft.png + images/win/textright.png + images/win/textunder.png + images/win/zoomin.png + images/win/zoomout.png + + diff --git a/Fwk/AppFwk/cafUserInterface/CMakeLists.txt b/Fwk/AppFwk/cafUserInterface/CMakeLists.txt index b210e4a322..be7ce26d54 100644 --- a/Fwk/AppFwk/cafUserInterface/CMakeLists.txt +++ b/Fwk/AppFwk/cafUserInterface/CMakeLists.txt @@ -1,35 +1,46 @@ cmake_minimum_required (VERSION 2.8) +# Qt +find_package ( Qt4 COMPONENTS QtCore QtGui QtMain ) +include (${QT_USE_FILE}) + project (cafUserInterface) include_directories( ${cafProjectDataModel_SOURCE_DIR} ) +include_directories ( + ${cafPdmCore_SOURCE_DIR} + ${cafPdmUiCore_SOURCE_DIR} + ${cafPdmXml_SOURCE_DIR} +) + # These headers need to go through Qt's MOC compiler set( QOBJECT_HEADERS - cafUiTreeModelPdm.h - cafUiProcess.h - - cafPdmSettings.h - cafPdmUiLineEditor.h + cafPdmUiCheckBoxDelegate.h cafPdmUiCheckBoxEditor.h + cafPdmUiColorEditor.h cafPdmUiComboBoxEditor.h - cafPdmUiPushButtonEditor.h + cafPdmUiDoubleSliderEditor.h cafPdmUiFilePathEditor.h + cafPdmUiLineEditor.h cafPdmUiListEditor.h + cafPdmUiListView.h + cafPdmUiListViewEditor.h + cafPdmUiPropertyView.h + cafPdmUiPushButtonEditor.h cafPdmUiSliderEditor.h - cafPdmUiDoubleSliderEditor.h + cafPdmUiTableView.h + cafPdmUiTableViewDelegate.h + cafPdmUiTableViewEditor.h + cafPdmUiTableViewModel.h cafPdmUiTextEditor.h - - cafPdmUiColorEditor.h - - cafPdmUiPropertyView.h - cafPdmUiPropertyDialog.h + cafPdmUiToolButtonEditor.h cafPdmUiTreeView.h cafPdmUiTreeViewModel.h - cafPdmUiListView.h - cafPdmUiListViewEditor.h + cafPdmUiTreeViewEditor.h + cafUiProcess.h ) if ( (${CMAKE_VERSION} VERSION_LESS 2.8.6) OR (NOT CMAKE_AUTOMOC) ) @@ -37,50 +48,90 @@ if ( (${CMAKE_VERSION} VERSION_LESS 2.8.6) OR (NOT CMAKE_AUTOMOC) ) endif() -add_library( ${PROJECT_NAME} - cafAboutDialog.cpp - cafAboutDialog.h - cafPdmSettings.cpp - cafPdmUiCheckBoxEditor.cpp - cafPdmUiCheckBoxEditor.h - cafPdmUiColorEditor.cpp - cafPdmUiColorEditor.h - cafPdmUiComboBoxEditor.cpp - cafPdmUiComboBoxEditor.h - cafPdmUiDefaultObjectEditor.cpp - cafPdmUiDefaultObjectEditor.h - cafPdmUiDoubleSliderEditor.cpp - cafPdmUiDoubleSliderEditor.h - cafPdmUiFilePathEditor.cpp - cafPdmUiFilePathEditor.h - cafPdmUiLineEditor.cpp - cafPdmUiLineEditor.h - cafPdmUiListEditor.cpp - cafPdmUiListEditor.h +set( PROJECT_FILES + + # field editors + cafPdmUiCheckBoxDelegate.cpp + cafPdmUiCheckBoxDelegate.h + cafPdmUiCheckBoxEditor.cpp + cafPdmUiCheckBoxEditor.h + cafPdmUiColorEditor.cpp + cafPdmUiColorEditor.h + cafPdmUiComboBoxEditor.cpp + cafPdmUiComboBoxEditor.h + cafPdmUiDoubleSliderEditor.cpp + cafPdmUiDoubleSliderEditor.h + cafPdmUiDragDropInterface.h + cafPdmUiFilePathEditor.cpp + cafPdmUiFilePathEditor.h + cafPdmUiLineEditor.cpp + cafPdmUiLineEditor.h + cafPdmUiListEditor.cpp + cafPdmUiListEditor.h + cafPdmUiPushButtonEditor.cpp + cafPdmUiPushButtonEditor.h + cafPdmUiSliderEditor.cpp + cafPdmUiSliderEditor.h + cafPdmUiTextEditor.cpp + cafPdmUiTextEditor.h + cafPdmUiToolBarEditor.cpp + cafPdmUiToolBarEditor.h + cafPdmUiToolButtonEditor.cpp + cafPdmUiToolButtonEditor.h + + # object editors + cafPdmUiDefaultObjectEditor.cpp + cafPdmUiDefaultObjectEditor.h + cafPdmUiListView.cpp + cafPdmUiListView.h cafPdmUiListViewEditor.cpp cafPdmUiListViewEditor.h - cafPdmUiListView.cpp - cafPdmUiPropertyDialog.cpp - cafPdmUiPropertyDialog.h - cafPdmUiPropertyView.cpp - cafPdmUiPropertyView.h - cafPdmUiPushButtonEditor.cpp - cafPdmUiPushButtonEditor.h - cafPdmUiSliderEditor.cpp - cafPdmUiSliderEditor.h - cafPdmUiTextEditor.cpp - cafPdmUiTextEditor.h + cafPdmUiTableItemEditor.cpp + cafPdmUiTableItemEditor.h + cafPdmUiTableView.cpp + cafPdmUiTableView.h + cafPdmUiTableViewDelegate.cpp + cafPdmUiTableViewDelegate.h + cafPdmUiTableViewEditor.cpp + cafPdmUiTableViewEditor.h + cafPdmUiTableViewModel.cpp + cafPdmUiTableViewModel.h + cafPdmUiTreeEditorHandle.cpp + cafPdmUiTreeEditorHandle.h + cafPdmUiTreeItemEditor.cpp + cafPdmUiTreeItemEditor.h + cafPdmUiTreeView.cpp + cafPdmUiTreeView.h cafPdmUiTreeViewEditor.cpp cafPdmUiTreeViewEditor.h cafPdmUiTreeViewModel.cpp cafPdmUiTreeViewModel.h - cafPdmUiTreeView.cpp - cafProgressInfo.cpp - cafProgressInfo.h - cafUiProcess.cpp - cafUiProcess.h - cafUiTreeModelPdm.cpp - cafUiTreeModelPdm.h + cafPdmUiPropertyView.cpp + cafPdmUiPropertyView.h + cafPdmUiPropertyViewDialog.cpp + cafPdmUiPropertyViewDialog.h + + # div + cafAboutDialog.cpp + cafAboutDialog.h + cafProgressInfo.cpp + cafProgressInfo.h + cafUiProcess.cpp + cafUiProcess.h +) + +add_library( ${PROJECT_NAME} + + ${PROJECT_FILES} ${MOC_FILES_CPP} ) + +target_link_libraries ( ${PROJECT_NAME} + cafProjectDataModel + cafPdmUiCore + cafPdmCore + ${QT_LIBRARIES} +) + +source_group("" FILES ${PROJECT_FILES}) diff --git a/Fwk/AppFwk/cafUserInterface/PdmUi.plantuml b/Fwk/AppFwk/cafUserInterface/PdmUi.plantuml new file mode 100644 index 0000000000..03f2bd124a --- /dev/null +++ b/Fwk/AppFwk/cafUserInterface/PdmUi.plantuml @@ -0,0 +1,49 @@ +@startuml + +Namespace TreeView{ + +QWidget <|-- PdmUiTreeView + +PdmUiTreeView --* PdmUiTreeViewEditor +PdmUiTreeView --* QTreeView + + +PdmUiTreeViewEditor "N" <--> "1" PdmUiItem<> +PdmUiTreeViewEditor "UpdateUi()" <--> "setValueFromUi()" PdmUiItem<> + +PdmUiTreeViewEditor "signals"<--> "confAndUpdate()" QTreeView +PdmUiTreeViewEditor ---* PdmUiTreeViewModel +'PdmUiTreeViewEditor --* "?, N" PdmUiTreeItemEditor + + +PdmUiTreeViewModel --> PdmUiTreeItemEditor : "SetValueFromUi()" +PdmUiTreeViewModel <-- PdmUiTreeItemEditor : "UpdatUi()" +PdmUiTreeViewModel --* PdmUiTreeOrdering +'PdmUiTreeViewModel ---* "?, N" PdmUiTreeItemEditor + +PdmUiTreeOrdering "N" <--> "1" PdmUiItem2<> +PdmUiTreeOrdering --* PdmUiTreeItemEditor + +PdmUiTreeItemEditor "N" <-- PdmUiItem2<> : UpdateUi(), removeFromList() +PdmUiTreeItemEditor --> "1" PdmUiItem2<> : setValueFromUi() + +} + +namespace Properties{ +QWidget <|-- PdmUiPropertyView + +PdmUiPropertyView --* PdmUiDefaultObjectEditor +PdmUiDefaultObjectEditor --* "N" PdmUiFieldEditor +"QWidget3<>" --* "QWidget2<>" + +PdmUiPropertyView --* "QWidget3<>" + +PdmField --> "N" PdmUiFieldEditor : UpdateUi(), removeFromList() +PdmUiFieldEditor --> "1" PdmField : setValueFromUi() +PdmUiFieldEditor --> "QWidget2<>" : configureAndUpdate() +PdmUiFieldEditor <-- "QWidget2<>" : signals() +PdmUiDefaultObjectEditor "N" <--> "1" PdmObject + +} + +@enduml \ No newline at end of file diff --git a/Fwk/AppFwk/cafUserInterface/cafAboutDialog.cpp b/Fwk/AppFwk/cafUserInterface/cafAboutDialog.cpp index 19bf80e9e9..5f66d2dd58 100644 --- a/Fwk/AppFwk/cafUserInterface/cafAboutDialog.cpp +++ b/Fwk/AppFwk/cafUserInterface/cafAboutDialog.cpp @@ -78,11 +78,11 @@ AboutDialog::AboutDialog(QWidget* parent) //-------------------------------------------------------------------------------------------------- /// Set application name to show in the dialog. Must be specified if any other app info is to be displayed //-------------------------------------------------------------------------------------------------- -void AboutDialog::setApplicationName(const QString& appName) +void AboutDialog::setApplicationName(const QString& appName) { assert(!m_isCreated); m_appName = appName; -} +} //-------------------------------------------------------------------------------------------------- @@ -92,7 +92,7 @@ void AboutDialog::setApplicationVersion(const QString& ver) { assert(!m_isCreated); m_appVersion = ver; -} +} //-------------------------------------------------------------------------------------------------- @@ -102,7 +102,7 @@ void AboutDialog::setCopyright(const QString& copyright) { assert(!m_isCreated); m_appCopyright = copyright; -} +} //-------------------------------------------------------------------------------------------------- @@ -112,7 +112,7 @@ void AboutDialog::showQtVersion(bool show) { assert(!m_isCreated); m_showQtVersion = show; -} +} //-------------------------------------------------------------------------------------------------- @@ -136,7 +136,7 @@ void AboutDialog::setIsDebugBuild(bool isDebugBuild) { assert(!m_isCreated); m_isDebugBuild = isDebugBuild; -} +} //-------------------------------------------------------------------------------------------------- @@ -194,7 +194,7 @@ void AboutDialog::create() if (!m_appVersion.isEmpty()) { QString appVer = m_appVersion; -// appVer += cvf::System::is64Bit() ? " (64-bit)" : " (32-bit)"; +// appVer += cvf::System::is64Bit() ? " (64-bit)" : " (32-bit)"; QLabel* appVersionLabel = new QLabel(this); QFont appVersionFont(appVersionLabel->font()); @@ -228,7 +228,7 @@ void AboutDialog::create() // Possibly show extend version info - if (m_showQtVersion || + if (m_showQtVersion || m_verLabels.size() > 0) { QGridLayout* verInfoLayout = new QGridLayout; diff --git a/Fwk/AppFwk/cafUserInterface/cafAboutDialog.h b/Fwk/AppFwk/cafUserInterface/cafAboutDialog.h index 11702c1c21..3fa4c8ad5e 100644 --- a/Fwk/AppFwk/cafUserInterface/cafAboutDialog.h +++ b/Fwk/AppFwk/cafUserInterface/cafAboutDialog.h @@ -54,33 +54,33 @@ class AboutDialog : public QDialog public: AboutDialog(QWidget* parent); - void setApplicationName(const QString& appName); - void setApplicationVersion(const QString& ver); - void setCopyright(const QString& copyright); + void setApplicationName(const QString& appName); + void setApplicationVersion(const QString& ver); + void setCopyright(const QString& copyright); - void showQtVersion(bool show); - void addVersionEntry(const QString& verLabel, const QString& verText); - void setIsDebugBuild(bool isDebugBuild); + void showQtVersion(bool show); + void addVersionEntry(const QString& verLabel, const QString& verText); + void setIsDebugBuild(bool isDebugBuild); - void create(); + void create(); static QString versionStringForcurrentOpenGLContext(); private: - void addStringPairToVerInfoLayout(const QString& labelStr, const QString& infoStr, QGridLayout* verInfoLayout, int insertRow); + void addStringPairToVerInfoLayout(const QString& labelStr, const QString& infoStr, QGridLayout* verInfoLayout, int insertRow); private: - bool m_isCreated; // Indicates if the create() function has been called + bool m_isCreated; // Indicates if the create() function has been called - QString m_appName; // Application name, appears in bold at the top of the dialog. - QString m_appVersion; // Application version info. Can be empty - QString m_appCopyright; // Application copyright string. Can be empty + QString m_appName; // Application name, appears in bold at the top of the dialog. + QString m_appVersion; // Application version info. Can be empty + QString m_appCopyright; // Application copyright string. Can be empty - bool m_showQtVersion; // Flags whether Qt version info should be shown - QStringList m_verLabels; // Labels for user specified version entries - QStringList m_verTexts; // The actual version text for user specified version entries + bool m_showQtVersion; // Flags whether Qt version info should be shown + QStringList m_verLabels; // Labels for user specified version entries + QStringList m_verTexts; // The actual version text for user specified version entries - bool m_isDebugBuild; // If set to true, will show info in dlg to indicate that this is a debug build + bool m_isDebugBuild; // If set to true, will show info in dlg to indicate that this is a debug build }; } diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmSettings.cpp b/Fwk/AppFwk/cafUserInterface/cafPdmSettings.cpp deleted file mode 100644 index a8e3a3ba5c..0000000000 --- a/Fwk/AppFwk/cafUserInterface/cafPdmSettings.cpp +++ /dev/null @@ -1,116 +0,0 @@ -//################################################################################################## -// -// Custom Visualization Core library -// Copyright (C) 2011-2013 Ceetron AS -// -// This library may be used under the terms of either the GNU General Public License or -// the GNU Lesser General Public License as follows: -// -// GNU General Public License Usage -// This library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. -// -// See the GNU General Public License at <> -// for more details. -// -// GNU Lesser General Public License Usage -// This library is free software; you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation; either version 2.1 of the License, or -// (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. -// -// See the GNU Lesser General Public License at <> -// for more details. -// -//################################################################################################## - - -#include "cafPdmSettings.h" -#include "cafPdmField.h" - -#include - - -namespace caf -{ - - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void Settings::readFieldsFromApplicationStore(caf::PdmObject* object) -{ - // Qt doc : - // - // Constructs a QSettings object for accessing settings of the application and organization - // set previously with a call to QCoreApplication::setOrganizationName(), - // QCoreApplication::setOrganizationDomain(), and QCoreApplication::setApplicationName(). - QSettings settings; - - QString prefix = object->classKeyword(); - if (!prefix.isEmpty()) - { - prefix += "/"; - } - - std::vector fields; - object->fields(fields); - size_t i; - for (i = 0; i < fields.size(); i++) - { - caf::PdmFieldHandle* fieldHandle = fields[i]; - - QString keywordWithPrefix = prefix + fieldHandle->keyword(); - if (settings.contains(keywordWithPrefix)) - { - QVariant val = settings.value(keywordWithPrefix); - fieldHandle->setValueFromUi(val); - } - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void Settings::writeFieldsToApplicationStore(caf::PdmObject* object) -{ - assert(object); - - // Qt doc : - // - // Constructs a QSettings object for accessing settings of the application and organization - // set previously with a call to QCoreApplication::setOrganizationName(), - // QCoreApplication::setOrganizationDomain(), and QCoreApplication::setApplicationName(). - QSettings settings; - - QString prefix = object->classKeyword(); - if (!prefix.isEmpty()) - { - prefix += "/"; - } - - std::vector fields; - object->fields(fields); - - size_t i; - for (i = 0; i < fields.size(); i++) - { - caf::PdmFieldHandle* fieldHandle = fields[i]; - - QString keywordWithPrefix = prefix + fieldHandle->keyword(); - settings.setValue(keywordWithPrefix, fieldHandle->uiValue()); - } -} - - -} // namespace caf diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiCheckBoxDelegate.cpp b/Fwk/AppFwk/cafUserInterface/cafPdmUiCheckBoxDelegate.cpp new file mode 100644 index 0000000000..89448602fa --- /dev/null +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiCheckBoxDelegate.cpp @@ -0,0 +1,128 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) Ceetron Solutions AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + +#include "cafPdmUiCheckBoxDelegate.h" + +#include +#include + + +namespace caf +{ + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +PdmUiCheckBoxDelegate::PdmUiCheckBoxDelegate(QObject* pParent) + : QStyledItemDelegate(pParent) +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +PdmUiCheckBoxDelegate::~PdmUiCheckBoxDelegate() +{ +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiCheckBoxDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + QStyleOptionViewItemV4 viewItemOption(option); + + const int textMargin = QApplication::style()->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1; + QRect newRect = QStyle::alignedRect(option.direction, Qt::AlignCenter, + QSize(option.decorationSize.width() + 5,option.decorationSize.height()), + QRect(option.rect.x() + textMargin, option.rect.y(), + option.rect.width() - (2 * textMargin), option.rect.height())); + viewItemOption.rect = newRect; + + QStyledItemDelegate::paint(painter, viewItemOption, index); +} + + +//-------------------------------------------------------------------------------------------------- +/// Returns true to avoid other factories to produce editors for a check box +//-------------------------------------------------------------------------------------------------- +bool PdmUiCheckBoxDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) +{ + Q_ASSERT(event); + Q_ASSERT(model); + + // make sure that the item is checkable + Qt::ItemFlags flags = model->flags(index); + if (!(flags & Qt::ItemIsUserCheckable) || !(flags & Qt::ItemIsEnabled)) + return false; + + // make sure that we have a check state + QVariant value = index.data(Qt::CheckStateRole); + if (!value.isValid()) + return false; + + // make sure that we have the right event type + if (event->type() == QEvent::MouseButtonRelease) + { + const int textMargin = QApplication::style()->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1; + QRect checkRect = QStyle::alignedRect(option.direction, Qt::AlignCenter, + option.decorationSize, + QRect(option.rect.x() + (2 * textMargin), option.rect.y(), + option.rect.width() - (2 * textMargin), + option.rect.height())); + + if (!checkRect.contains(static_cast(event)->pos())) + return true; + } + else if (event->type() == QEvent::KeyPress) + { + if (static_cast(event)->key() != Qt::Key_Space && static_cast(event)->key() != Qt::Key_Select) + return true; + } + else + { + return true; + } + + Qt::CheckState state = (static_cast(value.toInt()) == Qt::Checked ? Qt::Unchecked : Qt::Checked); + return model->setData(index, state, Qt::CheckStateRole); +} + + +} // end namespace caf + diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiCheckBoxDelegate.h b/Fwk/AppFwk/cafUserInterface/cafPdmUiCheckBoxDelegate.h new file mode 100644 index 0000000000..8908dc38a9 --- /dev/null +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiCheckBoxDelegate.h @@ -0,0 +1,63 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) Ceetron Solutions AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + +#pragma once + +#include + +namespace caf +{ + +//-------------------------------------------------------------------------------------------------- +/// Special handling of center aligned check boxes +/// +/// Based on http://qt-project.org/faq/answer/how_can_i_align_the_checkboxes_in_a_view +/// +//-------------------------------------------------------------------------------------------------- +class PdmUiCheckBoxDelegate : public QStyledItemDelegate +{ + Q_OBJECT + +public: + PdmUiCheckBoxDelegate( QObject* pParent = 0 ); + virtual ~PdmUiCheckBoxDelegate(); + + virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; + virtual bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index); +}; + + +} // end namespace caf diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiCheckBoxEditor.cpp b/Fwk/AppFwk/cafUserInterface/cafPdmUiCheckBoxEditor.cpp index 7a8ac5dc30..7c83fe3551 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiCheckBoxEditor.cpp +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiCheckBoxEditor.cpp @@ -64,7 +64,11 @@ void PdmUiCheckBoxEditor::configureAndUpdateUi(const QString& uiConfigName) assert(!m_label.isNull()); PdmUiCheckBoxEditorAttribute attributes; - field()->ownerObject()->editorAttribute(field(), uiConfigName, &attributes); + caf::PdmUiObjectHandle* uiObject = uiObj(field()->fieldHandle()->ownerObject()); + if (uiObject) + { + uiObject->editorAttribute(field()->fieldHandle(), uiConfigName, &attributes); + } if (attributes.m_useNativeCheckBoxLabel) { diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiColorEditor.cpp b/Fwk/AppFwk/cafUserInterface/cafPdmUiColorEditor.cpp index 18e8ad2ec8..630a8bdf5b 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiColorEditor.cpp +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiColorEditor.cpp @@ -89,7 +89,11 @@ void PdmUiColorEditor::configureAndUpdateUi(const QString& uiConfigName) m_label->setEnabled(!field()->isUiReadOnly(uiConfigName)); - field()->ownerObject()->editorAttribute(field(), uiConfigName, &m_attributes); + caf::PdmUiObjectHandle* uiObject = uiObj(field()->fieldHandle()->ownerObject()); + if (uiObject) + { + uiObject->editorAttribute(field()->fieldHandle(), uiConfigName, &m_attributes); + } QColor col = field()->uiValue().value(); setColor(col); diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiComboBoxEditor.cpp b/Fwk/AppFwk/cafUserInterface/cafPdmUiComboBoxEditor.cpp index 7931de06ce..a360b886a3 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiComboBoxEditor.cpp +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiComboBoxEditor.cpp @@ -59,41 +59,47 @@ CAF_PDM_UI_FIELD_EDITOR_SOURCE_INIT(PdmUiComboBoxEditor); //-------------------------------------------------------------------------------------------------- void PdmUiComboBoxEditor::configureAndUpdateUi(const QString& uiConfigName) { - assert(!m_comboBox.isNull()); - assert(!m_label.isNull()); - - QIcon ic = field()->uiIcon(uiConfigName); - if (!ic.isNull()) - { - m_label->setPixmap(ic.pixmap(ic.actualSize(QSize(64, 64)))); - } - else + if (!m_label.isNull()) { - m_label->setText(field()->uiName(uiConfigName)); + QIcon ic = field()->uiIcon(uiConfigName); + if (!ic.isNull()) + { + m_label->setPixmap(ic.pixmap(ic.actualSize(QSize(64, 64)))); + } + else + { + m_label->setText(field()->uiName(uiConfigName)); + } + m_label->setEnabled(!field()->isUiReadOnly(uiConfigName)); } - m_label->setEnabled(!field()->isUiReadOnly(uiConfigName)); - m_comboBox->setEnabled(!field()->isUiReadOnly(uiConfigName)); - - // Demo code for attribute retreival when becoming relevant - // PdmUiComboBoxEditorAttribute attributes; - // field()->ownerObject()->editorAttribute(field(), uiConfigName, &attributes); - - bool fromMenuOnly = false; - QList options = field()->valueOptions(&fromMenuOnly); - m_comboBox->blockSignals(true); - m_comboBox->clear(); - if (!options.isEmpty()) - { - m_comboBox->addItems(PdmOptionItemInfo::extractUiTexts(options)); - m_comboBox->setCurrentIndex(field()->uiValue().toInt()); - } - else + if (!m_comboBox.isNull()) { - m_comboBox->addItem(field()->uiValue().toString()); - m_comboBox->setCurrentIndex(0); + m_comboBox->setEnabled(!field()->isUiReadOnly(uiConfigName)); + + // Demo code for attribute retreival when becoming relevant + // PdmUiComboBoxEditorAttribute attributes; + // field()->ownerObject()->editorAttribute(field(), uiConfigName, &attributes); + + bool fromMenuOnly = false; + QList options = field()->valueOptions(&fromMenuOnly); + m_comboBox->blockSignals(true); + m_comboBox->clear(); + if (!options.isEmpty()) + { + for (int i = 0; i < options.size(); i++) + { + m_comboBox->addItem(options[i].icon, options[i].optionUiText); + } + m_comboBox->setCurrentIndex(field()->uiValue().toInt()); + } + else + { + m_comboBox->addItem(field()->uiValue().toString()); + m_comboBox->setCurrentIndex(0); + } + m_comboBox->blockSignals(false); } - m_comboBox->blockSignals(false); } @@ -103,7 +109,7 @@ void PdmUiComboBoxEditor::configureAndUpdateUi(const QString& uiConfigName) QWidget* PdmUiComboBoxEditor::createEditorWidget(QWidget * parent) { m_comboBox = new QComboBox(parent); - connect(m_comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(slotCurrentIndexChanged(int))); + connect(m_comboBox, SIGNAL(activated(int)), this, SLOT(slotIndexActivated(int))); return m_comboBox; } @@ -119,7 +125,7 @@ QWidget* PdmUiComboBoxEditor::createLabelWidget(QWidget * parent) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void PdmUiComboBoxEditor::slotCurrentIndexChanged(int index) +void PdmUiComboBoxEditor::slotIndexActivated(int index) { QVariant v; v = index; diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiComboBoxEditor.h b/Fwk/AppFwk/cafUserInterface/cafPdmUiComboBoxEditor.h index b9c0480cda..2645cc9aa7 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiComboBoxEditor.h +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiComboBoxEditor.h @@ -74,7 +74,7 @@ class PdmUiComboBoxEditor : public PdmUiFieldEditorHandle virtual void configureAndUpdateUi(const QString& uiConfigName); protected slots: - void slotCurrentIndexChanged(int index); + void slotIndexActivated(int index); private: QPointer m_comboBox; diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiDefaultObjectEditor.cpp b/Fwk/AppFwk/cafUserInterface/cafPdmUiDefaultObjectEditor.cpp index 5bfee7de4f..5982e940d6 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiDefaultObjectEditor.cpp +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiDefaultObjectEditor.cpp @@ -37,21 +37,20 @@ #include "cafPdmUiDefaultObjectEditor.h" -#include "cafPdmObject.h" -#include "cafPdmUiFieldEditorHandle.h" -#include "cafPdmUiOrdering.h" #include "cafPdmField.h" +#include "cafPdmObject.h" +#include "cafPdmProxyValueField.h" +#include "cafPdmUiCheckBoxEditor.h" #include "cafPdmUiComboBoxEditor.h" +#include "cafPdmUiFieldEditorHandle.h" #include "cafPdmUiLineEditor.h" -#include "cafPdmUiCheckBoxEditor.h" #include "cafPdmUiListEditor.h" +#include "cafPdmUiOrdering.h" - -#include #include +#include #include -#include @@ -66,15 +65,11 @@ CAF_PDM_UI_REGISTER_DEFAULT_FIELD_EDITOR(PdmUiLineEditor, int); CAF_PDM_UI_REGISTER_DEFAULT_FIELD_EDITOR(PdmUiLineEditor, double); CAF_PDM_UI_REGISTER_DEFAULT_FIELD_EDITOR(PdmUiLineEditor, float); CAF_PDM_UI_REGISTER_DEFAULT_FIELD_EDITOR(PdmUiLineEditor, quint64); - CAF_PDM_UI_REGISTER_DEFAULT_FIELD_EDITOR(PdmUiListEditor, std::vector); CAF_PDM_UI_REGISTER_DEFAULT_FIELD_EDITOR(PdmUiListEditor, std::vector); CAF_PDM_UI_REGISTER_DEFAULT_FIELD_EDITOR(PdmUiListEditor, std::vector); CAF_PDM_UI_REGISTER_DEFAULT_FIELD_EDITOR(PdmUiListEditor, std::vector); - - - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -88,7 +83,9 @@ PdmUiDefaultObjectEditor::PdmUiDefaultObjectEditor() //-------------------------------------------------------------------------------------------------- PdmUiDefaultObjectEditor::~PdmUiDefaultObjectEditor() { - + // If there are field editor present, the usage of this editor has not cleared correctly + // The intended usage is to call the method setPdmObject(NULL) before closing the dialog + assert(m_fieldViews.size() == 0); } //-------------------------------------------------------------------------------------------------- @@ -112,7 +109,11 @@ void PdmUiDefaultObjectEditor::configureAndUpdateUi(const QString& uiConfigName) PdmUiOrdering config; if (pdmObject()) { - pdmObject()->uiOrdering(uiConfigName, config); + caf::PdmUiObjectHandle* uiObject = uiObj(pdmObject()); + if (uiObject) + { + uiObject->uiOrdering(uiConfigName, config); + } } // Set all fieldViews to be unvisited @@ -215,12 +216,12 @@ void PdmUiDefaultObjectEditor::recursiveSetupFieldsAndGroups(const std::vector

(uiItems[i]); + PdmUiFieldHandle* field = dynamic_cast(uiItems[i]); PdmUiFieldEditorHandle* fieldEditor = NULL; // Find or create FieldEditor std::map::iterator it; - it = m_fieldViews.find(field->keyword()); + it = m_fieldViews.find(field->fieldHandle()->keyword()); if (it == m_fieldViews.end()) { @@ -233,7 +234,7 @@ void PdmUiDefaultObjectEditor::recursiveSetupFieldsAndGroups(const std::vector

fieldHandle())); // Handle a single value field with valueOptions: Make a combobox @@ -253,9 +254,22 @@ void PdmUiDefaultObjectEditor::recursiveSetupFieldsAndGroups(const std::vector

keyword()] = fieldEditor; + m_fieldViews[field->fieldHandle()->keyword()] = fieldEditor; fieldEditor->createWidgets(parent); } + else + { + // This assert happens if no editor is available for a given field + // If the macro for registering the editor is put as the single statement + // in a cpp file, a dummy static class must be used to make sure the compile unit + // is included + // + // See cafPdmUiCoreColor3f and cafPdmUiCoreVec3d + + // This assert will trigger for PdmChildArrayField and PdmChildField + // Consider to exclude assert or add editors for these types if the assert is reintroduced + //assert(false); + } } else { diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiDoubleSliderEditor.cpp b/Fwk/AppFwk/cafUserInterface/cafPdmUiDoubleSliderEditor.cpp index b875d5f266..fc73ec86dd 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiDoubleSliderEditor.cpp +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiDoubleSliderEditor.cpp @@ -110,7 +110,11 @@ void PdmUiDoubleSliderEditor::configureAndUpdateUi(const QString& uiConfigName) m_lineEdit->setEnabled(!field()->isUiReadOnly(uiConfigName)); m_slider->setEnabled(!field()->isUiReadOnly(uiConfigName)); - field()->ownerObject()->editorAttribute(field(), uiConfigName, &m_attributes); + caf::PdmUiObjectHandle* uiObject = uiObj(field()->fieldHandle()->ownerObject()); + if (uiObject) + { + uiObject->editorAttribute(field()->fieldHandle(), uiConfigName, &m_attributes); + } PdmDoubleValidator* pdmValidator = new PdmDoubleValidator(m_attributes.m_minimum, m_attributes.m_maximum, m_attributes.m_decimals, this); m_lineEdit->setValidator(pdmValidator); diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiDragDropInterface.h b/Fwk/AppFwk/cafUserInterface/cafPdmUiDragDropInterface.h new file mode 100644 index 0000000000..20aaa9ab59 --- /dev/null +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiDragDropInterface.h @@ -0,0 +1,74 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2015- Ceetron Solutions AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + + +#pragma once + +#include + +class QMimeData; + +namespace caf +{ + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +class PdmUiDragDropInterface +{ +public: + virtual ~PdmUiDragDropInterface() = 0; + +protected: + + friend class PdmUiTreeViewModel; + friend class PdmUiTreeViewWidget; + + // Forwarding from Qt functions in QAbstractItemModel + virtual Qt::DropActions supportedDropActions() const = 0; + virtual Qt::ItemFlags flags(const QModelIndex &index) const = 0; + virtual bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) = 0; + virtual QMimeData* mimeData(const QModelIndexList &indexes) const = 0; + virtual QStringList mimeTypes() const = 0; + + // Forwarding of tree view events + virtual void onDragCanceled() = 0; + virtual void onProposedDropActionUpdated(Qt::DropAction action) = 0; +}; + +inline PdmUiDragDropInterface::~PdmUiDragDropInterface() { } + +} // end namespace caf diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiFilePathEditor.cpp b/Fwk/AppFwk/cafUserInterface/cafPdmUiFilePathEditor.cpp index 1b3f92c7b7..0b16102795 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiFilePathEditor.cpp +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiFilePathEditor.cpp @@ -86,7 +86,11 @@ void PdmUiFilePathEditor::configureAndUpdateUi(const QString& uiConfigName) m_lineEdit->setEnabled(!field()->isUiReadOnly(uiConfigName)); m_lineEdit->setToolTip(field()->uiToolTip(uiConfigName)); - field()->ownerObject()->editorAttribute(field(), uiConfigName, &m_attributes); + caf::PdmUiObjectHandle* uiObject = uiObj(field()->fieldHandle()->ownerObject()); + if (uiObject) + { + uiObject->editorAttribute(field()->fieldHandle(), uiConfigName, &m_attributes); + } m_lineEdit->setText(field()->uiValue().toString()); diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiLineEditor.cpp b/Fwk/AppFwk/cafUserInterface/cafPdmUiLineEditor.cpp index fbcc9c26da..e46d513fcf 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiLineEditor.cpp +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiLineEditor.cpp @@ -37,20 +37,115 @@ #include "cafPdmUiLineEditor.h" -#include "cafPdmUiDefaultObjectEditor.h" - +#include "cafFactory.h" +#include "cafPdmField.h" #include "cafPdmObject.h" +#include "cafPdmUiDefaultObjectEditor.h" #include "cafPdmUiFieldEditorHandle.h" #include "cafPdmUiOrdering.h" +#include "cafSelectionManager.h" -#include "cafPdmField.h" - -#include -#include #include +#include +#include +#include +#include +#include +#include +#include #include -#include "cafFactory.h" + + + +class PdmUniqueIdValidator : public QValidator +{ +public: + PdmUniqueIdValidator(const std::set& usedIds, bool multipleSelectionOfSameFieldsSelected, const QString& errorMessage, QObject* parent) + : QValidator(parent) + { + m_usedIds = usedIds; + m_nextValidValue = 0; + m_multipleSelectionOfSameFieldsSelected = multipleSelectionOfSameFieldsSelected; + m_errorMessage = errorMessage; + + computeNextValidId(); + } + + virtual State validate(QString& currentString, int &) const + { + if (m_multipleSelectionOfSameFieldsSelected) + { + return QValidator::Invalid; + } + + if (currentString.isEmpty()) + { + return QValidator::Intermediate; + } + + bool isValidInteger = false; + int currentValue = currentString.toInt(&isValidInteger); + + if (!isValidInteger) + { + return QValidator::Invalid; + } + + if (currentValue < 0) + { + return QValidator::Invalid; + } + + if (m_usedIds.find(currentValue) != m_usedIds.end()) + { + QApplication* qapplication = qobject_cast(qApp); + + foreach(QWidget* widget, qapplication->topLevelWidgets()) + { + if (widget->inherits("QMainWindow")) + { + QMainWindow* mainWindow = qobject_cast(widget); + if (mainWindow && mainWindow->statusBar()) + { + mainWindow->statusBar()->showMessage(m_errorMessage, 3000); + } + } + } + + return QValidator::Intermediate; + } + + return QValidator::Acceptable; + } + + virtual void fixup(QString& editorText) const + { + editorText = QString::number(m_nextValidValue); + } + +private: + int computeNextValidId() + { + if (!m_usedIds.empty()) + { + m_nextValidValue = *m_usedIds.rbegin(); + } + else + { + m_nextValidValue = 1; + } + + return m_nextValidValue; + } + +private: + std::set m_usedIds; + + int m_nextValidValue; + bool m_multipleSelectionOfSameFieldsSelected; + QString m_errorMessage; +}; @@ -65,43 +160,89 @@ CAF_PDM_UI_FIELD_EDITOR_SOURCE_INIT(PdmUiLineEditor); //-------------------------------------------------------------------------------------------------- void PdmUiLineEditor::configureAndUpdateUi(const QString& uiConfigName) { - assert(!m_lineEdit.isNull()); - assert(!m_label.isNull()); - - QIcon ic = field()->uiIcon(uiConfigName); - if (!ic.isNull()) + if (!m_label.isNull()) { - m_label->setPixmap(ic.pixmap(ic.actualSize(QSize(64, 64)))); + QIcon ic = field()->uiIcon(uiConfigName); + if (!ic.isNull()) + { + m_label->setPixmap(ic.pixmap(ic.actualSize(QSize(64, 64)))); + } + else + { + m_label->setText(field()->uiName(uiConfigName)); + } + + m_label->setEnabled(!field()->isUiReadOnly(uiConfigName)); + m_label->setToolTip(field()->uiToolTip(uiConfigName)); } - else + + + if (!m_lineEdit.isNull()) { - m_label->setText(field()->uiName(uiConfigName)); - } + m_lineEdit->setEnabled(!field()->isUiReadOnly(uiConfigName)); + m_lineEdit->setToolTip(field()->uiToolTip(uiConfigName)); - m_label->setEnabled(!field()->isUiReadOnly(uiConfigName)); - m_label->setToolTip(field()->uiToolTip(uiConfigName)); + { + PdmUiLineEditorAttribute leab; + caf::PdmUiObjectHandle* uiObject = uiObj(field()->fieldHandle()->ownerObject()); + if (uiObject) + { + uiObject->editorAttribute(field()->fieldHandle(), uiConfigName, &leab); + } - m_lineEdit->setEnabled(!field()->isUiReadOnly(uiConfigName)); - m_lineEdit->setToolTip(field()->uiToolTip(uiConfigName)); + if (leab.useRangeValidator) + { + m_lineEdit->setValidator(new QIntValidator(leab.minValue, leab.maxValue, this)); + } + } - PdmUiLineEditorAttribute leab; - field()->ownerObject()->editorAttribute(field(), uiConfigName, &leab); - if (leab.useRangeValidator) - { - m_lineEdit->setValidator(new QIntValidator(leab.minValue, leab.maxValue, this)); - } + { + PdmUiLineEditorAttributeUniqueValues leab; + caf::PdmUiObjectHandle* uiObject = uiObj(field()->fieldHandle()->ownerObject()); + if (uiObject) + { + uiObject->editorAttribute(field()->fieldHandle(), uiConfigName, &leab); + } + if (leab.usedIds.size() > 0) + { + if (isMultipleFieldsWithSameKeywordSelected(field()->fieldHandle())) + { + QMessageBox::information(NULL, "Invalid operation", "The field you are manipulating is defined to have unique values. A selection of multiple fields is detected. Please select a single item."); + } - bool fromMenuOnly = false; - QList enumNames = field()->valueOptions(&fromMenuOnly); - if (!enumNames.isEmpty() && fromMenuOnly == true) - { - QStringList uiTexts = PdmOptionItemInfo::extractUiTexts(enumNames); - int enumValue = field()->uiValue().toInt(); - m_lineEdit->setText(uiTexts.at(enumValue)); - } - else - { - m_lineEdit->setText(field()->uiValue().toString()); + m_lineEdit->setValidator(new PdmUniqueIdValidator(leab.usedIds, isMultipleFieldsWithSameKeywordSelected(field()->fieldHandle()), leab.errorMessage, this)); + } + } + + + bool fromMenuOnly = false; + QList enumNames = field()->valueOptions(&fromMenuOnly); + if (!enumNames.isEmpty() && fromMenuOnly == true) + { + int enumValue = field()->uiValue().toInt(); + m_lineEdit->setText(enumNames[enumValue].optionUiText); + } + else + { + PdmUiLineEditorAttributeUiDisplayString leab; + caf::PdmUiObjectHandle* uiObject = uiObj(field()->fieldHandle()->ownerObject()); + if (uiObject) + { + uiObject->editorAttribute(field()->fieldHandle(), uiConfigName, &leab); + } + + QString displayString; + if (leab.m_displayString.isEmpty()) + { + displayString = field()->uiValue().toString(); + } + else + { + displayString = leab.m_displayString; + } + + m_lineEdit->setText(displayString); + } } } @@ -136,5 +277,37 @@ void PdmUiLineEditor::slotEditingFinished() this->setValueToField(v); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool PdmUiLineEditor::isMultipleFieldsWithSameKeywordSelected(PdmFieldHandle* editorField) const +{ + std::vector fieldsToUpdate; + fieldsToUpdate.push_back(editorField); + + // For current selection, find all fields with same keyword + std::vector items; + SelectionManager::instance()->selectedItems(items, SelectionManager::CURRENT); + + for (size_t i = 0; i < items.size(); i++) + { + PdmUiFieldHandle* uiField = dynamic_cast(items[i]); + if (!uiField) continue; + + PdmFieldHandle* field = uiField->fieldHandle(); + if (field && field != editorField && field->keyword() == editorField->keyword()) + { + fieldsToUpdate.push_back(field); + } + } + + if (fieldsToUpdate.size() > 1) + { + return true; + } + + return false; +} + } // end namespace caf diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiLineEditor.h b/Fwk/AppFwk/cafUserInterface/cafPdmUiLineEditor.h index c444a5c1de..25a8782f98 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiLineEditor.h +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiLineEditor.h @@ -36,22 +36,23 @@ #pragma once + #include "cafPdmUiFieldEditorHandle.h" + +#include +#include +#include #include #include -#include -#include -#include class QGridLayout; namespace caf { -//================================================================================================== -/// The default editor for several PdmFields. -//================================================================================================== - +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- class PdmUiLineEditorAttribute : public PdmUiEditorAttribute { public: @@ -69,6 +70,37 @@ class PdmUiLineEditorAttribute : public PdmUiEditorAttribute }; +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +class PdmUiLineEditorAttributeUniqueValues : public PdmUiEditorAttribute +{ +public: + PdmUiLineEditorAttributeUniqueValues() + {} + +public: + std::set usedIds; + QString errorMessage; +}; + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +class PdmUiLineEditorAttributeUiDisplayString : public PdmUiEditorAttribute +{ +public: + PdmUiLineEditorAttributeUiDisplayString() + {} + +public: + QString m_displayString; +}; + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- class PdmUiLineEditor : public PdmUiFieldEditorHandle { Q_OBJECT @@ -86,6 +118,9 @@ class PdmUiLineEditor : public PdmUiFieldEditorHandle protected slots: void slotEditingFinished(); +private: + bool isMultipleFieldsWithSameKeywordSelected(PdmFieldHandle* editorField) const; + private: QPointer m_lineEdit; QPointer m_label; diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiListEditor.cpp b/Fwk/AppFwk/cafUserInterface/cafPdmUiListEditor.cpp index 059d7e4c52..e89f1fa61e 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiListEditor.cpp +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiListEditor.cpp @@ -114,6 +114,10 @@ PdmUiListEditor::~PdmUiListEditor() //-------------------------------------------------------------------------------------------------- void PdmUiListEditor::configureAndUpdateUi(const QString& uiConfigName) { + // TODO: Fix assert here when undoing in testapp + // See PdmUiComboBoxEditor for pattern + // This might also apply to other editors + assert(!m_listView.isNull()); assert(!m_label.isNull()); assert(m_listView->selectionModel()); @@ -149,7 +153,7 @@ void PdmUiListEditor::configureAndUpdateUi(const QString& uiConfigName) assert(m_optionsOnly); // Handling Additions on the fly not implemented strListModel->setItemsEditable(false); - QModelIndex currentItem = m_listView->selectionModel()->currentIndex(); + QModelIndex currentItem = m_listView->selectionModel()->currentIndex(); QStringList texts = PdmOptionItemInfo::extractUiTexts(m_options); strListModel->setStringList(texts); @@ -200,7 +204,7 @@ void PdmUiListEditor::configureAndUpdateUi(const QString& uiConfigName) m_listView->selectionModel()->blockSignals(true); QItemSelection selection = m_listView->selectionModel()->selection(); - QModelIndex currentItem = m_listView->selectionModel()->currentIndex(); + QModelIndex currentItem = m_listView->selectionModel()->currentIndex(); QVariant fieldValue = field()->uiValue(); QStringList texts = fieldValue.toStringList(); texts.push_back(""); diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiListView.cpp b/Fwk/AppFwk/cafUserInterface/cafPdmUiListView.cpp index f9bd1d805c..e496a088f3 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiListView.cpp +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiListView.cpp @@ -37,7 +37,8 @@ #include "cafPdmUiListView.h" -#include "cafPdmObject.h" +#include "cafPdmObjectGroup.h" +#include "cafPdmObjectHandle.h" #include "cafPdmUiListViewEditor.h" #include @@ -79,7 +80,7 @@ PdmUiListView::~PdmUiListView() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void PdmUiListView::setPdmObject(caf::PdmObject* object) +void PdmUiListView::setPdmObject(caf::PdmObjectCollection* object) { assert(m_listViewEditor); diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiListView.h b/Fwk/AppFwk/cafUserInterface/cafPdmUiListView.h index a075039d16..f2a4f12e69 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiListView.h +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiListView.h @@ -44,7 +44,7 @@ class QVBoxLayout; namespace caf { -class PdmObject; +class PdmObjectCollection; class PdmUiListViewEditor; //================================================================================================== @@ -57,7 +57,7 @@ class PdmUiListView : public QWidget PdmUiListView(QWidget* parent = 0, Qt::WindowFlags f = 0); ~PdmUiListView(); - void setPdmObject(caf::PdmObject* object); + void setPdmObject(caf::PdmObjectCollection* object); private: PdmUiListViewEditor* m_listViewEditor; diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiListViewEditor.cpp b/Fwk/AppFwk/cafUserInterface/cafPdmUiListViewEditor.cpp index a03375dee9..958d994b2d 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiListViewEditor.cpp +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiListViewEditor.cpp @@ -37,15 +37,14 @@ #include "cafPdmUiListViewEditor.h" -#include "cafPdmObject.h" #include "cafPdmField.h" +#include "cafPdmObject.h" +#include "cafPdmObjectGroup.h" #include "cafPdmUiEditorHandle.h" -#include "cafUiTreeModelPdm.h" -#include "cafPdmDocument.h" -#include #include #include +#include @@ -55,7 +54,7 @@ namespace caf //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -UiTableModelPdm::UiTableModelPdm(QObject* parent) +UiListViewModelPdm::UiListViewModelPdm(QObject* parent) : QAbstractTableModel(parent) { m_columnCount = 0; @@ -65,7 +64,7 @@ UiTableModelPdm::UiTableModelPdm(QObject* parent) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -int UiTableModelPdm::rowCount(const QModelIndex &parent /*= QModelIndex( ) */) const +int UiListViewModelPdm::rowCount(const QModelIndex &parent /*= QModelIndex( ) */) const { if (!m_pdmObjectGroup) { @@ -78,7 +77,7 @@ int UiTableModelPdm::rowCount(const QModelIndex &parent /*= QModelIndex( ) */) c //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -int UiTableModelPdm::columnCount(const QModelIndex &parent /*= QModelIndex( ) */) const +int UiListViewModelPdm::columnCount(const QModelIndex &parent /*= QModelIndex( ) */) const { if (!m_pdmObjectGroup) { @@ -96,7 +95,7 @@ int UiTableModelPdm::columnCount(const QModelIndex &parent /*= QModelIndex( ) */ //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void UiTableModelPdm::computeColumnCount() +void UiListViewModelPdm::computeColumnCount() { if (m_editorAttribute.fieldNames.size() > 0) { @@ -123,7 +122,7 @@ void UiTableModelPdm::computeColumnCount() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QVariant UiTableModelPdm::headerData(int section, Qt::Orientation orientation, int role /*= Qt::DisplayRole */) const +QVariant UiListViewModelPdm::headerData(int section, Qt::Orientation orientation, int role /*= Qt::DisplayRole */) const { return QVariant(QString("Header %1").arg(section)); } @@ -131,13 +130,13 @@ QVariant UiTableModelPdm::headerData(int section, Qt::Orientation orientation, i //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QVariant caf::UiTableModelPdm::data(const QModelIndex &index, int role /*= Qt::DisplayRole */) const +QVariant caf::UiListViewModelPdm::data(const QModelIndex &index, int role /*= Qt::DisplayRole */) const { if (m_pdmObjectGroup && (role == Qt::DisplayRole || role == Qt::EditRole)) { if (index.row() < static_cast(m_pdmObjectGroup->objects.size())) { - PdmObject* pdmObject = m_pdmObjectGroup->objects[index.row()]; + PdmObjectHandle* pdmObject = m_pdmObjectGroup->objects[index.row()]; if (pdmObject) { std::vector fields; @@ -164,7 +163,15 @@ QVariant caf::UiTableModelPdm::data(const QModelIndex &index, int role /*= Qt::D fieldIndex = index.column(); } - return fields[fieldIndex]->uiValue(); + PdmUiFieldHandle* uiFieldHandle = fields[fieldIndex]->uiCapability(); + if (uiFieldHandle) + { + return uiFieldHandle->uiValue(); + } + else + { + return QVariant(); + } } } } @@ -177,14 +184,18 @@ QVariant caf::UiTableModelPdm::data(const QModelIndex &index, int role /*= Qt::D //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void caf::UiTableModelPdm::setPdmData(PdmObjectGroup* objectGroup, const QString& configName) +void caf::UiListViewModelPdm::setPdmData(PdmObjectCollection* objectGroup, const QString& configName) { m_pdmObjectGroup = objectGroup; m_configName = configName; if (m_pdmObjectGroup) { - m_pdmObjectGroup->objectEditorAttribute(m_configName, &m_editorAttribute); + caf::PdmUiObjectHandle* uiObject = uiObj(m_pdmObjectGroup); + if (uiObject) + { + uiObject->objectEditorAttribute(m_configName, &m_editorAttribute); + } } computeColumnCount(); @@ -217,7 +228,7 @@ QWidget* PdmUiListViewEditor::createWidget(QWidget* parent) m_layout = new QVBoxLayout(); m_mainWidget->setLayout(m_layout); - m_tableModelPdm = new UiTableModelPdm(m_mainWidget); + m_tableModelPdm = new UiListViewModelPdm(m_mainWidget); m_tableView = new QTableView(m_mainWidget); m_tableView->setShowGrid(false); @@ -233,7 +244,7 @@ QWidget* PdmUiListViewEditor::createWidget(QWidget* parent) //-------------------------------------------------------------------------------------------------- void PdmUiListViewEditor::configureAndUpdateUi(const QString& uiConfigName) { - PdmObjectGroup* objectGroup = dynamic_cast(pdmObject()); + PdmObjectCollection* objectGroup = dynamic_cast(pdmObject()); m_tableModelPdm->setPdmData(objectGroup, uiConfigName); m_tableView->resizeColumnsToContents(); diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiListViewEditor.h b/Fwk/AppFwk/cafUserInterface/cafPdmUiListViewEditor.h index c46119994a..ce2c9c55e4 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiListViewEditor.h +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiListViewEditor.h @@ -50,7 +50,7 @@ namespace caf { class PdmUiFieldEditorHandle; class PdmUiItem; -class PdmObjectGroup; +class PdmObjectCollection; @@ -73,14 +73,14 @@ class PdmUiListViewEditorAttribute : public PdmUiEditorAttribute //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -class UiTableModelPdm : public QAbstractTableModel +class UiListViewModelPdm : public QAbstractTableModel { Q_OBJECT public: - UiTableModelPdm(QObject* parent); + UiListViewModelPdm(QObject* parent); - void setPdmData(PdmObjectGroup* objectGroup, const QString& configName); + void setPdmData(PdmObjectCollection* objectGroup, const QString& configName); // Qt overrides virtual int rowCount( const QModelIndex &parent = QModelIndex( ) ) const; @@ -92,7 +92,7 @@ class UiTableModelPdm : public QAbstractTableModel void computeColumnCount(); private: - PdmObjectGroup* m_pdmObjectGroup; + PdmObjectCollection* m_pdmObjectGroup; QString m_configName; PdmUiListViewEditorAttribute m_editorAttribute; int m_columnCount; @@ -118,7 +118,7 @@ class PdmUiListViewEditor : public PdmUiObjectEditorHandle QLayout* m_layout; QTableView* m_tableView; - UiTableModelPdm* m_tableModelPdm; + UiListViewModelPdm* m_tableModelPdm; }; diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiPropertyDialog.cpp b/Fwk/AppFwk/cafUserInterface/cafPdmUiPropertyDialog.cpp deleted file mode 100644 index 277dc3153d..0000000000 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiPropertyDialog.cpp +++ /dev/null @@ -1,92 +0,0 @@ -//################################################################################################## -// -// Custom Visualization Core library -// Copyright (C) 2011-2013 Ceetron AS -// -// This library may be used under the terms of either the GNU General Public License or -// the GNU Lesser General Public License as follows: -// -// GNU General Public License Usage -// This library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. -// -// See the GNU General Public License at <> -// for more details. -// -// GNU Lesser General Public License Usage -// This library is free software; you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation; either version 2.1 of the License, or -// (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. -// -// See the GNU Lesser General Public License at <> -// for more details. -// -//################################################################################################## - - -#include "cafPdmUiPropertyDialog.h" - -#include "cafPdmObject.h" -#include "cafPdmUiPropertyView.h" - -#include -#include - -#include - - - -namespace caf { - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -PdmUiPropertyDialog::PdmUiPropertyDialog(QWidget* parent, caf::PdmObject* object, const QString& windowTitle) - : QDialog(parent) -{ - assert(object); - - m_pdmObject = object; - m_windowTitle = windowTitle; - - setupUi(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void PdmUiPropertyDialog::setupUi() -{ - setWindowTitle(m_windowTitle); - - m_pdmUiPropertyView = new caf::PdmUiPropertyView(this); - - QVBoxLayout* dialogLayout = new QVBoxLayout; - setLayout(dialogLayout); - - dialogLayout->addWidget(m_pdmUiPropertyView); - m_pdmUiPropertyView->showProperties(m_pdmObject); - - // Buttons - QDialogButtonBox* buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); - connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept())); - connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); - - dialogLayout->addWidget(buttonBox); - - this->resize(400, 200); -} - - -} // end namespace caf diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiPropertyDialog.h b/Fwk/AppFwk/cafUserInterface/cafPdmUiPropertyDialog.h deleted file mode 100644 index 4c4ca7b797..0000000000 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiPropertyDialog.h +++ /dev/null @@ -1,70 +0,0 @@ -//################################################################################################## -// -// Custom Visualization Core library -// Copyright (C) 2011-2013 Ceetron AS -// -// This library may be used under the terms of either the GNU General Public License or -// the GNU Lesser General Public License as follows: -// -// GNU General Public License Usage -// This library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. -// -// See the GNU General Public License at <> -// for more details. -// -// GNU Lesser General Public License Usage -// This library is free software; you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation; either version 2.1 of the License, or -// (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. -// -// See the GNU Lesser General Public License at <> -// for more details. -// -//################################################################################################## - - -#pragma once - -#include - -namespace caf -{ - class PdmObject; - class PdmUiPropertyView; - - -//================================================================================================== -// -// -// -//================================================================================================== -class PdmUiPropertyDialog : public QDialog -{ - Q_OBJECT - -public: - PdmUiPropertyDialog(QWidget* parent, caf::PdmObject* object, const QString& windowTitle); - -private: - void setupUi(); - -private: - QString m_windowTitle; - caf::PdmObject* m_pdmObject; - caf::PdmUiPropertyView* m_pdmUiPropertyView; -}; - - -} // end namespace caf diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiPropertyView.cpp b/Fwk/AppFwk/cafUserInterface/cafPdmUiPropertyView.cpp index 5dd66dafb2..56791fd923 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiPropertyView.cpp +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiPropertyView.cpp @@ -83,7 +83,7 @@ void PdmUiPropertyView::setUiConfigurationName(QString uiConfigName) if (m_currentObjectView) { - PdmObject* object = m_currentObjectView->pdmObject(); + PdmObjectHandle* object = m_currentObjectView->pdmObject(); delete m_currentObjectView; m_currentObjectView = NULL; this->showProperties(object); @@ -94,7 +94,7 @@ void PdmUiPropertyView::setUiConfigurationName(QString uiConfigName) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void PdmUiPropertyView::showProperties(caf::PdmObject* object) +void PdmUiPropertyView::showProperties( PdmObjectHandle* object) { // Find specialized object view handle @@ -108,7 +108,10 @@ void PdmUiPropertyView::showProperties(caf::PdmObject* object) { if (object) { - if (m_currentObjectView->pdmObject()->uiEditorTypeName(m_uiConfigName) != object->uiEditorTypeName(m_uiConfigName)) + PdmUiObjectHandle* uiObject1 = uiObj(m_currentObjectView->pdmObject()); + PdmUiObjectHandle* uiObject2 = uiObj(object); + + if (uiObject1 && uiObject2 && (uiObject1->uiEditorTypeName(m_uiConfigName) != uiObject2->uiEditorTypeName(m_uiConfigName))) { rebuildWidget = true; } @@ -148,7 +151,7 @@ void PdmUiPropertyView::showProperties(caf::PdmObject* object) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -caf::PdmObject* PdmUiPropertyView::currentObject() +PdmObjectHandle* PdmUiPropertyView::currentObject() { if (!m_currentObjectView) return NULL; return m_currentObjectView->pdmObject(); diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiPropertyView.h b/Fwk/AppFwk/cafUserInterface/cafPdmUiPropertyView.h index 36cad39a12..7b7083d5a2 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiPropertyView.h +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiPropertyView.h @@ -44,7 +44,7 @@ class QVBoxLayout; namespace caf { -class PdmObject; +class PdmObjectHandle; class PdmUiObjectEditorHandle; //================================================================================================== @@ -58,10 +58,10 @@ class PdmUiPropertyView : public QWidget PdmUiPropertyView(QWidget* parent = 0, Qt::WindowFlags f = 0); ~PdmUiPropertyView(); - void setUiConfigurationName(QString uiConfigName); - caf::PdmObject* currentObject(); + void setUiConfigurationName(QString uiConfigName); + PdmObjectHandle* currentObject(); public slots: - void showProperties(caf::PdmObject* object); + void showProperties(caf::PdmObjectHandle* object); // Signal/Slot system needs caf:: prefix in some cases private: PdmUiObjectEditorHandle* m_currentObjectView; diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiPropertyViewDialog.cpp b/Fwk/AppFwk/cafUserInterface/cafPdmUiPropertyViewDialog.cpp new file mode 100644 index 0000000000..e53998a216 --- /dev/null +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiPropertyViewDialog.cpp @@ -0,0 +1,114 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2015- Ceetron Solutions AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + + +#include "cafPdmUiPropertyViewDialog.h" + +#include "cafPdmObject.h" +#include "cafPdmUiPropertyView.h" + +#include + + +namespace caf +{ + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +PdmUiPropertyViewDialog::PdmUiPropertyViewDialog(QWidget* parent, PdmObject* object, const QString& windowTitle, const QString& uiConfigName) +{ + initialize(parent, object, windowTitle, uiConfigName, QDialogButtonBox::Ok | QDialogButtonBox::Cancel); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +PdmUiPropertyViewDialog::PdmUiPropertyViewDialog(QWidget* parent, PdmObject* object, const QString& windowTitle, + const QString& uiConfigName, const QDialogButtonBox::StandardButtons& standardButtons) +{ + initialize(parent, object, windowTitle, uiConfigName, standardButtons); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +PdmUiPropertyViewDialog::~PdmUiPropertyViewDialog() +{ + m_pdmUiPropertyView->showProperties(NULL); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiPropertyViewDialog::initialize(QWidget* parent, PdmObject* object, const QString& windowTitle, + const QString& uiConfigName, const QDialogButtonBox::StandardButtons& standardButtons) +{ + m_pdmObject = object; + m_windowTitle = windowTitle; + m_uiConfigName = uiConfigName; + + setupUi(standardButtons); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiPropertyViewDialog::setupUi(const QDialogButtonBox::StandardButtons& standardButtons) +{ + setWindowTitle(m_windowTitle); + + m_pdmUiPropertyView = new PdmUiPropertyView(this); + m_pdmUiPropertyView->setUiConfigurationName(m_uiConfigName); + + QVBoxLayout* dialogLayout = new QVBoxLayout; + setLayout(dialogLayout); + + dialogLayout->addWidget(m_pdmUiPropertyView); + m_pdmUiPropertyView->showProperties(m_pdmObject); + + // Buttons + QDialogButtonBox* buttonBox = new QDialogButtonBox(standardButtons); + connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept())); + connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); + + dialogLayout->addWidget(buttonBox); +} + + +} //End of namespace caf + diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiPropertyViewDialog.h b/Fwk/AppFwk/cafUserInterface/cafPdmUiPropertyViewDialog.h new file mode 100644 index 0000000000..3cdf73787e --- /dev/null +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiPropertyViewDialog.h @@ -0,0 +1,69 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2015- Ceetron Solutions AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + + +#pragma once + +#include +#include + +namespace caf +{ + +class PdmObject; +class PdmUiPropertyView; + + +class PdmUiPropertyViewDialog : public QDialog +{ +public: + PdmUiPropertyViewDialog(QWidget* parent, PdmObject* object, const QString& windowTitle, const QString& uiConfigName); + PdmUiPropertyViewDialog(QWidget* parent, PdmObject* object, const QString& windowTitle, const QString& uiConfigName, const QDialogButtonBox::StandardButtons& standardButtons); + ~PdmUiPropertyViewDialog(); + +private: + void initialize(QWidget* parent, PdmObject* object, const QString& windowTitle, const QString& uiConfigName, const QDialogButtonBox::StandardButtons& standardButtons); + void setupUi(const QDialogButtonBox::StandardButtons& standardButtons); + +private: + QString m_windowTitle; + QString m_uiConfigName; + PdmObject* m_pdmObject; + PdmUiPropertyView* m_pdmUiPropertyView; +}; + +} // End of namespace caf + diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiPushButtonEditor.cpp b/Fwk/AppFwk/cafUserInterface/cafPdmUiPushButtonEditor.cpp index 67fdfa6384..42108b0f76 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiPushButtonEditor.cpp +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiPushButtonEditor.cpp @@ -81,7 +81,11 @@ void PdmUiPushButtonEditor::configureAndUpdateUi(const QString& uiConfigName) m_label->setToolTip(field()->uiToolTip(uiConfigName)); PdmUiPushButtonEditorAttribute attributes; - field()->ownerObject()->editorAttribute(field(), uiConfigName, &attributes); + caf::PdmUiObjectHandle* uiObject = uiObj(field()->fieldHandle()->ownerObject()); + if (uiObject) + { + uiObject->editorAttribute(field()->fieldHandle(), uiConfigName, &attributes); + } QVariant variantFieldValue = field()->uiValue(); @@ -109,8 +113,6 @@ void PdmUiPushButtonEditor::configureAndUpdateUi(const QString& uiConfigName) { m_pushButton->setChecked(field()->uiValue().toBool()); } - - } @@ -139,7 +141,7 @@ QWidget* PdmUiPushButtonEditor::createLabelWidget(QWidget * parent) void PdmUiPushButtonEditor::slotClicked(bool checked) { - if (dynamic_cast *> (field())) + if (field() && dynamic_cast *> (field()->fieldHandle())) { QVariant v; v = checked; diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiSliderEditor.cpp b/Fwk/AppFwk/cafUserInterface/cafPdmUiSliderEditor.cpp index 09ef67ab65..ce09b82736 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiSliderEditor.cpp +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiSliderEditor.cpp @@ -83,7 +83,11 @@ void PdmUiSliderEditor::configureAndUpdateUi(const QString& uiConfigName) m_slider->setEnabled(!field()->isUiReadOnly(uiConfigName)); m_slider->setToolTip(field()->uiToolTip(uiConfigName)); - field()->ownerObject()->editorAttribute(field(), uiConfigName, &m_attributes); + caf::PdmUiObjectHandle* uiObject = uiObj(field()->fieldHandle()->ownerObject()); + if (uiObject) + { + uiObject->editorAttribute(field()->fieldHandle(), uiConfigName, &m_attributes); + } { m_spinBox->blockSignals(true); diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiTableItemEditor.cpp b/Fwk/AppFwk/cafUserInterface/cafPdmUiTableItemEditor.cpp new file mode 100644 index 0000000000..32ad3d34f1 --- /dev/null +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiTableItemEditor.cpp @@ -0,0 +1,81 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2014 Ceetron Solutions AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + + +#include "cafPdmUiTableItemEditor.h" + +#include "cafPdmField.h" +#include "cafPdmObject.h" +#include "cafPdmUiEditorHandle.h" +#include "cafPdmUiTableViewModel.h" + + +namespace caf +{ + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +PdmUiTableItemEditor::PdmUiTableItemEditor(PdmUiTableViewModel* model, caf::PdmObjectHandle* pdmObject, int row) +{ + m_model = model; + m_row = row; + + caf::PdmUiObjectHandle* uiObject = uiObj(pdmObject); + this->bindToPdmItem(uiObject); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +PdmUiTableItemEditor::~PdmUiTableItemEditor() +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiTableItemEditor::configureAndUpdateUi(const QString& uiConfigName) +{ + QModelIndex miStart = m_model->index(m_row, 0); + QModelIndex miEnd = m_model->index(m_row, m_model->columnCount()); + + m_model->notifyDataChanged(miStart, miEnd); +} + + +} // end namespace caf diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiTableItemEditor.h b/Fwk/AppFwk/cafUserInterface/cafPdmUiTableItemEditor.h new file mode 100644 index 0000000000..04d8a489fc --- /dev/null +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiTableItemEditor.h @@ -0,0 +1,66 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2014 Ceetron Solutions AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + +#pragma once + +#include "cafPdmUiEditorHandle.h" + +namespace caf +{ +class PdmUiTableViewModel; +class PdmObjectHandle; + + +//-------------------------------------------------------------------------------------------------- +/// This class is used to update a row in the model when a field value changes +//-------------------------------------------------------------------------------------------------- +class PdmUiTableItemEditor : public PdmUiEditorHandle +{ +public: + PdmUiTableItemEditor(PdmUiTableViewModel* model, caf::PdmObjectHandle* pdmObject, int row); + virtual ~PdmUiTableItemEditor(); + +protected: // Interface to override: + virtual void configureAndUpdateUi(const QString& uiConfigName); + +private: + PdmUiTableViewModel* m_model; + int m_row; +}; + + + +} // End of namespace caf diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiTableView.cpp b/Fwk/AppFwk/cafUserInterface/cafPdmUiTableView.cpp new file mode 100644 index 0000000000..6b96a90e40 --- /dev/null +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiTableView.cpp @@ -0,0 +1,156 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) Ceetron Solutions AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + + +#include "cafPdmUiTableView.h" + +#include "cafPdmObject.h" +#include "cafPdmUiTableViewEditor.h" + +#include + + +namespace caf +{ + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +PdmUiTableView::PdmUiTableView(QWidget* parent, Qt::WindowFlags f) + : QWidget (parent, f) +{ + QHBoxLayout* layout = new QHBoxLayout(this); + layout->setContentsMargins(0, 0, 0, 0); + layout->setSpacing(0); + + setLayout(layout); + + m_listViewEditor = new PdmUiTableViewEditor(); + + QWidget* widget = m_listViewEditor->createWidget(this); + layout->addWidget(widget); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +PdmUiTableView::~PdmUiTableView() +{ + if (m_listViewEditor) delete m_listViewEditor; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiTableView::setListField(PdmChildArrayFieldHandle* listField) +{ + assert(m_listViewEditor); + + m_listViewEditor->setListField(listField); + + // SIG_CAF_HACK + m_listViewEditor->updateUi(m_uiConfigName); +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +// SIG_CAF_HACK +void PdmUiTableView::setUiConfigurationName(QString uiConfigName) +{ + if (uiConfigName != m_uiConfigName) + { + m_uiConfigName = uiConfigName; + m_listViewEditor->updateUi(uiConfigName); + } +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QTableView* PdmUiTableView::tableView() +{ + assert(m_listViewEditor); + + return m_listViewEditor->tableView(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiTableView::enableDefaultContextMenu(bool enable) +{ + m_listViewEditor->enableDefaultContextMenu(enable); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiTableView::setSelectionRole(SelectionManager::SelectionRole role) +{ + m_listViewEditor->setSelectionRole(role); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiTableView::handleModelNotification(caf::PdmObjectHandle* itemThatChanged) +{ + // Nothing to do for now +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiTableView::handleModelSelectionChange() +{ + m_listViewEditor->handleModelSelectionChange(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +PdmObjectHandle* PdmUiTableView::pdmObjectFromModelIndex(const QModelIndex& mi) +{ + return m_listViewEditor->pdmObjectFromModelIndex(mi); +} + + +} //End of namespace caf + diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiTableView.h b/Fwk/AppFwk/cafUserInterface/cafPdmUiTableView.h new file mode 100644 index 0000000000..b34c10865c --- /dev/null +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiTableView.h @@ -0,0 +1,89 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) Ceetron Solutions AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + + +#pragma once + +#include "cafNotificationCenter.h" +#include "cafSelectionManager.h" + +#include +#include +#include + +class QTableView; + +namespace caf +{ + +class PdmObjectHandle; +class PdmUiTableViewEditor; +class PdmChildArrayFieldHandle; + +//================================================================================================== +/// +//================================================================================================== +class PdmUiTableView : public QWidget, public DataModelObserver +{ + Q_OBJECT +public: + PdmUiTableView(QWidget* parent = 0, Qt::WindowFlags f = 0); + ~PdmUiTableView(); + + PdmObjectHandle* pdmObjectFromModelIndex(const QModelIndex& mi); + + // SIG_CAF_HACK + void setUiConfigurationName(QString uiConfigName); + + void setListField(PdmChildArrayFieldHandle* object); + + void enableDefaultContextMenu(bool enable); + void setSelectionRole(SelectionManager::SelectionRole role); + + QTableView* tableView(); + + virtual void handleModelNotification(caf::PdmObjectHandle* itemThatChanged); + virtual void handleModelSelectionChange(); + +private: + PdmUiTableViewEditor* m_listViewEditor; + QString m_uiConfigName; +}; + + + +} // End of namespace caf + diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiTableViewDelegate.cpp b/Fwk/AppFwk/cafUserInterface/cafPdmUiTableViewDelegate.cpp new file mode 100644 index 0000000000..244fbd81c2 --- /dev/null +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiTableViewDelegate.cpp @@ -0,0 +1,119 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) Ceetron Solutions AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + +#include "cafPdmUiTableViewDelegate.h" + +#include "cafPdmUiFieldEditorHandle.h" +#include "cafPdmUiTableViewModel.h" + +#include + + +namespace caf +{ + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +PdmUiTableViewDelegate::PdmUiTableViewDelegate(QObject* parent, PdmUiTableViewModel* model) + : QStyledItemDelegate(parent), + m_model(model) +{ + m_activeEditorCount = 0; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +PdmUiTableViewDelegate::~PdmUiTableViewDelegate() +{ + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QWidget * PdmUiTableViewDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const +{ + assert(m_model); + QWidget* editorWidget = m_model->getEditorWidgetAndTransferOwnership(parent, index); + + connect( editorWidget, SIGNAL(destroyed(QObject*)), SLOT(slotEditorDestroyed(QObject*))); + m_activeEditorCount++; + + return editorWidget; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiTableViewDelegate::setEditorData(QWidget* editor, const QModelIndex& index) const +{ + PdmUiFieldEditorHandle* fieldHandle = m_model->getEditor(index); + if (fieldHandle) + { + fieldHandle->updateUi(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiTableViewDelegate::updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index) const +{ + editor->setGeometry(option.rect); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiTableViewDelegate::slotEditorDestroyed(QObject* obj) +{ + m_activeEditorCount--; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool PdmUiTableViewDelegate::isEditorOpen() const +{ + return m_activeEditorCount > 0; +} + + +} // end namespace caf + + diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiTableViewDelegate.h b/Fwk/AppFwk/cafUserInterface/cafPdmUiTableViewDelegate.h new file mode 100644 index 0000000000..5419640c1a --- /dev/null +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiTableViewDelegate.h @@ -0,0 +1,78 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) Ceetron Solutions AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + +#pragma once + + +#include + + +namespace caf +{ + +class PdmUiTableViewModel; + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +class PdmUiTableViewDelegate : public QStyledItemDelegate +{ + Q_OBJECT + +public: + PdmUiTableViewDelegate(QObject* parent, PdmUiTableViewModel* model); + ~PdmUiTableViewDelegate(); + + QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const; + void setEditorData(QWidget* editor, const QModelIndex& index) const; + void updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index) const; + + bool isEditorOpen() const; + +protected slots: + void slotEditorDestroyed(QObject* obj); + +private: + PdmUiTableViewModel* m_model; + + // Counter for active table cell editors + mutable int m_activeEditorCount; +}; + + + +} // end namespace caf diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiTableViewEditor.cpp b/Fwk/AppFwk/cafUserInterface/cafPdmUiTableViewEditor.cpp new file mode 100644 index 0000000000..70ad2a96b8 --- /dev/null +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiTableViewEditor.cpp @@ -0,0 +1,426 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) Ceetron Solutions AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + + +#include "cafPdmUiTableViewEditor.h" + +#include "cafPdmChildArrayField.h" +#include "cafPdmField.h" +#include "cafPdmObject.h" +#include "cafPdmUiCheckBoxDelegate.h" +#include "cafPdmUiCommandSystemProxy.h" +#include "cafPdmUiEditorHandle.h" +#include "cafPdmUiTableViewDelegate.h" +#include "cafPdmUiTableViewModel.h" + +#include +#include +#include +#include +#include +#include +#include + + + +namespace caf +{ + +class FocusEventHandler : public QObject +{ +public: + FocusEventHandler(PdmUiTableViewEditor* tableViewEditor) + : QObject(tableViewEditor) + { + m_tableViewEditor = tableViewEditor; + } + +protected: + bool eventFilter(QObject *obj, QEvent *event) + { + if (event->type() == QEvent::FocusIn || + event->type() == QEvent::FocusOut) + { + m_tableViewEditor->tableViewWidgetFocusChanged(event); + } + + // standard event processing + return QObject::eventFilter(obj, event); + } + + +private: + PdmUiTableViewEditor* m_tableViewEditor; +}; + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +PdmUiTableViewEditor::PdmUiTableViewEditor() +{ + m_layout = NULL;; + m_tableView = NULL; + m_tableModelPdm = NULL; + m_pdmListField = NULL; + m_delegate = NULL; + + m_useDefaultContextMenu = false; + + m_checkboxDelegate = new PdmUiCheckBoxDelegate(this); + + m_selectionRole = SelectionManager::CURRENT; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +PdmUiTableViewEditor::~PdmUiTableViewEditor() +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QWidget* PdmUiTableViewEditor::createWidget(QWidget* parent) +{ + m_mainWidget = new QWidget(parent); + m_layout = new QVBoxLayout(); + m_mainWidget->setLayout(m_layout); + + m_tableModelPdm = new PdmUiTableViewModel(m_mainWidget); + + m_delegate = new PdmUiTableViewDelegate(this, m_tableModelPdm); + + m_tableView = new QTableView(m_mainWidget); + m_tableView->setShowGrid(true); + m_tableView->setModel(m_tableModelPdm); + + connect(m_tableView->selectionModel(), SIGNAL(selectionChanged( const QItemSelection & , const QItemSelection & )), SLOT(slotSelectionChanged( const QItemSelection & , const QItemSelection & ))); + connect(m_tableView->selectionModel(), SIGNAL(currentChanged( const QModelIndex & , const QModelIndex & )), SLOT(slotCurrentChanged( const QModelIndex& , const QModelIndex& ))); + + FocusEventHandler* tableViewWidgetFocusEventHandler = new FocusEventHandler(this); + m_tableView->installEventFilter(tableViewWidgetFocusEventHandler); + + updateContextMenuSignals(); + + QHBoxLayout* layoutForIconLabel = new QHBoxLayout(); + m_tableHeading = new QLabel(m_mainWidget); + m_tableHeadingIcon = new QLabel(m_mainWidget); + layoutForIconLabel->addWidget(m_tableHeadingIcon); + layoutForIconLabel->addSpacing(5); + layoutForIconLabel->addWidget(m_tableHeading); + layoutForIconLabel->addStretch(); + + m_layout->addItem(layoutForIconLabel); + + m_layout->addWidget(m_tableView); + + return m_mainWidget; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiTableViewEditor::configureAndUpdateUi(const QString& uiConfigName) +{ + m_tableModelPdm->setPdmData(m_pdmListField, uiConfigName); + + if (m_tableModelPdm->rowCount() > 0) + { + for (int i = 0; i < m_tableModelPdm->columnCount(); i++) + { + if (m_tableModelPdm->isRepresentingBoolean(m_tableModelPdm->index(0, i))) + { + m_tableView->setItemDelegateForColumn(i, m_checkboxDelegate); + } + else + { + m_tableView->setItemDelegateForColumn(i, m_delegate); + } + } + } + + if (m_pdmListField && m_pdmListField->uiCapability()) + { + QString text = ""; + m_tableHeadingIcon->setPixmap(m_pdmListField->uiCapability()->uiIcon(uiConfigName).pixmap(16, 16)); + m_tableHeading->setText(m_pdmListField->uiCapability()->uiName(uiConfigName) + QString(" (%1)").arg(m_pdmListField->size())); + } + else + { + m_tableHeading->setText(""); + m_tableHeadingIcon->setPixmap(QPixmap()); + } +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiTableViewEditor::setListField(PdmChildArrayFieldHandle* pdmListField) +{ + m_pdmListField = pdmListField; + + caf::PdmUiFieldHandle* uifield = NULL; + if (m_pdmListField) + { + uifield = m_pdmListField->uiCapability(); + } + this->bindToPdmItem(uifield); + + if (!m_pdmListField) + { + m_tableModelPdm->setPdmData(NULL, ""); + m_tableHeading->setText(""); + m_tableHeadingIcon->setPixmap(QPixmap()); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiTableViewEditor::selectedUiItems(const QModelIndexList& modelIndexList, std::vector& objects) +{ + for (int i = 0; i < modelIndexList.size(); i++) + { + QModelIndex mi = modelIndexList[i]; + int row = mi.row(); + + caf::PdmUiObjectHandle* uiObject = uiObj(m_tableModelPdm->pdmObjectForRow(row)); + if (uiObject) + { + objects.push_back(uiObject); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiTableViewEditor::customMenuRequested(QPoint pos) +{ + // This is function is required to execute before populating the menu + // Several commands rely on the activeChildArrayFieldHandle in the selection manager + SelectionManager::instance()->setActiveChildArrayFieldHandle(m_pdmListField); + + QMenu menu; + caf::PdmUiCommandSystemProxy::instance()->populateMenuWithDefaultCommands("PdmUiTreeViewEditor", &menu); + + if (menu.actions().size() > 0) + { + // Qt doc: QAbstractScrollArea and its subclasses that map the context menu event to coordinates of the viewport(). + QPoint globalPos = m_tableView->viewport()->mapToGlobal(pos); + + menu.exec(globalPos); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QTableView* PdmUiTableViewEditor::tableView() +{ + return m_tableView; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiTableViewEditor::enableDefaultContextMenu(bool enable) +{ + m_useDefaultContextMenu = enable; + + updateContextMenuSignals(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiTableViewEditor::updateContextMenuSignals() +{ + if (!m_tableView) return; + + if (m_useDefaultContextMenu) + { + m_tableView->setContextMenuPolicy(Qt::CustomContextMenu); + connect(m_tableView, SIGNAL(customContextMenuRequested(QPoint)), SLOT(customMenuRequested(QPoint))); + } + else + { + m_tableView->setContextMenuPolicy(Qt::DefaultContextMenu); + disconnect(m_tableView, 0, this, 0); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiTableViewEditor::setSelectionRole(SelectionManager::SelectionRole role) +{ + m_selectionRole = role; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiTableViewEditor::slotCurrentChanged(const QModelIndex & current, const QModelIndex & previous) +{ + if (isSelectionRoleDefined()) + { + std::vector items; + QModelIndexList list; + list.append(current); + selectedUiItems(list, items); + + SelectionManager::instance()->setSelectedItems(items, m_selectionRole); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiTableViewEditor::handleModelSelectionChange() +{ + if (isSelectionRoleDefined()) + { + std::vector items; + SelectionManager::instance()->selectedItems(items, m_selectionRole); + + // TODO: Handle multiple selection + if (items.size() == 1) + { + PdmObject* pdmObj = dynamic_cast(items[0]); + QItemSelection itemSelection = m_tableModelPdm->modelIndexFromPdmObject(pdmObj); + if (itemSelection.size() > 0) + { + m_tableView->selectionModel()->select(itemSelection, QItemSelectionModel::SelectCurrent); + } + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// NOTE: If no selection role is defined, the selection manager is not changed, the selection in the +/// editor is local to the editor +//-------------------------------------------------------------------------------------------------- +void PdmUiTableViewEditor::slotSelectionChanged(const QItemSelection & selected, const QItemSelection & deselected) +{ + updateSelectionManagerFromTableSelection(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool PdmUiTableViewEditor::isSelectionRoleDefined() const +{ + return m_selectionRole != SelectionManager::UNDEFINED; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +PdmObjectHandle* PdmUiTableViewEditor::pdmObjectFromModelIndex(const QModelIndex& mi) +{ + if (mi.isValid()) + { + return m_tableModelPdm->pdmObjectForRow(mi.row()); + } + + return NULL; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiTableViewEditor::tableViewWidgetFocusChanged(QEvent* focusEvent) +{ + if (m_delegate->isEditorOpen()) + { + // The table view emits focus out when a table cell editor is active + // Do not update the selection when this state occurs + return; + } + + if (isSelectionRoleDefined()) + { + if (focusEvent->type() == QEvent::FocusIn) + { + updateSelectionManagerFromTableSelection(); + } + else if (focusEvent->type() == QEvent::FocusOut) + { + // Clearing the selection here causes the Menu to not display all items + // Not sure how this can be handled correctly + // SelectionManager::instance()->clear(m_selectionRole); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiTableViewEditor::updateSelectionManagerFromTableSelection() +{ + if (isSelectionRoleDefined()) + { + std::vector items; + + QModelIndexList modelIndexList = m_tableView->selectionModel()->selectedIndexes(); + for (int i = 0; i < modelIndexList.size(); i++) + { + QModelIndex mi = modelIndexList[i]; + PdmFieldHandle* pdmFieldHandle = m_tableModelPdm->getField(mi); + + if (pdmFieldHandle && pdmFieldHandle->uiCapability()) + { + items.push_back(pdmFieldHandle->uiCapability()); + } + } + + if (items.size() > 1) + { + // Selection of a single row is handled by slotCurrentChanged() + // Multiple selection of fields is handled here + SelectionManager::instance()->setSelectedItems(items, m_selectionRole); + } + } +} + + +} // end namespace caf + + diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiTableViewEditor.h b/Fwk/AppFwk/cafUserInterface/cafPdmUiTableViewEditor.h new file mode 100644 index 0000000000..34396e6136 --- /dev/null +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiTableViewEditor.h @@ -0,0 +1,125 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) Ceetron Solutions AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + + +#pragma once + +#include "cafPdmDocument.h" +#include "cafPdmUiFieldEditorHandle.h" +#include "cafPdmUiObjectEditorHandle.h" +#include "cafSelectionManager.h" + +#include +#include +#include + +class QItemSelection; +class QLabel; +class QMenu; +class QTableView; + +namespace caf +{ + +class PdmUiCheckBoxDelegate; +class PdmUiFieldEditorHandle; +class PdmUiItem; +class PdmUiTableViewDelegate; +class PdmUiTableViewModel; + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- + +class PdmUiTableViewEditor : public PdmUiEditorHandle +{ + Q_OBJECT + +public: + PdmUiTableViewEditor(); + ~PdmUiTableViewEditor(); + + void enableDefaultContextMenu(bool enable); + void setSelectionRole(SelectionManager::SelectionRole role); + + PdmObjectHandle* pdmObjectFromModelIndex(const QModelIndex& mi); + + void setListField(PdmChildArrayFieldHandle* pdmListField); + QWidget* createWidget(QWidget* parent); + + QTableView* tableView(); + + void handleModelSelectionChange(); +protected: + virtual void configureAndUpdateUi(const QString& uiConfigName); + +private: + void updateContextMenuSignals(); + void selectedUiItems(const QModelIndexList& modelIndexList, std::vector& objects); + bool isSelectionRoleDefined() const; + void tableViewWidgetFocusChanged(QEvent* focusEvent); + void updateSelectionManagerFromTableSelection(); + +private slots: + void customMenuRequested(QPoint pos); + void slotCurrentChanged(const QModelIndex & current, const QModelIndex & previous); + void slotSelectionChanged(const QItemSelection & selected, const QItemSelection & deselected); + +private: + friend class FocusEventHandler; + + std::map m_fieldViews; + + QPointer m_mainWidget; + QLayout* m_layout; + QLabel* m_tableHeading; + QLabel* m_tableHeadingIcon; + + QTableView* m_tableView; + PdmUiTableViewModel* m_tableModelPdm; + + PdmChildArrayFieldHandle* m_pdmListField; + PdmUiTableViewDelegate* m_delegate; + PdmUiCheckBoxDelegate* m_checkboxDelegate; + + bool m_useDefaultContextMenu; + SelectionManager::SelectionRole m_selectionRole; +}; + + + +} // end namespace caf diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiTableViewModel.cpp b/Fwk/AppFwk/cafUserInterface/cafPdmUiTableViewModel.cpp new file mode 100644 index 0000000000..8a7a012f37 --- /dev/null +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiTableViewModel.cpp @@ -0,0 +1,584 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2014 Ceetron Solutions AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + + +#include "cafPdmUiTableViewModel.h" + +#include "cafPdmChildArrayField.h" +#include "cafPdmField.h" +#include "cafPdmObject.h" +#include "cafPdmUiComboBoxEditor.h" +#include "cafPdmUiCommandSystemProxy.h" +#include "cafPdmUiLineEditor.h" +#include "cafPdmUiTableItemEditor.h" +#include "cafSelectionManager.h" + + +namespace caf +{ + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +PdmUiTableViewModel::PdmUiTableViewModel(QWidget* parent) + : QAbstractTableModel(parent) +{ + m_pdmList = NULL; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +int PdmUiTableViewModel::rowCount(const QModelIndex &parent /*= QModelIndex( ) */) const +{ + if (!m_pdmList) return 0; + + size_t itemCount = m_pdmList->size(); + return static_cast(itemCount); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +int PdmUiTableViewModel::columnCount(const QModelIndex &parent /*= QModelIndex( ) */) const +{ + return static_cast(m_modelColumnIndexToFieldIndex.size()); + + // SIG_CAF_HACK + // Magne hack to comment out code that crashed + /* + std::vector listObjects; + if (m_pdmList) + { + m_pdmList->childObjects(&listObjects); + + if (listObjects.size() > 0) + { + PdmObject* pdmObject = listObjects[0]; + if (pdmObject) + { + std::vector fields; + pdmObject->fields(fields); + + return static_cast(fields.size()); + } + } + } + + return 0; + */ +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QVariant PdmUiTableViewModel::headerData(int section, Qt::Orientation orientation, int role /*= Qt::DisplayRole */) const +{ + if (role == Qt::DisplayRole) + { + if (orientation == Qt::Horizontal) + { + PdmUiFieldHandle* uiFieldHandle = getField(createIndex(0, section))->uiCapability(); + if (uiFieldHandle) + { + return uiFieldHandle->uiName(m_currentConfigName); + } + } + } + + return QVariant(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +Qt::ItemFlags PdmUiTableViewModel::flags(const QModelIndex &index) const +{ + if (!index.isValid()) + return Qt::ItemIsEnabled; + + Qt::ItemFlags flagMask = QAbstractItemModel::flags(index); + + if (isRepresentingBoolean(index)) + { + flagMask = flagMask | Qt::ItemIsUserCheckable; + } + else + { + flagMask = flagMask | Qt::ItemIsEditable; + } + + PdmFieldHandle* field = getField(index); + PdmUiFieldHandle* uiFieldHandle = field->uiCapability(); + if (uiFieldHandle) + { + if (uiFieldHandle->isUiReadOnly(m_currentConfigName)) + { + flagMask = flagMask ^ Qt::ItemIsEditable; + } + } + return flagMask; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool PdmUiTableViewModel::setData(const QModelIndex &index, const QVariant &value, int role /*= Qt::EditRole*/) +{ + if (role == Qt::CheckStateRole) + { + if (isRepresentingBoolean(index)) + { + // Clear current selection, UI does not behave well for multiple selection + SelectionManager::instance()->clear(SelectionManager::CURRENT); + + bool toggleOn = (value == Qt::Checked); + PdmFieldHandle* field = getField(index); + + PdmUiFieldHandle* uiFieldHandle = field->uiCapability(); + PdmUiCommandSystemProxy::instance()->setUiValueToField(uiFieldHandle, toggleOn); + + return true; + } + } + + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QVariant PdmUiTableViewModel::data(const QModelIndex &index, int role /*= Qt::DisplayRole */) const +{ + if (role == Qt::DisplayRole || role == Qt::EditRole) + { + PdmFieldHandle* fieldHandle = getField(index); + PdmUiFieldHandle* uiFieldHandle = fieldHandle->uiCapability(); + if (uiFieldHandle) + { + bool fromMenuOnly = false; + QList valueOptions = uiFieldHandle->valueOptions(&fromMenuOnly); + if (!valueOptions.isEmpty()) + { + int listIndex = uiFieldHandle->uiValue().toInt(); + if (listIndex == -1) + { + return ""; + } + + return valueOptions[listIndex].optionUiText; + } + + QVariant val; + + PdmObjectHandle* objForRow = this->pdmObjectForRow(index.row()); + PdmUiObjectHandle* uiObjForRow = uiObj(objForRow); + if (uiObjForRow) + { + // NOTE: Redesign + // To be able to get formatted string, an editor attribute concept is used + // TODO: Create a function in pdmObject like this + // virtual void defineDisplayString(const PdmFieldHandle* field, QString uiConfigName) {} + + PdmUiLineEditorAttributeUiDisplayString leab; + uiObjForRow->editorAttribute(fieldHandle, m_currentConfigName, &leab); + + if (!leab.m_displayString.isEmpty()) + { + val = leab.m_displayString; + } + else + { + val = uiFieldHandle->uiValue(); + } + } + else + { + val = uiFieldHandle->uiValue(); + } + + return val; + } + else + { + assert(false); + } + } + else if (role == Qt::CheckStateRole) + { + if (isRepresentingBoolean(index)) + { + PdmUiFieldHandle* uiFieldHandle = getField(index)->uiCapability(); + if (uiFieldHandle) + { + QVariant val = uiFieldHandle->uiValue(); + bool isToggledOn = val.toBool(); + if (isToggledOn) + { + return Qt::Checked; + } + else + { + return Qt::Unchecked; + } + } + else + { + return QVariant(); + } + } + } + + return QVariant(); +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiTableViewModel::setPdmData(PdmChildArrayFieldHandle* listField, const QString& configName) +{ + beginResetModel(); + + m_pdmList = listField; + m_currentConfigName = configName; + + PdmUiOrdering config; + + if (m_pdmList && m_pdmList->size() > 0) + { + PdmObjectHandle* firstObject = m_pdmList->at(0); + + PdmUiObjectHandle* uiObject = uiObj(firstObject); + if (uiObject) + { + uiObject->uiOrdering(configName, config); + } + } + + const std::vector& uiItems = config.uiItems(); + + // Set all fieldViews to be unvisited + std::map::iterator it; + for (it = m_fieldEditors.begin(); it != m_fieldEditors.end(); ++it) + { + it->second->setField(NULL); + } + + m_modelColumnIndexToFieldIndex.clear(); + + for (size_t i = 0; i < uiItems.size(); ++i) + { + if (uiItems[i]->isUiHidden(configName)) continue; + + if (uiItems[i]->isUiGroup()) continue; + + { + PdmUiFieldHandle* field = dynamic_cast(uiItems[i]); + PdmUiFieldEditorHandle* fieldEditor = NULL; + + // Find or create FieldEditor + std::map::iterator it; + it = m_fieldEditors.find(field->fieldHandle()->keyword()); + + if (it == m_fieldEditors.end()) + { + // If editor type is specified, find in factory + if ( !uiItems[i]->uiEditorTypeName(configName).isEmpty() ) + { + fieldEditor = Factory::instance()->create(field->uiEditorTypeName(configName)); + } + else + { + // Find the default field editor + + QString editorTypeName = qStringTypeName(*(field->fieldHandle())); + + // Handle a single value field with valueOptions: Make a combobox + + if (field->uiValue().type() != QVariant::List) + { + bool useOptionsOnly = true; + QList options = field->valueOptions( &useOptionsOnly); + + if (!options.empty()) + { + editorTypeName = PdmUiComboBoxEditor::uiEditorTypeName(); + } + } + + fieldEditor = Factory::instance()->create(editorTypeName); + } + + if (fieldEditor) + { + m_fieldEditors[field->fieldHandle()->keyword()] = fieldEditor; + } + } + else + { + fieldEditor = it->second; + } + + if (fieldEditor) + { + fieldEditor->setField(field); + + //TODO: Create/update is not required at this point, as UI is recreated in getEditorWidgetAndTransferOwnership() + // Can be moved, but a move will require changes in PdmUiFieldEditorHandle + fieldEditor->createWidgets(NULL); + fieldEditor->updateUi(configName); + + int fieldIndex = getFieldIndex(field->fieldHandle()); + m_modelColumnIndexToFieldIndex.push_back(fieldIndex); + } + } + } + + + // Remove all fieldViews not mentioned by the configuration from the layout + + std::vector< QString > fvhToRemoveFromMap; + for (it = m_fieldEditors.begin(); it != m_fieldEditors.end(); ++it) + { + if (it->second->field() == 0) + { + PdmUiFieldEditorHandle* fvh = it->second; + delete fvh; + fvhToRemoveFromMap.push_back(it->first); + } + } + + for (size_t i = 0; i < fvhToRemoveFromMap.size(); ++i) + { + m_fieldEditors.erase(fvhToRemoveFromMap[i]); + } + + recreateTableItemEditors(); + + endResetModel(); +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +PdmFieldHandle* PdmUiTableViewModel::getField(const QModelIndex &index) const +{ + if (m_pdmList && index.row() < static_cast(m_pdmList->size())) + { + PdmObjectHandle* pdmObject = m_pdmList->at(index.row()); + if (pdmObject) + { + std::vector fields; + pdmObject->fields(fields); + + int fieldIndex = m_modelColumnIndexToFieldIndex[index.column()]; + if (fieldIndex < static_cast(fields.size())) + { + return fields[fieldIndex]; + } + else + { + assert(false); + } + } + } + + return NULL; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +PdmUiFieldEditorHandle* PdmUiTableViewModel::getEditor(const QModelIndex &index) +{ + PdmFieldHandle* field = getField(index); + if (!field) + { + return NULL; + } + + PdmUiFieldEditorHandle* editor = NULL; + + std::map::iterator it; + it = m_fieldEditors.find(field->keyword()); + + if (it != m_fieldEditors.end()) + { + editor = it->second; + if (editor) + { + if (field) + { + editor->setField(field->uiCapability()); + } + } + } + + return editor; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QWidget* PdmUiTableViewModel::getEditorWidgetAndTransferOwnership(QWidget* parent, const QModelIndex &index) +{ + PdmUiFieldEditorHandle* editor = getEditor(index); + if (editor) + { + // Recreate editor widget, as the delegate takes ownership of the QWidget and destroys it when + // edit is completed. This will cause the editor widget pointer to be NULL, as it is a guarded pointer + // using QPointer + editor->createWidgets(parent); + QWidget* editorWidget = editor->editorWidget(); + editorWidget->setParent(parent); + + return editorWidget; + } + + return NULL; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiTableViewModel::notifyDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight) +{ + emit dataChanged(topLeft, bottomRight); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiTableViewModel::recreateTableItemEditors() +{ + for (size_t i = 0; i < m_tableItemEditors.size(); i++) + { + delete m_tableItemEditors[i]; + } + m_tableItemEditors.clear(); + + if (m_pdmList) + { + for (size_t i = 0; i < m_pdmList->size(); i++) + { + PdmObjectHandle* pdmObject = m_pdmList->at(i); + m_tableItemEditors.push_back(new PdmUiTableItemEditor(this, pdmObject, static_cast(i))); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +PdmObjectHandle* PdmUiTableViewModel::pdmObjectForRow(int row) const +{ + if (m_pdmList && row < m_pdmList->size()) + { + return m_pdmList->at(row); + } + + return NULL; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool PdmUiTableViewModel::isRepresentingBoolean(const QModelIndex &index) const +{ + if (getField(index)) + { + QVariant val = getField(index)->uiCapability()->uiValue(); + if (val.type() == QVariant::Bool) + { + return true; + } + } + + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QItemSelection PdmUiTableViewModel::modelIndexFromPdmObject(PdmObjectHandle* pdmObject) +{ + QItemSelection itemSelection; + + for (int i = 0; i < this->rowCount(); i++) + { + PdmObjectHandle* obj = this->pdmObjectForRow(i); + if (obj == pdmObject) + { + // Currently selection only on model index, can be exteded to select whole row + itemSelection.select(this->createIndex(i, 0), this->createIndex(i, 0)); + } + } + + return itemSelection; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +int PdmUiTableViewModel::getFieldIndex(PdmFieldHandle* field) const +{ + if (m_pdmList && m_pdmList->size() > 0) + { + PdmObjectHandle* pdmObject = m_pdmList->at(0); + if (pdmObject) + { + std::vector fields; + pdmObject->fields(fields); + + for (size_t i = 0; i < fields.size(); i++) + { + if (fields[i]->keyword() == field->keyword()) + { + return static_cast(i); + } + } + } + } + + return -1; +} + + + +} // end namespace caf diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiTableViewModel.h b/Fwk/AppFwk/cafUserInterface/cafPdmUiTableViewModel.h new file mode 100644 index 0000000000..ff130d65f2 --- /dev/null +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiTableViewModel.h @@ -0,0 +1,106 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2014 Ceetron Solutions AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + +#pragma once + +#include "cafPdmUiTreeOrdering.h" + +#include +#include + +namespace caf +{ + +class PdmChildArrayFieldHandle; +class PdmObjectHandle; +class PdmUiFieldEditorHandle; +class PdmUiItem; +class PdmUiTableItemEditor; +class PdmUiTreeOrdering; +class PdmUiTreeViewEditor; + +//================================================================================================== +// +// +//================================================================================================== +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +class PdmUiTableViewModel : public QAbstractTableModel +{ + Q_OBJECT + +public: + PdmUiTableViewModel(QWidget* parent); + + QItemSelection modelIndexFromPdmObject(PdmObjectHandle* pdmObject); + PdmFieldHandle* getField(const QModelIndex &index) const; + void setPdmData(PdmChildArrayFieldHandle* pdmObject, const QString& configName); + PdmObjectHandle* pdmObjectForRow(int row) const; + + // Qt overrides + virtual int rowCount( const QModelIndex &parent = QModelIndex( ) ) const; + virtual int columnCount( const QModelIndex &parent = QModelIndex( ) ) const; + virtual QVariant data( const QModelIndex &index, int role = Qt::DisplayRole ) const; + virtual QVariant headerData( int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const; + + virtual Qt::ItemFlags flags(const QModelIndex &index) const; + virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); + + void selectedUiItems(std::vector& objects); + + PdmUiFieldEditorHandle* getEditor(const QModelIndex &index); + QWidget* getEditorWidgetAndTransferOwnership(QWidget* parent, const QModelIndex &index); + void notifyDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight); + + bool isRepresentingBoolean(const QModelIndex &index) const; + +private: + int getFieldIndex(PdmFieldHandle* field) const; + void recreateTableItemEditors(); + +private: + PdmChildArrayFieldHandle* m_pdmList; + QString m_currentConfigName; + + std::map m_fieldEditors; + std::vector m_modelColumnIndexToFieldIndex; + + std::vector m_tableItemEditors; +}; + + +} // End of namespace caf diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiTextEditor.cpp b/Fwk/AppFwk/cafUserInterface/cafPdmUiTextEditor.cpp index 6771e82559..8203e6d0e8 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiTextEditor.cpp +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiTextEditor.cpp @@ -37,21 +37,18 @@ #include "cafPdmUiTextEditor.h" -#include "cafPdmUiDefaultObjectEditor.h" - +#include "cafPdmField.h" #include "cafPdmObject.h" +#include "cafPdmUiDefaultObjectEditor.h" #include "cafPdmUiFieldEditorHandle.h" #include "cafPdmUiOrdering.h" -#include "cafPdmField.h" - #include #include #include #include #include -#include "cafFactory.h" @@ -61,6 +58,25 @@ namespace caf CAF_PDM_UI_FIELD_EDITOR_SOURCE_INIT(PdmUiTextEditor); +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TextEdit::TextEdit(QWidget *parent /*= 0*/) : QTextEdit(parent) +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void TextEdit::focusOutEvent(QFocusEvent *e) +{ + QTextEdit::focusOutEvent(e); + + emit editingFinished(); +} + + + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -87,17 +103,23 @@ void PdmUiTextEditor::configureAndUpdateUi(const QString& uiConfigName) m_textEdit->setToolTip(field()->uiToolTip(uiConfigName)); PdmUiTextEditorAttribute leab; - field()->ownerObject()->editorAttribute(field(), uiConfigName, &leab); + + caf::PdmUiObjectHandle* uiObject = uiObj(field()->fieldHandle()->ownerObject()); + if (uiObject) + { + uiObject->editorAttribute(field()->fieldHandle(), uiConfigName, &leab); + } + m_textMode = leab.textMode; if (leab.showSaveButton) { - disconnect(m_textEdit, SIGNAL(textChanged()), this, SLOT(slotTextChanged())); + disconnect(m_textEdit, SIGNAL(editingFinished()), this, SLOT(slotSetValueToField())); m_saveButton->show(); } else { - connect(m_textEdit, SIGNAL(textChanged()), this, SLOT(slotTextChanged())); + connect(m_textEdit, SIGNAL(editingFinished()), this, SLOT(slotSetValueToField())); m_saveButton->hide(); } @@ -115,7 +137,6 @@ void PdmUiTextEditor::configureAndUpdateUi(const QString& uiConfigName) } - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -123,11 +144,11 @@ QWidget* PdmUiTextEditor::createEditorWidget(QWidget * parent) { QWidget* containerWidget = new QWidget(parent); - m_textEdit = new QTextEdit(containerWidget); - connect(m_textEdit, SIGNAL(textChanged()), this, SLOT(slotTextChanged())); + m_textEdit = new TextEdit(containerWidget); + connect(m_textEdit, SIGNAL(editingFinished()), this, SLOT(slotSetValueToField())); m_saveButton = new QPushButton("Save changes", containerWidget); - connect(m_saveButton, SIGNAL(clicked()), this, SLOT(slotSaveButtonClicked())); + connect(m_saveButton, SIGNAL(clicked()), this, SLOT(slotSetValueToField())); QVBoxLayout* layout = new QVBoxLayout; layout->addWidget(m_textEdit); @@ -154,7 +175,7 @@ QWidget* PdmUiTextEditor::createLabelWidget(QWidget * parent) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void PdmUiTextEditor::slotTextChanged() +void PdmUiTextEditor::slotSetValueToField() { QVariant v; QString textValue; @@ -174,13 +195,5 @@ void PdmUiTextEditor::slotTextChanged() this->setValueToField(v); } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void PdmUiTextEditor::slotSaveButtonClicked() -{ - slotTextChanged(); -} - } // end namespace caf diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiTextEditor.h b/Fwk/AppFwk/cafUserInterface/cafPdmUiTextEditor.h index 0e669307ea..2b87b39cc2 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiTextEditor.h +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiTextEditor.h @@ -50,9 +50,8 @@ namespace caf { //================================================================================================== -/// An editor to show (and possibly edit?) formatted larger portions of text +/// //================================================================================================== - class PdmUiTextEditorAttribute : public PdmUiEditorAttribute { public: @@ -73,7 +72,26 @@ class PdmUiTextEditorAttribute : public PdmUiEditorAttribute bool showSaveButton; }; +//================================================================================================== +/// Override focus out event and emit editinghFinished to avoid multiple field changed events +//================================================================================================== +class TextEdit : public QTextEdit +{ + Q_OBJECT +public: + explicit TextEdit(QWidget *parent = 0); +protected: + virtual void focusOutEvent(QFocusEvent *e); + +signals: + void editingFinished(); +}; + + +//================================================================================================== +/// An editor to show (and possibly edit?) formatted larger portions of text +//================================================================================================== class PdmUiTextEditor : public PdmUiFieldEditorHandle { Q_OBJECT @@ -89,11 +107,10 @@ class PdmUiTextEditor : public PdmUiFieldEditorHandle virtual void configureAndUpdateUi(const QString& uiConfigName); protected slots: - void slotTextChanged(); - void slotSaveButtonClicked(); + void slotSetValueToField(); private: - QPointer m_textEdit; + QPointer m_textEdit; QPointer m_saveButton; QPointer m_label; diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiToolBarEditor.cpp b/Fwk/AppFwk/cafUserInterface/cafPdmUiToolBarEditor.cpp new file mode 100644 index 0000000000..5fff9907ab --- /dev/null +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiToolBarEditor.cpp @@ -0,0 +1,235 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2014 Ceetron Solutions AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + + +#include "cafPdmUiToolBarEditor.h" + +#include "cafPdmField.h" +#include "cafPdmUiComboBoxEditor.h" +#include "cafPdmUiFieldEditorHandle.h" +#include "cafPdmUiPushButtonEditor.h" +#include "cafPdmUiToolButtonEditor.h" + +#include +#include +#include + +#include +#include "cafPdmUiOrdering.h" +#include "cafPdmObjectHandle.h" +#include "cafPdmUiObjectHandle.h" +#include "cafPdmUiFieldHandle.h" + + +namespace caf +{ + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +PdmUiToolBarEditor::PdmUiToolBarEditor(const QString& title, QMainWindow* mainWindow) +{ + m_toolbar = new QToolBar(mainWindow); + m_toolbar->setObjectName(title); + m_toolbar->setWindowTitle(title); + + mainWindow->addToolBar(m_toolbar); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +PdmUiToolBarEditor::~PdmUiToolBarEditor() +{ + clear(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiToolBarEditor::configureAndUpdateUi(const QString& uiConfigName) +{ + for (size_t fIdx = 0; fIdx < m_fields.size(); fIdx++) + { + PdmFieldHandle* field = m_fields[fIdx]; + PdmUiFieldEditorHandle* fieldEditor = NULL; + + PdmUiOrdering config; + + caf::PdmUiObjectHandle* ownerUiObject = uiObj(field->ownerObject()); + if (ownerUiObject) + { + ownerUiObject->uiOrdering(uiConfigName, config); + } + + // Find or create FieldEditor + std::map::iterator it; + it = m_fieldViews.find(field->keyword()); + + if (it == m_fieldViews.end()) + { + /* + + //Code used to support other editor types than bool + //Not tested + + // If editor type is specified, find in factory + if (!field->uiEditorTypeName(uiConfigName).isEmpty()) + { + fieldEditor = caf::Factory::instance()->create(field->uiEditorTypeName(uiConfigName)); + } + else + { + // Find the default field editor + + QString editorTypeName = qStringTypeName(*field); + + // Handle a single value field with valueOptions: Make a combobox + + QVariant::Type qtType = field->uiValue().type(); + + if (field->uiValue().type() != QVariant::List) + { + bool useOptionsOnly = true; + QList options = field->valueOptions(&useOptionsOnly); + + if (!options.empty()) + { + editorTypeName = caf::PdmUiComboBoxEditor::uiEditorTypeName(); + } + } + + if (field->uiValue().type() == QVariant::Bool) + { + // Special handling of bool values into tool button editors + + editorTypeName = caf::PdmUiToolButtonEditor::uiEditorTypeName(); + } + + fieldEditor = caf::Factory::instance()->create(editorTypeName); + } + */ + + caf::PdmUiFieldHandle* uiFieldHandle = field->uiCapability(); + + QString editorTypeName; + if (uiFieldHandle && uiFieldHandle->uiValue().type() == QVariant::Bool) + { + // Special handling of bool values into tool button editors + + editorTypeName = caf::PdmUiToolButtonEditor::uiEditorTypeName(); + } + + fieldEditor = caf::Factory::instance()->create(editorTypeName); + + if (fieldEditor) + { + m_fieldViews[field->keyword()] = fieldEditor; + fieldEditor->createWidgets(NULL); + m_actions.push_back(m_toolbar->addWidget(fieldEditor->editorWidget())); + + fieldEditor->setField(uiFieldHandle); + fieldEditor->updateUi(uiConfigName); + } + + } + } + + assert(m_fields.size() == m_fieldViews.size()); + assert(static_cast(m_fields.size()) == m_actions.size()); + + for (size_t i = 0; i < m_fields.size(); i++) + { + caf::PdmFieldHandle* field = m_fields[i]; + + // Enabled state of a tool button is controlled by the QAction associated with a tool button + // Changing the state of a widget directly has no effect + // See Qt doc for QToolBar::insertWidget + QAction* action = m_actions[static_cast(i)]; + + caf::PdmUiFieldHandle* uiFieldHandle = field->uiCapability(); + if (uiFieldHandle) + { + action->setEnabled(!uiFieldHandle->isUiReadOnly(uiConfigName)); + } + + // TODO: Show/hide of tool bar items can be done by + // action->setVisible(!field->isUiHidden(uiConfigName)); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiToolBarEditor::setFields(std::vector& fields) +{ + clear(); + + for (size_t i = 0; i < fields.size(); i++) + { + caf::PdmUiFieldHandle* uiFieldHandle = fields[i]->uiCapability(); + + // Supports only bool fields + assert(uiFieldHandle->uiValue().type() == QVariant::Bool); + } + + m_fields = fields; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiToolBarEditor::clear() +{ + std::map::iterator it; + for (it = m_fieldViews.begin(); it != m_fieldViews.end(); ++it) + { + delete it->second; + } + + m_fieldViews.clear(); + + if (m_toolbar) + { + m_toolbar->clear(); + } + + m_actions.clear(); +} + + +} // end namespace caf diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiToolBarEditor.h b/Fwk/AppFwk/cafUserInterface/cafPdmUiToolBarEditor.h new file mode 100644 index 0000000000..d1547faf4b --- /dev/null +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiToolBarEditor.h @@ -0,0 +1,81 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2014 Ceetron Solutions AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + + +#pragma once + +#include "cafPdmUiEditorHandle.h" +#include "cafPdmUiFieldEditorHandle.h" + +#include + +#include + +class QToolBar; +class QMainWindow; + +namespace caf +{ + class PdmUiFieldEditorHandle; + class PdmUiItem; + class PdmFieldHandle; + + +class PdmUiToolBarEditor : public PdmUiEditorHandle +{ +public: + PdmUiToolBarEditor(const QString& title, QMainWindow* mainWindow); + ~PdmUiToolBarEditor(); + + void setFields(std::vector& fields); + +protected: + virtual void configureAndUpdateUi(const QString& uiConfigName); + +private: + void clear(); + +private: + QToolBar* m_toolbar; + + std::vector m_fields; + std::map m_fieldViews; + + QList m_actions; +}; + + +} // end namespace caf diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiToolButtonEditor.cpp b/Fwk/AppFwk/cafUserInterface/cafPdmUiToolButtonEditor.cpp new file mode 100644 index 0000000000..fc640bd691 --- /dev/null +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiToolButtonEditor.cpp @@ -0,0 +1,118 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2014 Ceetron Solutions AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + + +#include "cafPdmUiToolButtonEditor.h" + +#include "cafPdmUiFieldHandle.h" +#include "cafPdmFieldHandle.h" +#include "cafPdmObjectHandle.h" +#include "cafPdmUiObjectHandle.h" + + +namespace caf +{ + +CAF_PDM_UI_FIELD_EDITOR_SOURCE_INIT(PdmUiToolButtonEditor); + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiToolButtonEditor::configureAndUpdateUi(const QString& uiConfigName) +{ + assert(!m_toolButton.isNull()); + + QIcon ic = field()->uiIcon(uiConfigName); + if (!ic.isNull()) + { + m_toolButton->setIcon(ic); + } + + QString buttonText = field()->uiName(uiConfigName); + m_toolButton->setText(buttonText); + + m_toolButton->setEnabled(!field()->isUiReadOnly(uiConfigName)); + m_toolButton->setToolTip(field()->uiToolTip(uiConfigName)); + + PdmUiToolButtonEditorAttribute attributes; + + PdmUiObjectHandle* pdmUiOjectHandle = uiObj(field()->fieldHandle()->ownerObject()); + if (pdmUiOjectHandle) + { + pdmUiOjectHandle->editorAttribute(field()->fieldHandle(), uiConfigName, &attributes); + } + bool isCheckable = attributes.m_checkable; + m_toolButton->setCheckable(isCheckable); + + QVariant variantFieldValue = field()->uiValue(); + if (isCheckable) + { + m_toolButton->setChecked(field()->uiValue().toBool()); + } +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QWidget* PdmUiToolButtonEditor::createEditorWidget(QWidget * parent) +{ + m_toolButton = new QToolButton(parent); + connect(m_toolButton, SIGNAL(clicked(bool)), this, SLOT(slotClicked(bool))); + return m_toolButton; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QWidget* PdmUiToolButtonEditor::createLabelWidget(QWidget * parent) +{ + return NULL; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiToolButtonEditor::slotClicked(bool checked) +{ + QVariant v; + v = checked; + this->setValueToField(v); +} + + +} // end namespace caf diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiToolButtonEditor.h b/Fwk/AppFwk/cafUserInterface/cafPdmUiToolButtonEditor.h new file mode 100644 index 0000000000..6d86c9f8bc --- /dev/null +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiToolButtonEditor.h @@ -0,0 +1,84 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2014 Ceetron Solutions AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + + +#pragma once + +#include "cafPdmUiFieldEditorHandle.h" + +#include +#include +#include + +namespace caf +{ + +class PdmUiToolButtonEditorAttribute : public PdmUiEditorAttribute +{ +public: + PdmUiToolButtonEditorAttribute() + { + m_checkable = true; + } + +public: + bool m_checkable; +}; + + +class PdmUiToolButtonEditor : public PdmUiFieldEditorHandle +{ + Q_OBJECT + CAF_PDM_UI_FIELD_EDITOR_HEADER_INIT; + +public: + PdmUiToolButtonEditor() {} + virtual ~PdmUiToolButtonEditor() {} + +protected: + virtual QWidget* createEditorWidget(QWidget * parent); + virtual QWidget* createLabelWidget(QWidget * parent); + virtual void configureAndUpdateUi(const QString& uiConfigName); + +protected slots: + void slotClicked(bool checked); + +private: + QPointer m_toolButton; +}; + + +} // end namespace caf diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiTreeEditorHandle.cpp b/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeEditorHandle.cpp similarity index 98% rename from Fwk/AppFwk/cafProjectDataModel/cafPdmUiTreeEditorHandle.cpp rename to Fwk/AppFwk/cafUserInterface/cafPdmUiTreeEditorHandle.cpp index 943a9a0fbe..8e530450f7 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiTreeEditorHandle.cpp +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeEditorHandle.cpp @@ -59,8 +59,6 @@ QWidget* PdmUiTreeEditorHandle::getOrCreateWidget(QWidget* parent) //-------------------------------------------------------------------------------------------------- void PdmUiTreeEditorHandle::setPdmItemRoot(PdmUiItem* root) { - cleanupBeforeSettingPdmObject(); - this->bindToPdmItem(root); } diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiTreeEditorHandle.h b/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeEditorHandle.h similarity index 87% rename from Fwk/AppFwk/cafProjectDataModel/cafPdmUiTreeEditorHandle.h rename to Fwk/AppFwk/cafUserInterface/cafPdmUiTreeEditorHandle.h index e96a59c6b9..a001cc1b84 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiTreeEditorHandle.h +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeEditorHandle.h @@ -46,10 +46,10 @@ namespace caf { -class PdmObject; +class PdmObjectHandle; //================================================================================================== -/// Abstract class to handle editors for complete PdmObjects +/// //================================================================================================== class PdmUiTreeEditorHandle: public PdmUiEditorHandle @@ -63,10 +63,14 @@ class PdmUiTreeEditorHandle: public PdmUiEditorHandle void setPdmItemRoot(PdmUiItem* root); PdmUiItem* pdmItemRoot(); + void updateSubTree(PdmUiItem* root) { this->updateMySubTree(root); } protected: virtual QWidget* createWidget(QWidget* parent) = 0; - virtual void cleanupBeforeSettingPdmObject() {}; + + /// Supposed to update the representation of the tree from root and downwards, as gracefully as possible. + /// Will be called when the content of root might have been changed + virtual void updateMySubTree(PdmUiItem* root) = 0; protected: QPointer m_widget; diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeItemEditor.cpp b/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeItemEditor.cpp new file mode 100644 index 0000000000..011abca12a --- /dev/null +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeItemEditor.cpp @@ -0,0 +1,65 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2013 Ceetron AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + + +#include "cafPdmUiTreeItemEditor.h" +#include "cafPdmUiTreeEditorHandle.h" + +namespace caf +{ + + //-------------------------------------------------------------------------------------------------- + /// + //-------------------------------------------------------------------------------------------------- + PdmUiTreeItemEditor::PdmUiTreeItemEditor(PdmUiItem* uiItem) + { + m_treeViewEditor = NULL; + this->bindToPdmItem(uiItem); + } + + //-------------------------------------------------------------------------------------------------- + /// + //-------------------------------------------------------------------------------------------------- + void PdmUiTreeItemEditor::configureAndUpdateUi(const QString& uiConfigName) + { + if (m_treeViewEditor) + { + m_treeViewEditor->updateSubTree(this->pdmItem()); + } + } + +} //End of namespace caf + diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeItemEditor.h b/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeItemEditor.h new file mode 100644 index 0000000000..2055e79235 --- /dev/null +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeItemEditor.h @@ -0,0 +1,68 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2013 Ceetron AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + + +#pragma once +#include "cafPdmUiEditorHandle.h" + +namespace caf +{ + class PdmUiTreeEditorHandle; + +//================================================================================================== +/// A class that tells the treeViewEditor to update the sub tree of its associate PdmUiItem, when +/// needed. (Typically because of a direct call to updateConnectedEditors() ) +//================================================================================================== + +class PdmUiTreeItemEditor: public PdmUiEditorHandle +{ +public: + PdmUiTreeItemEditor(PdmUiItem* uiItem); + virtual ~PdmUiTreeItemEditor() {}; + + void setTreeViewEditor(PdmUiTreeEditorHandle* treeViewEditor) { m_treeViewEditor = treeViewEditor; } + +protected: // Interface to override: + + virtual void configureAndUpdateUi(const QString& uiConfigName); + +private: + PdmUiTreeEditorHandle* m_treeViewEditor; +}; + + +} // End of namespace caf + diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeView.cpp b/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeView.cpp index 47a3287770..ae7f872f48 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeView.cpp +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeView.cpp @@ -42,7 +42,7 @@ #include #include "cafPdmUiTreeViewEditor.h" - +#include namespace caf { @@ -55,9 +55,7 @@ PdmUiTreeView::PdmUiTreeView(QWidget* parent, Qt::WindowFlags f) : QWidget (parent, f) { m_layout = new QVBoxLayout(this); - m_layout->insertStretch(1, 1); m_layout->setContentsMargins(0, 0, 0, 0); - m_layout->setSpacing(0); setLayout(m_layout); @@ -66,7 +64,8 @@ PdmUiTreeView::PdmUiTreeView(QWidget* parent, Qt::WindowFlags f) QWidget * widget = m_treeViewEditor->getOrCreateWidget(this); this->m_layout->insertWidget(0, widget); - this->m_layout->setStretchFactor(widget, 10); + + connect(m_treeViewEditor, SIGNAL(selectionChanged()), SLOT(slotOnSelectionChanged())); } //-------------------------------------------------------------------------------------------------- @@ -94,9 +93,10 @@ void PdmUiTreeView::setUiConfigurationName(QString uiConfigName) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void PdmUiTreeView::setPdmObject(caf::PdmObject* object) +void PdmUiTreeView::setPdmItem(caf::PdmUiItem* object) { - m_treeViewEditor->setPdmObject(object); + m_treeViewEditor->setPdmItemRoot(object); + m_treeViewEditor->updateUi(m_uiConfigName); } //-------------------------------------------------------------------------------------------------- @@ -107,5 +107,101 @@ QTreeView* PdmUiTreeView::treeView() return m_treeViewEditor->treeView(); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiTreeView::selectedUiItems(std::vector& objects) +{ + m_treeViewEditor->selectedUiItems(objects); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiTreeView::slotOnSelectionChanged() +{ + emit selectionChanged(); + + std::vector objects; + m_treeViewEditor->selectedUiItems(objects); + PdmObjectHandle* objHandle = NULL; + + if (objects.size()) + { + PdmUiObjectHandle* uiObjH = dynamic_cast< PdmUiObjectHandle*>(objects[0]); + if (uiObjH) + { + objHandle = uiObjH->objectHandle(); + } + } + + emit selectedObjectChanged(objHandle); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiTreeView::enableDefaultContextMenu(bool enable) +{ + m_treeViewEditor->enableDefaultContextMenu(enable); +} + +//-------------------------------------------------------------------------------------------------- +/// Enables or disables automatic updating of the SelectionManager selection state based on +/// the selections in this tree view +//-------------------------------------------------------------------------------------------------- +void PdmUiTreeView::enableSelectionManagerUpdating(bool enable) +{ + m_treeViewEditor->enableSelectionManagerUpdating(enable); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiTreeView::selectAsCurrentItem(PdmUiItem* uiItem) +{ + m_treeViewEditor->selectAsCurrentItem(uiItem); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiTreeView::setExpanded(const PdmUiItem* uiItem, bool doExpand) const +{ + m_treeViewEditor->setExpanded(uiItem, doExpand); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +PdmUiItem* PdmUiTreeView::uiItemFromModelIndex(const QModelIndex& index) const +{ + return m_treeViewEditor->uiItemFromModelIndex(index); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QModelIndex PdmUiTreeView::findModelIndex(const PdmUiItem* object) const +{ + return m_treeViewEditor->findModelIndex(object); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiTreeView::setDragDropInterface(PdmUiDragDropInterface* dragDropInterface) +{ + m_treeViewEditor->setDragDropInterface(dragDropInterface); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiTreeView::enableAppendOfClassNameToUiItemText(bool enable) +{ + m_treeViewEditor->enableAppendOfClassNameToUiItemText(enable); +} + } //End of namespace caf diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeView.h b/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeView.h index 481f8452fe..62f2431028 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeView.h +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeView.h @@ -41,12 +41,17 @@ class QVBoxLayout; class QTreeView; +class QItemSelection; +class QMenu; +class QModelIndex; namespace caf { -class PdmObject; +class PdmUiItem; class PdmUiTreeViewEditor; +class PdmUiDragDropInterface; +class PdmObjectHandle; //================================================================================================== /// @@ -59,11 +64,35 @@ class PdmUiTreeView : public QWidget PdmUiTreeView(QWidget* parent = 0, Qt::WindowFlags f = 0); ~PdmUiTreeView(); + void enableDefaultContextMenu(bool enable); + void enableSelectionManagerUpdating(bool enable); // TODO: rename + void enableAppendOfClassNameToUiItemText(bool enable); + void setUiConfigurationName(QString uiConfigName); - void setPdmObject(caf::PdmObject* object); + void setPdmItem(caf::PdmUiItem* object); QTreeView* treeView(); + void selectedUiItems(std::vector& objects); // TODO: rename + void selectAsCurrentItem(PdmUiItem* uiItem); + void setExpanded(const PdmUiItem* uiItem, bool doExpand) const ; + + // QModelIndex access + // Use this translation only when it is inconvenient to traverse + // the Pdm model directly. + PdmUiItem* uiItemFromModelIndex(const QModelIndex& index) const; + QModelIndex findModelIndex(const PdmUiItem* object) const; + + void setDragDropInterface(PdmUiDragDropInterface* dragDropInterface); + +signals: + void selectionChanged(); + // Convenience signal for use with PdmUiPropertyView + void selectedObjectChanged(caf::PdmObjectHandle* object); // Signal/Slot system needs caf:: prefix in some cases + +private slots: + void slotOnSelectionChanged(); + private: PdmUiTreeViewEditor* m_treeViewEditor; QString m_uiConfigName; diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeViewEditor.cpp b/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeViewEditor.cpp index 3dea7a3ae2..0316cc511b 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeViewEditor.cpp +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeViewEditor.cpp @@ -34,60 +34,81 @@ // //################################################################################################## - #include "cafPdmUiTreeViewEditor.h" -#include "cafPdmObject.h" +#include "cafPdmChildArrayField.h" #include "cafPdmField.h" +#include "cafPdmObject.h" +#include "cafPdmUiCommandSystemProxy.h" +#include "cafPdmUiDragDropInterface.h" #include "cafPdmUiEditorHandle.h" -#include "cafUiTreeModelPdm.h" +#include "cafPdmUiTreeOrdering.h" +#include "cafPdmUiTreeViewModel.h" +#include "cafSelectionManager.h" -#include +#include +#include #include -#include +#include +#include #include +#include +#include +namespace caf +{ //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -class MySortFilterProxyModel : public QSortFilterProxyModel +class PdmUiTreeViewWidget : public QTreeView { public: - MySortFilterProxyModel(QObject *parent = 0) - : QSortFilterProxyModel(parent) + PdmUiTreeViewWidget(QWidget* parent = 0) : QTreeView(parent) {}; + virtual ~PdmUiTreeViewWidget() {}; + +protected: + virtual void dragMoveEvent(QDragMoveEvent* event) { + caf::PdmUiTreeViewModel* treeViewModel = dynamic_cast(model()); + if (treeViewModel && treeViewModel->dragDropInterface()) + { + treeViewModel->dragDropInterface()->onProposedDropActionUpdated(event->proposedAction()); + } + QTreeView::dragMoveEvent(event); } - void notifyModelChanged() + virtual void dragLeaveEvent(QDragLeaveEvent* event) { - QModelIndex startModelIdx = index(0,0); - QModelIndex endModelIdx = index(rowCount(startModelIdx), 0); + caf::PdmUiTreeViewModel* treeViewModel = dynamic_cast(model()); + if (treeViewModel && treeViewModel->dragDropInterface()) + { + treeViewModel->dragDropInterface()->onDragCanceled(); + } - emit dataChanged(startModelIdx, endModelIdx); + QTreeView::dragLeaveEvent(event); } }; - -namespace caf -{ - - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- PdmUiTreeViewEditor::PdmUiTreeViewEditor() { -} + m_useDefaultContextMenu = false; + m_updateSelectionManager = false; + m_appendClassNameToUiItemText = false; +} //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- PdmUiTreeViewEditor::~PdmUiTreeViewEditor() { + m_treeViewModel->setPdmItemRoot(NULL); } //-------------------------------------------------------------------------------------------------- @@ -100,106 +121,261 @@ QWidget* PdmUiTreeViewEditor::createWidget(QWidget* parent) m_layout->setContentsMargins(0, 0, 0, 0); m_mainWidget->setLayout(m_layout); - m_treeModelPdm = new caf::UiTreeModelPdm(m_mainWidget); - m_treeView = new QTreeView(m_mainWidget); + m_treeViewModel = new caf::PdmUiTreeViewModel(this); + m_treeView = new PdmUiTreeViewWidget(m_mainWidget); + m_treeView->setModel(m_treeViewModel); + m_treeView->installEventFilter(this); - m_proxyTreeModelPdm = new MySortFilterProxyModel(m_mainWidget); - m_proxyTreeModelPdm->setSourceModel(m_treeModelPdm); - m_treeView->setModel(m_proxyTreeModelPdm); + connect(treeView()->selectionModel(), SIGNAL(selectionChanged( const QItemSelection & , const QItemSelection & )), SLOT(slotOnSelectionChanged( const QItemSelection & , const QItemSelection & ))); - m_treeView->setSortingEnabled(true); - m_treeView->sortByColumn(1, Qt::AscendingOrder); - - m_layout->addWidget(m_treeView); - m_proxyEditor = new PdmUiProxyEditorHandle(this); - + updateContextMenuSignals(); + return m_mainWidget; } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void PdmUiTreeViewEditor::configureAndUpdateUi(const QString& uiConfigName) { - if (this->pdmObject()) + // If we have a real object, get its editor attributes (Column headers for now) + + if (this->pdmItemRoot() && dynamic_cast(this->pdmItemRoot())) + { + dynamic_cast(this->pdmItemRoot())->objectEditorAttribute(uiConfigName, &m_editorAttributes); + } + + m_treeViewModel->setColumnHeaders(m_editorAttributes.columnHeaders); + m_treeViewModel->setUiConfigName(uiConfigName); + m_treeViewModel->setPdmItemRoot(this->pdmItemRoot()); + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QTreeView* PdmUiTreeViewEditor::treeView() +{ + return m_treeView; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiTreeViewEditor::selectedUiItems(std::vector& objects) +{ + if (!this->treeView()) return; + + QModelIndexList idxList = this->treeView()->selectionModel()->selectedIndexes(); + + for (int i = 0; i < idxList.size(); i++) + { + caf::PdmUiItem* item = this->m_treeViewModel->uiItemFromModelIndex(idxList[i]); + if (item) + { + objects.push_back(item); + } + } +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiTreeViewEditor::updateMySubTree(PdmUiItem* uiItem) +{ + if (m_treeViewModel) { m_treeViewModel->updateSubTree(uiItem); } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiTreeViewEditor::enableDefaultContextMenu(bool enable) +{ + m_useDefaultContextMenu = enable; + + updateContextMenuSignals(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiTreeViewEditor::enableSelectionManagerUpdating(bool enable) +{ + m_updateSelectionManager = enable; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiTreeViewEditor::updateContextMenuSignals() +{ + if (!m_treeView) return; + + if (m_useDefaultContextMenu) { - this->pdmObject()->objectEditorAttribute(uiConfigName, &m_editorAttributes); + m_treeView->setContextMenuPolicy(Qt::CustomContextMenu); + connect(m_treeView, SIGNAL(customContextMenuRequested(QPoint)), SLOT(customMenuRequested(QPoint))); } + else + { + m_treeView->setContextMenuPolicy(Qt::DefaultContextMenu); + disconnect(m_treeView, 0, this, 0); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiTreeViewEditor::customMenuRequested(QPoint pos) +{ + // This seems a bit strange. Why ? + SelectionManager::instance()->setActiveChildArrayFieldHandle(this->currentChildArrayFieldHandle()); + + QMenu menu; + caf::PdmUiCommandSystemProxy::instance()->populateMenuWithDefaultCommands("PdmUiTreeViewEditor", &menu); - if (!m_treeModelPdm->treeItemRoot() || m_treeModelPdm->treeItemRoot()->dataObject() != this->pdmObject()) + if (menu.actions().size() > 0) { - caf::PdmUiTreeItem* treeItemRoot = caf::UiTreeItemBuilderPdm::buildViewItems(NULL, -1, this->pdmObject()); - m_treeModelPdm->setTreeItemRoot(treeItemRoot); + // Qt doc: QAbstractScrollArea and its subclasses that map the context menu event to coordinates of the viewport(). + QPoint globalPos = m_treeView->viewport()->mapToGlobal(pos); + + menu.exec(globalPos); } +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +PdmChildArrayFieldHandle* PdmUiTreeViewEditor::currentChildArrayFieldHandle() +{ + PdmUiItem* currentSelectedItem = SelectionManager::instance()->selectedItem(SelectionManager::CURRENT); - // Update tree model, and set the proxy editor for all Pdm child objects - if (m_treeModelPdm->treeItemRoot() && m_treeModelPdm->treeItemRoot()->dataObject()) + PdmUiFieldHandle* uiFieldHandle = dynamic_cast(currentSelectedItem); + if (uiFieldHandle) { - m_treeModelPdm->updateUiSubTree(m_treeModelPdm->treeItemRoot()->dataObject()); + PdmFieldHandle* fieldHandle = uiFieldHandle->fieldHandle(); - std::vector children; - childObjects(m_treeModelPdm->treeItemRoot()->dataObject(), children); + if (dynamic_cast(fieldHandle)) + { + return dynamic_cast(fieldHandle); + } + } + + PdmObjectHandle* pdmObject = dynamic_cast(currentSelectedItem); + if (pdmObject) + { + PdmChildArrayFieldHandle* parentChildArray = dynamic_cast(pdmObject->parentField()); - size_t cIdx; - for (cIdx = 0; cIdx < children.size(); ++cIdx) + if (parentChildArray) { - addEditorRecursively(children[cIdx], m_proxyEditor); + return parentChildArray; } } - m_treeModelPdm->setColumnHeaders(m_editorAttributes.columnHeaders); + return NULL; +} - // Notify all connected views that the complete model is updated - m_treeModelPdm->notifyModelChanged(); - m_proxyTreeModelPdm->notifyModelChanged(); +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiTreeViewEditor::selectAsCurrentItem(PdmUiItem* uiItem) +{ + QModelIndex index = m_treeViewModel->findModelIndex(uiItem); + m_treeView->setCurrentIndex(index); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void PdmUiTreeViewEditor::addEditorRecursively(PdmObject* pdmObject, PdmUiEditorHandle* editorHandle) +void PdmUiTreeViewEditor::slotOnSelectionChanged(const QItemSelection & selected, const QItemSelection & deselected) { - if (!pdmObject) return; + this->updateSelectionManager(); - std::vector children; - childObjects(pdmObject, children); + emit selectionChanged(); +} - size_t cIdx; - for (cIdx = 0; cIdx < children.size(); ++cIdx) - { - addEditorRecursively(children[cIdx], editorHandle); - } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiTreeViewEditor::setExpanded(const PdmUiItem* uiItem, bool doExpand) const +{ + QModelIndex index = m_treeViewModel->findModelIndex(uiItem); + m_treeView->setExpanded(index, doExpand); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +PdmUiItem* PdmUiTreeViewEditor::uiItemFromModelIndex(const QModelIndex& index) const +{ + return m_treeViewModel->uiItemFromModelIndex(index); +} - pdmObject->addFieldEditor(editorHandle); +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QModelIndex PdmUiTreeViewEditor::findModelIndex(const PdmUiItem* object) const +{ + return m_treeViewModel->findModelIndex(object); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiTreeViewEditor::setDragDropInterface(PdmUiDragDropInterface* dragDropInterface) +{ + m_treeViewModel->setDragDropInterface(dragDropInterface); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void PdmUiTreeViewEditor::childObjects(PdmObject* pdmObject, std::vector& children) +bool PdmUiTreeViewEditor::eventFilter(QObject *obj, QEvent *event) { - if (!pdmObject) return; + if (event->type() == QEvent::FocusIn) + { + this->updateSelectionManager(); + } - std::vector fields; - pdmObject->fields(fields); + // standard event processing + return QObject::eventFilter(obj, event); +} - size_t fIdx; - for (fIdx = 0; fIdx < fields.size(); ++fIdx) + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiTreeViewEditor::updateSelectionManager() +{ + if (m_updateSelectionManager) { - if (fields[fIdx]) fields[fIdx]->childObjects(&children); + std::vector items; + this->selectedUiItems(items); + + SelectionManager::instance()->setSelectedItems(items); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QTreeView* PdmUiTreeViewEditor::treeView() +void PdmUiTreeViewEditor::enableAppendOfClassNameToUiItemText(bool enable) { - return m_treeView; + m_appendClassNameToUiItemText = enable; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool PdmUiTreeViewEditor::isAppendOfClassNameToUiItemTextEnabled() +{ + return m_appendClassNameToUiItemText; +} } // end namespace caf diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeViewEditor.h b/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeViewEditor.h index 04ae2f44f9..6ee6b37e32 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeViewEditor.h +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeViewEditor.h @@ -37,25 +37,31 @@ #pragma once -#include "cafPdmUiObjectEditorHandle.h" +#include "cafPdmUiTreeEditorHandle.h" #include "cafPdmUiFieldEditorHandle.h" +#include "cafPdmUiTreeViewModel.h" -#include +#include #include +#include +#include +#include + class MySortFilterProxyModel; class QGridLayout; -class QVBoxLayout; +class QMenu; class QTreeView; +class QVBoxLayout; namespace caf { -class PdmUiFieldEditorHandle; -class PdmUiItem; -class UiTreeModelPdm; -class PdmUiProxyEditorHandle; +class PdmUiItem; +class PdmUiTreeViewModel; +class PdmChildArrayFieldHandle; +class PdmUiDragDropInterface; //-------------------------------------------------------------------------------------------------- /// @@ -71,36 +77,70 @@ class PdmUiTreeViewEditorAttribute : public PdmUiEditorAttribute QStringList columnHeaders; }; - -class PdmUiTreeViewEditor : public PdmUiObjectEditorHandle +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +class PdmUiTreeViewEditor : public PdmUiTreeEditorHandle { + Q_OBJECT public: PdmUiTreeViewEditor(); ~PdmUiTreeViewEditor(); + void enableDefaultContextMenu(bool enable); + void enableSelectionManagerUpdating(bool enable); + + void enableAppendOfClassNameToUiItemText(bool enable); + bool isAppendOfClassNameToUiItemTextEnabled(); + QTreeView* treeView(); + void selectAsCurrentItem(PdmUiItem* uiItem); + void selectedUiItems(std::vector& objects); + void setExpanded(const PdmUiItem* uiItem, bool doExpand) const; + + PdmUiItem* uiItemFromModelIndex(const QModelIndex& index) const; + QModelIndex findModelIndex(const PdmUiItem* object) const; + + QWidget* createWidget(QWidget* parent); + + void setDragDropInterface(PdmUiDragDropInterface* dragDropInterface); + +signals: + void selectionChanged(); + protected: - virtual QWidget* createWidget(QWidget* parent); virtual void configureAndUpdateUi(const QString& uiConfigName); + virtual void updateMySubTree(PdmUiItem* uiItem); + + void updateContextMenuSignals(); + +private slots: + void customMenuRequested(QPoint pos); + void slotOnSelectionChanged(const QItemSelection & selected, const QItemSelection & deselected); + private: - void addEditorRecursively(PdmObject* pdmObject, PdmUiEditorHandle* editorHandle); + void uiItemsFromModelIndexList(const QModelIndexList& modelIndexList, std::vector& objects); + + PdmChildArrayFieldHandle* currentChildArrayFieldHandle(); + + void updateSelectionManager(); - static void childObjects(PdmObject* pdmObject, std::vector& children); + virtual bool eventFilter(QObject *obj, QEvent *event); private: - QPointer m_mainWidget; - QVBoxLayout* m_layout; + QPointer m_mainWidget; + QVBoxLayout* m_layout; - QTreeView* m_treeView; - UiTreeModelPdm* m_treeModelPdm; - MySortFilterProxyModel* m_proxyTreeModelPdm; + QTreeView* m_treeView; + PdmUiTreeViewModel* m_treeViewModel; - // Forward update events to the tree view editor connected to Pdm root object using a proxy editor - PdmUiProxyEditorHandle* m_proxyEditor; + PdmUiTreeViewEditorAttribute m_editorAttributes; - PdmUiTreeViewEditorAttribute m_editorAttributes; + bool m_useDefaultContextMenu; + bool m_updateSelectionManager; + bool m_appendClassNameToUiItemText; }; diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeViewModel.cpp b/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeViewModel.cpp index 223c98d105..e38a6bdf61 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeViewModel.cpp +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeViewModel.cpp @@ -36,11 +36,16 @@ #include "cafPdmUiTreeViewModel.h" + #include "cafPdmField.h" #include "cafPdmObject.h" +#include "cafPdmUiDragDropInterface.h" +#include "cafPdmUiTreeItemEditor.h" #include "cafPdmUiTreeOrdering.h" +#include "cafPdmUiTreeViewEditor.h" - +#include +#include namespace caf { @@ -48,47 +53,417 @@ namespace caf //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -PdmUiTreeViewModel::PdmUiTreeViewModel(QObject* parent) +PdmUiTreeViewModel::PdmUiTreeViewModel(PdmUiTreeViewEditor* treeViewEditor) { - m_treeItemRoot = NULL; + m_treeOrderingRoot = NULL; + m_dragDropInterface = NULL; + + m_treeViewEditor = treeViewEditor; } +//-------------------------------------------------------------------------------------------------- +/// Will populate the tree with the contents of the Pdm data structure rooted at rootItem. +/// Will not show the rootItem itself, only the children and downwards +//-------------------------------------------------------------------------------------------------- +void PdmUiTreeViewModel::setPdmItemRoot(PdmUiItem* rootItem) +{ + // Check if we are already watching this root + if (m_treeOrderingRoot && m_treeOrderingRoot->activeItem() == rootItem) + { + this->updateSubTree(rootItem); + return; + } + + PdmUiTreeOrdering* newRoot = NULL; + PdmUiFieldHandle* field = dynamic_cast (rootItem); + + if (field) + { + newRoot = new PdmUiTreeOrdering(field->fieldHandle()); + PdmUiObjectHandle::expandUiTree(newRoot, m_uiConfigName); + } + else + { + PdmUiObjectHandle * obj = dynamic_cast (rootItem); + if (obj) + { + newRoot = obj->uiTreeOrdering(m_uiConfigName); + } + } + + assert( newRoot || rootItem == NULL ); // Only fields, objects or NULL is allowed. + + //if (newRoot) newRoot->debugDump(0); + + this->resetTree(newRoot); +} //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void PdmUiTreeViewModel::setTreeItemRoot(PdmUiTreeItem* root) +void PdmUiTreeViewModel::resetTree(PdmUiTreeOrdering* newRoot) { beginResetModel(); - if (m_treeItemRoot) + if (m_treeOrderingRoot) { - delete m_treeItemRoot; + delete m_treeOrderingRoot; } - m_treeItemRoot = root; + m_treeOrderingRoot = newRoot; + + updateEditorsForSubTree(m_treeOrderingRoot); + endResetModel(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QModelIndex PdmUiTreeViewModel::index(int row, int column, const QModelIndex &parentIndex /*= QModelIndex( ) */) const +void PdmUiTreeViewModel::setColumnHeaders(const QStringList& columnHeaders) +{ + m_columnHeaders = columnHeaders; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiTreeViewModel::emitDataChanged(const QModelIndex& index) +{ + emit dataChanged(index, index); +} + +//-------------------------------------------------------------------------------------------------- +/// Refreshes the UI-tree below the supplied root PdmUiItem +//-------------------------------------------------------------------------------------------------- +void PdmUiTreeViewModel::updateSubTree(PdmUiItem* pdmRoot) +{ + // Build the new "Correct" Tree + + PdmUiTreeOrdering* newTreeRootTmp = NULL; + PdmUiFieldHandle* field = dynamic_cast (pdmRoot); + if (field) + { + newTreeRootTmp = new PdmUiTreeOrdering(field->fieldHandle()); + } + else + { + PdmUiObjectHandle* obj = dynamic_cast (pdmRoot); + if (obj) + { + newTreeRootTmp = new PdmUiTreeOrdering(obj->objectHandle()); + } + } + + PdmUiObjectHandle::expandUiTree(newTreeRootTmp, m_uiConfigName); + +#if CAF_PDM_TREE_VIEW_DEBUG_PRINT + std::cout << std::endl << "New Stuff: " << std::endl ; + newTreeRootTmp->debugDump(0); +#endif + + // Find the corresponding entry for "root" in the existing Ui tree + + QModelIndex existingSubTreeRootModIdx = findModelIndex(pdmRoot); + + PdmUiTreeOrdering* existingSubTreeRoot = NULL; + if (existingSubTreeRootModIdx.isValid()) + { + existingSubTreeRoot = treeItemFromIndex(existingSubTreeRootModIdx); + } + else + { + existingSubTreeRoot = m_treeOrderingRoot; + } + +#if CAF_PDM_TREE_VIEW_DEBUG_PRINT + std::cout << std::endl << "Old :"<< std::endl ; + existingSubTreeRoot->debugDump(0); +#endif + + updateSubTreeRecursive(existingSubTreeRootModIdx, existingSubTreeRoot, newTreeRootTmp); + + delete newTreeRootTmp; + + updateEditorsForSubTree(existingSubTreeRoot); + +#if CAF_PDM_TREE_VIEW_DEBUG_PRINT + std::cout << std::endl << "Result :"<< std::endl ; + existingSubTreeRoot->debugDump(0); +#endif +} + +class RecursiveUpdateData +{ +public: + RecursiveUpdateData(QModelIndex mi, PdmUiTreeOrdering* existingChild, PdmUiTreeOrdering* sourceChild) + : m_modelIndex(mi), + m_existingChild(existingChild), + m_sourceChild(sourceChild) + { + }; + + QModelIndex m_modelIndex; + PdmUiTreeOrdering* m_existingChild; + PdmUiTreeOrdering* m_sourceChild; +}; + +//-------------------------------------------------------------------------------------------------- +/// Makes the existingSubTreeRoot tree become identical to the tree in sourceSubTreeRoot, +/// calling begin..() end..() to make the UI update accordingly. +/// This assumes that all the items have a pointer an unique PdmObject +//-------------------------------------------------------------------------------------------------- +void PdmUiTreeViewModel::updateSubTreeRecursive(const QModelIndex& existingSubTreeRootModIdx, PdmUiTreeOrdering* existingSubTreeRoot, PdmUiTreeOrdering* sourceSubTreeRoot) +{ + // Build map for source items + std::map sourceTreeMap; + for (int i = 0; i < sourceSubTreeRoot->childCount() ; ++i) + { + PdmUiTreeOrdering* child = sourceSubTreeRoot->child(i); + + if (child && child->activeItem()) + { + sourceTreeMap[child->activeItem()] = i; + } + } + + // Detect items to be deleted from existing tree + std::vector indicesToRemoveFromExisting; + for (int i = 0; i < existingSubTreeRoot->childCount() ; ++i) + { + PdmUiTreeOrdering* child = existingSubTreeRoot->child(i); + + std::map::iterator it = sourceTreeMap.find(child->activeItem()); + if (it == sourceTreeMap.end()) + { + indicesToRemoveFromExisting.push_back(i); + } + } + + // Delete items with largest index first from existing + for (std::vector::reverse_iterator it = indicesToRemoveFromExisting.rbegin(); it != indicesToRemoveFromExisting.rend(); it++) + { + this->beginRemoveRows(existingSubTreeRootModIdx, *it, *it); + existingSubTreeRoot->removeChildren(*it, 1); + this->endRemoveRows(); + } + + // Build map for existing items without the deleted items + std::map existingTreeMap; + for (int i = 0; i < existingSubTreeRoot->childCount() ; ++i) + { + PdmUiTreeOrdering* child = existingSubTreeRoot->child(i); + + if (child && child->activeItem()) + { + existingTreeMap[child->activeItem()] = i; + } + } + + // Check if there are any changes between existing and source + // If no changes, update the subtree recursively + bool anyChanges = false; + if (existingSubTreeRoot->childCount() == sourceSubTreeRoot->childCount()) + { + for (int i = 0; i < existingSubTreeRoot->childCount(); ++i) + { + if (existingSubTreeRoot->child(i)->activeItem() != sourceSubTreeRoot->child(i)->activeItem()) + { + anyChanges = true; + break; + } + } + } + else + { + anyChanges = true; + } + + if (!anyChanges) + { + // Notify Qt that the toggle/name/icon etc might have been changed + emitDataChanged(existingSubTreeRootModIdx); + + // No changes to list of children at this level, call update on all children + for (int i = 0; i < existingSubTreeRoot->childCount(); ++i) + { + updateSubTreeRecursive( index(i, 0, existingSubTreeRootModIdx), existingSubTreeRoot->child(i), sourceSubTreeRoot->child(i)); + } + } + else + { + std::vector recursiveUpdateData; + std::vector newMergedOrdering; + + emit layoutAboutToBeChanged(); + { + // Detect items to be moved from source to existing + // Merge items from existing and source into newMergedOrdering using order in sourceSubTreeRoot + std::vector indicesToRemoveFromSource; + for (int i = 0; i < sourceSubTreeRoot->childCount() ; ++i) + { + PdmUiTreeOrdering* sourceChild = sourceSubTreeRoot->child(i); + std::map::iterator it = existingTreeMap.find(sourceChild->activeItem()); + if (it != existingTreeMap.end()) + { + newMergedOrdering.push_back(existingSubTreeRoot->child(it->second)); + + recursiveUpdateData.push_back(RecursiveUpdateData(index(static_cast(newMergedOrdering.size() - 1), 0, existingSubTreeRootModIdx), existingSubTreeRoot->child(it->second), sourceChild)); + } + else + { + newMergedOrdering.push_back(sourceChild); + + indicesToRemoveFromSource.push_back(i); + } + } + + // Delete new items from source because they have been moved into newMergedOrdering + for (std::vector::reverse_iterator it = indicesToRemoveFromSource.rbegin(); it != indicesToRemoveFromSource.rend(); it++) + { + // Use the removeChildrenNoDelete() to remove the pointer from the list without deleting the pointer + sourceSubTreeRoot->removeChildrenNoDelete(*it, 1); + } + + // Delete all items from existingSubTreeRoot, as the complete list is present in newMergedOrdering + existingSubTreeRoot->removeChildrenNoDelete(0, existingSubTreeRoot->childCount()); + + // First, reorder all items in existing tree, as this operation is valid when later emitting the signal layoutChanged() + // Insert of new items before issuing this signal causes the tree items below the inserted item to collapse + for (size_t i = 0; i < newMergedOrdering.size(); i++) + { + if (existingTreeMap.find(newMergedOrdering[i]->activeItem()) != existingTreeMap.end()) + { + existingSubTreeRoot->appendChild(newMergedOrdering[i]); + } + } + } + + emit layoutChanged(); + + // Insert new items into existingSubTreeRoot + for (size_t i = 0; i < newMergedOrdering.size(); i++) + { + if (existingTreeMap.find(newMergedOrdering[i]->activeItem()) == existingTreeMap.end()) + { + this->beginInsertRows(existingSubTreeRootModIdx, static_cast(i), static_cast(i)); + existingSubTreeRoot->insertChild(static_cast(i), newMergedOrdering[i]); + this->endInsertRows(); + } + } + + for (size_t i = 0; i < recursiveUpdateData.size(); i++) + { + updateSubTreeRecursive(recursiveUpdateData[i].m_modelIndex, recursiveUpdateData[i].m_existingChild, recursiveUpdateData[i].m_sourceChild); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiTreeViewModel::updateEditorsForSubTree(PdmUiTreeOrdering* root) +{ + if (!root) return; + + if (!root->editor()) + { + PdmUiTreeItemEditor* treeItemEditor = new PdmUiTreeItemEditor(root->activeItem()); + root->setEditor(treeItemEditor); + assert(root->editor()); + } + + PdmUiTreeItemEditor* treeItemEditor = dynamic_cast(root->editor()); + if (treeItemEditor) + { + treeItemEditor->setTreeViewEditor(m_treeViewEditor); + } + + for (int i = 0; i < root->childCount(); ++i) + { + updateEditorsForSubTree(root->child(i)); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +PdmUiTreeOrdering* caf::PdmUiTreeViewModel::treeItemFromIndex(const QModelIndex& index) const +{ + if (!index.isValid()) + { + return m_treeOrderingRoot; + } + + assert(index.internalPointer()); + + PdmUiTreeOrdering* treeItem = static_cast(index.internalPointer()); + + return treeItem; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QModelIndex caf::PdmUiTreeViewModel::findModelIndex( const PdmUiItem * object) const +{ + QModelIndex foundIndex; + int numRows = rowCount(QModelIndex()); + int r = 0; + while (r < numRows && !foundIndex.isValid()) + { + foundIndex = findModelIndexRecursive(index(r, 0, QModelIndex()), object); + ++r; + } + return foundIndex; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QModelIndex caf::PdmUiTreeViewModel::findModelIndexRecursive(const QModelIndex& currentIndex, const PdmUiItem * pdmItem) const { -// if (!m_treeItemRoot) -// return QModelIndex(); + if (currentIndex.internalPointer()) + { + PdmUiTreeOrdering* treeItem = static_cast(currentIndex.internalPointer()); + if (treeItem->activeItem() == pdmItem) return currentIndex; + } + + int row; + for (row = 0; row < rowCount(currentIndex); ++row) + { + QModelIndex foundIndex = findModelIndexRecursive(index(row, 0, currentIndex), pdmItem); + if (foundIndex.isValid()) return foundIndex; + } + return QModelIndex(); +} - if (!hasIndex(row, column, parentIndex)) + + +//-------------------------------------------------------------------------------------------------- +/// An invalid parent index is implicitly meaning the root item, and not "above" root, since +/// we are not showing the root item itself +//-------------------------------------------------------------------------------------------------- +QModelIndex PdmUiTreeViewModel::index(int row, int column, const QModelIndex &parentIndex ) const +{ + if (!m_treeOrderingRoot) return QModelIndex(); - PdmUiTreeItem* parentItem = NULL; + PdmUiTreeOrdering* parentItem = NULL; if (!parentIndex.isValid()) - parentItem = m_treeItemRoot; + parentItem = m_treeOrderingRoot; else - parentItem = static_cast(parentIndex.internalPointer()); + parentItem = static_cast(parentIndex.internalPointer()); + + assert(parentItem); - PdmUiTreeItem* childItem = parentItem->child(row); + if (parentItem->childCount() <= row) + { + return QModelIndex(); + } + + PdmUiTreeOrdering* childItem = parentItem->child(row); if (childItem) return createIndex(row, column, childItem); else @@ -100,37 +475,31 @@ QModelIndex PdmUiTreeViewModel::index(int row, int column, const QModelIndex &pa //-------------------------------------------------------------------------------------------------- QModelIndex PdmUiTreeViewModel::parent(const QModelIndex &childIndex) const { -// if (!m_treeItemRoot) return QModelIndex(); - if (!childIndex.isValid()) return QModelIndex(); - PdmUiTreeItem* childItem = static_cast(childIndex.internalPointer()); + PdmUiTreeOrdering* childItem = static_cast(childIndex.internalPointer()); if (!childItem) return QModelIndex(); - PdmUiTreeItem* parentItem = childItem->parent(); + PdmUiTreeOrdering* parentItem = childItem->parent(); if (!parentItem) return QModelIndex(); - if (parentItem == m_treeItemRoot) return QModelIndex(); + if (parentItem == m_treeOrderingRoot) return QModelIndex(); - return createIndex(parentItem->row(), 0, parentItem); + return createIndex(parentItem->indexInParent(), 0, parentItem); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -int PdmUiTreeViewModel::rowCount(const QModelIndex &parentIndex /*= QModelIndex( ) */) const +int PdmUiTreeViewModel::rowCount(const QModelIndex &parentIndex ) const { - if (!m_treeItemRoot) + if (!m_treeOrderingRoot) return 0; if (parentIndex.column() > 0) return 0; - PdmUiTreeItem* parentItem; - if (!parentIndex.isValid()) - parentItem = m_treeItemRoot; - else - parentItem = PdmUiTreeViewModel::getTreeItemFromIndex(parentIndex); + PdmUiTreeOrdering* parentItem = this->treeItemFromIndex(parentIndex); return parentItem->childCount(); } @@ -138,147 +507,158 @@ int PdmUiTreeViewModel::rowCount(const QModelIndex &parentIndex /*= QModelIndex( //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -int PdmUiTreeViewModel::columnCount(const QModelIndex &parentIndex /*= QModelIndex( ) */) const +int PdmUiTreeViewModel::columnCount(const QModelIndex &parentIndex ) const { - if (!m_treeItemRoot) + if (!m_treeOrderingRoot) return 0; - if (parentIndex.isValid()) - { - PdmUiTreeItem* parentItem = PdmUiTreeViewModel::getTreeItemFromIndex(parentIndex); - if (parentItem) - { - return parentItem->columnCount(); - } - else - { - return 0; - } - } - else - return m_treeItemRoot->columnCount(); + return 1; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QVariant PdmUiTreeViewModel::data(const QModelIndex &index, int role /*= Qt::DisplayRole */) const +QVariant PdmUiTreeViewModel::data(const QModelIndex &index, int role ) const { if (!index.isValid()) + { + return QVariant(); + } + + PdmUiTreeOrdering* uitreeOrdering = static_cast(index.internalPointer()); + if (!uitreeOrdering) + { return QVariant(); + } - PdmUiTreeOrdering* uitreeOrdering = static_cast(index.internalPointer()); - if (!uitreeOrdering) - { - return QVariant(); - } - PdmFieldHandle* pdmField = uitreeOrdering->field(); - PdmObject* pdmObj = uitreeOrdering->object(); - - if (role == Qt::DisplayRole || role == Qt::EditRole) - { - if (pdmField && !pdmField->uiName().isEmpty()) - { - return pdmField->uiName(); - } - else if (pdmObj) - { - if (pdmObj->userDescriptionField()) - return pdmObj->userDescriptionField()->uiValue(); - else - return pdmObj->uiName(); - } - else if (uitreeOrdering->uiItem()) - { - return uitreeOrdering->uiItem()->uiName(); - } - else - { - // Should not get here - assert(0); - } - } - else if (role == Qt::DecorationRole) - { - if (pdmField && !pdmField->uiIcon().isNull()) - { - return pdmField->uiIcon(); - } - else if (pdmObj) - { - return pdmObj->uiIcon(); - } - else if (uitreeOrdering->uiItem()) - { - return uitreeOrdering->uiItem()->uiIcon(); - } - else - { - // Should not get here - assert(0); - } - } - else if (role == Qt::ToolTipRole) - { - if (pdmField && !pdmField->uiToolTip().isEmpty()) - return pdmField->uiToolTip(); - else if (pdmObj) - { - return pdmObj->uiToolTip(); - } - else if (uitreeOrdering->uiItem()) - { - return uitreeOrdering->uiItem()->uiToolTip(); - } - else - { - // Should not get here - assert(0); - } - } - else if (role == Qt::WhatsThisRole) - { - if (pdmField && !pdmField->uiWhatsThis().isEmpty()) - return pdmField->uiWhatsThis(); - else if (pdmObj) - { - return pdmObj->uiWhatsThis(); - } - else if (uitreeOrdering->uiItem()) - { - return uitreeOrdering->uiItem()->uiWhatsThis(); - } - else - { - // Should not get here - assert(0); - } - } - else if (role == Qt::CheckStateRole) - { - if (pdmObj && pdmObj->objectToggleField()) - { - bool isToggledOn = pdmObj->objectToggleField()->uiValue().toBool(); - if (isToggledOn) - { - return Qt::Checked; - } - else - { - return Qt::Unchecked; - } - } - } + bool isObjRep = uitreeOrdering->isRepresentingObject(); + bool isFieldRep = uitreeOrdering->isRepresentingField(); + bool isDisplayOnly = uitreeOrdering->isDisplayItemOnly(); - return QVariant(); -} -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void PdmUiTreeViewModel::emitDataChanged(const QModelIndex& index) -{ - emit dataChanged(index, index); + if (role == Qt::DisplayRole && !uitreeOrdering->isValid()) + { + QString str; + +#ifdef DEBUG + str = "Invalid uiordering"; +#endif + + return QVariant(str); + } + + if (role == Qt::DisplayRole || role == Qt::EditRole) + { + if (isObjRep) + { + PdmUiObjectHandle* pdmUiObject = uiObj(uitreeOrdering->object()); + if (pdmUiObject) + { + QVariant v; + if (pdmUiObject->userDescriptionField()) + { + caf::PdmUiFieldHandle* uiFieldHandle = pdmUiObject->userDescriptionField()->uiCapability(); + if (uiFieldHandle) + { + v = uiFieldHandle->uiValue(); + } + } + else + { + v = pdmUiObject->uiName(); + } + + QString txt = v.toString(); + + if (m_treeViewEditor->isAppendOfClassNameToUiItemTextEnabled()) + { + PdmObjectHandle* pdmObjHandle = pdmUiObject->objectHandle(); + if (pdmObjHandle) + { + txt += " - "; + txt += typeid(*pdmObjHandle).name(); + } + } + + return txt; + } + else + { + return QVariant(); + } + } + + if (uitreeOrdering->activeItem()) + { + return uitreeOrdering->activeItem()->uiName(); + } + else + { + return QVariant(); + } + } + else if (role == Qt::DecorationRole) + { + if (uitreeOrdering->activeItem()) + { + return uitreeOrdering->activeItem()->uiIcon(); + } + else + { + return QVariant(); + } + } + else if (role == Qt::ToolTipRole) + { + if (uitreeOrdering->activeItem()) + { + return uitreeOrdering->activeItem()->uiToolTip(); + } + else + { + return QVariant(); + } + } + else if (role == Qt::WhatsThisRole) + { + if (uitreeOrdering->activeItem()) + { + return uitreeOrdering->activeItem()->uiWhatsThis(); + } + else + { + return QVariant(); + } + } + else if (role == Qt::CheckStateRole) + { + if (isObjRep) + { + PdmUiObjectHandle* pdmUiObj = uiObj(uitreeOrdering->object()); + if (pdmUiObj && pdmUiObj->objectToggleField()) + { + caf::PdmUiFieldHandle* uiFieldHandle = pdmUiObj->objectToggleField()->uiCapability(); + if (uiFieldHandle) + { + bool isToggledOn = uiFieldHandle->uiValue().toBool(); + if (isToggledOn) + { + return Qt::Checked; + } + else + { + return Qt::Unchecked; + } + } + else + { + return QVariant(); + } + } + } + } + + return QVariant(); } //-------------------------------------------------------------------------------------------------- @@ -290,33 +670,39 @@ bool PdmUiTreeViewModel::setData(const QModelIndex &index, const QVariant &value { return false; } - - PdmUiTreeItem* treeItem = PdmUiTreeViewModel::getTreeItemFromIndex(index); + + PdmUiTreeOrdering* treeItem = PdmUiTreeViewModel::treeItemFromIndex(index); assert(treeItem); - - PdmObject* obj = treeItem->dataObject()->object(); - if (!obj) - { - return false; - } - - if (role == Qt::EditRole && obj->userDescriptionField()) - { - obj->userDescriptionField()->setValueFromUi(value); - emitDataChanged(index); - - return true; - } - else if (role == Qt::CheckStateRole && obj->objectToggleField()) + if (!treeItem->isRepresentingObject()) return false; + + PdmUiObjectHandle* uiObject = uiObj(treeItem->object()); + if (uiObject) { - bool toggleOn = (value == Qt::Checked); - - obj->objectToggleField()->setValueFromUi(toggleOn); + if (role == Qt::EditRole && uiObject->userDescriptionField()) + { + PdmUiFieldHandle* userDescriptionUiField = uiObject->userDescriptionField()->uiCapability(); + if (userDescriptionUiField) + { + userDescriptionUiField->setValueFromUi(value); + } + + return true; + } + else if ( role == Qt::CheckStateRole && + uiObject->objectToggleField() && + !uiObject->objectToggleField()->uiCapability()->isUiReadOnly(m_uiConfigName)) + { + bool toggleOn = (value == Qt::Checked); - emitDataChanged(index); + PdmUiFieldHandle* toggleUiField = uiObject->objectToggleField()->uiCapability(); + if (toggleUiField) + { + toggleUiField->setValueFromUi(value); + } - return true; + return true; + } } return false; @@ -329,36 +715,44 @@ bool PdmUiTreeViewModel::setData(const QModelIndex &index, const QVariant &value Qt::ItemFlags PdmUiTreeViewModel::flags(const QModelIndex &index) const { if (!index.isValid()) + { return Qt::ItemIsEnabled; + } Qt::ItemFlags flagMask = QAbstractItemModel::flags(index); - PdmUiTreeItem* treeItem = getTreeItemFromIndex(index); - if (treeItem) + PdmUiTreeOrdering* treeItem = treeItemFromIndex(index); + assert(treeItem); + + if (treeItem->isRepresentingObject()) { - PdmObject* pdmObject = treeItem->dataObject()->object(); - if (pdmObject) + PdmUiObjectHandle* pdmUiObject = uiObj(treeItem->object()); + if (pdmUiObject) { - if (pdmObject->userDescriptionField() && !pdmObject->userDescriptionField()->isUiReadOnly()) + if (pdmUiObject->userDescriptionField() && !pdmUiObject->userDescriptionField()->uiCapability()->isUiReadOnly()) { flagMask = flagMask | Qt::ItemIsEditable; } - if (pdmObject->objectToggleField()) + if (pdmUiObject->objectToggleField()) { flagMask = flagMask | Qt::ItemIsUserCheckable; } + } + } - if (pdmObject->isUiReadOnly()) - { - flagMask = flagMask & (~Qt::ItemIsEnabled); - } - + if (treeItem->isValid()) + { + if (treeItem->activeItem()->isUiReadOnly()) + { + flagMask = flagMask & (~Qt::ItemIsEnabled); } } - else + + if (m_dragDropInterface) { - flagMask = flagMask & (~Qt::ItemIsEditable); + Qt::ItemFlags dragDropFlags = m_dragDropInterface->flags(index); + flagMask |= dragDropFlags; } return flagMask; @@ -366,202 +760,110 @@ Qt::ItemFlags PdmUiTreeViewModel::flags(const QModelIndex &index) const //-------------------------------------------------------------------------------------------------- -/// Refreshes the UI-tree below the supplied root PdmObject +/// //-------------------------------------------------------------------------------------------------- -void PdmUiTreeViewModel::updateUiSubTree(PdmObject* pdmRoot) +QVariant PdmUiTreeViewModel::headerData(int section, Qt::Orientation orientation, int role /*= Qt::DisplayRole */) const { - // Build the new "Correct" Tree - - PdmUiTreeOrdering* tempUpdatedPdmTree = pdmRoot->uiTreeOrdering(); - - // Find the corresponding entry for "root" in the existing Ui tree - - QModelIndex uiSubTreeRootModelIdx = getModelIndexFromPdmObject(pdmRoot); + if (role != Qt::DisplayRole) + return QVariant(); - PdmUiTreeItem* uiModelSubTreeRoot = NULL; - if (uiSubTreeRootModelIdx.isValid()) - { - uiModelSubTreeRoot = getTreeItemFromIndex(uiSubTreeRootModelIdx); - } - else + if (section < m_columnHeaders.size()) { - uiModelSubTreeRoot = m_treeItemRoot; + return m_columnHeaders[section]; } - - updateModelSubTree(uiSubTreeRootModelIdx, uiModelSubTreeRoot, tempUpdatedPdmTree); - - delete tempUpdatedPdmTree; + return QVariant(); } //-------------------------------------------------------------------------------------------------- -/// Makes the destinationSubTreeRoot tree become identical to the tree in sourceSubTreeRoot, -/// calling begin..() end..() to make the UI update accordingly. -/// This assumes that all the items have a pointer an unique PdmObject +/// //-------------------------------------------------------------------------------------------------- -void PdmUiTreeViewModel::updateModelSubTree(const QModelIndex& modelIdxOfDestinationSubTreeRoot, PdmUiTreeItem* destinationSubTreeRoot, PdmUiTreeItem* sourceSubTreeRoot) +PdmUiItem* PdmUiTreeViewModel::uiItemFromModelIndex(const QModelIndex& index) const { - // First loop over children in the old ui tree, deleting the ones not present in - // the newUiTree - - for (int resultChildIdx = 0; resultChildIdx < destinationSubTreeRoot->childCount() ; ++resultChildIdx) - { - PdmUiTreeItem* oldChild = destinationSubTreeRoot->child(resultChildIdx); - int childIndex = sourceSubTreeRoot->findChildItemIndex(oldChild->dataObject()); - - if (childIndex == -1) // Not found - { - this->beginRemoveRows(modelIdxOfDestinationSubTreeRoot, resultChildIdx, resultChildIdx); - destinationSubTreeRoot->removeChildren(resultChildIdx, 1); - this->endRemoveRows(); - resultChildIdx--; - } - } - - // Then loop over the children in the new ui tree, finding the corresponding items in the old tree. - // If they are found, we move them to the correct position. - // If not found, we pulls the item out of the old ui tree, inserting it into the new tree to avoid the default delete operation in ~UiTreeItem() - - int sourceChildCount = sourceSubTreeRoot->childCount(); - int sourceChildIdx = 0; - - for (int resultChildIdx = 0; resultChildIdx < sourceChildCount; ++resultChildIdx, ++sourceChildIdx) + PdmUiTreeOrdering* treeItem = this->treeItemFromIndex(index); + if (treeItem) { - PdmUiTreeItem* newChild = sourceSubTreeRoot->child(sourceChildIdx); - int childIndex = destinationSubTreeRoot->findChildItemIndex(newChild->dataObject()); - - if (childIndex == -1) // Not found - { - this->beginInsertRows(modelIdxOfDestinationSubTreeRoot, resultChildIdx, resultChildIdx); - destinationSubTreeRoot->insertChild(resultChildIdx, newChild); - this->endInsertRows(); - sourceSubTreeRoot->removeChildrenNoDelete(sourceChildIdx, 1); - sourceChildIdx--; - } - else if (childIndex != resultChildIdx) // Found, but must be moved - { - assert(childIndex > resultChildIdx); - - PdmUiTreeItem* oldChild = destinationSubTreeRoot->child(childIndex); - this->beginMoveRows(modelIdxOfDestinationSubTreeRoot, childIndex, childIndex, modelIdxOfDestinationSubTreeRoot, resultChildIdx); - destinationSubTreeRoot->removeChildrenNoDelete(childIndex, 1); - destinationSubTreeRoot->insertChild(resultChildIdx, oldChild); - this->endMoveRows(); - updateModelSubTree( index(resultChildIdx, 0, modelIdxOfDestinationSubTreeRoot), oldChild, newChild); - } - else // Found the corresponding item in the right place. - { - PdmUiTreeItem* oldChild = destinationSubTreeRoot->child(childIndex); - updateModelSubTree( index(resultChildIdx, 0, modelIdxOfDestinationSubTreeRoot), oldChild, newChild); - } + return treeItem->activeItem(); } - - + + return NULL; } - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -PdmUiTreeItem* PdmUiTreeViewModel::treeItemRoot() +void PdmUiTreeViewModel::setDragDropInterface(PdmUiDragDropInterface* dragDropInterface) { - return m_treeItemRoot; + m_dragDropInterface = dragDropInterface; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void PdmUiTreeViewModel::notifyModelChanged() +PdmUiDragDropInterface* PdmUiTreeViewModel::dragDropInterface() { - QModelIndex startModelIdx = index(0,0); - QModelIndex endModelIdx = index(rowCount(startModelIdx), 0); - - emit dataChanged(startModelIdx, endModelIdx); + return m_dragDropInterface; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QVariant PdmUiTreeViewModel::headerData(int section, Qt::Orientation orientation, int role /*= Qt::DisplayRole */) const +QStringList PdmUiTreeViewModel::mimeTypes() const { - if (role != Qt::DisplayRole) - return QVariant(); - - if (section < m_columnHeaders.size()) + if (m_dragDropInterface) { - return m_columnHeaders[section]; + return m_dragDropInterface->mimeTypes(); + } + else + { + return QAbstractItemModel::mimeTypes(); } - - return QVariant(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void PdmUiTreeViewModel::setColumnHeaders(const QStringList& columnHeaders) -{ - m_columnHeaders = columnHeaders; } - - - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -PdmUiTreeItem* caf::PdmUiTreeViewModel::getTreeItemFromIndex(const QModelIndex& index) +QMimeData * PdmUiTreeViewModel::mimeData(const QModelIndexList &indexes) const { - if (index.isValid()) + if (m_dragDropInterface) { - assert(index.internalPointer()); - - PdmUiTreeItem* treeItem = static_cast(index.internalPointer()); - return treeItem; + return m_dragDropInterface->mimeData(indexes); + } + else + { + return QAbstractItemModel::mimeData(indexes); } - - return NULL; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QModelIndex caf::PdmUiTreeViewModel::getModelIndexFromPdmObjectRecursive(const QModelIndex& currentIndex, const PdmObject * object) const +bool PdmUiTreeViewModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) { - if (currentIndex.internalPointer()) + if (m_dragDropInterface) { - PdmUiTreeItem* treeItem = static_cast(currentIndex.internalPointer()); - if (treeItem->dataObject()->object() == object) return currentIndex; + return m_dragDropInterface->dropMimeData(data, action, row, column, parent); + } + else + { + return QAbstractItemModel::dropMimeData(data, action, row, column, parent); } - - int row; - for (row = 0; row < rowCount(currentIndex); ++row) - { - QModelIndex foundIndex = getModelIndexFromPdmObjectRecursive(index(row, 0, currentIndex), object); - if (foundIndex.isValid()) return foundIndex; - } - return QModelIndex(); } - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QModelIndex caf::PdmUiTreeViewModel::getModelIndexFromPdmObject( const PdmObject * object) const +Qt::DropActions PdmUiTreeViewModel::supportedDropActions() const { - QModelIndex foundIndex; - int numRows = rowCount(QModelIndex()); - int r = 0; - while (r < numRows && !foundIndex.isValid()) - { - foundIndex = getModelIndexFromPdmObjectRecursive(index(r, 0, QModelIndex()), object); - ++r; - } - return foundIndex; + if (m_dragDropInterface) + { + return m_dragDropInterface->supportedDropActions(); + } + else + { + return QAbstractItemModel::supportedDropActions(); + } } - - - - } // end namespace caf diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeViewModel.h b/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeViewModel.h index c8a1028be6..60dbb127ec 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeViewModel.h +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeViewModel.h @@ -34,7 +34,6 @@ // //################################################################################################## - #pragma once #include "cafUiTreeItem.h" @@ -42,18 +41,15 @@ #include #include -#include -#include "cafPdmPointer.h" - - namespace caf { -class PdmObject; - -//typedef UiTreeItem > PdmUiTreeItem; +class PdmObjectHandle; +class PdmUiItem; +class PdmUiTreeViewEditor; class PdmUiTreeOrdering; -typedef UiTreeItem PdmUiTreeItem; +class PdmUiDragDropInterface; + //================================================================================================== // // This class is intended to replace UiTreeModelPdm (cafUiTreeModelPdm) @@ -64,51 +60,62 @@ class PdmUiTreeViewModel : public QAbstractItemModel Q_OBJECT public: - PdmUiTreeViewModel(QObject* parent); + PdmUiTreeViewModel(PdmUiTreeViewEditor* treeViewEditor); - void setTreeItemRoot(PdmUiTreeItem* root); - PdmUiTreeItem* treeItemRoot(); + void setPdmItemRoot(PdmUiItem* rootItem); + void updateSubTree(PdmUiItem* subTreeRoot); + + void setColumnHeaders(const QStringList& columnHeaders); + void setUiConfigName(const QString& uiConfigName) { m_uiConfigName = uiConfigName; } + + // These are supposed to be used from the Editor only, and to implement selection support. + + PdmUiItem* uiItemFromModelIndex(const QModelIndex& index) const; + QModelIndex findModelIndex(const PdmUiItem* object) const; + + void setDragDropInterface(PdmUiDragDropInterface* dragDropInterface); + PdmUiDragDropInterface* dragDropInterface(); + +private: + void updateSubTreeRecursive(const QModelIndex& uiSubTreeRootModelIdx, PdmUiTreeOrdering* uiModelSubTreeRoot, PdmUiTreeOrdering* updatedPdmSubTreeRoot); + PdmUiTreeOrdering* treeItemFromIndex(const QModelIndex& index) const; + QModelIndex findModelIndexRecursive(const QModelIndex& currentIndex, const PdmUiItem * object) const; + + void resetTree(PdmUiTreeOrdering* root); void emitDataChanged(const QModelIndex& index); + void updateEditorsForSubTree(PdmUiTreeOrdering* root); - static PdmUiTreeItem* getTreeItemFromIndex(const QModelIndex& index); - QModelIndex getModelIndexFromPdmObject(const PdmObject* object) const; - void updateUiSubTree(PdmObject* root); + PdmUiTreeOrdering* m_treeOrderingRoot; + QStringList m_columnHeaders; + QString m_uiConfigName; - void notifyModelChanged(); - void setColumnHeaders(const QStringList& columnHeaders); + PdmUiTreeViewEditor* m_treeViewEditor; + + PdmUiDragDropInterface* m_dragDropInterface; + +private: -public: // Overrides from QAbstractItemModel + virtual QModelIndex index(int row, int column, const QModelIndex &parentIndex = QModelIndex( )) const; virtual QModelIndex parent(const QModelIndex &index) const; + virtual int rowCount(const QModelIndex &parentIndex = QModelIndex( ) ) const; virtual int columnCount(const QModelIndex &parentIndex = QModelIndex( ) ) const; + virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole ) const; - virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const; - - virtual Qt::ItemFlags flags(const QModelIndex &index) const; virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); + virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const; + virtual Qt::ItemFlags flags(const QModelIndex &index) const; -protected: - QModelIndex getModelIndexFromPdmObjectRecursive(const QModelIndex& currentIndex, const PdmObject * object) const; -private: - void updateModelSubTree(const QModelIndex& uiSubTreeRootModelIdx, PdmUiTreeItem* uiModelSubTreeRoot, PdmUiTreeItem* updatedPdmSubTreeRoot); - - PdmUiTreeItem* m_treeItemRoot; - QStringList m_columnHeaders; + virtual QStringList mimeTypes() const; + virtual QMimeData* mimeData(const QModelIndexList &indexes) const; + virtual bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent); + virtual Qt::DropActions supportedDropActions() const; }; -//================================================================================================== -/// -//================================================================================================== -class UiTreeItemBuilderPdm -{ -public: - static PdmUiTreeItem* buildViewItems(PdmUiTreeItem* parentTreeItem, int position, caf::PdmObject* object); -}; - } // End of namespace caf diff --git a/Fwk/AppFwk/cafUserInterface/cafProgressInfo.cpp b/Fwk/AppFwk/cafUserInterface/cafProgressInfo.cpp index b0a70ac7c1..498170c2e6 100644 --- a/Fwk/AppFwk/cafUserInterface/cafProgressInfo.cpp +++ b/Fwk/AppFwk/cafUserInterface/cafProgressInfo.cpp @@ -45,383 +45,390 @@ namespace caf { -//================================================================================================== -/// -/// \class caf::ProgressInfo -/// This class provides a simple frontend to the Qt progressbar, allowing distributed -/// progress calculation. -/// -/// Create an instance of this object in the method/function that needs progress information -/// Then call incrementProgress() or setProgress() at proper times in your method. -/// When the method returns, the ProgressInfo destructor will clean up and finish. -/// The real beauty is that this class will magically interact with possible ProgressInfo instances -/// in functions that your method calls, providing a complete, consistent and detailed progress bar -/// -/// caf::ProgressInfo progInfo(3, "Open File"); -/// progInfo.setProgressDescription("Reading"); -/// ...readFile() -/// progInfo.incrementProgress(); -/// progInfo.setProgressDescription("Validating"); -/// ... validateData(); -/// progInfo.incrementProgress(); -/// progInfo.setProgressDescription("Building geometry"); -/// ... buildGeometry(); -/// progInfo.incrementProgress(); // not needed really, because the destructor will send the progress to top. -//================================================================================================== - -//-------------------------------------------------------------------------------------------------- -/// The title will be written centered in the dialog, under other progress titles in action. -/// If you do not need a title for a particular level, simply pass "" and it will be ignored. -/// \sa setProgressDescription -//-------------------------------------------------------------------------------------------------- -ProgressInfo::ProgressInfo(size_t maxProgressValue, const QString& title) -{ - ProgressInfoStatic::start(maxProgressValue, title); - - if (qApp) + //================================================================================================== + /// + /// \class caf::ProgressInfo + /// This class provides a simple frontend to the Qt progressbar, allowing distributed + /// progress calculation. + /// + /// Create an instance of this object in the method/function that needs progress information + /// Then call incrementProgress() or setProgress() at proper times in your method. + /// When the method returns, the ProgressInfo destructor will clean up and finish. + /// The real beauty is that this class will magically interact with possible ProgressInfo instances + /// in functions that your method calls, providing a complete, consistent and detailed progress bar + /// + /// caf::ProgressInfo progInfo(3, "Open File"); + /// progInfo.setProgressDescription("Reading"); + /// ...readFile() + /// progInfo.incrementProgress(); + /// progInfo.setProgressDescription("Validating"); + /// ... validateData(); + /// progInfo.incrementProgress(); + /// progInfo.setProgressDescription("Building geometry"); + /// ... buildGeometry(); + /// progInfo.incrementProgress(); // not needed really, because the destructor will send the progress to top. + //================================================================================================== + + //-------------------------------------------------------------------------------------------------- + /// The title will be written centered in the dialog, under other progress titles in action. + /// If you do not need a title for a particular level, simply pass "" and it will be ignored. + /// \sa setProgressDescription + //-------------------------------------------------------------------------------------------------- + ProgressInfo::ProgressInfo(size_t maxProgressValue, const QString& title) { - QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); + ProgressInfoStatic::start(maxProgressValue, title); + + if (qApp) + { + QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); + } } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -ProgressInfo::~ProgressInfo() -{ - ProgressInfoStatic::finished(); - - if (qApp) + + //-------------------------------------------------------------------------------------------------- + /// + //-------------------------------------------------------------------------------------------------- + ProgressInfo::~ProgressInfo() { - QApplication::restoreOverrideCursor(); + ProgressInfoStatic::finished(); + + if (qApp) + { + QApplication::restoreOverrideCursor(); + } } -} - -//-------------------------------------------------------------------------------------------------- -/// Sets a description of the step currently being executed. -/// Used to create a nice text in the progressDialog, by appending " : " -/// to the current levels title. If no title is requested for this level, the ":" is omitted. -/// So: One line per level that has title and/or description. -/// in the format: -/// : <Description> -/// The ":" is only there when needed -//-------------------------------------------------------------------------------------------------- -void ProgressInfo::setProgressDescription(const QString& description) -{ - ProgressInfoStatic::setProgressDescription(description); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void ProgressInfo::setProgress(size_t progressValue) -{ - ProgressInfoStatic::setProgress(progressValue); -} - -//-------------------------------------------------------------------------------------------------- -/// Increments progress by 1, or by the amount set by setNextProgressStepSize -//-------------------------------------------------------------------------------------------------- -void ProgressInfo::incrementProgress() -{ - ProgressInfoStatic::incrementProgress(); -} - -//-------------------------------------------------------------------------------------------------- -/// To make a certain operation span more of the progress bar than one tick, -/// set the number of progress ticks that you want it to use before calling it. -/// Eg. -/// caf::ProgressInfo progInfo(5, "Doing things"); -/// // ... Do one small thing -/// progInfo.incrementProgress(); -/// progInfo.setNextProgressStepSize(3); -/// // ... Some heavy function call with its own progress handling -/// progInfo.incrementProgress(); -/// -//-------------------------------------------------------------------------------------------------- -void ProgressInfo::setNextProgressIncrement(size_t nextStepSize) -{ - ProgressInfoStatic::setNextProgressIncrement(nextStepSize); -} - - - - - - - - -//================================================================================================== -/// -/// Internal file-scope private functions to implement the progress dialog -/// -/// -/// -//================================================================================================== - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -static QProgressDialog* progressDialog() -{ - static QPointer<QProgressDialog> progDialog; - if (progDialog.isNull()) - { - progDialog = new QProgressDialog(); - - progDialog->hide(); - } - return progDialog; -} - -//-------------------------------------------------------------------------------------------------- -/// A static vector containing the maximum values for the progress on each sublevel (call stack level) -//-------------------------------------------------------------------------------------------------- -static std::vector<size_t>& maxProgressStack() -{ - static std::vector<size_t> m_maxProgressStack; - - return m_maxProgressStack; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -static std::vector<QString>& titleStack() -{ - static std::vector<QString> m_titleStack; - - return m_titleStack; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -static std::vector<QString>& descriptionStack() -{ - static std::vector<QString> m_descriptionStack; - - return m_descriptionStack; -} - -//-------------------------------------------------------------------------------------------------- -/// The actual progress value on each level (call stack level) 0 corresponds to the outermost function -//-------------------------------------------------------------------------------------------------- -static std::vector<size_t>& progressStack() -{ - static std::vector<size_t> m_progressStack; - - return m_progressStack; -} - -//-------------------------------------------------------------------------------------------------- -/// The number of progress ticks (span) on each callstack level that the level deeper (in callstack) shall fill -/// used to balance the progress, making some (heavy) operations span more of the progress bar -//-------------------------------------------------------------------------------------------------- -static std::vector<size_t>& progressSpanStack() -{ - static std::vector<size_t> m_progressSpanStack; - - return m_progressSpanStack; -} - -//-------------------------------------------------------------------------------------------------- -/// Calculate the total maximum value for the progress bar composed -/// of the complete stack -//-------------------------------------------------------------------------------------------------- -static size_t currentTotalMaxProgressValue() -{ - size_t levCount = 1; - for (size_t levelDepth = 0; levelDepth < maxProgressStack().size(); ++levelDepth) + + //-------------------------------------------------------------------------------------------------- + /// Sets a description of the step currently being executed. + /// Used to create a nice text in the progressDialog, by appending " : <your text>" + /// to the current levels title. If no title is requested for this level, the ":" is omitted. + /// So: One line per level that has title and/or description. + /// in the format: + /// <Title>: <Description> + /// The ":" is only there when needed + //-------------------------------------------------------------------------------------------------- + void ProgressInfo::setProgressDescription(const QString& description) { - levCount *= maxProgressStack()[levelDepth]; + ProgressInfoStatic::setProgressDescription(description); } - return levCount; -} - -//-------------------------------------------------------------------------------------------------- -/// Calculate the total progress value based on the current level subdivision and progress -//-------------------------------------------------------------------------------------------------- -static size_t currentTotalProgress() -{ - double progress = 0; - for (int i = static_cast<int>(progressStack().size()) - 1; i >= 0; --i) + + //-------------------------------------------------------------------------------------------------- + /// + //-------------------------------------------------------------------------------------------------- + void ProgressInfo::setProgress(size_t progressValue) { - size_t span = (i < 1) ? 1 : progressSpanStack()[i-1]; - progress = span*(progress + progressStack()[i])/maxProgressStack()[i]; + ProgressInfoStatic::setProgress(progressValue); } - size_t totalIntProgress = static_cast<size_t>(currentTotalMaxProgressValue()*progress); + //-------------------------------------------------------------------------------------------------- + /// Increments progress by 1, or by the amount set by setNextProgressStepSize + //-------------------------------------------------------------------------------------------------- + void ProgressInfo::incrementProgress() + { + ProgressInfoStatic::incrementProgress(); + } + + //-------------------------------------------------------------------------------------------------- + /// To make a certain operation span more of the progress bar than one tick, + /// set the number of progress ticks that you want it to use before calling it. + /// Eg. + /// caf::ProgressInfo progInfo(5, "Doing things"); + /// // ... Do one small thing + /// progInfo.incrementProgress(); + /// progInfo.setNextProgressStepSize(3); + /// // ... Some heavy function call with its own progress handling + /// progInfo.incrementProgress(); + /// + //-------------------------------------------------------------------------------------------------- + void ProgressInfo::setNextProgressIncrement(size_t nextStepSize) + { + ProgressInfoStatic::setNextProgressIncrement(nextStepSize); + } + + - return totalIntProgress; -} -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -static QString currentComposedLabel() -{ - QString labelText; - for (size_t i = 0; i < titleStack().size(); ++i) + + + + //================================================================================================== + /// + /// Internal file-scope private functions to implement the progress dialog + /// + /// + /// + //================================================================================================== + + //-------------------------------------------------------------------------------------------------- + /// + //-------------------------------------------------------------------------------------------------- + static QProgressDialog* progressDialog() { - if (!titleStack()[i].isEmpty()) labelText += titleStack()[i]; - if (!titleStack()[i].isEmpty() && !descriptionStack()[i].isEmpty()) labelText +=": "; - if (!descriptionStack()[i].isEmpty()) labelText += descriptionStack()[i] ; - if (!(titleStack()[i].isEmpty() && descriptionStack()[i].isEmpty())) labelText += "\n"; + static QPointer<QProgressDialog> progDialog; + if (progDialog.isNull()) + { + progDialog = new QProgressDialog(); + + progDialog->hide(); + } + return progDialog; } - labelText += "\n "; - return labelText; - -} - -static bool isUpdatePossible() -{ - if (!qApp) return false; - - if (!progressDialog()) return false; - - return progressDialog()->thread() == QThread::currentThread(); -} -//================================================================================================== -/// -/// \class caf::ProgressInfoStatic -/// -/// -/// -//================================================================================================== - - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void ProgressInfoStatic::start(size_t maxProgressValue, const QString& title) -{ - if (!isUpdatePossible()) return; - - if (!maxProgressStack().size()) + + //-------------------------------------------------------------------------------------------------- + /// A static vector containing the maximum values for the progress on each sublevel (call stack level) + //-------------------------------------------------------------------------------------------------- + static std::vector<size_t>& maxProgressStack() { - progressDialog()->setWindowModality(Qt::ApplicationModal); - progressDialog()->setMinimum(0); - progressDialog()->setWindowTitle(title); - progressDialog()->setCancelButton(NULL); - progressDialog()->show(); + static std::vector<size_t> m_maxProgressStack; + + return m_maxProgressStack; } - maxProgressStack().push_back(maxProgressValue); - progressStack().push_back(0); - progressSpanStack().push_back(1); - titleStack().push_back(title); - descriptionStack().push_back(""); + //-------------------------------------------------------------------------------------------------- + /// + //-------------------------------------------------------------------------------------------------- + static std::vector<QString>& titleStack() + { + static std::vector<QString> m_titleStack; - progressDialog()->setMaximum(static_cast<int>(currentTotalMaxProgressValue())); - progressDialog()->setValue(static_cast<int>(currentTotalProgress())); - progressDialog()->setLabelText(currentComposedLabel()); + return m_titleStack; + } - QCoreApplication::processEvents(); -} + //-------------------------------------------------------------------------------------------------- + /// + //-------------------------------------------------------------------------------------------------- + static std::vector<QString>& descriptionStack() + { + static std::vector<QString> m_descriptionStack; + return m_descriptionStack; + } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void ProgressInfoStatic::setProgressDescription(const QString& description) -{ - if (!isUpdatePossible()) return; + //-------------------------------------------------------------------------------------------------- + /// The actual progress value on each level (call stack level) 0 corresponds to the outermost function + //-------------------------------------------------------------------------------------------------- + static std::vector<size_t>& progressStack() + { + static std::vector<size_t> m_progressStack; - descriptionStack().back() = description; + return m_progressStack; + } - progressDialog()->setLabelText(currentComposedLabel()); - QCoreApplication::processEvents(); -} + //-------------------------------------------------------------------------------------------------- + /// The number of progress ticks (span) on each callstack level that the level deeper (in callstack) shall fill + /// used to balance the progress, making some (heavy) operations span more of the progress bar + //-------------------------------------------------------------------------------------------------- + static std::vector<size_t>& progressSpanStack() + { + static std::vector<size_t> m_progressSpanStack; -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void ProgressInfoStatic::setProgress(size_t progressValue) -{ - if (!isUpdatePossible()) return; + return m_progressSpanStack; + } - if (progressValue == progressStack().back()) return; // Do nothing if no progress. + //-------------------------------------------------------------------------------------------------- + /// Calculate the total maximum value for the progress bar composed + /// of the complete stack + //-------------------------------------------------------------------------------------------------- + static size_t currentTotalMaxProgressValue() + { + size_t levCount = 1; + for (size_t levelDepth = 0; levelDepth < maxProgressStack().size(); ++levelDepth) + { + levCount *= maxProgressStack()[levelDepth]; + } + return levCount; + } - // Guard against the max value set for this level - if (progressValue > maxProgressStack().back() ) progressValue = maxProgressStack().back(); + //-------------------------------------------------------------------------------------------------- + /// Calculate the total progress value based on the current level subdivision and progress + //-------------------------------------------------------------------------------------------------- + static size_t currentTotalProgress() + { + double progress = 0; + for (int i = static_cast<int>(progressStack().size()) - 1; i >= 0; --i) + { + size_t span = (i < 1) ? 1 : progressSpanStack()[i - 1]; + progress = span*(progress + progressStack()[i]) / maxProgressStack()[i]; + } - progressStack().back() = progressValue; - progressSpanStack().back() = 1; + size_t totalIntProgress = static_cast<size_t>(currentTotalMaxProgressValue()*progress); - int totalProgress = static_cast<int>(currentTotalProgress()); - int totalMaxProgress = static_cast<int>(currentTotalMaxProgressValue()); + return totalIntProgress; + } - assert(static_cast<int>(totalProgress) <= totalMaxProgress); + //-------------------------------------------------------------------------------------------------- + /// + //-------------------------------------------------------------------------------------------------- + static QString currentComposedLabel() + { + QString labelText; - progressDialog()->setMaximum(totalMaxProgress); - progressDialog()->setValue(totalProgress); + for (size_t i = 0; i < titleStack().size(); ++i) + { + if (!titleStack()[i].isEmpty()) labelText += titleStack()[i]; + if (!titleStack()[i].isEmpty() && !descriptionStack()[i].isEmpty()) labelText += ": "; + if (!descriptionStack()[i].isEmpty()) labelText += descriptionStack()[i]; + if (!(titleStack()[i].isEmpty() && descriptionStack()[i].isEmpty())) labelText += "\n"; + } + labelText += "\n "; + return labelText; - QCoreApplication::processEvents(); -} + } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void ProgressInfoStatic::incrementProgress() -{ - if (!isUpdatePossible()) return; + static bool isUpdatePossible() + { + if (!qApp) return false; - assert(progressStack().size()); - ProgressInfoStatic::setProgress(progressStack().back() + progressSpanStack().back()); -} + if (!progressDialog()) return false; + return progressDialog()->thread() == QThread::currentThread(); + } + //================================================================================================== + /// + /// \class caf::ProgressInfoStatic + /// + /// + /// + //================================================================================================== + + + //-------------------------------------------------------------------------------------------------- + /// + //-------------------------------------------------------------------------------------------------- + void ProgressInfoStatic::start(size_t maxProgressValue, const QString& title) + { + if (!isUpdatePossible()) return; -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void ProgressInfoStatic::setNextProgressIncrement(size_t nextStepSize) -{ - if (!isUpdatePossible()) return; + if (!maxProgressStack().size()) + { + //progressDialog()->setWindowModality(Qt::ApplicationModal); + progressDialog()->setMinimum(0); + progressDialog()->setWindowTitle(title); + progressDialog()->setCancelButton(NULL); + progressDialog()->show(); + } - assert(progressSpanStack().size()); + maxProgressStack().push_back(maxProgressValue); + progressStack().push_back(0); + progressSpanStack().push_back(1); + titleStack().push_back(title); + descriptionStack().push_back(""); - progressSpanStack().back() = nextStepSize; -} + progressDialog()->setMaximum(static_cast<int>(currentTotalMaxProgressValue())); + progressDialog()->setValue(static_cast<int>(currentTotalProgress())); + progressDialog()->setLabelText(currentComposedLabel()); + //QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents); + if (progressDialog()) progressDialog()->repaint(); + } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void ProgressInfoStatic::finished() -{ - if (!isUpdatePossible()) return; - assert(maxProgressStack().size() && progressStack().size() && progressSpanStack().size() && titleStack().size() && descriptionStack().size()); + //-------------------------------------------------------------------------------------------------- + /// + //-------------------------------------------------------------------------------------------------- + void ProgressInfoStatic::setProgressDescription(const QString& description) + { + if (!isUpdatePossible()) return; - // Set progress to max value, and leave it there until somebody touches the progress again + descriptionStack().back() = description; - ProgressInfoStatic::setProgress(maxProgressStack().back()); + progressDialog()->setLabelText(currentComposedLabel()); + //QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents); + if (progressDialog()) progressDialog()->repaint(); - // Pop all the stacks - maxProgressStack().pop_back(); - progressStack().pop_back(); - progressSpanStack().pop_back(); - titleStack().pop_back(); - descriptionStack().pop_back(); + } - // Update the text to reflect the "previous level" - progressDialog()->setLabelText(currentComposedLabel()); + //-------------------------------------------------------------------------------------------------- + /// + //-------------------------------------------------------------------------------------------------- + void ProgressInfoStatic::setProgress(size_t progressValue) + { + if (!isUpdatePossible()) return; + + if (progressValue == progressStack().back()) return; // Do nothing if no progress. + + // Guard against the max value set for this level + if (progressValue > maxProgressStack().back()) progressValue = maxProgressStack().back(); + + progressStack().back() = progressValue; + progressSpanStack().back() = 1; + + int totalProgress = static_cast<int>(currentTotalProgress()); + int totalMaxProgress = static_cast<int>(currentTotalMaxProgressValue()); + + assert(static_cast<int>(totalProgress) <= totalMaxProgress); + + progressDialog()->setMaximum(totalMaxProgress); + progressDialog()->setValue(totalProgress); + + //QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents); + if (progressDialog()) progressDialog()->repaint(); + + } - // If we are finishing the last level, clean up - if (!maxProgressStack().size()) + //-------------------------------------------------------------------------------------------------- + /// + //-------------------------------------------------------------------------------------------------- + void ProgressInfoStatic::incrementProgress() { - if (progressDialog() != NULL) + if (!isUpdatePossible()) return; + + assert(progressStack().size()); + ProgressInfoStatic::setProgress(progressStack().back() + progressSpanStack().back()); + } + + + //-------------------------------------------------------------------------------------------------- + /// + //-------------------------------------------------------------------------------------------------- + void ProgressInfoStatic::setNextProgressIncrement(size_t nextStepSize) + { + if (!isUpdatePossible()) return; + + assert(progressSpanStack().size()); + + progressSpanStack().back() = nextStepSize; + } + + + //-------------------------------------------------------------------------------------------------- + /// + //-------------------------------------------------------------------------------------------------- + void ProgressInfoStatic::finished() + { + if (!isUpdatePossible()) return; + + assert(maxProgressStack().size() && progressStack().size() && progressSpanStack().size() && titleStack().size() && descriptionStack().size()); + + // Set progress to max value, and leave it there until somebody touches the progress again + + ProgressInfoStatic::setProgress(maxProgressStack().back()); + + // Pop all the stacks + maxProgressStack().pop_back(); + progressStack().pop_back(); + progressSpanStack().pop_back(); + titleStack().pop_back(); + descriptionStack().pop_back(); + + // Update the text to reflect the "previous level" + progressDialog()->setLabelText(currentComposedLabel()); + + // If we are finishing the last level, clean up + if (!maxProgressStack().size()) { - progressDialog()->hide(); - delete progressDialog(); + if (progressDialog() != NULL) + { + progressDialog()->hide(); + delete progressDialog(); + } } - } - // Make sure the Gui is repainted - QCoreApplication::processEvents(); -} + // Make sure the Gui is repainted + //QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents); + if (progressDialog()) progressDialog()->repaint(); + + } } // namespace caf diff --git a/Fwk/AppFwk/cafUserInterface/cafUiTreeModelPdm.cpp b/Fwk/AppFwk/cafUserInterface/cafUiTreeModelPdm.cpp deleted file mode 100644 index 4e5832b608..0000000000 --- a/Fwk/AppFwk/cafUserInterface/cafUiTreeModelPdm.cpp +++ /dev/null @@ -1,647 +0,0 @@ -//################################################################################################## -// -// Custom Visualization Core library -// Copyright (C) 2011-2013 Ceetron AS -// -// This library may be used under the terms of either the GNU General Public License or -// the GNU Lesser General Public License as follows: -// -// GNU General Public License Usage -// This library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. -// -// See the GNU General Public License at <<http://www.gnu.org/licenses/gpl.html>> -// for more details. -// -// GNU Lesser General Public License Usage -// This library is free software; you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation; either version 2.1 of the License, or -// (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. -// -// See the GNU Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>> -// for more details. -// -//################################################################################################## - - -#include "cafUiTreeModelPdm.h" -#include "cafPdmField.h" -#include "cafPdmObject.h" - - - -namespace caf -{ - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -UiTreeModelPdm::UiTreeModelPdm(QObject* parent) -{ - m_treeItemRoot = NULL; -} - - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void UiTreeModelPdm::setTreeItemRoot(PdmUiTreeItem* root) -{ - beginResetModel(); - - if (m_treeItemRoot) - { - delete m_treeItemRoot; - } - - m_treeItemRoot = root; - endResetModel(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -QModelIndex UiTreeModelPdm::index(int row, int column, const QModelIndex &parentIndex /*= QModelIndex( ) */) const -{ - if (!m_treeItemRoot) - return QModelIndex(); - - if (!hasIndex(row, column, parentIndex)) - return QModelIndex(); - - PdmUiTreeItem* parentItem = NULL; - - if (!parentIndex.isValid()) - parentItem = m_treeItemRoot; - else - parentItem = UiTreeModelPdm::getTreeItemFromIndex(parentIndex); - - - PdmUiTreeItem* childItem = parentItem->child(row); - if (childItem) - return createIndex(row, column, childItem); - else - return QModelIndex(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -QModelIndex UiTreeModelPdm::parent(const QModelIndex &childIndex) const -{ - if (!m_treeItemRoot) return QModelIndex(); - - if (!childIndex.isValid()) return QModelIndex(); - - PdmUiTreeItem* childItem = UiTreeModelPdm::getTreeItemFromIndex(childIndex); - if (!childItem) return QModelIndex(); - - PdmUiTreeItem* parentItem = childItem->parent(); - if (!parentItem) return QModelIndex(); - - if (parentItem == m_treeItemRoot) return QModelIndex(); - - return createIndex(parentItem->row(), 0, parentItem); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -int UiTreeModelPdm::rowCount(const QModelIndex &parentIndex /*= QModelIndex( ) */) const -{ - if (!m_treeItemRoot) - return 0; - - if (parentIndex.column() > 0) - return 0; - - PdmUiTreeItem* parentItem; - if (!parentIndex.isValid()) - parentItem = m_treeItemRoot; - else - parentItem = UiTreeModelPdm::getTreeItemFromIndex(parentIndex); - - return parentItem->childCount(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -int UiTreeModelPdm::columnCount(const QModelIndex &parentIndex /*= QModelIndex( ) */) const -{ - if (!m_treeItemRoot) - return 0; - - if (parentIndex.isValid()) - { - PdmUiTreeItem* parentItem = UiTreeModelPdm::getTreeItemFromIndex(parentIndex); - if (parentItem) - { - return parentItem->columnCount(); - } - else - { - return 0; - } - } - else - return m_treeItemRoot->columnCount(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -QVariant UiTreeModelPdm::data(const QModelIndex &index, int role /*= Qt::DisplayRole */) const -{ - if (!m_treeItemRoot) - return QVariant(); - - if (!index.isValid()) - return QVariant(); - - PdmUiTreeItem* treeItem = UiTreeModelPdm::getTreeItemFromIndex(index); - assert(treeItem); - - PdmObject* obj = treeItem->dataObject(); - - if (obj == NULL) return QVariant(); - - // We try to find the context of the object first: The parent field - // If found, use its data to describe the thing - // Note: This code will only find first field pointing at the current object. Its valid for now, - // but will not generally be valid if references is introduced in the pdm system - - PdmFieldHandle* parentField = 0; - - PdmUiTreeItem* parentTreeItem = treeItem->parent(); - if (parentTreeItem) - { - PdmObject* parentObj = parentTreeItem->dataObject(); - if (parentObj) - { - std::vector<PdmFieldHandle*> fields; - parentObj->fields(fields); - - size_t i; - for (i = 0; i < fields.size(); ++i) - { - std::vector<PdmObject*> children; - if (fields[i]) fields[i]->childObjects(&children); - size_t cIdx; - for (cIdx = 0; cIdx < children.size(); ++ cIdx) - { - if (children[cIdx] == obj) - { - parentField = fields[i]; - break; - } - } - if (parentField) break; - } - } - } - - assert(obj); - - if (role == Qt::DisplayRole || role == Qt::EditRole) - { - if (obj->userDescriptionField()) - { - return obj->userDescriptionField()->uiValue(); - } - else - { - if (parentField && !parentField->uiName().isEmpty()) - return parentField->uiName(); - else - return obj->uiName(); - } - } - else if (role == Qt::DecorationRole) - { - if (parentField && !parentField->uiIcon().isNull()) - return parentField->uiIcon(); - else - return obj->uiIcon(); - } - else if (role == Qt::ToolTipRole) - { - if (parentField && !parentField->uiToolTip().isEmpty()) - return parentField->uiToolTip(); - else - return obj->uiToolTip(); - } - else if (role == Qt::WhatsThisRole) - { - if (parentField && !parentField->uiWhatsThis().isEmpty()) - return parentField->uiWhatsThis(); - else - return obj->uiWhatsThis(); - } - else if (role == Qt::CheckStateRole) - { - if (obj->objectToggleField()) - { - bool isToggledOn = obj->objectToggleField()->uiValue().toBool(); - if (isToggledOn) - { - return Qt::Checked; - } - else - { - return Qt::Unchecked; - } - } - } - - return QVariant(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void UiTreeModelPdm::emitDataChanged(const QModelIndex& index) -{ - emit dataChanged(index, index); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool UiTreeModelPdm::setData(const QModelIndex &index, const QVariant &value, int role /*= Qt::EditRole*/) -{ - if (!index.isValid()) - { - return false; - } - - PdmUiTreeItem* treeItem = UiTreeModelPdm::getTreeItemFromIndex(index); - assert(treeItem); - - PdmObject* obj = treeItem->dataObject(); - assert(obj); - - if (role == Qt::EditRole && obj->userDescriptionField()) - { - obj->userDescriptionField()->setValueFromUi(value); - - emitDataChanged(index); - - return true; - } - else if (role == Qt::CheckStateRole && obj->objectToggleField()) - { - bool toggleOn = (value == Qt::Checked); - - obj->objectToggleField()->setValueFromUi(toggleOn); - - emitDataChanged(index); - - return true; - } - - return false; -} - -//-------------------------------------------------------------------------------------------------- -/// Enable edit of this item if we have a editable user description field for a pdmObject -/// Disable edit for other items -//-------------------------------------------------------------------------------------------------- -Qt::ItemFlags UiTreeModelPdm::flags(const QModelIndex &index) const -{ - if (!index.isValid()) - return Qt::ItemIsEnabled; - - Qt::ItemFlags flagMask = QAbstractItemModel::flags(index); - - PdmUiTreeItem* treeItem = getTreeItemFromIndex(index); - if (treeItem) - { - PdmObject* pdmObject = treeItem->dataObject(); - if (pdmObject) - { - if (pdmObject->userDescriptionField() && !pdmObject->userDescriptionField()->isUiReadOnly()) - { - flagMask = flagMask | Qt::ItemIsEditable; - } - - if (pdmObject->objectToggleField()) - { - flagMask = flagMask | Qt::ItemIsUserCheckable; - } - - if (pdmObject->isUiReadOnly()) - { - flagMask = flagMask & (~Qt::ItemIsEnabled); - } - - } - } - else - { - flagMask = flagMask & (~Qt::ItemIsEditable); - } - - return flagMask; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool UiTreeModelPdm::removeRows_special(int position, int count, const QModelIndex &parent /*= QModelIndex()*/) -{ - if (count <= 0) return true; - - PdmUiTreeItem* parentItem = NULL; - if (parent.isValid()) - { - parentItem = getTreeItemFromIndex(parent); - } - else - { - parentItem = m_treeItemRoot; - } - - if (!parentItem) return true; - - bool success = true; - - beginRemoveRows(parent, position, position + count - 1); - success = parentItem->removeChildren(position, count); - endRemoveRows(); - - return success; -} - -//-------------------------------------------------------------------------------------------------- -/// Refreshes the UI-tree below the supplied root PdmObject -//-------------------------------------------------------------------------------------------------- -void UiTreeModelPdm::updateUiSubTree(PdmObject* pdmRoot) -{ - // Build the new "Correct" Tree - - PdmUiTreeItem* tempUpdatedPdmTree = UiTreeItemBuilderPdm::buildViewItems(NULL, -1, pdmRoot); - if (!tempUpdatedPdmTree) return; - - // Find the corresponding entry for "root" in the existing Ui tree - - QModelIndex uiSubTreeRootModelIdx = getModelIndexFromPdmObject(pdmRoot); - - PdmUiTreeItem* uiModelSubTreeRoot = NULL; - if (uiSubTreeRootModelIdx.isValid()) - { - uiModelSubTreeRoot = getTreeItemFromIndex(uiSubTreeRootModelIdx); - } - else - { - uiModelSubTreeRoot = m_treeItemRoot; - } - - - updateModelSubTree(uiSubTreeRootModelIdx, uiModelSubTreeRoot, tempUpdatedPdmTree); - - delete tempUpdatedPdmTree; -} - -//-------------------------------------------------------------------------------------------------- -/// Makes the destinationSubTreeRoot tree become identical to the tree in sourceSubTreeRoot, -/// calling begin..() end..() to make the UI update accordingly. -/// This assumes that all the items have a pointer an unique PdmObject -//-------------------------------------------------------------------------------------------------- -void UiTreeModelPdm::updateModelSubTree(const QModelIndex& modelIdxOfDestinationSubTreeRoot, PdmUiTreeItem* destinationSubTreeRoot, PdmUiTreeItem* sourceSubTreeRoot) -{ - // First loop over children in the old ui tree, deleting the ones not present in - // the newUiTree - - for (int resultChildIdx = 0; resultChildIdx < destinationSubTreeRoot->childCount() ; ++resultChildIdx) - { - PdmUiTreeItem* oldChild = destinationSubTreeRoot->child(resultChildIdx); - int childIndex = sourceSubTreeRoot->findChildItemIndex(oldChild->dataObject()); - - if (childIndex == -1) // Not found - { - this->beginRemoveRows(modelIdxOfDestinationSubTreeRoot, resultChildIdx, resultChildIdx); - destinationSubTreeRoot->removeChildren(resultChildIdx, 1); - this->endRemoveRows(); - resultChildIdx--; - } - } - - // Then loop over the children in the new ui tree, finding the corresponding items in the old tree. - // If they are found, we move them to the correct position. - // If not found, we pulls the item out of the old ui tree, inserting it into the new tree to avoid the default delete operation in ~UiTreeItem() - - int sourceChildCount = sourceSubTreeRoot->childCount(); - int sourceChildIdx = 0; - - for (int resultChildIdx = 0; resultChildIdx < sourceChildCount; ++resultChildIdx, ++sourceChildIdx) - { - PdmUiTreeItem* newChild = sourceSubTreeRoot->child(sourceChildIdx); - int childIndex = destinationSubTreeRoot->findChildItemIndex(newChild->dataObject()); - - if (childIndex == -1) // Not found - { - this->beginInsertRows(modelIdxOfDestinationSubTreeRoot, resultChildIdx, resultChildIdx); - destinationSubTreeRoot->insertChild(resultChildIdx, newChild); - this->endInsertRows(); - sourceSubTreeRoot->removeChildrenNoDelete(sourceChildIdx, 1); - sourceChildIdx--; - } - else if (childIndex != resultChildIdx) // Found, but must be moved - { - assert(childIndex > resultChildIdx); - - PdmUiTreeItem* oldChild = destinationSubTreeRoot->child(childIndex); - this->beginMoveRows(modelIdxOfDestinationSubTreeRoot, childIndex, childIndex, modelIdxOfDestinationSubTreeRoot, resultChildIdx); - destinationSubTreeRoot->removeChildrenNoDelete(childIndex, 1); - destinationSubTreeRoot->insertChild(resultChildIdx, oldChild); - this->endMoveRows(); - updateModelSubTree( index(resultChildIdx, 0, modelIdxOfDestinationSubTreeRoot), oldChild, newChild); - } - else // Found the corresponding item in the right place. - { - PdmUiTreeItem* oldChild = destinationSubTreeRoot->child(childIndex); - updateModelSubTree( index(resultChildIdx, 0, modelIdxOfDestinationSubTreeRoot), oldChild, newChild); - } - } - - -} - - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -PdmUiTreeItem* UiTreeModelPdm::treeItemRoot() -{ - return m_treeItemRoot; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void UiTreeModelPdm::notifyModelChanged() -{ - QModelIndex startModelIdx = index(0,0); - QModelIndex endModelIdx = index(rowCount(startModelIdx), 0); - - emit dataChanged(startModelIdx, endModelIdx); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -QVariant UiTreeModelPdm::headerData(int section, Qt::Orientation orientation, int role /*= Qt::DisplayRole */) const -{ - if (role != Qt::DisplayRole) - return QVariant(); - - if (section < m_columnHeaders.size()) - { - return m_columnHeaders[section]; - } - - return QVariant(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void UiTreeModelPdm::setColumnHeaders(const QStringList& columnHeaders) -{ - m_columnHeaders = columnHeaders; -} - - - - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -PdmUiTreeItem* caf::UiTreeModelPdm::getTreeItemFromIndex(const QModelIndex& index) -{ - if (index.isValid()) - { - assert(index.internalPointer()); - - PdmUiTreeItem* treeItem = static_cast<PdmUiTreeItem*>(index.internalPointer()); - return treeItem; - } - - return NULL; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -QModelIndex caf::UiTreeModelPdm::getModelIndexFromPdmObjectRecursive(const QModelIndex& currentIndex, const PdmObject * object) const -{ - if (currentIndex.internalPointer()) - { - PdmUiTreeItem* treeItem = static_cast<PdmUiTreeItem*>(currentIndex.internalPointer()); - if (treeItem->dataObject() == object) return currentIndex; - } - - int row; - for (row = 0; row < rowCount(currentIndex); ++row) - { - QModelIndex foundIndex = getModelIndexFromPdmObjectRecursive(index(row, 0, currentIndex), object); - if (foundIndex.isValid()) return foundIndex; - } - return QModelIndex(); -} - - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -QModelIndex caf::UiTreeModelPdm::getModelIndexFromPdmObject( const PdmObject * object) const -{ - QModelIndex foundIndex; - int numRows = rowCount(QModelIndex()); - int r = 0; - while (r < numRows && !foundIndex.isValid()) - { - foundIndex = getModelIndexFromPdmObjectRecursive(index(r, 0, QModelIndex()), object); - ++r; - } - return foundIndex; -} - - - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -PdmUiTreeItem* UiTreeItemBuilderPdm::buildViewItems(PdmUiTreeItem* parentTreeItem, int position, caf::PdmObject* object) -{ - if (object == NULL) - { - return NULL; - } - - - PdmUiTreeItem* objectTreeItem = NULL; - - // Ignore this particular object if the field it resides in is hidden. - // Child objects of this object, however, is not hidden - // Todo: This is a Hack to make oilField disappear. Must be rewritten when - // a more general ui tree building method is in place. - - std::vector<caf::PdmFieldHandle*> parentFields; - object->parentFields(parentFields); - if (parentFields.size() == 1 && parentFields[0]->isUiHidden()) - { - objectTreeItem = parentTreeItem; - } - else - { - objectTreeItem = new PdmUiTreeItem(parentTreeItem, position, object); - } - - std::vector<caf::PdmFieldHandle*> fields; - object->fields(fields); - - std::vector<caf::PdmFieldHandle*>::iterator it; - for (it = fields.begin(); it != fields.end(); it++) - { - caf::PdmFieldHandle* field = *it; - - // Fix for hidden legend definitions. There is only one visible legend definition, the others reside in a hidden container - // Todo: This is a Hack. Must be rewritten when a more general ui tree building method is in place. - // See comment at top of this method. - if (field->isUiChildrenHidden()) - { - continue; - } - - std::vector<caf::PdmObject*> children; - field->childObjects(&children); - size_t i; - for (i = 0; i < children.size(); i++) - { - caf::PdmObject* childObj = children[i]; - assert(childObj); - - // NOTE: -1 as second argument indicates that child objects will be appended to collection - UiTreeItemBuilderPdm::buildViewItems(objectTreeItem, -1, childObj); - } - } - - return objectTreeItem; -} - - - -} // end namespace caf diff --git a/Fwk/AppFwk/cafUserInterface/cafUiTreeModelPdm.h b/Fwk/AppFwk/cafUserInterface/cafUiTreeModelPdm.h deleted file mode 100644 index 2bba5d4210..0000000000 --- a/Fwk/AppFwk/cafUserInterface/cafUiTreeModelPdm.h +++ /dev/null @@ -1,113 +0,0 @@ -//################################################################################################## -// -// Custom Visualization Core library -// Copyright (C) 2011-2013 Ceetron AS -// -// This library may be used under the terms of either the GNU General Public License or -// the GNU Lesser General Public License as follows: -// -// GNU General Public License Usage -// This library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. -// -// See the GNU General Public License at <<http://www.gnu.org/licenses/gpl.html>> -// for more details. -// -// GNU Lesser General Public License Usage -// This library is free software; you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation; either version 2.1 of the License, or -// (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. -// -// See the GNU Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>> -// for more details. -// -//################################################################################################## - - -#pragma once - -#include "cafUiTreeItem.h" - -#include <QAbstractItemModel> -#include <QStringList> - -#include <assert.h> -#include "cafPdmPointer.h" - - -namespace caf -{ - -class PdmObject; - -typedef UiTreeItem<PdmPointer<PdmObject> > PdmUiTreeItem; - -//================================================================================================== -/// -//================================================================================================== -class UiTreeModelPdm : public QAbstractItemModel -{ - Q_OBJECT - -public: - UiTreeModelPdm(QObject* parent); - - void setTreeItemRoot(PdmUiTreeItem* root); - PdmUiTreeItem* treeItemRoot(); - - void emitDataChanged(const QModelIndex& index); - - static PdmUiTreeItem* getTreeItemFromIndex(const QModelIndex& index); - QModelIndex getModelIndexFromPdmObject(const PdmObject* object) const; - void updateUiSubTree(PdmObject* root); - - void notifyModelChanged(); - void setColumnHeaders(const QStringList& columnHeaders); - -public: - // Overrides from QAbstractItemModel - virtual QModelIndex index(int row, int column, const QModelIndex &parentIndex = QModelIndex( )) const; - virtual QModelIndex parent(const QModelIndex &index) const; - virtual int rowCount(const QModelIndex &parentIndex = QModelIndex( ) ) const; - virtual int columnCount(const QModelIndex &parentIndex = QModelIndex( ) ) const; - virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole ) const; - virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const; - - virtual Qt::ItemFlags flags(const QModelIndex &index) const; - virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); - - - virtual bool removeRows_special(int position, int rows, const QModelIndex &parent = QModelIndex()); - -protected: - QModelIndex getModelIndexFromPdmObjectRecursive(const QModelIndex& currentIndex, const PdmObject * object) const; -private: - void updateModelSubTree(const QModelIndex& uiSubTreeRootModelIdx, PdmUiTreeItem* uiModelSubTreeRoot, PdmUiTreeItem* updatedPdmSubTreeRoot); - - PdmUiTreeItem* m_treeItemRoot; - QStringList m_columnHeaders; -}; - - - -//================================================================================================== -/// -//================================================================================================== -class UiTreeItemBuilderPdm -{ -public: - static PdmUiTreeItem* buildViewItems(PdmUiTreeItem* parentTreeItem, int position, caf::PdmObject* object); -}; - -} // End of namespace caf diff --git a/Fwk/AppFwk/cafUserInterface/cafUserInterface_UnitTests/CMakeLists.txt b/Fwk/AppFwk/cafUserInterface/cafUserInterface_UnitTests/CMakeLists.txt new file mode 100644 index 0000000000..beaa8685a6 --- /dev/null +++ b/Fwk/AppFwk/cafUserInterface/cafUserInterface_UnitTests/CMakeLists.txt @@ -0,0 +1,61 @@ +cmake_minimum_required (VERSION 2.8) + +find_package ( Qt4 COMPONENTS QtCore QtGui QtMain ) +include (${QT_USE_FILE}) + +project ( cafUserInterface_UnitTests ) + +include_directories ( + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/.. + + ${cafProjectDataModel_SOURCE_DIR} + ${cafPdmCore_SOURCE_DIR} + ${cafPdmUiCore_SOURCE_DIR} + ${cafPdmXml_SOURCE_DIR} + + ${cafUserInterface_SOURCE_DIR} + +) + + +set( PROJECT_FILES + + cafUserInterface_UnitTests.cpp + + cafPdmUiTreeViewModelTest.cpp + + gtest/gtest-all.cpp +) + +# add the executable +add_executable (${PROJECT_NAME} + ${PROJECT_FILES} +) + +source_group("" FILES ${PROJECT_FILES}) + +message(STATUS ${PROJECT_NAME}" - Qt includes : " ${QT_LIBRARIES}) + +target_link_libraries ( ${PROJECT_NAME} + cafProjectDataModel + cafPdmUiCore + cafPdmCore + cafPdmXml + cafUserInterface + ${QT_LIBRARIES} +) + +# Copy Qt Dlls +if (MSVC) + set (QTLIBLIST QtCore QtGui) + foreach (qtlib ${QTLIBLIST}) + + # Debug + execute_process(COMMAND cmake -E copy_if_different ${QT_BINARY_DIR}/${qtlib}d4.dll ${CMAKE_CURRENT_BINARY_DIR}/Debug/${qtlib}d4.dll) + + # Release + execute_process(COMMAND cmake -E copy_if_different ${QT_BINARY_DIR}/${qtlib}4.dll ${CMAKE_CURRENT_BINARY_DIR}/Release/${qtlib}4.dll) + endforeach( qtlib ) +endif(MSVC) + diff --git a/Fwk/AppFwk/cafUserInterface/cafUserInterface_UnitTests/cafPdmUiTreeViewModelTest.cpp b/Fwk/AppFwk/cafUserInterface/cafUserInterface_UnitTests/cafPdmUiTreeViewModelTest.cpp new file mode 100644 index 0000000000..123fe67b78 --- /dev/null +++ b/Fwk/AppFwk/cafUserInterface/cafUserInterface_UnitTests/cafPdmUiTreeViewModelTest.cpp @@ -0,0 +1,204 @@ + +#include "gtest/gtest.h" + +#include "cafPdmChildArrayField.h" +#include "cafPdmObject.h" +#include "cafPdmUiTreeView.h" + +#include <QModelIndex> +#include <QApplication> + +using namespace caf; + + + +class SimpleObj: public caf::PdmObject +{ + CAF_PDM_HEADER_INIT; +public: + SimpleObj() : PdmObject() + { + CAF_PDM_InitObject("SimpleObj", "", "Tooltip SimpleObj", "WhatsThis SimpleObj"); + + } + ~SimpleObj() {} + +}; +CAF_PDM_SOURCE_INIT(SimpleObj, "SimpleObj"); + + + +class DemoPdmObject: public caf::PdmObject +{ + CAF_PDM_HEADER_INIT; +public: + + DemoPdmObject() + { + CAF_PDM_InitObject("DemoPdmObject", "", "Tooltip DemoPdmObject", "WhatsThis DemoPdmObject"); + + CAF_PDM_InitFieldNoDefault(&m_simpleObjPtrField, "SimpleObjPtrField", "SimpleObjPtrField", "", "Tooltip", "WhatsThis"); + } + + ~DemoPdmObject() + { + m_simpleObjPtrField.deleteAllChildObjects(); + } + + caf::PdmChildArrayField<caf::PdmObjectHandle*> m_simpleObjPtrField; +}; + +CAF_PDM_SOURCE_INIT(DemoPdmObject, "DemoPdmObject"); + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(PdmUiTreeViewModelTest, DeleteOneItemAndVerifyTreeOrdering) +{ + SimpleObj* obj1 = new SimpleObj; + SimpleObj* obj2 = new SimpleObj; + SimpleObj* obj3 = new SimpleObj; + SimpleObj* obj4 = new SimpleObj; + + DemoPdmObject* demoObj = new DemoPdmObject; + demoObj->m_simpleObjPtrField.push_back(obj1); + demoObj->m_simpleObjPtrField.push_back(obj2); + demoObj->m_simpleObjPtrField.push_back(obj3); + demoObj->m_simpleObjPtrField.push_back(obj4); + + PdmUiTreeView treeView; + treeView.setPdmItem(demoObj); + + QModelIndex mi; + mi = treeView.findModelIndex(obj1); + EXPECT_TRUE(mi.isValid()); + + demoObj->m_simpleObjPtrField.removeChildObject(obj1); + demoObj->m_simpleObjPtrField().uiCapability()->updateConnectedEditors(); + + mi = treeView.findModelIndex(obj1); + EXPECT_FALSE(mi.isValid()); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(PdmUiTreeViewModelTest, AddOneItemAndVerifyTreeOrdering) +{ + SimpleObj* obj1 = new SimpleObj; + SimpleObj* obj2 = new SimpleObj; + SimpleObj* obj3 = new SimpleObj; + SimpleObj* obj4 = new SimpleObj; + + DemoPdmObject* demoObj = new DemoPdmObject; + demoObj->m_simpleObjPtrField.push_back(obj1); + demoObj->m_simpleObjPtrField.push_back(obj2); + demoObj->m_simpleObjPtrField.push_back(obj3); + + PdmUiTreeView treeView; + treeView.setPdmItem(demoObj); + + QModelIndex mi; + mi = treeView.findModelIndex(obj4); + EXPECT_FALSE(mi.isValid()); + + demoObj->m_simpleObjPtrField.push_back(obj4); + demoObj->m_simpleObjPtrField().uiCapability()->updateConnectedEditors(); + + mi = treeView.findModelIndex(obj4); + EXPECT_TRUE(mi.isValid()); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(PdmUiTreeViewModelTest, ChangeOrderingAndVerifyTreeOrdering) +{ + SimpleObj* obj1 = new SimpleObj; + SimpleObj* obj2 = new SimpleObj; + SimpleObj* obj3 = new SimpleObj; + SimpleObj* obj4 = new SimpleObj; + + DemoPdmObject* demoObj = new DemoPdmObject; + demoObj->m_simpleObjPtrField.push_back(obj1); + demoObj->m_simpleObjPtrField.push_back(obj2); + demoObj->m_simpleObjPtrField.push_back(obj3); + demoObj->m_simpleObjPtrField.push_back(obj4); + + PdmUiTreeView treeView; + treeView.setPdmItem(demoObj); + + QModelIndex mi; + mi = treeView.findModelIndex(obj4); + EXPECT_EQ(3, mi.row()); + + demoObj->m_simpleObjPtrField.clear(); + demoObj->m_simpleObjPtrField.push_back(obj1); + demoObj->m_simpleObjPtrField.push_back(obj4); + demoObj->m_simpleObjPtrField.push_back(obj3); + demoObj->m_simpleObjPtrField.push_back(obj2); + + demoObj->m_simpleObjPtrField().uiCapability()->updateConnectedEditors(); + + mi = treeView.findModelIndex(obj4); + EXPECT_EQ(1, mi.row()); +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(PdmUiTreeViewModelTest, ChangeDeepInTreeNotifyRootAndVerifyTreeOrdering) +{ + DemoPdmObject* root = new DemoPdmObject; + + SimpleObj* rootObj1 = new SimpleObj; + root->m_simpleObjPtrField.push_back(rootObj1); + + DemoPdmObject* demoObj = new DemoPdmObject; + root->m_simpleObjPtrField.push_back(demoObj); + + SimpleObj* obj1 = new SimpleObj; + SimpleObj* obj2 = new SimpleObj; + SimpleObj* obj3 = new SimpleObj; + SimpleObj* obj4 = new SimpleObj; + demoObj->m_simpleObjPtrField.push_back(obj1); + demoObj->m_simpleObjPtrField.push_back(obj2); + demoObj->m_simpleObjPtrField.push_back(obj3); + demoObj->m_simpleObjPtrField.push_back(obj4); + + PdmUiTreeView treeView; + treeView.setPdmItem(root); + + QModelIndex mi; + mi = treeView.findModelIndex(obj4); + EXPECT_EQ(3, mi.row()); + + demoObj->m_simpleObjPtrField.removeChildObject(obj4); + + root->m_simpleObjPtrField().uiCapability()->updateConnectedEditors(); + + mi = treeView.findModelIndex(obj4); + EXPECT_FALSE(mi.isValid()); +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(PdmUiTreeViewModelTest, DISABLED_PerformanceLargeNumberOfItems) +{ + //int objCount = 20000; + int objCount = 100000; + + DemoPdmObject* demoObj = new DemoPdmObject; + for (int i = 0; i < objCount; i++) + { + demoObj->m_simpleObjPtrField.push_back(new SimpleObj); + } + + PdmUiTreeView treeView; + treeView.setPdmItem(demoObj); + demoObj->m_simpleObjPtrField().uiCapability()->updateConnectedEditors(); +} diff --git a/Fwk/AppFwk/cafUserInterface/cafUserInterface_UnitTests/cafUserInterface_UnitTests.cpp b/Fwk/AppFwk/cafUserInterface/cafUserInterface_UnitTests/cafUserInterface_UnitTests.cpp new file mode 100644 index 0000000000..033eccd4e6 --- /dev/null +++ b/Fwk/AppFwk/cafUserInterface/cafUserInterface_UnitTests/cafUserInterface_UnitTests.cpp @@ -0,0 +1,59 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2014 Ceetron Solutions AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <<http://www.gnu.org/licenses/gpl.html>> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>> +// for more details. +// +//################################################################################################## + + +#include "gtest/gtest.h" +#include <stdio.h> +#include <iostream> +#include <string> + +#include <QApplication> + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +int main(int argc, char **argv) +{ + QApplication app(argc, argv); + + testing::InitGoogleTest(&argc, argv); + int result = RUN_ALL_TESTS(); + + char text[5]; + std::cin.getline(text, 5); + + return result; +} diff --git a/Fwk/AppFwk/cafUserInterface/cafUserInterface_UnitTests/gtest/gtest-all.cpp b/Fwk/AppFwk/cafUserInterface/cafUserInterface_UnitTests/gtest/gtest-all.cpp new file mode 100644 index 0000000000..644479a63c --- /dev/null +++ b/Fwk/AppFwk/cafUserInterface/cafUserInterface_UnitTests/gtest/gtest-all.cpp @@ -0,0 +1,8510 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: mheule@google.com (Markus Heule) +// +// Google C++ Testing Framework (Google Test) +// +// Sometimes it's desirable to build Google Test by compiling a single file. +// This file serves this purpose. + +// This line ensures that gtest.h can be compiled on its own, even +// when it's fused. +#include <gtest/gtest.h> + +// The following lines pull in the real gtest *.cc files. +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: wan@google.com (Zhanyong Wan) +// +// The Google C++ Testing Framework (Google Test) + +// Copyright 2007, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: wan@google.com (Zhanyong Wan) +// +// Utilities for testing Google Test itself and code that uses Google Test +// (e.g. frameworks built on top of Google Test). + +#ifndef GTEST_INCLUDE_GTEST_GTEST_SPI_H_ +#define GTEST_INCLUDE_GTEST_GTEST_SPI_H_ + + +namespace testing { + +// This helper class can be used to mock out Google Test failure reporting +// so that we can test Google Test or code that builds on Google Test. +// +// An object of this class appends a TestPartResult object to the +// TestPartResultArray object given in the constructor whenever a Google Test +// failure is reported. It can either intercept only failures that are +// generated in the same thread that created this object or it can intercept +// all generated failures. The scope of this mock object can be controlled with +// the second argument to the two arguments constructor. +class GTEST_API_ ScopedFakeTestPartResultReporter + : public TestPartResultReporterInterface { + public: + // The two possible mocking modes of this object. + enum InterceptMode { + INTERCEPT_ONLY_CURRENT_THREAD, // Intercepts only thread local failures. + INTERCEPT_ALL_THREADS // Intercepts all failures. + }; + + // The c'tor sets this object as the test part result reporter used + // by Google Test. The 'result' parameter specifies where to report the + // results. This reporter will only catch failures generated in the current + // thread. DEPRECATED + explicit ScopedFakeTestPartResultReporter(TestPartResultArray* result); + + // Same as above, but you can choose the interception scope of this object. + ScopedFakeTestPartResultReporter(InterceptMode intercept_mode, + TestPartResultArray* result); + + // The d'tor restores the previous test part result reporter. + virtual ~ScopedFakeTestPartResultReporter(); + + // Appends the TestPartResult object to the TestPartResultArray + // received in the constructor. + // + // This method is from the TestPartResultReporterInterface + // interface. + virtual void ReportTestPartResult(const TestPartResult& result); + private: + void Init(); + + const InterceptMode intercept_mode_; + TestPartResultReporterInterface* old_reporter_; + TestPartResultArray* const result_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedFakeTestPartResultReporter); +}; + +namespace internal { + +// A helper class for implementing EXPECT_FATAL_FAILURE() and +// EXPECT_NONFATAL_FAILURE(). Its destructor verifies that the given +// TestPartResultArray contains exactly one failure that has the given +// type and contains the given substring. If that's not the case, a +// non-fatal failure will be generated. +class GTEST_API_ SingleFailureChecker { + public: + // The constructor remembers the arguments. + SingleFailureChecker(const TestPartResultArray* results, + TestPartResult::Type type, + const char* substr); + ~SingleFailureChecker(); + private: + const TestPartResultArray* const results_; + const TestPartResult::Type type_; + const String substr_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(SingleFailureChecker); +}; + +} // namespace internal + +} // namespace testing + +// A set of macros for testing Google Test assertions or code that's expected +// to generate Google Test fatal failures. It verifies that the given +// statement will cause exactly one fatal Google Test failure with 'substr' +// being part of the failure message. +// +// There are two different versions of this macro. EXPECT_FATAL_FAILURE only +// affects and considers failures generated in the current thread and +// EXPECT_FATAL_FAILURE_ON_ALL_THREADS does the same but for all threads. +// +// The verification of the assertion is done correctly even when the statement +// throws an exception or aborts the current function. +// +// Known restrictions: +// - 'statement' cannot reference local non-static variables or +// non-static members of the current object. +// - 'statement' cannot return a value. +// - You cannot stream a failure message to this macro. +// +// Note that even though the implementations of the following two +// macros are much alike, we cannot refactor them to use a common +// helper macro, due to some peculiarity in how the preprocessor +// works. The AcceptsMacroThatExpandsToUnprotectedComma test in +// gtest_unittest.cc will fail to compile if we do that. +#define EXPECT_FATAL_FAILURE(statement, substr) \ + do { \ + class GTestExpectFatalFailureHelper {\ + public:\ + static void Execute() { statement; }\ + };\ + ::testing::TestPartResultArray gtest_failures;\ + ::testing::internal::SingleFailureChecker gtest_checker(\ + >est_failures, ::testing::TestPartResult::kFatalFailure, (substr));\ + {\ + ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ + ::testing::ScopedFakeTestPartResultReporter:: \ + INTERCEPT_ONLY_CURRENT_THREAD, >est_failures);\ + GTestExpectFatalFailureHelper::Execute();\ + }\ + } while (::testing::internal::AlwaysFalse()) + +#define EXPECT_FATAL_FAILURE_ON_ALL_THREADS(statement, substr) \ + do { \ + class GTestExpectFatalFailureHelper {\ + public:\ + static void Execute() { statement; }\ + };\ + ::testing::TestPartResultArray gtest_failures;\ + ::testing::internal::SingleFailureChecker gtest_checker(\ + >est_failures, ::testing::TestPartResult::kFatalFailure, (substr));\ + {\ + ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ + ::testing::ScopedFakeTestPartResultReporter:: \ + INTERCEPT_ALL_THREADS, >est_failures);\ + GTestExpectFatalFailureHelper::Execute();\ + }\ + } while (::testing::internal::AlwaysFalse()) + +// A macro for testing Google Test assertions or code that's expected to +// generate Google Test non-fatal failures. It asserts that the given +// statement will cause exactly one non-fatal Google Test failure with 'substr' +// being part of the failure message. +// +// There are two different versions of this macro. EXPECT_NONFATAL_FAILURE only +// affects and considers failures generated in the current thread and +// EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS does the same but for all threads. +// +// 'statement' is allowed to reference local variables and members of +// the current object. +// +// The verification of the assertion is done correctly even when the statement +// throws an exception or aborts the current function. +// +// Known restrictions: +// - You cannot stream a failure message to this macro. +// +// Note that even though the implementations of the following two +// macros are much alike, we cannot refactor them to use a common +// helper macro, due to some peculiarity in how the preprocessor +// works. If we do that, the code won't compile when the user gives +// EXPECT_NONFATAL_FAILURE() a statement that contains a macro that +// expands to code containing an unprotected comma. The +// AcceptsMacroThatExpandsToUnprotectedComma test in gtest_unittest.cc +// catches that. +// +// For the same reason, we have to write +// if (::testing::internal::AlwaysTrue()) { statement; } +// instead of +// GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement) +// to avoid an MSVC warning on unreachable code. +#define EXPECT_NONFATAL_FAILURE(statement, substr) \ + do {\ + ::testing::TestPartResultArray gtest_failures;\ + ::testing::internal::SingleFailureChecker gtest_checker(\ + >est_failures, ::testing::TestPartResult::kNonFatalFailure, \ + (substr));\ + {\ + ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ + ::testing::ScopedFakeTestPartResultReporter:: \ + INTERCEPT_ONLY_CURRENT_THREAD, >est_failures);\ + if (::testing::internal::AlwaysTrue()) { statement; }\ + }\ + } while (::testing::internal::AlwaysFalse()) + +#define EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(statement, substr) \ + do {\ + ::testing::TestPartResultArray gtest_failures;\ + ::testing::internal::SingleFailureChecker gtest_checker(\ + >est_failures, ::testing::TestPartResult::kNonFatalFailure, \ + (substr));\ + {\ + ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ + ::testing::ScopedFakeTestPartResultReporter::INTERCEPT_ALL_THREADS,\ + >est_failures);\ + if (::testing::internal::AlwaysTrue()) { statement; }\ + }\ + } while (::testing::internal::AlwaysFalse()) + +#endif // GTEST_INCLUDE_GTEST_GTEST_SPI_H_ + +#include <ctype.h> +#include <math.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <wchar.h> +#include <wctype.h> + +#include <algorithm> +#include <ostream> +#include <sstream> +#include <vector> + +#if GTEST_OS_LINUX + +// TODO(kenton@google.com): Use autoconf to detect availability of +// gettimeofday(). +#define GTEST_HAS_GETTIMEOFDAY_ 1 + +#include <fcntl.h> +#include <limits.h> +#include <sched.h> +// Declares vsnprintf(). This header is not available on Windows. +#include <strings.h> +#include <sys/mman.h> +#include <sys/time.h> +#include <unistd.h> +#include <string> +#include <vector> + +#elif GTEST_OS_SYMBIAN +#define GTEST_HAS_GETTIMEOFDAY_ 1 +#include <sys/time.h> // NOLINT + +#elif GTEST_OS_ZOS +#define GTEST_HAS_GETTIMEOFDAY_ 1 +#include <sys/time.h> // NOLINT + +// On z/OS we additionally need strings.h for strcasecmp. +#include <strings.h> // NOLINT + +#elif GTEST_OS_WINDOWS_MOBILE // We are on Windows CE. + +#include <windows.h> // NOLINT + +#elif GTEST_OS_WINDOWS // We are on Windows proper. + +#include <io.h> // NOLINT +#include <sys/timeb.h> // NOLINT +#include <sys/types.h> // NOLINT +#include <sys/stat.h> // NOLINT + +#if GTEST_OS_WINDOWS_MINGW +// MinGW has gettimeofday() but not _ftime64(). +// TODO(kenton@google.com): Use autoconf to detect availability of +// gettimeofday(). +// TODO(kenton@google.com): There are other ways to get the time on +// Windows, like GetTickCount() or GetSystemTimeAsFileTime(). MinGW +// supports these. consider using them instead. +#define GTEST_HAS_GETTIMEOFDAY_ 1 +#include <sys/time.h> // NOLINT +#endif // GTEST_OS_WINDOWS_MINGW + +// cpplint thinks that the header is already included, so we want to +// silence it. +#include <windows.h> // NOLINT + +#else + +// Assume other platforms have gettimeofday(). +// TODO(kenton@google.com): Use autoconf to detect availability of +// gettimeofday(). +#define GTEST_HAS_GETTIMEOFDAY_ 1 + +// cpplint thinks that the header is already included, so we want to +// silence it. +#include <sys/time.h> // NOLINT +#include <unistd.h> // NOLINT + +#endif // GTEST_OS_LINUX + +#if GTEST_HAS_EXCEPTIONS +#include <stdexcept> +#endif + +// Indicates that this translation unit is part of Google Test's +// implementation. It must come before gtest-internal-inl.h is +// included, or there will be a compiler error. This trick is to +// prevent a user from accidentally including gtest-internal-inl.h in +// his code. +#define GTEST_IMPLEMENTATION_ 1 +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Utility functions and classes used by the Google C++ testing framework. +// +// Author: wan@google.com (Zhanyong Wan) +// +// This file contains purely Google Test's internal implementation. Please +// DO NOT #INCLUDE IT IN A USER PROGRAM. + +#ifndef GTEST_SRC_GTEST_INTERNAL_INL_H_ +#define GTEST_SRC_GTEST_INTERNAL_INL_H_ + +// GTEST_IMPLEMENTATION_ is defined to 1 iff the current translation unit is +// part of Google Test's implementation; otherwise it's undefined. +#if !GTEST_IMPLEMENTATION_ +// A user is trying to include this from his code - just say no. +#error "gtest-internal-inl.h is part of Google Test's internal implementation." +#error "It must not be included except by Google Test itself." +#endif // GTEST_IMPLEMENTATION_ + +#ifndef _WIN32_WCE +#include <errno.h> +#endif // !_WIN32_WCE +#include <stddef.h> +#include <stdlib.h> // For strtoll/_strtoul64/malloc/free. +#include <string.h> // For memmove. + +#include <algorithm> +#include <string> +#include <vector> + + +#if GTEST_OS_WINDOWS +#include <windows.h> // For DWORD. +#endif // GTEST_OS_WINDOWS + + +namespace testing { + +// Declares the flags. +// +// We don't want the users to modify this flag in the code, but want +// Google Test's own unit tests to be able to access it. Therefore we +// declare it here as opposed to in gtest.h. +GTEST_DECLARE_bool_(death_test_use_fork); + +namespace internal { + +// The value of GetTestTypeId() as seen from within the Google Test +// library. This is solely for testing GetTestTypeId(). +GTEST_API_ extern const TypeId kTestTypeIdInGoogleTest; + +// Names of the flags (needed for parsing Google Test flags). +const char kAlsoRunDisabledTestsFlag[] = "also_run_disabled_tests"; +const char kBreakOnFailureFlag[] = "break_on_failure"; +const char kCatchExceptionsFlag[] = "catch_exceptions"; +const char kColorFlag[] = "color"; +const char kFilterFlag[] = "filter"; +const char kListTestsFlag[] = "list_tests"; +const char kOutputFlag[] = "output"; +const char kPrintTimeFlag[] = "print_time"; +const char kRandomSeedFlag[] = "random_seed"; +const char kRepeatFlag[] = "repeat"; +const char kShuffleFlag[] = "shuffle"; +const char kStackTraceDepthFlag[] = "stack_trace_depth"; +const char kThrowOnFailureFlag[] = "throw_on_failure"; + +// A valid random seed must be in [1, kMaxRandomSeed]. +const int kMaxRandomSeed = 99999; + +// g_help_flag is true iff the --help flag or an equivalent form is +// specified on the command line. +GTEST_API_ extern bool g_help_flag; + +// Returns the current time in milliseconds. +GTEST_API_ TimeInMillis GetTimeInMillis(); + +// Returns true iff Google Test should use colors in the output. +GTEST_API_ bool ShouldUseColor(bool stdout_is_tty); + +// Formats the given time in milliseconds as seconds. +GTEST_API_ std::string FormatTimeInMillisAsSeconds(TimeInMillis ms); + +// Parses a string for an Int32 flag, in the form of "--flag=value". +// +// On success, stores the value of the flag in *value, and returns +// true. On failure, returns false without changing *value. +GTEST_API_ bool ParseInt32Flag( + const char* str, const char* flag, Int32* value); + +// Returns a random seed in range [1, kMaxRandomSeed] based on the +// given --gtest_random_seed flag value. +inline int GetRandomSeedFromFlag(Int32 random_seed_flag) { + const unsigned int raw_seed = (random_seed_flag == 0) ? + static_cast<unsigned int>(GetTimeInMillis()) : + static_cast<unsigned int>(random_seed_flag); + + // Normalizes the actual seed to range [1, kMaxRandomSeed] such that + // it's easy to type. + const int normalized_seed = + static_cast<int>((raw_seed - 1U) % + static_cast<unsigned int>(kMaxRandomSeed)) + 1; + return normalized_seed; +} + +// Returns the first valid random seed after 'seed'. The behavior is +// undefined if 'seed' is invalid. The seed after kMaxRandomSeed is +// considered to be 1. +inline int GetNextRandomSeed(int seed) { + GTEST_CHECK_(1 <= seed && seed <= kMaxRandomSeed) + << "Invalid random seed " << seed << " - must be in [1, " + << kMaxRandomSeed << "]."; + const int next_seed = seed + 1; + return (next_seed > kMaxRandomSeed) ? 1 : next_seed; +} + +// This class saves the values of all Google Test flags in its c'tor, and +// restores them in its d'tor. +class GTestFlagSaver { + public: + // The c'tor. + GTestFlagSaver() { + also_run_disabled_tests_ = GTEST_FLAG(also_run_disabled_tests); + break_on_failure_ = GTEST_FLAG(break_on_failure); + catch_exceptions_ = GTEST_FLAG(catch_exceptions); + color_ = GTEST_FLAG(color); + death_test_style_ = GTEST_FLAG(death_test_style); + death_test_use_fork_ = GTEST_FLAG(death_test_use_fork); + filter_ = GTEST_FLAG(filter); + internal_run_death_test_ = GTEST_FLAG(internal_run_death_test); + list_tests_ = GTEST_FLAG(list_tests); + output_ = GTEST_FLAG(output); + print_time_ = GTEST_FLAG(print_time); + random_seed_ = GTEST_FLAG(random_seed); + repeat_ = GTEST_FLAG(repeat); + shuffle_ = GTEST_FLAG(shuffle); + stack_trace_depth_ = GTEST_FLAG(stack_trace_depth); + throw_on_failure_ = GTEST_FLAG(throw_on_failure); + } + + // The d'tor is not virtual. DO NOT INHERIT FROM THIS CLASS. + ~GTestFlagSaver() { + GTEST_FLAG(also_run_disabled_tests) = also_run_disabled_tests_; + GTEST_FLAG(break_on_failure) = break_on_failure_; + GTEST_FLAG(catch_exceptions) = catch_exceptions_; + GTEST_FLAG(color) = color_; + GTEST_FLAG(death_test_style) = death_test_style_; + GTEST_FLAG(death_test_use_fork) = death_test_use_fork_; + GTEST_FLAG(filter) = filter_; + GTEST_FLAG(internal_run_death_test) = internal_run_death_test_; + GTEST_FLAG(list_tests) = list_tests_; + GTEST_FLAG(output) = output_; + GTEST_FLAG(print_time) = print_time_; + GTEST_FLAG(random_seed) = random_seed_; + GTEST_FLAG(repeat) = repeat_; + GTEST_FLAG(shuffle) = shuffle_; + GTEST_FLAG(stack_trace_depth) = stack_trace_depth_; + GTEST_FLAG(throw_on_failure) = throw_on_failure_; + } + private: + // Fields for saving the original values of flags. + bool also_run_disabled_tests_; + bool break_on_failure_; + bool catch_exceptions_; + String color_; + String death_test_style_; + bool death_test_use_fork_; + String filter_; + String internal_run_death_test_; + bool list_tests_; + String output_; + bool print_time_; + bool pretty_; + internal::Int32 random_seed_; + internal::Int32 repeat_; + bool shuffle_; + internal::Int32 stack_trace_depth_; + bool throw_on_failure_; +} GTEST_ATTRIBUTE_UNUSED_; + +// Converts a Unicode code point to a narrow string in UTF-8 encoding. +// code_point parameter is of type UInt32 because wchar_t may not be +// wide enough to contain a code point. +// The output buffer str must containt at least 32 characters. +// The function returns the address of the output buffer. +// If the code_point is not a valid Unicode code point +// (i.e. outside of Unicode range U+0 to U+10FFFF) it will be output +// as '(Invalid Unicode 0xXXXXXXXX)'. +GTEST_API_ char* CodePointToUtf8(UInt32 code_point, char* str); + +// Converts a wide string to a narrow string in UTF-8 encoding. +// The wide string is assumed to have the following encoding: +// UTF-16 if sizeof(wchar_t) == 2 (on Windows, Cygwin, Symbian OS) +// UTF-32 if sizeof(wchar_t) == 4 (on Linux) +// Parameter str points to a null-terminated wide string. +// Parameter num_chars may additionally limit the number +// of wchar_t characters processed. -1 is used when the entire string +// should be processed. +// If the string contains code points that are not valid Unicode code points +// (i.e. outside of Unicode range U+0 to U+10FFFF) they will be output +// as '(Invalid Unicode 0xXXXXXXXX)'. If the string is in UTF16 encoding +// and contains invalid UTF-16 surrogate pairs, values in those pairs +// will be encoded as individual Unicode characters from Basic Normal Plane. +GTEST_API_ String WideStringToUtf8(const wchar_t* str, int num_chars); + +// Reads the GTEST_SHARD_STATUS_FILE environment variable, and creates the file +// if the variable is present. If a file already exists at this location, this +// function will write over it. If the variable is present, but the file cannot +// be created, prints an error and exits. +void WriteToShardStatusFileIfNeeded(); + +// Checks whether sharding is enabled by examining the relevant +// environment variable values. If the variables are present, +// but inconsistent (e.g., shard_index >= total_shards), prints +// an error and exits. If in_subprocess_for_death_test, sharding is +// disabled because it must only be applied to the original test +// process. Otherwise, we could filter out death tests we intended to execute. +GTEST_API_ bool ShouldShard(const char* total_shards_str, + const char* shard_index_str, + bool in_subprocess_for_death_test); + +// Parses the environment variable var as an Int32. If it is unset, +// returns default_val. If it is not an Int32, prints an error and +// and aborts. +GTEST_API_ Int32 Int32FromEnvOrDie(const char* env_var, Int32 default_val); + +// Given the total number of shards, the shard index, and the test id, +// returns true iff the test should be run on this shard. The test id is +// some arbitrary but unique non-negative integer assigned to each test +// method. Assumes that 0 <= shard_index < total_shards. +GTEST_API_ bool ShouldRunTestOnShard( + int total_shards, int shard_index, int test_id); + +// STL container utilities. + +// Returns the number of elements in the given container that satisfy +// the given predicate. +template <class Container, typename Predicate> +inline int CountIf(const Container& c, Predicate predicate) { + return static_cast<int>(std::count_if(c.begin(), c.end(), predicate)); +} + +// Applies a function/functor to each element in the container. +template <class Container, typename Functor> +void ForEach(const Container& c, Functor functor) { + std::for_each(c.begin(), c.end(), functor); +} + +// Returns the i-th element of the vector, or default_value if i is not +// in range [0, v.size()). +template <typename E> +inline E GetElementOr(const std::vector<E>& v, int i, E default_value) { + return (i < 0 || i >= static_cast<int>(v.size())) ? default_value : v[i]; +} + +// Performs an in-place shuffle of a range of the vector's elements. +// 'begin' and 'end' are element indices as an STL-style range; +// i.e. [begin, end) are shuffled, where 'end' == size() means to +// shuffle to the end of the vector. +template <typename E> +void ShuffleRange(internal::Random* random, int begin, int end, + std::vector<E>* v) { + const int size = static_cast<int>(v->size()); + GTEST_CHECK_(0 <= begin && begin <= size) + << "Invalid shuffle range start " << begin << ": must be in range [0, " + << size << "]."; + GTEST_CHECK_(begin <= end && end <= size) + << "Invalid shuffle range finish " << end << ": must be in range [" + << begin << ", " << size << "]."; + + // Fisher-Yates shuffle, from + // http://en.wikipedia.org/wiki/Fisher-Yates_shuffle + for (int range_width = end - begin; range_width >= 2; range_width--) { + const int last_in_range = begin + range_width - 1; + const int selected = begin + random->Generate(range_width); + std::swap((*v)[selected], (*v)[last_in_range]); + } +} + +// Performs an in-place shuffle of the vector's elements. +template <typename E> +inline void Shuffle(internal::Random* random, std::vector<E>* v) { + ShuffleRange(random, 0, static_cast<int>(v->size()), v); +} + +// A function for deleting an object. Handy for being used as a +// functor. +template <typename T> +static void Delete(T* x) { + delete x; +} + +// A predicate that checks the key of a TestProperty against a known key. +// +// TestPropertyKeyIs is copyable. +class TestPropertyKeyIs { + public: + // Constructor. + // + // TestPropertyKeyIs has NO default constructor. + explicit TestPropertyKeyIs(const char* key) + : key_(key) {} + + // Returns true iff the test name of test property matches on key_. + bool operator()(const TestProperty& test_property) const { + return String(test_property.key()).Compare(key_) == 0; + } + + private: + String key_; +}; + +class TestInfoImpl { + public: + TestInfoImpl(TestInfo* parent, const char* test_case_name, + const char* name, const char* test_case_comment, + const char* comment, TypeId fixture_class_id, + internal::TestFactoryBase* factory); + ~TestInfoImpl(); + + // Returns true if this test should run. + bool should_run() const { return should_run_; } + + // Sets the should_run member. + void set_should_run(bool should) { should_run_ = should; } + + // Returns true if this test is disabled. Disabled tests are not run. + bool is_disabled() const { return is_disabled_; } + + // Sets the is_disabled member. + void set_is_disabled(bool is) { is_disabled_ = is; } + + // Returns true if this test matches the filter specified by the user. + bool matches_filter() const { return matches_filter_; } + + // Sets the matches_filter member. + void set_matches_filter(bool matches) { matches_filter_ = matches; } + + // Returns the test case name. + const char* test_case_name() const { return test_case_name_.c_str(); } + + // Returns the test name. + const char* name() const { return name_.c_str(); } + + // Returns the test case comment. + const char* test_case_comment() const { return test_case_comment_.c_str(); } + + // Returns the test comment. + const char* comment() const { return comment_.c_str(); } + + // Returns the ID of the test fixture class. + TypeId fixture_class_id() const { return fixture_class_id_; } + + // Returns the test result. + TestResult* result() { return &result_; } + const TestResult* result() const { return &result_; } + + // Creates the test object, runs it, records its result, and then + // deletes it. + void Run(); + + // Clears the test result. + void ClearResult() { result_.Clear(); } + + // Clears the test result in the given TestInfo object. + static void ClearTestResult(TestInfo * test_info) { + test_info->impl()->ClearResult(); + } + + private: + // These fields are immutable properties of the test. + TestInfo* const parent_; // The owner of this object + const String test_case_name_; // Test case name + const String name_; // Test name + const String test_case_comment_; // Test case comment + const String comment_; // Test comment + const TypeId fixture_class_id_; // ID of the test fixture class + bool should_run_; // True iff this test should run + bool is_disabled_; // True iff this test is disabled + bool matches_filter_; // True if this test matches the + // user-specified filter. + internal::TestFactoryBase* const factory_; // The factory that creates + // the test object + + // This field is mutable and needs to be reset before running the + // test for the second time. + TestResult result_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestInfoImpl); +}; + +// Class UnitTestOptions. +// +// This class contains functions for processing options the user +// specifies when running the tests. It has only static members. +// +// In most cases, the user can specify an option using either an +// environment variable or a command line flag. E.g. you can set the +// test filter using either GTEST_FILTER or --gtest_filter. If both +// the variable and the flag are present, the latter overrides the +// former. +class GTEST_API_ UnitTestOptions { + public: + // Functions for processing the gtest_output flag. + + // Returns the output format, or "" for normal printed output. + static String GetOutputFormat(); + + // Returns the absolute path of the requested output file, or the + // default (test_detail.xml in the original working directory) if + // none was explicitly specified. + static String GetAbsolutePathToOutputFile(); + + // Functions for processing the gtest_filter flag. + + // Returns true iff the wildcard pattern matches the string. The + // first ':' or '\0' character in pattern marks the end of it. + // + // This recursive algorithm isn't very efficient, but is clear and + // works well enough for matching test names, which are short. + static bool PatternMatchesString(const char *pattern, const char *str); + + // Returns true iff the user-specified filter matches the test case + // name and the test name. + static bool FilterMatchesTest(const String &test_case_name, + const String &test_name); + +#if GTEST_OS_WINDOWS + // Function for supporting the gtest_catch_exception flag. + + // Returns EXCEPTION_EXECUTE_HANDLER if Google Test should handle the + // given SEH exception, or EXCEPTION_CONTINUE_SEARCH otherwise. + // This function is useful as an __except condition. + static int GTestShouldProcessSEH(DWORD exception_code); +#endif // GTEST_OS_WINDOWS + + // Returns true if "name" matches the ':' separated list of glob-style + // filters in "filter". + static bool MatchesFilter(const String& name, const char* filter); +}; + +// Returns the current application's name, removing directory path if that +// is present. Used by UnitTestOptions::GetOutputFile. +GTEST_API_ FilePath GetCurrentExecutableName(); + +// The role interface for getting the OS stack trace as a string. +class OsStackTraceGetterInterface { + public: + OsStackTraceGetterInterface() {} + virtual ~OsStackTraceGetterInterface() {} + + // Returns the current OS stack trace as a String. Parameters: + // + // max_depth - the maximum number of stack frames to be included + // in the trace. + // skip_count - the number of top frames to be skipped; doesn't count + // against max_depth. + virtual String CurrentStackTrace(int max_depth, int skip_count) = 0; + + // UponLeavingGTest() should be called immediately before Google Test calls + // user code. It saves some information about the current stack that + // CurrentStackTrace() will use to find and hide Google Test stack frames. + virtual void UponLeavingGTest() = 0; + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(OsStackTraceGetterInterface); +}; + +// A working implementation of the OsStackTraceGetterInterface interface. +class OsStackTraceGetter : public OsStackTraceGetterInterface { + public: + OsStackTraceGetter() : caller_frame_(NULL) {} + virtual String CurrentStackTrace(int max_depth, int skip_count); + virtual void UponLeavingGTest(); + + // This string is inserted in place of stack frames that are part of + // Google Test's implementation. + static const char* const kElidedFramesMarker; + + private: + Mutex mutex_; // protects all internal state + + // We save the stack frame below the frame that calls user code. + // We do this because the address of the frame immediately below + // the user code changes between the call to UponLeavingGTest() + // and any calls to CurrentStackTrace() from within the user code. + void* caller_frame_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(OsStackTraceGetter); +}; + +// Information about a Google Test trace point. +struct TraceInfo { + const char* file; + int line; + String message; +}; + +// This is the default global test part result reporter used in UnitTestImpl. +// This class should only be used by UnitTestImpl. +class DefaultGlobalTestPartResultReporter + : public TestPartResultReporterInterface { + public: + explicit DefaultGlobalTestPartResultReporter(UnitTestImpl* unit_test); + // Implements the TestPartResultReporterInterface. Reports the test part + // result in the current test. + virtual void ReportTestPartResult(const TestPartResult& result); + + private: + UnitTestImpl* const unit_test_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultGlobalTestPartResultReporter); +}; + +// This is the default per thread test part result reporter used in +// UnitTestImpl. This class should only be used by UnitTestImpl. +class DefaultPerThreadTestPartResultReporter + : public TestPartResultReporterInterface { + public: + explicit DefaultPerThreadTestPartResultReporter(UnitTestImpl* unit_test); + // Implements the TestPartResultReporterInterface. The implementation just + // delegates to the current global test part result reporter of *unit_test_. + virtual void ReportTestPartResult(const TestPartResult& result); + + private: + UnitTestImpl* const unit_test_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultPerThreadTestPartResultReporter); +}; + +// The private implementation of the UnitTest class. We don't protect +// the methods under a mutex, as this class is not accessible by a +// user and the UnitTest class that delegates work to this class does +// proper locking. +class GTEST_API_ UnitTestImpl { + public: + explicit UnitTestImpl(UnitTest* parent); + virtual ~UnitTestImpl(); + + // There are two different ways to register your own TestPartResultReporter. + // You can register your own repoter to listen either only for test results + // from the current thread or for results from all threads. + // By default, each per-thread test result repoter just passes a new + // TestPartResult to the global test result reporter, which registers the + // test part result for the currently running test. + + // Returns the global test part result reporter. + TestPartResultReporterInterface* GetGlobalTestPartResultReporter(); + + // Sets the global test part result reporter. + void SetGlobalTestPartResultReporter( + TestPartResultReporterInterface* reporter); + + // Returns the test part result reporter for the current thread. + TestPartResultReporterInterface* GetTestPartResultReporterForCurrentThread(); + + // Sets the test part result reporter for the current thread. + void SetTestPartResultReporterForCurrentThread( + TestPartResultReporterInterface* reporter); + + // Gets the number of successful test cases. + int successful_test_case_count() const; + + // Gets the number of failed test cases. + int failed_test_case_count() const; + + // Gets the number of all test cases. + int total_test_case_count() const; + + // Gets the number of all test cases that contain at least one test + // that should run. + int test_case_to_run_count() const; + + // Gets the number of successful tests. + int successful_test_count() const; + + // Gets the number of failed tests. + int failed_test_count() const; + + // Gets the number of disabled tests. + int disabled_test_count() const; + + // Gets the number of all tests. + int total_test_count() const; + + // Gets the number of tests that should run. + int test_to_run_count() const; + + // Gets the elapsed time, in milliseconds. + TimeInMillis elapsed_time() const { return elapsed_time_; } + + // Returns true iff the unit test passed (i.e. all test cases passed). + bool Passed() const { return !Failed(); } + + // Returns true iff the unit test failed (i.e. some test case failed + // or something outside of all tests failed). + bool Failed() const { + return failed_test_case_count() > 0 || ad_hoc_test_result()->Failed(); + } + + // Gets the i-th test case among all the test cases. i can range from 0 to + // total_test_case_count() - 1. If i is not in that range, returns NULL. + const TestCase* GetTestCase(int i) const { + const int index = GetElementOr(test_case_indices_, i, -1); + return index < 0 ? NULL : test_cases_[i]; + } + + // Gets the i-th test case among all the test cases. i can range from 0 to + // total_test_case_count() - 1. If i is not in that range, returns NULL. + TestCase* GetMutableTestCase(int i) { + const int index = GetElementOr(test_case_indices_, i, -1); + return index < 0 ? NULL : test_cases_[index]; + } + + // Provides access to the event listener list. + TestEventListeners* listeners() { return &listeners_; } + + // Returns the TestResult for the test that's currently running, or + // the TestResult for the ad hoc test if no test is running. + TestResult* current_test_result(); + + // Returns the TestResult for the ad hoc test. + const TestResult* ad_hoc_test_result() const { return &ad_hoc_test_result_; } + + // Sets the OS stack trace getter. + // + // Does nothing if the input and the current OS stack trace getter + // are the same; otherwise, deletes the old getter and makes the + // input the current getter. + void set_os_stack_trace_getter(OsStackTraceGetterInterface* getter); + + // Returns the current OS stack trace getter if it is not NULL; + // otherwise, creates an OsStackTraceGetter, makes it the current + // getter, and returns it. + OsStackTraceGetterInterface* os_stack_trace_getter(); + + // Returns the current OS stack trace as a String. + // + // The maximum number of stack frames to be included is specified by + // the gtest_stack_trace_depth flag. The skip_count parameter + // specifies the number of top frames to be skipped, which doesn't + // count against the number of frames to be included. + // + // For example, if Foo() calls Bar(), which in turn calls + // CurrentOsStackTraceExceptTop(1), Foo() will be included in the + // trace but Bar() and CurrentOsStackTraceExceptTop() won't. + String CurrentOsStackTraceExceptTop(int skip_count); + + // Finds and returns a TestCase with the given name. If one doesn't + // exist, creates one and returns it. + // + // Arguments: + // + // test_case_name: name of the test case + // set_up_tc: pointer to the function that sets up the test case + // tear_down_tc: pointer to the function that tears down the test case + TestCase* GetTestCase(const char* test_case_name, + const char* comment, + Test::SetUpTestCaseFunc set_up_tc, + Test::TearDownTestCaseFunc tear_down_tc); + + // Adds a TestInfo to the unit test. + // + // Arguments: + // + // set_up_tc: pointer to the function that sets up the test case + // tear_down_tc: pointer to the function that tears down the test case + // test_info: the TestInfo object + void AddTestInfo(Test::SetUpTestCaseFunc set_up_tc, + Test::TearDownTestCaseFunc tear_down_tc, + TestInfo * test_info) { + // In order to support thread-safe death tests, we need to + // remember the original working directory when the test program + // was first invoked. We cannot do this in RUN_ALL_TESTS(), as + // the user may have changed the current directory before calling + // RUN_ALL_TESTS(). Therefore we capture the current directory in + // AddTestInfo(), which is called to register a TEST or TEST_F + // before main() is reached. + if (original_working_dir_.IsEmpty()) { + original_working_dir_.Set(FilePath::GetCurrentDir()); + GTEST_CHECK_(!original_working_dir_.IsEmpty()) + << "Failed to get the current working directory."; + } + + GetTestCase(test_info->test_case_name(), + test_info->test_case_comment(), + set_up_tc, + tear_down_tc)->AddTestInfo(test_info); + } + +#if GTEST_HAS_PARAM_TEST + // Returns ParameterizedTestCaseRegistry object used to keep track of + // value-parameterized tests and instantiate and register them. + internal::ParameterizedTestCaseRegistry& parameterized_test_registry() { + return parameterized_test_registry_; + } +#endif // GTEST_HAS_PARAM_TEST + + // Sets the TestCase object for the test that's currently running. + void set_current_test_case(TestCase* a_current_test_case) { + current_test_case_ = a_current_test_case; + } + + // Sets the TestInfo object for the test that's currently running. If + // current_test_info is NULL, the assertion results will be stored in + // ad_hoc_test_result_. + void set_current_test_info(TestInfo* a_current_test_info) { + current_test_info_ = a_current_test_info; + } + + // Registers all parameterized tests defined using TEST_P and + // INSTANTIATE_TEST_P, creating regular tests for each test/parameter + // combination. This method can be called more then once; it has + // guards protecting from registering the tests more then once. + // If value-parameterized tests are disabled, RegisterParameterizedTests + // is present but does nothing. + void RegisterParameterizedTests(); + + // Runs all tests in this UnitTest object, prints the result, and + // returns 0 if all tests are successful, or 1 otherwise. If any + // exception is thrown during a test on Windows, this test is + // considered to be failed, but the rest of the tests will still be + // run. (We disable exceptions on Linux and Mac OS X, so the issue + // doesn't apply there.) + int RunAllTests(); + + // Clears the results of all tests, including the ad hoc test. + void ClearResult() { + ForEach(test_cases_, TestCase::ClearTestCaseResult); + ad_hoc_test_result_.Clear(); + } + + enum ReactionToSharding { + HONOR_SHARDING_PROTOCOL, + IGNORE_SHARDING_PROTOCOL + }; + + // Matches the full name of each test against the user-specified + // filter to decide whether the test should run, then records the + // result in each TestCase and TestInfo object. + // If shard_tests == HONOR_SHARDING_PROTOCOL, further filters tests + // based on sharding variables in the environment. + // Returns the number of tests that should run. + int FilterTests(ReactionToSharding shard_tests); + + // Prints the names of the tests matching the user-specified filter flag. + void ListTestsMatchingFilter(); + + const TestCase* current_test_case() const { return current_test_case_; } + TestInfo* current_test_info() { return current_test_info_; } + const TestInfo* current_test_info() const { return current_test_info_; } + + // Returns the vector of environments that need to be set-up/torn-down + // before/after the tests are run. + std::vector<Environment*>& environments() { return environments_; } + + // Getters for the per-thread Google Test trace stack. + std::vector<TraceInfo>& gtest_trace_stack() { + return *(gtest_trace_stack_.pointer()); + } + const std::vector<TraceInfo>& gtest_trace_stack() const { + return gtest_trace_stack_.get(); + } + +#if GTEST_HAS_DEATH_TEST + void InitDeathTestSubprocessControlInfo() { + internal_run_death_test_flag_.reset(ParseInternalRunDeathTestFlag()); + } + // Returns a pointer to the parsed --gtest_internal_run_death_test + // flag, or NULL if that flag was not specified. + // This information is useful only in a death test child process. + // Must not be called before a call to InitGoogleTest. + const InternalRunDeathTestFlag* internal_run_death_test_flag() const { + return internal_run_death_test_flag_.get(); + } + + // Returns a pointer to the current death test factory. + internal::DeathTestFactory* death_test_factory() { + return death_test_factory_.get(); + } + + void SuppressTestEventsIfInSubprocess(); + + friend class ReplaceDeathTestFactory; +#endif // GTEST_HAS_DEATH_TEST + + // Initializes the event listener performing XML output as specified by + // UnitTestOptions. Must not be called before InitGoogleTest. + void ConfigureXmlOutput(); + + // Performs initialization dependent upon flag values obtained in + // ParseGoogleTestFlagsOnly. Is called from InitGoogleTest after the call to + // ParseGoogleTestFlagsOnly. In case a user neglects to call InitGoogleTest + // this function is also called from RunAllTests. Since this function can be + // called more than once, it has to be idempotent. + void PostFlagParsingInit(); + + // Gets the random seed used at the start of the current test iteration. + int random_seed() const { return random_seed_; } + + // Gets the random number generator. + internal::Random* random() { return &random_; } + + // Shuffles all test cases, and the tests within each test case, + // making sure that death tests are still run first. + void ShuffleTests(); + + // Restores the test cases and tests to their order before the first shuffle. + void UnshuffleTests(); + + private: + friend class ::testing::UnitTest; + + // The UnitTest object that owns this implementation object. + UnitTest* const parent_; + + // The working directory when the first TEST() or TEST_F() was + // executed. + internal::FilePath original_working_dir_; + + // The default test part result reporters. + DefaultGlobalTestPartResultReporter default_global_test_part_result_reporter_; + DefaultPerThreadTestPartResultReporter + default_per_thread_test_part_result_reporter_; + + // Points to (but doesn't own) the global test part result reporter. + TestPartResultReporterInterface* global_test_part_result_repoter_; + + // Protects read and write access to global_test_part_result_reporter_. + internal::Mutex global_test_part_result_reporter_mutex_; + + // Points to (but doesn't own) the per-thread test part result reporter. + internal::ThreadLocal<TestPartResultReporterInterface*> + per_thread_test_part_result_reporter_; + + // The vector of environments that need to be set-up/torn-down + // before/after the tests are run. + std::vector<Environment*> environments_; + + // The vector of TestCases in their original order. It owns the + // elements in the vector. + std::vector<TestCase*> test_cases_; + + // Provides a level of indirection for the test case list to allow + // easy shuffling and restoring the test case order. The i-th + // element of this vector is the index of the i-th test case in the + // shuffled order. + std::vector<int> test_case_indices_; + +#if GTEST_HAS_PARAM_TEST + // ParameterizedTestRegistry object used to register value-parameterized + // tests. + internal::ParameterizedTestCaseRegistry parameterized_test_registry_; + + // Indicates whether RegisterParameterizedTests() has been called already. + bool parameterized_tests_registered_; +#endif // GTEST_HAS_PARAM_TEST + + // Index of the last death test case registered. Initially -1. + int last_death_test_case_; + + // This points to the TestCase for the currently running test. It + // changes as Google Test goes through one test case after another. + // When no test is running, this is set to NULL and Google Test + // stores assertion results in ad_hoc_test_result_. Initially NULL. + TestCase* current_test_case_; + + // This points to the TestInfo for the currently running test. It + // changes as Google Test goes through one test after another. When + // no test is running, this is set to NULL and Google Test stores + // assertion results in ad_hoc_test_result_. Initially NULL. + TestInfo* current_test_info_; + + // Normally, a user only writes assertions inside a TEST or TEST_F, + // or inside a function called by a TEST or TEST_F. Since Google + // Test keeps track of which test is current running, it can + // associate such an assertion with the test it belongs to. + // + // If an assertion is encountered when no TEST or TEST_F is running, + // Google Test attributes the assertion result to an imaginary "ad hoc" + // test, and records the result in ad_hoc_test_result_. + TestResult ad_hoc_test_result_; + + // The list of event listeners that can be used to track events inside + // Google Test. + TestEventListeners listeners_; + + // The OS stack trace getter. Will be deleted when the UnitTest + // object is destructed. By default, an OsStackTraceGetter is used, + // but the user can set this field to use a custom getter if that is + // desired. + OsStackTraceGetterInterface* os_stack_trace_getter_; + + // True iff PostFlagParsingInit() has been called. + bool post_flag_parse_init_performed_; + + // The random number seed used at the beginning of the test run. + int random_seed_; + + // Our random number generator. + internal::Random random_; + + // How long the test took to run, in milliseconds. + TimeInMillis elapsed_time_; + +#if GTEST_HAS_DEATH_TEST + // The decomposed components of the gtest_internal_run_death_test flag, + // parsed when RUN_ALL_TESTS is called. + internal::scoped_ptr<InternalRunDeathTestFlag> internal_run_death_test_flag_; + internal::scoped_ptr<internal::DeathTestFactory> death_test_factory_; +#endif // GTEST_HAS_DEATH_TEST + + // A per-thread stack of traces created by the SCOPED_TRACE() macro. + internal::ThreadLocal<std::vector<TraceInfo> > gtest_trace_stack_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(UnitTestImpl); +}; // class UnitTestImpl + +// Convenience function for accessing the global UnitTest +// implementation object. +inline UnitTestImpl* GetUnitTestImpl() { + return UnitTest::GetInstance()->impl(); +} + +// Internal helper functions for implementing the simple regular +// expression matcher. +GTEST_API_ bool IsInSet(char ch, const char* str); +GTEST_API_ bool IsDigit(char ch); +GTEST_API_ bool IsPunct(char ch); +GTEST_API_ bool IsRepeat(char ch); +GTEST_API_ bool IsWhiteSpace(char ch); +GTEST_API_ bool IsWordChar(char ch); +GTEST_API_ bool IsValidEscape(char ch); +GTEST_API_ bool AtomMatchesChar(bool escaped, char pattern, char ch); +GTEST_API_ bool ValidateRegex(const char* regex); +GTEST_API_ bool MatchRegexAtHead(const char* regex, const char* str); +GTEST_API_ bool MatchRepetitionAndRegexAtHead( + bool escaped, char ch, char repeat, const char* regex, const char* str); +GTEST_API_ bool MatchRegexAnywhere(const char* regex, const char* str); + +// Parses the command line for Google Test flags, without initializing +// other parts of Google Test. +GTEST_API_ void ParseGoogleTestFlagsOnly(int* argc, char** argv); +GTEST_API_ void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv); + +#if GTEST_HAS_DEATH_TEST + +// Returns the message describing the last system error, regardless of the +// platform. +String GetLastErrnoDescription(); + +#if GTEST_OS_WINDOWS +// Provides leak-safe Windows kernel handle ownership. +class AutoHandle { + public: + AutoHandle() : handle_(INVALID_HANDLE_VALUE) {} + explicit AutoHandle(HANDLE handle) : handle_(handle) {} + + ~AutoHandle() { Reset(); } + + HANDLE Get() const { return handle_; } + void Reset() { Reset(INVALID_HANDLE_VALUE); } + void Reset(HANDLE handle) { + if (handle != handle_) { + if (handle_ != INVALID_HANDLE_VALUE) + ::CloseHandle(handle_); + handle_ = handle; + } + } + + private: + HANDLE handle_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(AutoHandle); +}; +#endif // GTEST_OS_WINDOWS + +// Attempts to parse a string into a positive integer pointed to by the +// number parameter. Returns true if that is possible. +// GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we can use +// it here. +template <typename Integer> +bool ParseNaturalNumber(const ::std::string& str, Integer* number) { + // Fail fast if the given string does not begin with a digit; + // this bypasses strtoXXX's "optional leading whitespace and plus + // or minus sign" semantics, which are undesirable here. + if (str.empty() || !isdigit(str[0])) { + return false; + } + errno = 0; + + char* end; + // BiggestConvertible is the largest integer type that system-provided + // string-to-number conversion routines can return. +#if GTEST_OS_WINDOWS && !defined(__GNUC__) + // MSVC and C++ Builder define __int64 instead of the standard long long. + typedef unsigned __int64 BiggestConvertible; + const BiggestConvertible parsed = _strtoui64(str.c_str(), &end, 10); +#else + typedef unsigned long long BiggestConvertible; // NOLINT + const BiggestConvertible parsed = strtoull(str.c_str(), &end, 10); +#endif // GTEST_OS_WINDOWS && !defined(__GNUC__) + const bool parse_success = *end == '\0' && errno == 0; + + // TODO(vladl@google.com): Convert this to compile time assertion when it is + // available. + GTEST_CHECK_(sizeof(Integer) <= sizeof(parsed)); + + const Integer result = static_cast<Integer>(parsed); + if (parse_success && static_cast<BiggestConvertible>(result) == parsed) { + *number = result; + return true; + } + return false; +} +#endif // GTEST_HAS_DEATH_TEST + +// TestResult contains some private methods that should be hidden from +// Google Test user but are required for testing. This class allow our tests +// to access them. +// +// This class is supplied only for the purpose of testing Google Test's own +// constructs. Do not use it in user tests, either directly or indirectly. +class TestResultAccessor { + public: + static void RecordProperty(TestResult* test_result, + const TestProperty& property) { + test_result->RecordProperty(property); + } + + static void ClearTestPartResults(TestResult* test_result) { + test_result->ClearTestPartResults(); + } + + static const std::vector<testing::TestPartResult>& test_part_results( + const TestResult& test_result) { + return test_result.test_part_results(); + } +}; + +} // namespace internal +} // namespace testing + +#endif // GTEST_SRC_GTEST_INTERNAL_INL_H_ +#undef GTEST_IMPLEMENTATION_ + +#if GTEST_OS_WINDOWS +#define vsnprintf _vsnprintf +#endif // GTEST_OS_WINDOWS + +namespace testing { + +using internal::CountIf; +using internal::ForEach; +using internal::GetElementOr; +using internal::Shuffle; + +// Constants. + +// A test whose test case name or test name matches this filter is +// disabled and not run. +static const char kDisableTestFilter[] = "DISABLED_*:*/DISABLED_*"; + +// A test case whose name matches this filter is considered a death +// test case and will be run before test cases whose name doesn't +// match this filter. +static const char kDeathTestCaseFilter[] = "*DeathTest:*DeathTest/*"; + +// A test filter that matches everything. +static const char kUniversalFilter[] = "*"; + +// The default output file for XML output. +static const char kDefaultOutputFile[] = "test_detail.xml"; + +// The environment variable name for the test shard index. +static const char kTestShardIndex[] = "GTEST_SHARD_INDEX"; +// The environment variable name for the total number of test shards. +static const char kTestTotalShards[] = "GTEST_TOTAL_SHARDS"; +// The environment variable name for the test shard status file. +static const char kTestShardStatusFile[] = "GTEST_SHARD_STATUS_FILE"; + +namespace internal { + +// The text used in failure messages to indicate the start of the +// stack trace. +const char kStackTraceMarker[] = "\nStack trace:\n"; + +// g_help_flag is true iff the --help flag or an equivalent form is +// specified on the command line. +bool g_help_flag = false; + +} // namespace internal + +GTEST_DEFINE_bool_( + also_run_disabled_tests, + internal::BoolFromGTestEnv("also_run_disabled_tests", false), + "Run disabled tests too, in addition to the tests normally being run."); + +GTEST_DEFINE_bool_( + break_on_failure, + internal::BoolFromGTestEnv("break_on_failure", false), + "True iff a failed assertion should be a debugger break-point."); + +GTEST_DEFINE_bool_( + catch_exceptions, + internal::BoolFromGTestEnv("catch_exceptions", false), + "True iff " GTEST_NAME_ + " should catch exceptions and treat them as test failures."); + +GTEST_DEFINE_string_( + color, + internal::StringFromGTestEnv("color", "auto"), + "Whether to use colors in the output. Valid values: yes, no, " + "and auto. 'auto' means to use colors if the output is " + "being sent to a terminal and the TERM environment variable " + "is set to xterm, xterm-color, xterm-256color, linux or cygwin."); + +GTEST_DEFINE_string_( + filter, + internal::StringFromGTestEnv("filter", kUniversalFilter), + "A colon-separated list of glob (not regex) patterns " + "for filtering the tests to run, optionally followed by a " + "'-' and a : separated list of negative patterns (tests to " + "exclude). A test is run if it matches one of the positive " + "patterns and does not match any of the negative patterns."); + +GTEST_DEFINE_bool_(list_tests, false, + "List all tests without running them."); + +GTEST_DEFINE_string_( + output, + internal::StringFromGTestEnv("output", ""), + "A format (currently must be \"xml\"), optionally followed " + "by a colon and an output file name or directory. A directory " + "is indicated by a trailing pathname separator. " + "Examples: \"xml:filename.xml\", \"xml::directoryname/\". " + "If a directory is specified, output files will be created " + "within that directory, with file-names based on the test " + "executable's name and, if necessary, made unique by adding " + "digits."); + +GTEST_DEFINE_bool_( + print_time, + internal::BoolFromGTestEnv("print_time", true), + "True iff " GTEST_NAME_ + " should display elapsed time in text output."); + +GTEST_DEFINE_int32_( + random_seed, + internal::Int32FromGTestEnv("random_seed", 0), + "Random number seed to use when shuffling test orders. Must be in range " + "[1, 99999], or 0 to use a seed based on the current time."); + +GTEST_DEFINE_int32_( + repeat, + internal::Int32FromGTestEnv("repeat", 1), + "How many times to repeat each test. Specify a negative number " + "for repeating forever. Useful for shaking out flaky tests."); + +GTEST_DEFINE_bool_( + show_internal_stack_frames, false, + "True iff " GTEST_NAME_ " should include internal stack frames when " + "printing test failure stack traces."); + +GTEST_DEFINE_bool_( + shuffle, + internal::BoolFromGTestEnv("shuffle", false), + "True iff " GTEST_NAME_ + " should randomize tests' order on every run."); + +GTEST_DEFINE_int32_( + stack_trace_depth, + internal::Int32FromGTestEnv("stack_trace_depth", kMaxStackTraceDepth), + "The maximum number of stack frames to print when an " + "assertion fails. The valid range is 0 through 100, inclusive."); + +GTEST_DEFINE_bool_( + throw_on_failure, + internal::BoolFromGTestEnv("throw_on_failure", false), + "When this flag is specified, a failed assertion will throw an exception " + "if exceptions are enabled or exit the program with a non-zero code " + "otherwise."); + +namespace internal { + +// Generates a random number from [0, range), using a Linear +// Congruential Generator (LCG). Crashes if 'range' is 0 or greater +// than kMaxRange. +UInt32 Random::Generate(UInt32 range) { + // These constants are the same as are used in glibc's rand(3). + state_ = (1103515245U*state_ + 12345U) % kMaxRange; + + GTEST_CHECK_(range > 0) + << "Cannot generate a number in the range [0, 0)."; + GTEST_CHECK_(range <= kMaxRange) + << "Generation of a number in [0, " << range << ") was requested, " + << "but this can only generate numbers in [0, " << kMaxRange << ")."; + + // Converting via modulus introduces a bit of downward bias, but + // it's simple, and a linear congruential generator isn't too good + // to begin with. + return state_ % range; +} + +// GTestIsInitialized() returns true iff the user has initialized +// Google Test. Useful for catching the user mistake of not initializing +// Google Test before calling RUN_ALL_TESTS(). +// +// A user must call testing::InitGoogleTest() to initialize Google +// Test. g_init_gtest_count is set to the number of times +// InitGoogleTest() has been called. We don't protect this variable +// under a mutex as it is only accessed in the main thread. +int g_init_gtest_count = 0; +static bool GTestIsInitialized() { return g_init_gtest_count != 0; } + +// Iterates over a vector of TestCases, keeping a running sum of the +// results of calling a given int-returning method on each. +// Returns the sum. +static int SumOverTestCaseList(const std::vector<TestCase*>& case_list, + int (TestCase::*method)() const) { + int sum = 0; + for (size_t i = 0; i < case_list.size(); i++) { + sum += (case_list[i]->*method)(); + } + return sum; +} + +// Returns true iff the test case passed. +static bool TestCasePassed(const TestCase* test_case) { + return test_case->should_run() && test_case->Passed(); +} + +// Returns true iff the test case failed. +static bool TestCaseFailed(const TestCase* test_case) { + return test_case->should_run() && test_case->Failed(); +} + +// Returns true iff test_case contains at least one test that should +// run. +static bool ShouldRunTestCase(const TestCase* test_case) { + return test_case->should_run(); +} + +// AssertHelper constructor. +AssertHelper::AssertHelper(TestPartResult::Type type, + const char* file, + int line, + const char* message) + : data_(new AssertHelperData(type, file, line, message)) { +} + +AssertHelper::~AssertHelper() { + delete data_; +} + +// Message assignment, for assertion streaming support. +void AssertHelper::operator=(const Message& message) const { + UnitTest::GetInstance()-> + AddTestPartResult(data_->type, data_->file, data_->line, + AppendUserMessage(data_->message, message), + UnitTest::GetInstance()->impl() + ->CurrentOsStackTraceExceptTop(1) + // Skips the stack frame for this function itself. + ); // NOLINT +} + +// Mutex for linked pointers. +GTEST_DEFINE_STATIC_MUTEX_(g_linked_ptr_mutex); + +// Application pathname gotten in InitGoogleTest. +String g_executable_path; + +// Returns the current application's name, removing directory path if that +// is present. +FilePath GetCurrentExecutableName() { + FilePath result; + +#if GTEST_OS_WINDOWS + result.Set(FilePath(g_executable_path).RemoveExtension("exe")); +#else + result.Set(FilePath(g_executable_path)); +#endif // GTEST_OS_WINDOWS + + return result.RemoveDirectoryName(); +} + +// Functions for processing the gtest_output flag. + +// Returns the output format, or "" for normal printed output. +String UnitTestOptions::GetOutputFormat() { + const char* const gtest_output_flag = GTEST_FLAG(output).c_str(); + if (gtest_output_flag == NULL) return String(""); + + const char* const colon = strchr(gtest_output_flag, ':'); + return (colon == NULL) ? + String(gtest_output_flag) : + String(gtest_output_flag, colon - gtest_output_flag); +} + +// Returns the name of the requested output file, or the default if none +// was explicitly specified. +String UnitTestOptions::GetAbsolutePathToOutputFile() { + const char* const gtest_output_flag = GTEST_FLAG(output).c_str(); + if (gtest_output_flag == NULL) + return String(""); + + const char* const colon = strchr(gtest_output_flag, ':'); + if (colon == NULL) + return String(internal::FilePath::ConcatPaths( + internal::FilePath( + UnitTest::GetInstance()->original_working_dir()), + internal::FilePath(kDefaultOutputFile)).ToString() ); + + internal::FilePath output_name(colon + 1); + if (!output_name.IsAbsolutePath()) + // TODO(wan@google.com): on Windows \some\path is not an absolute + // path (as its meaning depends on the current drive), yet the + // following logic for turning it into an absolute path is wrong. + // Fix it. + output_name = internal::FilePath::ConcatPaths( + internal::FilePath(UnitTest::GetInstance()->original_working_dir()), + internal::FilePath(colon + 1)); + + if (!output_name.IsDirectory()) + return output_name.ToString(); + + internal::FilePath result(internal::FilePath::GenerateUniqueFileName( + output_name, internal::GetCurrentExecutableName(), + GetOutputFormat().c_str())); + return result.ToString(); +} + +// Returns true iff the wildcard pattern matches the string. The +// first ':' or '\0' character in pattern marks the end of it. +// +// This recursive algorithm isn't very efficient, but is clear and +// works well enough for matching test names, which are short. +bool UnitTestOptions::PatternMatchesString(const char *pattern, + const char *str) { + switch (*pattern) { + case '\0': + case ':': // Either ':' or '\0' marks the end of the pattern. + return *str == '\0'; + case '?': // Matches any single character. + return *str != '\0' && PatternMatchesString(pattern + 1, str + 1); + case '*': // Matches any string (possibly empty) of characters. + return (*str != '\0' && PatternMatchesString(pattern, str + 1)) || + PatternMatchesString(pattern + 1, str); + default: // Non-special character. Matches itself. + return *pattern == *str && + PatternMatchesString(pattern + 1, str + 1); + } +} + +bool UnitTestOptions::MatchesFilter(const String& name, const char* filter) { + const char *cur_pattern = filter; + for (;;) { + if (PatternMatchesString(cur_pattern, name.c_str())) { + return true; + } + + // Finds the next pattern in the filter. + cur_pattern = strchr(cur_pattern, ':'); + + // Returns if no more pattern can be found. + if (cur_pattern == NULL) { + return false; + } + + // Skips the pattern separater (the ':' character). + cur_pattern++; + } +} + +// TODO(keithray): move String function implementations to gtest-string.cc. + +// Returns true iff the user-specified filter matches the test case +// name and the test name. +bool UnitTestOptions::FilterMatchesTest(const String &test_case_name, + const String &test_name) { + const String& full_name = String::Format("%s.%s", + test_case_name.c_str(), + test_name.c_str()); + + // Split --gtest_filter at '-', if there is one, to separate into + // positive filter and negative filter portions + const char* const p = GTEST_FLAG(filter).c_str(); + const char* const dash = strchr(p, '-'); + String positive; + String negative; + if (dash == NULL) { + positive = GTEST_FLAG(filter).c_str(); // Whole string is a positive filter + negative = String(""); + } else { + positive = String(p, dash - p); // Everything up to the dash + negative = String(dash+1); // Everything after the dash + if (positive.empty()) { + // Treat '-test1' as the same as '*-test1' + positive = kUniversalFilter; + } + } + + // A filter is a colon-separated list of patterns. It matches a + // test if any pattern in it matches the test. + return (MatchesFilter(full_name, positive.c_str()) && + !MatchesFilter(full_name, negative.c_str())); +} + +#if GTEST_OS_WINDOWS +// Returns EXCEPTION_EXECUTE_HANDLER if Google Test should handle the +// given SEH exception, or EXCEPTION_CONTINUE_SEARCH otherwise. +// This function is useful as an __except condition. +int UnitTestOptions::GTestShouldProcessSEH(DWORD exception_code) { + // Google Test should handle an exception if: + // 1. the user wants it to, AND + // 2. this is not a breakpoint exception. + return (GTEST_FLAG(catch_exceptions) && + exception_code != EXCEPTION_BREAKPOINT) ? + EXCEPTION_EXECUTE_HANDLER : + EXCEPTION_CONTINUE_SEARCH; +} +#endif // GTEST_OS_WINDOWS + +} // namespace internal + +// The c'tor sets this object as the test part result reporter used by +// Google Test. The 'result' parameter specifies where to report the +// results. Intercepts only failures from the current thread. +ScopedFakeTestPartResultReporter::ScopedFakeTestPartResultReporter( + TestPartResultArray* result) + : intercept_mode_(INTERCEPT_ONLY_CURRENT_THREAD), + result_(result) { + Init(); +} + +// The c'tor sets this object as the test part result reporter used by +// Google Test. The 'result' parameter specifies where to report the +// results. +ScopedFakeTestPartResultReporter::ScopedFakeTestPartResultReporter( + InterceptMode intercept_mode, TestPartResultArray* result) + : intercept_mode_(intercept_mode), + result_(result) { + Init(); +} + +void ScopedFakeTestPartResultReporter::Init() { + internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); + if (intercept_mode_ == INTERCEPT_ALL_THREADS) { + old_reporter_ = impl->GetGlobalTestPartResultReporter(); + impl->SetGlobalTestPartResultReporter(this); + } else { + old_reporter_ = impl->GetTestPartResultReporterForCurrentThread(); + impl->SetTestPartResultReporterForCurrentThread(this); + } +} + +// The d'tor restores the test part result reporter used by Google Test +// before. +ScopedFakeTestPartResultReporter::~ScopedFakeTestPartResultReporter() { + internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); + if (intercept_mode_ == INTERCEPT_ALL_THREADS) { + impl->SetGlobalTestPartResultReporter(old_reporter_); + } else { + impl->SetTestPartResultReporterForCurrentThread(old_reporter_); + } +} + +// Increments the test part result count and remembers the result. +// This method is from the TestPartResultReporterInterface interface. +void ScopedFakeTestPartResultReporter::ReportTestPartResult( + const TestPartResult& result) { + result_->Append(result); +} + +namespace internal { + +// Returns the type ID of ::testing::Test. We should always call this +// instead of GetTypeId< ::testing::Test>() to get the type ID of +// testing::Test. This is to work around a suspected linker bug when +// using Google Test as a framework on Mac OS X. The bug causes +// GetTypeId< ::testing::Test>() to return different values depending +// on whether the call is from the Google Test framework itself or +// from user test code. GetTestTypeId() is guaranteed to always +// return the same value, as it always calls GetTypeId<>() from the +// gtest.cc, which is within the Google Test framework. +TypeId GetTestTypeId() { + return GetTypeId<Test>(); +} + +// The value of GetTestTypeId() as seen from within the Google Test +// library. This is solely for testing GetTestTypeId(). +extern const TypeId kTestTypeIdInGoogleTest = GetTestTypeId(); + +// This predicate-formatter checks that 'results' contains a test part +// failure of the given type and that the failure message contains the +// given substring. +AssertionResult HasOneFailure(const char* /* results_expr */, + const char* /* type_expr */, + const char* /* substr_expr */, + const TestPartResultArray& results, + TestPartResult::Type type, + const char* substr) { + const String expected(type == TestPartResult::kFatalFailure ? + "1 fatal failure" : + "1 non-fatal failure"); + Message msg; + if (results.size() != 1) { + msg << "Expected: " << expected << "\n" + << " Actual: " << results.size() << " failures"; + for (int i = 0; i < results.size(); i++) { + msg << "\n" << results.GetTestPartResult(i); + } + return AssertionFailure(msg); + } + + const TestPartResult& r = results.GetTestPartResult(0); + if (r.type() != type) { + msg << "Expected: " << expected << "\n" + << " Actual:\n" + << r; + return AssertionFailure(msg); + } + + if (strstr(r.message(), substr) == NULL) { + msg << "Expected: " << expected << " containing \"" + << substr << "\"\n" + << " Actual:\n" + << r; + return AssertionFailure(msg); + } + + return AssertionSuccess(); +} + +// The constructor of SingleFailureChecker remembers where to look up +// test part results, what type of failure we expect, and what +// substring the failure message should contain. +SingleFailureChecker:: SingleFailureChecker( + const TestPartResultArray* results, + TestPartResult::Type type, + const char* substr) + : results_(results), + type_(type), + substr_(substr) {} + +// The destructor of SingleFailureChecker verifies that the given +// TestPartResultArray contains exactly one failure that has the given +// type and contains the given substring. If that's not the case, a +// non-fatal failure will be generated. +SingleFailureChecker::~SingleFailureChecker() { + EXPECT_PRED_FORMAT3(HasOneFailure, *results_, type_, substr_.c_str()); +} + +DefaultGlobalTestPartResultReporter::DefaultGlobalTestPartResultReporter( + UnitTestImpl* unit_test) : unit_test_(unit_test) {} + +void DefaultGlobalTestPartResultReporter::ReportTestPartResult( + const TestPartResult& result) { + unit_test_->current_test_result()->AddTestPartResult(result); + unit_test_->listeners()->repeater()->OnTestPartResult(result); +} + +DefaultPerThreadTestPartResultReporter::DefaultPerThreadTestPartResultReporter( + UnitTestImpl* unit_test) : unit_test_(unit_test) {} + +void DefaultPerThreadTestPartResultReporter::ReportTestPartResult( + const TestPartResult& result) { + unit_test_->GetGlobalTestPartResultReporter()->ReportTestPartResult(result); +} + +// Returns the global test part result reporter. +TestPartResultReporterInterface* +UnitTestImpl::GetGlobalTestPartResultReporter() { + internal::MutexLock lock(&global_test_part_result_reporter_mutex_); + return global_test_part_result_repoter_; +} + +// Sets the global test part result reporter. +void UnitTestImpl::SetGlobalTestPartResultReporter( + TestPartResultReporterInterface* reporter) { + internal::MutexLock lock(&global_test_part_result_reporter_mutex_); + global_test_part_result_repoter_ = reporter; +} + +// Returns the test part result reporter for the current thread. +TestPartResultReporterInterface* +UnitTestImpl::GetTestPartResultReporterForCurrentThread() { + return per_thread_test_part_result_reporter_.get(); +} + +// Sets the test part result reporter for the current thread. +void UnitTestImpl::SetTestPartResultReporterForCurrentThread( + TestPartResultReporterInterface* reporter) { + per_thread_test_part_result_reporter_.set(reporter); +} + +// Gets the number of successful test cases. +int UnitTestImpl::successful_test_case_count() const { + return CountIf(test_cases_, TestCasePassed); +} + +// Gets the number of failed test cases. +int UnitTestImpl::failed_test_case_count() const { + return CountIf(test_cases_, TestCaseFailed); +} + +// Gets the number of all test cases. +int UnitTestImpl::total_test_case_count() const { + return static_cast<int>(test_cases_.size()); +} + +// Gets the number of all test cases that contain at least one test +// that should run. +int UnitTestImpl::test_case_to_run_count() const { + return CountIf(test_cases_, ShouldRunTestCase); +} + +// Gets the number of successful tests. +int UnitTestImpl::successful_test_count() const { + return SumOverTestCaseList(test_cases_, &TestCase::successful_test_count); +} + +// Gets the number of failed tests. +int UnitTestImpl::failed_test_count() const { + return SumOverTestCaseList(test_cases_, &TestCase::failed_test_count); +} + +// Gets the number of disabled tests. +int UnitTestImpl::disabled_test_count() const { + return SumOverTestCaseList(test_cases_, &TestCase::disabled_test_count); +} + +// Gets the number of all tests. +int UnitTestImpl::total_test_count() const { + return SumOverTestCaseList(test_cases_, &TestCase::total_test_count); +} + +// Gets the number of tests that should run. +int UnitTestImpl::test_to_run_count() const { + return SumOverTestCaseList(test_cases_, &TestCase::test_to_run_count); +} + +// Returns the current OS stack trace as a String. +// +// The maximum number of stack frames to be included is specified by +// the gtest_stack_trace_depth flag. The skip_count parameter +// specifies the number of top frames to be skipped, which doesn't +// count against the number of frames to be included. +// +// For example, if Foo() calls Bar(), which in turn calls +// CurrentOsStackTraceExceptTop(1), Foo() will be included in the +// trace but Bar() and CurrentOsStackTraceExceptTop() won't. +String UnitTestImpl::CurrentOsStackTraceExceptTop(int skip_count) { + (void)skip_count; + return String(""); +} + +// Returns the current time in milliseconds. +TimeInMillis GetTimeInMillis() { +#if GTEST_OS_WINDOWS_MOBILE || defined(__BORLANDC__) + // Difference between 1970-01-01 and 1601-01-01 in milliseconds. + // http://analogous.blogspot.com/2005/04/epoch.html + const TimeInMillis kJavaEpochToWinFileTimeDelta = + static_cast<TimeInMillis>(116444736UL) * 100000UL; + const DWORD kTenthMicrosInMilliSecond = 10000; + + SYSTEMTIME now_systime; + FILETIME now_filetime; + ULARGE_INTEGER now_int64; + // TODO(kenton@google.com): Shouldn't this just use + // GetSystemTimeAsFileTime()? + GetSystemTime(&now_systime); + if (SystemTimeToFileTime(&now_systime, &now_filetime)) { + now_int64.LowPart = now_filetime.dwLowDateTime; + now_int64.HighPart = now_filetime.dwHighDateTime; + now_int64.QuadPart = (now_int64.QuadPart / kTenthMicrosInMilliSecond) - + kJavaEpochToWinFileTimeDelta; + return now_int64.QuadPart; + } + return 0; +#elif GTEST_OS_WINDOWS && !GTEST_HAS_GETTIMEOFDAY_ + __timeb64 now; +#ifdef _MSC_VER + // MSVC 8 deprecates _ftime64(), so we want to suppress warning 4996 + // (deprecated function) there. + // TODO(kenton@google.com): Use GetTickCount()? Or use + // SystemTimeToFileTime() +#pragma warning(push) // Saves the current warning state. +#pragma warning(disable:4996) // Temporarily disables warning 4996. + _ftime64(&now); +#pragma warning(pop) // Restores the warning state. +#else + _ftime64(&now); +#endif // _MSC_VER + return static_cast<TimeInMillis>(now.time) * 1000 + now.millitm; +#elif GTEST_HAS_GETTIMEOFDAY_ + struct timeval now; + gettimeofday(&now, NULL); + return static_cast<TimeInMillis>(now.tv_sec) * 1000 + now.tv_usec / 1000; +#else +#error "Don't know how to get the current time on your system." +#endif +} + +// Utilities + +// class String + +// Returns the input enclosed in double quotes if it's not NULL; +// otherwise returns "(null)". For example, "\"Hello\"" is returned +// for input "Hello". +// +// This is useful for printing a C string in the syntax of a literal. +// +// Known issue: escape sequences are not handled yet. +String String::ShowCStringQuoted(const char* c_str) { + return c_str ? String::Format("\"%s\"", c_str) : String("(null)"); +} + +// Copies at most length characters from str into a newly-allocated +// piece of memory of size length+1. The memory is allocated with new[]. +// A terminating null byte is written to the memory, and a pointer to it +// is returned. If str is NULL, NULL is returned. +static char* CloneString(const char* str, size_t length) { + if (str == NULL) { + return NULL; + } else { + char* const clone = new char[length + 1]; + posix::StrNCpy(clone, str, length); + clone[length] = '\0'; + return clone; + } +} + +// Clones a 0-terminated C string, allocating memory using new. The +// caller is responsible for deleting[] the return value. Returns the +// cloned string, or NULL if the input is NULL. +const char * String::CloneCString(const char* c_str) { + return (c_str == NULL) ? + NULL : CloneString(c_str, strlen(c_str)); +} + +#if GTEST_OS_WINDOWS_MOBILE +// Creates a UTF-16 wide string from the given ANSI string, allocating +// memory using new. The caller is responsible for deleting the return +// value using delete[]. Returns the wide string, or NULL if the +// input is NULL. +LPCWSTR String::AnsiToUtf16(const char* ansi) { + if (!ansi) return NULL; + const int length = strlen(ansi); + const int unicode_length = + MultiByteToWideChar(CP_ACP, 0, ansi, length, + NULL, 0); + WCHAR* unicode = new WCHAR[unicode_length + 1]; + MultiByteToWideChar(CP_ACP, 0, ansi, length, + unicode, unicode_length); + unicode[unicode_length] = 0; + return unicode; +} + +// Creates an ANSI string from the given wide string, allocating +// memory using new. The caller is responsible for deleting the return +// value using delete[]. Returns the ANSI string, or NULL if the +// input is NULL. +const char* String::Utf16ToAnsi(LPCWSTR utf16_str) { + if (!utf16_str) return NULL; + const int ansi_length = + WideCharToMultiByte(CP_ACP, 0, utf16_str, -1, + NULL, 0, NULL, NULL); + char* ansi = new char[ansi_length + 1]; + WideCharToMultiByte(CP_ACP, 0, utf16_str, -1, + ansi, ansi_length, NULL, NULL); + ansi[ansi_length] = 0; + return ansi; +} + +#endif // GTEST_OS_WINDOWS_MOBILE + +// Compares two C strings. Returns true iff they have the same content. +// +// Unlike strcmp(), this function can handle NULL argument(s). A NULL +// C string is considered different to any non-NULL C string, +// including the empty string. +bool String::CStringEquals(const char * lhs, const char * rhs) { + if ( lhs == NULL ) return rhs == NULL; + + if ( rhs == NULL ) return false; + + return strcmp(lhs, rhs) == 0; +} + +#if GTEST_HAS_STD_WSTRING || GTEST_HAS_GLOBAL_WSTRING + +// Converts an array of wide chars to a narrow string using the UTF-8 +// encoding, and streams the result to the given Message object. +static void StreamWideCharsToMessage(const wchar_t* wstr, size_t length, + Message* msg) { + // TODO(wan): consider allowing a testing::String object to + // contain '\0'. This will make it behave more like std::string, + // and will allow ToUtf8String() to return the correct encoding + // for '\0' s.t. we can get rid of the conditional here (and in + // several other places). + for (size_t i = 0; i != length; ) { // NOLINT + if (wstr[i] != L'\0') { + *msg << WideStringToUtf8(wstr + i, static_cast<int>(length - i)); + while (i != length && wstr[i] != L'\0') + i++; + } else { + *msg << '\0'; + i++; + } + } +} + +#endif // GTEST_HAS_STD_WSTRING || GTEST_HAS_GLOBAL_WSTRING + +} // namespace internal + +#if GTEST_HAS_STD_WSTRING +// Converts the given wide string to a narrow string using the UTF-8 +// encoding, and streams the result to this Message object. +Message& Message::operator <<(const ::std::wstring& wstr) { + internal::StreamWideCharsToMessage(wstr.c_str(), wstr.length(), this); + return *this; +} +#endif // GTEST_HAS_STD_WSTRING + +#if GTEST_HAS_GLOBAL_WSTRING +// Converts the given wide string to a narrow string using the UTF-8 +// encoding, and streams the result to this Message object. +Message& Message::operator <<(const ::wstring& wstr) { + internal::StreamWideCharsToMessage(wstr.c_str(), wstr.length(), this); + return *this; +} +#endif // GTEST_HAS_GLOBAL_WSTRING + +namespace internal { + +// Formats a value to be used in a failure message. + +// For a char value, we print it as a C++ char literal and as an +// unsigned integer (both in decimal and in hexadecimal). +String FormatForFailureMessage(char ch) { + const unsigned int ch_as_uint = ch; + // A String object cannot contain '\0', so we print "\\0" when ch is + // '\0'. + return String::Format("'%s' (%u, 0x%X)", + ch ? String::Format("%c", ch).c_str() : "\\0", + ch_as_uint, ch_as_uint); +} + +// For a wchar_t value, we print it as a C++ wchar_t literal and as an +// unsigned integer (both in decimal and in hexidecimal). +String FormatForFailureMessage(wchar_t wchar) { + // The C++ standard doesn't specify the exact size of the wchar_t + // type. It just says that it shall have the same size as another + // integral type, called its underlying type. + // + // Therefore, in order to print a wchar_t value in the numeric form, + // we first convert it to the largest integral type (UInt64) and + // then print the converted value. + // + // We use streaming to print the value as "%llu" doesn't work + // correctly with MSVC 7.1. + const UInt64 wchar_as_uint64 = wchar; + Message msg; + // A String object cannot contain '\0', so we print "\\0" when wchar is + // L'\0'. + char buffer[32]; // CodePointToUtf8 requires a buffer that big. + msg << "L'" + << (wchar ? CodePointToUtf8(static_cast<UInt32>(wchar), buffer) : "\\0") + << "' (" << wchar_as_uint64 << ", 0x" << ::std::setbase(16) + << wchar_as_uint64 << ")"; + return msg.GetString(); +} + +} // namespace internal + +// AssertionResult constructors. +// Used in EXPECT_TRUE/FALSE(assertion_result). +AssertionResult::AssertionResult(const AssertionResult& other) + : success_(other.success_), + message_(other.message_.get() != NULL ? + new internal::String(*other.message_) : + static_cast<internal::String*>(NULL)) { +} + +// Returns the assertion's negation. Used with EXPECT/ASSERT_FALSE. +AssertionResult AssertionResult::operator!() const { + AssertionResult negation(!success_); + if (message_.get() != NULL) + negation << *message_; + return negation; +} + +// Makes a successful assertion result. +AssertionResult AssertionSuccess() { + return AssertionResult(true); +} + +// Makes a failed assertion result. +AssertionResult AssertionFailure() { + return AssertionResult(false); +} + +// Makes a failed assertion result with the given failure message. +// Deprecated; use AssertionFailure() << message. +AssertionResult AssertionFailure(const Message& message) { + return AssertionFailure() << message; +} + +namespace internal { + +// Constructs and returns the message for an equality assertion +// (e.g. ASSERT_EQ, EXPECT_STREQ, etc) failure. +// +// The first four parameters are the expressions used in the assertion +// and their values, as strings. For example, for ASSERT_EQ(foo, bar) +// where foo is 5 and bar is 6, we have: +// +// expected_expression: "foo" +// actual_expression: "bar" +// expected_value: "5" +// actual_value: "6" +// +// The ignoring_case parameter is true iff the assertion is a +// *_STRCASEEQ*. When it's true, the string " (ignoring case)" will +// be inserted into the message. +AssertionResult EqFailure(const char* expected_expression, + const char* actual_expression, + const String& expected_value, + const String& actual_value, + bool ignoring_case) { + Message msg; + msg << "Value of: " << actual_expression; + if (actual_value != actual_expression) { + msg << "\n Actual: " << actual_value; + } + + msg << "\nExpected: " << expected_expression; + if (ignoring_case) { + msg << " (ignoring case)"; + } + if (expected_value != expected_expression) { + msg << "\nWhich is: " << expected_value; + } + + return AssertionFailure(msg); +} + +// Constructs a failure message for Boolean assertions such as EXPECT_TRUE. +String GetBoolAssertionFailureMessage(const AssertionResult& assertion_result, + const char* expression_text, + const char* actual_predicate_value, + const char* expected_predicate_value) { + const char* actual_message = assertion_result.message(); + Message msg; + msg << "Value of: " << expression_text + << "\n Actual: " << actual_predicate_value; + if (actual_message[0] != '\0') + msg << " (" << actual_message << ")"; + msg << "\nExpected: " << expected_predicate_value; + return msg.GetString(); +} + +// Helper function for implementing ASSERT_NEAR. +AssertionResult DoubleNearPredFormat(const char* expr1, + const char* expr2, + const char* abs_error_expr, + double val1, + double val2, + double abs_error) { + const double diff = fabs(val1 - val2); + if (diff <= abs_error) return AssertionSuccess(); + + // TODO(wan): do not print the value of an expression if it's + // already a literal. + Message msg; + msg << "The difference between " << expr1 << " and " << expr2 + << " is " << diff << ", which exceeds " << abs_error_expr << ", where\n" + << expr1 << " evaluates to " << val1 << ",\n" + << expr2 << " evaluates to " << val2 << ", and\n" + << abs_error_expr << " evaluates to " << abs_error << "."; + return AssertionFailure(msg); +} + + +// Helper template for implementing FloatLE() and DoubleLE(). +template <typename RawType> +AssertionResult FloatingPointLE(const char* expr1, + const char* expr2, + RawType val1, + RawType val2) { + // Returns success if val1 is less than val2, + if (val1 < val2) { + return AssertionSuccess(); + } + + // or if val1 is almost equal to val2. + const FloatingPoint<RawType> lhs(val1), rhs(val2); + if (lhs.AlmostEquals(rhs)) { + return AssertionSuccess(); + } + + // Note that the above two checks will both fail if either val1 or + // val2 is NaN, as the IEEE floating-point standard requires that + // any predicate involving a NaN must return false. + + StrStream val1_ss; + val1_ss << std::setprecision(std::numeric_limits<RawType>::digits10 + 2) + << val1; + + StrStream val2_ss; + val2_ss << std::setprecision(std::numeric_limits<RawType>::digits10 + 2) + << val2; + + Message msg; + msg << "Expected: (" << expr1 << ") <= (" << expr2 << ")\n" + << " Actual: " << StrStreamToString(&val1_ss) << " vs " + << StrStreamToString(&val2_ss); + + return AssertionFailure(msg); +} + +} // namespace internal + +// Asserts that val1 is less than, or almost equal to, val2. Fails +// otherwise. In particular, it fails if either val1 or val2 is NaN. +AssertionResult FloatLE(const char* expr1, const char* expr2, + float val1, float val2) { + return internal::FloatingPointLE<float>(expr1, expr2, val1, val2); +} + +// Asserts that val1 is less than, or almost equal to, val2. Fails +// otherwise. In particular, it fails if either val1 or val2 is NaN. +AssertionResult DoubleLE(const char* expr1, const char* expr2, + double val1, double val2) { + return internal::FloatingPointLE<double>(expr1, expr2, val1, val2); +} + +namespace internal { + +// The helper function for {ASSERT|EXPECT}_EQ with int or enum +// arguments. +AssertionResult CmpHelperEQ(const char* expected_expression, + const char* actual_expression, + BiggestInt expected, + BiggestInt actual) { + if (expected == actual) { + return AssertionSuccess(); + } + + return EqFailure(expected_expression, + actual_expression, + FormatForComparisonFailureMessage(expected, actual), + FormatForComparisonFailureMessage(actual, expected), + false); +} + +// A macro for implementing the helper functions needed to implement +// ASSERT_?? and EXPECT_?? with integer or enum arguments. It is here +// just to avoid copy-and-paste of similar code. +#define GTEST_IMPL_CMP_HELPER_(op_name, op)\ +AssertionResult CmpHelper##op_name(const char* expr1, const char* expr2, \ + BiggestInt val1, BiggestInt val2) {\ + if (val1 op val2) {\ + return AssertionSuccess();\ + } else {\ + Message msg;\ + msg << "Expected: (" << expr1 << ") " #op " (" << expr2\ + << "), actual: " << FormatForComparisonFailureMessage(val1, val2)\ + << " vs " << FormatForComparisonFailureMessage(val2, val1);\ + return AssertionFailure(msg);\ + }\ +} + +// Implements the helper function for {ASSERT|EXPECT}_NE with int or +// enum arguments. +GTEST_IMPL_CMP_HELPER_(NE, !=) +// Implements the helper function for {ASSERT|EXPECT}_LE with int or +// enum arguments. +GTEST_IMPL_CMP_HELPER_(LE, <=) +// Implements the helper function for {ASSERT|EXPECT}_LT with int or +// enum arguments. +GTEST_IMPL_CMP_HELPER_(LT, < ) +// Implements the helper function for {ASSERT|EXPECT}_GE with int or +// enum arguments. +GTEST_IMPL_CMP_HELPER_(GE, >=) +// Implements the helper function for {ASSERT|EXPECT}_GT with int or +// enum arguments. +GTEST_IMPL_CMP_HELPER_(GT, > ) + +#undef GTEST_IMPL_CMP_HELPER_ + +// The helper function for {ASSERT|EXPECT}_STREQ. +AssertionResult CmpHelperSTREQ(const char* expected_expression, + const char* actual_expression, + const char* expected, + const char* actual) { + if (String::CStringEquals(expected, actual)) { + return AssertionSuccess(); + } + + return EqFailure(expected_expression, + actual_expression, + String::ShowCStringQuoted(expected), + String::ShowCStringQuoted(actual), + false); +} + +// The helper function for {ASSERT|EXPECT}_STRCASEEQ. +AssertionResult CmpHelperSTRCASEEQ(const char* expected_expression, + const char* actual_expression, + const char* expected, + const char* actual) { + if (String::CaseInsensitiveCStringEquals(expected, actual)) { + return AssertionSuccess(); + } + + return EqFailure(expected_expression, + actual_expression, + String::ShowCStringQuoted(expected), + String::ShowCStringQuoted(actual), + true); +} + +// The helper function for {ASSERT|EXPECT}_STRNE. +AssertionResult CmpHelperSTRNE(const char* s1_expression, + const char* s2_expression, + const char* s1, + const char* s2) { + if (!String::CStringEquals(s1, s2)) { + return AssertionSuccess(); + } else { + Message msg; + msg << "Expected: (" << s1_expression << ") != (" + << s2_expression << "), actual: \"" + << s1 << "\" vs \"" << s2 << "\""; + return AssertionFailure(msg); + } +} + +// The helper function for {ASSERT|EXPECT}_STRCASENE. +AssertionResult CmpHelperSTRCASENE(const char* s1_expression, + const char* s2_expression, + const char* s1, + const char* s2) { + if (!String::CaseInsensitiveCStringEquals(s1, s2)) { + return AssertionSuccess(); + } else { + Message msg; + msg << "Expected: (" << s1_expression << ") != (" + << s2_expression << ") (ignoring case), actual: \"" + << s1 << "\" vs \"" << s2 << "\""; + return AssertionFailure(msg); + } +} + +} // namespace internal + +namespace { + +// Helper functions for implementing IsSubString() and IsNotSubstring(). + +// This group of overloaded functions return true iff needle is a +// substring of haystack. NULL is considered a substring of itself +// only. + +bool IsSubstringPred(const char* needle, const char* haystack) { + if (needle == NULL || haystack == NULL) + return needle == haystack; + + return strstr(haystack, needle) != NULL; +} + +bool IsSubstringPred(const wchar_t* needle, const wchar_t* haystack) { + if (needle == NULL || haystack == NULL) + return needle == haystack; + + return wcsstr(haystack, needle) != NULL; +} + +// StringType here can be either ::std::string or ::std::wstring. +template <typename StringType> +bool IsSubstringPred(const StringType& needle, + const StringType& haystack) { + return haystack.find(needle) != StringType::npos; +} + +// This function implements either IsSubstring() or IsNotSubstring(), +// depending on the value of the expected_to_be_substring parameter. +// StringType here can be const char*, const wchar_t*, ::std::string, +// or ::std::wstring. +template <typename StringType> +AssertionResult IsSubstringImpl( + bool expected_to_be_substring, + const char* needle_expr, const char* haystack_expr, + const StringType& needle, const StringType& haystack) { + if (IsSubstringPred(needle, haystack) == expected_to_be_substring) + return AssertionSuccess(); + + const bool is_wide_string = sizeof(needle[0]) > 1; + const char* const begin_string_quote = is_wide_string ? "L\"" : "\""; + return AssertionFailure( + Message() + << "Value of: " << needle_expr << "\n" + << " Actual: " << begin_string_quote << needle << "\"\n" + << "Expected: " << (expected_to_be_substring ? "" : "not ") + << "a substring of " << haystack_expr << "\n" + << "Which is: " << begin_string_quote << haystack << "\""); +} + +} // namespace + +// IsSubstring() and IsNotSubstring() check whether needle is a +// substring of haystack (NULL is considered a substring of itself +// only), and return an appropriate error message when they fail. + +AssertionResult IsSubstring( + const char* needle_expr, const char* haystack_expr, + const char* needle, const char* haystack) { + return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); +} + +AssertionResult IsSubstring( + const char* needle_expr, const char* haystack_expr, + const wchar_t* needle, const wchar_t* haystack) { + return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); +} + +AssertionResult IsNotSubstring( + const char* needle_expr, const char* haystack_expr, + const char* needle, const char* haystack) { + return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); +} + +AssertionResult IsNotSubstring( + const char* needle_expr, const char* haystack_expr, + const wchar_t* needle, const wchar_t* haystack) { + return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); +} + +AssertionResult IsSubstring( + const char* needle_expr, const char* haystack_expr, + const ::std::string& needle, const ::std::string& haystack) { + return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); +} + +AssertionResult IsNotSubstring( + const char* needle_expr, const char* haystack_expr, + const ::std::string& needle, const ::std::string& haystack) { + return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); +} + +#if GTEST_HAS_STD_WSTRING +AssertionResult IsSubstring( + const char* needle_expr, const char* haystack_expr, + const ::std::wstring& needle, const ::std::wstring& haystack) { + return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); +} + +AssertionResult IsNotSubstring( + const char* needle_expr, const char* haystack_expr, + const ::std::wstring& needle, const ::std::wstring& haystack) { + return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); +} +#endif // GTEST_HAS_STD_WSTRING + +namespace internal { + +#if GTEST_OS_WINDOWS + +namespace { + +// Helper function for IsHRESULT{SuccessFailure} predicates +AssertionResult HRESULTFailureHelper(const char* expr, + const char* expected, + long hr) { // NOLINT +#if GTEST_OS_WINDOWS_MOBILE + // Windows CE doesn't support FormatMessage. + const char error_text[] = ""; +#else + // Looks up the human-readable system message for the HRESULT code + // and since we're not passing any params to FormatMessage, we don't + // want inserts expanded. + const DWORD kFlags = FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS; + const DWORD kBufSize = 4096; // String::Format can't exceed this length. + // Gets the system's human readable message string for this HRESULT. + char error_text[kBufSize] = { '\0' }; + DWORD message_length = ::FormatMessageA(kFlags, + 0, // no source, we're asking system + hr, // the error + 0, // no line width restrictions + error_text, // output buffer + kBufSize, // buf size + NULL); // no arguments for inserts + // Trims tailing white space (FormatMessage leaves a trailing cr-lf) + for (; message_length && isspace(error_text[message_length - 1]); + --message_length) { + error_text[message_length - 1] = '\0'; + } +#endif // GTEST_OS_WINDOWS_MOBILE + + const String error_hex(String::Format("0x%08X ", hr)); + Message msg; + msg << "Expected: " << expr << " " << expected << ".\n" + << " Actual: " << error_hex << error_text << "\n"; + + return ::testing::AssertionFailure(msg); +} + +} // namespace + +AssertionResult IsHRESULTSuccess(const char* expr, long hr) { // NOLINT + if (SUCCEEDED(hr)) { + return AssertionSuccess(); + } + return HRESULTFailureHelper(expr, "succeeds", hr); +} + +AssertionResult IsHRESULTFailure(const char* expr, long hr) { // NOLINT + if (FAILED(hr)) { + return AssertionSuccess(); + } + return HRESULTFailureHelper(expr, "fails", hr); +} + +#endif // GTEST_OS_WINDOWS + +// Utility functions for encoding Unicode text (wide strings) in +// UTF-8. + +// A Unicode code-point can have upto 21 bits, and is encoded in UTF-8 +// like this: +// +// Code-point length Encoding +// 0 - 7 bits 0xxxxxxx +// 8 - 11 bits 110xxxxx 10xxxxxx +// 12 - 16 bits 1110xxxx 10xxxxxx 10xxxxxx +// 17 - 21 bits 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx + +// The maximum code-point a one-byte UTF-8 sequence can represent. +const UInt32 kMaxCodePoint1 = (static_cast<UInt32>(1) << 7) - 1; + +// The maximum code-point a two-byte UTF-8 sequence can represent. +const UInt32 kMaxCodePoint2 = (static_cast<UInt32>(1) << (5 + 6)) - 1; + +// The maximum code-point a three-byte UTF-8 sequence can represent. +const UInt32 kMaxCodePoint3 = (static_cast<UInt32>(1) << (4 + 2*6)) - 1; + +// The maximum code-point a four-byte UTF-8 sequence can represent. +const UInt32 kMaxCodePoint4 = (static_cast<UInt32>(1) << (3 + 3*6)) - 1; + +// Chops off the n lowest bits from a bit pattern. Returns the n +// lowest bits. As a side effect, the original bit pattern will be +// shifted to the right by n bits. +inline UInt32 ChopLowBits(UInt32* bits, int n) { + const UInt32 low_bits = *bits & ((static_cast<UInt32>(1) << n) - 1); + *bits >>= n; + return low_bits; +} + +// Converts a Unicode code point to a narrow string in UTF-8 encoding. +// code_point parameter is of type UInt32 because wchar_t may not be +// wide enough to contain a code point. +// The output buffer str must containt at least 32 characters. +// The function returns the address of the output buffer. +// If the code_point is not a valid Unicode code point +// (i.e. outside of Unicode range U+0 to U+10FFFF) it will be output +// as '(Invalid Unicode 0xXXXXXXXX)'. +char* CodePointToUtf8(UInt32 code_point, char* str) { + if (code_point <= kMaxCodePoint1) { + str[1] = '\0'; + str[0] = static_cast<char>(code_point); // 0xxxxxxx + } else if (code_point <= kMaxCodePoint2) { + str[2] = '\0'; + str[1] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx + str[0] = static_cast<char>(0xC0 | code_point); // 110xxxxx + } else if (code_point <= kMaxCodePoint3) { + str[3] = '\0'; + str[2] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx + str[1] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx + str[0] = static_cast<char>(0xE0 | code_point); // 1110xxxx + } else if (code_point <= kMaxCodePoint4) { + str[4] = '\0'; + str[3] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx + str[2] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx + str[1] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx + str[0] = static_cast<char>(0xF0 | code_point); // 11110xxx + } else { + // The longest string String::Format can produce when invoked + // with these parameters is 28 character long (not including + // the terminating nul character). We are asking for 32 character + // buffer just in case. This is also enough for strncpy to + // null-terminate the destination string. + posix::StrNCpy( + str, String::Format("(Invalid Unicode 0x%X)", code_point).c_str(), 32); + str[31] = '\0'; // Makes sure no change in the format to strncpy leaves + // the result unterminated. + } + return str; +} + +// The following two functions only make sense if the the system +// uses UTF-16 for wide string encoding. All supported systems +// with 16 bit wchar_t (Windows, Cygwin, Symbian OS) do use UTF-16. + +// Determines if the arguments constitute UTF-16 surrogate pair +// and thus should be combined into a single Unicode code point +// using CreateCodePointFromUtf16SurrogatePair. +inline bool IsUtf16SurrogatePair(wchar_t first, wchar_t second) { + return sizeof(wchar_t) == 2 && + (first & 0xFC00) == 0xD800 && (second & 0xFC00) == 0xDC00; +} + +// Creates a Unicode code point from UTF16 surrogate pair. +inline UInt32 CreateCodePointFromUtf16SurrogatePair(wchar_t first, + wchar_t second) { + const UInt32 mask = (1 << 10) - 1; + return (sizeof(wchar_t) == 2) ? + (((first & mask) << 10) | (second & mask)) + 0x10000 : + // This function should not be called when the condition is + // false, but we provide a sensible default in case it is. + static_cast<UInt32>(first); +} + +// Converts a wide string to a narrow string in UTF-8 encoding. +// The wide string is assumed to have the following encoding: +// UTF-16 if sizeof(wchar_t) == 2 (on Windows, Cygwin, Symbian OS) +// UTF-32 if sizeof(wchar_t) == 4 (on Linux) +// Parameter str points to a null-terminated wide string. +// Parameter num_chars may additionally limit the number +// of wchar_t characters processed. -1 is used when the entire string +// should be processed. +// If the string contains code points that are not valid Unicode code points +// (i.e. outside of Unicode range U+0 to U+10FFFF) they will be output +// as '(Invalid Unicode 0xXXXXXXXX)'. If the string is in UTF16 encoding +// and contains invalid UTF-16 surrogate pairs, values in those pairs +// will be encoded as individual Unicode characters from Basic Normal Plane. +String WideStringToUtf8(const wchar_t* str, int num_chars) { + if (num_chars == -1) + num_chars = static_cast<int>(wcslen(str)); + + StrStream stream; + for (int i = 0; i < num_chars; ++i) { + UInt32 unicode_code_point; + + if (str[i] == L'\0') { + break; + } else if (i + 1 < num_chars && IsUtf16SurrogatePair(str[i], str[i + 1])) { + unicode_code_point = CreateCodePointFromUtf16SurrogatePair(str[i], + str[i + 1]); + i++; + } else { + unicode_code_point = static_cast<UInt32>(str[i]); + } + + char buffer[32]; // CodePointToUtf8 requires a buffer this big. + stream << CodePointToUtf8(unicode_code_point, buffer); + } + return StrStreamToString(&stream); +} + +// Converts a wide C string to a String using the UTF-8 encoding. +// NULL will be converted to "(null)". +String String::ShowWideCString(const wchar_t * wide_c_str) { + if (wide_c_str == NULL) return String("(null)"); + + return String(internal::WideStringToUtf8(wide_c_str, -1).c_str()); +} + +// Similar to ShowWideCString(), except that this function encloses +// the converted string in double quotes. +String String::ShowWideCStringQuoted(const wchar_t* wide_c_str) { + if (wide_c_str == NULL) return String("(null)"); + + return String::Format("L\"%s\"", + String::ShowWideCString(wide_c_str).c_str()); +} + +// Compares two wide C strings. Returns true iff they have the same +// content. +// +// Unlike wcscmp(), this function can handle NULL argument(s). A NULL +// C string is considered different to any non-NULL C string, +// including the empty string. +bool String::WideCStringEquals(const wchar_t * lhs, const wchar_t * rhs) { + if (lhs == NULL) return rhs == NULL; + + if (rhs == NULL) return false; + + return wcscmp(lhs, rhs) == 0; +} + +// Helper function for *_STREQ on wide strings. +AssertionResult CmpHelperSTREQ(const char* expected_expression, + const char* actual_expression, + const wchar_t* expected, + const wchar_t* actual) { + if (String::WideCStringEquals(expected, actual)) { + return AssertionSuccess(); + } + + return EqFailure(expected_expression, + actual_expression, + String::ShowWideCStringQuoted(expected), + String::ShowWideCStringQuoted(actual), + false); +} + +// Helper function for *_STRNE on wide strings. +AssertionResult CmpHelperSTRNE(const char* s1_expression, + const char* s2_expression, + const wchar_t* s1, + const wchar_t* s2) { + if (!String::WideCStringEquals(s1, s2)) { + return AssertionSuccess(); + } + + Message msg; + msg << "Expected: (" << s1_expression << ") != (" + << s2_expression << "), actual: " + << String::ShowWideCStringQuoted(s1) + << " vs " << String::ShowWideCStringQuoted(s2); + return AssertionFailure(msg); +} + +// Compares two C strings, ignoring case. Returns true iff they have +// the same content. +// +// Unlike strcasecmp(), this function can handle NULL argument(s). A +// NULL C string is considered different to any non-NULL C string, +// including the empty string. +bool String::CaseInsensitiveCStringEquals(const char * lhs, const char * rhs) { + if (lhs == NULL) + return rhs == NULL; + if (rhs == NULL) + return false; + return posix::StrCaseCmp(lhs, rhs) == 0; +} + + // Compares two wide C strings, ignoring case. Returns true iff they + // have the same content. + // + // Unlike wcscasecmp(), this function can handle NULL argument(s). + // A NULL C string is considered different to any non-NULL wide C string, + // including the empty string. + // NB: The implementations on different platforms slightly differ. + // On windows, this method uses _wcsicmp which compares according to LC_CTYPE + // environment variable. On GNU platform this method uses wcscasecmp + // which compares according to LC_CTYPE category of the current locale. + // On MacOS X, it uses towlower, which also uses LC_CTYPE category of the + // current locale. +bool String::CaseInsensitiveWideCStringEquals(const wchar_t* lhs, + const wchar_t* rhs) { + if ( lhs == NULL ) return rhs == NULL; + + if ( rhs == NULL ) return false; + +#if GTEST_OS_WINDOWS + return _wcsicmp(lhs, rhs) == 0; +#elif GTEST_OS_LINUX + return wcscasecmp(lhs, rhs) == 0; +#else + // Mac OS X and Cygwin don't define wcscasecmp. Other unknown OSes + // may not define it either. + wint_t left, right; + do { + left = towlower(*lhs++); + right = towlower(*rhs++); + } while (left && left == right); + return left == right; +#endif // OS selector +} + +// Compares this with another String. +// Returns < 0 if this is less than rhs, 0 if this is equal to rhs, or > 0 +// if this is greater than rhs. +int String::Compare(const String & rhs) const { + const char* const lhs_c_str = c_str(); + const char* const rhs_c_str = rhs.c_str(); + + if (lhs_c_str == NULL) { + return rhs_c_str == NULL ? 0 : -1; // NULL < anything except NULL + } else if (rhs_c_str == NULL) { + return 1; + } + + const size_t shorter_str_len = + length() <= rhs.length() ? length() : rhs.length(); + for (size_t i = 0; i != shorter_str_len; i++) { + if (lhs_c_str[i] < rhs_c_str[i]) { + return -1; + } else if (lhs_c_str[i] > rhs_c_str[i]) { + return 1; + } + } + return (length() < rhs.length()) ? -1 : + (length() > rhs.length()) ? 1 : 0; +} + +// Returns true iff this String ends with the given suffix. *Any* +// String is considered to end with a NULL or empty suffix. +bool String::EndsWith(const char* suffix) const { + if (suffix == NULL || CStringEquals(suffix, "")) return true; + + if (c_str() == NULL) return false; + + const size_t this_len = strlen(c_str()); + const size_t suffix_len = strlen(suffix); + return (this_len >= suffix_len) && + CStringEquals(c_str() + this_len - suffix_len, suffix); +} + +// Returns true iff this String ends with the given suffix, ignoring case. +// Any String is considered to end with a NULL or empty suffix. +bool String::EndsWithCaseInsensitive(const char* suffix) const { + if (suffix == NULL || CStringEquals(suffix, "")) return true; + + if (c_str() == NULL) return false; + + const size_t this_len = strlen(c_str()); + const size_t suffix_len = strlen(suffix); + return (this_len >= suffix_len) && + CaseInsensitiveCStringEquals(c_str() + this_len - suffix_len, suffix); +} + +// Formats a list of arguments to a String, using the same format +// spec string as for printf. +// +// We do not use the StringPrintf class as it is not universally +// available. +// +// The result is limited to 4096 characters (including the tailing 0). +// If 4096 characters are not enough to format the input, or if +// there's an error, "<formatting error or buffer exceeded>" is +// returned. +String String::Format(const char * format, ...) { + va_list args; + va_start(args, format); + + char buffer[4096]; + const int kBufferSize = sizeof(buffer)/sizeof(buffer[0]); + + // MSVC 8 deprecates vsnprintf(), so we want to suppress warning + // 4996 (deprecated function) there. +#ifdef _MSC_VER // We are using MSVC. +#pragma warning(push) // Saves the current warning state. +#pragma warning(disable:4996) // Temporarily disables warning 4996. + const int size = vsnprintf(buffer, kBufferSize, format, args); +#pragma warning(pop) // Restores the warning state. +#else // We are not using MSVC. + const int size = vsnprintf(buffer, kBufferSize, format, args); +#endif // _MSC_VER + va_end(args); + + // vsnprintf()'s behavior is not portable. When the buffer is not + // big enough, it returns a negative value in MSVC, and returns the + // needed buffer size on Linux. When there is an output error, it + // always returns a negative value. For simplicity, we lump the two + // error cases together. + if (size < 0 || size >= kBufferSize) { + return String("<formatting error or buffer exceeded>"); + } else { + return String(buffer, size); + } +} + +// Converts the buffer in a StrStream to a String, converting NUL +// bytes to "\\0" along the way. +String StrStreamToString(StrStream* ss) { + const ::std::string& str = ss->str(); + const char* const start = str.c_str(); + const char* const end = start + str.length(); + + // We need to use a helper StrStream to do this transformation + // because String doesn't support push_back(). + StrStream helper; + for (const char* ch = start; ch != end; ++ch) { + if (*ch == '\0') { + helper << "\\0"; // Replaces NUL with "\\0"; + } else { + helper.put(*ch); + } + } + + return String(helper.str().c_str()); +} + +// Appends the user-supplied message to the Google-Test-generated message. +String AppendUserMessage(const String& gtest_msg, + const Message& user_msg) { + // Appends the user message if it's non-empty. + const String user_msg_string = user_msg.GetString(); + if (user_msg_string.empty()) { + return gtest_msg; + } + + Message msg; + msg << gtest_msg << "\n" << user_msg_string; + + return msg.GetString(); +} + +} // namespace internal + +// class TestResult + +// Creates an empty TestResult. +TestResult::TestResult() + : death_test_count_(0), + elapsed_time_(0) { +} + +// D'tor. +TestResult::~TestResult() { +} + +// Returns the i-th test part result among all the results. i can +// range from 0 to total_part_count() - 1. If i is not in that range, +// aborts the program. +const TestPartResult& TestResult::GetTestPartResult(int i) const { + if (i < 0 || i >= total_part_count()) + internal::posix::Abort(); + return test_part_results_.at(i); +} + +// Returns the i-th test property. i can range from 0 to +// test_property_count() - 1. If i is not in that range, aborts the +// program. +const TestProperty& TestResult::GetTestProperty(int i) const { + if (i < 0 || i >= test_property_count()) + internal::posix::Abort(); + return test_properties_.at(i); +} + +// Clears the test part results. +void TestResult::ClearTestPartResults() { + test_part_results_.clear(); +} + +// Adds a test part result to the list. +void TestResult::AddTestPartResult(const TestPartResult& test_part_result) { + test_part_results_.push_back(test_part_result); +} + +// Adds a test property to the list. If a property with the same key as the +// supplied property is already represented, the value of this test_property +// replaces the old value for that key. +void TestResult::RecordProperty(const TestProperty& test_property) { + if (!ValidateTestProperty(test_property)) { + return; + } + internal::MutexLock lock(&test_properites_mutex_); + const std::vector<TestProperty>::iterator property_with_matching_key = + std::find_if(test_properties_.begin(), test_properties_.end(), + internal::TestPropertyKeyIs(test_property.key())); + if (property_with_matching_key == test_properties_.end()) { + test_properties_.push_back(test_property); + return; + } + property_with_matching_key->SetValue(test_property.value()); +} + +// Adds a failure if the key is a reserved attribute of Google Test +// testcase tags. Returns true if the property is valid. +bool TestResult::ValidateTestProperty(const TestProperty& test_property) { + internal::String key(test_property.key()); + if (key == "name" || key == "status" || key == "time" || key == "classname") { + ADD_FAILURE() + << "Reserved key used in RecordProperty(): " + << key + << " ('name', 'status', 'time', and 'classname' are reserved by " + << GTEST_NAME_ << ")"; + return false; + } + return true; +} + +// Clears the object. +void TestResult::Clear() { + test_part_results_.clear(); + test_properties_.clear(); + death_test_count_ = 0; + elapsed_time_ = 0; +} + +// Returns true iff the test failed. +bool TestResult::Failed() const { + for (int i = 0; i < total_part_count(); ++i) { + if (GetTestPartResult(i).failed()) + return true; + } + return false; +} + +// Returns true iff the test part fatally failed. +static bool TestPartFatallyFailed(const TestPartResult& result) { + return result.fatally_failed(); +} + +// Returns true iff the test fatally failed. +bool TestResult::HasFatalFailure() const { + return CountIf(test_part_results_, TestPartFatallyFailed) > 0; +} + +// Returns true iff the test part non-fatally failed. +static bool TestPartNonfatallyFailed(const TestPartResult& result) { + return result.nonfatally_failed(); +} + +// Returns true iff the test has a non-fatal failure. +bool TestResult::HasNonfatalFailure() const { + return CountIf(test_part_results_, TestPartNonfatallyFailed) > 0; +} + +// Gets the number of all test parts. This is the sum of the number +// of successful test parts and the number of failed test parts. +int TestResult::total_part_count() const { + return static_cast<int>(test_part_results_.size()); +} + +// Returns the number of the test properties. +int TestResult::test_property_count() const { + return static_cast<int>(test_properties_.size()); +} + +// class Test + +// Creates a Test object. + +// The c'tor saves the values of all Google Test flags. +Test::Test() + : gtest_flag_saver_(new internal::GTestFlagSaver) { +} + +// The d'tor restores the values of all Google Test flags. +Test::~Test() { + delete gtest_flag_saver_; +} + +// Sets up the test fixture. +// +// A sub-class may override this. +void Test::SetUp() { +} + +// Tears down the test fixture. +// +// A sub-class may override this. +void Test::TearDown() { +} + +// Allows user supplied key value pairs to be recorded for later output. +void Test::RecordProperty(const char* key, const char* value) { + UnitTest::GetInstance()->RecordPropertyForCurrentTest(key, value); +} + +// Allows user supplied key value pairs to be recorded for later output. +void Test::RecordProperty(const char* key, int value) { + Message value_message; + value_message << value; + RecordProperty(key, value_message.GetString().c_str()); +} + +namespace internal { + +void ReportFailureInUnknownLocation(TestPartResult::Type result_type, + const String& message) { + // This function is a friend of UnitTest and as such has access to + // AddTestPartResult. + UnitTest::GetInstance()->AddTestPartResult( + result_type, + NULL, // No info about the source file where the exception occurred. + -1, // We have no info on which line caused the exception. + message, + String()); // No stack trace, either. +} + +} // namespace internal + +#if GTEST_OS_WINDOWS +// We are on Windows. + +// Adds an "exception thrown" fatal failure to the current test. +static void AddExceptionThrownFailure(DWORD exception_code, + const char* location) { + Message message; + message << "Exception thrown with code 0x" << std::setbase(16) << + exception_code << std::setbase(10) << " in " << location << "."; + + internal::ReportFailureInUnknownLocation(TestPartResult::kFatalFailure, + message.GetString()); +} + +#endif // GTEST_OS_WINDOWS + +// Google Test requires all tests in the same test case to use the same test +// fixture class. This function checks if the current test has the +// same fixture class as the first test in the current test case. If +// yes, it returns true; otherwise it generates a Google Test failure and +// returns false. +bool Test::HasSameFixtureClass() { + internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); + const TestCase* const test_case = impl->current_test_case(); + + // Info about the first test in the current test case. + const internal::TestInfoImpl* const first_test_info = + test_case->test_info_list()[0]->impl(); + const internal::TypeId first_fixture_id = first_test_info->fixture_class_id(); + const char* const first_test_name = first_test_info->name(); + + // Info about the current test. + const internal::TestInfoImpl* const this_test_info = + impl->current_test_info()->impl(); + const internal::TypeId this_fixture_id = this_test_info->fixture_class_id(); + const char* const this_test_name = this_test_info->name(); + + if (this_fixture_id != first_fixture_id) { + // Is the first test defined using TEST? + const bool first_is_TEST = first_fixture_id == internal::GetTestTypeId(); + // Is this test defined using TEST? + const bool this_is_TEST = this_fixture_id == internal::GetTestTypeId(); + + if (first_is_TEST || this_is_TEST) { + // The user mixed TEST and TEST_F in this test case - we'll tell + // him/her how to fix it. + + // Gets the name of the TEST and the name of the TEST_F. Note + // that first_is_TEST and this_is_TEST cannot both be true, as + // the fixture IDs are different for the two tests. + const char* const TEST_name = + first_is_TEST ? first_test_name : this_test_name; + const char* const TEST_F_name = + first_is_TEST ? this_test_name : first_test_name; + + ADD_FAILURE() + << "All tests in the same test case must use the same test fixture\n" + << "class, so mixing TEST_F and TEST in the same test case is\n" + << "illegal. In test case " << this_test_info->test_case_name() + << ",\n" + << "test " << TEST_F_name << " is defined using TEST_F but\n" + << "test " << TEST_name << " is defined using TEST. You probably\n" + << "want to change the TEST to TEST_F or move it to another test\n" + << "case."; + } else { + // The user defined two fixture classes with the same name in + // two namespaces - we'll tell him/her how to fix it. + ADD_FAILURE() + << "All tests in the same test case must use the same test fixture\n" + << "class. However, in test case " + << this_test_info->test_case_name() << ",\n" + << "you defined test " << first_test_name + << " and test " << this_test_name << "\n" + << "using two different test fixture classes. This can happen if\n" + << "the two classes are from different namespaces or translation\n" + << "units and have the same name. You should probably rename one\n" + << "of the classes to put the tests into different test cases."; + } + return false; + } + + return true; +} + +// Runs the test and updates the test result. +void Test::Run() { + if (!HasSameFixtureClass()) return; + + internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); +#if GTEST_HAS_SEH + // Catch SEH-style exceptions. + impl->os_stack_trace_getter()->UponLeavingGTest(); + __try { + SetUp(); + } __except(internal::UnitTestOptions::GTestShouldProcessSEH( + GetExceptionCode())) { + AddExceptionThrownFailure(GetExceptionCode(), "SetUp()"); + } + + // We will run the test only if SetUp() had no fatal failure. + if (!HasFatalFailure()) { + impl->os_stack_trace_getter()->UponLeavingGTest(); + __try { + TestBody(); + } __except(internal::UnitTestOptions::GTestShouldProcessSEH( + GetExceptionCode())) { + AddExceptionThrownFailure(GetExceptionCode(), "the test body"); + } + } + + // However, we want to clean up as much as possible. Hence we will + // always call TearDown(), even if SetUp() or the test body has + // failed. + impl->os_stack_trace_getter()->UponLeavingGTest(); + __try { + TearDown(); + } __except(internal::UnitTestOptions::GTestShouldProcessSEH( + GetExceptionCode())) { + AddExceptionThrownFailure(GetExceptionCode(), "TearDown()"); + } + +#else // We are on a compiler or platform that doesn't support SEH. + impl->os_stack_trace_getter()->UponLeavingGTest(); + SetUp(); + + // We will run the test only if SetUp() was successful. + if (!HasFatalFailure()) { + impl->os_stack_trace_getter()->UponLeavingGTest(); + TestBody(); + } + + // However, we want to clean up as much as possible. Hence we will + // always call TearDown(), even if SetUp() or the test body has + // failed. + impl->os_stack_trace_getter()->UponLeavingGTest(); + TearDown(); +#endif // GTEST_HAS_SEH +} + + +// Returns true iff the current test has a fatal failure. +bool Test::HasFatalFailure() { + return internal::GetUnitTestImpl()->current_test_result()->HasFatalFailure(); +} + +// Returns true iff the current test has a non-fatal failure. +bool Test::HasNonfatalFailure() { + return internal::GetUnitTestImpl()->current_test_result()-> + HasNonfatalFailure(); +} + +// class TestInfo + +// Constructs a TestInfo object. It assumes ownership of the test factory +// object via impl_. +TestInfo::TestInfo(const char* a_test_case_name, + const char* a_name, + const char* a_test_case_comment, + const char* a_comment, + internal::TypeId fixture_class_id, + internal::TestFactoryBase* factory) { + impl_ = new internal::TestInfoImpl(this, a_test_case_name, a_name, + a_test_case_comment, a_comment, + fixture_class_id, factory); +} + +// Destructs a TestInfo object. +TestInfo::~TestInfo() { + delete impl_; +} + +namespace internal { + +// Creates a new TestInfo object and registers it with Google Test; +// returns the created object. +// +// Arguments: +// +// test_case_name: name of the test case +// name: name of the test +// test_case_comment: a comment on the test case that will be included in +// the test output +// comment: a comment on the test that will be included in the +// test output +// fixture_class_id: ID of the test fixture class +// set_up_tc: pointer to the function that sets up the test case +// tear_down_tc: pointer to the function that tears down the test case +// factory: pointer to the factory that creates a test object. +// The newly created TestInfo instance will assume +// ownership of the factory object. +TestInfo* MakeAndRegisterTestInfo( + const char* test_case_name, const char* name, + const char* test_case_comment, const char* comment, + TypeId fixture_class_id, + SetUpTestCaseFunc set_up_tc, + TearDownTestCaseFunc tear_down_tc, + TestFactoryBase* factory) { + TestInfo* const test_info = + new TestInfo(test_case_name, name, test_case_comment, comment, + fixture_class_id, factory); + GetUnitTestImpl()->AddTestInfo(set_up_tc, tear_down_tc, test_info); + return test_info; +} + +#if GTEST_HAS_PARAM_TEST +void ReportInvalidTestCaseType(const char* test_case_name, + const char* file, int line) { + Message errors; + errors + << "Attempted redefinition of test case " << test_case_name << ".\n" + << "All tests in the same test case must use the same test fixture\n" + << "class. However, in test case " << test_case_name << ", you tried\n" + << "to define a test using a fixture class different from the one\n" + << "used earlier. This can happen if the two fixture classes are\n" + << "from different namespaces and have the same name. You should\n" + << "probably rename one of the classes to put the tests into different\n" + << "test cases."; + + fprintf(stderr, "%s %s", FormatFileLocation(file, line).c_str(), + errors.GetString().c_str()); +} +#endif // GTEST_HAS_PARAM_TEST + +} // namespace internal + +// Returns the test case name. +const char* TestInfo::test_case_name() const { + return impl_->test_case_name(); +} + +// Returns the test name. +const char* TestInfo::name() const { + return impl_->name(); +} + +// Returns the test case comment. +const char* TestInfo::test_case_comment() const { + return impl_->test_case_comment(); +} + +// Returns the test comment. +const char* TestInfo::comment() const { + return impl_->comment(); +} + +// Returns true if this test should run. +bool TestInfo::should_run() const { return impl_->should_run(); } + +// Returns true if this test matches the user-specified filter. +bool TestInfo::matches_filter() const { return impl_->matches_filter(); } + +// Returns the result of the test. +const TestResult* TestInfo::result() const { return impl_->result(); } + +// Increments the number of death tests encountered in this test so +// far. +int TestInfo::increment_death_test_count() { + return impl_->result()->increment_death_test_count(); +} + +namespace { + +// A predicate that checks the test name of a TestInfo against a known +// value. +// +// This is used for implementation of the TestCase class only. We put +// it in the anonymous namespace to prevent polluting the outer +// namespace. +// +// TestNameIs is copyable. +class TestNameIs { + public: + // Constructor. + // + // TestNameIs has NO default constructor. + explicit TestNameIs(const char* name) + : name_(name) {} + + // Returns true iff the test name of test_info matches name_. + bool operator()(const TestInfo * test_info) const { + return test_info && internal::String(test_info->name()).Compare(name_) == 0; + } + + private: + internal::String name_; +}; + +} // namespace + +namespace internal { + +// This method expands all parameterized tests registered with macros TEST_P +// and INSTANTIATE_TEST_CASE_P into regular tests and registers those. +// This will be done just once during the program runtime. +void UnitTestImpl::RegisterParameterizedTests() { +#if GTEST_HAS_PARAM_TEST + if (!parameterized_tests_registered_) { + parameterized_test_registry_.RegisterTests(); + parameterized_tests_registered_ = true; + } +#endif +} + +// Creates the test object, runs it, records its result, and then +// deletes it. +void TestInfoImpl::Run() { + if (!should_run_) return; + + // Tells UnitTest where to store test result. + UnitTestImpl* const impl = internal::GetUnitTestImpl(); + impl->set_current_test_info(parent_); + + TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater(); + + // Notifies the unit test event listeners that a test is about to start. + repeater->OnTestStart(*parent_); + + const TimeInMillis start = GetTimeInMillis(); + + impl->os_stack_trace_getter()->UponLeavingGTest(); +#if GTEST_HAS_SEH + // Catch SEH-style exceptions. + Test* test = NULL; + + __try { + // Creates the test object. + test = factory_->CreateTest(); + } __except(internal::UnitTestOptions::GTestShouldProcessSEH( + GetExceptionCode())) { + AddExceptionThrownFailure(GetExceptionCode(), + "the test fixture's constructor"); + return; + } +#else // We are on a compiler or platform that doesn't support SEH. + + // TODO(wan): If test->Run() throws, test won't be deleted. This is + // not a problem now as we don't use exceptions. If we were to + // enable exceptions, we should revise the following to be + // exception-safe. + + // Creates the test object. + Test* test = factory_->CreateTest(); +#endif // GTEST_HAS_SEH + + // Runs the test only if the constructor of the test fixture didn't + // generate a fatal failure. + if (!Test::HasFatalFailure()) { + test->Run(); + } + + // Deletes the test object. + impl->os_stack_trace_getter()->UponLeavingGTest(); + delete test; + test = NULL; + + result_.set_elapsed_time(GetTimeInMillis() - start); + + // Notifies the unit test event listener that a test has just finished. + repeater->OnTestEnd(*parent_); + + // Tells UnitTest to stop associating assertion results to this + // test. + impl->set_current_test_info(NULL); +} + +} // namespace internal + +// class TestCase + +// Gets the number of successful tests in this test case. +int TestCase::successful_test_count() const { + return CountIf(test_info_list_, TestPassed); +} + +// Gets the number of failed tests in this test case. +int TestCase::failed_test_count() const { + return CountIf(test_info_list_, TestFailed); +} + +int TestCase::disabled_test_count() const { + return CountIf(test_info_list_, TestDisabled); +} + +// Get the number of tests in this test case that should run. +int TestCase::test_to_run_count() const { + return CountIf(test_info_list_, ShouldRunTest); +} + +// Gets the number of all tests. +int TestCase::total_test_count() const { + return static_cast<int>(test_info_list_.size()); +} + +// Creates a TestCase with the given name. +// +// Arguments: +// +// name: name of the test case +// set_up_tc: pointer to the function that sets up the test case +// tear_down_tc: pointer to the function that tears down the test case +TestCase::TestCase(const char* a_name, const char* a_comment, + Test::SetUpTestCaseFunc set_up_tc, + Test::TearDownTestCaseFunc tear_down_tc) + : name_(a_name), + comment_(a_comment), + set_up_tc_(set_up_tc), + tear_down_tc_(tear_down_tc), + should_run_(false), + elapsed_time_(0) { +} + +// Destructor of TestCase. +TestCase::~TestCase() { + // Deletes every Test in the collection. + ForEach(test_info_list_, internal::Delete<TestInfo>); +} + +// Returns the i-th test among all the tests. i can range from 0 to +// total_test_count() - 1. If i is not in that range, returns NULL. +const TestInfo* TestCase::GetTestInfo(int i) const { + const int index = GetElementOr(test_indices_, i, -1); + return index < 0 ? NULL : test_info_list_[index]; +} + +// Returns the i-th test among all the tests. i can range from 0 to +// total_test_count() - 1. If i is not in that range, returns NULL. +TestInfo* TestCase::GetMutableTestInfo(int i) { + const int index = GetElementOr(test_indices_, i, -1); + return index < 0 ? NULL : test_info_list_[index]; +} + +// Adds a test to this test case. Will delete the test upon +// destruction of the TestCase object. +void TestCase::AddTestInfo(TestInfo * test_info) { + test_info_list_.push_back(test_info); + test_indices_.push_back(static_cast<int>(test_indices_.size())); +} + +// Runs every test in this TestCase. +void TestCase::Run() { + if (!should_run_) return; + + internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); + impl->set_current_test_case(this); + + TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater(); + + repeater->OnTestCaseStart(*this); + impl->os_stack_trace_getter()->UponLeavingGTest(); + set_up_tc_(); + + const internal::TimeInMillis start = internal::GetTimeInMillis(); + for (int i = 0; i < total_test_count(); i++) { + GetMutableTestInfo(i)->impl()->Run(); + } + elapsed_time_ = internal::GetTimeInMillis() - start; + + impl->os_stack_trace_getter()->UponLeavingGTest(); + tear_down_tc_(); + repeater->OnTestCaseEnd(*this); + impl->set_current_test_case(NULL); +} + +// Clears the results of all tests in this test case. +void TestCase::ClearResult() { + ForEach(test_info_list_, internal::TestInfoImpl::ClearTestResult); +} + +// Returns true iff test passed. +bool TestCase::TestPassed(const TestInfo * test_info) { + const internal::TestInfoImpl* const impl = test_info->impl(); + return impl->should_run() && impl->result()->Passed(); +} + +// Returns true iff test failed. +bool TestCase::TestFailed(const TestInfo * test_info) { + const internal::TestInfoImpl* const impl = test_info->impl(); + return impl->should_run() && impl->result()->Failed(); +} + +// Returns true iff test is disabled. +bool TestCase::TestDisabled(const TestInfo * test_info) { + return test_info->impl()->is_disabled(); +} + +// Returns true if the given test should run. +bool TestCase::ShouldRunTest(const TestInfo *test_info) { + return test_info->impl()->should_run(); +} + +// Shuffles the tests in this test case. +void TestCase::ShuffleTests(internal::Random* random) { + Shuffle(random, &test_indices_); +} + +// Restores the test order to before the first shuffle. +void TestCase::UnshuffleTests() { + for (size_t i = 0; i < test_indices_.size(); i++) { + test_indices_[i] = static_cast<int>(i); + } +} + +// Formats a countable noun. Depending on its quantity, either the +// singular form or the plural form is used. e.g. +// +// FormatCountableNoun(1, "formula", "formuli") returns "1 formula". +// FormatCountableNoun(5, "book", "books") returns "5 books". +static internal::String FormatCountableNoun(int count, + const char * singular_form, + const char * plural_form) { + return internal::String::Format("%d %s", count, + count == 1 ? singular_form : plural_form); +} + +// Formats the count of tests. +static internal::String FormatTestCount(int test_count) { + return FormatCountableNoun(test_count, "test", "tests"); +} + +// Formats the count of test cases. +static internal::String FormatTestCaseCount(int test_case_count) { + return FormatCountableNoun(test_case_count, "test case", "test cases"); +} + +// Converts a TestPartResult::Type enum to human-friendly string +// representation. Both kNonFatalFailure and kFatalFailure are translated +// to "Failure", as the user usually doesn't care about the difference +// between the two when viewing the test result. +static const char * TestPartResultTypeToString(TestPartResult::Type type) { + switch (type) { + case TestPartResult::kSuccess: + return "Success"; + + case TestPartResult::kNonFatalFailure: + case TestPartResult::kFatalFailure: +#ifdef _MSC_VER + return "error: "; +#else + return "Failure\n"; +#endif + } + + return "Unknown result type"; +} + +// Prints a TestPartResult to a String. +static internal::String PrintTestPartResultToString( + const TestPartResult& test_part_result) { + return (Message() + << internal::FormatFileLocation(test_part_result.file_name(), + test_part_result.line_number()) + << " " << TestPartResultTypeToString(test_part_result.type()) + << test_part_result.message()).GetString(); +} + +// Prints a TestPartResult. +static void PrintTestPartResult(const TestPartResult& test_part_result) { + const internal::String& result = + PrintTestPartResultToString(test_part_result); + printf("%s\n", result.c_str()); + fflush(stdout); + // If the test program runs in Visual Studio or a debugger, the + // following statements add the test part result message to the Output + // window such that the user can double-click on it to jump to the + // corresponding source code location; otherwise they do nothing. +#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE + // We don't call OutputDebugString*() on Windows Mobile, as printing + // to stdout is done by OutputDebugString() there already - we don't + // want the same message printed twice. + ::OutputDebugStringA(result.c_str()); + ::OutputDebugStringA("\n"); +#endif +} + +// class PrettyUnitTestResultPrinter + +namespace internal { + +enum GTestColor { + COLOR_DEFAULT, + COLOR_RED, + COLOR_GREEN, + COLOR_YELLOW +}; + +#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE + +// Returns the character attribute for the given color. +WORD GetColorAttribute(GTestColor color) { + switch (color) { + case COLOR_RED: return FOREGROUND_RED; + case COLOR_GREEN: return FOREGROUND_GREEN; + case COLOR_YELLOW: return FOREGROUND_RED | FOREGROUND_GREEN; + default: return 0; + } +} + +#else + +// Returns the ANSI color code for the given color. COLOR_DEFAULT is +// an invalid input. +const char* GetAnsiColorCode(GTestColor color) { + switch (color) { + case COLOR_RED: return "1"; + case COLOR_GREEN: return "2"; + case COLOR_YELLOW: return "3"; + default: return NULL; + }; +} + +#endif // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE + +// Returns true iff Google Test should use colors in the output. +bool ShouldUseColor(bool stdout_is_tty) { + const char* const gtest_color = GTEST_FLAG(color).c_str(); + + if (String::CaseInsensitiveCStringEquals(gtest_color, "auto")) { +#if GTEST_OS_WINDOWS + // On Windows the TERM variable is usually not set, but the + // console there does support colors. + return stdout_is_tty; +#else + // On non-Windows platforms, we rely on the TERM variable. + const char* const term = posix::GetEnv("TERM"); + const bool term_supports_color = + String::CStringEquals(term, "xterm") || + String::CStringEquals(term, "xterm-color") || + String::CStringEquals(term, "xterm-256color") || + String::CStringEquals(term, "linux") || + String::CStringEquals(term, "cygwin"); + return stdout_is_tty && term_supports_color; +#endif // GTEST_OS_WINDOWS + } + + return String::CaseInsensitiveCStringEquals(gtest_color, "yes") || + String::CaseInsensitiveCStringEquals(gtest_color, "true") || + String::CaseInsensitiveCStringEquals(gtest_color, "t") || + String::CStringEquals(gtest_color, "1"); + // We take "yes", "true", "t", and "1" as meaning "yes". If the + // value is neither one of these nor "auto", we treat it as "no" to + // be conservative. +} + +// Helpers for printing colored strings to stdout. Note that on Windows, we +// cannot simply emit special characters and have the terminal change colors. +// This routine must actually emit the characters rather than return a string +// that would be colored when printed, as can be done on Linux. +void ColoredPrintf(GTestColor color, const char* fmt, ...) { + va_list args; + va_start(args, fmt); + +#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_SYMBIAN || GTEST_OS_ZOS + const bool use_color = false; +#else + static const bool in_color_mode = + ShouldUseColor(posix::IsATTY(posix::FileNo(stdout)) != 0); + const bool use_color = in_color_mode && (color != COLOR_DEFAULT); +#endif // GTEST_OS_WINDOWS_MOBILE || GTEST_OS_SYMBIAN || GTEST_OS_ZOS + // The '!= 0' comparison is necessary to satisfy MSVC 7.1. + + if (!use_color) { + vprintf(fmt, args); + va_end(args); + return; + } + +#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE + const HANDLE stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE); + + // Gets the current text color. + CONSOLE_SCREEN_BUFFER_INFO buffer_info; + GetConsoleScreenBufferInfo(stdout_handle, &buffer_info); + const WORD old_color_attrs = buffer_info.wAttributes; + + // We need to flush the stream buffers into the console before each + // SetConsoleTextAttribute call lest it affect the text that is already + // printed but has not yet reached the console. + fflush(stdout); + SetConsoleTextAttribute(stdout_handle, + GetColorAttribute(color) | FOREGROUND_INTENSITY); + vprintf(fmt, args); + + fflush(stdout); + // Restores the text color. + SetConsoleTextAttribute(stdout_handle, old_color_attrs); +#else + printf("\033[0;3%sm", GetAnsiColorCode(color)); + vprintf(fmt, args); + printf("\033[m"); // Resets the terminal to default. +#endif // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE + va_end(args); +} + +// This class implements the TestEventListener interface. +// +// Class PrettyUnitTestResultPrinter is copyable. +class PrettyUnitTestResultPrinter : public TestEventListener { + public: + PrettyUnitTestResultPrinter() {} + static void PrintTestName(const char * test_case, const char * test) { + printf("%s.%s", test_case, test); + } + + // The following methods override what's in the TestEventListener class. + virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) {} + virtual void OnTestIterationStart(const UnitTest& unit_test, int iteration); + virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test); + virtual void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) {} + virtual void OnTestCaseStart(const TestCase& test_case); + virtual void OnTestStart(const TestInfo& test_info); + virtual void OnTestPartResult(const TestPartResult& result); + virtual void OnTestEnd(const TestInfo& test_info); + virtual void OnTestCaseEnd(const TestCase& test_case); + virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test); + virtual void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) {} + virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration); + virtual void OnTestProgramEnd(const UnitTest& /*unit_test*/) {} + + private: + static void PrintFailedTests(const UnitTest& unit_test); + + internal::String test_case_name_; +}; + + // Fired before each iteration of tests starts. +void PrettyUnitTestResultPrinter::OnTestIterationStart( + const UnitTest& unit_test, int iteration) { + if (GTEST_FLAG(repeat) != 1) + printf("\nRepeating all tests (iteration %d) . . .\n\n", iteration + 1); + + const char* const filter = GTEST_FLAG(filter).c_str(); + + // Prints the filter if it's not *. This reminds the user that some + // tests may be skipped. + if (!internal::String::CStringEquals(filter, kUniversalFilter)) { + ColoredPrintf(COLOR_YELLOW, + "Note: %s filter = %s\n", GTEST_NAME_, filter); + } + + if (internal::ShouldShard(kTestTotalShards, kTestShardIndex, false)) { + ColoredPrintf(COLOR_YELLOW, + "Note: This is test shard %s of %s.\n", + internal::posix::GetEnv(kTestShardIndex), + internal::posix::GetEnv(kTestTotalShards)); + } + + if (GTEST_FLAG(shuffle)) { + ColoredPrintf(COLOR_YELLOW, + "Note: Randomizing tests' orders with a seed of %d .\n", + unit_test.random_seed()); + } + + ColoredPrintf(COLOR_GREEN, "[==========] "); + printf("Running %s from %s.\n", + FormatTestCount(unit_test.test_to_run_count()).c_str(), + FormatTestCaseCount(unit_test.test_case_to_run_count()).c_str()); + fflush(stdout); +} + +void PrettyUnitTestResultPrinter::OnEnvironmentsSetUpStart( + const UnitTest& /*unit_test*/) { + ColoredPrintf(COLOR_GREEN, "[----------] "); + printf("Global test environment set-up.\n"); + fflush(stdout); +} + +void PrettyUnitTestResultPrinter::OnTestCaseStart(const TestCase& test_case) { + test_case_name_ = test_case.name(); + const internal::String counts = + FormatCountableNoun(test_case.test_to_run_count(), "test", "tests"); + ColoredPrintf(COLOR_GREEN, "[----------] "); + printf("%s from %s", counts.c_str(), test_case_name_.c_str()); + if (test_case.comment()[0] == '\0') { + printf("\n"); + } else { + printf(", where %s\n", test_case.comment()); + } + fflush(stdout); +} + +void PrettyUnitTestResultPrinter::OnTestStart(const TestInfo& test_info) { + ColoredPrintf(COLOR_GREEN, "[ RUN ] "); + PrintTestName(test_case_name_.c_str(), test_info.name()); + if (test_info.comment()[0] == '\0') { + printf("\n"); + } else { + printf(", where %s\n", test_info.comment()); + } + fflush(stdout); +} + +// Called after an assertion failure. +void PrettyUnitTestResultPrinter::OnTestPartResult( + const TestPartResult& result) { + // If the test part succeeded, we don't need to do anything. + if (result.type() == TestPartResult::kSuccess) + return; + + // Print failure message from the assertion (e.g. expected this and got that). + PrintTestPartResult(result); + fflush(stdout); +} + +void PrettyUnitTestResultPrinter::OnTestEnd(const TestInfo& test_info) { + if (test_info.result()->Passed()) { + ColoredPrintf(COLOR_GREEN, "[ OK ] "); + } else { + ColoredPrintf(COLOR_RED, "[ FAILED ] "); + } + PrintTestName(test_case_name_.c_str(), test_info.name()); + if (GTEST_FLAG(print_time)) { + printf(" (%s ms)\n", internal::StreamableToString( + test_info.result()->elapsed_time()).c_str()); + } else { + printf("\n"); + } + fflush(stdout); +} + +void PrettyUnitTestResultPrinter::OnTestCaseEnd(const TestCase& test_case) { + if (!GTEST_FLAG(print_time)) return; + + test_case_name_ = test_case.name(); + const internal::String counts = + FormatCountableNoun(test_case.test_to_run_count(), "test", "tests"); + ColoredPrintf(COLOR_GREEN, "[----------] "); + printf("%s from %s (%s ms total)\n\n", + counts.c_str(), test_case_name_.c_str(), + internal::StreamableToString(test_case.elapsed_time()).c_str()); + fflush(stdout); +} + +void PrettyUnitTestResultPrinter::OnEnvironmentsTearDownStart( + const UnitTest& /*unit_test*/) { + ColoredPrintf(COLOR_GREEN, "[----------] "); + printf("Global test environment tear-down\n"); + fflush(stdout); +} + +// Internal helper for printing the list of failed tests. +void PrettyUnitTestResultPrinter::PrintFailedTests(const UnitTest& unit_test) { + const int failed_test_count = unit_test.failed_test_count(); + if (failed_test_count == 0) { + return; + } + + for (int i = 0; i < unit_test.total_test_case_count(); ++i) { + const TestCase& test_case = *unit_test.GetTestCase(i); + if (!test_case.should_run() || (test_case.failed_test_count() == 0)) { + continue; + } + for (int j = 0; j < test_case.total_test_count(); ++j) { + const TestInfo& test_info = *test_case.GetTestInfo(j); + if (!test_info.should_run() || test_info.result()->Passed()) { + continue; + } + ColoredPrintf(COLOR_RED, "[ FAILED ] "); + printf("%s.%s", test_case.name(), test_info.name()); + if (test_case.comment()[0] != '\0' || + test_info.comment()[0] != '\0') { + printf(", where %s", test_case.comment()); + if (test_case.comment()[0] != '\0' && + test_info.comment()[0] != '\0') { + printf(" and "); + } + } + printf("%s\n", test_info.comment()); + } + } +} + + void PrettyUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test, + int /*iteration*/) { + ColoredPrintf(COLOR_GREEN, "[==========] "); + printf("%s from %s ran.", + FormatTestCount(unit_test.test_to_run_count()).c_str(), + FormatTestCaseCount(unit_test.test_case_to_run_count()).c_str()); + if (GTEST_FLAG(print_time)) { + printf(" (%s ms total)", + internal::StreamableToString(unit_test.elapsed_time()).c_str()); + } + printf("\n"); + ColoredPrintf(COLOR_GREEN, "[ PASSED ] "); + printf("%s.\n", FormatTestCount(unit_test.successful_test_count()).c_str()); + + int num_failures = unit_test.failed_test_count(); + if (!unit_test.Passed()) { + const int failed_test_count = unit_test.failed_test_count(); + ColoredPrintf(COLOR_RED, "[ FAILED ] "); + printf("%s, listed below:\n", FormatTestCount(failed_test_count).c_str()); + PrintFailedTests(unit_test); + printf("\n%2d FAILED %s\n", num_failures, + num_failures == 1 ? "TEST" : "TESTS"); + } + + int num_disabled = unit_test.disabled_test_count(); + if (num_disabled && !GTEST_FLAG(also_run_disabled_tests)) { + if (!num_failures) { + printf("\n"); // Add a spacer if no FAILURE banner is displayed. + } + ColoredPrintf(COLOR_YELLOW, + " YOU HAVE %d DISABLED %s\n\n", + num_disabled, + num_disabled == 1 ? "TEST" : "TESTS"); + } + // Ensure that Google Test output is printed before, e.g., heapchecker output. + fflush(stdout); +} + +// End PrettyUnitTestResultPrinter + +// class TestEventRepeater +// +// This class forwards events to other event listeners. +class TestEventRepeater : public TestEventListener { + public: + TestEventRepeater() : forwarding_enabled_(true) {} + virtual ~TestEventRepeater(); + void Append(TestEventListener *listener); + TestEventListener* Release(TestEventListener* listener); + + // Controls whether events will be forwarded to listeners_. Set to false + // in death test child processes. + bool forwarding_enabled() const { return forwarding_enabled_; } + void set_forwarding_enabled(bool enable) { forwarding_enabled_ = enable; } + + virtual void OnTestProgramStart(const UnitTest& unit_test); + virtual void OnTestIterationStart(const UnitTest& unit_test, int iteration); + virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test); + virtual void OnEnvironmentsSetUpEnd(const UnitTest& unit_test); + virtual void OnTestCaseStart(const TestCase& test_case); + virtual void OnTestStart(const TestInfo& test_info); + virtual void OnTestPartResult(const TestPartResult& result); + virtual void OnTestEnd(const TestInfo& test_info); + virtual void OnTestCaseEnd(const TestCase& test_case); + virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test); + virtual void OnEnvironmentsTearDownEnd(const UnitTest& unit_test); + virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration); + virtual void OnTestProgramEnd(const UnitTest& unit_test); + + private: + // Controls whether events will be forwarded to listeners_. Set to false + // in death test child processes. + bool forwarding_enabled_; + // The list of listeners that receive events. + std::vector<TestEventListener*> listeners_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestEventRepeater); +}; + +TestEventRepeater::~TestEventRepeater() { + ForEach(listeners_, Delete<TestEventListener>); +} + +void TestEventRepeater::Append(TestEventListener *listener) { + listeners_.push_back(listener); +} + +// TODO(vladl@google.com): Factor the search functionality into Vector::Find. +TestEventListener* TestEventRepeater::Release(TestEventListener *listener) { + for (size_t i = 0; i < listeners_.size(); ++i) { + if (listeners_[i] == listener) { + listeners_.erase(listeners_.begin() + i); + return listener; + } + } + + return NULL; +} + +// Since most methods are very similar, use macros to reduce boilerplate. +// This defines a member that forwards the call to all listeners. +#define GTEST_REPEATER_METHOD_(Name, Type) \ +void TestEventRepeater::Name(const Type& parameter) { \ + if (forwarding_enabled_) { \ + for (size_t i = 0; i < listeners_.size(); i++) { \ + listeners_[i]->Name(parameter); \ + } \ + } \ +} +// This defines a member that forwards the call to all listeners in reverse +// order. +#define GTEST_REVERSE_REPEATER_METHOD_(Name, Type) \ +void TestEventRepeater::Name(const Type& parameter) { \ + if (forwarding_enabled_) { \ + for (int i = static_cast<int>(listeners_.size()) - 1; i >= 0; i--) { \ + listeners_[i]->Name(parameter); \ + } \ + } \ +} + +GTEST_REPEATER_METHOD_(OnTestProgramStart, UnitTest) +GTEST_REPEATER_METHOD_(OnEnvironmentsSetUpStart, UnitTest) +GTEST_REPEATER_METHOD_(OnTestCaseStart, TestCase) +GTEST_REPEATER_METHOD_(OnTestStart, TestInfo) +GTEST_REPEATER_METHOD_(OnTestPartResult, TestPartResult) +GTEST_REPEATER_METHOD_(OnEnvironmentsTearDownStart, UnitTest) +GTEST_REVERSE_REPEATER_METHOD_(OnEnvironmentsSetUpEnd, UnitTest) +GTEST_REVERSE_REPEATER_METHOD_(OnEnvironmentsTearDownEnd, UnitTest) +GTEST_REVERSE_REPEATER_METHOD_(OnTestEnd, TestInfo) +GTEST_REVERSE_REPEATER_METHOD_(OnTestCaseEnd, TestCase) +GTEST_REVERSE_REPEATER_METHOD_(OnTestProgramEnd, UnitTest) + +#undef GTEST_REPEATER_METHOD_ +#undef GTEST_REVERSE_REPEATER_METHOD_ + +void TestEventRepeater::OnTestIterationStart(const UnitTest& unit_test, + int iteration) { + if (forwarding_enabled_) { + for (size_t i = 0; i < listeners_.size(); i++) { + listeners_[i]->OnTestIterationStart(unit_test, iteration); + } + } +} + +void TestEventRepeater::OnTestIterationEnd(const UnitTest& unit_test, + int iteration) { + if (forwarding_enabled_) { + for (int i = static_cast<int>(listeners_.size()) - 1; i >= 0; i--) { + listeners_[i]->OnTestIterationEnd(unit_test, iteration); + } + } +} + +// End TestEventRepeater + +// This class generates an XML output file. +class XmlUnitTestResultPrinter : public EmptyTestEventListener { + public: + explicit XmlUnitTestResultPrinter(const char* output_file); + + virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration); + + private: + // Is c a whitespace character that is normalized to a space character + // when it appears in an XML attribute value? + static bool IsNormalizableWhitespace(char c) { + return c == 0x9 || c == 0xA || c == 0xD; + } + + // May c appear in a well-formed XML document? + static bool IsValidXmlCharacter(char c) { + return IsNormalizableWhitespace(c) || c >= 0x20; + } + + // Returns an XML-escaped copy of the input string str. If + // is_attribute is true, the text is meant to appear as an attribute + // value, and normalizable whitespace is preserved by replacing it + // with character references. + static String EscapeXml(const char* str, bool is_attribute); + + // Returns the given string with all characters invalid in XML removed. + static String RemoveInvalidXmlCharacters(const char* str); + + // Convenience wrapper around EscapeXml when str is an attribute value. + static String EscapeXmlAttribute(const char* str) { + return EscapeXml(str, true); + } + + // Convenience wrapper around EscapeXml when str is not an attribute value. + static String EscapeXmlText(const char* str) { return EscapeXml(str, false); } + + // Streams an XML CDATA section, escaping invalid CDATA sequences as needed. + static void OutputXmlCDataSection(::std::ostream* stream, const char* data); + + // Streams an XML representation of a TestInfo object. + static void OutputXmlTestInfo(::std::ostream* stream, + const char* test_case_name, + const TestInfo& test_info); + + // Prints an XML representation of a TestCase object + static void PrintXmlTestCase(FILE* out, const TestCase& test_case); + + // Prints an XML summary of unit_test to output stream out. + static void PrintXmlUnitTest(FILE* out, const UnitTest& unit_test); + + // Produces a string representing the test properties in a result as space + // delimited XML attributes based on the property key="value" pairs. + // When the String is not empty, it includes a space at the beginning, + // to delimit this attribute from prior attributes. + static String TestPropertiesAsXmlAttributes(const TestResult& result); + + // The output file. + const String output_file_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(XmlUnitTestResultPrinter); +}; + +// Creates a new XmlUnitTestResultPrinter. +XmlUnitTestResultPrinter::XmlUnitTestResultPrinter(const char* output_file) + : output_file_(output_file) { + if (output_file_.c_str() == NULL || output_file_.empty()) { + fprintf(stderr, "XML output file may not be null\n"); + fflush(stderr); + exit(EXIT_FAILURE); + } +} + +// Called after the unit test ends. +void XmlUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test, + int /*iteration*/) { + FILE* xmlout = NULL; + FilePath output_file(output_file_); + FilePath output_dir(output_file.RemoveFileName()); + + if (output_dir.CreateDirectoriesRecursively()) { + xmlout = posix::FOpen(output_file_.c_str(), "w"); + } + if (xmlout == NULL) { + // TODO(wan): report the reason of the failure. + // + // We don't do it for now as: + // + // 1. There is no urgent need for it. + // 2. It's a bit involved to make the errno variable thread-safe on + // all three operating systems (Linux, Windows, and Mac OS). + // 3. To interpret the meaning of errno in a thread-safe way, + // we need the strerror_r() function, which is not available on + // Windows. + fprintf(stderr, + "Unable to open file \"%s\"\n", + output_file_.c_str()); + fflush(stderr); + exit(EXIT_FAILURE); + } + PrintXmlUnitTest(xmlout, unit_test); + fclose(xmlout); +} + +// Returns an XML-escaped copy of the input string str. If is_attribute +// is true, the text is meant to appear as an attribute value, and +// normalizable whitespace is preserved by replacing it with character +// references. +// +// Invalid XML characters in str, if any, are stripped from the output. +// It is expected that most, if not all, of the text processed by this +// module will consist of ordinary English text. +// If this module is ever modified to produce version 1.1 XML output, +// most invalid characters can be retained using character references. +// TODO(wan): It might be nice to have a minimally invasive, human-readable +// escaping scheme for invalid characters, rather than dropping them. +String XmlUnitTestResultPrinter::EscapeXml(const char* str, bool is_attribute) { + Message m; + + if (str != NULL) { + for (const char* src = str; *src; ++src) { + switch (*src) { + case '<': + m << "<"; + break; + case '>': + m << ">"; + break; + case '&': + m << "&"; + break; + case '\'': + if (is_attribute) + m << "'"; + else + m << '\''; + break; + case '"': + if (is_attribute) + m << """; + else + m << '"'; + break; + default: + if (IsValidXmlCharacter(*src)) { + if (is_attribute && IsNormalizableWhitespace(*src)) + m << String::Format("&#x%02X;", unsigned(*src)); + else + m << *src; + } + break; + } + } + } + + return m.GetString(); +} + +// Returns the given string with all characters invalid in XML removed. +// Currently invalid characters are dropped from the string. An +// alternative is to replace them with certain characters such as . or ?. +String XmlUnitTestResultPrinter::RemoveInvalidXmlCharacters(const char* str) { + char* const output = new char[strlen(str) + 1]; + char* appender = output; + for (char ch = *str; ch != '\0'; ch = *++str) + if (IsValidXmlCharacter(ch)) + *appender++ = ch; + *appender = '\0'; + + String ret_value(output); + delete[] output; + return ret_value; +} + +// The following routines generate an XML representation of a UnitTest +// object. +// +// This is how Google Test concepts map to the DTD: +// +// <testsuites name="AllTests"> <-- corresponds to a UnitTest object +// <testsuite name="testcase-name"> <-- corresponds to a TestCase object +// <testcase name="test-name"> <-- corresponds to a TestInfo object +// <failure message="...">...</failure> +// <failure message="...">...</failure> +// <failure message="...">...</failure> +// <-- individual assertion failures +// </testcase> +// </testsuite> +// </testsuites> + +// Formats the given time in milliseconds as seconds. +std::string FormatTimeInMillisAsSeconds(TimeInMillis ms) { + ::std::stringstream ss; + ss << ms/1000.0; + return ss.str(); +} + +// Streams an XML CDATA section, escaping invalid CDATA sequences as needed. +void XmlUnitTestResultPrinter::OutputXmlCDataSection(::std::ostream* stream, + const char* data) { + const char* segment = data; + *stream << "<![CDATA["; + for (;;) { + const char* const next_segment = strstr(segment, "]]>"); + if (next_segment != NULL) { + stream->write( + segment, static_cast<std::streamsize>(next_segment - segment)); + *stream << "]]>]]><![CDATA["; + segment = next_segment + strlen("]]>"); + } else { + *stream << segment; + break; + } + } + *stream << "]]>"; +} + +// Prints an XML representation of a TestInfo object. +// TODO(wan): There is also value in printing properties with the plain printer. +void XmlUnitTestResultPrinter::OutputXmlTestInfo(::std::ostream* stream, + const char* test_case_name, + const TestInfo& test_info) { + const TestResult& result = *test_info.result(); + *stream << " <testcase name=\"" + << EscapeXmlAttribute(test_info.name()).c_str() + << "\" status=\"" + << (test_info.should_run() ? "run" : "notrun") + << "\" time=\"" + << FormatTimeInMillisAsSeconds(result.elapsed_time()) + << "\" classname=\"" << EscapeXmlAttribute(test_case_name).c_str() + << "\"" << TestPropertiesAsXmlAttributes(result).c_str(); + + int failures = 0; + for (int i = 0; i < result.total_part_count(); ++i) { + const TestPartResult& part = result.GetTestPartResult(i); + if (part.failed()) { + if (++failures == 1) + *stream << ">\n"; + *stream << " <failure message=\"" + << EscapeXmlAttribute(part.summary()).c_str() + << "\" type=\"\">"; + const String message = RemoveInvalidXmlCharacters(String::Format( + "%s:%d\n%s", + part.file_name(), part.line_number(), + part.message()).c_str()); + OutputXmlCDataSection(stream, message.c_str()); + *stream << "</failure>\n"; + } + } + + if (failures == 0) + *stream << " />\n"; + else + *stream << " </testcase>\n"; +} + +// Prints an XML representation of a TestCase object +void XmlUnitTestResultPrinter::PrintXmlTestCase(FILE* out, + const TestCase& test_case) { + fprintf(out, + " <testsuite name=\"%s\" tests=\"%d\" failures=\"%d\" " + "disabled=\"%d\" ", + EscapeXmlAttribute(test_case.name()).c_str(), + test_case.total_test_count(), + test_case.failed_test_count(), + test_case.disabled_test_count()); + fprintf(out, + "errors=\"0\" time=\"%s\">\n", + FormatTimeInMillisAsSeconds(test_case.elapsed_time()).c_str()); + for (int i = 0; i < test_case.total_test_count(); ++i) { + StrStream stream; + OutputXmlTestInfo(&stream, test_case.name(), *test_case.GetTestInfo(i)); + fprintf(out, "%s", StrStreamToString(&stream).c_str()); + } + fprintf(out, " </testsuite>\n"); +} + +// Prints an XML summary of unit_test to output stream out. +void XmlUnitTestResultPrinter::PrintXmlUnitTest(FILE* out, + const UnitTest& unit_test) { + fprintf(out, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"); + fprintf(out, + "<testsuites tests=\"%d\" failures=\"%d\" disabled=\"%d\" " + "errors=\"0\" time=\"%s\" ", + unit_test.total_test_count(), + unit_test.failed_test_count(), + unit_test.disabled_test_count(), + FormatTimeInMillisAsSeconds(unit_test.elapsed_time()).c_str()); + if (GTEST_FLAG(shuffle)) { + fprintf(out, "random_seed=\"%d\" ", unit_test.random_seed()); + } + fprintf(out, "name=\"AllTests\">\n"); + for (int i = 0; i < unit_test.total_test_case_count(); ++i) + PrintXmlTestCase(out, *unit_test.GetTestCase(i)); + fprintf(out, "</testsuites>\n"); +} + +// Produces a string representing the test properties in a result as space +// delimited XML attributes based on the property key="value" pairs. +String XmlUnitTestResultPrinter::TestPropertiesAsXmlAttributes( + const TestResult& result) { + Message attributes; + for (int i = 0; i < result.test_property_count(); ++i) { + const TestProperty& property = result.GetTestProperty(i); + attributes << " " << property.key() << "=" + << "\"" << EscapeXmlAttribute(property.value()) << "\""; + } + return attributes.GetString(); +} + +// End XmlUnitTestResultPrinter + +// Class ScopedTrace + +// Pushes the given source file location and message onto a per-thread +// trace stack maintained by Google Test. +// L < UnitTest::mutex_ +ScopedTrace::ScopedTrace(const char* file, int line, const Message& message) { + TraceInfo trace; + trace.file = file; + trace.line = line; + trace.message = message.GetString(); + + UnitTest::GetInstance()->PushGTestTrace(trace); +} + +// Pops the info pushed by the c'tor. +// L < UnitTest::mutex_ +ScopedTrace::~ScopedTrace() { + UnitTest::GetInstance()->PopGTestTrace(); +} + + +// class OsStackTraceGetter + +// Returns the current OS stack trace as a String. Parameters: +// +// max_depth - the maximum number of stack frames to be included +// in the trace. +// skip_count - the number of top frames to be skipped; doesn't count +// against max_depth. +// +// L < mutex_ +// We use "L < mutex_" to denote that the function may acquire mutex_. +String OsStackTraceGetter::CurrentStackTrace(int, int) { + return String(""); +} + +// L < mutex_ +void OsStackTraceGetter::UponLeavingGTest() { +} + +const char* const +OsStackTraceGetter::kElidedFramesMarker = + "... " GTEST_NAME_ " internal frames ..."; + +} // namespace internal + +// class TestEventListeners + +TestEventListeners::TestEventListeners() + : repeater_(new internal::TestEventRepeater()), + default_result_printer_(NULL), + default_xml_generator_(NULL) { +} + +TestEventListeners::~TestEventListeners() { delete repeater_; } + +// Returns the standard listener responsible for the default console +// output. Can be removed from the listeners list to shut down default +// console output. Note that removing this object from the listener list +// with Release transfers its ownership to the user. +void TestEventListeners::Append(TestEventListener* listener) { + repeater_->Append(listener); +} + +// Removes the given event listener from the list and returns it. It then +// becomes the caller's responsibility to delete the listener. Returns +// NULL if the listener is not found in the list. +TestEventListener* TestEventListeners::Release(TestEventListener* listener) { + if (listener == default_result_printer_) + default_result_printer_ = NULL; + else if (listener == default_xml_generator_) + default_xml_generator_ = NULL; + return repeater_->Release(listener); +} + +// Returns repeater that broadcasts the TestEventListener events to all +// subscribers. +TestEventListener* TestEventListeners::repeater() { return repeater_; } + +// Sets the default_result_printer attribute to the provided listener. +// The listener is also added to the listener list and previous +// default_result_printer is removed from it and deleted. The listener can +// also be NULL in which case it will not be added to the list. Does +// nothing if the previous and the current listener objects are the same. +void TestEventListeners::SetDefaultResultPrinter(TestEventListener* listener) { + if (default_result_printer_ != listener) { + // It is an error to pass this method a listener that is already in the + // list. + delete Release(default_result_printer_); + default_result_printer_ = listener; + if (listener != NULL) + Append(listener); + } +} + +// Sets the default_xml_generator attribute to the provided listener. The +// listener is also added to the listener list and previous +// default_xml_generator is removed from it and deleted. The listener can +// also be NULL in which case it will not be added to the list. Does +// nothing if the previous and the current listener objects are the same. +void TestEventListeners::SetDefaultXmlGenerator(TestEventListener* listener) { + if (default_xml_generator_ != listener) { + // It is an error to pass this method a listener that is already in the + // list. + delete Release(default_xml_generator_); + default_xml_generator_ = listener; + if (listener != NULL) + Append(listener); + } +} + +// Controls whether events will be forwarded by the repeater to the +// listeners in the list. +bool TestEventListeners::EventForwardingEnabled() const { + return repeater_->forwarding_enabled(); +} + +void TestEventListeners::SuppressEventForwarding() { + repeater_->set_forwarding_enabled(false); +} + +// class UnitTest + +// Gets the singleton UnitTest object. The first time this method is +// called, a UnitTest object is constructed and returned. Consecutive +// calls will return the same object. +// +// We don't protect this under mutex_ as a user is not supposed to +// call this before main() starts, from which point on the return +// value will never change. +UnitTest * UnitTest::GetInstance() { + // When compiled with MSVC 7.1 in optimized mode, destroying the + // UnitTest object upon exiting the program messes up the exit code, + // causing successful tests to appear failed. We have to use a + // different implementation in this case to bypass the compiler bug. + // This implementation makes the compiler happy, at the cost of + // leaking the UnitTest object. + + // CodeGear C++Builder insists on a public destructor for the + // default implementation. Use this implementation to keep good OO + // design with private destructor. + +#if (_MSC_VER == 1310 && !defined(_DEBUG)) || defined(__BORLANDC__) + static UnitTest* const instance = new UnitTest; + return instance; +#else + static UnitTest instance; + return &instance; +#endif // (_MSC_VER == 1310 && !defined(_DEBUG)) || defined(__BORLANDC__) +} + +// Gets the number of successful test cases. +int UnitTest::successful_test_case_count() const { + return impl()->successful_test_case_count(); +} + +// Gets the number of failed test cases. +int UnitTest::failed_test_case_count() const { + return impl()->failed_test_case_count(); +} + +// Gets the number of all test cases. +int UnitTest::total_test_case_count() const { + return impl()->total_test_case_count(); +} + +// Gets the number of all test cases that contain at least one test +// that should run. +int UnitTest::test_case_to_run_count() const { + return impl()->test_case_to_run_count(); +} + +// Gets the number of successful tests. +int UnitTest::successful_test_count() const { + return impl()->successful_test_count(); +} + +// Gets the number of failed tests. +int UnitTest::failed_test_count() const { return impl()->failed_test_count(); } + +// Gets the number of disabled tests. +int UnitTest::disabled_test_count() const { + return impl()->disabled_test_count(); +} + +// Gets the number of all tests. +int UnitTest::total_test_count() const { return impl()->total_test_count(); } + +// Gets the number of tests that should run. +int UnitTest::test_to_run_count() const { return impl()->test_to_run_count(); } + +// Gets the elapsed time, in milliseconds. +internal::TimeInMillis UnitTest::elapsed_time() const { + return impl()->elapsed_time(); +} + +// Returns true iff the unit test passed (i.e. all test cases passed). +bool UnitTest::Passed() const { return impl()->Passed(); } + +// Returns true iff the unit test failed (i.e. some test case failed +// or something outside of all tests failed). +bool UnitTest::Failed() const { return impl()->Failed(); } + +// Gets the i-th test case among all the test cases. i can range from 0 to +// total_test_case_count() - 1. If i is not in that range, returns NULL. +const TestCase* UnitTest::GetTestCase(int i) const { + return impl()->GetTestCase(i); +} + +// Gets the i-th test case among all the test cases. i can range from 0 to +// total_test_case_count() - 1. If i is not in that range, returns NULL. +TestCase* UnitTest::GetMutableTestCase(int i) { + return impl()->GetMutableTestCase(i); +} + +// Returns the list of event listeners that can be used to track events +// inside Google Test. +TestEventListeners& UnitTest::listeners() { + return *impl()->listeners(); +} + +// Registers and returns a global test environment. When a test +// program is run, all global test environments will be set-up in the +// order they were registered. After all tests in the program have +// finished, all global test environments will be torn-down in the +// *reverse* order they were registered. +// +// The UnitTest object takes ownership of the given environment. +// +// We don't protect this under mutex_, as we only support calling it +// from the main thread. +Environment* UnitTest::AddEnvironment(Environment* env) { + if (env == NULL) { + return NULL; + } + + impl_->environments().push_back(env); + return env; +} + +#if GTEST_HAS_EXCEPTIONS +// A failed Google Test assertion will throw an exception of this type +// when exceptions are enabled. We derive it from std::runtime_error, +// which is for errors presumably detectable only at run time. Since +// std::runtime_error inherits from std::exception, many testing +// frameworks know how to extract and print the message inside it. +class GoogleTestFailureException : public ::std::runtime_error { + public: + explicit GoogleTestFailureException(const TestPartResult& failure) + : ::std::runtime_error(PrintTestPartResultToString(failure).c_str()) {} +}; +#endif + +// Adds a TestPartResult to the current TestResult object. All Google Test +// assertion macros (e.g. ASSERT_TRUE, EXPECT_EQ, etc) eventually call +// this to report their results. The user code should use the +// assertion macros instead of calling this directly. +// L < mutex_ +void UnitTest::AddTestPartResult(TestPartResult::Type result_type, + const char* file_name, + int line_number, + const internal::String& message, + const internal::String& os_stack_trace) { + Message msg; + msg << message; + + internal::MutexLock lock(&mutex_); + if (impl_->gtest_trace_stack().size() > 0) { + msg << "\n" << GTEST_NAME_ << " trace:"; + + for (int i = static_cast<int>(impl_->gtest_trace_stack().size()); + i > 0; --i) { + const internal::TraceInfo& trace = impl_->gtest_trace_stack()[i - 1]; + msg << "\n" << internal::FormatFileLocation(trace.file, trace.line) + << " " << trace.message; + } + } + + if (os_stack_trace.c_str() != NULL && !os_stack_trace.empty()) { + msg << internal::kStackTraceMarker << os_stack_trace; + } + + const TestPartResult result = + TestPartResult(result_type, file_name, line_number, + msg.GetString().c_str()); + impl_->GetTestPartResultReporterForCurrentThread()-> + ReportTestPartResult(result); + + if (result_type != TestPartResult::kSuccess) { + // gtest_break_on_failure takes precedence over + // gtest_throw_on_failure. This allows a user to set the latter + // in the code (perhaps in order to use Google Test assertions + // with another testing framework) and specify the former on the + // command line for debugging. + if (GTEST_FLAG(break_on_failure)) { +#if GTEST_OS_WINDOWS + // Using DebugBreak on Windows allows gtest to still break into a debugger + // when a failure happens and both the --gtest_break_on_failure and + // the --gtest_catch_exceptions flags are specified. + DebugBreak(); +#else + *static_cast<int*>(NULL) = 1; +#endif // GTEST_OS_WINDOWS + } else if (GTEST_FLAG(throw_on_failure)) { +#if GTEST_HAS_EXCEPTIONS + throw GoogleTestFailureException(result); +#else + // We cannot call abort() as it generates a pop-up in debug mode + // that cannot be suppressed in VC 7.1 or below. + exit(1); +#endif + } + } +} + +// Creates and adds a property to the current TestResult. If a property matching +// the supplied value already exists, updates its value instead. +void UnitTest::RecordPropertyForCurrentTest(const char* key, + const char* value) { + const TestProperty test_property(key, value); + impl_->current_test_result()->RecordProperty(test_property); +} + +// Runs all tests in this UnitTest object and prints the result. +// Returns 0 if successful, or 1 otherwise. +// +// We don't protect this under mutex_, as we only support calling it +// from the main thread. +int UnitTest::Run() { +#if GTEST_HAS_SEH + // Catch SEH-style exceptions. + + const bool in_death_test_child_process = + internal::GTEST_FLAG(internal_run_death_test).length() > 0; + + // Either the user wants Google Test to catch exceptions thrown by the + // tests or this is executing in the context of death test child + // process. In either case the user does not want to see pop-up dialogs + // about crashes - they are expected.. + if (GTEST_FLAG(catch_exceptions) || in_death_test_child_process) { +#if !GTEST_OS_WINDOWS_MOBILE + // SetErrorMode doesn't exist on CE. + SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOALIGNMENTFAULTEXCEPT | + SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX); +#endif // !GTEST_OS_WINDOWS_MOBILE + +#if (defined(_MSC_VER) || GTEST_OS_WINDOWS_MINGW) && !GTEST_OS_WINDOWS_MOBILE + // Death test children can be terminated with _abort(). On Windows, + // _abort() can show a dialog with a warning message. This forces the + // abort message to go to stderr instead. + _set_error_mode(_OUT_TO_STDERR); +#endif + +#if _MSC_VER >= 1400 && !GTEST_OS_WINDOWS_MOBILE + // In the debug version, Visual Studio pops up a separate dialog + // offering a choice to debug the aborted program. We need to suppress + // this dialog or it will pop up for every EXPECT/ASSERT_DEATH statement + // executed. Google Test will notify the user of any unexpected + // failure via stderr. + // + // VC++ doesn't define _set_abort_behavior() prior to the version 8.0. + // Users of prior VC versions shall suffer the agony and pain of + // clicking through the countless debug dialogs. + // TODO(vladl@google.com): find a way to suppress the abort dialog() in the + // debug mode when compiled with VC 7.1 or lower. + if (!GTEST_FLAG(break_on_failure)) + _set_abort_behavior( + 0x0, // Clear the following flags: + _WRITE_ABORT_MSG | _CALL_REPORTFAULT); // pop-up window, core dump. +#endif + } + + __try { + return impl_->RunAllTests(); + } __except(internal::UnitTestOptions::GTestShouldProcessSEH( + GetExceptionCode())) { + printf("Exception thrown with code 0x%x.\nFAIL\n", GetExceptionCode()); + fflush(stdout); + return 1; + } + +#else // We are on a compiler or platform that doesn't support SEH. + + return impl_->RunAllTests(); +#endif // GTEST_HAS_SEH +} + +// Returns the working directory when the first TEST() or TEST_F() was +// executed. +const char* UnitTest::original_working_dir() const { + return impl_->original_working_dir_.c_str(); +} + +// Returns the TestCase object for the test that's currently running, +// or NULL if no test is running. +// L < mutex_ +const TestCase* UnitTest::current_test_case() const { + internal::MutexLock lock(&mutex_); + return impl_->current_test_case(); +} + +// Returns the TestInfo object for the test that's currently running, +// or NULL if no test is running. +// L < mutex_ +const TestInfo* UnitTest::current_test_info() const { + internal::MutexLock lock(&mutex_); + return impl_->current_test_info(); +} + +// Returns the random seed used at the start of the current test run. +int UnitTest::random_seed() const { return impl_->random_seed(); } + +#if GTEST_HAS_PARAM_TEST +// Returns ParameterizedTestCaseRegistry object used to keep track of +// value-parameterized tests and instantiate and register them. +// L < mutex_ +internal::ParameterizedTestCaseRegistry& + UnitTest::parameterized_test_registry() { + return impl_->parameterized_test_registry(); +} +#endif // GTEST_HAS_PARAM_TEST + +// Creates an empty UnitTest. +UnitTest::UnitTest() { + impl_ = new internal::UnitTestImpl(this); +} + +// Destructor of UnitTest. +UnitTest::~UnitTest() { + delete impl_; +} + +// Pushes a trace defined by SCOPED_TRACE() on to the per-thread +// Google Test trace stack. +// L < mutex_ +void UnitTest::PushGTestTrace(const internal::TraceInfo& trace) { + internal::MutexLock lock(&mutex_); + impl_->gtest_trace_stack().push_back(trace); +} + +// Pops a trace from the per-thread Google Test trace stack. +// L < mutex_ +void UnitTest::PopGTestTrace() { + internal::MutexLock lock(&mutex_); + impl_->gtest_trace_stack().pop_back(); +} + +namespace internal { + +UnitTestImpl::UnitTestImpl(UnitTest* parent) + : parent_(parent), +#ifdef _MSC_VER +#pragma warning(push) // Saves the current warning state. +#pragma warning(disable:4355) // Temporarily disables warning 4355 + // (using this in initializer). + default_global_test_part_result_reporter_(this), + default_per_thread_test_part_result_reporter_(this), +#pragma warning(pop) // Restores the warning state again. +#else + default_global_test_part_result_reporter_(this), + default_per_thread_test_part_result_reporter_(this), +#endif // _MSC_VER + global_test_part_result_repoter_( + &default_global_test_part_result_reporter_), + per_thread_test_part_result_reporter_( + &default_per_thread_test_part_result_reporter_), +#if GTEST_HAS_PARAM_TEST + parameterized_test_registry_(), + parameterized_tests_registered_(false), +#endif // GTEST_HAS_PARAM_TEST + last_death_test_case_(-1), + current_test_case_(NULL), + current_test_info_(NULL), + ad_hoc_test_result_(), + os_stack_trace_getter_(NULL), + post_flag_parse_init_performed_(false), + random_seed_(0), // Will be overridden by the flag before first use. + random_(0), // Will be reseeded before first use. +#if GTEST_HAS_DEATH_TEST + elapsed_time_(0), + internal_run_death_test_flag_(NULL), + death_test_factory_(new DefaultDeathTestFactory) { +#else + elapsed_time_(0) { +#endif // GTEST_HAS_DEATH_TEST + listeners()->SetDefaultResultPrinter(new PrettyUnitTestResultPrinter); +} + +UnitTestImpl::~UnitTestImpl() { + // Deletes every TestCase. + ForEach(test_cases_, internal::Delete<TestCase>); + + // Deletes every Environment. + ForEach(environments_, internal::Delete<Environment>); + + delete os_stack_trace_getter_; +} + +#if GTEST_HAS_DEATH_TEST +// Disables event forwarding if the control is currently in a death test +// subprocess. Must not be called before InitGoogleTest. +void UnitTestImpl::SuppressTestEventsIfInSubprocess() { + if (internal_run_death_test_flag_.get() != NULL) + listeners()->SuppressEventForwarding(); +} +#endif // GTEST_HAS_DEATH_TEST + +// Initializes event listeners performing XML output as specified by +// UnitTestOptions. Must not be called before InitGoogleTest. +void UnitTestImpl::ConfigureXmlOutput() { + const String& output_format = UnitTestOptions::GetOutputFormat(); + if (output_format == "xml") { + listeners()->SetDefaultXmlGenerator(new XmlUnitTestResultPrinter( + UnitTestOptions::GetAbsolutePathToOutputFile().c_str())); + } else if (output_format != "") { + printf("WARNING: unrecognized output format \"%s\" ignored.\n", + output_format.c_str()); + fflush(stdout); + } +} + +// Performs initialization dependent upon flag values obtained in +// ParseGoogleTestFlagsOnly. Is called from InitGoogleTest after the call to +// ParseGoogleTestFlagsOnly. In case a user neglects to call InitGoogleTest +// this function is also called from RunAllTests. Since this function can be +// called more than once, it has to be idempotent. +void UnitTestImpl::PostFlagParsingInit() { + // Ensures that this function does not execute more than once. + if (!post_flag_parse_init_performed_) { + post_flag_parse_init_performed_ = true; + +#if GTEST_HAS_DEATH_TEST + InitDeathTestSubprocessControlInfo(); + SuppressTestEventsIfInSubprocess(); +#endif // GTEST_HAS_DEATH_TEST + + // Registers parameterized tests. This makes parameterized tests + // available to the UnitTest reflection API without running + // RUN_ALL_TESTS. + RegisterParameterizedTests(); + + // Configures listeners for XML output. This makes it possible for users + // to shut down the default XML output before invoking RUN_ALL_TESTS. + ConfigureXmlOutput(); + } +} + +// A predicate that checks the name of a TestCase against a known +// value. +// +// This is used for implementation of the UnitTest class only. We put +// it in the anonymous namespace to prevent polluting the outer +// namespace. +// +// TestCaseNameIs is copyable. +class TestCaseNameIs { + public: + // Constructor. + explicit TestCaseNameIs(const String& name) + : name_(name) {} + + // Returns true iff the name of test_case matches name_. + bool operator()(const TestCase* test_case) const { + return test_case != NULL && strcmp(test_case->name(), name_.c_str()) == 0; + } + + private: + String name_; +}; + +// Finds and returns a TestCase with the given name. If one doesn't +// exist, creates one and returns it. It's the CALLER'S +// RESPONSIBILITY to ensure that this function is only called WHEN THE +// TESTS ARE NOT SHUFFLED. +// +// Arguments: +// +// test_case_name: name of the test case +// set_up_tc: pointer to the function that sets up the test case +// tear_down_tc: pointer to the function that tears down the test case +TestCase* UnitTestImpl::GetTestCase(const char* test_case_name, + const char* comment, + Test::SetUpTestCaseFunc set_up_tc, + Test::TearDownTestCaseFunc tear_down_tc) { + // Can we find a TestCase with the given name? + const std::vector<TestCase*>::const_iterator test_case = + std::find_if(test_cases_.begin(), test_cases_.end(), + TestCaseNameIs(test_case_name)); + + if (test_case != test_cases_.end()) + return *test_case; + + // No. Let's create one. + TestCase* const new_test_case = + new TestCase(test_case_name, comment, set_up_tc, tear_down_tc); + + // Is this a death test case? + if (internal::UnitTestOptions::MatchesFilter(String(test_case_name), + kDeathTestCaseFilter)) { + // Yes. Inserts the test case after the last death test case + // defined so far. This only works when the test cases haven't + // been shuffled. Otherwise we may end up running a death test + // after a non-death test. + ++last_death_test_case_; + test_cases_.insert(test_cases_.begin() + last_death_test_case_, + new_test_case); + } else { + // No. Appends to the end of the list. + test_cases_.push_back(new_test_case); + } + + test_case_indices_.push_back(static_cast<int>(test_case_indices_.size())); + return new_test_case; +} + +// Helpers for setting up / tearing down the given environment. They +// are for use in the ForEach() function. +static void SetUpEnvironment(Environment* env) { env->SetUp(); } +static void TearDownEnvironment(Environment* env) { env->TearDown(); } + +// Runs all tests in this UnitTest object, prints the result, and +// returns 0 if all tests are successful, or 1 otherwise. If any +// exception is thrown during a test on Windows, this test is +// considered to be failed, but the rest of the tests will still be +// run. (We disable exceptions on Linux and Mac OS X, so the issue +// doesn't apply there.) +// When parameterized tests are enabled, it expands and registers +// parameterized tests first in RegisterParameterizedTests(). +// All other functions called from RunAllTests() may safely assume that +// parameterized tests are ready to be counted and run. +int UnitTestImpl::RunAllTests() { + // Makes sure InitGoogleTest() was called. + if (!GTestIsInitialized()) { + printf("%s", + "\nThis test program did NOT call ::testing::InitGoogleTest " + "before calling RUN_ALL_TESTS(). Please fix it.\n"); + return 1; + } + + // Do not run any test if the --help flag was specified. + if (g_help_flag) + return 0; + + // Repeats the call to the post-flag parsing initialization in case the + // user didn't call InitGoogleTest. + PostFlagParsingInit(); + + // Even if sharding is not on, test runners may want to use the + // GTEST_SHARD_STATUS_FILE to query whether the test supports the sharding + // protocol. + internal::WriteToShardStatusFileIfNeeded(); + + // True iff we are in a subprocess for running a thread-safe-style + // death test. + bool in_subprocess_for_death_test = false; + +#if GTEST_HAS_DEATH_TEST + in_subprocess_for_death_test = (internal_run_death_test_flag_.get() != NULL); +#endif // GTEST_HAS_DEATH_TEST + + const bool should_shard = ShouldShard(kTestTotalShards, kTestShardIndex, + in_subprocess_for_death_test); + + // Compares the full test names with the filter to decide which + // tests to run. + const bool has_tests_to_run = FilterTests(should_shard + ? HONOR_SHARDING_PROTOCOL + : IGNORE_SHARDING_PROTOCOL) > 0; + + // Lists the tests and exits if the --gtest_list_tests flag was specified. + if (GTEST_FLAG(list_tests)) { + // This must be called *after* FilterTests() has been called. + ListTestsMatchingFilter(); + return 0; + } + + random_seed_ = GTEST_FLAG(shuffle) ? + GetRandomSeedFromFlag(GTEST_FLAG(random_seed)) : 0; + + // True iff at least one test has failed. + bool failed = false; + + TestEventListener* repeater = listeners()->repeater(); + + repeater->OnTestProgramStart(*parent_); + + // How many times to repeat the tests? We don't want to repeat them + // when we are inside the subprocess of a death test. + const int repeat = in_subprocess_for_death_test ? 1 : GTEST_FLAG(repeat); + // Repeats forever if the repeat count is negative. + const bool forever = repeat < 0; + for (int i = 0; forever || i != repeat; i++) { + ClearResult(); + + const TimeInMillis start = GetTimeInMillis(); + + // Shuffles test cases and tests if requested. + if (has_tests_to_run && GTEST_FLAG(shuffle)) { + random()->Reseed(random_seed_); + // This should be done before calling OnTestIterationStart(), + // such that a test event listener can see the actual test order + // in the event. + ShuffleTests(); + } + + // Tells the unit test event listeners that the tests are about to start. + repeater->OnTestIterationStart(*parent_, i); + + // Runs each test case if there is at least one test to run. + if (has_tests_to_run) { + // Sets up all environments beforehand. + repeater->OnEnvironmentsSetUpStart(*parent_); + ForEach(environments_, SetUpEnvironment); + repeater->OnEnvironmentsSetUpEnd(*parent_); + + // Runs the tests only if there was no fatal failure during global + // set-up. + if (!Test::HasFatalFailure()) { + for (int test_index = 0; test_index < total_test_case_count(); + test_index++) { + GetMutableTestCase(test_index)->Run(); + } + } + + // Tears down all environments in reverse order afterwards. + repeater->OnEnvironmentsTearDownStart(*parent_); + std::for_each(environments_.rbegin(), environments_.rend(), + TearDownEnvironment); + repeater->OnEnvironmentsTearDownEnd(*parent_); + } + + elapsed_time_ = GetTimeInMillis() - start; + + // Tells the unit test event listener that the tests have just finished. + repeater->OnTestIterationEnd(*parent_, i); + + // Gets the result and clears it. + if (!Passed()) { + failed = true; + } + + // Restores the original test order after the iteration. This + // allows the user to quickly repro a failure that happens in the + // N-th iteration without repeating the first (N - 1) iterations. + // This is not enclosed in "if (GTEST_FLAG(shuffle)) { ... }", in + // case the user somehow changes the value of the flag somewhere + // (it's always safe to unshuffle the tests). + UnshuffleTests(); + + if (GTEST_FLAG(shuffle)) { + // Picks a new random seed for each iteration. + random_seed_ = GetNextRandomSeed(random_seed_); + } + } + + repeater->OnTestProgramEnd(*parent_); + + // Returns 0 if all tests passed, or 1 other wise. + return failed ? 1 : 0; +} + +// Reads the GTEST_SHARD_STATUS_FILE environment variable, and creates the file +// if the variable is present. If a file already exists at this location, this +// function will write over it. If the variable is present, but the file cannot +// be created, prints an error and exits. +void WriteToShardStatusFileIfNeeded() { + const char* const test_shard_file = posix::GetEnv(kTestShardStatusFile); + if (test_shard_file != NULL) { + FILE* const file = posix::FOpen(test_shard_file, "w"); + if (file == NULL) { + ColoredPrintf(COLOR_RED, + "Could not write to the test shard status file \"%s\" " + "specified by the %s environment variable.\n", + test_shard_file, kTestShardStatusFile); + fflush(stdout); + exit(EXIT_FAILURE); + } + fclose(file); + } +} + +// Checks whether sharding is enabled by examining the relevant +// environment variable values. If the variables are present, +// but inconsistent (i.e., shard_index >= total_shards), prints +// an error and exits. If in_subprocess_for_death_test, sharding is +// disabled because it must only be applied to the original test +// process. Otherwise, we could filter out death tests we intended to execute. +bool ShouldShard(const char* total_shards_env, + const char* shard_index_env, + bool in_subprocess_for_death_test) { + if (in_subprocess_for_death_test) { + return false; + } + + const Int32 total_shards = Int32FromEnvOrDie(total_shards_env, -1); + const Int32 shard_index = Int32FromEnvOrDie(shard_index_env, -1); + + if (total_shards == -1 && shard_index == -1) { + return false; + } else if (total_shards == -1 && shard_index != -1) { + const Message msg = Message() + << "Invalid environment variables: you have " + << kTestShardIndex << " = " << shard_index + << ", but have left " << kTestTotalShards << " unset.\n"; + ColoredPrintf(COLOR_RED, msg.GetString().c_str()); + fflush(stdout); + exit(EXIT_FAILURE); + } else if (total_shards != -1 && shard_index == -1) { + const Message msg = Message() + << "Invalid environment variables: you have " + << kTestTotalShards << " = " << total_shards + << ", but have left " << kTestShardIndex << " unset.\n"; + ColoredPrintf(COLOR_RED, msg.GetString().c_str()); + fflush(stdout); + exit(EXIT_FAILURE); + } else if (shard_index < 0 || shard_index >= total_shards) { + const Message msg = Message() + << "Invalid environment variables: we require 0 <= " + << kTestShardIndex << " < " << kTestTotalShards + << ", but you have " << kTestShardIndex << "=" << shard_index + << ", " << kTestTotalShards << "=" << total_shards << ".\n"; + ColoredPrintf(COLOR_RED, msg.GetString().c_str()); + fflush(stdout); + exit(EXIT_FAILURE); + } + + return total_shards > 1; +} + +// Parses the environment variable var as an Int32. If it is unset, +// returns default_val. If it is not an Int32, prints an error +// and aborts. +Int32 Int32FromEnvOrDie(const char* const var, Int32 default_val) { + const char* str_val = posix::GetEnv(var); + if (str_val == NULL) { + return default_val; + } + + Int32 result; + if (!ParseInt32(Message() << "The value of environment variable " << var, + str_val, &result)) { + exit(EXIT_FAILURE); + } + return result; +} + +// Given the total number of shards, the shard index, and the test id, +// returns true iff the test should be run on this shard. The test id is +// some arbitrary but unique non-negative integer assigned to each test +// method. Assumes that 0 <= shard_index < total_shards. +bool ShouldRunTestOnShard(int total_shards, int shard_index, int test_id) { + return (test_id % total_shards) == shard_index; +} + +// Compares the name of each test with the user-specified filter to +// decide whether the test should be run, then records the result in +// each TestCase and TestInfo object. +// If shard_tests == true, further filters tests based on sharding +// variables in the environment - see +// http://code.google.com/p/googletest/wiki/GoogleTestAdvancedGuide. +// Returns the number of tests that should run. +int UnitTestImpl::FilterTests(ReactionToSharding shard_tests) { + const Int32 total_shards = shard_tests == HONOR_SHARDING_PROTOCOL ? + Int32FromEnvOrDie(kTestTotalShards, -1) : -1; + const Int32 shard_index = shard_tests == HONOR_SHARDING_PROTOCOL ? + Int32FromEnvOrDie(kTestShardIndex, -1) : -1; + + // num_runnable_tests are the number of tests that will + // run across all shards (i.e., match filter and are not disabled). + // num_selected_tests are the number of tests to be run on + // this shard. + int num_runnable_tests = 0; + int num_selected_tests = 0; + for (size_t i = 0; i < test_cases_.size(); i++) { + TestCase* const test_case = test_cases_[i]; + const String &test_case_name = test_case->name(); + test_case->set_should_run(false); + + for (size_t j = 0; j < test_case->test_info_list().size(); j++) { + TestInfo* const test_info = test_case->test_info_list()[j]; + const String test_name(test_info->name()); + // A test is disabled if test case name or test name matches + // kDisableTestFilter. + const bool is_disabled = + internal::UnitTestOptions::MatchesFilter(test_case_name, + kDisableTestFilter) || + internal::UnitTestOptions::MatchesFilter(test_name, + kDisableTestFilter); + test_info->impl()->set_is_disabled(is_disabled); + + const bool matches_filter = + internal::UnitTestOptions::FilterMatchesTest(test_case_name, + test_name); + test_info->impl()->set_matches_filter(matches_filter); + + const bool is_runnable = + (GTEST_FLAG(also_run_disabled_tests) || !is_disabled) && + matches_filter; + + const bool is_selected = is_runnable && + (shard_tests == IGNORE_SHARDING_PROTOCOL || + ShouldRunTestOnShard(total_shards, shard_index, + num_runnable_tests)); + + num_runnable_tests += is_runnable; + num_selected_tests += is_selected; + + test_info->impl()->set_should_run(is_selected); + test_case->set_should_run(test_case->should_run() || is_selected); + } + } + return num_selected_tests; +} + +// Prints the names of the tests matching the user-specified filter flag. +void UnitTestImpl::ListTestsMatchingFilter() { + for (size_t i = 0; i < test_cases_.size(); i++) { + const TestCase* const test_case = test_cases_[i]; + bool printed_test_case_name = false; + + for (size_t j = 0; j < test_case->test_info_list().size(); j++) { + const TestInfo* const test_info = + test_case->test_info_list()[j]; + if (test_info->matches_filter()) { + if (!printed_test_case_name) { + printed_test_case_name = true; + printf("%s.\n", test_case->name()); + } + printf(" %s\n", test_info->name()); + } + } + } + fflush(stdout); +} + +// Sets the OS stack trace getter. +// +// Does nothing if the input and the current OS stack trace getter are +// the same; otherwise, deletes the old getter and makes the input the +// current getter. +void UnitTestImpl::set_os_stack_trace_getter( + OsStackTraceGetterInterface* getter) { + if (os_stack_trace_getter_ != getter) { + delete os_stack_trace_getter_; + os_stack_trace_getter_ = getter; + } +} + +// Returns the current OS stack trace getter if it is not NULL; +// otherwise, creates an OsStackTraceGetter, makes it the current +// getter, and returns it. +OsStackTraceGetterInterface* UnitTestImpl::os_stack_trace_getter() { + if (os_stack_trace_getter_ == NULL) { + os_stack_trace_getter_ = new OsStackTraceGetter; + } + + return os_stack_trace_getter_; +} + +// Returns the TestResult for the test that's currently running, or +// the TestResult for the ad hoc test if no test is running. +TestResult* UnitTestImpl::current_test_result() { + return current_test_info_ ? + current_test_info_->impl()->result() : &ad_hoc_test_result_; +} + +// Shuffles all test cases, and the tests within each test case, +// making sure that death tests are still run first. +void UnitTestImpl::ShuffleTests() { + // Shuffles the death test cases. + ShuffleRange(random(), 0, last_death_test_case_ + 1, &test_case_indices_); + + // Shuffles the non-death test cases. + ShuffleRange(random(), last_death_test_case_ + 1, + static_cast<int>(test_cases_.size()), &test_case_indices_); + + // Shuffles the tests inside each test case. + for (size_t i = 0; i < test_cases_.size(); i++) { + test_cases_[i]->ShuffleTests(random()); + } +} + +// Restores the test cases and tests to their order before the first shuffle. +void UnitTestImpl::UnshuffleTests() { + for (size_t i = 0; i < test_cases_.size(); i++) { + // Unshuffles the tests in each test case. + test_cases_[i]->UnshuffleTests(); + // Resets the index of each test case. + test_case_indices_[i] = static_cast<int>(i); + } +} + +// TestInfoImpl constructor. The new instance assumes ownership of the test +// factory object. +TestInfoImpl::TestInfoImpl(TestInfo* parent, + const char* a_test_case_name, + const char* a_name, + const char* a_test_case_comment, + const char* a_comment, + TypeId a_fixture_class_id, + internal::TestFactoryBase* factory) : + parent_(parent), + test_case_name_(String(a_test_case_name)), + name_(String(a_name)), + test_case_comment_(String(a_test_case_comment)), + comment_(String(a_comment)), + fixture_class_id_(a_fixture_class_id), + should_run_(false), + is_disabled_(false), + matches_filter_(false), + factory_(factory) { +} + +// TestInfoImpl destructor. +TestInfoImpl::~TestInfoImpl() { + delete factory_; +} + +// Returns the current OS stack trace as a String. +// +// The maximum number of stack frames to be included is specified by +// the gtest_stack_trace_depth flag. The skip_count parameter +// specifies the number of top frames to be skipped, which doesn't +// count against the number of frames to be included. +// +// For example, if Foo() calls Bar(), which in turn calls +// GetCurrentOsStackTraceExceptTop(..., 1), Foo() will be included in +// the trace but Bar() and GetCurrentOsStackTraceExceptTop() won't. +String GetCurrentOsStackTraceExceptTop(UnitTest* /*unit_test*/, + int skip_count) { + // We pass skip_count + 1 to skip this wrapper function in addition + // to what the user really wants to skip. + return GetUnitTestImpl()->CurrentOsStackTraceExceptTop(skip_count + 1); +} + +// Used by the GTEST_HIDE_UNREACHABLE_CODE_ macro to suppress unreachable +// code warnings. +namespace { +class ClassUniqueToAlwaysTrue {}; +} + +bool IsTrue(bool condition) { return condition; } + +bool AlwaysTrue() { +#if GTEST_HAS_EXCEPTIONS + // This condition is always false so AlwaysTrue() never actually throws, + // but it makes the compiler think that it may throw. + if (IsTrue(false)) + throw ClassUniqueToAlwaysTrue(); +#endif // GTEST_HAS_EXCEPTIONS + return true; +} + +// If *pstr starts with the given prefix, modifies *pstr to be right +// past the prefix and returns true; otherwise leaves *pstr unchanged +// and returns false. None of pstr, *pstr, and prefix can be NULL. +bool SkipPrefix(const char* prefix, const char** pstr) { + const size_t prefix_len = strlen(prefix); + if (strncmp(*pstr, prefix, prefix_len) == 0) { + *pstr += prefix_len; + return true; + } + return false; +} + +// Parses a string as a command line flag. The string should have +// the format "--flag=value". When def_optional is true, the "=value" +// part can be omitted. +// +// Returns the value of the flag, or NULL if the parsing failed. +const char* ParseFlagValue(const char* str, + const char* flag, + bool def_optional) { + // str and flag must not be NULL. + if (str == NULL || flag == NULL) return NULL; + + // The flag must start with "--" followed by GTEST_FLAG_PREFIX_. + const String flag_str = String::Format("--%s%s", GTEST_FLAG_PREFIX_, flag); + const size_t flag_len = flag_str.length(); + if (strncmp(str, flag_str.c_str(), flag_len) != 0) return NULL; + + // Skips the flag name. + const char* flag_end = str + flag_len; + + // When def_optional is true, it's OK to not have a "=value" part. + if (def_optional && (flag_end[0] == '\0')) { + return flag_end; + } + + // If def_optional is true and there are more characters after the + // flag name, or if def_optional is false, there must be a '=' after + // the flag name. + if (flag_end[0] != '=') return NULL; + + // Returns the string after "=". + return flag_end + 1; +} + +// Parses a string for a bool flag, in the form of either +// "--flag=value" or "--flag". +// +// In the former case, the value is taken as true as long as it does +// not start with '0', 'f', or 'F'. +// +// In the latter case, the value is taken as true. +// +// On success, stores the value of the flag in *value, and returns +// true. On failure, returns false without changing *value. +bool ParseBoolFlag(const char* str, const char* flag, bool* value) { + // Gets the value of the flag as a string. + const char* const value_str = ParseFlagValue(str, flag, true); + + // Aborts if the parsing failed. + if (value_str == NULL) return false; + + // Converts the string value to a bool. + *value = !(*value_str == '0' || *value_str == 'f' || *value_str == 'F'); + return true; +} + +// Parses a string for an Int32 flag, in the form of +// "--flag=value". +// +// On success, stores the value of the flag in *value, and returns +// true. On failure, returns false without changing *value. +bool ParseInt32Flag(const char* str, const char* flag, Int32* value) { + // Gets the value of the flag as a string. + const char* const value_str = ParseFlagValue(str, flag, false); + + // Aborts if the parsing failed. + if (value_str == NULL) return false; + + // Sets *value to the value of the flag. + return ParseInt32(Message() << "The value of flag --" << flag, + value_str, value); +} + +// Parses a string for a string flag, in the form of +// "--flag=value". +// +// On success, stores the value of the flag in *value, and returns +// true. On failure, returns false without changing *value. +bool ParseStringFlag(const char* str, const char* flag, String* value) { + // Gets the value of the flag as a string. + const char* const value_str = ParseFlagValue(str, flag, false); + + // Aborts if the parsing failed. + if (value_str == NULL) return false; + + // Sets *value to the value of the flag. + *value = value_str; + return true; +} + +// Determines whether a string has a prefix that Google Test uses for its +// flags, i.e., starts with GTEST_FLAG_PREFIX_ or GTEST_FLAG_PREFIX_DASH_. +// If Google Test detects that a command line flag has its prefix but is not +// recognized, it will print its help message. Flags starting with +// GTEST_INTERNAL_PREFIX_ followed by "internal_" are considered Google Test +// internal flags and do not trigger the help message. +static bool HasGoogleTestFlagPrefix(const char* str) { + return (SkipPrefix("--", &str) || + SkipPrefix("-", &str) || + SkipPrefix("/", &str)) && + !SkipPrefix(GTEST_FLAG_PREFIX_ "internal_", &str) && + (SkipPrefix(GTEST_FLAG_PREFIX_, &str) || + SkipPrefix(GTEST_FLAG_PREFIX_DASH_, &str)); +} + +// Prints a string containing code-encoded text. The following escape +// sequences can be used in the string to control the text color: +// +// @@ prints a single '@' character. +// @R changes the color to red. +// @G changes the color to green. +// @Y changes the color to yellow. +// @D changes to the default terminal text color. +// +// TODO(wan@google.com): Write tests for this once we add stdout +// capturing to Google Test. +static void PrintColorEncoded(const char* str) { + GTestColor color = COLOR_DEFAULT; // The current color. + + // Conceptually, we split the string into segments divided by escape + // sequences. Then we print one segment at a time. At the end of + // each iteration, the str pointer advances to the beginning of the + // next segment. + for (;;) { + const char* p = strchr(str, '@'); + if (p == NULL) { + ColoredPrintf(color, "%s", str); + return; + } + + ColoredPrintf(color, "%s", String(str, p - str).c_str()); + + const char ch = p[1]; + str = p + 2; + if (ch == '@') { + ColoredPrintf(color, "@"); + } else if (ch == 'D') { + color = COLOR_DEFAULT; + } else if (ch == 'R') { + color = COLOR_RED; + } else if (ch == 'G') { + color = COLOR_GREEN; + } else if (ch == 'Y') { + color = COLOR_YELLOW; + } else { + --str; + } + } +} + +static const char kColorEncodedHelpMessage[] = +"This program contains tests written using " GTEST_NAME_ ". You can use the\n" +"following command line flags to control its behavior:\n" +"\n" +"Test Selection:\n" +" @G--" GTEST_FLAG_PREFIX_ "list_tests@D\n" +" List the names of all tests instead of running them. The name of\n" +" TEST(Foo, Bar) is \"Foo.Bar\".\n" +" @G--" GTEST_FLAG_PREFIX_ "filter=@YPOSTIVE_PATTERNS" + "[@G-@YNEGATIVE_PATTERNS]@D\n" +" Run only the tests whose name matches one of the positive patterns but\n" +" none of the negative patterns. '?' matches any single character; '*'\n" +" matches any substring; ':' separates two patterns.\n" +" @G--" GTEST_FLAG_PREFIX_ "also_run_disabled_tests@D\n" +" Run all disabled tests too.\n" +"\n" +"Test Execution:\n" +" @G--" GTEST_FLAG_PREFIX_ "repeat=@Y[COUNT]@D\n" +" Run the tests repeatedly; use a negative count to repeat forever.\n" +" @G--" GTEST_FLAG_PREFIX_ "shuffle@D\n" +" Randomize tests' orders on every iteration.\n" +" @G--" GTEST_FLAG_PREFIX_ "random_seed=@Y[NUMBER]@D\n" +" Random number seed to use for shuffling test orders (between 1 and\n" +" 99999, or 0 to use a seed based on the current time).\n" +"\n" +"Test Output:\n" +" @G--" GTEST_FLAG_PREFIX_ "color=@Y(@Gyes@Y|@Gno@Y|@Gauto@Y)@D\n" +" Enable/disable colored output. The default is @Gauto@D.\n" +" -@G-" GTEST_FLAG_PREFIX_ "print_time=0@D\n" +" Don't print the elapsed time of each test.\n" +" @G--" GTEST_FLAG_PREFIX_ "output=xml@Y[@G:@YDIRECTORY_PATH@G" + GTEST_PATH_SEP_ "@Y|@G:@YFILE_PATH]@D\n" +" Generate an XML report in the given directory or with the given file\n" +" name. @YFILE_PATH@D defaults to @Gtest_details.xml@D.\n" +"\n" +"Assertion Behavior:\n" +#if GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS +" @G--" GTEST_FLAG_PREFIX_ "death_test_style=@Y(@Gfast@Y|@Gthreadsafe@Y)@D\n" +" Set the default death test style.\n" +#endif // GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS +" @G--" GTEST_FLAG_PREFIX_ "break_on_failure@D\n" +" Turn assertion failures into debugger break-points.\n" +" @G--" GTEST_FLAG_PREFIX_ "throw_on_failure@D\n" +" Turn assertion failures into C++ exceptions.\n" +#if GTEST_OS_WINDOWS +" @G--" GTEST_FLAG_PREFIX_ "catch_exceptions@D\n" +" Suppress pop-ups caused by exceptions.\n" +#endif // GTEST_OS_WINDOWS +"\n" +"Except for @G--" GTEST_FLAG_PREFIX_ "list_tests@D, you can alternatively set " + "the corresponding\n" +"environment variable of a flag (all letters in upper-case). For example, to\n" +"disable colored text output, you can either specify @G--" GTEST_FLAG_PREFIX_ + "color=no@D or set\n" +"the @G" GTEST_FLAG_PREFIX_UPPER_ "COLOR@D environment variable to @Gno@D.\n" +"\n" +"For more information, please read the " GTEST_NAME_ " documentation at\n" +"@G" GTEST_PROJECT_URL_ "@D. If you find a bug in " GTEST_NAME_ "\n" +"(not one in your own code or tests), please report it to\n" +"@G<" GTEST_DEV_EMAIL_ ">@D.\n"; + +// Parses the command line for Google Test flags, without initializing +// other parts of Google Test. The type parameter CharType can be +// instantiated to either char or wchar_t. +template <typename CharType> +void ParseGoogleTestFlagsOnlyImpl(int* argc, CharType** argv) { + for (int i = 1; i < *argc; i++) { + const String arg_string = StreamableToString(argv[i]); + const char* const arg = arg_string.c_str(); + + using internal::ParseBoolFlag; + using internal::ParseInt32Flag; + using internal::ParseStringFlag; + + // Do we see a Google Test flag? + if (ParseBoolFlag(arg, kAlsoRunDisabledTestsFlag, + >EST_FLAG(also_run_disabled_tests)) || + ParseBoolFlag(arg, kBreakOnFailureFlag, + >EST_FLAG(break_on_failure)) || + ParseBoolFlag(arg, kCatchExceptionsFlag, + >EST_FLAG(catch_exceptions)) || + ParseStringFlag(arg, kColorFlag, >EST_FLAG(color)) || + ParseStringFlag(arg, kDeathTestStyleFlag, + >EST_FLAG(death_test_style)) || + ParseBoolFlag(arg, kDeathTestUseFork, + >EST_FLAG(death_test_use_fork)) || + ParseStringFlag(arg, kFilterFlag, >EST_FLAG(filter)) || + ParseStringFlag(arg, kInternalRunDeathTestFlag, + >EST_FLAG(internal_run_death_test)) || + ParseBoolFlag(arg, kListTestsFlag, >EST_FLAG(list_tests)) || + ParseStringFlag(arg, kOutputFlag, >EST_FLAG(output)) || + ParseBoolFlag(arg, kPrintTimeFlag, >EST_FLAG(print_time)) || + ParseInt32Flag(arg, kRandomSeedFlag, >EST_FLAG(random_seed)) || + ParseInt32Flag(arg, kRepeatFlag, >EST_FLAG(repeat)) || + ParseBoolFlag(arg, kShuffleFlag, >EST_FLAG(shuffle)) || + ParseInt32Flag(arg, kStackTraceDepthFlag, + >EST_FLAG(stack_trace_depth)) || + ParseBoolFlag(arg, kThrowOnFailureFlag, >EST_FLAG(throw_on_failure)) + ) { + // Yes. Shift the remainder of the argv list left by one. Note + // that argv has (*argc + 1) elements, the last one always being + // NULL. The following loop moves the trailing NULL element as + // well. + for (int j = i; j != *argc; j++) { + argv[j] = argv[j + 1]; + } + + // Decrements the argument count. + (*argc)--; + + // We also need to decrement the iterator as we just removed + // an element. + i--; + } else if (arg_string == "--help" || arg_string == "-h" || + arg_string == "-?" || arg_string == "/?" || + HasGoogleTestFlagPrefix(arg)) { + // Both help flag and unrecognized Google Test flags (excluding + // internal ones) trigger help display. + g_help_flag = true; + } + } + + if (g_help_flag) { + // We print the help here instead of in RUN_ALL_TESTS(), as the + // latter may not be called at all if the user is using Google + // Test with another testing framework. + PrintColorEncoded(kColorEncodedHelpMessage); + } +} + +// Parses the command line for Google Test flags, without initializing +// other parts of Google Test. +void ParseGoogleTestFlagsOnly(int* argc, char** argv) { + ParseGoogleTestFlagsOnlyImpl(argc, argv); +} +void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv) { + ParseGoogleTestFlagsOnlyImpl(argc, argv); +} + +// The internal implementation of InitGoogleTest(). +// +// The type parameter CharType can be instantiated to either char or +// wchar_t. +template <typename CharType> +void InitGoogleTestImpl(int* argc, CharType** argv) { + g_init_gtest_count++; + + // We don't want to run the initialization code twice. + if (g_init_gtest_count != 1) return; + + if (*argc <= 0) return; + + internal::g_executable_path = internal::StreamableToString(argv[0]); + +#if GTEST_HAS_DEATH_TEST + g_argvs.clear(); + for (int i = 0; i != *argc; i++) { + g_argvs.push_back(StreamableToString(argv[i])); + } +#endif // GTEST_HAS_DEATH_TEST + + ParseGoogleTestFlagsOnly(argc, argv); + GetUnitTestImpl()->PostFlagParsingInit(); +} + +} // namespace internal + +// Initializes Google Test. This must be called before calling +// RUN_ALL_TESTS(). In particular, it parses a command line for the +// flags that Google Test recognizes. Whenever a Google Test flag is +// seen, it is removed from argv, and *argc is decremented. +// +// No value is returned. Instead, the Google Test flag variables are +// updated. +// +// Calling the function for the second time has no user-visible effect. +void InitGoogleTest(int* argc, char** argv) { + internal::InitGoogleTestImpl(argc, argv); +} + +// This overloaded version can be used in Windows programs compiled in +// UNICODE mode. +void InitGoogleTest(int* argc, wchar_t** argv) { + internal::InitGoogleTestImpl(argc, argv); +} + +} // namespace testing +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: wan@google.com (Zhanyong Wan), vladl@google.com (Vlad Losev) +// +// This file implements death tests. + + +#if GTEST_HAS_DEATH_TEST + +#if GTEST_OS_MAC +#include <crt_externs.h> +#endif // GTEST_OS_MAC + +#include <errno.h> +#include <fcntl.h> +#include <limits.h> +#include <stdarg.h> + +#if GTEST_OS_WINDOWS +#include <windows.h> +#else +#include <sys/mman.h> +#include <sys/wait.h> +#endif // GTEST_OS_WINDOWS + +#endif // GTEST_HAS_DEATH_TEST + + +// Indicates that this translation unit is part of Google Test's +// implementation. It must come before gtest-internal-inl.h is +// included, or there will be a compiler error. This trick is to +// prevent a user from accidentally including gtest-internal-inl.h in +// his code. +#define GTEST_IMPLEMENTATION_ 1 +#undef GTEST_IMPLEMENTATION_ + +namespace testing { + +// Constants. + +// The default death test style. +static const char kDefaultDeathTestStyle[] = "fast"; + +GTEST_DEFINE_string_( + death_test_style, + internal::StringFromGTestEnv("death_test_style", kDefaultDeathTestStyle), + "Indicates how to run a death test in a forked child process: " + "\"threadsafe\" (child process re-executes the test binary " + "from the beginning, running only the specific death test) or " + "\"fast\" (child process runs the death test immediately " + "after forking)."); + +GTEST_DEFINE_bool_( + death_test_use_fork, + internal::BoolFromGTestEnv("death_test_use_fork", false), + "Instructs to use fork()/_exit() instead of clone() in death tests. " + "Ignored and always uses fork() on POSIX systems where clone() is not " + "implemented. Useful when running under valgrind or similar tools if " + "those do not support clone(). Valgrind 3.3.1 will just fail if " + "it sees an unsupported combination of clone() flags. " + "It is not recommended to use this flag w/o valgrind though it will " + "work in 99% of the cases. Once valgrind is fixed, this flag will " + "most likely be removed."); + +namespace internal { +GTEST_DEFINE_string_( + internal_run_death_test, "", + "Indicates the file, line number, temporal index of " + "the single death test to run, and a file descriptor to " + "which a success code may be sent, all separated by " + "colons. This flag is specified if and only if the current " + "process is a sub-process launched for running a thread-safe " + "death test. FOR INTERNAL USE ONLY."); +} // namespace internal + +#if GTEST_HAS_DEATH_TEST + +// ExitedWithCode constructor. +ExitedWithCode::ExitedWithCode(int exit_code) : exit_code_(exit_code) { +} + +// ExitedWithCode function-call operator. +bool ExitedWithCode::operator()(int exit_status) const { +#if GTEST_OS_WINDOWS + return exit_status == exit_code_; +#else + return WIFEXITED(exit_status) && WEXITSTATUS(exit_status) == exit_code_; +#endif // GTEST_OS_WINDOWS +} + +#if !GTEST_OS_WINDOWS +// KilledBySignal constructor. +KilledBySignal::KilledBySignal(int signum) : signum_(signum) { +} + +// KilledBySignal function-call operator. +bool KilledBySignal::operator()(int exit_status) const { + return WIFSIGNALED(exit_status) && WTERMSIG(exit_status) == signum_; +} +#endif // !GTEST_OS_WINDOWS + +namespace internal { + +// Utilities needed for death tests. + +// Generates a textual description of a given exit code, in the format +// specified by wait(2). +static String ExitSummary(int exit_code) { + Message m; +#if GTEST_OS_WINDOWS + m << "Exited with exit status " << exit_code; +#else + if (WIFEXITED(exit_code)) { + m << "Exited with exit status " << WEXITSTATUS(exit_code); + } else if (WIFSIGNALED(exit_code)) { + m << "Terminated by signal " << WTERMSIG(exit_code); + } +#ifdef WCOREDUMP + if (WCOREDUMP(exit_code)) { + m << " (core dumped)"; + } +#endif +#endif // GTEST_OS_WINDOWS + return m.GetString(); +} + +// Returns true if exit_status describes a process that was terminated +// by a signal, or exited normally with a nonzero exit code. +bool ExitedUnsuccessfully(int exit_status) { + return !ExitedWithCode(0)(exit_status); +} + +#if !GTEST_OS_WINDOWS +// Generates a textual failure message when a death test finds more than +// one thread running, or cannot determine the number of threads, prior +// to executing the given statement. It is the responsibility of the +// caller not to pass a thread_count of 1. +static String DeathTestThreadWarning(size_t thread_count) { + Message msg; + msg << "Death tests use fork(), which is unsafe particularly" + << " in a threaded context. For this test, " << GTEST_NAME_ << " "; + if (thread_count == 0) + msg << "couldn't detect the number of threads."; + else + msg << "detected " << thread_count << " threads."; + return msg.GetString(); +} +#endif // !GTEST_OS_WINDOWS + +// Flag characters for reporting a death test that did not die. +static const char kDeathTestLived = 'L'; +static const char kDeathTestReturned = 'R'; +static const char kDeathTestInternalError = 'I'; + +// An enumeration describing all of the possible ways that a death test +// can conclude. DIED means that the process died while executing the +// test code; LIVED means that process lived beyond the end of the test +// code; and RETURNED means that the test statement attempted a "return," +// which is not allowed. IN_PROGRESS means the test has not yet +// concluded. +enum DeathTestOutcome { IN_PROGRESS, DIED, LIVED, RETURNED }; + +// Routine for aborting the program which is safe to call from an +// exec-style death test child process, in which case the error +// message is propagated back to the parent process. Otherwise, the +// message is simply printed to stderr. In either case, the program +// then exits with status 1. +void DeathTestAbort(const String& message) { + // On a POSIX system, this function may be called from a threadsafe-style + // death test child process, which operates on a very small stack. Use + // the heap for any additional non-minuscule memory requirements. + const InternalRunDeathTestFlag* const flag = + GetUnitTestImpl()->internal_run_death_test_flag(); + if (flag != NULL) { + FILE* parent = posix::FDOpen(flag->write_fd(), "w"); + fputc(kDeathTestInternalError, parent); + fprintf(parent, "%s", message.c_str()); + fflush(parent); + _exit(1); + } else { + fprintf(stderr, "%s", message.c_str()); + fflush(stderr); + abort(); + } +} + +// A replacement for CHECK that calls DeathTestAbort if the assertion +// fails. +#define GTEST_DEATH_TEST_CHECK_(expression) \ + do { \ + if (!::testing::internal::IsTrue(expression)) { \ + DeathTestAbort(::testing::internal::String::Format( \ + "CHECK failed: File %s, line %d: %s", \ + __FILE__, __LINE__, #expression)); \ + } \ + } while (::testing::internal::AlwaysFalse()) + +// This macro is similar to GTEST_DEATH_TEST_CHECK_, but it is meant for +// evaluating any system call that fulfills two conditions: it must return +// -1 on failure, and set errno to EINTR when it is interrupted and +// should be tried again. The macro expands to a loop that repeatedly +// evaluates the expression as long as it evaluates to -1 and sets +// errno to EINTR. If the expression evaluates to -1 but errno is +// something other than EINTR, DeathTestAbort is called. +#define GTEST_DEATH_TEST_CHECK_SYSCALL_(expression) \ + do { \ + int gtest_retval; \ + do { \ + gtest_retval = (expression); \ + } while (gtest_retval == -1 && errno == EINTR); \ + if (gtest_retval == -1) { \ + DeathTestAbort(::testing::internal::String::Format( \ + "CHECK failed: File %s, line %d: %s != -1", \ + __FILE__, __LINE__, #expression)); \ + } \ + } while (::testing::internal::AlwaysFalse()) + +// Returns the message describing the last system error in errno. +String GetLastErrnoDescription() { + return String(errno == 0 ? "" : posix::StrError(errno)); +} + +// This is called from a death test parent process to read a failure +// message from the death test child process and log it with the FATAL +// severity. On Windows, the message is read from a pipe handle. On other +// platforms, it is read from a file descriptor. +static void FailFromInternalError(int fd) { + Message error; + char buffer[256]; + int num_read; + + do { + while ((num_read = posix::Read(fd, buffer, 255)) > 0) { + buffer[num_read] = '\0'; + error << buffer; + } + } while (num_read == -1 && errno == EINTR); + + if (num_read == 0) { + GTEST_LOG_(FATAL) << error.GetString(); + } else { + const int last_error = errno; + GTEST_LOG_(FATAL) << "Error while reading death test internal: " + << GetLastErrnoDescription() << " [" << last_error << "]"; + } +} + +// Death test constructor. Increments the running death test count +// for the current test. +DeathTest::DeathTest() { + TestInfo* const info = GetUnitTestImpl()->current_test_info(); + if (info == NULL) { + DeathTestAbort("Cannot run a death test outside of a TEST or " + "TEST_F construct"); + } +} + +// Creates and returns a death test by dispatching to the current +// death test factory. +bool DeathTest::Create(const char* statement, const RE* regex, + const char* file, int line, DeathTest** test) { + return GetUnitTestImpl()->death_test_factory()->Create( + statement, regex, file, line, test); +} + +const char* DeathTest::LastMessage() { + return last_death_test_message_.c_str(); +} + +void DeathTest::set_last_death_test_message(const String& message) { + last_death_test_message_ = message; +} + +String DeathTest::last_death_test_message_; + +// Provides cross platform implementation for some death functionality. +class DeathTestImpl : public DeathTest { + protected: + DeathTestImpl(const char* a_statement, const RE* a_regex) + : statement_(a_statement), + regex_(a_regex), + spawned_(false), + status_(-1), + outcome_(IN_PROGRESS), + read_fd_(-1), + write_fd_(-1) {} + + // read_fd_ is expected to be closed and cleared by a derived class. + ~DeathTestImpl() { GTEST_DEATH_TEST_CHECK_(read_fd_ == -1); } + + void Abort(AbortReason reason); + virtual bool Passed(bool status_ok); + + const char* statement() const { return statement_; } + const RE* regex() const { return regex_; } + bool spawned() const { return spawned_; } + void set_spawned(bool is_spawned) { spawned_ = is_spawned; } + int status() const { return status_; } + void set_status(int a_status) { status_ = a_status; } + DeathTestOutcome outcome() const { return outcome_; } + void set_outcome(DeathTestOutcome an_outcome) { outcome_ = an_outcome; } + int read_fd() const { return read_fd_; } + void set_read_fd(int fd) { read_fd_ = fd; } + int write_fd() const { return write_fd_; } + void set_write_fd(int fd) { write_fd_ = fd; } + + // Called in the parent process only. Reads the result code of the death + // test child process via a pipe, interprets it to set the outcome_ + // member, and closes read_fd_. Outputs diagnostics and terminates in + // case of unexpected codes. + void ReadAndInterpretStatusByte(); + + private: + // The textual content of the code this object is testing. This class + // doesn't own this string and should not attempt to delete it. + const char* const statement_; + // The regular expression which test output must match. DeathTestImpl + // doesn't own this object and should not attempt to delete it. + const RE* const regex_; + // True if the death test child process has been successfully spawned. + bool spawned_; + // The exit status of the child process. + int status_; + // How the death test concluded. + DeathTestOutcome outcome_; + // Descriptor to the read end of the pipe to the child process. It is + // always -1 in the child process. The child keeps its write end of the + // pipe in write_fd_. + int read_fd_; + // Descriptor to the child's write end of the pipe to the parent process. + // It is always -1 in the parent process. The parent keeps its end of the + // pipe in read_fd_. + int write_fd_; +}; + +// Called in the parent process only. Reads the result code of the death +// test child process via a pipe, interprets it to set the outcome_ +// member, and closes read_fd_. Outputs diagnostics and terminates in +// case of unexpected codes. +void DeathTestImpl::ReadAndInterpretStatusByte() { + char flag; + int bytes_read; + + // The read() here blocks until data is available (signifying the + // failure of the death test) or until the pipe is closed (signifying + // its success), so it's okay to call this in the parent before + // the child process has exited. + do { + bytes_read = posix::Read(read_fd(), &flag, 1); + } while (bytes_read == -1 && errno == EINTR); + + if (bytes_read == 0) { + set_outcome(DIED); + } else if (bytes_read == 1) { + switch (flag) { + case kDeathTestReturned: + set_outcome(RETURNED); + break; + case kDeathTestLived: + set_outcome(LIVED); + break; + case kDeathTestInternalError: + FailFromInternalError(read_fd()); // Does not return. + break; + default: + GTEST_LOG_(FATAL) << "Death test child process reported " + << "unexpected status byte (" + << static_cast<unsigned int>(flag) << ")"; + } + } else { + GTEST_LOG_(FATAL) << "Read from death test child process failed: " + << GetLastErrnoDescription(); + } + GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Close(read_fd())); + set_read_fd(-1); +} + +// Signals that the death test code which should have exited, didn't. +// Should be called only in a death test child process. +// Writes a status byte to the child's status file descriptor, then +// calls _exit(1). +void DeathTestImpl::Abort(AbortReason reason) { + // The parent process considers the death test to be a failure if + // it finds any data in our pipe. So, here we write a single flag byte + // to the pipe, then exit. + const char status_ch = + reason == TEST_DID_NOT_DIE ? kDeathTestLived : kDeathTestReturned; + GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Write(write_fd(), &status_ch, 1)); + GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Close(write_fd())); + _exit(1); // Exits w/o any normal exit hooks (we were supposed to crash) +} + +// Assesses the success or failure of a death test, using both private +// members which have previously been set, and one argument: +// +// Private data members: +// outcome: An enumeration describing how the death test +// concluded: DIED, LIVED, or RETURNED. The death test fails +// in the latter two cases. +// status: The exit status of the child process. On *nix, it is in the +// in the format specified by wait(2). On Windows, this is the +// value supplied to the ExitProcess() API or a numeric code +// of the exception that terminated the program. +// regex: A regular expression object to be applied to +// the test's captured standard error output; the death test +// fails if it does not match. +// +// Argument: +// status_ok: true if exit_status is acceptable in the context of +// this particular death test, which fails if it is false +// +// Returns true iff all of the above conditions are met. Otherwise, the +// first failing condition, in the order given above, is the one that is +// reported. Also sets the last death test message string. +bool DeathTestImpl::Passed(bool status_ok) { + if (!spawned()) + return false; + + const String error_message = GetCapturedStderr(); + + bool success = false; + Message buffer; + + buffer << "Death test: " << statement() << "\n"; + switch (outcome()) { + case LIVED: + buffer << " Result: failed to die.\n" + << " Error msg: " << error_message; + break; + case RETURNED: + buffer << " Result: illegal return in test statement.\n" + << " Error msg: " << error_message; + break; + case DIED: + if (status_ok) { + const bool matched = RE::PartialMatch(error_message.c_str(), *regex()); + if (matched) { + success = true; + } else { + buffer << " Result: died but not with expected error.\n" + << " Expected: " << regex()->pattern() << "\n" + << "Actual msg: " << error_message; + } + } else { + buffer << " Result: died but not with expected exit code:\n" + << " " << ExitSummary(status()) << "\n"; + } + break; + case IN_PROGRESS: + default: + GTEST_LOG_(FATAL) + << "DeathTest::Passed somehow called before conclusion of test"; + } + + DeathTest::set_last_death_test_message(buffer.GetString()); + return success; +} + +#if GTEST_OS_WINDOWS +// WindowsDeathTest implements death tests on Windows. Due to the +// specifics of starting new processes on Windows, death tests there are +// always threadsafe, and Google Test considers the +// --gtest_death_test_style=fast setting to be equivalent to +// --gtest_death_test_style=threadsafe there. +// +// A few implementation notes: Like the Linux version, the Windows +// implementation uses pipes for child-to-parent communication. But due to +// the specifics of pipes on Windows, some extra steps are required: +// +// 1. The parent creates a communication pipe and stores handles to both +// ends of it. +// 2. The parent starts the child and provides it with the information +// necessary to acquire the handle to the write end of the pipe. +// 3. The child acquires the write end of the pipe and signals the parent +// using a Windows event. +// 4. Now the parent can release the write end of the pipe on its side. If +// this is done before step 3, the object's reference count goes down to +// 0 and it is destroyed, preventing the child from acquiring it. The +// parent now has to release it, or read operations on the read end of +// the pipe will not return when the child terminates. +// 5. The parent reads child's output through the pipe (outcome code and +// any possible error messages) from the pipe, and its stderr and then +// determines whether to fail the test. +// +// Note: to distinguish Win32 API calls from the local method and function +// calls, the former are explicitly resolved in the global namespace. +// +class WindowsDeathTest : public DeathTestImpl { + public: + WindowsDeathTest(const char* statement, + const RE* regex, + const char* file, + int line) + : DeathTestImpl(statement, regex), file_(file), line_(line) {} + + // All of these virtual functions are inherited from DeathTest. + virtual int Wait(); + virtual TestRole AssumeRole(); + + private: + // The name of the file in which the death test is located. + const char* const file_; + // The line number on which the death test is located. + const int line_; + // Handle to the write end of the pipe to the child process. + AutoHandle write_handle_; + // Child process handle. + AutoHandle child_handle_; + // Event the child process uses to signal the parent that it has + // acquired the handle to the write end of the pipe. After seeing this + // event the parent can release its own handles to make sure its + // ReadFile() calls return when the child terminates. + AutoHandle event_handle_; +}; + +// Waits for the child in a death test to exit, returning its exit +// status, or 0 if no child process exists. As a side effect, sets the +// outcome data member. +int WindowsDeathTest::Wait() { + if (!spawned()) + return 0; + + // Wait until the child either signals that it has acquired the write end + // of the pipe or it dies. + const HANDLE wait_handles[2] = { child_handle_.Get(), event_handle_.Get() }; + switch (::WaitForMultipleObjects(2, + wait_handles, + FALSE, // Waits for any of the handles. + INFINITE)) { + case WAIT_OBJECT_0: + case WAIT_OBJECT_0 + 1: + break; + default: + GTEST_DEATH_TEST_CHECK_(false); // Should not get here. + } + + // The child has acquired the write end of the pipe or exited. + // We release the handle on our side and continue. + write_handle_.Reset(); + event_handle_.Reset(); + + ReadAndInterpretStatusByte(); + + // Waits for the child process to exit if it haven't already. This + // returns immediately if the child has already exited, regardless of + // whether previous calls to WaitForMultipleObjects synchronized on this + // handle or not. + GTEST_DEATH_TEST_CHECK_( + WAIT_OBJECT_0 == ::WaitForSingleObject(child_handle_.Get(), + INFINITE)); + DWORD status; + GTEST_DEATH_TEST_CHECK_(::GetExitCodeProcess(child_handle_.Get(), &status) + != FALSE); + child_handle_.Reset(); + set_status(static_cast<int>(status)); + return this->status(); +} + +// The AssumeRole process for a Windows death test. It creates a child +// process with the same executable as the current process to run the +// death test. The child process is given the --gtest_filter and +// --gtest_internal_run_death_test flags such that it knows to run the +// current death test only. +DeathTest::TestRole WindowsDeathTest::AssumeRole() { + const UnitTestImpl* const impl = GetUnitTestImpl(); + const InternalRunDeathTestFlag* const flag = + impl->internal_run_death_test_flag(); + const TestInfo* const info = impl->current_test_info(); + const int death_test_index = info->result()->death_test_count(); + + if (flag != NULL) { + // ParseInternalRunDeathTestFlag() has performed all the necessary + // processing. + set_write_fd(flag->write_fd()); + return EXECUTE_TEST; + } + + // WindowsDeathTest uses an anonymous pipe to communicate results of + // a death test. + SECURITY_ATTRIBUTES handles_are_inheritable = { + sizeof(SECURITY_ATTRIBUTES), NULL, TRUE }; + HANDLE read_handle, write_handle; + GTEST_DEATH_TEST_CHECK_( + ::CreatePipe(&read_handle, &write_handle, &handles_are_inheritable, + 0) // Default buffer size. + != FALSE); + set_read_fd(::_open_osfhandle(reinterpret_cast<intptr_t>(read_handle), + O_RDONLY)); + write_handle_.Reset(write_handle); + event_handle_.Reset(::CreateEvent( + &handles_are_inheritable, + TRUE, // The event will automatically reset to non-signaled state. + FALSE, // The initial state is non-signalled. + NULL)); // The even is unnamed. + GTEST_DEATH_TEST_CHECK_(event_handle_.Get() != NULL); + const String filter_flag = String::Format("--%s%s=%s.%s", + GTEST_FLAG_PREFIX_, kFilterFlag, + info->test_case_name(), + info->name()); + const String internal_flag = String::Format( + "--%s%s=%s|%d|%d|%u|%Iu|%Iu", + GTEST_FLAG_PREFIX_, + kInternalRunDeathTestFlag, + file_, line_, + death_test_index, + static_cast<unsigned int>(::GetCurrentProcessId()), + // size_t has the same with as pointers on both 32-bit and 64-bit + // Windows platforms. + // See http://msdn.microsoft.com/en-us/library/tcxf1dw6.aspx. + reinterpret_cast<size_t>(write_handle), + reinterpret_cast<size_t>(event_handle_.Get())); + + char executable_path[_MAX_PATH + 1]; // NOLINT + GTEST_DEATH_TEST_CHECK_( + _MAX_PATH + 1 != ::GetModuleFileNameA(NULL, + executable_path, + _MAX_PATH)); + + String command_line = String::Format("%s %s \"%s\"", + ::GetCommandLineA(), + filter_flag.c_str(), + internal_flag.c_str()); + + DeathTest::set_last_death_test_message(""); + + CaptureStderr(); + // Flush the log buffers since the log streams are shared with the child. + FlushInfoLog(); + + // The child process will share the standard handles with the parent. + STARTUPINFOA startup_info; + memset(&startup_info, 0, sizeof(STARTUPINFO)); + startup_info.dwFlags = STARTF_USESTDHANDLES; + startup_info.hStdInput = ::GetStdHandle(STD_INPUT_HANDLE); + startup_info.hStdOutput = ::GetStdHandle(STD_OUTPUT_HANDLE); + startup_info.hStdError = ::GetStdHandle(STD_ERROR_HANDLE); + + PROCESS_INFORMATION process_info; + GTEST_DEATH_TEST_CHECK_(::CreateProcessA( + executable_path, + const_cast<char*>(command_line.c_str()), + NULL, // Retuned process handle is not inheritable. + NULL, // Retuned thread handle is not inheritable. + TRUE, // Child inherits all inheritable handles (for write_handle_). + 0x0, // Default creation flags. + NULL, // Inherit the parent's environment. + UnitTest::GetInstance()->original_working_dir(), + &startup_info, + &process_info) != FALSE); + child_handle_.Reset(process_info.hProcess); + ::CloseHandle(process_info.hThread); + set_spawned(true); + return OVERSEE_TEST; +} +#else // We are not on Windows. + +// ForkingDeathTest provides implementations for most of the abstract +// methods of the DeathTest interface. Only the AssumeRole method is +// left undefined. +class ForkingDeathTest : public DeathTestImpl { + public: + ForkingDeathTest(const char* statement, const RE* regex); + + // All of these virtual functions are inherited from DeathTest. + virtual int Wait(); + + protected: + void set_child_pid(pid_t child_pid) { child_pid_ = child_pid; } + + private: + // PID of child process during death test; 0 in the child process itself. + pid_t child_pid_; +}; + +// Constructs a ForkingDeathTest. +ForkingDeathTest::ForkingDeathTest(const char* a_statement, const RE* a_regex) + : DeathTestImpl(a_statement, a_regex), + child_pid_(-1) {} + +// Waits for the child in a death test to exit, returning its exit +// status, or 0 if no child process exists. As a side effect, sets the +// outcome data member. +int ForkingDeathTest::Wait() { + if (!spawned()) + return 0; + + ReadAndInterpretStatusByte(); + + int status_value; + GTEST_DEATH_TEST_CHECK_SYSCALL_(waitpid(child_pid_, &status_value, 0)); + set_status(status_value); + return status_value; +} + +// A concrete death test class that forks, then immediately runs the test +// in the child process. +class NoExecDeathTest : public ForkingDeathTest { + public: + NoExecDeathTest(const char* a_statement, const RE* a_regex) : + ForkingDeathTest(a_statement, a_regex) { } + virtual TestRole AssumeRole(); +}; + +// The AssumeRole process for a fork-and-run death test. It implements a +// straightforward fork, with a simple pipe to transmit the status byte. +DeathTest::TestRole NoExecDeathTest::AssumeRole() { + const size_t thread_count = GetThreadCount(); + if (thread_count != 1) { + GTEST_LOG_(WARNING) << DeathTestThreadWarning(thread_count); + } + + int pipe_fd[2]; + GTEST_DEATH_TEST_CHECK_(pipe(pipe_fd) != -1); + + DeathTest::set_last_death_test_message(""); + CaptureStderr(); + // When we fork the process below, the log file buffers are copied, but the + // file descriptors are shared. We flush all log files here so that closing + // the file descriptors in the child process doesn't throw off the + // synchronization between descriptors and buffers in the parent process. + // This is as close to the fork as possible to avoid a race condition in case + // there are multiple threads running before the death test, and another + // thread writes to the log file. + FlushInfoLog(); + + const pid_t child_pid = fork(); + GTEST_DEATH_TEST_CHECK_(child_pid != -1); + set_child_pid(child_pid); + if (child_pid == 0) { + GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[0])); + set_write_fd(pipe_fd[1]); + // Redirects all logging to stderr in the child process to prevent + // concurrent writes to the log files. We capture stderr in the parent + // process and append the child process' output to a log. + LogToStderr(); + // Event forwarding to the listeners of event listener API mush be shut + // down in death test subprocesses. + GetUnitTestImpl()->listeners()->SuppressEventForwarding(); + return EXECUTE_TEST; + } else { + GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1])); + set_read_fd(pipe_fd[0]); + set_spawned(true); + return OVERSEE_TEST; + } +} + +// A concrete death test class that forks and re-executes the main +// program from the beginning, with command-line flags set that cause +// only this specific death test to be run. +class ExecDeathTest : public ForkingDeathTest { + public: + ExecDeathTest(const char* a_statement, const RE* a_regex, + const char* file, int line) : + ForkingDeathTest(a_statement, a_regex), file_(file), line_(line) { } + virtual TestRole AssumeRole(); + private: + // The name of the file in which the death test is located. + const char* const file_; + // The line number on which the death test is located. + const int line_; +}; + +// Utility class for accumulating command-line arguments. +class Arguments { + public: + Arguments() { + args_.push_back(NULL); + } + + ~Arguments() { + for (std::vector<char*>::iterator i = args_.begin(); i != args_.end(); + ++i) { + free(*i); + } + } + void AddArgument(const char* argument) { + args_.insert(args_.end() - 1, posix::StrDup(argument)); + } + + template <typename Str> + void AddArguments(const ::std::vector<Str>& arguments) { + for (typename ::std::vector<Str>::const_iterator i = arguments.begin(); + i != arguments.end(); + ++i) { + args_.insert(args_.end() - 1, posix::StrDup(i->c_str())); + } + } + char* const* Argv() { + return &args_[0]; + } + private: + std::vector<char*> args_; +}; + +// A struct that encompasses the arguments to the child process of a +// threadsafe-style death test process. +struct ExecDeathTestArgs { + char* const* argv; // Command-line arguments for the child's call to exec + int close_fd; // File descriptor to close; the read end of a pipe +}; + +#if GTEST_OS_MAC +inline char** GetEnviron() { + // When Google Test is built as a framework on MacOS X, the environ variable + // is unavailable. Apple's documentation (man environ) recommends using + // _NSGetEnviron() instead. + return *_NSGetEnviron(); +} +#else +// Some POSIX platforms expect you to declare environ. extern "C" makes +// it reside in the global namespace. +extern "C" char** environ; +inline char** GetEnviron() { return environ; } +#endif // GTEST_OS_MAC + +// The main function for a threadsafe-style death test child process. +// This function is called in a clone()-ed process and thus must avoid +// any potentially unsafe operations like malloc or libc functions. +static int ExecDeathTestChildMain(void* child_arg) { + ExecDeathTestArgs* const args = static_cast<ExecDeathTestArgs*>(child_arg); + GTEST_DEATH_TEST_CHECK_SYSCALL_(close(args->close_fd)); + + // We need to execute the test program in the same environment where + // it was originally invoked. Therefore we change to the original + // working directory first. + const char* const original_dir = + UnitTest::GetInstance()->original_working_dir(); + // We can safely call chdir() as it's a direct system call. + if (chdir(original_dir) != 0) { + DeathTestAbort(String::Format("chdir(\"%s\") failed: %s", + original_dir, + GetLastErrnoDescription().c_str())); + return EXIT_FAILURE; + } + + // We can safely call execve() as it's a direct system call. We + // cannot use execvp() as it's a libc function and thus potentially + // unsafe. Since execve() doesn't search the PATH, the user must + // invoke the test program via a valid path that contains at least + // one path separator. + execve(args->argv[0], args->argv, GetEnviron()); + DeathTestAbort(String::Format("execve(%s, ...) in %s failed: %s", + args->argv[0], + original_dir, + GetLastErrnoDescription().c_str())); + return EXIT_FAILURE; +} + +// Two utility routines that together determine the direction the stack +// grows. +// This could be accomplished more elegantly by a single recursive +// function, but we want to guard against the unlikely possibility of +// a smart compiler optimizing the recursion away. +bool StackLowerThanAddress(const void* ptr) { + int dummy; + return &dummy < ptr; +} + +bool StackGrowsDown() { + int dummy; + return StackLowerThanAddress(&dummy); +} + +// A threadsafe implementation of fork(2) for threadsafe-style death tests +// that uses clone(2). It dies with an error message if anything goes +// wrong. +static pid_t ExecDeathTestFork(char* const* argv, int close_fd) { + ExecDeathTestArgs args = { argv, close_fd }; + pid_t child_pid = -1; + +#if GTEST_HAS_CLONE + const bool use_fork = GTEST_FLAG(death_test_use_fork); + + if (!use_fork) { + static const bool stack_grows_down = StackGrowsDown(); + const size_t stack_size = getpagesize(); + // MMAP_ANONYMOUS is not defined on Mac, so we use MAP_ANON instead. + void* const stack = mmap(NULL, stack_size, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_PRIVATE, -1, 0); + GTEST_DEATH_TEST_CHECK_(stack != MAP_FAILED); + void* const stack_top = + static_cast<char*>(stack) + (stack_grows_down ? stack_size : 0); + + child_pid = clone(&ExecDeathTestChildMain, stack_top, SIGCHLD, &args); + + GTEST_DEATH_TEST_CHECK_(munmap(stack, stack_size) != -1); + } +#else + const bool use_fork = true; +#endif // GTEST_HAS_CLONE + + if (use_fork && (child_pid = fork()) == 0) { + ExecDeathTestChildMain(&args); + _exit(0); + } + + GTEST_DEATH_TEST_CHECK_(child_pid != -1); + return child_pid; +} + +// The AssumeRole process for a fork-and-exec death test. It re-executes the +// main program from the beginning, setting the --gtest_filter +// and --gtest_internal_run_death_test flags to cause only the current +// death test to be re-run. +DeathTest::TestRole ExecDeathTest::AssumeRole() { + const UnitTestImpl* const impl = GetUnitTestImpl(); + const InternalRunDeathTestFlag* const flag = + impl->internal_run_death_test_flag(); + const TestInfo* const info = impl->current_test_info(); + const int death_test_index = info->result()->death_test_count(); + + if (flag != NULL) { + set_write_fd(flag->write_fd()); + return EXECUTE_TEST; + } + + int pipe_fd[2]; + GTEST_DEATH_TEST_CHECK_(pipe(pipe_fd) != -1); + // Clear the close-on-exec flag on the write end of the pipe, lest + // it be closed when the child process does an exec: + GTEST_DEATH_TEST_CHECK_(fcntl(pipe_fd[1], F_SETFD, 0) != -1); + + const String filter_flag = + String::Format("--%s%s=%s.%s", + GTEST_FLAG_PREFIX_, kFilterFlag, + info->test_case_name(), info->name()); + const String internal_flag = + String::Format("--%s%s=%s|%d|%d|%d", + GTEST_FLAG_PREFIX_, kInternalRunDeathTestFlag, + file_, line_, death_test_index, pipe_fd[1]); + Arguments args; + args.AddArguments(GetArgvs()); + args.AddArgument(filter_flag.c_str()); + args.AddArgument(internal_flag.c_str()); + + DeathTest::set_last_death_test_message(""); + + CaptureStderr(); + // See the comment in NoExecDeathTest::AssumeRole for why the next line + // is necessary. + FlushInfoLog(); + + const pid_t child_pid = ExecDeathTestFork(args.Argv(), pipe_fd[0]); + GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1])); + set_child_pid(child_pid); + set_read_fd(pipe_fd[0]); + set_spawned(true); + return OVERSEE_TEST; +} + +#endif // !GTEST_OS_WINDOWS + +// Creates a concrete DeathTest-derived class that depends on the +// --gtest_death_test_style flag, and sets the pointer pointed to +// by the "test" argument to its address. If the test should be +// skipped, sets that pointer to NULL. Returns true, unless the +// flag is set to an invalid value. +bool DefaultDeathTestFactory::Create(const char* statement, const RE* regex, + const char* file, int line, + DeathTest** test) { + UnitTestImpl* const impl = GetUnitTestImpl(); + const InternalRunDeathTestFlag* const flag = + impl->internal_run_death_test_flag(); + const int death_test_index = impl->current_test_info() + ->increment_death_test_count(); + + if (flag != NULL) { + if (death_test_index > flag->index()) { + DeathTest::set_last_death_test_message(String::Format( + "Death test count (%d) somehow exceeded expected maximum (%d)", + death_test_index, flag->index())); + return false; + } + + if (!(flag->file() == file && flag->line() == line && + flag->index() == death_test_index)) { + *test = NULL; + return true; + } + } + +#if GTEST_OS_WINDOWS + if (GTEST_FLAG(death_test_style) == "threadsafe" || + GTEST_FLAG(death_test_style) == "fast") { + *test = new WindowsDeathTest(statement, regex, file, line); + } +#else + if (GTEST_FLAG(death_test_style) == "threadsafe") { + *test = new ExecDeathTest(statement, regex, file, line); + } else if (GTEST_FLAG(death_test_style) == "fast") { + *test = new NoExecDeathTest(statement, regex); + } +#endif // GTEST_OS_WINDOWS + else { // NOLINT - this is more readable than unbalanced brackets inside #if. + DeathTest::set_last_death_test_message(String::Format( + "Unknown death test style \"%s\" encountered", + GTEST_FLAG(death_test_style).c_str())); + return false; + } + + return true; +} + +// Splits a given string on a given delimiter, populating a given +// vector with the fields. GTEST_HAS_DEATH_TEST implies that we have +// ::std::string, so we can use it here. +static void SplitString(const ::std::string& str, char delimiter, + ::std::vector< ::std::string>* dest) { + ::std::vector< ::std::string> parsed; + ::std::string::size_type pos = 0; + while (::testing::internal::AlwaysTrue()) { + const ::std::string::size_type colon = str.find(delimiter, pos); + if (colon == ::std::string::npos) { + parsed.push_back(str.substr(pos)); + break; + } else { + parsed.push_back(str.substr(pos, colon - pos)); + pos = colon + 1; + } + } + dest->swap(parsed); +} + +#if GTEST_OS_WINDOWS +// Recreates the pipe and event handles from the provided parameters, +// signals the event, and returns a file descriptor wrapped around the pipe +// handle. This function is called in the child process only. +int GetStatusFileDescriptor(unsigned int parent_process_id, + size_t write_handle_as_size_t, + size_t event_handle_as_size_t) { + AutoHandle parent_process_handle(::OpenProcess(PROCESS_DUP_HANDLE, + FALSE, // Non-inheritable. + parent_process_id)); + if (parent_process_handle.Get() == INVALID_HANDLE_VALUE) { + DeathTestAbort(String::Format("Unable to open parent process %u", + parent_process_id)); + } + + // TODO(vladl@google.com): Replace the following check with a + // compile-time assertion when available. + GTEST_CHECK_(sizeof(HANDLE) <= sizeof(size_t)); + + const HANDLE write_handle = + reinterpret_cast<HANDLE>(write_handle_as_size_t); + HANDLE dup_write_handle; + + // The newly initialized handle is accessible only in in the parent + // process. To obtain one accessible within the child, we need to use + // DuplicateHandle. + if (!::DuplicateHandle(parent_process_handle.Get(), write_handle, + ::GetCurrentProcess(), &dup_write_handle, + 0x0, // Requested privileges ignored since + // DUPLICATE_SAME_ACCESS is used. + FALSE, // Request non-inheritable handler. + DUPLICATE_SAME_ACCESS)) { + DeathTestAbort(String::Format( + "Unable to duplicate the pipe handle %Iu from the parent process %u", + write_handle_as_size_t, parent_process_id)); + } + + const HANDLE event_handle = reinterpret_cast<HANDLE>(event_handle_as_size_t); + HANDLE dup_event_handle; + + if (!::DuplicateHandle(parent_process_handle.Get(), event_handle, + ::GetCurrentProcess(), &dup_event_handle, + 0x0, + FALSE, + DUPLICATE_SAME_ACCESS)) { + DeathTestAbort(String::Format( + "Unable to duplicate the event handle %Iu from the parent process %u", + event_handle_as_size_t, parent_process_id)); + } + + const int write_fd = + ::_open_osfhandle(reinterpret_cast<intptr_t>(dup_write_handle), O_APPEND); + if (write_fd == -1) { + DeathTestAbort(String::Format( + "Unable to convert pipe handle %Iu to a file descriptor", + write_handle_as_size_t)); + } + + // Signals the parent that the write end of the pipe has been acquired + // so the parent can release its own write end. + ::SetEvent(dup_event_handle); + + return write_fd; +} +#endif // GTEST_OS_WINDOWS + +// Returns a newly created InternalRunDeathTestFlag object with fields +// initialized from the GTEST_FLAG(internal_run_death_test) flag if +// the flag is specified; otherwise returns NULL. +InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag() { + if (GTEST_FLAG(internal_run_death_test) == "") return NULL; + + // GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we + // can use it here. + int line = -1; + int index = -1; + ::std::vector< ::std::string> fields; + SplitString(GTEST_FLAG(internal_run_death_test).c_str(), '|', &fields); + int write_fd = -1; + +#if GTEST_OS_WINDOWS + unsigned int parent_process_id = 0; + size_t write_handle_as_size_t = 0; + size_t event_handle_as_size_t = 0; + + if (fields.size() != 6 + || !ParseNaturalNumber(fields[1], &line) + || !ParseNaturalNumber(fields[2], &index) + || !ParseNaturalNumber(fields[3], &parent_process_id) + || !ParseNaturalNumber(fields[4], &write_handle_as_size_t) + || !ParseNaturalNumber(fields[5], &event_handle_as_size_t)) { + DeathTestAbort(String::Format( + "Bad --gtest_internal_run_death_test flag: %s", + GTEST_FLAG(internal_run_death_test).c_str())); + } + write_fd = GetStatusFileDescriptor(parent_process_id, + write_handle_as_size_t, + event_handle_as_size_t); +#else + if (fields.size() != 4 + || !ParseNaturalNumber(fields[1], &line) + || !ParseNaturalNumber(fields[2], &index) + || !ParseNaturalNumber(fields[3], &write_fd)) { + DeathTestAbort(String::Format( + "Bad --gtest_internal_run_death_test flag: %s", + GTEST_FLAG(internal_run_death_test).c_str())); + } +#endif // GTEST_OS_WINDOWS + return new InternalRunDeathTestFlag(fields[0], line, index, write_fd); +} + +} // namespace internal + +#endif // GTEST_HAS_DEATH_TEST + +} // namespace testing +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: keith.ray@gmail.com (Keith Ray) + + +#include <stdlib.h> + +#if GTEST_OS_WINDOWS_MOBILE +#include <windows.h> +#elif GTEST_OS_WINDOWS +#include <direct.h> +#include <io.h> +#elif GTEST_OS_SYMBIAN +// Symbian OpenC has PATH_MAX in sys/syslimits.h +#include <sys/syslimits.h> +#else +#include <limits.h> +#include <climits> // Some Linux distributions define PATH_MAX here. +#endif // GTEST_OS_WINDOWS_MOBILE + +#if GTEST_OS_WINDOWS +#define GTEST_PATH_MAX_ _MAX_PATH +#elif defined(PATH_MAX) +#define GTEST_PATH_MAX_ PATH_MAX +#elif defined(_XOPEN_PATH_MAX) +#define GTEST_PATH_MAX_ _XOPEN_PATH_MAX +#else +#define GTEST_PATH_MAX_ _POSIX_PATH_MAX +#endif // GTEST_OS_WINDOWS + + +namespace testing { +namespace internal { + +#if GTEST_OS_WINDOWS +// On Windows, '\\' is the standard path separator, but many tools and the +// Windows API also accept '/' as an alternate path separator. Unless otherwise +// noted, a file path can contain either kind of path separators, or a mixture +// of them. +const char kPathSeparator = '\\'; +const char kAlternatePathSeparator = '/'; +const char kPathSeparatorString[] = "\\"; +const char kAlternatePathSeparatorString[] = "/"; +#if GTEST_OS_WINDOWS_MOBILE +// Windows CE doesn't have a current directory. You should not use +// the current directory in tests on Windows CE, but this at least +// provides a reasonable fallback. +const char kCurrentDirectoryString[] = "\\"; +// Windows CE doesn't define INVALID_FILE_ATTRIBUTES +const DWORD kInvalidFileAttributes = 0xffffffff; +#else +const char kCurrentDirectoryString[] = ".\\"; +#endif // GTEST_OS_WINDOWS_MOBILE +#else +const char kPathSeparator = '/'; +const char kPathSeparatorString[] = "/"; +const char kCurrentDirectoryString[] = "./"; +#endif // GTEST_OS_WINDOWS + +// Returns whether the given character is a valid path separator. +static bool IsPathSeparator(char c) { +#if GTEST_HAS_ALT_PATH_SEP_ + return (c == kPathSeparator) || (c == kAlternatePathSeparator); +#else + return c == kPathSeparator; +#endif +} + +// Returns the current working directory, or "" if unsuccessful. +FilePath FilePath::GetCurrentDir() { +#if GTEST_OS_WINDOWS_MOBILE + // Windows CE doesn't have a current directory, so we just return + // something reasonable. + return FilePath(kCurrentDirectoryString); +#elif GTEST_OS_WINDOWS + char cwd[GTEST_PATH_MAX_ + 1] = { '\0' }; + return FilePath(_getcwd(cwd, sizeof(cwd)) == NULL ? "" : cwd); +#else + char cwd[GTEST_PATH_MAX_ + 1] = { '\0' }; + return FilePath(getcwd(cwd, sizeof(cwd)) == NULL ? "" : cwd); +#endif // GTEST_OS_WINDOWS_MOBILE +} + +// Returns a copy of the FilePath with the case-insensitive extension removed. +// Example: FilePath("dir/file.exe").RemoveExtension("EXE") returns +// FilePath("dir/file"). If a case-insensitive extension is not +// found, returns a copy of the original FilePath. +FilePath FilePath::RemoveExtension(const char* extension) const { + String dot_extension(String::Format(".%s", extension)); + if (pathname_.EndsWithCaseInsensitive(dot_extension.c_str())) { + return FilePath(String(pathname_.c_str(), pathname_.length() - 4)); + } + return *this; +} + +// Returns a pointer to the last occurence of a valid path separator in +// the FilePath. On Windows, for example, both '/' and '\' are valid path +// separators. Returns NULL if no path separator was found. +const char* FilePath::FindLastPathSeparator() const { + const char* const last_sep = strrchr(c_str(), kPathSeparator); +#if GTEST_HAS_ALT_PATH_SEP_ + const char* const last_alt_sep = strrchr(c_str(), kAlternatePathSeparator); + // Comparing two pointers of which only one is NULL is undefined. + if (last_alt_sep != NULL && + (last_sep == NULL || last_alt_sep > last_sep)) { + return last_alt_sep; + } +#endif + return last_sep; +} + +// Returns a copy of the FilePath with the directory part removed. +// Example: FilePath("path/to/file").RemoveDirectoryName() returns +// FilePath("file"). If there is no directory part ("just_a_file"), it returns +// the FilePath unmodified. If there is no file part ("just_a_dir/") it +// returns an empty FilePath (""). +// On Windows platform, '\' is the path separator, otherwise it is '/'. +FilePath FilePath::RemoveDirectoryName() const { + const char* const last_sep = FindLastPathSeparator(); + return last_sep ? FilePath(String(last_sep + 1)) : *this; +} + +// RemoveFileName returns the directory path with the filename removed. +// Example: FilePath("path/to/file").RemoveFileName() returns "path/to/". +// If the FilePath is "a_file" or "/a_file", RemoveFileName returns +// FilePath("./") or, on Windows, FilePath(".\\"). If the filepath does +// not have a file, like "just/a/dir/", it returns the FilePath unmodified. +// On Windows platform, '\' is the path separator, otherwise it is '/'. +FilePath FilePath::RemoveFileName() const { + const char* const last_sep = FindLastPathSeparator(); + String dir; + if (last_sep) { + dir = String(c_str(), last_sep + 1 - c_str()); + } else { + dir = kCurrentDirectoryString; + } + return FilePath(dir); +} + +// Helper functions for naming files in a directory for xml output. + +// Given directory = "dir", base_name = "test", number = 0, +// extension = "xml", returns "dir/test.xml". If number is greater +// than zero (e.g., 12), returns "dir/test_12.xml". +// On Windows platform, uses \ as the separator rather than /. +FilePath FilePath::MakeFileName(const FilePath& directory, + const FilePath& base_name, + int number, + const char* extension) { + String file; + if (number == 0) { + file = String::Format("%s.%s", base_name.c_str(), extension); + } else { + file = String::Format("%s_%d.%s", base_name.c_str(), number, extension); + } + return ConcatPaths(directory, FilePath(file)); +} + +// Given directory = "dir", relative_path = "test.xml", returns "dir/test.xml". +// On Windows, uses \ as the separator rather than /. +FilePath FilePath::ConcatPaths(const FilePath& directory, + const FilePath& relative_path) { + if (directory.IsEmpty()) + return relative_path; + const FilePath dir(directory.RemoveTrailingPathSeparator()); + return FilePath(String::Format("%s%c%s", dir.c_str(), kPathSeparator, + relative_path.c_str())); +} + +// Returns true if pathname describes something findable in the file-system, +// either a file, directory, or whatever. +bool FilePath::FileOrDirectoryExists() const { +#if GTEST_OS_WINDOWS_MOBILE + LPCWSTR unicode = String::AnsiToUtf16(pathname_.c_str()); + const DWORD attributes = GetFileAttributes(unicode); + delete [] unicode; + return attributes != kInvalidFileAttributes; +#else + posix::StatStruct file_stat; + return posix::Stat(pathname_.c_str(), &file_stat) == 0; +#endif // GTEST_OS_WINDOWS_MOBILE +} + +// Returns true if pathname describes a directory in the file-system +// that exists. +bool FilePath::DirectoryExists() const { + bool result = false; +#if GTEST_OS_WINDOWS + // Don't strip off trailing separator if path is a root directory on + // Windows (like "C:\\"). + const FilePath& path(IsRootDirectory() ? *this : + RemoveTrailingPathSeparator()); +#else + const FilePath& path(*this); +#endif + +#if GTEST_OS_WINDOWS_MOBILE + LPCWSTR unicode = String::AnsiToUtf16(path.c_str()); + const DWORD attributes = GetFileAttributes(unicode); + delete [] unicode; + if ((attributes != kInvalidFileAttributes) && + (attributes & FILE_ATTRIBUTE_DIRECTORY)) { + result = true; + } +#else + posix::StatStruct file_stat; + result = posix::Stat(path.c_str(), &file_stat) == 0 && + posix::IsDir(file_stat); +#endif // GTEST_OS_WINDOWS_MOBILE + + return result; +} + +// Returns true if pathname describes a root directory. (Windows has one +// root directory per disk drive.) +bool FilePath::IsRootDirectory() const { +#if GTEST_OS_WINDOWS + // TODO(wan@google.com): on Windows a network share like + // \\server\share can be a root directory, although it cannot be the + // current directory. Handle this properly. + return pathname_.length() == 3 && IsAbsolutePath(); +#else + return pathname_.length() == 1 && IsPathSeparator(pathname_.c_str()[0]); +#endif +} + +// Returns true if pathname describes an absolute path. +bool FilePath::IsAbsolutePath() const { + const char* const name = pathname_.c_str(); +#if GTEST_OS_WINDOWS + return pathname_.length() >= 3 && + ((name[0] >= 'a' && name[0] <= 'z') || + (name[0] >= 'A' && name[0] <= 'Z')) && + name[1] == ':' && + IsPathSeparator(name[2]); +#else + return IsPathSeparator(name[0]); +#endif +} + +// Returns a pathname for a file that does not currently exist. The pathname +// will be directory/base_name.extension or +// directory/base_name_<number>.extension if directory/base_name.extension +// already exists. The number will be incremented until a pathname is found +// that does not already exist. +// Examples: 'dir/foo_test.xml' or 'dir/foo_test_1.xml'. +// There could be a race condition if two or more processes are calling this +// function at the same time -- they could both pick the same filename. +FilePath FilePath::GenerateUniqueFileName(const FilePath& directory, + const FilePath& base_name, + const char* extension) { + FilePath full_pathname; + int number = 0; + do { + full_pathname.Set(MakeFileName(directory, base_name, number++, extension)); + } while (full_pathname.FileOrDirectoryExists()); + return full_pathname; +} + +// Returns true if FilePath ends with a path separator, which indicates that +// it is intended to represent a directory. Returns false otherwise. +// This does NOT check that a directory (or file) actually exists. +bool FilePath::IsDirectory() const { + return !pathname_.empty() && + IsPathSeparator(pathname_.c_str()[pathname_.length() - 1]); +} + +// Create directories so that path exists. Returns true if successful or if +// the directories already exist; returns false if unable to create directories +// for any reason. +bool FilePath::CreateDirectoriesRecursively() const { + if (!this->IsDirectory()) { + return false; + } + + if (pathname_.length() == 0 || this->DirectoryExists()) { + return true; + } + + const FilePath parent(this->RemoveTrailingPathSeparator().RemoveFileName()); + return parent.CreateDirectoriesRecursively() && this->CreateFolder(); +} + +// Create the directory so that path exists. Returns true if successful or +// if the directory already exists; returns false if unable to create the +// directory for any reason, including if the parent directory does not +// exist. Not named "CreateDirectory" because that's a macro on Windows. +bool FilePath::CreateFolder() const { +#if GTEST_OS_WINDOWS_MOBILE + FilePath removed_sep(this->RemoveTrailingPathSeparator()); + LPCWSTR unicode = String::AnsiToUtf16(removed_sep.c_str()); + int result = CreateDirectory(unicode, NULL) ? 0 : -1; + delete [] unicode; +#elif GTEST_OS_WINDOWS + int result = _mkdir(pathname_.c_str()); +#else + int result = mkdir(pathname_.c_str(), 0777); +#endif // GTEST_OS_WINDOWS_MOBILE + + if (result == -1) { + return this->DirectoryExists(); // An error is OK if the directory exists. + } + return true; // No error. +} + +// If input name has a trailing separator character, remove it and return the +// name, otherwise return the name string unmodified. +// On Windows platform, uses \ as the separator, other platforms use /. +FilePath FilePath::RemoveTrailingPathSeparator() const { + return IsDirectory() + ? FilePath(String(pathname_.c_str(), pathname_.length() - 1)) + : *this; +} + +// Removes any redundant separators that might be in the pathname. +// For example, "bar///foo" becomes "bar/foo". Does not eliminate other +// redundancies that might be in a pathname involving "." or "..". +// TODO(wan@google.com): handle Windows network shares (e.g. \\server\share). +void FilePath::Normalize() { + if (pathname_.c_str() == NULL) { + pathname_ = ""; + return; + } + const char* src = pathname_.c_str(); + char* const dest = new char[pathname_.length() + 1]; + char* dest_ptr = dest; + memset(dest_ptr, 0, pathname_.length() + 1); + + while (*src != '\0') { + *dest_ptr = *src; + if (!IsPathSeparator(*src)) { + src++; + } else { +#if GTEST_HAS_ALT_PATH_SEP_ + if (*dest_ptr == kAlternatePathSeparator) { + *dest_ptr = kPathSeparator; + } +#endif + while (IsPathSeparator(*src)) + src++; + } + dest_ptr++; + } + *dest_ptr = '\0'; + pathname_ = dest; + delete[] dest; +} + +} // namespace internal +} // namespace testing +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: wan@google.com (Zhanyong Wan) + + +#include <limits.h> +#include <stdlib.h> +#include <stdio.h> + +#if GTEST_OS_WINDOWS_MOBILE +#include <windows.h> // For TerminateProcess() +#elif GTEST_OS_WINDOWS +#include <io.h> +#include <sys/stat.h> +#else +#include <unistd.h> +#endif // GTEST_OS_WINDOWS_MOBILE + +#if GTEST_OS_MAC +#include <mach/mach_init.h> +#include <mach/task.h> +#include <mach/vm_map.h> +#endif // GTEST_OS_MAC + + +// Indicates that this translation unit is part of Google Test's +// implementation. It must come before gtest-internal-inl.h is +// included, or there will be a compiler error. This trick is to +// prevent a user from accidentally including gtest-internal-inl.h in +// his code. +#define GTEST_IMPLEMENTATION_ 1 +#undef GTEST_IMPLEMENTATION_ + +namespace testing { +namespace internal { + +#if defined(_MSC_VER) || defined(__BORLANDC__) +// MSVC and C++Builder do not provide a definition of STDERR_FILENO. +const int kStdOutFileno = 1; +const int kStdErrFileno = 2; +#else +const int kStdOutFileno = STDOUT_FILENO; +const int kStdErrFileno = STDERR_FILENO; +#endif // _MSC_VER + +#if GTEST_OS_MAC + +// Returns the number of threads running in the process, or 0 to indicate that +// we cannot detect it. +size_t GetThreadCount() { + const task_t task = mach_task_self(); + mach_msg_type_number_t thread_count; + thread_act_array_t thread_list; + const kern_return_t status = task_threads(task, &thread_list, &thread_count); + if (status == KERN_SUCCESS) { + // task_threads allocates resources in thread_list and we need to free them + // to avoid leaks. + vm_deallocate(task, + reinterpret_cast<vm_address_t>(thread_list), + sizeof(thread_t) * thread_count); + return static_cast<size_t>(thread_count); + } else { + return 0; + } +} + +#else + +size_t GetThreadCount() { + // There's no portable way to detect the number of threads, so we just + // return 0 to indicate that we cannot detect it. + return 0; +} + +#endif // GTEST_OS_MAC + +#if GTEST_USES_POSIX_RE + +// Implements RE. Currently only needed for death tests. + +RE::~RE() { + if (is_valid_) { + // regfree'ing an invalid regex might crash because the content + // of the regex is undefined. Since the regex's are essentially + // the same, one cannot be valid (or invalid) without the other + // being so too. + regfree(&partial_regex_); + regfree(&full_regex_); + } + free(const_cast<char*>(pattern_)); +} + +// Returns true iff regular expression re matches the entire str. +bool RE::FullMatch(const char* str, const RE& re) { + if (!re.is_valid_) return false; + + regmatch_t match; + return regexec(&re.full_regex_, str, 1, &match, 0) == 0; +} + +// Returns true iff regular expression re matches a substring of str +// (including str itself). +bool RE::PartialMatch(const char* str, const RE& re) { + if (!re.is_valid_) return false; + + regmatch_t match; + return regexec(&re.partial_regex_, str, 1, &match, 0) == 0; +} + +// Initializes an RE from its string representation. +void RE::Init(const char* regex) { + pattern_ = posix::StrDup(regex); + + // Reserves enough bytes to hold the regular expression used for a + // full match. + const size_t full_regex_len = strlen(regex) + 10; + char* const full_pattern = new char[full_regex_len]; + + snprintf(full_pattern, full_regex_len, "^(%s)$", regex); + is_valid_ = regcomp(&full_regex_, full_pattern, REG_EXTENDED) == 0; + // We want to call regcomp(&partial_regex_, ...) even if the + // previous expression returns false. Otherwise partial_regex_ may + // not be properly initialized can may cause trouble when it's + // freed. + // + // Some implementation of POSIX regex (e.g. on at least some + // versions of Cygwin) doesn't accept the empty string as a valid + // regex. We change it to an equivalent form "()" to be safe. + if (is_valid_) { + const char* const partial_regex = (*regex == '\0') ? "()" : regex; + is_valid_ = regcomp(&partial_regex_, partial_regex, REG_EXTENDED) == 0; + } + EXPECT_TRUE(is_valid_) + << "Regular expression \"" << regex + << "\" is not a valid POSIX Extended regular expression."; + + delete[] full_pattern; +} + +#elif GTEST_USES_SIMPLE_RE + +// Returns true iff ch appears anywhere in str (excluding the +// terminating '\0' character). +bool IsInSet(char ch, const char* str) { + return ch != '\0' && strchr(str, ch) != NULL; +} + +// Returns true iff ch belongs to the given classification. Unlike +// similar functions in <ctype.h>, these aren't affected by the +// current locale. +bool IsDigit(char ch) { return '0' <= ch && ch <= '9'; } +bool IsPunct(char ch) { + return IsInSet(ch, "^-!\"#$%&'()*+,./:;<=>?@[\\]_`{|}~"); +} +bool IsRepeat(char ch) { return IsInSet(ch, "?*+"); } +bool IsWhiteSpace(char ch) { return IsInSet(ch, " \f\n\r\t\v"); } +bool IsWordChar(char ch) { + return ('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z') || + ('0' <= ch && ch <= '9') || ch == '_'; +} + +// Returns true iff "\\c" is a supported escape sequence. +bool IsValidEscape(char c) { + return (IsPunct(c) || IsInSet(c, "dDfnrsStvwW")); +} + +// Returns true iff the given atom (specified by escaped and pattern) +// matches ch. The result is undefined if the atom is invalid. +bool AtomMatchesChar(bool escaped, char pattern_char, char ch) { + if (escaped) { // "\\p" where p is pattern_char. + switch (pattern_char) { + case 'd': return IsDigit(ch); + case 'D': return !IsDigit(ch); + case 'f': return ch == '\f'; + case 'n': return ch == '\n'; + case 'r': return ch == '\r'; + case 's': return IsWhiteSpace(ch); + case 'S': return !IsWhiteSpace(ch); + case 't': return ch == '\t'; + case 'v': return ch == '\v'; + case 'w': return IsWordChar(ch); + case 'W': return !IsWordChar(ch); + } + return IsPunct(pattern_char) && pattern_char == ch; + } + + return (pattern_char == '.' && ch != '\n') || pattern_char == ch; +} + +// Helper function used by ValidateRegex() to format error messages. +String FormatRegexSyntaxError(const char* regex, int index) { + return (Message() << "Syntax error at index " << index + << " in simple regular expression \"" << regex << "\": ").GetString(); +} + +// Generates non-fatal failures and returns false if regex is invalid; +// otherwise returns true. +bool ValidateRegex(const char* regex) { + if (regex == NULL) { + // TODO(wan@google.com): fix the source file location in the + // assertion failures to match where the regex is used in user + // code. + ADD_FAILURE() << "NULL is not a valid simple regular expression."; + return false; + } + + bool is_valid = true; + + // True iff ?, *, or + can follow the previous atom. + bool prev_repeatable = false; + for (int i = 0; regex[i]; i++) { + if (regex[i] == '\\') { // An escape sequence + i++; + if (regex[i] == '\0') { + ADD_FAILURE() << FormatRegexSyntaxError(regex, i - 1) + << "'\\' cannot appear at the end."; + return false; + } + + if (!IsValidEscape(regex[i])) { + ADD_FAILURE() << FormatRegexSyntaxError(regex, i - 1) + << "invalid escape sequence \"\\" << regex[i] << "\"."; + is_valid = false; + } + prev_repeatable = true; + } else { // Not an escape sequence. + const char ch = regex[i]; + + if (ch == '^' && i > 0) { + ADD_FAILURE() << FormatRegexSyntaxError(regex, i) + << "'^' can only appear at the beginning."; + is_valid = false; + } else if (ch == '$' && regex[i + 1] != '\0') { + ADD_FAILURE() << FormatRegexSyntaxError(regex, i) + << "'$' can only appear at the end."; + is_valid = false; + } else if (IsInSet(ch, "()[]{}|")) { + ADD_FAILURE() << FormatRegexSyntaxError(regex, i) + << "'" << ch << "' is unsupported."; + is_valid = false; + } else if (IsRepeat(ch) && !prev_repeatable) { + ADD_FAILURE() << FormatRegexSyntaxError(regex, i) + << "'" << ch << "' can only follow a repeatable token."; + is_valid = false; + } + + prev_repeatable = !IsInSet(ch, "^$?*+"); + } + } + + return is_valid; +} + +// Matches a repeated regex atom followed by a valid simple regular +// expression. The regex atom is defined as c if escaped is false, +// or \c otherwise. repeat is the repetition meta character (?, *, +// or +). The behavior is undefined if str contains too many +// characters to be indexable by size_t, in which case the test will +// probably time out anyway. We are fine with this limitation as +// std::string has it too. +bool MatchRepetitionAndRegexAtHead( + bool escaped, char c, char repeat, const char* regex, + const char* str) { + const size_t min_count = (repeat == '+') ? 1 : 0; + const size_t max_count = (repeat == '?') ? 1 : + static_cast<size_t>(-1) - 1; + // We cannot call numeric_limits::max() as it conflicts with the + // max() macro on Windows. + + for (size_t i = 0; i <= max_count; ++i) { + // We know that the atom matches each of the first i characters in str. + if (i >= min_count && MatchRegexAtHead(regex, str + i)) { + // We have enough matches at the head, and the tail matches too. + // Since we only care about *whether* the pattern matches str + // (as opposed to *how* it matches), there is no need to find a + // greedy match. + return true; + } + if (str[i] == '\0' || !AtomMatchesChar(escaped, c, str[i])) + return false; + } + return false; +} + +// Returns true iff regex matches a prefix of str. regex must be a +// valid simple regular expression and not start with "^", or the +// result is undefined. +bool MatchRegexAtHead(const char* regex, const char* str) { + if (*regex == '\0') // An empty regex matches a prefix of anything. + return true; + + // "$" only matches the end of a string. Note that regex being + // valid guarantees that there's nothing after "$" in it. + if (*regex == '$') + return *str == '\0'; + + // Is the first thing in regex an escape sequence? + const bool escaped = *regex == '\\'; + if (escaped) + ++regex; + if (IsRepeat(regex[1])) { + // MatchRepetitionAndRegexAtHead() calls MatchRegexAtHead(), so + // here's an indirect recursion. It terminates as the regex gets + // shorter in each recursion. + return MatchRepetitionAndRegexAtHead( + escaped, regex[0], regex[1], regex + 2, str); + } else { + // regex isn't empty, isn't "$", and doesn't start with a + // repetition. We match the first atom of regex with the first + // character of str and recurse. + return (*str != '\0') && AtomMatchesChar(escaped, *regex, *str) && + MatchRegexAtHead(regex + 1, str + 1); + } +} + +// Returns true iff regex matches any substring of str. regex must be +// a valid simple regular expression, or the result is undefined. +// +// The algorithm is recursive, but the recursion depth doesn't exceed +// the regex length, so we won't need to worry about running out of +// stack space normally. In rare cases the time complexity can be +// exponential with respect to the regex length + the string length, +// but usually it's must faster (often close to linear). +bool MatchRegexAnywhere(const char* regex, const char* str) { + if (regex == NULL || str == NULL) + return false; + + if (*regex == '^') + return MatchRegexAtHead(regex + 1, str); + + // A successful match can be anywhere in str. + do { + if (MatchRegexAtHead(regex, str)) + return true; + } while (*str++ != '\0'); + return false; +} + +// Implements the RE class. + +RE::~RE() { + free(const_cast<char*>(pattern_)); + free(const_cast<char*>(full_pattern_)); +} + +// Returns true iff regular expression re matches the entire str. +bool RE::FullMatch(const char* str, const RE& re) { + return re.is_valid_ && MatchRegexAnywhere(re.full_pattern_, str); +} + +// Returns true iff regular expression re matches a substring of str +// (including str itself). +bool RE::PartialMatch(const char* str, const RE& re) { + return re.is_valid_ && MatchRegexAnywhere(re.pattern_, str); +} + +// Initializes an RE from its string representation. +void RE::Init(const char* regex) { + pattern_ = full_pattern_ = NULL; + if (regex != NULL) { + pattern_ = posix::StrDup(regex); + } + + is_valid_ = ValidateRegex(regex); + if (!is_valid_) { + // No need to calculate the full pattern when the regex is invalid. + return; + } + + const size_t len = strlen(regex); + // Reserves enough bytes to hold the regular expression used for a + // full match: we need space to prepend a '^', append a '$', and + // terminate the string with '\0'. + char* buffer = static_cast<char*>(malloc(len + 3)); + full_pattern_ = buffer; + + if (*regex != '^') + *buffer++ = '^'; // Makes sure full_pattern_ starts with '^'. + + // We don't use snprintf or strncpy, as they trigger a warning when + // compiled with VC++ 8.0. + memcpy(buffer, regex, len); + buffer += len; + + if (len == 0 || regex[len - 1] != '$') + *buffer++ = '$'; // Makes sure full_pattern_ ends with '$'. + + *buffer = '\0'; +} + +#endif // GTEST_USES_POSIX_RE + + +GTestLog::GTestLog(GTestLogSeverity severity, const char* file, int line) + : severity_(severity) { + const char* const marker = + severity == GTEST_INFO ? "[ INFO ]" : + severity == GTEST_WARNING ? "[WARNING]" : + severity == GTEST_ERROR ? "[ ERROR ]" : "[ FATAL ]"; + GetStream() << ::std::endl << marker << " " + << FormatFileLocation(file, line).c_str() << ": "; +} + +// Flushes the buffers and, if severity is GTEST_FATAL, aborts the program. +GTestLog::~GTestLog() { + GetStream() << ::std::endl; + if (severity_ == GTEST_FATAL) { + fflush(stderr); + posix::Abort(); + } +} +// Disable Microsoft deprecation warnings for POSIX functions called from +// this class (creat, dup, dup2, and close) +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable: 4996) +#endif // _MSC_VER + +#if GTEST_HAS_STREAM_REDIRECTION_ + +// Object that captures an output stream (stdout/stderr). +class CapturedStream { + public: + // The ctor redirects the stream to a temporary file. + CapturedStream(int fd) : fd_(fd), uncaptured_fd_(dup(fd)) { +#if GTEST_OS_WINDOWS + char temp_dir_path[MAX_PATH + 1] = { '\0' }; // NOLINT + char temp_file_path[MAX_PATH + 1] = { '\0' }; // NOLINT + + ::GetTempPathA(sizeof(temp_dir_path), temp_dir_path); + const UINT success = ::GetTempFileNameA(temp_dir_path, + "gtest_redir", + 0, // Generate unique file name. + temp_file_path); + GTEST_CHECK_(success != 0) + << "Unable to create a temporary file in " << temp_dir_path; + const int captured_fd = creat(temp_file_path, _S_IREAD | _S_IWRITE); + GTEST_CHECK_(captured_fd != -1) << "Unable to open temporary file " + << temp_file_path; + filename_ = temp_file_path; +#else + // There's no guarantee that a test has write access to the + // current directory, so we create the temporary file in the /tmp + // directory instead. + char name_template[] = "/tmp/captured_stream.XXXXXX"; + const int captured_fd = mkstemp(name_template); + filename_ = name_template; +#endif // GTEST_OS_WINDOWS + fflush(NULL); + dup2(captured_fd, fd_); + close(captured_fd); + } + + ~CapturedStream() { + remove(filename_.c_str()); + } + + String GetCapturedString() { + if (uncaptured_fd_ != -1) { + // Restores the original stream. + fflush(NULL); + dup2(uncaptured_fd_, fd_); + close(uncaptured_fd_); + uncaptured_fd_ = -1; + } + + FILE* const file = posix::FOpen(filename_.c_str(), "r"); + const String content = ReadEntireFile(file); + posix::FClose(file); + return content; + } + + private: + // Reads the entire content of a file as a String. + static String ReadEntireFile(FILE* file); + + // Returns the size (in bytes) of a file. + static size_t GetFileSize(FILE* file); + + const int fd_; // A stream to capture. + int uncaptured_fd_; + // Name of the temporary file holding the stderr output. + ::std::string filename_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(CapturedStream); +}; + +// Returns the size (in bytes) of a file. +size_t CapturedStream::GetFileSize(FILE* file) { + fseek(file, 0, SEEK_END); + return static_cast<size_t>(ftell(file)); +} + +// Reads the entire content of a file as a string. +String CapturedStream::ReadEntireFile(FILE* file) { + const size_t file_size = GetFileSize(file); + char* const buffer = new char[file_size]; + + size_t bytes_last_read = 0; // # of bytes read in the last fread() + size_t bytes_read = 0; // # of bytes read so far + + fseek(file, 0, SEEK_SET); + + // Keeps reading the file until we cannot read further or the + // pre-determined file size is reached. + do { + bytes_last_read = fread(buffer+bytes_read, 1, file_size-bytes_read, file); + bytes_read += bytes_last_read; + } while (bytes_last_read > 0 && bytes_read < file_size); + + const String content(buffer, bytes_read); + delete[] buffer; + + return content; +} + +#ifdef _MSC_VER +#pragma warning(pop) +#endif // _MSC_VER + +static CapturedStream* g_captured_stderr = NULL; +static CapturedStream* g_captured_stdout = NULL; + +// Starts capturing an output stream (stdout/stderr). +void CaptureStream(int fd, const char* stream_name, CapturedStream** stream) { + if (*stream != NULL) { + GTEST_LOG_(FATAL) << "Only one " << stream_name + << " capturer can exist at a time."; + } + *stream = new CapturedStream(fd); +} + +// Stops capturing the output stream and returns the captured string. +String GetCapturedStream(CapturedStream** captured_stream) { + const String content = (*captured_stream)->GetCapturedString(); + + delete *captured_stream; + *captured_stream = NULL; + + return content; +} + +// Starts capturing stdout. +void CaptureStdout() { + CaptureStream(kStdOutFileno, "stdout", &g_captured_stdout); +} + +// Starts capturing stderr. +void CaptureStderr() { + CaptureStream(kStdErrFileno, "stderr", &g_captured_stderr); +} + +// Stops capturing stdout and returns the captured string. +String GetCapturedStdout() { return GetCapturedStream(&g_captured_stdout); } + +// Stops capturing stderr and returns the captured string. +String GetCapturedStderr() { return GetCapturedStream(&g_captured_stderr); } + +#endif // GTEST_HAS_STREAM_REDIRECTION_ + +#if GTEST_HAS_DEATH_TEST + +// A copy of all command line arguments. Set by InitGoogleTest(). +::std::vector<String> g_argvs; + +// Returns the command line as a vector of strings. +const ::std::vector<String>& GetArgvs() { return g_argvs; } + +#endif // GTEST_HAS_DEATH_TEST + +#if GTEST_OS_WINDOWS_MOBILE +namespace posix { +void Abort() { + DebugBreak(); + TerminateProcess(GetCurrentProcess(), 1); +} +} // namespace posix +#endif // GTEST_OS_WINDOWS_MOBILE + +// Returns the name of the environment variable corresponding to the +// given flag. For example, FlagToEnvVar("foo") will return +// "GTEST_FOO" in the open-source version. +static String FlagToEnvVar(const char* flag) { + const String full_flag = + (Message() << GTEST_FLAG_PREFIX_ << flag).GetString(); + + Message env_var; + for (size_t i = 0; i != full_flag.length(); i++) { + env_var << static_cast<char>(toupper(full_flag.c_str()[i])); + } + + return env_var.GetString(); +} + +// Parses 'str' for a 32-bit signed integer. If successful, writes +// the result to *value and returns true; otherwise leaves *value +// unchanged and returns false. +bool ParseInt32(const Message& src_text, const char* str, Int32* value) { + // Parses the environment variable as a decimal integer. + char* end = NULL; + const long long_value = strtol(str, &end, 10); // NOLINT + + // Has strtol() consumed all characters in the string? + if (*end != '\0') { + // No - an invalid character was encountered. + Message msg; + msg << "WARNING: " << src_text + << " is expected to be a 32-bit integer, but actually" + << " has value \"" << str << "\".\n"; + printf("%s", msg.GetString().c_str()); + fflush(stdout); + return false; + } + + // Is the parsed value in the range of an Int32? + const Int32 result = static_cast<Int32>(long_value); + if (long_value == LONG_MAX || long_value == LONG_MIN || + // The parsed value overflows as a long. (strtol() returns + // LONG_MAX or LONG_MIN when the input overflows.) + result != long_value + // The parsed value overflows as an Int32. + ) { + Message msg; + msg << "WARNING: " << src_text + << " is expected to be a 32-bit integer, but actually" + << " has value " << str << ", which overflows.\n"; + printf("%s", msg.GetString().c_str()); + fflush(stdout); + return false; + } + + *value = result; + return true; +} + +// Reads and returns the Boolean environment variable corresponding to +// the given flag; if it's not set, returns default_value. +// +// The value is considered true iff it's not "0". +bool BoolFromGTestEnv(const char* flag, bool default_value) { + const String env_var = FlagToEnvVar(flag); + const char* const string_value = posix::GetEnv(env_var.c_str()); + return string_value == NULL ? + default_value : strcmp(string_value, "0") != 0; +} + +// Reads and returns a 32-bit integer stored in the environment +// variable corresponding to the given flag; if it isn't set or +// doesn't represent a valid 32-bit integer, returns default_value. +Int32 Int32FromGTestEnv(const char* flag, Int32 default_value) { + const String env_var = FlagToEnvVar(flag); + const char* const string_value = posix::GetEnv(env_var.c_str()); + if (string_value == NULL) { + // The environment variable is not set. + return default_value; + } + + Int32 result = default_value; + if (!ParseInt32(Message() << "Environment variable " << env_var, + string_value, &result)) { + printf("The default value %s is used.\n", + (Message() << default_value).GetString().c_str()); + fflush(stdout); + return default_value; + } + + return result; +} + +// Reads and returns the string environment variable corresponding to +// the given flag; if it's not set, returns default_value. +const char* StringFromGTestEnv(const char* flag, const char* default_value) { + const String env_var = FlagToEnvVar(flag); + const char* const value = posix::GetEnv(env_var.c_str()); + return value == NULL ? default_value : value; +} + +} // namespace internal +} // namespace testing +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: mheule@google.com (Markus Heule) +// +// The Google C++ Testing Framework (Google Test) + + +// Indicates that this translation unit is part of Google Test's +// implementation. It must come before gtest-internal-inl.h is +// included, or there will be a compiler error. This trick is to +// prevent a user from accidentally including gtest-internal-inl.h in +// his code. +#define GTEST_IMPLEMENTATION_ 1 +#undef GTEST_IMPLEMENTATION_ + +namespace testing { + +using internal::GetUnitTestImpl; + +// Gets the summary of the failure message by omitting the stack trace +// in it. +internal::String TestPartResult::ExtractSummary(const char* message) { + const char* const stack_trace = strstr(message, internal::kStackTraceMarker); + return stack_trace == NULL ? internal::String(message) : + internal::String(message, stack_trace - message); +} + +// Prints a TestPartResult object. +std::ostream& operator<<(std::ostream& os, const TestPartResult& result) { + return os + << result.file_name() << ":" << result.line_number() << ": " + << (result.type() == TestPartResult::kSuccess ? "Success" : + result.type() == TestPartResult::kFatalFailure ? "Fatal failure" : + "Non-fatal failure") << ":\n" + << result.message() << std::endl; +} + +// Appends a TestPartResult to the array. +void TestPartResultArray::Append(const TestPartResult& result) { + array_.push_back(result); +} + +// Returns the TestPartResult at the given index (0-based). +const TestPartResult& TestPartResultArray::GetTestPartResult(int index) const { + if (index < 0 || index >= size()) { + printf("\nInvalid index (%d) into TestPartResultArray.\n", index); + internal::posix::Abort(); + } + + return array_[index]; +} + +// Returns the number of TestPartResult objects in the array. +int TestPartResultArray::size() const { + return static_cast<int>(array_.size()); +} + +namespace internal { + +HasNewFatalFailureHelper::HasNewFatalFailureHelper() + : has_new_fatal_failure_(false), + original_reporter_(GetUnitTestImpl()-> + GetTestPartResultReporterForCurrentThread()) { + GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread(this); +} + +HasNewFatalFailureHelper::~HasNewFatalFailureHelper() { + GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread( + original_reporter_); +} + +void HasNewFatalFailureHelper::ReportTestPartResult( + const TestPartResult& result) { + if (result.fatally_failed()) + has_new_fatal_failure_ = true; + original_reporter_->ReportTestPartResult(result); +} + +} // namespace internal + +} // namespace testing +// Copyright 2008 Google Inc. +// All Rights Reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: wan@google.com (Zhanyong Wan) + + +namespace testing { +namespace internal { + +#if GTEST_HAS_TYPED_TEST_P + +// Skips to the first non-space char in str. Returns an empty string if str +// contains only whitespace characters. +static const char* SkipSpaces(const char* str) { + while (isspace(*str)) + str++; + return str; +} + +// Verifies that registered_tests match the test names in +// defined_test_names_; returns registered_tests if successful, or +// aborts the program otherwise. +const char* TypedTestCasePState::VerifyRegisteredTestNames( + const char* file, int line, const char* registered_tests) { + typedef ::std::set<const char*>::const_iterator DefinedTestIter; + registered_ = true; + + // Skip initial whitespace in registered_tests since some + // preprocessors prefix stringizied literals with whitespace. + registered_tests = SkipSpaces(registered_tests); + + Message errors; + ::std::set<String> tests; + for (const char* names = registered_tests; names != NULL; + names = SkipComma(names)) { + const String name = GetPrefixUntilComma(names); + if (tests.count(name) != 0) { + errors << "Test " << name << " is listed more than once.\n"; + continue; + } + + bool found = false; + for (DefinedTestIter it = defined_test_names_.begin(); + it != defined_test_names_.end(); + ++it) { + if (name == *it) { + found = true; + break; + } + } + + if (found) { + tests.insert(name); + } else { + errors << "No test named " << name + << " can be found in this test case.\n"; + } + } + + for (DefinedTestIter it = defined_test_names_.begin(); + it != defined_test_names_.end(); + ++it) { + if (tests.count(*it) == 0) { + errors << "You forgot to list test " << *it << ".\n"; + } + } + + const String& errors_str = errors.GetString(); + if (errors_str != "") { + fprintf(stderr, "%s %s", FormatFileLocation(file, line).c_str(), + errors_str.c_str()); + fflush(stderr); + posix::Abort(); + } + + return registered_tests; +} + +#endif // GTEST_HAS_TYPED_TEST_P + +} // namespace internal +} // namespace testing diff --git a/Fwk/AppFwk/cafUserInterface/cafUserInterface_UnitTests/gtest/gtest.h b/Fwk/AppFwk/cafUserInterface/cafUserInterface_UnitTests/gtest/gtest.h new file mode 100644 index 0000000000..c0a1902e25 --- /dev/null +++ b/Fwk/AppFwk/cafUserInterface/cafUserInterface_UnitTests/gtest/gtest.h @@ -0,0 +1,18007 @@ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: wan@google.com (Zhanyong Wan) +// +// The Google C++ Testing Framework (Google Test) +// +// This header file defines the public API for Google Test. It should be +// included by any test program that uses Google Test. +// +// IMPORTANT NOTE: Due to limitation of the C++ language, we have to +// leave some internal implementation details in this header file. +// They are clearly marked by comments like this: +// +// // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +// +// Such code is NOT meant to be used by a user directly, and is subject +// to CHANGE WITHOUT NOTICE. Therefore DO NOT DEPEND ON IT in a user +// program! +// +// Acknowledgment: Google Test borrowed the idea of automatic test +// registration from Barthelemy Dagenais' (barthelemy@prologique.com) +// easyUnit framework. + +#ifndef GTEST_INCLUDE_GTEST_GTEST_H_ +#define GTEST_INCLUDE_GTEST_GTEST_H_ + +#include <limits> +#include <vector> + +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee) +// +// The Google C++ Testing Framework (Google Test) +// +// This header file declares functions and macros used internally by +// Google Test. They are subject to change without notice. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_ + +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: wan@google.com (Zhanyong Wan) +// +// Low-level types and utilities for porting Google Test to various +// platforms. They are subject to change without notice. DO NOT USE +// THEM IN USER CODE. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_ + +// The user can define the following macros in the build script to +// control Google Test's behavior. If the user doesn't define a macro +// in this list, Google Test will define it. +// +// GTEST_HAS_CLONE - Define it to 1/0 to indicate that clone(2) +// is/isn't available. +// GTEST_HAS_EXCEPTIONS - Define it to 1/0 to indicate that exceptions +// are enabled. +// GTEST_HAS_GLOBAL_STRING - Define it to 1/0 to indicate that ::string +// is/isn't available (some systems define +// ::string, which is different to std::string). +// GTEST_HAS_GLOBAL_WSTRING - Define it to 1/0 to indicate that ::string +// is/isn't available (some systems define +// ::wstring, which is different to std::wstring). +// GTEST_HAS_PTHREAD - Define it to 1/0 to indicate that <pthread.h> +// is/isn't available. +// GTEST_HAS_RTTI - Define it to 1/0 to indicate that RTTI is/isn't +// enabled. +// GTEST_HAS_STD_WSTRING - Define it to 1/0 to indicate that +// std::wstring does/doesn't work (Google Test can +// be used where std::wstring is unavailable). +// GTEST_HAS_TR1_TUPLE - Define it to 1/0 to indicate tr1::tuple +// is/isn't available. +// GTEST_HAS_SEH - Define it to 1/0 to indicate whether the +// compiler supports Microsoft's "Structured +// Exception Handling". +// GTEST_USE_OWN_TR1_TUPLE - Define it to 1/0 to indicate whether Google +// Test's own tr1 tuple implementation should be +// used. Unused when the user sets +// GTEST_HAS_TR1_TUPLE to 0. +// GTEST_LINKED_AS_SHARED_LIBRARY +// - Define to 1 when compiling tests that use +// Google Test as a shared library (known as +// DLL on Windows). +// GTEST_CREATE_SHARED_LIBRARY +// - Define to 1 when compiling Google Test itself +// as a shared library. + +// This header defines the following utilities: +// +// Macros indicating the current platform (defined to 1 if compiled on +// the given platform; otherwise undefined): +// GTEST_OS_AIX - IBM AIX +// GTEST_OS_CYGWIN - Cygwin +// GTEST_OS_LINUX - Linux +// GTEST_OS_MAC - Mac OS X +// GTEST_OS_SOLARIS - Sun Solaris +// GTEST_OS_SYMBIAN - Symbian +// GTEST_OS_WINDOWS - Windows (Desktop, MinGW, or Mobile) +// GTEST_OS_WINDOWS_DESKTOP - Windows Desktop +// GTEST_OS_WINDOWS_MINGW - MinGW +// GTEST_OS_WINDOWS_MOBILE - Windows Mobile +// GTEST_OS_ZOS - z/OS +// +// Among the platforms, Cygwin, Linux, Max OS X, and Windows have the +// most stable support. Since core members of the Google Test project +// don't have access to other platforms, support for them may be less +// stable. If you notice any problems on your platform, please notify +// googletestframework@googlegroups.com (patches for fixing them are +// even more welcome!). +// +// Note that it is possible that none of the GTEST_OS_* macros are defined. +// +// Macros indicating available Google Test features (defined to 1 if +// the corresponding feature is supported; otherwise undefined): +// GTEST_HAS_COMBINE - the Combine() function (for value-parameterized +// tests) +// GTEST_HAS_DEATH_TEST - death tests +// GTEST_HAS_PARAM_TEST - value-parameterized tests +// GTEST_HAS_TYPED_TEST - typed tests +// GTEST_HAS_TYPED_TEST_P - type-parameterized tests +// GTEST_USES_POSIX_RE - enhanced POSIX regex is used. +// GTEST_USES_SIMPLE_RE - our own simple regex is used; +// the above two are mutually exclusive. +// GTEST_CAN_COMPARE_NULL - accepts untyped NULL in EXPECT_EQ(). +// +// Macros for basic C++ coding: +// GTEST_AMBIGUOUS_ELSE_BLOCKER_ - for disabling a gcc warning. +// GTEST_ATTRIBUTE_UNUSED_ - declares that a class' instances or a +// variable don't have to be used. +// GTEST_DISALLOW_ASSIGN_ - disables operator=. +// GTEST_DISALLOW_COPY_AND_ASSIGN_ - disables copy ctor and operator=. +// GTEST_MUST_USE_RESULT_ - declares that a function's result must be used. +// +// Synchronization: +// Mutex, MutexLock, ThreadLocal, GetThreadCount() +// - synchronization primitives. +// GTEST_IS_THREADSAFE - defined to 1 to indicate that the above +// synchronization primitives have real implementations +// and Google Test is thread-safe; or 0 otherwise. +// +// Template meta programming: +// is_pointer - as in TR1; needed on Symbian and IBM XL C/C++ only. +// +// Smart pointers: +// scoped_ptr - as in TR2. +// +// Regular expressions: +// RE - a simple regular expression class using the POSIX +// Extended Regular Expression syntax. Not available on +// Windows. +// +// Logging: +// GTEST_LOG_() - logs messages at the specified severity level. +// LogToStderr() - directs all log messages to stderr. +// FlushInfoLog() - flushes informational log messages. +// +// Stdout and stderr capturing: +// CaptureStdout() - starts capturing stdout. +// GetCapturedStdout() - stops capturing stdout and returns the captured +// string. +// CaptureStderr() - starts capturing stderr. +// GetCapturedStderr() - stops capturing stderr and returns the captured +// string. +// +// Integer types: +// TypeWithSize - maps an integer to a int type. +// Int32, UInt32, Int64, UInt64, TimeInMillis +// - integers of known sizes. +// BiggestInt - the biggest signed integer type. +// +// Command-line utilities: +// GTEST_FLAG() - references a flag. +// GTEST_DECLARE_*() - declares a flag. +// GTEST_DEFINE_*() - defines a flag. +// GetArgvs() - returns the command line as a vector of strings. +// +// Environment variable utilities: +// GetEnv() - gets the value of an environment variable. +// BoolFromGTestEnv() - parses a bool environment variable. +// Int32FromGTestEnv() - parses an Int32 environment variable. +// StringFromGTestEnv() - parses a string environment variable. + +#include <stddef.h> // For ptrdiff_t +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#ifndef _WIN32_WCE +#include <sys/stat.h> +#endif // !_WIN32_WCE + +#include <iostream> // NOLINT +#include <sstream> // NOLINT +#include <string> // NOLINT + +#define GTEST_DEV_EMAIL_ "googletestframework@@googlegroups.com" +#define GTEST_FLAG_PREFIX_ "gtest_" +#define GTEST_FLAG_PREFIX_DASH_ "gtest-" +#define GTEST_FLAG_PREFIX_UPPER_ "GTEST_" +#define GTEST_NAME_ "Google Test" +#define GTEST_PROJECT_URL_ "http://code.google.com/p/googletest/" + +// Determines the version of gcc that is used to compile this. +#ifdef __GNUC__ +// 40302 means version 4.3.2. +#define GTEST_GCC_VER_ \ + (__GNUC__*10000 + __GNUC_MINOR__*100 + __GNUC_PATCHLEVEL__) +#endif // __GNUC__ + +// Determines the platform on which Google Test is compiled. +#ifdef __CYGWIN__ +#define GTEST_OS_CYGWIN 1 +#elif defined __SYMBIAN32__ +#define GTEST_OS_SYMBIAN 1 +#elif defined _WIN32 +#define GTEST_OS_WINDOWS 1 +#ifdef _WIN32_WCE +#define GTEST_OS_WINDOWS_MOBILE 1 +#elif defined(__MINGW__) || defined(__MINGW32__) +#define GTEST_OS_WINDOWS_MINGW 1 +#else +#define GTEST_OS_WINDOWS_DESKTOP 1 +#endif // _WIN32_WCE +#elif defined __APPLE__ +#define GTEST_OS_MAC 1 +#elif defined __linux__ +#define GTEST_OS_LINUX 1 +#elif defined __MVS__ +#define GTEST_OS_ZOS 1 +#elif defined(__sun) && defined(__SVR4) +#define GTEST_OS_SOLARIS 1 +#elif defined(_AIX) +#define GTEST_OS_AIX 1 +#endif // __CYGWIN__ + +#if GTEST_OS_CYGWIN || GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_SYMBIAN || \ + GTEST_OS_SOLARIS || GTEST_OS_AIX + +// On some platforms, <regex.h> needs someone to define size_t, and +// won't compile otherwise. We can #include it here as we already +// included <stdlib.h>, which is guaranteed to define size_t through +// <stddef.h>. +#include <regex.h> // NOLINT +#include <strings.h> // NOLINT +#include <sys/types.h> // NOLINT +#include <time.h> // NOLINT +#include <unistd.h> // NOLINT + +#define GTEST_USES_POSIX_RE 1 + +#elif GTEST_OS_WINDOWS + +#if !GTEST_OS_WINDOWS_MOBILE +#include <direct.h> // NOLINT +#include <io.h> // NOLINT +#endif + +// <regex.h> is not available on Windows. Use our own simple regex +// implementation instead. +#define GTEST_USES_SIMPLE_RE 1 + +#else + +// <regex.h> may not be available on this platform. Use our own +// simple regex implementation instead. +#define GTEST_USES_SIMPLE_RE 1 + +#endif // GTEST_OS_CYGWIN || GTEST_OS_LINUX || GTEST_OS_MAC || + // GTEST_OS_SYMBIAN || GTEST_OS_SOLARIS || GTEST_OS_AIX + +#ifndef GTEST_HAS_EXCEPTIONS +// The user didn't tell us whether exceptions are enabled, so we need +// to figure it out. +#if defined(_MSC_VER) || defined(__BORLANDC__) +// MSVC's and C++Builder's implementations of the STL use the _HAS_EXCEPTIONS +// macro to enable exceptions, so we'll do the same. +// Assumes that exceptions are enabled by default. +#ifndef _HAS_EXCEPTIONS +#define _HAS_EXCEPTIONS 1 +#endif // _HAS_EXCEPTIONS +#define GTEST_HAS_EXCEPTIONS _HAS_EXCEPTIONS +#elif defined(__GNUC__) && __EXCEPTIONS +// gcc defines __EXCEPTIONS to 1 iff exceptions are enabled. +#define GTEST_HAS_EXCEPTIONS 1 +#elif defined(__SUNPRO_CC) +// Sun Pro CC supports exceptions. However, there is no compile-time way of +// detecting whether they are enabled or not. Therefore, we assume that +// they are enabled unless the user tells us otherwise. +#define GTEST_HAS_EXCEPTIONS 1 +#elif defined(__IBMCPP__) && __EXCEPTIONS +// xlC defines __EXCEPTIONS to 1 iff exceptions are enabled. +#define GTEST_HAS_EXCEPTIONS 1 +#else +// For other compilers, we assume exceptions are disabled to be +// conservative. +#define GTEST_HAS_EXCEPTIONS 0 +#endif // defined(_MSC_VER) || defined(__BORLANDC__) +#endif // GTEST_HAS_EXCEPTIONS + +#if !defined(GTEST_HAS_STD_STRING) +// Even though we don't use this macro any longer, we keep it in case +// some clients still depend on it. +#define GTEST_HAS_STD_STRING 1 +#elif !GTEST_HAS_STD_STRING +// The user told us that ::std::string isn't available. +#error "Google Test cannot be used where ::std::string isn't available." +#endif // !defined(GTEST_HAS_STD_STRING) + +#ifndef GTEST_HAS_GLOBAL_STRING +// The user didn't tell us whether ::string is available, so we need +// to figure it out. + +#define GTEST_HAS_GLOBAL_STRING 0 + +#endif // GTEST_HAS_GLOBAL_STRING + +#ifndef GTEST_HAS_STD_WSTRING +// The user didn't tell us whether ::std::wstring is available, so we need +// to figure it out. +// TODO(wan@google.com): uses autoconf to detect whether ::std::wstring +// is available. + +// Cygwin 1.5 and below doesn't support ::std::wstring. +// Cygwin 1.7 might add wstring support; this should be updated when clear. +// Solaris' libc++ doesn't support it either. +#define GTEST_HAS_STD_WSTRING (!(GTEST_OS_CYGWIN || GTEST_OS_SOLARIS)) + +#endif // GTEST_HAS_STD_WSTRING + +#ifndef GTEST_HAS_GLOBAL_WSTRING +// The user didn't tell us whether ::wstring is available, so we need +// to figure it out. +#define GTEST_HAS_GLOBAL_WSTRING \ + (GTEST_HAS_STD_WSTRING && GTEST_HAS_GLOBAL_STRING) +#endif // GTEST_HAS_GLOBAL_WSTRING + +// Determines whether RTTI is available. +#ifndef GTEST_HAS_RTTI +// The user didn't tell us whether RTTI is enabled, so we need to +// figure it out. + +#ifdef _MSC_VER + +#ifdef _CPPRTTI // MSVC defines this macro iff RTTI is enabled. +#define GTEST_HAS_RTTI 1 +#else +#define GTEST_HAS_RTTI 0 +#endif + +// Starting with version 4.3.2, gcc defines __GXX_RTTI iff RTTI is enabled. +#elif defined(__GNUC__) && (GTEST_GCC_VER_ >= 40302) + +#ifdef __GXX_RTTI +#define GTEST_HAS_RTTI 1 +#else +#define GTEST_HAS_RTTI 0 +#endif // __GXX_RTTI + +// Starting with version 9.0 IBM Visual Age defines __RTTI_ALL__ to 1 if +// both the typeid and dynamic_cast features are present. +#elif defined(__IBMCPP__) && (__IBMCPP__ >= 900) + +#ifdef __RTTI_ALL__ +#define GTEST_HAS_RTTI 1 +#else +#define GTEST_HAS_RTTI 0 +#endif + +#else + +// For all other compilers, we assume RTTI is enabled. +#define GTEST_HAS_RTTI 1 + +#endif // _MSC_VER + +#endif // GTEST_HAS_RTTI + +// It's this header's responsibility to #include <typeinfo> when RTTI +// is enabled. +#if GTEST_HAS_RTTI +#include <typeinfo> +#endif + +// Determines whether Google Test can use the pthreads library. +#ifndef GTEST_HAS_PTHREAD +// The user didn't tell us explicitly, so we assume pthreads support is +// available on Linux and Mac. +// +// To disable threading support in Google Test, add -DGTEST_HAS_PTHREAD=0 +// to your compiler flags. +#define GTEST_HAS_PTHREAD (GTEST_OS_LINUX || GTEST_OS_MAC) +#endif // GTEST_HAS_PTHREAD + +// Determines whether Google Test can use tr1/tuple. You can define +// this macro to 0 to prevent Google Test from using tuple (any +// feature depending on tuple with be disabled in this mode). +#ifndef GTEST_HAS_TR1_TUPLE +// The user didn't tell us not to do it, so we assume it's OK. +#define GTEST_HAS_TR1_TUPLE 1 +#endif // GTEST_HAS_TR1_TUPLE + +// Determines whether Google Test's own tr1 tuple implementation +// should be used. +#ifndef GTEST_USE_OWN_TR1_TUPLE +// The user didn't tell us, so we need to figure it out. + +// We use our own TR1 tuple if we aren't sure the user has an +// implementation of it already. At this time, GCC 4.0.0+ and MSVC +// 2010 are the only mainstream compilers that come with a TR1 tuple +// implementation. NVIDIA's CUDA NVCC compiler pretends to be GCC by +// defining __GNUC__ and friends, but cannot compile GCC's tuple +// implementation. MSVC 2008 (9.0) provides TR1 tuple in a 323 MB +// Feature Pack download, which we cannot assume the user has. +#if (defined(__GNUC__) && !defined(__CUDACC__) && (GTEST_GCC_VER_ >= 40000)) \ + || _MSC_VER >= 1600 +#define GTEST_USE_OWN_TR1_TUPLE 0 +#else +#define GTEST_USE_OWN_TR1_TUPLE 1 +#endif + +#endif // GTEST_USE_OWN_TR1_TUPLE + +// To avoid conditional compilation everywhere, we make it +// gtest-port.h's responsibility to #include the header implementing +// tr1/tuple. +#if GTEST_HAS_TR1_TUPLE + +#if GTEST_USE_OWN_TR1_TUPLE +// This file was GENERATED by a script. DO NOT EDIT BY HAND!!! + +// Copyright 2009 Google Inc. +// All Rights Reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: wan@google.com (Zhanyong Wan) + +// Implements a subset of TR1 tuple needed by Google Test and Google Mock. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_ + +#include <utility> // For ::std::pair. + +// The compiler used in Symbian has a bug that prevents us from declaring the +// tuple template as a friend (it complains that tuple is redefined). This +// hack bypasses the bug by declaring the members that should otherwise be +// private as public. +// Sun Studio versions < 12 also have the above bug. +#if defined(__SYMBIAN32__) || (defined(__SUNPRO_CC) && __SUNPRO_CC < 0x590) +#define GTEST_DECLARE_TUPLE_AS_FRIEND_ public: +#else +#define GTEST_DECLARE_TUPLE_AS_FRIEND_ \ + template <GTEST_10_TYPENAMES_(U)> friend class tuple; \ + private: +#endif + +// GTEST_n_TUPLE_(T) is the type of an n-tuple. +#define GTEST_0_TUPLE_(T) tuple<> +#define GTEST_1_TUPLE_(T) tuple<T##0, void, void, void, void, void, void, \ + void, void, void> +#define GTEST_2_TUPLE_(T) tuple<T##0, T##1, void, void, void, void, void, \ + void, void, void> +#define GTEST_3_TUPLE_(T) tuple<T##0, T##1, T##2, void, void, void, void, \ + void, void, void> +#define GTEST_4_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, void, void, void, \ + void, void, void> +#define GTEST_5_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, void, void, \ + void, void, void> +#define GTEST_6_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, void, \ + void, void, void> +#define GTEST_7_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, T##6, \ + void, void, void> +#define GTEST_8_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, T##6, \ + T##7, void, void> +#define GTEST_9_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, T##6, \ + T##7, T##8, void> +#define GTEST_10_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, T##6, \ + T##7, T##8, T##9> + +// GTEST_n_TYPENAMES_(T) declares a list of n typenames. +#define GTEST_0_TYPENAMES_(T) +#define GTEST_1_TYPENAMES_(T) typename T##0 +#define GTEST_2_TYPENAMES_(T) typename T##0, typename T##1 +#define GTEST_3_TYPENAMES_(T) typename T##0, typename T##1, typename T##2 +#define GTEST_4_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ + typename T##3 +#define GTEST_5_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ + typename T##3, typename T##4 +#define GTEST_6_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ + typename T##3, typename T##4, typename T##5 +#define GTEST_7_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ + typename T##3, typename T##4, typename T##5, typename T##6 +#define GTEST_8_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ + typename T##3, typename T##4, typename T##5, typename T##6, typename T##7 +#define GTEST_9_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ + typename T##3, typename T##4, typename T##5, typename T##6, \ + typename T##7, typename T##8 +#define GTEST_10_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ + typename T##3, typename T##4, typename T##5, typename T##6, \ + typename T##7, typename T##8, typename T##9 + +// In theory, defining stuff in the ::std namespace is undefined +// behavior. We can do this as we are playing the role of a standard +// library vendor. +namespace std { +namespace tr1 { + +template <typename T0 = void, typename T1 = void, typename T2 = void, + typename T3 = void, typename T4 = void, typename T5 = void, + typename T6 = void, typename T7 = void, typename T8 = void, + typename T9 = void> +class tuple; + +// Anything in namespace gtest_internal is Google Test's INTERNAL +// IMPLEMENTATION DETAIL and MUST NOT BE USED DIRECTLY in user code. +namespace gtest_internal { + +// ByRef<T>::type is T if T is a reference; otherwise it's const T&. +template <typename T> +struct ByRef { typedef const T& type; }; // NOLINT +template <typename T> +struct ByRef<T&> { typedef T& type; }; // NOLINT + +// A handy wrapper for ByRef. +#define GTEST_BY_REF_(T) typename ::std::tr1::gtest_internal::ByRef<T>::type + +// AddRef<T>::type is T if T is a reference; otherwise it's T&. This +// is the same as tr1::add_reference<T>::type. +template <typename T> +struct AddRef { typedef T& type; }; // NOLINT +template <typename T> +struct AddRef<T&> { typedef T& type; }; // NOLINT + +// A handy wrapper for AddRef. +#define GTEST_ADD_REF_(T) typename ::std::tr1::gtest_internal::AddRef<T>::type + +// A helper for implementing get<k>(). +template <int k> class Get; + +// A helper for implementing tuple_element<k, T>. kIndexValid is true +// iff k < the number of fields in tuple type T. +template <bool kIndexValid, int kIndex, class Tuple> +struct TupleElement; + +template <GTEST_10_TYPENAMES_(T)> +struct TupleElement<true, 0, GTEST_10_TUPLE_(T)> { typedef T0 type; }; + +template <GTEST_10_TYPENAMES_(T)> +struct TupleElement<true, 1, GTEST_10_TUPLE_(T)> { typedef T1 type; }; + +template <GTEST_10_TYPENAMES_(T)> +struct TupleElement<true, 2, GTEST_10_TUPLE_(T)> { typedef T2 type; }; + +template <GTEST_10_TYPENAMES_(T)> +struct TupleElement<true, 3, GTEST_10_TUPLE_(T)> { typedef T3 type; }; + +template <GTEST_10_TYPENAMES_(T)> +struct TupleElement<true, 4, GTEST_10_TUPLE_(T)> { typedef T4 type; }; + +template <GTEST_10_TYPENAMES_(T)> +struct TupleElement<true, 5, GTEST_10_TUPLE_(T)> { typedef T5 type; }; + +template <GTEST_10_TYPENAMES_(T)> +struct TupleElement<true, 6, GTEST_10_TUPLE_(T)> { typedef T6 type; }; + +template <GTEST_10_TYPENAMES_(T)> +struct TupleElement<true, 7, GTEST_10_TUPLE_(T)> { typedef T7 type; }; + +template <GTEST_10_TYPENAMES_(T)> +struct TupleElement<true, 8, GTEST_10_TUPLE_(T)> { typedef T8 type; }; + +template <GTEST_10_TYPENAMES_(T)> +struct TupleElement<true, 9, GTEST_10_TUPLE_(T)> { typedef T9 type; }; + +} // namespace gtest_internal + +template <> +class tuple<> { + public: + tuple() {} + tuple(const tuple& /* t */) {} + tuple& operator=(const tuple& /* t */) { return *this; } +}; + +template <GTEST_1_TYPENAMES_(T)> +class GTEST_1_TUPLE_(T) { + public: + template <int k> friend class gtest_internal::Get; + + tuple() : f0_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0) : f0_(f0) {} + + tuple(const tuple& t) : f0_(t.f0_) {} + + template <GTEST_1_TYPENAMES_(U)> + tuple(const GTEST_1_TUPLE_(U)& t) : f0_(t.f0_) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template <GTEST_1_TYPENAMES_(U)> + tuple& operator=(const GTEST_1_TUPLE_(U)& t) { + return CopyFrom(t); + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template <GTEST_1_TYPENAMES_(U)> + tuple& CopyFrom(const GTEST_1_TUPLE_(U)& t) { + f0_ = t.f0_; + return *this; + } + + T0 f0_; +}; + +template <GTEST_2_TYPENAMES_(T)> +class GTEST_2_TUPLE_(T) { + public: + template <int k> friend class gtest_internal::Get; + + tuple() : f0_(), f1_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1) : f0_(f0), + f1_(f1) {} + + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_) {} + + template <GTEST_2_TYPENAMES_(U)> + tuple(const GTEST_2_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_) {} + template <typename U0, typename U1> + tuple(const ::std::pair<U0, U1>& p) : f0_(p.first), f1_(p.second) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template <GTEST_2_TYPENAMES_(U)> + tuple& operator=(const GTEST_2_TUPLE_(U)& t) { + return CopyFrom(t); + } + template <typename U0, typename U1> + tuple& operator=(const ::std::pair<U0, U1>& p) { + f0_ = p.first; + f1_ = p.second; + return *this; + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template <GTEST_2_TYPENAMES_(U)> + tuple& CopyFrom(const GTEST_2_TUPLE_(U)& t) { + f0_ = t.f0_; + f1_ = t.f1_; + return *this; + } + + T0 f0_; + T1 f1_; +}; + +template <GTEST_3_TYPENAMES_(T)> +class GTEST_3_TUPLE_(T) { + public: + template <int k> friend class gtest_internal::Get; + + tuple() : f0_(), f1_(), f2_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, + GTEST_BY_REF_(T2) f2) : f0_(f0), f1_(f1), f2_(f2) {} + + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_) {} + + template <GTEST_3_TYPENAMES_(U)> + tuple(const GTEST_3_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template <GTEST_3_TYPENAMES_(U)> + tuple& operator=(const GTEST_3_TUPLE_(U)& t) { + return CopyFrom(t); + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template <GTEST_3_TYPENAMES_(U)> + tuple& CopyFrom(const GTEST_3_TUPLE_(U)& t) { + f0_ = t.f0_; + f1_ = t.f1_; + f2_ = t.f2_; + return *this; + } + + T0 f0_; + T1 f1_; + T2 f2_; +}; + +template <GTEST_4_TYPENAMES_(T)> +class GTEST_4_TUPLE_(T) { + public: + template <int k> friend class gtest_internal::Get; + + tuple() : f0_(), f1_(), f2_(), f3_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, + GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3) : f0_(f0), f1_(f1), f2_(f2), + f3_(f3) {} + + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_) {} + + template <GTEST_4_TYPENAMES_(U)> + tuple(const GTEST_4_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), + f3_(t.f3_) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template <GTEST_4_TYPENAMES_(U)> + tuple& operator=(const GTEST_4_TUPLE_(U)& t) { + return CopyFrom(t); + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template <GTEST_4_TYPENAMES_(U)> + tuple& CopyFrom(const GTEST_4_TUPLE_(U)& t) { + f0_ = t.f0_; + f1_ = t.f1_; + f2_ = t.f2_; + f3_ = t.f3_; + return *this; + } + + T0 f0_; + T1 f1_; + T2 f2_; + T3 f3_; +}; + +template <GTEST_5_TYPENAMES_(T)> +class GTEST_5_TUPLE_(T) { + public: + template <int k> friend class gtest_internal::Get; + + tuple() : f0_(), f1_(), f2_(), f3_(), f4_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, + GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, + GTEST_BY_REF_(T4) f4) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4) {} + + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), + f4_(t.f4_) {} + + template <GTEST_5_TYPENAMES_(U)> + tuple(const GTEST_5_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), + f3_(t.f3_), f4_(t.f4_) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template <GTEST_5_TYPENAMES_(U)> + tuple& operator=(const GTEST_5_TUPLE_(U)& t) { + return CopyFrom(t); + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template <GTEST_5_TYPENAMES_(U)> + tuple& CopyFrom(const GTEST_5_TUPLE_(U)& t) { + f0_ = t.f0_; + f1_ = t.f1_; + f2_ = t.f2_; + f3_ = t.f3_; + f4_ = t.f4_; + return *this; + } + + T0 f0_; + T1 f1_; + T2 f2_; + T3 f3_; + T4 f4_; +}; + +template <GTEST_6_TYPENAMES_(T)> +class GTEST_6_TUPLE_(T) { + public: + template <int k> friend class gtest_internal::Get; + + tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, + GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4, + GTEST_BY_REF_(T5) f5) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4), + f5_(f5) {} + + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), + f4_(t.f4_), f5_(t.f5_) {} + + template <GTEST_6_TYPENAMES_(U)> + tuple(const GTEST_6_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), + f3_(t.f3_), f4_(t.f4_), f5_(t.f5_) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template <GTEST_6_TYPENAMES_(U)> + tuple& operator=(const GTEST_6_TUPLE_(U)& t) { + return CopyFrom(t); + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template <GTEST_6_TYPENAMES_(U)> + tuple& CopyFrom(const GTEST_6_TUPLE_(U)& t) { + f0_ = t.f0_; + f1_ = t.f1_; + f2_ = t.f2_; + f3_ = t.f3_; + f4_ = t.f4_; + f5_ = t.f5_; + return *this; + } + + T0 f0_; + T1 f1_; + T2 f2_; + T3 f3_; + T4 f4_; + T5 f5_; +}; + +template <GTEST_7_TYPENAMES_(T)> +class GTEST_7_TUPLE_(T) { + public: + template <int k> friend class gtest_internal::Get; + + tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, + GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4, + GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6) : f0_(f0), f1_(f1), f2_(f2), + f3_(f3), f4_(f4), f5_(f5), f6_(f6) {} + + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), + f4_(t.f4_), f5_(t.f5_), f6_(t.f6_) {} + + template <GTEST_7_TYPENAMES_(U)> + tuple(const GTEST_7_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), + f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template <GTEST_7_TYPENAMES_(U)> + tuple& operator=(const GTEST_7_TUPLE_(U)& t) { + return CopyFrom(t); + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template <GTEST_7_TYPENAMES_(U)> + tuple& CopyFrom(const GTEST_7_TUPLE_(U)& t) { + f0_ = t.f0_; + f1_ = t.f1_; + f2_ = t.f2_; + f3_ = t.f3_; + f4_ = t.f4_; + f5_ = t.f5_; + f6_ = t.f6_; + return *this; + } + + T0 f0_; + T1 f1_; + T2 f2_; + T3 f3_; + T4 f4_; + T5 f5_; + T6 f6_; +}; + +template <GTEST_8_TYPENAMES_(T)> +class GTEST_8_TUPLE_(T) { + public: + template <int k> friend class gtest_internal::Get; + + tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_(), f7_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, + GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4, + GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6, + GTEST_BY_REF_(T7) f7) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4), + f5_(f5), f6_(f6), f7_(f7) {} + + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), + f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_) {} + + template <GTEST_8_TYPENAMES_(U)> + tuple(const GTEST_8_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), + f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template <GTEST_8_TYPENAMES_(U)> + tuple& operator=(const GTEST_8_TUPLE_(U)& t) { + return CopyFrom(t); + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template <GTEST_8_TYPENAMES_(U)> + tuple& CopyFrom(const GTEST_8_TUPLE_(U)& t) { + f0_ = t.f0_; + f1_ = t.f1_; + f2_ = t.f2_; + f3_ = t.f3_; + f4_ = t.f4_; + f5_ = t.f5_; + f6_ = t.f6_; + f7_ = t.f7_; + return *this; + } + + T0 f0_; + T1 f1_; + T2 f2_; + T3 f3_; + T4 f4_; + T5 f5_; + T6 f6_; + T7 f7_; +}; + +template <GTEST_9_TYPENAMES_(T)> +class GTEST_9_TUPLE_(T) { + public: + template <int k> friend class gtest_internal::Get; + + tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_(), f7_(), f8_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, + GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4, + GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6, GTEST_BY_REF_(T7) f7, + GTEST_BY_REF_(T8) f8) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4), + f5_(f5), f6_(f6), f7_(f7), f8_(f8) {} + + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), + f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_) {} + + template <GTEST_9_TYPENAMES_(U)> + tuple(const GTEST_9_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), + f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template <GTEST_9_TYPENAMES_(U)> + tuple& operator=(const GTEST_9_TUPLE_(U)& t) { + return CopyFrom(t); + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template <GTEST_9_TYPENAMES_(U)> + tuple& CopyFrom(const GTEST_9_TUPLE_(U)& t) { + f0_ = t.f0_; + f1_ = t.f1_; + f2_ = t.f2_; + f3_ = t.f3_; + f4_ = t.f4_; + f5_ = t.f5_; + f6_ = t.f6_; + f7_ = t.f7_; + f8_ = t.f8_; + return *this; + } + + T0 f0_; + T1 f1_; + T2 f2_; + T3 f3_; + T4 f4_; + T5 f5_; + T6 f6_; + T7 f7_; + T8 f8_; +}; + +template <GTEST_10_TYPENAMES_(T)> +class tuple { + public: + template <int k> friend class gtest_internal::Get; + + tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_(), f7_(), f8_(), + f9_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, + GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4, + GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6, GTEST_BY_REF_(T7) f7, + GTEST_BY_REF_(T8) f8, GTEST_BY_REF_(T9) f9) : f0_(f0), f1_(f1), f2_(f2), + f3_(f3), f4_(f4), f5_(f5), f6_(f6), f7_(f7), f8_(f8), f9_(f9) {} + + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), + f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_), f9_(t.f9_) {} + + template <GTEST_10_TYPENAMES_(U)> + tuple(const GTEST_10_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), + f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_), + f9_(t.f9_) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template <GTEST_10_TYPENAMES_(U)> + tuple& operator=(const GTEST_10_TUPLE_(U)& t) { + return CopyFrom(t); + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template <GTEST_10_TYPENAMES_(U)> + tuple& CopyFrom(const GTEST_10_TUPLE_(U)& t) { + f0_ = t.f0_; + f1_ = t.f1_; + f2_ = t.f2_; + f3_ = t.f3_; + f4_ = t.f4_; + f5_ = t.f5_; + f6_ = t.f6_; + f7_ = t.f7_; + f8_ = t.f8_; + f9_ = t.f9_; + return *this; + } + + T0 f0_; + T1 f1_; + T2 f2_; + T3 f3_; + T4 f4_; + T5 f5_; + T6 f6_; + T7 f7_; + T8 f8_; + T9 f9_; +}; + +// 6.1.3.2 Tuple creation functions. + +// Known limitations: we don't support passing an +// std::tr1::reference_wrapper<T> to make_tuple(). And we don't +// implement tie(). + +inline tuple<> make_tuple() { return tuple<>(); } + +template <GTEST_1_TYPENAMES_(T)> +inline GTEST_1_TUPLE_(T) make_tuple(const T0& f0) { + return GTEST_1_TUPLE_(T)(f0); +} + +template <GTEST_2_TYPENAMES_(T)> +inline GTEST_2_TUPLE_(T) make_tuple(const T0& f0, const T1& f1) { + return GTEST_2_TUPLE_(T)(f0, f1); +} + +template <GTEST_3_TYPENAMES_(T)> +inline GTEST_3_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2) { + return GTEST_3_TUPLE_(T)(f0, f1, f2); +} + +template <GTEST_4_TYPENAMES_(T)> +inline GTEST_4_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, + const T3& f3) { + return GTEST_4_TUPLE_(T)(f0, f1, f2, f3); +} + +template <GTEST_5_TYPENAMES_(T)> +inline GTEST_5_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, + const T3& f3, const T4& f4) { + return GTEST_5_TUPLE_(T)(f0, f1, f2, f3, f4); +} + +template <GTEST_6_TYPENAMES_(T)> +inline GTEST_6_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, + const T3& f3, const T4& f4, const T5& f5) { + return GTEST_6_TUPLE_(T)(f0, f1, f2, f3, f4, f5); +} + +template <GTEST_7_TYPENAMES_(T)> +inline GTEST_7_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, + const T3& f3, const T4& f4, const T5& f5, const T6& f6) { + return GTEST_7_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6); +} + +template <GTEST_8_TYPENAMES_(T)> +inline GTEST_8_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, + const T3& f3, const T4& f4, const T5& f5, const T6& f6, const T7& f7) { + return GTEST_8_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6, f7); +} + +template <GTEST_9_TYPENAMES_(T)> +inline GTEST_9_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, + const T3& f3, const T4& f4, const T5& f5, const T6& f6, const T7& f7, + const T8& f8) { + return GTEST_9_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6, f7, f8); +} + +template <GTEST_10_TYPENAMES_(T)> +inline GTEST_10_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, + const T3& f3, const T4& f4, const T5& f5, const T6& f6, const T7& f7, + const T8& f8, const T9& f9) { + return GTEST_10_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6, f7, f8, f9); +} + +// 6.1.3.3 Tuple helper classes. + +template <typename Tuple> struct tuple_size; + +template <GTEST_0_TYPENAMES_(T)> +struct tuple_size<GTEST_0_TUPLE_(T)> { static const int value = 0; }; + +template <GTEST_1_TYPENAMES_(T)> +struct tuple_size<GTEST_1_TUPLE_(T)> { static const int value = 1; }; + +template <GTEST_2_TYPENAMES_(T)> +struct tuple_size<GTEST_2_TUPLE_(T)> { static const int value = 2; }; + +template <GTEST_3_TYPENAMES_(T)> +struct tuple_size<GTEST_3_TUPLE_(T)> { static const int value = 3; }; + +template <GTEST_4_TYPENAMES_(T)> +struct tuple_size<GTEST_4_TUPLE_(T)> { static const int value = 4; }; + +template <GTEST_5_TYPENAMES_(T)> +struct tuple_size<GTEST_5_TUPLE_(T)> { static const int value = 5; }; + +template <GTEST_6_TYPENAMES_(T)> +struct tuple_size<GTEST_6_TUPLE_(T)> { static const int value = 6; }; + +template <GTEST_7_TYPENAMES_(T)> +struct tuple_size<GTEST_7_TUPLE_(T)> { static const int value = 7; }; + +template <GTEST_8_TYPENAMES_(T)> +struct tuple_size<GTEST_8_TUPLE_(T)> { static const int value = 8; }; + +template <GTEST_9_TYPENAMES_(T)> +struct tuple_size<GTEST_9_TUPLE_(T)> { static const int value = 9; }; + +template <GTEST_10_TYPENAMES_(T)> +struct tuple_size<GTEST_10_TUPLE_(T)> { static const int value = 10; }; + +template <int k, class Tuple> +struct tuple_element { + typedef typename gtest_internal::TupleElement< + k < (tuple_size<Tuple>::value), k, Tuple>::type type; +}; + +#define GTEST_TUPLE_ELEMENT_(k, Tuple) typename tuple_element<k, Tuple >::type + +// 6.1.3.4 Element access. + +namespace gtest_internal { + +template <> +class Get<0> { + public: + template <class Tuple> + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(0, Tuple)) + Field(Tuple& t) { return t.f0_; } // NOLINT + + template <class Tuple> + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(0, Tuple)) + ConstField(const Tuple& t) { return t.f0_; } +}; + +template <> +class Get<1> { + public: + template <class Tuple> + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(1, Tuple)) + Field(Tuple& t) { return t.f1_; } // NOLINT + + template <class Tuple> + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(1, Tuple)) + ConstField(const Tuple& t) { return t.f1_; } +}; + +template <> +class Get<2> { + public: + template <class Tuple> + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(2, Tuple)) + Field(Tuple& t) { return t.f2_; } // NOLINT + + template <class Tuple> + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(2, Tuple)) + ConstField(const Tuple& t) { return t.f2_; } +}; + +template <> +class Get<3> { + public: + template <class Tuple> + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(3, Tuple)) + Field(Tuple& t) { return t.f3_; } // NOLINT + + template <class Tuple> + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(3, Tuple)) + ConstField(const Tuple& t) { return t.f3_; } +}; + +template <> +class Get<4> { + public: + template <class Tuple> + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(4, Tuple)) + Field(Tuple& t) { return t.f4_; } // NOLINT + + template <class Tuple> + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(4, Tuple)) + ConstField(const Tuple& t) { return t.f4_; } +}; + +template <> +class Get<5> { + public: + template <class Tuple> + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(5, Tuple)) + Field(Tuple& t) { return t.f5_; } // NOLINT + + template <class Tuple> + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(5, Tuple)) + ConstField(const Tuple& t) { return t.f5_; } +}; + +template <> +class Get<6> { + public: + template <class Tuple> + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(6, Tuple)) + Field(Tuple& t) { return t.f6_; } // NOLINT + + template <class Tuple> + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(6, Tuple)) + ConstField(const Tuple& t) { return t.f6_; } +}; + +template <> +class Get<7> { + public: + template <class Tuple> + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(7, Tuple)) + Field(Tuple& t) { return t.f7_; } // NOLINT + + template <class Tuple> + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(7, Tuple)) + ConstField(const Tuple& t) { return t.f7_; } +}; + +template <> +class Get<8> { + public: + template <class Tuple> + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(8, Tuple)) + Field(Tuple& t) { return t.f8_; } // NOLINT + + template <class Tuple> + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(8, Tuple)) + ConstField(const Tuple& t) { return t.f8_; } +}; + +template <> +class Get<9> { + public: + template <class Tuple> + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(9, Tuple)) + Field(Tuple& t) { return t.f9_; } // NOLINT + + template <class Tuple> + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(9, Tuple)) + ConstField(const Tuple& t) { return t.f9_; } +}; + +} // namespace gtest_internal + +template <int k, GTEST_10_TYPENAMES_(T)> +GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_10_TUPLE_(T))) +get(GTEST_10_TUPLE_(T)& t) { + return gtest_internal::Get<k>::Field(t); +} + +template <int k, GTEST_10_TYPENAMES_(T)> +GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_10_TUPLE_(T))) +get(const GTEST_10_TUPLE_(T)& t) { + return gtest_internal::Get<k>::ConstField(t); +} + +// 6.1.3.5 Relational operators + +// We only implement == and !=, as we don't have a need for the rest yet. + +namespace gtest_internal { + +// SameSizeTuplePrefixComparator<k, k>::Eq(t1, t2) returns true if the +// first k fields of t1 equals the first k fields of t2. +// SameSizeTuplePrefixComparator(k1, k2) would be a compiler error if +// k1 != k2. +template <int kSize1, int kSize2> +struct SameSizeTuplePrefixComparator; + +template <> +struct SameSizeTuplePrefixComparator<0, 0> { + template <class Tuple1, class Tuple2> + static bool Eq(const Tuple1& /* t1 */, const Tuple2& /* t2 */) { + return true; + } +}; + +template <int k> +struct SameSizeTuplePrefixComparator<k, k> { + template <class Tuple1, class Tuple2> + static bool Eq(const Tuple1& t1, const Tuple2& t2) { + return SameSizeTuplePrefixComparator<k - 1, k - 1>::Eq(t1, t2) && + ::std::tr1::get<k - 1>(t1) == ::std::tr1::get<k - 1>(t2); + } +}; + +} // namespace gtest_internal + +template <GTEST_10_TYPENAMES_(T), GTEST_10_TYPENAMES_(U)> +inline bool operator==(const GTEST_10_TUPLE_(T)& t, + const GTEST_10_TUPLE_(U)& u) { + return gtest_internal::SameSizeTuplePrefixComparator< + tuple_size<GTEST_10_TUPLE_(T)>::value, + tuple_size<GTEST_10_TUPLE_(U)>::value>::Eq(t, u); +} + +template <GTEST_10_TYPENAMES_(T), GTEST_10_TYPENAMES_(U)> +inline bool operator!=(const GTEST_10_TUPLE_(T)& t, + const GTEST_10_TUPLE_(U)& u) { return !(t == u); } + +// 6.1.4 Pairs. +// Unimplemented. + +} // namespace tr1 +} // namespace std + +#undef GTEST_0_TUPLE_ +#undef GTEST_1_TUPLE_ +#undef GTEST_2_TUPLE_ +#undef GTEST_3_TUPLE_ +#undef GTEST_4_TUPLE_ +#undef GTEST_5_TUPLE_ +#undef GTEST_6_TUPLE_ +#undef GTEST_7_TUPLE_ +#undef GTEST_8_TUPLE_ +#undef GTEST_9_TUPLE_ +#undef GTEST_10_TUPLE_ + +#undef GTEST_0_TYPENAMES_ +#undef GTEST_1_TYPENAMES_ +#undef GTEST_2_TYPENAMES_ +#undef GTEST_3_TYPENAMES_ +#undef GTEST_4_TYPENAMES_ +#undef GTEST_5_TYPENAMES_ +#undef GTEST_6_TYPENAMES_ +#undef GTEST_7_TYPENAMES_ +#undef GTEST_8_TYPENAMES_ +#undef GTEST_9_TYPENAMES_ +#undef GTEST_10_TYPENAMES_ + +#undef GTEST_DECLARE_TUPLE_AS_FRIEND_ +#undef GTEST_BY_REF_ +#undef GTEST_ADD_REF_ +#undef GTEST_TUPLE_ELEMENT_ + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_ +#elif GTEST_OS_SYMBIAN + +// On Symbian, BOOST_HAS_TR1_TUPLE causes Boost's TR1 tuple library to +// use STLport's tuple implementation, which unfortunately doesn't +// work as the copy of STLport distributed with Symbian is incomplete. +// By making sure BOOST_HAS_TR1_TUPLE is undefined, we force Boost to +// use its own tuple implementation. +#ifdef BOOST_HAS_TR1_TUPLE +#undef BOOST_HAS_TR1_TUPLE +#endif // BOOST_HAS_TR1_TUPLE + +// This prevents <boost/tr1/detail/config.hpp>, which defines +// BOOST_HAS_TR1_TUPLE, from being #included by Boost's <tuple>. +#define BOOST_TR1_DETAIL_CONFIG_HPP_INCLUDED +#include <tuple> + +#elif defined(__GNUC__) && (GTEST_GCC_VER_ >= 40000) +// GCC 4.0+ implements tr1/tuple in the <tr1/tuple> header. This does +// not conform to the TR1 spec, which requires the header to be <tuple>. + +#if !GTEST_HAS_RTTI && GTEST_GCC_VER_ < 40302 +// Until version 4.3.2, gcc has a bug that causes <tr1/functional>, +// which is #included by <tr1/tuple>, to not compile when RTTI is +// disabled. _TR1_FUNCTIONAL is the header guard for +// <tr1/functional>. Hence the following #define is a hack to prevent +// <tr1/functional> from being included. +#define _TR1_FUNCTIONAL 1 +#include <tr1/tuple> +#undef _TR1_FUNCTIONAL // Allows the user to #include + // <tr1/functional> if he chooses to. +#else +#include <tr1/tuple> // NOLINT +#endif // !GTEST_HAS_RTTI && GTEST_GCC_VER_ < 40302 + +#else +// If the compiler is not GCC 4.0+, we assume the user is using a +// spec-conforming TR1 implementation. +#include <tuple> // NOLINT +#endif // GTEST_USE_OWN_TR1_TUPLE + +#endif // GTEST_HAS_TR1_TUPLE + +// Determines whether clone(2) is supported. +// Usually it will only be available on Linux, excluding +// Linux on the Itanium architecture. +// Also see http://linux.die.net/man/2/clone. +#ifndef GTEST_HAS_CLONE +// The user didn't tell us, so we need to figure it out. + +#if GTEST_OS_LINUX && !defined(__ia64__) +#define GTEST_HAS_CLONE 1 +#else +#define GTEST_HAS_CLONE 0 +#endif // GTEST_OS_LINUX && !defined(__ia64__) + +#endif // GTEST_HAS_CLONE + +// Determines whether to support stream redirection. This is used to test +// output correctness and to implement death tests. +#if !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_SYMBIAN +#define GTEST_HAS_STREAM_REDIRECTION_ 1 +#endif // !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_SYMBIAN + +// Determines whether to support death tests. +// Google Test does not support death tests for VC 7.1 and earlier as +// abort() in a VC 7.1 application compiled as GUI in debug config +// pops up a dialog window that cannot be suppressed programmatically. +#if (GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_CYGWIN || GTEST_OS_SOLARIS || \ + (GTEST_OS_WINDOWS_DESKTOP && _MSC_VER >= 1400) || \ + GTEST_OS_WINDOWS_MINGW || GTEST_OS_AIX) +#define GTEST_HAS_DEATH_TEST 1 +#include <vector> // NOLINT +#endif + +// We don't support MSVC 7.1 with exceptions disabled now. Therefore +// all the compilers we care about are adequate for supporting +// value-parameterized tests. +#define GTEST_HAS_PARAM_TEST 1 + +// Determines whether to support type-driven tests. + +// Typed tests need <typeinfo> and variadic macros, which GCC, VC++ 8.0, +// Sun Pro CC, and IBM Visual Age support. +#if defined(__GNUC__) || (_MSC_VER >= 1400) || defined(__SUNPRO_CC) || \ + defined(__IBMCPP__) +#define GTEST_HAS_TYPED_TEST 1 +#define GTEST_HAS_TYPED_TEST_P 1 +#endif + +// Determines whether to support Combine(). This only makes sense when +// value-parameterized tests are enabled. The implementation doesn't +// work on Sun Studio since it doesn't understand templated conversion +// operators. +#if GTEST_HAS_PARAM_TEST && GTEST_HAS_TR1_TUPLE && !defined(__SUNPRO_CC) +#define GTEST_HAS_COMBINE 1 +#endif + +// Determines whether the system compiler uses UTF-16 for encoding wide strings. +#define GTEST_WIDE_STRING_USES_UTF16_ \ + (GTEST_OS_WINDOWS || GTEST_OS_CYGWIN || GTEST_OS_SYMBIAN || GTEST_OS_AIX) + +// Defines some utility macros. + +// The GNU compiler emits a warning if nested "if" statements are followed by +// an "else" statement and braces are not used to explicitly disambiguate the +// "else" binding. This leads to problems with code like: +// +// if (gate) +// ASSERT_*(condition) << "Some message"; +// +// The "switch (0) case 0:" idiom is used to suppress this. +#ifdef __INTEL_COMPILER +#define GTEST_AMBIGUOUS_ELSE_BLOCKER_ +#else +#define GTEST_AMBIGUOUS_ELSE_BLOCKER_ switch (0) case 0: // NOLINT +#endif + +// Use this annotation at the end of a struct/class definition to +// prevent the compiler from optimizing away instances that are never +// used. This is useful when all interesting logic happens inside the +// c'tor and / or d'tor. Example: +// +// struct Foo { +// Foo() { ... } +// } GTEST_ATTRIBUTE_UNUSED_; +// +// Also use it after a variable or parameter declaration to tell the +// compiler the variable/parameter does not have to be used. +#if defined(__GNUC__) && !defined(COMPILER_ICC) +#define GTEST_ATTRIBUTE_UNUSED_ __attribute__ ((unused)) +#else +#define GTEST_ATTRIBUTE_UNUSED_ +#endif + +// A macro to disallow operator= +// This should be used in the private: declarations for a class. +#define GTEST_DISALLOW_ASSIGN_(type)\ + void operator=(type const &) + +// A macro to disallow copy constructor and operator= +// This should be used in the private: declarations for a class. +#define GTEST_DISALLOW_COPY_AND_ASSIGN_(type)\ + type(type const &);\ + GTEST_DISALLOW_ASSIGN_(type) + +// Tell the compiler to warn about unused return values for functions declared +// with this macro. The macro should be used on function declarations +// following the argument list: +// +// Sprocket* AllocateSprocket() GTEST_MUST_USE_RESULT_; +#if defined(__GNUC__) && (GTEST_GCC_VER_ >= 30400) && !defined(COMPILER_ICC) +#define GTEST_MUST_USE_RESULT_ __attribute__ ((warn_unused_result)) +#else +#define GTEST_MUST_USE_RESULT_ +#endif // __GNUC__ && (GTEST_GCC_VER_ >= 30400) && !COMPILER_ICC + +// Determine whether the compiler supports Microsoft's Structured Exception +// Handling. This is supported by several Windows compilers but generally +// does not exist on any other system. +#ifndef GTEST_HAS_SEH +// The user didn't tell us, so we need to figure it out. + +#if defined(_MSC_VER) || defined(__BORLANDC__) +// These two compilers are known to support SEH. +#define GTEST_HAS_SEH 1 +#else +// Assume no SEH. +#define GTEST_HAS_SEH 0 +#endif + +#endif // GTEST_HAS_SEH + +#ifdef _MSC_VER + +#if GTEST_LINKED_AS_SHARED_LIBRARY +#define GTEST_API_ __declspec(dllimport) +#elif GTEST_CREATE_SHARED_LIBRARY +#define GTEST_API_ __declspec(dllexport) +#endif + +#endif // _MSC_VER + +#ifndef GTEST_API_ +#define GTEST_API_ +#endif + +namespace testing { + +class Message; + +namespace internal { + +class String; + +typedef ::std::stringstream StrStream; + +// A helper for suppressing warnings on constant condition. It just +// returns 'condition'. +GTEST_API_ bool IsTrue(bool condition); + +// Defines scoped_ptr. + +// This implementation of scoped_ptr is PARTIAL - it only contains +// enough stuff to satisfy Google Test's need. +template <typename T> +class scoped_ptr { + public: + typedef T element_type; + + explicit scoped_ptr(T* p = NULL) : ptr_(p) {} + ~scoped_ptr() { reset(); } + + T& operator*() const { return *ptr_; } + T* operator->() const { return ptr_; } + T* get() const { return ptr_; } + + T* release() { + T* const ptr = ptr_; + ptr_ = NULL; + return ptr; + } + + void reset(T* p = NULL) { + if (p != ptr_) { + if (IsTrue(sizeof(T) > 0)) { // Makes sure T is a complete type. + delete ptr_; + } + ptr_ = p; + } + } + private: + T* ptr_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(scoped_ptr); +}; + +// Defines RE. + +// A simple C++ wrapper for <regex.h>. It uses the POSIX Extended +// Regular Expression syntax. +class GTEST_API_ RE { + public: + // A copy constructor is required by the Standard to initialize object + // references from r-values. + RE(const RE& other) { Init(other.pattern()); } + + // Constructs an RE from a string. + RE(const ::std::string& regex) { Init(regex.c_str()); } // NOLINT + +#if GTEST_HAS_GLOBAL_STRING + RE(const ::string& regex) { Init(regex.c_str()); } // NOLINT +#endif // GTEST_HAS_GLOBAL_STRING + + RE(const char* regex) { Init(regex); } // NOLINT + ~RE(); + + // Returns the string representation of the regex. + const char* pattern() const { return pattern_; } + + // FullMatch(str, re) returns true iff regular expression re matches + // the entire str. + // PartialMatch(str, re) returns true iff regular expression re + // matches a substring of str (including str itself). + // + // TODO(wan@google.com): make FullMatch() and PartialMatch() work + // when str contains NUL characters. + static bool FullMatch(const ::std::string& str, const RE& re) { + return FullMatch(str.c_str(), re); + } + static bool PartialMatch(const ::std::string& str, const RE& re) { + return PartialMatch(str.c_str(), re); + } + +#if GTEST_HAS_GLOBAL_STRING + static bool FullMatch(const ::string& str, const RE& re) { + return FullMatch(str.c_str(), re); + } + static bool PartialMatch(const ::string& str, const RE& re) { + return PartialMatch(str.c_str(), re); + } +#endif // GTEST_HAS_GLOBAL_STRING + + static bool FullMatch(const char* str, const RE& re); + static bool PartialMatch(const char* str, const RE& re); + + private: + void Init(const char* regex); + + // We use a const char* instead of a string, as Google Test may be used + // where string is not available. We also do not use Google Test's own + // String type here, in order to simplify dependencies between the + // files. + const char* pattern_; + bool is_valid_; +#if GTEST_USES_POSIX_RE + regex_t full_regex_; // For FullMatch(). + regex_t partial_regex_; // For PartialMatch(). +#else // GTEST_USES_SIMPLE_RE + const char* full_pattern_; // For FullMatch(); +#endif + + GTEST_DISALLOW_ASSIGN_(RE); +}; + +// Defines logging utilities: +// GTEST_LOG_(severity) - logs messages at the specified severity level. The +// message itself is streamed into the macro. +// LogToStderr() - directs all log messages to stderr. +// FlushInfoLog() - flushes informational log messages. + +enum GTestLogSeverity { + GTEST_INFO, + GTEST_WARNING, + GTEST_ERROR, + GTEST_FATAL +}; + +// Formats log entry severity, provides a stream object for streaming the +// log message, and terminates the message with a newline when going out of +// scope. +class GTEST_API_ GTestLog { + public: + GTestLog(GTestLogSeverity severity, const char* file, int line); + + // Flushes the buffers and, if severity is GTEST_FATAL, aborts the program. + ~GTestLog(); + + ::std::ostream& GetStream() { return ::std::cerr; } + + private: + const GTestLogSeverity severity_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(GTestLog); +}; + +#define GTEST_LOG_(severity) \ + ::testing::internal::GTestLog(::testing::internal::GTEST_##severity, \ + __FILE__, __LINE__).GetStream() + +inline void LogToStderr() {} +inline void FlushInfoLog() { fflush(NULL); } + +// INTERNAL IMPLEMENTATION - DO NOT USE. +// +// GTEST_CHECK_ is an all-mode assert. It aborts the program if the condition +// is not satisfied. +// Synopsys: +// GTEST_CHECK_(boolean_condition); +// or +// GTEST_CHECK_(boolean_condition) << "Additional message"; +// +// This checks the condition and if the condition is not satisfied +// it prints message about the condition violation, including the +// condition itself, plus additional message streamed into it, if any, +// and then it aborts the program. It aborts the program irrespective of +// whether it is built in the debug mode or not. +#define GTEST_CHECK_(condition) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (::testing::internal::IsTrue(condition)) \ + ; \ + else \ + GTEST_LOG_(FATAL) << "Condition " #condition " failed. " + +// An all-mode assert to verify that the given POSIX-style function +// call returns 0 (indicating success). Known limitation: this +// doesn't expand to a balanced 'if' statement, so enclose the macro +// in {} if you need to use it as the only statement in an 'if' +// branch. +#define GTEST_CHECK_POSIX_SUCCESS_(posix_call) \ + if (const int gtest_error = (posix_call)) \ + GTEST_LOG_(FATAL) << #posix_call << "failed with error " \ + << gtest_error + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// Downcasts the pointer of type Base to Derived. +// Derived must be a subclass of Base. The parameter MUST +// point to a class of type Derived, not any subclass of it. +// When RTTI is available, the function performs a runtime +// check to enforce this. +template <class Derived, class Base> +Derived* CheckedDowncastToActualType(Base* base) { +#if GTEST_HAS_RTTI + GTEST_CHECK_(typeid(*base) == typeid(Derived)); + return dynamic_cast<Derived*>(base); // NOLINT +#else + return static_cast<Derived*>(base); // Poor man's downcast. +#endif +} + +#if GTEST_HAS_STREAM_REDIRECTION_ + +// Defines the stderr capturer: +// CaptureStdout - starts capturing stdout. +// GetCapturedStdout - stops capturing stdout and returns the captured string. +// CaptureStderr - starts capturing stderr. +// GetCapturedStderr - stops capturing stderr and returns the captured string. +// +GTEST_API_ void CaptureStdout(); +GTEST_API_ String GetCapturedStdout(); +GTEST_API_ void CaptureStderr(); +GTEST_API_ String GetCapturedStderr(); + +#endif // GTEST_HAS_STREAM_REDIRECTION_ + + +#if GTEST_HAS_DEATH_TEST + +// A copy of all command line arguments. Set by InitGoogleTest(). +extern ::std::vector<String> g_argvs; + +// GTEST_HAS_DEATH_TEST implies we have ::std::string. +const ::std::vector<String>& GetArgvs(); + +#endif // GTEST_HAS_DEATH_TEST + +// Defines synchronization primitives. + +#if GTEST_HAS_PTHREAD + +// Sleeps for (roughly) n milli-seconds. This function is only for +// testing Google Test's own constructs. Don't use it in user tests, +// either directly or indirectly. +inline void SleepMilliseconds(int n) { + const timespec time = { + 0, // 0 seconds. + n * 1000L * 1000L, // And n ms. + }; + nanosleep(&time, NULL); +} + +// Allows a controller thread to pause execution of newly created +// threads until notified. Instances of this class must be created +// and destroyed in the controller thread. +// +// This class is only for testing Google Test's own constructs. Do not +// use it in user tests, either directly or indirectly. +class Notification { + public: + Notification() : notified_(false) {} + + // Notifies all threads created with this notification to start. Must + // be called from the controller thread. + void Notify() { notified_ = true; } + + // Blocks until the controller thread notifies. Must be called from a test + // thread. + void WaitForNotification() { + while(!notified_) { + SleepMilliseconds(10); + } + } + + private: + volatile bool notified_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(Notification); +}; + +// As a C-function, ThreadFuncWithCLinkage cannot be templated itself. +// Consequently, it cannot select a correct instantiation of ThreadWithParam +// in order to call its Run(). Introducing ThreadWithParamBase as a +// non-templated base class for ThreadWithParam allows us to bypass this +// problem. +class ThreadWithParamBase { + public: + virtual ~ThreadWithParamBase() {} + virtual void Run() = 0; +}; + +// pthread_create() accepts a pointer to a function type with the C linkage. +// According to the Standard (7.5/1), function types with different linkages +// are different even if they are otherwise identical. Some compilers (for +// example, SunStudio) treat them as different types. Since class methods +// cannot be defined with C-linkage we need to define a free C-function to +// pass into pthread_create(). +extern "C" inline void* ThreadFuncWithCLinkage(void* thread) { + static_cast<ThreadWithParamBase*>(thread)->Run(); + return NULL; +} + +// Helper class for testing Google Test's multi-threading constructs. +// To use it, write: +// +// void ThreadFunc(int param) { /* Do things with param */ } +// Notification thread_can_start; +// ... +// // The thread_can_start parameter is optional; you can supply NULL. +// ThreadWithParam<int> thread(&ThreadFunc, 5, &thread_can_start); +// thread_can_start.Notify(); +// +// These classes are only for testing Google Test's own constructs. Do +// not use them in user tests, either directly or indirectly. +template <typename T> +class ThreadWithParam : public ThreadWithParamBase { + public: + typedef void (*UserThreadFunc)(T); + + ThreadWithParam( + UserThreadFunc func, T param, Notification* thread_can_start) + : func_(func), + param_(param), + thread_can_start_(thread_can_start), + finished_(false) { + ThreadWithParamBase* const base = this; + // The thread can be created only after all fields except thread_ + // have been initialized. + GTEST_CHECK_POSIX_SUCCESS_( + pthread_create(&thread_, 0, &ThreadFuncWithCLinkage, base)); + } + ~ThreadWithParam() { Join(); } + + void Join() { + if (!finished_) { + GTEST_CHECK_POSIX_SUCCESS_(pthread_join(thread_, 0)); + finished_ = true; + } + } + + virtual void Run() { + if (thread_can_start_ != NULL) + thread_can_start_->WaitForNotification(); + func_(param_); + } + + private: + const UserThreadFunc func_; // User-supplied thread function. + const T param_; // User-supplied parameter to the thread function. + // When non-NULL, used to block execution until the controller thread + // notifies. + Notification* const thread_can_start_; + bool finished_; // true iff we know that the thread function has finished. + pthread_t thread_; // The native thread object. + + GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadWithParam); +}; + +// gtest-port.h guarantees to #include <pthread.h> when GTEST_HAS_PTHREAD is +// true. +#include <pthread.h> + +// MutexBase and Mutex implement mutex on pthreads-based platforms. They +// are used in conjunction with class MutexLock: +// +// Mutex mutex; +// ... +// MutexLock lock(&mutex); // Acquires the mutex and releases it at the end +// // of the current scope. +// +// MutexBase implements behavior for both statically and dynamically +// allocated mutexes. Do not use MutexBase directly. Instead, write +// the following to define a static mutex: +// +// GTEST_DEFINE_STATIC_MUTEX_(g_some_mutex); +// +// You can forward declare a static mutex like this: +// +// GTEST_DECLARE_STATIC_MUTEX_(g_some_mutex); +// +// To create a dynamic mutex, just define an object of type Mutex. +class MutexBase { + public: + // Acquires this mutex. + void Lock() { + GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_lock(&mutex_)); + owner_ = pthread_self(); + } + + // Releases this mutex. + void Unlock() { + // We don't protect writing to owner_ here, as it's the caller's + // responsibility to ensure that the current thread holds the + // mutex when this is called. + owner_ = 0; + GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_unlock(&mutex_)); + } + + // Does nothing if the current thread holds the mutex. Otherwise, crashes + // with high probability. + void AssertHeld() const { + GTEST_CHECK_(owner_ == pthread_self()) + << "The current thread is not holding the mutex @" << this; + } + + // A static mutex may be used before main() is entered. It may even + // be used before the dynamic initialization stage. Therefore we + // must be able to initialize a static mutex object at link time. + // This means MutexBase has to be a POD and its member variables + // have to be public. + public: + pthread_mutex_t mutex_; // The underlying pthread mutex. + pthread_t owner_; // The thread holding the mutex; 0 means no one holds it. +}; + +// Forward-declares a static mutex. +#define GTEST_DECLARE_STATIC_MUTEX_(mutex) \ + extern ::testing::internal::MutexBase mutex + +// Defines and statically (i.e. at link time) initializes a static mutex. +#define GTEST_DEFINE_STATIC_MUTEX_(mutex) \ + ::testing::internal::MutexBase mutex = { PTHREAD_MUTEX_INITIALIZER, 0 } + +// The Mutex class can only be used for mutexes created at runtime. It +// shares its API with MutexBase otherwise. +class Mutex : public MutexBase { + public: + Mutex() { + GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_init(&mutex_, NULL)); + owner_ = 0; + } + ~Mutex() { + GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_destroy(&mutex_)); + } + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(Mutex); +}; + +// We cannot name this class MutexLock as the ctor declaration would +// conflict with a macro named MutexLock, which is defined on some +// platforms. Hence the typedef trick below. +class GTestMutexLock { + public: + explicit GTestMutexLock(MutexBase* mutex) + : mutex_(mutex) { mutex_->Lock(); } + + ~GTestMutexLock() { mutex_->Unlock(); } + + private: + MutexBase* const mutex_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(GTestMutexLock); +}; + +typedef GTestMutexLock MutexLock; + +// Helpers for ThreadLocal. + +// pthread_key_create() requires DeleteThreadLocalValue() to have +// C-linkage. Therefore it cannot be templatized to access +// ThreadLocal<T>. Hence the need for class +// ThreadLocalValueHolderBase. +class ThreadLocalValueHolderBase { + public: + virtual ~ThreadLocalValueHolderBase() {} +}; + +// Called by pthread to delete thread-local data stored by +// pthread_setspecific(). +extern "C" inline void DeleteThreadLocalValue(void* value_holder) { + delete static_cast<ThreadLocalValueHolderBase*>(value_holder); +} + +// Implements thread-local storage on pthreads-based systems. +// +// // Thread 1 +// ThreadLocal<int> tl(100); // 100 is the default value for each thread. +// +// // Thread 2 +// tl.set(150); // Changes the value for thread 2 only. +// EXPECT_EQ(150, tl.get()); +// +// // Thread 1 +// EXPECT_EQ(100, tl.get()); // In thread 1, tl has the original value. +// tl.set(200); +// EXPECT_EQ(200, tl.get()); +// +// The template type argument T must have a public copy constructor. +// In addition, the default ThreadLocal constructor requires T to have +// a public default constructor. +// +// An object managed for a thread by a ThreadLocal instance is deleted +// when the thread exits. Or, if the ThreadLocal instance dies in +// that thread, when the ThreadLocal dies. It's the user's +// responsibility to ensure that all other threads using a ThreadLocal +// have exited when it dies, or the per-thread objects for those +// threads will not be deleted. +// +// Google Test only uses global ThreadLocal objects. That means they +// will die after main() has returned. Therefore, no per-thread +// object managed by Google Test will be leaked as long as all threads +// using Google Test have exited when main() returns. +template <typename T> +class ThreadLocal { + public: + ThreadLocal() : key_(CreateKey()), + default_() {} + explicit ThreadLocal(const T& value) : key_(CreateKey()), + default_(value) {} + + ~ThreadLocal() { + // Destroys the managed object for the current thread, if any. + DeleteThreadLocalValue(pthread_getspecific(key_)); + + // Releases resources associated with the key. This will *not* + // delete managed objects for other threads. + GTEST_CHECK_POSIX_SUCCESS_(pthread_key_delete(key_)); + } + + T* pointer() { return GetOrCreateValue(); } + const T* pointer() const { return GetOrCreateValue(); } + const T& get() const { return *pointer(); } + void set(const T& value) { *pointer() = value; } + + private: + // Holds a value of type T. + class ValueHolder : public ThreadLocalValueHolderBase { + public: + explicit ValueHolder(const T& value) : value_(value) {} + + T* pointer() { return &value_; } + + private: + T value_; + GTEST_DISALLOW_COPY_AND_ASSIGN_(ValueHolder); + }; + + static pthread_key_t CreateKey() { + pthread_key_t key; + // When a thread exits, DeleteThreadLocalValue() will be called on + // the object managed for that thread. + GTEST_CHECK_POSIX_SUCCESS_( + pthread_key_create(&key, &DeleteThreadLocalValue)); + return key; + } + + T* GetOrCreateValue() const { + ThreadLocalValueHolderBase* const holder = + static_cast<ThreadLocalValueHolderBase*>(pthread_getspecific(key_)); + if (holder != NULL) { + return CheckedDowncastToActualType<ValueHolder>(holder)->pointer(); + } + + ValueHolder* const new_holder = new ValueHolder(default_); + ThreadLocalValueHolderBase* const holder_base = new_holder; + GTEST_CHECK_POSIX_SUCCESS_(pthread_setspecific(key_, holder_base)); + return new_holder->pointer(); + } + + // A key pthreads uses for looking up per-thread values. + const pthread_key_t key_; + const T default_; // The default value for each thread. + + GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadLocal); +}; + +#define GTEST_IS_THREADSAFE 1 + +#else // GTEST_HAS_PTHREAD + +// A dummy implementation of synchronization primitives (mutex, lock, +// and thread-local variable). Necessary for compiling Google Test where +// mutex is not supported - using Google Test in multiple threads is not +// supported on such platforms. + +class Mutex { + public: + Mutex() {} + void AssertHeld() const {} +}; + +#define GTEST_DECLARE_STATIC_MUTEX_(mutex) \ + extern ::testing::internal::Mutex mutex + +#define GTEST_DEFINE_STATIC_MUTEX_(mutex) ::testing::internal::Mutex mutex + +class GTestMutexLock { + public: + explicit GTestMutexLock(Mutex*) {} // NOLINT +}; + +typedef GTestMutexLock MutexLock; + +template <typename T> +class ThreadLocal { + public: + ThreadLocal() : value_() {} + explicit ThreadLocal(const T& value) : value_(value) {} + T* pointer() { return &value_; } + const T* pointer() const { return &value_; } + const T& get() const { return value_; } + void set(const T& value) { value_ = value; } + private: + T value_; +}; + +// The above synchronization primitives have dummy implementations. +// Therefore Google Test is not thread-safe. +#define GTEST_IS_THREADSAFE 0 + +#endif // GTEST_HAS_PTHREAD + +// Returns the number of threads running in the process, or 0 to indicate that +// we cannot detect it. +GTEST_API_ size_t GetThreadCount(); + +// Passing non-POD classes through ellipsis (...) crashes the ARM +// compiler and generates a warning in Sun Studio. The Nokia Symbian +// and the IBM XL C/C++ compiler try to instantiate a copy constructor +// for objects passed through ellipsis (...), failing for uncopyable +// objects. We define this to ensure that only POD is passed through +// ellipsis on these systems. +#if defined(__SYMBIAN32__) || defined(__IBMCPP__) || defined(__SUNPRO_CC) +// We lose support for NULL detection where the compiler doesn't like +// passing non-POD classes through ellipsis (...). +#define GTEST_ELLIPSIS_NEEDS_POD_ 1 +#else +#define GTEST_CAN_COMPARE_NULL 1 +#endif + +// The Nokia Symbian and IBM XL C/C++ compilers cannot decide between +// const T& and const T* in a function template. These compilers +// _can_ decide between class template specializations for T and T*, +// so a tr1::type_traits-like is_pointer works. +#if defined(__SYMBIAN32__) || defined(__IBMCPP__) +#define GTEST_NEEDS_IS_POINTER_ 1 +#endif + +template <bool bool_value> +struct bool_constant { + typedef bool_constant<bool_value> type; + static const bool value = bool_value; +}; +template <bool bool_value> const bool bool_constant<bool_value>::value; + +typedef bool_constant<false> false_type; +typedef bool_constant<true> true_type; + +template <typename T> +struct is_pointer : public false_type {}; + +template <typename T> +struct is_pointer<T*> : public true_type {}; + +#if GTEST_OS_WINDOWS +#define GTEST_PATH_SEP_ "\\" +#define GTEST_HAS_ALT_PATH_SEP_ 1 +// The biggest signed integer type the compiler supports. +typedef __int64 BiggestInt; +#else +#define GTEST_PATH_SEP_ "/" +#define GTEST_HAS_ALT_PATH_SEP_ 0 +typedef long long BiggestInt; // NOLINT +#endif // GTEST_OS_WINDOWS + +// The testing::internal::posix namespace holds wrappers for common +// POSIX functions. These wrappers hide the differences between +// Windows/MSVC and POSIX systems. Since some compilers define these +// standard functions as macros, the wrapper cannot have the same name +// as the wrapped function. + +namespace posix { + +// Functions with a different name on Windows. + +#if GTEST_OS_WINDOWS + +typedef struct _stat StatStruct; + +#ifdef __BORLANDC__ +inline int IsATTY(int fd) { return isatty(fd); } +inline int StrCaseCmp(const char* s1, const char* s2) { + return stricmp(s1, s2); +} +inline char* StrDup(const char* src) { return strdup(src); } +#else // !__BORLANDC__ +#if GTEST_OS_WINDOWS_MOBILE +inline int IsATTY(int /* fd */) { return 0; } +#else +inline int IsATTY(int fd) { return _isatty(fd); } +#endif // GTEST_OS_WINDOWS_MOBILE +inline int StrCaseCmp(const char* s1, const char* s2) { + return _stricmp(s1, s2); +} +inline char* StrDup(const char* src) { return _strdup(src); } +#endif // __BORLANDC__ + +#if GTEST_OS_WINDOWS_MOBILE +inline int FileNo(FILE* file) { return reinterpret_cast<int>(_fileno(file)); } +// Stat(), RmDir(), and IsDir() are not needed on Windows CE at this +// time and thus not defined there. +#else +inline int FileNo(FILE* file) { return _fileno(file); } +inline int Stat(const char* path, StatStruct* buf) { return _stat(path, buf); } +inline int RmDir(const char* dir) { return _rmdir(dir); } +inline bool IsDir(const StatStruct& st) { + return (_S_IFDIR & st.st_mode) != 0; +} +#endif // GTEST_OS_WINDOWS_MOBILE + +#else + +typedef struct stat StatStruct; + +inline int FileNo(FILE* file) { return fileno(file); } +inline int IsATTY(int fd) { return isatty(fd); } +inline int Stat(const char* path, StatStruct* buf) { return stat(path, buf); } +inline int StrCaseCmp(const char* s1, const char* s2) { + return strcasecmp(s1, s2); +} +inline char* StrDup(const char* src) { return strdup(src); } +inline int RmDir(const char* dir) { return rmdir(dir); } +inline bool IsDir(const StatStruct& st) { return S_ISDIR(st.st_mode); } + +#endif // GTEST_OS_WINDOWS + +// Functions deprecated by MSVC 8.0. + +#ifdef _MSC_VER +// Temporarily disable warning 4996 (deprecated function). +#pragma warning(push) +#pragma warning(disable:4996) +#endif + +inline const char* StrNCpy(char* dest, const char* src, size_t n) { + return strncpy(dest, src, n); +} + +// ChDir(), FReopen(), FDOpen(), Read(), Write(), Close(), and +// StrError() aren't needed on Windows CE at this time and thus not +// defined there. + +#if !GTEST_OS_WINDOWS_MOBILE +inline int ChDir(const char* dir) { return chdir(dir); } +#endif +inline FILE* FOpen(const char* path, const char* mode) { + return fopen(path, mode); +} +#if !GTEST_OS_WINDOWS_MOBILE +inline FILE *FReopen(const char* path, const char* mode, FILE* stream) { + return freopen(path, mode, stream); +} +inline FILE* FDOpen(int fd, const char* mode) { return fdopen(fd, mode); } +#endif +inline int FClose(FILE* fp) { return fclose(fp); } +#if !GTEST_OS_WINDOWS_MOBILE +inline int Read(int fd, void* buf, unsigned int count) { + return static_cast<int>(read(fd, buf, count)); +} +inline int Write(int fd, const void* buf, unsigned int count) { + return static_cast<int>(write(fd, buf, count)); +} +inline int Close(int fd) { return close(fd); } +inline const char* StrError(int errnum) { return strerror(errnum); } +#endif +inline const char* GetEnv(const char* name) { +#if GTEST_OS_WINDOWS_MOBILE + // We are on Windows CE, which has no environment variables. + return NULL; +#elif defined(__BORLANDC__) || defined(__SunOS_5_8) || defined(__SunOS_5_9) + // Environment variables which we programmatically clear will be set to the + // empty string rather than unset (NULL). Handle that case. + const char* const env = getenv(name); + return (env != NULL && env[0] != '\0') ? env : NULL; +#else + return getenv(name); +#endif +} + +#ifdef _MSC_VER +#pragma warning(pop) // Restores the warning state. +#endif + +#if GTEST_OS_WINDOWS_MOBILE +// Windows CE has no C library. The abort() function is used in +// several places in Google Test. This implementation provides a reasonable +// imitation of standard behaviour. +void Abort(); +#else +inline void Abort() { abort(); } +#endif // GTEST_OS_WINDOWS_MOBILE + +} // namespace posix + +// The maximum number a BiggestInt can represent. This definition +// works no matter BiggestInt is represented in one's complement or +// two's complement. +// +// We cannot rely on numeric_limits in STL, as __int64 and long long +// are not part of standard C++ and numeric_limits doesn't need to be +// defined for them. +const BiggestInt kMaxBiggestInt = + ~(static_cast<BiggestInt>(1) << (8*sizeof(BiggestInt) - 1)); + +// This template class serves as a compile-time function from size to +// type. It maps a size in bytes to a primitive type with that +// size. e.g. +// +// TypeWithSize<4>::UInt +// +// is typedef-ed to be unsigned int (unsigned integer made up of 4 +// bytes). +// +// Such functionality should belong to STL, but I cannot find it +// there. +// +// Google Test uses this class in the implementation of floating-point +// comparison. +// +// For now it only handles UInt (unsigned int) as that's all Google Test +// needs. Other types can be easily added in the future if need +// arises. +template <size_t size> +class TypeWithSize { + public: + // This prevents the user from using TypeWithSize<N> with incorrect + // values of N. + typedef void UInt; +}; + +// The specialization for size 4. +template <> +class TypeWithSize<4> { + public: + // unsigned int has size 4 in both gcc and MSVC. + // + // As base/basictypes.h doesn't compile on Windows, we cannot use + // uint32, uint64, and etc here. + typedef int Int; + typedef unsigned int UInt; +}; + +// The specialization for size 8. +template <> +class TypeWithSize<8> { + public: +#if GTEST_OS_WINDOWS + typedef __int64 Int; + typedef unsigned __int64 UInt; +#else + typedef long long Int; // NOLINT + typedef unsigned long long UInt; // NOLINT +#endif // GTEST_OS_WINDOWS +}; + +// Integer types of known sizes. +typedef TypeWithSize<4>::Int Int32; +typedef TypeWithSize<4>::UInt UInt32; +typedef TypeWithSize<8>::Int Int64; +typedef TypeWithSize<8>::UInt UInt64; +typedef TypeWithSize<8>::Int TimeInMillis; // Represents time in milliseconds. + +// Utilities for command line flags and environment variables. + +// Macro for referencing flags. +#define GTEST_FLAG(name) FLAGS_gtest_##name + +// Macros for declaring flags. +#define GTEST_DECLARE_bool_(name) GTEST_API_ extern bool GTEST_FLAG(name) +#define GTEST_DECLARE_int32_(name) \ + GTEST_API_ extern ::testing::internal::Int32 GTEST_FLAG(name) +#define GTEST_DECLARE_string_(name) \ + GTEST_API_ extern ::testing::internal::String GTEST_FLAG(name) + +// Macros for defining flags. +#define GTEST_DEFINE_bool_(name, default_val, doc) \ + GTEST_API_ bool GTEST_FLAG(name) = (default_val) +#define GTEST_DEFINE_int32_(name, default_val, doc) \ + GTEST_API_ ::testing::internal::Int32 GTEST_FLAG(name) = (default_val) +#define GTEST_DEFINE_string_(name, default_val, doc) \ + GTEST_API_ ::testing::internal::String GTEST_FLAG(name) = (default_val) + +// Parses 'str' for a 32-bit signed integer. If successful, writes the result +// to *value and returns true; otherwise leaves *value unchanged and returns +// false. +// TODO(chandlerc): Find a better way to refactor flag and environment parsing +// out of both gtest-port.cc and gtest.cc to avoid exporting this utility +// function. +bool ParseInt32(const Message& src_text, const char* str, Int32* value); + +// Parses a bool/Int32/string from the environment variable +// corresponding to the given Google Test flag. +bool BoolFromGTestEnv(const char* flag, bool default_val); +GTEST_API_ Int32 Int32FromGTestEnv(const char* flag, Int32 default_val); +const char* StringFromGTestEnv(const char* flag, const char* default_val); + +} // namespace internal +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_ + +#if GTEST_OS_LINUX +#include <stdlib.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <unistd.h> +#endif // GTEST_OS_LINUX + +#include <ctype.h> +#include <string.h> +#include <iomanip> +#include <limits> +#include <set> + +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee) +// +// The Google C++ Testing Framework (Google Test) +// +// This header file declares the String class and functions used internally by +// Google Test. They are subject to change without notice. They should not used +// by code external to Google Test. +// +// This header file is #included by <gtest/internal/gtest-internal.h>. +// It should not be #included by other files. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_ + +#ifdef __BORLANDC__ +// string.h is not guaranteed to provide strcpy on C++ Builder. +#include <mem.h> +#endif + +#include <string.h> + +#include <string> + +namespace testing { +namespace internal { + +// String - a UTF-8 string class. +// +// For historic reasons, we don't use std::string. +// +// TODO(wan@google.com): replace this class with std::string or +// implement it in terms of the latter. +// +// Note that String can represent both NULL and the empty string, +// while std::string cannot represent NULL. +// +// NULL and the empty string are considered different. NULL is less +// than anything (including the empty string) except itself. +// +// This class only provides minimum functionality necessary for +// implementing Google Test. We do not intend to implement a full-fledged +// string class here. +// +// Since the purpose of this class is to provide a substitute for +// std::string on platforms where it cannot be used, we define a copy +// constructor and assignment operators such that we don't need +// conditional compilation in a lot of places. +// +// In order to make the representation efficient, the d'tor of String +// is not virtual. Therefore DO NOT INHERIT FROM String. +class GTEST_API_ String { + public: + // Static utility methods + + // Returns the input enclosed in double quotes if it's not NULL; + // otherwise returns "(null)". For example, "\"Hello\"" is returned + // for input "Hello". + // + // This is useful for printing a C string in the syntax of a literal. + // + // Known issue: escape sequences are not handled yet. + static String ShowCStringQuoted(const char* c_str); + + // Clones a 0-terminated C string, allocating memory using new. The + // caller is responsible for deleting the return value using + // delete[]. Returns the cloned string, or NULL if the input is + // NULL. + // + // This is different from strdup() in string.h, which allocates + // memory using malloc(). + static const char* CloneCString(const char* c_str); + +#if GTEST_OS_WINDOWS_MOBILE + // Windows CE does not have the 'ANSI' versions of Win32 APIs. To be + // able to pass strings to Win32 APIs on CE we need to convert them + // to 'Unicode', UTF-16. + + // Creates a UTF-16 wide string from the given ANSI string, allocating + // memory using new. The caller is responsible for deleting the return + // value using delete[]. Returns the wide string, or NULL if the + // input is NULL. + // + // The wide string is created using the ANSI codepage (CP_ACP) to + // match the behaviour of the ANSI versions of Win32 calls and the + // C runtime. + static LPCWSTR AnsiToUtf16(const char* c_str); + + // Creates an ANSI string from the given wide string, allocating + // memory using new. The caller is responsible for deleting the return + // value using delete[]. Returns the ANSI string, or NULL if the + // input is NULL. + // + // The returned string is created using the ANSI codepage (CP_ACP) to + // match the behaviour of the ANSI versions of Win32 calls and the + // C runtime. + static const char* Utf16ToAnsi(LPCWSTR utf16_str); +#endif + + // Compares two C strings. Returns true iff they have the same content. + // + // Unlike strcmp(), this function can handle NULL argument(s). A + // NULL C string is considered different to any non-NULL C string, + // including the empty string. + static bool CStringEquals(const char* lhs, const char* rhs); + + // Converts a wide C string to a String using the UTF-8 encoding. + // NULL will be converted to "(null)". If an error occurred during + // the conversion, "(failed to convert from wide string)" is + // returned. + static String ShowWideCString(const wchar_t* wide_c_str); + + // Similar to ShowWideCString(), except that this function encloses + // the converted string in double quotes. + static String ShowWideCStringQuoted(const wchar_t* wide_c_str); + + // Compares two wide C strings. Returns true iff they have the same + // content. + // + // Unlike wcscmp(), this function can handle NULL argument(s). A + // NULL C string is considered different to any non-NULL C string, + // including the empty string. + static bool WideCStringEquals(const wchar_t* lhs, const wchar_t* rhs); + + // Compares two C strings, ignoring case. Returns true iff they + // have the same content. + // + // Unlike strcasecmp(), this function can handle NULL argument(s). + // A NULL C string is considered different to any non-NULL C string, + // including the empty string. + static bool CaseInsensitiveCStringEquals(const char* lhs, + const char* rhs); + + // Compares two wide C strings, ignoring case. Returns true iff they + // have the same content. + // + // Unlike wcscasecmp(), this function can handle NULL argument(s). + // A NULL C string is considered different to any non-NULL wide C string, + // including the empty string. + // NB: The implementations on different platforms slightly differ. + // On windows, this method uses _wcsicmp which compares according to LC_CTYPE + // environment variable. On GNU platform this method uses wcscasecmp + // which compares according to LC_CTYPE category of the current locale. + // On MacOS X, it uses towlower, which also uses LC_CTYPE category of the + // current locale. + static bool CaseInsensitiveWideCStringEquals(const wchar_t* lhs, + const wchar_t* rhs); + + // Formats a list of arguments to a String, using the same format + // spec string as for printf. + // + // We do not use the StringPrintf class as it is not universally + // available. + // + // The result is limited to 4096 characters (including the tailing + // 0). If 4096 characters are not enough to format the input, + // "<buffer exceeded>" is returned. + static String Format(const char* format, ...); + + // C'tors + + // The default c'tor constructs a NULL string. + String() : c_str_(NULL), length_(0) {} + + // Constructs a String by cloning a 0-terminated C string. + String(const char* a_c_str) { // NOLINT + if (a_c_str == NULL) { + c_str_ = NULL; + length_ = 0; + } else { + ConstructNonNull(a_c_str, strlen(a_c_str)); + } + } + + // Constructs a String by copying a given number of chars from a + // buffer. E.g. String("hello", 3) creates the string "hel", + // String("a\0bcd", 4) creates "a\0bc", String(NULL, 0) creates "", + // and String(NULL, 1) results in access violation. + String(const char* buffer, size_t a_length) { + ConstructNonNull(buffer, a_length); + } + + // The copy c'tor creates a new copy of the string. The two + // String objects do not share content. + String(const String& str) : c_str_(NULL), length_(0) { *this = str; } + + // D'tor. String is intended to be a final class, so the d'tor + // doesn't need to be virtual. + ~String() { delete[] c_str_; } + + // Allows a String to be implicitly converted to an ::std::string or + // ::string, and vice versa. Converting a String containing a NULL + // pointer to ::std::string or ::string is undefined behavior. + // Converting a ::std::string or ::string containing an embedded NUL + // character to a String will result in the prefix up to the first + // NUL character. + String(const ::std::string& str) { + ConstructNonNull(str.c_str(), str.length()); + } + + operator ::std::string() const { return ::std::string(c_str(), length()); } + +#if GTEST_HAS_GLOBAL_STRING + String(const ::string& str) { + ConstructNonNull(str.c_str(), str.length()); + } + + operator ::string() const { return ::string(c_str(), length()); } +#endif // GTEST_HAS_GLOBAL_STRING + + // Returns true iff this is an empty string (i.e. ""). + bool empty() const { return (c_str() != NULL) && (length() == 0); } + + // Compares this with another String. + // Returns < 0 if this is less than rhs, 0 if this is equal to rhs, or > 0 + // if this is greater than rhs. + int Compare(const String& rhs) const; + + // Returns true iff this String equals the given C string. A NULL + // string and a non-NULL string are considered not equal. + bool operator==(const char* a_c_str) const { return Compare(a_c_str) == 0; } + + // Returns true iff this String is less than the given String. A + // NULL string is considered less than "". + bool operator<(const String& rhs) const { return Compare(rhs) < 0; } + + // Returns true iff this String doesn't equal the given C string. A NULL + // string and a non-NULL string are considered not equal. + bool operator!=(const char* a_c_str) const { return !(*this == a_c_str); } + + // Returns true iff this String ends with the given suffix. *Any* + // String is considered to end with a NULL or empty suffix. + bool EndsWith(const char* suffix) const; + + // Returns true iff this String ends with the given suffix, not considering + // case. Any String is considered to end with a NULL or empty suffix. + bool EndsWithCaseInsensitive(const char* suffix) const; + + // Returns the length of the encapsulated string, or 0 if the + // string is NULL. + size_t length() const { return length_; } + + // Gets the 0-terminated C string this String object represents. + // The String object still owns the string. Therefore the caller + // should NOT delete the return value. + const char* c_str() const { return c_str_; } + + // Assigns a C string to this object. Self-assignment works. + const String& operator=(const char* a_c_str) { + return *this = String(a_c_str); + } + + // Assigns a String object to this object. Self-assignment works. + const String& operator=(const String& rhs) { + if (this != &rhs) { + delete[] c_str_; + if (rhs.c_str() == NULL) { + c_str_ = NULL; + length_ = 0; + } else { + ConstructNonNull(rhs.c_str(), rhs.length()); + } + } + + return *this; + } + + private: + // Constructs a non-NULL String from the given content. This + // function can only be called when data_ has not been allocated. + // ConstructNonNull(NULL, 0) results in an empty string (""). + // ConstructNonNull(NULL, non_zero) is undefined behavior. + void ConstructNonNull(const char* buffer, size_t a_length) { + char* const str = new char[a_length + 1]; + memcpy(str, buffer, a_length); + str[a_length] = '\0'; + c_str_ = str; + length_ = a_length; + } + + const char* c_str_; + size_t length_; +}; // class String + +// Streams a String to an ostream. Each '\0' character in the String +// is replaced with "\\0". +inline ::std::ostream& operator<<(::std::ostream& os, const String& str) { + if (str.c_str() == NULL) { + os << "(null)"; + } else { + const char* const c_str = str.c_str(); + for (size_t i = 0; i != str.length(); i++) { + if (c_str[i] == '\0') { + os << "\\0"; + } else { + os << c_str[i]; + } + } + } + return os; +} + +// Gets the content of the StrStream's buffer as a String. Each '\0' +// character in the buffer is replaced with "\\0". +GTEST_API_ String StrStreamToString(StrStream* stream); + +// Converts a streamable value to a String. A NULL pointer is +// converted to "(null)". When the input value is a ::string, +// ::std::string, ::wstring, or ::std::wstring object, each NUL +// character in it is replaced with "\\0". + +// Declared here but defined in gtest.h, so that it has access +// to the definition of the Message class, required by the ARM +// compiler. +template <typename T> +String StreamableToString(const T& streamable); + +} // namespace internal +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: keith.ray@gmail.com (Keith Ray) +// +// Google Test filepath utilities +// +// This header file declares classes and functions used internally by +// Google Test. They are subject to change without notice. +// +// This file is #included in <gtest/internal/gtest-internal.h>. +// Do not include this header file separately! + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_ + + +namespace testing { +namespace internal { + +// FilePath - a class for file and directory pathname manipulation which +// handles platform-specific conventions (like the pathname separator). +// Used for helper functions for naming files in a directory for xml output. +// Except for Set methods, all methods are const or static, which provides an +// "immutable value object" -- useful for peace of mind. +// A FilePath with a value ending in a path separator ("like/this/") represents +// a directory, otherwise it is assumed to represent a file. In either case, +// it may or may not represent an actual file or directory in the file system. +// Names are NOT checked for syntax correctness -- no checking for illegal +// characters, malformed paths, etc. + +class GTEST_API_ FilePath { + public: + FilePath() : pathname_("") { } + FilePath(const FilePath& rhs) : pathname_(rhs.pathname_) { } + + explicit FilePath(const char* pathname) : pathname_(pathname) { + Normalize(); + } + + explicit FilePath(const String& pathname) : pathname_(pathname) { + Normalize(); + } + + FilePath& operator=(const FilePath& rhs) { + Set(rhs); + return *this; + } + + void Set(const FilePath& rhs) { + pathname_ = rhs.pathname_; + } + + String ToString() const { return pathname_; } + const char* c_str() const { return pathname_.c_str(); } + + // Returns the current working directory, or "" if unsuccessful. + static FilePath GetCurrentDir(); + + // Given directory = "dir", base_name = "test", number = 0, + // extension = "xml", returns "dir/test.xml". If number is greater + // than zero (e.g., 12), returns "dir/test_12.xml". + // On Windows platform, uses \ as the separator rather than /. + static FilePath MakeFileName(const FilePath& directory, + const FilePath& base_name, + int number, + const char* extension); + + // Given directory = "dir", relative_path = "test.xml", + // returns "dir/test.xml". + // On Windows, uses \ as the separator rather than /. + static FilePath ConcatPaths(const FilePath& directory, + const FilePath& relative_path); + + // Returns a pathname for a file that does not currently exist. The pathname + // will be directory/base_name.extension or + // directory/base_name_<number>.extension if directory/base_name.extension + // already exists. The number will be incremented until a pathname is found + // that does not already exist. + // Examples: 'dir/foo_test.xml' or 'dir/foo_test_1.xml'. + // There could be a race condition if two or more processes are calling this + // function at the same time -- they could both pick the same filename. + static FilePath GenerateUniqueFileName(const FilePath& directory, + const FilePath& base_name, + const char* extension); + + // Returns true iff the path is NULL or "". + bool IsEmpty() const { return c_str() == NULL || *c_str() == '\0'; } + + // If input name has a trailing separator character, removes it and returns + // the name, otherwise return the name string unmodified. + // On Windows platform, uses \ as the separator, other platforms use /. + FilePath RemoveTrailingPathSeparator() const; + + // Returns a copy of the FilePath with the directory part removed. + // Example: FilePath("path/to/file").RemoveDirectoryName() returns + // FilePath("file"). If there is no directory part ("just_a_file"), it returns + // the FilePath unmodified. If there is no file part ("just_a_dir/") it + // returns an empty FilePath (""). + // On Windows platform, '\' is the path separator, otherwise it is '/'. + FilePath RemoveDirectoryName() const; + + // RemoveFileName returns the directory path with the filename removed. + // Example: FilePath("path/to/file").RemoveFileName() returns "path/to/". + // If the FilePath is "a_file" or "/a_file", RemoveFileName returns + // FilePath("./") or, on Windows, FilePath(".\\"). If the filepath does + // not have a file, like "just/a/dir/", it returns the FilePath unmodified. + // On Windows platform, '\' is the path separator, otherwise it is '/'. + FilePath RemoveFileName() const; + + // Returns a copy of the FilePath with the case-insensitive extension removed. + // Example: FilePath("dir/file.exe").RemoveExtension("EXE") returns + // FilePath("dir/file"). If a case-insensitive extension is not + // found, returns a copy of the original FilePath. + FilePath RemoveExtension(const char* extension) const; + + // Creates directories so that path exists. Returns true if successful or if + // the directories already exist; returns false if unable to create + // directories for any reason. Will also return false if the FilePath does + // not represent a directory (that is, it doesn't end with a path separator). + bool CreateDirectoriesRecursively() const; + + // Create the directory so that path exists. Returns true if successful or + // if the directory already exists; returns false if unable to create the + // directory for any reason, including if the parent directory does not + // exist. Not named "CreateDirectory" because that's a macro on Windows. + bool CreateFolder() const; + + // Returns true if FilePath describes something in the file-system, + // either a file, directory, or whatever, and that something exists. + bool FileOrDirectoryExists() const; + + // Returns true if pathname describes a directory in the file-system + // that exists. + bool DirectoryExists() const; + + // Returns true if FilePath ends with a path separator, which indicates that + // it is intended to represent a directory. Returns false otherwise. + // This does NOT check that a directory (or file) actually exists. + bool IsDirectory() const; + + // Returns true if pathname describes a root directory. (Windows has one + // root directory per disk drive.) + bool IsRootDirectory() const; + + // Returns true if pathname describes an absolute path. + bool IsAbsolutePath() const; + + private: + // Replaces multiple consecutive separators with a single separator. + // For example, "bar///foo" becomes "bar/foo". Does not eliminate other + // redundancies that might be in a pathname involving "." or "..". + // + // A pathname with multiple consecutive separators may occur either through + // user error or as a result of some scripts or APIs that generate a pathname + // with a trailing separator. On other platforms the same API or script + // may NOT generate a pathname with a trailing "/". Then elsewhere that + // pathname may have another "/" and pathname components added to it, + // without checking for the separator already being there. + // The script language and operating system may allow paths like "foo//bar" + // but some of the functions in FilePath will not handle that correctly. In + // particular, RemoveTrailingPathSeparator() only removes one separator, and + // it is called in CreateDirectoriesRecursively() assuming that it will change + // a pathname from directory syntax (trailing separator) to filename syntax. + // + // On Windows this method also replaces the alternate path separator '/' with + // the primary path separator '\\', so that for example "bar\\/\\foo" becomes + // "bar\\foo". + + void Normalize(); + + // Returns a pointer to the last occurence of a valid path separator in + // the FilePath. On Windows, for example, both '/' and '\' are valid path + // separators. Returns NULL if no path separator was found. + const char* FindLastPathSeparator() const; + + String pathname_; +}; // class FilePath + +} // namespace internal +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_ +// This file was GENERATED by command: +// pump.py gtest-type-util.h.pump +// DO NOT EDIT BY HAND!!! + +// Copyright 2008 Google Inc. +// All Rights Reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: wan@google.com (Zhanyong Wan) + +// Type utilities needed for implementing typed and type-parameterized +// tests. This file is generated by a SCRIPT. DO NOT EDIT BY HAND! +// +// Currently we support at most 50 types in a list, and at most 50 +// type-parameterized tests in one type-parameterized test case. +// Please contact googletestframework@googlegroups.com if you need +// more. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ + + +#if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P + +// #ifdef __GNUC__ is too general here. It is possible to use gcc without using +// libstdc++ (which is where cxxabi.h comes from). +#ifdef __GLIBCXX__ +#include <cxxabi.h> +#endif // __GLIBCXX__ + +namespace testing { +namespace internal { + +// AssertyTypeEq<T1, T2>::type is defined iff T1 and T2 are the same +// type. This can be used as a compile-time assertion to ensure that +// two types are equal. + +template <typename T1, typename T2> +struct AssertTypeEq; + +template <typename T> +struct AssertTypeEq<T, T> { + typedef bool type; +}; + +// GetTypeName<T>() returns a human-readable name of type T. +template <typename T> +String GetTypeName() { +#if GTEST_HAS_RTTI + + const char* const name = typeid(T).name(); +#ifdef __GLIBCXX__ + int status = 0; + // gcc's implementation of typeid(T).name() mangles the type name, + // so we have to demangle it. + char* const readable_name = abi::__cxa_demangle(name, 0, 0, &status); + const String name_str(status == 0 ? readable_name : name); + free(readable_name); + return name_str; +#else + return name; +#endif // __GLIBCXX__ + +#else + return "<type>"; +#endif // GTEST_HAS_RTTI +} + +// A unique type used as the default value for the arguments of class +// template Types. This allows us to simulate variadic templates +// (e.g. Types<int>, Type<int, double>, and etc), which C++ doesn't +// support directly. +struct None {}; + +// The following family of struct and struct templates are used to +// represent type lists. In particular, TypesN<T1, T2, ..., TN> +// represents a type list with N types (T1, T2, ..., and TN) in it. +// Except for Types0, every struct in the family has two member types: +// Head for the first type in the list, and Tail for the rest of the +// list. + +// The empty type list. +struct Types0 {}; + +// Type lists of length 1, 2, 3, and so on. + +template <typename T1> +struct Types1 { + typedef T1 Head; + typedef Types0 Tail; +}; +template <typename T1, typename T2> +struct Types2 { + typedef T1 Head; + typedef Types1<T2> Tail; +}; + +template <typename T1, typename T2, typename T3> +struct Types3 { + typedef T1 Head; + typedef Types2<T2, T3> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4> +struct Types4 { + typedef T1 Head; + typedef Types3<T2, T3, T4> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5> +struct Types5 { + typedef T1 Head; + typedef Types4<T2, T3, T4, T5> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6> +struct Types6 { + typedef T1 Head; + typedef Types5<T2, T3, T4, T5, T6> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7> +struct Types7 { + typedef T1 Head; + typedef Types6<T2, T3, T4, T5, T6, T7> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8> +struct Types8 { + typedef T1 Head; + typedef Types7<T2, T3, T4, T5, T6, T7, T8> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9> +struct Types9 { + typedef T1 Head; + typedef Types8<T2, T3, T4, T5, T6, T7, T8, T9> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10> +struct Types10 { + typedef T1 Head; + typedef Types9<T2, T3, T4, T5, T6, T7, T8, T9, T10> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11> +struct Types11 { + typedef T1 Head; + typedef Types10<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12> +struct Types12 { + typedef T1 Head; + typedef Types11<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13> +struct Types13 { + typedef T1 Head; + typedef Types12<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14> +struct Types14 { + typedef T1 Head; + typedef Types13<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15> +struct Types15 { + typedef T1 Head; + typedef Types14<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16> +struct Types16 { + typedef T1 Head; + typedef Types15<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17> +struct Types17 { + typedef T1 Head; + typedef Types16<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18> +struct Types18 { + typedef T1 Head; + typedef Types17<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19> +struct Types19 { + typedef T1 Head; + typedef Types18<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20> +struct Types20 { + typedef T1 Head; + typedef Types19<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21> +struct Types21 { + typedef T1 Head; + typedef Types20<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22> +struct Types22 { + typedef T1 Head; + typedef Types21<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23> +struct Types23 { + typedef T1 Head; + typedef Types22<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24> +struct Types24 { + typedef T1 Head; + typedef Types23<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25> +struct Types25 { + typedef T1 Head; + typedef Types24<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26> +struct Types26 { + typedef T1 Head; + typedef Types25<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27> +struct Types27 { + typedef T1 Head; + typedef Types26<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28> +struct Types28 { + typedef T1 Head; + typedef Types27<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29> +struct Types29 { + typedef T1 Head; + typedef Types28<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30> +struct Types30 { + typedef T1 Head; + typedef Types29<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31> +struct Types31 { + typedef T1 Head; + typedef Types30<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32> +struct Types32 { + typedef T1 Head; + typedef Types31<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33> +struct Types33 { + typedef T1 Head; + typedef Types32<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34> +struct Types34 { + typedef T1 Head; + typedef Types33<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33, T34> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35> +struct Types35 { + typedef T1 Head; + typedef Types34<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33, T34, T35> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36> +struct Types36 { + typedef T1 Head; + typedef Types35<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33, T34, T35, T36> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37> +struct Types37 { + typedef T1 Head; + typedef Types36<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33, T34, T35, T36, T37> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38> +struct Types38 { + typedef T1 Head; + typedef Types37<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33, T34, T35, T36, T37, T38> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39> +struct Types39 { + typedef T1 Head; + typedef Types38<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33, T34, T35, T36, T37, T38, T39> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40> +struct Types40 { + typedef T1 Head; + typedef Types39<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41> +struct Types41 { + typedef T1 Head; + typedef Types40<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42> +struct Types42 { + typedef T1 Head; + typedef Types41<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43> +struct Types43 { + typedef T1 Head; + typedef Types42<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, + T43> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43, typename T44> +struct Types44 { + typedef T1 Head; + typedef Types43<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, + T44> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43, typename T44, typename T45> +struct Types45 { + typedef T1 Head; + typedef Types44<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, + T44, T45> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43, typename T44, typename T45, + typename T46> +struct Types46 { + typedef T1 Head; + typedef Types45<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, + T44, T45, T46> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43, typename T44, typename T45, + typename T46, typename T47> +struct Types47 { + typedef T1 Head; + typedef Types46<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, + T44, T45, T46, T47> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43, typename T44, typename T45, + typename T46, typename T47, typename T48> +struct Types48 { + typedef T1 Head; + typedef Types47<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, + T44, T45, T46, T47, T48> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43, typename T44, typename T45, + typename T46, typename T47, typename T48, typename T49> +struct Types49 { + typedef T1 Head; + typedef Types48<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, + T44, T45, T46, T47, T48, T49> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43, typename T44, typename T45, + typename T46, typename T47, typename T48, typename T49, typename T50> +struct Types50 { + typedef T1 Head; + typedef Types49<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, + T44, T45, T46, T47, T48, T49, T50> Tail; +}; + + +} // namespace internal + +// We don't want to require the users to write TypesN<...> directly, +// as that would require them to count the length. Types<...> is much +// easier to write, but generates horrible messages when there is a +// compiler error, as gcc insists on printing out each template +// argument, even if it has the default value (this means Types<int> +// will appear as Types<int, None, None, ..., None> in the compiler +// errors). +// +// Our solution is to combine the best part of the two approaches: a +// user would write Types<T1, ..., TN>, and Google Test will translate +// that to TypesN<T1, ..., TN> internally to make error messages +// readable. The translation is done by the 'type' member of the +// Types template. +template <typename T1 = internal::None, typename T2 = internal::None, + typename T3 = internal::None, typename T4 = internal::None, + typename T5 = internal::None, typename T6 = internal::None, + typename T7 = internal::None, typename T8 = internal::None, + typename T9 = internal::None, typename T10 = internal::None, + typename T11 = internal::None, typename T12 = internal::None, + typename T13 = internal::None, typename T14 = internal::None, + typename T15 = internal::None, typename T16 = internal::None, + typename T17 = internal::None, typename T18 = internal::None, + typename T19 = internal::None, typename T20 = internal::None, + typename T21 = internal::None, typename T22 = internal::None, + typename T23 = internal::None, typename T24 = internal::None, + typename T25 = internal::None, typename T26 = internal::None, + typename T27 = internal::None, typename T28 = internal::None, + typename T29 = internal::None, typename T30 = internal::None, + typename T31 = internal::None, typename T32 = internal::None, + typename T33 = internal::None, typename T34 = internal::None, + typename T35 = internal::None, typename T36 = internal::None, + typename T37 = internal::None, typename T38 = internal::None, + typename T39 = internal::None, typename T40 = internal::None, + typename T41 = internal::None, typename T42 = internal::None, + typename T43 = internal::None, typename T44 = internal::None, + typename T45 = internal::None, typename T46 = internal::None, + typename T47 = internal::None, typename T48 = internal::None, + typename T49 = internal::None, typename T50 = internal::None> +struct Types { + typedef internal::Types50<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, + T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, + T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, + T41, T42, T43, T44, T45, T46, T47, T48, T49, T50> type; +}; + +template <> +struct Types<internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None> { + typedef internal::Types0 type; +}; +template <typename T1> +struct Types<T1, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None> { + typedef internal::Types1<T1> type; +}; +template <typename T1, typename T2> +struct Types<T1, T2, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None> { + typedef internal::Types2<T1, T2> type; +}; +template <typename T1, typename T2, typename T3> +struct Types<T1, T2, T3, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None> { + typedef internal::Types3<T1, T2, T3> type; +}; +template <typename T1, typename T2, typename T3, typename T4> +struct Types<T1, T2, T3, T4, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None> { + typedef internal::Types4<T1, T2, T3, T4> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5> +struct Types<T1, T2, T3, T4, T5, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None> { + typedef internal::Types5<T1, T2, T3, T4, T5> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6> +struct Types<T1, T2, T3, T4, T5, T6, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None> { + typedef internal::Types6<T1, T2, T3, T4, T5, T6> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7> +struct Types<T1, T2, T3, T4, T5, T6, T7, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None> { + typedef internal::Types7<T1, T2, T3, T4, T5, T6, T7> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None> { + typedef internal::Types8<T1, T2, T3, T4, T5, T6, T7, T8> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None> { + typedef internal::Types9<T1, T2, T3, T4, T5, T6, T7, T8, T9> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None> { + typedef internal::Types10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None> { + typedef internal::Types11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None> { + typedef internal::Types12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, + T12> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None> { + typedef internal::Types13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, + T13> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None> { + typedef internal::Types14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, + T13, T14> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None> { + typedef internal::Types15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, + T13, T14, T15> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None> { + typedef internal::Types16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, + T13, T14, T15, T16> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None> { + typedef internal::Types17<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, + T13, T14, T15, T16, T17> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None> { + typedef internal::Types18<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, + T13, T14, T15, T16, T17, T18> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None> { + typedef internal::Types19<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, + T13, T14, T15, T16, T17, T18, T19> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None> { + typedef internal::Types20<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, + T13, T14, T15, T16, T17, T18, T19, T20> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None> { + typedef internal::Types21<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, + T13, T14, T15, T16, T17, T18, T19, T20, T21> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None> { + typedef internal::Types22<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, + T13, T14, T15, T16, T17, T18, T19, T20, T21, T22> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None> { + typedef internal::Types23<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, + T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None> { + typedef internal::Types24<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, + T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None> { + typedef internal::Types25<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, + T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None> { + typedef internal::Types26<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, + T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, + T26> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None> { + typedef internal::Types27<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, + T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, + T27> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None> { + typedef internal::Types28<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, + T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, + T27, T28> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None> { + typedef internal::Types29<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, + T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, + T27, T28, T29> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None> { + typedef internal::Types30<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, + T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, + T27, T28, T29, T30> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, + T31, internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None> { + typedef internal::Types31<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, + T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, + T27, T28, T29, T30, T31> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, + T31, T32, internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None> { + typedef internal::Types32<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, + T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, + T27, T28, T29, T30, T31, T32> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, + T31, T32, T33, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None> { + typedef internal::Types33<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, + T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, + T27, T28, T29, T30, T31, T32, T33> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, + T31, T32, T33, T34, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None> { + typedef internal::Types34<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, + T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, + T27, T28, T29, T30, T31, T32, T33, T34> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, + T31, T32, T33, T34, T35, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None> { + typedef internal::Types35<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, + T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, + T27, T28, T29, T30, T31, T32, T33, T34, T35> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, + T31, T32, T33, T34, T35, T36, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None> { + typedef internal::Types36<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, + T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, + T27, T28, T29, T30, T31, T32, T33, T34, T35, T36> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, + T31, T32, T33, T34, T35, T36, T37, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None> { + typedef internal::Types37<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, + T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, + T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, + T31, T32, T33, T34, T35, T36, T37, T38, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None> { + typedef internal::Types38<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, + T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, + T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, + T31, T32, T33, T34, T35, T36, T37, T38, T39, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None> { + typedef internal::Types39<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, + T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, + T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, + T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None> { + typedef internal::Types40<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, + T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, + T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, + T40> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, + T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None> { + typedef internal::Types41<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, + T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, + T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, + T41> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, + T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None> { + typedef internal::Types42<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, + T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, + T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, + T41, T42> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, + T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None> { + typedef internal::Types43<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, + T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, + T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, + T41, T42, T43> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43, typename T44> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, + T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None> { + typedef internal::Types44<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, + T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, + T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, + T41, T42, T43, T44> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43, typename T44, typename T45> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, + T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, T45, + internal::None, internal::None, internal::None, internal::None, + internal::None> { + typedef internal::Types45<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, + T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, + T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, + T41, T42, T43, T44, T45> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43, typename T44, typename T45, + typename T46> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, + T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, T45, + T46, internal::None, internal::None, internal::None, internal::None> { + typedef internal::Types46<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, + T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, + T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, + T41, T42, T43, T44, T45, T46> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43, typename T44, typename T45, + typename T46, typename T47> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, + T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, T45, + T46, T47, internal::None, internal::None, internal::None> { + typedef internal::Types47<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, + T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, + T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, + T41, T42, T43, T44, T45, T46, T47> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43, typename T44, typename T45, + typename T46, typename T47, typename T48> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, + T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, T45, + T46, T47, T48, internal::None, internal::None> { + typedef internal::Types48<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, + T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, + T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, + T41, T42, T43, T44, T45, T46, T47, T48> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43, typename T44, typename T45, + typename T46, typename T47, typename T48, typename T49> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, + T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, T45, + T46, T47, T48, T49, internal::None> { + typedef internal::Types49<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, + T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, + T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, + T41, T42, T43, T44, T45, T46, T47, T48, T49> type; +}; + +namespace internal { + +#define GTEST_TEMPLATE_ template <typename T> class + +// The template "selector" struct TemplateSel<Tmpl> is used to +// represent Tmpl, which must be a class template with one type +// parameter, as a type. TemplateSel<Tmpl>::Bind<T>::type is defined +// as the type Tmpl<T>. This allows us to actually instantiate the +// template "selected" by TemplateSel<Tmpl>. +// +// This trick is necessary for simulating typedef for class templates, +// which C++ doesn't support directly. +template <GTEST_TEMPLATE_ Tmpl> +struct TemplateSel { + template <typename T> + struct Bind { + typedef Tmpl<T> type; + }; +}; + +#define GTEST_BIND_(TmplSel, T) \ + TmplSel::template Bind<T>::type + +// A unique struct template used as the default value for the +// arguments of class template Templates. This allows us to simulate +// variadic templates (e.g. Templates<int>, Templates<int, double>, +// and etc), which C++ doesn't support directly. +template <typename T> +struct NoneT {}; + +// The following family of struct and struct templates are used to +// represent template lists. In particular, TemplatesN<T1, T2, ..., +// TN> represents a list of N templates (T1, T2, ..., and TN). Except +// for Templates0, every struct in the family has two member types: +// Head for the selector of the first template in the list, and Tail +// for the rest of the list. + +// The empty template list. +struct Templates0 {}; + +// Template lists of length 1, 2, 3, and so on. + +template <GTEST_TEMPLATE_ T1> +struct Templates1 { + typedef TemplateSel<T1> Head; + typedef Templates0 Tail; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2> +struct Templates2 { + typedef TemplateSel<T1> Head; + typedef Templates1<T2> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3> +struct Templates3 { + typedef TemplateSel<T1> Head; + typedef Templates2<T2, T3> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4> +struct Templates4 { + typedef TemplateSel<T1> Head; + typedef Templates3<T2, T3, T4> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5> +struct Templates5 { + typedef TemplateSel<T1> Head; + typedef Templates4<T2, T3, T4, T5> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6> +struct Templates6 { + typedef TemplateSel<T1> Head; + typedef Templates5<T2, T3, T4, T5, T6> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7> +struct Templates7 { + typedef TemplateSel<T1> Head; + typedef Templates6<T2, T3, T4, T5, T6, T7> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8> +struct Templates8 { + typedef TemplateSel<T1> Head; + typedef Templates7<T2, T3, T4, T5, T6, T7, T8> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9> +struct Templates9 { + typedef TemplateSel<T1> Head; + typedef Templates8<T2, T3, T4, T5, T6, T7, T8, T9> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10> +struct Templates10 { + typedef TemplateSel<T1> Head; + typedef Templates9<T2, T3, T4, T5, T6, T7, T8, T9, T10> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11> +struct Templates11 { + typedef TemplateSel<T1> Head; + typedef Templates10<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12> +struct Templates12 { + typedef TemplateSel<T1> Head; + typedef Templates11<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13> +struct Templates13 { + typedef TemplateSel<T1> Head; + typedef Templates12<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14> +struct Templates14 { + typedef TemplateSel<T1> Head; + typedef Templates13<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15> +struct Templates15 { + typedef TemplateSel<T1> Head; + typedef Templates14<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16> +struct Templates16 { + typedef TemplateSel<T1> Head; + typedef Templates15<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17> +struct Templates17 { + typedef TemplateSel<T1> Head; + typedef Templates16<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18> +struct Templates18 { + typedef TemplateSel<T1> Head; + typedef Templates17<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19> +struct Templates19 { + typedef TemplateSel<T1> Head; + typedef Templates18<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20> +struct Templates20 { + typedef TemplateSel<T1> Head; + typedef Templates19<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21> +struct Templates21 { + typedef TemplateSel<T1> Head; + typedef Templates20<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22> +struct Templates22 { + typedef TemplateSel<T1> Head; + typedef Templates21<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23> +struct Templates23 { + typedef TemplateSel<T1> Head; + typedef Templates22<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24> +struct Templates24 { + typedef TemplateSel<T1> Head; + typedef Templates23<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25> +struct Templates25 { + typedef TemplateSel<T1> Head; + typedef Templates24<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26> +struct Templates26 { + typedef TemplateSel<T1> Head; + typedef Templates25<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27> +struct Templates27 { + typedef TemplateSel<T1> Head; + typedef Templates26<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28> +struct Templates28 { + typedef TemplateSel<T1> Head; + typedef Templates27<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, + T28> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29> +struct Templates29 { + typedef TemplateSel<T1> Head; + typedef Templates28<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30> +struct Templates30 { + typedef TemplateSel<T1> Head; + typedef Templates29<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31> +struct Templates31 { + typedef TemplateSel<T1> Head; + typedef Templates30<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32> +struct Templates32 { + typedef TemplateSel<T1> Head; + typedef Templates31<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33> +struct Templates33 { + typedef TemplateSel<T1> Head; + typedef Templates32<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34> +struct Templates34 { + typedef TemplateSel<T1> Head; + typedef Templates33<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35> +struct Templates35 { + typedef TemplateSel<T1> Head; + typedef Templates34<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34, T35> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36> +struct Templates36 { + typedef TemplateSel<T1> Head; + typedef Templates35<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34, T35, T36> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, + GTEST_TEMPLATE_ T37> +struct Templates37 { + typedef TemplateSel<T1> Head; + typedef Templates36<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34, T35, T36, T37> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, + GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38> +struct Templates38 { + typedef TemplateSel<T1> Head; + typedef Templates37<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34, T35, T36, T37, T38> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, + GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39> +struct Templates39 { + typedef TemplateSel<T1> Head; + typedef Templates38<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, + GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, + GTEST_TEMPLATE_ T40> +struct Templates40 { + typedef TemplateSel<T1> Head; + typedef Templates39<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, + GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, + GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41> +struct Templates41 { + typedef TemplateSel<T1> Head; + typedef Templates40<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, + GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, + GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42> +struct Templates42 { + typedef TemplateSel<T1> Head; + typedef Templates41<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, + T42> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, + GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, + GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42, + GTEST_TEMPLATE_ T43> +struct Templates43 { + typedef TemplateSel<T1> Head; + typedef Templates42<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, + T43> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, + GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, + GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42, + GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44> +struct Templates44 { + typedef TemplateSel<T1> Head; + typedef Templates43<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, + T43, T44> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, + GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, + GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42, + GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45> +struct Templates45 { + typedef TemplateSel<T1> Head; + typedef Templates44<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, + T43, T44, T45> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, + GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, + GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42, + GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45, + GTEST_TEMPLATE_ T46> +struct Templates46 { + typedef TemplateSel<T1> Head; + typedef Templates45<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, + T43, T44, T45, T46> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, + GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, + GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42, + GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45, + GTEST_TEMPLATE_ T46, GTEST_TEMPLATE_ T47> +struct Templates47 { + typedef TemplateSel<T1> Head; + typedef Templates46<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, + T43, T44, T45, T46, T47> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, + GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, + GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42, + GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45, + GTEST_TEMPLATE_ T46, GTEST_TEMPLATE_ T47, GTEST_TEMPLATE_ T48> +struct Templates48 { + typedef TemplateSel<T1> Head; + typedef Templates47<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, + T43, T44, T45, T46, T47, T48> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, + GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, + GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42, + GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45, + GTEST_TEMPLATE_ T46, GTEST_TEMPLATE_ T47, GTEST_TEMPLATE_ T48, + GTEST_TEMPLATE_ T49> +struct Templates49 { + typedef TemplateSel<T1> Head; + typedef Templates48<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, + T43, T44, T45, T46, T47, T48, T49> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, + GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, + GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42, + GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45, + GTEST_TEMPLATE_ T46, GTEST_TEMPLATE_ T47, GTEST_TEMPLATE_ T48, + GTEST_TEMPLATE_ T49, GTEST_TEMPLATE_ T50> +struct Templates50 { + typedef TemplateSel<T1> Head; + typedef Templates49<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, + T43, T44, T45, T46, T47, T48, T49, T50> Tail; +}; + + +// We don't want to require the users to write TemplatesN<...> directly, +// as that would require them to count the length. Templates<...> is much +// easier to write, but generates horrible messages when there is a +// compiler error, as gcc insists on printing out each template +// argument, even if it has the default value (this means Templates<list> +// will appear as Templates<list, NoneT, NoneT, ..., NoneT> in the compiler +// errors). +// +// Our solution is to combine the best part of the two approaches: a +// user would write Templates<T1, ..., TN>, and Google Test will translate +// that to TemplatesN<T1, ..., TN> internally to make error messages +// readable. The translation is done by the 'type' member of the +// Templates template. +template <GTEST_TEMPLATE_ T1 = NoneT, GTEST_TEMPLATE_ T2 = NoneT, + GTEST_TEMPLATE_ T3 = NoneT, GTEST_TEMPLATE_ T4 = NoneT, + GTEST_TEMPLATE_ T5 = NoneT, GTEST_TEMPLATE_ T6 = NoneT, + GTEST_TEMPLATE_ T7 = NoneT, GTEST_TEMPLATE_ T8 = NoneT, + GTEST_TEMPLATE_ T9 = NoneT, GTEST_TEMPLATE_ T10 = NoneT, + GTEST_TEMPLATE_ T11 = NoneT, GTEST_TEMPLATE_ T12 = NoneT, + GTEST_TEMPLATE_ T13 = NoneT, GTEST_TEMPLATE_ T14 = NoneT, + GTEST_TEMPLATE_ T15 = NoneT, GTEST_TEMPLATE_ T16 = NoneT, + GTEST_TEMPLATE_ T17 = NoneT, GTEST_TEMPLATE_ T18 = NoneT, + GTEST_TEMPLATE_ T19 = NoneT, GTEST_TEMPLATE_ T20 = NoneT, + GTEST_TEMPLATE_ T21 = NoneT, GTEST_TEMPLATE_ T22 = NoneT, + GTEST_TEMPLATE_ T23 = NoneT, GTEST_TEMPLATE_ T24 = NoneT, + GTEST_TEMPLATE_ T25 = NoneT, GTEST_TEMPLATE_ T26 = NoneT, + GTEST_TEMPLATE_ T27 = NoneT, GTEST_TEMPLATE_ T28 = NoneT, + GTEST_TEMPLATE_ T29 = NoneT, GTEST_TEMPLATE_ T30 = NoneT, + GTEST_TEMPLATE_ T31 = NoneT, GTEST_TEMPLATE_ T32 = NoneT, + GTEST_TEMPLATE_ T33 = NoneT, GTEST_TEMPLATE_ T34 = NoneT, + GTEST_TEMPLATE_ T35 = NoneT, GTEST_TEMPLATE_ T36 = NoneT, + GTEST_TEMPLATE_ T37 = NoneT, GTEST_TEMPLATE_ T38 = NoneT, + GTEST_TEMPLATE_ T39 = NoneT, GTEST_TEMPLATE_ T40 = NoneT, + GTEST_TEMPLATE_ T41 = NoneT, GTEST_TEMPLATE_ T42 = NoneT, + GTEST_TEMPLATE_ T43 = NoneT, GTEST_TEMPLATE_ T44 = NoneT, + GTEST_TEMPLATE_ T45 = NoneT, GTEST_TEMPLATE_ T46 = NoneT, + GTEST_TEMPLATE_ T47 = NoneT, GTEST_TEMPLATE_ T48 = NoneT, + GTEST_TEMPLATE_ T49 = NoneT, GTEST_TEMPLATE_ T50 = NoneT> +struct Templates { + typedef Templates50<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, + T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, + T42, T43, T44, T45, T46, T47, T48, T49, T50> type; +}; + +template <> +struct Templates<NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT> { + typedef Templates0 type; +}; +template <GTEST_TEMPLATE_ T1> +struct Templates<T1, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT> { + typedef Templates1<T1> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2> +struct Templates<T1, T2, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT> { + typedef Templates2<T1, T2> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3> +struct Templates<T1, T2, T3, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { + typedef Templates3<T1, T2, T3> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4> +struct Templates<T1, T2, T3, T4, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { + typedef Templates4<T1, T2, T3, T4> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5> +struct Templates<T1, T2, T3, T4, T5, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { + typedef Templates5<T1, T2, T3, T4, T5> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6> +struct Templates<T1, T2, T3, T4, T5, T6, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { + typedef Templates6<T1, T2, T3, T4, T5, T6> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7> +struct Templates<T1, T2, T3, T4, T5, T6, T7, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { + typedef Templates7<T1, T2, T3, T4, T5, T6, T7> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { + typedef Templates8<T1, T2, T3, T4, T5, T6, T7, T8> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { + typedef Templates9<T1, T2, T3, T4, T5, T6, T7, T8, T9> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { + typedef Templates10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { + typedef Templates11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { + typedef Templates12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { + typedef Templates13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, + T13> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { + typedef Templates14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT> { + typedef Templates15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT> { + typedef Templates16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT> { + typedef Templates17<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT> { + typedef Templates18<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT> { + typedef Templates19<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT> { + typedef Templates20<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT> { + typedef Templates21<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT> { + typedef Templates22<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT> { + typedef Templates23<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT> { + typedef Templates24<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT> { + typedef Templates25<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT> { + typedef Templates26<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT> { + typedef Templates27<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, + T27> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT> { + typedef Templates28<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, + T28> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT> { + typedef Templates29<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, + T28, T29> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { + typedef Templates30<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, + T28, T29, T30> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { + typedef Templates31<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, + T28, T29, T30, T31> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { + typedef Templates32<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, + T28, T29, T30, T31, T32> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { + typedef Templates33<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, + T28, T29, T30, T31, T32, T33> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33, T34, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { + typedef Templates34<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, + T28, T29, T30, T31, T32, T33, T34> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33, T34, T35, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { + typedef Templates35<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, + T28, T29, T30, T31, T32, T33, T34, T35> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33, T34, T35, T36, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { + typedef Templates36<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, + T28, T29, T30, T31, T32, T33, T34, T35, T36> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, + GTEST_TEMPLATE_ T37> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33, T34, T35, T36, T37, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { + typedef Templates37<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, + T28, T29, T30, T31, T32, T33, T34, T35, T36, T37> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, + GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33, T34, T35, T36, T37, T38, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { + typedef Templates38<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, + T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, + GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { + typedef Templates39<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, + T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, + GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, + GTEST_TEMPLATE_ T40> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { + typedef Templates40<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, + T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, + GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, + GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { + typedef Templates41<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, + T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, + T41> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, + GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, + GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { + typedef Templates42<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, + T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, + T42> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, + GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, + GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42, + GTEST_TEMPLATE_ T43> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { + typedef Templates43<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, + T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, + T42, T43> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, + GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, + GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42, + GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { + typedef Templates44<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, + T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, + T42, T43, T44> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, + GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, + GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42, + GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, + T45, NoneT, NoneT, NoneT, NoneT, NoneT> { + typedef Templates45<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, + T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, + T42, T43, T44, T45> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, + GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, + GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42, + GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45, + GTEST_TEMPLATE_ T46> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, + T45, T46, NoneT, NoneT, NoneT, NoneT> { + typedef Templates46<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, + T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, + T42, T43, T44, T45, T46> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, + GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, + GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42, + GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45, + GTEST_TEMPLATE_ T46, GTEST_TEMPLATE_ T47> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, + T45, T46, T47, NoneT, NoneT, NoneT> { + typedef Templates47<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, + T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, + T42, T43, T44, T45, T46, T47> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, + GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, + GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42, + GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45, + GTEST_TEMPLATE_ T46, GTEST_TEMPLATE_ T47, GTEST_TEMPLATE_ T48> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, + T45, T46, T47, T48, NoneT, NoneT> { + typedef Templates48<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, + T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, + T42, T43, T44, T45, T46, T47, T48> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, + GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, + GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42, + GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45, + GTEST_TEMPLATE_ T46, GTEST_TEMPLATE_ T47, GTEST_TEMPLATE_ T48, + GTEST_TEMPLATE_ T49> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, + T45, T46, T47, T48, T49, NoneT> { + typedef Templates49<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, + T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, + T42, T43, T44, T45, T46, T47, T48, T49> type; +}; + +// The TypeList template makes it possible to use either a single type +// or a Types<...> list in TYPED_TEST_CASE() and +// INSTANTIATE_TYPED_TEST_CASE_P(). + +template <typename T> +struct TypeList { typedef Types1<T> type; }; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43, typename T44, typename T45, + typename T46, typename T47, typename T48, typename T49, typename T50> +struct TypeList<Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, + T44, T45, T46, T47, T48, T49, T50> > { + typedef typename Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, + T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, + T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, + T41, T42, T43, T44, T45, T46, T47, T48, T49, T50>::type type; +}; + +} // namespace internal +} // namespace testing + +#endif // GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ + +// Due to C++ preprocessor weirdness, we need double indirection to +// concatenate two tokens when one of them is __LINE__. Writing +// +// foo ## __LINE__ +// +// will result in the token foo__LINE__, instead of foo followed by +// the current line number. For more details, see +// http://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.6 +#define GTEST_CONCAT_TOKEN_(foo, bar) GTEST_CONCAT_TOKEN_IMPL_(foo, bar) +#define GTEST_CONCAT_TOKEN_IMPL_(foo, bar) foo ## bar + +// Google Test defines the testing::Message class to allow construction of +// test messages via the << operator. The idea is that anything +// streamable to std::ostream can be streamed to a testing::Message. +// This allows a user to use his own types in Google Test assertions by +// overloading the << operator. +// +// util/gtl/stl_logging-inl.h overloads << for STL containers. These +// overloads cannot be defined in the std namespace, as that will be +// undefined behavior. Therefore, they are defined in the global +// namespace instead. +// +// C++'s symbol lookup rule (i.e. Koenig lookup) says that these +// overloads are visible in either the std namespace or the global +// namespace, but not other namespaces, including the testing +// namespace which Google Test's Message class is in. +// +// To allow STL containers (and other types that has a << operator +// defined in the global namespace) to be used in Google Test assertions, +// testing::Message must access the custom << operator from the global +// namespace. Hence this helper function. +// +// Note: Jeffrey Yasskin suggested an alternative fix by "using +// ::operator<<;" in the definition of Message's operator<<. That fix +// doesn't require a helper function, but unfortunately doesn't +// compile with MSVC. +template <typename T> +inline void GTestStreamToHelper(std::ostream* os, const T& val) { + *os << val; +} + +namespace testing { + +// Forward declaration of classes. + +class AssertionResult; // Result of an assertion. +class Message; // Represents a failure message. +class Test; // Represents a test. +class TestInfo; // Information about a test. +class TestPartResult; // Result of a test part. +class UnitTest; // A collection of test cases. + +namespace internal { + +struct TraceInfo; // Information about a trace point. +class ScopedTrace; // Implements scoped trace. +class TestInfoImpl; // Opaque implementation of TestInfo +class UnitTestImpl; // Opaque implementation of UnitTest + +// How many times InitGoogleTest() has been called. +extern int g_init_gtest_count; + +// The text used in failure messages to indicate the start of the +// stack trace. +GTEST_API_ extern const char kStackTraceMarker[]; + +// A secret type that Google Test users don't know about. It has no +// definition on purpose. Therefore it's impossible to create a +// Secret object, which is what we want. +class Secret; + +// Two overloaded helpers for checking at compile time whether an +// expression is a null pointer literal (i.e. NULL or any 0-valued +// compile-time integral constant). Their return values have +// different sizes, so we can use sizeof() to test which version is +// picked by the compiler. These helpers have no implementations, as +// we only need their signatures. +// +// Given IsNullLiteralHelper(x), the compiler will pick the first +// version if x can be implicitly converted to Secret*, and pick the +// second version otherwise. Since Secret is a secret and incomplete +// type, the only expression a user can write that has type Secret* is +// a null pointer literal. Therefore, we know that x is a null +// pointer literal if and only if the first version is picked by the +// compiler. +char IsNullLiteralHelper(Secret* p); +char (&IsNullLiteralHelper(...))[2]; // NOLINT + +// A compile-time bool constant that is true if and only if x is a +// null pointer literal (i.e. NULL or any 0-valued compile-time +// integral constant). +#ifdef GTEST_ELLIPSIS_NEEDS_POD_ +// We lose support for NULL detection where the compiler doesn't like +// passing non-POD classes through ellipsis (...). +#define GTEST_IS_NULL_LITERAL_(x) false +#else +#define GTEST_IS_NULL_LITERAL_(x) \ + (sizeof(::testing::internal::IsNullLiteralHelper(x)) == 1) +#endif // GTEST_ELLIPSIS_NEEDS_POD_ + +// Appends the user-supplied message to the Google-Test-generated message. +GTEST_API_ String AppendUserMessage(const String& gtest_msg, + const Message& user_msg); + +// A helper class for creating scoped traces in user programs. +class GTEST_API_ ScopedTrace { + public: + // The c'tor pushes the given source file location and message onto + // a trace stack maintained by Google Test. + ScopedTrace(const char* file, int line, const Message& message); + + // The d'tor pops the info pushed by the c'tor. + // + // Note that the d'tor is not virtual in order to be efficient. + // Don't inherit from ScopedTrace! + ~ScopedTrace(); + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedTrace); +} GTEST_ATTRIBUTE_UNUSED_; // A ScopedTrace object does its job in its + // c'tor and d'tor. Therefore it doesn't + // need to be used otherwise. + +// Converts a streamable value to a String. A NULL pointer is +// converted to "(null)". When the input value is a ::string, +// ::std::string, ::wstring, or ::std::wstring object, each NUL +// character in it is replaced with "\\0". +// Declared here but defined in gtest.h, so that it has access +// to the definition of the Message class, required by the ARM +// compiler. +template <typename T> +String StreamableToString(const T& streamable); + +// Formats a value to be used in a failure message. + +#ifdef GTEST_NEEDS_IS_POINTER_ + +// These are needed as the Nokia Symbian and IBM XL C/C++ compilers +// cannot decide between const T& and const T* in a function template. +// These compilers _can_ decide between class template specializations +// for T and T*, so a tr1::type_traits-like is_pointer works, and we +// can overload on that. + +// This overload makes sure that all pointers (including +// those to char or wchar_t) are printed as raw pointers. +template <typename T> +inline String FormatValueForFailureMessage(internal::true_type /*dummy*/, + T* pointer) { + return StreamableToString(static_cast<const void*>(pointer)); +} + +template <typename T> +inline String FormatValueForFailureMessage(internal::false_type /*dummy*/, + const T& value) { + return StreamableToString(value); +} + +template <typename T> +inline String FormatForFailureMessage(const T& value) { + return FormatValueForFailureMessage( + typename internal::is_pointer<T>::type(), value); +} + +#else + +// These are needed as the above solution using is_pointer has the +// limitation that T cannot be a type without external linkage, when +// compiled using MSVC. + +template <typename T> +inline String FormatForFailureMessage(const T& value) { + return StreamableToString(value); +} + +// This overload makes sure that all pointers (including +// those to char or wchar_t) are printed as raw pointers. +template <typename T> +inline String FormatForFailureMessage(T* pointer) { + return StreamableToString(static_cast<const void*>(pointer)); +} + +#endif // GTEST_NEEDS_IS_POINTER_ + +// These overloaded versions handle narrow and wide characters. +GTEST_API_ String FormatForFailureMessage(char ch); +GTEST_API_ String FormatForFailureMessage(wchar_t wchar); + +// When this operand is a const char* or char*, and the other operand +// is a ::std::string or ::string, we print this operand as a C string +// rather than a pointer. We do the same for wide strings. + +// This internal macro is used to avoid duplicated code. +#define GTEST_FORMAT_IMPL_(operand2_type, operand1_printer)\ +inline String FormatForComparisonFailureMessage(\ + operand2_type::value_type* str, const operand2_type& /*operand2*/) {\ + return operand1_printer(str);\ +}\ +inline String FormatForComparisonFailureMessage(\ + const operand2_type::value_type* str, const operand2_type& /*operand2*/) {\ + return operand1_printer(str);\ +} + +GTEST_FORMAT_IMPL_(::std::string, String::ShowCStringQuoted) +#if GTEST_HAS_STD_WSTRING +GTEST_FORMAT_IMPL_(::std::wstring, String::ShowWideCStringQuoted) +#endif // GTEST_HAS_STD_WSTRING + +#if GTEST_HAS_GLOBAL_STRING +GTEST_FORMAT_IMPL_(::string, String::ShowCStringQuoted) +#endif // GTEST_HAS_GLOBAL_STRING +#if GTEST_HAS_GLOBAL_WSTRING +GTEST_FORMAT_IMPL_(::wstring, String::ShowWideCStringQuoted) +#endif // GTEST_HAS_GLOBAL_WSTRING + +#undef GTEST_FORMAT_IMPL_ + +// Constructs and returns the message for an equality assertion +// (e.g. ASSERT_EQ, EXPECT_STREQ, etc) failure. +// +// The first four parameters are the expressions used in the assertion +// and their values, as strings. For example, for ASSERT_EQ(foo, bar) +// where foo is 5 and bar is 6, we have: +// +// expected_expression: "foo" +// actual_expression: "bar" +// expected_value: "5" +// actual_value: "6" +// +// The ignoring_case parameter is true iff the assertion is a +// *_STRCASEEQ*. When it's true, the string " (ignoring case)" will +// be inserted into the message. +GTEST_API_ AssertionResult EqFailure(const char* expected_expression, + const char* actual_expression, + const String& expected_value, + const String& actual_value, + bool ignoring_case); + +// Constructs a failure message for Boolean assertions such as EXPECT_TRUE. +GTEST_API_ String GetBoolAssertionFailureMessage( + const AssertionResult& assertion_result, + const char* expression_text, + const char* actual_predicate_value, + const char* expected_predicate_value); + +// This template class represents an IEEE floating-point number +// (either single-precision or double-precision, depending on the +// template parameters). +// +// The purpose of this class is to do more sophisticated number +// comparison. (Due to round-off error, etc, it's very unlikely that +// two floating-points will be equal exactly. Hence a naive +// comparison by the == operation often doesn't work.) +// +// Format of IEEE floating-point: +// +// The most-significant bit being the leftmost, an IEEE +// floating-point looks like +// +// sign_bit exponent_bits fraction_bits +// +// Here, sign_bit is a single bit that designates the sign of the +// number. +// +// For float, there are 8 exponent bits and 23 fraction bits. +// +// For double, there are 11 exponent bits and 52 fraction bits. +// +// More details can be found at +// http://en.wikipedia.org/wiki/IEEE_floating-point_standard. +// +// Template parameter: +// +// RawType: the raw floating-point type (either float or double) +template <typename RawType> +class FloatingPoint { + public: + // Defines the unsigned integer type that has the same size as the + // floating point number. + typedef typename TypeWithSize<sizeof(RawType)>::UInt Bits; + + // Constants. + + // # of bits in a number. + static const size_t kBitCount = 8*sizeof(RawType); + + // # of fraction bits in a number. + static const size_t kFractionBitCount = + std::numeric_limits<RawType>::digits - 1; + + // # of exponent bits in a number. + static const size_t kExponentBitCount = kBitCount - 1 - kFractionBitCount; + + // The mask for the sign bit. + static const Bits kSignBitMask = static_cast<Bits>(1) << (kBitCount - 1); + + // The mask for the fraction bits. + static const Bits kFractionBitMask = + ~static_cast<Bits>(0) >> (kExponentBitCount + 1); + + // The mask for the exponent bits. + static const Bits kExponentBitMask = ~(kSignBitMask | kFractionBitMask); + + // How many ULP's (Units in the Last Place) we want to tolerate when + // comparing two numbers. The larger the value, the more error we + // allow. A 0 value means that two numbers must be exactly the same + // to be considered equal. + // + // The maximum error of a single floating-point operation is 0.5 + // units in the last place. On Intel CPU's, all floating-point + // calculations are done with 80-bit precision, while double has 64 + // bits. Therefore, 4 should be enough for ordinary use. + // + // See the following article for more details on ULP: + // http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm. + static const size_t kMaxUlps = 4; + + // Constructs a FloatingPoint from a raw floating-point number. + // + // On an Intel CPU, passing a non-normalized NAN (Not a Number) + // around may change its bits, although the new value is guaranteed + // to be also a NAN. Therefore, don't expect this constructor to + // preserve the bits in x when x is a NAN. + explicit FloatingPoint(const RawType& x) { u_.value_ = x; } + + // Static methods + + // Reinterprets a bit pattern as a floating-point number. + // + // This function is needed to test the AlmostEquals() method. + static RawType ReinterpretBits(const Bits bits) { + FloatingPoint fp(0); + fp.u_.bits_ = bits; + return fp.u_.value_; + } + + // Returns the floating-point number that represent positive infinity. + static RawType Infinity() { + return ReinterpretBits(kExponentBitMask); + } + + // Non-static methods + + // Returns the bits that represents this number. + const Bits &bits() const { return u_.bits_; } + + // Returns the exponent bits of this number. + Bits exponent_bits() const { return kExponentBitMask & u_.bits_; } + + // Returns the fraction bits of this number. + Bits fraction_bits() const { return kFractionBitMask & u_.bits_; } + + // Returns the sign bit of this number. + Bits sign_bit() const { return kSignBitMask & u_.bits_; } + + // Returns true iff this is NAN (not a number). + bool is_nan() const { + // It's a NAN if the exponent bits are all ones and the fraction + // bits are not entirely zeros. + return (exponent_bits() == kExponentBitMask) && (fraction_bits() != 0); + } + + // Returns true iff this number is at most kMaxUlps ULP's away from + // rhs. In particular, this function: + // + // - returns false if either number is (or both are) NAN. + // - treats really large numbers as almost equal to infinity. + // - thinks +0.0 and -0.0 are 0 DLP's apart. + bool AlmostEquals(const FloatingPoint& rhs) const { + // The IEEE standard says that any comparison operation involving + // a NAN must return false. + if (is_nan() || rhs.is_nan()) return false; + + return DistanceBetweenSignAndMagnitudeNumbers(u_.bits_, rhs.u_.bits_) + <= kMaxUlps; + } + + private: + // The data type used to store the actual floating-point number. + union FloatingPointUnion { + RawType value_; // The raw floating-point number. + Bits bits_; // The bits that represent the number. + }; + + // Converts an integer from the sign-and-magnitude representation to + // the biased representation. More precisely, let N be 2 to the + // power of (kBitCount - 1), an integer x is represented by the + // unsigned number x + N. + // + // For instance, + // + // -N + 1 (the most negative number representable using + // sign-and-magnitude) is represented by 1; + // 0 is represented by N; and + // N - 1 (the biggest number representable using + // sign-and-magnitude) is represented by 2N - 1. + // + // Read http://en.wikipedia.org/wiki/Signed_number_representations + // for more details on signed number representations. + static Bits SignAndMagnitudeToBiased(const Bits &sam) { + if (kSignBitMask & sam) { + // sam represents a negative number. + return ~sam + 1; + } else { + // sam represents a positive number. + return kSignBitMask | sam; + } + } + + // Given two numbers in the sign-and-magnitude representation, + // returns the distance between them as an unsigned number. + static Bits DistanceBetweenSignAndMagnitudeNumbers(const Bits &sam1, + const Bits &sam2) { + const Bits biased1 = SignAndMagnitudeToBiased(sam1); + const Bits biased2 = SignAndMagnitudeToBiased(sam2); + return (biased1 >= biased2) ? (biased1 - biased2) : (biased2 - biased1); + } + + FloatingPointUnion u_; +}; + +// Typedefs the instances of the FloatingPoint template class that we +// care to use. +typedef FloatingPoint<float> Float; +typedef FloatingPoint<double> Double; + +// In order to catch the mistake of putting tests that use different +// test fixture classes in the same test case, we need to assign +// unique IDs to fixture classes and compare them. The TypeId type is +// used to hold such IDs. The user should treat TypeId as an opaque +// type: the only operation allowed on TypeId values is to compare +// them for equality using the == operator. +typedef const void* TypeId; + +template <typename T> +class TypeIdHelper { + public: + // dummy_ must not have a const type. Otherwise an overly eager + // compiler (e.g. MSVC 7.1 & 8.0) may try to merge + // TypeIdHelper<T>::dummy_ for different Ts as an "optimization". + static bool dummy_; +}; + +template <typename T> +bool TypeIdHelper<T>::dummy_ = false; + +// GetTypeId<T>() returns the ID of type T. Different values will be +// returned for different types. Calling the function twice with the +// same type argument is guaranteed to return the same ID. +template <typename T> +TypeId GetTypeId() { + // The compiler is required to allocate a different + // TypeIdHelper<T>::dummy_ variable for each T used to instantiate + // the template. Therefore, the address of dummy_ is guaranteed to + // be unique. + return &(TypeIdHelper<T>::dummy_); +} + +// Returns the type ID of ::testing::Test. Always call this instead +// of GetTypeId< ::testing::Test>() to get the type ID of +// ::testing::Test, as the latter may give the wrong result due to a +// suspected linker bug when compiling Google Test as a Mac OS X +// framework. +GTEST_API_ TypeId GetTestTypeId(); + +// Defines the abstract factory interface that creates instances +// of a Test object. +class TestFactoryBase { + public: + virtual ~TestFactoryBase() {} + + // Creates a test instance to run. The instance is both created and destroyed + // within TestInfoImpl::Run() + virtual Test* CreateTest() = 0; + + protected: + TestFactoryBase() {} + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestFactoryBase); +}; + +// This class provides implementation of TeastFactoryBase interface. +// It is used in TEST and TEST_F macros. +template <class TestClass> +class TestFactoryImpl : public TestFactoryBase { + public: + virtual Test* CreateTest() { return new TestClass; } +}; + +#if GTEST_OS_WINDOWS + +// Predicate-formatters for implementing the HRESULT checking macros +// {ASSERT|EXPECT}_HRESULT_{SUCCEEDED|FAILED} +// We pass a long instead of HRESULT to avoid causing an +// include dependency for the HRESULT type. +GTEST_API_ AssertionResult IsHRESULTSuccess(const char* expr, + long hr); // NOLINT +GTEST_API_ AssertionResult IsHRESULTFailure(const char* expr, + long hr); // NOLINT + +#endif // GTEST_OS_WINDOWS + +// Formats a source file path and a line number as they would appear +// in a compiler error message. +inline String FormatFileLocation(const char* file, int line) { + const char* const file_name = file == NULL ? "unknown file" : file; + if (line < 0) { + return String::Format("%s:", file_name); + } +#ifdef _MSC_VER + return String::Format("%s(%d):", file_name, line); +#else + return String::Format("%s:%d:", file_name, line); +#endif // _MSC_VER +} + +// Types of SetUpTestCase() and TearDownTestCase() functions. +typedef void (*SetUpTestCaseFunc)(); +typedef void (*TearDownTestCaseFunc)(); + +// Creates a new TestInfo object and registers it with Google Test; +// returns the created object. +// +// Arguments: +// +// test_case_name: name of the test case +// name: name of the test +// test_case_comment: a comment on the test case that will be included in +// the test output +// comment: a comment on the test that will be included in the +// test output +// fixture_class_id: ID of the test fixture class +// set_up_tc: pointer to the function that sets up the test case +// tear_down_tc: pointer to the function that tears down the test case +// factory: pointer to the factory that creates a test object. +// The newly created TestInfo instance will assume +// ownership of the factory object. +GTEST_API_ TestInfo* MakeAndRegisterTestInfo( + const char* test_case_name, const char* name, + const char* test_case_comment, const char* comment, + TypeId fixture_class_id, + SetUpTestCaseFunc set_up_tc, + TearDownTestCaseFunc tear_down_tc, + TestFactoryBase* factory); + +// If *pstr starts with the given prefix, modifies *pstr to be right +// past the prefix and returns true; otherwise leaves *pstr unchanged +// and returns false. None of pstr, *pstr, and prefix can be NULL. +bool SkipPrefix(const char* prefix, const char** pstr); + +#if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P + +// State of the definition of a type-parameterized test case. +class GTEST_API_ TypedTestCasePState { + public: + TypedTestCasePState() : registered_(false) {} + + // Adds the given test name to defined_test_names_ and return true + // if the test case hasn't been registered; otherwise aborts the + // program. + bool AddTestName(const char* file, int line, const char* case_name, + const char* test_name) { + if (registered_) { + fprintf(stderr, "%s Test %s must be defined before " + "REGISTER_TYPED_TEST_CASE_P(%s, ...).\n", + FormatFileLocation(file, line).c_str(), test_name, case_name); + fflush(stderr); + posix::Abort(); + } + defined_test_names_.insert(test_name); + return true; + } + + // Verifies that registered_tests match the test names in + // defined_test_names_; returns registered_tests if successful, or + // aborts the program otherwise. + const char* VerifyRegisteredTestNames( + const char* file, int line, const char* registered_tests); + + private: + bool registered_; + ::std::set<const char*> defined_test_names_; +}; + +// Skips to the first non-space char after the first comma in 'str'; +// returns NULL if no comma is found in 'str'. +inline const char* SkipComma(const char* str) { + const char* comma = strchr(str, ','); + if (comma == NULL) { + return NULL; + } + while (isspace(*(++comma))) {} + return comma; +} + +// Returns the prefix of 'str' before the first comma in it; returns +// the entire string if it contains no comma. +inline String GetPrefixUntilComma(const char* str) { + const char* comma = strchr(str, ','); + return comma == NULL ? String(str) : String(str, comma - str); +} + +// TypeParameterizedTest<Fixture, TestSel, Types>::Register() +// registers a list of type-parameterized tests with Google Test. The +// return value is insignificant - we just need to return something +// such that we can call this function in a namespace scope. +// +// Implementation note: The GTEST_TEMPLATE_ macro declares a template +// template parameter. It's defined in gtest-type-util.h. +template <GTEST_TEMPLATE_ Fixture, class TestSel, typename Types> +class TypeParameterizedTest { + public: + // 'index' is the index of the test in the type list 'Types' + // specified in INSTANTIATE_TYPED_TEST_CASE_P(Prefix, TestCase, + // Types). Valid values for 'index' are [0, N - 1] where N is the + // length of Types. + static bool Register(const char* prefix, const char* case_name, + const char* test_names, int index) { + typedef typename Types::Head Type; + typedef Fixture<Type> FixtureClass; + typedef typename GTEST_BIND_(TestSel, Type) TestClass; + + // First, registers the first type-parameterized test in the type + // list. + MakeAndRegisterTestInfo( + String::Format("%s%s%s/%d", prefix, prefix[0] == '\0' ? "" : "/", + case_name, index).c_str(), + GetPrefixUntilComma(test_names).c_str(), + String::Format("TypeParam = %s", GetTypeName<Type>().c_str()).c_str(), + "", + GetTypeId<FixtureClass>(), + TestClass::SetUpTestCase, + TestClass::TearDownTestCase, + new TestFactoryImpl<TestClass>); + + // Next, recurses (at compile time) with the tail of the type list. + return TypeParameterizedTest<Fixture, TestSel, typename Types::Tail> + ::Register(prefix, case_name, test_names, index + 1); + } +}; + +// The base case for the compile time recursion. +template <GTEST_TEMPLATE_ Fixture, class TestSel> +class TypeParameterizedTest<Fixture, TestSel, Types0> { + public: + static bool Register(const char* /*prefix*/, const char* /*case_name*/, + const char* /*test_names*/, int /*index*/) { + return true; + } +}; + +// TypeParameterizedTestCase<Fixture, Tests, Types>::Register() +// registers *all combinations* of 'Tests' and 'Types' with Google +// Test. The return value is insignificant - we just need to return +// something such that we can call this function in a namespace scope. +template <GTEST_TEMPLATE_ Fixture, typename Tests, typename Types> +class TypeParameterizedTestCase { + public: + static bool Register(const char* prefix, const char* case_name, + const char* test_names) { + typedef typename Tests::Head Head; + + // First, register the first test in 'Test' for each type in 'Types'. + TypeParameterizedTest<Fixture, Head, Types>::Register( + prefix, case_name, test_names, 0); + + // Next, recurses (at compile time) with the tail of the test list. + return TypeParameterizedTestCase<Fixture, typename Tests::Tail, Types> + ::Register(prefix, case_name, SkipComma(test_names)); + } +}; + +// The base case for the compile time recursion. +template <GTEST_TEMPLATE_ Fixture, typename Types> +class TypeParameterizedTestCase<Fixture, Templates0, Types> { + public: + static bool Register(const char* /*prefix*/, const char* /*case_name*/, + const char* /*test_names*/) { + return true; + } +}; + +#endif // GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P + +// Returns the current OS stack trace as a String. +// +// The maximum number of stack frames to be included is specified by +// the gtest_stack_trace_depth flag. The skip_count parameter +// specifies the number of top frames to be skipped, which doesn't +// count against the number of frames to be included. +// +// For example, if Foo() calls Bar(), which in turn calls +// GetCurrentOsStackTraceExceptTop(..., 1), Foo() will be included in +// the trace but Bar() and GetCurrentOsStackTraceExceptTop() won't. +GTEST_API_ String GetCurrentOsStackTraceExceptTop(UnitTest* unit_test, + int skip_count); + +// Helpers for suppressing warnings on unreachable code or constant +// condition. + +// Always returns true. +GTEST_API_ bool AlwaysTrue(); + +// Always returns false. +inline bool AlwaysFalse() { return !AlwaysTrue(); } + +// A simple Linear Congruential Generator for generating random +// numbers with a uniform distribution. Unlike rand() and srand(), it +// doesn't use global state (and therefore can't interfere with user +// code). Unlike rand_r(), it's portable. An LCG isn't very random, +// but it's good enough for our purposes. +class GTEST_API_ Random { + public: + static const UInt32 kMaxRange = 1u << 31; + + explicit Random(UInt32 seed) : state_(seed) {} + + void Reseed(UInt32 seed) { state_ = seed; } + + // Generates a random number from [0, range). Crashes if 'range' is + // 0 or greater than kMaxRange. + UInt32 Generate(UInt32 range); + + private: + UInt32 state_; + GTEST_DISALLOW_COPY_AND_ASSIGN_(Random); +}; + +} // namespace internal +} // namespace testing + +#define GTEST_MESSAGE_(message, result_type) \ + ::testing::internal::AssertHelper(result_type, __FILE__, __LINE__, message) \ + = ::testing::Message() + +#define GTEST_FATAL_FAILURE_(message) \ + return GTEST_MESSAGE_(message, ::testing::TestPartResult::kFatalFailure) + +#define GTEST_NONFATAL_FAILURE_(message) \ + GTEST_MESSAGE_(message, ::testing::TestPartResult::kNonFatalFailure) + +#define GTEST_SUCCESS_(message) \ + GTEST_MESSAGE_(message, ::testing::TestPartResult::kSuccess) + +// Suppresses MSVC warnings 4072 (unreachable code) for the code following +// statement if it returns or throws (or doesn't return or throw in some +// situations). +#define GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement) \ + if (::testing::internal::AlwaysTrue()) { statement; } + +#define GTEST_TEST_THROW_(statement, expected_exception, fail) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (const char* gtest_msg = "") { \ + bool gtest_caught_expected = false; \ + try { \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ + } \ + catch (expected_exception const&) { \ + gtest_caught_expected = true; \ + } \ + catch (...) { \ + gtest_msg = "Expected: " #statement " throws an exception of type " \ + #expected_exception ".\n Actual: it throws a different " \ + "type."; \ + goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \ + } \ + if (!gtest_caught_expected) { \ + gtest_msg = "Expected: " #statement " throws an exception of type " \ + #expected_exception ".\n Actual: it throws nothing."; \ + goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \ + } \ + } else \ + GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__): \ + fail(gtest_msg) + +#define GTEST_TEST_NO_THROW_(statement, fail) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (const char* gtest_msg = "") { \ + try { \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ + } \ + catch (...) { \ + gtest_msg = "Expected: " #statement " doesn't throw an exception.\n" \ + " Actual: it throws."; \ + goto GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__); \ + } \ + } else \ + GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__): \ + fail(gtest_msg) + +#define GTEST_TEST_ANY_THROW_(statement, fail) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (const char* gtest_msg = "") { \ + bool gtest_caught_any = false; \ + try { \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ + } \ + catch (...) { \ + gtest_caught_any = true; \ + } \ + if (!gtest_caught_any) { \ + gtest_msg = "Expected: " #statement " throws an exception.\n" \ + " Actual: it doesn't."; \ + goto GTEST_CONCAT_TOKEN_(gtest_label_testanythrow_, __LINE__); \ + } \ + } else \ + GTEST_CONCAT_TOKEN_(gtest_label_testanythrow_, __LINE__): \ + fail(gtest_msg) + + +// Implements Boolean test assertions such as EXPECT_TRUE. expression can be +// either a boolean expression or an AssertionResult. text is a textual +// represenation of expression as it was passed into the EXPECT_TRUE. +#define GTEST_TEST_BOOLEAN_(expression, text, actual, expected, fail) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (const ::testing::AssertionResult gtest_ar_ = \ + ::testing::AssertionResult(expression)) \ + ; \ + else \ + fail(::testing::internal::GetBoolAssertionFailureMessage(\ + gtest_ar_, text, #actual, #expected).c_str()) + +#define GTEST_TEST_NO_FATAL_FAILURE_(statement, fail) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (const char* gtest_msg = "") { \ + ::testing::internal::HasNewFatalFailureHelper gtest_fatal_failure_checker; \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ + if (gtest_fatal_failure_checker.has_new_fatal_failure()) { \ + gtest_msg = "Expected: " #statement " doesn't generate new fatal " \ + "failures in the current thread.\n" \ + " Actual: it does."; \ + goto GTEST_CONCAT_TOKEN_(gtest_label_testnofatal_, __LINE__); \ + } \ + } else \ + GTEST_CONCAT_TOKEN_(gtest_label_testnofatal_, __LINE__): \ + fail(gtest_msg) + +// Expands to the name of the class that implements the given test. +#define GTEST_TEST_CLASS_NAME_(test_case_name, test_name) \ + test_case_name##_##test_name##_Test + +// Helper macro for defining tests. +#define GTEST_TEST_(test_case_name, test_name, parent_class, parent_id)\ +class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) : public parent_class {\ + public:\ + GTEST_TEST_CLASS_NAME_(test_case_name, test_name)() {}\ + private:\ + virtual void TestBody();\ + static ::testing::TestInfo* const test_info_;\ + GTEST_DISALLOW_COPY_AND_ASSIGN_(\ + GTEST_TEST_CLASS_NAME_(test_case_name, test_name));\ +};\ +\ +::testing::TestInfo* const GTEST_TEST_CLASS_NAME_(test_case_name, test_name)\ + ::test_info_ =\ + ::testing::internal::MakeAndRegisterTestInfo(\ + #test_case_name, #test_name, "", "", \ + (parent_id), \ + parent_class::SetUpTestCase, \ + parent_class::TearDownTestCase, \ + new ::testing::internal::TestFactoryImpl<\ + GTEST_TEST_CLASS_NAME_(test_case_name, test_name)>);\ +void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody() + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: wan@google.com (Zhanyong Wan) +// +// The Google C++ Testing Framework (Google Test) +// +// This header file defines the public API for death tests. It is +// #included by gtest.h so a user doesn't need to include this +// directly. + +#ifndef GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_ +#define GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_ + +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee) +// +// The Google C++ Testing Framework (Google Test) +// +// This header file defines internal utilities needed for implementing +// death tests. They are subject to change without notice. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_ + + +namespace testing { +namespace internal { + +GTEST_DECLARE_string_(internal_run_death_test); + +// Names of the flags (needed for parsing Google Test flags). +const char kDeathTestStyleFlag[] = "death_test_style"; +const char kDeathTestUseFork[] = "death_test_use_fork"; +const char kInternalRunDeathTestFlag[] = "internal_run_death_test"; + +#if GTEST_HAS_DEATH_TEST + +// DeathTest is a class that hides much of the complexity of the +// GTEST_DEATH_TEST_ macro. It is abstract; its static Create method +// returns a concrete class that depends on the prevailing death test +// style, as defined by the --gtest_death_test_style and/or +// --gtest_internal_run_death_test flags. + +// In describing the results of death tests, these terms are used with +// the corresponding definitions: +// +// exit status: The integer exit information in the format specified +// by wait(2) +// exit code: The integer code passed to exit(3), _exit(2), or +// returned from main() +class GTEST_API_ DeathTest { + public: + // Create returns false if there was an error determining the + // appropriate action to take for the current death test; for example, + // if the gtest_death_test_style flag is set to an invalid value. + // The LastMessage method will return a more detailed message in that + // case. Otherwise, the DeathTest pointer pointed to by the "test" + // argument is set. If the death test should be skipped, the pointer + // is set to NULL; otherwise, it is set to the address of a new concrete + // DeathTest object that controls the execution of the current test. + static bool Create(const char* statement, const RE* regex, + const char* file, int line, DeathTest** test); + DeathTest(); + virtual ~DeathTest() { } + + // A helper class that aborts a death test when it's deleted. + class ReturnSentinel { + public: + explicit ReturnSentinel(DeathTest* test) : test_(test) { } + ~ReturnSentinel() { test_->Abort(TEST_ENCOUNTERED_RETURN_STATEMENT); } + private: + DeathTest* const test_; + GTEST_DISALLOW_COPY_AND_ASSIGN_(ReturnSentinel); + } GTEST_ATTRIBUTE_UNUSED_; + + // An enumeration of possible roles that may be taken when a death + // test is encountered. EXECUTE means that the death test logic should + // be executed immediately. OVERSEE means that the program should prepare + // the appropriate environment for a child process to execute the death + // test, then wait for it to complete. + enum TestRole { OVERSEE_TEST, EXECUTE_TEST }; + + // An enumeration of the two reasons that a test might be aborted. + enum AbortReason { TEST_ENCOUNTERED_RETURN_STATEMENT, TEST_DID_NOT_DIE }; + + // Assumes one of the above roles. + virtual TestRole AssumeRole() = 0; + + // Waits for the death test to finish and returns its status. + virtual int Wait() = 0; + + // Returns true if the death test passed; that is, the test process + // exited during the test, its exit status matches a user-supplied + // predicate, and its stderr output matches a user-supplied regular + // expression. + // The user-supplied predicate may be a macro expression rather + // than a function pointer or functor, or else Wait and Passed could + // be combined. + virtual bool Passed(bool exit_status_ok) = 0; + + // Signals that the death test did not die as expected. + virtual void Abort(AbortReason reason) = 0; + + // Returns a human-readable outcome message regarding the outcome of + // the last death test. + static const char* LastMessage(); + + static void set_last_death_test_message(const String& message); + + private: + // A string containing a description of the outcome of the last death test. + static String last_death_test_message_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(DeathTest); +}; + +// Factory interface for death tests. May be mocked out for testing. +class DeathTestFactory { + public: + virtual ~DeathTestFactory() { } + virtual bool Create(const char* statement, const RE* regex, + const char* file, int line, DeathTest** test) = 0; +}; + +// A concrete DeathTestFactory implementation for normal use. +class DefaultDeathTestFactory : public DeathTestFactory { + public: + virtual bool Create(const char* statement, const RE* regex, + const char* file, int line, DeathTest** test); +}; + +// Returns true if exit_status describes a process that was terminated +// by a signal, or exited normally with a nonzero exit code. +GTEST_API_ bool ExitedUnsuccessfully(int exit_status); + +// This macro is for implementing ASSERT_DEATH*, EXPECT_DEATH*, +// ASSERT_EXIT*, and EXPECT_EXIT*. +#define GTEST_DEATH_TEST_(statement, predicate, regex, fail) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (::testing::internal::AlwaysTrue()) { \ + const ::testing::internal::RE& gtest_regex = (regex); \ + ::testing::internal::DeathTest* gtest_dt; \ + if (!::testing::internal::DeathTest::Create(#statement, >est_regex, \ + __FILE__, __LINE__, >est_dt)) { \ + goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \ + } \ + if (gtest_dt != NULL) { \ + ::testing::internal::scoped_ptr< ::testing::internal::DeathTest> \ + gtest_dt_ptr(gtest_dt); \ + switch (gtest_dt->AssumeRole()) { \ + case ::testing::internal::DeathTest::OVERSEE_TEST: \ + if (!gtest_dt->Passed(predicate(gtest_dt->Wait()))) { \ + goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \ + } \ + break; \ + case ::testing::internal::DeathTest::EXECUTE_TEST: { \ + ::testing::internal::DeathTest::ReturnSentinel \ + gtest_sentinel(gtest_dt); \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ + gtest_dt->Abort(::testing::internal::DeathTest::TEST_DID_NOT_DIE); \ + break; \ + } \ + } \ + } \ + } else \ + GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__): \ + fail(::testing::internal::DeathTest::LastMessage()) +// The symbol "fail" here expands to something into which a message +// can be streamed. + +// A class representing the parsed contents of the +// --gtest_internal_run_death_test flag, as it existed when +// RUN_ALL_TESTS was called. +class InternalRunDeathTestFlag { + public: + InternalRunDeathTestFlag(const String& a_file, + int a_line, + int an_index, + int a_write_fd) + : file_(a_file), line_(a_line), index_(an_index), + write_fd_(a_write_fd) {} + + ~InternalRunDeathTestFlag() { + if (write_fd_ >= 0) + posix::Close(write_fd_); + } + + String file() const { return file_; } + int line() const { return line_; } + int index() const { return index_; } + int write_fd() const { return write_fd_; } + + private: + String file_; + int line_; + int index_; + int write_fd_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(InternalRunDeathTestFlag); +}; + +// Returns a newly created InternalRunDeathTestFlag object with fields +// initialized from the GTEST_FLAG(internal_run_death_test) flag if +// the flag is specified; otherwise returns NULL. +InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag(); + +#else // GTEST_HAS_DEATH_TEST + +// This macro is used for implementing macros such as +// EXPECT_DEATH_IF_SUPPORTED and ASSERT_DEATH_IF_SUPPORTED on systems where +// death tests are not supported. Those macros must compile on such systems +// iff EXPECT_DEATH and ASSERT_DEATH compile with the same parameters on +// systems that support death tests. This allows one to write such a macro +// on a system that does not support death tests and be sure that it will +// compile on a death-test supporting system. +// +// Parameters: +// statement - A statement that a macro such as EXPECT_DEATH would test +// for program termination. This macro has to make sure this +// statement is compiled but not executed, to ensure that +// EXPECT_DEATH_IF_SUPPORTED compiles with a certain +// parameter iff EXPECT_DEATH compiles with it. +// regex - A regex that a macro such as EXPECT_DEATH would use to test +// the output of statement. This parameter has to be +// compiled but not evaluated by this macro, to ensure that +// this macro only accepts expressions that a macro such as +// EXPECT_DEATH would accept. +// terminator - Must be an empty statement for EXPECT_DEATH_IF_SUPPORTED +// and a return statement for ASSERT_DEATH_IF_SUPPORTED. +// This ensures that ASSERT_DEATH_IF_SUPPORTED will not +// compile inside functions where ASSERT_DEATH doesn't +// compile. +// +// The branch that has an always false condition is used to ensure that +// statement and regex are compiled (and thus syntactically correct) but +// never executed. The unreachable code macro protects the terminator +// statement from generating an 'unreachable code' warning in case +// statement unconditionally returns or throws. The Message constructor at +// the end allows the syntax of streaming additional messages into the +// macro, for compilational compatibility with EXPECT_DEATH/ASSERT_DEATH. +#define GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, terminator) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (::testing::internal::AlwaysTrue()) { \ + GTEST_LOG_(WARNING) \ + << "Death tests are not supported on this platform.\n" \ + << "Statement '" #statement "' cannot be verified."; \ + } else if (::testing::internal::AlwaysFalse()) { \ + ::testing::internal::RE::PartialMatch(".*", (regex)); \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ + terminator; \ + } else \ + ::testing::Message() + +#endif // GTEST_HAS_DEATH_TEST + +} // namespace internal +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_ + +namespace testing { + +// This flag controls the style of death tests. Valid values are "threadsafe", +// meaning that the death test child process will re-execute the test binary +// from the start, running only a single death test, or "fast", +// meaning that the child process will execute the test logic immediately +// after forking. +GTEST_DECLARE_string_(death_test_style); + +#if GTEST_HAS_DEATH_TEST + +// The following macros are useful for writing death tests. + +// Here's what happens when an ASSERT_DEATH* or EXPECT_DEATH* is +// executed: +// +// 1. It generates a warning if there is more than one active +// thread. This is because it's safe to fork() or clone() only +// when there is a single thread. +// +// 2. The parent process clone()s a sub-process and runs the death +// test in it; the sub-process exits with code 0 at the end of the +// death test, if it hasn't exited already. +// +// 3. The parent process waits for the sub-process to terminate. +// +// 4. The parent process checks the exit code and error message of +// the sub-process. +// +// Examples: +// +// ASSERT_DEATH(server.SendMessage(56, "Hello"), "Invalid port number"); +// for (int i = 0; i < 5; i++) { +// EXPECT_DEATH(server.ProcessRequest(i), +// "Invalid request .* in ProcessRequest()") +// << "Failed to die on request " << i); +// } +// +// ASSERT_EXIT(server.ExitNow(), ::testing::ExitedWithCode(0), "Exiting"); +// +// bool KilledBySIGHUP(int exit_code) { +// return WIFSIGNALED(exit_code) && WTERMSIG(exit_code) == SIGHUP; +// } +// +// ASSERT_EXIT(client.HangUpServer(), KilledBySIGHUP, "Hanging up!"); +// +// On the regular expressions used in death tests: +// +// On POSIX-compliant systems (*nix), we use the <regex.h> library, +// which uses the POSIX extended regex syntax. +// +// On other platforms (e.g. Windows), we only support a simple regex +// syntax implemented as part of Google Test. This limited +// implementation should be enough most of the time when writing +// death tests; though it lacks many features you can find in PCRE +// or POSIX extended regex syntax. For example, we don't support +// union ("x|y"), grouping ("(xy)"), brackets ("[xy]"), and +// repetition count ("x{5,7}"), among others. +// +// Below is the syntax that we do support. We chose it to be a +// subset of both PCRE and POSIX extended regex, so it's easy to +// learn wherever you come from. In the following: 'A' denotes a +// literal character, period (.), or a single \\ escape sequence; +// 'x' and 'y' denote regular expressions; 'm' and 'n' are for +// natural numbers. +// +// c matches any literal character c +// \\d matches any decimal digit +// \\D matches any character that's not a decimal digit +// \\f matches \f +// \\n matches \n +// \\r matches \r +// \\s matches any ASCII whitespace, including \n +// \\S matches any character that's not a whitespace +// \\t matches \t +// \\v matches \v +// \\w matches any letter, _, or decimal digit +// \\W matches any character that \\w doesn't match +// \\c matches any literal character c, which must be a punctuation +// . matches any single character except \n +// A? matches 0 or 1 occurrences of A +// A* matches 0 or many occurrences of A +// A+ matches 1 or many occurrences of A +// ^ matches the beginning of a string (not that of each line) +// $ matches the end of a string (not that of each line) +// xy matches x followed by y +// +// If you accidentally use PCRE or POSIX extended regex features +// not implemented by us, you will get a run-time failure. In that +// case, please try to rewrite your regular expression within the +// above syntax. +// +// This implementation is *not* meant to be as highly tuned or robust +// as a compiled regex library, but should perform well enough for a +// death test, which already incurs significant overhead by launching +// a child process. +// +// Known caveats: +// +// A "threadsafe" style death test obtains the path to the test +// program from argv[0] and re-executes it in the sub-process. For +// simplicity, the current implementation doesn't search the PATH +// when launching the sub-process. This means that the user must +// invoke the test program via a path that contains at least one +// path separator (e.g. path/to/foo_test and +// /absolute/path/to/bar_test are fine, but foo_test is not). This +// is rarely a problem as people usually don't put the test binary +// directory in PATH. +// +// TODO(wan@google.com): make thread-safe death tests search the PATH. + +// Asserts that a given statement causes the program to exit, with an +// integer exit status that satisfies predicate, and emitting error output +// that matches regex. +#define ASSERT_EXIT(statement, predicate, regex) \ + GTEST_DEATH_TEST_(statement, predicate, regex, GTEST_FATAL_FAILURE_) + +// Like ASSERT_EXIT, but continues on to successive tests in the +// test case, if any: +#define EXPECT_EXIT(statement, predicate, regex) \ + GTEST_DEATH_TEST_(statement, predicate, regex, GTEST_NONFATAL_FAILURE_) + +// Asserts that a given statement causes the program to exit, either by +// explicitly exiting with a nonzero exit code or being killed by a +// signal, and emitting error output that matches regex. +#define ASSERT_DEATH(statement, regex) \ + ASSERT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex) + +// Like ASSERT_DEATH, but continues on to successive tests in the +// test case, if any: +#define EXPECT_DEATH(statement, regex) \ + EXPECT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex) + +// Two predicate classes that can be used in {ASSERT,EXPECT}_EXIT*: + +// Tests that an exit code describes a normal exit with a given exit code. +class GTEST_API_ ExitedWithCode { + public: + explicit ExitedWithCode(int exit_code); + bool operator()(int exit_status) const; + private: + // No implementation - assignment is unsupported. + void operator=(const ExitedWithCode& other); + + const int exit_code_; +}; + +#if !GTEST_OS_WINDOWS +// Tests that an exit code describes an exit due to termination by a +// given signal. +class GTEST_API_ KilledBySignal { + public: + explicit KilledBySignal(int signum); + bool operator()(int exit_status) const; + private: + const int signum_; +}; +#endif // !GTEST_OS_WINDOWS + +// EXPECT_DEBUG_DEATH asserts that the given statements die in debug mode. +// The death testing framework causes this to have interesting semantics, +// since the sideeffects of the call are only visible in opt mode, and not +// in debug mode. +// +// In practice, this can be used to test functions that utilize the +// LOG(DFATAL) macro using the following style: +// +// int DieInDebugOr12(int* sideeffect) { +// if (sideeffect) { +// *sideeffect = 12; +// } +// LOG(DFATAL) << "death"; +// return 12; +// } +// +// TEST(TestCase, TestDieOr12WorksInDgbAndOpt) { +// int sideeffect = 0; +// // Only asserts in dbg. +// EXPECT_DEBUG_DEATH(DieInDebugOr12(&sideeffect), "death"); +// +// #ifdef NDEBUG +// // opt-mode has sideeffect visible. +// EXPECT_EQ(12, sideeffect); +// #else +// // dbg-mode no visible sideeffect. +// EXPECT_EQ(0, sideeffect); +// #endif +// } +// +// This will assert that DieInDebugReturn12InOpt() crashes in debug +// mode, usually due to a DCHECK or LOG(DFATAL), but returns the +// appropriate fallback value (12 in this case) in opt mode. If you +// need to test that a function has appropriate side-effects in opt +// mode, include assertions against the side-effects. A general +// pattern for this is: +// +// EXPECT_DEBUG_DEATH({ +// // Side-effects here will have an effect after this statement in +// // opt mode, but none in debug mode. +// EXPECT_EQ(12, DieInDebugOr12(&sideeffect)); +// }, "death"); +// +#ifdef NDEBUG + +#define EXPECT_DEBUG_DEATH(statement, regex) \ + do { statement; } while (::testing::internal::AlwaysFalse()) + +#define ASSERT_DEBUG_DEATH(statement, regex) \ + do { statement; } while (::testing::internal::AlwaysFalse()) + +#else + +#define EXPECT_DEBUG_DEATH(statement, regex) \ + EXPECT_DEATH(statement, regex) + +#define ASSERT_DEBUG_DEATH(statement, regex) \ + ASSERT_DEATH(statement, regex) + +#endif // NDEBUG for EXPECT_DEBUG_DEATH +#endif // GTEST_HAS_DEATH_TEST + +// EXPECT_DEATH_IF_SUPPORTED(statement, regex) and +// ASSERT_DEATH_IF_SUPPORTED(statement, regex) expand to real death tests if +// death tests are supported; otherwise they just issue a warning. This is +// useful when you are combining death test assertions with normal test +// assertions in one test. +#if GTEST_HAS_DEATH_TEST +#define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \ + EXPECT_DEATH(statement, regex) +#define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \ + ASSERT_DEATH(statement, regex) +#else +#define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \ + GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, ) +#define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \ + GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, return) +#endif + +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_ +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: wan@google.com (Zhanyong Wan) +// +// The Google C++ Testing Framework (Google Test) +// +// This header file defines the Message class. +// +// IMPORTANT NOTE: Due to limitation of the C++ language, we have to +// leave some internal implementation details in this header file. +// They are clearly marked by comments like this: +// +// // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +// +// Such code is NOT meant to be used by a user directly, and is subject +// to CHANGE WITHOUT NOTICE. Therefore DO NOT DEPEND ON IT in a user +// program! + +#ifndef GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_ +#define GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_ + +#include <limits> + + +namespace testing { + +// The Message class works like an ostream repeater. +// +// Typical usage: +// +// 1. You stream a bunch of values to a Message object. +// It will remember the text in a StrStream. +// 2. Then you stream the Message object to an ostream. +// This causes the text in the Message to be streamed +// to the ostream. +// +// For example; +// +// testing::Message foo; +// foo << 1 << " != " << 2; +// std::cout << foo; +// +// will print "1 != 2". +// +// Message is not intended to be inherited from. In particular, its +// destructor is not virtual. +// +// Note that StrStream behaves differently in gcc and in MSVC. You +// can stream a NULL char pointer to it in the former, but not in the +// latter (it causes an access violation if you do). The Message +// class hides this difference by treating a NULL char pointer as +// "(null)". +class GTEST_API_ Message { + private: + // The type of basic IO manipulators (endl, ends, and flush) for + // narrow streams. + typedef std::ostream& (*BasicNarrowIoManip)(std::ostream&); + + public: + // Constructs an empty Message. + // We allocate the StrStream separately because it otherwise each use of + // ASSERT/EXPECT in a procedure adds over 200 bytes to the procedure's + // stack frame leading to huge stack frames in some cases; gcc does not reuse + // the stack space. + Message() : ss_(new internal::StrStream) { + // By default, we want there to be enough precision when printing + // a double to a Message. + *ss_ << std::setprecision(std::numeric_limits<double>::digits10 + 2); + } + + // Copy constructor. + Message(const Message& msg) : ss_(new internal::StrStream) { // NOLINT + *ss_ << msg.GetString(); + } + + // Constructs a Message from a C-string. + explicit Message(const char* str) : ss_(new internal::StrStream) { + *ss_ << str; + } + + ~Message() { delete ss_; } +#if GTEST_OS_SYMBIAN + // Streams a value (either a pointer or not) to this object. + template <typename T> + inline Message& operator <<(const T& value) { + StreamHelper(typename internal::is_pointer<T>::type(), value); + return *this; + } +#else + // Streams a non-pointer value to this object. + template <typename T> + inline Message& operator <<(const T& val) { + ::GTestStreamToHelper(ss_, val); + return *this; + } + + // Streams a pointer value to this object. + // + // This function is an overload of the previous one. When you + // stream a pointer to a Message, this definition will be used as it + // is more specialized. (The C++ Standard, section + // [temp.func.order].) If you stream a non-pointer, then the + // previous definition will be used. + // + // The reason for this overload is that streaming a NULL pointer to + // ostream is undefined behavior. Depending on the compiler, you + // may get "0", "(nil)", "(null)", or an access violation. To + // ensure consistent result across compilers, we always treat NULL + // as "(null)". + template <typename T> + inline Message& operator <<(T* const& pointer) { // NOLINT + if (pointer == NULL) { + *ss_ << "(null)"; + } else { + ::GTestStreamToHelper(ss_, pointer); + } + return *this; + } +#endif // GTEST_OS_SYMBIAN + + // Since the basic IO manipulators are overloaded for both narrow + // and wide streams, we have to provide this specialized definition + // of operator <<, even though its body is the same as the + // templatized version above. Without this definition, streaming + // endl or other basic IO manipulators to Message will confuse the + // compiler. + Message& operator <<(BasicNarrowIoManip val) { + *ss_ << val; + return *this; + } + + // Instead of 1/0, we want to see true/false for bool values. + Message& operator <<(bool b) { + return *this << (b ? "true" : "false"); + } + + // These two overloads allow streaming a wide C string to a Message + // using the UTF-8 encoding. + Message& operator <<(const wchar_t* wide_c_str) { + return *this << internal::String::ShowWideCString(wide_c_str); + } + Message& operator <<(wchar_t* wide_c_str) { + return *this << internal::String::ShowWideCString(wide_c_str); + } + +#if GTEST_HAS_STD_WSTRING + // Converts the given wide string to a narrow string using the UTF-8 + // encoding, and streams the result to this Message object. + Message& operator <<(const ::std::wstring& wstr); +#endif // GTEST_HAS_STD_WSTRING + +#if GTEST_HAS_GLOBAL_WSTRING + // Converts the given wide string to a narrow string using the UTF-8 + // encoding, and streams the result to this Message object. + Message& operator <<(const ::wstring& wstr); +#endif // GTEST_HAS_GLOBAL_WSTRING + + // Gets the text streamed to this object so far as a String. + // Each '\0' character in the buffer is replaced with "\\0". + // + // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. + internal::String GetString() const { + return internal::StrStreamToString(ss_); + } + + private: +#if GTEST_OS_SYMBIAN + // These are needed as the Nokia Symbian Compiler cannot decide between + // const T& and const T* in a function template. The Nokia compiler _can_ + // decide between class template specializations for T and T*, so a + // tr1::type_traits-like is_pointer works, and we can overload on that. + template <typename T> + inline void StreamHelper(internal::true_type /*dummy*/, T* pointer) { + if (pointer == NULL) { + *ss_ << "(null)"; + } else { + ::GTestStreamToHelper(ss_, pointer); + } + } + template <typename T> + inline void StreamHelper(internal::false_type /*dummy*/, const T& value) { + ::GTestStreamToHelper(ss_, value); + } +#endif // GTEST_OS_SYMBIAN + + // We'll hold the text streamed to this object here. + internal::StrStream* const ss_; + + // We declare (but don't implement) this to prevent the compiler + // from implementing the assignment operator. + void operator=(const Message&); +}; + +// Streams a Message to an ostream. +inline std::ostream& operator <<(std::ostream& os, const Message& sb) { + return os << sb.GetString(); +} + +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_ +// This file was GENERATED by a script. DO NOT EDIT BY HAND!!! + +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: vladl@google.com (Vlad Losev) +// +// Macros and functions for implementing parameterized tests +// in Google C++ Testing Framework (Google Test) +// +// This file is generated by a SCRIPT. DO NOT EDIT BY HAND! +// +#ifndef GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_ +#define GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_ + + +// Value-parameterized tests allow you to test your code with different +// parameters without writing multiple copies of the same test. +// +// Here is how you use value-parameterized tests: + +#if 0 + +// To write value-parameterized tests, first you should define a fixture +// class. It must be derived from testing::TestWithParam<T>, where T is +// the type of your parameter values. TestWithParam<T> is itself derived +// from testing::Test. T can be any copyable type. If it's a raw pointer, +// you are responsible for managing the lifespan of the pointed values. + +class FooTest : public ::testing::TestWithParam<const char*> { + // You can implement all the usual class fixture members here. +}; + +// Then, use the TEST_P macro to define as many parameterized tests +// for this fixture as you want. The _P suffix is for "parameterized" +// or "pattern", whichever you prefer to think. + +TEST_P(FooTest, DoesBlah) { + // Inside a test, access the test parameter with the GetParam() method + // of the TestWithParam<T> class: + EXPECT_TRUE(foo.Blah(GetParam())); + ... +} + +TEST_P(FooTest, HasBlahBlah) { + ... +} + +// Finally, you can use INSTANTIATE_TEST_CASE_P to instantiate the test +// case with any set of parameters you want. Google Test defines a number +// of functions for generating test parameters. They return what we call +// (surprise!) parameter generators. Here is a summary of them, which +// are all in the testing namespace: +// +// +// Range(begin, end [, step]) - Yields values {begin, begin+step, +// begin+step+step, ...}. The values do not +// include end. step defaults to 1. +// Values(v1, v2, ..., vN) - Yields values {v1, v2, ..., vN}. +// ValuesIn(container) - Yields values from a C-style array, an STL +// ValuesIn(begin,end) container, or an iterator range [begin, end). +// Bool() - Yields sequence {false, true}. +// Combine(g1, g2, ..., gN) - Yields all combinations (the Cartesian product +// for the math savvy) of the values generated +// by the N generators. +// +// For more details, see comments at the definitions of these functions below +// in this file. +// +// The following statement will instantiate tests from the FooTest test case +// each with parameter values "meeny", "miny", and "moe". + +INSTANTIATE_TEST_CASE_P(InstantiationName, + FooTest, + Values("meeny", "miny", "moe")); + +// To distinguish different instances of the pattern, (yes, you +// can instantiate it more then once) the first argument to the +// INSTANTIATE_TEST_CASE_P macro is a prefix that will be added to the +// actual test case name. Remember to pick unique prefixes for different +// instantiations. The tests from the instantiation above will have +// these names: +// +// * InstantiationName/FooTest.DoesBlah/0 for "meeny" +// * InstantiationName/FooTest.DoesBlah/1 for "miny" +// * InstantiationName/FooTest.DoesBlah/2 for "moe" +// * InstantiationName/FooTest.HasBlahBlah/0 for "meeny" +// * InstantiationName/FooTest.HasBlahBlah/1 for "miny" +// * InstantiationName/FooTest.HasBlahBlah/2 for "moe" +// +// You can use these names in --gtest_filter. +// +// This statement will instantiate all tests from FooTest again, each +// with parameter values "cat" and "dog": + +const char* pets[] = {"cat", "dog"}; +INSTANTIATE_TEST_CASE_P(AnotherInstantiationName, FooTest, ValuesIn(pets)); + +// The tests from the instantiation above will have these names: +// +// * AnotherInstantiationName/FooTest.DoesBlah/0 for "cat" +// * AnotherInstantiationName/FooTest.DoesBlah/1 for "dog" +// * AnotherInstantiationName/FooTest.HasBlahBlah/0 for "cat" +// * AnotherInstantiationName/FooTest.HasBlahBlah/1 for "dog" +// +// Please note that INSTANTIATE_TEST_CASE_P will instantiate all tests +// in the given test case, whether their definitions come before or +// AFTER the INSTANTIATE_TEST_CASE_P statement. +// +// Please also note that generator expressions (including parameters to the +// generators) are evaluated in InitGoogleTest(), after main() has started. +// This allows the user on one hand, to adjust generator parameters in order +// to dynamically determine a set of tests to run and on the other hand, +// give the user a chance to inspect the generated tests with Google Test +// reflection API before RUN_ALL_TESTS() is executed. +// +// You can see samples/sample7_unittest.cc and samples/sample8_unittest.cc +// for more examples. +// +// In the future, we plan to publish the API for defining new parameter +// generators. But for now this interface remains part of the internal +// implementation and is subject to change. + +#endif // 0 + + +#if !GTEST_OS_SYMBIAN +#include <utility> +#endif + +// scripts/fuse_gtest.py depends on gtest's own header being #included +// *unconditionally*. Therefore these #includes cannot be moved +// inside #if GTEST_HAS_PARAM_TEST. +// Copyright 2008 Google Inc. +// All Rights Reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: vladl@google.com (Vlad Losev) + +// Type and function utilities for implementing parameterized tests. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_ + +#include <iterator> +#include <utility> +#include <vector> + +// scripts/fuse_gtest.py depends on gtest's own header being #included +// *unconditionally*. Therefore these #includes cannot be moved +// inside #if GTEST_HAS_PARAM_TEST. +// Copyright 2003 Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: Dan Egnor (egnor@google.com) +// +// A "smart" pointer type with reference tracking. Every pointer to a +// particular object is kept on a circular linked list. When the last pointer +// to an object is destroyed or reassigned, the object is deleted. +// +// Used properly, this deletes the object when the last reference goes away. +// There are several caveats: +// - Like all reference counting schemes, cycles lead to leaks. +// - Each smart pointer is actually two pointers (8 bytes instead of 4). +// - Every time a pointer is assigned, the entire list of pointers to that +// object is traversed. This class is therefore NOT SUITABLE when there +// will often be more than two or three pointers to a particular object. +// - References are only tracked as long as linked_ptr<> objects are copied. +// If a linked_ptr<> is converted to a raw pointer and back, BAD THINGS +// will happen (double deletion). +// +// A good use of this class is storing object references in STL containers. +// You can safely put linked_ptr<> in a vector<>. +// Other uses may not be as good. +// +// Note: If you use an incomplete type with linked_ptr<>, the class +// *containing* linked_ptr<> must have a constructor and destructor (even +// if they do nothing!). +// +// Bill Gibbons suggested we use something like this. +// +// Thread Safety: +// Unlike other linked_ptr implementations, in this implementation +// a linked_ptr object is thread-safe in the sense that: +// - it's safe to copy linked_ptr objects concurrently, +// - it's safe to copy *from* a linked_ptr and read its underlying +// raw pointer (e.g. via get()) concurrently, and +// - it's safe to write to two linked_ptrs that point to the same +// shared object concurrently. +// TODO(wan@google.com): rename this to safe_linked_ptr to avoid +// confusion with normal linked_ptr. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_ + +#include <stdlib.h> +#include <assert.h> + + +namespace testing { +namespace internal { + +// Protects copying of all linked_ptr objects. +GTEST_API_ GTEST_DECLARE_STATIC_MUTEX_(g_linked_ptr_mutex); + +// This is used internally by all instances of linked_ptr<>. It needs to be +// a non-template class because different types of linked_ptr<> can refer to +// the same object (linked_ptr<Superclass>(obj) vs linked_ptr<Subclass>(obj)). +// So, it needs to be possible for different types of linked_ptr to participate +// in the same circular linked list, so we need a single class type here. +// +// DO NOT USE THIS CLASS DIRECTLY YOURSELF. Use linked_ptr<T>. +class linked_ptr_internal { + public: + // Create a new circle that includes only this instance. + void join_new() { + next_ = this; + } + + // Many linked_ptr operations may change p.link_ for some linked_ptr + // variable p in the same circle as this object. Therefore we need + // to prevent two such operations from occurring concurrently. + // + // Note that different types of linked_ptr objects can coexist in a + // circle (e.g. linked_ptr<Base>, linked_ptr<Derived1>, and + // linked_ptr<Derived2>). Therefore we must use a single mutex to + // protect all linked_ptr objects. This can create serious + // contention in production code, but is acceptable in a testing + // framework. + + // Join an existing circle. + // L < g_linked_ptr_mutex + void join(linked_ptr_internal const* ptr) { + MutexLock lock(&g_linked_ptr_mutex); + + linked_ptr_internal const* p = ptr; + while (p->next_ != ptr) p = p->next_; + p->next_ = this; + next_ = ptr; + } + + // Leave whatever circle we're part of. Returns true if we were the + // last member of the circle. Once this is done, you can join() another. + // L < g_linked_ptr_mutex + bool depart() { + MutexLock lock(&g_linked_ptr_mutex); + + if (next_ == this) return true; + linked_ptr_internal const* p = next_; + while (p->next_ != this) p = p->next_; + p->next_ = next_; + return false; + } + + private: + mutable linked_ptr_internal const* next_; +}; + +template <typename T> +class linked_ptr { + public: + typedef T element_type; + + // Take over ownership of a raw pointer. This should happen as soon as + // possible after the object is created. + explicit linked_ptr(T* ptr = NULL) { capture(ptr); } + ~linked_ptr() { depart(); } + + // Copy an existing linked_ptr<>, adding ourselves to the list of references. + template <typename U> linked_ptr(linked_ptr<U> const& ptr) { copy(&ptr); } + linked_ptr(linked_ptr const& ptr) { // NOLINT + assert(&ptr != this); + copy(&ptr); + } + + // Assignment releases the old value and acquires the new. + template <typename U> linked_ptr& operator=(linked_ptr<U> const& ptr) { + depart(); + copy(&ptr); + return *this; + } + + linked_ptr& operator=(linked_ptr const& ptr) { + if (&ptr != this) { + depart(); + copy(&ptr); + } + return *this; + } + + // Smart pointer members. + void reset(T* ptr = NULL) { + depart(); + capture(ptr); + } + T* get() const { return value_; } + T* operator->() const { return value_; } + T& operator*() const { return *value_; } + // Release ownership of the pointed object and returns it. + // Sole ownership by this linked_ptr object is required. + T* release() { + bool last = link_.depart(); + assert(last); + T* v = value_; + value_ = NULL; + return v; + } + + bool operator==(T* p) const { return value_ == p; } + bool operator!=(T* p) const { return value_ != p; } + template <typename U> + bool operator==(linked_ptr<U> const& ptr) const { + return value_ == ptr.get(); + } + template <typename U> + bool operator!=(linked_ptr<U> const& ptr) const { + return value_ != ptr.get(); + } + + private: + template <typename U> + friend class linked_ptr; + + T* value_; + linked_ptr_internal link_; + + void depart() { + if (link_.depart()) delete value_; + } + + void capture(T* ptr) { + value_ = ptr; + link_.join_new(); + } + + template <typename U> void copy(linked_ptr<U> const* ptr) { + value_ = ptr->get(); + if (value_) + link_.join(&ptr->link_); + else + link_.join_new(); + } +}; + +template<typename T> inline +bool operator==(T* ptr, const linked_ptr<T>& x) { + return ptr == x.get(); +} + +template<typename T> inline +bool operator!=(T* ptr, const linked_ptr<T>& x) { + return ptr != x.get(); +} + +// A function to convert T* into linked_ptr<T> +// Doing e.g. make_linked_ptr(new FooBarBaz<type>(arg)) is a shorter notation +// for linked_ptr<FooBarBaz<type> >(new FooBarBaz<type>(arg)) +template <typename T> +linked_ptr<T> make_linked_ptr(T* ptr) { + return linked_ptr<T>(ptr); +} + +} // namespace internal +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_ + +#if GTEST_HAS_PARAM_TEST + +namespace testing { +namespace internal { + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// Outputs a message explaining invalid registration of different +// fixture class for the same test case. This may happen when +// TEST_P macro is used to define two tests with the same name +// but in different namespaces. +GTEST_API_ void ReportInvalidTestCaseType(const char* test_case_name, + const char* file, int line); + +template <typename> class ParamGeneratorInterface; +template <typename> class ParamGenerator; + +// Interface for iterating over elements provided by an implementation +// of ParamGeneratorInterface<T>. +template <typename T> +class ParamIteratorInterface { + public: + virtual ~ParamIteratorInterface() {} + // A pointer to the base generator instance. + // Used only for the purposes of iterator comparison + // to make sure that two iterators belong to the same generator. + virtual const ParamGeneratorInterface<T>* BaseGenerator() const = 0; + // Advances iterator to point to the next element + // provided by the generator. The caller is responsible + // for not calling Advance() on an iterator equal to + // BaseGenerator()->End(). + virtual void Advance() = 0; + // Clones the iterator object. Used for implementing copy semantics + // of ParamIterator<T>. + virtual ParamIteratorInterface* Clone() const = 0; + // Dereferences the current iterator and provides (read-only) access + // to the pointed value. It is the caller's responsibility not to call + // Current() on an iterator equal to BaseGenerator()->End(). + // Used for implementing ParamGenerator<T>::operator*(). + virtual const T* Current() const = 0; + // Determines whether the given iterator and other point to the same + // element in the sequence generated by the generator. + // Used for implementing ParamGenerator<T>::operator==(). + virtual bool Equals(const ParamIteratorInterface& other) const = 0; +}; + +// Class iterating over elements provided by an implementation of +// ParamGeneratorInterface<T>. It wraps ParamIteratorInterface<T> +// and implements the const forward iterator concept. +template <typename T> +class ParamIterator { + public: + typedef T value_type; + typedef const T& reference; + typedef ptrdiff_t difference_type; + + // ParamIterator assumes ownership of the impl_ pointer. + ParamIterator(const ParamIterator& other) : impl_(other.impl_->Clone()) {} + ParamIterator& operator=(const ParamIterator& other) { + if (this != &other) + impl_.reset(other.impl_->Clone()); + return *this; + } + + const T& operator*() const { return *impl_->Current(); } + const T* operator->() const { return impl_->Current(); } + // Prefix version of operator++. + ParamIterator& operator++() { + impl_->Advance(); + return *this; + } + // Postfix version of operator++. + ParamIterator operator++(int /*unused*/) { + ParamIteratorInterface<T>* clone = impl_->Clone(); + impl_->Advance(); + return ParamIterator(clone); + } + bool operator==(const ParamIterator& other) const { + return impl_.get() == other.impl_.get() || impl_->Equals(*other.impl_); + } + bool operator!=(const ParamIterator& other) const { + return !(*this == other); + } + + private: + friend class ParamGenerator<T>; + explicit ParamIterator(ParamIteratorInterface<T>* impl) : impl_(impl) {} + scoped_ptr<ParamIteratorInterface<T> > impl_; +}; + +// ParamGeneratorInterface<T> is the binary interface to access generators +// defined in other translation units. +template <typename T> +class ParamGeneratorInterface { + public: + typedef T ParamType; + + virtual ~ParamGeneratorInterface() {} + + // Generator interface definition + virtual ParamIteratorInterface<T>* Begin() const = 0; + virtual ParamIteratorInterface<T>* End() const = 0; +}; + +// Wraps ParamGeneratorInterface<T> and provides general generator syntax +// compatible with the STL Container concept. +// This class implements copy initialization semantics and the contained +// ParamGeneratorInterface<T> instance is shared among all copies +// of the original object. This is possible because that instance is immutable. +template<typename T> +class ParamGenerator { + public: + typedef ParamIterator<T> iterator; + + explicit ParamGenerator(ParamGeneratorInterface<T>* impl) : impl_(impl) {} + ParamGenerator(const ParamGenerator& other) : impl_(other.impl_) {} + + ParamGenerator& operator=(const ParamGenerator& other) { + impl_ = other.impl_; + return *this; + } + + iterator begin() const { return iterator(impl_->Begin()); } + iterator end() const { return iterator(impl_->End()); } + + private: + ::testing::internal::linked_ptr<const ParamGeneratorInterface<T> > impl_; +}; + +// Generates values from a range of two comparable values. Can be used to +// generate sequences of user-defined types that implement operator+() and +// operator<(). +// This class is used in the Range() function. +template <typename T, typename IncrementT> +class RangeGenerator : public ParamGeneratorInterface<T> { + public: + RangeGenerator(T begin, T end, IncrementT step) + : begin_(begin), end_(end), + step_(step), end_index_(CalculateEndIndex(begin, end, step)) {} + virtual ~RangeGenerator() {} + + virtual ParamIteratorInterface<T>* Begin() const { + return new Iterator(this, begin_, 0, step_); + } + virtual ParamIteratorInterface<T>* End() const { + return new Iterator(this, end_, end_index_, step_); + } + + private: + class Iterator : public ParamIteratorInterface<T> { + public: + Iterator(const ParamGeneratorInterface<T>* base, T value, int index, + IncrementT step) + : base_(base), value_(value), index_(index), step_(step) {} + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface<T>* BaseGenerator() const { + return base_; + } + virtual void Advance() { + value_ = value_ + step_; + index_++; + } + virtual ParamIteratorInterface<T>* Clone() const { + return new Iterator(*this); + } + virtual const T* Current() const { return &value_; } + virtual bool Equals(const ParamIteratorInterface<T>& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const int other_index = + CheckedDowncastToActualType<const Iterator>(&other)->index_; + return index_ == other_index; + } + + private: + Iterator(const Iterator& other) + : ParamIteratorInterface<T>(), + base_(other.base_), value_(other.value_), index_(other.index_), + step_(other.step_) {} + + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + + const ParamGeneratorInterface<T>* const base_; + T value_; + int index_; + const IncrementT step_; + }; // class RangeGenerator::Iterator + + static int CalculateEndIndex(const T& begin, + const T& end, + const IncrementT& step) { + int end_index = 0; + for (T i = begin; i < end; i = i + step) + end_index++; + return end_index; + } + + // No implementation - assignment is unsupported. + void operator=(const RangeGenerator& other); + + const T begin_; + const T end_; + const IncrementT step_; + // The index for the end() iterator. All the elements in the generated + // sequence are indexed (0-based) to aid iterator comparison. + const int end_index_; +}; // class RangeGenerator + + +// Generates values from a pair of STL-style iterators. Used in the +// ValuesIn() function. The elements are copied from the source range +// since the source can be located on the stack, and the generator +// is likely to persist beyond that stack frame. +template <typename T> +class ValuesInIteratorRangeGenerator : public ParamGeneratorInterface<T> { + public: + template <typename ForwardIterator> + ValuesInIteratorRangeGenerator(ForwardIterator begin, ForwardIterator end) + : container_(begin, end) {} + virtual ~ValuesInIteratorRangeGenerator() {} + + virtual ParamIteratorInterface<T>* Begin() const { + return new Iterator(this, container_.begin()); + } + virtual ParamIteratorInterface<T>* End() const { + return new Iterator(this, container_.end()); + } + + private: + typedef typename ::std::vector<T> ContainerType; + + class Iterator : public ParamIteratorInterface<T> { + public: + Iterator(const ParamGeneratorInterface<T>* base, + typename ContainerType::const_iterator iterator) + : base_(base), iterator_(iterator) {} + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface<T>* BaseGenerator() const { + return base_; + } + virtual void Advance() { + ++iterator_; + value_.reset(); + } + virtual ParamIteratorInterface<T>* Clone() const { + return new Iterator(*this); + } + // We need to use cached value referenced by iterator_ because *iterator_ + // can return a temporary object (and of type other then T), so just + // having "return &*iterator_;" doesn't work. + // value_ is updated here and not in Advance() because Advance() + // can advance iterator_ beyond the end of the range, and we cannot + // detect that fact. The client code, on the other hand, is + // responsible for not calling Current() on an out-of-range iterator. + virtual const T* Current() const { + if (value_.get() == NULL) + value_.reset(new T(*iterator_)); + return value_.get(); + } + virtual bool Equals(const ParamIteratorInterface<T>& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + return iterator_ == + CheckedDowncastToActualType<const Iterator>(&other)->iterator_; + } + + private: + Iterator(const Iterator& other) + // The explicit constructor call suppresses a false warning + // emitted by gcc when supplied with the -Wextra option. + : ParamIteratorInterface<T>(), + base_(other.base_), + iterator_(other.iterator_) {} + + const ParamGeneratorInterface<T>* const base_; + typename ContainerType::const_iterator iterator_; + // A cached value of *iterator_. We keep it here to allow access by + // pointer in the wrapping iterator's operator->(). + // value_ needs to be mutable to be accessed in Current(). + // Use of scoped_ptr helps manage cached value's lifetime, + // which is bound by the lifespan of the iterator itself. + mutable scoped_ptr<const T> value_; + }; // class ValuesInIteratorRangeGenerator::Iterator + + // No implementation - assignment is unsupported. + void operator=(const ValuesInIteratorRangeGenerator& other); + + const ContainerType container_; +}; // class ValuesInIteratorRangeGenerator + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// Stores a parameter value and later creates tests parameterized with that +// value. +template <class TestClass> +class ParameterizedTestFactory : public TestFactoryBase { + public: + typedef typename TestClass::ParamType ParamType; + explicit ParameterizedTestFactory(ParamType parameter) : + parameter_(parameter) {} + virtual Test* CreateTest() { + TestClass::SetParam(¶meter_); + return new TestClass(); + } + + private: + const ParamType parameter_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestFactory); +}; + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// TestMetaFactoryBase is a base class for meta-factories that create +// test factories for passing into MakeAndRegisterTestInfo function. +template <class ParamType> +class TestMetaFactoryBase { + public: + virtual ~TestMetaFactoryBase() {} + + virtual TestFactoryBase* CreateTestFactory(ParamType parameter) = 0; +}; + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// TestMetaFactory creates test factories for passing into +// MakeAndRegisterTestInfo function. Since MakeAndRegisterTestInfo receives +// ownership of test factory pointer, same factory object cannot be passed +// into that method twice. But ParameterizedTestCaseInfo is going to call +// it for each Test/Parameter value combination. Thus it needs meta factory +// creator class. +template <class TestCase> +class TestMetaFactory + : public TestMetaFactoryBase<typename TestCase::ParamType> { + public: + typedef typename TestCase::ParamType ParamType; + + TestMetaFactory() {} + + virtual TestFactoryBase* CreateTestFactory(ParamType parameter) { + return new ParameterizedTestFactory<TestCase>(parameter); + } + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestMetaFactory); +}; + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// ParameterizedTestCaseInfoBase is a generic interface +// to ParameterizedTestCaseInfo classes. ParameterizedTestCaseInfoBase +// accumulates test information provided by TEST_P macro invocations +// and generators provided by INSTANTIATE_TEST_CASE_P macro invocations +// and uses that information to register all resulting test instances +// in RegisterTests method. The ParameterizeTestCaseRegistry class holds +// a collection of pointers to the ParameterizedTestCaseInfo objects +// and calls RegisterTests() on each of them when asked. +class ParameterizedTestCaseInfoBase { + public: + virtual ~ParameterizedTestCaseInfoBase() {} + + // Base part of test case name for display purposes. + virtual const String& GetTestCaseName() const = 0; + // Test case id to verify identity. + virtual TypeId GetTestCaseTypeId() const = 0; + // UnitTest class invokes this method to register tests in this + // test case right before running them in RUN_ALL_TESTS macro. + // This method should not be called more then once on any single + // instance of a ParameterizedTestCaseInfoBase derived class. + virtual void RegisterTests() = 0; + + protected: + ParameterizedTestCaseInfoBase() {} + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseInfoBase); +}; + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// ParameterizedTestCaseInfo accumulates tests obtained from TEST_P +// macro invocations for a particular test case and generators +// obtained from INSTANTIATE_TEST_CASE_P macro invocations for that +// test case. It registers tests with all values generated by all +// generators when asked. +template <class TestCase> +class ParameterizedTestCaseInfo : public ParameterizedTestCaseInfoBase { + public: + // ParamType and GeneratorCreationFunc are private types but are required + // for declarations of public methods AddTestPattern() and + // AddTestCaseInstantiation(). + typedef typename TestCase::ParamType ParamType; + // A function that returns an instance of appropriate generator type. + typedef ParamGenerator<ParamType>(GeneratorCreationFunc)(); + + explicit ParameterizedTestCaseInfo(const char* name) + : test_case_name_(name) {} + + // Test case base name for display purposes. + virtual const String& GetTestCaseName() const { return test_case_name_; } + // Test case id to verify identity. + virtual TypeId GetTestCaseTypeId() const { return GetTypeId<TestCase>(); } + // TEST_P macro uses AddTestPattern() to record information + // about a single test in a LocalTestInfo structure. + // test_case_name is the base name of the test case (without invocation + // prefix). test_base_name is the name of an individual test without + // parameter index. For the test SequenceA/FooTest.DoBar/1 FooTest is + // test case base name and DoBar is test base name. + void AddTestPattern(const char* test_case_name, + const char* test_base_name, + TestMetaFactoryBase<ParamType>* meta_factory) { + tests_.push_back(linked_ptr<TestInfo>(new TestInfo(test_case_name, + test_base_name, + meta_factory))); + } + // INSTANTIATE_TEST_CASE_P macro uses AddGenerator() to record information + // about a generator. + int AddTestCaseInstantiation(const char* instantiation_name, + GeneratorCreationFunc* func, + const char* /* file */, + int /* line */) { + instantiations_.push_back(::std::make_pair(instantiation_name, func)); + return 0; // Return value used only to run this method in namespace scope. + } + // UnitTest class invokes this method to register tests in this test case + // test cases right before running tests in RUN_ALL_TESTS macro. + // This method should not be called more then once on any single + // instance of a ParameterizedTestCaseInfoBase derived class. + // UnitTest has a guard to prevent from calling this method more then once. + virtual void RegisterTests() { + for (typename TestInfoContainer::iterator test_it = tests_.begin(); + test_it != tests_.end(); ++test_it) { + linked_ptr<TestInfo> test_info = *test_it; + for (typename InstantiationContainer::iterator gen_it = + instantiations_.begin(); gen_it != instantiations_.end(); + ++gen_it) { + const String& instantiation_name = gen_it->first; + ParamGenerator<ParamType> generator((*gen_it->second)()); + + Message test_case_name_stream; + if ( !instantiation_name.empty() ) + test_case_name_stream << instantiation_name.c_str() << "/"; + test_case_name_stream << test_info->test_case_base_name.c_str(); + + int i = 0; + for (typename ParamGenerator<ParamType>::iterator param_it = + generator.begin(); + param_it != generator.end(); ++param_it, ++i) { + Message test_name_stream; + test_name_stream << test_info->test_base_name.c_str() << "/" << i; + ::testing::internal::MakeAndRegisterTestInfo( + test_case_name_stream.GetString().c_str(), + test_name_stream.GetString().c_str(), + "", // test_case_comment + "", // comment; TODO(vladl@google.com): provide parameter value + // representation. + GetTestCaseTypeId(), + TestCase::SetUpTestCase, + TestCase::TearDownTestCase, + test_info->test_meta_factory->CreateTestFactory(*param_it)); + } // for param_it + } // for gen_it + } // for test_it + } // RegisterTests + + private: + // LocalTestInfo structure keeps information about a single test registered + // with TEST_P macro. + struct TestInfo { + TestInfo(const char* a_test_case_base_name, + const char* a_test_base_name, + TestMetaFactoryBase<ParamType>* a_test_meta_factory) : + test_case_base_name(a_test_case_base_name), + test_base_name(a_test_base_name), + test_meta_factory(a_test_meta_factory) {} + + const String test_case_base_name; + const String test_base_name; + const scoped_ptr<TestMetaFactoryBase<ParamType> > test_meta_factory; + }; + typedef ::std::vector<linked_ptr<TestInfo> > TestInfoContainer; + // Keeps pairs of <Instantiation name, Sequence generator creation function> + // received from INSTANTIATE_TEST_CASE_P macros. + typedef ::std::vector<std::pair<String, GeneratorCreationFunc*> > + InstantiationContainer; + + const String test_case_name_; + TestInfoContainer tests_; + InstantiationContainer instantiations_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseInfo); +}; // class ParameterizedTestCaseInfo + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// ParameterizedTestCaseRegistry contains a map of ParameterizedTestCaseInfoBase +// classes accessed by test case names. TEST_P and INSTANTIATE_TEST_CASE_P +// macros use it to locate their corresponding ParameterizedTestCaseInfo +// descriptors. +class ParameterizedTestCaseRegistry { + public: + ParameterizedTestCaseRegistry() {} + ~ParameterizedTestCaseRegistry() { + for (TestCaseInfoContainer::iterator it = test_case_infos_.begin(); + it != test_case_infos_.end(); ++it) { + delete *it; + } + } + + // Looks up or creates and returns a structure containing information about + // tests and instantiations of a particular test case. + template <class TestCase> + ParameterizedTestCaseInfo<TestCase>* GetTestCasePatternHolder( + const char* test_case_name, + const char* file, + int line) { + ParameterizedTestCaseInfo<TestCase>* typed_test_info = NULL; + for (TestCaseInfoContainer::iterator it = test_case_infos_.begin(); + it != test_case_infos_.end(); ++it) { + if ((*it)->GetTestCaseName() == test_case_name) { + if ((*it)->GetTestCaseTypeId() != GetTypeId<TestCase>()) { + // Complain about incorrect usage of Google Test facilities + // and terminate the program since we cannot guaranty correct + // test case setup and tear-down in this case. + ReportInvalidTestCaseType(test_case_name, file, line); + abort(); + } else { + // At this point we are sure that the object we found is of the same + // type we are looking for, so we downcast it to that type + // without further checks. + typed_test_info = CheckedDowncastToActualType< + ParameterizedTestCaseInfo<TestCase> >(*it); + } + break; + } + } + if (typed_test_info == NULL) { + typed_test_info = new ParameterizedTestCaseInfo<TestCase>(test_case_name); + test_case_infos_.push_back(typed_test_info); + } + return typed_test_info; + } + void RegisterTests() { + for (TestCaseInfoContainer::iterator it = test_case_infos_.begin(); + it != test_case_infos_.end(); ++it) { + (*it)->RegisterTests(); + } + } + + private: + typedef ::std::vector<ParameterizedTestCaseInfoBase*> TestCaseInfoContainer; + + TestCaseInfoContainer test_case_infos_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseRegistry); +}; + +} // namespace internal +} // namespace testing + +#endif // GTEST_HAS_PARAM_TEST + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_ +// This file was GENERATED by a script. DO NOT EDIT BY HAND!!! + +// Copyright 2008 Google Inc. +// All Rights Reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: vladl@google.com (Vlad Losev) + +// Type and function utilities for implementing parameterized tests. +// This file is generated by a SCRIPT. DO NOT EDIT BY HAND! +// +// Currently Google Test supports at most 50 arguments in Values, +// and at most 10 arguments in Combine. Please contact +// googletestframework@googlegroups.com if you need more. +// Please note that the number of arguments to Combine is limited +// by the maximum arity of the implementation of tr1::tuple which is +// currently set at 10. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_ + +// scripts/fuse_gtest.py depends on gtest's own header being #included +// *unconditionally*. Therefore these #includes cannot be moved +// inside #if GTEST_HAS_PARAM_TEST. + +#if GTEST_HAS_PARAM_TEST + +namespace testing { + +// Forward declarations of ValuesIn(), which is implemented in +// include/gtest/gtest-param-test.h. +template <typename ForwardIterator> +internal::ParamGenerator< + typename ::std::iterator_traits<ForwardIterator>::value_type> ValuesIn( + ForwardIterator begin, ForwardIterator end); + +template <typename T, size_t N> +internal::ParamGenerator<T> ValuesIn(const T (&array)[N]); + +template <class Container> +internal::ParamGenerator<typename Container::value_type> ValuesIn( + const Container& container); + +namespace internal { + +// Used in the Values() function to provide polymorphic capabilities. +template <typename T1> +class ValueArray1 { + public: + explicit ValueArray1(T1 v1) : v1_(v1) {} + + template <typename T> + operator ParamGenerator<T>() const { return ValuesIn(&v1_, &v1_ + 1); } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray1& other); + + const T1 v1_; +}; + +template <typename T1, typename T2> +class ValueArray2 { + public: + ValueArray2(T1 v1, T2 v2) : v1_(v1), v2_(v2) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray2& other); + + const T1 v1_; + const T2 v2_; +}; + +template <typename T1, typename T2, typename T3> +class ValueArray3 { + public: + ValueArray3(T1 v1, T2 v2, T3 v3) : v1_(v1), v2_(v2), v3_(v3) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray3& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; +}; + +template <typename T1, typename T2, typename T3, typename T4> +class ValueArray4 { + public: + ValueArray4(T1 v1, T2 v2, T3 v3, T4 v4) : v1_(v1), v2_(v2), v3_(v3), + v4_(v4) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray4& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5> +class ValueArray5 { + public: + ValueArray5(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5) : v1_(v1), v2_(v2), v3_(v3), + v4_(v4), v5_(v5) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray5& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6> +class ValueArray6 { + public: + ValueArray6(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6) : v1_(v1), v2_(v2), + v3_(v3), v4_(v4), v5_(v5), v6_(v6) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray6& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7> +class ValueArray7 { + public: + ValueArray7(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7) : v1_(v1), + v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray7& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8> +class ValueArray8 { + public: + ValueArray8(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, + T8 v8) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray8& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9> +class ValueArray9 { + public: + ValueArray9(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, + T9 v9) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray9& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10> +class ValueArray10 { + public: + ValueArray10(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray10& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11> +class ValueArray11 { + public: + ValueArray11(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), + v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray11& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12> +class ValueArray12 { + public: + ValueArray12(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), + v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray12& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13> +class ValueArray13 { + public: + ValueArray13(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), + v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), + v12_(v12), v13_(v13) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray13& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14> +class ValueArray14 { + public: + ValueArray14(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14) : v1_(v1), v2_(v2), v3_(v3), + v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), + v11_(v11), v12_(v12), v13_(v13), v14_(v14) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray14& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15> +class ValueArray15 { + public: + ValueArray15(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15) : v1_(v1), v2_(v2), + v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), + v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray15& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16> +class ValueArray16 { + public: + ValueArray16(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16) : v1_(v1), + v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), + v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), + v16_(v16) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray16& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17> +class ValueArray17 { + public: + ValueArray17(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, + T17 v17) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), + v15_(v15), v16_(v16), v17_(v17) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray17& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18> +class ValueArray18 { + public: + ValueArray18(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), + v15_(v15), v16_(v16), v17_(v17), v18_(v18) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray18& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19> +class ValueArray19 { + public: + ValueArray19(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), + v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), + v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray19& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20> +class ValueArray20 { + public: + ValueArray20(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), + v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), + v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), + v19_(v19), v20_(v20) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray20& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21> +class ValueArray21 { + public: + ValueArray21(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), + v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), + v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), + v18_(v18), v19_(v19), v20_(v20), v21_(v21) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray21& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22> +class ValueArray22 { + public: + ValueArray22(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22) : v1_(v1), v2_(v2), v3_(v3), + v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), + v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), + v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray22& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23> +class ValueArray23 { + public: + ValueArray23(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23) : v1_(v1), v2_(v2), + v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), + v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), + v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), + v23_(v23) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, + v23_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray23& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24> +class ValueArray24 { + public: + ValueArray24(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24) : v1_(v1), + v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), + v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), + v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), + v22_(v22), v23_(v23), v24_(v24) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray24& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25> +class ValueArray25 { + public: + ValueArray25(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, + T25 v25) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), + v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), + v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray25& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26> +class ValueArray26 { + public: + ValueArray26(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), + v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), + v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray26& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27> +class ValueArray27 { + public: + ValueArray27(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), + v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), + v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), + v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), + v26_(v26), v27_(v27) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray27& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28> +class ValueArray28 { + public: + ValueArray28(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), + v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), + v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), + v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), + v25_(v25), v26_(v26), v27_(v27), v28_(v28) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray28& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29> +class ValueArray29 { + public: + ValueArray29(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), + v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), + v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), + v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), + v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray29& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30> +class ValueArray30 { + public: + ValueArray30(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30) : v1_(v1), v2_(v2), v3_(v3), + v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), + v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), + v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), + v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), + v29_(v29), v30_(v30) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_, v30_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray30& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31> +class ValueArray31 { + public: + ValueArray31(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31) : v1_(v1), v2_(v2), + v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), + v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), + v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), + v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), + v29_(v29), v30_(v30), v31_(v31) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray31& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32> +class ValueArray32 { + public: + ValueArray32(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32) : v1_(v1), + v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), + v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), + v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), + v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), + v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray32& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33> +class ValueArray33 { + public: + ValueArray33(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, + T33 v33) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), + v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), + v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), + v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), + v33_(v33) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray33& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34> +class ValueArray34 { + public: + ValueArray34(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), + v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), + v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), + v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), + v33_(v33), v34_(v34) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray34& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35> +class ValueArray35 { + public: + ValueArray35(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), + v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), + v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), + v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), + v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), + v32_(v32), v33_(v33), v34_(v34), v35_(v35) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, + v35_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray35& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36> +class ValueArray36 { + public: + ValueArray36(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), + v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), + v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), + v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), + v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), + v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, + v36_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray36& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37> +class ValueArray37 { + public: + ValueArray37(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), + v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), + v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), + v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), + v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), + v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), + v36_(v36), v37_(v37) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, + v36_, v37_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray37& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38> +class ValueArray38 { + public: + ValueArray38(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38) : v1_(v1), v2_(v2), v3_(v3), + v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), + v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), + v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), + v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), + v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), + v35_(v35), v36_(v36), v37_(v37), v38_(v38) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, + v36_, v37_, v38_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray38& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39> +class ValueArray39 { + public: + ValueArray39(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39) : v1_(v1), v2_(v2), + v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), + v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), + v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), + v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), + v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), + v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, + v36_, v37_, v38_, v39_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray39& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40> +class ValueArray40 { + public: + ValueArray40(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40) : v1_(v1), + v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), + v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), + v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), + v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), + v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), + v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), + v40_(v40) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, + v36_, v37_, v38_, v39_, v40_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray40& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41> +class ValueArray41 { + public: + ValueArray41(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, + T41 v41) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), + v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), + v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), + v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), + v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), + v39_(v39), v40_(v40), v41_(v41) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, + v36_, v37_, v38_, v39_, v40_, v41_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray41& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42> +class ValueArray42 { + public: + ValueArray42(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), + v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), + v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), + v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), + v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), + v39_(v39), v40_(v40), v41_(v41), v42_(v42) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, + v36_, v37_, v38_, v39_, v40_, v41_, v42_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray42& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; + const T42 v42_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43> +class ValueArray43 { + public: + ValueArray43(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), + v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), + v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), + v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), + v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), + v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), + v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, + v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray43& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; + const T42 v42_; + const T43 v43_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43, typename T44> +class ValueArray44 { + public: + ValueArray44(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43, T44 v44) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), + v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), + v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), + v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), + v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), + v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), + v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42), + v43_(v43), v44_(v44) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, + v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray44& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; + const T42 v42_; + const T43 v43_; + const T44 v44_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43, typename T44, typename T45> +class ValueArray45 { + public: + ValueArray45(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43, T44 v44, T45 v45) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), + v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), + v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), + v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), + v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), + v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), + v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41), + v42_(v42), v43_(v43), v44_(v44), v45_(v45) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, + v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_, v45_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray45& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; + const T42 v42_; + const T43 v43_; + const T44 v44_; + const T45 v45_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43, typename T44, typename T45, + typename T46> +class ValueArray46 { + public: + ValueArray46(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43, T44 v44, T45 v45, T46 v46) : v1_(v1), v2_(v2), v3_(v3), + v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), + v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), + v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), + v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), + v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), + v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), + v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45), v46_(v46) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, + v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_, v45_, v46_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray46& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; + const T42 v42_; + const T43 v43_; + const T44 v44_; + const T45 v45_; + const T46 v46_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43, typename T44, typename T45, + typename T46, typename T47> +class ValueArray47 { + public: + ValueArray47(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47) : v1_(v1), v2_(v2), + v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), + v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), + v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), + v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), + v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), + v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), + v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45), v46_(v46), + v47_(v47) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, + v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_, v45_, v46_, + v47_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray47& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; + const T42 v42_; + const T43 v43_; + const T44 v44_; + const T45 v45_; + const T46 v46_; + const T47 v47_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43, typename T44, typename T45, + typename T46, typename T47, typename T48> +class ValueArray48 { + public: + ValueArray48(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48) : v1_(v1), + v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), + v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), + v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), + v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), + v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), + v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), + v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45), + v46_(v46), v47_(v47), v48_(v48) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, + v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_, v45_, v46_, v47_, + v48_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray48& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; + const T42 v42_; + const T43 v43_; + const T44 v44_; + const T45 v45_; + const T46 v46_; + const T47 v47_; + const T48 v48_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43, typename T44, typename T45, + typename T46, typename T47, typename T48, typename T49> +class ValueArray49 { + public: + ValueArray49(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48, + T49 v49) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), + v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), + v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), + v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), + v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), + v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44), + v45_(v45), v46_(v46), v47_(v47), v48_(v48), v49_(v49) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, + v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_, v45_, v46_, v47_, + v48_, v49_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray49& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; + const T42 v42_; + const T43 v43_; + const T44 v44_; + const T45 v45_; + const T46 v46_; + const T47 v47_; + const T48 v48_; + const T49 v49_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43, typename T44, typename T45, + typename T46, typename T47, typename T48, typename T49, typename T50> +class ValueArray50 { + public: + ValueArray50(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48, T49 v49, + T50 v50) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), + v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), + v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), + v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), + v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), + v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44), + v45_(v45), v46_(v46), v47_(v47), v48_(v48), v49_(v49), v50_(v50) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, + v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_, v45_, v46_, v47_, + v48_, v49_, v50_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray50& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; + const T42 v42_; + const T43 v43_; + const T44 v44_; + const T45 v45_; + const T46 v46_; + const T47 v47_; + const T48 v48_; + const T49 v49_; + const T50 v50_; +}; + +#if GTEST_HAS_COMBINE +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// Generates values from the Cartesian product of values produced +// by the argument generators. +// +template <typename T1, typename T2> +class CartesianProductGenerator2 + : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2> > { + public: + typedef ::std::tr1::tuple<T1, T2> ParamType; + + CartesianProductGenerator2(const ParamGenerator<T1>& g1, + const ParamGenerator<T2>& g2) + : g1_(g1), g2_(g2) {} + virtual ~CartesianProductGenerator2() {} + + virtual ParamIteratorInterface<ParamType>* Begin() const { + return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin()); + } + virtual ParamIteratorInterface<ParamType>* End() const { + return new Iterator(this, g1_, g1_.end(), g2_, g2_.end()); + } + + private: + class Iterator : public ParamIteratorInterface<ParamType> { + public: + Iterator(const ParamGeneratorInterface<ParamType>* base, + const ParamGenerator<T1>& g1, + const typename ParamGenerator<T1>::iterator& current1, + const ParamGenerator<T2>& g2, + const typename ParamGenerator<T2>::iterator& current2) + : base_(base), + begin1_(g1.begin()), end1_(g1.end()), current1_(current1), + begin2_(g2.begin()), end2_(g2.end()), current2_(current2) { + ComputeCurrentValue(); + } + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const { + return base_; + } + // Advance should not be called on beyond-of-range iterators + // so no component iterators must be beyond end of range, either. + virtual void Advance() { + assert(!AtEnd()); + ++current2_; + if (current2_ == end2_) { + current2_ = begin2_; + ++current1_; + } + ComputeCurrentValue(); + } + virtual ParamIteratorInterface<ParamType>* Clone() const { + return new Iterator(*this); + } + virtual const ParamType* Current() const { return ¤t_value_; } + virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const Iterator* typed_other = + CheckedDowncastToActualType<const Iterator>(&other); + // We must report iterators equal if they both point beyond their + // respective ranges. That can happen in a variety of fashions, + // so we have to consult AtEnd(). + return (AtEnd() && typed_other->AtEnd()) || + ( + current1_ == typed_other->current1_ && + current2_ == typed_other->current2_); + } + + private: + Iterator(const Iterator& other) + : base_(other.base_), + begin1_(other.begin1_), + end1_(other.end1_), + current1_(other.current1_), + begin2_(other.begin2_), + end2_(other.end2_), + current2_(other.current2_) { + ComputeCurrentValue(); + } + + void ComputeCurrentValue() { + if (!AtEnd()) + current_value_ = ParamType(*current1_, *current2_); + } + bool AtEnd() const { + // We must report iterator past the end of the range when either of the + // component iterators has reached the end of its range. + return + current1_ == end1_ || + current2_ == end2_; + } + + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + + const ParamGeneratorInterface<ParamType>* const base_; + // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. + // current[i]_ is the actual traversing iterator. + const typename ParamGenerator<T1>::iterator begin1_; + const typename ParamGenerator<T1>::iterator end1_; + typename ParamGenerator<T1>::iterator current1_; + const typename ParamGenerator<T2>::iterator begin2_; + const typename ParamGenerator<T2>::iterator end2_; + typename ParamGenerator<T2>::iterator current2_; + ParamType current_value_; + }; // class CartesianProductGenerator2::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator2& other); + + const ParamGenerator<T1> g1_; + const ParamGenerator<T2> g2_; +}; // class CartesianProductGenerator2 + + +template <typename T1, typename T2, typename T3> +class CartesianProductGenerator3 + : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3> > { + public: + typedef ::std::tr1::tuple<T1, T2, T3> ParamType; + + CartesianProductGenerator3(const ParamGenerator<T1>& g1, + const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3) + : g1_(g1), g2_(g2), g3_(g3) {} + virtual ~CartesianProductGenerator3() {} + + virtual ParamIteratorInterface<ParamType>* Begin() const { + return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, + g3_.begin()); + } + virtual ParamIteratorInterface<ParamType>* End() const { + return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end()); + } + + private: + class Iterator : public ParamIteratorInterface<ParamType> { + public: + Iterator(const ParamGeneratorInterface<ParamType>* base, + const ParamGenerator<T1>& g1, + const typename ParamGenerator<T1>::iterator& current1, + const ParamGenerator<T2>& g2, + const typename ParamGenerator<T2>::iterator& current2, + const ParamGenerator<T3>& g3, + const typename ParamGenerator<T3>::iterator& current3) + : base_(base), + begin1_(g1.begin()), end1_(g1.end()), current1_(current1), + begin2_(g2.begin()), end2_(g2.end()), current2_(current2), + begin3_(g3.begin()), end3_(g3.end()), current3_(current3) { + ComputeCurrentValue(); + } + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const { + return base_; + } + // Advance should not be called on beyond-of-range iterators + // so no component iterators must be beyond end of range, either. + virtual void Advance() { + assert(!AtEnd()); + ++current3_; + if (current3_ == end3_) { + current3_ = begin3_; + ++current2_; + } + if (current2_ == end2_) { + current2_ = begin2_; + ++current1_; + } + ComputeCurrentValue(); + } + virtual ParamIteratorInterface<ParamType>* Clone() const { + return new Iterator(*this); + } + virtual const ParamType* Current() const { return ¤t_value_; } + virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const Iterator* typed_other = + CheckedDowncastToActualType<const Iterator>(&other); + // We must report iterators equal if they both point beyond their + // respective ranges. That can happen in a variety of fashions, + // so we have to consult AtEnd(). + return (AtEnd() && typed_other->AtEnd()) || + ( + current1_ == typed_other->current1_ && + current2_ == typed_other->current2_ && + current3_ == typed_other->current3_); + } + + private: + Iterator(const Iterator& other) + : base_(other.base_), + begin1_(other.begin1_), + end1_(other.end1_), + current1_(other.current1_), + begin2_(other.begin2_), + end2_(other.end2_), + current2_(other.current2_), + begin3_(other.begin3_), + end3_(other.end3_), + current3_(other.current3_) { + ComputeCurrentValue(); + } + + void ComputeCurrentValue() { + if (!AtEnd()) + current_value_ = ParamType(*current1_, *current2_, *current3_); + } + bool AtEnd() const { + // We must report iterator past the end of the range when either of the + // component iterators has reached the end of its range. + return + current1_ == end1_ || + current2_ == end2_ || + current3_ == end3_; + } + + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + + const ParamGeneratorInterface<ParamType>* const base_; + // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. + // current[i]_ is the actual traversing iterator. + const typename ParamGenerator<T1>::iterator begin1_; + const typename ParamGenerator<T1>::iterator end1_; + typename ParamGenerator<T1>::iterator current1_; + const typename ParamGenerator<T2>::iterator begin2_; + const typename ParamGenerator<T2>::iterator end2_; + typename ParamGenerator<T2>::iterator current2_; + const typename ParamGenerator<T3>::iterator begin3_; + const typename ParamGenerator<T3>::iterator end3_; + typename ParamGenerator<T3>::iterator current3_; + ParamType current_value_; + }; // class CartesianProductGenerator3::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator3& other); + + const ParamGenerator<T1> g1_; + const ParamGenerator<T2> g2_; + const ParamGenerator<T3> g3_; +}; // class CartesianProductGenerator3 + + +template <typename T1, typename T2, typename T3, typename T4> +class CartesianProductGenerator4 + : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4> > { + public: + typedef ::std::tr1::tuple<T1, T2, T3, T4> ParamType; + + CartesianProductGenerator4(const ParamGenerator<T1>& g1, + const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3, + const ParamGenerator<T4>& g4) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4) {} + virtual ~CartesianProductGenerator4() {} + + virtual ParamIteratorInterface<ParamType>* Begin() const { + return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, + g3_.begin(), g4_, g4_.begin()); + } + virtual ParamIteratorInterface<ParamType>* End() const { + return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), + g4_, g4_.end()); + } + + private: + class Iterator : public ParamIteratorInterface<ParamType> { + public: + Iterator(const ParamGeneratorInterface<ParamType>* base, + const ParamGenerator<T1>& g1, + const typename ParamGenerator<T1>::iterator& current1, + const ParamGenerator<T2>& g2, + const typename ParamGenerator<T2>::iterator& current2, + const ParamGenerator<T3>& g3, + const typename ParamGenerator<T3>::iterator& current3, + const ParamGenerator<T4>& g4, + const typename ParamGenerator<T4>::iterator& current4) + : base_(base), + begin1_(g1.begin()), end1_(g1.end()), current1_(current1), + begin2_(g2.begin()), end2_(g2.end()), current2_(current2), + begin3_(g3.begin()), end3_(g3.end()), current3_(current3), + begin4_(g4.begin()), end4_(g4.end()), current4_(current4) { + ComputeCurrentValue(); + } + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const { + return base_; + } + // Advance should not be called on beyond-of-range iterators + // so no component iterators must be beyond end of range, either. + virtual void Advance() { + assert(!AtEnd()); + ++current4_; + if (current4_ == end4_) { + current4_ = begin4_; + ++current3_; + } + if (current3_ == end3_) { + current3_ = begin3_; + ++current2_; + } + if (current2_ == end2_) { + current2_ = begin2_; + ++current1_; + } + ComputeCurrentValue(); + } + virtual ParamIteratorInterface<ParamType>* Clone() const { + return new Iterator(*this); + } + virtual const ParamType* Current() const { return ¤t_value_; } + virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const Iterator* typed_other = + CheckedDowncastToActualType<const Iterator>(&other); + // We must report iterators equal if they both point beyond their + // respective ranges. That can happen in a variety of fashions, + // so we have to consult AtEnd(). + return (AtEnd() && typed_other->AtEnd()) || + ( + current1_ == typed_other->current1_ && + current2_ == typed_other->current2_ && + current3_ == typed_other->current3_ && + current4_ == typed_other->current4_); + } + + private: + Iterator(const Iterator& other) + : base_(other.base_), + begin1_(other.begin1_), + end1_(other.end1_), + current1_(other.current1_), + begin2_(other.begin2_), + end2_(other.end2_), + current2_(other.current2_), + begin3_(other.begin3_), + end3_(other.end3_), + current3_(other.current3_), + begin4_(other.begin4_), + end4_(other.end4_), + current4_(other.current4_) { + ComputeCurrentValue(); + } + + void ComputeCurrentValue() { + if (!AtEnd()) + current_value_ = ParamType(*current1_, *current2_, *current3_, + *current4_); + } + bool AtEnd() const { + // We must report iterator past the end of the range when either of the + // component iterators has reached the end of its range. + return + current1_ == end1_ || + current2_ == end2_ || + current3_ == end3_ || + current4_ == end4_; + } + + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + + const ParamGeneratorInterface<ParamType>* const base_; + // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. + // current[i]_ is the actual traversing iterator. + const typename ParamGenerator<T1>::iterator begin1_; + const typename ParamGenerator<T1>::iterator end1_; + typename ParamGenerator<T1>::iterator current1_; + const typename ParamGenerator<T2>::iterator begin2_; + const typename ParamGenerator<T2>::iterator end2_; + typename ParamGenerator<T2>::iterator current2_; + const typename ParamGenerator<T3>::iterator begin3_; + const typename ParamGenerator<T3>::iterator end3_; + typename ParamGenerator<T3>::iterator current3_; + const typename ParamGenerator<T4>::iterator begin4_; + const typename ParamGenerator<T4>::iterator end4_; + typename ParamGenerator<T4>::iterator current4_; + ParamType current_value_; + }; // class CartesianProductGenerator4::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator4& other); + + const ParamGenerator<T1> g1_; + const ParamGenerator<T2> g2_; + const ParamGenerator<T3> g3_; + const ParamGenerator<T4> g4_; +}; // class CartesianProductGenerator4 + + +template <typename T1, typename T2, typename T3, typename T4, typename T5> +class CartesianProductGenerator5 + : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4, T5> > { + public: + typedef ::std::tr1::tuple<T1, T2, T3, T4, T5> ParamType; + + CartesianProductGenerator5(const ParamGenerator<T1>& g1, + const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3, + const ParamGenerator<T4>& g4, const ParamGenerator<T5>& g5) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5) {} + virtual ~CartesianProductGenerator5() {} + + virtual ParamIteratorInterface<ParamType>* Begin() const { + return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, + g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin()); + } + virtual ParamIteratorInterface<ParamType>* End() const { + return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), + g4_, g4_.end(), g5_, g5_.end()); + } + + private: + class Iterator : public ParamIteratorInterface<ParamType> { + public: + Iterator(const ParamGeneratorInterface<ParamType>* base, + const ParamGenerator<T1>& g1, + const typename ParamGenerator<T1>::iterator& current1, + const ParamGenerator<T2>& g2, + const typename ParamGenerator<T2>::iterator& current2, + const ParamGenerator<T3>& g3, + const typename ParamGenerator<T3>::iterator& current3, + const ParamGenerator<T4>& g4, + const typename ParamGenerator<T4>::iterator& current4, + const ParamGenerator<T5>& g5, + const typename ParamGenerator<T5>::iterator& current5) + : base_(base), + begin1_(g1.begin()), end1_(g1.end()), current1_(current1), + begin2_(g2.begin()), end2_(g2.end()), current2_(current2), + begin3_(g3.begin()), end3_(g3.end()), current3_(current3), + begin4_(g4.begin()), end4_(g4.end()), current4_(current4), + begin5_(g5.begin()), end5_(g5.end()), current5_(current5) { + ComputeCurrentValue(); + } + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const { + return base_; + } + // Advance should not be called on beyond-of-range iterators + // so no component iterators must be beyond end of range, either. + virtual void Advance() { + assert(!AtEnd()); + ++current5_; + if (current5_ == end5_) { + current5_ = begin5_; + ++current4_; + } + if (current4_ == end4_) { + current4_ = begin4_; + ++current3_; + } + if (current3_ == end3_) { + current3_ = begin3_; + ++current2_; + } + if (current2_ == end2_) { + current2_ = begin2_; + ++current1_; + } + ComputeCurrentValue(); + } + virtual ParamIteratorInterface<ParamType>* Clone() const { + return new Iterator(*this); + } + virtual const ParamType* Current() const { return ¤t_value_; } + virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const Iterator* typed_other = + CheckedDowncastToActualType<const Iterator>(&other); + // We must report iterators equal if they both point beyond their + // respective ranges. That can happen in a variety of fashions, + // so we have to consult AtEnd(). + return (AtEnd() && typed_other->AtEnd()) || + ( + current1_ == typed_other->current1_ && + current2_ == typed_other->current2_ && + current3_ == typed_other->current3_ && + current4_ == typed_other->current4_ && + current5_ == typed_other->current5_); + } + + private: + Iterator(const Iterator& other) + : base_(other.base_), + begin1_(other.begin1_), + end1_(other.end1_), + current1_(other.current1_), + begin2_(other.begin2_), + end2_(other.end2_), + current2_(other.current2_), + begin3_(other.begin3_), + end3_(other.end3_), + current3_(other.current3_), + begin4_(other.begin4_), + end4_(other.end4_), + current4_(other.current4_), + begin5_(other.begin5_), + end5_(other.end5_), + current5_(other.current5_) { + ComputeCurrentValue(); + } + + void ComputeCurrentValue() { + if (!AtEnd()) + current_value_ = ParamType(*current1_, *current2_, *current3_, + *current4_, *current5_); + } + bool AtEnd() const { + // We must report iterator past the end of the range when either of the + // component iterators has reached the end of its range. + return + current1_ == end1_ || + current2_ == end2_ || + current3_ == end3_ || + current4_ == end4_ || + current5_ == end5_; + } + + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + + const ParamGeneratorInterface<ParamType>* const base_; + // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. + // current[i]_ is the actual traversing iterator. + const typename ParamGenerator<T1>::iterator begin1_; + const typename ParamGenerator<T1>::iterator end1_; + typename ParamGenerator<T1>::iterator current1_; + const typename ParamGenerator<T2>::iterator begin2_; + const typename ParamGenerator<T2>::iterator end2_; + typename ParamGenerator<T2>::iterator current2_; + const typename ParamGenerator<T3>::iterator begin3_; + const typename ParamGenerator<T3>::iterator end3_; + typename ParamGenerator<T3>::iterator current3_; + const typename ParamGenerator<T4>::iterator begin4_; + const typename ParamGenerator<T4>::iterator end4_; + typename ParamGenerator<T4>::iterator current4_; + const typename ParamGenerator<T5>::iterator begin5_; + const typename ParamGenerator<T5>::iterator end5_; + typename ParamGenerator<T5>::iterator current5_; + ParamType current_value_; + }; // class CartesianProductGenerator5::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator5& other); + + const ParamGenerator<T1> g1_; + const ParamGenerator<T2> g2_; + const ParamGenerator<T3> g3_; + const ParamGenerator<T4> g4_; + const ParamGenerator<T5> g5_; +}; // class CartesianProductGenerator5 + + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6> +class CartesianProductGenerator6 + : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4, T5, + T6> > { + public: + typedef ::std::tr1::tuple<T1, T2, T3, T4, T5, T6> ParamType; + + CartesianProductGenerator6(const ParamGenerator<T1>& g1, + const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3, + const ParamGenerator<T4>& g4, const ParamGenerator<T5>& g5, + const ParamGenerator<T6>& g6) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6) {} + virtual ~CartesianProductGenerator6() {} + + virtual ParamIteratorInterface<ParamType>* Begin() const { + return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, + g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin()); + } + virtual ParamIteratorInterface<ParamType>* End() const { + return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), + g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end()); + } + + private: + class Iterator : public ParamIteratorInterface<ParamType> { + public: + Iterator(const ParamGeneratorInterface<ParamType>* base, + const ParamGenerator<T1>& g1, + const typename ParamGenerator<T1>::iterator& current1, + const ParamGenerator<T2>& g2, + const typename ParamGenerator<T2>::iterator& current2, + const ParamGenerator<T3>& g3, + const typename ParamGenerator<T3>::iterator& current3, + const ParamGenerator<T4>& g4, + const typename ParamGenerator<T4>::iterator& current4, + const ParamGenerator<T5>& g5, + const typename ParamGenerator<T5>::iterator& current5, + const ParamGenerator<T6>& g6, + const typename ParamGenerator<T6>::iterator& current6) + : base_(base), + begin1_(g1.begin()), end1_(g1.end()), current1_(current1), + begin2_(g2.begin()), end2_(g2.end()), current2_(current2), + begin3_(g3.begin()), end3_(g3.end()), current3_(current3), + begin4_(g4.begin()), end4_(g4.end()), current4_(current4), + begin5_(g5.begin()), end5_(g5.end()), current5_(current5), + begin6_(g6.begin()), end6_(g6.end()), current6_(current6) { + ComputeCurrentValue(); + } + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const { + return base_; + } + // Advance should not be called on beyond-of-range iterators + // so no component iterators must be beyond end of range, either. + virtual void Advance() { + assert(!AtEnd()); + ++current6_; + if (current6_ == end6_) { + current6_ = begin6_; + ++current5_; + } + if (current5_ == end5_) { + current5_ = begin5_; + ++current4_; + } + if (current4_ == end4_) { + current4_ = begin4_; + ++current3_; + } + if (current3_ == end3_) { + current3_ = begin3_; + ++current2_; + } + if (current2_ == end2_) { + current2_ = begin2_; + ++current1_; + } + ComputeCurrentValue(); + } + virtual ParamIteratorInterface<ParamType>* Clone() const { + return new Iterator(*this); + } + virtual const ParamType* Current() const { return ¤t_value_; } + virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const Iterator* typed_other = + CheckedDowncastToActualType<const Iterator>(&other); + // We must report iterators equal if they both point beyond their + // respective ranges. That can happen in a variety of fashions, + // so we have to consult AtEnd(). + return (AtEnd() && typed_other->AtEnd()) || + ( + current1_ == typed_other->current1_ && + current2_ == typed_other->current2_ && + current3_ == typed_other->current3_ && + current4_ == typed_other->current4_ && + current5_ == typed_other->current5_ && + current6_ == typed_other->current6_); + } + + private: + Iterator(const Iterator& other) + : base_(other.base_), + begin1_(other.begin1_), + end1_(other.end1_), + current1_(other.current1_), + begin2_(other.begin2_), + end2_(other.end2_), + current2_(other.current2_), + begin3_(other.begin3_), + end3_(other.end3_), + current3_(other.current3_), + begin4_(other.begin4_), + end4_(other.end4_), + current4_(other.current4_), + begin5_(other.begin5_), + end5_(other.end5_), + current5_(other.current5_), + begin6_(other.begin6_), + end6_(other.end6_), + current6_(other.current6_) { + ComputeCurrentValue(); + } + + void ComputeCurrentValue() { + if (!AtEnd()) + current_value_ = ParamType(*current1_, *current2_, *current3_, + *current4_, *current5_, *current6_); + } + bool AtEnd() const { + // We must report iterator past the end of the range when either of the + // component iterators has reached the end of its range. + return + current1_ == end1_ || + current2_ == end2_ || + current3_ == end3_ || + current4_ == end4_ || + current5_ == end5_ || + current6_ == end6_; + } + + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + + const ParamGeneratorInterface<ParamType>* const base_; + // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. + // current[i]_ is the actual traversing iterator. + const typename ParamGenerator<T1>::iterator begin1_; + const typename ParamGenerator<T1>::iterator end1_; + typename ParamGenerator<T1>::iterator current1_; + const typename ParamGenerator<T2>::iterator begin2_; + const typename ParamGenerator<T2>::iterator end2_; + typename ParamGenerator<T2>::iterator current2_; + const typename ParamGenerator<T3>::iterator begin3_; + const typename ParamGenerator<T3>::iterator end3_; + typename ParamGenerator<T3>::iterator current3_; + const typename ParamGenerator<T4>::iterator begin4_; + const typename ParamGenerator<T4>::iterator end4_; + typename ParamGenerator<T4>::iterator current4_; + const typename ParamGenerator<T5>::iterator begin5_; + const typename ParamGenerator<T5>::iterator end5_; + typename ParamGenerator<T5>::iterator current5_; + const typename ParamGenerator<T6>::iterator begin6_; + const typename ParamGenerator<T6>::iterator end6_; + typename ParamGenerator<T6>::iterator current6_; + ParamType current_value_; + }; // class CartesianProductGenerator6::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator6& other); + + const ParamGenerator<T1> g1_; + const ParamGenerator<T2> g2_; + const ParamGenerator<T3> g3_; + const ParamGenerator<T4> g4_; + const ParamGenerator<T5> g5_; + const ParamGenerator<T6> g6_; +}; // class CartesianProductGenerator6 + + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7> +class CartesianProductGenerator7 + : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, + T7> > { + public: + typedef ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7> ParamType; + + CartesianProductGenerator7(const ParamGenerator<T1>& g1, + const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3, + const ParamGenerator<T4>& g4, const ParamGenerator<T5>& g5, + const ParamGenerator<T6>& g6, const ParamGenerator<T7>& g7) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7) {} + virtual ~CartesianProductGenerator7() {} + + virtual ParamIteratorInterface<ParamType>* Begin() const { + return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, + g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_, + g7_.begin()); + } + virtual ParamIteratorInterface<ParamType>* End() const { + return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), + g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end()); + } + + private: + class Iterator : public ParamIteratorInterface<ParamType> { + public: + Iterator(const ParamGeneratorInterface<ParamType>* base, + const ParamGenerator<T1>& g1, + const typename ParamGenerator<T1>::iterator& current1, + const ParamGenerator<T2>& g2, + const typename ParamGenerator<T2>::iterator& current2, + const ParamGenerator<T3>& g3, + const typename ParamGenerator<T3>::iterator& current3, + const ParamGenerator<T4>& g4, + const typename ParamGenerator<T4>::iterator& current4, + const ParamGenerator<T5>& g5, + const typename ParamGenerator<T5>::iterator& current5, + const ParamGenerator<T6>& g6, + const typename ParamGenerator<T6>::iterator& current6, + const ParamGenerator<T7>& g7, + const typename ParamGenerator<T7>::iterator& current7) + : base_(base), + begin1_(g1.begin()), end1_(g1.end()), current1_(current1), + begin2_(g2.begin()), end2_(g2.end()), current2_(current2), + begin3_(g3.begin()), end3_(g3.end()), current3_(current3), + begin4_(g4.begin()), end4_(g4.end()), current4_(current4), + begin5_(g5.begin()), end5_(g5.end()), current5_(current5), + begin6_(g6.begin()), end6_(g6.end()), current6_(current6), + begin7_(g7.begin()), end7_(g7.end()), current7_(current7) { + ComputeCurrentValue(); + } + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const { + return base_; + } + // Advance should not be called on beyond-of-range iterators + // so no component iterators must be beyond end of range, either. + virtual void Advance() { + assert(!AtEnd()); + ++current7_; + if (current7_ == end7_) { + current7_ = begin7_; + ++current6_; + } + if (current6_ == end6_) { + current6_ = begin6_; + ++current5_; + } + if (current5_ == end5_) { + current5_ = begin5_; + ++current4_; + } + if (current4_ == end4_) { + current4_ = begin4_; + ++current3_; + } + if (current3_ == end3_) { + current3_ = begin3_; + ++current2_; + } + if (current2_ == end2_) { + current2_ = begin2_; + ++current1_; + } + ComputeCurrentValue(); + } + virtual ParamIteratorInterface<ParamType>* Clone() const { + return new Iterator(*this); + } + virtual const ParamType* Current() const { return ¤t_value_; } + virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const Iterator* typed_other = + CheckedDowncastToActualType<const Iterator>(&other); + // We must report iterators equal if they both point beyond their + // respective ranges. That can happen in a variety of fashions, + // so we have to consult AtEnd(). + return (AtEnd() && typed_other->AtEnd()) || + ( + current1_ == typed_other->current1_ && + current2_ == typed_other->current2_ && + current3_ == typed_other->current3_ && + current4_ == typed_other->current4_ && + current5_ == typed_other->current5_ && + current6_ == typed_other->current6_ && + current7_ == typed_other->current7_); + } + + private: + Iterator(const Iterator& other) + : base_(other.base_), + begin1_(other.begin1_), + end1_(other.end1_), + current1_(other.current1_), + begin2_(other.begin2_), + end2_(other.end2_), + current2_(other.current2_), + begin3_(other.begin3_), + end3_(other.end3_), + current3_(other.current3_), + begin4_(other.begin4_), + end4_(other.end4_), + current4_(other.current4_), + begin5_(other.begin5_), + end5_(other.end5_), + current5_(other.current5_), + begin6_(other.begin6_), + end6_(other.end6_), + current6_(other.current6_), + begin7_(other.begin7_), + end7_(other.end7_), + current7_(other.current7_) { + ComputeCurrentValue(); + } + + void ComputeCurrentValue() { + if (!AtEnd()) + current_value_ = ParamType(*current1_, *current2_, *current3_, + *current4_, *current5_, *current6_, *current7_); + } + bool AtEnd() const { + // We must report iterator past the end of the range when either of the + // component iterators has reached the end of its range. + return + current1_ == end1_ || + current2_ == end2_ || + current3_ == end3_ || + current4_ == end4_ || + current5_ == end5_ || + current6_ == end6_ || + current7_ == end7_; + } + + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + + const ParamGeneratorInterface<ParamType>* const base_; + // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. + // current[i]_ is the actual traversing iterator. + const typename ParamGenerator<T1>::iterator begin1_; + const typename ParamGenerator<T1>::iterator end1_; + typename ParamGenerator<T1>::iterator current1_; + const typename ParamGenerator<T2>::iterator begin2_; + const typename ParamGenerator<T2>::iterator end2_; + typename ParamGenerator<T2>::iterator current2_; + const typename ParamGenerator<T3>::iterator begin3_; + const typename ParamGenerator<T3>::iterator end3_; + typename ParamGenerator<T3>::iterator current3_; + const typename ParamGenerator<T4>::iterator begin4_; + const typename ParamGenerator<T4>::iterator end4_; + typename ParamGenerator<T4>::iterator current4_; + const typename ParamGenerator<T5>::iterator begin5_; + const typename ParamGenerator<T5>::iterator end5_; + typename ParamGenerator<T5>::iterator current5_; + const typename ParamGenerator<T6>::iterator begin6_; + const typename ParamGenerator<T6>::iterator end6_; + typename ParamGenerator<T6>::iterator current6_; + const typename ParamGenerator<T7>::iterator begin7_; + const typename ParamGenerator<T7>::iterator end7_; + typename ParamGenerator<T7>::iterator current7_; + ParamType current_value_; + }; // class CartesianProductGenerator7::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator7& other); + + const ParamGenerator<T1> g1_; + const ParamGenerator<T2> g2_; + const ParamGenerator<T3> g3_; + const ParamGenerator<T4> g4_; + const ParamGenerator<T5> g5_; + const ParamGenerator<T6> g6_; + const ParamGenerator<T7> g7_; +}; // class CartesianProductGenerator7 + + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8> +class CartesianProductGenerator8 + : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, + T7, T8> > { + public: + typedef ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8> ParamType; + + CartesianProductGenerator8(const ParamGenerator<T1>& g1, + const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3, + const ParamGenerator<T4>& g4, const ParamGenerator<T5>& g5, + const ParamGenerator<T6>& g6, const ParamGenerator<T7>& g7, + const ParamGenerator<T8>& g8) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), + g8_(g8) {} + virtual ~CartesianProductGenerator8() {} + + virtual ParamIteratorInterface<ParamType>* Begin() const { + return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, + g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_, + g7_.begin(), g8_, g8_.begin()); + } + virtual ParamIteratorInterface<ParamType>* End() const { + return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), + g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end(), g8_, + g8_.end()); + } + + private: + class Iterator : public ParamIteratorInterface<ParamType> { + public: + Iterator(const ParamGeneratorInterface<ParamType>* base, + const ParamGenerator<T1>& g1, + const typename ParamGenerator<T1>::iterator& current1, + const ParamGenerator<T2>& g2, + const typename ParamGenerator<T2>::iterator& current2, + const ParamGenerator<T3>& g3, + const typename ParamGenerator<T3>::iterator& current3, + const ParamGenerator<T4>& g4, + const typename ParamGenerator<T4>::iterator& current4, + const ParamGenerator<T5>& g5, + const typename ParamGenerator<T5>::iterator& current5, + const ParamGenerator<T6>& g6, + const typename ParamGenerator<T6>::iterator& current6, + const ParamGenerator<T7>& g7, + const typename ParamGenerator<T7>::iterator& current7, + const ParamGenerator<T8>& g8, + const typename ParamGenerator<T8>::iterator& current8) + : base_(base), + begin1_(g1.begin()), end1_(g1.end()), current1_(current1), + begin2_(g2.begin()), end2_(g2.end()), current2_(current2), + begin3_(g3.begin()), end3_(g3.end()), current3_(current3), + begin4_(g4.begin()), end4_(g4.end()), current4_(current4), + begin5_(g5.begin()), end5_(g5.end()), current5_(current5), + begin6_(g6.begin()), end6_(g6.end()), current6_(current6), + begin7_(g7.begin()), end7_(g7.end()), current7_(current7), + begin8_(g8.begin()), end8_(g8.end()), current8_(current8) { + ComputeCurrentValue(); + } + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const { + return base_; + } + // Advance should not be called on beyond-of-range iterators + // so no component iterators must be beyond end of range, either. + virtual void Advance() { + assert(!AtEnd()); + ++current8_; + if (current8_ == end8_) { + current8_ = begin8_; + ++current7_; + } + if (current7_ == end7_) { + current7_ = begin7_; + ++current6_; + } + if (current6_ == end6_) { + current6_ = begin6_; + ++current5_; + } + if (current5_ == end5_) { + current5_ = begin5_; + ++current4_; + } + if (current4_ == end4_) { + current4_ = begin4_; + ++current3_; + } + if (current3_ == end3_) { + current3_ = begin3_; + ++current2_; + } + if (current2_ == end2_) { + current2_ = begin2_; + ++current1_; + } + ComputeCurrentValue(); + } + virtual ParamIteratorInterface<ParamType>* Clone() const { + return new Iterator(*this); + } + virtual const ParamType* Current() const { return ¤t_value_; } + virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const Iterator* typed_other = + CheckedDowncastToActualType<const Iterator>(&other); + // We must report iterators equal if they both point beyond their + // respective ranges. That can happen in a variety of fashions, + // so we have to consult AtEnd(). + return (AtEnd() && typed_other->AtEnd()) || + ( + current1_ == typed_other->current1_ && + current2_ == typed_other->current2_ && + current3_ == typed_other->current3_ && + current4_ == typed_other->current4_ && + current5_ == typed_other->current5_ && + current6_ == typed_other->current6_ && + current7_ == typed_other->current7_ && + current8_ == typed_other->current8_); + } + + private: + Iterator(const Iterator& other) + : base_(other.base_), + begin1_(other.begin1_), + end1_(other.end1_), + current1_(other.current1_), + begin2_(other.begin2_), + end2_(other.end2_), + current2_(other.current2_), + begin3_(other.begin3_), + end3_(other.end3_), + current3_(other.current3_), + begin4_(other.begin4_), + end4_(other.end4_), + current4_(other.current4_), + begin5_(other.begin5_), + end5_(other.end5_), + current5_(other.current5_), + begin6_(other.begin6_), + end6_(other.end6_), + current6_(other.current6_), + begin7_(other.begin7_), + end7_(other.end7_), + current7_(other.current7_), + begin8_(other.begin8_), + end8_(other.end8_), + current8_(other.current8_) { + ComputeCurrentValue(); + } + + void ComputeCurrentValue() { + if (!AtEnd()) + current_value_ = ParamType(*current1_, *current2_, *current3_, + *current4_, *current5_, *current6_, *current7_, *current8_); + } + bool AtEnd() const { + // We must report iterator past the end of the range when either of the + // component iterators has reached the end of its range. + return + current1_ == end1_ || + current2_ == end2_ || + current3_ == end3_ || + current4_ == end4_ || + current5_ == end5_ || + current6_ == end6_ || + current7_ == end7_ || + current8_ == end8_; + } + + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + + const ParamGeneratorInterface<ParamType>* const base_; + // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. + // current[i]_ is the actual traversing iterator. + const typename ParamGenerator<T1>::iterator begin1_; + const typename ParamGenerator<T1>::iterator end1_; + typename ParamGenerator<T1>::iterator current1_; + const typename ParamGenerator<T2>::iterator begin2_; + const typename ParamGenerator<T2>::iterator end2_; + typename ParamGenerator<T2>::iterator current2_; + const typename ParamGenerator<T3>::iterator begin3_; + const typename ParamGenerator<T3>::iterator end3_; + typename ParamGenerator<T3>::iterator current3_; + const typename ParamGenerator<T4>::iterator begin4_; + const typename ParamGenerator<T4>::iterator end4_; + typename ParamGenerator<T4>::iterator current4_; + const typename ParamGenerator<T5>::iterator begin5_; + const typename ParamGenerator<T5>::iterator end5_; + typename ParamGenerator<T5>::iterator current5_; + const typename ParamGenerator<T6>::iterator begin6_; + const typename ParamGenerator<T6>::iterator end6_; + typename ParamGenerator<T6>::iterator current6_; + const typename ParamGenerator<T7>::iterator begin7_; + const typename ParamGenerator<T7>::iterator end7_; + typename ParamGenerator<T7>::iterator current7_; + const typename ParamGenerator<T8>::iterator begin8_; + const typename ParamGenerator<T8>::iterator end8_; + typename ParamGenerator<T8>::iterator current8_; + ParamType current_value_; + }; // class CartesianProductGenerator8::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator8& other); + + const ParamGenerator<T1> g1_; + const ParamGenerator<T2> g2_; + const ParamGenerator<T3> g3_; + const ParamGenerator<T4> g4_; + const ParamGenerator<T5> g5_; + const ParamGenerator<T6> g6_; + const ParamGenerator<T7> g7_; + const ParamGenerator<T8> g8_; +}; // class CartesianProductGenerator8 + + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9> +class CartesianProductGenerator9 + : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, + T7, T8, T9> > { + public: + typedef ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9> ParamType; + + CartesianProductGenerator9(const ParamGenerator<T1>& g1, + const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3, + const ParamGenerator<T4>& g4, const ParamGenerator<T5>& g5, + const ParamGenerator<T6>& g6, const ParamGenerator<T7>& g7, + const ParamGenerator<T8>& g8, const ParamGenerator<T9>& g9) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8), + g9_(g9) {} + virtual ~CartesianProductGenerator9() {} + + virtual ParamIteratorInterface<ParamType>* Begin() const { + return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, + g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_, + g7_.begin(), g8_, g8_.begin(), g9_, g9_.begin()); + } + virtual ParamIteratorInterface<ParamType>* End() const { + return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), + g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end(), g8_, + g8_.end(), g9_, g9_.end()); + } + + private: + class Iterator : public ParamIteratorInterface<ParamType> { + public: + Iterator(const ParamGeneratorInterface<ParamType>* base, + const ParamGenerator<T1>& g1, + const typename ParamGenerator<T1>::iterator& current1, + const ParamGenerator<T2>& g2, + const typename ParamGenerator<T2>::iterator& current2, + const ParamGenerator<T3>& g3, + const typename ParamGenerator<T3>::iterator& current3, + const ParamGenerator<T4>& g4, + const typename ParamGenerator<T4>::iterator& current4, + const ParamGenerator<T5>& g5, + const typename ParamGenerator<T5>::iterator& current5, + const ParamGenerator<T6>& g6, + const typename ParamGenerator<T6>::iterator& current6, + const ParamGenerator<T7>& g7, + const typename ParamGenerator<T7>::iterator& current7, + const ParamGenerator<T8>& g8, + const typename ParamGenerator<T8>::iterator& current8, + const ParamGenerator<T9>& g9, + const typename ParamGenerator<T9>::iterator& current9) + : base_(base), + begin1_(g1.begin()), end1_(g1.end()), current1_(current1), + begin2_(g2.begin()), end2_(g2.end()), current2_(current2), + begin3_(g3.begin()), end3_(g3.end()), current3_(current3), + begin4_(g4.begin()), end4_(g4.end()), current4_(current4), + begin5_(g5.begin()), end5_(g5.end()), current5_(current5), + begin6_(g6.begin()), end6_(g6.end()), current6_(current6), + begin7_(g7.begin()), end7_(g7.end()), current7_(current7), + begin8_(g8.begin()), end8_(g8.end()), current8_(current8), + begin9_(g9.begin()), end9_(g9.end()), current9_(current9) { + ComputeCurrentValue(); + } + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const { + return base_; + } + // Advance should not be called on beyond-of-range iterators + // so no component iterators must be beyond end of range, either. + virtual void Advance() { + assert(!AtEnd()); + ++current9_; + if (current9_ == end9_) { + current9_ = begin9_; + ++current8_; + } + if (current8_ == end8_) { + current8_ = begin8_; + ++current7_; + } + if (current7_ == end7_) { + current7_ = begin7_; + ++current6_; + } + if (current6_ == end6_) { + current6_ = begin6_; + ++current5_; + } + if (current5_ == end5_) { + current5_ = begin5_; + ++current4_; + } + if (current4_ == end4_) { + current4_ = begin4_; + ++current3_; + } + if (current3_ == end3_) { + current3_ = begin3_; + ++current2_; + } + if (current2_ == end2_) { + current2_ = begin2_; + ++current1_; + } + ComputeCurrentValue(); + } + virtual ParamIteratorInterface<ParamType>* Clone() const { + return new Iterator(*this); + } + virtual const ParamType* Current() const { return ¤t_value_; } + virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const Iterator* typed_other = + CheckedDowncastToActualType<const Iterator>(&other); + // We must report iterators equal if they both point beyond their + // respective ranges. That can happen in a variety of fashions, + // so we have to consult AtEnd(). + return (AtEnd() && typed_other->AtEnd()) || + ( + current1_ == typed_other->current1_ && + current2_ == typed_other->current2_ && + current3_ == typed_other->current3_ && + current4_ == typed_other->current4_ && + current5_ == typed_other->current5_ && + current6_ == typed_other->current6_ && + current7_ == typed_other->current7_ && + current8_ == typed_other->current8_ && + current9_ == typed_other->current9_); + } + + private: + Iterator(const Iterator& other) + : base_(other.base_), + begin1_(other.begin1_), + end1_(other.end1_), + current1_(other.current1_), + begin2_(other.begin2_), + end2_(other.end2_), + current2_(other.current2_), + begin3_(other.begin3_), + end3_(other.end3_), + current3_(other.current3_), + begin4_(other.begin4_), + end4_(other.end4_), + current4_(other.current4_), + begin5_(other.begin5_), + end5_(other.end5_), + current5_(other.current5_), + begin6_(other.begin6_), + end6_(other.end6_), + current6_(other.current6_), + begin7_(other.begin7_), + end7_(other.end7_), + current7_(other.current7_), + begin8_(other.begin8_), + end8_(other.end8_), + current8_(other.current8_), + begin9_(other.begin9_), + end9_(other.end9_), + current9_(other.current9_) { + ComputeCurrentValue(); + } + + void ComputeCurrentValue() { + if (!AtEnd()) + current_value_ = ParamType(*current1_, *current2_, *current3_, + *current4_, *current5_, *current6_, *current7_, *current8_, + *current9_); + } + bool AtEnd() const { + // We must report iterator past the end of the range when either of the + // component iterators has reached the end of its range. + return + current1_ == end1_ || + current2_ == end2_ || + current3_ == end3_ || + current4_ == end4_ || + current5_ == end5_ || + current6_ == end6_ || + current7_ == end7_ || + current8_ == end8_ || + current9_ == end9_; + } + + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + + const ParamGeneratorInterface<ParamType>* const base_; + // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. + // current[i]_ is the actual traversing iterator. + const typename ParamGenerator<T1>::iterator begin1_; + const typename ParamGenerator<T1>::iterator end1_; + typename ParamGenerator<T1>::iterator current1_; + const typename ParamGenerator<T2>::iterator begin2_; + const typename ParamGenerator<T2>::iterator end2_; + typename ParamGenerator<T2>::iterator current2_; + const typename ParamGenerator<T3>::iterator begin3_; + const typename ParamGenerator<T3>::iterator end3_; + typename ParamGenerator<T3>::iterator current3_; + const typename ParamGenerator<T4>::iterator begin4_; + const typename ParamGenerator<T4>::iterator end4_; + typename ParamGenerator<T4>::iterator current4_; + const typename ParamGenerator<T5>::iterator begin5_; + const typename ParamGenerator<T5>::iterator end5_; + typename ParamGenerator<T5>::iterator current5_; + const typename ParamGenerator<T6>::iterator begin6_; + const typename ParamGenerator<T6>::iterator end6_; + typename ParamGenerator<T6>::iterator current6_; + const typename ParamGenerator<T7>::iterator begin7_; + const typename ParamGenerator<T7>::iterator end7_; + typename ParamGenerator<T7>::iterator current7_; + const typename ParamGenerator<T8>::iterator begin8_; + const typename ParamGenerator<T8>::iterator end8_; + typename ParamGenerator<T8>::iterator current8_; + const typename ParamGenerator<T9>::iterator begin9_; + const typename ParamGenerator<T9>::iterator end9_; + typename ParamGenerator<T9>::iterator current9_; + ParamType current_value_; + }; // class CartesianProductGenerator9::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator9& other); + + const ParamGenerator<T1> g1_; + const ParamGenerator<T2> g2_; + const ParamGenerator<T3> g3_; + const ParamGenerator<T4> g4_; + const ParamGenerator<T5> g5_; + const ParamGenerator<T6> g6_; + const ParamGenerator<T7> g7_; + const ParamGenerator<T8> g8_; + const ParamGenerator<T9> g9_; +}; // class CartesianProductGenerator9 + + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10> +class CartesianProductGenerator10 + : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, + T7, T8, T9, T10> > { + public: + typedef ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> ParamType; + + CartesianProductGenerator10(const ParamGenerator<T1>& g1, + const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3, + const ParamGenerator<T4>& g4, const ParamGenerator<T5>& g5, + const ParamGenerator<T6>& g6, const ParamGenerator<T7>& g7, + const ParamGenerator<T8>& g8, const ParamGenerator<T9>& g9, + const ParamGenerator<T10>& g10) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8), + g9_(g9), g10_(g10) {} + virtual ~CartesianProductGenerator10() {} + + virtual ParamIteratorInterface<ParamType>* Begin() const { + return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, + g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_, + g7_.begin(), g8_, g8_.begin(), g9_, g9_.begin(), g10_, g10_.begin()); + } + virtual ParamIteratorInterface<ParamType>* End() const { + return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), + g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end(), g8_, + g8_.end(), g9_, g9_.end(), g10_, g10_.end()); + } + + private: + class Iterator : public ParamIteratorInterface<ParamType> { + public: + Iterator(const ParamGeneratorInterface<ParamType>* base, + const ParamGenerator<T1>& g1, + const typename ParamGenerator<T1>::iterator& current1, + const ParamGenerator<T2>& g2, + const typename ParamGenerator<T2>::iterator& current2, + const ParamGenerator<T3>& g3, + const typename ParamGenerator<T3>::iterator& current3, + const ParamGenerator<T4>& g4, + const typename ParamGenerator<T4>::iterator& current4, + const ParamGenerator<T5>& g5, + const typename ParamGenerator<T5>::iterator& current5, + const ParamGenerator<T6>& g6, + const typename ParamGenerator<T6>::iterator& current6, + const ParamGenerator<T7>& g7, + const typename ParamGenerator<T7>::iterator& current7, + const ParamGenerator<T8>& g8, + const typename ParamGenerator<T8>::iterator& current8, + const ParamGenerator<T9>& g9, + const typename ParamGenerator<T9>::iterator& current9, + const ParamGenerator<T10>& g10, + const typename ParamGenerator<T10>::iterator& current10) + : base_(base), + begin1_(g1.begin()), end1_(g1.end()), current1_(current1), + begin2_(g2.begin()), end2_(g2.end()), current2_(current2), + begin3_(g3.begin()), end3_(g3.end()), current3_(current3), + begin4_(g4.begin()), end4_(g4.end()), current4_(current4), + begin5_(g5.begin()), end5_(g5.end()), current5_(current5), + begin6_(g6.begin()), end6_(g6.end()), current6_(current6), + begin7_(g7.begin()), end7_(g7.end()), current7_(current7), + begin8_(g8.begin()), end8_(g8.end()), current8_(current8), + begin9_(g9.begin()), end9_(g9.end()), current9_(current9), + begin10_(g10.begin()), end10_(g10.end()), current10_(current10) { + ComputeCurrentValue(); + } + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const { + return base_; + } + // Advance should not be called on beyond-of-range iterators + // so no component iterators must be beyond end of range, either. + virtual void Advance() { + assert(!AtEnd()); + ++current10_; + if (current10_ == end10_) { + current10_ = begin10_; + ++current9_; + } + if (current9_ == end9_) { + current9_ = begin9_; + ++current8_; + } + if (current8_ == end8_) { + current8_ = begin8_; + ++current7_; + } + if (current7_ == end7_) { + current7_ = begin7_; + ++current6_; + } + if (current6_ == end6_) { + current6_ = begin6_; + ++current5_; + } + if (current5_ == end5_) { + current5_ = begin5_; + ++current4_; + } + if (current4_ == end4_) { + current4_ = begin4_; + ++current3_; + } + if (current3_ == end3_) { + current3_ = begin3_; + ++current2_; + } + if (current2_ == end2_) { + current2_ = begin2_; + ++current1_; + } + ComputeCurrentValue(); + } + virtual ParamIteratorInterface<ParamType>* Clone() const { + return new Iterator(*this); + } + virtual const ParamType* Current() const { return ¤t_value_; } + virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const Iterator* typed_other = + CheckedDowncastToActualType<const Iterator>(&other); + // We must report iterators equal if they both point beyond their + // respective ranges. That can happen in a variety of fashions, + // so we have to consult AtEnd(). + return (AtEnd() && typed_other->AtEnd()) || + ( + current1_ == typed_other->current1_ && + current2_ == typed_other->current2_ && + current3_ == typed_other->current3_ && + current4_ == typed_other->current4_ && + current5_ == typed_other->current5_ && + current6_ == typed_other->current6_ && + current7_ == typed_other->current7_ && + current8_ == typed_other->current8_ && + current9_ == typed_other->current9_ && + current10_ == typed_other->current10_); + } + + private: + Iterator(const Iterator& other) + : base_(other.base_), + begin1_(other.begin1_), + end1_(other.end1_), + current1_(other.current1_), + begin2_(other.begin2_), + end2_(other.end2_), + current2_(other.current2_), + begin3_(other.begin3_), + end3_(other.end3_), + current3_(other.current3_), + begin4_(other.begin4_), + end4_(other.end4_), + current4_(other.current4_), + begin5_(other.begin5_), + end5_(other.end5_), + current5_(other.current5_), + begin6_(other.begin6_), + end6_(other.end6_), + current6_(other.current6_), + begin7_(other.begin7_), + end7_(other.end7_), + current7_(other.current7_), + begin8_(other.begin8_), + end8_(other.end8_), + current8_(other.current8_), + begin9_(other.begin9_), + end9_(other.end9_), + current9_(other.current9_), + begin10_(other.begin10_), + end10_(other.end10_), + current10_(other.current10_) { + ComputeCurrentValue(); + } + + void ComputeCurrentValue() { + if (!AtEnd()) + current_value_ = ParamType(*current1_, *current2_, *current3_, + *current4_, *current5_, *current6_, *current7_, *current8_, + *current9_, *current10_); + } + bool AtEnd() const { + // We must report iterator past the end of the range when either of the + // component iterators has reached the end of its range. + return + current1_ == end1_ || + current2_ == end2_ || + current3_ == end3_ || + current4_ == end4_ || + current5_ == end5_ || + current6_ == end6_ || + current7_ == end7_ || + current8_ == end8_ || + current9_ == end9_ || + current10_ == end10_; + } + + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + + const ParamGeneratorInterface<ParamType>* const base_; + // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. + // current[i]_ is the actual traversing iterator. + const typename ParamGenerator<T1>::iterator begin1_; + const typename ParamGenerator<T1>::iterator end1_; + typename ParamGenerator<T1>::iterator current1_; + const typename ParamGenerator<T2>::iterator begin2_; + const typename ParamGenerator<T2>::iterator end2_; + typename ParamGenerator<T2>::iterator current2_; + const typename ParamGenerator<T3>::iterator begin3_; + const typename ParamGenerator<T3>::iterator end3_; + typename ParamGenerator<T3>::iterator current3_; + const typename ParamGenerator<T4>::iterator begin4_; + const typename ParamGenerator<T4>::iterator end4_; + typename ParamGenerator<T4>::iterator current4_; + const typename ParamGenerator<T5>::iterator begin5_; + const typename ParamGenerator<T5>::iterator end5_; + typename ParamGenerator<T5>::iterator current5_; + const typename ParamGenerator<T6>::iterator begin6_; + const typename ParamGenerator<T6>::iterator end6_; + typename ParamGenerator<T6>::iterator current6_; + const typename ParamGenerator<T7>::iterator begin7_; + const typename ParamGenerator<T7>::iterator end7_; + typename ParamGenerator<T7>::iterator current7_; + const typename ParamGenerator<T8>::iterator begin8_; + const typename ParamGenerator<T8>::iterator end8_; + typename ParamGenerator<T8>::iterator current8_; + const typename ParamGenerator<T9>::iterator begin9_; + const typename ParamGenerator<T9>::iterator end9_; + typename ParamGenerator<T9>::iterator current9_; + const typename ParamGenerator<T10>::iterator begin10_; + const typename ParamGenerator<T10>::iterator end10_; + typename ParamGenerator<T10>::iterator current10_; + ParamType current_value_; + }; // class CartesianProductGenerator10::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator10& other); + + const ParamGenerator<T1> g1_; + const ParamGenerator<T2> g2_; + const ParamGenerator<T3> g3_; + const ParamGenerator<T4> g4_; + const ParamGenerator<T5> g5_; + const ParamGenerator<T6> g6_; + const ParamGenerator<T7> g7_; + const ParamGenerator<T8> g8_; + const ParamGenerator<T9> g9_; + const ParamGenerator<T10> g10_; +}; // class CartesianProductGenerator10 + + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// Helper classes providing Combine() with polymorphic features. They allow +// casting CartesianProductGeneratorN<T> to ParamGenerator<U> if T is +// convertible to U. +// +template <class Generator1, class Generator2> +class CartesianProductHolder2 { + public: +CartesianProductHolder2(const Generator1& g1, const Generator2& g2) + : g1_(g1), g2_(g2) {} + template <typename T1, typename T2> + operator ParamGenerator< ::std::tr1::tuple<T1, T2> >() const { + return ParamGenerator< ::std::tr1::tuple<T1, T2> >( + new CartesianProductGenerator2<T1, T2>( + static_cast<ParamGenerator<T1> >(g1_), + static_cast<ParamGenerator<T2> >(g2_))); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder2& other); + + const Generator1 g1_; + const Generator2 g2_; +}; // class CartesianProductHolder2 + +template <class Generator1, class Generator2, class Generator3> +class CartesianProductHolder3 { + public: +CartesianProductHolder3(const Generator1& g1, const Generator2& g2, + const Generator3& g3) + : g1_(g1), g2_(g2), g3_(g3) {} + template <typename T1, typename T2, typename T3> + operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3> >() const { + return ParamGenerator< ::std::tr1::tuple<T1, T2, T3> >( + new CartesianProductGenerator3<T1, T2, T3>( + static_cast<ParamGenerator<T1> >(g1_), + static_cast<ParamGenerator<T2> >(g2_), + static_cast<ParamGenerator<T3> >(g3_))); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder3& other); + + const Generator1 g1_; + const Generator2 g2_; + const Generator3 g3_; +}; // class CartesianProductHolder3 + +template <class Generator1, class Generator2, class Generator3, + class Generator4> +class CartesianProductHolder4 { + public: +CartesianProductHolder4(const Generator1& g1, const Generator2& g2, + const Generator3& g3, const Generator4& g4) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4) {} + template <typename T1, typename T2, typename T3, typename T4> + operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4> >() const { + return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4> >( + new CartesianProductGenerator4<T1, T2, T3, T4>( + static_cast<ParamGenerator<T1> >(g1_), + static_cast<ParamGenerator<T2> >(g2_), + static_cast<ParamGenerator<T3> >(g3_), + static_cast<ParamGenerator<T4> >(g4_))); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder4& other); + + const Generator1 g1_; + const Generator2 g2_; + const Generator3 g3_; + const Generator4 g4_; +}; // class CartesianProductHolder4 + +template <class Generator1, class Generator2, class Generator3, + class Generator4, class Generator5> +class CartesianProductHolder5 { + public: +CartesianProductHolder5(const Generator1& g1, const Generator2& g2, + const Generator3& g3, const Generator4& g4, const Generator5& g5) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5) {} + template <typename T1, typename T2, typename T3, typename T4, typename T5> + operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5> >() const { + return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5> >( + new CartesianProductGenerator5<T1, T2, T3, T4, T5>( + static_cast<ParamGenerator<T1> >(g1_), + static_cast<ParamGenerator<T2> >(g2_), + static_cast<ParamGenerator<T3> >(g3_), + static_cast<ParamGenerator<T4> >(g4_), + static_cast<ParamGenerator<T5> >(g5_))); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder5& other); + + const Generator1 g1_; + const Generator2 g2_; + const Generator3 g3_; + const Generator4 g4_; + const Generator5 g5_; +}; // class CartesianProductHolder5 + +template <class Generator1, class Generator2, class Generator3, + class Generator4, class Generator5, class Generator6> +class CartesianProductHolder6 { + public: +CartesianProductHolder6(const Generator1& g1, const Generator2& g2, + const Generator3& g3, const Generator4& g4, const Generator5& g5, + const Generator6& g6) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6) {} + template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6> + operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6> >() const { + return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6> >( + new CartesianProductGenerator6<T1, T2, T3, T4, T5, T6>( + static_cast<ParamGenerator<T1> >(g1_), + static_cast<ParamGenerator<T2> >(g2_), + static_cast<ParamGenerator<T3> >(g3_), + static_cast<ParamGenerator<T4> >(g4_), + static_cast<ParamGenerator<T5> >(g5_), + static_cast<ParamGenerator<T6> >(g6_))); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder6& other); + + const Generator1 g1_; + const Generator2 g2_; + const Generator3 g3_; + const Generator4 g4_; + const Generator5 g5_; + const Generator6 g6_; +}; // class CartesianProductHolder6 + +template <class Generator1, class Generator2, class Generator3, + class Generator4, class Generator5, class Generator6, class Generator7> +class CartesianProductHolder7 { + public: +CartesianProductHolder7(const Generator1& g1, const Generator2& g2, + const Generator3& g3, const Generator4& g4, const Generator5& g5, + const Generator6& g6, const Generator7& g7) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7) {} + template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7> + operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, + T7> >() const { + return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7> >( + new CartesianProductGenerator7<T1, T2, T3, T4, T5, T6, T7>( + static_cast<ParamGenerator<T1> >(g1_), + static_cast<ParamGenerator<T2> >(g2_), + static_cast<ParamGenerator<T3> >(g3_), + static_cast<ParamGenerator<T4> >(g4_), + static_cast<ParamGenerator<T5> >(g5_), + static_cast<ParamGenerator<T6> >(g6_), + static_cast<ParamGenerator<T7> >(g7_))); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder7& other); + + const Generator1 g1_; + const Generator2 g2_; + const Generator3 g3_; + const Generator4 g4_; + const Generator5 g5_; + const Generator6 g6_; + const Generator7 g7_; +}; // class CartesianProductHolder7 + +template <class Generator1, class Generator2, class Generator3, + class Generator4, class Generator5, class Generator6, class Generator7, + class Generator8> +class CartesianProductHolder8 { + public: +CartesianProductHolder8(const Generator1& g1, const Generator2& g2, + const Generator3& g3, const Generator4& g4, const Generator5& g5, + const Generator6& g6, const Generator7& g7, const Generator8& g8) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), + g8_(g8) {} + template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8> + operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, + T8> >() const { + return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8> >( + new CartesianProductGenerator8<T1, T2, T3, T4, T5, T6, T7, T8>( + static_cast<ParamGenerator<T1> >(g1_), + static_cast<ParamGenerator<T2> >(g2_), + static_cast<ParamGenerator<T3> >(g3_), + static_cast<ParamGenerator<T4> >(g4_), + static_cast<ParamGenerator<T5> >(g5_), + static_cast<ParamGenerator<T6> >(g6_), + static_cast<ParamGenerator<T7> >(g7_), + static_cast<ParamGenerator<T8> >(g8_))); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder8& other); + + const Generator1 g1_; + const Generator2 g2_; + const Generator3 g3_; + const Generator4 g4_; + const Generator5 g5_; + const Generator6 g6_; + const Generator7 g7_; + const Generator8 g8_; +}; // class CartesianProductHolder8 + +template <class Generator1, class Generator2, class Generator3, + class Generator4, class Generator5, class Generator6, class Generator7, + class Generator8, class Generator9> +class CartesianProductHolder9 { + public: +CartesianProductHolder9(const Generator1& g1, const Generator2& g2, + const Generator3& g3, const Generator4& g4, const Generator5& g5, + const Generator6& g6, const Generator7& g7, const Generator8& g8, + const Generator9& g9) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8), + g9_(g9) {} + template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9> + operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8, + T9> >() const { + return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8, + T9> >( + new CartesianProductGenerator9<T1, T2, T3, T4, T5, T6, T7, T8, T9>( + static_cast<ParamGenerator<T1> >(g1_), + static_cast<ParamGenerator<T2> >(g2_), + static_cast<ParamGenerator<T3> >(g3_), + static_cast<ParamGenerator<T4> >(g4_), + static_cast<ParamGenerator<T5> >(g5_), + static_cast<ParamGenerator<T6> >(g6_), + static_cast<ParamGenerator<T7> >(g7_), + static_cast<ParamGenerator<T8> >(g8_), + static_cast<ParamGenerator<T9> >(g9_))); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder9& other); + + const Generator1 g1_; + const Generator2 g2_; + const Generator3 g3_; + const Generator4 g4_; + const Generator5 g5_; + const Generator6 g6_; + const Generator7 g7_; + const Generator8 g8_; + const Generator9 g9_; +}; // class CartesianProductHolder9 + +template <class Generator1, class Generator2, class Generator3, + class Generator4, class Generator5, class Generator6, class Generator7, + class Generator8, class Generator9, class Generator10> +class CartesianProductHolder10 { + public: +CartesianProductHolder10(const Generator1& g1, const Generator2& g2, + const Generator3& g3, const Generator4& g4, const Generator5& g5, + const Generator6& g6, const Generator7& g7, const Generator8& g8, + const Generator9& g9, const Generator10& g10) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8), + g9_(g9), g10_(g10) {} + template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10> + operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8, + T9, T10> >() const { + return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8, + T9, T10> >( + new CartesianProductGenerator10<T1, T2, T3, T4, T5, T6, T7, T8, T9, + T10>( + static_cast<ParamGenerator<T1> >(g1_), + static_cast<ParamGenerator<T2> >(g2_), + static_cast<ParamGenerator<T3> >(g3_), + static_cast<ParamGenerator<T4> >(g4_), + static_cast<ParamGenerator<T5> >(g5_), + static_cast<ParamGenerator<T6> >(g6_), + static_cast<ParamGenerator<T7> >(g7_), + static_cast<ParamGenerator<T8> >(g8_), + static_cast<ParamGenerator<T9> >(g9_), + static_cast<ParamGenerator<T10> >(g10_))); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder10& other); + + const Generator1 g1_; + const Generator2 g2_; + const Generator3 g3_; + const Generator4 g4_; + const Generator5 g5_; + const Generator6 g6_; + const Generator7 g7_; + const Generator8 g8_; + const Generator9 g9_; + const Generator10 g10_; +}; // class CartesianProductHolder10 + +#endif // GTEST_HAS_COMBINE + +} // namespace internal +} // namespace testing + +#endif // GTEST_HAS_PARAM_TEST + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_ + +#if GTEST_HAS_PARAM_TEST + +namespace testing { + +// Functions producing parameter generators. +// +// Google Test uses these generators to produce parameters for value- +// parameterized tests. When a parameterized test case is instantiated +// with a particular generator, Google Test creates and runs tests +// for each element in the sequence produced by the generator. +// +// In the following sample, tests from test case FooTest are instantiated +// each three times with parameter values 3, 5, and 8: +// +// class FooTest : public TestWithParam<int> { ... }; +// +// TEST_P(FooTest, TestThis) { +// } +// TEST_P(FooTest, TestThat) { +// } +// INSTANTIATE_TEST_CASE_P(TestSequence, FooTest, Values(3, 5, 8)); +// + +// Range() returns generators providing sequences of values in a range. +// +// Synopsis: +// Range(start, end) +// - returns a generator producing a sequence of values {start, start+1, +// start+2, ..., }. +// Range(start, end, step) +// - returns a generator producing a sequence of values {start, start+step, +// start+step+step, ..., }. +// Notes: +// * The generated sequences never include end. For example, Range(1, 5) +// returns a generator producing a sequence {1, 2, 3, 4}. Range(1, 9, 2) +// returns a generator producing {1, 3, 5, 7}. +// * start and end must have the same type. That type may be any integral or +// floating-point type or a user defined type satisfying these conditions: +// * It must be assignable (have operator=() defined). +// * It must have operator+() (operator+(int-compatible type) for +// two-operand version). +// * It must have operator<() defined. +// Elements in the resulting sequences will also have that type. +// * Condition start < end must be satisfied in order for resulting sequences +// to contain any elements. +// +template <typename T, typename IncrementT> +internal::ParamGenerator<T> Range(T start, T end, IncrementT step) { + return internal::ParamGenerator<T>( + new internal::RangeGenerator<T, IncrementT>(start, end, step)); +} + +template <typename T> +internal::ParamGenerator<T> Range(T start, T end) { + return Range(start, end, 1); +} + +// ValuesIn() function allows generation of tests with parameters coming from +// a container. +// +// Synopsis: +// ValuesIn(const T (&array)[N]) +// - returns a generator producing sequences with elements from +// a C-style array. +// ValuesIn(const Container& container) +// - returns a generator producing sequences with elements from +// an STL-style container. +// ValuesIn(Iterator begin, Iterator end) +// - returns a generator producing sequences with elements from +// a range [begin, end) defined by a pair of STL-style iterators. These +// iterators can also be plain C pointers. +// +// Please note that ValuesIn copies the values from the containers +// passed in and keeps them to generate tests in RUN_ALL_TESTS(). +// +// Examples: +// +// This instantiates tests from test case StringTest +// each with C-string values of "foo", "bar", and "baz": +// +// const char* strings[] = {"foo", "bar", "baz"}; +// INSTANTIATE_TEST_CASE_P(StringSequence, SrtingTest, ValuesIn(strings)); +// +// This instantiates tests from test case StlStringTest +// each with STL strings with values "a" and "b": +// +// ::std::vector< ::std::string> GetParameterStrings() { +// ::std::vector< ::std::string> v; +// v.push_back("a"); +// v.push_back("b"); +// return v; +// } +// +// INSTANTIATE_TEST_CASE_P(CharSequence, +// StlStringTest, +// ValuesIn(GetParameterStrings())); +// +// +// This will also instantiate tests from CharTest +// each with parameter values 'a' and 'b': +// +// ::std::list<char> GetParameterChars() { +// ::std::list<char> list; +// list.push_back('a'); +// list.push_back('b'); +// return list; +// } +// ::std::list<char> l = GetParameterChars(); +// INSTANTIATE_TEST_CASE_P(CharSequence2, +// CharTest, +// ValuesIn(l.begin(), l.end())); +// +template <typename ForwardIterator> +internal::ParamGenerator< + typename ::std::iterator_traits<ForwardIterator>::value_type> ValuesIn( + ForwardIterator begin, + ForwardIterator end) { + typedef typename ::std::iterator_traits<ForwardIterator>::value_type + ParamType; + return internal::ParamGenerator<ParamType>( + new internal::ValuesInIteratorRangeGenerator<ParamType>(begin, end)); +} + +template <typename T, size_t N> +internal::ParamGenerator<T> ValuesIn(const T (&array)[N]) { + return ValuesIn(array, array + N); +} + +template <class Container> +internal::ParamGenerator<typename Container::value_type> ValuesIn( + const Container& container) { + return ValuesIn(container.begin(), container.end()); +} + +// Values() allows generating tests from explicitly specified list of +// parameters. +// +// Synopsis: +// Values(T v1, T v2, ..., T vN) +// - returns a generator producing sequences with elements v1, v2, ..., vN. +// +// For example, this instantiates tests from test case BarTest each +// with values "one", "two", and "three": +// +// INSTANTIATE_TEST_CASE_P(NumSequence, BarTest, Values("one", "two", "three")); +// +// This instantiates tests from test case BazTest each with values 1, 2, 3.5. +// The exact type of values will depend on the type of parameter in BazTest. +// +// INSTANTIATE_TEST_CASE_P(FloatingNumbers, BazTest, Values(1, 2, 3.5)); +// +// Currently, Values() supports from 1 to 50 parameters. +// +template <typename T1> +internal::ValueArray1<T1> Values(T1 v1) { + return internal::ValueArray1<T1>(v1); +} + +template <typename T1, typename T2> +internal::ValueArray2<T1, T2> Values(T1 v1, T2 v2) { + return internal::ValueArray2<T1, T2>(v1, v2); +} + +template <typename T1, typename T2, typename T3> +internal::ValueArray3<T1, T2, T3> Values(T1 v1, T2 v2, T3 v3) { + return internal::ValueArray3<T1, T2, T3>(v1, v2, v3); +} + +template <typename T1, typename T2, typename T3, typename T4> +internal::ValueArray4<T1, T2, T3, T4> Values(T1 v1, T2 v2, T3 v3, T4 v4) { + return internal::ValueArray4<T1, T2, T3, T4>(v1, v2, v3, v4); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5> +internal::ValueArray5<T1, T2, T3, T4, T5> Values(T1 v1, T2 v2, T3 v3, T4 v4, + T5 v5) { + return internal::ValueArray5<T1, T2, T3, T4, T5>(v1, v2, v3, v4, v5); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6> +internal::ValueArray6<T1, T2, T3, T4, T5, T6> Values(T1 v1, T2 v2, T3 v3, + T4 v4, T5 v5, T6 v6) { + return internal::ValueArray6<T1, T2, T3, T4, T5, T6>(v1, v2, v3, v4, v5, v6); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7> +internal::ValueArray7<T1, T2, T3, T4, T5, T6, T7> Values(T1 v1, T2 v2, T3 v3, + T4 v4, T5 v5, T6 v6, T7 v7) { + return internal::ValueArray7<T1, T2, T3, T4, T5, T6, T7>(v1, v2, v3, v4, v5, + v6, v7); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8> +internal::ValueArray8<T1, T2, T3, T4, T5, T6, T7, T8> Values(T1 v1, T2 v2, + T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8) { + return internal::ValueArray8<T1, T2, T3, T4, T5, T6, T7, T8>(v1, v2, v3, v4, + v5, v6, v7, v8); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9> +internal::ValueArray9<T1, T2, T3, T4, T5, T6, T7, T8, T9> Values(T1 v1, T2 v2, + T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9) { + return internal::ValueArray9<T1, T2, T3, T4, T5, T6, T7, T8, T9>(v1, v2, v3, + v4, v5, v6, v7, v8, v9); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10> +internal::ValueArray10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> Values(T1 v1, + T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10) { + return internal::ValueArray10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(v1, + v2, v3, v4, v5, v6, v7, v8, v9, v10); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11> +internal::ValueArray11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, + T11> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11) { + return internal::ValueArray11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, + T11>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12> +internal::ValueArray12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, + T12> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12) { + return internal::ValueArray12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, + T12>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13> +internal::ValueArray13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, + T13> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13) { + return internal::ValueArray13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, + T12, T13>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14> +internal::ValueArray14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14) { + return internal::ValueArray14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, + T12, T13, T14>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, + v14); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15> +internal::ValueArray15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, + T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15) { + return internal::ValueArray15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, + T12, T13, T14, T15>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, + v13, v14, v15); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16> +internal::ValueArray16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, + T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, + T16 v16) { + return internal::ValueArray16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, + T12, T13, T14, T15, T16>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, + v12, v13, v14, v15, v16); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17> +internal::ValueArray17<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, + T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, + T16 v16, T17 v17) { + return internal::ValueArray17<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, + T12, T13, T14, T15, T16, T17>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, + v11, v12, v13, v14, v15, v16, v17); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18> +internal::ValueArray18<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, + T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, + T16 v16, T17 v17, T18 v18) { + return internal::ValueArray18<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, + T12, T13, T14, T15, T16, T17, T18>(v1, v2, v3, v4, v5, v6, v7, v8, v9, + v10, v11, v12, v13, v14, v15, v16, v17, v18); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19> +internal::ValueArray19<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, + T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, + T15 v15, T16 v16, T17 v17, T18 v18, T19 v19) { + return internal::ValueArray19<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, + T12, T13, T14, T15, T16, T17, T18, T19>(v1, v2, v3, v4, v5, v6, v7, v8, + v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20> +internal::ValueArray20<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20> Values(T1 v1, T2 v2, T3 v3, T4 v4, + T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, + T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20) { + return internal::ValueArray20<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, + T12, T13, T14, T15, T16, T17, T18, T19, T20>(v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21> +internal::ValueArray21<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21> Values(T1 v1, T2 v2, T3 v3, T4 v4, + T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, + T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21) { + return internal::ValueArray21<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, + T12, T13, T14, T15, T16, T17, T18, T19, T20, T21>(v1, v2, v3, v4, v5, v6, + v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22> +internal::ValueArray22<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22> Values(T1 v1, T2 v2, T3 v3, + T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, + T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, + T21 v21, T22 v22) { + return internal::ValueArray22<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, + T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22>(v1, v2, v3, v4, + v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, + v20, v21, v22); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23> +internal::ValueArray23<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23> Values(T1 v1, T2 v2, + T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, + T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, + T21 v21, T22 v22, T23 v23) { + return internal::ValueArray23<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, + T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23>(v1, v2, v3, + v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, + v20, v21, v22, v23); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24> +internal::ValueArray24<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24> Values(T1 v1, T2 v2, + T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, + T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, + T21 v21, T22 v22, T23 v23, T24 v24) { + return internal::ValueArray24<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, + T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24>(v1, v2, + v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, + v19, v20, v21, v22, v23, v24); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25> +internal::ValueArray25<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25> Values(T1 v1, + T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, + T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, + T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25) { + return internal::ValueArray25<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, + T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25>(v1, + v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, + v18, v19, v20, v21, v22, v23, v24, v25); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26> +internal::ValueArray26<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, + T26> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26) { + return internal::ValueArray26<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, + T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, + T26>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, + v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27> +internal::ValueArray27<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, + T27> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27) { + return internal::ValueArray27<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, + T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, + T26, T27>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, + v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28> +internal::ValueArray28<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, + T28> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28) { + return internal::ValueArray28<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, + T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, + T26, T27, T28>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, + v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, + v28); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29> +internal::ValueArray29<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29) { + return internal::ValueArray29<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, + T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, + T26, T27, T28, T29>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, + v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, + v27, v28, v29); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30> +internal::ValueArray30<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, + T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, + T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, + T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30) { + return internal::ValueArray30<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, + T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, + T26, T27, T28, T29, T30>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, + v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, + v26, v27, v28, v29, v30); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31> +internal::ValueArray31<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, + T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, + T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, + T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31) { + return internal::ValueArray31<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, + T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, + T26, T27, T28, T29, T30, T31>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, + v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, + v25, v26, v27, v28, v29, v30, v31); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32> +internal::ValueArray32<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, + T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, + T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, + T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, + T32 v32) { + return internal::ValueArray32<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, + T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, + T26, T27, T28, T29, T30, T31, T32>(v1, v2, v3, v4, v5, v6, v7, v8, v9, + v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, + v24, v25, v26, v27, v28, v29, v30, v31, v32); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33> +internal::ValueArray33<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, + T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, + T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, + T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, + T32 v32, T33 v33) { + return internal::ValueArray33<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, + T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, + T26, T27, T28, T29, T30, T31, T32, T33>(v1, v2, v3, v4, v5, v6, v7, v8, + v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, + v24, v25, v26, v27, v28, v29, v30, v31, v32, v33); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34> +internal::ValueArray34<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, + T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, + T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, + T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, + T31 v31, T32 v32, T33 v33, T34 v34) { + return internal::ValueArray34<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, + T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, + T26, T27, T28, T29, T30, T31, T32, T33, T34>(v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, + v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35> +internal::ValueArray35<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34, T35> Values(T1 v1, T2 v2, T3 v3, T4 v4, + T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, + T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, + T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, + T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35) { + return internal::ValueArray35<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, + T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, + T26, T27, T28, T29, T30, T31, T32, T33, T34, T35>(v1, v2, v3, v4, v5, v6, + v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, + v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36> +internal::ValueArray36<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34, T35, T36> Values(T1 v1, T2 v2, T3 v3, T4 v4, + T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, + T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, + T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, + T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36) { + return internal::ValueArray36<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, + T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, + T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36>(v1, v2, v3, v4, + v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, + v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, + v34, v35, v36); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37> +internal::ValueArray37<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34, T35, T36, T37> Values(T1 v1, T2 v2, T3 v3, + T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, + T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, + T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, + T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, + T37 v37) { + return internal::ValueArray37<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, + T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, + T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37>(v1, v2, v3, + v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, + v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, + v34, v35, v36, v37); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38> +internal::ValueArray38<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34, T35, T36, T37, T38> Values(T1 v1, T2 v2, + T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, + T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, + T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, + T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, + T37 v37, T38 v38) { + return internal::ValueArray38<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, + T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, + T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38>(v1, v2, + v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, + v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, + v33, v34, v35, v36, v37, v38); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39> +internal::ValueArray39<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39> Values(T1 v1, T2 v2, + T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, + T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, + T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, + T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, + T37 v37, T38 v38, T39 v39) { + return internal::ValueArray39<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, + T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, + T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39>(v1, + v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, + v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, + v32, v33, v34, v35, v36, v37, v38, v39); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40> +internal::ValueArray40<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40> Values(T1 v1, + T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, + T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, + T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, + T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, + T36 v36, T37 v37, T38 v38, T39 v39, T40 v40) { + return internal::ValueArray40<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, + T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, + T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, + T40>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, + v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, + v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41> +internal::ValueArray41<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, + T41> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41) { + return internal::ValueArray41<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, + T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, + T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, + T40, T41>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, + v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, + v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42> +internal::ValueArray42<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, + T42> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42) { + return internal::ValueArray42<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, + T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, + T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, + T40, T41, T42>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, + v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, + v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, + v42); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43> +internal::ValueArray43<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, + T43> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43) { + return internal::ValueArray43<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, + T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, + T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, + T40, T41, T42, T43>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, + v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, + v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, + v41, v42, v43); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43, typename T44> +internal::ValueArray44<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, + T44> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43, T44 v44) { + return internal::ValueArray44<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, + T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, + T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, + T40, T41, T42, T43, T44>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, + v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, + v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, + v40, v41, v42, v43, v44); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43, typename T44, typename T45> +internal::ValueArray45<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, + T44, T45> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, + T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, + T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, + T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, + T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, + T41 v41, T42 v42, T43 v43, T44 v44, T45 v45) { + return internal::ValueArray45<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, + T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, + T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, + T40, T41, T42, T43, T44, T45>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, + v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, + v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, + v39, v40, v41, v42, v43, v44, v45); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43, typename T44, typename T45, + typename T46> +internal::ValueArray46<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, + T44, T45, T46> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, + T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, + T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, + T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, + T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, + T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46) { + return internal::ValueArray46<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, + T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, + T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, + T40, T41, T42, T43, T44, T45, T46>(v1, v2, v3, v4, v5, v6, v7, v8, v9, + v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, + v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, + v38, v39, v40, v41, v42, v43, v44, v45, v46); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43, typename T44, typename T45, + typename T46, typename T47> +internal::ValueArray47<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, + T44, T45, T46, T47> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, + T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, + T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, + T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, + T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, + T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47) { + return internal::ValueArray47<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, + T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, + T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, + T40, T41, T42, T43, T44, T45, T46, T47>(v1, v2, v3, v4, v5, v6, v7, v8, + v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, + v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, + v38, v39, v40, v41, v42, v43, v44, v45, v46, v47); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43, typename T44, typename T45, + typename T46, typename T47, typename T48> +internal::ValueArray48<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, + T44, T45, T46, T47, T48> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, + T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, + T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, + T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, + T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, + T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, + T48 v48) { + return internal::ValueArray48<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, + T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, + T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, + T40, T41, T42, T43, T44, T45, T46, T47, T48>(v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, + v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, + v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43, typename T44, typename T45, + typename T46, typename T47, typename T48, typename T49> +internal::ValueArray49<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, + T44, T45, T46, T47, T48, T49> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, + T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, + T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, + T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, + T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, + T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, + T47 v47, T48 v48, T49 v49) { + return internal::ValueArray49<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, + T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, + T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, + T40, T41, T42, T43, T44, T45, T46, T47, T48, T49>(v1, v2, v3, v4, v5, v6, + v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, + v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, + v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43, typename T44, typename T45, + typename T46, typename T47, typename T48, typename T49, typename T50> +internal::ValueArray50<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, + T44, T45, T46, T47, T48, T49, T50> Values(T1 v1, T2 v2, T3 v3, T4 v4, + T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, + T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, + T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, + T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, + T38 v38, T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, + T46 v46, T47 v47, T48 v48, T49 v49, T50 v50) { + return internal::ValueArray50<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, + T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, + T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, + T40, T41, T42, T43, T44, T45, T46, T47, T48, T49, T50>(v1, v2, v3, v4, + v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, + v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, + v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, + v48, v49, v50); +} + +// Bool() allows generating tests with parameters in a set of (false, true). +// +// Synopsis: +// Bool() +// - returns a generator producing sequences with elements {false, true}. +// +// It is useful when testing code that depends on Boolean flags. Combinations +// of multiple flags can be tested when several Bool()'s are combined using +// Combine() function. +// +// In the following example all tests in the test case FlagDependentTest +// will be instantiated twice with parameters false and true. +// +// class FlagDependentTest : public testing::TestWithParam<bool> { +// virtual void SetUp() { +// external_flag = GetParam(); +// } +// } +// INSTANTIATE_TEST_CASE_P(BoolSequence, FlagDependentTest, Bool()); +// +inline internal::ParamGenerator<bool> Bool() { + return Values(false, true); +} + +#if GTEST_HAS_COMBINE +// Combine() allows the user to combine two or more sequences to produce +// values of a Cartesian product of those sequences' elements. +// +// Synopsis: +// Combine(gen1, gen2, ..., genN) +// - returns a generator producing sequences with elements coming from +// the Cartesian product of elements from the sequences generated by +// gen1, gen2, ..., genN. The sequence elements will have a type of +// tuple<T1, T2, ..., TN> where T1, T2, ..., TN are the types +// of elements from sequences produces by gen1, gen2, ..., genN. +// +// Combine can have up to 10 arguments. This number is currently limited +// by the maximum number of elements in the tuple implementation used by Google +// Test. +// +// Example: +// +// This will instantiate tests in test case AnimalTest each one with +// the parameter values tuple("cat", BLACK), tuple("cat", WHITE), +// tuple("dog", BLACK), and tuple("dog", WHITE): +// +// enum Color { BLACK, GRAY, WHITE }; +// class AnimalTest +// : public testing::TestWithParam<tuple<const char*, Color> > {...}; +// +// TEST_P(AnimalTest, AnimalLooksNice) {...} +// +// INSTANTIATE_TEST_CASE_P(AnimalVariations, AnimalTest, +// Combine(Values("cat", "dog"), +// Values(BLACK, WHITE))); +// +// This will instantiate tests in FlagDependentTest with all variations of two +// Boolean flags: +// +// class FlagDependentTest +// : public testing::TestWithParam<tuple(bool, bool)> > { +// virtual void SetUp() { +// // Assigns external_flag_1 and external_flag_2 values from the tuple. +// tie(external_flag_1, external_flag_2) = GetParam(); +// } +// }; +// +// TEST_P(FlagDependentTest, TestFeature1) { +// // Test your code using external_flag_1 and external_flag_2 here. +// } +// INSTANTIATE_TEST_CASE_P(TwoBoolSequence, FlagDependentTest, +// Combine(Bool(), Bool())); +// +template <typename Generator1, typename Generator2> +internal::CartesianProductHolder2<Generator1, Generator2> Combine( + const Generator1& g1, const Generator2& g2) { + return internal::CartesianProductHolder2<Generator1, Generator2>( + g1, g2); +} + +template <typename Generator1, typename Generator2, typename Generator3> +internal::CartesianProductHolder3<Generator1, Generator2, Generator3> Combine( + const Generator1& g1, const Generator2& g2, const Generator3& g3) { + return internal::CartesianProductHolder3<Generator1, Generator2, Generator3>( + g1, g2, g3); +} + +template <typename Generator1, typename Generator2, typename Generator3, + typename Generator4> +internal::CartesianProductHolder4<Generator1, Generator2, Generator3, + Generator4> Combine( + const Generator1& g1, const Generator2& g2, const Generator3& g3, + const Generator4& g4) { + return internal::CartesianProductHolder4<Generator1, Generator2, Generator3, + Generator4>( + g1, g2, g3, g4); +} + +template <typename Generator1, typename Generator2, typename Generator3, + typename Generator4, typename Generator5> +internal::CartesianProductHolder5<Generator1, Generator2, Generator3, + Generator4, Generator5> Combine( + const Generator1& g1, const Generator2& g2, const Generator3& g3, + const Generator4& g4, const Generator5& g5) { + return internal::CartesianProductHolder5<Generator1, Generator2, Generator3, + Generator4, Generator5>( + g1, g2, g3, g4, g5); +} + +template <typename Generator1, typename Generator2, typename Generator3, + typename Generator4, typename Generator5, typename Generator6> +internal::CartesianProductHolder6<Generator1, Generator2, Generator3, + Generator4, Generator5, Generator6> Combine( + const Generator1& g1, const Generator2& g2, const Generator3& g3, + const Generator4& g4, const Generator5& g5, const Generator6& g6) { + return internal::CartesianProductHolder6<Generator1, Generator2, Generator3, + Generator4, Generator5, Generator6>( + g1, g2, g3, g4, g5, g6); +} + +template <typename Generator1, typename Generator2, typename Generator3, + typename Generator4, typename Generator5, typename Generator6, + typename Generator7> +internal::CartesianProductHolder7<Generator1, Generator2, Generator3, + Generator4, Generator5, Generator6, Generator7> Combine( + const Generator1& g1, const Generator2& g2, const Generator3& g3, + const Generator4& g4, const Generator5& g5, const Generator6& g6, + const Generator7& g7) { + return internal::CartesianProductHolder7<Generator1, Generator2, Generator3, + Generator4, Generator5, Generator6, Generator7>( + g1, g2, g3, g4, g5, g6, g7); +} + +template <typename Generator1, typename Generator2, typename Generator3, + typename Generator4, typename Generator5, typename Generator6, + typename Generator7, typename Generator8> +internal::CartesianProductHolder8<Generator1, Generator2, Generator3, + Generator4, Generator5, Generator6, Generator7, Generator8> Combine( + const Generator1& g1, const Generator2& g2, const Generator3& g3, + const Generator4& g4, const Generator5& g5, const Generator6& g6, + const Generator7& g7, const Generator8& g8) { + return internal::CartesianProductHolder8<Generator1, Generator2, Generator3, + Generator4, Generator5, Generator6, Generator7, Generator8>( + g1, g2, g3, g4, g5, g6, g7, g8); +} + +template <typename Generator1, typename Generator2, typename Generator3, + typename Generator4, typename Generator5, typename Generator6, + typename Generator7, typename Generator8, typename Generator9> +internal::CartesianProductHolder9<Generator1, Generator2, Generator3, + Generator4, Generator5, Generator6, Generator7, Generator8, + Generator9> Combine( + const Generator1& g1, const Generator2& g2, const Generator3& g3, + const Generator4& g4, const Generator5& g5, const Generator6& g6, + const Generator7& g7, const Generator8& g8, const Generator9& g9) { + return internal::CartesianProductHolder9<Generator1, Generator2, Generator3, + Generator4, Generator5, Generator6, Generator7, Generator8, Generator9>( + g1, g2, g3, g4, g5, g6, g7, g8, g9); +} + +template <typename Generator1, typename Generator2, typename Generator3, + typename Generator4, typename Generator5, typename Generator6, + typename Generator7, typename Generator8, typename Generator9, + typename Generator10> +internal::CartesianProductHolder10<Generator1, Generator2, Generator3, + Generator4, Generator5, Generator6, Generator7, Generator8, Generator9, + Generator10> Combine( + const Generator1& g1, const Generator2& g2, const Generator3& g3, + const Generator4& g4, const Generator5& g5, const Generator6& g6, + const Generator7& g7, const Generator8& g8, const Generator9& g9, + const Generator10& g10) { + return internal::CartesianProductHolder10<Generator1, Generator2, Generator3, + Generator4, Generator5, Generator6, Generator7, Generator8, Generator9, + Generator10>( + g1, g2, g3, g4, g5, g6, g7, g8, g9, g10); +} +#endif // GTEST_HAS_COMBINE + + + +#define TEST_P(test_case_name, test_name) \ + class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) \ + : public test_case_name { \ + public: \ + GTEST_TEST_CLASS_NAME_(test_case_name, test_name)() {} \ + virtual void TestBody(); \ + private: \ + static int AddToRegistry() { \ + ::testing::UnitTest::GetInstance()->parameterized_test_registry(). \ + GetTestCasePatternHolder<test_case_name>(\ + #test_case_name, __FILE__, __LINE__)->AddTestPattern(\ + #test_case_name, \ + #test_name, \ + new ::testing::internal::TestMetaFactory< \ + GTEST_TEST_CLASS_NAME_(test_case_name, test_name)>()); \ + return 0; \ + } \ + static int gtest_registering_dummy_; \ + GTEST_DISALLOW_COPY_AND_ASSIGN_(\ + GTEST_TEST_CLASS_NAME_(test_case_name, test_name)); \ + }; \ + int GTEST_TEST_CLASS_NAME_(test_case_name, \ + test_name)::gtest_registering_dummy_ = \ + GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::AddToRegistry(); \ + void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody() + +#define INSTANTIATE_TEST_CASE_P(prefix, test_case_name, generator) \ + ::testing::internal::ParamGenerator<test_case_name::ParamType> \ + gtest_##prefix##test_case_name##_EvalGenerator_() { return generator; } \ + int gtest_##prefix##test_case_name##_dummy_ = \ + ::testing::UnitTest::GetInstance()->parameterized_test_registry(). \ + GetTestCasePatternHolder<test_case_name>(\ + #test_case_name, __FILE__, __LINE__)->AddTestCaseInstantiation(\ + #prefix, \ + >est_##prefix##test_case_name##_EvalGenerator_, \ + __FILE__, __LINE__) + +} // namespace testing + +#endif // GTEST_HAS_PARAM_TEST + +#endif // GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_ +// Copyright 2006, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: wan@google.com (Zhanyong Wan) +// +// Google C++ Testing Framework definitions useful in production code. + +#ifndef GTEST_INCLUDE_GTEST_GTEST_PROD_H_ +#define GTEST_INCLUDE_GTEST_GTEST_PROD_H_ + +// When you need to test the private or protected members of a class, +// use the FRIEND_TEST macro to declare your tests as friends of the +// class. For example: +// +// class MyClass { +// private: +// void MyMethod(); +// FRIEND_TEST(MyClassTest, MyMethod); +// }; +// +// class MyClassTest : public testing::Test { +// // ... +// }; +// +// TEST_F(MyClassTest, MyMethod) { +// // Can call MyClass::MyMethod() here. +// } + +#define FRIEND_TEST(test_case_name, test_name)\ +friend class test_case_name##_##test_name##_Test + +#endif // GTEST_INCLUDE_GTEST_GTEST_PROD_H_ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: mheule@google.com (Markus Heule) +// + +#ifndef GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_ +#define GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_ + +#include <iosfwd> +#include <vector> + +namespace testing { + +// A copyable object representing the result of a test part (i.e. an +// assertion or an explicit FAIL(), ADD_FAILURE(), or SUCCESS()). +// +// Don't inherit from TestPartResult as its destructor is not virtual. +class GTEST_API_ TestPartResult { + public: + // The possible outcomes of a test part (i.e. an assertion or an + // explicit SUCCEED(), FAIL(), or ADD_FAILURE()). + enum Type { + kSuccess, // Succeeded. + kNonFatalFailure, // Failed but the test can continue. + kFatalFailure // Failed and the test should be terminated. + }; + + // C'tor. TestPartResult does NOT have a default constructor. + // Always use this constructor (with parameters) to create a + // TestPartResult object. + TestPartResult(Type a_type, + const char* a_file_name, + int a_line_number, + const char* a_message) + : type_(a_type), + file_name_(a_file_name), + line_number_(a_line_number), + summary_(ExtractSummary(a_message)), + message_(a_message) { + } + + // Gets the outcome of the test part. + Type type() const { return type_; } + + // Gets the name of the source file where the test part took place, or + // NULL if it's unknown. + const char* file_name() const { return file_name_.c_str(); } + + // Gets the line in the source file where the test part took place, + // or -1 if it's unknown. + int line_number() const { return line_number_; } + + // Gets the summary of the failure message. + const char* summary() const { return summary_.c_str(); } + + // Gets the message associated with the test part. + const char* message() const { return message_.c_str(); } + + // Returns true iff the test part passed. + bool passed() const { return type_ == kSuccess; } + + // Returns true iff the test part failed. + bool failed() const { return type_ != kSuccess; } + + // Returns true iff the test part non-fatally failed. + bool nonfatally_failed() const { return type_ == kNonFatalFailure; } + + // Returns true iff the test part fatally failed. + bool fatally_failed() const { return type_ == kFatalFailure; } + private: + Type type_; + + // Gets the summary of the failure message by omitting the stack + // trace in it. + static internal::String ExtractSummary(const char* message); + + // The name of the source file where the test part took place, or + // NULL if the source file is unknown. + internal::String file_name_; + // The line in the source file where the test part took place, or -1 + // if the line number is unknown. + int line_number_; + internal::String summary_; // The test failure summary. + internal::String message_; // The test failure message. +}; + +// Prints a TestPartResult object. +std::ostream& operator<<(std::ostream& os, const TestPartResult& result); + +// An array of TestPartResult objects. +// +// Don't inherit from TestPartResultArray as its destructor is not +// virtual. +class GTEST_API_ TestPartResultArray { + public: + TestPartResultArray() {} + + // Appends the given TestPartResult to the array. + void Append(const TestPartResult& result); + + // Returns the TestPartResult at the given index (0-based). + const TestPartResult& GetTestPartResult(int index) const; + + // Returns the number of TestPartResult objects in the array. + int size() const; + + private: + std::vector<TestPartResult> array_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestPartResultArray); +}; + +// This interface knows how to report a test part result. +class TestPartResultReporterInterface { + public: + virtual ~TestPartResultReporterInterface() {} + + virtual void ReportTestPartResult(const TestPartResult& result) = 0; +}; + +namespace internal { + +// This helper class is used by {ASSERT|EXPECT}_NO_FATAL_FAILURE to check if a +// statement generates new fatal failures. To do so it registers itself as the +// current test part result reporter. Besides checking if fatal failures were +// reported, it only delegates the reporting to the former result reporter. +// The original result reporter is restored in the destructor. +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +class GTEST_API_ HasNewFatalFailureHelper + : public TestPartResultReporterInterface { + public: + HasNewFatalFailureHelper(); + virtual ~HasNewFatalFailureHelper(); + virtual void ReportTestPartResult(const TestPartResult& result); + bool has_new_fatal_failure() const { return has_new_fatal_failure_; } + private: + bool has_new_fatal_failure_; + TestPartResultReporterInterface* original_reporter_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(HasNewFatalFailureHelper); +}; + +} // namespace internal + +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_ +// Copyright 2008 Google Inc. +// All Rights Reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: wan@google.com (Zhanyong Wan) + +#ifndef GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_ +#define GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_ + +// This header implements typed tests and type-parameterized tests. + +// Typed (aka type-driven) tests repeat the same test for types in a +// list. You must know which types you want to test with when writing +// typed tests. Here's how you do it: + +#if 0 + +// First, define a fixture class template. It should be parameterized +// by a type. Remember to derive it from testing::Test. +template <typename T> +class FooTest : public testing::Test { + public: + ... + typedef std::list<T> List; + static T shared_; + T value_; +}; + +// Next, associate a list of types with the test case, which will be +// repeated for each type in the list. The typedef is necessary for +// the macro to parse correctly. +typedef testing::Types<char, int, unsigned int> MyTypes; +TYPED_TEST_CASE(FooTest, MyTypes); + +// If the type list contains only one type, you can write that type +// directly without Types<...>: +// TYPED_TEST_CASE(FooTest, int); + +// Then, use TYPED_TEST() instead of TEST_F() to define as many typed +// tests for this test case as you want. +TYPED_TEST(FooTest, DoesBlah) { + // Inside a test, refer to TypeParam to get the type parameter. + // Since we are inside a derived class template, C++ requires use to + // visit the members of FooTest via 'this'. + TypeParam n = this->value_; + + // To visit static members of the fixture, add the TestFixture:: + // prefix. + n += TestFixture::shared_; + + // To refer to typedefs in the fixture, add the "typename + // TestFixture::" prefix. + typename TestFixture::List values; + values.push_back(n); + ... +} + +TYPED_TEST(FooTest, HasPropertyA) { ... } + +#endif // 0 + +// Type-parameterized tests are abstract test patterns parameterized +// by a type. Compared with typed tests, type-parameterized tests +// allow you to define the test pattern without knowing what the type +// parameters are. The defined pattern can be instantiated with +// different types any number of times, in any number of translation +// units. +// +// If you are designing an interface or concept, you can define a +// suite of type-parameterized tests to verify properties that any +// valid implementation of the interface/concept should have. Then, +// each implementation can easily instantiate the test suite to verify +// that it conforms to the requirements, without having to write +// similar tests repeatedly. Here's an example: + +#if 0 + +// First, define a fixture class template. It should be parameterized +// by a type. Remember to derive it from testing::Test. +template <typename T> +class FooTest : public testing::Test { + ... +}; + +// Next, declare that you will define a type-parameterized test case +// (the _P suffix is for "parameterized" or "pattern", whichever you +// prefer): +TYPED_TEST_CASE_P(FooTest); + +// Then, use TYPED_TEST_P() to define as many type-parameterized tests +// for this type-parameterized test case as you want. +TYPED_TEST_P(FooTest, DoesBlah) { + // Inside a test, refer to TypeParam to get the type parameter. + TypeParam n = 0; + ... +} + +TYPED_TEST_P(FooTest, HasPropertyA) { ... } + +// Now the tricky part: you need to register all test patterns before +// you can instantiate them. The first argument of the macro is the +// test case name; the rest are the names of the tests in this test +// case. +REGISTER_TYPED_TEST_CASE_P(FooTest, + DoesBlah, HasPropertyA); + +// Finally, you are free to instantiate the pattern with the types you +// want. If you put the above code in a header file, you can #include +// it in multiple C++ source files and instantiate it multiple times. +// +// To distinguish different instances of the pattern, the first +// argument to the INSTANTIATE_* macro is a prefix that will be added +// to the actual test case name. Remember to pick unique prefixes for +// different instances. +typedef testing::Types<char, int, unsigned int> MyTypes; +INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, MyTypes); + +// If the type list contains only one type, you can write that type +// directly without Types<...>: +// INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, int); + +#endif // 0 + + +// Implements typed tests. + +#if GTEST_HAS_TYPED_TEST + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// Expands to the name of the typedef for the type parameters of the +// given test case. +#define GTEST_TYPE_PARAMS_(TestCaseName) gtest_type_params_##TestCaseName##_ + +// The 'Types' template argument below must have spaces around it +// since some compilers may choke on '>>' when passing a template +// instance (e.g. Types<int>) +#define TYPED_TEST_CASE(CaseName, Types) \ + typedef ::testing::internal::TypeList< Types >::type \ + GTEST_TYPE_PARAMS_(CaseName) + +#define TYPED_TEST(CaseName, TestName) \ + template <typename gtest_TypeParam_> \ + class GTEST_TEST_CLASS_NAME_(CaseName, TestName) \ + : public CaseName<gtest_TypeParam_> { \ + private: \ + typedef CaseName<gtest_TypeParam_> TestFixture; \ + typedef gtest_TypeParam_ TypeParam; \ + virtual void TestBody(); \ + }; \ + bool gtest_##CaseName##_##TestName##_registered_ = \ + ::testing::internal::TypeParameterizedTest< \ + CaseName, \ + ::testing::internal::TemplateSel< \ + GTEST_TEST_CLASS_NAME_(CaseName, TestName)>, \ + GTEST_TYPE_PARAMS_(CaseName)>::Register(\ + "", #CaseName, #TestName, 0); \ + template <typename gtest_TypeParam_> \ + void GTEST_TEST_CLASS_NAME_(CaseName, TestName)<gtest_TypeParam_>::TestBody() + +#endif // GTEST_HAS_TYPED_TEST + +// Implements type-parameterized tests. + +#if GTEST_HAS_TYPED_TEST_P + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// Expands to the namespace name that the type-parameterized tests for +// the given type-parameterized test case are defined in. The exact +// name of the namespace is subject to change without notice. +#define GTEST_CASE_NAMESPACE_(TestCaseName) \ + gtest_case_##TestCaseName##_ + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// Expands to the name of the variable used to remember the names of +// the defined tests in the given test case. +#define GTEST_TYPED_TEST_CASE_P_STATE_(TestCaseName) \ + gtest_typed_test_case_p_state_##TestCaseName##_ + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE DIRECTLY. +// +// Expands to the name of the variable used to remember the names of +// the registered tests in the given test case. +#define GTEST_REGISTERED_TEST_NAMES_(TestCaseName) \ + gtest_registered_test_names_##TestCaseName##_ + +// The variables defined in the type-parameterized test macros are +// static as typically these macros are used in a .h file that can be +// #included in multiple translation units linked together. +#define TYPED_TEST_CASE_P(CaseName) \ + static ::testing::internal::TypedTestCasePState \ + GTEST_TYPED_TEST_CASE_P_STATE_(CaseName) + +#define TYPED_TEST_P(CaseName, TestName) \ + namespace GTEST_CASE_NAMESPACE_(CaseName) { \ + template <typename gtest_TypeParam_> \ + class TestName : public CaseName<gtest_TypeParam_> { \ + private: \ + typedef CaseName<gtest_TypeParam_> TestFixture; \ + typedef gtest_TypeParam_ TypeParam; \ + virtual void TestBody(); \ + }; \ + static bool gtest_##TestName##_defined_ = \ + GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).AddTestName(\ + __FILE__, __LINE__, #CaseName, #TestName); \ + } \ + template <typename gtest_TypeParam_> \ + void GTEST_CASE_NAMESPACE_(CaseName)::TestName<gtest_TypeParam_>::TestBody() + +#define REGISTER_TYPED_TEST_CASE_P(CaseName, ...) \ + namespace GTEST_CASE_NAMESPACE_(CaseName) { \ + typedef ::testing::internal::Templates<__VA_ARGS__>::type gtest_AllTests_; \ + } \ + static const char* const GTEST_REGISTERED_TEST_NAMES_(CaseName) = \ + GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).VerifyRegisteredTestNames(\ + __FILE__, __LINE__, #__VA_ARGS__) + +// The 'Types' template argument below must have spaces around it +// since some compilers may choke on '>>' when passing a template +// instance (e.g. Types<int>) +#define INSTANTIATE_TYPED_TEST_CASE_P(Prefix, CaseName, Types) \ + bool gtest_##Prefix##_##CaseName = \ + ::testing::internal::TypeParameterizedTestCase<CaseName, \ + GTEST_CASE_NAMESPACE_(CaseName)::gtest_AllTests_, \ + ::testing::internal::TypeList< Types >::type>::Register(\ + #Prefix, #CaseName, GTEST_REGISTERED_TEST_NAMES_(CaseName)) + +#endif // GTEST_HAS_TYPED_TEST_P + +#endif // GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_ + +// Depending on the platform, different string classes are available. +// On Linux, in addition to ::std::string, Google also makes use of +// class ::string, which has the same interface as ::std::string, but +// has a different implementation. +// +// The user can define GTEST_HAS_GLOBAL_STRING to 1 to indicate that +// ::string is available AND is a distinct type to ::std::string, or +// define it to 0 to indicate otherwise. +// +// If the user's ::std::string and ::string are the same class due to +// aliasing, he should define GTEST_HAS_GLOBAL_STRING to 0. +// +// If the user doesn't define GTEST_HAS_GLOBAL_STRING, it is defined +// heuristically. + +namespace testing { + +// Declares the flags. + +// This flag temporary enables the disabled tests. +GTEST_DECLARE_bool_(also_run_disabled_tests); + +// This flag brings the debugger on an assertion failure. +GTEST_DECLARE_bool_(break_on_failure); + +// This flag controls whether Google Test catches all test-thrown exceptions +// and logs them as failures. +GTEST_DECLARE_bool_(catch_exceptions); + +// This flag enables using colors in terminal output. Available values are +// "yes" to enable colors, "no" (disable colors), or "auto" (the default) +// to let Google Test decide. +GTEST_DECLARE_string_(color); + +// This flag sets up the filter to select by name using a glob pattern +// the tests to run. If the filter is not given all tests are executed. +GTEST_DECLARE_string_(filter); + +// This flag causes the Google Test to list tests. None of the tests listed +// are actually run if the flag is provided. +GTEST_DECLARE_bool_(list_tests); + +// This flag controls whether Google Test emits a detailed XML report to a file +// in addition to its normal textual output. +GTEST_DECLARE_string_(output); + +// This flags control whether Google Test prints the elapsed time for each +// test. +GTEST_DECLARE_bool_(print_time); + +// This flag specifies the random number seed. +GTEST_DECLARE_int32_(random_seed); + +// This flag sets how many times the tests are repeated. The default value +// is 1. If the value is -1 the tests are repeating forever. +GTEST_DECLARE_int32_(repeat); + +// This flag controls whether Google Test includes Google Test internal +// stack frames in failure stack traces. +GTEST_DECLARE_bool_(show_internal_stack_frames); + +// When this flag is specified, tests' order is randomized on every iteration. +GTEST_DECLARE_bool_(shuffle); + +// This flag specifies the maximum number of stack frames to be +// printed in a failure message. +GTEST_DECLARE_int32_(stack_trace_depth); + +// When this flag is specified, a failed assertion will throw an +// exception if exceptions are enabled, or exit the program with a +// non-zero code otherwise. +GTEST_DECLARE_bool_(throw_on_failure); + +// The upper limit for valid stack trace depths. +const int kMaxStackTraceDepth = 100; + +namespace internal { + +class AssertHelper; +class DefaultGlobalTestPartResultReporter; +class ExecDeathTest; +class NoExecDeathTest; +class FinalSuccessChecker; +class GTestFlagSaver; +class TestInfoImpl; +class TestResultAccessor; +class TestEventListenersAccessor; +class TestEventRepeater; +class WindowsDeathTest; +class UnitTestImpl* GetUnitTestImpl(); +void ReportFailureInUnknownLocation(TestPartResult::Type result_type, + const String& message); +class PrettyUnitTestResultPrinter; +class XmlUnitTestResultPrinter; + +// Converts a streamable value to a String. A NULL pointer is +// converted to "(null)". When the input value is a ::string, +// ::std::string, ::wstring, or ::std::wstring object, each NUL +// character in it is replaced with "\\0". +// Declared in gtest-internal.h but defined here, so that it has access +// to the definition of the Message class, required by the ARM +// compiler. +template <typename T> +String StreamableToString(const T& streamable) { + return (Message() << streamable).GetString(); +} + +} // namespace internal + +// A class for indicating whether an assertion was successful. When +// the assertion wasn't successful, the AssertionResult object +// remembers a non-empty message that describes how it failed. +// +// To create an instance of this class, use one of the factory functions +// (AssertionSuccess() and AssertionFailure()). +// +// This class is useful for two purposes: +// 1. Defining predicate functions to be used with Boolean test assertions +// EXPECT_TRUE/EXPECT_FALSE and their ASSERT_ counterparts +// 2. Defining predicate-format functions to be +// used with predicate assertions (ASSERT_PRED_FORMAT*, etc). +// +// For example, if you define IsEven predicate: +// +// testing::AssertionResult IsEven(int n) { +// if ((n % 2) == 0) +// return testing::AssertionSuccess(); +// else +// return testing::AssertionFailure() << n << " is odd"; +// } +// +// Then the failed expectation EXPECT_TRUE(IsEven(Fib(5))) +// will print the message +// +// Value of: IsEven(Fib(5)) +// Actual: false (5 is odd) +// Expected: true +// +// instead of a more opaque +// +// Value of: IsEven(Fib(5)) +// Actual: false +// Expected: true +// +// in case IsEven is a simple Boolean predicate. +// +// If you expect your predicate to be reused and want to support informative +// messages in EXPECT_FALSE and ASSERT_FALSE (negative assertions show up +// about half as often as positive ones in our tests), supply messages for +// both success and failure cases: +// +// testing::AssertionResult IsEven(int n) { +// if ((n % 2) == 0) +// return testing::AssertionSuccess() << n << " is even"; +// else +// return testing::AssertionFailure() << n << " is odd"; +// } +// +// Then a statement EXPECT_FALSE(IsEven(Fib(6))) will print +// +// Value of: IsEven(Fib(6)) +// Actual: true (8 is even) +// Expected: false +// +// NB: Predicates that support negative Boolean assertions have reduced +// performance in positive ones so be careful not to use them in tests +// that have lots (tens of thousands) of positive Boolean assertions. +// +// To use this class with EXPECT_PRED_FORMAT assertions such as: +// +// // Verifies that Foo() returns an even number. +// EXPECT_PRED_FORMAT1(IsEven, Foo()); +// +// you need to define: +// +// testing::AssertionResult IsEven(const char* expr, int n) { +// if ((n % 2) == 0) +// return testing::AssertionSuccess(); +// else +// return testing::AssertionFailure() +// << "Expected: " << expr << " is even\n Actual: it's " << n; +// } +// +// If Foo() returns 5, you will see the following message: +// +// Expected: Foo() is even +// Actual: it's 5 +// +class GTEST_API_ AssertionResult { + public: + // Copy constructor. + // Used in EXPECT_TRUE/FALSE(assertion_result). + AssertionResult(const AssertionResult& other); + // Used in the EXPECT_TRUE/FALSE(bool_expression). + explicit AssertionResult(bool success) : success_(success) {} + + // Returns true iff the assertion succeeded. + operator bool() const { return success_; } // NOLINT + + // Returns the assertion's negation. Used with EXPECT/ASSERT_FALSE. + AssertionResult operator!() const; + + // Returns the text streamed into this AssertionResult. Test assertions + // use it when they fail (i.e., the predicate's outcome doesn't match the + // assertion's expectation). When nothing has been streamed into the + // object, returns an empty string. + const char* message() const { + return message_.get() != NULL && message_->c_str() != NULL ? + message_->c_str() : ""; + } + // TODO(vladl@google.com): Remove this after making sure no clients use it. + // Deprecated; please use message() instead. + const char* failure_message() const { return message(); } + + // Streams a custom failure message into this object. + template <typename T> AssertionResult& operator<<(const T& value); + + private: + // No implementation - we want AssertionResult to be + // copy-constructible but not assignable. + void operator=(const AssertionResult& other); + + // Stores result of the assertion predicate. + bool success_; + // Stores the message describing the condition in case the expectation + // construct is not satisfied with the predicate's outcome. + // Referenced via a pointer to avoid taking too much stack frame space + // with test assertions. + internal::scoped_ptr<internal::String> message_; +}; // class AssertionResult + +// Streams a custom failure message into this object. +template <typename T> +AssertionResult& AssertionResult::operator<<(const T& value) { + Message msg; + if (message_.get() != NULL) + msg << *message_; + msg << value; + message_.reset(new internal::String(msg.GetString())); + return *this; +} + +// Makes a successful assertion result. +GTEST_API_ AssertionResult AssertionSuccess(); + +// Makes a failed assertion result. +GTEST_API_ AssertionResult AssertionFailure(); + +// Makes a failed assertion result with the given failure message. +// Deprecated; use AssertionFailure() << msg. +GTEST_API_ AssertionResult AssertionFailure(const Message& msg); + +// The abstract class that all tests inherit from. +// +// In Google Test, a unit test program contains one or many TestCases, and +// each TestCase contains one or many Tests. +// +// When you define a test using the TEST macro, you don't need to +// explicitly derive from Test - the TEST macro automatically does +// this for you. +// +// The only time you derive from Test is when defining a test fixture +// to be used a TEST_F. For example: +// +// class FooTest : public testing::Test { +// protected: +// virtual void SetUp() { ... } +// virtual void TearDown() { ... } +// ... +// }; +// +// TEST_F(FooTest, Bar) { ... } +// TEST_F(FooTest, Baz) { ... } +// +// Test is not copyable. +class GTEST_API_ Test { + public: + friend class internal::TestInfoImpl; + + // Defines types for pointers to functions that set up and tear down + // a test case. + typedef internal::SetUpTestCaseFunc SetUpTestCaseFunc; + typedef internal::TearDownTestCaseFunc TearDownTestCaseFunc; + + // The d'tor is virtual as we intend to inherit from Test. + virtual ~Test(); + + // Sets up the stuff shared by all tests in this test case. + // + // Google Test will call Foo::SetUpTestCase() before running the first + // test in test case Foo. Hence a sub-class can define its own + // SetUpTestCase() method to shadow the one defined in the super + // class. + static void SetUpTestCase() {} + + // Tears down the stuff shared by all tests in this test case. + // + // Google Test will call Foo::TearDownTestCase() after running the last + // test in test case Foo. Hence a sub-class can define its own + // TearDownTestCase() method to shadow the one defined in the super + // class. + static void TearDownTestCase() {} + + // Returns true iff the current test has a fatal failure. + static bool HasFatalFailure(); + + // Returns true iff the current test has a non-fatal failure. + static bool HasNonfatalFailure(); + + // Returns true iff the current test has a (either fatal or + // non-fatal) failure. + static bool HasFailure() { return HasFatalFailure() || HasNonfatalFailure(); } + + // Logs a property for the current test. Only the last value for a given + // key is remembered. + // These are public static so they can be called from utility functions + // that are not members of the test fixture. + // The arguments are const char* instead strings, as Google Test is used + // on platforms where string doesn't compile. + // + // Note that a driving consideration for these RecordProperty methods + // was to produce xml output suited to the Greenspan charting utility, + // which at present will only chart values that fit in a 32-bit int. It + // is the user's responsibility to restrict their values to 32-bit ints + // if they intend them to be used with Greenspan. + static void RecordProperty(const char* key, const char* value); + static void RecordProperty(const char* key, int value); + + protected: + // Creates a Test object. + Test(); + + // Sets up the test fixture. + virtual void SetUp(); + + // Tears down the test fixture. + virtual void TearDown(); + + private: + // Returns true iff the current test has the same fixture class as + // the first test in the current test case. + static bool HasSameFixtureClass(); + + // Runs the test after the test fixture has been set up. + // + // A sub-class must implement this to define the test logic. + // + // DO NOT OVERRIDE THIS FUNCTION DIRECTLY IN A USER PROGRAM. + // Instead, use the TEST or TEST_F macro. + virtual void TestBody() = 0; + + // Sets up, executes, and tears down the test. + void Run(); + + // Uses a GTestFlagSaver to save and restore all Google Test flags. + const internal::GTestFlagSaver* const gtest_flag_saver_; + + // Often a user mis-spells SetUp() as Setup() and spends a long time + // wondering why it is never called by Google Test. The declaration of + // the following method is solely for catching such an error at + // compile time: + // + // - The return type is deliberately chosen to be not void, so it + // will be a conflict if a user declares void Setup() in his test + // fixture. + // + // - This method is private, so it will be another compiler error + // if a user calls it from his test fixture. + // + // DO NOT OVERRIDE THIS FUNCTION. + // + // If you see an error about overriding the following function or + // about it being private, you have mis-spelled SetUp() as Setup(). + struct Setup_should_be_spelled_SetUp {}; + virtual Setup_should_be_spelled_SetUp* Setup() { return NULL; } + + // We disallow copying Tests. + GTEST_DISALLOW_COPY_AND_ASSIGN_(Test); +}; + +typedef internal::TimeInMillis TimeInMillis; + +// A copyable object representing a user specified test property which can be +// output as a key/value string pair. +// +// Don't inherit from TestProperty as its destructor is not virtual. +class TestProperty { + public: + // C'tor. TestProperty does NOT have a default constructor. + // Always use this constructor (with parameters) to create a + // TestProperty object. + TestProperty(const char* a_key, const char* a_value) : + key_(a_key), value_(a_value) { + } + + // Gets the user supplied key. + const char* key() const { + return key_.c_str(); + } + + // Gets the user supplied value. + const char* value() const { + return value_.c_str(); + } + + // Sets a new value, overriding the one supplied in the constructor. + void SetValue(const char* new_value) { + value_ = new_value; + } + + private: + // The key supplied by the user. + internal::String key_; + // The value supplied by the user. + internal::String value_; +}; + +// The result of a single Test. This includes a list of +// TestPartResults, a list of TestProperties, a count of how many +// death tests there are in the Test, and how much time it took to run +// the Test. +// +// TestResult is not copyable. +class GTEST_API_ TestResult { + public: + // Creates an empty TestResult. + TestResult(); + + // D'tor. Do not inherit from TestResult. + ~TestResult(); + + // Gets the number of all test parts. This is the sum of the number + // of successful test parts and the number of failed test parts. + int total_part_count() const; + + // Returns the number of the test properties. + int test_property_count() const; + + // Returns true iff the test passed (i.e. no test part failed). + bool Passed() const { return !Failed(); } + + // Returns true iff the test failed. + bool Failed() const; + + // Returns true iff the test fatally failed. + bool HasFatalFailure() const; + + // Returns true iff the test has a non-fatal failure. + bool HasNonfatalFailure() const; + + // Returns the elapsed time, in milliseconds. + TimeInMillis elapsed_time() const { return elapsed_time_; } + + // Returns the i-th test part result among all the results. i can range + // from 0 to test_property_count() - 1. If i is not in that range, aborts + // the program. + const TestPartResult& GetTestPartResult(int i) const; + + // Returns the i-th test property. i can range from 0 to + // test_property_count() - 1. If i is not in that range, aborts the + // program. + const TestProperty& GetTestProperty(int i) const; + + private: + friend class TestInfo; + friend class UnitTest; + friend class internal::DefaultGlobalTestPartResultReporter; + friend class internal::ExecDeathTest; + friend class internal::TestInfoImpl; + friend class internal::TestResultAccessor; + friend class internal::UnitTestImpl; + friend class internal::WindowsDeathTest; + + // Gets the vector of TestPartResults. + const std::vector<TestPartResult>& test_part_results() const { + return test_part_results_; + } + + // Gets the vector of TestProperties. + const std::vector<TestProperty>& test_properties() const { + return test_properties_; + } + + // Sets the elapsed time. + void set_elapsed_time(TimeInMillis elapsed) { elapsed_time_ = elapsed; } + + // Adds a test property to the list. The property is validated and may add + // a non-fatal failure if invalid (e.g., if it conflicts with reserved + // key names). If a property is already recorded for the same key, the + // value will be updated, rather than storing multiple values for the same + // key. + void RecordProperty(const TestProperty& test_property); + + // Adds a failure if the key is a reserved attribute of Google Test + // testcase tags. Returns true if the property is valid. + // TODO(russr): Validate attribute names are legal and human readable. + static bool ValidateTestProperty(const TestProperty& test_property); + + // Adds a test part result to the list. + void AddTestPartResult(const TestPartResult& test_part_result); + + // Returns the death test count. + int death_test_count() const { return death_test_count_; } + + // Increments the death test count, returning the new count. + int increment_death_test_count() { return ++death_test_count_; } + + // Clears the test part results. + void ClearTestPartResults(); + + // Clears the object. + void Clear(); + + // Protects mutable state of the property vector and of owned + // properties, whose values may be updated. + internal::Mutex test_properites_mutex_; + + // The vector of TestPartResults + std::vector<TestPartResult> test_part_results_; + // The vector of TestProperties + std::vector<TestProperty> test_properties_; + // Running count of death tests. + int death_test_count_; + // The elapsed time, in milliseconds. + TimeInMillis elapsed_time_; + + // We disallow copying TestResult. + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestResult); +}; // class TestResult + +// A TestInfo object stores the following information about a test: +// +// Test case name +// Test name +// Whether the test should be run +// A function pointer that creates the test object when invoked +// Test result +// +// The constructor of TestInfo registers itself with the UnitTest +// singleton such that the RUN_ALL_TESTS() macro knows which tests to +// run. +class GTEST_API_ TestInfo { + public: + // Destructs a TestInfo object. This function is not virtual, so + // don't inherit from TestInfo. + ~TestInfo(); + + // Returns the test case name. + const char* test_case_name() const; + + // Returns the test name. + const char* name() const; + + // Returns the test case comment. + const char* test_case_comment() const; + + // Returns the test comment. + const char* comment() const; + + // Returns true if this test should run, that is if the test is not disabled + // (or it is disabled but the also_run_disabled_tests flag has been specified) + // and its full name matches the user-specified filter. + // + // Google Test allows the user to filter the tests by their full names. + // The full name of a test Bar in test case Foo is defined as + // "Foo.Bar". Only the tests that match the filter will run. + // + // A filter is a colon-separated list of glob (not regex) patterns, + // optionally followed by a '-' and a colon-separated list of + // negative patterns (tests to exclude). A test is run if it + // matches one of the positive patterns and does not match any of + // the negative patterns. + // + // For example, *A*:Foo.* is a filter that matches any string that + // contains the character 'A' or starts with "Foo.". + bool should_run() const; + + // Returns the result of the test. + const TestResult* result() const; + + private: +#if GTEST_HAS_DEATH_TEST + friend class internal::DefaultDeathTestFactory; +#endif // GTEST_HAS_DEATH_TEST + friend class Test; + friend class TestCase; + friend class internal::TestInfoImpl; + friend class internal::UnitTestImpl; + friend TestInfo* internal::MakeAndRegisterTestInfo( + const char* test_case_name, const char* name, + const char* test_case_comment, const char* comment, + internal::TypeId fixture_class_id, + Test::SetUpTestCaseFunc set_up_tc, + Test::TearDownTestCaseFunc tear_down_tc, + internal::TestFactoryBase* factory); + + // Returns true if this test matches the user-specified filter. + bool matches_filter() const; + + // Increments the number of death tests encountered in this test so + // far. + int increment_death_test_count(); + + // Accessors for the implementation object. + internal::TestInfoImpl* impl() { return impl_; } + const internal::TestInfoImpl* impl() const { return impl_; } + + // Constructs a TestInfo object. The newly constructed instance assumes + // ownership of the factory object. + TestInfo(const char* test_case_name, const char* name, + const char* test_case_comment, const char* comment, + internal::TypeId fixture_class_id, + internal::TestFactoryBase* factory); + + // An opaque implementation object. + internal::TestInfoImpl* impl_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestInfo); +}; + +// A test case, which consists of a vector of TestInfos. +// +// TestCase is not copyable. +class GTEST_API_ TestCase { + public: + // Creates a TestCase with the given name. + // + // TestCase does NOT have a default constructor. Always use this + // constructor to create a TestCase object. + // + // Arguments: + // + // name: name of the test case + // set_up_tc: pointer to the function that sets up the test case + // tear_down_tc: pointer to the function that tears down the test case + TestCase(const char* name, const char* comment, + Test::SetUpTestCaseFunc set_up_tc, + Test::TearDownTestCaseFunc tear_down_tc); + + // Destructor of TestCase. + virtual ~TestCase(); + + // Gets the name of the TestCase. + const char* name() const { return name_.c_str(); } + + // Returns the test case comment. + const char* comment() const { return comment_.c_str(); } + + // Returns true if any test in this test case should run. + bool should_run() const { return should_run_; } + + // Gets the number of successful tests in this test case. + int successful_test_count() const; + + // Gets the number of failed tests in this test case. + int failed_test_count() const; + + // Gets the number of disabled tests in this test case. + int disabled_test_count() const; + + // Get the number of tests in this test case that should run. + int test_to_run_count() const; + + // Gets the number of all tests in this test case. + int total_test_count() const; + + // Returns true iff the test case passed. + bool Passed() const { return !Failed(); } + + // Returns true iff the test case failed. + bool Failed() const { return failed_test_count() > 0; } + + // Returns the elapsed time, in milliseconds. + TimeInMillis elapsed_time() const { return elapsed_time_; } + + // Returns the i-th test among all the tests. i can range from 0 to + // total_test_count() - 1. If i is not in that range, returns NULL. + const TestInfo* GetTestInfo(int i) const; + + private: + friend class Test; + friend class internal::UnitTestImpl; + + // Gets the (mutable) vector of TestInfos in this TestCase. + std::vector<TestInfo*>& test_info_list() { return test_info_list_; } + + // Gets the (immutable) vector of TestInfos in this TestCase. + const std::vector<TestInfo*>& test_info_list() const { + return test_info_list_; + } + + // Returns the i-th test among all the tests. i can range from 0 to + // total_test_count() - 1. If i is not in that range, returns NULL. + TestInfo* GetMutableTestInfo(int i); + + // Sets the should_run member. + void set_should_run(bool should) { should_run_ = should; } + + // Adds a TestInfo to this test case. Will delete the TestInfo upon + // destruction of the TestCase object. + void AddTestInfo(TestInfo * test_info); + + // Clears the results of all tests in this test case. + void ClearResult(); + + // Clears the results of all tests in the given test case. + static void ClearTestCaseResult(TestCase* test_case) { + test_case->ClearResult(); + } + + // Runs every test in this TestCase. + void Run(); + + // Returns true iff test passed. + static bool TestPassed(const TestInfo * test_info); + + // Returns true iff test failed. + static bool TestFailed(const TestInfo * test_info); + + // Returns true iff test is disabled. + static bool TestDisabled(const TestInfo * test_info); + + // Returns true if the given test should run. + static bool ShouldRunTest(const TestInfo *test_info); + + // Shuffles the tests in this test case. + void ShuffleTests(internal::Random* random); + + // Restores the test order to before the first shuffle. + void UnshuffleTests(); + + // Name of the test case. + internal::String name_; + // Comment on the test case. + internal::String comment_; + // The vector of TestInfos in their original order. It owns the + // elements in the vector. + std::vector<TestInfo*> test_info_list_; + // Provides a level of indirection for the test list to allow easy + // shuffling and restoring the test order. The i-th element in this + // vector is the index of the i-th test in the shuffled test list. + std::vector<int> test_indices_; + // Pointer to the function that sets up the test case. + Test::SetUpTestCaseFunc set_up_tc_; + // Pointer to the function that tears down the test case. + Test::TearDownTestCaseFunc tear_down_tc_; + // True iff any test in this test case should run. + bool should_run_; + // Elapsed time, in milliseconds. + TimeInMillis elapsed_time_; + + // We disallow copying TestCases. + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestCase); +}; + +// An Environment object is capable of setting up and tearing down an +// environment. The user should subclass this to define his own +// environment(s). +// +// An Environment object does the set-up and tear-down in virtual +// methods SetUp() and TearDown() instead of the constructor and the +// destructor, as: +// +// 1. You cannot safely throw from a destructor. This is a problem +// as in some cases Google Test is used where exceptions are enabled, and +// we may want to implement ASSERT_* using exceptions where they are +// available. +// 2. You cannot use ASSERT_* directly in a constructor or +// destructor. +class Environment { + public: + // The d'tor is virtual as we need to subclass Environment. + virtual ~Environment() {} + + // Override this to define how to set up the environment. + virtual void SetUp() {} + + // Override this to define how to tear down the environment. + virtual void TearDown() {} + private: + // If you see an error about overriding the following function or + // about it being private, you have mis-spelled SetUp() as Setup(). + struct Setup_should_be_spelled_SetUp {}; + virtual Setup_should_be_spelled_SetUp* Setup() { return NULL; } +}; + +// The interface for tracing execution of tests. The methods are organized in +// the order the corresponding events are fired. +class TestEventListener { + public: + virtual ~TestEventListener() {} + + // Fired before any test activity starts. + virtual void OnTestProgramStart(const UnitTest& unit_test) = 0; + + // Fired before each iteration of tests starts. There may be more than + // one iteration if GTEST_FLAG(repeat) is set. iteration is the iteration + // index, starting from 0. + virtual void OnTestIterationStart(const UnitTest& unit_test, + int iteration) = 0; + + // Fired before environment set-up for each iteration of tests starts. + virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test) = 0; + + // Fired after environment set-up for each iteration of tests ends. + virtual void OnEnvironmentsSetUpEnd(const UnitTest& unit_test) = 0; + + // Fired before the test case starts. + virtual void OnTestCaseStart(const TestCase& test_case) = 0; + + // Fired before the test starts. + virtual void OnTestStart(const TestInfo& test_info) = 0; + + // Fired after a failed assertion or a SUCCESS(). + virtual void OnTestPartResult(const TestPartResult& test_part_result) = 0; + + // Fired after the test ends. + virtual void OnTestEnd(const TestInfo& test_info) = 0; + + // Fired after the test case ends. + virtual void OnTestCaseEnd(const TestCase& test_case) = 0; + + // Fired before environment tear-down for each iteration of tests starts. + virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test) = 0; + + // Fired after environment tear-down for each iteration of tests ends. + virtual void OnEnvironmentsTearDownEnd(const UnitTest& unit_test) = 0; + + // Fired after each iteration of tests finishes. + virtual void OnTestIterationEnd(const UnitTest& unit_test, + int iteration) = 0; + + // Fired after all test activities have ended. + virtual void OnTestProgramEnd(const UnitTest& unit_test) = 0; +}; + +// The convenience class for users who need to override just one or two +// methods and are not concerned that a possible change to a signature of +// the methods they override will not be caught during the build. For +// comments about each method please see the definition of TestEventListener +// above. +class EmptyTestEventListener : public TestEventListener { + public: + virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) {} + virtual void OnTestIterationStart(const UnitTest& /*unit_test*/, + int /*iteration*/) {} + virtual void OnEnvironmentsSetUpStart(const UnitTest& /*unit_test*/) {} + virtual void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) {} + virtual void OnTestCaseStart(const TestCase& /*test_case*/) {} + virtual void OnTestStart(const TestInfo& /*test_info*/) {} + virtual void OnTestPartResult(const TestPartResult& /*test_part_result*/) {} + virtual void OnTestEnd(const TestInfo& /*test_info*/) {} + virtual void OnTestCaseEnd(const TestCase& /*test_case*/) {} + virtual void OnEnvironmentsTearDownStart(const UnitTest& /*unit_test*/) {} + virtual void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) {} + virtual void OnTestIterationEnd(const UnitTest& /*unit_test*/, + int /*iteration*/) {} + virtual void OnTestProgramEnd(const UnitTest& /*unit_test*/) {} +}; + +// TestEventListeners lets users add listeners to track events in Google Test. +class GTEST_API_ TestEventListeners { + public: + TestEventListeners(); + ~TestEventListeners(); + + // Appends an event listener to the end of the list. Google Test assumes + // the ownership of the listener (i.e. it will delete the listener when + // the test program finishes). + void Append(TestEventListener* listener); + + // Removes the given event listener from the list and returns it. It then + // becomes the caller's responsibility to delete the listener. Returns + // NULL if the listener is not found in the list. + TestEventListener* Release(TestEventListener* listener); + + // Returns the standard listener responsible for the default console + // output. Can be removed from the listeners list to shut down default + // console output. Note that removing this object from the listener list + // with Release transfers its ownership to the caller and makes this + // function return NULL the next time. + TestEventListener* default_result_printer() const { + return default_result_printer_; + } + + // Returns the standard listener responsible for the default XML output + // controlled by the --gtest_output=xml flag. Can be removed from the + // listeners list by users who want to shut down the default XML output + // controlled by this flag and substitute it with custom one. Note that + // removing this object from the listener list with Release transfers its + // ownership to the caller and makes this function return NULL the next + // time. + TestEventListener* default_xml_generator() const { + return default_xml_generator_; + } + + private: + friend class TestCase; + friend class internal::DefaultGlobalTestPartResultReporter; + friend class internal::NoExecDeathTest; + friend class internal::TestEventListenersAccessor; + friend class internal::TestInfoImpl; + friend class internal::UnitTestImpl; + + // Returns repeater that broadcasts the TestEventListener events to all + // subscribers. + TestEventListener* repeater(); + + // Sets the default_result_printer attribute to the provided listener. + // The listener is also added to the listener list and previous + // default_result_printer is removed from it and deleted. The listener can + // also be NULL in which case it will not be added to the list. Does + // nothing if the previous and the current listener objects are the same. + void SetDefaultResultPrinter(TestEventListener* listener); + + // Sets the default_xml_generator attribute to the provided listener. The + // listener is also added to the listener list and previous + // default_xml_generator is removed from it and deleted. The listener can + // also be NULL in which case it will not be added to the list. Does + // nothing if the previous and the current listener objects are the same. + void SetDefaultXmlGenerator(TestEventListener* listener); + + // Controls whether events will be forwarded by the repeater to the + // listeners in the list. + bool EventForwardingEnabled() const; + void SuppressEventForwarding(); + + // The actual list of listeners. + internal::TestEventRepeater* repeater_; + // Listener responsible for the standard result output. + TestEventListener* default_result_printer_; + // Listener responsible for the creation of the XML output file. + TestEventListener* default_xml_generator_; + + // We disallow copying TestEventListeners. + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestEventListeners); +}; + +// A UnitTest consists of a vector of TestCases. +// +// This is a singleton class. The only instance of UnitTest is +// created when UnitTest::GetInstance() is first called. This +// instance is never deleted. +// +// UnitTest is not copyable. +// +// This class is thread-safe as long as the methods are called +// according to their specification. +class GTEST_API_ UnitTest { + public: + // Gets the singleton UnitTest object. The first time this method + // is called, a UnitTest object is constructed and returned. + // Consecutive calls will return the same object. + static UnitTest* GetInstance(); + + // Runs all tests in this UnitTest object and prints the result. + // Returns 0 if successful, or 1 otherwise. + // + // This method can only be called from the main thread. + // + // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. + int Run() GTEST_MUST_USE_RESULT_; + + // Returns the working directory when the first TEST() or TEST_F() + // was executed. The UnitTest object owns the string. + const char* original_working_dir() const; + + // Returns the TestCase object for the test that's currently running, + // or NULL if no test is running. + const TestCase* current_test_case() const; + + // Returns the TestInfo object for the test that's currently running, + // or NULL if no test is running. + const TestInfo* current_test_info() const; + + // Returns the random seed used at the start of the current test run. + int random_seed() const; + +#if GTEST_HAS_PARAM_TEST + // Returns the ParameterizedTestCaseRegistry object used to keep track of + // value-parameterized tests and instantiate and register them. + // + // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. + internal::ParameterizedTestCaseRegistry& parameterized_test_registry(); +#endif // GTEST_HAS_PARAM_TEST + + // Gets the number of successful test cases. + int successful_test_case_count() const; + + // Gets the number of failed test cases. + int failed_test_case_count() const; + + // Gets the number of all test cases. + int total_test_case_count() const; + + // Gets the number of all test cases that contain at least one test + // that should run. + int test_case_to_run_count() const; + + // Gets the number of successful tests. + int successful_test_count() const; + + // Gets the number of failed tests. + int failed_test_count() const; + + // Gets the number of disabled tests. + int disabled_test_count() const; + + // Gets the number of all tests. + int total_test_count() const; + + // Gets the number of tests that should run. + int test_to_run_count() const; + + // Gets the elapsed time, in milliseconds. + TimeInMillis elapsed_time() const; + + // Returns true iff the unit test passed (i.e. all test cases passed). + bool Passed() const; + + // Returns true iff the unit test failed (i.e. some test case failed + // or something outside of all tests failed). + bool Failed() const; + + // Gets the i-th test case among all the test cases. i can range from 0 to + // total_test_case_count() - 1. If i is not in that range, returns NULL. + const TestCase* GetTestCase(int i) const; + + // Returns the list of event listeners that can be used to track events + // inside Google Test. + TestEventListeners& listeners(); + + private: + // Registers and returns a global test environment. When a test + // program is run, all global test environments will be set-up in + // the order they were registered. After all tests in the program + // have finished, all global test environments will be torn-down in + // the *reverse* order they were registered. + // + // The UnitTest object takes ownership of the given environment. + // + // This method can only be called from the main thread. + Environment* AddEnvironment(Environment* env); + + // Adds a TestPartResult to the current TestResult object. All + // Google Test assertion macros (e.g. ASSERT_TRUE, EXPECT_EQ, etc) + // eventually call this to report their results. The user code + // should use the assertion macros instead of calling this directly. + void AddTestPartResult(TestPartResult::Type result_type, + const char* file_name, + int line_number, + const internal::String& message, + const internal::String& os_stack_trace); + + // Adds a TestProperty to the current TestResult object. If the result already + // contains a property with the same key, the value will be updated. + void RecordPropertyForCurrentTest(const char* key, const char* value); + + // Gets the i-th test case among all the test cases. i can range from 0 to + // total_test_case_count() - 1. If i is not in that range, returns NULL. + TestCase* GetMutableTestCase(int i); + + // Accessors for the implementation object. + internal::UnitTestImpl* impl() { return impl_; } + const internal::UnitTestImpl* impl() const { return impl_; } + + // These classes and funcions are friends as they need to access private + // members of UnitTest. + friend class Test; + friend class internal::AssertHelper; + friend class internal::ScopedTrace; + friend Environment* AddGlobalTestEnvironment(Environment* env); + friend internal::UnitTestImpl* internal::GetUnitTestImpl(); + friend void internal::ReportFailureInUnknownLocation( + TestPartResult::Type result_type, + const internal::String& message); + + // Creates an empty UnitTest. + UnitTest(); + + // D'tor + virtual ~UnitTest(); + + // Pushes a trace defined by SCOPED_TRACE() on to the per-thread + // Google Test trace stack. + void PushGTestTrace(const internal::TraceInfo& trace); + + // Pops a trace from the per-thread Google Test trace stack. + void PopGTestTrace(); + + // Protects mutable state in *impl_. This is mutable as some const + // methods need to lock it too. + mutable internal::Mutex mutex_; + + // Opaque implementation object. This field is never changed once + // the object is constructed. We don't mark it as const here, as + // doing so will cause a warning in the constructor of UnitTest. + // Mutable state in *impl_ is protected by mutex_. + internal::UnitTestImpl* impl_; + + // We disallow copying UnitTest. + GTEST_DISALLOW_COPY_AND_ASSIGN_(UnitTest); +}; + +// A convenient wrapper for adding an environment for the test +// program. +// +// You should call this before RUN_ALL_TESTS() is called, probably in +// main(). If you use gtest_main, you need to call this before main() +// starts for it to take effect. For example, you can define a global +// variable like this: +// +// testing::Environment* const foo_env = +// testing::AddGlobalTestEnvironment(new FooEnvironment); +// +// However, we strongly recommend you to write your own main() and +// call AddGlobalTestEnvironment() there, as relying on initialization +// of global variables makes the code harder to read and may cause +// problems when you register multiple environments from different +// translation units and the environments have dependencies among them +// (remember that the compiler doesn't guarantee the order in which +// global variables from different translation units are initialized). +inline Environment* AddGlobalTestEnvironment(Environment* env) { + return UnitTest::GetInstance()->AddEnvironment(env); +} + +// Initializes Google Test. This must be called before calling +// RUN_ALL_TESTS(). In particular, it parses a command line for the +// flags that Google Test recognizes. Whenever a Google Test flag is +// seen, it is removed from argv, and *argc is decremented. +// +// No value is returned. Instead, the Google Test flag variables are +// updated. +// +// Calling the function for the second time has no user-visible effect. +GTEST_API_ void InitGoogleTest(int* argc, char** argv); + +// This overloaded version can be used in Windows programs compiled in +// UNICODE mode. +GTEST_API_ void InitGoogleTest(int* argc, wchar_t** argv); + +namespace internal { + +// These overloaded versions handle ::std::string and ::std::wstring. +GTEST_API_ inline String FormatForFailureMessage(const ::std::string& str) { + return (Message() << '"' << str << '"').GetString(); +} + +#if GTEST_HAS_STD_WSTRING +GTEST_API_ inline String FormatForFailureMessage(const ::std::wstring& wstr) { + return (Message() << "L\"" << wstr << '"').GetString(); +} +#endif // GTEST_HAS_STD_WSTRING + +// These overloaded versions handle ::string and ::wstring. +#if GTEST_HAS_GLOBAL_STRING +GTEST_API_ inline String FormatForFailureMessage(const ::string& str) { + return (Message() << '"' << str << '"').GetString(); +} +#endif // GTEST_HAS_GLOBAL_STRING + +#if GTEST_HAS_GLOBAL_WSTRING +GTEST_API_ inline String FormatForFailureMessage(const ::wstring& wstr) { + return (Message() << "L\"" << wstr << '"').GetString(); +} +#endif // GTEST_HAS_GLOBAL_WSTRING + +// Formats a comparison assertion (e.g. ASSERT_EQ, EXPECT_LT, and etc) +// operand to be used in a failure message. The type (but not value) +// of the other operand may affect the format. This allows us to +// print a char* as a raw pointer when it is compared against another +// char*, and print it as a C string when it is compared against an +// std::string object, for example. +// +// The default implementation ignores the type of the other operand. +// Some specialized versions are used to handle formatting wide or +// narrow C strings. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +template <typename T1, typename T2> +String FormatForComparisonFailureMessage(const T1& value, + const T2& /* other_operand */) { + return FormatForFailureMessage(value); +} + +// The helper function for {ASSERT|EXPECT}_EQ. +template <typename T1, typename T2> +AssertionResult CmpHelperEQ(const char* expected_expression, + const char* actual_expression, + const T1& expected, + const T2& actual) { +#ifdef _MSC_VER +#pragma warning(push) // Saves the current warning state. +#pragma warning(disable:4389) // Temporarily disables warning on + // signed/unsigned mismatch. +#endif + + if (expected == actual) { + return AssertionSuccess(); + } + +#ifdef _MSC_VER +#pragma warning(pop) // Restores the warning state. +#endif + + return EqFailure(expected_expression, + actual_expression, + FormatForComparisonFailureMessage(expected, actual), + FormatForComparisonFailureMessage(actual, expected), + false); +} + +// With this overloaded version, we allow anonymous enums to be used +// in {ASSERT|EXPECT}_EQ when compiled with gcc 4, as anonymous enums +// can be implicitly cast to BiggestInt. +GTEST_API_ AssertionResult CmpHelperEQ(const char* expected_expression, + const char* actual_expression, + BiggestInt expected, + BiggestInt actual); + +// The helper class for {ASSERT|EXPECT}_EQ. The template argument +// lhs_is_null_literal is true iff the first argument to ASSERT_EQ() +// is a null pointer literal. The following default implementation is +// for lhs_is_null_literal being false. +template <bool lhs_is_null_literal> +class EqHelper { + public: + // This templatized version is for the general case. + template <typename T1, typename T2> + static AssertionResult Compare(const char* expected_expression, + const char* actual_expression, + const T1& expected, + const T2& actual) { + return CmpHelperEQ(expected_expression, actual_expression, expected, + actual); + } + + // With this overloaded version, we allow anonymous enums to be used + // in {ASSERT|EXPECT}_EQ when compiled with gcc 4, as anonymous + // enums can be implicitly cast to BiggestInt. + // + // Even though its body looks the same as the above version, we + // cannot merge the two, as it will make anonymous enums unhappy. + static AssertionResult Compare(const char* expected_expression, + const char* actual_expression, + BiggestInt expected, + BiggestInt actual) { + return CmpHelperEQ(expected_expression, actual_expression, expected, + actual); + } +}; + +// This specialization is used when the first argument to ASSERT_EQ() +// is a null pointer literal. +template <> +class EqHelper<true> { + public: + // We define two overloaded versions of Compare(). The first + // version will be picked when the second argument to ASSERT_EQ() is + // NOT a pointer, e.g. ASSERT_EQ(0, AnIntFunction()) or + // EXPECT_EQ(false, a_bool). + template <typename T1, typename T2> + static AssertionResult Compare(const char* expected_expression, + const char* actual_expression, + const T1& expected, + const T2& actual) { + return CmpHelperEQ(expected_expression, actual_expression, expected, + actual); + } + + // This version will be picked when the second argument to + // ASSERT_EQ() is a pointer, e.g. ASSERT_EQ(NULL, a_pointer). + template <typename T1, typename T2> + static AssertionResult Compare(const char* expected_expression, + const char* actual_expression, + const T1& /* expected */, + T2* actual) { + // We already know that 'expected' is a null pointer. + return CmpHelperEQ(expected_expression, actual_expression, + static_cast<T2*>(NULL), actual); + } +}; + +// A macro for implementing the helper functions needed to implement +// ASSERT_?? and EXPECT_??. It is here just to avoid copy-and-paste +// of similar code. +// +// For each templatized helper function, we also define an overloaded +// version for BiggestInt in order to reduce code bloat and allow +// anonymous enums to be used with {ASSERT|EXPECT}_?? when compiled +// with gcc 4. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +#define GTEST_IMPL_CMP_HELPER_(op_name, op)\ +template <typename T1, typename T2>\ +AssertionResult CmpHelper##op_name(const char* expr1, const char* expr2, \ + const T1& val1, const T2& val2) {\ + if (val1 op val2) {\ + return AssertionSuccess();\ + } else {\ + Message msg;\ + msg << "Expected: (" << expr1 << ") " #op " (" << expr2\ + << "), actual: " << FormatForComparisonFailureMessage(val1, val2)\ + << " vs " << FormatForComparisonFailureMessage(val2, val1);\ + return AssertionFailure(msg);\ + }\ +}\ +GTEST_API_ AssertionResult CmpHelper##op_name(\ + const char* expr1, const char* expr2, BiggestInt val1, BiggestInt val2) + +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. + +// Implements the helper function for {ASSERT|EXPECT}_NE +GTEST_IMPL_CMP_HELPER_(NE, !=); +// Implements the helper function for {ASSERT|EXPECT}_LE +GTEST_IMPL_CMP_HELPER_(LE, <=); +// Implements the helper function for {ASSERT|EXPECT}_LT +GTEST_IMPL_CMP_HELPER_(LT, < ); +// Implements the helper function for {ASSERT|EXPECT}_GE +GTEST_IMPL_CMP_HELPER_(GE, >=); +// Implements the helper function for {ASSERT|EXPECT}_GT +GTEST_IMPL_CMP_HELPER_(GT, > ); + +#undef GTEST_IMPL_CMP_HELPER_ + +// The helper function for {ASSERT|EXPECT}_STREQ. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +GTEST_API_ AssertionResult CmpHelperSTREQ(const char* expected_expression, + const char* actual_expression, + const char* expected, + const char* actual); + +// The helper function for {ASSERT|EXPECT}_STRCASEEQ. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +GTEST_API_ AssertionResult CmpHelperSTRCASEEQ(const char* expected_expression, + const char* actual_expression, + const char* expected, + const char* actual); + +// The helper function for {ASSERT|EXPECT}_STRNE. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +GTEST_API_ AssertionResult CmpHelperSTRNE(const char* s1_expression, + const char* s2_expression, + const char* s1, + const char* s2); + +// The helper function for {ASSERT|EXPECT}_STRCASENE. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +GTEST_API_ AssertionResult CmpHelperSTRCASENE(const char* s1_expression, + const char* s2_expression, + const char* s1, + const char* s2); + + +// Helper function for *_STREQ on wide strings. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +GTEST_API_ AssertionResult CmpHelperSTREQ(const char* expected_expression, + const char* actual_expression, + const wchar_t* expected, + const wchar_t* actual); + +// Helper function for *_STRNE on wide strings. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +GTEST_API_ AssertionResult CmpHelperSTRNE(const char* s1_expression, + const char* s2_expression, + const wchar_t* s1, + const wchar_t* s2); + +} // namespace internal + +// IsSubstring() and IsNotSubstring() are intended to be used as the +// first argument to {EXPECT,ASSERT}_PRED_FORMAT2(), not by +// themselves. They check whether needle is a substring of haystack +// (NULL is considered a substring of itself only), and return an +// appropriate error message when they fail. +// +// The {needle,haystack}_expr arguments are the stringified +// expressions that generated the two real arguments. +GTEST_API_ AssertionResult IsSubstring( + const char* needle_expr, const char* haystack_expr, + const char* needle, const char* haystack); +GTEST_API_ AssertionResult IsSubstring( + const char* needle_expr, const char* haystack_expr, + const wchar_t* needle, const wchar_t* haystack); +GTEST_API_ AssertionResult IsNotSubstring( + const char* needle_expr, const char* haystack_expr, + const char* needle, const char* haystack); +GTEST_API_ AssertionResult IsNotSubstring( + const char* needle_expr, const char* haystack_expr, + const wchar_t* needle, const wchar_t* haystack); +GTEST_API_ AssertionResult IsSubstring( + const char* needle_expr, const char* haystack_expr, + const ::std::string& needle, const ::std::string& haystack); +GTEST_API_ AssertionResult IsNotSubstring( + const char* needle_expr, const char* haystack_expr, + const ::std::string& needle, const ::std::string& haystack); + +#if GTEST_HAS_STD_WSTRING +GTEST_API_ AssertionResult IsSubstring( + const char* needle_expr, const char* haystack_expr, + const ::std::wstring& needle, const ::std::wstring& haystack); +GTEST_API_ AssertionResult IsNotSubstring( + const char* needle_expr, const char* haystack_expr, + const ::std::wstring& needle, const ::std::wstring& haystack); +#endif // GTEST_HAS_STD_WSTRING + +namespace internal { + +// Helper template function for comparing floating-points. +// +// Template parameter: +// +// RawType: the raw floating-point type (either float or double) +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +template <typename RawType> +AssertionResult CmpHelperFloatingPointEQ(const char* expected_expression, + const char* actual_expression, + RawType expected, + RawType actual) { + const FloatingPoint<RawType> lhs(expected), rhs(actual); + + if (lhs.AlmostEquals(rhs)) { + return AssertionSuccess(); + } + + StrStream expected_ss; + expected_ss << std::setprecision(std::numeric_limits<RawType>::digits10 + 2) + << expected; + + StrStream actual_ss; + actual_ss << std::setprecision(std::numeric_limits<RawType>::digits10 + 2) + << actual; + + return EqFailure(expected_expression, + actual_expression, + StrStreamToString(&expected_ss), + StrStreamToString(&actual_ss), + false); +} + +// Helper function for implementing ASSERT_NEAR. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +GTEST_API_ AssertionResult DoubleNearPredFormat(const char* expr1, + const char* expr2, + const char* abs_error_expr, + double val1, + double val2, + double abs_error); + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// A class that enables one to stream messages to assertion macros +class GTEST_API_ AssertHelper { + public: + // Constructor. + AssertHelper(TestPartResult::Type type, + const char* file, + int line, + const char* message); + ~AssertHelper(); + + // Message assignment is a semantic trick to enable assertion + // streaming; see the GTEST_MESSAGE_ macro below. + void operator=(const Message& message) const; + + private: + // We put our data in a struct so that the size of the AssertHelper class can + // be as small as possible. This is important because gcc is incapable of + // re-using stack space even for temporary variables, so every EXPECT_EQ + // reserves stack space for another AssertHelper. + struct AssertHelperData { + AssertHelperData(TestPartResult::Type t, + const char* srcfile, + int line_num, + const char* msg) + : type(t), file(srcfile), line(line_num), message(msg) { } + + TestPartResult::Type const type; + const char* const file; + int const line; + String const message; + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(AssertHelperData); + }; + + AssertHelperData* const data_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(AssertHelper); +}; + +} // namespace internal + +#if GTEST_HAS_PARAM_TEST +// The abstract base class that all value-parameterized tests inherit from. +// +// This class adds support for accessing the test parameter value via +// the GetParam() method. +// +// Use it with one of the parameter generator defining functions, like Range(), +// Values(), ValuesIn(), Bool(), and Combine(). +// +// class FooTest : public ::testing::TestWithParam<int> { +// protected: +// FooTest() { +// // Can use GetParam() here. +// } +// virtual ~FooTest() { +// // Can use GetParam() here. +// } +// virtual void SetUp() { +// // Can use GetParam() here. +// } +// virtual void TearDown { +// // Can use GetParam() here. +// } +// }; +// TEST_P(FooTest, DoesBar) { +// // Can use GetParam() method here. +// Foo foo; +// ASSERT_TRUE(foo.DoesBar(GetParam())); +// } +// INSTANTIATE_TEST_CASE_P(OneToTenRange, FooTest, ::testing::Range(1, 10)); + +template <typename T> +class TestWithParam : public Test { + public: + typedef T ParamType; + + // The current parameter value. Is also available in the test fixture's + // constructor. + const ParamType& GetParam() const { return *parameter_; } + + private: + // Sets parameter value. The caller is responsible for making sure the value + // remains alive and unchanged throughout the current test. + static void SetParam(const ParamType* parameter) { + parameter_ = parameter; + } + + // Static value used for accessing parameter during a test lifetime. + static const ParamType* parameter_; + + // TestClass must be a subclass of TestWithParam<T>. + template <class TestClass> friend class internal::ParameterizedTestFactory; +}; + +template <typename T> +const T* TestWithParam<T>::parameter_ = NULL; + +#endif // GTEST_HAS_PARAM_TEST + +// Macros for indicating success/failure in test code. + +// ADD_FAILURE unconditionally adds a failure to the current test. +// SUCCEED generates a success - it doesn't automatically make the +// current test successful, as a test is only successful when it has +// no failure. +// +// EXPECT_* verifies that a certain condition is satisfied. If not, +// it behaves like ADD_FAILURE. In particular: +// +// EXPECT_TRUE verifies that a Boolean condition is true. +// EXPECT_FALSE verifies that a Boolean condition is false. +// +// FAIL and ASSERT_* are similar to ADD_FAILURE and EXPECT_*, except +// that they will also abort the current function on failure. People +// usually want the fail-fast behavior of FAIL and ASSERT_*, but those +// writing data-driven tests often find themselves using ADD_FAILURE +// and EXPECT_* more. +// +// Examples: +// +// EXPECT_TRUE(server.StatusIsOK()); +// ASSERT_FALSE(server.HasPendingRequest(port)) +// << "There are still pending requests " << "on port " << port; + +// Generates a nonfatal failure with a generic message. +#define ADD_FAILURE() GTEST_NONFATAL_FAILURE_("Failed") + +// Generates a fatal failure with a generic message. +#define GTEST_FAIL() GTEST_FATAL_FAILURE_("Failed") + +// Define this macro to 1 to omit the definition of FAIL(), which is a +// generic name and clashes with some other libraries. +#if !GTEST_DONT_DEFINE_FAIL +#define FAIL() GTEST_FAIL() +#endif + +// Generates a success with a generic message. +#define GTEST_SUCCEED() GTEST_SUCCESS_("Succeeded") + +// Define this macro to 1 to omit the definition of SUCCEED(), which +// is a generic name and clashes with some other libraries. +#if !GTEST_DONT_DEFINE_SUCCEED +#define SUCCEED() GTEST_SUCCEED() +#endif + +// Macros for testing exceptions. +// +// * {ASSERT|EXPECT}_THROW(statement, expected_exception): +// Tests that the statement throws the expected exception. +// * {ASSERT|EXPECT}_NO_THROW(statement): +// Tests that the statement doesn't throw any exception. +// * {ASSERT|EXPECT}_ANY_THROW(statement): +// Tests that the statement throws an exception. + +#define EXPECT_THROW(statement, expected_exception) \ + GTEST_TEST_THROW_(statement, expected_exception, GTEST_NONFATAL_FAILURE_) +#define EXPECT_NO_THROW(statement) \ + GTEST_TEST_NO_THROW_(statement, GTEST_NONFATAL_FAILURE_) +#define EXPECT_ANY_THROW(statement) \ + GTEST_TEST_ANY_THROW_(statement, GTEST_NONFATAL_FAILURE_) +#define ASSERT_THROW(statement, expected_exception) \ + GTEST_TEST_THROW_(statement, expected_exception, GTEST_FATAL_FAILURE_) +#define ASSERT_NO_THROW(statement) \ + GTEST_TEST_NO_THROW_(statement, GTEST_FATAL_FAILURE_) +#define ASSERT_ANY_THROW(statement) \ + GTEST_TEST_ANY_THROW_(statement, GTEST_FATAL_FAILURE_) + +// Boolean assertions. Condition can be either a Boolean expression or an +// AssertionResult. For more information on how to use AssertionResult with +// these macros see comments on that class. +#define EXPECT_TRUE(condition) \ + GTEST_TEST_BOOLEAN_(condition, #condition, false, true, \ + GTEST_NONFATAL_FAILURE_) +#define EXPECT_FALSE(condition) \ + GTEST_TEST_BOOLEAN_(!(condition), #condition, true, false, \ + GTEST_NONFATAL_FAILURE_) +#define ASSERT_TRUE(condition) \ + GTEST_TEST_BOOLEAN_(condition, #condition, false, true, \ + GTEST_FATAL_FAILURE_) +#define ASSERT_FALSE(condition) \ + GTEST_TEST_BOOLEAN_(!(condition), #condition, true, false, \ + GTEST_FATAL_FAILURE_) + +// Includes the auto-generated header that implements a family of +// generic predicate assertion macros. +// Copyright 2006, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// This file is AUTOMATICALLY GENERATED on 10/02/2008 by command +// 'gen_gtest_pred_impl.py 5'. DO NOT EDIT BY HAND! +// +// Implements a family of generic predicate assertion macros. + +#ifndef GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ +#define GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ + +// Makes sure this header is not included before gtest.h. +#ifndef GTEST_INCLUDE_GTEST_GTEST_H_ +#error Do not include gtest_pred_impl.h directly. Include gtest.h instead. +#endif // GTEST_INCLUDE_GTEST_GTEST_H_ + +// This header implements a family of generic predicate assertion +// macros: +// +// ASSERT_PRED_FORMAT1(pred_format, v1) +// ASSERT_PRED_FORMAT2(pred_format, v1, v2) +// ... +// +// where pred_format is a function or functor that takes n (in the +// case of ASSERT_PRED_FORMATn) values and their source expression +// text, and returns a testing::AssertionResult. See the definition +// of ASSERT_EQ in gtest.h for an example. +// +// If you don't care about formatting, you can use the more +// restrictive version: +// +// ASSERT_PRED1(pred, v1) +// ASSERT_PRED2(pred, v1, v2) +// ... +// +// where pred is an n-ary function or functor that returns bool, +// and the values v1, v2, ..., must support the << operator for +// streaming to std::ostream. +// +// We also define the EXPECT_* variations. +// +// For now we only support predicates whose arity is at most 5. +// Please email googletestframework@googlegroups.com if you need +// support for higher arities. + +// GTEST_ASSERT_ is the basic statement to which all of the assertions +// in this file reduce. Don't use this in your code. + +#define GTEST_ASSERT_(expression, on_failure) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (const ::testing::AssertionResult gtest_ar = (expression)) \ + ; \ + else \ + on_failure(gtest_ar.failure_message()) + + +// Helper function for implementing {EXPECT|ASSERT}_PRED1. Don't use +// this in your code. +template <typename Pred, + typename T1> +AssertionResult AssertPred1Helper(const char* pred_text, + const char* e1, + Pred pred, + const T1& v1) { + if (pred(v1)) return AssertionSuccess(); + + Message msg; + msg << pred_text << "(" + << e1 << ") evaluates to false, where" + << "\n" << e1 << " evaluates to " << v1; + return AssertionFailure(msg); +} + +// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT1. +// Don't use this in your code. +#define GTEST_PRED_FORMAT1_(pred_format, v1, on_failure)\ + GTEST_ASSERT_(pred_format(#v1, v1),\ + on_failure) + +// Internal macro for implementing {EXPECT|ASSERT}_PRED1. Don't use +// this in your code. +#define GTEST_PRED1_(pred, v1, on_failure)\ + GTEST_ASSERT_(::testing::AssertPred1Helper(#pred, \ + #v1, \ + pred, \ + v1), on_failure) + +// Unary predicate assertion macros. +#define EXPECT_PRED_FORMAT1(pred_format, v1) \ + GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_NONFATAL_FAILURE_) +#define EXPECT_PRED1(pred, v1) \ + GTEST_PRED1_(pred, v1, GTEST_NONFATAL_FAILURE_) +#define ASSERT_PRED_FORMAT1(pred_format, v1) \ + GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_FATAL_FAILURE_) +#define ASSERT_PRED1(pred, v1) \ + GTEST_PRED1_(pred, v1, GTEST_FATAL_FAILURE_) + + + +// Helper function for implementing {EXPECT|ASSERT}_PRED2. Don't use +// this in your code. +template <typename Pred, + typename T1, + typename T2> +AssertionResult AssertPred2Helper(const char* pred_text, + const char* e1, + const char* e2, + Pred pred, + const T1& v1, + const T2& v2) { + if (pred(v1, v2)) return AssertionSuccess(); + + Message msg; + msg << pred_text << "(" + << e1 << ", " + << e2 << ") evaluates to false, where" + << "\n" << e1 << " evaluates to " << v1 + << "\n" << e2 << " evaluates to " << v2; + return AssertionFailure(msg); +} + +// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT2. +// Don't use this in your code. +#define GTEST_PRED_FORMAT2_(pred_format, v1, v2, on_failure)\ + GTEST_ASSERT_(pred_format(#v1, #v2, v1, v2),\ + on_failure) + +// Internal macro for implementing {EXPECT|ASSERT}_PRED2. Don't use +// this in your code. +#define GTEST_PRED2_(pred, v1, v2, on_failure)\ + GTEST_ASSERT_(::testing::AssertPred2Helper(#pred, \ + #v1, \ + #v2, \ + pred, \ + v1, \ + v2), on_failure) + +// Binary predicate assertion macros. +#define EXPECT_PRED_FORMAT2(pred_format, v1, v2) \ + GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_NONFATAL_FAILURE_) +#define EXPECT_PRED2(pred, v1, v2) \ + GTEST_PRED2_(pred, v1, v2, GTEST_NONFATAL_FAILURE_) +#define ASSERT_PRED_FORMAT2(pred_format, v1, v2) \ + GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_FATAL_FAILURE_) +#define ASSERT_PRED2(pred, v1, v2) \ + GTEST_PRED2_(pred, v1, v2, GTEST_FATAL_FAILURE_) + + + +// Helper function for implementing {EXPECT|ASSERT}_PRED3. Don't use +// this in your code. +template <typename Pred, + typename T1, + typename T2, + typename T3> +AssertionResult AssertPred3Helper(const char* pred_text, + const char* e1, + const char* e2, + const char* e3, + Pred pred, + const T1& v1, + const T2& v2, + const T3& v3) { + if (pred(v1, v2, v3)) return AssertionSuccess(); + + Message msg; + msg << pred_text << "(" + << e1 << ", " + << e2 << ", " + << e3 << ") evaluates to false, where" + << "\n" << e1 << " evaluates to " << v1 + << "\n" << e2 << " evaluates to " << v2 + << "\n" << e3 << " evaluates to " << v3; + return AssertionFailure(msg); +} + +// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT3. +// Don't use this in your code. +#define GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, on_failure)\ + GTEST_ASSERT_(pred_format(#v1, #v2, #v3, v1, v2, v3),\ + on_failure) + +// Internal macro for implementing {EXPECT|ASSERT}_PRED3. Don't use +// this in your code. +#define GTEST_PRED3_(pred, v1, v2, v3, on_failure)\ + GTEST_ASSERT_(::testing::AssertPred3Helper(#pred, \ + #v1, \ + #v2, \ + #v3, \ + pred, \ + v1, \ + v2, \ + v3), on_failure) + +// Ternary predicate assertion macros. +#define EXPECT_PRED_FORMAT3(pred_format, v1, v2, v3) \ + GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, GTEST_NONFATAL_FAILURE_) +#define EXPECT_PRED3(pred, v1, v2, v3) \ + GTEST_PRED3_(pred, v1, v2, v3, GTEST_NONFATAL_FAILURE_) +#define ASSERT_PRED_FORMAT3(pred_format, v1, v2, v3) \ + GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, GTEST_FATAL_FAILURE_) +#define ASSERT_PRED3(pred, v1, v2, v3) \ + GTEST_PRED3_(pred, v1, v2, v3, GTEST_FATAL_FAILURE_) + + + +// Helper function for implementing {EXPECT|ASSERT}_PRED4. Don't use +// this in your code. +template <typename Pred, + typename T1, + typename T2, + typename T3, + typename T4> +AssertionResult AssertPred4Helper(const char* pred_text, + const char* e1, + const char* e2, + const char* e3, + const char* e4, + Pred pred, + const T1& v1, + const T2& v2, + const T3& v3, + const T4& v4) { + if (pred(v1, v2, v3, v4)) return AssertionSuccess(); + + Message msg; + msg << pred_text << "(" + << e1 << ", " + << e2 << ", " + << e3 << ", " + << e4 << ") evaluates to false, where" + << "\n" << e1 << " evaluates to " << v1 + << "\n" << e2 << " evaluates to " << v2 + << "\n" << e3 << " evaluates to " << v3 + << "\n" << e4 << " evaluates to " << v4; + return AssertionFailure(msg); +} + +// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT4. +// Don't use this in your code. +#define GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, on_failure)\ + GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, v1, v2, v3, v4),\ + on_failure) + +// Internal macro for implementing {EXPECT|ASSERT}_PRED4. Don't use +// this in your code. +#define GTEST_PRED4_(pred, v1, v2, v3, v4, on_failure)\ + GTEST_ASSERT_(::testing::AssertPred4Helper(#pred, \ + #v1, \ + #v2, \ + #v3, \ + #v4, \ + pred, \ + v1, \ + v2, \ + v3, \ + v4), on_failure) + +// 4-ary predicate assertion macros. +#define EXPECT_PRED_FORMAT4(pred_format, v1, v2, v3, v4) \ + GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, GTEST_NONFATAL_FAILURE_) +#define EXPECT_PRED4(pred, v1, v2, v3, v4) \ + GTEST_PRED4_(pred, v1, v2, v3, v4, GTEST_NONFATAL_FAILURE_) +#define ASSERT_PRED_FORMAT4(pred_format, v1, v2, v3, v4) \ + GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, GTEST_FATAL_FAILURE_) +#define ASSERT_PRED4(pred, v1, v2, v3, v4) \ + GTEST_PRED4_(pred, v1, v2, v3, v4, GTEST_FATAL_FAILURE_) + + + +// Helper function for implementing {EXPECT|ASSERT}_PRED5. Don't use +// this in your code. +template <typename Pred, + typename T1, + typename T2, + typename T3, + typename T4, + typename T5> +AssertionResult AssertPred5Helper(const char* pred_text, + const char* e1, + const char* e2, + const char* e3, + const char* e4, + const char* e5, + Pred pred, + const T1& v1, + const T2& v2, + const T3& v3, + const T4& v4, + const T5& v5) { + if (pred(v1, v2, v3, v4, v5)) return AssertionSuccess(); + + Message msg; + msg << pred_text << "(" + << e1 << ", " + << e2 << ", " + << e3 << ", " + << e4 << ", " + << e5 << ") evaluates to false, where" + << "\n" << e1 << " evaluates to " << v1 + << "\n" << e2 << " evaluates to " << v2 + << "\n" << e3 << " evaluates to " << v3 + << "\n" << e4 << " evaluates to " << v4 + << "\n" << e5 << " evaluates to " << v5; + return AssertionFailure(msg); +} + +// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT5. +// Don't use this in your code. +#define GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, on_failure)\ + GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, #v5, v1, v2, v3, v4, v5),\ + on_failure) + +// Internal macro for implementing {EXPECT|ASSERT}_PRED5. Don't use +// this in your code. +#define GTEST_PRED5_(pred, v1, v2, v3, v4, v5, on_failure)\ + GTEST_ASSERT_(::testing::AssertPred5Helper(#pred, \ + #v1, \ + #v2, \ + #v3, \ + #v4, \ + #v5, \ + pred, \ + v1, \ + v2, \ + v3, \ + v4, \ + v5), on_failure) + +// 5-ary predicate assertion macros. +#define EXPECT_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5) \ + GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, GTEST_NONFATAL_FAILURE_) +#define EXPECT_PRED5(pred, v1, v2, v3, v4, v5) \ + GTEST_PRED5_(pred, v1, v2, v3, v4, v5, GTEST_NONFATAL_FAILURE_) +#define ASSERT_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5) \ + GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, GTEST_FATAL_FAILURE_) +#define ASSERT_PRED5(pred, v1, v2, v3, v4, v5) \ + GTEST_PRED5_(pred, v1, v2, v3, v4, v5, GTEST_FATAL_FAILURE_) + + + +#endif // GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ + +// Macros for testing equalities and inequalities. +// +// * {ASSERT|EXPECT}_EQ(expected, actual): Tests that expected == actual +// * {ASSERT|EXPECT}_NE(v1, v2): Tests that v1 != v2 +// * {ASSERT|EXPECT}_LT(v1, v2): Tests that v1 < v2 +// * {ASSERT|EXPECT}_LE(v1, v2): Tests that v1 <= v2 +// * {ASSERT|EXPECT}_GT(v1, v2): Tests that v1 > v2 +// * {ASSERT|EXPECT}_GE(v1, v2): Tests that v1 >= v2 +// +// When they are not, Google Test prints both the tested expressions and +// their actual values. The values must be compatible built-in types, +// or you will get a compiler error. By "compatible" we mean that the +// values can be compared by the respective operator. +// +// Note: +// +// 1. It is possible to make a user-defined type work with +// {ASSERT|EXPECT}_??(), but that requires overloading the +// comparison operators and is thus discouraged by the Google C++ +// Usage Guide. Therefore, you are advised to use the +// {ASSERT|EXPECT}_TRUE() macro to assert that two objects are +// equal. +// +// 2. The {ASSERT|EXPECT}_??() macros do pointer comparisons on +// pointers (in particular, C strings). Therefore, if you use it +// with two C strings, you are testing how their locations in memory +// are related, not how their content is related. To compare two C +// strings by content, use {ASSERT|EXPECT}_STR*(). +// +// 3. {ASSERT|EXPECT}_EQ(expected, actual) is preferred to +// {ASSERT|EXPECT}_TRUE(expected == actual), as the former tells you +// what the actual value is when it fails, and similarly for the +// other comparisons. +// +// 4. Do not depend on the order in which {ASSERT|EXPECT}_??() +// evaluate their arguments, which is undefined. +// +// 5. These macros evaluate their arguments exactly once. +// +// Examples: +// +// EXPECT_NE(5, Foo()); +// EXPECT_EQ(NULL, a_pointer); +// ASSERT_LT(i, array_size); +// ASSERT_GT(records.size(), 0) << "There is no record left."; + +#define EXPECT_EQ(expected, actual) \ + EXPECT_PRED_FORMAT2(::testing::internal:: \ + EqHelper<GTEST_IS_NULL_LITERAL_(expected)>::Compare, \ + expected, actual) +#define EXPECT_NE(expected, actual) \ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperNE, expected, actual) +#define EXPECT_LE(val1, val2) \ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperLE, val1, val2) +#define EXPECT_LT(val1, val2) \ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperLT, val1, val2) +#define EXPECT_GE(val1, val2) \ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperGE, val1, val2) +#define EXPECT_GT(val1, val2) \ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperGT, val1, val2) + +#define ASSERT_EQ(expected, actual) \ + ASSERT_PRED_FORMAT2(::testing::internal:: \ + EqHelper<GTEST_IS_NULL_LITERAL_(expected)>::Compare, \ + expected, actual) +#define ASSERT_NE(val1, val2) \ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperNE, val1, val2) +#define ASSERT_LE(val1, val2) \ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperLE, val1, val2) +#define ASSERT_LT(val1, val2) \ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperLT, val1, val2) +#define ASSERT_GE(val1, val2) \ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperGE, val1, val2) +#define ASSERT_GT(val1, val2) \ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperGT, val1, val2) + +// C String Comparisons. All tests treat NULL and any non-NULL string +// as different. Two NULLs are equal. +// +// * {ASSERT|EXPECT}_STREQ(s1, s2): Tests that s1 == s2 +// * {ASSERT|EXPECT}_STRNE(s1, s2): Tests that s1 != s2 +// * {ASSERT|EXPECT}_STRCASEEQ(s1, s2): Tests that s1 == s2, ignoring case +// * {ASSERT|EXPECT}_STRCASENE(s1, s2): Tests that s1 != s2, ignoring case +// +// For wide or narrow string objects, you can use the +// {ASSERT|EXPECT}_??() macros. +// +// Don't depend on the order in which the arguments are evaluated, +// which is undefined. +// +// These macros evaluate their arguments exactly once. + +#define EXPECT_STREQ(expected, actual) \ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTREQ, expected, actual) +#define EXPECT_STRNE(s1, s2) \ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRNE, s1, s2) +#define EXPECT_STRCASEEQ(expected, actual) \ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASEEQ, expected, actual) +#define EXPECT_STRCASENE(s1, s2)\ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASENE, s1, s2) + +#define ASSERT_STREQ(expected, actual) \ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTREQ, expected, actual) +#define ASSERT_STRNE(s1, s2) \ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRNE, s1, s2) +#define ASSERT_STRCASEEQ(expected, actual) \ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASEEQ, expected, actual) +#define ASSERT_STRCASENE(s1, s2)\ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASENE, s1, s2) + +// Macros for comparing floating-point numbers. +// +// * {ASSERT|EXPECT}_FLOAT_EQ(expected, actual): +// Tests that two float values are almost equal. +// * {ASSERT|EXPECT}_DOUBLE_EQ(expected, actual): +// Tests that two double values are almost equal. +// * {ASSERT|EXPECT}_NEAR(v1, v2, abs_error): +// Tests that v1 and v2 are within the given distance to each other. +// +// Google Test uses ULP-based comparison to automatically pick a default +// error bound that is appropriate for the operands. See the +// FloatingPoint template class in gtest-internal.h if you are +// interested in the implementation details. + +#define EXPECT_FLOAT_EQ(expected, actual)\ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ<float>, \ + expected, actual) + +#define EXPECT_DOUBLE_EQ(expected, actual)\ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ<double>, \ + expected, actual) + +#define ASSERT_FLOAT_EQ(expected, actual)\ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ<float>, \ + expected, actual) + +#define ASSERT_DOUBLE_EQ(expected, actual)\ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ<double>, \ + expected, actual) + +#define EXPECT_NEAR(val1, val2, abs_error)\ + EXPECT_PRED_FORMAT3(::testing::internal::DoubleNearPredFormat, \ + val1, val2, abs_error) + +#define ASSERT_NEAR(val1, val2, abs_error)\ + ASSERT_PRED_FORMAT3(::testing::internal::DoubleNearPredFormat, \ + val1, val2, abs_error) + +// These predicate format functions work on floating-point values, and +// can be used in {ASSERT|EXPECT}_PRED_FORMAT2*(), e.g. +// +// EXPECT_PRED_FORMAT2(testing::DoubleLE, Foo(), 5.0); + +// Asserts that val1 is less than, or almost equal to, val2. Fails +// otherwise. In particular, it fails if either val1 or val2 is NaN. +GTEST_API_ AssertionResult FloatLE(const char* expr1, const char* expr2, + float val1, float val2); +GTEST_API_ AssertionResult DoubleLE(const char* expr1, const char* expr2, + double val1, double val2); + + +#if GTEST_OS_WINDOWS + +// Macros that test for HRESULT failure and success, these are only useful +// on Windows, and rely on Windows SDK macros and APIs to compile. +// +// * {ASSERT|EXPECT}_HRESULT_{SUCCEEDED|FAILED}(expr) +// +// When expr unexpectedly fails or succeeds, Google Test prints the +// expected result and the actual result with both a human-readable +// string representation of the error, if available, as well as the +// hex result code. +#define EXPECT_HRESULT_SUCCEEDED(expr) \ + EXPECT_PRED_FORMAT1(::testing::internal::IsHRESULTSuccess, (expr)) + +#define ASSERT_HRESULT_SUCCEEDED(expr) \ + ASSERT_PRED_FORMAT1(::testing::internal::IsHRESULTSuccess, (expr)) + +#define EXPECT_HRESULT_FAILED(expr) \ + EXPECT_PRED_FORMAT1(::testing::internal::IsHRESULTFailure, (expr)) + +#define ASSERT_HRESULT_FAILED(expr) \ + ASSERT_PRED_FORMAT1(::testing::internal::IsHRESULTFailure, (expr)) + +#endif // GTEST_OS_WINDOWS + +// Macros that execute statement and check that it doesn't generate new fatal +// failures in the current thread. +// +// * {ASSERT|EXPECT}_NO_FATAL_FAILURE(statement); +// +// Examples: +// +// EXPECT_NO_FATAL_FAILURE(Process()); +// ASSERT_NO_FATAL_FAILURE(Process()) << "Process() failed"; +// +#define ASSERT_NO_FATAL_FAILURE(statement) \ + GTEST_TEST_NO_FATAL_FAILURE_(statement, GTEST_FATAL_FAILURE_) +#define EXPECT_NO_FATAL_FAILURE(statement) \ + GTEST_TEST_NO_FATAL_FAILURE_(statement, GTEST_NONFATAL_FAILURE_) + +// Causes a trace (including the source file path, the current line +// number, and the given message) to be included in every test failure +// message generated by code in the current scope. The effect is +// undone when the control leaves the current scope. +// +// The message argument can be anything streamable to std::ostream. +// +// In the implementation, we include the current line number as part +// of the dummy variable name, thus allowing multiple SCOPED_TRACE()s +// to appear in the same block - as long as they are on different +// lines. +#define SCOPED_TRACE(message) \ + ::testing::internal::ScopedTrace GTEST_CONCAT_TOKEN_(gtest_trace_, __LINE__)(\ + __FILE__, __LINE__, ::testing::Message() << (message)) + +namespace internal { + +// This template is declared, but intentionally undefined. +template <typename T1, typename T2> +struct StaticAssertTypeEqHelper; + +template <typename T> +struct StaticAssertTypeEqHelper<T, T> {}; + +} // namespace internal + +// Compile-time assertion for type equality. +// StaticAssertTypeEq<type1, type2>() compiles iff type1 and type2 are +// the same type. The value it returns is not interesting. +// +// Instead of making StaticAssertTypeEq a class template, we make it a +// function template that invokes a helper class template. This +// prevents a user from misusing StaticAssertTypeEq<T1, T2> by +// defining objects of that type. +// +// CAVEAT: +// +// When used inside a method of a class template, +// StaticAssertTypeEq<T1, T2>() is effective ONLY IF the method is +// instantiated. For example, given: +// +// template <typename T> class Foo { +// public: +// void Bar() { testing::StaticAssertTypeEq<int, T>(); } +// }; +// +// the code: +// +// void Test1() { Foo<bool> foo; } +// +// will NOT generate a compiler error, as Foo<bool>::Bar() is never +// actually instantiated. Instead, you need: +// +// void Test2() { Foo<bool> foo; foo.Bar(); } +// +// to cause a compiler error. +template <typename T1, typename T2> +bool StaticAssertTypeEq() { + internal::StaticAssertTypeEqHelper<T1, T2>(); + return true; +} + +// Defines a test. +// +// The first parameter is the name of the test case, and the second +// parameter is the name of the test within the test case. +// +// The convention is to end the test case name with "Test". For +// example, a test case for the Foo class can be named FooTest. +// +// The user should put his test code between braces after using this +// macro. Example: +// +// TEST(FooTest, InitializesCorrectly) { +// Foo foo; +// EXPECT_TRUE(foo.StatusIsOK()); +// } + +// Note that we call GetTestTypeId() instead of GetTypeId< +// ::testing::Test>() here to get the type ID of testing::Test. This +// is to work around a suspected linker bug when using Google Test as +// a framework on Mac OS X. The bug causes GetTypeId< +// ::testing::Test>() to return different values depending on whether +// the call is from the Google Test framework itself or from user test +// code. GetTestTypeId() is guaranteed to always return the same +// value, as it always calls GetTypeId<>() from the Google Test +// framework. +#define GTEST_TEST(test_case_name, test_name)\ + GTEST_TEST_(test_case_name, test_name, \ + ::testing::Test, ::testing::internal::GetTestTypeId()) + +// Define this macro to 1 to omit the definition of TEST(), which +// is a generic name and clashes with some other libraries. +#if !GTEST_DONT_DEFINE_TEST +#define TEST(test_case_name, test_name) GTEST_TEST(test_case_name, test_name) +#endif + +// Defines a test that uses a test fixture. +// +// The first parameter is the name of the test fixture class, which +// also doubles as the test case name. The second parameter is the +// name of the test within the test case. +// +// A test fixture class must be declared earlier. The user should put +// his test code between braces after using this macro. Example: +// +// class FooTest : public testing::Test { +// protected: +// virtual void SetUp() { b_.AddElement(3); } +// +// Foo a_; +// Foo b_; +// }; +// +// TEST_F(FooTest, InitializesCorrectly) { +// EXPECT_TRUE(a_.StatusIsOK()); +// } +// +// TEST_F(FooTest, ReturnsElementCountCorrectly) { +// EXPECT_EQ(0, a_.size()); +// EXPECT_EQ(1, b_.size()); +// } + +#define TEST_F(test_fixture, test_name)\ + GTEST_TEST_(test_fixture, test_name, test_fixture, \ + ::testing::internal::GetTypeId<test_fixture>()) + +// Use this macro in main() to run all tests. It returns 0 if all +// tests are successful, or 1 otherwise. +// +// RUN_ALL_TESTS() should be invoked after the command line has been +// parsed by InitGoogleTest(). + +#define RUN_ALL_TESTS()\ + (::testing::UnitTest::GetInstance()->Run()) + +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_GTEST_H_ diff --git a/Fwk/AppFwk/cafViewer/CMakeLists.txt b/Fwk/AppFwk/cafViewer/CMakeLists.txt index 74f616361f..09960ee2ee 100644 --- a/Fwk/AppFwk/cafViewer/CMakeLists.txt +++ b/Fwk/AppFwk/cafViewer/CMakeLists.txt @@ -2,7 +2,17 @@ cmake_minimum_required (VERSION 2.8) project (cafViewer) +# Qt +find_package ( Qt4 COMPONENTS QtCore QtGui QtMain ) +include (${QT_USE_FILE}) + include_directories( + ${LibCore_SOURCE_DIR} + ${LibGeometry_SOURCE_DIR} + ${LibViewing_SOURCE_DIR} + ${LibRender_SOURCE_DIR} + ${LibGuiQt_SOURCE_DIR} + ${cafAnimControl_SOURCE_DIR} ) diff --git a/Fwk/AppFwk/cafViewer/cafCadNavigation.cpp b/Fwk/AppFwk/cafViewer/cafCadNavigation.cpp index f31032b0ec..92d557eb55 100644 --- a/Fwk/AppFwk/cafViewer/cafCadNavigation.cpp +++ b/Fwk/AppFwk/cafViewer/cafCadNavigation.cpp @@ -137,7 +137,7 @@ bool caf::CadNavigation::handleInputEvent(QInputEvent* inputEvent) bool needRedraw = m_trackball->updateNavigation(translatedMousePosX, translatedMousePosY); if (needRedraw) { - m_viewer->update(); + m_viewer->navigationPolicyUpdate(); } isEventHandled = true; } @@ -172,7 +172,7 @@ bool caf::CadNavigation::handleInputEvent(QInputEvent* inputEvent) cvf::Vec3d newVrp = vrp + trans; m_viewer->mainCamera()->setFromLookAt(newPos,newVrp, up ); - m_viewer->update(); + m_viewer->navigationPolicyUpdate(); } } isEventHandled = true; diff --git a/Fwk/AppFwk/cafViewer/cafCeetronNavigation.cpp b/Fwk/AppFwk/cafViewer/cafCeetronNavigation.cpp index 8202ac2432..a45b58d460 100644 --- a/Fwk/AppFwk/cafViewer/cafCeetronNavigation.cpp +++ b/Fwk/AppFwk/cafViewer/cafCeetronNavigation.cpp @@ -140,7 +140,7 @@ void caf::CeetronNavigation::mouseMoveEvent(QMouseEvent* event) bool needRedraw = m_trackball->updateNavigation(posX, posY); if (needRedraw) { - m_viewer->update(); + m_viewer->navigationPolicyUpdate(); } setCursorFromCurrentState(); @@ -208,7 +208,7 @@ void caf::CeetronNavigation::wheelEvent(QWheelEvent* event) m_trackball->updateNavigation(event->x(), posY + navDelta); m_trackball->endNavigation(); - m_viewer->update(); + m_viewer->navigationPolicyUpdate(); event->accept(); } @@ -254,14 +254,14 @@ void caf::CeetronNavigation::setCursorFromCurrentState() ManipulatorTrackball::NavigationType navType = m_trackball->activeNavigation(); switch (navType) { - case ManipulatorTrackball::PAN: + case ManipulatorTrackball::PAN: //m_viewer->setCursor(RiuCursors::get(RiuCursors::PAN)); return; - case ManipulatorTrackball::WALK: - //m_viewer->setCursor(RiuCursors::get(RiuCursors::WALK)); + case ManipulatorTrackball::WALK: + //m_viewer->setCursor(RiuCursors::get(RiuCursors::WALK)); return; - case ManipulatorTrackball::ROTATE: - //m_viewer->setCursor(RiuCursors::get(RiuCursors::ROTATE)); + case ManipulatorTrackball::ROTATE: + //m_viewer->setCursor(RiuCursors::get(RiuCursors::ROTATE)); return; default: break; diff --git a/Fwk/AppFwk/cafViewer/cafCeetronNavigation.h b/Fwk/AppFwk/cafViewer/cafCeetronNavigation.h index e9f7d78f73..5fbf9018bd 100644 --- a/Fwk/AppFwk/cafViewer/cafCeetronNavigation.h +++ b/Fwk/AppFwk/cafViewer/cafCeetronNavigation.h @@ -57,14 +57,14 @@ class CeetronNavigation : public NavigationPolicy virtual void setPointOfInterest(cvf::Vec3d poi); // Ceetron navigation stuff - void mouseMoveEvent(QMouseEvent* event); - void mousePressEvent(QMouseEvent* event); - void mouseReleaseEvent(QMouseEvent* event); + void mouseMoveEvent(QMouseEvent* event); + void mousePressEvent(QMouseEvent* event); + void mouseReleaseEvent(QMouseEvent* event); void wheelEvent(QWheelEvent* event); cvf::ManipulatorTrackball::NavigationType getNavigationTypeFromMouseButtons(Qt::MouseButtons mouseButtons); - void setCursorFromCurrentState(); + void setCursorFromCurrentState(); void initializeRotationCenter(); diff --git a/Fwk/AppFwk/cafViewer/cafCeetronPlusNavigation.cpp b/Fwk/AppFwk/cafViewer/cafCeetronPlusNavigation.cpp index ff76a6d206..e0aa92e12d 100644 --- a/Fwk/AppFwk/cafViewer/cafCeetronPlusNavigation.cpp +++ b/Fwk/AppFwk/cafViewer/cafCeetronPlusNavigation.cpp @@ -146,7 +146,7 @@ bool caf::CeetronPlusNavigation::handleInputEvent(QInputEvent* inputEvent) bool needRedraw = m_trackball->updateNavigation(translatedMousePosX, translatedMousePosY); if (needRedraw) { - m_viewer->update(); + m_viewer->navigationPolicyUpdate(); } } isEventHandled = true; @@ -257,6 +257,6 @@ void caf::CeetronPlusNavigation::zoomAlongRay(cvf::Ray* ray, int delta) cvf::Vec3d newVrp = vrp + trans; m_viewer->mainCamera()->setFromLookAt(newPos, newVrp, up ); - m_viewer->update(); + m_viewer->navigationPolicyUpdate(); } } diff --git a/Fwk/AppFwk/cafViewer/cafNavigationPolicy.cpp b/Fwk/AppFwk/cafViewer/cafNavigationPolicy.cpp index 52a1b3e37c..996a13feac 100644 --- a/Fwk/AppFwk/cafViewer/cafNavigationPolicy.cpp +++ b/Fwk/AppFwk/cafViewer/cafNavigationPolicy.cpp @@ -47,3 +47,12 @@ cvf::Vec3d caf::NavigationPolicy::pointOfInterest() if(!m_viewer->mainScene() || !m_viewer->mainScene()->boundingBox().isValid()) return cvf::Vec3d::ZERO; return m_viewer->mainScene()->boundingBox().center(); } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void caf::NavigationPolicy::setViewer(Viewer* viewer) +{ + m_viewer = viewer; + init(); +} diff --git a/Fwk/AppFwk/cafViewer/cafNavigationPolicy.h b/Fwk/AppFwk/cafViewer/cafNavigationPolicy.h index 66a9528e44..79d699aa66 100644 --- a/Fwk/AppFwk/cafViewer/cafNavigationPolicy.h +++ b/Fwk/AppFwk/cafViewer/cafNavigationPolicy.h @@ -66,8 +66,8 @@ class NavigationPolicy : public cvf::Object virtual void setPointOfInterest(cvf::Vec3d poi) = 0; // Interface used by caf::ViewerBase - void setViewer(Viewer* viewer) { m_viewer = viewer; init(); } - QPointer<Viewer> m_viewer; + void setViewer(Viewer* viewer); + QPointer<Viewer> m_viewer; }; } // End namespace caf diff --git a/Fwk/AppFwk/cafViewer/cafViewer.cpp b/Fwk/AppFwk/cafViewer/cafViewer.cpp index bfbaedf0c0..4e7af4fa1d 100644 --- a/Fwk/AppFwk/cafViewer/cafViewer.cpp +++ b/Fwk/AppFwk/cafViewer/cafViewer.cpp @@ -313,14 +313,14 @@ bool caf::Viewer::event(QEvent* e) case QEvent::MouseButtonRelease: case QEvent::MouseButtonDblClick: case QEvent::MouseMove: - case QEvent::TabletMove: - case QEvent::TabletPress: + case QEvent::TabletMove: + case QEvent::TabletPress: case QEvent::TabletRelease: case QEvent::TabletEnterProximity: case QEvent::TabletLeaveProximity: case QEvent::Wheel: case QEvent::TouchBegin: - case QEvent::TouchUpdate: + case QEvent::TouchUpdate: case QEvent::TouchEnd: if (m_navigationPolicy->handleInputEvent(static_cast<QInputEvent*>(e))) return true; @@ -518,7 +518,8 @@ void caf::Viewer::setView(const cvf::Vec3d& alongDirection, const cvf::Vec3d& up if (m_navigationPolicy.notNull()) { m_navigationPolicy->setView(alongDirection, upDirection); - update(); + + navigationPolicyUpdate(); } } @@ -544,7 +545,8 @@ void caf::Viewer::zoomAll() m_mainCamera->toLookAt(&eye, &vrp, &up); m_mainCamera->fitView(bb, vrp-eye, up); - update(); + + navigationPolicyUpdate(); } //-------------------------------------------------------------------------------------------------- @@ -592,16 +594,28 @@ bool caf::Viewer::isAnimationActive() //-------------------------------------------------------------------------------------------------- void caf::Viewer::slotSetCurrentFrame(int frameIndex) { - if (frameIndex < 0 || static_cast<size_t>(frameIndex) >= m_frameScenes.size() || m_frameScenes.at(frameIndex) == NULL) return; + if (m_frameScenes.size() == 0) return; + int clampedFrameIndex = frameIndex; - if(m_releaseOGLResourcesEachFrame) + if (static_cast<size_t>(frameIndex) >= m_frameScenes.size()) { - releaseOGlResourcesForCurrentFrame(); + clampedFrameIndex = static_cast<int>(m_frameScenes.size()) - 1; } - m_renderingSequence->firstRendering()->setScene(m_frameScenes.at(frameIndex)); + if (clampedFrameIndex < 0) + { + clampedFrameIndex = 0; + } + if (m_frameScenes.at(clampedFrameIndex) == NULL) return; + + if (m_releaseOGLResourcesEachFrame) + { + releaseOGlResourcesForCurrentFrame(); + } + + m_renderingSequence->firstRendering()->setScene(m_frameScenes.at(clampedFrameIndex)); update(); } @@ -639,6 +653,7 @@ void caf::Viewer::slotEndAnimation() } m_renderingSequence->firstRendering()->setScene(m_mainScene.p()); + update(); } @@ -792,3 +807,11 @@ void caf::Viewer::updateOverlayImagePresence() } } +//-------------------------------------------------------------------------------------------------- +/// Create a virtual method so it is possible to override this function in derived classes +//-------------------------------------------------------------------------------------------------- +void caf::Viewer::navigationPolicyUpdate() +{ + update(); +} + diff --git a/Fwk/AppFwk/cafViewer/cafViewer.h b/Fwk/AppFwk/cafViewer/cafViewer.h index 8cc92a41b5..a10c0caf3d 100644 --- a/Fwk/AppFwk/cafViewer/cafViewer.h +++ b/Fwk/AppFwk/cafViewer/cafViewer.h @@ -123,14 +123,16 @@ class Viewer : public caf::OpenGLWidget void enableOverlyPainting(bool val); // Performance information for debugging etc. - void enablePerfInfoHud(bool enable); - bool isPerfInfoHudEnabled(); + void enablePerfInfoHud(bool enable); + bool isPerfInfoHudEnabled(); void enableForcedImmediateMode(bool enable); // Find out whether the system supports shaders static bool isShadersSupported(); + virtual void navigationPolicyUpdate(); + public slots: virtual void slotSetCurrentFrame(int frameIndex); virtual void slotEndAnimation(); diff --git a/Fwk/AppFwk/cafVizExtensions/CMakeLists.txt b/Fwk/AppFwk/cafVizExtensions/CMakeLists.txt new file mode 100644 index 0000000000..6805a00f4d --- /dev/null +++ b/Fwk/AppFwk/cafVizExtensions/CMakeLists.txt @@ -0,0 +1,23 @@ +cmake_minimum_required (VERSION 2.8) + +project (cafVizExtensions) + +# Open GL +find_package( OpenGL ) + +include_directories( + ${LibCore_SOURCE_DIR} + ${LibGeometry_SOURCE_DIR} + ${LibGuiQt_SOURCE_DIR} + ${LibRender_SOURCE_DIR} + ${LibViewing_SOURCE_DIR} + ${CommonCode_SOURCE_DIR} +) + +add_library( ${PROJECT_NAME} + cafTransparentWBRenderConfiguration.h + cafTransparentWBRenderConfiguration.cpp + TranspWB_CombinationFrag.glsl + TranspWB_PartlyTranspPartsFrag.glsl + TranspWB_TransparentPartsFrag.glsl +) diff --git a/Fwk/AppFwk/cafVizExtensions/TranspWB_CombinationFrag.glsl b/Fwk/AppFwk/cafVizExtensions/TranspWB_CombinationFrag.glsl new file mode 100644 index 0000000000..78a4aadb84 --- /dev/null +++ b/Fwk/AppFwk/cafVizExtensions/TranspWB_CombinationFrag.glsl @@ -0,0 +1,44 @@ +//-------------------------------------------------------------------------------------- +// Weighted Blended Order-Independent Transparency +// Morgan McGuire and Louis Bavoil NVIDIA +// Journal of Computer Graphics Techniques Vol. 2, No. 2, 2013 +// Adapted by Jacob Støren to fit with a pure combination pass with no blending +//-------------------------------------------------------------------------------------- + +#extension GL_ARB_texture_rectangle : enable + +uniform sampler2DRect sumWeightedRgbAndProductOneMinusAlphaTexture; +uniform sampler2DRect sumWeightedAlphaTexture; +uniform sampler2DRect opaceColorTexture; + +void main(void) +{ + // Reference codeFrom the paper. Not correct because we do no blending in the last pass + // gl_FragColor = vec4(sumWeightedColor/clamp(sumWeightedAlpha, 1e-4, 5e4), productOneMinusAlpha); + + // Get the different components from the textures + vec3 sumWeightedColor = texture2DRect(sumWeightedRgbAndProductOneMinusAlphaTexture, gl_FragCoord.xy).rgb; + float sumWeightedAlpha = texture2DRect(sumWeightedAlphaTexture, gl_FragCoord.xy).r; + float productOneMinusAlpha = texture2DRect(sumWeightedRgbAndProductOneMinusAlphaTexture, gl_FragCoord.xy).a; + + vec4 opaceColor = texture2DRect(opaceColorTexture, gl_FragCoord.xy); + + //vec3 sumWColorPrSumWAlpha = sumWeightedColor/sumWeightedAlpha; + vec3 sumWColorPrSumWAlpha = sumWeightedColor/clamp(sumWeightedAlpha, 1.0e-7, 5.0e3 ); + + + // Helpers to visualize different parts of the equation + vec4 resultColor; + + //resultColor = opaceColor; + //resultColor = opaceColor * productOneMinusAlpha; + //resultColor = vec4(productOneMinusAlpha * opaceColor.rgb, 1.0); + //resultColor = vec4( sumWColorPrSumWAlpha, 1.0); + //resultColor = vec4(sumWColorPrSumWAlpha + productOneMinusAlpha * opaceColor.rgb, 1.0); + //resultColor = vec4(productOneMinusAlpha* sumWColorPrSumWAlpha, 1.0); + + // The final correct equation + resultColor = vec4(sumWColorPrSumWAlpha - productOneMinusAlpha * sumWColorPrSumWAlpha + productOneMinusAlpha * opaceColor.rgb, 1.0); + + gl_FragColor = resultColor; +} diff --git a/Fwk/AppFwk/cafVizExtensions/TranspWB_PartlyTranspPartsFrag.glsl b/Fwk/AppFwk/cafVizExtensions/TranspWB_PartlyTranspPartsFrag.glsl new file mode 100644 index 0000000000..f26e584a77 --- /dev/null +++ b/Fwk/AppFwk/cafVizExtensions/TranspWB_PartlyTranspPartsFrag.glsl @@ -0,0 +1,51 @@ +//-------------------------------------------------------------------------------------- +// Weighted Blended Order-Independent Transparency +// Morgan McGuire and Louis Bavoil NVIDIA +// Journal of Computer Graphics Techniques Vol. 2, No. 2, 2013 + +//-------------------------------------------------------------------------------------- + +#extension GL_ARB_draw_buffers : require + +vec4 srcFragment(); +vec4 lightFragment(vec4 srcFragColor, float shadowFactor); + +uniform int isOpaquePass; + +float depthWeight(float depth, float alpha) +{ + //return 1.0; // For testing + return alpha * max(1e-2, 3e3 * pow((1 - gl_FragCoord.z), 3)); // Proposed by paper + //return alpha * max(1e-1, 3e4 * pow((1 - gl_FragCoord.z), 4)); // JJS +} + +void main(void) +{ + vec4 color = srcFragment(); + color = lightFragment(color, 1.0); + if (isOpaquePass == 1) + { + if (color.a < 1.0) + { + discard; + } + else + { + gl_FragData[0] = color; + } + } + else + { + if (color.a == 1.0) + { + discard; + } + else + { + vec3 preMultipliedRgb = color.a*color.rgb; + + gl_FragData[0] = vec4(preMultipliedRgb * depthWeight(0, color.a), color.a); + gl_FragData[1].r = color.a * depthWeight(0, color.a); + } + } +} diff --git a/Fwk/AppFwk/cafVizExtensions/TranspWB_Shaders.h b/Fwk/AppFwk/cafVizExtensions/TranspWB_Shaders.h new file mode 100644 index 0000000000..beb17cdf29 --- /dev/null +++ b/Fwk/AppFwk/cafVizExtensions/TranspWB_Shaders.h @@ -0,0 +1,157 @@ + +// ----------------------------------------- +// THIS IS A GENERATED FILE!! DO NOT MODIFY +// ----------------------------------------- + +//############################################################################################################################# +//############################################################################################################################# +static const char TranspWB_CombinationFrag_inl[] = +"//-------------------------------------------------------------------------------------- \n" +"// Weighted Blended Order-Independent Transparency \n" +"// Morgan McGuire and Louis Bavoil NVIDIA \n" +"// Journal of Computer Graphics Techniques Vol. 2, No. 2, 2013 \n" +"// Adapted by Jacob Støren to fit with a pure combination pass with no blending \n" +"//-------------------------------------------------------------------------------------- \n" +" \n" +"#extension GL_ARB_texture_rectangle : enable \n" +" \n" +"uniform sampler2DRect sumWeightedRgbAndProductOneMinusAlphaTexture; \n" +"uniform sampler2DRect sumWeightedAlphaTexture; \n" +"uniform sampler2DRect opaceColorTexture; \n" +" \n" +"void main(void) \n" +"{ \n" +" // Reference codeFrom the paper. Not correct because we do no blending in the last pass \n" +" // gl_FragColor = vec4(sumWeightedColor/clamp(sumWeightedAlpha, 1e-4, 5e4), productOneMinusAlpha); \n" +" \n" +" // Get the different components from the textures \n" +" vec3 sumWeightedColor = texture2DRect(sumWeightedRgbAndProductOneMinusAlphaTexture, gl_FragCoord.xy).rgb; \n" +" float sumWeightedAlpha = texture2DRect(sumWeightedAlphaTexture, gl_FragCoord.xy).r; \n" +" float productOneMinusAlpha = texture2DRect(sumWeightedRgbAndProductOneMinusAlphaTexture, gl_FragCoord.xy).a; \n" +" \n" +" vec4 opaceColor = texture2DRect(opaceColorTexture, gl_FragCoord.xy); \n" +" \n" +" //vec3 sumWColorPrSumWAlpha = sumWeightedColor/sumWeightedAlpha; \n" +" vec3 sumWColorPrSumWAlpha = sumWeightedColor/clamp(sumWeightedAlpha, 1.0e-7, 5.0e3 ); \n" +" \n" +" \n" +" // Helpers to visualize different parts of the equation \n" +" vec4 resultColor; \n" +" \n" +" //resultColor = opaceColor; \n" +" //resultColor = opaceColor * productOneMinusAlpha; \n" +" //resultColor = vec4(productOneMinusAlpha * opaceColor.rgb, 1.0); \n" +" //resultColor = vec4( sumWColorPrSumWAlpha, 1.0); \n" +" //resultColor = vec4(sumWColorPrSumWAlpha + productOneMinusAlpha * opaceColor.rgb, 1.0); \n" +" //resultColor = vec4(productOneMinusAlpha* sumWColorPrSumWAlpha, 1.0); \n" +" \n" +" // The final correct equation \n" +" resultColor = vec4(sumWColorPrSumWAlpha - productOneMinusAlpha * sumWColorPrSumWAlpha + productOneMinusAlpha * opaceColor.rgb, 1.0); \n" +" \n" +" gl_FragColor = resultColor; \n" +"} \n"; + + + +//############################################################################################################################# +//############################################################################################################################# +static const char TranspWB_PartlyTranspPartsFrag_inl[] = +"//-------------------------------------------------------------------------------------- \n" +"// Weighted Blended Order-Independent Transparency \n" +"// Morgan McGuire and Louis Bavoil NVIDIA \n" +"// Journal of Computer Graphics Techniques Vol. 2, No. 2, 2013 \n" +" \n" +"//-------------------------------------------------------------------------------------- \n" +" \n" +"#extension GL_ARB_draw_buffers : require \n" +" \n" +"vec4 srcFragment(); \n" +"vec4 lightFragment(vec4 srcFragColor, float shadowFactor); \n" +" \n" +"uniform int isOpaquePass; \n" +" \n" +"float depthWeight(float depth, float alpha) \n" +"{ \n" +" //return 1.0; // For testing \n" +" return alpha * max(1e-2, 3e3 * pow((1 - gl_FragCoord.z), 3)); // Proposed by paper \n" +" //return alpha * max(1e-1, 3e4 * pow((1 - gl_FragCoord.z), 4)); // JJS \n" +"} \n" +" \n" +"void main(void) \n" +"{ \n" +" vec4 color = srcFragment(); \n" +" color = lightFragment(color, 1.0); \n" +" if (isOpaquePass == 1) \n" +" { \n" +" if (color.a < 1.0) \n" +" { \n" +" discard; \n" +" } \n" +" else \n" +" { \n" +" gl_FragData[0] = color; \n" +" } \n" +" } \n" +" else \n" +" { \n" +" if (color.a == 1.0) \n" +" { \n" +" discard; \n" +" } \n" +" else \n" +" { \n" +" vec3 preMultipliedRgb = color.a*color.rgb; \n" +" \n" +" gl_FragData[0] = vec4(preMultipliedRgb * depthWeight(0, color.a), color.a); \n" +" gl_FragData[1].r = color.a * depthWeight(0, color.a); \n" +" } \n" +" } \n" +"} \n"; + + + +//############################################################################################################################# +//############################################################################################################################# +static const char TranspWB_TransparentPartsFrag_inl[] = +"//-------------------------------------------------------------------------------------- \n" +"// Weighted Blended Order-Independent Transparency \n" +"// Morgan McGuire and Louis Bavoil NVIDIA \n" +"// Journal of Computer Graphics Techniques Vol. 2, No. 2, 2013 \n" +" \n" +"//-------------------------------------------------------------------------------------- \n" +" \n" +"#extension GL_ARB_draw_buffers : require \n" +" \n" +"vec4 srcFragment(); \n" +"vec4 lightFragment(vec4 srcFragColor, float shadowFactor); \n" +" \n" +"uniform float cameraNear; \n" +"uniform float cameraFar; \n" +" \n" +"float realZDepth(float fragCoordZ) { \n" +" \n" +" return (cameraFar * cameraNear) / (cameraFar - fragCoordZ * (cameraFar - cameraNear)) ; \n" +"} \n" +" \n" +"float depthWeight(float fragCoordZ, float alpha) \n" +"{ \n" +" //return 1.0; // For testing \n" +" //return alpha * max(1e-2, 3e3 * pow((1 - fragCoordZ), 3)); // Proposed by paper \n" +" \n" +" float zDepth = realZDepth(fragCoordZ); \n" +" return alpha * max(1e-2, min(3e3, 10 / (1e5 + pow(zDepth/10, 3) + pow(zDepth/200, 6) ))); // Proposed by paper \n" +" //return zDepth; \n" +"} \n" +" \n" +"void main(void) \n" +"{ \n" +" vec4 color = srcFragment(); \n" +" color = lightFragment(color, 1.0); \n" +" \n" +" vec3 preMultipliedRgb = color.a*color.rgb; \n" +" \n" +" gl_FragData[0] = vec4(preMultipliedRgb * depthWeight(gl_FragCoord.z, color.a), color.a); \n" +" gl_FragData[1].r = color.a * depthWeight(gl_FragCoord.z, color.a); \n" +"} \n"; + + diff --git a/Fwk/AppFwk/cafVizExtensions/TranspWB_TransparentPartsFrag.glsl b/Fwk/AppFwk/cafVizExtensions/TranspWB_TransparentPartsFrag.glsl new file mode 100644 index 0000000000..0b529b82d2 --- /dev/null +++ b/Fwk/AppFwk/cafVizExtensions/TranspWB_TransparentPartsFrag.glsl @@ -0,0 +1,40 @@ +//-------------------------------------------------------------------------------------- +// Weighted Blended Order-Independent Transparency +// Morgan McGuire and Louis Bavoil NVIDIA +// Journal of Computer Graphics Techniques Vol. 2, No. 2, 2013 + +//-------------------------------------------------------------------------------------- + +#extension GL_ARB_draw_buffers : require + +vec4 srcFragment(); +vec4 lightFragment(vec4 srcFragColor, float shadowFactor); + +uniform float cameraNear; +uniform float cameraFar; + +float realZDepth(float fragCoordZ) { + + return (cameraFar * cameraNear) / (cameraFar - fragCoordZ * (cameraFar - cameraNear)) ; +} + +float depthWeight(float fragCoordZ, float alpha) +{ + //return 1.0; // For testing + //return alpha * max(1e-2, 3e3 * pow((1 - fragCoordZ), 3)); // Proposed by paper + + float zDepth = realZDepth(fragCoordZ); + return alpha * max(1e-2, min(3e3, 10 / (1e5 + pow(zDepth/10, 3) + pow(zDepth/200, 6) ))); // Proposed by paper + //return zDepth; +} + +void main(void) +{ + vec4 color = srcFragment(); + color = lightFragment(color, 1.0); + + vec3 preMultipliedRgb = color.a*color.rgb; + + gl_FragData[0] = vec4(preMultipliedRgb * depthWeight(gl_FragCoord.z, color.a), color.a); + gl_FragData[1].r = color.a * depthWeight(gl_FragCoord.z, color.a); +} diff --git a/Fwk/AppFwk/cafVizExtensions/cafTransparentWBRenderConfiguration.cpp b/Fwk/AppFwk/cafVizExtensions/cafTransparentWBRenderConfiguration.cpp new file mode 100644 index 0000000000..77982076ba --- /dev/null +++ b/Fwk/AppFwk/cafVizExtensions/cafTransparentWBRenderConfiguration.cpp @@ -0,0 +1,557 @@ + +#include "cafTransparentWBRenderConfiguration.h" + +#include "cvfLibCore.h" +#include "cvfLibRender.h" +#include "cvfLibViewing.h" +#include "cvfRenderQueueSorter.h" +#include "cvfDynamicUniformSet.h" + +#include "TranspWB_Shaders.h" + +namespace caf { + +using namespace cvf; + +/* + This is an implementation of + Weighted Blended Order-Independent Transparency + based on + Morgan McGuire and Louis Bavoil NVIDIA + Journal of Computer Graphics Techniques Vol. 2, No. 2, 2013 + + It can be developed further to support completely unsorted and partially transparent objects + by making the first pass include all parts, but discard transparent fragments, + while the transparency pass discards all opaque fragments. + This should be quite possible. (Experimentally done now) + + A more experimental idea To improve high opaque transparent object looks, and make them + hide the transparent object behind, better, + we can set a threshold on the opacity (above 0.9 e.g), and limis it contribution to the + blended color to just include one (possible) transparent layer behind it. + To do this we will try to make the Z-buffer for the transparent pass contain the + depth of the fragment behind the one with opaqueThreshold < alpha < 1.0 + + To do this we need to do somewhat the following (experimental idea): + P0 Opaque Pass => TB: OpaqueBuffer, DB: DepthBufferOpaque, TB: DepthBufferToPeel + Including all parts + Discarding all transparent fragments with alpha < opaqueThreshold + Opaque fragments rendered normally, also write to depth to DepthbufferToPeel + If (opaqueThreshold < alpha < 1.0) discard color, write depth to DepthBufferToPeel + + P1 Peel Pass (TB: DepthBufferToPeel) ==> PeeledDepthBuffer + Discarding all transparent fragments with alpha < opaqueThreshold + Discard all fragments with depth <= DepthBufferToPeel, + Normal depth test + + P3 Transparent Pass (DB: DepthBufferOpaque, TB: PeeledDepthBuffer) => WeightedSumColorAndAlpha, ProdOneMinusAlpha + This pass is the mostly the same as the one described in the original method except (No write to depth buffer) + Discard Opaque fragments + if (depth > PeeledDepthBuffer) discard + + P4 Combination pass + +*/ + +class RenderPassPreparator : public cvf::DynamicUniformSet +{ +public: + RenderPassPreparator(TransparentWBRenderConfiguration* renderConfiguration) + { + CVF_ASSERT(renderConfiguration); + m_renderConfiguration = renderConfiguration; + } + virtual cvf::UniformSet* uniformSet() { return NULL; } + virtual void update(cvf::Rendering* rendering) + { + m_renderConfiguration->updateEffectsForRendering(rendering); + } + +private: + TransparentWBRenderConfiguration * m_renderConfiguration; +}; + + +class RenderQueueFilter : public cvf::RenderQueueSorterBasic +{ +public: + RenderQueueFilter(cvf::RenderStateBlending* blendingToRespect, bool isOpaquePass, cvf::RenderQueueSorterBasic::SortStrategy sortStrategy): + cvf::RenderQueueSorterBasic(sortStrategy) + { + CVF_ASSERT(blendingToRespect); + + m_blendingToRespect = blendingToRespect; + m_isOpaquePass = isOpaquePass; + } + + virtual void sort(cvf::RenderQueue* renderQueue) const + { + using namespace cvf; + std::vector<RenderItem*>* renderItems = renderQueue->renderItemsForSorting(); + std::vector<RenderItem*> filteredRenderItems; + filteredRenderItems.reserve(renderItems->size()); + + for (size_t riIdx = 0; riIdx < renderItems->size(); ++riIdx) + { + bool hasBlending = (*renderItems)[riIdx]->effect()->renderStateOfType(cvf::RenderState::BLENDING) == m_blendingToRespect.p(); + if (m_isOpaquePass && !hasBlending) + { + filteredRenderItems.push_back((*renderItems)[riIdx]); + } + if (!m_isOpaquePass && hasBlending) + { + filteredRenderItems.push_back((*renderItems)[riIdx]); + } + } + + renderItems->swap(filteredRenderItems); + + cvf::RenderQueueSorterBasic::sort(renderQueue); + } + +private: + cvf::ref<cvf::RenderStateBlending> m_blendingToRespect; + bool m_isOpaquePass; +}; + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TransparentWBRenderConfiguration::TransparentWBRenderConfiguration() +{ + // Initialize effect system + WBTransparencySurfaceEffectGenerator::initStaticData(); +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TransparentWBRenderConfiguration::~TransparentWBRenderConfiguration() +{ + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void TransparentWBRenderConfiguration::setUpRenderSequence(cvf::RenderSequence* renderSeq) +{ + if (EffectGenerator::renderingMode() == EffectGenerator::SHADER_BASED) + { + // Set up opaque pass + ref<RenderbufferObject> depthBuffer = new RenderbufferObject(RenderbufferObject::DEPTH_COMPONENT24, 1, 1); + ref<Texture> opaceColorTexture = new Texture(Texture::TEXTURE_RECTANGLE, Texture::RGBA32F); + ref<Texture> sumWeightedRgbAndProductOneMinusAlphaTexture = new Texture(Texture::TEXTURE_RECTANGLE, Texture::RGBA32F); + ref<Texture> sumWeightedAlphaTexture = new Texture(Texture::TEXTURE_RECTANGLE, Texture::R32F); + + ref<RenderPassPreparator> renderPassPrep = new RenderPassPreparator(this); + + { + m_opaceRendering = renderSeq->firstRendering(); + CVF_ASSERT(m_opaceRendering.notNull()); + + m_opaceRenderingFbo = new FramebufferObject; + + m_opaceRenderingFbo->attachDepthRenderbuffer(depthBuffer.p()); + + opaceColorTexture->setSize(1, 1); + m_opaceRenderingFbo->attachColorTexture2d(0, opaceColorTexture.p()); + + m_opaceRendering->setTargetFramebuffer(m_opaceRenderingFbo.p()); + //m_opaceRendering->camera()->viewport()->setClearColor(Color4f(0.69f, 0.77f, 0.87f, 1.0f)); + m_opaceRendering->addDynamicUniformSet(renderPassPrep.p()); + m_opaceRendering->setRenderQueueSorter(new RenderQueueFilter(WBTransparencySurfaceEffectGenerator::m_blending.p(), true, RenderQueueSorterBasic::EFFECT_ONLY)); + + } + + // Set up transparency pass + { + // Frame buffer + m_transparencyFbo = new FramebufferObject; + + m_transparencyFbo->attachDepthRenderbuffer(depthBuffer.p()); + + sumWeightedRgbAndProductOneMinusAlphaTexture->setSize(1, 1); + m_transparencyFbo->attachColorTexture2d(0, sumWeightedRgbAndProductOneMinusAlphaTexture.p()); + + sumWeightedAlphaTexture->setSize(1, 1); + m_transparencyFbo->attachColorTexture2d(1, sumWeightedAlphaTexture.p()); + + // Rendering + m_transparentRendering = new Rendering; + + m_transparentRendering->setTargetFramebuffer(m_transparencyFbo.p()); + ref<Camera> transpCam = new Camera; + transpCam->viewport()->setClearColor(Color4f(0, 0, 0, 1)); + copyCameraView(renderSeq->firstRendering()->camera(), transpCam.p()); + m_transparentRendering->setCamera(transpCam.p()); + m_transparentRendering->setClearMode(Viewport::CLEAR_COLOR); + + renderSeq->addRendering(m_transparentRendering.p()); + m_transparentRendering->addDynamicUniformSet(renderPassPrep.p()); + m_transparentRendering->setRenderQueueSorter(new RenderQueueFilter(WBTransparencySurfaceEffectGenerator::m_blending.p(), false, RenderQueueSorterBasic::EFFECT_ONLY)); + } + + // Setup last rendering combining the textures on the screen + // ------------------------------------------------------------------------- + { + SingleQuadRenderingGenerator quadRenderGen; + ref<Sampler> sampler = new Sampler; + sampler->setWrapMode(cvf::Sampler::CLAMP_TO_EDGE); + sampler->setMinFilter(cvf::Sampler::NEAREST); + sampler->setMagFilter(cvf::Sampler::NEAREST); + + quadRenderGen.addTexture(sumWeightedRgbAndProductOneMinusAlphaTexture.p(), sampler.p(), "sumWeightedRgbAndProductOneMinusAlphaTexture"); + quadRenderGen.addTexture(sumWeightedAlphaTexture.p(), sampler.p(), "sumWeightedAlphaTexture"); + quadRenderGen.addTexture(opaceColorTexture.p(), sampler.p(), "opaceColorTexture"); + + quadRenderGen.addFragmentShaderCode(String(TranspWB_CombinationFrag_inl)); + m_combinationRendering = quadRenderGen.generate(); + renderSeq->addRendering(m_combinationRendering.p()); + m_combinationRendering->addDynamicUniformSet(renderPassPrep.p()); + + } + } + else + { + m_opaceRendering = renderSeq->firstRendering(); + m_opaceRendering->setRenderQueueSorter(new RenderQueueFilter(WBTransparencySurfaceEffectGenerator::m_oGL11Blending.p(), true, RenderQueueSorterBasic::EFFECT_ONLY)); + + m_transparentRendering = new Rendering; + ref<Camera> transpCam = new Camera; + copyCameraView(renderSeq->firstRendering()->camera(), transpCam.p()); + m_transparentRendering->setCamera(transpCam.p()); + m_transparentRendering->setClearMode(Viewport::DO_NOT_CLEAR); + + renderSeq->addRendering(m_transparentRendering.p()); + m_transparentRendering->setRenderQueueSorter(new RenderQueueFilter(WBTransparencySurfaceEffectGenerator::m_oGL11Blending.p(), false, RenderQueueSorterBasic::BACK_TO_FRONT)); + + } + +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void TransparentWBRenderConfiguration::resize(int width, int height) +{ + // Resize the FBO (and the rendering viewports) + + m_opaceRendering->camera()->viewport()->set(0, 0, width, height); + m_transparentRendering->camera()->viewport()->set(0, 0, width, height); + + if (EffectGenerator::renderingMode() == EffectGenerator::SHADER_BASED) + { + m_combinationRendering->camera()->viewport()->set(0, 0, width, height); + + m_opaceRenderingFbo->resizeAttachedBuffers(width, height); + m_transparencyFbo->resizeAttachedBuffers(width, height); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void TransparentWBRenderConfiguration::copyCameraView(Camera* srcCamera, Camera* dstCamera) +{ + if (srcCamera->projection() == Camera::PERSPECTIVE) + { + dstCamera->setProjectionAsPerspective(srcCamera->fieldOfViewYDeg(), srcCamera->nearPlane(), srcCamera->farPlane()); + } + else + { + dstCamera->setProjectionAsOrtho(srcCamera->frontPlaneFrustumHeight(), srcCamera->nearPlane(), srcCamera->farPlane()); + } + + dstCamera->setViewMatrix(srcCamera->viewMatrix()); +} + + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void TransparentWBRenderConfiguration::prepareForRendering() +{ + m_transparentRendering->setScene(m_opaceRendering->scene()); + copyCameraView(m_opaceRendering->camera(), m_transparentRendering->camera()); + WBTransparencySurfaceEffectGenerator::m_cameraNearUniform->set((float)(m_opaceRendering->camera()->nearPlane())); + WBTransparencySurfaceEffectGenerator::m_cameraFarUniform->set((float)(m_opaceRendering->camera()->farPlane())); + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void TransparentWBRenderConfiguration::updateEffectsForRendering(Rendering *rendering) +{ + if (EffectGenerator::renderingMode() == EffectGenerator::SHADER_BASED) + { + // This is to support partially transparent objects. So not yet actually operational. + if (rendering == m_opaceRendering) + { + WBTransparencySurfaceEffectGenerator::m_renderPassUniform->set(1); + WBTransparencySurfaceEffectGenerator::m_blending->enableBlending(false); + WBTransparencySurfaceEffectGenerator::m_depth->enableDepthWrite(true); + } + else if (rendering == m_transparentRendering) + { + WBTransparencySurfaceEffectGenerator::m_renderPassUniform->set(0); + WBTransparencySurfaceEffectGenerator::m_blending->enableBlending(true); + WBTransparencySurfaceEffectGenerator::m_depth->enableDepthWrite(false); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +cvf::ref<cvf::Rendering> TransparentWBRenderConfiguration::overlayRendering() +{ + if (EffectGenerator::renderingMode() == EffectGenerator::SHADER_BASED) + { + return m_combinationRendering; + } + else + { + return m_transparentRendering; + } +} + + + + +//================================================================================================== +// +// WBTransparencySurfaceEffectGenerator +// +//================================================================================================== + +cvf::ref<cvf::ShaderProgram> WBTransparencySurfaceEffectGenerator::m_shaderForTransparentParts; +cvf::ref<cvf::ShaderProgram> WBTransparencySurfaceEffectGenerator::m_shaderForOpaqueParts; +cvf::ref<cvf::ShaderProgram> WBTransparencySurfaceEffectGenerator::m_shaderForTransparentPartsSpec; +cvf::ref<cvf::ShaderProgram> WBTransparencySurfaceEffectGenerator::m_shaderForOpaquePartsSpec; +cvf::ref<cvf::UniformInt> WBTransparencySurfaceEffectGenerator::m_renderPassUniform; +cvf::ref<cvf::RenderStateBlending> WBTransparencySurfaceEffectGenerator::m_blending; +cvf::ref<cvf::RenderStateBlending> WBTransparencySurfaceEffectGenerator::m_oGL11Blending; +cvf::ref<cvf::RenderStateDepth> WBTransparencySurfaceEffectGenerator::m_depth; + +cvf::ref<cvf::UniformFloat> WBTransparencySurfaceEffectGenerator::m_cameraNearUniform; +cvf::ref<cvf::UniformFloat> WBTransparencySurfaceEffectGenerator::m_cameraFarUniform; + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +WBTransparencySurfaceEffectGenerator::WBTransparencySurfaceEffectGenerator(const cvf::Color4f& color, PolygonOffset polygonOffset, bool useSpecular) +{ + m_color = color; + m_polygonOffset = polygonOffset; + m_useSpecularColor = useSpecular; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void WBTransparencySurfaceEffectGenerator::updateForShaderBasedRendering(cvf::Effect* effect) const +{ + if (m_color.a() < 1.0f) + { + if (m_useSpecularColor) + { + effect->setShaderProgram(m_shaderForTransparentPartsSpec.p()); + } + else + { + effect->setShaderProgram(m_shaderForTransparentParts.p()); + } + //effect->setUniform(m_renderPassUniform.p()); // To be used in effects for partially transparent objects + effect->setUniform(m_cameraNearUniform.p()); + effect->setUniform(m_cameraFarUniform.p()); + + } + else + { + if (m_useSpecularColor) + { + effect->setShaderProgram(m_shaderForOpaquePartsSpec.p()); + } + else + { + effect->setShaderProgram(m_shaderForOpaqueParts.p()); + } + } + + effect->setUniform(new cvf::UniformFloat("u_color", m_color)); + + if (m_color.a() < 1.0f) + { + effect->setRenderState(m_blending.p()); + } + + this->updateCommonEffect(effect); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void WBTransparencySurfaceEffectGenerator::updateForFixedFunctionRendering(cvf::Effect* effect) const +{ + cvf::ref<cvf::Effect> eff = effect; + + cvf::ref<cvf::RenderStateMaterial_FF> mat = new cvf::RenderStateMaterial_FF(m_color.toColor3f()); + mat->setAlpha(m_color.a()); + + eff->setRenderState(mat.p()); + + cvf::ref<cvf::RenderStateLighting_FF> lighting = new cvf::RenderStateLighting_FF; + lighting->enableTwoSided(true); + eff->setRenderState(lighting.p()); + + if (m_color.a() < 1.0f) + { + effect->setRenderState(m_oGL11Blending.p()); + } + + this->updateCommonEffect(effect); + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void WBTransparencySurfaceEffectGenerator::updateCommonEffect(cvf::Effect* effect) const +{ + if (m_polygonOffset != PO_NONE) + { + cvf::ref<cvf::RenderStatePolygonOffset> polyOffset = EffectGenerator::CreateAngConfigurePolygonOffsetRenderState(m_polygonOffset); + effect->setRenderState(polyOffset.p()); + } + + if (m_color.a() < 1.0f) + { + effect->setRenderState(m_depth.p()); + } + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool WBTransparencySurfaceEffectGenerator::isEqual(const EffectGenerator* other) const +{ + const WBTransparencySurfaceEffectGenerator* otherSurfaceEffect = dynamic_cast<const WBTransparencySurfaceEffectGenerator*>(other); + + if (otherSurfaceEffect) + { + if (m_color == otherSurfaceEffect->m_color + && m_polygonOffset == otherSurfaceEffect->m_polygonOffset + && m_useSpecularColor == otherSurfaceEffect->m_useSpecularColor) + { + return true; + } + } + + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +EffectGenerator* WBTransparencySurfaceEffectGenerator::copy() const +{ + WBTransparencySurfaceEffectGenerator* effGen = new WBTransparencySurfaceEffectGenerator(m_color, m_polygonOffset, m_useSpecularColor); + + return effGen; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void WBTransparencySurfaceEffectGenerator::initStaticData() +{ + if (m_blending.notNull()) return; + + { + ShaderProgramGenerator transpPartsShaderGen("TranspPartsShader", ShaderSourceProvider::instance()); + transpPartsShaderGen.addVertexCode(cvf::ShaderSourceRepository::vs_Standard); + transpPartsShaderGen.addFragmentCode(ShaderSourceRepository::src_Color); + transpPartsShaderGen.addFragmentCode(CommonShaderSources::light_AmbientDiffuse()); + + transpPartsShaderGen.addFragmentCode(String(TranspWB_TransparentPartsFrag_inl)); + + m_shaderForTransparentParts = transpPartsShaderGen.generate(); + } + { + ShaderProgramGenerator transpPartsShaderGen("TranspPartsShader", ShaderSourceProvider::instance()); + transpPartsShaderGen.addVertexCode(cvf::ShaderSourceRepository::vs_Standard); + transpPartsShaderGen.addFragmentCode(ShaderSourceRepository::src_Color); + transpPartsShaderGen.addFragmentCode(ShaderSourceRepository::light_SimpleHeadlight); + + transpPartsShaderGen.addFragmentCode(String(TranspWB_TransparentPartsFrag_inl)); + + m_shaderForTransparentPartsSpec = transpPartsShaderGen.generate(); + } + +#if 0 // Code to use when implementing support for partial transparency, but supposedly in a different effect generator + { + // Shader for partly transparent objects + + ShaderProgramGenerator partlyTranspShaderGen("CommonShader", ShaderSourceProvider::instance()); + partlyTranspShaderGen.addVertexCode(cvf::ShaderSourceRepository::vs_Standard); + partlyTranspShaderGen.addFragmentCode(ShaderSourceRepository::src_Color); + partlyTranspShaderGen.addFragmentCode(ShaderSourceRepository::light_SimpleHeadlight); + partlyTranspShaderGen.addFragmentCode(String(TranspWB_PartlyTranspPartsFrag_inl)); + + m_partlyTranspPartShader = partlyTranspShaderGen.generate(); + } +#endif + + { + ShaderProgramGenerator opaquePartsShaderGen("OpaquePartsShader", ShaderSourceProvider::instance()); + opaquePartsShaderGen.addVertexCode(cvf::ShaderSourceRepository::vs_Standard); + opaquePartsShaderGen.addFragmentCode(ShaderSourceRepository::src_Color); + opaquePartsShaderGen.addFragmentCode(CommonShaderSources::light_AmbientDiffuse()); + opaquePartsShaderGen.addFragmentCode(ShaderSourceRepository::fs_Standard); + m_shaderForOpaqueParts = opaquePartsShaderGen.generate(); + } + { + ShaderProgramGenerator opaquePartsShaderGen("OpaquePartsShader", ShaderSourceProvider::instance()); + opaquePartsShaderGen.addVertexCode(cvf::ShaderSourceRepository::vs_Standard); + opaquePartsShaderGen.addFragmentCode(ShaderSourceRepository::src_Color); + opaquePartsShaderGen.addFragmentCode(ShaderSourceRepository::light_SimpleHeadlight); + opaquePartsShaderGen.addFragmentCode(ShaderSourceRepository::fs_Standard); + m_shaderForOpaquePartsSpec = opaquePartsShaderGen.generate(); + } + + + + + m_blending = new RenderStateBlending; + m_blending->setFunctionSeparate(RenderStateBlending::ONE, RenderStateBlending::ONE, RenderStateBlending::ZERO, RenderStateBlending::ONE_MINUS_SRC_ALPHA); + m_blending->setEquation(RenderStateBlending::FUNC_ADD); + m_blending->enableBlending(true); + + m_oGL11Blending = new RenderStateBlending; + m_oGL11Blending->configureTransparencyBlending(); + + m_depth = new RenderStateDepth; + m_depth->enableDepthWrite(false); + + m_renderPassUniform = new UniformInt("isOpaquePass", 1); + m_cameraNearUniform = new UniformFloat("cameraNear", 0.01); + m_cameraFarUniform = new UniformFloat("cameraFar",1000); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +WBTransparencySurfaceEffectGenerator::~WBTransparencySurfaceEffectGenerator() +{ + +} + + +} diff --git a/Fwk/AppFwk/cafVizExtensions/cafTransparentWBRenderConfiguration.h b/Fwk/AppFwk/cafVizExtensions/cafTransparentWBRenderConfiguration.h new file mode 100644 index 0000000000..7db966c6c2 --- /dev/null +++ b/Fwk/AppFwk/cafVizExtensions/cafTransparentWBRenderConfiguration.h @@ -0,0 +1,116 @@ + +#include "cvfBase.h" +#include "cvfObject.h" +#include "cvfColor4.h" +#include "cvfString.h" +#include "cafEffectGenerator.h" +#include "cvfRendering.h" + +namespace cvf +{ + class Rendering; + class Scene; + class Camera; + class RenderSequence; + class FramebufferObject; + class UniformInt; + class UniformFloat; + class Effect; + class RenderStateBlending; + class RenderStateDepth; + class ShaderProgram; +} + +namespace caf +{ + + class TransparentWBRenderConfiguration : public cvf::Object + { + public: + TransparentWBRenderConfiguration(); + virtual ~TransparentWBRenderConfiguration(); + + void resize(int width, int height); + void prepareForRendering(); // UpdateCameras and scene ... + + void setUpRenderSequence(cvf::RenderSequence* renderSeq); + + //cvf::ref<cvf::Effect> transparentPartEffect(const cvf::Color4f& color); + //void setupTransparentPartEffect(cvf::Effect* effectToModify, ShaderProgramGenerator& shaderGen); + + cvf::ref<cvf::Rendering> overlayRendering(); + + private: + //void initShaders(); + static void copyCameraView(cvf::Camera* srcCamera, cvf::Camera* dstCamera); + friend class RenderPassPreparator; + void updateEffectsForRendering(cvf::Rendering *rendering); + + + cvf::ref<cvf::Rendering> m_opaceRendering; + cvf::ref<cvf::Rendering> m_transparentRendering; + cvf::ref<cvf::Rendering> m_combinationRendering; + + cvf::ref<cvf::FramebufferObject> m_opaceRenderingFbo; + cvf::ref<cvf::FramebufferObject> m_transparencyFbo; +#if 0 + cvf::ref<cvf::UniformInt> m_renderPassUniform; + cvf::ref<cvf::RenderStateBlending> m_blending; + cvf::ref<cvf::RenderStateDepth> m_depth; + + cvf::ref<cvf::ShaderProgram> m_shaderForTransparentParts; + cvf::ref<cvf::ShaderProgram> m_simpleSolidShader; + cvf::ref<cvf::ShaderProgram> m_partlyTranspPartShader; +#endif + + cvf::String m_finalFragShaderCode; + + }; + + + + + //================================================================================================== + // + // SurfaceEffectGenerator + // + //================================================================================================== + class WBTransparencySurfaceEffectGenerator : public EffectGenerator + { + public: + WBTransparencySurfaceEffectGenerator(const cvf::Color4f& color, caf::PolygonOffset polygonOffset, bool useSpecular); + ~WBTransparencySurfaceEffectGenerator(); + + protected: + virtual bool isEqual(const EffectGenerator* other) const; + virtual EffectGenerator* copy() const; + + virtual void updateForShaderBasedRendering(cvf::Effect* effect) const; + virtual void updateForFixedFunctionRendering(cvf::Effect* effect) const; + + private: + void updateCommonEffect(cvf::Effect* effect) const; + static void initStaticData(); + + private: + cvf::Color4f m_color; + caf::PolygonOffset m_polygonOffset; + bool m_useSpecularColor; + friend class TransparentWBRenderConfiguration; + + static cvf::ref<cvf::ShaderProgram> m_shaderForTransparentParts; + static cvf::ref<cvf::ShaderProgram> m_shaderForTransparentPartsSpec; + static cvf::ref<cvf::ShaderProgram> m_shaderForOpaqueParts; + static cvf::ref<cvf::ShaderProgram> m_shaderForOpaquePartsSpec; + + static cvf::ref<cvf::UniformInt> m_renderPassUniform; + static cvf::ref<cvf::RenderStateBlending> m_blending; + static cvf::ref<cvf::RenderStateBlending> m_oGL11Blending; + + static cvf::ref<cvf::UniformFloat> m_cameraNearUniform; + static cvf::ref<cvf::UniformFloat> m_cameraFarUniform; + + static cvf::ref<cvf::RenderStateDepth> m_depth; + }; + +} \ No newline at end of file diff --git a/ResInsightVersion.cmake b/ResInsightVersion.cmake index b137de59b1..d891160a9a 100644 --- a/ResInsightVersion.cmake +++ b/ResInsightVersion.cmake @@ -1,8 +1,15 @@ set(CMAKE_MAJOR_VERSION 1) -set(CMAKE_MINOR_VERSION 4) +set(CMAKE_MINOR_VERSION 5) set(CMAKE_PATCH_VERSION 0) -set(DEV_VERSION "") +# set(DEV_VERSION "-dev") +# set(DEV_VERSION "-RC") + +# https://github.com/CRAVA/crava/tree/master/libs/nrlib +set(NRLIB_GITHUB_SHA "ba35d4359882f1c6f5e9dc30eb95fe52af50fd6f") + +# https://github.com/Ensembles/ert +set(ERT_GITHUB_SHA "9eb4c76cb930450c35e6d44d479da1141e296c7a") set(PRODUCTVER ${CMAKE_MAJOR_VERSION},${CMAKE_MINOR_VERSION},0,${CMAKE_PATCH_VERSION}) set(STRPRODUCTVER ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}.${CMAKE_PATCH_VERSION}${DEV_VERSION}) diff --git a/ThirdParty/Ert/.gitignore b/ThirdParty/Ert/.gitignore index 43c43a690a..1ec65bb69b 100644 --- a/ThirdParty/Ert/.gitignore +++ b/ThirdParty/Ert/.gitignore @@ -22,4 +22,5 @@ devel/python/lib64 scratch.sparsebundle *.iml *.DS_Store +__ert_lib_path.py diff --git a/ThirdParty/Ert/.travis.yml b/ThirdParty/Ert/.travis.yml new file mode 100644 index 0000000000..e28b6c4420 --- /dev/null +++ b/ThirdParty/Ert/.travis.yml @@ -0,0 +1,38 @@ +language: python + +python: + - 2.7_with_system_site_packages + +compiler: + - gcc + +addons: + apt: + packages: + - liblapack-dev + - texlive-latex-base + - valgrind + - python-qt4 + - python-qt4-gl + +before_install: + - wget http://repo.continuum.io/miniconda/Miniconda-latest-Linux-x86_64.sh -O miniconda.sh + - chmod +x miniconda.sh + - ./miniconda.sh -b + - export PATH=/home/travis/miniconda/bin:$PATH + - conda update --yes conda + +install: + - conda install --yes numpy scipy matplotlib pandas pyopengl sphinx + +before_script: + - sudo apt-get install libplplot-dev + - sudo apt-get install python-tk + - mkdir build + - cd build + - echo "WORKFLOW_JOB_DIRECTORY ../devel/share/workflows/jobs/internal/config" > DEFAULT_SITE_CONFIG_FILE + - echo "WORKFLOW_JOB_DIRECTORY ../devel/share/workflows/jobs/internal-gui/config" >> DEFAULT_SITE_CONFIG_FILE + - echo "JOB_SCRIPT ../devel/share/bin/job_dispatch.py" >> DEFAULT_SITE_CONFIG_FILE + - cmake -DPYTHON_INSTALL_PREFIX=python -DBUILD_ERT=ON -DERT_BUILD_GUI=ON -DBUILD_ENS_PLOT=ON -DBUILD_TESTS=ON -DBUILD_APPLICATIONS=ON -DUSE_RUNPATH=ON -DBUILD_PYTHON=ON -DERT_USE_OPENMP=ON -DERT_DOC=ON -DSITE_CONFIG_FILE=DEFAULT_SITE_CONFIG_FILE ../devel + +script: make && ctest --output-on-failure -LE StatoilData diff --git a/ThirdParty/Ert/devel/CMakeLists.txt b/ThirdParty/Ert/devel/CMakeLists.txt index 49c1750621..b435f95919 100644 --- a/ThirdParty/Ert/devel/CMakeLists.txt +++ b/ThirdParty/Ert/devel/CMakeLists.txt @@ -22,7 +22,7 @@ option( BUILD_ENS_PLOT "Build small Eclipse plotting program - no" OFF) option( BUILD_TESTS "Should the tests be built" OFF) option( BUILD_APPLICATIONS "Should we build small utility applications" OFF) option( BUILD_ECL_SUMMARY "Build the commandline application ecl_summary" OFF) -option( BUILD_PYTHON "Run py_compile on the python wrappers" OFF) +option( BUILD_PYTHON "Run py_compile on the python wrappers" ON) option( BUILD_SHARED_LIBS "Build shared libraries" ON ) option( INSTALL_ERT "Should anything be installed when issuing make install?" ON) option( ERT_BUILD_GUI "Should the pyQt based gui be compiled and installed" OFF ) @@ -84,8 +84,8 @@ if (ERT_USE_OPENMP) endif() -include(cmake/ert_check.cmake) include(cmake/ert_find.cmake) +include(cmake/ert_check.cmake) include(cmake/Modules/UseMultiArch.cmake) include(cmake/ert_link.cmake) @@ -207,10 +207,14 @@ endif() if (BUILD_PYTHON) - include(cmake/python.cmake2) - add_subdirectory( python ) - if(ERT_DOC) - add_subdirectory( docs ) + if (ERT_WINDOWS) + message(STATUS "Python is not supported on Windows") + else() + include(cmake/python.cmake2) + add_subdirectory( python ) + if(ERT_DOC) + add_subdirectory( docs ) + endif() endif() endif() diff --git a/ThirdParty/Ert/devel/cmake/ert_check.cmake b/ThirdParty/Ert/devel/cmake/ert_check.cmake index 5950d216a1..24c03a1543 100644 --- a/ThirdParty/Ert/devel/cmake/ert_check.cmake +++ b/ThirdParty/Ert/devel/cmake/ert_check.cmake @@ -1,3 +1,5 @@ +include(CheckSymbolExists) + check_function_exists( fseeko HAVE_FSEEKO ) if (HAVE_HFSEEKO) add_definitions( -DHAVE_FSEEKO ) @@ -110,6 +112,17 @@ if (HAVE__USLEEP) add_definitions( -DHAVE__USLEEP ) endif() +check_symbol_exists(_tzname time.h HAVE_WINDOWS_TZNAME) +if (HAVE_WINDOWS_TZNAME) + add_definitions(-DHAVE_WINDOWS_TZNAME) +else() + check_symbol_exists(tzname time.h HAVE_TZNAME) + if (HAVE_TZNAME) + add_definitions(-DHAVE_TZNAME) + else() + message(FATAL_ERROR "Could not find tzname global variable") + endif() +endif() check_function_exists(pthread_yield_np HAVE_YIELD_NP) if (HAVE_YIELD_NP) @@ -122,6 +135,11 @@ if (HAVE_YIELD) endif() +check_function_exists(pthread_timedjoin_np HAVE_TIMEDJOIN) +if (HAVE_TIMEDJOIN) + add_definitions(-DHAVE_TIMEDJOIN) +endif() + # Checking based on compiling. Some of the code generates warnings, so we just cut down to bare-bone compiler flags. set( CMAKE_C_FLAGS_main ${CMAKE_C_FLAGS} ) diff --git a/ThirdParty/Ert/devel/cmake/ert_find.cmake b/ThirdParty/Ert/devel/cmake/ert_find.cmake index 801134ded0..c4d448d6df 100644 --- a/ThirdParty/Ert/devel/cmake/ert_find.cmake +++ b/ThirdParty/Ert/devel/cmake/ert_find.cmake @@ -2,7 +2,7 @@ set(NEED_LIBDL OFF) find_library( DL_LIBRARY NAMES dl ) find_path( DLFUNC_HEADER dlfcn.h ) if (DL_LIBRARY AND DLFUNC_HEADER) - set(CMAKE_REQUIRED_LIBRARIES dl) + set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} dl) check_function_exists( dladdr HAVE_DLADDR ) if (HAVE_DLADDR) @@ -30,6 +30,7 @@ if (PTHREAD_LIBRARY) if (WITH_PTHREAD) add_definitions( -DWITH_PTHREAD ) endif() + set (CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} pthread) else() set( WITH_PTHREAD FALSE ) message("pthread library not found - pthread support will not be included") @@ -85,3 +86,7 @@ endif() if (ERT_WINDOWS) find_library( SHLWAPI_LIBRARY NAMES Shlwapi ) endif() + +if (UNIX) + set (CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} m) +endif(UNIX) diff --git a/ThirdParty/Ert/devel/cmake/python.cmake2 b/ThirdParty/Ert/devel/cmake/python.cmake2 index 99991808e9..414b9bbd9d 100644 --- a/ThirdParty/Ert/devel/cmake/python.cmake2 +++ b/ThirdParty/Ert/devel/cmake/python.cmake2 @@ -8,7 +8,11 @@ function(add_python_package target package_path source_files install_package) foreach (file ${source_files} ) set( source_file ${CMAKE_CURRENT_SOURCE_DIR}/${file} ) set( build_file ${PROJECT_BINARY_DIR}/${package_path}/${file} ) - set( install_file ${CMAKE_INSTALL_PREFIX}/${package_path}/${file} ) + if("$ENV{DESTDIR}" STREQUAL "") + set( install_file ${CMAKE_INSTALL_PREFIX}/${package_path}/${file} ) + else() + set( install_file $ENV{DESTDIR}/${CMAKE_INSTALL_PREFIX}/${package_path}/${file} ) + endif() add_custom_command( OUTPUT ${build_file} diff --git a/ThirdParty/Ert/devel/debian/control b/ThirdParty/Ert/devel/debian/control index 8198d32937..763f72dc09 100644 --- a/ThirdParty/Ert/devel/debian/control +++ b/ThirdParty/Ert/devel/debian/control @@ -2,7 +2,7 @@ Source: ert.ecl Priority: extra Maintainer: Arne Morten Kvarving <arne.morten.kvarving@sintef.no> Build-Depends: debhelper (>= 8.0.0), cmake, liblapack-dev, libquadmath0, - iputils-ping, zlib1g-dev, git + iputils-ping, zlib1g-dev, git, python-dev Standards-Version: 3.9.2 Section: libs Homepage: http://ert.nr.no @@ -24,3 +24,11 @@ Depends: ${shlibs:Depends}, ${misc:Depends} Description: The Ensemble based Reservoir Tool ERT - Ensemble based Reservoir Tool is a tool for managing en ensemble of reservoir models. + +Package: python-ert.ecl +Section: python +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends}, libert.ecl1 +Description: The Ensemble based Reservoir Tool - Python bindings + ERT - Ensemble based Reservoir Tool is a tool for managing en ensemble + of reservoir models. diff --git a/ThirdParty/Ert/devel/debian/rules b/ThirdParty/Ert/devel/debian/rules index f73eb28cac..c816b38cd0 100644 --- a/ThirdParty/Ert/devel/debian/rules +++ b/ThirdParty/Ert/devel/debian/rules @@ -13,4 +13,4 @@ dh $@ override_dh_auto_configure: - dh_auto_configure -- -DBUILD_SHARED_LIBS=1 -DBUILD_ECL_SUMMARY=1 -DCMAKE_BUILD_TYPE=Release + DESTDIR=$$(pwd)/debian/tmp dh_auto_configure -- -DBUILD_SHARED_LIBS=1 -DBUILD_ECL_SUMMARY=1 -DCMAKE_BUILD_TYPE=Release diff --git a/ThirdParty/Ert/devel/docs/user/distributions/index.rst b/ThirdParty/Ert/devel/docs/user/distributions/index.rst new file mode 100644 index 0000000000..c1b8f9ea94 --- /dev/null +++ b/ThirdParty/Ert/devel/docs/user/distributions/index.rst @@ -0,0 +1,141 @@ +.. toctree:: + :maxdepth: 1 + +.. _prior_distributions: + +Prior distributions avaliable in ERT +==================================== + +The :ref:`GEN_KW <gen_kw>` keyword is typically used in sensitivy +studies and as parameters which are updated with the Ensemble Smoother +in a model updating project. In your configuration file the +:ref:`GEN_KW <gen_kw>` keyword is configured as: + +:: + + GEN_KW ID my_template.txt my_eclipse_include.txt my_priors.txt + +The file ``my_priors.txt`` contains the names of the variables +you are considering, and specifies the distribution which should be +used for the initial sampling. + + +NORMAL +------ +To set a normal (Gaussian) prior, use the keyword NORMAL. It takes two +arguments, a mean value and a standard deviation. Thus, the following +example will assign a normal prior with mean 0 and standard deviation +1 to the variable VAR1: + +:: + + VAR1 NORMAL 0 1 + +LOGNORMAL +--------- +A stochastic variable is log normally distributed if the logarithm of +the variable is normally distributed. In other words, if X is normally +distributed, then Y = exp(X) is log normally distributed. + +A log normal prior is suited to model positive quanties with a heavy +tail (tendency to take large values). To set a log normal prior, use +the keyword LOGNORMAL. It takes two arguments, the mean and standard +deviation of the *logarithm* of the variable: + +:: + + VAR2 LOGNORMAL 0 + +TRUNCATED_NORMAL +----------------- + +This *TRUNCATED_NORMAL* distribution works as follows: + + 1. Draw random variable X ~ N(mu,std) + 2. Clamp X to the interval [min, max] + +This is **not** a proper truncated normal distribution; hence the +clamping to ``[min,max]` should be an exceptional event. To configure +this distribution for a situation with mean 1, standard deviation 0.25 +and hard limits 0 and 10: + +:: + + VAR3 TRUNCATED_NORMAL 1 0.25 0 10 + + +UNIFORM +------- + +A stochastic variable is uniformly distributed if has a constant +probability density on a closed interval. Thus, the uniform +distribution is completely characterized by it's minimum and maximum +value. To assign a uniform distribution to a variable, use the keyword +UNIFORM, which takes a minimum and a maximum value for a the +variable. Here is an example, which assigns a uniform distribution +between 0 and 1 to a variable ``VAR4``: + +:: + + VAR4 UNIFORM 0 1 + +It can be shown that among all distributions bounded below by a and +above by b, the uniform distribution with parameters a and b has the +maximal entropy (contains the least information). Thus, the uniform +distribution should be your preferred prior distribution for robust +modeling of bounded variables. + + +LOGUNIF +------- + +A stochastic variable is log uniformly distributed if it's logarithm +is uniformly distributed on the interval [a,b]. To assign a log +uniform distribution to a a variable, use the keyword LOGUNIF, which +takes a minimum and a maximum value for the output variable as +arguments. The example + +:: + + VAR5 LOGUNIF 0.00001 1 + +will give values in the range [0.00001,1] - with considerably more +weight towards the lower limit. The log uniform distribution is useful +when modeling a bounded positive variable who has most of it's +probability weight towards one of the bounds. + +CONST +----- + +The keyword CONST is used to assign a Dirac distribution to a +variable, i.e. set it to a constant value. Here is an example of use: + +:: + + CONST 1.0 + + + +Priors and transformations +========================== + +The Ensemble Smoother method, which ERT uses for updating of +parameters, works with normally distributed variables. So internally +in ERT the interplay between ``GEN_KW`` variables and updates is as +follows: + + 1. ERT samples a random variable ``x ~ N(0,1)`` - before outputing + to the forward model this is *transformed* to ``y ~ F(Y)`` where + the the distribution ``F(Y)`` is the correct prior distribution. + + 2. When the prior simulations are complete ERT calculates misfits + between simulated and observed values and *updates* the + parameters; hence the variables ``x`` now represent samples from + a posterior distribution which is Normal with mean and standard + deviation *different from (0,1)*. + +The transformation prescribed by ``F(y)`` still "works" - but it no +longer maps to a distribution in the same family as initially +specified by the prior. A consequence of this is that the update +process can *not* give you a posterior with updated parameters in the +same distribution family as the Prior. diff --git a/ThirdParty/Ert/devel/docs/user/index.rst b/ThirdParty/Ert/devel/docs/user/index.rst index 6fcb3255b6..8848329bc8 100644 --- a/ThirdParty/Ert/devel/docs/user/index.rst +++ b/ThirdParty/Ert/devel/docs/user/index.rst @@ -10,3 +10,5 @@ Contents: keywords/index workflows/index observations/index + distributions/index + localization/index diff --git a/ThirdParty/Ert/devel/docs/user/keywords/index.rst b/ThirdParty/Ert/devel/docs/user/keywords/index.rst index 17c5f28ce0..a7017fea43 100644 --- a/ThirdParty/Ert/devel/docs/user/keywords/index.rst +++ b/ThirdParty/Ert/devel/docs/user/keywords/index.rst @@ -767,22 +767,32 @@ The keywords in this section are used to define a parametrization of the ECLIPSE GEN_KW ID my_template.txt my_eclipse_include.txt my_priors.txt - Here ID is an (arbitrary) unique string, my_template.txt is the name of a template file, my_eclipse_include.txt is the name of the file which is made for each member based on my_template.txt and my_priors.txt is a file containing a list of parametrized keywords and a prior distribution for each. Note that you must manually edit the ECLIPSE data file so that my_eclipse_include.txt is included. + Here ID is an (arbitrary) unique string, my_template.txt is + the name of a template file, my_eclipse_include.txt is the + name of the file which is made for each member based on + my_template.txt and my_priors.txt is a file containing a list + of parametrized keywords and a prior distribution for + each. Note that you must manually edit the ECLIPSE data file + so that my_eclipse_include.txt is included. - Let us consider an example where the GEN_KW parameter type is used to estimate pore volume multipliers. We would then declare a GEN_KW instance in the main enkf configuration file: + Let us consider an example where the GEN_KW parameter type is + used to estimate pore volume multipliers. We would then + declare a GEN_KW instance in the main enkf configuration file: :: GEN_KW PAR_MULTPV multpv_template.txt multpv.txt multpv_priors.txt - In the GRID or EDIT section of the ECLIPSE data file, we would insert the following include statement: + In the GRID or EDIT section of the ECLIPSE data file, we would + insert the following include statement: :: INCLUDE 'multpv.txt' / - The template file multpv_template.txt would contain some parametrized ECLIPSE statements: + The template file multpv_template.txt would contain some + parametrized ECLIPSE statements: :: @@ -798,24 +808,37 @@ The keywords in this section are used to define a parametrization of the ECLIPSE 300*<MULTPV_BOX2> / ENDBOX - Here, <MULTPV_BOX1> and <MULTPV_BOX2> will act as magic strings. Note that the '<' '>' must be present around the magic strings. In this case, the parameter configuration file multpv_priors.txt could look like this: + Here, <MULTPV_BOX1> and <MULTPV_BOX2> will act as magic + strings. Note that the '<' '>' must be present around the + magic strings. In this case, the parameter configuration file + multpv_priors.txt could look like this: :: MULTPV_BOX2 UNIFORM 0.98 1.03 MULTPV_BOX1 UNIFORM 0.85 1.00 - In general, the first keyword on each line in the parameter configuration file defines a key, which when found in the template file enclosed in '<' and '>', is replaced with a value. The rest of the line defines a prior distribution for the key. See Prior distributions available in enkf for a list of available prior distributions. + In general, the first keyword on each line in the parameter + configuration file defines a key, which when found in the + template file enclosed in '<' and '>', is replaced with a + value. The rest of the line defines a prior distribution for + the key. See Prior distributions available in enkf for a list + of available prior distributions. **Example: Using GEN_KW to estimate fault transmissibility multipliers** - Previously enkf supported a datatype MULTFLT for estimating fault transmissibility multipliers. This has now been depreceated, as the functionality can be easily achieved with the help of GEN_KW. In th enkf config file: + Previously enkf supported a datatype MULTFLT for estimating + fault transmissibility multipliers. This has now been + depreceated, as the functionality can be easily achieved with + the help of GEN_KW. In th enkf config file: :: GEN_KW MY-FAULTS MULTFLT.tmpl MULTFLT.INC MULTFLT.txt - Here MY-FAULTS is the (arbitrary) key assigned to the fault multiplers, MULTFLT.tmpl is the template file, which can look like this: + Here MY-FAULTS is the (arbitrary) key assigned to the fault + multiplers, MULTFLT.tmpl is the template file, which can look + like this: :: @@ -824,22 +847,38 @@ The keywords in this section are used to define a parametrization of the ECLIPSE 'FAULT2' <FAULT2> / / - and finally the initial distribution of the parameters FAULT1 and FAULT2 are defined in the file MULTFLT.txt: + and finally the initial distribution of the parameters FAULT1 + and FAULT2 are defined in the file MULTFLT.txt: :: FAULT1 LOGUNIF 0.00001 0.1 FAULT2 UNIFORM 0.00 1.0 + The various prior distributions available for the ``GEN_KW`` + keyword are here :ref:`prior distributions available in ERT <prior_distributions>` + + Loading GEN_KW values from an external file - The default use of the GEN_KW keyword is to let the ERT application sample random values for the elements in the GEN_KW instance, but it is also possible to tell ERT to load a precreated set of data files, this can for instance be used as a component in a experimental design based workflow. When using external files to initialize the GEN_KW instances you supply an extra keyword INIT_FILE:/path/to/priors/files%d which tells where the prior files are: + The default use of the GEN_KW keyword is to let the ERT + application sample random values for the elements in the + GEN_KW instance, but it is also possible to tell ERT to load a + precreated set of data files, this can for instance be used as + a component in a experimental design based workflow. When + using external files to initialize the GEN_KW instances you + supply an extra keyword ``INIT_FILE:/path/to/priors/files%d`` + which tells where the prior files are: :: GEN_KW MY-FAULTS MULTFLT.tmpl MULTFLT.INC MULTFLT.txt INIT_FILES:priors/multflt/faults%d - In the example above you must prepare files priors/multflt/faults0, priors/multflt/faults1, ... priors/multflt/faultsn which ert will load when you initialize the case. The format of the GEN_KW input files can be of two varieties: + In the example above you must prepare files + priors/multflt/faults0, priors/multflt/faults1, + ... priors/multflt/faultsn which ert will load when you + initialize the case. The format of the GEN_KW input files can + be of two varieties: 1. The files can be plain ASCII text files with a list of numbers: diff --git a/ThirdParty/Ert/devel/docs/user/localization/index.rst b/ThirdParty/Ert/devel/docs/user/localization/index.rst new file mode 100644 index 0000000000..2095e12856 --- /dev/null +++ b/ThirdParty/Ert/devel/docs/user/localization/index.rst @@ -0,0 +1,917 @@ + +Keywords for the local configuration file +========================================= + + + +General overview +---------------- + +To create a configuration for localization you must "program" your own +configuration file, this file is then loaded from the ert/enkf proper +application. The 'commands' available in the local_config programming +language are listed below. + +An alterative way to 'program' the local config commands is by writing a Python script, and invoking it from a workflow. +Not all the commands available from the local config programming are supported for Python scripting. + + +**Local config ERT script example:** + +:: + + from ert.enkf import ErtScript + from ert.enkf import LocalConfig + + class LocalConfigJob(ErtScript): + + + def run(self): + + ert = self.ert() + local_config = ert.getLocalConfig() + + # Add your local config commands here + dataset_multflt = local_config.createDataset("DATASET_MULTFLT") + ... + + # Write to file for debugging + local_config.writeLocalConfigFile("tmp/debug_local_config.txt") + + + +List of keywords +---------------- +=========================================================================================== =========================================================== ============================================================================================================================================== +Keyword name ERT script function Purpose +=========================================================================================== =========================================================== ============================================================================================================================================== +:ref:`CREATE_MINISTEP <create_ministep>` createMinistep Creates ministep +:ref:`CREATE_UPDATESTEP <create_updatestep>` createUpdatestep Creates updatestep +:ref:`CREATE_DATASET <create_dataset>` createDataset Creates dataset +:ref:`COPY_DATASET <copy_dataset>` copyDataset Deep copy of dataset +:ref:`CREATE_OBSSET <create_obsset>` createObsdata Creates observation set +:ref:`COPY_OBSSET <copy_obsset>` copyObsdata Deep copy of observation set +:ref:`ATTACH_MINISTEP <attach_ministep>` attachMinistep Attaches ministep to update step +:ref:`ATTACH_DATASET <attach_dataset>` attachDataset Attaches dataset to mini step +:ref:`ATTACH_OBSSET <attach_obsset>` attachObsset Attaches observation set to mini step +:ref:`ADD_DATA <add_data>` addNode Adds data node to dataset +:ref:`DEL_DATA <del_data>` del Deletes observation node from dataset +:ref:`ADD_OBS <add_obs>` addNodeAndRange Adds observation node to observation set +:ref:`DEL_OBS <del_obs>` del Deletes observation node from observation set +:ref:`DATASET_DEL_ALL_DATA <dataset_del_all_data>` clear Delete all the data keys from a dataset +:ref:`ACTIVE_LIST_ADD_DATA_INDEX <active_list_add_data_index>` addActiveIndex Adds data index to the list of active indices +:ref:`ACTIVE_LIST_ADD_OBS_INDEX <active_list_add_obs_index>` addActiveIndex Adds observation index to the list of active indices +:ref:`ACTIVE_LIST_ADD_MANY_DATA_INDEX <active_list_add_many_data_index>` addActiveIndex Adds several data indices to the list of active indices +:ref:`ACTIVE_LIST_ADD_MANY_OBS_INDEX <active_list_add_many_obs_index>` addActiveIndex Adds several observation indinces to the list of active indices +:ref:`INSTALL_DEFAULT_UPDATESTEP <install_default_updatestep>` Installs default update step +:ref:`ADD_FIELD <add_field>` addField Adds field node to dataset +:ref:`LOAD_FILE <load_file>` EclGrid, EclInitFile, Loads eclipse file in restart format +:ref:`CREATE_ECLREGION <create_eclregion>` EclRegion Creates a new region for use when defining active regions for fields +:ref:`ECLREGION_SELECT_ALL <eclregion_select_all>` select_active Selects or deselects cells in a region +:ref:`ECLREGION_SELECT_VALUE_EQUAL <eclregion_select_value_equal>` select_equal Selects or deselects cells in a region equal to given value +:ref:`ECLREGION_SELECT_VALUE_LESS <eclregion_select_value_less>` select_less Selects or deselects cells in a region equal less than a given value +:ref:`ECLREGION_SELECT_VALUE_MORE <eclregion_select_value_more>` select_more Selects or deselects cells in a region equal greater than a given value +:ref:`ECLREGION_SELECT_BOX <eclregion_select_box>` select_box Selects or deselects cells in a box +:ref:`ECLREGION_SELECT_SLICE <eclregion_select_slice>` select_islice, select_jslice, select_kslice Selects or deselects cells in a slice +:ref:`ECLREGION_SELECT_PLANE <eclregion_select_plane>` select_below_plane Selects or deselects cells in a half space defined by a plane +:ref:`ECLREGION_SELECT_IN_POLYGON <eclregion_select_in_polygon>` select_inside_polygon Selects or deselects cells in region inside polygon +:ref:`CREATE_POLYGON <create_polygon>` :ref:`Example <create_polygon>` Creates a geo-polygon based on coordinate list +:ref:`LOAD_POLYGON <load_polygon>` :ref:`Example <load_polygon>` Loads polygon in Irap RMS format from file +:ref:`LOAD_SURFACE <load_surface>` Loads surface in Irap RMS format from file +:ref:`CREATE_SURFACE_REGION <create_surface_region>` Creates region to select or deselect parts of a surface +:ref:`SURFACE_REGION_SELECT_IN_POLYGON <surface_region_select_in_polygon>` Creates region to select or deselect parts of a surface +:ref:`SURFACE_REGION_SELECT_LINE <surface_region_select_line>` Selects or deselects parts of a surface in half space define by a line +:ref:`ADD_DATA_SURFACE <add_data_surface>` Adds surface node to dataset with elements in a surface region +=========================================================================================== =========================================================== ============================================================================================================================================== + +.. ########################################################################################################### + +.. _create_updatestep: +.. topic:: CREATE_UPDATESTEP + + | This function will create a new updatestep with the name 'NAME_OF_UPDATESTEP'. Observe that you must add (at least) one ministep to the updatestep, otherwise it will not be able to do anything. + + + *Example:* + + :: + + -- Update step in time interval 0->1 + CREATE_UPDATESTEP UPDATESTEP_0_1 + + + *Example:* + + :: + + update_step_0_1 = local_config.createUpdatestep("UPDATESTEP_0_1") + + +.. ########################################################################################################### + + +.. _create_ministep: +.. topic:: CREATE_MINISTEP + + | This function will create a new ministep with the name 'NAME_OF_MINISTEP'. A given OBSSET can be attached to a given ministep.The ministep is then ready for adding data. Before the ministep can be used you must attach it to an updatestep with the ATTACH_MINISTEP command + + *Example:* + + :: + + -- Mini step 0 in update step 0->1 + CREATE_MINISTEP MINISTEP_0_1_0 + + *Example:* + + :: + + ministep_0_1_0 = local_config.createMinistep("MINISTEP_0_1_0") + + + +.. ########################################################################################################### + +.. _create_dataset: +.. topic:: CREATE_DATASET + + | This function will create a new dataset, i.e. a collection of enkf_nodes which should be updated together. Before you can actually use a dataset you must attach it to a ministep with the ATTACH_DATASET command. + + *Example:* + + :: + + -- Create a DATASET_MULTFLT dataset + CREATE_DATASET DATASET_MULTFLT + + *Example:* + + :: + + dataset_multflt = local_config.createDataset("DATASET_MULTFLT") + +.. ########################################################################################################### + +.. _copy_dataset: +.. topic:: COPY_DATASET + + | Will create a new local_obsset instance which is a copy of the 'SRC_OBSSET'; this is a deep copy where also the lowest level active_list instances are copied, and can then subsequently be updated independently of each other. + + + *Example:* + + :: + + -- Deep copy DATASET_MULTFLT dataset + COPY_DATASET DATASET_MULTFLT COPY_DATASET_MULTFLT + +.. ########################################################################################################### + +.. _create_obsset: +.. topic:: CREATE_OBSSET + + | This function will create an observation set, i.e. a collection of observation keys which will be used as the observations in one ministep. Before the obsset can be used it must be attached to a ministep with the ATTACH_OBSSET command. + + + *Example:* + + :: + + -- Create a OBS_WELL obsset + CREATE_OBSSET OBS_WELL + + *Example:* + + :: + + obsset_obs_well = local_config.createObsdata("OBS_WELL") + + +.. ########################################################################################################### + +.. _copy_obsset: +.. topic:: COPY_OBSSET + + | Will create a new local_obsset instance which is a copy of the 'SRC_OBSSET'; this is a deep copy where also the lowest level active_list instances are copied, and can then subsequently be updated independently of each other. + + + *Example:* + + :: + + -- Deep copy OBS_WELL observation set + COPY_OBSSET OBS_WELL COPY_OBS_WELL + +.. ########################################################################################################### + +.. _attach_ministep: +.. topic:: ATTACH_MINISTEP + + | This function will attach the ministep 'NAME_OF_MINISTEP' to the updatestep 'NAME_OF_UPDATESTEP'; one ministep can be attached to many updatesteps. + + *Example:* + + :: + + -- Attach MINISTEP_0_1_0 to UPDATESTEP_0_1 + ATTACH_MINISTEP UPDATESTEP_0_1 MINISTEP_0_1_0 + + *Example:* + + :: + + update_step_0_1.attachMinistep(ministep_0_1_0) + + +.. ########################################################################################################### + +.. _attach_dataset: +.. topic:: ATTACH_DATASET + + | Will attach the dataset 'NAME_OF_DATASET' to the ministep given by 'NAME_OF_MINISTEP'. + + *Example:* + + :: + + -- Attach DATASET_MULTFLT to MINISTEP_0_1_0 + ATTACH_MINISTEP MINISTEP_0_1_0 DATASET_MULTFLT + + *Example:* + + :: + + ministep_0_1_0.attachDataset(dataset_multflt) + + +.. ########################################################################################################### + +.. _attach_obsset: +.. topic:: ATTACH_OBSSET + + | Will attach the obsset 'NAME_OF_OBSSET' to the ministep given by 'NAME_OF_MINISTEP'. + + *Example:* + + :: + + -- Attach OBS_WELL to MINISTEP_0_1_0 + ATTACH_MINISTEP MINISTEP_0_1_0 OBS_WELL + + *Example:* + + :: + + ministep_0_1_0.attachObsset(obsset_obs_well) + + +.. ########################################################################################################### + +.. _add_data: +.. topic:: ADD_DATA + + | This function will install 'KEY' as one enkf node which should be updated in this dataset. If you do not manipulate the KEY further with the ACTIVE_LIST_ADD_DATA_INDEX function the KEY will be added as 'ALL_ACTIVE', i.e. all elements will be updated. + + + *Example:* + + :: + + -- Add data node to data set + ADD_DATA DATASET_MULTFLT MULTFLT + + *Example:* + + :: + + dataset_multflt.addNode("MULTFLT") + +.. ########################################################################################################### + +.. _del_data: +.. topic:: DEL_DATA + + | This function will delete the data 'KEY' from the dataset 'NAME_OF_DATASET'. + + + *Example:* + + :: + + -- Delete data node from data set + DEL_DATA DATASET_MULTFLT MULTFLT + + *Example:* + + :: + + del dataset_multflt["MULTFLT"] + + +.. ########################################################################################################### + +.. _add_obs: +.. topic:: ADD_OBS + + | This function will install the observation 'OBS_KEY' as an observation for this obsset - similarly to the ADD_DATA function. + + + *Example:* + + :: + + -- Add data node to observation set + ADD_OBS OBS_WELL WOPR:OBS_WELL + + *Example:* + + :: + + -- The obsset has a time range + obsset_obs_well.addNodeAndRange("WOPR:OBS_WELL", 0, 1) + + +.. ########################################################################################################### + +.. _del_obs: +.. topic:: DEL_OBS + + | This function will delete the obs 'OBS_KEY' from the obsset 'NAME_OF_OBSSET'. + + + *Example:* + + :: + + -- Delete data node from observation set + DEL_OBS OBS_WELL WOPR:OBS_WELL + + *Example:* + + :: + + del obsset_obs_well["WOPR:OBS_WELL"] + + +.. ########################################################################################################### + +.. _dataset_del_all_data: +.. topic:: DATASET_DEL_ALL_DATA + + | This function will delete all the data keys from the dataset 'NAME_OF_DATASET'. + + + *Example:* + + :: + + -- Delete all data nodes from DATASET_MULTFLT + DATASET_DEL_ALL_DATA DATASET_MULTFLT + + *Example:* + + :: + + dataset_multflt.clear() + +.. ########################################################################################################### + +.. _active_list_add_data_index: +.. topic:: ACTIVE_LIST_ADD_DATA_INDEX + + | This function will say that the data with name 'DATA_KEY' in dataset with name 'DATASTEP_NAME' should have the index 'INDEX' active. + + + *Example:* + + :: + + -- Add index 0 from data MULTFLT to dataset DATASET_MULTFLT + ACTIVE_LIST_ADD_DATA_INDEX DATASET_MULTFLT MULTFLT 0 + + *Example:* + + :: + + active_list = dataset_multflt.getActiveList("MULTFLT") + active_list.addActiveIndex(0); + +.. ########################################################################################################### + +.. _active_list_add_obs_index: +.. topic:: ACTIVE_LIST_ADD_OBS_INDEX + + | This function will say that the observation with name 'OBS_KEY' in obsset with name 'OBSSET_NAME' should have the index 'INDEX' active. + + + *Example:* + + :: + + -- Add index 0 from data WOPR:OBS_WELL to obsset OBS_WELL + ACTIVE_LIST_ADD_OBS_INDEX OBS_WELL WOPR:OBS_WELL 0 + + *Example:* + + :: + + active_list = obsset_obs_well.getActiveList("WOPR:OBS_WELL") + active_list.addActiveIndex(0); + +.. ########################################################################################################### + +.. _active_list_add_many_data_index: +.. topic:: ACTIVE_LIST_ADD_MANY_DATA_INDEX + + | This function is similar to ACTIVE_LIST_ADD_DATA_INDEX, but it will add many indices. + + + *Example:* + + :: + + -- Add indices 0, 1 and 2 from data MULTFLT to dataset DATASET_MULTFLT + ACTIVE_LIST_ADD_MANY_DATA_INDEX DATASET_MULTFLT MULTFLT 0 1 2 + + +.. ########################################################################################################### + +.. _active_list_add_many_obs_index: +.. topic:: ACTIVE_LIST_ADD_MANY_OBS_INDEX + + | This function is similar to ACTIVE_LIST_ADD_OBS_INDEX, but it will add many indices. + + + *Example:* + + :: + + -- Add index 0, 1 and 2 from data WOPR:OBS_WELL to obsset OBS_WELL + ACTIVE_LIST_ADD_MANY_OBS_INDEX OBS_WELL WOPR:OBS_WELL 0 1 2 + +.. ########################################################################################################### + + +.. _install_default_updatestep: +.. topic:: INSTALL_DEFAULT_UPDATESTEP + + | This function will install 'NAME_OF_UPDATESTEP' as the default updatestep which applies to all report steps where you have not explicitly set another updatestep with the INSTALL_UPDATESTEP function. + + + + *Example:* + + :: + + -- Install default update step + INSTALL_DEFAULT_UPDATESTEP ALL_ACTIVE + + + +.. ########################################################################################################### + +.. _add_field: +.. topic:: ADD_FIELD + + | This function will install the node with name 'FIELD_NAME' in the dataset 'DATASET_NAME'. It will in addition select all the (currently) active cells in the region 'ECLREGION_NAME' as active for this field/ministep combination. The ADD_FIELD command is actually a shortcut of: ADD_DATA DATASET FIELD_NAME; followed by: ACTIVE_LIST_ADD_MANY_DATA_INDEX <All the indices from the region> + + + + *Example:* + + :: + + -- Add data node PORO to data set DATA_PORO activating indices in ECLREG_PORO + ADD_FIELD DATA_PORO PORO ECLREG_PORO + + *Example:* + + :: + + # Load Eclipse grid + ecl_grid = EclGrid("path/to/LOCAL.GRDECL") + + with open("path/to/LOCAL.GRDECL","r") as fileH: + local_kw = Ecl3DKW.read_grdecl(ecl_grid, fileH, "LOCAL") + + # Define Eclipse region + eclreg_poro = EclRegion(ecl_grid, False) + eclreg_poro.select_more(local_kw, 1) + + # Create dataset and add field to dataset + data_poro = local_config.createDataset("DATA_PORO") + data_poro.addField("PORO", eclreg_poro) + + +.. ########################################################################################################### + +.. _load_file: +.. topic:: LOAD_FILE + + | This function will load an ECLIPSE file in restart format (i.e. restart file or INIT file), the keywords in this file can then subsequently be used in ECLREGION_SELECT_VALUE_XXX commands below. The 'KEY' argument is a string which will be used later when we refer to the content of this file + + + + + *Example:* + + :: + + -- Load Eclipse init file + LOAD_FILE REFINIT path/to/FULLMODEL.INIT + + *Example:* + + :: + + # Load Eclipse grid and init file + ecl_grid = EclGrid("path/to/FULLMODEL.GRDECL") + refinit_file = EclInitFile(grid , "path/to/somefile.init") + +.. ########################################################################################################### + +.. _create_eclregion: +.. topic:: CREATE_ECLREGION + + | This function will create a new region 'ECLREGION_NAME', which can subsequently be used when defining active regions for fields. The second argument, SELECT_ALL, is a boolean value. If this value is set to true the region will start with all cells selected, if set to false the region will start with no cells selected. + + + *Example:* + + :: + + -- New Eclipse region with all cells inactive + CREATE_ECLREGION ECL_REGION FALSE + + *Example:* + + :: + + # Define Eclipse region + eclreg_poro = EclRegion(ecl_grid, False) + +.. ########################################################################################################### + +.. _eclregion_select_all: +.. topic:: ECLREGION_SELECT_ALL + + | Will select all the cells in the region (or deselect if SELECT == FALSE). + + + + + + *Example:* + + :: + + -- Select cells in region + ECLREGION_SELECT_ALL ECL_REGION TRUE + + + *Example:* + + :: + + eclreg_poro.select_active() + + + + +.. ########################################################################################################### + +.. _eclregion_select_value_equal: +.. topic:: ECLREGION_SELECT_VALUE_EQUAL + + | This function will compare an ecl_kw instance loaded from file with a user supplied value, and select (or deselect) all cells which match this value. It is assumed that the ECLIPSE keyword is an INTEGER keyword, for float comparisons use the ECLREGION_SELECT_VALUE_LESS and ECLREGION_SELECT_VALUE_MORE functions. + + + + + + + *Example:* + + :: + + -- Select cells in region ECL_REGION equal to 0 + ECLREGION_SELECT_VALUE_EQUAL ECL_REGION ECL_REGION:LOCAL 0 TRUE + + + *Example:* + + :: + + # Load Eclipse grid + ecl_grid = EclGrid("path/to/LOCAL.GRDECL") + + with open("path/to/LOCAL.GRDECL","r") as fileH: + local_kw = Ecl3DKW.read_grdecl(ecl_grid, fileH, "LOCAL", ecl_type= EclTypeEnum.ECL_INT_TYPE) + + # Define Eclipse region + eclreg_poro = EclRegion(ecl_grid, False) + eclreg_poro.select_equal(local_kw, 1) + print 'GRID LOADED%s' % ecl_grid + print ecl_grid.getDims() + print local_kw.header + + + +.. ########################################################################################################### + +.. _eclregion_select_value_less: +.. topic:: ECLREGION_SELECT_VALUE_LESS + + | This function will compare an ecl_kw instance loaded from disc with a numerical value, and select all cells which have numerical below the limiting value. The ecl_kw value should be a floating point value like e.g. PRESSURE or PORO. The arguments are just as for ECLREGION_SELECT_VALUE_EQUAL. + + + + + + *Example:* + + :: + + -- Select cells in region ECL_REGION less than 1 + ECLREGION_SELECT_VALUE_LESS ECL_REGION ECL_REGION:LOCAL 1 TRUE + + *Example:* + + :: + + eclreg_poro.select_less(local_kw, 1) + + +.. ########################################################################################################### + +.. _eclregion_select_value_more: +.. topic:: ECLREGION_SELECT_VALUE_MORE + + | This function will compare an ecl_kw instance loaded from disc with a numerical value, and select all cells which have numerical above the limiting value. The ecl_kw value should be a floating point value like e.g. PRESSURE or PORO. The arguments are just as for ECLREGION_SELECT_VALUE_EQUAL. + + + + + + *Example:* + + :: + + -- Select cells in region ECL_REGION greater than 0 + ECLREGION_SELECT_VALUE_MORE ECL_REGION ECL_REGION:LOCAL 0 TRUE + + *Example:* + + :: + + eclreg_poro.select_more(local_kw, 1) + +.. ########################################################################################################### + +.. _eclregion_select_box: +.. topic:: ECLREGION_SELECT_BOX + + | This function will select (or deselect) all the cells in the box defined by the six coordinates i1 i2 j1 j2 k1 k2. The coordinates are inclusive, and the counting starts at 1. + + + + + *Example:* + + :: + + -- Select cells in box [0,1] x [2,3] x [4,5] + ECLREGION_SELECT_BOX ECL_REGION 0 1 2 3 4 5 TRUE + + *Example:* + + :: + + eclreg_poro.select_box((0,2,4),(1,3,5)) + + + +.. ########################################################################################################### + +.. _eclregion_select_slice: +.. topic:: ECLREGION_SELECT_SLICE + + | This function will select a slice in the direction given by 'dir', which can 'x', 'y' or 'z'. Depending on the value of 'dir' the numbers n1 and n2 are interpreted as (i1 i2), (j1 j2) or (k1 k2) respectively. The numbers n1 and n2 are inclusice and the counting starts at 1. It is OK to use very high/low values to imply "the rest of the cells" in one direction. + + + + *Example:* + + :: + + -- Select layer from z=2 to z=3 + ECLREGION_SELECT_SLICE ECL_REGION z 2 3 TRUE + + *Example:* + + :: + + eclreg_poro.select_kslice(2,3) + + +.. ########################################################################################################### + +.. _eclregion_select_plane: +.. topic:: ECLREGION_SELECT_PLANE + + | Will select all points which have positive (sign > 0) distance to the plane defined by normal vector n = (nx,ny,nz) and point p = (px,py,pz). If sign < 0 all cells with negative distance to plane will be selected. + + + *Example:* + + :: + + -- Select half space defined by plane perpendicular to vector [1 1 1] + ECLREGION_SELECT_PLANE ECL_REGION 1 1 1 0 0 0 -1 TRUE + + *Example:* + + :: + + eclreg_poro.select_below_plane((1,1,1),(0,0,0)) + + +.. ########################################################################################################### + +.. _eclregion_select_in_polygon: +.. topic:: ECLREGION_SELECT_IN_POLYGON + + | Well select all the points which are inside the polygon with name 'POLYGON_NAME'. The polygon should have been created with command CREATE_POLYGON or loaded with command 'LOAD_POLYGON' first. + + + + + *Example:* + + :: + + -- Select region inside polygon in xy plane + ECLREGION_SELECT_IN_POLYGON POLYGON TRUE + + *Example:* + + :: + + polygon = [(0,0) , (0,1) , (1,0)] + eclreg_poro.select_inside_polygon(polygon) + +.. ########################################################################################################### + +.. _create_polygon: +.. topic:: CREATE_POLYGON + + | Will create a geo_polygon instance based on the coordinate list: (x1,y1), (x2,y2), (x3,y3), ... The polygon should not be explicitly closed - i.e. you should in general have (x1,y1) != (xn,yn). The polygon will be stored under the name 'POLYGON_NAME' - which should later be used when referring to the polygon in region select operations. + + + + *Example:* + + :: + + -- Create polygon in xy plane + CREATE_POLYGON POLYGON 0 0 0 1 1 0 TRUE + + *Example:* + + :: + + polygon = [(0,0) , (0,1) , (1,0)] + +.. ########################################################################################################### + +.. _load_polygon: +.. topic:: LOAD_POLYGON + + | Will load a polygon instance from the file 'FILENAME' - the file should be in irap RMS format. The polygon will be stored under the name 'POLYGON_NAME' which can then later be used to refer to the polygon for e.g. select operations. + + + + + + *Example:* + + :: + + -- Load polygon from RMS file + LOAD_POLYGON path/to/polygon.irap + + *Example:* + + :: + + polygon = [] + with open("polygon.ply","r") as fileH: + for line in fileH.readlines(): + tmp = line.split() + polygon.append( (float(tmp[0]) , float(tmp[1]))) + +.. ########################################################################################################### + +.. _load_surface: +.. topic:: LOAD_SURFACE + + | Will load an irap surface from file 'SURFACE_FILE'. The surface will be stored internally as 'SURFACE_NAME' - this function is mainly needed to have a base surface available for the CREATE_SURFACE_REGION command. + + + + + + + *Example:* + + :: + + -- Load Irap RMS surface from file + LOAD_SURFACE path/to/surface.irap + +.. ########################################################################################################### + +.. _create_surface_region: +.. topic:: CREATE_SURFACE_REGION + + | Will create a new surface region object which can be used to select and deselect parts of a surface. The region will be called 'REGION_NAME' and it will be based on the surface given by 'BASE_SURFACE'. 'PRESELECT' is a boolean 'TRUE' or 'FALSE' which determines whether the region is created with all points selected, or no points selected. + + + + *Example:* + + :: + + -- Create surface region in xy plane + CREATE_SURFACE_REGION SURF_REGION BASE_SURFACE TRUE + +.. ########################################################################################################### + +.. _surface_region_select_in_polygon: +.. topic:: SURFACE_REGION_SELECT_IN_POLYGON + + | Well select all the points which are inside the polygon with name 'POLYGON_NAME'. The polygon should have been created with command CREATE_POLYGON or loaded with command 'LOAD_POLYGON' first. + + + + + + + + *Example:* + + :: + + -- Select surface region inside polygon + SURFACE_REGION_SELECT_IN_POLYGON SURF_REGION TRIANGLE TRUE + + +.. ########################################################################################################### + +.. _surface_region_select_line: +.. topic:: SURFACE_REGION_SELECT_LINE + + | Well select|deselect all the points which are above|below the line: (x1,y1) -> (x2,y2). If SIGN is positive the select will apply to all points with a positive (right hand system) distance to the line; if SIGN is negative the selector will apply to all points with a negative distance to the line. + + + + + + + + + *Example:* + + :: + + -- Select surface region inside a half space defined by a line from [0,0] to [1,1] + SURFACE_REGION_SELECT_LINE SURF_REGION 0 0 1 1 -1 TRUE + +.. ########################################################################################################### + +.. _add_data_surface: +.. topic:: ADD_DATA_SURFACE + + | Will add the node 'SURFACE_NAME' (not one of the loaded surfaces, but an enkf_node object) to the dataset 'DATASET_NAME'. Only the elements in the region 'REGION_NAME' will be added. Typically SURFACE_REGION_SELECT_xxxx has been used first to build a suitable region selection. + + + + + + + + + + *Example:* + + :: + + -- Add EnKF node object to dataset DATA_MULTFLT, with elements in SURF_REGION from BASE_SURFACE + ADD_DATA_SURFACE DATA_MULTFLT BASE_SURFACE SURF_REGION + + + +.. ########################################################################################################### + + + diff --git a/ThirdParty/Ert/devel/libconfig/src/config_content_node.c b/ThirdParty/Ert/devel/libconfig/src/config_content_node.c index 5966a6120f..939b55cfe5 100644 --- a/ThirdParty/Ert/devel/libconfig/src/config_content_node.c +++ b/ThirdParty/Ert/devel/libconfig/src/config_content_node.c @@ -1,19 +1,19 @@ /* - Copyright (C) 2012 Statoil ASA, Norway. - - The file 'config_content_node.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> - for more details. + Copyright (C) 2012 Statoil ASA, Norway. + + The file 'config_content_node.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> + for more details. */ #include <stdbool.h> @@ -30,7 +30,7 @@ #define CONFIG_CONTENT_NODE_ID 6752887 struct config_content_node_struct { UTIL_TYPE_ID_DECLARATION; - const config_schema_item_type * schema; + const config_schema_item_type * schema; stringlist_type * stringlist; /* The values which have been set. */ const config_path_elm_type * cwd; stringlist_type * string_storage; @@ -59,7 +59,7 @@ void config_content_node_add_value(config_content_node_type * node , const char void config_content_node_set(config_content_node_type * node , const stringlist_type * token_list) { int argc = stringlist_get_size( token_list ) - 1; - for (int iarg=0; iarg < argc; iarg++) + for (int iarg=0; iarg < argc; iarg++) config_content_node_add_value( node , stringlist_iget( token_list , iarg + 1)); } @@ -149,7 +149,7 @@ const char * config_content_node_iget_as_path(config_content_node_type * node , const char * config_value = config_content_node_iget(node , index); char * path_value = config_path_elm_alloc_path( node->cwd , config_value ); config_content_node_push_string( node , path_value ); - + return path_value; } } @@ -161,7 +161,7 @@ const char * config_content_node_iget_as_abspath( config_content_node_type * nod const char * config_value = config_content_node_iget(node , index); char * path_value = config_path_elm_alloc_abspath( node->cwd , config_value ); config_content_node_push_string( node , path_value ); - + return path_value; } } @@ -173,7 +173,7 @@ const char * config_content_node_iget_as_relpath( config_content_node_type * nod const char * config_value = config_content_node_iget(node , index); char * path_value = config_path_elm_alloc_relpath( node->cwd , config_value ); config_content_node_push_string( node , path_value ); - + return path_value; } } @@ -216,13 +216,13 @@ const config_path_elm_type * config_content_node_get_path_elm( const config_cont Which will be inserted in the opt_hash dictionary as : {"KEY1" : "VALUE1" , ... } Elements which do not conform to this syntax are - ignored. + ignored. */ - + void config_content_node_init_opt_hash( const config_content_node_type * node , hash_type * opt_hash , int elm_offset) { int i; - for (i = elm_offset; i < config_content_node_get_size( node ); i++) + for (i = elm_offset; i < config_content_node_get_size( node ); i++) hash_add_option( opt_hash , config_content_node_iget( node , i )); } diff --git a/ThirdParty/Ert/devel/libecl/include/ert/ecl/ecl_grid.h b/ThirdParty/Ert/devel/libecl/include/ert/ecl/ecl_grid.h index 3c89292906..a11c7e34d8 100644 --- a/ThirdParty/Ert/devel/libecl/include/ert/ecl/ecl_grid.h +++ b/ThirdParty/Ert/devel/libecl/include/ert/ecl/ecl_grid.h @@ -56,6 +56,10 @@ extern "C" { void ecl_grid_get_cell_corner_xyz1(const ecl_grid_type * grid , int global_index , int corner_nr , double * xpos , double * ypos , double * zpos ); void ecl_grid_get_corner_xyz(const ecl_grid_type * grid , int i , int j , int k, double * xpos , double * ypos , double * zpos ); + double ecl_grid_get_cell_dx1( const ecl_grid_type * grid , int global_index ); + double ecl_grid_get_cell_dx3( const ecl_grid_type * grid , int i , int j , int k); + double ecl_grid_get_cell_dy1( const ecl_grid_type * grid , int global_index ); + double ecl_grid_get_cell_dy3( const ecl_grid_type * grid , int i , int j , int k); double ecl_grid_get_cell_thickness3( const ecl_grid_type * grid , int i , int j , int k); double ecl_grid_get_cell_thickness1( const ecl_grid_type * grid , int global_index ); double ecl_grid_get_cdepth1(const ecl_grid_type * grid , int global_index); diff --git a/ThirdParty/Ert/devel/libecl/include/ert/ecl/ecl_sum_tstep.h b/ThirdParty/Ert/devel/libecl/include/ert/ecl/ecl_sum_tstep.h index c0f285e49f..ec5a6da2e7 100644 --- a/ThirdParty/Ert/devel/libecl/include/ert/ecl/ecl_sum_tstep.h +++ b/ThirdParty/Ert/devel/libecl/include/ert/ecl/ecl_sum_tstep.h @@ -52,7 +52,11 @@ typedef struct ecl_sum_tstep_struct ecl_sum_tstep_type; void ecl_sum_tstep_fwrite( const ecl_sum_tstep_type * ministep , const int_vector_type * index_map , fortio_type * fortio); void ecl_sum_tstep_iset( ecl_sum_tstep_type * tstep , int index , float value); void ecl_sum_tstep_set_from_node( ecl_sum_tstep_type * tstep , const smspec_node_type * smspec_node , float value); + void ecl_sum_tstep_set_from_key( ecl_sum_tstep_type * tstep , const char * gen_key , float value); + double ecl_sum_tstep_get_from_key( const ecl_sum_tstep_type * tstep , const char * gen_key); + bool ecl_sum_tstep_has_key(const ecl_sum_tstep_type * tstep , const char * gen_key); + bool ecl_sum_tstep_sim_time_equal( const ecl_sum_tstep_type * tstep1 , const ecl_sum_tstep_type * tstep2 ); UTIL_SAFE_CAST_HEADER( ecl_sum_tstep ); diff --git a/ThirdParty/Ert/devel/libecl/include/ert/ecl/ecl_util.h b/ThirdParty/Ert/devel/libecl/include/ert/ecl/ecl_util.h index df304122ab..9c2b0441c7 100644 --- a/ThirdParty/Ert/devel/libecl/include/ert/ecl/ecl_util.h +++ b/ThirdParty/Ert/devel/libecl/include/ert/ecl/ecl_util.h @@ -42,20 +42,6 @@ typedef enum { ECL_OTHER_FILE = 0 , ECL_DATA_FILE = 512 } ecl_file_enum; -#define ECL_FILE_ENUM_DEFS {.value = 0 , .name="ECL_OTHER_FILE"}, \ -{.value = 1 , .name="ECL_RESTART_FILE"}, \ -{.value = 2 , .name="ECL_UNIFIED_RESTART_FILE"}, \ -{.value = 4 , .name="ECL_SUMMARY_FILE"}, \ -{.value = 8 , .name="ECL_UNIFIED_SUMMARY_FILE"}, \ -{.value = 16 , .name="ECL_SUMMARY_HEADER_FILE"}, \ -{.value = 32 , .name="ECL_GRID_FILE"}, \ -{.value = 64 , .name="ECL_EGRID_FILE"}, \ -{.value = 128 , .name="ECL_INIT_FILE"}, \ -{.value = 256 , .name="ECL_RFT_FILE"}, \ -{.value = 512 , .name="ECL_DATA_FILE"} -#define ECL_FILE_ENUM_SIZE 11 - - /* This enum enumerates the four different ways summary and restart information diff --git a/ThirdParty/Ert/devel/libecl/include/ert/ecl/layer.h b/ThirdParty/Ert/devel/libecl/include/ert/ecl/layer.h index fae3e71479..639d418c51 100644 --- a/ThirdParty/Ert/devel/libecl/include/ert/ecl/layer.h +++ b/ThirdParty/Ert/devel/libecl/include/ert/ecl/layer.h @@ -78,6 +78,7 @@ extern "C" { void layer_update_active( layer_type * layer , const ecl_grid_type * grid , int k); void layer_cells_equal( const layer_type * layer , int value , int_vector_type * i_list , int_vector_type * j_list); + int layer_count_equal( const layer_type * layer , int value ); UTIL_IS_INSTANCE_HEADER( layer ); UTIL_SAFE_CAST_HEADER( layer ); diff --git a/ThirdParty/Ert/devel/libecl/src/ecl_file.c b/ThirdParty/Ert/devel/libecl/src/ecl_file.c index 4894d490fa..8e91a857f4 100644 --- a/ThirdParty/Ert/devel/libecl/src/ecl_file.c +++ b/ThirdParty/Ert/devel/libecl/src/ecl_file.c @@ -742,11 +742,6 @@ void ecl_file_fprintf_kw_list( const ecl_file_type * ecl_file , FILE * stream ) file_map_fprintf_kw_list( ecl_file->active_map , stream ); } -#ifdef HAVE_FORK -const char * ecl_file_enum_iget( int index , int * value) { - return util_enum_iget( index , ECL_FILE_ENUM_SIZE , (const util_enum_element_type []) { ECL_FILE_ENUM_DEFS } , value); -} -#endif /*****************************************************************/ diff --git a/ThirdParty/Ert/devel/libecl/src/ecl_grid.c b/ThirdParty/Ert/devel/libecl/src/ecl_grid.c index 9edcf66382..0f41998c79 100644 --- a/ThirdParty/Ert/devel/libecl/src/ecl_grid.c +++ b/ThirdParty/Ert/devel/libecl/src/ecl_grid.c @@ -639,6 +639,7 @@ struct ecl_grid_struct { but in cases with skewed cells this has proved numerically challenging. */ bool is_metric; + int eclipse_version; }; @@ -1338,6 +1339,7 @@ static ecl_grid_type * ecl_grid_alloc_empty(ecl_grid_type * global_grid , int du grid->parent_grid = NULL; grid->children = hash_alloc(); grid->coarse_cells = vector_alloc_new(); + grid->eclipse_version = 0; return grid; } @@ -2283,8 +2285,12 @@ static void ecl_grid_init_nnc_cells( ecl_grid_type * grid1, ecl_grid_type * grid */ static void ecl_grid_init_nnc(ecl_grid_type * main_grid, ecl_file_type * ecl_file) { int num_nnchead_kw = ecl_file_get_num_named_kw( ecl_file , NNCHEAD_KW ); - int i; + + if(num_nnchead_kw > 0 && main_grid->eclipse_version == 2015){ + return; //Eclipse 2015 has an error with nnc. + } + for (i = 0; i < num_nnchead_kw; i++) { ecl_file_push_block(ecl_file); /* <---------------------------------------------------------------- */ ecl_file_select_block(ecl_file , NNCHEAD_KW , i); @@ -2366,11 +2372,15 @@ static ecl_grid_type * ecl_grid_alloc_EGRID__( ecl_grid_type * main_grid , const ecl_kw_type * actnum_kw = NULL; ecl_kw_type * mapaxes_kw = NULL; int dualp_flag; + int eclipse_version; if (grid_nr == 0) { ecl_kw_type * filehead_kw = ecl_file_iget_named_kw( ecl_file , FILEHEAD_KW , grid_nr); dualp_flag = ecl_kw_iget_int( filehead_kw , FILEHEAD_DUALP_INDEX ); - } else + eclipse_version = ecl_kw_iget_int( filehead_kw, FILEHEAD_YEAR_INDEX); + } else{ dualp_flag = main_grid->dualp_flag; + eclipse_version = main_grid->eclipse_version; + } /** If ACTNUM is not present - that is is interpreted as - all active. */ @@ -2399,6 +2409,7 @@ static ecl_grid_type * ecl_grid_alloc_EGRID__( ecl_grid_type * main_grid , const corsnum_kw ); if (ECL_GRID_MAINGRID_LGR_NR != grid_nr) ecl_grid_set_lgr_name_EGRID(ecl_grid , ecl_file , grid_nr); + ecl_grid->eclipse_version = eclipse_version; return ecl_grid; } } @@ -4311,21 +4322,44 @@ double ecl_grid_get_cell_thickness3( const ecl_grid_type * grid , int i , int j +double ecl_grid_get_cell_dx1( const ecl_grid_type * grid , int global_index ) { + fprintf(stderr , "** WARNING: The ecl_grid_get_cell_dx1() function is only a stub returning -1.\n"); + fprintf(stderr , " If you need a correct value for cell dx you must rebuild a new ert version.\n"); + return -1; +} + + +double ecl_grid_get_cell_dx3( const ecl_grid_type * grid , int i , int j , int k) { + const int global_index = ecl_grid_get_global_index3(grid , i,j,k); + return ecl_grid_get_cell_dx1( grid , global_index ); +} + + +double ecl_grid_get_cell_dy1( const ecl_grid_type * grid , int global_index ) { + fprintf(stderr , "** WARNING: The ecl_grid_get_cell_dy1() function is only a stub returning -1.\n"); + fprintf(stderr , " If you need a correct value for cell dy you must update rebuild a new ert version.\n"); + return -1; +} + + +double ecl_grid_get_cell_dy3( const ecl_grid_type * grid , int i , int j , int k) { + const int global_index = ecl_grid_get_global_index3(grid , i,j,k); + return ecl_grid_get_cell_dy1( grid , global_index ); +} + + const nnc_info_type * ecl_grid_get_cell_nnc_info1( const ecl_grid_type * grid , int global_index) { const ecl_cell_type * cell = ecl_grid_get_cell( grid , global_index); return cell->nnc_info; } - - const nnc_info_type * ecl_grid_get_cell_nnc_info3( const ecl_grid_type * grid , int i , int j , int k) { const int global_index = ecl_grid_get_global_index3(grid , i,j,k); return ecl_grid_get_cell_nnc_info1(grid, global_index); } - /*****************************************************************/ /* Functions to query whether a cell is active or not. */ diff --git a/ThirdParty/Ert/devel/libecl/src/ecl_sum_tstep.c b/ThirdParty/Ert/devel/libecl/src/ecl_sum_tstep.c index 11efcc4fca..898b04c8f1 100644 --- a/ThirdParty/Ert/devel/libecl/src/ecl_sum_tstep.c +++ b/ThirdParty/Ert/devel/libecl/src/ecl_sum_tstep.c @@ -294,6 +294,16 @@ void ecl_sum_tstep_set_from_key( ecl_sum_tstep_type * tstep , const char * gen_k ecl_sum_tstep_set_from_node( tstep , smspec_node , value); } +double ecl_sum_tstep_get_from_key(const ecl_sum_tstep_type * tstep , const char * gen_key) { + const smspec_node_type * smspec_node = ecl_smspec_get_general_var_node( tstep->smspec , gen_key ); + int data_index = smspec_node_get_params_index( smspec_node ); + return ecl_sum_tstep_iget( tstep , data_index); +} + +bool ecl_sum_tstep_has_key(const ecl_sum_tstep_type * tstep , const char * gen_key) { + return ecl_smspec_has_general_var(tstep->smspec, gen_key); +} + bool ecl_sum_tstep_sim_time_equal( const ecl_sum_tstep_type * tstep1 , const ecl_sum_tstep_type * tstep2 ) { if (tstep1->sim_time == tstep2->sim_time) diff --git a/ThirdParty/Ert/devel/libecl/src/ecl_util.c b/ThirdParty/Ert/devel/libecl/src/ecl_util.c index ad32fe86aa..0c55d1cf74 100644 --- a/ThirdParty/Ert/devel/libecl/src/ecl_util.c +++ b/ThirdParty/Ert/devel/libecl/src/ecl_util.c @@ -1522,9 +1522,6 @@ time_t ecl_util_make_date(int mday , int month , int year) { /* Small functions to support enum introspection. */ #ifdef HAVE_FORK -const char * ecl_util_file_enum_iget( int index, int * value) { - return util_enum_iget( index , ECL_FILE_ENUM_SIZE , (const util_enum_element_type []) { ECL_FILE_ENUM_DEFS }, value); -} const char * ecl_util_phase_enum_iget( int index, int * value) { return util_enum_iget( index , ECL_PHASE_ENUM_SIZE , (const util_enum_element_type []) { ECL_PHASE_ENUM_DEFS }, value); diff --git a/ThirdParty/Ert/devel/libecl/src/layer.c b/ThirdParty/Ert/devel/libecl/src/layer.c index 45dd8db976..ecd0972aa1 100644 --- a/ThirdParty/Ert/devel/libecl/src/layer.c +++ b/ThirdParty/Ert/devel/libecl/src/layer.c @@ -772,6 +772,21 @@ void layer_cells_equal( const layer_type * layer , int value , int_vector_type * } +int layer_count_equal( const layer_type * layer , int value ) { + int num_equal = 0; + int i,j; + for (j=0; j < layer->ny; j++) { + for (i=0; i < layer->nx; i++) { + cell_type * cell = layer_iget_cell( layer , i , j ); + if (cell->cell_value == value) + num_equal++; + } + } + return num_equal; +} + + + void layer_update_active( layer_type * layer , const ecl_grid_type * grid , int k) { diff --git a/ThirdParty/Ert/devel/libecl/tests/tests.cmake b/ThirdParty/Ert/devel/libecl/tests/tests.cmake index d540312d5b..a819f6fd12 100644 --- a/ThirdParty/Ert/devel/libecl/tests/tests.cmake +++ b/ThirdParty/Ert/devel/libecl/tests/tests.cmake @@ -114,6 +114,9 @@ add_executable( ecl_grid_simple ecl_grid_simple.c ) target_link_libraries( ecl_grid_simple ecl test_util ) add_test( ecl_grid_simple ${EXECUTABLE_OUTPUT_PATH}/ecl_grid_simple ${PROJECT_SOURCE_DIR}/test-data/Statoil/ECLIPSE/Gurbat/ECLIPSE.EGRID ) +add_test( ecl_grid_ecl2015_1 ${EXECUTABLE_OUTPUT_PATH}/ecl_grid_simple ${PROJECT_SOURCE_DIR}/test-data/Statoil/ECLIPSE/Eclipse2015_NNC_BUG/FF15_2015B2_LGRM_RDI15_HIST_RDIREAL1_NOSIM_GRID.EGRID ) +add_test( ecl_grid_ecl2015_2 ${EXECUTABLE_OUTPUT_PATH}/ecl_grid_simple ${PROJECT_SOURCE_DIR}/test-data/Statoil/ECLIPSE/Eclipse2015_NNC_BUG/FF15_2015B2_LGRM_RDI15_HIST_RDIREAL1_20142.EGRID ) + add_executable( ecl_grid_DEPTHZ ecl_grid_DEPTHZ.c ) target_link_libraries( ecl_grid_DEPTHZ ecl test_util ) @@ -370,4 +373,6 @@ set_property( TEST ecl_grid_copy_statoil3 PROPERTY LABELS StatoilData ) set_property( TEST ecl_grid_copy_statoil4 PROPERTY LABELS StatoilData ) set_property( TEST ecl_layer_statoil PROPERTY LABELS StatoilData ) set_property( TEST ecl_grid_layer_contains1 PROPERTY LABELS StatoilData ) -set_property( TEST ecl_grid_layer_contains2 PROPERTY LABELS StatoilData ) \ No newline at end of file +set_property( TEST ecl_grid_layer_contains2 PROPERTY LABELS StatoilData ) +set_property( TEST ecl_grid_ecl2015_1 PROPERTY LABELS StatoilData ) +set_property( TEST ecl_grid_ecl2015_2 PROPERTY LABELS StatoilData ) diff --git a/ThirdParty/Ert/devel/libenkf/include/ert/enkf/active_list.h b/ThirdParty/Ert/devel/libenkf/include/ert/enkf/active_list.h index 9e1e90c68b..613796c374 100644 --- a/ThirdParty/Ert/devel/libenkf/include/ert/enkf/active_list.h +++ b/ThirdParty/Ert/devel/libenkf/include/ert/enkf/active_list.h @@ -1,19 +1,19 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'active_list.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> - for more details. + Copyright (C) 2011 Statoil ASA, Norway. + + The file 'active_list.h' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> + for more details. */ #ifndef __ACTIVE_LIST_H__ @@ -29,7 +29,7 @@ extern "C" { typedef struct active_list_struct active_list_type; - active_list_type * active_list_alloc( ); + active_list_type * active_list_alloc( ); void active_list_reset(active_list_type * ); void active_list_add_index(active_list_type * , int); void active_list_free( active_list_type *); @@ -41,10 +41,11 @@ typedef struct active_list_struct active_list_type; active_mode_type active_list_get_mode(const active_list_type * ); void active_list_free__( void * arg ); active_list_type * active_list_alloc_copy( const active_list_type * src); - void active_list_fprintf( const active_list_type * active_list , bool obs , const char * key , FILE * stream ); + void active_list_fprintf( const active_list_type * active_list , const char * dataset_key , const char * key , FILE * stream ); + void active_list_summary_fprintf( const active_list_type * active_list , const char * dataset_key , const char * key , FILE * stream); bool active_list_iget( const active_list_type * active_list , int index ); bool active_list_equal( const active_list_type * active_list1 , const active_list_type * active_list2); - void active_list_copy( active_list_type * target , const active_list_type * src); + void active_list_copy( active_list_type * target , const active_list_type * src); UTIL_IS_INSTANCE_HEADER( active_list ); diff --git a/ThirdParty/Ert/devel/libenkf/include/ert/enkf/custom_kw_config.h b/ThirdParty/Ert/devel/libenkf/include/ert/enkf/custom_kw_config.h index 48d1387d9f..2328964ee7 100644 --- a/ThirdParty/Ert/devel/libenkf/include/ert/enkf/custom_kw_config.h +++ b/ThirdParty/Ert/devel/libenkf/include/ert/enkf/custom_kw_config.h @@ -21,7 +21,7 @@ extern "C" { char * custom_kw_config_get_result_file(const custom_kw_config_type * config); char * custom_kw_config_get_output_file(const custom_kw_config_type * config); bool custom_kw_config_parse_result_file(custom_kw_config_type * config, const char * result_file, stringlist_type * result); - void custom_kw_config_serialize(custom_kw_config_type * config, stringlist_type * config_set); + void custom_kw_config_serialize(const custom_kw_config_type * config, stringlist_type * config_set); void custom_kw_config_deserialize(custom_kw_config_type * config, stringlist_type * config_set); bool custom_kw_config_has_key(const custom_kw_config_type * config, const char * key); bool custom_kw_config_key_is_double(const custom_kw_config_type * config, const char * key); diff --git a/ThirdParty/Ert/devel/libenkf/include/ert/enkf/enkf_analysis.h b/ThirdParty/Ert/devel/libenkf/include/ert/enkf/enkf_analysis.h index d6a8877db3..1cc7033130 100644 --- a/ThirdParty/Ert/devel/libenkf/include/ert/enkf/enkf_analysis.h +++ b/ThirdParty/Ert/devel/libenkf/include/ert/enkf/enkf_analysis.h @@ -1,19 +1,19 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'enkf_analysis.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> - for more details. + Copyright (C) 2011 Statoil ASA, Norway. + + The file 'enkf_analysis.h' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> + for more details. */ @@ -33,19 +33,21 @@ extern "C" { -void enkf_analysis_fprintf_obs_summary(const obs_data_type * obs_data , - const meas_data_type * meas_data , - const int_vector_type * step_list , +void enkf_analysis_fprintf_obs_summary(const obs_data_type * obs_data , + const meas_data_type * meas_data , + const int_vector_type * step_list , const char * ministep_name , FILE * stream ); - -void enkf_analysis_deactivate_outliers(obs_data_type * obs_data , - meas_data_type * meas_data , - double std_cutoff , - double alpha); + +void enkf_analysis_deactivate_outliers(obs_data_type * obs_data , + meas_data_type * meas_data , + double std_cutoff , + double alpha, + bool verbose); void enkf_analysis_deactivate_std_zero(obs_data_type * obs_data , - meas_data_type * meas_data); + meas_data_type * meas_data, + bool verbose); #ifdef __cplusplus diff --git a/ThirdParty/Ert/devel/libenkf/include/ert/enkf/enkf_defaults.h b/ThirdParty/Ert/devel/libenkf/include/ert/enkf/enkf_defaults.h index 8b51a6d9e3..de0d7bd335 100644 --- a/ThirdParty/Ert/devel/libenkf/include/ert/enkf/enkf_defaults.h +++ b/ThirdParty/Ert/devel/libenkf/include/ert/enkf/enkf_defaults.h @@ -254,7 +254,7 @@ #define DEFAULT_START_TAG "<" #define DEFAULT_END_TAG ">" -#define DEFAULT_MANUAL_URL "http://ert.nr.no/wiki/index.php/User_Manual" +#define DEFAULT_MANUAL_URL "http://ert.nr.no/ert/index.php/User_Manual" #define DEFAULT_BROWSER "firefox" /*****************************************************************/ diff --git a/ThirdParty/Ert/devel/libenkf/include/ert/enkf/enkf_obs.h b/ThirdParty/Ert/devel/libenkf/include/ert/enkf/enkf_obs.h index 10a349b4bd..f045ba16b9 100644 --- a/ThirdParty/Ert/devel/libenkf/include/ert/enkf/enkf_obs.h +++ b/ThirdParty/Ert/devel/libenkf/include/ert/enkf/enkf_obs.h @@ -26,6 +26,7 @@ extern "C" { #include <ert/util/hash.h> #include <ert/util/stringlist.h> #include <ert/util/int_vector.h> +#include <ert/util/type_macros.h> #include <ert/sched/history.h> @@ -96,6 +97,8 @@ extern "C" { double enkf_obs_scale_correlated_std(const enkf_obs_type * enkf_obs , enkf_fs_type * fs , const int_vector_type * ens_active_list , const local_obsdata_type * local_obsdata); local_obsdata_type * enkf_obs_alloc_all_active_local_obs( const enkf_obs_type * enkf_obs , const char * key); + UTIL_IS_INSTANCE_HEADER( enkf_obs ); + #ifdef __cplusplus } #endif diff --git a/ThirdParty/Ert/devel/libenkf/include/ert/enkf/enkf_state.h b/ThirdParty/Ert/devel/libenkf/include/ert/enkf/enkf_state.h index 8b4c3e8eed..2d2bf321e8 100644 --- a/ThirdParty/Ert/devel/libenkf/include/ert/enkf/enkf_state.h +++ b/ThirdParty/Ert/devel/libenkf/include/ert/enkf/enkf_state.h @@ -1,19 +1,19 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'enkf_state.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> - for more details. + Copyright (C) 2011 Statoil ASA, Norway. + + The file 'enkf_state.h' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> + for more details. */ #ifndef __ENKF_STATE_H__ @@ -32,7 +32,7 @@ extern "C" { #include <ert/sched/sched_file.h> - + #include <ert/ecl/fortio.h> #include <ert/ecl/ecl_file.h> @@ -57,7 +57,7 @@ typedef struct enkf_state_struct enkf_state_type; bool enkf_state_get_pre_clear_runpath( const enkf_state_type * enkf_state ); void enkf_state_set_pre_clear_runpath( enkf_state_type * enkf_state , bool pre_clear_runpath ); - + keep_runpath_type enkf_state_get_keep_runpath( const enkf_state_type * enkf_state ); void enkf_state_set_keep_runpath( enkf_state_type * enkf_state , keep_runpath_type keep_runpath); keep_runpath_type member_config_get_keep_runpath(const member_config_type * member_config); @@ -77,24 +77,24 @@ typedef struct enkf_state_struct enkf_state_type; void * enkf_state_run_eclipse__(void * ); void * enkf_state_start_forward_model__(void * ); - void enkf_state_load_from_forward_model(enkf_state_type * enkf_state , - run_arg_type * run_arg , - int * result , - bool interactive , + void enkf_state_load_from_forward_model(enkf_state_type * enkf_state , + run_arg_type * run_arg , + int * result , + bool interactive , stringlist_type * msg_list); - void enkf_state_forward_init(enkf_state_type * enkf_state , - run_arg_type * run_arg , + void enkf_state_forward_init(enkf_state_type * enkf_state , + run_arg_type * run_arg , int * result ); void enkf_state_init_eclipse(enkf_state_type *enkf_state, const run_arg_type * run_arg ); - + enkf_state_type * enkf_state_alloc(int , - rng_type * main_rng , - enkf_fs_type * fs, - const char * casename , - bool pre_clear_runpath, - keep_runpath_type , + rng_type * main_rng , + enkf_fs_type * fs, + const char * casename , + bool pre_clear_runpath, + keep_runpath_type , model_config_type * , ensemble_config_type * , const site_config_type * , diff --git a/ThirdParty/Ert/devel/libenkf/include/ert/enkf/local_config.h b/ThirdParty/Ert/devel/libenkf/include/ert/enkf/local_config.h index 76cbb69fb0..e7324df691 100644 --- a/ThirdParty/Ert/devel/libenkf/include/ert/enkf/local_config.h +++ b/ThirdParty/Ert/devel/libenkf/include/ert/enkf/local_config.h @@ -39,7 +39,7 @@ typedef enum { CREATE_MINISTEP = 2, /* MINISTEP_NAME OBSSET_NAME -> local_config_alloc_ministep(); */ ATTACH_MINISTEP = 3, /* UPDATESTEP_NAME , MINISTEP_NAME -> local_updatestep_add_ministep(); */ CREATE_DATASET = 4, /* NAME */ - ATTACH_DATASET = 5, /* DATASET_NAME MINISETP_NAME */ + ATTACH_DATASET = 5, /* DATASET_NAME MINISTEP_NAME */ CREATE_OBSSET = 6, /* NAME */ ADD_DATA = 7, /* DATA_KEY -> local_ministep_add_node(); */ ADD_OBS = 8, /* OBS_KEY -> local_ministep_add_obs(); */ @@ -47,8 +47,6 @@ typedef enum { ACTIVE_LIST_ADD_DATA_INDEX = 10, /* DATA_KEY , ACTIVE_INDEX */ ACTIVE_LIST_ADD_MANY_OBS_INDEX = 11, /* OBS_KEY , NUM_INDEX , INDEX1, INDEX2, INDEX3,... */ ACTIVE_LIST_ADD_MANY_DATA_INDEX = 12, /* DATA_KEY , NUM_INDEX , INDEX1 , INDEX2 , INDEX3 ,... */ - INSTALL_UPDATESTEP = 13, /* UPDATESTEP_NAME , STEP1 , STEP2 local_config_set_updatestep() */ - INSTALL_DEFAULT_UPDATESTEP = 14, /* UPDATETSTEP_NAME local_config_set_default_updatestep() */ DEL_DATA = 16, /* DATASET KEY*/ DEL_OBS = 17, /* MINISTEP OBS_KEY */ DATASET_DEL_ALL_DATA = 18, /* DATASET */ @@ -56,6 +54,7 @@ typedef enum { ADD_FIELD = 20, /* MINISTEP FIELD_NAME REGION_NAME */ COPY_DATASET = 21, /* SRC_NAME TARGET_NAME */ COPY_OBSSET = 22, /* SRC_NAME TARGET_NAME */ + ATTACH_OBSSET = 23, /* OBSSET_NAME MINISTEP_NAME */ /*****************************************************************/ CREATE_ECLREGION = 100, /* Name of region TRUE|FALSE*/ LOAD_FILE = 101, /* Key, filename */ @@ -87,14 +86,13 @@ typedef enum { #define CREATE_DATASET_STRING "CREATE_DATASET" #define ATTACH_DATASET_STRING "ATTACH_DATASET" #define CREATE_OBSSET_STRING "CREATE_OBSSET" +#define ATTACH_OBSSET_STRING "ATTACH_OBSSET" #define ADD_DATA_STRING "ADD_DATA" #define ADD_OBS_STRING "ADD_OBS" #define ACTIVE_LIST_ADD_OBS_INDEX_STRING "ACTIVE_LIST_ADD_OBS_INDEX" #define ACTIVE_LIST_ADD_DATA_INDEX_STRING "ACTIVE_LIST_ADD_DATA_INDEX" #define ACTIVE_LIST_ADD_MANY_OBS_INDEX_STRING "ACTIVE_LIST_ADD_MANY_OBS_INDEX" #define ACTIVE_LIST_ADD_MANY_DATA_INDEX_STRING "ACTIVE_LIST_ADD_MANY_DATA_INDEX" -#define INSTALL_UPDATESTEP_STRING "INSTALL_UPDATESTEP" -#define INSTALL_DEFAULT_UPDATESTEP_STRING "INSTALL_DEFAULT_UPDATESTEP" #define DEL_DATA_STRING "DEL_DATA" #define DEL_OBS_STRING "DEL_OBS" #define ADD_FIELD_STRING "ADD_FIELD" @@ -124,13 +122,12 @@ typedef enum { typedef struct local_config_struct local_config_type; local_config_type * local_config_alloc( ); +void local_config_clear( local_config_type * local_config ); void local_config_free( local_config_type * local_config ); -local_updatestep_type * local_config_alloc_updatestep( local_config_type * local_config , const char * key ); -local_ministep_type * local_config_alloc_ministep( local_config_type * local_config , const char * key , const char * obsset_name); +local_ministep_type * local_config_alloc_ministep( local_config_type * local_config , const char * key ); local_ministep_type * local_config_alloc_ministep_copy( local_config_type * local_config , const char * src_key , const char * new_key); -void local_config_set_default_updatestep( local_config_type * local_config , const char * default_key); -const local_updatestep_type * local_config_iget_updatestep( const local_config_type * local_config , int index); -local_updatestep_type * local_config_get_updatestep( const local_config_type * local_config , const char * key); +void local_config_set_default_updatestep( local_config_type * local_config , local_updatestep_type * update_step ); +local_updatestep_type * local_config_get_updatestep( const local_config_type * local_config ); local_ministep_type * local_config_get_ministep( const local_config_type * local_config , const char * key); void local_config_set_updatestep(local_config_type * local_config, int step1 , int step2 , const char * key); void local_config_reload( local_config_type * local_config , const ecl_grid_type * ecl_grid , const ensemble_config_type * ensemble_config , const enkf_obs_type * enkf_obs , @@ -140,9 +137,12 @@ const char * local_config_get_cmd_string( local_config_instruct stringlist_type * local_config_get_config_files( const local_config_type * local_config ); void local_config_clear_config_files( local_config_type * local_config ); void local_config_add_config_file( local_config_type * local_config , const char * config_file ); + void local_config_fprintf( const local_config_type * local_config , const char * config_file); +void local_config_summary_fprintf( const local_config_type * local_config , const char * config_file); void local_config_fprintf_config( const local_config_type * local_config , FILE * stream); - +local_obsdata_type * local_config_alloc_obsset( local_config_type * local_config , const char * obsset_name ); +local_dataset_type * local_config_alloc_dataset( local_config_type * local_config , const char * key ); #ifdef __cplusplus } #endif diff --git a/ThirdParty/Ert/devel/libenkf/include/ert/enkf/local_dataset.h b/ThirdParty/Ert/devel/libenkf/include/ert/enkf/local_dataset.h index 2a8d2d59fa..0a4e107c2f 100644 --- a/ThirdParty/Ert/devel/libenkf/include/ert/enkf/local_dataset.h +++ b/ThirdParty/Ert/devel/libenkf/include/ert/enkf/local_dataset.h @@ -1,20 +1,20 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. - + Copyright (C) 2011 Statoil ASA, Norway. + The file 'local_dataset.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> - for more details. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> + for more details. */ #ifndef __LOCAL_DATASET_H__ @@ -35,15 +35,16 @@ void local_dataset_del_node( local_dataset_type * dataset , cons void local_dataset_clear( local_dataset_type * dataset); const char * local_dataset_get_name( const local_dataset_type * dataset); void local_dataset_fprintf( const local_dataset_type * dataset , FILE * stream); +void local_dataset_summary_fprintf( const local_dataset_type * dataset , FILE * stream); active_list_type * local_dataset_get_node_active_list(const local_dataset_type * dataset , const char * node_key ); stringlist_type * local_dataset_alloc_keys( const local_dataset_type * dataset ); int local_dataset_get_size( const local_dataset_type * dataset ); void local_dataset_del_node( local_dataset_type * dataset , const char * node_key); void local_dataset_clear( local_dataset_type * dataset); +bool local_dataset_has_key(const local_dataset_type * dataset, const char * key); - #ifdef __cplusplus } #endif -#endif +#endif diff --git a/ThirdParty/Ert/devel/libenkf/include/ert/enkf/local_ministep.h b/ThirdParty/Ert/devel/libenkf/include/ert/enkf/local_ministep.h index d09177fc17..0a71053a77 100644 --- a/ThirdParty/Ert/devel/libenkf/include/ert/enkf/local_ministep.h +++ b/ThirdParty/Ert/devel/libenkf/include/ert/enkf/local_ministep.h @@ -29,15 +29,18 @@ extern "C" { #include <ert/enkf/active_list.h> #include <ert/enkf/local_dataset.h> #include <ert/enkf/local_obsdata.h> +#include <ert/enkf/local_obsdata_node.h> typedef struct local_ministep_struct local_ministep_type; -local_ministep_type * local_ministep_alloc(const char * name , local_obsdata_type * observations); +local_ministep_type * local_ministep_alloc(const char * name); void local_ministep_free(local_ministep_type * ministep); void local_ministep_free__(void * arg); void local_ministep_add_obs(local_ministep_type * ministep, const char * obs_key); active_list_type * local_ministep_get_node_active_list(const local_ministep_type * ministep , const char * node_key ); hash_iter_type * local_ministep_alloc_dataset_iter( const local_ministep_type * ministep ); +stringlist_type * local_ministep_alloc_data_keys( const local_ministep_type * ministep ); +bool local_ministep_has_data_key(const local_ministep_type * ministep , const char * key); local_ministep_type * local_ministep_alloc_copy( const local_ministep_type * src , const char * name); void local_ministep_del_obs( local_ministep_type * ministep , const char * obs_key); void local_ministep_del_node( local_ministep_type * ministep , const char * node_key); @@ -45,9 +48,14 @@ const char * local_ministep_get_name( const local_ministep_type * minis void local_ministep_clear_nodes( local_ministep_type * ministep); void local_ministep_clear_observations( local_ministep_type * ministep); void local_ministep_fprintf( const local_ministep_type * ministep , FILE * stream ); +void local_ministep_summary_fprintf( const local_ministep_type * ministep , FILE * stream); void local_ministep_add_dataset( local_ministep_type * ministep , const local_dataset_type * dataset); +void local_ministep_add_obsdata( local_ministep_type * ministep , local_obsdata_type * obsdata); +void local_ministep_add_obsdata_node( local_ministep_type * ministep , local_obsdata_node_type * obsdatanode); local_obsdata_type * local_ministep_get_obsdata(const local_ministep_type * ministep); local_dataset_type * local_ministep_get_dataset( const local_ministep_type * ministep, const char * dataset_name); +bool local_ministep_has_dataset( const local_ministep_type * ministep, const char * dataset_name); +int local_ministep_get_num_dataset( const local_ministep_type * ministep ); UTIL_SAFE_CAST_HEADER(local_ministep); UTIL_IS_INSTANCE_HEADER(local_ministep); diff --git a/ThirdParty/Ert/devel/libenkf/include/ert/enkf/local_obsdata.h b/ThirdParty/Ert/devel/libenkf/include/ert/enkf/local_obsdata.h index dcb2ae5d14..7b0fb5c878 100644 --- a/ThirdParty/Ert/devel/libenkf/include/ert/enkf/local_obsdata.h +++ b/ThirdParty/Ert/devel/libenkf/include/ert/enkf/local_obsdata.h @@ -42,7 +42,9 @@ typedef struct local_obsdata_struct local_obsdata_type; local_obsdata_node_type * local_obsdata_get( const local_obsdata_type * data , const char * key); void local_obsdata_clear( local_obsdata_type * data ); void local_obsdata_del_node( local_obsdata_type * data , const char * key); - void local_obsdata_reset_tstep_list( local_obsdata_type * data , const int_vector_type * step_list); + void local_obsdata_reset_tstep_list( local_obsdata_type * data , const int_vector_type * step_list); + void local_obsdata_fprintf( const local_obsdata_type * obsdata , FILE * stream ); + void local_obsdata_summary_fprintf( const local_obsdata_type * obsdata , FILE * stream); UTIL_IS_INSTANCE_HEADER( local_obsdata ); diff --git a/ThirdParty/Ert/devel/libenkf/include/ert/enkf/local_updatestep.h b/ThirdParty/Ert/devel/libenkf/include/ert/enkf/local_updatestep.h index 324a69f5c3..043f0c5f57 100644 --- a/ThirdParty/Ert/devel/libenkf/include/ert/enkf/local_updatestep.h +++ b/ThirdParty/Ert/devel/libenkf/include/ert/enkf/local_updatestep.h @@ -37,6 +37,7 @@ int local_updatestep_get_num_ministep( const local_updateste local_updatestep_type * local_updatestep_alloc_copy( const local_updatestep_type * src , const char * name ); void local_updatestep_fprintf( const local_updatestep_type * updatestep , FILE * stream); const char * local_updatestep_get_name( const local_updatestep_type * updatestep ); +bool local_updatestep_has_data_key( const local_updatestep_type * update_step , const char * key); #ifdef __cplusplus } diff --git a/ThirdParty/Ert/devel/libenkf/include/ert/enkf/obs_data.h b/ThirdParty/Ert/devel/libenkf/include/ert/enkf/obs_data.h index db56079675..d6c9cf2d0b 100644 --- a/ThirdParty/Ert/devel/libenkf/include/ert/enkf/obs_data.h +++ b/ThirdParty/Ert/devel/libenkf/include/ert/enkf/obs_data.h @@ -39,7 +39,7 @@ const char * obs_data_iget_keyword( const obs_data_type * obs_data , int index ) double obs_data_iget_value( const obs_data_type * obs_data , int index ); double obs_data_iget_std( const obs_data_type * obs_data , int index ); active_type obs_data_iget_active_mode( const obs_data_type * obs_data , int index ); -void obs_block_deactivate( obs_block_type * obs_block , int iobs , const char * msg); +void obs_block_deactivate( obs_block_type * obs_block , int iobs , bool verbose , const char * msg); int obs_block_get_size( const obs_block_type * obs_block ); void obs_block_iset( obs_block_type * obs_block , int iobs , double value , double std); void obs_block_iset_missing( obs_block_type * obs_block , int iobs ); @@ -68,8 +68,12 @@ void obs_data_scale_kernel(const obs_data_type * obs_data , matr void obs_data_fprintf(const obs_data_type * , const meas_data_type * meas_data , FILE *); void obs_data_iget_value_std(const obs_data_type * obs_data , int index , double * value , double * std); int obs_data_get_active_size(const obs_data_type * obs_data ); +int obs_data_get_total_size( const obs_data_type * obs_data ); int obs_data_get_num_blocks( const obs_data_type * obs_data ); const char * obs_block_get_key( const obs_block_type * obs_block) ; +double obs_data_iget_value( const obs_data_type * obs_data , int total_index ); +double obs_data_iget_std( const obs_data_type * obs_data , int total_index ); + #ifdef __cplusplus } diff --git a/ThirdParty/Ert/devel/libenkf/include/ert/enkf/run_arg.h b/ThirdParty/Ert/devel/libenkf/include/ert/enkf/run_arg.h index 6eb5a8f88a..2c154ac00b 100644 --- a/ThirdParty/Ert/devel/libenkf/include/ert/enkf/run_arg.h +++ b/ThirdParty/Ert/devel/libenkf/include/ert/enkf/run_arg.h @@ -1,19 +1,19 @@ /* - Copyright (C) 2014 Statoil ASA, Norway. - - The file 'run_arg.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> - for more details. + Copyright (C) 2014 Statoil ASA, Norway. + + The file 'run_arg.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> + for more details. */ #ifndef __RUN_ARG_H__ @@ -29,22 +29,22 @@ extern "C" { #include <ert/enkf/enkf_types.h> #include <ert/enkf/enkf_fs.h> - + typedef struct run_arg_struct run_arg_type; UTIL_SAFE_CAST_HEADER( run_arg ); -UTIL_IS_INSTANCE_HEADER( run_arg ); +UTIL_IS_INSTANCE_HEADER( run_arg ); run_arg_type * run_arg_alloc_ENSEMBLE_EXPERIMENT(enkf_fs_type * fs , int iens , int iter , const char * runpath); run_arg_type * run_arg_alloc_INIT_ONLY(enkf_fs_type * init_fs , int iens , int iter , const char * runpath); run_arg_type * run_arg_alloc_SMOOTHER_RUN(enkf_fs_type * simulate_fs , enkf_fs_type * update_target_fs , int iens , int iter , const char * runpath); - run_arg_type * run_arg_alloc_ENKF_ASSIMILATION(enkf_fs_type * fs , - int iens , + run_arg_type * run_arg_alloc_ENKF_ASSIMILATION(enkf_fs_type * fs , + int iens , state_enum init_state_parameter , state_enum init_state_dynamic , - int step1 , + int step1 , int step2 , const char * runpath); @@ -67,9 +67,9 @@ UTIL_IS_INSTANCE_HEADER( run_arg ); const char * run_arg_get_runpath( const run_arg_type * run_arg); void run_arg_complete_run(run_arg_type * run_arg); run_status_type run_arg_get_run_status( const run_arg_type * run_arg ); - - void run_arg_set_inactive( run_arg_type * run_arg ); + int run_arg_get_queue_index( const run_arg_type * run_arg ); + bool run_arg_is_submitted( const run_arg_type * run_arg ); bool run_arg_can_retry( const run_arg_type * run_arg ); diff --git a/ThirdParty/Ert/devel/libenkf/src/CMakeLists.txt b/ThirdParty/Ert/devel/libenkf/src/CMakeLists.txt index f261889a39..546433b426 100644 --- a/ThirdParty/Ert/devel/libenkf/src/CMakeLists.txt +++ b/ThirdParty/Ert/devel/libenkf/src/CMakeLists.txt @@ -209,6 +209,11 @@ if (USE_RUNPATH) add_runpath( enkf ) endif() +add_custom_target(ert_share_symlinking ALL + COMMENT "Symlinking to the development share directory." + COMMAND ln -sf -t ${PROJECT_BINARY_DIR} ${PROJECT_SOURCE_DIR}/share +) + #----------------------------------------------------------------- if (INSTALL_ERT) install(TARGETS enkf DESTINATION ${CMAKE_INSTALL_LIBDIR}) diff --git a/ThirdParty/Ert/devel/libenkf/src/active_list.c b/ThirdParty/Ert/devel/libenkf/src/active_list.c index 77e20efda9..6768cf9f3f 100644 --- a/ThirdParty/Ert/devel/libenkf/src/active_list.c +++ b/ThirdParty/Ert/devel/libenkf/src/active_list.c @@ -207,22 +207,32 @@ bool active_list_iget( const active_list_type * active_list , int index ) { /*****************************************************************/ -void active_list_fprintf( const active_list_type * active_list , bool obs , const char *key , FILE * stream ) { +void active_list_fprintf( const active_list_type * active_list , const char *dataset_key, const char *key , FILE * stream ) { if (active_list->mode == PARTLY_ACTIVE) { int i; - if (obs) - fprintf(stream , "%s %s %d\n" , local_config_get_cmd_string( ACTIVE_LIST_ADD_MANY_OBS_INDEX ) , key , int_vector_size( active_list->index_list )); - else - fprintf(stream , "%s %s %d\n" , local_config_get_cmd_string( ACTIVE_LIST_ADD_MANY_OBS_INDEX ) , key , int_vector_size( active_list->index_list )); + fprintf(stream , "%s %s %s " , local_config_get_cmd_string( ACTIVE_LIST_ADD_DATA_INDEX ) , dataset_key, key); for (i = 0; i < int_vector_size( active_list->index_list ); i++) { - fprintf(stream , "%6d " , int_vector_iget( active_list->index_list , i)); + fprintf(stream , " %6d " , int_vector_iget( active_list->index_list , i)); if ((i % 10) == 9) fprintf(stream , "\n"); } + fprintf(stream , "\n"); } /* else: if mode == ALL_ACTIVE nothing is written */ } +void active_list_summary_fprintf( const active_list_type * active_list , const char *dataset_key, const char *key , FILE * stream) { + int number_of_active = int_vector_size( active_list->index_list ); + if (active_list->mode == ALL_ACTIVE){ + fprintf(stream , "NUMBER OF ACTIVE:%d,STATUS:%s,", number_of_active, "ALL_ACTIVE"); + } + else if (active_list->mode == PARTLY_ACTIVE){ + fprintf(stream , "NUMBER OF ACTIVE:%d,STATUS:%s,", number_of_active, "PARTLY_ACTIVE"); + } + else + fprintf(stream , "NUMBER OF ACTIVE:%d,STATUS:%s,", number_of_active, "INACTIVE"); +} + bool active_list_equal( const active_list_type * active_list1 , const active_list_type * active_list2) { diff --git a/ThirdParty/Ert/devel/libenkf/src/custom_kw_config.c b/ThirdParty/Ert/devel/libenkf/src/custom_kw_config.c index 847d497c65..c0187de12a 100644 --- a/ThirdParty/Ert/devel/libenkf/src/custom_kw_config.c +++ b/ThirdParty/Ert/devel/libenkf/src/custom_kw_config.c @@ -80,8 +80,9 @@ static void custom_kw_config_reset__(custom_kw_config_type * config) { config->key_definition_file = NULL; } -void custom_kw_config_serialize(custom_kw_config_type * config, stringlist_type * config_set) { - pthread_rwlock_rdlock(& config->rw_lock); +void custom_kw_config_serialize(const custom_kw_config_type * config, stringlist_type * config_set) { + pthread_rwlock_t * rw_lock = (pthread_rwlock_t *)& config->rw_lock; + pthread_rwlock_rdlock(rw_lock); { stringlist_clear(config_set); @@ -100,7 +101,7 @@ void custom_kw_config_serialize(custom_kw_config_type * config, stringlist_type stringlist_free(configured_keys); } - pthread_rwlock_unlock(& config->rw_lock); + pthread_rwlock_unlock(rw_lock); } void custom_kw_config_deserialize(custom_kw_config_type * config, stringlist_type * config_set) { diff --git a/ThirdParty/Ert/devel/libenkf/src/enkf_analysis.c b/ThirdParty/Ert/devel/libenkf/src/enkf_analysis.c index fcb7d3a5c3..901e029a30 100644 --- a/ThirdParty/Ert/devel/libenkf/src/enkf_analysis.c +++ b/ThirdParty/Ert/devel/libenkf/src/enkf_analysis.c @@ -106,7 +106,7 @@ void enkf_analysis_fprintf_obs_summary(const obs_data_type * obs_data , const me -void enkf_analysis_deactivate_outliers(obs_data_type * obs_data , meas_data_type * meas_data , double std_cutoff , double alpha) { +void enkf_analysis_deactivate_outliers(obs_data_type * obs_data , meas_data_type * meas_data , double std_cutoff , double alpha, bool verbose) { for (int block_nr =0; block_nr < obs_data_get_num_blocks( obs_data ); block_nr++) { obs_block_type * obs_block = obs_data_iget_block( obs_data , block_nr); meas_block_type * meas_block = meas_data_iget_block( meas_data , block_nr ); @@ -121,7 +121,7 @@ void enkf_analysis_deactivate_outliers(obs_data_type * obs_data , meas_data_type De activated because the ensemble has to small variation for this particular measurement. */ - obs_block_deactivate( obs_block , iobs , "No ensemble variation"); + obs_block_deactivate( obs_block , iobs , verbose , "No ensemble variation"); meas_block_deactivate( meas_block , iobs ); } else { double ens_mean = meas_block_iget_ens_mean( meas_block , iobs ); @@ -136,7 +136,7 @@ void enkf_analysis_deactivate_outliers(obs_data_type * obs_data , meas_data_type */ if (fabs( innov ) > alpha * (ens_std + obs_std)) { - obs_block_deactivate(obs_block , iobs , "No overlap"); + obs_block_deactivate(obs_block , iobs , verbose , "No overlap"); meas_block_deactivate(meas_block , iobs); } } @@ -146,7 +146,7 @@ void enkf_analysis_deactivate_outliers(obs_data_type * obs_data , meas_data_type } } -void enkf_analysis_deactivate_std_zero(obs_data_type * obs_data , meas_data_type * meas_data) { +void enkf_analysis_deactivate_std_zero(obs_data_type * obs_data , meas_data_type * meas_data , bool verbose) { for (int block_nr =0; block_nr < obs_data_get_num_blocks( obs_data ); block_nr++) { obs_block_type * obs_block = obs_data_iget_block( obs_data , block_nr); @@ -162,7 +162,7 @@ void enkf_analysis_deactivate_std_zero(obs_data_type * obs_data , meas_data_type De activated because the ensemble has to small variation for this particular measurement. */ - obs_block_deactivate( obs_block , iobs , "No ensemble variation"); + obs_block_deactivate( obs_block , iobs , verbose , "No ensemble variation"); meas_block_deactivate( meas_block , iobs ); } } diff --git a/ThirdParty/Ert/devel/libenkf/src/enkf_main.c b/ThirdParty/Ert/devel/libenkf/src/enkf_main.c index e870978d9b..b04229162b 100644 --- a/ThirdParty/Ert/devel/libenkf/src/enkf_main.c +++ b/ThirdParty/Ert/devel/libenkf/src/enkf_main.c @@ -330,30 +330,6 @@ qc_module_type * enkf_main_get_qc_module( const enkf_main_type * enkf_main ) { } -/* - Adding inverse observation keys to the enkf_nodes; can be called - several times. -*/ - - -void enkf_main_update_obs_keys( enkf_main_type * enkf_main ) { - /* First clear all existing observation keys. */ - ensemble_config_clear_obs_keys( enkf_main->ensemble_config ); - - /* Add new observation keys. */ - { - hash_type * map = enkf_obs_alloc_data_map(enkf_main->obs); - hash_iter_type * iter = hash_iter_alloc(map); - const char * obs_key = hash_iter_get_next_key(iter); - while (obs_key != NULL) { - const char * state_kw = hash_get(map , obs_key); - ensemble_config_add_obs_key(enkf_main->ensemble_config , state_kw , obs_key); - obs_key = hash_iter_get_next_key(iter); - } - hash_iter_free(iter); - hash_free(map); - } -} void enkf_main_alloc_obs( enkf_main_type * enkf_main ) { enkf_main->obs = enkf_obs_alloc( model_config_get_history(enkf_main->model_config), @@ -370,8 +346,7 @@ void enkf_main_load_obs( enkf_main_type * enkf_main , const char * obs_config_fi if (enkf_obs_load(enkf_main->obs , obs_config_file , analysis_config_get_std_cutoff(enkf_main->analysis_config))) { - enkf_main_update_obs_keys(enkf_main); - enkf_main_update_local_updates(enkf_main ); + enkf_main_update_local_updates( enkf_main ); } else fprintf(stderr,"** Warning: failed to load observation data from: %s \n",obs_config_file); } @@ -1067,7 +1042,7 @@ void enkf_main_init_PC( const enkf_main_type * enkf_main , double std_cutoff = analysis_config_get_std_cutoff( analysis_config ); double alpha = analysis_config_get_alpha( analysis_config ); - enkf_analysis_deactivate_outliers( obs_data , meas_data , std_cutoff , alpha); + enkf_analysis_deactivate_outliers( obs_data , meas_data , std_cutoff , alpha, enkf_main->verbose); } { @@ -1181,8 +1156,7 @@ static void enkf_main_analysis_update( enkf_main_type * enkf_main , analysis_module_init_update( module , ens_mask , S , R , dObs , E , D ); { hash_iter_type * dataset_iter = local_ministep_alloc_dataset_iter( ministep ); - enkf_fs_type * src_fs = enkf_main_get_fs( enkf_main ); - serialize_info_type * serialize_info = serialize_info_alloc( src_fs , + serialize_info_type * serialize_info = serialize_info_alloc( target_fs, //src_fs - we have already copied the parameters from the src_fs to the target_fs target_fs , iens_active_index, target_step , @@ -1268,6 +1242,7 @@ static void enkf_main_analysis_update( enkf_main_type * enkf_main , matrix_free( R ); matrix_free( dObs ); matrix_free( X ); + matrix_free( A ); } @@ -1316,12 +1291,35 @@ bool enkf_main_UPDATE(enkf_main_type * enkf_main , const int_vector_type * step_ meas_data_type * meas_forecast = meas_data_alloc( ens_mask ); meas_data_type * meas_analyzed = meas_data_alloc( ens_mask ); local_config_type * local_config = enkf_main->local_config; - const local_updatestep_type * updatestep = local_config_iget_updatestep( local_config , current_step ); /* Only last step considered when forming local update */ + const local_updatestep_type * updatestep = local_config_get_updatestep( local_config ); hash_type * use_count = hash_alloc(); const char * log_path = analysis_config_get_log_path( enkf_main->analysis_config ); FILE * log_stream; + + /* Copy all the parameter nodes. */ + if (target_fs != source_fs) { + stringlist_type * param_keys = ensemble_config_alloc_keylist_from_var_type(enkf_main->ensemble_config, PARAMETER ); + for (int i=0; i < stringlist_get_size( param_keys ); i++) { + const char * key = stringlist_iget( param_keys , i ); + if (local_updatestep_has_data_key(updatestep, key)) { + enkf_config_node_type * config_node = ensemble_config_get_node( enkf_main->ensemble_config , key ); + enkf_node_type * data_node = enkf_node_alloc( config_node ); + for (int j=0; j < int_vector_size( ens_active_list ); j++) { + node_id_type node_id = {.iens = int_vector_iget( ens_active_list , j ), + .state = FORECAST , + .report_step = 0 }; + enkf_node_load( data_node , source_fs , node_id ); + enkf_node_store( data_node , target_fs , false , node_id ); + } + enkf_node_free( data_node ); + } + } + stringlist_free( param_keys ); + } + + if ((local_updatestep_get_num_ministep( updatestep ) > 1) && (analysis_config_get_module_option( analysis_config , ANALYSIS_ITERABLE))) { util_exit("** ERROR: Can not combine iterable modules with multi step updates - sorry\n"); @@ -1368,7 +1366,7 @@ bool enkf_main_UPDATE(enkf_main_type * enkf_main , const int_vector_type * step_ - enkf_analysis_deactivate_outliers( obs_data , meas_forecast , std_cutoff , alpha); + enkf_analysis_deactivate_outliers( obs_data , meas_forecast , std_cutoff , alpha , enkf_main->verbose); if (enkf_main->verbose) enkf_analysis_fprintf_obs_summary( obs_data , meas_forecast , step_list , local_ministep_get_name( ministep ) , stdout ); @@ -1407,8 +1405,30 @@ bool enkf_main_UPDATE(enkf_main_type * enkf_main , const int_vector_type * step_ if (target_state_map != source_state_map) { state_map_set_from_inverted_mask( target_state_map , ens_mask , STATE_PARENT_FAILURE); state_map_set_from_mask( target_state_map , ens_mask , STATE_INITIALIZED ); - enkf_fs_fsync( target_fs ); - } + enkf_fs_fsync( target_fs ); + } + + /* Copy all the nodes which have been updates */ + if (target_fs != source_fs) { + stringlist_type * param_keys = ensemble_config_alloc_keylist_from_var_type(enkf_main->ensemble_config, PARAMETER ); + for (int i=0; i < stringlist_get_size( param_keys ); i++) { + const char * key = stringlist_iget( param_keys , i ); + if (!local_updatestep_has_data_key(updatestep, key)) { + enkf_config_node_type * config_node = ensemble_config_get_node( enkf_main->ensemble_config , key ); + enkf_node_type * data_node = enkf_node_alloc( config_node ); + for (int j=0; j < int_vector_size( ens_active_list ); j++) { + node_id_type node_id = {.iens = int_vector_iget( ens_active_list , j ), + .state = FORECAST , + .report_step = 0 }; + enkf_node_load( data_node , source_fs , node_id ); + enkf_node_store( data_node , target_fs , false , node_id ); + } + enkf_node_free( data_node ); + } + } + stringlist_free( param_keys ); + } + } bool_vector_free( ens_mask ); int_vector_free( ens_active_list ); @@ -1545,26 +1565,26 @@ void enkf_main_isubmit_job( enkf_main_type * enkf_main , run_arg_type * run_arg if (run_arg_get_run_mode(run_arg) != INIT_ONLY) { // The job_queue_node will take ownership of this arg_pack; and destroy it when // the job_queue_node is discarded. - arg_pack_type * load_arg = arg_pack_alloc(); + arg_pack_type * callback_arg = arg_pack_alloc(); /* Prepare the job and submit it to the queue */ - arg_pack_append_ptr( load_arg , enkf_state ); - arg_pack_append_ptr( load_arg , run_arg ); + arg_pack_append_ptr( callback_arg , enkf_state ); + arg_pack_append_ptr( callback_arg , run_arg ); { - int queue_index = job_queue_add_job_mt( job_queue , - job_script , - enkf_state_complete_forward_modelOK__ , - enkf_state_complete_forward_modelRETRY__ , - enkf_state_complete_forward_modelEXIT__, - load_arg , - ecl_config_get_num_cpu( ecl_config ), - run_path , - member_config_get_jobname( member_config ) , - 1, - (const char *[1]) { run_path } ); + int queue_index = job_queue_add_job( job_queue , + job_script , + enkf_state_complete_forward_modelOK__ , + enkf_state_complete_forward_modelRETRY__ , + enkf_state_complete_forward_modelEXIT__, + callback_arg , + ecl_config_get_num_cpu( ecl_config ), + run_path , + member_config_get_jobname( member_config ) , + 1, + (const char *[1]) { run_path } ); run_arg_set_queue_index( run_arg , queue_index ); run_arg_increase_submit_count( run_arg ); @@ -1574,13 +1594,12 @@ void enkf_main_isubmit_job( enkf_main_type * enkf_main , run_arg_type * run_arg -static void * enkf_main_isubmit_job__( void * arg ) { +void * enkf_main_isubmit_job__( void * arg ) { arg_pack_type * arg_pack = arg_pack_safe_cast( arg ); enkf_main_type * enkf_main = enkf_main_safe_cast( arg_pack_iget_ptr( arg_pack , 0 )); run_arg_type * run_arg = run_arg_safe_cast( arg_pack_iget_ptr( arg_pack , 1)); enkf_main_isubmit_job( enkf_main , run_arg ); - arg_pack_free( arg_pack ); return NULL; } @@ -1588,21 +1607,21 @@ static void * enkf_main_isubmit_job__( void * arg ) { -void enkf_main_submit_jobs( enkf_main_type * enkf_main , - const ert_run_context_type * run_context ) { +void enkf_main_submit_jobs__( enkf_main_type * enkf_main , + const ert_run_context_type * run_context , + thread_pool_type * submit_threads, + arg_pack_type ** arg_pack_list) { runpath_list_type * runpath_list = qc_module_get_runpath_list( enkf_main->qc_module ); - runpath_list_clear( runpath_list ); { int iens; const bool_vector_type * iactive = ert_run_context_get_iactive( run_context ); const int active_ens_size = util_int_min( bool_vector_size( iactive ) , enkf_main_get_ensemble_size( enkf_main )); - thread_pool_type * submit_threads = thread_pool_alloc( 4 , true ); for (iens = 0; iens < active_ens_size; iens++) { if (bool_vector_iget(iactive , iens)) { run_arg_type * run_arg = ert_run_context_iens_get_arg( run_context , iens); - arg_pack_type * arg_pack = arg_pack_alloc( ); // This is discarded by the enkf_main_isubmit_job__() + arg_pack_type * arg_pack = arg_pack_list[iens]; arg_pack_append_ptr( arg_pack , enkf_main ); arg_pack_append_ptr( arg_pack , run_arg); @@ -1610,20 +1629,38 @@ void enkf_main_submit_jobs( enkf_main_type * enkf_main , thread_pool_add_job(submit_threads , enkf_main_isubmit_job__ , arg_pack); } } - - /* - After this join all directories/files for the simulations - have been set up correctly, and all the jobs have been added - to the job_queue manager. - */ - - thread_pool_join(submit_threads); - thread_pool_free(submit_threads); } runpath_list_fprintf( runpath_list ); } +void enkf_main_submit_jobs( enkf_main_type * enkf_main , + const ert_run_context_type * run_context) { + + int ens_size = enkf_main_get_ensemble_size( enkf_main ); + arg_pack_type ** arg_pack_list = util_malloc( ens_size * sizeof * arg_pack_list ); + thread_pool_type * submit_threads = thread_pool_alloc( 4 , true ); + int iens; + for (iens = 0; iens < ens_size; iens++) + arg_pack_list[iens] = arg_pack_alloc( ); + + enkf_main_submit_jobs__(enkf_main , run_context , submit_threads , arg_pack_list); + + /* + After this join all directories/files for the simulations + have been set up correctly, and all the jobs have been added + to the job_queue manager. + */ + + thread_pool_join(submit_threads); + thread_pool_free(submit_threads); + + for (iens = 0; iens < ens_size; iens++) + arg_pack_free( arg_pack_list[iens] ); + free( arg_pack_list ); +} + + /** If all simulations have completed successfully the function will @@ -1693,11 +1730,12 @@ static bool enkf_main_run_step(enkf_main_type * enkf_main , { job_queue_type * job_queue = site_config_get_job_queue(enkf_main->site_config); job_queue_manager_type * queue_manager = job_queue_manager_alloc( job_queue ); + bool restart_queue = true; /* Start the queue */ if (ert_run_context_get_mode( run_context ) != INIT_ONLY) { if (site_config_has_job_script( enkf_main->site_config )) - job_queue_manager_start_queue( queue_manager , job_size , verbose_queue ); + job_queue_manager_start_queue( queue_manager , job_size , verbose_queue , restart_queue); else util_exit("No job script specified, can not start any jobs. Use the key JOB_SCRIPT in the config file\n"); } @@ -2165,76 +2203,69 @@ ert_run_context_type * enkf_main_alloc_ert_run_context_ENKF_ASSIMILATION( const here... */ -void enkf_main_create_all_active_config( const enkf_main_type * enkf_main , - const char * local_config_file ) { +void enkf_main_create_all_active_config( const enkf_main_type * enkf_main) { bool single_node_update = analysis_config_get_single_node_update( enkf_main->analysis_config ); bool update_results = analysis_config_get_update_results( enkf_main->analysis_config ); + local_config_type * local_config = enkf_main->local_config; + local_config_clear( local_config ); + { + local_updatestep_type * default_step = local_config_get_updatestep(local_config); + local_ministep_type * ministep = local_config_alloc_ministep( local_config , "ALL_ACTIVE"); + local_obsdata_type * obsdata = local_config_alloc_obsset(local_config, "ALL_OBS"); + local_dataset_type * all_active_dataset = local_config_alloc_dataset(local_config, "ALL_DATA"); - const char * update_step_name = "ALL_ACTIVE"; - const char * ministep_name = "ALL_ACTIVE"; - const char * obsset_name = "ALL_OBS"; - const char * dataset_name = "ALL_DATA"; // <- This is is created for possible further use, even if - // single_node_update is true. - - FILE * stream = util_fopen( local_config_file , "w"); - - fprintf(stream , "%-32s %s\n", local_config_get_cmd_string( CREATE_UPDATESTEP ) , update_step_name); - fprintf(stream , "%-32s %s \n", local_config_get_cmd_string( CREATE_OBSSET ) , obsset_name); - fprintf(stream , "%-32s %s %s \n", local_config_get_cmd_string( CREATE_MINISTEP ) , ministep_name , obsset_name); - fprintf(stream , "%-32s %s %s \n" , local_config_get_cmd_string( ATTACH_MINISTEP ), update_step_name , ministep_name); - - fprintf(stream , "%-32s %s \n", local_config_get_cmd_string( CREATE_DATASET ) , dataset_name); - if (!single_node_update) - fprintf(stream , "%-32s %s %s \n", local_config_get_cmd_string( ATTACH_DATASET ) , ministep_name , dataset_name); + local_updatestep_add_ministep( default_step , ministep ); - /* Adding all observation keys */ - { - hash_iter_type * obs_iter = enkf_obs_alloc_iter( enkf_main->obs ); - while ( !hash_iter_is_complete(obs_iter) ) { - const char * obs_key = hash_iter_get_next_key( obs_iter ); - fprintf(stream , "%-32s %s %s\n",local_config_get_cmd_string( ADD_OBS ) , obsset_name , obs_key); + /* Adding all observation keys */ + { + hash_iter_type * obs_iter = enkf_obs_alloc_iter( enkf_main->obs ); + while ( !hash_iter_is_complete(obs_iter) ) { + const char * obs_key = hash_iter_get_next_key( obs_iter ); + local_obsdata_node_type * obsdata_node = local_obsdata_node_alloc( obs_key ); + local_obsdata_add_node(obsdata, obsdata_node ); + } + local_ministep_add_obsdata(ministep, obsdata); + hash_iter_free( obs_iter ); } - hash_iter_free( obs_iter ); - } - /* Adding all node which can be updated. */ - { - stringlist_type * keylist = ensemble_config_alloc_keylist_from_var_type( enkf_main->ensemble_config , PARAMETER + DYNAMIC_STATE + DYNAMIC_RESULT); - int i; - for (i = 0; i < stringlist_get_size( keylist ); i++) { - const char * key = stringlist_iget( keylist , i); - const enkf_config_node_type * config_node = ensemble_config_get_node( enkf_main->ensemble_config , key ); - enkf_var_type var_type = enkf_config_node_get_var_type( config_node ); - bool add_node = true; + /* Adding all node which can be updated. */ + { + stringlist_type * keylist = ensemble_config_alloc_keylist_from_var_type( enkf_main->ensemble_config , PARAMETER + DYNAMIC_STATE + DYNAMIC_RESULT); + int i; + for (i = 0; i < stringlist_get_size( keylist ); i++) { + const char * key = stringlist_iget( keylist , i); + const enkf_config_node_type * config_node = ensemble_config_get_node( enkf_main->ensemble_config , key ); + enkf_var_type var_type = enkf_config_node_get_var_type( config_node ); + bool add_node = true; - if ((var_type == DYNAMIC_RESULT) && (!update_results)) - add_node = false; + if ((var_type == DYNAMIC_RESULT) && (!update_results)) + add_node = false; - /* - Make sure the funny GEN_KW instance masquerading as - SCHEDULE_PREDICTION_FILE is not added to the soup. - */ - if (util_string_equal(key , "PRED")) - add_node = false; + /* + Make sure the funny GEN_KW instance masquerading as + SCHEDULE_PREDICTION_FILE is not added to the soup. + */ + if (util_string_equal(key , "PRED")) + add_node = false; - if (add_node) { - if (single_node_update) { - fprintf(stream , "%-32s %s \n" , local_config_get_cmd_string( CREATE_DATASET ) , key); - fprintf(stream , "%-32s %s %s \n" , local_config_get_cmd_string( ATTACH_DATASET ) , ministep_name , key); - fprintf(stream , "%-32s %s %s\n" , local_config_get_cmd_string( ADD_DATA ) , key , key); + if (add_node) { + if (single_node_update) { + local_dataset_type * this_dataset = local_config_alloc_dataset(local_config, key); + local_dataset_add_node(this_dataset, key); + local_ministep_add_dataset(ministep, this_dataset); + } + local_dataset_add_node(all_active_dataset, key); } - fprintf(stream , "%-32s %s %s\n",local_config_get_cmd_string( ADD_DATA ) , dataset_name , key); } + stringlist_free( keylist); } - stringlist_free( keylist); - } + if (!single_node_update) + local_ministep_add_dataset(ministep, all_active_dataset); - /* Install the ALL_ACTIVE step as the default. */ - fprintf(stream , "%-32s ALL_ACTIVE" , local_config_get_cmd_string( INSTALL_DEFAULT_UPDATESTEP )); - fclose( stream ); + } } @@ -2777,23 +2808,7 @@ void enkf_main_update_local_updates( enkf_main_type * enkf_main) { const enkf_obs_type * enkf_obs = enkf_main_get_obs( enkf_main ); if (enkf_obs_have_obs( enkf_obs )) { /* First create the default ALL_ACTIVE configuration. */ - { - char * all_active_config_file = util_alloc_tmp_file("/tmp" , "enkf_local_config" , true); - enkf_main_create_all_active_config( enkf_main , - all_active_config_file ); - - /** - This is where the local configuration files are actually parsed. - */ - local_config_reload( enkf_main->local_config , - ecl_config_get_grid( enkf_main->ecl_config ), - enkf_main->ensemble_config , - enkf_main->obs , - all_active_config_file ); - - unlink( all_active_config_file ); - free(all_active_config_file); - } + enkf_main_create_all_active_config( enkf_main ); } } diff --git a/ThirdParty/Ert/devel/libenkf/src/enkf_main_jobs.c b/ThirdParty/Ert/devel/libenkf/src/enkf_main_jobs.c index ffe2471244..7a9cf14497 100644 --- a/ThirdParty/Ert/devel/libenkf/src/enkf_main_jobs.c +++ b/ThirdParty/Ert/devel/libenkf/src/enkf_main_jobs.c @@ -256,11 +256,9 @@ void * enkf_main_scale_obs_std_JOB(void * self, const stringlist_type * args ) { enkf_main_type * enkf_main = enkf_main_safe_cast( self ); double scale_factor; - util_sscanf_double(stringlist_iget(args, 0), &scale_factor); - - if (enkf_main_have_obs(enkf_main)) { - enkf_obs_type * observations = enkf_main_get_obs(enkf_main); - enkf_obs_scale_std(observations, scale_factor); + if (util_sscanf_double(stringlist_iget(args, 0), &scale_factor)) { + analysis_config_type * analysis_config = enkf_main_get_analysis_config( enkf_main ); + analysis_config_set_global_std_scaling( analysis_config , scale_factor ); } return NULL; } diff --git a/ThirdParty/Ert/devel/libenkf/src/enkf_obs.c b/ThirdParty/Ert/devel/libenkf/src/enkf_obs.c index 81418a1d7b..8270d31371 100644 --- a/ThirdParty/Ert/devel/libenkf/src/enkf_obs.c +++ b/ThirdParty/Ert/devel/libenkf/src/enkf_obs.c @@ -186,8 +186,9 @@ static conf_class_type * enkf_obs_get_obs_conf_class(); ////////////////////////////////////////////////////////////////////////////////////// - +#define ENKF_OBS_TYPE_ID 637297 struct enkf_obs_struct { + UTIL_TYPE_ID_DECLARATION; /** A hash of obs_vector_types indexed by user provided keys. */ vector_type * obs_vector; hash_type * obs_hash; @@ -218,7 +219,7 @@ static int enkf_obs_get_last_restart( const enkf_obs_type * enkf_obs ) { return time_map_get_size( enkf_obs->obs_time ) - 1; } - +UTIL_IS_INSTANCE_FUNCTION( enkf_obs , ENKF_OBS_TYPE_ID ) enkf_obs_type * enkf_obs_alloc( const history_type * history , time_map_type * external_time_map , @@ -227,6 +228,7 @@ enkf_obs_type * enkf_obs_alloc( const history_type * history , ensemble_config_type * ensemble_config ) { enkf_obs_type * enkf_obs = util_malloc(sizeof * enkf_obs); + UTIL_TYPE_ID_INIT( enkf_obs , ENKF_OBS_TYPE_ID ); enkf_obs->obs_hash = hash_alloc(); enkf_obs->obs_vector = vector_alloc_new(); enkf_obs->obs_time = time_map_alloc(); @@ -356,7 +358,7 @@ static void enkf_obs_get_obs_and_measure_summary(const enkf_obs_type * enkf if (obs_vector_iget_active( obs_vector , step ) && active_list_iget( active_list , 0 /* Index into the scalar summary observation */)) { { const summary_obs_type * summary_obs = obs_vector_iget_node( obs_vector , step ); - double_vector_iset( obs_std , active_count , summary_obs_get_std( summary_obs )); + double_vector_iset( obs_std , active_count , summary_obs_get_std( summary_obs ) * summary_obs_get_std_scaling( summary_obs )); double_vector_iset( obs_value , active_count , summary_obs_get_value( summary_obs )); last_step = step; } @@ -518,6 +520,34 @@ void enkf_obs_clear( enkf_obs_type * enkf_obs ) { + +/* + Adding inverse observation keys to the enkf_nodes; can be called + several times. +*/ + + +static void enkf_obs_update_keys( enkf_obs_type * enkf_obs ) { + /* First clear all existing observation keys. */ + ensemble_config_clear_obs_keys( enkf_obs->ensemble_config ); + + /* Add new observation keys. */ + { + hash_type * map = enkf_obs_alloc_data_map(enkf_obs); + hash_iter_type * iter = hash_iter_alloc(map); + const char * obs_key = hash_iter_get_next_key(iter); + while (obs_key != NULL) { + const char * state_kw = hash_get(map , obs_key); + ensemble_config_add_obs_key(enkf_obs->ensemble_config , state_kw , obs_key); + obs_key = hash_iter_get_next_key(iter); + } + hash_iter_free(iter); + hash_free(map); + } +} + + + /** This function will load an observation configuration from the observation file @config_file. @@ -531,7 +561,7 @@ void enkf_obs_clear( enkf_obs_type * enkf_obs ) { bool enkf_obs_load(enkf_obs_type * enkf_obs , const char * config_file, double std_cutoff) { - + if (enkf_obs->valid) { int last_report = enkf_obs_get_last_restart( enkf_obs ); conf_class_type * enkf_conf_class = enkf_obs_get_obs_conf_class(); @@ -643,6 +673,7 @@ bool enkf_obs_load(enkf_obs_type * enkf_obs , conf_instance_free(enkf_conf ); conf_class_free( enkf_conf_class); + enkf_obs_update_keys( enkf_obs ); return true; } else return false; diff --git a/ThirdParty/Ert/devel/libenkf/src/enkf_state.c b/ThirdParty/Ert/devel/libenkf/src/enkf_state.c index 40195cb5e3..168ed7cfef 100644 --- a/ThirdParty/Ert/devel/libenkf/src/enkf_state.c +++ b/ThirdParty/Ert/devel/libenkf/src/enkf_state.c @@ -1,19 +1,19 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'enkf_state.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> - for more details. + Copyright (C) 2011 Statoil ASA, Norway. + + The file 'enkf_state.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> + for more details. */ #include <sys/types.h> @@ -85,21 +85,21 @@ This struct contains various objects which the enkf_state needs during operation, which the enkf_state_object *DOES NOT* own. The struct only contains pointers to objects owned by (typically) the - enkf_main object. + enkf_main object. If the enkf_state object writes to any of the objects in this struct that can be considered a serious *BUG*. The elements in this struct should not change during the - application lifetime? + application lifetime? */ typedef struct shared_info_struct { model_config_type * model_config; /* .... */ ext_joblist_type * joblist; /* The list of external jobs which are installed - and *how* they should be run (with Python code) */ - job_queue_type * job_queue; /* The queue handling external jobs. (i.e. LSF / TORQUE / rsh / local / ... )*/ + job_queue_type * job_queue; /* The queue handling external jobs. (i.e. LSF / TORQUE / rsh / local / ... )*/ const site_config_type * site_config; - ert_templates_type * templates; + ert_templates_type * templates; const ecl_config_type * ecl_config; } shared_info_type; @@ -118,7 +118,7 @@ struct enkf_state_struct { operation on the ECLIPSE data file. Will at least contain the key INIT" - which will describe initialization of ECLIPSE (EQUIL or RESTART).*/ ensemble_config_type * ensemble_config; /* The config nodes for the enkf_node objects contained in node_hash. */ - + shared_info_type * shared_info; /* Pointers to shared objects which is needed by the enkf_state object (read only). */ member_config_type * my_config; /* Private config information for this member; not updated during a simulation. */ rng_type * rng; @@ -144,14 +144,14 @@ static shared_info_type * shared_info_alloc(const site_config_type * site_config static void shared_info_free(shared_info_type * shared_info) { - /** - Adding something here is a BUG - this object does + /** + Adding something here is a BUG - this object does not own anything. */ free( shared_info ); } - + @@ -173,9 +173,9 @@ void enkf_state_initialize(enkf_state_type * enkf_state , enkf_fs_type * fs , co enkf_node_type * param_node = enkf_state_get_node(enkf_state, stringlist_iget(param_list, ip)); node_id_type node_id = { .report_step = 0, .iens = iens, .state = init_state }; bool has_data = enkf_node_has_data(param_node, fs, node_id); - + if ((init_mode == INIT_FORCE) || (has_data == false) || (current_state == STATE_LOAD_FAILURE)) { - if (enkf_node_initialize(param_node, iens, enkf_state->rng)) + if (enkf_node_initialize(param_node, iens, enkf_state->rng)) enkf_node_store(param_node, fs, true, node_id); } } @@ -227,9 +227,9 @@ void enkf_state_update_eclbase( enkf_state_type * enkf_state ) { const char * eclbase = member_config_update_eclbase( enkf_state->my_config , enkf_state->shared_info->ecl_config , enkf_state->subst_list); const char * casename = member_config_get_casename( enkf_state->my_config ); /* Mostly NULL */ { - enkf_state_add_subst_kw(enkf_state , "ECL_BASE" , eclbase , NULL); - enkf_state_add_subst_kw(enkf_state , "ECLBASE" , eclbase , NULL); - + enkf_state_add_subst_kw(enkf_state , "ECL_BASE" , eclbase , NULL); + enkf_state_add_subst_kw(enkf_state , "ECLBASE" , eclbase , NULL); + if (casename == NULL) enkf_state_add_subst_kw( enkf_state , "CASE" , eclbase , NULL); /* No CASE_TABLE loaded - using the eclbase as default. */ else @@ -239,8 +239,8 @@ void enkf_state_update_eclbase( enkf_state_type * enkf_state ) { void enkf_state_update_jobname( enkf_state_type * enkf_state ) { - member_config_update_jobname( enkf_state->my_config , - model_config_get_jobname_fmt( enkf_state->shared_info->model_config ) , + member_config_update_jobname( enkf_state->my_config , + model_config_get_jobname_fmt( enkf_state->shared_info->model_config ) , enkf_state->subst_list); } @@ -259,7 +259,7 @@ static void enkf_state_set_static_subst_kw(enkf_state_type * enkf_state) { enkf_state_add_subst_kw(enkf_state , "IENS" , iens_s , NULL); enkf_state_add_subst_kw(enkf_state , "IENSP1" , iensp1_s , NULL); enkf_state_add_subst_kw(enkf_state , "IENS4" , iens4_s , NULL); - + free(iensp1_s); free(iens_s); free(iens4_s); @@ -282,7 +282,7 @@ static void enkf_state_add_nodes( enkf_state_type * enkf_state, const ensemble_c } else enkf_state_add_node(enkf_state , key , config_node); } - + // 2: Add container nodes - must ensure that all other nodes have // been added already (this implies that containers of containers // will be victim of hash retrieval order problems .... @@ -292,7 +292,7 @@ static void enkf_state_add_nodes( enkf_state_type * enkf_state, const ensemble_c const enkf_config_node_type * config_node = ensemble_config_get_node(ensemble_config , key); enkf_state_add_node( enkf_state , key , config_node ); } - + stringlist_free(keylist); stringlist_free( container_keys ); } @@ -315,33 +315,33 @@ void enkf_state_set_pre_clear_runpath( enkf_state_type * enkf_state , bool pre_c enkf_state_type * enkf_state_alloc(int iens, - rng_type * main_rng , - enkf_fs_type * fs, - const char * casename , - bool pre_clear_runpath , - keep_runpath_type keep_runpath , + rng_type * main_rng , + enkf_fs_type * fs, + const char * casename , + bool pre_clear_runpath , + keep_runpath_type keep_runpath , model_config_type * model_config, ensemble_config_type * ensemble_config, const site_config_type * site_config, const ecl_config_type * ecl_config, ert_templates_type * templates, - subst_list_type * subst_parent) { - + subst_list_type * subst_parent) { + enkf_state_type * enkf_state = util_malloc(sizeof *enkf_state ); UTIL_TYPE_ID_INIT( enkf_state , ENKF_STATE_TYPE_ID ); enkf_state->ensemble_config = ensemble_config; enkf_state->shared_info = shared_info_alloc(site_config , model_config , ecl_config , templates); - + enkf_state->node_hash = hash_alloc(); enkf_state->restart_kw_list = stringlist_alloc_new(); enkf_state->subst_list = subst_list_alloc( subst_parent ); - enkf_state->rng = rng_alloc( rng_get_type( main_rng ) , INIT_DEFAULT ); + enkf_state->rng = rng_alloc( rng_get_type( main_rng ) , INIT_DEFAULT ); rng_rng_init( enkf_state->rng , main_rng ); /* <- Not thread safe */ /* The user MUST specify an INIT_FILE, and for the first timestep the - <INIT> tag in the data file will be replaced by an + <INIT> tag in the data file will be replaced by an INCLDUE EQUIL_INIT_FILE @@ -386,8 +386,8 @@ enkf_state_type * enkf_state_alloc(int iens, enkf_state_add_subst_kw(enkf_state , "RESTART_FILE2" , "---" , "The ECLIPSE restart file this simulation should end with."); enkf_state_add_subst_kw(enkf_state , "RANDINT" , "---" , "Random integer value (depreceated: use __RANDINT__() instead)."); enkf_state_add_subst_kw(enkf_state , "RANDFLOAT" , "---" , "Random float value (depreceated: use __RANDFLOAT__() instead)."); - enkf_state_add_subst_kw(enkf_state , "INIT" , "---" , "The code which will be inserted at the <INIT> tag"); - if (casename != NULL) + enkf_state_add_subst_kw(enkf_state , "INIT" , "---" , "The code which will be inserted at the <INIT> tag"); + if (casename != NULL) enkf_state_add_subst_kw(enkf_state , "CASE" , casename , "The casename for this realization - as loaded from the CASE_TABLE file."); else enkf_state_add_subst_kw(enkf_state , "CASE" , "---" , "The casename for this realization - similar to ECLBASE."); @@ -395,7 +395,7 @@ enkf_state_type * enkf_state_alloc(int iens, enkf_state->my_config = member_config_alloc( iens , casename , pre_clear_runpath , keep_runpath , ecl_config , ensemble_config , fs); enkf_state_set_static_subst_kw( enkf_state ); enkf_state_add_nodes( enkf_state , ensemble_config ); - + return enkf_state; } @@ -421,7 +421,7 @@ bool enkf_state_has_node(const enkf_state_type * enkf_state , const char * node_ void enkf_state_add_node(enkf_state_type * enkf_state , const char * node_key , const enkf_config_node_type * config) { - if (enkf_state_has_node(enkf_state , node_key)) + if (enkf_state_has_node(enkf_state , node_key)) enkf_state_del_node( enkf_state , node_key ); /* Deleting the old instance (if we had one). */ { enkf_node_type *enkf_node; @@ -429,9 +429,9 @@ void enkf_state_add_node(enkf_state_type * enkf_state , const char * node_key , enkf_node = enkf_node_alloc_shared_container( config , enkf_state->node_hash ); else enkf_node = enkf_node_alloc( config ); - + hash_insert_hash_owned_ref(enkf_state->node_hash , node_key , enkf_node, enkf_node_free__); - + /* Setting the global subst list so that the GEN_KW templates can contain e.g. <IENS> and <CWD>. */ if (enkf_node_get_impl_type( enkf_node ) == GEN_KW) gen_kw_set_subst_parent( enkf_node_value_ptr( enkf_node ) , enkf_state->subst_list ); @@ -457,7 +457,7 @@ void enkf_state_update_node( enkf_state_type * enkf_state , const char * node_ke bool modified = true; /* ehhhh? */ if (modified) - enkf_state_add_node( enkf_state , node_key , config_node ); + enkf_state_add_node( enkf_state , node_key , config_node ); } } @@ -472,42 +472,42 @@ static ecl_sum_type * enkf_state_load_ecl_sum(const enkf_state_type * enkf_state if (ecl_config_active( ecl_config )) { const bool fmt_file = ecl_config_get_formatted(ecl_config); const char * eclbase = enkf_state_get_eclbase( enkf_state ); - + stringlist_type * data_files = stringlist_alloc_new(); char * header_file = ecl_util_alloc_exfilename(run_arg_get_runpath(run_arg) , eclbase , ECL_SUMMARY_HEADER_FILE , fmt_file , -1); char * unified_file = ecl_util_alloc_exfilename(run_arg_get_runpath(run_arg) , eclbase , ECL_UNIFIED_SUMMARY_FILE , fmt_file , -1); - ecl_sum_type * summary = NULL; - + ecl_sum_type * summary = NULL; + /* Should we load from a unified summary file, or from several non-unified files? */ - if (unified_file != NULL) + if (unified_file != NULL) /* Use unified file: */ stringlist_append_ref( data_files , unified_file); else { - /* Use several non unified files. */ + /* Use several non unified files. */ /* Bypassing the query to model_config_load_results() */ int report_step = run_arg_get_load_start( run_arg ); if (report_step == 0) report_step++; // Ignore looking for the .S0000 summary file (it does not exist). while (true) { char * summary_file = ecl_util_alloc_exfilename(run_arg_get_runpath( run_arg ) , eclbase , ECL_SUMMARY_FILE , fmt_file , report_step); - + if (summary_file != NULL) stringlist_append_owned_ref( data_files , summary_file); else - /* + /* We stop the loading at first 'hole' in the series of summary files; the internalize layer must report failure if we are missing data. */ break; - + if ((run_arg_get_run_mode( run_arg ) == ENKF_ASSIMILATION) && (run_arg_get_step2( run_arg ) == report_step)) break; report_step++; } - } - + } + if ((header_file != NULL) && (stringlist_get_size(data_files) > 0)) { summary = ecl_sum_fread_alloc(header_file , data_files , SUMMARY_KEY_JOIN_STRING ); { @@ -519,17 +519,17 @@ static ecl_sum_type * enkf_state_load_ecl_sum(const enkf_state_type * enkf_state { int end_day,end_month,end_year; int sum_day,sum_month,sum_year; - + util_set_date_values( end_time , &end_day , &end_month , &end_year ); util_set_date_values( ecl_sum_get_end_time( summary ) , &sum_day , &sum_month , &sum_year ); - stringlist_append_owned_ref( messages , - util_alloc_sprintf("Summary ended at %02d/%02d/%4d - expected at least END_DATE: %02d/%02d/%4d" , - sum_day , sum_month , sum_year , + stringlist_append_owned_ref( messages , + util_alloc_sprintf("Summary ended at %02d/%02d/%4d - expected at least END_DATE: %02d/%02d/%4d" , + sum_day , sum_month , sum_year , end_day , end_month , end_year )); } ecl_sum_free( summary ); summary = NULL; - *result |= LOAD_FAILURE; + *result |= LOAD_FAILURE; } } } @@ -543,14 +543,14 @@ static ecl_sum_type * enkf_state_load_ecl_sum(const enkf_state_type * enkf_state } -static void enkf_state_log_GEN_DATA_load( const enkf_node_type * enkf_node , int report_step , stringlist_type * msg_list) { +static void enkf_state_log_GEN_DATA_load( const enkf_node_type * enkf_node , int report_step , stringlist_type * msg_list) { /* In interactive mode we explicitly report the loads of GEN_DATA instances. */ char * load_file = enkf_config_node_alloc_infile(enkf_node_get_config( enkf_node ) , report_step); int data_size = gen_data_get_size( enkf_node_value_ptr( enkf_node )); - stringlist_append_owned_ref( msg_list , - util_alloc_sprintf("Loaded GEN_DATA:%s instance for step:%d from file:%s size:%d" , - enkf_node_get_key( enkf_node ) , - report_step , + stringlist_append_owned_ref( msg_list , + util_alloc_sprintf("Loaded GEN_DATA:%s instance for step:%d from file:%s size:%d" , + enkf_node_get_key( enkf_node ) , + report_step , load_file , data_size)); free( load_file ); @@ -568,15 +568,15 @@ static void enkf_state_log_custom_kw_load(const enkf_node_type * enkf_node, int } static bool enkf_state_report_step_compatible(const enkf_state_type * enkf_state, const ecl_sum_type * ecl_sum_simulated) { - bool ret = true; + bool ret = true; const model_config_type * model_config = enkf_state->shared_info->model_config; - const ecl_sum_type * ecl_sum_reference = model_config_get_refcase(model_config); + const ecl_sum_type * ecl_sum_reference = model_config_get_refcase(model_config); if (ecl_sum_reference) //Can be NULL - ret = ecl_sum_report_step_compatible(ecl_sum_reference, ecl_sum_simulated); - - return ret; + ret = ecl_sum_report_step_compatible(ecl_sum_reference, ecl_sum_simulated); + + return ret; } @@ -591,11 +591,11 @@ static bool enkf_state_internalize_dynamic_eclipse_results(enkf_state_type * enk bool load_summary = ensemble_config_has_impl_type(enkf_state->ensemble_config, SUMMARY); if (load_summary) { int load_start = run_arg_get_load_start( run_arg ); - + if (load_start == 0) { /* Do not attempt to load the "S0000" summary results. */ load_start++; } - + { /* Looking for summary files on disk, and loading them. */ ecl_sum_type * summary = enkf_state_load_ecl_sum( enkf_state , run_arg , msg_list , result ); @@ -604,23 +604,23 @@ static bool enkf_state_internalize_dynamic_eclipse_results(enkf_state_type * enk if (summary != NULL) { int_vector_type * time_index = __enkf_state_get_time_index(result_fs, summary); - /* + /* Now there are two related / conflicting(?) systems for checking summary time consistency, both internally in the time_map and also through the enkf_state_report_step_compatible() function. */ - + /*Check the loaded summary against the reference ecl_sum_type */ if (!enkf_state_report_step_compatible(enkf_state, summary)) { *result |= REPORT_STEP_INCOMPATIBLE; } - + /* The actual loading internalizing - from ecl_sum -> enkf_node. */ const int iens = member_config_get_iens( enkf_state->my_config ); const int step2 = ecl_sum_get_last_report_step( summary ); /* Step2 is just taken from the number of steps found in the summary file. */ - + int_vector_iset_block( time_index , 0 , load_start , -1 ); int_vector_resize( time_index , step2 + 1); @@ -661,7 +661,7 @@ static bool enkf_state_internalize_dynamic_eclipse_results(enkf_state_type * enk } stringlist_free(keys); - ecl_sum_free( summary ); + ecl_sum_free( summary ); int_vector_free( time_index ); return true; } else { @@ -690,14 +690,14 @@ static bool enkf_state_internalize_dynamic_eclipse_results(enkf_state_type * enk __realloc_static_kw("INTEHEAD" , 0) ==> "INTEHEAD_0" - In the enkf layer the key used will then be INTEHEAD_0. + In the enkf layer the key used will then be INTEHEAD_0. */ static char * __realloc_static_kw(char * kw , int occurence) { char * new_kw = util_alloc_sprintf("%s_%d" , kw , occurence); free(kw); - ecl_util_escape_kw(new_kw); + ecl_util_escape_kw(new_kw); return new_kw; } @@ -758,22 +758,22 @@ static void enkf_state_internalize_custom_kw(enkf_state_type * enkf_state, -static void enkf_state_internalize_GEN_DATA(enkf_state_type * enkf_state , - run_arg_type * run_arg , - const model_config_type * model_config , - int last_report , - int * result, - bool interactive , +static void enkf_state_internalize_GEN_DATA(enkf_state_type * enkf_state , + run_arg_type * run_arg , + const model_config_type * model_config , + int last_report , + int * result, + bool interactive , stringlist_type * msg_list) { { member_config_type * my_config = enkf_state->my_config; - const int iens = member_config_get_iens( my_config ); + const int iens = member_config_get_iens( my_config ); stringlist_type * keylist_GEN_DATA = ensemble_config_alloc_keylist_from_impl_type(enkf_state->ensemble_config , GEN_DATA ); enkf_fs_type * result_fs = run_arg_get_result_fs( run_arg ); - + for (int ikey=0; ikey < stringlist_get_size( keylist_GEN_DATA ); ikey++) { enkf_node_type * node = enkf_state_get_node( enkf_state , stringlist_iget( keylist_GEN_DATA , ikey)); - + if (enkf_node_vector_storage(node)) { util_abort("%s: holy shit - vector storage not correctly implemented for GEN_DATA\n",__func__); @@ -783,39 +783,39 @@ static void enkf_state_internalize_GEN_DATA(enkf_state_type * enkf_state , if (interactive) enkf_state_log_GEN_DATA_load( node , 0 , msg_list ); } else { - *result |= LOAD_FAILURE; + *result |= LOAD_FAILURE; ert_log_add_fmt_message(3 , NULL , "[%03d:----] Failed to load data for vector node:%s.",iens , enkf_node_get_key( node )); - if (interactive) + if (interactive) stringlist_append_owned_ref( msg_list , util_alloc_sprintf("Failed to load vector:%s" , enkf_node_get_key( node ))); } - + } else { - + for (int report_step = run_arg_get_load_start( run_arg ); report_step <= last_report; report_step++) { if (enkf_node_internalize(node , report_step)) { - + if (enkf_node_has_func(node , forward_load_func)) { if (enkf_node_forward_load(node , run_arg_get_runpath( run_arg ) , NULL , NULL , report_step , iens )) { - node_id_type node_id = {.report_step = report_step , - .iens = iens , + node_id_type node_id = {.report_step = report_step , + .iens = iens , .state = FORECAST }; enkf_node_store( node , result_fs, false , node_id ); - - if (interactive) + + if (interactive) enkf_state_log_GEN_DATA_load( node , report_step , msg_list ); - + } else { - *result |= LOAD_FAILURE; + *result |= LOAD_FAILURE; ert_log_add_fmt_message(1 , stderr , "[%03d:%04d] Failed load data for node:%s.",iens , report_step , enkf_node_get_key( node )); - - if (interactive) - stringlist_append_owned_ref(msg_list , + + if (interactive) + stringlist_append_owned_ref(msg_list , util_alloc_sprintf("Failed to load: %s at step:%d" , enkf_node_get_key( node ) , report_step)); } } - } - } + } + } } } } @@ -826,66 +826,66 @@ static void enkf_state_internalize_GEN_DATA(enkf_state_type * enkf_state , This function loads the STATE from a forward simulation. In ECLIPSE speak that means to load the solution vectors (PRESSURE/SWAT/..) and the necessary static keywords. - + When the state has been loaded it goes straight to disk. */ -static void enkf_state_internalize_eclipse_state(enkf_state_type * enkf_state , - run_arg_type * run_arg , - const model_config_type * model_config , - int report_step , - bool store_vectors , - int * result, - bool interactive , +static void enkf_state_internalize_eclipse_state(enkf_state_type * enkf_state , + run_arg_type * run_arg , + const model_config_type * model_config , + int report_step , + bool store_vectors , + int * result, + bool interactive , stringlist_type * msg_list) { shared_info_type * shared_info = enkf_state->shared_info; const ecl_config_type * ecl_config = shared_info->ecl_config; enkf_fs_type * result_fs = run_arg_get_result_fs( run_arg ); if (ecl_config_active( ecl_config )) { member_config_type * my_config = enkf_state->my_config; - const int iens = member_config_get_iens( my_config ); + const int iens = member_config_get_iens( my_config ); const bool fmt_file = ecl_config_get_formatted( ecl_config ); const bool unified = ecl_config_get_unified_restart( ecl_config ); const bool internalize_state = model_config_internalize_state( model_config , report_step ); ecl_file_type * restart_file; - - + + /** Loading the restart block. */ - - if (unified) + + if (unified) util_abort("%s: sorry - unified restart files are not supported \n",__func__); { char * filename = ecl_util_alloc_exfilename(run_arg_get_runpath(run_arg) , member_config_get_eclbase(enkf_state->my_config) , ECL_RESTART_FILE , fmt_file , report_step); if (filename) { restart_file = ecl_file_open( filename , 0 ); free(filename); - } else + } else restart_file = NULL; /* No restart information was found; if that is expected the program will fail hard in the enkf_node_forward_load() functions. */ } - + /*****************************************************************/ - - + + /** Iterating through the restart file: - + 1. Build up enkf_state->restart_kw_list. 2. Send static keywords straight out. */ - + if (restart_file) { stringlist_clear( enkf_state->restart_kw_list ); { - int ikw; + int ikw; for (ikw =0; ikw < ecl_file_get_size( restart_file ); ikw++) { ert_impl_type impl_type; const ecl_kw_type * ecl_kw = ecl_file_iget_kw( restart_file , ikw); int occurence = ecl_file_iget_occurence( restart_file , ikw ); /* This is essentially the static counter value. */ char * kw = util_alloc_string_copy( ecl_kw_get_header( ecl_kw ) ); - /** + /** Observe that this test will never succeed for static keywords, because the internalized key has appended a _<occurence>. */ @@ -896,71 +896,71 @@ static void enkf_state_internalize_eclipse_state(enkf_state_type * enkf_state , PRESSURE. The first occurence of PRESSURE will be for the ordinary grid, and then there will be subsequent PRESSURE sections for each LGR section. The way this is implemented here is as follows: - + 1. The first occurence of pressure is internalized as the enkf_node pressure (if we indeed have a pressure node). - + 2. The consecutive pressure nodes are internalized as static parameters. - + The variable 'occurence' is the key here. */ - + if (occurence == 0) { const enkf_config_node_type * config_node = ensemble_config_get_node(enkf_state->ensemble_config , kw); impl_type = enkf_config_node_get_impl_type(config_node); - } else + } else impl_type = STATIC; } else impl_type = STATIC; - - - if (impl_type == FIELD) + + + if (impl_type == FIELD) stringlist_append_copy(enkf_state->restart_kw_list , kw); else if (impl_type == STATIC) { if (ecl_config_include_static_kw(ecl_config , kw)) { /* It is a static kw like INTEHEAD or SCON */ - /* + /* Observe that for static keywords we do NOT ask the node 'privately' if internalize_state is false: It is impossible to single out static keywords for internalization. */ - + /* Now we mangle the static keyword .... */ kw = __realloc_static_kw(kw , occurence); - - if (internalize_state) { + + if (internalize_state) { stringlist_append_copy( enkf_state->restart_kw_list , kw); - + ensemble_config_ensure_static_key(enkf_state->ensemble_config , kw ); - + if (!enkf_state_has_node(enkf_state , kw)) { const enkf_config_node_type * config_node = ensemble_config_get_node(enkf_state->ensemble_config , kw); - enkf_state_add_node(enkf_state , kw , config_node); + enkf_state_add_node(enkf_state , kw , config_node); } - - /* + + /* The following thing can happen: - + 1. A static keyword appears at report step n, and is added to the enkf_state object. - + 2. At report step n+k that static keyword is no longer active, and it is consequently no longer part of restart_kw_list(). - + 3. However it is still part of the enkf_state. Not loaded here, and subsequently purged from enkf_main. - + One keyword where this occurs is FIPOIL, which at least might appear only in the first restart file. Unused static keywords of this type are purged from the enkf_main object by a call to enkf_main_del_unused_static(). The purge is based on looking at the internal __report_step state of the static kw. */ - + { enkf_node_type * enkf_node = enkf_state_get_node(enkf_state , kw); node_id_type node_id = {.report_step = report_step , .iens = iens , .state = FORECAST }; - + enkf_node_ecl_load_static(enkf_node , ecl_kw , report_step , iens); /* Static kewyords go straight out .... @@ -969,7 +969,7 @@ static void enkf_state_internalize_eclipse_state(enkf_state_type * enkf_state , enkf_node_free_data(enkf_node); } } - } + } } else util_abort("%s: hm - something wrong - can (currently) only load FIELD/STATIC implementations from restart files - aborting \n",__func__); free(kw); @@ -977,49 +977,49 @@ static void enkf_state_internalize_eclipse_state(enkf_state_type * enkf_state , enkf_fs_fwrite_restart_kw_list( result_fs , report_step , iens , enkf_state->restart_kw_list ); } } - + /******************************************************************/ - /** + /** Starting on the enkf_node_forward_load() function calls. This is where the actual loading (apart from static keywords) is done. Observe that this loading might involve other load functions than the ones used for loading PRESSURE++ from ECLIPSE restart files (e.g. for loading seismic results..) */ - + { hash_iter_type * iter = hash_iter_alloc(enkf_state->node_hash); while ( !hash_iter_is_complete(iter) ) { enkf_node_type * enkf_node = hash_iter_get_next_value(iter); - if (enkf_node_get_var_type(enkf_node) == DYNAMIC_STATE && + if (enkf_node_get_var_type(enkf_node) == DYNAMIC_STATE && enkf_node_get_impl_type(enkf_node) == FIELD) { bool internalize_kw = internalize_state; if (!internalize_kw) internalize_kw = enkf_node_internalize(enkf_node , report_step); - + if (internalize_kw) { if (enkf_node_has_func(enkf_node , forward_load_func)) { if (enkf_node_forward_load(enkf_node , run_arg_get_runpath( run_arg ) , NULL , restart_file , report_step , iens )) { - node_id_type node_id = {.report_step = report_step , - .iens = iens , + node_id_type node_id = {.report_step = report_step , + .iens = iens , .state = FORECAST }; enkf_node_store( enkf_node , result_fs, store_vectors , node_id ); } else { - *result |= LOAD_FAILURE; + *result |= LOAD_FAILURE; ert_log_add_fmt_message( 1 , NULL , "[%03d:%04d] Failed load data for node:%s.",iens , report_step , enkf_node_get_key( enkf_node )); - - if (interactive) + + if (interactive) stringlist_append_owned_ref(msg_list , util_alloc_sprintf("Failed to load: %s at step:%d" , enkf_node_get_key( enkf_node ) , report_step)); } } - } - } - } + } + } + } hash_iter_free(iter); } - + /*****************************************************************/ /* Cleaning up */ if (restart_file != NULL) ecl_file_close( restart_file ); @@ -1037,7 +1037,7 @@ static void enkf_state_internalize_eclipse_state(enkf_state_type * enkf_state , Will mainly be called at the end of the forward model, but can also be called manually from external scope. */ - + static void enkf_state_internalize_results(enkf_state_type * enkf_state , run_arg_type * run_arg , int * result , bool interactive , stringlist_type * msg_list) { model_config_type * model_config = enkf_state->shared_info->model_config; @@ -1048,7 +1048,7 @@ static void enkf_state_internalize_results(enkf_state_type * enkf_state , run_ar in these results are inferred from the loading of summary results, hence we must load the summary results first. */ - + enkf_state_internalize_dynamic_eclipse_results(enkf_state , run_arg , model_config , result, interactive , msg_list); { enkf_fs_type * result_fs = run_arg_get_result_fs( run_arg ); @@ -1058,28 +1058,28 @@ static void enkf_state_internalize_results(enkf_state_type * enkf_state , run_ar /* If we are in true assimilation mode we use the step2 setting, otherwise we are - just in plain gready-load-mode. + just in plain gready-load-mode. */ if (run_arg_get_run_mode(run_arg) == ENKF_ASSIMILATION) last_report = run_arg_get_step2( run_arg ); /* Ensure that the last step is internalized? */ model_config_set_internalize_state( model_config , last_report); - + for (report_step = run_arg_get_load_start( run_arg ); report_step <= last_report; report_step++) { bool store_vectors = (report_step == last_report) ? true : false; - if (model_config_load_state( model_config , report_step)) + if (model_config_load_state( model_config , report_step)) enkf_state_internalize_eclipse_state(enkf_state , run_arg , model_config , report_step , store_vectors , result , interactive , msg_list); } - + enkf_state_internalize_GEN_DATA(enkf_state , run_arg , model_config , last_report , result , interactive , msg_list); enkf_state_internalize_custom_kw(enkf_state, run_arg, model_config, result, interactive, msg_list); } } -void enkf_state_forward_init(enkf_state_type * enkf_state , - run_arg_type * run_arg , +void enkf_state_forward_init(enkf_state_type * enkf_state , + run_arg_type * run_arg , int * result ) { if (run_arg_get_step1(run_arg) == 0) { @@ -1089,28 +1089,28 @@ void enkf_state_forward_init(enkf_state_type * enkf_state , enkf_node_type * node = hash_iter_get_next_value(iter); if (enkf_node_use_forward_init(node)) { enkf_fs_type * result_fs = run_arg_get_result_fs( run_arg ); - node_id_type node_id = {.report_step = 0 , - .iens = iens , + node_id_type node_id = {.report_step = 0 , + .iens = iens , .state = ANALYZED }; - /* + /* Will not reinitialize; i.e. it is essential that the forward model uses the state given from the stored - instance, and not from the current run of e.g. RMS. + instance, and not from the current run of e.g. RMS. */ - if (!enkf_node_has_data( node , result_fs , node_id)) { + if (!enkf_node_has_data( node , result_fs , node_id)) { if (enkf_node_forward_init(node , run_arg_get_runpath( run_arg ) , iens )) enkf_node_store( node , result_fs , false , node_id ); else { char * init_file = enkf_config_node_alloc_initfile( enkf_node_get_config( node ) , run_arg_get_runpath(run_arg) , iens ); - if (init_file && !util_file_exists( init_file )) + if (init_file && !util_file_exists( init_file )) fprintf(stderr,"File not found: %s - failed to initialize node: %s\n", init_file , enkf_node_get_key( node )); else fprintf(stderr,"Failed to initialize node: %s\n", enkf_node_get_key( node )); - + util_safe_free( init_file ); *result |= LOAD_FAILURE; } @@ -1125,21 +1125,21 @@ void enkf_state_forward_init(enkf_state_type * enkf_state , -void enkf_state_load_from_forward_model(enkf_state_type * enkf_state , - run_arg_type * run_arg , - int * result, - bool interactive , +void enkf_state_load_from_forward_model(enkf_state_type * enkf_state , + run_arg_type * run_arg , + int * result, + bool interactive , stringlist_type * msg_list) { - - + + if (ensemble_config_have_forward_init( enkf_state->ensemble_config )) enkf_state_forward_init( enkf_state , run_arg , result ); - + enkf_state_internalize_results( enkf_state , run_arg , result , interactive , msg_list ); { state_map_type * state_map = enkf_fs_get_state_map( run_arg_get_result_fs( run_arg ) ); int iens = member_config_get_iens( enkf_state->my_config ); - if (*result & LOAD_FAILURE) + if (*result & LOAD_FAILURE) state_map_iset( state_map , iens , STATE_LOAD_FAILURE); else state_map_iset( state_map , iens , STATE_HAS_DATA); @@ -1149,36 +1149,36 @@ void enkf_state_load_from_forward_model(enkf_state_type * enkf_state , /** Observe that this does not return the loadOK flag; it will load as - good as it can all the data it should, and be done with it. + good as it can all the data it should, and be done with it. */ void * enkf_state_load_from_forward_model_mt( void * arg ) { arg_pack_type * arg_pack = arg_pack_safe_cast( arg ); enkf_state_type * enkf_state = enkf_state_safe_cast(arg_pack_iget_ptr( arg_pack , 0 )); run_arg_type * run_arg = arg_pack_iget_ptr( arg_pack , 1 ); - bool interactive = arg_pack_iget_bool( arg_pack , 2 ); + bool interactive = arg_pack_iget_bool( arg_pack , 2 ); stringlist_type * msg_list = arg_pack_iget_ptr( arg_pack , 3 ); bool manual_load = arg_pack_iget_bool( arg_pack , 4 ); int * result = arg_pack_iget_ptr( arg_pack , 5 ); - - int iens = run_arg_get_iens( run_arg ); - - if (manual_load) + + int iens = run_arg_get_iens( run_arg ); + + if (manual_load) state_map_update_undefined(enkf_fs_get_state_map( run_arg_get_result_fs(run_arg) ) , iens , STATE_INITIALIZED); - + enkf_state_load_from_forward_model( enkf_state , run_arg , result , interactive , msg_list ); if (*result & REPORT_STEP_INCOMPATIBLE) { // If refcase has been used for observations: crash and burn. fprintf(stderr,"** Warning the timesteps in refcase and current simulation are not in accordance - something wrong with schedule file?\n"); *result -= REPORT_STEP_INCOMPATIBLE; } - + if (interactive) { printf("."); fflush(stdout); - } + } return NULL; -} +} @@ -1204,7 +1204,7 @@ static void enkf_state_write_restart_file(enkf_state_type * enkf_state , const r for (ikw = 0; ikw < stringlist_get_size(enkf_state->restart_kw_list); ikw++) { kw = stringlist_iget( enkf_state->restart_kw_list , ikw); - /* + /* Observe that here we are *ONLY* iterating over the restart_kw_list instance, and *NOT* the enkf_state instance. I.e. arbitrary dynamic keys, and no-longer-active @@ -1212,26 +1212,26 @@ static void enkf_state_write_restart_file(enkf_state_type * enkf_state , const r If the restart kw_list asks for a keyword which we do not have, we assume it is a static keyword and add it it to the - enkf_state instance. - + enkf_state instance. + This is a bit unfortunate, because a bug/problem of some sort, might be masked (seemingly solved) by adding a static keyword, before things blow up completely at a later instant. - */ - if (!ensemble_config_has_key(enkf_state->ensemble_config , kw)) + */ + if (!ensemble_config_has_key(enkf_state->ensemble_config , kw)) ensemble_config_ensure_static_key(enkf_state->ensemble_config , kw ); - + if (!enkf_state_has_node(enkf_state , kw)) { const enkf_config_node_type * config_node = ensemble_config_get_node(enkf_state->ensemble_config , kw); - enkf_state_add_node(enkf_state , kw , config_node); + enkf_state_add_node(enkf_state , kw , config_node); } - + { - enkf_node_type * enkf_node = enkf_state_get_node(enkf_state , kw); - enkf_var_type var_type = enkf_node_get_var_type(enkf_node); + enkf_node_type * enkf_node = enkf_state_get_node(enkf_state , kw); + enkf_var_type var_type = enkf_node_get_var_type(enkf_node); if (var_type == STATIC_STATE) { - node_id_type node_id = {.report_step = run_arg_get_step1(run_arg) , - .iens = iens , + node_id_type node_id = {.report_step = run_arg_get_step1(run_arg) , + .iens = iens , .state = run_arg_get_dynamic_init_state(run_arg) }; enkf_node_load( enkf_node , fs , node_id); } @@ -1239,7 +1239,7 @@ static void enkf_state_write_restart_file(enkf_state_type * enkf_state , const r /* Pressure and saturations */ if (enkf_node_get_impl_type(enkf_node) == FIELD) enkf_node_ecl_write(enkf_node , NULL , fortio , run_arg_get_step1(run_arg)); - else + else util_abort("%s: internal error wrong implementetion type:%d - node:%s aborting \n",__func__ , enkf_node_get_impl_type(enkf_node) , enkf_node_get_key(enkf_node)); } else if (var_type == STATIC_STATE) { enkf_node_ecl_write(enkf_node , NULL , fortio , run_arg_get_step1(run_arg)); @@ -1249,7 +1249,7 @@ static void enkf_state_write_restart_file(enkf_state_type * enkf_state , const r fprintf(stderr,"node : %s \n",enkf_node_get_key(enkf_node)); util_abort("%s: internal error - should not be here ... \n",__func__); } - + } } fortio_fclose(fortio); @@ -1281,16 +1281,16 @@ void enkf_state_ecl_write(enkf_state_type * enkf_state, const run_arg_type * run stringlist_append_copy(enkf_state->restart_kw_list , "RV"); stringlist_append_copy(enkf_state->restart_kw_list , "RS"); } - + { - /** - This iteration manipulates the hash (thorugh the enkf_state_del_node() call) - + /** + This iteration manipulates the hash (thorugh the enkf_state_del_node() call) + ----------------------------------------------------------------------------------------- T H I S W I L L D E A D L O C K I F T H E H A S H _ I T E R A P I I S U S E D. ----------------------------------------------------------------------------------------- */ - + const shared_info_type * shared_info = enkf_state->shared_info; const model_config_type * model_config = shared_info->model_config; const char * base_name = model_config_get_gen_kw_export_file(model_config); @@ -1310,8 +1310,8 @@ void enkf_state_ecl_write(enkf_state_type * enkf_state, const run_arg_type * run bool forward_init = enkf_node_use_forward_init( enkf_node ); if ((run_arg_get_step1(run_arg) == 0) && (forward_init)) { - node_id_type node_id = {.report_step = 0, - .iens = iens , + node_id_type node_id = {.report_step = 0, + .iens = iens , .state = ANALYZED }; if (enkf_node_has_data( enkf_node , fs , node_id)) @@ -1333,7 +1333,7 @@ void enkf_state_ecl_write(enkf_state_type * enkf_state, const run_arg_type * run /** This function takes a report_step and a analyzed|forecast state as input; the enkf_state instance is set accordingly and written to - disk. + disk. */ @@ -1342,14 +1342,14 @@ void enkf_state_fwrite(const enkf_state_type * enkf_state , enkf_fs_type * fs , const int num_keys = hash_get_size(enkf_state->node_hash); char ** key_list = hash_alloc_keylist(enkf_state->node_hash); int ikey; - + for (ikey = 0; ikey < num_keys; ikey++) { enkf_node_type * enkf_node = hash_get(enkf_state->node_hash , key_list[ikey]); - if (enkf_node_include_type(enkf_node , mask)) { + if (enkf_node_include_type(enkf_node , mask)) { node_id_type node_id = {.report_step = report_step , .iens = member_config_get_iens( my_config ) , .state = state }; enkf_node_store( enkf_node, fs , true , node_id ); } - } + } util_free_stringlist(key_list , num_keys); } @@ -1363,8 +1363,8 @@ void enkf_state_fread(enkf_state_type * enkf_state , enkf_fs_type * fs , int mas for (ikey = 0; ikey < num_keys; ikey++) { enkf_node_type * enkf_node = hash_get(enkf_state->node_hash , key_list[ikey]); if (enkf_node_include_type(enkf_node , mask)) { - node_id_type node_id = {.report_step = report_step , - .iens = member_config_get_iens( my_config ) , + node_id_type node_id = {.report_step = report_step , + .iens = member_config_get_iens( my_config ) , .state = state }; bool forward_init = enkf_node_use_forward_init( enkf_node ); if (forward_init) @@ -1391,7 +1391,7 @@ static void enkf_state_fread_state_nodes(enkf_state_type * enkf_state , enkf_fs_ int ikey; - /* + /* First pass - load all the STATIC nodes. It is essential to use the restart_kw_list when loading static nodes, otherwise static nodes which were only present at e.g. step == 0 will create @@ -1410,7 +1410,7 @@ static void enkf_state_fread_state_nodes(enkf_state_type * enkf_state , enkf_fs_ The restart_kw_list mentions a keyword which is (not yet) part of the enkf_state object. This is assumed to be a static keyword and added as such. - + This will break hard for the following situation: 1. Someone has simulated with a dynamic keyword (i.e. field @@ -1425,7 +1425,7 @@ static void enkf_state_fread_state_nodes(enkf_state_type * enkf_state , enkf_fs_ (or node not found); hopefully this scenario is not very probable. */ - + /* add the config node. */ if (!ensemble_config_has_key( enkf_state->ensemble_config , key)) ensemble_config_ensure_static_key( enkf_state->ensemble_config , key); @@ -1433,15 +1433,15 @@ static void enkf_state_fread_state_nodes(enkf_state_type * enkf_state , enkf_fs_ /* Add the state node */ if (!enkf_state_has_node( enkf_state , key )) { const enkf_config_node_type * config_node = ensemble_config_get_node(enkf_state->ensemble_config , key); - enkf_state_add_node(enkf_state , key , config_node); + enkf_state_add_node(enkf_state , key , config_node); } - + enkf_node = hash_get(enkf_state->node_hash , key); var_type = enkf_node_get_var_type( enkf_node ); - + if (var_type == STATIC_STATE) { - node_id_type node_id = { .report_step = report_step , - .iens = iens , + node_id_type node_id = { .report_step = report_step , + .iens = iens , .state = load_state }; enkf_node_load( enkf_node , fs , node_id); } @@ -1453,25 +1453,25 @@ static void enkf_state_fread_state_nodes(enkf_state_type * enkf_state , enkf_fs_ const int num_keys = hash_get_size(enkf_state->node_hash); char ** key_list = hash_alloc_keylist(enkf_state->node_hash); int ikey; - + for (ikey = 0; ikey < num_keys; ikey++) { enkf_node_type * enkf_node = hash_get(enkf_state->node_hash , key_list[ikey]); enkf_var_type var_type = enkf_node_get_var_type( enkf_node ); - node_id_type node_id = {.report_step = report_step , - .iens = iens , + node_id_type node_id = {.report_step = report_step , + .iens = iens , .state = BOTH }; - + if (var_type == DYNAMIC_STATE) { - /* + /* Here the enkf_node_try_load() function is used NOT because we accept that the node is not present, but because the try_fread() function accepts the BOTH state type. */ - if (!enkf_node_try_load(enkf_node , fs , node_id)) + if (!enkf_node_try_load(enkf_node , fs , node_id)) util_abort("%s: failed to load node:%s report_step:%d iens:%d \n",__func__ , key_list[ikey] , report_step , iens ); } } - util_free_stringlist(key_list , num_keys); + util_free_stringlist(key_list , num_keys); } } @@ -1490,7 +1490,7 @@ static void enkf_state_fread_initial_state(enkf_state_type * enkf_state , enkf_f const int num_keys = hash_get_size(enkf_state->node_hash); char ** key_list = hash_alloc_keylist(enkf_state->node_hash); int ikey; - + for (ikey = 0; ikey < num_keys; ikey++) { enkf_node_type * enkf_node = hash_get(enkf_state->node_hash , key_list[ikey]); if (enkf_node_get_var_type(enkf_node) == DYNAMIC_STATE) { @@ -1499,15 +1499,15 @@ static void enkf_state_fread_initial_state(enkf_state_type * enkf_state , enkf_f /* Just checked for != NULL */ char * load_file = enkf_config_node_alloc_infile( config_node , 0); if (load_file != NULL) { - node_id_type node_id = {.report_step = 0 , - .iens = member_config_get_iens( my_config ) , + node_id_type node_id = {.report_step = 0 , + .iens = member_config_get_iens( my_config ) , .state = ANALYZED }; enkf_node_load(enkf_node , fs , node_id); } - + util_safe_free( load_file ); } - } + } util_free_stringlist(key_list , num_keys); } @@ -1516,16 +1516,16 @@ void enkf_state_free_nodes(enkf_state_type * enkf_state, int mask) { const int num_keys = hash_get_size(enkf_state->node_hash); char ** key_list = hash_alloc_keylist(enkf_state->node_hash); int ikey; - + for (ikey = 0; ikey < num_keys; ikey++) { enkf_node_type * enkf_node = hash_get(enkf_state->node_hash , key_list[ikey]); - if (enkf_node_include_type(enkf_node , mask)) + if (enkf_node_include_type(enkf_node , mask)) enkf_state_del_node(enkf_state , enkf_node_get_key(enkf_node)); - } + } util_free_stringlist(key_list , num_keys); } - + @@ -1555,9 +1555,9 @@ enkf_node_type * enkf_state_get_node(const enkf_state_type * enkf_state , const void enkf_state_del_node(enkf_state_type * enkf_state , const char * node_key) { - if (hash_has_key(enkf_state->node_hash , node_key)) + if (hash_has_key(enkf_state->node_hash , node_key)) hash_del(enkf_state->node_hash , node_key); - else + else fprintf(stderr,"%s: tried to remove node:%s which is not in state - internal error?? \n",__func__ , node_key); } @@ -1591,14 +1591,14 @@ static void enkf_state_set_dynamic_subst_kw__(enkf_state_type * enkf_state , con enkf_state_add_subst_kw(enkf_state , "TSTEP2" , step2_s , NULL); enkf_state_add_subst_kw(enkf_state , "TSTEP1_04" , step1_s04 , NULL); enkf_state_add_subst_kw(enkf_state , "TSTEP2_04" , step2_s04 , NULL); - + free(step1_s); free(step2_s); free(step1_s04); free(step2_s04); } - + /* Restart file names and RESTART keyword in datafile. */ { const char * eclbase = member_config_get_eclbase( enkf_state->my_config ); @@ -1606,10 +1606,10 @@ static void enkf_state_set_dynamic_subst_kw__(enkf_state_type * enkf_state , con { char * restart_file1 = ecl_util_alloc_filename(NULL , eclbase , ECL_RESTART_FILE , fmt_file , step1); char * restart_file2 = ecl_util_alloc_filename(NULL , eclbase , ECL_RESTART_FILE , fmt_file , step2); - + enkf_state_add_subst_kw(enkf_state , "RESTART_FILE1" , restart_file1 , NULL); enkf_state_add_subst_kw(enkf_state , "RESTART_FILE2" , restart_file2 , NULL); - + free(restart_file1); free(restart_file2); } @@ -1631,25 +1631,25 @@ static void enkf_state_set_dynamic_subst_kw__(enkf_state_type * enkf_state , con char * tmp_include = util_alloc_sprintf("INCLUDE\n \'%s\' /\n",init_file); enkf_state_add_subst_kw(enkf_state , "INIT" , tmp_include , NULL); free(tmp_include); - } /* - if init_file == NULL that means the user has not supplied the INIT_SECTION keyword, + } /* + if init_file == NULL that means the user has not supplied the INIT_SECTION keyword, and the EQUIL (or whatever) info to initialize the model is inlined in the datafile. */ - } - - + } + + { - /** + /** Adding keys for <RANDINT> and <RANDFLOAT> - these are only added for backwards compatibility, should be replaced with prober function callbacks. */ char * randint_value = util_alloc_sprintf( "%u" , rng_forward( enkf_state->rng )); char * randfloat_value = util_alloc_sprintf( "%12.10f" , rng_get_double( enkf_state->rng )); - + enkf_state_add_subst_kw( enkf_state , "RANDINT" , randint_value , NULL); enkf_state_add_subst_kw( enkf_state , "RANDFLOAT" , randfloat_value , NULL); - + free( randint_value ); free( randfloat_value ); } @@ -1674,14 +1674,14 @@ void enkf_state_printf_subst_list(enkf_state_type * enkf_state , int step1 , int const char * key = subst_list_iget_key( enkf_state->subst_list , ikw); const char * value = subst_list_iget_value( enkf_state->subst_list , ikw); const char * desc = subst_list_iget_doc_string( enkf_state->subst_list , ikw ); - + if (value != NULL) printf(fmt_string , key , value , desc); else printf(fmt_string , key , "[Not set]" , desc); } printf("------------------------------------------------------------------------------------------------------------------------\n"); - + } @@ -1689,7 +1689,7 @@ void enkf_state_printf_subst_list(enkf_state_type * enkf_state , int step1 , int /** init_step : The parameters are loaded from this EnKF/report step. - report_step1 : The simulation should start from this report step; + report_step1 : The simulation should start from this report step; dynamic data are loaded from this step. report_step2 : The simulation should stop at this report step. (unless run_mode == ENSEMBLE_PREDICTION - where it just runs til end.) @@ -1702,10 +1702,10 @@ void enkf_state_printf_subst_list(enkf_state_type * enkf_state , int step1 , int void enkf_state_init_eclipse(enkf_state_type *enkf_state, const run_arg_type * run_arg ) { - const member_config_type * my_config = enkf_state->my_config; + const member_config_type * my_config = enkf_state->my_config; const ecl_config_type * ecl_config = enkf_state->shared_info->ecl_config; { - if (member_config_pre_clear_runpath( my_config )) + if (member_config_pre_clear_runpath( my_config )) util_clear_directory( run_arg_get_runpath( run_arg ) , true , false ); util_make_path(run_arg_get_runpath( run_arg )); @@ -1721,7 +1721,7 @@ void enkf_state_init_eclipse(enkf_state_type *enkf_state, const run_arg_type * r sched_file_fprintf_i( ecl_config_get_sched_file( ecl_config ) , run_arg_get_step2(run_arg) , schedule_file_target); else sched_file_fprintf( ecl_config_get_sched_file( ecl_config ) , schedule_file_target); - + free(schedule_file_target); } } @@ -1735,20 +1735,20 @@ void enkf_state_init_eclipse(enkf_state_type *enkf_state, const run_arg_type * r enkf_fs_type * init_fs = run_arg_get_init_fs( run_arg ); /* Loading parameter information: loaded from timestep: run_arg->init_step_parameters. */ enkf_state_fread(enkf_state , init_fs , PARAMETER , run_arg_get_parameter_init_step(run_arg) , run_arg_get_parameter_init_state(run_arg)); - - + + /* Loading state information: loaded from timestep: run_arg->step1 */ if (run_arg_get_step1(run_arg) == 0) - enkf_state_fread_initial_state(enkf_state , init_fs); + enkf_state_fread_initial_state(enkf_state , init_fs); else enkf_state_fread_state_nodes( enkf_state , init_fs , run_arg_get_step1(run_arg) , run_arg_get_dynamic_init_state(run_arg)); enkf_state_set_dynamic_subst_kw( enkf_state , run_arg ); ert_templates_instansiate( enkf_state->shared_info->templates , run_arg_get_runpath( run_arg ) , enkf_state->subst_list ); enkf_state_ecl_write( enkf_state , run_arg , init_fs); - + if (member_config_get_eclbase( my_config ) != NULL) { - + /* Writing the ECLIPSE data file. */ if (ecl_config_get_data_file( ecl_config ) != NULL) { char * data_file = ecl_util_alloc_filename(run_arg_get_runpath( run_arg ) , member_config_get_eclbase( my_config ) , ECL_DATA_FILE , true , -1); @@ -1774,14 +1774,14 @@ bool enkf_state_complete_forward_modelEXIT__(void * arg ); bool enkf_state_complete_forward_modelRETRY__(void * arg ); -/** +/** This function is called when: 1. The external queue system has said that everything is OK; BUT the ert layer failed to load all the data. - + 2. The external queue system has seen the job fail. - + The parameter and state variables will be resampled before retrying. And all random elements in templates+++ will be resampled. @@ -1798,7 +1798,7 @@ static void enkf_state_internal_retry(enkf_state_type * enkf_state , run_arg_typ ert_log_add_fmt_message( 1 , NULL , "[%03d:%04d - %04d] Failed to load all data.",iens , run_arg_get_step1(run_arg) , run_arg_get_step2(run_arg)); else ert_log_add_fmt_message( 1 , NULL , "[%03d:%04d - %04d] Forward model failed.",iens, run_arg_get_step1(run_arg) , run_arg_get_step2(run_arg)); - + if (run_arg_can_retry( run_arg ) ) { ert_log_add_fmt_message( 1 , NULL , "[%03d] Resampling and resubmitting realization." ,iens); { @@ -1810,11 +1810,11 @@ static void enkf_state_internal_retry(enkf_state_type * enkf_state , run_arg_typ } stringlist_free( init_keys ); } - + enkf_state_init_eclipse( enkf_state , run_arg ); /* Possibly clear the directory and do a FULL rewrite of ALL the necessary files. */ job_queue_iset_external_restart( shared_info->job_queue , run_arg_get_queue_index(run_arg) ); /* Here we inform the queue system that it should pick up this job and try again. */ run_arg_increase_submit_count( run_arg ); - } + } } @@ -1848,16 +1848,16 @@ static void enkf_state_clear_runpath( const enkf_state_type * enkf_state , run_a unlink_runpath = false; /* Compiler .. */ } } - + if (unlink_runpath) util_clear_directory(run_arg_get_runpath( run_arg ) , true , true); } -/** +/** Observe that if run_arg == false, this routine will return with job_completeOK == true, that might be a bit misleading. - + Observe that if an internal retry is performed, this function will be called several times - MUST BE REENTRANT. */ @@ -1865,9 +1865,9 @@ static void enkf_state_clear_runpath( const enkf_state_type * enkf_state , run_a static bool enkf_state_complete_forward_modelOK(enkf_state_type * enkf_state , run_arg_type * run_arg) { const member_config_type * my_config = enkf_state->my_config; const int iens = member_config_get_iens( my_config ); - int result = 0; + int result = 0; + - /** The queue system has reported that the run is OK, i.e. it has completed and produced the targetfile it should. We then check @@ -1875,15 +1875,15 @@ static bool enkf_state_complete_forward_modelOK(enkf_state_type * enkf_state , r is OK the final status is updated, otherwise: restart. */ ert_log_add_fmt_message( 2 , NULL , "[%03d:%04d-%04d] Forward model complete - starting to load results." , iens , run_arg_get_step1(run_arg), run_arg_get_step2(run_arg)); - enkf_state_load_from_forward_model(enkf_state , run_arg , &result , false , NULL); - + enkf_state_load_from_forward_model(enkf_state , run_arg , &result , false , NULL); + if (result & REPORT_STEP_INCOMPATIBLE) { // If refcase has been used for observations: crash and burn. fprintf(stderr,"** Warning the timesteps in refcase and current simulation are not in accordance - something wrong with schedule file?\n"); result -= REPORT_STEP_INCOMPATIBLE; } - - + + if (0 == result) { /* The loading succeded - so this is a howling success! We set @@ -1893,11 +1893,11 @@ static bool enkf_state_complete_forward_modelOK(enkf_state_type * enkf_state , r */ run_arg_set_run_status( run_arg , JOB_RUN_OK); ert_log_add_fmt_message( 2 , NULL , "[%03d:%04d-%04d] Results loaded successfully." , iens , run_arg_get_step1(run_arg), run_arg_get_step2(run_arg)); - + enkf_state_clear_runpath( enkf_state , run_arg ); run_arg_complete_run(run_arg); /* free() on runpath */ - } - return (0 == result) ? true : false; + } + return (0 == result) ? true : false; } @@ -1905,7 +1905,7 @@ bool enkf_state_complete_forward_modelOK__(void * arg ) { arg_pack_type * arg_pack = arg_pack_safe_cast( arg ); enkf_state_type * enkf_state = enkf_state_safe_cast( arg_pack_iget_ptr( arg_pack , 0 )); run_arg_type * run_arg = run_arg_safe_cast( arg_pack_iget_ptr( arg_pack , 1 )); - + return enkf_state_complete_forward_modelOK( enkf_state , run_arg); } @@ -1914,12 +1914,12 @@ bool enkf_state_complete_forward_modelOK__(void * arg ) { static bool enkf_state_complete_forward_model_EXIT_handler__(enkf_state_type * enkf_state , run_arg_type * run_arg , bool is_retry) { const member_config_type * my_config = enkf_state->my_config; const int iens = member_config_get_iens( my_config ); - /* + /* The external queue system has said that the job failed - we might give it another try from this scope, possibly involving a resampling. */ - + if (is_retry) { if (run_arg_can_retry(run_arg)) { enkf_state_internal_retry(enkf_state, run_arg , false); @@ -1942,10 +1942,10 @@ static bool enkf_state_complete_forward_model_EXIT_handler__(enkf_state_type * e static bool enkf_state_complete_forward_model_EXIT_handler(void * arg, bool allow_retry ) { arg_pack_type * arg_pack = arg_pack_safe_cast( arg ); - + enkf_state_type * enkf_state = arg_pack_iget_ptr( arg_pack , 0 ); run_arg_type * run_arg = arg_pack_iget_ptr( arg_pack , 1 ); - + return enkf_state_complete_forward_model_EXIT_handler__( enkf_state , run_arg , allow_retry ); } diff --git a/ThirdParty/Ert/devel/libenkf/src/local_config.c b/ThirdParty/Ert/devel/libenkf/src/local_config.c index b885f1ba39..2930e0ee94 100644 --- a/ThirdParty/Ert/devel/libenkf/src/local_config.c +++ b/ThirdParty/Ert/devel/libenkf/src/local_config.c @@ -60,11 +60,10 @@ ministep to the updatestep, otherwise it will not be able to do anything. -CREATE_MINISTEP [NAME_OF_MINISTEP OBSSET_NAME] +CREATE_MINISTEP [NAME_OF_MINISTEP] ----------------------------------------------- This function will create a new ministep with the name -'NAME_OF_MINISTEP'. The ministep will be based on the observation -set given by OBSSET_NAME (which must be created first).The ministep +'NAME_OF_MINISTEP'. A given OBSSET can be attached to a given ministep.The ministep is then ready for adding data. Before the ministep can be used you must attach it to an updatestep with the ATTACH_MINISTEP command @@ -147,7 +146,7 @@ This function will delete the obs 'OBS_KEY' from the obsset DATASET_DEL_ALL_DATA [NAME_OF_DATASET] -------------------------------------- This function will delete all the data keys from the dataset -'NAME_OF_MINISTEP'. +'NAME_OF_DATASET'. OBSSET_DEL_ALL_OBS [NAME_OF_OBSSET] @@ -171,26 +170,13 @@ with name 'DATASTEP_NAME' should have the index 'INDEX' active. ACTIVE_LIST_ADD_MANY_OBS_INDEX[OBSSET_NAME OBS_KEY N INDEX1 INDEX2 INDEX3 .. INDEXN] ---------------------------------------------------------------------------------------- -This function is simular to ACTIVE_LIST_ADD_OBS_INDEX, but it will add many indices. +This function is similar to ACTIVE_LIST_ADD_OBS_INDEX, but it will add many indices. ACTIVE_LIST_ADD_MANY_DATA_INDEX[DATA_NAME DATA_KEY N INDEX1 INDEX2 INDEX3 .. INDEXN] ------------------------------------------------------------------------------------------ -This function is simular to ACTIVE_LIST_ADD_DATA_INDEX, but it will add many indices. - - -INSTALL_UPDATESTEP [NAME_OF_UPDATESTEP STEP1 STEP2] ----------------------------------------------------- -This function will install the updatestep 'NAME_OF_UPDATESTEP' for the -report steps [STEP1,..,STEP2]. - - -INSTALL_DEFAULT_UPDATESTEP [NAME_OF_UPDATESTEP] ------------------------------------------------ -This function will install 'NAME_OF_UPDATESTEP' as the default -updatestep which applies to all report streps where you have not -explicitly set another updatestep with the INSTALL_UPDATESTEP function. +This function is similar to ACTIVE_LIST_ADD_DATA_INDEX, but it will add many indices. @@ -522,7 +508,6 @@ core EnKF updating: struct local_config_struct { - vector_type * updatestep; /* This is an indexed vector with (pointers to) local_reportsstep instances. */ local_updatestep_type * default_updatestep; /* A default report step returned if no particular report step has been installed for this time index. */ hash_type * updatestep_storage; /* These three hash tables are the 'holding area' for the local_updatestep, */ hash_type * ministep_storage; /* local_ministep instances. */ @@ -532,13 +517,26 @@ struct local_config_struct { }; -static void local_config_clear( local_config_type * local_config ) { +/** + Instances of local_updatestep and local_ministep are allocated from + the local_config object, and then subsequently manipulated from the calling scope. +*/ + +static local_updatestep_type * local_config_alloc_updatestep( local_config_type * local_config , const char * key ) { + local_updatestep_type * updatestep = local_updatestep_alloc( key ); + hash_insert_hash_owned_ref( local_config->updatestep_storage , key , updatestep , local_updatestep_free__); + return updatestep; +} + + + +void local_config_clear( local_config_type * local_config ) { local_config->default_updatestep = NULL; hash_clear( local_config->updatestep_storage ); hash_clear( local_config->ministep_storage ); hash_clear( local_config->dataset_storage ); hash_clear( local_config->obsdata_storage ); - vector_clear( local_config->updatestep ); + local_config->default_updatestep = local_config_alloc_updatestep(local_config, "DEFAULT"); } @@ -552,7 +550,6 @@ local_config_type * local_config_alloc( ) { local_config->ministep_storage = hash_alloc(); local_config->dataset_storage = hash_alloc(); local_config->obsdata_storage = hash_alloc(); - local_config->updatestep = vector_alloc_new(); local_config->config_files = stringlist_alloc_new(); local_config_clear( local_config ); @@ -561,7 +558,6 @@ local_config_type * local_config_alloc( ) { void local_config_free(local_config_type * local_config) { - vector_free( local_config->updatestep ); hash_free( local_config->updatestep_storage ); hash_free( local_config->ministep_storage); hash_free( local_config->dataset_storage); @@ -571,32 +567,12 @@ void local_config_free(local_config_type * local_config) { -/** - Actual report step must have been installed in the - updatestep_storage with local_config_alloc_updatestep() first. -*/ -void local_config_set_default_updatestep( local_config_type * local_config , const char * default_key) { - local_updatestep_type * default_updatestep = local_config_get_updatestep( local_config , default_key ); - local_config->default_updatestep = default_updatestep; -} -/** - Instances of local_updatestep and local_ministep are allocated from - the local_config object, and then subsequently manipulated from the calling scope. -*/ -local_updatestep_type * local_config_alloc_updatestep( local_config_type * local_config , const char * key ) { - local_updatestep_type * updatestep = local_updatestep_alloc( key ); - hash_insert_hash_owned_ref( local_config->updatestep_storage , key , updatestep , local_updatestep_free__); - return updatestep; -} - - -local_ministep_type * local_config_alloc_ministep( local_config_type * local_config , const char * key , const char * obsset_name) { - local_obsdata_type * obsdata = hash_get( local_config->obsdata_storage , obsset_name ); - local_ministep_type * ministep = local_ministep_alloc( key , obsdata ); +local_ministep_type * local_config_alloc_ministep( local_config_type * local_config , const char * key) { + local_ministep_type * ministep = local_ministep_alloc( key ); hash_insert_hash_owned_ref( local_config->ministep_storage , key , ministep , local_ministep_free__); return ministep; } @@ -608,7 +584,6 @@ local_obsdata_type * local_config_alloc_obsset( local_config_type * local_config } - local_dataset_type * local_config_alloc_dataset( local_config_type * local_config , const char * key ) { local_dataset_type * dataset = local_dataset_alloc( key ); hash_insert_hash_owned_ref( local_config->dataset_storage , key , dataset , local_dataset_free__); @@ -664,14 +639,8 @@ local_ministep_type * local_config_alloc_ministep_copy( local_config_type * loca -const local_updatestep_type * local_config_iget_updatestep( const local_config_type * local_config , int index) { - const local_updatestep_type * updatestep = vector_safe_iget_const( local_config->updatestep , index ); - if (updatestep == NULL) - /* - No particular report step has been installed for this - time-index, revert to the default. - */ - updatestep = local_config->default_updatestep; +local_updatestep_type * local_config_get_updatestep( const local_config_type * local_config) { + local_updatestep_type * updatestep = local_config->default_updatestep; if (updatestep == NULL) util_exit("%s: fatal error. No report step information for step:%d - and no default \n",__func__ , index); @@ -680,27 +649,6 @@ const local_updatestep_type * local_config_iget_updatestep( const local_config_t } -local_updatestep_type * local_config_get_updatestep( const local_config_type * local_config , const char * key) { - return hash_get( local_config->updatestep_storage , key ); -} - - -/** - This will 'install' the updatestep instance identified with 'key' - for report steps [step1,step2]. Observe that the report step must - have been allocated with 'local_config_alloc_updatestep()' first. -*/ - - -void local_config_set_updatestep(local_config_type * local_config, int step1 , int step2 , const char * key) { - local_updatestep_type * updatestep = hash_get( local_config->updatestep_storage , key ); - int step; - - for ( step = step1; step < step2 + 1; step++) - vector_safe_iset_ref(local_config->updatestep , step , updatestep ); - -} - /*******************************************************************/ /* Functions related to loading a local config instance from disk. */ @@ -739,6 +687,9 @@ const char * local_config_get_cmd_string( local_config_instruction_type cmd ) { case(CREATE_OBSSET): return CREATE_OBSSET_STRING; break; + case(ATTACH_OBSSET): + return ATTACH_OBSSET_STRING; + break; case(ADD_DATA): return ADD_DATA_STRING; break; @@ -757,12 +708,6 @@ const char * local_config_get_cmd_string( local_config_instruction_type cmd ) { case(ACTIVE_LIST_ADD_MANY_DATA_INDEX): return ACTIVE_LIST_ADD_MANY_DATA_INDEX_STRING; break; - case(INSTALL_UPDATESTEP): - return INSTALL_UPDATESTEP_STRING; - break; - case(INSTALL_DEFAULT_UPDATESTEP): - return INSTALL_DEFAULT_UPDATESTEP_STRING; - break; case(DEL_DATA): return DEL_DATA_STRING; break; @@ -947,12 +892,11 @@ static void local_config_init_cmd_table( hash_type * cmd_table ) { hash_insert_int(cmd_table , CREATE_OBSSET_STRING , CREATE_OBSSET); hash_insert_int(cmd_table , ADD_DATA_STRING , ADD_DATA); hash_insert_int(cmd_table , ADD_OBS_STRING , ADD_OBS ); + hash_insert_int(cmd_table , ATTACH_OBSSET_STRING , ATTACH_OBSSET); hash_insert_int(cmd_table , ACTIVE_LIST_ADD_OBS_INDEX_STRING , ACTIVE_LIST_ADD_OBS_INDEX); hash_insert_int(cmd_table , ACTIVE_LIST_ADD_DATA_INDEX_STRING , ACTIVE_LIST_ADD_DATA_INDEX); hash_insert_int(cmd_table , ACTIVE_LIST_ADD_MANY_OBS_INDEX_STRING , ACTIVE_LIST_ADD_MANY_OBS_INDEX); hash_insert_int(cmd_table , ACTIVE_LIST_ADD_MANY_DATA_INDEX_STRING , ACTIVE_LIST_ADD_MANY_DATA_INDEX); - hash_insert_int(cmd_table , INSTALL_UPDATESTEP_STRING , INSTALL_UPDATESTEP); - hash_insert_int(cmd_table , INSTALL_DEFAULT_UPDATESTEP_STRING , INSTALL_DEFAULT_UPDATESTEP); hash_insert_int(cmd_table , DEL_DATA_STRING , DEL_DATA); hash_insert_int(cmd_table , DEL_OBS_STRING , DEL_OBS); hash_insert_int(cmd_table , COPY_DATASET_STRING , COPY_DATASET); @@ -990,10 +934,8 @@ static void local_config_CREATE_UPDATESTEP( local_config_type * config , local_c static void local_config_CREATE_MINISTEP( local_config_type * config , local_context_type * context , FILE * stream , bool binary) { char * mini_name = read_alloc_string( stream , binary ); - char * obs_name = read_alloc_string( stream , binary ); - local_config_alloc_ministep( config , mini_name , obs_name ); + local_config_alloc_ministep( config , mini_name ); free( mini_name ); - free( obs_name ); } @@ -1009,7 +951,7 @@ static void local_config_ATTACH_MINISTEP( local_config_type * config , local_con char * update_name = read_alloc_string( stream , binary ); char * mini_name = read_alloc_string( stream , binary ); { - local_updatestep_type * update = local_config_get_updatestep( config , update_name ); + local_updatestep_type * update = local_config_get_updatestep( config ); local_ministep_type * ministep = local_config_get_ministep( config , mini_name ); local_updatestep_add_ministep( update , ministep ); } @@ -1054,6 +996,18 @@ static void local_config_ATTACH_DATASET( local_config_type * config , local_cont free( dataset_name ); } +static void local_config_ATTACH_OBSSET( local_config_type * config , local_context_type * context , FILE * stream , bool binary) { + char * mini_name = read_alloc_string( stream , binary ); + char * obsset_name = read_alloc_string( stream , binary ); + { + local_ministep_type * ministep = local_config_get_ministep( config , mini_name ); + local_obsdata_type * obsdata = hash_get( config->obsdata_storage , obsset_name ); + local_ministep_add_obsdata(ministep, obsdata); + } + free( mini_name ); + free( obsset_name ); +} + static void local_config_ADD_DATA( local_config_type * config , local_context_type * context , FILE * stream , bool binary) { char * dataset_name = read_alloc_string( stream , binary ); char * data_key = read_alloc_string( stream , binary ); @@ -1158,23 +1112,7 @@ static void local_config_ACTIVE_LIST_ADD_MANY_DATA_INDEX( local_config_type * co int_vector_free( int_vector ); } -static void local_config_INSTALL_UPDATESTEP( local_config_type * config , local_context_type * context , FILE * stream , bool binary) { - char * update_name = read_alloc_string( stream , binary ); - { - int step1,step2; - - step1 = read_int( stream , binary ); - step2 = read_int( stream , binary ); - local_config_set_updatestep( config , step1 , step2 , update_name ); - } - free( update_name ); -} -static void local_config_INSTALL_DEFAULT_UPDATESTEP( local_config_type * config , local_context_type * context , FILE * stream , bool binary) { - char * update_name = read_alloc_string( stream , binary ); - local_config_set_default_updatestep( config , update_name ); - free( update_name ); -} static void local_config_DEL_DATA( local_config_type * config , local_context_type * context , FILE * stream , bool binary) { char * dataset_name = read_alloc_string( stream , binary ); @@ -1606,6 +1544,9 @@ static void local_config_load_file( local_config_type * local_config , case(ATTACH_DATASET): local_config_ATTACH_DATASET( local_config , context , stream , binary ); break; + case(ATTACH_OBSSET): + local_config_ATTACH_OBSSET( local_config , context , stream , binary ); + break; case(ADD_DATA): local_config_ADD_DATA( local_config , context , stream , binary ); break; @@ -1624,12 +1565,6 @@ static void local_config_load_file( local_config_type * local_config , case(ACTIVE_LIST_ADD_MANY_DATA_INDEX): local_config_ACTIVE_LIST_ADD_MANY_DATA_INDEX( local_config , context , stream , binary ); break; - case(INSTALL_UPDATESTEP): - local_config_INSTALL_UPDATESTEP( local_config , context , stream , binary ); - break; - case(INSTALL_DEFAULT_UPDATESTEP): - local_config_INSTALL_DEFAULT_UPDATESTEP( local_config , context , stream , binary ); - break; case(DEL_DATA): local_config_DEL_DATA( local_config , context , stream , binary ); break; @@ -1729,49 +1664,74 @@ void local_config_reload( local_config_type * local_config , void local_config_fprintf( const local_config_type * local_config , const char * config_file) { FILE * stream = util_mkdir_fopen( config_file , "w"); - /* Start with dumping all the ministep instances. */ + + /* Write DATASET. */ { - hash_iter_type * hash_iter = hash_iter_alloc( local_config->ministep_storage ); + hash_iter_type * hash_iter = hash_iter_alloc( local_config->dataset_storage ); while (!hash_iter_is_complete( hash_iter )) { - const local_ministep_type * ministep = hash_iter_get_next_value( hash_iter ); - local_ministep_fprintf( ministep , stream ); + const local_dataset_type * dataset = hash_iter_get_next_value( hash_iter ); + local_dataset_fprintf( dataset , stream ); } hash_iter_free( hash_iter ); } - - /* Dumping all the reportstep instances as ATTACH_MINISTEP commands. */ + /* Write OBSDATA. */ { - hash_iter_type * hash_iter = hash_iter_alloc( local_config->updatestep_storage ); + hash_iter_type * hash_iter = hash_iter_alloc( local_config->obsdata_storage ); while (!hash_iter_is_complete( hash_iter )) { - const local_updatestep_type * updatestep = hash_iter_get_next_value( hash_iter ); - local_updatestep_fprintf( updatestep , stream ); + const local_obsdata_type * obsdata = hash_iter_get_next_value( hash_iter ); + local_obsdata_fprintf( obsdata , stream ); } hash_iter_free( hash_iter ); } - /* Writing out the updatestep / time */ + + /* Write MINISTEP. */ { - int i; - for (i=0; i < vector_get_size( local_config->updatestep ); i++) { - const local_updatestep_type * updatestep = vector_iget_const( local_config->updatestep , i ); - if (updatestep != NULL) - fprintf(stream , "%s %s %d %d \n", local_config_get_cmd_string( INSTALL_UPDATESTEP ) , local_updatestep_get_name( updatestep ) , i , i ); + hash_iter_type * hash_iter = hash_iter_alloc( local_config->ministep_storage ); + + while (!hash_iter_is_complete( hash_iter )) { + const local_ministep_type * ministep = hash_iter_get_next_value( hash_iter ); + local_ministep_fprintf( ministep , stream ); } + + hash_iter_free( hash_iter ); } - /* Installing the default updatestep */ - if (local_config->default_updatestep != NULL) - fprintf(stream , "%s %s\n", local_config_get_cmd_string( INSTALL_DEFAULT_UPDATESTEP ) , local_updatestep_get_name( local_config->default_updatestep )); + + /* Write UPDATESTEP */ + if (local_config->default_updatestep) + local_updatestep_fprintf( local_config->default_updatestep , stream ); fclose( stream ); } +void local_config_summary_fprintf( const local_config_type * local_config , const char * config_file) { + + FILE * stream = util_mkdir_fopen( config_file , "w"); + + const local_updatestep_type * updatestep = local_config_get_updatestep( local_config ); // There is only one update step, the default + { + hash_iter_type * hash_iter = hash_iter_alloc( local_config->ministep_storage ); + while (!hash_iter_is_complete( hash_iter )) { + const local_ministep_type * ministep = hash_iter_get_next_value( hash_iter ); + + fprintf(stream , "UPDATE_STEP:%s,", local_updatestep_get_name(updatestep)); + + local_ministep_summary_fprintf( ministep , stream); + + } + + hash_iter_free( hash_iter ); + } + + fclose( stream ); +} void local_config_fprintf_config( const local_config_type * local_config , FILE * stream) { fprintf( stream , CONFIG_COMMENTLINE_FORMAT ); diff --git a/ThirdParty/Ert/devel/libenkf/src/local_dataset.c b/ThirdParty/Ert/devel/libenkf/src/local_dataset.c index aa29cf4040..e1351242e9 100644 --- a/ThirdParty/Ert/devel/libenkf/src/local_dataset.c +++ b/ThirdParty/Ert/devel/libenkf/src/local_dataset.c @@ -1,19 +1,19 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'local_nodeset.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> - for more details. + Copyright (C) 2011 Statoil ASA, Norway. + + The file 'local_dataset.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> + for more details. */ @@ -25,7 +25,7 @@ #include <ert/enkf/enkf_macros.h> #include <ert/enkf/local_ministep.h> -#include <ert/enkf/local_config.h> +#include <ert/enkf/local_config.h> #include <ert/enkf/active_list.h> #include <ert/enkf/local_dataset.h> @@ -93,6 +93,10 @@ void local_dataset_add_node(local_dataset_type * dataset, const char *node_key) hash_insert_hash_owned_ref( dataset->nodes , node_key , active_list_alloc( ALL_ACTIVE ) , active_list_free__); } +bool local_dataset_has_key(const local_dataset_type * dataset, const char * key) { + return hash_has_key( dataset->nodes , key ); +} + void local_dataset_del_node( local_dataset_type * dataset , const char * node_key) { hash_del( dataset->nodes , node_key ); @@ -114,17 +118,33 @@ stringlist_type * local_dataset_alloc_keys( const local_dataset_type * dataset ) void local_dataset_fprintf( const local_dataset_type * dataset , FILE * stream) { + fprintf(stream , "\n%s %s\n", local_config_get_cmd_string( CREATE_DATASET ), local_dataset_get_name(dataset)); + { hash_iter_type * data_iter = hash_iter_alloc( dataset->nodes ); while (!hash_iter_is_complete( data_iter )) { const char * data_key = hash_iter_get_next_key( data_iter ); active_list_type * active_list = hash_get( dataset->nodes , data_key ); - + fprintf(stream , "%s %s %s\n", local_config_get_cmd_string( ADD_DATA ) , dataset->name , data_key ); - active_list_fprintf( active_list , false , data_key , stream ); + active_list_fprintf( active_list , local_dataset_get_name(dataset) , data_key , stream ); } hash_iter_free( data_iter ); + } } +void local_dataset_summary_fprintf( const local_dataset_type * dataset , FILE * stream) { +{ + hash_iter_type * data_iter = hash_iter_alloc( dataset->nodes ); + while (!hash_iter_is_complete( data_iter )) { + const char * data_key = hash_iter_get_next_key( data_iter ); + fprintf(stream , "NAME OF DATA:%s,", data_key ); + + active_list_type * active_list = hash_get( dataset->nodes , data_key ); + active_list_summary_fprintf( active_list , local_dataset_get_name(dataset) , data_key , stream); + } + hash_iter_free( data_iter ); + } +} int local_dataset_get_size( const local_dataset_type * dataset ) { diff --git a/ThirdParty/Ert/devel/libenkf/src/local_ministep.c b/ThirdParty/Ert/devel/libenkf/src/local_ministep.c index e96d226ca2..345d67eb78 100644 --- a/ThirdParty/Ert/devel/libenkf/src/local_ministep.c +++ b/ThirdParty/Ert/devel/libenkf/src/local_ministep.c @@ -28,6 +28,7 @@ #include <ert/enkf/local_ministep.h> #include <ert/enkf/local_dataset.h> #include <ert/enkf/local_obsdata.h> +#include <ert/enkf/local_obsdata_node.h> /** This file implements a 'ministep' configuration for active / @@ -65,11 +66,18 @@ struct local_ministep_struct { UTIL_SAFE_CAST_FUNCTION(local_ministep , LOCAL_MINISTEP_TYPE_ID) UTIL_IS_INSTANCE_FUNCTION(local_ministep , LOCAL_MINISTEP_TYPE_ID) -local_ministep_type * local_ministep_alloc(const char * name , local_obsdata_type * observations) { +local_ministep_type * local_ministep_alloc(const char * name) { local_ministep_type * ministep = util_malloc( sizeof * ministep ); ministep->name = util_alloc_string_copy( name ); - ministep->observations = observations; + + char* obsdata_name = "OBSDATA_"; + char* result = malloc(strlen(obsdata_name)+strlen(name)+1); + strcpy(result, obsdata_name); + strcat(result, name); + ministep->observations = local_obsdata_alloc(result); + + ministep->datasets = hash_alloc(); UTIL_TYPE_ID_INIT( ministep , LOCAL_MINISTEP_TYPE_ID); @@ -106,6 +114,7 @@ local_ministep_type * local_ministep_alloc_copy( const local_ministep_type * src void local_ministep_free(local_ministep_type * ministep) { free(ministep->name); hash_free( ministep->datasets ); + local_obsdata_free(ministep->observations); free( ministep ); } @@ -135,7 +144,31 @@ void local_ministep_add_dataset( local_ministep_type * ministep , const local_da hash_insert_ref( ministep->datasets , local_dataset_get_name( dataset ) , dataset ); } +void local_ministep_add_obsdata( local_ministep_type * ministep , local_obsdata_type * obsdata) { + if (ministep->observations == NULL) + ministep->observations = obsdata; + else { // Add nodes from input observations to existing observations + int iobs; + for (iobs = 0; iobs < local_obsdata_get_size( obsdata ); iobs++) { + local_obsdata_node_type * obs_node = local_obsdata_iget( obsdata , iobs ); + local_obsdata_node_type * new_node = local_obsdata_node_alloc_copy(obs_node); + local_ministep_add_obsdata_node(ministep, new_node); + } + } +} + +void local_ministep_add_obsdata_node( local_ministep_type * ministep , local_obsdata_node_type * obsdatanode) { + local_obsdata_type * obsdata = local_ministep_get_obsdata(ministep); + local_obsdata_add_node(obsdata, obsdatanode); +} + +bool local_ministep_has_dataset( const local_ministep_type * ministep, const char * dataset_name) { + return hash_has_key( ministep->datasets, dataset_name ); +} +int local_ministep_get_num_dataset( const local_ministep_type * ministep ) { + return hash_get_size( ministep->datasets ); +} local_dataset_type * local_ministep_get_dataset( const local_ministep_type * ministep, const char * dataset_name) { return hash_get( ministep->datasets, dataset_name ); @@ -145,29 +178,108 @@ local_obsdata_type * local_ministep_get_obsdata( const local_ministep_type * min return ministep->observations; } - - const char * local_ministep_get_name( const local_ministep_type * ministep ) { return ministep->name; } - /*****************************************************************/ hash_iter_type * local_ministep_alloc_dataset_iter( const local_ministep_type * ministep ) { return hash_iter_alloc( ministep->datasets ); } +/*****************************************************************/ -void local_ministep_fprintf( const local_ministep_type * ministep , FILE * stream ) { - fprintf(stream , "%s %s %s\n", local_config_get_cmd_string( CREATE_MINISTEP ), ministep->name , local_obsdata_get_name( ministep->observations) ); +/* + The keys referenced in the local_ministep_alloc_data_keys() and + local_ministep_has_data_key() are the underlying *enkf_node* keys - + not the keys used to index the local_datasets managed by this + local_ministep. +*/ + +stringlist_type * local_ministep_alloc_data_keys( const local_ministep_type * ministep ) { + stringlist_type * keys = stringlist_alloc_new(); { hash_iter_type * dataset_iter = hash_iter_alloc( ministep->datasets ); while (!hash_iter_is_complete( dataset_iter )) { - const char * dataset_key = hash_iter_get_next_key( dataset_iter ); + const local_dataset_type * dataset = hash_iter_get_next_value( dataset_iter ); + stringlist_type * node_keys = local_dataset_alloc_keys( dataset ); + for (int i=0; i < stringlist_get_size( node_keys ); i++) { + const char * data_key = stringlist_iget( node_keys , i ); + if (!stringlist_contains(keys , data_key )) + stringlist_append_copy( keys , data_key ); + } + stringlist_free( node_keys ); + } + hash_iter_free( dataset_iter ); + } + return keys; +} + - fprintf(stream , "%s %s %s\n", local_config_get_cmd_string( ATTACH_DATASET ) , ministep->name , dataset_key ); +bool local_ministep_has_data_key(const local_ministep_type * ministep , const char * key) { + bool has_key = false; + { + hash_iter_type * dataset_iter = hash_iter_alloc( ministep->datasets ); + + while (true) { + const local_dataset_type * dataset = hash_iter_get_next_value( dataset_iter ); + if (dataset) { + if (local_dataset_has_key( dataset , key)) { + has_key = true; + break; + } + } else + break; } + hash_iter_free( dataset_iter ); } + return has_key; } + +/*****************************************************************/ + +void local_ministep_fprintf( const local_ministep_type * ministep , FILE * stream ) { + fprintf(stream , "\n%s %s\n", local_config_get_cmd_string( CREATE_MINISTEP ), ministep->name); + { + /* Dumping all the DATASET instances. */ + { + hash_iter_type * dataset_iter = hash_iter_alloc( ministep->datasets ); + while (!hash_iter_is_complete( dataset_iter )) { + const local_dataset_type * dataset = hash_iter_get_next_value( dataset_iter ); + fprintf(stream , "%s %s %s\n", local_config_get_cmd_string( ATTACH_DATASET ) , ministep->name , local_dataset_get_name( dataset ) ); + } + hash_iter_free( dataset_iter ); + } + + /* Only one OBSDATA */ + local_obsdata_type * obsdata = local_ministep_get_obsdata(ministep); + local_obsdata_fprintf( obsdata , stream ); + fprintf(stream , "%s %s %s\n", local_config_get_cmd_string( ATTACH_OBSSET ) , ministep->name, local_obsdata_get_name(obsdata)); + } +} + +void local_ministep_summary_fprintf( const local_ministep_type * ministep , FILE * stream) { + + fprintf(stream , "MINISTEP:%s,", ministep->name); + + { + /* Dumping all the DATASET instances. */ + { + hash_iter_type * dataset_iter = hash_iter_alloc( ministep->datasets ); + while (!hash_iter_is_complete( dataset_iter )) { + const local_dataset_type * dataset = hash_iter_get_next_value( dataset_iter ); + local_dataset_summary_fprintf(dataset, stream); + } + hash_iter_free( dataset_iter ); + } + + /* Only one OBSDATA */ + local_obsdata_type * obsdata = local_ministep_get_obsdata(ministep); + local_obsdata_summary_fprintf( obsdata , stream); + fprintf(stream, "\n"); + } +} + + diff --git a/ThirdParty/Ert/devel/libenkf/src/local_obsdata.c b/ThirdParty/Ert/devel/libenkf/src/local_obsdata.c index e4f4f40672..fa33e8d14e 100644 --- a/ThirdParty/Ert/devel/libenkf/src/local_obsdata.c +++ b/ThirdParty/Ert/devel/libenkf/src/local_obsdata.c @@ -22,6 +22,7 @@ #include <ert/util/vector.h> #include <ert/util/hash.h> +#include <ert/enkf/local_config.h> #include <ert/enkf/local_obsdata.h> @@ -145,3 +146,29 @@ void local_obsdata_reset_tstep_list( local_obsdata_type * data , const int_vecto local_obsdata_node_reset_tstep_list(node, step_list); } } + + +void local_obsdata_fprintf( const local_obsdata_type * obsdata , FILE * stream ) { +fprintf(stream , "\n%s %s\n", local_config_get_cmd_string( CREATE_OBSSET ) , local_obsdata_get_name(obsdata)); + { + int i; + for (i=0; i < local_obsdata_get_size( obsdata ); i++ ) { + local_obsdata_node_type * node = local_obsdata_iget( obsdata , i ); + const char * obs_key = local_obsdata_node_get_key(node); + + fprintf(stream , "%s %s %s\n", local_config_get_cmd_string( ADD_OBS ) , local_obsdata_get_name(obsdata) , obs_key ); + } + } +} + +void local_obsdata_summary_fprintf( const local_obsdata_type * obsdata , FILE * stream) { + + fprintf(stream , "LOCAL OBSDATA NAME:%s,LOCAL OBSDATA SIZE:%d,", local_obsdata_get_name(obsdata), local_obsdata_get_size(obsdata) ); + + int i; + for (i = 0; i < local_obsdata_get_size( obsdata ); i++ ) { + local_obsdata_node_type * node = local_obsdata_iget( obsdata , i ); + const char * obs_key = local_obsdata_node_get_key(node); + fprintf(stream , "OBSERVATION:%s,", obs_key ); + } +} diff --git a/ThirdParty/Ert/devel/libenkf/src/local_updatestep.c b/ThirdParty/Ert/devel/libenkf/src/local_updatestep.c index 0ebeff175c..6d4ea53260 100644 --- a/ThirdParty/Ert/devel/libenkf/src/local_updatestep.c +++ b/ThirdParty/Ert/devel/libenkf/src/local_updatestep.c @@ -57,6 +57,16 @@ local_updatestep_type * local_updatestep_alloc( const char * name ) { } +bool local_updatestep_has_data_key( const local_updatestep_type * update_step , const char * key) { + bool has_key = false; + for (int i = 0; i < vector_get_size( update_step->ministep ); i++) { + const local_ministep_type * ministep = vector_iget_const( update_step->ministep , i ); + if (local_ministep_has_data_key(ministep, key)) + has_key = true; + } + return has_key; +} + /** Observe that use_count values are not copied. */ @@ -110,7 +120,7 @@ const char * local_updatestep_get_name( const local_updatestep_type * updatestep void local_updatestep_fprintf( const local_updatestep_type * updatestep , FILE * stream) { - fprintf(stream , "%s %s\n" , local_config_get_cmd_string( CREATE_UPDATESTEP ) , updatestep->name ); + fprintf(stream , "\n%s %s\n" , local_config_get_cmd_string( CREATE_UPDATESTEP ) , updatestep->name ); { int i; for (i=0; i < vector_get_size( updatestep->ministep ); i++) { diff --git a/ThirdParty/Ert/devel/libenkf/src/obs_data.c b/ThirdParty/Ert/devel/libenkf/src/obs_data.c index 1d1390838b..90868c5413 100644 --- a/ThirdParty/Ert/devel/libenkf/src/obs_data.c +++ b/ThirdParty/Ert/devel/libenkf/src/obs_data.c @@ -139,12 +139,12 @@ static void obs_block_free__( void * arg ) { } -void obs_block_deactivate( obs_block_type * obs_block , int iobs , const char * msg) { +void obs_block_deactivate( obs_block_type * obs_block , int iobs , bool verbose , const char * msg) { if (obs_block->active_mode[ iobs ] == ACTIVE) { - printf("Deactivating: %s(%d) : %s \n",obs_block->obs_key , iobs , msg); + if (verbose) + printf("Deactivating: %s(%d) : %s \n",obs_block->obs_key , iobs , msg); obs_block->active_mode[ iobs ] = DEACTIVATED; obs_block->active_size--; - } } @@ -692,3 +692,54 @@ int obs_data_get_active_size( const obs_data_type * obs_data ) { int obs_data_get_num_blocks( const obs_data_type * obs_data ) { return vector_get_size( obs_data->data ); } + + + +int obs_data_get_total_size( const obs_data_type * obs_data ) { + int total_size = 0; + for (int block_nr = 0; block_nr < vector_get_size( obs_data->data ); block_nr++) { + const obs_block_type * obs_block = vector_iget_const( obs_data->data , block_nr ); + total_size += obs_block->size; + } + return total_size; +} + + +static const obs_block_type * obs_data_lookup_block( const obs_data_type * obs_data, int total_index , int * block_offset) { + if (total_index < obs_data_get_total_size( obs_data )) { + const obs_block_type * obs_block; + int total_offset = 0; + int block_index = 0; + int block_size; + + + while (true) { + obs_block = vector_iget_const( obs_data->data , block_index ); + block_size = obs_block->size; + if ((block_size + total_offset) > total_index) + break; + + total_offset += block_size; + block_index++; + } + *block_offset = total_offset; + return obs_block; + } else { + util_abort("%s: could not lookup obs-block \n",__func__); + return NULL; + } +} + + +double obs_data_iget_value( const obs_data_type * obs_data , int total_index ) { + int total_offset; + const obs_block_type * obs_block = obs_data_lookup_block( obs_data , total_index , &total_offset ); + return obs_block_iget_value( obs_block , total_index - total_offset ); +} + + +double obs_data_iget_std( const obs_data_type * obs_data , int total_index ) { + int total_offset; + const obs_block_type * obs_block = obs_data_lookup_block( obs_data , total_index , &total_offset ); + return obs_block_iget_std( obs_block , total_index - total_offset ); +} diff --git a/ThirdParty/Ert/devel/libenkf/src/run_arg.c b/ThirdParty/Ert/devel/libenkf/src/run_arg.c index ad09ae797d..96e343c3b1 100644 --- a/ThirdParty/Ert/devel/libenkf/src/run_arg.c +++ b/ThirdParty/Ert/devel/libenkf/src/run_arg.c @@ -1,19 +1,19 @@ /* - Copyright (C) 2014 Statoil ASA, Norway. - - The file 'run_arg.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> - for more details. + Copyright (C) 2014 Statoil ASA, Norway. + + The file 'run_arg.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> + for more details. */ @@ -27,18 +27,17 @@ #define RUN_ARG_TYPE_ID 66143287 - +#define INVALID_QUEUE_INDEX -99 struct run_arg_struct { UTIL_TYPE_ID_DECLARATION; int iens; - bool active; /* Is this state object active at all - used for instance in ensemble experiments where only some of the members are integrated. */ int init_step_parameters; /* The report step we initialize parameters from - will often be equal to step1, but can be different. */ state_enum init_state_parameter; /* Whether we should init from a forecast or an analyzed state - parameters. */ state_enum init_state_dynamic; /* Whether we should init from a forecast or an analyzed state - dynamic state variables. */ - int max_internal_submit; /* How many times the enkf_state object should try to resubmit when the queueu has said everything is OK - but the load fails. */ - int num_internal_submit; + int max_internal_submit; /* How many times the enkf_state object should try to resubmit when the queueu has said everything is OK - but the load fails. */ + int num_internal_submit; int load_start; /* When loading back results - start at this step. */ int step1; /* The forward model is integrated: step1 -> step2 */ int step2; @@ -46,7 +45,7 @@ struct run_arg_struct { char * run_path; /* The currently used runpath - is realloced / freed for every step. */ run_mode_type run_mode; /* What type of run this is */ int queue_index; /* The job will in general have a different index in the queue than the iens number. */ - + enkf_fs_type * init_fs; enkf_fs_type * result_fs; enkf_fs_type * update_target_fs; @@ -55,28 +54,28 @@ struct run_arg_struct { /* Return value - set by the called routine!! */ run_status_type run_status; }; - + UTIL_SAFE_CAST_FUNCTION( run_arg , RUN_ARG_TYPE_ID ) UTIL_IS_INSTANCE_FUNCTION( run_arg , RUN_ARG_TYPE_ID ) -static run_arg_type * run_arg_alloc(enkf_fs_type * init_fs , - enkf_fs_type * result_fs , - enkf_fs_type * update_target_fs , - int iens , - run_mode_type run_mode , - int init_step_parameters , +static run_arg_type * run_arg_alloc(enkf_fs_type * init_fs , + enkf_fs_type * result_fs , + enkf_fs_type * update_target_fs , + int iens , + run_mode_type run_mode , + int init_step_parameters , state_enum init_state_parameter , state_enum init_state_dynamic , - int step1 , + int step1 , int step2 , int iter , const char * runpath) { - + run_arg_type * run_arg = util_malloc(sizeof * run_arg ); UTIL_TYPE_ID_INIT(run_arg , RUN_ARG_TYPE_ID); - + run_arg->init_fs = init_fs; run_arg->result_fs = result_fs; run_arg->update_target_fs = update_target_fs; @@ -91,24 +90,25 @@ static run_arg_type * run_arg_alloc(enkf_fs_type * init_fs , run_arg->iter = iter; run_arg->run_path = util_alloc_abs_path( runpath ); run_arg->num_internal_submit = 0; + run_arg->queue_index = INVALID_QUEUE_INDEX; if (step1 == 0) run_arg->load_start = 1; else run_arg->load_start = step1; - + return run_arg; } -run_arg_type * run_arg_alloc_ENKF_ASSIMILATION(enkf_fs_type * fs , - int iens , +run_arg_type * run_arg_alloc_ENKF_ASSIMILATION(enkf_fs_type * fs , + int iens , state_enum init_state_parameter , state_enum init_state_dynamic , - int step1 , + int step1 , int step2 , const char * runpath) { - + return run_arg_alloc(fs,fs,fs,iens,ENKF_ASSIMILATION,step1 , init_state_parameter, init_state_dynamic , step1 , step2 , 0 , runpath); } @@ -157,7 +157,10 @@ void run_arg_increase_submit_count( run_arg_type * run_arg ) { void run_arg_set_queue_index( run_arg_type * run_arg , int queue_index) { - run_arg->queue_index = queue_index; + if (run_arg->queue_index == INVALID_QUEUE_INDEX) + run_arg->queue_index = queue_index; + else + util_abort("%s: attempt to reset run_arg->queue_index. These objects should not be recycled\n",__func__); } @@ -222,15 +225,20 @@ int run_arg_get_parameter_init_step( const run_arg_type * run_arg ) { -void run_arg_set_inactive( run_arg_type * run_arg ) { - run_arg->active = false; -} - - int run_arg_get_queue_index( const run_arg_type * run_arg ) { + if (run_arg->queue_index == INVALID_QUEUE_INDEX) + util_abort("%s: sorry internal error - asking for the queue_index in a not-initialized run_arg object.\n" , __func__); + return run_arg->queue_index; } +bool run_arg_is_submitted( const run_arg_type * run_arg ) { + if (run_arg->queue_index == INVALID_QUEUE_INDEX) + return false; + else + return true; +} + run_status_type run_arg_get_run_status( const run_arg_type * run_arg) { return run_arg->run_status; diff --git a/ThirdParty/Ert/devel/libenkf/src/site_config.c b/ThirdParty/Ert/devel/libenkf/src/site_config.c index 3bcd51e615..5a2fb10941 100644 --- a/ThirdParty/Ert/devel/libenkf/src/site_config.c +++ b/ThirdParty/Ert/devel/libenkf/src/site_config.c @@ -581,11 +581,6 @@ static void site_config_set_job_queue__(site_config_type * site_config, job_driv site_config->driver_type_site = driver_type; } -void site_config_set_job_queue(site_config_type * site_config, const char * queue_name) { - job_driver_type driver_type = job_queue_lookup_driver_name(queue_name); - site_config_set_job_queue__(site_config, driver_type); -} - bool site_config_queue_is_running(const site_config_type * site_config) { return job_queue_is_running(site_config->job_queue); } diff --git a/ThirdParty/Ert/devel/libenkf/tests/enkf_obs_fs.c b/ThirdParty/Ert/devel/libenkf/tests/enkf_obs_fs.c index f3c86c2401..bc56830f09 100644 --- a/ThirdParty/Ert/devel/libenkf/tests/enkf_obs_fs.c +++ b/ThirdParty/Ert/devel/libenkf/tests/enkf_obs_fs.c @@ -75,7 +75,7 @@ void test_iget(ert_test_context_type * test_context) { enkf_main_type * enkf_main = ert_test_context_get_main( test_context ); enkf_obs_type * enkf_obs = enkf_main_get_obs( enkf_main ); - test_assert_int_equal( 31 , enkf_obs_get_size( enkf_obs ) ); + test_assert_int_equal( 32 , enkf_obs_get_size( enkf_obs ) ); for (int iobs = 0; iobs < enkf_obs_get_size( enkf_obs ); iobs++) { obs_vector_type * vec1 = enkf_obs_iget_vector( enkf_obs , iobs ); obs_vector_type * vec2 = enkf_obs_get_vector( enkf_obs , obs_vector_get_key( vec1 )); diff --git a/ThirdParty/Ert/devel/libenkf/tests/enkf_run_arg.c b/ThirdParty/Ert/devel/libenkf/tests/enkf_run_arg.c index df1401a04d..5c472a529d 100644 --- a/ThirdParty/Ert/devel/libenkf/tests/enkf_run_arg.c +++ b/ThirdParty/Ert/devel/libenkf/tests/enkf_run_arg.c @@ -1,19 +1,19 @@ /* - Copyright (C) 2014 Statoil ASA, Norway. - - The file 'ert_run_context.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> - for more details. + Copyright (C) 2014 Statoil ASA, Norway. + + The file 'ert_run_context.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> + for more details. */ #include <stdlib.h> @@ -26,6 +26,38 @@ #include <ert/enkf/run_arg.h> #include <ert/enkf/enkf_fs.h> + +void call_get_queue_index( void * arg ) { + run_arg_type * run_arg = run_arg_safe_cast( arg ); + run_arg_get_queue_index( run_arg ); +} + +void call_set_queue_index( void * arg ) { + run_arg_type * run_arg = run_arg_safe_cast( arg ); + run_arg_set_queue_index( run_arg , 88 ); +} + + +void test_queue_index() { + test_work_area_type * test_area = test_work_area_alloc("run_arg/ENS"); + { + enkf_fs_type * fs = enkf_fs_create_fs("sim" , BLOCK_FS_DRIVER_ID , NULL , true); + run_arg_type * run_arg = run_arg_alloc_ENSEMBLE_EXPERIMENT(fs , 0 , 6 , "path"); + + test_assert_false( run_arg_is_submitted( run_arg ) ); + test_assert_util_abort("run_arg_get_queue_index" , call_get_queue_index , run_arg ); + + run_arg_set_queue_index(run_arg, 78); + test_assert_true( run_arg_is_submitted( run_arg ) ); + test_assert_int_equal( 78 , run_arg_get_queue_index( run_arg )); + + test_assert_util_abort("run_arg_set_queue_index" , call_set_queue_index , run_arg ); + run_arg_free( run_arg ); + enkf_fs_decref( fs ); + } + test_work_area_free( test_area ); +} + void call_get_result_fs( void * arg ) { run_arg_type * run_arg = run_arg_safe_cast( arg ); run_arg_get_result_fs( run_arg ); @@ -51,7 +83,7 @@ void test_SMOOTHER_RUN( ) { test_assert_ptr_equal( run_arg_get_result_fs( run_arg ) , sim_fs ); test_assert_ptr_equal( run_arg_get_update_target_fs( run_arg ) , target_fs ); run_arg_free( run_arg ); - + enkf_fs_decref( sim_fs ); enkf_fs_decref( target_fs ); } @@ -71,7 +103,7 @@ void test_INIT_ONLY( ) { test_assert_util_abort( "run_arg_get_result_fs" , call_get_result_fs , run_arg ); test_assert_util_abort( "run_arg_get_update_target_fs" , call_get_update_target_fs , run_arg ); run_arg_free( run_arg ); - + enkf_fs_decref( init_fs ); } test_work_area_free( test_area ); @@ -82,10 +114,10 @@ void test_ENSEMBLE_EXPERIMENT( ) { test_work_area_type * test_area = test_work_area_alloc("run_arg/ENS"); { enkf_fs_type * fs = enkf_fs_create_fs("sim" , BLOCK_FS_DRIVER_ID , NULL , true); - + run_arg_type * run_arg = run_arg_alloc_ENSEMBLE_EXPERIMENT(fs , 0 , 6 , "path"); test_assert_true( run_arg_is_instance( run_arg )); - + test_assert_ptr_equal( run_arg_get_init_fs( run_arg ) , fs ); test_assert_ptr_equal( run_arg_get_result_fs( run_arg ) , fs ); test_assert_util_abort( "run_arg_get_update_target_fs" , call_get_update_target_fs , run_arg ); @@ -102,6 +134,7 @@ void test_ENKF_ASSIMILATION( ) { } int main(int argc , char ** argv) { + test_queue_index(); test_SMOOTHER_RUN(); test_INIT_ONLY(); test_ENSEMBLE_EXPERIMENT(); diff --git a/ThirdParty/Ert/devel/libert_util/include/ert/util/arg_pack.h b/ThirdParty/Ert/devel/libert_util/include/ert/util/arg_pack.h index 9c95f8cb48..a05c56db84 100644 --- a/ThirdParty/Ert/devel/libert_util/include/ert/util/arg_pack.h +++ b/ThirdParty/Ert/devel/libert_util/include/ert/util/arg_pack.h @@ -1,19 +1,19 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'arg_pack.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> - for more details. + Copyright (C) 2011 Statoil ASA, Norway. + + The file 'arg_pack.h' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> + for more details. */ #ifndef __ARG_PACK_H__ @@ -42,12 +42,12 @@ typedef void * (arg_node_copyc_ftype) (const void *); void arg_pack_lock(arg_pack_type *); void arg_pack_fscanf(arg_pack_type * arg , FILE * stream, const char * filename); void arg_pack_fprintf(const arg_pack_type * , FILE * ); - + void arg_pack_append_ptr(arg_pack_type * , void *); void arg_pack_append_const_ptr(arg_pack_type * , const void *); void arg_pack_append_owned_ptr(arg_pack_type * , void * , arg_node_free_ftype *); void arg_pack_append_copy(arg_pack_type * , void * , arg_node_copyc_ftype * , arg_node_free_ftype *); - + /* void arg_pack_iset_copy(arg_pack_type * arg_pack , int index , void * ptr, arg_node_copyc_ftype * copyc , arg_node_free_ftype * freef); void arg_pack_iset_ptr(arg_pack_type * arg_pack, int index , void * ptr); @@ -59,9 +59,9 @@ typedef void * (arg_node_copyc_ftype) (const void *); node_ctype arg_pack_iget_ctype(const arg_pack_type * arg_pack ,int index); int arg_pack_size( const arg_pack_type * arg_pack ); - + /*****************************************************************/ - + #define APPEND_TYPED_HEADER(type) void arg_pack_append_ ## type (arg_pack_type * , type); #define IGET_TYPED_HEADER(type) type arg_pack_iget_ ## type( const arg_pack_type * , int ); #define ISET_TYPED_HEADER(type) void arg_pack_iset_ ## type( arg_pack_type * , int , type value); @@ -95,4 +95,4 @@ ISET_TYPED_HEADER(size_t) } #endif #endif - + diff --git a/ThirdParty/Ert/devel/libert_util/include/ert/util/buffer.h b/ThirdParty/Ert/devel/libert_util/include/ert/util/buffer.h index b5201d4c73..1c7de976d1 100644 --- a/ThirdParty/Ert/devel/libert_util/include/ert/util/buffer.h +++ b/ThirdParty/Ert/devel/libert_util/include/ert/util/buffer.h @@ -1,19 +1,19 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'buffer.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> - for more details. + Copyright (C) 2011 Statoil ASA, Norway. + + The file 'buffer.h' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> + for more details. */ #ifndef __BUFFER_H__ @@ -28,6 +28,7 @@ extern "C" { #include <string.h> #include <time.h> +#include <ert/util/type_macros.h> #include <ert/util/ssize_t.h> @@ -49,13 +50,10 @@ extern "C" { size_t buffer_fread(buffer_type * buffer , void * target_ptr , size_t item_size , size_t items); size_t buffer_safe_fwrite(buffer_type * buffer , const void * src_ptr , size_t item_size , size_t items); size_t buffer_fwrite(buffer_type * buffer , const void * src_ptr , size_t item_size , size_t items); - const char * buffer_fread_string(buffer_type * buffer); - char * buffer_fread_alloc_string(buffer_type * buffer); - void buffer_fwrite_string(buffer_type * buffer , const char * string); void buffer_summarize(const buffer_type * buffer , const char *); - + void buffer_fwrite_char_ptr(buffer_type * buffer , const char * string_ptr ); - void buffer_terminate_char_ptr( buffer_type * buffer ); + void buffer_strcat(buffer_type * buffer , const char * string); void buffer_fwrite_char(buffer_type * buffer , char value); void buffer_fwrite_int(buffer_type * buffer , int value); void buffer_fskip_bool(buffer_type * buffer); @@ -72,21 +70,22 @@ extern "C" { size_t buffer_get_remaining_size(const buffer_type * buffer); void * buffer_get_data(const buffer_type * buffer); void * buffer_alloc_data_copy(const buffer_type * buffer); + void * buffer_iget_data(const buffer_type * buffer, size_t offset); void buffer_stream_fwrite( const buffer_type * buffer , FILE * stream ); int buffer_fgetc( buffer_type * buffer ); void buffer_fseek(buffer_type * buffer , ssize_t offset , int whence); void buffer_fskip(buffer_type * buffer, ssize_t offset); void buffer_clear( buffer_type * buffer ); - + void buffer_fskip_int(buffer_type * buffer); void buffer_fskip_time_t(buffer_type * buffer); time_t buffer_fread_time_t(buffer_type * buffer); void buffer_fwrite_time_t(buffer_type * buffer , time_t value); void buffer_rewind(buffer_type * buffer ); - + double buffer_fread_double(buffer_type * buffer); void buffer_fwrite_double(buffer_type * buffer , double value); - + size_t buffer_stream_fwrite_n( const buffer_type * buffer , size_t offset , ssize_t write_size , FILE * stream ); void buffer_stream_fprintf( const buffer_type * buffer , FILE * stream ); void buffer_stream_fread( buffer_type * buffer , size_t byte_size , FILE * stream); @@ -97,6 +96,13 @@ extern "C" { size_t buffer_fwrite_compressed(buffer_type * buffer, const void * ptr , size_t byte_size); size_t buffer_fread_compressed(buffer_type * buffer , size_t compressed_size , void * target_ptr , size_t target_size); #endif + + +#include "buffer_string.h" + + UTIL_IS_INSTANCE_HEADER( buffer ); + UTIL_SAFE_CAST_HEADER( buffer ); + #ifdef __cplusplus } #endif diff --git a/ThirdParty/Ert/devel/libert_util/include/ert/util/buffer_string.h b/ThirdParty/Ert/devel/libert_util/include/ert/util/buffer_string.h new file mode 100644 index 0000000000..c516bbd028 --- /dev/null +++ b/ThirdParty/Ert/devel/libert_util/include/ert/util/buffer_string.h @@ -0,0 +1,7 @@ +/* + These functions are very deprecated and should not be used further. +*/ + +const char * buffer_fread_string(buffer_type * buffer); +char * buffer_fread_alloc_string(buffer_type * buffer); +void buffer_fwrite_string(buffer_type * buffer , const char * string); diff --git a/ThirdParty/Ert/devel/libert_util/include/ert/util/hash.h b/ThirdParty/Ert/devel/libert_util/include/ert/util/hash.h index 8c3428e792..478c8e366a 100644 --- a/ThirdParty/Ert/devel/libert_util/include/ert/util/hash.h +++ b/ThirdParty/Ert/devel/libert_util/include/ert/util/hash.h @@ -49,7 +49,7 @@ bool hash_has_key(const hash_type *, const char *); void * hash_pop( hash_type * hash , const char * key); void * hash_safe_get( const hash_type * hash , const char * key ); void * hash_get(const hash_type *, const char *); -char * hash_get_string(hash_type * , const char *); +char * hash_get_string(const hash_type * , const char *); void hash_del(hash_type *, const char *); void hash_safe_del(hash_type * , const char * ); void hash_clear(hash_type *); @@ -75,11 +75,11 @@ hash_type * hash_alloc_from_options(const stringlist_type *); bool hash_add_option( hash_type * hash, const char * key_value); int hash_inc_counter(hash_type * hash , const char * counter_key); -int hash_get_counter(hash_type * hash , const char * key); +int hash_get_counter(const hash_type * hash , const char * key); void hash_insert_int(hash_type * , const char * , int); -int hash_get_int(hash_type * , const char *); +int hash_get_int(const hash_type * , const char *); void hash_insert_double(hash_type * , const char * , double); -double hash_get_double(hash_type * , const char *); +double hash_get_double(const hash_type * , const char *); void hash_apply( hash_type * hash , hash_apply_ftype * func); UTIL_IS_INSTANCE_HEADER(hash); diff --git a/ThirdParty/Ert/devel/libert_util/include/ert/util/rng.h b/ThirdParty/Ert/devel/libert_util/include/ert/util/rng.h index 73ea7e6259..4e3385bc25 100644 --- a/ThirdParty/Ert/devel/libert_util/include/ert/util/rng.h +++ b/ThirdParty/Ert/devel/libert_util/include/ert/util/rng.h @@ -68,6 +68,7 @@ typedef enum { unsigned int rng_forward( rng_type * rng ); double rng_get_double( rng_type * rng ); int rng_get_int( rng_type * rng , int max_value ); + unsigned int rng_get_max_int(const rng_type * rng); double rng_std_normal( rng_type * rng ); void rng_shuffle_int( rng_type * rng , int * data , size_t num_elements); diff --git a/ThirdParty/Ert/devel/libert_util/include/ert/util/subst_list.h b/ThirdParty/Ert/devel/libert_util/include/ert/util/subst_list.h index 1db5f55078..8f08133250 100644 --- a/ThirdParty/Ert/devel/libert_util/include/ert/util/subst_list.h +++ b/ThirdParty/Ert/devel/libert_util/include/ert/util/subst_list.h @@ -1,30 +1,31 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'subst_list.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> - for more details. + Copyright (C) 2011 Statoil ASA, Norway. + + The file 'subst_list.h' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> + for more details. */ #ifndef __SUBST_H__ #define __SUBST_H__ -#ifdef __cplusplus +#ifdef __cplusplus extern "C" { #endif #include <stdio.h> #include <stdbool.h> +#include <ert/util/type_macros.h> #include <ert/util/subst_func.h> typedef struct subst_list_struct subst_list_type; @@ -43,7 +44,7 @@ extern "C" { void subst_list_prepend_copy(subst_list_type * , const char * , const char * , const char * doc_string); void subst_list_prepend_ref(subst_list_type * , const char * , const char * , const char * doc_string); void subst_list_prepend_owned_ref(subst_list_type * , const char * , const char * , const char * doc_string); - + bool subst_list_filter_file(const subst_list_type * , const char * , const char * ); bool subst_list_update_file(const subst_list_type * , const char * ); bool subst_list_update_string(const subst_list_type * , char ** ); @@ -57,8 +58,9 @@ extern "C" { bool subst_list_has_key( const subst_list_type * subst_list , const char * key); char * subst_list_alloc_string_representation( const subst_list_type * subst_list ); int subst_list_add_from_string( subst_list_type * subst_list , const char * arg_string, bool append); - -#ifdef __cplusplus + + UTIL_IS_INSTANCE_HEADER( subst_list ); +#ifdef __cplusplus } #endif #endif diff --git a/ThirdParty/Ert/devel/libert_util/include/ert/util/thread_pool_posix.h b/ThirdParty/Ert/devel/libert_util/include/ert/util/thread_pool_posix.h index 3f456c39e9..a749ed2c35 100644 --- a/ThirdParty/Ert/devel/libert_util/include/ert/util/thread_pool_posix.h +++ b/ThirdParty/Ert/devel/libert_util/include/ert/util/thread_pool_posix.h @@ -29,7 +29,7 @@ extern "C" { void thread_pool_restart( thread_pool_type * tp ); void * thread_pool_iget_return_value( const thread_pool_type * pool , int queue_index ); int thread_pool_get_max_running( const thread_pool_type * pool ); - + bool thread_pool_try_join(thread_pool_type * pool, int timeout_seconds); #ifdef __cplusplus } #endif diff --git a/ThirdParty/Ert/devel/libert_util/include/ert/util/util.h b/ThirdParty/Ert/devel/libert_util/include/ert/util/util.h index 9097d87a03..c91fc6ba52 100644 --- a/ThirdParty/Ert/devel/libert_util/include/ert/util/util.h +++ b/ThirdParty/Ert/devel/libert_util/include/ert/util/util.h @@ -104,6 +104,7 @@ typedef enum {left_pad = 0, //#define UTIL_CXX_MALLOC(var , num_elm) (typeof (var)) util_malloc( (num_elm) * sizeof var) void util_bitmask_on(int * , int ); + char * util_get_timezone(); time_t util_make_datetime(int , int , int , int , int , int ); void util_fprintf_datetime(time_t , FILE * ); void util_fprintf_date(time_t , FILE * ); diff --git a/ThirdParty/Ert/devel/libert_util/src/CMakeLists.txt b/ThirdParty/Ert/devel/libert_util/src/CMakeLists.txt index a72e315e87..42d20cc758 100644 --- a/ThirdParty/Ert/devel/libert_util/src/CMakeLists.txt +++ b/ThirdParty/Ert/devel/libert_util/src/CMakeLists.txt @@ -67,6 +67,7 @@ set(header_files type_vector_functions.h ui_return.h struct_vector.h + buffer_string.h ) set( test_source test_util.c ) diff --git a/ThirdParty/Ert/devel/libert_util/src/arg_pack.c b/ThirdParty/Ert/devel/libert_util/src/arg_pack.c index 32789760e2..b1b3bcc207 100644 --- a/ThirdParty/Ert/devel/libert_util/src/arg_pack.c +++ b/ThirdParty/Ert/devel/libert_util/src/arg_pack.c @@ -1,19 +1,19 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'arg_pack.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> - for more details. + Copyright (C) 2011 Statoil ASA, Norway. + + The file 'arg_pack.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> + for more details. */ #include <stdlib.h> @@ -61,14 +61,14 @@ void some_function(const char * arg1 , int arg2 , double arg3) { ..... - } + } + - void some_function__(void * __arg_pack) { arg_pack_type * arg_pack = arg_pack_safe_cast( __arg_pack ); const char * arg1 = arg_pack_iget_ptr( arg_pack , 0); int arg2 = arg_pack_iget_int( arg_pack , 1); - double arg3 = arg_pack_iget_double(arg_pack , 2); + double arg3 = arg_pack_iget_double(arg_pack , 2); some_function( arg1 , arg2 , arg3 ); } @@ -76,7 +76,7 @@ ..... arg_pack_type * arg_pack = arg_pack_alloc(); - arg_pack_append_ptr(arg_pack , "ARG1"); + arg_pack_append_ptr(arg_pack , "ARG1"); arg_pack_append_int(arg_pack , 1); arg_pack_append_double(arg_pack , 3.14159265); @@ -84,7 +84,7 @@ */ - + #define ARG_PACK_TYPE_ID 668268 @@ -101,10 +101,10 @@ typedef struct { struct arg_pack_struct { UTIL_TYPE_ID_DECLARATION; - int size; /* The number of arguments appended to this arg_pack instance. */ + int size; /* The number of arguments appended to this arg_pack instance. */ int alloc_size; /* The number of nodes allocated to this arg_pack - will in general be greater than size. */ - bool locked; /* To insure against unwaranted modifictaions - you can explicitly lock the arg_pack instance. This only */ - arg_node_type **nodes; /* Vector of nodes */ + bool locked; /* To insure against unwaranted modifictaions - you can explicitly lock the arg_pack instance. This only */ + arg_node_type **nodes; /* Vector of nodes */ }; @@ -126,7 +126,7 @@ static void arg_node_realloc_buffer(arg_node_type * node , int new_size) { static void __arg_node_assert_type(const arg_node_type * node , node_ctype arg_type) { - if (arg_type != node->ctype) + if (arg_type != node->ctype) util_abort("%s: asked for type:\'%s\' inserted as:\'%s\' - aborting \n" , __func__ , node_ctype_name(arg_type) , node_ctype_name(node->ctype)); } @@ -182,7 +182,7 @@ static size_t arg_node_get_size_t( const arg_node_type * node) { arg_pack, as that will delete the pointer you are using as well. */ - + static void * arg_node_get_ptr(const arg_node_type * node , bool get_ptr) { if (get_ptr) { if (node->ctype != CTYPE_VOID_POINTER) @@ -250,7 +250,7 @@ static void arg_node_set_size_t( arg_node_type * node , size_t value) { static void arg_node_set_ptr(arg_node_type * node , const void * ptr , arg_node_copyc_ftype * copyc , arg_node_free_ftype * destructor) { node->ctype = CTYPE_VOID_POINTER; node->destructor = destructor; - node->copyc = copyc; + node->copyc = copyc; if (copyc != NULL) node->buffer = copyc( ptr ); else @@ -264,7 +264,7 @@ static void arg_node_set_ptr(arg_node_type * node , const void * ptr , arg_node_ static void arg_node_clear(arg_node_type * node) { if (node->ctype == CTYPE_VOID_POINTER) { - if (node->destructor != NULL) + if (node->destructor != NULL) node->destructor( node->buffer ); /* When you have cleared - must not reuse the thing. */ node->destructor = NULL; @@ -338,7 +338,7 @@ UTIL_SAFE_CAST_FUNCTION_CONST( arg_pack , ARG_PACK_TYPE_ID) UTIL_IS_INSTANCE_FUNCTION(arg_pack , ARG_PACK_TYPE_ID) static void __arg_pack_assert_index(const arg_pack_type * arg , int iarg) { - if (iarg < 0 || iarg >= arg->size) + if (iarg < 0 || iarg >= arg->size) util_abort("%s: arg_pack() object filled with %d arguments - %d invalid argument number - aborting \n",__func__ , arg->size , iarg); } @@ -369,11 +369,11 @@ static arg_node_type * arg_pack_iget_new_node( arg_pack_type * arg_pack , int in arg_node_free( arg_pack->nodes[index] ); /* Free the existing current node. */ arg_pack->nodes[index] = arg_node_alloc_empty( ); /* Allocate a new fresh instance. */ } - + if (arg_pack->size == arg_pack->alloc_size) arg_pack_realloc_nodes(arg_pack , 1 + arg_pack->alloc_size * 2); /* We have to grow the vector of nodes. */ - if (index == arg_pack->size) + if (index == arg_pack->size) arg_pack->size++; /* We are asking for the first element beyond the current length of the vector, i.e. append. */ return arg_pack->nodes[index]; } @@ -414,7 +414,7 @@ arg_pack_type * arg_pack_alloc() { void arg_pack_free(arg_pack_type * arg_pack) { int i; - for (i=0; i < arg_pack->alloc_size; i++) + for (i=0; i < arg_pack->alloc_size; i++) arg_node_free( arg_pack->nodes[i] ); free(arg_pack->nodes); @@ -430,7 +430,7 @@ void arg_pack_free__(void * __arg_pack) { void arg_pack_clear(arg_pack_type * arg_pack) { - if (arg_pack->locked) + if (arg_pack->locked) util_abort("%s: arg_pack has been locked - abortng \n",__func__); { int i; @@ -445,7 +445,7 @@ void arg_pack_clear(arg_pack_type * arg_pack) { /* Access functions: 1. Append - 2. iget + 2. iget 3. iset (can NOT create holes in the vector) ******************************************************************/ @@ -527,7 +527,7 @@ node_ctype arg_pack_iget_ctype(const arg_pack_type * arg_pack ,int index) { void arg_pack_iset_copy(arg_pack_type * arg_pack , int index , const void * ptr, arg_node_copyc_ftype * copyc , arg_node_free_ftype * freef) { - arg_node_type * node = arg_pack_iget_new_node( arg_pack , index ); + arg_node_type * node = arg_pack_iget_new_node( arg_pack , index ); arg_node_set_ptr(node , ptr , copyc , freef); } @@ -577,7 +577,7 @@ void arg_pack_fscanf(arg_pack_type * arg , FILE * stream, const char * filename) arg_node_type * node = arg->nodes[iarg]; fmt = util_strcat_realloc(fmt , arg_node_fmt(node)); } - + switch(arg->size) { case(0): break; @@ -603,7 +603,7 @@ void arg_pack_fscanf(arg_pack_type * arg , FILE * stream, const char * filename) arg0 = arg_pack_iget_adress(arg , 0); arg1 = arg_pack_iget_adress(arg , 1); arg2 = arg_pack_iget_adress(arg , 2); - + scan_count = fscanf(stream , fmt , arg0 , arg1 , arg2); break; } @@ -614,7 +614,7 @@ void arg_pack_fscanf(arg_pack_type * arg , FILE * stream, const char * filename) arg1 = arg_pack_iget_adress(arg , 1); arg2 = arg_pack_iget_adress(arg , 2); arg3 = arg_pack_iget_adress(arg , 3); - + scan_count = fscanf(stream , fmt , arg0 , arg1 , arg2 , arg3); break; } @@ -635,11 +635,11 @@ void arg_pack_fscanf(arg_pack_type * arg , FILE * stream, const char * filename) util_abort("%s: sorry %s not allocated for %d arguments from file %s\n",__func__ , __func__ , arg->size, filename); } - + if (scan_count != arg->size) { util_abort("%s: wanted %d arguments - only found: %d in file %s \n", __func__ , arg->size , scan_count, filename); } - + free(fmt); } diff --git a/ThirdParty/Ert/devel/libert_util/src/buffer.c b/ThirdParty/Ert/devel/libert_util/src/buffer.c index 7a2491d9ba..46b56f6ab3 100644 --- a/ThirdParty/Ert/devel/libert_util/src/buffer.c +++ b/ThirdParty/Ert/devel/libert_util/src/buffer.c @@ -1,19 +1,19 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'buffer.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> - for more details. + Copyright (C) 2011 Statoil ASA, Norway. + + The file 'buffer.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> + for more details. */ @@ -25,6 +25,7 @@ #include <ert/util/ssize_t.h> #include <ert/util/util.h> +#include <ert/util/type_macros.h> #include <ert/util/buffer.h> @@ -53,7 +54,7 @@ struct buffer_struct { - size_t __id; + UTIL_TYPE_ID_DECLARATION; char * data; /* The actual storage. */ size_t alloc_size; /* The total byte size of the buffer. */ size_t content_size; /* The extent of initialized data in the buffer - i.e. the meaningful content in the buffer. */ @@ -64,8 +65,8 @@ struct buffer_struct { /*****************************************************************/ - - +UTIL_IS_INSTANCE_FUNCTION( buffer , BUFFER_TYPE_ID ) +UTIL_SAFE_CAST_FUNCTION( buffer , BUFFER_TYPE_ID ) /** @@ -99,7 +100,7 @@ static void buffer_resize__(buffer_type * buffer , size_t new_size, bool abort_o static buffer_type * buffer_alloc_empty( ) { buffer_type * buffer = util_malloc( sizeof * buffer ); - buffer->__id = BUFFER_TYPE_ID; + UTIL_TYPE_ID_INIT( buffer , BUFFER_TYPE_ID ); buffer->data = NULL; buffer->alloc_size = 0; @@ -128,11 +129,11 @@ void buffer_shrink_to_fit( buffer_type * buffer ) { data. Observe that the buffer will 'steal' the input data pointer, in the process the data pointer might very well be realloced() leaving the original pointer invalid. - + All the content of the input data pointer will be assumed to be valid, i.e. the fields content_size and pos will be set to the value @buffer_size. - + When calling buffer_free() at a later stage the hijacked data will also be freed. */ @@ -144,7 +145,7 @@ buffer_type * buffer_alloc_private_wrapper(void * data , size_t buffer_size ) { buffer->content_size = buffer_size; buffer->pos = buffer_size; buffer->alloc_size = buffer_size; - + return buffer; } @@ -193,7 +194,7 @@ void buffer_clear( buffer_type * buffer ) { /*****************************************************************/ -/** +/** Observe that it is the functions with _safe_ in the name which most closely mimicks the behaviour of fread(), and fwrite() - these functions will *NOT* abort if the buffer is to small, @@ -212,19 +213,19 @@ static size_t buffer_fread__(buffer_type * buffer , void * target_ptr , size_t i size_t remaining_items = remaining_size / item_size; size_t read_items = util_size_t_min( items , remaining_items ); size_t read_bytes = read_items * item_size; - + memcpy( target_ptr , &buffer->data[buffer->pos] , read_bytes ); buffer->pos += read_bytes; - + if (read_items < items) { /* The buffer was not large enough - what to do now???? */ - if (abort_on_error) + if (abort_on_error) util_abort("%s: tried to read beyond the length of the buffer: Wanted:%ld Size:%ld \n",__func__ , items , read_items); - else + else /* OK we emulate fread() behaviour - setting errno to EOVERFLOW*/ errno = ENOMEM;//EOVERFLOW; } - + return read_items; } @@ -253,7 +254,7 @@ static size_t buffer_fwrite__(buffer_type * buffer , const void * src_ptr , size */ remaining_size = buffer->alloc_size - buffer->pos; } - + { size_t remaining_items = remaining_size / item_size; @@ -262,12 +263,12 @@ static size_t buffer_fwrite__(buffer_type * buffer , const void * src_ptr , size memcpy( &buffer->data[buffer->pos] , src_ptr , write_bytes ); buffer->pos += write_bytes; - + if (write_items < items) { /* The buffer was not large enough - what to do now???? */ if (abort_on_error) util_abort("%s: failed to write %d elements to the buffer \n",__func__ , items); /* This code is never executed - abort is in resize__(); */ - else + else /* OK we emulate fwrite() behaviour - setting errno to ENOMEM */ errno = ENOMEM; } @@ -308,10 +309,10 @@ void buffer_fseek(buffer_type * buffer , ssize_t offset , int whence) { new_pos = buffer->pos + offset; else if (whence == SEEK_END) new_pos = buffer->content_size + offset; - else + else util_abort("%s: unrecognized whence indicator - aborting \n",__func__); - - /** + + /** Observe that we can seek to the very end of the buffer. I.e. for a buffer with content_size == 20 we can seek to position 20. */ @@ -360,15 +361,26 @@ int buffer_fgetc( buffer_type * buffer ) { } /** - This function writes all the elements in the string __NOT__ - including the terminating \0 character into the buffer. This should - not be confused with buffer_fwrite_string() function which both - prepends the string with an integer length specifier and also - includes the terminating \0. + This function writes all the elements in the string including the + terminating \0 character into the buffer. This should not be + confused with buffer_fwrite_string() function which in addition + prepends the string with an integer length. */ void buffer_fwrite_char_ptr(buffer_type * buffer , const char * string_ptr ) { - buffer_fwrite(buffer , string_ptr , sizeof * string_ptr , strlen( string_ptr )); + buffer_fwrite(buffer , string_ptr , sizeof * string_ptr , strlen( string_ptr ) + 1); +} + + +void buffer_strcat(buffer_type * buffer , const char * string) { + if (buffer->content_size == 0) + buffer_fwrite_char_ptr( buffer , string ); + else { + if (buffer->data[ buffer->content_size - 1] == '\0') { + buffer_fseek( buffer , -1 , SEEK_END); + buffer_fwrite_char_ptr( buffer , string ); + } + } } @@ -377,7 +389,7 @@ void buffer_fwrite_char_ptr(buffer_type * buffer , const char * string_ptr ) { of the buffer will be checked, and no new \0 will be added if the buffer is already \0 terminated. */ -void buffer_terminate_char_ptr( buffer_type * buffer ) { +static void buffer_terminate_char_ptr( buffer_type * buffer ) { if (buffer->data[ buffer->content_size - 1] != '\0') buffer_fwrite_char( buffer , '\0'); } @@ -448,57 +460,6 @@ void buffer_fwrite_double(buffer_type * buffer , double value) { -/** - Storing strings: - ---------------- - - When storing a string (\0 terminated char pointer) what is actually - written to the buffer is - - 1. The length of the string - as returned from strlen(). - 2. The string content INCLUDING the terminating \0. - - -*/ - - -/** - This function will return a pointer to the current position in the - buffer, and advance the buffer position forward until a \0 - terminater is found. If \0 is not found the thing will abort(). - - Observe that the return value will point straight into the buffer, - this is highly volatile memory, and in general it will be safer to - use buffer_fread_alloc_string() to get a copy of the string. -*/ - -const char * buffer_fread_string(buffer_type * buffer) { - int string_length = buffer_fread_int( buffer ); - char * string_ptr = &buffer->data[buffer->pos]; - char c; - buffer_fskip( buffer , string_length ); - c = buffer_fread_char( buffer ); - if (c != '\0') - util_abort("%s: internal error - malformed string representation in buffer \n",__func__); - return string_ptr; -} - - - -char * buffer_fread_alloc_string(buffer_type * buffer) { - return util_alloc_string_copy( buffer_fread_string( buffer )); -} - - - -/** - Observe that this function writes a leading integer string length. -*/ -void buffer_fwrite_string(buffer_type * buffer , const char * string) { - buffer_fwrite_int( buffer , strlen( string )); /* Writing the length of the string */ - buffer_fwrite(buffer , string , 1 , strlen( string ) + 1); /* Writing the string content ** WITH ** the terminating \0 */ -} - @@ -528,22 +489,27 @@ size_t buffer_get_remaining_size(const buffer_type * buffer) { return buffer->content_size - buffer->pos; } -/** +/** Returns a pointer to the internal storage of the buffer. Observe that this storage is volatile, and the return value from this function should not be kept around; alternatively you can use buffer_alloc_data_copy(). */ -void * buffer_get_data(const buffer_type * buffer) { +void * buffer_get_data(const buffer_type * buffer) { return buffer->data; } +void * buffer_iget_data(const buffer_type * buffer, size_t offset) { + return &buffer->data[offset]; +} + + /** Returns a copy of the initialized (i.e. buffer->content_size) buffer content. */ -void * buffer_alloc_data_copy(const buffer_type * buffer) { +void * buffer_alloc_data_copy(const buffer_type * buffer) { return util_alloc_copy(buffer->data , buffer->content_size ); } @@ -571,11 +537,11 @@ void * buffer_alloc_data_copy(const buffer_type * buffer) { ------------------------------------------------- | 0 | 1 | 2 | 3 | x | x | x | 4 | 5 | 6 | 7 | x | ------------------------------------------------- - + If you are shifting beyound the end of the buffer, it will be automatically resized. - + buffer_memshift(buffer , 2 , -4) -------------------------------- @@ -583,7 +549,7 @@ void * buffer_alloc_data_copy(const buffer_type * buffer) { | 4 | 5 | 6 | 7 | 8 | x | x | x | x | x | x | x | ------------------------------------------------- - + When shifting to the left, content is lost (without warning/error) when it is shifted beyond the start of the buffer. @@ -593,7 +559,7 @@ void * buffer_alloc_data_copy(const buffer_type * buffer) { case it is set to the new end of the buffer. */ -void buffer_memshift(buffer_type * buffer , size_t offset, ssize_t shift) { +void buffer_memshift(buffer_type * buffer , size_t offset, ssize_t shift) { /* Do we need to grow the buffer? */ if (shift > 0) { if (buffer->alloc_size <= (buffer->content_size + shift)) { @@ -601,7 +567,7 @@ void buffer_memshift(buffer_type * buffer , size_t offset, ssize_t shift) { buffer_resize__(buffer , new_size , true ); } } - + { size_t move_size; if (shift < 0) @@ -611,7 +577,7 @@ void buffer_memshift(buffer_type * buffer , size_t offset, ssize_t shift) { move_size = buffer->content_size - offset; memmove( &buffer->data[offset + shift] , &buffer->data[offset] , move_size ); buffer->content_size += shift; - buffer->pos = util_size_t_min( buffer->pos , buffer->content_size); + buffer->pos = util_size_t_min( buffer->pos , buffer->content_size); } } @@ -625,7 +591,6 @@ void buffer_replace_data(buffer_type * buffer , size_t offset , size_t old_size void buffer_replace_string( buffer_type * buffer , size_t offset , size_t old_size , const char * new_string) { - buffer_replace_data( buffer , offset , old_size , new_string , strlen(new_string)); } @@ -635,34 +600,28 @@ void buffer_replace_string( buffer_type * buffer , size_t offset , size_t old_si the string @expr in @buffer. The search will start at the current position in the buffer, if the string is found true is returned AND the internal pos is updated to point at the match. - + If the string is NOT found the function will return false, without touching internal state. */ bool buffer_strstr( buffer_type * buffer , const char * expr ) { - /** - If this condition is satisfied the assumption that buffer->data - is a \0 terminated string certainly breaks down. - */ - if ((buffer->content_size == 0) || (buffer->pos == buffer->content_size)) - return false; + bool match = false; - { - char * match = NULL; - - match = strstr( &buffer->data[buffer->pos] , expr); - if (match != NULL) - buffer->pos = match - buffer->data; - - return (match != NULL); + if (strlen(expr) > 0) { + char * match_ptr = strstr( &buffer->data[buffer->pos] , expr ); + if (match_ptr) { + buffer->pos += match_ptr - &buffer->data[buffer->pos]; + match = true; + } } + return match; } bool buffer_strchr( buffer_type * buffer , int c) { - /** + /** If this condition is satisfied the assumption that buffer->data is a \0 terminated string certainly breaks down. */ @@ -670,30 +629,37 @@ bool buffer_strchr( buffer_type * buffer , int c) { return false; { - char * match = NULL; - - match = strchr( &buffer->data[buffer->pos] , c); - if (match != NULL) - buffer->pos = match - buffer->data; - - return (match != NULL); + bool match = false; + size_t pos = buffer->pos; + + while (true) { + if (buffer->data[pos] == c) { + match = true; + buffer->pos = pos; + break; + } + pos++; + if (pos == buffer->content_size) + break; + } + + return match; } } - bool buffer_search_replace( buffer_type * buffer , const char * old_string , const char * new_string) { - const int shift = strlen( new_string ) - strlen( old_string ); - bool match = buffer_strstr( buffer , old_string ); + bool match = buffer_strstr( buffer , old_string ); if (match) { size_t offset = buffer_get_offset( buffer ) + strlen( old_string ); + const int shift = strlen( new_string ) - strlen( old_string ); if (shift != 0) buffer_memshift( buffer , offset , shift ); - - /** Search continues at the end of the newly inserted string - i.e. no room for recursions. */ - buffer_fwrite( buffer , new_string , strlen( new_string ) , sizeof * new_string ); + + buffer_fwrite( buffer , new_string , 1 , strlen(new_string)); + buffer_terminate_char_ptr( buffer ); } return match; } @@ -723,14 +689,14 @@ void buffer_summarize(const buffer_type * buffer , const char * header) { /** This is the lowest level: 'read buffer content from file' function. It will read 'byte_size' bytes from stream and fill the - buffer with the data. - + buffer with the data. + When the function completes the buffer position is at the end of the buffer, i.e. it is ready for more calls to buffer_stream_fread; this is in contrast to the higher level functions buffer_fread_alloc() / buffer_fread_realloc() which reposition the buffer position to the beginning of the buffer. - + Before reading from the buffer with e.g. buffer_fread_int() the buffer must be repositioned with buffer_rewind(). */ @@ -758,8 +724,8 @@ void buffer_stream_fread( buffer_type * buffer , size_t byte_size , FILE * strea void buffer_fread_realloc(buffer_type * buffer , const char * filename) { size_t file_size = util_file_size( filename ); - FILE * stream = util_fopen( filename , "r"); - + FILE * stream = util_fopen( filename , "r"); + buffer_clear( buffer ); /* Setting: content_size = 0; pos = 0; */ buffer_stream_fread( buffer , file_size , stream ); buffer_rewind( buffer ); /* Setting: pos = 0; */ @@ -779,7 +745,7 @@ buffer_type * buffer_fread_alloc(const char * filename) { /** Will write parts of the buffer to the stream. Will start at buffer position @offset and write @write_size bytes. - + o If @offset is invalid, i.e. less than zero or greater than buffer->content_size the function will fail hard. @@ -787,7 +753,7 @@ buffer_type * buffer_fread_alloc(const char * filename) { function will just write all the available data, but not complain any more. - o @write_size == 0 that is interpreted as "write everything from offset". + o @write_size == 0 that is interpreted as "write everything from offset". o @write_size < 0 is interpreted as : "Write everything except the abs(@write_size) last bytes. @@ -802,15 +768,15 @@ size_t buffer_stream_fwrite_n( const buffer_type * buffer , size_t offset , ssiz ssize_t len; if (write_size > 0) /* Normal - write @write_size bytes from offset */ - len = write_size; - else if (write_size == 0) /* Write everything from the offset */ + len = write_size; + else if (write_size == 0) /* Write everything from the offset */ len = buffer->content_size - offset; else /* @write_size < 0 - write everything excluding the last abs(write_size) bytes. */ len = buffer->content_size - offset - abs( write_size ); if (len < 0) util_abort("%s: invalid length spesifier - tried to write %ld bytes \n",__func__ , len); - + util_fwrite( &buffer->data[offset] , 1 , len , stream , __func__); return len; } @@ -829,7 +795,7 @@ void buffer_stream_fprintf( const buffer_type * buffer , FILE * stream ) { /** - Dumps buffer content to a stream - without any metadata. + Dumps buffer content to a stream - without any metadata. */ void buffer_store(const buffer_type * buffer , const char * filename) { FILE * stream = util_fopen(filename , "w"); @@ -838,6 +804,8 @@ void buffer_store(const buffer_type * buffer , const char * filename) { } +#include "buffer_string.c" + #ifdef WITH_ZLIB #include "buffer_zlib.c" #endif diff --git a/ThirdParty/Ert/devel/libert_util/src/buffer_string.c b/ThirdParty/Ert/devel/libert_util/src/buffer_string.c new file mode 100644 index 0000000000..ab8ed74dc1 --- /dev/null +++ b/ThirdParty/Ert/devel/libert_util/src/buffer_string.c @@ -0,0 +1,57 @@ +/* + The functions buffer_fread_string() and buffer_fwrite_string() + should not be used; the embedded integer just creates chaos and + should the sole responsability of the calling scope. +*/ + +/** + Storing strings: + ---------------- + + When storing a string (\0 terminated char pointer) what is actually + written to the buffer is + + 1. The length of the string - as returned from strlen(). + 2. The string content INCLUDING the terminating \0. + + +*/ + + +/** + This function will return a pointer to the current position in the + buffer, and advance the buffer position forward until a \0 + terminater is found. If \0 is not found the thing will abort(). + + Observe that the return value will point straight into the buffer, + this is highly volatile memory, and in general it will be safer to + use buffer_fread_alloc_string() to get a copy of the string. +*/ + +const char * buffer_fread_string(buffer_type * buffer) { + int string_length = buffer_fread_int( buffer ); + char * string_ptr = &buffer->data[buffer->pos]; + char c; + buffer_fskip( buffer , string_length ); + c = buffer_fread_char( buffer ); + if (c != '\0') + util_abort("%s: internal error - malformed string representation in buffer \n",__func__); + return string_ptr; +} + + + +char * buffer_fread_alloc_string(buffer_type * buffer) { + return util_alloc_string_copy( buffer_fread_string( buffer )); +} + + + +/** + Observe that this function writes a leading integer string length. +*/ +void buffer_fwrite_string(buffer_type * buffer , const char * string) { + buffer_fwrite_int( buffer , strlen( string )); /* Writing the length of the string */ + buffer_fwrite(buffer , string , 1 , strlen( string ) + 1); /* Writing the string content ** WITH ** the terminating \0 */ +} + diff --git a/ThirdParty/Ert/devel/libert_util/src/hash.c b/ThirdParty/Ert/devel/libert_util/src/hash.c index 1007e3d982..0237da18f1 100644 --- a/ThirdParty/Ert/devel/libert_util/src/hash.c +++ b/ThirdParty/Ert/devel/libert_util/src/hash.c @@ -159,8 +159,9 @@ static void * __hash_get_node_unlocked(const hash_type *__hash , const char *key difficult due to locking requirements. */ -static void * __hash_get_node(hash_type *hash , const char *key, bool abort_on_error) { +static void * __hash_get_node(const hash_type *hash_in , const char *key, bool abort_on_error) { hash_node_type * node; + hash_type * hash = (hash_type *)hash_in; __hash_rdlock( hash ); node = __hash_get_node_unlocked(hash , key , abort_on_error); __hash_unlock( hash ); @@ -168,7 +169,7 @@ static void * __hash_get_node(hash_type *hash , const char *key, bool abort_on_e } -static node_data_type * hash_get_node_data(hash_type *hash , const char *key) { +static node_data_type * hash_get_node_data(const hash_type *hash , const char *key) { hash_node_type * node = __hash_get_node(hash , key , true); return hash_node_get_data(node); } @@ -356,7 +357,7 @@ void hash_insert_string(hash_type * hash , const char * key , const char * value } -char * hash_get_string(hash_type * hash , const char * key) { +char * hash_get_string(const hash_type * hash , const char * key) { node_data_type * node_data = hash_get_node_data(hash , key); return node_data_get_string( node_data ); } @@ -369,7 +370,7 @@ void hash_insert_int(hash_type * hash , const char * key , int value) { } -int hash_get_int(hash_type * hash , const char * key) { +int hash_get_int(const hash_type * hash , const char * key) { node_data_type * node_data = hash_get_node_data(hash , key); return node_data_get_int( node_data ); } @@ -400,7 +401,7 @@ int hash_inc_counter(hash_type * hash , const char * counter_key) { Will return 0 if the key is not in the hash. */ -int hash_get_counter(hash_type * hash , const char * key) { +int hash_get_counter(const hash_type * hash , const char * key) { if (hash_has_key( hash , key )) return hash_get_int( hash , key ); else @@ -414,7 +415,7 @@ void hash_insert_double(hash_type * hash , const char * key , double value) { __hash_insert_node(hash , hash_node); } -double hash_get_double(hash_type * hash , const char * key) { +double hash_get_double(const hash_type * hash , const char * key) { node_data_type * node_data = hash_get_node_data(hash , key); return node_data_get_double( node_data ); } diff --git a/ThirdParty/Ert/devel/libert_util/src/rng.c b/ThirdParty/Ert/devel/libert_util/src/rng.c index 037c7ab50f..90851e423a 100644 --- a/ThirdParty/Ert/devel/libert_util/src/rng.c +++ b/ThirdParty/Ert/devel/libert_util/src/rng.c @@ -230,6 +230,15 @@ rng_alg_type rng_get_type( const rng_type * rng ) { return rng->type; } +unsigned int rng_get_max_int(const rng_type * rng) { + unsigned int MAX = -1; + if(rng->max_value < MAX) { + return rng->max_value; + } else { + return MAX; + } +} + /*****************************************************************/ void rng_shuffle( rng_type * rng , char * data , size_t element_size , size_t num_elements) { diff --git a/ThirdParty/Ert/devel/libert_util/src/string_util.c b/ThirdParty/Ert/devel/libert_util/src/string_util.c index 53a788564b..ec7c85b654 100644 --- a/ThirdParty/Ert/devel/libert_util/src/string_util.c +++ b/ThirdParty/Ert/devel/libert_util/src/string_util.c @@ -1,19 +1,19 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. - - The file 'string_util.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> - for more details. + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'string_util.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> + for more details. */ #include <ctype.h> @@ -27,13 +27,13 @@ /*****************************************************************/ -/* +/* This functions parses an input string 'range_string' of the type: "0,1,8, 10 - 20 , 15,17-21" - + I.e. integers separated by "," and "-". The integer values are - parsed out. + parsed out. */ //#include <stringlist.h> @@ -47,11 +47,11 @@ // NULL ); // stringlist_type * tokens; // tokens = tokenize_buffer( tokenizer , range_string , true); -// +// // stringlist_free( tokens ); // tokenizer_free( tokenizer ); -//} - +//} + static bool valid_characters( const char * range_string ) { @@ -63,7 +63,7 @@ static bool valid_characters( const char * range_string ) { char c = range_string[offset]; if (isspace(c) || isdigit(c) || c == ',' || c == '-') offset++; - else + else valid = false; if (offset == strlen( range_string ) || !valid) break; @@ -90,14 +90,14 @@ static int_vector_type * string_util_sscanf_alloc_active_list(const char * range int item; active_list = int_vector_alloc(0,0); tokens = basic_parser_tokenize_buffer( parser , range_string , true); - + for (item = 0; item < stringlist_get_size( tokens ); item++) { const char * string_item = stringlist_iget( tokens , item ); char * pos_ptr = (char *) string_item; int value1 , value2; - + value1 = strtol( string_item , &pos_ptr , 10); - if (*pos_ptr == '\0') + if (*pos_ptr == '\0') // The pos_ptr points to the end of the string, i.e. this was a single digit. value2 = value1; else { @@ -105,20 +105,20 @@ static int_vector_type * string_util_sscanf_alloc_active_list(const char * range while (isspace(*pos_ptr) || *pos_ptr == '-') pos_ptr++; util_sscanf_int( pos_ptr , &value2); - } - + } + { int value; - for (value = value1; value <= value2; value++) + for (value = value1; value <= value2; value++) int_vector_append( active_list , value ); } } - - + + stringlist_free( tokens ); basic_parser_free( parser ); } - + return active_list; } @@ -170,7 +170,7 @@ int_vector_type * string_util_alloc_active_list( const char * range_string ) { /* This is the only function which actually invokes the low level - string parsing in util_sscanf_alloc_active_list(). + string parsing in util_sscanf_alloc_active_list(). */ bool string_util_update_active_mask( const char * range_string , bool_vector_type * active_mask) { @@ -179,7 +179,7 @@ bool string_util_update_active_mask( const char * range_string , bool_vector_typ if (sscanf_active) { for (i=0; i < int_vector_size( sscanf_active ); i++) bool_vector_iset( active_mask , int_vector_iget(sscanf_active , i) , true ); - + int_vector_free( sscanf_active ); return true; } else @@ -223,6 +223,6 @@ bool string_util_init_value_list( const char * range_string , int_vector_type * int_vector_type * string_util_alloc_value_list(const char * range_string) { int_vector_type * value_list = int_vector_alloc(0,0); - string_util_init_value_list( range_string , value_list); + string_util_init_value_list( range_string , value_list); return value_list; } diff --git a/ThirdParty/Ert/devel/libert_util/src/stringlist.c b/ThirdParty/Ert/devel/libert_util/src/stringlist.c index 5e9cab85e4..ff8ea03bf5 100644 --- a/ThirdParty/Ert/devel/libert_util/src/stringlist.c +++ b/ThirdParty/Ert/devel/libert_util/src/stringlist.c @@ -1,19 +1,19 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'stringlist.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> - for more details. + Copyright (C) 2011 Statoil ASA, Norway. + + The file 'stringlist.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> + for more details. */ #include <string.h> @@ -38,7 +38,7 @@ This file implements a very thin wrapper around a list (vector) of strings, and the total number of strings. It is mostly to avoid sending both argc and argv. - + Most of the functionality is implemented through vector.c and stateless functions in util.c */ @@ -63,7 +63,7 @@ static void stringlist_fprintf__(const stringlist_type * stringlist, const char const char * s = stringlist_iget(stringlist , i); fprintf(stream , "%s%s", s , sep); } - + fprintf(stream , "%s", stringlist_iget( stringlist , length - 1 )); } } @@ -140,7 +140,7 @@ static stringlist_type * stringlist_alloc_empty( bool alloc_vector ) { stringlist->strings = vector_alloc_new(); else stringlist->strings = NULL; - + return stringlist; } @@ -156,9 +156,9 @@ stringlist_type * stringlist_alloc_new() { stringlist_type * stringlist_alloc_argv_copy(const char ** argv , int argc) { int iarg; stringlist_type * stringlist = stringlist_alloc_empty( true); - for (iarg = 0; iarg < argc; iarg++) + for (iarg = 0; iarg < argc; iarg++) stringlist_append_copy( stringlist , argv[iarg]); - + return stringlist; } @@ -166,7 +166,7 @@ stringlist_type * stringlist_alloc_argv_copy(const char ** argv , int argc) { stringlist_type * stringlist_alloc_argv_ref(const char ** argv , int argc) { int iarg; stringlist_type * stringlist = stringlist_alloc_empty( true ); - for (iarg = 0; iarg < argc; iarg++) + for (iarg = 0; iarg < argc; iarg++) stringlist_append_ref( stringlist , argv[iarg]); return stringlist; @@ -176,19 +176,19 @@ stringlist_type * stringlist_alloc_argv_ref(const char ** argv , int argc) { stringlist_type * stringlist_alloc_argv_owned_ref(const char ** argv , int argc) { int iarg; stringlist_type * stringlist = stringlist_alloc_empty( true ); - for (iarg = 0; iarg < argc; iarg++) + for (iarg = 0; iarg < argc; iarg++) stringlist_append_owned_ref( stringlist , argv[iarg]); - + return stringlist; } -/** +/** Allocates a new stringlist instance where all the new string are references to the string found in the existing stringlist - instance. -*/ + instance. +*/ stringlist_type * stringlist_alloc_shallow_copy(const stringlist_type * src) { stringlist_type * copy = stringlist_alloc_empty( false ); copy->strings = vector_alloc_copy( src->strings , false); @@ -223,7 +223,7 @@ stringlist_type * stringlist_alloc_shallow_copy_with_limits(const stringlist_typ stringlist_type * stringlist_alloc_deep_copy_with_limits(const stringlist_type * src, int offset , int num_strings) { stringlist_type * copy = stringlist_alloc_empty( true ); int i; - for (i = 0; i < num_strings; i++) + for (i = 0; i < num_strings; i++) stringlist_append_copy( copy , stringlist_iget( src , i + offset)); return copy; } @@ -256,7 +256,7 @@ void stringlist_append_stringlist_ref(stringlist_type * stringlist , const strin /** Insert a copy of a stringlist in some position. - + Can probably be made more efficient. */ @@ -302,7 +302,7 @@ void stringlist_deep_copy( stringlist_type * target , const stringlist_type * sr -/** +/** Frees all the memory contained by the stringlist. */ void stringlist_clear(stringlist_type * stringlist) { @@ -352,11 +352,11 @@ const char * stringlist_back(const stringlist_type * stringlist) { int stringlist_iget_as_int( const stringlist_type * stringlist , int index , bool * valid) { const char * string_value = stringlist_iget( stringlist , index ); int value = -1; - + if (valid != NULL) *valid = false; - if (util_sscanf_int(string_value , &value)) + if (util_sscanf_int(string_value , &value)) if (valid != NULL) *valid = true; @@ -430,7 +430,7 @@ int stringlist_get_size(const stringlist_type * stringlist) { /* - Return NULL if the list has zero entries. + Return NULL if the list has zero entries. */ static char ** stringlist_alloc_char__(const stringlist_type * stringlist, bool deep_copy) { char ** strings = NULL; @@ -460,7 +460,7 @@ char ** stringlist_alloc_char_ref(const stringlist_type * stringlist) { -/** +/** Scans the stringlist (linear scan) to see if it contains (at least) one occurence of 's'. Will never return true if the input string @s equals NULL, altough the stringlist itself can contain @@ -471,7 +471,7 @@ bool stringlist_contains(const stringlist_type * stringlist , const char * s) { int size = stringlist_get_size( stringlist ); int index = 0; bool contains = false; - + while ((index < size) && (!contains)) { const char * istring = stringlist_iget(stringlist , index); if (istring != NULL) @@ -491,7 +491,7 @@ int_vector_type * stringlist_find(const stringlist_type * stringlist, const char int_vector_type * indicies = int_vector_alloc(0, -1); int size = stringlist_get_size( stringlist ); int index = 0; - + while (index < size ) { const char * istring = stringlist_iget(stringlist , index); if (istring != NULL) @@ -562,25 +562,25 @@ char * stringlist_alloc_joined_substring( const stringlist_type * s , int start_ { char * string = NULL; int i; - + /* Start with allocating a string long enough to hold all the substrings. */ { int sep_length = strlen( sep ); int total_length = 0; for (i=start_index; i < end_index; i++) total_length += (strlen(stringlist_iget( s , i)) + sep_length); - + total_length += (1 - sep_length); string = util_malloc( total_length * sizeof * string ); string[0] = '\0'; } - + for (i = start_index; i < end_index; i ++) { strcat( string , stringlist_iget( s , i)); if (i < (end_index - 1)) strcat( string , sep ); } - + return string; } } @@ -602,7 +602,7 @@ char * stringlist_alloc_joined_string(const stringlist_type * s , const char * s in the list. The actual functionality is in the util_split_string() function. */ - + stringlist_type * stringlist_alloc_from_split( const char * input_string , const char * sep ) { @@ -624,7 +624,7 @@ void stringlist_buffer_fwrite( const stringlist_type * s , buffer_type * buffer int i; int size = stringlist_get_size( s ); buffer_fwrite_int( buffer , size ); - for (i=0; i < size; i++) + for (i=0; i < size; i++) buffer_fwrite_string(buffer , stringlist_iget(s , i) ); } @@ -633,11 +633,11 @@ void stringlist_fwrite(const stringlist_type * s, FILE * stream) { int i; int size = stringlist_get_size( s ); util_fwrite_int( size , stream); - for (i=0; i < size; i++) + for (i=0; i < size; i++) util_fwrite_string(stringlist_iget(s , i) , stream); } -/* +/* When a stringlist is loaded from file the current content of the stringlist is discarded; and the stringlist becomes the owner of all the data read in. @@ -754,7 +754,7 @@ int stringlist_select_matching_files(stringlist_type * names , const char * path WIN32_FIND_DATA file_data; HANDLE file_handle; char * pattern = util_alloc_filename( path , file_pattern , NULL ); - + stringlist_clear( names ); file_handle = FindFirstFile( pattern , &file_data ); if (file_handle != INVALID_HANDLE_VALUE) { @@ -765,7 +765,7 @@ int stringlist_select_matching_files(stringlist_type * names , const char * path } FindClose( file_handle ); free( pattern ); - + return stringlist_get_size( names ); } #endif @@ -783,7 +783,7 @@ int stringlist_append_matching_elements(stringlist_type * target , const stringl } return match_count; } - + int stringlist_select_matching_elements(stringlist_type * target , const stringlist_type * src , const char * pattern) { stringlist_clear( target ); return stringlist_append_matching_elements( target , src , pattern ); diff --git a/ThirdParty/Ert/devel/libert_util/src/subst_list.c b/ThirdParty/Ert/devel/libert_util/src/subst_list.c index ec51b8fb76..b9bb515114 100644 --- a/ThirdParty/Ert/devel/libert_util/src/subst_list.c +++ b/ThirdParty/Ert/devel/libert_util/src/subst_list.c @@ -1,19 +1,19 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'subst_list.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> - for more details. + Copyright (C) 2011 Statoil ASA, Norway. + + The file 'subst_list.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> + for more details. */ #include <ctype.h> @@ -32,7 +32,7 @@ /** This file implements a small support struct for search-replace operations, along with wrapped calls to util_string_replace_inplace(). - + Substitutions can be carried out on files and string in memory (char * with \0 termination); and the operations can be carried out inplace, or in a filtering mode where a new file/string is created. @@ -46,16 +46,16 @@ * subst_list_insert_ref(subst_list , key , value); * subst_list_insert_owned_ref(subst_list , key , value); - * subst_list_insert_copy(subst_list , key , value ); - + * subst_list_insert_copy(subst_list , key , value ); + The difference between these functions is who is owning the memory pointed to by the value pointer. 3. Do the actual search-replace operation on a file or memory buffer: - + * subst_list_filter_file() : Does search-replace on a file. * subst_list_update_string() : Does search-replace on a buffer. - + 4. Free the subst_list and go home. Internally the (key,value) pairs used for substitutions are stored in a @@ -71,10 +71,10 @@ */ -typedef enum { SUBST_DEEP_COPY = 1, +typedef enum { SUBST_DEEP_COPY = 1, SUBST_MANAGED_REF = 2, SUBST_SHARED_REF = 3} subst_insert_type; /* Mode used in the subst_list_insert__() function */ - + #define SUBST_LIST_TYPE_ID 6614320 struct subst_list_struct { @@ -83,7 +83,7 @@ struct subst_list_struct { vector_type * string_data; /* The string substitutions we should do. */ vector_type * func_data; /* The functions we support. */ const subst_func_pool_type * func_pool; /* NOT owned by the subst_list instance - can be NULL */ - hash_type * map; + hash_type * map; }; @@ -96,16 +96,16 @@ typedef struct { -/* +/* The subst_list type is implemented as a hash of subst_list_node instances. This node type is not exported out of this file scope at all. */ -typedef struct { +typedef struct { bool value_owner; /* Wether the memory pointed to by value should bee freed.*/ char * value; - char * key; + char * key; char * doc_string; /* A doc_string of this substitution - only for documentation - can be NULL. */ } subst_list_string_type; @@ -120,7 +120,7 @@ static subst_list_string_type * subst_list_string_alloc(const char * key) { subst_list_string_type * node = util_malloc(sizeof * node ); node->value_owner = false; node->value = NULL; - node->doc_string = NULL; + node->doc_string = NULL; node->key = util_alloc_string_copy( key ); return node; } @@ -148,7 +148,7 @@ static void subst_list_string_free__(void * node) { /** - input_value can be NULL. + input_value can be NULL. */ static void subst_list_string_set_value(subst_list_string_type * node, const char * input_value , const char * doc_string , subst_insert_type insert_mode) { subst_list_string_free_content( node ); @@ -158,15 +158,15 @@ static void subst_list_string_set_value(subst_list_string_type * node, const cha value = util_alloc_string_copy(input_value); else value = (char *) input_value; - + if (insert_mode == SUBST_SHARED_REF) node->value_owner = false; else node->value_owner = true; - + node->value = value; } - + if (doc_string != NULL) node->doc_string = util_realloc_string_copy( node->doc_string , doc_string ); } @@ -176,7 +176,7 @@ static void subst_list_string_set_value(subst_list_string_type * node, const cha When arriving at this function the main subst scope should already have verified that the requested function is available in the function pool. */ - + static subst_list_func_type * subst_list_func_alloc( const char * func_name, subst_func_type * func) { subst_list_func_type * subst_func = util_malloc( sizeof * subst_func ); subst_func->name = util_alloc_string_copy( func_name ); @@ -231,14 +231,14 @@ static subst_list_string_type * subst_list_insert_new_node(subst_list_type * sub vector_append_owned_ref( subst_list->string_data , new_node , subst_list_string_free__ ); else vector_insert_owned_ref( subst_list->string_data , 0 , new_node , subst_list_string_free__ ); - + hash_insert_ref( subst_list->map , key , new_node ); return new_node; } /*****************************************************************/ -static UTIL_IS_INSTANCE_FUNCTION( subst_list , SUBST_LIST_TYPE_ID ) +UTIL_IS_INSTANCE_FUNCTION( subst_list , SUBST_LIST_TYPE_ID ) /** @@ -266,13 +266,13 @@ bool subst_list_has_key( const subst_list_type * subst_list , const char * key) } -/* +/* The input argument is currently only (void *), runtime it will be checked whether it is of type subst_list_type, in which case it is interpreted as a parent instance, if it is of type subst_func_pool_type it is interpreted as a func_pool instance, otherwise the function will fail hard. - + If the the input argument is a subst_list parent, the func_pool of the parent is used also for the newly allocated subst_list instance. @@ -289,14 +289,14 @@ subst_list_type * subst_list_alloc(const void * input_arg) { subst_list->func_data = vector_alloc_new(); if (input_arg != NULL) { - if (subst_list_is_instance( input_arg )) + if (subst_list_is_instance( input_arg )) subst_list_set_parent( subst_list , input_arg ); else if (subst_func_pool_is_instance( input_arg )) subst_list->func_pool = input_arg; else util_abort("%s: run_time cast failed - invalid type on input argument.\n",__func__); } - + return subst_list; } @@ -315,10 +315,10 @@ subst_list_type * subst_list_alloc(const void * input_arg) { */ -static void subst_list_insert__(subst_list_type * subst_list , const char * key , const char * value , const char * doc_string, bool append , +static void subst_list_insert__(subst_list_type * subst_list , const char * key , const char * value , const char * doc_string, bool append , subst_insert_type insert_mode) { subst_list_string_type * node = subst_list_get_string_node(subst_list , key); - + if (node == NULL) /* Did not have the node. */ node = subst_list_insert_new_node(subst_list , key ,append); subst_list_string_set_value(node , value , doc_string , insert_mode); @@ -346,7 +346,7 @@ static void subst_list_insert__(subst_list_type * subst_list , const char * key to do whatever it wants with the value pointer. */ - + void subst_list_append_ref(subst_list_type * subst_list , const char * key , const char * value, const char * doc_string) { subst_list_insert__(subst_list , key , value , doc_string , true , SUBST_SHARED_REF); } @@ -381,7 +381,7 @@ void subst_list_prepend_copy(subst_list_type * subst_list , const char * key , c */ void subst_list_insert_func(subst_list_type * subst_list , const char * func_name , const char * local_func_name) { - + if (subst_list->func_pool != NULL && subst_func_pool_has_func( subst_list->func_pool , func_name )) { subst_list_func_type * subst_func = subst_list_func_alloc( local_func_name , subst_func_pool_get_func( subst_list->func_pool , func_name )); vector_append_owned_ref( subst_list->func_data , subst_func , subst_list_func_free__ ); @@ -407,10 +407,10 @@ void subst_list_free(subst_list_type * subst_list) { /* Below comes many different functions for doing the actual updating the functions differ in the form of the input and output. At the - lowest level, is the function - + lowest level, is the function + subst_list_uppdate_buffer() - + which will update a buffer instance. This function again will call two separate functions for pure string substitutions and for function evaluation. @@ -486,19 +486,19 @@ static bool subst_list_eval_funcs____(const subst_list_type * subst_list , const for (index = 0; index < vector_get_size( subst_list->func_data); index++) { const subst_list_func_type * subst_func = vector_iget_const( subst_list->func_data , index ); const char * func_name = subst_func->name; - + bool match; buffer_rewind( buffer ); do { size_t match_pos; match = buffer_strstr( buffer , func_name ); match_pos = buffer_get_offset( buffer ); - + if (match) { bool update = false; char * arg_start = buffer_get_data( buffer ); arg_start += buffer_get_offset( buffer ) + strlen( func_name ); - + if (arg_start[0] == '(') { /* We require that an opening paren follows immediately behind the function name. */ char * arg_end = strchr( arg_start , ')'); if (arg_end != NULL) { @@ -506,8 +506,8 @@ static bool subst_list_eval_funcs____(const subst_list_type * subst_list , const char * arg_content = util_alloc_substring_copy( arg_start, 1 , arg_end - arg_start - 1); stringlist_type * arg_list = basic_parser_tokenize_buffer( parser , arg_content , true); char * func_eval = subst_list_func_eval( subst_func , arg_list ); - int old_len = strlen(func_name) + strlen( arg_content) + 2; - + int old_len = strlen(func_name) + strlen( arg_content) + 2; + if (func_eval != NULL) { buffer_memshift( buffer , match_pos + old_len , strlen( func_eval ) - old_len); buffer_fwrite( buffer , func_eval , strlen( func_eval ) , sizeof * func_eval ); @@ -515,17 +515,17 @@ static bool subst_list_eval_funcs____(const subst_list_type * subst_list , const update = true; global_match = true; } - + free( arg_content ); stringlist_free( arg_list ); - } - } - if (!update) + } + } + if (!update) buffer_fseek( buffer , match_pos + strlen( func_name ) , SEEK_SET); } } while (match); } - if (subst_list->parent != NULL) + if (subst_list->parent != NULL) global_match = (subst_list_eval_funcs____( subst_list->parent , parser , buffer ) || global_match); return global_match; } @@ -548,7 +548,7 @@ static bool subst_list_eval_funcs__(const subst_list_type * subst_list , buffer_ Inherited defintions -------------------- - + In this situation we have defined a (key,value) substitution, where the value depends on a value following afterwards: @@ -559,7 +559,7 @@ static bool subst_list_eval_funcs__(const subst_list_type * subst_list , buffer_ subsequently "<CASE>" is replaced with "Test4". A typical use case here is that the common definition of "<PATH>" is in the parent, and consequently parent should run first (i.e. top - down). + down). However, in other cases the order of defintion might very well be opposite, i.e. with "<CASE>" first and then things will blow up: @@ -569,8 +569,8 @@ static bool subst_list_eval_funcs__(const subst_list_type * subst_list , buffer_ and, the final <CASE> will not be resolved. I.e. there is no obvious 'right' way to do it. - - + + Overriding defaults ------------------- @@ -598,7 +598,7 @@ static bool subst_list_replace_strings( const subst_list_type * subst_list , buf bool match = false; if (subst_list->parent != NULL) match = subst_list_replace_strings( subst_list->parent , buffer ); - + /* The actual string replace */ match = (subst_list_replace_strings__( subst_list , buffer ) || match); return match; @@ -641,7 +641,7 @@ bool subst_list_filter_file(const subst_list_type * subst_list , const char * sr buffer_type * buffer = buffer_fread_alloc( src_file ); buffer_fseek( buffer , 0 , SEEK_END ); /* Ensure that the buffer is a \0 terminated string. */ buffer_fwrite_char( buffer , '\0'); - + /*****************************************************************/ /* Backup file ?? */ if (util_same_file(src_file , target_file)) { @@ -649,19 +649,19 @@ bool subst_list_filter_file(const subst_list_type * subst_list , const char * sr backup_file = util_alloc_tmp_file("/tmp" , backup_prefix , false); free(backup_prefix); } - - + + /* Writing backup file */ if (backup_file != NULL) { FILE * stream = util_fopen(backup_file , "w"); buffer_stream_fwrite_n( buffer , 0 , -1 , stream ); /* -1: Do not write the trailing \0. */ fclose(stream); } - - + + /* Doing the actual update */ match = subst_list_update_buffer(subst_list , buffer); - + /* Writing updated file */ { @@ -669,7 +669,7 @@ bool subst_list_filter_file(const subst_list_type * subst_list , const char * sr buffer_stream_fwrite_n( buffer , 0 , -1 , stream ); /* -1: Do not write the trailing \0. */ fclose(stream); } - + /* OK - all went hunka dory - unlink the backup file and leave the building. */ if (backup_file != NULL) { remove( backup_file ); @@ -697,7 +697,7 @@ bool subst_list_update_string(const subst_list_type * subst_list , char ** strin bool match = subst_list_update_buffer(subst_list , buffer); *string = buffer_get_data( buffer ); buffer_free_container( buffer ); - + return match; } @@ -774,7 +774,7 @@ subst_list_type * subst_list_alloc_deep_copy(const subst_list_type * src) { copy = subst_list_alloc( src->parent ); else copy = subst_list_alloc( src->func_pool); - + { int index; for (index = 0; index < vector_get_size( src->string_data ); index++) { @@ -787,7 +787,7 @@ subst_list_type * subst_list_alloc_deep_copy(const subst_list_type * src) { subst_list_func_type * copy_node = subst_list_func_alloc( src_node->name , src_node->func ); vector_append_owned_ref( copy->func_data , copy_node , subst_list_func_free__ ); } - + } return copy; } @@ -856,29 +856,28 @@ void subst_list_fprintf(const subst_list_type * subst_list , FILE * stream) { KEY1=Value1, Key2=Value2, Key3=Value3. Will return NULL is there are no elements in the subst_list. */ - + char * subst_list_alloc_string_representation( const subst_list_type * subst_list ) { int size = subst_list_get_size( subst_list ); char * return_string = NULL; if (size > 0) { buffer_type * buffer = buffer_alloc( 512 ); int i; - + for (i=0; i < size; i++) { buffer_fwrite_char_ptr( buffer , subst_list_iget_key( subst_list , i)); - buffer_fwrite_char(buffer , '='); - buffer_fwrite_char_ptr( buffer , subst_list_iget_value( subst_list , i)); - if (i < (size - 1)) - buffer_fwrite_char_ptr( buffer , ", "); + buffer_strcat(buffer , "="); + buffer_strcat( buffer , subst_list_iget_value( subst_list , i)); + if (i < (size - 1)) + buffer_strcat( buffer , ", "); } - buffer_fwrite_char( buffer , '\0'); buffer_shrink_to_fit( buffer ); return_string = buffer_get_data( buffer ); buffer_free_container( buffer ); } return return_string; } - + /** Will loose tagging .... */ int subst_list_add_from_string( subst_list_type * subst_list , const char * arg_string, bool append) { @@ -886,7 +885,7 @@ int subst_list_add_from_string( subst_list_type * subst_list , const char * arg_ if (arg_string != NULL) { char ** key_value_list; int num_arg, iarg; - + util_split_string(arg_string , "," , &num_arg , &key_value_list); for (iarg = 0; iarg < num_arg; iarg++) { if (strchr(key_value_list[iarg] , '=') == NULL) @@ -902,27 +901,27 @@ int subst_list_add_from_string( subst_list_type * subst_list , const char * arg_ int arg_length , value_length; while (isspace(*tmp)) /* Skipping initial space */ tmp++; - + arg_length = strcspn(tmp , " ="); key = util_alloc_substring_copy(tmp , 0 , arg_length); tmp += arg_length; while ((*tmp == ' ') || (*tmp == '=')) tmp++; - + value_length = strcspn(tmp , " "); value = util_alloc_substring_copy( tmp , 0 , value_length); - + /* Setting the argument */ if (append) subst_list_append_copy( subst_list , key , value , NULL); else subst_list_prepend_copy( subst_list , key , value , NULL); - + free(key); free(value); tmp += value_length; - - + + /* Accept only trailing space - any other character indicates a failed parsing. */ while (*tmp != '\0') { if (!isspace(*tmp)) diff --git a/ThirdParty/Ert/devel/libert_util/src/template_loop.c b/ThirdParty/Ert/devel/libert_util/src/template_loop.c index 9bd37d2ed8..a56be8149d 100644 --- a/ThirdParty/Ert/devel/libert_util/src/template_loop.c +++ b/ThirdParty/Ert/devel/libert_util/src/template_loop.c @@ -119,15 +119,13 @@ static void loop_free( loop_type * loop ) { static void replace_1var( buffer_type * var_expansion , int shift , int write_offset , int shift_offset , const char * value) { buffer_memshift( var_expansion , shift_offset , shift ); buffer_fseek( var_expansion , write_offset , SEEK_SET ); - buffer_fwrite_char_ptr( var_expansion , value ); + buffer_fwrite( var_expansion , value , strlen(value) , 1); } static void loop_eval( const loop_type * loop , const char * body , buffer_type * var_expansion , int ivar) { buffer_clear( var_expansion ); buffer_fwrite_char_ptr( var_expansion , body ); - buffer_terminate_char_ptr( var_expansion ); - { const char * value = stringlist_iget( loop->items , ivar ); int value_length = strlen( value ); @@ -235,13 +233,12 @@ static int template_eval_loop( const template_type * template , buffer_type * bu for (ivar =0; ivar < stringlist_get_size( loop->items ); ivar++) { loop_eval(loop , body , var_expansion , ivar ); - buffer_fwrite_char_ptr( loop_expansion , buffer_get_data( var_expansion )); + buffer_strcat( loop_expansion , buffer_get_data( var_expansion )); } buffer_free( var_expansion ); util_safe_free( body ); } - buffer_terminate_char_ptr( loop_expansion ); { int tag_length = loop->endtag_offset + loop->endtag_length - loop->opentag_offset; int offset = loop->endtag_offset + loop->endtag_length; @@ -249,7 +246,7 @@ static int template_eval_loop( const template_type * template , buffer_type * bu buffer_memshift( buffer , offset , shift ); buffer_fseek( buffer , loop->opentag_offset , SEEK_SET ); - buffer_fwrite_char_ptr( buffer , buffer_get_data( loop_expansion )); + buffer_fwrite( buffer , buffer_get_data( loop_expansion ) , 1 , buffer_get_string_size( loop_expansion )); global_offset = loop->opentag_offset + buffer_get_string_size( loop_expansion ); } diff --git a/ThirdParty/Ert/devel/libert_util/src/test_util.c b/ThirdParty/Ert/devel/libert_util/src/test_util.c index b7569c57a2..c92189d41e 100644 --- a/ThirdParty/Ert/devel/libert_util/src/test_util.c +++ b/ThirdParty/Ert/devel/libert_util/src/test_util.c @@ -25,7 +25,9 @@ #include <signal.h> #include <ert/util/util.h> +#include <ert/util/arg_pack.h> #include <ert/util/test_util.h> +#include <ert/util/stringlist.h> void test_error_exit( const char * fmt , ...) { @@ -317,3 +319,28 @@ void test_assert_util_abort(const char * function_name , void call_func (void *) #endif + + +/*****************************************************************/ + +#ifdef WITH_PTHREAD +#include <pthread.h> + +pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + +void * thread_pool_test_func1( void * arg ) { + int * value = (int *) arg; + pthread_mutex_lock( &mutex ); + value[0]++; + pthread_mutex_unlock( &mutex ); + return NULL; +} +#endif + + +void * test_argpack_is_stringlist( void * arg ) { + arg_pack_type * arg_pack = arg_pack_safe_cast( arg ); + void * arg0 = arg_pack_iget_ptr( arg_pack , 0 ); + test_assert_true( stringlist_is_instance( arg0 ) ); + return NULL; +} diff --git a/ThirdParty/Ert/devel/libert_util/src/thread_pool.c b/ThirdParty/Ert/devel/libert_util/src/thread_pool.c index 9673623814..a55864d560 100644 --- a/ThirdParty/Ert/devel/libert_util/src/thread_pool.c +++ b/ThirdParty/Ert/devel/libert_util/src/thread_pool.c @@ -1,19 +1,19 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'thread_pool.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> - for more details. + Copyright (C) 2011 Statoil ASA, Norway. + + The file 'thread_pool.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> + for more details. */ #include <ert/util/thread_pool.h> diff --git a/ThirdParty/Ert/devel/libert_util/src/thread_pool_posix.c b/ThirdParty/Ert/devel/libert_util/src/thread_pool_posix.c index 1439d9ac08..e890c70364 100644 --- a/ThirdParty/Ert/devel/libert_util/src/thread_pool_posix.c +++ b/ThirdParty/Ert/devel/libert_util/src/thread_pool_posix.c @@ -20,11 +20,13 @@ #include <string.h> #include <stdlib.h> #include <stdio.h> +#include <signal.h> #include <pthread.h> #include <unistd.h> #include <ert/util/thread_pool.h> #include <ert/util/util.h> +#include <ert/util/type_macros.h> /** This file implements a small thread_pool object based on @@ -117,8 +119,9 @@ typedef struct { - +#define THREAD_POOL_TYPE_ID 71443207 struct thread_pool_struct { + UTIL_TYPE_ID_DECLARATION; thread_pool_arg_type * queue; /* The jobs to be executed are appended in this vector. */ int queue_index; /* The index of the next job to run. */ int queue_size; /* The number of jobs in the queue - including those which are complete. [Should be protected / atomic / ... ] */ @@ -134,7 +137,7 @@ struct thread_pool_struct { }; - +static UTIL_SAFE_CAST_FUNCTION( thread_pool , THREAD_POOL_TYPE_ID ) /** @@ -212,7 +215,7 @@ static void * thread_pool_start_job( void * arg ) { */ static void * thread_pool_main_loop( void * arg ) { - thread_pool_type * tp = (thread_pool_type *) arg; + thread_pool_type * tp = thread_pool_safe_cast( arg ); { const int usleep_init = 1000; /* The sleep time when there are free slots available - but no jobs wanting to run. */ int internal_offset = 0; /* Keep track of the (index of) the last job slot fired off - minor time saving. */ @@ -262,9 +265,8 @@ static void * thread_pool_main_loop( void * arg ) { if (!slot_found) { util_yield(); } - } else { - util_usleep(usleep_init); /* There are no jobs wanting to run. */ - } + } else + util_usleep(usleep_init); /* There are no jobs wanting to run. */ /*****************************************************************/ /* @@ -349,6 +351,65 @@ void thread_pool_join(thread_pool_type * pool) { } } +/* + This will try to join the thread; if the manager thread has not + completed within @timeout_seconds the function will return false. If + the join fails the queue will be reset in a non-joining state and it + will be open for more jobs. Probably not in a 100% sane state. +*/ + +bool thread_pool_try_join(thread_pool_type * pool, int timeout_seconds) { + bool join_ok = true; + + pool->join = true; /* Signals to the main thread that joining can start. */ + if (pool->max_running > 0) { + struct timespec ts; + time_t timeout_time = time( NULL ); + + util_inplace_forward_seconds(&timeout_time , timeout_seconds ); + ts.tv_sec = timeout_time; + ts.tv_nsec = 0; + +#ifdef HAVE_TIMEDJOIN + + { + int join_return = pthread_timedjoin_np( pool->dispatch_thread , NULL , &ts); /* Wait for the main thread to complete. */ + if (join_return == 0) + pool->accepting_jobs = false; + else { + pool->join = false; + join_ok = false; + } + } + +#else + + while(true) { + if (pthread_kill(pool->dispatch_thread, 0) == 0){ + util_yield(); + } else { + pthread_join(pool->dispatch_thread, NULL); + pool->accepting_jobs = false; + break; + } + + time_t now = time(NULL); + + if(util_difftime_seconds(now, timeout_time) <= 0) { + join_ok = false; + break; + } + } + +#endif + + + + } + return join_ok; +} + + /** @@ -360,6 +421,7 @@ void thread_pool_join(thread_pool_type * pool) { thread_pool_type * thread_pool_alloc(int max_running , bool start_queue) { thread_pool_type * pool = util_malloc( sizeof *pool ); + UTIL_TYPE_ID_INIT( pool , THREAD_POOL_TYPE_ID ); pool->job_slots = util_calloc( max_running , sizeof * pool->job_slots ); pool->max_running = max_running; pool->queue = NULL; diff --git a/ThirdParty/Ert/devel/libert_util/src/util.c b/ThirdParty/Ert/devel/libert_util/src/util.c index 3d071d4da8..7943741047 100644 --- a/ThirdParty/Ert/devel/libert_util/src/util.c +++ b/ThirdParty/Ert/devel/libert_util/src/util.c @@ -2637,6 +2637,7 @@ static int util_get_base_length(const char * file) { int path_length = util_get_path_length(file); const char * base_start; const char * last_point; + long character_index; if (path_length == strlen(file)) return 0; @@ -2646,7 +2647,9 @@ static int util_get_base_length(const char * file) { base_start = &file[path_length + 1]; last_point = strrchr(base_start , '.'); - if (last_point == NULL) + character_index = last_point - base_start; + + if (last_point == NULL || character_index == 0) return strlen(base_start); else return last_point - base_start; @@ -3243,6 +3246,15 @@ double util_difftime_seconds( time_t start_time , time_t end_time) { */ +char * util_get_timezone() { +#if defined(HAVE_TZNAME) + return tzname[0]; +#elif defined(HAVE_WINDOWS_TZNAME) + return _tzname[0]; +#endif +} + + time_t util_make_datetime(int sec, int min, int hour , int mday , int month , int year) { struct tm ts; ts.tm_sec = sec; @@ -3250,7 +3262,7 @@ time_t util_make_datetime(int sec, int min, int hour , int mday , int month , in ts.tm_hour = hour; ts.tm_mday = mday; ts.tm_mon = month - 1; - ts.tm_year = year - 1900; + ts.tm_year = year - 1900; ts.tm_isdst = -1; /* Negative value means mktime tries to determine automagically whether Daylight Saving Time is in effect. */ { time_t t = mktime( &ts ); @@ -4849,6 +4861,7 @@ void util_install_signals(void) { Killing with SIGKILL (-9) will not give a backtrace.*/ signal(SIGABRT , util_abort_signal); /* Signal abort. */ signal(SIGILL , util_abort_signal); /* Signal illegal instruction. */ + signal(SIGFPE , util_abort_signal); /* Floating point exception */ } diff --git a/ThirdParty/Ert/devel/libert_util/src/util_env.c b/ThirdParty/Ert/devel/libert_util/src/util_env.c index 934e3e75ae..c52a473931 100644 --- a/ThirdParty/Ert/devel/libert_util/src/util_env.c +++ b/ThirdParty/Ert/devel/libert_util/src/util_env.c @@ -228,7 +228,6 @@ char * util_alloc_envvar( const char * value ) { buffer_type * buffer = buffer_alloc( 1024 ); /* Start by filling up a buffer instance with the current content of @value. */ buffer_fwrite_char_ptr( buffer , value ); - buffer_fwrite_char( buffer , '\0' ); buffer_rewind( buffer ); diff --git a/ThirdParty/Ert/devel/libert_util/tests/CMakeLists.txt b/ThirdParty/Ert/devel/libert_util/tests/CMakeLists.txt index 996618d796..2b5c522c49 100644 --- a/ThirdParty/Ert/devel/libert_util/tests/CMakeLists.txt +++ b/ThirdParty/Ert/devel/libert_util/tests/CMakeLists.txt @@ -10,6 +10,11 @@ set(PING_SERVERS "" CACHE STRING "List of servers for testing ping") link_directories( ${ERT_BINARY_DIR}/libert_util/src ) +add_executable( test_thread_pool test_thread_pool.c ) +target_link_libraries( test_thread_pool ert_util test_util ) +add_test( test_thread_pool valgrind --error-exitcode=1 --tool=memcheck ${EXECUTABLE_OUTPUT_PATH}/test_thread_pool ) + + add_executable( ert_util_type_vector_test ert_util_type_vector_test.c ) target_link_libraries( ert_util_type_vector_test ert_util test_util ) add_test( ert_util_type_vector_test ${EXECUTABLE_OUTPUT_PATH}/ert_util_type_vector_test ) @@ -18,10 +23,19 @@ add_executable( ert_util_matrix ert_util_matrix.c ) target_link_libraries( ert_util_matrix ert_util test_util ) add_test( ert_util_matrix ${EXECUTABLE_OUTPUT_PATH}/ert_util_matrix ) +add_executable( ert_util_subst_list ert_util_subst_list.c ) +target_link_libraries( ert_util_subst_list ert_util test_util ) +add_test( ert_util_subst_list ${EXECUTABLE_OUTPUT_PATH}/ert_util_subst_list ) + + add_executable( ert_util_matrix_stat ert_util_matrix_stat.c ) target_link_libraries( ert_util_matrix_stat ert_util test_util ) add_test( ert_util_matrix_stat ${EXECUTABLE_OUTPUT_PATH}/ert_util_matrix_stat ) +add_executable( ert_util_buffer ert_util_buffer.c ) +target_link_libraries( ert_util_buffer ert_util test_util ) +add_test( ert_util_buffer ${EXECUTABLE_OUTPUT_PATH}/ert_util_buffer ) + add_executable( ert_util_statistics ert_util_statistics.c ) target_link_libraries( ert_util_statistics ert_util test_util ) add_test( ert_util_statistics ${EXECUTABLE_OUTPUT_PATH}/ert_util_statistics ) @@ -146,6 +160,10 @@ add_executable( ert_util_parent_path ert_util_parent_path.c ) target_link_libraries( ert_util_parent_path ert_util test_util ) add_test( ert_util_parent_path ${EXECUTABLE_OUTPUT_PATH}/ert_util_parent_path) +add_executable( ert_util_alloc_file_components ert_util_alloc_file_components.c ) +target_link_libraries( ert_util_alloc_file_components ert_util test_util ) +add_test( ert_util_alloc_file_components ${EXECUTABLE_OUTPUT_PATH}/ert_util_alloc_file_components) + add_executable( ert_util_work_area ert_util_work_area.c ) target_link_libraries( ert_util_work_area ert_util test_util ) add_test( NAME ert_util_work_area diff --git a/ThirdParty/Ert/devel/libert_util/tests/ert_util_alloc_file_components.c b/ThirdParty/Ert/devel/libert_util/tests/ert_util_alloc_file_components.c new file mode 100644 index 0000000000..bb9e6d57a9 --- /dev/null +++ b/ThirdParty/Ert/devel/libert_util/tests/ert_util_alloc_file_components.c @@ -0,0 +1,43 @@ +#include <stdlib.h> +#include <stdbool.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> + +#include <ert/util/util.h> +#include <ert/util/test_util.h> + + +bool checkPath(const char * path, const char * directory, const char * base_name, const char * extension) { + char * dir; + char * base; + char * ext; + + util_alloc_file_components(path, &dir, &base, &ext); + + bool success = true; + + success = success && (util_string_equal(dir, directory) || dir == directory); + success = success && (util_string_equal(base, base_name) || base == base_name); + success = success && (util_string_equal(ext, extension) || ext == extension); + + free(dir); + free(base); + free(ext); + + return success; +} + +int main(int argc , char ** argv) { + + test_assert_true(checkPath("/dir/filename.ext", "/dir", "filename", "ext")); + test_assert_true(checkPath("/dir/subdir/filename.ext", "/dir/subdir", "filename", "ext")); + test_assert_true(checkPath("/dir/subdir/filename.name.ext", "/dir/subdir", "filename.name", "ext")); + test_assert_true(checkPath("/dir/subdir/filename", "/dir/subdir", "filename", NULL)); + test_assert_true(checkPath("filename.ext", NULL, "filename", "ext")); + test_assert_true(checkPath("filename", NULL, "filename", NULL)); + test_assert_true(checkPath(".filename", NULL, ".filename", NULL)); + test_assert_true(checkPath(".filename.ext", NULL, ".filename", "ext")); + + exit(0); +} \ No newline at end of file diff --git a/ThirdParty/Ert/devel/libert_util/tests/ert_util_buffer.c b/ThirdParty/Ert/devel/libert_util/tests/ert_util_buffer.c new file mode 100644 index 0000000000..8c032474ce --- /dev/null +++ b/ThirdParty/Ert/devel/libert_util/tests/ert_util_buffer.c @@ -0,0 +1,144 @@ +/* + Copyright (C) 2015 Statoil ASA, Norway. + + The file 'ert_util_buffer.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> + for more details. +*/ +#include <stdlib.h> +#include <stdbool.h> + +#include <ert/util/test_util.h> +#include <ert/util/buffer.h> + + + +void test_create() { + buffer_type * buffer = buffer_alloc( 1024 ); + test_assert_true( buffer_is_instance( buffer )); + buffer_free( buffer ); +} + + +void test_buffer_strchr() { + buffer_type * buffer = buffer_alloc( 1024 ); + test_assert_false( buffer_strchr( buffer , 'A')); + buffer_fwrite_char_ptr(buffer , "XX AB AB AB"); + test_assert_false( buffer_strchr( buffer , 'A')); + + buffer_rewind( buffer ); + test_assert_true( buffer_strchr( buffer , 'A')); buffer_fskip(buffer , 1); + test_assert_true( buffer_strchr( buffer , 'A')); buffer_fskip(buffer , 1); + test_assert_true( buffer_strchr( buffer , 'A')); buffer_fskip(buffer , 1); + test_assert_false( buffer_strchr( buffer , 'A')); + buffer_free( buffer ); +} + +void test_buffer_strstr() { + buffer_type * buffer = buffer_alloc( 1024 ); + test_assert_false( buffer_strstr( buffer , "Hello World" )); + test_assert_false( buffer_strstr( buffer , "" )); + + buffer_fwrite_char_ptr( buffer , "ABC"); + test_assert_int_equal( buffer_get_size( buffer ), 4 ); + test_assert_false( buffer_strstr( buffer , "ABC")); + + buffer_rewind( buffer ); + test_assert_true( buffer_strstr( buffer , "ABC")); + test_assert_int_equal( buffer_get_offset(buffer) , 0); + test_assert_string_equal( "ABC" , buffer_get_data(buffer)); + + { + size_t pos = buffer_get_offset( buffer ); + test_assert_false( buffer_strstr( buffer , "ABCD" )); + test_assert_size_t_equal( pos , buffer_get_offset( buffer )); + } + buffer_rewind( buffer ); + test_assert_true( buffer_strstr( buffer , "AB" )); + test_assert_true( buffer_strstr( buffer , "ABC" )); + test_assert_true( buffer_strstr( buffer , "BC" )); + test_assert_false( buffer_strstr( buffer , "ABC" )); +} + + + + +void test_buffer_search_replace1() { + buffer_type * buffer = buffer_alloc( 1024 ); + test_assert_false( buffer_search_replace( buffer , "" , "XYZ")); + test_assert_false( buffer_search_replace( buffer , "XYZ" , "ABC")); + test_assert_false( buffer_search_replace( buffer , "XYZ" , "")); + + buffer_fwrite_char_ptr(buffer , "ABC 123"); + buffer_rewind(buffer); + test_assert_true( buffer_search_replace( buffer, "ABC" , "XYZ" )); + buffer_rewind( buffer ); + test_assert_string_equal( "XYZ 123" , buffer_get_data( buffer )); + + buffer_rewind( buffer ); + test_assert_true( buffer_search_replace( buffer, "XYZ" , "A")); + buffer_rewind( buffer ); + test_assert_string_equal( "A 123" , buffer_get_data( buffer )); + + buffer_rewind( buffer ); + test_assert_true( buffer_search_replace( buffer, "A", "XYZ")); + buffer_rewind( buffer ); + test_assert_string_equal( "XYZ 123" , buffer_get_data( buffer )); + + buffer_free( buffer ); +} + + +void test_buffer_search_replace2() { + buffer_type * buffer = buffer_alloc( 1024 ); + buffer_fwrite_char_ptr(buffer , "MAGIC_PRINT magic-list.txt <ERTCASE> __MAGIC__"); + + buffer_rewind( buffer ); + test_assert_false( buffer_search_replace( buffer , "<CASE>" , "SUPERCase")); + test_assert_string_equal( "MAGIC_PRINT magic-list.txt <ERTCASE> __MAGIC__" , buffer_get_data( buffer)); + + buffer_rewind( buffer ); + test_assert_true( buffer_search_replace( buffer , "<ERTCASE>" , "default")); + test_assert_string_equal( "MAGIC_PRINT magic-list.txt default __MAGIC__" , buffer_get_data( buffer)); + + + buffer_free( buffer ); +} + + +void test_char_ptr( ) { + buffer_type * buffer = buffer_alloc(1024); + buffer_fwrite_char_ptr( buffer , "Hello World"); + test_assert_size_t_equal( buffer_get_size( buffer ) , 12 ); + test_assert_int_equal( strlen( buffer_get_data( buffer )) , 11); + + buffer_clear( buffer ); + buffer_fwrite_char_ptr(buffer , "Hello" ); + buffer_strcat( buffer , " " ); + buffer_strcat( buffer , "World" ); + test_assert_size_t_equal( buffer_get_size( buffer ) , 12 ); + test_assert_int_equal( strlen( buffer_get_data( buffer )) , 11); + + buffer_free( buffer ); +} + + +int main( int argc , char ** argv) { + test_create(); + test_char_ptr(); + test_buffer_strchr(); + test_buffer_strstr(); + test_buffer_search_replace1(); + test_buffer_search_replace2(); + exit(0); +} diff --git a/ThirdParty/Ert/devel/libert_util/tests/ert_util_subst_list.c b/ThirdParty/Ert/devel/libert_util/tests/ert_util_subst_list.c new file mode 100644 index 0000000000..e5d5c1a526 --- /dev/null +++ b/ThirdParty/Ert/devel/libert_util/tests/ert_util_subst_list.c @@ -0,0 +1,97 @@ +/* + Copyright (C) 2015 Statoil ASA, Norway. + + The file 'ert_util_subst_list.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> + for more details. +*/ +#include <stdlib.h> +#include <stdbool.h> +#include <string.h> + +#include <ert/util/test_work_area.h> +#include <ert/util/subst_list.h> +#include <ert/util/test_util.h> + + +void test_create() { + subst_list_type * subst_list = subst_list_alloc( NULL ); + test_assert_true( subst_list_is_instance( subst_list ) ); + subst_list_free( subst_list ); +} + + +void test_filter_file1() { + subst_list_type * subst_list = subst_list_alloc( NULL ); + test_work_area_type * work_area = test_work_area_alloc("subst_list/filter1"); + { + FILE * stream = util_fopen("template" , "w"); + fprintf(stream , "<KEY1>\n<KEY2>\n<KEY3>\n<KEY4>\n"); + fclose(stream); + } + subst_list_append_copy( subst_list , "<KEY1>" , "Value1" , NULL); + subst_list_append_copy( subst_list , "<KEY2>" , "Value2" , NULL); + subst_list_append_copy( subst_list , "<KEY3>" , "Value3" , NULL); + subst_list_append_copy( subst_list , "<KEY4>" , "Value4" , NULL); + + subst_list_filter_file( subst_list , "template" , "target"); + + { + FILE * stream = util_fopen("target" , "r"); + char s1[128],s2[128],s3[128],s4[128]; + + test_assert_int_equal( 4 , fscanf( stream , "%s %s %s %s" , s1,s2,s3,s4)); + fclose(stream); + + test_assert_string_equal( s1 , "Value1"); + test_assert_string_equal( s2 , "Value2"); + test_assert_string_equal( s3 , "Value3"); + test_assert_string_equal( s4 , "Value4"); + } + test_work_area_free( work_area ); + subst_list_free( subst_list ); +} + + +void test_filter_file2() { + subst_list_type * subst_list = subst_list_alloc( NULL ); + test_work_area_type * work_area = test_work_area_alloc("subst_list/filter2"); + { + FILE * stream = util_fopen("template" , "w"); + fprintf(stream , "MAGIC_PRINT magic-list.txt <ERTCASE> __MAGIC__"); + fclose(stream); + } + + subst_list_append_copy( subst_list , "<QC_PATH>" , "QC" , NULL); + subst_list_append_copy( subst_list , "__MAGIC__" , "MagicAllTheWayToWorkFlow" , NULL); + subst_list_append_copy( subst_list , "<CASE>" , "SUPERcase" , NULL); + subst_list_append_copy( subst_list , "<ERTCASE>" , "default" , NULL); + subst_list_filter_file( subst_list , "template" , "target"); + + { + char * target_string = util_fread_alloc_file_content( "target" , NULL ); + test_assert_string_equal( target_string , "MAGIC_PRINT magic-list.txt default MagicAllTheWayToWorkFlow"); + free( target_string ); + } + test_work_area_free( work_area ); + subst_list_free( subst_list ); +} + + + + +int main(int argc , char ** argv) { + test_create(); + test_filter_file1(); + test_filter_file2(); +} diff --git a/ThirdParty/Ert/devel/libert_util/tests/test_thread_pool.c b/ThirdParty/Ert/devel/libert_util/tests/test_thread_pool.c new file mode 100644 index 0000000000..d7338a9522 --- /dev/null +++ b/ThirdParty/Ert/devel/libert_util/tests/test_thread_pool.c @@ -0,0 +1,70 @@ +/* + Copyright (C) 2015 Statoil ASA, Norway. + + The file 'test_thread_pool.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> + for more details. +*/ +#include <stdlib.h> +#include <pthread.h> + +#include <ert/util/test_util.h> +#include <ert/util/thread_pool.h> + + +pthread_mutex_t lock; + + +void create_and_destroy() { + int run_size = 10; + thread_pool_type * tp = thread_pool_alloc( run_size , true ); + + thread_pool_join( tp ); + thread_pool_free( tp ); +} + + +void * inc(void * arg) { + int * int_arg = (int *) arg; + pthread_mutex_lock( &lock ); + int_arg[0]++; + pthread_mutex_unlock( &lock ); + return NULL; +} + + +void run() { + int run_size = 10; + int job_size = 1000; + int value = 0; + thread_pool_type * tp = thread_pool_alloc( run_size , true ); + + pthread_mutex_init(&lock , NULL); + for (int i=0; i < job_size; i++) + thread_pool_add_job( tp , inc , &value ); + + thread_pool_join( tp ); + thread_pool_free( tp ); + test_assert_int_equal( job_size , value ); + pthread_mutex_destroy( &lock ); +} + + + + + + +int main( int argc , char ** argv) { + create_and_destroy(); + run(); +} diff --git a/ThirdParty/Ert/devel/libjob_queue/include/ert/job_queue/job_list.h b/ThirdParty/Ert/devel/libjob_queue/include/ert/job_queue/job_list.h new file mode 100644 index 0000000000..9ab6070065 --- /dev/null +++ b/ThirdParty/Ert/devel/libjob_queue/include/ert/job_queue/job_list.h @@ -0,0 +1,53 @@ +/* + Copyright (C) 2015 Statoil ASA, Norway. + + The file 'job_node.h' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> + for more details. +*/ + +#ifndef __JOB_LIST_H__ +#define __JOB_LIST_H__ + + +#ifdef __cplusplus +extern "C" { +#endif + +#include <ert/util/type_macros.h> + +#include <ert/job_queue/queue_driver.h> +#include <ert/job_queue/job_node.h> + + +typedef struct job_list_struct job_list_type; + + job_list_type * job_list_alloc(); + void job_list_free( job_list_type * job_list ); + int job_list_get_size( const job_list_type * job_list ); + void job_list_add_job( job_list_type * job_list , job_queue_node_type * job_node ); + job_queue_node_type * job_list_iget_job( const job_list_type * job_list , int queue_index); + void job_list_reset( job_list_type * job_list ); + void job_list_get_wrlock( job_list_type * list); + void job_list_get_rdlock( job_list_type * list); + void job_list_reader_wait( job_list_type * list, int usleep_time1, int usleep_time2); + void job_list_unlock( job_list_type * list); + + UTIL_SAFE_CAST_HEADER( job_list ); + UTIL_IS_INSTANCE_HEADER( job_list ); + +#ifdef __cplusplus +} +#endif +#endif + diff --git a/ThirdParty/Ert/devel/libjob_queue/include/ert/job_queue/job_node.h b/ThirdParty/Ert/devel/libjob_queue/include/ert/job_queue/job_node.h new file mode 100644 index 0000000000..e41196651c --- /dev/null +++ b/ThirdParty/Ert/devel/libjob_queue/include/ert/job_queue/job_node.h @@ -0,0 +1,115 @@ +/* + Copyright (C) 2015 Statoil ASA, Norway. + + The file 'job_node.h' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> + for more details. +*/ + +#ifndef __JOB_NODE_H__ +#define __JOB_NODE_H__ + + +#ifdef __cplusplus +extern "C" { +#endif + +#include <ert/util/type_macros.h> +#include <ert/job_queue/queue_driver.h> +#include <ert/job_queue/job_queue_status.h> + +/** + This struct holds the job_queue information about one job. Observe + the following: + + 1. This struct is purely static - i.e. it is invisible outside of + this file-scope. + + 2. Typically the driver would like to store some additional + information, i.e. the PID of the running process for the local + driver; that is stored in a (driver specific) struct under the + field job_data. + + 3. If the driver detects that a job has failed it leaves an EXIT + file, the exit status is (currently) not reliably transferred + back to to the job_queue layer. + +*/ + +typedef bool (job_callback_ftype) (void *); +typedef struct job_queue_node_struct job_queue_node_type; + + + bool job_queue_node_status_transition( job_queue_node_type * node , job_queue_status_type * status , job_status_type new_status); + submit_status_type job_queue_node_submit( job_queue_node_type * node , job_queue_status_type * status , queue_driver_type * driver); + void job_queue_node_free_error_info( job_queue_node_type * node ); + void job_queue_node_fscanf_EXIT( job_queue_node_type * node ); + void job_queue_node_clear_error_info(job_queue_node_type * node); + void job_queue_node_clear(job_queue_node_type * node); + void job_queue_node_free_data(job_queue_node_type * node); + job_queue_node_type * job_queue_node_alloc( const char * job_name , + const char * run_path , + const char * run_cmd , + int argc , + const char ** argv , + int num_cpu , + const char * ok_file, + const char * exit_file, + job_callback_ftype * done_callback, + job_callback_ftype * retry_callback, + job_callback_ftype * exit_callback, + void * callback_arg); + + + job_queue_node_type * job_queue_node_alloc_simple( const char * job_name , + const char * run_path , + const char * run_cmd , + int argc , + const char ** argv ); + + bool job_queue_node_kill( job_queue_node_type * node , job_queue_status_type * status , queue_driver_type * driver); + void job_queue_node_free(job_queue_node_type * node); + job_status_type job_queue_node_get_status(const job_queue_node_type * node); + void job_queue_node_free_driver_data( job_queue_node_type * node , queue_driver_type * driver); + void job_queue_node_restart( job_queue_node_type * node , job_queue_status_type * status); + bool job_queue_node_update_status( job_queue_node_type * node , job_queue_status_type * status , queue_driver_type * driver); + + const char * job_queue_node_get_run_path( const job_queue_node_type * node); + const char * job_queue_node_get_name( const job_queue_node_type * node); + int job_queue_node_get_submit_attempt( const job_queue_node_type * node); + void job_queue_node_reset_submit_attempt( job_queue_node_type * node); + const char * job_queue_node_get_failed_job( const job_queue_node_type * node); + const char * job_queue_node_get_error_reason( const job_queue_node_type * node); + const char * job_queue_node_get_stderr_capture( const job_queue_node_type * node); + const char * job_queue_node_get_stderr_file( const job_queue_node_type * node); + + time_t job_queue_node_get_sim_start( const job_queue_node_type * node ); + time_t job_queue_node_get_sim_end( const job_queue_node_type * node ); + time_t job_queue_node_get_submit_time( const job_queue_node_type * node ); + + const char * job_queue_node_get_ok_file( const job_queue_node_type * node); + const char * job_queue_node_get_exit_file( const job_queue_node_type * node); + + bool job_queue_node_run_DONE_callback( job_queue_node_type * node ); + bool job_queue_node_run_RETRY_callback( job_queue_node_type * node ); + void job_queue_node_run_EXIT_callback( job_queue_node_type * node ); + int job_queue_node_get_queue_index( const job_queue_node_type * node ); + void job_queue_node_set_queue_index( job_queue_node_type * node , int queue_index); + + UTIL_IS_INSTANCE_HEADER( job_queue_node ); + UTIL_SAFE_CAST_HEADER( job_queue_node ); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/ThirdParty/Ert/devel/libjob_queue/include/ert/job_queue/job_queue.h b/ThirdParty/Ert/devel/libjob_queue/include/ert/job_queue/job_queue.h index e74eaa770b..94be97734c 100644 --- a/ThirdParty/Ert/devel/libjob_queue/include/ert/job_queue/job_queue.h +++ b/ThirdParty/Ert/devel/libjob_queue/include/ert/job_queue/job_queue.h @@ -27,11 +27,11 @@ extern "C" { #include <ert/util/path_fmt.h> #include <ert/job_queue/queue_driver.h> +#include <ert/job_queue/job_node.h> - typedef bool (job_callback_ftype) (void *); typedef struct job_queue_struct job_queue_type; - typedef struct job_queue_node_struct job_queue_node_type; + void job_queue_submit_complete( job_queue_type * queue ); job_driver_type job_queue_get_driver_type( const job_queue_type * queue ); @@ -42,29 +42,17 @@ extern "C" { job_queue_type * job_queue_alloc( int , const char * ok_file , const char * exit_file); void job_queue_free(job_queue_type *); - int job_queue_add_job_mt(job_queue_type * , - const char * run_cmd , - job_callback_ftype * done_callback, - job_callback_ftype * retry_callback, - job_callback_ftype * exit_callback, - void * callback_arg , - int num_cpu , - const char * , - const char * , - int argc , - const char ** argv ); - - int job_queue_add_job_st(job_queue_type * , - const char * run_cmd , - job_callback_ftype * done_callback, - job_callback_ftype * retry_callback, - job_callback_ftype * exit_callback, - void * callback_arg , - int num_cpu , - const char * , - const char * , - int argc , - const char ** argv ); + int job_queue_add_job(job_queue_type * , + const char * run_cmd , + job_callback_ftype * done_callback, + job_callback_ftype * retry_callback, + job_callback_ftype * exit_callback, + void * callback_arg , + int num_cpu , + const char * , + const char * , + int argc , + const char ** argv ); void job_queue_reset(job_queue_type * queue); void job_queue_run_jobs(job_queue_type * queue, int num_total_run, bool verbose); @@ -72,14 +60,12 @@ extern "C" { void * job_queue_run_jobs__(void * ); void job_queue_start_manager_thread( job_queue_type * job_queue , pthread_t * queue_thread , int job_size , bool verbose); - job_status_type job_queue_iget_job_status(const job_queue_type * , int ); - const char * job_queue_status_name( job_status_type status ); + job_status_type job_queue_iget_job_status(job_queue_type * , int ); int job_queue_iget_status_summary( const job_queue_type * queue , job_status_type status); time_t job_queue_iget_sim_start( job_queue_type * queue, int job_index); time_t job_queue_iget_sim_end( job_queue_type * queue, int job_index); time_t job_queue_iget_submit_time( job_queue_type * queue, int job_index); - job_driver_type job_queue_lookup_driver_name( const char * driver_name ); void job_queue_set_max_job_duration(job_queue_type * queue, int max_duration_seconds); int job_queue_get_max_job_duration(const job_queue_type * queue); @@ -98,20 +84,25 @@ extern "C" { void * job_queue_iget_job_data( job_queue_type * job_queue , int job_nr ); int job_queue_get_active_size( const job_queue_type * queue ); + int job_queue_get_num_callback( const job_queue_type * queue); int job_queue_get_num_running( const job_queue_type * queue); int job_queue_get_num_pending( const job_queue_type * queue); int job_queue_get_num_waiting( const job_queue_type * queue); int job_queue_get_num_complete( const job_queue_type * queue); int job_queue_get_num_failed( const job_queue_type * queue); int job_queue_get_num_killed( const job_queue_type * queue); - const char * job_queue_iget_failed_job( const job_queue_type * queue , int job_index); - const char * job_queue_iget_error_reason( const job_queue_type * queue , int job_index); - const char * job_queue_iget_stderr_capture( const job_queue_type * queue , int job_index); - const char * job_queue_iget_stderr_file( const job_queue_type * queue , int job_index); - const char * job_queue_iget_run_path( const job_queue_type * queue , int job_index); + const char * job_queue_iget_failed_job( job_queue_type * queue , int job_index); + const char * job_queue_iget_error_reason( job_queue_type * queue , int job_index); + const char * job_queue_iget_stderr_capture( job_queue_type * queue , int job_index); + const char * job_queue_iget_stderr_file( job_queue_type * queue , int job_index); + const char * job_queue_iget_run_path( job_queue_type * queue , int job_index); void job_queue_iset_external_restart(job_queue_type * queue , int job_index); job_queue_node_type * job_queue_iget_job( job_queue_type * job_queue , int job_nr ); bool job_queue_has_driver(const job_queue_type * queue ); + job_queue_node_type * job_queue_iget_node(job_queue_type * queue , int job_index); + int job_queue_get_max_running( const job_queue_type * queue ); + + UTIL_SAFE_CAST_HEADER( job_queue ); #ifdef __cplusplus } diff --git a/ThirdParty/Ert/devel/libjob_queue/include/ert/job_queue/job_queue_manager.h b/ThirdParty/Ert/devel/libjob_queue/include/ert/job_queue/job_queue_manager.h index e4bbf8554d..72bd72e292 100644 --- a/ThirdParty/Ert/devel/libjob_queue/include/ert/job_queue/job_queue_manager.h +++ b/ThirdParty/Ert/devel/libjob_queue/include/ert/job_queue/job_queue_manager.h @@ -1,19 +1,19 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'job_queue.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> - for more details. + Copyright (C) 2011 Statoil ASA, Norway. + + The file 'job_queue.h' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> + for more details. */ #ifndef __JOB_QUEUE_MANAGER_H__ @@ -30,12 +30,19 @@ typedef struct job_queue_manager_struct job_queue_manager_type; job_queue_manager_type * job_queue_manager_alloc( job_queue_type * job_queue ); void job_queue_manager_free( job_queue_manager_type * manager ); - void job_queue_manager_start_queue( job_queue_manager_type * manager , int num_total_run , bool verbose); + void job_queue_manager_start_queue( job_queue_manager_type * manager , int num_total_run , bool verbose , bool reset_queue); + bool job_queue_manager_try_wait( job_queue_manager_type * manager , int timeout_seconds); void job_queue_manager_wait( job_queue_manager_type * manager); int job_queue_manager_get_num_running( const job_queue_manager_type * manager); - int job_queue_manager_get_num_complete( const job_queue_manager_type * manager); + int job_queue_manager_get_num_success( const job_queue_manager_type * manager); + int job_queue_manager_get_num_failed( const job_queue_manager_type * manager); bool job_queue_manager_is_running( const job_queue_manager_type * manager); + + bool job_queue_manager_job_success( const job_queue_manager_type * manager , int job_index); bool job_queue_manager_job_complete( const job_queue_manager_type * manager , int job_index); + bool job_queue_manager_job_waiting( const job_queue_manager_type * manager , int job_index); + bool job_queue_manager_job_running( const job_queue_manager_type * manager , int job_index); + bool job_queue_manager_job_failed( const job_queue_manager_type * manager , int job_index); UTIL_IS_INSTANCE_HEADER( job_queue_manager ); diff --git a/ThirdParty/Ert/devel/libjob_queue/include/ert/job_queue/job_queue_status.h b/ThirdParty/Ert/devel/libjob_queue/include/ert/job_queue/job_queue_status.h new file mode 100644 index 0000000000..78684b05cd --- /dev/null +++ b/ThirdParty/Ert/devel/libjob_queue/include/ert/job_queue/job_queue_status.h @@ -0,0 +1,46 @@ +/* + Copyright (C) 2015 Statoil ASA, Norway. + + The file 'job_status_test.h' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> + for more details. +*/ + +#ifndef __JOB_QUEUE_STATUS_H__ +#define __JOB_QUEUE_STATUS_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <ert/util/type_macros.h> +#include <ert/job_queue/queue_driver.h> + + typedef struct job_queue_status_struct job_queue_status_type; + + job_queue_status_type * job_queue_status_alloc(); + void job_queue_status_free( job_queue_status_type * status ); + int job_queue_status_get_count( job_queue_status_type * status , job_status_type status_type); + void job_queue_status_clear( job_queue_status_type * status ); + void job_queue_status_inc( job_queue_status_type * status_count , job_status_type status_type); + bool job_queue_status_transition( job_queue_status_type * status_count , job_status_type src_status , job_status_type target_status); + int job_queue_status_get_total_count( const job_queue_status_type * status ); + const char * job_queue_status_name( job_status_type status ); + + UTIL_IS_INSTANCE_HEADER( job_queue_status ); + UTIL_SAFE_CAST_HEADER( job_queue_status ); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/ThirdParty/Ert/devel/libjob_queue/include/ert/job_queue/queue_driver.h b/ThirdParty/Ert/devel/libjob_queue/include/ert/job_queue/queue_driver.h index d30a917122..c24e130d36 100644 --- a/ThirdParty/Ert/devel/libjob_queue/include/ert/job_queue/queue_driver.h +++ b/ThirdParty/Ert/devel/libjob_queue/include/ert/job_queue/queue_driver.h @@ -103,12 +103,10 @@ extern "C" { */ #define JOB_QUEUE_CAN_KILL (JOB_QUEUE_WAITING + JOB_QUEUE_RUNNING + JOB_QUEUE_PENDING + JOB_QUEUE_SUBMITTED + JOB_QUEUE_USER_EXIT) - - +#define JOB_QUEUE_WAITING_STATUS (JOB_QUEUE_WAITING + JOB_QUEUE_PENDING) #define JOB_QUEUE_CAN_UPDATE_STATUS (JOB_QUEUE_RUNNING + JOB_QUEUE_PENDING + JOB_QUEUE_SUBMITTED) - #define JOB_QUEUE_COMPLETE_STATUS (JOB_QUEUE_USER_EXIT + JOB_QUEUE_SUCCESS + JOB_QUEUE_FAILED) @@ -147,6 +145,13 @@ extern "C" { const char * queue_driver_type_enum_iget(int index, int * value); const char * queue_driver_status_enum_iget(int index, int * value); + typedef enum {SUBMIT_OK = 0 , + SUBMIT_JOB_FAIL = 1 , /* Typically no more attempts. */ + SUBMIT_DRIVER_FAIL = 2 , /* The driver would not take the job - for whatever reason?? */ + SUBMIT_QUEUE_CLOSED = 3 } /* The queue is currently not accepting more jobs - either (temporarilty) + because of pause or it is going down. */ submit_status_type; + + #ifdef __cplusplus } #endif diff --git a/ThirdParty/Ert/devel/libjob_queue/src/CMakeLists.txt b/ThirdParty/Ert/devel/libjob_queue/src/CMakeLists.txt index 6db8d00d34..04b71eef7d 100644 --- a/ThirdParty/Ert/devel/libjob_queue/src/CMakeLists.txt +++ b/ThirdParty/Ert/devel/libjob_queue/src/CMakeLists.txt @@ -1,7 +1,8 @@ #configure_file (${CMAKE_CURRENT_SOURCE_DIR}/CMake/include/libjob_queue_build_config.h.in ${CMAKE_CURRENT_BINARY_DIR}/libjob_queue_build_config.h) -set(source_files forward_model.c queue_driver.c job_queue.c local_driver.c rsh_driver.c torque_driver.c ext_job.c ext_joblist.c workflow_job.c workflow.c workflow_joblist.c job_queue_manager.c) -set(header_files job_queue.h queue_driver.h local_driver.h rsh_driver.h torque_driver.h ext_job.h ext_joblist.h forward_model.h workflow_job.h workflow.h workflow_joblist.h job_queue_manager.h) + +set(source_files job_queue_status.c forward_model.c queue_driver.c job_queue.c job_node.c job_list.c local_driver.c rsh_driver.c torque_driver.c ext_job.c ext_joblist.c workflow_job.c workflow.c workflow_joblist.c job_queue_manager.c) +set(header_files job_queue.h queue_driver.h local_driver.h job_node.h job_list.h rsh_driver.h torque_driver.h ext_job.h ext_joblist.h forward_model.h workflow_job.h workflow.h workflow_joblist.h job_queue_manager.h) set_property(SOURCE rsh_driver.c PROPERTY COMPILE_FLAGS "-Wno-error") list( APPEND source_files lsf_driver.c) diff --git a/ThirdParty/Ert/devel/libjob_queue/src/job_list.c b/ThirdParty/Ert/devel/libjob_queue/src/job_list.c new file mode 100644 index 0000000000..99805cb13d --- /dev/null +++ b/ThirdParty/Ert/devel/libjob_queue/src/job_list.c @@ -0,0 +1,151 @@ +/* + Copyright (C) 2015 Statoil ASA, Norway. + + The file 'job_list.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> + for more details. +*/ + +#define _GNU_SOURCE /* Must define this to get access to pthread_rwlock_t */ +#include <stdbool.h> +#include <string.h> +#include <stdlib.h> +#include <stdio.h> +#include <pthread.h> +#include <unistd.h> + +#include <ert/util/msg.h> +#include <ert/util/util.h> +#include <ert/util/thread_pool.h> +#include <ert/util/arg_pack.h> + +#include <ert/job_queue/job_node.h> +#include <ert/job_queue/job_list.h> + + +#define JOB_LIST_TYPE_ID 8154222 + +struct job_list_struct { + UTIL_TYPE_ID_DECLARATION; + int active_size; + int alloc_size; + job_queue_node_type ** jobs; + pthread_rwlock_t lock; +}; + + +UTIL_IS_INSTANCE_FUNCTION( job_list , JOB_LIST_TYPE_ID ) +UTIL_SAFE_CAST_FUNCTION( job_list , JOB_LIST_TYPE_ID ) + +job_list_type * job_list_alloc() { + job_list_type * job_list = util_malloc( sizeof * job_list ); + UTIL_TYPE_ID_INIT( job_list , JOB_LIST_TYPE_ID ); + job_list->active_size = 0; + job_list->alloc_size = 0; + job_list->jobs = NULL; + pthread_rwlock_init( &job_list->lock , NULL); + return job_list; +} + + +void job_list_reset( job_list_type * job_list ) { + int queue_index; + for (queue_index = 0; queue_index < job_list->active_size; queue_index++) { + job_queue_node_type * node = job_list_iget_job( job_list , queue_index ); + job_queue_node_free( node ); + job_list->jobs[queue_index] = NULL; + } + job_list->active_size = 0; +} + + +int job_list_get_size( const job_list_type * job_list ) { + return job_list->active_size; +} + + +/* + This takes ownership to the job node instance. +*/ +#define QUEUE_DEBUG 1 +void job_list_add_job( job_list_type * job_list , job_queue_node_type * job_node ) { + if (job_list->alloc_size == job_list->active_size) { + +#ifdef QUEUE_DEBUG + int new_alloc_size = job_list->alloc_size + 1; + job_queue_node_type ** new_jobs = util_malloc( sizeof * new_jobs * new_alloc_size ); + memcpy( new_jobs , job_list->jobs , sizeof * new_jobs * job_list->active_size ); + free( job_list->jobs ); + job_list->jobs = new_jobs; +#else + int new_alloc_size = util_int_max( 16 , job_list->alloc_size * 2); + job_list->jobs = util_realloc( job_list->jobs , sizeof * job_list->jobs * new_alloc_size ); +#endif + + job_list->alloc_size = new_alloc_size; + } + + { + int queue_index = job_list_get_size( job_list ); + job_queue_node_set_queue_index(job_node, queue_index ); + job_list->jobs[queue_index] = job_node; + } + job_list->active_size++; + +} + + +job_queue_node_type * job_list_iget_job( const job_list_type * job_list , int queue_index) { + if (queue_index >= 0 && queue_index < job_list->active_size) + return job_list->jobs[queue_index]; + else { + util_abort("%s: invalid queue_index:%d Valid range: [0,%d) \n",__func__ , queue_index , queue_index); + return NULL; + } +} + + +void job_list_free( job_list_type * job_list ) { + if (job_list->alloc_size > 0) { + job_list_reset( job_list ); + free( job_list->jobs ); + } + free( job_list ); +} + + + +void job_list_get_wrlock( job_list_type * list) { + pthread_rwlock_wrlock( &list->lock ); +} + +void job_list_get_rdlock( job_list_type * list) { + pthread_rwlock_rdlock( &list->lock ); +} + + +void job_list_unlock( job_list_type * list) { + pthread_rwlock_unlock( &list->lock ); +} + + +void job_list_reader_wait( job_list_type * list, int usleep_time1, int usleep_time2) { + if (pthread_rwlock_tryrdlock( &list->lock ) == 0) { + // Seems to be no writers waiting - take a short sleep and return. + pthread_rwlock_unlock( &list->lock ); + usleep( usleep_time1 ); + } else + // A writer already has the lock - let more writers get access; sleep longer. + usleep( usleep_time2 ); + +} diff --git a/ThirdParty/Ert/devel/libjob_queue/src/job_node.c b/ThirdParty/Ert/devel/libjob_queue/src/job_node.c new file mode 100644 index 0000000000..94c8f5077a --- /dev/null +++ b/ThirdParty/Ert/devel/libjob_queue/src/job_node.c @@ -0,0 +1,558 @@ +/* + Copyright (C) 2015 Statoil ASA, Norway. + + The file 'job_node.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> + for more details. +*/ + +#define _GNU_SOURCE /* Must define this to get access to pthread_rwlock_t */ +#include <stdbool.h> +#include <string.h> +#include <stdlib.h> +#include <stdio.h> +#include <pthread.h> +#include <unistd.h> + +#include <ert/util/msg.h> +#include <ert/util/util.h> +#include <ert/util/thread_pool.h> +#include <ert/util/arg_pack.h> +#include <ert/util/type_macros.h> + +#include <ert/job_queue/job_node.h> + +#define JOB_QUEUE_NODE_TYPE_ID 3315299 +#define INVALID_QUEUE_INDEX -999 + +struct job_queue_node_struct { + UTIL_TYPE_ID_DECLARATION; + int num_cpu; /* How many cpu's will this job need - the driver is free to ignore if not relevant. */ + char *run_cmd; /* The path to the actual executable. */ + char *exit_file; /* The queue will look for the occurence of this file to detect a failure. */ + char *ok_file; /* The queue will look for this file to verify that the job was OK - can be NULL - in which case it is ignored. */ + char *job_name; /* The name of the job. */ + char *run_path; /* Where the job is run - absolute path. */ + job_callback_ftype *done_callback; + job_callback_ftype *retry_callback; /* To determine if job can be retried */ + job_callback_ftype *exit_callback; /* Callback to perform any cleanup */ + void *callback_arg; + int argc; /* The number of commandline arguments to pass when starting the job. */ + char **argv; /* The commandline arguments. */ + int queue_index; + + /*-----------------------------------------------------------------*/ + char *failed_job; /* Name of the job (in the chain) which has failed. */ + char *error_reason; /* The error message from the failed job. */ + char *stderr_capture; + char *stderr_file; /* Name of the file containing stderr information. */ + /*-----------------------------------------------------------------*/ + + int submit_attempt; /* Which attempt is this ... */ + job_status_type job_status; /* The current status of the job. */ + pthread_mutex_t data_mutex; /* Protecting the access to the job_data pointer. */ + void *job_data; /* Driver specific data about this job - fully handled by the driver. */ + time_t submit_time; /* When was the job added to job_queue - the FIRST TIME. */ + time_t sim_start; /* When did the job change status -> RUNNING - the LAST TIME. */ + time_t sim_end ; /* When did the job finish successfully */ +}; + + + +void job_queue_node_free_error_info( job_queue_node_type * node ) { + util_safe_free(node->error_reason); + util_safe_free(node->stderr_capture); + util_safe_free(node->stderr_file); + util_safe_free(node->failed_job); +} + + + +/* + When the job script has detected failure it will create a "EXIT" + file in the runpath directory; this function will inspect the EXIT + file and determine which job has failed, the reason the job script + has given to fail the job (typically missing TARGET_FILE) and + capture the stderr from the job. + + The file is XML formatted: + + ------------------------------------------------ + <error> + <time>HH:MM:SS</time> + <job> Name of job </job> + <reason> Reason why the job failed </reason> + <stderr> + Capture of stderr from the job, can typically be + a multiline string. + </stderr> + </error> + ------------------------------------------------ + + This format is written by the dump_EXIT_file() function in the + job_dispatch.py script. +*/ + +/* + This extremely half-assed XML "parsing" should of course be kept a + secret... +*/ + +static char * __alloc_tag_content( const char * xml_buffer , const char * tag) { + char * open_tag = util_alloc_sprintf("<%s>" , tag); + char * close_tag = util_alloc_sprintf("</%s>" , tag); + + char * start_ptr = strstr( xml_buffer , open_tag ); + char * end_ptr = strstr( xml_buffer , close_tag ); + char * tag_content = NULL; + + if ((start_ptr != NULL) && (end_ptr != NULL)) { + int length; + start_ptr += strlen(open_tag); + + length = end_ptr - start_ptr; + tag_content = util_alloc_substring_copy( start_ptr , 0 , length ); + } + + free( open_tag ); + free( close_tag ); + return tag_content; +} + + + + +/** + This code is meant to capture which of the jobs has failed; why it + has failed and the stderr stream of the failing job. Depending on + the failure circumstances the EXIT file might not be around. +*/ + +void job_queue_node_fscanf_EXIT( job_queue_node_type * node ) { + job_queue_node_free_error_info( node ); + if (node->exit_file) { + if (util_file_exists( node->exit_file )) { + char * xml_buffer = util_fread_alloc_file_content( node->exit_file, NULL); + + node->failed_job = __alloc_tag_content( xml_buffer , "job" ); + node->error_reason = __alloc_tag_content( xml_buffer , "reason" ); + node->stderr_capture = __alloc_tag_content( xml_buffer , "stderr"); + node->stderr_file = __alloc_tag_content( xml_buffer , "stderr_file"); + + free( xml_buffer ); + } else + node->failed_job = util_alloc_sprintf("EXIT file:%s not found - load failure?" , node->exit_file); + } +} + + + + + + +UTIL_IS_INSTANCE_FUNCTION( job_queue_node , JOB_QUEUE_NODE_TYPE_ID ) +UTIL_SAFE_CAST_FUNCTION( job_queue_node , JOB_QUEUE_NODE_TYPE_ID ) + + + +int job_queue_node_get_queue_index( const job_queue_node_type * node ) { + if (node->queue_index == INVALID_QUEUE_INDEX) + util_abort("%s: internal error: asked for not-yet-initialized node->queue_index\n",__func__); + return node->queue_index; +} + +void job_queue_node_set_queue_index( job_queue_node_type * node , int queue_index) { + if (node->queue_index == INVALID_QUEUE_INDEX) + node->queue_index = queue_index; + else + util_abort("%s: internal error: atteeempt to reset queue_index \n",__func__); +} + + +/* + The error information is retained even after the job has completed + completely, so that calling scope can ask for it - that is the + reason there are separate free() and clear functions for the error related fields. +*/ + +void job_queue_node_free_data(job_queue_node_type * node) { + util_safe_free( node->job_name ); + util_safe_free( node->exit_file ); + util_safe_free( node->ok_file ); + util_safe_free( node->run_cmd ); + util_free_stringlist( node->argv , node->argc ); + + if (node->job_data != NULL) + util_abort("%s: internal error - driver spesific job data has not been freed - will leak.\n",__func__); +} + + +void job_queue_node_free(job_queue_node_type * node) { + job_queue_node_free_data(node); + job_queue_node_free_error_info(node); + util_safe_free(node->run_path); + free(node); +} + + +job_status_type job_queue_node_get_status(const job_queue_node_type * node) { + return node->job_status; +} + + + + + + +/******************************************************************/ +/* + These four functions all require that the caller has aquired the + data lock before entering. +*/ + + + + + +void job_queue_node_reset_submit_attempt( job_queue_node_type * node) { + node->submit_attempt = 0; +} + +int job_queue_node_get_submit_attempt( const job_queue_node_type * node) { + return node->submit_attempt; +} + + + + + + + + + +job_queue_node_type * job_queue_node_alloc_simple( const char * job_name , + const char * run_path , + const char * run_cmd , + int argc , + const char ** argv) { + return job_queue_node_alloc( job_name , run_path , run_cmd , argc , argv , 1, NULL , NULL, NULL, NULL, NULL, NULL); +} + + +job_queue_node_type * job_queue_node_alloc( const char * job_name , + const char * run_path , + const char * run_cmd , + int argc , + const char ** argv, + int num_cpu, + const char * ok_file, + const char * exit_file, + job_callback_ftype * done_callback, + job_callback_ftype * retry_callback, + job_callback_ftype * exit_callback, + void * callback_arg) { + + if (util_is_directory( run_path )) { + job_queue_node_type * node = util_malloc(sizeof * node ); + + UTIL_TYPE_ID_INIT( node , JOB_QUEUE_NODE_TYPE_ID ); + { + /* The data initialized in this block should *NEVER* change. */ + node->job_name = util_alloc_string_copy( job_name ); + + if (util_is_abs_path(run_path)) + node->run_path = util_alloc_string_copy( run_path ); + else + node->run_path = util_alloc_realpath( run_path ); + + node->run_cmd = util_alloc_string_copy( run_cmd ); + node->argc = argc; + node->argv = util_alloc_stringlist_copy( argv , argc ); + node->num_cpu = num_cpu; + + if (ok_file) + node->ok_file = util_alloc_filename(node->run_path , ok_file , NULL); + else + node->ok_file = NULL; + + if (exit_file) + node->exit_file = util_alloc_filename(node->run_path , exit_file , NULL); + else + node->exit_file = NULL; + + node->exit_callback = exit_callback; + node->retry_callback = retry_callback; + node->done_callback = done_callback; + node->callback_arg = callback_arg; + } + { + node->error_reason = NULL; + node->stderr_capture = NULL; + node->stderr_file = NULL; + node->failed_job = NULL; + } + { + node->job_status = JOB_QUEUE_NOT_ACTIVE; + node->queue_index = INVALID_QUEUE_INDEX; + node->submit_attempt = 0; + node->job_data = NULL; /* The allocation is run in single thread mode - we assume. */ + node->sim_start = 0; + node->sim_end = 0; + node->submit_time = time( NULL ); + } + + pthread_mutex_init( &node->data_mutex , NULL ); + return node; + } else + return NULL; +} + + +const char * job_queue_node_get_error_reason( const job_queue_node_type * node) { + return node->error_reason; +} + +const char * job_queue_node_get_stderr_capture( const job_queue_node_type * node) { + return node->stderr_capture; +} + + +const char * job_queue_node_get_stderr_file( const job_queue_node_type * node) { + return node->stderr_file; +} + + +const char * job_queue_node_get_exit_file( const job_queue_node_type * node) { + return node->exit_file; +} + + +const char * job_queue_node_get_ok_file( const job_queue_node_type * node) { + return node->ok_file; +} + + + +const char * job_queue_node_get_run_path( const job_queue_node_type * node) { + return node->run_path; +} + +const char * job_queue_node_get_name( const job_queue_node_type * node) { + return node->job_name; +} + +const char * job_queue_node_get_failed_job( const job_queue_node_type * node) { + return node->failed_job; +} + + +time_t job_queue_node_get_sim_start( const job_queue_node_type * node ) { + return node->sim_start; +} + + +time_t job_queue_node_get_sim_end( const job_queue_node_type * node ) { + return node->sim_end; +} + +time_t job_queue_node_get_submit_time( const job_queue_node_type * node ) { + return node->submit_time; +} + + + +bool job_queue_node_run_DONE_callback( job_queue_node_type * node ) { + bool OK = true; + if (node->done_callback) + OK = node->done_callback( node->callback_arg ); + + return OK; +} + + +bool job_queue_node_run_RETRY_callback( job_queue_node_type * node ) { + bool retry = false; + if (node->retry_callback) + retry = node->retry_callback( node->callback_arg ); + + return retry; +} + + +void job_queue_node_run_EXIT_callback( job_queue_node_type * node ) { + if (node->exit_callback) + node->exit_callback( node->callback_arg ); +} + +static void job_queue_node_set_status(job_queue_node_type * node , job_status_type new_status) { + if (new_status != node->job_status) { + node->job_status = new_status; + + /* + We record sim start when the node is in state JOB_QUEUE_WAITING + to be sure that we do not miss the start time completely for + very fast jobs which are registered in the state + JOB_QUEUE_RUNNING. + */ + if (new_status == JOB_QUEUE_WAITING) + node->sim_start = time( NULL ); + + if (new_status == JOB_QUEUE_RUNNING) + node->sim_start = time( NULL ); + + if (new_status == JOB_QUEUE_SUCCESS) + node->sim_end = time( NULL ); + + if (new_status == JOB_QUEUE_FAILED) + job_queue_node_fscanf_EXIT( node ); + + } +} + + +submit_status_type job_queue_node_submit( job_queue_node_type * node , job_queue_status_type * status , queue_driver_type * driver) { + submit_status_type submit_status; + void * job_data = queue_driver_submit_job( driver, + node->run_cmd, + node->num_cpu, + node->run_path, + node->job_name, + node->argc, + (const char **) node->argv); + pthread_mutex_lock( &node->data_mutex ); + { + if (job_data != NULL) { + job_status_type old_status = node->job_status; + job_status_type new_status = JOB_QUEUE_SUBMITTED; + + node->job_data = job_data; + node->submit_attempt++; + /* + The status JOB_QUEUE_SUBMITTED is internal, and not + exported anywhere. The job_queue_update_status() will + update this to PENDING or RUNNING at the next call. The + important difference between SUBMITTED and WAITING is + that SUBMITTED have job_data != NULL and the + job_queue_node free function must be called on it. + */ + submit_status = SUBMIT_OK; + job_queue_node_set_status( node , new_status); + job_queue_status_transition(status, old_status, new_status); + } else + /* + In this case the status of the job itself will be + unmodified; i.e. it will still be WAITING, and a new attempt + to submit it will be performed in the next round. + */ + submit_status = SUBMIT_DRIVER_FAIL; + } + pthread_mutex_unlock( &node->data_mutex ); + return submit_status; +} + + +bool job_queue_node_update_status( job_queue_node_type * node , job_queue_status_type * status , queue_driver_type * driver) { + bool status_change = false; + pthread_mutex_lock( &node->data_mutex ); + { + if (node->job_data) { + job_status_type current_status = job_queue_node_get_status(node); + if (current_status & JOB_QUEUE_CAN_UPDATE_STATUS) { + job_status_type new_status = queue_driver_get_status( driver , node->job_data); + status_change = job_queue_status_transition(status , current_status , new_status); + job_queue_node_set_status(node,new_status); + } + } + } + pthread_mutex_unlock( &node->data_mutex ); + return status_change; +} + + +bool job_queue_node_status_transition( job_queue_node_type * node , job_queue_status_type * status , job_status_type new_status) { + bool status_change; + pthread_mutex_lock( &node->data_mutex ); + { + job_status_type old_status = job_queue_node_get_status( node ); + status_change = job_queue_status_transition(status , old_status, new_status); + + if (status_change) + job_queue_node_set_status( node , new_status ); + } + pthread_mutex_unlock( &node->data_mutex ); + return status_change; +} + + + +bool job_queue_node_kill( job_queue_node_type * node , job_queue_status_type * status , queue_driver_type * driver) { + bool result = false; + pthread_mutex_lock( &node->data_mutex ); + { + job_status_type current_status = job_queue_node_get_status( node ); + if (current_status & JOB_QUEUE_CAN_KILL) { + /* + Jobs with status JOB_QUEUE_WAITING are killable - in the + sense that status should be set to JOB_QUEUE_USER_KILLED; but + they do not have any driver specific job_data, and the + driver->kill_job() function can NOT be called. + */ + if (current_status != JOB_QUEUE_WAITING) { + queue_driver_kill_job( driver , node->job_data ); + if (node->job_data) { + queue_driver_free_job( driver , node->job_data ); + node->job_data = NULL; + } + } + job_queue_status_transition(status, current_status, JOB_QUEUE_USER_KILLED); + job_queue_node_set_status( node , JOB_QUEUE_USER_KILLED); + result = true; + } + } + pthread_mutex_unlock( &node->data_mutex ); + return result; +} + + +/* + This frees the storage allocated by the driver - the storage + allocated by the queue layer is retained. + + In the case of jobs which are first marked as successfull by the + queue layer, and then subsequently set to status EXIT by the + DONE_callback this function will be called twice; i.e. we must + protect against a double free. +*/ + +void job_queue_node_free_driver_data( job_queue_node_type * node , queue_driver_type * driver) { + pthread_mutex_lock( &node->data_mutex ); + { + if (node->job_data != NULL) + queue_driver_free_job( driver , node->job_data ); + node->job_data = NULL; + } + pthread_mutex_unlock( &node->data_mutex ); +} + + + +void job_queue_node_restart( job_queue_node_type * node , job_queue_status_type * status) { + pthread_mutex_lock( &node->data_mutex ); + { + job_status_type current_status = job_queue_node_get_status( node ); + job_queue_status_transition(status, current_status, JOB_QUEUE_WAITING); + job_queue_node_set_status( node , JOB_QUEUE_WAITING); + job_queue_node_reset_submit_attempt(node); + } + pthread_mutex_unlock( &node->data_mutex ); +} diff --git a/ThirdParty/Ert/devel/libjob_queue/src/job_queue.c b/ThirdParty/Ert/devel/libjob_queue/src/job_queue.c index 78cbce65ff..0ad7df26f6 100644 --- a/ThirdParty/Ert/devel/libjob_queue/src/job_queue.c +++ b/ThirdParty/Ert/devel/libjob_queue/src/job_queue.c @@ -30,13 +30,14 @@ #include <ert/util/arg_pack.h> #include <ert/job_queue/job_queue.h> +#include <ert/job_queue/job_node.h> +#include <ert/job_queue/job_list.h> +#include <ert/job_queue/job_queue_status.h> #include <ert/job_queue/queue_driver.h> - -#define JOB_QUEUE_START_SIZE 16 - /** + The running of external jobs is handled thruogh an abstract job_queue implemented in this file; the job_queue then contains a 'driver' which actually runs the job. All drivers must support the @@ -88,46 +89,6 @@ */ -/* - Threads and such. - ================= - - The job_queue is executed with mulitple threads, and the potential for - thread-related fuckups is immense. There are essentially two different scopes - which acces the internal state of the queue concurrently: - - 1. The function job_queue_run_jobs() is the main function administrating the - queue, this includes starting and stopping jobs, and collecting the - status of the various jobs. The thread running this function is the - default 'owner' of the information in the job_queue instance. - - 2. External scope can: - - o Query the status of the queue / individual jobs. [Read access] - - o Issue commands to make the queue resubmit/kill/wait/... [Write access] - - Observe that there can be maaany concurrent invokations of the second - type. Data structures which can change must obviously be protected with - read/write locking, however scalars are NOT protected, i.e the two code blocks: - - - ... - state = new_value; - ... - - and - - ... - return state; - - can run concurrently. In principle we might risk that the return value from - "return state;" is inconsistent, i.e. different from both new_value and the - value state had prior to the statement "state = new_value;" - however all - tests should be explicit so that such an inconsistency is actually OK. - -*/ - /* Some words about status @@ -224,12 +185,6 @@ -typedef enum {SUBMIT_OK = 0 , - SUBMIT_JOB_FAIL = 1 , /* Typically no more attempts. */ - SUBMIT_DRIVER_FAIL = 2 , /* The driver would not take the job - for whatever reason?? */ - SUBMIT_QUEUE_CLOSED = 3 } /* The queue is currently not accepting more jobs - either (temporarilty) - because of pause or it is going down. */ submit_status_type; - /** @@ -250,437 +205,58 @@ typedef enum {SUBMIT_OK = 0 , */ -struct job_queue_node_struct { - job_status_type job_status; /* The current status of the job. */ - int submit_attempt; /* Which attempt is this ... */ - int num_cpu; /* How many cpu's will this job need - the driver is free to ignore if not relevant. */ - char *run_cmd; /* The path to the actual executable. */ - char *exit_file; /* The queue will look for the occurence of this file to detect a failure. */ - char *ok_file; /* The queue will look for this file to verify that the job was OK - can be NULL - in which case it is ignored. */ - char *job_name; /* The name of the job. */ - char *run_path; /* Where the job is run - absolute path. */ - /*-----------------------------------------------------------------*/ - char *failed_job; /* Name of the job (in the chain) which has failed. */ - char *error_reason; /* The error message from the failed job. */ - char *stderr_capture; - char *stderr_file; /* Name of the file containing stderr information. */ - /*-----------------------------------------------------------------*/ - void *job_data; /* Driver specific data about this job - fully handled by the driver. */ - int argc; /* The number of commandline arguments to pass when starting the job. */ - char **argv; /* The commandline arguments. */ - time_t submit_time; /* When was the job added to job_queue - the FIRST TIME. */ - time_t sim_start; /* When did the job change status -> RUNNING - the LAST TIME. */ - time_t sim_end ; /* When did the job finish successfully */ - pthread_rwlock_t job_lock; /* This lock provides read/write locking of the job_data field. */ - job_callback_ftype *done_callback; - job_callback_ftype *retry_callback; /* To determine if job can be retried */ - job_callback_ftype *exit_callback; /* Callback to perform any cleanup */ - void *callback_arg; -}; - -static const int status_index[] = { JOB_QUEUE_NOT_ACTIVE , // Initial, allocated job state, job not added - controlled by job_queue - JOB_QUEUE_WAITING , // The job is ready to be started - controlled by job_queue - JOB_QUEUE_SUBMITTED , // Job is submitted to driver - temporary state - controlled by job_queue - JOB_QUEUE_PENDING , // Job is pending, before actual execution - controlled by queue_driver - JOB_QUEUE_RUNNING , // Job is executing - controlled by queue_driver - JOB_QUEUE_DONE , // Job is done (sucessful or not), temporary state - controlled/returned by by queue_driver - JOB_QUEUE_EXIT , // Job is done, with exit status != 0, temporary state - controlled/returned by by queue_driver - JOB_QUEUE_USER_EXIT , // User / queue system has requested killing of job - controlled by job_queue / external scope - JOB_QUEUE_USER_KILLED, // Job has been killed, due to JOB_QUEUE_USER_EXIT, FINAL STATE - controlled by job_queue - JOB_QUEUE_SUCCESS , // All good, comes after JOB_QUEUE_DONE, with additional checks, FINAL STATE - controlled by job_queue - JOB_QUEUE_RUNNING_CALLBACK, // Temporary state, while running requested callbacks after an ended job - controlled by job_queue - JOB_QUEUE_FAILED }; // Job has failed, no more retries, FINAL STATE - -static const char* status_name[] = { "JOB_QUEUE_NOT_ACTIVE" , - "JOB_QUEUE_WAITING" , - "JOB_QUEUE_SUBMITTED" , - "JOB_QUEUE_PENDING" , - "JOB_QUEUE_RUNNING" , - "JOB_QUEUE_DONE" , - "JOB_QUEUE_EXIT" , - "JOB_QUEUE_USER_KILLED" , - "JOB_QUEUE_USER_EXIT" , - "JOB_QUEUE_SUCCESS" , - "JOB_QUEUE_RUNNING_CALLBACK", - "JOB_QUEUE_FAILED" }; - - - /*****************************************************************/ - -/** - - This is the struct for a whole queue. Observe the following: - - 1. The number of elements is specified at the allocation time, and - all nodes are allocated then; i.e. when xx_insert_job() is called - from external scope a new node is not actaully created - internally, it is just an existing node which is initialized. - - 2. The queue can start running before all jobs are added. - -*/ +#define JOB_QUEUE_TYPE_ID 665210 struct job_queue_struct { - int active_size; /* The current number of job slots in the queue. */ - int alloc_size; /* The current allocated size of jobs array. */ - int max_submit; /* The maximum number of submit attempts for one job. */ + UTIL_TYPE_ID_DECLARATION; + job_list_type * job_list; + job_queue_status_type * status; char * exit_file; /* The queue will look for the occurence of this file to detect a failure. */ char * ok_file; /* The queue will look for this file to verify that the job was OK - can be NULL - in which case it is ignored. */ - job_queue_node_type ** jobs; /* A vector of job nodes .*/ - queue_driver_type * driver; /* A pointer to a driver instance (LSF|LOCAL|RSH) which actually 'does it'. */ - int status_list[JOB_QUEUE_MAX_STATE]; /* The number of jobs in the different states. */ - int old_status_list[JOB_QUEUE_MAX_STATE]; /* Should the display be updated ?? */ + queue_driver_type * driver; /* A pointer to a driver instance (LSF|LOCAL|RSH) which actually 'does it'. */ + bool open; /* True if the queue has been reset and is ready for use, false if the queue has been used and not reset */ bool user_exit; /* If there comes an external signal to abondond the whole thing user_exit will be set to true, and things start to dwindle down. */ bool running; bool pause_on; bool submit_complete; - bool grow; /* The function adding new jobs is requesting the job_queue function to grow the jobs array. */ + + int max_submit; /* The maximum number of submit attempts for one job. */ int max_ok_wait_time; /* Seconds to wait for an OK file - when the job itself has said all OK. */ int max_duration; /* Maximum allowed time for a job to run, 0 = unlimited */ time_t stop_time; /* A job is only allowed to run until this time. 0 = no time set, ignore stop_time */ unsigned long usleep_time; /* The sleep time before checking for updates. */ - pthread_mutex_t status_mutex; /* This mutex ensure that the status-change code is only run by one thread. */ pthread_mutex_t run_mutex; /* This mutex is used to ensure that ONLY one thread is executing the job_queue_run_jobs(). */ - pthread_mutex_t queue_mutex; thread_pool_type * work_pool; }; -/*****************************************************************/ - -static void job_queue_grow( job_queue_type * queue ); - - - - - -static int STATUS_INDEX( job_status_type status ) { - int index = 0; - - while (true) { - if (status_index[index] == status) - return index; - - index++; - if (index == JOB_QUEUE_MAX_STATE) - util_abort("%s: failed to get index from status:%d \n",__func__ , status); - } -} - -/* - int status_index = 0; - int status = input_status; - while ( (status != 1) && (status_index < JOB_QUEUE_MAX_STATE)) { - status >>= 1; - status_index++; - } - if (status != 1) - util_abort("%s: failed to get index from status:%d \n",__func__ , status); - return status_index; -} -*/ -/*****************************************************************/ -/* - When the job script has detected failure it will create a "EXIT" - file in the runpath directory; this function will inspect the EXIT - file and determine which job has failed, the reason the job script - has given to fail the job (typically missing TARGET_FILE) and - capture the stderr from the job. - - The file is XML formatted: - - ------------------------------------------------ - <error> - <time>HH:MM:SS</time> - <job> Name of job </job> - <reason> Reason why the job failed </reason> - <stderr> - Capture of stderr from the job, can typically be - a multiline string. - </stderr> - </error> - ------------------------------------------------ - - This format is written by the dump_EXIT_file() function in the - job_dispatch.py script. -*/ /* - This extremely half-assed XML "parsing" should of course be kept a - secret... -*/ - -static char * __alloc_tag_content( const char * xml_buffer , const char * tag) { - char * open_tag = util_alloc_sprintf("<%s>" , tag); - char * close_tag = util_alloc_sprintf("</%s>" , tag); - - char * start_ptr = strstr( xml_buffer , open_tag ); - char * end_ptr = strstr( xml_buffer , close_tag ); - char * tag_content = NULL; - - if ((start_ptr != NULL) && (end_ptr != NULL)) { - int length; - start_ptr += strlen(open_tag); - - length = end_ptr - start_ptr; - tag_content = util_alloc_substring_copy( start_ptr , 0 , length ); - } - - free( open_tag ); - free( close_tag ); - return tag_content; -} - - -static void job_queue_node_free_error_info( job_queue_node_type * node ) { - util_safe_free(node->error_reason); - util_safe_free(node->stderr_capture); - util_safe_free(node->stderr_file); - util_safe_free(node->failed_job); -} + Must hold on to: + 1. A write lock for the job node. + 3. A read lock for the job_list - -/** - This code is meant to capture which of the jobs has failed; why it - has failed and the stderr stream of the failing job. Depending on - the failure circumstances the EXIT file might not be around. */ - -static void job_queue_node_fscanf_EXIT( job_queue_node_type * node ) { - job_queue_node_free_error_info( node ); - if (node->exit_file) { - if (util_file_exists( node->exit_file )) { - char * xml_buffer = util_fread_alloc_file_content( node->exit_file, NULL); - - node->failed_job = __alloc_tag_content( xml_buffer , "job" ); - node->error_reason = __alloc_tag_content( xml_buffer , "reason" ); - node->stderr_capture = __alloc_tag_content( xml_buffer , "stderr"); - node->stderr_file = __alloc_tag_content( xml_buffer , "stderr_file"); - - free( xml_buffer ); - } else - node->failed_job = util_alloc_sprintf("EXIT file:%s not found - load failure?" , node->exit_file); - } -} - - - -static void job_queue_node_clear_error_info(job_queue_node_type * node) { - node->failed_job = NULL; - node->error_reason = NULL; - node->stderr_capture = NULL; - node->stderr_file = NULL; - node->run_path = NULL; -} - - - -static void job_queue_node_clear(job_queue_node_type * node) { - node->job_status = JOB_QUEUE_NOT_ACTIVE; - node->submit_attempt = 0; - node->job_name = NULL; - node->job_data = NULL; - node->exit_file = NULL; - node->ok_file = NULL; - node->run_cmd = NULL; - node->argc = 0; - node->argv = NULL; - node->exit_callback = NULL; - node->retry_callback = NULL; - node->done_callback = NULL; - node->callback_arg = NULL; - node->sim_start = 0; - node->sim_end = 0; -} - - -static job_queue_node_type * job_queue_node_alloc( ) { - job_queue_node_type * node = util_malloc(sizeof * node ); - - job_queue_node_clear(node); - job_queue_node_clear_error_info(node); - pthread_rwlock_init( &node->job_lock , NULL); - - return node; -} - - -/* - The error information is retained even after the job has completed - completely, so that calling scope can ask for it - that is the - reason there are separate free() and clear functions for the error related fields. -*/ - -static void job_queue_node_free_data(job_queue_node_type * node) { - util_safe_free( node->job_name ); - util_safe_free( node->exit_file ); - util_safe_free( node->ok_file ); - util_safe_free( node->run_cmd ); - util_free_stringlist( node->argv , node->argc ); - if (node->callback_arg) { - arg_pack_free( node->callback_arg ); - node->callback_arg = NULL; - } - - if (node->job_data != NULL) - util_abort("%s: internal error - driver spesific job data has not been freed - will leak.\n",__func__); -} - - -static void job_queue_node_free(job_queue_node_type * node) { - job_queue_node_free_data(node); - job_queue_node_free_error_info(node); - util_safe_free(node->run_path); - free(node); -} - - -static job_status_type job_queue_node_get_status(const job_queue_node_type * node) { - return node->job_status; +static bool job_queue_change_node_status(job_queue_type * queue , job_queue_node_type * node , job_status_type new_status) { + return job_queue_node_status_transition( node , queue->status , new_status ); } -static void job_queue_node_finalize(job_queue_node_type * node) { - job_queue_node_free_data(node); - job_queue_node_clear(node); -} - - - /*****************************************************************/ -static bool job_queue_change_node_status(job_queue_type * , job_queue_node_type * , job_status_type ); - - -static void job_queue_initialize_node(job_queue_type * queue , - const char * run_cmd , - job_callback_ftype * done_callback, - job_callback_ftype * retry_callback, - job_callback_ftype * exit_callback, - void * callback_arg , - int num_cpu , - const char * run_path , - const char * job_name , - int job_index , - int argc , - const char ** argv) { - - job_queue_node_type * node = queue->jobs[job_index]; - node->submit_attempt = 0; - node->num_cpu = num_cpu; - node->job_name = util_alloc_string_copy( job_name ); - node->job_data = NULL; /* The allocation is run in single thread mode - we assume. */ - node->argc = argc; - node->argv = util_alloc_stringlist_copy( argv , argc ); - - util_safe_free(node->run_path); // Might have a value from previous run. - if (util_is_abs_path(run_path)) - node->run_path = util_alloc_string_copy( run_path ); - else - node->run_path = util_alloc_realpath( run_path ); - - if ( !util_is_directory(node->run_path) ) - util_abort("%s: the run_path: %s does not exist - aborting \n",__func__ , node->run_path); - - if (queue->exit_file != NULL) - node->exit_file = util_alloc_filename(node->run_path , queue->exit_file , NULL); - if (queue->ok_file != NULL) - node->ok_file = util_alloc_filename(node->run_path , queue->ok_file , NULL); - node->run_cmd = util_alloc_string_copy( run_cmd ); - - node->exit_callback = exit_callback; - node->retry_callback = retry_callback; - node->done_callback = done_callback; - node->callback_arg = callback_arg; - node->sim_start = 0; - node->sim_end = 0; - node->submit_time = time( NULL ); - - /* Now the job is ready to be picked by the queue manager. */ - job_queue_change_node_status(queue , node , JOB_QUEUE_WAITING); -} -static void job_queue_assert_queue_index(const job_queue_type * queue , int queue_index) { - if (queue_index < 0 || queue_index >= queue->active_size) - util_abort("%s: invalid queue_index - internal error - aborting \n",__func__); -} - - - -/** - This function WILL be called by several threads concurrently; both - directly from the thread running the job_queue_run_jobs() function, - and indirectly thorugh exported functions like: - - job_queue_set_external_restart(); - job_queue_set_external_fail(); - ... - - It is therefor essential that only one thread is running this code - at time. -*/ - -static bool job_queue_change_node_status(job_queue_type * queue , job_queue_node_type * node , job_status_type new_status) { - bool status_change = false; - pthread_mutex_lock( &queue->status_mutex ); - { - job_status_type old_status = job_queue_node_get_status( node ); - - if (new_status != old_status) { - node->job_status = new_status; - queue->status_list[ STATUS_INDEX(old_status) ]--; - queue->status_list[ STATUS_INDEX(new_status) ]++; - - if (new_status == JOB_QUEUE_RUNNING) - node->sim_start = time( NULL ); - - if (new_status == JOB_QUEUE_SUCCESS) - node->sim_end = time( NULL ); - - status_change = true; - - if (new_status == JOB_QUEUE_FAILED) - job_queue_node_fscanf_EXIT( node ); - } - } - pthread_mutex_unlock( &queue->status_mutex ); - return status_change; -} - - - -/* - This frees the storage allocated by the driver - the storage - allocated by the queue layer is retained. - - In the case of jobs which are first marked as successfull by the - queue layer, and then subsequently set to status EXIT by the - DONE_callback this function will be called twice; i.e. we must - protect against a double free. -*/ - -static void job_queue_free_job_driver_data(job_queue_type * queue , job_queue_node_type * node) { - pthread_rwlock_wrlock( &node->job_lock ); - { - if (node->job_data != NULL) - queue_driver_free_job( queue->driver , node->job_data ); - node->job_data = NULL; - } - pthread_rwlock_unlock( &node->job_lock ); -} - /** @@ -694,82 +270,35 @@ static void job_queue_free_job_driver_data(job_queue_type * queue , job_queue_no */ /* - Will return true if the status has changed since the last time. + Will return true if there is any status change. Must already hold + on to joblist readlock */ static bool job_queue_update_status(job_queue_type * queue ) { bool update = false; - queue_driver_type *driver = queue->driver; int ijob; - - for (ijob = 0; ijob < queue->active_size; ijob++) { - job_queue_node_type * node = queue->jobs[ijob]; - - pthread_rwlock_rdlock( &node->job_lock ); - { - if (node->job_data != NULL) { - job_status_type current_status = job_queue_node_get_status(node); - if (current_status & JOB_QUEUE_CAN_UPDATE_STATUS) { - job_status_type new_status = queue_driver_get_status( driver , node->job_data); - job_queue_change_node_status(queue , node , new_status); - } - } - } - pthread_rwlock_unlock( &node->job_lock ); - } - - /* Has the net status changed? */ - { - int istat; - for (istat = 0; istat < JOB_QUEUE_MAX_STATE; istat++) { - if (queue->old_status_list[istat] != queue->status_list[istat]) - update = true; - queue->old_status_list[istat] = queue->status_list[istat]; - } + for (ijob = 0; ijob < job_list_get_size( queue->job_list ); ijob++) { + job_queue_node_type * node = job_list_iget_job( queue->job_list , ijob ); + bool node_update = job_queue_node_update_status( node , queue->status , queue->driver ); + if (node_update) + update = true; } return update; } - +/* + Must hold on to joblist readlock +*/ static submit_status_type job_queue_submit_job(job_queue_type * queue , int queue_index) { submit_status_type submit_status; if (queue->user_exit || queue->pause_on) submit_status = SUBMIT_QUEUE_CLOSED; /* The queue is currently not accepting more jobs. */ else { - job_queue_assert_queue_index(queue , queue_index); { - job_queue_node_type * node = queue->jobs[queue_index]; - void * job_data = queue_driver_submit_job( queue->driver , - node->run_cmd , - node->num_cpu , - node->run_path , - node->job_name , - node->argc , - (const char **) node->argv ); - - if (job_data != NULL) { - pthread_rwlock_wrlock( &node->job_lock ); - { - node->job_data = job_data; - node->submit_attempt++; - job_queue_change_node_status(queue , node , JOB_QUEUE_SUBMITTED ); - submit_status = SUBMIT_OK; - /* - The status JOB_QUEUE_SUBMITTED is internal, and not exported anywhere. The job_queue_update_status() will - update this to PENDING or RUNNING at the next call. The important difference between SUBMITTED and WAITING - is that SUBMITTED have job_data != NULL and the job_queue_node free function must be called on it. - */ - } - pthread_rwlock_unlock( &node->job_lock ); - } else - /* - In this case the status of the job itself will be - unmodified; i.e. it will still be WAITING, and a new attempt - to submit it will be performed in the next round. - */ - submit_status = SUBMIT_DRIVER_FAIL; + job_queue_node_type * node = job_list_iget_job( queue->job_list , queue_index ); + submit_status = job_queue_node_submit( node , queue->status , queue->driver ); } } return submit_status; @@ -780,42 +309,6 @@ static submit_status_type job_queue_submit_job(job_queue_type * queue , int queu -const char * job_queue_iget_run_path( const job_queue_type * queue , int job_index) { - job_queue_node_type * node = queue->jobs[job_index]; - return node->run_path; -} - - -const char * job_queue_iget_failed_job( const job_queue_type * queue , int job_index) { - job_queue_node_type * node = queue->jobs[job_index]; - return node->failed_job; -} - - -const char * job_queue_iget_error_reason( const job_queue_type * queue , int job_index) { - job_queue_node_type * node = queue->jobs[job_index]; - return node->error_reason; -} - - -const char * job_queue_iget_stderr_capture( const job_queue_type * queue , int job_index) { - job_queue_node_type * node = queue->jobs[job_index]; - return node->stderr_capture; -} - - -const char * job_queue_iget_stderr_file( const job_queue_type * queue , int job_index) { - job_queue_node_type * node = queue->jobs[job_index]; - return node->stderr_file; -} - - - - -job_status_type job_queue_iget_job_status(const job_queue_type * queue , int job_index) { - job_queue_node_type * node = queue->jobs[job_index]; - return node->job_status; -} @@ -836,9 +329,12 @@ job_status_type job_queue_iget_job_status(const job_queue_type * queue , int job */ int job_queue_iget_status_summary( const job_queue_type * queue , job_status_type status) { - return queue->status_list[ STATUS_INDEX( status ) ]; + return job_queue_status_get_count(queue->status, status); } +int job_queue_get_num_callback( const job_queue_type * queue) { + return job_queue_iget_status_summary( queue , JOB_QUEUE_RUNNING_CALLBACK ); +} int job_queue_get_num_running( const job_queue_type * queue) { return job_queue_iget_status_summary( queue , JOB_QUEUE_RUNNING ); @@ -865,7 +361,7 @@ int job_queue_get_num_killed( const job_queue_type * queue) { } int job_queue_get_active_size( const job_queue_type * queue ) { - return queue->active_size; + return job_list_get_size( queue->job_list ); } void job_queue_set_max_job_duration(job_queue_type * queue, int max_duration_seconds) { @@ -887,10 +383,11 @@ time_t job_queue_get_job_stop_time(const job_queue_type * queue) { void job_queue_set_auto_job_stop_time(job_queue_type * queue) { time_t sum_run_time_succeded_jobs = 0; int num_succeded_jobs = 0; - for (int i = 0; i < queue->active_size; ++i) { - if (JOB_QUEUE_SUCCESS == job_queue_iget_job_status(queue,i)) { + + for (int i = 0; i < job_list_get_size( queue->job_list ); i++) { + if (job_queue_iget_job_status(queue,i) == JOB_QUEUE_SUCCESS) { sum_run_time_succeded_jobs += difftime(job_queue_iget_sim_end(queue, i), job_queue_iget_sim_start(queue, i)); - ++num_succeded_jobs; + num_succeded_jobs++; } } @@ -918,38 +415,100 @@ void job_queue_set_auto_job_stop_time(job_queue_type * queue) { meaningfully killed; that is because these jobs have not yet been submitted to the queue system, and there is not yet established a mapping between external id and queue_index. + + Must hold on to joblist:read lock. */ -bool job_queue_kill_job_node( job_queue_type * queue , job_queue_node_type * node) { - bool result = false; - pthread_rwlock_wrlock( &node->job_lock ); - { - if (node->job_status & JOB_QUEUE_CAN_KILL) { - queue_driver_type * driver = queue->driver; - /* - Jobs with status JOB_QUEUE_WAITING are killable - in the sense that status should be set to - JOB_QUEUE_USER_KILLED; but they do not have any driver specific job_data, and the driver->kill_job() function - can NOT be called. - */ - if (node->job_status != JOB_QUEUE_WAITING) { - queue_driver_kill_job( driver , node->job_data ); - queue_driver_free_job( driver , node->job_data ); - node->job_data = NULL; - } - job_queue_change_node_status( queue , node , JOB_QUEUE_USER_KILLED ); - result = true; - } - } - pthread_rwlock_unlock( &node->job_lock ); +static bool job_queue_kill_job_node( job_queue_type * queue , job_queue_node_type * node) { + bool result = job_queue_node_kill( node , queue->status , queue->driver ); return result; } +#define ASSIGN_LOCKED_ATTRIBUTE( var , func , ...) \ +job_list_get_rdlock( queue->job_list ); \ +{ \ + job_queue_node_type * node = job_list_iget_job( queue->job_list , job_index ); \ + var = func(__VA_ARGS__); \ +} \ +job_list_unlock( queue->job_list ); + + + bool job_queue_kill_job( job_queue_type * queue , int job_index) { - job_queue_node_type * node = queue->jobs[job_index]; - return job_queue_kill_job_node(queue, node); + bool result; + ASSIGN_LOCKED_ATTRIBUTE( result , job_queue_kill_job_node , queue , node); + return result; +} + + +time_t job_queue_iget_sim_start( job_queue_type * queue, int job_index) { + time_t sim_start; + ASSIGN_LOCKED_ATTRIBUTE( sim_start , job_queue_node_get_sim_start , node ); + return sim_start; +} + + +time_t job_queue_iget_sim_end( job_queue_type * queue, int job_index) { + time_t sim_end; + ASSIGN_LOCKED_ATTRIBUTE( sim_end , job_queue_node_get_sim_end , node ); + return sim_end; +} + + +time_t job_queue_iget_submit_time( job_queue_type * queue, int job_index) { + time_t submit_time; + ASSIGN_LOCKED_ATTRIBUTE( submit_time , job_queue_node_get_submit_time , node ); + return submit_time; +} + +const char * job_queue_iget_run_path( job_queue_type * queue , int job_index) { + const char * run_path; + ASSIGN_LOCKED_ATTRIBUTE(run_path, job_queue_node_get_run_path, node ); + return run_path; +} + + +const char * job_queue_iget_failed_job( job_queue_type * queue , int job_index) { + const char * failed_job; + ASSIGN_LOCKED_ATTRIBUTE(failed_job, job_queue_node_get_failed_job, node ); + return failed_job; +} + + +const char * job_queue_iget_error_reason( job_queue_type * queue , int job_index) { + const char * error_reason; + ASSIGN_LOCKED_ATTRIBUTE(error_reason, job_queue_node_get_error_reason, node ); + return error_reason; +} + + +const char * job_queue_iget_stderr_capture( job_queue_type * queue , int job_index) { + const char * stderr_capture; + ASSIGN_LOCKED_ATTRIBUTE(stderr_capture, job_queue_node_get_stderr_capture, node ); + return stderr_capture; +} + + +const char * job_queue_iget_stderr_file( job_queue_type * queue , int job_index) { + const char * stderr_file; + ASSIGN_LOCKED_ATTRIBUTE(stderr_file, job_queue_node_get_stderr_file, node ); + return stderr_file; +} + + + +job_status_type job_queue_iget_job_status( job_queue_type * queue , int job_index) { + job_status_type job_status; + ASSIGN_LOCKED_ATTRIBUTE(job_status, job_queue_node_get_status , node ); + return job_status; } + + + + + /** The external scope asks the queue to restart the the job; we reset the submit counter to zero. This function should typically be used @@ -958,9 +517,12 @@ bool job_queue_kill_job( job_queue_type * queue , int job_index) { */ void job_queue_iset_external_restart(job_queue_type * queue , int job_index) { - job_queue_node_type * node = queue->jobs[job_index]; - node->submit_attempt = 0; - job_queue_change_node_status( queue , node , JOB_QUEUE_WAITING ); + job_list_get_rdlock( queue->job_list ); + { + job_queue_node_type * node = job_list_iget_job( queue->job_list , job_index ); + job_queue_node_restart(node,queue->status); + } + job_list_unlock( queue->job_list ); } @@ -980,26 +542,16 @@ void job_queue_iset_external_restart(job_queue_type * queue , int job_index) { */ void job_queue_iset_external_fail(job_queue_type * queue , int job_index) { - job_queue_node_type * node = queue->jobs[job_index]; - job_queue_change_node_status( queue , node , JOB_QUEUE_EXIT); + job_list_get_rdlock( queue->job_list ); + { + job_queue_node_type * node = job_list_iget_job( queue->job_list , job_index ); + job_queue_node_status_transition(node,queue->status,JOB_QUEUE_EXIT); + } + job_list_unlock( queue->job_list ); } -time_t job_queue_iget_sim_start( job_queue_type * queue, int job_index) { - job_queue_node_type * node = queue->jobs[job_index]; - return node->sim_start; -} - -time_t job_queue_iget_sim_end( job_queue_type * queue, int job_index) { - job_queue_node_type * node = queue->jobs[job_index]; - return node->sim_end; -} - -time_t job_queue_iget_submit_time( job_queue_type * queue, int job_index) { - job_queue_node_type * node = queue->jobs[job_index]; - return node->submit_time; -} @@ -1013,25 +565,28 @@ static void job_queue_update_spinner( int * phase ) { } -static void job_queue_print_summary(const job_queue_type *queue, bool status_change ) { +static void job_queue_print_summary(job_queue_type *queue, bool status_change ) { const char * status_fmt = "Waiting: %3d Pending: %3d Running: %3d Checking/Loading: %3d Failed: %3d Complete: %3d [ ]\b\b"; int string_length = 105; if (status_change) { for (int i=0; i < string_length; i++) printf("\b"); + { - int waiting = queue->status_list[ STATUS_INDEX(JOB_QUEUE_WAITING) ]; - int pending = queue->status_list[ STATUS_INDEX(JOB_QUEUE_PENDING) ]; + int waiting = job_queue_status_get_count( queue->status , JOB_QUEUE_WAITING ); + int pending = job_queue_status_get_count( queue->status , JOB_QUEUE_PENDING ); /* EXIT and DONE are included in "xxx_running", because the target file has not yet been checked. */ - int running = queue->status_list[ STATUS_INDEX(JOB_QUEUE_RUNNING) ] + queue->status_list[ STATUS_INDEX(JOB_QUEUE_DONE) ] + queue->status_list[ STATUS_INDEX(JOB_QUEUE_EXIT) ]; - int complete = queue->status_list[ STATUS_INDEX(JOB_QUEUE_SUCCESS) ]; - int failed = queue->status_list[ STATUS_INDEX(JOB_QUEUE_FAILED) ]; - int loading = queue->status_list[ STATUS_INDEX(JOB_QUEUE_RUNNING_CALLBACK) ]; + int running = job_queue_status_get_count( queue->status , JOB_QUEUE_RUNNING ) + + job_queue_status_get_count( queue->status , JOB_QUEUE_DONE ) + + job_queue_status_get_count( queue->status , JOB_QUEUE_EXIT ); + int complete = job_queue_status_get_count( queue->status , JOB_QUEUE_SUCCESS ); + int failed = job_queue_status_get_count( queue->status , JOB_QUEUE_FAILED ); + int loading = job_queue_status_get_count( queue->status , JOB_QUEUE_RUNNING_CALLBACK ); printf(status_fmt , waiting , pending , running , loading , failed , complete); } @@ -1042,39 +597,26 @@ static void job_queue_print_summary(const job_queue_type *queue, bool status_cha - -static void job_queue_clear_status( job_queue_type * queue ) { - for (int i=0; i < JOB_QUEUE_MAX_STATE; i++) { - queue->status_list[i] = 0; - queue->old_status_list[i] = 0; - } -} - - /** This function goes through all the nodes and call finalize on - them. hat about jobs which were NOT in a CAN_KILL state when the + them. What about jobs which were NOT in a CAN_KILL state when the killing was done, i.e. jobs which are in one of the intermediate load like states?? They */ void job_queue_reset(job_queue_type * queue) { - int i; - - for (i=0; i < queue->active_size; i++) - job_queue_node_finalize(queue->jobs[i]); - - job_queue_clear_status( queue ); + job_list_get_wrlock( queue->job_list ); + job_list_reset( queue->job_list ); + job_list_unlock( queue->job_list ); + job_queue_status_clear(queue->status); /* Be ready for the next run */ - queue->grow = false; queue->submit_complete = false; queue->pause_on = false; queue->user_exit = false; queue->open = true; - queue->active_size = 0; queue->stop_time = 0; } @@ -1086,24 +628,27 @@ bool job_queue_is_running( const job_queue_type * queue ) { static void job_queue_user_exit__( job_queue_type * queue ) { int queue_index; - for (queue_index = 0; queue_index < queue->active_size; queue_index++) { - job_queue_change_node_status( queue , queue->jobs[queue_index] , JOB_QUEUE_USER_EXIT); + for (queue_index = 0; queue_index < job_list_get_size( queue->job_list ); queue_index++) { + job_queue_node_type * node = job_list_iget_job( queue->job_list , queue_index ); + job_queue_node_status_transition(node,queue->status,JOB_QUEUE_USER_EXIT); } } static bool job_queue_check_node_status_files( const job_queue_type * job_queue , job_queue_node_type * node) { - if ((node->exit_file != NULL) && util_file_exists(node->exit_file)) + const char * exit_file = job_queue_node_get_exit_file( node ); + if ((exit_file != NULL) && util_file_exists(exit_file)) return false; /* It has failed. */ else { - if (node->ok_file == NULL) + const char * ok_file = job_queue_node_get_ok_file( node ); + if (ok_file == NULL) return true; /* If the ok-file has not been set we just return true immediately. */ else { int ok_sleep_time = 1; /* Time to wait between checks for OK|EXIT file. */ int total_wait_time = 0; while (true) { - if (util_file_exists( node->ok_file )) { + if (util_file_exists( ok_file )) { return true; break; } else { @@ -1123,27 +668,26 @@ static bool job_queue_check_node_status_files( const job_queue_type * job_queue static void * job_queue_run_DONE_callback( void * arg ) { - job_queue_type * job_queue; - job_queue_node_type * node; - { - arg_pack_type * arg_pack = arg_pack_safe_cast( arg ); - job_queue = arg_pack_iget_ptr( arg_pack , 0 ); - node = arg_pack_iget_ptr( arg_pack , 1 ); - arg_pack_free( arg_pack ); - } - job_queue_free_job_driver_data( job_queue , node ); + arg_pack_type * arg_pack = arg_pack_safe_cast( arg ); + job_queue_type * job_queue = arg_pack_iget_ptr( arg_pack , 0 ); + int queue_index = arg_pack_iget_int( arg_pack , 1 ); + job_list_get_rdlock( job_queue->job_list ); { + job_queue_node_type * node = job_list_iget_job( job_queue->job_list , queue_index ); bool OK = job_queue_check_node_status_files( job_queue , node ); if (OK) - if (node->done_callback != NULL) - OK = node->done_callback( node->callback_arg ); + OK = job_queue_node_run_DONE_callback( node ); if (OK) job_queue_change_node_status( job_queue , node , JOB_QUEUE_SUCCESS ); else job_queue_change_node_status( job_queue , node , JOB_QUEUE_EXIT ); + + job_queue_node_free_driver_data( node , job_queue->driver ); } + job_list_unlock(job_queue->job_list ); + arg_pack_free( arg_pack ); return NULL; } @@ -1153,75 +697,76 @@ static void job_queue_handle_DONE( job_queue_type * queue , job_queue_node_type { arg_pack_type * arg_pack = arg_pack_alloc(); arg_pack_append_ptr( arg_pack , queue ); - arg_pack_append_ptr( arg_pack , node ); + arg_pack_append_int( arg_pack , job_queue_node_get_queue_index(node)); thread_pool_add_job( queue->work_pool , job_queue_run_DONE_callback , arg_pack ); } } static void * job_queue_run_EXIT_callback( void * arg ) { - job_queue_type * job_queue; - job_queue_node_type * node; - { - arg_pack_type * arg_pack = arg_pack_safe_cast( arg ); - job_queue = arg_pack_iget_ptr( arg_pack , 0 ); - node = arg_pack_iget_ptr( arg_pack , 1 ); - arg_pack_free( arg_pack ); - } - job_queue_free_job_driver_data( job_queue , node ); - - if (node->submit_attempt < job_queue->max_submit) - job_queue_change_node_status( job_queue , node , JOB_QUEUE_WAITING ); /* The job will be picked up for antother go. */ - else { - bool retry = false; - - if (node->retry_callback != NULL) - retry = node->retry_callback( node->callback_arg ); + arg_pack_type * arg_pack = arg_pack_safe_cast( arg ); + job_queue_type * job_queue = arg_pack_iget_ptr( arg_pack , 0 ); + int queue_index = arg_pack_iget_int( arg_pack , 1 ); - if (retry) { - /* OK - we have invoked the retry_callback() - and that has returned true; - giving this job a brand new start. */ - node->submit_attempt = 0; - job_queue_change_node_status(job_queue , node , JOB_QUEUE_WAITING); - } else { - // It's time to call it a day + job_list_get_rdlock( job_queue->job_list ); + { + job_queue_node_type * node = job_list_iget_job( job_queue->job_list , queue_index ); - if (node->exit_callback != NULL) - node->exit_callback( node->callback_arg ); - job_queue_change_node_status(job_queue , node , JOB_QUEUE_FAILED); + if (job_queue_node_get_submit_attempt( node ) < job_queue->max_submit) + job_queue_change_node_status( job_queue , node , JOB_QUEUE_WAITING ); /* The job will be picked up for antother go. */ + else { + bool retry = job_queue_node_run_RETRY_callback( node ); + + if (retry) { + /* OK - we have invoked the retry_callback() - and that has returned true; + giving this job a brand new start. */ + job_queue_node_reset_submit_attempt( node ); + job_queue_change_node_status(job_queue , node , JOB_QUEUE_WAITING); + } else { + // It's time to call it a day + + job_queue_node_run_EXIT_callback( node ); + job_queue_change_node_status(job_queue , node , JOB_QUEUE_FAILED); + } } + job_queue_node_free_driver_data( node , job_queue->driver ); } + job_list_unlock(job_queue->job_list ); + arg_pack_free( arg_pack ); + return NULL; } static void * job_queue_run_USER_EXIT_callback( void * arg ) { - job_queue_type * job_queue; - job_queue_node_type * node; - { - arg_pack_type * arg_pack = arg_pack_safe_cast( arg ); - job_queue = arg_pack_iget_ptr( arg_pack , 0 ); - node = arg_pack_iget_ptr( arg_pack , 1 ); - arg_pack_free( arg_pack ); - } - job_queue_free_job_driver_data( job_queue , node ); + arg_pack_type * arg_pack = arg_pack_safe_cast( arg ); + job_queue_type * job_queue = arg_pack_iget_ptr( arg_pack , 0 ); + int queue_index = arg_pack_iget_int( arg_pack , 1 ); - // It's time to call it a day - if (node->exit_callback != NULL) - node->exit_callback( node->callback_arg ); + job_list_get_rdlock( job_queue->job_list ); + { + job_queue_node_type * node = job_list_iget_job( job_queue->job_list , queue_index ); + job_queue_node_free_driver_data( node , job_queue->driver ); - job_queue_change_node_status(job_queue, node, JOB_QUEUE_USER_KILLED); + // It's time to call it a day + job_queue_node_run_EXIT_callback( node ); + job_queue_change_node_status(job_queue, node, JOB_QUEUE_USER_KILLED); + } + job_list_unlock(job_queue->job_list ); + arg_pack_free( arg_pack ); return NULL; } + + + static void job_queue_handle_USER_EXIT( job_queue_type * queue , job_queue_node_type * node) { - // TODO: Right place for this? job_queue_kill_job_node(queue, node); job_queue_change_node_status(queue , node , JOB_QUEUE_RUNNING_CALLBACK ); { arg_pack_type * arg_pack = arg_pack_alloc(); arg_pack_append_ptr( arg_pack , queue ); - arg_pack_append_ptr( arg_pack , node ); + arg_pack_append_int( arg_pack , job_queue_node_get_queue_index(node)); thread_pool_add_job( queue->work_pool , job_queue_run_USER_EXIT_callback , arg_pack ); } } @@ -1231,57 +776,12 @@ static void job_queue_handle_EXIT( job_queue_type * queue , job_queue_node_type { arg_pack_type * arg_pack = arg_pack_alloc(); arg_pack_append_ptr( arg_pack , queue ); - arg_pack_append_ptr( arg_pack , node ); + arg_pack_append_int( arg_pack , job_queue_node_get_queue_index(node)); thread_pool_add_job( queue->work_pool , job_queue_run_EXIT_callback , arg_pack ); } } -/*****************************************************************/ - -int job_queue_get_max_running_option(queue_driver_type * driver) { - char * max_running_string = (char*)queue_driver_get_option(driver, MAX_RUNNING); - int max_running; - if (!util_sscanf_int(max_running_string, &max_running)) { - fprintf(stderr, "%s: Unable to parse option MAX_RUNNING with value %s to an int", __func__, max_running_string); - } - return max_running; -} - -void job_queue_set_max_running_option(queue_driver_type * driver, int max_running) { - char * max_running_string = util_alloc_sprintf("%d", max_running); - queue_driver_set_option(driver, MAX_RUNNING, max_running_string); - free(max_running_string); -} - - -/** - Observe that if the max number of running jobs is decreased, - nothing will be done to reduce the number of jobs currently - running; but no more jobs will be submitted until the number of - running has fallen below the new limit. - - The updated value will also be pushed down to the current driver. - - NOTE: These next three *max_running functions should not be used, rather - use the set_option feature, with MAX_RUNNING. They are (maybe) used by python - therefore not removed. -*/ -int job_queue_get_max_running( const job_queue_type * queue ) { - return job_queue_get_max_running_option(queue->driver); -} - -void job_queue_set_max_running( job_queue_type * queue , int max_running ) { - job_queue_set_max_running_option(queue->driver, max_running); -} - -/* - The return value is the new value for max_running. -*/ -int job_queue_inc_max_runnning( job_queue_type * queue, int delta ) { - job_queue_set_max_running( queue , job_queue_get_max_running( queue ) + delta ); - return job_queue_get_max_running( queue ); -} /*****************************************************************/ @@ -1289,21 +789,19 @@ static void job_queue_check_expired(job_queue_type * queue) { if ((job_queue_get_max_job_duration(queue) <= 0) && (job_queue_get_job_stop_time(queue) <= 0)) return; - for (int i = 0; i < queue->active_size; i++) { - job_queue_node_type * node = queue->jobs[i]; + for (int i = 0; i < job_list_get_size( queue->job_list ); i++) { + job_queue_node_type * node = job_list_iget_job( queue->job_list , i ); if (job_queue_node_get_status(node) == JOB_QUEUE_RUNNING) { time_t now = time(NULL); if ( job_queue_get_max_job_duration(queue) > 0) { - double elapsed = difftime(now, node->sim_start); - if (elapsed > job_queue_get_max_job_duration(queue)) { + double elapsed = difftime(now, job_queue_node_get_sim_start( node )); + if (elapsed > job_queue_get_max_job_duration(queue)) job_queue_change_node_status(queue, node, JOB_QUEUE_USER_EXIT); - } } if (job_queue_get_job_stop_time(queue) > 0) { - if (now >= job_queue_get_job_stop_time(queue)) { + if (now >= job_queue_get_job_stop_time(queue)) job_queue_change_node_status(queue, node, JOB_QUEUE_USER_EXIT); - } } } } @@ -1322,6 +820,18 @@ void job_queue_check_open(job_queue_type* queue) { If the total number of jobs is not known in advance the job_queue_run_jobs function can be called with @num_total_run == 0. In that case it is paramount to call the function job_queue_submit_complete() whan all jobs have been submitted. + + Observe that this function is assumed to have ~exclusive access to + the jobs array; meaning that: + + 1. The jobs array is read without taking a reader lock. + + 2. Other functions accessing the jobs array concurrently must + take a read lock. + + 3. This function should be the *only* function modifying + the jobs array, and that is done *with* the write lock. + */ void job_queue_run_jobs(job_queue_type * queue , int num_total_run, bool verbose) { @@ -1344,6 +854,7 @@ void job_queue_run_jobs(job_queue_type * queue , int num_total_run, bool verbose do { bool local_user_exit = false; + job_list_get_rdlock( queue->job_list ); /*****************************************************************/ if (queue->user_exit) {/* An external thread has called the job_queue_user_exit() function, and we should kill all jobs, do some clearing up and go home. Observe that we will go through the @@ -1365,9 +876,9 @@ void job_queue_run_jobs(job_queue_type * queue , int num_total_run, bool verbose { - int num_complete = queue->status_list[ STATUS_INDEX(JOB_QUEUE_SUCCESS) ] + - queue->status_list[ STATUS_INDEX(JOB_QUEUE_FAILED) ] + - queue->status_list[ STATUS_INDEX(JOB_QUEUE_USER_KILLED) ]; + int num_complete = job_queue_status_get_count(queue->status, JOB_QUEUE_SUCCESS) + + job_queue_status_get_count(queue->status, JOB_QUEUE_FAILED) + + job_queue_status_get_count(queue->status, JOB_QUEUE_USER_KILLED); if ((num_total_run > 0) && (num_total_run == num_complete)) /* The number of jobs completed is equal to the number @@ -1386,7 +897,7 @@ void job_queue_run_jobs(job_queue_type * queue , int num_total_run, bool verbose 2. The user has used job_queue_complete_submit() to signal that no more jobs will be forthcoming. */ - if ((num_complete == queue->active_size) && queue->submit_complete) + if ((num_complete == job_list_get_size( queue->job_list )) && queue->submit_complete) cont = false; } } @@ -1396,7 +907,7 @@ void job_queue_run_jobs(job_queue_type * queue , int num_total_run, bool verbose /* Submitting new jobs */ int max_submit = 5; /* This is the maximum number of jobs submitted in one while() { ... } below. Only to ensure that the waiting time before a status update is not too long. */ - int total_active = queue->status_list[ STATUS_INDEX(JOB_QUEUE_PENDING) ] + queue->status_list[ STATUS_INDEX(JOB_QUEUE_RUNNING) ]; + int total_active = job_queue_status_get_count(queue->status, JOB_QUEUE_PENDING) + job_queue_status_get_count(queue->status, JOB_QUEUE_RUNNING); int num_submit_new; { @@ -1408,20 +919,20 @@ void job_queue_run_jobs(job_queue_type * queue , int num_total_run, bool verbose If max_running == 0 that should be interpreted as no limit; i.e. the queue layer will attempt to send an unlimited number of jobs to the driver - the driver can reject the jobs. */ - num_submit_new = util_int_min( max_submit , queue->status_list[ STATUS_INDEX( JOB_QUEUE_WAITING )]); + num_submit_new = util_int_min( max_submit , job_queue_status_get_count(queue->status, JOB_QUEUE_WAITING)); } new_jobs = false; - if (queue->status_list[ STATUS_INDEX(JOB_QUEUE_WAITING) ] > 0) /* We have waiting jobs at all */ - if (num_submit_new > 0) /* The queue can allow more running jobs */ + if (job_queue_status_get_count(queue->status, JOB_QUEUE_WAITING) > 0) /* We have waiting jobs at all */ + if (num_submit_new > 0) /* The queue can allow more running jobs */ new_jobs = true; if (new_jobs) { int submit_count = 0; int queue_index = 0; - while ((queue_index < queue->active_size) && (num_submit_new > 0)) { - job_queue_node_type * node = queue->jobs[queue_index]; + while ((queue_index < job_list_get_size( queue->job_list )) && (num_submit_new > 0)) { + job_queue_node_type * node = job_list_iget_job( queue->job_list , queue_index ); if (job_queue_node_get_status(node) == JOB_QUEUE_WAITING) { { submit_status_type submit_status = job_queue_submit_job(queue , queue_index); @@ -1443,8 +954,8 @@ void job_queue_run_jobs(job_queue_type * queue , int num_total_run, bool verbose Checking for complete / exited / overtime jobs */ int queue_index; - for (queue_index = 0; queue_index < queue->active_size; queue_index++) { - job_queue_node_type * node = queue->jobs[queue_index]; + for (queue_index = 0; queue_index < job_list_get_size( queue->job_list ); queue_index++) { + job_queue_node_type * node = job_list_iget_job( queue->job_list , queue_index ); switch (job_queue_node_get_status(node)) { case(JOB_QUEUE_DONE): @@ -1463,22 +974,18 @@ void job_queue_run_jobs(job_queue_type * queue , int num_total_run, bool verbose } } - - if (local_user_exit) - cont = false; /* This is how we signal that we want to get out . */ - - if (queue->grow) - /* - The add_job function has signaled that it needs more - job slots. We must grow the jobs array. - */ - job_queue_grow( queue ); - else - if (!new_jobs && cont) - util_usleep(queue->usleep_time); - } + } else + /* print an updated status to stdout before exiting. */ + if (verbose) + job_queue_print_summary(queue , true); + } + job_list_unlock( queue->job_list ); + if (local_user_exit) + cont = false; /* This is how we signal that we want to get out . */ + else { + util_yield(); + job_list_reader_wait( queue->job_list , queue->usleep_time , 8 * queue->usleep_time); } - } while ( cont ); queue->running = false; } @@ -1489,29 +996,18 @@ void job_queue_run_jobs(job_queue_type * queue , int num_total_run, bool verbose } /* - Set the queue's "open" flag to false to signal that the queue is not ready to be used in a - new job_queue_run_jobs or job_queue_add_job method call as it has not been reset yet. Not - resetting the queue here implies that the queue object is still available for queries after - this method has finished - */ - + Set the queue's "open" flag to false to signal that the queue is + not ready to be used in a new job_queue_run_jobs or + job_queue_add_job method call as it has not been reset yet. Not + resetting the queue here implies that the queue object is still + available for queries after this method has finished + */ queue->open = false; - - pthread_mutex_unlock( &queue->run_mutex ); } -/* - An external thread sets the user_exit flag to true, then subsequently the - thread managing the queue will see this, and close down the queue. -*/ - -void job_queue_user_exit( job_queue_type * queue) { - queue->user_exit = true; -} - void * job_queue_run_jobs__(void * __arg_pack) { @@ -1532,7 +1028,6 @@ void job_queue_start_manager_thread( job_queue_type * job_queue , pthread_t * qu arg_pack_append_ptr(queue_args , job_queue); arg_pack_append_int(queue_args , job_size); arg_pack_append_bool(queue_args , verbose); - job_queue_reset(job_queue); /* The running status of the job is set to true here; this is to @@ -1550,7 +1045,7 @@ void job_queue_start_manager_thread( job_queue_type * job_queue , pthread_t * qu The most flexible use scenario is as follows: 1. The job_queue_run_jobs() is run by one thread. - 2. Jobs are added asyncronously with job_queue_add_job_mt() from othread threads(s). + 2. Jobs are added asyncronously with job_queue_add_job() from othread threads(s). Unfortunately it does not work properly (i.e. Ctrl-C breaks) to use a Python @@ -1584,126 +1079,98 @@ void job_queue_run_jobs_threaded(job_queue_type * queue , int num_total_run, boo submitted proper to one of the drivers (when a slot is ready). When submitted the job will get (driver specific) job_data != NULL and status SUBMITTED. - - The internal data structure jobs will grow as needed when new jobs - are added. Exactly how this growth takes place is regulated by the - @mt parameter, and is very important to get right: - - mt == true: This means that we are running in multi threaded - mode, and in particular another thread is already running the - job_queue_run_jobs() function. In this case the - job_queue_add_job__() function will only signal that it needs - to grow the jobs array with the grow flag, and then block - until the job_queue_run_jobs() function actually expands the - array. - - mt == false: There is no other thread running the - job_queue_run_jobs() function and it is safe for the - job_queue_add_job__() function to manipulate the jobs array - itself. - - Other thread running job_queue_run_jobs() | mt == true | Result - --------------------------------------------------------------------------- - Yes | Yes | OK - Yes | No | Crash and burn - No | Yes | Deadlock - No | No | OK - --------------------------------------------------------------------------- */ -static int job_queue_add_job__(job_queue_type * queue , - const char * run_cmd , - job_callback_ftype * done_callback, - job_callback_ftype * retry_callback, - job_callback_ftype * exit_callback, - void * callback_arg , - int num_cpu , - const char * run_path , - const char * job_name , - int argc , - const char ** argv, - bool mt) { +int job_queue_add_job(job_queue_type * queue , + const char * run_cmd , + job_callback_ftype * done_callback, + job_callback_ftype * retry_callback, + job_callback_ftype * exit_callback, + void * callback_arg , + int num_cpu , + const char * run_path , + const char * job_name , + int argc , + const char ** argv) { //Fail hard if queue is not open job_queue_check_open(queue); - if (!queue->user_exit) {/* We do not accept new jobs if a user-shutdown has been iniated. */ - int job_index; // This should be better protected lockwise - - pthread_mutex_lock( &queue->queue_mutex ); - { - if (queue->active_size == queue->alloc_size) { - if (mt) { - queue->grow = true; /* Signal to the thread running the queue that we need more job slots. - Wait for the queue_size to increase; this will off course deadlock hard - unless another thread is ready to pick up the signal to grow. */ - while (queue->active_size == queue->alloc_size) { - sleep( 1 ); - } - } else - /* - The function is called in single threaded mode, and we - are certain that is safe for this thread to manipulate - the jobs array directly. - */ - job_queue_grow( queue ); + int queue_index; + job_queue_node_type * node = job_queue_node_alloc( job_name , + run_path , + run_cmd , + argc , + argv , + num_cpu , + queue->ok_file , + queue->exit_file, + done_callback , + retry_callback , + exit_callback , + callback_arg ); + if (node) { + job_list_get_wrlock( queue->job_list ); + { + job_list_add_job( queue->job_list , node ); + queue_index = job_queue_node_get_queue_index(node); + job_queue_change_node_status(queue , node , JOB_QUEUE_WAITING); } - - job_index = queue->active_size; - queue->active_size++; + job_list_unlock( queue->job_list ); + return queue_index; /* Handle used by the calling scope. */ + } else { + char * cwd = util_alloc_cwd(); + util_abort("%s: failed to create job %s in path: %s cwd:%s \n",__func__ , job_name , run_path , cwd); + return -1; } - pthread_mutex_unlock( &queue->queue_mutex ); - - job_queue_initialize_node(queue , run_cmd , done_callback , retry_callback , exit_callback, callback_arg , num_cpu , run_path , job_name , job_index , argc , argv); - return job_index; /* Handle used by the calling scope. */ } else return -1; } -/** - Adding a new job in multi-threaded mode, i.e. another thread is - running the job_queue_run_jobs() function. -*/ -int job_queue_add_job_mt(job_queue_type * queue , - const char * run_cmd , - job_callback_ftype * done_callback, - job_callback_ftype * retry_callback, - job_callback_ftype * exit_callback, - void * callback_arg , - int num_cpu , - const char * run_path , - const char * job_name , - int argc , - const char ** argv) { - return job_queue_add_job__(queue , run_cmd , done_callback, retry_callback, exit_callback , callback_arg , num_cpu , run_path , job_name , argc , argv , true); -} +UTIL_SAFE_CAST_FUNCTION( job_queue , JOB_QUEUE_TYPE_ID) /** - Adding a new job in single-threaded mode, i.e. no another thread is - accessing the queue. + Observe that the job_queue returned by this function is NOT ready + for use; a driver must be set explicitly with a call to + job_queue_set_driver() first. */ -int job_queue_add_job_st(job_queue_type * queue , - const char * run_cmd , - job_callback_ftype * done_callback, - job_callback_ftype * retry_callback, - job_callback_ftype * exit_callback, - void * callback_arg , - int num_cpu , - const char * run_path , - const char * job_name , - int argc , - const char ** argv) { - return job_queue_add_job__(queue , run_cmd , done_callback , retry_callback, exit_callback , callback_arg , num_cpu , run_path , job_name , argc , argv , false); -} +job_queue_type * job_queue_alloc(int max_submit , + const char * ok_file , + const char * exit_file ) { + job_queue_type * queue = util_malloc(sizeof * queue ); + UTIL_TYPE_ID_INIT( queue , JOB_QUEUE_TYPE_ID); + queue->usleep_time = 250000; /* 1000000 : 1 second */ + queue->max_ok_wait_time = 60; + queue->max_duration = 0; + queue->stop_time = 0; + queue->max_submit = max_submit; + queue->driver = NULL; + queue->ok_file = util_alloc_string_copy( ok_file ); + queue->exit_file = util_alloc_string_copy( exit_file ); + queue->open = true; + queue->user_exit = false; + queue->pause_on = false; + queue->running = false; + queue->submit_complete = false; + queue->work_pool = NULL; + queue->job_list = job_list_alloc( ); + queue->status = job_queue_status_alloc( ); + + pthread_mutex_init( &queue->run_mutex , NULL ); + + return queue; +} + + /** When the job_queue_run_jobs() has been called with @total_num_jobs == 0 that means that the total number of jobs to run is not known @@ -1738,23 +1205,6 @@ bool job_queue_has_driver(const job_queue_type * queue ) { } -job_driver_type job_queue_lookup_driver_name( const char * driver_name ) { - if (strcmp( driver_name , "LOCAL") == 0) - return LOCAL_DRIVER; - else if (strcmp( driver_name , "RSH") == 0) - return RSH_DRIVER; - else if (strcmp( driver_name , "LSF") == 0) - return LSF_DRIVER; - else { - util_abort("%s: driver:%s not recognized \n",__func__ , driver_name); - return NULL_DRIVER; - } -} - -/*****************************************************************/ - - - void job_queue_set_max_submit( job_queue_type * job_queue , int max_submit ) { job_queue->max_submit = max_submit; } @@ -1765,85 +1215,11 @@ int job_queue_get_max_submit(const job_queue_type * job_queue ) { } - -static void job_queue_grow( job_queue_type * queue ) { - int alloc_size = util_int_max( 2 * queue->alloc_size , JOB_QUEUE_START_SIZE ); - job_queue_node_type ** new_jobs = util_calloc(alloc_size , sizeof * queue->jobs ); - job_queue_node_type ** old_jobs = queue->jobs; - if (old_jobs != NULL) - memcpy( new_jobs , queue->jobs , queue->alloc_size * sizeof * queue->jobs ); - - - { - int i; - /* Creating the new nodes. */ - for (i = queue->alloc_size; i < alloc_size; i++) - new_jobs[i] = job_queue_node_alloc(); - - /* Assigning the job pointer to the new array. */ - queue->jobs = new_jobs; - - /* Free the old array - only the pointers, not the actual nodes! */ - util_safe_free( old_jobs ); - - /* Update the status with the new nodes. */ - for (i=queue->alloc_size; i < alloc_size; i++) - queue->status_list[ STATUS_INDEX(job_queue_node_get_status(queue->jobs[i])) ]++; - - queue->alloc_size = alloc_size; - } - queue->grow = false; -} - - -/** - Observe that the job_queue returned by this function is NOT ready - for use; a driver must be set explicitly with a call to - job_queue_set_driver() first. -*/ - -job_queue_type * job_queue_alloc(int max_submit , - const char * ok_file , - const char * exit_file ) { - - - - job_queue_type * queue = util_malloc(sizeof * queue ); - queue->jobs = NULL; - queue->usleep_time = 250000; /* 1000000 : 1 second */ - queue->max_ok_wait_time = 60; - queue->max_duration = 0; - queue->stop_time = 0; - queue->max_submit = max_submit; - queue->driver = NULL; - queue->ok_file = util_alloc_string_copy( ok_file ); - queue->exit_file = util_alloc_string_copy( exit_file ); - queue->open = true; - queue->user_exit = false; - queue->pause_on = false; - queue->running = false; - queue->grow = false; - queue->submit_complete = false; - queue->active_size = 0; - queue->alloc_size = 0; - queue->jobs = NULL; - queue->work_pool = NULL; - job_queue_grow( queue ); - - job_queue_clear_status( queue ); - pthread_mutex_init( &queue->status_mutex , NULL); - pthread_mutex_init( &queue->queue_mutex , NULL); - pthread_mutex_init( &queue->run_mutex , NULL ); - - return queue; -} - /** Returns true if the queue is currently paused, which means that no more jobs are submitted. */ - bool job_queue_get_pause( const job_queue_type * job_queue ) { return job_queue->pause_on; } @@ -1858,16 +1234,13 @@ void job_queue_set_pause_off( job_queue_type * job_queue) { job_queue->pause_on = false; } +/* + An external thread sets the user_exit flag to true, then subsequently the + thread managing the queue will see this, and close down the queue. +*/ -void * job_queue_iget_job_data( job_queue_type * job_queue , int job_nr ) { - job_queue_node_type * job = job_queue->jobs[ job_nr ]; - return job->job_data; -} - - -job_queue_node_type * job_queue_iget_job( job_queue_type * job_queue , int job_nr ) { - job_queue_node_type * job = job_queue->jobs[ job_nr ]; - return job; +void job_queue_user_exit( job_queue_type * queue) { + queue->user_exit = true; } @@ -1875,28 +1248,59 @@ job_queue_node_type * job_queue_iget_job( job_queue_type * job_queue , int job_n void job_queue_free(job_queue_type * queue) { util_safe_free( queue->ok_file ); util_safe_free( queue->exit_file ); - { - int i; - for (i=0; i < queue->alloc_size; i++) - job_queue_node_free(queue->jobs[i]); - - free(queue->jobs); - } + job_list_free( queue->job_list ); + job_queue_status_free( queue->status ); free(queue); - queue = NULL; } -/*****************************************************************/ -const char * job_queue_status_name( job_status_type status ) { - return status_name[ STATUS_INDEX(status) ]; + + + +int job_queue_get_max_running_option(queue_driver_type * driver) { + char * max_running_string = (char*)queue_driver_get_option(driver, MAX_RUNNING); + int max_running; + if (!util_sscanf_int(max_running_string, &max_running)) { + fprintf(stderr, "%s: Unable to parse option MAX_RUNNING with value %s to an int", __func__, max_running_string); + } + return max_running; } -/*****************************************************************/ +void job_queue_set_max_running_option(queue_driver_type * driver, int max_running) { + char * max_running_string = util_alloc_sprintf("%d", max_running); + queue_driver_set_option(driver, MAX_RUNNING, max_running_string); + free(max_running_string); +} + + +/** + Observe that if the max number of running jobs is decreased, + nothing will be done to reduce the number of jobs currently + running; but no more jobs will be submitted until the number of + running has fallen below the new limit. + + The updated value will also be pushed down to the current driver. + + NOTE: These next three *max_running functions should not be used, rather + use the set_option feature, with MAX_RUNNING. They are (maybe) used by python + therefore not removed. +*/ +int job_queue_get_max_running( const job_queue_type * queue ) { + return job_queue_get_max_running_option(queue->driver); +} -job_status_type job_queue_get_status( queue_driver_type * driver , job_queue_node_type * job) { - return queue_driver_get_status( driver , job->job_data ); +void job_queue_set_max_running( job_queue_type * queue , int max_running ) { + job_queue_set_max_running_option(queue->driver, max_running); } +/* + The return value is the new value for max_running. +*/ +int job_queue_inc_max_runnning( job_queue_type * queue, int delta ) { + job_queue_set_max_running( queue , job_queue_get_max_running( queue ) + delta ); + return job_queue_get_max_running( queue ); +} + + diff --git a/ThirdParty/Ert/devel/libjob_queue/src/job_queue_manager.c b/ThirdParty/Ert/devel/libjob_queue/src/job_queue_manager.c index c9140c2ed0..4890a21df6 100644 --- a/ThirdParty/Ert/devel/libjob_queue/src/job_queue_manager.c +++ b/ThirdParty/Ert/devel/libjob_queue/src/job_queue_manager.c @@ -1,19 +1,19 @@ /* - Copyright (C) 2014 Statoil ASA, Norway. - - The file 'job_queue_manager.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> - for more details. + Copyright (C) 2014 Statoil ASA, Norway. + + The file 'job_queue_manager.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> + for more details. */ #define _GNU_SOURCE /* Must define this to get access to pthread_rwlock_t */ @@ -21,6 +21,7 @@ #include <string.h> #include <stdlib.h> #include <stdio.h> +#include <signal.h> #include <pthread.h> #include <unistd.h> @@ -57,14 +58,52 @@ void job_queue_manager_free( job_queue_manager_type * manager) { } -void job_queue_manager_start_queue( job_queue_manager_type * manager , int num_total_run , bool verbose) { +void job_queue_manager_start_queue( job_queue_manager_type * manager , int num_total_run , bool verbose , bool reset_queue) { + if (reset_queue) + job_queue_reset( manager->job_queue ); + job_queue_start_manager_thread( manager->job_queue , &manager->queue_thread , num_total_run , verbose ); } void job_queue_manager_wait( job_queue_manager_type * manager) { - pthread_join( manager->queue_thread , NULL ); + pthread_join( manager->queue_thread , NULL ); +} + + +bool job_queue_manager_try_wait( job_queue_manager_type * manager , int timeout_seconds) { + struct timespec ts; + time_t timeout_time = time( NULL ); + + util_inplace_forward_seconds(&timeout_time , timeout_seconds ); + ts.tv_sec = timeout_time; + ts.tv_nsec = 0; + +#ifdef HAVE_TIMEDJOIN + { + int join_return = pthread_timedjoin_np( manager->queue_thread , NULL , &ts); /* Wait for the main thread to complete. */ + if (join_return == 0) + return true; + else + return false; + } +#else + while(true) { + if (pthread_kill(manager->queue_thread, 0) == 0){ + util_yield(); + } else { + return true; + } + + time_t now = time(NULL); + + if(util_difftime_seconds(now, timeout_time) <= 0) { + return false; + } + } + +#endif } @@ -78,10 +117,15 @@ int job_queue_manager_get_num_running( const job_queue_manager_type * manager) { } -int job_queue_manager_get_num_complete( const job_queue_manager_type * manager) { +int job_queue_manager_get_num_success( const job_queue_manager_type * manager) { return job_queue_get_num_complete( manager->job_queue ); } +int job_queue_manager_get_num_failed( const job_queue_manager_type * manager) { + return job_queue_get_num_failed( manager->job_queue ); +} + + bool job_queue_manager_job_complete( const job_queue_manager_type * manager , int job_index) { job_status_type status = job_queue_iget_job_status( manager->job_queue , job_index ); @@ -90,3 +134,38 @@ bool job_queue_manager_job_complete( const job_queue_manager_type * manager , in else return false; } + + +bool job_queue_manager_job_waiting( const job_queue_manager_type * manager , int job_index) { + job_status_type status = job_queue_iget_job_status( manager->job_queue , job_index ); + if (status & JOB_QUEUE_WAITING_STATUS) + return true; + else + return false; +} + +bool job_queue_manager_job_running( const job_queue_manager_type * manager , int job_index) { + job_status_type status = job_queue_iget_job_status( manager->job_queue , job_index ); + if (status == JOB_QUEUE_RUNNING) + return true; + else + return false; +} + + +bool job_queue_manager_job_failed( const job_queue_manager_type * manager , int job_index) { + job_status_type status = job_queue_iget_job_status( manager->job_queue , job_index ); + if (status == JOB_QUEUE_FAILED) + return true; + else + return false; +} + + +bool job_queue_manager_job_success( const job_queue_manager_type * manager , int job_index) { + job_status_type status = job_queue_iget_job_status( manager->job_queue , job_index ); + if (status == JOB_QUEUE_SUCCESS) + return true; + else + return false; +} diff --git a/ThirdParty/Ert/devel/libjob_queue/src/job_queue_status.c b/ThirdParty/Ert/devel/libjob_queue/src/job_queue_status.c new file mode 100644 index 0000000000..7c54dab0ce --- /dev/null +++ b/ThirdParty/Ert/devel/libjob_queue/src/job_queue_status.c @@ -0,0 +1,161 @@ +/* + Copyright (C) 2015 Statoil ASA, Norway. + + The file 'job_status_test.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> + for more details. +*/ +#include <pthread.h> + +#include <ert/util/type_macros.h> +#include <ert/util/util.h> + +#include <ert/job_queue/queue_driver.h> +#include <ert/job_queue/job_queue_status.h> + +#define JOB_QUEUE_STATUS_TYPE_ID 777620306 + +struct job_queue_status_struct { + UTIL_TYPE_ID_DECLARATION; + int status_list[JOB_QUEUE_MAX_STATE]; + pthread_mutex_t update_mutex; +}; + +static const int status_index[] = { JOB_QUEUE_NOT_ACTIVE , // Initial, allocated job state, job not added - controlled by job_queue + JOB_QUEUE_WAITING , // The job is ready to be started - controlled by job_queue + JOB_QUEUE_SUBMITTED , // Job is submitted to driver - temporary state - controlled by job_queue + JOB_QUEUE_PENDING , // Job is pending, before actual execution - controlled by queue_driver + JOB_QUEUE_RUNNING , // Job is executing - controlled by queue_driver + JOB_QUEUE_DONE , // Job is done (sucessful or not), temporary state - controlled/returned by by queue_driver + JOB_QUEUE_EXIT , // Job is done, with exit status != 0, temporary state - controlled/returned by by queue_driver + JOB_QUEUE_USER_EXIT , // User / queue system has requested killing of job - controlled by job_queue / external scope + JOB_QUEUE_USER_KILLED, // Job has been killed, due to JOB_QUEUE_USER_EXIT, FINAL STATE - controlled by job_queue + JOB_QUEUE_SUCCESS , // All good, comes after JOB_QUEUE_DONE, with additional checks, FINAL STATE - controlled by job_queue + JOB_QUEUE_RUNNING_CALLBACK, // Temporary state, while running requested callbacks after an ended job - controlled by job_queue + JOB_QUEUE_FAILED }; // Job has failed, no more retries, FINAL STATE + +static const char* status_name[] = { "JOB_QUEUE_NOT_ACTIVE" , + "JOB_QUEUE_WAITING" , + "JOB_QUEUE_SUBMITTED" , + "JOB_QUEUE_PENDING" , + "JOB_QUEUE_RUNNING" , + "JOB_QUEUE_DONE" , + "JOB_QUEUE_EXIT" , + "JOB_QUEUE_USER_KILLED" , + "JOB_QUEUE_USER_EXIT" , + "JOB_QUEUE_SUCCESS" , + "JOB_QUEUE_RUNNING_CALLBACK", + "JOB_QUEUE_FAILED" }; + +static int STATUS_INDEX( job_status_type status ) { + int index = 0; + + while (true) { + if (status_index[index] == status) + return index; + + index++; + if (index == JOB_QUEUE_MAX_STATE) + util_abort("%s: failed to get index from status:%d \n",__func__ , status); + } +} + + +UTIL_IS_INSTANCE_FUNCTION( job_queue_status , JOB_QUEUE_STATUS_TYPE_ID ) +UTIL_SAFE_CAST_FUNCTION( job_queue_status , JOB_QUEUE_STATUS_TYPE_ID ) + + +job_queue_status_type * job_queue_status_alloc() { + job_queue_status_type * status = util_malloc( sizeof * status ); + UTIL_TYPE_ID_INIT( status , JOB_QUEUE_STATUS_TYPE_ID ); + pthread_mutex_init( &status->update_mutex , NULL ); + job_queue_status_clear( status ); + return status; +} + + +void job_queue_status_free( job_queue_status_type * status ) { + free( status ); +} + + +void job_queue_status_clear( job_queue_status_type * status ) { + int index; + for (index = 0; index < JOB_QUEUE_MAX_STATE; index++) + status->status_list[ index ] = 0; +} + + +int job_queue_status_get_count( job_queue_status_type * status_count , job_status_type status_type) { + int index = STATUS_INDEX( status_type ); + int count; + + count = status_count->status_list[index]; + + return count; +} + + +void job_queue_status_inc( job_queue_status_type * status_count , job_status_type status_type) { + int index = STATUS_INDEX( status_type ); + + pthread_mutex_lock( &status_count->update_mutex ); + { + int count = status_count->status_list[index]; + status_count->status_list[index] = count + 1; + } + pthread_mutex_unlock( &status_count->update_mutex ); +} + + +static void job_queue_status_dec( job_queue_status_type * status_count , job_status_type status_type) { + int index = STATUS_INDEX( status_type ); + + pthread_mutex_lock( &status_count->update_mutex ); + { + int count = status_count->status_list[index]; + status_count->status_list[index] = count - 1; + } + pthread_mutex_unlock( &status_count->update_mutex ); +} + + +/* + The important point is that each individual ++ and -- operation is + atomic, if the different status counts do not add upp perfectly at + all times that is ok. +*/ + + +bool job_queue_status_transition( job_queue_status_type * status_count , job_status_type src_status , job_status_type target_status) { + if (src_status != target_status) { + job_queue_status_dec( status_count , src_status ); + job_queue_status_inc( status_count , target_status ); + return true; + } else + return false; +} + + +int job_queue_status_get_total_count( const job_queue_status_type * status ) { + int total_count = 0; + for (int index = 0; index < JOB_QUEUE_MAX_STATE; index++) + total_count += status->status_list[ index ]; + return total_count; +} + + +const char * job_queue_status_name( job_status_type status ) { + int index = STATUS_INDEX( status ); + return status_name[index]; +} diff --git a/ThirdParty/Ert/devel/libjob_queue/src/lsf_driver.c b/ThirdParty/Ert/devel/libjob_queue/src/lsf_driver.c index 94813f684a..137e02a842 100644 --- a/ThirdParty/Ert/devel/libjob_queue/src/lsf_driver.c +++ b/ThirdParty/Ert/devel/libjob_queue/src/lsf_driver.c @@ -21,6 +21,7 @@ #include <string.h> #include <pthread.h> #include <dlfcn.h> +#include <unistd.h> #include <ert/util/util.h> #include <ert/util/hash.h> @@ -348,12 +349,11 @@ static int lsf_driver_submit_internal_job( lsf_driver_type * driver , char * command; { buffer_type * command_buffer = buffer_alloc( 256 ); - buffer_fwrite_char_ptr( command_buffer , submit_cmd ); + buffer_strcat( command_buffer , submit_cmd ); for (int iarg = 0; iarg < argc; iarg++) { - buffer_fwrite_char( command_buffer , ' '); - buffer_fwrite_char_ptr( command_buffer , argv[ iarg ]); + buffer_strcat( command_buffer , " "); + buffer_strcat( command_buffer , argv[ iarg ]); } - buffer_terminate_char_ptr( command_buffer ); command = buffer_get_data( command_buffer ); buffer_free_container( command_buffer ); } diff --git a/ThirdParty/Ert/devel/libjob_queue/src/rsh_driver.c b/ThirdParty/Ert/devel/libjob_queue/src/rsh_driver.c index b1726f1ecf..38e0237320 100644 --- a/ThirdParty/Ert/devel/libjob_queue/src/rsh_driver.c +++ b/ThirdParty/Ert/devel/libjob_queue/src/rsh_driver.c @@ -341,7 +341,7 @@ void rsh_driver_free__(void * __driver) { } -void rsh_driver_set_host_list( rsh_driver_type * rsh_driver , hash_type * rsh_host_list) { +void rsh_driver_set_host_list( rsh_driver_type * rsh_driver , const hash_type * rsh_host_list) { rsh_driver_clear_host_list( rsh_driver ); if (rsh_host_list != NULL) { hash_iter_type * hash_iter = hash_iter_alloc( rsh_host_list ); @@ -429,7 +429,7 @@ bool rsh_driver_set_option( void * __driver , const char * option_key , const vo rsh_driver_add_host_from_string( driver , value ); else if (strcmp(RSH_HOSTLIST , option_key) == 0) { /* Set full host list - value should be hash of integers. */ if (value != NULL) { - hash_type * hash_value = hash_safe_cast( value ); + const hash_type * hash_value = hash_safe_cast_const( value ); rsh_driver_set_host_list( driver , hash_value ); } } else if (strcmp( RSH_CLEAR_HOSTLIST , option_key) == 0) diff --git a/ThirdParty/Ert/devel/libjob_queue/tests/CMakeLists.txt b/ThirdParty/Ert/devel/libjob_queue/tests/CMakeLists.txt index c3d06dd340..e97c5a7a5c 100644 --- a/ThirdParty/Ert/devel/libjob_queue/tests/CMakeLists.txt +++ b/ThirdParty/Ert/devel/libjob_queue/tests/CMakeLists.txt @@ -1,17 +1,25 @@ +add_executable( job_status_test job_status_test.c ) add_executable( job_loadOK job_loadOK.c ) add_executable( job_loadFail job_loadFail.c ) +add_executable( job_node_test job_node_test.c ) +add_executable( job_list_test job_list_test.c ) add_executable( create_file create_file.c ) add_executable( job_workflow_test job_workflow_test.c ) add_executable( job_lsf_parse_bsub_stdout job_lsf_parse_bsub_stdout.c ) add_executable( ext_joblist_test ext_joblist_test.c ) + +target_link_libraries( job_status_test job_queue test_util ) target_link_libraries( job_workflow_test job_queue test_util ) target_link_libraries( create_file job_queue test_util ) target_link_libraries( job_loadOK job_queue test_util ) target_link_libraries( job_loadFail job_queue test_util ) target_link_libraries( ext_joblist_test job_queue test_util ) target_link_libraries( job_lsf_parse_bsub_stdout job_queue test_util) +target_link_libraries( job_node_test job_queue test_util) +target_link_libraries( job_list_test job_queue test_util) +add_test( job_status_test ${EXECUTABLE_OUTPUT_PATH}/job_status_test) add_test( job_lsf_parse_bsub_stdout ${EXECUTABLE_OUTPUT_PATH}/job_lsf_parse_bsub_stdout ) add_test( job_workflow_test ${EXECUTABLE_OUTPUT_PATH}/job_workflow_test ${EXECUTABLE_OUTPUT_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/data/internal_job) @@ -24,7 +32,8 @@ add_test( job_loadFail1 ${EXECUTABLE_OUTPUT_PATH}/job_loadFail ${CMAKE_CURRENT_S add_test( job_loadFail2 ${EXECUTABLE_OUTPUT_PATH}/job_loadFail ${CMAKE_CURRENT_SOURCE_DIR}/data/externalFail) add_test( job_loadFail3 ${EXECUTABLE_OUTPUT_PATH}/job_loadFail ${CMAKE_CURRENT_SOURCE_DIR}/data/internalFail ${CMAKE_CURRENT_SOURCE_DIR}/data/externalFail) - +add_test( job_node_test ${EXECUTABLE_OUTPUT_PATH}/job_node_test) +add_test( job_list_test valgrind --leak-check=full --error-exitcode=1 ${EXECUTABLE_OUTPUT_PATH}/job_list_test) add_test( ext_joblist_test ${EXECUTABLE_OUTPUT_PATH}/ext_joblist_test ${CMAKE_CURRENT_SOURCE_DIR}/data/jobs/util ${CMAKE_CURRENT_SOURCE_DIR}) add_executable( job_program_output job_program_output.c ) @@ -34,6 +43,14 @@ add_executable( job_queue_test job_job_queue_test.c ) target_link_libraries( job_queue_test job_queue test_util ) add_test( job_queue_test ${EXECUTABLE_OUTPUT_PATH}/job_queue_test ${EXECUTABLE_OUTPUT_PATH}/job_program_output ) +add_executable( job_queue_stress_task job_queue_stress_task.c ) +target_link_libraries( job_queue_stress_task ert_util ) + +add_executable( job_queue_stress_test job_queue_stress_test.c ) +target_link_libraries( job_queue_stress_test job_queue test_util ) +add_test( job_queue_stress_test ${EXECUTABLE_OUTPUT_PATH}/job_queue_stress_test ${EXECUTABLE_OUTPUT_PATH}/job_queue_stress_task ) + + add_executable( job_queue_driver_test job_queue_driver_test.c ) target_link_libraries( job_queue_driver_test job_queue test_util ) add_test( job_queue_driver_test ${EXECUTABLE_OUTPUT_PATH}/job_queue_driver_test ) diff --git a/ThirdParty/Ert/devel/libjob_queue/tests/job_job_queue_test.c b/ThirdParty/Ert/devel/libjob_queue/tests/job_job_queue_test.c index fb30d56e93..63baa2bdaa 100644 --- a/ThirdParty/Ert/devel/libjob_queue/tests/job_job_queue_test.c +++ b/ThirdParty/Ert/devel/libjob_queue/tests/job_job_queue_test.c @@ -1,19 +1,19 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. - - The file 'job_queue_test.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> - for more details. + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'job_queue_test.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> + for more details. */ #include <stdlib.h> #include <stdbool.h> @@ -27,8 +27,9 @@ #include <ert/util/test_work_area.h> #include <ert/job_queue/job_queue.h> +#include <ert/job_queue/job_queue_manager.h> -void submit_jobs_to_queue(job_queue_type * queue, test_work_area_type * work_area, char * executable_to_run, int number_of_jobs, int number_of_slowjobs, char* sleep_short, char* sleep_long, bool multithreaded) { +void submit_jobs_to_queue(job_queue_type * queue, test_work_area_type * work_area, char * executable_to_run, int number_of_jobs, int number_of_slowjobs, char* sleep_short, char* sleep_long) { int submitted_slowjobs = 0; for (int i = 0; i < number_of_jobs; i++) { char * runpath = util_alloc_sprintf("%s/%s_%d", test_work_area_get_cwd(work_area), "job", i); @@ -40,43 +41,29 @@ void submit_jobs_to_queue(job_queue_type * queue, test_work_area_type * work_are submitted_slowjobs++; } - if (multithreaded) { - - job_queue_add_job_mt(queue, executable_to_run, NULL, NULL, NULL, NULL, 1, runpath, "Testjob", 2, (const char *[2]) { - runpath, sleeptime - }); - } else { - - job_queue_add_job_st(queue, executable_to_run, NULL, NULL, NULL, NULL, 1, runpath, "Testjob", 2, (const char *[2]) { - runpath, sleeptime - }); - } + job_queue_add_job(queue, executable_to_run, NULL, NULL, NULL, NULL, 1, runpath, "Testjob", 2, (const char *[2]) {runpath, sleeptime}); free(runpath); } + test_assert_int_equal( number_of_jobs , job_queue_get_active_size(queue) ); } void monitor_job_queue(job_queue_type * queue, int max_job_duration, time_t stop_time, int min_realizations) { - bool cont = true; - - if (0 >= min_realizations) - cont = false; - - while (cont) { - //Check if minimum number of realizations have run, and if so, kill the rest after a certain time - if ((job_queue_get_num_complete(queue) >= min_realizations)) { - job_queue_set_max_job_duration(queue, max_job_duration); - - job_queue_set_job_stop_time(queue, stop_time); - - cont = false; - } - - if (cont) { + if (min_realizations > 0) { + while (true) { util_usleep(100); + + //Check if minimum number of realizations have run, and if so, kill the rest after a certain time + if ((job_queue_get_num_complete(queue) >= min_realizations)) { + job_queue_set_max_job_duration(queue, max_job_duration); + job_queue_set_job_stop_time(queue, stop_time); + break; + } } } } + + void run_jobs_with_time_limit_test(char * executable_to_run, int number_of_jobs, int number_of_slowjobs, char * sleep_short, char * sleep_long, int max_sleep) { test_work_area_type * work_area = test_work_area_alloc("job_queue"); job_queue_type * queue = job_queue_alloc(number_of_jobs, "OK.status", "ERROR"); @@ -85,9 +72,9 @@ void run_jobs_with_time_limit_test(char * executable_to_run, int number_of_jobs, job_queue_set_driver(queue, driver); job_queue_set_max_job_duration(queue, max_sleep); - submit_jobs_to_queue(queue, work_area, executable_to_run, number_of_jobs, number_of_slowjobs, sleep_short, sleep_long, false); + submit_jobs_to_queue(queue, work_area, executable_to_run, number_of_jobs, number_of_slowjobs, sleep_short, sleep_long); - job_queue_run_jobs(queue, number_of_jobs, true); + job_queue_run_jobs(queue, number_of_jobs, false); test_assert_int_equal(number_of_jobs - number_of_slowjobs, job_queue_get_num_complete(queue)); test_assert_int_equal(number_of_slowjobs, job_queue_get_num_killed(queue)); @@ -104,48 +91,46 @@ void run_jobs_with_time_limit_test(char * executable_to_run, int number_of_jobs, } -void run_and_monitor_jobs(char * executable_to_run, int max_job_duration, time_t stop_time, int min_realizations, int num_completed, int interval_between_jobs) { - int number_of_jobs = 10; +void run_and_monitor_jobs(char * executable_to_run, + int number_of_jobs , + int max_job_duration, + time_t stop_time, + int min_realizations, + int min_completed, + int max_completed , + int interval_between_jobs) { + test_work_area_type * work_area = test_work_area_alloc("job_queue"); job_queue_type * queue = job_queue_alloc(number_of_jobs, "OK.status", "ERROR"); + job_queue_manager_type * queue_manager = job_queue_manager_alloc( queue ); queue_driver_type * driver = queue_driver_alloc_local(); - job_queue_set_driver(queue, driver); - arg_pack_type * arg_pack = arg_pack_alloc(); - arg_pack_append_ptr(arg_pack, queue); - arg_pack_append_int(arg_pack, 0); - arg_pack_append_bool(arg_pack, true); + job_queue_set_driver(queue, driver); - thread_pool_type * pool = thread_pool_alloc(1, true); - thread_pool_add_job(pool, job_queue_run_jobs__, arg_pack); int job_run_time = 0; for (int i = 0; i < number_of_jobs; i++) { char * runpath = util_alloc_sprintf("%s/%s_%d", test_work_area_get_cwd(work_area), "job", i); - util_make_path(runpath); - char * sleeptime = util_alloc_sprintf("%d", job_run_time); - job_queue_add_job_mt(queue, executable_to_run, NULL, NULL, NULL, NULL, 1, runpath, "Testjob", 2, (const char *[2]) { - runpath, sleeptime - }); + util_make_path(runpath); + job_queue_add_job(queue, executable_to_run, NULL, NULL, NULL, NULL, 1, runpath, "Testjob", 2, (const char *[2]) {runpath, sleeptime}); job_run_time += interval_between_jobs; free(sleeptime); free(runpath); } - job_queue_submit_complete(queue); + job_queue_manager_start_queue(queue_manager,0,false,false); + monitor_job_queue( queue , max_job_duration , stop_time , min_realizations ); + job_queue_manager_wait(queue_manager); - monitor_job_queue(queue, max_job_duration, stop_time, min_realizations); - - thread_pool_join(pool); - thread_pool_free(pool); - + printf("Completed: %d <= %d <= %d ?\n",min_completed , job_queue_get_num_complete(queue) , max_completed); + test_assert_true(job_queue_get_num_complete(queue) >= min_completed); + test_assert_true(job_queue_get_num_complete(queue) <= max_completed); - test_assert_int_equal(num_completed, job_queue_get_num_complete(queue)); - test_assert_int_equal(number_of_jobs - num_completed, job_queue_get_num_killed(queue)); + test_assert_int_equal(number_of_jobs - job_queue_get_num_complete( queue ) , job_queue_get_num_killed(queue)); test_assert_bool_equal(false, job_queue_get_open(queue)); job_queue_reset(queue); test_assert_bool_equal(true, job_queue_get_open(queue)); @@ -153,6 +138,7 @@ void run_and_monitor_jobs(char * executable_to_run, int max_job_duration, time_t job_queue_free(queue); queue_driver_free(driver); + job_queue_manager_free( queue_manager ); test_work_area_free(work_area); } @@ -168,12 +154,12 @@ void run_jobs_time_limit_multithreaded(char * executable_to_run, int number_of_j arg_pack_type * arg_pack = arg_pack_alloc(); arg_pack_append_ptr(arg_pack, queue); arg_pack_append_int(arg_pack, 0); - arg_pack_append_bool(arg_pack, true); + arg_pack_append_bool(arg_pack, false); thread_pool_type * pool = thread_pool_alloc(1, true); thread_pool_add_job(pool, job_queue_run_jobs__, arg_pack); - submit_jobs_to_queue(queue, work_area, executable_to_run, number_of_jobs, number_of_slowjobs, sleep_short, sleep_long, true); + submit_jobs_to_queue(queue, work_area, executable_to_run, number_of_jobs, number_of_slowjobs, sleep_short, sleep_long); job_queue_submit_complete(queue); thread_pool_join(pool); @@ -191,8 +177,8 @@ void run_jobs_time_limit_multithreaded(char * executable_to_run, int number_of_j test_work_area_free(work_area); } -void JobQueueRunJobs_ReuseQueue_AllOk(char ** argv) { - printf("Running JobQueueRunJobs_ReuseQueue_AllOk\n"); +void test1(char ** argv) { + printf("001: Running JobQueueRunJobs_ReuseQueue_AllOk\n"); int number_of_jobs = 20; int number_of_queue_reuse = 10; @@ -204,9 +190,9 @@ void JobQueueRunJobs_ReuseQueue_AllOk(char ** argv) { job_queue_set_driver(queue, driver); for (int j = 0; j < number_of_queue_reuse; j++) { - submit_jobs_to_queue(queue, work_area, argv[1], number_of_jobs, 0, "0", "0", false); + submit_jobs_to_queue(queue, work_area, argv[1], number_of_jobs, 0, "0", "0"); - job_queue_run_jobs(queue, number_of_jobs, true); + job_queue_run_jobs(queue, number_of_jobs, false); test_assert_int_equal(number_of_jobs, job_queue_get_num_complete(queue)); test_assert_bool_equal(false, job_queue_get_open(queue)); @@ -220,8 +206,8 @@ void JobQueueRunJobs_ReuseQueue_AllOk(char ** argv) { } -void JobQueueRunJobs_ReuseQueueWithStopTime_AllOk(char ** argv) { - printf("Running JobQueueRunJobs_ReuseQueueWithStopTime_AllOk\n"); +void test2(char ** argv) { + printf("002: Running JobQueueRunJobs_ReuseQueueWithStopTime_AllOk\n"); int number_of_jobs = 3; int number_of_slow_jobs = 2; @@ -234,11 +220,11 @@ void JobQueueRunJobs_ReuseQueueWithStopTime_AllOk(char ** argv) { job_queue_set_driver(queue, driver); for (int j = 0; j < number_of_queue_reuse; j++) { - submit_jobs_to_queue(queue, work_area, argv[1], number_of_jobs, number_of_slow_jobs, "1", "5", false); + submit_jobs_to_queue(queue, work_area, argv[1], number_of_jobs, number_of_slow_jobs, "1", "5"); - job_queue_run_jobs(queue, number_of_jobs, true); - time_t current_time = time(NULL); - job_queue_set_job_stop_time(queue, current_time); + job_queue_run_jobs(queue, number_of_jobs, false); + time_t current_time = time(NULL); + job_queue_set_job_stop_time(queue, current_time); test_assert_int_equal(number_of_jobs, job_queue_get_num_complete(queue)); test_assert_bool_equal(false, job_queue_get_open(queue)); @@ -253,25 +239,31 @@ void JobQueueRunJobs_ReuseQueueWithStopTime_AllOk(char ** argv) { } -void JobQueueSetStopTime_StopTimeEarly_MinRealisationsAreRun(char ** argv) { - printf("Running JobQueueSetStopTime_StopTimeEarly_MinRealisationsAreRun\n"); +void test3(char ** argv) { + printf("003: Running JobQueueSetStopTime_StopTimeEarly_MinRealisationsAreRun\n"); //Use stop_time to to stop jobs after min_realizations are finished + int number_of_jobs = 10; int min_realizations = 5; int num_expected_completed = 5; int max_duration_time = 0; int interval_between_jobs = 2; - time_t currenttime; - time(¤ttime); - time_t stoptime = currenttime; - run_and_monitor_jobs(argv[1], max_duration_time, stoptime, min_realizations, num_expected_completed, interval_between_jobs); + time_t stoptime = time( NULL ); + run_and_monitor_jobs(argv[1], number_of_jobs , max_duration_time, stoptime, min_realizations, num_expected_completed, num_expected_completed , interval_between_jobs); } -void JobQueueSetStopTime_StopTimeLate_AllRealisationsAreRun(char ** argv) { - printf("Running JobQueueSetStopTime_StopTimeLate_AllRealisationsAreRun\n"); +void test4(char ** argv) { + printf("004: Running JobQueueSetMaxDuration_Duration5Seconds_KillsAllJobsWithDurationMoreThan5Seconds\n"); + run_jobs_with_time_limit_test(argv[1], 100, 23, "1", "100", 5); +} + + +void test5(char ** argv) { + printf("005: Running JobQueueSetStopTime_StopTimeLate_AllRealisationsAreRun\n"); //Use stop_time to to stop jobs after min_realizations are finished + int number_of_jobs = 10; int min_realizations = 5; int num_expected_completed = 10; int max_duration_time = 0; @@ -279,12 +271,13 @@ void JobQueueSetStopTime_StopTimeLate_AllRealisationsAreRun(char ** argv) { time_t currenttime; time(¤ttime); time_t stoptime = currenttime + 15; - run_and_monitor_jobs(argv[1], max_duration_time, stoptime, min_realizations, num_expected_completed, interval_between_jobs); + run_and_monitor_jobs(argv[1], number_of_jobs , max_duration_time, stoptime, min_realizations, num_expected_completed, num_expected_completed , interval_between_jobs); } -void JobQueueSetStopTimeAndMaxDuration_MaxDurationShort_StopTimeLate_MinRealisationsAreRun(char ** argv) { - printf("Running JobQueueSetStopTimeAndMaxDuration_MaxDurationShort_StopTimeLong_MinRealisationsAreRun\n"); +void test6(char ** argv) { + printf("006: Running JobQueueSetStopTimeAndMaxDuration_MaxDurationShort_StopTimeLong_MinRealisationsAreRun\n"); + int number_of_jobs = 10; int min_realizations = 1; int num_expected_completed = 1; int max_duration_time = 1; @@ -292,13 +285,14 @@ void JobQueueSetStopTimeAndMaxDuration_MaxDurationShort_StopTimeLate_MinRealisat time_t currenttime; time(¤ttime); time_t stoptime = currenttime + 10; - run_and_monitor_jobs(argv[1], max_duration_time, stoptime, min_realizations, num_expected_completed, interval_between_jobs); + run_and_monitor_jobs(argv[1], number_of_jobs , max_duration_time, stoptime, min_realizations, num_expected_completed, number_of_jobs , interval_between_jobs); } -void JobQueueSetStopTimeAndMaxDuration_MaxDurationLong_StopTimeEarly_MinRealisationsAreRun(char ** argv) { - printf("Running JobQueueSetStopTimeAndMaxDuration_MaxDurationLong_StopTimeEarly_MinRealisationsAreRun\n"); +void test7(char ** argv) { + printf("007: Running JobQueueSetStopTimeAndMaxDuration_MaxDurationLong_StopTimeEarly_MinRealisationsAreRun\n"); + int number_of_jobs = 10; int min_realizations = 1; int num_expected_completed = 1; int max_duration_time = 10; @@ -306,101 +300,108 @@ void JobQueueSetStopTimeAndMaxDuration_MaxDurationLong_StopTimeEarly_MinRealisat time_t currenttime; time(¤ttime); time_t stoptime = currenttime + 1; - run_and_monitor_jobs(argv[1], max_duration_time, stoptime, min_realizations, num_expected_completed, interval_between_jobs); + run_and_monitor_jobs(argv[1], number_of_jobs , max_duration_time, stoptime, min_realizations, num_expected_completed, num_expected_completed , interval_between_jobs); } -void JobQueueSetMaxDurationAfterMinRealizations_MaxDurationShort_OnlyMinRealizationsAreRun(char ** argv) { - printf("Running JobQueueSetMaxDurationAfterMinRealizations_MaxDurationShort_OnlyMinRealizationsAreRun\n"); +void test8(char ** argv) { + printf("008: Running JobQueueSetMaxDurationAfterMinRealizations_MaxDurationShort_OnlyMinRealizationsAreRun\n"); // Must have one job completed, the rest are then killed due to the max_duration_time gets exceeded. + int number_of_jobs = 10; int min_realizations = 1; int num_expected_completed = 1; int max_duration_time = 1; int interval_between_jobs = 2; time_t currenttime = 0; - run_and_monitor_jobs(argv[1], max_duration_time, currenttime, min_realizations, num_expected_completed, interval_between_jobs); + run_and_monitor_jobs(argv[1], number_of_jobs , max_duration_time, currenttime, min_realizations, num_expected_completed, 3 , interval_between_jobs); } -void JobQueueSetMaxDurationAfterMinRealizations_MaxDurationLooong_AllRealizationsAreRun(char ** argv) { - printf("Running JobQueueSetMaxDurationAfterMinRealizations_MaxDurationLooong_AllRealizationsAreRun\n"); +void test9(char ** argv) { + printf("009: Running JobQueueSetMaxDurationAfterMinRealizations_MaxDurationLooong_AllRealizationsAreRun\n"); // Min realizations is 1, but the max running time exceeds the time used by any of the jobs, so all run to completion + int number_of_jobs = 10; int min_realizations = 1; int num_expected_completed = 10; int max_duration_time = 12; int interval_between_jobs = 1; time_t currenttime = 0; - run_and_monitor_jobs(argv[1], max_duration_time, currenttime, min_realizations, num_expected_completed, interval_between_jobs); + run_and_monitor_jobs(argv[1], number_of_jobs , max_duration_time, currenttime, min_realizations, num_expected_completed, num_expected_completed , interval_between_jobs); } -void JobQueueSetMaxDurationAfterMinRealizations_MaxDurationSemiLong_MoreThanMinRealizationsAreRun(char ** argv) { - printf("Running JobQueueSetMaxDurationAfterMinRealizations_MaxDurationSemiLong_MoreThanMinRealizationsAreRun\n"); - // Min is 3, but max_duration_time allows for one more to be completed +void test10(char ** argv) { + printf("010: Running JobQueueSetMaxDurationAfterMinRealizations_MaxDurationSemiLong_MoreThanMinRealizationsAreRun\n"); + + int number_of_jobs = 10; int min_realizations = 3; - int num_expected_completed = 4; int max_duration_time = 7; int interval_between_jobs = 2; time_t currenttime = 0; - run_and_monitor_jobs(argv[1], max_duration_time, currenttime, min_realizations, num_expected_completed, interval_between_jobs); + run_and_monitor_jobs(argv[1], number_of_jobs , max_duration_time, currenttime, min_realizations, min_realizations , number_of_jobs , interval_between_jobs); } -void JobQueueSetMaxDurationAfterMinRealizations_MaxDurationShortButMinRealizationsIsAll_AllRealizationsAreRun(char ** argv) { - printf("Running JobQueueSetMaxDurationAfterMinRealizations_MaxDurationShortButMinRealizationsIsAll_AllRealizationsAreRun\n"); +void test11(char ** argv) { + printf("011: Running JobQueueSetMaxDurationAfterMinRealizations_MaxDurationShortButMinRealizationsIsAll_AllRealizationsAreRun\n"); // Min is 10, so all run to completion + int number_of_jobs = 10; int min_realizations = 10; int num_expected_completed = 10; int max_duration_time = 1; int interval_between_jobs = 0; time_t currenttime = 0; - run_and_monitor_jobs(argv[1], max_duration_time, currenttime, min_realizations, num_expected_completed, interval_between_jobs); + run_and_monitor_jobs(argv[1], number_of_jobs , max_duration_time, currenttime, min_realizations, num_expected_completed, num_expected_completed , interval_between_jobs); } -void JobQueueSetMaxDuration_DurationZero_AllRealisationsAreRun(char ** argv) { - printf("Running JobQueueSetMaxDuration_DurationZero_AllRealisationsAreRun\n"); +void test12(char ** argv) { + printf("012: Running JobQueueSetMaxDuration_DurationZero_AllRealisationsAreRun\n"); run_jobs_with_time_limit_test(argv[1], 10, 0, "1", "100", 0); // 0 as limit means no limit*/ } -void JobQueueSetMaxDuration_Duration5Seconds_KillsAllJobsWithDurationMoreThan5Seconds(char ** argv) { - printf("Running JobQueueSetMaxDuration_Duration5Seconds_KillsAllJobsWithDurationMoreThan5Seconds\n"); - run_jobs_with_time_limit_test(argv[1], 100, 23, "1", "100", 5); -} - -void JobQueueSetMaxDurationRunJobsLoopInThread_Duration5Seconds_KillsAllJobsWithDurationMoreThan5Seconds(char ** argv) { - printf("Running JobQueueSetMaxDurationRunJobsLoopInThread_Duration5Seconds_KillsAllJobsWithDurationMoreThan5Seconds\n"); +void test13(char ** argv) { + printf("013: Running JobQueueSetMaxDurationRunJobsLoopInThread_Duration5Seconds_KillsAllJobsWithDurationMoreThan5Seconds\n"); run_jobs_time_limit_multithreaded(argv[1], 100, 23, "1", "100", 5); } -void JobQueueSetAutoStopTime_ThreeQuickJobs_AutoStopTimeKillsTheRest(char ** argv) { - printf("Running JobQueueSetAutoStopTime_ThreeQuickJobs_AutoStopTimeKillsTheRest\n"); +void test14(char ** argv) { + printf("014: Running JobQueueSetAutoStopTime_ThreeQuickJobs_AutoStopTimeKillsTheRest\n"); int number_of_jobs = 10; test_work_area_type * work_area = test_work_area_alloc("job_queue"); job_queue_type * queue = job_queue_alloc(number_of_jobs, "OK.status", "ERROR"); queue_driver_type * driver = queue_driver_alloc_local(); + job_queue_manager_type * queue_manager = job_queue_manager_alloc( queue ); job_queue_set_driver(queue, driver); - arg_pack_type * arg_pack = arg_pack_alloc(); - arg_pack_append_ptr(arg_pack, queue); - arg_pack_append_int(arg_pack, 0); - arg_pack_append_bool(arg_pack, true); - - thread_pool_type * pool = thread_pool_alloc(1, true); - thread_pool_add_job(pool, job_queue_run_jobs__, arg_pack); int number_of_slowjobs = 7; + int number_of_fastjobs = number_of_jobs - number_of_slowjobs; char * sleep_short = "0"; char * sleep_long = "100"; - - submit_jobs_to_queue(queue, work_area, argv[1], number_of_jobs, number_of_slowjobs, sleep_short, sleep_long, false); - - util_usleep(1000000); + submit_jobs_to_queue(queue, work_area, argv[1], number_of_jobs, number_of_slowjobs, sleep_short, sleep_long); job_queue_submit_complete(queue); + job_queue_manager_start_queue( queue_manager , 10 , false , false); + + /* + The jobs are distributed with some very fast, and some quite + long. Here we busy wait until all the fast ones have completed and + then we calculate a stop for the remaining jobs with the + job_queue_set_auto_job_stop_time() function. + */ + + while (true) { + int num_complete = job_queue_get_num_complete(queue); + if (num_complete == number_of_fastjobs) + break; + util_usleep( 100000 ); + } + job_queue_set_auto_job_stop_time(queue); - thread_pool_join(pool); + job_queue_manager_wait(queue_manager); + test_assert_int_equal(number_of_jobs - number_of_slowjobs, job_queue_get_num_complete(queue)); test_assert_int_equal(number_of_slowjobs, job_queue_get_num_killed(queue)); @@ -411,14 +412,14 @@ void JobQueueSetAutoStopTime_ThreeQuickJobs_AutoStopTimeKillsTheRest(char ** arg test_assert_int_equal(0, job_queue_get_num_complete(queue)); - thread_pool_free(pool); + job_queue_manager_free( queue_manager ); job_queue_free(queue); queue_driver_free(driver); test_work_area_free(work_area); } -void JobQueueSetAutoStopTime_NoJobsAreFinished_AutoStopDoesNothing(char ** argv) { - printf("Running JobQueueSetAutoStopTime_NoJobsAreFinished_AutoStopDoesNothing\n"); +void test15(char ** argv) { + printf("015: Running JobQueueSetAutoStopTime_NoJobsAreFinished_AutoStopDoesNothing\n"); int number_of_jobs = 10; @@ -429,7 +430,7 @@ void JobQueueSetAutoStopTime_NoJobsAreFinished_AutoStopDoesNothing(char ** argv) char * sleep_long = "100"; - submit_jobs_to_queue(queue, work_area, argv[1], number_of_jobs, number_of_jobs, "0", sleep_long, false); + submit_jobs_to_queue(queue, work_area, argv[1], number_of_jobs, number_of_jobs, "0", sleep_long); job_queue_set_auto_job_stop_time(queue); @@ -441,8 +442,8 @@ void JobQueueSetAutoStopTime_NoJobsAreFinished_AutoStopDoesNothing(char ** argv) test_work_area_free(work_area); } -void JobQueueSetAutoStopTime_AllJobsAreFinished_AutoStopDoesNothing(char ** argv) { - printf("Running JobQueueSetAutoStopTime_AllJobsAreFinished_AutoStopDoesNothing\n"); +void test16(char ** argv) { + printf("016: Running JobQueueSetAutoStopTime_AllJobsAreFinished_AutoStopDoesNothing\n"); int number_of_jobs = 10; test_work_area_type * work_area = test_work_area_alloc("job_queue"); @@ -451,9 +452,9 @@ void JobQueueSetAutoStopTime_AllJobsAreFinished_AutoStopDoesNothing(char ** argv queue_driver_type * driver = queue_driver_alloc_local(); job_queue_set_driver(queue, driver); - submit_jobs_to_queue(queue, work_area, argv[1], number_of_jobs, 0, "0", "0", false); + submit_jobs_to_queue(queue, work_area, argv[1], number_of_jobs, 0, "0", "0"); - job_queue_run_jobs(queue, number_of_jobs, true); + job_queue_run_jobs(queue, number_of_jobs, false); test_assert_int_equal(number_of_jobs, job_queue_get_num_complete(queue)); test_assert_bool_equal(false, job_queue_get_open(queue)); @@ -465,28 +466,26 @@ void JobQueueSetAutoStopTime_AllJobsAreFinished_AutoStopDoesNothing(char ** argv test_work_area_free(work_area); } + int main(int argc, char ** argv) { - JobQueueRunJobs_ReuseQueue_AllOk(argv); - JobQueueRunJobs_ReuseQueueWithStopTime_AllOk(argv); - - JobQueueSetMaxDuration_DurationZero_AllRealisationsAreRun(argv); - JobQueueSetMaxDuration_Duration5Seconds_KillsAllJobsWithDurationMoreThan5Seconds(argv); - JobQueueSetMaxDurationRunJobsLoopInThread_Duration5Seconds_KillsAllJobsWithDurationMoreThan5Seconds(argv); - - JobQueueSetMaxDurationAfterMinRealizations_MaxDurationShort_OnlyMinRealizationsAreRun(argv); - JobQueueSetMaxDurationAfterMinRealizations_MaxDurationLooong_AllRealizationsAreRun(argv); - JobQueueSetMaxDurationAfterMinRealizations_MaxDurationSemiLong_MoreThanMinRealizationsAreRun(argv); - JobQueueSetMaxDurationAfterMinRealizations_MaxDurationShortButMinRealizationsIsAll_AllRealizationsAreRun(argv); - - JobQueueSetStopTime_StopTimeEarly_MinRealisationsAreRun(argv); - JobQueueSetStopTime_StopTimeLate_AllRealisationsAreRun(argv); - - JobQueueSetStopTimeAndMaxDuration_MaxDurationShort_StopTimeLate_MinRealisationsAreRun(argv); - JobQueueSetStopTimeAndMaxDuration_MaxDurationLong_StopTimeEarly_MinRealisationsAreRun(argv); - - JobQueueSetAutoStopTime_ThreeQuickJobs_AutoStopTimeKillsTheRest(argv); - JobQueueSetAutoStopTime_NoJobsAreFinished_AutoStopDoesNothing(argv); - JobQueueSetAutoStopTime_AllJobsAreFinished_AutoStopDoesNothing(argv); + util_install_signals(); + + test1(argv); + test2(argv); + test3(argv); + test4(argv); + test5(argv); + test6(argv); + test7(argv); + test8(argv); + test9(argv); + test10(argv); + test11(argv); + test12(argv); + test13(argv); + test14(argv); + test15(argv); + test16(argv); exit(0); } diff --git a/ThirdParty/Ert/devel/libjob_queue/tests/job_list_test.c b/ThirdParty/Ert/devel/libjob_queue/tests/job_list_test.c new file mode 100644 index 0000000000..9ab24a1b61 --- /dev/null +++ b/ThirdParty/Ert/devel/libjob_queue/tests/job_list_test.c @@ -0,0 +1,77 @@ +/* + Copyright (C) 2015 Statoil ASA, Norway. + + The file 'job_node_test.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> + for more details. +*/ +#include <stdlib.h> +#include <stdbool.h> + +#include <ert/util/test_util.h> +#include <ert/util/arg_pack.h> + +#include <ert/job_queue/job_node.h> +#include <ert/job_queue/job_list.h> + + +void test_create() { + job_list_type * list = job_list_alloc(); + test_assert_true( job_list_is_instance( list )); + test_assert_int_equal( 0 , job_list_get_size( list )); + job_list_free( list ); +} + + + +void call_add_job( void * arg ) { + arg_pack_type * arg_pack = arg_pack_safe_cast( arg ); + job_list_type * job_list = arg_pack_iget_ptr( arg_pack , 0 ); + job_queue_node_type * node = arg_pack_iget_ptr( arg_pack , 1 ); + job_list_add_job( job_list , node ); +} + + +void call_iget_job( void * arg ) { + job_list_type * job_list = job_list_safe_cast( arg ); + job_list_iget_job( job_list , 10); +} + + + +void test_add_job() { + job_list_type * list = job_list_alloc(); + job_queue_node_type * node = job_queue_node_alloc_simple("name" , "/tmp" , "/bin/ls" , 0 , NULL); + job_list_add_job( list , node ); + test_assert_int_equal( job_list_get_size( list ) , 1 ); + test_assert_int_equal( job_queue_node_get_queue_index(node) , 0 ); + test_assert_ptr_equal( node , job_list_iget_job(list , 0)); + { + arg_pack_type * arg_pack = arg_pack_alloc( ); + arg_pack_append_ptr( arg_pack , list ); + arg_pack_append_ptr( arg_pack , node ); + test_assert_util_abort("job_queue_node_set_queue_index", call_add_job, arg_pack ); + arg_pack_free( arg_pack ); + } + test_assert_util_abort("job_list_iget_job", call_iget_job, list); + job_list_reset( list ); + test_assert_int_equal( 0 , job_list_get_size( list )); + job_list_free( list ); +} + + +int main( int argc , char ** argv) { + util_install_signals(); + test_create(); + test_add_job(); +} diff --git a/ThirdParty/Ert/devel/libjob_queue/tests/job_node_test.c b/ThirdParty/Ert/devel/libjob_queue/tests/job_node_test.c new file mode 100644 index 0000000000..29f901548e --- /dev/null +++ b/ThirdParty/Ert/devel/libjob_queue/tests/job_node_test.c @@ -0,0 +1,58 @@ +/* + Copyright (C) 2015 Statoil ASA, Norway. + + The file 'job_node_test.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> + for more details. +*/ +#include <stdlib.h> +#include <stdbool.h> + +#include <ert/util/test_util.h> +#include <ert/job_queue/job_node.h> + + +void test_create() { + job_queue_node_type * node = job_queue_node_alloc_simple("name" , "/tmp" , "/bin/ls" , 0 , NULL); + test_assert_true( job_queue_node_is_instance( node )); + job_queue_node_free( node ); +} + + + +void call_get_queue_index( void * arg ) { + job_queue_node_type * node = job_queue_node_safe_cast( arg ); + job_queue_node_get_queue_index( node ); +} + + + + +void test_queue_index() { + job_queue_node_type * node = job_queue_node_alloc_simple( "name" , "/tmp" , "/bin/ls" , 0 , NULL ); + test_assert_util_abort("job_queue_node_get_queue_index" , call_get_queue_index , node ); +} + + +void test_path_does_not_exist() { + job_queue_node_type * node = job_queue_node_alloc_simple( "name" , "does-not-exist" , "/bin/ls" , 0 , NULL); + test_assert_NULL( node ); +} + + +int main( int argc , char ** argv) { + util_install_signals(); + test_create(); + test_queue_index(); + test_path_does_not_exist(); +} diff --git a/ThirdParty/Ert/devel/libjob_queue/tests/job_queue_stress_task.c b/ThirdParty/Ert/devel/libjob_queue/tests/job_queue_stress_task.c new file mode 100644 index 0000000000..c08d3f7e0e --- /dev/null +++ b/ThirdParty/Ert/devel/libjob_queue/tests/job_queue_stress_task.c @@ -0,0 +1,57 @@ +/* + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'job_queue_test.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> + for more details. +*/ + +#include <unistd.h> + +#include <ert/util/util.h> + + +/* + This is a small test job used by the job_queue_stress_test. The job + does the following: + + 0. Chadir to runpath + 1. Create the file @runfile. + 2. Wait with usleep( @usleep_time ). + 3. Remove the @runfile. + 4. Create new file @OK_file + 5. exit. +*/ + +int main(int argc, char ** argv) { + const char * runpath = argv[1]; + const char * runfile = argv[2]; + const char * OK_file = argv[3]; + + int usleep_time; + + util_chdir( runpath ); + util_sscanf_int( argv[4] , &usleep_time ); + { + FILE * stream = util_fopen( runfile , "w"); + fprintf(stream , "Running ... \n"); + fclose( stream ); + } + usleep( usleep_time ); + util_unlink_existing(runfile); + { + FILE * stream = util_fopen( OK_file , "w"); + fprintf(stream , "OK ... \n"); + fclose( stream ); + } +} diff --git a/ThirdParty/Ert/devel/libjob_queue/tests/job_queue_stress_test.c b/ThirdParty/Ert/devel/libjob_queue/tests/job_queue_stress_test.c new file mode 100644 index 0000000000..e6c797b984 --- /dev/null +++ b/ThirdParty/Ert/devel/libjob_queue/tests/job_queue_stress_test.c @@ -0,0 +1,261 @@ +/* + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'job_queue_test.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> + for more details. + */ +#include <stdlib.h> +#include <stdbool.h> +#include <time.h> +#include <unistd.h> + +#include <ert/util/util.h> +#include <ert/util/thread_pool.h> +#include <ert/util/arg_pack.h> + +#include <ert/util/test_util.h> +#include <ert/util/arg_pack.h> +#include <ert/util/test_work_area.h> +#include <ert/util/rng.h> +#include <ert/util/type_macros.h> + +#include <ert/job_queue/job_queue.h> +#include <ert/job_queue/job_queue_manager.h> + +#define JOB_TYPE_ID 77539 +typedef struct { + UTIL_TYPE_ID_DECLARATION; + char * run_path; + bool callback_run; + int queue_index; + int submit_usleep; + int callback_usleep; + int run_usleep; + int argc; + char ** argv; + const char * cmd; +} job_type; + + + +UTIL_SAFE_CAST_FUNCTION( job , JOB_TYPE_ID ) + +job_type * alloc_job( rng_type * rng , const char * cmd) { + const int second = 1000000; + const int submit_min = 0; + const int submit_max = 10 * second; + + const int callback_min = 0.5 * second; + const int callback_max = 2 * second; + + const int run_min = 2 * second; + const int run_max = 10 * second; + + job_type * job = util_malloc( sizeof * job ); + UTIL_TYPE_ID_INIT( job , JOB_TYPE_ID ) + job->callback_run = false; + job->queue_index = -1; + job->submit_usleep = submit_min + rng_get_int( rng , (submit_max - submit_min )); + job->callback_usleep = callback_min + rng_get_int( rng , (callback_max - callback_min )); + job->run_usleep = run_min + rng_get_int( rng , (run_max - run_min )); + job->run_path = util_alloc_sprintf("%08d", rng_get_int(rng , 100000000)); + job->cmd = cmd; + job->argc = 4; + + job->argv = util_malloc( 4 * sizeof * job->argv ); + job->argv[0] = job->run_path; + job->argv[1] = "RUNNING"; + job->argv[2] = "OK"; + job->argv[3] = util_alloc_sprintf("%d", job->run_usleep); + + util_make_path( job->run_path ); + return job; +} + + +job_type ** alloc_jobs( rng_type * rng , int num_jobs , const char * cmd) { + job_type ** jobs = util_malloc( num_jobs * sizeof * jobs ); + for (int i=0; i < num_jobs; i++) { + job_type * job = alloc_job( rng , cmd); + job_safe_cast( job ); + jobs[i] = job; + } + return jobs; +} + + + +bool callback( void * arg ) { + job_type * job = job_safe_cast( arg ); + usleep( job->callback_usleep ); + job->callback_run = true; + return true; +} + + +void * submit_job__( void * arg ) { + arg_pack_type * arg_pack = arg_pack_safe_cast( arg ); + job_type * job = job_safe_cast( arg_pack_iget_ptr( arg_pack , 0 ) ); + job_queue_type * queue = arg_pack_iget_ptr( arg_pack , 1 ); + job->queue_index = job_queue_add_job( queue , job->cmd , callback , NULL , NULL , job , 1 , job->run_path , job->run_path , job->argc , (const char **) job->argv ); + usleep( job->submit_usleep ); + return NULL; +} + + +void submit_jobs( job_queue_type * queue , int num_jobs , job_type ** jobs , thread_pool_type * tp) { + for (int i=0; i < num_jobs; i++) { + job_type * job = jobs[i]; + arg_pack_type * arg = arg_pack_alloc(); + arg_pack_append_ptr( arg , job ); + arg_pack_append_ptr( arg , queue ); + thread_pool_add_job(tp , submit_job__ , arg ); + } +} + + +void check_jobs( int num_jobs , job_type ** jobs ) { + for (int i=0; i < num_jobs; i++) { + job_type * job = jobs[i]; + if (!job->callback_run) + fprintf(stderr,"The callback has not been registered on job:%d/%d \n",i,job->queue_index); + test_assert_true( job->callback_run ); + } +} + + +void * global_status( void * arg ) { + job_queue_type * job_queue = job_queue_safe_cast( arg ); + int counter = 0; + while (true) { + util_usleep(100000); + + if (job_queue_get_num_complete(job_queue) == job_queue_get_active_size(job_queue)) + break; + + if ((counter % 10) == 0) + printf("Waiting:%03d Running:%03d Callback:%03d Complete:%03d \n", + job_queue_get_num_waiting(job_queue) , + job_queue_get_num_running(job_queue), + job_queue_get_num_callback( job_queue ) , + job_queue_get_num_complete(job_queue)); + + counter++; + } + return NULL; +} + + +void * status_job__( void * arg ) { + const int usleep_time = 10000; + arg_pack_type * arg_pack = arg_pack_safe_cast( arg ); + job_type * job = job_safe_cast( arg_pack_iget_ptr( arg_pack , 0 ) ); + job_queue_type * queue = arg_pack_iget_ptr( arg_pack , 1 ); + char * run_file = util_alloc_filename( job->run_path , "RUNNING" , NULL); + + while (true) { + if (job->queue_index >= 0) { + job_status_type status; + if (util_is_file(run_file)) { + status = job_queue_iget_job_status(queue, job->queue_index); + if (util_is_file(run_file)) + test_assert_true( (status == JOB_QUEUE_RUNNING) || (status == JOB_QUEUE_SUBMITTED) ); + } + status = job_queue_iget_job_status(queue, job->queue_index); + if (status == JOB_QUEUE_SUCCESS) + break; + } + usleep( usleep_time ); + } + + free( run_file ); + return NULL; +} + + + +void status_jobs( job_queue_type * queue , int num_jobs , job_type ** jobs , thread_pool_type * tp) { + for (int i=0; i < num_jobs; i++) { + job_type * job = jobs[i]; + arg_pack_type * arg = arg_pack_alloc(); + arg_pack_append_ptr( arg , job ); + arg_pack_append_ptr( arg , queue ); + thread_pool_add_job(tp , status_job__ , arg ); + } + thread_pool_add_job( tp , global_status , queue ); +} + + +/* + The purpose of this test is to stress the queue system with a + massively multithreaded workload. The test will submit jobs, let + them run and run a callback. The various elements are pimped with + usleep() calls to ensure that all of these actions: + + 1. Submit + 2. Run callback + 3. Check status + + Are performed concurrently. The total runtime of the test should be + ~ 120 seconds. +*/ + + +int main(int argc , char ** argv) { + const int queue_timeout = 180; + const int submit_timeout = 180; + const int status_timeout = 180; + const int number_of_jobs = 250; + const int submit_threads = number_of_jobs / 10 ; + const int status_threads = number_of_jobs + 1; + const char * job = util_alloc_abs_path(argv[1]); + rng_type * rng = rng_alloc( MZRAN , INIT_CLOCK ); + test_work_area_type * work_area = test_work_area_alloc("job_queue"); + job_type **jobs = alloc_jobs( rng , number_of_jobs , job); + + job_queue_type * queue = job_queue_alloc(number_of_jobs, "OK", "ERROR"); + queue_driver_type * driver = queue_driver_alloc_local(); + job_queue_manager_type * queue_manager = job_queue_manager_alloc( queue ); + + job_queue_set_driver(queue, driver); + job_queue_manager_start_queue(queue_manager, 0, false , true); + + { + thread_pool_type * status_pool = thread_pool_alloc( status_threads , true ); + thread_pool_type * submit_pool = thread_pool_alloc( submit_threads , true ); + + submit_jobs( queue , number_of_jobs , jobs , submit_pool ); + status_jobs( queue , number_of_jobs , jobs , status_pool ); + + if (!thread_pool_try_join( submit_pool , submit_timeout )) + util_exit("Joining submit pool failed \n"); + thread_pool_free( submit_pool ); + + job_queue_submit_complete(queue); + + if (!thread_pool_try_join( status_pool , status_timeout)) + util_exit("Joining status pool failed \n"); + thread_pool_free( status_pool ); + } + + if (!job_queue_manager_try_wait(queue_manager , queue_timeout)) + util_exit("job_queue never completed \n"); + + job_queue_manager_free(queue_manager); + job_queue_free(queue); + queue_driver_free(driver); + check_jobs( number_of_jobs , jobs ); + test_work_area_free(work_area); + rng_free( rng ); +} diff --git a/ThirdParty/Ert/devel/libjob_queue/tests/job_status_test.c b/ThirdParty/Ert/devel/libjob_queue/tests/job_status_test.c new file mode 100644 index 0000000000..bde1fa9889 --- /dev/null +++ b/ThirdParty/Ert/devel/libjob_queue/tests/job_status_test.c @@ -0,0 +1,111 @@ +/* + Copyright (C) 2015 Statoil ASA, Norway. + + The file 'job_status_test.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> + for more details. +*/ + +#include <stdlib.h> +#include <stdbool.h> +#include <pthread.h> + +#include <ert/job_queue/job_queue_status.h> +#include <ert/job_queue/queue_driver.h> +#include <ert/util/test_util.h> + + +void call_get_status( void * arg ) { + job_queue_status_type * job_status = job_queue_status_safe_cast( arg ); + job_queue_status_get_count( job_status , JOB_QUEUE_DONE + JOB_QUEUE_USER_EXIT); +} + + + +void test_create() { + job_queue_status_type * status = job_queue_status_alloc(); + test_assert_true( job_queue_status_is_instance( status )); + test_assert_int_equal( job_queue_status_get_count( status , JOB_QUEUE_DONE ) , 0 ); + test_assert_util_abort( "STATUS_INDEX" , call_get_status , status ); + job_queue_status_free( status ); +} + + +void * add_sim( void * arg ) { + job_queue_status_type * job_status = job_queue_status_safe_cast( arg ); + job_queue_status_inc( job_status , JOB_QUEUE_WAITING ); + return NULL; +} + + +void * user_exit( void * arg ) { + job_queue_status_type * job_status = job_queue_status_safe_cast( arg ); + job_queue_status_transition( job_status , JOB_QUEUE_WAITING , JOB_QUEUE_USER_EXIT); + return NULL; +} + + +void * user_done( void * arg ) { + job_queue_status_type * job_status = job_queue_status_safe_cast( arg ); + job_queue_status_transition( job_status , JOB_QUEUE_WAITING , JOB_QUEUE_DONE); + return NULL; +} + + + +void test_update() { + int N = 15000; + pthread_t * thread_list = util_malloc( 2*N*sizeof * thread_list); + + job_queue_status_type * status = job_queue_status_alloc(); + test_assert_int_equal( 0 , job_queue_status_get_total_count( status )); + for (int i=0; i < 2*N; i++) + pthread_create( &thread_list[i] , NULL , add_sim , status ); + + for (int i=0; i < 2*N; i++) + pthread_join( thread_list[i] , NULL ); + + test_assert_int_equal( 2*N , job_queue_status_get_count( status , JOB_QUEUE_WAITING )); + for (int i=0; i < 2*N; i++) { + if ((i % 2) == 0) + pthread_create( &thread_list[i] , NULL , user_exit , status ); + else + pthread_create( &thread_list[i] , NULL , user_done , status ); + } + for (int i=0; i < 2*N; i++) + pthread_join( thread_list[i] , NULL ); + + test_assert_int_equal( 0 , job_queue_status_get_count( status , JOB_QUEUE_WAITING )); + test_assert_int_equal( N , job_queue_status_get_count( status , JOB_QUEUE_USER_EXIT )); + test_assert_int_equal( N , job_queue_status_get_count( status , JOB_QUEUE_DONE )); + + test_assert_int_equal( 2*N , job_queue_status_get_total_count( status )); + job_queue_status_free( status ); +} + + +void test_name() { + test_assert_string_equal( job_queue_status_name( JOB_QUEUE_NOT_ACTIVE ) , + "JOB_QUEUE_NOT_ACTIVE" ); + test_assert_string_equal( job_queue_status_name( JOB_QUEUE_EXIT ) , + "JOB_QUEUE_EXIT" ); + test_assert_string_equal( job_queue_status_name( JOB_QUEUE_FAILED ) , + "JOB_QUEUE_FAILED" ); +} + + +int main( int argc , char ** argv) { + test_create(); + test_update(); + test_name(); +} diff --git a/ThirdParty/Ert/devel/python/python/ert/config/__init__.py b/ThirdParty/Ert/devel/python/python/ert/config/__init__.py index 0420a73e17..da46f58b29 100644 --- a/ThirdParty/Ert/devel/python/python/ert/config/__init__.py +++ b/ThirdParty/Ert/devel/python/python/ert/config/__init__.py @@ -20,6 +20,7 @@ from .unrecognized_enum import UnrecognizedEnum from .content_type_enum import ContentTypeEnum +from .config_error import ConfigError from .config_content import ConfigContent , ContentItem, ContentNode from .config_parser import ConfigParser, SchemaItem -from .config_error import ConfigError + diff --git a/ThirdParty/Ert/devel/python/python/ert/config/config_content.py b/ThirdParty/Ert/devel/python/python/ert/config/config_content.py index b9dc960930..99bae616af 100644 --- a/ThirdParty/Ert/devel/python/python/ert/config/config_content.py +++ b/ThirdParty/Ert/devel/python/python/ert/config/config_content.py @@ -16,7 +16,7 @@ import os.path -from ert.config import UnrecognizedEnum, CONFIG_LIB, ContentTypeEnum +from ert.config import UnrecognizedEnum, CONFIG_LIB, ContentTypeEnum,ConfigError from ert.cwrap import BaseCClass, CWrapper class ContentNode(BaseCClass): @@ -47,6 +47,20 @@ def __getitem__(self, index): typed_get = self.typed_get[content_type] return typed_get( self , index ) + def getPath(self , index = 0, absolute = True , relative_start = None): + index = self.__assertIndex(index) + content_type = ContentNode.cNamespace().iget_type(self, index) + if content_type in [ContentTypeEnum.CONFIG_EXISTING_PATH , ContentTypeEnum.CONFIG_PATH]: + if absolute: + return ContentNode.cNamespace().iget_as_abspath(self, index) + else: + if relative_start is None: + return ContentNode.cNamespace().iget_as_relpath(self, index) + else: + abs_path = ContentNode.cNamespace().iget_as_abspath(self, index) + return os.path.relpath( abs_path , relative_start ) + else: + raise TypeError("The getPath() method can only be called on PATH items") def content(self, sep=" "): return ContentNode.cNamespace().get_full_string(self, sep) @@ -84,6 +98,8 @@ def __getitem__(self, index): else: raise TypeError("[] operator must have integer index") + def last(self): + return self[-1] def getValue(self , item_index = -1 , node_index = 0): node = self[item_index] @@ -126,6 +142,8 @@ def free(self): ConfigContent.cNamespace().free(self) + def getErrors(self): + return ConfigContent.cNamespace().get_errors(self) cwrapper = CWrapper(CONFIG_LIB) @@ -137,6 +155,7 @@ def free(self): ConfigContent.cNamespace().is_valid = cwrapper.prototype("bool config_content_is_valid( config_content )") ConfigContent.cNamespace().has_key = cwrapper.prototype("bool config_content_has_item( config_content , char*)") ConfigContent.cNamespace().get_item = cwrapper.prototype("content_item_ref config_content_get_item( config_content , char*)") +ConfigContent.cNamespace().get_errors = cwrapper.prototype("config_error_ref config_content_get_errors( content_node )") ContentItem.cNamespace().size = cwrapper.prototype("int config_content_item_get_size( content_item )") ContentItem.cNamespace().iget_content_node = cwrapper.prototype("content_node_ref config_content_item_iget_node( content_item , int)") @@ -145,10 +164,14 @@ def free(self): ContentNode.cNamespace().size = cwrapper.prototype("int config_content_node_get_size( content_node )") ContentNode.cNamespace().get_full_string = cwrapper.prototype("char* config_content_node_get_full_string( content_node , char* )") ContentNode.cNamespace().iget_type = cwrapper.prototype("config_content_type_enum config_content_node_iget_type( content_node , int)") +ContentNode.cNamespace().iget_as_abspath = cwrapper.prototype("char* config_content_node_iget_as_abspath( content_node , int)") +ContentNode.cNamespace().iget_as_relpath = cwrapper.prototype("char* config_content_node_iget_as_relpath( content_node , int)") +ContentNode.typed_get[ContentTypeEnum.CONFIG_STRING] = iget_as_string = cwrapper.prototype("char* config_content_node_iget( content_node , int)") ContentNode.typed_get[ContentTypeEnum.CONFIG_INT] = iget_as_int = cwrapper.prototype("int config_content_node_iget_as_int( content_node , int)") -ContentNode.typed_get[ContentTypeEnum.CONFIG_BOOL] = iget_as_bool = cwrapper.prototype("bool config_content_node_iget_as_bool( content_node , int)") ContentNode.typed_get[ContentTypeEnum.CONFIG_FLOAT] = iget_as_double = cwrapper.prototype("double config_content_node_iget_as_double( content_node , int)") ContentNode.typed_get[ContentTypeEnum.CONFIG_PATH] = iget_as_path = cwrapper.prototype("char* config_content_node_iget_as_path( content_node , int)") -ContentNode.typed_get[ContentTypeEnum.CONFIG_STRING] = iget_as_string = cwrapper.prototype("char* config_content_node_iget( content_node , int)") +ContentNode.typed_get[ContentTypeEnum.CONFIG_EXISTING_PATH] = iget_as_path = cwrapper.prototype("char* config_content_node_iget_as_path( content_node , int)") +ContentNode.typed_get[ContentTypeEnum.CONFIG_BOOL] = iget_as_bool = cwrapper.prototype("bool config_content_node_iget_as_bool( content_node , int)") + diff --git a/ThirdParty/Ert/devel/python/python/ert/config/config_error.py b/ThirdParty/Ert/devel/python/python/ert/config/config_error.py index 69ed8eda98..2cbeb17563 100644 --- a/ThirdParty/Ert/devel/python/python/ert/config/config_error.py +++ b/ThirdParty/Ert/devel/python/python/ert/config/config_error.py @@ -43,9 +43,7 @@ def free(self): ################################################################## cwrapper = CWrapper(CONFIG_LIB) -cwrapper.registerType("config_error", ConfigError) -cwrapper.registerType("config_error_obj", ConfigError.createPythonObject) -cwrapper.registerType("config_error_ref", ConfigError.createCReference) +cwrapper.registerObjectType("config_error", ConfigError) ConfigError.cNamespace().free = cwrapper.prototype("void config_error_free(config_error)") ConfigError.cNamespace().count = cwrapper.prototype("int config_error_count(config_error)") diff --git a/ThirdParty/Ert/devel/python/python/ert/config/config_parser.py b/ThirdParty/Ert/devel/python/python/ert/config/config_parser.py index f1d64b72ec..4b118e5e6b 100644 --- a/ThirdParty/Ert/devel/python/python/ert/config/config_parser.py +++ b/ThirdParty/Ert/devel/python/python/ert/config/config_parser.py @@ -14,6 +14,7 @@ # See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> # for more details. +import sys import os.path from ert.config import UnrecognizedEnum, CONFIG_LIB, ContentTypeEnum , ConfigContent @@ -57,9 +58,13 @@ def __contains__(self , keyword): return ConfigParser.cNamespace().has_schema_item( self , keyword ) - def add(self, keyword, required=False): - return ConfigParser.cNamespace().add(self, keyword, required).setParent( self ) + def add(self, keyword, required=False , value_type = None): + item = ConfigParser.cNamespace().add(self, keyword, required).setParent( self ) + if value_type: + item.iset_type( 0 , value_type ) + return item + def getSchemaItem(self , keyword): if keyword in self: @@ -80,6 +85,10 @@ def parse(self, config_file, comment_string="--", include_kw="INCLUDE", define_k if config_content.isValid(): return config_content else: + sys.stderr.write("Errors parsing:%s \n" % config_file) + for count,error in enumerate(config_content.getErrors()): + sys.stderr.write(" %02d:%s\n" % (count , error)) + raise Exception("Parsing:%s failed" % config_file) else: raise IOError("File: %s does not exists" % config_file) diff --git a/ThirdParty/Ert/devel/python/python/ert/cwrap/clib.py b/ThirdParty/Ert/devel/python/python/ert/cwrap/clib.py index b599b659c4..11ed71b11f 100644 --- a/ThirdParty/Ert/devel/python/python/ert/cwrap/clib.py +++ b/ThirdParty/Ert/devel/python/python/ert/cwrap/clib.py @@ -46,12 +46,17 @@ # Passing None to the CDLL() function means to open a lib handle to # the current runnning process, i.e. like dlopen( NULL ). We must # special case this to avoid creating the bogus argument 'None.so'. -def lib_name(lib , platform_key): +def lib_name(lib , path = None): if lib is None: - so_name = None + return None else: + platform_key = platform.system().lower() so_name = "%s.%s" % (lib , so_extension[ platform_key ]) - return so_name + if path: + return os.path.join( path , so_name ) + else: + return so_name + @@ -73,15 +78,14 @@ def __load( lib_list, ert_prefix): error_list = {} dll = None - platform_key = platform.system().lower() for lib in lib_list: - so_name = lib_name( lib , platform_key ) + if ert_prefix: + lib_file = lib_name( lib , path = ert_lib_path ) + else: + lib_file = lib_name( lib ) + try: - if ert_prefix and so_name: - ert_lib = os.path.join(ert_lib_path , so_name) - dll = ctypes.CDLL(ert_lib, ctypes.RTLD_GLOBAL) - else: - dll = ctypes.CDLL(so_name , ctypes.RTLD_GLOBAL) + dll = ctypes.CDLL(lib_file , ctypes.RTLD_GLOBAL) return dll except Exception, exc: error_list[lib] = exc diff --git a/ThirdParty/Ert/devel/python/python/ert/cwrap/cwrap.py b/ThirdParty/Ert/devel/python/python/ert/cwrap/cwrap.py index d2f1bb19ce..6dd5ea59ca 100644 --- a/ThirdParty/Ert/devel/python/python/ert/cwrap/cwrap.py +++ b/ThirdParty/Ert/devel/python/python/ert/cwrap/cwrap.py @@ -73,8 +73,12 @@ def registerDefaultTypes(cls): """Registers the default available types for prototyping.""" cls.registerType("void", None) cls.registerType("void*", ctypes.c_void_p) + cls.registerType("uint", ctypes.c_uint) + cls.registerType("uint*", ctypes.POINTER(ctypes.c_uint)) cls.registerType("int", ctypes.c_int) cls.registerType("int*", ctypes.POINTER(ctypes.c_int)) + cls.registerType("int64", ctypes.c_int64) + cls.registerType("int64*", ctypes.POINTER(ctypes.c_int64)) cls.registerType("size_t", ctypes.c_size_t) cls.registerType("size_t*", ctypes.POINTER(ctypes.c_size_t)) cls.registerType("bool", ctypes.c_bool) diff --git a/ThirdParty/Ert/devel/python/python/ert/ecl/CMakeLists.txt b/ThirdParty/Ert/devel/python/python/ert/ecl/CMakeLists.txt index 18f8cbfae5..115dd9685c 100644 --- a/ThirdParty/Ert/devel/python/python/ert/ecl/CMakeLists.txt +++ b/ThirdParty/Ert/devel/python/python/ert/ecl/CMakeLists.txt @@ -1,29 +1,30 @@ set(PYTHON_SOURCES __init__.py ecl.py + ecl_3d_file.py + ecl_3dkw.py ecl_case.py ecl_default.py ecl_file.py - ecl_3d_file.py - ecl_init_file.py - ecl_restart_file.py ecl_grav.py ecl_grav_calc.py ecl_grid.py + ecl_init_file.py ecl_kw.py - ecl_3dkw.py ecl_npv.py ecl_region.py + ecl_restart_file.py ecl_rft.py ecl_rft_cell.py ecl_smspec_node.py ecl_subsidence.py ecl_sum.py + ecl_sum_keyword_vector.py ecl_sum_node.py + ecl_sum_tstep.py ecl_sum_vector.py ecl_util.py fortio.py - ecl_sum_keyword_vector.py ) if (BUILD_ERT) diff --git a/ThirdParty/Ert/devel/python/python/ert/ecl/__init__.py b/ThirdParty/Ert/devel/python/python/ert/ecl/__init__.py index a534e1d0b6..2b7d718e59 100644 --- a/ThirdParty/Ert/devel/python/python/ert/ecl/__init__.py +++ b/ThirdParty/Ert/devel/python/python/ert/ecl/__init__.py @@ -77,6 +77,7 @@ ECL_LIB = clib.ert_load("libecl") +from .ecl_sum_tstep import EclSumTStep from .ecl_sum import EclSum #, EclSumVector, EclSumNode, EclSMSPECNode from .ecl_sum_keyword_vector import EclSumKeyWordVector from .ecl_util import EclFileEnum, EclFileFlagEnum, EclPhaseEnum, EclTypeEnum, EclUtil diff --git a/ThirdParty/Ert/devel/python/python/ert/ecl/ecl.py b/ThirdParty/Ert/devel/python/python/ert/ecl/ecl.py index 02b4cc7f1e..5c41880c15 100644 --- a/ThirdParty/Ert/devel/python/python/ert/ecl/ecl.py +++ b/ThirdParty/Ert/devel/python/python/ert/ecl/ecl.py @@ -117,12 +117,8 @@ class default_wrapper(object): ecl_default = default_wrapper() -from .ecl_util import EclFileEnum, EclFileFlagEnum, EclPhaseEnum, EclTypeEnum, EclUtil - -#make enum values globally available in ert.ecl.ecl -for enum in EclFileEnum.enum_names: - globals()[enum] = getattr(EclFileEnum, enum) - +from .ecl_util import EclFileFlagEnum, EclPhaseEnum, EclTypeEnum, EclUtil + for enum in EclFileFlagEnum.enum_names: globals()[enum] = getattr(EclFileFlagEnum, enum) diff --git a/ThirdParty/Ert/devel/python/python/ert/ecl/ecl_file.py b/ThirdParty/Ert/devel/python/python/ert/ecl/ecl_file.py index 35a7f61893..e81e3d27c7 100644 --- a/ThirdParty/Ert/devel/python/python/ert/ecl/ecl_file.py +++ b/ThirdParty/Ert/devel/python/python/ert/ecl/ecl_file.py @@ -275,11 +275,11 @@ def select_restart_section( self, index = None , report_step = None , sim_time = """ OK = False - if report_step: + if not report_step is None: OK = cfunc.restart_block_step( self , report_step ) - elif sim_time: + elif not sim_time is None: OK = cfunc.restart_block_time( self , CTime( sim_time ) ) - elif index: + elif not index is None: OK = cfunc.restart_block_iselect( self, index ) else: raise TypeError("select_restart_section() requires either dtime or report_step argument - none given") diff --git a/ThirdParty/Ert/devel/python/python/ert/ecl/ecl_grid.py b/ThirdParty/Ert/devel/python/python/ert/ecl/ecl_grid.py index a2e62a9b64..9cd00974e1 100644 --- a/ThirdParty/Ert/devel/python/python/ert/ecl/ecl_grid.py +++ b/ThirdParty/Ert/devel/python/python/ert/ecl/ecl_grid.py @@ -121,8 +121,16 @@ def create(cls , specgrid , zcorn , coord , actnum , mapaxes = None ): return obj + @classmethod + def create_ref(cls , c_ptr , parent = None ): + obj = object.__new__( cls ) + obj.init_cref( c_ptr , parent ) + return obj + + @classmethod def create_rectangular(cls , dims , dV , actnum = None): + warnings.warn("The create_rectangular method is deprecated - use createRectangular( )") return cls.createRectangular( dims , dV , actnum ) @@ -1057,6 +1065,11 @@ def globalKWCopy(self, kw , default_value): else: raise ValueError("The input keyword must have nx*n*nz or nactive elements. Size:%d invalid" % len(kw)) + + def exportACTNUMKw(self): + actnum = EclKW.create("ACTNUM" , self.getGlobalSize() , EclTypeEnum.ECL_INT_TYPE) + cfunc.init_actnum( self , actnum.getDataPtr() ) + return actnum # 2. Creating a wrapper object around the libecl library, diff --git a/ThirdParty/Ert/devel/python/python/ert/ecl/ecl_kw.py b/ThirdParty/Ert/devel/python/python/ert/ecl/ecl_kw.py index d83d816bd5..981afd057d 100644 --- a/ThirdParty/Ert/devel/python/python/ert/ecl/ecl_kw.py +++ b/ThirdParty/Ert/devel/python/python/ert/ecl/ecl_kw.py @@ -775,8 +775,11 @@ def size(self): return cfunc.get_size( self ) def set_name( self , name ): + if len(name) > 8: + raise ValueError("Sorry: the name property must be max 8 characters long :-(") cfunc.set_header( self , name ) + def get_name( self ): return self.getName() @@ -1016,6 +1019,15 @@ def fixUninitialized(self , grid): cfunc.fix_uninitialized( self , dims[0] , dims[1], dims[2] , actnum.getDataPtr() ) + def getDataPtr(self): + if self.ecl_type == EclTypeEnum.ECL_INT_TYPE: + return cfunc.int_ptr( self ) + elif self.ecl_type == EclTypeEnum.ECL_FLOAT_TYPE: + return cfunc.float_ptr( self ) + elif self.ecl_type == EclTypeEnum.ECL_DOUBLE_TYPE: + return cfunc.double_ptr( self ) + else: + raise ValueError("Only numeric types can export data pointer") ################################################################# diff --git a/ThirdParty/Ert/devel/python/python/ert/ecl/ecl_sum.py b/ThirdParty/Ert/devel/python/python/ert/ecl/ecl_sum.py index a93dd9b57a..55b46b8e08 100644 --- a/ThirdParty/Ert/devel/python/python/ert/ecl/ecl_sum.py +++ b/ThirdParty/Ert/devel/python/python/ert/ecl/ecl_sum.py @@ -30,6 +30,7 @@ # index as the first argument and the key/key_index as second # argument. In the python code this order has been reversed. from ert.cwrap import BaseCClass, CWrapper, CFILE +from ert.ecl import EclSumTStep from ert.ecl.ecl_sum_vector import EclSumVector from ert.ecl.ecl_smspec_node import EclSMSPECNode from ert.util import StringList, CTime, DoubleVector, TimeVector, IntVector @@ -110,6 +111,7 @@ def __init__(self, load_case , join_string = ":" , include_restart = True): def writer(case , start_time , nx,ny,nz , fmt_output = False , unified = True , time_in_days = True , key_join_string = ":"): """ The writer is not generally usable. + @rtype: EclSum """ return EclSum.cNamespace().create_writer( case , fmt_output , unified , key_join_string , CTime(start_time) , time_in_days , nx , ny , nz) @@ -119,8 +121,9 @@ def addVariable(self , variable , wgname = None , num = 0 , unit = "None" , defa def addTStep(self , report_step , sim_days): - tstep = EclSum.cNamespace().add_tstep( self , report_step , sim_days ) - return tstep + """ @rtype: EclSumTStep """ + sim_seconds = sim_days * 24 * 60 * 60 + return EclSum.cNamespace().add_tstep(self, report_step, sim_seconds) def _initialize(self): @@ -973,7 +976,9 @@ def createPythonObject(cls, c_pointer): ################################################################# -# 2. Creating a wrapper object around the libecl library, + + +# 2. Creating a wrapper object around the libecl library, # registering the type map : ecl_kw <-> EclKW cwrapper = CWrapper(ECL_LIB) cwrapper.registerType( "ecl_sum" , EclSum ) @@ -1030,9 +1035,10 @@ def createPythonObject(cls, c_pointer): EclSum.cNamespace().create_well_list = cwrapper.prototype("stringlist_obj ecl_sum_alloc_well_list( ecl_sum , char* )") EclSum.cNamespace().create_group_list = cwrapper.prototype("stringlist_obj ecl_sum_alloc_group_list( ecl_sum , char* )") -EclSum.cNamespace().create_writer = cwrapper.prototype("ecl_sum_obj ecl_sum_alloc_writer( char* , bool , bool , char* , time_t , bool , int , int , int)") -EclSum.cNamespace().add_variable = cwrapper.prototype("void ecl_sum_add_var(ecl_sum , char* , char* , int , char*, double)") -EclSum.cNamespace().add_tstep = cwrapper.prototype("c_void_p ecl_sum_add_tstep(ecl_sum , int , double)") +EclSum.cNamespace().create_writer = cwrapper.prototype("ecl_sum_obj ecl_sum_alloc_writer( char* , bool , bool , char* , time_t , bool , int , int , int)") +EclSum.cNamespace().add_variable = cwrapper.prototype("void ecl_sum_add_var(ecl_sum , char* , char* , int , char*, double)") +EclSum.cNamespace().add_tstep = cwrapper.prototype("ecl_sum_tstep_ref ecl_sum_add_tstep(ecl_sum , int , double)") import ert.ecl.ecl_sum_keyword_vector -EclSum.cNamespace().dump_csv_line = cwrapper.prototype("void ecl_sum_dump_line_to_csv_file(ecl_sum , time_t , ecl_sum_vector, FILE)") +EclSum.cNamespace().dump_csv_line = cwrapper.prototype("void ecl_sum_dump_line_to_csv_file(ecl_sum , time_t , ecl_sum_vector, FILE)") +EclSum.cNamespace().get_smspec = cwrapper.prototype("void* ecl_sum_get_smspec(ecl_sum)") diff --git a/ThirdParty/Ert/devel/python/python/ert/ecl/ecl_sum_tstep.py b/ThirdParty/Ert/devel/python/python/ert/ecl/ecl_sum_tstep.py new file mode 100644 index 0000000000..34dcfd7eb8 --- /dev/null +++ b/ThirdParty/Ert/devel/python/python/ert/ecl/ecl_sum_tstep.py @@ -0,0 +1,56 @@ +from ert.cwrap import BaseCClass, CWrapper +from ert.ecl import ECL_LIB + + +class EclSumTStep(BaseCClass): + def __init__(self, report_step, mini_step, sim_days, smspec): + sim_seconds = sim_days * 24 * 60 * 60 + + c_pointer = EclSumTStep.cNamespace().alloc(report_step, mini_step, sim_seconds, smspec) + super(EclSumTStep, self).__init__(c_pointer) + + def getSimDays(self): + """ @rtype: double """ + return EclSumTStep.cNamespace().get_sim_days(self) + + def getReport(self): + """ @rtype: int """ + return EclSumTStep.cNamespace().get_report(self) + + def getMiniStep(self): + """ @rtype: int """ + return EclSumTStep.cNamespace().get_ministep(self) + + def __getitem__(self, key): + """ @rtype: double """ + if not key in self: + raise KeyError("Key '%s' is not available." % key) + + return EclSumTStep.cNamespace().get_from_key(self, key) + + def __setitem__(self, key, value): + if not key in self: + raise KeyError("Key '%s' is not available." % key) + + EclSumTStep.cNamespace().set_from_key(self, key, value) + + def __contains__(self, key): + return EclSumTStep.cNamespace().has_key(self, key) + + def free(self): + EclSumTStep.cNamespace().free(self) + + +cwrapper = CWrapper(ECL_LIB) +cwrapper.registerObjectType("ecl_sum_tstep", EclSumTStep) + +EclSumTStep.cNamespace().alloc = cwrapper.prototype("void* ecl_sum_tstep_alloc_new(int, int, float, void*)") +EclSumTStep.cNamespace().free = cwrapper.prototype("void ecl_sum_tstep_free(ecl_sum_tstep)") + +EclSumTStep.cNamespace().get_sim_days = cwrapper.prototype("double ecl_sum_tstep_get_sim_days(ecl_sum_tstep)") +EclSumTStep.cNamespace().get_report = cwrapper.prototype("int ecl_sum_tstep_get_report(ecl_sum_tstep)") +EclSumTStep.cNamespace().get_ministep = cwrapper.prototype("int ecl_sum_tstep_get_ministep(ecl_sum_tstep)") + +EclSumTStep.cNamespace().set_from_key = cwrapper.prototype("void ecl_sum_tstep_set_from_key(ecl_sum_tstep, char*, float)") +EclSumTStep.cNamespace().get_from_key = cwrapper.prototype("double ecl_sum_tstep_get_from_key(ecl_sum_tstep, char*)") +EclSumTStep.cNamespace().has_key = cwrapper.prototype("bool ecl_sum_tstep_has_key(ecl_sum_tstep)") \ No newline at end of file diff --git a/ThirdParty/Ert/devel/python/python/ert/ecl/ecl_util.py b/ThirdParty/Ert/devel/python/python/ert/ecl/ecl_util.py index 65ca98009c..650593c420 100644 --- a/ThirdParty/Ert/devel/python/python/ert/ecl/ecl_util.py +++ b/ThirdParty/Ert/devel/python/python/ert/ecl/ecl_util.py @@ -24,13 +24,37 @@ In addition to the enum definitions there are a few stateless functions from ecl_util.c which are not bound to any class type. """ -from ert.cwrap import create_enum, CWrapper, CWrapperNameSpace - +import ctypes +from ert.cwrap import create_enum, CWrapper, CWrapperNameSpace, BaseCEnum from ert.ecl import ECL_LIB +class EclFileEnum(BaseCEnum): + ECL_OTHER_FILE = None + ECL_RESTART_FILE = None + ECL_UNIFIED_RESTART_FILE = None + ECL_SUMMARY_FILE = None + ECL_UNIFIED_SUMMARY_FILE = None + ECL_GRID_FILE = None + ECL_EGRID_FILE = None + ECL_INIT_FILE = None + ECL_RFT_FILE = None + ECL_DATA_FILE = None + + +EclFileEnum.addEnum("ECL_OTHER_FILE", 0) +EclFileEnum.addEnum("ECL_RESTART_FILE", 1) +EclFileEnum.addEnum("ECL_UNIFIED_RESTART_FILE", 2) +EclFileEnum.addEnum("ECL_SUMMARY_FILE", 4) +EclFileEnum.addEnum("ECL_UNIFIED_SUMMARY_FILE", 8) +EclFileEnum.addEnum("ECL_SUMMARY_HEADER_FILE", 16) +EclFileEnum.addEnum("ECL_GRID_FILE", 32) +EclFileEnum.addEnum("ECL_EGRID_FILE", 64) +EclFileEnum.addEnum("ECL_INIT_FILE", 128) +EclFileEnum.addEnum("ECL_RFT_FILE", 256) +EclFileEnum.addEnum("ECL_DATA_FILE", 512) + +EclFileEnum.registerEnum(ECL_LIB, "ecl_file_enum") -# ecl_file_enum from ecl_util.h -EclFileEnum = create_enum(ECL_LIB, "ecl_util_file_enum_iget", "ecl_file_enum") # ecl_phase_enum from ecl_util.h EclPhaseEnum = create_enum(ECL_LIB, "ecl_util_phase_enum_iget", "ecl_phase_enum") @@ -42,16 +66,16 @@ EclFileFlagEnum = create_enum(ECL_LIB, "ecl_util_file_flags_enum_iget", "ecl_file_flag_enum") - - cwrapper = CWrapper(ECL_LIB) cfunc = CWrapperNameSpace("ecl_util") cfunc.get_num_cpu = cwrapper.prototype("int ecl_util_get_num_cpu( char* )") -cfunc.get_file_type = cwrapper.prototype("int ecl_util_get_file_type( char* , bool* , int*)") +cfunc.get_file_type = cwrapper.prototype("ecl_file_enum ecl_util_get_file_type( char* , bool* , int*)") cfunc.get_type_name = cwrapper.prototype("char* ecl_util_get_type_name( int )") cfunc.get_start_date = cwrapper.prototype("time_t ecl_util_get_start_date( char* )") + + class EclUtil(object): @staticmethod def get_num_cpu( datafile ): @@ -69,8 +93,9 @@ def get_file_type( filename ): """ Will inspect an ECLIPSE filename and return an integer type flag. """ - return cfunc.get_file_type(filename, None, None) - + file_type , fmt , step = EclUtil.inspectExtension( filename ) + return file_type + @staticmethod def type_name(ecl_type): return cfunc.get_type_name(ecl_type) @@ -79,7 +104,24 @@ def type_name(ecl_type): def get_start_date(datafile): return cfunc.get_start_date(datafile).datetime() + @staticmethod + def inspectExtension( filename ): + """Will inspect an ECLIPSE filename and return a tuple consisting of + file type (EclFileEnum), a bool for formatted or not, and an + integer for the step number. + """ + fmt_file = ctypes.c_bool() + report_step = ctypes.c_int(-1) + file_type = cfunc.get_file_type(filename, ctypes.byref(fmt_file) , ctypes.byref(report_step)) + if report_step.value == -1: + step = None + else: + step = report_step.value + + return (file_type , fmt_file.value , step) + + get_num_cpu = EclUtil.get_num_cpu get_file_type = EclUtil.get_file_type diff --git a/ThirdParty/Ert/devel/python/python/ert/ecl/faults/layer.py b/ThirdParty/Ert/devel/python/python/ert/ecl/faults/layer.py index 95e528a76f..088762dbcb 100644 --- a/ThirdParty/Ert/devel/python/python/ert/ecl/faults/layer.py +++ b/ThirdParty/Ert/devel/python/python/ert/ecl/faults/layer.py @@ -157,7 +157,6 @@ def addFaultBarrier(self , fault , K , link_segments = True ): def addIJBarrier(self , ij_list): if len(ij_list) < 2: - print "ij_list:%s" % ij_list raise ValueError("Must have at least two (i,j) points") nx = self.getNX() @@ -227,6 +226,10 @@ def cellsEqual(self , value): return ij_list + def countEqual(self , value): + return Layer.cNamespace().count_equal( self , value ) + + cwrapper = CWrapper(ECL_LIB) CWrapper.registerObjectType("layer", Layer) @@ -248,5 +251,6 @@ def cellsEqual(self , value): Layer.cNamespace().cell_sum = cwrapper.prototype("int layer_get_cell_sum(layer)") Layer.cNamespace().update_connected = cwrapper.prototype("void layer_update_connected_cells(layer,int,int,int,int)") Layer.cNamespace().cells_equal = cwrapper.prototype("void layer_cells_equal( layer, int,int_vector,int_vector)") +Layer.cNamespace().count_equal = cwrapper.prototype("int layer_count_equal( layer, int)") Layer.cNamespace().active_cell = cwrapper.prototype("bool layer_iget_active( layer, int,int)") Layer.cNamespace().update_active = cwrapper.prototype("bool layer_update_active( layer, ecl_grid , int)") diff --git a/ThirdParty/Ert/devel/python/python/ert/enkf/CMakeLists.txt b/ThirdParty/Ert/devel/python/python/ert/enkf/CMakeLists.txt index ecec6ee9c5..75db4dcdbf 100644 --- a/ThirdParty/Ert/devel/python/python/ert/enkf/CMakeLists.txt +++ b/ThirdParty/Ert/devel/python/python/ert/enkf/CMakeLists.txt @@ -18,9 +18,13 @@ set(PYTHON_SOURCES ert_template.py ert_templates.py ert_workflow_list.py + key_manager.py local_config.py + local_dataset.py + local_ministep.py local_obsdata.py local_obsdata_node.py + local_updatestep.py meas_block.py meas_data.py model_config.py @@ -37,7 +41,7 @@ set(PYTHON_SOURCES summary_key_set.py ) -add_python_package("python.ert.enkf" ${PYTHON_INSTALL_PREFIX}/ert/enkf "${PYTHON_SOURCES}" True) +add_python_package("python.ert.enkf" ${PYTHON_INSTALL_PREFIX}/ert/enkf "${PYTHON_SOURCES}" True) add_subdirectory(data) add_subdirectory(enums) diff --git a/ThirdParty/Ert/devel/python/python/ert/enkf/__init__.py b/ThirdParty/Ert/devel/python/python/ert/enkf/__init__.py index 9aa0b9dcb4..6b1f75231d 100644 --- a/ThirdParty/Ert/devel/python/python/ert/enkf/__init__.py +++ b/ThirdParty/Ert/devel/python/python/ert/enkf/__init__.py @@ -44,8 +44,12 @@ from .active_list import ActiveList from .data import * +from .local_dataset import LocalDataset from .local_obsdata_node import LocalObsdataNode from .local_obsdata import LocalObsdata +from .local_ministep import LocalMinistep +from .local_updatestep import LocalUpdateStep + from .observations import * from .obs_block import ObsBlock diff --git a/ThirdParty/Ert/devel/python/python/ert/enkf/ecl_config.py b/ThirdParty/Ert/devel/python/python/ert/enkf/ecl_config.py index fe5fe40327..f895155081 100644 --- a/ThirdParty/Ert/devel/python/python/ert/enkf/ecl_config.py +++ b/ThirdParty/Ert/devel/python/python/ert/enkf/ecl_config.py @@ -13,6 +13,8 @@ # # See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> # for more details. +from warnings import warn + from ert.cwrap import BaseCClass, CWrapper from ert.enkf import ENKF_LIB from ert.util import StringList @@ -67,7 +69,13 @@ def validateGridFile(self , gridfile): return EclConfig.cNamespace().validate_gridfile(self, gridfile) def get_grid(self): - return EclConfig.cNamespace().get_grid(self) + warning_message = "The method get_grid() is deprecated. Use getGrid() instead" + warn(warning_message) + return self.getGrid( ) + + def getGrid(self): + c_ptr = EclConfig.cNamespace().get_grid(self) + return EclGrid.create_ref( c_ptr ) #----------------------------------------------------------------- diff --git a/ThirdParty/Ert/devel/python/python/ert/enkf/enkf_main.py b/ThirdParty/Ert/devel/python/python/ert/enkf/enkf_main.py index 4c50d5cfb1..30f1a38bdb 100644 --- a/ThirdParty/Ert/devel/python/python/ert/enkf/enkf_main.py +++ b/ThirdParty/Ert/devel/python/python/ert/enkf/enkf_main.py @@ -17,6 +17,7 @@ from ert.enkf import AnalysisConfig, EclConfig, EnkfObs, EnKFState, LocalConfig, ModelConfig, EnsembleConfig, PlotConfig, SiteConfig, ENKF_LIB, EnkfSimulationRunner, EnkfFsManager, ErtWorkflowList, PostSimulationHook from ert.enkf.enums import EnkfInitModeEnum +from ert.enkf.key_manager import KeyManager from ert.util import SubstitutionList, Log @@ -36,6 +37,7 @@ def __init__(self, model_config, strict=True): self.__fs_manager = EnkfFsManager(self) + self.__key_manager = KeyManager(self) @staticmethod def loadSiteConfig(): @@ -100,10 +102,13 @@ def logh(self): """ @rtype: Log """ return EnKFMain.cNamespace().get_logh(self).setParent(self) - def local_config(self): + def getLocalConfig(self): """ @rtype: LocalConfig """ - return EnKFMain.cNamespace().get_local_config(self).setParent(self) - + config = EnKFMain.cNamespace().get_local_config(self).setParent(self) + config.initAttributes( self.ensembleConfig() , self.getObservations() , self.eclConfig().get_grid() ) + return config + + def siteConfig(self): """ @rtype: SiteConfig """ return EnKFMain.cNamespace().get_site_config(self).setParent(self) @@ -200,6 +205,10 @@ def getEnkfFsManager(self): """ @rtype: EnkfFsManager """ return self.__fs_manager + def getKeyManager(self): + """ :rtype: KeyManager """ + return self.__key_manager + def getWorkflowList(self): """ @rtype: ErtWorkflowList """ return EnKFMain.cNamespace().get_workflow_list(self).setParent(self) diff --git a/ThirdParty/Ert/devel/python/python/ert/enkf/enkf_obs.py b/ThirdParty/Ert/devel/python/python/ert/enkf/enkf_obs.py index bef5c98386..f4cd631a49 100644 --- a/ThirdParty/Ert/devel/python/python/ert/enkf/enkf_obs.py +++ b/ThirdParty/Ert/devel/python/python/ert/enkf/enkf_obs.py @@ -135,6 +135,8 @@ def getObservationAndMeasureData(self, fs, local_obsdata, state, active_list, me def scaleCorrelatedStd( self , fs , local_obsdata , active_list): return EnkfObs.cNamespace().scale_correlated_std( self , fs , active_list , local_obsdata ) + def localScaleStd( self , local_obsdata , scale_factor): + return EnkfObs.cNamespace().local_scale_std( self , local_obsdata, scale_factor) def load(self , config_file): if not os.path.isfile( config_file ): @@ -170,3 +172,6 @@ def free(self): EnkfObs.cNamespace().get_obs_and_measure_data = cwrapper.prototype("void enkf_obs_get_obs_and_measure_data(enkf_obs, enkf_fs, local_obsdata, enkf_state_type_enum, int_vector, meas_data, obs_data)") EnkfObs.cNamespace().create_all_active_obs = cwrapper.prototype("local_obsdata_obj enkf_obs_alloc_all_active_local_obs( enkf_obs , char*)"); EnkfObs.cNamespace().scale_correlated_std = cwrapper.prototype("double enkf_obs_scale_correlated_std( enkf_obs , enkf_fs , int_vector , local_obsdata)"); +EnkfObs.cNamespace().local_scale_std = cwrapper.prototype("void enkf_obs_local_scale_std( enkf_obs , local_obsdata , double)"); + + diff --git a/ThirdParty/Ert/devel/python/python/ert/enkf/export/custom_kw_collector.py b/ThirdParty/Ert/devel/python/python/ert/enkf/export/custom_kw_collector.py index 74116f2f18..30f78b2067 100644 --- a/ThirdParty/Ert/devel/python/python/ert/enkf/export/custom_kw_collector.py +++ b/ThirdParty/Ert/devel/python/python/ert/enkf/export/custom_kw_collector.py @@ -1,6 +1,7 @@ from pandas import DataFrame from ert.enkf import ErtImplType, EnKFMain, EnkfFs, RealizationStateEnum, CustomKWConfig, EnkfNode, NodeId, \ EnkfStateType +from ert.enkf.key_manager import KeyManager class CustomKWCollector(object): @@ -8,19 +9,8 @@ class CustomKWCollector(object): @staticmethod def getAllCustomKWKeys(ert): """ @rtype: list of str """ - custom_kw_keys = ert.ensembleConfig().getKeylistFromImplType(ErtImplType.CUSTOM_KW) - custom_kw_keys = [key for key in custom_kw_keys] - - custom_kw_list = [] - for name in custom_kw_keys: - enkf_config_node = ert.ensembleConfig().getNode(name) - custom_kw_config = enkf_config_node.getModelConfig() - assert isinstance(custom_kw_config, CustomKWConfig) - - for key in custom_kw_config: - custom_kw_list.append("%s:%s" % (name, key)) - - return custom_kw_list + key_manager = KeyManager(ert) + return key_manager.customKwKeys() @staticmethod def groupKeys(keys): diff --git a/ThirdParty/Ert/devel/python/python/ert/enkf/export/gen_data_collector.py b/ThirdParty/Ert/devel/python/python/ert/enkf/export/gen_data_collector.py index 9ee2127d11..867483999c 100644 --- a/ThirdParty/Ert/devel/python/python/ert/enkf/export/gen_data_collector.py +++ b/ThirdParty/Ert/devel/python/python/ert/enkf/export/gen_data_collector.py @@ -8,9 +8,7 @@ class GenDataCollector(object): - @staticmethod - def loadGenData(ert, case_name, key, report_step): """@type ert: EnKFMain @type case_name: str @@ -36,10 +34,12 @@ def loadGenData(ert, case_name, key, report_step): data_array.fill( numpy.nan ) for realization_index, realization_number in enumerate(realizations): realization_vector = ensemble_data[realization_number] - for data_index in range(data_size): - if active_mask[data_index]: - value = realization_vector[data_index] - data_array[data_index][realization_index] = value + + if len(realization_vector) > 0: # Must check because of a bug changing between different case with different states + for data_index in range(data_size): + if active_mask[data_index]: + value = realization_vector[data_index] + data_array[data_index][realization_index] = value return DataFrame( data = data_array , columns = realizations ) diff --git a/ThirdParty/Ert/devel/python/python/ert/enkf/export/gen_kw_collector.py b/ThirdParty/Ert/devel/python/python/ert/enkf/export/gen_kw_collector.py index f4d40acaaf..00bc1417f5 100644 --- a/ThirdParty/Ert/devel/python/python/ert/enkf/export/gen_kw_collector.py +++ b/ThirdParty/Ert/devel/python/python/ert/enkf/export/gen_kw_collector.py @@ -2,6 +2,7 @@ from pandas import DataFrame, MultiIndex import numpy from ert.enkf import ErtImplType, EnKFMain, EnkfFs, RealizationStateEnum, GenKwConfig +from ert.enkf.key_manager import KeyManager from ert.enkf.plot_data import EnsemblePlotGenKW from ert.util import BoolVector @@ -20,22 +21,8 @@ def createActiveList(ert, fs): @staticmethod def getAllGenKwKeys(ert): """ @rtype: list of str """ - gen_kw_keys = ert.ensembleConfig().getKeylistFromImplType(ErtImplType.GEN_KW) - gen_kw_keys = [key for key in gen_kw_keys] - - gen_kw_list = [] - for key in gen_kw_keys: - enkf_config_node = ert.ensembleConfig().getNode(key) - gen_kw_config = enkf_config_node.getModelConfig() - assert isinstance(gen_kw_config, GenKwConfig) - - for keyword_index, keyword in enumerate(gen_kw_config): - gen_kw_list.append("%s:%s" % (key, keyword)) - - if gen_kw_config.shouldUseLogScale(keyword_index): - gen_kw_list.append("LOG10_%s:%s" % (key, keyword)) - - return gen_kw_list + key_manager = KeyManager(ert) + return key_manager.genKwKeys() @staticmethod def loadAllGenKwData(ert, case_name, keys=None): diff --git a/ThirdParty/Ert/devel/python/python/ert/enkf/export/misfit_collector.py b/ThirdParty/Ert/devel/python/python/ert/enkf/export/misfit_collector.py index 700b7e57f1..275118488d 100644 --- a/ThirdParty/Ert/devel/python/python/ert/enkf/export/misfit_collector.py +++ b/ThirdParty/Ert/devel/python/python/ert/enkf/export/misfit_collector.py @@ -1,6 +1,7 @@ from pandas import DataFrame import numpy from ert.enkf import EnKFMain, EnkfFs, RealizationStateEnum, EnkfStateType +from ert.enkf.key_manager import KeyManager from ert.util import BoolVector @@ -16,16 +17,10 @@ def createActiveList(ert, fs): return [iens for iens in active_list] @staticmethod - def getAllMisfitKeys(ert): + def getAllMisfitKeys(ert, sort_keys=True): """ @rtype: list of str """ - keys = [] - for obs_vector in ert.getObservations(): - key = "MISFIT:%s" % obs_vector.getObservationKey() - keys.append(key) - - keys.append("MISFIT:TOTAL") - - return keys + key_manager = KeyManager(ert) + return key_manager.misfitKeys(sort_keys=sort_keys) @staticmethod def loadAllMisfitData(ert, case_name): @@ -37,7 +32,7 @@ def loadAllMisfitData(ert, case_name): fs = ert.getEnkfFsManager().getFileSystem(case_name) realizations = MisfitCollector.createActiveList(ert, fs) - misfit_keys = MisfitCollector.getAllMisfitKeys(ert) + misfit_keys = MisfitCollector.getAllMisfitKeys(ert, sort_keys=False) misfit_sum_index = len(misfit_keys) - 1 misfit_array = numpy.empty(shape=(len(misfit_keys), len(realizations)), dtype=numpy.float64) diff --git a/ThirdParty/Ert/devel/python/python/ert/enkf/export/summary_collector.py b/ThirdParty/Ert/devel/python/python/ert/enkf/export/summary_collector.py index b82053c1b4..322ad3d946 100644 --- a/ThirdParty/Ert/devel/python/python/ert/enkf/export/summary_collector.py +++ b/ThirdParty/Ert/devel/python/python/ert/enkf/export/summary_collector.py @@ -1,6 +1,7 @@ from pandas import DataFrame, MultiIndex import numpy from ert.enkf import ErtImplType, EnKFMain, EnkfFs, RealizationStateEnum +from ert.enkf.key_manager import KeyManager from ert.enkf.plot_data import EnsemblePlotData from ert.util import BoolVector @@ -19,8 +20,8 @@ def createActiveList(ert, fs): @staticmethod def getAllSummaryKeys(ert): """ @rtype: list of str """ - keys = ert.ensembleConfig().getKeylistFromImplType(ErtImplType.SUMMARY) - return sorted([key for key in keys], key=lambda k : k.lower()) + key_manager = KeyManager(ert) + return key_manager.summaryKeys() @staticmethod def loadAllSummaryData(ert, case_name, keys=None): diff --git a/ThirdParty/Ert/devel/python/python/ert/enkf/export/summary_observation_collector.py b/ThirdParty/Ert/devel/python/python/ert/enkf/export/summary_observation_collector.py index c434f62ddf..7eb9df6f31 100644 --- a/ThirdParty/Ert/devel/python/python/ert/enkf/export/summary_observation_collector.py +++ b/ThirdParty/Ert/devel/python/python/ert/enkf/export/summary_observation_collector.py @@ -1,6 +1,7 @@ from pandas import DataFrame, MultiIndex import numpy from ert.enkf import ErtImplType, EnKFMain, EnkfFs, RealizationStateEnum, EnkfObservationImplementationType +from ert.enkf.key_manager import KeyManager from ert.enkf.plot_data import EnsemblePlotData from ert.util import BoolVector @@ -13,10 +14,8 @@ def getAllObservationKeys(ert): @type ert: EnKFMain @rtype: list of str """ - ensemble_config = ert.ensembleConfig() - keys = sorted([key for key in ensemble_config.getKeylistFromImplType(ErtImplType.SUMMARY)]) - observation_keys = [key for key in keys if len(ensemble_config.getNode(key).getObservationKeys()) > 0] - return observation_keys + key_manager = KeyManager(ert) + return key_manager.summaryKeysWithObservations() @staticmethod def loadObservationData(ert, case_name, keys=None): diff --git a/ThirdParty/Ert/devel/python/python/ert/enkf/key_manager.py b/ThirdParty/Ert/devel/python/python/ert/enkf/key_manager.py new file mode 100644 index 0000000000..2331ce5080 --- /dev/null +++ b/ThirdParty/Ert/devel/python/python/ert/enkf/key_manager.py @@ -0,0 +1,154 @@ +from ert.enkf import ErtImplType, GenKwConfig, CustomKWConfig + + +class KeyManager(object): + + def __init__(self, ert): + super(KeyManager, self).__init__() + """ + @type ert: ert.enkf.EnKFMain + """ + self.__ert = ert + + self.__all_keys = None + self.__all_keys_with_observations = None + self.__summary_keys = None + self.__summary_keys_with_observations = None + self.__gen_data_keys = None + self.__gen_kw_keys = None + self.__custom_kw_keys = None + self.__misfit_keys = None + + + def ert(self): + """ :rtype: ert.enkf.EnKFMain """ + return self.__ert + + def ensembleConfig(self): + """ :rtype: ert.enkf.EnsembleConfig """ + return self.ert().ensembleConfig() + + def summaryKeys(self): + """ :rtype: list of str """ + if self.__summary_keys is None: + self.__summary_keys = sorted([key for key in self.ensembleConfig().getKeylistFromImplType(ErtImplType.SUMMARY)], key=lambda k : k.lower()) + + return self.__summary_keys + + def summaryKeysWithObservations(self): + """ :rtype: list of str """ + if self.__summary_keys_with_observations is None: + self.__summary_keys_with_observations = sorted([key for key in self.summaryKeys() if len(self.ensembleConfig().getNode(key).getObservationKeys()) > 0], key=lambda k : k.lower()) + + return self.__summary_keys_with_observations + + def genKwKeys(self): + """ :rtype: list of str """ + if self.__gen_kw_keys is None: + gen_kw_keys = self.ert().ensembleConfig().getKeylistFromImplType(ErtImplType.GEN_KW) + gen_kw_keys = [key for key in gen_kw_keys] + + gen_kw_list = [] + for key in gen_kw_keys: + enkf_config_node = self.ert().ensembleConfig().getNode(key) + gen_kw_config = enkf_config_node.getModelConfig() + assert isinstance(gen_kw_config, GenKwConfig) + + for keyword_index, keyword in enumerate(gen_kw_config): + gen_kw_list.append("%s:%s" % (key, keyword)) + + if gen_kw_config.shouldUseLogScale(keyword_index): + gen_kw_list.append("LOG10_%s:%s" % (key, keyword)) + + self.__gen_kw_keys = sorted(gen_kw_list, key=lambda k : k.lower()) + + return self.__gen_kw_keys + + + def customKwKeys(self): + """ :rtype: list of str """ + if self.__custom_kw_keys is None: + custom_kw_keys = self.ert().ensembleConfig().getKeylistFromImplType(ErtImplType.CUSTOM_KW) + + keys = [] + for name in custom_kw_keys: + enkf_config_node = self.ert().ensembleConfig().getNode(name) + custom_kw_config = enkf_config_node.getModelConfig() + assert isinstance(custom_kw_config, CustomKWConfig) + + for key in custom_kw_config: + keys.append("%s:%s" % (name, key)) + + self.__custom_kw_keys = sorted([key for key in keys], key=lambda k : k.lower()) + + return self.__custom_kw_keys + + + def genDataKeys(self): + """ :rtype: list of str """ + if self.__gen_data_keys is None: + gen_data_keys = self.ert().ensembleConfig().getKeylistFromImplType(ErtImplType.GEN_DATA) + gen_data_list = [] + for key in gen_data_keys: + enkf_config_node = self.ert().ensembleConfig().getNode(key) + gen_data_config = enkf_config_node.getDataModelConfig() + + for report_step in range(self.ert().getHistoryLength() + 1): + if gen_data_config.hasReportStep(report_step): + gen_data_list.append("%s@%d" % (key, report_step)) + self.__gen_data_keys = sorted(gen_data_list, key=lambda k : k.lower()) + + return self.__gen_data_keys + + def misfitKeys(self, sort_keys=True): + """ @rtype: list of str """ + if self.__misfit_keys is None: + keys = [] + for obs_vector in self.ert().getObservations(): + key = "MISFIT:%s" % obs_vector.getObservationKey() + keys.append(key) + + keys.append("MISFIT:TOTAL") + + self.__misfit_keys = sorted(keys, key=lambda k : k.lower()) if sort_keys else keys + + return self.__misfit_keys + + + def allDataTypeKeys(self): + """ :rtype: list of str """ + if self.__all_keys is None: + self.__all_keys = self.summaryKeys() + self.genKwKeys() + self.customKwKeys() + self.genDataKeys() + + return self.__all_keys + + def allDataTypeKeysWithObservations(self): + """ :rtype: list of str """ + if self.__all_keys_with_observations is None: + self.__all_keys_with_observations = self.summaryKeysWithObservations() + + return self.__all_keys_with_observations + + def isKeyWithObservations(self, key): + """ :rtype: bool """ + return key in self.allDataTypeKeysWithObservations() + + def isSummaryKey(self, key): + """ :rtype: bool """ + return key in self.summaryKeys() + + def isGenKwKey(self, key): + """ :rtype: bool """ + return key in self.genKwKeys() + + def isCustomKwKey(self, key): + """ :rtype: bool """ + return key in self.customKwKeys() + + def isGenDataKey(self, key): + """ :rtype: bool """ + return key in self.genDataKeys() + + def isMisfitKey(self, key): + """ :rtype: bool """ + return key in self.misfitKeys() \ No newline at end of file diff --git a/ThirdParty/Ert/devel/python/python/ert/enkf/local_config.py b/ThirdParty/Ert/devel/python/python/ert/enkf/local_config.py index 3024634f33..2fed30687a 100644 --- a/ThirdParty/Ert/devel/python/python/ert/enkf/local_config.py +++ b/ThirdParty/Ert/devel/python/python/ert/enkf/local_config.py @@ -14,36 +14,170 @@ # See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> # for more details. from ert.cwrap import BaseCClass, CWrapper -from ert.enkf import ENKF_LIB - -from ert.util import StringList +from ert.enkf import ENKF_LIB, LocalUpdateStep +from ert.enkf.local_ministep import LocalMinistep class LocalConfig(BaseCClass): + def __init__(self): raise NotImplementedError("Class can not be instantiated directly!") + + + # The LocalConfig class is created as a reference to an existing + # underlying C structure by the method + # EnkFMain.local_config(). When the pointer to the C + # local_config_type object has been properly wrapped we 'decorate' + # the Python object with references to the ensemble_config , + # observations and grid. + # + # This implies that the Python object LocalConfig is richer than + # the underlying C object local_config_type; the extra attributes + # are only used for validation. + + def initAttributes(self , ensemble_config , obs , grid): + self.ensemble_config = ensemble_config + self.obs = obs + self.grid = grid + + + def __getObservations(self): + return self.obs + + def __getEnsembleConfig(self): + return self.ensemble_config + + def getGrid(self): + # The grid can be None + return self.grid + + + def free(self): + LocalConfig.cNamespace().free(self) + + def clear(self): + LocalConfig.cNamespace().clear(self) - def get_config_files(self): + + def getConfigFiles(self): """ @rtype: StringList """ return LocalConfig.cNamespace().get_config_files(self).setParent(self) - def clear_config_files(self): + def clearConfigFiles(self): LocalConfig.cNamespace().clear_config_files(self) - def add_config_file(self, filename): + def addConfigFile(self, filename): + assert isinstance(filename, str) LocalConfig.cNamespace().add_config_file(self, filename) + + def createMinistep(self, mini_step_key): + """ @rtype: Ministep """ + assert isinstance(mini_step_key, str) + LocalConfig.cNamespace().create_ministep(self, mini_step_key) + return self.getMinistep(mini_step_key) + + def createObsdata(self, obsset_key): + """ @rtype: Obsdata """ + assert isinstance(obsset_key, str) + LocalConfig.cNamespace().create_obsdata(self, obsset_key) + obsdata = self.getObsdata(obsset_key) + obsdata.initObservations( self.__getObservations() ) + return obsdata + + + def copyObsdata(self, src_key, target_key): + """ @rtype: Obsdata """ + assert isinstance(src_key, str) + assert isinstance(target_key, str) + obsdata = LocalConfig.cNamespace().copy_obsdata(self, src_key, target_key) + obsdata.initObservations( self.__getObservations() ) + return obsdata + + + def createDataset(self, dataset_key): + """ @rtype: Dataset """ + assert isinstance(dataset_key, str) + LocalConfig.cNamespace().create_dataset(self, dataset_key) + data = self.getDataset(dataset_key) + data.initEnsembleConfig( self.__getEnsembleConfig() ) + return data + + + def copyDataset(self, src_key, target_key): + """ @rtype: Dataset """ + assert isinstance(src_key, str) + assert isinstance(target_key, str) + data = LocalConfig.cNamespace().copy_dataset(self, src_key, target_key) + data.initEnsembleConfig( self.__getEnsembleConfig() ) + return data + + + def getUpdatestep(self): + """ @rtype: UpdateStep """ + return LocalConfig.cNamespace().get_updatestep(self) - def free(self): - LocalConfig.cNamespace().free(self) + def getMinistep(self, mini_step_key): + """ @rtype: Ministep """ + assert isinstance(mini_step_key, str) + return LocalConfig.cNamespace().get_ministep(self, mini_step_key) + + def getObsdata(self, obsset_key): + """ @rtype: Obsdata """ + assert isinstance(obsset_key, str) + return LocalConfig.cNamespace().get_obsdata(self, obsset_key) + + def getDataset(self, dataset_key): + """ @rtype: Dataset """ + assert isinstance(dataset_key, str) + return LocalConfig.cNamespace().get_dataset(self, dataset_key) + + + def attachMinistep(self, update_step, mini_step): + assert isinstance(mini_step, LocalMinistep) + assert isinstance(update_step, LocalUpdateStep) + LocalConfig.cNamespace().attach_ministep(update_step, mini_step) + + def writeLocalConfigFile(self, filename): + assert isinstance(filename, str) + LocalConfig.cNamespace().write_local_config_file(self, filename) + + + def writeSummaryFile(self, filename): + """ + Writes a summary of the local config object + The summary contains the Obsset with their respective + number of observations and the Datasets with the number of active indices + """ + assert isinstance(filename, str) + LocalConfig.cNamespace().write_local_config_summary_file(self, filename) + cwrapper = CWrapper(ENKF_LIB) -cwrapper.registerType("local_config", LocalConfig) -cwrapper.registerType("local_config_obj", LocalConfig.createPythonObject) -cwrapper.registerType("local_config_ref", LocalConfig.createCReference) - -LocalConfig.cNamespace().free = cwrapper.prototype("void local_config_free( local_config )") -LocalConfig.cNamespace().get_config_files = cwrapper.prototype("stringlist_ref local_config_get_config_files( local_config )") -LocalConfig.cNamespace().clear_config_files = cwrapper.prototype("void local_config_clear_config_files( local_config )") -LocalConfig.cNamespace().add_config_file = cwrapper.prototype("void local_config_add_config_file( local_config , char*)") +cwrapper.registerObjectType("local_config", LocalConfig) + +LocalConfig.cNamespace().free = cwrapper.prototype("void local_config_free( local_config )") +LocalConfig.cNamespace().clear = cwrapper.prototype("void local_config_clear( local_config )") +LocalConfig.cNamespace().get_config_files = cwrapper.prototype("stringlist_ref local_config_get_config_files( local_config )") +LocalConfig.cNamespace().clear_config_files = cwrapper.prototype("void local_config_clear_config_files( local_config )") +LocalConfig.cNamespace().add_config_file = cwrapper.prototype("void local_config_add_config_file( local_config , char*)") +LocalConfig.cNamespace().get_updatestep = cwrapper.prototype("local_updatestep_ref local_config_get_updatestep( local_config )") + +LocalConfig.cNamespace().get_ministep = cwrapper.prototype("local_ministep_ref local_config_get_ministep( local_config, char*)") +LocalConfig.cNamespace().create_ministep = cwrapper.prototype("void local_config_alloc_ministep( local_config, char*)") +LocalConfig.cNamespace().attach_ministep = cwrapper.prototype("void local_updatestep_add_ministep( local_updatestep, local_ministep)") + +LocalConfig.cNamespace().get_obsdata = cwrapper.prototype("local_obsdata_ref local_config_get_obsdata( local_config, char*)") +LocalConfig.cNamespace().create_obsdata = cwrapper.prototype("void local_config_alloc_obsset( local_config, char*)") +LocalConfig.cNamespace().copy_obsdata = cwrapper.prototype("local_obsdata_ref local_config_alloc_obsdata_copy( local_config, char*, char*)") + +LocalConfig.cNamespace().get_dataset = cwrapper.prototype("local_dataset_ref local_config_get_dataset( local_config, char*)") +LocalConfig.cNamespace().create_dataset = cwrapper.prototype("void local_config_alloc_dataset( local_config, char*)") +LocalConfig.cNamespace().copy_dataset = cwrapper.prototype("local_dataset_ref local_config_alloc_dataset_copy( local_config, char*, char*)") + +LocalConfig.cNamespace().write_local_config_file = cwrapper.prototype("void local_config_fprintf( local_config, char*)") +LocalConfig.cNamespace().write_local_config_summary_file = cwrapper.prototype("void local_config_summary_fprintf( local_config, char*)") + + + diff --git a/ThirdParty/Ert/devel/python/python/ert/enkf/local_dataset.py b/ThirdParty/Ert/devel/python/python/ert/enkf/local_dataset.py new file mode 100644 index 0000000000..be6c8ebb1e --- /dev/null +++ b/ThirdParty/Ert/devel/python/python/ert/enkf/local_dataset.py @@ -0,0 +1,94 @@ +from ert.cwrap import BaseCClass, CWrapper +from ert.enkf import ENKF_LIB +from ert.ecl import EclRegion + +class LocalDataset(BaseCClass): + + def __init__(self, name): + raise NotImplementedError("Class can not be instantiated directly!") + + + def initEnsembleConfig(self , config): + self.ensemble_config = config + + + def __len__(self): + """ @rtype: int """ + return LocalDataset.cNamespace().size(self) + + def __contains__(self , key): + """ @rtype: bool """ + return LocalDataset.cNamespace().has_key(self, key) + + def __delitem__(self, key): + assert isinstance(key, str) + if key in self: + LocalDataset.cNamespace().del_node(self, key) + else: + raise KeyError("Unknown key:%s" % key) + + def getName(self): + """ @rtype: str """ + return LocalDataset.cNamespace().name(self) + + def addNode(self, key): + assert isinstance(key, str) + if key in self.ensemble_config: + if not LocalDataset.cNamespace().has_key(self, key): + LocalDataset.cNamespace().add_node(self, key) + else: + raise KeyError("Tried to add existing data key:%s " % key) + else: + raise KeyError("Tried to add data key:%s - not in ensemble" % key) + + + def addNodeWithIndex(self, key, index): + assert isinstance(key, str) + assert isinstance(index, int) + + self.addNode( key ) + active_list = self.getActiveList(key) + active_list.addActiveIndex(index) + + + def addField(self, key, ecl_region): + assert isinstance(key, str) + assert isinstance(ecl_region, EclRegion) + + self.addNode( key ) + active_list = self.getActiveList(key) + active_region = ecl_region.getActiveList() + for i in active_region: + active_list.addActiveIndex(i) + + + def getActiveList(self, key): + """ @rtype: ActiveList """ + if key in self: + return LocalDataset.cNamespace().active_list(self , key) + else: + raise KeyError("Local key:%s not recognized" % key) + + + def free(self): + LocalDataset.cNamespace().free(self) + + + +cwrapper = CWrapper(ENKF_LIB) +cwrapper.registerObjectType("local_dataset", LocalDataset) + +LocalDataset.cNamespace().alloc = cwrapper.prototype("c_void_p local_dataset_alloc(char*)") +LocalDataset.cNamespace().size = cwrapper.prototype("c_void_p local_dataset_get_size(char*)") +LocalDataset.cNamespace().has_key = cwrapper.prototype("bool local_dataset_has_key(local_dataset, char*)") +LocalDataset.cNamespace().free = cwrapper.prototype("void local_dataset_free(local_dataset)") +LocalDataset.cNamespace().name = cwrapper.prototype("char* local_dataset_get_name(local_dataset)") +LocalDataset.cNamespace().active_list = cwrapper.prototype("active_list_ref local_dataset_get_node_active_list(local_dataset, char*)") +LocalDataset.cNamespace().add_node = cwrapper.prototype("void local_dataset_add_node(local_dataset, char*)") +LocalDataset.cNamespace().del_node = cwrapper.prototype("void local_dataset_del_node(local_dataset, char*)") + + + + + + diff --git a/ThirdParty/Ert/devel/python/python/ert/enkf/local_ministep.py b/ThirdParty/Ert/devel/python/python/ert/enkf/local_ministep.py new file mode 100644 index 0000000000..dee6a99d00 --- /dev/null +++ b/ThirdParty/Ert/devel/python/python/ert/enkf/local_ministep.py @@ -0,0 +1,60 @@ +import ert.util +from ert.cwrap import BaseCClass, CWrapper +from ert.enkf import ENKF_LIB, LocalObsdata, LocalObsdataNode, LocalDataset + +class LocalMinistep(BaseCClass): + + def __init__(self, ministep_key): + raise NotImplementedError("Class can not be instantiated directly!") + + # Will used the data keys; and ignore observation keys. + def __getitem__(self, data_key): + if data_key in self: + return LocalMinistep.cNamespace().get_local_data(self , data_key) + else: + raise KeyError("No such data key: %s" % data_key) + + def __len__(self): + return LocalMinistep.cNamespace().data_size( self ) + + def __contains__(self , data_key): + return LocalMinistep.cNamespace().has_local_data(self , data_key) + + def addNode(self, node): + assert isinstance(node, LocalObsdataNode) + LocalMinistep.cNamespace().add_node(self,node) + + def attachObsset(self, obs_set): + assert isinstance(obs_set, LocalObsdata) + LocalMinistep.cNamespace().attach_obsset(self,obs_set) + + + def attachDataset(self, dataset): + assert isinstance(dataset, LocalDataset) + LocalMinistep.cNamespace().attach_dataset(self,dataset) + + def getLocalObsData(self): + """ @rtype: LocalObsdata """ + return LocalMinistep.cNamespace().get_local_obs_data(self) + + def getName(self): + """ @rtype: str """ + return LocalMinistep.cNamespace().name(self) + + def free(self): + LocalMinistep.cNamespace().free(self) + +cwrapper = CWrapper(ENKF_LIB) +cwrapper.registerObjectType("local_ministep", LocalMinistep) + +LocalMinistep.cNamespace().alloc = cwrapper.prototype("c_void_p local_ministep_alloc(char*)") +LocalMinistep.cNamespace().add_node = cwrapper.prototype("void local_ministep_add_obsdata_node(local_ministep,local_obsdata_node)") +LocalMinistep.cNamespace().get_local_obs_data = cwrapper.prototype("local_obsdata_ref local_ministep_get_obsdata(local_ministep)") +LocalMinistep.cNamespace().get_local_data = cwrapper.prototype("local_dataset_ref local_ministep_get_dataset(local_ministep , char*)") +LocalMinistep.cNamespace().has_local_data = cwrapper.prototype("bool local_ministep_has_dataset(local_ministep , char*)") +LocalMinistep.cNamespace().free = cwrapper.prototype("void local_ministep_free(local_ministep)") +LocalMinistep.cNamespace().attach_obsset = cwrapper.prototype("void local_ministep_add_obsdata(local_ministep,local_obsdata)") +LocalMinistep.cNamespace().attach_dataset = cwrapper.prototype("void local_ministep_add_dataset(local_ministep,local_dataset)") +LocalMinistep.cNamespace().name = cwrapper.prototype("char* local_ministep_get_name(local_ministep)") +LocalMinistep.cNamespace().data_size = cwrapper.prototype("int local_ministep_get_num_dataset(local_ministep)") + diff --git a/ThirdParty/Ert/devel/python/python/ert/enkf/local_obsdata.py b/ThirdParty/Ert/devel/python/python/ert/enkf/local_obsdata.py index fa4b20292b..cfce87a01e 100644 --- a/ThirdParty/Ert/devel/python/python/ert/enkf/local_obsdata.py +++ b/ThirdParty/Ert/devel/python/python/ert/enkf/local_obsdata.py @@ -1,18 +1,42 @@ from ert.cwrap import BaseCClass, CWrapper -from ert.enkf import ENKF_LIB, LocalObsdataNode +from ert.enkf import ENKF_LIB, LocalObsdataNode class LocalObsdata(BaseCClass): - def __init__(self, name): - assert isinstance(name, str) + + def __init__(self, name , obs = None): + # The obs instance should be a EnkFObs instance; some circular dependency problems + # by importing it right away. It is not really optional, but it is made optional + # here to be able to give a decent error message for old call sites which did not + # supply the obs argument. + if obs is None: + msg = """ + +The LocalObsdata constructor has recently changed, as a second +argument you should pass the EnkFObs instance with all the +observations. You can typically get this instance from the ert main +object as: + + obs = ert.getObservations() + local_obs = LocalObsData("YOUR-KEY" , obs) + +""" + raise Exception( msg ) + assert isinstance(name, str) + c_pointer = LocalObsdata.cNamespace().alloc(name) super(LocalObsdata, self).__init__(c_pointer) + self.initObservations( obs ) + + def initObservations(self , obs): + self.obs = obs + def __len__(self): - """ @rtype: int """ - return LocalObsdata.cNamespace().size(self) + """ @rtype: int """ + return LocalObsdata.cNamespace().size(self) def __getitem__(self, key): @@ -27,27 +51,13 @@ def __getitem__(self, key): return LocalObsdata.cNamespace().get_node(self, key).setParent(self) else: raise KeyError("Unknown key:%s" % key) - def __iter__(self): cur = 0 while cur < len(self): - yield self[cur] - cur += 1 - - - def addNode(self, node): - """ @rtype: bool """ - assert isinstance(node, LocalObsdataNode) - node.convertToCReference(self) - already_exists_node_for_key = LocalObsdata.cNamespace().add_node(self, node) - return already_exists_node_for_key - - - def addObsVector(self , obs_vector): - self.addNode( obs_vector.createLocalObs() ) - - + yield self[cur] + cur += 1 + def __contains__(self, item): """ @rtype: bool """ if isinstance(item, str): @@ -56,7 +66,43 @@ def __contains__(self, item): return LocalObsdata.cNamespace().has_node(self, item.getKey()) return False + + def __delitem__(self, key): + assert isinstance(key, str) + if key in self: + LocalObsdata.cNamespace().del_node(self, key) + else: + raise KeyError("Unknown key:%s" % key) + + def addNode(self, node): + assert isinstance(node, LocalObsdataNode) + if node.getKey() in self.obs: + if node not in self: + node.convertToCReference(self) + LocalObsdata.cNamespace().add_node(self, node) + else: + raise KeyError("Tried to add existing observation key:%s " % node.getKey()) + + else: + raise KeyError("The observation node: %s is not recognized observation key" % node.getKey()) + def addNodeAndRange(self, key, step_1, step_2): + assert isinstance(key, str) + assert isinstance(step_1, int) + assert isinstance(step_2, int) + node = LocalObsdataNode(key) + self.addNode( node ) + node.addRange(step_1, step_2) + + + def clear(self): + LocalObsdata.cNamespace().clear(self) + + + def addObsVector(self , obs_vector): + self.addNode( obs_vector.createLocalObs() ) + + def getName(self): """ @rtype: str """ return LocalObsdata.cNamespace().name(self) @@ -67,18 +113,18 @@ def free(self): cwrapper = CWrapper(ENKF_LIB) -cwrapper.registerType("local_obsdata", LocalObsdata) -cwrapper.registerType("local_obsdata_obj", LocalObsdata.createPythonObject) -cwrapper.registerType("local_obsdata_ref", LocalObsdata.createCReference) - -LocalObsdata.cNamespace().alloc = cwrapper.prototype("c_void_p local_obsdata_alloc(char*)") -LocalObsdata.cNamespace().free = cwrapper.prototype("void local_obsdata_free(local_obsdata)") -LocalObsdata.cNamespace().size = cwrapper.prototype("int local_obsdata_get_size(local_obsdata)") -LocalObsdata.cNamespace().has_node = cwrapper.prototype("bool local_obsdata_has_node(local_obsdata, char*)") -LocalObsdata.cNamespace().add_node = cwrapper.prototype("bool local_obsdata_add_node(local_obsdata, local_obsdata_node)") +cwrapper.registerObjectType("local_obsdata", LocalObsdata) + +LocalObsdata.cNamespace().alloc = cwrapper.prototype("c_void_p local_obsdata_alloc(char*)") +LocalObsdata.cNamespace().free = cwrapper.prototype("void local_obsdata_free(local_obsdata)") +LocalObsdata.cNamespace().size = cwrapper.prototype("int local_obsdata_get_size(local_obsdata)") +LocalObsdata.cNamespace().has_node = cwrapper.prototype("bool local_obsdata_has_node(local_obsdata, char*)") +LocalObsdata.cNamespace().add_node = cwrapper.prototype("bool local_obsdata_add_node(local_obsdata, local_obsdata_node)") +LocalObsdata.cNamespace().del_node = cwrapper.prototype("void local_obsdata_del_node(local_obsdata, char*)") +LocalObsdata.cNamespace().clear = cwrapper.prototype("void local_dataset_clear(local_obsdata)") LocalObsdata.cNamespace().iget_node = cwrapper.prototype("local_obsdata_node_ref local_obsdata_iget(local_obsdata, int)") -LocalObsdata.cNamespace().get_node = cwrapper.prototype("local_obsdata_node_ref local_obsdata_get(local_obsdata, char*)") -LocalObsdata.cNamespace().name = cwrapper.prototype("char* local_obsdata_get_name(local_obsdata)") +LocalObsdata.cNamespace().get_node = cwrapper.prototype("local_obsdata_node_ref local_obsdata_get(local_obsdata, char*)") +LocalObsdata.cNamespace().name = cwrapper.prototype("char* local_obsdata_get_name(local_obsdata)") diff --git a/ThirdParty/Ert/devel/python/python/ert/enkf/local_updatestep.py b/ThirdParty/Ert/devel/python/python/ert/enkf/local_updatestep.py new file mode 100644 index 0000000000..67c8ec3ba2 --- /dev/null +++ b/ThirdParty/Ert/devel/python/python/ert/enkf/local_updatestep.py @@ -0,0 +1,42 @@ +from ert.cwrap import BaseCClass, CWrapper +from ert.enkf import ENKF_LIB, LocalMinistep + +class LocalUpdateStep(BaseCClass): + + def __init__(self, updatestep_key): + raise NotImplementedError("Class can not be instantiated directly!") + + def __len__(self): + """ @rtype: int """ + return LocalUpdateStep.cNamespace().size(self) + + def __getitem__(self, index): + """ @rtype: LocalMinistep """ + assert isinstance(index, int) + if index < len(self): + return LocalUpdateStep.cNamespace().iget_ministep(self, index) + else: + raise IndexError("Invalid index") + + def attachMinistep(self, ministep): + assert isinstance(ministep, LocalMinistep) + LocalUpdateStep.cNamespace().attach_ministep(self,ministep) + + def getName(self): + """ @rtype: str """ + return LocalUpdateStep.cNamespace().name(self) + + def free(self): + LocalUpdateStep.cNamespace().free(self) + +cwrapper = CWrapper(ENKF_LIB) +cwrapper.registerObjectType("local_updatestep", LocalUpdateStep) + +LocalUpdateStep.cNamespace().alloc = cwrapper.prototype("c_void_p local_updatestep_alloc(char*)") +LocalUpdateStep.cNamespace().size = cwrapper.prototype("int local_updatestep_get_num_ministep(local_updatestep)") +LocalUpdateStep.cNamespace().iget_ministep = cwrapper.prototype("local_ministep_ref local_updatestep_iget_ministep(local_updatestep, int)") +LocalUpdateStep.cNamespace().free = cwrapper.prototype("void local_updatestep_free(local_updatestep)") +LocalUpdateStep.cNamespace().attach_ministep = cwrapper.prototype("void local_updatestep_add_ministep(local_updatestep,local_ministep)") +LocalUpdateStep.cNamespace().name = cwrapper.prototype("char* local_updatestep_get_name(local_updatestep)") + + diff --git a/ThirdParty/Ert/devel/python/python/ert/enkf/obs_data.py b/ThirdParty/Ert/devel/python/python/ert/enkf/obs_data.py index e692b2f831..716cd66055 100644 --- a/ThirdParty/Ert/devel/python/python/ert/enkf/obs_data.py +++ b/ThirdParty/Ert/devel/python/python/ert/enkf/obs_data.py @@ -12,9 +12,21 @@ def __init__(self, global_std_scaling=1.0): def __len__(self): """ @rtype: int """ - return ObsData.cNamespace().active_size(self) + return ObsData.cNamespace().total_size(self) + def __getitem__(self , index): + if index < 0: + index += len(self) + if index >= len(self): + raise IndexError("Invalid index:%d valid range: [0,%d)" % (index , len(self))) + + value = ObsData.cNamespace().iget_value( self , index ) + std = ObsData.cNamespace().iget_std( self , index ) + return (value,std) + + + def addBlock(self , obs_key , obs_size): error_covar = None error_covar_owner = False @@ -64,7 +76,9 @@ def free(self): ObsData.cNamespace().alloc = cwrapper.prototype("c_void_p obs_data_alloc(double)") ObsData.cNamespace().free = cwrapper.prototype("void obs_data_free(obs_data)") -ObsData.cNamespace().active_size = cwrapper.prototype("int obs_data_get_active_size(obs_data)") +ObsData.cNamespace().total_size = cwrapper.prototype("int obs_data_get_total_size(obs_data)") +ObsData.cNamespace().iget_value = cwrapper.prototype("double obs_data_iget_value(obs_data)") +ObsData.cNamespace().iget_std = cwrapper.prototype("double obs_data_iget_std(obs_data)") ObsData.cNamespace().add_block = cwrapper.prototype("obs_block_ref obs_data_add_block(obs_data , char* , int , matrix , bool)") ObsData.cNamespace().allocdObs = cwrapper.prototype("matrix_obj obs_data_allocdObs(obs_data)") diff --git a/ThirdParty/Ert/devel/python/python/ert/enkf/run_arg.py b/ThirdParty/Ert/devel/python/python/ert/enkf/run_arg.py index 6a91bde787..3f86c22500 100644 --- a/ThirdParty/Ert/devel/python/python/ert/enkf/run_arg.py +++ b/ThirdParty/Ert/devel/python/python/ert/enkf/run_arg.py @@ -23,7 +23,7 @@ class RunArg(BaseCClass): def __init__(self , c_ptr , parent = None , is_reference = False ): - super(RunArg , self).__init__( c_ptr , parent = None , is_reference = is_reference ) + super(RunArg , self).__init__( c_ptr , parent = parent , is_reference = is_reference ) @classmethod @@ -37,7 +37,8 @@ def free(self): def getQueueIndex(self): return RunArg.cNamespace().get_queue_index( self ) - + def isSubmitted(self): + return RunArg.cNamespace().is_submitted( self ) @@ -48,3 +49,4 @@ def getQueueIndex(self): RunArg.cNamespace().alloc_ENSEMBLE_EXPERIMENT = cwrapper.prototype("c_void_p run_arg_alloc_ENSEMBLE_EXPERIMENT(enkf_fs , int, int, char*)") RunArg.cNamespace().free = cwrapper.prototype("void run_arg_free(run_arg)") RunArg.cNamespace().get_queue_index = cwrapper.prototype("int run_arg_get_queue_index(run_arg)") +RunArg.cNamespace().is_submitted = cwrapper.prototype("bool run_arg_is_submitted(run_arg)") diff --git a/ThirdParty/Ert/devel/python/python/ert/enkf/site_config.py b/ThirdParty/Ert/devel/python/python/ert/enkf/site_config.py index ecb98e6e5f..e4955a14d8 100644 --- a/ThirdParty/Ert/devel/python/python/ert/enkf/site_config.py +++ b/ThirdParty/Ert/devel/python/python/ert/enkf/site_config.py @@ -29,7 +29,9 @@ def getQueueName(self): return SiteConfig.cNamespace().get_queue_name( self ) def setJobQueue(self, queue): - SiteConfig.cNamespace().set_job_queue( self , queue) + raise Exception("The function setJobQueue() is not properly implemented") + + def getLsfQueue(self): """ @rtype: str """ @@ -141,6 +143,11 @@ def getRshHostList(self): def addRshHost(self, host, max_running): SiteConfig.cNamespace().add_rsh_host(self, host, max_running) + def getLocation(self): + """ @rtype: str """ + return SiteConfig.cNamespace().get_location(self) + + def free(self): SiteConfig.cNamespace().free(self) @@ -152,7 +159,6 @@ def free(self): SiteConfig.cNamespace().free = cwrapper.prototype("void site_config_free( site_config )") SiteConfig.cNamespace().get_queue_name = cwrapper.prototype("char* site_config_get_queue_name(site_config)") -SiteConfig.cNamespace().set_job_queue = cwrapper.prototype("void site_config_set_job_queue(site_config, char*)") SiteConfig.cNamespace().get_lsf_queue = cwrapper.prototype("char* site_config_get_lsf_queue(site_config)") SiteConfig.cNamespace().set_lsf_queue = cwrapper.prototype("void site_config_set_lsf_queue(site_config, char*)") SiteConfig.cNamespace().get_max_running_lsf = cwrapper.prototype("int site_config_get_max_running_lsf(site_config)") @@ -186,3 +192,4 @@ def free(self): SiteConfig.cNamespace().update_pathvar = cwrapper.prototype("void site_config_update_pathvar(site_config, char*, char*)") SiteConfig.cNamespace().get_job_queue = cwrapper.prototype("job_queue_ref site_config_get_job_queue(site_config)") SiteConfig.cNamespace().queue_is_running = cwrapper.prototype("bool site_config_queue_is_running(site_config)") +SiteConfig.cNamespace().get_location = cwrapper.prototype("char* site_config_get_location(site_config)") diff --git a/ThirdParty/Ert/devel/python/python/ert/job_queue/driver.py b/ThirdParty/Ert/devel/python/python/ert/job_queue/driver.py index 075c7243bb..fe379e33a9 100644 --- a/ThirdParty/Ert/devel/python/python/ert/job_queue/driver.py +++ b/ThirdParty/Ert/devel/python/python/ert/job_queue/driver.py @@ -141,7 +141,7 @@ def __init__( self, max_running, rsh_host_list, rsh_cmd="/usr/bin/ssh" ): cfunc.free_driver = cwrapper.prototype("void queue_driver_free( driver )") cfunc.submit = cwrapper.prototype("c_void_p queue_driver_submit_job( driver , char* , int , char* , char* , int , char**)") cfunc.free_job = cwrapper.prototype("void queue_driver_free_job( driver , job )") -cfunc.cget_status = cwrapper.prototype("int job_queue_get_status( driver , job)") +cfunc.cget_status = cwrapper.prototype("int queue_driver_get_status( driver , job)") cfunc.kill_job = cwrapper.prototype("void queue_driver_kill_job( driver , job )") cfunc.set_max_running = cwrapper.prototype("void queue_driver_set_max_running( driver , int )") cfunc.get_max_running = cwrapper.prototype("int queue_driver_get_max_running( driver )") diff --git a/ThirdParty/Ert/devel/python/python/ert/job_queue/ert_script.py b/ThirdParty/Ert/devel/python/python/ert/job_queue/ert_script.py index 1cc3119be7..12e3f9b07e 100644 --- a/ThirdParty/Ert/devel/python/python/ert/job_queue/ert_script.py +++ b/ThirdParty/Ert/devel/python/python/ert/job_queue/ert_script.py @@ -38,6 +38,12 @@ def hasFailed(self): def cancel(self): self.__is_cancelled = True + def cleanup(self): + """ + Override to perform cleanup after a run. + """ + pass + def initializeAndRun(self, argument_types, argument_values, verbose=False): """ @type argument_types: list of type @@ -66,10 +72,11 @@ def initializeAndRun(self, argument_types, argument_values, verbose=False): return self.run(*arguments) except Exception as e: sys.stderr.write("The script '%s' caused an error while running:\n" % self.__class__.__name__) - traceback.print_exception(sys.exc_type, sys.exc_value, sys.exc_traceback) self.__failed = True stack_trace = traceback.format_exception(sys.exc_type, sys.exc_value, sys.exc_traceback) return "".join(stack_trace) + finally: + self.cleanup() __module_count = 0 # Need to have unique modules in case of identical object naming in scripts diff --git a/ThirdParty/Ert/devel/python/python/ert/job_queue/job_queue_manager.py b/ThirdParty/Ert/devel/python/python/ert/job_queue/job_queue_manager.py index 9840b13a8f..afc1118dd9 100644 --- a/ThirdParty/Ert/devel/python/python/ert/job_queue/job_queue_manager.py +++ b/ThirdParty/Ert/devel/python/python/ert/job_queue/job_queue_manager.py @@ -33,15 +33,18 @@ def __init__(self, queue): super(JobQueueManager, self).__init__(c_ptr) - def startQueue(self , total_size , verbose = False): - JobQueueManager.cNamespace().start_queue( self , total_size , verbose ) + def startQueue(self , total_size , verbose = False , reset_queue = True): + JobQueueManager.cNamespace().start_queue( self , total_size , verbose , reset_queue) def getNumRunning(self): return JobQueueManager.cNamespace().get_num_running( self ) - def getNumComplete(self): - return JobQueueManager.cNamespace().get_num_complete( self ) + def getNumSuccess(self): + return JobQueueManager.cNamespace().get_num_success( self ) + def getNumFailed(self): + return JobQueueManager.cNamespace().get_num_failed( self ) + def isRunning(self): return JobQueueManager.cNamespace().is_running( self ) @@ -50,8 +53,18 @@ def free(self): def jobComplete(self , job_index): return JobQueueManager.cNamespace().job_complete( self , job_index ) - - + + def jobRunning(self , job_index): + return JobQueueManager.cNamespace().job_running( self , job_index ) + + def jobWaiting(self , job_index): + return JobQueueManager.cNamespace().job_waiting( self , job_index ) + + def jobFailed(self , job_index): + return JobQueueManager.cNamespace().job_failed( self , job_index ) + + def jobSuccess(self , job_index): + return JobQueueManager.cNamespace().job_success( self , job_index ) ################################################################# @@ -61,8 +74,13 @@ def jobComplete(self , job_index): JobQueueManager.cNamespace().alloc = cwrapper.prototype("c_void_p job_queue_manager_alloc( job_queue) ") JobQueueManager.cNamespace().free = cwrapper.prototype("void job_queue_manager_free( job_queue_manager )") -JobQueueManager.cNamespace().start_queue = cwrapper.prototype("void job_queue_manager_start_queue( job_queue_manager , int , bool)") +JobQueueManager.cNamespace().start_queue = cwrapper.prototype("void job_queue_manager_start_queue( job_queue_manager , int , bool, bool)") JobQueueManager.cNamespace().get_num_running = cwrapper.prototype("int job_queue_manager_get_num_running( job_queue_manager )") -JobQueueManager.cNamespace().get_num_complete = cwrapper.prototype("int job_queue_manager_get_num_complete( job_queue_manager )") +JobQueueManager.cNamespace().get_num_success = cwrapper.prototype("int job_queue_manager_get_num_success( job_queue_manager )") +JobQueueManager.cNamespace().get_num_failed = cwrapper.prototype("int job_queue_manager_get_num_failed( job_queue_manager )") JobQueueManager.cNamespace().is_running = cwrapper.prototype("bool job_queue_manager_is_running( job_queue_manager )") -JobQueueManager.cNamespace().job_complete = cwrapper.prototype("bool job_queue_manager_job_complete( job_queue_manager , int)") +JobQueueManager.cNamespace().job_complete = cwrapper.prototype("bool job_queue_manager_job_success( job_queue_manager , int)") +JobQueueManager.cNamespace().job_running = cwrapper.prototype("bool job_queue_manager_job_running( job_queue_manager , int)") +JobQueueManager.cNamespace().job_failed = cwrapper.prototype("bool job_queue_manager_job_failed( job_queue_manager , int)") +JobQueueManager.cNamespace().job_waiting = cwrapper.prototype("bool job_queue_manager_job_waiting( job_queue_manager , int)") +JobQueueManager.cNamespace().job_success = cwrapper.prototype("bool job_queue_manager_job_success( job_queue_manager , int)") diff --git a/ThirdParty/Ert/devel/python/python/ert/job_queue/queue.py b/ThirdParty/Ert/devel/python/python/ert/job_queue/queue.py index efed10d231..8832073896 100644 --- a/ThirdParty/Ert/devel/python/python/ert/job_queue/queue.py +++ b/ThirdParty/Ert/devel/python/python/ert/job_queue/queue.py @@ -174,7 +174,7 @@ def submit( self, cmd, run_path, job_name, argv, num_cpu=1): exit_callback = None - queue_index = JobQueue.cNamespace().add_job_mt(self, + queue_index = JobQueue.cNamespace().add_job(self, cmd, done_callback, retry_callback, @@ -186,8 +186,8 @@ def submit( self, cmd, run_path, job_name, argv, num_cpu=1): len(argv), c_argv) - job = Job(self.driver, JobQueue.cNamespace().get_job_ptr(self, queue_index), queue_index, False) - + job_ptr = None + job = Job(self.driver, job_ptr , queue_index, False) self.jobs.add_job(job, job_name) return job @@ -287,8 +287,7 @@ def getJobStatus(self, job_number): JobQueue.cNamespace().set_max_running = cwrapper.prototype("void job_queue_set_max_running( job_queue , int)") JobQueue.cNamespace().get_max_running = cwrapper.prototype("int job_queue_get_max_running( job_queue )") JobQueue.cNamespace().set_driver = cwrapper.prototype("void job_queue_set_driver( job_queue , c_void_p )") -JobQueue.cNamespace().add_job_mt = cwrapper.prototype("int job_queue_add_job_mt( job_queue , char* , c_void_p , c_void_p , c_void_p , c_void_p , int , char* , char* , int , char**)") -JobQueue.cNamespace().add_job_st = cwrapper.prototype("int job_queue_add_job_st( job_queue , char* , c_void_p , c_void_p , c_void_p , c_void_p , int , char* , char* , int , char**)") +JobQueue.cNamespace().add_job = cwrapper.prototype("int job_queue_add_job( job_queue , char* , c_void_p , c_void_p , c_void_p , c_void_p , int , char* , char* , int , char**)") JobQueue.cNamespace().start_queue = cwrapper.prototype("void job_queue_run_jobs( job_queue , int , bool)") JobQueue.cNamespace().run_jobs = cwrapper.prototype("void job_queue_run_jobs_threaded(job_queue , int , bool)") @@ -299,7 +298,6 @@ def getJobStatus(self, job_number): JobQueue.cNamespace().is_running = cwrapper.prototype("int job_queue_is_running( job_queue )") JobQueue.cNamespace().submit_complete = cwrapper.prototype("void job_queue_submit_complete( job_queue )") -JobQueue.cNamespace().get_job_ptr = cwrapper.prototype("c_void_p job_queue_iget_job( job_queue , int)") #warn fix return type JobQueue.cNamespace().iget_sim_start = cwrapper.prototype("time_t job_queue_iget_sim_start( job_queue , int)") JobQueue.cNamespace().get_active_size = cwrapper.prototype("int job_queue_get_active_size( job_queue )") JobQueue.cNamespace().get_pause = cwrapper.prototype("bool job_queue_get_pause(job_queue)") diff --git a/ThirdParty/Ert/devel/python/python/ert/job_queue/workflow.py b/ThirdParty/Ert/devel/python/python/ert/job_queue/workflow.py index 98fe8feead..5f3ceb73b1 100644 --- a/ThirdParty/Ert/devel/python/python/ert/job_queue/workflow.py +++ b/ThirdParty/Ert/devel/python/python/ert/job_queue/workflow.py @@ -49,6 +49,10 @@ def run(self, ert, verbose=False, context=None): self.__current_job = job if not self.__cancelled: return_value = job.run(ert, args, verbose) + + if job.hasFailed(): + print(return_value) + #todo store results? self.__current_job = None diff --git a/ThirdParty/Ert/devel/python/python/ert/job_queue/workflow_job.py b/ThirdParty/Ert/devel/python/python/ert/job_queue/workflow_job.py index b58dfc2d9f..cab00a8710 100644 --- a/ThirdParty/Ert/devel/python/python/ert/job_queue/workflow_job.py +++ b/ThirdParty/Ert/devel/python/python/ert/job_queue/workflow_job.py @@ -53,7 +53,7 @@ def isPlugin(self): """ @rtype: bool """ if self.isInternalScript(): script_obj = ErtScript.loadScriptFromFile(self.getInternalScriptPath()) - return issubclass(script_obj, ErtPlugin) + return script_obj is not None and issubclass(script_obj, ErtPlugin) return False diff --git a/ThirdParty/Ert/devel/python/python/ert/sched/sched_file.py b/ThirdParty/Ert/devel/python/python/ert/sched/sched_file.py index bbe5e16e34..4cf8a835c1 100644 --- a/ThirdParty/Ert/devel/python/python/ert/sched/sched_file.py +++ b/ThirdParty/Ert/devel/python/python/ert/sched/sched_file.py @@ -13,6 +13,8 @@ # # See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> # for more details. +import os.path + from ert.cwrap import BaseCClass, CWrapper from ert.sched import SCHED_LIB from ert.util import CTime @@ -20,8 +22,11 @@ class SchedFile(BaseCClass): def __init__(self, filename, start_time): - c_ptr = SchedFile.cNamespace().parse(filename, CTime(start_time)) - super(SchedFile, self).__init__(c_ptr) + if os.path.isfile(filename): + c_ptr = SchedFile.cNamespace().parse(filename, CTime(start_time)) + super(SchedFile, self).__init__(c_ptr) + else: + raise IOError("No such file: %s" % filename) @property def length(self): diff --git a/ThirdParty/Ert/devel/python/python/ert/server/ert_client.py b/ThirdParty/Ert/devel/python/python/ert/server/ert_client.py index 6e15ac136c..7452483237 100644 --- a/ThirdParty/Ert/devel/python/python/ert/server/ert_client.py +++ b/ThirdParty/Ert/devel/python/python/ert/server/ert_client.py @@ -18,8 +18,14 @@ import socket import json import datetime +import time from ert.server import ErtServer +class ServerReturnedNoneException(Exception): + pass + +class ConnectionErrorException(Exception): + pass class ErtClient(object): def __init__(self , port , host): @@ -30,7 +36,8 @@ def __init__(self , port , host): try: self.socket.connect((self.host , self.port)) except socket.error: - sys.exit("Failed to connect to port:%d at %s." % (port , host)) + raise Exception("Failed to connect to port:%d at %s." % (port , host)) + @staticmethod def convert_to_datetime(data): @@ -43,11 +50,19 @@ def convert_to_datetime(data): return result def sendRecv(self , data): - self.socket.sendall( json.dumps(data) + "\n" ) - recv = self.socket.recv(4096) + + try: + self.socket.sendall( json.dumps(data) + "\n" ) + recv = self.socket.recv(4096) + except: + raise ConnectionErrorException() + result = json.loads(recv) + if result is not None: + result0 = result[0] + else: + raise ServerReturnedNoneException() - result0 = result[0] if result0 == "OK": result = result[1:] if data == ["TIME_STEP"]: @@ -60,8 +75,19 @@ def sendRecv(self , data): raise Exception("Ert server returned result[0] == %s - must have OK|ERROR as first element in return list" % result[0]) - @staticmethod def runCommand( cmd , port , host): - client = ErtClient( port , host ) - return client.sendRecv( cmd ) + while True: + client = ErtClient(port, host) + try: + result = client.sendRecv(cmd) + return result + except ServerReturnedNoneException: + print("The server returned null on command %s, the command will be resent." % cmd) + time.sleep(3) + except ConnectionErrorException: + print("Connection dropped unexpectedly on command %s, the command will be resent." % cmd) + time.sleep(3) + except: + print("Unhandled exception on command %s - this will be raised to a higher place." % cmd) + raise diff --git a/ThirdParty/Ert/devel/python/python/ert/server/ert_server.py b/ThirdParty/Ert/devel/python/python/ert/server/ert_server.py index 0a3662af08..9cef1048a1 100644 --- a/ThirdParty/Ert/devel/python/python/ert/server/ert_server.py +++ b/ThirdParty/Ert/devel/python/python/ert/server/ert_server.py @@ -12,7 +12,8 @@ # FITNESS FOR A PARTICULAR PURPOSE. # # See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> -# for more details. +# for more details. +import logging import sys import threading @@ -51,16 +52,18 @@ class ErtServer(object): DATE_FORMAT = '%Y-%m-%d %H:%M:%S' site_config = None - def __init__(self , config_file , logger): + def __init__(self , config , logger=None): installAbortSignals() self.queue_lock = threading.Lock() self.ert_handle = None + + if logger is None: + logger = logging + self.logger = logger - if os.path.exists(config_file): - self.open( config_file ) - else: - raise IOError("The config file:%s does not exist" % config_file) + + self.open(config) self.initCmdTable() self.run_context = None @@ -87,9 +90,18 @@ def initCmdTable(self): "TIME_STEP": self.handleTIMESTEP } - def open(self , config_file): + def open(self , config): + if isinstance(config, EnKFMain): + config_file = config.getUserConfigFile() + else: + if os.path.exists(config): + config_file = config + config = EnKFMain( config ) + else: + raise IOError("The config file:%s does not exist" % config) + self.config_file = config_file - self.ert_handle = EnKFMain( config_file ) + self.ert_handle = config self.logger.info("Have connect ert handle to:%s" , config_file) @@ -123,22 +135,33 @@ def evalCmd(self , cmd_expr): raise KeyError("The command:%s was not recognized" % cmd) + + # The STATUS action can either report results for the complete + # simulation set, or it can report the status of one particular + # realisation. If the function is called with zero arguments it + # will return the global status, if called with one argument it + # will return the status for that realisation. + def handleSTATUS(self , args): if self.isConnected(): if self.run_context is None: return self.SUCCESS(["READY"]) else: - if self.run_context.isRunning(): - if len(args) == 0: - return self.SUCCESS(["RUNNING" , self.run_context.getNumRunning() , self.run_context.getNumComplete()]) + if len(args) == 0: + if self.run_context.isRunning(): + return self.SUCCESS(["RUNNING" , self.run_context.getNumRunning() , self.run_context.getNumSuccess() , self.run_context.getNumFailed()]) else: - iens = args[0] - if self.run_context.realisationComplete(iens): - return self.SUCCESS(["COMPLETE"]) - else: - return self.SUCCESS(["RUNNING"]) + return self.SUCCESS(["COMPLETE" , self.run_context.getNumRunning() , self.run_context.getNumSuccess() , self.run_context.getNumFailed()]) else: - return self.SUCCESS(["COMPLETE"]) + iens = args[0] + + if self.run_context.realisationRunning(iens): + return self.SUCCESS(["RUNNING"]) + elif self.run_context.realisationFailed(iens): + return self.SUCCESS(["FAILED"]) + elif self.run_context.realisationSuccess(iens): + return self.SUCCESS(["SUCCESS"]) + else: return self.SUCCESS(["CLOSED"]) diff --git a/ThirdParty/Ert/devel/python/python/ert/server/ert_socket.py b/ThirdParty/Ert/devel/python/python/ert/server/ert_socket.py index 351edc6fba..411fea81fa 100644 --- a/ThirdParty/Ert/devel/python/python/ert/server/ert_socket.py +++ b/ThirdParty/Ert/devel/python/python/ert/server/ert_socket.py @@ -21,13 +21,12 @@ import json import traceback import socket +import fcntl from ert.server import ErtServer, SUCCESS , ERROR class ErtHandler(SocketServer.StreamRequestHandler): ert_server = None - config_file = None - logger = None def handle(self): string_data = self.rfile.readline().strip() @@ -52,12 +51,12 @@ def evalCmd(self , data): try: result = self.ert_server.evalCmd( data ) except Exception,e: - result = ERROR( "Exception raised" , exception = e) + tb = traceback.format_exc() + result = ERROR( "Exception raised:" , exception = tb) self.returnToClient( result ) - def handleQuit(self): shutdown_thread = threading.Thread( target = self.server.shutdown ) shutdown_thread.start() @@ -71,18 +70,26 @@ class ErtSocketServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer): class ErtSocket(object): - def __init__(self , config_file , port , host , logger): + def __init__(self , config , port , host , logger): + self.host = host + self.port = port self.server = ErtSocketServer((host , port) , ErtHandler) - self.open(config_file , logger) + self._setupSocketCloseOnExec() + self.open(config , logger) + self.__is_listening = False + def _setupSocketCloseOnExec(self): + fd = self.server.fileno() + old_flags = fcntl.fcntl(fd, fcntl.F_GETFD) + fcntl.fcntl(fd, fcntl.F_SETFD, old_flags | fcntl.FD_CLOEXEC) @staticmethod - def connect(config_file , port , host , logger , info_callback = None , timeout = 60 , sleep_time = 5): + def connect(config , port , host , logger = None, info_callback = None , timeout = 60 , sleep_time = 5): start_time = time.time() ert_socket = None while True: try: - ert_socket = ErtSocket(config_file , port, host , logger) + ert_socket = ErtSocket(config , port, host , logger) break except socket.error: if info_callback: @@ -95,17 +102,16 @@ def connect(config_file , port , host , logger , info_callback = None , timeout return ert_socket - - def open(self , config_file , logger): - ErtHandler.ert_server = ErtServer( config_file , logger ) - - + def open(self , config , logger): + ErtHandler.ert_server = ErtServer( config , logger ) def evalCmd(self , cmd): return ErtHandler.ert_server.evalCmd( cmd ) - def listen(self): + self.__is_listening = True self.server.serve_forever( ) - - + + def shutdown(self): + if self.__is_listening: + self.server.shutdown() diff --git a/ThirdParty/Ert/devel/python/python/ert/server/run_context.py b/ThirdParty/Ert/devel/python/python/ert/server/run_context.py index b122dc193c..c981888104 100644 --- a/ThirdParty/Ert/devel/python/python/ert/server/run_context.py +++ b/ThirdParty/Ert/devel/python/python/ert/server/run_context.py @@ -15,8 +15,8 @@ # for more details. from ert.job_queue import JobQueueManager -from ert.enkf import RunArg -from ert.util import BoolVector +from ert.enkf import RunArg, ENKF_LIB +from ert.util import BoolVector, ArgPack, CThreadPool class RunContext(object): def __init__(self , ert_handle , size , run_fs , run_count): @@ -33,8 +33,10 @@ def __init__(self , ert_handle , size , run_fs , run_count): self.ert_handle.addDataKW("<ELCO_RUN_COUNT>" , "%s" % run_count) self.ert_run_context = self.ert_handle.getRunContextENSEMPLE_EXPERIMENT( run_fs , mask ) - + self.thread_pool = CThreadPool( 8 ) + self.submit_func = CThreadPool.lookupCFunction( ENKF_LIB , "enkf_main_isubmit_job__" ) + def isRunning(self): return self.queue_manager.isRunning() @@ -43,15 +45,45 @@ def getNumRunning(self): return self.queue_manager.getNumRunning() - def getNumComplete(self): - return self.queue_manager.getNumComplete() - + def getNumSuccess(self): + return self.queue_manager.getNumSuccess() + + + def getNumFailed(self): + return self.queue_manager.getNumFailed() + def startSimulation(self , iens): - self.ert_handle.submitSimulation( self.ert_run_context.iensGet( iens )) + member_context = self.ert_run_context.iensGet( iens ) + arg = ArgPack( self.ert_handle , member_context ) + self.thread_pool.addTask( self.submit_func , arg ) + + def realisationSuccess(self, iens): + run_arg = self.ert_run_context.iensGet( iens ) + queue_index = run_arg.getQueueIndex() + return self.queue_manager.jobSuccess( queue_index ) - def realisationComplete(self, iens): + + def realisationFailed(self, iens): run_arg = self.ert_run_context.iensGet( iens ) queue_index = run_arg.getQueueIndex() - return self.queue_manager.jobComplete( queue_index ) + return self.queue_manager.jobFailed( queue_index ) + + + # Running is slightly misleading; we have three catogories: + # Complete, Failed, and "Running". Running in this context is + # actually the 'the rest', and includes jobs in all sorts of + # waiting. + + def realisationRunning(self, iens): + run_arg = self.ert_run_context.iensGet( iens ) + if run_arg.isSubmitted(): + queue_index = run_arg.getQueueIndex() + if self.queue_manager.jobRunning( queue_index ) or self.queue_manager.jobWaiting( queue_index ): + return True + else: + return False + else: + return True + diff --git a/ThirdParty/Ert/devel/python/python/ert/test/CMakeLists.txt b/ThirdParty/Ert/devel/python/python/ert/test/CMakeLists.txt index 62ac811f64..94c3fa2e77 100644 --- a/ThirdParty/Ert/devel/python/python/ert/test/CMakeLists.txt +++ b/ThirdParty/Ert/devel/python/python/ert/test/CMakeLists.txt @@ -6,6 +6,7 @@ set(PYTHON_SOURCES test_run.py source_enumerator.py test_area.py + path_context.py ) add_python_package("python.ert.test" ${PYTHON_INSTALL_PREFIX}/ert/test "${PYTHON_SOURCES}" True) diff --git a/ThirdParty/Ert/devel/python/python/ert/test/__init__.py b/ThirdParty/Ert/devel/python/python/ert/test/__init__.py index da9a6f283d..66efef55bf 100644 --- a/ThirdParty/Ert/devel/python/python/ert/test/__init__.py +++ b/ThirdParty/Ert/devel/python/python/ert/test/__init__.py @@ -4,6 +4,7 @@ from .source_enumerator import SourceEnumerator from .test_area import TestArea , TestAreaContext from .ert_test_runner import ErtTestRunner +from .path_context import PathContext try: from .ert_test_context import ErtTestContext, ErtTest except ImportError: diff --git a/ThirdParty/Ert/devel/python/python/ert/test/extended_testcase.py b/ThirdParty/Ert/devel/python/python/ert/test/extended_testcase.py index 3445ab9d12..01a8383bc5 100644 --- a/ThirdParty/Ert/devel/python/python/ert/test/extended_testcase.py +++ b/ThirdParty/Ert/devel/python/python/ert/test/extended_testcase.py @@ -147,24 +147,7 @@ def createTestPath(self, path, testdata_root=None): def createSharePath(self, path, share_root=None): if share_root is None and self.__share_root is None: - file_path = os.path.realpath(__file__) - build_root = os.path.realpath(os.path.join(os.path.dirname(file_path), "../../../../devel/share/")) - site_packages_build_root = os.path.realpath(os.path.join(os.path.dirname(file_path), "../../../../../../devel/share/")) - src_root = os.path.realpath(os.path.join(os.path.dirname(file_path), "../../../../share/")) - env_root = os.getenv("ERT_TEST_ROOT_PATH") - - if env_root is not None and os.path.exists(env_root): - root = os.path.realpath(env_root) - elif os.path.exists(build_root): - root = os.path.realpath(build_root) - elif os.path.exists(site_packages_build_root): - root = os.path.realpath(site_packages_build_root) - elif os.path.exists(src_root): - root = os.path.realpath(src_root) - else: - root = None - - self.setShareRoot(root) + self.setShareRoot(ExtendedTestCase.findShareRoot()) root_path = self.__share_root if share_root is not None: @@ -175,15 +158,34 @@ def createSharePath(self, path, share_root=None): return os.path.realpath(os.path.join(root_path , path)) - + + @staticmethod + def findShareRoot(): + file_path = os.path.realpath(__file__) + build_root = os.path.realpath(os.path.join(os.path.dirname(file_path), "../../../../devel/share/")) + site_packages_build_root = os.path.realpath(os.path.join(os.path.dirname(file_path), "../../../../../../devel/share/")) + src_root = os.path.realpath(os.path.join(os.path.dirname(file_path), "../../../../share/")) + env_root = os.getenv("ERT_SHARE_PATH") + + if env_root is not None and os.path.exists(env_root): + root = os.path.realpath(env_root) + elif os.path.exists(build_root): + root = os.path.realpath(build_root) + elif os.path.exists(site_packages_build_root): + root = os.path.realpath(site_packages_build_root) + elif os.path.exists(src_root): + root = os.path.realpath(src_root) + else: + root = None + + return root + def assertNotRaises(self, func): try: func() except: self.fail() - - @staticmethod def slowTestShouldNotRun(): """ diff --git a/ThirdParty/Ert/devel/python/python/ert/test/path_context.py b/ThirdParty/Ert/devel/python/python/ert/test/path_context.py new file mode 100644 index 0000000000..0db2fc320b --- /dev/null +++ b/ThirdParty/Ert/devel/python/python/ert/test/path_context.py @@ -0,0 +1,46 @@ +import os +import shutil + +class PathContext(object): + def __init__(self , path , store = False): + self.path = path + self.cwd = os.getcwd() + self.store = store + self.path_list = [ ] + + if not os.path.exists(path): + work_path = path + + while True: + work_path , base = os.path.split(work_path) + if work_path: + if os.path.isdir(work_path): + break + else: + self.path_list.append( work_path ) + else: + break + + os.makedirs( path ) + else: + if not self.store: + raise OSError("Entry %s already exists" % path) + os.chdir( path ) + + + + def __exit__(self , exc_type , exc_val , exc_tb): + os.chdir( self.cwd ) + if self.store == False: + shutil.rmtree( self.path ) + for path in self.path_list: + try: + os.rmdir( path ) + except OSError: + break + + return False + + + def __enter__(self): + return self diff --git a/ThirdParty/Ert/devel/python/python/ert/util/CMakeLists.txt b/ThirdParty/Ert/devel/python/python/ert/util/CMakeLists.txt index e8a7ae9876..f0c3f86924 100644 --- a/ThirdParty/Ert/devel/python/python/ert/util/CMakeLists.txt +++ b/ThirdParty/Ert/devel/python/python/ert/util/CMakeLists.txt @@ -17,11 +17,13 @@ set(PYTHON_SOURCES stringlist.py substitution_list.py thread_pool.py + cthread_pool.py time_vector.py ui_return.py util_func.py vector_template.py version.py + arg_pack.py ) add_python_package("python.ert.util" ${PYTHON_INSTALL_PREFIX}/ert/util "${PYTHON_SOURCES}" True) diff --git a/ThirdParty/Ert/devel/python/python/ert/util/__init__.py b/ThirdParty/Ert/devel/python/python/ert/util/__init__.py index 6299f5b8d8..9311f5ebdd 100644 --- a/ThirdParty/Ert/devel/python/python/ert/util/__init__.py +++ b/ThirdParty/Ert/devel/python/python/ert/util/__init__.py @@ -73,8 +73,10 @@ from .substitution_list import SubstitutionList from .ui_return import UIReturn from .thread_pool import ThreadPool +from .cthread_pool import CThreadPool , startCThreadPool from .install_abort_signals import installAbortSignals from .profiler import Profiler +from .arg_pack import ArgPack # Check if latex functionality exists in libert_util if hasattr(UTIL_LIB, "latex_alloc"): diff --git a/ThirdParty/Ert/devel/python/python/ert/util/arg_pack.py b/ThirdParty/Ert/devel/python/python/ert/util/arg_pack.py new file mode 100644 index 0000000000..befb03e0a7 --- /dev/null +++ b/ThirdParty/Ert/devel/python/python/ert/util/arg_pack.py @@ -0,0 +1,63 @@ +# Copyright (C) 2015 Statoil ASA, Norway. +# +# The file 'arg_pack.py' is part of ERT - Ensemble based Reservoir Tool. +# +# ERT is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# ERT is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. +# +# See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> +# for more details. + +from ert.util import UTIL_LIB +from ert.cwrap import CWrapper, BaseCClass + + +class ArgPack(BaseCClass): + + def __init__(self , *args): + c_ptr = ArgPack.cNamespace().alloc() + super(ArgPack, self).__init__(c_ptr) + self.child_list = [] + for arg in args: + self.append( arg ) + + + + def append(self , data): + if isinstance(data , int): + ArgPack.cNamespace().append_int( self , data ) + elif isinstance(data , float): + ArgPack.cNamespace().append_double( self , data ) + elif isinstance(data , BaseCClass): + ArgPack.cNamespace().append_ptr( self , BaseCClass.from_param( data ) ) + self.child_list.append( data ) + else: + raise TypeError("Can only add int/double/basecclass") + + + def __len__(self): + return ArgPack.cNamespace().size(self) + + + + def free(self): + ArgPack.cNamespace().free(self) + + + +CWrapper.registerObjectType("arg_pack", ArgPack) + +cwrapper = CWrapper(UTIL_LIB) + +ArgPack.cNamespace().alloc = cwrapper.prototype("c_void_p arg_pack_alloc( )") +ArgPack.cNamespace().free = cwrapper.prototype("void arg_pack_free(arg_pack )") +ArgPack.cNamespace().size = cwrapper.prototype("int arg_pack_size(arg_pack )") +ArgPack.cNamespace().append_int = cwrapper.prototype("void arg_pack_append_int(arg_pack , int)") +ArgPack.cNamespace().append_double = cwrapper.prototype("void arg_pack_append_double(arg_pack ,double)") +ArgPack.cNamespace().append_ptr = cwrapper.prototype("void arg_pack_append_ptr(arg_pack , c_void_p)") diff --git a/ThirdParty/Ert/devel/python/python/ert/util/cthread_pool.py b/ThirdParty/Ert/devel/python/python/ert/util/cthread_pool.py new file mode 100644 index 0000000000..74190de652 --- /dev/null +++ b/ThirdParty/Ert/devel/python/python/ert/util/cthread_pool.py @@ -0,0 +1,83 @@ +# Copyright (C) 2015 Statoil ASA, Norway. +# +# The file 'cthread_pool.py' is part of ERT - Ensemble based Reservoir Tool. +# +# ERT is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# ERT is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. +# +# See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> +# for more details. + +import ctypes +from ert.util import UTIL_LIB +from ert.cwrap import CWrapper, BaseCClass + +class CThreadPool(BaseCClass): + def __init__(self , pool_size , start = True): + c_ptr = CThreadPool.cNamespace().alloc( pool_size , start ) + super(CThreadPool, self).__init__(c_ptr) + self.arg_list = [] + + def addTask(self , cfunc , arg): + """ + The function should come from CThreadPool.lookupCFunction(). + """ + if isinstance(arg, BaseCClass): + arg_ptr = BaseCClass.from_param( arg ) + else: + arg_ptr = arg + + self.arg_list.append( arg ) + CThreadPool.cNamespace().add_job( self , cfunc , arg_ptr ) + + + def join(self): + CThreadPool.cNamespace().join( self ) + + + def free(self): + self.join( ) + CThreadPool.cNamespace().free( self ) + + + @staticmethod + def lookupCFunction(lib , name): + if isinstance(lib , ctypes.CDLL): + func = getattr(lib , name) + return func + else: + raise TypeError("The lib argument must of type ctypes.CDLL") + + + +class CThreadPoolContextManager(object): + + def __init__(self , tp): + self.__tp = tp + + def __enter__(self): + return self.__tp + + def __exit__(self, exc_type, exc_val, exc_tb): + self.__tp.join() + return False + + +def startCThreadPool( size ): + return CThreadPoolContextManager( CThreadPool( size , start = True )) + + + +CWrapper.registerObjectType("thread_pool", CThreadPool) + +cwrapper = CWrapper(UTIL_LIB) +CThreadPool.cNamespace().alloc = cwrapper.prototype("c_void_p thread_pool_alloc( int , bool )") +CThreadPool.cNamespace().free = cwrapper.prototype("void thread_pool_free( thread_pool )") +CThreadPool.cNamespace().add_job = cwrapper.prototype("void thread_pool_add_job( thread_pool , c_void_p , c_void_p)") +CThreadPool.cNamespace().join = cwrapper.prototype("void thread_pool_join( thread_pool )") diff --git a/ThirdParty/Ert/devel/python/python/ert/util/ctime.py b/ThirdParty/Ert/devel/python/python/ert/util/ctime.py index 11498654e5..3f7a434725 100644 --- a/ThirdParty/Ert/devel/python/python/ert/util/ctime.py +++ b/ThirdParty/Ert/devel/python/python/ert/util/ctime.py @@ -15,12 +15,11 @@ # for more details. -import math import ctypes import datetime import time -from types import NoneType from ert.cwrap import CWrapper, BaseCValue +from ert.util import UTIL_LIB class CTime(BaseCValue): @@ -32,9 +31,9 @@ def __init__(self, value): elif isinstance(value, CTime): value = value.value() elif isinstance(value, datetime.datetime): - value = int(math.floor(time.mktime((value.year, value.month, value.day, value.hour, value.minute, value.second, 0, 0, -1 )))) + value = CTime._mktime(value.second, value.minute, value.hour, value.day, value.month, value.year) elif isinstance(value, datetime.date): - value = int(math.floor(time.mktime((value.year, value.month, value.day, 0, 0, 0, 0, 0, -1 )))) + value = CTime._mktime(0, 0, 0, value.day, value.month, value.year) else: raise NotImplementedError("Can not convert class %s to CTime" % value.__class__) @@ -57,7 +56,7 @@ def datetime(self): return datetime.datetime(*self.time()[0:6]) def __str__(self): - return "%s" % (str(self.datetime())) + return self.datetime().strftime("%Y-%m-%d %H:%M:%S%z") def __ge__(self, other): return self > other or self == other @@ -131,11 +130,26 @@ def timetuple(self): # this function is a requirement for comparing against datetime objects where the CTime is on the right side pass + def __repr__(self): + return "time_t value: %d [%s]" % (self.value(), str(self)) + + @property def stripped(self): return time.strptime(self, "%Y-%m-%d %H:%M:S%") + @classmethod + def timezone(cls): + """ + Returns the current timezone "in" C + @rtype: str + """ + return CTime._timezone() -cwrapper = CWrapper(None) + +cwrapper = CWrapper(UTIL_LIB) cwrapper.registerType("time_t", CTime) +CTime._timezone = cwrapper.prototype("char* util_get_timezone()") +CTime._mktime = cwrapper.prototype("long util_make_datetime(int, int, int, int, int, int)") + diff --git a/ThirdParty/Ert/devel/python/python/ert/util/int_vector.py b/ThirdParty/Ert/devel/python/python/ert/util/int_vector.py index 86362269de..2eb97c1cb3 100644 --- a/ThirdParty/Ert/devel/python/python/ert/util/int_vector.py +++ b/ThirdParty/Ert/devel/python/python/ert/util/int_vector.py @@ -25,9 +25,8 @@ def __init__(self, default_value=0, initial_size=0): super(IntVector, self).__init__(default_value, initial_size) @classmethod - def active_list(cls , range_string): - """ - Will create a IntVector instance with the values from @range_string. + def active_list(cls , range_string ): + """Will create a IntVector instance with the values from @range_string. The range_string input should be of the type "1,3-5,9,17", i.e. integer values separated by commas, and dashes to @@ -37,10 +36,26 @@ def active_list(cls , range_string): "1,4-7,10" => {1,4,5,6,7,10} "1,4-7,10X" => {} - The empty list will evaluate to false + The empty list will evaluate to false. The values in the input + string are meant to indicate "active values", i.e. the output + values are sorted and repeated values are only counted once: + + "1,1,7,2" => {1,2,7} + """ return cls.cNamespace().create_active_list(range_string) - + + @classmethod + def valueList(cls , range_string): + """Will create a IntVecter of all the values in the @range_string. + + Will not sort the values, and not uniquiefy - in contrast to + the active_list() method. + + """ + return cls.cNamespace().create_value_list(range_string) + + def count(self, value): """ @rtype: int """ return IntVector.cNamespace().count_equal(self, value) @@ -84,7 +99,8 @@ def count(self, value): IntVector.cNamespace().set_default = cwrapper.prototype("void int_vector_set_default( int_vector , int)") IntVector.cNamespace().get_default = cwrapper.prototype("int int_vector_get_default( int_vector )") IntVector.cNamespace().element_size = cwrapper.prototype("int int_vector_element_size( int_vector )") -IntVector.cNamespace().create_active_list = cwrapper.prototype("int_vector_obj string_util_alloc_active_list( char* )") +IntVector.cNamespace().create_active_list = cwrapper.prototype("int_vector_obj string_util_alloc_active_list( char*)") +IntVector.cNamespace().create_value_list = cwrapper.prototype("int_vector_obj string_util_alloc_value_list( char*)") IntVector.cNamespace().permute = cwrapper.prototype("void int_vector_permute(int_vector, permutation_vector)") IntVector.cNamespace().sort_perm = cwrapper.prototype("permutation_vector_obj int_vector_alloc_sort_perm(int_vector)") diff --git a/ThirdParty/Ert/devel/python/python/ert/util/rng.py b/ThirdParty/Ert/devel/python/python/ert/util/rng.py index 536a67ded3..c5f00a6d94 100644 --- a/ThirdParty/Ert/devel/python/python/ert/util/rng.py +++ b/ThirdParty/Ert/devel/python/python/ert/util/rng.py @@ -45,9 +45,12 @@ def getDouble(self): return RandomNumberGenerator.cNamespace().get_double(self) - def getInt(self): + def getInt(self, max=None): """ @rtype: float """ - return RandomNumberGenerator.cNamespace().get_int(self) + if max is None: + max = RandomNumberGenerator.cNamespace().get_max_int(self) + + return RandomNumberGenerator.cNamespace().get_int(self, max) def free(self): @@ -64,6 +67,7 @@ def free(self): RandomNumberGenerator.cNamespace().rng_alloc = cwrapper.prototype("c_void_p rng_alloc(rng_alg_type_enum, rng_init_mode_enum)") RandomNumberGenerator.cNamespace().free = cwrapper.prototype("void rng_free(rng)") RandomNumberGenerator.cNamespace().get_double = cwrapper.prototype("double rng_get_double(rng)") -RandomNumberGenerator.cNamespace().get_int = cwrapper.prototype("int rng_get_int(rng)") +RandomNumberGenerator.cNamespace().get_int = cwrapper.prototype("int rng_get_int(rng, int)") +RandomNumberGenerator.cNamespace().get_max_int = cwrapper.prototype("uint rng_get_max_int(rng)") RandomNumberGenerator.cNamespace().state_size = cwrapper.prototype("int rng_state_size(rng)") RandomNumberGenerator.cNamespace().set_state = cwrapper.prototype("void rng_set_state(rng , char*)") diff --git a/ThirdParty/Ert/devel/python/python/ert/util/stat.py b/ThirdParty/Ert/devel/python/python/ert/util/stat.py index d32b79d33d..f552a7acd5 100644 --- a/ThirdParty/Ert/devel/python/python/ert/util/stat.py +++ b/ThirdParty/Ert/devel/python/python/ert/util/stat.py @@ -18,7 +18,7 @@ from ert.util import UTIL_LIB from ert.util import Matrix from ert.util import LLSQResultEnum -from ert.cwrap import CWrapper, CWrapperNameSpace +from ert.cwrap import CWrapper, CWrapperNameSpace, CWrapError def quantile( data, q ): @@ -30,6 +30,9 @@ def quantile_sorted( data, q ): def polyfit(n,x,y,s = None): + if cfunc.polyfit is None: + raise NotImplementedError("Sorry - your ert distribution has been built without lapack support") + if isinstance(x,Matrix): xm = x else: @@ -79,5 +82,8 @@ def polyfit(n,x,y,s = None): cfunc.quantile = cwrapper.prototype("double statistics_empirical_quantile( double_vector , double )") cfunc.quantile_sorted = cwrapper.prototype("double statistics_empirical_quantile( double_vector , double )") -cfunc.polyfit = cwrapper.prototype("llsq_result_enum matrix_stat_polyfit(matrix , matrix , matrix , matrix)") +try: + cfunc.polyfit = cwrapper.prototype("llsq_result_enum matrix_stat_polyfit(matrix , matrix , matrix , matrix)") +except CWrapError: + cfunc.polyfit = None diff --git a/ThirdParty/Ert/devel/python/python/ert/util/stringlist.py b/ThirdParty/Ert/devel/python/python/ert/util/stringlist.py index 143dfcae8d..1bb2ecd837 100644 --- a/ThirdParty/Ert/devel/python/python/ert/util/stringlist.py +++ b/ThirdParty/Ert/devel/python/python/ert/util/stringlist.py @@ -69,6 +69,21 @@ def __init__(self, initial=None): raise TypeError("Item: %s not a string" % s) + def __eq__(self , other): + if len(self) == len(other): + if isinstance( other , StringList): + return StringList.cNamespace().equal(self, other) + else: + equal = True + for index,s2 in enumerate(other): + if self[index] != s2: + equal = False + break + return equal + else: + return False + + def __setitem__(self, index, value): if isinstance(index, IntType): length = self.__len__() @@ -240,6 +255,7 @@ def back(self): StringList.cNamespace().iset = cwrapper.prototype("void stringlist_iset_copy( stringlist , int , char* )") StringList.cNamespace().get_size = cwrapper.prototype("int stringlist_get_size( stringlist )") StringList.cNamespace().contains = cwrapper.prototype("bool stringlist_contains(stringlist , char*)") +StringList.cNamespace().equal = cwrapper.prototype("bool stringlist_equal(stringlist , stringlist)") StringList.cNamespace().sort = cwrapper.prototype("void stringlist_python_sort( stringlist , int)") StringList.cNamespace().pop = cwrapper.prototype("char* stringlist_pop(stringlist)") StringList.cNamespace().last = cwrapper.prototype("char* stringlist_get_last(stringlist)") diff --git a/ThirdParty/Ert/devel/python/python/ert_gui/CMakeLists.txt b/ThirdParty/Ert/devel/python/python/ert_gui/CMakeLists.txt index f119b0ad23..643fad617b 100644 --- a/ThirdParty/Ert/devel/python/python/ert_gui/CMakeLists.txt +++ b/ThirdParty/Ert/devel/python/python/ert_gui/CMakeLists.txt @@ -1,21 +1,21 @@ set(PYTHON_SOURCES __init__.py + about_dialog.py ert_splash.py gert_main.py ide_test.py main_window.py newconfig.py - about_dialog.py ) -add_python_package("python.ert_gui" ${PYTHON_INSTALL_PREFIX}/ert_gui "${PYTHON_SOURCES}" True) +add_python_package("python.ert_gui" ${PYTHON_INSTALL_PREFIX}/ert_gui "${PYTHON_SOURCES}" True) add_subdirectory(ide) add_subdirectory(models) add_subdirectory(pages) +add_subdirectory(plottery) add_subdirectory(shell) add_subdirectory(simulation) add_subdirectory(tools) add_subdirectory(viewer) add_subdirectory(widgets) - diff --git a/ThirdParty/Ert/devel/python/python/ert_gui/gert_main.py b/ThirdParty/Ert/devel/python/python/ert_gui/gert_main.py index db2a86090e..7741834032 100644 --- a/ThirdParty/Ert/devel/python/python/ert_gui/gert_main.py +++ b/ThirdParty/Ert/devel/python/python/ert_gui/gert_main.py @@ -247,7 +247,7 @@ def main(argv): window.addDock("Configuration Summary", SummaryPanel(), area=Qt.BottomDockWidgetArea) window.addTool(IdeTool(os.path.basename(config_file), ert.reloadERT, help_tool)) - window.addTool(PlotTool()) + window.addTool(PlotTool(ert.ert())) window.addTool(ExportTool()) window.addTool(WorkflowsTool()) window.addTool(ManageCasesTool()) diff --git a/ThirdParty/Ert/devel/python/python/ert_gui/models/connectors/init/case_list.py b/ThirdParty/Ert/devel/python/python/ert_gui/models/connectors/init/case_list.py index 340dc7a97a..f3ab98c067 100644 --- a/ThirdParty/Ert/devel/python/python/ert_gui/models/connectors/init/case_list.py +++ b/ThirdParty/Ert/devel/python/python/ert_gui/models/connectors/init/case_list.py @@ -34,6 +34,15 @@ def getAllCasesWithDataAndNotRunning(self): return cases_with_data_and_not_running + def getAllCasesNotRunning(self): + cases = self.getList() + cases_not_running = [] + for case in cases: + if not self.ert().getEnkfFsManager().isCaseRunning(case): + cases_not_running.append(case) + + return cases_not_running + def getCaseRealizationStates(self, case_name): state_map = self.ert().getEnkfFsManager().getStateMapForCase(case_name) diff --git a/ThirdParty/Ert/devel/python/python/ert_gui/models/mixins/connectorless/CMakeLists.txt b/ThirdParty/Ert/devel/python/python/ert_gui/models/mixins/connectorless/CMakeLists.txt index f48937f005..c5b3f552cc 100644 --- a/ThirdParty/Ert/devel/python/python/ert_gui/models/mixins/connectorless/CMakeLists.txt +++ b/ThirdParty/Ert/devel/python/python/ert_gui/models/mixins/connectorless/CMakeLists.txt @@ -1,6 +1,7 @@ set(PYTHON_SOURCES __init__.py default_boolean_model.py + default_choice_list_model.py default_name_format_model.py default_path_model.py function_button_model.py diff --git a/ThirdParty/Ert/devel/python/python/ert_gui/models/mixins/connectorless/__init__.py b/ThirdParty/Ert/devel/python/python/ert_gui/models/mixins/connectorless/__init__.py index 1e4cbfe915..612e817818 100644 --- a/ThirdParty/Ert/devel/python/python/ert_gui/models/mixins/connectorless/__init__.py +++ b/ThirdParty/Ert/devel/python/python/ert_gui/models/mixins/connectorless/__init__.py @@ -3,3 +3,4 @@ from .default_boolean_model import DefaultBooleanModel from .string_model import StringModel from .default_name_format_model import DefaultNameFormatModel +from .default_choice_list_model import DefaultChoiceListModel diff --git a/ThirdParty/Ert/devel/python/python/ert_gui/models/mixins/connectorless/default_choice_list_model.py b/ThirdParty/Ert/devel/python/python/ert_gui/models/mixins/connectorless/default_choice_list_model.py new file mode 100644 index 0000000000..890ea767fc --- /dev/null +++ b/ThirdParty/Ert/devel/python/python/ert_gui/models/mixins/connectorless/default_choice_list_model.py @@ -0,0 +1,26 @@ +from ert_gui.models.mixins import ChoiceModelMixin, ListModelMixin + + +class DefaultChoiceListModel(ListModelMixin, ChoiceModelMixin): + + def __init__(self, choices, default_choice=None): + assert choices is not None and len(choices) > 0 + self.__choices = choices + self.__value = None if not default_choice in choices else default_choice + super(DefaultChoiceListModel, self).__init__() + + def getList(self): + return self.__choices + + def getChoices(self): + return self.getList() + + def getCurrentChoice(self): + if self.__value is None: + return self.getList()[0] + return self.__value + + def setCurrentChoice(self, value): + self.__value = value + self.observable().notify(self.CURRENT_CHOICE_CHANGED_EVENT) + diff --git a/ThirdParty/Ert/devel/python/python/ert_gui/pages/run_dialog.py b/ThirdParty/Ert/devel/python/python/ert_gui/pages/run_dialog.py index dc37053900..d8569eb3b0 100644 --- a/ThirdParty/Ert/devel/python/python/ert_gui/pages/run_dialog.py +++ b/ThirdParty/Ert/devel/python/python/ert_gui/pages/run_dialog.py @@ -2,6 +2,7 @@ from PyQt4.QtCore import Qt, pyqtSignal, QTimer, QSize from PyQt4.QtGui import QDialog, QVBoxLayout, QLayout, QMessageBox, QPushButton, QHBoxLayout, QColor, QLabel from ert_gui.models.connectors.run import SimulationsTracker +from ert_gui.models.ert_connector import ErtConnector from ert_gui.models.mixins.run_model import RunModelMixin from ert_gui.tools.plot.plot_tool import PlotTool from ert_gui.widgets import util @@ -57,11 +58,16 @@ def __init__(self, run_model): self.running_time = QLabel("") - self.plot_tool = PlotTool() + ert = None + if isinstance(run_model, ErtConnector): + ert = run_model.ert() + + self.plot_tool = PlotTool(ert) self.plot_tool.setParent(self) self.plot_button = QPushButton(self.plot_tool.getName()) self.plot_button.clicked.connect(self.plot_tool.trigger) - + self.plot_button.setEnabled(ert is not None) + self.kill_button = QPushButton("Kill simulations") self.done_button = QPushButton("Done") self.done_button.setHidden(True) @@ -194,4 +200,4 @@ def hideKillAndShowDone(self): self.__update_timer.stop() self.processing_animation.hide() self.kill_button.setHidden(True) - self.done_button.setHidden(False) \ No newline at end of file + self.done_button.setHidden(False) diff --git a/ThirdParty/Ert/devel/python/python/ert_gui/plottery/CMakeLists.txt b/ThirdParty/Ert/devel/python/python/ert_gui/plottery/CMakeLists.txt new file mode 100644 index 0000000000..138639ecd0 --- /dev/null +++ b/ThirdParty/Ert/devel/python/python/ert_gui/plottery/CMakeLists.txt @@ -0,0 +1,10 @@ +set(PYTHON_SOURCES + __init__.py + plot_config.py + plot_context.py + plot_data_gatherer.py +) + +add_python_package("python.ert_gui.plottery" ${PYTHON_INSTALL_PREFIX}/ert_gui/plottery "${PYTHON_SOURCES}" True) + +add_subdirectory(plots) diff --git a/ThirdParty/Ert/devel/python/python/ert_gui/plottery/__init__.py b/ThirdParty/Ert/devel/python/python/ert_gui/plottery/__init__.py new file mode 100644 index 0000000000..20003f6e23 --- /dev/null +++ b/ThirdParty/Ert/devel/python/python/ert_gui/plottery/__init__.py @@ -0,0 +1,4 @@ +from .plot_data_gatherer import PlotDataGatherer +from .plot_config import PlotConfig +from .plot_context import PlotContext + diff --git a/ThirdParty/Ert/devel/python/python/ert_gui/plottery/plot_config.py b/ThirdParty/Ert/devel/python/python/ert_gui/plottery/plot_config.py new file mode 100644 index 0000000000..1dcef021a5 --- /dev/null +++ b/ThirdParty/Ert/devel/python/python/ert_gui/plottery/plot_config.py @@ -0,0 +1,143 @@ +import itertools + + +class PlotConfig(object): + + def __init__(self, title="Unnamed", x_label=None, y_label=None): + super(PlotConfig, self).__init__() + self.__title = title + + self.__line_color_cycle = itertools.cycle(["#000000"]) #Black + # Blueish, Greenlike, Beigeoid, Pinkness, Orangy-Brown + self.setLineColorCycle(["#386CB0", "#7FC97F", "#FDC086", "#F0027F", "#BF5B17"]) + + self.__legend_items = [] + self.__legend_labels = [] + + self.__x_label = x_label + self.__y_label = y_label + + + self.__line_color = None + self.__line_style = "-" + self.__line_alpha = 0.8 + self.__line_marker = None + + self.__observations_enabled = True + self.__observations_color = "#000000" #Black + self.__observations_alpha = 1.0 + + self.__refcase_enabled = True + self.__refcase_color = "#000000" #Black + self.__refcase_alpha = 0.8 + self.__refcase_style = "-" + self.__refcase_marker = "x" + self.__refcase_width = 2.0 + + self.__legend_enabled = True + self.__grid_enabled = True + self.__date_support_active = True + + + def lineColor(self): + if self.__line_color is None: + self.nextColor() + + return self.__line_color + + def nextColor(self): + self.__line_color = self.__line_color_cycle.next() + return self.__line_color + + def setLineColorCycle(self, color_list): + self.__line_color_cycle = itertools.cycle(color_list) + + def addLegendItem(self, label, item): + self.__legend_items.append(item) + self.__legend_labels.append(label) + + def title(self): + """ :rtype: str """ + return self.__title + + def lineStyle(self): + return self.__line_style + + def lineAlpha(self): + return self.__line_alpha + + def lineMarker(self): + return self.__line_marker + + def xLabel(self): + return self.__x_label + + def yLabel(self): + return self.__y_label + + def legendItems(self): + return self.__legend_items + + def legendLabels(self): + return self.__legend_labels + + def setXLabel(self, label): + self.__x_label = label + + def setYLabel(self, label): + self.__y_label = label + + + def setObservationsEnabled(self, enabled): + self.__observations_enabled = enabled + + def isObservationsEnabled(self): + return self.__observations_enabled + + def observationsColor(self): + return self.__observations_color + + def observationsAlpha(self): + return self.__observations_alpha + + + def setRefcaseEnabled(self, enabled): + self.__refcase_enabled = enabled + + def isRefcaseEnabled(self): + return self.__refcase_enabled + + def refcaseColor(self): + return self.__refcase_color + + def refcaseAlpha(self): + return self.__refcase_alpha + + def refcaseStyle(self): + return self.__refcase_style + + def refcaseMarker(self): + return self.__refcase_marker + + def refcaseWidth(self): + return self.__refcase_width + + + def isLegendEnabled(self): + return self.__legend_enabled + + def setLegendEnabled(self, enabled): + self.__legend_enabled = enabled + + + def isGridEnabled(self): + return self.__grid_enabled + + def setGridEnabled(self, enabled): + self.__grid_enabled = enabled + + def deactiveDateSupport(self): + self.__date_support_active = False + + def isDateSupportActive(self): + return self.__date_support_active diff --git a/ThirdParty/Ert/devel/python/python/ert_gui/plottery/plot_context.py b/ThirdParty/Ert/devel/python/python/ert_gui/plottery/plot_context.py new file mode 100644 index 0000000000..9a6b02790c --- /dev/null +++ b/ThirdParty/Ert/devel/python/python/ert_gui/plottery/plot_context.py @@ -0,0 +1,39 @@ +from .plot_config import PlotConfig +from .plot_data_gatherer import PlotDataGatherer + +class PlotContext(object): + + def __init__(self, ert, figure, plot_config, cases, key, data_gatherer): + super(PlotContext, self).__init__() + self.__data_gatherer = data_gatherer + self.__key = key + self.__cases = cases + self.__figure = figure + self.__ert = ert + self.__plot_config = plot_config + + def figure(self): + """ :rtype: matplotlib.figure.Figure""" + return self.__figure + + def plotConfig(self): + """ :rtype: PlotConfig """ + return self.__plot_config + + def ert(self): + """ :rtype: ert.enkf.EnKFMain""" + return self.__ert + + def cases(self): + """ :rtype: list of str """ + return self.__cases + + def key(self): + """ :rtype: str """ + return self.__key + + def dataGatherer(self): + """ :rtype: PlotDataGatherer """ + return self.__data_gatherer + + diff --git a/ThirdParty/Ert/devel/python/python/ert_gui/plottery/plot_data_gatherer.py b/ThirdParty/Ert/devel/python/python/ert_gui/plottery/plot_data_gatherer.py new file mode 100644 index 0000000000..7c60ddfe3b --- /dev/null +++ b/ThirdParty/Ert/devel/python/python/ert_gui/plottery/plot_data_gatherer.py @@ -0,0 +1,132 @@ +from pandas import DataFrame +from ert.enkf.export import GenKwCollector, SummaryCollector, GenDataCollector, SummaryObservationCollector, \ + GenDataObservationCollector, CustomKWCollector + + +class PlotDataGatherer(object): + + def __init__(self, dataGatherFunc, conditionFunc, refcaseGatherFunc=None, observationGatherFunc=None): + super(PlotDataGatherer, self).__init__() + + self.__dataGatherFunction = dataGatherFunc + self.__conditionFunction = conditionFunc + self.__refcaseGatherFunction = refcaseGatherFunc + self.__observationGatherFunction = observationGatherFunc + + def hasRefcaseGatherFunction(self): + """ :rtype: bool """ + return self.__refcaseGatherFunction is not None + + def hasObservationGatherFunction(self): + """ :rtype: bool """ + return self.__observationGatherFunction is not None + + def canGatherDataForKey(self, key): + """ :rtype: bool """ + return self.__conditionFunction(key) + + def gatherData(self, ert, case, key): + """ :rtype: pandas.DataFrame """ + if not self.canGatherDataForKey(key): + raise UserWarning("Unable to gather data for key: %s" % key) + + return self.__dataGatherFunction(ert, case, key) + + def gatherRefcaseData(self, ert, key): + """ :rtype: pandas.DataFrame """ + if not self.canGatherDataForKey(key) or not self.hasRefcaseGatherFunction(): + raise UserWarning("Unable to gather refcase data for key: %s" % key) + + return self.__refcaseGatherFunction(ert, key) + + def gatherObservationData(self, ert, case, key): + """ :rtype: pandas.DataFrame """ + if not self.canGatherDataForKey(key) or not self.hasObservationGatherFunction(): + raise UserWarning("Unable to gather observation data for key: %s" % key) + + return self.__observationGatherFunction(ert, case, key) + + + @staticmethod + def gatherGenKwData(ert, case, key): + """ :rtype: pandas.DataFrame """ + data = GenKwCollector.loadAllGenKwData(ert, case, [key]) + return data[key].dropna() + + @staticmethod + def gatherSummaryData(ert, case, key): + """ :rtype: pandas.DataFrame """ + data = SummaryCollector.loadAllSummaryData(ert, case, [key]) + if not data.empty: + data = data.reset_index() + data = data.pivot(index="Date", columns="Realization", values=key) + + return data #.dropna() + + @staticmethod + def gatherSummaryRefcaseData(ert, key): + refcase = ert.eclConfig().getRefcase() + + if not key in refcase: + return DataFrame() + + vector = refcase.get_vector(key, report_only=False) + + rows = [] + for index in range(1, len(vector)): + node = vector[index] + row = { + "Date": node.date, + key: node.value + } + rows.append(row) + + data = DataFrame(rows) + data = data.set_index("Date") + + return data + + @staticmethod + def gatherSummaryObservationData(ert, case, key): + if ert.getKeyManager().isKeyWithObservations(key): + return SummaryObservationCollector.loadObservationData(ert, case, [key]).dropna() + else: + return DataFrame() + + + @staticmethod + def gatherGenDataData(ert, case, key): + """ :rtype: pandas.DataFrame """ + key, report_step = key.split("@", 1) + report_step = int(report_step) + try: + data = GenDataCollector.loadGenData(ert, case, key, report_step) + except ValueError: + data = DataFrame() + + return data.dropna() # removes all rows that has a NaN + + + @staticmethod + def gatherGenDataObservationData(ert, case, key_with_report_step): + """ :rtype: pandas.DataFrame """ + key, report_step = key_with_report_step.split("@", 1) + report_step = int(report_step) + + obs_key = GenDataObservationCollector.getObservationKeyForDataKey(ert, key, report_step) + + if obs_key is not None: + obs_data = GenDataObservationCollector.loadGenDataObservations(ert, case, [obs_key]) + columns = {obs_key: key_with_report_step, "STD_%s" % obs_key: "STD_%s" % key_with_report_step} + obs_data = obs_data.rename(columns=columns) + else: + obs_data = DataFrame() + + return obs_data.dropna() + + @staticmethod + def gatherCustomKwData(ert, case, key): + """ :rtype: pandas.DataFrame """ + data = CustomKWCollector.loadAllCustomKWData(ert, case, [key]) + + return data diff --git a/ThirdParty/Ert/devel/python/python/ert_gui/plottery/plots/CMakeLists.txt b/ThirdParty/Ert/devel/python/python/ert_gui/plottery/plots/CMakeLists.txt new file mode 100644 index 0000000000..31fc925843 --- /dev/null +++ b/ThirdParty/Ert/devel/python/python/ert_gui/plottery/plots/CMakeLists.txt @@ -0,0 +1,14 @@ +set(PYTHON_SOURCES + __init__.py + ensemble.py + gaussian_kde.py + histogram.py + observations.py + overview.py + plot_tools.py + refcase.py + statistics.py +) + +add_python_package("python.ert_gui.plottery.plots" ${PYTHON_INSTALL_PREFIX}/ert_gui/plottery/plots "${PYTHON_SOURCES}" True) + diff --git a/ThirdParty/Ert/devel/python/python/ert_gui/plottery/plots/__init__.py b/ThirdParty/Ert/devel/python/python/ert_gui/plottery/plots/__init__.py new file mode 100644 index 0000000000..2cc576334d --- /dev/null +++ b/ThirdParty/Ert/devel/python/python/ert_gui/plottery/plots/__init__.py @@ -0,0 +1,9 @@ +from .histogram import plotHistogram +from .gaussian_kde import plotGaussianKDE + +from .refcase import plotRefcase +from .observations import plotObservations + +from .ensemble import plotEnsemble +from .statistics import plotStatistics +from .overview import plotOverview \ No newline at end of file diff --git a/ThirdParty/Ert/devel/python/python/ert_gui/plottery/plots/ensemble.py b/ThirdParty/Ert/devel/python/python/ert_gui/plottery/plots/ensemble.py new file mode 100644 index 0000000000..63b37ebf52 --- /dev/null +++ b/ThirdParty/Ert/devel/python/python/ert_gui/plottery/plots/ensemble.py @@ -0,0 +1,52 @@ +from .refcase import plotRefcase +from .observations import plotObservations +from .plot_tools import PlotTools + +def plotEnsemble(plot_context): + """ + @type plot_context: PlotContext + """ + ert = plot_context.ert() + key = plot_context.key() + config = plot_context.plotConfig() + axes = plot_context.figure().add_subplot(111) + """:type: matplotlib.axes.Axes """ + + case_list = plot_context.cases() + + for case in case_list: + data = plot_context.dataGatherer().gatherData(ert, case, key) + if not data.empty: + if not data.index.is_all_dates: + config.deactiveDateSupport() + + _plotLines(axes, config, data, case) + config.nextColor() + + plotRefcase(plot_context, axes) + plotObservations(plot_context, axes) + + default_x_label = "Date" if config.isDateSupportActive() else "Index" + PlotTools.finalizePlot(plot_context, axes, default_x_label=default_x_label, default_y_label="Value") + + +def _plotLines(axes, plot_config, data, ensemble_label): + """ + @type axes: matplotlib.axes.Axes + @type plot_config: PlotConfig + @type data: DataFrame + @type ensemble_label: Str + """ + + line_color = plot_config.lineColor() + line_alpha = plot_config.lineAlpha() + line_marker = plot_config.lineMarker() + line_style = plot_config.lineStyle() + + if plot_config.isDateSupportActive(): + lines = axes.plot_date(x=data.index.values, y=data, color=line_color, alpha=line_alpha, marker=line_marker, linestyle=line_style) + else: + lines = axes.plot(data.index.values, data, color=line_color, alpha=line_alpha, marker=line_marker, linestyle=line_style) + + if len(lines) > 0: + plot_config.addLegendItem(ensemble_label, lines[0]) diff --git a/ThirdParty/Ert/devel/python/python/ert_gui/plottery/plots/gaussian_kde.py b/ThirdParty/Ert/devel/python/python/ert_gui/plottery/plots/gaussian_kde.py new file mode 100644 index 0000000000..0f864be7b3 --- /dev/null +++ b/ThirdParty/Ert/devel/python/python/ert_gui/plottery/plots/gaussian_kde.py @@ -0,0 +1,65 @@ +import numpy +from scipy.stats import gaussian_kde +from .plot_tools import PlotTools + + +def plotGaussianKDE(plot_context): + """ + @type plot_context: PlotContext + """ + ert = plot_context.ert() + key = plot_context.key() + config = plot_context.plotConfig() + axes = plot_context.figure().add_subplot(111) + """:type: matplotlib.axes.Axes """ + + config.deactiveDateSupport() + + if key.startswith("LOG10_"): + key = key[6:] + axes.set_xscale("log") + + case_list = plot_context.cases() + for case in case_list: + data = plot_context.dataGatherer().gatherData(ert, case, key) + + if not data.empty and data.nunique() > 1: + _plotGaussianKDE(axes, config, data, case) + config.nextColor() + + PlotTools.finalizePlot(plot_context, axes, default_x_label="Value", default_y_label="Density") + + +def _plotGaussianKDE(axes, plot_config, data, label): + """ + @type axes: matplotlib.axes.Axes + @type plot_config: PlotConfig + @type data: DataFrame + @type label: Str + """ + + # axes.set_xlabel(plot_config.xLabel()) + # axes.set_ylabel(plot_config.yLabel()) + + line_color = plot_config.lineColor() + line_alpha = plot_config.lineAlpha() + line_marker = plot_config.lineMarker() + line_style = plot_config.lineStyle() + line_width = 2 + + if data.dtype == "object": + data = data.convert_objects(convert_numeric=True) + + if data.dtype == "object": + pass + + else: + sample_range = data.max() - data.min() + indexes = numpy.linspace(data.min() - 0.5 * sample_range, data.max() + 0.5 * sample_range, 1000) + gkde = gaussian_kde(data.values) + evaluated_gkde = gkde.evaluate(indexes) + + lines = axes.plot(indexes, evaluated_gkde, linewidth=line_width, color=line_color, alpha=line_alpha) + + if len(lines) > 0: + plot_config.addLegendItem(label, lines[0]) \ No newline at end of file diff --git a/ThirdParty/Ert/devel/python/python/ert_gui/plottery/plots/histogram.py b/ThirdParty/Ert/devel/python/python/ert_gui/plottery/plots/histogram.py new file mode 100644 index 0000000000..8ba9250373 --- /dev/null +++ b/ThirdParty/Ert/devel/python/python/ert_gui/plottery/plots/histogram.py @@ -0,0 +1,141 @@ +from math import sqrt, ceil, floor, log10 +from matplotlib.patches import Rectangle +import numpy +from .plot_tools import PlotTools + + + +def plotHistogram(plot_context): + """ + @type plot_context: ert_gui.plottery.PlotContext + """ + ert = plot_context.ert() + key = plot_context.key() + config = plot_context.plotConfig() + case_list = plot_context.cases() + case_count = len(case_list) + + if config.xLabel() is None: + config.setXLabel("Value") + + if config.yLabel() is None: + config.setYLabel("Count") + + use_log_scale = False + if key.startswith("LOG10_"): + key = key[6:] + use_log_scale = True + + data = {} + minimum = None + maximum = None + for case in case_list: + data[case] = plot_context.dataGatherer().gatherData(ert, case, key) + + if minimum is None: + minimum = data[case].min() + else: + minimum = min(minimum, data[case].min()) + + if maximum is None: + maximum = data[case].max() + else: + maximum = max(maximum, data[case].max()) + + #todo: bin count must also be determined across all cases... + + axes = {} + """:type: dict of (str, matplotlib.axes.Axes) """ + for index, case in enumerate(case_list): + axes[case] = plot_context.figure().add_subplot(case_count, 1, index + 1) + + axes[case].set_title("%s (%s)" % (config.title(), case)) + + if use_log_scale: + axes[case].set_xscale("log") + + if not data[case].empty: + _plotHistogram(axes[case], config, data[case], case, use_log_scale, minimum, maximum) + + config.nextColor() + PlotTools.showGrid(axes[case], plot_context) + + max_count = max([subplot.get_ylim()[1] for subplot in axes.values()]) + + for subplot in axes.values(): + subplot.set_ylim(0, max_count) + + +def _plotHistogram(axes, plot_config, data, label, use_log_scale=False, minimum=None, maximum=None): + """ + @type axes: matplotlib.axes.Axes + @type plot_config: PlotConfig + @type data: DataFrame + @type label: Str + """ + + axes.set_xlabel(plot_config.xLabel()) + axes.set_ylabel(plot_config.yLabel()) + + line_color = plot_config.lineColor() + line_alpha = plot_config.lineAlpha() + line_marker = plot_config.lineMarker() + line_style = plot_config.lineStyle() + line_width = 2 + + if data.dtype == "object": + data = data.convert_objects(convert_numeric=True) + + if data.dtype == "object": + counts = data.value_counts() + x = counts.index.values + freq = counts.values + pos = numpy.arange(len(x)) + width = 1.0 + axes.set_xticks(pos + (width / 2.0)) + axes.set_xticklabels(x) + axes.bar(pos, freq, alpha=line_alpha, color=line_color, width=width) + else: + bins = int(ceil(sqrt(len(data.index)))) + + if use_log_scale: + bins = _histogramLogBins(data, bins, minimum, maximum) + elif minimum is not None and maximum is not None: + bins = numpy.linspace(minimum, maximum, bins) + + axes.hist(data.values, alpha=line_alpha, bins=bins, color=line_color) + + rectangle = Rectangle((0, 0), 1, 1, color=line_color) # creates rectangle patch for legend use.' + plot_config.addLegendItem(label, rectangle) + + + +def _histogramLogBins(data, bin_count, minimum=None, maximum=None): + """ + @type data: pandas.DataFrame + @rtype: int + """ + + if minimum is None: + minimum = data.min() + + if maximum is None: + maximum = data.max() + + minimum = log10(float(minimum)) + maximum = log10(float(maximum)) + + min_value = int(floor(minimum)) + max_value = int(ceil(maximum)) + + log_bin_count = max_value - min_value + + if log_bin_count < bin_count: + next_bin_count = log_bin_count * 2 + + if bin_count - log_bin_count > next_bin_count - bin_count: + log_bin_count = next_bin_count + else: + log_bin_count = bin_count + + return 10 ** numpy.linspace(minimum, maximum, log_bin_count) \ No newline at end of file diff --git a/ThirdParty/Ert/devel/python/python/ert_gui/plottery/plots/observations.py b/ThirdParty/Ert/devel/python/python/ert_gui/plottery/plots/observations.py new file mode 100644 index 0000000000..6df1291480 --- /dev/null +++ b/ThirdParty/Ert/devel/python/python/ert_gui/plottery/plots/observations.py @@ -0,0 +1,29 @@ +def plotObservations(plot_context, axes): + ert = plot_context.ert() + key = plot_context.key() + config = plot_context.plotConfig() + case_list = plot_context.cases() + data_gatherer = plot_context.dataGatherer() + + if config.isObservationsEnabled() and data_gatherer.hasObservationGatherFunction(): + if len(case_list) > 0: + observation_data = data_gatherer.gatherObservationData(ert, case_list[0], key) + + if not observation_data.empty: + _plotObservations(axes, config, observation_data, value_column=key) + + + +def _plotObservations(axes, plot_config, data, value_column): + """ + @type axes: matplotlib.axes.Axes + @type plot_config: PlotConfig + @type data: DataFrame + @type value_column: Str + """ + + error_color = plot_config.observationsColor() + error_alpha = plot_config.observationsAlpha() + + errorbars = axes.errorbar(x=data.index.values, y=data[value_column], yerr=data["STD_%s" % value_column], + fmt=' ', ecolor=error_color, alpha=error_alpha) \ No newline at end of file diff --git a/ThirdParty/Ert/devel/python/python/ert_gui/plottery/plots/overview.py b/ThirdParty/Ert/devel/python/python/ert_gui/plottery/plots/overview.py new file mode 100644 index 0000000000..93686dbdba --- /dev/null +++ b/ThirdParty/Ert/devel/python/python/ert_gui/plottery/plots/overview.py @@ -0,0 +1,54 @@ +from matplotlib.patches import Rectangle +from pandas import DataFrame +from .refcase import plotRefcase +from .observations import plotObservations +from .plot_tools import PlotTools + + +def plotOverview(plot_context): + """ + @type plot_context: ert_gui.plottery.PlotContext + """ + ert = plot_context.ert() + key = plot_context.key() + config = plot_context.plotConfig() + axes = plot_context.figure().add_subplot(111) + """:type: matplotlib.axes.Axes """ + + case_list = plot_context.cases() + for case in case_list: + data = plot_context.dataGatherer().gatherData(ert, case, key) + if not data.empty: + if not data.index.is_all_dates: + config.deactiveDateSupport() + + min_max_data = DataFrame() + min_max_data["Minimum"] = data.min(axis=1) + min_max_data["Maximum"] = data.max(axis=1) + + _plotArea(axes, config, min_max_data, case) + config.nextColor() + + plotRefcase(plot_context, axes) + plotObservations(plot_context, axes) + + default_x_label = "Date" if config.isDateSupportActive() else "Index" + PlotTools.finalizePlot(plot_context, axes, default_x_label=default_x_label, default_y_label="Value") + + +def _plotArea(axes, plot_config, data, ensemble_label): + """ + @type axes: matplotlib.axes.Axes + @type plot_config: PlotConfig + @type data: DataFrame + @type ensemble_label: Str + """ + + line_color = plot_config.lineColor() + line_alpha = plot_config.lineAlpha() * 0.5 + + poly_collection = axes.fill_between(data.index.values, data["Minimum"].values, data["Maximum"].values, alpha=line_alpha, color=line_color) + + rectangle = Rectangle((0, 0), 1, 1, color=line_color) # creates rectangle patch for legend use. + + plot_config.addLegendItem(ensemble_label, rectangle) \ No newline at end of file diff --git a/ThirdParty/Ert/devel/python/python/ert_gui/plottery/plots/plot_tools.py b/ThirdParty/Ert/devel/python/python/ert_gui/plottery/plots/plot_tools.py new file mode 100644 index 0000000000..1e8a4a09e3 --- /dev/null +++ b/ThirdParty/Ert/devel/python/python/ert_gui/plottery/plots/plot_tools.py @@ -0,0 +1,48 @@ +class PlotTools(object): + @staticmethod + def showGrid(axes, plot_context): + config = plot_context.plotConfig() + if config.isGridEnabled(): + axes.grid() + + + @staticmethod + def showLegend(axes, plot_context): + config = plot_context.plotConfig() + if config.isLegendEnabled() and len(config.legendItems()) > 0: + axes.legend(config.legendItems(), config.legendLabels()) + + + @staticmethod + def finalizePlot(plot_context, axes, default_x_label="Unnamed", default_y_label="Unnamed"): + PlotTools.showLegend(axes, plot_context) + PlotTools.showGrid(axes, plot_context) + + PlotTools.__setupLabels(plot_context, default_x_label, default_y_label) + + plot_config = plot_context.plotConfig() + axes.set_xlabel(plot_config.xLabel()) + axes.set_ylabel(plot_config.yLabel()) + + axes.set_title(plot_config.title()) + + if plot_config.isDateSupportActive(): + plot_context.figure().autofmt_xdate() + + + @staticmethod + def __setupLabels(plot_context, default_x_label, default_y_label): + ert = plot_context.ert() + key = plot_context.key() + config = plot_context.plotConfig() + + if config.xLabel() is None: + config.setXLabel(default_x_label) + + if config.yLabel() is None: + config.setYLabel(default_y_label) + + if ert.eclConfig().hasRefcase() and key in ert.eclConfig().getRefcase(): + unit = ert.eclConfig().getRefcase().unit(key) + if unit != "": + config.setYLabel(unit) \ No newline at end of file diff --git a/ThirdParty/Ert/devel/python/python/ert_gui/plottery/plots/refcase.py b/ThirdParty/Ert/devel/python/python/ert_gui/plottery/plots/refcase.py new file mode 100644 index 0000000000..bab0d828b9 --- /dev/null +++ b/ThirdParty/Ert/devel/python/python/ert_gui/plottery/plots/refcase.py @@ -0,0 +1,30 @@ +def plotRefcase(plot_context, axes): + ert = plot_context.ert() + key = plot_context.key() + config = plot_context.plotConfig() + data_gatherer = plot_context.dataGatherer() + + if config.isRefcaseEnabled() and data_gatherer.hasRefcaseGatherFunction(): + refcase_data = data_gatherer.gatherRefcaseData(ert, key) + + if not refcase_data.empty: + _plotRefcase(axes, config, refcase_data) + + +def _plotRefcase(axes, plot_config, data): + """ + @type axes: matplotlib.axes.Axes + @type plot_config: PlotConfig + @type data: DataFrame + """ + + line_color = plot_config.refcaseColor() + line_alpha = plot_config.refcaseAlpha() + line_marker = plot_config.refcaseMarker() + line_style = plot_config.refcaseStyle() + line_width = plot_config.refcaseWidth() + + lines = axes.plot_date(x=data.index.values, y=data, color=line_color, alpha=line_alpha, marker=line_marker, linestyle=line_style, linewidth=line_width) + + if len(lines) > 0: + plot_config.addLegendItem("Refcase", lines[0]) \ No newline at end of file diff --git a/ThirdParty/Ert/devel/python/python/ert_gui/plottery/plots/statistics.py b/ThirdParty/Ert/devel/python/python/ert_gui/plottery/plots/statistics.py new file mode 100644 index 0000000000..72e08c36f7 --- /dev/null +++ b/ThirdParty/Ert/devel/python/python/ert_gui/plottery/plots/statistics.py @@ -0,0 +1,71 @@ +from matplotlib.patches import Rectangle +from pandas import DataFrame +from .refcase import plotRefcase +from .observations import plotObservations +from .plot_tools import PlotTools + + +def plotStatistics(plot_context): + """ + @type plot_context: PlotContext + """ + ert = plot_context.ert() + key = plot_context.key() + config = plot_context.plotConfig() + axes = plot_context.figure().add_subplot(111) + """:type: matplotlib.axes.Axes """ + + case_list = plot_context.cases() + for case in case_list: + data = plot_context.dataGatherer().gatherData(ert, case, key) + if not data.empty: + if not data.index.is_all_dates: + config.deactiveDateSupport() + + statistics_data = DataFrame() + + statistics_data["Minimum"] = data.min(axis=1) + statistics_data["Maximum"] = data.max(axis=1) + statistics_data["Mean"] = data.mean(axis=1) + statistics_data["p10"] = data.quantile(0.1, axis=1) + statistics_data["p33"] = data.quantile(0.33, axis=1) + statistics_data["p50"] = data.quantile(0.50, axis=1) + statistics_data["p67"] = data.quantile(0.67, axis=1) + statistics_data["p90"] = data.quantile(0.90, axis=1) + + _plotPercentiles(axes, config, statistics_data, case) + config.nextColor() + + plotRefcase(plot_context, axes) + plotObservations(plot_context, axes) + + default_x_label = "Date" if config.isDateSupportActive() else "Index" + PlotTools.finalizePlot(plot_context, axes, default_x_label=default_x_label, default_y_label="Value") + + +def _plotPercentiles(axes, plot_config, data, ensemble_label): + """ + @type axes: matplotlib.axes.Axes + @type plot_config: PlotConfig + @type data: DataFrame + @type ensemble_label: Str + """ + + line_color = plot_config.lineColor() + line_alpha = plot_config.lineAlpha() + + minimum_line = axes.plot(data.index.values, data["Minimum"].values, alpha=line_alpha, linestyle="--", color=line_color) + maximum_line = axes.plot(data.index.values, data["Maximum"].values, alpha=line_alpha, linestyle="--", color=line_color) + p50_line = axes.plot(data.index.values, data["p50"].values, alpha=line_alpha, linestyle="--", color=line_color, marker="x") + mean_line = axes.plot(data.index.values, data["Mean"].values, alpha=line_alpha, linestyle="-", color=line_color, marker="") + axes.fill_between(data.index.values, data["p10"].values, data["p90"].values, alpha=line_alpha * 0.3, color=line_color) + axes.fill_between(data.index.values, data["p33"].values, data["p67"].values, alpha=line_alpha * 0.5, color=line_color) + + rectangle_p10_p90 = Rectangle((0, 0), 1, 1, color=line_color, alpha=line_alpha * 0.3) # creates rectangle patch for legend use. + rectangle_p33_p67 = Rectangle((0, 0), 1, 1, color=line_color, alpha=line_alpha * 0.5) # creates rectangle patch for legend use. + + plot_config.addLegendItem("Minimum/Maximum", minimum_line[0]) + plot_config.addLegendItem("P50", p50_line[0]) + plot_config.addLegendItem("Mean", mean_line[0]) + plot_config.addLegendItem("P10-P90", rectangle_p10_p90) + plot_config.addLegendItem("P33-P67", rectangle_p33_p67) diff --git a/ThirdParty/Ert/devel/python/python/ert_gui/shell/debug.py b/ThirdParty/Ert/devel/python/python/ert_gui/shell/debug.py index 54eee75d37..2ad45b402a 100644 --- a/ThirdParty/Ert/devel/python/python/ert_gui/shell/debug.py +++ b/ThirdParty/Ert/devel/python/python/ert_gui/shell/debug.py @@ -1,9 +1,15 @@ +from ert import Version from ert_gui.shell import ShellFunction, assertConfigLoaded class Debug(ShellFunction): def __init__(self, shell_context): super(Debug, self).__init__("debug", shell_context) + self.addHelpFunction("site_config", None, "Show the path to the current site_config") + self.addHelpFunction("version", None, "Show the internalized ert version number") + self.addHelpFunction("timestamp", None, "Show the build timestamp") + self.addHelpFunction("git_commit", None, "Show the git commit") + self.addHelpFunction("info", None, "Shows site_config, version, timestamp and Git Commit") self.addHelpFunction("last_plugin_result", None, "Shows the last plugin result.") self.addHelpFunction("eval", "<Python expression>", "Evaluate a Python expression. " "The last plugin result is defined as: x") @@ -16,6 +22,26 @@ def __init__(self, shell_context): def setLastPluginResult(self, result): self.__last_plugin_result = result + @assertConfigLoaded + def do_site_config(self, line): + print("Site Config: %s" % self.ert().siteConfig().getLocation()) + + def do_version(self, line): + print("Version: %s" % Version.getVersion()) + + def do_timestamp(self, line): + print("Timestamp: %s" % Version.getBuildTime()) + + def do_git_commit(self, line): + print("Git Commit: %s" % Version.getGitCommit(True)) + + @assertConfigLoaded + def do_info(self, line): + print("Site Config: %s" % self.ert().siteConfig().getLocation()) + print("Version: %s" % Version.getVersion()) + print("Timestamp: %s" % Version.getBuildTime()) + print("Git Commit: %s" % Version.getGitCommit(True)) + def do_last_plugin_result(self, line): print("Last plugin result: %s" % self.__last_plugin_result) diff --git a/ThirdParty/Ert/devel/python/python/ert_gui/shell/shell_plot.py b/ThirdParty/Ert/devel/python/python/ert_gui/shell/shell_plot.py index 3293ce7c05..9f0ef96cca 100644 --- a/ThirdParty/Ert/devel/python/python/ert_gui/shell/shell_plot.py +++ b/ThirdParty/Ert/devel/python/python/ert_gui/shell/shell_plot.py @@ -16,6 +16,7 @@ class ShellPlot(object): def __init__(self, name): super(ShellPlot, self).__init__() clist = plt.rcParams['axes.color_cycle'] + clist = ["#386CB0", "#7FC97F", "#FDC086", "#F0027F", "#BF5B17"] self.__color_cycle = itertools.cycle(clist) self.figure = plt.figure() diff --git a/ThirdParty/Ert/devel/python/python/ert_gui/tools/CMakeLists.txt b/ThirdParty/Ert/devel/python/python/ert_gui/tools/CMakeLists.txt index b321023f01..80bcd31456 100644 --- a/ThirdParty/Ert/devel/python/python/ert_gui/tools/CMakeLists.txt +++ b/ThirdParty/Ert/devel/python/python/ert_gui/tools/CMakeLists.txt @@ -4,7 +4,7 @@ set(PYTHON_SOURCES tool.py ) -add_python_package("python.ert_gui.tools" ${PYTHON_INSTALL_PREFIX}/ert_gui/tools "${PYTHON_SOURCES}" True) +add_python_package("python.ert_gui.tools" ${PYTHON_INSTALL_PREFIX}/ert_gui/tools "${PYTHON_SOURCES}" True) add_subdirectory(export) add_subdirectory(help) diff --git a/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/CMakeLists.txt b/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/CMakeLists.txt index 55d30a0e4d..c8593cf313 100644 --- a/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/CMakeLists.txt +++ b/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/CMakeLists.txt @@ -5,21 +5,13 @@ set(PYTHON_SOURCES data_type_keys_list_model.py data_type_keys_widget.py data_type_proxy_model.py - export_plot.py filter_popup.py - plot_bridge.py plot_case_model.py plot_case_selection_widget.py - plot_metrics_tracker.py - plot_panel.py - plot_panel_tracker.py - plot_scale_widget.py plot_tool.py - plot_tool_bar.py + plot_widget.py plot_window.py - report_step_widget.py ) -add_python_package("python.ert_gui.tools.plot" ${PYTHON_INSTALL_PREFIX}/ert_gui/tools/plot "${PYTHON_SOURCES}" True) +add_python_package("python.ert_gui.tools.plot" ${PYTHON_INSTALL_PREFIX}/ert_gui/tools/plot "${PYTHON_SOURCES}" True) -add_subdirectory(data) diff --git a/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/__init__.py b/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/__init__.py index b31e60ab3e..18b18ef513 100644 --- a/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/__init__.py +++ b/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/__init__.py @@ -1,7 +1,6 @@ -from .plot_bridge import PlotBridge -from .export_plot import ExportPlot -from .filter_popup import FilterPopup +from .plot_widget import PlotWidget +from .filter_popup import FilterPopup from .data_type_keys_list_model import DataTypeKeysListModel from .data_type_proxy_model import DataTypeProxyModel @@ -9,19 +8,12 @@ from .plot_case_model import PlotCaseModel from .plot_case_selection_widget import CaseSelectionWidget -from .report_step_widget import ReportStepWidget -from .plot_scale_widget import PlotScalesWidget - -from .plot_tool_bar import PlotToolBar from .color_chooser import ColorChooser from .customize_plot_widget import CustomizePlotWidget -from .plot_panel_tracker import PlotPanelTracker -from .plot_metrics_tracker import PlotMetricsTracker - -from .plot_panel import PlotPanel from .plot_window import PlotWindow from .plot_tool import PlotTool + diff --git a/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/customize_plot_widget.py b/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/customize_plot_widget.py index 4dae2928ed..e68e2bf89e 100644 --- a/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/customize_plot_widget.py +++ b/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/customize_plot_widget.py @@ -5,34 +5,36 @@ class CustomizePlotWidget(QWidget): - customPlotSettingsChanged = pyqtSignal(dict) + customPlotSettingsChanged = pyqtSignal() def __init__(self): QWidget.__init__(self) self.__custom = { } self.__layout = QVBoxLayout() - self.addCheckBox("error_bar_only", "Show only error bars", False) + self.addCheckBox("show_observations", "Show observations", True) self.addCheckBox("show_refcase", "Show refcase", True) + self.addCheckBox("show_legend", "Show legend", True) + self.addCheckBox("show_grid", "Show grid", True) self.__layout.addSpacing(20) - self.addColorChooser("observation", "Observation", QColor(0, 0, 0, 255)) - self.addColorChooser("observation_area", "Observation Error", QColor(0, 0, 0, 38)) - self.addColorChooser("observation_error_bar", "Observation Error Bar", QColor(0, 0, 0, 255)) - self.addColorChooser("refcase", "Refcase", QColor(0, 0, 0, 178)) - self.addColorChooser("ensemble_1", "Case #1", QColor(56, 108, 176, 204)) - self.addColorChooser("ensemble_2", "Case #2", QColor(127, 201, 127, 204)) - self.addColorChooser("ensemble_3", "Case #3", QColor(253, 192, 134, 204)) - self.addColorChooser("ensemble_4", "Case #4", QColor(240, 2, 127, 204)) - self.addColorChooser("ensemble_5", "Case #5", QColor(191, 91, 23, 204)) + # self.addColorChooser("observation", "Observation", QColor(0, 0, 0, 255)) + # self.addColorChooser("observation_area", "Observation Error", QColor(0, 0, 0, 38)) + # self.addColorChooser("observation_error_bar", "Observation Error Bar", QColor(0, 0, 0, 255)) + # self.addColorChooser("refcase", "Refcase", QColor(0, 0, 0, 178)) + # self.addColorChooser("ensemble_1", "Case #1", QColor(56, 108, 176, 204)) + # self.addColorChooser("ensemble_2", "Case #2", QColor(127, 201, 127, 204)) + # self.addColorChooser("ensemble_3", "Case #3", QColor(253, 192, 134, 204)) + # self.addColorChooser("ensemble_4", "Case #4", QColor(240, 2, 127, 204)) + # self.addColorChooser("ensemble_5", "Case #5", QColor(191, 91, 23, 204)) self.__layout.addStretch() self.setLayout(self.__layout) def emitChange(self): - self.customPlotSettingsChanged.emit(self.__custom) + self.customPlotSettingsChanged.emit() def addCheckBox(self, name, description, default_value): checkbox = QCheckBox(description) diff --git a/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/data/CMakeLists.txt b/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/data/CMakeLists.txt deleted file mode 100644 index 46c21eebf6..0000000000 --- a/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/data/CMakeLists.txt +++ /dev/null @@ -1,13 +0,0 @@ -set(PYTHON_SOURCES - __init__.py - ensemble_plot_data.py - histogram_plot_data.py - histogram_plot_data_factory.py - observation_plot_data.py - plot_data.py - plot_data_fetcher.py - refcase_plot_data.py -) - -add_python_package("python.ert_gui.tools.plot.data" ${PYTHON_INSTALL_PREFIX}/ert_gui/tools/plot/data "${PYTHON_SOURCES}" True) - diff --git a/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/data/__init__.py b/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/data/__init__.py deleted file mode 100644 index e5778b3bd6..0000000000 --- a/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/data/__init__.py +++ /dev/null @@ -1,7 +0,0 @@ -from .histogram_plot_data import CaseHistogramPlotData, HistogramPlotData -from .histogram_plot_data_factory import HistogramPlotDataFactory, ReportStepLessHistogramPlotDataFactory -from .observation_plot_data import ObservationPlotData -from .refcase_plot_data import RefcasePlotData -from .ensemble_plot_data import EnsemblePlotData -from .plot_data import PlotData -from .plot_data_fetcher import PlotDataFetcher \ No newline at end of file diff --git a/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/data/ensemble_plot_data.py b/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/data/ensemble_plot_data.py deleted file mode 100644 index 1f909d6c22..0000000000 --- a/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/data/ensemble_plot_data.py +++ /dev/null @@ -1,143 +0,0 @@ -from PyQt4.QtCore import QObject, pyqtSlot, QString -import math - - -class EnsemblePlotData(QObject): - def __init__(self, name, case_name, parent=None): - QObject.__init__(self, parent) - - self.__name = name - self.__case_name = case_name - - self.__x_values = None - self.__y_values = None - self.__y_min_values = None - self.__y_max_values = None - - self.__has_data = False - - self.__min_x = None - self.__max_x = None - self.__min_y = None - self.__max_y = None - - - - def setEnsembleData(self, x_values, y_values, y_min_values, y_max_values): - if x_values is not None and y_values is not None and y_min_values is not None and y_max_values is not None: - self.__x_values = x_values - self.__y_values = y_values - - self.__y_min_values = y_min_values - self.__y_max_values = y_max_values - - self.__has_data = True - - - def updateBoundaries(self, min_x, max_x, min_y, max_y): - if min_x is not None and (self.__min_x is None or self.__min_x > min_x): - self.__min_x = min_x - - if max_x is not None and (self.__max_x is None or self.__max_x < max_x): - self.__max_x = max_x - - if min_y is not None and (self.__min_y is None or self.__min_y > min_y): - self.__min_y = min_y - - if max_y is not None and (self.__max_y is None or self.__max_y < max_y): - self.__max_y = max_y - - - - @pyqtSlot(result=str) - def name(self): - return self.__name - - @pyqtSlot(result=str) - def caseName(self): - return self.__case_name - - @pyqtSlot(result="QVariantList") - def xValues(self): - return self.__x_values - - @pyqtSlot(result="QVariantList") - def yValues(self): - return self.__y_values - - @pyqtSlot(result="QVariantList") - def yMinValues(self): - return self.__y_min_values - - @pyqtSlot(result="QVariantList") - def yMaxValues(self): - return self.__y_max_values - - @pyqtSlot(QString, result=int) - def realizationCount(self): - return len(self.__y_values) - - @pyqtSlot(result=float) - def minX(self): - return self.__min_x - - @pyqtSlot(result=float) - def maxX(self): - return self.__max_x - - @pyqtSlot(result=float) - def minY(self): - return self.__min_y - - @pyqtSlot(result=float) - def maxY(self): - return self.__max_y - - @pyqtSlot(result=bool) - def isValid(self): - return self.hasBoundaries() and self.hasData() - - @pyqtSlot(result=bool) - def hasBoundaries(self): - return self.__min_x is not None and self.__max_x is not None and self.__min_y is not None and self.__max_y is not None - - @pyqtSlot(result=bool) - def hasData(self): - return self.__has_data - - - - @pyqtSlot(float, result="QVariantList") - def xPercentile(self, percentile): - values = [] - transposed_data = map(list, map(None, *self.__y_values)) - for row in transposed_data: - row = sorted(row) - values.append(self.percentile(row, percentile)) - - return values - - - def percentile(self, N, percent, key=lambda x:x): - """ - Find the percentile of a list of values. - - @parameter N - is a list of values. Note N MUST BE already sorted. - @parameter percent - a float value from 0.0 to 1.0. - @parameter key - optional key function to compute value from each element of N. - - @return - the percentile of the values - """ - if not N: - return None - k = (len(N) - 1) * percent - f = math.floor(k) - c = math.ceil(k) - - if f == c: - return key(N[int(k)]) - - d0 = key(N[int(f)]) * (c - k) - d1 = key(N[int(c)]) * (k - f) - - return d0 + d1 \ No newline at end of file diff --git a/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/data/histogram_plot_data.py b/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/data/histogram_plot_data.py deleted file mode 100644 index 759c058e65..0000000000 --- a/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/data/histogram_plot_data.py +++ /dev/null @@ -1,167 +0,0 @@ -from math import ceil, sqrt -from PyQt4.QtCore import QObject, pyqtSlot, QString - - -class CaseHistogramPlotData(QObject): - def __init__(self, case_name, report_step_time, parent=None): - QObject.__init__(self, parent) - - self.__case_name = case_name - self.__report_step_time = report_step_time - - self.__min = None - self.__max = None - - self.__samples = [] - - - def addSample(self, sample): - self.__samples.append(sample) - - if self.__min is None or self.__min > sample: - self.__min = sample - - if self.__max is None or self.__max < sample: - self.__max = sample - - def __len__(self): - return len(self.__samples) - - - @pyqtSlot(result=float) - def min(self): - return self.__min - - - @pyqtSlot(result=float) - def max(self): - return self.__max - - - @pyqtSlot(result="QVariantList") - def samples(self): - return self.__samples - - -class HistogramPlotData(QObject): - def __init__(self, name, report_step_time, parent=None): - QObject.__init__(self, parent) - - self.__name = name - self.__report_step_time = report_step_time - - self.__min = None - self.__max = None - - self.__case_list = [] - self.__case_histograms = {} - - self.__observation = None - self.__observation_error = None - self.__refcase = None - - - def addCase(self, case_name): - if not case_name in self.__case_histograms: - self.__case_histograms[case_name] = CaseHistogramPlotData(case_name, self.__report_step_time, parent=self) - self.__case_list.append(case_name) - - - def addSample(self, case_name, sample): - self.addCase(case_name) - - self.__case_histograms[case_name].addSample(sample) - - if self.__min is None or self.__min > sample: - self.__min = sample - - if self.__max is None or self.__max < sample: - self.__max = sample - - - def setRefcase(self, value): - self.__refcase = value - - if self.__min is None or self.__min > value: - self.__min = value - - if self.__max is None or self.__max < value: - self.__max = value - - def setObservation(self, value, error): - self.__observation = value - self.__observation_error = error - - if value >= 0: - error_value = max(0, value - error) - else: - error_value = value - error - - if self.__min is None or self.__min > error_value: - self.__min = error_value - - if self.__max is None or self.__max < value + error: - self.__max = value + error - - - @pyqtSlot(result=str) - def name(self): - return self.__name - - - @pyqtSlot(result=bool) - def hasRefcase(self): - return self.__refcase is not None - - @pyqtSlot(result=bool) - def hasObservation(self): - return self.__observation is not None - - @pyqtSlot(result=float) - def refcase(self): - return self.__refcase - - @pyqtSlot(result=float) - def observation(self): - return self.__observation - - @pyqtSlot(result=float) - def observationError(self): - return self.__observation_error - - @pyqtSlot(QString, result=bool) - def hasCaseHistogram(self, case_name): - return str(case_name) in self.__case_histograms - - @pyqtSlot(QString, result=QObject) - def caseHistogram(self, case_name): - return self.__case_histograms[str(case_name)] - - @pyqtSlot(result=float) - def min(self): - return self.__min - - @pyqtSlot(result=float) - def max(self): - return self.__max - - @pyqtSlot(result=int) - def reportStepTime(self): - return self.__report_step_time - - @pyqtSlot(result=int) - def maxCount(self): - max_sample_count = 0 - for histogram in self.__case_histograms.values(): - max_sample_count = max(max_sample_count, len(histogram)) - - return max_sample_count - - @pyqtSlot(QString, result=bool) - def isValid(self, case_name): - return self.hasObservation() or self.hasRefcase() or self.hasCaseHistogram(case_name) - - @pyqtSlot(result=int) - def numberOfBins(self): - return ceil(sqrt(self.maxCount())) - diff --git a/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/data/histogram_plot_data_factory.py b/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/data/histogram_plot_data_factory.py deleted file mode 100644 index 5a942bee59..0000000000 --- a/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/data/histogram_plot_data_factory.py +++ /dev/null @@ -1,149 +0,0 @@ -from ert_gui.tools.plot.data import HistogramPlotData - - -class HistogramPlotDataFactory(object): - def __init__(self, name): - super(HistogramPlotDataFactory, self).__init__() - self.__name = name - - self.__observations = None - self.__refcase = None - self.__case_names = [] - self.__ensemble_data = {} - - def setObservations(self, x_values, y_values, std_values, min_y, max_y): - if x_values is not None: - self.__observations = {"x_values": x_values, - "y_values": y_values, - "std_values": std_values, - "min_y": min_y, - "max_y": max_y, - "reverse_lookup": {}} - - rl = self.__observations["reverse_lookup"] - - for index in range(len(x_values)): - x = x_values[index] - rl[x] = index - - - def hasObservationSample(self, x_value): - return x_value in self.__observations["reverse_lookup"] - - - def setRefcase(self, x_values, y_values, min_y, max_y): - if x_values is not None and y_values is not None: - self.__refcase = {"x_values": x_values, - "y_values": y_values, - "min_y": min_y, - "max_y": max_y, - "reverse_lookup": {}} - - rl = self.__refcase["reverse_lookup"] - - for index in range(len(x_values)): - x = x_values[index] - rl[x] = index - - - def hasRefcaseSample(self, x_value): - return x_value in self.__refcase["reverse_lookup"] - - def addEnsembleData(self, case_name, x_values, y_values, min_y, max_y): - self.__case_names.append(case_name) - - ensemble_data = {"x_values": x_values, - "y_values": y_values, - "min_y": min_y, - "max_y": max_y, - "reverse_lookup": {}} - - rl = ensemble_data["reverse_lookup"] - - for index in range(len(x_values)): - x = x_values[index] - rl[x] = index - - self.__ensemble_data[case_name] = ensemble_data - - def hasEnsembleSample(self, case_name, x_value): - ensemble_data = self.__ensemble_data[case_name] - return x_value in ensemble_data["reverse_lookup"] - - def hasEnsembleData(self): - return len(self.__case_names) > 0 - - def hasObservations(self): - """ @rtype: bool """ - return self.__observations is not None - - def hasRefcaseData(self): - """ @rtype: bool """ - return self.__refcase is not None - - def hasRefcase(self): - """ @rtype: bool """ - return self.__refcase is not None - - - def observationIndex(self, x_value): - return self.__observations["reverse_lookup"][x_value] - - def refcaseIndex(self, x_value): - return self.__refcase["reverse_lookup"][x_value] - - def ensembleIndex(self, case_name, x_value): - ensemble = self.__ensemble_data[case_name] - return ensemble["reverse_lookup"][x_value] - - def ensembleData(self, case_name): - """ @rtype: EnsemblePlotData """ - return self.__ensemble_data[case_name] - - def getEnsembleSamples(self, case_name, x_value): - """ @rtype: list of float """ - index = self.ensembleIndex(case_name, x_value) - ensemble = self.ensembleData(case_name) - result = [] - for realization in ensemble["y_values"]: - if len(realization) > 0 and index < len(realization): - result.append(realization[index]) - - return result - - - def getHistogramData(self, x_value): - """ @rtype: HistogramPlotData """ - histogram_data = HistogramPlotData(self.__name, x_value) - - if self.hasObservations(): - if self.hasObservationSample(x_value): - index = self.observationIndex(x_value) - value = self.__observations["y_values"][index] - std = self.__observations["std_values"][index] - histogram_data.setObservation(value, std) - - if self.hasRefcase(): - if self.hasRefcaseSample(x_value): - index = self.refcaseIndex(x_value) - value = self.__refcase["y_values"][index] - histogram_data.setRefcase(value) - - for case_name in self.__case_names: - histogram_data.addCase(case_name) - - if self.hasEnsembleSample(case_name, x_value): - for sample in self.getEnsembleSamples(case_name, x_value): - histogram_data.addSample(case_name, sample) - - return histogram_data - - -class ReportStepLessHistogramPlotDataFactory(HistogramPlotDataFactory): - def __init__(self, name): - super(ReportStepLessHistogramPlotDataFactory, self).__init__(name) - - def getHistogramData(self, x_value): - return super(ReportStepLessHistogramPlotDataFactory, self).getHistogramData(0) - - diff --git a/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/data/observation_plot_data.py b/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/data/observation_plot_data.py deleted file mode 100644 index 37fc4685e9..0000000000 --- a/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/data/observation_plot_data.py +++ /dev/null @@ -1,91 +0,0 @@ -from PyQt4.QtCore import QObject, pyqtSlot - - -class ObservationPlotData(QObject): - def __init__(self, name, parent=None): - QObject.__init__(self, parent) - - self.__name = name - self.__x_values = [] - self.__y_values = [] - self.__std_values = [] - self.__is_continuous = True - self.__has_data = False - - self.__min_x = None - self.__max_x = None - self.__min_y = None - self.__max_y = None - - - def setObservationData(self, x_values, y_values, std_values, continuous): - if x_values is not None and y_values is not None and std_values is not None: - self.__x_values = x_values - self.__y_values = y_values - self.__std_values = std_values - self.__is_continuous = continuous - self.__has_data = True - - - def updateBoundaries(self, min_x, max_x, min_y, max_y): - if min_x is not None and (self.__min_x is None or self.__min_x > min_x): - self.__min_x = min_x - - if max_x is not None and (self.__max_x is None or self.__max_x < max_x): - self.__max_x = max_x - - if min_y is not None and (self.__min_y is None or self.__min_y > min_y): - self.__min_y = min_y - - if max_y is not None and (self.__max_y is None or self.__max_y < max_y): - self.__max_y = max_y - - - - @pyqtSlot(result=str) - def name(self): - return self.__name - - @pyqtSlot(result="QVariantList") - def xValues(self): - return self.__x_values - - @pyqtSlot(result="QVariantList") - def yValues(self): - return self.__y_values - - @pyqtSlot(result="QVariantList") - def stdValues(self): - return self.__std_values - - @pyqtSlot(result=bool) - def isContinuous(self): - return self.__is_continuous - - @pyqtSlot(result=float) - def minX(self): - return self.__min_x - - @pyqtSlot(result=float) - def maxX(self): - return self.__max_x - - @pyqtSlot(result=float) - def minY(self): - return self.__min_y - - @pyqtSlot(result=float) - def maxY(self): - return self.__max_y - - @pyqtSlot(result=bool) - def isValid(self): - return self.hasBoundaries() and self.hasData() - - @pyqtSlot(result=bool) - def hasBoundaries(self): - return self.__min_x is not None and self.__max_x is not None and self.__min_y is not None and self.__max_y is not None - - @pyqtSlot(result=bool) - def hasData(self): - return self.__has_data diff --git a/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/data/plot_data.py b/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/data/plot_data.py deleted file mode 100644 index 09c25c9168..0000000000 --- a/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/data/plot_data.py +++ /dev/null @@ -1,195 +0,0 @@ -from PyQt4.QtCore import QObject, pyqtSlot, QString -from ert_gui.tools.plot.data import HistogramPlotDataFactory, HistogramPlotData, ObservationPlotData, RefcasePlotData, EnsemblePlotData - - -class PlotData(QObject): - def __init__(self, name, parent=None): - QObject.__init__(self, parent) - - self.__name = name - - #: :type: ObservationPlotData - self.__observation_data = None - #: :type: RefcasePlotData - self.__refcase_data = None - #: :type: EnsemblePlotData - self.__ensemble_data = {} - - self.__user_data = {} - - #: :type: HistogramPlotDataFactory - self.__histogram_factory = None - - self.__unit_x = "Unknown" - self.__unit_y = "Unknown" - - self.__min_x = None - self.__max_x = None - self.__min_y = None - self.__max_y = None - - self.__use_log_scale = False - - self.__case_list = [] - - - def setObservationData(self, observation_data): - if observation_data.isValid(): - observation_data.setParent(self) - self.__observation_data = observation_data - self.updateBoundaries(observation_data.minX(), observation_data.maxX(), observation_data.minY(), observation_data.maxY()) - - - def setRefcaseData(self, refcase_data): - refcase_data.setParent(self) - self.__refcase_data = refcase_data - self.updateBoundaries(refcase_data.minX(), refcase_data.maxX(), refcase_data.minY(), refcase_data.maxY()) - - def setHistogramFactory(self, histogram_factory): - assert isinstance(histogram_factory, HistogramPlotDataFactory) - self.__histogram_factory = histogram_factory - - def setUnitX(self, unit): - self.__unit_x = unit - - def setUnitY(self, unit): - self.__unit_y = unit - - def addEnsembleData(self, ensemble_data): - if ensemble_data.isValid(): - ensemble_data.setParent(self) - case_name = ensemble_data.caseName() - self.__case_list.append(case_name) - self.__ensemble_data[case_name] = ensemble_data - self.updateBoundaries(ensemble_data.minX(), ensemble_data.maxX(), ensemble_data.minY(), ensemble_data.maxY()) - - def setUserData(self, name, data): - data.setParent(self) - self.__user_data[name] = data - - def updateBoundaries(self, min_x, max_x, min_y, max_y): - if min_x is not None and (self.__min_x is None or self.__min_x > min_x): - self.__min_x = min_x - - if max_x is not None and (self.__max_x is None or self.__max_x < max_x): - self.__max_x = max_x - - if min_y is not None and (self.__min_y is None or self.__min_y > min_y): - self.__min_y = min_y - - if max_y is not None and (self.__max_y is None or self.__max_y < max_y): - self.__max_y = max_y - - def setShouldUseLogScale(self, use_log_scale): - self.__use_log_scale = use_log_scale - - @pyqtSlot(result=str) - def name(self): - """ @rtype: str """ - return self.__name - - @pyqtSlot(result=str) - def unitX(self): - """ @rtype: str """ - return self.__unit_x - - @pyqtSlot(result=str) - def unitY(self): - """ @rtype: str """ - return self.__unit_y - - @pyqtSlot(result=QObject) - def observationData(self): - """ @rtype: ObservationPlotData """ - return self.__observation_data - - @pyqtSlot(result=bool) - def hasObservationData(self): - """ @rtype: bool """ - return self.__observation_data is not None and self.__observation_data.isValid() - - @pyqtSlot(result=QObject) - def refcaseData(self): - """ @rtype: RefcasePlotData """ - return self.__refcase_data - - @pyqtSlot(result=bool) - def hasRefcaseData(self): - """ @rtype: bool """ - return self.__refcase_data is not None and self.__refcase_data.isValid() - - @pyqtSlot(QString, result=QObject) - def ensembleData(self, case_name): - """ @rtype: EnsemblePlotData """ - return self.__ensemble_data[str(case_name)] - - @pyqtSlot(result=bool) - def hasEnsembleData(self): - """ @rtype: bool """ - return len(self.__ensemble_data.keys()) > 0 - - @pyqtSlot(QString, result=bool) - def hasEnsembleDataForCase(self, case_name): - """ @rtype: bool """ - return str(case_name) in self.__ensemble_data - - @pyqtSlot(QString, result=bool) - def hasUserData(self, name): - """ @rtype: bool """ - return str(name) in self.__user_data - - @pyqtSlot(QString, result=int) - def realizationCount(self, case): - """ @rtype: int """ - return self.__ensemble_data[str(case)].realizationCount() - - @pyqtSlot(result=bool) - def hasHistogram(self): - """ @rtype: bool """ - return self.__histogram_factory is not None - - @pyqtSlot(result=float) - def minX(self): - return self.__min_x - - @pyqtSlot(result=float) - def maxX(self): - return self.__max_x - - @pyqtSlot(result=float) - def minY(self): - return self.__min_y - - @pyqtSlot(result=float) - def maxY(self): - return self.__max_y - - @pyqtSlot(result=bool) - def isValid(self): - return self.hasBoundaries() and (self.hasObservationData() or self.hasRefcaseData() or self.hasEnsembleData() or self.hasHistogram()) - - @pyqtSlot(result=bool) - def hasBoundaries(self): - return self.__min_x is not None and self.__max_x is not None and self.__min_y is not None and self.__max_y is not None - - @pyqtSlot(result="QStringList") - def caseList(self): - return self.__case_list - - @pyqtSlot(result=bool) - def shouldUseLogScale(self): - return self.__use_log_scale - - @pyqtSlot(int, result=QObject) - def histogramData(self, report_step_time): - if self.__histogram_factory is not None: - data = self.__histogram_factory.getHistogramData(report_step_time) - data.setParent(self) - - return data - return None - - @pyqtSlot("QString", result=QObject) - def getUserData(self, name): - return self.__user_data[str(name)] - diff --git a/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/data/plot_data_fetcher.py b/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/data/plot_data_fetcher.py deleted file mode 100644 index d0be283efd..0000000000 --- a/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/data/plot_data_fetcher.py +++ /dev/null @@ -1,232 +0,0 @@ -from ert.enkf.plot import EnsembleDataFetcher, ObservationDataFetcher, RefcaseDataFetcher, BlockObservationDataFetcher, EnsembleGenKWFetcher, EnsembleGenDataFetcher, ObservationGenDataFetcher -from ert.enkf.plot import EnsembleBlockDataFetcher, PcaDataFetcher -from ert_gui.models.connectors.plot import DataTypeKeysModel -from ert_gui.tools.plot.data import PlotData, ObservationPlotData, EnsemblePlotData, RefcasePlotData, HistogramPlotDataFactory, ReportStepLessHistogramPlotDataFactory -from ert_gui.models import ErtConnector - - -class PlotDataFetcher(ErtConnector): - - def getPlotDataForKeyAndCases(self, key, cases): - observation_data_fetcher = ObservationDataFetcher(self.ert()) - block_observation_data_fetcher = BlockObservationDataFetcher(self.ert()) - gen_kw_fetcher = EnsembleGenKWFetcher(self.ert()) - gen_data_fetcher = EnsembleGenDataFetcher(self.ert()) - - if self.isBlockObservationKey(key): - return self.fetchBlockObservationData(block_observation_data_fetcher, key, cases) - - elif self.isSummaryKey(key): - return self.fetchSummaryData(observation_data_fetcher, key, cases) - - elif self.isGenKWKey(key): - return self.fetchGenKWData(gen_kw_fetcher, key, cases) - - elif self.isGenDataKey(key): - return self.fetchGenData(gen_data_fetcher, key, cases) - - elif self.isPcaDataKey(key): - plot_data = PlotData(key) - pca_plot_data = self.fetchPcaData(key, cases) - plot_data.setUserData("PCA", pca_plot_data) - return plot_data - - else: - raise NotImplementedError("Key %s not supported." % key) - - - def isSummaryKey(self, key): - ensemble_data_fetcher = ObservationDataFetcher(self.ert()) - return ensemble_data_fetcher.supportsKey(key) - - - def isBlockObservationKey(self, key): - block_observation_data_fetcher = BlockObservationDataFetcher(self.ert()) - return block_observation_data_fetcher.supportsKey(key) - - - def isGenKWKey(self, key): - gen_kw_fetcher = EnsembleGenKWFetcher(self.ert()) - return gen_kw_fetcher.supportsKey(key) - - - def isGenDataKey(self, key): - obs_gen_data_fetcher = ObservationGenDataFetcher(self.ert()) - return obs_gen_data_fetcher.supportsKey(key) - - - def isPcaDataKey(self, key): - pca_data_fetcher = PcaDataFetcher(self.ert()) - return pca_data_fetcher.supportsKey(key) or DataTypeKeysModel().isCustomPcaKey(key) - - def isCustomPcaDataKey(self, key): - return DataTypeKeysModel().isCustomPcaKey(key) - - def dataTypeKeySupportsReportSteps(self, key): - return self.isSummaryKey(key) - - def fetchGenData(self, gen_data_fetcher, key, cases): - plot_data = PlotData(key) - - gen_data_observation_fetcher = ObservationGenDataFetcher(self.ert()) - - if gen_data_observation_fetcher.hasData(key): - self.addObservationData(plot_data, key, gen_data_observation_fetcher) - self.addEnsembleData(plot_data, key, cases, gen_data_fetcher) - self.addPcaData(plot_data, key, cases) - - return plot_data - - - def fetchGenKWData(self, gen_kw_fetcher, key, cases): - plot_data = PlotData(key) - - histogram_factory = ReportStepLessHistogramPlotDataFactory(key) - self.addEnsembleData(plot_data, key, cases, gen_kw_fetcher, histogram_factory) - plot_data.setHistogramFactory(histogram_factory) - - return plot_data - - - def fetchBlockObservationData(self, block_observation_data_fetcher, key, cases): - plot_data = PlotData(key) - - plot_data.setUnitY(self.ert().eclConfig().getDepthUnit()) - plot_data.setUnitX(self.ert().eclConfig().getPressureUnit()) - - if block_observation_data_fetcher.hasData(key): - block_observation_data_fetcher.setSelectedReportStepIndex(0) - self.addObservationData(plot_data, key, block_observation_data_fetcher) - - ensemble_block_data_fetcher = EnsembleBlockDataFetcher(self.ert()) - ensemble_block_data_fetcher.setSelectedReportStepIndex(0) - self.addEnsembleData(plot_data, key, cases, ensemble_block_data_fetcher) - - self.addPcaData(plot_data, key, cases) - - return plot_data - - - def fetchSummaryData(self, observation_data_fetcher, key, cases): - plot_data = PlotData(key) - - histogram_factory = HistogramPlotDataFactory(key) - refcase_fetcher = RefcaseDataFetcher(self.ert()) - - self.addObservationData(plot_data, key, observation_data_fetcher, histogram_factory) - - self.addRefcaseData(plot_data, key, refcase_fetcher, histogram_factory) - - self.addEnsembleData(plot_data, key, cases, EnsembleDataFetcher(self.ert()), histogram_factory) - - self.addPcaData(plot_data, key, cases) - - if refcase_fetcher.hasRefcase(): - unit = refcase_fetcher.getRefCase().unit(key) - if unit != "": - plot_data.setUnitY(unit) - - plot_data.setHistogramFactory(histogram_factory) - - return plot_data - - - def addEnsembleData(self, plot_data, key, cases, fetcher, histogram_factory=None): - for case in cases: - ensemble_data = fetcher.fetchData(key, case) - - if "use_log_scale" in ensemble_data: - plot_data.setShouldUseLogScale(ensemble_data["use_log_scale"]) - - if len(ensemble_data) > 0: - ensemble_plot_data = EnsemblePlotData(key, case) - - if "min_y_values" in ensemble_data: - min_values = ensemble_data["min_y_values"] - elif "min_x_values" in ensemble_data: - min_values = ensemble_data["min_x_values"] - else: - min_values = [] - - - if "max_y_values" in ensemble_data: - max_values = ensemble_data["max_y_values"] - elif "max_x_values" in ensemble_data: - max_values = ensemble_data["max_x_values"] - else: - max_values = [] - - ensemble_plot_data.setEnsembleData(ensemble_data["x"], ensemble_data["y"], min_values, max_values) - ensemble_plot_data.updateBoundaries(ensemble_data["min_x"], ensemble_data["max_x"], ensemble_data["min_y"], ensemble_data["max_y"]) - plot_data.addEnsembleData(ensemble_plot_data) - - if histogram_factory is not None: - histogram_factory.addEnsembleData(case, ensemble_data["x"], ensemble_data["y"], ensemble_data["min_y"], ensemble_data["max_y"]) - - - def addObservationData(self, plot_data, key, fetcher, histogram_factory=None): - observation_data = fetcher.fetchData(key) - - observation_plot_data = ObservationPlotData(key) - observation_plot_data.setObservationData(observation_data["x"], observation_data["y"], observation_data["std"], observation_data["continuous"]) - observation_plot_data.updateBoundaries(observation_data["min_x"], observation_data["max_x"], observation_data["min_y"], observation_data["max_y"]) - - plot_data.setObservationData(observation_plot_data) - - if histogram_factory is not None: - histogram_factory.setObservations(observation_data["x"], observation_data["y"], observation_data["std"], observation_data["min_y"], observation_data["max_y"]) - - - def addRefcaseData(self, plot_data, key, fetcher, histogram_factory=None): - refcase_data = fetcher.fetchData(key) - refcase_plot_data = RefcasePlotData(key) - refcase_plot_data.setRefcaseData(refcase_data["x"], refcase_data["y"]) - refcase_plot_data.updateBoundaries(refcase_data["min_x"], refcase_data["max_x"], refcase_data["min_y"], refcase_data["max_y"]) - plot_data.setRefcaseData(refcase_plot_data) - - if histogram_factory is not None: - histogram_factory.setRefcase(refcase_data["x"], refcase_data["y"], refcase_data["min_y"], refcase_data["max_y"]) - - - def addPcaData(self, plot_data, key, cases): - if plot_data.hasObservationData() and plot_data.hasEnsembleData(): - plot_data.setUserData("PCA", self.fetchPcaData(key, cases)) - else: - plot_data.setUserData("PCA", PlotData("No ensemble data available for %s" % key)) - - - def fetchPcaData(self, key, cases): - """ @rtype: PlotData """ - if key.startswith("PCA:"): - pca_name = key - else: - pca_name ="PCA:%s" % key - - pca_data_fetcher = PcaDataFetcher(self.ert()) - pca_plot_data = PlotData(pca_name) - - if DataTypeKeysModel().isCustomPcaKey(key): - obs_keys = DataTypeKeysModel().getCustomPcaKeyObsKeys(key) - else: - obs_keys = pca_data_fetcher.getObsKeys(key) - - for case in cases: - - pca_data = pca_data_fetcher.fetchData(obs_keys, case) - - if pca_data["x"] is not None: - - if not pca_plot_data.hasObservationData(): - pca_observation_plot_data = ObservationPlotData(pca_name) - pca_observation_plot_data.setObservationData(pca_data["x"], pca_data["obs_y"], [0.0 for x in pca_data["x"]], False) - pca_observation_plot_data.updateBoundaries(pca_data["min_x"], pca_data["max_x"], pca_data["min_y"], pca_data["max_y"]) - pca_plot_data.setObservationData(pca_observation_plot_data) - - pca_ensemble_plot_data = EnsemblePlotData(key, case) - pca_ensemble_plot_data.setEnsembleData(pca_data["x"], pca_data["y"], [], []) - pca_ensemble_plot_data.updateBoundaries(pca_data["min_x"], pca_data["max_x"], pca_data["min_y"], pca_data["max_y"]) - pca_plot_data.addEnsembleData(pca_ensemble_plot_data) - - return pca_plot_data - - diff --git a/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/data/refcase_plot_data.py b/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/data/refcase_plot_data.py deleted file mode 100644 index 2375f2b51d..0000000000 --- a/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/data/refcase_plot_data.py +++ /dev/null @@ -1,89 +0,0 @@ -from PyQt4.QtCore import QObject, pyqtSlot - - -class RefcasePlotData(QObject): - def __init__(self, name, parent=None): - QObject.__init__(self, parent) - - self.__name = name - - self.__x_values = [] - self.__y_values = [] - self.__has_data = False - - self.__min_x = None - self.__max_x = None - self.__min_y = None - self.__max_y = None - - - - def setRefcaseData(self, x_values, y_values): - if x_values is not None and y_values is not None: - self.__x_values = x_values - self.__y_values = y_values - self.__has_data = True - - - def updateBoundaries(self, min_x, max_x, min_y, max_y): - if min_x is not None and (self.__min_x is None or self.__min_x > min_x): - self.__min_x = min_x - - if max_x is not None and (self.__max_x is None or self.__max_x < max_x): - self.__max_x = max_x - - if min_y is not None and (self.__min_y is None or self.__min_y > min_y): - self.__min_y = min_y - - if max_y is not None and (self.__max_y is None or self.__max_y < max_y): - self.__max_y = max_y - - - - @pyqtSlot(result=str) - def name(self): - return self.__name - - - - @pyqtSlot(result="QVariantList") - def xValues(self): - return self.__x_values - - @pyqtSlot(result="QVariantList") - def yValues(self): - return self.__y_values - - - @pyqtSlot(result=float) - def minX(self): - return self.__min_x - - @pyqtSlot(result=float) - def maxX(self): - return self.__max_x - - @pyqtSlot(result=float) - def minY(self): - return self.__min_y - - @pyqtSlot(result=float) - def maxY(self): - return self.__max_y - - - @pyqtSlot(result=bool) - def isValid(self): - return self.hasBoundaries() and self.hasData() - - @pyqtSlot(result=bool) - def hasBoundaries(self): - return self.__min_x is not None and self.__max_x is not None and self.__min_y is not None and self.__max_y is not None - - - @pyqtSlot(result=bool) - def hasData(self): - return self.__has_data - - - diff --git a/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/data_type_keys_list_model.py b/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/data_type_keys_list_model.py index 417a610ef1..478444c5c5 100644 --- a/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/data_type_keys_list_model.py +++ b/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/data_type_keys_list_model.py @@ -1,6 +1,5 @@ from PyQt4.QtCore import QAbstractItemModel, QModelIndex, Qt, QVariant from PyQt4.QtGui import QColor -from ert_gui.models.connectors.plot import DataTypeKeysModel from ert_gui.widgets import util @@ -9,11 +8,16 @@ class DataTypeKeysListModel(QAbstractItemModel): HAS_OBSERVATIONS = QColor(237, 218, 116) GROUP_ITEM = QColor(64, 64, 64) - def __init__(self): + def __init__(self, ert): + """ + @type ert: ert.enkf.EnKFMain + """ QAbstractItemModel.__init__(self) + self.__ert = ert self.__icon = util.resourceIcon("ide/small/bullet_star") - self.__items = DataTypeKeysModel().getAllKeys() + def keyManager(self): + return self.__ert.getKeyManager() def index(self, row, column, parent=None, *args, **kwargs): return self.createIndex(row, column, parent) @@ -22,7 +26,7 @@ def parent(self, index=None): return QModelIndex() def rowCount(self, parent=None, *args, **kwargs): - return len(self.__items) + return len(self.keyManager().allDataTypeKeys()) def columnCount(self, QModelIndex_parent=None, *args, **kwargs): return 1 @@ -31,14 +35,14 @@ def data(self, index, role=None): assert isinstance(index, QModelIndex) if index.isValid(): - items = self.__items + items = self.keyManager().allDataTypeKeys() row = index.row() item = items[row] if role == Qt.DisplayRole: return item elif role == Qt.BackgroundRole: - if DataTypeKeysModel().isObservationKey(item): + if self.keyManager().isKeyWithObservations(item): return self.HAS_OBSERVATIONS return QVariant() @@ -48,28 +52,25 @@ def itemAt(self, index): if index.isValid(): row = index.row() - return self.__items[row] + return self.keyManager().allDataTypeKeys()[row] return None def isSummaryKey(self, key): - return DataTypeKeysModel().isSummaryKey(str(key)) + return self.keyManager().isSummaryKey(key) def isBlockKey(self, key): - return DataTypeKeysModel().isBlockKey(str(key)) + return False def isGenKWKey(self, key): - return DataTypeKeysModel().isGenKWKey(str(key)) + return self.keyManager().isGenKwKey(key) def isGenDataKey(self, key): - return DataTypeKeysModel().isGenDataKey(str(key)) - - def isCustomPcaKey(self, key): - return DataTypeKeysModel().isCustomPcaKey(str(key)) - - - - + return self.keyManager().isGenDataKey(key) + def isCustomKwKey(self, key): + return self.keyManager().isCustomKwKey(key) + def isCustomPcaKey(self, key): + return False diff --git a/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/data_type_keys_widget.py b/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/data_type_keys_widget.py index af3c1fc743..8bc8b78c2b 100644 --- a/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/data_type_keys_widget.py +++ b/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/data_type_keys_widget.py @@ -7,9 +7,9 @@ class DataTypeKeysWidget(QWidget): - dataTypeKeySelected = pyqtSignal(str) + dataTypeKeySelected = pyqtSignal() - def __init__(self): + def __init__(self, model): QWidget.__init__(self) self.__filter_popup = FilterPopup(self) @@ -17,7 +17,7 @@ def __init__(self): layout = QVBoxLayout() - self.model = DataTypeKeysListModel() + self.model = model self.filter_model = DataTypeProxyModel(self.model) filter_layout = QHBoxLayout() @@ -46,17 +46,18 @@ def __init__(self): self.setLayout(layout) def onItemChanged(self, item): - self.filter_model.setShowBlockKeys(item["block"]) + # self.filter_model.setShowBlockKeys(item["block"]) self.filter_model.setShowSummaryKeys(item["summary"]) self.filter_model.setShowGenKWKeys(item["gen_kw"]) self.filter_model.setShowGenDataKeys(item["gen_data"]) - self.filter_model.setShowCustomPcaKeys(item["custom_pca"]) + self.filter_model.setShowCustomKwKeys(item["custom_kw"]) + # self.filter_model.setShowCustomPcaKeys(item["custom_pca"]) def itemSelected(self): selected_item = self.getSelectedItem() if selected_item is not None: - self.dataTypeKeySelected.emit(selected_item) + self.dataTypeKeySelected.emit() def getSelectedItem(self): diff --git a/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/data_type_proxy_model.py b/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/data_type_proxy_model.py index 9d67fb51b1..059762f9ef 100644 --- a/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/data_type_proxy_model.py +++ b/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/data_type_proxy_model.py @@ -27,6 +27,7 @@ def __init__(self, model , parent=None): self.__show_block_keys = True self.__show_gen_kw_keys = True self.__show_gen_data_keys = True + self.__show_custom_kw_keys = True self.__show_custom_pca_keys = True self.setFilterCaseSensitivity(Qt.CaseInsensitive) @@ -52,6 +53,9 @@ def filterAcceptsRow(self, index, q_model_index): elif not self.__show_gen_data_keys and source_model.isGenDataKey(key): show = False + elif not self.__show_custom_kw_keys and source_model.isCustomKwKey(key): + show = False + elif not self.__show_custom_pca_keys and source_model.isCustomPcaKey(key): show = False @@ -78,6 +82,10 @@ def setShowGenDataKeys(self, visible): self.__show_gen_data_keys = visible self.invalidateFilter() + def setShowCustomKwKeys(self, visible): + self.__show_custom_kw_keys = visible + self.invalidateFilter() + def setShowCustomPcaKeys(self, visible): self.__show_custom_pca_keys = visible self.invalidateFilter() diff --git a/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/export_plot.py b/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/export_plot.py deleted file mode 100644 index c9ce40b24a..0000000000 --- a/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/export_plot.py +++ /dev/null @@ -1,150 +0,0 @@ -# Copyright (C) 2014 Statoil ASA, Norway. -# -# The file 'export_plot.py' is part of ERT - Ensemble based Reservoir Tool. -# -# ERT is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# ERT is distributed in the hope that it will be useful, but WITHOUT ANY -# WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. -# -# See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> -# for more details. -import os -from PyQt4.QtCore import QSize, QSizeF, Qt, QStringList, QFileInfo -from PyQt4.QtGui import QPrinter, QImage, QPainter, QFileDialog, QApplication, QCursor - -from ert_gui.models.connectors.plot.plot_settings import PlotSettingsModel -from ert_gui.tools.plot.plot_bridge import PlotWebPage, PlotBridge -from ert_gui.tools.plot.plot_panel import PlotPanel - - -class ExportPlot(object): - def __init__(self, active_plot_panel, settings, custom_settings, path=None): - super(ExportPlot, self).__init__() - assert isinstance(active_plot_panel, PlotPanel) - self.__active_plot_panel = active_plot_panel - self.__settings = settings - self.__custom_settings = custom_settings - self.__bridge = None - """:type: PlotBridge """ - self.__plot_bridge_org = active_plot_panel.getPlotBridge() - self.__width = self.__plot_bridge_org.getPrintWidth() - self.__height = self.__plot_bridge_org.getPrintHeight() + 20 - self.__file_name = None - self.__selected_file_type = None - self.__path = path - - - def export(self): - if self.__path is not None: - default_export_path = self.__path - else: - default_export_path = PlotSettingsModel().getDefaultPlotPath() - - dialog = QFileDialog(self.__active_plot_panel) - dialog.setFileMode(QFileDialog.AnyFile) - #dialog.setNameFilter("Image (*.png);; PDF (*.pdf)") - dialog.setNameFilter("Image (*.png)") - dialog.setWindowTitle("Export plot") - dialog.setDirectory(default_export_path) - dialog.setOption(QFileDialog.DontUseNativeDialog, True) - dialog.setLabelText(QFileDialog.FileType, "Select file type: ") - dialog.setAcceptMode(QFileDialog.AcceptSave) - dialog.selectFile(self.getDefaultFileName()) - - if dialog.exec_(): - result = dialog.selectedFiles() - assert isinstance(result, QStringList) - if len(result) == 1: - file_info = QFileInfo(result[0]) - self.__file_name = file_info.fileName() - self.__path = file_info.path() - self.__selected_file_type = dialog.selectedNameFilter() - name = self.__active_plot_panel.getName() - url = self.__active_plot_panel.getUrl() - - - web_page = PlotWebPage("export - %s" % name) - web_page.mainFrame().setScrollBarPolicy(Qt.Vertical, Qt.ScrollBarAlwaysOff) - web_page.mainFrame().setScrollBarPolicy(Qt.Horizontal, Qt.ScrollBarAlwaysOff) - web_page.setViewportSize(QSize(self.__width, self.__height)) - self.__bridge = PlotBridge(web_page, url) - self.__bridge.plotReady.connect(self.plotReady) - QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) - - - def plotReady(self): - data = self.__plot_bridge_org.getPlotData() - self.__bridge.setPlotData(data) - self.__bridge.updatePlotSize(QSize(self.__width, self.__height)) - self.__bridge.setCustomSettings(self.__custom_settings) - - self.__bridge.setReportStepTime(self.__settings["report_step"]) - - x_min = self.__settings["x_min"] - x_max = self.__settings["x_max"] - y_min = self.__settings["y_min"] - y_max = self.__settings["y_max"] - self.__bridge.setScales(x_min, x_max, y_min, y_max) - - self.__bridge.renderingFinished.connect(self.performExport) - - - def performExport(self): - file_name = os.path.join(str(self.__path), str(self.__file_name)) - view = self.__bridge.getPage() - if not self.__file_name.isEmpty(): - if str(self.__selected_file_type) == "PDF (*.pdf)": - if not file_name.endswith(".pdf"): - file_name += ".pdf" - self.exportPDF(view, file_name, self.__width, self.__height) - elif str(self.__selected_file_type) == "Image (*.png)": - if not file_name.endswith(".png"): - file_name += ".png" - self.exportPNG(view, file_name, self.__width, self.__height) - - - def exportPDF(self, view, file_name, width, height): - pdf = QPrinter() - pdf.setOutputFormat(QPrinter.PdfFormat) - pdf.setPrintRange(QPrinter.AllPages) - pdf.setOrientation(QPrinter.Portrait) - pdf.setResolution(QPrinter.HighResolution) - pdf.setPaperSize(QSizeF(width,height),QPrinter.Point) - pdf.setFullPage(True) - pdf.setOutputFileName(file_name) - view.mainFrame().print_(pdf) - - QApplication.restoreOverrideCursor() - - - def exportPNG(self, view, file_name, width, height): - image = QImage(QSize(width, height), QImage.Format_ARGB32_Premultiplied) - paint = QPainter(image) - paint.setRenderHint(QPainter.Antialiasing, True) - paint.setRenderHint(QPainter.HighQualityAntialiasing, True) - paint.setRenderHint(QPainter.TextAntialiasing, True) - paint.setRenderHint(QPainter.SmoothPixmapTransform, True) - view.mainFrame().render(paint) - image.save(file_name) - paint.end() - - QApplication.restoreOverrideCursor() - - - def getDefaultFileName(self): - name = str(self.__plot_bridge_org.getPlotTitle()) - name = name.replace(":"," ") - name = name.replace("@", "-") - type = self.__active_plot_panel.getName() - - name = type + " " + name + ".png" - - return name - - def getCurrentPath(self): - return self.__path \ No newline at end of file diff --git a/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/filter_popup.py b/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/filter_popup.py index 20ebbf21d4..d66dc12768 100644 --- a/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/filter_popup.py +++ b/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/filter_popup.py @@ -23,10 +23,11 @@ def __init__(self, parent=None): self.__layout.addWidget(QLabel("Filter by data type:")) self.addFilterItem("Summary", "summary") - self.addFilterItem("Block", "block") + # self.addFilterItem("Block", "block") self.addFilterItem("Gen KW", "gen_kw") self.addFilterItem("Gen Data", "gen_data") - self.addFilterItem("Custom PCA", "custom_pca") + self.addFilterItem("Custom KW", "custom_kw") + # self.addFilterItem("Custom PCA", "custom_pca") frame.setLayout(self.__layout) diff --git a/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/plot_bridge.py b/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/plot_bridge.py deleted file mode 100644 index 8631c620fe..0000000000 --- a/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/plot_bridge.py +++ /dev/null @@ -1,224 +0,0 @@ -import json -import os -from PyQt4.QtCore import QObject, pyqtSlot, pyqtSignal, QUrl, QVariant -from PyQt4.QtWebKit import QWebPage -from ert.util import CTime -from ert_gui.tools.plot.data import PlotData - -class PlotWebPage(QWebPage): - def __init__(self, name): - QWebPage.__init__(self) - self.name = name - - def javaScriptConsoleMessage(self, message, line_number, source_id): - print("[%s] Source: %s at line: %d -> %s" % (self.name, source_id, line_number, message)) - - -class PlotBridge(QObject): - plotReady = pyqtSignal() - renderingFinished = pyqtSignal() - - def __init__(self, web_page, plot_url): - QObject.__init__(self) - assert isinstance(web_page, QWebPage) - - self.__web_page = web_page - self.__ready = False - self.__html_ready = False - self.__data = PlotData("invalid", parent=self) - self.__size = None - self.__temporary_data_object = None - - self.applyContextObject() - - root_path = os.getenv("ERT_SHARE_PATH") - path = os.path.join(root_path, plot_url) - self.__web_page.mainFrame().load(QUrl("file://%s" % path)) - self.__web_page.loadFinished.connect(self.loadFinished) - - - def applyContextObject(self): - self.__web_page.mainFrame().addToJavaScriptWindowObject("plot_data_source", self) - - def updatePlotSize(self, size): - self.__size = size - if self.isReady(): - self.__web_page.mainFrame().evaluateJavaScript("setSize(%d,%d);" % (size.width(), size.height())) - self.renderNow() - - def supportsPlotProperties(self, time=False, value=False, depth=False, index=False, histogram=False, pca=False): - time = str(time).lower() - value = str(value).lower() - depth = str(depth).lower() - index = str(index).lower() - histogram = str(histogram).lower() - pca = str(pca).lower() - return self.__web_page.mainFrame().evaluateJavaScript("supportsPlotProperties(%s,%s,%s,%s,%s,%s);" % (time, value, depth, index, histogram, pca)).toBool() - - def setPlotData(self, data): - self.__data = data - self.__web_page.mainFrame().evaluateJavaScript("updatePlot();") - - def setReportStepTime(self, report_step_time): - if report_step_time is None: - report_step_time = "null" - - if isinstance(report_step_time, CTime): - report_step_time = report_step_time.ctime() - - self.__web_page.mainFrame().evaluateJavaScript("setReportStepTime(%s);" % report_step_time) - - - def setScales(self, x_min, x_max, y_min, y_max): - if x_min is None: - x_min = "null" - - if x_max is None: - x_max = "null" - - if y_min is None: - y_min = "null" - - if y_max is None: - y_max = "null" - - if isinstance(x_min, CTime): - x_min = x_min.ctime() - - if isinstance(x_max, CTime): - x_max = x_max.ctime() - - if isinstance(y_min, CTime): - y_min = y_min.ctime() - - if isinstance(y_max, CTime): - y_max = y_max.ctime() - - scales = (x_min, x_max, y_min, y_max) - self.__web_page.mainFrame().evaluateJavaScript("setScales(%s,%s,%s,%s);" % scales) - - @pyqtSlot(result=QObject) - def getPlotData(self): - return self.__data - - - @pyqtSlot() - def htmlInitialized(self): - # print("[%s] Initialized!" % self.__name) - self.__html_ready = True - self.checkStatus() - - def loadFinished(self, ok): - self.__ready = True - self.checkStatus() - - def checkStatus(self): - if self.__ready and self.__html_ready: - # print("[%s] Ready!" % self.__name) - self.plotReady.emit() - if self.__size is not None: - self.updatePlotSize(self.__size) - - def isReady(self): - return self.__ready and self.__html_ready - - def getPrintWidth(self): - return self.__web_page.mainFrame().evaluateJavaScript("getPrintWidth();").toInt()[0] - - def getPrintHeight(self): - return self.__web_page.mainFrame().evaluateJavaScript("getPrintHeight();").toInt()[0] - - def getPage(self): - return self.__web_page - - def setCustomSettings(self, settings): - json_settings = json.dumps(settings) - self.__web_page.mainFrame().evaluateJavaScript("setCustomSettings(%s);" % json_settings) - - def renderNow(self): - self.__web_page.mainFrame().evaluateJavaScript("renderNow()") - - - def getPlotTitle(self): - return self.__web_page.mainFrame().evaluateJavaScript("getPlotTitle();" ).toString() - - - def xAxisType(self): - """ @rtype: str """ - axis_type = self.__web_page.mainFrame().evaluateJavaScript("xAxisType();") - - if axis_type.isNull(): - return None - - return str(axis_type.toString()) - - - def yAxisType(self): - """ @rtype: str """ - axis_type = self.__web_page.mainFrame().evaluateJavaScript("yAxisType();") - - if axis_type.isNull(): - return None - - return str(axis_type.toString()) - - - def isReportStepCapable(self): - """ @rtype: bool """ - return self.__web_page.mainFrame().evaluateJavaScript("isReportStepCapable();" ).toBool() - - - @pyqtSlot(result=QObject) - def getTemporaryData(self): - return self.__temporary_data_object - - - def getXScales(self, data): - """ @rtype: (float, float) """ - self.__temporary_data_object = data - x_min = self.__web_page.mainFrame().evaluateJavaScript("getXMin();") - x_max = self.__web_page.mainFrame().evaluateJavaScript("getXMax();") - - if x_min.isNull(): - x_min = None - elif x_min.typeName() == "double": - x_min = x_min.toDouble()[0] - else: - raise TypeError("Unknown type %s for x_min" % x_min.typeName()) - - if x_max.isNull(): - x_max = None - elif x_max.typeName() == "double": - x_max = x_max.toDouble()[0] - else: - raise TypeError("Unknown type %s for x_max" % x_max.typeName()) - - return x_min, x_max - - - def getYScales(self, data): - """ @rtype: (float, float) """ - self.__temporary_data_object = data - y_min = self.__web_page.mainFrame().evaluateJavaScript("getYMin();") - y_max = self.__web_page.mainFrame().evaluateJavaScript("getYMax();") - - if y_min.isNull(): - y_min = None - elif y_min.typeName() == "double": - y_min = y_min.toDouble()[0] - else: - raise TypeError("Unknown type %s for y_min" % y_min.typeName()) - - if y_max.isNull(): - y_max = None - elif y_max.typeName() == "double": - y_max = y_max.toDouble()[0] - else: - raise TypeError("Unknown type %s for y_max" % y_max.typeName()) - - return y_min, y_max - - - - - diff --git a/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/plot_case_model.py b/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/plot_case_model.py index fcb59930c3..2bf2b56b02 100644 --- a/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/plot_case_model.py +++ b/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/plot_case_model.py @@ -47,7 +47,7 @@ def itemAt(self, index): def getAllItems(self): if self.__data is None: - self.__data = CaseList().getAllCasesWithDataAndNotRunning() + self.__data = CaseList().getAllCasesNotRunning() return self.__data diff --git a/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/plot_metrics_tracker.py b/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/plot_metrics_tracker.py deleted file mode 100644 index 80b4883e35..0000000000 --- a/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/plot_metrics_tracker.py +++ /dev/null @@ -1,84 +0,0 @@ -class PlotMetricsTracker(object): - def __init__(self): - super(PlotMetricsTracker, self).__init__() - - self.__data_type_key = None - self.__data_type_key_support_report_steps = False - self.__scale_types = {} - - self.__scales = {} - - def addScaleType(self, scale_name, scale_type): - """ - @type scale_name: str - @type scale_type: int or float or CTime - """ - self.__scale_types[scale_name] = scale_type - - - def getType(self, scale_name): - """ - @type scale_name: str - @rtype: int or float or CTime or None - """ - - if scale_name is None: - return None - - if not scale_name in self.__scale_types: - raise KeyError("Scale type with name: '%s' does not exist!" % scale_name) - - return self.__scale_types[scale_name] - - - def __createScaleTracker(self): - scale_tracker = {} - - for scale_name in self.__scale_types.keys(): - scale_tracker[scale_name] = (None, None) - - return scale_tracker - - def setDataTypeKey(self, data_type_key): - """ @type data_type_key: str """ - self.__data_type_key = data_type_key - - if not data_type_key in self.__scales: - self.__scales[data_type_key] = self.__createScaleTracker() - - def getDataTypeKey(self): - """ @rtype: str """ - return self.__data_type_key - - - def setScalesForType(self, scale_name, min_value, max_value): - if scale_name is not None: - if not scale_name in self.__scales[self.__data_type_key]: - raise KeyError("Scale name '%s' not registered!" % scale_name) - - self.__scales[self.__data_type_key][scale_name] = (min_value, max_value) - - - def getScalesForType(self, scale_name): - """ @rtype: tuple of (int, int) or tuple of (float, float) or tuple of (CTime, CTime) """ - scale_tracker = self.__scales[self.__data_type_key] - if not scale_name in scale_tracker: - return None, None - - return scale_tracker[scale_name] - - def setDataTypeKeySupportsReportSteps(self, supports_report_steps): - self.__data_type_key_support_report_steps = supports_report_steps - - def dataTypeSupportsReportStep(self): - return self.__data_type_key_support_report_steps - - def resetScaleType(self, scale_name): - self.setScalesForType(scale_name, None, None) - - def hasScale(self, scale_name): - if scale_name is None: - return True - - scale_tracker = self.__scales[self.__data_type_key] - return not scale_tracker[scale_name] == (None, None) diff --git a/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/plot_panel.py b/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/plot_panel.py deleted file mode 100644 index 78d16ea506..0000000000 --- a/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/plot_panel.py +++ /dev/null @@ -1,124 +0,0 @@ -from PyQt4.QtCore import Qt, pyqtSignal -from PyQt4.QtGui import QWidget, QGridLayout, QPainter, QShortcut, QMainWindow -from PyQt4.QtWebKit import QWebView, QWebSettings, QWebInspector - -from ert_gui.tools.plot import PlotBridge -from ert_gui.tools.plot.plot_bridge import PlotWebPage - - -class PlotWebView(QWebView): - def __init__(self, name): - QWebView.__init__(self) - self.setPage(PlotWebPage(name)) - self.setRenderHint(QPainter.Antialiasing, True) - self.setContextMenuPolicy(Qt.NoContextMenu) - self.settings().setAttribute(QWebSettings.JavascriptEnabled, True) - self.settings().setAttribute(QWebSettings.LocalContentCanAccessFileUrls, True) - self.settings().setAttribute(QWebSettings.LocalContentCanAccessRemoteUrls, True) - self.settings().clearMemoryCaches() - - self.__inspector_window = None - - shortcut = QShortcut(self) - shortcut.setKey(Qt.Key_F12) - shortcut.activated.connect(self.toggleInspector) - - - def toggleInspector(self): - if self.__inspector_window is None: - self.settings().setAttribute(QWebSettings.DeveloperExtrasEnabled, True) - web_inspector = QWebInspector() - web_inspector.setPage(self.page()) - - self.__inspector_window = QMainWindow(self) - self.__inspector_window.setCentralWidget(web_inspector) - self.__inspector_window.resize(900, 600) - self.__inspector_window.setVisible(False) - - self.__inspector_window.setVisible(not self.__inspector_window.isVisible()) - - -class PlotPanel(QWidget): - plotReady = pyqtSignal() - - def __init__(self, name, debug_name, plot_url): - QWidget.__init__(self) - - self.__name = name - self.__debug_name = debug_name - self.__plot_url = plot_url - - layout = QGridLayout() - - self.web_view = PlotWebView(debug_name) - - layout.addWidget(self.web_view) - self.setLayout(layout) - - self.__plot_is_visible = True - self.__plot_bridge = PlotBridge(self.getWebView().page(), plot_url) - self.__plot_bridge.plotReady.connect(self.plotReady) - - - def getName(self): - return self.__name - - def getUrl(self): - return self.__plot_url - - def getWebView(self): - return self.web_view - - def setSettings(self, settings): - if self.isPlotVisible(): - self.__plot_bridge.setPlotSettings(settings) - - def isReady(self): - return self.__plot_bridge.isReady() - - - def resizeEvent(self, event): - QWidget.resizeEvent(self, event) - if self.isPlotVisible(): - self.__plot_bridge.updatePlotSize(size = self.size()) - - - def supportsPlotProperties(self, time=False, value=False, depth=False, index=False, histogram=False, pca=False): - return self.__plot_bridge.supportsPlotProperties(time, value, depth, index, histogram, pca) - - def isPlotVisible(self): - return self.__plot_is_visible - - def setPlotIsVisible(self, visible): - self.__plot_is_visible = visible - - def getPlotBridge(self): - """ @rtype: PlotBridge """ - return self.__plot_bridge - - def renderNow(self): - if self.isPlotVisible(): - self.__plot_bridge.renderNow() - - - def xAxisType(self): - """ @rtype: str """ - return self.__plot_bridge.xAxisType() - - - def yAxisType(self): - """ @rtype: str """ - return self.__plot_bridge.yAxisType() - - def getXScales(self, data): - """ @rtype: (float, float) """ - return self.__plot_bridge.getXScales(data) - - def getYScales(self, data): - """ @rtype: (float, float) """ - return self.__plot_bridge.getYScales(data) - - - def isReportStepCapable(self): - """ @rtype: bool """ - return self.__plot_bridge.isReportStepCapable() \ No newline at end of file diff --git a/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/plot_panel_tracker.py b/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/plot_panel_tracker.py deleted file mode 100644 index e518e06ae1..0000000000 --- a/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/plot_panel_tracker.py +++ /dev/null @@ -1,56 +0,0 @@ -from PyQt4.QtGui import QTabWidget - -class PlotPanelTracker(object): - def __init__(self, tab_widget): - """@type tab_widget: QTabWidget""" - super(PlotPanelTracker, self).__init__() - - self.__selected_widget_for_type = {} - self.__tab_widget = tab_widget - - self.__key_type_tester_map = {} - - def addKeyTypeTester(self, key_type, tester_function): - if key_type in self.__key_type_tester_map: - raise KeyError("Key type '%s' already exists!" % key_type) - - self.__key_type_tester_map[key_type] = tester_function - - - def storePlotType(self, fetcher, key): - """ - @type fetcher: PlotDataFetcher - @type key: str - """ - if key is not None: - for key_type in self.__key_type_tester_map: - data_type_tester_function = self.__key_type_tester_map[key_type] - - if data_type_tester_function(fetcher, key): - self.__selected_widget_for_type[key_type] = self.__tab_widget.currentWidget() - return - - raise NotImplementedError("Key '%s' not supported." % key) - - - def restorePlotType(self, fetcher, key): - """ - @type fetcher: PlotDataFetcher - @type key: str - """ - if key is not None: - for key_type in self.__key_type_tester_map: - data_type_tester_function = self.__key_type_tester_map[key_type] - - if data_type_tester_function(fetcher, key): - - if key_type in self.__selected_widget_for_type: - widget = self.__selected_widget_for_type[key_type] - self.__tab_widget.setCurrentWidget(widget) - else: - if self.__tab_widget.count() > 0: - self.__tab_widget.setCurrentIndex(0) - - return - - raise NotImplementedError("Key '%s' not supported." % key) diff --git a/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/plot_scale_widget.py b/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/plot_scale_widget.py deleted file mode 100644 index 20bb964f88..0000000000 --- a/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/plot_scale_widget.py +++ /dev/null @@ -1,143 +0,0 @@ -from PyQt4.QtCore import pyqtSignal, Qt -from PyQt4.QtGui import QWidget, QVBoxLayout, QCheckBox, QDoubleSpinBox, QSpinBox, QStackedWidget, QSizePolicy, QLabel - -from ert.util import CTime -from ert_gui.models.connectors.plot import ReportStepsModel -from ert_gui.widgets.list_spin_box import ListSpinBox - - -class PlotScalesWidget(QWidget): - plotScaleChanged = pyqtSignal() - - def __init__(self, type_key, title, select_min_time_value=False): - QWidget.__init__(self) - - self.__type_key = type_key - self.__type = None - - self.__double_spinner = self.createDoubleSpinner(minimum=-1e15, maximum=1e15) - self.__integer_spinner = self.createIntegerSpinner(minimum=0, maximum=1e10) - - self.__time_map = ReportStepsModel().getList() - self.__time_index_map = {} - for index in range(len(self.__time_map)): - time = self.__time_map[index] - self.__time_index_map[time] = index - - self.__time_spinner = self.createTimeSpinner(select_minimum_value=select_min_time_value) - - layout = QVBoxLayout() - self.setLayout(layout) - - self.__label = QLabel(title) - self.__label.setAlignment(Qt.AlignHCenter) - - self.__stack = QStackedWidget() - self.__stack.setSizePolicy(QSizePolicy(QSizePolicy.Preferred)) - self.__stack.addWidget(self.__integer_spinner) - self.__stack.addWidget(self.__double_spinner) - self.__stack.addWidget(self.__time_spinner) - - layout.addWidget(self.__stack) - layout.addWidget(self.__label) - - self.setLayout(layout) - - def createDoubleSpinner(self, minimum, maximum): - spinner = QDoubleSpinBox() - spinner.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored) - spinner.setMinimumWidth(105) - spinner.setRange(minimum, maximum) - spinner.setKeyboardTracking(False) - spinner.setDecimals(8) - - spinner.editingFinished.connect(self.plotScaleChanged) - spinner.valueChanged.connect(self.plotScaleChanged) - - return spinner - - def createIntegerSpinner(self, minimum, maximum): - spinner = QSpinBox() - spinner.setMinimumWidth(75) - spinner.setRange(minimum, maximum) - spinner.setKeyboardTracking(False) - - spinner.editingFinished.connect(self.plotScaleChanged) - spinner.valueChanged.connect(self.plotScaleChanged) - - return spinner - - def createTimeSpinner(self, select_minimum_value): - def converter(item): - return "%s" % (str(item.date())) - - spinner = ListSpinBox(self.__time_map) - spinner.setMinimumWidth(75) - - if select_minimum_value: - spinner.setValue(0) - - spinner.valueChanged[int].connect(self.plotScaleChanged) - spinner.editingFinished.connect(self.plotScaleChanged) - spinner.setStringConverter(converter) - - return spinner - - - def getValue(self): - if self.__type is int: - return self.__integer_spinner.value() - elif self.__type is float: - return self.__double_spinner.value() - elif self.__type is CTime: - index = self.__time_spinner.value() - return self.__time_map[index] - else: - raise TypeError("Unsupported spinner type: %s" % self.__type) - - - def setValue(self, value): - if value is not None: - if self.__type is int: - self.__integer_spinner.setValue(int(value)) - elif self.__type is float: - self.__double_spinner.setValue(value) - elif self.__type is CTime: - index = self.__time_index_map[value] - self.__time_spinner.setValue(index) - else: - raise TypeError("Unsupported spinner type: %s" % self.__type) - - - def setFontSize(self, size): - font = self.__double_spinner.font() - font.setPointSize(size) - self.__double_spinner.setFont(font) - - font = self.__integer_spinner.font() - font.setPointSize(size) - self.__integer_spinner.setFont(font) - - font = self.__time_spinner.font() - font.setPointSize(size) - self.__time_spinner.setFont(font) - - font = self.__label.font() - font.setPointSize(size) - self.__label.setFont(font) - - - def setType(self, spinner_type): - self.__type = spinner_type - if spinner_type is int: - self.__stack.setCurrentWidget(self.__integer_spinner) - elif spinner_type is float: - self.__stack.setCurrentWidget(self.__double_spinner) - elif spinner_type is CTime: - self.__stack.setCurrentWidget(self.__time_spinner) - else: - raise TypeError("Unsupported spinner type: %s" % spinner_type) - - - def getType(self): - return self.__type diff --git a/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/plot_tool.py b/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/plot_tool.py index 8a4497f383..4dc34e3784 100644 --- a/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/plot_tool.py +++ b/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/plot_tool.py @@ -4,11 +4,12 @@ class PlotTool(Tool): - def __init__(self): + def __init__(self, ert): super(PlotTool, self).__init__("Create Plot", "tools/plot", util.resourceIcon("ide/chart_curve_add")) + self.__ert = ert def trigger(self): - plot_window = PlotWindow(self.parent()) + plot_window = PlotWindow(self.__ert, self.parent()) plot_window.show() diff --git a/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/plot_tool_bar.py b/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/plot_tool_bar.py deleted file mode 100644 index d549c4b8ad..0000000000 --- a/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/plot_tool_bar.py +++ /dev/null @@ -1,105 +0,0 @@ -from PyQt4.QtCore import Qt, pyqtSignal -from PyQt4.QtGui import QToolBar -from ert.util import CTime -from ert_gui.tools.plot import ReportStepWidget, PlotScalesWidget -from ert_gui.widgets import util - - -class PlotToolBar(QToolBar): - FONT_SIZE = 11 - - exportClicked = pyqtSignal() - resetScalesClicked = pyqtSignal() - reportStepChanged = pyqtSignal() - plotScalesChanged = pyqtSignal() - - def __init__(self): - QToolBar.__init__(self, "PlotTools") - - self.setObjectName("PlotToolBar") - self.setToolButtonStyle(Qt.ToolButtonTextUnderIcon) - - self.__reset_scales = self.createAction("Reset Scales", util.resourceIcon("ide/transform_scale")) - self.__reset_scales.triggered.connect(self.resetScalesClicked) - - self.__x_min, self.__x_min_action = self.addScaler("x_min", "X Minimum", spinner_type=CTime, select_min_time_value=True) - self.__x_max, self.__x_max_action = self.addScaler("x_max", "X Maximum", spinner_type=CTime) - self.__y_min, self.__y_min_action = self.addScaler("y_min", "Y Minimum", spinner_type=float, select_min_time_value=True) - self.__y_max, self.__y_max_action = self.addScaler("y_max", "Y Maximum", spinner_type=float) - - self.__report_step_widget = ReportStepWidget() - self.__report_step_widget.reportStepTimeSelected.connect(self.reportStepChanged) - self.__report_step_widget.setFontSize(PlotToolBar.FONT_SIZE) - - self.__report_step_widget_action = self.addWidget(self.__report_step_widget) - - self.addSeparator() - - export_action = self.createAction("Export Plot", util.resourceIcon("ide/table_export")) - export_action.triggered.connect(self.exportClicked) - - - def createAction(self, title, icon): - action = self.addAction(title) - action.setIcon(icon) - - w = self.widgetForAction(action) - font = w.font() - font.setPointSize(PlotToolBar.FONT_SIZE) - w.setFont(font) - - return action - - def addScaler(self, type_key, title, spinner_type, select_min_time_value=False): - scaler = PlotScalesWidget(type_key, title, select_min_time_value=select_min_time_value) - scaler.setFontSize(PlotToolBar.FONT_SIZE) - scaler.plotScaleChanged.connect(self.plotScalesChanged) - scaler.setType(spinner_type) - - action = self.addWidget(scaler) - - return scaler, action - - - def setToolBarOptions(self, x_type, y_type, report_step_capable): - self.blockSignals(True) - self.__x_min_action.setVisible(x_type is not None) - self.__x_max_action.setVisible(x_type is not None) - - self.__y_min_action.setVisible(y_type is not None) - self.__y_max_action.setVisible(y_type is not None) - - if x_type is not None: - self.__x_min.setType(x_type) - self.__x_max.setType(x_type) - - if y_type is not None: - self.__y_min.setType(y_type) - self.__y_max.setType(y_type) - - self.__report_step_widget_action.setVisible(report_step_capable) - self.blockSignals(False) - - - def getXScales(self): - return (self.__x_min.getValue()), (self.__x_max.getValue()) - - - def getYScales(self): - return (self.__y_min.getValue()), (self.__y_max.getValue()) - - - def getReportStep(self): - """ @rtype: CTime """ - return self.__report_step_widget.getSelectedValue() - - - def setScales(self, x_min, x_max, y_min, y_max): - self.blockSignals(True) - - self.__x_min.setValue(x_min) - self.__x_max.setValue(x_max) - self.__y_min.setValue(y_min) - self.__y_max.setValue(y_max) - - self.blockSignals(False) diff --git a/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/plot_widget.py b/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/plot_widget.py new file mode 100644 index 0000000000..d745039192 --- /dev/null +++ b/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/plot_widget.py @@ -0,0 +1,68 @@ +from PyQt4.QtCore import Qt +from PyQt4.QtGui import QWidget, QVBoxLayout + +from matplotlib.figure import Figure +from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas, NavigationToolbar2QT as NavigationToolbar + +class PlotWidget(QWidget): + def __init__(self, name, plotFunction, plot_condition_function_list, plotContextFunction, parent=None): + QWidget.__init__(self, parent) + + self.__name = name + self.__plotFunction = plotFunction + self.__plotContextFunction = plotContextFunction + self.__plot_conditions = plot_condition_function_list + """:type: list of functions """ + self.__figure = Figure() + self.__figure.set_tight_layout(True) + self.__canvas = FigureCanvas(self.__figure) + self.__canvas.setParent(self) + self.__canvas.setFocusPolicy(Qt.StrongFocus) + self.__canvas.setFocus() + + vbox = QVBoxLayout() + vbox.addWidget(self.__canvas) + self.__toolbar = NavigationToolbar(self.__canvas, self) + vbox.addWidget(self.__toolbar) + self.setLayout(vbox) + + self.__dirty = True + self.__active = False + self.resetPlot() + + + + def getFigure(self): + """ :rtype: matplotlib.figure.Figure""" + return self.__figure + + + def resetPlot(self): + self.__figure.clear() + + + def updatePlot(self): + if self.isDirty() and self.isActive(): + print("Drawing: %s" % self.__name) + self.resetPlot() + plot_context = self.__plotContextFunction(self.getFigure()) + self.__plotFunction(plot_context) + self.__canvas.draw() + + self.setDirty(False) + + + def setDirty(self, dirty=True): + self.__dirty = dirty + + def isDirty(self): + return self.__dirty + + def setActive(self, active=True): + self.__active = active + + def isActive(self): + return self.__active + + def canPlotKey(self, key): + return any([plotConditionFunction(key) for plotConditionFunction in self.__plot_conditions]) \ No newline at end of file diff --git a/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/plot_window.py b/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/plot_window.py index 394cea0d3e..18dda0476a 100644 --- a/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/plot_window.py +++ b/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/plot_window.py @@ -1,251 +1,123 @@ from PyQt4.QtCore import Qt from PyQt4.QtGui import QMainWindow, QDockWidget, QTabWidget, QWidget, QVBoxLayout -from ert.util import CTime + from ert_gui.models.connectors.init import CaseSelectorModel -from ert_gui.tools.plot import PlotPanel, DataTypeKeysWidget, CaseSelectionWidget, ExportPlot, CustomizePlotWidget, PlotToolBar, PlotMetricsTracker, PlotPanelTracker -from ert_gui.tools.plot.data import PlotDataFetcher +from ert_gui.plottery import PlotContext, PlotDataGatherer, PlotConfig, plots + + +from ert_gui.tools.plot import DataTypeKeysWidget, CaseSelectionWidget, CustomizePlotWidget, PlotWidget +from ert_gui.tools.plot import DataTypeKeysListModel from ert_gui.widgets.util import may_take_a_long_time class PlotWindow(QMainWindow): - def __init__(self, parent): + def __init__(self, ert, parent): QMainWindow.__init__(self, parent) + self.__ert = ert + """:type: ert.enkf.enkf_main.EnKFMain""" + self.setMinimumWidth(750) self.setMinimumHeight(500) self.setWindowTitle("Plotting") self.activateWindow() - self.__plot_data = None - - self.__plot_metrics_tracker = PlotMetricsTracker() - self.__plot_metrics_tracker.addScaleType("value", float) - self.__plot_metrics_tracker.addScaleType("depth", float) - self.__plot_metrics_tracker.addScaleType("pca", float) - self.__plot_metrics_tracker.addScaleType("index", int) - self.__plot_metrics_tracker.addScaleType("count", int) - self.__plot_metrics_tracker.addScaleType("time", CTime) - self.__central_tab = QTabWidget() self.__central_tab.currentChanged.connect(self.currentPlotChanged) - self.__plot_panel_tracker = PlotPanelTracker(self.__central_tab) - self.__plot_panel_tracker.addKeyTypeTester("summary", PlotDataFetcher.isSummaryKey) - self.__plot_panel_tracker.addKeyTypeTester("block", PlotDataFetcher.isBlockObservationKey) - self.__plot_panel_tracker.addKeyTypeTester("gen_kw", PlotDataFetcher.isGenKWKey) - self.__plot_panel_tracker.addKeyTypeTester("gen_data", PlotDataFetcher.isGenDataKey) - self.__plot_panel_tracker.addKeyTypeTester("custom_pca", PlotDataFetcher.isCustomPcaDataKey) - - central_widget = QWidget() central_layout = QVBoxLayout() central_layout.setContentsMargins(0, 0, 0, 0) central_widget.setLayout(central_layout) - self.__toolbar = PlotToolBar() - self.__toolbar.resetScalesClicked.connect(self.resetCurrentScales) - - central_layout.addWidget(self.__toolbar) central_layout.addWidget(self.__central_tab) self.setCentralWidget(central_widget) + key_manager = ert.getKeyManager() + """:type: ert.enkf.key_manager.KeyManager """ + + self.__plot_widgets = [] + """:type: list of PlotWidget""" - self.__plot_panels = [] - """:type: list of PlotPanel""" + self.__data_gatherers = [] + """:type: list of PlotDataGatherer """ - self.addPlotPanel("Ensemble plot", "gui/plots/simple_plot.html", short_name="EP") - self.addPlotPanel("Ensemble overview plot", "gui/plots/simple_overview_plot.html", short_name="EOP") - self.addPlotPanel("Ensemble statistics", "gui/plots/ensemble_statistics_plot.html", short_name="ES") - self.addPlotPanel("Histogram", "gui/plots/histogram.html", short_name="Histogram") - self.addPlotPanel("Distribution", "gui/plots/gen_kw.html", short_name="Distribution") - self.addPlotPanel("RFT plot", "gui/plots/rft.html", short_name="RFT") - self.addPlotPanel("RFT overview plot", "gui/plots/rft_overview.html", short_name="oRFT") - self.addPlotPanel("Ensemble plot", "gui/plots/gen_data.html", short_name="epGenData") - self.addPlotPanel("Ensemble overview plot", "gui/plots/gen_data_overview.html", short_name="eopGenData") - self.addPlotPanel("Ensemble statistics", "gui/plots/gen_data_statistics_plot.html", short_name="esGenData") - self.addPlotPanel("PCA plot", "gui/plots/pca.html", short_name="PCA") + PDG = PlotDataGatherer + summary_gatherer = self.createDataGatherer(PDG.gatherSummaryData, key_manager.isSummaryKey, refcaseGatherFunc=PDG.gatherSummaryRefcaseData, observationGatherFunc=PDG.gatherSummaryObservationData) + gen_data_gatherer = self.createDataGatherer(PDG.gatherGenDataData, key_manager.isGenDataKey, observationGatherFunc=PDG.gatherGenDataObservationData) + gen_kw_gatherer = self.createDataGatherer(PDG.gatherGenKwData, key_manager.isGenKwKey) + custom_kw_gatherer = self.createDataGatherer(PDG.gatherCustomKwData, key_manager.isCustomKwKey) - self.__data_type_keys_widget = DataTypeKeysWidget() + + self.addPlotWidget("Ensemble", plots.plotEnsemble, [summary_gatherer, gen_data_gatherer]) + self.addPlotWidget("Overview", plots.plotOverview, [summary_gatherer, gen_data_gatherer]) + self.addPlotWidget("Statistics", plots.plotStatistics, [summary_gatherer, gen_data_gatherer]) + self.addPlotWidget("Histogram", plots.plotHistogram, [gen_kw_gatherer, custom_kw_gatherer]) + self.addPlotWidget("Gaussian KDE", plots.plotGaussianKDE, [gen_kw_gatherer, custom_kw_gatherer]) + + + self.__data_types_key_model = DataTypeKeysListModel(ert) + + self.__data_type_keys_widget = DataTypeKeysWidget(self.__data_types_key_model) self.__data_type_keys_widget.dataTypeKeySelected.connect(self.keySelected) self.addDock("Data types", self.__data_type_keys_widget) current_case = CaseSelectorModel().getCurrentChoice() self.__case_selection_widget = CaseSelectionWidget(current_case) - self.__case_selection_widget.caseSelectionChanged.connect(self.caseSelectionChanged) + self.__case_selection_widget.caseSelectionChanged.connect(self.keySelected) plot_case_dock = self.addDock("Plot case", self.__case_selection_widget) self.__customize_plot_widget = CustomizePlotWidget() - self.__customize_plot_widget.customPlotSettingsChanged.connect(self.plotSettingsChanged) + self.__customize_plot_widget.customPlotSettingsChanged.connect(self.keySelected) customize_plot_dock = self.addDock("Customize", self.__customize_plot_widget) - self.__toolbar.exportClicked.connect(self.exportActivePlot) - self.__toolbar.plotScalesChanged.connect(self.plotSettingsChanged) - self.__toolbar.reportStepChanged.connect(self.plotSettingsChanged) - self.__exporter = None self.tabifyDockWidget(plot_case_dock, customize_plot_dock) plot_case_dock.show() plot_case_dock.raise_() - self.__plot_cases = self.__case_selection_widget.getPlotCaseNames() - - - def fetchDefaultXScales(self): - if self.__plot_data is not None: - active_plot = self.getActivePlot() - x_axis_type_name = active_plot.xAxisType() - - x_axis_type = self.__plot_metrics_tracker.getType(x_axis_type_name) - - if x_axis_type is not None: - x_min, x_max = active_plot.getXScales(self.__plot_data) - - if x_axis_type is CTime and x_min is not None and x_max is not None: - x_min = int(x_min) - x_max = int(x_max) - - self.__plot_metrics_tracker.setScalesForType(x_axis_type_name, x_min, x_max) + self.__plot_widgets[self.__central_tab.currentIndex()].setActive() + self.__data_type_keys_widget.selectDefault() - - def fetchDefaultYScales(self): - if self.__plot_data is not None: - active_plot = self.getActivePlot() - y_axis_type_name = active_plot.yAxisType() - - y_axis_type = self.__plot_metrics_tracker.getType(y_axis_type_name) - - if y_axis_type is not None: - y_min, y_max = active_plot.getYScales(self.__plot_data) - - if y_axis_type is CTime and y_min is not None and y_max is not None: - y_min = int(y_min) - y_max = int(y_max) - - self.__plot_metrics_tracker.setScalesForType(y_axis_type_name, y_min, y_max) - - - def resetCurrentScales(self): - active_plot = self.getActivePlot() - x_axis_type_name = active_plot.xAxisType() - y_axis_type_name = active_plot.yAxisType() - - self.__plot_metrics_tracker.resetScaleType(x_axis_type_name) - self.__plot_metrics_tracker.resetScaleType(y_axis_type_name) - - self.currentPlotChanged() - self.plotSettingsChanged() - - - def getActivePlot(self): - """ @rtype: PlotPanel """ - if not self.__central_tab.currentIndex() > -1: - raise AssertionError("No plot selected!") - - active_plot = self.__central_tab.currentWidget() - assert isinstance(active_plot, PlotPanel) - - return active_plot + def createDataGatherer(self, dataGatherFunc, gatherConditionFunc, refcaseGatherFunc=None, observationGatherFunc=None): + data_gatherer = PlotDataGatherer(dataGatherFunc, gatherConditionFunc, refcaseGatherFunc=refcaseGatherFunc, observationGatherFunc=observationGatherFunc) + self.__data_gatherers.append(data_gatherer) + return data_gatherer def currentPlotChanged(self): - active_plot = self.getActivePlot() - - if active_plot.isReady(): - x_axis_type_name = active_plot.xAxisType() - x_axis_type = self.__plot_metrics_tracker.getType(x_axis_type_name) - - y_axis_type_name = active_plot.yAxisType() - y_axis_type = self.__plot_metrics_tracker.getType(y_axis_type_name) - - if not self.__plot_metrics_tracker.hasScale(x_axis_type_name): - self.fetchDefaultXScales() - - if not self.__plot_metrics_tracker.hasScale(y_axis_type_name): - self.fetchDefaultYScales() - - x_min, x_max = self.__plot_metrics_tracker.getScalesForType(x_axis_type_name) - y_min, y_max = self.__plot_metrics_tracker.getScalesForType(y_axis_type_name) - - self.__toolbar.setToolBarOptions(x_axis_type, y_axis_type, active_plot.isReportStepCapable() and self.__plot_metrics_tracker.dataTypeSupportsReportStep()) - self.__toolbar.setScales(x_min, x_max, y_min, y_max) + for plot_widget in self.__plot_widgets: + plot_widget.setActive(False) + index = self.__central_tab.indexOf(plot_widget) + if index == self.__central_tab.currentIndex() and plot_widget.canPlotKey(self.getSelectedKey()): + plot_widget.setActive() + plot_widget.updatePlot() - def plotSettingsChanged(self): - x_min, x_max = self.__toolbar.getXScales() - y_min, y_max = self.__toolbar.getYScales() - active_plot = self.getActivePlot() + def createPlotContext(self, figure): + key = self.getSelectedKey() + cases = self.__case_selection_widget.getPlotCaseNames() + data_gatherer = next((data_gatherer for data_gatherer in self.__data_gatherers if data_gatherer.canGatherDataForKey(key)), None) + plot_config = PlotConfig(key) + self.applyCustomization(plot_config) + return PlotContext(self.__ert, figure, plot_config, cases, key, data_gatherer) - x_axis_type_name = active_plot.xAxisType() - y_axis_type_name = active_plot.yAxisType() + def getSelectedKey(self): + key = str(self.__data_type_keys_widget.getSelectedItem()) + return key - self.__plot_metrics_tracker.setScalesForType(x_axis_type_name, x_min, x_max) - self.__plot_metrics_tracker.setScalesForType(y_axis_type_name, y_min, y_max) + def addPlotWidget(self, name, plotFunction, data_gatherers, enabled=True): + plot_condition_function_list = [data_gatherer.canGatherDataForKey for data_gatherer in data_gatherers] + plot_widget = PlotWidget(name, plotFunction, plot_condition_function_list, self.createPlotContext) - self.updatePlots() - - - def updatePlots(self): - report_step = self.__toolbar.getReportStep() - - for plot_panel in self.__plot_panels: - if plot_panel.isPlotVisible(): - model = plot_panel.getPlotBridge() - model.setPlotData(self.__plot_data) - model.setCustomSettings(self.__customize_plot_widget.getCustomSettings()) - model.setReportStepTime(report_step) - - x_axis_type_name = plot_panel.xAxisType() - y_axis_type_name = plot_panel.yAxisType() - - x_min, x_max = self.__plot_metrics_tracker.getScalesForType(x_axis_type_name) - y_min, y_max = self.__plot_metrics_tracker.getScalesForType(y_axis_type_name) - - model.setScales(x_min, x_max, y_min, y_max) - - plot_panel.renderNow() - - - def exportActivePlot(self): - active_plot = self.getActivePlot() - - if self.__exporter is None: - path = None - else: - path = self.__exporter.getCurrentPath() - - - report_step = self.__toolbar.getReportStep() - - x_axis_type_name = active_plot.xAxisType() - y_axis_type_name = active_plot.yAxisType() - - x_min, x_max = self.__plot_metrics_tracker.getScalesForType(x_axis_type_name) - y_min, y_max = self.__plot_metrics_tracker.getScalesForType(y_axis_type_name) - - settings = {"x_min": x_min, - "x_max": x_max, - "y_min": y_min, - "y_max": y_max, - "report_step": report_step} - - self.__exporter = ExportPlot(active_plot, settings, self.__customize_plot_widget.getCustomSettings(), path) - - self.__exporter.export() - - - def addPlotPanel(self, name, path, short_name=None): - if short_name is None: - short_name = name - - plot_panel = PlotPanel(name, short_name, path) - plot_panel.plotReady.connect(self.plotReady) - self.__plot_panels.append(plot_panel) - self.__central_tab.addTab(plot_panel, name) + index = self.__central_tab.addTab(plot_widget, name) + self.__plot_widgets.append(plot_widget) + self.__central_tab.setTabEnabled(index, enabled) def addDock(self, name, widget, area=Qt.LeftDockWidgetArea, allowed_areas=Qt.AllDockWidgetAreas): @@ -259,87 +131,24 @@ def addDock(self, name, widget, area=Qt.LeftDockWidgetArea, allowed_areas=Qt.All return dock_widget - def checkPlotStatus(self): - for plot_panel in self.__plot_panels: - if not plot_panel.isReady(): - return False - - if len(self.__plot_cases) == 0: - return False - - return True - - def plotReady(self): - if self.checkPlotStatus(): - self.__data_type_keys_widget.selectDefault() - self.currentPlotChanged() - self.__customize_plot_widget.emitChange() - + def applyCustomization(self, plot_config): + custom = self.__customize_plot_widget.getCustomSettings() - def caseSelectionChanged(self): - self.__plot_cases = self.__case_selection_widget.getPlotCaseNames() - self.keySelected(self.__plot_metrics_tracker.getDataTypeKey()) - - - def showOrHidePlotTab(self, plot_panel, is_visible, show_plot): - plot_panel.setPlotIsVisible(show_plot) - if show_plot and not is_visible: - index = self.__plot_panels.index(plot_panel) - self.__central_tab.insertTab(index, plot_panel, plot_panel.getName()) - elif not show_plot and is_visible: - index = self.__central_tab.indexOf(plot_panel) - self.__central_tab.removeTab(index) + plot_config.setObservationsEnabled(custom["show_observations"]) + plot_config.setRefcaseEnabled(custom["show_refcase"]) + plot_config.setLegendEnabled(custom["show_legend"]) + plot_config.setGridEnabled(custom["show_grid"]) @may_take_a_long_time - def keySelected(self, key): - key = str(key) - old_data_type_key = self.__plot_metrics_tracker.getDataTypeKey() - self.__plot_metrics_tracker.setDataTypeKey(key) - - plot_data_fetcher = PlotDataFetcher() - self.__plot_data = plot_data_fetcher.getPlotDataForKeyAndCases(key, self.__plot_cases) - self.__plot_data.setParent(self) - - self.__central_tab.blockSignals(True) - - self.__plot_panel_tracker.storePlotType(plot_data_fetcher, old_data_type_key) - - for plot_panel in self.__plot_panels: - self.showOrHidePlotTab(plot_panel, False, True) - - self.__plot_metrics_tracker.setDataTypeKeySupportsReportSteps(plot_data_fetcher.dataTypeKeySupportsReportSteps(key)) - show_pca = plot_data_fetcher.isPcaDataKey(key) - for plot_panel in self.__plot_panels: - visible = self.__central_tab.indexOf(plot_panel) > -1 - - if plot_data_fetcher.isSummaryKey(key): - show_plot = plot_panel.supportsPlotProperties(time=True, value=True, histogram=True, pca=show_pca) - self.showOrHidePlotTab(plot_panel, visible, show_plot) - - elif plot_data_fetcher.isBlockObservationKey(key): - show_plot = plot_panel.supportsPlotProperties(depth=True, value=True, pca=show_pca) - self.showOrHidePlotTab(plot_panel, visible, show_plot) - - elif plot_data_fetcher.isGenKWKey(key): - show_plot = plot_panel.supportsPlotProperties(value=True, histogram=True, pca=show_pca) - self.showOrHidePlotTab(plot_panel, visible, show_plot) - - elif plot_data_fetcher.isGenDataKey(key): - show_plot = plot_panel.supportsPlotProperties(index=True, pca=show_pca) - self.showOrHidePlotTab(plot_panel, visible, show_plot) - - elif plot_data_fetcher.isPcaDataKey(key): - show_plot = plot_panel.supportsPlotProperties(pca=show_pca) - self.showOrHidePlotTab(plot_panel, visible, show_plot) - - else: - raise NotImplementedError("Key %s not supported." % key) - - self.__plot_panel_tracker.restorePlotType(plot_data_fetcher, key) + def keySelected(self): + key = self.getSelectedKey() - self.__central_tab.blockSignals(False) - self.currentPlotChanged() + for plot_widget in self.__plot_widgets: + plot_widget.setDirty() + index = self.__central_tab.indexOf(plot_widget) + self.__central_tab.setTabEnabled(index, plot_widget.canPlotKey(key)) - if self.checkPlotStatus(): - self.plotSettingsChanged() + for plot_widget in self.__plot_widgets: + if plot_widget.canPlotKey(key): + plot_widget.updatePlot() diff --git a/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/report_step_widget.py b/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/report_step_widget.py deleted file mode 100644 index e16176470e..0000000000 --- a/ThirdParty/Ert/devel/python/python/ert_gui/tools/plot/report_step_widget.py +++ /dev/null @@ -1,45 +0,0 @@ -from PyQt4.QtCore import pyqtSignal, Qt -from PyQt4.QtGui import QWidget, QVBoxLayout, QLabel -from ert_gui.models.connectors.plot.report_steps import ReportStepsModel -from ert_gui.widgets.list_spin_box import ListSpinBox - - -class ReportStepWidget(QWidget): - reportStepTimeSelected = pyqtSignal(int) - def __init__(self): - QWidget.__init__(self) - - layout = QVBoxLayout() - self.setLayout(layout) - - def converter(item): - return "%s" % (str(item.date())) - - self.__items = ReportStepsModel().getList() - self.__time_spinner = ListSpinBox(self.__items) - self.__time_spinner.valueChanged[int].connect(self.valueSelected) - self.__time_spinner.setStringConverter(converter) - layout.addWidget(self.__time_spinner) - - self.__label = QLabel("Report Step") - - layout.addWidget(self.__label, 0, Qt.AlignHCenter) - layout.addStretch() - - - def valueSelected(self, index): - self.reportStepTimeSelected.emit(self.__items[index]) - - def getSelectedValue(self): - """ @rtype: CTime """ - index = self.__time_spinner.value() - return self.__items[index] - - def setFontSize(self, size): - font = self.__time_spinner.font() - font.setPointSize(size) - self.__time_spinner.setFont(font) - - font = self.__label.font() - font.setPointSize(size) - self.__label.setFont(font) diff --git a/ThirdParty/Ert/devel/python/python/ert_gui/widgets/custom_dialog.py b/ThirdParty/Ert/devel/python/python/ert_gui/widgets/custom_dialog.py index 9abc952aeb..fb969f41cc 100644 --- a/ThirdParty/Ert/devel/python/python/ert_gui/widgets/custom_dialog.py +++ b/ThirdParty/Ert/devel/python/python/ert_gui/widgets/custom_dialog.py @@ -83,6 +83,10 @@ def createSpace(self, size = 5): return qw + def addSpace(self, size=10): + """ Add some vertical spacing """ + space_widget = self.createSpace(size) + self.layout.addRow("", space_widget) def addOption(self, option_widget): """ @@ -93,6 +97,11 @@ def addOption(self, option_widget): option_widget.validationChanged.connect(self.optionValidationChanged) self.layout.addRow(option_widget.getLabel(), option_widget) + def addWidget(self, widget, label=""): + if not label.endswith(":"): + label = "%s:" % label + self.layout.addRow(label, widget) + def addButtons(self): buttons = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel, Qt.Horizontal, self) diff --git a/ThirdParty/Ert/devel/python/tests/CMakeLists.txt b/ThirdParty/Ert/devel/python/tests/CMakeLists.txt index 23067e8a1f..f0cc9487fa 100644 --- a/ThirdParty/Ert/devel/python/tests/CMakeLists.txt +++ b/ThirdParty/Ert/devel/python/tests/CMakeLists.txt @@ -32,6 +32,7 @@ endfunction(addPythonTest) add_subdirectory(core) +add_subdirectory(share) if(BUILD_ERT) add_subdirectory(ert) diff --git a/ThirdParty/Ert/devel/python/tests/core/cwrap/test_basecvalue.py b/ThirdParty/Ert/devel/python/tests/core/cwrap/test_basecvalue.py index 572c023519..31acefcd16 100644 --- a/ThirdParty/Ert/devel/python/tests/core/cwrap/test_basecvalue.py +++ b/ThirdParty/Ert/devel/python/tests/core/cwrap/test_basecvalue.py @@ -1,4 +1,4 @@ -from ctypes import c_ubyte, c_long +from ctypes import c_ubyte, c_double from ert.cwrap import BaseCValue, clib, CWrapper from ert.test import ExtendedTestCase @@ -7,8 +7,8 @@ class UnsignedByteValue(BaseCValue): DATA_TYPE = c_ubyte -class TimeTValue(BaseCValue): - DATA_TYPE = c_long +class MaxDouble(BaseCValue): + DATA_TYPE = c_double class BaseCValueTest(ExtendedTestCase): @@ -17,8 +17,8 @@ def setUp(self): self.ert_wrapper = CWrapper(ert) - self.ert_wrapper.registerType("time_t", TimeTValue) - self.make_date = self.ert_wrapper.prototype("time_t util_make_date(int, int, int)") + self.ert_wrapper.registerType("pow_double", MaxDouble) + self.double_max = self.ert_wrapper.prototype("pow_double util_double_max(double, double)") def test_illegal_type(self): @@ -62,8 +62,8 @@ def test_from_param(self): UnsignedByteValue.from_param("exception") - def test_time_t(self): - future = self.make_date(1, 1, 2050) + def test_double_max(self): + double_max = self.double_max(2.97, 2.98) - self.assertIsInstance(future, TimeTValue) - self.assertEqual(future.value(), 2524604400) + self.assertIsInstance(double_max, MaxDouble) + self.assertEqual(double_max.value(), 2.98) diff --git a/ThirdParty/Ert/devel/python/tests/core/ecl/CMakeLists.txt b/ThirdParty/Ert/devel/python/tests/core/ecl/CMakeLists.txt index 67cc33090b..ff37b91ddc 100644 --- a/ThirdParty/Ert/devel/python/tests/core/ecl/CMakeLists.txt +++ b/ThirdParty/Ert/devel/python/tests/core/ecl/CMakeLists.txt @@ -31,6 +31,7 @@ set(TEST_SOURCES test_rft_cell.py test_statoil_faults.py test_sum.py + test_ecl_util.py ) add_python_package("python.tests.ecl" ${PYTHON_INSTALL_PREFIX}/tests/ecl "${TEST_SOURCES}" False) @@ -62,6 +63,7 @@ addPythonTest(ecl.fault_blocks ecl.test_fault_blocks.FaultBlockTest ) addPythonTest(ecl.fault_blocks_statoil ecl.test_fault_blocks_statoil.FaultBlockTest LABELS StatoilData) addPythonTest(ecl.ecl_npv ecl.test_npv.NPVTest LABELS StatoilData) addPythonTest(ecl.ecl_deprecation ecl.test_deprecation.DeprecationTest ) +addPythonTest(ecl.ecl_util ecl.test_ecl_util.EclUtilTest ) addPythonTest(ecl.indexed_read ecl.test_indexed_read.EclIndexedReadTest LABELS StatoilData) @@ -74,4 +76,4 @@ if (NOT ${NFS_RUNPATH} STREQUAL "") if (NOT ${RSH_SERVERS} STREQUAL "") addPythonTest(ert.ecl.ecl_queue_RSH tests.ecl.test_ecl_submit.RSHSubmitTest ARGUMENTS ${NFS_RUNPATH} ${RSH_SERVERS} LABELS StatoilData:Slow) endif() -endif() \ No newline at end of file +endif() diff --git a/ThirdParty/Ert/devel/python/tests/core/ecl/test_deprecation.py b/ThirdParty/Ert/devel/python/tests/core/ecl/test_deprecation.py index 966ffce403..f4aaf00bb7 100644 --- a/ThirdParty/Ert/devel/python/tests/core/ecl/test_deprecation.py +++ b/ThirdParty/Ert/devel/python/tests/core/ecl/test_deprecation.py @@ -25,7 +25,7 @@ class DeprecationTest(ExtendedTestCase): def test_EclGrid_get_corner_xyz(self): - grid = EclGrid.create_rectangular( (10,20,30) , (1,1,1) ) + grid = EclGrid.createRectangular( (10,20,30) , (1,1,1) ) with warnings.catch_warnings(): grid.get_corner_xyz(0 , global_index = 10) @@ -33,13 +33,20 @@ def test_ecl_ecl_ecl(self): with warnings.catch_warnings(): import ert.ecl.ecl as ecl + # Added in 1.8.x development def test_EclGrid_dims_property(self): - grid = EclGrid.create_rectangular( (10,20,30) , (1,1,1) ) + grid = EclGrid.createRectangular( (10,20,30) , (1,1,1) ) with warnings.catch_warnings(): d = grid.dims + # Added in 1.9.x development + def test_EclGrid_dims_property(self): + with warnings.catch_warnings(): + grid = EclGrid.create_rectangular( (10,20,30) , (1,1,1) ) + + # Added in 1.8.x development @@ -56,7 +63,7 @@ def test_EclKW_min_max(self): # Added in 1.8.x development def test_EclRegion_properties(self): - grid = EclGrid.create_rectangular( (10,10,10) , (1,1,1)) + grid = EclGrid.createRectangular( (10,10,10) , (1,1,1)) region = EclRegion( grid , False ) with warnings.catch_warnings(): @@ -76,4 +83,7 @@ def test_EclRegion_properties(self): # Deprecated method from 1.8.4 def test_BoolVector_active_mask(self): with warnings.catch_warnings(): - active_vector = BoolVector.active_mask("1,1,1,1,1,1") \ No newline at end of file + active_vector = BoolVector.active_mask("1,1,1,1,1,1") + + + diff --git a/ThirdParty/Ert/devel/python/tests/core/ecl/test_ecl_sum_tstep.py b/ThirdParty/Ert/devel/python/tests/core/ecl/test_ecl_sum_tstep.py new file mode 100644 index 0000000000..ddcdcaa609 --- /dev/null +++ b/ThirdParty/Ert/devel/python/tests/core/ecl/test_ecl_sum_tstep.py @@ -0,0 +1,41 @@ +from datetime import datetime +import random +from ert.ecl import EclSumTStep, EclSum +from ert.test import ExtendedTestCase + + +class EclSumTStepTest(ExtendedTestCase): + + def test_creation(self): + ecl_sum = EclSum.writer("TEST", datetime(2010, 1, 1), 10, 10, 10) + ecl_sum.addVariable("FOPT") + ecl_sum.addVariable("FOPR") + + smspec = ecl_sum.cNamespace().get_smspec(ecl_sum) + + test_data = [(1, 0, 10), (1, 1, 20), (1, 2, 30), (2, 0, 40)] + + for report_step, mini_step, sim_days in test_data: + ecl_sum_tstep = EclSumTStep(report_step, mini_step, sim_days, smspec) + + self.assertEqual(ecl_sum_tstep.getSimDays(), sim_days) + self.assertEqual(ecl_sum_tstep.getReport(), report_step) + self.assertEqual(ecl_sum_tstep.getMiniStep(), mini_step) + + self.assertTrue("FOPT" in ecl_sum_tstep) + self.assertTrue("FOPR" in ecl_sum_tstep) + self.assertFalse("WWCT" in ecl_sum_tstep) + + random_float = random.random() + ecl_sum_tstep["FOPT"] = random_float + ecl_sum_tstep["FOPR"] = random_float + 1 + + self.assertAlmostEqual(random_float, ecl_sum_tstep["FOPT"], places=5) + self.assertAlmostEqual(random_float + 1, ecl_sum_tstep["FOPR"], places=5) + + with self.assertRaises(KeyError): + ecl_sum_tstep["FROPR"] = 2 + + with self.assertRaises(KeyError): + value = ecl_sum_tstep["FROPR"] + diff --git a/ThirdParty/Ert/devel/python/tests/core/ecl/test_ecl_util.py b/ThirdParty/Ert/devel/python/tests/core/ecl/test_ecl_util.py new file mode 100644 index 0000000000..5e174aa353 --- /dev/null +++ b/ThirdParty/Ert/devel/python/tests/core/ecl/test_ecl_util.py @@ -0,0 +1,31 @@ +# Copyright (C) 2015 Statoil ASA, Norway. +# +# The file 'sum_test.py' is part of ERT - Ensemble based Reservoir Tool. +# +# ERT is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# ERT is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. +# +# See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> +# for more details. + +from ert.ecl import EclUtil, EclTypeEnum , EclFileEnum +from ert.test import ExtendedTestCase + + +class EclUtilTest(ExtendedTestCase): + + def test_enums(self): + source_file_path = "libecl/include/ert/ecl/ecl_util.h" + self.assertEnumIsFullyDefined(EclFileEnum, "ecl_file_enum", source_file_path) + + + def test_file_type(self): + file_type , fmt , report = EclUtil.inspectExtension("CASE.X0078") + self.assertEqual( file_type , EclFileEnum.ECL_RESTART_FILE ) + diff --git a/ThirdParty/Ert/devel/python/tests/core/ecl/test_faults.py b/ThirdParty/Ert/devel/python/tests/core/ecl/test_faults.py index f0576dd69d..0407f4a65b 100644 --- a/ThirdParty/Ert/devel/python/tests/core/ecl/test_faults.py +++ b/ThirdParty/Ert/devel/python/tests/core/ecl/test_faults.py @@ -17,19 +17,24 @@ from unittest import skipIf import time +from ert import util from ert.ecl.faults import FaultCollection, Fault, FaultLine, FaultSegment,FaultBlockLayer from ert.ecl import EclGrid, EclKW, EclTypeEnum from ert.test import ExtendedTestCase, TestAreaContext from ert.geo import Polyline , CPolyline + class FaultTest(ExtendedTestCase): + @classmethod + def setUpClass(cls): + cls.grid = EclGrid.create_rectangular( (151,100,50) , (1,1,1)) + def setUp(self): self.faults1 = self.createTestPath("local/ECLIPSE/FAULTS/fault1.grdecl") self.faults2 = self.createTestPath("local/ECLIPSE/FAULTS/fault2.grdecl") - self.grid = EclGrid.create_rectangular( (151,100,50) , (1,1,1)) - - + + def test_PolylineIJ(self): nx = 10 ny = 10 @@ -506,10 +511,9 @@ def test_fault_line_order(self): \'F\' 110 110 49 49 1 43 \'X\' / \'F\' 111 111 48 48 1 43 \'Y\' / / -""") - with open("faults.grdecl") as f: - faults = FaultCollection( grid , "faults.grdecl" ) - +""") + faults = FaultCollection( grid , "faults.grdecl" ) + fault = faults["F"] layer = fault[29] self.assertEqual(len(layer) , 2) @@ -518,7 +522,7 @@ def test_fault_line_order(self): line2 = layer[1] self.assertEqual(len(line1) , 4) self.assertEqual(len(line2) , 2) - + seg0 = line1[0] seg1 = line1[1] seg2 = line1[2] @@ -527,7 +531,7 @@ def test_fault_line_order(self): self.assertEqual( seg1.getCorners() , (50 * (nx + 1) + 107 , 50 * (nx + 1) + 108)) self.assertEqual( seg2.getCorners() , (50 * (nx + 1) + 108 , 49 * (nx + 1) + 108)) self.assertEqual( seg3.getCorners() , (49 * (nx + 1) + 108 , 49 * (nx + 1) + 109)) - + @@ -647,8 +651,7 @@ def test_num_linesegment(self): \'F2\' 1 8 2 2 1 1 \'Y\' / / """) - with open("faults.grdecl") as f: - faults = FaultCollection( grid , "faults.grdecl" ) + faults = FaultCollection( grid , "faults.grdecl" ) f1 = faults["F1"] f2 = faults["F2"] diff --git a/ThirdParty/Ert/devel/python/tests/core/ecl/test_grid.py b/ThirdParty/Ert/devel/python/tests/core/ecl/test_grid.py index 006fc8b747..db07243322 100644 --- a/ThirdParty/Ert/devel/python/tests/core/ecl/test_grid.py +++ b/ThirdParty/Ert/devel/python/tests/core/ecl/test_grid.py @@ -132,6 +132,10 @@ def test_init_ACTNUM(self): self.assertEqual( actnum[0] , 1 ) self.assertEqual( actnum[nx*ny*nz - 1] , 1 ) + actnum_kw = grid.exportACTNUMKw( ) + self.assertEqual(len(actnum_kw) , len(actnum)) + for a1,a2 in zip(actnum, actnum_kw): + self.assertEqual(a1, a2) diff --git a/ThirdParty/Ert/devel/python/tests/core/ecl/test_kw.py b/ThirdParty/Ert/devel/python/tests/core/ecl/test_kw.py index e29562f32d..9e2c16a473 100644 --- a/ThirdParty/Ert/devel/python/tests/core/ecl/test_kw.py +++ b/ThirdParty/Ert/devel/python/tests/core/ecl/test_kw.py @@ -259,8 +259,16 @@ def test_sliced_set(self): self.assertEqual(kw[4] , 66) self.assertEqual(kw[5] , 99) + + def test_long_name(self): + with self.assertRaises(ValueError): + EclKW.create("LONGLONGNAME" , 10 , EclTypeEnum.ECL_INT_TYPE) + kw = EclKW.create("REGIONS" , 10 , EclTypeEnum.ECL_INT_TYPE) + with self.assertRaises(ValueError): + kw.set_name("LONGLONGNAME") + #def cutoff( x , arg ): # if x < arg: # return 0 diff --git a/ThirdParty/Ert/devel/python/tests/core/ecl/test_layer.py b/ThirdParty/Ert/devel/python/tests/core/ecl/test_layer.py index 713dac5a4f..26a176288f 100644 --- a/ThirdParty/Ert/devel/python/tests/core/ecl/test_layer.py +++ b/ThirdParty/Ert/devel/python/tests/core/ecl/test_layer.py @@ -259,7 +259,6 @@ def test_add_polyline_barrier(self): pl = CPolyline( init_points = [(0 , 0) , (d/2 , d/2) , (d,d)]) layer.addPolylineBarrier( pl , grid , 0) for i in range(d): - print i self.assertTrue( layer.bottomBarrier(i,i) ) if i < (d - 1): self.assertTrue( layer.leftBarrier(i+1,i) ) @@ -296,3 +295,12 @@ def test_assign(self): layer.assign(10) self.assertEqual( layer.cellSum() , 500 ) + + + def test_count_equal(self): + layer = Layer(10,10) + self.assertEqual( 100 , layer.countEqual( 0 )) + self.assertEqual( 0 , layer.countEqual( 1 )) + + layer[3,3] = 3 + self.assertEqual( 1 , layer.countEqual( 3 )) diff --git a/ThirdParty/Ert/devel/python/tests/core/util/CMakeLists.txt b/ThirdParty/Ert/devel/python/tests/core/util/CMakeLists.txt index 962c7bf8f8..99f023ad3f 100644 --- a/ThirdParty/Ert/devel/python/tests/core/util/CMakeLists.txt +++ b/ThirdParty/Ert/devel/python/tests/core/util/CMakeLists.txt @@ -10,10 +10,13 @@ set(TEST_SOURCES test_string_list.py test_substitution_list.py test_thread_pool.py + test_cthread_pool.py test_ui_return.py test_vectors.py test_version.py test_work_area.py + test_path_context.py + test_arg_pack.py ) add_python_package("python.tests.core.util" ${PYTHON_INSTALL_PREFIX}/tests/core/util "${TEST_SOURCES}" False) @@ -29,7 +32,11 @@ addPythonTest(core.util.tvector core.util.test_vectors.UtilTest) addPythonTest(core.util.ui_return core.util.test_ui_return.UIReturnTest) addPythonTest(core.util.work_area core.util.test_work_area.WorkAreaTest) addPythonTest(core.util.version core.util.test_version.VersionTest) +addPythonTest(core.util.path_context core.util.test_path_context.PathContextTest) +addPythonTest(core.util.thread_pool core.util.test_thread_pool.ThreadPoolTest) +addPythonTest(core.util.cthread_pool core.util.test_cthread_pool.CThreadPoolTest) +addPythonTest(core.util.arg_pack core.util.test_arg_pack.ArgPackTest) #add_test( NAME python.tests.ert.util.latex # WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} -# COMMAND ctest_run.py ${PROJECT_BINARY_DIR}/${PYTHON_INSTALL_PREFIX} core.util.test_latex.LatexTest ) \ No newline at end of file +# COMMAND ctest_run.py ${PROJECT_BINARY_DIR}/${PYTHON_INSTALL_PREFIX} core.util.test_latex.LatexTest ) diff --git a/ThirdParty/Ert/devel/python/tests/core/util/test_arg_pack.py b/ThirdParty/Ert/devel/python/tests/core/util/test_arg_pack.py new file mode 100644 index 0000000000..3c6c003c58 --- /dev/null +++ b/ThirdParty/Ert/devel/python/tests/core/util/test_arg_pack.py @@ -0,0 +1,39 @@ +import ctypes +from ert.cwrap import clib +from ert.util import ArgPack, StringList +from ert.test import ExtendedTestCase + +TEST_LIB = clib.ert_load("libtest_util") + +class ArgPackTest(ExtendedTestCase): + + def test_create(self): + arg = ArgPack() + self.assertEqual( len(arg) , 0 ) + + arg.append( StringList( ) ) + self.assertEqual( len(arg) , 1 ) + + arg.append(3.14) + self.assertEqual( len(arg) , 2 ) + + o = object() + with self.assertRaises(TypeError): + arg.append( o ) + + + def test_args(self): + arg = ArgPack(1,2,3) + self.assertEqual( len(arg) , 3) + + + def test_append_ptr(self): + arg = ArgPack( StringList() ) + self.assertEqual( len(arg) , 1) + + func = getattr( TEST_LIB , "test_argpack_is_stringlist" ) + func.restype = None + func.argtypes = [ ArgPack ] + + func( arg ) + diff --git a/ThirdParty/Ert/devel/python/tests/core/util/test_cthread_pool.py b/ThirdParty/Ert/devel/python/tests/core/util/test_cthread_pool.py new file mode 100644 index 0000000000..999aecfcd6 --- /dev/null +++ b/ThirdParty/Ert/devel/python/tests/core/util/test_cthread_pool.py @@ -0,0 +1,41 @@ +import time +import ctypes +from ert.cwrap import clib +from ert.util import CThreadPool , startCThreadPool +from ert.test import ExtendedTestCase + +TEST_LIB = clib.ert_load("libtest_util") + + +class CThreadPoolTest(ExtendedTestCase): + + def test_cfunc(self): + with self.assertRaises( TypeError ): + func = CThreadPool.lookupCFunction( "WRONG-TYPE" , "no-this-does-not-exist") + + with self.assertRaises( AttributeError ): + func = CThreadPool.lookupCFunction( TEST_LIB , "no-this-does-not-exist") + + + + def test_create(self): + pool = CThreadPool(32 , start = True) + job = CThreadPool.lookupCFunction( TEST_LIB , "thread_pool_test_func1") + arg = ctypes.c_int(0) + + N = 256 + for i in range(N): + pool.addTask( job , ctypes.byref( arg ) ) + pool.join() + self.assertEqual( arg.value , N ) + + + def test_context(self): + N = 256 + arg = ctypes.c_int(0) + job = CThreadPool.lookupCFunction( TEST_LIB , "thread_pool_test_func1") + with startCThreadPool( 16 ) as tp: + for i in range(N): + tp.addTask( job , ctypes.byref( arg ) ) + self.assertEqual( arg.value , N ) + diff --git a/ThirdParty/Ert/devel/python/tests/core/util/test_ctime.py b/ThirdParty/Ert/devel/python/tests/core/util/test_ctime.py index 380497efa8..70e48820f9 100644 --- a/ThirdParty/Ert/devel/python/tests/core/util/test_ctime.py +++ b/ThirdParty/Ert/devel/python/tests/core/util/test_ctime.py @@ -1,8 +1,13 @@ from datetime import datetime, date - +import time +from pytz import timezone from ert.util import CTime +def timezoneOffsetInSeconds(dt): + local_timezone = timezone(CTime.timezone()) + return int(local_timezone.utcoffset(dt).total_seconds()) + try: from unittest2 import TestCase except ImportError: @@ -11,13 +16,15 @@ class CTimeTest(TestCase): + def test_creation(self): - t0 = CTime(-60 * 60) + delta = timezoneOffsetInSeconds(datetime(1970, 1, 1)) + t0 = CTime(-delta) t1 = CTime(t0) self.assertEqual(t0, t1) - t2 = CTime(datetime(1970, 1, 1, 0)) + t2 = CTime(datetime(1970, 1, 1)) self.assertEqual(t0, t2) t3 = CTime(date(1970, 1, 1)) @@ -28,10 +35,13 @@ def test_creation(self): def test_c_time(self): - c_time = CTime(0) - self.assertEqual(str(c_time), "1970-01-01 01:00:00") + delta = timezoneOffsetInSeconds(datetime(1970, 1, 1)) + c_time = CTime(-delta) + py_time = datetime(1970, 1, 1) - date_time = CTime(datetime(1970, 1, 1, 1, 0, 0)) + self.assertEqual(str(c_time), py_time.strftime("%Y-%m-%d %H:%M:%S%z")) + + date_time = CTime(py_time) self.assertEqual(c_time, date_time) date_time_after = CTime(datetime(1970, 1, 1, 1, 0, 5)) @@ -127,3 +137,21 @@ def test_range(self): self.assertTrue(c0 <= c2 <= d2) self.assertTrue(dt0 <= c2 <= c2) + + + def test_conversion(self): + t = CTime(0) + + self.assertEqual(t.value(), 0) + self.assertEqual(t.ctime(), 0) + self.assertEqual(t.time(), time.localtime(0)) + + # These conversions depend on timezone + utc = timezone('utc') + local_timezone = timezone(CTime.timezone()) + + localized_dt = local_timezone.localize(t.datetime()) + self.assertEqual(localized_dt.astimezone(utc), datetime(1970, 1, 1, 0, tzinfo=utc)) + + localized_d = datetime(1970, 1, 1, 0, tzinfo=utc).astimezone(local_timezone) + self.assertEqual(t.date(), localized_d.date()) diff --git a/ThirdParty/Ert/devel/python/tests/core/util/test_path_context.py b/ThirdParty/Ert/devel/python/tests/core/util/test_path_context.py new file mode 100644 index 0000000000..06cb537574 --- /dev/null +++ b/ThirdParty/Ert/devel/python/tests/core/util/test_path_context.py @@ -0,0 +1,40 @@ +import os +from ert.test import ExtendedTestCase, PathContext,TestAreaContext + + +class PathContextTest(ExtendedTestCase): + def test_error(self): + with self.assertRaises(OSError): + with PathContext("/usr/lib/testing"): + pass + + with open("/tmp/file" , "w") as f: + f.write("xx") + + with self.assertRaises(OSError): + with PathContext("/tmp/file"): + pass + + + def test_chdir(self): + with PathContext("/tmp/pc"): + self.assertEqual( os.getcwd() , "/tmp/pc") + + + def test_cleanup(self): + with TestAreaContext("pathcontext"): + os.makedirs("path/1") + + with self.assertRaises(OSError): + with PathContext("path/1"): + pass + + with PathContext("path/1/next/2/level"): + with open("../../file" , "w") as f: + f.write("Crap") + + self.assertTrue(os.path.isdir("path/1")) + self.assertTrue(os.path.isdir("path/1/next")) + self.assertFalse(os.path.isdir("path/1/next/2")) + + diff --git a/ThirdParty/Ert/devel/python/tests/core/util/test_string_list.py b/ThirdParty/Ert/devel/python/tests/core/util/test_string_list.py index 95796c1e27..c8d8947fc6 100644 --- a/ThirdParty/Ert/devel/python/tests/core/util/test_string_list.py +++ b/ThirdParty/Ert/devel/python/tests/core/util/test_string_list.py @@ -74,10 +74,16 @@ def test_in_and_not_in(self): self.assertTrue("Bjarne" not in s) def test_append(self): - s = StringList(["A", "B"]) - s.append("C") - self.assertEqual(list(s), ["A", "B", "C"]) + s1 = StringList(["A", "B"]) + s1.append("C") + s2 = StringList(["A","B","C"]) + self.assertEqual(s1, ["A", "B", "C"]) + self.assertEqual(s1, s2) + self.assertFalse(s1 == ["A","B","D"]) + self.assertFalse(s1 == ["A","B","C" , "D"]) + + def test_append_not_string(self): s = StringList() s.append(10) diff --git a/ThirdParty/Ert/devel/python/tests/core/util/test_vectors.py b/ThirdParty/Ert/devel/python/tests/core/util/test_vectors.py index 7762b9827f..10a1faaa68 100644 --- a/ThirdParty/Ert/devel/python/tests/core/util/test_vectors.py +++ b/ThirdParty/Ert/devel/python/tests/core/util/test_vectors.py @@ -128,7 +128,16 @@ def test_activeList(self): active_list = IntVector.active_list("1,10,100-105X") self.assertFalse(active_list) + + def test_value_list(self): + list2 = IntVector.valueList("3,10-12,0,1") + self.assertTrue( len(list2) == 6 ) + expected = [3,10,11,12,0,1] + for v1,v2 in zip(list2,expected): + self.assertEqual( v1 , v2) + + def test_contains_int(self): iv = IntVector() diff --git a/ThirdParty/Ert/devel/python/tests/ctest_run.py b/ThirdParty/Ert/devel/python/tests/ctest_run.py index ceeafa47bf..1ab2bb37a6 100644 --- a/ThirdParty/Ert/devel/python/tests/ctest_run.py +++ b/ThirdParty/Ert/devel/python/tests/ctest_run.py @@ -1,4 +1,5 @@ #!/usr/bin/env python +import os import sys try: @@ -7,27 +8,21 @@ from unittest import TextTestRunner -def runTestCase(tests): - test_result = TextTestRunner(verbosity=0).run(tests) - if test_result.errors or test_result.failures: - for (test, trace_back) in test_result.errors: - sys.stderr.write("=================================================================\n") - sys.stderr.write("Test:%s error \n" % test.id()) - sys.stderr.write("%s\n" % trace_back) - - for (test, trace_back) in test_result.failures: - sys.stderr.write("=================================================================\n") - sys.stderr.write("Test:%s failure \n" % test.id()) - sys.stderr.write("%s\n" % trace_back) +def runTestCase(tests, verbosity=0): + test_result = TextTestRunner(verbosity=verbosity).run(tests) + if len(test_result.errors) or len(test_result.failures): + test_result.printErrors() return False else: return True if __name__ == '__main__': - PYTHONPATH = sys.argv[1] - sys.path.insert(0, PYTHONPATH) + TEST_PYTHONPATH = sys.argv[1] + os.environ["PYTHONPATH"] = TEST_PYTHONPATH + os.pathsep + os.getenv("PYTHONPATH", "") + for path_element in reversed(TEST_PYTHONPATH.split(os.pathsep)): + sys.path.insert(0, path_element) test_class_path = sys.argv[2] argv = [] @@ -38,9 +33,11 @@ def runTestCase(tests): pass from ert.test import ErtTestRunner + tests = ErtTestRunner.getTestsFromTestClass(test_class_path, argv) - if runTestCase(tests): + # Set verbosity to 2 to see which test method in a class that fails. + if runTestCase(tests, verbosity=0): sys.exit(0) else: sys.exit(1) diff --git a/ThirdParty/Ert/devel/python/tests/ert/config/test_config.py b/ThirdParty/Ert/devel/python/tests/ert/config/test_config.py index a348289dc7..80cf5f389b 100644 --- a/ThirdParty/Ert/devel/python/tests/ert/config/test_config.py +++ b/ThirdParty/Ert/devel/python/tests/ert/config/test_config.py @@ -14,6 +14,7 @@ # # See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> # for more details. +import os from ert.config import ContentTypeEnum, UnrecognizedEnum, SchemaItem, ContentItem, ContentNode, ConfigParser, ConfigContent from ert.test import ExtendedTestCase, TestAreaContext @@ -123,12 +124,16 @@ def test_parser_content(self): schema_item.iset_type(2 , ContentTypeEnum.CONFIG_INT ) schema_item.iset_type(3 , ContentTypeEnum.CONFIG_BOOL ) schema_item.iset_type(4 , ContentTypeEnum.CONFIG_FLOAT ) - + schema_item.iset_type(5 , ContentTypeEnum.CONFIG_PATH ) + with TestAreaContext("config/parse2"): with open("config","w") as fileH: - fileH.write("KEY VALUE1 VALUE2 100 True 3.14\n") - - content = conf.parse("config") + fileH.write("KEY VALUE1 VALUE2 100 True 3.14 path/file.txt\n") + + cwd0 = os.getcwd( ) + os.makedirs("tmp") + os.chdir("tmp") + content = conf.parse("../config") self.assertTrue( content.isValid() ) self.assertTrue( "KEY" in content ) self.assertFalse( "NOKEY" in content ) @@ -139,11 +144,30 @@ def test_parser_content(self): item = content["KEY"] self.assertEqual(len(item) , 1) + line = item[0] + with self.assertRaises(TypeError): + line.getPath(4) + + with self.assertRaises(TypeError): + line.getPath() + + + rel_path = line.getPath(index = 5, absolute = False) + self.assertEqual( rel_path , "../path/file.txt" ) + get = line[5] + self.assertEqual( get , "../path/file.txt") + abs_path = line.getPath(index = 5) + self.assertEqual( abs_path , os.path.join(cwd0 , "path/file.txt")) + + rel_path = line.getPath(index = 5, absolute = False , relative_start = "../") + self.assertEqual( rel_path , "path/file.txt" ) + + with self.assertRaises(IndexError): item[10] node = item[0] - self.assertEqual(len(node) , 5) + self.assertEqual(len(node) , 6) with self.assertRaises(IndexError): node[6] @@ -152,7 +176,7 @@ def test_parser_content(self): self.assertEqual( node[2] , 100 ) self.assertEqual( node[3] , True ) self.assertEqual( node[4] , 3.14) - + self.assertEqual( content.getValue( "KEY" , 0 , 1 ) , "VALUE2" ) self.assertEqual( content.cNamespace().iget( content , "KEY" , 0 , 1) , "VALUE2") @@ -171,7 +195,7 @@ def test_parser_content(self): self.assertEqual( content.cNamespace().get_occurences( content , "KEY" ) , 1) self.assertEqual( content.cNamespace().get_occurences( content , "MISSING-KEY" ) , 0) - + def test_schema(self): schema_item = SchemaItem("TestItem") diff --git a/ThirdParty/Ert/devel/python/tests/ert/enkf/CMakeLists.txt b/ThirdParty/Ert/devel/python/tests/ert/enkf/CMakeLists.txt index 2fe35a5ac7..7784525f43 100644 --- a/ThirdParty/Ert/devel/python/tests/ert/enkf/CMakeLists.txt +++ b/ThirdParty/Ert/devel/python/tests/ert/enkf/CMakeLists.txt @@ -19,6 +19,7 @@ set(TEST_SOURCES test_labscale.py test_linalg.py test_local_obsdata_node.py + test_local_config.py test_meas_block.py test_meas_data.py test_obs_block.py @@ -32,12 +33,14 @@ set(TEST_SOURCES test_time_map.py test_update.py test_ensemble_config.py + test_deprecation.py ) add_python_package("python.tests.ert.enkf" ${PYTHON_INSTALL_PREFIX}/tests/ert/enkf "${TEST_SOURCES}" False) addPythonTest(ert.enkf.enkf tests.ert.enkf.test_enkf.EnKFTest LABELS StatoilData) addPythonTest(ert.enkf.enkf_obs tests.ert.enkf.test_enkf_obs.EnKFObsTest LABELS StatoilData) +addPythonTest(ert.enkf.deprecation tests.ert.enkf.test_deprecation.DeprecationTest) addPythonTest(ert.enkf.meas_block tests.ert.enkf.test_meas_block.MeasBlockTest) addPythonTest(ert.enkf.meas_data tests.ert.enkf.test_meas_data.MeasDataTest) addPythonTest(ert.enkf.obs_data tests.ert.enkf.test_obs_data.ObsDataTest) @@ -66,6 +69,7 @@ addPythonTest(ert.enkf.update tests.ert.enkf.test_update.UpdateTest LABELS Stato addPythonTest(ert.enkf.labscale tests.ert.enkf.test_labscale.LabScaleTest LABELS StatoilData) addPythonTest(ert.enkf.active_list tests.ert.enkf.test_active_list.ActiveListTest) addPythonTest(ert.enkf.local_obsdata_node tests.ert.enkf.test_local_obsdata_node.LocalObsdataNodeTest) +addPythonTest(ert.enkf.local_config tests.ert.enkf.test_local_config.LocalConfigTest) addPythonTest(ert.enkf.ensemble_config tests.ert.enkf.test_ensemble_config.EnsembleConfigTest) add_subdirectory(data) diff --git a/ThirdParty/Ert/devel/python/tests/ert/enkf/export/test_numpy_and_pandas.py b/ThirdParty/Ert/devel/python/tests/ert/enkf/export/test_numpy_and_pandas.py index f83ddfcfcb..e3763467ff 100644 --- a/ThirdParty/Ert/devel/python/tests/ert/enkf/export/test_numpy_and_pandas.py +++ b/ThirdParty/Ert/devel/python/tests/ert/enkf/export/test_numpy_and_pandas.py @@ -1,5 +1,6 @@ import numpy -from pandas import MultiIndex, DataFrame, pandas +from pandas import MultiIndex, DataFrame +import pandas as pandas from ert.test import ExtendedTestCase diff --git a/ThirdParty/Ert/devel/python/tests/ert/enkf/test_deprecation.py b/ThirdParty/Ert/devel/python/tests/ert/enkf/test_deprecation.py new file mode 100644 index 0000000000..3a09b9f5e5 --- /dev/null +++ b/ThirdParty/Ert/devel/python/tests/ert/enkf/test_deprecation.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python +# Copyright (C) 2011 Statoil ASA, Norway. +# +# The file 'test_deprecation.py' is part of ERT - Ensemble based Reservoir Tool. +# +# ERT is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# ERT is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. +# +# See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> +# for more details. +import warnings + +from ert.test import ErtTestContext, ExtendedTestCase + + +class DeprecationTest(ExtendedTestCase): + def setUp(self): + self.config_file = self.createTestPath("local/simple_config/minimum_config") + self.obs_file = self.createTestPath("local/simple_config/minimum_config") + + + # Added in 1.10 development + def test(self): + with ErtTestContext("enkf_deprecation", self.config_file) as test_context: + ert = test_context.getErt() + + ecl_config = ert.eclConfig() + with warnings.catch_warnings(): + ecl_config.get_grid( ) + + diff --git a/ThirdParty/Ert/devel/python/tests/ert/enkf/test_enkf_obs.py b/ThirdParty/Ert/devel/python/tests/ert/enkf/test_enkf_obs.py index f647aadc1f..6d579e4c9b 100644 --- a/ThirdParty/Ert/devel/python/tests/ert/enkf/test_enkf_obs.py +++ b/ThirdParty/Ert/devel/python/tests/ert/enkf/test_enkf_obs.py @@ -6,7 +6,8 @@ from ert.util import BoolVector,IntVector from ert.enkf import ActiveMode, EnsembleConfig -from ert.enkf import ObsVector , LocalObsdata, EnkfObs, TimeMap +from ert.enkf.enums import EnkfStateType +from ert.enkf import ObsVector , LocalObsdata, EnkfObs, TimeMap, LocalObsdataNode , ObsData , MeasData, ActiveList class EnKFObsTest(ExtendedTestCase): @@ -17,13 +18,78 @@ def setUp(self): self.refcase = self.createTestPath("Statoil/config/obs_testing/EXAMPLE_01_BASE") self.grid = self.createTestPath("Statoil/config/obs_testing/EXAMPLE_01_BASE.EGRID") + + def test_scale_obs(self): + with ErtTestContext("obs_test", self.config_file) as test_context: + ert = test_context.getErt() + obs = ert.getObservations() + + obs1 = obs["WWCT:OP_1"].getNode( 50 ) + obs2 = obs["WWCT:OP_1_50"].getNode( 50 ) + + self.assertEqual( obs1.getStandardDeviation( ) , obs2.getStandardDeviation( )) + std0 = obs1.getStandardDeviation( ) + + local_obsdata = LocalObsdata("obs" , obs) + node1 = LocalObsdataNode( "WWCT:OP_1" ) + node1.addRange( 50 , 50 ) + node2 = LocalObsdataNode( "WWCT:OP_1_50" ) + node2.addRange( 50 , 50 ) + local_obsdata.addNode( node1 ) + local_obsdata.addNode( node2 ) + + mask = BoolVector( default_value = True ) + mask[2] = True + meas_data = MeasData(mask) + obs_data = ObsData( ) + fs = ert.getEnkfFsManager().getCurrentFileSystem() + active_list = IntVector() + active_list.initRange(0,2,1) + obs.getObservationAndMeasureData( fs , local_obsdata , EnkfStateType.FORECAST , active_list , meas_data , obs_data ) + self.assertEqual( 2 , len(obs_data) ) + + v1 = obs_data[0] + v2 = obs_data[1] + + self.assertEqual( v1[1] , std0 ) + self.assertEqual( v2[1] , std0 ) + + meas_data = MeasData(mask) + obs_data = ObsData( 10 ) + obs.getObservationAndMeasureData( fs , local_obsdata , EnkfStateType.FORECAST , active_list , meas_data , obs_data ) + self.assertEqual( 2 , len(obs_data) ) + + v1 = obs_data[0] + v2 = obs_data[1] + + self.assertEqual( v1[1] , std0*10) + self.assertEqual( v2[1] , std0*10 ) + + actl = ActiveList() + obs1.updateStdScaling( 10 , actl) + obs2.updateStdScaling( 20 , actl) + meas_data = MeasData(mask) + obs_data = ObsData( ) + obs.getObservationAndMeasureData( fs , local_obsdata , EnkfStateType.FORECAST , active_list , meas_data , obs_data ) + self.assertEqual( 2 , len(obs_data) ) + + v1 = obs_data[0] + v2 = obs_data[1] + + self.assertEqual( v1[1] , std0*10) + self.assertEqual( v2[1] , std0*20) + + + + + def testObs(self): with ErtTestContext("obs_test", self.config_file) as test_context: ert = test_context.getErt() obs = ert.getObservations() - self.assertEqual(31, len(obs)) + self.assertEqual(32, len(obs)) for v in obs: self.assertTrue(isinstance(v, ObsVector)) @@ -59,7 +125,7 @@ def test_obs_block_scale_std(self): active_list.initRange(0 , ert.getEnsembleSize() , 1 ) obs = ert.getObservations() - obs_data = LocalObsdata( "OBSxx" ) + obs_data = LocalObsdata( "OBSxx" , obs ) obs_vector = obs["WWCT:OP_1"] obs_data.addObsVector( obs_vector ) scale_factor = obs.scaleCorrelatedStd( fs , obs_data , active_list ) @@ -111,15 +177,15 @@ def test_create(self): obs.load("/does/not/exist") self.assertTrue( obs.load(self.obs_config) ) - self.assertEqual( len(obs) , 32 ) + self.assertEqual( len(obs) , 33 ) obs.clear() self.assertEqual( len(obs) , 0 ) obs.load(self.obs_config) - self.assertEqual( len(obs) , 32 ) + self.assertEqual( len(obs) , 33 ) self.assertFalse( "RFT2" in obs ) obs.load(self.obs_config2) - self.assertEqual( len(obs) , 33 ) + self.assertEqual( len(obs) , 35 ) self.assertTrue( "RFT2" in obs ) @@ -127,11 +193,30 @@ def test_create(self): def test_ert_obs_reload(self): with ErtTestContext("obs_test_reload", self.config_file) as test_context: ert = test_context.getErt() + ens_config = ert.ensembleConfig( ) + wwct_op1 = ens_config["WWCT:OP_1"] + wopr_op5 = ens_config["WOPR:OP_5"] + obs = ert.getObservations() - self.assertEqual( len(obs) , 31 ) - ert.loadObservations("observations2") - self.assertEqual( len(obs) , 1 ) - - ert.loadObservations("observations" , clear = False) self.assertEqual( len(obs) , 32 ) + + keys = wwct_op1.getObservationKeys() + self.assertEqual( len(keys) , 2 ) + self.assertTrue( "WWCT:OP_1" in keys ) + self.assertTrue( "WWCT:OP_1_50" in keys ) + + self.assertEqual( wopr_op5.getObservationKeys() , [] ) + ert.loadObservations("observations2") + self.assertEqual( len(obs) , 2 ) + self.assertEqual( wwct_op1.getObservationKeys() , [] ) + self.assertEqual( wopr_op5.getObservationKeys() , ["WOPR:OP_5"] ) + + ert.loadObservations("observations" , clear = False) + self.assertEqual( len(obs) , 34 ) + keys = wwct_op1.getObservationKeys() + self.assertEqual( len(keys) , 2 ) + self.assertTrue( "WWCT:OP_1" in keys ) + self.assertTrue( "WWCT:OP_1_50" in keys ) + + self.assertEqual( wopr_op5.getObservationKeys() , ["WOPR:OP_5"] ) diff --git a/ThirdParty/Ert/devel/python/tests/ert/enkf/test_local_config.py b/ThirdParty/Ert/devel/python/tests/ert/enkf/test_local_config.py new file mode 100644 index 0000000000..d1805c369e --- /dev/null +++ b/ThirdParty/Ert/devel/python/tests/ert/enkf/test_local_config.py @@ -0,0 +1,163 @@ +import os.path +from ert.ecl import EclGrid + +from ert.test import ExtendedTestCase +from ert.test import ErtTestContext +from ert.enkf.local_ministep import LocalMinistep +from ert.enkf.active_list import ActiveList +from ert.enkf.local_obsdata import LocalObsdata +from ert.enkf.local_updatestep import LocalUpdateStep +from ert.enkf.local_obsdata_node import LocalObsdataNode +from ert.enkf import local_config + +class LocalConfigTest(ExtendedTestCase): + + def setUp(self): + + self.config = self.createTestPath("local/custom_kw/mini_config") + + def testLocalConfig(self): + + with ErtTestContext("python/enkf/data/local_config", self.config) as test_context: + + main = test_context.getErt() + self.assertTrue(main, "Load failed") + + local_config = main.getLocalConfig() + self.AllActive(local_config) + + self.MiniStep(local_config) + + self.AttachMinistep(local_config) + + self.LocalDataset(local_config) + + self.LocalObsdata(local_config) + + sfile = "local_config.txt" + local_config.writeLocalConfigFile( sfile ) + self.assertTrue( os.path.isfile( sfile )) + + self.clear(local_config) + + grid = local_config.getGrid() + self.assertTrue( isinstance( grid , EclGrid )) + + + def clear(self, local_config): + local_config.clear() + updateStep = local_config.getUpdatestep( ) + self.assertEqual( len(updateStep) , 0 ) + + + + def AllActive(self , local_config): + updateStep = local_config.getUpdatestep( ) + ministep = updateStep[0] + self.assertEqual( 1 , len(ministep) ) + dataset = ministep["ALL_DATA"] + + self.assertTrue( "PERLIN_PARAM" in dataset ) + self.assertTrue( "PERLIN" in dataset ) + + obsdata = ministep.getLocalObsData() + self.assertEqual( len(obsdata) , 3 ) + + + def MiniStep( self, local_config ): + + # Ministep + ministep = local_config.createMinistep("MINISTEP") + self.assertTrue(isinstance(ministep, LocalMinistep)) + + self.assertFalse( "DATA" in ministep ) + with self.assertRaises(KeyError): + ministep["DATA"] + + + def AttachMinistep( self, local_config): + + # Update step + updatestep = local_config.getUpdatestep( ) + self.assertTrue(isinstance(updatestep, LocalUpdateStep)) + n1 = len(updatestep) + + # Ministep + ministep = local_config.createMinistep("MINISTEP") + self.assertTrue(isinstance(ministep, LocalMinistep)) + + # Attach + updatestep.attachMinistep(ministep) + self.assertTrue(isinstance(updatestep[0], LocalMinistep)) + + self.assertEqual( len(updatestep) , n1 + 1 ) + + + def LocalDataset( self, local_config ): + # Data + data_scale = local_config.createDataset("DATA_SCALE") + with self.assertRaises(KeyError): + data_scale.addNode("MISSING") + + data_scale.addNode("PERLIN_PARAM") + active_list = data_scale.getActiveList("PERLIN_PARAM") + self.assertTrue(isinstance(active_list, ActiveList)) + active_list.addActiveIndex(0) + + self.assertTrue("PERLIN_PARAM" in data_scale) + self.assertFalse("MISSING" in data_scale) + + ministep = local_config.createMinistep("MINISTEP") + ministep.attachDataset( data_scale ) + self.assertTrue( "DATA_SCALE" in ministep ) + data_scale_get = ministep["DATA_SCALE"] + self.assertTrue( "PERLIN_PARAM" in data_scale_get ) + + + + + def LocalObsdata( self, local_config ): + + + # Creating + local_obs_data_1 = local_config.createObsdata("OBSSET_1") + self.assertTrue(isinstance(local_obs_data_1, LocalObsdata)) + + with self.assertRaises(KeyError): + local_obs_data_1.addNodeAndRange("MISSING_KEY" , 0 , 1 ) + + local_obs_data_1.addNodeAndRange("GEN_PERLIN_1", 0, 1) + local_obs_data_1.addNodeAndRange("GEN_PERLIN_2", 0, 1) + + self.assertEqual( len(local_obs_data_1) , 2 ) + + # Delete node + del local_obs_data_1["GEN_PERLIN_1"] + self.assertEqual( len(local_obs_data_1) , 1 ) + + # Get node + node = local_obs_data_1["GEN_PERLIN_2"] + self.assertTrue(isinstance(node, LocalObsdataNode)) + + + + def AttachObsData( self , local_config): + + local_obs_data_1 = local_config.createObsdata("OBSSET_1") + self.assertTrue(isinstance(local_obs_data_1, LocalObsdata)) + + # Obsdata + local_obs_data_1.addNodeAndRange("GEN_PERLIN_1", 0, 1) + local_obs_data_1.addNodeAndRange("GEN_PERLIN_2", 0, 1) + + # Ministep + ministep = local_config.createMinistep("MINISTEP") + self.assertTrue(isinstance(ministep, LocalMinistep)) + + # Attach obsset + ministep.attachObsset(local_obs_data_1) + + # Retrieve attached obsset + local_obs_data_new = ministep.getLocalObsData() + self.assertEqual( len(local_obs_data_new) , 2 ) + diff --git a/ThirdParty/Ert/devel/python/tests/ert/enkf/test_obs_data.py b/ThirdParty/Ert/devel/python/tests/ert/enkf/test_obs_data.py index 85dc2ff6f7..d5136a6e53 100644 --- a/ThirdParty/Ert/devel/python/tests/ert/enkf/test_obs_data.py +++ b/ThirdParty/Ert/devel/python/tests/ert/enkf/test_obs_data.py @@ -33,7 +33,17 @@ def test_create(self): R = obs_data.createR() self.assertEqual( (2,2) , R.dims() ) - - + with self.assertRaises(IndexError): + obs_data[10] + + v,s = obs_data[0] + self.assertEqual( v , 10 ) + self.assertEqual( s , 10 ) + + + v,s = obs_data[1] + self.assertEqual( v , 12 ) + self.assertEqual( s , 12 ) + diff --git a/ThirdParty/Ert/devel/python/tests/ert/enkf/test_run_arg.py b/ThirdParty/Ert/devel/python/tests/ert/enkf/test_run_arg.py index b4e234f79f..8f5f00fbf3 100644 --- a/ThirdParty/Ert/devel/python/tests/ert/enkf/test_run_arg.py +++ b/ThirdParty/Ert/devel/python/tests/ert/enkf/test_run_arg.py @@ -19,11 +19,14 @@ from ert.enkf import RunArg from ert.enkf.enums import EnkfRunType from ert.test import ExtendedTestCase - +from ert.util import ArgPack class RunArgTest(ExtendedTestCase): def test_create(self): run_arg = RunArg.ENSEMBLE_EXPERIMENT(fs , 10 , 10 , "/path/to/run") + arg_pack = ArgPack( run_arg , 10 ) + + self.assertFalse( run_arg.isSubmitted( ) ) diff --git a/ThirdParty/Ert/devel/python/tests/ert/sched/test_sched.py b/ThirdParty/Ert/devel/python/tests/ert/sched/test_sched.py index e5bd6a9d0c..9e803d1073 100644 --- a/ThirdParty/Ert/devel/python/tests/ert/sched/test_sched.py +++ b/ThirdParty/Ert/devel/python/tests/ert/sched/test_sched.py @@ -30,13 +30,18 @@ def setUp(self): self.sched_file = SchedFile(src_file, self.start_time) self.file_list = [] + def test_missing(self): + with self.assertRaises(IOError): + SchedFile("/does/not/exist", datetime.date(2000 , 1 , 1)) + + def addFile( self, filename ): self.file_list.append(filename) def tearDown(self): for f in self.file_list: if os.path.exists(f): - os.unlink(f) + os.unlink(f) def test_load(self): self.assertTrue(self.sched_file, "Load failed") diff --git a/ThirdParty/Ert/devel/python/tests/ert/server/test_socket.py b/ThirdParty/Ert/devel/python/tests/ert/server/test_socket.py index 0cc865d40e..1e9ebdfc29 100644 --- a/ThirdParty/Ert/devel/python/tests/ert/server/test_socket.py +++ b/ThirdParty/Ert/devel/python/tests/ert/server/test_socket.py @@ -95,12 +95,25 @@ def test_connect(self): self.runCommand( ["MISSING_COMMAND"] , port ) self.runCommand( ["QUIT"] , port , expected = ["QUIT"] ) - - # Server is closed - with self.assertRaises(Exception): - self.runCommand( ["STATUS"] , port ) + start_time = time.time() + exception_raised = False + while True: + try: + self.runCommand( ["STATUS"] , port ) + time.sleep( 1 ) + except Exception: + exception_raised = True + break + + if time.time() - start_time > 10: + break + + if not exception_raised: + raise Exception("Expected exception when connecting to closed server") + + def test_time_map(self): port = self.base_port + 1 diff --git a/ThirdParty/Ert/devel/python/tests/gui/CMakeLists.txt b/ThirdParty/Ert/devel/python/tests/gui/CMakeLists.txt index 61c7dfc1da..3895f93989 100644 --- a/ThirdParty/Ert/devel/python/tests/gui/CMakeLists.txt +++ b/ThirdParty/Ert/devel/python/tests/gui/CMakeLists.txt @@ -11,5 +11,5 @@ addPythonTest(gui.observable tests.gui.test_observable.ObservableTest) add_subdirectory(ertshell) add_subdirectory(ide) -add_subdirectory(plot) + diff --git a/ThirdParty/Ert/devel/python/tests/gui/plot/CMakeLists.txt b/ThirdParty/Ert/devel/python/tests/gui/plot/CMakeLists.txt deleted file mode 100644 index dc5af18069..0000000000 --- a/ThirdParty/Ert/devel/python/tests/gui/plot/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -set(TEST_SOURCES - __init__.py - test_plot_metrics_tracker.py -) - -add_python_package("python.tests.gui.plot" ${PYTHON_INSTALL_PREFIX}/tests/gui/plot "${TEST_SOURCES}" False) - -addPythonTest(gui.plot.plot_metrics_tracker tests.gui.plot.test_plot_metrics_tracker.PlotMetricTrackerTest) \ No newline at end of file diff --git a/ThirdParty/Ert/devel/python/tests/gui/plot/__init__.py b/ThirdParty/Ert/devel/python/tests/gui/plot/__init__.py deleted file mode 100644 index 284bf2e772..0000000000 --- a/ThirdParty/Ert/devel/python/tests/gui/plot/__init__.py +++ /dev/null @@ -1 +0,0 @@ -__author__ = 'jpb' diff --git a/ThirdParty/Ert/devel/python/tests/gui/plot/test_plot_metrics_tracker.py b/ThirdParty/Ert/devel/python/tests/gui/plot/test_plot_metrics_tracker.py deleted file mode 100644 index 845dbb5d64..0000000000 --- a/ThirdParty/Ert/devel/python/tests/gui/plot/test_plot_metrics_tracker.py +++ /dev/null @@ -1,60 +0,0 @@ -from ert.test.extended_testcase import ExtendedTestCase -from ert_gui.tools.plot.plot_metrics_tracker import PlotMetricsTracker - - -class PlotMetricTrackerTest(ExtendedTestCase): - - def test_creation(self): - pmt = PlotMetricsTracker() - - self.assertIsNone(pmt.getType(None)) - - with self.assertRaises(KeyError): - pmt.getType("type") - - - self.assertIsNone(pmt.getDataTypeKey()) - - pmt.setDataTypeKey("test data type") - self.assertEqual(pmt.getDataTypeKey(), "test data type") - - - - def test_scale_types(self): - pmt = PlotMetricsTracker() - - pmt.addScaleType("index", int) - self.assertEqual(pmt.getType("index"), int) - - pmt.addScaleType("value", float) - self.assertEqual(pmt.getType("value"), float) - - - with self.assertRaises(KeyError): - pmt.getScalesForType("index") - - - pmt.setDataTypeKey("TestData1") - self.assertEqual(pmt.getScalesForType("index"), (None, None)) - self.assertEqual(pmt.getScalesForType("value"), (None, None)) - - pmt.setDataTypeKey("TestData2") - self.assertEqual(pmt.getScalesForType("index"), (None, None)) - self.assertEqual(pmt.getScalesForType("value"), (None, None)) - - pmt.setScalesForType("index", 1, 2) - pmt.setScalesForType("value", 1.5, 2.9) - self.assertEqual(pmt.getScalesForType("index"), (1, 2)) - self.assertEqual(pmt.getScalesForType("value"), (1.5, 2.9)) - - pmt.setDataTypeKey("TestData1") - self.assertEqual(pmt.getScalesForType("index"), (None, None)) - self.assertEqual(pmt.getScalesForType("value"), (None, None)) - - pmt.setScalesForType("index", 10, 20) - pmt.setScalesForType("value", 2.5, 3.9) - self.assertEqual(pmt.getScalesForType("index"), (10, 20)) - self.assertEqual(pmt.getScalesForType("value"), (2.5, 3.9)) - - with self.assertRaises(KeyError): - pmt.setScalesForType("time", 99, 999) diff --git a/ThirdParty/Ert/devel/python/tests/share/CMakeLists.txt b/ThirdParty/Ert/devel/python/tests/share/CMakeLists.txt new file mode 100644 index 0000000000..572d5d0c4e --- /dev/null +++ b/ThirdParty/Ert/devel/python/tests/share/CMakeLists.txt @@ -0,0 +1,8 @@ +set(TEST_SOURCES + __init__.py + test_synthesizer.py +) + +add_python_package("python.tests.share" ${PYTHON_INSTALL_PREFIX}/tests/share "${TEST_SOURCES}" False) + +addPythonTest(share.synthesizer share.test_synthesizer.SynthesizerTest) \ No newline at end of file diff --git a/ThirdParty/Ert/devel/python/tests/share/__init__.py b/ThirdParty/Ert/devel/python/tests/share/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/ThirdParty/Ert/devel/python/tests/share/test_synthesizer.py b/ThirdParty/Ert/devel/python/tests/share/test_synthesizer.py new file mode 100644 index 0000000000..805d0d3ba9 --- /dev/null +++ b/ThirdParty/Ert/devel/python/tests/share/test_synthesizer.py @@ -0,0 +1,46 @@ +import sys +import os +from ert.test import ExtendedTestCase + +try: + from synthesizer import OilSimulator +except ImportError as e: + share_lib_path = os.path.join(ExtendedTestCase.findShareRoot(), "lib") + + sys.path.insert(0, share_lib_path) + synthesizer_module = __import__("synthesizer") + OilSimulator = synthesizer_module.OilSimulator + sys.path.pop(0) + + +class SynthesizerTest(ExtendedTestCase): + + def test_oil_simulator(self): + sim = OilSimulator() + sim.addWell("OP1", seed=1) + sim.addBlock("6,6,6", seed=2) + + expected_values = [ + [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0], + [0.3359771423145687, 0.3359771423145687, 0.25672494192349865, 0.25672494192349865, 0.010039005455891323, 0.010039005455891323, 0.029013112597713192, 0.7641143089523995, 0.3359771423145687, 0.25672494192349865, 0.010039005455891323, 0.7641143089523995, 0.029013112597713192, 0.8462347957619747], + [0.7252470407619624, 1.0612241830765312, 0.5175173529594699, 0.7742422948829686, 0.017973831236885583, 0.028012836692776905, 0.02418370085402209, 0.7135738912023045, 0.7252470407619624, 0.5175173529594699, 0.017973831236885583, 0.7135738912023045, 0.02418370085402209, 0.6888364145396828], + [0.7723163496234255, 1.8335405326999568, 0.5742386073607806, 1.3484809022437492, 0.11041673583737899, 0.1384295725301559, 0.12508507685507134, 0.7435277106858791, 0.7723163496234255, 0.5742386073607806, 0.11041673583737899, 0.7435277106858791, 0.12508507685507134, 0.6403046565762696], + [0.6038799675664164, 2.437420500266373, 0.6888868738548185, 2.037367776098568, 0.267892132439122, 0.4063217049692779, 0.3072960610203287, 1.140767885762087, 0.6038799675664164, 0.6888868738548185, 0.267892132439122, 1.140767885762087, 0.3072960610203287, 0.5205364945011657], + [0.23016535126253962, 2.6675858515289126, 0.721655666522216, 2.7590234426207836, 0.35552466124555465, 0.7618463662148325, 0.6070184801736589, 3.135379250454838, 0.23016535126253962, 0.721655666522216, 0.35552466124555465, 3.135379250454838, 0.6070184801736589, 0.4800677649914682], + [0.026293782934652718, 2.693879634463565, 0.7131990780527108, 3.4722225206734945, 0.6392372725163122, 1.4010836387311447, 0.8647254356377257, 7.131990780527107, 0.026293782934652718, 0.7131990780527108, 0.6392372725163122, 7.131990780527107, 0.8647254356377257, 0.3872974839053025], + [0.0, 2.693879634463565, 0.8676997908824122, 4.339922311555907, 0.8580356376693129, 2.2591192764004577, 0.8956197493411856, 8.676997908824122, 0.0, 0.8676997908824122, 0.8580356376693129, 8.676997908824122, 0.8956197493411856, 0.22557165737149715], + [0.10560669451549878, 2.799486328979064, 0.869082212788759, 5.209004524344666, 0.8903674796589355, 3.1494867560593933, 0.8939664328113363, 8.229423492288294, 0.10560669451549878, 0.869082212788759, 0.8903674796589355, 8.229423492288294, 0.8939664328113363, 0.1340241573819292], + [0.08615885630000791, 2.885645185279072, 0.44074890315982446, 5.64975342750449, 0.9425699260811738, 4.0920566821405675, 0.9040831722665535, 4.407489031598244, 0.08615885630000791, 0.44074890315982446, 0.9425699260811738, 4.407489031598244, 0.9040831722665535, 0.13404047971467026] + ] + + for report_step in range(10): + sim.step(scale=1.0 / 10.0) + + values = [sim.fopr(), sim.fopt(), sim.fgpr(), sim.fgpt(), sim.fwpr(), sim.fwpt(), sim.fwct(), sim.fgor(), + sim.opr("OP1"), sim.gpr("OP1"), sim.wpr("OP1"), sim.gor("OP1"), sim.wct("OP1"), sim.bpr("6,6,6")] + + self.assertAlmostEqual(values[0], values[8]) # fopr = opr:op1 + self.assertAlmostEqual(values[2], values[9]) # fgpr = gpr:op1 + self.assertAlmostEqual(values[4], values[10]) # fwpr = wpr:op1 + + self.assertAlmostEqualList(values, expected_values[report_step]) diff --git a/ThirdParty/Ert/devel/redhat/ert.ecl.spec b/ThirdParty/Ert/devel/redhat/ert.ecl.spec index e50ca7a0fe..1ae33fa569 100644 --- a/ThirdParty/Ert/devel/redhat/ert.ecl.spec +++ b/ThirdParty/Ert/devel/redhat/ert.ecl.spec @@ -5,7 +5,7 @@ %define tag final2 Name: ert.ecl -Version: 2013.10 +Version: 2015.10 Release: 0 Summary: ERT - Ensemble based Reservoir Tool - ECL library License: GPL-3+ @@ -14,7 +14,9 @@ Url: http://ert.nr.no Source0: https://github.com/OPM/%{name}/archive/release/%{version}/%{tag}.tar.gz#/%{name}-%{version}.tar.gz BuildRequires: lapack-devel zlib-devel iputils BuildRequires: gcc -BuildRequires: cmake28 +%{?!el6:BuildRequires: python-devel} +%{?el6:BuildRequires: cmake28} +%{?!el6:BuildRequires: cmake} BuildRoot: %{_tmppath}/%{name}-%{version}-build Requires: libert.ecl1 = %{version} @@ -27,7 +29,19 @@ tool to do assisted history matching with Ensemble Kalman Filter %package -n libert.ecl1 Summary: ERT - Ensemble based Reservoir Tool - ECL library Group: System/Libraries -%{?el5:BuildArch: %{_arch}} + +%{?!el6: +%package -n python-ert.ecl +Summary: ERT - Ensemble based Reservoir Tool - Python bindings +Group: Python/Libraries +Requires: libert.ecl1 + +%description -n python-ert.ecl +ERT - Ensemble based Reservoir Tool is a tool for managing en ensemble +of reservoir models. The initial motivation for creating ERT was a as +tool to do assisted history matching with Ensemble Kalman Filter +(EnKF). This package contains the Python bindings. +} %description -n libert.ecl1 ERT - Ensemble based Reservoir Tool is a tool for managing en ensemble @@ -41,7 +55,6 @@ Group: Development/Libraries/C and C++ Requires: %{name} = %{version} Requires: lapack-devel Requires: libert.ecl1 = %{version} -%{?el5:BuildArch: %{_arch}} %description devel This package contains the development and header files for ert.ecl @@ -51,7 +64,7 @@ This package contains the development and header files for ert.ecl %build cd devel -cmake28 -DBUILD_SHARED_LIBS=1 -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=%{_prefix} -DBUILD_ECL_SUMMARY=1 +DESTDIR=${RPM_BUILD_ROOT} %{?el6:cmake28} %{?!el6:cmake} -DBUILD_SHARED_LIBS=1 -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=%{_prefix} -DBUILD_ECL_SUMMARY=1 %{?el6:-DBUILD_PYTHON=0} make %install @@ -77,3 +90,9 @@ rm -rf %{buildroot} %defattr(-,root,root,-) %{_libdir}/*.so %{_includedir}/* + +%{?!el6: +%files -n python-ert.ecl +%defattr(-,root,root,-) +/usr/lib/python2.7/site-packages/ert/* +} diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/add_fixed_length_schedule_kw.html b/ThirdParty/Ert/devel/share/gui/help/config/keywords/add_fixed_length_schedule_kw.html index d2786f5659..7fd6807ce1 100644 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/add_fixed_length_schedule_kw.html +++ b/ThirdParty/Ert/devel/share/gui/help/config/keywords/add_fixed_length_schedule_kw.html @@ -1 +1 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#ADD_FIXED_LENGTH_SCHEDULE_KW>Click here to view help on the wiki page.</a> \ No newline at end of file +<a href=http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#ADD_FIXED_LENGTH_SCHEDULE_KW>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/add_static_kw.html~HEAD b/ThirdParty/Ert/devel/share/gui/help/config/keywords/add_static_kw.html~HEAD deleted file mode 100644 index f69dbd13cf..0000000000 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/add_static_kw.html~HEAD +++ /dev/null @@ -1 +0,0 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#ADD_STATIC_KW>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/analysis_copy.html b/ThirdParty/Ert/devel/share/gui/help/config/keywords/analysis_copy.html index 4d0e042fef..bb65f45d44 100644 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/analysis_copy.html +++ b/ThirdParty/Ert/devel/share/gui/help/config/keywords/analysis_copy.html @@ -1 +1 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#ANALYSIS_COPY>Click here to view help on the wiki page.</a> \ No newline at end of file +<a href=http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#ANALYSIS_COPY>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/analysis_enkf_update.html b/ThirdParty/Ert/devel/share/gui/help/config/keywords/analysis_enkf_update.html index 580c4dcb7d..ba92057398 100644 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/analysis_enkf_update.html +++ b/ThirdParty/Ert/devel/share/gui/help/config/keywords/analysis_enkf_update.html @@ -1 +1 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#ANALYSIS_ENKF_UPDATE>Click here to view help on the wiki page.</a> \ No newline at end of file +<a href=http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#ANALYSIS_ENKF_UPDATE>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/analysis_load.html b/ThirdParty/Ert/devel/share/gui/help/config/keywords/analysis_load.html index 5e3a647ebc..0439e95c26 100644 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/analysis_load.html +++ b/ThirdParty/Ert/devel/share/gui/help/config/keywords/analysis_load.html @@ -1 +1 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#ANALYSIS_LOAD>Click here to view help on the wiki page.</a> \ No newline at end of file +<a href=http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#ANALYSIS_LOAD>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/analysis_select.html b/ThirdParty/Ert/devel/share/gui/help/config/keywords/analysis_select.html index bd37b1c6ef..5be06c89cb 100644 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/analysis_select.html +++ b/ThirdParty/Ert/devel/share/gui/help/config/keywords/analysis_select.html @@ -1 +1 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#ANALYSIS_SELECT>Click here to view help on the wiki page.</a> \ No newline at end of file +<a href=http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#ANALYSIS_SELECT>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/analysis_set_var.html b/ThirdParty/Ert/devel/share/gui/help/config/keywords/analysis_set_var.html index 66ef1fb449..7513aae255 100644 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/analysis_set_var.html +++ b/ThirdParty/Ert/devel/share/gui/help/config/keywords/analysis_set_var.html @@ -1 +1 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#ANALYSIS_SET_VAR>Click here to view help on the wiki page.</a> \ No newline at end of file +<a href=http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#ANALYSIS_SET_VAR>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/analysis_update.html b/ThirdParty/Ert/devel/share/gui/help/config/keywords/analysis_update.html index 2667d60c1c..be8ec82a19 100644 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/analysis_update.html +++ b/ThirdParty/Ert/devel/share/gui/help/config/keywords/analysis_update.html @@ -1 +1 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#ANALYSIS_UPDATE>Click here to view help on the wiki page.</a> \ No newline at end of file +<a href=http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#ANALYSIS_UPDATE>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/create_case.html b/ThirdParty/Ert/devel/share/gui/help/config/keywords/create_case.html index 363483fc44..7a634a6b3a 100644 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/create_case.html +++ b/ThirdParty/Ert/devel/share/gui/help/config/keywords/create_case.html @@ -1 +1 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#CREATE_CASE>Click here to view help on the wiki page.</a> \ No newline at end of file +<a href=http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#CREATE_CASE>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/data_file.html~HEAD b/ThirdParty/Ert/devel/share/gui/help/config/keywords/data_file.html~HEAD deleted file mode 100644 index 67263b1346..0000000000 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/data_file.html~HEAD +++ /dev/null @@ -1 +0,0 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#DATA_FILE>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/data_kw.html~HEAD b/ThirdParty/Ert/devel/share/gui/help/config/keywords/data_kw.html~HEAD deleted file mode 100644 index e21da1043e..0000000000 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/data_kw.html~HEAD +++ /dev/null @@ -1 +0,0 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#DATA_KW>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/data_ranking.html b/ThirdParty/Ert/devel/share/gui/help/config/keywords/data_ranking.html index 7d171050bf..9336015252 100644 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/data_ranking.html +++ b/ThirdParty/Ert/devel/share/gui/help/config/keywords/data_ranking.html @@ -1 +1 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#DATA_RANKING>Click here to view help on the wiki page.</a> \ No newline at end of file +<a href=http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#DATA_RANKING>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/define.html b/ThirdParty/Ert/devel/share/gui/help/config/keywords/define.html index 4721ab3a19..b1f1a19e61 100644 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/define.html +++ b/ThirdParty/Ert/devel/share/gui/help/config/keywords/define.html @@ -1 +1 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#DEFINE>Click here to view help on the wiki page.</a> \ No newline at end of file +<a href=http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#DEFINE>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/delete_runpath.html b/ThirdParty/Ert/devel/share/gui/help/config/keywords/delete_runpath.html index a5557b5943..397ba46143 100644 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/delete_runpath.html +++ b/ThirdParty/Ert/devel/share/gui/help/config/keywords/delete_runpath.html @@ -1 +1 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#DELETE_RUNPATH>Click here to view help on the wiki page.</a> \ No newline at end of file +<a href=http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#DELETE_RUNPATH>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/eclbase.html~HEAD b/ThirdParty/Ert/devel/share/gui/help/config/keywords/eclbase.html~HEAD deleted file mode 100644 index a15ca207e0..0000000000 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/eclbase.html~HEAD +++ /dev/null @@ -1 +0,0 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#ECLBASE>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/end_date.html b/ThirdParty/Ert/devel/share/gui/help/config/keywords/end_date.html index e8b0961967..13ea1a5f5b 100644 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/end_date.html +++ b/ThirdParty/Ert/devel/share/gui/help/config/keywords/end_date.html @@ -1 +1 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#END_DATE>Click here to view help on the wiki page.</a> \ No newline at end of file +<a href=http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#END_DATE>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/enkf_alpha.html~HEAD b/ThirdParty/Ert/devel/share/gui/help/config/keywords/enkf_alpha.html~HEAD deleted file mode 100644 index b5c5becbca..0000000000 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/enkf_alpha.html~HEAD +++ /dev/null @@ -1 +0,0 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#ENKF_ALPHA>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/enkf_bootstrap.html b/ThirdParty/Ert/devel/share/gui/help/config/keywords/enkf_bootstrap.html index aaac93ede6..62c4d5e1e0 100644 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/enkf_bootstrap.html +++ b/ThirdParty/Ert/devel/share/gui/help/config/keywords/enkf_bootstrap.html @@ -1 +1 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#ENKF_BOOTSTRAP>Click here to view help on the wiki page.</a> \ No newline at end of file +<a href=http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#ENKF_BOOTSTRAP>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/enkf_cv_folds.html b/ThirdParty/Ert/devel/share/gui/help/config/keywords/enkf_cv_folds.html index 41946518ad..8d32df09a6 100644 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/enkf_cv_folds.html +++ b/ThirdParty/Ert/devel/share/gui/help/config/keywords/enkf_cv_folds.html @@ -1 +1 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#ENKF_CV_FOLDS>Click here to view help on the wiki page.</a> \ No newline at end of file +<a href=http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#ENKF_CV_FOLDS>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/enkf_force_ncomp.html b/ThirdParty/Ert/devel/share/gui/help/config/keywords/enkf_force_ncomp.html index 9a55eeb2f0..bff2df9366 100644 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/enkf_force_ncomp.html +++ b/ThirdParty/Ert/devel/share/gui/help/config/keywords/enkf_force_ncomp.html @@ -1 +1 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#ENKF_FORCE_NCOMP>Click here to view help on the wiki page.</a> \ No newline at end of file +<a href=http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#ENKF_FORCE_NCOMP>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/enkf_local_cv.html b/ThirdParty/Ert/devel/share/gui/help/config/keywords/enkf_local_cv.html index e0d8eb8719..7ea90f84f9 100644 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/enkf_local_cv.html +++ b/ThirdParty/Ert/devel/share/gui/help/config/keywords/enkf_local_cv.html @@ -1 +1 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#ENKF_LOCAL_CV>Click here to view help on the wiki page.</a> \ No newline at end of file +<a href=http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#ENKF_LOCAL_CV>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/enkf_merge_observations.html~HEAD b/ThirdParty/Ert/devel/share/gui/help/config/keywords/enkf_merge_observations.html~HEAD deleted file mode 100644 index 43efa8bd55..0000000000 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/enkf_merge_observations.html~HEAD +++ /dev/null @@ -1 +0,0 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#ENKF_MERGE_OBSERVATIONS>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/enkf_mode.html~HEAD b/ThirdParty/Ert/devel/share/gui/help/config/keywords/enkf_mode.html~HEAD deleted file mode 100644 index e119f6ee21..0000000000 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/enkf_mode.html~HEAD +++ /dev/null @@ -1 +0,0 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#ENKF_MODE>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/enkf_ncomp.html b/ThirdParty/Ert/devel/share/gui/help/config/keywords/enkf_ncomp.html index f62fbaa777..438e8b761d 100644 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/enkf_ncomp.html +++ b/ThirdParty/Ert/devel/share/gui/help/config/keywords/enkf_ncomp.html @@ -1 +1 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#ENKF_NCOMP>Click here to view help on the wiki page.</a> \ No newline at end of file +<a href=http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#ENKF_NCOMP>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/enkf_pen_press.html b/ThirdParty/Ert/devel/share/gui/help/config/keywords/enkf_pen_press.html index f172c3ccbf..7385cf5292 100644 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/enkf_pen_press.html +++ b/ThirdParty/Ert/devel/share/gui/help/config/keywords/enkf_pen_press.html @@ -1 +1 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#ENKF_PEN_PRESS>Click here to view help on the wiki page.</a> \ No newline at end of file +<a href=http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#ENKF_PEN_PRESS>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/enkf_rerun.html~HEAD b/ThirdParty/Ert/devel/share/gui/help/config/keywords/enkf_rerun.html~HEAD deleted file mode 100644 index 9913097265..0000000000 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/enkf_rerun.html~HEAD +++ /dev/null @@ -1 +0,0 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#ENKF_RERUN>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/enkf_scaling.html b/ThirdParty/Ert/devel/share/gui/help/config/keywords/enkf_scaling.html index f0b940597c..26f232374d 100644 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/enkf_scaling.html +++ b/ThirdParty/Ert/devel/share/gui/help/config/keywords/enkf_scaling.html @@ -1 +1 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#ENKF_SCALING>Click here to view help on the wiki page.</a> \ No newline at end of file +<a href=http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#ENKF_SCALING>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/enkf_sched_file.html~HEAD b/ThirdParty/Ert/devel/share/gui/help/config/keywords/enkf_sched_file.html~HEAD deleted file mode 100644 index 9c7e1d7e88..0000000000 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/enkf_sched_file.html~HEAD +++ /dev/null @@ -1 +0,0 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#ENKF_SCHED_FILE>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/enkf_truncation.html~HEAD b/ThirdParty/Ert/devel/share/gui/help/config/keywords/enkf_truncation.html~HEAD deleted file mode 100644 index f433135ed0..0000000000 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/enkf_truncation.html~HEAD +++ /dev/null @@ -1 +0,0 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#ENKF_TRUNCATION>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/ensemble_run.html b/ThirdParty/Ert/devel/share/gui/help/config/keywords/ensemble_run.html index 7132b849cc..d0c173a933 100644 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/ensemble_run.html +++ b/ThirdParty/Ert/devel/share/gui/help/config/keywords/ensemble_run.html @@ -1 +1 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#ENSEMBLE_RUN>Click here to view help on the wiki page.</a> \ No newline at end of file +<a href=http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#ENSEMBLE_RUN>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/enspath.html b/ThirdParty/Ert/devel/share/gui/help/config/keywords/enspath.html index 9efc6d3dc8..cc2d44680e 100644 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/enspath.html +++ b/ThirdParty/Ert/devel/share/gui/help/config/keywords/enspath.html @@ -1 +1 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#ENSPATH>Click here to view help on the wiki page.</a> \ No newline at end of file +<a href=http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#ENSPATH>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/export_field.html b/ThirdParty/Ert/devel/share/gui/help/config/keywords/export_field.html index 0f067b9ecd..e1cf6dddec 100644 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/export_field.html +++ b/ThirdParty/Ert/devel/share/gui/help/config/keywords/export_field.html @@ -1 +1 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#EXPORT_FIELD>Click here to view help on the wiki page.</a> \ No newline at end of file +<a href=http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#EXPORT_FIELD>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/export_field_ecl_grdecl.html b/ThirdParty/Ert/devel/share/gui/help/config/keywords/export_field_ecl_grdecl.html index 8572b67c02..256e994c04 100644 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/export_field_ecl_grdecl.html +++ b/ThirdParty/Ert/devel/share/gui/help/config/keywords/export_field_ecl_grdecl.html @@ -1 +1 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#EXPORT_FIELD_ECL_GRDECL>Click here to view help on the wiki page.</a> \ No newline at end of file +<a href=http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#EXPORT_FIELD_ECL_GRDECL>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/export_field_rms_roff.html b/ThirdParty/Ert/devel/share/gui/help/config/keywords/export_field_rms_roff.html index 6de0a005d6..69b24e56a4 100644 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/export_field_rms_roff.html +++ b/ThirdParty/Ert/devel/share/gui/help/config/keywords/export_field_rms_roff.html @@ -1 +1 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#EXPORT_FIELD_RMS_ROFF>Click here to view help on the wiki page.</a> \ No newline at end of file +<a href=http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#EXPORT_FIELD_RMS_ROFF>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/export_ranking.html b/ThirdParty/Ert/devel/share/gui/help/config/keywords/export_ranking.html index 4f426d65cc..82e3807b97 100644 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/export_ranking.html +++ b/ThirdParty/Ert/devel/share/gui/help/config/keywords/export_ranking.html @@ -1 +1 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#EXPORT_RANKING>Click here to view help on the wiki page.</a> \ No newline at end of file +<a href=http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#EXPORT_RANKING>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/field.html b/ThirdParty/Ert/devel/share/gui/help/config/keywords/field.html index 3bead91bbd..7002f52e4e 100644 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/field.html +++ b/ThirdParty/Ert/devel/share/gui/help/config/keywords/field.html @@ -1 +1 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#FIELD>Click here to view help on the wiki page.</a> \ No newline at end of file +<a href=http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#FIELD>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/forward_model.html~HEAD b/ThirdParty/Ert/devel/share/gui/help/config/keywords/forward_model.html~HEAD deleted file mode 100644 index 4eea6b1a6a..0000000000 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/forward_model.html~HEAD +++ /dev/null @@ -1 +0,0 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#FORWARD_MODEL>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/gen_data.html b/ThirdParty/Ert/devel/share/gui/help/config/keywords/gen_data.html index 98cee9a9b9..4225d803d4 100644 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/gen_data.html +++ b/ThirdParty/Ert/devel/share/gui/help/config/keywords/gen_data.html @@ -1 +1 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#GEN_DATA>Click here to view help on the wiki page.</a> \ No newline at end of file +<a href=http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#GEN_DATA>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/gen_kw.html b/ThirdParty/Ert/devel/share/gui/help/config/keywords/gen_kw.html index 183aa965f7..92666c8c31 100644 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/gen_kw.html +++ b/ThirdParty/Ert/devel/share/gui/help/config/keywords/gen_kw.html @@ -1 +1 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#GEN_KW>Click here to view help on the wiki page.</a> \ No newline at end of file +<a href=http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#GEN_KW>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/gen_param.html b/ThirdParty/Ert/devel/share/gui/help/config/keywords/gen_param.html index 0a1e12cab4..d8ac1acef5 100644 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/gen_param.html +++ b/ThirdParty/Ert/devel/share/gui/help/config/keywords/gen_param.html @@ -1 +1 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#GEN_PARAM>Click here to view help on the wiki page.</a> \ No newline at end of file +<a href=http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#GEN_PARAM>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/grid.html~HEAD b/ThirdParty/Ert/devel/share/gui/help/config/keywords/grid.html~HEAD deleted file mode 100644 index 845ada5e0f..0000000000 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/grid.html~HEAD +++ /dev/null @@ -1 +0,0 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#GRID>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/history_source.html~HEAD b/ThirdParty/Ert/devel/share/gui/help/config/keywords/history_source.html~HEAD deleted file mode 100644 index 517e473e65..0000000000 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/history_source.html~HEAD +++ /dev/null @@ -1 +0,0 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#HISTORY_SOURCE>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/image_type.html~HEAD b/ThirdParty/Ert/devel/share/gui/help/config/keywords/image_type.html~HEAD deleted file mode 100644 index 810637150b..0000000000 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/image_type.html~HEAD +++ /dev/null @@ -1 +0,0 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#IMAGE_TYPE>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/image_viewer.html~HEAD b/ThirdParty/Ert/devel/share/gui/help/config/keywords/image_viewer.html~HEAD deleted file mode 100644 index a0c251aa26..0000000000 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/image_viewer.html~HEAD +++ /dev/null @@ -1 +0,0 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#IMAGE_VIEWER>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/init_case_from_existing.html b/ThirdParty/Ert/devel/share/gui/help/config/keywords/init_case_from_existing.html index ae84aa20f7..ba679851bf 100644 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/init_case_from_existing.html +++ b/ThirdParty/Ert/devel/share/gui/help/config/keywords/init_case_from_existing.html @@ -1 +1 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#INIT_CASE_FROM_EXISTING>Click here to view help on the wiki page.</a> \ No newline at end of file +<a href=http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#INIT_CASE_FROM_EXISTING>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/init_misfit_table.html b/ThirdParty/Ert/devel/share/gui/help/config/keywords/init_misfit_table.html index 3276ffe504..a242e1e5ce 100644 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/init_misfit_table.html +++ b/ThirdParty/Ert/devel/share/gui/help/config/keywords/init_misfit_table.html @@ -1 +1 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#INIT_MISFIT_TABLE>Click here to view help on the wiki page.</a> \ No newline at end of file +<a href=http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#INIT_MISFIT_TABLE>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/init_section.html~HEAD b/ThirdParty/Ert/devel/share/gui/help/config/keywords/init_section.html~HEAD deleted file mode 100644 index dc04b799ef..0000000000 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/init_section.html~HEAD +++ /dev/null @@ -1 +0,0 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#INIT_SECTION>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/install_job.html b/ThirdParty/Ert/devel/share/gui/help/config/keywords/install_job.html index 4714a44773..8c97722da7 100644 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/install_job.html +++ b/ThirdParty/Ert/devel/share/gui/help/config/keywords/install_job.html @@ -1 +1 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#INSTALL_JOB>Click here to view help on the wiki page.</a> \ No newline at end of file +<a href=http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#INSTALL_JOB>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/job_script.html~HEAD b/ThirdParty/Ert/devel/share/gui/help/config/keywords/job_script.html~HEAD deleted file mode 100644 index 5eb1ca0e6f..0000000000 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/job_script.html~HEAD +++ /dev/null @@ -1 +0,0 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#JOB_SCRIPT>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/jobname.html b/ThirdParty/Ert/devel/share/gui/help/config/keywords/jobname.html index 2163b6831d..c1b4e7290e 100644 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/jobname.html +++ b/ThirdParty/Ert/devel/share/gui/help/config/keywords/jobname.html @@ -1 +1 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#JOBNAME>Click here to view help on the wiki page.</a> \ No newline at end of file +<a href=http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#JOBNAME>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/keep_runpath.html b/ThirdParty/Ert/devel/share/gui/help/config/keywords/keep_runpath.html index 6c98c30642..5cdc840fcc 100644 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/keep_runpath.html +++ b/ThirdParty/Ert/devel/share/gui/help/config/keywords/keep_runpath.html @@ -1 +1 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#KEEP_RUNPATH>Click here to view help on the wiki page.</a> \ No newline at end of file +<a href=http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#KEEP_RUNPATH>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/keywords.txt b/ThirdParty/Ert/devel/share/gui/help/config/keywords/keywords.txt index 3ecbc5a4d4..79d5fc80ea 100644 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/keywords.txt +++ b/ThirdParty/Ert/devel/share/gui/help/config/keywords/keywords.txt @@ -1,100 +1,100 @@ -data_file http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#DATA_FILE -eclbase http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#ECLBASE -jobname http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#JOBNAME -grid http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#GRID -init_section http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#INIT_SECTION -num_realizations http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#NUM_REALIZATIONS -schedule_file http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#SCHEDULE_FILE -data_kw http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#DATA_KW -delete_runpath http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#DELETE_RUNPATH -enkf_sched_file http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#ENKF_SCHED_FILE -end_date http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#END_DATE -enspath http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#ENSPATH -select_case http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#SELECT_CASE -history_source http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#HISTORY_SOURCE -refcase http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#REFCASE -install_job http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#INSTALL_JOB -keep_runpath http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#KEEP_RUNPATH -obs_config http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#OBS_CONFIG -result_path http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#RESULT_PATH -runpath http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#RUNPATH -runpath_file http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#RUNPATH_FILE -min_realizations http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#MIN_REALIZATIONS -stop_long_running http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#STOP_LONG_RUNNING -max_runtime http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#MAX_RUNTIME -field http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#FIELD -gen_data http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#GEN_DATA -gen_kw http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#GEN_KW -gen_param http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#GEN_PARAM -surface http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#SURFACE -summary http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#SUMMARY -enkf_alpha http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#ENKF_ALPHA -enkf_bootstrap http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#ENKF_BOOTSTRAP -enkf_cv_folds http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#ENKF_CV_FOLDS -enkf_force_ncomp http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#ENKF_FORCE_NCOMP -enkf_local_cv http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#ENKF_LOCAL_CV -enkf_pen_press http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#ENKF_PEN_PRESS -enkf_mode http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#ENKF_MODE -enkf_merge_observations http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#ENKF_MERGE_OBSERVATIONS -enkf_ncomp http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#ENKF_NCOMP -enkf_rerun http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#ENKF_RERUN -enkf_scaling http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#ENKF_SCALING -enkf_truncation http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#ENKF_TRUNCATION -update_log_path http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#UPDATE_LOG_PATH -analysis_load http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#ANALYSIS_LOAD -analysis_select http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#ANALYSIS_SELECT -analysis_set_var http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#ANALYSIS_SET_VAR -analysis_copy http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#ANALYSIS_COPY -add_fixed_length_schedule_kw http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#ADD_FIXED_LENGTH_SCHEDULE_KW -add_static_kw http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#ADD_STATIC_KW -define http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#DEFINE -schedule_prediction_file http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#SCHEDULE_PREDICTION_FILE -forward_model http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#FORWARD_MODEL -job_script http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#JOB_SCRIPT -queue_system http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#QUEUE_SYSTEM -lsf_server http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#LSF_SERVER -lsf_queue http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#LSF_QUEUE -max_running_lsf http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#MAX_RUNNING_LSF -max_running_local http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#MAX_RUNNING_LOCAL -rsh_host http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#RSH_HOST -rsh_command http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#RSH_COMMAND -max_running_rsh http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#MAX_RUNNING_RSH -image_viewer http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#IMAGE_VIEWER -image_type http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#IMAGE_TYPE -plot_driver http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#PLOT_DRIVER -plot_errorbar http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#PLOT_ERRORBAR -plot_errorbar_max http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#PLOT_ERRORBAR_MAX -plot_height http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#PLOT_HEIGHT -plot_refcase http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#PLOT_REFCASE -refcase_list http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#REFCASE_LIST -plot_path http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#PLOT_PATH -plot_width http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#PLOT_WIDTH -rft_config http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#RFT_CONFIG -rftpath http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#RFTPATH -select_case http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#SELECT_CASE -create_case http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#CREATE_CASE -init_case_from_existing http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#INIT_CASE_FROM_EXISTING -export_field http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#EXPORT_FIELD -export_field_rms_roff http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#EXPORT_FIELD_RMS_ROFF -export_field_ecl_grdecl http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#EXPORT_FIELD_ECL_GRDECL -analysis_update http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#ANALYSIS_UPDATE -analysis_enkf_update http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#ANALYSIS_ENKF_UPDATE -run_smoother http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#RUN_SMOOTHER -run_smoother_with_iter http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#RUN_SMOOTHER_WITH_ITER -ensemble_run http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#ENSEMBLE_RUN -load_results http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#LOAD_RESULTS -load_results_iter http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#LOAD_RESULTS_ITER -observation_ranking http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#OBSERVATION_RANKING -data_ranking http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#DATA_RANKING -export_ranking http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#EXPORT_RANKING -init_misfit_table http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#INIT_MISFIT_TABLE -qc_workflow http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#QC_WORKFLOW -qc_path http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#QC_PATH -report_context http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#REPORT_CONTEXT -report_list http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#REPORT_LIST -report_path http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#REPORT_PATH -report_search_path http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#REPORT_SEARCH_PATH -report_well_list http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#REPORT_WELL_LIST -report_group_list http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#REPORT_GROUP_LIST -setenv http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#SETENV -update_path http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#UPDATE_PATH \ No newline at end of file +data_file http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#DATA_FILE +eclbase http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#ECLBASE +jobname http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#JOBNAME +grid http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#GRID +init_section http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#INIT_SECTION +num_realizations http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#NUM_REALIZATIONS +schedule_file http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#SCHEDULE_FILE +data_kw http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#DATA_KW +delete_runpath http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#DELETE_RUNPATH +enkf_sched_file http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#ENKF_SCHED_FILE +end_date http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#END_DATE +enspath http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#ENSPATH +select_case http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#SELECT_CASE +history_source http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#HISTORY_SOURCE +refcase http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#REFCASE +install_job http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#INSTALL_JOB +keep_runpath http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#KEEP_RUNPATH +obs_config http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#OBS_CONFIG +result_path http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#RESULT_PATH +runpath http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#RUNPATH +runpath_file http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#RUNPATH_FILE +min_realizations http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#MIN_REALIZATIONS +stop_long_running http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#STOP_LONG_RUNNING +max_runtime http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#MAX_RUNTIME +field http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#FIELD +gen_data http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#GEN_DATA +gen_kw http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#GEN_KW +gen_param http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#GEN_PARAM +surface http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#SURFACE +summary http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#SUMMARY +enkf_alpha http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#ENKF_ALPHA +enkf_bootstrap http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#ENKF_BOOTSTRAP +enkf_cv_folds http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#ENKF_CV_FOLDS +enkf_force_ncomp http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#ENKF_FORCE_NCOMP +enkf_local_cv http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#ENKF_LOCAL_CV +enkf_pen_press http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#ENKF_PEN_PRESS +enkf_mode http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#ENKF_MODE +enkf_merge_observations http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#ENKF_MERGE_OBSERVATIONS +enkf_ncomp http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#ENKF_NCOMP +enkf_rerun http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#ENKF_RERUN +enkf_scaling http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#ENKF_SCALING +enkf_truncation http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#ENKF_TRUNCATION +update_log_path http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#UPDATE_LOG_PATH +analysis_load http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#ANALYSIS_LOAD +analysis_select http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#ANALYSIS_SELECT +analysis_set_var http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#ANALYSIS_SET_VAR +analysis_copy http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#ANALYSIS_COPY +add_fixed_length_schedule_kw http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#ADD_FIXED_LENGTH_SCHEDULE_KW +add_static_kw http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#ADD_STATIC_KW +define http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#DEFINE +schedule_prediction_file http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#SCHEDULE_PREDICTION_FILE +forward_model http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#FORWARD_MODEL +job_script http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#JOB_SCRIPT +queue_system http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#QUEUE_SYSTEM +lsf_server http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#LSF_SERVER +lsf_queue http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#LSF_QUEUE +max_running_lsf http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#MAX_RUNNING_LSF +max_running_local http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#MAX_RUNNING_LOCAL +rsh_host http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#RSH_HOST +rsh_command http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#RSH_COMMAND +max_running_rsh http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#MAX_RUNNING_RSH +image_viewer http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#IMAGE_VIEWER +image_type http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#IMAGE_TYPE +plot_driver http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#PLOT_DRIVER +plot_errorbar http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#PLOT_ERRORBAR +plot_errorbar_max http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#PLOT_ERRORBAR_MAX +plot_height http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#PLOT_HEIGHT +plot_refcase http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#PLOT_REFCASE +refcase_list http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#REFCASE_LIST +plot_path http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#PLOT_PATH +plot_width http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#PLOT_WIDTH +rft_config http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#RFT_CONFIG +rftpath http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#RFTPATH +select_case http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#SELECT_CASE +create_case http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#CREATE_CASE +init_case_from_existing http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#INIT_CASE_FROM_EXISTING +export_field http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#EXPORT_FIELD +export_field_rms_roff http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#EXPORT_FIELD_RMS_ROFF +export_field_ecl_grdecl http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#EXPORT_FIELD_ECL_GRDECL +analysis_update http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#ANALYSIS_UPDATE +analysis_enkf_update http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#ANALYSIS_ENKF_UPDATE +run_smoother http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#RUN_SMOOTHER +run_smoother_with_iter http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#RUN_SMOOTHER_WITH_ITER +ensemble_run http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#ENSEMBLE_RUN +load_results http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#LOAD_RESULTS +load_results_iter http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#LOAD_RESULTS_ITER +observation_ranking http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#OBSERVATION_RANKING +data_ranking http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#DATA_RANKING +export_ranking http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#EXPORT_RANKING +init_misfit_table http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#INIT_MISFIT_TABLE +qc_workflow http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#QC_WORKFLOW +qc_path http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#QC_PATH +report_context http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#REPORT_CONTEXT +report_list http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#REPORT_LIST +report_path http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#REPORT_PATH +report_search_path http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#REPORT_SEARCH_PATH +report_well_list http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#REPORT_WELL_LIST +report_group_list http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#REPORT_GROUP_LIST +setenv http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#SETENV +update_path http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#UPDATE_PATH \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/load_results.html b/ThirdParty/Ert/devel/share/gui/help/config/keywords/load_results.html index 1510767b99..2def17d6d9 100644 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/load_results.html +++ b/ThirdParty/Ert/devel/share/gui/help/config/keywords/load_results.html @@ -1 +1 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#LOAD_RESULTS>Click here to view help on the wiki page.</a> \ No newline at end of file +<a href=http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#LOAD_RESULTS>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/load_results_iter.html b/ThirdParty/Ert/devel/share/gui/help/config/keywords/load_results_iter.html index 04d868798c..11a79d6e59 100644 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/load_results_iter.html +++ b/ThirdParty/Ert/devel/share/gui/help/config/keywords/load_results_iter.html @@ -1 +1 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#LOAD_RESULTS_ITER>Click here to view help on the wiki page.</a> \ No newline at end of file +<a href=http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#LOAD_RESULTS_ITER>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/lsf_queue.html~HEAD b/ThirdParty/Ert/devel/share/gui/help/config/keywords/lsf_queue.html~HEAD deleted file mode 100644 index 9a294d649f..0000000000 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/lsf_queue.html~HEAD +++ /dev/null @@ -1 +0,0 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#LSF_QUEUE>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/lsf_server.html b/ThirdParty/Ert/devel/share/gui/help/config/keywords/lsf_server.html index bc158ce4c1..fd9aac3cc2 100644 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/lsf_server.html +++ b/ThirdParty/Ert/devel/share/gui/help/config/keywords/lsf_server.html @@ -1 +1 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#LSF_SERVER>Click here to view help on the wiki page.</a> \ No newline at end of file +<a href=http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#LSF_SERVER>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/max_running_local.html~HEAD b/ThirdParty/Ert/devel/share/gui/help/config/keywords/max_running_local.html~HEAD deleted file mode 100644 index fc4f5d6c5e..0000000000 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/max_running_local.html~HEAD +++ /dev/null @@ -1 +0,0 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#MAX_RUNNING_LOCAL>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/max_running_lsf.html~HEAD b/ThirdParty/Ert/devel/share/gui/help/config/keywords/max_running_lsf.html~HEAD deleted file mode 100644 index 5ac5df8bb4..0000000000 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/max_running_lsf.html~HEAD +++ /dev/null @@ -1 +0,0 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#MAX_RUNNING_LSF>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/max_running_rsh.html~HEAD b/ThirdParty/Ert/devel/share/gui/help/config/keywords/max_running_rsh.html~HEAD deleted file mode 100644 index c219d781eb..0000000000 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/max_running_rsh.html~HEAD +++ /dev/null @@ -1 +0,0 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#MAX_RUNNING_RSH>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/max_runtime.html b/ThirdParty/Ert/devel/share/gui/help/config/keywords/max_runtime.html index 749e5b5437..3e1de4739b 100644 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/max_runtime.html +++ b/ThirdParty/Ert/devel/share/gui/help/config/keywords/max_runtime.html @@ -1 +1 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#MAX_RUNTIME>Click here to view help on the wiki page.</a> \ No newline at end of file +<a href=http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#MAX_RUNTIME>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/min_realizations.html b/ThirdParty/Ert/devel/share/gui/help/config/keywords/min_realizations.html index a3ddc94425..4f54035717 100644 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/min_realizations.html +++ b/ThirdParty/Ert/devel/share/gui/help/config/keywords/min_realizations.html @@ -1 +1 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#MIN_REALIZATIONS>Click here to view help on the wiki page.</a> \ No newline at end of file +<a href=http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#MIN_REALIZATIONS>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/num_realizations.html~HEAD b/ThirdParty/Ert/devel/share/gui/help/config/keywords/num_realizations.html~HEAD deleted file mode 100644 index 3314abdc98..0000000000 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/num_realizations.html~HEAD +++ /dev/null @@ -1 +0,0 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#NUM_REALIZATIONS>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/obs_config.html~HEAD b/ThirdParty/Ert/devel/share/gui/help/config/keywords/obs_config.html~HEAD deleted file mode 100644 index 58b2087624..0000000000 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/obs_config.html~HEAD +++ /dev/null @@ -1 +0,0 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#OBS_CONFIG>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/observation_ranking.html b/ThirdParty/Ert/devel/share/gui/help/config/keywords/observation_ranking.html index 1cce3fd21f..be2ff2fe01 100644 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/observation_ranking.html +++ b/ThirdParty/Ert/devel/share/gui/help/config/keywords/observation_ranking.html @@ -1 +1 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#OBSERVATION_RANKING>Click here to view help on the wiki page.</a> \ No newline at end of file +<a href=http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#OBSERVATION_RANKING>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/plot_driver.html~HEAD b/ThirdParty/Ert/devel/share/gui/help/config/keywords/plot_driver.html~HEAD deleted file mode 100644 index 8d596aa2bf..0000000000 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/plot_driver.html~HEAD +++ /dev/null @@ -1 +0,0 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#PLOT_DRIVER>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/plot_errorbar.html b/ThirdParty/Ert/devel/share/gui/help/config/keywords/plot_errorbar.html index 8dc1f04c64..0568bb659d 100644 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/plot_errorbar.html +++ b/ThirdParty/Ert/devel/share/gui/help/config/keywords/plot_errorbar.html @@ -1 +1 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#PLOT_ERRORBAR>Click here to view help on the wiki page.</a> \ No newline at end of file +<a href=http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#PLOT_ERRORBAR>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/plot_errorbar_max.html~HEAD b/ThirdParty/Ert/devel/share/gui/help/config/keywords/plot_errorbar_max.html~HEAD deleted file mode 100644 index 11d2e0d3a0..0000000000 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/plot_errorbar_max.html~HEAD +++ /dev/null @@ -1 +0,0 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#PLOT_ERRORBAR_MAX>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/plot_height.html~HEAD b/ThirdParty/Ert/devel/share/gui/help/config/keywords/plot_height.html~HEAD deleted file mode 100644 index 7e8e70a614..0000000000 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/plot_height.html~HEAD +++ /dev/null @@ -1 +0,0 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#PLOT_HEIGHT>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/plot_path.html~HEAD b/ThirdParty/Ert/devel/share/gui/help/config/keywords/plot_path.html~HEAD deleted file mode 100644 index 88ba65eb41..0000000000 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/plot_path.html~HEAD +++ /dev/null @@ -1 +0,0 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#PLOT_PATH>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/plot_refcase.html b/ThirdParty/Ert/devel/share/gui/help/config/keywords/plot_refcase.html index 8d20e136b0..a7d3d67fb9 100644 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/plot_refcase.html +++ b/ThirdParty/Ert/devel/share/gui/help/config/keywords/plot_refcase.html @@ -1 +1 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#PLOT_REFCASE>Click here to view help on the wiki page.</a> \ No newline at end of file +<a href=http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#PLOT_REFCASE>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/plot_width.html~HEAD b/ThirdParty/Ert/devel/share/gui/help/config/keywords/plot_width.html~HEAD deleted file mode 100644 index 26cc77a710..0000000000 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/plot_width.html~HEAD +++ /dev/null @@ -1 +0,0 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#PLOT_WIDTH>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/qc_path.html b/ThirdParty/Ert/devel/share/gui/help/config/keywords/qc_path.html index b291a46a71..26029f50f1 100644 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/qc_path.html +++ b/ThirdParty/Ert/devel/share/gui/help/config/keywords/qc_path.html @@ -1 +1 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#QC_PATH>Click here to view help on the wiki page.</a> \ No newline at end of file +<a href=http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#QC_PATH>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/qc_workflow.html b/ThirdParty/Ert/devel/share/gui/help/config/keywords/qc_workflow.html index 38901e8394..61ebf75d26 100644 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/qc_workflow.html +++ b/ThirdParty/Ert/devel/share/gui/help/config/keywords/qc_workflow.html @@ -1 +1 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#QC_WORKFLOW>Click here to view help on the wiki page.</a> \ No newline at end of file +<a href=http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#QC_WORKFLOW>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/queue_system.html b/ThirdParty/Ert/devel/share/gui/help/config/keywords/queue_system.html index e06952bf8b..d23625073f 100644 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/queue_system.html +++ b/ThirdParty/Ert/devel/share/gui/help/config/keywords/queue_system.html @@ -5,4 +5,4 @@ <dt><b>LOCAL:</b> Submits the jobs to your local workstation. </dl> <br/> -<a href="http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#QUEUE_SYSTEM">More information in the wiki.</a> +<a href="http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#QUEUE_SYSTEM">More information in the wiki.</a> diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/queue_system.html~HEAD b/ThirdParty/Ert/devel/share/gui/help/config/keywords/queue_system.html~HEAD deleted file mode 100644 index 99018f9949..0000000000 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/queue_system.html~HEAD +++ /dev/null @@ -1 +0,0 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#QUEUE_SYSTEM>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/refcase.html~HEAD b/ThirdParty/Ert/devel/share/gui/help/config/keywords/refcase.html~HEAD deleted file mode 100644 index 08d1a76fb5..0000000000 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/refcase.html~HEAD +++ /dev/null @@ -1 +0,0 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#REFCASE>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/refcase_list.html b/ThirdParty/Ert/devel/share/gui/help/config/keywords/refcase_list.html index 37b3d471f3..9fa95da112 100644 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/refcase_list.html +++ b/ThirdParty/Ert/devel/share/gui/help/config/keywords/refcase_list.html @@ -1 +1 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#REFCASE_LIST>Click here to view help on the wiki page.</a> \ No newline at end of file +<a href=http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#REFCASE_LIST>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/report_context.html b/ThirdParty/Ert/devel/share/gui/help/config/keywords/report_context.html index 332754b50b..552263e58a 100644 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/report_context.html +++ b/ThirdParty/Ert/devel/share/gui/help/config/keywords/report_context.html @@ -1 +1 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#REPORT_CONTEXT>Click here to view help on the wiki page.</a> \ No newline at end of file +<a href=http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#REPORT_CONTEXT>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/report_group_list.html b/ThirdParty/Ert/devel/share/gui/help/config/keywords/report_group_list.html index e253eb0ef7..77e6854c9b 100644 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/report_group_list.html +++ b/ThirdParty/Ert/devel/share/gui/help/config/keywords/report_group_list.html @@ -1 +1 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#REPORT_GROUP_LIST>Click here to view help on the wiki page.</a> \ No newline at end of file +<a href=http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#REPORT_GROUP_LIST>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/report_list.html b/ThirdParty/Ert/devel/share/gui/help/config/keywords/report_list.html index 512e8cdd08..c256814c55 100644 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/report_list.html +++ b/ThirdParty/Ert/devel/share/gui/help/config/keywords/report_list.html @@ -1 +1 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#REPORT_LIST>Click here to view help on the wiki page.</a> \ No newline at end of file +<a href=http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#REPORT_LIST>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/report_path.html b/ThirdParty/Ert/devel/share/gui/help/config/keywords/report_path.html index 711aa8c825..d2dc8e7d4a 100644 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/report_path.html +++ b/ThirdParty/Ert/devel/share/gui/help/config/keywords/report_path.html @@ -1 +1 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#REPORT_PATH>Click here to view help on the wiki page.</a> \ No newline at end of file +<a href=http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#REPORT_PATH>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/report_search_path.html b/ThirdParty/Ert/devel/share/gui/help/config/keywords/report_search_path.html index c7c0ac1f5d..0840bb7e1c 100644 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/report_search_path.html +++ b/ThirdParty/Ert/devel/share/gui/help/config/keywords/report_search_path.html @@ -1 +1 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#REPORT_SEARCH_PATH>Click here to view help on the wiki page.</a> \ No newline at end of file +<a href=http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#REPORT_SEARCH_PATH>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/report_well_list.html b/ThirdParty/Ert/devel/share/gui/help/config/keywords/report_well_list.html index e8579adc7b..094fa02b36 100644 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/report_well_list.html +++ b/ThirdParty/Ert/devel/share/gui/help/config/keywords/report_well_list.html @@ -1 +1 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#REPORT_WELL_LIST>Click here to view help on the wiki page.</a> \ No newline at end of file +<a href=http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#REPORT_WELL_LIST>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/result_path.html b/ThirdParty/Ert/devel/share/gui/help/config/keywords/result_path.html index 242f708267..5ca7fa5241 100644 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/result_path.html +++ b/ThirdParty/Ert/devel/share/gui/help/config/keywords/result_path.html @@ -1 +1 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#RESULT_PATH>Click here to view help on the wiki page.</a> \ No newline at end of file +<a href=http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#RESULT_PATH>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/rft_config.html b/ThirdParty/Ert/devel/share/gui/help/config/keywords/rft_config.html index c5f8cc80dc..fa68edbb47 100644 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/rft_config.html +++ b/ThirdParty/Ert/devel/share/gui/help/config/keywords/rft_config.html @@ -1 +1 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#RFT_CONFIG>Click here to view help on the wiki page.</a> \ No newline at end of file +<a href=http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#RFT_CONFIG>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/rftpath.html b/ThirdParty/Ert/devel/share/gui/help/config/keywords/rftpath.html index 863dec10b9..ca1df0aa92 100644 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/rftpath.html +++ b/ThirdParty/Ert/devel/share/gui/help/config/keywords/rftpath.html @@ -1 +1 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#RFTPATH>Click here to view help on the wiki page.</a> \ No newline at end of file +<a href=http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#RFTPATH>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/rsh_command.html~HEAD b/ThirdParty/Ert/devel/share/gui/help/config/keywords/rsh_command.html~HEAD deleted file mode 100644 index 5b4b606c61..0000000000 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/rsh_command.html~HEAD +++ /dev/null @@ -1 +0,0 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#RSH_COMMAND>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/rsh_host.html~HEAD b/ThirdParty/Ert/devel/share/gui/help/config/keywords/rsh_host.html~HEAD deleted file mode 100644 index 49ba3b46a4..0000000000 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/rsh_host.html~HEAD +++ /dev/null @@ -1 +0,0 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#RSH_HOST>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/run_smoother.html b/ThirdParty/Ert/devel/share/gui/help/config/keywords/run_smoother.html index 305fc0b1d2..5d61059e82 100644 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/run_smoother.html +++ b/ThirdParty/Ert/devel/share/gui/help/config/keywords/run_smoother.html @@ -1 +1 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#RUN_SMOOTHER>Click here to view help on the wiki page.</a> \ No newline at end of file +<a href=http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#RUN_SMOOTHER>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/run_smoother_with_iter.html b/ThirdParty/Ert/devel/share/gui/help/config/keywords/run_smoother_with_iter.html index 14d805f1a9..f71187c49e 100644 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/run_smoother_with_iter.html +++ b/ThirdParty/Ert/devel/share/gui/help/config/keywords/run_smoother_with_iter.html @@ -1 +1 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#RUN_SMOOTHER_WITH_ITER>Click here to view help on the wiki page.</a> \ No newline at end of file +<a href=http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#RUN_SMOOTHER_WITH_ITER>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/runpath.html~HEAD b/ThirdParty/Ert/devel/share/gui/help/config/keywords/runpath.html~HEAD deleted file mode 100644 index 89303eaa37..0000000000 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/runpath.html~HEAD +++ /dev/null @@ -1 +0,0 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#RUNPATH>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/runpath_file.html b/ThirdParty/Ert/devel/share/gui/help/config/keywords/runpath_file.html index 2e83b4513f..e5839c9695 100644 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/runpath_file.html +++ b/ThirdParty/Ert/devel/share/gui/help/config/keywords/runpath_file.html @@ -1 +1 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#RUNPATH_FILE>Click here to view help on the wiki page.</a> \ No newline at end of file +<a href=http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#RUNPATH_FILE>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/schedule_file.html~HEAD b/ThirdParty/Ert/devel/share/gui/help/config/keywords/schedule_file.html~HEAD deleted file mode 100644 index 8d94d5d2ab..0000000000 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/schedule_file.html~HEAD +++ /dev/null @@ -1 +0,0 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#SCHEDULE_FILE>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/schedule_prediction_file.html~HEAD b/ThirdParty/Ert/devel/share/gui/help/config/keywords/schedule_prediction_file.html~HEAD deleted file mode 100644 index 0f3c2a29ac..0000000000 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/schedule_prediction_file.html~HEAD +++ /dev/null @@ -1 +0,0 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#SCHEDULE_PREDICTION_FILE>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/select_case.html b/ThirdParty/Ert/devel/share/gui/help/config/keywords/select_case.html index 877772b866..68f628f3c3 100644 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/select_case.html +++ b/ThirdParty/Ert/devel/share/gui/help/config/keywords/select_case.html @@ -1 +1 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#SELECT_CASE>Click here to view help on the wiki page.</a> \ No newline at end of file +<a href=http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#SELECT_CASE>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/setenv.html~HEAD b/ThirdParty/Ert/devel/share/gui/help/config/keywords/setenv.html~HEAD deleted file mode 100644 index aaa34ca9ae..0000000000 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/setenv.html~HEAD +++ /dev/null @@ -1 +0,0 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#SETENV>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/stop_long_running.html b/ThirdParty/Ert/devel/share/gui/help/config/keywords/stop_long_running.html index 4bc741bf20..0abd696273 100644 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/stop_long_running.html +++ b/ThirdParty/Ert/devel/share/gui/help/config/keywords/stop_long_running.html @@ -1 +1 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#STOP_LONG_RUNNING>Click here to view help on the wiki page.</a> \ No newline at end of file +<a href=http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#STOP_LONG_RUNNING>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/summary.html b/ThirdParty/Ert/devel/share/gui/help/config/keywords/summary.html index f4cf208cce..8083f8729b 100644 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/summary.html +++ b/ThirdParty/Ert/devel/share/gui/help/config/keywords/summary.html @@ -1 +1 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#SUMMARY>Click here to view help on the wiki page.</a> \ No newline at end of file +<a href=http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#SUMMARY>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/surface.html b/ThirdParty/Ert/devel/share/gui/help/config/keywords/surface.html index 9ea333c494..c26f69080a 100644 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/surface.html +++ b/ThirdParty/Ert/devel/share/gui/help/config/keywords/surface.html @@ -1 +1 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#SURFACE>Click here to view help on the wiki page.</a> \ No newline at end of file +<a href=http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#SURFACE>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/update_log_path.html b/ThirdParty/Ert/devel/share/gui/help/config/keywords/update_log_path.html index af497a446a..c321b261c8 100644 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/update_log_path.html +++ b/ThirdParty/Ert/devel/share/gui/help/config/keywords/update_log_path.html @@ -1 +1 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#UPDATE_LOG_PATH>Click here to view help on the wiki page.</a> \ No newline at end of file +<a href=http://ert.nr.no/ert/index.php/Creating_a_configuration_file_for_ERT#UPDATE_LOG_PATH>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/help/config/keywords/update_path.html~HEAD b/ThirdParty/Ert/devel/share/gui/help/config/keywords/update_path.html~HEAD deleted file mode 100644 index 0763a2e9f1..0000000000 --- a/ThirdParty/Ert/devel/share/gui/help/config/keywords/update_path.html~HEAD +++ /dev/null @@ -1 +0,0 @@ -<a href=http://ert.nr.no/wiki/index.php/Creating_a_configuration_file_for_ERT#UPDATE_PATH>Click here to view help on the wiki page.</a> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/plots/ensemble_statistics_plot.html b/ThirdParty/Ert/devel/share/gui/plots/ensemble_statistics_plot.html deleted file mode 100644 index ed551a1ec0..0000000000 --- a/ThirdParty/Ert/devel/share/gui/plots/ensemble_statistics_plot.html +++ /dev/null @@ -1,146 +0,0 @@ -<!DOCTYPE html> -<!-- Copyright (C) 2013 Statoil ASA, Norway. --> -<!-- --> -<!-- The file 'simple_overview_plot.html' is part of ERT - Ensemble based Reservoir Tool. --> -<!-- --> -<!-- ERT is free software: you can redistribute it and/or modify --> -<!-- it under the terms of the GNU General Public License as published by --> -<!-- the Free Software Foundation, either version 3 of the License, or --> -<!-- (at your option) any later version. --> -<!-- --> -<!-- ERT is distributed in the hope that it will be useful, but WITHOUT ANY --> -<!-- WARRANTY; without even the implied warranty of MERCHANTABILITY or --> -<!-- FITNESS FOR A PARTICULAR PURPOSE. --> -<!-- --> -<!-- See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> --> -<!-- for more details. --> - -<html> -<head> - <meta charset="utf-8"> - <link rel="stylesheet" type="text/css" href="style/plot.css"/> -</head> - -<script src="libs/d3.v3.js"></script> -<script src="scripts/styles.js"></script> -<script src="scripts/base_plot.js"></script> -<script src="scripts/base_plot_time_dimension.js"></script> -<script src="scripts/base_plot_value_dimension.js"></script> -<script src="scripts/canvas_plot_statistics.js"></script> -<script src="scripts/canvas_plot_line.js"></script> -<script src="scripts/canvas_plot_stippled_line.js"></script> -<script src="scripts/canvas_plot_area.js"></script> -<script src="scripts/canvas_error_bar.js"></script> -<script src="scripts/canvas_plot_circle.js"></script> -<script src="scripts/canvas_plot_legend.js"></script> - -<script> - var plot = null; - - var time_dimension = null; - var value_dimension = null; - - function initialize() { - if (!(typeof plot_data_source === 'undefined')) { - createPlot(); - updatePlot(); - plot_data_source.htmlInitialized(); - } else { -// createPlot(); -// plot.setData(data); - console.log("Unable to load data!"); - alert("Unable to load data!"); - } - } - - function createPlot() { - time_dimension = BasePlotTimeDimension(); - value_dimension = BasePlotValueDimension(); - plot = new StatisticsPlot(d3.select("body"), time_dimension, value_dimension); - plot.setRenderingFinishedCallback(function() { - plot_data_source.renderingFinished(); - }); - } - - function updatePlot() { - var data = plot_data_source.getPlotData(); - plot.setData(data); - value_dimension.setUnit(data.unitY()); - } - - function setSize(width, height) { - plot.resize(width, height - 75); - } - - function setScales(x_min, x_max, y_min, y_max) { - plot.setScales(x_min, x_max, y_min, y_max); - } - - function setReportStepTime(report_step_time) { - // Not supported by this plot - } - - function supportsPlotProperties(time, value, depth, index, histogram, pca){ - return time && value && !depth; - } - - function getPrintWidth(){ - return 1600; - } - - function getPrintHeight(){ - return 1200; - } - - function setCustomSettings(settings) { - plot.setCustomSettings(settings); - STYLES.updateColors(settings); - } - - function renderNow(){ - plot.renderNow(); - } - - function getPlotTitle(){ - return plot.getTitle(); - } - - function xAxisType() { - return "time"; - } - - function yAxisType() { - return "value"; - } - - function isReportStepCapable() { - return false; - } - - function getXMin() { - var data = plot_data_source.getTemporaryData(); - return data.minX(); - } - - function getXMax() { - var data = plot_data_source.getTemporaryData(); - return data.maxX(); - } - - function getYMin() { - var data = plot_data_source.getTemporaryData(); - return data.minY(); - } - - function getYMax() { - var data = plot_data_source.getTemporaryData(); - return data.maxY(); - } - -</script> - -<body onload="initialize();"> - -</body> - -</html> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/plots/gen_data.html b/ThirdParty/Ert/devel/share/gui/plots/gen_data.html deleted file mode 100644 index b186896624..0000000000 --- a/ThirdParty/Ert/devel/share/gui/plots/gen_data.html +++ /dev/null @@ -1,148 +0,0 @@ -<!DOCTYPE html> -<!-- Copyright (C) 2013 Statoil ASA, Norway. --> -<!-- --> -<!-- The file 'simple_plot.html' is part of ERT - Ensemble based Reservoir Tool. --> -<!-- --> -<!-- ERT is free software: you can redistribute it and/or modify --> -<!-- it under the terms of the GNU General Public License as published by --> -<!-- the Free Software Foundation, either version 3 of the License, or --> -<!-- (at your option) any later version. --> -<!-- --> -<!-- ERT is distributed in the hope that it will be useful, but WITHOUT ANY --> -<!-- WARRANTY; without even the implied warranty of MERCHANTABILITY or --> -<!-- FITNESS FOR A PARTICULAR PURPOSE. --> -<!-- --> -<!-- See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> --> -<!-- for more details. --> - -<html> -<head> - <meta charset="utf-8"> - <link rel="stylesheet" type="text/css" href="style/plot.css"/> -</head> - -<script src="libs/d3.v3.js"></script> -<script src="scripts/styles.js"></script> -<script src="scripts/base_plot.js"></script> -<script src="scripts/base_plot_time_dimension.js"></script> -<script src="scripts/base_plot_value_dimension.js"></script> -<script src="scripts/base_plot_integer_dimension.js"></script> -<script src="scripts/render_tracker.js"></script> -<script src="scripts/canvas_plot.js"></script> -<script src="scripts/canvas_plot_line.js"></script> -<script src="scripts/canvas_plot_stippled_line.js"></script> -<script src="scripts/canvas_plot_area.js"></script> -<script src="scripts/canvas_error_bar.js"></script> -<script src="scripts/canvas_plot_circle.js"></script> -<script src="scripts/canvas_plot_legend.js"></script> - -<script> - var plot = null; - - var index_dimension = null; - var value_dimension = null; - - function initialize() { - if (!(typeof plot_data_source === 'undefined')) { - createPlot(); - updatePlot(); - plot_data_source.htmlInitialized(); - } else { - createPlot(); - plot.setData(data); - console.log("Unable to load data!"); - alert("Unable to load data!"); - } - } - - function createPlot() { - index_dimension = BasePlotIntegerDimension(); - value_dimension = BasePlotValueDimension(); - index_dimension.setUnit("Index"); - plot = new Plot(d3.select("body"), index_dimension, value_dimension); - plot.setRenderingFinishedCallback(function () { - plot_data_source.renderingFinished(); - }); - } - - function updatePlot() { - var data = plot_data_source.getPlotData(); - plot.setData(data); - value_dimension.setUnit(data.unitY()); - } - - function setSize(width, height) { - plot.resize(width, height - 75); - } - - function setScales(x_min, x_max, y_min, y_max) { - plot.setScales(x_min, x_max, y_min, y_max); - } - - function setReportStepTime(report_step_time) { - // Not supported by this plot - } - - function supportsPlotProperties(time, value, depth, index, histogram) { - return index; - } - - function getPrintWidth() { - return 1600; - } - - function getPrintHeight() { - return 1200; - } - - function setCustomSettings(settings) { - plot.setCustomSettings(settings); - STYLES.updateColors(settings); - } - - function renderNow() { - plot.renderNow(); - } - - function getPlotTitle() { - return plot.getTitle(); - } - - function xAxisType() { - return "index"; - } - - function yAxisType() { - return "value"; - } - - function isReportStepCapable() { - return false; - } - - function getXMin() { - var data = plot_data_source.getTemporaryData(); - return data.minX(); - } - - function getXMax() { - var data = plot_data_source.getTemporaryData(); - return data.maxX(); - } - - function getYMin() { - var data = plot_data_source.getTemporaryData(); - return data.minY(); - } - - function getYMax() { - var data = plot_data_source.getTemporaryData(); - return data.maxY(); - } -</script> - -<body onload="initialize();"> - -</body> - -</html> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/plots/gen_data_overview.html b/ThirdParty/Ert/devel/share/gui/plots/gen_data_overview.html deleted file mode 100644 index 7498115052..0000000000 --- a/ThirdParty/Ert/devel/share/gui/plots/gen_data_overview.html +++ /dev/null @@ -1,147 +0,0 @@ -<!DOCTYPE html> -<!-- Copyright (C) 2013 Statoil ASA, Norway. --> -<!-- --> -<!-- The file 'simple_overview_plot.html' is part of ERT - Ensemble based Reservoir Tool. --> -<!-- --> -<!-- ERT is free software: you can redistribute it and/or modify --> -<!-- it under the terms of the GNU General Public License as published by --> -<!-- the Free Software Foundation, either version 3 of the License, or --> -<!-- (at your option) any later version. --> -<!-- --> -<!-- ERT is distributed in the hope that it will be useful, but WITHOUT ANY --> -<!-- WARRANTY; without even the implied warranty of MERCHANTABILITY or --> -<!-- FITNESS FOR A PARTICULAR PURPOSE. --> -<!-- --> -<!-- See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> --> -<!-- for more details. --> - -<html> -<head> - <meta charset="utf-8"> - <link rel="stylesheet" type="text/css" href="style/plot.css"/> -</head> - -<script src="libs/d3.v3.js"></script> -<script src="scripts/styles.js"></script> -<script src="scripts/base_plot.js"></script> -<script src="scripts/base_plot_time_dimension.js"></script> -<script src="scripts/base_plot_value_dimension.js"></script> -<script src="scripts/base_plot_integer_dimension.js"></script> -<script src="scripts/canvas_plot_overview.js"></script> -<script src="scripts/canvas_plot_line.js"></script> -<script src="scripts/canvas_plot_stippled_line.js"></script> -<script src="scripts/canvas_plot_area.js"></script> -<script src="scripts/canvas_error_bar.js"></script> -<script src="scripts/canvas_plot_circle.js"></script> -<script src="scripts/canvas_plot_legend.js"></script> - -<script> - var plot = null; - - var index_dimension = null; - var value_dimension = null; - - function initialize() { - if (!(typeof plot_data_source === 'undefined')) { - createPlot(); - updatePlot(); - plot_data_source.htmlInitialized(); - } else { -// createPlot(); -// plot.setData(data); - console.log("Unable to load data!"); - alert("Unable to load data!"); - } - } - - function createPlot() { - index_dimension = BasePlotIntegerDimension(); - value_dimension = BasePlotValueDimension(); - index_dimension.setUnit("Index"); - plot = new OverviewPlot(d3.select("body"), index_dimension, value_dimension); - plot.setRenderingFinishedCallback(function() { - plot_data_source.renderingFinished(); - }); - } - - function updatePlot() { - var data = plot_data_source.getPlotData(); - plot.setData(data); - value_dimension.setUnit(data.unitY()); - } - - function setSize(width, height) { - plot.resize(width, height - 75); - } - - function setScales(x_min, x_max, y_min, y_max) { - plot.setScales(x_min, x_max, y_min, y_max); - } - - function setReportStepTime(report_step_time) { - // Not supported by this plot - } - - function supportsPlotProperties(time, value, depth, index, histogram){ - return index; - } - - function getPrintWidth(){ - return 1600; - } - - function getPrintHeight(){ - return 1200; - } - - function setCustomSettings(settings) { - plot.setCustomSettings(settings); - STYLES.updateColors(settings); - } - - function renderNow(){ - plot.renderNow(); - } - - function getPlotTitle(){ - return plot.getTitle(); - } - - function xAxisType() { - return "index"; - } - - function yAxisType() { - return "value"; - } - - function isReportStepCapable() { - return false; - } - - function getXMin() { - var data = plot_data_source.getTemporaryData(); - return data.minX(); - } - - function getXMax() { - var data = plot_data_source.getTemporaryData(); - return data.maxX(); - } - - function getYMin() { - var data = plot_data_source.getTemporaryData(); - return data.minY(); - } - - function getYMax() { - var data = plot_data_source.getTemporaryData(); - return data.maxY(); - } -</script> - -<body onload="initialize();"> - -</body> - -</html> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/plots/gen_data_statistics_plot.html b/ThirdParty/Ert/devel/share/gui/plots/gen_data_statistics_plot.html deleted file mode 100644 index 0569fb6253..0000000000 --- a/ThirdParty/Ert/devel/share/gui/plots/gen_data_statistics_plot.html +++ /dev/null @@ -1,146 +0,0 @@ -<!DOCTYPE html> -<!-- Copyright (C) 2013 Statoil ASA, Norway. --> -<!-- --> -<!-- The file 'simple_overview_plot.html' is part of ERT - Ensemble based Reservoir Tool. --> -<!-- --> -<!-- ERT is free software: you can redistribute it and/or modify --> -<!-- it under the terms of the GNU General Public License as published by --> -<!-- the Free Software Foundation, either version 3 of the License, or --> -<!-- (at your option) any later version. --> -<!-- --> -<!-- ERT is distributed in the hope that it will be useful, but WITHOUT ANY --> -<!-- WARRANTY; without even the implied warranty of MERCHANTABILITY or --> -<!-- FITNESS FOR A PARTICULAR PURPOSE. --> -<!-- --> -<!-- See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> --> -<!-- for more details. --> - -<html> -<head> - <meta charset="utf-8"> - <link rel="stylesheet" type="text/css" href="style/plot.css"/> -</head> - -<script src="libs/d3.v3.js"></script> -<script src="scripts/styles.js"></script> -<script src="scripts/base_plot.js"></script> -<script src="scripts/base_plot_integer_dimension.js"></script> -<script src="scripts/base_plot_value_dimension.js"></script> -<script src="scripts/canvas_plot_statistics.js"></script> -<script src="scripts/canvas_plot_line.js"></script> -<script src="scripts/canvas_plot_stippled_line.js"></script> -<script src="scripts/canvas_plot_area.js"></script> -<script src="scripts/canvas_error_bar.js"></script> -<script src="scripts/canvas_plot_circle.js"></script> -<script src="scripts/canvas_plot_legend.js"></script> - -<script> - var plot = null; - - var index_dimension = null; - var value_dimension = null; - - function initialize() { - if (!(typeof plot_data_source === 'undefined')) { - createPlot(); - updatePlot(); - plot_data_source.htmlInitialized(); - } else { -// createPlot(); -// plot.setData(data); - console.log("Unable to load data!"); - alert("Unable to load data!"); - } - } - - function createPlot() { - index_dimension = BasePlotIntegerDimension(); - value_dimension = BasePlotValueDimension(); - plot = new StatisticsPlot(d3.select("body"), index_dimension, value_dimension); - plot.setRenderingFinishedCallback(function() { - plot_data_source.renderingFinished(); - }); - } - - function updatePlot() { - var data = plot_data_source.getPlotData(); - plot.setData(data); - value_dimension.setUnit(data.unitY()); - } - - function setSize(width, height) { - plot.resize(width, height - 75); - } - - function setScales(x_min, x_max, y_min, y_max) { - plot.setScales(x_min, x_max, y_min, y_max); - } - - function setReportStepTime(report_step_time) { - // Not supported by this plot - } - - function supportsPlotProperties(time, value, depth, index, histogram, pca){ - return index; - } - - function getPrintWidth(){ - return 1600; - } - - function getPrintHeight(){ - return 1200; - } - - function setCustomSettings(settings) { - plot.setCustomSettings(settings); - STYLES.updateColors(settings); - } - - function renderNow(){ - plot.renderNow(); - } - - function getPlotTitle(){ - return plot.getTitle(); - } - - function xAxisType() { - return "index"; - } - - function yAxisType() { - return "value"; - } - - function isReportStepCapable() { - return false; - } - - function getXMin() { - var data = plot_data_source.getTemporaryData(); - return data.minX(); - } - - function getXMax() { - var data = plot_data_source.getTemporaryData(); - return data.maxX(); - } - - function getYMin() { - var data = plot_data_source.getTemporaryData(); - return data.minY(); - } - - function getYMax() { - var data = plot_data_source.getTemporaryData(); - return data.maxY(); - } - -</script> - -<body onload="initialize();"> - -</body> - -</html> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/plots/gen_kw.html b/ThirdParty/Ert/devel/share/gui/plots/gen_kw.html deleted file mode 100644 index b705a1867f..0000000000 --- a/ThirdParty/Ert/devel/share/gui/plots/gen_kw.html +++ /dev/null @@ -1,144 +0,0 @@ -<!DOCTYPE html> -<!-- Copyright (C) 2014 Statoil ASA, Norway. --> -<!-- --> -<!-- The file 'gen_kw.html' is part of ERT - Ensemble based Reservoir Tool. --> -<!-- --> -<!-- ERT is free software: you can redistribute it and/or modify --> -<!-- it under the terms of the GNU General Public License as published by --> -<!-- the Free Software Foundation, either version 3 of the License, or --> -<!-- (at your option) any later version. --> -<!-- --> -<!-- ERT is distributed in the hope that it will be useful, but WITHOUT ANY --> -<!-- WARRANTY; without even the implied warranty of MERCHANTABILITY or --> -<!-- FITNESS FOR A PARTICULAR PURPOSE. --> -<!-- --> -<!-- See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> --> -<!-- for more details. --> - -<html> -<head> - <meta charset="utf-8"> - <link rel="stylesheet" type="text/css" href="style/plot.css"/> -</head> - -<script src="libs/d3.v3.js"></script> -<script src="scripts/styles.js"></script> -<script src="scripts/base_plot.js"></script> -<script src="scripts/base_plot_value_dimension.js"></script> -<script src="scripts/base_plot_ordinal_dimension.js"></script> -<script src="scripts/canvas_plot_distribution.js"></script> -<script src="scripts/canvas_plot_line.js"></script> -<script src="scripts/canvas_plot_stippled_line.js"></script> -<script src="scripts/canvas_plot_area.js"></script> -<script src="scripts/canvas_error_bar.js"></script> -<script src="scripts/canvas_plot_circle.js"></script> -<script src="scripts/canvas_plot_legend.js"></script> - -<script> - var plot = null; - - var case_dimension = null; - var value_dimension = null; - - function initialize() { - if (!(typeof plot_data_source === 'undefined')) { - createPlot(); - updatePlot(); - plot_data_source.htmlInitialized(); - } else { - createPlot(); - plot.setData(data); - console.log("Unable to load data!"); - alert("Unable to load data!"); - } - } - - function createPlot() { - case_dimension = BasePlotOrdinalDimension(true); - value_dimension = BasePlotValueDimension(); - case_dimension.setUnit("Case"); - plot = new DistributionPlot(d3.select("body"), case_dimension, value_dimension); - } - - function updatePlot() { - var data = plot_data_source.getPlotData(); - plot.setData(data); - value_dimension.setUnit(data.unitY()); - } - - function setSize(width, height) { - plot.resize(width, height - 75); - } - - function setScales(x_min, x_max, y_min, y_max) { - plot.setScales(0, 1, y_min, y_max); - } - - function setReportStepTime(report_step_time) { - // Not supported by this plot - } - - function supportsPlotProperties(time, value, depth, index, histogram, pca){ - return !time && value && !depth; - } - - function getPrintWidth(){ - return 1600; - } - - function getPrintHeight(){ - return 1200; - } - - function setCustomSettings(settings) { - plot.setCustomSettings(settings); - STYLES.updateColors(settings); - } - - function renderNow(){ - plot.renderNow(); - } - - function getPlotTitle(){ - return plot.getTitle(); - } - - function xAxisType() { - return null; - } - - function yAxisType() { - return "value"; - } - - function isReportStepCapable() { - return false; - } - - function getXMin() { - var data = plot_data_source.getTemporaryData(); - return data.minX(); - } - - function getXMax() { - var data = plot_data_source.getTemporaryData(); - return data.maxX(); - } - - function getYMin() { - var data = plot_data_source.getTemporaryData(); - return data.minY(); - } - - function getYMax() { - var data = plot_data_source.getTemporaryData(); - return data.maxY(); - } - -</script> - -<body onload="initialize();"> - -</body> - -</html> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/plots/histogram.html b/ThirdParty/Ert/devel/share/gui/plots/histogram.html deleted file mode 100644 index a414542cbc..0000000000 --- a/ThirdParty/Ert/devel/share/gui/plots/histogram.html +++ /dev/null @@ -1,307 +0,0 @@ -<!DOCTYPE html> -<!-- Copyright (C) 2013 Statoil ASA, Norway. --> -<!-- --> -<!-- The file 'histogram.html' is part of ERT - Ensemble based Reservoir Tool. --> -<!-- --> -<!-- ERT is free software: you can redistribute it and/or modify --> -<!-- it under the terms of the GNU General Public License as published by --> -<!-- the Free Software Foundation, either version 3 of the License, or --> -<!-- (at your option) any later version. --> -<!-- --> -<!-- ERT is distributed in the hope that it will be useful, but WITHOUT ANY --> -<!-- WARRANTY; without even the implied warranty of MERCHANTABILITY or --> -<!-- FITNESS FOR A PARTICULAR PURPOSE. --> -<!-- --> -<!-- See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> --> -<!-- for more details. --> - -<html> -<head> - <meta charset="utf-8"> - <style> - html { - height: 100%; - } - - body { - height: 90%; - background-color: #eee; - } - - </style> - - <link rel="stylesheet" type="text/css" href="style/plot.css"/> -</head> - -<script src="libs/d3.v3.js"></script> -<script src="scripts/styles.js"></script> -<script src="scripts/canvas_plot_legend.js"></script> -<script src="scripts/canvas_plot_line.js"></script> -<script src="scripts/canvas_plot_stippled_line.js"></script> -<script src="scripts/canvas_plot_area.js"></script> -<script src="scripts/canvas_plot_circle.js"></script> -<script src="scripts/base_plot_integer_dimension.js"></script> -<script src="scripts/base_plot_value_dimension.js"></script> -<script src="scripts/histogram_renderer.js"></script> -<script src="scripts/histogram.js"></script> - -<script> - var stored_data = null; - var stored_width = 1000; - var stored_height = 500; - var stored_histogram_height = 500; - var stored_report_step_time = null; - - var histogram_div = null; - var histograms = []; - var style_count = 5; - - var count_dimension = null; - var value_dimension = null; - - var custom_min_x = null; - var custom_max_x = null; - - var custom_min_y = null; - var custom_max_y = null; - - - function initialize() { - if (!(typeof plot_data_source === 'undefined')) { - createPlot(); - updatePlot(); - plot_data_source.htmlInitialized(); - } else { -// createPlot(); -// plot.setData(data); - console.log("Unable to load data!"); - alert("Unable to load data!"); - } - } - - function createPlot() { - histogram_div = d3.select("body").append("div").attr("class", "histogram-div"); - count_dimension = BasePlotIntegerDimension(); - count_dimension.setUnit("# of realizations"); - value_dimension = BasePlotValueDimension(); - for (var index = 0; index < STYLES.ensemble_colors.length; index++) { - var histogram = new Histogram(histogram_div, value_dimension, count_dimension); - histogram.setVisible(false); - var style_name = STYLES.ensemble_colors[index]; - histogram.style(STYLES[style_name]); - - histograms.push(histogram); - } - } - - function getPrintWidth(){ - return 1200; - } - - function getPrintHeight(){ - stored_data = plot_data_source.getPlotData(); - var default_height = 425; - if (stored_data != null && stored_data.isValid()) { - var number_of_histograms = stored_data.caseList().length; - return calculateHistogramHeight(stored_height, number_of_histograms) * number_of_histograms + (12 * number_of_histograms); - } - return default_height; - - } - - - function findMaxBinCount(case_list, data) { - var bin_count = data.numberOfBins(); - - var max_bin_count = 0; - for(var index = 0; index < case_list.length; index++) { - var histogram = histograms[index]; - var case_name = case_list[index]; - - var layout = histogram.histogramLayout(bin_count); - var bins = layout(data.caseHistogram(case_name).samples()); - - for(var i = 0; i < bins.length; i++) { - max_bin_count = Math.max(max_bin_count, bins[i].y); - } - } - return max_bin_count; - } - - function updateXDomain(use_log_scale, data) { - var min_x = data.min(); - var max_x = data.max(); - - if (custom_min_x != null) { - min_x = custom_min_x; - } - - if (custom_max_x != null) { - max_x = custom_max_x; - } - - value_dimension.setIsLogScale(use_log_scale); - value_dimension.setDomain(min_x, max_x); - } - - function updateYDomain(case_list, histogram_data){ - var max_bin_count = findMaxBinCount(case_list, histogram_data); - var min_y = 0; - var max_y = max_bin_count + 1; - - if (custom_min_y != null) { - min_y = custom_min_y; - } - - if (custom_max_y != null) { - max_y = custom_max_y; - } - count_dimension.setDomain(min_y, max_y); - } - - function updatePlot() { - stored_data = plot_data_source.getPlotData(); - - if (stored_data != null && stored_data.isValid()) { - var histogram_data; - - if(stored_report_step_time == null) { - histogram_data = stored_data.histogramData(stored_data.maxX()); - } else { - histogram_data = stored_data.histogramData(stored_report_step_time); - } - - updateXDomain(stored_data.shouldUseLogScale(), histogram_data); - var case_list = stored_data.caseList(); - value_dimension.setUnit(stored_data.unitY()); - - updateYDomain(case_list, histogram_data); - - calculateSize(stored_width, stored_height); - for(var index = 0; index < case_list.length; index++) { - var histogram = histograms[index]; - histogram.setVisible(true); - histogram.setSize(stored_width, stored_histogram_height); - histogram(histogram_data, case_list[index]); - } - - for(var index = case_list.length; index < style_count; index++) { - var histogram = histograms[index]; - histogram.setVisible(false); - } - - plot_data_source.renderingFinished(); - } - } - - function calculateSize(width, height) { - stored_width = width; - stored_height = height; - - if(stored_data != null) { - var case_list = stored_data.caseList(); - var count = Math.max(case_list.length, 1); - stored_histogram_height = calculateHistogramHeight(stored_height, count); - } - } - - function calculateHistogramHeight(height, count) { - return Math.max(250, ((height - 50) - 20 * count) / count); - } - - function setSize(width, height) { - calculateSize(width, height); - - for(var i = 0; i < histograms.length; i++) { - var histogram = histograms[i]; - histogram.setSize(stored_width, stored_histogram_height); - } - } - - function setScales(x_min, x_max, y_min, y_max) { - custom_min_x = x_min; - custom_max_x = x_max; - - custom_min_y = y_min; - custom_max_y = y_max; - } - - function setReportStepTime(report_step_time) { - stored_report_step_time = report_step_time; - updatePlot(); - - } - - function supportsPlotProperties(time, value, depth, index, histogram, pca){ - return histogram; - } - - function setCustomSettings(settings) { - STYLES.updateColors(settings); - } - - function renderNow(){ - self.updatePlot(); - } - - function getPlotTitle(){ - return histograms[0].getTitle(); - } - - function xAxisType() { - return "value"; - } - - function yAxisType() { - return "count"; - } - - function isReportStepCapable() { - return true; - } - - function getXMin() { - var data = plot_data_source.getTemporaryData(); - return data.minY(); - } - - function getXMax() { - var data = plot_data_source.getTemporaryData(); - return data.maxY(); - } - - function getYMin() { - return 0; - } - - function getYMax() { - var data = plot_data_source.getTemporaryData(); - - if (data != null && data.isValid()) { - var histogram_data; - - if (stored_report_step_time == null) { - histogram_data = data.histogramData(data.maxX()); - } else { - histogram_data = data.histogramData(stored_report_step_time); - } - value_dimension.setIsLogScale(data.shouldUseLogScale()); -// value_dimension.setDomain(histogram_data.min(), histogram_data.max()); // min/max for current report step - value_dimension.setDomain(data.minY(), data.maxY()); // min/max for whole dataset - - var case_list = data.caseList(); - var max_bin_count = findMaxBinCount(case_list, histogram_data); - return max_bin_count + 1; - } - - return 1; - } - - -</script> - -<body onload="initialize();"> - -</body> - -</html> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/plots/libs/d3.v3.js b/ThirdParty/Ert/devel/share/gui/plots/libs/d3.v3.js deleted file mode 100644 index b0cb637255..0000000000 --- a/ThirdParty/Ert/devel/share/gui/plots/libs/d3.v3.js +++ /dev/null @@ -1,9274 +0,0 @@ -!function() { - var d3 = { - version: "3.4.1" - }; - if (!Date.now) Date.now = function() { - return +new Date(); - }; - var d3_arraySlice = [].slice, d3_array = function(list) { - return d3_arraySlice.call(list); - }; - var d3_document = document, d3_documentElement = d3_document.documentElement, d3_window = window; - try { - d3_array(d3_documentElement.childNodes)[0].nodeType; - } catch (e) { - d3_array = function(list) { - var i = list.length, array = new Array(i); - while (i--) array[i] = list[i]; - return array; - }; - } - try { - d3_document.createElement("div").style.setProperty("opacity", 0, ""); - } catch (error) { - var d3_element_prototype = d3_window.Element.prototype, d3_element_setAttribute = d3_element_prototype.setAttribute, d3_element_setAttributeNS = d3_element_prototype.setAttributeNS, d3_style_prototype = d3_window.CSSStyleDeclaration.prototype, d3_style_setProperty = d3_style_prototype.setProperty; - d3_element_prototype.setAttribute = function(name, value) { - d3_element_setAttribute.call(this, name, value + ""); - }; - d3_element_prototype.setAttributeNS = function(space, local, value) { - d3_element_setAttributeNS.call(this, space, local, value + ""); - }; - d3_style_prototype.setProperty = function(name, value, priority) { - d3_style_setProperty.call(this, name, value + "", priority); - }; - } - d3.ascending = function(a, b) { - return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN; - }; - d3.descending = function(a, b) { - return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN; - }; - d3.min = function(array, f) { - var i = -1, n = array.length, a, b; - if (arguments.length === 1) { - while (++i < n && !((a = array[i]) != null && a <= a)) a = undefined; - while (++i < n) if ((b = array[i]) != null && a > b) a = b; - } else { - while (++i < n && !((a = f.call(array, array[i], i)) != null && a <= a)) a = undefined; - while (++i < n) if ((b = f.call(array, array[i], i)) != null && a > b) a = b; - } - return a; - }; - d3.max = function(array, f) { - var i = -1, n = array.length, a, b; - if (arguments.length === 1) { - while (++i < n && !((a = array[i]) != null && a <= a)) a = undefined; - while (++i < n) if ((b = array[i]) != null && b > a) a = b; - } else { - while (++i < n && !((a = f.call(array, array[i], i)) != null && a <= a)) a = undefined; - while (++i < n) if ((b = f.call(array, array[i], i)) != null && b > a) a = b; - } - return a; - }; - d3.extent = function(array, f) { - var i = -1, n = array.length, a, b, c; - if (arguments.length === 1) { - while (++i < n && !((a = c = array[i]) != null && a <= a)) a = c = undefined; - while (++i < n) if ((b = array[i]) != null) { - if (a > b) a = b; - if (c < b) c = b; - } - } else { - while (++i < n && !((a = c = f.call(array, array[i], i)) != null && a <= a)) a = undefined; - while (++i < n) if ((b = f.call(array, array[i], i)) != null) { - if (a > b) a = b; - if (c < b) c = b; - } - } - return [ a, c ]; - }; - d3.sum = function(array, f) { - var s = 0, n = array.length, a, i = -1; - if (arguments.length === 1) { - while (++i < n) if (!isNaN(a = +array[i])) s += a; - } else { - while (++i < n) if (!isNaN(a = +f.call(array, array[i], i))) s += a; - } - return s; - }; - function d3_number(x) { - return x != null && !isNaN(x); - } - d3.mean = function(array, f) { - var n = array.length, a, m = 0, i = -1, j = 0; - if (arguments.length === 1) { - while (++i < n) if (d3_number(a = array[i])) m += (a - m) / ++j; - } else { - while (++i < n) if (d3_number(a = f.call(array, array[i], i))) m += (a - m) / ++j; - } - return j ? m : undefined; - }; - d3.quantile = function(values, p) { - var H = (values.length - 1) * p + 1, h = Math.floor(H), v = +values[h - 1], e = H - h; - return e ? v + e * (values[h] - v) : v; - }; - d3.median = function(array, f) { - if (arguments.length > 1) array = array.map(f); - array = array.filter(d3_number); - return array.length ? d3.quantile(array.sort(d3.ascending), .5) : undefined; - }; - d3.bisector = function(f) { - return { - left: function(a, x, lo, hi) { - if (arguments.length < 3) lo = 0; - if (arguments.length < 4) hi = a.length; - while (lo < hi) { - var mid = lo + hi >>> 1; - if (f.call(a, a[mid], mid) < x) lo = mid + 1; else hi = mid; - } - return lo; - }, - right: function(a, x, lo, hi) { - if (arguments.length < 3) lo = 0; - if (arguments.length < 4) hi = a.length; - while (lo < hi) { - var mid = lo + hi >>> 1; - if (x < f.call(a, a[mid], mid)) hi = mid; else lo = mid + 1; - } - return lo; - } - }; - }; - var d3_bisector = d3.bisector(function(d) { - return d; - }); - d3.bisectLeft = d3_bisector.left; - d3.bisect = d3.bisectRight = d3_bisector.right; - d3.shuffle = function(array) { - var m = array.length, t, i; - while (m) { - i = Math.random() * m-- | 0; - t = array[m], array[m] = array[i], array[i] = t; - } - return array; - }; - d3.permute = function(array, indexes) { - var i = indexes.length, permutes = new Array(i); - while (i--) permutes[i] = array[indexes[i]]; - return permutes; - }; - d3.pairs = function(array) { - var i = 0, n = array.length - 1, p0, p1 = array[0], pairs = new Array(n < 0 ? 0 : n); - while (i < n) pairs[i] = [ p0 = p1, p1 = array[++i] ]; - return pairs; - }; - d3.zip = function() { - if (!(n = arguments.length)) return []; - for (var i = -1, m = d3.min(arguments, d3_zipLength), zips = new Array(m); ++i < m; ) { - for (var j = -1, n, zip = zips[i] = new Array(n); ++j < n; ) { - zip[j] = arguments[j][i]; - } - } - return zips; - }; - function d3_zipLength(d) { - return d.length; - } - d3.transpose = function(matrix) { - return d3.zip.apply(d3, matrix); - }; - d3.keys = function(map) { - var keys = []; - for (var key in map) keys.push(key); - return keys; - }; - d3.values = function(map) { - var values = []; - for (var key in map) values.push(map[key]); - return values; - }; - d3.entries = function(map) { - var entries = []; - for (var key in map) entries.push({ - key: key, - value: map[key] - }); - return entries; - }; - d3.merge = function(arrays) { - var n = arrays.length, m, i = -1, j = 0, merged, array; - while (++i < n) j += arrays[i].length; - merged = new Array(j); - while (--n >= 0) { - array = arrays[n]; - m = array.length; - while (--m >= 0) { - merged[--j] = array[m]; - } - } - return merged; - }; - var abs = Math.abs; - d3.range = function(start, stop, step) { - if (arguments.length < 3) { - step = 1; - if (arguments.length < 2) { - stop = start; - start = 0; - } - } - if ((stop - start) / step === Infinity) throw new Error("infinite range"); - var range = [], k = d3_range_integerScale(abs(step)), i = -1, j; - start *= k, stop *= k, step *= k; - if (step < 0) while ((j = start + step * ++i) > stop) range.push(j / k); else while ((j = start + step * ++i) < stop) range.push(j / k); - return range; - }; - function d3_range_integerScale(x) { - var k = 1; - while (x * k % 1) k *= 10; - return k; - } - function d3_class(ctor, properties) { - try { - for (var key in properties) { - Object.defineProperty(ctor.prototype, key, { - value: properties[key], - enumerable: false - }); - } - } catch (e) { - ctor.prototype = properties; - } - } - d3.map = function(object) { - var map = new d3_Map(); - if (object instanceof d3_Map) object.forEach(function(key, value) { - map.set(key, value); - }); else for (var key in object) map.set(key, object[key]); - return map; - }; - function d3_Map() {} - d3_class(d3_Map, { - has: d3_map_has, - get: function(key) { - return this[d3_map_prefix + key]; - }, - set: function(key, value) { - return this[d3_map_prefix + key] = value; - }, - remove: d3_map_remove, - keys: d3_map_keys, - values: function() { - var values = []; - this.forEach(function(key, value) { - values.push(value); - }); - return values; - }, - entries: function() { - var entries = []; - this.forEach(function(key, value) { - entries.push({ - key: key, - value: value - }); - }); - return entries; - }, - size: d3_map_size, - empty: d3_map_empty, - forEach: function(f) { - for (var key in this) if (key.charCodeAt(0) === d3_map_prefixCode) f.call(this, key.substring(1), this[key]); - } - }); - var d3_map_prefix = "\x00", d3_map_prefixCode = d3_map_prefix.charCodeAt(0); - function d3_map_has(key) { - return d3_map_prefix + key in this; - } - function d3_map_remove(key) { - key = d3_map_prefix + key; - return key in this && delete this[key]; - } - function d3_map_keys() { - var keys = []; - this.forEach(function(key) { - keys.push(key); - }); - return keys; - } - function d3_map_size() { - var size = 0; - for (var key in this) if (key.charCodeAt(0) === d3_map_prefixCode) ++size; - return size; - } - function d3_map_empty() { - for (var key in this) if (key.charCodeAt(0) === d3_map_prefixCode) return false; - return true; - } - d3.nest = function() { - var nest = {}, keys = [], sortKeys = [], sortValues, rollup; - function map(mapType, array, depth) { - if (depth >= keys.length) return rollup ? rollup.call(nest, array) : sortValues ? array.sort(sortValues) : array; - var i = -1, n = array.length, key = keys[depth++], keyValue, object, setter, valuesByKey = new d3_Map(), values; - while (++i < n) { - if (values = valuesByKey.get(keyValue = key(object = array[i]))) { - values.push(object); - } else { - valuesByKey.set(keyValue, [ object ]); - } - } - if (mapType) { - object = mapType(); - setter = function(keyValue, values) { - object.set(keyValue, map(mapType, values, depth)); - }; - } else { - object = {}; - setter = function(keyValue, values) { - object[keyValue] = map(mapType, values, depth); - }; - } - valuesByKey.forEach(setter); - return object; - } - function entries(map, depth) { - if (depth >= keys.length) return map; - var array = [], sortKey = sortKeys[depth++]; - map.forEach(function(key, keyMap) { - array.push({ - key: key, - values: entries(keyMap, depth) - }); - }); - return sortKey ? array.sort(function(a, b) { - return sortKey(a.key, b.key); - }) : array; - } - nest.map = function(array, mapType) { - return map(mapType, array, 0); - }; - nest.entries = function(array) { - return entries(map(d3.map, array, 0), 0); - }; - nest.key = function(d) { - keys.push(d); - return nest; - }; - nest.sortKeys = function(order) { - sortKeys[keys.length - 1] = order; - return nest; - }; - nest.sortValues = function(order) { - sortValues = order; - return nest; - }; - nest.rollup = function(f) { - rollup = f; - return nest; - }; - return nest; - }; - d3.set = function(array) { - var set = new d3_Set(); - if (array) for (var i = 0, n = array.length; i < n; ++i) set.add(array[i]); - return set; - }; - function d3_Set() {} - d3_class(d3_Set, { - has: d3_map_has, - add: function(value) { - this[d3_map_prefix + value] = true; - return value; - }, - remove: function(value) { - value = d3_map_prefix + value; - return value in this && delete this[value]; - }, - values: d3_map_keys, - size: d3_map_size, - empty: d3_map_empty, - forEach: function(f) { - for (var value in this) if (value.charCodeAt(0) === d3_map_prefixCode) f.call(this, value.substring(1)); - } - }); - d3.behavior = {}; - d3.rebind = function(target, source) { - var i = 1, n = arguments.length, method; - while (++i < n) target[method = arguments[i]] = d3_rebind(target, source, source[method]); - return target; - }; - function d3_rebind(target, source, method) { - return function() { - var value = method.apply(source, arguments); - return value === source ? target : value; - }; - } - function d3_vendorSymbol(object, name) { - if (name in object) return name; - name = name.charAt(0).toUpperCase() + name.substring(1); - for (var i = 0, n = d3_vendorPrefixes.length; i < n; ++i) { - var prefixName = d3_vendorPrefixes[i] + name; - if (prefixName in object) return prefixName; - } - } - var d3_vendorPrefixes = [ "webkit", "ms", "moz", "Moz", "o", "O" ]; - function d3_noop() {} - d3.dispatch = function() { - var dispatch = new d3_dispatch(), i = -1, n = arguments.length; - while (++i < n) dispatch[arguments[i]] = d3_dispatch_event(dispatch); - return dispatch; - }; - function d3_dispatch() {} - d3_dispatch.prototype.on = function(type, listener) { - var i = type.indexOf("."), name = ""; - if (i >= 0) { - name = type.substring(i + 1); - type = type.substring(0, i); - } - if (type) return arguments.length < 2 ? this[type].on(name) : this[type].on(name, listener); - if (arguments.length === 2) { - if (listener == null) for (type in this) { - if (this.hasOwnProperty(type)) this[type].on(name, null); - } - return this; - } - }; - function d3_dispatch_event(dispatch) { - var listeners = [], listenerByName = new d3_Map(); - function event() { - var z = listeners, i = -1, n = z.length, l; - while (++i < n) if (l = z[i].on) l.apply(this, arguments); - return dispatch; - } - event.on = function(name, listener) { - var l = listenerByName.get(name), i; - if (arguments.length < 2) return l && l.on; - if (l) { - l.on = null; - listeners = listeners.slice(0, i = listeners.indexOf(l)).concat(listeners.slice(i + 1)); - listenerByName.remove(name); - } - if (listener) listeners.push(listenerByName.set(name, { - on: listener - })); - return dispatch; - }; - return event; - } - d3.event = null; - function d3_eventPreventDefault() { - d3.event.preventDefault(); - } - function d3_eventSource() { - var e = d3.event, s; - while (s = e.sourceEvent) e = s; - return e; - } - function d3_eventDispatch(target) { - var dispatch = new d3_dispatch(), i = 0, n = arguments.length; - while (++i < n) dispatch[arguments[i]] = d3_dispatch_event(dispatch); - dispatch.of = function(thiz, argumentz) { - return function(e1) { - try { - var e0 = e1.sourceEvent = d3.event; - e1.target = target; - d3.event = e1; - dispatch[e1.type].apply(thiz, argumentz); - } finally { - d3.event = e0; - } - }; - }; - return dispatch; - } - d3.requote = function(s) { - return s.replace(d3_requote_re, "\\$&"); - }; - var d3_requote_re = /[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g; - var d3_subclass = {}.__proto__ ? function(object, prototype) { - object.__proto__ = prototype; - } : function(object, prototype) { - for (var property in prototype) object[property] = prototype[property]; - }; - function d3_selection(groups) { - d3_subclass(groups, d3_selectionPrototype); - return groups; - } - var d3_select = function(s, n) { - return n.querySelector(s); - }, d3_selectAll = function(s, n) { - return n.querySelectorAll(s); - }, d3_selectMatcher = d3_documentElement[d3_vendorSymbol(d3_documentElement, "matchesSelector")], d3_selectMatches = function(n, s) { - return d3_selectMatcher.call(n, s); - }; - if (typeof Sizzle === "function") { - d3_select = function(s, n) { - return Sizzle(s, n)[0] || null; - }; - d3_selectAll = function(s, n) { - return Sizzle.uniqueSort(Sizzle(s, n)); - }; - d3_selectMatches = Sizzle.matchesSelector; - } - d3.selection = function() { - return d3_selectionRoot; - }; - var d3_selectionPrototype = d3.selection.prototype = []; - d3_selectionPrototype.select = function(selector) { - var subgroups = [], subgroup, subnode, group, node; - selector = d3_selection_selector(selector); - for (var j = -1, m = this.length; ++j < m; ) { - subgroups.push(subgroup = []); - subgroup.parentNode = (group = this[j]).parentNode; - for (var i = -1, n = group.length; ++i < n; ) { - if (node = group[i]) { - subgroup.push(subnode = selector.call(node, node.__data__, i, j)); - if (subnode && "__data__" in node) subnode.__data__ = node.__data__; - } else { - subgroup.push(null); - } - } - } - return d3_selection(subgroups); - }; - function d3_selection_selector(selector) { - return typeof selector === "function" ? selector : function() { - return d3_select(selector, this); - }; - } - d3_selectionPrototype.selectAll = function(selector) { - var subgroups = [], subgroup, node; - selector = d3_selection_selectorAll(selector); - for (var j = -1, m = this.length; ++j < m; ) { - for (var group = this[j], i = -1, n = group.length; ++i < n; ) { - if (node = group[i]) { - subgroups.push(subgroup = d3_array(selector.call(node, node.__data__, i, j))); - subgroup.parentNode = node; - } - } - } - return d3_selection(subgroups); - }; - function d3_selection_selectorAll(selector) { - return typeof selector === "function" ? selector : function() { - return d3_selectAll(selector, this); - }; - } - var d3_nsPrefix = { - svg: "http://www.w3.org/2000/svg", - xhtml: "http://www.w3.org/1999/xhtml", - xlink: "http://www.w3.org/1999/xlink", - xml: "http://www.w3.org/XML/1998/namespace", - xmlns: "http://www.w3.org/2000/xmlns/" - }; - d3.ns = { - prefix: d3_nsPrefix, - qualify: function(name) { - var i = name.indexOf(":"), prefix = name; - if (i >= 0) { - prefix = name.substring(0, i); - name = name.substring(i + 1); - } - return d3_nsPrefix.hasOwnProperty(prefix) ? { - space: d3_nsPrefix[prefix], - local: name - } : name; - } - }; - d3_selectionPrototype.attr = function(name, value) { - if (arguments.length < 2) { - if (typeof name === "string") { - var node = this.node(); - name = d3.ns.qualify(name); - return name.local ? node.getAttributeNS(name.space, name.local) : node.getAttribute(name); - } - for (value in name) this.each(d3_selection_attr(value, name[value])); - return this; - } - return this.each(d3_selection_attr(name, value)); - }; - function d3_selection_attr(name, value) { - name = d3.ns.qualify(name); - function attrNull() { - this.removeAttribute(name); - } - function attrNullNS() { - this.removeAttributeNS(name.space, name.local); - } - function attrConstant() { - this.setAttribute(name, value); - } - function attrConstantNS() { - this.setAttributeNS(name.space, name.local, value); - } - function attrFunction() { - var x = value.apply(this, arguments); - if (x == null) this.removeAttribute(name); else this.setAttribute(name, x); - } - function attrFunctionNS() { - var x = value.apply(this, arguments); - if (x == null) this.removeAttributeNS(name.space, name.local); else this.setAttributeNS(name.space, name.local, x); - } - return value == null ? name.local ? attrNullNS : attrNull : typeof value === "function" ? name.local ? attrFunctionNS : attrFunction : name.local ? attrConstantNS : attrConstant; - } - function d3_collapse(s) { - return s.trim().replace(/\s+/g, " "); - } - d3_selectionPrototype.classed = function(name, value) { - if (arguments.length < 2) { - if (typeof name === "string") { - var node = this.node(), n = (name = d3_selection_classes(name)).length, i = -1; - if (value = node.classList) { - while (++i < n) if (!value.contains(name[i])) return false; - } else { - value = node.getAttribute("class"); - while (++i < n) if (!d3_selection_classedRe(name[i]).test(value)) return false; - } - return true; - } - for (value in name) this.each(d3_selection_classed(value, name[value])); - return this; - } - return this.each(d3_selection_classed(name, value)); - }; - function d3_selection_classedRe(name) { - return new RegExp("(?:^|\\s+)" + d3.requote(name) + "(?:\\s+|$)", "g"); - } - function d3_selection_classes(name) { - return name.trim().split(/^|\s+/); - } - function d3_selection_classed(name, value) { - name = d3_selection_classes(name).map(d3_selection_classedName); - var n = name.length; - function classedConstant() { - var i = -1; - while (++i < n) name[i](this, value); - } - function classedFunction() { - var i = -1, x = value.apply(this, arguments); - while (++i < n) name[i](this, x); - } - return typeof value === "function" ? classedFunction : classedConstant; - } - function d3_selection_classedName(name) { - var re = d3_selection_classedRe(name); - return function(node, value) { - if (c = node.classList) return value ? c.add(name) : c.remove(name); - var c = node.getAttribute("class") || ""; - if (value) { - re.lastIndex = 0; - if (!re.test(c)) node.setAttribute("class", d3_collapse(c + " " + name)); - } else { - node.setAttribute("class", d3_collapse(c.replace(re, " "))); - } - }; - } - d3_selectionPrototype.style = function(name, value, priority) { - var n = arguments.length; - if (n < 3) { - if (typeof name !== "string") { - if (n < 2) value = ""; - for (priority in name) this.each(d3_selection_style(priority, name[priority], value)); - return this; - } - if (n < 2) return d3_window.getComputedStyle(this.node(), null).getPropertyValue(name); - priority = ""; - } - return this.each(d3_selection_style(name, value, priority)); - }; - function d3_selection_style(name, value, priority) { - function styleNull() { - this.style.removeProperty(name); - } - function styleConstant() { - this.style.setProperty(name, value, priority); - } - function styleFunction() { - var x = value.apply(this, arguments); - if (x == null) this.style.removeProperty(name); else this.style.setProperty(name, x, priority); - } - return value == null ? styleNull : typeof value === "function" ? styleFunction : styleConstant; - } - d3_selectionPrototype.property = function(name, value) { - if (arguments.length < 2) { - if (typeof name === "string") return this.node()[name]; - for (value in name) this.each(d3_selection_property(value, name[value])); - return this; - } - return this.each(d3_selection_property(name, value)); - }; - function d3_selection_property(name, value) { - function propertyNull() { - delete this[name]; - } - function propertyConstant() { - this[name] = value; - } - function propertyFunction() { - var x = value.apply(this, arguments); - if (x == null) delete this[name]; else this[name] = x; - } - return value == null ? propertyNull : typeof value === "function" ? propertyFunction : propertyConstant; - } - d3_selectionPrototype.text = function(value) { - return arguments.length ? this.each(typeof value === "function" ? function() { - var v = value.apply(this, arguments); - this.textContent = v == null ? "" : v; - } : value == null ? function() { - this.textContent = ""; - } : function() { - this.textContent = value; - }) : this.node().textContent; - }; - d3_selectionPrototype.html = function(value) { - return arguments.length ? this.each(typeof value === "function" ? function() { - var v = value.apply(this, arguments); - this.innerHTML = v == null ? "" : v; - } : value == null ? function() { - this.innerHTML = ""; - } : function() { - this.innerHTML = value; - }) : this.node().innerHTML; - }; - d3_selectionPrototype.append = function(name) { - name = d3_selection_creator(name); - return this.select(function() { - return this.appendChild(name.apply(this, arguments)); - }); - }; - function d3_selection_creator(name) { - return typeof name === "function" ? name : (name = d3.ns.qualify(name)).local ? function() { - return this.ownerDocument.createElementNS(name.space, name.local); - } : function() { - return this.ownerDocument.createElementNS(this.namespaceURI, name); - }; - } - d3_selectionPrototype.insert = function(name, before) { - name = d3_selection_creator(name); - before = d3_selection_selector(before); - return this.select(function() { - return this.insertBefore(name.apply(this, arguments), before.apply(this, arguments) || null); - }); - }; - d3_selectionPrototype.remove = function() { - return this.each(function() { - var parent = this.parentNode; - if (parent) parent.removeChild(this); - }); - }; - d3_selectionPrototype.data = function(value, key) { - var i = -1, n = this.length, group, node; - if (!arguments.length) { - value = new Array(n = (group = this[0]).length); - while (++i < n) { - if (node = group[i]) { - value[i] = node.__data__; - } - } - return value; - } - function bind(group, groupData) { - var i, n = group.length, m = groupData.length, n0 = Math.min(n, m), updateNodes = new Array(m), enterNodes = new Array(m), exitNodes = new Array(n), node, nodeData; - if (key) { - var nodeByKeyValue = new d3_Map(), dataByKeyValue = new d3_Map(), keyValues = [], keyValue; - for (i = -1; ++i < n; ) { - keyValue = key.call(node = group[i], node.__data__, i); - if (nodeByKeyValue.has(keyValue)) { - exitNodes[i] = node; - } else { - nodeByKeyValue.set(keyValue, node); - } - keyValues.push(keyValue); - } - for (i = -1; ++i < m; ) { - keyValue = key.call(groupData, nodeData = groupData[i], i); - if (node = nodeByKeyValue.get(keyValue)) { - updateNodes[i] = node; - node.__data__ = nodeData; - } else if (!dataByKeyValue.has(keyValue)) { - enterNodes[i] = d3_selection_dataNode(nodeData); - } - dataByKeyValue.set(keyValue, nodeData); - nodeByKeyValue.remove(keyValue); - } - for (i = -1; ++i < n; ) { - if (nodeByKeyValue.has(keyValues[i])) { - exitNodes[i] = group[i]; - } - } - } else { - for (i = -1; ++i < n0; ) { - node = group[i]; - nodeData = groupData[i]; - if (node) { - node.__data__ = nodeData; - updateNodes[i] = node; - } else { - enterNodes[i] = d3_selection_dataNode(nodeData); - } - } - for (;i < m; ++i) { - enterNodes[i] = d3_selection_dataNode(groupData[i]); - } - for (;i < n; ++i) { - exitNodes[i] = group[i]; - } - } - enterNodes.update = updateNodes; - enterNodes.parentNode = updateNodes.parentNode = exitNodes.parentNode = group.parentNode; - enter.push(enterNodes); - update.push(updateNodes); - exit.push(exitNodes); - } - var enter = d3_selection_enter([]), update = d3_selection([]), exit = d3_selection([]); - if (typeof value === "function") { - while (++i < n) { - bind(group = this[i], value.call(group, group.parentNode.__data__, i)); - } - } else { - while (++i < n) { - bind(group = this[i], value); - } - } - update.enter = function() { - return enter; - }; - update.exit = function() { - return exit; - }; - return update; - }; - function d3_selection_dataNode(data) { - return { - __data__: data - }; - } - d3_selectionPrototype.datum = function(value) { - return arguments.length ? this.property("__data__", value) : this.property("__data__"); - }; - d3_selectionPrototype.filter = function(filter) { - var subgroups = [], subgroup, group, node; - if (typeof filter !== "function") filter = d3_selection_filter(filter); - for (var j = 0, m = this.length; j < m; j++) { - subgroups.push(subgroup = []); - subgroup.parentNode = (group = this[j]).parentNode; - for (var i = 0, n = group.length; i < n; i++) { - if ((node = group[i]) && filter.call(node, node.__data__, i, j)) { - subgroup.push(node); - } - } - } - return d3_selection(subgroups); - }; - function d3_selection_filter(selector) { - return function() { - return d3_selectMatches(this, selector); - }; - } - d3_selectionPrototype.order = function() { - for (var j = -1, m = this.length; ++j < m; ) { - for (var group = this[j], i = group.length - 1, next = group[i], node; --i >= 0; ) { - if (node = group[i]) { - if (next && next !== node.nextSibling) next.parentNode.insertBefore(node, next); - next = node; - } - } - } - return this; - }; - d3_selectionPrototype.sort = function(comparator) { - comparator = d3_selection_sortComparator.apply(this, arguments); - for (var j = -1, m = this.length; ++j < m; ) this[j].sort(comparator); - return this.order(); - }; - function d3_selection_sortComparator(comparator) { - if (!arguments.length) comparator = d3.ascending; - return function(a, b) { - return a && b ? comparator(a.__data__, b.__data__) : !a - !b; - }; - } - d3_selectionPrototype.each = function(callback) { - return d3_selection_each(this, function(node, i, j) { - callback.call(node, node.__data__, i, j); - }); - }; - function d3_selection_each(groups, callback) { - for (var j = 0, m = groups.length; j < m; j++) { - for (var group = groups[j], i = 0, n = group.length, node; i < n; i++) { - if (node = group[i]) callback(node, i, j); - } - } - return groups; - } - d3_selectionPrototype.call = function(callback) { - var args = d3_array(arguments); - callback.apply(args[0] = this, args); - return this; - }; - d3_selectionPrototype.empty = function() { - return !this.node(); - }; - d3_selectionPrototype.node = function() { - for (var j = 0, m = this.length; j < m; j++) { - for (var group = this[j], i = 0, n = group.length; i < n; i++) { - var node = group[i]; - if (node) return node; - } - } - return null; - }; - d3_selectionPrototype.size = function() { - var n = 0; - this.each(function() { - ++n; - }); - return n; - }; - function d3_selection_enter(selection) { - d3_subclass(selection, d3_selection_enterPrototype); - return selection; - } - var d3_selection_enterPrototype = []; - d3.selection.enter = d3_selection_enter; - d3.selection.enter.prototype = d3_selection_enterPrototype; - d3_selection_enterPrototype.append = d3_selectionPrototype.append; - d3_selection_enterPrototype.empty = d3_selectionPrototype.empty; - d3_selection_enterPrototype.node = d3_selectionPrototype.node; - d3_selection_enterPrototype.call = d3_selectionPrototype.call; - d3_selection_enterPrototype.size = d3_selectionPrototype.size; - d3_selection_enterPrototype.select = function(selector) { - var subgroups = [], subgroup, subnode, upgroup, group, node; - for (var j = -1, m = this.length; ++j < m; ) { - upgroup = (group = this[j]).update; - subgroups.push(subgroup = []); - subgroup.parentNode = group.parentNode; - for (var i = -1, n = group.length; ++i < n; ) { - if (node = group[i]) { - subgroup.push(upgroup[i] = subnode = selector.call(group.parentNode, node.__data__, i, j)); - subnode.__data__ = node.__data__; - } else { - subgroup.push(null); - } - } - } - return d3_selection(subgroups); - }; - d3_selection_enterPrototype.insert = function(name, before) { - if (arguments.length < 2) before = d3_selection_enterInsertBefore(this); - return d3_selectionPrototype.insert.call(this, name, before); - }; - function d3_selection_enterInsertBefore(enter) { - var i0, j0; - return function(d, i, j) { - var group = enter[j].update, n = group.length, node; - if (j != j0) j0 = j, i0 = 0; - if (i >= i0) i0 = i + 1; - while (!(node = group[i0]) && ++i0 < n) ; - return node; - }; - } - d3_selectionPrototype.transition = function() { - var id = d3_transitionInheritId || ++d3_transitionId, subgroups = [], subgroup, node, transition = d3_transitionInherit || { - time: Date.now(), - ease: d3_ease_cubicInOut, - delay: 0, - duration: 250 - }; - for (var j = -1, m = this.length; ++j < m; ) { - subgroups.push(subgroup = []); - for (var group = this[j], i = -1, n = group.length; ++i < n; ) { - if (node = group[i]) d3_transitionNode(node, i, id, transition); - subgroup.push(node); - } - } - return d3_transition(subgroups, id); - }; - d3_selectionPrototype.interrupt = function() { - return this.each(d3_selection_interrupt); - }; - function d3_selection_interrupt() { - var lock = this.__transition__; - if (lock) ++lock.active; - } - d3.select = function(node) { - var group = [ typeof node === "string" ? d3_select(node, d3_document) : node ]; - group.parentNode = d3_documentElement; - return d3_selection([ group ]); - }; - d3.selectAll = function(nodes) { - var group = d3_array(typeof nodes === "string" ? d3_selectAll(nodes, d3_document) : nodes); - group.parentNode = d3_documentElement; - return d3_selection([ group ]); - }; - var d3_selectionRoot = d3.select(d3_documentElement); - d3_selectionPrototype.on = function(type, listener, capture) { - var n = arguments.length; - if (n < 3) { - if (typeof type !== "string") { - if (n < 2) listener = false; - for (capture in type) this.each(d3_selection_on(capture, type[capture], listener)); - return this; - } - if (n < 2) return (n = this.node()["__on" + type]) && n._; - capture = false; - } - return this.each(d3_selection_on(type, listener, capture)); - }; - function d3_selection_on(type, listener, capture) { - var name = "__on" + type, i = type.indexOf("."), wrap = d3_selection_onListener; - if (i > 0) type = type.substring(0, i); - var filter = d3_selection_onFilters.get(type); - if (filter) type = filter, wrap = d3_selection_onFilter; - function onRemove() { - var l = this[name]; - if (l) { - this.removeEventListener(type, l, l.$); - delete this[name]; - } - } - function onAdd() { - var l = wrap(listener, d3_array(arguments)); - onRemove.call(this); - this.addEventListener(type, this[name] = l, l.$ = capture); - l._ = listener; - } - function removeAll() { - var re = new RegExp("^__on([^.]+)" + d3.requote(type) + "$"), match; - for (var name in this) { - if (match = name.match(re)) { - var l = this[name]; - this.removeEventListener(match[1], l, l.$); - delete this[name]; - } - } - } - return i ? listener ? onAdd : onRemove : listener ? d3_noop : removeAll; - } - var d3_selection_onFilters = d3.map({ - mouseenter: "mouseover", - mouseleave: "mouseout" - }); - d3_selection_onFilters.forEach(function(k) { - if ("on" + k in d3_document) d3_selection_onFilters.remove(k); - }); - function d3_selection_onListener(listener, argumentz) { - return function(e) { - var o = d3.event; - d3.event = e; - argumentz[0] = this.__data__; - try { - listener.apply(this, argumentz); - } finally { - d3.event = o; - } - }; - } - function d3_selection_onFilter(listener, argumentz) { - var l = d3_selection_onListener(listener, argumentz); - return function(e) { - var target = this, related = e.relatedTarget; - if (!related || related !== target && !(related.compareDocumentPosition(target) & 8)) { - l.call(target, e); - } - }; - } - var d3_event_dragSelect = "onselectstart" in d3_document ? null : d3_vendorSymbol(d3_documentElement.style, "userSelect"), d3_event_dragId = 0; - function d3_event_dragSuppress() { - var name = ".dragsuppress-" + ++d3_event_dragId, click = "click" + name, w = d3.select(d3_window).on("touchmove" + name, d3_eventPreventDefault).on("dragstart" + name, d3_eventPreventDefault).on("selectstart" + name, d3_eventPreventDefault); - if (d3_event_dragSelect) { - var style = d3_documentElement.style, select = style[d3_event_dragSelect]; - style[d3_event_dragSelect] = "none"; - } - return function(suppressClick) { - w.on(name, null); - if (d3_event_dragSelect) style[d3_event_dragSelect] = select; - if (suppressClick) { - function off() { - w.on(click, null); - } - w.on(click, function() { - d3_eventPreventDefault(); - off(); - }, true); - setTimeout(off, 0); - } - }; - } - d3.mouse = function(container) { - return d3_mousePoint(container, d3_eventSource()); - }; - var d3_mouse_bug44083 = /WebKit/.test(d3_window.navigator.userAgent) ? -1 : 0; - function d3_mousePoint(container, e) { - if (e.changedTouches) e = e.changedTouches[0]; - var svg = container.ownerSVGElement || container; - if (svg.createSVGPoint) { - var point = svg.createSVGPoint(); - if (d3_mouse_bug44083 < 0 && (d3_window.scrollX || d3_window.scrollY)) { - svg = d3.select("body").append("svg").style({ - position: "absolute", - top: 0, - left: 0, - margin: 0, - padding: 0, - border: "none" - }, "important"); - var ctm = svg[0][0].getScreenCTM(); - d3_mouse_bug44083 = !(ctm.f || ctm.e); - svg.remove(); - } - if (d3_mouse_bug44083) point.x = e.pageX, point.y = e.pageY; else point.x = e.clientX, - point.y = e.clientY; - point = point.matrixTransform(container.getScreenCTM().inverse()); - return [ point.x, point.y ]; - } - var rect = container.getBoundingClientRect(); - return [ e.clientX - rect.left - container.clientLeft, e.clientY - rect.top - container.clientTop ]; - } - d3.touches = function(container, touches) { - if (arguments.length < 2) touches = d3_eventSource().touches; - return touches ? d3_array(touches).map(function(touch) { - var point = d3_mousePoint(container, touch); - point.identifier = touch.identifier; - return point; - }) : []; - }; - d3.behavior.drag = function() { - var event = d3_eventDispatch(drag, "drag", "dragstart", "dragend"), origin = null, mousedown = dragstart(d3_noop, d3.mouse, "mousemove", "mouseup"), touchstart = dragstart(touchid, touchposition, "touchmove", "touchend"); - function drag() { - this.on("mousedown.drag", mousedown).on("touchstart.drag", touchstart); - } - function touchid() { - return d3.event.changedTouches[0].identifier; - } - function touchposition(parent, id) { - return d3.touches(parent).filter(function(p) { - return p.identifier === id; - })[0]; - } - function dragstart(id, position, move, end) { - return function() { - var target = this, parent = target.parentNode, event_ = event.of(target, arguments), eventTarget = d3.event.target, eventId = id(), drag = eventId == null ? "drag" : "drag-" + eventId, origin_ = position(parent, eventId), dragged = 0, offset, w = d3.select(d3_window).on(move + "." + drag, moved).on(end + "." + drag, ended), dragRestore = d3_event_dragSuppress(); - if (origin) { - offset = origin.apply(target, arguments); - offset = [ offset.x - origin_[0], offset.y - origin_[1] ]; - } else { - offset = [ 0, 0 ]; - } - event_({ - type: "dragstart" - }); - function moved() { - var p = position(parent, eventId), dx = p[0] - origin_[0], dy = p[1] - origin_[1]; - dragged |= dx | dy; - origin_ = p; - event_({ - type: "drag", - x: p[0] + offset[0], - y: p[1] + offset[1], - dx: dx, - dy: dy - }); - } - function ended() { - w.on(move + "." + drag, null).on(end + "." + drag, null); - dragRestore(dragged && d3.event.target === eventTarget); - event_({ - type: "dragend" - }); - } - }; - } - drag.origin = function(x) { - if (!arguments.length) return origin; - origin = x; - return drag; - }; - return d3.rebind(drag, event, "on"); - }; - var Ï€ = Math.PI, Ï„ = 2 * Ï€, halfÏ€ = Ï€ / 2, ε = 1e-6, ε2 = ε * ε, d3_radians = Ï€ / 180, d3_degrees = 180 / Ï€; - function d3_sgn(x) { - return x > 0 ? 1 : x < 0 ? -1 : 0; - } - function d3_cross2d(a, b, c) { - return (b[0] - a[0]) * (c[1] - a[1]) - (b[1] - a[1]) * (c[0] - a[0]); - } - function d3_acos(x) { - return x > 1 ? 0 : x < -1 ? Ï€ : Math.acos(x); - } - function d3_asin(x) { - return x > 1 ? halfÏ€ : x < -1 ? -halfÏ€ : Math.asin(x); - } - function d3_sinh(x) { - return ((x = Math.exp(x)) - 1 / x) / 2; - } - function d3_cosh(x) { - return ((x = Math.exp(x)) + 1 / x) / 2; - } - function d3_tanh(x) { - return ((x = Math.exp(2 * x)) - 1) / (x + 1); - } - function d3_haversin(x) { - return (x = Math.sin(x / 2)) * x; - } - var Ï = Math.SQRT2, Ï2 = 2, Ï4 = 4; - d3.interpolateZoom = function(p0, p1) { - var ux0 = p0[0], uy0 = p0[1], w0 = p0[2], ux1 = p1[0], uy1 = p1[1], w1 = p1[2]; - var dx = ux1 - ux0, dy = uy1 - uy0, d2 = dx * dx + dy * dy, d1 = Math.sqrt(d2), b0 = (w1 * w1 - w0 * w0 + Ï4 * d2) / (2 * w0 * Ï2 * d1), b1 = (w1 * w1 - w0 * w0 - Ï4 * d2) / (2 * w1 * Ï2 * d1), r0 = Math.log(Math.sqrt(b0 * b0 + 1) - b0), r1 = Math.log(Math.sqrt(b1 * b1 + 1) - b1), dr = r1 - r0, S = (dr || Math.log(w1 / w0)) / Ï; - function interpolate(t) { - var s = t * S; - if (dr) { - var coshr0 = d3_cosh(r0), u = w0 / (Ï2 * d1) * (coshr0 * d3_tanh(Ï * s + r0) - d3_sinh(r0)); - return [ ux0 + u * dx, uy0 + u * dy, w0 * coshr0 / d3_cosh(Ï * s + r0) ]; - } - return [ ux0 + t * dx, uy0 + t * dy, w0 * Math.exp(Ï * s) ]; - } - interpolate.duration = S * 1e3; - return interpolate; - }; - d3.behavior.zoom = function() { - var view = { - x: 0, - y: 0, - k: 1 - }, translate0, center, size = [ 960, 500 ], scaleExtent = d3_behavior_zoomInfinity, mousedown = "mousedown.zoom", mousemove = "mousemove.zoom", mouseup = "mouseup.zoom", mousewheelTimer, touchstart = "touchstart.zoom", touchtime, event = d3_eventDispatch(zoom, "zoomstart", "zoom", "zoomend"), x0, x1, y0, y1; - function zoom(g) { - g.on(mousedown, mousedowned).on(d3_behavior_zoomWheel + ".zoom", mousewheeled).on(mousemove, mousewheelreset).on("dblclick.zoom", dblclicked).on(touchstart, touchstarted); - } - zoom.event = function(g) { - g.each(function() { - var event_ = event.of(this, arguments), view1 = view; - if (d3_transitionInheritId) { - d3.select(this).transition().each("start.zoom", function() { - view = this.__chart__ || { - x: 0, - y: 0, - k: 1 - }; - zoomstarted(event_); - }).tween("zoom:zoom", function() { - var dx = size[0], dy = size[1], cx = dx / 2, cy = dy / 2, i = d3.interpolateZoom([ (cx - view.x) / view.k, (cy - view.y) / view.k, dx / view.k ], [ (cx - view1.x) / view1.k, (cy - view1.y) / view1.k, dx / view1.k ]); - return function(t) { - var l = i(t), k = dx / l[2]; - this.__chart__ = view = { - x: cx - l[0] * k, - y: cy - l[1] * k, - k: k - }; - zoomed(event_); - }; - }).each("end.zoom", function() { - zoomended(event_); - }); - } else { - this.__chart__ = view; - zoomstarted(event_); - zoomed(event_); - zoomended(event_); - } - }); - }; - zoom.translate = function(_) { - if (!arguments.length) return [ view.x, view.y ]; - view = { - x: +_[0], - y: +_[1], - k: view.k - }; - rescale(); - return zoom; - }; - zoom.scale = function(_) { - if (!arguments.length) return view.k; - view = { - x: view.x, - y: view.y, - k: +_ - }; - rescale(); - return zoom; - }; - zoom.scaleExtent = function(_) { - if (!arguments.length) return scaleExtent; - scaleExtent = _ == null ? d3_behavior_zoomInfinity : [ +_[0], +_[1] ]; - return zoom; - }; - zoom.center = function(_) { - if (!arguments.length) return center; - center = _ && [ +_[0], +_[1] ]; - return zoom; - }; - zoom.size = function(_) { - if (!arguments.length) return size; - size = _ && [ +_[0], +_[1] ]; - return zoom; - }; - zoom.x = function(z) { - if (!arguments.length) return x1; - x1 = z; - x0 = z.copy(); - view = { - x: 0, - y: 0, - k: 1 - }; - return zoom; - }; - zoom.y = function(z) { - if (!arguments.length) return y1; - y1 = z; - y0 = z.copy(); - view = { - x: 0, - y: 0, - k: 1 - }; - return zoom; - }; - function location(p) { - return [ (p[0] - view.x) / view.k, (p[1] - view.y) / view.k ]; - } - function point(l) { - return [ l[0] * view.k + view.x, l[1] * view.k + view.y ]; - } - function scaleTo(s) { - view.k = Math.max(scaleExtent[0], Math.min(scaleExtent[1], s)); - } - function translateTo(p, l) { - l = point(l); - view.x += p[0] - l[0]; - view.y += p[1] - l[1]; - } - function rescale() { - if (x1) x1.domain(x0.range().map(function(x) { - return (x - view.x) / view.k; - }).map(x0.invert)); - if (y1) y1.domain(y0.range().map(function(y) { - return (y - view.y) / view.k; - }).map(y0.invert)); - } - function zoomstarted(event) { - event({ - type: "zoomstart" - }); - } - function zoomed(event) { - rescale(); - event({ - type: "zoom", - scale: view.k, - translate: [ view.x, view.y ] - }); - } - function zoomended(event) { - event({ - type: "zoomend" - }); - } - function mousedowned() { - var target = this, event_ = event.of(target, arguments), eventTarget = d3.event.target, dragged = 0, w = d3.select(d3_window).on(mousemove, moved).on(mouseup, ended), l = location(d3.mouse(target)), dragRestore = d3_event_dragSuppress(); - d3_selection_interrupt.call(target); - zoomstarted(event_); - function moved() { - dragged = 1; - translateTo(d3.mouse(target), l); - zoomed(event_); - } - function ended() { - w.on(mousemove, d3_window === target ? mousewheelreset : null).on(mouseup, null); - dragRestore(dragged && d3.event.target === eventTarget); - zoomended(event_); - } - } - function touchstarted() { - var target = this, event_ = event.of(target, arguments), locations0 = {}, distance0 = 0, scale0, eventId = d3.event.changedTouches[0].identifier, touchmove = "touchmove.zoom-" + eventId, touchend = "touchend.zoom-" + eventId, w = d3.select(d3_window).on(touchmove, moved).on(touchend, ended), t = d3.select(target).on(mousedown, null).on(touchstart, started), dragRestore = d3_event_dragSuppress(); - d3_selection_interrupt.call(target); - started(); - zoomstarted(event_); - function relocate() { - var touches = d3.touches(target); - scale0 = view.k; - touches.forEach(function(t) { - if (t.identifier in locations0) locations0[t.identifier] = location(t); - }); - return touches; - } - function started() { - var changed = d3.event.changedTouches; - for (var i = 0, n = changed.length; i < n; ++i) { - locations0[changed[i].identifier] = null; - } - var touches = relocate(), now = Date.now(); - if (touches.length === 1) { - if (now - touchtime < 500) { - var p = touches[0], l = locations0[p.identifier]; - scaleTo(view.k * 2); - translateTo(p, l); - d3_eventPreventDefault(); - zoomed(event_); - } - touchtime = now; - } else if (touches.length > 1) { - var p = touches[0], q = touches[1], dx = p[0] - q[0], dy = p[1] - q[1]; - distance0 = dx * dx + dy * dy; - } - } - function moved() { - var touches = d3.touches(target), p0, l0, p1, l1; - for (var i = 0, n = touches.length; i < n; ++i, l1 = null) { - p1 = touches[i]; - if (l1 = locations0[p1.identifier]) { - if (l0) break; - p0 = p1, l0 = l1; - } - } - if (l1) { - var distance1 = (distance1 = p1[0] - p0[0]) * distance1 + (distance1 = p1[1] - p0[1]) * distance1, scale1 = distance0 && Math.sqrt(distance1 / distance0); - p0 = [ (p0[0] + p1[0]) / 2, (p0[1] + p1[1]) / 2 ]; - l0 = [ (l0[0] + l1[0]) / 2, (l0[1] + l1[1]) / 2 ]; - scaleTo(scale1 * scale0); - } - touchtime = null; - translateTo(p0, l0); - zoomed(event_); - } - function ended() { - if (d3.event.touches.length) { - var changed = d3.event.changedTouches; - for (var i = 0, n = changed.length; i < n; ++i) { - delete locations0[changed[i].identifier]; - } - for (var identifier in locations0) { - return void relocate(); - } - } - w.on(touchmove, null).on(touchend, null); - t.on(mousedown, mousedowned).on(touchstart, touchstarted); - dragRestore(); - zoomended(event_); - } - } - function mousewheeled() { - var event_ = event.of(this, arguments); - if (mousewheelTimer) clearTimeout(mousewheelTimer); else d3_selection_interrupt.call(this), - zoomstarted(event_); - mousewheelTimer = setTimeout(function() { - mousewheelTimer = null; - zoomended(event_); - }, 50); - d3_eventPreventDefault(); - var point = center || d3.mouse(this); - if (!translate0) translate0 = location(point); - scaleTo(Math.pow(2, d3_behavior_zoomDelta() * .002) * view.k); - translateTo(point, translate0); - zoomed(event_); - } - function mousewheelreset() { - translate0 = null; - } - function dblclicked() { - var event_ = event.of(this, arguments), p = d3.mouse(this), l = location(p), k = Math.log(view.k) / Math.LN2; - zoomstarted(event_); - scaleTo(Math.pow(2, d3.event.shiftKey ? Math.ceil(k) - 1 : Math.floor(k) + 1)); - translateTo(p, l); - zoomed(event_); - zoomended(event_); - } - return d3.rebind(zoom, event, "on"); - }; - var d3_behavior_zoomInfinity = [ 0, Infinity ]; - var d3_behavior_zoomDelta, d3_behavior_zoomWheel = "onwheel" in d3_document ? (d3_behavior_zoomDelta = function() { - return -d3.event.deltaY * (d3.event.deltaMode ? 120 : 1); - }, "wheel") : "onmousewheel" in d3_document ? (d3_behavior_zoomDelta = function() { - return d3.event.wheelDelta; - }, "mousewheel") : (d3_behavior_zoomDelta = function() { - return -d3.event.detail; - }, "MozMousePixelScroll"); - function d3_Color() {} - d3_Color.prototype.toString = function() { - return this.rgb() + ""; - }; - d3.hsl = function(h, s, l) { - return arguments.length === 1 ? h instanceof d3_Hsl ? d3_hsl(h.h, h.s, h.l) : d3_rgb_parse("" + h, d3_rgb_hsl, d3_hsl) : d3_hsl(+h, +s, +l); - }; - function d3_hsl(h, s, l) { - return new d3_Hsl(h, s, l); - } - function d3_Hsl(h, s, l) { - this.h = h; - this.s = s; - this.l = l; - } - var d3_hslPrototype = d3_Hsl.prototype = new d3_Color(); - d3_hslPrototype.brighter = function(k) { - k = Math.pow(.7, arguments.length ? k : 1); - return d3_hsl(this.h, this.s, this.l / k); - }; - d3_hslPrototype.darker = function(k) { - k = Math.pow(.7, arguments.length ? k : 1); - return d3_hsl(this.h, this.s, k * this.l); - }; - d3_hslPrototype.rgb = function() { - return d3_hsl_rgb(this.h, this.s, this.l); - }; - function d3_hsl_rgb(h, s, l) { - var m1, m2; - h = isNaN(h) ? 0 : (h %= 360) < 0 ? h + 360 : h; - s = isNaN(s) ? 0 : s < 0 ? 0 : s > 1 ? 1 : s; - l = l < 0 ? 0 : l > 1 ? 1 : l; - m2 = l <= .5 ? l * (1 + s) : l + s - l * s; - m1 = 2 * l - m2; - function v(h) { - if (h > 360) h -= 360; else if (h < 0) h += 360; - if (h < 60) return m1 + (m2 - m1) * h / 60; - if (h < 180) return m2; - if (h < 240) return m1 + (m2 - m1) * (240 - h) / 60; - return m1; - } - function vv(h) { - return Math.round(v(h) * 255); - } - return d3_rgb(vv(h + 120), vv(h), vv(h - 120)); - } - d3.hcl = function(h, c, l) { - return arguments.length === 1 ? h instanceof d3_Hcl ? d3_hcl(h.h, h.c, h.l) : h instanceof d3_Lab ? d3_lab_hcl(h.l, h.a, h.b) : d3_lab_hcl((h = d3_rgb_lab((h = d3.rgb(h)).r, h.g, h.b)).l, h.a, h.b) : d3_hcl(+h, +c, +l); - }; - function d3_hcl(h, c, l) { - return new d3_Hcl(h, c, l); - } - function d3_Hcl(h, c, l) { - this.h = h; - this.c = c; - this.l = l; - } - var d3_hclPrototype = d3_Hcl.prototype = new d3_Color(); - d3_hclPrototype.brighter = function(k) { - return d3_hcl(this.h, this.c, Math.min(100, this.l + d3_lab_K * (arguments.length ? k : 1))); - }; - d3_hclPrototype.darker = function(k) { - return d3_hcl(this.h, this.c, Math.max(0, this.l - d3_lab_K * (arguments.length ? k : 1))); - }; - d3_hclPrototype.rgb = function() { - return d3_hcl_lab(this.h, this.c, this.l).rgb(); - }; - function d3_hcl_lab(h, c, l) { - if (isNaN(h)) h = 0; - if (isNaN(c)) c = 0; - return d3_lab(l, Math.cos(h *= d3_radians) * c, Math.sin(h) * c); - } - d3.lab = function(l, a, b) { - return arguments.length === 1 ? l instanceof d3_Lab ? d3_lab(l.l, l.a, l.b) : l instanceof d3_Hcl ? d3_hcl_lab(l.l, l.c, l.h) : d3_rgb_lab((l = d3.rgb(l)).r, l.g, l.b) : d3_lab(+l, +a, +b); - }; - function d3_lab(l, a, b) { - return new d3_Lab(l, a, b); - } - function d3_Lab(l, a, b) { - this.l = l; - this.a = a; - this.b = b; - } - var d3_lab_K = 18; - var d3_lab_X = .95047, d3_lab_Y = 1, d3_lab_Z = 1.08883; - var d3_labPrototype = d3_Lab.prototype = new d3_Color(); - d3_labPrototype.brighter = function(k) { - return d3_lab(Math.min(100, this.l + d3_lab_K * (arguments.length ? k : 1)), this.a, this.b); - }; - d3_labPrototype.darker = function(k) { - return d3_lab(Math.max(0, this.l - d3_lab_K * (arguments.length ? k : 1)), this.a, this.b); - }; - d3_labPrototype.rgb = function() { - return d3_lab_rgb(this.l, this.a, this.b); - }; - function d3_lab_rgb(l, a, b) { - var y = (l + 16) / 116, x = y + a / 500, z = y - b / 200; - x = d3_lab_xyz(x) * d3_lab_X; - y = d3_lab_xyz(y) * d3_lab_Y; - z = d3_lab_xyz(z) * d3_lab_Z; - return d3_rgb(d3_xyz_rgb(3.2404542 * x - 1.5371385 * y - .4985314 * z), d3_xyz_rgb(-.969266 * x + 1.8760108 * y + .041556 * z), d3_xyz_rgb(.0556434 * x - .2040259 * y + 1.0572252 * z)); - } - function d3_lab_hcl(l, a, b) { - return l > 0 ? d3_hcl(Math.atan2(b, a) * d3_degrees, Math.sqrt(a * a + b * b), l) : d3_hcl(NaN, NaN, l); - } - function d3_lab_xyz(x) { - return x > .206893034 ? x * x * x : (x - 4 / 29) / 7.787037; - } - function d3_xyz_lab(x) { - return x > .008856 ? Math.pow(x, 1 / 3) : 7.787037 * x + 4 / 29; - } - function d3_xyz_rgb(r) { - return Math.round(255 * (r <= .00304 ? 12.92 * r : 1.055 * Math.pow(r, 1 / 2.4) - .055)); - } - d3.rgb = function(r, g, b) { - return arguments.length === 1 ? r instanceof d3_Rgb ? d3_rgb(r.r, r.g, r.b) : d3_rgb_parse("" + r, d3_rgb, d3_hsl_rgb) : d3_rgb(~~r, ~~g, ~~b); - }; - function d3_rgbNumber(value) { - return d3_rgb(value >> 16, value >> 8 & 255, value & 255); - } - function d3_rgbString(value) { - return d3_rgbNumber(value) + ""; - } - function d3_rgb(r, g, b) { - return new d3_Rgb(r, g, b); - } - function d3_Rgb(r, g, b) { - this.r = r; - this.g = g; - this.b = b; - } - var d3_rgbPrototype = d3_Rgb.prototype = new d3_Color(); - d3_rgbPrototype.brighter = function(k) { - k = Math.pow(.7, arguments.length ? k : 1); - var r = this.r, g = this.g, b = this.b, i = 30; - if (!r && !g && !b) return d3_rgb(i, i, i); - if (r && r < i) r = i; - if (g && g < i) g = i; - if (b && b < i) b = i; - return d3_rgb(Math.min(255, ~~(r / k)), Math.min(255, ~~(g / k)), Math.min(255, ~~(b / k))); - }; - d3_rgbPrototype.darker = function(k) { - k = Math.pow(.7, arguments.length ? k : 1); - return d3_rgb(~~(k * this.r), ~~(k * this.g), ~~(k * this.b)); - }; - d3_rgbPrototype.hsl = function() { - return d3_rgb_hsl(this.r, this.g, this.b); - }; - d3_rgbPrototype.toString = function() { - return "#" + d3_rgb_hex(this.r) + d3_rgb_hex(this.g) + d3_rgb_hex(this.b); - }; - function d3_rgb_hex(v) { - return v < 16 ? "0" + Math.max(0, v).toString(16) : Math.min(255, v).toString(16); - } - function d3_rgb_parse(format, rgb, hsl) { - var r = 0, g = 0, b = 0, m1, m2, name; - m1 = /([a-z]+)\((.*)\)/i.exec(format); - if (m1) { - m2 = m1[2].split(","); - switch (m1[1]) { - case "hsl": - { - return hsl(parseFloat(m2[0]), parseFloat(m2[1]) / 100, parseFloat(m2[2]) / 100); - } - - case "rgb": - { - return rgb(d3_rgb_parseNumber(m2[0]), d3_rgb_parseNumber(m2[1]), d3_rgb_parseNumber(m2[2])); - } - } - } - if (name = d3_rgb_names.get(format)) return rgb(name.r, name.g, name.b); - if (format != null && format.charAt(0) === "#") { - if (format.length === 4) { - r = format.charAt(1); - r += r; - g = format.charAt(2); - g += g; - b = format.charAt(3); - b += b; - } else if (format.length === 7) { - r = format.substring(1, 3); - g = format.substring(3, 5); - b = format.substring(5, 7); - } - r = parseInt(r, 16); - g = parseInt(g, 16); - b = parseInt(b, 16); - } - return rgb(r, g, b); - } - function d3_rgb_hsl(r, g, b) { - var min = Math.min(r /= 255, g /= 255, b /= 255), max = Math.max(r, g, b), d = max - min, h, s, l = (max + min) / 2; - if (d) { - s = l < .5 ? d / (max + min) : d / (2 - max - min); - if (r == max) h = (g - b) / d + (g < b ? 6 : 0); else if (g == max) h = (b - r) / d + 2; else h = (r - g) / d + 4; - h *= 60; - } else { - h = NaN; - s = l > 0 && l < 1 ? 0 : h; - } - return d3_hsl(h, s, l); - } - function d3_rgb_lab(r, g, b) { - r = d3_rgb_xyz(r); - g = d3_rgb_xyz(g); - b = d3_rgb_xyz(b); - var x = d3_xyz_lab((.4124564 * r + .3575761 * g + .1804375 * b) / d3_lab_X), y = d3_xyz_lab((.2126729 * r + .7151522 * g + .072175 * b) / d3_lab_Y), z = d3_xyz_lab((.0193339 * r + .119192 * g + .9503041 * b) / d3_lab_Z); - return d3_lab(116 * y - 16, 500 * (x - y), 200 * (y - z)); - } - function d3_rgb_xyz(r) { - return (r /= 255) <= .04045 ? r / 12.92 : Math.pow((r + .055) / 1.055, 2.4); - } - function d3_rgb_parseNumber(c) { - var f = parseFloat(c); - return c.charAt(c.length - 1) === "%" ? Math.round(f * 2.55) : f; - } - var d3_rgb_names = d3.map({ - aliceblue: 15792383, - antiquewhite: 16444375, - aqua: 65535, - aquamarine: 8388564, - azure: 15794175, - beige: 16119260, - bisque: 16770244, - black: 0, - blanchedalmond: 16772045, - blue: 255, - blueviolet: 9055202, - brown: 10824234, - burlywood: 14596231, - cadetblue: 6266528, - chartreuse: 8388352, - chocolate: 13789470, - coral: 16744272, - cornflowerblue: 6591981, - cornsilk: 16775388, - crimson: 14423100, - cyan: 65535, - darkblue: 139, - darkcyan: 35723, - darkgoldenrod: 12092939, - darkgray: 11119017, - darkgreen: 25600, - darkgrey: 11119017, - darkkhaki: 12433259, - darkmagenta: 9109643, - darkolivegreen: 5597999, - darkorange: 16747520, - darkorchid: 10040012, - darkred: 9109504, - darksalmon: 15308410, - darkseagreen: 9419919, - darkslateblue: 4734347, - darkslategray: 3100495, - darkslategrey: 3100495, - darkturquoise: 52945, - darkviolet: 9699539, - deeppink: 16716947, - deepskyblue: 49151, - dimgray: 6908265, - dimgrey: 6908265, - dodgerblue: 2003199, - firebrick: 11674146, - floralwhite: 16775920, - forestgreen: 2263842, - fuchsia: 16711935, - gainsboro: 14474460, - ghostwhite: 16316671, - gold: 16766720, - goldenrod: 14329120, - gray: 8421504, - green: 32768, - greenyellow: 11403055, - grey: 8421504, - honeydew: 15794160, - hotpink: 16738740, - indianred: 13458524, - indigo: 4915330, - ivory: 16777200, - khaki: 15787660, - lavender: 15132410, - lavenderblush: 16773365, - lawngreen: 8190976, - lemonchiffon: 16775885, - lightblue: 11393254, - lightcoral: 15761536, - lightcyan: 14745599, - lightgoldenrodyellow: 16448210, - lightgray: 13882323, - lightgreen: 9498256, - lightgrey: 13882323, - lightpink: 16758465, - lightsalmon: 16752762, - lightseagreen: 2142890, - lightskyblue: 8900346, - lightslategray: 7833753, - lightslategrey: 7833753, - lightsteelblue: 11584734, - lightyellow: 16777184, - lime: 65280, - limegreen: 3329330, - linen: 16445670, - magenta: 16711935, - maroon: 8388608, - mediumaquamarine: 6737322, - mediumblue: 205, - mediumorchid: 12211667, - mediumpurple: 9662683, - mediumseagreen: 3978097, - mediumslateblue: 8087790, - mediumspringgreen: 64154, - mediumturquoise: 4772300, - mediumvioletred: 13047173, - midnightblue: 1644912, - mintcream: 16121850, - mistyrose: 16770273, - moccasin: 16770229, - navajowhite: 16768685, - navy: 128, - oldlace: 16643558, - olive: 8421376, - olivedrab: 7048739, - orange: 16753920, - orangered: 16729344, - orchid: 14315734, - palegoldenrod: 15657130, - palegreen: 10025880, - paleturquoise: 11529966, - palevioletred: 14381203, - papayawhip: 16773077, - peachpuff: 16767673, - peru: 13468991, - pink: 16761035, - plum: 14524637, - powderblue: 11591910, - purple: 8388736, - red: 16711680, - rosybrown: 12357519, - royalblue: 4286945, - saddlebrown: 9127187, - salmon: 16416882, - sandybrown: 16032864, - seagreen: 3050327, - seashell: 16774638, - sienna: 10506797, - silver: 12632256, - skyblue: 8900331, - slateblue: 6970061, - slategray: 7372944, - slategrey: 7372944, - snow: 16775930, - springgreen: 65407, - steelblue: 4620980, - tan: 13808780, - teal: 32896, - thistle: 14204888, - tomato: 16737095, - turquoise: 4251856, - violet: 15631086, - wheat: 16113331, - white: 16777215, - whitesmoke: 16119285, - yellow: 16776960, - yellowgreen: 10145074 - }); - d3_rgb_names.forEach(function(key, value) { - d3_rgb_names.set(key, d3_rgbNumber(value)); - }); - function d3_functor(v) { - return typeof v === "function" ? v : function() { - return v; - }; - } - d3.functor = d3_functor; - function d3_identity(d) { - return d; - } - d3.xhr = d3_xhrType(d3_identity); - function d3_xhrType(response) { - return function(url, mimeType, callback) { - if (arguments.length === 2 && typeof mimeType === "function") callback = mimeType, - mimeType = null; - return d3_xhr(url, mimeType, response, callback); - }; - } - function d3_xhr(url, mimeType, response, callback) { - var xhr = {}, dispatch = d3.dispatch("beforesend", "progress", "load", "error"), headers = {}, request = new XMLHttpRequest(), responseType = null; - if (d3_window.XDomainRequest && !("withCredentials" in request) && /^(http(s)?:)?\/\//.test(url)) request = new XDomainRequest(); - "onload" in request ? request.onload = request.onerror = respond : request.onreadystatechange = function() { - request.readyState > 3 && respond(); - }; - function respond() { - var status = request.status, result; - if (!status && request.responseText || status >= 200 && status < 300 || status === 304) { - try { - result = response.call(xhr, request); - } catch (e) { - dispatch.error.call(xhr, e); - return; - } - dispatch.load.call(xhr, result); - } else { - dispatch.error.call(xhr, request); - } - } - request.onprogress = function(event) { - var o = d3.event; - d3.event = event; - try { - dispatch.progress.call(xhr, request); - } finally { - d3.event = o; - } - }; - xhr.header = function(name, value) { - name = (name + "").toLowerCase(); - if (arguments.length < 2) return headers[name]; - if (value == null) delete headers[name]; else headers[name] = value + ""; - return xhr; - }; - xhr.mimeType = function(value) { - if (!arguments.length) return mimeType; - mimeType = value == null ? null : value + ""; - return xhr; - }; - xhr.responseType = function(value) { - if (!arguments.length) return responseType; - responseType = value; - return xhr; - }; - xhr.response = function(value) { - response = value; - return xhr; - }; - [ "get", "post" ].forEach(function(method) { - xhr[method] = function() { - return xhr.send.apply(xhr, [ method ].concat(d3_array(arguments))); - }; - }); - xhr.send = function(method, data, callback) { - if (arguments.length === 2 && typeof data === "function") callback = data, data = null; - request.open(method, url, true); - if (mimeType != null && !("accept" in headers)) headers["accept"] = mimeType + ",*/*"; - if (request.setRequestHeader) for (var name in headers) request.setRequestHeader(name, headers[name]); - if (mimeType != null && request.overrideMimeType) request.overrideMimeType(mimeType); - if (responseType != null) request.responseType = responseType; - if (callback != null) xhr.on("error", callback).on("load", function(request) { - callback(null, request); - }); - dispatch.beforesend.call(xhr, request); - request.send(data == null ? null : data); - return xhr; - }; - xhr.abort = function() { - request.abort(); - return xhr; - }; - d3.rebind(xhr, dispatch, "on"); - return callback == null ? xhr : xhr.get(d3_xhr_fixCallback(callback)); - } - function d3_xhr_fixCallback(callback) { - return callback.length === 1 ? function(error, request) { - callback(error == null ? request : null); - } : callback; - } - d3.dsv = function(delimiter, mimeType) { - var reFormat = new RegExp('["' + delimiter + "\n]"), delimiterCode = delimiter.charCodeAt(0); - function dsv(url, row, callback) { - if (arguments.length < 3) callback = row, row = null; - var xhr = d3_xhr(url, mimeType, row == null ? response : typedResponse(row), callback); - xhr.row = function(_) { - return arguments.length ? xhr.response((row = _) == null ? response : typedResponse(_)) : row; - }; - return xhr; - } - function response(request) { - return dsv.parse(request.responseText); - } - function typedResponse(f) { - return function(request) { - return dsv.parse(request.responseText, f); - }; - } - dsv.parse = function(text, f) { - var o; - return dsv.parseRows(text, function(row, i) { - if (o) return o(row, i - 1); - var a = new Function("d", "return {" + row.map(function(name, i) { - return JSON.stringify(name) + ": d[" + i + "]"; - }).join(",") + "}"); - o = f ? function(row, i) { - return f(a(row), i); - } : a; - }); - }; - dsv.parseRows = function(text, f) { - var EOL = {}, EOF = {}, rows = [], N = text.length, I = 0, n = 0, t, eol; - function token() { - if (I >= N) return EOF; - if (eol) return eol = false, EOL; - var j = I; - if (text.charCodeAt(j) === 34) { - var i = j; - while (i++ < N) { - if (text.charCodeAt(i) === 34) { - if (text.charCodeAt(i + 1) !== 34) break; - ++i; - } - } - I = i + 2; - var c = text.charCodeAt(i + 1); - if (c === 13) { - eol = true; - if (text.charCodeAt(i + 2) === 10) ++I; - } else if (c === 10) { - eol = true; - } - return text.substring(j + 1, i).replace(/""/g, '"'); - } - while (I < N) { - var c = text.charCodeAt(I++), k = 1; - if (c === 10) eol = true; else if (c === 13) { - eol = true; - if (text.charCodeAt(I) === 10) ++I, ++k; - } else if (c !== delimiterCode) continue; - return text.substring(j, I - k); - } - return text.substring(j); - } - while ((t = token()) !== EOF) { - var a = []; - while (t !== EOL && t !== EOF) { - a.push(t); - t = token(); - } - if (f && !(a = f(a, n++))) continue; - rows.push(a); - } - return rows; - }; - dsv.format = function(rows) { - if (Array.isArray(rows[0])) return dsv.formatRows(rows); - var fieldSet = new d3_Set(), fields = []; - rows.forEach(function(row) { - for (var field in row) { - if (!fieldSet.has(field)) { - fields.push(fieldSet.add(field)); - } - } - }); - return [ fields.map(formatValue).join(delimiter) ].concat(rows.map(function(row) { - return fields.map(function(field) { - return formatValue(row[field]); - }).join(delimiter); - })).join("\n"); - }; - dsv.formatRows = function(rows) { - return rows.map(formatRow).join("\n"); - }; - function formatRow(row) { - return row.map(formatValue).join(delimiter); - } - function formatValue(text) { - return reFormat.test(text) ? '"' + text.replace(/\"/g, '""') + '"' : text; - } - return dsv; - }; - d3.csv = d3.dsv(",", "text/csv"); - d3.tsv = d3.dsv(" ", "text/tab-separated-values"); - var d3_timer_queueHead, d3_timer_queueTail, d3_timer_interval, d3_timer_timeout, d3_timer_active, d3_timer_frame = d3_window[d3_vendorSymbol(d3_window, "requestAnimationFrame")] || function(callback) { - setTimeout(callback, 17); - }; - d3.timer = function(callback, delay, then) { - var n = arguments.length; - if (n < 2) delay = 0; - if (n < 3) then = Date.now(); - var time = then + delay, timer = { - c: callback, - t: time, - f: false, - n: null - }; - if (d3_timer_queueTail) d3_timer_queueTail.n = timer; else d3_timer_queueHead = timer; - d3_timer_queueTail = timer; - if (!d3_timer_interval) { - d3_timer_timeout = clearTimeout(d3_timer_timeout); - d3_timer_interval = 1; - d3_timer_frame(d3_timer_step); - } - }; - function d3_timer_step() { - var now = d3_timer_mark(), delay = d3_timer_sweep() - now; - if (delay > 24) { - if (isFinite(delay)) { - clearTimeout(d3_timer_timeout); - d3_timer_timeout = setTimeout(d3_timer_step, delay); - } - d3_timer_interval = 0; - } else { - d3_timer_interval = 1; - d3_timer_frame(d3_timer_step); - } - } - d3.timer.flush = function() { - d3_timer_mark(); - d3_timer_sweep(); - }; - function d3_timer_mark() { - var now = Date.now(); - d3_timer_active = d3_timer_queueHead; - while (d3_timer_active) { - if (now >= d3_timer_active.t) d3_timer_active.f = d3_timer_active.c(now - d3_timer_active.t); - d3_timer_active = d3_timer_active.n; - } - return now; - } - function d3_timer_sweep() { - var t0, t1 = d3_timer_queueHead, time = Infinity; - while (t1) { - if (t1.f) { - t1 = t0 ? t0.n = t1.n : d3_timer_queueHead = t1.n; - } else { - if (t1.t < time) time = t1.t; - t1 = (t0 = t1).n; - } - } - d3_timer_queueTail = t0; - return time; - } - function d3_format_precision(x, p) { - return p - (x ? Math.ceil(Math.log(x) / Math.LN10) : 1); - } - d3.round = function(x, n) { - return n ? Math.round(x * (n = Math.pow(10, n))) / n : Math.round(x); - }; - var d3_formatPrefixes = [ "y", "z", "a", "f", "p", "n", "µ", "m", "", "k", "M", "G", "T", "P", "E", "Z", "Y" ].map(d3_formatPrefix); - d3.formatPrefix = function(value, precision) { - var i = 0; - if (value) { - if (value < 0) value *= -1; - if (precision) value = d3.round(value, d3_format_precision(value, precision)); - i = 1 + Math.floor(1e-12 + Math.log(value) / Math.LN10); - i = Math.max(-24, Math.min(24, Math.floor((i <= 0 ? i + 1 : i - 1) / 3) * 3)); - } - return d3_formatPrefixes[8 + i / 3]; - }; - function d3_formatPrefix(d, i) { - var k = Math.pow(10, abs(8 - i) * 3); - return { - scale: i > 8 ? function(d) { - return d / k; - } : function(d) { - return d * k; - }, - symbol: d - }; - } - function d3_locale_numberFormat(locale) { - var locale_decimal = locale.decimal, locale_thousands = locale.thousands, locale_grouping = locale.grouping, locale_currency = locale.currency, formatGroup = locale_grouping ? function(value) { - var i = value.length, t = [], j = 0, g = locale_grouping[0]; - while (i > 0 && g > 0) { - t.push(value.substring(i -= g, i + g)); - g = locale_grouping[j = (j + 1) % locale_grouping.length]; - } - return t.reverse().join(locale_thousands); - } : d3_identity; - return function(specifier) { - var match = d3_format_re.exec(specifier), fill = match[1] || " ", align = match[2] || ">", sign = match[3] || "", symbol = match[4] || "", zfill = match[5], width = +match[6], comma = match[7], precision = match[8], type = match[9], scale = 1, prefix = "", suffix = "", integer = false; - if (precision) precision = +precision.substring(1); - if (zfill || fill === "0" && align === "=") { - zfill = fill = "0"; - align = "="; - if (comma) width -= Math.floor((width - 1) / 4); - } - switch (type) { - case "n": - comma = true; - type = "g"; - break; - - case "%": - scale = 100; - suffix = "%"; - type = "f"; - break; - - case "p": - scale = 100; - suffix = "%"; - type = "r"; - break; - - case "b": - case "o": - case "x": - case "X": - if (symbol === "#") prefix = "0" + type.toLowerCase(); - - case "c": - case "d": - integer = true; - precision = 0; - break; - - case "s": - scale = -1; - type = "r"; - break; - } - if (symbol === "$") prefix = locale_currency[0], suffix = locale_currency[1]; - if (type == "r" && !precision) type = "g"; - if (precision != null) { - if (type == "g") precision = Math.max(1, Math.min(21, precision)); else if (type == "e" || type == "f") precision = Math.max(0, Math.min(20, precision)); - } - type = d3_format_types.get(type) || d3_format_typeDefault; - var zcomma = zfill && comma; - return function(value) { - if (integer && value % 1) return ""; - var negative = value < 0 || value === 0 && 1 / value < 0 ? (value = -value, "-") : sign; - if (scale < 0) { - var unit = d3.formatPrefix(value, precision); - value = unit.scale(value); - suffix = unit.symbol; - } else { - value *= scale; - } - value = type(value, precision); - var i = value.lastIndexOf("."), before = i < 0 ? value : value.substring(0, i), after = i < 0 ? "" : locale_decimal + value.substring(i + 1); - if (!zfill && comma) before = formatGroup(before); - var length = prefix.length + before.length + after.length + (zcomma ? 0 : negative.length), padding = length < width ? new Array(length = width - length + 1).join(fill) : ""; - if (zcomma) before = formatGroup(padding + before); - negative += prefix; - value = before + after; - return (align === "<" ? negative + value + padding : align === ">" ? padding + negative + value : align === "^" ? padding.substring(0, length >>= 1) + negative + value + padding.substring(length) : negative + (zcomma ? value : padding + value)) + suffix; - }; - }; - } - var d3_format_re = /(?:([^{])?([<>=^]))?([+\- ])?([$#])?(0)?(\d+)?(,)?(\.-?\d+)?([a-z%])?/i; - var d3_format_types = d3.map({ - b: function(x) { - return x.toString(2); - }, - c: function(x) { - return String.fromCharCode(x); - }, - o: function(x) { - return x.toString(8); - }, - x: function(x) { - return x.toString(16); - }, - X: function(x) { - return x.toString(16).toUpperCase(); - }, - g: function(x, p) { - return x.toPrecision(p); - }, - e: function(x, p) { - return x.toExponential(p); - }, - f: function(x, p) { - return x.toFixed(p); - }, - r: function(x, p) { - return (x = d3.round(x, d3_format_precision(x, p))).toFixed(Math.max(0, Math.min(20, d3_format_precision(x * (1 + 1e-15), p)))); - } - }); - function d3_format_typeDefault(x) { - return x + ""; - } - var d3_time = d3.time = {}, d3_date = Date; - function d3_date_utc() { - this._ = new Date(arguments.length > 1 ? Date.UTC.apply(this, arguments) : arguments[0]); - } - d3_date_utc.prototype = { - getDate: function() { - return this._.getUTCDate(); - }, - getDay: function() { - return this._.getUTCDay(); - }, - getFullYear: function() { - return this._.getUTCFullYear(); - }, - getHours: function() { - return this._.getUTCHours(); - }, - getMilliseconds: function() { - return this._.getUTCMilliseconds(); - }, - getMinutes: function() { - return this._.getUTCMinutes(); - }, - getMonth: function() { - return this._.getUTCMonth(); - }, - getSeconds: function() { - return this._.getUTCSeconds(); - }, - getTime: function() { - return this._.getTime(); - }, - getTimezoneOffset: function() { - return 0; - }, - valueOf: function() { - return this._.valueOf(); - }, - setDate: function() { - d3_time_prototype.setUTCDate.apply(this._, arguments); - }, - setDay: function() { - d3_time_prototype.setUTCDay.apply(this._, arguments); - }, - setFullYear: function() { - d3_time_prototype.setUTCFullYear.apply(this._, arguments); - }, - setHours: function() { - d3_time_prototype.setUTCHours.apply(this._, arguments); - }, - setMilliseconds: function() { - d3_time_prototype.setUTCMilliseconds.apply(this._, arguments); - }, - setMinutes: function() { - d3_time_prototype.setUTCMinutes.apply(this._, arguments); - }, - setMonth: function() { - d3_time_prototype.setUTCMonth.apply(this._, arguments); - }, - setSeconds: function() { - d3_time_prototype.setUTCSeconds.apply(this._, arguments); - }, - setTime: function() { - d3_time_prototype.setTime.apply(this._, arguments); - } - }; - var d3_time_prototype = Date.prototype; - function d3_time_interval(local, step, number) { - function round(date) { - var d0 = local(date), d1 = offset(d0, 1); - return date - d0 < d1 - date ? d0 : d1; - } - function ceil(date) { - step(date = local(new d3_date(date - 1)), 1); - return date; - } - function offset(date, k) { - step(date = new d3_date(+date), k); - return date; - } - function range(t0, t1, dt) { - var time = ceil(t0), times = []; - if (dt > 1) { - while (time < t1) { - if (!(number(time) % dt)) times.push(new Date(+time)); - step(time, 1); - } - } else { - while (time < t1) times.push(new Date(+time)), step(time, 1); - } - return times; - } - function range_utc(t0, t1, dt) { - try { - d3_date = d3_date_utc; - var utc = new d3_date_utc(); - utc._ = t0; - return range(utc, t1, dt); - } finally { - d3_date = Date; - } - } - local.floor = local; - local.round = round; - local.ceil = ceil; - local.offset = offset; - local.range = range; - var utc = local.utc = d3_time_interval_utc(local); - utc.floor = utc; - utc.round = d3_time_interval_utc(round); - utc.ceil = d3_time_interval_utc(ceil); - utc.offset = d3_time_interval_utc(offset); - utc.range = range_utc; - return local; - } - function d3_time_interval_utc(method) { - return function(date, k) { - try { - d3_date = d3_date_utc; - var utc = new d3_date_utc(); - utc._ = date; - return method(utc, k)._; - } finally { - d3_date = Date; - } - }; - } - d3_time.year = d3_time_interval(function(date) { - date = d3_time.day(date); - date.setMonth(0, 1); - return date; - }, function(date, offset) { - date.setFullYear(date.getFullYear() + offset); - }, function(date) { - return date.getFullYear(); - }); - d3_time.years = d3_time.year.range; - d3_time.years.utc = d3_time.year.utc.range; - d3_time.day = d3_time_interval(function(date) { - var day = new d3_date(2e3, 0); - day.setFullYear(date.getFullYear(), date.getMonth(), date.getDate()); - return day; - }, function(date, offset) { - date.setDate(date.getDate() + offset); - }, function(date) { - return date.getDate() - 1; - }); - d3_time.days = d3_time.day.range; - d3_time.days.utc = d3_time.day.utc.range; - d3_time.dayOfYear = function(date) { - var year = d3_time.year(date); - return Math.floor((date - year - (date.getTimezoneOffset() - year.getTimezoneOffset()) * 6e4) / 864e5); - }; - [ "sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday" ].forEach(function(day, i) { - i = 7 - i; - var interval = d3_time[day] = d3_time_interval(function(date) { - (date = d3_time.day(date)).setDate(date.getDate() - (date.getDay() + i) % 7); - return date; - }, function(date, offset) { - date.setDate(date.getDate() + Math.floor(offset) * 7); - }, function(date) { - var day = d3_time.year(date).getDay(); - return Math.floor((d3_time.dayOfYear(date) + (day + i) % 7) / 7) - (day !== i); - }); - d3_time[day + "s"] = interval.range; - d3_time[day + "s"].utc = interval.utc.range; - d3_time[day + "OfYear"] = function(date) { - var day = d3_time.year(date).getDay(); - return Math.floor((d3_time.dayOfYear(date) + (day + i) % 7) / 7); - }; - }); - d3_time.week = d3_time.sunday; - d3_time.weeks = d3_time.sunday.range; - d3_time.weeks.utc = d3_time.sunday.utc.range; - d3_time.weekOfYear = d3_time.sundayOfYear; - function d3_locale_timeFormat(locale) { - var locale_dateTime = locale.dateTime, locale_date = locale.date, locale_time = locale.time, locale_periods = locale.periods, locale_days = locale.days, locale_shortDays = locale.shortDays, locale_months = locale.months, locale_shortMonths = locale.shortMonths; - function d3_time_format(template) { - var n = template.length; - function format(date) { - var string = [], i = -1, j = 0, c, p, f; - while (++i < n) { - if (template.charCodeAt(i) === 37) { - string.push(template.substring(j, i)); - if ((p = d3_time_formatPads[c = template.charAt(++i)]) != null) c = template.charAt(++i); - if (f = d3_time_formats[c]) c = f(date, p == null ? c === "e" ? " " : "0" : p); - string.push(c); - j = i + 1; - } - } - string.push(template.substring(j, i)); - return string.join(""); - } - format.parse = function(string) { - var d = { - y: 1900, - m: 0, - d: 1, - H: 0, - M: 0, - S: 0, - L: 0, - Z: null - }, i = d3_time_parse(d, template, string, 0); - if (i != string.length) return null; - if ("p" in d) d.H = d.H % 12 + d.p * 12; - var localZ = d.Z != null && d3_date !== d3_date_utc, date = new (localZ ? d3_date_utc : d3_date)(); - if ("j" in d) date.setFullYear(d.y, 0, d.j); else if ("w" in d && ("W" in d || "U" in d)) { - date.setFullYear(d.y, 0, 1); - date.setFullYear(d.y, 0, "W" in d ? (d.w + 6) % 7 + d.W * 7 - (date.getDay() + 5) % 7 : d.w + d.U * 7 - (date.getDay() + 6) % 7); - } else date.setFullYear(d.y, d.m, d.d); - date.setHours(d.H + Math.floor(d.Z / 100), d.M + d.Z % 100, d.S, d.L); - return localZ ? date._ : date; - }; - format.toString = function() { - return template; - }; - return format; - } - function d3_time_parse(date, template, string, j) { - var c, p, t, i = 0, n = template.length, m = string.length; - while (i < n) { - if (j >= m) return -1; - c = template.charCodeAt(i++); - if (c === 37) { - t = template.charAt(i++); - p = d3_time_parsers[t in d3_time_formatPads ? template.charAt(i++) : t]; - if (!p || (j = p(date, string, j)) < 0) return -1; - } else if (c != string.charCodeAt(j++)) { - return -1; - } - } - return j; - } - d3_time_format.utc = function(template) { - var local = d3_time_format(template); - function format(date) { - try { - d3_date = d3_date_utc; - var utc = new d3_date(); - utc._ = date; - return local(utc); - } finally { - d3_date = Date; - } - } - format.parse = function(string) { - try { - d3_date = d3_date_utc; - var date = local.parse(string); - return date && date._; - } finally { - d3_date = Date; - } - }; - format.toString = local.toString; - return format; - }; - d3_time_format.multi = d3_time_format.utc.multi = d3_time_formatMulti; - var d3_time_periodLookup = d3.map(), d3_time_dayRe = d3_time_formatRe(locale_days), d3_time_dayLookup = d3_time_formatLookup(locale_days), d3_time_dayAbbrevRe = d3_time_formatRe(locale_shortDays), d3_time_dayAbbrevLookup = d3_time_formatLookup(locale_shortDays), d3_time_monthRe = d3_time_formatRe(locale_months), d3_time_monthLookup = d3_time_formatLookup(locale_months), d3_time_monthAbbrevRe = d3_time_formatRe(locale_shortMonths), d3_time_monthAbbrevLookup = d3_time_formatLookup(locale_shortMonths); - locale_periods.forEach(function(p, i) { - d3_time_periodLookup.set(p.toLowerCase(), i); - }); - var d3_time_formats = { - a: function(d) { - return locale_shortDays[d.getDay()]; - }, - A: function(d) { - return locale_days[d.getDay()]; - }, - b: function(d) { - return locale_shortMonths[d.getMonth()]; - }, - B: function(d) { - return locale_months[d.getMonth()]; - }, - c: d3_time_format(locale_dateTime), - d: function(d, p) { - return d3_time_formatPad(d.getDate(), p, 2); - }, - e: function(d, p) { - return d3_time_formatPad(d.getDate(), p, 2); - }, - H: function(d, p) { - return d3_time_formatPad(d.getHours(), p, 2); - }, - I: function(d, p) { - return d3_time_formatPad(d.getHours() % 12 || 12, p, 2); - }, - j: function(d, p) { - return d3_time_formatPad(1 + d3_time.dayOfYear(d), p, 3); - }, - L: function(d, p) { - return d3_time_formatPad(d.getMilliseconds(), p, 3); - }, - m: function(d, p) { - return d3_time_formatPad(d.getMonth() + 1, p, 2); - }, - M: function(d, p) { - return d3_time_formatPad(d.getMinutes(), p, 2); - }, - p: function(d) { - return locale_periods[+(d.getHours() >= 12)]; - }, - S: function(d, p) { - return d3_time_formatPad(d.getSeconds(), p, 2); - }, - U: function(d, p) { - return d3_time_formatPad(d3_time.sundayOfYear(d), p, 2); - }, - w: function(d) { - return d.getDay(); - }, - W: function(d, p) { - return d3_time_formatPad(d3_time.mondayOfYear(d), p, 2); - }, - x: d3_time_format(locale_date), - X: d3_time_format(locale_time), - y: function(d, p) { - return d3_time_formatPad(d.getFullYear() % 100, p, 2); - }, - Y: function(d, p) { - return d3_time_formatPad(d.getFullYear() % 1e4, p, 4); - }, - Z: d3_time_zone, - "%": function() { - return "%"; - } - }; - var d3_time_parsers = { - a: d3_time_parseWeekdayAbbrev, - A: d3_time_parseWeekday, - b: d3_time_parseMonthAbbrev, - B: d3_time_parseMonth, - c: d3_time_parseLocaleFull, - d: d3_time_parseDay, - e: d3_time_parseDay, - H: d3_time_parseHour24, - I: d3_time_parseHour24, - j: d3_time_parseDayOfYear, - L: d3_time_parseMilliseconds, - m: d3_time_parseMonthNumber, - M: d3_time_parseMinutes, - p: d3_time_parseAmPm, - S: d3_time_parseSeconds, - U: d3_time_parseWeekNumberSunday, - w: d3_time_parseWeekdayNumber, - W: d3_time_parseWeekNumberMonday, - x: d3_time_parseLocaleDate, - X: d3_time_parseLocaleTime, - y: d3_time_parseYear, - Y: d3_time_parseFullYear, - Z: d3_time_parseZone, - "%": d3_time_parseLiteralPercent - }; - function d3_time_parseWeekdayAbbrev(date, string, i) { - d3_time_dayAbbrevRe.lastIndex = 0; - var n = d3_time_dayAbbrevRe.exec(string.substring(i)); - return n ? (date.w = d3_time_dayAbbrevLookup.get(n[0].toLowerCase()), i + n[0].length) : -1; - } - function d3_time_parseWeekday(date, string, i) { - d3_time_dayRe.lastIndex = 0; - var n = d3_time_dayRe.exec(string.substring(i)); - return n ? (date.w = d3_time_dayLookup.get(n[0].toLowerCase()), i + n[0].length) : -1; - } - function d3_time_parseMonthAbbrev(date, string, i) { - d3_time_monthAbbrevRe.lastIndex = 0; - var n = d3_time_monthAbbrevRe.exec(string.substring(i)); - return n ? (date.m = d3_time_monthAbbrevLookup.get(n[0].toLowerCase()), i + n[0].length) : -1; - } - function d3_time_parseMonth(date, string, i) { - d3_time_monthRe.lastIndex = 0; - var n = d3_time_monthRe.exec(string.substring(i)); - return n ? (date.m = d3_time_monthLookup.get(n[0].toLowerCase()), i + n[0].length) : -1; - } - function d3_time_parseLocaleFull(date, string, i) { - return d3_time_parse(date, d3_time_formats.c.toString(), string, i); - } - function d3_time_parseLocaleDate(date, string, i) { - return d3_time_parse(date, d3_time_formats.x.toString(), string, i); - } - function d3_time_parseLocaleTime(date, string, i) { - return d3_time_parse(date, d3_time_formats.X.toString(), string, i); - } - function d3_time_parseAmPm(date, string, i) { - var n = d3_time_periodLookup.get(string.substring(i, i += 2).toLowerCase()); - return n == null ? -1 : (date.p = n, i); - } - return d3_time_format; - } - var d3_time_formatPads = { - "-": "", - _: " ", - "0": "0" - }, d3_time_numberRe = /^\s*\d+/, d3_time_percentRe = /^%/; - function d3_time_formatPad(value, fill, width) { - var sign = value < 0 ? "-" : "", string = (sign ? -value : value) + "", length = string.length; - return sign + (length < width ? new Array(width - length + 1).join(fill) + string : string); - } - function d3_time_formatRe(names) { - return new RegExp("^(?:" + names.map(d3.requote).join("|") + ")", "i"); - } - function d3_time_formatLookup(names) { - var map = new d3_Map(), i = -1, n = names.length; - while (++i < n) map.set(names[i].toLowerCase(), i); - return map; - } - function d3_time_parseWeekdayNumber(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.substring(i, i + 1)); - return n ? (date.w = +n[0], i + n[0].length) : -1; - } - function d3_time_parseWeekNumberSunday(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.substring(i)); - return n ? (date.U = +n[0], i + n[0].length) : -1; - } - function d3_time_parseWeekNumberMonday(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.substring(i)); - return n ? (date.W = +n[0], i + n[0].length) : -1; - } - function d3_time_parseFullYear(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.substring(i, i + 4)); - return n ? (date.y = +n[0], i + n[0].length) : -1; - } - function d3_time_parseYear(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.substring(i, i + 2)); - return n ? (date.y = d3_time_expandYear(+n[0]), i + n[0].length) : -1; - } - function d3_time_parseZone(date, string, i) { - return /^[+-]\d{4}$/.test(string = string.substring(i, i + 5)) ? (date.Z = +string, - i + 5) : -1; - } - function d3_time_expandYear(d) { - return d + (d > 68 ? 1900 : 2e3); - } - function d3_time_parseMonthNumber(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.substring(i, i + 2)); - return n ? (date.m = n[0] - 1, i + n[0].length) : -1; - } - function d3_time_parseDay(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.substring(i, i + 2)); - return n ? (date.d = +n[0], i + n[0].length) : -1; - } - function d3_time_parseDayOfYear(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.substring(i, i + 3)); - return n ? (date.j = +n[0], i + n[0].length) : -1; - } - function d3_time_parseHour24(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.substring(i, i + 2)); - return n ? (date.H = +n[0], i + n[0].length) : -1; - } - function d3_time_parseMinutes(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.substring(i, i + 2)); - return n ? (date.M = +n[0], i + n[0].length) : -1; - } - function d3_time_parseSeconds(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.substring(i, i + 2)); - return n ? (date.S = +n[0], i + n[0].length) : -1; - } - function d3_time_parseMilliseconds(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.substring(i, i + 3)); - return n ? (date.L = +n[0], i + n[0].length) : -1; - } - function d3_time_zone(d) { - var z = d.getTimezoneOffset(), zs = z > 0 ? "-" : "+", zh = ~~(abs(z) / 60), zm = abs(z) % 60; - return zs + d3_time_formatPad(zh, "0", 2) + d3_time_formatPad(zm, "0", 2); - } - function d3_time_parseLiteralPercent(date, string, i) { - d3_time_percentRe.lastIndex = 0; - var n = d3_time_percentRe.exec(string.substring(i, i + 1)); - return n ? i + n[0].length : -1; - } - function d3_time_formatMulti(formats) { - var n = formats.length, i = -1; - while (++i < n) formats[i][0] = this(formats[i][0]); - return function(date) { - var i = 0, f = formats[i]; - while (!f[1](date)) f = formats[++i]; - return f[0](date); - }; - } - d3.locale = function(locale) { - return { - numberFormat: d3_locale_numberFormat(locale), - timeFormat: d3_locale_timeFormat(locale) - }; - }; - var d3_locale_enUS = d3.locale({ - decimal: ".", - thousands: ",", - grouping: [ 3 ], - currency: [ "$", "" ], - dateTime: "%a %b %e %X %Y", - date: "%m/%d/%Y", - time: "%H:%M:%S", - periods: [ "AM", "PM" ], - days: [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ], - shortDays: [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ], - months: [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ], - shortMonths: [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ] - }); - d3.format = d3_locale_enUS.numberFormat; - d3.geo = {}; - function d3_adder() {} - d3_adder.prototype = { - s: 0, - t: 0, - add: function(y) { - d3_adderSum(y, this.t, d3_adderTemp); - d3_adderSum(d3_adderTemp.s, this.s, this); - if (this.s) this.t += d3_adderTemp.t; else this.s = d3_adderTemp.t; - }, - reset: function() { - this.s = this.t = 0; - }, - valueOf: function() { - return this.s; - } - }; - var d3_adderTemp = new d3_adder(); - function d3_adderSum(a, b, o) { - var x = o.s = a + b, bv = x - a, av = x - bv; - o.t = a - av + (b - bv); - } - d3.geo.stream = function(object, listener) { - if (object && d3_geo_streamObjectType.hasOwnProperty(object.type)) { - d3_geo_streamObjectType[object.type](object, listener); - } else { - d3_geo_streamGeometry(object, listener); - } - }; - function d3_geo_streamGeometry(geometry, listener) { - if (geometry && d3_geo_streamGeometryType.hasOwnProperty(geometry.type)) { - d3_geo_streamGeometryType[geometry.type](geometry, listener); - } - } - var d3_geo_streamObjectType = { - Feature: function(feature, listener) { - d3_geo_streamGeometry(feature.geometry, listener); - }, - FeatureCollection: function(object, listener) { - var features = object.features, i = -1, n = features.length; - while (++i < n) d3_geo_streamGeometry(features[i].geometry, listener); - } - }; - var d3_geo_streamGeometryType = { - Sphere: function(object, listener) { - listener.sphere(); - }, - Point: function(object, listener) { - object = object.coordinates; - listener.point(object[0], object[1], object[2]); - }, - MultiPoint: function(object, listener) { - var coordinates = object.coordinates, i = -1, n = coordinates.length; - while (++i < n) object = coordinates[i], listener.point(object[0], object[1], object[2]); - }, - LineString: function(object, listener) { - d3_geo_streamLine(object.coordinates, listener, 0); - }, - MultiLineString: function(object, listener) { - var coordinates = object.coordinates, i = -1, n = coordinates.length; - while (++i < n) d3_geo_streamLine(coordinates[i], listener, 0); - }, - Polygon: function(object, listener) { - d3_geo_streamPolygon(object.coordinates, listener); - }, - MultiPolygon: function(object, listener) { - var coordinates = object.coordinates, i = -1, n = coordinates.length; - while (++i < n) d3_geo_streamPolygon(coordinates[i], listener); - }, - GeometryCollection: function(object, listener) { - var geometries = object.geometries, i = -1, n = geometries.length; - while (++i < n) d3_geo_streamGeometry(geometries[i], listener); - } - }; - function d3_geo_streamLine(coordinates, listener, closed) { - var i = -1, n = coordinates.length - closed, coordinate; - listener.lineStart(); - while (++i < n) coordinate = coordinates[i], listener.point(coordinate[0], coordinate[1], coordinate[2]); - listener.lineEnd(); - } - function d3_geo_streamPolygon(coordinates, listener) { - var i = -1, n = coordinates.length; - listener.polygonStart(); - while (++i < n) d3_geo_streamLine(coordinates[i], listener, 1); - listener.polygonEnd(); - } - d3.geo.area = function(object) { - d3_geo_areaSum = 0; - d3.geo.stream(object, d3_geo_area); - return d3_geo_areaSum; - }; - var d3_geo_areaSum, d3_geo_areaRingSum = new d3_adder(); - var d3_geo_area = { - sphere: function() { - d3_geo_areaSum += 4 * Ï€; - }, - point: d3_noop, - lineStart: d3_noop, - lineEnd: d3_noop, - polygonStart: function() { - d3_geo_areaRingSum.reset(); - d3_geo_area.lineStart = d3_geo_areaRingStart; - }, - polygonEnd: function() { - var area = 2 * d3_geo_areaRingSum; - d3_geo_areaSum += area < 0 ? 4 * Ï€ + area : area; - d3_geo_area.lineStart = d3_geo_area.lineEnd = d3_geo_area.point = d3_noop; - } - }; - function d3_geo_areaRingStart() { - var λ00, φ00, λ0, cosφ0, sinφ0; - d3_geo_area.point = function(λ, φ) { - d3_geo_area.point = nextPoint; - λ0 = (λ00 = λ) * d3_radians, cosφ0 = Math.cos(φ = (φ00 = φ) * d3_radians / 2 + Ï€ / 4), - sinφ0 = Math.sin(φ); - }; - function nextPoint(λ, φ) { - λ *= d3_radians; - φ = φ * d3_radians / 2 + Ï€ / 4; - var dλ = λ - λ0, cosφ = Math.cos(φ), sinφ = Math.sin(φ), k = sinφ0 * sinφ, u = cosφ0 * cosφ + k * Math.cos(dλ), v = k * Math.sin(dλ); - d3_geo_areaRingSum.add(Math.atan2(v, u)); - λ0 = λ, cosφ0 = cosφ, sinφ0 = sinφ; - } - d3_geo_area.lineEnd = function() { - nextPoint(λ00, φ00); - }; - } - function d3_geo_cartesian(spherical) { - var λ = spherical[0], φ = spherical[1], cosφ = Math.cos(φ); - return [ cosφ * Math.cos(λ), cosφ * Math.sin(λ), Math.sin(φ) ]; - } - function d3_geo_cartesianDot(a, b) { - return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; - } - function d3_geo_cartesianCross(a, b) { - return [ a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0] ]; - } - function d3_geo_cartesianAdd(a, b) { - a[0] += b[0]; - a[1] += b[1]; - a[2] += b[2]; - } - function d3_geo_cartesianScale(vector, k) { - return [ vector[0] * k, vector[1] * k, vector[2] * k ]; - } - function d3_geo_cartesianNormalize(d) { - var l = Math.sqrt(d[0] * d[0] + d[1] * d[1] + d[2] * d[2]); - d[0] /= l; - d[1] /= l; - d[2] /= l; - } - function d3_geo_spherical(cartesian) { - return [ Math.atan2(cartesian[1], cartesian[0]), d3_asin(cartesian[2]) ]; - } - function d3_geo_sphericalEqual(a, b) { - return abs(a[0] - b[0]) < ε && abs(a[1] - b[1]) < ε; - } - d3.geo.bounds = function() { - var λ0, φ0, λ1, φ1, λ_, λ__, φ__, p0, dλSum, ranges, range; - var bound = { - point: point, - lineStart: lineStart, - lineEnd: lineEnd, - polygonStart: function() { - bound.point = ringPoint; - bound.lineStart = ringStart; - bound.lineEnd = ringEnd; - dλSum = 0; - d3_geo_area.polygonStart(); - }, - polygonEnd: function() { - d3_geo_area.polygonEnd(); - bound.point = point; - bound.lineStart = lineStart; - bound.lineEnd = lineEnd; - if (d3_geo_areaRingSum < 0) λ0 = -(λ1 = 180), φ0 = -(φ1 = 90); else if (dλSum > ε) φ1 = 90; else if (dλSum < -ε) φ0 = -90; - range[0] = λ0, range[1] = λ1; - } - }; - function point(λ, φ) { - ranges.push(range = [ λ0 = λ, λ1 = λ ]); - if (φ < φ0) φ0 = φ; - if (φ > φ1) φ1 = φ; - } - function linePoint(λ, φ) { - var p = d3_geo_cartesian([ λ * d3_radians, φ * d3_radians ]); - if (p0) { - var normal = d3_geo_cartesianCross(p0, p), equatorial = [ normal[1], -normal[0], 0 ], inflection = d3_geo_cartesianCross(equatorial, normal); - d3_geo_cartesianNormalize(inflection); - inflection = d3_geo_spherical(inflection); - var dλ = λ - λ_, s = dλ > 0 ? 1 : -1, λi = inflection[0] * d3_degrees * s, antimeridian = abs(dλ) > 180; - if (antimeridian ^ (s * λ_ < λi && λi < s * λ)) { - var φi = inflection[1] * d3_degrees; - if (φi > φ1) φ1 = φi; - } else if (λi = (λi + 360) % 360 - 180, antimeridian ^ (s * λ_ < λi && λi < s * λ)) { - var φi = -inflection[1] * d3_degrees; - if (φi < φ0) φ0 = φi; - } else { - if (φ < φ0) φ0 = φ; - if (φ > φ1) φ1 = φ; - } - if (antimeridian) { - if (λ < λ_) { - if (angle(λ0, λ) > angle(λ0, λ1)) λ1 = λ; - } else { - if (angle(λ, λ1) > angle(λ0, λ1)) λ0 = λ; - } - } else { - if (λ1 >= λ0) { - if (λ < λ0) λ0 = λ; - if (λ > λ1) λ1 = λ; - } else { - if (λ > λ_) { - if (angle(λ0, λ) > angle(λ0, λ1)) λ1 = λ; - } else { - if (angle(λ, λ1) > angle(λ0, λ1)) λ0 = λ; - } - } - } - } else { - point(λ, φ); - } - p0 = p, λ_ = λ; - } - function lineStart() { - bound.point = linePoint; - } - function lineEnd() { - range[0] = λ0, range[1] = λ1; - bound.point = point; - p0 = null; - } - function ringPoint(λ, φ) { - if (p0) { - var dλ = λ - λ_; - dλSum += abs(dλ) > 180 ? dλ + (dλ > 0 ? 360 : -360) : dλ; - } else λ__ = λ, φ__ = φ; - d3_geo_area.point(λ, φ); - linePoint(λ, φ); - } - function ringStart() { - d3_geo_area.lineStart(); - } - function ringEnd() { - ringPoint(λ__, φ__); - d3_geo_area.lineEnd(); - if (abs(dλSum) > ε) λ0 = -(λ1 = 180); - range[0] = λ0, range[1] = λ1; - p0 = null; - } - function angle(λ0, λ1) { - return (λ1 -= λ0) < 0 ? λ1 + 360 : λ1; - } - function compareRanges(a, b) { - return a[0] - b[0]; - } - function withinRange(x, range) { - return range[0] <= range[1] ? range[0] <= x && x <= range[1] : x < range[0] || range[1] < x; - } - return function(feature) { - φ1 = λ1 = -(λ0 = φ0 = Infinity); - ranges = []; - d3.geo.stream(feature, bound); - var n = ranges.length; - if (n) { - ranges.sort(compareRanges); - for (var i = 1, a = ranges[0], b, merged = [ a ]; i < n; ++i) { - b = ranges[i]; - if (withinRange(b[0], a) || withinRange(b[1], a)) { - if (angle(a[0], b[1]) > angle(a[0], a[1])) a[1] = b[1]; - if (angle(b[0], a[1]) > angle(a[0], a[1])) a[0] = b[0]; - } else { - merged.push(a = b); - } - } - var best = -Infinity, dλ; - for (var n = merged.length - 1, i = 0, a = merged[n], b; i <= n; a = b, ++i) { - b = merged[i]; - if ((dλ = angle(a[1], b[0])) > best) best = dλ, λ0 = b[0], λ1 = a[1]; - } - } - ranges = range = null; - return λ0 === Infinity || φ0 === Infinity ? [ [ NaN, NaN ], [ NaN, NaN ] ] : [ [ λ0, φ0 ], [ λ1, φ1 ] ]; - }; - }(); - d3.geo.centroid = function(object) { - d3_geo_centroidW0 = d3_geo_centroidW1 = d3_geo_centroidX0 = d3_geo_centroidY0 = d3_geo_centroidZ0 = d3_geo_centroidX1 = d3_geo_centroidY1 = d3_geo_centroidZ1 = d3_geo_centroidX2 = d3_geo_centroidY2 = d3_geo_centroidZ2 = 0; - d3.geo.stream(object, d3_geo_centroid); - var x = d3_geo_centroidX2, y = d3_geo_centroidY2, z = d3_geo_centroidZ2, m = x * x + y * y + z * z; - if (m < ε2) { - x = d3_geo_centroidX1, y = d3_geo_centroidY1, z = d3_geo_centroidZ1; - if (d3_geo_centroidW1 < ε) x = d3_geo_centroidX0, y = d3_geo_centroidY0, z = d3_geo_centroidZ0; - m = x * x + y * y + z * z; - if (m < ε2) return [ NaN, NaN ]; - } - return [ Math.atan2(y, x) * d3_degrees, d3_asin(z / Math.sqrt(m)) * d3_degrees ]; - }; - var d3_geo_centroidW0, d3_geo_centroidW1, d3_geo_centroidX0, d3_geo_centroidY0, d3_geo_centroidZ0, d3_geo_centroidX1, d3_geo_centroidY1, d3_geo_centroidZ1, d3_geo_centroidX2, d3_geo_centroidY2, d3_geo_centroidZ2; - var d3_geo_centroid = { - sphere: d3_noop, - point: d3_geo_centroidPoint, - lineStart: d3_geo_centroidLineStart, - lineEnd: d3_geo_centroidLineEnd, - polygonStart: function() { - d3_geo_centroid.lineStart = d3_geo_centroidRingStart; - }, - polygonEnd: function() { - d3_geo_centroid.lineStart = d3_geo_centroidLineStart; - } - }; - function d3_geo_centroidPoint(λ, φ) { - λ *= d3_radians; - var cosφ = Math.cos(φ *= d3_radians); - d3_geo_centroidPointXYZ(cosφ * Math.cos(λ), cosφ * Math.sin(λ), Math.sin(φ)); - } - function d3_geo_centroidPointXYZ(x, y, z) { - ++d3_geo_centroidW0; - d3_geo_centroidX0 += (x - d3_geo_centroidX0) / d3_geo_centroidW0; - d3_geo_centroidY0 += (y - d3_geo_centroidY0) / d3_geo_centroidW0; - d3_geo_centroidZ0 += (z - d3_geo_centroidZ0) / d3_geo_centroidW0; - } - function d3_geo_centroidLineStart() { - var x0, y0, z0; - d3_geo_centroid.point = function(λ, φ) { - λ *= d3_radians; - var cosφ = Math.cos(φ *= d3_radians); - x0 = cosφ * Math.cos(λ); - y0 = cosφ * Math.sin(λ); - z0 = Math.sin(φ); - d3_geo_centroid.point = nextPoint; - d3_geo_centroidPointXYZ(x0, y0, z0); - }; - function nextPoint(λ, φ) { - λ *= d3_radians; - var cosφ = Math.cos(φ *= d3_radians), x = cosφ * Math.cos(λ), y = cosφ * Math.sin(λ), z = Math.sin(φ), w = Math.atan2(Math.sqrt((w = y0 * z - z0 * y) * w + (w = z0 * x - x0 * z) * w + (w = x0 * y - y0 * x) * w), x0 * x + y0 * y + z0 * z); - d3_geo_centroidW1 += w; - d3_geo_centroidX1 += w * (x0 + (x0 = x)); - d3_geo_centroidY1 += w * (y0 + (y0 = y)); - d3_geo_centroidZ1 += w * (z0 + (z0 = z)); - d3_geo_centroidPointXYZ(x0, y0, z0); - } - } - function d3_geo_centroidLineEnd() { - d3_geo_centroid.point = d3_geo_centroidPoint; - } - function d3_geo_centroidRingStart() { - var λ00, φ00, x0, y0, z0; - d3_geo_centroid.point = function(λ, φ) { - λ00 = λ, φ00 = φ; - d3_geo_centroid.point = nextPoint; - λ *= d3_radians; - var cosφ = Math.cos(φ *= d3_radians); - x0 = cosφ * Math.cos(λ); - y0 = cosφ * Math.sin(λ); - z0 = Math.sin(φ); - d3_geo_centroidPointXYZ(x0, y0, z0); - }; - d3_geo_centroid.lineEnd = function() { - nextPoint(λ00, φ00); - d3_geo_centroid.lineEnd = d3_geo_centroidLineEnd; - d3_geo_centroid.point = d3_geo_centroidPoint; - }; - function nextPoint(λ, φ) { - λ *= d3_radians; - var cosφ = Math.cos(φ *= d3_radians), x = cosφ * Math.cos(λ), y = cosφ * Math.sin(λ), z = Math.sin(φ), cx = y0 * z - z0 * y, cy = z0 * x - x0 * z, cz = x0 * y - y0 * x, m = Math.sqrt(cx * cx + cy * cy + cz * cz), u = x0 * x + y0 * y + z0 * z, v = m && -d3_acos(u) / m, w = Math.atan2(m, u); - d3_geo_centroidX2 += v * cx; - d3_geo_centroidY2 += v * cy; - d3_geo_centroidZ2 += v * cz; - d3_geo_centroidW1 += w; - d3_geo_centroidX1 += w * (x0 + (x0 = x)); - d3_geo_centroidY1 += w * (y0 + (y0 = y)); - d3_geo_centroidZ1 += w * (z0 + (z0 = z)); - d3_geo_centroidPointXYZ(x0, y0, z0); - } - } - function d3_true() { - return true; - } - function d3_geo_clipPolygon(segments, compare, clipStartInside, interpolate, listener) { - var subject = [], clip = []; - segments.forEach(function(segment) { - if ((n = segment.length - 1) <= 0) return; - var n, p0 = segment[0], p1 = segment[n]; - if (d3_geo_sphericalEqual(p0, p1)) { - listener.lineStart(); - for (var i = 0; i < n; ++i) listener.point((p0 = segment[i])[0], p0[1]); - listener.lineEnd(); - return; - } - var a = new d3_geo_clipPolygonIntersection(p0, segment, null, true), b = new d3_geo_clipPolygonIntersection(p0, null, a, false); - a.o = b; - subject.push(a); - clip.push(b); - a = new d3_geo_clipPolygonIntersection(p1, segment, null, false); - b = new d3_geo_clipPolygonIntersection(p1, null, a, true); - a.o = b; - subject.push(a); - clip.push(b); - }); - clip.sort(compare); - d3_geo_clipPolygonLinkCircular(subject); - d3_geo_clipPolygonLinkCircular(clip); - if (!subject.length) return; - for (var i = 0, entry = clipStartInside, n = clip.length; i < n; ++i) { - clip[i].e = entry = !entry; - } - var start = subject[0], points, point; - while (1) { - var current = start, isSubject = true; - while (current.v) if ((current = current.n) === start) return; - points = current.z; - listener.lineStart(); - do { - current.v = current.o.v = true; - if (current.e) { - if (isSubject) { - for (var i = 0, n = points.length; i < n; ++i) listener.point((point = points[i])[0], point[1]); - } else { - interpolate(current.x, current.n.x, 1, listener); - } - current = current.n; - } else { - if (isSubject) { - points = current.p.z; - for (var i = points.length - 1; i >= 0; --i) listener.point((point = points[i])[0], point[1]); - } else { - interpolate(current.x, current.p.x, -1, listener); - } - current = current.p; - } - current = current.o; - points = current.z; - isSubject = !isSubject; - } while (!current.v); - listener.lineEnd(); - } - } - function d3_geo_clipPolygonLinkCircular(array) { - if (!(n = array.length)) return; - var n, i = 0, a = array[0], b; - while (++i < n) { - a.n = b = array[i]; - b.p = a; - a = b; - } - a.n = b = array[0]; - b.p = a; - } - function d3_geo_clipPolygonIntersection(point, points, other, entry) { - this.x = point; - this.z = points; - this.o = other; - this.e = entry; - this.v = false; - this.n = this.p = null; - } - function d3_geo_clip(pointVisible, clipLine, interpolate, clipStart) { - return function(rotate, listener) { - var line = clipLine(listener), rotatedClipStart = rotate.invert(clipStart[0], clipStart[1]); - var clip = { - point: point, - lineStart: lineStart, - lineEnd: lineEnd, - polygonStart: function() { - clip.point = pointRing; - clip.lineStart = ringStart; - clip.lineEnd = ringEnd; - segments = []; - polygon = []; - listener.polygonStart(); - }, - polygonEnd: function() { - clip.point = point; - clip.lineStart = lineStart; - clip.lineEnd = lineEnd; - segments = d3.merge(segments); - var clipStartInside = d3_geo_pointInPolygon(rotatedClipStart, polygon); - if (segments.length) { - d3_geo_clipPolygon(segments, d3_geo_clipSort, clipStartInside, interpolate, listener); - } else if (clipStartInside) { - listener.lineStart(); - interpolate(null, null, 1, listener); - listener.lineEnd(); - } - listener.polygonEnd(); - segments = polygon = null; - }, - sphere: function() { - listener.polygonStart(); - listener.lineStart(); - interpolate(null, null, 1, listener); - listener.lineEnd(); - listener.polygonEnd(); - } - }; - function point(λ, φ) { - var point = rotate(λ, φ); - if (pointVisible(λ = point[0], φ = point[1])) listener.point(λ, φ); - } - function pointLine(λ, φ) { - var point = rotate(λ, φ); - line.point(point[0], point[1]); - } - function lineStart() { - clip.point = pointLine; - line.lineStart(); - } - function lineEnd() { - clip.point = point; - line.lineEnd(); - } - var segments; - var buffer = d3_geo_clipBufferListener(), ringListener = clipLine(buffer), polygon, ring; - function pointRing(λ, φ) { - ring.push([ λ, φ ]); - var point = rotate(λ, φ); - ringListener.point(point[0], point[1]); - } - function ringStart() { - ringListener.lineStart(); - ring = []; - } - function ringEnd() { - pointRing(ring[0][0], ring[0][1]); - ringListener.lineEnd(); - var clean = ringListener.clean(), ringSegments = buffer.buffer(), segment, n = ringSegments.length; - ring.pop(); - polygon.push(ring); - ring = null; - if (!n) return; - if (clean & 1) { - segment = ringSegments[0]; - var n = segment.length - 1, i = -1, point; - listener.lineStart(); - while (++i < n) listener.point((point = segment[i])[0], point[1]); - listener.lineEnd(); - return; - } - if (n > 1 && clean & 2) ringSegments.push(ringSegments.pop().concat(ringSegments.shift())); - segments.push(ringSegments.filter(d3_geo_clipSegmentLength1)); - } - return clip; - }; - } - function d3_geo_clipSegmentLength1(segment) { - return segment.length > 1; - } - function d3_geo_clipBufferListener() { - var lines = [], line; - return { - lineStart: function() { - lines.push(line = []); - }, - point: function(λ, φ) { - line.push([ λ, φ ]); - }, - lineEnd: d3_noop, - buffer: function() { - var buffer = lines; - lines = []; - line = null; - return buffer; - }, - rejoin: function() { - if (lines.length > 1) lines.push(lines.pop().concat(lines.shift())); - } - }; - } - function d3_geo_clipSort(a, b) { - return ((a = a.x)[0] < 0 ? a[1] - halfÏ€ - ε : halfÏ€ - a[1]) - ((b = b.x)[0] < 0 ? b[1] - halfÏ€ - ε : halfÏ€ - b[1]); - } - function d3_geo_pointInPolygon(point, polygon) { - var meridian = point[0], parallel = point[1], meridianNormal = [ Math.sin(meridian), -Math.cos(meridian), 0 ], polarAngle = 0, winding = 0; - d3_geo_areaRingSum.reset(); - for (var i = 0, n = polygon.length; i < n; ++i) { - var ring = polygon[i], m = ring.length; - if (!m) continue; - var point0 = ring[0], λ0 = point0[0], φ0 = point0[1] / 2 + Ï€ / 4, sinφ0 = Math.sin(φ0), cosφ0 = Math.cos(φ0), j = 1; - while (true) { - if (j === m) j = 0; - point = ring[j]; - var λ = point[0], φ = point[1] / 2 + Ï€ / 4, sinφ = Math.sin(φ), cosφ = Math.cos(φ), dλ = λ - λ0, antimeridian = abs(dλ) > Ï€, k = sinφ0 * sinφ; - d3_geo_areaRingSum.add(Math.atan2(k * Math.sin(dλ), cosφ0 * cosφ + k * Math.cos(dλ))); - polarAngle += antimeridian ? dλ + (dλ >= 0 ? Ï„ : -Ï„) : dλ; - if (antimeridian ^ λ0 >= meridian ^ λ >= meridian) { - var arc = d3_geo_cartesianCross(d3_geo_cartesian(point0), d3_geo_cartesian(point)); - d3_geo_cartesianNormalize(arc); - var intersection = d3_geo_cartesianCross(meridianNormal, arc); - d3_geo_cartesianNormalize(intersection); - var φarc = (antimeridian ^ dλ >= 0 ? -1 : 1) * d3_asin(intersection[2]); - if (parallel > φarc || parallel === φarc && (arc[0] || arc[1])) { - winding += antimeridian ^ dλ >= 0 ? 1 : -1; - } - } - if (!j++) break; - λ0 = λ, sinφ0 = sinφ, cosφ0 = cosφ, point0 = point; - } - } - return (polarAngle < -ε || polarAngle < ε && d3_geo_areaRingSum < 0) ^ winding & 1; - } - var d3_geo_clipAntimeridian = d3_geo_clip(d3_true, d3_geo_clipAntimeridianLine, d3_geo_clipAntimeridianInterpolate, [ -Ï€, -Ï€ / 2 ]); - function d3_geo_clipAntimeridianLine(listener) { - var λ0 = NaN, φ0 = NaN, sλ0 = NaN, clean; - return { - lineStart: function() { - listener.lineStart(); - clean = 1; - }, - point: function(λ1, φ1) { - var sλ1 = λ1 > 0 ? Ï€ : -Ï€, dλ = abs(λ1 - λ0); - if (abs(dλ - Ï€) < ε) { - listener.point(λ0, φ0 = (φ0 + φ1) / 2 > 0 ? halfÏ€ : -halfÏ€); - listener.point(sλ0, φ0); - listener.lineEnd(); - listener.lineStart(); - listener.point(sλ1, φ0); - listener.point(λ1, φ0); - clean = 0; - } else if (sλ0 !== sλ1 && dλ >= Ï€) { - if (abs(λ0 - sλ0) < ε) λ0 -= sλ0 * ε; - if (abs(λ1 - sλ1) < ε) λ1 -= sλ1 * ε; - φ0 = d3_geo_clipAntimeridianIntersect(λ0, φ0, λ1, φ1); - listener.point(sλ0, φ0); - listener.lineEnd(); - listener.lineStart(); - listener.point(sλ1, φ0); - clean = 0; - } - listener.point(λ0 = λ1, φ0 = φ1); - sλ0 = sλ1; - }, - lineEnd: function() { - listener.lineEnd(); - λ0 = φ0 = NaN; - }, - clean: function() { - return 2 - clean; - } - }; - } - function d3_geo_clipAntimeridianIntersect(λ0, φ0, λ1, φ1) { - var cosφ0, cosφ1, sinλ0_λ1 = Math.sin(λ0 - λ1); - return abs(sinλ0_λ1) > ε ? Math.atan((Math.sin(φ0) * (cosφ1 = Math.cos(φ1)) * Math.sin(λ1) - Math.sin(φ1) * (cosφ0 = Math.cos(φ0)) * Math.sin(λ0)) / (cosφ0 * cosφ1 * sinλ0_λ1)) : (φ0 + φ1) / 2; - } - function d3_geo_clipAntimeridianInterpolate(from, to, direction, listener) { - var φ; - if (from == null) { - φ = direction * halfÏ€; - listener.point(-Ï€, φ); - listener.point(0, φ); - listener.point(Ï€, φ); - listener.point(Ï€, 0); - listener.point(Ï€, -φ); - listener.point(0, -φ); - listener.point(-Ï€, -φ); - listener.point(-Ï€, 0); - listener.point(-Ï€, φ); - } else if (abs(from[0] - to[0]) > ε) { - var s = from[0] < to[0] ? Ï€ : -Ï€; - φ = direction * s / 2; - listener.point(-s, φ); - listener.point(0, φ); - listener.point(s, φ); - } else { - listener.point(to[0], to[1]); - } - } - function d3_geo_clipCircle(radius) { - var cr = Math.cos(radius), smallRadius = cr > 0, notHemisphere = abs(cr) > ε, interpolate = d3_geo_circleInterpolate(radius, 6 * d3_radians); - return d3_geo_clip(visible, clipLine, interpolate, smallRadius ? [ 0, -radius ] : [ -Ï€, radius - Ï€ ]); - function visible(λ, φ) { - return Math.cos(λ) * Math.cos(φ) > cr; - } - function clipLine(listener) { - var point0, c0, v0, v00, clean; - return { - lineStart: function() { - v00 = v0 = false; - clean = 1; - }, - point: function(λ, φ) { - var point1 = [ λ, φ ], point2, v = visible(λ, φ), c = smallRadius ? v ? 0 : code(λ, φ) : v ? code(λ + (λ < 0 ? Ï€ : -Ï€), φ) : 0; - if (!point0 && (v00 = v0 = v)) listener.lineStart(); - if (v !== v0) { - point2 = intersect(point0, point1); - if (d3_geo_sphericalEqual(point0, point2) || d3_geo_sphericalEqual(point1, point2)) { - point1[0] += ε; - point1[1] += ε; - v = visible(point1[0], point1[1]); - } - } - if (v !== v0) { - clean = 0; - if (v) { - listener.lineStart(); - point2 = intersect(point1, point0); - listener.point(point2[0], point2[1]); - } else { - point2 = intersect(point0, point1); - listener.point(point2[0], point2[1]); - listener.lineEnd(); - } - point0 = point2; - } else if (notHemisphere && point0 && smallRadius ^ v) { - var t; - if (!(c & c0) && (t = intersect(point1, point0, true))) { - clean = 0; - if (smallRadius) { - listener.lineStart(); - listener.point(t[0][0], t[0][1]); - listener.point(t[1][0], t[1][1]); - listener.lineEnd(); - } else { - listener.point(t[1][0], t[1][1]); - listener.lineEnd(); - listener.lineStart(); - listener.point(t[0][0], t[0][1]); - } - } - } - if (v && (!point0 || !d3_geo_sphericalEqual(point0, point1))) { - listener.point(point1[0], point1[1]); - } - point0 = point1, v0 = v, c0 = c; - }, - lineEnd: function() { - if (v0) listener.lineEnd(); - point0 = null; - }, - clean: function() { - return clean | (v00 && v0) << 1; - } - }; - } - function intersect(a, b, two) { - var pa = d3_geo_cartesian(a), pb = d3_geo_cartesian(b); - var n1 = [ 1, 0, 0 ], n2 = d3_geo_cartesianCross(pa, pb), n2n2 = d3_geo_cartesianDot(n2, n2), n1n2 = n2[0], determinant = n2n2 - n1n2 * n1n2; - if (!determinant) return !two && a; - var c1 = cr * n2n2 / determinant, c2 = -cr * n1n2 / determinant, n1xn2 = d3_geo_cartesianCross(n1, n2), A = d3_geo_cartesianScale(n1, c1), B = d3_geo_cartesianScale(n2, c2); - d3_geo_cartesianAdd(A, B); - var u = n1xn2, w = d3_geo_cartesianDot(A, u), uu = d3_geo_cartesianDot(u, u), t2 = w * w - uu * (d3_geo_cartesianDot(A, A) - 1); - if (t2 < 0) return; - var t = Math.sqrt(t2), q = d3_geo_cartesianScale(u, (-w - t) / uu); - d3_geo_cartesianAdd(q, A); - q = d3_geo_spherical(q); - if (!two) return q; - var λ0 = a[0], λ1 = b[0], φ0 = a[1], φ1 = b[1], z; - if (λ1 < λ0) z = λ0, λ0 = λ1, λ1 = z; - var δλ = λ1 - λ0, polar = abs(δλ - Ï€) < ε, meridian = polar || δλ < ε; - if (!polar && φ1 < φ0) z = φ0, φ0 = φ1, φ1 = z; - if (meridian ? polar ? φ0 + φ1 > 0 ^ q[1] < (abs(q[0] - λ0) < ε ? φ0 : φ1) : φ0 <= q[1] && q[1] <= φ1 : δλ > Ï€ ^ (λ0 <= q[0] && q[0] <= λ1)) { - var q1 = d3_geo_cartesianScale(u, (-w + t) / uu); - d3_geo_cartesianAdd(q1, A); - return [ q, d3_geo_spherical(q1) ]; - } - } - function code(λ, φ) { - var r = smallRadius ? radius : Ï€ - radius, code = 0; - if (λ < -r) code |= 1; else if (λ > r) code |= 2; - if (φ < -r) code |= 4; else if (φ > r) code |= 8; - return code; - } - } - function d3_geom_clipLine(x0, y0, x1, y1) { - return function(line) { - var a = line.a, b = line.b, ax = a.x, ay = a.y, bx = b.x, by = b.y, t0 = 0, t1 = 1, dx = bx - ax, dy = by - ay, r; - r = x0 - ax; - if (!dx && r > 0) return; - r /= dx; - if (dx < 0) { - if (r < t0) return; - if (r < t1) t1 = r; - } else if (dx > 0) { - if (r > t1) return; - if (r > t0) t0 = r; - } - r = x1 - ax; - if (!dx && r < 0) return; - r /= dx; - if (dx < 0) { - if (r > t1) return; - if (r > t0) t0 = r; - } else if (dx > 0) { - if (r < t0) return; - if (r < t1) t1 = r; - } - r = y0 - ay; - if (!dy && r > 0) return; - r /= dy; - if (dy < 0) { - if (r < t0) return; - if (r < t1) t1 = r; - } else if (dy > 0) { - if (r > t1) return; - if (r > t0) t0 = r; - } - r = y1 - ay; - if (!dy && r < 0) return; - r /= dy; - if (dy < 0) { - if (r > t1) return; - if (r > t0) t0 = r; - } else if (dy > 0) { - if (r < t0) return; - if (r < t1) t1 = r; - } - if (t0 > 0) line.a = { - x: ax + t0 * dx, - y: ay + t0 * dy - }; - if (t1 < 1) line.b = { - x: ax + t1 * dx, - y: ay + t1 * dy - }; - return line; - }; - } - var d3_geo_clipExtentMAX = 1e9; - d3.geo.clipExtent = function() { - var x0, y0, x1, y1, stream, clip, clipExtent = { - stream: function(output) { - if (stream) stream.valid = false; - stream = clip(output); - stream.valid = true; - return stream; - }, - extent: function(_) { - if (!arguments.length) return [ [ x0, y0 ], [ x1, y1 ] ]; - clip = d3_geo_clipExtent(x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1]); - if (stream) stream.valid = false, stream = null; - return clipExtent; - } - }; - return clipExtent.extent([ [ 0, 0 ], [ 960, 500 ] ]); - }; - function d3_geo_clipExtent(x0, y0, x1, y1) { - return function(listener) { - var listener_ = listener, bufferListener = d3_geo_clipBufferListener(), clipLine = d3_geom_clipLine(x0, y0, x1, y1), segments, polygon, ring; - var clip = { - point: point, - lineStart: lineStart, - lineEnd: lineEnd, - polygonStart: function() { - listener = bufferListener; - segments = []; - polygon = []; - clean = true; - }, - polygonEnd: function() { - listener = listener_; - segments = d3.merge(segments); - var clipStartInside = insidePolygon([ x0, y1 ]), inside = clean && clipStartInside, visible = segments.length; - if (inside || visible) { - listener.polygonStart(); - if (inside) { - listener.lineStart(); - interpolate(null, null, 1, listener); - listener.lineEnd(); - } - if (visible) { - d3_geo_clipPolygon(segments, compare, clipStartInside, interpolate, listener); - } - listener.polygonEnd(); - } - segments = polygon = ring = null; - } - }; - function insidePolygon(p) { - var wn = 0, n = polygon.length, y = p[1]; - for (var i = 0; i < n; ++i) { - for (var j = 1, v = polygon[i], m = v.length, a = v[0], b; j < m; ++j) { - b = v[j]; - if (a[1] <= y) { - if (b[1] > y && d3_cross2d(a, b, p) > 0) ++wn; - } else { - if (b[1] <= y && d3_cross2d(a, b, p) < 0) --wn; - } - a = b; - } - } - return wn !== 0; - } - function interpolate(from, to, direction, listener) { - var a = 0, a1 = 0; - if (from == null || (a = corner(from, direction)) !== (a1 = corner(to, direction)) || comparePoints(from, to) < 0 ^ direction > 0) { - do { - listener.point(a === 0 || a === 3 ? x0 : x1, a > 1 ? y1 : y0); - } while ((a = (a + direction + 4) % 4) !== a1); - } else { - listener.point(to[0], to[1]); - } - } - function pointVisible(x, y) { - return x0 <= x && x <= x1 && y0 <= y && y <= y1; - } - function point(x, y) { - if (pointVisible(x, y)) listener.point(x, y); - } - var x__, y__, v__, x_, y_, v_, first, clean; - function lineStart() { - clip.point = linePoint; - if (polygon) polygon.push(ring = []); - first = true; - v_ = false; - x_ = y_ = NaN; - } - function lineEnd() { - if (segments) { - linePoint(x__, y__); - if (v__ && v_) bufferListener.rejoin(); - segments.push(bufferListener.buffer()); - } - clip.point = point; - if (v_) listener.lineEnd(); - } - function linePoint(x, y) { - x = Math.max(-d3_geo_clipExtentMAX, Math.min(d3_geo_clipExtentMAX, x)); - y = Math.max(-d3_geo_clipExtentMAX, Math.min(d3_geo_clipExtentMAX, y)); - var v = pointVisible(x, y); - if (polygon) ring.push([ x, y ]); - if (first) { - x__ = x, y__ = y, v__ = v; - first = false; - if (v) { - listener.lineStart(); - listener.point(x, y); - } - } else { - if (v && v_) listener.point(x, y); else { - var l = { - a: { - x: x_, - y: y_ - }, - b: { - x: x, - y: y - } - }; - if (clipLine(l)) { - if (!v_) { - listener.lineStart(); - listener.point(l.a.x, l.a.y); - } - listener.point(l.b.x, l.b.y); - if (!v) listener.lineEnd(); - clean = false; - } else if (v) { - listener.lineStart(); - listener.point(x, y); - clean = false; - } - } - } - x_ = x, y_ = y, v_ = v; - } - return clip; - }; - function corner(p, direction) { - return abs(p[0] - x0) < ε ? direction > 0 ? 0 : 3 : abs(p[0] - x1) < ε ? direction > 0 ? 2 : 1 : abs(p[1] - y0) < ε ? direction > 0 ? 1 : 0 : direction > 0 ? 3 : 2; - } - function compare(a, b) { - return comparePoints(a.x, b.x); - } - function comparePoints(a, b) { - var ca = corner(a, 1), cb = corner(b, 1); - return ca !== cb ? ca - cb : ca === 0 ? b[1] - a[1] : ca === 1 ? a[0] - b[0] : ca === 2 ? a[1] - b[1] : b[0] - a[0]; - } - } - function d3_geo_compose(a, b) { - function compose(x, y) { - return x = a(x, y), b(x[0], x[1]); - } - if (a.invert && b.invert) compose.invert = function(x, y) { - return x = b.invert(x, y), x && a.invert(x[0], x[1]); - }; - return compose; - } - function d3_geo_conic(projectAt) { - var φ0 = 0, φ1 = Ï€ / 3, m = d3_geo_projectionMutator(projectAt), p = m(φ0, φ1); - p.parallels = function(_) { - if (!arguments.length) return [ φ0 / Ï€ * 180, φ1 / Ï€ * 180 ]; - return m(φ0 = _[0] * Ï€ / 180, φ1 = _[1] * Ï€ / 180); - }; - return p; - } - function d3_geo_conicEqualArea(φ0, φ1) { - var sinφ0 = Math.sin(φ0), n = (sinφ0 + Math.sin(φ1)) / 2, C = 1 + sinφ0 * (2 * n - sinφ0), Ï0 = Math.sqrt(C) / n; - function forward(λ, φ) { - var Ï = Math.sqrt(C - 2 * n * Math.sin(φ)) / n; - return [ Ï * Math.sin(λ *= n), Ï0 - Ï * Math.cos(λ) ]; - } - forward.invert = function(x, y) { - var Ï0_y = Ï0 - y; - return [ Math.atan2(x, Ï0_y) / n, d3_asin((C - (x * x + Ï0_y * Ï0_y) * n * n) / (2 * n)) ]; - }; - return forward; - } - (d3.geo.conicEqualArea = function() { - return d3_geo_conic(d3_geo_conicEqualArea); - }).raw = d3_geo_conicEqualArea; - d3.geo.albers = function() { - return d3.geo.conicEqualArea().rotate([ 96, 0 ]).center([ -.6, 38.7 ]).parallels([ 29.5, 45.5 ]).scale(1070); - }; - d3.geo.albersUsa = function() { - var lower48 = d3.geo.albers(); - var alaska = d3.geo.conicEqualArea().rotate([ 154, 0 ]).center([ -2, 58.5 ]).parallels([ 55, 65 ]); - var hawaii = d3.geo.conicEqualArea().rotate([ 157, 0 ]).center([ -3, 19.9 ]).parallels([ 8, 18 ]); - var point, pointStream = { - point: function(x, y) { - point = [ x, y ]; - } - }, lower48Point, alaskaPoint, hawaiiPoint; - function albersUsa(coordinates) { - var x = coordinates[0], y = coordinates[1]; - point = null; - (lower48Point(x, y), point) || (alaskaPoint(x, y), point) || hawaiiPoint(x, y); - return point; - } - albersUsa.invert = function(coordinates) { - var k = lower48.scale(), t = lower48.translate(), x = (coordinates[0] - t[0]) / k, y = (coordinates[1] - t[1]) / k; - return (y >= .12 && y < .234 && x >= -.425 && x < -.214 ? alaska : y >= .166 && y < .234 && x >= -.214 && x < -.115 ? hawaii : lower48).invert(coordinates); - }; - albersUsa.stream = function(stream) { - var lower48Stream = lower48.stream(stream), alaskaStream = alaska.stream(stream), hawaiiStream = hawaii.stream(stream); - return { - point: function(x, y) { - lower48Stream.point(x, y); - alaskaStream.point(x, y); - hawaiiStream.point(x, y); - }, - sphere: function() { - lower48Stream.sphere(); - alaskaStream.sphere(); - hawaiiStream.sphere(); - }, - lineStart: function() { - lower48Stream.lineStart(); - alaskaStream.lineStart(); - hawaiiStream.lineStart(); - }, - lineEnd: function() { - lower48Stream.lineEnd(); - alaskaStream.lineEnd(); - hawaiiStream.lineEnd(); - }, - polygonStart: function() { - lower48Stream.polygonStart(); - alaskaStream.polygonStart(); - hawaiiStream.polygonStart(); - }, - polygonEnd: function() { - lower48Stream.polygonEnd(); - alaskaStream.polygonEnd(); - hawaiiStream.polygonEnd(); - } - }; - }; - albersUsa.precision = function(_) { - if (!arguments.length) return lower48.precision(); - lower48.precision(_); - alaska.precision(_); - hawaii.precision(_); - return albersUsa; - }; - albersUsa.scale = function(_) { - if (!arguments.length) return lower48.scale(); - lower48.scale(_); - alaska.scale(_ * .35); - hawaii.scale(_); - return albersUsa.translate(lower48.translate()); - }; - albersUsa.translate = function(_) { - if (!arguments.length) return lower48.translate(); - var k = lower48.scale(), x = +_[0], y = +_[1]; - lower48Point = lower48.translate(_).clipExtent([ [ x - .455 * k, y - .238 * k ], [ x + .455 * k, y + .238 * k ] ]).stream(pointStream).point; - alaskaPoint = alaska.translate([ x - .307 * k, y + .201 * k ]).clipExtent([ [ x - .425 * k + ε, y + .12 * k + ε ], [ x - .214 * k - ε, y + .234 * k - ε ] ]).stream(pointStream).point; - hawaiiPoint = hawaii.translate([ x - .205 * k, y + .212 * k ]).clipExtent([ [ x - .214 * k + ε, y + .166 * k + ε ], [ x - .115 * k - ε, y + .234 * k - ε ] ]).stream(pointStream).point; - return albersUsa; - }; - return albersUsa.scale(1070); - }; - var d3_geo_pathAreaSum, d3_geo_pathAreaPolygon, d3_geo_pathArea = { - point: d3_noop, - lineStart: d3_noop, - lineEnd: d3_noop, - polygonStart: function() { - d3_geo_pathAreaPolygon = 0; - d3_geo_pathArea.lineStart = d3_geo_pathAreaRingStart; - }, - polygonEnd: function() { - d3_geo_pathArea.lineStart = d3_geo_pathArea.lineEnd = d3_geo_pathArea.point = d3_noop; - d3_geo_pathAreaSum += abs(d3_geo_pathAreaPolygon / 2); - } - }; - function d3_geo_pathAreaRingStart() { - var x00, y00, x0, y0; - d3_geo_pathArea.point = function(x, y) { - d3_geo_pathArea.point = nextPoint; - x00 = x0 = x, y00 = y0 = y; - }; - function nextPoint(x, y) { - d3_geo_pathAreaPolygon += y0 * x - x0 * y; - x0 = x, y0 = y; - } - d3_geo_pathArea.lineEnd = function() { - nextPoint(x00, y00); - }; - } - var d3_geo_pathBoundsX0, d3_geo_pathBoundsY0, d3_geo_pathBoundsX1, d3_geo_pathBoundsY1; - var d3_geo_pathBounds = { - point: d3_geo_pathBoundsPoint, - lineStart: d3_noop, - lineEnd: d3_noop, - polygonStart: d3_noop, - polygonEnd: d3_noop - }; - function d3_geo_pathBoundsPoint(x, y) { - if (x < d3_geo_pathBoundsX0) d3_geo_pathBoundsX0 = x; - if (x > d3_geo_pathBoundsX1) d3_geo_pathBoundsX1 = x; - if (y < d3_geo_pathBoundsY0) d3_geo_pathBoundsY0 = y; - if (y > d3_geo_pathBoundsY1) d3_geo_pathBoundsY1 = y; - } - function d3_geo_pathBuffer() { - var pointCircle = d3_geo_pathBufferCircle(4.5), buffer = []; - var stream = { - point: point, - lineStart: function() { - stream.point = pointLineStart; - }, - lineEnd: lineEnd, - polygonStart: function() { - stream.lineEnd = lineEndPolygon; - }, - polygonEnd: function() { - stream.lineEnd = lineEnd; - stream.point = point; - }, - pointRadius: function(_) { - pointCircle = d3_geo_pathBufferCircle(_); - return stream; - }, - result: function() { - if (buffer.length) { - var result = buffer.join(""); - buffer = []; - return result; - } - } - }; - function point(x, y) { - buffer.push("M", x, ",", y, pointCircle); - } - function pointLineStart(x, y) { - buffer.push("M", x, ",", y); - stream.point = pointLine; - } - function pointLine(x, y) { - buffer.push("L", x, ",", y); - } - function lineEnd() { - stream.point = point; - } - function lineEndPolygon() { - buffer.push("Z"); - } - return stream; - } - function d3_geo_pathBufferCircle(radius) { - return "m0," + radius + "a" + radius + "," + radius + " 0 1,1 0," + -2 * radius + "a" + radius + "," + radius + " 0 1,1 0," + 2 * radius + "z"; - } - var d3_geo_pathCentroid = { - point: d3_geo_pathCentroidPoint, - lineStart: d3_geo_pathCentroidLineStart, - lineEnd: d3_geo_pathCentroidLineEnd, - polygonStart: function() { - d3_geo_pathCentroid.lineStart = d3_geo_pathCentroidRingStart; - }, - polygonEnd: function() { - d3_geo_pathCentroid.point = d3_geo_pathCentroidPoint; - d3_geo_pathCentroid.lineStart = d3_geo_pathCentroidLineStart; - d3_geo_pathCentroid.lineEnd = d3_geo_pathCentroidLineEnd; - } - }; - function d3_geo_pathCentroidPoint(x, y) { - d3_geo_centroidX0 += x; - d3_geo_centroidY0 += y; - ++d3_geo_centroidZ0; - } - function d3_geo_pathCentroidLineStart() { - var x0, y0; - d3_geo_pathCentroid.point = function(x, y) { - d3_geo_pathCentroid.point = nextPoint; - d3_geo_pathCentroidPoint(x0 = x, y0 = y); - }; - function nextPoint(x, y) { - var dx = x - x0, dy = y - y0, z = Math.sqrt(dx * dx + dy * dy); - d3_geo_centroidX1 += z * (x0 + x) / 2; - d3_geo_centroidY1 += z * (y0 + y) / 2; - d3_geo_centroidZ1 += z; - d3_geo_pathCentroidPoint(x0 = x, y0 = y); - } - } - function d3_geo_pathCentroidLineEnd() { - d3_geo_pathCentroid.point = d3_geo_pathCentroidPoint; - } - function d3_geo_pathCentroidRingStart() { - var x00, y00, x0, y0; - d3_geo_pathCentroid.point = function(x, y) { - d3_geo_pathCentroid.point = nextPoint; - d3_geo_pathCentroidPoint(x00 = x0 = x, y00 = y0 = y); - }; - function nextPoint(x, y) { - var dx = x - x0, dy = y - y0, z = Math.sqrt(dx * dx + dy * dy); - d3_geo_centroidX1 += z * (x0 + x) / 2; - d3_geo_centroidY1 += z * (y0 + y) / 2; - d3_geo_centroidZ1 += z; - z = y0 * x - x0 * y; - d3_geo_centroidX2 += z * (x0 + x); - d3_geo_centroidY2 += z * (y0 + y); - d3_geo_centroidZ2 += z * 3; - d3_geo_pathCentroidPoint(x0 = x, y0 = y); - } - d3_geo_pathCentroid.lineEnd = function() { - nextPoint(x00, y00); - }; - } - function d3_geo_pathContext(context) { - var pointRadius = 4.5; - var stream = { - point: point, - lineStart: function() { - stream.point = pointLineStart; - }, - lineEnd: lineEnd, - polygonStart: function() { - stream.lineEnd = lineEndPolygon; - }, - polygonEnd: function() { - stream.lineEnd = lineEnd; - stream.point = point; - }, - pointRadius: function(_) { - pointRadius = _; - return stream; - }, - result: d3_noop - }; - function point(x, y) { - context.moveTo(x, y); - context.arc(x, y, pointRadius, 0, Ï„); - } - function pointLineStart(x, y) { - context.moveTo(x, y); - stream.point = pointLine; - } - function pointLine(x, y) { - context.lineTo(x, y); - } - function lineEnd() { - stream.point = point; - } - function lineEndPolygon() { - context.closePath(); - } - return stream; - } - function d3_geo_resample(project) { - var δ2 = .5, cosMinDistance = Math.cos(30 * d3_radians), maxDepth = 16; - function resample(stream) { - return (maxDepth ? resampleRecursive : resampleNone)(stream); - } - function resampleNone(stream) { - return d3_geo_transformPoint(stream, function(x, y) { - x = project(x, y); - stream.point(x[0], x[1]); - }); - } - function resampleRecursive(stream) { - var λ00, φ00, x00, y00, a00, b00, c00, λ0, x0, y0, a0, b0, c0; - var resample = { - point: point, - lineStart: lineStart, - lineEnd: lineEnd, - polygonStart: function() { - stream.polygonStart(); - resample.lineStart = ringStart; - }, - polygonEnd: function() { - stream.polygonEnd(); - resample.lineStart = lineStart; - } - }; - function point(x, y) { - x = project(x, y); - stream.point(x[0], x[1]); - } - function lineStart() { - x0 = NaN; - resample.point = linePoint; - stream.lineStart(); - } - function linePoint(λ, φ) { - var c = d3_geo_cartesian([ λ, φ ]), p = project(λ, φ); - resampleLineTo(x0, y0, λ0, a0, b0, c0, x0 = p[0], y0 = p[1], λ0 = λ, a0 = c[0], b0 = c[1], c0 = c[2], maxDepth, stream); - stream.point(x0, y0); - } - function lineEnd() { - resample.point = point; - stream.lineEnd(); - } - function ringStart() { - lineStart(); - resample.point = ringPoint; - resample.lineEnd = ringEnd; - } - function ringPoint(λ, φ) { - linePoint(λ00 = λ, φ00 = φ), x00 = x0, y00 = y0, a00 = a0, b00 = b0, c00 = c0; - resample.point = linePoint; - } - function ringEnd() { - resampleLineTo(x0, y0, λ0, a0, b0, c0, x00, y00, λ00, a00, b00, c00, maxDepth, stream); - resample.lineEnd = lineEnd; - lineEnd(); - } - return resample; - } - function resampleLineTo(x0, y0, λ0, a0, b0, c0, x1, y1, λ1, a1, b1, c1, depth, stream) { - var dx = x1 - x0, dy = y1 - y0, d2 = dx * dx + dy * dy; - if (d2 > 4 * δ2 && depth--) { - var a = a0 + a1, b = b0 + b1, c = c0 + c1, m = Math.sqrt(a * a + b * b + c * c), φ2 = Math.asin(c /= m), λ2 = abs(abs(c) - 1) < ε || abs(λ0 - λ1) < ε ? (λ0 + λ1) / 2 : Math.atan2(b, a), p = project(λ2, φ2), x2 = p[0], y2 = p[1], dx2 = x2 - x0, dy2 = y2 - y0, dz = dy * dx2 - dx * dy2; - if (dz * dz / d2 > δ2 || abs((dx * dx2 + dy * dy2) / d2 - .5) > .3 || a0 * a1 + b0 * b1 + c0 * c1 < cosMinDistance) { - resampleLineTo(x0, y0, λ0, a0, b0, c0, x2, y2, λ2, a /= m, b /= m, c, depth, stream); - stream.point(x2, y2); - resampleLineTo(x2, y2, λ2, a, b, c, x1, y1, λ1, a1, b1, c1, depth, stream); - } - } - } - resample.precision = function(_) { - if (!arguments.length) return Math.sqrt(δ2); - maxDepth = (δ2 = _ * _) > 0 && 16; - return resample; - }; - return resample; - } - d3.geo.path = function() { - var pointRadius = 4.5, projection, context, projectStream, contextStream, cacheStream; - function path(object) { - if (object) { - if (typeof pointRadius === "function") contextStream.pointRadius(+pointRadius.apply(this, arguments)); - if (!cacheStream || !cacheStream.valid) cacheStream = projectStream(contextStream); - d3.geo.stream(object, cacheStream); - } - return contextStream.result(); - } - path.area = function(object) { - d3_geo_pathAreaSum = 0; - d3.geo.stream(object, projectStream(d3_geo_pathArea)); - return d3_geo_pathAreaSum; - }; - path.centroid = function(object) { - d3_geo_centroidX0 = d3_geo_centroidY0 = d3_geo_centroidZ0 = d3_geo_centroidX1 = d3_geo_centroidY1 = d3_geo_centroidZ1 = d3_geo_centroidX2 = d3_geo_centroidY2 = d3_geo_centroidZ2 = 0; - d3.geo.stream(object, projectStream(d3_geo_pathCentroid)); - return d3_geo_centroidZ2 ? [ d3_geo_centroidX2 / d3_geo_centroidZ2, d3_geo_centroidY2 / d3_geo_centroidZ2 ] : d3_geo_centroidZ1 ? [ d3_geo_centroidX1 / d3_geo_centroidZ1, d3_geo_centroidY1 / d3_geo_centroidZ1 ] : d3_geo_centroidZ0 ? [ d3_geo_centroidX0 / d3_geo_centroidZ0, d3_geo_centroidY0 / d3_geo_centroidZ0 ] : [ NaN, NaN ]; - }; - path.bounds = function(object) { - d3_geo_pathBoundsX1 = d3_geo_pathBoundsY1 = -(d3_geo_pathBoundsX0 = d3_geo_pathBoundsY0 = Infinity); - d3.geo.stream(object, projectStream(d3_geo_pathBounds)); - return [ [ d3_geo_pathBoundsX0, d3_geo_pathBoundsY0 ], [ d3_geo_pathBoundsX1, d3_geo_pathBoundsY1 ] ]; - }; - path.projection = function(_) { - if (!arguments.length) return projection; - projectStream = (projection = _) ? _.stream || d3_geo_pathProjectStream(_) : d3_identity; - return reset(); - }; - path.context = function(_) { - if (!arguments.length) return context; - contextStream = (context = _) == null ? new d3_geo_pathBuffer() : new d3_geo_pathContext(_); - if (typeof pointRadius !== "function") contextStream.pointRadius(pointRadius); - return reset(); - }; - path.pointRadius = function(_) { - if (!arguments.length) return pointRadius; - pointRadius = typeof _ === "function" ? _ : (contextStream.pointRadius(+_), +_); - return path; - }; - function reset() { - cacheStream = null; - return path; - } - return path.projection(d3.geo.albersUsa()).context(null); - }; - function d3_geo_pathProjectStream(project) { - var resample = d3_geo_resample(function(x, y) { - return project([ x * d3_degrees, y * d3_degrees ]); - }); - return function(stream) { - return d3_geo_projectionRadians(resample(stream)); - }; - } - d3.geo.transform = function(methods) { - return { - stream: function(stream) { - var transform = new d3_geo_transform(stream); - for (var k in methods) transform[k] = methods[k]; - return transform; - } - }; - }; - function d3_geo_transform(stream) { - this.stream = stream; - } - d3_geo_transform.prototype = { - point: function(x, y) { - this.stream.point(x, y); - }, - sphere: function() { - this.stream.sphere(); - }, - lineStart: function() { - this.stream.lineStart(); - }, - lineEnd: function() { - this.stream.lineEnd(); - }, - polygonStart: function() { - this.stream.polygonStart(); - }, - polygonEnd: function() { - this.stream.polygonEnd(); - } - }; - function d3_geo_transformPoint(stream, point) { - return { - point: point, - sphere: function() { - stream.sphere(); - }, - lineStart: function() { - stream.lineStart(); - }, - lineEnd: function() { - stream.lineEnd(); - }, - polygonStart: function() { - stream.polygonStart(); - }, - polygonEnd: function() { - stream.polygonEnd(); - } - }; - } - d3.geo.projection = d3_geo_projection; - d3.geo.projectionMutator = d3_geo_projectionMutator; - function d3_geo_projection(project) { - return d3_geo_projectionMutator(function() { - return project; - })(); - } - function d3_geo_projectionMutator(projectAt) { - var project, rotate, projectRotate, projectResample = d3_geo_resample(function(x, y) { - x = project(x, y); - return [ x[0] * k + δx, δy - x[1] * k ]; - }), k = 150, x = 480, y = 250, λ = 0, φ = 0, δλ = 0, δφ = 0, δγ = 0, δx, δy, preclip = d3_geo_clipAntimeridian, postclip = d3_identity, clipAngle = null, clipExtent = null, stream; - function projection(point) { - point = projectRotate(point[0] * d3_radians, point[1] * d3_radians); - return [ point[0] * k + δx, δy - point[1] * k ]; - } - function invert(point) { - point = projectRotate.invert((point[0] - δx) / k, (δy - point[1]) / k); - return point && [ point[0] * d3_degrees, point[1] * d3_degrees ]; - } - projection.stream = function(output) { - if (stream) stream.valid = false; - stream = d3_geo_projectionRadians(preclip(rotate, projectResample(postclip(output)))); - stream.valid = true; - return stream; - }; - projection.clipAngle = function(_) { - if (!arguments.length) return clipAngle; - preclip = _ == null ? (clipAngle = _, d3_geo_clipAntimeridian) : d3_geo_clipCircle((clipAngle = +_) * d3_radians); - return invalidate(); - }; - projection.clipExtent = function(_) { - if (!arguments.length) return clipExtent; - clipExtent = _; - postclip = _ ? d3_geo_clipExtent(_[0][0], _[0][1], _[1][0], _[1][1]) : d3_identity; - return invalidate(); - }; - projection.scale = function(_) { - if (!arguments.length) return k; - k = +_; - return reset(); - }; - projection.translate = function(_) { - if (!arguments.length) return [ x, y ]; - x = +_[0]; - y = +_[1]; - return reset(); - }; - projection.center = function(_) { - if (!arguments.length) return [ λ * d3_degrees, φ * d3_degrees ]; - λ = _[0] % 360 * d3_radians; - φ = _[1] % 360 * d3_radians; - return reset(); - }; - projection.rotate = function(_) { - if (!arguments.length) return [ δλ * d3_degrees, δφ * d3_degrees, δγ * d3_degrees ]; - δλ = _[0] % 360 * d3_radians; - δφ = _[1] % 360 * d3_radians; - δγ = _.length > 2 ? _[2] % 360 * d3_radians : 0; - return reset(); - }; - d3.rebind(projection, projectResample, "precision"); - function reset() { - projectRotate = d3_geo_compose(rotate = d3_geo_rotation(δλ, δφ, δγ), project); - var center = project(λ, φ); - δx = x - center[0] * k; - δy = y + center[1] * k; - return invalidate(); - } - function invalidate() { - if (stream) stream.valid = false, stream = null; - return projection; - } - return function() { - project = projectAt.apply(this, arguments); - projection.invert = project.invert && invert; - return reset(); - }; - } - function d3_geo_projectionRadians(stream) { - return d3_geo_transformPoint(stream, function(x, y) { - stream.point(x * d3_radians, y * d3_radians); - }); - } - function d3_geo_equirectangular(λ, φ) { - return [ λ, φ ]; - } - (d3.geo.equirectangular = function() { - return d3_geo_projection(d3_geo_equirectangular); - }).raw = d3_geo_equirectangular.invert = d3_geo_equirectangular; - d3.geo.rotation = function(rotate) { - rotate = d3_geo_rotation(rotate[0] % 360 * d3_radians, rotate[1] * d3_radians, rotate.length > 2 ? rotate[2] * d3_radians : 0); - function forward(coordinates) { - coordinates = rotate(coordinates[0] * d3_radians, coordinates[1] * d3_radians); - return coordinates[0] *= d3_degrees, coordinates[1] *= d3_degrees, coordinates; - } - forward.invert = function(coordinates) { - coordinates = rotate.invert(coordinates[0] * d3_radians, coordinates[1] * d3_radians); - return coordinates[0] *= d3_degrees, coordinates[1] *= d3_degrees, coordinates; - }; - return forward; - }; - function d3_geo_identityRotation(λ, φ) { - return [ λ > Ï€ ? λ - Ï„ : λ < -Ï€ ? λ + Ï„ : λ, φ ]; - } - d3_geo_identityRotation.invert = d3_geo_equirectangular; - function d3_geo_rotation(δλ, δφ, δγ) { - return δλ ? δφ || δγ ? d3_geo_compose(d3_geo_rotationλ(δλ), d3_geo_rotationφγ(δφ, δγ)) : d3_geo_rotationλ(δλ) : δφ || δγ ? d3_geo_rotationφγ(δφ, δγ) : d3_geo_identityRotation; - } - function d3_geo_forwardRotationλ(δλ) { - return function(λ, φ) { - return λ += δλ, [ λ > Ï€ ? λ - Ï„ : λ < -Ï€ ? λ + Ï„ : λ, φ ]; - }; - } - function d3_geo_rotationλ(δλ) { - var rotation = d3_geo_forwardRotationλ(δλ); - rotation.invert = d3_geo_forwardRotationλ(-δλ); - return rotation; - } - function d3_geo_rotationφγ(δφ, δγ) { - var cosδφ = Math.cos(δφ), sinδφ = Math.sin(δφ), cosδγ = Math.cos(δγ), sinδγ = Math.sin(δγ); - function rotation(λ, φ) { - var cosφ = Math.cos(φ), x = Math.cos(λ) * cosφ, y = Math.sin(λ) * cosφ, z = Math.sin(φ), k = z * cosδφ + x * sinδφ; - return [ Math.atan2(y * cosδγ - k * sinδγ, x * cosδφ - z * sinδφ), d3_asin(k * cosδγ + y * sinδγ) ]; - } - rotation.invert = function(λ, φ) { - var cosφ = Math.cos(φ), x = Math.cos(λ) * cosφ, y = Math.sin(λ) * cosφ, z = Math.sin(φ), k = z * cosδγ - y * sinδγ; - return [ Math.atan2(y * cosδγ + z * sinδγ, x * cosδφ + k * sinδφ), d3_asin(k * cosδφ - x * sinδφ) ]; - }; - return rotation; - } - d3.geo.circle = function() { - var origin = [ 0, 0 ], angle, precision = 6, interpolate; - function circle() { - var center = typeof origin === "function" ? origin.apply(this, arguments) : origin, rotate = d3_geo_rotation(-center[0] * d3_radians, -center[1] * d3_radians, 0).invert, ring = []; - interpolate(null, null, 1, { - point: function(x, y) { - ring.push(x = rotate(x, y)); - x[0] *= d3_degrees, x[1] *= d3_degrees; - } - }); - return { - type: "Polygon", - coordinates: [ ring ] - }; - } - circle.origin = function(x) { - if (!arguments.length) return origin; - origin = x; - return circle; - }; - circle.angle = function(x) { - if (!arguments.length) return angle; - interpolate = d3_geo_circleInterpolate((angle = +x) * d3_radians, precision * d3_radians); - return circle; - }; - circle.precision = function(_) { - if (!arguments.length) return precision; - interpolate = d3_geo_circleInterpolate(angle * d3_radians, (precision = +_) * d3_radians); - return circle; - }; - return circle.angle(90); - }; - function d3_geo_circleInterpolate(radius, precision) { - var cr = Math.cos(radius), sr = Math.sin(radius); - return function(from, to, direction, listener) { - var step = direction * precision; - if (from != null) { - from = d3_geo_circleAngle(cr, from); - to = d3_geo_circleAngle(cr, to); - if (direction > 0 ? from < to : from > to) from += direction * Ï„; - } else { - from = radius + direction * Ï„; - to = radius - .5 * step; - } - for (var point, t = from; direction > 0 ? t > to : t < to; t -= step) { - listener.point((point = d3_geo_spherical([ cr, -sr * Math.cos(t), -sr * Math.sin(t) ]))[0], point[1]); - } - }; - } - function d3_geo_circleAngle(cr, point) { - var a = d3_geo_cartesian(point); - a[0] -= cr; - d3_geo_cartesianNormalize(a); - var angle = d3_acos(-a[1]); - return ((-a[2] < 0 ? -angle : angle) + 2 * Math.PI - ε) % (2 * Math.PI); - } - d3.geo.distance = function(a, b) { - var Δλ = (b[0] - a[0]) * d3_radians, φ0 = a[1] * d3_radians, φ1 = b[1] * d3_radians, sinΔλ = Math.sin(Δλ), cosΔλ = Math.cos(Δλ), sinφ0 = Math.sin(φ0), cosφ0 = Math.cos(φ0), sinφ1 = Math.sin(φ1), cosφ1 = Math.cos(φ1), t; - return Math.atan2(Math.sqrt((t = cosφ1 * sinΔλ) * t + (t = cosφ0 * sinφ1 - sinφ0 * cosφ1 * cosΔλ) * t), sinφ0 * sinφ1 + cosφ0 * cosφ1 * cosΔλ); - }; - d3.geo.graticule = function() { - var x1, x0, X1, X0, y1, y0, Y1, Y0, dx = 10, dy = dx, DX = 90, DY = 360, x, y, X, Y, precision = 2.5; - function graticule() { - return { - type: "MultiLineString", - coordinates: lines() - }; - } - function lines() { - return d3.range(Math.ceil(X0 / DX) * DX, X1, DX).map(X).concat(d3.range(Math.ceil(Y0 / DY) * DY, Y1, DY).map(Y)).concat(d3.range(Math.ceil(x0 / dx) * dx, x1, dx).filter(function(x) { - return abs(x % DX) > ε; - }).map(x)).concat(d3.range(Math.ceil(y0 / dy) * dy, y1, dy).filter(function(y) { - return abs(y % DY) > ε; - }).map(y)); - } - graticule.lines = function() { - return lines().map(function(coordinates) { - return { - type: "LineString", - coordinates: coordinates - }; - }); - }; - graticule.outline = function() { - return { - type: "Polygon", - coordinates: [ X(X0).concat(Y(Y1).slice(1), X(X1).reverse().slice(1), Y(Y0).reverse().slice(1)) ] - }; - }; - graticule.extent = function(_) { - if (!arguments.length) return graticule.minorExtent(); - return graticule.majorExtent(_).minorExtent(_); - }; - graticule.majorExtent = function(_) { - if (!arguments.length) return [ [ X0, Y0 ], [ X1, Y1 ] ]; - X0 = +_[0][0], X1 = +_[1][0]; - Y0 = +_[0][1], Y1 = +_[1][1]; - if (X0 > X1) _ = X0, X0 = X1, X1 = _; - if (Y0 > Y1) _ = Y0, Y0 = Y1, Y1 = _; - return graticule.precision(precision); - }; - graticule.minorExtent = function(_) { - if (!arguments.length) return [ [ x0, y0 ], [ x1, y1 ] ]; - x0 = +_[0][0], x1 = +_[1][0]; - y0 = +_[0][1], y1 = +_[1][1]; - if (x0 > x1) _ = x0, x0 = x1, x1 = _; - if (y0 > y1) _ = y0, y0 = y1, y1 = _; - return graticule.precision(precision); - }; - graticule.step = function(_) { - if (!arguments.length) return graticule.minorStep(); - return graticule.majorStep(_).minorStep(_); - }; - graticule.majorStep = function(_) { - if (!arguments.length) return [ DX, DY ]; - DX = +_[0], DY = +_[1]; - return graticule; - }; - graticule.minorStep = function(_) { - if (!arguments.length) return [ dx, dy ]; - dx = +_[0], dy = +_[1]; - return graticule; - }; - graticule.precision = function(_) { - if (!arguments.length) return precision; - precision = +_; - x = d3_geo_graticuleX(y0, y1, 90); - y = d3_geo_graticuleY(x0, x1, precision); - X = d3_geo_graticuleX(Y0, Y1, 90); - Y = d3_geo_graticuleY(X0, X1, precision); - return graticule; - }; - return graticule.majorExtent([ [ -180, -90 + ε ], [ 180, 90 - ε ] ]).minorExtent([ [ -180, -80 - ε ], [ 180, 80 + ε ] ]); - }; - function d3_geo_graticuleX(y0, y1, dy) { - var y = d3.range(y0, y1 - ε, dy).concat(y1); - return function(x) { - return y.map(function(y) { - return [ x, y ]; - }); - }; - } - function d3_geo_graticuleY(x0, x1, dx) { - var x = d3.range(x0, x1 - ε, dx).concat(x1); - return function(y) { - return x.map(function(x) { - return [ x, y ]; - }); - }; - } - function d3_source(d) { - return d.source; - } - function d3_target(d) { - return d.target; - } - d3.geo.greatArc = function() { - var source = d3_source, source_, target = d3_target, target_; - function greatArc() { - return { - type: "LineString", - coordinates: [ source_ || source.apply(this, arguments), target_ || target.apply(this, arguments) ] - }; - } - greatArc.distance = function() { - return d3.geo.distance(source_ || source.apply(this, arguments), target_ || target.apply(this, arguments)); - }; - greatArc.source = function(_) { - if (!arguments.length) return source; - source = _, source_ = typeof _ === "function" ? null : _; - return greatArc; - }; - greatArc.target = function(_) { - if (!arguments.length) return target; - target = _, target_ = typeof _ === "function" ? null : _; - return greatArc; - }; - greatArc.precision = function() { - return arguments.length ? greatArc : 0; - }; - return greatArc; - }; - d3.geo.interpolate = function(source, target) { - return d3_geo_interpolate(source[0] * d3_radians, source[1] * d3_radians, target[0] * d3_radians, target[1] * d3_radians); - }; - function d3_geo_interpolate(x0, y0, x1, y1) { - var cy0 = Math.cos(y0), sy0 = Math.sin(y0), cy1 = Math.cos(y1), sy1 = Math.sin(y1), kx0 = cy0 * Math.cos(x0), ky0 = cy0 * Math.sin(x0), kx1 = cy1 * Math.cos(x1), ky1 = cy1 * Math.sin(x1), d = 2 * Math.asin(Math.sqrt(d3_haversin(y1 - y0) + cy0 * cy1 * d3_haversin(x1 - x0))), k = 1 / Math.sin(d); - var interpolate = d ? function(t) { - var B = Math.sin(t *= d) * k, A = Math.sin(d - t) * k, x = A * kx0 + B * kx1, y = A * ky0 + B * ky1, z = A * sy0 + B * sy1; - return [ Math.atan2(y, x) * d3_degrees, Math.atan2(z, Math.sqrt(x * x + y * y)) * d3_degrees ]; - } : function() { - return [ x0 * d3_degrees, y0 * d3_degrees ]; - }; - interpolate.distance = d; - return interpolate; - } - d3.geo.length = function(object) { - d3_geo_lengthSum = 0; - d3.geo.stream(object, d3_geo_length); - return d3_geo_lengthSum; - }; - var d3_geo_lengthSum; - var d3_geo_length = { - sphere: d3_noop, - point: d3_noop, - lineStart: d3_geo_lengthLineStart, - lineEnd: d3_noop, - polygonStart: d3_noop, - polygonEnd: d3_noop - }; - function d3_geo_lengthLineStart() { - var λ0, sinφ0, cosφ0; - d3_geo_length.point = function(λ, φ) { - λ0 = λ * d3_radians, sinφ0 = Math.sin(φ *= d3_radians), cosφ0 = Math.cos(φ); - d3_geo_length.point = nextPoint; - }; - d3_geo_length.lineEnd = function() { - d3_geo_length.point = d3_geo_length.lineEnd = d3_noop; - }; - function nextPoint(λ, φ) { - var sinφ = Math.sin(φ *= d3_radians), cosφ = Math.cos(φ), t = abs((λ *= d3_radians) - λ0), cosΔλ = Math.cos(t); - d3_geo_lengthSum += Math.atan2(Math.sqrt((t = cosφ * Math.sin(t)) * t + (t = cosφ0 * sinφ - sinφ0 * cosφ * cosΔλ) * t), sinφ0 * sinφ + cosφ0 * cosφ * cosΔλ); - λ0 = λ, sinφ0 = sinφ, cosφ0 = cosφ; - } - } - function d3_geo_azimuthal(scale, angle) { - function azimuthal(λ, φ) { - var cosλ = Math.cos(λ), cosφ = Math.cos(φ), k = scale(cosλ * cosφ); - return [ k * cosφ * Math.sin(λ), k * Math.sin(φ) ]; - } - azimuthal.invert = function(x, y) { - var Ï = Math.sqrt(x * x + y * y), c = angle(Ï), sinc = Math.sin(c), cosc = Math.cos(c); - return [ Math.atan2(x * sinc, Ï * cosc), Math.asin(Ï && y * sinc / Ï) ]; - }; - return azimuthal; - } - var d3_geo_azimuthalEqualArea = d3_geo_azimuthal(function(cosλcosφ) { - return Math.sqrt(2 / (1 + cosλcosφ)); - }, function(Ï) { - return 2 * Math.asin(Ï / 2); - }); - (d3.geo.azimuthalEqualArea = function() { - return d3_geo_projection(d3_geo_azimuthalEqualArea); - }).raw = d3_geo_azimuthalEqualArea; - var d3_geo_azimuthalEquidistant = d3_geo_azimuthal(function(cosλcosφ) { - var c = Math.acos(cosλcosφ); - return c && c / Math.sin(c); - }, d3_identity); - (d3.geo.azimuthalEquidistant = function() { - return d3_geo_projection(d3_geo_azimuthalEquidistant); - }).raw = d3_geo_azimuthalEquidistant; - function d3_geo_conicConformal(φ0, φ1) { - var cosφ0 = Math.cos(φ0), t = function(φ) { - return Math.tan(Ï€ / 4 + φ / 2); - }, n = φ0 === φ1 ? Math.sin(φ0) : Math.log(cosφ0 / Math.cos(φ1)) / Math.log(t(φ1) / t(φ0)), F = cosφ0 * Math.pow(t(φ0), n) / n; - if (!n) return d3_geo_mercator; - function forward(λ, φ) { - var Ï = abs(abs(φ) - halfÏ€) < ε ? 0 : F / Math.pow(t(φ), n); - return [ Ï * Math.sin(n * λ), F - Ï * Math.cos(n * λ) ]; - } - forward.invert = function(x, y) { - var Ï0_y = F - y, Ï = d3_sgn(n) * Math.sqrt(x * x + Ï0_y * Ï0_y); - return [ Math.atan2(x, Ï0_y) / n, 2 * Math.atan(Math.pow(F / Ï, 1 / n)) - halfÏ€ ]; - }; - return forward; - } - (d3.geo.conicConformal = function() { - return d3_geo_conic(d3_geo_conicConformal); - }).raw = d3_geo_conicConformal; - function d3_geo_conicEquidistant(φ0, φ1) { - var cosφ0 = Math.cos(φ0), n = φ0 === φ1 ? Math.sin(φ0) : (cosφ0 - Math.cos(φ1)) / (φ1 - φ0), G = cosφ0 / n + φ0; - if (abs(n) < ε) return d3_geo_equirectangular; - function forward(λ, φ) { - var Ï = G - φ; - return [ Ï * Math.sin(n * λ), G - Ï * Math.cos(n * λ) ]; - } - forward.invert = function(x, y) { - var Ï0_y = G - y; - return [ Math.atan2(x, Ï0_y) / n, G - d3_sgn(n) * Math.sqrt(x * x + Ï0_y * Ï0_y) ]; - }; - return forward; - } - (d3.geo.conicEquidistant = function() { - return d3_geo_conic(d3_geo_conicEquidistant); - }).raw = d3_geo_conicEquidistant; - var d3_geo_gnomonic = d3_geo_azimuthal(function(cosλcosφ) { - return 1 / cosλcosφ; - }, Math.atan); - (d3.geo.gnomonic = function() { - return d3_geo_projection(d3_geo_gnomonic); - }).raw = d3_geo_gnomonic; - function d3_geo_mercator(λ, φ) { - return [ λ, Math.log(Math.tan(Ï€ / 4 + φ / 2)) ]; - } - d3_geo_mercator.invert = function(x, y) { - return [ x, 2 * Math.atan(Math.exp(y)) - halfÏ€ ]; - }; - function d3_geo_mercatorProjection(project) { - var m = d3_geo_projection(project), scale = m.scale, translate = m.translate, clipExtent = m.clipExtent, clipAuto; - m.scale = function() { - var v = scale.apply(m, arguments); - return v === m ? clipAuto ? m.clipExtent(null) : m : v; - }; - m.translate = function() { - var v = translate.apply(m, arguments); - return v === m ? clipAuto ? m.clipExtent(null) : m : v; - }; - m.clipExtent = function(_) { - var v = clipExtent.apply(m, arguments); - if (v === m) { - if (clipAuto = _ == null) { - var k = Ï€ * scale(), t = translate(); - clipExtent([ [ t[0] - k, t[1] - k ], [ t[0] + k, t[1] + k ] ]); - } - } else if (clipAuto) { - v = null; - } - return v; - }; - return m.clipExtent(null); - } - (d3.geo.mercator = function() { - return d3_geo_mercatorProjection(d3_geo_mercator); - }).raw = d3_geo_mercator; - var d3_geo_orthographic = d3_geo_azimuthal(function() { - return 1; - }, Math.asin); - (d3.geo.orthographic = function() { - return d3_geo_projection(d3_geo_orthographic); - }).raw = d3_geo_orthographic; - var d3_geo_stereographic = d3_geo_azimuthal(function(cosλcosφ) { - return 1 / (1 + cosλcosφ); - }, function(Ï) { - return 2 * Math.atan(Ï); - }); - (d3.geo.stereographic = function() { - return d3_geo_projection(d3_geo_stereographic); - }).raw = d3_geo_stereographic; - function d3_geo_transverseMercator(λ, φ) { - return [ Math.log(Math.tan(Ï€ / 4 + φ / 2)), -λ ]; - } - d3_geo_transverseMercator.invert = function(x, y) { - return [ -y, 2 * Math.atan(Math.exp(x)) - halfÏ€ ]; - }; - (d3.geo.transverseMercator = function() { - var projection = d3_geo_mercatorProjection(d3_geo_transverseMercator), center = projection.center, rotate = projection.rotate; - projection.center = function(_) { - return _ ? center([ -_[1], _[0] ]) : (_ = center(), [ -_[1], _[0] ]); - }; - projection.rotate = function(_) { - return _ ? rotate([ _[0], _[1], _.length > 2 ? _[2] + 90 : 90 ]) : (_ = rotate(), - [ _[0], _[1], _[2] - 90 ]); - }; - return projection.rotate([ 0, 0 ]); - }).raw = d3_geo_transverseMercator; - d3.geom = {}; - function d3_geom_pointX(d) { - return d[0]; - } - function d3_geom_pointY(d) { - return d[1]; - } - d3.geom.hull = function(vertices) { - var x = d3_geom_pointX, y = d3_geom_pointY; - if (arguments.length) return hull(vertices); - function hull(data) { - if (data.length < 3) return []; - var fx = d3_functor(x), fy = d3_functor(y), i, n = data.length, points = [], flippedPoints = []; - for (i = 0; i < n; i++) { - points.push([ +fx.call(this, data[i], i), +fy.call(this, data[i], i), i ]); - } - points.sort(d3_geom_hullOrder); - for (i = 0; i < n; i++) flippedPoints.push([ points[i][0], -points[i][1] ]); - var upper = d3_geom_hullUpper(points), lower = d3_geom_hullUpper(flippedPoints); - var skipLeft = lower[0] === upper[0], skipRight = lower[lower.length - 1] === upper[upper.length - 1], polygon = []; - for (i = upper.length - 1; i >= 0; --i) polygon.push(data[points[upper[i]][2]]); - for (i = +skipLeft; i < lower.length - skipRight; ++i) polygon.push(data[points[lower[i]][2]]); - return polygon; - } - hull.x = function(_) { - return arguments.length ? (x = _, hull) : x; - }; - hull.y = function(_) { - return arguments.length ? (y = _, hull) : y; - }; - return hull; - }; - function d3_geom_hullUpper(points) { - var n = points.length, hull = [ 0, 1 ], hs = 2; - for (var i = 2; i < n; i++) { - while (hs > 1 && d3_cross2d(points[hull[hs - 2]], points[hull[hs - 1]], points[i]) <= 0) --hs; - hull[hs++] = i; - } - return hull.slice(0, hs); - } - function d3_geom_hullOrder(a, b) { - return a[0] - b[0] || a[1] - b[1]; - } - d3.geom.polygon = function(coordinates) { - d3_subclass(coordinates, d3_geom_polygonPrototype); - return coordinates; - }; - var d3_geom_polygonPrototype = d3.geom.polygon.prototype = []; - d3_geom_polygonPrototype.area = function() { - var i = -1, n = this.length, a, b = this[n - 1], area = 0; - while (++i < n) { - a = b; - b = this[i]; - area += a[1] * b[0] - a[0] * b[1]; - } - return area * .5; - }; - d3_geom_polygonPrototype.centroid = function(k) { - var i = -1, n = this.length, x = 0, y = 0, a, b = this[n - 1], c; - if (!arguments.length) k = -1 / (6 * this.area()); - while (++i < n) { - a = b; - b = this[i]; - c = a[0] * b[1] - b[0] * a[1]; - x += (a[0] + b[0]) * c; - y += (a[1] + b[1]) * c; - } - return [ x * k, y * k ]; - }; - d3_geom_polygonPrototype.clip = function(subject) { - var input, closed = d3_geom_polygonClosed(subject), i = -1, n = this.length - d3_geom_polygonClosed(this), j, m, a = this[n - 1], b, c, d; - while (++i < n) { - input = subject.slice(); - subject.length = 0; - b = this[i]; - c = input[(m = input.length - closed) - 1]; - j = -1; - while (++j < m) { - d = input[j]; - if (d3_geom_polygonInside(d, a, b)) { - if (!d3_geom_polygonInside(c, a, b)) { - subject.push(d3_geom_polygonIntersect(c, d, a, b)); - } - subject.push(d); - } else if (d3_geom_polygonInside(c, a, b)) { - subject.push(d3_geom_polygonIntersect(c, d, a, b)); - } - c = d; - } - if (closed) subject.push(subject[0]); - a = b; - } - return subject; - }; - function d3_geom_polygonInside(p, a, b) { - return (b[0] - a[0]) * (p[1] - a[1]) < (b[1] - a[1]) * (p[0] - a[0]); - } - function d3_geom_polygonIntersect(c, d, a, b) { - var x1 = c[0], x3 = a[0], x21 = d[0] - x1, x43 = b[0] - x3, y1 = c[1], y3 = a[1], y21 = d[1] - y1, y43 = b[1] - y3, ua = (x43 * (y1 - y3) - y43 * (x1 - x3)) / (y43 * x21 - x43 * y21); - return [ x1 + ua * x21, y1 + ua * y21 ]; - } - function d3_geom_polygonClosed(coordinates) { - var a = coordinates[0], b = coordinates[coordinates.length - 1]; - return !(a[0] - b[0] || a[1] - b[1]); - } - var d3_geom_voronoiEdges, d3_geom_voronoiCells, d3_geom_voronoiBeaches, d3_geom_voronoiBeachPool = [], d3_geom_voronoiFirstCircle, d3_geom_voronoiCircles, d3_geom_voronoiCirclePool = []; - function d3_geom_voronoiBeach() { - d3_geom_voronoiRedBlackNode(this); - this.edge = this.site = this.circle = null; - } - function d3_geom_voronoiCreateBeach(site) { - var beach = d3_geom_voronoiBeachPool.pop() || new d3_geom_voronoiBeach(); - beach.site = site; - return beach; - } - function d3_geom_voronoiDetachBeach(beach) { - d3_geom_voronoiDetachCircle(beach); - d3_geom_voronoiBeaches.remove(beach); - d3_geom_voronoiBeachPool.push(beach); - d3_geom_voronoiRedBlackNode(beach); - } - function d3_geom_voronoiRemoveBeach(beach) { - var circle = beach.circle, x = circle.x, y = circle.cy, vertex = { - x: x, - y: y - }, previous = beach.P, next = beach.N, disappearing = [ beach ]; - d3_geom_voronoiDetachBeach(beach); - var lArc = previous; - while (lArc.circle && abs(x - lArc.circle.x) < ε && abs(y - lArc.circle.cy) < ε) { - previous = lArc.P; - disappearing.unshift(lArc); - d3_geom_voronoiDetachBeach(lArc); - lArc = previous; - } - disappearing.unshift(lArc); - d3_geom_voronoiDetachCircle(lArc); - var rArc = next; - while (rArc.circle && abs(x - rArc.circle.x) < ε && abs(y - rArc.circle.cy) < ε) { - next = rArc.N; - disappearing.push(rArc); - d3_geom_voronoiDetachBeach(rArc); - rArc = next; - } - disappearing.push(rArc); - d3_geom_voronoiDetachCircle(rArc); - var nArcs = disappearing.length, iArc; - for (iArc = 1; iArc < nArcs; ++iArc) { - rArc = disappearing[iArc]; - lArc = disappearing[iArc - 1]; - d3_geom_voronoiSetEdgeEnd(rArc.edge, lArc.site, rArc.site, vertex); - } - lArc = disappearing[0]; - rArc = disappearing[nArcs - 1]; - rArc.edge = d3_geom_voronoiCreateEdge(lArc.site, rArc.site, null, vertex); - d3_geom_voronoiAttachCircle(lArc); - d3_geom_voronoiAttachCircle(rArc); - } - function d3_geom_voronoiAddBeach(site) { - var x = site.x, directrix = site.y, lArc, rArc, dxl, dxr, node = d3_geom_voronoiBeaches._; - while (node) { - dxl = d3_geom_voronoiLeftBreakPoint(node, directrix) - x; - if (dxl > ε) node = node.L; else { - dxr = x - d3_geom_voronoiRightBreakPoint(node, directrix); - if (dxr > ε) { - if (!node.R) { - lArc = node; - break; - } - node = node.R; - } else { - if (dxl > -ε) { - lArc = node.P; - rArc = node; - } else if (dxr > -ε) { - lArc = node; - rArc = node.N; - } else { - lArc = rArc = node; - } - break; - } - } - } - var newArc = d3_geom_voronoiCreateBeach(site); - d3_geom_voronoiBeaches.insert(lArc, newArc); - if (!lArc && !rArc) return; - if (lArc === rArc) { - d3_geom_voronoiDetachCircle(lArc); - rArc = d3_geom_voronoiCreateBeach(lArc.site); - d3_geom_voronoiBeaches.insert(newArc, rArc); - newArc.edge = rArc.edge = d3_geom_voronoiCreateEdge(lArc.site, newArc.site); - d3_geom_voronoiAttachCircle(lArc); - d3_geom_voronoiAttachCircle(rArc); - return; - } - if (!rArc) { - newArc.edge = d3_geom_voronoiCreateEdge(lArc.site, newArc.site); - return; - } - d3_geom_voronoiDetachCircle(lArc); - d3_geom_voronoiDetachCircle(rArc); - var lSite = lArc.site, ax = lSite.x, ay = lSite.y, bx = site.x - ax, by = site.y - ay, rSite = rArc.site, cx = rSite.x - ax, cy = rSite.y - ay, d = 2 * (bx * cy - by * cx), hb = bx * bx + by * by, hc = cx * cx + cy * cy, vertex = { - x: (cy * hb - by * hc) / d + ax, - y: (bx * hc - cx * hb) / d + ay - }; - d3_geom_voronoiSetEdgeEnd(rArc.edge, lSite, rSite, vertex); - newArc.edge = d3_geom_voronoiCreateEdge(lSite, site, null, vertex); - rArc.edge = d3_geom_voronoiCreateEdge(site, rSite, null, vertex); - d3_geom_voronoiAttachCircle(lArc); - d3_geom_voronoiAttachCircle(rArc); - } - function d3_geom_voronoiLeftBreakPoint(arc, directrix) { - var site = arc.site, rfocx = site.x, rfocy = site.y, pby2 = rfocy - directrix; - if (!pby2) return rfocx; - var lArc = arc.P; - if (!lArc) return -Infinity; - site = lArc.site; - var lfocx = site.x, lfocy = site.y, plby2 = lfocy - directrix; - if (!plby2) return lfocx; - var hl = lfocx - rfocx, aby2 = 1 / pby2 - 1 / plby2, b = hl / plby2; - if (aby2) return (-b + Math.sqrt(b * b - 2 * aby2 * (hl * hl / (-2 * plby2) - lfocy + plby2 / 2 + rfocy - pby2 / 2))) / aby2 + rfocx; - return (rfocx + lfocx) / 2; - } - function d3_geom_voronoiRightBreakPoint(arc, directrix) { - var rArc = arc.N; - if (rArc) return d3_geom_voronoiLeftBreakPoint(rArc, directrix); - var site = arc.site; - return site.y === directrix ? site.x : Infinity; - } - function d3_geom_voronoiCell(site) { - this.site = site; - this.edges = []; - } - d3_geom_voronoiCell.prototype.prepare = function() { - var halfEdges = this.edges, iHalfEdge = halfEdges.length, edge; - while (iHalfEdge--) { - edge = halfEdges[iHalfEdge].edge; - if (!edge.b || !edge.a) halfEdges.splice(iHalfEdge, 1); - } - halfEdges.sort(d3_geom_voronoiHalfEdgeOrder); - return halfEdges.length; - }; - function d3_geom_voronoiCloseCells(extent) { - var x0 = extent[0][0], x1 = extent[1][0], y0 = extent[0][1], y1 = extent[1][1], x2, y2, x3, y3, cells = d3_geom_voronoiCells, iCell = cells.length, cell, iHalfEdge, halfEdges, nHalfEdges, start, end; - while (iCell--) { - cell = cells[iCell]; - if (!cell || !cell.prepare()) continue; - halfEdges = cell.edges; - nHalfEdges = halfEdges.length; - iHalfEdge = 0; - while (iHalfEdge < nHalfEdges) { - end = halfEdges[iHalfEdge].end(), x3 = end.x, y3 = end.y; - start = halfEdges[++iHalfEdge % nHalfEdges].start(), x2 = start.x, y2 = start.y; - if (abs(x3 - x2) > ε || abs(y3 - y2) > ε) { - halfEdges.splice(iHalfEdge, 0, new d3_geom_voronoiHalfEdge(d3_geom_voronoiCreateBorderEdge(cell.site, end, abs(x3 - x0) < ε && y1 - y3 > ε ? { - x: x0, - y: abs(x2 - x0) < ε ? y2 : y1 - } : abs(y3 - y1) < ε && x1 - x3 > ε ? { - x: abs(y2 - y1) < ε ? x2 : x1, - y: y1 - } : abs(x3 - x1) < ε && y3 - y0 > ε ? { - x: x1, - y: abs(x2 - x1) < ε ? y2 : y0 - } : abs(y3 - y0) < ε && x3 - x0 > ε ? { - x: abs(y2 - y0) < ε ? x2 : x0, - y: y0 - } : null), cell.site, null)); - ++nHalfEdges; - } - } - } - } - function d3_geom_voronoiHalfEdgeOrder(a, b) { - return b.angle - a.angle; - } - function d3_geom_voronoiCircle() { - d3_geom_voronoiRedBlackNode(this); - this.x = this.y = this.arc = this.site = this.cy = null; - } - function d3_geom_voronoiAttachCircle(arc) { - var lArc = arc.P, rArc = arc.N; - if (!lArc || !rArc) return; - var lSite = lArc.site, cSite = arc.site, rSite = rArc.site; - if (lSite === rSite) return; - var bx = cSite.x, by = cSite.y, ax = lSite.x - bx, ay = lSite.y - by, cx = rSite.x - bx, cy = rSite.y - by; - var d = 2 * (ax * cy - ay * cx); - if (d >= -ε2) return; - var ha = ax * ax + ay * ay, hc = cx * cx + cy * cy, x = (cy * ha - ay * hc) / d, y = (ax * hc - cx * ha) / d, cy = y + by; - var circle = d3_geom_voronoiCirclePool.pop() || new d3_geom_voronoiCircle(); - circle.arc = arc; - circle.site = cSite; - circle.x = x + bx; - circle.y = cy + Math.sqrt(x * x + y * y); - circle.cy = cy; - arc.circle = circle; - var before = null, node = d3_geom_voronoiCircles._; - while (node) { - if (circle.y < node.y || circle.y === node.y && circle.x <= node.x) { - if (node.L) node = node.L; else { - before = node.P; - break; - } - } else { - if (node.R) node = node.R; else { - before = node; - break; - } - } - } - d3_geom_voronoiCircles.insert(before, circle); - if (!before) d3_geom_voronoiFirstCircle = circle; - } - function d3_geom_voronoiDetachCircle(arc) { - var circle = arc.circle; - if (circle) { - if (!circle.P) d3_geom_voronoiFirstCircle = circle.N; - d3_geom_voronoiCircles.remove(circle); - d3_geom_voronoiCirclePool.push(circle); - d3_geom_voronoiRedBlackNode(circle); - arc.circle = null; - } - } - function d3_geom_voronoiClipEdges(extent) { - var edges = d3_geom_voronoiEdges, clip = d3_geom_clipLine(extent[0][0], extent[0][1], extent[1][0], extent[1][1]), i = edges.length, e; - while (i--) { - e = edges[i]; - if (!d3_geom_voronoiConnectEdge(e, extent) || !clip(e) || abs(e.a.x - e.b.x) < ε && abs(e.a.y - e.b.y) < ε) { - e.a = e.b = null; - edges.splice(i, 1); - } - } - } - function d3_geom_voronoiConnectEdge(edge, extent) { - var vb = edge.b; - if (vb) return true; - var va = edge.a, x0 = extent[0][0], x1 = extent[1][0], y0 = extent[0][1], y1 = extent[1][1], lSite = edge.l, rSite = edge.r, lx = lSite.x, ly = lSite.y, rx = rSite.x, ry = rSite.y, fx = (lx + rx) / 2, fy = (ly + ry) / 2, fm, fb; - if (ry === ly) { - if (fx < x0 || fx >= x1) return; - if (lx > rx) { - if (!va) va = { - x: fx, - y: y0 - }; else if (va.y >= y1) return; - vb = { - x: fx, - y: y1 - }; - } else { - if (!va) va = { - x: fx, - y: y1 - }; else if (va.y < y0) return; - vb = { - x: fx, - y: y0 - }; - } - } else { - fm = (lx - rx) / (ry - ly); - fb = fy - fm * fx; - if (fm < -1 || fm > 1) { - if (lx > rx) { - if (!va) va = { - x: (y0 - fb) / fm, - y: y0 - }; else if (va.y >= y1) return; - vb = { - x: (y1 - fb) / fm, - y: y1 - }; - } else { - if (!va) va = { - x: (y1 - fb) / fm, - y: y1 - }; else if (va.y < y0) return; - vb = { - x: (y0 - fb) / fm, - y: y0 - }; - } - } else { - if (ly < ry) { - if (!va) va = { - x: x0, - y: fm * x0 + fb - }; else if (va.x >= x1) return; - vb = { - x: x1, - y: fm * x1 + fb - }; - } else { - if (!va) va = { - x: x1, - y: fm * x1 + fb - }; else if (va.x < x0) return; - vb = { - x: x0, - y: fm * x0 + fb - }; - } - } - } - edge.a = va; - edge.b = vb; - return true; - } - function d3_geom_voronoiEdge(lSite, rSite) { - this.l = lSite; - this.r = rSite; - this.a = this.b = null; - } - function d3_geom_voronoiCreateEdge(lSite, rSite, va, vb) { - var edge = new d3_geom_voronoiEdge(lSite, rSite); - d3_geom_voronoiEdges.push(edge); - if (va) d3_geom_voronoiSetEdgeEnd(edge, lSite, rSite, va); - if (vb) d3_geom_voronoiSetEdgeEnd(edge, rSite, lSite, vb); - d3_geom_voronoiCells[lSite.i].edges.push(new d3_geom_voronoiHalfEdge(edge, lSite, rSite)); - d3_geom_voronoiCells[rSite.i].edges.push(new d3_geom_voronoiHalfEdge(edge, rSite, lSite)); - return edge; - } - function d3_geom_voronoiCreateBorderEdge(lSite, va, vb) { - var edge = new d3_geom_voronoiEdge(lSite, null); - edge.a = va; - edge.b = vb; - d3_geom_voronoiEdges.push(edge); - return edge; - } - function d3_geom_voronoiSetEdgeEnd(edge, lSite, rSite, vertex) { - if (!edge.a && !edge.b) { - edge.a = vertex; - edge.l = lSite; - edge.r = rSite; - } else if (edge.l === rSite) { - edge.b = vertex; - } else { - edge.a = vertex; - } - } - function d3_geom_voronoiHalfEdge(edge, lSite, rSite) { - var va = edge.a, vb = edge.b; - this.edge = edge; - this.site = lSite; - this.angle = rSite ? Math.atan2(rSite.y - lSite.y, rSite.x - lSite.x) : edge.l === lSite ? Math.atan2(vb.x - va.x, va.y - vb.y) : Math.atan2(va.x - vb.x, vb.y - va.y); - } - d3_geom_voronoiHalfEdge.prototype = { - start: function() { - return this.edge.l === this.site ? this.edge.a : this.edge.b; - }, - end: function() { - return this.edge.l === this.site ? this.edge.b : this.edge.a; - } - }; - function d3_geom_voronoiRedBlackTree() { - this._ = null; - } - function d3_geom_voronoiRedBlackNode(node) { - node.U = node.C = node.L = node.R = node.P = node.N = null; - } - d3_geom_voronoiRedBlackTree.prototype = { - insert: function(after, node) { - var parent, grandpa, uncle; - if (after) { - node.P = after; - node.N = after.N; - if (after.N) after.N.P = node; - after.N = node; - if (after.R) { - after = after.R; - while (after.L) after = after.L; - after.L = node; - } else { - after.R = node; - } - parent = after; - } else if (this._) { - after = d3_geom_voronoiRedBlackFirst(this._); - node.P = null; - node.N = after; - after.P = after.L = node; - parent = after; - } else { - node.P = node.N = null; - this._ = node; - parent = null; - } - node.L = node.R = null; - node.U = parent; - node.C = true; - after = node; - while (parent && parent.C) { - grandpa = parent.U; - if (parent === grandpa.L) { - uncle = grandpa.R; - if (uncle && uncle.C) { - parent.C = uncle.C = false; - grandpa.C = true; - after = grandpa; - } else { - if (after === parent.R) { - d3_geom_voronoiRedBlackRotateLeft(this, parent); - after = parent; - parent = after.U; - } - parent.C = false; - grandpa.C = true; - d3_geom_voronoiRedBlackRotateRight(this, grandpa); - } - } else { - uncle = grandpa.L; - if (uncle && uncle.C) { - parent.C = uncle.C = false; - grandpa.C = true; - after = grandpa; - } else { - if (after === parent.L) { - d3_geom_voronoiRedBlackRotateRight(this, parent); - after = parent; - parent = after.U; - } - parent.C = false; - grandpa.C = true; - d3_geom_voronoiRedBlackRotateLeft(this, grandpa); - } - } - parent = after.U; - } - this._.C = false; - }, - remove: function(node) { - if (node.N) node.N.P = node.P; - if (node.P) node.P.N = node.N; - node.N = node.P = null; - var parent = node.U, sibling, left = node.L, right = node.R, next, red; - if (!left) next = right; else if (!right) next = left; else next = d3_geom_voronoiRedBlackFirst(right); - if (parent) { - if (parent.L === node) parent.L = next; else parent.R = next; - } else { - this._ = next; - } - if (left && right) { - red = next.C; - next.C = node.C; - next.L = left; - left.U = next; - if (next !== right) { - parent = next.U; - next.U = node.U; - node = next.R; - parent.L = node; - next.R = right; - right.U = next; - } else { - next.U = parent; - parent = next; - node = next.R; - } - } else { - red = node.C; - node = next; - } - if (node) node.U = parent; - if (red) return; - if (node && node.C) { - node.C = false; - return; - } - do { - if (node === this._) break; - if (node === parent.L) { - sibling = parent.R; - if (sibling.C) { - sibling.C = false; - parent.C = true; - d3_geom_voronoiRedBlackRotateLeft(this, parent); - sibling = parent.R; - } - if (sibling.L && sibling.L.C || sibling.R && sibling.R.C) { - if (!sibling.R || !sibling.R.C) { - sibling.L.C = false; - sibling.C = true; - d3_geom_voronoiRedBlackRotateRight(this, sibling); - sibling = parent.R; - } - sibling.C = parent.C; - parent.C = sibling.R.C = false; - d3_geom_voronoiRedBlackRotateLeft(this, parent); - node = this._; - break; - } - } else { - sibling = parent.L; - if (sibling.C) { - sibling.C = false; - parent.C = true; - d3_geom_voronoiRedBlackRotateRight(this, parent); - sibling = parent.L; - } - if (sibling.L && sibling.L.C || sibling.R && sibling.R.C) { - if (!sibling.L || !sibling.L.C) { - sibling.R.C = false; - sibling.C = true; - d3_geom_voronoiRedBlackRotateLeft(this, sibling); - sibling = parent.L; - } - sibling.C = parent.C; - parent.C = sibling.L.C = false; - d3_geom_voronoiRedBlackRotateRight(this, parent); - node = this._; - break; - } - } - sibling.C = true; - node = parent; - parent = parent.U; - } while (!node.C); - if (node) node.C = false; - } - }; - function d3_geom_voronoiRedBlackRotateLeft(tree, node) { - var p = node, q = node.R, parent = p.U; - if (parent) { - if (parent.L === p) parent.L = q; else parent.R = q; - } else { - tree._ = q; - } - q.U = parent; - p.U = q; - p.R = q.L; - if (p.R) p.R.U = p; - q.L = p; - } - function d3_geom_voronoiRedBlackRotateRight(tree, node) { - var p = node, q = node.L, parent = p.U; - if (parent) { - if (parent.L === p) parent.L = q; else parent.R = q; - } else { - tree._ = q; - } - q.U = parent; - p.U = q; - p.L = q.R; - if (p.L) p.L.U = p; - q.R = p; - } - function d3_geom_voronoiRedBlackFirst(node) { - while (node.L) node = node.L; - return node; - } - function d3_geom_voronoi(sites, bbox) { - var site = sites.sort(d3_geom_voronoiVertexOrder).pop(), x0, y0, circle; - d3_geom_voronoiEdges = []; - d3_geom_voronoiCells = new Array(sites.length); - d3_geom_voronoiBeaches = new d3_geom_voronoiRedBlackTree(); - d3_geom_voronoiCircles = new d3_geom_voronoiRedBlackTree(); - while (true) { - circle = d3_geom_voronoiFirstCircle; - if (site && (!circle || site.y < circle.y || site.y === circle.y && site.x < circle.x)) { - if (site.x !== x0 || site.y !== y0) { - d3_geom_voronoiCells[site.i] = new d3_geom_voronoiCell(site); - d3_geom_voronoiAddBeach(site); - x0 = site.x, y0 = site.y; - } - site = sites.pop(); - } else if (circle) { - d3_geom_voronoiRemoveBeach(circle.arc); - } else { - break; - } - } - if (bbox) d3_geom_voronoiClipEdges(bbox), d3_geom_voronoiCloseCells(bbox); - var diagram = { - cells: d3_geom_voronoiCells, - edges: d3_geom_voronoiEdges - }; - d3_geom_voronoiBeaches = d3_geom_voronoiCircles = d3_geom_voronoiEdges = d3_geom_voronoiCells = null; - return diagram; - } - function d3_geom_voronoiVertexOrder(a, b) { - return b.y - a.y || b.x - a.x; - } - d3.geom.voronoi = function(points) { - var x = d3_geom_pointX, y = d3_geom_pointY, fx = x, fy = y, clipExtent = d3_geom_voronoiClipExtent; - if (points) return voronoi(points); - function voronoi(data) { - var polygons = new Array(data.length), x0 = clipExtent[0][0], y0 = clipExtent[0][1], x1 = clipExtent[1][0], y1 = clipExtent[1][1]; - d3_geom_voronoi(sites(data), clipExtent).cells.forEach(function(cell, i) { - var edges = cell.edges, site = cell.site, polygon = polygons[i] = edges.length ? edges.map(function(e) { - var s = e.start(); - return [ s.x, s.y ]; - }) : site.x >= x0 && site.x <= x1 && site.y >= y0 && site.y <= y1 ? [ [ x0, y1 ], [ x1, y1 ], [ x1, y0 ], [ x0, y0 ] ] : []; - polygon.point = data[i]; - }); - return polygons; - } - function sites(data) { - return data.map(function(d, i) { - return { - x: Math.round(fx(d, i) / ε) * ε, - y: Math.round(fy(d, i) / ε) * ε, - i: i - }; - }); - } - voronoi.links = function(data) { - return d3_geom_voronoi(sites(data)).edges.filter(function(edge) { - return edge.l && edge.r; - }).map(function(edge) { - return { - source: data[edge.l.i], - target: data[edge.r.i] - }; - }); - }; - voronoi.triangles = function(data) { - var triangles = []; - d3_geom_voronoi(sites(data)).cells.forEach(function(cell, i) { - var site = cell.site, edges = cell.edges.sort(d3_geom_voronoiHalfEdgeOrder), j = -1, m = edges.length, e0, s0, e1 = edges[m - 1].edge, s1 = e1.l === site ? e1.r : e1.l; - while (++j < m) { - e0 = e1; - s0 = s1; - e1 = edges[j].edge; - s1 = e1.l === site ? e1.r : e1.l; - if (i < s0.i && i < s1.i && d3_geom_voronoiTriangleArea(site, s0, s1) < 0) { - triangles.push([ data[i], data[s0.i], data[s1.i] ]); - } - } - }); - return triangles; - }; - voronoi.x = function(_) { - return arguments.length ? (fx = d3_functor(x = _), voronoi) : x; - }; - voronoi.y = function(_) { - return arguments.length ? (fy = d3_functor(y = _), voronoi) : y; - }; - voronoi.clipExtent = function(_) { - if (!arguments.length) return clipExtent === d3_geom_voronoiClipExtent ? null : clipExtent; - clipExtent = _ == null ? d3_geom_voronoiClipExtent : _; - return voronoi; - }; - voronoi.size = function(_) { - if (!arguments.length) return clipExtent === d3_geom_voronoiClipExtent ? null : clipExtent && clipExtent[1]; - return voronoi.clipExtent(_ && [ [ 0, 0 ], _ ]); - }; - return voronoi; - }; - var d3_geom_voronoiClipExtent = [ [ -1e6, -1e6 ], [ 1e6, 1e6 ] ]; - function d3_geom_voronoiTriangleArea(a, b, c) { - return (a.x - c.x) * (b.y - a.y) - (a.x - b.x) * (c.y - a.y); - } - d3.geom.delaunay = function(vertices) { - return d3.geom.voronoi().triangles(vertices); - }; - d3.geom.quadtree = function(points, x1, y1, x2, y2) { - var x = d3_geom_pointX, y = d3_geom_pointY, compat; - if (compat = arguments.length) { - x = d3_geom_quadtreeCompatX; - y = d3_geom_quadtreeCompatY; - if (compat === 3) { - y2 = y1; - x2 = x1; - y1 = x1 = 0; - } - return quadtree(points); - } - function quadtree(data) { - var d, fx = d3_functor(x), fy = d3_functor(y), xs, ys, i, n, x1_, y1_, x2_, y2_; - if (x1 != null) { - x1_ = x1, y1_ = y1, x2_ = x2, y2_ = y2; - } else { - x2_ = y2_ = -(x1_ = y1_ = Infinity); - xs = [], ys = []; - n = data.length; - if (compat) for (i = 0; i < n; ++i) { - d = data[i]; - if (d.x < x1_) x1_ = d.x; - if (d.y < y1_) y1_ = d.y; - if (d.x > x2_) x2_ = d.x; - if (d.y > y2_) y2_ = d.y; - xs.push(d.x); - ys.push(d.y); - } else for (i = 0; i < n; ++i) { - var x_ = +fx(d = data[i], i), y_ = +fy(d, i); - if (x_ < x1_) x1_ = x_; - if (y_ < y1_) y1_ = y_; - if (x_ > x2_) x2_ = x_; - if (y_ > y2_) y2_ = y_; - xs.push(x_); - ys.push(y_); - } - } - var dx = x2_ - x1_, dy = y2_ - y1_; - if (dx > dy) y2_ = y1_ + dx; else x2_ = x1_ + dy; - function insert(n, d, x, y, x1, y1, x2, y2) { - if (isNaN(x) || isNaN(y)) return; - if (n.leaf) { - var nx = n.x, ny = n.y; - if (nx != null) { - if (abs(nx - x) + abs(ny - y) < .01) { - insertChild(n, d, x, y, x1, y1, x2, y2); - } else { - var nPoint = n.point; - n.x = n.y = n.point = null; - insertChild(n, nPoint, nx, ny, x1, y1, x2, y2); - insertChild(n, d, x, y, x1, y1, x2, y2); - } - } else { - n.x = x, n.y = y, n.point = d; - } - } else { - insertChild(n, d, x, y, x1, y1, x2, y2); - } - } - function insertChild(n, d, x, y, x1, y1, x2, y2) { - var sx = (x1 + x2) * .5, sy = (y1 + y2) * .5, right = x >= sx, bottom = y >= sy, i = (bottom << 1) + right; - n.leaf = false; - n = n.nodes[i] || (n.nodes[i] = d3_geom_quadtreeNode()); - if (right) x1 = sx; else x2 = sx; - if (bottom) y1 = sy; else y2 = sy; - insert(n, d, x, y, x1, y1, x2, y2); - } - var root = d3_geom_quadtreeNode(); - root.add = function(d) { - insert(root, d, +fx(d, ++i), +fy(d, i), x1_, y1_, x2_, y2_); - }; - root.visit = function(f) { - d3_geom_quadtreeVisit(f, root, x1_, y1_, x2_, y2_); - }; - i = -1; - if (x1 == null) { - while (++i < n) { - insert(root, data[i], xs[i], ys[i], x1_, y1_, x2_, y2_); - } - --i; - } else data.forEach(root.add); - xs = ys = data = d = null; - return root; - } - quadtree.x = function(_) { - return arguments.length ? (x = _, quadtree) : x; - }; - quadtree.y = function(_) { - return arguments.length ? (y = _, quadtree) : y; - }; - quadtree.extent = function(_) { - if (!arguments.length) return x1 == null ? null : [ [ x1, y1 ], [ x2, y2 ] ]; - if (_ == null) x1 = y1 = x2 = y2 = null; else x1 = +_[0][0], y1 = +_[0][1], x2 = +_[1][0], - y2 = +_[1][1]; - return quadtree; - }; - quadtree.size = function(_) { - if (!arguments.length) return x1 == null ? null : [ x2 - x1, y2 - y1 ]; - if (_ == null) x1 = y1 = x2 = y2 = null; else x1 = y1 = 0, x2 = +_[0], y2 = +_[1]; - return quadtree; - }; - return quadtree; - }; - function d3_geom_quadtreeCompatX(d) { - return d.x; - } - function d3_geom_quadtreeCompatY(d) { - return d.y; - } - function d3_geom_quadtreeNode() { - return { - leaf: true, - nodes: [], - point: null, - x: null, - y: null - }; - } - function d3_geom_quadtreeVisit(f, node, x1, y1, x2, y2) { - if (!f(node, x1, y1, x2, y2)) { - var sx = (x1 + x2) * .5, sy = (y1 + y2) * .5, children = node.nodes; - if (children[0]) d3_geom_quadtreeVisit(f, children[0], x1, y1, sx, sy); - if (children[1]) d3_geom_quadtreeVisit(f, children[1], sx, y1, x2, sy); - if (children[2]) d3_geom_quadtreeVisit(f, children[2], x1, sy, sx, y2); - if (children[3]) d3_geom_quadtreeVisit(f, children[3], sx, sy, x2, y2); - } - } - d3.interpolateRgb = d3_interpolateRgb; - function d3_interpolateRgb(a, b) { - a = d3.rgb(a); - b = d3.rgb(b); - var ar = a.r, ag = a.g, ab = a.b, br = b.r - ar, bg = b.g - ag, bb = b.b - ab; - return function(t) { - return "#" + d3_rgb_hex(Math.round(ar + br * t)) + d3_rgb_hex(Math.round(ag + bg * t)) + d3_rgb_hex(Math.round(ab + bb * t)); - }; - } - d3.interpolateObject = d3_interpolateObject; - function d3_interpolateObject(a, b) { - var i = {}, c = {}, k; - for (k in a) { - if (k in b) { - i[k] = d3_interpolate(a[k], b[k]); - } else { - c[k] = a[k]; - } - } - for (k in b) { - if (!(k in a)) { - c[k] = b[k]; - } - } - return function(t) { - for (k in i) c[k] = i[k](t); - return c; - }; - } - d3.interpolateNumber = d3_interpolateNumber; - function d3_interpolateNumber(a, b) { - b -= a = +a; - return function(t) { - return a + b * t; - }; - } - d3.interpolateString = d3_interpolateString; - function d3_interpolateString(a, b) { - var m, i, j, s0 = 0, s1 = 0, s = [], q = [], n, o; - a = a + "", b = b + ""; - d3_interpolate_number.lastIndex = 0; - for (i = 0; m = d3_interpolate_number.exec(b); ++i) { - if (m.index) s.push(b.substring(s0, s1 = m.index)); - q.push({ - i: s.length, - x: m[0] - }); - s.push(null); - s0 = d3_interpolate_number.lastIndex; - } - if (s0 < b.length) s.push(b.substring(s0)); - for (i = 0, n = q.length; (m = d3_interpolate_number.exec(a)) && i < n; ++i) { - o = q[i]; - if (o.x == m[0]) { - if (o.i) { - if (s[o.i + 1] == null) { - s[o.i - 1] += o.x; - s.splice(o.i, 1); - for (j = i + 1; j < n; ++j) q[j].i--; - } else { - s[o.i - 1] += o.x + s[o.i + 1]; - s.splice(o.i, 2); - for (j = i + 1; j < n; ++j) q[j].i -= 2; - } - } else { - if (s[o.i + 1] == null) { - s[o.i] = o.x; - } else { - s[o.i] = o.x + s[o.i + 1]; - s.splice(o.i + 1, 1); - for (j = i + 1; j < n; ++j) q[j].i--; - } - } - q.splice(i, 1); - n--; - i--; - } else { - o.x = d3_interpolateNumber(parseFloat(m[0]), parseFloat(o.x)); - } - } - while (i < n) { - o = q.pop(); - if (s[o.i + 1] == null) { - s[o.i] = o.x; - } else { - s[o.i] = o.x + s[o.i + 1]; - s.splice(o.i + 1, 1); - } - n--; - } - if (s.length === 1) { - return s[0] == null ? (o = q[0].x, function(t) { - return o(t) + ""; - }) : function() { - return b; - }; - } - return function(t) { - for (i = 0; i < n; ++i) s[(o = q[i]).i] = o.x(t); - return s.join(""); - }; - } - var d3_interpolate_number = /[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g; - d3.interpolate = d3_interpolate; - function d3_interpolate(a, b) { - var i = d3.interpolators.length, f; - while (--i >= 0 && !(f = d3.interpolators[i](a, b))) ; - return f; - } - d3.interpolators = [ function(a, b) { - var t = typeof b; - return (t === "string" ? d3_rgb_names.has(b) || /^(#|rgb\(|hsl\()/.test(b) ? d3_interpolateRgb : d3_interpolateString : b instanceof d3_Color ? d3_interpolateRgb : t === "object" ? Array.isArray(b) ? d3_interpolateArray : d3_interpolateObject : d3_interpolateNumber)(a, b); - } ]; - d3.interpolateArray = d3_interpolateArray; - function d3_interpolateArray(a, b) { - var x = [], c = [], na = a.length, nb = b.length, n0 = Math.min(a.length, b.length), i; - for (i = 0; i < n0; ++i) x.push(d3_interpolate(a[i], b[i])); - for (;i < na; ++i) c[i] = a[i]; - for (;i < nb; ++i) c[i] = b[i]; - return function(t) { - for (i = 0; i < n0; ++i) c[i] = x[i](t); - return c; - }; - } - var d3_ease_default = function() { - return d3_identity; - }; - var d3_ease = d3.map({ - linear: d3_ease_default, - poly: d3_ease_poly, - quad: function() { - return d3_ease_quad; - }, - cubic: function() { - return d3_ease_cubic; - }, - sin: function() { - return d3_ease_sin; - }, - exp: function() { - return d3_ease_exp; - }, - circle: function() { - return d3_ease_circle; - }, - elastic: d3_ease_elastic, - back: d3_ease_back, - bounce: function() { - return d3_ease_bounce; - } - }); - var d3_ease_mode = d3.map({ - "in": d3_identity, - out: d3_ease_reverse, - "in-out": d3_ease_reflect, - "out-in": function(f) { - return d3_ease_reflect(d3_ease_reverse(f)); - } - }); - d3.ease = function(name) { - var i = name.indexOf("-"), t = i >= 0 ? name.substring(0, i) : name, m = i >= 0 ? name.substring(i + 1) : "in"; - t = d3_ease.get(t) || d3_ease_default; - m = d3_ease_mode.get(m) || d3_identity; - return d3_ease_clamp(m(t.apply(null, d3_arraySlice.call(arguments, 1)))); - }; - function d3_ease_clamp(f) { - return function(t) { - return t <= 0 ? 0 : t >= 1 ? 1 : f(t); - }; - } - function d3_ease_reverse(f) { - return function(t) { - return 1 - f(1 - t); - }; - } - function d3_ease_reflect(f) { - return function(t) { - return .5 * (t < .5 ? f(2 * t) : 2 - f(2 - 2 * t)); - }; - } - function d3_ease_quad(t) { - return t * t; - } - function d3_ease_cubic(t) { - return t * t * t; - } - function d3_ease_cubicInOut(t) { - if (t <= 0) return 0; - if (t >= 1) return 1; - var t2 = t * t, t3 = t2 * t; - return 4 * (t < .5 ? t3 : 3 * (t - t2) + t3 - .75); - } - function d3_ease_poly(e) { - return function(t) { - return Math.pow(t, e); - }; - } - function d3_ease_sin(t) { - return 1 - Math.cos(t * halfÏ€); - } - function d3_ease_exp(t) { - return Math.pow(2, 10 * (t - 1)); - } - function d3_ease_circle(t) { - return 1 - Math.sqrt(1 - t * t); - } - function d3_ease_elastic(a, p) { - var s; - if (arguments.length < 2) p = .45; - if (arguments.length) s = p / Ï„ * Math.asin(1 / a); else a = 1, s = p / 4; - return function(t) { - return 1 + a * Math.pow(2, -10 * t) * Math.sin((t - s) * Ï„ / p); - }; - } - function d3_ease_back(s) { - if (!s) s = 1.70158; - return function(t) { - return t * t * ((s + 1) * t - s); - }; - } - function d3_ease_bounce(t) { - return t < 1 / 2.75 ? 7.5625 * t * t : t < 2 / 2.75 ? 7.5625 * (t -= 1.5 / 2.75) * t + .75 : t < 2.5 / 2.75 ? 7.5625 * (t -= 2.25 / 2.75) * t + .9375 : 7.5625 * (t -= 2.625 / 2.75) * t + .984375; - } - d3.interpolateHcl = d3_interpolateHcl; - function d3_interpolateHcl(a, b) { - a = d3.hcl(a); - b = d3.hcl(b); - var ah = a.h, ac = a.c, al = a.l, bh = b.h - ah, bc = b.c - ac, bl = b.l - al; - if (isNaN(bc)) bc = 0, ac = isNaN(ac) ? b.c : ac; - if (isNaN(bh)) bh = 0, ah = isNaN(ah) ? b.h : ah; else if (bh > 180) bh -= 360; else if (bh < -180) bh += 360; - return function(t) { - return d3_hcl_lab(ah + bh * t, ac + bc * t, al + bl * t) + ""; - }; - } - d3.interpolateHsl = d3_interpolateHsl; - function d3_interpolateHsl(a, b) { - a = d3.hsl(a); - b = d3.hsl(b); - var ah = a.h, as = a.s, al = a.l, bh = b.h - ah, bs = b.s - as, bl = b.l - al; - if (isNaN(bs)) bs = 0, as = isNaN(as) ? b.s : as; - if (isNaN(bh)) bh = 0, ah = isNaN(ah) ? b.h : ah; else if (bh > 180) bh -= 360; else if (bh < -180) bh += 360; - return function(t) { - return d3_hsl_rgb(ah + bh * t, as + bs * t, al + bl * t) + ""; - }; - } - d3.interpolateLab = d3_interpolateLab; - function d3_interpolateLab(a, b) { - a = d3.lab(a); - b = d3.lab(b); - var al = a.l, aa = a.a, ab = a.b, bl = b.l - al, ba = b.a - aa, bb = b.b - ab; - return function(t) { - return d3_lab_rgb(al + bl * t, aa + ba * t, ab + bb * t) + ""; - }; - } - d3.interpolateRound = d3_interpolateRound; - function d3_interpolateRound(a, b) { - b -= a; - return function(t) { - return Math.round(a + b * t); - }; - } - d3.transform = function(string) { - var g = d3_document.createElementNS(d3.ns.prefix.svg, "g"); - return (d3.transform = function(string) { - if (string != null) { - g.setAttribute("transform", string); - var t = g.transform.baseVal.consolidate(); - } - return new d3_transform(t ? t.matrix : d3_transformIdentity); - })(string); - }; - function d3_transform(m) { - var r0 = [ m.a, m.b ], r1 = [ m.c, m.d ], kx = d3_transformNormalize(r0), kz = d3_transformDot(r0, r1), ky = d3_transformNormalize(d3_transformCombine(r1, r0, -kz)) || 0; - if (r0[0] * r1[1] < r1[0] * r0[1]) { - r0[0] *= -1; - r0[1] *= -1; - kx *= -1; - kz *= -1; - } - this.rotate = (kx ? Math.atan2(r0[1], r0[0]) : Math.atan2(-r1[0], r1[1])) * d3_degrees; - this.translate = [ m.e, m.f ]; - this.scale = [ kx, ky ]; - this.skew = ky ? Math.atan2(kz, ky) * d3_degrees : 0; - } - d3_transform.prototype.toString = function() { - return "translate(" + this.translate + ")rotate(" + this.rotate + ")skewX(" + this.skew + ")scale(" + this.scale + ")"; - }; - function d3_transformDot(a, b) { - return a[0] * b[0] + a[1] * b[1]; - } - function d3_transformNormalize(a) { - var k = Math.sqrt(d3_transformDot(a, a)); - if (k) { - a[0] /= k; - a[1] /= k; - } - return k; - } - function d3_transformCombine(a, b, k) { - a[0] += k * b[0]; - a[1] += k * b[1]; - return a; - } - var d3_transformIdentity = { - a: 1, - b: 0, - c: 0, - d: 1, - e: 0, - f: 0 - }; - d3.interpolateTransform = d3_interpolateTransform; - function d3_interpolateTransform(a, b) { - var s = [], q = [], n, A = d3.transform(a), B = d3.transform(b), ta = A.translate, tb = B.translate, ra = A.rotate, rb = B.rotate, wa = A.skew, wb = B.skew, ka = A.scale, kb = B.scale; - if (ta[0] != tb[0] || ta[1] != tb[1]) { - s.push("translate(", null, ",", null, ")"); - q.push({ - i: 1, - x: d3_interpolateNumber(ta[0], tb[0]) - }, { - i: 3, - x: d3_interpolateNumber(ta[1], tb[1]) - }); - } else if (tb[0] || tb[1]) { - s.push("translate(" + tb + ")"); - } else { - s.push(""); - } - if (ra != rb) { - if (ra - rb > 180) rb += 360; else if (rb - ra > 180) ra += 360; - q.push({ - i: s.push(s.pop() + "rotate(", null, ")") - 2, - x: d3_interpolateNumber(ra, rb) - }); - } else if (rb) { - s.push(s.pop() + "rotate(" + rb + ")"); - } - if (wa != wb) { - q.push({ - i: s.push(s.pop() + "skewX(", null, ")") - 2, - x: d3_interpolateNumber(wa, wb) - }); - } else if (wb) { - s.push(s.pop() + "skewX(" + wb + ")"); - } - if (ka[0] != kb[0] || ka[1] != kb[1]) { - n = s.push(s.pop() + "scale(", null, ",", null, ")"); - q.push({ - i: n - 4, - x: d3_interpolateNumber(ka[0], kb[0]) - }, { - i: n - 2, - x: d3_interpolateNumber(ka[1], kb[1]) - }); - } else if (kb[0] != 1 || kb[1] != 1) { - s.push(s.pop() + "scale(" + kb + ")"); - } - n = q.length; - return function(t) { - var i = -1, o; - while (++i < n) s[(o = q[i]).i] = o.x(t); - return s.join(""); - }; - } - function d3_uninterpolateNumber(a, b) { - b = b - (a = +a) ? 1 / (b - a) : 0; - return function(x) { - return (x - a) * b; - }; - } - function d3_uninterpolateClamp(a, b) { - b = b - (a = +a) ? 1 / (b - a) : 0; - return function(x) { - return Math.max(0, Math.min(1, (x - a) * b)); - }; - } - d3.layout = {}; - d3.layout.bundle = function() { - return function(links) { - var paths = [], i = -1, n = links.length; - while (++i < n) paths.push(d3_layout_bundlePath(links[i])); - return paths; - }; - }; - function d3_layout_bundlePath(link) { - var start = link.source, end = link.target, lca = d3_layout_bundleLeastCommonAncestor(start, end), points = [ start ]; - while (start !== lca) { - start = start.parent; - points.push(start); - } - var k = points.length; - while (end !== lca) { - points.splice(k, 0, end); - end = end.parent; - } - return points; - } - function d3_layout_bundleAncestors(node) { - var ancestors = [], parent = node.parent; - while (parent != null) { - ancestors.push(node); - node = parent; - parent = parent.parent; - } - ancestors.push(node); - return ancestors; - } - function d3_layout_bundleLeastCommonAncestor(a, b) { - if (a === b) return a; - var aNodes = d3_layout_bundleAncestors(a), bNodes = d3_layout_bundleAncestors(b), aNode = aNodes.pop(), bNode = bNodes.pop(), sharedNode = null; - while (aNode === bNode) { - sharedNode = aNode; - aNode = aNodes.pop(); - bNode = bNodes.pop(); - } - return sharedNode; - } - d3.layout.chord = function() { - var chord = {}, chords, groups, matrix, n, padding = 0, sortGroups, sortSubgroups, sortChords; - function relayout() { - var subgroups = {}, groupSums = [], groupIndex = d3.range(n), subgroupIndex = [], k, x, x0, i, j; - chords = []; - groups = []; - k = 0, i = -1; - while (++i < n) { - x = 0, j = -1; - while (++j < n) { - x += matrix[i][j]; - } - groupSums.push(x); - subgroupIndex.push(d3.range(n)); - k += x; - } - if (sortGroups) { - groupIndex.sort(function(a, b) { - return sortGroups(groupSums[a], groupSums[b]); - }); - } - if (sortSubgroups) { - subgroupIndex.forEach(function(d, i) { - d.sort(function(a, b) { - return sortSubgroups(matrix[i][a], matrix[i][b]); - }); - }); - } - k = (Ï„ - padding * n) / k; - x = 0, i = -1; - while (++i < n) { - x0 = x, j = -1; - while (++j < n) { - var di = groupIndex[i], dj = subgroupIndex[di][j], v = matrix[di][dj], a0 = x, a1 = x += v * k; - subgroups[di + "-" + dj] = { - index: di, - subindex: dj, - startAngle: a0, - endAngle: a1, - value: v - }; - } - groups[di] = { - index: di, - startAngle: x0, - endAngle: x, - value: (x - x0) / k - }; - x += padding; - } - i = -1; - while (++i < n) { - j = i - 1; - while (++j < n) { - var source = subgroups[i + "-" + j], target = subgroups[j + "-" + i]; - if (source.value || target.value) { - chords.push(source.value < target.value ? { - source: target, - target: source - } : { - source: source, - target: target - }); - } - } - } - if (sortChords) resort(); - } - function resort() { - chords.sort(function(a, b) { - return sortChords((a.source.value + a.target.value) / 2, (b.source.value + b.target.value) / 2); - }); - } - chord.matrix = function(x) { - if (!arguments.length) return matrix; - n = (matrix = x) && matrix.length; - chords = groups = null; - return chord; - }; - chord.padding = function(x) { - if (!arguments.length) return padding; - padding = x; - chords = groups = null; - return chord; - }; - chord.sortGroups = function(x) { - if (!arguments.length) return sortGroups; - sortGroups = x; - chords = groups = null; - return chord; - }; - chord.sortSubgroups = function(x) { - if (!arguments.length) return sortSubgroups; - sortSubgroups = x; - chords = null; - return chord; - }; - chord.sortChords = function(x) { - if (!arguments.length) return sortChords; - sortChords = x; - if (chords) resort(); - return chord; - }; - chord.chords = function() { - if (!chords) relayout(); - return chords; - }; - chord.groups = function() { - if (!groups) relayout(); - return groups; - }; - return chord; - }; - d3.layout.force = function() { - var force = {}, event = d3.dispatch("start", "tick", "end"), size = [ 1, 1 ], drag, alpha, friction = .9, linkDistance = d3_layout_forceLinkDistance, linkStrength = d3_layout_forceLinkStrength, charge = -30, chargeDistance2 = d3_layout_forceChargeDistance2, gravity = .1, theta2 = .64, nodes = [], links = [], distances, strengths, charges; - function repulse(node) { - return function(quad, x1, _, x2) { - if (quad.point !== node) { - var dx = quad.cx - node.x, dy = quad.cy - node.y, dw = x2 - x1, dn = dx * dx + dy * dy; - if (dw * dw / theta2 < dn) { - if (dn < chargeDistance2) { - var k = quad.charge / dn; - node.px -= dx * k; - node.py -= dy * k; - } - return true; - } - if (quad.point && dn && dn < chargeDistance2) { - var k = quad.pointCharge / dn; - node.px -= dx * k; - node.py -= dy * k; - } - } - return !quad.charge; - }; - } - force.tick = function() { - if ((alpha *= .99) < .005) { - event.end({ - type: "end", - alpha: alpha = 0 - }); - return true; - } - var n = nodes.length, m = links.length, q, i, o, s, t, l, k, x, y; - for (i = 0; i < m; ++i) { - o = links[i]; - s = o.source; - t = o.target; - x = t.x - s.x; - y = t.y - s.y; - if (l = x * x + y * y) { - l = alpha * strengths[i] * ((l = Math.sqrt(l)) - distances[i]) / l; - x *= l; - y *= l; - t.x -= x * (k = s.weight / (t.weight + s.weight)); - t.y -= y * k; - s.x += x * (k = 1 - k); - s.y += y * k; - } - } - if (k = alpha * gravity) { - x = size[0] / 2; - y = size[1] / 2; - i = -1; - if (k) while (++i < n) { - o = nodes[i]; - o.x += (x - o.x) * k; - o.y += (y - o.y) * k; - } - } - if (charge) { - d3_layout_forceAccumulate(q = d3.geom.quadtree(nodes), alpha, charges); - i = -1; - while (++i < n) { - if (!(o = nodes[i]).fixed) { - q.visit(repulse(o)); - } - } - } - i = -1; - while (++i < n) { - o = nodes[i]; - if (o.fixed) { - o.x = o.px; - o.y = o.py; - } else { - o.x -= (o.px - (o.px = o.x)) * friction; - o.y -= (o.py - (o.py = o.y)) * friction; - } - } - event.tick({ - type: "tick", - alpha: alpha - }); - }; - force.nodes = function(x) { - if (!arguments.length) return nodes; - nodes = x; - return force; - }; - force.links = function(x) { - if (!arguments.length) return links; - links = x; - return force; - }; - force.size = function(x) { - if (!arguments.length) return size; - size = x; - return force; - }; - force.linkDistance = function(x) { - if (!arguments.length) return linkDistance; - linkDistance = typeof x === "function" ? x : +x; - return force; - }; - force.distance = force.linkDistance; - force.linkStrength = function(x) { - if (!arguments.length) return linkStrength; - linkStrength = typeof x === "function" ? x : +x; - return force; - }; - force.friction = function(x) { - if (!arguments.length) return friction; - friction = +x; - return force; - }; - force.charge = function(x) { - if (!arguments.length) return charge; - charge = typeof x === "function" ? x : +x; - return force; - }; - force.chargeDistance = function(x) { - if (!arguments.length) return Math.sqrt(chargeDistance2); - chargeDistance2 = x * x; - return force; - }; - force.gravity = function(x) { - if (!arguments.length) return gravity; - gravity = +x; - return force; - }; - force.theta = function(x) { - if (!arguments.length) return Math.sqrt(theta2); - theta2 = x * x; - return force; - }; - force.alpha = function(x) { - if (!arguments.length) return alpha; - x = +x; - if (alpha) { - if (x > 0) alpha = x; else alpha = 0; - } else if (x > 0) { - event.start({ - type: "start", - alpha: alpha = x - }); - d3.timer(force.tick); - } - return force; - }; - force.start = function() { - var i, n = nodes.length, m = links.length, w = size[0], h = size[1], neighbors, o; - for (i = 0; i < n; ++i) { - (o = nodes[i]).index = i; - o.weight = 0; - } - for (i = 0; i < m; ++i) { - o = links[i]; - if (typeof o.source == "number") o.source = nodes[o.source]; - if (typeof o.target == "number") o.target = nodes[o.target]; - ++o.source.weight; - ++o.target.weight; - } - for (i = 0; i < n; ++i) { - o = nodes[i]; - if (isNaN(o.x)) o.x = position("x", w); - if (isNaN(o.y)) o.y = position("y", h); - if (isNaN(o.px)) o.px = o.x; - if (isNaN(o.py)) o.py = o.y; - } - distances = []; - if (typeof linkDistance === "function") for (i = 0; i < m; ++i) distances[i] = +linkDistance.call(this, links[i], i); else for (i = 0; i < m; ++i) distances[i] = linkDistance; - strengths = []; - if (typeof linkStrength === "function") for (i = 0; i < m; ++i) strengths[i] = +linkStrength.call(this, links[i], i); else for (i = 0; i < m; ++i) strengths[i] = linkStrength; - charges = []; - if (typeof charge === "function") for (i = 0; i < n; ++i) charges[i] = +charge.call(this, nodes[i], i); else for (i = 0; i < n; ++i) charges[i] = charge; - function position(dimension, size) { - if (!neighbors) { - neighbors = new Array(n); - for (j = 0; j < n; ++j) { - neighbors[j] = []; - } - for (j = 0; j < m; ++j) { - var o = links[j]; - neighbors[o.source.index].push(o.target); - neighbors[o.target.index].push(o.source); - } - } - var candidates = neighbors[i], j = -1, m = candidates.length, x; - while (++j < m) if (!isNaN(x = candidates[j][dimension])) return x; - return Math.random() * size; - } - return force.resume(); - }; - force.resume = function() { - return force.alpha(.1); - }; - force.stop = function() { - return force.alpha(0); - }; - force.drag = function() { - if (!drag) drag = d3.behavior.drag().origin(d3_identity).on("dragstart.force", d3_layout_forceDragstart).on("drag.force", dragmove).on("dragend.force", d3_layout_forceDragend); - if (!arguments.length) return drag; - this.on("mouseover.force", d3_layout_forceMouseover).on("mouseout.force", d3_layout_forceMouseout).call(drag); - }; - function dragmove(d) { - d.px = d3.event.x, d.py = d3.event.y; - force.resume(); - } - return d3.rebind(force, event, "on"); - }; - function d3_layout_forceDragstart(d) { - d.fixed |= 2; - } - function d3_layout_forceDragend(d) { - d.fixed &= ~6; - } - function d3_layout_forceMouseover(d) { - d.fixed |= 4; - d.px = d.x, d.py = d.y; - } - function d3_layout_forceMouseout(d) { - d.fixed &= ~4; - } - function d3_layout_forceAccumulate(quad, alpha, charges) { - var cx = 0, cy = 0; - quad.charge = 0; - if (!quad.leaf) { - var nodes = quad.nodes, n = nodes.length, i = -1, c; - while (++i < n) { - c = nodes[i]; - if (c == null) continue; - d3_layout_forceAccumulate(c, alpha, charges); - quad.charge += c.charge; - cx += c.charge * c.cx; - cy += c.charge * c.cy; - } - } - if (quad.point) { - if (!quad.leaf) { - quad.point.x += Math.random() - .5; - quad.point.y += Math.random() - .5; - } - var k = alpha * charges[quad.point.index]; - quad.charge += quad.pointCharge = k; - cx += k * quad.point.x; - cy += k * quad.point.y; - } - quad.cx = cx / quad.charge; - quad.cy = cy / quad.charge; - } - var d3_layout_forceLinkDistance = 20, d3_layout_forceLinkStrength = 1, d3_layout_forceChargeDistance2 = Infinity; - d3.layout.hierarchy = function() { - var sort = d3_layout_hierarchySort, children = d3_layout_hierarchyChildren, value = d3_layout_hierarchyValue; - function recurse(node, depth, nodes) { - var childs = children.call(hierarchy, node, depth); - node.depth = depth; - nodes.push(node); - if (childs && (n = childs.length)) { - var i = -1, n, c = node.children = new Array(n), v = 0, j = depth + 1, d; - while (++i < n) { - d = c[i] = recurse(childs[i], j, nodes); - d.parent = node; - v += d.value; - } - if (sort) c.sort(sort); - if (value) node.value = v; - } else { - delete node.children; - if (value) { - node.value = +value.call(hierarchy, node, depth) || 0; - } - } - return node; - } - function revalue(node, depth) { - var children = node.children, v = 0; - if (children && (n = children.length)) { - var i = -1, n, j = depth + 1; - while (++i < n) v += revalue(children[i], j); - } else if (value) { - v = +value.call(hierarchy, node, depth) || 0; - } - if (value) node.value = v; - return v; - } - function hierarchy(d) { - var nodes = []; - recurse(d, 0, nodes); - return nodes; - } - hierarchy.sort = function(x) { - if (!arguments.length) return sort; - sort = x; - return hierarchy; - }; - hierarchy.children = function(x) { - if (!arguments.length) return children; - children = x; - return hierarchy; - }; - hierarchy.value = function(x) { - if (!arguments.length) return value; - value = x; - return hierarchy; - }; - hierarchy.revalue = function(root) { - revalue(root, 0); - return root; - }; - return hierarchy; - }; - function d3_layout_hierarchyRebind(object, hierarchy) { - d3.rebind(object, hierarchy, "sort", "children", "value"); - object.nodes = object; - object.links = d3_layout_hierarchyLinks; - return object; - } - function d3_layout_hierarchyChildren(d) { - return d.children; - } - function d3_layout_hierarchyValue(d) { - return d.value; - } - function d3_layout_hierarchySort(a, b) { - return b.value - a.value; - } - function d3_layout_hierarchyLinks(nodes) { - return d3.merge(nodes.map(function(parent) { - return (parent.children || []).map(function(child) { - return { - source: parent, - target: child - }; - }); - })); - } - d3.layout.partition = function() { - var hierarchy = d3.layout.hierarchy(), size = [ 1, 1 ]; - function position(node, x, dx, dy) { - var children = node.children; - node.x = x; - node.y = node.depth * dy; - node.dx = dx; - node.dy = dy; - if (children && (n = children.length)) { - var i = -1, n, c, d; - dx = node.value ? dx / node.value : 0; - while (++i < n) { - position(c = children[i], x, d = c.value * dx, dy); - x += d; - } - } - } - function depth(node) { - var children = node.children, d = 0; - if (children && (n = children.length)) { - var i = -1, n; - while (++i < n) d = Math.max(d, depth(children[i])); - } - return 1 + d; - } - function partition(d, i) { - var nodes = hierarchy.call(this, d, i); - position(nodes[0], 0, size[0], size[1] / depth(nodes[0])); - return nodes; - } - partition.size = function(x) { - if (!arguments.length) return size; - size = x; - return partition; - }; - return d3_layout_hierarchyRebind(partition, hierarchy); - }; - d3.layout.pie = function() { - var value = Number, sort = d3_layout_pieSortByValue, startAngle = 0, endAngle = Ï„; - function pie(data) { - var values = data.map(function(d, i) { - return +value.call(pie, d, i); - }); - var a = +(typeof startAngle === "function" ? startAngle.apply(this, arguments) : startAngle); - var k = ((typeof endAngle === "function" ? endAngle.apply(this, arguments) : endAngle) - a) / d3.sum(values); - var index = d3.range(data.length); - if (sort != null) index.sort(sort === d3_layout_pieSortByValue ? function(i, j) { - return values[j] - values[i]; - } : function(i, j) { - return sort(data[i], data[j]); - }); - var arcs = []; - index.forEach(function(i) { - var d; - arcs[i] = { - data: data[i], - value: d = values[i], - startAngle: a, - endAngle: a += d * k - }; - }); - return arcs; - } - pie.value = function(x) { - if (!arguments.length) return value; - value = x; - return pie; - }; - pie.sort = function(x) { - if (!arguments.length) return sort; - sort = x; - return pie; - }; - pie.startAngle = function(x) { - if (!arguments.length) return startAngle; - startAngle = x; - return pie; - }; - pie.endAngle = function(x) { - if (!arguments.length) return endAngle; - endAngle = x; - return pie; - }; - return pie; - }; - var d3_layout_pieSortByValue = {}; - d3.layout.stack = function() { - var values = d3_identity, order = d3_layout_stackOrderDefault, offset = d3_layout_stackOffsetZero, out = d3_layout_stackOut, x = d3_layout_stackX, y = d3_layout_stackY; - function stack(data, index) { - var series = data.map(function(d, i) { - return values.call(stack, d, i); - }); - var points = series.map(function(d) { - return d.map(function(v, i) { - return [ x.call(stack, v, i), y.call(stack, v, i) ]; - }); - }); - var orders = order.call(stack, points, index); - series = d3.permute(series, orders); - points = d3.permute(points, orders); - var offsets = offset.call(stack, points, index); - var n = series.length, m = series[0].length, i, j, o; - for (j = 0; j < m; ++j) { - out.call(stack, series[0][j], o = offsets[j], points[0][j][1]); - for (i = 1; i < n; ++i) { - out.call(stack, series[i][j], o += points[i - 1][j][1], points[i][j][1]); - } - } - return data; - } - stack.values = function(x) { - if (!arguments.length) return values; - values = x; - return stack; - }; - stack.order = function(x) { - if (!arguments.length) return order; - order = typeof x === "function" ? x : d3_layout_stackOrders.get(x) || d3_layout_stackOrderDefault; - return stack; - }; - stack.offset = function(x) { - if (!arguments.length) return offset; - offset = typeof x === "function" ? x : d3_layout_stackOffsets.get(x) || d3_layout_stackOffsetZero; - return stack; - }; - stack.x = function(z) { - if (!arguments.length) return x; - x = z; - return stack; - }; - stack.y = function(z) { - if (!arguments.length) return y; - y = z; - return stack; - }; - stack.out = function(z) { - if (!arguments.length) return out; - out = z; - return stack; - }; - return stack; - }; - function d3_layout_stackX(d) { - return d.x; - } - function d3_layout_stackY(d) { - return d.y; - } - function d3_layout_stackOut(d, y0, y) { - d.y0 = y0; - d.y = y; - } - var d3_layout_stackOrders = d3.map({ - "inside-out": function(data) { - var n = data.length, i, j, max = data.map(d3_layout_stackMaxIndex), sums = data.map(d3_layout_stackReduceSum), index = d3.range(n).sort(function(a, b) { - return max[a] - max[b]; - }), top = 0, bottom = 0, tops = [], bottoms = []; - for (i = 0; i < n; ++i) { - j = index[i]; - if (top < bottom) { - top += sums[j]; - tops.push(j); - } else { - bottom += sums[j]; - bottoms.push(j); - } - } - return bottoms.reverse().concat(tops); - }, - reverse: function(data) { - return d3.range(data.length).reverse(); - }, - "default": d3_layout_stackOrderDefault - }); - var d3_layout_stackOffsets = d3.map({ - silhouette: function(data) { - var n = data.length, m = data[0].length, sums = [], max = 0, i, j, o, y0 = []; - for (j = 0; j < m; ++j) { - for (i = 0, o = 0; i < n; i++) o += data[i][j][1]; - if (o > max) max = o; - sums.push(o); - } - for (j = 0; j < m; ++j) { - y0[j] = (max - sums[j]) / 2; - } - return y0; - }, - wiggle: function(data) { - var n = data.length, x = data[0], m = x.length, i, j, k, s1, s2, s3, dx, o, o0, y0 = []; - y0[0] = o = o0 = 0; - for (j = 1; j < m; ++j) { - for (i = 0, s1 = 0; i < n; ++i) s1 += data[i][j][1]; - for (i = 0, s2 = 0, dx = x[j][0] - x[j - 1][0]; i < n; ++i) { - for (k = 0, s3 = (data[i][j][1] - data[i][j - 1][1]) / (2 * dx); k < i; ++k) { - s3 += (data[k][j][1] - data[k][j - 1][1]) / dx; - } - s2 += s3 * data[i][j][1]; - } - y0[j] = o -= s1 ? s2 / s1 * dx : 0; - if (o < o0) o0 = o; - } - for (j = 0; j < m; ++j) y0[j] -= o0; - return y0; - }, - expand: function(data) { - var n = data.length, m = data[0].length, k = 1 / n, i, j, o, y0 = []; - for (j = 0; j < m; ++j) { - for (i = 0, o = 0; i < n; i++) o += data[i][j][1]; - if (o) for (i = 0; i < n; i++) data[i][j][1] /= o; else for (i = 0; i < n; i++) data[i][j][1] = k; - } - for (j = 0; j < m; ++j) y0[j] = 0; - return y0; - }, - zero: d3_layout_stackOffsetZero - }); - function d3_layout_stackOrderDefault(data) { - return d3.range(data.length); - } - function d3_layout_stackOffsetZero(data) { - var j = -1, m = data[0].length, y0 = []; - while (++j < m) y0[j] = 0; - return y0; - } - function d3_layout_stackMaxIndex(array) { - var i = 1, j = 0, v = array[0][1], k, n = array.length; - for (;i < n; ++i) { - if ((k = array[i][1]) > v) { - j = i; - v = k; - } - } - return j; - } - function d3_layout_stackReduceSum(d) { - return d.reduce(d3_layout_stackSum, 0); - } - function d3_layout_stackSum(p, d) { - return p + d[1]; - } - d3.layout.histogram = function() { - var frequency = true, valuer = Number, ranger = d3_layout_histogramRange, binner = d3_layout_histogramBinSturges; - function histogram(data, i) { - var bins = [], values = data.map(valuer, this), range = ranger.call(this, values, i), thresholds = binner.call(this, range, values, i), bin, i = -1, n = values.length, m = thresholds.length - 1, k = frequency ? 1 : 1 / n, x; - while (++i < m) { - bin = bins[i] = []; - bin.dx = thresholds[i + 1] - (bin.x = thresholds[i]); - bin.y = 0; - } - if (m > 0) { - i = -1; - while (++i < n) { - x = values[i]; - if (x >= range[0] && x <= range[1]) { - bin = bins[d3.bisect(thresholds, x, 1, m) - 1]; - bin.y += k; - bin.push(data[i]); - } - } - } - return bins; - } - histogram.value = function(x) { - if (!arguments.length) return valuer; - valuer = x; - return histogram; - }; - histogram.range = function(x) { - if (!arguments.length) return ranger; - ranger = d3_functor(x); - return histogram; - }; - histogram.bins = function(x) { - if (!arguments.length) return binner; - binner = typeof x === "number" ? function(range) { - return d3_layout_histogramBinFixed(range, x); - } : d3_functor(x); - return histogram; - }; - histogram.frequency = function(x) { - if (!arguments.length) return frequency; - frequency = !!x; - return histogram; - }; - return histogram; - }; - function d3_layout_histogramBinSturges(range, values) { - return d3_layout_histogramBinFixed(range, Math.ceil(Math.log(values.length) / Math.LN2 + 1)); - } - function d3_layout_histogramBinFixed(range, n) { - var x = -1, b = +range[0], m = (range[1] - b) / n, f = []; - while (++x <= n) f[x] = m * x + b; - return f; - } - function d3_layout_histogramRange(values) { - return [ d3.min(values), d3.max(values) ]; - } - d3.layout.tree = function() { - var hierarchy = d3.layout.hierarchy().sort(null).value(null), separation = d3_layout_treeSeparation, size = [ 1, 1 ], nodeSize = false; - function tree(d, i) { - var nodes = hierarchy.call(this, d, i), root = nodes[0]; - function firstWalk(node, previousSibling) { - var children = node.children, layout = node._tree; - if (children && (n = children.length)) { - var n, firstChild = children[0], previousChild, ancestor = firstChild, child, i = -1; - while (++i < n) { - child = children[i]; - firstWalk(child, previousChild); - ancestor = apportion(child, previousChild, ancestor); - previousChild = child; - } - d3_layout_treeShift(node); - var midpoint = .5 * (firstChild._tree.prelim + child._tree.prelim); - if (previousSibling) { - layout.prelim = previousSibling._tree.prelim + separation(node, previousSibling); - layout.mod = layout.prelim - midpoint; - } else { - layout.prelim = midpoint; - } - } else { - if (previousSibling) { - layout.prelim = previousSibling._tree.prelim + separation(node, previousSibling); - } - } - } - function secondWalk(node, x) { - node.x = node._tree.prelim + x; - var children = node.children; - if (children && (n = children.length)) { - var i = -1, n; - x += node._tree.mod; - while (++i < n) { - secondWalk(children[i], x); - } - } - } - function apportion(node, previousSibling, ancestor) { - if (previousSibling) { - var vip = node, vop = node, vim = previousSibling, vom = node.parent.children[0], sip = vip._tree.mod, sop = vop._tree.mod, sim = vim._tree.mod, som = vom._tree.mod, shift; - while (vim = d3_layout_treeRight(vim), vip = d3_layout_treeLeft(vip), vim && vip) { - vom = d3_layout_treeLeft(vom); - vop = d3_layout_treeRight(vop); - vop._tree.ancestor = node; - shift = vim._tree.prelim + sim - vip._tree.prelim - sip + separation(vim, vip); - if (shift > 0) { - d3_layout_treeMove(d3_layout_treeAncestor(vim, node, ancestor), node, shift); - sip += shift; - sop += shift; - } - sim += vim._tree.mod; - sip += vip._tree.mod; - som += vom._tree.mod; - sop += vop._tree.mod; - } - if (vim && !d3_layout_treeRight(vop)) { - vop._tree.thread = vim; - vop._tree.mod += sim - sop; - } - if (vip && !d3_layout_treeLeft(vom)) { - vom._tree.thread = vip; - vom._tree.mod += sip - som; - ancestor = node; - } - } - return ancestor; - } - d3_layout_treeVisitAfter(root, function(node, previousSibling) { - node._tree = { - ancestor: node, - prelim: 0, - mod: 0, - change: 0, - shift: 0, - number: previousSibling ? previousSibling._tree.number + 1 : 0 - }; - }); - firstWalk(root); - secondWalk(root, -root._tree.prelim); - var left = d3_layout_treeSearch(root, d3_layout_treeLeftmost), right = d3_layout_treeSearch(root, d3_layout_treeRightmost), deep = d3_layout_treeSearch(root, d3_layout_treeDeepest), x0 = left.x - separation(left, right) / 2, x1 = right.x + separation(right, left) / 2, y1 = deep.depth || 1; - d3_layout_treeVisitAfter(root, nodeSize ? function(node) { - node.x *= size[0]; - node.y = node.depth * size[1]; - delete node._tree; - } : function(node) { - node.x = (node.x - x0) / (x1 - x0) * size[0]; - node.y = node.depth / y1 * size[1]; - delete node._tree; - }); - return nodes; - } - tree.separation = function(x) { - if (!arguments.length) return separation; - separation = x; - return tree; - }; - tree.size = function(x) { - if (!arguments.length) return nodeSize ? null : size; - nodeSize = (size = x) == null; - return tree; - }; - tree.nodeSize = function(x) { - if (!arguments.length) return nodeSize ? size : null; - nodeSize = (size = x) != null; - return tree; - }; - return d3_layout_hierarchyRebind(tree, hierarchy); - }; - function d3_layout_treeSeparation(a, b) { - return a.parent == b.parent ? 1 : 2; - } - function d3_layout_treeLeft(node) { - var children = node.children; - return children && children.length ? children[0] : node._tree.thread; - } - function d3_layout_treeRight(node) { - var children = node.children, n; - return children && (n = children.length) ? children[n - 1] : node._tree.thread; - } - function d3_layout_treeSearch(node, compare) { - var children = node.children; - if (children && (n = children.length)) { - var child, n, i = -1; - while (++i < n) { - if (compare(child = d3_layout_treeSearch(children[i], compare), node) > 0) { - node = child; - } - } - } - return node; - } - function d3_layout_treeRightmost(a, b) { - return a.x - b.x; - } - function d3_layout_treeLeftmost(a, b) { - return b.x - a.x; - } - function d3_layout_treeDeepest(a, b) { - return a.depth - b.depth; - } - function d3_layout_treeVisitAfter(node, callback) { - function visit(node, previousSibling) { - var children = node.children; - if (children && (n = children.length)) { - var child, previousChild = null, i = -1, n; - while (++i < n) { - child = children[i]; - visit(child, previousChild); - previousChild = child; - } - } - callback(node, previousSibling); - } - visit(node, null); - } - function d3_layout_treeShift(node) { - var shift = 0, change = 0, children = node.children, i = children.length, child; - while (--i >= 0) { - child = children[i]._tree; - child.prelim += shift; - child.mod += shift; - shift += child.shift + (change += child.change); - } - } - function d3_layout_treeMove(ancestor, node, shift) { - ancestor = ancestor._tree; - node = node._tree; - var change = shift / (node.number - ancestor.number); - ancestor.change += change; - node.change -= change; - node.shift += shift; - node.prelim += shift; - node.mod += shift; - } - function d3_layout_treeAncestor(vim, node, ancestor) { - return vim._tree.ancestor.parent == node.parent ? vim._tree.ancestor : ancestor; - } - d3.layout.pack = function() { - var hierarchy = d3.layout.hierarchy().sort(d3_layout_packSort), padding = 0, size = [ 1, 1 ], radius; - function pack(d, i) { - var nodes = hierarchy.call(this, d, i), root = nodes[0], w = size[0], h = size[1], r = radius == null ? Math.sqrt : typeof radius === "function" ? radius : function() { - return radius; - }; - root.x = root.y = 0; - d3_layout_treeVisitAfter(root, function(d) { - d.r = +r(d.value); - }); - d3_layout_treeVisitAfter(root, d3_layout_packSiblings); - if (padding) { - var dr = padding * (radius ? 1 : Math.max(2 * root.r / w, 2 * root.r / h)) / 2; - d3_layout_treeVisitAfter(root, function(d) { - d.r += dr; - }); - d3_layout_treeVisitAfter(root, d3_layout_packSiblings); - d3_layout_treeVisitAfter(root, function(d) { - d.r -= dr; - }); - } - d3_layout_packTransform(root, w / 2, h / 2, radius ? 1 : 1 / Math.max(2 * root.r / w, 2 * root.r / h)); - return nodes; - } - pack.size = function(_) { - if (!arguments.length) return size; - size = _; - return pack; - }; - pack.radius = function(_) { - if (!arguments.length) return radius; - radius = _ == null || typeof _ === "function" ? _ : +_; - return pack; - }; - pack.padding = function(_) { - if (!arguments.length) return padding; - padding = +_; - return pack; - }; - return d3_layout_hierarchyRebind(pack, hierarchy); - }; - function d3_layout_packSort(a, b) { - return a.value - b.value; - } - function d3_layout_packInsert(a, b) { - var c = a._pack_next; - a._pack_next = b; - b._pack_prev = a; - b._pack_next = c; - c._pack_prev = b; - } - function d3_layout_packSplice(a, b) { - a._pack_next = b; - b._pack_prev = a; - } - function d3_layout_packIntersects(a, b) { - var dx = b.x - a.x, dy = b.y - a.y, dr = a.r + b.r; - return .999 * dr * dr > dx * dx + dy * dy; - } - function d3_layout_packSiblings(node) { - if (!(nodes = node.children) || !(n = nodes.length)) return; - var nodes, xMin = Infinity, xMax = -Infinity, yMin = Infinity, yMax = -Infinity, a, b, c, i, j, k, n; - function bound(node) { - xMin = Math.min(node.x - node.r, xMin); - xMax = Math.max(node.x + node.r, xMax); - yMin = Math.min(node.y - node.r, yMin); - yMax = Math.max(node.y + node.r, yMax); - } - nodes.forEach(d3_layout_packLink); - a = nodes[0]; - a.x = -a.r; - a.y = 0; - bound(a); - if (n > 1) { - b = nodes[1]; - b.x = b.r; - b.y = 0; - bound(b); - if (n > 2) { - c = nodes[2]; - d3_layout_packPlace(a, b, c); - bound(c); - d3_layout_packInsert(a, c); - a._pack_prev = c; - d3_layout_packInsert(c, b); - b = a._pack_next; - for (i = 3; i < n; i++) { - d3_layout_packPlace(a, b, c = nodes[i]); - var isect = 0, s1 = 1, s2 = 1; - for (j = b._pack_next; j !== b; j = j._pack_next, s1++) { - if (d3_layout_packIntersects(j, c)) { - isect = 1; - break; - } - } - if (isect == 1) { - for (k = a._pack_prev; k !== j._pack_prev; k = k._pack_prev, s2++) { - if (d3_layout_packIntersects(k, c)) { - break; - } - } - } - if (isect) { - if (s1 < s2 || s1 == s2 && b.r < a.r) d3_layout_packSplice(a, b = j); else d3_layout_packSplice(a = k, b); - i--; - } else { - d3_layout_packInsert(a, c); - b = c; - bound(c); - } - } - } - } - var cx = (xMin + xMax) / 2, cy = (yMin + yMax) / 2, cr = 0; - for (i = 0; i < n; i++) { - c = nodes[i]; - c.x -= cx; - c.y -= cy; - cr = Math.max(cr, c.r + Math.sqrt(c.x * c.x + c.y * c.y)); - } - node.r = cr; - nodes.forEach(d3_layout_packUnlink); - } - function d3_layout_packLink(node) { - node._pack_next = node._pack_prev = node; - } - function d3_layout_packUnlink(node) { - delete node._pack_next; - delete node._pack_prev; - } - function d3_layout_packTransform(node, x, y, k) { - var children = node.children; - node.x = x += k * node.x; - node.y = y += k * node.y; - node.r *= k; - if (children) { - var i = -1, n = children.length; - while (++i < n) d3_layout_packTransform(children[i], x, y, k); - } - } - function d3_layout_packPlace(a, b, c) { - var db = a.r + c.r, dx = b.x - a.x, dy = b.y - a.y; - if (db && (dx || dy)) { - var da = b.r + c.r, dc = dx * dx + dy * dy; - da *= da; - db *= db; - var x = .5 + (db - da) / (2 * dc), y = Math.sqrt(Math.max(0, 2 * da * (db + dc) - (db -= dc) * db - da * da)) / (2 * dc); - c.x = a.x + x * dx + y * dy; - c.y = a.y + x * dy - y * dx; - } else { - c.x = a.x + db; - c.y = a.y; - } - } - d3.layout.cluster = function() { - var hierarchy = d3.layout.hierarchy().sort(null).value(null), separation = d3_layout_treeSeparation, size = [ 1, 1 ], nodeSize = false; - function cluster(d, i) { - var nodes = hierarchy.call(this, d, i), root = nodes[0], previousNode, x = 0; - d3_layout_treeVisitAfter(root, function(node) { - var children = node.children; - if (children && children.length) { - node.x = d3_layout_clusterX(children); - node.y = d3_layout_clusterY(children); - } else { - node.x = previousNode ? x += separation(node, previousNode) : 0; - node.y = 0; - previousNode = node; - } - }); - var left = d3_layout_clusterLeft(root), right = d3_layout_clusterRight(root), x0 = left.x - separation(left, right) / 2, x1 = right.x + separation(right, left) / 2; - d3_layout_treeVisitAfter(root, nodeSize ? function(node) { - node.x = (node.x - root.x) * size[0]; - node.y = (root.y - node.y) * size[1]; - } : function(node) { - node.x = (node.x - x0) / (x1 - x0) * size[0]; - node.y = (1 - (root.y ? node.y / root.y : 1)) * size[1]; - }); - return nodes; - } - cluster.separation = function(x) { - if (!arguments.length) return separation; - separation = x; - return cluster; - }; - cluster.size = function(x) { - if (!arguments.length) return nodeSize ? null : size; - nodeSize = (size = x) == null; - return cluster; - }; - cluster.nodeSize = function(x) { - if (!arguments.length) return nodeSize ? size : null; - nodeSize = (size = x) != null; - return cluster; - }; - return d3_layout_hierarchyRebind(cluster, hierarchy); - }; - function d3_layout_clusterY(children) { - return 1 + d3.max(children, function(child) { - return child.y; - }); - } - function d3_layout_clusterX(children) { - return children.reduce(function(x, child) { - return x + child.x; - }, 0) / children.length; - } - function d3_layout_clusterLeft(node) { - var children = node.children; - return children && children.length ? d3_layout_clusterLeft(children[0]) : node; - } - function d3_layout_clusterRight(node) { - var children = node.children, n; - return children && (n = children.length) ? d3_layout_clusterRight(children[n - 1]) : node; - } - d3.layout.treemap = function() { - var hierarchy = d3.layout.hierarchy(), round = Math.round, size = [ 1, 1 ], padding = null, pad = d3_layout_treemapPadNull, sticky = false, stickies, mode = "squarify", ratio = .5 * (1 + Math.sqrt(5)); - function scale(children, k) { - var i = -1, n = children.length, child, area; - while (++i < n) { - area = (child = children[i]).value * (k < 0 ? 0 : k); - child.area = isNaN(area) || area <= 0 ? 0 : area; - } - } - function squarify(node) { - var children = node.children; - if (children && children.length) { - var rect = pad(node), row = [], remaining = children.slice(), child, best = Infinity, score, u = mode === "slice" ? rect.dx : mode === "dice" ? rect.dy : mode === "slice-dice" ? node.depth & 1 ? rect.dy : rect.dx : Math.min(rect.dx, rect.dy), n; - scale(remaining, rect.dx * rect.dy / node.value); - row.area = 0; - while ((n = remaining.length) > 0) { - row.push(child = remaining[n - 1]); - row.area += child.area; - if (mode !== "squarify" || (score = worst(row, u)) <= best) { - remaining.pop(); - best = score; - } else { - row.area -= row.pop().area; - position(row, u, rect, false); - u = Math.min(rect.dx, rect.dy); - row.length = row.area = 0; - best = Infinity; - } - } - if (row.length) { - position(row, u, rect, true); - row.length = row.area = 0; - } - children.forEach(squarify); - } - } - function stickify(node) { - var children = node.children; - if (children && children.length) { - var rect = pad(node), remaining = children.slice(), child, row = []; - scale(remaining, rect.dx * rect.dy / node.value); - row.area = 0; - while (child = remaining.pop()) { - row.push(child); - row.area += child.area; - if (child.z != null) { - position(row, child.z ? rect.dx : rect.dy, rect, !remaining.length); - row.length = row.area = 0; - } - } - children.forEach(stickify); - } - } - function worst(row, u) { - var s = row.area, r, rmax = 0, rmin = Infinity, i = -1, n = row.length; - while (++i < n) { - if (!(r = row[i].area)) continue; - if (r < rmin) rmin = r; - if (r > rmax) rmax = r; - } - s *= s; - u *= u; - return s ? Math.max(u * rmax * ratio / s, s / (u * rmin * ratio)) : Infinity; - } - function position(row, u, rect, flush) { - var i = -1, n = row.length, x = rect.x, y = rect.y, v = u ? round(row.area / u) : 0, o; - if (u == rect.dx) { - if (flush || v > rect.dy) v = rect.dy; - while (++i < n) { - o = row[i]; - o.x = x; - o.y = y; - o.dy = v; - x += o.dx = Math.min(rect.x + rect.dx - x, v ? round(o.area / v) : 0); - } - o.z = true; - o.dx += rect.x + rect.dx - x; - rect.y += v; - rect.dy -= v; - } else { - if (flush || v > rect.dx) v = rect.dx; - while (++i < n) { - o = row[i]; - o.x = x; - o.y = y; - o.dx = v; - y += o.dy = Math.min(rect.y + rect.dy - y, v ? round(o.area / v) : 0); - } - o.z = false; - o.dy += rect.y + rect.dy - y; - rect.x += v; - rect.dx -= v; - } - } - function treemap(d) { - var nodes = stickies || hierarchy(d), root = nodes[0]; - root.x = 0; - root.y = 0; - root.dx = size[0]; - root.dy = size[1]; - if (stickies) hierarchy.revalue(root); - scale([ root ], root.dx * root.dy / root.value); - (stickies ? stickify : squarify)(root); - if (sticky) stickies = nodes; - return nodes; - } - treemap.size = function(x) { - if (!arguments.length) return size; - size = x; - return treemap; - }; - treemap.padding = function(x) { - if (!arguments.length) return padding; - function padFunction(node) { - var p = x.call(treemap, node, node.depth); - return p == null ? d3_layout_treemapPadNull(node) : d3_layout_treemapPad(node, typeof p === "number" ? [ p, p, p, p ] : p); - } - function padConstant(node) { - return d3_layout_treemapPad(node, x); - } - var type; - pad = (padding = x) == null ? d3_layout_treemapPadNull : (type = typeof x) === "function" ? padFunction : type === "number" ? (x = [ x, x, x, x ], - padConstant) : padConstant; - return treemap; - }; - treemap.round = function(x) { - if (!arguments.length) return round != Number; - round = x ? Math.round : Number; - return treemap; - }; - treemap.sticky = function(x) { - if (!arguments.length) return sticky; - sticky = x; - stickies = null; - return treemap; - }; - treemap.ratio = function(x) { - if (!arguments.length) return ratio; - ratio = x; - return treemap; - }; - treemap.mode = function(x) { - if (!arguments.length) return mode; - mode = x + ""; - return treemap; - }; - return d3_layout_hierarchyRebind(treemap, hierarchy); - }; - function d3_layout_treemapPadNull(node) { - return { - x: node.x, - y: node.y, - dx: node.dx, - dy: node.dy - }; - } - function d3_layout_treemapPad(node, padding) { - var x = node.x + padding[3], y = node.y + padding[0], dx = node.dx - padding[1] - padding[3], dy = node.dy - padding[0] - padding[2]; - if (dx < 0) { - x += dx / 2; - dx = 0; - } - if (dy < 0) { - y += dy / 2; - dy = 0; - } - return { - x: x, - y: y, - dx: dx, - dy: dy - }; - } - d3.random = { - normal: function(µ, σ) { - var n = arguments.length; - if (n < 2) σ = 1; - if (n < 1) µ = 0; - return function() { - var x, y, r; - do { - x = Math.random() * 2 - 1; - y = Math.random() * 2 - 1; - r = x * x + y * y; - } while (!r || r > 1); - return µ + σ * x * Math.sqrt(-2 * Math.log(r) / r); - }; - }, - logNormal: function() { - var random = d3.random.normal.apply(d3, arguments); - return function() { - return Math.exp(random()); - }; - }, - bates: function(m) { - var random = d3.random.irwinHall(m); - return function() { - return random() / m; - }; - }, - irwinHall: function(m) { - return function() { - for (var s = 0, j = 0; j < m; j++) s += Math.random(); - return s; - }; - } - }; - d3.scale = {}; - function d3_scaleExtent(domain) { - var start = domain[0], stop = domain[domain.length - 1]; - return start < stop ? [ start, stop ] : [ stop, start ]; - } - function d3_scaleRange(scale) { - return scale.rangeExtent ? scale.rangeExtent() : d3_scaleExtent(scale.range()); - } - function d3_scale_bilinear(domain, range, uninterpolate, interpolate) { - var u = uninterpolate(domain[0], domain[1]), i = interpolate(range[0], range[1]); - return function(x) { - return i(u(x)); - }; - } - function d3_scale_nice(domain, nice) { - var i0 = 0, i1 = domain.length - 1, x0 = domain[i0], x1 = domain[i1], dx; - if (x1 < x0) { - dx = i0, i0 = i1, i1 = dx; - dx = x0, x0 = x1, x1 = dx; - } - domain[i0] = nice.floor(x0); - domain[i1] = nice.ceil(x1); - return domain; - } - function d3_scale_niceStep(step) { - return step ? { - floor: function(x) { - return Math.floor(x / step) * step; - }, - ceil: function(x) { - return Math.ceil(x / step) * step; - } - } : d3_scale_niceIdentity; - } - var d3_scale_niceIdentity = { - floor: d3_identity, - ceil: d3_identity - }; - function d3_scale_polylinear(domain, range, uninterpolate, interpolate) { - var u = [], i = [], j = 0, k = Math.min(domain.length, range.length) - 1; - if (domain[k] < domain[0]) { - domain = domain.slice().reverse(); - range = range.slice().reverse(); - } - while (++j <= k) { - u.push(uninterpolate(domain[j - 1], domain[j])); - i.push(interpolate(range[j - 1], range[j])); - } - return function(x) { - var j = d3.bisect(domain, x, 1, k) - 1; - return i[j](u[j](x)); - }; - } - d3.scale.linear = function() { - return d3_scale_linear([ 0, 1 ], [ 0, 1 ], d3_interpolate, false); - }; - function d3_scale_linear(domain, range, interpolate, clamp) { - var output, input; - function rescale() { - var linear = Math.min(domain.length, range.length) > 2 ? d3_scale_polylinear : d3_scale_bilinear, uninterpolate = clamp ? d3_uninterpolateClamp : d3_uninterpolateNumber; - output = linear(domain, range, uninterpolate, interpolate); - input = linear(range, domain, uninterpolate, d3_interpolate); - return scale; - } - function scale(x) { - return output(x); - } - scale.invert = function(y) { - return input(y); - }; - scale.domain = function(x) { - if (!arguments.length) return domain; - domain = x.map(Number); - return rescale(); - }; - scale.range = function(x) { - if (!arguments.length) return range; - range = x; - return rescale(); - }; - scale.rangeRound = function(x) { - return scale.range(x).interpolate(d3_interpolateRound); - }; - scale.clamp = function(x) { - if (!arguments.length) return clamp; - clamp = x; - return rescale(); - }; - scale.interpolate = function(x) { - if (!arguments.length) return interpolate; - interpolate = x; - return rescale(); - }; - scale.ticks = function(m) { - return d3_scale_linearTicks(domain, m); - }; - scale.tickFormat = function(m, format) { - return d3_scale_linearTickFormat(domain, m, format); - }; - scale.nice = function(m) { - d3_scale_linearNice(domain, m); - return rescale(); - }; - scale.copy = function() { - return d3_scale_linear(domain, range, interpolate, clamp); - }; - return rescale(); - } - function d3_scale_linearRebind(scale, linear) { - return d3.rebind(scale, linear, "range", "rangeRound", "interpolate", "clamp"); - } - function d3_scale_linearNice(domain, m) { - return d3_scale_nice(domain, d3_scale_niceStep(d3_scale_linearTickRange(domain, m)[2])); - } - function d3_scale_linearTickRange(domain, m) { - if (m == null) m = 10; - var extent = d3_scaleExtent(domain), span = extent[1] - extent[0], step = Math.pow(10, Math.floor(Math.log(span / m) / Math.LN10)), err = m / span * step; - if (err <= .15) step *= 10; else if (err <= .35) step *= 5; else if (err <= .75) step *= 2; - extent[0] = Math.ceil(extent[0] / step) * step; - extent[1] = Math.floor(extent[1] / step) * step + step * .5; - extent[2] = step; - return extent; - } - function d3_scale_linearTicks(domain, m) { - return d3.range.apply(d3, d3_scale_linearTickRange(domain, m)); - } - function d3_scale_linearTickFormat(domain, m, format) { - var range = d3_scale_linearTickRange(domain, m); - return d3.format(format ? format.replace(d3_format_re, function(a, b, c, d, e, f, g, h, i, j) { - return [ b, c, d, e, f, g, h, i || "." + d3_scale_linearFormatPrecision(j, range), j ].join(""); - }) : ",." + d3_scale_linearPrecision(range[2]) + "f"); - } - var d3_scale_linearFormatSignificant = { - s: 1, - g: 1, - p: 1, - r: 1, - e: 1 - }; - function d3_scale_linearPrecision(value) { - return -Math.floor(Math.log(value) / Math.LN10 + .01); - } - function d3_scale_linearFormatPrecision(type, range) { - var p = d3_scale_linearPrecision(range[2]); - return type in d3_scale_linearFormatSignificant ? Math.abs(p - d3_scale_linearPrecision(Math.max(Math.abs(range[0]), Math.abs(range[1])))) + +(type !== "e") : p - (type === "%") * 2; - } - d3.scale.log = function() { - return d3_scale_log(d3.scale.linear().domain([ 0, 1 ]), 10, true, [ 1, 10 ]); - }; - function d3_scale_log(linear, base, positive, domain) { - function log(x) { - return (positive ? Math.log(x < 0 ? 0 : x) : -Math.log(x > 0 ? 0 : -x)) / Math.log(base); - } - function pow(x) { - return positive ? Math.pow(base, x) : -Math.pow(base, -x); - } - function scale(x) { - return linear(log(x)); - } - scale.invert = function(x) { - return pow(linear.invert(x)); - }; - scale.domain = function(x) { - if (!arguments.length) return domain; - positive = x[0] >= 0; - linear.domain((domain = x.map(Number)).map(log)); - return scale; - }; - scale.base = function(_) { - if (!arguments.length) return base; - base = +_; - linear.domain(domain.map(log)); - return scale; - }; - scale.nice = function() { - var niced = d3_scale_nice(domain.map(log), positive ? Math : d3_scale_logNiceNegative); - linear.domain(niced); - domain = niced.map(pow); - return scale; - }; - scale.ticks = function() { - var extent = d3_scaleExtent(domain), ticks = [], u = extent[0], v = extent[1], i = Math.floor(log(u)), j = Math.ceil(log(v)), n = base % 1 ? 2 : base; - if (isFinite(j - i)) { - if (positive) { - for (;i < j; i++) for (var k = 1; k < n; k++) ticks.push(pow(i) * k); - ticks.push(pow(i)); - } else { - ticks.push(pow(i)); - for (;i++ < j; ) for (var k = n - 1; k > 0; k--) ticks.push(pow(i) * k); - } - for (i = 0; ticks[i] < u; i++) {} - for (j = ticks.length; ticks[j - 1] > v; j--) {} - ticks = ticks.slice(i, j); - } - return ticks; - }; - scale.tickFormat = function(n, format) { - if (!arguments.length) return d3_scale_logFormat; - if (arguments.length < 2) format = d3_scale_logFormat; else if (typeof format !== "function") format = d3.format(format); - var k = Math.max(.1, n / scale.ticks().length), f = positive ? (e = 1e-12, Math.ceil) : (e = -1e-12, - Math.floor), e; - return function(d) { - return d / pow(f(log(d) + e)) <= k ? format(d) : ""; - }; - }; - scale.copy = function() { - return d3_scale_log(linear.copy(), base, positive, domain); - }; - return d3_scale_linearRebind(scale, linear); - } - var d3_scale_logFormat = d3.format(".0e"), d3_scale_logNiceNegative = { - floor: function(x) { - return -Math.ceil(-x); - }, - ceil: function(x) { - return -Math.floor(-x); - } - }; - d3.scale.pow = function() { - return d3_scale_pow(d3.scale.linear(), 1, [ 0, 1 ]); - }; - function d3_scale_pow(linear, exponent, domain) { - var powp = d3_scale_powPow(exponent), powb = d3_scale_powPow(1 / exponent); - function scale(x) { - return linear(powp(x)); - } - scale.invert = function(x) { - return powb(linear.invert(x)); - }; - scale.domain = function(x) { - if (!arguments.length) return domain; - linear.domain((domain = x.map(Number)).map(powp)); - return scale; - }; - scale.ticks = function(m) { - return d3_scale_linearTicks(domain, m); - }; - scale.tickFormat = function(m, format) { - return d3_scale_linearTickFormat(domain, m, format); - }; - scale.nice = function(m) { - return scale.domain(d3_scale_linearNice(domain, m)); - }; - scale.exponent = function(x) { - if (!arguments.length) return exponent; - powp = d3_scale_powPow(exponent = x); - powb = d3_scale_powPow(1 / exponent); - linear.domain(domain.map(powp)); - return scale; - }; - scale.copy = function() { - return d3_scale_pow(linear.copy(), exponent, domain); - }; - return d3_scale_linearRebind(scale, linear); - } - function d3_scale_powPow(e) { - return function(x) { - return x < 0 ? -Math.pow(-x, e) : Math.pow(x, e); - }; - } - d3.scale.sqrt = function() { - return d3.scale.pow().exponent(.5); - }; - d3.scale.ordinal = function() { - return d3_scale_ordinal([], { - t: "range", - a: [ [] ] - }); - }; - function d3_scale_ordinal(domain, ranger) { - var index, range, rangeBand; - function scale(x) { - return range[((index.get(x) || ranger.t === "range" && index.set(x, domain.push(x))) - 1) % range.length]; - } - function steps(start, step) { - return d3.range(domain.length).map(function(i) { - return start + step * i; - }); - } - scale.domain = function(x) { - if (!arguments.length) return domain; - domain = []; - index = new d3_Map(); - var i = -1, n = x.length, xi; - while (++i < n) if (!index.has(xi = x[i])) index.set(xi, domain.push(xi)); - return scale[ranger.t].apply(scale, ranger.a); - }; - scale.range = function(x) { - if (!arguments.length) return range; - range = x; - rangeBand = 0; - ranger = { - t: "range", - a: arguments - }; - return scale; - }; - scale.rangePoints = function(x, padding) { - if (arguments.length < 2) padding = 0; - var start = x[0], stop = x[1], step = (stop - start) / (Math.max(1, domain.length - 1) + padding); - range = steps(domain.length < 2 ? (start + stop) / 2 : start + step * padding / 2, step); - rangeBand = 0; - ranger = { - t: "rangePoints", - a: arguments - }; - return scale; - }; - scale.rangeBands = function(x, padding, outerPadding) { - if (arguments.length < 2) padding = 0; - if (arguments.length < 3) outerPadding = padding; - var reverse = x[1] < x[0], start = x[reverse - 0], stop = x[1 - reverse], step = (stop - start) / (domain.length - padding + 2 * outerPadding); - range = steps(start + step * outerPadding, step); - if (reverse) range.reverse(); - rangeBand = step * (1 - padding); - ranger = { - t: "rangeBands", - a: arguments - }; - return scale; - }; - scale.rangeRoundBands = function(x, padding, outerPadding) { - if (arguments.length < 2) padding = 0; - if (arguments.length < 3) outerPadding = padding; - var reverse = x[1] < x[0], start = x[reverse - 0], stop = x[1 - reverse], step = Math.floor((stop - start) / (domain.length - padding + 2 * outerPadding)), error = stop - start - (domain.length - padding) * step; - range = steps(start + Math.round(error / 2), step); - if (reverse) range.reverse(); - rangeBand = Math.round(step * (1 - padding)); - ranger = { - t: "rangeRoundBands", - a: arguments - }; - return scale; - }; - scale.rangeBand = function() { - return rangeBand; - }; - scale.rangeExtent = function() { - return d3_scaleExtent(ranger.a[0]); - }; - scale.copy = function() { - return d3_scale_ordinal(domain, ranger); - }; - return scale.domain(domain); - } - d3.scale.category10 = function() { - return d3.scale.ordinal().range(d3_category10); - }; - d3.scale.category20 = function() { - return d3.scale.ordinal().range(d3_category20); - }; - d3.scale.category20b = function() { - return d3.scale.ordinal().range(d3_category20b); - }; - d3.scale.category20c = function() { - return d3.scale.ordinal().range(d3_category20c); - }; - var d3_category10 = [ 2062260, 16744206, 2924588, 14034728, 9725885, 9197131, 14907330, 8355711, 12369186, 1556175 ].map(d3_rgbString); - var d3_category20 = [ 2062260, 11454440, 16744206, 16759672, 2924588, 10018698, 14034728, 16750742, 9725885, 12955861, 9197131, 12885140, 14907330, 16234194, 8355711, 13092807, 12369186, 14408589, 1556175, 10410725 ].map(d3_rgbString); - var d3_category20b = [ 3750777, 5395619, 7040719, 10264286, 6519097, 9216594, 11915115, 13556636, 9202993, 12426809, 15186514, 15190932, 8666169, 11356490, 14049643, 15177372, 8077683, 10834324, 13528509, 14589654 ].map(d3_rgbString); - var d3_category20c = [ 3244733, 7057110, 10406625, 13032431, 15095053, 16616764, 16625259, 16634018, 3253076, 7652470, 10607003, 13101504, 7695281, 10394312, 12369372, 14342891, 6513507, 9868950, 12434877, 14277081 ].map(d3_rgbString); - d3.scale.quantile = function() { - return d3_scale_quantile([], []); - }; - function d3_scale_quantile(domain, range) { - var thresholds; - function rescale() { - var k = 0, q = range.length; - thresholds = []; - while (++k < q) thresholds[k - 1] = d3.quantile(domain, k / q); - return scale; - } - function scale(x) { - if (!isNaN(x = +x)) return range[d3.bisect(thresholds, x)]; - } - scale.domain = function(x) { - if (!arguments.length) return domain; - domain = x.filter(function(d) { - return !isNaN(d); - }).sort(d3.ascending); - return rescale(); - }; - scale.range = function(x) { - if (!arguments.length) return range; - range = x; - return rescale(); - }; - scale.quantiles = function() { - return thresholds; - }; - scale.invertExtent = function(y) { - y = range.indexOf(y); - return y < 0 ? [ NaN, NaN ] : [ y > 0 ? thresholds[y - 1] : domain[0], y < thresholds.length ? thresholds[y] : domain[domain.length - 1] ]; - }; - scale.copy = function() { - return d3_scale_quantile(domain, range); - }; - return rescale(); - } - d3.scale.quantize = function() { - return d3_scale_quantize(0, 1, [ 0, 1 ]); - }; - function d3_scale_quantize(x0, x1, range) { - var kx, i; - function scale(x) { - return range[Math.max(0, Math.min(i, Math.floor(kx * (x - x0))))]; - } - function rescale() { - kx = range.length / (x1 - x0); - i = range.length - 1; - return scale; - } - scale.domain = function(x) { - if (!arguments.length) return [ x0, x1 ]; - x0 = +x[0]; - x1 = +x[x.length - 1]; - return rescale(); - }; - scale.range = function(x) { - if (!arguments.length) return range; - range = x; - return rescale(); - }; - scale.invertExtent = function(y) { - y = range.indexOf(y); - y = y < 0 ? NaN : y / kx + x0; - return [ y, y + 1 / kx ]; - }; - scale.copy = function() { - return d3_scale_quantize(x0, x1, range); - }; - return rescale(); - } - d3.scale.threshold = function() { - return d3_scale_threshold([ .5 ], [ 0, 1 ]); - }; - function d3_scale_threshold(domain, range) { - function scale(x) { - if (x <= x) return range[d3.bisect(domain, x)]; - } - scale.domain = function(_) { - if (!arguments.length) return domain; - domain = _; - return scale; - }; - scale.range = function(_) { - if (!arguments.length) return range; - range = _; - return scale; - }; - scale.invertExtent = function(y) { - y = range.indexOf(y); - return [ domain[y - 1], domain[y] ]; - }; - scale.copy = function() { - return d3_scale_threshold(domain, range); - }; - return scale; - } - d3.scale.identity = function() { - return d3_scale_identity([ 0, 1 ]); - }; - function d3_scale_identity(domain) { - function identity(x) { - return +x; - } - identity.invert = identity; - identity.domain = identity.range = function(x) { - if (!arguments.length) return domain; - domain = x.map(identity); - return identity; - }; - identity.ticks = function(m) { - return d3_scale_linearTicks(domain, m); - }; - identity.tickFormat = function(m, format) { - return d3_scale_linearTickFormat(domain, m, format); - }; - identity.copy = function() { - return d3_scale_identity(domain); - }; - return identity; - } - d3.svg = {}; - d3.svg.arc = function() { - var innerRadius = d3_svg_arcInnerRadius, outerRadius = d3_svg_arcOuterRadius, startAngle = d3_svg_arcStartAngle, endAngle = d3_svg_arcEndAngle; - function arc() { - var r0 = innerRadius.apply(this, arguments), r1 = outerRadius.apply(this, arguments), a0 = startAngle.apply(this, arguments) + d3_svg_arcOffset, a1 = endAngle.apply(this, arguments) + d3_svg_arcOffset, da = (a1 < a0 && (da = a0, - a0 = a1, a1 = da), a1 - a0), df = da < Ï€ ? "0" : "1", c0 = Math.cos(a0), s0 = Math.sin(a0), c1 = Math.cos(a1), s1 = Math.sin(a1); - return da >= d3_svg_arcMax ? r0 ? "M0," + r1 + "A" + r1 + "," + r1 + " 0 1,1 0," + -r1 + "A" + r1 + "," + r1 + " 0 1,1 0," + r1 + "M0," + r0 + "A" + r0 + "," + r0 + " 0 1,0 0," + -r0 + "A" + r0 + "," + r0 + " 0 1,0 0," + r0 + "Z" : "M0," + r1 + "A" + r1 + "," + r1 + " 0 1,1 0," + -r1 + "A" + r1 + "," + r1 + " 0 1,1 0," + r1 + "Z" : r0 ? "M" + r1 * c0 + "," + r1 * s0 + "A" + r1 + "," + r1 + " 0 " + df + ",1 " + r1 * c1 + "," + r1 * s1 + "L" + r0 * c1 + "," + r0 * s1 + "A" + r0 + "," + r0 + " 0 " + df + ",0 " + r0 * c0 + "," + r0 * s0 + "Z" : "M" + r1 * c0 + "," + r1 * s0 + "A" + r1 + "," + r1 + " 0 " + df + ",1 " + r1 * c1 + "," + r1 * s1 + "L0,0" + "Z"; - } - arc.innerRadius = function(v) { - if (!arguments.length) return innerRadius; - innerRadius = d3_functor(v); - return arc; - }; - arc.outerRadius = function(v) { - if (!arguments.length) return outerRadius; - outerRadius = d3_functor(v); - return arc; - }; - arc.startAngle = function(v) { - if (!arguments.length) return startAngle; - startAngle = d3_functor(v); - return arc; - }; - arc.endAngle = function(v) { - if (!arguments.length) return endAngle; - endAngle = d3_functor(v); - return arc; - }; - arc.centroid = function() { - var r = (innerRadius.apply(this, arguments) + outerRadius.apply(this, arguments)) / 2, a = (startAngle.apply(this, arguments) + endAngle.apply(this, arguments)) / 2 + d3_svg_arcOffset; - return [ Math.cos(a) * r, Math.sin(a) * r ]; - }; - return arc; - }; - var d3_svg_arcOffset = -halfÏ€, d3_svg_arcMax = Ï„ - ε; - function d3_svg_arcInnerRadius(d) { - return d.innerRadius; - } - function d3_svg_arcOuterRadius(d) { - return d.outerRadius; - } - function d3_svg_arcStartAngle(d) { - return d.startAngle; - } - function d3_svg_arcEndAngle(d) { - return d.endAngle; - } - function d3_svg_line(projection) { - var x = d3_geom_pointX, y = d3_geom_pointY, defined = d3_true, interpolate = d3_svg_lineLinear, interpolateKey = interpolate.key, tension = .7; - function line(data) { - var segments = [], points = [], i = -1, n = data.length, d, fx = d3_functor(x), fy = d3_functor(y); - function segment() { - segments.push("M", interpolate(projection(points), tension)); - } - while (++i < n) { - if (defined.call(this, d = data[i], i)) { - points.push([ +fx.call(this, d, i), +fy.call(this, d, i) ]); - } else if (points.length) { - segment(); - points = []; - } - } - if (points.length) segment(); - return segments.length ? segments.join("") : null; - } - line.x = function(_) { - if (!arguments.length) return x; - x = _; - return line; - }; - line.y = function(_) { - if (!arguments.length) return y; - y = _; - return line; - }; - line.defined = function(_) { - if (!arguments.length) return defined; - defined = _; - return line; - }; - line.interpolate = function(_) { - if (!arguments.length) return interpolateKey; - if (typeof _ === "function") interpolateKey = interpolate = _; else interpolateKey = (interpolate = d3_svg_lineInterpolators.get(_) || d3_svg_lineLinear).key; - return line; - }; - line.tension = function(_) { - if (!arguments.length) return tension; - tension = _; - return line; - }; - return line; - } - d3.svg.line = function() { - return d3_svg_line(d3_identity); - }; - var d3_svg_lineInterpolators = d3.map({ - linear: d3_svg_lineLinear, - "linear-closed": d3_svg_lineLinearClosed, - step: d3_svg_lineStep, - "step-before": d3_svg_lineStepBefore, - "step-after": d3_svg_lineStepAfter, - basis: d3_svg_lineBasis, - "basis-open": d3_svg_lineBasisOpen, - "basis-closed": d3_svg_lineBasisClosed, - bundle: d3_svg_lineBundle, - cardinal: d3_svg_lineCardinal, - "cardinal-open": d3_svg_lineCardinalOpen, - "cardinal-closed": d3_svg_lineCardinalClosed, - monotone: d3_svg_lineMonotone - }); - d3_svg_lineInterpolators.forEach(function(key, value) { - value.key = key; - value.closed = /-closed$/.test(key); - }); - function d3_svg_lineLinear(points) { - return points.join("L"); - } - function d3_svg_lineLinearClosed(points) { - return d3_svg_lineLinear(points) + "Z"; - } - function d3_svg_lineStep(points) { - var i = 0, n = points.length, p = points[0], path = [ p[0], ",", p[1] ]; - while (++i < n) path.push("H", (p[0] + (p = points[i])[0]) / 2, "V", p[1]); - if (n > 1) path.push("H", p[0]); - return path.join(""); - } - function d3_svg_lineStepBefore(points) { - var i = 0, n = points.length, p = points[0], path = [ p[0], ",", p[1] ]; - while (++i < n) path.push("V", (p = points[i])[1], "H", p[0]); - return path.join(""); - } - function d3_svg_lineStepAfter(points) { - var i = 0, n = points.length, p = points[0], path = [ p[0], ",", p[1] ]; - while (++i < n) path.push("H", (p = points[i])[0], "V", p[1]); - return path.join(""); - } - function d3_svg_lineCardinalOpen(points, tension) { - return points.length < 4 ? d3_svg_lineLinear(points) : points[1] + d3_svg_lineHermite(points.slice(1, points.length - 1), d3_svg_lineCardinalTangents(points, tension)); - } - function d3_svg_lineCardinalClosed(points, tension) { - return points.length < 3 ? d3_svg_lineLinear(points) : points[0] + d3_svg_lineHermite((points.push(points[0]), - points), d3_svg_lineCardinalTangents([ points[points.length - 2] ].concat(points, [ points[1] ]), tension)); - } - function d3_svg_lineCardinal(points, tension) { - return points.length < 3 ? d3_svg_lineLinear(points) : points[0] + d3_svg_lineHermite(points, d3_svg_lineCardinalTangents(points, tension)); - } - function d3_svg_lineHermite(points, tangents) { - if (tangents.length < 1 || points.length != tangents.length && points.length != tangents.length + 2) { - return d3_svg_lineLinear(points); - } - var quad = points.length != tangents.length, path = "", p0 = points[0], p = points[1], t0 = tangents[0], t = t0, pi = 1; - if (quad) { - path += "Q" + (p[0] - t0[0] * 2 / 3) + "," + (p[1] - t0[1] * 2 / 3) + "," + p[0] + "," + p[1]; - p0 = points[1]; - pi = 2; - } - if (tangents.length > 1) { - t = tangents[1]; - p = points[pi]; - pi++; - path += "C" + (p0[0] + t0[0]) + "," + (p0[1] + t0[1]) + "," + (p[0] - t[0]) + "," + (p[1] - t[1]) + "," + p[0] + "," + p[1]; - for (var i = 2; i < tangents.length; i++, pi++) { - p = points[pi]; - t = tangents[i]; - path += "S" + (p[0] - t[0]) + "," + (p[1] - t[1]) + "," + p[0] + "," + p[1]; - } - } - if (quad) { - var lp = points[pi]; - path += "Q" + (p[0] + t[0] * 2 / 3) + "," + (p[1] + t[1] * 2 / 3) + "," + lp[0] + "," + lp[1]; - } - return path; - } - function d3_svg_lineCardinalTangents(points, tension) { - var tangents = [], a = (1 - tension) / 2, p0, p1 = points[0], p2 = points[1], i = 1, n = points.length; - while (++i < n) { - p0 = p1; - p1 = p2; - p2 = points[i]; - tangents.push([ a * (p2[0] - p0[0]), a * (p2[1] - p0[1]) ]); - } - return tangents; - } - function d3_svg_lineBasis(points) { - if (points.length < 3) return d3_svg_lineLinear(points); - var i = 1, n = points.length, pi = points[0], x0 = pi[0], y0 = pi[1], px = [ x0, x0, x0, (pi = points[1])[0] ], py = [ y0, y0, y0, pi[1] ], path = [ x0, ",", y0, "L", d3_svg_lineDot4(d3_svg_lineBasisBezier3, px), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier3, py) ]; - points.push(points[n - 1]); - while (++i <= n) { - pi = points[i]; - px.shift(); - px.push(pi[0]); - py.shift(); - py.push(pi[1]); - d3_svg_lineBasisBezier(path, px, py); - } - points.pop(); - path.push("L", pi); - return path.join(""); - } - function d3_svg_lineBasisOpen(points) { - if (points.length < 4) return d3_svg_lineLinear(points); - var path = [], i = -1, n = points.length, pi, px = [ 0 ], py = [ 0 ]; - while (++i < 3) { - pi = points[i]; - px.push(pi[0]); - py.push(pi[1]); - } - path.push(d3_svg_lineDot4(d3_svg_lineBasisBezier3, px) + "," + d3_svg_lineDot4(d3_svg_lineBasisBezier3, py)); - --i; - while (++i < n) { - pi = points[i]; - px.shift(); - px.push(pi[0]); - py.shift(); - py.push(pi[1]); - d3_svg_lineBasisBezier(path, px, py); - } - return path.join(""); - } - function d3_svg_lineBasisClosed(points) { - var path, i = -1, n = points.length, m = n + 4, pi, px = [], py = []; - while (++i < 4) { - pi = points[i % n]; - px.push(pi[0]); - py.push(pi[1]); - } - path = [ d3_svg_lineDot4(d3_svg_lineBasisBezier3, px), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier3, py) ]; - --i; - while (++i < m) { - pi = points[i % n]; - px.shift(); - px.push(pi[0]); - py.shift(); - py.push(pi[1]); - d3_svg_lineBasisBezier(path, px, py); - } - return path.join(""); - } - function d3_svg_lineBundle(points, tension) { - var n = points.length - 1; - if (n) { - var x0 = points[0][0], y0 = points[0][1], dx = points[n][0] - x0, dy = points[n][1] - y0, i = -1, p, t; - while (++i <= n) { - p = points[i]; - t = i / n; - p[0] = tension * p[0] + (1 - tension) * (x0 + t * dx); - p[1] = tension * p[1] + (1 - tension) * (y0 + t * dy); - } - } - return d3_svg_lineBasis(points); - } - function d3_svg_lineDot4(a, b) { - return a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3]; - } - var d3_svg_lineBasisBezier1 = [ 0, 2 / 3, 1 / 3, 0 ], d3_svg_lineBasisBezier2 = [ 0, 1 / 3, 2 / 3, 0 ], d3_svg_lineBasisBezier3 = [ 0, 1 / 6, 2 / 3, 1 / 6 ]; - function d3_svg_lineBasisBezier(path, x, y) { - path.push("C", d3_svg_lineDot4(d3_svg_lineBasisBezier1, x), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier1, y), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier2, x), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier2, y), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier3, x), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier3, y)); - } - function d3_svg_lineSlope(p0, p1) { - return (p1[1] - p0[1]) / (p1[0] - p0[0]); - } - function d3_svg_lineFiniteDifferences(points) { - var i = 0, j = points.length - 1, m = [], p0 = points[0], p1 = points[1], d = m[0] = d3_svg_lineSlope(p0, p1); - while (++i < j) { - m[i] = (d + (d = d3_svg_lineSlope(p0 = p1, p1 = points[i + 1]))) / 2; - } - m[i] = d; - return m; - } - function d3_svg_lineMonotoneTangents(points) { - var tangents = [], d, a, b, s, m = d3_svg_lineFiniteDifferences(points), i = -1, j = points.length - 1; - while (++i < j) { - d = d3_svg_lineSlope(points[i], points[i + 1]); - if (abs(d) < ε) { - m[i] = m[i + 1] = 0; - } else { - a = m[i] / d; - b = m[i + 1] / d; - s = a * a + b * b; - if (s > 9) { - s = d * 3 / Math.sqrt(s); - m[i] = s * a; - m[i + 1] = s * b; - } - } - } - i = -1; - while (++i <= j) { - s = (points[Math.min(j, i + 1)][0] - points[Math.max(0, i - 1)][0]) / (6 * (1 + m[i] * m[i])); - tangents.push([ s || 0, m[i] * s || 0 ]); - } - return tangents; - } - function d3_svg_lineMonotone(points) { - return points.length < 3 ? d3_svg_lineLinear(points) : points[0] + d3_svg_lineHermite(points, d3_svg_lineMonotoneTangents(points)); - } - d3.svg.line.radial = function() { - var line = d3_svg_line(d3_svg_lineRadial); - line.radius = line.x, delete line.x; - line.angle = line.y, delete line.y; - return line; - }; - function d3_svg_lineRadial(points) { - var point, i = -1, n = points.length, r, a; - while (++i < n) { - point = points[i]; - r = point[0]; - a = point[1] + d3_svg_arcOffset; - point[0] = r * Math.cos(a); - point[1] = r * Math.sin(a); - } - return points; - } - function d3_svg_area(projection) { - var x0 = d3_geom_pointX, x1 = d3_geom_pointX, y0 = 0, y1 = d3_geom_pointY, defined = d3_true, interpolate = d3_svg_lineLinear, interpolateKey = interpolate.key, interpolateReverse = interpolate, L = "L", tension = .7; - function area(data) { - var segments = [], points0 = [], points1 = [], i = -1, n = data.length, d, fx0 = d3_functor(x0), fy0 = d3_functor(y0), fx1 = x0 === x1 ? function() { - return x; - } : d3_functor(x1), fy1 = y0 === y1 ? function() { - return y; - } : d3_functor(y1), x, y; - function segment() { - segments.push("M", interpolate(projection(points1), tension), L, interpolateReverse(projection(points0.reverse()), tension), "Z"); - } - while (++i < n) { - if (defined.call(this, d = data[i], i)) { - points0.push([ x = +fx0.call(this, d, i), y = +fy0.call(this, d, i) ]); - points1.push([ +fx1.call(this, d, i), +fy1.call(this, d, i) ]); - } else if (points0.length) { - segment(); - points0 = []; - points1 = []; - } - } - if (points0.length) segment(); - return segments.length ? segments.join("") : null; - } - area.x = function(_) { - if (!arguments.length) return x1; - x0 = x1 = _; - return area; - }; - area.x0 = function(_) { - if (!arguments.length) return x0; - x0 = _; - return area; - }; - area.x1 = function(_) { - if (!arguments.length) return x1; - x1 = _; - return area; - }; - area.y = function(_) { - if (!arguments.length) return y1; - y0 = y1 = _; - return area; - }; - area.y0 = function(_) { - if (!arguments.length) return y0; - y0 = _; - return area; - }; - area.y1 = function(_) { - if (!arguments.length) return y1; - y1 = _; - return area; - }; - area.defined = function(_) { - if (!arguments.length) return defined; - defined = _; - return area; - }; - area.interpolate = function(_) { - if (!arguments.length) return interpolateKey; - if (typeof _ === "function") interpolateKey = interpolate = _; else interpolateKey = (interpolate = d3_svg_lineInterpolators.get(_) || d3_svg_lineLinear).key; - interpolateReverse = interpolate.reverse || interpolate; - L = interpolate.closed ? "M" : "L"; - return area; - }; - area.tension = function(_) { - if (!arguments.length) return tension; - tension = _; - return area; - }; - return area; - } - d3_svg_lineStepBefore.reverse = d3_svg_lineStepAfter; - d3_svg_lineStepAfter.reverse = d3_svg_lineStepBefore; - d3.svg.area = function() { - return d3_svg_area(d3_identity); - }; - d3.svg.area.radial = function() { - var area = d3_svg_area(d3_svg_lineRadial); - area.radius = area.x, delete area.x; - area.innerRadius = area.x0, delete area.x0; - area.outerRadius = area.x1, delete area.x1; - area.angle = area.y, delete area.y; - area.startAngle = area.y0, delete area.y0; - area.endAngle = area.y1, delete area.y1; - return area; - }; - d3.svg.chord = function() { - var source = d3_source, target = d3_target, radius = d3_svg_chordRadius, startAngle = d3_svg_arcStartAngle, endAngle = d3_svg_arcEndAngle; - function chord(d, i) { - var s = subgroup(this, source, d, i), t = subgroup(this, target, d, i); - return "M" + s.p0 + arc(s.r, s.p1, s.a1 - s.a0) + (equals(s, t) ? curve(s.r, s.p1, s.r, s.p0) : curve(s.r, s.p1, t.r, t.p0) + arc(t.r, t.p1, t.a1 - t.a0) + curve(t.r, t.p1, s.r, s.p0)) + "Z"; - } - function subgroup(self, f, d, i) { - var subgroup = f.call(self, d, i), r = radius.call(self, subgroup, i), a0 = startAngle.call(self, subgroup, i) + d3_svg_arcOffset, a1 = endAngle.call(self, subgroup, i) + d3_svg_arcOffset; - return { - r: r, - a0: a0, - a1: a1, - p0: [ r * Math.cos(a0), r * Math.sin(a0) ], - p1: [ r * Math.cos(a1), r * Math.sin(a1) ] - }; - } - function equals(a, b) { - return a.a0 == b.a0 && a.a1 == b.a1; - } - function arc(r, p, a) { - return "A" + r + "," + r + " 0 " + +(a > Ï€) + ",1 " + p; - } - function curve(r0, p0, r1, p1) { - return "Q 0,0 " + p1; - } - chord.radius = function(v) { - if (!arguments.length) return radius; - radius = d3_functor(v); - return chord; - }; - chord.source = function(v) { - if (!arguments.length) return source; - source = d3_functor(v); - return chord; - }; - chord.target = function(v) { - if (!arguments.length) return target; - target = d3_functor(v); - return chord; - }; - chord.startAngle = function(v) { - if (!arguments.length) return startAngle; - startAngle = d3_functor(v); - return chord; - }; - chord.endAngle = function(v) { - if (!arguments.length) return endAngle; - endAngle = d3_functor(v); - return chord; - }; - return chord; - }; - function d3_svg_chordRadius(d) { - return d.radius; - } - d3.svg.diagonal = function() { - var source = d3_source, target = d3_target, projection = d3_svg_diagonalProjection; - function diagonal(d, i) { - var p0 = source.call(this, d, i), p3 = target.call(this, d, i), m = (p0.y + p3.y) / 2, p = [ p0, { - x: p0.x, - y: m - }, { - x: p3.x, - y: m - }, p3 ]; - p = p.map(projection); - return "M" + p[0] + "C" + p[1] + " " + p[2] + " " + p[3]; - } - diagonal.source = function(x) { - if (!arguments.length) return source; - source = d3_functor(x); - return diagonal; - }; - diagonal.target = function(x) { - if (!arguments.length) return target; - target = d3_functor(x); - return diagonal; - }; - diagonal.projection = function(x) { - if (!arguments.length) return projection; - projection = x; - return diagonal; - }; - return diagonal; - }; - function d3_svg_diagonalProjection(d) { - return [ d.x, d.y ]; - } - d3.svg.diagonal.radial = function() { - var diagonal = d3.svg.diagonal(), projection = d3_svg_diagonalProjection, projection_ = diagonal.projection; - diagonal.projection = function(x) { - return arguments.length ? projection_(d3_svg_diagonalRadialProjection(projection = x)) : projection; - }; - return diagonal; - }; - function d3_svg_diagonalRadialProjection(projection) { - return function() { - var d = projection.apply(this, arguments), r = d[0], a = d[1] + d3_svg_arcOffset; - return [ r * Math.cos(a), r * Math.sin(a) ]; - }; - } - d3.svg.symbol = function() { - var type = d3_svg_symbolType, size = d3_svg_symbolSize; - function symbol(d, i) { - return (d3_svg_symbols.get(type.call(this, d, i)) || d3_svg_symbolCircle)(size.call(this, d, i)); - } - symbol.type = function(x) { - if (!arguments.length) return type; - type = d3_functor(x); - return symbol; - }; - symbol.size = function(x) { - if (!arguments.length) return size; - size = d3_functor(x); - return symbol; - }; - return symbol; - }; - function d3_svg_symbolSize() { - return 64; - } - function d3_svg_symbolType() { - return "circle"; - } - function d3_svg_symbolCircle(size) { - var r = Math.sqrt(size / Ï€); - return "M0," + r + "A" + r + "," + r + " 0 1,1 0," + -r + "A" + r + "," + r + " 0 1,1 0," + r + "Z"; - } - var d3_svg_symbols = d3.map({ - circle: d3_svg_symbolCircle, - cross: function(size) { - var r = Math.sqrt(size / 5) / 2; - return "M" + -3 * r + "," + -r + "H" + -r + "V" + -3 * r + "H" + r + "V" + -r + "H" + 3 * r + "V" + r + "H" + r + "V" + 3 * r + "H" + -r + "V" + r + "H" + -3 * r + "Z"; - }, - diamond: function(size) { - var ry = Math.sqrt(size / (2 * d3_svg_symbolTan30)), rx = ry * d3_svg_symbolTan30; - return "M0," + -ry + "L" + rx + ",0" + " 0," + ry + " " + -rx + ",0" + "Z"; - }, - square: function(size) { - var r = Math.sqrt(size) / 2; - return "M" + -r + "," + -r + "L" + r + "," + -r + " " + r + "," + r + " " + -r + "," + r + "Z"; - }, - "triangle-down": function(size) { - var rx = Math.sqrt(size / d3_svg_symbolSqrt3), ry = rx * d3_svg_symbolSqrt3 / 2; - return "M0," + ry + "L" + rx + "," + -ry + " " + -rx + "," + -ry + "Z"; - }, - "triangle-up": function(size) { - var rx = Math.sqrt(size / d3_svg_symbolSqrt3), ry = rx * d3_svg_symbolSqrt3 / 2; - return "M0," + -ry + "L" + rx + "," + ry + " " + -rx + "," + ry + "Z"; - } - }); - d3.svg.symbolTypes = d3_svg_symbols.keys(); - var d3_svg_symbolSqrt3 = Math.sqrt(3), d3_svg_symbolTan30 = Math.tan(30 * d3_radians); - function d3_transition(groups, id) { - d3_subclass(groups, d3_transitionPrototype); - groups.id = id; - return groups; - } - var d3_transitionPrototype = [], d3_transitionId = 0, d3_transitionInheritId, d3_transitionInherit; - d3_transitionPrototype.call = d3_selectionPrototype.call; - d3_transitionPrototype.empty = d3_selectionPrototype.empty; - d3_transitionPrototype.node = d3_selectionPrototype.node; - d3_transitionPrototype.size = d3_selectionPrototype.size; - d3.transition = function(selection) { - return arguments.length ? d3_transitionInheritId ? selection.transition() : selection : d3_selectionRoot.transition(); - }; - d3.transition.prototype = d3_transitionPrototype; - d3_transitionPrototype.select = function(selector) { - var id = this.id, subgroups = [], subgroup, subnode, node; - selector = d3_selection_selector(selector); - for (var j = -1, m = this.length; ++j < m; ) { - subgroups.push(subgroup = []); - for (var group = this[j], i = -1, n = group.length; ++i < n; ) { - if ((node = group[i]) && (subnode = selector.call(node, node.__data__, i, j))) { - if ("__data__" in node) subnode.__data__ = node.__data__; - d3_transitionNode(subnode, i, id, node.__transition__[id]); - subgroup.push(subnode); - } else { - subgroup.push(null); - } - } - } - return d3_transition(subgroups, id); - }; - d3_transitionPrototype.selectAll = function(selector) { - var id = this.id, subgroups = [], subgroup, subnodes, node, subnode, transition; - selector = d3_selection_selectorAll(selector); - for (var j = -1, m = this.length; ++j < m; ) { - for (var group = this[j], i = -1, n = group.length; ++i < n; ) { - if (node = group[i]) { - transition = node.__transition__[id]; - subnodes = selector.call(node, node.__data__, i, j); - subgroups.push(subgroup = []); - for (var k = -1, o = subnodes.length; ++k < o; ) { - if (subnode = subnodes[k]) d3_transitionNode(subnode, k, id, transition); - subgroup.push(subnode); - } - } - } - } - return d3_transition(subgroups, id); - }; - d3_transitionPrototype.filter = function(filter) { - var subgroups = [], subgroup, group, node; - if (typeof filter !== "function") filter = d3_selection_filter(filter); - for (var j = 0, m = this.length; j < m; j++) { - subgroups.push(subgroup = []); - for (var group = this[j], i = 0, n = group.length; i < n; i++) { - if ((node = group[i]) && filter.call(node, node.__data__, i, j)) { - subgroup.push(node); - } - } - } - return d3_transition(subgroups, this.id); - }; - d3_transitionPrototype.tween = function(name, tween) { - var id = this.id; - if (arguments.length < 2) return this.node().__transition__[id].tween.get(name); - return d3_selection_each(this, tween == null ? function(node) { - node.__transition__[id].tween.remove(name); - } : function(node) { - node.__transition__[id].tween.set(name, tween); - }); - }; - function d3_transition_tween(groups, name, value, tween) { - var id = groups.id; - return d3_selection_each(groups, typeof value === "function" ? function(node, i, j) { - node.__transition__[id].tween.set(name, tween(value.call(node, node.__data__, i, j))); - } : (value = tween(value), function(node) { - node.__transition__[id].tween.set(name, value); - })); - } - d3_transitionPrototype.attr = function(nameNS, value) { - if (arguments.length < 2) { - for (value in nameNS) this.attr(value, nameNS[value]); - return this; - } - var interpolate = nameNS == "transform" ? d3_interpolateTransform : d3_interpolate, name = d3.ns.qualify(nameNS); - function attrNull() { - this.removeAttribute(name); - } - function attrNullNS() { - this.removeAttributeNS(name.space, name.local); - } - function attrTween(b) { - return b == null ? attrNull : (b += "", function() { - var a = this.getAttribute(name), i; - return a !== b && (i = interpolate(a, b), function(t) { - this.setAttribute(name, i(t)); - }); - }); - } - function attrTweenNS(b) { - return b == null ? attrNullNS : (b += "", function() { - var a = this.getAttributeNS(name.space, name.local), i; - return a !== b && (i = interpolate(a, b), function(t) { - this.setAttributeNS(name.space, name.local, i(t)); - }); - }); - } - return d3_transition_tween(this, "attr." + nameNS, value, name.local ? attrTweenNS : attrTween); - }; - d3_transitionPrototype.attrTween = function(nameNS, tween) { - var name = d3.ns.qualify(nameNS); - function attrTween(d, i) { - var f = tween.call(this, d, i, this.getAttribute(name)); - return f && function(t) { - this.setAttribute(name, f(t)); - }; - } - function attrTweenNS(d, i) { - var f = tween.call(this, d, i, this.getAttributeNS(name.space, name.local)); - return f && function(t) { - this.setAttributeNS(name.space, name.local, f(t)); - }; - } - return this.tween("attr." + nameNS, name.local ? attrTweenNS : attrTween); - }; - d3_transitionPrototype.style = function(name, value, priority) { - var n = arguments.length; - if (n < 3) { - if (typeof name !== "string") { - if (n < 2) value = ""; - for (priority in name) this.style(priority, name[priority], value); - return this; - } - priority = ""; - } - function styleNull() { - this.style.removeProperty(name); - } - function styleString(b) { - return b == null ? styleNull : (b += "", function() { - var a = d3_window.getComputedStyle(this, null).getPropertyValue(name), i; - return a !== b && (i = d3_interpolate(a, b), function(t) { - this.style.setProperty(name, i(t), priority); - }); - }); - } - return d3_transition_tween(this, "style." + name, value, styleString); - }; - d3_transitionPrototype.styleTween = function(name, tween, priority) { - if (arguments.length < 3) priority = ""; - function styleTween(d, i) { - var f = tween.call(this, d, i, d3_window.getComputedStyle(this, null).getPropertyValue(name)); - return f && function(t) { - this.style.setProperty(name, f(t), priority); - }; - } - return this.tween("style." + name, styleTween); - }; - d3_transitionPrototype.text = function(value) { - return d3_transition_tween(this, "text", value, d3_transition_text); - }; - function d3_transition_text(b) { - if (b == null) b = ""; - return function() { - this.textContent = b; - }; - } - d3_transitionPrototype.remove = function() { - return this.each("end.transition", function() { - var p; - if (this.__transition__.count < 2 && (p = this.parentNode)) p.removeChild(this); - }); - }; - d3_transitionPrototype.ease = function(value) { - var id = this.id; - if (arguments.length < 1) return this.node().__transition__[id].ease; - if (typeof value !== "function") value = d3.ease.apply(d3, arguments); - return d3_selection_each(this, function(node) { - node.__transition__[id].ease = value; - }); - }; - d3_transitionPrototype.delay = function(value) { - var id = this.id; - return d3_selection_each(this, typeof value === "function" ? function(node, i, j) { - node.__transition__[id].delay = +value.call(node, node.__data__, i, j); - } : (value = +value, function(node) { - node.__transition__[id].delay = value; - })); - }; - d3_transitionPrototype.duration = function(value) { - var id = this.id; - return d3_selection_each(this, typeof value === "function" ? function(node, i, j) { - node.__transition__[id].duration = Math.max(1, value.call(node, node.__data__, i, j)); - } : (value = Math.max(1, value), function(node) { - node.__transition__[id].duration = value; - })); - }; - d3_transitionPrototype.each = function(type, listener) { - var id = this.id; - if (arguments.length < 2) { - var inherit = d3_transitionInherit, inheritId = d3_transitionInheritId; - d3_transitionInheritId = id; - d3_selection_each(this, function(node, i, j) { - d3_transitionInherit = node.__transition__[id]; - type.call(node, node.__data__, i, j); - }); - d3_transitionInherit = inherit; - d3_transitionInheritId = inheritId; - } else { - d3_selection_each(this, function(node) { - var transition = node.__transition__[id]; - (transition.event || (transition.event = d3.dispatch("start", "end"))).on(type, listener); - }); - } - return this; - }; - d3_transitionPrototype.transition = function() { - var id0 = this.id, id1 = ++d3_transitionId, subgroups = [], subgroup, group, node, transition; - for (var j = 0, m = this.length; j < m; j++) { - subgroups.push(subgroup = []); - for (var group = this[j], i = 0, n = group.length; i < n; i++) { - if (node = group[i]) { - transition = Object.create(node.__transition__[id0]); - transition.delay += transition.duration; - d3_transitionNode(node, i, id1, transition); - } - subgroup.push(node); - } - } - return d3_transition(subgroups, id1); - }; - function d3_transitionNode(node, i, id, inherit) { - var lock = node.__transition__ || (node.__transition__ = { - active: 0, - count: 0 - }), transition = lock[id]; - if (!transition) { - var time = inherit.time; - transition = lock[id] = { - tween: new d3_Map(), - time: time, - ease: inherit.ease, - delay: inherit.delay, - duration: inherit.duration - }; - ++lock.count; - d3.timer(function(elapsed) { - var d = node.__data__, ease = transition.ease, delay = transition.delay, duration = transition.duration, timer = d3_timer_active, tweened = []; - timer.t = delay + time; - if (delay <= elapsed) return start(elapsed - delay); - timer.c = start; - function start(elapsed) { - if (lock.active > id) return stop(); - lock.active = id; - transition.event && transition.event.start.call(node, d, i); - transition.tween.forEach(function(key, value) { - if (value = value.call(node, d, i)) { - tweened.push(value); - } - }); - d3.timer(function() { - timer.c = tick(elapsed || 1) ? d3_true : tick; - return 1; - }, 0, time); - } - function tick(elapsed) { - if (lock.active !== id) return stop(); - var t = elapsed / duration, e = ease(t), n = tweened.length; - while (n > 0) { - tweened[--n].call(node, e); - } - if (t >= 1) { - transition.event && transition.event.end.call(node, d, i); - return stop(); - } - } - function stop() { - if (--lock.count) delete lock[id]; else delete node.__transition__; - return 1; - } - }, 0, time); - } - } - d3.svg.axis = function() { - var scale = d3.scale.linear(), orient = d3_svg_axisDefaultOrient, innerTickSize = 6, outerTickSize = 6, tickPadding = 3, tickArguments_ = [ 10 ], tickValues = null, tickFormat_; - function axis(g) { - g.each(function() { - var g = d3.select(this); - var scale0 = this.__chart__ || scale, scale1 = this.__chart__ = scale.copy(); - var ticks = tickValues == null ? scale1.ticks ? scale1.ticks.apply(scale1, tickArguments_) : scale1.domain() : tickValues, tickFormat = tickFormat_ == null ? scale1.tickFormat ? scale1.tickFormat.apply(scale1, tickArguments_) : d3_identity : tickFormat_, tick = g.selectAll(".tick").data(ticks, scale1), tickEnter = tick.enter().insert("g", ".domain").attr("class", "tick").style("opacity", ε), tickExit = d3.transition(tick.exit()).style("opacity", ε).remove(), tickUpdate = d3.transition(tick).style("opacity", 1), tickTransform; - var range = d3_scaleRange(scale1), path = g.selectAll(".domain").data([ 0 ]), pathUpdate = (path.enter().append("path").attr("class", "domain"), - d3.transition(path)); - tickEnter.append("line"); - tickEnter.append("text"); - var lineEnter = tickEnter.select("line"), lineUpdate = tickUpdate.select("line"), text = tick.select("text").text(tickFormat), textEnter = tickEnter.select("text"), textUpdate = tickUpdate.select("text"); - switch (orient) { - case "bottom": - { - tickTransform = d3_svg_axisX; - lineEnter.attr("y2", innerTickSize); - textEnter.attr("y", Math.max(innerTickSize, 0) + tickPadding); - lineUpdate.attr("x2", 0).attr("y2", innerTickSize); - textUpdate.attr("x", 0).attr("y", Math.max(innerTickSize, 0) + tickPadding); - text.attr("dy", ".71em").style("text-anchor", "middle"); - pathUpdate.attr("d", "M" + range[0] + "," + outerTickSize + "V0H" + range[1] + "V" + outerTickSize); - break; - } - - case "top": - { - tickTransform = d3_svg_axisX; - lineEnter.attr("y2", -innerTickSize); - textEnter.attr("y", -(Math.max(innerTickSize, 0) + tickPadding)); - lineUpdate.attr("x2", 0).attr("y2", -innerTickSize); - textUpdate.attr("x", 0).attr("y", -(Math.max(innerTickSize, 0) + tickPadding)); - text.attr("dy", "0em").style("text-anchor", "middle"); - pathUpdate.attr("d", "M" + range[0] + "," + -outerTickSize + "V0H" + range[1] + "V" + -outerTickSize); - break; - } - - case "left": - { - tickTransform = d3_svg_axisY; - lineEnter.attr("x2", -innerTickSize); - textEnter.attr("x", -(Math.max(innerTickSize, 0) + tickPadding)); - lineUpdate.attr("x2", -innerTickSize).attr("y2", 0); - textUpdate.attr("x", -(Math.max(innerTickSize, 0) + tickPadding)).attr("y", 0); - text.attr("dy", ".32em").style("text-anchor", "end"); - pathUpdate.attr("d", "M" + -outerTickSize + "," + range[0] + "H0V" + range[1] + "H" + -outerTickSize); - break; - } - - case "right": - { - tickTransform = d3_svg_axisY; - lineEnter.attr("x2", innerTickSize); - textEnter.attr("x", Math.max(innerTickSize, 0) + tickPadding); - lineUpdate.attr("x2", innerTickSize).attr("y2", 0); - textUpdate.attr("x", Math.max(innerTickSize, 0) + tickPadding).attr("y", 0); - text.attr("dy", ".32em").style("text-anchor", "start"); - pathUpdate.attr("d", "M" + outerTickSize + "," + range[0] + "H0V" + range[1] + "H" + outerTickSize); - break; - } - } - if (scale1.rangeBand) { - var x = scale1, dx = x.rangeBand() / 2; - scale0 = scale1 = function(d) { - return x(d) + dx; - }; - } else if (scale0.rangeBand) { - scale0 = scale1; - } else { - tickExit.call(tickTransform, scale1); - } - tickEnter.call(tickTransform, scale0); - tickUpdate.call(tickTransform, scale1); - }); - } - axis.scale = function(x) { - if (!arguments.length) return scale; - scale = x; - return axis; - }; - axis.orient = function(x) { - if (!arguments.length) return orient; - orient = x in d3_svg_axisOrients ? x + "" : d3_svg_axisDefaultOrient; - return axis; - }; - axis.ticks = function() { - if (!arguments.length) return tickArguments_; - tickArguments_ = arguments; - return axis; - }; - axis.tickValues = function(x) { - if (!arguments.length) return tickValues; - tickValues = x; - return axis; - }; - axis.tickFormat = function(x) { - if (!arguments.length) return tickFormat_; - tickFormat_ = x; - return axis; - }; - axis.tickSize = function(x) { - var n = arguments.length; - if (!n) return innerTickSize; - innerTickSize = +x; - outerTickSize = +arguments[n - 1]; - return axis; - }; - axis.innerTickSize = function(x) { - if (!arguments.length) return innerTickSize; - innerTickSize = +x; - return axis; - }; - axis.outerTickSize = function(x) { - if (!arguments.length) return outerTickSize; - outerTickSize = +x; - return axis; - }; - axis.tickPadding = function(x) { - if (!arguments.length) return tickPadding; - tickPadding = +x; - return axis; - }; - axis.tickSubdivide = function() { - return arguments.length && axis; - }; - return axis; - }; - var d3_svg_axisDefaultOrient = "bottom", d3_svg_axisOrients = { - top: 1, - right: 1, - bottom: 1, - left: 1 - }; - function d3_svg_axisX(selection, x) { - selection.attr("transform", function(d) { - return "translate(" + x(d) + ",0)"; - }); - } - function d3_svg_axisY(selection, y) { - selection.attr("transform", function(d) { - return "translate(0," + y(d) + ")"; - }); - } - d3.svg.brush = function() { - var event = d3_eventDispatch(brush, "brushstart", "brush", "brushend"), x = null, y = null, xExtent = [ 0, 0 ], yExtent = [ 0, 0 ], xExtentDomain, yExtentDomain, xClamp = true, yClamp = true, resizes = d3_svg_brushResizes[0]; - function brush(g) { - g.each(function() { - var g = d3.select(this).style("pointer-events", "all").style("-webkit-tap-highlight-color", "rgba(0,0,0,0)").on("mousedown.brush", brushstart).on("touchstart.brush", brushstart); - var background = g.selectAll(".background").data([ 0 ]); - background.enter().append("rect").attr("class", "background").style("visibility", "hidden").style("cursor", "crosshair"); - g.selectAll(".extent").data([ 0 ]).enter().append("rect").attr("class", "extent").style("cursor", "move"); - var resize = g.selectAll(".resize").data(resizes, d3_identity); - resize.exit().remove(); - resize.enter().append("g").attr("class", function(d) { - return "resize " + d; - }).style("cursor", function(d) { - return d3_svg_brushCursor[d]; - }).append("rect").attr("x", function(d) { - return /[ew]$/.test(d) ? -3 : null; - }).attr("y", function(d) { - return /^[ns]/.test(d) ? -3 : null; - }).attr("width", 6).attr("height", 6).style("visibility", "hidden"); - resize.style("display", brush.empty() ? "none" : null); - var gUpdate = d3.transition(g), backgroundUpdate = d3.transition(background), range; - if (x) { - range = d3_scaleRange(x); - backgroundUpdate.attr("x", range[0]).attr("width", range[1] - range[0]); - redrawX(gUpdate); - } - if (y) { - range = d3_scaleRange(y); - backgroundUpdate.attr("y", range[0]).attr("height", range[1] - range[0]); - redrawY(gUpdate); - } - redraw(gUpdate); - }); - } - brush.event = function(g) { - g.each(function() { - var event_ = event.of(this, arguments), extent1 = { - x: xExtent, - y: yExtent, - i: xExtentDomain, - j: yExtentDomain - }, extent0 = this.__chart__ || extent1; - this.__chart__ = extent1; - if (d3_transitionInheritId) { - d3.select(this).transition().each("start.brush", function() { - xExtentDomain = extent0.i; - yExtentDomain = extent0.j; - xExtent = extent0.x; - yExtent = extent0.y; - event_({ - type: "brushstart" - }); - }).tween("brush:brush", function() { - var xi = d3_interpolateArray(xExtent, extent1.x), yi = d3_interpolateArray(yExtent, extent1.y); - xExtentDomain = yExtentDomain = null; - return function(t) { - xExtent = extent1.x = xi(t); - yExtent = extent1.y = yi(t); - event_({ - type: "brush", - mode: "resize" - }); - }; - }).each("end.brush", function() { - xExtentDomain = extent1.i; - yExtentDomain = extent1.j; - event_({ - type: "brush", - mode: "resize" - }); - event_({ - type: "brushend" - }); - }); - } else { - event_({ - type: "brushstart" - }); - event_({ - type: "brush", - mode: "resize" - }); - event_({ - type: "brushend" - }); - } - }); - }; - function redraw(g) { - g.selectAll(".resize").attr("transform", function(d) { - return "translate(" + xExtent[+/e$/.test(d)] + "," + yExtent[+/^s/.test(d)] + ")"; - }); - } - function redrawX(g) { - g.select(".extent").attr("x", xExtent[0]); - g.selectAll(".extent,.n>rect,.s>rect").attr("width", xExtent[1] - xExtent[0]); - } - function redrawY(g) { - g.select(".extent").attr("y", yExtent[0]); - g.selectAll(".extent,.e>rect,.w>rect").attr("height", yExtent[1] - yExtent[0]); - } - function brushstart() { - var target = this, eventTarget = d3.select(d3.event.target), event_ = event.of(target, arguments), g = d3.select(target), resizing = eventTarget.datum(), resizingX = !/^(n|s)$/.test(resizing) && x, resizingY = !/^(e|w)$/.test(resizing) && y, dragging = eventTarget.classed("extent"), dragRestore = d3_event_dragSuppress(), center, origin = d3.mouse(target), offset; - var w = d3.select(d3_window).on("keydown.brush", keydown).on("keyup.brush", keyup); - if (d3.event.changedTouches) { - w.on("touchmove.brush", brushmove).on("touchend.brush", brushend); - } else { - w.on("mousemove.brush", brushmove).on("mouseup.brush", brushend); - } - g.interrupt().selectAll("*").interrupt(); - if (dragging) { - origin[0] = xExtent[0] - origin[0]; - origin[1] = yExtent[0] - origin[1]; - } else if (resizing) { - var ex = +/w$/.test(resizing), ey = +/^n/.test(resizing); - offset = [ xExtent[1 - ex] - origin[0], yExtent[1 - ey] - origin[1] ]; - origin[0] = xExtent[ex]; - origin[1] = yExtent[ey]; - } else if (d3.event.altKey) center = origin.slice(); - g.style("pointer-events", "none").selectAll(".resize").style("display", null); - d3.select("body").style("cursor", eventTarget.style("cursor")); - event_({ - type: "brushstart" - }); - brushmove(); - function keydown() { - if (d3.event.keyCode == 32) { - if (!dragging) { - center = null; - origin[0] -= xExtent[1]; - origin[1] -= yExtent[1]; - dragging = 2; - } - d3_eventPreventDefault(); - } - } - function keyup() { - if (d3.event.keyCode == 32 && dragging == 2) { - origin[0] += xExtent[1]; - origin[1] += yExtent[1]; - dragging = 0; - d3_eventPreventDefault(); - } - } - function brushmove() { - var point = d3.mouse(target), moved = false; - if (offset) { - point[0] += offset[0]; - point[1] += offset[1]; - } - if (!dragging) { - if (d3.event.altKey) { - if (!center) center = [ (xExtent[0] + xExtent[1]) / 2, (yExtent[0] + yExtent[1]) / 2 ]; - origin[0] = xExtent[+(point[0] < center[0])]; - origin[1] = yExtent[+(point[1] < center[1])]; - } else center = null; - } - if (resizingX && move1(point, x, 0)) { - redrawX(g); - moved = true; - } - if (resizingY && move1(point, y, 1)) { - redrawY(g); - moved = true; - } - if (moved) { - redraw(g); - event_({ - type: "brush", - mode: dragging ? "move" : "resize" - }); - } - } - function move1(point, scale, i) { - var range = d3_scaleRange(scale), r0 = range[0], r1 = range[1], position = origin[i], extent = i ? yExtent : xExtent, size = extent[1] - extent[0], min, max; - if (dragging) { - r0 -= position; - r1 -= size + position; - } - min = (i ? yClamp : xClamp) ? Math.max(r0, Math.min(r1, point[i])) : point[i]; - if (dragging) { - max = (min += position) + size; - } else { - if (center) position = Math.max(r0, Math.min(r1, 2 * center[i] - min)); - if (position < min) { - max = min; - min = position; - } else { - max = position; - } - } - if (extent[0] != min || extent[1] != max) { - if (i) yExtentDomain = null; else xExtentDomain = null; - extent[0] = min; - extent[1] = max; - return true; - } - } - function brushend() { - brushmove(); - g.style("pointer-events", "all").selectAll(".resize").style("display", brush.empty() ? "none" : null); - d3.select("body").style("cursor", null); - w.on("mousemove.brush", null).on("mouseup.brush", null).on("touchmove.brush", null).on("touchend.brush", null).on("keydown.brush", null).on("keyup.brush", null); - dragRestore(); - event_({ - type: "brushend" - }); - } - } - brush.x = function(z) { - if (!arguments.length) return x; - x = z; - resizes = d3_svg_brushResizes[!x << 1 | !y]; - return brush; - }; - brush.y = function(z) { - if (!arguments.length) return y; - y = z; - resizes = d3_svg_brushResizes[!x << 1 | !y]; - return brush; - }; - brush.clamp = function(z) { - if (!arguments.length) return x && y ? [ xClamp, yClamp ] : x ? xClamp : y ? yClamp : null; - if (x && y) xClamp = !!z[0], yClamp = !!z[1]; else if (x) xClamp = !!z; else if (y) yClamp = !!z; - return brush; - }; - brush.extent = function(z) { - var x0, x1, y0, y1, t; - if (!arguments.length) { - if (x) { - if (xExtentDomain) { - x0 = xExtentDomain[0], x1 = xExtentDomain[1]; - } else { - x0 = xExtent[0], x1 = xExtent[1]; - if (x.invert) x0 = x.invert(x0), x1 = x.invert(x1); - if (x1 < x0) t = x0, x0 = x1, x1 = t; - } - } - if (y) { - if (yExtentDomain) { - y0 = yExtentDomain[0], y1 = yExtentDomain[1]; - } else { - y0 = yExtent[0], y1 = yExtent[1]; - if (y.invert) y0 = y.invert(y0), y1 = y.invert(y1); - if (y1 < y0) t = y0, y0 = y1, y1 = t; - } - } - return x && y ? [ [ x0, y0 ], [ x1, y1 ] ] : x ? [ x0, x1 ] : y && [ y0, y1 ]; - } - if (x) { - x0 = z[0], x1 = z[1]; - if (y) x0 = x0[0], x1 = x1[0]; - xExtentDomain = [ x0, x1 ]; - if (x.invert) x0 = x(x0), x1 = x(x1); - if (x1 < x0) t = x0, x0 = x1, x1 = t; - if (x0 != xExtent[0] || x1 != xExtent[1]) xExtent = [ x0, x1 ]; - } - if (y) { - y0 = z[0], y1 = z[1]; - if (x) y0 = y0[1], y1 = y1[1]; - yExtentDomain = [ y0, y1 ]; - if (y.invert) y0 = y(y0), y1 = y(y1); - if (y1 < y0) t = y0, y0 = y1, y1 = t; - if (y0 != yExtent[0] || y1 != yExtent[1]) yExtent = [ y0, y1 ]; - } - return brush; - }; - brush.clear = function() { - if (!brush.empty()) { - xExtent = [ 0, 0 ], yExtent = [ 0, 0 ]; - xExtentDomain = yExtentDomain = null; - } - return brush; - }; - brush.empty = function() { - return !!x && xExtent[0] == xExtent[1] || !!y && yExtent[0] == yExtent[1]; - }; - return d3.rebind(brush, event, "on"); - }; - var d3_svg_brushCursor = { - n: "ns-resize", - e: "ew-resize", - s: "ns-resize", - w: "ew-resize", - nw: "nwse-resize", - ne: "nesw-resize", - se: "nwse-resize", - sw: "nesw-resize" - }; - var d3_svg_brushResizes = [ [ "n", "e", "s", "w", "nw", "ne", "se", "sw" ], [ "e", "w" ], [ "n", "s" ], [] ]; - var d3_time_format = d3_time.format = d3_locale_enUS.timeFormat; - var d3_time_formatUtc = d3_time_format.utc; - var d3_time_formatIso = d3_time_formatUtc("%Y-%m-%dT%H:%M:%S.%LZ"); - d3_time_format.iso = Date.prototype.toISOString && +new Date("2000-01-01T00:00:00.000Z") ? d3_time_formatIsoNative : d3_time_formatIso; - function d3_time_formatIsoNative(date) { - return date.toISOString(); - } - d3_time_formatIsoNative.parse = function(string) { - var date = new Date(string); - return isNaN(date) ? null : date; - }; - d3_time_formatIsoNative.toString = d3_time_formatIso.toString; - d3_time.second = d3_time_interval(function(date) { - return new d3_date(Math.floor(date / 1e3) * 1e3); - }, function(date, offset) { - date.setTime(date.getTime() + Math.floor(offset) * 1e3); - }, function(date) { - return date.getSeconds(); - }); - d3_time.seconds = d3_time.second.range; - d3_time.seconds.utc = d3_time.second.utc.range; - d3_time.minute = d3_time_interval(function(date) { - return new d3_date(Math.floor(date / 6e4) * 6e4); - }, function(date, offset) { - date.setTime(date.getTime() + Math.floor(offset) * 6e4); - }, function(date) { - return date.getMinutes(); - }); - d3_time.minutes = d3_time.minute.range; - d3_time.minutes.utc = d3_time.minute.utc.range; - d3_time.hour = d3_time_interval(function(date) { - var timezone = date.getTimezoneOffset() / 60; - return new d3_date((Math.floor(date / 36e5 - timezone) + timezone) * 36e5); - }, function(date, offset) { - date.setTime(date.getTime() + Math.floor(offset) * 36e5); - }, function(date) { - return date.getHours(); - }); - d3_time.hours = d3_time.hour.range; - d3_time.hours.utc = d3_time.hour.utc.range; - d3_time.month = d3_time_interval(function(date) { - date = d3_time.day(date); - date.setDate(1); - return date; - }, function(date, offset) { - date.setMonth(date.getMonth() + offset); - }, function(date) { - return date.getMonth(); - }); - d3_time.months = d3_time.month.range; - d3_time.months.utc = d3_time.month.utc.range; - function d3_time_scale(linear, methods, format) { - function scale(x) { - return linear(x); - } - scale.invert = function(x) { - return d3_time_scaleDate(linear.invert(x)); - }; - scale.domain = function(x) { - if (!arguments.length) return linear.domain().map(d3_time_scaleDate); - linear.domain(x); - return scale; - }; - function tickMethod(extent, count) { - var span = extent[1] - extent[0], target = span / count, i = d3.bisect(d3_time_scaleSteps, target); - return i == d3_time_scaleSteps.length ? [ methods.year, d3_scale_linearTickRange(extent.map(function(d) { - return d / 31536e6; - }), count)[2] ] : !i ? [ d3_time_scaleMilliseconds, d3_scale_linearTickRange(extent, count)[2] ] : methods[target / d3_time_scaleSteps[i - 1] < d3_time_scaleSteps[i] / target ? i - 1 : i]; - } - scale.nice = function(interval, skip) { - var domain = scale.domain(), extent = d3_scaleExtent(domain), method = interval == null ? tickMethod(extent, 10) : typeof interval === "number" && tickMethod(extent, interval); - if (method) interval = method[0], skip = method[1]; - function skipped(date) { - return !isNaN(date) && !interval.range(date, d3_time_scaleDate(+date + 1), skip).length; - } - return scale.domain(d3_scale_nice(domain, skip > 1 ? { - floor: function(date) { - while (skipped(date = interval.floor(date))) date = d3_time_scaleDate(date - 1); - return date; - }, - ceil: function(date) { - while (skipped(date = interval.ceil(date))) date = d3_time_scaleDate(+date + 1); - return date; - } - } : interval)); - }; - scale.ticks = function(interval, skip) { - var extent = d3_scaleExtent(scale.domain()), method = interval == null ? tickMethod(extent, 10) : typeof interval === "number" ? tickMethod(extent, interval) : !interval.range && [ { - range: interval - }, skip ]; - if (method) interval = method[0], skip = method[1]; - return interval.range(extent[0], d3_time_scaleDate(+extent[1] + 1), skip < 1 ? 1 : skip); - }; - scale.tickFormat = function() { - return format; - }; - scale.copy = function() { - return d3_time_scale(linear.copy(), methods, format); - }; - return d3_scale_linearRebind(scale, linear); - } - function d3_time_scaleDate(t) { - return new Date(t); - } - var d3_time_scaleSteps = [ 1e3, 5e3, 15e3, 3e4, 6e4, 3e5, 9e5, 18e5, 36e5, 108e5, 216e5, 432e5, 864e5, 1728e5, 6048e5, 2592e6, 7776e6, 31536e6 ]; - var d3_time_scaleLocalMethods = [ [ d3_time.second, 1 ], [ d3_time.second, 5 ], [ d3_time.second, 15 ], [ d3_time.second, 30 ], [ d3_time.minute, 1 ], [ d3_time.minute, 5 ], [ d3_time.minute, 15 ], [ d3_time.minute, 30 ], [ d3_time.hour, 1 ], [ d3_time.hour, 3 ], [ d3_time.hour, 6 ], [ d3_time.hour, 12 ], [ d3_time.day, 1 ], [ d3_time.day, 2 ], [ d3_time.week, 1 ], [ d3_time.month, 1 ], [ d3_time.month, 3 ], [ d3_time.year, 1 ] ]; - var d3_time_scaleLocalFormat = d3_time_format.multi([ [ ".%L", function(d) { - return d.getMilliseconds(); - } ], [ ":%S", function(d) { - return d.getSeconds(); - } ], [ "%I:%M", function(d) { - return d.getMinutes(); - } ], [ "%I %p", function(d) { - return d.getHours(); - } ], [ "%a %d", function(d) { - return d.getDay() && d.getDate() != 1; - } ], [ "%b %d", function(d) { - return d.getDate() != 1; - } ], [ "%B", function(d) { - return d.getMonth(); - } ], [ "%Y", d3_true ] ]); - var d3_time_scaleMilliseconds = { - range: function(start, stop, step) { - return d3.range(+start, +stop, step).map(d3_time_scaleDate); - }, - floor: d3_identity, - ceil: d3_identity - }; - d3_time_scaleLocalMethods.year = d3_time.year; - d3_time.scale = function() { - return d3_time_scale(d3.scale.linear(), d3_time_scaleLocalMethods, d3_time_scaleLocalFormat); - }; - var d3_time_scaleUtcMethods = d3_time_scaleLocalMethods.map(function(m) { - return [ m[0].utc, m[1] ]; - }); - var d3_time_scaleUtcFormat = d3_time_formatUtc.multi([ [ ".%L", function(d) { - return d.getUTCMilliseconds(); - } ], [ ":%S", function(d) { - return d.getUTCSeconds(); - } ], [ "%I:%M", function(d) { - return d.getUTCMinutes(); - } ], [ "%I %p", function(d) { - return d.getUTCHours(); - } ], [ "%a %d", function(d) { - return d.getUTCDay() && d.getUTCDate() != 1; - } ], [ "%b %d", function(d) { - return d.getUTCDate() != 1; - } ], [ "%B", function(d) { - return d.getUTCMonth(); - } ], [ "%Y", d3_true ] ]); - d3_time_scaleUtcMethods.year = d3_time.year.utc; - d3_time.scale.utc = function() { - return d3_time_scale(d3.scale.linear(), d3_time_scaleUtcMethods, d3_time_scaleUtcFormat); - }; - d3.text = d3_xhrType(function(request) { - return request.responseText; - }); - d3.json = function(url, callback) { - return d3_xhr(url, "application/json", d3_json, callback); - }; - function d3_json(request) { - return JSON.parse(request.responseText); - } - d3.html = function(url, callback) { - return d3_xhr(url, "text/html", d3_html, callback); - }; - function d3_html(request) { - var range = d3_document.createRange(); - range.selectNode(d3_document.body); - return range.createContextualFragment(request.responseText); - } - d3.xml = d3_xhrType(function(request) { - return request.responseXML; - }); - if (typeof define === "function" && define.amd) { - define(d3); - } else if (typeof module === "object" && module.exports) { - module.exports = d3; - } else { - this.d3 = d3; - } -}(); \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/plots/libs/d3.v3.min.js b/ThirdParty/Ert/devel/share/gui/plots/libs/d3.v3.min.js deleted file mode 100644 index 8cfc9ef3f4..0000000000 --- a/ThirdParty/Ert/devel/share/gui/plots/libs/d3.v3.min.js +++ /dev/null @@ -1,5 +0,0 @@ -!function(){function n(n){return null!=n&&!isNaN(n)}function t(n){return n.length}function e(n){for(var t=1;n*t%1;)t*=10;return t}function r(n,t){try{for(var e in t)Object.defineProperty(n.prototype,e,{value:t[e],enumerable:!1})}catch(r){n.prototype=t}}function u(){}function i(n){return aa+n in this}function o(n){return n=aa+n,n in this&&delete this[n]}function a(){var n=[];return this.forEach(function(t){n.push(t)}),n}function c(){var n=0;for(var t in this)t.charCodeAt(0)===ca&&++n;return n}function s(){for(var n in this)if(n.charCodeAt(0)===ca)return!1;return!0}function l(){}function f(n,t,e){return function(){var r=e.apply(t,arguments);return r===t?n:r}}function h(n,t){if(t in n)return t;t=t.charAt(0).toUpperCase()+t.substring(1);for(var e=0,r=sa.length;r>e;++e){var u=sa[e]+t;if(u in n)return u}}function g(){}function p(){}function v(n){function t(){for(var t,r=e,u=-1,i=r.length;++u<i;)(t=r[u].on)&&t.apply(this,arguments);return n}var e=[],r=new u;return t.on=function(t,u){var i,o=r.get(t);return arguments.length<2?o&&o.on:(o&&(o.on=null,e=e.slice(0,i=e.indexOf(o)).concat(e.slice(i+1)),r.remove(t)),u&&e.push(r.set(t,{on:u})),n)},t}function d(){Xo.event.preventDefault()}function m(){for(var n,t=Xo.event;n=t.sourceEvent;)t=n;return t}function y(n){for(var t=new p,e=0,r=arguments.length;++e<r;)t[arguments[e]]=v(t);return t.of=function(e,r){return function(u){try{var i=u.sourceEvent=Xo.event;u.target=n,Xo.event=u,t[u.type].apply(e,r)}finally{Xo.event=i}}},t}function x(n){return fa(n,da),n}function M(n){return"function"==typeof n?n:function(){return ha(n,this)}}function _(n){return"function"==typeof n?n:function(){return ga(n,this)}}function b(n,t){function e(){this.removeAttribute(n)}function r(){this.removeAttributeNS(n.space,n.local)}function u(){this.setAttribute(n,t)}function i(){this.setAttributeNS(n.space,n.local,t)}function o(){var e=t.apply(this,arguments);null==e?this.removeAttribute(n):this.setAttribute(n,e)}function a(){var e=t.apply(this,arguments);null==e?this.removeAttributeNS(n.space,n.local):this.setAttributeNS(n.space,n.local,e)}return n=Xo.ns.qualify(n),null==t?n.local?r:e:"function"==typeof t?n.local?a:o:n.local?i:u}function w(n){return n.trim().replace(/\s+/g," ")}function S(n){return new RegExp("(?:^|\\s+)"+Xo.requote(n)+"(?:\\s+|$)","g")}function k(n){return n.trim().split(/^|\s+/)}function E(n,t){function e(){for(var e=-1;++e<u;)n[e](this,t)}function r(){for(var e=-1,r=t.apply(this,arguments);++e<u;)n[e](this,r)}n=k(n).map(A);var u=n.length;return"function"==typeof t?r:e}function A(n){var t=S(n);return function(e,r){if(u=e.classList)return r?u.add(n):u.remove(n);var u=e.getAttribute("class")||"";r?(t.lastIndex=0,t.test(u)||e.setAttribute("class",w(u+" "+n))):e.setAttribute("class",w(u.replace(t," ")))}}function C(n,t,e){function r(){this.style.removeProperty(n)}function u(){this.style.setProperty(n,t,e)}function i(){var r=t.apply(this,arguments);null==r?this.style.removeProperty(n):this.style.setProperty(n,r,e)}return null==t?r:"function"==typeof t?i:u}function N(n,t){function e(){delete this[n]}function r(){this[n]=t}function u(){var e=t.apply(this,arguments);null==e?delete this[n]:this[n]=e}return null==t?e:"function"==typeof t?u:r}function L(n){return"function"==typeof n?n:(n=Xo.ns.qualify(n)).local?function(){return this.ownerDocument.createElementNS(n.space,n.local)}:function(){return this.ownerDocument.createElementNS(this.namespaceURI,n)}}function z(n){return{__data__:n}}function q(n){return function(){return va(this,n)}}function T(n){return arguments.length||(n=Xo.ascending),function(t,e){return t&&e?n(t.__data__,e.__data__):!t-!e}}function R(n,t){for(var e=0,r=n.length;r>e;e++)for(var u,i=n[e],o=0,a=i.length;a>o;o++)(u=i[o])&&t(u,o,e);return n}function D(n){return fa(n,ya),n}function P(n){var t,e;return function(r,u,i){var o,a=n[i].update,c=a.length;for(i!=e&&(e=i,t=0),u>=t&&(t=u+1);!(o=a[t])&&++t<c;);return o}}function U(){var n=this.__transition__;n&&++n.active}function j(n,t,e){function r(){var t=this[o];t&&(this.removeEventListener(n,t,t.$),delete this[o])}function u(){var u=c(t,Bo(arguments));r.call(this),this.addEventListener(n,this[o]=u,u.$=e),u._=t}function i(){var t,e=new RegExp("^__on([^.]+)"+Xo.requote(n)+"$");for(var r in this)if(t=r.match(e)){var u=this[r];this.removeEventListener(t[1],u,u.$),delete this[r]}}var o="__on"+n,a=n.indexOf("."),c=H;a>0&&(n=n.substring(0,a));var s=Ma.get(n);return s&&(n=s,c=F),a?t?u:r:t?g:i}function H(n,t){return function(e){var r=Xo.event;Xo.event=e,t[0]=this.__data__;try{n.apply(this,t)}finally{Xo.event=r}}}function F(n,t){var e=H(n,t);return function(n){var t=this,r=n.relatedTarget;r&&(r===t||8&r.compareDocumentPosition(t))||e.call(t,n)}}function O(){var n=".dragsuppress-"+ ++ba,t="click"+n,e=Xo.select(Go).on("touchmove"+n,d).on("dragstart"+n,d).on("selectstart"+n,d);if(_a){var r=Jo.style,u=r[_a];r[_a]="none"}return function(i){function o(){e.on(t,null)}e.on(n,null),_a&&(r[_a]=u),i&&(e.on(t,function(){d(),o()},!0),setTimeout(o,0))}}function Y(n,t){t.changedTouches&&(t=t.changedTouches[0]);var e=n.ownerSVGElement||n;if(e.createSVGPoint){var r=e.createSVGPoint();if(0>wa&&(Go.scrollX||Go.scrollY)){e=Xo.select("body").append("svg").style({position:"absolute",top:0,left:0,margin:0,padding:0,border:"none"},"important");var u=e[0][0].getScreenCTM();wa=!(u.f||u.e),e.remove()}return wa?(r.x=t.pageX,r.y=t.pageY):(r.x=t.clientX,r.y=t.clientY),r=r.matrixTransform(n.getScreenCTM().inverse()),[r.x,r.y]}var i=n.getBoundingClientRect();return[t.clientX-i.left-n.clientLeft,t.clientY-i.top-n.clientTop]}function I(n){return n>0?1:0>n?-1:0}function Z(n,t,e){return(t[0]-n[0])*(e[1]-n[1])-(t[1]-n[1])*(e[0]-n[0])}function V(n){return n>1?0:-1>n?Sa:Math.acos(n)}function X(n){return n>1?Ea:-1>n?-Ea:Math.asin(n)}function $(n){return((n=Math.exp(n))-1/n)/2}function B(n){return((n=Math.exp(n))+1/n)/2}function W(n){return((n=Math.exp(2*n))-1)/(n+1)}function J(n){return(n=Math.sin(n/2))*n}function G(){}function K(n,t,e){return new Q(n,t,e)}function Q(n,t,e){this.h=n,this.s=t,this.l=e}function nt(n,t,e){function r(n){return n>360?n-=360:0>n&&(n+=360),60>n?i+(o-i)*n/60:180>n?o:240>n?i+(o-i)*(240-n)/60:i}function u(n){return Math.round(255*r(n))}var i,o;return n=isNaN(n)?0:(n%=360)<0?n+360:n,t=isNaN(t)?0:0>t?0:t>1?1:t,e=0>e?0:e>1?1:e,o=.5>=e?e*(1+t):e+t-e*t,i=2*e-o,gt(u(n+120),u(n),u(n-120))}function tt(n,t,e){return new et(n,t,e)}function et(n,t,e){this.h=n,this.c=t,this.l=e}function rt(n,t,e){return isNaN(n)&&(n=0),isNaN(t)&&(t=0),ut(e,Math.cos(n*=Na)*t,Math.sin(n)*t)}function ut(n,t,e){return new it(n,t,e)}function it(n,t,e){this.l=n,this.a=t,this.b=e}function ot(n,t,e){var r=(n+16)/116,u=r+t/500,i=r-e/200;return u=ct(u)*Fa,r=ct(r)*Oa,i=ct(i)*Ya,gt(lt(3.2404542*u-1.5371385*r-.4985314*i),lt(-.969266*u+1.8760108*r+.041556*i),lt(.0556434*u-.2040259*r+1.0572252*i))}function at(n,t,e){return n>0?tt(Math.atan2(e,t)*La,Math.sqrt(t*t+e*e),n):tt(0/0,0/0,n)}function ct(n){return n>.206893034?n*n*n:(n-4/29)/7.787037}function st(n){return n>.008856?Math.pow(n,1/3):7.787037*n+4/29}function lt(n){return Math.round(255*(.00304>=n?12.92*n:1.055*Math.pow(n,1/2.4)-.055))}function ft(n){return gt(n>>16,255&n>>8,255&n)}function ht(n){return ft(n)+""}function gt(n,t,e){return new pt(n,t,e)}function pt(n,t,e){this.r=n,this.g=t,this.b=e}function vt(n){return 16>n?"0"+Math.max(0,n).toString(16):Math.min(255,n).toString(16)}function dt(n,t,e){var r,u,i,o=0,a=0,c=0;if(r=/([a-z]+)\((.*)\)/i.exec(n))switch(u=r[2].split(","),r[1]){case"hsl":return e(parseFloat(u[0]),parseFloat(u[1])/100,parseFloat(u[2])/100);case"rgb":return t(Mt(u[0]),Mt(u[1]),Mt(u[2]))}return(i=Va.get(n))?t(i.r,i.g,i.b):(null!=n&&"#"===n.charAt(0)&&(4===n.length?(o=n.charAt(1),o+=o,a=n.charAt(2),a+=a,c=n.charAt(3),c+=c):7===n.length&&(o=n.substring(1,3),a=n.substring(3,5),c=n.substring(5,7)),o=parseInt(o,16),a=parseInt(a,16),c=parseInt(c,16)),t(o,a,c))}function mt(n,t,e){var r,u,i=Math.min(n/=255,t/=255,e/=255),o=Math.max(n,t,e),a=o-i,c=(o+i)/2;return a?(u=.5>c?a/(o+i):a/(2-o-i),r=n==o?(t-e)/a+(e>t?6:0):t==o?(e-n)/a+2:(n-t)/a+4,r*=60):(r=0/0,u=c>0&&1>c?0:r),K(r,u,c)}function yt(n,t,e){n=xt(n),t=xt(t),e=xt(e);var r=st((.4124564*n+.3575761*t+.1804375*e)/Fa),u=st((.2126729*n+.7151522*t+.072175*e)/Oa),i=st((.0193339*n+.119192*t+.9503041*e)/Ya);return ut(116*u-16,500*(r-u),200*(u-i))}function xt(n){return(n/=255)<=.04045?n/12.92:Math.pow((n+.055)/1.055,2.4)}function Mt(n){var t=parseFloat(n);return"%"===n.charAt(n.length-1)?Math.round(2.55*t):t}function _t(n){return"function"==typeof n?n:function(){return n}}function bt(n){return n}function wt(n){return function(t,e,r){return 2===arguments.length&&"function"==typeof e&&(r=e,e=null),St(t,e,n,r)}}function St(n,t,e,r){function u(){var n,t=c.status;if(!t&&c.responseText||t>=200&&300>t||304===t){try{n=e.call(i,c)}catch(r){return o.error.call(i,r),void 0}o.load.call(i,n)}else o.error.call(i,c)}var i={},o=Xo.dispatch("beforesend","progress","load","error"),a={},c=new XMLHttpRequest,s=null;return!Go.XDomainRequest||"withCredentials"in c||!/^(http(s)?:)?\/\//.test(n)||(c=new XDomainRequest),"onload"in c?c.onload=c.onerror=u:c.onreadystatechange=function(){c.readyState>3&&u()},c.onprogress=function(n){var t=Xo.event;Xo.event=n;try{o.progress.call(i,c)}finally{Xo.event=t}},i.header=function(n,t){return n=(n+"").toLowerCase(),arguments.length<2?a[n]:(null==t?delete a[n]:a[n]=t+"",i)},i.mimeType=function(n){return arguments.length?(t=null==n?null:n+"",i):t},i.responseType=function(n){return arguments.length?(s=n,i):s},i.response=function(n){return e=n,i},["get","post"].forEach(function(n){i[n]=function(){return i.send.apply(i,[n].concat(Bo(arguments)))}}),i.send=function(e,r,u){if(2===arguments.length&&"function"==typeof r&&(u=r,r=null),c.open(e,n,!0),null==t||"accept"in a||(a.accept=t+",*/*"),c.setRequestHeader)for(var l in a)c.setRequestHeader(l,a[l]);return null!=t&&c.overrideMimeType&&c.overrideMimeType(t),null!=s&&(c.responseType=s),null!=u&&i.on("error",u).on("load",function(n){u(null,n)}),o.beforesend.call(i,c),c.send(null==r?null:r),i},i.abort=function(){return c.abort(),i},Xo.rebind(i,o,"on"),null==r?i:i.get(kt(r))}function kt(n){return 1===n.length?function(t,e){n(null==t?e:null)}:n}function Et(){var n=At(),t=Ct()-n;t>24?(isFinite(t)&&(clearTimeout(Wa),Wa=setTimeout(Et,t)),Ba=0):(Ba=1,Ga(Et))}function At(){var n=Date.now();for(Ja=Xa;Ja;)n>=Ja.t&&(Ja.f=Ja.c(n-Ja.t)),Ja=Ja.n;return n}function Ct(){for(var n,t=Xa,e=1/0;t;)t.f?t=n?n.n=t.n:Xa=t.n:(t.t<e&&(e=t.t),t=(n=t).n);return $a=n,e}function Nt(n,t){return t-(n?Math.ceil(Math.log(n)/Math.LN10):1)}function Lt(n,t){var e=Math.pow(10,3*oa(8-t));return{scale:t>8?function(n){return n/e}:function(n){return n*e},symbol:n}}function zt(n){var t=n.decimal,e=n.thousands,r=n.grouping,u=n.currency,i=r?function(n){for(var t=n.length,u=[],i=0,o=r[0];t>0&&o>0;)u.push(n.substring(t-=o,t+o)),o=r[i=(i+1)%r.length];return u.reverse().join(e)}:bt;return function(n){var e=Qa.exec(n),r=e[1]||" ",o=e[2]||">",a=e[3]||"",c=e[4]||"",s=e[5],l=+e[6],f=e[7],h=e[8],g=e[9],p=1,v="",d="",m=!1;switch(h&&(h=+h.substring(1)),(s||"0"===r&&"="===o)&&(s=r="0",o="=",f&&(l-=Math.floor((l-1)/4))),g){case"n":f=!0,g="g";break;case"%":p=100,d="%",g="f";break;case"p":p=100,d="%",g="r";break;case"b":case"o":case"x":case"X":"#"===c&&(v="0"+g.toLowerCase());case"c":case"d":m=!0,h=0;break;case"s":p=-1,g="r"}"$"===c&&(v=u[0],d=u[1]),"r"!=g||h||(g="g"),null!=h&&("g"==g?h=Math.max(1,Math.min(21,h)):("e"==g||"f"==g)&&(h=Math.max(0,Math.min(20,h)))),g=nc.get(g)||qt;var y=s&&f;return function(n){if(m&&n%1)return"";var e=0>n||0===n&&0>1/n?(n=-n,"-"):a;if(0>p){var u=Xo.formatPrefix(n,h);n=u.scale(n),d=u.symbol}else n*=p;n=g(n,h);var c=n.lastIndexOf("."),x=0>c?n:n.substring(0,c),M=0>c?"":t+n.substring(c+1);!s&&f&&(x=i(x));var _=v.length+x.length+M.length+(y?0:e.length),b=l>_?new Array(_=l-_+1).join(r):"";return y&&(x=i(b+x)),e+=v,n=x+M,("<"===o?e+n+b:">"===o?b+e+n:"^"===o?b.substring(0,_>>=1)+e+n+b.substring(_):e+(y?n:b+n))+d}}}function qt(n){return n+""}function Tt(){this._=new Date(arguments.length>1?Date.UTC.apply(this,arguments):arguments[0])}function Rt(n,t,e){function r(t){var e=n(t),r=i(e,1);return r-t>t-e?e:r}function u(e){return t(e=n(new ec(e-1)),1),e}function i(n,e){return t(n=new ec(+n),e),n}function o(n,r,i){var o=u(n),a=[];if(i>1)for(;r>o;)e(o)%i||a.push(new Date(+o)),t(o,1);else for(;r>o;)a.push(new Date(+o)),t(o,1);return a}function a(n,t,e){try{ec=Tt;var r=new Tt;return r._=n,o(r,t,e)}finally{ec=Date}}n.floor=n,n.round=r,n.ceil=u,n.offset=i,n.range=o;var c=n.utc=Dt(n);return c.floor=c,c.round=Dt(r),c.ceil=Dt(u),c.offset=Dt(i),c.range=a,n}function Dt(n){return function(t,e){try{ec=Tt;var r=new Tt;return r._=t,n(r,e)._}finally{ec=Date}}}function Pt(n){function t(n){function t(t){for(var e,u,i,o=[],a=-1,c=0;++a<r;)37===n.charCodeAt(a)&&(o.push(n.substring(c,a)),null!=(u=uc[e=n.charAt(++a)])&&(e=n.charAt(++a)),(i=C[e])&&(e=i(t,null==u?"e"===e?" ":"0":u)),o.push(e),c=a+1);return o.push(n.substring(c,a)),o.join("")}var r=n.length;return t.parse=function(t){var r={y:1900,m:0,d:1,H:0,M:0,S:0,L:0,Z:null},u=e(r,n,t,0);if(u!=t.length)return null;"p"in r&&(r.H=r.H%12+12*r.p);var i=null!=r.Z&&ec!==Tt,o=new(i?Tt:ec);return"j"in r?o.setFullYear(r.y,0,r.j):"w"in r&&("W"in r||"U"in r)?(o.setFullYear(r.y,0,1),o.setFullYear(r.y,0,"W"in r?(r.w+6)%7+7*r.W-(o.getDay()+5)%7:r.w+7*r.U-(o.getDay()+6)%7)):o.setFullYear(r.y,r.m,r.d),o.setHours(r.H+Math.floor(r.Z/100),r.M+r.Z%100,r.S,r.L),i?o._:o},t.toString=function(){return n},t}function e(n,t,e,r){for(var u,i,o,a=0,c=t.length,s=e.length;c>a;){if(r>=s)return-1;if(u=t.charCodeAt(a++),37===u){if(o=t.charAt(a++),i=N[o in uc?t.charAt(a++):o],!i||(r=i(n,e,r))<0)return-1}else if(u!=e.charCodeAt(r++))return-1}return r}function r(n,t,e){b.lastIndex=0;var r=b.exec(t.substring(e));return r?(n.w=w.get(r[0].toLowerCase()),e+r[0].length):-1}function u(n,t,e){M.lastIndex=0;var r=M.exec(t.substring(e));return r?(n.w=_.get(r[0].toLowerCase()),e+r[0].length):-1}function i(n,t,e){E.lastIndex=0;var r=E.exec(t.substring(e));return r?(n.m=A.get(r[0].toLowerCase()),e+r[0].length):-1}function o(n,t,e){S.lastIndex=0;var r=S.exec(t.substring(e));return r?(n.m=k.get(r[0].toLowerCase()),e+r[0].length):-1}function a(n,t,r){return e(n,C.c.toString(),t,r)}function c(n,t,r){return e(n,C.x.toString(),t,r)}function s(n,t,r){return e(n,C.X.toString(),t,r)}function l(n,t,e){var r=x.get(t.substring(e,e+=2).toLowerCase());return null==r?-1:(n.p=r,e)}var f=n.dateTime,h=n.date,g=n.time,p=n.periods,v=n.days,d=n.shortDays,m=n.months,y=n.shortMonths;t.utc=function(n){function e(n){try{ec=Tt;var t=new ec;return t._=n,r(t)}finally{ec=Date}}var r=t(n);return e.parse=function(n){try{ec=Tt;var t=r.parse(n);return t&&t._}finally{ec=Date}},e.toString=r.toString,e},t.multi=t.utc.multi=ee;var x=Xo.map(),M=jt(v),_=Ht(v),b=jt(d),w=Ht(d),S=jt(m),k=Ht(m),E=jt(y),A=Ht(y);p.forEach(function(n,t){x.set(n.toLowerCase(),t)});var C={a:function(n){return d[n.getDay()]},A:function(n){return v[n.getDay()]},b:function(n){return y[n.getMonth()]},B:function(n){return m[n.getMonth()]},c:t(f),d:function(n,t){return Ut(n.getDate(),t,2)},e:function(n,t){return Ut(n.getDate(),t,2)},H:function(n,t){return Ut(n.getHours(),t,2)},I:function(n,t){return Ut(n.getHours()%12||12,t,2)},j:function(n,t){return Ut(1+tc.dayOfYear(n),t,3)},L:function(n,t){return Ut(n.getMilliseconds(),t,3)},m:function(n,t){return Ut(n.getMonth()+1,t,2)},M:function(n,t){return Ut(n.getMinutes(),t,2)},p:function(n){return p[+(n.getHours()>=12)]},S:function(n,t){return Ut(n.getSeconds(),t,2)},U:function(n,t){return Ut(tc.sundayOfYear(n),t,2)},w:function(n){return n.getDay()},W:function(n,t){return Ut(tc.mondayOfYear(n),t,2)},x:t(h),X:t(g),y:function(n,t){return Ut(n.getFullYear()%100,t,2)},Y:function(n,t){return Ut(n.getFullYear()%1e4,t,4)},Z:ne,"%":function(){return"%"}},N={a:r,A:u,b:i,B:o,c:a,d:Bt,e:Bt,H:Jt,I:Jt,j:Wt,L:Qt,m:$t,M:Gt,p:l,S:Kt,U:Ot,w:Ft,W:Yt,x:c,X:s,y:Zt,Y:It,Z:Vt,"%":te};return t}function Ut(n,t,e){var r=0>n?"-":"",u=(r?-n:n)+"",i=u.length;return r+(e>i?new Array(e-i+1).join(t)+u:u)}function jt(n){return new RegExp("^(?:"+n.map(Xo.requote).join("|")+")","i")}function Ht(n){for(var t=new u,e=-1,r=n.length;++e<r;)t.set(n[e].toLowerCase(),e);return t}function Ft(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+1));return r?(n.w=+r[0],e+r[0].length):-1}function Ot(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e));return r?(n.U=+r[0],e+r[0].length):-1}function Yt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e));return r?(n.W=+r[0],e+r[0].length):-1}function It(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+4));return r?(n.y=+r[0],e+r[0].length):-1}function Zt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+2));return r?(n.y=Xt(+r[0]),e+r[0].length):-1}function Vt(n,t,e){return/^[+-]\d{4}$/.test(t=t.substring(e,e+5))?(n.Z=+t,e+5):-1}function Xt(n){return n+(n>68?1900:2e3)}function $t(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+2));return r?(n.m=r[0]-1,e+r[0].length):-1}function Bt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+2));return r?(n.d=+r[0],e+r[0].length):-1}function Wt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+3));return r?(n.j=+r[0],e+r[0].length):-1}function Jt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+2));return r?(n.H=+r[0],e+r[0].length):-1}function Gt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+2));return r?(n.M=+r[0],e+r[0].length):-1}function Kt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+2));return r?(n.S=+r[0],e+r[0].length):-1}function Qt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+3));return r?(n.L=+r[0],e+r[0].length):-1}function ne(n){var t=n.getTimezoneOffset(),e=t>0?"-":"+",r=~~(oa(t)/60),u=oa(t)%60;return e+Ut(r,"0",2)+Ut(u,"0",2)}function te(n,t,e){oc.lastIndex=0;var r=oc.exec(t.substring(e,e+1));return r?e+r[0].length:-1}function ee(n){for(var t=n.length,e=-1;++e<t;)n[e][0]=this(n[e][0]);return function(t){for(var e=0,r=n[e];!r[1](t);)r=n[++e];return r[0](t)}}function re(){}function ue(n,t,e){var r=e.s=n+t,u=r-n,i=r-u;e.t=n-i+(t-u)}function ie(n,t){n&&lc.hasOwnProperty(n.type)&&lc[n.type](n,t)}function oe(n,t,e){var r,u=-1,i=n.length-e;for(t.lineStart();++u<i;)r=n[u],t.point(r[0],r[1],r[2]);t.lineEnd()}function ae(n,t){var e=-1,r=n.length;for(t.polygonStart();++e<r;)oe(n[e],t,1);t.polygonEnd()}function ce(){function n(n,t){n*=Na,t=t*Na/2+Sa/4;var e=n-r,o=Math.cos(t),a=Math.sin(t),c=i*a,s=u*o+c*Math.cos(e),l=c*Math.sin(e);hc.add(Math.atan2(l,s)),r=n,u=o,i=a}var t,e,r,u,i;gc.point=function(o,a){gc.point=n,r=(t=o)*Na,u=Math.cos(a=(e=a)*Na/2+Sa/4),i=Math.sin(a)},gc.lineEnd=function(){n(t,e)}}function se(n){var t=n[0],e=n[1],r=Math.cos(e);return[r*Math.cos(t),r*Math.sin(t),Math.sin(e)]}function le(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]}function fe(n,t){return[n[1]*t[2]-n[2]*t[1],n[2]*t[0]-n[0]*t[2],n[0]*t[1]-n[1]*t[0]]}function he(n,t){n[0]+=t[0],n[1]+=t[1],n[2]+=t[2]}function ge(n,t){return[n[0]*t,n[1]*t,n[2]*t]}function pe(n){var t=Math.sqrt(n[0]*n[0]+n[1]*n[1]+n[2]*n[2]);n[0]/=t,n[1]/=t,n[2]/=t}function ve(n){return[Math.atan2(n[1],n[0]),X(n[2])]}function de(n,t){return oa(n[0]-t[0])<Aa&&oa(n[1]-t[1])<Aa}function me(n,t){n*=Na;var e=Math.cos(t*=Na);ye(e*Math.cos(n),e*Math.sin(n),Math.sin(t))}function ye(n,t,e){++pc,dc+=(n-dc)/pc,mc+=(t-mc)/pc,yc+=(e-yc)/pc}function xe(){function n(n,u){n*=Na;var i=Math.cos(u*=Na),o=i*Math.cos(n),a=i*Math.sin(n),c=Math.sin(u),s=Math.atan2(Math.sqrt((s=e*c-r*a)*s+(s=r*o-t*c)*s+(s=t*a-e*o)*s),t*o+e*a+r*c);vc+=s,xc+=s*(t+(t=o)),Mc+=s*(e+(e=a)),_c+=s*(r+(r=c)),ye(t,e,r)}var t,e,r;kc.point=function(u,i){u*=Na;var o=Math.cos(i*=Na);t=o*Math.cos(u),e=o*Math.sin(u),r=Math.sin(i),kc.point=n,ye(t,e,r)}}function Me(){kc.point=me}function _e(){function n(n,t){n*=Na;var e=Math.cos(t*=Na),o=e*Math.cos(n),a=e*Math.sin(n),c=Math.sin(t),s=u*c-i*a,l=i*o-r*c,f=r*a-u*o,h=Math.sqrt(s*s+l*l+f*f),g=r*o+u*a+i*c,p=h&&-V(g)/h,v=Math.atan2(h,g);bc+=p*s,wc+=p*l,Sc+=p*f,vc+=v,xc+=v*(r+(r=o)),Mc+=v*(u+(u=a)),_c+=v*(i+(i=c)),ye(r,u,i)}var t,e,r,u,i;kc.point=function(o,a){t=o,e=a,kc.point=n,o*=Na;var c=Math.cos(a*=Na);r=c*Math.cos(o),u=c*Math.sin(o),i=Math.sin(a),ye(r,u,i)},kc.lineEnd=function(){n(t,e),kc.lineEnd=Me,kc.point=me}}function be(){return!0}function we(n,t,e,r,u){var i=[],o=[];if(n.forEach(function(n){if(!((t=n.length-1)<=0)){var t,e=n[0],r=n[t];if(de(e,r)){u.lineStart();for(var a=0;t>a;++a)u.point((e=n[a])[0],e[1]);return u.lineEnd(),void 0}var c=new ke(e,n,null,!0),s=new ke(e,null,c,!1);c.o=s,i.push(c),o.push(s),c=new ke(r,n,null,!1),s=new ke(r,null,c,!0),c.o=s,i.push(c),o.push(s)}}),o.sort(t),Se(i),Se(o),i.length){for(var a=0,c=e,s=o.length;s>a;++a)o[a].e=c=!c;for(var l,f,h=i[0];;){for(var g=h,p=!0;g.v;)if((g=g.n)===h)return;l=g.z,u.lineStart();do{if(g.v=g.o.v=!0,g.e){if(p)for(var a=0,s=l.length;s>a;++a)u.point((f=l[a])[0],f[1]);else r(g.x,g.n.x,1,u);g=g.n}else{if(p){l=g.p.z;for(var a=l.length-1;a>=0;--a)u.point((f=l[a])[0],f[1])}else r(g.x,g.p.x,-1,u);g=g.p}g=g.o,l=g.z,p=!p}while(!g.v);u.lineEnd()}}}function Se(n){if(t=n.length){for(var t,e,r=0,u=n[0];++r<t;)u.n=e=n[r],e.p=u,u=e;u.n=e=n[0],e.p=u}}function ke(n,t,e,r){this.x=n,this.z=t,this.o=e,this.e=r,this.v=!1,this.n=this.p=null}function Ee(n,t,e,r){return function(u,i){function o(t,e){var r=u(t,e);n(t=r[0],e=r[1])&&i.point(t,e)}function a(n,t){var e=u(n,t);d.point(e[0],e[1])}function c(){y.point=a,d.lineStart()}function s(){y.point=o,d.lineEnd()}function l(n,t){v.push([n,t]);var e=u(n,t);M.point(e[0],e[1])}function f(){M.lineStart(),v=[]}function h(){l(v[0][0],v[0][1]),M.lineEnd();var n,t=M.clean(),e=x.buffer(),r=e.length;if(v.pop(),p.push(v),v=null,r){if(1&t){n=e[0];var u,r=n.length-1,o=-1;for(i.lineStart();++o<r;)i.point((u=n[o])[0],u[1]);return i.lineEnd(),void 0}r>1&&2&t&&e.push(e.pop().concat(e.shift())),g.push(e.filter(Ae))}}var g,p,v,d=t(i),m=u.invert(r[0],r[1]),y={point:o,lineStart:c,lineEnd:s,polygonStart:function(){y.point=l,y.lineStart=f,y.lineEnd=h,g=[],p=[],i.polygonStart()},polygonEnd:function(){y.point=o,y.lineStart=c,y.lineEnd=s,g=Xo.merge(g);var n=Le(m,p);g.length?we(g,Ne,n,e,i):n&&(i.lineStart(),e(null,null,1,i),i.lineEnd()),i.polygonEnd(),g=p=null},sphere:function(){i.polygonStart(),i.lineStart(),e(null,null,1,i),i.lineEnd(),i.polygonEnd()}},x=Ce(),M=t(x);return y}}function Ae(n){return n.length>1}function Ce(){var n,t=[];return{lineStart:function(){t.push(n=[])},point:function(t,e){n.push([t,e])},lineEnd:g,buffer:function(){var e=t;return t=[],n=null,e},rejoin:function(){t.length>1&&t.push(t.pop().concat(t.shift()))}}}function Ne(n,t){return((n=n.x)[0]<0?n[1]-Ea-Aa:Ea-n[1])-((t=t.x)[0]<0?t[1]-Ea-Aa:Ea-t[1])}function Le(n,t){var e=n[0],r=n[1],u=[Math.sin(e),-Math.cos(e),0],i=0,o=0;hc.reset();for(var a=0,c=t.length;c>a;++a){var s=t[a],l=s.length;if(l)for(var f=s[0],h=f[0],g=f[1]/2+Sa/4,p=Math.sin(g),v=Math.cos(g),d=1;;){d===l&&(d=0),n=s[d];var m=n[0],y=n[1]/2+Sa/4,x=Math.sin(y),M=Math.cos(y),_=m-h,b=oa(_)>Sa,w=p*x;if(hc.add(Math.atan2(w*Math.sin(_),v*M+w*Math.cos(_))),i+=b?_+(_>=0?ka:-ka):_,b^h>=e^m>=e){var S=fe(se(f),se(n));pe(S);var k=fe(u,S);pe(k);var E=(b^_>=0?-1:1)*X(k[2]);(r>E||r===E&&(S[0]||S[1]))&&(o+=b^_>=0?1:-1)}if(!d++)break;h=m,p=x,v=M,f=n}}return(-Aa>i||Aa>i&&0>hc)^1&o}function ze(n){var t,e=0/0,r=0/0,u=0/0;return{lineStart:function(){n.lineStart(),t=1},point:function(i,o){var a=i>0?Sa:-Sa,c=oa(i-e);oa(c-Sa)<Aa?(n.point(e,r=(r+o)/2>0?Ea:-Ea),n.point(u,r),n.lineEnd(),n.lineStart(),n.point(a,r),n.point(i,r),t=0):u!==a&&c>=Sa&&(oa(e-u)<Aa&&(e-=u*Aa),oa(i-a)<Aa&&(i-=a*Aa),r=qe(e,r,i,o),n.point(u,r),n.lineEnd(),n.lineStart(),n.point(a,r),t=0),n.point(e=i,r=o),u=a},lineEnd:function(){n.lineEnd(),e=r=0/0},clean:function(){return 2-t}}}function qe(n,t,e,r){var u,i,o=Math.sin(n-e);return oa(o)>Aa?Math.atan((Math.sin(t)*(i=Math.cos(r))*Math.sin(e)-Math.sin(r)*(u=Math.cos(t))*Math.sin(n))/(u*i*o)):(t+r)/2}function Te(n,t,e,r){var u;if(null==n)u=e*Ea,r.point(-Sa,u),r.point(0,u),r.point(Sa,u),r.point(Sa,0),r.point(Sa,-u),r.point(0,-u),r.point(-Sa,-u),r.point(-Sa,0),r.point(-Sa,u);else if(oa(n[0]-t[0])>Aa){var i=n[0]<t[0]?Sa:-Sa;u=e*i/2,r.point(-i,u),r.point(0,u),r.point(i,u)}else r.point(t[0],t[1])}function Re(n){function t(n,t){return Math.cos(n)*Math.cos(t)>i}function e(n){var e,i,c,s,l;return{lineStart:function(){s=c=!1,l=1},point:function(f,h){var g,p=[f,h],v=t(f,h),d=o?v?0:u(f,h):v?u(f+(0>f?Sa:-Sa),h):0;if(!e&&(s=c=v)&&n.lineStart(),v!==c&&(g=r(e,p),(de(e,g)||de(p,g))&&(p[0]+=Aa,p[1]+=Aa,v=t(p[0],p[1]))),v!==c)l=0,v?(n.lineStart(),g=r(p,e),n.point(g[0],g[1])):(g=r(e,p),n.point(g[0],g[1]),n.lineEnd()),e=g;else if(a&&e&&o^v){var m;d&i||!(m=r(p,e,!0))||(l=0,o?(n.lineStart(),n.point(m[0][0],m[0][1]),n.point(m[1][0],m[1][1]),n.lineEnd()):(n.point(m[1][0],m[1][1]),n.lineEnd(),n.lineStart(),n.point(m[0][0],m[0][1])))}!v||e&&de(e,p)||n.point(p[0],p[1]),e=p,c=v,i=d},lineEnd:function(){c&&n.lineEnd(),e=null},clean:function(){return l|(s&&c)<<1}}}function r(n,t,e){var r=se(n),u=se(t),o=[1,0,0],a=fe(r,u),c=le(a,a),s=a[0],l=c-s*s;if(!l)return!e&&n;var f=i*c/l,h=-i*s/l,g=fe(o,a),p=ge(o,f),v=ge(a,h);he(p,v);var d=g,m=le(p,d),y=le(d,d),x=m*m-y*(le(p,p)-1);if(!(0>x)){var M=Math.sqrt(x),_=ge(d,(-m-M)/y);if(he(_,p),_=ve(_),!e)return _;var b,w=n[0],S=t[0],k=n[1],E=t[1];w>S&&(b=w,w=S,S=b);var A=S-w,C=oa(A-Sa)<Aa,N=C||Aa>A;if(!C&&k>E&&(b=k,k=E,E=b),N?C?k+E>0^_[1]<(oa(_[0]-w)<Aa?k:E):k<=_[1]&&_[1]<=E:A>Sa^(w<=_[0]&&_[0]<=S)){var L=ge(d,(-m+M)/y);return he(L,p),[_,ve(L)]}}}function u(t,e){var r=o?n:Sa-n,u=0;return-r>t?u|=1:t>r&&(u|=2),-r>e?u|=4:e>r&&(u|=8),u}var i=Math.cos(n),o=i>0,a=oa(i)>Aa,c=cr(n,6*Na);return Ee(t,e,c,o?[0,-n]:[-Sa,n-Sa])}function De(n,t,e,r){return function(u){var i,o=u.a,a=u.b,c=o.x,s=o.y,l=a.x,f=a.y,h=0,g=1,p=l-c,v=f-s;if(i=n-c,p||!(i>0)){if(i/=p,0>p){if(h>i)return;g>i&&(g=i)}else if(p>0){if(i>g)return;i>h&&(h=i)}if(i=e-c,p||!(0>i)){if(i/=p,0>p){if(i>g)return;i>h&&(h=i)}else if(p>0){if(h>i)return;g>i&&(g=i)}if(i=t-s,v||!(i>0)){if(i/=v,0>v){if(h>i)return;g>i&&(g=i)}else if(v>0){if(i>g)return;i>h&&(h=i)}if(i=r-s,v||!(0>i)){if(i/=v,0>v){if(i>g)return;i>h&&(h=i)}else if(v>0){if(h>i)return;g>i&&(g=i)}return h>0&&(u.a={x:c+h*p,y:s+h*v}),1>g&&(u.b={x:c+g*p,y:s+g*v}),u}}}}}}function Pe(n,t,e,r){function u(r,u){return oa(r[0]-n)<Aa?u>0?0:3:oa(r[0]-e)<Aa?u>0?2:1:oa(r[1]-t)<Aa?u>0?1:0:u>0?3:2}function i(n,t){return o(n.x,t.x)}function o(n,t){var e=u(n,1),r=u(t,1);return e!==r?e-r:0===e?t[1]-n[1]:1===e?n[0]-t[0]:2===e?n[1]-t[1]:t[0]-n[0]}return function(a){function c(n){for(var t=0,e=d.length,r=n[1],u=0;e>u;++u)for(var i,o=1,a=d[u],c=a.length,s=a[0];c>o;++o)i=a[o],s[1]<=r?i[1]>r&&Z(s,i,n)>0&&++t:i[1]<=r&&Z(s,i,n)<0&&--t,s=i;return 0!==t}function s(i,a,c,s){var l=0,f=0;if(null==i||(l=u(i,c))!==(f=u(a,c))||o(i,a)<0^c>0){do s.point(0===l||3===l?n:e,l>1?r:t);while((l=(l+c+4)%4)!==f)}else s.point(a[0],a[1])}function l(u,i){return u>=n&&e>=u&&i>=t&&r>=i}function f(n,t){l(n,t)&&a.point(n,t)}function h(){N.point=p,d&&d.push(m=[]),S=!0,w=!1,_=b=0/0}function g(){v&&(p(y,x),M&&w&&A.rejoin(),v.push(A.buffer())),N.point=f,w&&a.lineEnd()}function p(n,t){n=Math.max(-Ac,Math.min(Ac,n)),t=Math.max(-Ac,Math.min(Ac,t));var e=l(n,t);if(d&&m.push([n,t]),S)y=n,x=t,M=e,S=!1,e&&(a.lineStart(),a.point(n,t));else if(e&&w)a.point(n,t);else{var r={a:{x:_,y:b},b:{x:n,y:t}};C(r)?(w||(a.lineStart(),a.point(r.a.x,r.a.y)),a.point(r.b.x,r.b.y),e||a.lineEnd(),k=!1):e&&(a.lineStart(),a.point(n,t),k=!1)}_=n,b=t,w=e}var v,d,m,y,x,M,_,b,w,S,k,E=a,A=Ce(),C=De(n,t,e,r),N={point:f,lineStart:h,lineEnd:g,polygonStart:function(){a=A,v=[],d=[],k=!0},polygonEnd:function(){a=E,v=Xo.merge(v);var t=c([n,r]),e=k&&t,u=v.length;(e||u)&&(a.polygonStart(),e&&(a.lineStart(),s(null,null,1,a),a.lineEnd()),u&&we(v,i,t,s,a),a.polygonEnd()),v=d=m=null}};return N}}function Ue(n,t){function e(e,r){return e=n(e,r),t(e[0],e[1])}return n.invert&&t.invert&&(e.invert=function(e,r){return e=t.invert(e,r),e&&n.invert(e[0],e[1])}),e}function je(n){var t=0,e=Sa/3,r=nr(n),u=r(t,e);return u.parallels=function(n){return arguments.length?r(t=n[0]*Sa/180,e=n[1]*Sa/180):[180*(t/Sa),180*(e/Sa)]},u}function He(n,t){function e(n,t){var e=Math.sqrt(i-2*u*Math.sin(t))/u;return[e*Math.sin(n*=u),o-e*Math.cos(n)]}var r=Math.sin(n),u=(r+Math.sin(t))/2,i=1+r*(2*u-r),o=Math.sqrt(i)/u;return e.invert=function(n,t){var e=o-t;return[Math.atan2(n,e)/u,X((i-(n*n+e*e)*u*u)/(2*u))]},e}function Fe(){function n(n,t){Nc+=u*n-r*t,r=n,u=t}var t,e,r,u;Rc.point=function(i,o){Rc.point=n,t=r=i,e=u=o},Rc.lineEnd=function(){n(t,e)}}function Oe(n,t){Lc>n&&(Lc=n),n>qc&&(qc=n),zc>t&&(zc=t),t>Tc&&(Tc=t)}function Ye(){function n(n,t){o.push("M",n,",",t,i)}function t(n,t){o.push("M",n,",",t),a.point=e}function e(n,t){o.push("L",n,",",t)}function r(){a.point=n}function u(){o.push("Z")}var i=Ie(4.5),o=[],a={point:n,lineStart:function(){a.point=t},lineEnd:r,polygonStart:function(){a.lineEnd=u},polygonEnd:function(){a.lineEnd=r,a.point=n},pointRadius:function(n){return i=Ie(n),a},result:function(){if(o.length){var n=o.join("");return o=[],n}}};return a}function Ie(n){return"m0,"+n+"a"+n+","+n+" 0 1,1 0,"+-2*n+"a"+n+","+n+" 0 1,1 0,"+2*n+"z"}function Ze(n,t){dc+=n,mc+=t,++yc}function Ve(){function n(n,r){var u=n-t,i=r-e,o=Math.sqrt(u*u+i*i);xc+=o*(t+n)/2,Mc+=o*(e+r)/2,_c+=o,Ze(t=n,e=r)}var t,e;Pc.point=function(r,u){Pc.point=n,Ze(t=r,e=u)}}function Xe(){Pc.point=Ze}function $e(){function n(n,t){var e=n-r,i=t-u,o=Math.sqrt(e*e+i*i);xc+=o*(r+n)/2,Mc+=o*(u+t)/2,_c+=o,o=u*n-r*t,bc+=o*(r+n),wc+=o*(u+t),Sc+=3*o,Ze(r=n,u=t)}var t,e,r,u;Pc.point=function(i,o){Pc.point=n,Ze(t=r=i,e=u=o)},Pc.lineEnd=function(){n(t,e)}}function Be(n){function t(t,e){n.moveTo(t,e),n.arc(t,e,o,0,ka)}function e(t,e){n.moveTo(t,e),a.point=r}function r(t,e){n.lineTo(t,e)}function u(){a.point=t}function i(){n.closePath()}var o=4.5,a={point:t,lineStart:function(){a.point=e},lineEnd:u,polygonStart:function(){a.lineEnd=i},polygonEnd:function(){a.lineEnd=u,a.point=t},pointRadius:function(n){return o=n,a},result:g};return a}function We(n){function t(n){return(a?r:e)(n)}function e(t){return Ke(t,function(e,r){e=n(e,r),t.point(e[0],e[1])})}function r(t){function e(e,r){e=n(e,r),t.point(e[0],e[1])}function r(){x=0/0,S.point=i,t.lineStart()}function i(e,r){var i=se([e,r]),o=n(e,r);u(x,M,y,_,b,w,x=o[0],M=o[1],y=e,_=i[0],b=i[1],w=i[2],a,t),t.point(x,M)}function o(){S.point=e,t.lineEnd()}function c(){r(),S.point=s,S.lineEnd=l}function s(n,t){i(f=n,h=t),g=x,p=M,v=_,d=b,m=w,S.point=i}function l(){u(x,M,y,_,b,w,g,p,f,v,d,m,a,t),S.lineEnd=o,o()}var f,h,g,p,v,d,m,y,x,M,_,b,w,S={point:e,lineStart:r,lineEnd:o,polygonStart:function(){t.polygonStart(),S.lineStart=c},polygonEnd:function(){t.polygonEnd(),S.lineStart=r}};return S}function u(t,e,r,a,c,s,l,f,h,g,p,v,d,m){var y=l-t,x=f-e,M=y*y+x*x;if(M>4*i&&d--){var _=a+g,b=c+p,w=s+v,S=Math.sqrt(_*_+b*b+w*w),k=Math.asin(w/=S),E=oa(oa(w)-1)<Aa||oa(r-h)<Aa?(r+h)/2:Math.atan2(b,_),A=n(E,k),C=A[0],N=A[1],L=C-t,z=N-e,q=x*L-y*z;(q*q/M>i||oa((y*L+x*z)/M-.5)>.3||o>a*g+c*p+s*v)&&(u(t,e,r,a,c,s,C,N,E,_/=S,b/=S,w,d,m),m.point(C,N),u(C,N,E,_,b,w,l,f,h,g,p,v,d,m))}}var i=.5,o=Math.cos(30*Na),a=16;return t.precision=function(n){return arguments.length?(a=(i=n*n)>0&&16,t):Math.sqrt(i)},t}function Je(n){var t=We(function(t,e){return n([t*La,e*La])});return function(n){return tr(t(n))}}function Ge(n){this.stream=n}function Ke(n,t){return{point:t,sphere:function(){n.sphere()},lineStart:function(){n.lineStart()},lineEnd:function(){n.lineEnd()},polygonStart:function(){n.polygonStart()},polygonEnd:function(){n.polygonEnd()}}}function Qe(n){return nr(function(){return n})()}function nr(n){function t(n){return n=a(n[0]*Na,n[1]*Na),[n[0]*h+c,s-n[1]*h]}function e(n){return n=a.invert((n[0]-c)/h,(s-n[1])/h),n&&[n[0]*La,n[1]*La]}function r(){a=Ue(o=ur(m,y,x),i);var n=i(v,d);return c=g-n[0]*h,s=p+n[1]*h,u()}function u(){return l&&(l.valid=!1,l=null),t}var i,o,a,c,s,l,f=We(function(n,t){return n=i(n,t),[n[0]*h+c,s-n[1]*h]}),h=150,g=480,p=250,v=0,d=0,m=0,y=0,x=0,M=Ec,_=bt,b=null,w=null;return t.stream=function(n){return l&&(l.valid=!1),l=tr(M(o,f(_(n)))),l.valid=!0,l},t.clipAngle=function(n){return arguments.length?(M=null==n?(b=n,Ec):Re((b=+n)*Na),u()):b -},t.clipExtent=function(n){return arguments.length?(w=n,_=n?Pe(n[0][0],n[0][1],n[1][0],n[1][1]):bt,u()):w},t.scale=function(n){return arguments.length?(h=+n,r()):h},t.translate=function(n){return arguments.length?(g=+n[0],p=+n[1],r()):[g,p]},t.center=function(n){return arguments.length?(v=n[0]%360*Na,d=n[1]%360*Na,r()):[v*La,d*La]},t.rotate=function(n){return arguments.length?(m=n[0]%360*Na,y=n[1]%360*Na,x=n.length>2?n[2]%360*Na:0,r()):[m*La,y*La,x*La]},Xo.rebind(t,f,"precision"),function(){return i=n.apply(this,arguments),t.invert=i.invert&&e,r()}}function tr(n){return Ke(n,function(t,e){n.point(t*Na,e*Na)})}function er(n,t){return[n,t]}function rr(n,t){return[n>Sa?n-ka:-Sa>n?n+ka:n,t]}function ur(n,t,e){return n?t||e?Ue(or(n),ar(t,e)):or(n):t||e?ar(t,e):rr}function ir(n){return function(t,e){return t+=n,[t>Sa?t-ka:-Sa>t?t+ka:t,e]}}function or(n){var t=ir(n);return t.invert=ir(-n),t}function ar(n,t){function e(n,t){var e=Math.cos(t),a=Math.cos(n)*e,c=Math.sin(n)*e,s=Math.sin(t),l=s*r+a*u;return[Math.atan2(c*i-l*o,a*r-s*u),X(l*i+c*o)]}var r=Math.cos(n),u=Math.sin(n),i=Math.cos(t),o=Math.sin(t);return e.invert=function(n,t){var e=Math.cos(t),a=Math.cos(n)*e,c=Math.sin(n)*e,s=Math.sin(t),l=s*i-c*o;return[Math.atan2(c*i+s*o,a*r+l*u),X(l*r-a*u)]},e}function cr(n,t){var e=Math.cos(n),r=Math.sin(n);return function(u,i,o,a){var c=o*t;null!=u?(u=sr(e,u),i=sr(e,i),(o>0?i>u:u>i)&&(u+=o*ka)):(u=n+o*ka,i=n-.5*c);for(var s,l=u;o>0?l>i:i>l;l-=c)a.point((s=ve([e,-r*Math.cos(l),-r*Math.sin(l)]))[0],s[1])}}function sr(n,t){var e=se(t);e[0]-=n,pe(e);var r=V(-e[1]);return((-e[2]<0?-r:r)+2*Math.PI-Aa)%(2*Math.PI)}function lr(n,t,e){var r=Xo.range(n,t-Aa,e).concat(t);return function(n){return r.map(function(t){return[n,t]})}}function fr(n,t,e){var r=Xo.range(n,t-Aa,e).concat(t);return function(n){return r.map(function(t){return[t,n]})}}function hr(n){return n.source}function gr(n){return n.target}function pr(n,t,e,r){var u=Math.cos(t),i=Math.sin(t),o=Math.cos(r),a=Math.sin(r),c=u*Math.cos(n),s=u*Math.sin(n),l=o*Math.cos(e),f=o*Math.sin(e),h=2*Math.asin(Math.sqrt(J(r-t)+u*o*J(e-n))),g=1/Math.sin(h),p=h?function(n){var t=Math.sin(n*=h)*g,e=Math.sin(h-n)*g,r=e*c+t*l,u=e*s+t*f,o=e*i+t*a;return[Math.atan2(u,r)*La,Math.atan2(o,Math.sqrt(r*r+u*u))*La]}:function(){return[n*La,t*La]};return p.distance=h,p}function vr(){function n(n,u){var i=Math.sin(u*=Na),o=Math.cos(u),a=oa((n*=Na)-t),c=Math.cos(a);Uc+=Math.atan2(Math.sqrt((a=o*Math.sin(a))*a+(a=r*i-e*o*c)*a),e*i+r*o*c),t=n,e=i,r=o}var t,e,r;jc.point=function(u,i){t=u*Na,e=Math.sin(i*=Na),r=Math.cos(i),jc.point=n},jc.lineEnd=function(){jc.point=jc.lineEnd=g}}function dr(n,t){function e(t,e){var r=Math.cos(t),u=Math.cos(e),i=n(r*u);return[i*u*Math.sin(t),i*Math.sin(e)]}return e.invert=function(n,e){var r=Math.sqrt(n*n+e*e),u=t(r),i=Math.sin(u),o=Math.cos(u);return[Math.atan2(n*i,r*o),Math.asin(r&&e*i/r)]},e}function mr(n,t){function e(n,t){var e=oa(oa(t)-Ea)<Aa?0:o/Math.pow(u(t),i);return[e*Math.sin(i*n),o-e*Math.cos(i*n)]}var r=Math.cos(n),u=function(n){return Math.tan(Sa/4+n/2)},i=n===t?Math.sin(n):Math.log(r/Math.cos(t))/Math.log(u(t)/u(n)),o=r*Math.pow(u(n),i)/i;return i?(e.invert=function(n,t){var e=o-t,r=I(i)*Math.sqrt(n*n+e*e);return[Math.atan2(n,e)/i,2*Math.atan(Math.pow(o/r,1/i))-Ea]},e):xr}function yr(n,t){function e(n,t){var e=i-t;return[e*Math.sin(u*n),i-e*Math.cos(u*n)]}var r=Math.cos(n),u=n===t?Math.sin(n):(r-Math.cos(t))/(t-n),i=r/u+n;return oa(u)<Aa?er:(e.invert=function(n,t){var e=i-t;return[Math.atan2(n,e)/u,i-I(u)*Math.sqrt(n*n+e*e)]},e)}function xr(n,t){return[n,Math.log(Math.tan(Sa/4+t/2))]}function Mr(n){var t,e=Qe(n),r=e.scale,u=e.translate,i=e.clipExtent;return e.scale=function(){var n=r.apply(e,arguments);return n===e?t?e.clipExtent(null):e:n},e.translate=function(){var n=u.apply(e,arguments);return n===e?t?e.clipExtent(null):e:n},e.clipExtent=function(n){var o=i.apply(e,arguments);if(o===e){if(t=null==n){var a=Sa*r(),c=u();i([[c[0]-a,c[1]-a],[c[0]+a,c[1]+a]])}}else t&&(o=null);return o},e.clipExtent(null)}function _r(n,t){return[Math.log(Math.tan(Sa/4+t/2)),-n]}function br(n){return n[0]}function wr(n){return n[1]}function Sr(n){for(var t=n.length,e=[0,1],r=2,u=2;t>u;u++){for(;r>1&&Z(n[e[r-2]],n[e[r-1]],n[u])<=0;)--r;e[r++]=u}return e.slice(0,r)}function kr(n,t){return n[0]-t[0]||n[1]-t[1]}function Er(n,t,e){return(e[0]-t[0])*(n[1]-t[1])<(e[1]-t[1])*(n[0]-t[0])}function Ar(n,t,e,r){var u=n[0],i=e[0],o=t[0]-u,a=r[0]-i,c=n[1],s=e[1],l=t[1]-c,f=r[1]-s,h=(a*(c-s)-f*(u-i))/(f*o-a*l);return[u+h*o,c+h*l]}function Cr(n){var t=n[0],e=n[n.length-1];return!(t[0]-e[0]||t[1]-e[1])}function Nr(){Jr(this),this.edge=this.site=this.circle=null}function Lr(n){var t=Jc.pop()||new Nr;return t.site=n,t}function zr(n){Or(n),$c.remove(n),Jc.push(n),Jr(n)}function qr(n){var t=n.circle,e=t.x,r=t.cy,u={x:e,y:r},i=n.P,o=n.N,a=[n];zr(n);for(var c=i;c.circle&&oa(e-c.circle.x)<Aa&&oa(r-c.circle.cy)<Aa;)i=c.P,a.unshift(c),zr(c),c=i;a.unshift(c),Or(c);for(var s=o;s.circle&&oa(e-s.circle.x)<Aa&&oa(r-s.circle.cy)<Aa;)o=s.N,a.push(s),zr(s),s=o;a.push(s),Or(s);var l,f=a.length;for(l=1;f>l;++l)s=a[l],c=a[l-1],$r(s.edge,c.site,s.site,u);c=a[0],s=a[f-1],s.edge=Vr(c.site,s.site,null,u),Fr(c),Fr(s)}function Tr(n){for(var t,e,r,u,i=n.x,o=n.y,a=$c._;a;)if(r=Rr(a,o)-i,r>Aa)a=a.L;else{if(u=i-Dr(a,o),!(u>Aa)){r>-Aa?(t=a.P,e=a):u>-Aa?(t=a,e=a.N):t=e=a;break}if(!a.R){t=a;break}a=a.R}var c=Lr(n);if($c.insert(t,c),t||e){if(t===e)return Or(t),e=Lr(t.site),$c.insert(c,e),c.edge=e.edge=Vr(t.site,c.site),Fr(t),Fr(e),void 0;if(!e)return c.edge=Vr(t.site,c.site),void 0;Or(t),Or(e);var s=t.site,l=s.x,f=s.y,h=n.x-l,g=n.y-f,p=e.site,v=p.x-l,d=p.y-f,m=2*(h*d-g*v),y=h*h+g*g,x=v*v+d*d,M={x:(d*y-g*x)/m+l,y:(h*x-v*y)/m+f};$r(e.edge,s,p,M),c.edge=Vr(s,n,null,M),e.edge=Vr(n,p,null,M),Fr(t),Fr(e)}}function Rr(n,t){var e=n.site,r=e.x,u=e.y,i=u-t;if(!i)return r;var o=n.P;if(!o)return-1/0;e=o.site;var a=e.x,c=e.y,s=c-t;if(!s)return a;var l=a-r,f=1/i-1/s,h=l/s;return f?(-h+Math.sqrt(h*h-2*f*(l*l/(-2*s)-c+s/2+u-i/2)))/f+r:(r+a)/2}function Dr(n,t){var e=n.N;if(e)return Rr(e,t);var r=n.site;return r.y===t?r.x:1/0}function Pr(n){this.site=n,this.edges=[]}function Ur(n){for(var t,e,r,u,i,o,a,c,s,l,f=n[0][0],h=n[1][0],g=n[0][1],p=n[1][1],v=Xc,d=v.length;d--;)if(i=v[d],i&&i.prepare())for(a=i.edges,c=a.length,o=0;c>o;)l=a[o].end(),r=l.x,u=l.y,s=a[++o%c].start(),t=s.x,e=s.y,(oa(r-t)>Aa||oa(u-e)>Aa)&&(a.splice(o,0,new Br(Xr(i.site,l,oa(r-f)<Aa&&p-u>Aa?{x:f,y:oa(t-f)<Aa?e:p}:oa(u-p)<Aa&&h-r>Aa?{x:oa(e-p)<Aa?t:h,y:p}:oa(r-h)<Aa&&u-g>Aa?{x:h,y:oa(t-h)<Aa?e:g}:oa(u-g)<Aa&&r-f>Aa?{x:oa(e-g)<Aa?t:f,y:g}:null),i.site,null)),++c)}function jr(n,t){return t.angle-n.angle}function Hr(){Jr(this),this.x=this.y=this.arc=this.site=this.cy=null}function Fr(n){var t=n.P,e=n.N;if(t&&e){var r=t.site,u=n.site,i=e.site;if(r!==i){var o=u.x,a=u.y,c=r.x-o,s=r.y-a,l=i.x-o,f=i.y-a,h=2*(c*f-s*l);if(!(h>=-Ca)){var g=c*c+s*s,p=l*l+f*f,v=(f*g-s*p)/h,d=(c*p-l*g)/h,f=d+a,m=Gc.pop()||new Hr;m.arc=n,m.site=u,m.x=v+o,m.y=f+Math.sqrt(v*v+d*d),m.cy=f,n.circle=m;for(var y=null,x=Wc._;x;)if(m.y<x.y||m.y===x.y&&m.x<=x.x){if(!x.L){y=x.P;break}x=x.L}else{if(!x.R){y=x;break}x=x.R}Wc.insert(y,m),y||(Bc=m)}}}}function Or(n){var t=n.circle;t&&(t.P||(Bc=t.N),Wc.remove(t),Gc.push(t),Jr(t),n.circle=null)}function Yr(n){for(var t,e=Vc,r=De(n[0][0],n[0][1],n[1][0],n[1][1]),u=e.length;u--;)t=e[u],(!Ir(t,n)||!r(t)||oa(t.a.x-t.b.x)<Aa&&oa(t.a.y-t.b.y)<Aa)&&(t.a=t.b=null,e.splice(u,1))}function Ir(n,t){var e=n.b;if(e)return!0;var r,u,i=n.a,o=t[0][0],a=t[1][0],c=t[0][1],s=t[1][1],l=n.l,f=n.r,h=l.x,g=l.y,p=f.x,v=f.y,d=(h+p)/2,m=(g+v)/2;if(v===g){if(o>d||d>=a)return;if(h>p){if(i){if(i.y>=s)return}else i={x:d,y:c};e={x:d,y:s}}else{if(i){if(i.y<c)return}else i={x:d,y:s};e={x:d,y:c}}}else if(r=(h-p)/(v-g),u=m-r*d,-1>r||r>1)if(h>p){if(i){if(i.y>=s)return}else i={x:(c-u)/r,y:c};e={x:(s-u)/r,y:s}}else{if(i){if(i.y<c)return}else i={x:(s-u)/r,y:s};e={x:(c-u)/r,y:c}}else if(v>g){if(i){if(i.x>=a)return}else i={x:o,y:r*o+u};e={x:a,y:r*a+u}}else{if(i){if(i.x<o)return}else i={x:a,y:r*a+u};e={x:o,y:r*o+u}}return n.a=i,n.b=e,!0}function Zr(n,t){this.l=n,this.r=t,this.a=this.b=null}function Vr(n,t,e,r){var u=new Zr(n,t);return Vc.push(u),e&&$r(u,n,t,e),r&&$r(u,t,n,r),Xc[n.i].edges.push(new Br(u,n,t)),Xc[t.i].edges.push(new Br(u,t,n)),u}function Xr(n,t,e){var r=new Zr(n,null);return r.a=t,r.b=e,Vc.push(r),r}function $r(n,t,e,r){n.a||n.b?n.l===e?n.b=r:n.a=r:(n.a=r,n.l=t,n.r=e)}function Br(n,t,e){var r=n.a,u=n.b;this.edge=n,this.site=t,this.angle=e?Math.atan2(e.y-t.y,e.x-t.x):n.l===t?Math.atan2(u.x-r.x,r.y-u.y):Math.atan2(r.x-u.x,u.y-r.y)}function Wr(){this._=null}function Jr(n){n.U=n.C=n.L=n.R=n.P=n.N=null}function Gr(n,t){var e=t,r=t.R,u=e.U;u?u.L===e?u.L=r:u.R=r:n._=r,r.U=u,e.U=r,e.R=r.L,e.R&&(e.R.U=e),r.L=e}function Kr(n,t){var e=t,r=t.L,u=e.U;u?u.L===e?u.L=r:u.R=r:n._=r,r.U=u,e.U=r,e.L=r.R,e.L&&(e.L.U=e),r.R=e}function Qr(n){for(;n.L;)n=n.L;return n}function nu(n,t){var e,r,u,i=n.sort(tu).pop();for(Vc=[],Xc=new Array(n.length),$c=new Wr,Wc=new Wr;;)if(u=Bc,i&&(!u||i.y<u.y||i.y===u.y&&i.x<u.x))(i.x!==e||i.y!==r)&&(Xc[i.i]=new Pr(i),Tr(i),e=i.x,r=i.y),i=n.pop();else{if(!u)break;qr(u.arc)}t&&(Yr(t),Ur(t));var o={cells:Xc,edges:Vc};return $c=Wc=Vc=Xc=null,o}function tu(n,t){return t.y-n.y||t.x-n.x}function eu(n,t,e){return(n.x-e.x)*(t.y-n.y)-(n.x-t.x)*(e.y-n.y)}function ru(n){return n.x}function uu(n){return n.y}function iu(){return{leaf:!0,nodes:[],point:null,x:null,y:null}}function ou(n,t,e,r,u,i){if(!n(t,e,r,u,i)){var o=.5*(e+u),a=.5*(r+i),c=t.nodes;c[0]&&ou(n,c[0],e,r,o,a),c[1]&&ou(n,c[1],o,r,u,a),c[2]&&ou(n,c[2],e,a,o,i),c[3]&&ou(n,c[3],o,a,u,i)}}function au(n,t){n=Xo.rgb(n),t=Xo.rgb(t);var e=n.r,r=n.g,u=n.b,i=t.r-e,o=t.g-r,a=t.b-u;return function(n){return"#"+vt(Math.round(e+i*n))+vt(Math.round(r+o*n))+vt(Math.round(u+a*n))}}function cu(n,t){var e,r={},u={};for(e in n)e in t?r[e]=fu(n[e],t[e]):u[e]=n[e];for(e in t)e in n||(u[e]=t[e]);return function(n){for(e in r)u[e]=r[e](n);return u}}function su(n,t){return t-=n=+n,function(e){return n+t*e}}function lu(n,t){var e,r,u,i,o,a=0,c=0,s=[],l=[];for(n+="",t+="",Qc.lastIndex=0,r=0;e=Qc.exec(t);++r)e.index&&s.push(t.substring(a,c=e.index)),l.push({i:s.length,x:e[0]}),s.push(null),a=Qc.lastIndex;for(a<t.length&&s.push(t.substring(a)),r=0,i=l.length;(e=Qc.exec(n))&&i>r;++r)if(o=l[r],o.x==e[0]){if(o.i)if(null==s[o.i+1])for(s[o.i-1]+=o.x,s.splice(o.i,1),u=r+1;i>u;++u)l[u].i--;else for(s[o.i-1]+=o.x+s[o.i+1],s.splice(o.i,2),u=r+1;i>u;++u)l[u].i-=2;else if(null==s[o.i+1])s[o.i]=o.x;else for(s[o.i]=o.x+s[o.i+1],s.splice(o.i+1,1),u=r+1;i>u;++u)l[u].i--;l.splice(r,1),i--,r--}else o.x=su(parseFloat(e[0]),parseFloat(o.x));for(;i>r;)o=l.pop(),null==s[o.i+1]?s[o.i]=o.x:(s[o.i]=o.x+s[o.i+1],s.splice(o.i+1,1)),i--;return 1===s.length?null==s[0]?(o=l[0].x,function(n){return o(n)+""}):function(){return t}:function(n){for(r=0;i>r;++r)s[(o=l[r]).i]=o.x(n);return s.join("")}}function fu(n,t){for(var e,r=Xo.interpolators.length;--r>=0&&!(e=Xo.interpolators[r](n,t)););return e}function hu(n,t){var e,r=[],u=[],i=n.length,o=t.length,a=Math.min(n.length,t.length);for(e=0;a>e;++e)r.push(fu(n[e],t[e]));for(;i>e;++e)u[e]=n[e];for(;o>e;++e)u[e]=t[e];return function(n){for(e=0;a>e;++e)u[e]=r[e](n);return u}}function gu(n){return function(t){return 0>=t?0:t>=1?1:n(t)}}function pu(n){return function(t){return 1-n(1-t)}}function vu(n){return function(t){return.5*(.5>t?n(2*t):2-n(2-2*t))}}function du(n){return n*n}function mu(n){return n*n*n}function yu(n){if(0>=n)return 0;if(n>=1)return 1;var t=n*n,e=t*n;return 4*(.5>n?e:3*(n-t)+e-.75)}function xu(n){return function(t){return Math.pow(t,n)}}function Mu(n){return 1-Math.cos(n*Ea)}function _u(n){return Math.pow(2,10*(n-1))}function bu(n){return 1-Math.sqrt(1-n*n)}function wu(n,t){var e;return arguments.length<2&&(t=.45),arguments.length?e=t/ka*Math.asin(1/n):(n=1,e=t/4),function(r){return 1+n*Math.pow(2,-10*r)*Math.sin((r-e)*ka/t)}}function Su(n){return n||(n=1.70158),function(t){return t*t*((n+1)*t-n)}}function ku(n){return 1/2.75>n?7.5625*n*n:2/2.75>n?7.5625*(n-=1.5/2.75)*n+.75:2.5/2.75>n?7.5625*(n-=2.25/2.75)*n+.9375:7.5625*(n-=2.625/2.75)*n+.984375}function Eu(n,t){n=Xo.hcl(n),t=Xo.hcl(t);var e=n.h,r=n.c,u=n.l,i=t.h-e,o=t.c-r,a=t.l-u;return isNaN(o)&&(o=0,r=isNaN(r)?t.c:r),isNaN(i)?(i=0,e=isNaN(e)?t.h:e):i>180?i-=360:-180>i&&(i+=360),function(n){return rt(e+i*n,r+o*n,u+a*n)+""}}function Au(n,t){n=Xo.hsl(n),t=Xo.hsl(t);var e=n.h,r=n.s,u=n.l,i=t.h-e,o=t.s-r,a=t.l-u;return isNaN(o)&&(o=0,r=isNaN(r)?t.s:r),isNaN(i)?(i=0,e=isNaN(e)?t.h:e):i>180?i-=360:-180>i&&(i+=360),function(n){return nt(e+i*n,r+o*n,u+a*n)+""}}function Cu(n,t){n=Xo.lab(n),t=Xo.lab(t);var e=n.l,r=n.a,u=n.b,i=t.l-e,o=t.a-r,a=t.b-u;return function(n){return ot(e+i*n,r+o*n,u+a*n)+""}}function Nu(n,t){return t-=n,function(e){return Math.round(n+t*e)}}function Lu(n){var t=[n.a,n.b],e=[n.c,n.d],r=qu(t),u=zu(t,e),i=qu(Tu(e,t,-u))||0;t[0]*e[1]<e[0]*t[1]&&(t[0]*=-1,t[1]*=-1,r*=-1,u*=-1),this.rotate=(r?Math.atan2(t[1],t[0]):Math.atan2(-e[0],e[1]))*La,this.translate=[n.e,n.f],this.scale=[r,i],this.skew=i?Math.atan2(u,i)*La:0}function zu(n,t){return n[0]*t[0]+n[1]*t[1]}function qu(n){var t=Math.sqrt(zu(n,n));return t&&(n[0]/=t,n[1]/=t),t}function Tu(n,t,e){return n[0]+=e*t[0],n[1]+=e*t[1],n}function Ru(n,t){var e,r=[],u=[],i=Xo.transform(n),o=Xo.transform(t),a=i.translate,c=o.translate,s=i.rotate,l=o.rotate,f=i.skew,h=o.skew,g=i.scale,p=o.scale;return a[0]!=c[0]||a[1]!=c[1]?(r.push("translate(",null,",",null,")"),u.push({i:1,x:su(a[0],c[0])},{i:3,x:su(a[1],c[1])})):c[0]||c[1]?r.push("translate("+c+")"):r.push(""),s!=l?(s-l>180?l+=360:l-s>180&&(s+=360),u.push({i:r.push(r.pop()+"rotate(",null,")")-2,x:su(s,l)})):l&&r.push(r.pop()+"rotate("+l+")"),f!=h?u.push({i:r.push(r.pop()+"skewX(",null,")")-2,x:su(f,h)}):h&&r.push(r.pop()+"skewX("+h+")"),g[0]!=p[0]||g[1]!=p[1]?(e=r.push(r.pop()+"scale(",null,",",null,")"),u.push({i:e-4,x:su(g[0],p[0])},{i:e-2,x:su(g[1],p[1])})):(1!=p[0]||1!=p[1])&&r.push(r.pop()+"scale("+p+")"),e=u.length,function(n){for(var t,i=-1;++i<e;)r[(t=u[i]).i]=t.x(n);return r.join("")}}function Du(n,t){return t=t-(n=+n)?1/(t-n):0,function(e){return(e-n)*t}}function Pu(n,t){return t=t-(n=+n)?1/(t-n):0,function(e){return Math.max(0,Math.min(1,(e-n)*t))}}function Uu(n){for(var t=n.source,e=n.target,r=Hu(t,e),u=[t];t!==r;)t=t.parent,u.push(t);for(var i=u.length;e!==r;)u.splice(i,0,e),e=e.parent;return u}function ju(n){for(var t=[],e=n.parent;null!=e;)t.push(n),n=e,e=e.parent;return t.push(n),t}function Hu(n,t){if(n===t)return n;for(var e=ju(n),r=ju(t),u=e.pop(),i=r.pop(),o=null;u===i;)o=u,u=e.pop(),i=r.pop();return o}function Fu(n){n.fixed|=2}function Ou(n){n.fixed&=-7}function Yu(n){n.fixed|=4,n.px=n.x,n.py=n.y}function Iu(n){n.fixed&=-5}function Zu(n,t,e){var r=0,u=0;if(n.charge=0,!n.leaf)for(var i,o=n.nodes,a=o.length,c=-1;++c<a;)i=o[c],null!=i&&(Zu(i,t,e),n.charge+=i.charge,r+=i.charge*i.cx,u+=i.charge*i.cy);if(n.point){n.leaf||(n.point.x+=Math.random()-.5,n.point.y+=Math.random()-.5);var s=t*e[n.point.index];n.charge+=n.pointCharge=s,r+=s*n.point.x,u+=s*n.point.y}n.cx=r/n.charge,n.cy=u/n.charge}function Vu(n,t){return Xo.rebind(n,t,"sort","children","value"),n.nodes=n,n.links=Wu,n}function Xu(n){return n.children}function $u(n){return n.value}function Bu(n,t){return t.value-n.value}function Wu(n){return Xo.merge(n.map(function(n){return(n.children||[]).map(function(t){return{source:n,target:t}})}))}function Ju(n){return n.x}function Gu(n){return n.y}function Ku(n,t,e){n.y0=t,n.y=e}function Qu(n){return Xo.range(n.length)}function ni(n){for(var t=-1,e=n[0].length,r=[];++t<e;)r[t]=0;return r}function ti(n){for(var t,e=1,r=0,u=n[0][1],i=n.length;i>e;++e)(t=n[e][1])>u&&(r=e,u=t);return r}function ei(n){return n.reduce(ri,0)}function ri(n,t){return n+t[1]}function ui(n,t){return ii(n,Math.ceil(Math.log(t.length)/Math.LN2+1))}function ii(n,t){for(var e=-1,r=+n[0],u=(n[1]-r)/t,i=[];++e<=t;)i[e]=u*e+r;return i}function oi(n){return[Xo.min(n),Xo.max(n)]}function ai(n,t){return n.parent==t.parent?1:2}function ci(n){var t=n.children;return t&&t.length?t[0]:n._tree.thread}function si(n){var t,e=n.children;return e&&(t=e.length)?e[t-1]:n._tree.thread}function li(n,t){var e=n.children;if(e&&(u=e.length))for(var r,u,i=-1;++i<u;)t(r=li(e[i],t),n)>0&&(n=r);return n}function fi(n,t){return n.x-t.x}function hi(n,t){return t.x-n.x}function gi(n,t){return n.depth-t.depth}function pi(n,t){function e(n,r){var u=n.children;if(u&&(o=u.length))for(var i,o,a=null,c=-1;++c<o;)i=u[c],e(i,a),a=i;t(n,r)}e(n,null)}function vi(n){for(var t,e=0,r=0,u=n.children,i=u.length;--i>=0;)t=u[i]._tree,t.prelim+=e,t.mod+=e,e+=t.shift+(r+=t.change)}function di(n,t,e){n=n._tree,t=t._tree;var r=e/(t.number-n.number);n.change+=r,t.change-=r,t.shift+=e,t.prelim+=e,t.mod+=e}function mi(n,t,e){return n._tree.ancestor.parent==t.parent?n._tree.ancestor:e}function yi(n,t){return n.value-t.value}function xi(n,t){var e=n._pack_next;n._pack_next=t,t._pack_prev=n,t._pack_next=e,e._pack_prev=t}function Mi(n,t){n._pack_next=t,t._pack_prev=n}function _i(n,t){var e=t.x-n.x,r=t.y-n.y,u=n.r+t.r;return.999*u*u>e*e+r*r}function bi(n){function t(n){l=Math.min(n.x-n.r,l),f=Math.max(n.x+n.r,f),h=Math.min(n.y-n.r,h),g=Math.max(n.y+n.r,g)}if((e=n.children)&&(s=e.length)){var e,r,u,i,o,a,c,s,l=1/0,f=-1/0,h=1/0,g=-1/0;if(e.forEach(wi),r=e[0],r.x=-r.r,r.y=0,t(r),s>1&&(u=e[1],u.x=u.r,u.y=0,t(u),s>2))for(i=e[2],Ei(r,u,i),t(i),xi(r,i),r._pack_prev=i,xi(i,u),u=r._pack_next,o=3;s>o;o++){Ei(r,u,i=e[o]);var p=0,v=1,d=1;for(a=u._pack_next;a!==u;a=a._pack_next,v++)if(_i(a,i)){p=1;break}if(1==p)for(c=r._pack_prev;c!==a._pack_prev&&!_i(c,i);c=c._pack_prev,d++);p?(d>v||v==d&&u.r<r.r?Mi(r,u=a):Mi(r=c,u),o--):(xi(r,i),u=i,t(i))}var m=(l+f)/2,y=(h+g)/2,x=0;for(o=0;s>o;o++)i=e[o],i.x-=m,i.y-=y,x=Math.max(x,i.r+Math.sqrt(i.x*i.x+i.y*i.y));n.r=x,e.forEach(Si)}}function wi(n){n._pack_next=n._pack_prev=n}function Si(n){delete n._pack_next,delete n._pack_prev}function ki(n,t,e,r){var u=n.children;if(n.x=t+=r*n.x,n.y=e+=r*n.y,n.r*=r,u)for(var i=-1,o=u.length;++i<o;)ki(u[i],t,e,r)}function Ei(n,t,e){var r=n.r+e.r,u=t.x-n.x,i=t.y-n.y;if(r&&(u||i)){var o=t.r+e.r,a=u*u+i*i;o*=o,r*=r;var c=.5+(r-o)/(2*a),s=Math.sqrt(Math.max(0,2*o*(r+a)-(r-=a)*r-o*o))/(2*a);e.x=n.x+c*u+s*i,e.y=n.y+c*i-s*u}else e.x=n.x+r,e.y=n.y}function Ai(n){return 1+Xo.max(n,function(n){return n.y})}function Ci(n){return n.reduce(function(n,t){return n+t.x},0)/n.length}function Ni(n){var t=n.children;return t&&t.length?Ni(t[0]):n}function Li(n){var t,e=n.children;return e&&(t=e.length)?Li(e[t-1]):n}function zi(n){return{x:n.x,y:n.y,dx:n.dx,dy:n.dy}}function qi(n,t){var e=n.x+t[3],r=n.y+t[0],u=n.dx-t[1]-t[3],i=n.dy-t[0]-t[2];return 0>u&&(e+=u/2,u=0),0>i&&(r+=i/2,i=0),{x:e,y:r,dx:u,dy:i}}function Ti(n){var t=n[0],e=n[n.length-1];return e>t?[t,e]:[e,t]}function Ri(n){return n.rangeExtent?n.rangeExtent():Ti(n.range())}function Di(n,t,e,r){var u=e(n[0],n[1]),i=r(t[0],t[1]);return function(n){return i(u(n))}}function Pi(n,t){var e,r=0,u=n.length-1,i=n[r],o=n[u];return i>o&&(e=r,r=u,u=e,e=i,i=o,o=e),n[r]=t.floor(i),n[u]=t.ceil(o),n}function Ui(n){return n?{floor:function(t){return Math.floor(t/n)*n},ceil:function(t){return Math.ceil(t/n)*n}}:ls}function ji(n,t,e,r){var u=[],i=[],o=0,a=Math.min(n.length,t.length)-1;for(n[a]<n[0]&&(n=n.slice().reverse(),t=t.slice().reverse());++o<=a;)u.push(e(n[o-1],n[o])),i.push(r(t[o-1],t[o]));return function(t){var e=Xo.bisect(n,t,1,a)-1;return i[e](u[e](t))}}function Hi(n,t,e,r){function u(){var u=Math.min(n.length,t.length)>2?ji:Di,c=r?Pu:Du;return o=u(n,t,c,e),a=u(t,n,c,fu),i}function i(n){return o(n)}var o,a;return i.invert=function(n){return a(n)},i.domain=function(t){return arguments.length?(n=t.map(Number),u()):n},i.range=function(n){return arguments.length?(t=n,u()):t},i.rangeRound=function(n){return i.range(n).interpolate(Nu)},i.clamp=function(n){return arguments.length?(r=n,u()):r},i.interpolate=function(n){return arguments.length?(e=n,u()):e},i.ticks=function(t){return Ii(n,t)},i.tickFormat=function(t,e){return Zi(n,t,e)},i.nice=function(t){return Oi(n,t),u()},i.copy=function(){return Hi(n,t,e,r)},u()}function Fi(n,t){return Xo.rebind(n,t,"range","rangeRound","interpolate","clamp")}function Oi(n,t){return Pi(n,Ui(Yi(n,t)[2]))}function Yi(n,t){null==t&&(t=10);var e=Ti(n),r=e[1]-e[0],u=Math.pow(10,Math.floor(Math.log(r/t)/Math.LN10)),i=t/r*u;return.15>=i?u*=10:.35>=i?u*=5:.75>=i&&(u*=2),e[0]=Math.ceil(e[0]/u)*u,e[1]=Math.floor(e[1]/u)*u+.5*u,e[2]=u,e}function Ii(n,t){return Xo.range.apply(Xo,Yi(n,t))}function Zi(n,t,e){var r=Yi(n,t);return Xo.format(e?e.replace(Qa,function(n,t,e,u,i,o,a,c,s,l){return[t,e,u,i,o,a,c,s||"."+Xi(l,r),l].join("")}):",."+Vi(r[2])+"f")}function Vi(n){return-Math.floor(Math.log(n)/Math.LN10+.01)}function Xi(n,t){var e=Vi(t[2]);return n in fs?Math.abs(e-Vi(Math.max(Math.abs(t[0]),Math.abs(t[1]))))+ +("e"!==n):e-2*("%"===n)}function $i(n,t,e,r){function u(n){return(e?Math.log(0>n?0:n):-Math.log(n>0?0:-n))/Math.log(t)}function i(n){return e?Math.pow(t,n):-Math.pow(t,-n)}function o(t){return n(u(t))}return o.invert=function(t){return i(n.invert(t))},o.domain=function(t){return arguments.length?(e=t[0]>=0,n.domain((r=t.map(Number)).map(u)),o):r},o.base=function(e){return arguments.length?(t=+e,n.domain(r.map(u)),o):t},o.nice=function(){var t=Pi(r.map(u),e?Math:gs);return n.domain(t),r=t.map(i),o},o.ticks=function(){var n=Ti(r),o=[],a=n[0],c=n[1],s=Math.floor(u(a)),l=Math.ceil(u(c)),f=t%1?2:t;if(isFinite(l-s)){if(e){for(;l>s;s++)for(var h=1;f>h;h++)o.push(i(s)*h);o.push(i(s))}else for(o.push(i(s));s++<l;)for(var h=f-1;h>0;h--)o.push(i(s)*h);for(s=0;o[s]<a;s++);for(l=o.length;o[l-1]>c;l--);o=o.slice(s,l)}return o},o.tickFormat=function(n,t){if(!arguments.length)return hs;arguments.length<2?t=hs:"function"!=typeof t&&(t=Xo.format(t));var r,a=Math.max(.1,n/o.ticks().length),c=e?(r=1e-12,Math.ceil):(r=-1e-12,Math.floor);return function(n){return n/i(c(u(n)+r))<=a?t(n):""}},o.copy=function(){return $i(n.copy(),t,e,r)},Fi(o,n)}function Bi(n,t,e){function r(t){return n(u(t))}var u=Wi(t),i=Wi(1/t);return r.invert=function(t){return i(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain((e=t.map(Number)).map(u)),r):e},r.ticks=function(n){return Ii(e,n)},r.tickFormat=function(n,t){return Zi(e,n,t)},r.nice=function(n){return r.domain(Oi(e,n))},r.exponent=function(o){return arguments.length?(u=Wi(t=o),i=Wi(1/t),n.domain(e.map(u)),r):t},r.copy=function(){return Bi(n.copy(),t,e)},Fi(r,n)}function Wi(n){return function(t){return 0>t?-Math.pow(-t,n):Math.pow(t,n)}}function Ji(n,t){function e(e){return o[((i.get(e)||"range"===t.t&&i.set(e,n.push(e)))-1)%o.length]}function r(t,e){return Xo.range(n.length).map(function(n){return t+e*n})}var i,o,a;return e.domain=function(r){if(!arguments.length)return n;n=[],i=new u;for(var o,a=-1,c=r.length;++a<c;)i.has(o=r[a])||i.set(o,n.push(o));return e[t.t].apply(e,t.a)},e.range=function(n){return arguments.length?(o=n,a=0,t={t:"range",a:arguments},e):o},e.rangePoints=function(u,i){arguments.length<2&&(i=0);var c=u[0],s=u[1],l=(s-c)/(Math.max(1,n.length-1)+i);return o=r(n.length<2?(c+s)/2:c+l*i/2,l),a=0,t={t:"rangePoints",a:arguments},e},e.rangeBands=function(u,i,c){arguments.length<2&&(i=0),arguments.length<3&&(c=i);var s=u[1]<u[0],l=u[s-0],f=u[1-s],h=(f-l)/(n.length-i+2*c);return o=r(l+h*c,h),s&&o.reverse(),a=h*(1-i),t={t:"rangeBands",a:arguments},e},e.rangeRoundBands=function(u,i,c){arguments.length<2&&(i=0),arguments.length<3&&(c=i);var s=u[1]<u[0],l=u[s-0],f=u[1-s],h=Math.floor((f-l)/(n.length-i+2*c)),g=f-l-(n.length-i)*h;return o=r(l+Math.round(g/2),h),s&&o.reverse(),a=Math.round(h*(1-i)),t={t:"rangeRoundBands",a:arguments},e},e.rangeBand=function(){return a},e.rangeExtent=function(){return Ti(t.a[0])},e.copy=function(){return Ji(n,t)},e.domain(n)}function Gi(n,t){function e(){var e=0,i=t.length;for(u=[];++e<i;)u[e-1]=Xo.quantile(n,e/i);return r}function r(n){return isNaN(n=+n)?void 0:t[Xo.bisect(u,n)]}var u;return r.domain=function(t){return arguments.length?(n=t.filter(function(n){return!isNaN(n)}).sort(Xo.ascending),e()):n},r.range=function(n){return arguments.length?(t=n,e()):t},r.quantiles=function(){return u},r.invertExtent=function(e){return e=t.indexOf(e),0>e?[0/0,0/0]:[e>0?u[e-1]:n[0],e<u.length?u[e]:n[n.length-1]]},r.copy=function(){return Gi(n,t)},e()}function Ki(n,t,e){function r(t){return e[Math.max(0,Math.min(o,Math.floor(i*(t-n))))]}function u(){return i=e.length/(t-n),o=e.length-1,r}var i,o;return r.domain=function(e){return arguments.length?(n=+e[0],t=+e[e.length-1],u()):[n,t]},r.range=function(n){return arguments.length?(e=n,u()):e},r.invertExtent=function(t){return t=e.indexOf(t),t=0>t?0/0:t/i+n,[t,t+1/i]},r.copy=function(){return Ki(n,t,e)},u()}function Qi(n,t){function e(e){return e>=e?t[Xo.bisect(n,e)]:void 0}return e.domain=function(t){return arguments.length?(n=t,e):n},e.range=function(n){return arguments.length?(t=n,e):t},e.invertExtent=function(e){return e=t.indexOf(e),[n[e-1],n[e]]},e.copy=function(){return Qi(n,t)},e}function no(n){function t(n){return+n}return t.invert=t,t.domain=t.range=function(e){return arguments.length?(n=e.map(t),t):n},t.ticks=function(t){return Ii(n,t)},t.tickFormat=function(t,e){return Zi(n,t,e)},t.copy=function(){return no(n)},t}function to(n){return n.innerRadius}function eo(n){return n.outerRadius}function ro(n){return n.startAngle}function uo(n){return n.endAngle}function io(n){function t(t){function o(){s.push("M",i(n(l),a))}for(var c,s=[],l=[],f=-1,h=t.length,g=_t(e),p=_t(r);++f<h;)u.call(this,c=t[f],f)?l.push([+g.call(this,c,f),+p.call(this,c,f)]):l.length&&(o(),l=[]);return l.length&&o(),s.length?s.join(""):null}var e=br,r=wr,u=be,i=oo,o=i.key,a=.7;return t.x=function(n){return arguments.length?(e=n,t):e},t.y=function(n){return arguments.length?(r=n,t):r},t.defined=function(n){return arguments.length?(u=n,t):u},t.interpolate=function(n){return arguments.length?(o="function"==typeof n?i=n:(i=Ms.get(n)||oo).key,t):o},t.tension=function(n){return arguments.length?(a=n,t):a},t}function oo(n){return n.join("L")}function ao(n){return oo(n)+"Z"}function co(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t<e;)u.push("H",(r[0]+(r=n[t])[0])/2,"V",r[1]);return e>1&&u.push("H",r[0]),u.join("")}function so(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t<e;)u.push("V",(r=n[t])[1],"H",r[0]);return u.join("")}function lo(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t<e;)u.push("H",(r=n[t])[0],"V",r[1]);return u.join("")}function fo(n,t){return n.length<4?oo(n):n[1]+po(n.slice(1,n.length-1),vo(n,t))}function ho(n,t){return n.length<3?oo(n):n[0]+po((n.push(n[0]),n),vo([n[n.length-2]].concat(n,[n[1]]),t))}function go(n,t){return n.length<3?oo(n):n[0]+po(n,vo(n,t))}function po(n,t){if(t.length<1||n.length!=t.length&&n.length!=t.length+2)return oo(n);var e=n.length!=t.length,r="",u=n[0],i=n[1],o=t[0],a=o,c=1;if(e&&(r+="Q"+(i[0]-2*o[0]/3)+","+(i[1]-2*o[1]/3)+","+i[0]+","+i[1],u=n[1],c=2),t.length>1){a=t[1],i=n[c],c++,r+="C"+(u[0]+o[0])+","+(u[1]+o[1])+","+(i[0]-a[0])+","+(i[1]-a[1])+","+i[0]+","+i[1];for(var s=2;s<t.length;s++,c++)i=n[c],a=t[s],r+="S"+(i[0]-a[0])+","+(i[1]-a[1])+","+i[0]+","+i[1]}if(e){var l=n[c];r+="Q"+(i[0]+2*a[0]/3)+","+(i[1]+2*a[1]/3)+","+l[0]+","+l[1]}return r}function vo(n,t){for(var e,r=[],u=(1-t)/2,i=n[0],o=n[1],a=1,c=n.length;++a<c;)e=i,i=o,o=n[a],r.push([u*(o[0]-e[0]),u*(o[1]-e[1])]);return r}function mo(n){if(n.length<3)return oo(n);var t=1,e=n.length,r=n[0],u=r[0],i=r[1],o=[u,u,u,(r=n[1])[0]],a=[i,i,i,r[1]],c=[u,",",i,"L",_o(ws,o),",",_o(ws,a)];for(n.push(n[e-1]);++t<=e;)r=n[t],o.shift(),o.push(r[0]),a.shift(),a.push(r[1]),bo(c,o,a);return n.pop(),c.push("L",r),c.join("")}function yo(n){if(n.length<4)return oo(n);for(var t,e=[],r=-1,u=n.length,i=[0],o=[0];++r<3;)t=n[r],i.push(t[0]),o.push(t[1]);for(e.push(_o(ws,i)+","+_o(ws,o)),--r;++r<u;)t=n[r],i.shift(),i.push(t[0]),o.shift(),o.push(t[1]),bo(e,i,o);return e.join("")}function xo(n){for(var t,e,r=-1,u=n.length,i=u+4,o=[],a=[];++r<4;)e=n[r%u],o.push(e[0]),a.push(e[1]);for(t=[_o(ws,o),",",_o(ws,a)],--r;++r<i;)e=n[r%u],o.shift(),o.push(e[0]),a.shift(),a.push(e[1]),bo(t,o,a);return t.join("")}function Mo(n,t){var e=n.length-1;if(e)for(var r,u,i=n[0][0],o=n[0][1],a=n[e][0]-i,c=n[e][1]-o,s=-1;++s<=e;)r=n[s],u=s/e,r[0]=t*r[0]+(1-t)*(i+u*a),r[1]=t*r[1]+(1-t)*(o+u*c);return mo(n)}function _o(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]+n[3]*t[3]}function bo(n,t,e){n.push("C",_o(_s,t),",",_o(_s,e),",",_o(bs,t),",",_o(bs,e),",",_o(ws,t),",",_o(ws,e))}function wo(n,t){return(t[1]-n[1])/(t[0]-n[0])}function So(n){for(var t=0,e=n.length-1,r=[],u=n[0],i=n[1],o=r[0]=wo(u,i);++t<e;)r[t]=(o+(o=wo(u=i,i=n[t+1])))/2;return r[t]=o,r}function ko(n){for(var t,e,r,u,i=[],o=So(n),a=-1,c=n.length-1;++a<c;)t=wo(n[a],n[a+1]),oa(t)<Aa?o[a]=o[a+1]=0:(e=o[a]/t,r=o[a+1]/t,u=e*e+r*r,u>9&&(u=3*t/Math.sqrt(u),o[a]=u*e,o[a+1]=u*r));for(a=-1;++a<=c;)u=(n[Math.min(c,a+1)][0]-n[Math.max(0,a-1)][0])/(6*(1+o[a]*o[a])),i.push([u||0,o[a]*u||0]);return i}function Eo(n){return n.length<3?oo(n):n[0]+po(n,ko(n))}function Ao(n){for(var t,e,r,u=-1,i=n.length;++u<i;)t=n[u],e=t[0],r=t[1]+ys,t[0]=e*Math.cos(r),t[1]=e*Math.sin(r);return n}function Co(n){function t(t){function c(){v.push("M",a(n(m),f),l,s(n(d.reverse()),f),"Z")}for(var h,g,p,v=[],d=[],m=[],y=-1,x=t.length,M=_t(e),_=_t(u),b=e===r?function(){return g}:_t(r),w=u===i?function(){return p}:_t(i);++y<x;)o.call(this,h=t[y],y)?(d.push([g=+M.call(this,h,y),p=+_.call(this,h,y)]),m.push([+b.call(this,h,y),+w.call(this,h,y)])):d.length&&(c(),d=[],m=[]);return d.length&&c(),v.length?v.join(""):null}var e=br,r=br,u=0,i=wr,o=be,a=oo,c=a.key,s=a,l="L",f=.7;return t.x=function(n){return arguments.length?(e=r=n,t):r},t.x0=function(n){return arguments.length?(e=n,t):e},t.x1=function(n){return arguments.length?(r=n,t):r},t.y=function(n){return arguments.length?(u=i=n,t):i},t.y0=function(n){return arguments.length?(u=n,t):u},t.y1=function(n){return arguments.length?(i=n,t):i},t.defined=function(n){return arguments.length?(o=n,t):o},t.interpolate=function(n){return arguments.length?(c="function"==typeof n?a=n:(a=Ms.get(n)||oo).key,s=a.reverse||a,l=a.closed?"M":"L",t):c},t.tension=function(n){return arguments.length?(f=n,t):f},t}function No(n){return n.radius}function Lo(n){return[n.x,n.y]}function zo(n){return function(){var t=n.apply(this,arguments),e=t[0],r=t[1]+ys;return[e*Math.cos(r),e*Math.sin(r)]}}function qo(){return 64}function To(){return"circle"}function Ro(n){var t=Math.sqrt(n/Sa);return"M0,"+t+"A"+t+","+t+" 0 1,1 0,"+-t+"A"+t+","+t+" 0 1,1 0,"+t+"Z"}function Do(n,t){return fa(n,Ns),n.id=t,n}function Po(n,t,e,r){var u=n.id;return R(n,"function"==typeof e?function(n,i,o){n.__transition__[u].tween.set(t,r(e.call(n,n.__data__,i,o)))}:(e=r(e),function(n){n.__transition__[u].tween.set(t,e)}))}function Uo(n){return null==n&&(n=""),function(){this.textContent=n}}function jo(n,t,e,r){var i=n.__transition__||(n.__transition__={active:0,count:0}),o=i[e];if(!o){var a=r.time;o=i[e]={tween:new u,time:a,ease:r.ease,delay:r.delay,duration:r.duration},++i.count,Xo.timer(function(r){function u(r){return i.active>e?s():(i.active=e,o.event&&o.event.start.call(n,l,t),o.tween.forEach(function(e,r){(r=r.call(n,l,t))&&v.push(r)}),Xo.timer(function(){return p.c=c(r||1)?be:c,1},0,a),void 0)}function c(r){if(i.active!==e)return s();for(var u=r/g,a=f(u),c=v.length;c>0;)v[--c].call(n,a);return u>=1?(o.event&&o.event.end.call(n,l,t),s()):void 0}function s(){return--i.count?delete i[e]:delete n.__transition__,1}var l=n.__data__,f=o.ease,h=o.delay,g=o.duration,p=Ja,v=[];return p.t=h+a,r>=h?u(r-h):(p.c=u,void 0)},0,a)}}function Ho(n,t){n.attr("transform",function(n){return"translate("+t(n)+",0)"})}function Fo(n,t){n.attr("transform",function(n){return"translate(0,"+t(n)+")"})}function Oo(n){return n.toISOString()}function Yo(n,t,e){function r(t){return n(t)}function u(n,e){var r=n[1]-n[0],u=r/e,i=Xo.bisect(js,u);return i==js.length?[t.year,Yi(n.map(function(n){return n/31536e6}),e)[2]]:i?t[u/js[i-1]<js[i]/u?i-1:i]:[Os,Yi(n,e)[2]] -}return r.invert=function(t){return Io(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain(t),r):n.domain().map(Io)},r.nice=function(n,t){function e(e){return!isNaN(e)&&!n.range(e,Io(+e+1),t).length}var i=r.domain(),o=Ti(i),a=null==n?u(o,10):"number"==typeof n&&u(o,n);return a&&(n=a[0],t=a[1]),r.domain(Pi(i,t>1?{floor:function(t){for(;e(t=n.floor(t));)t=Io(t-1);return t},ceil:function(t){for(;e(t=n.ceil(t));)t=Io(+t+1);return t}}:n))},r.ticks=function(n,t){var e=Ti(r.domain()),i=null==n?u(e,10):"number"==typeof n?u(e,n):!n.range&&[{range:n},t];return i&&(n=i[0],t=i[1]),n.range(e[0],Io(+e[1]+1),1>t?1:t)},r.tickFormat=function(){return e},r.copy=function(){return Yo(n.copy(),t,e)},Fi(r,n)}function Io(n){return new Date(n)}function Zo(n){return JSON.parse(n.responseText)}function Vo(n){var t=Wo.createRange();return t.selectNode(Wo.body),t.createContextualFragment(n.responseText)}var Xo={version:"3.4.1"};Date.now||(Date.now=function(){return+new Date});var $o=[].slice,Bo=function(n){return $o.call(n)},Wo=document,Jo=Wo.documentElement,Go=window;try{Bo(Jo.childNodes)[0].nodeType}catch(Ko){Bo=function(n){for(var t=n.length,e=new Array(t);t--;)e[t]=n[t];return e}}try{Wo.createElement("div").style.setProperty("opacity",0,"")}catch(Qo){var na=Go.Element.prototype,ta=na.setAttribute,ea=na.setAttributeNS,ra=Go.CSSStyleDeclaration.prototype,ua=ra.setProperty;na.setAttribute=function(n,t){ta.call(this,n,t+"")},na.setAttributeNS=function(n,t,e){ea.call(this,n,t,e+"")},ra.setProperty=function(n,t,e){ua.call(this,n,t+"",e)}}Xo.ascending=function(n,t){return t>n?-1:n>t?1:n>=t?0:0/0},Xo.descending=function(n,t){return n>t?-1:t>n?1:t>=n?0:0/0},Xo.min=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u<i&&!(null!=(e=n[u])&&e>=e);)e=void 0;for(;++u<i;)null!=(r=n[u])&&e>r&&(e=r)}else{for(;++u<i&&!(null!=(e=t.call(n,n[u],u))&&e>=e);)e=void 0;for(;++u<i;)null!=(r=t.call(n,n[u],u))&&e>r&&(e=r)}return e},Xo.max=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u<i&&!(null!=(e=n[u])&&e>=e);)e=void 0;for(;++u<i;)null!=(r=n[u])&&r>e&&(e=r)}else{for(;++u<i&&!(null!=(e=t.call(n,n[u],u))&&e>=e);)e=void 0;for(;++u<i;)null!=(r=t.call(n,n[u],u))&&r>e&&(e=r)}return e},Xo.extent=function(n,t){var e,r,u,i=-1,o=n.length;if(1===arguments.length){for(;++i<o&&!(null!=(e=u=n[i])&&e>=e);)e=u=void 0;for(;++i<o;)null!=(r=n[i])&&(e>r&&(e=r),r>u&&(u=r))}else{for(;++i<o&&!(null!=(e=u=t.call(n,n[i],i))&&e>=e);)e=void 0;for(;++i<o;)null!=(r=t.call(n,n[i],i))&&(e>r&&(e=r),r>u&&(u=r))}return[e,u]},Xo.sum=function(n,t){var e,r=0,u=n.length,i=-1;if(1===arguments.length)for(;++i<u;)isNaN(e=+n[i])||(r+=e);else for(;++i<u;)isNaN(e=+t.call(n,n[i],i))||(r+=e);return r},Xo.mean=function(t,e){var r,u=t.length,i=0,o=-1,a=0;if(1===arguments.length)for(;++o<u;)n(r=t[o])&&(i+=(r-i)/++a);else for(;++o<u;)n(r=e.call(t,t[o],o))&&(i+=(r-i)/++a);return a?i:void 0},Xo.quantile=function(n,t){var e=(n.length-1)*t+1,r=Math.floor(e),u=+n[r-1],i=e-r;return i?u+i*(n[r]-u):u},Xo.median=function(t,e){return arguments.length>1&&(t=t.map(e)),t=t.filter(n),t.length?Xo.quantile(t.sort(Xo.ascending),.5):void 0},Xo.bisector=function(n){return{left:function(t,e,r,u){for(arguments.length<3&&(r=0),arguments.length<4&&(u=t.length);u>r;){var i=r+u>>>1;n.call(t,t[i],i)<e?r=i+1:u=i}return r},right:function(t,e,r,u){for(arguments.length<3&&(r=0),arguments.length<4&&(u=t.length);u>r;){var i=r+u>>>1;e<n.call(t,t[i],i)?u=i:r=i+1}return r}}};var ia=Xo.bisector(function(n){return n});Xo.bisectLeft=ia.left,Xo.bisect=Xo.bisectRight=ia.right,Xo.shuffle=function(n){for(var t,e,r=n.length;r;)e=0|Math.random()*r--,t=n[r],n[r]=n[e],n[e]=t;return n},Xo.permute=function(n,t){for(var e=t.length,r=new Array(e);e--;)r[e]=n[t[e]];return r},Xo.pairs=function(n){for(var t,e=0,r=n.length-1,u=n[0],i=new Array(0>r?0:r);r>e;)i[e]=[t=u,u=n[++e]];return i},Xo.zip=function(){if(!(u=arguments.length))return[];for(var n=-1,e=Xo.min(arguments,t),r=new Array(e);++n<e;)for(var u,i=-1,o=r[n]=new Array(u);++i<u;)o[i]=arguments[i][n];return r},Xo.transpose=function(n){return Xo.zip.apply(Xo,n)},Xo.keys=function(n){var t=[];for(var e in n)t.push(e);return t},Xo.values=function(n){var t=[];for(var e in n)t.push(n[e]);return t},Xo.entries=function(n){var t=[];for(var e in n)t.push({key:e,value:n[e]});return t},Xo.merge=function(n){for(var t,e,r,u=n.length,i=-1,o=0;++i<u;)o+=n[i].length;for(e=new Array(o);--u>=0;)for(r=n[u],t=r.length;--t>=0;)e[--o]=r[t];return e};var oa=Math.abs;Xo.range=function(n,t,r){if(arguments.length<3&&(r=1,arguments.length<2&&(t=n,n=0)),1/0===(t-n)/r)throw new Error("infinite range");var u,i=[],o=e(oa(r)),a=-1;if(n*=o,t*=o,r*=o,0>r)for(;(u=n+r*++a)>t;)i.push(u/o);else for(;(u=n+r*++a)<t;)i.push(u/o);return i},Xo.map=function(n){var t=new u;if(n instanceof u)n.forEach(function(n,e){t.set(n,e)});else for(var e in n)t.set(e,n[e]);return t},r(u,{has:i,get:function(n){return this[aa+n]},set:function(n,t){return this[aa+n]=t},remove:o,keys:a,values:function(){var n=[];return this.forEach(function(t,e){n.push(e)}),n},entries:function(){var n=[];return this.forEach(function(t,e){n.push({key:t,value:e})}),n},size:c,empty:s,forEach:function(n){for(var t in this)t.charCodeAt(0)===ca&&n.call(this,t.substring(1),this[t])}});var aa="\x00",ca=aa.charCodeAt(0);Xo.nest=function(){function n(t,a,c){if(c>=o.length)return r?r.call(i,a):e?a.sort(e):a;for(var s,l,f,h,g=-1,p=a.length,v=o[c++],d=new u;++g<p;)(h=d.get(s=v(l=a[g])))?h.push(l):d.set(s,[l]);return t?(l=t(),f=function(e,r){l.set(e,n(t,r,c))}):(l={},f=function(e,r){l[e]=n(t,r,c)}),d.forEach(f),l}function t(n,e){if(e>=o.length)return n;var r=[],u=a[e++];return n.forEach(function(n,u){r.push({key:n,values:t(u,e)})}),u?r.sort(function(n,t){return u(n.key,t.key)}):r}var e,r,i={},o=[],a=[];return i.map=function(t,e){return n(e,t,0)},i.entries=function(e){return t(n(Xo.map,e,0),0)},i.key=function(n){return o.push(n),i},i.sortKeys=function(n){return a[o.length-1]=n,i},i.sortValues=function(n){return e=n,i},i.rollup=function(n){return r=n,i},i},Xo.set=function(n){var t=new l;if(n)for(var e=0,r=n.length;r>e;++e)t.add(n[e]);return t},r(l,{has:i,add:function(n){return this[aa+n]=!0,n},remove:function(n){return n=aa+n,n in this&&delete this[n]},values:a,size:c,empty:s,forEach:function(n){for(var t in this)t.charCodeAt(0)===ca&&n.call(this,t.substring(1))}}),Xo.behavior={},Xo.rebind=function(n,t){for(var e,r=1,u=arguments.length;++r<u;)n[e=arguments[r]]=f(n,t,t[e]);return n};var sa=["webkit","ms","moz","Moz","o","O"];Xo.dispatch=function(){for(var n=new p,t=-1,e=arguments.length;++t<e;)n[arguments[t]]=v(n);return n},p.prototype.on=function(n,t){var e=n.indexOf("."),r="";if(e>=0&&(r=n.substring(e+1),n=n.substring(0,e)),n)return arguments.length<2?this[n].on(r):this[n].on(r,t);if(2===arguments.length){if(null==t)for(n in this)this.hasOwnProperty(n)&&this[n].on(r,null);return this}},Xo.event=null,Xo.requote=function(n){return n.replace(la,"\\$&")};var la=/[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g,fa={}.__proto__?function(n,t){n.__proto__=t}:function(n,t){for(var e in t)n[e]=t[e]},ha=function(n,t){return t.querySelector(n)},ga=function(n,t){return t.querySelectorAll(n)},pa=Jo[h(Jo,"matchesSelector")],va=function(n,t){return pa.call(n,t)};"function"==typeof Sizzle&&(ha=function(n,t){return Sizzle(n,t)[0]||null},ga=function(n,t){return Sizzle.uniqueSort(Sizzle(n,t))},va=Sizzle.matchesSelector),Xo.selection=function(){return xa};var da=Xo.selection.prototype=[];da.select=function(n){var t,e,r,u,i=[];n=M(n);for(var o=-1,a=this.length;++o<a;){i.push(t=[]),t.parentNode=(r=this[o]).parentNode;for(var c=-1,s=r.length;++c<s;)(u=r[c])?(t.push(e=n.call(u,u.__data__,c,o)),e&&"__data__"in u&&(e.__data__=u.__data__)):t.push(null)}return x(i)},da.selectAll=function(n){var t,e,r=[];n=_(n);for(var u=-1,i=this.length;++u<i;)for(var o=this[u],a=-1,c=o.length;++a<c;)(e=o[a])&&(r.push(t=Bo(n.call(e,e.__data__,a,u))),t.parentNode=e);return x(r)};var ma={svg:"http://www.w3.org/2000/svg",xhtml:"http://www.w3.org/1999/xhtml",xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"};Xo.ns={prefix:ma,qualify:function(n){var t=n.indexOf(":"),e=n;return t>=0&&(e=n.substring(0,t),n=n.substring(t+1)),ma.hasOwnProperty(e)?{space:ma[e],local:n}:n}},da.attr=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node();return n=Xo.ns.qualify(n),n.local?e.getAttributeNS(n.space,n.local):e.getAttribute(n)}for(t in n)this.each(b(t,n[t]));return this}return this.each(b(n,t))},da.classed=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node(),r=(n=k(n)).length,u=-1;if(t=e.classList){for(;++u<r;)if(!t.contains(n[u]))return!1}else for(t=e.getAttribute("class");++u<r;)if(!S(n[u]).test(t))return!1;return!0}for(t in n)this.each(E(t,n[t]));return this}return this.each(E(n,t))},da.style=function(n,t,e){var r=arguments.length;if(3>r){if("string"!=typeof n){2>r&&(t="");for(e in n)this.each(C(e,n[e],t));return this}if(2>r)return Go.getComputedStyle(this.node(),null).getPropertyValue(n);e=""}return this.each(C(n,t,e))},da.property=function(n,t){if(arguments.length<2){if("string"==typeof n)return this.node()[n];for(t in n)this.each(N(t,n[t]));return this}return this.each(N(n,t))},da.text=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.textContent=null==t?"":t}:null==n?function(){this.textContent=""}:function(){this.textContent=n}):this.node().textContent},da.html=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.innerHTML=null==t?"":t}:null==n?function(){this.innerHTML=""}:function(){this.innerHTML=n}):this.node().innerHTML},da.append=function(n){return n=L(n),this.select(function(){return this.appendChild(n.apply(this,arguments))})},da.insert=function(n,t){return n=L(n),t=M(t),this.select(function(){return this.insertBefore(n.apply(this,arguments),t.apply(this,arguments)||null)})},da.remove=function(){return this.each(function(){var n=this.parentNode;n&&n.removeChild(this)})},da.data=function(n,t){function e(n,e){var r,i,o,a=n.length,f=e.length,h=Math.min(a,f),g=new Array(f),p=new Array(f),v=new Array(a);if(t){var d,m=new u,y=new u,x=[];for(r=-1;++r<a;)d=t.call(i=n[r],i.__data__,r),m.has(d)?v[r]=i:m.set(d,i),x.push(d);for(r=-1;++r<f;)d=t.call(e,o=e[r],r),(i=m.get(d))?(g[r]=i,i.__data__=o):y.has(d)||(p[r]=z(o)),y.set(d,o),m.remove(d);for(r=-1;++r<a;)m.has(x[r])&&(v[r]=n[r])}else{for(r=-1;++r<h;)i=n[r],o=e[r],i?(i.__data__=o,g[r]=i):p[r]=z(o);for(;f>r;++r)p[r]=z(e[r]);for(;a>r;++r)v[r]=n[r]}p.update=g,p.parentNode=g.parentNode=v.parentNode=n.parentNode,c.push(p),s.push(g),l.push(v)}var r,i,o=-1,a=this.length;if(!arguments.length){for(n=new Array(a=(r=this[0]).length);++o<a;)(i=r[o])&&(n[o]=i.__data__);return n}var c=D([]),s=x([]),l=x([]);if("function"==typeof n)for(;++o<a;)e(r=this[o],n.call(r,r.parentNode.__data__,o));else for(;++o<a;)e(r=this[o],n);return s.enter=function(){return c},s.exit=function(){return l},s},da.datum=function(n){return arguments.length?this.property("__data__",n):this.property("__data__")},da.filter=function(n){var t,e,r,u=[];"function"!=typeof n&&(n=q(n));for(var i=0,o=this.length;o>i;i++){u.push(t=[]),t.parentNode=(e=this[i]).parentNode;for(var a=0,c=e.length;c>a;a++)(r=e[a])&&n.call(r,r.__data__,a,i)&&t.push(r)}return x(u)},da.order=function(){for(var n=-1,t=this.length;++n<t;)for(var e,r=this[n],u=r.length-1,i=r[u];--u>=0;)(e=r[u])&&(i&&i!==e.nextSibling&&i.parentNode.insertBefore(e,i),i=e);return this},da.sort=function(n){n=T.apply(this,arguments);for(var t=-1,e=this.length;++t<e;)this[t].sort(n);return this.order()},da.each=function(n){return R(this,function(t,e,r){n.call(t,t.__data__,e,r)})},da.call=function(n){var t=Bo(arguments);return n.apply(t[0]=this,t),this},da.empty=function(){return!this.node()},da.node=function(){for(var n=0,t=this.length;t>n;n++)for(var e=this[n],r=0,u=e.length;u>r;r++){var i=e[r];if(i)return i}return null},da.size=function(){var n=0;return this.each(function(){++n}),n};var ya=[];Xo.selection.enter=D,Xo.selection.enter.prototype=ya,ya.append=da.append,ya.empty=da.empty,ya.node=da.node,ya.call=da.call,ya.size=da.size,ya.select=function(n){for(var t,e,r,u,i,o=[],a=-1,c=this.length;++a<c;){r=(u=this[a]).update,o.push(t=[]),t.parentNode=u.parentNode;for(var s=-1,l=u.length;++s<l;)(i=u[s])?(t.push(r[s]=e=n.call(u.parentNode,i.__data__,s,a)),e.__data__=i.__data__):t.push(null)}return x(o)},ya.insert=function(n,t){return arguments.length<2&&(t=P(this)),da.insert.call(this,n,t)},da.transition=function(){for(var n,t,e=ks||++Ls,r=[],u=Es||{time:Date.now(),ease:yu,delay:0,duration:250},i=-1,o=this.length;++i<o;){r.push(n=[]);for(var a=this[i],c=-1,s=a.length;++c<s;)(t=a[c])&&jo(t,c,e,u),n.push(t)}return Do(r,e)},da.interrupt=function(){return this.each(U)},Xo.select=function(n){var t=["string"==typeof n?ha(n,Wo):n];return t.parentNode=Jo,x([t])},Xo.selectAll=function(n){var t=Bo("string"==typeof n?ga(n,Wo):n);return t.parentNode=Jo,x([t])};var xa=Xo.select(Jo);da.on=function(n,t,e){var r=arguments.length;if(3>r){if("string"!=typeof n){2>r&&(t=!1);for(e in n)this.each(j(e,n[e],t));return this}if(2>r)return(r=this.node()["__on"+n])&&r._;e=!1}return this.each(j(n,t,e))};var Ma=Xo.map({mouseenter:"mouseover",mouseleave:"mouseout"});Ma.forEach(function(n){"on"+n in Wo&&Ma.remove(n)});var _a="onselectstart"in Wo?null:h(Jo.style,"userSelect"),ba=0;Xo.mouse=function(n){return Y(n,m())};var wa=/WebKit/.test(Go.navigator.userAgent)?-1:0;Xo.touches=function(n,t){return arguments.length<2&&(t=m().touches),t?Bo(t).map(function(t){var e=Y(n,t);return e.identifier=t.identifier,e}):[]},Xo.behavior.drag=function(){function n(){this.on("mousedown.drag",o).on("touchstart.drag",a)}function t(){return Xo.event.changedTouches[0].identifier}function e(n,t){return Xo.touches(n).filter(function(n){return n.identifier===t})[0]}function r(n,t,e,r){return function(){function o(){var n=t(l,g),e=n[0]-v[0],r=n[1]-v[1];d|=e|r,v=n,f({type:"drag",x:n[0]+c[0],y:n[1]+c[1],dx:e,dy:r})}function a(){m.on(e+"."+p,null).on(r+"."+p,null),y(d&&Xo.event.target===h),f({type:"dragend"})}var c,s=this,l=s.parentNode,f=u.of(s,arguments),h=Xo.event.target,g=n(),p=null==g?"drag":"drag-"+g,v=t(l,g),d=0,m=Xo.select(Go).on(e+"."+p,o).on(r+"."+p,a),y=O();i?(c=i.apply(s,arguments),c=[c.x-v[0],c.y-v[1]]):c=[0,0],f({type:"dragstart"})}}var u=y(n,"drag","dragstart","dragend"),i=null,o=r(g,Xo.mouse,"mousemove","mouseup"),a=r(t,e,"touchmove","touchend");return n.origin=function(t){return arguments.length?(i=t,n):i},Xo.rebind(n,u,"on")};var Sa=Math.PI,ka=2*Sa,Ea=Sa/2,Aa=1e-6,Ca=Aa*Aa,Na=Sa/180,La=180/Sa,za=Math.SQRT2,qa=2,Ta=4;Xo.interpolateZoom=function(n,t){function e(n){var t=n*y;if(m){var e=B(v),o=i/(qa*h)*(e*W(za*t+v)-$(v));return[r+o*s,u+o*l,i*e/B(za*t+v)]}return[r+n*s,u+n*l,i*Math.exp(za*t)]}var r=n[0],u=n[1],i=n[2],o=t[0],a=t[1],c=t[2],s=o-r,l=a-u,f=s*s+l*l,h=Math.sqrt(f),g=(c*c-i*i+Ta*f)/(2*i*qa*h),p=(c*c-i*i-Ta*f)/(2*c*qa*h),v=Math.log(Math.sqrt(g*g+1)-g),d=Math.log(Math.sqrt(p*p+1)-p),m=d-v,y=(m||Math.log(c/i))/za;return e.duration=1e3*y,e},Xo.behavior.zoom=function(){function n(n){n.on(A,s).on(Pa+".zoom",f).on(C,h).on("dblclick.zoom",g).on(L,l)}function t(n){return[(n[0]-S.x)/S.k,(n[1]-S.y)/S.k]}function e(n){return[n[0]*S.k+S.x,n[1]*S.k+S.y]}function r(n){S.k=Math.max(E[0],Math.min(E[1],n))}function u(n,t){t=e(t),S.x+=n[0]-t[0],S.y+=n[1]-t[1]}function i(){_&&_.domain(M.range().map(function(n){return(n-S.x)/S.k}).map(M.invert)),w&&w.domain(b.range().map(function(n){return(n-S.y)/S.k}).map(b.invert))}function o(n){n({type:"zoomstart"})}function a(n){i(),n({type:"zoom",scale:S.k,translate:[S.x,S.y]})}function c(n){n({type:"zoomend"})}function s(){function n(){l=1,u(Xo.mouse(r),g),a(i)}function e(){f.on(C,Go===r?h:null).on(N,null),p(l&&Xo.event.target===s),c(i)}var r=this,i=z.of(r,arguments),s=Xo.event.target,l=0,f=Xo.select(Go).on(C,n).on(N,e),g=t(Xo.mouse(r)),p=O();U.call(r),o(i)}function l(){function n(){var n=Xo.touches(g);return h=S.k,n.forEach(function(n){n.identifier in v&&(v[n.identifier]=t(n))}),n}function e(){for(var t=Xo.event.changedTouches,e=0,i=t.length;i>e;++e)v[t[e].identifier]=null;var o=n(),c=Date.now();if(1===o.length){if(500>c-x){var s=o[0],l=v[s.identifier];r(2*S.k),u(s,l),d(),a(p)}x=c}else if(o.length>1){var s=o[0],f=o[1],h=s[0]-f[0],g=s[1]-f[1];m=h*h+g*g}}function i(){for(var n,t,e,i,o=Xo.touches(g),c=0,s=o.length;s>c;++c,i=null)if(e=o[c],i=v[e.identifier]){if(t)break;n=e,t=i}if(i){var l=(l=e[0]-n[0])*l+(l=e[1]-n[1])*l,f=m&&Math.sqrt(l/m);n=[(n[0]+e[0])/2,(n[1]+e[1])/2],t=[(t[0]+i[0])/2,(t[1]+i[1])/2],r(f*h)}x=null,u(n,t),a(p)}function f(){if(Xo.event.touches.length){for(var t=Xo.event.changedTouches,e=0,r=t.length;r>e;++e)delete v[t[e].identifier];for(var u in v)return void n()}b.on(M,null).on(_,null),w.on(A,s).on(L,l),k(),c(p)}var h,g=this,p=z.of(g,arguments),v={},m=0,y=Xo.event.changedTouches[0].identifier,M="touchmove.zoom-"+y,_="touchend.zoom-"+y,b=Xo.select(Go).on(M,i).on(_,f),w=Xo.select(g).on(A,null).on(L,e),k=O();U.call(g),e(),o(p)}function f(){var n=z.of(this,arguments);m?clearTimeout(m):(U.call(this),o(n)),m=setTimeout(function(){m=null,c(n)},50),d();var e=v||Xo.mouse(this);p||(p=t(e)),r(Math.pow(2,.002*Ra())*S.k),u(e,p),a(n)}function h(){p=null}function g(){var n=z.of(this,arguments),e=Xo.mouse(this),i=t(e),s=Math.log(S.k)/Math.LN2;o(n),r(Math.pow(2,Xo.event.shiftKey?Math.ceil(s)-1:Math.floor(s)+1)),u(e,i),a(n),c(n)}var p,v,m,x,M,_,b,w,S={x:0,y:0,k:1},k=[960,500],E=Da,A="mousedown.zoom",C="mousemove.zoom",N="mouseup.zoom",L="touchstart.zoom",z=y(n,"zoomstart","zoom","zoomend");return n.event=function(n){n.each(function(){var n=z.of(this,arguments),t=S;ks?Xo.select(this).transition().each("start.zoom",function(){S=this.__chart__||{x:0,y:0,k:1},o(n)}).tween("zoom:zoom",function(){var e=k[0],r=k[1],u=e/2,i=r/2,o=Xo.interpolateZoom([(u-S.x)/S.k,(i-S.y)/S.k,e/S.k],[(u-t.x)/t.k,(i-t.y)/t.k,e/t.k]);return function(t){var r=o(t),c=e/r[2];this.__chart__=S={x:u-r[0]*c,y:i-r[1]*c,k:c},a(n)}}).each("end.zoom",function(){c(n)}):(this.__chart__=S,o(n),a(n),c(n))})},n.translate=function(t){return arguments.length?(S={x:+t[0],y:+t[1],k:S.k},i(),n):[S.x,S.y]},n.scale=function(t){return arguments.length?(S={x:S.x,y:S.y,k:+t},i(),n):S.k},n.scaleExtent=function(t){return arguments.length?(E=null==t?Da:[+t[0],+t[1]],n):E},n.center=function(t){return arguments.length?(v=t&&[+t[0],+t[1]],n):v},n.size=function(t){return arguments.length?(k=t&&[+t[0],+t[1]],n):k},n.x=function(t){return arguments.length?(_=t,M=t.copy(),S={x:0,y:0,k:1},n):_},n.y=function(t){return arguments.length?(w=t,b=t.copy(),S={x:0,y:0,k:1},n):w},Xo.rebind(n,z,"on")};var Ra,Da=[0,1/0],Pa="onwheel"in Wo?(Ra=function(){return-Xo.event.deltaY*(Xo.event.deltaMode?120:1)},"wheel"):"onmousewheel"in Wo?(Ra=function(){return Xo.event.wheelDelta},"mousewheel"):(Ra=function(){return-Xo.event.detail},"MozMousePixelScroll");G.prototype.toString=function(){return this.rgb()+""},Xo.hsl=function(n,t,e){return 1===arguments.length?n instanceof Q?K(n.h,n.s,n.l):dt(""+n,mt,K):K(+n,+t,+e)};var Ua=Q.prototype=new G;Ua.brighter=function(n){return n=Math.pow(.7,arguments.length?n:1),K(this.h,this.s,this.l/n)},Ua.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),K(this.h,this.s,n*this.l)},Ua.rgb=function(){return nt(this.h,this.s,this.l)},Xo.hcl=function(n,t,e){return 1===arguments.length?n instanceof et?tt(n.h,n.c,n.l):n instanceof it?at(n.l,n.a,n.b):at((n=yt((n=Xo.rgb(n)).r,n.g,n.b)).l,n.a,n.b):tt(+n,+t,+e)};var ja=et.prototype=new G;ja.brighter=function(n){return tt(this.h,this.c,Math.min(100,this.l+Ha*(arguments.length?n:1)))},ja.darker=function(n){return tt(this.h,this.c,Math.max(0,this.l-Ha*(arguments.length?n:1)))},ja.rgb=function(){return rt(this.h,this.c,this.l).rgb()},Xo.lab=function(n,t,e){return 1===arguments.length?n instanceof it?ut(n.l,n.a,n.b):n instanceof et?rt(n.l,n.c,n.h):yt((n=Xo.rgb(n)).r,n.g,n.b):ut(+n,+t,+e)};var Ha=18,Fa=.95047,Oa=1,Ya=1.08883,Ia=it.prototype=new G;Ia.brighter=function(n){return ut(Math.min(100,this.l+Ha*(arguments.length?n:1)),this.a,this.b)},Ia.darker=function(n){return ut(Math.max(0,this.l-Ha*(arguments.length?n:1)),this.a,this.b)},Ia.rgb=function(){return ot(this.l,this.a,this.b)},Xo.rgb=function(n,t,e){return 1===arguments.length?n instanceof pt?gt(n.r,n.g,n.b):dt(""+n,gt,nt):gt(~~n,~~t,~~e)};var Za=pt.prototype=new G;Za.brighter=function(n){n=Math.pow(.7,arguments.length?n:1);var t=this.r,e=this.g,r=this.b,u=30;return t||e||r?(t&&u>t&&(t=u),e&&u>e&&(e=u),r&&u>r&&(r=u),gt(Math.min(255,~~(t/n)),Math.min(255,~~(e/n)),Math.min(255,~~(r/n)))):gt(u,u,u)},Za.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),gt(~~(n*this.r),~~(n*this.g),~~(n*this.b))},Za.hsl=function(){return mt(this.r,this.g,this.b)},Za.toString=function(){return"#"+vt(this.r)+vt(this.g)+vt(this.b)};var Va=Xo.map({aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074});Va.forEach(function(n,t){Va.set(n,ft(t))}),Xo.functor=_t,Xo.xhr=wt(bt),Xo.dsv=function(n,t){function e(n,e,i){arguments.length<3&&(i=e,e=null);var o=St(n,t,null==e?r:u(e),i);return o.row=function(n){return arguments.length?o.response(null==(e=n)?r:u(n)):e},o}function r(n){return e.parse(n.responseText)}function u(n){return function(t){return e.parse(t.responseText,n)}}function i(t){return t.map(o).join(n)}function o(n){return a.test(n)?'"'+n.replace(/\"/g,'""')+'"':n}var a=new RegExp('["'+n+"\n]"),c=n.charCodeAt(0);return e.parse=function(n,t){var r;return e.parseRows(n,function(n,e){if(r)return r(n,e-1);var u=new Function("d","return {"+n.map(function(n,t){return JSON.stringify(n)+": d["+t+"]"}).join(",")+"}");r=t?function(n,e){return t(u(n),e)}:u})},e.parseRows=function(n,t){function e(){if(l>=s)return o;if(u)return u=!1,i;var t=l;if(34===n.charCodeAt(t)){for(var e=t;e++<s;)if(34===n.charCodeAt(e)){if(34!==n.charCodeAt(e+1))break;++e}l=e+2;var r=n.charCodeAt(e+1);return 13===r?(u=!0,10===n.charCodeAt(e+2)&&++l):10===r&&(u=!0),n.substring(t+1,e).replace(/""/g,'"')}for(;s>l;){var r=n.charCodeAt(l++),a=1;if(10===r)u=!0;else if(13===r)u=!0,10===n.charCodeAt(l)&&(++l,++a);else if(r!==c)continue;return n.substring(t,l-a)}return n.substring(t)}for(var r,u,i={},o={},a=[],s=n.length,l=0,f=0;(r=e())!==o;){for(var h=[];r!==i&&r!==o;)h.push(r),r=e();(!t||(h=t(h,f++)))&&a.push(h)}return a},e.format=function(t){if(Array.isArray(t[0]))return e.formatRows(t);var r=new l,u=[];return t.forEach(function(n){for(var t in n)r.has(t)||u.push(r.add(t))}),[u.map(o).join(n)].concat(t.map(function(t){return u.map(function(n){return o(t[n])}).join(n)})).join("\n")},e.formatRows=function(n){return n.map(i).join("\n")},e},Xo.csv=Xo.dsv(",","text/csv"),Xo.tsv=Xo.dsv(" ","text/tab-separated-values");var Xa,$a,Ba,Wa,Ja,Ga=Go[h(Go,"requestAnimationFrame")]||function(n){setTimeout(n,17)};Xo.timer=function(n,t,e){var r=arguments.length;2>r&&(t=0),3>r&&(e=Date.now());var u=e+t,i={c:n,t:u,f:!1,n:null};$a?$a.n=i:Xa=i,$a=i,Ba||(Wa=clearTimeout(Wa),Ba=1,Ga(Et))},Xo.timer.flush=function(){At(),Ct()},Xo.round=function(n,t){return t?Math.round(n*(t=Math.pow(10,t)))/t:Math.round(n)};var Ka=["y","z","a","f","p","n","\xb5","m","","k","M","G","T","P","E","Z","Y"].map(Lt);Xo.formatPrefix=function(n,t){var e=0;return n&&(0>n&&(n*=-1),t&&(n=Xo.round(n,Nt(n,t))),e=1+Math.floor(1e-12+Math.log(n)/Math.LN10),e=Math.max(-24,Math.min(24,3*Math.floor((0>=e?e+1:e-1)/3)))),Ka[8+e/3]};var Qa=/(?:([^{])?([<>=^]))?([+\- ])?([$#])?(0)?(\d+)?(,)?(\.-?\d+)?([a-z%])?/i,nc=Xo.map({b:function(n){return n.toString(2)},c:function(n){return String.fromCharCode(n)},o:function(n){return n.toString(8)},x:function(n){return n.toString(16)},X:function(n){return n.toString(16).toUpperCase()},g:function(n,t){return n.toPrecision(t)},e:function(n,t){return n.toExponential(t)},f:function(n,t){return n.toFixed(t)},r:function(n,t){return(n=Xo.round(n,Nt(n,t))).toFixed(Math.max(0,Math.min(20,Nt(n*(1+1e-15),t))))}}),tc=Xo.time={},ec=Date;Tt.prototype={getDate:function(){return this._.getUTCDate()},getDay:function(){return this._.getUTCDay()},getFullYear:function(){return this._.getUTCFullYear()},getHours:function(){return this._.getUTCHours()},getMilliseconds:function(){return this._.getUTCMilliseconds()},getMinutes:function(){return this._.getUTCMinutes()},getMonth:function(){return this._.getUTCMonth()},getSeconds:function(){return this._.getUTCSeconds()},getTime:function(){return this._.getTime()},getTimezoneOffset:function(){return 0},valueOf:function(){return this._.valueOf()},setDate:function(){rc.setUTCDate.apply(this._,arguments)},setDay:function(){rc.setUTCDay.apply(this._,arguments)},setFullYear:function(){rc.setUTCFullYear.apply(this._,arguments)},setHours:function(){rc.setUTCHours.apply(this._,arguments)},setMilliseconds:function(){rc.setUTCMilliseconds.apply(this._,arguments)},setMinutes:function(){rc.setUTCMinutes.apply(this._,arguments)},setMonth:function(){rc.setUTCMonth.apply(this._,arguments)},setSeconds:function(){rc.setUTCSeconds.apply(this._,arguments)},setTime:function(){rc.setTime.apply(this._,arguments)}};var rc=Date.prototype;tc.year=Rt(function(n){return n=tc.day(n),n.setMonth(0,1),n},function(n,t){n.setFullYear(n.getFullYear()+t)},function(n){return n.getFullYear()}),tc.years=tc.year.range,tc.years.utc=tc.year.utc.range,tc.day=Rt(function(n){var t=new ec(2e3,0);return t.setFullYear(n.getFullYear(),n.getMonth(),n.getDate()),t},function(n,t){n.setDate(n.getDate()+t)},function(n){return n.getDate()-1}),tc.days=tc.day.range,tc.days.utc=tc.day.utc.range,tc.dayOfYear=function(n){var t=tc.year(n);return Math.floor((n-t-6e4*(n.getTimezoneOffset()-t.getTimezoneOffset()))/864e5)},["sunday","monday","tuesday","wednesday","thursday","friday","saturday"].forEach(function(n,t){t=7-t;var e=tc[n]=Rt(function(n){return(n=tc.day(n)).setDate(n.getDate()-(n.getDay()+t)%7),n},function(n,t){n.setDate(n.getDate()+7*Math.floor(t))},function(n){var e=tc.year(n).getDay();return Math.floor((tc.dayOfYear(n)+(e+t)%7)/7)-(e!==t)});tc[n+"s"]=e.range,tc[n+"s"].utc=e.utc.range,tc[n+"OfYear"]=function(n){var e=tc.year(n).getDay();return Math.floor((tc.dayOfYear(n)+(e+t)%7)/7)}}),tc.week=tc.sunday,tc.weeks=tc.sunday.range,tc.weeks.utc=tc.sunday.utc.range,tc.weekOfYear=tc.sundayOfYear;var uc={"-":"",_:" ",0:"0"},ic=/^\s*\d+/,oc=/^%/;Xo.locale=function(n){return{numberFormat:zt(n),timeFormat:Pt(n)}};var ac=Xo.locale({decimal:".",thousands:",",grouping:[3],currency:["$",""],dateTime:"%a %b %e %X %Y",date:"%m/%d/%Y",time:"%H:%M:%S",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]});Xo.format=ac.numberFormat,Xo.geo={},re.prototype={s:0,t:0,add:function(n){ue(n,this.t,cc),ue(cc.s,this.s,this),this.s?this.t+=cc.t:this.s=cc.t},reset:function(){this.s=this.t=0},valueOf:function(){return this.s}};var cc=new re;Xo.geo.stream=function(n,t){n&&sc.hasOwnProperty(n.type)?sc[n.type](n,t):ie(n,t)};var sc={Feature:function(n,t){ie(n.geometry,t)},FeatureCollection:function(n,t){for(var e=n.features,r=-1,u=e.length;++r<u;)ie(e[r].geometry,t)}},lc={Sphere:function(n,t){t.sphere()},Point:function(n,t){n=n.coordinates,t.point(n[0],n[1],n[2])},MultiPoint:function(n,t){for(var e=n.coordinates,r=-1,u=e.length;++r<u;)n=e[r],t.point(n[0],n[1],n[2])},LineString:function(n,t){oe(n.coordinates,t,0)},MultiLineString:function(n,t){for(var e=n.coordinates,r=-1,u=e.length;++r<u;)oe(e[r],t,0)},Polygon:function(n,t){ae(n.coordinates,t)},MultiPolygon:function(n,t){for(var e=n.coordinates,r=-1,u=e.length;++r<u;)ae(e[r],t)},GeometryCollection:function(n,t){for(var e=n.geometries,r=-1,u=e.length;++r<u;)ie(e[r],t)}};Xo.geo.area=function(n){return fc=0,Xo.geo.stream(n,gc),fc};var fc,hc=new re,gc={sphere:function(){fc+=4*Sa},point:g,lineStart:g,lineEnd:g,polygonStart:function(){hc.reset(),gc.lineStart=ce},polygonEnd:function(){var n=2*hc;fc+=0>n?4*Sa+n:n,gc.lineStart=gc.lineEnd=gc.point=g}};Xo.geo.bounds=function(){function n(n,t){x.push(M=[l=n,h=n]),f>t&&(f=t),t>g&&(g=t)}function t(t,e){var r=se([t*Na,e*Na]);if(m){var u=fe(m,r),i=[u[1],-u[0],0],o=fe(i,u);pe(o),o=ve(o);var c=t-p,s=c>0?1:-1,v=o[0]*La*s,d=oa(c)>180;if(d^(v>s*p&&s*t>v)){var y=o[1]*La;y>g&&(g=y)}else if(v=(v+360)%360-180,d^(v>s*p&&s*t>v)){var y=-o[1]*La;f>y&&(f=y)}else f>e&&(f=e),e>g&&(g=e);d?p>t?a(l,t)>a(l,h)&&(h=t):a(t,h)>a(l,h)&&(l=t):h>=l?(l>t&&(l=t),t>h&&(h=t)):t>p?a(l,t)>a(l,h)&&(h=t):a(t,h)>a(l,h)&&(l=t)}else n(t,e);m=r,p=t}function e(){_.point=t}function r(){M[0]=l,M[1]=h,_.point=n,m=null}function u(n,e){if(m){var r=n-p;y+=oa(r)>180?r+(r>0?360:-360):r}else v=n,d=e;gc.point(n,e),t(n,e)}function i(){gc.lineStart()}function o(){u(v,d),gc.lineEnd(),oa(y)>Aa&&(l=-(h=180)),M[0]=l,M[1]=h,m=null}function a(n,t){return(t-=n)<0?t+360:t}function c(n,t){return n[0]-t[0]}function s(n,t){return t[0]<=t[1]?t[0]<=n&&n<=t[1]:n<t[0]||t[1]<n}var l,f,h,g,p,v,d,m,y,x,M,_={point:n,lineStart:e,lineEnd:r,polygonStart:function(){_.point=u,_.lineStart=i,_.lineEnd=o,y=0,gc.polygonStart()},polygonEnd:function(){gc.polygonEnd(),_.point=n,_.lineStart=e,_.lineEnd=r,0>hc?(l=-(h=180),f=-(g=90)):y>Aa?g=90:-Aa>y&&(f=-90),M[0]=l,M[1]=h -}};return function(n){g=h=-(l=f=1/0),x=[],Xo.geo.stream(n,_);var t=x.length;if(t){x.sort(c);for(var e,r=1,u=x[0],i=[u];t>r;++r)e=x[r],s(e[0],u)||s(e[1],u)?(a(u[0],e[1])>a(u[0],u[1])&&(u[1]=e[1]),a(e[0],u[1])>a(u[0],u[1])&&(u[0]=e[0])):i.push(u=e);for(var o,e,p=-1/0,t=i.length-1,r=0,u=i[t];t>=r;u=e,++r)e=i[r],(o=a(u[1],e[0]))>p&&(p=o,l=e[0],h=u[1])}return x=M=null,1/0===l||1/0===f?[[0/0,0/0],[0/0,0/0]]:[[l,f],[h,g]]}}(),Xo.geo.centroid=function(n){pc=vc=dc=mc=yc=xc=Mc=_c=bc=wc=Sc=0,Xo.geo.stream(n,kc);var t=bc,e=wc,r=Sc,u=t*t+e*e+r*r;return Ca>u&&(t=xc,e=Mc,r=_c,Aa>vc&&(t=dc,e=mc,r=yc),u=t*t+e*e+r*r,Ca>u)?[0/0,0/0]:[Math.atan2(e,t)*La,X(r/Math.sqrt(u))*La]};var pc,vc,dc,mc,yc,xc,Mc,_c,bc,wc,Sc,kc={sphere:g,point:me,lineStart:xe,lineEnd:Me,polygonStart:function(){kc.lineStart=_e},polygonEnd:function(){kc.lineStart=xe}},Ec=Ee(be,ze,Te,[-Sa,-Sa/2]),Ac=1e9;Xo.geo.clipExtent=function(){var n,t,e,r,u,i,o={stream:function(n){return u&&(u.valid=!1),u=i(n),u.valid=!0,u},extent:function(a){return arguments.length?(i=Pe(n=+a[0][0],t=+a[0][1],e=+a[1][0],r=+a[1][1]),u&&(u.valid=!1,u=null),o):[[n,t],[e,r]]}};return o.extent([[0,0],[960,500]])},(Xo.geo.conicEqualArea=function(){return je(He)}).raw=He,Xo.geo.albers=function(){return Xo.geo.conicEqualArea().rotate([96,0]).center([-.6,38.7]).parallels([29.5,45.5]).scale(1070)},Xo.geo.albersUsa=function(){function n(n){var i=n[0],o=n[1];return t=null,e(i,o),t||(r(i,o),t)||u(i,o),t}var t,e,r,u,i=Xo.geo.albers(),o=Xo.geo.conicEqualArea().rotate([154,0]).center([-2,58.5]).parallels([55,65]),a=Xo.geo.conicEqualArea().rotate([157,0]).center([-3,19.9]).parallels([8,18]),c={point:function(n,e){t=[n,e]}};return n.invert=function(n){var t=i.scale(),e=i.translate(),r=(n[0]-e[0])/t,u=(n[1]-e[1])/t;return(u>=.12&&.234>u&&r>=-.425&&-.214>r?o:u>=.166&&.234>u&&r>=-.214&&-.115>r?a:i).invert(n)},n.stream=function(n){var t=i.stream(n),e=o.stream(n),r=a.stream(n);return{point:function(n,u){t.point(n,u),e.point(n,u),r.point(n,u)},sphere:function(){t.sphere(),e.sphere(),r.sphere()},lineStart:function(){t.lineStart(),e.lineStart(),r.lineStart()},lineEnd:function(){t.lineEnd(),e.lineEnd(),r.lineEnd()},polygonStart:function(){t.polygonStart(),e.polygonStart(),r.polygonStart()},polygonEnd:function(){t.polygonEnd(),e.polygonEnd(),r.polygonEnd()}}},n.precision=function(t){return arguments.length?(i.precision(t),o.precision(t),a.precision(t),n):i.precision()},n.scale=function(t){return arguments.length?(i.scale(t),o.scale(.35*t),a.scale(t),n.translate(i.translate())):i.scale()},n.translate=function(t){if(!arguments.length)return i.translate();var s=i.scale(),l=+t[0],f=+t[1];return e=i.translate(t).clipExtent([[l-.455*s,f-.238*s],[l+.455*s,f+.238*s]]).stream(c).point,r=o.translate([l-.307*s,f+.201*s]).clipExtent([[l-.425*s+Aa,f+.12*s+Aa],[l-.214*s-Aa,f+.234*s-Aa]]).stream(c).point,u=a.translate([l-.205*s,f+.212*s]).clipExtent([[l-.214*s+Aa,f+.166*s+Aa],[l-.115*s-Aa,f+.234*s-Aa]]).stream(c).point,n},n.scale(1070)};var Cc,Nc,Lc,zc,qc,Tc,Rc={point:g,lineStart:g,lineEnd:g,polygonStart:function(){Nc=0,Rc.lineStart=Fe},polygonEnd:function(){Rc.lineStart=Rc.lineEnd=Rc.point=g,Cc+=oa(Nc/2)}},Dc={point:Oe,lineStart:g,lineEnd:g,polygonStart:g,polygonEnd:g},Pc={point:Ze,lineStart:Ve,lineEnd:Xe,polygonStart:function(){Pc.lineStart=$e},polygonEnd:function(){Pc.point=Ze,Pc.lineStart=Ve,Pc.lineEnd=Xe}};Xo.geo.path=function(){function n(n){return n&&("function"==typeof a&&i.pointRadius(+a.apply(this,arguments)),o&&o.valid||(o=u(i)),Xo.geo.stream(n,o)),i.result()}function t(){return o=null,n}var e,r,u,i,o,a=4.5;return n.area=function(n){return Cc=0,Xo.geo.stream(n,u(Rc)),Cc},n.centroid=function(n){return dc=mc=yc=xc=Mc=_c=bc=wc=Sc=0,Xo.geo.stream(n,u(Pc)),Sc?[bc/Sc,wc/Sc]:_c?[xc/_c,Mc/_c]:yc?[dc/yc,mc/yc]:[0/0,0/0]},n.bounds=function(n){return qc=Tc=-(Lc=zc=1/0),Xo.geo.stream(n,u(Dc)),[[Lc,zc],[qc,Tc]]},n.projection=function(n){return arguments.length?(u=(e=n)?n.stream||Je(n):bt,t()):e},n.context=function(n){return arguments.length?(i=null==(r=n)?new Ye:new Be(n),"function"!=typeof a&&i.pointRadius(a),t()):r},n.pointRadius=function(t){return arguments.length?(a="function"==typeof t?t:(i.pointRadius(+t),+t),n):a},n.projection(Xo.geo.albersUsa()).context(null)},Xo.geo.transform=function(n){return{stream:function(t){var e=new Ge(t);for(var r in n)e[r]=n[r];return e}}},Ge.prototype={point:function(n,t){this.stream.point(n,t)},sphere:function(){this.stream.sphere()},lineStart:function(){this.stream.lineStart()},lineEnd:function(){this.stream.lineEnd()},polygonStart:function(){this.stream.polygonStart()},polygonEnd:function(){this.stream.polygonEnd()}},Xo.geo.projection=Qe,Xo.geo.projectionMutator=nr,(Xo.geo.equirectangular=function(){return Qe(er)}).raw=er.invert=er,Xo.geo.rotation=function(n){function t(t){return t=n(t[0]*Na,t[1]*Na),t[0]*=La,t[1]*=La,t}return n=ur(n[0]%360*Na,n[1]*Na,n.length>2?n[2]*Na:0),t.invert=function(t){return t=n.invert(t[0]*Na,t[1]*Na),t[0]*=La,t[1]*=La,t},t},rr.invert=er,Xo.geo.circle=function(){function n(){var n="function"==typeof r?r.apply(this,arguments):r,t=ur(-n[0]*Na,-n[1]*Na,0).invert,u=[];return e(null,null,1,{point:function(n,e){u.push(n=t(n,e)),n[0]*=La,n[1]*=La}}),{type:"Polygon",coordinates:[u]}}var t,e,r=[0,0],u=6;return n.origin=function(t){return arguments.length?(r=t,n):r},n.angle=function(r){return arguments.length?(e=cr((t=+r)*Na,u*Na),n):t},n.precision=function(r){return arguments.length?(e=cr(t*Na,(u=+r)*Na),n):u},n.angle(90)},Xo.geo.distance=function(n,t){var e,r=(t[0]-n[0])*Na,u=n[1]*Na,i=t[1]*Na,o=Math.sin(r),a=Math.cos(r),c=Math.sin(u),s=Math.cos(u),l=Math.sin(i),f=Math.cos(i);return Math.atan2(Math.sqrt((e=f*o)*e+(e=s*l-c*f*a)*e),c*l+s*f*a)},Xo.geo.graticule=function(){function n(){return{type:"MultiLineString",coordinates:t()}}function t(){return Xo.range(Math.ceil(i/d)*d,u,d).map(h).concat(Xo.range(Math.ceil(s/m)*m,c,m).map(g)).concat(Xo.range(Math.ceil(r/p)*p,e,p).filter(function(n){return oa(n%d)>Aa}).map(l)).concat(Xo.range(Math.ceil(a/v)*v,o,v).filter(function(n){return oa(n%m)>Aa}).map(f))}var e,r,u,i,o,a,c,s,l,f,h,g,p=10,v=p,d=90,m=360,y=2.5;return n.lines=function(){return t().map(function(n){return{type:"LineString",coordinates:n}})},n.outline=function(){return{type:"Polygon",coordinates:[h(i).concat(g(c).slice(1),h(u).reverse().slice(1),g(s).reverse().slice(1))]}},n.extent=function(t){return arguments.length?n.majorExtent(t).minorExtent(t):n.minorExtent()},n.majorExtent=function(t){return arguments.length?(i=+t[0][0],u=+t[1][0],s=+t[0][1],c=+t[1][1],i>u&&(t=i,i=u,u=t),s>c&&(t=s,s=c,c=t),n.precision(y)):[[i,s],[u,c]]},n.minorExtent=function(t){return arguments.length?(r=+t[0][0],e=+t[1][0],a=+t[0][1],o=+t[1][1],r>e&&(t=r,r=e,e=t),a>o&&(t=a,a=o,o=t),n.precision(y)):[[r,a],[e,o]]},n.step=function(t){return arguments.length?n.majorStep(t).minorStep(t):n.minorStep()},n.majorStep=function(t){return arguments.length?(d=+t[0],m=+t[1],n):[d,m]},n.minorStep=function(t){return arguments.length?(p=+t[0],v=+t[1],n):[p,v]},n.precision=function(t){return arguments.length?(y=+t,l=lr(a,o,90),f=fr(r,e,y),h=lr(s,c,90),g=fr(i,u,y),n):y},n.majorExtent([[-180,-90+Aa],[180,90-Aa]]).minorExtent([[-180,-80-Aa],[180,80+Aa]])},Xo.geo.greatArc=function(){function n(){return{type:"LineString",coordinates:[t||r.apply(this,arguments),e||u.apply(this,arguments)]}}var t,e,r=hr,u=gr;return n.distance=function(){return Xo.geo.distance(t||r.apply(this,arguments),e||u.apply(this,arguments))},n.source=function(e){return arguments.length?(r=e,t="function"==typeof e?null:e,n):r},n.target=function(t){return arguments.length?(u=t,e="function"==typeof t?null:t,n):u},n.precision=function(){return arguments.length?n:0},n},Xo.geo.interpolate=function(n,t){return pr(n[0]*Na,n[1]*Na,t[0]*Na,t[1]*Na)},Xo.geo.length=function(n){return Uc=0,Xo.geo.stream(n,jc),Uc};var Uc,jc={sphere:g,point:g,lineStart:vr,lineEnd:g,polygonStart:g,polygonEnd:g},Hc=dr(function(n){return Math.sqrt(2/(1+n))},function(n){return 2*Math.asin(n/2)});(Xo.geo.azimuthalEqualArea=function(){return Qe(Hc)}).raw=Hc;var Fc=dr(function(n){var t=Math.acos(n);return t&&t/Math.sin(t)},bt);(Xo.geo.azimuthalEquidistant=function(){return Qe(Fc)}).raw=Fc,(Xo.geo.conicConformal=function(){return je(mr)}).raw=mr,(Xo.geo.conicEquidistant=function(){return je(yr)}).raw=yr;var Oc=dr(function(n){return 1/n},Math.atan);(Xo.geo.gnomonic=function(){return Qe(Oc)}).raw=Oc,xr.invert=function(n,t){return[n,2*Math.atan(Math.exp(t))-Ea]},(Xo.geo.mercator=function(){return Mr(xr)}).raw=xr;var Yc=dr(function(){return 1},Math.asin);(Xo.geo.orthographic=function(){return Qe(Yc)}).raw=Yc;var Ic=dr(function(n){return 1/(1+n)},function(n){return 2*Math.atan(n)});(Xo.geo.stereographic=function(){return Qe(Ic)}).raw=Ic,_r.invert=function(n,t){return[-t,2*Math.atan(Math.exp(n))-Ea]},(Xo.geo.transverseMercator=function(){var n=Mr(_r),t=n.center,e=n.rotate;return n.center=function(n){return n?t([-n[1],n[0]]):(n=t(),[-n[1],n[0]])},n.rotate=function(n){return n?e([n[0],n[1],n.length>2?n[2]+90:90]):(n=e(),[n[0],n[1],n[2]-90])},n.rotate([0,0])}).raw=_r,Xo.geom={},Xo.geom.hull=function(n){function t(n){if(n.length<3)return[];var t,u=_t(e),i=_t(r),o=n.length,a=[],c=[];for(t=0;o>t;t++)a.push([+u.call(this,n[t],t),+i.call(this,n[t],t),t]);for(a.sort(kr),t=0;o>t;t++)c.push([a[t][0],-a[t][1]]);var s=Sr(a),l=Sr(c),f=l[0]===s[0],h=l[l.length-1]===s[s.length-1],g=[];for(t=s.length-1;t>=0;--t)g.push(n[a[s[t]][2]]);for(t=+f;t<l.length-h;++t)g.push(n[a[l[t]][2]]);return g}var e=br,r=wr;return arguments.length?t(n):(t.x=function(n){return arguments.length?(e=n,t):e},t.y=function(n){return arguments.length?(r=n,t):r},t)},Xo.geom.polygon=function(n){return fa(n,Zc),n};var Zc=Xo.geom.polygon.prototype=[];Zc.area=function(){for(var n,t=-1,e=this.length,r=this[e-1],u=0;++t<e;)n=r,r=this[t],u+=n[1]*r[0]-n[0]*r[1];return.5*u},Zc.centroid=function(n){var t,e,r=-1,u=this.length,i=0,o=0,a=this[u-1];for(arguments.length||(n=-1/(6*this.area()));++r<u;)t=a,a=this[r],e=t[0]*a[1]-a[0]*t[1],i+=(t[0]+a[0])*e,o+=(t[1]+a[1])*e;return[i*n,o*n]},Zc.clip=function(n){for(var t,e,r,u,i,o,a=Cr(n),c=-1,s=this.length-Cr(this),l=this[s-1];++c<s;){for(t=n.slice(),n.length=0,u=this[c],i=t[(r=t.length-a)-1],e=-1;++e<r;)o=t[e],Er(o,l,u)?(Er(i,l,u)||n.push(Ar(i,o,l,u)),n.push(o)):Er(i,l,u)&&n.push(Ar(i,o,l,u)),i=o;a&&n.push(n[0]),l=u}return n};var Vc,Xc,$c,Bc,Wc,Jc=[],Gc=[];Pr.prototype.prepare=function(){for(var n,t=this.edges,e=t.length;e--;)n=t[e].edge,n.b&&n.a||t.splice(e,1);return t.sort(jr),t.length},Br.prototype={start:function(){return this.edge.l===this.site?this.edge.a:this.edge.b},end:function(){return this.edge.l===this.site?this.edge.b:this.edge.a}},Wr.prototype={insert:function(n,t){var e,r,u;if(n){if(t.P=n,t.N=n.N,n.N&&(n.N.P=t),n.N=t,n.R){for(n=n.R;n.L;)n=n.L;n.L=t}else n.R=t;e=n}else this._?(n=Qr(this._),t.P=null,t.N=n,n.P=n.L=t,e=n):(t.P=t.N=null,this._=t,e=null);for(t.L=t.R=null,t.U=e,t.C=!0,n=t;e&&e.C;)r=e.U,e===r.L?(u=r.R,u&&u.C?(e.C=u.C=!1,r.C=!0,n=r):(n===e.R&&(Gr(this,e),n=e,e=n.U),e.C=!1,r.C=!0,Kr(this,r))):(u=r.L,u&&u.C?(e.C=u.C=!1,r.C=!0,n=r):(n===e.L&&(Kr(this,e),n=e,e=n.U),e.C=!1,r.C=!0,Gr(this,r))),e=n.U;this._.C=!1},remove:function(n){n.N&&(n.N.P=n.P),n.P&&(n.P.N=n.N),n.N=n.P=null;var t,e,r,u=n.U,i=n.L,o=n.R;if(e=i?o?Qr(o):i:o,u?u.L===n?u.L=e:u.R=e:this._=e,i&&o?(r=e.C,e.C=n.C,e.L=i,i.U=e,e!==o?(u=e.U,e.U=n.U,n=e.R,u.L=n,e.R=o,o.U=e):(e.U=u,u=e,n=e.R)):(r=n.C,n=e),n&&(n.U=u),!r){if(n&&n.C)return n.C=!1,void 0;do{if(n===this._)break;if(n===u.L){if(t=u.R,t.C&&(t.C=!1,u.C=!0,Gr(this,u),t=u.R),t.L&&t.L.C||t.R&&t.R.C){t.R&&t.R.C||(t.L.C=!1,t.C=!0,Kr(this,t),t=u.R),t.C=u.C,u.C=t.R.C=!1,Gr(this,u),n=this._;break}}else if(t=u.L,t.C&&(t.C=!1,u.C=!0,Kr(this,u),t=u.L),t.L&&t.L.C||t.R&&t.R.C){t.L&&t.L.C||(t.R.C=!1,t.C=!0,Gr(this,t),t=u.L),t.C=u.C,u.C=t.L.C=!1,Kr(this,u),n=this._;break}t.C=!0,n=u,u=u.U}while(!n.C);n&&(n.C=!1)}}},Xo.geom.voronoi=function(n){function t(n){var t=new Array(n.length),r=a[0][0],u=a[0][1],i=a[1][0],o=a[1][1];return nu(e(n),a).cells.forEach(function(e,a){var c=e.edges,s=e.site,l=t[a]=c.length?c.map(function(n){var t=n.start();return[t.x,t.y]}):s.x>=r&&s.x<=i&&s.y>=u&&s.y<=o?[[r,o],[i,o],[i,u],[r,u]]:[];l.point=n[a]}),t}function e(n){return n.map(function(n,t){return{x:Math.round(i(n,t)/Aa)*Aa,y:Math.round(o(n,t)/Aa)*Aa,i:t}})}var r=br,u=wr,i=r,o=u,a=Kc;return n?t(n):(t.links=function(n){return nu(e(n)).edges.filter(function(n){return n.l&&n.r}).map(function(t){return{source:n[t.l.i],target:n[t.r.i]}})},t.triangles=function(n){var t=[];return nu(e(n)).cells.forEach(function(e,r){for(var u,i,o=e.site,a=e.edges.sort(jr),c=-1,s=a.length,l=a[s-1].edge,f=l.l===o?l.r:l.l;++c<s;)u=l,i=f,l=a[c].edge,f=l.l===o?l.r:l.l,r<i.i&&r<f.i&&eu(o,i,f)<0&&t.push([n[r],n[i.i],n[f.i]])}),t},t.x=function(n){return arguments.length?(i=_t(r=n),t):r},t.y=function(n){return arguments.length?(o=_t(u=n),t):u},t.clipExtent=function(n){return arguments.length?(a=null==n?Kc:n,t):a===Kc?null:a},t.size=function(n){return arguments.length?t.clipExtent(n&&[[0,0],n]):a===Kc?null:a&&a[1]},t)};var Kc=[[-1e6,-1e6],[1e6,1e6]];Xo.geom.delaunay=function(n){return Xo.geom.voronoi().triangles(n)},Xo.geom.quadtree=function(n,t,e,r,u){function i(n){function i(n,t,e,r,u,i,o,a){if(!isNaN(e)&&!isNaN(r))if(n.leaf){var c=n.x,l=n.y;if(null!=c)if(oa(c-e)+oa(l-r)<.01)s(n,t,e,r,u,i,o,a);else{var f=n.point;n.x=n.y=n.point=null,s(n,f,c,l,u,i,o,a),s(n,t,e,r,u,i,o,a)}else n.x=e,n.y=r,n.point=t}else s(n,t,e,r,u,i,o,a)}function s(n,t,e,r,u,o,a,c){var s=.5*(u+a),l=.5*(o+c),f=e>=s,h=r>=l,g=(h<<1)+f;n.leaf=!1,n=n.nodes[g]||(n.nodes[g]=iu()),f?u=s:a=s,h?o=l:c=l,i(n,t,e,r,u,o,a,c)}var l,f,h,g,p,v,d,m,y,x=_t(a),M=_t(c);if(null!=t)v=t,d=e,m=r,y=u;else if(m=y=-(v=d=1/0),f=[],h=[],p=n.length,o)for(g=0;p>g;++g)l=n[g],l.x<v&&(v=l.x),l.y<d&&(d=l.y),l.x>m&&(m=l.x),l.y>y&&(y=l.y),f.push(l.x),h.push(l.y);else for(g=0;p>g;++g){var _=+x(l=n[g],g),b=+M(l,g);v>_&&(v=_),d>b&&(d=b),_>m&&(m=_),b>y&&(y=b),f.push(_),h.push(b)}var w=m-v,S=y-d;w>S?y=d+w:m=v+S;var k=iu();if(k.add=function(n){i(k,n,+x(n,++g),+M(n,g),v,d,m,y)},k.visit=function(n){ou(n,k,v,d,m,y)},g=-1,null==t){for(;++g<p;)i(k,n[g],f[g],h[g],v,d,m,y);--g}else n.forEach(k.add);return f=h=n=l=null,k}var o,a=br,c=wr;return(o=arguments.length)?(a=ru,c=uu,3===o&&(u=e,r=t,e=t=0),i(n)):(i.x=function(n){return arguments.length?(a=n,i):a},i.y=function(n){return arguments.length?(c=n,i):c},i.extent=function(n){return arguments.length?(null==n?t=e=r=u=null:(t=+n[0][0],e=+n[0][1],r=+n[1][0],u=+n[1][1]),i):null==t?null:[[t,e],[r,u]]},i.size=function(n){return arguments.length?(null==n?t=e=r=u=null:(t=e=0,r=+n[0],u=+n[1]),i):null==t?null:[r-t,u-e]},i)},Xo.interpolateRgb=au,Xo.interpolateObject=cu,Xo.interpolateNumber=su,Xo.interpolateString=lu;var Qc=/[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g;Xo.interpolate=fu,Xo.interpolators=[function(n,t){var e=typeof t;return("string"===e?Va.has(t)||/^(#|rgb\(|hsl\()/.test(t)?au:lu:t instanceof G?au:"object"===e?Array.isArray(t)?hu:cu:su)(n,t)}],Xo.interpolateArray=hu;var ns=function(){return bt},ts=Xo.map({linear:ns,poly:xu,quad:function(){return du},cubic:function(){return mu},sin:function(){return Mu},exp:function(){return _u},circle:function(){return bu},elastic:wu,back:Su,bounce:function(){return ku}}),es=Xo.map({"in":bt,out:pu,"in-out":vu,"out-in":function(n){return vu(pu(n))}});Xo.ease=function(n){var t=n.indexOf("-"),e=t>=0?n.substring(0,t):n,r=t>=0?n.substring(t+1):"in";return e=ts.get(e)||ns,r=es.get(r)||bt,gu(r(e.apply(null,$o.call(arguments,1))))},Xo.interpolateHcl=Eu,Xo.interpolateHsl=Au,Xo.interpolateLab=Cu,Xo.interpolateRound=Nu,Xo.transform=function(n){var t=Wo.createElementNS(Xo.ns.prefix.svg,"g");return(Xo.transform=function(n){if(null!=n){t.setAttribute("transform",n);var e=t.transform.baseVal.consolidate()}return new Lu(e?e.matrix:rs)})(n)},Lu.prototype.toString=function(){return"translate("+this.translate+")rotate("+this.rotate+")skewX("+this.skew+")scale("+this.scale+")"};var rs={a:1,b:0,c:0,d:1,e:0,f:0};Xo.interpolateTransform=Ru,Xo.layout={},Xo.layout.bundle=function(){return function(n){for(var t=[],e=-1,r=n.length;++e<r;)t.push(Uu(n[e]));return t}},Xo.layout.chord=function(){function n(){var n,s,f,h,g,p={},v=[],d=Xo.range(i),m=[];for(e=[],r=[],n=0,h=-1;++h<i;){for(s=0,g=-1;++g<i;)s+=u[h][g];v.push(s),m.push(Xo.range(i)),n+=s}for(o&&d.sort(function(n,t){return o(v[n],v[t])}),a&&m.forEach(function(n,t){n.sort(function(n,e){return a(u[t][n],u[t][e])})}),n=(ka-l*i)/n,s=0,h=-1;++h<i;){for(f=s,g=-1;++g<i;){var y=d[h],x=m[y][g],M=u[y][x],_=s,b=s+=M*n;p[y+"-"+x]={index:y,subindex:x,startAngle:_,endAngle:b,value:M}}r[y]={index:y,startAngle:f,endAngle:s,value:(s-f)/n},s+=l}for(h=-1;++h<i;)for(g=h-1;++g<i;){var w=p[h+"-"+g],S=p[g+"-"+h];(w.value||S.value)&&e.push(w.value<S.value?{source:S,target:w}:{source:w,target:S})}c&&t()}function t(){e.sort(function(n,t){return c((n.source.value+n.target.value)/2,(t.source.value+t.target.value)/2)})}var e,r,u,i,o,a,c,s={},l=0;return s.matrix=function(n){return arguments.length?(i=(u=n)&&u.length,e=r=null,s):u},s.padding=function(n){return arguments.length?(l=n,e=r=null,s):l},s.sortGroups=function(n){return arguments.length?(o=n,e=r=null,s):o},s.sortSubgroups=function(n){return arguments.length?(a=n,e=null,s):a},s.sortChords=function(n){return arguments.length?(c=n,e&&t(),s):c},s.chords=function(){return e||n(),e},s.groups=function(){return r||n(),r},s},Xo.layout.force=function(){function n(n){return function(t,e,r,u){if(t.point!==n){var i=t.cx-n.x,o=t.cy-n.y,a=u-e,c=i*i+o*o;if(c>a*a/d){if(p>c){var s=t.charge/c;n.px-=i*s,n.py-=o*s}return!0}if(t.point&&c&&p>c){var s=t.pointCharge/c;n.px-=i*s,n.py-=o*s}}return!t.charge}}function t(n){n.px=Xo.event.x,n.py=Xo.event.y,a.resume()}var e,r,u,i,o,a={},c=Xo.dispatch("start","tick","end"),s=[1,1],l=.9,f=us,h=is,g=-30,p=os,v=.1,d=.64,m=[],y=[];return a.tick=function(){if((r*=.99)<.005)return c.end({type:"end",alpha:r=0}),!0;var t,e,a,f,h,p,d,x,M,_=m.length,b=y.length;for(e=0;b>e;++e)a=y[e],f=a.source,h=a.target,x=h.x-f.x,M=h.y-f.y,(p=x*x+M*M)&&(p=r*i[e]*((p=Math.sqrt(p))-u[e])/p,x*=p,M*=p,h.x-=x*(d=f.weight/(h.weight+f.weight)),h.y-=M*d,f.x+=x*(d=1-d),f.y+=M*d);if((d=r*v)&&(x=s[0]/2,M=s[1]/2,e=-1,d))for(;++e<_;)a=m[e],a.x+=(x-a.x)*d,a.y+=(M-a.y)*d;if(g)for(Zu(t=Xo.geom.quadtree(m),r,o),e=-1;++e<_;)(a=m[e]).fixed||t.visit(n(a));for(e=-1;++e<_;)a=m[e],a.fixed?(a.x=a.px,a.y=a.py):(a.x-=(a.px-(a.px=a.x))*l,a.y-=(a.py-(a.py=a.y))*l);c.tick({type:"tick",alpha:r})},a.nodes=function(n){return arguments.length?(m=n,a):m},a.links=function(n){return arguments.length?(y=n,a):y},a.size=function(n){return arguments.length?(s=n,a):s},a.linkDistance=function(n){return arguments.length?(f="function"==typeof n?n:+n,a):f},a.distance=a.linkDistance,a.linkStrength=function(n){return arguments.length?(h="function"==typeof n?n:+n,a):h},a.friction=function(n){return arguments.length?(l=+n,a):l},a.charge=function(n){return arguments.length?(g="function"==typeof n?n:+n,a):g},a.chargeDistance=function(n){return arguments.length?(p=n*n,a):Math.sqrt(p)},a.gravity=function(n){return arguments.length?(v=+n,a):v},a.theta=function(n){return arguments.length?(d=n*n,a):Math.sqrt(d)},a.alpha=function(n){return arguments.length?(n=+n,r?r=n>0?n:0:n>0&&(c.start({type:"start",alpha:r=n}),Xo.timer(a.tick)),a):r},a.start=function(){function n(n,r){if(!e){for(e=new Array(c),a=0;c>a;++a)e[a]=[];for(a=0;s>a;++a){var u=y[a];e[u.source.index].push(u.target),e[u.target.index].push(u.source)}}for(var i,o=e[t],a=-1,s=o.length;++a<s;)if(!isNaN(i=o[a][n]))return i;return Math.random()*r}var t,e,r,c=m.length,l=y.length,p=s[0],v=s[1];for(t=0;c>t;++t)(r=m[t]).index=t,r.weight=0;for(t=0;l>t;++t)r=y[t],"number"==typeof r.source&&(r.source=m[r.source]),"number"==typeof r.target&&(r.target=m[r.target]),++r.source.weight,++r.target.weight;for(t=0;c>t;++t)r=m[t],isNaN(r.x)&&(r.x=n("x",p)),isNaN(r.y)&&(r.y=n("y",v)),isNaN(r.px)&&(r.px=r.x),isNaN(r.py)&&(r.py=r.y);if(u=[],"function"==typeof f)for(t=0;l>t;++t)u[t]=+f.call(this,y[t],t);else for(t=0;l>t;++t)u[t]=f;if(i=[],"function"==typeof h)for(t=0;l>t;++t)i[t]=+h.call(this,y[t],t);else for(t=0;l>t;++t)i[t]=h;if(o=[],"function"==typeof g)for(t=0;c>t;++t)o[t]=+g.call(this,m[t],t);else for(t=0;c>t;++t)o[t]=g;return a.resume()},a.resume=function(){return a.alpha(.1)},a.stop=function(){return a.alpha(0)},a.drag=function(){return e||(e=Xo.behavior.drag().origin(bt).on("dragstart.force",Fu).on("drag.force",t).on("dragend.force",Ou)),arguments.length?(this.on("mouseover.force",Yu).on("mouseout.force",Iu).call(e),void 0):e},Xo.rebind(a,c,"on")};var us=20,is=1,os=1/0;Xo.layout.hierarchy=function(){function n(t,o,a){var c=u.call(e,t,o);if(t.depth=o,a.push(t),c&&(s=c.length)){for(var s,l,f=-1,h=t.children=new Array(s),g=0,p=o+1;++f<s;)l=h[f]=n(c[f],p,a),l.parent=t,g+=l.value;r&&h.sort(r),i&&(t.value=g)}else delete t.children,i&&(t.value=+i.call(e,t,o)||0);return t}function t(n,r){var u=n.children,o=0;if(u&&(a=u.length))for(var a,c=-1,s=r+1;++c<a;)o+=t(u[c],s);else i&&(o=+i.call(e,n,r)||0);return i&&(n.value=o),o}function e(t){var e=[];return n(t,0,e),e}var r=Bu,u=Xu,i=$u;return e.sort=function(n){return arguments.length?(r=n,e):r},e.children=function(n){return arguments.length?(u=n,e):u},e.value=function(n){return arguments.length?(i=n,e):i},e.revalue=function(n){return t(n,0),n},e},Xo.layout.partition=function(){function n(t,e,r,u){var i=t.children;if(t.x=e,t.y=t.depth*u,t.dx=r,t.dy=u,i&&(o=i.length)){var o,a,c,s=-1;for(r=t.value?r/t.value:0;++s<o;)n(a=i[s],e,c=a.value*r,u),e+=c}}function t(n){var e=n.children,r=0;if(e&&(u=e.length))for(var u,i=-1;++i<u;)r=Math.max(r,t(e[i]));return 1+r}function e(e,i){var o=r.call(this,e,i);return n(o[0],0,u[0],u[1]/t(o[0])),o}var r=Xo.layout.hierarchy(),u=[1,1];return e.size=function(n){return arguments.length?(u=n,e):u},Vu(e,r)},Xo.layout.pie=function(){function n(i){var o=i.map(function(e,r){return+t.call(n,e,r)}),a=+("function"==typeof r?r.apply(this,arguments):r),c=(("function"==typeof u?u.apply(this,arguments):u)-a)/Xo.sum(o),s=Xo.range(i.length);null!=e&&s.sort(e===as?function(n,t){return o[t]-o[n]}:function(n,t){return e(i[n],i[t])});var l=[];return s.forEach(function(n){var t;l[n]={data:i[n],value:t=o[n],startAngle:a,endAngle:a+=t*c}}),l}var t=Number,e=as,r=0,u=ka;return n.value=function(e){return arguments.length?(t=e,n):t},n.sort=function(t){return arguments.length?(e=t,n):e},n.startAngle=function(t){return arguments.length?(r=t,n):r},n.endAngle=function(t){return arguments.length?(u=t,n):u},n};var as={};Xo.layout.stack=function(){function n(a,c){var s=a.map(function(e,r){return t.call(n,e,r)}),l=s.map(function(t){return t.map(function(t,e){return[i.call(n,t,e),o.call(n,t,e)]})}),f=e.call(n,l,c);s=Xo.permute(s,f),l=Xo.permute(l,f);var h,g,p,v=r.call(n,l,c),d=s.length,m=s[0].length;for(g=0;m>g;++g)for(u.call(n,s[0][g],p=v[g],l[0][g][1]),h=1;d>h;++h)u.call(n,s[h][g],p+=l[h-1][g][1],l[h][g][1]);return a}var t=bt,e=Qu,r=ni,u=Ku,i=Ju,o=Gu;return n.values=function(e){return arguments.length?(t=e,n):t},n.order=function(t){return arguments.length?(e="function"==typeof t?t:cs.get(t)||Qu,n):e},n.offset=function(t){return arguments.length?(r="function"==typeof t?t:ss.get(t)||ni,n):r},n.x=function(t){return arguments.length?(i=t,n):i},n.y=function(t){return arguments.length?(o=t,n):o},n.out=function(t){return arguments.length?(u=t,n):u},n};var cs=Xo.map({"inside-out":function(n){var t,e,r=n.length,u=n.map(ti),i=n.map(ei),o=Xo.range(r).sort(function(n,t){return u[n]-u[t]}),a=0,c=0,s=[],l=[];for(t=0;r>t;++t)e=o[t],c>a?(a+=i[e],s.push(e)):(c+=i[e],l.push(e));return l.reverse().concat(s)},reverse:function(n){return Xo.range(n.length).reverse()},"default":Qu}),ss=Xo.map({silhouette:function(n){var t,e,r,u=n.length,i=n[0].length,o=[],a=0,c=[];for(e=0;i>e;++e){for(t=0,r=0;u>t;t++)r+=n[t][e][1];r>a&&(a=r),o.push(r)}for(e=0;i>e;++e)c[e]=(a-o[e])/2;return c},wiggle:function(n){var t,e,r,u,i,o,a,c,s,l=n.length,f=n[0],h=f.length,g=[];for(g[0]=c=s=0,e=1;h>e;++e){for(t=0,u=0;l>t;++t)u+=n[t][e][1];for(t=0,i=0,a=f[e][0]-f[e-1][0];l>t;++t){for(r=0,o=(n[t][e][1]-n[t][e-1][1])/(2*a);t>r;++r)o+=(n[r][e][1]-n[r][e-1][1])/a;i+=o*n[t][e][1]}g[e]=c-=u?i/u*a:0,s>c&&(s=c)}for(e=0;h>e;++e)g[e]-=s;return g},expand:function(n){var t,e,r,u=n.length,i=n[0].length,o=1/u,a=[];for(e=0;i>e;++e){for(t=0,r=0;u>t;t++)r+=n[t][e][1];if(r)for(t=0;u>t;t++)n[t][e][1]/=r;else for(t=0;u>t;t++)n[t][e][1]=o}for(e=0;i>e;++e)a[e]=0;return a},zero:ni});Xo.layout.histogram=function(){function n(n,i){for(var o,a,c=[],s=n.map(e,this),l=r.call(this,s,i),f=u.call(this,l,s,i),i=-1,h=s.length,g=f.length-1,p=t?1:1/h;++i<g;)o=c[i]=[],o.dx=f[i+1]-(o.x=f[i]),o.y=0;if(g>0)for(i=-1;++i<h;)a=s[i],a>=l[0]&&a<=l[1]&&(o=c[Xo.bisect(f,a,1,g)-1],o.y+=p,o.push(n[i]));return c}var t=!0,e=Number,r=oi,u=ui;return n.value=function(t){return arguments.length?(e=t,n):e},n.range=function(t){return arguments.length?(r=_t(t),n):r},n.bins=function(t){return arguments.length?(u="number"==typeof t?function(n){return ii(n,t)}:_t(t),n):u},n.frequency=function(e){return arguments.length?(t=!!e,n):t},n},Xo.layout.tree=function(){function n(n,i){function o(n,t){var r=n.children,u=n._tree;if(r&&(i=r.length)){for(var i,a,s,l=r[0],f=l,h=-1;++h<i;)s=r[h],o(s,a),f=c(s,a,f),a=s;vi(n);var g=.5*(l._tree.prelim+s._tree.prelim);t?(u.prelim=t._tree.prelim+e(n,t),u.mod=u.prelim-g):u.prelim=g}else t&&(u.prelim=t._tree.prelim+e(n,t))}function a(n,t){n.x=n._tree.prelim+t;var e=n.children;if(e&&(r=e.length)){var r,u=-1;for(t+=n._tree.mod;++u<r;)a(e[u],t)}}function c(n,t,r){if(t){for(var u,i=n,o=n,a=t,c=n.parent.children[0],s=i._tree.mod,l=o._tree.mod,f=a._tree.mod,h=c._tree.mod;a=si(a),i=ci(i),a&&i;)c=ci(c),o=si(o),o._tree.ancestor=n,u=a._tree.prelim+f-i._tree.prelim-s+e(a,i),u>0&&(di(mi(a,n,r),n,u),s+=u,l+=u),f+=a._tree.mod,s+=i._tree.mod,h+=c._tree.mod,l+=o._tree.mod;a&&!si(o)&&(o._tree.thread=a,o._tree.mod+=f-l),i&&!ci(c)&&(c._tree.thread=i,c._tree.mod+=s-h,r=n)}return r}var s=t.call(this,n,i),l=s[0];pi(l,function(n,t){n._tree={ancestor:n,prelim:0,mod:0,change:0,shift:0,number:t?t._tree.number+1:0}}),o(l),a(l,-l._tree.prelim);var f=li(l,hi),h=li(l,fi),g=li(l,gi),p=f.x-e(f,h)/2,v=h.x+e(h,f)/2,d=g.depth||1;return pi(l,u?function(n){n.x*=r[0],n.y=n.depth*r[1],delete n._tree}:function(n){n.x=(n.x-p)/(v-p)*r[0],n.y=n.depth/d*r[1],delete n._tree}),s}var t=Xo.layout.hierarchy().sort(null).value(null),e=ai,r=[1,1],u=!1;return n.separation=function(t){return arguments.length?(e=t,n):e},n.size=function(t){return arguments.length?(u=null==(r=t),n):u?null:r},n.nodeSize=function(t){return arguments.length?(u=null!=(r=t),n):u?r:null},Vu(n,t)},Xo.layout.pack=function(){function n(n,i){var o=e.call(this,n,i),a=o[0],c=u[0],s=u[1],l=null==t?Math.sqrt:"function"==typeof t?t:function(){return t};if(a.x=a.y=0,pi(a,function(n){n.r=+l(n.value)}),pi(a,bi),r){var f=r*(t?1:Math.max(2*a.r/c,2*a.r/s))/2;pi(a,function(n){n.r+=f}),pi(a,bi),pi(a,function(n){n.r-=f})}return ki(a,c/2,s/2,t?1:1/Math.max(2*a.r/c,2*a.r/s)),o}var t,e=Xo.layout.hierarchy().sort(yi),r=0,u=[1,1];return n.size=function(t){return arguments.length?(u=t,n):u},n.radius=function(e){return arguments.length?(t=null==e||"function"==typeof e?e:+e,n):t},n.padding=function(t){return arguments.length?(r=+t,n):r},Vu(n,e)},Xo.layout.cluster=function(){function n(n,i){var o,a=t.call(this,n,i),c=a[0],s=0;pi(c,function(n){var t=n.children;t&&t.length?(n.x=Ci(t),n.y=Ai(t)):(n.x=o?s+=e(n,o):0,n.y=0,o=n)});var l=Ni(c),f=Li(c),h=l.x-e(l,f)/2,g=f.x+e(f,l)/2;return pi(c,u?function(n){n.x=(n.x-c.x)*r[0],n.y=(c.y-n.y)*r[1]}:function(n){n.x=(n.x-h)/(g-h)*r[0],n.y=(1-(c.y?n.y/c.y:1))*r[1]}),a}var t=Xo.layout.hierarchy().sort(null).value(null),e=ai,r=[1,1],u=!1;return n.separation=function(t){return arguments.length?(e=t,n):e},n.size=function(t){return arguments.length?(u=null==(r=t),n):u?null:r},n.nodeSize=function(t){return arguments.length?(u=null!=(r=t),n):u?r:null},Vu(n,t)},Xo.layout.treemap=function(){function n(n,t){for(var e,r,u=-1,i=n.length;++u<i;)r=(e=n[u]).value*(0>t?0:t),e.area=isNaN(r)||0>=r?0:r}function t(e){var i=e.children;if(i&&i.length){var o,a,c,s=f(e),l=[],h=i.slice(),p=1/0,v="slice"===g?s.dx:"dice"===g?s.dy:"slice-dice"===g?1&e.depth?s.dy:s.dx:Math.min(s.dx,s.dy);for(n(h,s.dx*s.dy/e.value),l.area=0;(c=h.length)>0;)l.push(o=h[c-1]),l.area+=o.area,"squarify"!==g||(a=r(l,v))<=p?(h.pop(),p=a):(l.area-=l.pop().area,u(l,v,s,!1),v=Math.min(s.dx,s.dy),l.length=l.area=0,p=1/0);l.length&&(u(l,v,s,!0),l.length=l.area=0),i.forEach(t)}}function e(t){var r=t.children;if(r&&r.length){var i,o=f(t),a=r.slice(),c=[];for(n(a,o.dx*o.dy/t.value),c.area=0;i=a.pop();)c.push(i),c.area+=i.area,null!=i.z&&(u(c,i.z?o.dx:o.dy,o,!a.length),c.length=c.area=0);r.forEach(e)}}function r(n,t){for(var e,r=n.area,u=0,i=1/0,o=-1,a=n.length;++o<a;)(e=n[o].area)&&(i>e&&(i=e),e>u&&(u=e));return r*=r,t*=t,r?Math.max(t*u*p/r,r/(t*i*p)):1/0}function u(n,t,e,r){var u,i=-1,o=n.length,a=e.x,s=e.y,l=t?c(n.area/t):0;if(t==e.dx){for((r||l>e.dy)&&(l=e.dy);++i<o;)u=n[i],u.x=a,u.y=s,u.dy=l,a+=u.dx=Math.min(e.x+e.dx-a,l?c(u.area/l):0);u.z=!0,u.dx+=e.x+e.dx-a,e.y+=l,e.dy-=l}else{for((r||l>e.dx)&&(l=e.dx);++i<o;)u=n[i],u.x=a,u.y=s,u.dx=l,s+=u.dy=Math.min(e.y+e.dy-s,l?c(u.area/l):0);u.z=!1,u.dy+=e.y+e.dy-s,e.x+=l,e.dx-=l}}function i(r){var u=o||a(r),i=u[0];return i.x=0,i.y=0,i.dx=s[0],i.dy=s[1],o&&a.revalue(i),n([i],i.dx*i.dy/i.value),(o?e:t)(i),h&&(o=u),u}var o,a=Xo.layout.hierarchy(),c=Math.round,s=[1,1],l=null,f=zi,h=!1,g="squarify",p=.5*(1+Math.sqrt(5));return i.size=function(n){return arguments.length?(s=n,i):s},i.padding=function(n){function t(t){var e=n.call(i,t,t.depth);return null==e?zi(t):qi(t,"number"==typeof e?[e,e,e,e]:e)}function e(t){return qi(t,n)}if(!arguments.length)return l;var r;return f=null==(l=n)?zi:"function"==(r=typeof n)?t:"number"===r?(n=[n,n,n,n],e):e,i},i.round=function(n){return arguments.length?(c=n?Math.round:Number,i):c!=Number},i.sticky=function(n){return arguments.length?(h=n,o=null,i):h},i.ratio=function(n){return arguments.length?(p=n,i):p},i.mode=function(n){return arguments.length?(g=n+"",i):g},Vu(i,a)},Xo.random={normal:function(n,t){var e=arguments.length;return 2>e&&(t=1),1>e&&(n=0),function(){var e,r,u;do e=2*Math.random()-1,r=2*Math.random()-1,u=e*e+r*r;while(!u||u>1);return n+t*e*Math.sqrt(-2*Math.log(u)/u)}},logNormal:function(){var n=Xo.random.normal.apply(Xo,arguments);return function(){return Math.exp(n())}},bates:function(n){var t=Xo.random.irwinHall(n);return function(){return t()/n}},irwinHall:function(n){return function(){for(var t=0,e=0;n>e;e++)t+=Math.random();return t}}},Xo.scale={};var ls={floor:bt,ceil:bt};Xo.scale.linear=function(){return Hi([0,1],[0,1],fu,!1)};var fs={s:1,g:1,p:1,r:1,e:1};Xo.scale.log=function(){return $i(Xo.scale.linear().domain([0,1]),10,!0,[1,10])};var hs=Xo.format(".0e"),gs={floor:function(n){return-Math.ceil(-n)},ceil:function(n){return-Math.floor(-n)}};Xo.scale.pow=function(){return Bi(Xo.scale.linear(),1,[0,1])},Xo.scale.sqrt=function(){return Xo.scale.pow().exponent(.5)},Xo.scale.ordinal=function(){return Ji([],{t:"range",a:[[]]})},Xo.scale.category10=function(){return Xo.scale.ordinal().range(ps)},Xo.scale.category20=function(){return Xo.scale.ordinal().range(vs)},Xo.scale.category20b=function(){return Xo.scale.ordinal().range(ds)},Xo.scale.category20c=function(){return Xo.scale.ordinal().range(ms)};var ps=[2062260,16744206,2924588,14034728,9725885,9197131,14907330,8355711,12369186,1556175].map(ht),vs=[2062260,11454440,16744206,16759672,2924588,10018698,14034728,16750742,9725885,12955861,9197131,12885140,14907330,16234194,8355711,13092807,12369186,14408589,1556175,10410725].map(ht),ds=[3750777,5395619,7040719,10264286,6519097,9216594,11915115,13556636,9202993,12426809,15186514,15190932,8666169,11356490,14049643,15177372,8077683,10834324,13528509,14589654].map(ht),ms=[3244733,7057110,10406625,13032431,15095053,16616764,16625259,16634018,3253076,7652470,10607003,13101504,7695281,10394312,12369372,14342891,6513507,9868950,12434877,14277081].map(ht);Xo.scale.quantile=function(){return Gi([],[]) -},Xo.scale.quantize=function(){return Ki(0,1,[0,1])},Xo.scale.threshold=function(){return Qi([.5],[0,1])},Xo.scale.identity=function(){return no([0,1])},Xo.svg={},Xo.svg.arc=function(){function n(){var n=t.apply(this,arguments),i=e.apply(this,arguments),o=r.apply(this,arguments)+ys,a=u.apply(this,arguments)+ys,c=(o>a&&(c=o,o=a,a=c),a-o),s=Sa>c?"0":"1",l=Math.cos(o),f=Math.sin(o),h=Math.cos(a),g=Math.sin(a);return c>=xs?n?"M0,"+i+"A"+i+","+i+" 0 1,1 0,"+-i+"A"+i+","+i+" 0 1,1 0,"+i+"M0,"+n+"A"+n+","+n+" 0 1,0 0,"+-n+"A"+n+","+n+" 0 1,0 0,"+n+"Z":"M0,"+i+"A"+i+","+i+" 0 1,1 0,"+-i+"A"+i+","+i+" 0 1,1 0,"+i+"Z":n?"M"+i*l+","+i*f+"A"+i+","+i+" 0 "+s+",1 "+i*h+","+i*g+"L"+n*h+","+n*g+"A"+n+","+n+" 0 "+s+",0 "+n*l+","+n*f+"Z":"M"+i*l+","+i*f+"A"+i+","+i+" 0 "+s+",1 "+i*h+","+i*g+"L0,0"+"Z"}var t=to,e=eo,r=ro,u=uo;return n.innerRadius=function(e){return arguments.length?(t=_t(e),n):t},n.outerRadius=function(t){return arguments.length?(e=_t(t),n):e},n.startAngle=function(t){return arguments.length?(r=_t(t),n):r},n.endAngle=function(t){return arguments.length?(u=_t(t),n):u},n.centroid=function(){var n=(t.apply(this,arguments)+e.apply(this,arguments))/2,i=(r.apply(this,arguments)+u.apply(this,arguments))/2+ys;return[Math.cos(i)*n,Math.sin(i)*n]},n};var ys=-Ea,xs=ka-Aa;Xo.svg.line=function(){return io(bt)};var Ms=Xo.map({linear:oo,"linear-closed":ao,step:co,"step-before":so,"step-after":lo,basis:mo,"basis-open":yo,"basis-closed":xo,bundle:Mo,cardinal:go,"cardinal-open":fo,"cardinal-closed":ho,monotone:Eo});Ms.forEach(function(n,t){t.key=n,t.closed=/-closed$/.test(n)});var _s=[0,2/3,1/3,0],bs=[0,1/3,2/3,0],ws=[0,1/6,2/3,1/6];Xo.svg.line.radial=function(){var n=io(Ao);return n.radius=n.x,delete n.x,n.angle=n.y,delete n.y,n},so.reverse=lo,lo.reverse=so,Xo.svg.area=function(){return Co(bt)},Xo.svg.area.radial=function(){var n=Co(Ao);return n.radius=n.x,delete n.x,n.innerRadius=n.x0,delete n.x0,n.outerRadius=n.x1,delete n.x1,n.angle=n.y,delete n.y,n.startAngle=n.y0,delete n.y0,n.endAngle=n.y1,delete n.y1,n},Xo.svg.chord=function(){function n(n,a){var c=t(this,i,n,a),s=t(this,o,n,a);return"M"+c.p0+r(c.r,c.p1,c.a1-c.a0)+(e(c,s)?u(c.r,c.p1,c.r,c.p0):u(c.r,c.p1,s.r,s.p0)+r(s.r,s.p1,s.a1-s.a0)+u(s.r,s.p1,c.r,c.p0))+"Z"}function t(n,t,e,r){var u=t.call(n,e,r),i=a.call(n,u,r),o=c.call(n,u,r)+ys,l=s.call(n,u,r)+ys;return{r:i,a0:o,a1:l,p0:[i*Math.cos(o),i*Math.sin(o)],p1:[i*Math.cos(l),i*Math.sin(l)]}}function e(n,t){return n.a0==t.a0&&n.a1==t.a1}function r(n,t,e){return"A"+n+","+n+" 0 "+ +(e>Sa)+",1 "+t}function u(n,t,e,r){return"Q 0,0 "+r}var i=hr,o=gr,a=No,c=ro,s=uo;return n.radius=function(t){return arguments.length?(a=_t(t),n):a},n.source=function(t){return arguments.length?(i=_t(t),n):i},n.target=function(t){return arguments.length?(o=_t(t),n):o},n.startAngle=function(t){return arguments.length?(c=_t(t),n):c},n.endAngle=function(t){return arguments.length?(s=_t(t),n):s},n},Xo.svg.diagonal=function(){function n(n,u){var i=t.call(this,n,u),o=e.call(this,n,u),a=(i.y+o.y)/2,c=[i,{x:i.x,y:a},{x:o.x,y:a},o];return c=c.map(r),"M"+c[0]+"C"+c[1]+" "+c[2]+" "+c[3]}var t=hr,e=gr,r=Lo;return n.source=function(e){return arguments.length?(t=_t(e),n):t},n.target=function(t){return arguments.length?(e=_t(t),n):e},n.projection=function(t){return arguments.length?(r=t,n):r},n},Xo.svg.diagonal.radial=function(){var n=Xo.svg.diagonal(),t=Lo,e=n.projection;return n.projection=function(n){return arguments.length?e(zo(t=n)):t},n},Xo.svg.symbol=function(){function n(n,r){return(Ss.get(t.call(this,n,r))||Ro)(e.call(this,n,r))}var t=To,e=qo;return n.type=function(e){return arguments.length?(t=_t(e),n):t},n.size=function(t){return arguments.length?(e=_t(t),n):e},n};var Ss=Xo.map({circle:Ro,cross:function(n){var t=Math.sqrt(n/5)/2;return"M"+-3*t+","+-t+"H"+-t+"V"+-3*t+"H"+t+"V"+-t+"H"+3*t+"V"+t+"H"+t+"V"+3*t+"H"+-t+"V"+t+"H"+-3*t+"Z"},diamond:function(n){var t=Math.sqrt(n/(2*Cs)),e=t*Cs;return"M0,"+-t+"L"+e+",0"+" 0,"+t+" "+-e+",0"+"Z"},square:function(n){var t=Math.sqrt(n)/2;return"M"+-t+","+-t+"L"+t+","+-t+" "+t+","+t+" "+-t+","+t+"Z"},"triangle-down":function(n){var t=Math.sqrt(n/As),e=t*As/2;return"M0,"+e+"L"+t+","+-e+" "+-t+","+-e+"Z"},"triangle-up":function(n){var t=Math.sqrt(n/As),e=t*As/2;return"M0,"+-e+"L"+t+","+e+" "+-t+","+e+"Z"}});Xo.svg.symbolTypes=Ss.keys();var ks,Es,As=Math.sqrt(3),Cs=Math.tan(30*Na),Ns=[],Ls=0;Ns.call=da.call,Ns.empty=da.empty,Ns.node=da.node,Ns.size=da.size,Xo.transition=function(n){return arguments.length?ks?n.transition():n:xa.transition()},Xo.transition.prototype=Ns,Ns.select=function(n){var t,e,r,u=this.id,i=[];n=M(n);for(var o=-1,a=this.length;++o<a;){i.push(t=[]);for(var c=this[o],s=-1,l=c.length;++s<l;)(r=c[s])&&(e=n.call(r,r.__data__,s,o))?("__data__"in r&&(e.__data__=r.__data__),jo(e,s,u,r.__transition__[u]),t.push(e)):t.push(null)}return Do(i,u)},Ns.selectAll=function(n){var t,e,r,u,i,o=this.id,a=[];n=_(n);for(var c=-1,s=this.length;++c<s;)for(var l=this[c],f=-1,h=l.length;++f<h;)if(r=l[f]){i=r.__transition__[o],e=n.call(r,r.__data__,f,c),a.push(t=[]);for(var g=-1,p=e.length;++g<p;)(u=e[g])&&jo(u,g,o,i),t.push(u)}return Do(a,o)},Ns.filter=function(n){var t,e,r,u=[];"function"!=typeof n&&(n=q(n));for(var i=0,o=this.length;o>i;i++){u.push(t=[]);for(var e=this[i],a=0,c=e.length;c>a;a++)(r=e[a])&&n.call(r,r.__data__,a,i)&&t.push(r)}return Do(u,this.id)},Ns.tween=function(n,t){var e=this.id;return arguments.length<2?this.node().__transition__[e].tween.get(n):R(this,null==t?function(t){t.__transition__[e].tween.remove(n)}:function(r){r.__transition__[e].tween.set(n,t)})},Ns.attr=function(n,t){function e(){this.removeAttribute(a)}function r(){this.removeAttributeNS(a.space,a.local)}function u(n){return null==n?e:(n+="",function(){var t,e=this.getAttribute(a);return e!==n&&(t=o(e,n),function(n){this.setAttribute(a,t(n))})})}function i(n){return null==n?r:(n+="",function(){var t,e=this.getAttributeNS(a.space,a.local);return e!==n&&(t=o(e,n),function(n){this.setAttributeNS(a.space,a.local,t(n))})})}if(arguments.length<2){for(t in n)this.attr(t,n[t]);return this}var o="transform"==n?Ru:fu,a=Xo.ns.qualify(n);return Po(this,"attr."+n,t,a.local?i:u)},Ns.attrTween=function(n,t){function e(n,e){var r=t.call(this,n,e,this.getAttribute(u));return r&&function(n){this.setAttribute(u,r(n))}}function r(n,e){var r=t.call(this,n,e,this.getAttributeNS(u.space,u.local));return r&&function(n){this.setAttributeNS(u.space,u.local,r(n))}}var u=Xo.ns.qualify(n);return this.tween("attr."+n,u.local?r:e)},Ns.style=function(n,t,e){function r(){this.style.removeProperty(n)}function u(t){return null==t?r:(t+="",function(){var r,u=Go.getComputedStyle(this,null).getPropertyValue(n);return u!==t&&(r=fu(u,t),function(t){this.style.setProperty(n,r(t),e)})})}var i=arguments.length;if(3>i){if("string"!=typeof n){2>i&&(t="");for(e in n)this.style(e,n[e],t);return this}e=""}return Po(this,"style."+n,t,u)},Ns.styleTween=function(n,t,e){function r(r,u){var i=t.call(this,r,u,Go.getComputedStyle(this,null).getPropertyValue(n));return i&&function(t){this.style.setProperty(n,i(t),e)}}return arguments.length<3&&(e=""),this.tween("style."+n,r)},Ns.text=function(n){return Po(this,"text",n,Uo)},Ns.remove=function(){return this.each("end.transition",function(){var n;this.__transition__.count<2&&(n=this.parentNode)&&n.removeChild(this)})},Ns.ease=function(n){var t=this.id;return arguments.length<1?this.node().__transition__[t].ease:("function"!=typeof n&&(n=Xo.ease.apply(Xo,arguments)),R(this,function(e){e.__transition__[t].ease=n}))},Ns.delay=function(n){var t=this.id;return R(this,"function"==typeof n?function(e,r,u){e.__transition__[t].delay=+n.call(e,e.__data__,r,u)}:(n=+n,function(e){e.__transition__[t].delay=n}))},Ns.duration=function(n){var t=this.id;return R(this,"function"==typeof n?function(e,r,u){e.__transition__[t].duration=Math.max(1,n.call(e,e.__data__,r,u))}:(n=Math.max(1,n),function(e){e.__transition__[t].duration=n}))},Ns.each=function(n,t){var e=this.id;if(arguments.length<2){var r=Es,u=ks;ks=e,R(this,function(t,r,u){Es=t.__transition__[e],n.call(t,t.__data__,r,u)}),Es=r,ks=u}else R(this,function(r){var u=r.__transition__[e];(u.event||(u.event=Xo.dispatch("start","end"))).on(n,t)});return this},Ns.transition=function(){for(var n,t,e,r,u=this.id,i=++Ls,o=[],a=0,c=this.length;c>a;a++){o.push(n=[]);for(var t=this[a],s=0,l=t.length;l>s;s++)(e=t[s])&&(r=Object.create(e.__transition__[u]),r.delay+=r.duration,jo(e,s,i,r)),n.push(e)}return Do(o,i)},Xo.svg.axis=function(){function n(n){n.each(function(){var n,s=Xo.select(this),l=this.__chart__||e,f=this.__chart__=e.copy(),h=null==c?f.ticks?f.ticks.apply(f,a):f.domain():c,g=null==t?f.tickFormat?f.tickFormat.apply(f,a):bt:t,p=s.selectAll(".tick").data(h,f),v=p.enter().insert("g",".domain").attr("class","tick").style("opacity",Aa),d=Xo.transition(p.exit()).style("opacity",Aa).remove(),m=Xo.transition(p).style("opacity",1),y=Ri(f),x=s.selectAll(".domain").data([0]),M=(x.enter().append("path").attr("class","domain"),Xo.transition(x));v.append("line"),v.append("text");var _=v.select("line"),b=m.select("line"),w=p.select("text").text(g),S=v.select("text"),k=m.select("text");switch(r){case"bottom":n=Ho,_.attr("y2",u),S.attr("y",Math.max(u,0)+o),b.attr("x2",0).attr("y2",u),k.attr("x",0).attr("y",Math.max(u,0)+o),w.attr("dy",".71em").style("text-anchor","middle"),M.attr("d","M"+y[0]+","+i+"V0H"+y[1]+"V"+i);break;case"top":n=Ho,_.attr("y2",-u),S.attr("y",-(Math.max(u,0)+o)),b.attr("x2",0).attr("y2",-u),k.attr("x",0).attr("y",-(Math.max(u,0)+o)),w.attr("dy","0em").style("text-anchor","middle"),M.attr("d","M"+y[0]+","+-i+"V0H"+y[1]+"V"+-i);break;case"left":n=Fo,_.attr("x2",-u),S.attr("x",-(Math.max(u,0)+o)),b.attr("x2",-u).attr("y2",0),k.attr("x",-(Math.max(u,0)+o)).attr("y",0),w.attr("dy",".32em").style("text-anchor","end"),M.attr("d","M"+-i+","+y[0]+"H0V"+y[1]+"H"+-i);break;case"right":n=Fo,_.attr("x2",u),S.attr("x",Math.max(u,0)+o),b.attr("x2",u).attr("y2",0),k.attr("x",Math.max(u,0)+o).attr("y",0),w.attr("dy",".32em").style("text-anchor","start"),M.attr("d","M"+i+","+y[0]+"H0V"+y[1]+"H"+i)}if(f.rangeBand){var E=f,A=E.rangeBand()/2;l=f=function(n){return E(n)+A}}else l.rangeBand?l=f:d.call(n,f);v.call(n,l),m.call(n,f)})}var t,e=Xo.scale.linear(),r=zs,u=6,i=6,o=3,a=[10],c=null;return n.scale=function(t){return arguments.length?(e=t,n):e},n.orient=function(t){return arguments.length?(r=t in qs?t+"":zs,n):r},n.ticks=function(){return arguments.length?(a=arguments,n):a},n.tickValues=function(t){return arguments.length?(c=t,n):c},n.tickFormat=function(e){return arguments.length?(t=e,n):t},n.tickSize=function(t){var e=arguments.length;return e?(u=+t,i=+arguments[e-1],n):u},n.innerTickSize=function(t){return arguments.length?(u=+t,n):u},n.outerTickSize=function(t){return arguments.length?(i=+t,n):i},n.tickPadding=function(t){return arguments.length?(o=+t,n):o},n.tickSubdivide=function(){return arguments.length&&n},n};var zs="bottom",qs={top:1,right:1,bottom:1,left:1};Xo.svg.brush=function(){function n(i){i.each(function(){var i=Xo.select(this).style("pointer-events","all").style("-webkit-tap-highlight-color","rgba(0,0,0,0)").on("mousedown.brush",u).on("touchstart.brush",u),o=i.selectAll(".background").data([0]);o.enter().append("rect").attr("class","background").style("visibility","hidden").style("cursor","crosshair"),i.selectAll(".extent").data([0]).enter().append("rect").attr("class","extent").style("cursor","move");var a=i.selectAll(".resize").data(p,bt);a.exit().remove(),a.enter().append("g").attr("class",function(n){return"resize "+n}).style("cursor",function(n){return Ts[n]}).append("rect").attr("x",function(n){return/[ew]$/.test(n)?-3:null}).attr("y",function(n){return/^[ns]/.test(n)?-3:null}).attr("width",6).attr("height",6).style("visibility","hidden"),a.style("display",n.empty()?"none":null);var l,f=Xo.transition(i),h=Xo.transition(o);c&&(l=Ri(c),h.attr("x",l[0]).attr("width",l[1]-l[0]),e(f)),s&&(l=Ri(s),h.attr("y",l[0]).attr("height",l[1]-l[0]),r(f)),t(f)})}function t(n){n.selectAll(".resize").attr("transform",function(n){return"translate("+l[+/e$/.test(n)]+","+f[+/^s/.test(n)]+")"})}function e(n){n.select(".extent").attr("x",l[0]),n.selectAll(".extent,.n>rect,.s>rect").attr("width",l[1]-l[0])}function r(n){n.select(".extent").attr("y",f[0]),n.selectAll(".extent,.e>rect,.w>rect").attr("height",f[1]-f[0])}function u(){function u(){32==Xo.event.keyCode&&(C||(x=null,L[0]-=l[1],L[1]-=f[1],C=2),d())}function p(){32==Xo.event.keyCode&&2==C&&(L[0]+=l[1],L[1]+=f[1],C=0,d())}function v(){var n=Xo.mouse(_),u=!1;M&&(n[0]+=M[0],n[1]+=M[1]),C||(Xo.event.altKey?(x||(x=[(l[0]+l[1])/2,(f[0]+f[1])/2]),L[0]=l[+(n[0]<x[0])],L[1]=f[+(n[1]<x[1])]):x=null),E&&m(n,c,0)&&(e(S),u=!0),A&&m(n,s,1)&&(r(S),u=!0),u&&(t(S),w({type:"brush",mode:C?"move":"resize"}))}function m(n,t,e){var r,u,a=Ri(t),c=a[0],s=a[1],p=L[e],v=e?f:l,d=v[1]-v[0];return C&&(c-=p,s-=d+p),r=(e?g:h)?Math.max(c,Math.min(s,n[e])):n[e],C?u=(r+=p)+d:(x&&(p=Math.max(c,Math.min(s,2*x[e]-r))),r>p?(u=r,r=p):u=p),v[0]!=r||v[1]!=u?(e?o=null:i=null,v[0]=r,v[1]=u,!0):void 0}function y(){v(),S.style("pointer-events","all").selectAll(".resize").style("display",n.empty()?"none":null),Xo.select("body").style("cursor",null),z.on("mousemove.brush",null).on("mouseup.brush",null).on("touchmove.brush",null).on("touchend.brush",null).on("keydown.brush",null).on("keyup.brush",null),N(),w({type:"brushend"})}var x,M,_=this,b=Xo.select(Xo.event.target),w=a.of(_,arguments),S=Xo.select(_),k=b.datum(),E=!/^(n|s)$/.test(k)&&c,A=!/^(e|w)$/.test(k)&&s,C=b.classed("extent"),N=O(),L=Xo.mouse(_),z=Xo.select(Go).on("keydown.brush",u).on("keyup.brush",p);if(Xo.event.changedTouches?z.on("touchmove.brush",v).on("touchend.brush",y):z.on("mousemove.brush",v).on("mouseup.brush",y),S.interrupt().selectAll("*").interrupt(),C)L[0]=l[0]-L[0],L[1]=f[0]-L[1];else if(k){var q=+/w$/.test(k),T=+/^n/.test(k);M=[l[1-q]-L[0],f[1-T]-L[1]],L[0]=l[q],L[1]=f[T]}else Xo.event.altKey&&(x=L.slice());S.style("pointer-events","none").selectAll(".resize").style("display",null),Xo.select("body").style("cursor",b.style("cursor")),w({type:"brushstart"}),v()}var i,o,a=y(n,"brushstart","brush","brushend"),c=null,s=null,l=[0,0],f=[0,0],h=!0,g=!0,p=Rs[0];return n.event=function(n){n.each(function(){var n=a.of(this,arguments),t={x:l,y:f,i:i,j:o},e=this.__chart__||t;this.__chart__=t,ks?Xo.select(this).transition().each("start.brush",function(){i=e.i,o=e.j,l=e.x,f=e.y,n({type:"brushstart"})}).tween("brush:brush",function(){var e=hu(l,t.x),r=hu(f,t.y);return i=o=null,function(u){l=t.x=e(u),f=t.y=r(u),n({type:"brush",mode:"resize"})}}).each("end.brush",function(){i=t.i,o=t.j,n({type:"brush",mode:"resize"}),n({type:"brushend"})}):(n({type:"brushstart"}),n({type:"brush",mode:"resize"}),n({type:"brushend"}))})},n.x=function(t){return arguments.length?(c=t,p=Rs[!c<<1|!s],n):c},n.y=function(t){return arguments.length?(s=t,p=Rs[!c<<1|!s],n):s},n.clamp=function(t){return arguments.length?(c&&s?(h=!!t[0],g=!!t[1]):c?h=!!t:s&&(g=!!t),n):c&&s?[h,g]:c?h:s?g:null},n.extent=function(t){var e,r,u,a,h;return arguments.length?(c&&(e=t[0],r=t[1],s&&(e=e[0],r=r[0]),i=[e,r],c.invert&&(e=c(e),r=c(r)),e>r&&(h=e,e=r,r=h),(e!=l[0]||r!=l[1])&&(l=[e,r])),s&&(u=t[0],a=t[1],c&&(u=u[1],a=a[1]),o=[u,a],s.invert&&(u=s(u),a=s(a)),u>a&&(h=u,u=a,a=h),(u!=f[0]||a!=f[1])&&(f=[u,a])),n):(c&&(i?(e=i[0],r=i[1]):(e=l[0],r=l[1],c.invert&&(e=c.invert(e),r=c.invert(r)),e>r&&(h=e,e=r,r=h))),s&&(o?(u=o[0],a=o[1]):(u=f[0],a=f[1],s.invert&&(u=s.invert(u),a=s.invert(a)),u>a&&(h=u,u=a,a=h))),c&&s?[[e,u],[r,a]]:c?[e,r]:s&&[u,a])},n.clear=function(){return n.empty()||(l=[0,0],f=[0,0],i=o=null),n},n.empty=function(){return!!c&&l[0]==l[1]||!!s&&f[0]==f[1]},Xo.rebind(n,a,"on")};var Ts={n:"ns-resize",e:"ew-resize",s:"ns-resize",w:"ew-resize",nw:"nwse-resize",ne:"nesw-resize",se:"nwse-resize",sw:"nesw-resize"},Rs=[["n","e","s","w","nw","ne","se","sw"],["e","w"],["n","s"],[]],Ds=tc.format=ac.timeFormat,Ps=Ds.utc,Us=Ps("%Y-%m-%dT%H:%M:%S.%LZ");Ds.iso=Date.prototype.toISOString&&+new Date("2000-01-01T00:00:00.000Z")?Oo:Us,Oo.parse=function(n){var t=new Date(n);return isNaN(t)?null:t},Oo.toString=Us.toString,tc.second=Rt(function(n){return new ec(1e3*Math.floor(n/1e3))},function(n,t){n.setTime(n.getTime()+1e3*Math.floor(t))},function(n){return n.getSeconds()}),tc.seconds=tc.second.range,tc.seconds.utc=tc.second.utc.range,tc.minute=Rt(function(n){return new ec(6e4*Math.floor(n/6e4))},function(n,t){n.setTime(n.getTime()+6e4*Math.floor(t))},function(n){return n.getMinutes()}),tc.minutes=tc.minute.range,tc.minutes.utc=tc.minute.utc.range,tc.hour=Rt(function(n){var t=n.getTimezoneOffset()/60;return new ec(36e5*(Math.floor(n/36e5-t)+t))},function(n,t){n.setTime(n.getTime()+36e5*Math.floor(t))},function(n){return n.getHours()}),tc.hours=tc.hour.range,tc.hours.utc=tc.hour.utc.range,tc.month=Rt(function(n){return n=tc.day(n),n.setDate(1),n},function(n,t){n.setMonth(n.getMonth()+t)},function(n){return n.getMonth()}),tc.months=tc.month.range,tc.months.utc=tc.month.utc.range;var js=[1e3,5e3,15e3,3e4,6e4,3e5,9e5,18e5,36e5,108e5,216e5,432e5,864e5,1728e5,6048e5,2592e6,7776e6,31536e6],Hs=[[tc.second,1],[tc.second,5],[tc.second,15],[tc.second,30],[tc.minute,1],[tc.minute,5],[tc.minute,15],[tc.minute,30],[tc.hour,1],[tc.hour,3],[tc.hour,6],[tc.hour,12],[tc.day,1],[tc.day,2],[tc.week,1],[tc.month,1],[tc.month,3],[tc.year,1]],Fs=Ds.multi([[".%L",function(n){return n.getMilliseconds()}],[":%S",function(n){return n.getSeconds()}],["%I:%M",function(n){return n.getMinutes()}],["%I %p",function(n){return n.getHours()}],["%a %d",function(n){return n.getDay()&&1!=n.getDate()}],["%b %d",function(n){return 1!=n.getDate()}],["%B",function(n){return n.getMonth()}],["%Y",be]]),Os={range:function(n,t,e){return Xo.range(+n,+t,e).map(Io)},floor:bt,ceil:bt};Hs.year=tc.year,tc.scale=function(){return Yo(Xo.scale.linear(),Hs,Fs)};var Ys=Hs.map(function(n){return[n[0].utc,n[1]]}),Is=Ps.multi([[".%L",function(n){return n.getUTCMilliseconds()}],[":%S",function(n){return n.getUTCSeconds()}],["%I:%M",function(n){return n.getUTCMinutes()}],["%I %p",function(n){return n.getUTCHours()}],["%a %d",function(n){return n.getUTCDay()&&1!=n.getUTCDate()}],["%b %d",function(n){return 1!=n.getUTCDate()}],["%B",function(n){return n.getUTCMonth()}],["%Y",be]]);Ys.year=tc.year.utc,tc.scale.utc=function(){return Yo(Xo.scale.linear(),Ys,Is)},Xo.text=wt(function(n){return n.responseText}),Xo.json=function(n,t){return St(n,"application/json",Zo,t)},Xo.html=function(n,t){return St(n,"text/html",Vo,t)},Xo.xml=wt(function(n){return n.responseXML}),"function"==typeof define&&define.amd?define(Xo):"object"==typeof module&&module.exports?module.exports=Xo:this.d3=Xo}(); \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/plots/pca.html b/ThirdParty/Ert/devel/share/gui/plots/pca.html deleted file mode 100644 index 22fbdf4ffb..0000000000 --- a/ThirdParty/Ert/devel/share/gui/plots/pca.html +++ /dev/null @@ -1,178 +0,0 @@ -<!DOCTYPE html> -<!-- Copyright (C) 2014 Statoil ASA, Norway. --> -<!-- --> -<!-- The file 'gen_kw.html' is part of ERT - Ensemble based Reservoir Tool. --> -<!-- --> -<!-- ERT is free software: you can redistribute it and/or modify --> -<!-- it under the terms of the GNU General Public License as published by --> -<!-- the Free Software Foundation, either version 3 of the License, or --> -<!-- (at your option) any later version. --> -<!-- --> -<!-- ERT is distributed in the hope that it will be useful, but WITHOUT ANY --> -<!-- WARRANTY; without even the implied warranty of MERCHANTABILITY or --> -<!-- FITNESS FOR A PARTICULAR PURPOSE. --> -<!-- --> -<!-- See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> --> -<!-- for more details. --> - -<html> -<head> - <meta charset="utf-8"> - <link rel="stylesheet" type="text/css" href="style/plot.css"/> -</head> - -<script src="libs/d3.v3.js"></script> -<script src="scripts/styles.js"></script> -<script src="scripts/base_plot.js"></script> -<script src="scripts/base_plot_value_dimension.js"></script> -<script src="scripts/base_plot_ordinal_dimension.js"></script> -<script src="scripts/canvas_plot_pca.js"></script> -<script src="scripts/canvas_plot_line.js"></script> -<script src="scripts/canvas_plot_stippled_line.js"></script> -<script src="scripts/canvas_plot_area.js"></script> -<script src="scripts/canvas_error_bar.js"></script> -<script src="scripts/canvas_plot_circle.js"></script> -<script src="scripts/canvas_plot_cross.js"></script> -<script src="scripts/canvas_plot_legend.js"></script> - -<script> - var plot = null; - - var ordinal_dimension = null; - var value_dimension = null; - - function initialize() { - if (!(typeof plot_data_source === 'undefined')) { - createPlot(); - updatePlot(); - plot_data_source.htmlInitialized(); - } else { - createPlot(); - plot.setData(data); - console.log("Unable to load data!"); - alert("Unable to load data!"); - } - } - - function createPlot() { - ordinal_dimension = BasePlotOrdinalDimension(false); - value_dimension = BasePlotValueDimension(); - ordinal_dimension.setUnit("Principal Component"); - value_dimension.setUnit("Value"); - plot = new PcaPlot(d3.select("body"), ordinal_dimension, value_dimension); - plot.setRenderingFinishedCallback(function() { - plot_data_source.renderingFinished(); - }); - } - - function updatePlot() { - var data = plot_data_source.getPlotData(); - if(data.hasUserData("PCA")) { - plot.setData(data.getUserData("PCA")); - } - } - - function setSize(width, height) { - plot.resize(width, height - 75); - } - - function setScales(x_min, x_max, y_min, y_max) { - plot.setScales(x_min, x_max, y_min, y_max); - } - - function setReportStepTime(report_step_time) { - // Not supported by this plot - } - - function supportsPlotProperties(time, value, depth, index, histogram, pca){ - return pca; - } - - function getPrintWidth(){ - return 1600; - } - - function getPrintHeight(){ - return 1200; - } - - function setCustomSettings(settings) { - plot.setCustomSettings(settings); - STYLES.updateColors(settings); - } - - function renderNow(){ - plot.renderNow(); - } - - function getPlotTitle(){ - return plot.getTitle(); - } - - function xAxisType() { - return null; - } - - function yAxisType() { - return "pca"; - } - - function isReportStepCapable() { - return false; - } - - function getXMin() { - var data = plot_data_source.getTemporaryData(); - if(data.hasUserData("PCA")) { - data = data.getUserData("PCA"); - - if(data.hasBoundaries()) { - return data.minX(); - } - } - return null; - } - - function getXMax() { - var data = plot_data_source.getTemporaryData(); - if(data.hasUserData("PCA")) { - data = data.getUserData("PCA"); - - if(data.hasBoundaries()) { - return data.maxX(); - } - } - return null; - } - - function getYMin() { - var data = plot_data_source.getTemporaryData(); - if(data.hasUserData("PCA")) { - data = data.getUserData("PCA"); - - if(data.hasBoundaries()) { - return data.minY(); - } - } - return null; - } - - function getYMax() { - var data = plot_data_source.getTemporaryData(); - if(data.hasUserData("PCA")) { - data = data.getUserData("PCA"); - - if(data.hasBoundaries()) { - return data.maxY(); - } - } - return null; - } - -</script> - -<body onload="initialize();"> - -</body> - -</html> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/plots/rft.html b/ThirdParty/Ert/devel/share/gui/plots/rft.html deleted file mode 100644 index c84775d54e..0000000000 --- a/ThirdParty/Ert/devel/share/gui/plots/rft.html +++ /dev/null @@ -1,162 +0,0 @@ -<!DOCTYPE html> -<!-- Copyright (C) 2013 Statoil ASA, Norway. --> -<!-- --> -<!-- The file 'simple_plot.html' is part of ERT - Ensemble based Reservoir Tool. --> -<!-- --> -<!-- ERT is free software: you can redistribute it and/or modify --> -<!-- it under the terms of the GNU General Public License as published by --> -<!-- the Free Software Foundation, either version 3 of the License, or --> -<!-- (at your option) any later version. --> -<!-- --> -<!-- ERT is distributed in the hope that it will be useful, but WITHOUT ANY --> -<!-- WARRANTY; without even the implied warranty of MERCHANTABILITY or --> -<!-- FITNESS FOR A PARTICULAR PURPOSE. --> -<!-- --> -<!-- See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> --> -<!-- for more details. --> - -<html> -<head> - <meta charset="utf-8"> - <link rel="stylesheet" type="text/css" href="style/plot.css"/> -</head> - -<script src="libs/d3.v3.js"></script> -<script src="scripts/styles.js"></script> -<script src="scripts/base_plot.js"></script> -<script src="scripts/base_plot_time_dimension.js"></script> -<script src="scripts/base_plot_value_dimension.js"></script> -<script src="scripts/render_tracker.js"></script> -<script src="scripts/canvas_plot.js"></script> -<script src="scripts/canvas_plot_line.js"></script> -<script src="scripts/canvas_plot_stippled_line.js"></script> -<script src="scripts/canvas_plot_area.js"></script> -<script src="scripts/canvas_error_bar.js"></script> -<script src="scripts/canvas_plot_circle.js"></script> -<script src="scripts/canvas_plot_legend.js"></script> - -<script> - var plot = null; - - var x_dimension = null; - var y_dimension = null; - - function initialize() { - if (!(typeof plot_data_source === 'undefined')) { - createPlot(); - updatePlot(); - plot_data_source.htmlInitialized(); - } else { - createPlot(); - plot.setData(data); - console.log("Unable to load data!"); - alert("Unable to load data!"); - } - } - - function createPlot() { - x_dimension = BasePlotValueDimension(); - y_dimension = BasePlotValueDimension(true); - plot = new Plot(d3.select("body"), x_dimension, y_dimension); - plot.setVerticalErrorBar(false); - plot.setHorizontalDrawDirection(false); - plot.setRenderingFinishedCallback(function() { - plot_data_source.renderingFinished(); - }); - } - - function updatePlot() { - var data = plot_data_source.getPlotData(); - plot.setData(data); - x_dimension.setUnit(data.unitX()); - y_dimension.setUnit(data.unitY()); - } - - function setSize(width, height) { - plot.resize(width, height - 75); - } - - function setScales(x_min, x_max, y_min, y_max) { - plot.setScales(x_min, x_max, y_min, y_max); - } - - function setReportStepTime(report_step_time) { - // Not supported by this plot - } - - function supportsPlotProperties(time, value, depth, index, histogram, pca){ - return !time && value && depth; - } - - function getPrintWidth(){ - return 1600; - } - - function getPrintHeight(){ - return 1200; - } - - function setCustomSettings(settings) { - plot.setCustomSettings(settings); - STYLES.updateColors(settings); - } - - function renderNow(){ - plot.renderNow(); - } - - function getPlotTitle(){ - return plot.getTitle(); - } - - function xAxisType() { - return "value"; - } - - function yAxisType() { - return "depth"; - } - - function isReportStepCapable() { - return false; - } - - function getXMin() { - var data = plot_data_source.getTemporaryData(); - if(!data.hasBoundaries()) { - return null; - } - return data.minX(); - } - - function getXMax() { - var data = plot_data_source.getTemporaryData(); - if(!data.hasBoundaries()) { - return null; - } - return data.maxX(); - } - - function getYMin() { - var data = plot_data_source.getTemporaryData(); - if(!data.hasBoundaries()) { - return null; - } - return data.minY(); - } - - function getYMax() { - var data = plot_data_source.getTemporaryData(); - if(!data.hasBoundaries()) { - return null; - } - return data.maxY(); - } - -</script> - -<body onload="initialize();"> - -</body> - -</html> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/plots/rft_overview.html b/ThirdParty/Ert/devel/share/gui/plots/rft_overview.html deleted file mode 100644 index f73115fab0..0000000000 --- a/ThirdParty/Ert/devel/share/gui/plots/rft_overview.html +++ /dev/null @@ -1,160 +0,0 @@ -<!DOCTYPE html> -<!-- Copyright (C) 2013 Statoil ASA, Norway. --> -<!-- --> -<!-- The file 'simple_overview_plot.html' is part of ERT - Ensemble based Reservoir Tool. --> -<!-- --> -<!-- ERT is free software: you can redistribute it and/or modify --> -<!-- it under the terms of the GNU General Public License as published by --> -<!-- the Free Software Foundation, either version 3 of the License, or --> -<!-- (at your option) any later version. --> -<!-- --> -<!-- ERT is distributed in the hope that it will be useful, but WITHOUT ANY --> -<!-- WARRANTY; without even the implied warranty of MERCHANTABILITY or --> -<!-- FITNESS FOR A PARTICULAR PURPOSE. --> -<!-- --> -<!-- See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> --> -<!-- for more details. --> - -<html> -<head> - <meta charset="utf-8"> - <link rel="stylesheet" type="text/css" href="style/plot.css"/> -</head> - -<script src="libs/d3.v3.js"></script> -<script src="scripts/styles.js"></script> -<script src="scripts/base_plot.js"></script> -<script src="scripts/base_plot_time_dimension.js"></script> -<script src="scripts/base_plot_value_dimension.js"></script> -<script src="scripts/canvas_plot_overview.js"></script> -<script src="scripts/canvas_plot_line.js"></script> -<script src="scripts/canvas_plot_stippled_line.js"></script> -<script src="scripts/canvas_plot_area.js"></script> -<script src="scripts/canvas_error_bar.js"></script> -<script src="scripts/canvas_plot_circle.js"></script> -<script src="scripts/canvas_plot_legend.js"></script> - -<script> - var plot = null; - - var x_dimension = null; - var y_dimension = null; - - function initialize() { - if (!(typeof plot_data_source === 'undefined')) { - createPlot(); - updatePlot(); - plot_data_source.htmlInitialized(); - } else { -// createPlot(); -// plot.setData(data); - console.log("Unable to load data!"); - alert("Unable to load data!"); - } - } - - function createPlot() { - x_dimension = BasePlotValueDimension(); - y_dimension = BasePlotValueDimension(true); - plot = new OverviewPlot(d3.select("body"), x_dimension, y_dimension); - plot.setVerticalErrorBar(false); - plot.setHorizontalDrawDirection(false); - plot.setRenderingFinishedCallback(function() { - plot_data_source.renderingFinished(); - }); - } - - function updatePlot() { - var data = plot_data_source.getPlotData(); - plot.setData(data); - x_dimension.setUnit(data.unitX()); - y_dimension.setUnit(data.unitY()); - } - - function setSize(width, height) { - plot.resize(width, height - 75); - } - - function setScales(x_min, x_max, y_min, y_max) { - plot.setScales(x_min, x_max, y_min, y_max); - } - - function setReportStepTime(report_step_time) { - // Not supported by this plot - } - - function supportsPlotProperties(time, value, depth, index, histogram, pca){ - return !time && value && depth; - } - - function getPrintWidth(){ - return 1600; - } - - function getPrintHeight(){ - return 1200; - } - - function setCustomSettings(settings) { - plot.setCustomSettings(settings); - STYLES.updateColors(settings); - } - - function renderNow(){ - plot.renderNow(); - } - - function getPlotTitle(){ - return plot.getTitle(); - } - - function xAxisType() { - return "value"; - } - - function yAxisType() { - return "depth"; - } - - function isReportStepCapable() { - return false; - } - - function getXMin() { - var data = plot_data_source.getTemporaryData(); - if(!data.hasBoundaries()) { - return null; - } - return data.minX(); - } - - function getXMax() { - var data = plot_data_source.getTemporaryData(); - if(!data.hasBoundaries()) { - return null; - } - return data.maxX(); - } - - function getYMin() { - var data = plot_data_source.getTemporaryData(); - if(!data.hasBoundaries()) { - return null; - } - return data.minY(); - } - - function getYMax() { - var data = plot_data_source.getTemporaryData(); - if(!data.hasBoundaries()) { - return null; - } - return data.maxY(); - } -</script> - -<body onload="initialize();"> - -</body> - -</html> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/plots/scripts/base_plot.js b/ThirdParty/Ert/devel/share/gui/plots/scripts/base_plot.js deleted file mode 100644 index ed70241950..0000000000 --- a/ThirdParty/Ert/devel/share/gui/plots/scripts/base_plot.js +++ /dev/null @@ -1,440 +0,0 @@ -// Copyright (C) 2013 Statoil ASA, Norway. -// -// The file 'base_plot.js' is part of ERT - Ensemble based Reservoir Tool. -// -// ERT is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// ERT is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. -// -// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> -// for more details. - -function BasePlot(element, x_dimension, y_dimension) { - this.stored_data = null; - this.margin = {left: 90, right: 20, top: 20, bottom: 30}; - this.root_elemenet = element; - - this.render_observations = true; - this.render_refcase = true; - - this.custom_y_min = null; - this.custom_y_max = null; - this.custom_x_min = null; - this.custom_x_max = null; - - this.render_finished = false; - this.render_callback_finished = false; - this.rendering_finished_callback = null; - - this.pre_render_callback = null; - this.render_callback = null; - - this.dimension_x = x_dimension; - this.dimension_y = y_dimension; - - this.vertical_error_bar = true; - this.error_bar_only = false; - - var group = this.root_elemenet.append("div") - .attr("class", "plot"); - - this.title = group.append("div") - .attr("class", "plot-title") - .text(this.getTitle()); - - this.axis_label_group = group.append("div") - .attr("id", "axis-label-group") - - this.x_label = this.axis_label_group.append("div") - .attr("class", "x axis-label") - .text("") - - this.y_label = this.axis_label_group.append("div") - .attr("class", "y axis-label") - .text(""); - - var plot_area = group.append("div").attr("class", "plot-area"); - - this.width = 1024 - this.margin.left - this.margin.right; - this.height = 512 - this.margin.top - this.margin.bottom; - - this.canvas = plot_area.append("canvas") - .attr("id", "plot-canvas") - .attr("width", this.width) - .attr("height", this.height) - .style("position", "absolute") - .style("top", (this.margin.top) + "px") - .style("left", (this.margin.left) + "px") - .style("z-index", 5); - - this.overlay_canvas = plot_area.append("canvas") - .attr("id", "plot-overlay-canvas") - .attr("width", this.width) - .attr("height", this.height) - .style("position", "absolute") - .style("top", (this.margin.top) + "px") - .style("left", (this.margin.left) + "px") - .style("z-index", 5); - - this.plot_group = plot_area.append("svg") - .attr("class", "plot-svg") - .style("z-index", 10); - - this.legend_group = group.append("div") - .attr("class", "plot-legend-group"); - - this.y_axis = d3.svg.axis() - .scale(this.dimension_y.scale()) - .orient("left"); - - this.dimension_y.format(this.y_axis, this.width); - - this.x_axis = d3.svg.axis() - .scale(this.dimension_x.scale()) - .orient("bottom"); - - this.dimension_x.format(this.x_axis, this.height); - - this.plot_group.append("g") - .attr("class", "y axis pale") - .attr("transform", "translate(" + this.margin.left + "," + this.margin.top + ")") - .call(this.y_axis); - - this.plot_group.append("g") - .attr("class", "x axis pale") - .attr("transform", "translate(" + this.margin.left + ", " + (this.height + this.margin.top) + ")") - .call(this.x_axis); - - - this.x = this.dimension_x; - this.y = this.dimension_y; - - this.legend = CanvasPlotLegend(); - this.legend_list = []; - - this.line_renderer = CanvasPlotLine().x(this.x).y(this.y); - this.area_renderer = CanvasPlotArea().x(this.x).y(this.y); - this.error_bar_renderer = CanvasErrorBar().x(this.x).y(this.y); - this.stippled_line_renderer = CanvasPlotStippledLine().x(this.x).y(this.y); -} - -BasePlot.prototype.resize = function(width, height) { - //Some magic margins... - width = width - 80; - height = height - 70; - - this.width = width - this.margin.left - this.margin.right; - this.height = height - this.margin.top - this.margin.bottom; - - this.dimension_x.format(this.x_axis, this.height); - this.dimension_y.format(this.y_axis, this.width); - - this.dimension_x.setRange(0, this.width); - this.dimension_y.setRange(this.height, 0); - - this.plot_group.style("width", width + "px").style("height", height + "px"); - - this.canvas.attr("width", this.width).attr("height", this.height); - this.overlay_canvas.attr("width", this.width).attr("height", this.height); - - this.plot_group.select(".x.axis").attr("transform", "translate(" + this.margin.left + ", " + (this.height + this.margin.top) + ")"); -}; - -BasePlot.prototype.setScales = function(x_min, x_max, y_min, y_max) { - - if(this.custom_y_min != y_min || this.custom_y_max != y_max || - this.custom_x_min != x_min || this.custom_x_max != x_max) { - this.custom_y_min = y_min; - this.custom_y_max = y_max; - this.custom_x_min = x_min; - this.custom_x_max = x_max; - } -}; - -BasePlot.prototype.setYDomain = function(min_y, max_y, ordinals) { - if (arguments.length == 3 && this.dimension_y.isOrdinal()) { - this.dimension_y.setDomain(ordinals); - } else { - var min = min_y; - var max = max_y; - - if (this.custom_y_min != null) { - min = this.custom_y_min; - } - - if (this.custom_y_max != null) { - max = this.custom_y_max; - } - - this.dimension_y.setDomain(min, max); - } -}; - -BasePlot.prototype.setXDomain = function(min_x, max_x, ordinals) { - if (arguments.length == 3 && this.dimension_x.isOrdinal()) { - this.dimension_x.setDomain(ordinals); - } else { - var min = min_x; - var max = max_x; - if (this.custom_x_min != null) { - min = this.custom_x_min; - } - - if (this.custom_x_max != null) { - max = this.custom_x_max; - } - - this.dimension_x.setDomain(min, max); - } -}; - -BasePlot.prototype.setData = function(data) { - this.stored_data = data; -}; - -BasePlot.prototype.getTitle = function(){ - if(this.stored_data != null && "name" in this.stored_data){ - return this.stored_data.name(); - } else { - return "No data"; - } -}; - -BasePlot.prototype.render = function() { - if(this.stored_data == null) { - return; - } - - var data = this.stored_data; - this.render_finished = false; - this.render_callback_finished = false; - - this.title.text(this.getTitle()); - - if (this.dimension_x.getUnit() == "") { - this.x_label.text(""); - } else { - this.x_label.text("X: " + this.dimension_x.getUnit()); - } - - if (this.dimension_y.getUnit() == "") { - this.y_label.text(""); - } else { - this.y_label.text("Y: " + this.dimension_y.getUnit()); - } - - if(data.hasBoundaries()) { - this.setYDomain(data.minY(), data.maxY()); - this.setXDomain(data.minX(), data.maxX()); - } - - if(this.pre_render_callback != null) { - this.pre_render_callback(data); - } - - this.resetLegends(); - - var axis = this.plot_group.select(".y.axis").call(this.y_axis); - this.dimension_y.relabel(axis); - - axis = this.plot_group.select(".x.axis").call(this.x_axis); - this.dimension_x.relabel(axis); - - this.canvas.attr("width", this.width).attr("height", this.height); - this.overlay_canvas.attr("width", this.width).attr("height", this.height); - - var context = this.canvas.node().getContext("2d"); - context.save(); - context.clearRect(0, 0, this.width, this.height); - - var overlay_context = this.overlay_canvas.node().getContext("2d"); - overlay_context.save(); - overlay_context.clearRect(0, 0, this.width, this.height); - - this.render_callback(context, data); - - if(this.render_observations) { - this.renderObservations(overlay_context, data); - } - - if(this.render_refcase) { - this.renderRefcase(overlay_context, data); - } - - overlay_context.restore(); - context.restore(); - this.finishedRendering(); - -}; - -BasePlot.prototype.setRenderCallback = function(callback) { - this.render_callback = callback; -}; - -BasePlot.prototype.setPreRenderCallback = function(callback) { - this.pre_render_callback = callback; -}; - - -BasePlot.prototype.resetLegends = function() { - this.legend_list = []; -}; - -BasePlot.prototype.addLegend = function(style, name, render_function) { - this.legend_list.push({"style": style, "name": name,"render_function": render_function}); -}; - - -BasePlot.prototype.renderObservations = function(context, data) { - if(data.hasObservationData()) { - var obs_data = data.observationData(); - if(obs_data.isContinuous() && !this.error_bar_only) { - var x_values = obs_data.xValues(); - var y_values = obs_data.yValues(); - var std_values = obs_data.stdValues(); - - var obs_x_area_samples = []; - var obs_y_area_samples = []; - - for (var index = 0; index < x_values.length; index++) { - obs_x_area_samples.push(x_values[index]); - obs_y_area_samples.push(y_values[index] + std_values[index]); - } - - for (var index = x_values.length - 1; index >= 0; index--) { - obs_x_area_samples.push(x_values[index]); - obs_y_area_samples.push(y_values[index] - std_values[index]); - } - - this.area_renderer.style(STYLES["observation_area"]); - this.area_renderer(context, obs_x_area_samples, obs_y_area_samples); - - this.stippled_line_renderer.style(STYLES["observation"]); - this.stippled_line_renderer(context, x_values, y_values); - - this.addLegend(STYLES["observation"], "Observation", CanvasPlotLegend.stippledLine); - this.addLegend(STYLES["observation_area"], "Observation error", CanvasPlotLegend.filledCircle); - - } else { - - var obs_x_samples = obs_data.xValues(); - var obs_y_samples = obs_data.yValues(); - var obs_std_samples = obs_data.stdValues(); - - for (var index = 0; index < obs_x_samples.length; index++) { - var x = obs_x_samples[index]; - var y = obs_y_samples[index]; - var error = obs_std_samples[index]; - - this.error_bar_renderer.style(STYLES["observation_error_bar"]); - this.error_bar_renderer(context, x, y, error, this.vertical_error_bar); - } - this.addLegend(STYLES["observation_error_bar"], "Observation error bar", CanvasPlotLegend.errorBar); - } - } -}; - - -BasePlot.prototype.renderRefcase = function(context, data) { - if(data.hasRefcaseData()) { - var refcase_data = data.refcaseData(); - var style = STYLES["refcase"]; - - this.line_renderer.style(style); - this.line_renderer(context, refcase_data.xValues(), refcase_data.yValues()); - - this.addLegend(style, "Refcase", CanvasPlotLegend.simpleLine); - } -}; - -BasePlot.prototype.createLineRenderer = function() { - return CanvasPlotLine().x(this.x).y(this.y); -}; - -BasePlot.prototype.createCircleRenderer = function() { - return CanvasCircle().x(this.x).y(this.y); -}; - -BasePlot.prototype.createCrossRenderer = function() { - return CanvasCross().x(this.x).y(this.y); -}; - -BasePlot.prototype.createStippledLineRenderer = function() { - return CanvasPlotStippledLine().x(this.x).y(this.y); -}; - -BasePlot.prototype.createAreaRenderer = function() { - return CanvasPlotArea().x(this.x).y(this.y); -}; - - -BasePlot.prototype.setVerticalErrorBar = function(vertical){ - this.vertical_error_bar = vertical; - -}; - -BasePlot.prototype.setCustomSettings = function (settings) { - if ("error_bar_only" in settings) { - this.error_bar_only = settings["error_bar_only"]; - } - - if ("show_observations" in settings) { - this.setRenderObservations(settings["show_observations"]); - } - - if ("show_refcase" in settings) { - this.setRenderRefcase(settings["show_refcase"]); - } -}; - -BasePlot.prototype.renderCallbackFinishedRendering = function(){ - this.render_callback_finished = true; - this.emitFinishedRendering() -}; - -BasePlot.prototype.finishedRendering = function(){ - this.render_finished = true; - this.emitFinishedRendering(); -}; - -BasePlot.prototype.emitFinishedRendering = function(){ - if(this.rendering_finished_callback != null){ - if(this.render_finished && this.render_callback_finished) { - this.legend_group.selectAll(".plot-legend").data(this.legend_list).call(this.legend); - this.rendering_finished_callback(); - } - } -}; - -BasePlot.prototype.setRenderingFinishedCallback = function(callback) { - this.rendering_finished_callback = callback; -}; - -BasePlot.prototype.setLogScaleOnDimensionX = function(use_log_scale) { - this.dimension_x.setIsLogScale(use_log_scale); - this.x_axis.scale(this.dimension_x.scale()); - this.dimension_x.format(this.x_axis, this.height); -}; - -BasePlot.prototype.setLogScaleOnDimensionY = function(use_log_scale) { - this.dimension_y.setIsLogScale(use_log_scale); - this.y_axis.scale(this.dimension_y.scale()); - this.dimension_y.format(this.y_axis, this.width); -}; - -BasePlot.prototype.setRenderObservations = function(enabled) { - this.render_observations = enabled; -}; - -BasePlot.prototype.setRenderRefcase = function(enabled) { - this.render_refcase = enabled; -}; - -function isNumber(n) { - return !isNaN(parseFloat(n)) && isFinite(n); -} diff --git a/ThirdParty/Ert/devel/share/gui/plots/scripts/base_plot_integer_dimension.js b/ThirdParty/Ert/devel/share/gui/plots/scripts/base_plot_integer_dimension.js deleted file mode 100644 index d0f62f3bba..0000000000 --- a/ThirdParty/Ert/devel/share/gui/plots/scripts/base_plot_integer_dimension.js +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright (C) 2014 Statoil ASA, Norway. -// -// The file 'base_plot_time_dimension.js' is part of ERT - Ensemble based Reservoir Tool. -// -// ERT is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// ERT is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. -// -// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> -// for more details. - -function BasePlotIntegerDimension(){ - var scale = d3.time.scale().range([0, 1]).domain([1, 0]); - var unit = ""; - - var scaler = function(d) { - return scale(d); - }; - - var count_format = d3.format("d"); - - function dimension(value) { - return scaler(value); - } - - dimension.setDomain = function(min, max) { - if(min == max) { - min = Math.floor(min - 0.1 * min); - max = Math.ceil(max + 0.1 * max); - } - - scale.domain([min, max]); - - }; - - dimension.setRange = function(min, max) { - scale.range([min, max]); - }; - - dimension.scale = function() { - return scale; - }; - - dimension.isOrdinal = function() { - return false; - }; - - dimension.format = function(axis, max_length){ - axis.ticks(5) - .tickSize(-max_length, -max_length) - .tickFormat(count_format); - - return dimension; - }; - - dimension.relabel = function (axis) { - - }; - - dimension.setUnit = function(unit_in) { - unit = unit_in; - }; - - dimension.getUnit = function() { - return unit; - }; - - return dimension; -} \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/plots/scripts/base_plot_ordinal_dimension.js b/ThirdParty/Ert/devel/share/gui/plots/scripts/base_plot_ordinal_dimension.js deleted file mode 100644 index d46197f0f2..0000000000 --- a/ThirdParty/Ert/devel/share/gui/plots/scripts/base_plot_ordinal_dimension.js +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright (C) 2014 Statoil ASA, Norway. -// -// The file 'base_plot_ordinal_dimension.js' is part of ERT - Ensemble based Reservoir Tool. -// -// ERT is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// ERT is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. -// -// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> -// for more details. - -function BasePlotOrdinalDimension(point_style){ - var scale = null; - var unit = ""; - - if(point_style) { - scale = d3.scale.ordinal().rangePoints([0, 1], 1).domain(["unknown"]); - } else { - scale = d3.scale.ordinal().rangeRoundBands([0, 1], .5).domain(["unknown"]); - } - - var scaler = function(d) { - return scale(d); - }; - - function dimension(value) { - return scaler(value); - } - - dimension.setDomain = function(values) { - scale.domain(values); - }; - - dimension.setRange = function(min, max) { - if(point_style) { - scale.rangePoints([min, max], 1); - } else { - scale.rangeRoundBands([min, max], .5); - } - }; - - dimension.scale = function() { - return scale; - }; - - dimension.format = function(axis, max_length){ - axis.tickSize(-max_length, -max_length); - - return dimension; - }; - - dimension.isOrdinal = function() { - return true; - }; - - dimension.relabel = function (axis) { - - }; - - dimension.setUnit = function(unit_in) { - unit = unit_in; - }; - - dimension.getUnit = function() { - return unit; - }; - - return dimension; -} \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/plots/scripts/base_plot_time_dimension.js b/ThirdParty/Ert/devel/share/gui/plots/scripts/base_plot_time_dimension.js deleted file mode 100644 index d69c7b6663..0000000000 --- a/ThirdParty/Ert/devel/share/gui/plots/scripts/base_plot_time_dimension.js +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright (C) 2014 Statoil ASA, Norway. -// -// The file 'base_plot_time_dimension.js' is part of ERT - Ensemble based Reservoir Tool. -// -// ERT is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// ERT is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. -// -// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> -// for more details. - -function BasePlotTimeDimension(){ -// var scale = d3.scale.linear().range([1, 0]).domain([0, 1]).nice(); - var scale = d3.time.scale().range([0, 1]).domain([1, 0]); - var time_scale = d3.time.scale().range([0, 1]).domain([1, 0]); - - var unit = "Date"; - - var scaler = function(d) { - return scale(d); - }; - - var customTimeFormat = d3.time.format.multi([ - [".%L", function(d) { return d.getMilliseconds(); }], - [":%S", function(d) { return d.getSeconds(); }], - ["%I:%M", function(d) { return d.getMinutes(); }], - ["%I %p", function(d) { return d.getHours(); }], - ["%a %d", function(d) { return d.getDay() && d.getDate() != 1; }], - ["%b %d", function(d) { return d.getDate() != 1; }], - ["%b", function(d) { return d.getMonth(); }], - ["%Y", function() { return true; }] - ]); - - function dimension(value) { - return scaler(value); - } - - dimension.setDomain = function(min, max) { - time_scale.domain([new Date(min * 1000), new Date(max * 1000)]).nice(); - var domain = time_scale.domain(); - scale.domain([domain[0].getTime() / 1000, domain[1].getTime() / 1000]); - }; - - dimension.setRange = function(min, max) { - scale.range([min, max]); - time_scale.range([min, max]); - }; - - dimension.scale = function() { - return time_scale; - }; - - dimension.isOrdinal = function() { - return false; - }; - - dimension.format = function(axis, max_length){ - axis.tickFormat(customTimeFormat); - - return dimension; - }; - - dimension.relabel = function (axis) { - - }; - - dimension.setUnit = function(unit_in) { - unit = unit_in; - }; - - dimension.getUnit = function() { - return unit; - }; - - return dimension; -} \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/plots/scripts/base_plot_value_dimension.js b/ThirdParty/Ert/devel/share/gui/plots/scripts/base_plot_value_dimension.js deleted file mode 100644 index 2ff866d8b7..0000000000 --- a/ThirdParty/Ert/devel/share/gui/plots/scripts/base_plot_value_dimension.js +++ /dev/null @@ -1,157 +0,0 @@ -// Copyright (C) 2014 Statoil ASA, Norway. -// -// The file 'base_plot_value_dimension.js' is part of ERT - Ensemble based Reservoir Tool. -// -// ERT is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// ERT is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. -// -// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> -// for more details. - -function BasePlotValueDimension(flip_range) { - if (!arguments.length) { - var flip_range = false; - } - - var is_log_scale = false; - var tick_count = 10; - var ticks = null; - var unit = ""; - - var scale = d3.scale.linear().range([1, 0]).domain([0, 1]).nice(); - var log_scale = d3.scale.log().range([1, 0]).domain([0, 1]).nice(); - - var value_format = d3.format(".4g"); -// var value_log_format = d3.format("e"); -// -// var value_log_format_function = function (d) { -// var x = Math.log(d) / Math.log(10) + 1e-6; -// return Math.abs(x - Math.floor(x)) < 0.3 ? value_log_format(d) : ""; -// }; - - var scaler = function (d) { - if (is_log_scale) { - return log_scale(d); - } else { - return scale(d); - } - }; - - function dimension(value) { - return scaler(value); - } - - function powerOfTen(d) { - return d / Math.pow(10, Math.ceil(Math.log(d) / Math.LN10 - 1e-12)) === 1; - } - - dimension.setDomain = function (min, max) { - if (min == max) { - min = min - 0.1 * min; - max = max + 0.1 * max; - } - - if (flip_range) { - var tmp = min; - min = max; - max = tmp; - } - scale.domain([min, max]).nice(); - - - if(min <= 0.0) { - min = 0.000000001; - } - - if(max <= 0.0) { - max = 0.000000016; - } - - var from_log = Math.floor(Math.log(min) / Math.log(10)); - var to_log = Math.ceil(Math.log(max) / Math.log(10)); - var from = Math.pow(10, from_log); - var to = Math.pow(10, to_log); - log_scale.domain([from, to]); - }; - - dimension.setRange = function (min, max) { - scale.range([min, max]).nice(); - log_scale.range([min, max]).nice(); - }; - - dimension.scale = function () { - if (is_log_scale) { - return log_scale; - } else { - return scale; - } - }; - - dimension.isOrdinal = function () { - return false; - }; - - dimension.format = function (axis, max_length) { - - if (is_log_scale) { - axis.tickValues(null) - .tickPadding(10) - .ticks(1) - .tickSize(-max_length, -max_length); -// .tickFormat(value_log_format_function); - } else { - axis.tickPadding(10) - .tickSize(-max_length, -max_length) - .tickFormat(value_format) - .ticks(tick_count) - .tickValues(ticks); - } - - return dimension; - }; - - dimension.setIsLogScale = function (use_log_scale) { - is_log_scale = use_log_scale; - }; - - dimension.isLogScale = function () { - return is_log_scale; - }; - - dimension.relabel = function (axis) { - if (is_log_scale) { - axis.selectAll(".tick text") - .text(null) - .filter(powerOfTen) - .text(function (d) { - return "1.0×10"; - }) - .append("tspan") - .style("font-size", "70%") - .attr("dy", "-.7em") - .text(function (d) { - return Math.round(Math.log(d) / Math.LN10); - }); - } - }; - - dimension.setTicks = function(tick_list) { - ticks = tick_list; - }; - - dimension.setUnit = function(unit_in) { - unit = unit_in; - }; - - dimension.getUnit = function() { - return unit; - }; - - return dimension; -} diff --git a/ThirdParty/Ert/devel/share/gui/plots/scripts/canvas_error_bar.js b/ThirdParty/Ert/devel/share/gui/plots/scripts/canvas_error_bar.js deleted file mode 100644 index 2081f2c155..0000000000 --- a/ThirdParty/Ert/devel/share/gui/plots/scripts/canvas_error_bar.js +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright (C) 2013 Statoil ASA, Norway. -// -// The file 'canvas_error_bar.js' is part of ERT - Ensemble based Reservoir Tool. -// -// ERT is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// ERT is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. -// -// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> -// for more details. - - - -function CanvasErrorBar() { - var X = function (d) { return d; }; - var Y = function (d) { return d; }; - var style = STYLES["default"]; - var radius = 2.5; - - function render(context, x, y, error, vertical) { - context.lineWidth = style["stroke_width"]; - context.strokeStyle = style["stroke"]; - - x = X(x); - y = Y(y); - - context.beginPath(); - context.arc(x, y, radius, 0, 2 * Math.PI); - context.stroke(); - - - context.beginPath(); - if(vertical){ - error = Y(y + error) - Y(y); - - context.moveTo(x, y - radius); - context.lineTo(x, y - radius + error); - - context.moveTo(x - radius, y - radius + error); - context.lineTo(x + radius, y - radius + error); - - context.moveTo(x, y + radius); - context.lineTo(x, y + radius - error); - - context.moveTo(x - radius, y + radius - error); - context.lineTo(x + radius, y + radius - error); - - } else { - error = X(x + error) - X(x); - - context.moveTo(x - radius, y); - context.lineTo(x - radius + error, y); - - context.moveTo(x - radius + error, y - radius); - context.lineTo(x - radius + error, y + radius); - - context.moveTo(x + radius, y); - context.lineTo(x + radius - error, y); - - context.moveTo(x + radius - error, y - radius); - context.lineTo(x + radius - error, y + radius); - } - - context.stroke(); - - } - - render.x = function (value) { - if (!arguments.length) return X; - X = value; - return render; - }; - - render.y = function (value) { - if (!arguments.length) return Y; - Y = value; - return render; - }; - - render.style = function (value) { - if (!arguments.length) return style; - style = value; - return render; - }; - - return render; -} \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/plots/scripts/canvas_plot.js b/ThirdParty/Ert/devel/share/gui/plots/scripts/canvas_plot.js deleted file mode 100644 index ac70f58b21..0000000000 --- a/ThirdParty/Ert/devel/share/gui/plots/scripts/canvas_plot.js +++ /dev/null @@ -1,218 +0,0 @@ -// Copyright (C) 2013 Statoil ASA, Norway. -// -// The file 'canvas_plot.js' is part of ERT - Ensemble based Reservoir Tool. -// -// ERT is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// ERT is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. -// -// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> -// for more details. - - -function Plot(element, x_dimension, y_dimension) { - this.plot = new BasePlot(element, x_dimension, y_dimension); - - this.horizontal_draw_direction = true; - this.waiting_for_render_restart = false; - - - this.line_renderers = []; - for (var index = 1; index <= 5; index++) { - var renderer = this.plot.createLineRenderer(); - renderer.style(STYLES["ensemble_" + (index)]); - this.line_renderers.push(renderer) - } - - this.circle_renderers = []; - for (var index = 1; index <= 5; index++) { - var renderer = this.plot.createCircleRenderer(); - renderer.style(STYLES["ensemble_" + (index)]); - this.circle_renderers.push(renderer) - } - - this.tracker = new IncrementalRenderTracker(); - - var self = this; - - var progressivePreRenderer = function (context, data) { - var case_list = data.caseList(); - - for (var case_index = 0; case_index < case_list.length; case_index++) { - var style = STYLES["ensemble_" + (case_index + 1)]; - var case_name = case_list[case_index]; - - self.plot.addLegend(style, case_name, CanvasPlotLegend.simpleLine); - } - - self.progressiveRenderer(context, data, self, 0, 0); - }; - - var renderEnsembleProgressively = function (context, data) { - if (data.hasEnsembleData()) { - self.tracker.start(function () { - progressivePreRenderer(context, data); - }); - } - }; - - this.progressiveRenderer = function (context, data, self, case_index, realization) { - if (self.tracker.shouldStop()) { - self.tracker.stoppedRendering(); - return; - } - - var case_list = data.caseList(); - var case_name = case_list[case_index]; - var line_renderer = self.line_renderers[case_index]; - var circle_renderer = self.circle_renderers[case_index]; - - var ensemble_data = data.ensembleData(case_name); - var x_values = ensemble_data.xValues(); - var y_values = ensemble_data.yValues(); - - var realization_count = y_values.length; - if (!self.horizontal_draw_direction) { - realization_count = x_values.length; - } - - self.tracker.loopStart(); - for (var i = realization; i < realization_count; i++) { - if (self.horizontal_draw_direction) { - if(x_values.length == 1) { - circle_renderer(context, x_values[0], y_values[i][0]) - } else { - line_renderer(context, x_values, y_values[i]); - } - - } else { - if(y_values.length == 1) { - circle_renderer(context, x_values[i][0], y_values[0]) - } else { - line_renderer(context, x_values[i], y_values); - } - } - - realization++; - - if (self.tracker.shouldLoopStop()) { - break; - } - } - - if (realization == realization_count) { - case_index++; - realization = 0; - } - - if (case_index < case_list.length) { - window.setTimeout(function () { - self.progressiveRenderer(context, data, self, case_index, realization); - }, 15); - } else { - self.tracker.stoppedRendering(); - self.plot.renderCallbackFinishedRendering(); - } - }; - - - var renderEnsembleDirect = function(context, data) { - if(data.hasEnsembleData()) { - var case_list = data.caseList(); - - for(var case_index = 0; case_index < case_list.length; case_index++) { - var style = STYLES["ensemble_" + (case_index + 1)]; - var case_name = case_list[case_index]; - var line_renderer = self.line_renderers[case_index]; - var circle_renderer = self.circle_renderers[case_index]; - - var ensemble_data = data.ensembleData(case_name); - var x_values = ensemble_data.xValues(); - var y_values = ensemble_data.yValues(); - - var realization_count = y_values.length; - if (!self.horizontal_draw_direction) { - realization_count = x_values.length; - } - - - for (var i = 0; i < realization_count; i++) { - if (self.horizontal_draw_direction) { - if(x_values.length == 1) { - circle_renderer(context, x_values[0], y_values[i][0]) - } else { - line_renderer(context, x_values, y_values[i]); - } - - } else { - if(y_values.length == 1) { - circle_renderer(context, x_values[i][0], y_values[0]) - } else { - line_renderer(context, x_values[i], y_values); - } - } - - } - - self.plot.addLegend(style, case_name, CanvasPlotLegend.simpleLine); - } - self.plot.renderCallbackFinishedRendering(); - } - }; - - this.plot.setRenderCallback(renderEnsembleProgressively); - //this.plot.setRenderCallback(renderEnsembleDirect); -} - -Plot.prototype.resize = function (width, height) { - this.plot.resize(width, height); -}; - -Plot.prototype.setScales = function (x_min, x_max, y_min, y_max) { - this.plot.setScales(x_min, x_max, y_min, y_max); -}; - -Plot.prototype.setData = function (data) { - this.plot.setData(data); -}; - -Plot.prototype.setVerticalErrorBar = function (vertical) { - this.plot.setVerticalErrorBar(vertical); -}; - -Plot.prototype.setHorizontalDrawDirection = function (horizontal) { - this.horizontal_draw_direction = horizontal; -}; - -Plot.prototype.setCustomSettings = function (settings) { - this.plot.setCustomSettings(settings); -}; - -Plot.prototype.setRenderingFinishedCallback = function(callback) { - this.plot.setRenderingFinishedCallback(callback); -}; - -Plot.prototype.renderNow = function(){ - if(!this.tracker.isRunning()) { - this.waiting_for_render_restart = false; - this.plot.render(); - } else { - if(!this.waiting_for_render_restart) { - this.tracker.forceStop(); - this.waiting_for_render_restart = true; - - window.setTimeout(function () { - self.renderNow(); - }, 15); - } - } -}; - -Plot.prototype.getTitle = function(){ - return this.plot.getTitle(); -}; diff --git a/ThirdParty/Ert/devel/share/gui/plots/scripts/canvas_plot_area.js b/ThirdParty/Ert/devel/share/gui/plots/scripts/canvas_plot_area.js deleted file mode 100644 index 55ca1b417c..0000000000 --- a/ThirdParty/Ert/devel/share/gui/plots/scripts/canvas_plot_area.js +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright (C) 2013 Statoil ASA, Norway. -// -// The file 'canvas_plot_area.js' is part of ERT - Ensemble based Reservoir Tool. -// -// ERT is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// ERT is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. -// -// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> -// for more details. - - -function CanvasPlotArea() { - var x = function(d) { return d;}; - var y = function(d) { return d;}; - var style = STYLES["default"]; - - function render(context, x_samples, y_samples) { - context.lineWidth = style["stroke_width"]; - context.strokeStyle = style["stroke"]; - context.fillStyle = style["fill"]; - - context.beginPath(); - for(var index in x_samples) { - var x_sample = x_samples[index]; - var y_sample = y_samples[index]; - if(index == 0) { - context.moveTo(x(x_sample), y(y_sample)); - } else { - context.lineTo(x(x_sample), y(y_sample)); - } - } - context.closePath(); - context.stroke(); - context.fill(); - } - - render.x = function(value) { - if (!arguments.length) return x; - x = value; - return render; - }; - - render.y = function(value) { - if (!arguments.length) return y; - y = value; - return render; - }; - - render.style = function(value) { - if (!arguments.length) return style; - style = value; - return render; - }; - - return render; -} - -//append list_2 reversed to list_1 as a new list -CanvasPlotArea.mergePoints = function(list_1, list_2) { - var result = []; - - for (var j = 0; j < list_1.length; j++) { - result.push(list_1[j]); - } - - for (var k = list_2.length - 1; k >= 0; k--) { - result.push(list_2[k]); - } - - return result; -}; \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/plots/scripts/canvas_plot_circle.js b/ThirdParty/Ert/devel/share/gui/plots/scripts/canvas_plot_circle.js deleted file mode 100644 index 48e1ef1081..0000000000 --- a/ThirdParty/Ert/devel/share/gui/plots/scripts/canvas_plot_circle.js +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright (C) 2013 Statoil ASA, Norway. -// -// The file 'canvas_plot_circle.js' is part of ERT - Ensemble based Reservoir Tool. -// -// ERT is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// ERT is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. -// -// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> -// for more details. - - - -function CanvasCircle() { - var X = function (d) { return d; }; - var Y = function (d) { return d; }; - var style = STYLES["default"]; - var radius = 2.5; - var fill = false; - - function render(context, x, y) { - context.lineWidth = style["stroke_width"]; - context.strokeStyle = style["stroke"]; - context.fillStyle = style["fill"]; - - context.beginPath(); - context.arc(X(x), Y(y), radius, 0, 2 * Math.PI); - - if(fill) { - context.fill(); - } - - context.stroke(); - } - - render.x = function (value) { - if (!arguments.length) return X; - X = value; - return render; - }; - - render.y = function (value) { - if (!arguments.length) return Y; - Y = value; - return render; - }; - - render.style = function (value) { - if (!arguments.length) return style; - style = value; - return render; - }; - - render.fillCircle = function(fill_circle) { - if (!arguments.length) return fill; - fill = fill_circle; - return render; - }; - - render.radius = function(value) { - if (!arguments.length) return radius; - radius = value; - return render; - }; - - return render; -} \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/plots/scripts/canvas_plot_cross.js b/ThirdParty/Ert/devel/share/gui/plots/scripts/canvas_plot_cross.js deleted file mode 100644 index 1f66513ea5..0000000000 --- a/ThirdParty/Ert/devel/share/gui/plots/scripts/canvas_plot_cross.js +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright (C) 2013 Statoil ASA, Norway. -// -// The file 'canvas_plot_circle.js' is part of ERT - Ensemble based Reservoir Tool. -// -// ERT is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// ERT is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. -// -// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> -// for more details. - - - -function CanvasCross() { - var X = function (d) { return d; }; - var Y = function (d) { return d; }; - var style = STYLES["default"]; - var radius = 2.5; - var fill = false; - - function render(context, x, y) { - context.lineWidth = style["stroke_width"]; - context.strokeStyle = style["stroke"]; - context.fillStyle = style["fill"]; - - var cx = X(x); - var cy = Y(y); - context.beginPath(); - context.moveTo(cx - radius, cy - radius); - context.lineTo(cx + radius, cy + radius); - - context.moveTo(cx + radius, cy - radius); - context.lineTo(cx - radius, cy + radius); - - context.stroke(); - } - - render.x = function (value) { - if (!arguments.length) return X; - X = value; - return render; - }; - - render.y = function (value) { - if (!arguments.length) return Y; - Y = value; - return render; - }; - - render.style = function (value) { - if (!arguments.length) return style; - style = value; - return render; - }; - - render.radius = function(value) { - if (!arguments.length) return radius; - radius = value; - return render; - }; - - return render; -} \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/plots/scripts/canvas_plot_distribution.js b/ThirdParty/Ert/devel/share/gui/plots/scripts/canvas_plot_distribution.js deleted file mode 100644 index 8ea0167fcc..0000000000 --- a/ThirdParty/Ert/devel/share/gui/plots/scripts/canvas_plot_distribution.js +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright (C) 2014 Statoil ASA, Norway. -// -// The file 'canvas_plot_distribution.js' is part of ERT - Ensemble based Reservoir Tool. -// -// ERT is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// ERT is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. -// -// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> -// for more details. - - -function DistributionPlot(element, x_dimension, y_dimension) { - this.plot = new BasePlot(element, x_dimension, y_dimension); - this.horizontal_draw_direction = true; - - var self = this; - - var preRenderCallback = function(data) { - if (data.hasEnsembleData()) { - if (!self.horizontal_draw_direction) { - self.plot.setLogScaleOnDimensionX(data.shouldUseLogScale()); - } else { - self.plot.setLogScaleOnDimensionY(data.shouldUseLogScale()); - } - - self.plot.setXDomain(data.minX(), data.maxX(), data.caseList()); - self.plot.setYDomain(data.minY(), data.maxY(), data.caseList()); - } - }; - - var renderCallback = function (context, data) { - if (data.hasEnsembleData()) { - var case_list = data.caseList(); - - for (var i = 0; i < case_list.length; i++) { - var style = STYLES[("ensemble_" + (i + 1))]; - var case_name = case_list[i]; - var ensemble_data = data.ensembleData(case_name); - - - var values; - if (!self.horizontal_draw_direction) { - values = ensemble_data.xValues(); - } else { - values = ensemble_data.yValues(); - } - - var circle_renderer = self.plot.createCircleRenderer(); - circle_renderer.style(style); - circle_renderer.fillCircle(true); - circle_renderer.radius(5); - - for(var j = 0; j < values.length; j++) { - var value = values[j]; - if(isNumber(value)) { - if (self.horizontal_draw_direction) { - circle_renderer(context, case_name, value); - } else { - circle_renderer(context, value, case_name); - } - } - } - - self.plot.addLegend(style, case_name, CanvasPlotLegend.filledCircle); - } - self.plot.renderCallbackFinishedRendering(); - } - }; - - this.plot.setPreRenderCallback(preRenderCallback); - this.plot.setRenderCallback(renderCallback); -} - -DistributionPlot.prototype.resize = function (width, height) { - this.plot.resize(width, height); -}; - -DistributionPlot.prototype.setScales = function (x_min, x_max, y_min, y_max) { - this.plot.setScales(x_min, x_max, y_min, y_max); -}; - -DistributionPlot.prototype.setData = function (data) { - this.plot.setData(data); -}; - -DistributionPlot.prototype.setHorizontalDrawDirection = function (horizontal) { - this.horizontal_draw_direction = horizontal; -}; - -DistributionPlot.prototype.setCustomSettings = function (settings) { - this.plot.setCustomSettings(settings); -}; - -DistributionPlot.prototype.renderNow = function(){ - this.plot.render(); -}; - -DistributionPlot.prototype.getTitle = function(){ - return this.plot.getTitle(); -}; diff --git a/ThirdParty/Ert/devel/share/gui/plots/scripts/canvas_plot_legend.js b/ThirdParty/Ert/devel/share/gui/plots/scripts/canvas_plot_legend.js deleted file mode 100644 index 458a68c5d5..0000000000 --- a/ThirdParty/Ert/devel/share/gui/plots/scripts/canvas_plot_legend.js +++ /dev/null @@ -1,254 +0,0 @@ -// Copyright (C) 2013 Statoil ASA, Norway. -// -// The file 'canvas_plot_legend.js' is part of ERT - Ensemble based Reservoir Tool. -// -// ERT is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// ERT is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. -// -// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> -// for more details. - - -function CanvasPlotLegend() { - - var size = 12; - - function legend(selection) { - var groups = selection.enter() - .append("div") - .attr("class", "plot-legend"); - - groups.append("canvas") - .attr("width", size) - .attr("height", size) - .attr("class", "legend-marker") - .call(markerRenderer); - - selection.selectAll(".legend-marker") - .data(function(d) { return [d];}) - .transition() - .call(markerRenderer); - - groups.append("div") - .attr("class", "plot-legend-label") - .text(function(d) { - return d["name"]; - }); - - selection.selectAll(".plot-legend-label") - .data(function(d) { - return [d]; - }) - .transition() - .text(function(d) { - return d["name"]; - }); - - selection.exit() - .remove(); - } - - var markerRenderer = function(selection) { - selection.each(function(datum) { - var ctx = d3.select(this).node().getContext("2d"); - ctx.clearRect(0, 0, size, size); - var style = datum["style"]; - - ctx.save(); - if("render_function" in datum) { - ctx.transform(1, 0, 0, 1, 1, 1); - datum["render_function"](ctx, style, size - 2, size - 2); - } else { - ctx.fillStyle = style["fill"]; - ctx.fillRect(1, 1, size - 2, size - 2); - - ctx.strokeStyle = style["stroke"]; - ctx.lineWidth = style["stroke_width"]; - ctx.strokeRect(1, 1, size - 2, size - 2); - } - ctx.restore(); - }); - }; - - return legend; - -} - -CanvasPlotLegend.parseColor = function(input) { - var result = [255, 255, 255, 1]; - -// match = input.match(/^#([0-9a-f]{3})$/i); -// if(match) { -// match = match[1]; -// // in three-character format, each value is multiplied by 0x11 to give an -// // even scale from 0x00 to 0xff -// result[0] = parseInt(match.charAt(0), 16) * 0x11; -// result[1] = parseInt(match.charAt(1), 16) * 0x11; -// result[2] = parseInt(match.charAt(2), 16) * 0x11; -// return result; -// } -// -// console.log("2"); -// match = input.match(/^#([0-9a-f]{6})$/i); -// if(match) { -// match = match[1]; -// result[0] = parseInt(match.substr(0,2), 16); -// result[1] = parseInt(match.substr(2,4), 16); -// result[2] = parseInt(match.substr(4,6), 16); -// return result; -// } -// -// match = input.match(/^rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$/i); -// if(match) { -// result[0] = match[1]; -// result[1] = match[2]; -// result[2] = match[3]; -// return result; -// } -// if(input === undefined) { -// console.log("UNDEFINED!"); -// return result; -// } - var match = input.match(/^rgba\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+\.?\d*)\s*\)$/i); - if(match) { - result[0] = match[1]; - result[1] = match[2]; - result[2] = match[3]; - result[3] = parseFloat(match[4]); - return result; - } - - return result; -}; - -CanvasPlotLegend.asRgb = function(r, g, b) { - return "rgb(" + r + "," + g + "," + b + ")"; -}; - -CanvasPlotLegend.asRgba = function(r, g, b, a) { - return "rgba(" + r + "," + g + "," + b + "," + a + ")"; -}; - - -CanvasPlotLegend.componentToHex = function(c) { - var hex = c.toString(16); - return hex.length == 1 ? "0" + hex : hex; -}; - -CanvasPlotLegend.rgbToHex = function(r, g, b) { - return "#" + CanvasPlotLegend.componentToHex(r) + CanvasPlotLegend.componentToHex(g) + CanvasPlotLegend.componentToHex(b); -}; - -CanvasPlotLegend.circledLine = function(context, style, width, height) { - context.strokeStyle = style["stroke"]; - context.lineWidth = style["stroke_width"]; - context.fillStyle = style["fill"]; - context.beginPath(); - context.moveTo(0, height / 2); - context.lineTo(width, height / 2); - context.stroke(); - - context.beginPath(); - context.arc(width / 2, height / 2, 2.5, 0, 2 * Math.PI); - context.fill(); - context.stroke(); -}; - -CanvasPlotLegend.filledCircle = function(context, style, width, height) { - context.strokeStyle = style["stroke"]; - context.lineWidth = style["stroke_width"]; - context.fillStyle = style["fill"]; - - context.beginPath(); - context.arc(width / 2, height / 2, width / 2, 0, 2 * Math.PI); - context.fill(); - context.stroke(); -}; - -CanvasPlotLegend.cross = function(context, style, width, height) { - context.strokeStyle = style["stroke"]; - context.lineWidth = style["stroke_width"]; - context.fillStyle = style["fill"]; - - var cx = width / 2; - var cy = height / 2; - var radius = width / 2; - - context.beginPath(); - context.moveTo(cx - radius, cy - radius); - context.lineTo(cx + radius, cy + radius); - - context.moveTo(cx + radius, cy - radius); - context.lineTo(cx - radius, cy + radius); - context.stroke(); -}; - -CanvasPlotLegend.errorBar = function(context, style, width, height) { - context.strokeStyle = style["stroke"]; - context.lineWidth = 1; - context.fillStyle = style["fill"]; - var cx = width / 2; - var cy = height / 2; - var radius = 2; - context.beginPath(); - context.moveTo(cx, cy - radius); - context.lineTo(cx, 0); - context.moveTo(cx - radius, 0); - context.lineTo(cx + radius, 0); - - context.moveTo(cx, cy + radius); - context.lineTo(cx, height); - context.moveTo(cx - radius, height); - context.lineTo(cx + radius, height); - context.stroke(); - - context.beginPath(); - context.arc(cx, cy, radius, 0, 2 * Math.PI); - context.fill(); - context.stroke(); -}; - -CanvasPlotLegend.simpleLine = function(context, style, width, height) { - var color = style["stroke"]; - var rgba = CanvasPlotLegend.parseColor(color); - context.strokeStyle = CanvasPlotLegend.asRgba(rgba[0], rgba[1], rgba[2], 1.0); - context.lineWidth = style["stroke_width"] * 2; - - context.beginPath(); - context.moveTo(0, height / 2); - context.lineTo(width, height / 2); - context.stroke(); -}; - -CanvasPlotLegend.stippledLine = function(context, style, width, height) { - var line_renderer = CanvasPlotStippledLine(); - line_renderer.style(style); - line_renderer(context, [0, width], [height / 2, height / 2]); -}; - -CanvasPlotLegend.filledCircleWithLine = function(context, style, width, height) { - context.strokeStyle = style[0]["stroke"]; - context.lineWidth = style[0]["stroke_width"]; - context.fillStyle = style[0]["fill"]; - - context.beginPath(); - context.arc(width / 2, height / 2, (width - 1) / 2, 0, 2 * Math.PI); - context.fill(); - context.stroke(); - - - context.strokeStyle = style[1]["stroke"]; - context.lineWidth = style[1]["stroke_width"]; - context.fillStyle = style[1]["fill"]; - - context.beginPath(); - context.moveTo(0, height / 2); - context.lineTo(width, height / 2); - context.stroke(); -}; \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/plots/scripts/canvas_plot_line.js b/ThirdParty/Ert/devel/share/gui/plots/scripts/canvas_plot_line.js deleted file mode 100644 index 6fca068fcd..0000000000 --- a/ThirdParty/Ert/devel/share/gui/plots/scripts/canvas_plot_line.js +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright (C) 2013 Statoil ASA, Norway. -// -// The file 'canvas_plot_line.js' is part of ERT - Ensemble based Reservoir Tool. -// -// ERT is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// ERT is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. -// -// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> -// for more details. - -function CanvasPlotLine() { - var X = function (d) { return d; }; - var Y = function (d) { return d; }; - var style = STYLES["default"]; - - function render(context, x_samples, y_samples) { - context.lineWidth = style["stroke_width"]; - context.strokeStyle = style["stroke"]; - context.lineCap = style["line_cap"]; - - var length = Math.min(x_samples.length, y_samples.length); - - context.beginPath(); - for (var index = 0; index < length; index++) { - var x_sample = x_samples[index]; - var y_sample = y_samples[index]; - var x = X(x_sample); - var y = Y(y_sample); - - if (index == 0) { - context.moveTo(x, y); - } else { - context.lineTo(x, y); - } - } - - context.stroke(); - } - - render.x = function (value) { - if (!arguments.length) return X; - X = value; - return render; - }; - - render.y = function (value) { - if (!arguments.length) return Y; - Y = value; - return render; - }; - - render.style = function (value) { - if (!arguments.length) return style; - style = value; - return render; - }; - - return render; -} \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/plots/scripts/canvas_plot_overview.js b/ThirdParty/Ert/devel/share/gui/plots/scripts/canvas_plot_overview.js deleted file mode 100644 index dda9c48f3f..0000000000 --- a/ThirdParty/Ert/devel/share/gui/plots/scripts/canvas_plot_overview.js +++ /dev/null @@ -1,99 +0,0 @@ -// Copyright (C) 2013 Statoil ASA, Norway. -// -// The file 'canvas_plot_overview.js' is part of ERT - Ensemble based Reservoir Tool. -// -// ERT is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// ERT is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. -// -// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> -// for more details. - - -function OverviewPlot(element, x_dimension, y_dimension) { - this.plot = new BasePlot(element, x_dimension, y_dimension); - - this.horizontal_draw_direction = true; - - var self = this; - - var renderEnsemble = function (context, data) { - if (data.hasEnsembleData()) { - var case_list = data.caseList(); - - for (var i = 0; i < case_list.length; i++) { - var style = STYLES[("ensemble_" + (i + 1))]; - var case_name = case_list[i]; - var ensemble_data = data.ensembleData(case_name); - - var values = ensemble_data.xValues(); - if (!self.horizontal_draw_direction) { - values = ensemble_data.yValues(); - } - - var y_min_values = ensemble_data.yMinValues(); - var y_max_values = ensemble_data.yMaxValues(); - - var x_area_values = CanvasPlotArea.mergePoints(values, values); - var y_area_values = CanvasPlotArea.mergePoints(y_min_values, y_max_values); - - - self.plot.area_renderer.style(style); - if (self.horizontal_draw_direction) { - self.plot.area_renderer(context, x_area_values, y_area_values); - } else { - self.plot.area_renderer(context, y_area_values, x_area_values); - } - - self.plot.addLegend(style, case_name, CanvasPlotLegend.filledCircle); - } - self.plot.renderCallbackFinishedRendering(); - } - }; - - - this.plot.setRenderCallback(renderEnsemble); -} - -OverviewPlot.prototype.resize = function (width, height) { - this.plot.resize(width, height); -}; - -OverviewPlot.prototype.setScales = function (x_min, x_max, y_min, y_max) { - this.plot.setScales(x_min, x_max, y_min, y_max); -}; - -OverviewPlot.prototype.setData = function (data) { - this.plot.setData(data); -}; - - -OverviewPlot.prototype.setVerticalErrorBar = function (vertical) { - this.plot.setVerticalErrorBar(vertical); -}; - -OverviewPlot.prototype.setHorizontalDrawDirection = function (horizontal) { - this.horizontal_draw_direction = horizontal; -}; - -OverviewPlot.prototype.setCustomSettings = function (settings) { - this.plot.setCustomSettings(settings); -}; - -OverviewPlot.prototype.setRenderingFinishedCallback = function(callback) { - this.plot.setRenderingFinishedCallback(callback); -}; - -OverviewPlot.prototype.renderNow = function(){ - this.plot.render(); -}; - -OverviewPlot.prototype.getTitle = function(){ - return this.plot.getTitle(); -}; - diff --git a/ThirdParty/Ert/devel/share/gui/plots/scripts/canvas_plot_pca.js b/ThirdParty/Ert/devel/share/gui/plots/scripts/canvas_plot_pca.js deleted file mode 100644 index 3f8bae63a6..0000000000 --- a/ThirdParty/Ert/devel/share/gui/plots/scripts/canvas_plot_pca.js +++ /dev/null @@ -1,154 +0,0 @@ -// Copyright (C) 2014 Statoil ASA, Norway. -// -// The file 'canvas_plot_distribution.js' is part of ERT - Ensemble based Reservoir Tool. -// -// ERT is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// ERT is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. -// -// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> -// for more details. - - -function PcaPlot(element, x_dimension, y_dimension) { - this.plot = new BasePlot(element, x_dimension, y_dimension); - this.plot.setRenderObservations(false); - this.plot.setRenderRefcase(false); - - this.horizontal_draw_direction = true; - this.group_scale = d3.scale.ordinal(); - - var self = this; - - var preRenderCallback = function(data) { - if (data.hasEnsembleData()) { - if (!self.horizontal_draw_direction) { - self.plot.setLogScaleOnDimensionX(data.shouldUseLogScale()); - } else { - self.plot.setLogScaleOnDimensionY(data.shouldUseLogScale()); - } - - self.plot.setXDomain(data.minX(), data.maxX(), data.observationData().xValues()); - self.plot.setYDomain(data.minY(), data.maxY(), data.observationData().yValues()); - } - }; - - var renderCallback = function (context, data) { - if (data.hasEnsembleData()) { - var obs_data = data.observationData(); - var obs_x_values = obs_data.xValues(); - var obs_y_values = obs_data.yValues(); - - var case_list = data.caseList(); - - for (var i = 0; i < case_list.length; i++) { - var style = STYLES[("ensemble_" + (i + 1))]; - var case_name = case_list[i]; - - var ensemble_data = data.ensembleData(case_name); - - var x_values = ensemble_data.xValues(); - var y_values = ensemble_data.yValues(); - - var realization_count = y_values.length; - var pc_count = x_values.length; - if (!self.horizontal_draw_direction) { - realization_count = x_values.length; - pc_count = y_values.length; - } - - var circle_renderer = self.plot.createCircleRenderer(); - - var circle_scale = circle_renderer.x().scale(); - self.group_scale.domain(case_list).rangePoints([0, circle_scale.rangeBand()], 1); - - var scaler = function(value) { - var pc = value[0]; - var case_name = value[1]; - return circle_scale(pc) + self.group_scale(case_name); - }; - - circle_renderer.x(scaler); - - circle_renderer.style(style); - circle_renderer.fillCircle(true); - circle_renderer.radius(5); - - for (var j = 0; j < realization_count; j++) { - for(var pc = 0; pc < pc_count; pc++) { - if (self.horizontal_draw_direction) { - circle_renderer(context, [x_values[pc], case_name], y_values[j][pc]) - - } else { - circle_renderer(context, x_values[j][pc], [y_values[pc], case_name]) - } - } - } - - - var cross_renderer = self.plot.createCrossRenderer(); - - cross_renderer.x(scaler); - - cross_renderer.style(STYLES["observation"]); - cross_renderer.radius(5); - - - for(var pc = 0; pc < pc_count; pc++) { - if (self.horizontal_draw_direction) { - cross_renderer(context, [obs_x_values[pc], case_name], obs_y_values[pc]) - - } else { - cross_renderer(context, obs_x_values[pc], [obs_y_values[pc], case_name]) - } - } - - self.plot.addLegend(style, case_name, CanvasPlotLegend.filledCircle); - } - - self.plot.addLegend(STYLES["observation"], "Observation", CanvasPlotLegend.cross); - - self.plot.renderCallbackFinishedRendering(); - } - }; - - this.plot.setPreRenderCallback(preRenderCallback); - this.plot.setRenderCallback(renderCallback); -} - -PcaPlot.prototype.resize = function (width, height) { - this.plot.resize(width, height); -}; - -PcaPlot.prototype.setScales = function (x_min, x_max, y_min, y_max) { - this.plot.setScales(x_min, x_max, y_min, y_max); -}; - -PcaPlot.prototype.setData = function (data) { - this.plot.setData(data); -}; - -PcaPlot.prototype.setHorizontalDrawDirection = function (horizontal) { - this.horizontal_draw_direction = horizontal; -}; - -PcaPlot.prototype.setCustomSettings = function (settings) { - this.plot.setCustomSettings(settings); -}; - -PcaPlot.prototype.renderNow = function(){ - this.plot.render(); -}; - -PcaPlot.prototype.getTitle = function(){ - return this.plot.getTitle(); -}; - -PcaPlot.prototype.setRenderingFinishedCallback = function(callback) { - this.plot.setRenderingFinishedCallback(callback); -}; diff --git a/ThirdParty/Ert/devel/share/gui/plots/scripts/canvas_plot_rect.js b/ThirdParty/Ert/devel/share/gui/plots/scripts/canvas_plot_rect.js deleted file mode 100644 index 9bbb9fef42..0000000000 --- a/ThirdParty/Ert/devel/share/gui/plots/scripts/canvas_plot_rect.js +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright (C) 2013 Statoil ASA, Norway. -// -// The file 'canvas_plot_rect.js' is part of ERT - Ensemble based Reservoir Tool. -// -// ERT is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// ERT is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. -// -// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> -// for more details. - - - -function CanvasRect() { - var margin = {top: 0, right: 0, bottom: 0, left: 0}; - var X = function (d) { return d; }; - var Y = function (d) { return d; }; - var style = STYLES["default"]; - - function render(context, x1, y1, x2, y2) { - context.lineWidth = style["stroke_width"]; - context.strokeStyle = style["stroke"]; - context.fillStyle = style["fill"]; - - var x = X(x1); - var y = Y(y1); - var w = X(x2) - x; - var h = Y(y2) - y; - context.fillRect(x + margin.left, y + margin.top, w - margin.left - margin.right, h - margin.top - margin.bottom); - context.strokeRect(x + margin.left, y + margin.top, w - margin.left - margin.right, h - margin.top - margin.bottom); - } - - render.x = function (value) { - if (!arguments.length) return X; - X = value; - return render; - }; - - render.y = function (value) { - if (!arguments.length) return Y; - Y = value; - return render; - }; - - render.style = function (value) { - if (!arguments.length) return style; - style = value; - return render; - }; - - render.margin = function (top, right, bottom, left) { - if (!arguments.length) return margin; - margin = {top: top, right: right, bottom: bottom, left: left}; - return render; - }; - - - return render; -} \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/plots/scripts/canvas_plot_statistics.js b/ThirdParty/Ert/devel/share/gui/plots/scripts/canvas_plot_statistics.js deleted file mode 100644 index 9511ccfc1b..0000000000 --- a/ThirdParty/Ert/devel/share/gui/plots/scripts/canvas_plot_statistics.js +++ /dev/null @@ -1,148 +0,0 @@ -// Copyright (C) 2013 Statoil ASA, Norway. -// -// The file 'canvas_plot_overview.js' is part of ERT - Ensemble based Reservoir Tool. -// -// ERT is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// ERT is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. -// -// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> -// for more details. - - -function StatisticsPlot(element, x_dimension, y_dimension) { - this.plot = new BasePlot(element, x_dimension, y_dimension); - - var horizontal_draw_direction = true; - - var line_renderer = this.plot.createLineRenderer(); - var stippled_line_renderer = this.plot.createStippledLineRenderer(); - var area_renderer = this.plot.createAreaRenderer(); - var dark_area_renderer = this.plot.createAreaRenderer(); - - - var self = this; - - var renderEnsemble = function (context, data) { - if (data.hasEnsembleData()) { - var case_list = data.caseList(); - - for (var i = 0; i < case_list.length; i++) { - var style = STYLES[("ensemble_" + (i + 1))]; - var case_name = case_list[i]; - var ensemble_data = data.ensembleData(case_name); - - var values = ensemble_data.xValues(); - if (!horizontal_draw_direction) { - values = ensemble_data.yValues(); - } - - var y_min_values = ensemble_data.yMinValues(); - var y_max_values = ensemble_data.yMaxValues(); - var median = ensemble_data.xPercentile(0.5); - var p10 = ensemble_data.xPercentile(0.1); - var p33 = ensemble_data.xPercentile(0.33); - var p67 = ensemble_data.xPercentile(0.67); - var p90 = ensemble_data.xPercentile(0.9); - - var area_values = CanvasPlotArea.mergePoints(values, values); - - var area_style = { - stroke: "rgba(255,255, 255, 0.0)", - fill: style["fill"], - stroke_width: 1 - }; - - var dark_area_style = { - stroke: "rgba(255,255, 255, 0.0)", - fill: STYLES.darker(style["fill"]), - stroke_width: 1 - }; - - var stipple_style = { - stroke: style["stroke"], - fill: "rgba(255, 255, 255, 0.0)", - stroke_width: style["stroke_width"], - line_cap: "butt" - }; - - line_renderer.style(style); - stippled_line_renderer.style(stipple_style); - stippled_line_renderer.stippleLength(5); - area_renderer.style(area_style); - dark_area_renderer.style(dark_area_style); - - if (horizontal_draw_direction) { - stippled_line_renderer(context, values, y_max_values); - stippled_line_renderer(context, values, y_min_values); - - area_renderer(context, area_values, CanvasPlotArea.mergePoints(p10, p90)); - dark_area_renderer(context, area_values, CanvasPlotArea.mergePoints(p33, p67)); - - stippled_line_renderer(context, values, median); - - } else { - stippled_line_renderer(context, y_max_values, values); - stippled_line_renderer(context, y_min_values, values); - - area_renderer(context, CanvasPlotArea.mergePoints(p10, p90), area_values); - dark_area_renderer(context, CanvasPlotArea.mergePoints(p33, p67), area_values); - - stippled_line_renderer(context, median, values); - } - - self.plot.addLegend(area_style, "P10 - P90", CanvasPlotLegend.filledCircle); - self.plot.addLegend(dark_area_style, "P33 - P67", CanvasPlotLegend.filledCircle); - self.plot.addLegend(stipple_style, "Min - Median - Max", CanvasPlotLegend.stippledLine); - self.plot.addLegend(style, case_name, CanvasPlotLegend.filledCircle); - } - self.plot.renderCallbackFinishedRendering(); - } - }; - - - this.plot.setRenderCallback(renderEnsemble); -} - -StatisticsPlot.prototype.resize = function (width, height) { - this.plot.resize(width, height); -}; - -StatisticsPlot.prototype.setScales = function (x_min, x_max, y_min, y_max) { - this.plot.setScales(x_min, x_max, y_min, y_max); -}; - -StatisticsPlot.prototype.setData = function (data) { - this.plot.setData(data); -}; - - -StatisticsPlot.prototype.setVerticalErrorBar = function (vertical) { - this.plot.setVerticalErrorBar(vertical); -}; - -StatisticsPlot.prototype.setHorizontalDrawDirection = function (horizontal) { - this.horizontal_draw_direction = horizontal; -}; - -StatisticsPlot.prototype.setCustomSettings = function (settings) { - this.plot.setCustomSettings(settings); -}; - -StatisticsPlot.prototype.setRenderingFinishedCallback = function(callback) { - this.plot.setRenderingFinishedCallback(callback); -}; - -StatisticsPlot.prototype.renderNow = function(){ - this.plot.render(); -}; - -StatisticsPlot.prototype.getTitle = function(){ - return this.plot.getTitle(); -}; - diff --git a/ThirdParty/Ert/devel/share/gui/plots/scripts/canvas_plot_stippled_line.js b/ThirdParty/Ert/devel/share/gui/plots/scripts/canvas_plot_stippled_line.js deleted file mode 100644 index c8e6d6ef39..0000000000 --- a/ThirdParty/Ert/devel/share/gui/plots/scripts/canvas_plot_stippled_line.js +++ /dev/null @@ -1,129 +0,0 @@ -// Copyright (C) 2014 Statoil ASA, Norway. -// -// The file 'canvas_plot_stippled_line.js' is part of ERT - Ensemble based Reservoir Tool. -// -// ERT is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// ERT is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. -// -// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> -// for more details. - -function CanvasPlotStippledLine() { - var X = function (d) { return d; }; - var Y = function (d) { return d; }; - var style = STYLES["default"]; - var stipple_length = 2; - - var dashing = true; - var unfinished_pixels_from_previous = 0; - - - function render(context, x_samples, y_samples) { - context.lineWidth = style["stroke_width"]; - context.strokeStyle = style["stroke"]; - context.lineCap = style["line_cap"]; - dashing = true; - unfinished_pixels_from_previous = 0; - - var length = Math.min(x_samples.length, y_samples.length); - - context.beginPath(); - var previous_x = 0; - var previous_y = 0; - for (var index = 0; index < length; index++) { - var x_sample = x_samples[index]; - var y_sample = y_samples[index]; - var x = X(x_sample); - var y = Y(y_sample); - - if (index > 0) { - render.dashedLineFromTo(context, previous_x, previous_y, x, y); - } - previous_x = x; - previous_y = y; - } - - context.stroke(); - } - - render.dashedLineFromTo = function(context, x1, y1, x2, y2) { - var x = x1; - var y = y1; - var dash_length = stipple_length; - var dx = (x2 - x) + 0.00000001; - var dy = (y2 - y); - var slope = dy / dx; - var distance_remaining = Math.sqrt(dx * dx + dy * dy); - var unfinished_pixels = false; - var current_dash_length; - var x_step; - - context.moveTo(x, y); - - while(distance_remaining >= 0.1) { - if(unfinished_pixels_from_previous === 0) { - current_dash_length = dash_length; - } else { - current_dash_length = unfinished_pixels_from_previous; - unfinished_pixels_from_previous = 0; - dashing = !dashing; - } - - if(dash_length > distance_remaining) { - dash_length = distance_remaining; - unfinished_pixels = true; - } - - x_step = Math.sqrt(current_dash_length * current_dash_length / (1 + slope * slope)); - x += x_step; - y += slope * x_step; - - if(dashing) { - context.lineTo(x, y); - } else { - context.moveTo(x, y); - } - distance_remaining -= current_dash_length; - dashing = !dashing; - } - - if(unfinished_pixels) { - unfinished_pixels_from_previous = current_dash_length; - } - - - }; - - render.x = function (value) { - if (!arguments.length) return X; - X = value; - return render; - }; - - render.y = function (value) { - if (!arguments.length) return Y; - Y = value; - return render; - }; - - render.style = function (value) { - if (!arguments.length) return style; - style = value; - return render; - }; - - render.stippleLength = function (value) { - if (!arguments.length) return stipple_length; - stipple_length = value; - return render; - }; - - - return render; -} \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/plots/scripts/histogram.js b/ThirdParty/Ert/devel/share/gui/plots/scripts/histogram.js deleted file mode 100644 index 6db4fbe9f5..0000000000 --- a/ThirdParty/Ert/devel/share/gui/plots/scripts/histogram.js +++ /dev/null @@ -1,358 +0,0 @@ -// Copyright (C) 2013 Statoil ASA, Norway. -// -// The file 'histogram.js' is part of ERT - Ensemble based Reservoir Tool. -// -// ERT is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// ERT is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. -// -// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> -// for more details. - - -function Histogram(element, x_dimension, y_dimension) { - var stored_data = null; - var stored_case_name = ""; - - var margin = {left: 40, right: 30, top: 20, bottom: 30}; - var width = 384 - margin.left - margin.right; - var height = 256 - margin.top - margin.bottom; - - var style = STYLES["default"]; - - var custom_value_min = null; - var custom_value_max = null; - - var x_dimension = x_dimension; - var y_dimension = y_dimension; - - - var histogram_renderer = HistogramRenderer().x(x_dimension).y(y_dimension).margin(0, 1, 0, 1); - var line_renderer = CanvasPlotLine().x(x_dimension).y(y_dimension); - var stipple_renderer = CanvasPlotStippledLine().x(x_dimension).y(y_dimension); - var area_renderer = CanvasPlotArea().x(x_dimension).y(y_dimension); - var circle_renderer = CanvasCircle().x(x_dimension).y(y_dimension); - - var legend = CanvasPlotLegend(); - var legend_list = []; - - - - var group = element.append("div") - .attr("class", "histogram"); - - - var title = group.append("div") - .attr("class", "plot-title") - .text("Histogram"); - - var axis_label_group = group.append("div") - .attr("id", "axis-label-group") - - var x_label = axis_label_group.append("div") - .attr("class", "x axis-label") - .text(""); - - var y_label = axis_label_group.append("div") - .attr("class", "y axis-label") - .text(""); - - var histogram_area = group.append("div").attr("class", "plot-area"); - - var legend_group = group.append("div") - .attr("class", "plot-legend-group"); - - var histogram_group = histogram_area.append("svg") - .attr("class", "plot-svg"); - - - var svg = histogram_group.append("g") - .attr("transform", "translate(" + margin.left + "," + margin.top + ")") - .style("width", width + "px") - .style("height", height + "px"); - - var canvas = histogram_area.append("canvas") - .attr("id", "histogram-canvas") - .attr("width", width) - .attr("height", height) - .style("position", "absolute") - .style("top", (margin.top) + "px") - .style("left", (margin.left) + "px") - .style("z-index", 5); - - - - - var y_axis = d3.svg.axis() - .scale(y_dimension.scale()) - .orient("left"); - - var x_axis = d3.svg.axis() - .scale(x_dimension.scale()) - .orient("bottom"); - - histogram_group.append("g") - .attr("class", "y axis pale") - .attr("transform", "translate(" + margin.left + "," + margin.top + ")") - .call(y_axis); - - histogram_group.append("g") - .attr("class", "x axis") - .attr("transform", "translate(" + margin.left + ", " + (height + margin.top) + ")") - .call(x_axis); - - var resetLegends = function() { - legend_list = []; - }; - - var addLegend = function(style, name, render_function) { - legend_list.push({"style": style, "name": name,"render_function": render_function}); - }; - - function formatDate(ctime) { - var date = new Date(ctime * 1000); - var year = date.getFullYear(); - var month = date.getMonth() + 1; - var day = date.getDate(); - - if (month < 10) { - month = "0" + month; - } - - if (day < 10) { - day = "0" + day; - } - - return year + "-" + month + "-" + day; - } - - - function createLogBinFunction (bin_count) { - function binner(range, values) { - var thresholds = []; - - var range_diff = range[1] - range[0]; - - var from_log = Math.round(Math.log(range[0]) / Math.log(10)); - var to_log = Math.round(Math.log(range[1]) / Math.log(10)); - - var from_to_diff = to_log - from_log; - var log_bin_count = from_to_diff; - var log_bin_count_next = from_to_diff * 2; - - while(log_bin_count_next < bin_count) { - log_bin_count = log_bin_count_next; - log_bin_count_next += from_to_diff; - } - - - - if(log_bin_count_next - bin_count < bin_count - log_bin_count) { - bin_count = log_bin_count_next; - } else { - bin_count = log_bin_count; - } - - var step = from_to_diff / bin_count ; - - var sum = 0; - for(var i = 0; i <= bin_count; i++) { - sum += Math.pow(10, i * step); - } - - var bin_size = range_diff / sum; - - thresholds.push(range[0]); - - for(var i = 1; i < bin_count; i++) { - var value = thresholds[i - 1] + (bin_size * Math.pow(10, i * step)); - thresholds.push(value); - } - - - thresholds.push(range[1]); - - return thresholds; - - } - return binner; - } - - - - - function histogram(data, case_name) { - if (!arguments.length) { - if(stored_data == null) { - return; - } - data = stored_data; - case_name = stored_case_name; - } else { - stored_data = data; - stored_case_name = case_name; - } - - x_axis.scale(x_dimension.scale()); - x_dimension.format(x_axis, height); - x_axis.tickSize(0, 0); - - y_axis.scale(y_dimension.scale()); - y_dimension.format(y_axis, width); - - - resetLegends(); - - title.text(histogram.getTitle()); - - if (x_dimension.getUnit() == "") { - x_label.text(""); - } else { - x_label.text("X: " + x_dimension.getUnit()); - } - - if (y_dimension.getUnit() == "") { - y_label.text(""); - } else { - y_label.text("Y: " + y_dimension.getUnit()); - } - - var context = canvas.node().getContext("2d"); - context.save(); - context.clearRect(0, 0, width, height); - - - if(data.hasObservation()) { - line_renderer.style(STYLES["observation"]); - var obs = data.observation(); - var top = data.maxCount() + 1; - stipple_renderer(context, [obs, obs], [0, top]); - addLegend(STYLES["observation"], "Observation", CanvasPlotLegend.stippledLine); - - var error = data.observationError(); - area_renderer.style(STYLES["observation_area"]); - area_renderer(context, [obs - error, obs + error, obs + error, obs - error], [top, top, 0, 0]); - - addLegend(STYLES["observation_area"], "Observation error", CanvasPlotLegend.filledCircle); - } - - if(data.hasRefcase()) { - line_renderer.style(STYLES["refcase"]); - line_renderer(context, [data.refcase(), data.refcase()], [0, data.maxCount() + 1]); - addLegend(STYLES["refcase"], "Refcase", CanvasPlotLegend.simpleLine); - } - - if(data.hasCaseHistogram(case_name)) { - - var case_histogram = data.caseHistogram(case_name); - var bin_count = data.numberOfBins(); - - var bins = histogram.histogramLayout(bin_count)(case_histogram.samples()); - -// var ticks = []; -// for(var i = 0; i < bins.length; i++) { -// ticks.push(bins[i].x); -// -// if(i == bins.length - 1) { -// ticks.push(bins[i].x + bins[i].dx); -// } -// } -// -// x_dimension.setTicks(ticks); - - histogram_renderer.style(style); - histogram_renderer(context, bins); - - addLegend(style, case_name, CanvasPlotLegend.filledCircle); - } - - legend_group.selectAll(".plot-legend").data(legend_list).call(legend); - histogram_group.select(".y.axis").call(y_axis); - var axis = histogram_group.select(".x.axis").call(x_axis); - x_dimension.relabel(axis); - - context.restore(); - } - - - histogram.histogramLayout = function(bin_count) { - var layout = null; - var use_log_scale = false; - - if("isLogScale" in x_dimension) { - use_log_scale = x_dimension.isLogScale(); - } - - if(use_log_scale) { - layout = d3.layout.histogram() - .range(x_dimension.scale().domain()) - .bins(createLogBinFunction(bin_count)); - } else { - layout = d3.layout.histogram() - .range(x_dimension.scale().domain()) - .bins(bin_count); - } - - return layout; - }; - - histogram.setSize = function(w, h) { - w = w - 80; - h = h - 70; - - width = w - margin.left - margin.right; - height = h - margin.top - margin.bottom; - - x_dimension.setRange(0, width); - y_dimension.setRange(height, 0); - - histogram_group.style("width", w + "px"); - histogram_group.style("height", h + "px"); - - canvas.attr("width", width).attr("height", height); - - svg.style("width", width + "px"); - svg.style("height", height + "px"); - - histogram_group.select(".x.axis") - .attr("transform", "translate(" + margin.left + ", " + (height + margin.top) + ")"); - - }; - - - histogram.style = function (value) { - if (!arguments.length) return style; - style = value; - return histogram; - }; - - histogram.setValueScales = function(min, max) { - custom_value_min = min; - custom_value_max = max; - }; - - histogram.setVisible = function(visible) { - if(!visible) { - group.style("display", "none"); - } else { - group.style("display", "inline-block"); - } - }; - - histogram.getTitle = function(){ - var data = stored_data; - var report_date = data.reportStepTime(); - if(report_date == 0){ - return data.name(); - } else { - return data.name() + " @ " + formatDate(data.reportStepTime()); - } - }; - - return histogram; -} \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/plots/scripts/histogram_renderer.js b/ThirdParty/Ert/devel/share/gui/plots/scripts/histogram_renderer.js deleted file mode 100644 index 1675c774f2..0000000000 --- a/ThirdParty/Ert/devel/share/gui/plots/scripts/histogram_renderer.js +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright (C) 2013 Statoil ASA, Norway. -// -// The file 'histogram_renderer.js' is part of ERT - Ensemble based Reservoir Tool. -// -// ERT is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// ERT is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. -// -// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> -// for more details. - - -function HistogramRenderer() { - var margin = {top: 0, right: 0, bottom: 0, left: 0}; - var X = function (d) { return d; }; - var Y = function (d) { return d; }; - var style = STYLES["default"]; - - - function render(context, histogram_values) { - context.lineWidth = "1"; - context.strokeStyle = "rgba(0, 0, 0, 0.5)"; - - var fill = style["fill"]; - - context.fillStyle = STYLES.blendWithWhite(fill, 1.0); - - for(var j = 0; j < histogram_values.length; j++) { - var value = histogram_values[j]; - if(value.y > 0) { - var x = X(value.x); - var y = Y(value.y); - var w = X(value.x + value.dx) - x; - var h = Y(0) - y; - - context.fillRect(x + margin.left, y + margin.top, w - margin.left - margin.right, h - margin.top - margin.bottom); - context.strokeRect(x + margin.left, y + margin.top, w - margin.left - margin.right, h - margin.top - margin.bottom); - } - } - } - - render.x = function (value) { - if (!arguments.length) return X; - X = value; - return render; - }; - - render.y = function (value) { - if (!arguments.length) return Y; - Y = value; - return render; - }; - - render.style = function (value) { - if (!arguments.length) return style; - style = value; - return render; - }; - - render.margin = function (top, right, bottom, left) { - if (!arguments.length) return margin; - margin = {top: top, right: right, bottom: bottom, left: left}; - return render; - }; - - return render; -} diff --git a/ThirdParty/Ert/devel/share/gui/plots/scripts/render_tracker.js b/ThirdParty/Ert/devel/share/gui/plots/scripts/render_tracker.js deleted file mode 100644 index c7d02e68f5..0000000000 --- a/ThirdParty/Ert/devel/share/gui/plots/scripts/render_tracker.js +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright (C) 2013 Statoil ASA, Norway. -// -// The file 'render_tracker.js' is part of ERT - Ensemble based Reservoir Tool. -// -// ERT is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// ERT is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. -// -// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> -// for more details. - -function IncrementalRenderTracker() { - this.rendering_start = null; - this.max_loop_time = 500; - this.is_running = false; - this.should_stop = false; - - this.loop_start = null; - -} - -IncrementalRenderTracker.prototype.start = function(render_function) { - if(this.is_running) { -// console.log("Rendering -> activating kill!"); - this.should_stop = true; - } - - this.run(this, render_function); -}; - - -IncrementalRenderTracker.prototype.run = function(self, render_function) { - if(!this.is_running) { - this.rendering_start = Date.now(); - this.is_running = true; - this.should_stop = false; - - render_function(); - - } else { -// console.log("Waiting!"); - window.setTimeout(function() { self.run(self, render_function); }, 15); - } -}; - - -IncrementalRenderTracker.prototype.shouldStop = function() { - return this.should_stop; -}; - - -IncrementalRenderTracker.prototype.loopStart = function() { - this.loop_start = Date.now(); -}; - -IncrementalRenderTracker.prototype.shouldLoopStop = function() { - return (Date.now() - this.loop_start) > this.max_loop_time; -}; - -IncrementalRenderTracker.prototype.stoppedRendering = function() { - this.is_running = false; - this.should_stop = false; -// console.log("Rendering time: " + this.runningTime() + " ms"); -}; - -IncrementalRenderTracker.prototype.isRunning = function() { - return this.is_running; -}; - -IncrementalRenderTracker.prototype.runningTime = function() { - return (Date.now() - this.rendering_start); -}; - -IncrementalRenderTracker.prototype.forceStop = function() { - this.should_stop = true; -}; - - - - - - - - - - - diff --git a/ThirdParty/Ert/devel/share/gui/plots/scripts/styles.js b/ThirdParty/Ert/devel/share/gui/plots/scripts/styles.js deleted file mode 100644 index 394a075ff6..0000000000 --- a/ThirdParty/Ert/devel/share/gui/plots/scripts/styles.js +++ /dev/null @@ -1,201 +0,0 @@ -var STYLES = { - default: { - stroke: "rgba(0, 0, 0, 1.0)", - fill: "rgba(200, 200, 200, 1.0)", - stroke_width: 1, - dash_array: [], - line_cap: "butt" - }, - observation: { - stroke: "rgba(0, 0, 0, 1.0)", - fill: "rgba(0, 0, 0, 0.0)", - stroke_width: 1, - dash_array: [], - line_cap: "butt" - }, - observation_error_bar: { - stroke: "rgba(0, 0, 0, 1.0)", - fill: "rgba(0, 0, 0, 0.0)", - stroke_width: 1, - dash_array: [], - line_cap: "butt" - }, - observation_area: { - stroke: "rgba(0, 0, 0, 0.15)", - fill: "rgba(0, 0, 0, 0.2)", - stroke_width: 2, - dash_array: [], - line_cap: "butt" - }, - refcase: { - stroke: "rgba(0, 0, 0, 0.7)", - fill: "rgba(0, 0, 0, 0.0)", - stroke_width: 1.5, - dash_array: [], - line_cap: "butt" - }, - ensemble_1: { - stroke: "rgba(56, 108, 176, 0.8)", - fill: "rgba(56, 108, 176, 0.5)", - stroke_width: 1, - dash_array: [], - line_cap: "butt" - }, - ensemble_2: { - stroke: "rgba(127, 201, 127, 0.8)", - fill: "rgba(127, 201, 127, 0.5)", - stroke_width: 1, - dash_array: [], - line_cap: "butt" - }, - ensemble_3: { - stroke: "rgba(253, 192, 134, 0.8)", - fill: "rgba(253, 192, 134, 0.5)", - stroke_width: 1, - dash_array: [], - line_cap: "butt" - }, - ensemble_4: { - stroke: "rgba(240, 2, 127, 0.8)", - fill: "rgba(240, 2, 127, 0.5)", - stroke_width: 1, - dash_array: [], - line_cap: "butt" - }, - ensemble_5: { - stroke: "rgba(191, 91, 23, 0.8)", - fill: "rgba(191, 91, 23, 0.5)", - stroke_width: 1, - dash_array: [], - line_cap: "butt" - }, - - ensemble_colors: ["ensemble_1", "ensemble_2", "ensemble_3", "ensemble_4", "ensemble_5"] - -}; - - -STYLES.parseColor = function(input) { - var result = [255, 255, 255, 1]; - - var match = input.match(/^rgba\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+\.?\d*)\s*\)$/i); - if(match) { - result[0] = match[1]; - result[1] = match[2]; - result[2] = match[3]; - result[3] = parseFloat(match[4]); - return result; - } - - return result; -}; - - -STYLES.asRgb = function(r, g, b) { - return "rgb(" + r + "," + g + "," + b + ")"; -}; - -STYLES.asRgba = function(r, g, b, a) { - return "rgba(" + r + "," + g + "," + b + "," + a + ")"; -}; - - -STYLES.componentToHex = function(c) { - var hex = c.toString(16); - return hex.length == 1 ? "0" + hex : hex; -}; - -STYLES.rgbToHex = function(r, g, b) { - return "#" + CanvasPlotLegend.componentToHex(r) + CanvasPlotLegend.componentToHex(g) + CanvasPlotLegend.componentToHex(b); -}; - -STYLES.darker = function(color) { - var rgba = STYLES.parseColor(color); - - var f = 0.80; - var a = rgba[3]; - var r = parseInt(rgba[0] * f); - var g = parseInt(rgba[1] * f); - var b = parseInt(rgba[2] * f); - - return STYLES.asRgba(r, g, b, a); -}; - -STYLES.blendWithWhite = function(color, result_alpha) { - var rgba = STYLES.parseColor(color); - - var a = rgba[3]; - var ab = (1 - rgba[3]) * 255; - var r = parseInt(rgba[0] * a + ab); - var g = parseInt(rgba[1] * a + ab); - var b = parseInt(rgba[2] * a + ab); - - return STYLES.asRgba(r, g, b, result_alpha); -}; - -STYLES.createFillColor = function(color, fill_alpha, blend_with_white_alpha) { - var rgba = STYLES.parseColor(color); - rgba[3] = fill_alpha; - return STYLES.blendWithWhite(STYLES.asRgba(rgba[0], rgba[1], rgba[2], rgba[3]), blend_with_white_alpha); -}; - - -STYLES.updateColors = function(settings) { - var alpha = 0.7; - var fill_alpha = 0.5; - if("observation" in settings) { - STYLES["observation"]["stroke"] = settings["observation"]; - } - - if("observation_error_bar" in settings) { - STYLES["observation_error_bar"]["stroke"] = settings["observation_error_bar"]; - } - - if("observation_area" in settings) { - STYLES["observation_area"]["stroke"] = settings["observation_area"]; - STYLES["observation_area"]["fill"] = settings["observation_area"]; - } - - if("refcase" in settings) { - STYLES["refcase"]["stroke"] = settings["refcase"]; - } - - if("ensemble_1" in settings) { - STYLES["ensemble_1"]["stroke"] = settings["ensemble_1"]; -// STYLES["ensemble_1"]["fill"] = settings["ensemble_1"]; - STYLES["ensemble_1"]["fill"] = STYLES.createFillColor(settings["ensemble_1"], fill_alpha, alpha); - } - - if("ensemble_2" in settings) { - STYLES["ensemble_2"]["stroke"] = settings["ensemble_2"]; - STYLES["ensemble_2"]["fill"] = STYLES.createFillColor(settings["ensemble_2"], fill_alpha, alpha); -// STYLES["ensemble_2"]["fill"] = settings["ensemble_2"]; - } - - if("ensemble_3" in settings) { - STYLES["ensemble_3"]["stroke"] = settings["ensemble_3"]; - STYLES["ensemble_3"]["fill"] = STYLES.createFillColor(settings["ensemble_3"], fill_alpha, alpha); -// STYLES["ensemble_3"]["fill"] = settings["ensemble_3"]; - } - - if("ensemble_4" in settings) { - STYLES["ensemble_4"]["stroke"] = settings["ensemble_4"]; - STYLES["ensemble_4"]["fill"] = STYLES.createFillColor(settings["ensemble_4"], fill_alpha, alpha); -// STYLES["ensemble_4"]["fill"] = settings["ensemble_4"]; - } - - if("ensemble_5" in settings) { - STYLES["ensemble_5"]["stroke"] = settings["ensemble_5"]; - STYLES["ensemble_5"]["fill"] = STYLES.createFillColor(settings["ensemble_5"], fill_alpha, alpha); -// STYLES["ensemble_5"]["fill"] = settings["ensemble_5"]; - } - -}; - - -var alpha = 0.7; -STYLES["ensemble_1"]["fill"] = STYLES.blendWithWhite(STYLES["ensemble_1"]["fill"], alpha); -STYLES["ensemble_2"]["fill"] = STYLES.blendWithWhite(STYLES["ensemble_2"]["fill"], alpha); -STYLES["ensemble_3"]["fill"] = STYLES.blendWithWhite(STYLES["ensemble_3"]["fill"], alpha); -STYLES["ensemble_4"]["fill"] = STYLES.blendWithWhite(STYLES["ensemble_4"]["fill"], alpha); -STYLES["ensemble_5"]["fill"] = STYLES.blendWithWhite(STYLES["ensemble_5"]["fill"], alpha); \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/plots/simple_overview_plot.html b/ThirdParty/Ert/devel/share/gui/plots/simple_overview_plot.html deleted file mode 100644 index 506cbe30cd..0000000000 --- a/ThirdParty/Ert/devel/share/gui/plots/simple_overview_plot.html +++ /dev/null @@ -1,146 +0,0 @@ -<!DOCTYPE html> -<!-- Copyright (C) 2013 Statoil ASA, Norway. --> -<!-- --> -<!-- The file 'simple_overview_plot.html' is part of ERT - Ensemble based Reservoir Tool. --> -<!-- --> -<!-- ERT is free software: you can redistribute it and/or modify --> -<!-- it under the terms of the GNU General Public License as published by --> -<!-- the Free Software Foundation, either version 3 of the License, or --> -<!-- (at your option) any later version. --> -<!-- --> -<!-- ERT is distributed in the hope that it will be useful, but WITHOUT ANY --> -<!-- WARRANTY; without even the implied warranty of MERCHANTABILITY or --> -<!-- FITNESS FOR A PARTICULAR PURPOSE. --> -<!-- --> -<!-- See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> --> -<!-- for more details. --> - -<html> -<head> - <meta charset="utf-8"> - <link rel="stylesheet" type="text/css" href="style/plot.css"/> -</head> - -<script src="libs/d3.v3.js"></script> -<script src="scripts/styles.js"></script> -<script src="scripts/base_plot.js"></script> -<script src="scripts/base_plot_time_dimension.js"></script> -<script src="scripts/base_plot_value_dimension.js"></script> -<script src="scripts/canvas_plot_overview.js"></script> -<script src="scripts/canvas_plot_line.js"></script> -<script src="scripts/canvas_plot_stippled_line.js"></script> -<script src="scripts/canvas_plot_area.js"></script> -<script src="scripts/canvas_error_bar.js"></script> -<script src="scripts/canvas_plot_circle.js"></script> -<script src="scripts/canvas_plot_legend.js"></script> - -<script> - var plot = null; - - var time_dimension = null; - var value_dimension = null; - - function initialize() { - if (!(typeof plot_data_source === 'undefined')) { - createPlot(); - updatePlot(); - plot_data_source.htmlInitialized(); - } else { -// createPlot(); -// plot.setData(data); - console.log("Unable to load data!"); - alert("Unable to load data!"); - } - } - - function createPlot() { - time_dimension = BasePlotTimeDimension(); - value_dimension = BasePlotValueDimension(); - plot = new OverviewPlot(d3.select("body"), time_dimension, value_dimension); - plot.setRenderingFinishedCallback(function() { - plot_data_source.renderingFinished(); - }); - } - - function updatePlot() { - var data = plot_data_source.getPlotData(); - plot.setData(data); - value_dimension.setUnit(data.unitY()); - } - - function setSize(width, height) { - plot.resize(width, height - 75); - } - - function setScales(x_min, x_max, y_min, y_max) { - plot.setScales(x_min, x_max, y_min, y_max); - } - - function setReportStepTime(report_step_time) { - // Not supported by this plot - } - - function supportsPlotProperties(time, value, depth, index, histogram, pca){ - return time && value && !depth; - } - - function getPrintWidth(){ - return 1600; - } - - function getPrintHeight(){ - return 1200; - } - - function setCustomSettings(settings) { - plot.setCustomSettings(settings); - STYLES.updateColors(settings); - } - - function renderNow(){ - plot.renderNow(); - } - - function getPlotTitle(){ - return plot.getTitle(); - } - - function xAxisType() { - return "time"; - } - - function yAxisType() { - return "value"; - } - - function isReportStepCapable() { - return false; - } - - function getXMin() { - var data = plot_data_source.getTemporaryData(); - return data.minX(); - } - - function getXMax() { - var data = plot_data_source.getTemporaryData(); - return data.maxX(); - } - - function getYMin() { - var data = plot_data_source.getTemporaryData(); - return data.minY(); - } - - function getYMax() { - var data = plot_data_source.getTemporaryData(); - return data.maxY(); - } - -</script> - -<body onload="initialize();"> - -</body> - -</html> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/plots/simple_plot.html b/ThirdParty/Ert/devel/share/gui/plots/simple_plot.html deleted file mode 100644 index a7f549f5e1..0000000000 --- a/ThirdParty/Ert/devel/share/gui/plots/simple_plot.html +++ /dev/null @@ -1,160 +0,0 @@ -<!DOCTYPE html> -<!-- Copyright (C) 2013 Statoil ASA, Norway. --> -<!-- --> -<!-- The file 'simple_plot.html' is part of ERT - Ensemble based Reservoir Tool. --> -<!-- --> -<!-- ERT is free software: you can redistribute it and/or modify --> -<!-- it under the terms of the GNU General Public License as published by --> -<!-- the Free Software Foundation, either version 3 of the License, or --> -<!-- (at your option) any later version. --> -<!-- --> -<!-- ERT is distributed in the hope that it will be useful, but WITHOUT ANY --> -<!-- WARRANTY; without even the implied warranty of MERCHANTABILITY or --> -<!-- FITNESS FOR A PARTICULAR PURPOSE. --> -<!-- --> -<!-- See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> --> -<!-- for more details. --> - -<html> -<head> - <meta charset="utf-8"> - <link rel="stylesheet" type="text/css" href="style/plot.css"/> -</head> - -<script src="libs/d3.v3.js"></script> -<script src="scripts/styles.js"></script> -<script src="scripts/base_plot.js"></script> -<script src="scripts/base_plot_value_dimension.js"></script> -<script src="scripts/base_plot_time_dimension.js"></script> -<script src="scripts/render_tracker.js"></script> -<script src="scripts/canvas_plot.js"></script> -<script src="scripts/canvas_plot_line.js"></script> -<script src="scripts/canvas_plot_stippled_line.js"></script> - -<script src="scripts/canvas_plot_area.js"></script> -<script src="scripts/canvas_error_bar.js"></script> -<script src="scripts/canvas_plot_circle.js"></script> -<script src="scripts/canvas_plot_legend.js"></script> - -<script> - var plot = null; - - var time_dimension = null; - var value_dimension = null; - - function initialize() { - if (!(typeof plot_data_source === 'undefined')) { - createPlot(); - updatePlot(); - plot_data_source.htmlInitialized(); - } else { - createPlot(); - plot.setData(data); - console.log("Unable to load data!"); - alert("Unable to load data!"); - } - } - - function createPlot() { - time_dimension = BasePlotTimeDimension(); - value_dimension = BasePlotValueDimension(); - plot = new Plot(d3.select("body"), time_dimension, value_dimension); - plot.setRenderingFinishedCallback(function() { - plot_data_source.renderingFinished(); - }); - } - - function updatePlot() { - var data = plot_data_source.getPlotData(); - plot.setData(data); - value_dimension.setUnit(data.unitY()); - } - - function setSize(width, height) { - plot.resize(width, height - 75); - } - - function setScales(x_min, x_max, y_min, y_max) { - plot.setScales(x_min, x_max, y_min, y_max); - } - - function setReportStepTime(report_step_time) { - // Not supported by this plot - } - - function supportsPlotProperties(time, value, depth, index, histogram, pca){ - return time && value && !depth; - } - - function getPrintWidth() { - return 1600; - } - - function getPrintHeight() { - return 1200; - } - - function setCustomSettings(settings) { - plot.setCustomSettings(settings); - STYLES.updateColors(settings); - } - - function renderNow() { - plot.renderNow(); - } - - function getPlotTitle() { - return plot.getTitle(); - } - - function xAxisType() { - return "time"; - } - - function yAxisType() { - return "value"; - } - - function isReportStepCapable() { - return false; - } - - function getXMin() { - var data = plot_data_source.getTemporaryData(); - if(!data.hasBoundaries()) { - return null; - } - return data.minX(); - } - - function getXMax() { - var data = plot_data_source.getTemporaryData(); - if(!data.hasBoundaries()) { - return null; - } - return data.maxX(); - } - - function getYMin() { - var data = plot_data_source.getTemporaryData(); - if(!data.hasBoundaries()) { - return null; - } - return data.minY(); - } - - function getYMax() { - var data = plot_data_source.getTemporaryData(); - if(!data.hasBoundaries()) { - return null; - } - return data.maxY(); - } - -</script> - -<body onload="initialize();"> - -</body> - -</html> \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/gui/plots/style/plot.css b/ThirdParty/Ert/devel/share/gui/plots/style/plot.css deleted file mode 100644 index 6ce4738592..0000000000 --- a/ThirdParty/Ert/devel/share/gui/plots/style/plot.css +++ /dev/null @@ -1,156 +0,0 @@ -/* Copyright (C) 2013 Statoil ASA, Norway. */ -/* */ -/* The file 'plot.css' is part of ERT - Ensemble based Reservoir Tool. */ -/* */ -/* ERT is free software: you can redistribute it and/or modify */ -/* it under the terms of the GNU General Public License as published by */ -/* the Free Software Foundation, either version 3 of the License, or */ -/* (at your option) any later version. */ -/* */ -/* ERT is distributed in the hope that it will be useful, but WITHOUT ANY */ -/* WARRANTY; without even the implied warranty of MERCHANTABILITY or */ -/* FITNESS FOR A PARTICULAR PURPOSE. */ -/* */ -/* See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html> */ -/* for more details. */ - -html { - height: 100%; -} - -body { - height: 90%; - background-color: #eee; -} - -.plot { - margin: 5px; - padding: 10px; - border: 1px solid black; - background-color: white; - display: inline-block; -} - -.histogram { - margin: 5px; - padding: 10px; - border: 1px solid black; - background-color: white; - display: inline-block; -} - -.plot-svg { - display: block; - margin: 0; - padding: 0; -} - -.plot-title { - font-size: large; - width: auto; - text-align: center; - margin: 0px; - /*color: goldenrod;*/ - -} - - -.plot-area { - position: relative; -} - -.plot-legend-group { - /*background-color: #7FC97F;*/ - margin-left: auto; - margin-right: auto; - display: inline-block; - float: right; - -} - -.plot-legend { - display: inline; - margin-right: 15px; -} - - -.plot-legend-label { - font-family: Helvetica,serif; - font-size: medium; - font-variant: small-caps; - display: inline-block; - padding-left: 5px; -} - -.plot-legend-box { - border: solid 1px #000; - width: 10px; - height: 10px; - display: inline-block; - background-color: darkorchid; -} - -.plot-legend-line { - border: 2px none #000; - border-top-style: dotted; - - width: 10px; - height: 1px; - display: inline-block; - vertical-align: middle; -} - -/*.histograms {*/ - -/*}*/ - -/*.histogram-div {*/ - -/*}*/ - - -.histogram-svg { - display: block; - margin: 20px; - padding: 0; - width: 384px; - height: 256px; -} - -.histogram-title { - font-size: large; - width: auto; - text-align: center; - margin: 10px; - /*color: goldenrod;*/ - -} - - -.axis path, .axis line { - fill: none; - stroke: #000000; - shape-rendering: crispEdges; -} - -.axis line.minor { - fill: none; - stroke-dasharray: 1, 4; -} - -.pale line { - fill: none; - stroke: #999; - stroke-dasharray: 2, 2; -} - -#axis-label-group { - width: auto; - text-align: center; -} - -.axis-label { - font-size: small; - display: inline; - margin-right: 10px; -} diff --git a/ThirdParty/Ert/devel/share/lib/synthesizer/__init__.py b/ThirdParty/Ert/devel/share/lib/synthesizer/__init__.py new file mode 100644 index 0000000000..0bc890b220 --- /dev/null +++ b/ThirdParty/Ert/devel/share/lib/synthesizer/__init__.py @@ -0,0 +1,4 @@ +from .prime_generator import PrimeGenerator +from .perlin import PerlinNoise +from .shaped_perlin import ShapedNoise, ShapeFunction, ShapeCreator +from .oil_simulator import OilSimulator \ No newline at end of file diff --git a/ThirdParty/Ert/devel/share/lib/synthesizer/oil_simulator.py b/ThirdParty/Ert/devel/share/lib/synthesizer/oil_simulator.py new file mode 100644 index 0000000000..8ebf162e42 --- /dev/null +++ b/ThirdParty/Ert/devel/share/lib/synthesizer/oil_simulator.py @@ -0,0 +1,136 @@ +from . import ShapeFunction, ShapeCreator + +class OilSimulator(object): + OPR_SHAPE = ShapeFunction([0.0, 0.2, 0.5, 0.7, 1.0], [0.0, 0.7, 0.2, 0.1, 0.01]) + GPR_SHAPE = ShapeFunction([0.0, 0.2, 0.5, 0.7, 1.0], [0.0, 0.5, 0.7, 0.7, 0.3]) + WPR_SHAPE = ShapeFunction([0.0, 0.2, 0.5, 0.7, 1.0], [0.0, 0.01, 0.3, 0.7, 1]) + BPR_SHAPE= ShapeFunction([0.0, 0.2, 0.5, 0.7, 1.0], [1.0, 0.7, 0.5, 0.3, 0.1]) + + O_DIVERGENCE = ShapeFunction([0.0, 0.5, 0.7, 0.9, 1.0], [0.0, 0.5, 0.3, 0.1, 0.01]) + G_DIVERGENCE = ShapeFunction([0.0, 0.5, 0.7, 0.9, 1.0], [0.0, 0.1, 0.3, 0.2, 0.1]) + W_DIVERGENCE = ShapeFunction([0.0, 0.5, 0.7, 0.9, 1.0], [0.0, 0.1, 0.3, 0.2, 0.01]) + B_DIVERGENCE = ShapeFunction([0.0, 0.5, 0.7, 0.9, 1.0], [0.0, 0.1, 0.2, 0.3, 0.5]) + + def __init__(self): + self.__oprFunc = {} + self.__gprFunc = {} + self.__wprFunc = {} + self.__bprFunc = {} + self.__current_step = 0 + + self.__fopt = 0.0 + self.__fopr = 0.0 + self.__fgpt = 0.0 + self.__fgpr = 0.0 + self.__fwpt = 0.0 + self.__fwpr = 0.0 + + self.__fgor = 0.0 + self.__fwct = 0.0 + + self.__wells = {} + self.__bpr = {} + + def addWell(self, name, seed, persistence=0.2, octaves=8, divergence_scale=1.0): + oil_div = OilSimulator.O_DIVERGENCE.scaledCopy(divergence_scale) + gas_div = OilSimulator.G_DIVERGENCE.scaledCopy(divergence_scale) + water_div = OilSimulator.W_DIVERGENCE.scaledCopy(divergence_scale) + self.__oprFunc[name] = ShapeCreator.createNoiseFunction(OilSimulator.OPR_SHAPE, oil_div, seed, persistence=persistence, octaves=octaves, cutoff=0.0) + self.__gprFunc[name] = ShapeCreator.createNoiseFunction(OilSimulator.GPR_SHAPE, gas_div, seed * 7, persistence=persistence * 3.5, octaves=octaves / 2, cutoff=0.0) + self.__wprFunc[name] = ShapeCreator.createNoiseFunction(OilSimulator.WPR_SHAPE, water_div, seed * 11, persistence=persistence, octaves=octaves, cutoff=0.0) + + self.__wells[name] = {"opr": 0.0, "opt": 0.0, "gpr": 0.0, "gpt": 0.0, "wpr": 0.0, "wpt": 0.0} + + def addBlock(self, name, seed, persistence=0.2): + self.__bprFunc[name] = ShapeCreator.createNoiseFunction(OilSimulator.BPR_SHAPE, OilSimulator.B_DIVERGENCE, seed, persistence=persistence, cutoff=0.0) + self.__bpr[name] = 0.0 + + def step(self, scale=1.0): + self.__fopr = 0.0 + self.__fgpr = 0.0 + self.__fwpr = 0.0 + self.__fgor = 0.0 + self.__fwct = 0.0 + for key in self.__wells: + oprFunction = self.__oprFunc[key] + gprFunction = self.__gprFunc[key] + wprFunction = self.__wprFunc[key] + opr_value = oprFunction(self.__current_step, scale) + gpr_value = gprFunction(self.__current_step, scale) + wpr_value = wprFunction(self.__current_step, scale) + + well = self.__wells[key] + well["opr"] = opr_value + well["opt"] += opr_value + well["gpr"] = gpr_value + well["gpt"] += gpr_value + well["wpr"] = wpr_value + well["wpt"] += wpr_value + self.__fopr += opr_value + self.__fgpr += gpr_value + self.__fwpr += wpr_value + + self.__fgor += self.gor(key) + self.__fwct += self.wct(key) + + self.__fopt += self.__fopr + self.__fgpt += self.__fgpr + self.__fwpt += self.__fwpr + + self.__fgor /= len(self.__wells) + self.__fwct /= len(self.__wells) + + for key in self.__bpr: + bprFunction = self.__bprFunc[key] + self.__bpr[key] = bprFunction(self.__current_step, scale) + + self.__current_step += 1 + + def fopt(self): + return self.__fopt + + def fopr(self): + return self.__fopr + + def fgpt(self): + return self.__fgpt + + def fgpr(self): + return self.__fgpr + + def fwpt(self): + return self.__fwpt + + def fwpr(self): + return self.__fwpr + + def fgor(self): + return self.__fgor + + def fwct(self): + return self.__fwct + + def opr(self, well_name): + return self.__wells[well_name]["opr"] + + def gpr(self, well_name): + return self.__wells[well_name]["gpr"] + + def wpr(self, well_name): + return self.__wells[well_name]["wpr"] + + def wct(self, well_name): + opr = self.opr(well_name) + wpr = self.wpr(well_name) + opr = max(opr, 0.1) + return wpr / (wpr + opr) if (wpr + opr) > 0.0 else 0.0 + + def gor(self, well_name): + opr = self.opr(well_name) + gpr = self.gpr(well_name) + opr = max(opr, 0.1) + gpr = max(gpr, 0.1) + return gpr / opr + + def bpr(self, block_name): + return self.__bpr[block_name] diff --git a/ThirdParty/Ert/devel/share/lib/synthesizer/perlin.py b/ThirdParty/Ert/devel/share/lib/synthesizer/perlin.py new file mode 100644 index 0000000000..b3da8ae7e1 --- /dev/null +++ b/ThirdParty/Ert/devel/share/lib/synthesizer/perlin.py @@ -0,0 +1,57 @@ +import math + +from .prime_generator import PrimeGenerator + + +class PerlinNoise(object): + def __init__(self, persistence=0.5, number_of_octaves=4, prime_generator=None): + self.persistence = persistence + self.number_of_octaves = number_of_octaves + + self.octave_primes = prime_generator if prime_generator is not None else PrimeGenerator() + + def cosineInterpolation(self, a, b, x): + ft = x * 3.1415927 + f = (1.0 - math.cos(ft)) * 0.5 + return a * (1 - f) + b * f + + MAX_INT = (1 << 31) - 1 + + def noise(self, x, perturbation): + x += perturbation + x = ((x << 13) & PerlinNoise.MAX_INT) ^ x + x = (x * (x * x * 15731 + 789221) + 1376312589) & PerlinNoise.MAX_INT + return 1.0 - x / 1073741824.0 + + def smoothedNoise(self, x, perturbation): + return self.noise(x, perturbation) / 2.0 + self.noise(x - 1, perturbation) / 4.0 + self.noise(x + 1, perturbation) / 4.0 + + def interpolatedNoise(self, x, octave_number): + int_x = int(x) + frac_x = x - int_x + + perturbation = self.octave_primes[octave_number] + + v1 = self.smoothedNoise(int_x, perturbation) + v2 = self.smoothedNoise(int_x + 1, perturbation) + + return self.cosineInterpolation(v1, v2, frac_x) + + def perlinNoise1D(self, x): + total = 0.0 + + for octave in range(self.number_of_octaves - 1): + frequency = math.pow(2, octave) + amplitude = math.pow(self.persistence, octave) + + total += self.interpolatedNoise(x * frequency, octave_number=octave) * amplitude + + return total + + def __getitem__(self, x): + """ :rtype: float """ + return self.perlinNoise1D(x * 10.0) + + def __call__(self, x): + """ :rtype: float """ + return self[x] diff --git a/ThirdParty/Ert/devel/share/lib/synthesizer/prime_generator.py b/ThirdParty/Ert/devel/share/lib/synthesizer/prime_generator.py new file mode 100644 index 0000000000..d7c35107b4 --- /dev/null +++ b/ThirdParty/Ert/devel/share/lib/synthesizer/prime_generator.py @@ -0,0 +1,40 @@ +import random + +def rwh_primes2(n): + # http://stackoverflow.com/questions/2068372/fastest-way-to-list-all-primes-below-n-in-python/3035188#3035188 + """ Input n>=6, Returns a list of primes, 2 <= p < n """ + correction = (n % 6 > 1) + n = {0: n, 1: n - 1, 2: n + 4, 3: n + 3, 4: n + 2, 5: n + 1}[n % 6] + sieve = [True] * (n / 3) + sieve[0] = False + for i in xrange(int(n ** 0.5) / 3 + 1): + if sieve[i]: + k = 3 * i + 1 | 1 + sieve[((k * k) / 3)::2 * k] = [False] * ((n / 6 - (k * k) / 6 - 1) / k + 1) + sieve[(k * k + 4 * k - 2 * k * (i & 1)) / 3::2 * k] = [False] * ( + (n / 6 - (k * k + 4 * k - 2 * k * (i & 1)) / 6 - 1) / k + 1) + return [2, 3] + [3 * i + 1 | 1 for i in xrange(1, n / 3 - correction) if sieve[i]] + + + +class PrimeGenerator(object): + LIST_OF_PRIMES = rwh_primes2(10000) + + def __init__(self, seed=None): + self.__primes = {} + self.__random = random.Random(seed) + random.seed(seed) + + def __getitem__(self, index): + if not isinstance(index, (int, long)) or index < 0: + raise IndexError("Index must be a positive integer: %d" % index) + + if not index in self.__primes: + p1 = self.randomPrime() + self.__primes[index] = p1 + + return self.__primes[index] + + def randomPrime(self): + random_index = self.__random.randint(0, len(PrimeGenerator.LIST_OF_PRIMES) - 1) + return PrimeGenerator.LIST_OF_PRIMES[random_index] diff --git a/ThirdParty/Ert/devel/share/lib/synthesizer/shaped_perlin.py b/ThirdParty/Ert/devel/share/lib/synthesizer/shaped_perlin.py new file mode 100644 index 0000000000..65b63a1f02 --- /dev/null +++ b/ThirdParty/Ert/devel/share/lib/synthesizer/shaped_perlin.py @@ -0,0 +1,106 @@ +import math +from . import PrimeGenerator, PerlinNoise + + +class Interpolator(object): + def __init__(self, x, y): + self.x = x + self.y = y + + assert len(x) == len(y) + + def __call__(self, x): + if x <= self.x[0]: + y = self.y[0] + elif x >= self.x[len(self.x) - 1]: + y = self.y[len(self.x) - 1] + else: + y = None + for i in range(len(self.x) - 1): + if self.x[i] <= x < self.x[i + 1]: + x_diff = self.x[i + 1] - self.x[i] + frac_x = (x - self.x[i]) / x_diff + y = self.cosineInterpolation(self.y[i], self.y[i + 1], frac_x) + break + + return y + + def cosineInterpolation(self, a, b, x): + ft = x * 3.1415927 + f = (1.0 - math.cos(ft)) * 0.5 + return a * (1 - f) + b * f + + +class ShapeFunction(object): + def __init__(self, x, y, scale=1.0): + self.scale = scale + self.interpolator = Interpolator(x, y) + + def __call__(self, x): + return self.interpolator(x) * self.scale + + def scaledCopy(self, scale=1.0): + return ShapeFunction(self.interpolator.x, self.interpolator.y, scale) + + +class ConstantShapeFunction(ShapeFunction): + def __init__(self, value): + super(ConstantShapeFunction, self).__init__([0.0], [value]) + + + +class ShapedNoise(object): + + def __init__(self, noiseFunction, shapeFunction, divergenceFunction, offset=0.0, cutoff=None): + self.shapeFunction = shapeFunction + self.divergenceFunction = divergenceFunction + self.noiseFunction = noiseFunction + self.offset = offset + self.cutoff = cutoff + + def __call__(self, x, scale=1.0): + scaled_x = x * scale + result = self.shapeFunction(scaled_x) + self.noiseFunction(scaled_x) * self.divergenceFunction(scaled_x) + result += self.offset + if self.cutoff is not None: + result = max(result, self.cutoff) + return result + + +class ShapeCreator(object): + + @staticmethod + def createShapeFunction(count=1000, persistence=0.2, octaves=8, seed=1): + """ @rtype: ShapeFunction """ + prime_generator = PrimeGenerator(seed=seed) + perlininator = PerlinNoise(persistence=persistence, number_of_octaves=octaves, prime_generator=prime_generator) + + x_values = [x / float(count) for x in range(count)] + y_values = [perlininator(x) for x in x_values] + + return ShapeFunction(x_values, y_values) + + @staticmethod + def createShapedPerlinFunction(divergence_x, divergence_y, shape_seed=None, perlin_seed=None, count=1000, persistence=0.2, octaves=8, offset=0.0, cutoff=None): + """ @rtype: ShapedNoise """ + shapeFunction = ShapeCreator.createShapeFunction(count, persistence, octaves, shape_seed) + divergenceFunction = ShapeFunction(divergence_x, divergence_y) + prime_generator = PrimeGenerator(perlin_seed) + perlin_noise = PerlinNoise(persistence, octaves, prime_generator) + + return ShapedNoise(perlin_noise, shapeFunction, divergenceFunction, offset=offset, cutoff=cutoff) + + @staticmethod + def createNoiseFunction(shapeFunction=None, divergenceFunction=None, seed=None, persistence=0.2, octaves=8, offset=0.0, cutoff=None): + """ @rtype: ShapedNoise """ + if shapeFunction is None: + shapeFunction = ConstantShapeFunction(0.0) + + if divergenceFunction is None: + divergenceFunction = ConstantShapeFunction(1.0) + + prime_generator = PrimeGenerator(seed) + perlin_noise = PerlinNoise(persistence, octaves, prime_generator) + + noise = ShapedNoise(perlin_noise, shapeFunction, divergenceFunction, offset=offset, cutoff=cutoff) + return noise diff --git a/ThirdParty/Ert/devel/share/workflows/jobs/internal-gui/scripts/gen_data_rft_export.py b/ThirdParty/Ert/devel/share/workflows/jobs/internal-gui/scripts/gen_data_rft_export.py index 52f2bebec5..76c705cf73 100644 --- a/ThirdParty/Ert/devel/share/workflows/jobs/internal-gui/scripts/gen_data_rft_export.py +++ b/ThirdParty/Ert/devel/share/workflows/jobs/internal-gui/scripts/gen_data_rft_export.py @@ -80,7 +80,7 @@ def run(self, output_file, trajectory_path , case_list=None, infer_iteration=Tru conventions: 1. All the GEN_DATA RFT observations have key RFT_$WELL - 2. The trajectory files are in $trajectory_path/$WELL.txt + 2. The trajectory files are in $trajectory_path/$WELL.txt or $trajectory_path/$WELL_R.txt """ @@ -145,9 +145,8 @@ def run(self, output_file, trajectory_path , case_list=None, infer_iteration=Tru std = obs_node.getStandardDeviation( obs_index ) obs[data_index,0] = value obs[data_index,1] = std - - real_data = pandas.DataFrame( index = ["Realization","Well"]) + for iens in realizations: realization_frame = pandas.DataFrame( data = {"TVD" : tvd_arg , "Pressure" : rft_data[iens], @@ -160,9 +159,9 @@ def run(self, output_file, trajectory_path , case_list=None, infer_iteration=Tru realization_frame["Case"] = case realization_frame["Iteration"] = iteration_number - case_frame = pandas.concat( [case_frame , realization_frame] ) - - data_frame = pandas.concat([data_frame, case_frame]) + case_frame = case_frame.append(realization_frame) + + data_frame = data_frame.append(case_frame) data_frame.set_index(["Realization" , "Well" , "Case" , "Iteration"] , inplace = True) data_frame.to_csv(output_file) diff --git a/ThirdParty/Ert/devel/test-data/local/custom_kw/Refcase/CASE.EGRID b/ThirdParty/Ert/devel/test-data/local/custom_kw/Refcase/CASE.EGRID new file mode 100644 index 0000000000..33da9f7a70 Binary files /dev/null and b/ThirdParty/Ert/devel/test-data/local/custom_kw/Refcase/CASE.EGRID differ diff --git a/ThirdParty/Ert/devel/test-data/local/custom_kw/mini_config b/ThirdParty/Ert/devel/test-data/local/custom_kw/mini_config index 68cee8ce40..21a409d739 100644 --- a/ThirdParty/Ert/devel/test-data/local/custom_kw/mini_config +++ b/ThirdParty/Ert/devel/test-data/local/custom_kw/mini_config @@ -37,3 +37,5 @@ DATA_KW CSV_OUTPUT_PATH custom_output.csv OBS_CONFIG Observations/observations CUSTOM_KW AGGREGATED aggregated.txt aggregated_out.txt + +GRID Refcase/CASE.EGRID \ No newline at end of file diff --git a/ThirdParty/NRLib/CMakeLists.txt b/ThirdParty/NRLib/CMakeLists.txt new file mode 100644 index 0000000000..6c2851fe32 --- /dev/null +++ b/ThirdParty/NRLib/CMakeLists.txt @@ -0,0 +1,32 @@ +cmake_minimum_required (VERSION 2.8) + +project (NRLib) + +include_directories( + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/boost + ${CMAKE_CURRENT_SOURCE_DIR}/nrlib + ${CMAKE_CURRENT_SOURCE_DIR}/nrlib/well +) + +file ( GLOB NRLIB_IOTOOLS_SRC + nrlib/iotools/*.hpp + nrlib/iotools/*.cpp +) + +file ( GLOB NRLIB_WELL_SRC + nrlib/well/*.hpp + nrlib/well/*.cpp +) + +add_library( ${PROJECT_NAME} + boost/filesystem/operations.cpp + boost/filesystem/path.cpp + boost/filesystem/portability.cpp + boost/system/error_code.cpp + ${NRLIB_IOTOOLS_SRC} + ${NRLIB_WELL_SRC} +) + +add_subdirectory(well_UnitTests) + diff --git a/ThirdParty/NRLib/Readme.txt b/ThirdParty/NRLib/Readme.txt new file mode 100644 index 0000000000..318ccdb9c9 --- /dev/null +++ b/ThirdParty/NRLib/Readme.txt @@ -0,0 +1,20 @@ +How to update the source code files contained in NRLib +------------------------------------------------------ + +Download the latest boost files needed and place them in the boost folder: + +https://github.com/CRAVA/crava/tree/master/libs/boost + +Download the latest nrlib sub folders from here and replace the contents: + +https://github.com/CRAVA/crava/tree/master/libs/nrlib + +The following sub folders are currently used: + +exception +grid +iotools +stormgrid +surface +volume +well diff --git a/ThirdParty/NRLib/boost/cerrno.hpp b/ThirdParty/NRLib/boost/cerrno.hpp new file mode 100644 index 0000000000..6f2669846d --- /dev/null +++ b/ThirdParty/NRLib/boost/cerrno.hpp @@ -0,0 +1,331 @@ +// Boost cerrno.hpp header -------------------------------------------------// + +// Copyright Beman Dawes 2005. +// Use, modification, and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See library home page at http://www.boost.org/libs/system + +#ifndef BOOST_CERRNO_HPP +#define BOOST_CERRNO_HPP + +#include <cerrno> + +// supply errno values likely to be missing, particularly on Windows + +#ifndef EAFNOSUPPORT +#define EAFNOSUPPORT 9901 +#endif + +#ifndef EADDRINUSE +#define EADDRINUSE 9902 +#endif + +#ifndef EADDRNOTAVAIL +#define EADDRNOTAVAIL 9903 +#endif + +#ifndef EISCONN +#define EISCONN 9904 +#endif + +#ifndef EBADMSG +#define EBADMSG 9905 +#endif + +#ifndef ECONNABORTED +#define ECONNABORTED 9906 +#endif + +#ifndef EALREADY +#define EALREADY 9907 +#endif + +#ifndef ECONNREFUSED +#define ECONNREFUSED 9908 +#endif + +#ifndef ECONNRESET +#define ECONNRESET 9909 +#endif + +#ifndef EDESTADDRREQ +#define EDESTADDRREQ 9910 +#endif + +#ifndef EHOSTUNREACH +#define EHOSTUNREACH 9911 +#endif + +#ifndef EIDRM +#define EIDRM 9912 +#endif + +#ifndef EMSGSIZE +#define EMSGSIZE 9913 +#endif + +#ifndef ENETDOWN +#define ENETDOWN 9914 +#endif + +#ifndef ENETRESET +#define ENETRESET 9915 +#endif + +#ifndef ENETUNREACH +#define ENETUNREACH 9916 +#endif + +#ifndef ENOBUFS +#define ENOBUFS 9917 +#endif + +#ifndef ENOLINK +#define ENOLINK 9918 +#endif + +#ifndef ENODATA +#define ENODATA 9919 +#endif + +#ifndef ENOMSG +#define ENOMSG 9920 +#endif + +#ifndef ENOPROTOOPT +#define ENOPROTOOPT 9921 +#endif + +#ifndef ENOSR +#define ENOSR 9922 +#endif + +#ifndef ENOTSOCK +#define ENOTSOCK 9923 +#endif + +#ifndef ENOSTR +#define ENOSTR 9924 +#endif + +#ifndef ENOTCONN +#define ENOTCONN 9925 +#endif + +#ifndef ENOTSUP +#define ENOTSUP 9926 +#endif + +#ifndef ECANCELED +#define ECANCELED 9927 +#endif + +#ifndef EINPROGRESS +#define EINPROGRESS 9928 +#endif + +#ifndef EOPNOTSUPP +#define EOPNOTSUPP 9929 +#endif + +#ifndef EWOULDBLOCK +#define EWOULDBLOCK 9930 +#endif + +#ifndef EOWNERDEAD +#define EOWNERDEAD 9931 +#endif + +#ifndef EPROTO +#define EPROTO 9932 +#endif + +#ifndef EPROTONOSUPPORT +#define EPROTONOSUPPORT 9933 +#endif + +#ifndef ENOTRECOVERABLE +#define ENOTRECOVERABLE 9934 +#endif + +#ifndef ETIME +#define ETIME 9935 +#endif + +#ifndef ETXTBSY +#define ETXTBSY 9936 +#endif + +#ifndef ETIMEDOUT +#define ETIMEDOUT 9938 +#endif + +#ifndef ELOOP +#define ELOOP 9939 +#endif + +#ifndef EOVERFLOW +#define EOVERFLOW 9940 +#endif + +#ifndef EPROTOTYPE +#define EPROTOTYPE 9941 +#endif + +#ifndef ENOSYS +#define ENOSYS 9942 +#endif + +#ifndef EINVAL +#define EINVAL 9943 +#endif + +#ifndef ERANGE +#define ERANGE 9944 +#endif + +#ifndef EILSEQ +#define EILSEQ 9945 +#endif + +// Windows Mobile doesn't appear to define these: + +#ifndef E2BIG +#define E2BIG 9946 +#endif + +#ifndef EDOM +#define EDOM 9947 +#endif + +#ifndef EFAULT +#define EFAULT 9948 +#endif + +#ifndef EBADF +#define EBADF 9949 +#endif + +#ifndef EPIPE +#define EPIPE 9950 +#endif + +#ifndef EXDEV +#define EXDEV 9951 +#endif + +#ifndef EBUSY +#define EBUSY 9952 +#endif + +#ifndef ENOTEMPTY +#define ENOTEMPTY 9953 +#endif + +#ifndef ENOEXEC +#define ENOEXEC 9954 +#endif + +#ifndef EEXIST +#define EEXIST 9955 +#endif + +#ifndef EFBIG +#define EFBIG 9956 +#endif + +#ifndef ENAMETOOLONG +#define ENAMETOOLONG 9957 +#endif + +#ifndef ENOTTY +#define ENOTTY 9958 +#endif + +#ifndef EINTR +#define EINTR 9959 +#endif + +#ifndef ESPIPE +#define ESPIPE 9960 +#endif + +#ifndef EIO +#define EIO 9961 +#endif + +#ifndef EISDIR +#define EISDIR 9962 +#endif + +#ifndef ECHILD +#define ECHILD 9963 +#endif + +#ifndef ENOLCK +#define ENOLCK 9964 +#endif + +#ifndef ENOSPC +#define ENOSPC 9965 +#endif + +#ifndef ENXIO +#define ENXIO 9966 +#endif + +#ifndef ENODEV +#define ENODEV 9967 +#endif + +#ifndef ENOENT +#define ENOENT 9968 +#endif + +#ifndef ESRCH +#define ESRCH 9969 +#endif + +#ifndef ENOTDIR +#define ENOTDIR 9970 +#endif + +#ifndef ENOMEM +#define ENOMEM 9971 +#endif + +#ifndef EPERM +#define EPERM 9972 +#endif + +#ifndef EACCES +#define EACCES 9973 +#endif + +#ifndef EROFS +#define EROFS 9974 +#endif + +#ifndef EDEADLK +#define EDEADLK 9975 +#endif + +#ifndef EAGAIN +#define EAGAIN 9976 +#endif + +#ifndef ENFILE +#define ENFILE 9977 +#endif + +#ifndef EMFILE +#define EMFILE 9978 +#endif + +#ifndef EMLINK +#define EMLINK 9979 +#endif + +#endif // include guard diff --git a/ThirdParty/NRLib/boost/filesystem.hpp b/ThirdParty/NRLib/boost/filesystem.hpp new file mode 100644 index 0000000000..e64b8b2b4c --- /dev/null +++ b/ThirdParty/NRLib/boost/filesystem.hpp @@ -0,0 +1,20 @@ +// boost/filesystem/filesystem.hpp -----------------------------------------// + +// Copyright Beman Dawes 2005 + +// Use, modification, and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See library home page at http://www.boost.org/libs/filesystem + +//----------------------------------------------------------------------------// + +#ifndef BOOST_FILESYSTEM_FILESYSTEM_HPP +#define BOOST_FILESYSTEM_FILESYSTEM_HPP + +#include <boost/filesystem/operations.hpp> // includes path.hpp +#include <boost/filesystem/convenience.hpp> + +#endif + diff --git a/ThirdParty/NRLib/boost/filesystem/config.hpp b/ThirdParty/NRLib/boost/filesystem/config.hpp new file mode 100644 index 0000000000..3bf8cc70b0 --- /dev/null +++ b/ThirdParty/NRLib/boost/filesystem/config.hpp @@ -0,0 +1,122 @@ +// boost/filesystem/config.hpp ---------------------------------------------// + +// Copyright Beman Dawes 2003 + +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See library home page at http://www.boost.org/libs/filesystem + +//----------------------------------------------------------------------------// + +#ifndef BOOST_FILESYSTEM_CONFIG_HPP +#define BOOST_FILESYSTEM_CONFIG_HPP + +#define BOOST_FILESYSTEM_I18N // aid users wishing to compile several versions + +// ability to change namespace aids path_table.cpp ------------------------// +#ifndef BOOST_FILESYSTEM_NAMESPACE +# define BOOST_FILESYSTEM_NAMESPACE filesystem +#endif + +// This header implements separate compilation features as described in +// http://www.boost.org/more/separate_compilation.html + +// #include <boost/config.hpp> +// #include <boost/detail/workaround.hpp> + +// determine platform ------------------------------------------------------// + +// BOOST_CYGWIN_PATH implies BOOST_WINDOWS_PATH and BOOST_POSIX_API + +# if defined(BOOST_CYGWIN_PATH) +# if defined(BOOST_POSIX_PATH) +# error BOOST_POSIX_PATH is invalid when BOOST_CYGWIN_PATH is defined +# endif +# if defined(BOOST_WINDOWS_API) +# error BOOST_WINDOWS_API is invalid when BOOST_CYGWIN_PATH is defined +# endif +# define BOOST_WINDOWS_PATH +# define BOOST_POSIX_API +# endif + +// BOOST_POSIX_API or BOOST_WINDOWS_API specify which API to use + +# if defined( BOOST_WINDOWS_API ) && defined( BOOST_POSIX_API ) +# error both BOOST_WINDOWS_API and BOOST_POSIX_API are defined +# elif !defined( BOOST_WINDOWS_API ) && !defined( BOOST_POSIX_API ) +# if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) || defined(__CYGWIN__) +# define BOOST_WINDOWS_API +# else +# define BOOST_POSIX_API +# endif +# endif + +// BOOST_WINDOWS_PATH enables Windows path syntax recognition + +# if !defined(BOOST_POSIX_PATH) && (defined(_WIN32) || defined(__WIN32__) || defined(WIN32) || defined(__CYGWIN__)) +# define BOOST_WINDOWS_PATH +# endif + +// narrow support only for badly broken compilers or libraries -------------// + +// NRLib-version: Support for wide characters does not compile. + +//# if defined(BOOST_NO_STD_WSTRING) || defined(BOOST_NO_SFINAE) || defined(BOOST_NO_STD_LOCALE) || BOOST_WORKAROUND(__BORLANDC__, <0x610) +# define BOOST_FILESYSTEM_NARROW_ONLY +//# endif + +// enable dynamic linking on Windows ---------------------------------------// + +# if (defined(BOOST_ALL_DYN_LINK) || defined(BOOST_FILESYSTEM_DYN_LINK)) && defined(__BORLANDC__) && __BORLANDC__ < 0x610 && defined(__WIN32__) +# error Dynamic linking Boost.Filesystem does not work for Borland; use static linking instead +# endif + +#ifdef BOOST_HAS_DECLSPEC // defined in config system +// we need to import/export our code only if the user has specifically +// asked for it by defining either BOOST_ALL_DYN_LINK if they want all boost +// libraries to be dynamically linked, or BOOST_FILESYSTEM_DYN_LINK +// if they want just this one to be dynamically liked: +#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_FILESYSTEM_DYN_LINK) +// export if this is our own source, otherwise import: +#ifdef BOOST_FILESYSTEM_SOURCE +# define BOOST_FILESYSTEM_DECL __declspec(dllexport) +#else +# define BOOST_FILESYSTEM_DECL __declspec(dllimport) +#endif // BOOST_FILESYSTEM_SOURCE +#endif // DYN_LINK +#endif // BOOST_HAS_DECLSPEC +// +// if BOOST_FILESYSTEM_DECL isn't defined yet define it now: +#ifndef BOOST_FILESYSTEM_DECL +#define BOOST_FILESYSTEM_DECL +#endif + +// enable automatic library variant selection ------------------------------// + +#if 0 // NRLib: Comment out auto-linking +#if !defined(BOOST_FILESYSTEM_SOURCE) && !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_FILESYSTEM_NO_LIB) +// +// Set the name of our library, this will get undef'ed by auto_link.hpp +// once it's done with it: +// +#define BOOST_LIB_NAME boost_filesystem +// +// If we're importing code from a dll, then tell auto_link.hpp about it: +// +#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_FILESYSTEM_DYN_LINK) +# define BOOST_DYN_LINK +#endif +// +// And include the header that does the work: +// +#include <boost/config/auto_link.hpp> +#endif // auto-linking disabled +#endif // #if 0 + +// NRLib: Definitions copied from other places in Boost. +#define BOOST_STATIC_CONSTANT(type, assignment) static const type assignment + +#define BOOST_FILESYSTEM_NO_DEPRECATED + +#endif // BOOST_FILESYSTEM_CONFIG_HPP diff --git a/ThirdParty/NRLib/boost/filesystem/convenience.hpp b/ThirdParty/NRLib/boost/filesystem/convenience.hpp new file mode 100644 index 0000000000..3882cf5354 --- /dev/null +++ b/ThirdParty/NRLib/boost/filesystem/convenience.hpp @@ -0,0 +1,333 @@ +// boost/filesystem/convenience.hpp ----------------------------------------// + +// Copyright Beman Dawes, 2002-2005 +// Copyright Vladimir Prus, 2002 +// Use, modification, and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See library home page at http://www.boost.org/libs/filesystem + +//----------------------------------------------------------------------------// + +#ifndef BOOST_FILESYSTEM_CONVENIENCE_HPP +#define BOOST_FILESYSTEM_CONVENIENCE_HPP + +#include <boost/filesystem/operations.hpp> +#include <boost/system/error_code.hpp> +#include <vector> +#include <stack> + +//#include <boost/config/abi_prefix.hpp> // must be the last #include + +# ifndef BOOST_FILESYSTEM_NARROW_ONLY +# define BOOST_FS_FUNC(BOOST_FS_TYPE) \ + template<class Path> typename boost::enable_if<is_basic_path<Path>, \ + BOOST_FS_TYPE>::type +# define BOOST_FS_FUNC_STRING BOOST_FS_FUNC(typename Path::string_type) +# define BOOST_FS_TYPENAME typename +# else +# define BOOST_FS_FUNC(BOOST_FS_TYPE) inline BOOST_FS_TYPE + typedef boost::filesystem::path Path; +# define BOOST_FS_FUNC_STRING inline std::string +# define BOOST_FS_TYPENAME +# endif + +namespace boost +{ + namespace filesystem + { + + BOOST_FS_FUNC(bool) create_directories(const Path& ph) + { + if (ph.empty() || exists(ph)) + { + if ( !ph.empty() && !is_directory(ph) ) + throw basic_filesystem_error<Path>( + "boost::filesystem::create_directories", ph, + make_error_code( boost::system::errc::file_exists ) ); + return false; + } + + // First create branch, by calling ourself recursively + create_directories(ph.parent_path()); + // Now that parent's path exists, create the directory + create_directory(ph); + return true; + } + +# ifndef BOOST_FILESYSTEM_NO_DEPRECATED + + BOOST_FS_FUNC_STRING extension(const Path& ph) + { + typedef BOOST_FS_TYPENAME Path::string_type string_type; + string_type filename = ph.filename(); + + BOOST_FS_TYPENAME string_type::size_type n = filename.rfind('.'); + if (n != string_type::npos) + return filename.substr(n); + else + return string_type(); + } + + BOOST_FS_FUNC_STRING basename(const Path& ph) + { + typedef BOOST_FS_TYPENAME Path::string_type string_type; + string_type filename = ph.filename(); + BOOST_FS_TYPENAME string_type::size_type n = filename.rfind('.'); + return filename.substr(0, n); + } + + + BOOST_FS_FUNC(Path) change_extension( const Path & ph, + const BOOST_FS_TYPENAME Path::string_type & new_extension ) + { return ph.parent_path() / (basename(ph) + new_extension); } + +# endif + +# ifndef BOOST_FILESYSTEM_NARROW_ONLY + + // "do-the-right-thing" overloads ---------------------------------------// + + inline bool create_directories(const path& ph) + { return create_directories<path>(ph); } + inline bool create_directories(const wpath& ph) + { return create_directories<wpath>(ph); } + +# ifndef BOOST_FILESYSTEM_NO_DEPRECATED + inline std::string extension(const path& ph) + { return extension<path>(ph); } + inline std::wstring extension(const wpath& ph) + { return extension<wpath>(ph); } + + inline std::string basename(const path& ph) + { return basename<path>( ph ); } + inline std::wstring basename(const wpath& ph) + { return basename<wpath>( ph ); } + + inline path change_extension( const path & ph, const std::string& new_ex ) + { return change_extension<path>( ph, new_ex ); } + inline wpath change_extension( const wpath & ph, const std::wstring& new_ex ) + { return change_extension<wpath>( ph, new_ex ); } +# endif + +# endif + + + // basic_recursive_directory_iterator helpers --------------------------// + + namespace detail + { + template< class Path > + struct recur_dir_itr_imp + { + typedef basic_directory_iterator< Path > element_type; + std::stack< element_type, std::vector< element_type > > m_stack; + int m_level; + bool m_no_push; + bool m_no_throw; + + recur_dir_itr_imp() : m_level(0), m_no_push(false), m_no_throw(false) {} + }; + + } // namespace detail + + // basic_recursive_directory_iterator ----------------------------------// + + template< class Path > + class basic_recursive_directory_iterator + //: public boost::iterator_facade< + // basic_recursive_directory_iterator<Path>, + // basic_directory_entry<Path>, + // boost::single_pass_traversal_tag > + { + public: + typedef Path path_type; + typedef basic_directory_entry<Path> value_type; + typedef value_type& reference; + typedef const value_type* pointer; + typedef ptrdiff_t difference_type; + typedef std::input_iterator_tag iterator_category; + + basic_recursive_directory_iterator() : m_imp(0) {} // creates the "end" iterator + + explicit basic_recursive_directory_iterator( const Path & dir_path ); + basic_recursive_directory_iterator( const Path & dir_path, + system::error_code & ec ); + + ~basic_recursive_directory_iterator() { delete m_imp; } + reference operator*() const + { return dereference(); } + + pointer operator->() const + { return &(operator*()); } + + const basic_recursive_directory_iterator& operator++() { + increment(); + return *this; + } + + basic_recursive_directory_iterator operator++(int) { + basic_recursive_directory_iterator tmp(*this); + ++*this; + return tmp; + } + + bool operator==(const basic_recursive_directory_iterator& rhs) const + { return equal (rhs); } + + bool operator!=(const basic_recursive_directory_iterator& rhs) const + { return !operator==(rhs); } + + int level() const { return m_imp->m_level; } + + void pop(); + void no_push() + { + BOOST_ASSERT( m_imp->get() && "attempt to no_push() on end iterator" ); + m_imp->m_no_push = true; + } + + file_status status() const + { + BOOST_ASSERT( m_imp->get() + && "attempt to call status() on end recursive_iterator" ); + return m_imp->m_stack.top()->status(); + } + + file_status symlink_status() const + { + BOOST_ASSERT( m_imp->get() + && "attempt to call symlink_status() on end recursive_iterator" ); + return m_imp->m_stack.top()->symlink_status(); + } + + private: + + // shared_ptr provides shallow-copy semantics required for InputIterators. + // m_imp->get()==0 indicates the end iterator. + detail::recur_dir_itr_imp< Path > * m_imp; + + //typename boost::iterator_facade< + // basic_recursive_directory_iterator<Path>, + // basic_directory_entry<Path>, + // boost::single_pass_traversal_tag >::reference + reference dereference() const + { + assert( m_imp != 0 && "attempt to dereference end iterator" ); + return *m_imp->m_stack.top(); + } + + void increment(); + + bool equal( const basic_recursive_directory_iterator & rhs ) const + { return m_imp == rhs.m_imp; } + + }; + + typedef basic_recursive_directory_iterator<path> recursive_directory_iterator; +# ifndef BOOST_FILESYSTEM_NARROW_ONLY + typedef basic_recursive_directory_iterator<wpath> wrecursive_directory_iterator; +# endif + + // basic_recursive_directory_iterator implementation -------------------// + + // constructors + template<class Path> + basic_recursive_directory_iterator<Path>:: + basic_recursive_directory_iterator( const Path & dir_path ) + : m_imp( new detail::recur_dir_itr_imp<Path> ) + { + m_imp->m_stack.push( basic_directory_iterator<Path>( dir_path ) ); + if ( m_imp->m_stack.top () == basic_directory_iterator<Path>() ) + { m_imp->reset (); } + } + + template<class Path> + basic_recursive_directory_iterator<Path>:: + basic_recursive_directory_iterator( const Path & dir_path, + system::error_code & ec ) + : m_imp( new detail::recur_dir_itr_imp<Path> ) + { + m_imp->m_no_throw = true; + m_imp->m_stack.push( basic_directory_iterator<Path>( dir_path, ec ) ); + if ( m_imp->m_stack.top () == basic_directory_iterator<Path>() ) + { m_imp->reset (); } + } + + // increment + template<class Path> + void basic_recursive_directory_iterator<Path>::increment() + { + BOOST_ASSERT( m_imp->get() && "increment on end iterator" ); + + static const basic_directory_iterator<Path> end_itr; + + if ( m_imp->m_no_push ) + { m_imp->m_no_push = false; } + else if ( is_directory( m_imp->m_stack.top()->status() ) ) + { + system::error_code ec; +#if 0 // BOOST_WORKAROUND(__CODEGEARC__, BOOST_TESTED_AT(0x610)) + if ( m_imp->m_no_throw ) { + m_imp->m_stack.push( + basic_directory_iterator<Path>( *m_imp->m_stack.top(), ec ) + ); + } + else { + m_imp->m_stack.push( + basic_directory_iterator<Path>( *m_imp->m_stack.top() ) + ); + } +#else + m_imp->m_stack.push( + m_imp->m_no_throw + ? basic_directory_iterator<Path>( *m_imp->m_stack.top(), ec ) + : basic_directory_iterator<Path>( *m_imp->m_stack.top() ) ); +#endif + if ( m_imp->m_stack.top() != end_itr ) + { + ++m_imp->m_level; + return; + } + m_imp->m_stack.pop(); + } + + while ( !m_imp->m_stack.empty() + && ++m_imp->m_stack.top() == end_itr ) + { + m_imp->m_stack.pop(); + --m_imp->m_level; + } + + if ( m_imp->m_stack.empty() ) m_imp->reset(); // done, so make end iterator + } + + // pop + template<class Path> + void basic_recursive_directory_iterator<Path>::pop() + { + BOOST_ASSERT( m_imp->get() && "pop on end iterator" ); + BOOST_ASSERT( m_imp->m_level > 0 && "pop with level < 1" ); + + static const basic_directory_iterator<Path> end_itr; + + do + { + m_imp->m_stack.pop(); + --m_imp->m_level; + } + while ( !m_imp->m_stack.empty() + && ++m_imp->m_stack.top() == end_itr ); + + if ( m_imp->m_stack.empty() ) m_imp->reset(); // done, so make end iterator + } + + } // namespace filesystem +} // namespace boost + +#undef BOOST_FS_FUNC_STRING +#undef BOOST_FS_FUNC + +//#include <boost/config/abi_suffix.hpp> // pops abi_prefix.hpp pragmas +#endif // BOOST_FILESYSTEM_CONVENIENCE_HPP diff --git a/ThirdParty/NRLib/boost/filesystem/fstream.hpp b/ThirdParty/NRLib/boost/filesystem/fstream.hpp new file mode 100644 index 0000000000..af5d802258 --- /dev/null +++ b/ThirdParty/NRLib/boost/filesystem/fstream.hpp @@ -0,0 +1,584 @@ +// boost/filesystem/fstream.hpp --------------------------------------------// + +// Copyright Beman Dawes 2002. +// Use, modification, and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See library home page at http://www.boost.org/libs/filesystem + +//----------------------------------------------------------------------------// + +#ifndef BOOST_FILESYSTEM_FSTREAM_HPP +#define BOOST_FILESYSTEM_FSTREAM_HPP + +#include <boost/filesystem/operations.hpp> // for 8.3 hack (see below) +//#include <boost/utility/enable_if.hpp> +//#include <boost/detail/workaround.hpp> + +#include <iosfwd> +#include <fstream> + +//#include <boost/config/abi_prefix.hpp> // must be the last #include + +// NOTE: fstream.hpp for Boost 1.32.0 and earlier supplied workarounds for +// various compiler problems. They have been removed to ease development of the +// basic i18n functionality. Once the new interface is stable, the workarounds +// will be reinstated for any compilers that otherwise can support the rest of +// the library after internationalization. + +namespace boost +{ + namespace filesystem + { + namespace detail + { +# if defined(BOOST_WINDOWS_API) && !defined(BOOST_FILESYSTEM_NARROW_ONLY) +# if !defined(BOOST_DINKUMWARE_STDLIB) || BOOST_DINKUMWARE_STDLIB < 405 + // The 8.3 hack: + // C++98 does not supply a wchar_t open, so try to get an equivalent + // narrow char name based on the short, so-called 8.3, name. + // Not needed for Dinkumware 405 and later as they do supply wchar_t open. + BOOST_FILESYSTEM_DECL bool create_file_api( const std::wstring & ph, + std::ios_base::openmode mode ); // true if succeeds + BOOST_FILESYSTEM_DECL std::string narrow_path_api( + const std::wstring & ph ); // return is empty if fails + + inline std::string path_proxy( const std::wstring & file_ph, + std::ios_base::openmode mode ) + // Return a non-existant path if cannot supply narrow short path. + // An empty path doesn't work because some Dinkumware versions + // assert the path is non-empty. + { + std::string narrow_ph; + bool created_file( false ); + if ( !exists( file_ph ) + && (mode & std::ios_base::out) != 0 + && create_file_api( file_ph, mode ) ) + { + created_file = true; + } + narrow_ph = narrow_path_api( file_ph ); + if ( narrow_ph.empty() ) + { + if ( created_file ) remove_api( file_ph ); + narrow_ph = "\x01"; + } + return narrow_ph; + } +# else + // Dinkumware 405 and later does supply wchar_t functions + inline const std::wstring & path_proxy( const std::wstring & file_ph, + std::ios_base::openmode ) + { return file_ph; } +# endif +# endif + + inline const std::string & path_proxy( const std::string & file_ph, + std::ios_base::openmode ) + { return file_ph; } + + } // namespace detail + + template < class charT, class traits = std::char_traits<charT> > + class basic_filebuf : public std::basic_filebuf<charT,traits> + { + private: // disallow copying + basic_filebuf( const basic_filebuf & ); + const basic_filebuf & operator=( const basic_filebuf & ); + public: + basic_filebuf() {} + virtual ~basic_filebuf() {} + +# ifndef BOOST_FILESYSTEM_NARROW_ONLY + template<class Path> + typename boost::enable_if<is_basic_path<Path>, + basic_filebuf<charT,traits> *>::type + open( const Path & file_ph, std::ios_base::openmode mode ); + + basic_filebuf<charT,traits> * + open( const wpath & file_ph, std::ios_base::openmode mode ); +# endif + +# if !BOOST_WORKAROUND( BOOST_MSVC, <= 1200 ) // VC++ 6.0 can't handle this + basic_filebuf<charT,traits> * + open( const path & file_ph, std::ios_base::openmode mode ); +# endif + }; + + template < class charT, class traits = std::char_traits<charT> > + class basic_ifstream : public std::basic_ifstream<charT,traits> + { + private: // disallow copying + basic_ifstream( const basic_ifstream & ); + const basic_ifstream & operator=( const basic_ifstream & ); + public: + basic_ifstream() {} + + // use two signatures, rather than one signature with default second + // argument, to workaround VC++ 7.1 bug (ID VSWhidbey 38416) + +# ifndef BOOST_FILESYSTEM_NARROW_ONLY + template<class Path> + explicit basic_ifstream( const Path & file_ph, + typename boost::enable_if<is_basic_path<Path> >::type* dummy = 0 ); + + template<class Path> + basic_ifstream( const Path & file_ph, std::ios_base::openmode mode, + typename boost::enable_if<is_basic_path<Path> >::type* dummy = 0 ); + + template<class Path> + typename boost::enable_if<is_basic_path<Path>, void>::type + open( const Path & file_ph ); + + template<class Path> + typename boost::enable_if<is_basic_path<Path>, void>::type + open( const Path & file_ph, std::ios_base::openmode mode ); + + explicit basic_ifstream( const wpath & file_ph ); + basic_ifstream( const wpath & file_ph, std::ios_base::openmode mode ); + void open( const wpath & file_ph ); + void open( const wpath & file_ph, std::ios_base::openmode mode ); +# endif + + explicit basic_ifstream( const path & file_ph ); + basic_ifstream( const path & file_ph, std::ios_base::openmode mode ); +# if !BOOST_WORKAROUND( BOOST_MSVC, <= 1200 ) // VC++ 6.0 can't handle this + void open( const path & file_ph ); + void open( const path & file_ph, std::ios_base::openmode mode ); +# endif + virtual ~basic_ifstream() {} + }; + + template < class charT, class traits = std::char_traits<charT> > + class basic_ofstream : public std::basic_ofstream<charT,traits> + { + private: // disallow copying + basic_ofstream( const basic_ofstream & ); + const basic_ofstream & operator=( const basic_ofstream & ); + public: + basic_ofstream() {} + + // use two signatures, rather than one signature with default second + // argument, to workaround VC++ 7.1 bug (ID VSWhidbey 38416) + +# ifndef BOOST_FILESYSTEM_NARROW_ONLY + + template<class Path> + explicit basic_ofstream( const Path & file_ph, + typename boost::enable_if<is_basic_path<Path> >::type* dummy = 0 ); + explicit basic_ofstream( const wpath & file_ph ); + + template<class Path> + basic_ofstream( const Path & file_ph, std::ios_base::openmode mode, + typename boost::enable_if<is_basic_path<Path> >::type* dummy = 0 ); + basic_ofstream( const wpath & file_ph, std::ios_base::openmode mode ); + + template<class Path> + typename boost::enable_if<is_basic_path<Path>, void>::type + open( const Path & file_ph ); + void open( const wpath & file_ph ); + + template<class Path> + typename boost::enable_if<is_basic_path<Path>, void>::type + open( const Path & file_ph, std::ios_base::openmode mode ); + void open( const wpath & file_ph, std::ios_base::openmode mode ); + +# endif + + explicit basic_ofstream( const path & file_ph ); + basic_ofstream( const path & file_ph, std::ios_base::openmode mode ); +# if !BOOST_WORKAROUND( BOOST_MSVC, <= 1200 ) // VC++ 6.0 can't handle this + void open( const path & file_ph ); + void open( const path & file_ph, std::ios_base::openmode mode ); +# endif + virtual ~basic_ofstream() {} + }; + + template < class charT, class traits = std::char_traits<charT> > + class basic_fstream : public std::basic_fstream<charT,traits> + { + private: // disallow copying + basic_fstream( const basic_fstream & ); + const basic_fstream & operator=( const basic_fstream & ); + public: + basic_fstream() {} + + // use two signatures, rather than one signature with default second + // argument, to workaround VC++ 7.1 bug (ID VSWhidbey 38416) + +# ifndef BOOST_FILESYSTEM_NARROW_ONLY + + template<class Path> + explicit basic_fstream( const Path & file_ph, + typename boost::enable_if<is_basic_path<Path> >::type* dummy = 0 ); + explicit basic_fstream( const wpath & file_ph ); + + template<class Path> + basic_fstream( const Path & file_ph, std::ios_base::openmode mode, + typename boost::enable_if<is_basic_path<Path> >::type* dummy = 0 ); + basic_fstream( const wpath & file_ph, std::ios_base::openmode mode ); + + template<class Path> + typename boost::enable_if<is_basic_path<Path>, void>::type + open( const Path & file_ph ); + void open( const wpath & file_ph ); + + template<class Path> + typename boost::enable_if<is_basic_path<Path>, void>::type + open( const Path & file_ph, std::ios_base::openmode mode ); + void open( const wpath & file_ph, std::ios_base::openmode mode ); + +# endif + + explicit basic_fstream( const path & file_ph ); + basic_fstream( const path & file_ph, std::ios_base::openmode mode ); +# if !BOOST_WORKAROUND( BOOST_MSVC, <= 1200 ) // VC++ 6.0 can't handle this + void open( const path & file_ph ); + void open( const path & file_ph, std::ios_base::openmode mode ); +# endif + virtual ~basic_fstream() {} + + }; + + typedef basic_filebuf<char> filebuf; + typedef basic_ifstream<char> ifstream; + typedef basic_ofstream<char> ofstream; + typedef basic_fstream<char> fstream; + +# ifndef BOOST_FILESYSTEM_NARROW_ONLY + typedef basic_filebuf<wchar_t> wfilebuf; + typedef basic_ifstream<wchar_t> wifstream; + typedef basic_fstream<wchar_t> wfstream; + typedef basic_ofstream<wchar_t> wofstream; +# endif + +# ifndef BOOST_FILESYSTEM_NARROW_ONLY + +// basic_filebuf definitions -----------------------------------------------// + + template <class charT, class traits> + template<class Path> + typename boost::enable_if<is_basic_path<Path>, + basic_filebuf<charT,traits> *>::type + basic_filebuf<charT,traits>::open( const Path & file_ph, + std::ios_base::openmode mode ) + { + return (std::basic_filebuf<charT,traits>::open( detail::path_proxy( + file_ph.external_file_string(), mode ).c_str(), mode ) + == 0) ? 0 : this; + } + + template <class charT, class traits> + basic_filebuf<charT,traits> * + basic_filebuf<charT, traits>::open( const wpath & file_ph, + std::ios_base::openmode mode ) + { + return this->BOOST_NESTED_TEMPLATE open<wpath>( file_ph, mode ); + } + +// basic_ifstream definitions ----------------------------------------------// + + template <class charT, class traits> template<class Path> + basic_ifstream<charT,traits>::basic_ifstream(const Path & file_ph, + typename boost::enable_if<is_basic_path<Path> >::type* ) + : std::basic_ifstream<charT,traits>( + detail::path_proxy( file_ph.external_file_string(), + std::ios_base::in ).c_str(), std::ios_base::in ) {} + + template <class charT, class traits> + basic_ifstream<charT,traits>::basic_ifstream( const wpath & file_ph ) + : std::basic_ifstream<charT,traits>( + detail::path_proxy( file_ph.external_file_string(), + std::ios_base::in ).c_str(), std::ios_base::in ) {} + + template <class charT, class traits> template<class Path> + basic_ifstream<charT,traits>::basic_ifstream( const Path & file_ph, + std::ios_base::openmode mode, + typename boost::enable_if<is_basic_path<Path> >::type* ) + : std::basic_ifstream<charT,traits>( + detail::path_proxy( file_ph.external_file_string(), + mode ).c_str(), mode | std::ios_base::in ) {} + + template <class charT, class traits> + basic_ifstream<charT,traits>::basic_ifstream( const wpath & file_ph, + std::ios_base::openmode mode ) + : std::basic_ifstream<charT,traits>( + detail::path_proxy( file_ph.external_file_string(), + mode ).c_str(), mode | std::ios_base::in ) {} + + template <class charT, class traits> template<class Path> + typename boost::enable_if<is_basic_path<Path>, void>::type + basic_ifstream<charT,traits>::open( const Path & file_ph ) + { + std::basic_ifstream<charT,traits>::open( + detail::path_proxy( file_ph.external_file_string(), + std::ios_base::in ).c_str(), std::ios_base::in ); + } + + template <class charT, class traits> + void basic_ifstream<charT,traits>::open( const wpath & file_ph ) + { + std::basic_ifstream<charT,traits>::open( + detail::path_proxy( file_ph.external_file_string(), + std::ios_base::in ).c_str(), std::ios_base::in ); + } + + template <class charT, class traits> template<class Path> + typename boost::enable_if<is_basic_path<Path>, void>::type + basic_ifstream<charT,traits>::open( const Path & file_ph, + std::ios_base::openmode mode ) + { + std::basic_ifstream<charT,traits>::open( + detail::path_proxy( file_ph.external_file_string(), + mode ).c_str(), mode | std::ios_base::in ); + } + + template <class charT, class traits> + void basic_ifstream<charT,traits>::open( const wpath & file_ph, + std::ios_base::openmode mode ) + { + std::basic_ifstream<charT,traits>::open( + detail::path_proxy( file_ph.external_file_string(), + mode ).c_str(), mode | std::ios_base::in ); + } + +// basic_ofstream definitions ----------------------------------------------// + + template <class charT, class traits> template<class Path> + basic_ofstream<charT,traits>::basic_ofstream(const Path & file_ph, + typename boost::enable_if<is_basic_path<Path> >::type* ) + : std::basic_ofstream<charT,traits>( + detail::path_proxy( file_ph.external_file_string(), + std::ios_base::out ).c_str(), std::ios_base::out ) {} + + template <class charT, class traits> + basic_ofstream<charT,traits>::basic_ofstream( const wpath & file_ph ) + : std::basic_ofstream<charT,traits>( + detail::path_proxy( file_ph.external_file_string(), + std::ios_base::out ).c_str(), std::ios_base::out ) {} + + template <class charT, class traits> template<class Path> + basic_ofstream<charT,traits>::basic_ofstream( const Path & file_ph, + std::ios_base::openmode mode, + typename boost::enable_if<is_basic_path<Path> >::type* ) + : std::basic_ofstream<charT,traits>( + detail::path_proxy( file_ph.external_file_string(), + mode ).c_str(), mode | std::ios_base::out ) {} + + template <class charT, class traits> + basic_ofstream<charT,traits>::basic_ofstream( const wpath & file_ph, + std::ios_base::openmode mode ) + : std::basic_ofstream<charT,traits>( + detail::path_proxy( file_ph.external_file_string(), + mode ).c_str(), mode | std::ios_base::out ) {} + + template <class charT, class traits> template<class Path> + typename boost::enable_if<is_basic_path<Path>, void>::type + basic_ofstream<charT,traits>::open( const Path & file_ph ) + { + std::basic_ofstream<charT,traits>::open( + detail::path_proxy( file_ph.external_file_string(), + std::ios_base::out ).c_str(), std::ios_base::out ); + } + + template <class charT, class traits> + void basic_ofstream<charT,traits>::open( const wpath & file_ph ) + { + std::basic_ofstream<charT,traits>::open( + detail::path_proxy( file_ph.external_file_string(), + std::ios_base::out ).c_str(), std::ios_base::out ); + } + + template <class charT, class traits> template<class Path> + typename boost::enable_if<is_basic_path<Path>, void>::type + basic_ofstream<charT,traits>::open( const Path & file_ph, + std::ios_base::openmode mode ) + { + std::basic_ofstream<charT,traits>::open( + detail::path_proxy( file_ph.external_file_string(), + mode ).c_str(), mode | std::ios_base::out ); + } + + template <class charT, class traits> + void basic_ofstream<charT,traits>::open( const wpath & file_ph, + std::ios_base::openmode mode ) + { + std::basic_ofstream<charT,traits>::open( + detail::path_proxy( file_ph.external_file_string(), + mode ).c_str(), mode | std::ios_base::out ); + } + +// basic_fstream definitions -----------------------------------------------// + + template <class charT, class traits> template<class Path> + basic_fstream<charT,traits>::basic_fstream(const Path & file_ph, + typename boost::enable_if<is_basic_path<Path> >::type* ) + : std::basic_fstream<charT,traits>( + detail::path_proxy( file_ph.external_file_string(), + std::ios_base::in|std::ios_base::out ).c_str(), + std::ios_base::in|std::ios_base::out ) {} + + template <class charT, class traits> + basic_fstream<charT,traits>::basic_fstream( const wpath & file_ph ) + : std::basic_fstream<charT,traits>( + detail::path_proxy( file_ph.external_file_string(), + std::ios_base::in|std::ios_base::out ).c_str(), + std::ios_base::in|std::ios_base::out ) {} + + template <class charT, class traits> template<class Path> + basic_fstream<charT,traits>::basic_fstream( const Path & file_ph, + std::ios_base::openmode mode, + typename boost::enable_if<is_basic_path<Path> >::type* ) + : std::basic_fstream<charT,traits>( + detail::path_proxy( file_ph.external_file_string(), + mode ).c_str(), mode | std::ios_base::in | std::ios_base::out ) {} + + template <class charT, class traits> + basic_fstream<charT,traits>::basic_fstream( const wpath & file_ph, + std::ios_base::openmode mode ) + : std::basic_fstream<charT,traits>( + detail::path_proxy( file_ph.external_file_string(), + mode ).c_str(), mode | std::ios_base::in | std::ios_base::out ) {} + + template <class charT, class traits> template<class Path> + typename boost::enable_if<is_basic_path<Path>, void>::type + basic_fstream<charT,traits>::open( const Path & file_ph ) + { + std::basic_fstream<charT,traits>::open( + detail::path_proxy( file_ph.external_file_string(), + std::ios_base::in|std::ios_base::out ).c_str(), + std::ios_base::in|std::ios_base::out ); + } + + template <class charT, class traits> + void basic_fstream<charT,traits>::open( const wpath & file_ph ) + { + std::basic_fstream<charT,traits>::open( + detail::path_proxy( file_ph.external_file_string(), + std::ios_base::in|std::ios_base::out ).c_str(), + std::ios_base::in|std::ios_base::out ); + } + + template <class charT, class traits> template<class Path> + typename boost::enable_if<is_basic_path<Path>, void>::type + basic_fstream<charT,traits>::open( const Path & file_ph, + std::ios_base::openmode mode ) + { + std::basic_fstream<charT,traits>::open( + detail::path_proxy( file_ph.external_file_string(), + mode ).c_str(), mode | std::ios_base::in | std::ios_base::out ); + } + + template <class charT, class traits> + void basic_fstream<charT,traits>::open( const wpath & file_ph, + std::ios_base::openmode mode ) + { + std::basic_fstream<charT,traits>::open( + detail::path_proxy( file_ph.external_file_string(), + mode ).c_str(), mode | std::ios_base::in | std::ios_base::out ); + } + +# endif + +# if !BOOST_WORKAROUND( BOOST_MSVC, <= 1200 ) // VC++ 6.0 can't handle this + template <class charT, class traits> + basic_filebuf<charT,traits> * + basic_filebuf<charT, traits>::open( const path & file_ph, + std::ios_base::openmode mode ) + { + return std::basic_filebuf<charT,traits>::open( + file_ph.file_string().c_str(), mode ) == 0 ? 0 : this; + } +# endif + + template <class charT, class traits> + basic_ifstream<charT,traits>::basic_ifstream( const path & file_ph ) + : std::basic_ifstream<charT,traits>( + file_ph.file_string().c_str(), std::ios_base::in ) {} + + template <class charT, class traits> + basic_ifstream<charT,traits>::basic_ifstream( const path & file_ph, + std::ios_base::openmode mode ) + : std::basic_ifstream<charT,traits>( + file_ph.file_string().c_str(), mode ) {} + +# if !BOOST_WORKAROUND( BOOST_MSVC, <= 1200 ) // VC++ 6.0 can't handle this + template <class charT, class traits> + void basic_ifstream<charT,traits>::open( const path & file_ph ) + { + std::basic_ifstream<charT,traits>::open( + file_ph.file_string().c_str(), std::ios_base::in ); + } + + template <class charT, class traits> + void basic_ifstream<charT,traits>::open( const path & file_ph, + std::ios_base::openmode mode ) + { + std::basic_ifstream<charT,traits>::open( + file_ph.file_string().c_str(), mode ); + } +# endif + + template <class charT, class traits> + basic_ofstream<charT,traits>::basic_ofstream( const path & file_ph ) + : std::basic_ofstream<charT,traits>( + file_ph.file_string().c_str(), std::ios_base::out ) {} + + template <class charT, class traits> + basic_ofstream<charT,traits>::basic_ofstream( const path & file_ph, + std::ios_base::openmode mode ) + : std::basic_ofstream<charT,traits>( + file_ph.file_string().c_str(), mode ) {} + +# if !BOOST_WORKAROUND( BOOST_MSVC, <= 1200 ) // VC++ 6.0 can't handle this + template <class charT, class traits> + void basic_ofstream<charT,traits>::open( const path & file_ph ) + { + std::basic_ofstream<charT,traits>::open( + file_ph.file_string().c_str(), std::ios_base::out ); + } + + template <class charT, class traits> + void basic_ofstream<charT,traits>::open( const path & file_ph, + std::ios_base::openmode mode ) + { + std::basic_ofstream<charT,traits>::open( + file_ph.file_string().c_str(), mode ); + } +# endif + + template <class charT, class traits> + basic_fstream<charT,traits>::basic_fstream( const path & file_ph ) + : std::basic_fstream<charT,traits>( + file_ph.file_string().c_str(), + std::ios_base::in|std::ios_base::out ) {} + + + template <class charT, class traits> + basic_fstream<charT,traits>::basic_fstream( const path & file_ph, + std::ios_base::openmode mode ) + : std::basic_fstream<charT,traits>( + file_ph.file_string().c_str(), mode ) {} + +# if !BOOST_WORKAROUND( BOOST_MSVC, <= 1200 ) // VC++ 6.0 can't handle this + template <class charT, class traits> + void basic_fstream<charT,traits>::open( const path & file_ph ) + { + std::basic_fstream<charT,traits>::open( + file_ph.file_string().c_str(), std::ios_base::in|std::ios_base::out ); + } + + template <class charT, class traits> + void basic_fstream<charT,traits>::open( const path & file_ph, + std::ios_base::openmode mode ) + { + std::basic_fstream<charT,traits>::open( + file_ph.file_string().c_str(), mode ); + } +# endif + } // namespace filesystem +} // namespace boost + +//#include <boost/config/abi_suffix.hpp> // pops abi_prefix.hpp pragmas +#endif // BOOST_FILESYSTEM_FSTREAM_HPP diff --git a/ThirdParty/NRLib/boost/filesystem/module.mk b/ThirdParty/NRLib/boost/filesystem/module.mk new file mode 100644 index 0000000000..e354383d35 --- /dev/null +++ b/ThirdParty/NRLib/boost/filesystem/module.mk @@ -0,0 +1,3 @@ +SRC += filesystem/operations.cpp \ + filesystem/path.cpp \ + filesystem/portability.cpp diff --git a/ThirdParty/NRLib/boost/filesystem/operations.cpp b/ThirdParty/NRLib/boost/filesystem/operations.cpp new file mode 100644 index 0000000000..6b6314d0d4 --- /dev/null +++ b/ThirdParty/NRLib/boost/filesystem/operations.cpp @@ -0,0 +1,1382 @@ +// operations.cpp ----------------------------------------------------------// + +// Copyright 2002-2005 Beman Dawes +// Copyright 2001 Dietmar Kuehl +// Use, modification, and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy +// at http://www.boost.org/LICENSE_1_0.txt) + +// See library home page at http://www.boost.org/libs/filesystem + +//----------------------------------------------------------------------------// + +// define BOOST_FILESYSTEM_SOURCE so that <boost/filesystem/config.hpp> knows +// the library is being built (possibly exporting rather than importing code) +#define BOOST_FILESYSTEM_SOURCE + +#define _POSIX_PTHREAD_SEMANTICS // Sun readdir_r() needs this + +// enable the XPG-compliant version of readdir_r() on AIX +#if defined(_AIX) +# define _LINUX_SOURCE_COMPAT +#endif + +#if !(defined(__HP_aCC) && defined(_ILP32) && \ + !defined(_STATVFS_ACPP_PROBLEMS_FIXED)) +#define _FILE_OFFSET_BITS 64 // at worst, these defines may have no effect, +#endif +#define __USE_FILE_OFFSET64 // but that is harmless on Windows and on POSIX + // 64-bit systems or on 32-bit systems which don't have files larger + // than can be represented by a traditional POSIX/UNIX off_t type. + // OTOH, defining them should kick in 64-bit off_t's (and thus + // st_size) on 32-bit systems that provide the Large File + // Support (LFS) interface, such as Linux, Solaris, and IRIX. + // The defines are given before any headers are included to + // ensure that they are available to all included headers. + // That is required at least on Solaris, and possibly on other + // systems as well. + +// for some compilers (CodeWarrior, for example), windows.h +// is getting included by some other boost header, so do this early: +#if !defined(_WIN32_WINNT) +#define _WIN32_WINNT 0x0500 // Default to Windows 2K or later +#endif + + +#include <boost/filesystem/operations.hpp> +//#include <boost/scoped_array.hpp> +//#include <boost/throw_exception.hpp> +//#include <boost/detail/workaround.hpp> + +namespace fs = boost::filesystem; +using boost::system::error_code; +using boost::system::system_category; + +# if defined(BOOST_WINDOWS_API) +# include <windows.h> +# if defined(__BORLANDC__) || defined(__MWERKS__) +# if defined(__BORLANDC__) + using std::time_t; +# endif +# include <utime.h> +# else +# include <sys/utime.h> +# endif + +# else // BOOST_POSIX_API +# include <sys/types.h> +# if !defined(__APPLE__) && !defined(__OpenBSD__) +# include <sys/statvfs.h> +# define BOOST_STATVFS statvfs +# define BOOST_STATVFS_F_FRSIZE vfs.f_frsize +# else +#ifdef __OpenBSD__ +# include <sys/param.h> +#endif +# include <sys/mount.h> +# define BOOST_STATVFS statfs +# define BOOST_STATVFS_F_FRSIZE static_cast<boost::uintmax_t>( vfs.f_bsize ) +# endif +# include <dirent.h> +# include <unistd.h> +# include <fcntl.h> +# include <utime.h> +# include "limits.h" +# endif + +// BOOST_FILESYSTEM_STATUS_CACHE enables file_status cache in +// dir_itr_increment. The config tests are placed here because some of the +// macros being tested come from dirent.h. +// +// TODO: find out what macros indicate dirent::d_type present in more libraries +# if defined(BOOST_WINDOWS_API) \ + || defined(_DIRENT_HAVE_D_TYPE) // defined by GNU C library if d_type present +# define BOOST_FILESYSTEM_STATUS_CACHE +# endif + +#include <sys/stat.h> // even on Windows some functions use stat() +#include <string> +#include <cstring> +#include <cstdio> // for remove, rename +#include <cerrno> +#include <cassert> +// #include <iostream> // for debugging only; comment out when not in use + +#ifdef BOOST_NO_STDC_NAMESPACE +namespace std { using ::strcmp; using ::remove; using ::rename; } +#endif + +// helpers -----------------------------------------------------------------// + +namespace +{ + const error_code ok; + + bool is_empty_directory( const std::string & dir_path ) + { + static const fs::directory_iterator end_itr; + return fs::directory_iterator(fs::path(dir_path)) == end_itr; + } + +#ifdef BOOST_WINDOWS_API + +// For Windows, the xxxA form of various function names is used to avoid +// inadvertently getting wide forms of the functions. (The undecorated +// forms are actually macros, so can misfire if the user has various +// other macros defined. There was a bug report of this happening.) + + inline DWORD get_file_attributes( const char * ph ) + { return ::GetFileAttributesA( ph ); } + +# ifndef BOOST_FILESYSTEM_NARROW_ONLY + + inline DWORD get_file_attributes( const wchar_t * ph ) + { return ::GetFileAttributesW( ph ); } + + bool is_empty_directory( const std::wstring & dir_path ) + { + static const fs::wdirectory_iterator wend_itr; + return fs::wdirectory_iterator(fs::wpath(dir_path)) == wend_itr; + } + + inline BOOL get_file_attributes_ex( const wchar_t * ph, + WIN32_FILE_ATTRIBUTE_DATA & fad ) + { return ::GetFileAttributesExW( ph, ::GetFileExInfoStandard, &fad ); } + + HANDLE create_file( const wchar_t * ph, DWORD dwDesiredAccess, + DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, + DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, + HANDLE hTemplateFile ) + { + return ::CreateFileW( ph, dwDesiredAccess, dwShareMode, + lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, + hTemplateFile ); + } + + inline DWORD get_current_directory( DWORD sz, wchar_t * buf ) + { return ::GetCurrentDirectoryW( sz, buf ); } + + inline bool set_current_directory( const wchar_t * buf ) + { return ::SetCurrentDirectoryW( buf ) != 0 ; } + + inline bool get_free_disk_space( const std::wstring & ph, + PULARGE_INTEGER avail, PULARGE_INTEGER total, PULARGE_INTEGER free ) + { return ::GetDiskFreeSpaceExW( ph.c_str(), avail, total, free ) != 0; } + + inline std::size_t get_full_path_name( + const std::wstring & ph, std::size_t len, wchar_t * buf, wchar_t ** p ) + { + return static_cast<std::size_t>( + ::GetFullPathNameW( ph.c_str(), + static_cast<DWORD>(len), buf, p )); + } + + inline bool remove_directory( const std::wstring & ph ) + { return ::RemoveDirectoryW( ph.c_str() ) != 0; } + + inline bool delete_file( const std::wstring & ph ) + { return ::DeleteFileW( ph.c_str() ) != 0; } + + inline bool create_directory( const std::wstring & dir ) + { return ::CreateDirectoryW( dir.c_str(), 0 ) != 0; } + +#if _WIN32_WINNT >= 0x500 + inline bool create_hard_link( const std::wstring & to_ph, + const std::wstring & from_ph ) + { return ::CreateHardLinkW( from_ph.c_str(), to_ph.c_str(), 0 ) != 0; } +#endif + +# endif // ifndef BOOST_FILESYSTEM_NARROW_ONLY + + template< class String > + fs::file_status status_template( const String & ph, error_code & ec ) + { + DWORD attr( get_file_attributes( ph.c_str() ) ); + if ( attr == 0xFFFFFFFF ) + { + ec = error_code( ::GetLastError(), system_category ); + if ((ec.value() == ERROR_FILE_NOT_FOUND) + || (ec.value() == ERROR_PATH_NOT_FOUND) + || (ec.value() == ERROR_INVALID_NAME) // "tools/jam/src/:sys:stat.h", "//foo" + || (ec.value() == ERROR_INVALID_PARAMETER) // ":sys:stat.h" + || (ec.value() == ERROR_BAD_PATHNAME) // "//nosuch" on Win64 + || (ec.value() == ERROR_BAD_NETPATH)) // "//nosuch" on Win32 + { + ec = ok; // these are not considered errors; + // the status is considered not found + return fs::file_status( fs::file_not_found ); + } + else if ((ec.value() == ERROR_SHARING_VIOLATION)) + { + ec = ok; // these are not considered errors; + // the file exists but the type is not known + return fs::file_status( fs::type_unknown ); + } + return fs::file_status( fs::status_unknown ); + } + ec = ok;; + return (attr & FILE_ATTRIBUTE_DIRECTORY) + ? fs::file_status( fs::directory_file ) + : fs::file_status( fs::regular_file ); + } + + BOOL get_file_attributes_ex( const char * ph, + WIN32_FILE_ATTRIBUTE_DATA & fad ) + { return ::GetFileAttributesExA( ph, ::GetFileExInfoStandard, &fad ); } + + template< class String > + boost::filesystem::detail::query_pair + is_empty_template( const String & ph ) + { + WIN32_FILE_ATTRIBUTE_DATA fad; + if ( get_file_attributes_ex( ph.c_str(), fad ) == 0 ) + return std::make_pair( error_code( ::GetLastError(), system_category ), false ); + return std::make_pair( ok, + ( fad.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) + ? is_empty_directory( ph ) + :( !fad.nFileSizeHigh && !fad.nFileSizeLow ) ); + } + + HANDLE create_file( const char * ph, DWORD dwDesiredAccess, + DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, + DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, + HANDLE hTemplateFile ) + { + return ::CreateFileA( ph, dwDesiredAccess, dwShareMode, + lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, + hTemplateFile ); + } + + // Thanks to Jeremy Maitin-Shepard for much help and for permission to + // base the equivalent() implementation on portions of his + // file-equivalence-win32.cpp experimental code. + struct handle_wrapper + { + HANDLE handle; + handle_wrapper( HANDLE h ) + : handle(h) {} + ~handle_wrapper() + { + if ( handle != INVALID_HANDLE_VALUE ) + ::CloseHandle(handle); + } + }; + + template< class String > + boost::filesystem::detail::query_pair + equivalent_template( const String & ph1, const String & ph2 ) + { + // Note well: Physical location on external media is part of the + // equivalence criteria. If there are no open handles, physical location + // can change due to defragmentation or other relocations. Thus handles + // must be held open until location information for both paths has + // been retrieved. + handle_wrapper p1( + create_file( + ph1.c_str(), + 0, + FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, + 0, + OPEN_EXISTING, + FILE_FLAG_BACKUP_SEMANTICS, + 0 ) ); + int error1(0); // save error code in case we have to throw + if ( p1.handle == INVALID_HANDLE_VALUE ) + error1 = ::GetLastError(); + handle_wrapper p2( + create_file( + ph2.c_str(), + 0, + FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, + 0, + OPEN_EXISTING, + FILE_FLAG_BACKUP_SEMANTICS, + 0 ) ); + if ( p1.handle == INVALID_HANDLE_VALUE + || p2.handle == INVALID_HANDLE_VALUE ) + { + if ( p1.handle != INVALID_HANDLE_VALUE + || p2.handle != INVALID_HANDLE_VALUE ) + { return std::make_pair( ok, false ); } + assert( p1.handle == INVALID_HANDLE_VALUE + && p2.handle == INVALID_HANDLE_VALUE ); + { return std::make_pair( error_code( error1, system_category), false ); } + } + // at this point, both handles are known to be valid + BY_HANDLE_FILE_INFORMATION info1, info2; + if ( !::GetFileInformationByHandle( p1.handle, &info1 ) ) + { return std::make_pair( error_code( ::GetLastError(), system_category ), false ); } + if ( !::GetFileInformationByHandle( p2.handle, &info2 ) ) + { return std::make_pair( error_code( ::GetLastError(), system_category ), false ); } + // In theory, volume serial numbers are sufficient to distinguish between + // devices, but in practice VSN's are sometimes duplicated, so last write + // time and file size are also checked. + return std::make_pair( ok, + info1.dwVolumeSerialNumber == info2.dwVolumeSerialNumber + && info1.nFileIndexHigh == info2.nFileIndexHigh + && info1.nFileIndexLow == info2.nFileIndexLow + && info1.nFileSizeHigh == info2.nFileSizeHigh + && info1.nFileSizeLow == info2.nFileSizeLow + && info1.ftLastWriteTime.dwLowDateTime + == info2.ftLastWriteTime.dwLowDateTime + && info1.ftLastWriteTime.dwHighDateTime + == info2.ftLastWriteTime.dwHighDateTime ); + } + + template< class String > + boost::filesystem::detail::uintmax_pair + file_size_template( const String & ph ) + { + WIN32_FILE_ATTRIBUTE_DATA fad; + // by now, intmax_t is 64-bits on all Windows compilers + if ( get_file_attributes_ex( ph.c_str(), fad ) == 0 ) + return std::make_pair( error_code( ::GetLastError(), system_category ), 0 ); + if ( (fad.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) !=0 ) + return std::make_pair( error_code( ERROR_FILE_NOT_FOUND, system_category), 0 ); + return std::make_pair( ok, + (static_cast<boost::uintmax_t>(fad.nFileSizeHigh) + << (sizeof(fad.nFileSizeLow)*8)) + + fad.nFileSizeLow ); + } + + inline bool get_free_disk_space( const std::string & ph, + PULARGE_INTEGER avail, PULARGE_INTEGER total, PULARGE_INTEGER free ) + { return ::GetDiskFreeSpaceExA( ph.c_str(), avail, total, free ) != 0; } + + template< class String > + boost::filesystem::detail::space_pair + space_template( String & ph ) + { + ULARGE_INTEGER avail, total, free; + boost::filesystem::detail::space_pair result; + if ( get_free_disk_space( ph, &avail, &total, &free ) ) + { + result.first = ok; + result.second.capacity + = (static_cast<boost::uintmax_t>(total.HighPart) << 32) + + total.LowPart; + result.second.free + = (static_cast<boost::uintmax_t>(free.HighPart) << 32) + + free.LowPart; + result.second.available + = (static_cast<boost::uintmax_t>(avail.HighPart) << 32) + + avail.LowPart; + } + else + { + result.first = error_code( ::GetLastError(), system_category ); + result.second.capacity = result.second.free + = result.second.available = 0; + } + return result; + } + + inline DWORD get_current_directory( DWORD sz, char * buf ) + { return ::GetCurrentDirectoryA( sz, buf ); } + + template< class String > + error_code + get_current_path_template( String & ph ) + { + DWORD sz; + if ( (sz = get_current_directory( 0, + static_cast<typename String::value_type*>(0) )) == 0 ) + { sz = 1; } + typedef typename String::value_type value_type; + // boost::scoped_array<value_type> buf( new value_type[sz] ); + value_type* buf = new value_type[sz]; + if ( get_current_directory( sz, buf /*.get()*/ ) == 0 ) { + delete [] buf; + return error_code( ::GetLastError(), system_category ); + } + ph = buf; // buf.get(); + delete [] buf; + return ok; + } + + inline bool set_current_directory( const char * buf ) + { return ::SetCurrentDirectoryA( buf ) != 0; } + + template< class String > + error_code + set_current_path_template( const String & ph ) + { + return error_code( set_current_directory( ph.c_str() ) + ? 0 : ::GetLastError(), system_category ); + } + + inline std::size_t get_full_path_name( + const std::string & ph, std::size_t len, char * buf, char ** p ) + { + return static_cast<std::size_t>( + ::GetFullPathNameA( ph.c_str(), + static_cast<DWORD>(len), buf, p )); + } + + const std::size_t buf_size( 128 ); + + template<class String> + error_code + get_full_path_name_template( const String & ph, String & target ) + { + typename String::value_type buf[buf_size]; + typename String::value_type * pfn; + std::size_t len = get_full_path_name( ph, + buf_size , buf, &pfn ); + if ( len == 0 ) return error_code( ::GetLastError(), system_category ); + if ( len > buf_size ) + { + typedef typename String::value_type value_type; + // boost::scoped_array<value_type> big_buf( new value_type[len] ); + value_type* big_buf = new value_type[len]; + if ( (len=get_full_path_name( ph, len , big_buf/*.get()*/, &pfn )) == 0 ) { + delete [] big_buf; + return error_code( ::GetLastError(), system_category ); + } + big_buf[len] = '\0'; + target = big_buf; // big_buf.get(); + delete [] big_buf; + return ok; + } + buf[len] = '\0'; + target = buf; + return ok; + } + + template<class String> + error_code + get_file_write_time( const String & ph, FILETIME & last_write_time ) + { + handle_wrapper hw( + create_file( ph.c_str(), 0, + FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, 0, + OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 ) ); + if ( hw.handle == INVALID_HANDLE_VALUE ) + return error_code( ::GetLastError(), system_category ); + return error_code( ::GetFileTime( hw.handle, 0, 0, &last_write_time ) != 0 + ? 0 : ::GetLastError(), system_category ); + } + + template<class String> + error_code + set_file_write_time( const String & ph, const FILETIME & last_write_time ) + { + handle_wrapper hw( + create_file( ph.c_str(), FILE_WRITE_ATTRIBUTES, + FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, 0, + OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 ) ); + if ( hw.handle == INVALID_HANDLE_VALUE ) + return error_code( ::GetLastError(), system_category ); + return error_code( ::SetFileTime( hw.handle, 0, 0, &last_write_time ) != 0 + ? 0 : ::GetLastError(), system_category ); + } + + // these constants come from inspecting some Microsoft sample code + std::time_t to_time_t( const FILETIME & ft ) + { + __int64 t = (static_cast<__int64>( ft.dwHighDateTime ) << 32) + + ft.dwLowDateTime; +# if !defined( BOOST_MSVC ) || BOOST_MSVC > 1300 // > VC++ 7.0 + t -= 116444736000000000LL; +# else + t -= 116444736000000000; +# endif + t /= 10000000; + return static_cast<std::time_t>( t ); + } + + void to_FILETIME( std::time_t t, FILETIME & ft ) + { + __int64 temp = t; + temp *= 10000000; +# if !defined( BOOST_MSVC ) || BOOST_MSVC > 1300 // > VC++ 7.0 + temp += 116444736000000000LL; +# else + temp += 116444736000000000; +# endif + ft.dwLowDateTime = static_cast<DWORD>( temp ); + ft.dwHighDateTime = static_cast<DWORD>( temp >> 32 ); + } + + template<class String> + boost::filesystem::detail::time_pair + last_write_time_template( const String & ph ) + { + FILETIME lwt; + error_code ec( + get_file_write_time( ph, lwt ) ); + return std::make_pair( ec, to_time_t( lwt ) ); + } + + template<class String> + error_code + last_write_time_template( const String & ph, const std::time_t new_time ) + { + FILETIME lwt; + to_FILETIME( new_time, lwt ); + return set_file_write_time( ph, lwt ); + } + + bool remove_directory( const std::string & ph ) + { return ::RemoveDirectoryA( ph.c_str() ) != 0; } + + bool delete_file( const std::string & ph ) + { return ::DeleteFileA( ph.c_str() ) != 0; } + + template<class String> + error_code + remove_template( const String & ph ) + { + // TODO: test this code in the presence of Vista symlinks, + // including dangling, self-referal, and cyclic symlinks + error_code ec; + fs::file_status sf( fs::detail::status_api( ph, ec ) ); + if ( ec ) + return ec; + if ( sf.type() == fs::file_not_found ) + return ok; + if ( fs::is_directory( sf ) ) + { + if ( !remove_directory( ph ) ) + return error_code(::GetLastError(), system_category); + } + else + { + if ( !delete_file( ph ) ) return error_code(::GetLastError(), system_category); + } + return ok; + } + + inline bool create_directory( const std::string & dir ) + { return ::CreateDirectoryA( dir.c_str(), 0 ) != 0; } + + template<class String> + boost::filesystem::detail::query_pair + create_directory_template( const String & dir_ph ) + { + error_code error, dummy; + if ( create_directory( dir_ph ) ) return std::make_pair( error, true ); + error = error_code( ::GetLastError(), system_category ); + // an error here may simply mean the postcondition is already met + if ( error.value() == ERROR_ALREADY_EXISTS + && fs::is_directory( fs::detail::status_api( dir_ph, dummy ) ) ) + return std::make_pair( ok, false ); + return std::make_pair( error, false ); + } + +#if _WIN32_WINNT >= 0x500 + inline bool create_hard_link( const std::string & to_ph, + const std::string & from_ph ) + { return ::CreateHardLinkA( from_ph.c_str(), to_ph.c_str(), 0 ) != 0; } +#endif + +#if _WIN32_WINNT >= 0x500 + template<class String> + error_code + create_hard_link_template( const String & to_ph, + const String & from_ph ) + { + return error_code( create_hard_link( to_ph.c_str(), from_ph.c_str() ) + ? 0 : ::GetLastError(), system_category ); + } +#endif + +#else // BOOST_POSIX_API + + int posix_remove( const char * p ) + { +# if defined(__QNXNTO__) || (defined(__MSL__) && (defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__))) + // Some Metrowerks C library versions fail on directories because of a + // known Metrowerks coding error in ::remove. Workaround is to call + // rmdir() or unlink() as indicated. + // Same bug also reported for QNX, with the same fix. + int err = ::unlink( p ); + if ( err == 0 || errno != EPERM ) + return err; + return ::rmdir( p ); +# else + return std::remove( p ); +# endif + } + +#endif +} // unnamed namespace + +namespace boost +{ + namespace filesystem + { + namespace detail + { + BOOST_FILESYSTEM_DECL system::error_code throws; + +// free functions ----------------------------------------------------------// + + BOOST_FILESYSTEM_DECL error_code not_found_error() + { +# ifdef BOOST_WINDOWS_API + return error_code(ERROR_PATH_NOT_FOUND, system_category); +# else + return error_code(ENOENT, system_category); +# endif + } + + BOOST_FILESYSTEM_DECL bool possible_large_file_size_support() + { +# ifdef BOOST_POSIX_API + struct stat lcl_stat; + return sizeof( lcl_stat.st_size ) > 4; +# else + return true; +# endif + } + +# ifdef BOOST_WINDOWS_API + + BOOST_FILESYSTEM_DECL fs::file_status + status_api( const std::string & ph, error_code & ec ) + { return status_template( ph, ec ); } + +# ifndef BOOST_FILESYSTEM_NARROW_ONLY + + BOOST_FILESYSTEM_DECL fs::file_status + status_api( const std::wstring & ph, error_code & ec ) + { return status_template( ph, ec ); } + + BOOST_FILESYSTEM_DECL bool symbolic_link_exists_api( const std::wstring & ) + { return false; } + + BOOST_FILESYSTEM_DECL + fs::detail::query_pair is_empty_api( const std::wstring & ph ) + { return is_empty_template( ph ); } + + BOOST_FILESYSTEM_DECL + fs::detail::query_pair + equivalent_api( const std::wstring & ph1, const std::wstring & ph2 ) + { return equivalent_template( ph1, ph2 ); } + + BOOST_FILESYSTEM_DECL + fs::detail::uintmax_pair file_size_api( const std::wstring & ph ) + { return file_size_template( ph ); } + + BOOST_FILESYSTEM_DECL + fs::detail::space_pair space_api( const std::wstring & ph ) + { return space_template( ph ); } + + BOOST_FILESYSTEM_DECL + error_code + get_current_path_api( std::wstring & ph ) + { return get_current_path_template( ph ); } + + BOOST_FILESYSTEM_DECL + error_code + set_current_path_api( const std::wstring & ph ) + { return set_current_path_template( ph ); } + + BOOST_FILESYSTEM_DECL error_code + get_full_path_name_api( const std::wstring & ph, std::wstring & target ) + { return get_full_path_name_template( ph, target ); } + + BOOST_FILESYSTEM_DECL time_pair + last_write_time_api( const std::wstring & ph ) + { return last_write_time_template( ph ); } + + BOOST_FILESYSTEM_DECL error_code + last_write_time_api( const std::wstring & ph, std::time_t new_value ) + { return last_write_time_template( ph, new_value ); } + + BOOST_FILESYSTEM_DECL fs::detail::query_pair + create_directory_api( const std::wstring & ph ) + { return create_directory_template( ph ); } + +#if _WIN32_WINNT >= 0x500 + BOOST_FILESYSTEM_DECL error_code + create_hard_link_api( const std::wstring & to_ph, + const std::wstring & from_ph ) + { return create_hard_link_template( to_ph, from_ph ); } +#endif + + BOOST_FILESYSTEM_DECL error_code + create_symlink_api( const std::wstring & /*to_ph*/, + const std::wstring & /*from_ph*/ ) + { return error_code( ERROR_NOT_SUPPORTED, system_category ); } + + BOOST_FILESYSTEM_DECL error_code + remove_api( const std::wstring & ph ) { return remove_template( ph ); } + + BOOST_FILESYSTEM_DECL error_code + rename_api( const std::wstring & from, const std::wstring & to ) + { + return error_code( ::MoveFileW( from.c_str(), to.c_str() ) + ? 0 : ::GetLastError(), system_category ); + } + + BOOST_FILESYSTEM_DECL error_code + copy_file_api( const std::wstring & from, const std::wstring & to ) + { + return error_code( ::CopyFileW( from.c_str(), to.c_str(), /*fail_if_exists=*/true ) + ? 0 : ::GetLastError(), system_category ); + } + + BOOST_FILESYSTEM_DECL bool create_file_api( const std::wstring & ph, + std::ios_base::openmode mode ) // true if succeeds + { + DWORD access( + ((mode & std::ios_base::in) == 0 ? 0 : GENERIC_READ) + | ((mode & std::ios_base::out) == 0 ? 0 : GENERIC_WRITE) ); + + DWORD disposition(0); // see 27.8.1.3 Table 92 + if ( (mode&~std::ios_base::binary) + == (std::ios_base::out|std::ios_base::app) ) + disposition = OPEN_ALWAYS; + else if ( (mode&~(std::ios_base::binary|std::ios_base::out)) + == std::ios_base::in ) disposition = OPEN_EXISTING; + else if ( ((mode&~(std::ios_base::binary|std::ios_base::trunc)) + == std::ios_base::out ) + || ((mode&~std::ios_base::binary) + == (std::ios_base::in|std::ios_base::out|std::ios_base::trunc)) ) + disposition = CREATE_ALWAYS; + else assert( 0 && "invalid mode argument" ); + + HANDLE handle ( ::CreateFileW( ph.c_str(), access, + FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, 0, + disposition, (mode &std::ios_base::out) != 0 + ? FILE_ATTRIBUTE_ARCHIVE : FILE_ATTRIBUTE_NORMAL, 0 ) ); + if ( handle == INVALID_HANDLE_VALUE ) return false; + ::CloseHandle( handle ); + return true; + } + + BOOST_FILESYSTEM_DECL std::string narrow_path_api( + const std::wstring & ph ) // return is empty if fails + { + std::string narrow_short_form; + std::wstring short_form; + for ( DWORD buf_sz( static_cast<DWORD>( ph.size()+1 ));; ) + { + boost::scoped_array<wchar_t> buf( new wchar_t[buf_sz] ); + DWORD sz( ::GetShortPathNameW( ph.c_str(), buf.get(), buf_sz ) ); + if ( sz == 0 ) return narrow_short_form; + if ( sz <= buf_sz ) + { + short_form += buf.get(); + break; + } + buf_sz = sz + 1; + } + // contributed by Takeshi Mouri: + int narrow_sz( ::WideCharToMultiByte( CP_ACP, 0, + short_form.c_str(), static_cast<int>(short_form.size()), 0, 0, 0, 0 ) ); + boost::scoped_array<char> narrow_buf( new char[narrow_sz] ); + ::WideCharToMultiByte( CP_ACP, 0, + short_form.c_str(), static_cast<int>(short_form.size()), + narrow_buf.get(), narrow_sz, 0, 0 ); + narrow_short_form.assign(narrow_buf.get(), narrow_sz); + + return narrow_short_form; + } + + BOOST_FILESYSTEM_DECL error_code + dir_itr_first( void *& handle, const std::wstring & dir, + std::wstring & target, file_status & sf, file_status & symlink_sf ) + { + // use a form of search Sebastian Martel reports will work with Win98 + std::wstring dirpath( dir ); + dirpath += (dirpath.empty() + || dirpath[dirpath.size()-1] != L'\\') ? L"\\*" : L"*"; + + WIN32_FIND_DATAW data; + if ( (handle = ::FindFirstFileW( dirpath.c_str(), &data )) + == INVALID_HANDLE_VALUE ) + { + handle = 0; + return error_code( ::GetLastError() == ERROR_FILE_NOT_FOUND + ? 0 : ::GetLastError(), system_category ); + } + target = data.cFileName; + if ( data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) + { sf.type( directory_file ); symlink_sf.type( directory_file ); } + else { sf.type( regular_file ); symlink_sf.type( regular_file ); } + return ok; + } + + BOOST_FILESYSTEM_DECL error_code + dir_itr_increment( void *& handle, std::wstring & target, + file_status & sf, file_status & symlink_sf ) + { + WIN32_FIND_DATAW data; + if ( ::FindNextFileW( handle, &data ) == 0 ) // fails + { + int error = ::GetLastError(); + dir_itr_close( handle ); + return error_code( error == ERROR_NO_MORE_FILES ? 0 : error, system_category ); + } + target = data.cFileName; + if ( data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) + { sf.type( directory_file ); symlink_sf.type( directory_file ); } + else { sf.type( regular_file ); symlink_sf.type( regular_file ); } + return ok; + } + +# endif // ifndef BOOST_FILESYSTEM_NARROW_ONLY + + // suggested by Walter Landry + BOOST_FILESYSTEM_DECL bool symbolic_link_exists_api( const std::string & ) + { return false; } + + BOOST_FILESYSTEM_DECL + fs::detail::query_pair is_empty_api( const std::string & ph ) + { return is_empty_template( ph ); } + + BOOST_FILESYSTEM_DECL + fs::detail::query_pair + equivalent_api( const std::string & ph1, const std::string & ph2 ) + { return equivalent_template( ph1, ph2 ); } + + BOOST_FILESYSTEM_DECL + fs::detail::uintmax_pair file_size_api( const std::string & ph ) + { return file_size_template( ph ); } + + BOOST_FILESYSTEM_DECL + fs::detail::space_pair space_api( const std::string & ph ) + { return space_template( ph ); } + + BOOST_FILESYSTEM_DECL + error_code + get_current_path_api( std::string & ph ) + { return get_current_path_template( ph ); } + + BOOST_FILESYSTEM_DECL + error_code + set_current_path_api( const std::string & ph ) + { return set_current_path_template( ph ); } + + BOOST_FILESYSTEM_DECL error_code + get_full_path_name_api( const std::string & ph, std::string & target ) + { return get_full_path_name_template( ph, target ); } + + BOOST_FILESYSTEM_DECL time_pair + last_write_time_api( const std::string & ph ) + { return last_write_time_template( ph ); } + + BOOST_FILESYSTEM_DECL error_code + last_write_time_api( const std::string & ph, std::time_t new_value ) + { return last_write_time_template( ph, new_value ); } + + BOOST_FILESYSTEM_DECL fs::detail::query_pair + create_directory_api( const std::string & ph ) + { return create_directory_template( ph ); } + +#if _WIN32_WINNT >= 0x500 + BOOST_FILESYSTEM_DECL error_code + create_hard_link_api( const std::string & to_ph, + const std::string & from_ph ) + { + return create_hard_link_template( to_ph, from_ph ); + } +#endif + + BOOST_FILESYSTEM_DECL error_code + create_symlink_api( const std::string & /*to_ph*/, + const std::string & /*from_ph*/ ) + { return error_code( ERROR_NOT_SUPPORTED, system_category ); } + + BOOST_FILESYSTEM_DECL error_code + remove_api( const std::string & ph ) { return remove_template( ph ); } + + BOOST_FILESYSTEM_DECL error_code + rename_api( const std::string & from, const std::string & to ) + { + return error_code( ::MoveFileA( from.c_str(), to.c_str() ) + ? 0 : ::GetLastError(), system_category ); + } + + BOOST_FILESYSTEM_DECL error_code + copy_file_api( const std::string & from, const std::string & to ) + { + return error_code( ::CopyFileA( from.c_str(), to.c_str(), /*fail_if_exists=*/true ) + ? 0 : ::GetLastError(), system_category ); + } + + BOOST_FILESYSTEM_DECL error_code + dir_itr_first( void *& handle, const std::string & dir, + std::string & target, file_status & sf, file_status & symlink_sf ) + // Note: an empty root directory has no "." or ".." entries, so this + // causes a ERROR_FILE_NOT_FOUND error which we do not considered an + // error. It is treated as eof instead. + { + // use a form of search Sebastian Martel reports will work with Win98 + std::string dirpath( dir ); + dirpath += (dirpath.empty() + || (dirpath[dirpath.size()-1] != '\\' + && dirpath[dirpath.size()-1] != ':')) ? "\\*" : "*"; + + WIN32_FIND_DATAA data; + if ( (handle = ::FindFirstFileA( dirpath.c_str(), &data )) + == INVALID_HANDLE_VALUE ) + { + handle = 0; + return error_code( ::GetLastError() == ERROR_FILE_NOT_FOUND + ? 0 : ::GetLastError(), system_category ); + } + target = data.cFileName; + if ( data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) + { sf.type( directory_file ); symlink_sf.type( directory_file ); } + else { sf.type( regular_file ); symlink_sf.type( regular_file ); } + return ok; + } + + BOOST_FILESYSTEM_DECL error_code + dir_itr_close( void *& handle ) + { + if ( handle != 0 ) + { + bool ok = ::FindClose( handle ) != 0; + handle = 0; + return error_code( ok ? 0 : ::GetLastError(), system_category ); + } + return ok; + } + + BOOST_FILESYSTEM_DECL error_code + dir_itr_increment( void *& handle, std::string & target, + file_status & sf, file_status & symlink_sf ) + { + WIN32_FIND_DATAA data; + if ( ::FindNextFileA( handle, &data ) == 0 ) // fails + { + int error = ::GetLastError(); + dir_itr_close( handle ); + return error_code( error == ERROR_NO_MORE_FILES ? 0 : error, system_category ); + } + target = data.cFileName; + if ( data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) + { sf.type( directory_file ); symlink_sf.type( directory_file ); } + else { sf.type( regular_file ); symlink_sf.type( regular_file ); } + return ok; + } + +# else // BOOST_POSIX_API + + BOOST_FILESYSTEM_DECL fs::file_status + status_api( const std::string & ph, error_code & ec ) + { + struct stat path_stat; + if ( ::stat( ph.c_str(), &path_stat ) != 0 ) + { + if ( errno == ENOENT || errno == ENOTDIR ) + { + ec = ok; + return fs::file_status( fs::file_not_found ); + } + ec = error_code( errno, system_category ); + return fs::file_status( fs::status_unknown ); + } + ec = ok; + if ( S_ISDIR( path_stat.st_mode ) ) + return fs::file_status( fs::directory_file ); + if ( S_ISREG( path_stat.st_mode ) ) + return fs::file_status( fs::regular_file ); + if ( S_ISBLK( path_stat.st_mode ) ) + return fs::file_status( fs::block_file ); + if ( S_ISCHR( path_stat.st_mode ) ) + return fs::file_status( fs::character_file ); + if ( S_ISFIFO( path_stat.st_mode ) ) + return fs::file_status( fs::fifo_file ); + if ( S_ISSOCK( path_stat.st_mode ) ) + return fs::file_status( fs::socket_file ); + return fs::file_status( fs::type_unknown ); + } + + BOOST_FILESYSTEM_DECL fs::file_status + symlink_status_api( const std::string & ph, error_code & ec ) + { + struct stat path_stat; + if ( ::lstat( ph.c_str(), &path_stat ) != 0 ) + { + if ( errno == ENOENT || errno == ENOTDIR ) + { + ec = ok; + return fs::file_status( fs::file_not_found ); + } + ec = error_code( errno, system_category ); + return fs::file_status( fs::status_unknown ); + } + ec = ok; + if ( S_ISREG( path_stat.st_mode ) ) + return fs::file_status( fs::regular_file ); + if ( S_ISDIR( path_stat.st_mode ) ) + return fs::file_status( fs::directory_file ); + if ( S_ISLNK( path_stat.st_mode ) ) + return fs::file_status( fs::symlink_file ); + if ( S_ISBLK( path_stat.st_mode ) ) + return fs::file_status( fs::block_file ); + if ( S_ISCHR( path_stat.st_mode ) ) + return fs::file_status( fs::character_file ); + if ( S_ISFIFO( path_stat.st_mode ) ) + return fs::file_status( fs::fifo_file ); + if ( S_ISSOCK( path_stat.st_mode ) ) + return fs::file_status( fs::socket_file ); + return fs::file_status( fs::type_unknown ); + } + + // suggested by Walter Landry + BOOST_FILESYSTEM_DECL bool + symbolic_link_exists_api( const std::string & ph ) + { + struct stat path_stat; + return ::lstat( ph.c_str(), &path_stat ) == 0 + && S_ISLNK( path_stat.st_mode ); + } + + BOOST_FILESYSTEM_DECL query_pair + is_empty_api( const std::string & ph ) + { + struct stat path_stat; + if ( (::stat( ph.c_str(), &path_stat )) != 0 ) + return std::make_pair( error_code( errno, system_category ), false ); + return std::make_pair( ok, S_ISDIR( path_stat.st_mode ) + ? is_empty_directory( ph ) + : path_stat.st_size == 0 ); + } + + BOOST_FILESYSTEM_DECL query_pair + equivalent_api( const std::string & ph1, const std::string & ph2 ) + { + struct stat s2; + int e2( ::stat( ph2.c_str(), &s2 ) ); + struct stat s1; + int e1( ::stat( ph1.c_str(), &s1 ) ); + if ( e1 != 0 || e2 != 0 ) + return std::make_pair( error_code( e1 != 0 && e2 != 0 ? errno : 0, system_category ), false ); + // at this point, both stats are known to be valid + return std::make_pair( ok, + s1.st_dev == s2.st_dev + && s1.st_ino == s2.st_ino + // According to the POSIX stat specs, "The st_ino and st_dev fields + // taken together uniquely identify the file within the system." + // Just to be sure, size and mod time are also checked. + && s1.st_size == s2.st_size + && s1.st_mtime == s2.st_mtime ); + } + + BOOST_FILESYSTEM_DECL uintmax_pair + file_size_api( const std::string & ph ) + { + struct stat path_stat; + if ( ::stat( ph.c_str(), &path_stat ) != 0 ) + return std::make_pair( error_code( errno, system_category ), 0 ); + if ( !S_ISREG( path_stat.st_mode ) ) + return std::make_pair( error_code( EPERM, system_category ), 0 ); + return std::make_pair( ok, + static_cast<boost::uintmax_t>(path_stat.st_size) ); + } + + BOOST_FILESYSTEM_DECL space_pair + space_api( const std::string & ph ) + { + struct BOOST_STATVFS vfs; + space_pair result; + if ( ::BOOST_STATVFS( ph.c_str(), &vfs ) != 0 ) + { + result.first = error_code( errno, system_category ); + result.second.capacity = result.second.free + = result.second.available = 0; + } + else + { + result.first = ok; + result.second.capacity + = static_cast<boost::uintmax_t>(vfs.f_blocks) * BOOST_STATVFS_F_FRSIZE; + result.second.free + = static_cast<boost::uintmax_t>(vfs.f_bfree) * BOOST_STATVFS_F_FRSIZE; + result.second.available + = static_cast<boost::uintmax_t>(vfs.f_bavail) * BOOST_STATVFS_F_FRSIZE; + } + return result; + } + + BOOST_FILESYSTEM_DECL time_pair + last_write_time_api( const std::string & ph ) + { + struct stat path_stat; + if ( ::stat( ph.c_str(), &path_stat ) != 0 ) + return std::make_pair( error_code( errno, system_category ), 0 ); + return std::make_pair( ok, path_stat.st_mtime ); + } + + BOOST_FILESYSTEM_DECL error_code + last_write_time_api( const std::string & ph, std::time_t new_value ) + { + struct stat path_stat; + if ( ::stat( ph.c_str(), &path_stat ) != 0 ) + return error_code( errno, system_category ); + ::utimbuf buf; + buf.actime = path_stat.st_atime; // utime() updates access time too:-( + buf.modtime = new_value; + return error_code( ::utime( ph.c_str(), &buf ) != 0 ? errno : 0, system_category ); + } + + BOOST_FILESYSTEM_DECL error_code + get_current_path_api( std::string & ph ) + { + for ( long path_max = 32;; path_max *=2 ) // loop 'til buffer large enough + { + // boost::scoped_array<char> + char* buf = new char[static_cast<std::size_t>(path_max)]; + if ( ::getcwd( buf, static_cast<std::size_t>(path_max) ) == 0 ) + { + if ( errno != ERANGE + // bug in some versions of the Metrowerks C lib on the Mac: wrong errno set +# if defined(__MSL__) && (defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)) + && errno != 0 +# endif + ) + { + delete [] buf; + return error_code( errno, system_category ); + } + } + else + { + delete [] buf; + ph = buf; + break; + } + delete [] buf; + } + return ok; + } + + BOOST_FILESYSTEM_DECL error_code + set_current_path_api( const std::string & ph ) + { + return error_code( ::chdir( ph.c_str() ) + ? errno : 0, system_category ); + } + + BOOST_FILESYSTEM_DECL fs::detail::query_pair + create_directory_api( const std::string & ph ) + { + if ( ::mkdir( ph.c_str(), S_IRWXU|S_IRWXG|S_IRWXO ) == 0 ) + { return std::make_pair( ok, true ); } + int ec=errno; + error_code dummy; + if ( ec != EEXIST + || !fs::is_directory( status_api( ph, dummy ) ) ) + { return std::make_pair( error_code( ec, system_category ), false ); } + return std::make_pair( ok, false ); + } + + BOOST_FILESYSTEM_DECL error_code + create_hard_link_api( const std::string & to_ph, + const std::string & from_ph ) + { + return error_code( ::link( to_ph.c_str(), from_ph.c_str() ) == 0 + ? 0 : errno, system_category ); + } + + BOOST_FILESYSTEM_DECL error_code + create_symlink_api( const std::string & to_ph, + const std::string & from_ph ) + { + return error_code( ::symlink( to_ph.c_str(), from_ph.c_str() ) == 0 + ? 0 : errno, system_category ); + } + + BOOST_FILESYSTEM_DECL error_code + remove_api( const std::string & ph ) + { + if ( posix_remove( ph.c_str() ) == 0 ) + return ok; + int error = errno; + // POSIX says "If the directory is not an empty directory, rmdir() + // shall fail and set errno to EEXIST or ENOTEMPTY." + // Linux uses ENOTEMPTY, Solaris uses EEXIST. + if ( error == EEXIST ) error = ENOTEMPTY; + + error_code ec; + + // ignore errors if post-condition satisfied + return status_api(ph, ec).type() == file_not_found + ? ok : error_code( error, system_category ) ; + } + + BOOST_FILESYSTEM_DECL error_code + rename_api( const std::string & from, const std::string & to ) + { + // POSIX is too permissive so must check + error_code dummy; + if ( fs::exists( status_api( to, dummy ) ) ) + return error_code( EEXIST, system_category ); + return error_code( std::rename( from.c_str(), to.c_str() ) != 0 + ? errno : 0, system_category ); + } + + BOOST_FILESYSTEM_DECL error_code + copy_file_api( const std::string & from_file_ph, + const std::string & to_file_ph ) + { + const std::size_t buf_sz = 32768; + //boost::scoped_array<char> buf( new char [buf_sz] ); + char* buf = new char[buf_sz]; + int infile=-1, outfile=-1; // -1 means not open + struct stat from_stat; + + if ( ::stat( from_file_ph.c_str(), &from_stat ) != 0 + || (infile = ::open( from_file_ph.c_str(), + O_RDONLY )) < 0 + || (outfile = ::open( to_file_ph.c_str(), + O_WRONLY | O_CREAT | O_EXCL, + from_stat.st_mode )) < 0 ) + { + if ( infile >= 0 ) ::close( infile ); + delete [] buf; + return error_code( errno, system_category ); + } + + ssize_t sz, sz_read=1, sz_write; + while ( sz_read > 0 + && (sz_read = ::read( infile, buf, buf_sz )) > 0 ) + { + // Allow for partial writes - see Advanced Unix Programming (2nd Ed.), + // Marc Rochkind, Addison-Wesley, 2004, page 94 + sz_write = 0; + do + { + if ( (sz = ::write( outfile, buf + sz_write, + sz_read - sz_write )) < 0 ) + { + sz_read = sz; // cause read loop termination + break; // and error to be thrown after closes + } + sz_write += sz; + } while ( sz_write < sz_read ); + } + + if ( ::close( infile) < 0 ) sz_read = -1; + if ( ::close( outfile) < 0 ) sz_read = -1; + delete [] buf; + + return error_code( sz_read < 0 ? errno : 0, system_category ); + } + + // this code is based on Stevens and Rago, Advanced Programming in the + // UNIX envirnment, 2nd Ed., ISBN 0-201-43307-9, page 49 + error_code path_max( std::size_t & result ) + { +# ifdef PATH_MAX + static std::size_t max = PATH_MAX; +# else + static std::size_t max = 0; +# endif + if ( max == 0 ) + { + errno = 0; + long tmp = ::pathconf( "/", _PC_NAME_MAX ); + if ( tmp < 0 ) + { + if ( errno == 0 ) // indeterminate + max = 4096; // guess + else return error_code( errno, system_category ); + } + else max = static_cast<std::size_t>( tmp + 1 ); // relative root + } + result = max; + return ok; + } + + BOOST_FILESYSTEM_DECL error_code + dir_itr_first( void *& handle, void *& buffer, + const std::string & dir, std::string & target, + file_status &, file_status & ) + { + if ( (handle = ::opendir( dir.c_str() )) == 0 ) + return error_code( errno, system_category ); + target = std::string( "." ); // string was static but caused trouble + // when iteration called from dtor, after + // static had already been destroyed + std::size_t path_size; + error_code ec = path_max( path_size ); + if ( ec ) return ec; + dirent de; + buffer = std::malloc( (sizeof(dirent) - sizeof(de.d_name)) + + path_size + 1 ); // + 1 for "/0" + return ok; + } + + BOOST_FILESYSTEM_DECL error_code + dir_itr_close( void *& handle, void*& buffer ) + { + std::free( buffer ); + buffer = 0; + if ( handle == 0 ) return ok; + DIR * h( static_cast<DIR*>(handle) ); + handle = 0; + return error_code( ::closedir( h ) == 0 ? 0 : errno, system_category ); + } + + // warning: the only dirent member updated is d_name + inline int readdir_r_simulator( DIR * dirp, struct dirent * entry, + struct dirent ** result ) // *result set to 0 on end of directory + { + errno = 0; + + # if !defined(__CYGWIN__) \ + && defined(_POSIX_THREAD_SAFE_FUNCTIONS) \ + && defined(_SC_THREAD_SAFE_FUNCTIONS) \ + && (_POSIX_THREAD_SAFE_FUNCTIONS+0 >= 0) \ + && (!defined(__hpux) || (defined(__hpux) && defined(_REENTRANT))) + if ( ::sysconf( _SC_THREAD_SAFE_FUNCTIONS ) >= 0 ) + { return ::readdir_r( dirp, entry, result ); } + # endif + + struct dirent * p; + *result = 0; + if ( (p = ::readdir( dirp )) == 0 ) + return errno; + std::strcpy( entry->d_name, p->d_name ); + *result = entry; + return 0; + } + + BOOST_FILESYSTEM_DECL error_code + dir_itr_increment( void *& handle, void *& buffer, + std::string & target, file_status & sf, file_status & symlink_sf ) + { + assert( buffer != 0 ); + dirent * entry( static_cast<dirent *>(buffer) ); + dirent * result; + int return_code; + if ( (return_code = readdir_r_simulator( static_cast<DIR*>(handle), + entry, &result )) != 0 ) return error_code( errno, system_category ); + if ( result == 0 ) return dir_itr_close( handle, buffer ); + target = entry->d_name; +# ifdef BOOST_FILESYSTEM_STATUS_CACHE + if ( entry->d_type == DT_UNKNOWN ) // filesystem does not supply d_type value + { + sf = symlink_sf = fs::file_status(fs::status_unknown); + } + else // filesystem supplies d_type value + { + if ( entry->d_type == DT_DIR ) + sf = symlink_sf = fs::file_status( fs::directory_file ); + else if ( entry->d_type == DT_REG ) + sf = symlink_sf = fs::file_status( fs::regular_file ); + else if ( entry->d_type == DT_LNK ) + { + sf = fs::file_status( fs::status_unknown ); + symlink_sf = fs::file_status( fs::symlink_file ); + } + else sf = symlink_sf = fs::file_status( fs::status_unknown ); + } +# else + sf = symlink_sf = fs::file_status( fs::status_unknown ); +# endif + return ok; + } + +# endif + } // namespace detail + } // namespace filesystem +} // namespace boost diff --git a/ThirdParty/NRLib/boost/filesystem/operations.hpp b/ThirdParty/NRLib/boost/filesystem/operations.hpp new file mode 100644 index 0000000000..c5f0f51c99 --- /dev/null +++ b/ThirdParty/NRLib/boost/filesystem/operations.hpp @@ -0,0 +1,1211 @@ +// boost/filesystem/operations.hpp -----------------------------------------// + +// Copyright 2002-2005 Beman Dawes +// Copyright 2002 Jan Langer +// Copyright 2001 Dietmar Kuehl +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See library home page at http://www.boost.org/libs/filesystem + +//----------------------------------------------------------------------------// + +#ifndef BOOST_FILESYSTEM_OPERATIONS_HPP +#define BOOST_FILESYSTEM_OPERATIONS_HPP + +#include <boost/filesystem/path.hpp> + +//#include <boost/shared_ptr.hpp> +#include <memory> + +//#include <boost/utility/enable_if.hpp> +//#include <boost/type_traits/is_same.hpp> +//#include <boost/iterator.hpp> +//#include <boost/cstdint.hpp> +//#include <boost/assert.hpp> +#include <cassert> + +#include <string> +#include <utility> // for pair +#include <ctime> + +#ifdef BOOST_WINDOWS_API +# include <fstream> +# if !defined(_WIN32_WINNT) || _WIN32_WINNT >= 0x0500 +# define BOOST_FS_HARD_LINK // Default for Windows 2K or later +# endif +#endif + +// #include <boost/config/abi_prefix.hpp> // must be the last #include + +# ifdef BOOST_NO_STDC_NAMESPACE + namespace std { using ::time_t; } +# endif + +# ifndef BOOST_FILESYSTEM_NARROW_ONLY +# define BOOST_FS_FUNC(BOOST_FS_TYPE) \ + template<class Path> typename boost::enable_if<is_basic_path<Path>, \ + BOOST_FS_TYPE>::type +# define BOOST_INLINE_FS_FUNC(BOOST_FS_TYPE) \ + template<class Path> inline typename boost::enable_if<is_basic_path<Path>, \ + BOOST_FS_TYPE>::type +# define BOOST_FS_TYPENAME typename +# else +# define BOOST_FS_FUNC(BOOST_FS_TYPE) inline BOOST_FS_TYPE +# define BOOST_INLINE_FS_FUNC(BOOST_FS_TYPE) inline BOOST_FS_TYPE + typedef boost::filesystem::path Path; +# define BOOST_FS_TYPENAME +# endif + +//----------------------------------------------------------------------------// + +namespace boost +{ + typedef unsigned long long uintmax_t; + + namespace filesystem + { + template<class Path> class basic_directory_iterator; + + // BOOST_FILESYSTEM_NARROW_ONLY needs this: + typedef basic_directory_iterator<path> directory_iterator; + + template<class Path> class basic_directory_entry; + + enum file_type + { + status_unknown, + file_not_found, + regular_file, + directory_file, + // the following will never be reported by some operating or file systems + symlink_file, + block_file, + character_file, + fifo_file, + socket_file, + type_unknown // file does exist, but isn't one of the above types or + // we don't have strong enough permission to find its type + }; + + class file_status + { + public: + explicit file_status( file_type v = status_unknown ) : m_value(v) {} + + void type( file_type v ) { m_value = v; } + file_type type() const { return m_value; } + + private: + // the internal representation is unspecified so that additional state + // information such as permissions can be added in the future; this + // implementation just uses status_type as the internal representation + + file_type m_value; + }; + + inline bool status_known( file_status f ) { return f.type() != status_unknown; } + inline bool exists( file_status f ) { return f.type() != status_unknown && f.type() != file_not_found; } + inline bool is_regular_file(file_status f){ return f.type() == regular_file; } + inline bool is_directory( file_status f ) { return f.type() == directory_file; } + inline bool is_symlink( file_status f ) { return f.type() == symlink_file; } + inline bool is_other( file_status f ) { return exists(f) && !is_regular_file(f) && !is_directory(f) && !is_symlink(f); } + +# ifndef BOOST_FILESYSTEM_NO_DEPRECATED + inline bool is_regular( file_status f ) { return f.type() == regular_file; } +# endif + + struct space_info + { + // all values are byte counts + boost::uintmax_t capacity; + boost::uintmax_t free; // <= capacity + boost::uintmax_t available; // <= free + }; + + namespace detail + { + typedef std::pair< system::error_code, bool > + query_pair; + + typedef std::pair< system::error_code, boost::uintmax_t > + uintmax_pair; + + typedef std::pair< system::error_code, std::time_t > + time_pair; + + typedef std::pair< system::error_code, space_info > + space_pair; + + template< class Path > + struct directory_pair + { + typedef std::pair< system::error_code, + typename Path::external_string_type > type; + }; + +# ifndef BOOST_FILESYSTEM_NO_DEPRECATED + BOOST_FILESYSTEM_DECL bool + symbolic_link_exists_api( const std::string & ); // deprecated +# endif + + BOOST_FILESYSTEM_DECL file_status + status_api( const std::string & ph, system::error_code & ec ); +# ifndef BOOST_WINDOWS_API + BOOST_FILESYSTEM_DECL file_status + symlink_status_api( const std::string & ph, system::error_code & ec ); +# endif + BOOST_FILESYSTEM_DECL query_pair + is_empty_api( const std::string & ph ); + BOOST_FILESYSTEM_DECL query_pair + equivalent_api( const std::string & ph1, const std::string & ph2 ); + BOOST_FILESYSTEM_DECL uintmax_pair + file_size_api( const std::string & ph ); + BOOST_FILESYSTEM_DECL space_pair + space_api( const std::string & ph ); + BOOST_FILESYSTEM_DECL time_pair + last_write_time_api( const std::string & ph ); + BOOST_FILESYSTEM_DECL system::error_code + last_write_time_api( const std::string & ph, std::time_t new_value ); + BOOST_FILESYSTEM_DECL system::error_code + get_current_path_api( std::string & ph ); + BOOST_FILESYSTEM_DECL system::error_code + set_current_path_api( const std::string & ph ); + BOOST_FILESYSTEM_DECL query_pair + create_directory_api( const std::string & ph ); + BOOST_FILESYSTEM_DECL system::error_code + create_hard_link_api( const std::string & to_ph, + const std::string & from_ph ); + BOOST_FILESYSTEM_DECL system::error_code + create_symlink_api( const std::string & to_ph, + const std::string & from_ph ); + BOOST_FILESYSTEM_DECL system::error_code + remove_api( const std::string & ph ); + BOOST_FILESYSTEM_DECL system::error_code + rename_api( const std::string & from, const std::string & to ); + BOOST_FILESYSTEM_DECL system::error_code + copy_file_api( const std::string & from, const std::string & to ); + +# if defined(BOOST_WINDOWS_API) + + BOOST_FILESYSTEM_DECL system::error_code + get_full_path_name_api( const std::string & ph, std::string & target ); + +# if !defined(BOOST_FILESYSTEM_NARROW_ONLY) + + BOOST_FILESYSTEM_DECL boost::filesystem::file_status + status_api( const std::wstring & ph, system::error_code & ec ); + BOOST_FILESYSTEM_DECL query_pair + is_empty_api( const std::wstring & ph ); + BOOST_FILESYSTEM_DECL query_pair + equivalent_api( const std::wstring & ph1, const std::wstring & ph2 ); + BOOST_FILESYSTEM_DECL uintmax_pair + file_size_api( const std::wstring & ph ); + BOOST_FILESYSTEM_DECL space_pair + space_api( const std::wstring & ph ); + BOOST_FILESYSTEM_DECL system::error_code + get_full_path_name_api( const std::wstring & ph, std::wstring & target ); + BOOST_FILESYSTEM_DECL time_pair + last_write_time_api( const std::wstring & ph ); + BOOST_FILESYSTEM_DECL system::error_code + last_write_time_api( const std::wstring & ph, std::time_t new_value ); + BOOST_FILESYSTEM_DECL system::error_code + get_current_path_api( std::wstring & ph ); + BOOST_FILESYSTEM_DECL system::error_code + set_current_path_api( const std::wstring & ph ); + BOOST_FILESYSTEM_DECL query_pair + create_directory_api( const std::wstring & ph ); +# ifdef BOOST_FS_HARD_LINK + BOOST_FILESYSTEM_DECL system::error_code + create_hard_link_api( const std::wstring & existing_ph, + const std::wstring & new_ph ); +# endif + BOOST_FILESYSTEM_DECL system::error_code + create_symlink_api( const std::wstring & to_ph, + const std::wstring & from_ph ); + BOOST_FILESYSTEM_DECL system::error_code + remove_api( const std::wstring & ph ); + BOOST_FILESYSTEM_DECL system::error_code + rename_api( const std::wstring & from, const std::wstring & to ); + BOOST_FILESYSTEM_DECL system::error_code + copy_file_api( const std::wstring & from, const std::wstring & to ); + +# endif +# endif + + template<class Path> + bool remove_aux( const Path & ph, file_status f ); + + template<class Path> + unsigned long remove_all_aux( const Path & ph, file_status f ); + + } // namespace detail + +// operations functions ----------------------------------------------------// + + // The non-template overloads enable automatic conversion from std and + // C-style strings. See basic_path constructors. The enable_if for the + // templates implements the famous "do-the-right-thing" rule. + +// query functions ---------------------------------------------------------// + + BOOST_INLINE_FS_FUNC(file_status) + status( const Path & ph, system::error_code & ec ) + { return detail::status_api( ph.external_file_string(), ec ); } + + BOOST_FS_FUNC(file_status) + status( const Path & ph ) + { + system::error_code ec; + file_status result( detail::status_api( ph.external_file_string(), ec ) ); + if ( ec ) + throw( basic_filesystem_error<Path>( + "boost::filesystem::status", ph, ec ) ); + return result; + } + + BOOST_INLINE_FS_FUNC(file_status) + symlink_status( const Path & ph, system::error_code & ec ) +# ifdef BOOST_WINDOWS_API + { return detail::status_api( ph.external_file_string(), ec ); } +# else + { return detail::symlink_status_api( ph.external_file_string(), ec ); } +# endif + + BOOST_FS_FUNC(file_status) + symlink_status( const Path & ph ) + { + system::error_code ec; + file_status result( symlink_status( ph, ec ) ); + if ( ec ) + throw( basic_filesystem_error<Path>( + "boost::filesystem::symlink_status", ph, ec ) ); + return result; + } + +# ifndef BOOST_FILESYSTEM_NO_DEPRECATED + inline bool symbolic_link_exists( const path & ph ) + { return is_symlink( symlink_status(ph) ); } +# endif + + BOOST_FS_FUNC(bool) exists( const Path & ph ) + { + system::error_code ec; + file_status result( detail::status_api( ph.external_file_string(), ec ) ); + if ( ec ) + throw( basic_filesystem_error<Path>( + "boost::filesystem::exists", ph, ec ) ); + return exists( result ); + } + + BOOST_FS_FUNC(bool) is_directory( const Path & ph ) + { + system::error_code ec; + file_status result( detail::status_api( ph.external_file_string(), ec ) ); + if ( ec ) + throw( basic_filesystem_error<Path>( + "boost::filesystem::is_directory", ph, ec ) ); + return is_directory( result ); + } + + BOOST_FS_FUNC(bool) is_regular_file( const Path & ph ) + { + system::error_code ec; + file_status result( detail::status_api( ph.external_file_string(), ec ) ); + if ( ec ) + throw( basic_filesystem_error<Path>( + "boost::filesystem::is_regular_file", ph, ec ) ); + return is_regular_file( result ); + } + +# ifndef BOOST_FILESYSTEM_NO_DEPRECATED + BOOST_FS_FUNC(bool) is_regular( const Path & ph ) + { + system::error_code ec; + file_status result( detail::status_api( ph.external_file_string(), ec ) ); + if ( ec ) + throw( basic_filesystem_error<Path>( + "boost::filesystem::is_regular", ph, ec ) ); + return is_regular( result ); + } +# endif + + BOOST_FS_FUNC(bool) is_other( const Path & ph ) + { + system::error_code ec; + file_status result( detail::status_api( ph.external_file_string(), ec ) ); + if ( ec ) + throw( basic_filesystem_error<Path>( + "boost::filesystem::is_other", ph, ec ) ); + return is_other( result ); + } + + BOOST_FS_FUNC(bool) is_symlink( +# ifdef BOOST_WINDOWS_API + const Path & ) + { + return false; +# else + const Path & ph) + { + system::error_code ec; + file_status result( detail::symlink_status_api( ph.external_file_string(), ec ) ); + if ( ec ) + throw( basic_filesystem_error<Path>( + "boost::filesystem::is_symlink", ph, ec ) ); + return is_symlink( result ); +# endif + } + + // VC++ 7.0 and earlier has a serious namespace bug that causes a clash + // between boost::filesystem::is_empty and the unrelated type trait + // boost::is_empty. + +# if !defined( BOOST_MSVC ) || BOOST_MSVC > 1300 + BOOST_FS_FUNC(bool) is_empty( const Path & ph ) +# else + BOOST_FS_FUNC(bool) _is_empty( const Path & ph ) +# endif + { + detail::query_pair result( + detail::is_empty_api( ph.external_file_string() ) ); + if ( result.first ) + throw( basic_filesystem_error<Path>( + "boost::filesystem::is_empty", ph, result.first ) ); + return result.second; + } + + BOOST_FS_FUNC(bool) equivalent( const Path & ph1, const Path & ph2 ) + { + detail::query_pair result( detail::equivalent_api( + ph1.external_file_string(), ph2.external_file_string() ) ); + if ( result.first ) + throw( basic_filesystem_error<Path>( + "boost::filesystem::equivalent", ph1, ph2, result.first ) ); + return result.second; + } + + BOOST_FS_FUNC(boost::uintmax_t) file_size( const Path & ph ) + { + detail::uintmax_pair result + ( detail::file_size_api( ph.external_file_string() ) ); + if ( result.first ) + throw( basic_filesystem_error<Path>( + "boost::filesystem::file_size", ph, result.first ) ); + return result.second; + } + + BOOST_FS_FUNC(space_info) space( const Path & ph ) + { + detail::space_pair result + ( detail::space_api( ph.external_file_string() ) ); + if ( result.first ) + throw( basic_filesystem_error<Path>( + "boost::filesystem::space", ph, result.first ) ); + return result.second; + } + + BOOST_FS_FUNC(std::time_t) last_write_time( const Path & ph ) + { + detail::time_pair result + ( detail::last_write_time_api( ph.external_file_string() ) ); + if ( result.first ) + throw( basic_filesystem_error<Path>( + "boost::filesystem::last_write_time", ph, result.first ) ); + return result.second; + } + + +// operations --------------------------------------------------------------// + + BOOST_FS_FUNC(bool) create_directory( const Path & dir_ph ) + { + detail::query_pair result( + detail::create_directory_api( dir_ph.external_directory_string() ) ); + if ( result.first ) + throw( basic_filesystem_error<Path>( + "boost::filesystem::create_directory", + dir_ph, result.first ) ); + return result.second; + } + +#if !defined(BOOST_WINDOWS_API) || defined(BOOST_FS_HARD_LINK) + BOOST_FS_FUNC(void) + create_hard_link( const Path & to_ph, const Path & from_ph ) + { + system::error_code ec( + detail::create_hard_link_api( + to_ph.external_file_string(), + from_ph.external_file_string() ) ); + if ( ec ) + throw( basic_filesystem_error<Path>( + "boost::filesystem::create_hard_link", + to_ph, from_ph, ec ) ); + } + + BOOST_FS_FUNC(system::error_code) + create_hard_link( const Path & to_ph, const Path & from_ph, + system::error_code & ec ) + { + ec = detail::create_hard_link_api( + to_ph.external_file_string(), + from_ph.external_file_string() ); + return ec; + } +#endif + + BOOST_FS_FUNC(void) + create_symlink( const Path & to_ph, const Path & from_ph ) + { + system::error_code ec( + detail::create_symlink_api( + to_ph.external_file_string(), + from_ph.external_file_string() ) ); + if ( ec ) + throw( basic_filesystem_error<Path>( + "boost::filesystem::create_symlink", + to_ph, from_ph, ec ) ); + } + + BOOST_FS_FUNC(system::error_code) + create_symlink( const Path & to_ph, const Path & from_ph, + system::error_code & ec ) + { + ec = detail::create_symlink_api( + to_ph.external_file_string(), + from_ph.external_file_string() ); + return ec; + } + + BOOST_FS_FUNC(bool) remove( const Path & ph ) + { + system::error_code ec; + file_status f = symlink_status( ph, ec ); + if ( ec ) + throw( basic_filesystem_error<Path>( + "boost::filesystem::remove", ph, ec ) ); + return detail::remove_aux( ph, f ); + } + + BOOST_FS_FUNC(unsigned long) remove_all( const Path & ph ) + { + system::error_code ec; + file_status f = symlink_status( ph, ec ); + if ( ec ) + throw( basic_filesystem_error<Path>( + "boost::filesystem::remove_all", ph, ec ) ); + return exists( f ) ? detail::remove_all_aux( ph, f ) : 0; + } + + BOOST_FS_FUNC(void) rename( const Path & from_path, const Path & to_path ) + { + system::error_code ec( detail::rename_api( + from_path.external_directory_string(), + to_path.external_directory_string() ) ); + if ( ec ) + throw( basic_filesystem_error<Path>( + "boost::filesystem::rename", + from_path, to_path, ec ) ); + } + + BOOST_FS_FUNC(void) copy_file( const Path & from_path, const Path & to_path ) + { + system::error_code ec( detail::copy_file_api( + from_path.external_directory_string(), + to_path.external_directory_string() ) ); + if ( ec ) + throw( basic_filesystem_error<Path>( + "boost::filesystem::copy_file", + from_path, to_path, ec ) ); + } + + template< class Path > + Path current_path() + { + typename Path::external_string_type ph; + system::error_code ec( detail::get_current_path_api( ph ) ); + if ( ec ) + throw( basic_filesystem_error<Path>( + "boost::filesystem::current_path", ec ) ); + return Path( Path::traits_type::to_internal( ph ) ); + } + + BOOST_FS_FUNC(void) current_path( const Path & ph ) + { + system::error_code ec( detail::set_current_path_api( + ph.external_directory_string() ) ); + if ( ec ) + throw( basic_filesystem_error<Path>( + "boost::filesystem::current_path", ph, ec ) ); + } + + template< class Path > + const Path & initial_path() + { + static Path init_path; + if ( init_path.empty() ) init_path = current_path<Path>(); + return init_path; + } + +# ifndef BOOST_FILESYSTEM_NO_DEPRECATED + // legacy support + inline path current_path() // overload supports pre-i18n apps + { return current_path<boost::filesystem::path>(); } + inline const path & initial_path() // overload supports pre-i18n apps + { return initial_path<boost::filesystem::path>(); } +# endif + + BOOST_FS_FUNC(Path) system_complete( const Path & ph ) + { +# ifdef BOOST_WINDOWS_API + if ( ph.empty() ) return ph; + BOOST_FS_TYPENAME Path::external_string_type sys_ph; + system::error_code ec( detail::get_full_path_name_api( ph.external_file_string(), + sys_ph ) ); + if ( ec ) + throw( basic_filesystem_error<Path>( + "boost::filesystem::system_complete", ph, ec ) ); + return Path( Path::traits_type::to_internal( sys_ph ) ); +# else + return (ph.empty() || ph.is_complete()) + ? ph : current_path<Path>() / ph; +# endif + } + + BOOST_FS_FUNC(Path) + complete( const Path & ph, + const Path & base/* = initial_path<Path>() */) + { + assert( base.is_complete() + && (ph.is_complete() || !ph.has_root_name()) ); // "boost::filesystem::complete() precondition not met" +# ifdef BOOST_WINDOWS_PATH + if (ph.empty() || ph.is_complete()) return ph; + if ( !ph.has_root_name() ) + return ph.has_root_directory() + ? Path( base.root_name() ) / ph + : base / ph; + return base / ph; +# else + return (ph.empty() || ph.is_complete()) ? ph : base / ph; +# endif + } + + // VC++ 7.1 had trouble with default arguments, so separate one argument + // signatures are provided as workarounds; the effect is the same. + BOOST_FS_FUNC(Path) complete( const Path & ph ) + { return complete( ph, initial_path<Path>() ); } + + BOOST_FS_FUNC(void) + last_write_time( const Path & ph, const std::time_t new_time ) + { + system::error_code ec( detail::last_write_time_api( ph.external_file_string(), + new_time ) ); + if ( ec ) + throw( basic_filesystem_error<Path>( + "boost::filesystem::last_write_time", ph, ec ) ); + } + +# ifndef BOOST_FILESYSTEM_NARROW_ONLY + + // "do-the-right-thing" overloads ---------------------------------------// + + inline file_status status( const path & ph ) + { return status<path>( ph ); } + inline file_status status( const wpath & ph ) + { return status<wpath>( ph ); } + + inline file_status status( const path & ph, system::error_code & ec ) + { return status<path>( ph, ec ); } + inline file_status status( const wpath & ph, system::error_code & ec ) + { return status<wpath>( ph, ec ); } + + inline file_status symlink_status( const path & ph ) + { return symlink_status<path>( ph ); } + inline file_status symlink_status( const wpath & ph ) + { return symlink_status<wpath>( ph ); } + + inline file_status symlink_status( const path & ph, system::error_code & ec ) + { return symlink_status<path>( ph, ec ); } + inline file_status symlink_status( const wpath & ph, system::error_code & ec ) + { return symlink_status<wpath>( ph, ec ); } + + inline bool exists( const path & ph ) { return exists<path>( ph ); } + inline bool exists( const wpath & ph ) { return exists<wpath>( ph ); } + + inline bool is_directory( const path & ph ) + { return is_directory<path>( ph ); } + inline bool is_directory( const wpath & ph ) + { return is_directory<wpath>( ph ); } + + inline bool is_regular_file( const path & ph ) + { return is_regular_file<path>( ph ); } + inline bool is_regular_file( const wpath & ph ) + { return is_regular_file<wpath>( ph ); } + +# ifndef BOOST_FILESYSTEM_NO_DEPRECATED + inline bool is_regular( const path & ph ) + { return is_regular<path>( ph ); } + inline bool is_regular( const wpath & ph ) + { return is_regular<wpath>( ph ); } +# endif + + inline bool is_other( const path & ph ) + { return is_other<path>( ph ); } + inline bool is_other( const wpath & ph ) + { return is_other<wpath>( ph ); } + + inline bool is_symlink( const path & ph ) + { return is_symlink<path>( ph ); } + inline bool is_symlink( const wpath & ph ) + { return is_symlink<wpath>( ph ); } + + inline bool is_empty( const path & ph ) + { return is_empty<path>( ph ); } + inline bool is_empty( const wpath & ph ) + { return is_empty<wpath>( ph ); } + + inline bool equivalent( const path & ph1, const path & ph2 ) + { return equivalent<path>( ph1, ph2 ); } + inline bool equivalent( const wpath & ph1, const wpath & ph2 ) + { return equivalent<wpath>( ph1, ph2 ); } + + inline boost::uintmax_t file_size( const path & ph ) + { return file_size<path>( ph ); } + inline boost::uintmax_t file_size( const wpath & ph ) + { return file_size<wpath>( ph ); } + + inline space_info space( const path & ph ) + { return space<path>( ph ); } + inline space_info space( const wpath & ph ) + { return space<wpath>( ph ); } + + inline std::time_t last_write_time( const path & ph ) + { return last_write_time<path>( ph ); } + inline std::time_t last_write_time( const wpath & ph ) + { return last_write_time<wpath>( ph ); } + + inline bool create_directory( const path & dir_ph ) + { return create_directory<path>( dir_ph ); } + inline bool create_directory( const wpath & dir_ph ) + { return create_directory<wpath>( dir_ph ); } + +#if !defined(BOOST_WINDOWS_API) || defined(BOOST_FS_HARD_LINK) + inline void create_hard_link( const path & to_ph, + const path & from_ph ) + { return create_hard_link<path>( to_ph, from_ph ); } + inline void create_hard_link( const wpath & to_ph, + const wpath & from_ph ) + { return create_hard_link<wpath>( to_ph, from_ph ); } + + inline system::error_code create_hard_link( const path & to_ph, + const path & from_ph, system::error_code & ec ) + { return create_hard_link<path>( to_ph, from_ph, ec ); } + inline system::error_code create_hard_link( const wpath & to_ph, + const wpath & from_ph, system::error_code & ec ) + { return create_hard_link<wpath>( to_ph, from_ph, ec ); } +#endif + + inline void create_symlink( const path & to_ph, + const path & from_ph ) + { return create_symlink<path>( to_ph, from_ph ); } + inline void create_symlink( const wpath & to_ph, + const wpath & from_ph ) + { return create_symlink<wpath>( to_ph, from_ph ); } + + inline system::error_code create_symlink( const path & to_ph, + const path & from_ph, system::error_code & ec ) + { return create_symlink<path>( to_ph, from_ph, ec ); } + inline system::error_code create_symlink( const wpath & to_ph, + const wpath & from_ph, system::error_code & ec ) + { return create_symlink<wpath>( to_ph, from_ph, ec ); } + + inline bool remove( const path & ph ) + { return remove<path>( ph ); } + inline bool remove( const wpath & ph ) + { return remove<wpath>( ph ); } + + inline unsigned long remove_all( const path & ph ) + { return remove_all<path>( ph ); } + inline unsigned long remove_all( const wpath & ph ) + { return remove_all<wpath>( ph ); } + + inline void rename( const path & from_path, const path & to_path ) + { return rename<path>( from_path, to_path ); } + inline void rename( const wpath & from_path, const wpath & to_path ) + { return rename<wpath>( from_path, to_path ); } + + inline void copy_file( const path & from_path, const path & to_path ) + { return copy_file<path>( from_path, to_path ); } + inline void copy_file( const wpath & from_path, const wpath & to_path ) + { return copy_file<wpath>( from_path, to_path ); } + + inline path system_complete( const path & ph ) + { return system_complete<path>( ph ); } + inline wpath system_complete( const wpath & ph ) + { return system_complete<wpath>( ph ); } + + inline path complete( const path & ph, + const path & base/* = initial_path<path>()*/ ) + { return complete<path>( ph, base ); } + inline wpath complete( const wpath & ph, + const wpath & base/* = initial_path<wpath>()*/ ) + { return complete<wpath>( ph, base ); } + + inline path complete( const path & ph ) + { return complete<path>( ph, initial_path<path>() ); } + inline wpath complete( const wpath & ph ) + { return complete<wpath>( ph, initial_path<wpath>() ); } + + inline void last_write_time( const path & ph, const std::time_t new_time ) + { last_write_time<path>( ph, new_time ); } + inline void last_write_time( const wpath & ph, const std::time_t new_time ) + { last_write_time<wpath>( ph, new_time ); } + + inline void current_path( const path & ph ) + { current_path<path>( ph ); } + inline void current_path( const wpath & ph ) + { current_path<wpath>( ph ); } + +# endif // ifndef BOOST_FILESYSTEM_NARROW_ONLY + + namespace detail + { + template<class Path> + bool remove_aux( const Path & ph, file_status f ) + { + if ( exists( f ) ) + { + system::error_code ec = remove_api( ph.external_file_string() ); + if ( ec ) + throw( basic_filesystem_error<Path>( + "boost::filesystem::remove", ph, ec ) ); + return true; + } + return false; + } + + template<class Path> + unsigned long remove_all_aux( const Path & ph, file_status f ) + { + static const boost::filesystem::basic_directory_iterator<Path> end_itr; + unsigned long count = 1; + if ( !boost::filesystem::is_symlink( f ) // don't recurse symbolic links + && boost::filesystem::is_directory( f ) ) + { + for ( boost::filesystem::basic_directory_iterator<Path> itr( ph ); + itr != end_itr; ++itr ) + { + boost::system::error_code ec; + boost::filesystem::file_status fn = boost::filesystem::symlink_status( itr->path(), ec ); + if ( ec ) + throw( basic_filesystem_error<Path>( + "boost::filesystem:remove_all", ph, ec ) ); + count += remove_all_aux( itr->path(), fn ); + } + } + remove_aux( ph, f ); + return count; + } + +// test helper -------------------------------------------------------------// + + // not part of the documented interface because false positives are possible; + // there is no law that says that an OS that has large stat.st_size + // actually supports large file sizes. + BOOST_FILESYSTEM_DECL bool possible_large_file_size_support(); + +// directory_iterator helpers ----------------------------------------------// + +// forwarding functions avoid need for BOOST_FILESYSTEM_DECL for class +// basic_directory_iterator, and so avoid iterator_facade DLL template +// problems. They also overload to the proper external path character type. + + BOOST_FILESYSTEM_DECL system::error_code + dir_itr_first( void *& handle, +#if defined(BOOST_POSIX_API) + void *& buffer, +#endif + const std::string & dir_path, + std::string & target, file_status & fs, file_status & symlink_fs ); + // eof: return==0 && handle==0 + + BOOST_FILESYSTEM_DECL system::error_code + dir_itr_increment( void *& handle, +#if defined(BOOST_POSIX_API) + void *& buffer, +#endif + std::string & target, file_status & fs, file_status & symlink_fs ); + // eof: return==0 && handle==0 + + BOOST_FILESYSTEM_DECL system::error_code + dir_itr_close( void *& handle +#if defined(BOOST_POSIX_API) + , void *& buffer +#endif + ); + // Effects: none if handle==0, otherwise close handle, set handle=0 + +# if defined(BOOST_WINDOWS_API) && !defined(BOOST_FILESYSTEM_NARROW_ONLY) + BOOST_FILESYSTEM_DECL system::error_code + dir_itr_first( void *& handle, const std::wstring & ph, + std::wstring & target, file_status & fs, file_status & symlink_fs ); + BOOST_FILESYSTEM_DECL system::error_code + dir_itr_increment( void *& handle, std::wstring & target, + file_status & fs, file_status & symlink_fs ); +# endif + + template< class Path > + class dir_itr_imp + { + public: + basic_directory_entry<Path> m_directory_entry; + void * m_handle; +# ifdef BOOST_POSIX_API + void * m_buffer; // see dir_itr_increment implementation +# endif + dir_itr_imp() : m_handle(0) +# ifdef BOOST_POSIX_API + , m_buffer(0) +# endif + {} + + ~dir_itr_imp() { dir_itr_close( m_handle +#if defined(BOOST_POSIX_API) + , m_buffer +#endif + ); } + }; + + BOOST_FILESYSTEM_DECL system::error_code not_found_error(); + + } // namespace detail + +// basic_directory_iterator ------------------------------------------------// + template< class Path > + class basic_directory_iterator + //: public boost::iterator_facade< + // basic_directory_iterator<Path>, + // basic_directory_entry<Path>, + // boost::single_pass_traversal_tag > + { + public: + typedef Path path_type; + typedef basic_directory_entry<Path> value_type; + typedef value_type& reference; + typedef const value_type* pointer; + typedef ptrdiff_t difference_type; + typedef std::input_iterator_tag iterator_category; + + basic_directory_iterator() : m_imp(0) {} // creates the "end" iterator + + explicit basic_directory_iterator( const Path & dir_path ); + basic_directory_iterator( const Path & dir_path, system::error_code & ec ); + + ~basic_directory_iterator() { delete m_imp; } + + reference operator*() const + { return dereference(); } + + pointer operator->() const + { return &(operator*()); } + + const basic_directory_iterator& operator++() { + increment(); + return *this; + } + + basic_directory_iterator operator++(int) { + basic_directory_iterator tmp(*this); + ++*this; + return tmp; + } + + bool operator==(const basic_directory_iterator& rhs) const + { return equal (rhs); } + + bool operator!=(const basic_directory_iterator& rhs) const + { return !operator==(rhs); } + + private: + + // shared_ptr provides shallow-copy semantics required for InputIterators. + // m_imp.get()==0 indicates the end iterator. + // std::tr1::shared_ptr< detail::dir_itr_imp< Path > > m_imp; + detail::dir_itr_imp< Path >* m_imp; + + // friend class boost::iterator_core_access; + + //typename boost::iterator_facade< + // basic_directory_iterator<Path>, + // basic_directory_entry<Path>, + // boost::single_pass_traversal_tag >::reference dereference() const + reference dereference() const + { + assert( m_imp != 0 ); // attempt to dereference end iterator + return m_imp->m_directory_entry; + } + + void increment(); + + bool equal( const basic_directory_iterator & rhs ) const + { return m_imp == (rhs.m_imp); } + + system::error_code m_init( const Path & dir_path ); + }; + + typedef basic_directory_iterator< path > directory_iterator; +# ifndef BOOST_FILESYSTEM_NARROW_ONLY + typedef basic_directory_iterator< wpath > wdirectory_iterator; +# endif + + // basic_directory_iterator implementation ---------------------------// + + template<class Path> + system::error_code basic_directory_iterator<Path>::m_init( + const Path & dir_path ) + { + if ( dir_path.empty() ) + { + delete m_imp; + m_imp = 0; + return detail::not_found_error(); + } + typename Path::external_string_type name; + file_status fs, symlink_fs; + system::error_code ec( detail::dir_itr_first( m_imp->m_handle, +#if defined(BOOST_POSIX_API) + m_imp->m_buffer, +#endif + dir_path.external_directory_string(), + name, fs, symlink_fs ) ); + + if ( ec ) + { + delete m_imp; + m_imp = 0; + return ec; + } + + if ( m_imp->m_handle == 0 ) { + delete m_imp; + m_imp = 0; // eof, so make end iterator + } + else // not eof + { + m_imp->m_directory_entry.assign( dir_path + / Path::traits_type::to_internal( name ), fs, symlink_fs ); + if ( name[0] == dot<Path>::value // dot or dot-dot + && (name.size() == 1 + || (name[1] == dot<Path>::value + && name.size() == 2)) ) + { increment(); } + } + return boost::system::error_code(); + } + + template<class Path> + basic_directory_iterator<Path>::basic_directory_iterator( + const Path & dir_path ) + : m_imp( new detail::dir_itr_imp<Path> ) + { + system::error_code ec( m_init(dir_path) ); + if ( ec ) + { + throw( basic_filesystem_error<Path>( + "boost::filesystem::basic_directory_iterator constructor", + dir_path, ec ) ); + } + } + + template<class Path> + basic_directory_iterator<Path>::basic_directory_iterator( + const Path & dir_path, system::error_code & ec ) + : m_imp( new detail::dir_itr_imp<Path> ) + { + ec = m_init(dir_path); + } + + template<class Path> + void basic_directory_iterator<Path>::increment() + { + assert( m_imp != 0 ); // attempt to increment end iterator + assert( m_imp->m_handle != 0 ); // internal program error + + typename Path::external_string_type name; + file_status fs, symlink_fs; + system::error_code ec; + + for (;;) + { + ec = detail::dir_itr_increment( m_imp->m_handle, +#if defined(BOOST_POSIX_API) + m_imp->m_buffer, +#endif + name, fs, symlink_fs ); + if ( ec ) + { + throw( basic_filesystem_error<Path>( + "boost::filesystem::basic_directory_iterator increment", + m_imp->m_directory_entry.path().parent_path(), ec ) ); + } + if ( m_imp->m_handle == 0 ) { delete m_imp; m_imp = 0; return; } // eof, make end + if ( !(name[0] == dot<Path>::value // !(dot or dot-dot) + && (name.size() == 1 + || (name[1] == dot<Path>::value + && name.size() == 2))) ) + { + m_imp->m_directory_entry.replace_filename( + Path::traits_type::to_internal( name ), fs, symlink_fs ); + return; + } + } + } + + // basic_directory_entry -----------------------------------------------// + + template<class Path> + class basic_directory_entry + { + public: + typedef Path path_type; + typedef typename Path::string_type string_type; + + // compiler generated copy-ctor, copy assignment, and destructor apply + + basic_directory_entry() {} + explicit basic_directory_entry( const path_type & p, + file_status st = file_status(), file_status symlink_st=file_status() ) + : m_path(p), m_status(st), m_symlink_status(symlink_st) + {} + + void assign( const path_type & p, + file_status st, file_status symlink_st ) + { m_path = p; m_status = st; m_symlink_status = symlink_st; } + + void replace_filename( const string_type & s, + file_status st, file_status symlink_st ) + { + m_path.remove_filename(); + m_path /= s; + m_status = st; + m_symlink_status = symlink_st; + } + +# ifndef BOOST_FILESYSTEM_NO_DEPRECATED + void replace_leaf( const string_type & s, + file_status st, file_status symlink_st ) + { replace_filename( s, st, symlink_st ); } +# endif + + const Path & path() const { return m_path; } + file_status status() const; + file_status status( system::error_code & ec ) const; + file_status symlink_status() const; + file_status symlink_status( system::error_code & ec ) const; + + // conversion simplifies the most common use of basic_directory_entry + operator const path_type &() const { return m_path; } + +# ifndef BOOST_FILESYSTEM_NO_DEPRECATED + // deprecated functions preserve common use cases in legacy code + typename Path::string_type filename() const + { + return path().filename(); + } + typename Path::string_type leaf() const + { + return path().filename(); + } + typename Path::string_type string() const + { + return path().string(); + } +# endif + + private: + path_type m_path; + mutable file_status m_status; // stat()-like + mutable file_status m_symlink_status; // lstat()-like + // note: m_symlink_status is not used by Windows implementation + + }; // basic_directory_status + + typedef basic_directory_entry<path> directory_entry; +# ifndef BOOST_FILESYSTEM_NARROW_ONLY + typedef basic_directory_entry<wpath> wdirectory_entry; +# endif + + // basic_directory_entry implementation --------------------------------// + + template<class Path> + file_status + basic_directory_entry<Path>::status() const + { + if ( !status_known( m_status ) ) + { +# ifndef BOOST_WINDOWS_API + if ( status_known( m_symlink_status ) + && !is_symlink( m_symlink_status ) ) + { m_status = m_symlink_status; } + else { m_status = boost::filesystem::status( m_path ); } +# else + m_status = boost::filesystem::status( m_path ); +# endif + } + return m_status; + } + + template<class Path> + file_status + basic_directory_entry<Path>::status( system::error_code & ec ) const + { + if ( !status_known( m_status ) ) + { +# ifndef BOOST_WINDOWS_API + if ( status_known( m_symlink_status ) + && !is_symlink( m_symlink_status ) ) + { ec = boost::system::error_code();; m_status = m_symlink_status; } + else { m_status = boost::filesystem::status( m_path, ec ); } +# else + m_status = boost::filesystem::status( m_path, ec ); +# endif + } + else ec = boost::system::error_code();; + return m_status; + } + + template<class Path> + file_status + basic_directory_entry<Path>::symlink_status() const + { +# ifndef BOOST_WINDOWS_API + if ( !status_known( m_symlink_status ) ) + { m_symlink_status = boost::filesystem::symlink_status( m_path ); } + return m_symlink_status; +# else + return status(); +# endif + } + + template<class Path> + file_status + basic_directory_entry<Path>::symlink_status( system::error_code & ec ) const + { +# ifndef BOOST_WINDOWS_API + if ( !status_known( m_symlink_status ) ) + { m_symlink_status = boost::filesystem::symlink_status( m_path, ec ); } + else ec = boost::system::error_code();; + return m_symlink_status; +# else + return status( ec ); +# endif + } + } // namespace filesystem +} // namespace boost + +#undef BOOST_FS_FUNC + + +// #include <boost/config/abi_suffix.hpp> // pops abi_prefix.hpp pragmas +#endif // BOOST_FILESYSTEM_OPERATIONS_HPP diff --git a/ThirdParty/NRLib/boost/filesystem/path.cpp b/ThirdParty/NRLib/boost/filesystem/path.cpp new file mode 100644 index 0000000000..74a92af135 --- /dev/null +++ b/ThirdParty/NRLib/boost/filesystem/path.cpp @@ -0,0 +1,159 @@ +// path.cpp ----------------------------------------------------------------// + +// Copyright 2005 Beman Dawes + +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See library home page at http://www.boost.org/libs/filesystem + +//----------------------------------------------------------------------------// + +// define BOOST_FILESYSTEM_SOURCE so that <boost/filesystem/config.hpp> knows +// the library is being built (possibly exporting rather than importing code) +#define BOOST_FILESYSTEM_SOURCE + +#include <boost/filesystem/config.hpp> + +#ifndef BOOST_FILESYSTEM_NARROW_ONLY + +#include <boost/filesystem/path.hpp> +#include <boost/scoped_array.hpp> + +#include <locale> +#include <boost/cerrno.hpp> +#include <boost/system/error_code.hpp> + +#include <cwchar> // for std::mbstate_t + +namespace +{ + // std::locale construction can throw (if LC_MESSAGES is wrong, for example), + // so a static at function scope is used to ensure that exceptions can be + // caught. (A previous version was at namespace scope, so initialization + // occurred before main(), preventing exceptions from being caught.) + std::locale & loc() + { + // ISO C calls this "the locale-specific native environment": + static std::locale lc(""); + return lc; + } + + const std::codecvt<wchar_t, char, std::mbstate_t> *& + converter() + { + static const std::codecvt<wchar_t, char, std::mbstate_t> * + cvtr( + &std::use_facet<std::codecvt<wchar_t, char, std::mbstate_t> > + ( loc() ) ); + return cvtr; + } + + bool locked(false); +} // unnamed namespace + +namespace boost +{ + namespace filesystem + { + bool wpath_traits::imbue( const std::locale & new_loc, const std::nothrow_t & ) + { + if ( locked ) return false; + locked = true; + loc() = new_loc; + converter() = &std::use_facet + <std::codecvt<wchar_t, char, std::mbstate_t> >( loc() ); + return true; + } + + void wpath_traits::imbue( const std::locale & new_loc ) + { + if ( locked ) boost::throw_exception( + wfilesystem_error( + "boost::filesystem::wpath_traits::imbue() after lockdown", + make_error_code( system::posix::not_supported ) ) ); + imbue( new_loc, std::nothrow ); + } + + //namespace detail + //{ + // BOOST_FILESYSTEM_DECL + // const char * what( const char * sys_err_what, + // const path & path1, const path & path2, std::string & target) + // { + // try + // { + // if ( target.empty() ) + // { + // target = sys_err_what; + // if ( !path1.empty() ) + // { + // target += ": \""; + // target += path1.file_string(); + // target += "\""; + // } + // if ( !path2.empty() ) + // { + // target += ", \""; + // target += path2.file_string(); + // target += "\""; + // } + // } + // return target.c_str(); + // } + // catch (...) + // { + // return sys_err_what; + // } + // } + //} + +# ifdef BOOST_POSIX_API + +// Because this is POSIX only code, we don't have to worry about ABI issues +// described in http://www.boost.org/more/separate_compilation.html + + wpath_traits::external_string_type + wpath_traits::to_external( const wpath & ph, + const internal_string_type & src ) + { + locked = true; + std::size_t work_size( converter()->max_length() * (src.size()+1) ); + boost::scoped_array<char> work( new char[ work_size ] ); + std::mbstate_t state = std::mbstate_t(); // perhaps unneeded, but cuts bug reports + const internal_string_type::value_type * from_next; + external_string_type::value_type * to_next; + if ( converter()->out( + state, src.c_str(), src.c_str()+src.size(), from_next, work.get(), + work.get()+work_size, to_next ) != std::codecvt_base::ok ) + boost::throw_exception( boost::filesystem::wfilesystem_error( + "boost::filesystem::wpath::to_external conversion error", + ph, system::error_code( system::posix::invalid_argument, system::system_category ) ) ); + *to_next = '\0'; + return external_string_type( work.get() ); + } + + wpath_traits::internal_string_type + wpath_traits::to_internal( const external_string_type & src ) + { + locked = true; + std::size_t work_size( src.size()+1 ); + boost::scoped_array<wchar_t> work( new wchar_t[ work_size ] ); + std::mbstate_t state = std::mbstate_t(); // perhaps unneeded, but cuts bug reports + const external_string_type::value_type * from_next; + internal_string_type::value_type * to_next; + if ( converter()->in( + state, src.c_str(), src.c_str()+src.size(), from_next, work.get(), + work.get()+work_size, to_next ) != std::codecvt_base::ok ) + boost::throw_exception( boost::filesystem::wfilesystem_error( + "boost::filesystem::wpath::to_internal conversion error", + system::error_code( system::posix::invalid_argument, system::system_category ) ) ); + *to_next = L'\0'; + return internal_string_type( work.get() ); + } +# endif // BOOST_POSIX_API + + } // namespace filesystem +} // namespace boost + +#endif // ifndef BOOST_FILESYSTEM_NARROW_ONLY diff --git a/ThirdParty/NRLib/boost/filesystem/path.hpp b/ThirdParty/NRLib/boost/filesystem/path.hpp new file mode 100644 index 0000000000..3d87e349c3 --- /dev/null +++ b/ThirdParty/NRLib/boost/filesystem/path.hpp @@ -0,0 +1,1551 @@ +// boost/filesystem/path.hpp -----------------------------------------------// + +// Copyright Beman Dawes 2002-2005 +// Copyright Vladimir Prus 2002 + +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See library home page at http://www.boost.org/libs/filesystem + +// basic_path's stem(), extension(), and replace_extension() are based on +// basename(), extension(), and change_extension() from the original +// filesystem/convenience.hpp header by Vladimir Prus. + +//----------------------------------------------------------------------------// + +#ifndef BOOST_FILESYSTEM_PATH_HPP +#define BOOST_FILESYSTEM_PATH_HPP + +//#include <boost/filesystem/config.hpp> +#include "config.hpp" +#include <boost/system/system_error.hpp> +//#include "../exception/exception.hpp" +//#include <boost/iterator/iterator_facade.hpp> +//#include <boost/throw_exception.hpp> +//#include <boost/shared_ptr.hpp> +//#include <boost/type_traits/is_same.hpp> +//#include <boost/static_assert.hpp> + +#include <memory> // shared_ptr +#include <string> +#include <algorithm> // for lexicographical_compare +#include <iosfwd> // needed by basic_path inserter and extractor +#include <stdexcept> +#include <cassert> +#include <cstddef> + +# ifndef BOOST_FILESYSTEM_NARROW_ONLY +# include <locale> +# endif + +// #include <boost/config/abi_prefix.hpp> // must be the last #include + +//----------------------------------------------------------------------------// + +namespace boost +{ + namespace BOOST_FILESYSTEM_NAMESPACE + { + template<class String, class Traits> class basic_path; + + struct path_traits; + typedef basic_path< std::string, path_traits > path; + + struct path_traits + { + typedef std::string internal_string_type; + typedef std::string external_string_type; + static external_string_type to_external( const path &, + const internal_string_type & src ) { return src; } + static internal_string_type to_internal( + const external_string_type & src ) { return src; } + }; + +# ifndef BOOST_FILESYSTEM_NARROW_ONLY + + struct BOOST_FILESYSTEM_DECL wpath_traits; + + typedef basic_path< std::wstring, wpath_traits > wpath; + + struct BOOST_FILESYSTEM_DECL wpath_traits + { + typedef std::wstring internal_string_type; +# ifdef BOOST_WINDOWS_API + typedef std::wstring external_string_type; + static external_string_type to_external( const wpath &, + const internal_string_type & src ) { return src; } + static internal_string_type to_internal( + const external_string_type & src ) { return src; } +# else + typedef std::string external_string_type; + static external_string_type to_external( const wpath & ph, + const internal_string_type & src ); + static internal_string_type to_internal( + const external_string_type & src ); +# endif + static void imbue( const std::locale & loc ); + static bool imbue( const std::locale & loc, const std::nothrow_t & ); + }; + +# endif // ifndef BOOST_FILESYSTEM_NARROW_ONLY + + // path traits ---------------------------------------------------------// + + template<class Path> struct is_basic_path + { BOOST_STATIC_CONSTANT( bool, value = false ); }; + template<> struct is_basic_path<path> + { BOOST_STATIC_CONSTANT( bool, value = true ); }; +# ifndef BOOST_FILESYSTEM_NARROW_ONLY + template<> struct is_basic_path<wpath> + { BOOST_STATIC_CONSTANT( bool, value = true ); }; +# endif + + // These only have to be specialized if Path::string_type::value_type + // is not convertible from char, although specializations may eliminate + // compiler warnings. See ticket 2543. + template<class Path> struct slash + { BOOST_STATIC_CONSTANT( char, value = '/' ); }; + + template<class Path> struct dot + { BOOST_STATIC_CONSTANT( char, value = '.' ); }; + + template<class Path> struct colon + { BOOST_STATIC_CONSTANT( char, value = ':' ); }; + +# ifndef BOOST_FILESYSTEM_NARROW_ONLY + template<> struct slash<wpath> + { BOOST_STATIC_CONSTANT( wchar_t, value = L'/' ); }; + template<> struct dot<wpath> + { BOOST_STATIC_CONSTANT( wchar_t, value = L'.' ); }; + template<> struct colon<wpath> + { BOOST_STATIC_CONSTANT( wchar_t, value = L':' ); }; +# endif + +# ifdef BOOST_WINDOWS_PATH + template<class Path> struct path_alt_separator + { BOOST_STATIC_CONSTANT( char, value = '\\' ); }; +# ifndef BOOST_FILESYSTEM_NARROW_ONLY + template<> struct path_alt_separator<wpath> + { BOOST_STATIC_CONSTANT( wchar_t, value = L'\\' ); }; +# endif +# endif + + // workaround for VC++ 7.0 and earlier issues with nested classes + namespace detail + { + template<class Path> + class iterator_helper + { + public: + typedef typename Path::iterator iterator; + static void do_increment( iterator & ph ); + static void do_decrement( iterator & ph ); + }; + } + + // basic_path ----------------------------------------------------------// + + template<class String, class Traits> + class basic_path + { + // invariant: m_path valid according to the portable generic path grammar + + // validate template arguments +// TODO: get these working +// BOOST_STATIC_ASSERT( ::boost::is_same<String,typename Traits::internal_string_type>::value ); +// BOOST_STATIC_ASSERT( ::boost::is_same<typename Traits::external_string_type,std::string>::value || ::boost::is_same<typename Traits::external_string_type,std::wstring>::value ); + + public: + // compiler generates copy constructor and copy assignment + + typedef basic_path<String, Traits> path_type; + typedef String string_type; + typedef typename String::value_type value_type; + typedef Traits traits_type; + typedef typename Traits::external_string_type external_string_type; + + // constructors/destructor + basic_path() {} + basic_path( const string_type & s ) { operator/=( s ); } + basic_path( const value_type * s ) { operator/=( s ); } +# ifndef BOOST_NO_MEMBER_TEMPLATES + template <class InputIterator> + basic_path( InputIterator first, InputIterator last ) + { append( first, last ); } +# endif + ~basic_path() {} + + // assignments + basic_path & operator=( const string_type & s ) + { +# if defined(BOOST_DINKUMWARE_STDLIB) && BOOST_DINKUMWARE_STDLIB >= 310 + m_path.clear(); +# else + m_path.erase( m_path.begin(), m_path.end() ); +# endif + operator/=( s ); + return *this; + } + basic_path & operator=( const value_type * s ) + { +# if defined(BOOST_DINKUMWARE_STDLIB) && BOOST_DINKUMWARE_STDLIB >= 310 + m_path.clear(); +# else + m_path.erase( m_path.begin(), m_path.end() ); +# endif + operator/=( s ); + return *this; + } +# ifndef BOOST_NO_MEMBER_TEMPLATES + template <class InputIterator> + basic_path & assign( InputIterator first, InputIterator last ) + { m_path.clear(); append( first, last ); return *this; } +# endif + + // modifiers + basic_path & operator/=( const basic_path & rhs ) { return operator /=( rhs.string().c_str() ); } + basic_path & operator/=( const string_type & rhs ) { return operator /=( rhs.c_str() ); } + basic_path & operator/=( const value_type * s ); +# ifndef BOOST_NO_MEMBER_TEMPLATES + template <class InputIterator> + basic_path & append( InputIterator first, InputIterator last ); +# endif + + void swap( basic_path & rhs ) + { + m_path.swap( rhs.m_path ); +# ifdef BOOST_CYGWIN_PATH + std::swap( m_cygwin_root, rhs.m_cygwin_root ); +# endif + } + + basic_path & remove_filename(); + basic_path & replace_extension( const string_type & new_extension = string_type() ); + +# ifndef BOOST_FILESYSTEM_NO_DEPRECATED + basic_path & remove_leaf() { return remove_filename(); } +# endif + + // observers + const string_type & string() const { return m_path; } + const string_type file_string() const; + const string_type directory_string() const { return file_string(); } + + const external_string_type external_file_string() const { return Traits::to_external( *this, file_string() ); } + const external_string_type external_directory_string() const { return Traits::to_external( *this, directory_string() ); } + + basic_path root_path() const; + string_type root_name() const; + string_type root_directory() const; + basic_path relative_path() const; + basic_path parent_path() const; + string_type filename() const; + string_type stem() const; + string_type extension() const; + +# ifndef BOOST_FILESYSTEM_NO_DEPRECATED + string_type leaf() const { return filename(); } + basic_path branch_path() const { return parent_path(); } + bool has_leaf() const { return !m_path.empty(); } + bool has_branch_path() const { return !parent_path().empty(); } +# endif + + bool empty() const { return m_path.empty(); } // name consistent with std containers + bool is_complete() const; + bool has_root_path() const; + bool has_root_name() const; + bool has_root_directory() const; + bool has_relative_path() const { return !relative_path().empty(); } + bool has_filename() const { return !m_path.empty(); } + bool has_parent_path() const { return !parent_path().empty(); } + + // iterators + class iterator + { + public: + typedef string_type value_type; + typedef const string_type & reference; + typedef ptrdiff_t difference_type; + typedef const string_type * pointer; + typedef std::bidirectional_iterator_tag iterator_category; + + reference operator*() const + { return dereference(); } + + pointer operator->() const + { return &(operator*()); } + + const iterator& operator++() + { + increment(); + return *this; + } + + const iterator& operator++(int) + { + iterator tmp(*this); + ++*this; + return tmp; + } + + const iterator& operator--() + { + decrement(); + return *this; + } + + const iterator& operator--(int) + { + iterator tmp(*this); + --*this; + return tmp; + } + + bool operator==(const iterator& rhs) const + { return equal (rhs); } + + bool operator!=(const iterator& rhs) const + { return !operator==(rhs); } + + private: + friend class boost::BOOST_FILESYSTEM_NAMESPACE::basic_path<String, Traits>; + + const string_type & dereference() const + { return m_name; } + bool equal( const iterator & rhs ) const + { return m_path_ptr == rhs.m_path_ptr && m_pos == rhs.m_pos; } + + friend class boost::BOOST_FILESYSTEM_NAMESPACE::detail::iterator_helper<path_type>; + + void increment() + { + boost::BOOST_FILESYSTEM_NAMESPACE::detail::iterator_helper<path_type>::do_increment( + *this ); + } + void decrement() + { + boost::BOOST_FILESYSTEM_NAMESPACE::detail::iterator_helper<path_type>::do_decrement( + *this ); + } + + string_type m_name; // current element + const basic_path * m_path_ptr; // path being iterated over + typename string_type::size_type m_pos; // position of name in + // path_ptr->string(). The + // end() iterator is indicated by + // pos == path_ptr->m_path.size() + }; // iterator + + typedef iterator const_iterator; + + iterator begin() const; + iterator end() const; + + private: + // Note: This is an implementation for POSIX and Windows, where there + // are only minor differences between generic and native path grammars. + // Private members might be quite different in other implementations, + // particularly where there were wide differences between portable and + // native path formats, or between file_string() and + // directory_string() formats, or simply that the implementation + // was willing expend additional memory to achieve greater speed for + // some operations at the expense of other operations. + + string_type m_path; // invariant: portable path grammar + // on Windows, backslashes converted to slashes + +# ifdef BOOST_CYGWIN_PATH + bool m_cygwin_root; // if present, m_path[0] was slash. note: initialization + // done by append +# endif + + void m_append_separator_if_needed(); + void m_append( value_type value ); // converts Windows alt_separator + + // Was qualified; como433beta8 reports: + // warning #427-D: qualified name is not allowed in member declaration + friend class iterator; + friend class boost::BOOST_FILESYSTEM_NAMESPACE::detail::iterator_helper<path_type>; + + // Deprecated features ease transition for existing code. Don't use these + // in new code. +# ifndef BOOST_FILESYSTEM_NO_DEPRECATED + public: + typedef bool (*name_check)( const std::string & name ); + basic_path( const string_type & str, name_check ) { operator/=( str ); } + basic_path( const typename string_type::value_type * s, name_check ) + { operator/=( s );} + string_type native_file_string() const { return file_string(); } + string_type native_directory_string() const { return directory_string(); } + static bool default_name_check_writable() { return false; } + static void default_name_check( name_check ) {} + static name_check default_name_check() { return 0; } + basic_path & canonize(); + basic_path & normalize(); +# endif + }; + + // basic_path non-member functions ---------------------------------------// + + template< class String, class Traits > + inline void swap( basic_path<String, Traits> & lhs, + basic_path<String, Traits> & rhs ) { lhs.swap( rhs ); } + + template< class String, class Traits > + bool operator<( const basic_path<String, Traits> & lhs, const basic_path<String, Traits> & rhs ) + { + return std::lexicographical_compare( + lhs.begin(), lhs.end(), rhs.begin(), rhs.end() ); + } + + template< class String, class Traits > + bool operator<( const typename basic_path<String, Traits>::string_type::value_type * lhs, + const basic_path<String, Traits> & rhs ) + { + basic_path<String, Traits> tmp( lhs ); + return std::lexicographical_compare( + tmp.begin(), tmp.end(), rhs.begin(), rhs.end() ); + } + + template< class String, class Traits > + bool operator<( const typename basic_path<String, Traits>::string_type & lhs, + const basic_path<String, Traits> & rhs ) + { + basic_path<String, Traits> tmp( lhs ); + return std::lexicographical_compare( + tmp.begin(), tmp.end(), rhs.begin(), rhs.end() ); + } + + template< class String, class Traits > + bool operator<( const basic_path<String, Traits> & lhs, + const typename basic_path<String, Traits>::string_type::value_type * rhs ) + { + basic_path<String, Traits> tmp( rhs ); + return std::lexicographical_compare( + lhs.begin(), lhs.end(), tmp.begin(), tmp.end() ); + } + + template< class String, class Traits > + bool operator<( const basic_path<String, Traits> & lhs, + const typename basic_path<String, Traits>::string_type & rhs ) + { + basic_path<String, Traits> tmp( rhs ); + return std::lexicographical_compare( + lhs.begin(), lhs.end(), tmp.begin(), tmp.end() ); + } + + template< class String, class Traits > + inline bool operator==( const basic_path<String, Traits> & lhs, const basic_path<String, Traits> & rhs ) + { + return !(lhs < rhs) && !(rhs < lhs); + } + + template< class String, class Traits > + inline bool operator==( const typename basic_path<String, Traits>::string_type::value_type * lhs, + const basic_path<String, Traits> & rhs ) + { + basic_path<String, Traits> tmp( lhs ); + return !(tmp < rhs) && !(rhs < tmp); + } + + template< class String, class Traits > + inline bool operator==( const typename basic_path<String, Traits>::string_type & lhs, + const basic_path<String, Traits> & rhs ) + { + basic_path<String, Traits> tmp( lhs ); + return !(tmp < rhs) && !(rhs < tmp); + } + + template< class String, class Traits > + inline bool operator==( const basic_path<String, Traits> & lhs, + const typename basic_path<String, Traits>::string_type::value_type * rhs ) + { + basic_path<String, Traits> tmp( rhs ); + return !(lhs < tmp) && !(tmp < lhs); + } + + template< class String, class Traits > + inline bool operator==( const basic_path<String, Traits> & lhs, + const typename basic_path<String, Traits>::string_type & rhs ) + { + basic_path<String, Traits> tmp( rhs ); + return !(lhs < tmp) && !(tmp < lhs); + } + + template< class String, class Traits > + inline bool operator!=( const basic_path<String, Traits> & lhs, const basic_path<String, Traits> & rhs ) { return !(lhs == rhs); } + + template< class String, class Traits > + inline bool operator!=( const typename basic_path<String, Traits>::string_type::value_type * lhs, + const basic_path<String, Traits> & rhs ) { return !(basic_path<String, Traits>(lhs) == rhs); } + + template< class String, class Traits > + inline bool operator!=( const typename basic_path<String, Traits>::string_type & lhs, + const basic_path<String, Traits> & rhs ) { return !(basic_path<String, Traits>(lhs) == rhs); } + + template< class String, class Traits > + inline bool operator!=( const basic_path<String, Traits> & lhs, + const typename basic_path<String, Traits>::string_type::value_type * rhs ) + { return !(lhs == basic_path<String, Traits>(rhs)); } + + template< class String, class Traits > + inline bool operator!=( const basic_path<String, Traits> & lhs, + const typename basic_path<String, Traits>::string_type & rhs ) + { return !(lhs == basic_path<String, Traits>(rhs)); } + + template< class String, class Traits > + inline bool operator>( const basic_path<String, Traits> & lhs, const basic_path<String, Traits> & rhs ) { return rhs < lhs; } + + template< class String, class Traits > + inline bool operator>( const typename basic_path<String, Traits>::string_type::value_type * lhs, + const basic_path<String, Traits> & rhs ) { return rhs < basic_path<String, Traits>(lhs); } + + template< class String, class Traits > + inline bool operator>( const typename basic_path<String, Traits>::string_type & lhs, + const basic_path<String, Traits> & rhs ) { return rhs < basic_path<String, Traits>(lhs); } + + template< class String, class Traits > + inline bool operator>( const basic_path<String, Traits> & lhs, + const typename basic_path<String, Traits>::string_type::value_type * rhs ) + { return basic_path<String, Traits>(rhs) < lhs; } + + template< class String, class Traits > + inline bool operator>( const basic_path<String, Traits> & lhs, + const typename basic_path<String, Traits>::string_type & rhs ) + { return basic_path<String, Traits>(rhs) < lhs; } + + template< class String, class Traits > + inline bool operator<=( const basic_path<String, Traits> & lhs, const basic_path<String, Traits> & rhs ) { return !(rhs < lhs); } + + template< class String, class Traits > + inline bool operator<=( const typename basic_path<String, Traits>::string_type::value_type * lhs, + const basic_path<String, Traits> & rhs ) { return !(rhs < basic_path<String, Traits>(lhs)); } + + template< class String, class Traits > + inline bool operator<=( const typename basic_path<String, Traits>::string_type & lhs, + const basic_path<String, Traits> & rhs ) { return !(rhs < basic_path<String, Traits>(lhs)); } + + template< class String, class Traits > + inline bool operator<=( const basic_path<String, Traits> & lhs, + const typename basic_path<String, Traits>::string_type::value_type * rhs ) + { return !(basic_path<String, Traits>(rhs) < lhs); } + + template< class String, class Traits > + inline bool operator<=( const basic_path<String, Traits> & lhs, + const typename basic_path<String, Traits>::string_type & rhs ) + { return !(basic_path<String, Traits>(rhs) < lhs); } + + template< class String, class Traits > + inline bool operator>=( const basic_path<String, Traits> & lhs, const basic_path<String, Traits> & rhs ) { return !(lhs < rhs); } + + template< class String, class Traits > + inline bool operator>=( const typename basic_path<String, Traits>::string_type::value_type * lhs, + const basic_path<String, Traits> & rhs ) { return !(lhs < basic_path<String, Traits>(rhs)); } + + template< class String, class Traits > + inline bool operator>=( const typename basic_path<String, Traits>::string_type & lhs, + const basic_path<String, Traits> & rhs ) { return !(lhs < basic_path<String, Traits>(rhs)); } + + template< class String, class Traits > + inline bool operator>=( const basic_path<String, Traits> & lhs, + const typename basic_path<String, Traits>::string_type::value_type * rhs ) + { return !(basic_path<String, Traits>(lhs) < rhs); } + + template< class String, class Traits > + inline bool operator>=( const basic_path<String, Traits> & lhs, + const typename basic_path<String, Traits>::string_type & rhs ) + { return !(basic_path<String, Traits>(lhs) < rhs); } + + // operator / + + template< class String, class Traits > + inline basic_path<String, Traits> operator/( + const basic_path<String, Traits> & lhs, + const basic_path<String, Traits> & rhs ) + { return basic_path<String, Traits>( lhs ) /= rhs; } + + template< class String, class Traits > + inline basic_path<String, Traits> operator/( + const basic_path<String, Traits> & lhs, + const typename String::value_type * rhs ) + { return basic_path<String, Traits>( lhs ) /= + basic_path<String, Traits>( rhs ); } + + template< class String, class Traits > + inline basic_path<String, Traits> operator/( + const basic_path<String, Traits> & lhs, const String & rhs ) + { return basic_path<String, Traits>( lhs ) /= + basic_path<String, Traits>( rhs ); } + + template< class String, class Traits > + inline basic_path<String, Traits> operator/( + const typename String::value_type * lhs, + const basic_path<String, Traits> & rhs ) + { return basic_path<String, Traits>( lhs ) /= rhs; } + + template< class String, class Traits > + inline basic_path<String, Traits> operator/( + const String & lhs, const basic_path<String, Traits> & rhs ) + { return basic_path<String, Traits>( lhs ) /= rhs; } + + // inserters and extractors --------------------------------------------// + +// bypass VC++ 7.0 and earlier, and broken Borland compilers +# if !(defined(_MSC_VER) && _MSC_VER <= 1300) // && !BOOST_WORKAROUND(__BORLANDC__, < 0x610) + template< class Path > + std::basic_ostream< typename Path::string_type::value_type, + typename Path::string_type::traits_type > & + operator<< + ( std::basic_ostream< typename Path::string_type::value_type, + typename Path::string_type::traits_type >& os, const Path & ph ) + { + os << ph.string(); + return os; + } + + template< class Path > + std::basic_istream< typename Path::string_type::value_type, + typename Path::string_type::traits_type > & + operator>> + ( std::basic_istream< typename Path::string_type::value_type, + typename Path::string_type::traits_type >& is, Path & ph ) + { + typename Path::string_type str; + is >> str; + ph = str; + return is; + } +# elif 0 // BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) + template< class String, class Traits > + std::basic_ostream< BOOST_DEDUCED_TYPENAME String::value_type, + BOOST_DEDUCED_TYPENAME String::traits_type > & + operator<< + ( std::basic_ostream< BOOST_DEDUCED_TYPENAME String::value_type, + BOOST_DEDUCED_TYPENAME String::traits_type >& os, + const basic_path< String, Traits > & ph ) + { + os << ph.string(); + return os; + } + + template< class String, class Traits > + std::basic_istream< BOOST_DEDUCED_TYPENAME String::value_type, + BOOST_DEDUCED_TYPENAME String::traits_type > & + operator>> + ( std::basic_istream< BOOST_DEDUCED_TYPENAME String::value_type, + BOOST_DEDUCED_TYPENAME String::traits_type> & is, + basic_path< String, Traits > & ph ) + { + String str; + is >> str; + ph = str; + return is; + } +# endif + + // basic_filesystem_error helpers --------------------------------------// + + // Originally choice of implementation was done via specialization of + // basic_filesystem_error::what(). Several compilers (GCC, aCC, etc.) + // couldn't handle that, so the choice is now accomplished by overloading. + + namespace detail + { + // BOOST_FILESYSTEM_DECL version works for VC++ but not GCC. Go figure! + inline + const char * what( const char * sys_err_what, + const path & path1_arg, const path & path2_arg, std::string & target ) + { + try + { + if ( target.empty() ) + { + target = sys_err_what; + if ( !path1_arg.empty() ) + { + target += ": \""; + target += path1_arg.file_string(); + target += "\""; + } + if ( !path2_arg.empty() ) + { + target += ", \""; + target += path2_arg.file_string(); + target += "\""; + } + } + return target.c_str(); + } + catch (...) + { + return sys_err_what; + } + } + + template<class Path> + const char * what( const char * sys_err_what, + const Path & /*path1_arg*/, const Path & /*path2_arg*/, std::string & /*target*/ ) + { + return sys_err_what; + } + } + + // basic_filesystem_error ----------------------------------------------// + + + template<class Path> + class basic_filesystem_error : public system::system_error + { + // see http://www.boost.org/more/error_handling.html for design rationale + public: + // compiler generates copy constructor and copy assignment + + typedef Path path_type; + + basic_filesystem_error( const std::string & what_arg, + system::error_code ec ); + + basic_filesystem_error( const std::string & what_arg, + const path_type & path1_arg, system::error_code ec ); + + basic_filesystem_error( const std::string & what_arg, const path_type & path1_arg, + const path_type & path2_arg, system::error_code ec ); + + ~basic_filesystem_error() throw() { delete m_imp_ptr; } + + const path_type & path1() const + { + static const path_type empty_path; + return m_imp_ptr != 0 ? m_imp_ptr->m_path1 : empty_path ; + } + const path_type & path2() const + { + static const path_type empty_path; + return m_imp_ptr != 0 ? m_imp_ptr->m_path2 : empty_path ; + } + + const char * what() const throw() + { + if ( m_imp_ptr == 0 ) + return system::system_error::what(); + return detail::what( system::system_error::what(), m_imp_ptr->m_path1, + m_imp_ptr->m_path2, m_imp_ptr->m_what ); + } + + private: + struct m_imp + { + path_type m_path1; // may be empty() + path_type m_path2; // may be empty() + std::string m_what; // not built until needed + }; + // std::tr1::shared_ptr<m_imp> m_imp_ptr; + m_imp* m_imp_ptr; + }; + + typedef basic_filesystem_error<path> filesystem_error; + +# ifndef BOOST_FILESYSTEM_NARROW_ONLY + typedef basic_filesystem_error<wpath> wfilesystem_error; +# endif + + // path::name_checks -----------------------------------------------------// + + BOOST_FILESYSTEM_DECL bool portable_posix_name( const std::string & name ); + BOOST_FILESYSTEM_DECL bool windows_name( const std::string & name ); + BOOST_FILESYSTEM_DECL bool portable_name( const std::string & name ); + BOOST_FILESYSTEM_DECL bool portable_directory_name( const std::string & name ); + BOOST_FILESYSTEM_DECL bool portable_file_name( const std::string & name ); + BOOST_FILESYSTEM_DECL bool native( const std::string & name ); + inline bool no_check( const std::string & ) + { return true; } + +// implementation -----------------------------------------------------------// + + namespace detail + { + + // is_separator helper ------------------------------------------------// + + template<class Path> + inline bool is_separator( typename Path::string_type::value_type c ) + { + return c == slash<Path>::value +# ifdef BOOST_WINDOWS_PATH + || c == path_alt_separator<Path>::value +# endif + ; + } + + // filename_pos helper ----------------------------------------------------// + + template<class String, class Traits> + typename String::size_type filename_pos( + const String & str, // precondition: portable generic path grammar + typename String::size_type end_pos ) // end_pos is past-the-end position + // return 0 if str itself is filename (or empty) + { + typedef typename + boost::BOOST_FILESYSTEM_NAMESPACE::basic_path<String, Traits> path_type; + + // case: "//" + if ( end_pos == 2 + && str[0] == slash<path_type>::value + && str[1] == slash<path_type>::value ) return 0; + + // case: ends in "/" + if ( end_pos && str[end_pos-1] == slash<path_type>::value ) + return end_pos-1; + + // set pos to start of last element + typename String::size_type pos( + str.find_last_of( slash<path_type>::value, end_pos-1 ) ); +# ifdef BOOST_WINDOWS_PATH + if ( pos == String::npos ) + pos = str.find_last_of( path_alt_separator<path_type>::value, end_pos-1 ); + if ( pos == String::npos ) + pos = str.find_last_of( colon<path_type>::value, end_pos-2 ); +# endif + + return ( pos == String::npos // path itself must be a filename (or empty) + || (pos == 1 && str[0] == slash<path_type>::value) ) // or net + ? 0 // so filename is entire string + : pos + 1; // or starts after delimiter + } + + // first_element helper -----------------------------------------------// + // sets pos and len of first element, excluding extra separators + // if src.empty(), sets pos,len, to 0,0. + + template<class String, class Traits> + void first_element( + const String & src, // precondition: portable generic path grammar + typename String::size_type & element_pos, + typename String::size_type & element_size, +# if !(defined(_MSC_VER) && _MSC_VER <= 1310) // VC++ 7.1 + typename String::size_type size = String::npos +# else + typename String::size_type size = -1 +# endif + ) + { + if ( size == String::npos ) size = src.size(); + element_pos = 0; + element_size = 0; + if ( src.empty() ) return; + + typedef typename boost::BOOST_FILESYSTEM_NAMESPACE::basic_path<String, Traits> path_type; + + typename String::size_type cur(0); + + // deal with // [network] + if ( size >= 2 && src[0] == slash<path_type>::value + && src[1] == slash<path_type>::value + && (size == 2 + || src[2] != slash<path_type>::value) ) + { + cur += 2; + element_size += 2; + } + + // leading (not non-network) separator + else if ( src[0] == slash<path_type>::value ) + { + ++element_size; + // bypass extra leading separators + while ( cur+1 < size + && src[cur+1] == slash<path_type>::value ) + { + ++cur; + ++element_pos; + } + return; + } + + // at this point, we have either a plain name, a network name, + // or (on Windows only) a device name + + // find the end + while ( cur < size +# ifdef BOOST_WINDOWS_PATH + && src[cur] != colon<path_type>::value +# endif + && src[cur] != slash<path_type>::value ) + { + ++cur; + ++element_size; + } + +# ifdef BOOST_WINDOWS_PATH + if ( cur == size ) return; + // include device delimiter + if ( src[cur] == colon<path_type>::value ) + { ++element_size; } +# endif + + return; + } + + // root_directory_start helper ----------------------------------------// + + template<class String, class Traits> + typename String::size_type root_directory_start( + const String & s, // precondition: portable generic path grammar + typename String::size_type size ) + // return npos if no root_directory found + { + typedef typename boost::BOOST_FILESYSTEM_NAMESPACE::basic_path<String, Traits> path_type; + +# ifdef BOOST_WINDOWS_PATH + // case "c:/" + if ( size > 2 + && s[1] == colon<path_type>::value + && s[2] == slash<path_type>::value ) return 2; +# endif + + // case "//" + if ( size == 2 + && s[0] == slash<path_type>::value + && s[1] == slash<path_type>::value ) return String::npos; + + // case "//net {/}" + if ( size > 3 + && s[0] == slash<path_type>::value + && s[1] == slash<path_type>::value + && s[2] != slash<path_type>::value ) + { + typename String::size_type pos( + s.find( slash<path_type>::value, 2 ) ); + return pos < size ? pos : String::npos; + } + + // case "/" + if ( size > 0 && s[0] == slash<path_type>::value ) return 0; + + return String::npos; + } + + // is_non_root_slash helper -------------------------------------------// + + template<class String, class Traits> + bool is_non_root_slash( const String & str, + typename String::size_type pos ) // pos is position of the slash + { + typedef typename + boost::BOOST_FILESYSTEM_NAMESPACE::basic_path<String, Traits> + path_type; + + assert( !str.empty() && str[pos] == slash<path_type>::value ); + + // subsequent logic expects pos to be for leftmost slash of a set + while ( pos > 0 && str[pos-1] == slash<path_type>::value ) + --pos; + + return pos != 0 + && (pos <= 2 || str[1] != slash<path_type>::value + || str.find( slash<path_type>::value, 2 ) != pos) +# ifdef BOOST_WINDOWS_PATH + && (pos !=2 || str[1] != colon<path_type>::value) +# endif + ; + } + } // namespace detail + + // decomposition functions ----------------------------------------------// + + template<class String, class Traits> + String basic_path<String, Traits>::filename() const + { + typename String::size_type end_pos( + detail::filename_pos<String, Traits>( m_path, m_path.size() ) ); + return (m_path.size() + && end_pos + && m_path[end_pos] == slash<path_type>::value + && detail::is_non_root_slash< String, Traits >(m_path, end_pos)) + ? String( 1, dot<path_type>::value ) + : m_path.substr( end_pos ); + } + + template<class String, class Traits> + String basic_path<String, Traits>::stem() const + { + string_type name = filename(); + typename string_type::size_type n = name.rfind('.'); + return name.substr(0, n); + } + + template<class String, class Traits> + String basic_path<String, Traits>::extension() const + { + string_type name = filename(); + typename string_type::size_type n = name.rfind('.'); + if (n != string_type::npos) + return name.substr(n); + else + return string_type(); + } + + template<class String, class Traits> + basic_path<String, Traits> basic_path<String, Traits>::parent_path() const + { + typename String::size_type end_pos( + detail::filename_pos<String, Traits>( m_path, m_path.size() ) ); + + bool filename_was_separator( m_path.size() + && m_path[end_pos] == slash<path_type>::value ); + + // skip separators unless root directory + typename string_type::size_type root_dir_pos( detail::root_directory_start + <string_type, traits_type>( m_path, end_pos ) ); + for ( ; + end_pos > 0 + && (end_pos-1) != root_dir_pos + && m_path[end_pos-1] == slash<path_type>::value + ; + --end_pos ) {} + + return (end_pos == 1 && root_dir_pos == 0 && filename_was_separator) + ? path_type() + : path_type( m_path.substr( 0, end_pos ) ); + } + + template<class String, class Traits> + basic_path<String, Traits> basic_path<String, Traits>::relative_path() const + { + iterator itr( begin() ); + for ( ; itr.m_pos != m_path.size() + && (itr.m_name[0] == slash<path_type>::value +# ifdef BOOST_WINDOWS_PATH + || itr.m_name[itr.m_name.size()-1] + == colon<path_type>::value +# endif + ); ++itr ) {} + + return basic_path<String, Traits>( m_path.substr( itr.m_pos ) ); + } + + template<class String, class Traits> + String basic_path<String, Traits>::root_name() const + { + iterator itr( begin() ); + + return ( itr.m_pos != m_path.size() + && ( + ( itr.m_name.size() > 1 + && itr.m_name[0] == slash<path_type>::value + && itr.m_name[1] == slash<path_type>::value + ) +# ifdef BOOST_WINDOWS_PATH + || itr.m_name[itr.m_name.size()-1] + == colon<path_type>::value +# endif + ) ) + ? *itr + : String(); + } + + template<class String, class Traits> + String basic_path<String, Traits>::root_directory() const + { + typename string_type::size_type start( + detail::root_directory_start<String, Traits>( m_path, m_path.size() ) ); + + return start == string_type::npos + ? string_type() + : m_path.substr( start, 1 ); + } + + template<class String, class Traits> + basic_path<String, Traits> basic_path<String, Traits>::root_path() const + { + // even on POSIX, root_name() is non-empty() on network paths + return basic_path<String, Traits>( root_name() ) /= root_directory(); + } + + // path query functions -------------------------------------------------// + + template<class String, class Traits> + inline bool basic_path<String, Traits>::is_complete() const + { +# ifdef BOOST_WINDOWS_PATH + return has_root_name() && has_root_directory(); +# else + return has_root_directory(); +# endif + } + + template<class String, class Traits> + inline bool basic_path<String, Traits>::has_root_path() const + { + return !root_path().empty(); + } + + template<class String, class Traits> + inline bool basic_path<String, Traits>::has_root_name() const + { + return !root_name().empty(); + } + + template<class String, class Traits> + inline bool basic_path<String, Traits>::has_root_directory() const + { + return !root_directory().empty(); + } + + // append ---------------------------------------------------------------// + + template<class String, class Traits> + void basic_path<String, Traits>::m_append_separator_if_needed() + // requires: !empty() + { + if ( +# ifdef BOOST_WINDOWS_PATH + *(m_path.end()-1) != colon<path_type>::value && +# endif + *(m_path.end()-1) != slash<path_type>::value ) + { + m_path += slash<path_type>::value; + } + } + + template<class String, class Traits> + void basic_path<String, Traits>::m_append( value_type value ) + { +# ifdef BOOST_CYGWIN_PATH + if ( m_path.empty() ) m_cygwin_root = (value == slash<path_type>::value); +# endif + +# ifdef BOOST_WINDOWS_PATH + // for BOOST_WINDOWS_PATH, convert alt_separator ('\') to separator ('/') + m_path += ( value == path_alt_separator<path_type>::value + ? slash<path_type>::value + : value ); +# else + m_path += value; +# endif + } + + // except that it wouldn't work for BOOST_NO_MEMBER_TEMPLATES compilers, + // the append() member template could replace this code. + template<class String, class Traits> + basic_path<String, Traits> & basic_path<String, Traits>::operator /= + ( const value_type * next_p ) + { + // ignore escape sequence on POSIX or Windows + if ( *next_p == slash<path_type>::value + && *(next_p+1) == slash<path_type>::value + && *(next_p+2) == colon<path_type>::value ) next_p += 3; + + // append slash<path_type>::value if needed + if ( !empty() && *next_p != 0 + && !detail::is_separator<path_type>( *next_p ) ) + { m_append_separator_if_needed(); } + + for ( ; *next_p != 0; ++next_p ) m_append( *next_p ); + return *this; + } + +# ifndef BOOST_NO_MEMBER_TEMPLATES + template<class String, class Traits> template <class InputIterator> + basic_path<String, Traits> & basic_path<String, Traits>::append( + InputIterator first, InputIterator last ) + { + // append slash<path_type>::value if needed + if ( !empty() && first != last + && !detail::is_separator<path_type>( *first ) ) + { m_append_separator_if_needed(); } + + // song-and-dance to avoid violating InputIterator requirements + // (which prohibit lookahead) in detecting a possible escape sequence + // (escape sequences are simply ignored on POSIX and Windows) + bool was_escape_sequence(true); + std::size_t append_count(0); + typename String::size_type initial_pos( m_path.size() ); + + for ( ; first != last && *first; ++first ) + { + if ( append_count == 0 && *first != slash<path_type>::value ) + was_escape_sequence = false; + if ( append_count == 1 && *first != slash<path_type>::value ) + was_escape_sequence = false; + if ( append_count == 2 && *first != colon<path_type>::value ) + was_escape_sequence = false; + m_append( *first ); + ++append_count; + } + + // erase escape sequence if any + if ( was_escape_sequence && append_count >= 3 ) + m_path.erase( initial_pos, 3 ); + + return *this; + } +# endif + +# ifndef BOOST_FILESYSTEM_NO_DEPRECATED + + // canonize ------------------------------------------------------------// + + template<class String, class Traits> + basic_path<String, Traits> & basic_path<String, Traits>::canonize() + { + static const typename string_type::value_type dot_str[] + = { dot<path_type>::value, 0 }; + + if ( m_path.empty() ) return *this; + + path_type temp; + + for ( iterator itr( begin() ); itr != end(); ++itr ) + { + temp /= *itr; + }; + + if ( temp.empty() ) temp /= dot_str; + m_path = temp.m_path; + return *this; + } + + // normalize ------------------------------------------------------------// + + template<class String, class Traits> + basic_path<String, Traits> & basic_path<String, Traits>::normalize() + { + static const typename string_type::value_type dot_str[] + = { dot<path_type>::value, 0 }; + + if ( m_path.empty() ) return *this; + + path_type temp; + iterator start( begin() ); + iterator last( end() ); + iterator stop( last-- ); + for ( iterator itr( start ); itr != stop; ++itr ) + { + // ignore "." except at start and last + if ( itr->size() == 1 + && (*itr)[0] == dot<path_type>::value + && itr != start + && itr != last ) continue; + + // ignore a name and following ".." + if ( !temp.empty() + && itr->size() == 2 + && (*itr)[0] == dot<path_type>::value + && (*itr)[1] == dot<path_type>::value ) // dot dot + { + string_type lf( temp.filename() ); + if ( lf.size() > 0 + && (lf.size() != 1 + || (lf[0] != dot<path_type>::value + && lf[0] != slash<path_type>::value)) + && (lf.size() != 2 + || (lf[0] != dot<path_type>::value + && lf[1] != dot<path_type>::value +# ifdef BOOST_WINDOWS_PATH + && lf[1] != colon<path_type>::value +# endif + ) + ) + ) + { + temp.remove_filename(); + // if not root directory, must also remove "/" if any + if ( temp.m_path.size() > 0 + && temp.m_path[temp.m_path.size()-1] + == slash<path_type>::value ) + { + typename string_type::size_type rds( + detail::root_directory_start<String,Traits>( temp.m_path, + temp.m_path.size() ) ); + if ( rds == string_type::npos + || rds != temp.m_path.size()-1 ) + { temp.m_path.erase( temp.m_path.size()-1 ); } + } + + iterator next( itr ); + if ( temp.empty() && ++next != stop + && next == last && *last == dot_str ) temp /= dot_str; + continue; + } + } + + temp /= *itr; + }; + + if ( temp.empty() ) temp /= dot_str; + m_path = temp.m_path; + return *this; + } + +# endif + + // modifiers ------------------------------------------------------------// + + template<class String, class Traits> + basic_path<String, Traits> & basic_path<String, Traits>::remove_filename() + { + m_path.erase( + detail::filename_pos<String, Traits>( m_path, m_path.size() ) ); + return *this; + } + + template<class String, class Traits> + basic_path<String, Traits> & + basic_path<String, Traits>::replace_extension( const string_type & new_ext ) + { + // erase existing extension if any + string_type old_ext = extension(); + if ( !old_ext.empty() ) + m_path.erase( m_path.size() - old_ext.size() ); + + if ( !new_ext.empty() && new_ext[0] != dot<path_type>::value ) + m_path += dot<path_type>::value; + + m_path += new_ext; + + return *this; + } + + + // path conversion functions --------------------------------------------// + + template<class String, class Traits> + const String + basic_path<String, Traits>::file_string() const + { +# ifdef BOOST_WINDOWS_PATH + // for Windows, use the alternate separator, and bypass extra + // root separators + + typename string_type::size_type root_dir_start( + detail::root_directory_start<String, Traits>( m_path, m_path.size() ) ); + bool in_root( root_dir_start != string_type::npos ); + String s; + for ( typename string_type::size_type pos( 0 ); + pos != m_path.size(); ++pos ) + { + // special case // [net] + if ( pos == 0 && m_path.size() > 1 + && m_path[0] == slash<path_type>::value + && m_path[1] == slash<path_type>::value + && ( m_path.size() == 2 + || !detail::is_separator<path_type>( m_path[2] ) + ) ) + { + ++pos; + s += path_alt_separator<path_type>::value; + s += path_alt_separator<path_type>::value; + continue; + } + + // bypass extra root separators + if ( in_root ) + { + if ( s.size() > 0 + && s[s.size()-1] == path_alt_separator<path_type>::value + && m_path[pos] == slash<path_type>::value + ) continue; + } + + if ( m_path[pos] == slash<path_type>::value ) + s += path_alt_separator<path_type>::value; + else + s += m_path[pos]; + + if ( pos > root_dir_start + && m_path[pos] == slash<path_type>::value ) + { in_root = false; } + } +# ifdef BOOST_CYGWIN_PATH + if ( m_cygwin_root ) s[0] = slash<path_type>::value; +# endif + return s; +# else + return m_path; +# endif + } + + // iterator functions ---------------------------------------------------// + + template<class String, class Traits> + typename basic_path<String, Traits>::iterator basic_path<String, Traits>::begin() const + { + iterator itr; + itr.m_path_ptr = this; + typename string_type::size_type element_size; + detail::first_element<String, Traits>( m_path, itr.m_pos, element_size ); + itr.m_name = m_path.substr( itr.m_pos, element_size ); + return itr; + } + + template<class String, class Traits> + typename basic_path<String, Traits>::iterator basic_path<String, Traits>::end() const + { + iterator itr; + itr.m_path_ptr = this; + itr.m_pos = m_path.size(); + return itr; + } + + namespace detail + { + // do_increment ------------------------------------------------------// + + template<class Path> + void iterator_helper<Path>::do_increment( iterator & itr ) + { + typedef typename Path::string_type string_type; + typedef typename Path::traits_type traits_type; + + assert( itr.m_pos < itr.m_path_ptr->m_path.size() && "basic_path::iterator increment past end()" ); + + bool was_net( itr.m_name.size() > 2 + && itr.m_name[0] == slash<Path>::value + && itr.m_name[1] == slash<Path>::value + && itr.m_name[2] != slash<Path>::value ); + + // increment to position past current element + itr.m_pos += itr.m_name.size(); + + // if end reached, create end iterator + if ( itr.m_pos == itr.m_path_ptr->m_path.size() ) + { + itr.m_name.erase( itr.m_name.begin(), itr.m_name.end() ); // VC++ 6.0 lib didn't supply clear() + return; + } + + // process separator (Windows drive spec is only case not a separator) + if ( itr.m_path_ptr->m_path[itr.m_pos] == slash<Path>::value ) + { + // detect root directory + if ( was_net + # ifdef BOOST_WINDOWS_PATH + // case "c:/" + || itr.m_name[itr.m_name.size()-1] == colon<Path>::value + # endif + ) + { + itr.m_name = slash<Path>::value; + return; + } + + // bypass separators + while ( itr.m_pos != itr.m_path_ptr->m_path.size() + && itr.m_path_ptr->m_path[itr.m_pos] == slash<Path>::value ) + { ++itr.m_pos; } + + // detect trailing separator, and treat it as ".", per POSIX spec + if ( itr.m_pos == itr.m_path_ptr->m_path.size() + && detail::is_non_root_slash< string_type, traits_type >( + itr.m_path_ptr->m_path, itr.m_pos-1 ) ) + { + --itr.m_pos; + itr.m_name = dot<Path>::value; + return; + } + } + + // get next element + typename string_type::size_type end_pos( + itr.m_path_ptr->m_path.find( slash<Path>::value, itr.m_pos ) ); + itr.m_name = itr.m_path_ptr->m_path.substr( itr.m_pos, end_pos - itr.m_pos ); + } + + // do_decrement ------------------------------------------------------// + + template<class Path> + void iterator_helper<Path>::do_decrement( iterator & itr ) + { + assert( itr.m_pos && "basic_path::iterator decrement past begin()" ); + + typedef typename Path::string_type string_type; + typedef typename Path::traits_type traits_type; + + typename string_type::size_type end_pos( itr.m_pos ); + + typename string_type::size_type root_dir_pos( + detail::root_directory_start<string_type, traits_type>( + itr.m_path_ptr->m_path, end_pos ) ); + + // if at end and there was a trailing non-root '/', return "." + if ( itr.m_pos == itr.m_path_ptr->m_path.size() + && itr.m_path_ptr->m_path.size() > 1 + && itr.m_path_ptr->m_path[itr.m_pos-1] == slash<Path>::value + && detail::is_non_root_slash< string_type, traits_type >( + itr.m_path_ptr->m_path, itr.m_pos-1 ) + ) + { + --itr.m_pos; + itr.m_name = dot<Path>::value; + return; + } + + // skip separators unless root directory + for ( + ; + end_pos > 0 + && (end_pos-1) != root_dir_pos + && itr.m_path_ptr->m_path[end_pos-1] == slash<Path>::value + ; + --end_pos ) {} + + itr.m_pos = detail::filename_pos<string_type, traits_type> + ( itr.m_path_ptr->m_path, end_pos ); + itr.m_name = itr.m_path_ptr->m_path.substr( itr.m_pos, end_pos - itr.m_pos ); + } + } // namespace detail + + // basic_filesystem_error implementation --------------------------------// + + template<class Path> + basic_filesystem_error<Path>::basic_filesystem_error( + const std::string & what_arg, system::error_code ec ) + : system::system_error(ec, what_arg) + { + try + { + // m_imp_ptr.reset( new m_imp ); + m_imp_ptr = new m_imp; + } + catch (...) { m_imp_ptr = 0; } + } + + template<class Path> + basic_filesystem_error<Path>::basic_filesystem_error( + const std::string & what_arg, const path_type & path1_arg, + system::error_code ec ) + : system::system_error(ec, what_arg) + { + try + { + //m_imp_ptr.reset( new m_imp ); + m_imp_ptr = new m_imp; + m_imp_ptr->m_path1 = path1_arg; + } + catch (...) { m_imp_ptr = 0; } + } + + template<class Path> + basic_filesystem_error<Path>::basic_filesystem_error( + const std::string & what_arg, const path_type & path1_arg, + const path_type & path2_arg, system::error_code ec ) + : system::system_error(ec, what_arg) + { + try + { + // m_imp_ptr.reset( new m_imp ); + m_imp_ptr = new m_imp; + m_imp_ptr->m_path1 = path1_arg; + m_imp_ptr->m_path2 = path2_arg; + } + catch (...) { m_imp_ptr = 0; } + } + + } // namespace BOOST_FILESYSTEM_NAMESPACE +} // namespace boost + +//#include <boost/config/abi_suffix.hpp> // pops abi_prefix.hpp pragmas + +#endif // BOOST_FILESYSTEM_PATH_HPP diff --git a/ThirdParty/NRLib/boost/filesystem/portability.cpp b/ThirdParty/NRLib/boost/filesystem/portability.cpp new file mode 100644 index 0000000000..c4c5f02ecb --- /dev/null +++ b/ThirdParty/NRLib/boost/filesystem/portability.cpp @@ -0,0 +1,115 @@ +// portability.cpp ---------------------------------------------------------// + +// Copyright 2002-2005 Beman Dawes +// Use, modification, and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy +// at http://www.boost.org/LICENSE_1_0.txt) + +// See library home page at http://www.boost.org/libs/filesystem + +//----------------------------------------------------------------------------// + +// define BOOST_FILESYSTEM_SOURCE so that <boost/filesystem/config.hpp> knows +// the library is being built (possibly exporting rather than importing code) +#define BOOST_FILESYSTEM_SOURCE + +#include <boost/filesystem/config.hpp> +#include <boost/filesystem/path.hpp> + +namespace fs = boost::filesystem; + +#include <cstring> // SGI MIPSpro compilers need this + +# ifdef BOOST_NO_STDC_NAMESPACE + namespace std { using ::strerror; } +# endif + +//----------------------------------------------------------------------------// + +namespace +{ + const char invalid_chars[] = + "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F" + "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F" + "<>:\"/\\|"; + // note that the terminating '\0' is part of the string - thus the size below + // is sizeof(invalid_chars) rather than sizeof(invalid_chars)-1. I + const std::string windows_invalid_chars( invalid_chars, sizeof(invalid_chars) ); + + const std::string valid_posix( + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789._-" ); + +} // unnamed namespace + +namespace boost +{ + namespace filesystem + { + + // name_check functions ----------------------------------------------// + +# ifdef BOOST_WINDOWS + BOOST_FILESYSTEM_DECL bool native( const std::string & name ) + { + return windows_name( name ); + } +# else + BOOST_FILESYSTEM_DECL bool native( const std::string & name ) + { + return name.size() != 0 + && name[0] != ' ' + && name.find('/') == std::string::npos; + } +# endif + + BOOST_FILESYSTEM_DECL bool portable_posix_name( const std::string & name ) + { + return name.size() != 0 + && name.find_first_not_of( valid_posix ) == std::string::npos; + } + + BOOST_FILESYSTEM_DECL bool windows_name( const std::string & name ) + { + return name.size() != 0 + && name[0] != ' ' + && name.find_first_of( windows_invalid_chars ) == std::string::npos + && *(name.end()-1) != ' ' + && (*(name.end()-1) != '.' + || name.length() == 1 || name == ".."); + } + + BOOST_FILESYSTEM_DECL bool portable_name( const std::string & name ) + { + return + name.size() != 0 + && ( name == "." + || name == ".." + || (windows_name( name ) + && portable_posix_name( name ) + && name[0] != '.' && name[0] != '-')); + } + + BOOST_FILESYSTEM_DECL bool portable_directory_name( const std::string & name ) + { + return + name == "." + || name == ".." + || (portable_name( name ) + && name.find('.') == std::string::npos); + } + + BOOST_FILESYSTEM_DECL bool portable_file_name( const std::string & name ) + { + std::string::size_type pos; + return + portable_name( name ) + && name != "." + && name != ".." + && ( (pos = name.find( '.' )) == std::string::npos + || (name.find( '.', pos+1 ) == std::string::npos + && (pos + 5) > name.length() )) + ; + } + + } // namespace filesystem +} // namespace boost diff --git a/ThirdParty/NRLib/boost/system/config.hpp b/ThirdParty/NRLib/boost/system/config.hpp new file mode 100644 index 0000000000..2aede8aa59 --- /dev/null +++ b/ThirdParty/NRLib/boost/system/config.hpp @@ -0,0 +1,78 @@ +// boost/system/config.hpp -------------------------------------------------// + +// Copyright Beman Dawes 2003, 2006 + +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/libs/system for documentation. + +#ifndef BOOST_SYSTEM_CONFIG_HPP +#define BOOST_SYSTEM_CONFIG_HPP + +// #include <boost/config.hpp> + +// BOOST_POSIX_API or BOOST_WINDOWS_API specify which API to use. +// If not specified, a sensible default will be applied. + +# if defined( BOOST_WINDOWS_API ) && defined( BOOST_POSIX_API ) +# error both BOOST_WINDOWS_API and BOOST_POSIX_API are defined +# elif !defined( BOOST_WINDOWS_API ) && !defined( BOOST_POSIX_API ) +# if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) || defined(__CYGWIN__) +# define BOOST_WINDOWS_API +# else +# define BOOST_POSIX_API +# endif +# endif + +// enable dynamic linking on Windows ---------------------------------------// + +//# if (defined(BOOST_ALL_DYN_LINK) || defined(BOOST_SYSTEM_DYN_LINK)) && defined(__BORLANDC__) && defined(__WIN32__) +//# error Dynamic linking Boost.System does not work for Borland; use static linking instead +//# endif + +#ifdef BOOST_HAS_DECLSPEC // defined in config system +// we need to import/export our code only if the user has specifically +// asked for it by defining either BOOST_ALL_DYN_LINK if they want all boost +// libraries to be dynamically linked, or BOOST_SYSTEM_DYN_LINK +// if they want just this one to be dynamically liked: +#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_SYSTEM_DYN_LINK) +// export if this is our own source, otherwise import: +#ifdef BOOST_SYSTEM_SOURCE +# define BOOST_SYSTEM_DECL __declspec(dllexport) +#else +# define BOOST_SYSTEM_DECL __declspec(dllimport) +#endif // BOOST_SYSTEM_SOURCE +#endif // DYN_LINK +#endif // BOOST_HAS_DECLSPEC +// +// if BOOST_SYSTEM_DECL isn't defined yet define it now: +#ifndef BOOST_SYSTEM_DECL +#define BOOST_SYSTEM_DECL +#endif + +// enable automatic library variant selection ------------------------------// +#if 0 // NRLib: Disable automatic library selection. +#if !defined(BOOST_SYSTEM_SOURCE) && !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_SYSTEM_NO_LIB) +// +// Set the name of our library, this will get undef'ed by auto_link.hpp +// once it's done with it: +// +#define BOOST_LIB_NAME boost_system +// +// If we're importing code from a dll, then tell auto_link.hpp about it: +// +#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_SYSTEM_DYN_LINK) +# define BOOST_DYN_LINK +#endif +// +// And include the header that does the work: +// +#include <boost/config/auto_link.hpp> +#endif // auto-linking disabled +#endif + +#define BOOST_SYSTEM_NO_DEPRECATED + +#endif // BOOST_SYSTEM_CONFIG_HPP + diff --git a/ThirdParty/NRLib/boost/system/cygwin_error.hpp b/ThirdParty/NRLib/boost/system/cygwin_error.hpp new file mode 100644 index 0000000000..f2050b8c21 --- /dev/null +++ b/ThirdParty/NRLib/boost/system/cygwin_error.hpp @@ -0,0 +1,56 @@ +// boost/system/cygwin_error.hpp -------------------------------------------// + +// Copyright Beman Dawes 2007 + +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See library home page at http://www.boost.org/libs/system + +#ifndef BOOST_CYGWIN_ERROR_HPP +#define BOOST_CYGWIN_ERROR_HPP + +// This header is effectively empty for compiles on operating systems where +// it is not applicable. + +# ifdef __CYGWIN__ + +#include <boost/system/error_code.hpp> + +namespace boost +{ + namespace system + { + // To construct an error_code after a API error: + // + // error_code( errno, system_category ) + + // User code should use the portable "posix" enums for POSIX errors; this + // allows such code to be portable to non-POSIX systems. For the non-POSIX + // errno values that POSIX-based systems typically provide in addition to + // POSIX values, use the system specific enums below. + + namespace cygwin_error + { + enum cygwin_errno + { + no_net = ENONET, + no_package = ENOPKG, + no_share = ENOSHARE + }; + } // namespace cygwin_error + + template<> struct is_error_code_enum<cygwin_error::cygwin_errno> + { static const bool value = true; }; + + namespace cygwin_error + { + inline error_code make_error_code( cygwin_errno e ) + { return error_code( e, get_system_category() ); } + } + } +} + +#endif // __CYGWIN__ + +#endif // BOOST_CYGWIN_ERROR_HPP diff --git a/ThirdParty/NRLib/boost/system/error_code.cpp b/ThirdParty/NRLib/boost/system/error_code.cpp new file mode 100644 index 0000000000..2ceab7ac74 --- /dev/null +++ b/ThirdParty/NRLib/boost/system/error_code.cpp @@ -0,0 +1,445 @@ +// error_code support implementation file ----------------------------------// + +// Copyright Beman Dawes 2002, 2006 + +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See library home page at http://www.boost.org/libs/system + +//----------------------------------------------------------------------------// + +#if defined(_MSC_VER) && (_MSC_VER >= 1400) + // Error 'function': was declared deprecated + // http://msdn2.microsoft.com/en-us/library/ttcz0bys(VS.80).aspx + // This error is emitted when you use some perfectly conforming + // std lib functions in a perfectly correct way, and also by + // some of Microsoft's own std lib code ! +# pragma warning(disable:4996) +#endif +#if defined(__INTEL_COMPILER) || defined(__ICL) + // As above: gives warning when a "deprecated" + // std library function is encountered. +# pragma warning(disable:1786) +#endif + +// define BOOST_SYSTEM_SOURCE so that <boost/system/config.hpp> knows +// the library is being built (possibly exporting rather than importing code) +#define BOOST_SYSTEM_SOURCE + +#include <boost/system/config.hpp> +#include <boost/system/error_code.hpp> +#include <boost/cerrno.hpp> +#include <vector> +#include <cstdlib> +#include <cassert> + +using namespace boost::system; +using namespace boost::system::errc; + +#include <cstring> // for strerror/strerror_r + +# if defined( BOOST_WINDOWS_API ) +# include <windows.h> +# ifndef ERROR_INCORRECT_SIZE +# define ERROR_INCORRECT_SIZE ERROR_BAD_ARGUMENTS +# endif +# endif + +//----------------------------------------------------------------------------// + +namespace +{ + // standard error categories ---------------------------------------------// + + class generic_error_category : public error_category + { + public: + generic_error_category(){} + const char * name() const; + std::string message( int ev ) const; + }; + + class system_error_category : public error_category + { + public: + system_error_category(){} + const char * name() const; + std::string message( int ev ) const; + error_condition default_error_condition( int ev ) const; + }; + + // generic_error_category implementation ---------------------------------// + + const char * generic_error_category::name() const + { + return "generic"; + } + + std::string generic_error_category::message( int ev ) const + { + static std::string unknown_err( "Unknown error" ); + // strerror_r is preferred because it is always thread safe, + // however, we fallback to strerror in certain cases because: + // -- Windows doesn't provide strerror_r. + // -- HP and Sundo provide strerror_r on newer systems, but there is + // no way to tell if is available at runtime and in any case their + // versions of strerror are thread safe anyhow. + // -- Linux only sometimes provides strerror_r. + // -- Tru64 provides strerror_r only when compiled -pthread. + // -- VMS doesn't provide strerror_r, but on this platform, strerror is + // thread safe. + # if defined(BOOST_WINDOWS_API) || defined(__hpux) || defined(__sun)\ + || (defined(__linux) && (!defined(__USE_XOPEN2K) || defined(BOOST_SYSTEM_USE_STRERROR)))\ + || (defined(__osf__) && !defined(_REENTRANT))\ + || (defined(__vms))\ + || (defined(__QNXNTO__)) + const char * c_str = std::strerror( ev ); + return c_str + ? std::string( c_str ) + : unknown_err; + # else // use strerror_r + char buf[64]; + char * bp = buf; + std::size_t sz = sizeof(buf); + # if defined(__CYGWIN__) || defined(__USE_GNU) + // Oddball version of strerror_r + const char * c_str = strerror_r( ev, bp, sz ); + return c_str + ? std::string( c_str ) + : unknown_err; + # else + // POSIX version of strerror_r + int result; + for (;;) + { + // strerror_r returns 0 on success, otherwise ERANGE if buffer too small, + // invalid_argument if ev not a valid error number + # if defined (__sgi) + const char * c_str = strerror( ev ); + result = 0; + return c_str + ? std::string( c_str ) + : unknown_err; + # else + result = strerror_r( ev, bp, sz ); + # endif + if (result == 0 ) + break; + else + { + # if defined(__linux) + // Linux strerror_r returns -1 on error, with error number in errno + result = errno; + # endif + if ( result != ERANGE ) break; + if ( sz > sizeof(buf) ) std::free( bp ); + sz *= 2; + if ( (bp = static_cast<char*>(std::malloc( sz ))) == 0 ) + return std::string( "ENOMEM" ); + } + } + std::string msg; + try + { + msg = ( ( result == invalid_argument ) ? "Unknown error" : bp ); + } + +# ifndef BOOST_NO_EXCEPTIONS + // See ticket #2098 + catch(...) + { + // just eat the exception + } +# endif + + if ( sz > sizeof(buf) ) std::free( bp ); + sz = 0; + return msg; + # endif // else POSIX version of strerror_r + # endif // else use strerror_r + } + // system_error_category implementation --------------------------------// + + const char * system_error_category::name() const + { + return "system"; + } + + error_condition system_error_category::default_error_condition( int ev ) const + { + switch ( ev ) + { + case 0: return make_error_condition( success ); + # if defined(BOOST_POSIX_API) + // POSIX-like O/S -> posix_errno decode table ---------------------------// + case E2BIG: return make_error_condition( argument_list_too_long ); + case EACCES: return make_error_condition( permission_denied ); + case EADDRINUSE: return make_error_condition( address_in_use ); + case EADDRNOTAVAIL: return make_error_condition( address_not_available ); + case EAFNOSUPPORT: return make_error_condition( address_family_not_supported ); + case EAGAIN: return make_error_condition( resource_unavailable_try_again ); +# if EALREADY != EBUSY // EALREADY and EBUSY are the same on QNX Neutrino + case EALREADY: return make_error_condition( connection_already_in_progress ); +# endif + case EBADF: return make_error_condition( bad_file_descriptor ); + case EBADMSG: return make_error_condition( bad_message ); + case EBUSY: return make_error_condition( device_or_resource_busy ); + case ECANCELED: return make_error_condition( operation_canceled ); + case ECHILD: return make_error_condition( no_child_process ); + case ECONNABORTED: return make_error_condition( connection_aborted ); + case ECONNREFUSED: return make_error_condition( connection_refused ); + case ECONNRESET: return make_error_condition( connection_reset ); + case EDEADLK: return make_error_condition( resource_deadlock_would_occur ); + case EDESTADDRREQ: return make_error_condition( destination_address_required ); + case EDOM: return make_error_condition( argument_out_of_domain ); + case EEXIST: return make_error_condition( file_exists ); + case EFAULT: return make_error_condition( bad_address ); + case EFBIG: return make_error_condition( file_too_large ); + case EHOSTUNREACH: return make_error_condition( host_unreachable ); + case EIDRM: return make_error_condition( identifier_removed ); + case EILSEQ: return make_error_condition( illegal_byte_sequence ); + case EINPROGRESS: return make_error_condition( operation_in_progress ); + case EINTR: return make_error_condition( interrupted ); + case EINVAL: return make_error_condition( invalid_argument ); + case EIO: return make_error_condition( io_error ); + case EISCONN: return make_error_condition( already_connected ); + case EISDIR: return make_error_condition( is_a_directory ); + case ELOOP: return make_error_condition( too_many_synbolic_link_levels ); + case EMFILE: return make_error_condition( too_many_files_open ); + case EMLINK: return make_error_condition( too_many_links ); + case EMSGSIZE: return make_error_condition( message_size ); + case ENAMETOOLONG: return make_error_condition( filename_too_long ); + case ENETDOWN: return make_error_condition( network_down ); + case ENETRESET: return make_error_condition( network_reset ); + case ENETUNREACH: return make_error_condition( network_unreachable ); + case ENFILE: return make_error_condition( too_many_files_open_in_system ); + case ENOBUFS: return make_error_condition( no_buffer_space ); + case ENODATA: return make_error_condition( no_message_available ); + case ENODEV: return make_error_condition( no_such_device ); + case ENOENT: return make_error_condition( no_such_file_or_directory ); + case ENOEXEC: return make_error_condition( executable_format_error ); + case ENOLCK: return make_error_condition( no_lock_available ); + case ENOLINK: return make_error_condition( no_link ); + case ENOMEM: return make_error_condition( not_enough_memory ); + case ENOMSG: return make_error_condition( no_message ); + case ENOPROTOOPT: return make_error_condition( no_protocol_option ); + case ENOSPC: return make_error_condition( no_space_on_device ); + case ENOSR: return make_error_condition( no_stream_resources ); + case ENOSTR: return make_error_condition( not_a_stream ); + case ENOSYS: return make_error_condition( function_not_supported ); + case ENOTCONN: return make_error_condition( not_connected ); + case ENOTDIR: return make_error_condition( not_a_directory ); + # if ENOTEMPTY != EEXIST // AIX treats ENOTEMPTY and EEXIST as the same value + case ENOTEMPTY: return make_error_condition( directory_not_empty ); + # endif // ENOTEMPTY != EEXIST + case ENOTRECOVERABLE: return make_error_condition( state_not_recoverable ); + case ENOTSOCK: return make_error_condition( not_a_socket ); + case ENOTSUP: return make_error_condition( not_supported ); + case ENOTTY: return make_error_condition( inappropriate_io_control_operation ); + case ENXIO: return make_error_condition( no_such_device_or_address ); + # if EOPNOTSUPP != ENOTSUP + case EOPNOTSUPP: return make_error_condition( operation_not_supported ); + # endif // EOPNOTSUPP != ENOTSUP + case EOVERFLOW: return make_error_condition( value_too_large ); + case EOWNERDEAD: return make_error_condition( owner_dead ); + case EPERM: return make_error_condition( operation_not_permitted ); + case EPIPE: return make_error_condition( broken_pipe ); + case EPROTO: return make_error_condition( protocol_error ); + case EPROTONOSUPPORT: return make_error_condition( protocol_not_supported ); + case EPROTOTYPE: return make_error_condition( wrong_protocol_type ); + case ERANGE: return make_error_condition( result_out_of_range ); + case EROFS: return make_error_condition( read_only_file_system ); + case ESPIPE: return make_error_condition( invalid_seek ); + case ESRCH: return make_error_condition( no_such_process ); + case ETIME: return make_error_condition( stream_timeout ); + case ETIMEDOUT: return make_error_condition( timed_out ); + case ETXTBSY: return make_error_condition( text_file_busy ); + # if EAGAIN != EWOULDBLOCK + case EWOULDBLOCK: return make_error_condition( operation_would_block ); + # endif // EAGAIN != EWOULDBLOCK + case EXDEV: return make_error_condition( cross_device_link ); + #else + // Windows system -> posix_errno decode table ---------------------------// + // see WinError.h comments for descriptions of errors + case ERROR_ACCESS_DENIED: return make_error_condition( permission_denied ); + case ERROR_ALREADY_EXISTS: return make_error_condition( file_exists ); + case ERROR_BAD_UNIT: return make_error_condition( no_such_device ); + case ERROR_BUFFER_OVERFLOW: return make_error_condition( filename_too_long ); + case ERROR_BUSY: return make_error_condition( device_or_resource_busy ); + case ERROR_BUSY_DRIVE: return make_error_condition( device_or_resource_busy ); + case ERROR_CANNOT_MAKE: return make_error_condition( permission_denied ); + case ERROR_CANTOPEN: return make_error_condition( io_error ); + case ERROR_CANTREAD: return make_error_condition( io_error ); + case ERROR_CANTWRITE: return make_error_condition( io_error ); + case ERROR_CURRENT_DIRECTORY: return make_error_condition( permission_denied ); + case ERROR_DEV_NOT_EXIST: return make_error_condition( no_such_device ); + case ERROR_DEVICE_IN_USE: return make_error_condition( device_or_resource_busy ); + case ERROR_DIR_NOT_EMPTY: return make_error_condition( directory_not_empty ); + case ERROR_DIRECTORY: return make_error_condition( invalid_argument ); // WinError.h: "The directory name is invalid" + case ERROR_DISK_FULL: return make_error_condition( no_space_on_device ); + case ERROR_FILE_EXISTS: return make_error_condition( file_exists ); + case ERROR_FILE_NOT_FOUND: return make_error_condition( no_such_file_or_directory ); + case ERROR_HANDLE_DISK_FULL: return make_error_condition( no_space_on_device ); + case ERROR_INVALID_ACCESS: return make_error_condition( permission_denied ); + case ERROR_INVALID_DRIVE: return make_error_condition( no_such_device ); + case ERROR_INVALID_FUNCTION: return make_error_condition( function_not_supported ); + case ERROR_INVALID_HANDLE: return make_error_condition( invalid_argument ); + case ERROR_INVALID_NAME: return make_error_condition( invalid_argument ); + case ERROR_LOCK_VIOLATION: return make_error_condition( no_lock_available ); + case ERROR_LOCKED: return make_error_condition( no_lock_available ); + case ERROR_NEGATIVE_SEEK: return make_error_condition( invalid_argument ); + case ERROR_NOACCESS: return make_error_condition( permission_denied ); + case ERROR_NOT_ENOUGH_MEMORY: return make_error_condition( not_enough_memory ); + case ERROR_NOT_READY: return make_error_condition( resource_unavailable_try_again ); + case ERROR_NOT_SAME_DEVICE: return make_error_condition( cross_device_link ); + case ERROR_OPEN_FAILED: return make_error_condition( io_error ); + case ERROR_OPEN_FILES: return make_error_condition( device_or_resource_busy ); + case ERROR_OPERATION_ABORTED: return make_error_condition( operation_canceled ); + case ERROR_OUTOFMEMORY: return make_error_condition( not_enough_memory ); + case ERROR_PATH_NOT_FOUND: return make_error_condition( no_such_file_or_directory ); + case ERROR_READ_FAULT: return make_error_condition( io_error ); + case ERROR_RETRY: return make_error_condition( resource_unavailable_try_again ); + case ERROR_SEEK: return make_error_condition( io_error ); + case ERROR_SHARING_VIOLATION: return make_error_condition( permission_denied ); + case ERROR_TOO_MANY_OPEN_FILES: return make_error_condition( too_many_files_open ); + case ERROR_WRITE_FAULT: return make_error_condition( io_error ); + case ERROR_WRITE_PROTECT: return make_error_condition( permission_denied ); + case WSAEACCES: return make_error_condition( permission_denied ); + case WSAEADDRINUSE: return make_error_condition( address_in_use ); + case WSAEADDRNOTAVAIL: return make_error_condition( address_not_available ); + case WSAEAFNOSUPPORT: return make_error_condition( address_family_not_supported ); + case WSAEALREADY: return make_error_condition( connection_already_in_progress ); + case WSAEBADF: return make_error_condition( bad_file_descriptor ); + case WSAECONNABORTED: return make_error_condition( connection_aborted ); + case WSAECONNREFUSED: return make_error_condition( connection_refused ); + case WSAECONNRESET: return make_error_condition( connection_reset ); + case WSAEDESTADDRREQ: return make_error_condition( destination_address_required ); + case WSAEFAULT: return make_error_condition( bad_address ); + case WSAEHOSTUNREACH: return make_error_condition( host_unreachable ); + case WSAEINPROGRESS: return make_error_condition( operation_in_progress ); + case WSAEINTR: return make_error_condition( interrupted ); + case WSAEINVAL: return make_error_condition( invalid_argument ); + case WSAEISCONN: return make_error_condition( already_connected ); + case WSAEMFILE: return make_error_condition( too_many_files_open ); + case WSAEMSGSIZE: return make_error_condition( message_size ); + case WSAENAMETOOLONG: return make_error_condition( filename_too_long ); + case WSAENETDOWN: return make_error_condition( network_down ); + case WSAENETRESET: return make_error_condition( network_reset ); + case WSAENETUNREACH: return make_error_condition( network_unreachable ); + case WSAENOBUFS: return make_error_condition( no_buffer_space ); + case WSAENOPROTOOPT: return make_error_condition( no_protocol_option ); + case WSAENOTCONN: return make_error_condition( not_connected ); + case WSAENOTSOCK: return make_error_condition( not_a_socket ); + case WSAEOPNOTSUPP: return make_error_condition( operation_not_supported ); + case WSAEPROTONOSUPPORT: return make_error_condition( protocol_not_supported ); + case WSAEPROTOTYPE: return make_error_condition( wrong_protocol_type ); + case WSAETIMEDOUT: return make_error_condition( timed_out ); + case WSAEWOULDBLOCK: return make_error_condition( operation_would_block ); + #endif + default: return error_condition( ev, system_category ); + } + } + +# if !defined( BOOST_WINDOWS_API ) + + std::string system_error_category::message( int ev ) const + { + return generic_category.message( ev ); + } +# else +// TODO: + +//Some quick notes on the implementation (sorry for the noise if +//someone has already mentioned them): +// +//- The ::LocalFree() usage isn't exception safe. +// +//See: +// +//<http://boost.cvs.sourceforge.net/boost/boost/boost/asio/system_exception.hpp?revision=1.1&view=markup> +// +//in the implementation of what() for an example. +// +//Cheers, +//Chris + std::string system_error_category::message( int ev ) const + { +# ifndef BOOST_NO_ANSI_APIS + LPVOID lpMsgBuf; + DWORD retval = ::FormatMessageA( + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + ev, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language + (LPSTR) &lpMsgBuf, + 0, + NULL + ); + if (retval == 0) + return std::string("Unknown error"); + + std::string str( static_cast<LPCSTR>(lpMsgBuf) ); + ::LocalFree( lpMsgBuf ); // free the buffer +# else // WinCE workaround + LPVOID lpMsgBuf; + DWORD retval = ::FormatMessageW( + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + ev, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language + (LPWSTR) &lpMsgBuf, + 0, + NULL + ); + if (retval == 0) + return std::string("Unknown error"); + + int num_chars = (wcslen( static_cast<LPCWSTR>(lpMsgBuf) ) + 1) * 2; + LPSTR narrow_buffer = (LPSTR)_alloca( num_chars ); + if (::WideCharToMultiByte(CP_ACP, 0, static_cast<LPCWSTR>(lpMsgBuf), -1, narrow_buffer, num_chars, NULL, NULL) == 0) + return std::string("Unknown error"); + + std::string str( narrow_buffer ); + ::LocalFree( lpMsgBuf ); // free the buffer +# endif + while ( str.size() + && (str[str.size()-1] == '\n' || str[str.size()-1] == '\r') ) + str.erase( str.size()-1 ); + if ( str.size() && str[str.size()-1] == '.' ) + { str.erase( str.size()-1 ); } + return str; + } +# endif + +} // unnamed namespace + +namespace boost +{ + namespace system + { + + BOOST_SYSTEM_DECL error_code throws; // "throw on error" special error_code; + // note that it doesn't matter if this + // isn't initialized before use since + // the only use is to take its + // address for comparison purposes + + BOOST_SYSTEM_DECL const error_category & get_system_category() + { + static const system_error_category system_category_const; + return system_category_const; + } + + BOOST_SYSTEM_DECL const error_category & get_generic_category() + { + static const generic_error_category generic_category_const; + return generic_category_const; + } + + } // namespace system +} // namespace boost diff --git a/ThirdParty/NRLib/boost/system/error_code.hpp b/ThirdParty/NRLib/boost/system/error_code.hpp new file mode 100644 index 0000000000..bc43f74ee9 --- /dev/null +++ b/ThirdParty/NRLib/boost/system/error_code.hpp @@ -0,0 +1,506 @@ +// boost/system/error_code.hpp ---------------------------------------------// + +// Copyright Beman Dawes 2006, 2007 +// Copyright Christoper Kohlhoff 2007 + +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See library home page at http://www.boost.org/libs/system + +#ifndef BOOST_ERROR_CODE_HPP +#define BOOST_ERROR_CODE_HPP + +#include <boost/system/config.hpp> +//#include <boost/cstdint.hpp> +//#include <boost/assert.hpp> +//#include <boost/operators.hpp> +//#include <boost/noncopyable.hpp> +//#include <boost/utility/enable_if.hpp> +#include <ostream> +#include <string> +#include <stdexcept> +#include <functional> + +// TODO: undef these macros if not already defined +#include <boost/cerrno.hpp> + +#if !defined(BOOST_POSIX_API) && !defined(BOOST_WINDOWS_API) +# error BOOST_POSIX_API or BOOST_WINDOWS_API must be defined +#endif + +// #include <boost/config/abi_prefix.hpp> // must be the last #include + +namespace boost +{ + namespace system + { + + class error_code; + class error_condition; + + // "Concept" helpers ---------------------------------------------------// + + template< class T > + struct is_error_code_enum { static const bool value = false; }; + + template< class T > + struct is_error_condition_enum { static const bool value = false; }; + + // generic error_conditions --------------------------------------------// + + namespace errc + { + enum errc_t + { + success = 0, + address_family_not_supported = EAFNOSUPPORT, + address_in_use = EADDRINUSE, + address_not_available = EADDRNOTAVAIL, + already_connected = EISCONN, + argument_list_too_long = E2BIG, + argument_out_of_domain = EDOM, + bad_address = EFAULT, + bad_file_descriptor = EBADF, + bad_message = EBADMSG, + broken_pipe = EPIPE, + connection_aborted = ECONNABORTED, + connection_already_in_progress = EALREADY, + connection_refused = ECONNREFUSED, + connection_reset = ECONNRESET, + cross_device_link = EXDEV, + destination_address_required = EDESTADDRREQ, + device_or_resource_busy = EBUSY, + directory_not_empty = ENOTEMPTY, + executable_format_error = ENOEXEC, + file_exists = EEXIST, + file_too_large = EFBIG, + filename_too_long = ENAMETOOLONG, + function_not_supported = ENOSYS, + host_unreachable = EHOSTUNREACH, + identifier_removed = EIDRM, + illegal_byte_sequence = EILSEQ, + inappropriate_io_control_operation = ENOTTY, + interrupted = EINTR, + invalid_argument = EINVAL, + invalid_seek = ESPIPE, + io_error = EIO, + is_a_directory = EISDIR, + message_size = EMSGSIZE, + network_down = ENETDOWN, + network_reset = ENETRESET, + network_unreachable = ENETUNREACH, + no_buffer_space = ENOBUFS, + no_child_process = ECHILD, + no_link = ENOLINK, + no_lock_available = ENOLCK, + no_message_available = ENODATA, + no_message = ENOMSG, + no_protocol_option = ENOPROTOOPT, + no_space_on_device = ENOSPC, + no_stream_resources = ENOSR, + no_such_device_or_address = ENXIO, + no_such_device = ENODEV, + no_such_file_or_directory = ENOENT, + no_such_process = ESRCH, + not_a_directory = ENOTDIR, + not_a_socket = ENOTSOCK, + not_a_stream = ENOSTR, + not_connected = ENOTCONN, + not_enough_memory = ENOMEM, + not_supported = ENOTSUP, + operation_canceled = ECANCELED, + operation_in_progress = EINPROGRESS, + operation_not_permitted = EPERM, + operation_not_supported = EOPNOTSUPP, + operation_would_block = EWOULDBLOCK, + owner_dead = EOWNERDEAD, + permission_denied = EACCES, + protocol_error = EPROTO, + protocol_not_supported = EPROTONOSUPPORT, + read_only_file_system = EROFS, + resource_deadlock_would_occur = EDEADLK, + resource_unavailable_try_again = EAGAIN, + result_out_of_range = ERANGE, + state_not_recoverable = ENOTRECOVERABLE, + stream_timeout = ETIME, + text_file_busy = ETXTBSY, + timed_out = ETIMEDOUT, + too_many_files_open_in_system = ENFILE, + too_many_files_open = EMFILE, + too_many_links = EMLINK, + too_many_synbolic_link_levels = ELOOP, + value_too_large = EOVERFLOW, + wrong_protocol_type = EPROTOTYPE + }; + + } // namespace errc + +# ifndef BOOST_SYSTEM_NO_DEPRECATED + namespace posix = errc; + namespace posix_error = errc; +# endif + + template<> struct is_error_condition_enum<errc::errc_t> + { static const bool value = true; }; + + + // ----------------------------------------------------------------------// + + // Operating system specific interfaces --------------------------------// + + + // The interface is divided into general and system-specific portions to + // meet these requirements: + // + // * Code calling an operating system API can create an error_code with + // a single category (system_category), even for POSIX-like operating + // systems that return some POSIX errno values and some native errno + // values. This code should not have to pay the cost of distinguishing + // between categories, since it is not yet known if that is needed. + // + // * Users wishing to write system-specific code should be given enums for + // at least the common error cases. + // + // * System specific code should fail at compile time if moved to another + // operating system. + + // The system specific portions of the interface are located in headers + // with names reflecting the operating system. For example, + // + // <boost/system/cygwin_error.hpp> + // <boost/system/linux_error.hpp> + // <boost/system/windows_error.hpp> + // + // These headers are effectively empty for compiles on operating systems + // where they are not applicable. + + // ----------------------------------------------------------------------// + + // class error_category ------------------------------------------------// + + class error_category // : public noncopyable + { + public: + error_category() {} + virtual ~error_category(){} + virtual inline const char * name() const; // see implementation note below + virtual inline std::string message( int ev ) const; // see implementation note below + virtual inline error_condition default_error_condition( int ev ) const; + virtual inline bool equivalent( int code, const error_condition & condition ) const; + virtual inline bool equivalent( const error_code & code, int condition ) const; + + bool operator==(const error_category & rhs) const { return this == &rhs; } + bool operator!=(const error_category & rhs) const { return this != &rhs; } + bool operator<( const error_category & rhs ) const + { + return std::less<const error_category*>()( this, &rhs ); + } + private: + //non-copyable + error_category(const error_category& ); + error_category& operator=(const error_category& ); + }; + + // predefined error categories -----------------------------------------// + + BOOST_SYSTEM_DECL const error_category & get_system_category(); + BOOST_SYSTEM_DECL const error_category & get_generic_category(); + + static const error_category & system_category = get_system_category(); + static const error_category & generic_category = get_generic_category(); + +# ifndef BOOST_SYSTEM_NO_DEPRECATED + // deprecated synonyms + inline const error_category & get_posix_category() { return get_generic_category(); } + static const error_category & posix_category = get_generic_category(); + static const error_category & errno_ecat = get_generic_category(); + static const error_category & native_ecat = get_system_category(); +# endif + + // class error_condition -----------------------------------------------// + + // error_conditions are portable, error_codes are system or library specific + + class error_condition + { + public: + + // constructors: + error_condition() : m_val(0), m_cat(&get_generic_category()) {} + error_condition( int val, const error_category & cat ) : m_val(val), m_cat(&cat) {} + + //template <class ErrorConditionEnum> + // error_condition(ErrorConditionEnum e, + // typename boost::enable_if<is_error_condition_enum<ErrorConditionEnum> >::type* = 0) + //{ + // *this = make_error_condition(e); + //} + + // modifiers: + + void assign( int val, const error_category & cat ) + { + m_val = val; + m_cat = &cat; + } + + //template<typename ErrorConditionEnum> + // typename boost::enable_if<is_error_condition_enum<ErrorConditionEnum>, error_condition>::type & + // operator=( ErrorConditionEnum val ) + //{ + // *this = make_error_condition(val); + // return *this; + //} + + void clear() + { + m_val = 0; + m_cat = &get_generic_category(); + } + + // observers: + int value() const { return m_val; } + const error_category & category() const { return *m_cat; } + std::string message() const { return m_cat->message(value()); } + + typedef void (*unspecified_bool_type)(); + static void unspecified_bool_true() {} + + operator unspecified_bool_type() const // true if error + { + return m_val == 0 ? 0 : unspecified_bool_true; + } + + bool operator!() const // true if no error + { + return m_val == 0; + } + + // relationals: + // the more symmetrical non-member syntax allows enum + // conversions work for both rhs and lhs. + inline friend bool operator==( const error_condition & lhs, + const error_condition & rhs ) + { + return lhs.m_cat == rhs.m_cat && lhs.m_val == rhs.m_val; + } + + inline friend bool operator<( const error_condition & lhs, + const error_condition & rhs ) + // the more symmetrical non-member syntax allows enum + // conversions work for both rhs and lhs. + { + return lhs.m_cat < rhs.m_cat + || (lhs.m_cat == rhs.m_cat && lhs.m_val < rhs.m_val); + } + + private: + int m_val; + const error_category * m_cat; + + }; + + // class error_code ----------------------------------------------------// + + // We want error_code to be a value type that can be copied without slicing + // and without requiring heap allocation, but we also want it to have + // polymorphic behavior based on the error category. This is achieved by + // abstract base class error_category supplying the polymorphic behavior, + // and error_code containing a pointer to an object of a type derived + // from error_category. + class error_code + { + public: + + // constructors: + error_code() : m_val(0), m_cat(&get_system_category()) {} + error_code( int val, const error_category & cat ) : m_val(val), m_cat(&cat) {} + + //template <class ErrorCodeEnum> + // error_code(ErrorCodeEnum e, + // typename boost::enable_if<is_error_code_enum<ErrorCodeEnum> >::type* = 0) + //{ + // *this = make_error_code(e); + //} + + // modifiers: + void assign( int val, const error_category & cat ) + { + m_val = val; + m_cat = &cat; + } + + //template<typename ErrorCodeEnum> + // typename boost::enable_if<is_error_code_enum<ErrorCodeEnum>, error_code>::type & + // operator=( ErrorCodeEnum val ) + //{ + // *this = make_error_code(val); + // return *this; + //} + + void clear() + { + m_val = 0; + m_cat = &get_system_category(); + } + + // observers: + int value() const { return m_val; } + const error_category & category() const { return *m_cat; } + error_condition default_error_condition() const { return m_cat->default_error_condition(value()); } + std::string message() const { return m_cat->message(value()); } + + typedef void (*unspecified_bool_type)(); + static void unspecified_bool_true() {} + + operator unspecified_bool_type() const // true if error + { + return m_val == 0 ? 0 : unspecified_bool_true; + } + + bool operator!() const // true if no error + { + return m_val == 0; + } + + // relationals: + inline friend bool operator==( const error_code & lhs, + const error_code & rhs ) + // the more symmetrical non-member syntax allows enum + // conversions work for both rhs and lhs. + { + return lhs.m_cat == rhs.m_cat && lhs.m_val == rhs.m_val; + } + + inline friend bool operator<( const error_code & lhs, + const error_code & rhs ) + // the more symmetrical non-member syntax allows enum + // conversions work for both rhs and lhs. + { + return lhs.m_cat < rhs.m_cat + || (lhs.m_cat == rhs.m_cat && lhs.m_val < rhs.m_val); + } + + private: + int m_val; + const error_category * m_cat; + + }; + + // predefined error_code object used as "throw on error" tag + BOOST_SYSTEM_DECL extern error_code throws; + + // non-member functions ------------------------------------------------// + + inline bool operator!=( const error_code & lhs, + const error_code & rhs ) + { + return !(lhs == rhs); + } + + inline bool operator!=( const error_condition & lhs, + const error_condition & rhs ) + { + return !(lhs == rhs); + } + + inline bool operator==( const error_code & code, + const error_condition & condition ) + { + return code.category().equivalent( code.value(), condition ) + || condition.category().equivalent( code, condition.value() ); + } + + inline bool operator!=( const error_code & lhs, + const error_condition & rhs ) + { + return !(lhs == rhs); + } + + inline bool operator==( const error_condition & condition, + const error_code & code ) + { + return condition.category().equivalent( code, condition.value() ) + || code.category().equivalent( code.value(), condition ); + } + + inline bool operator!=( const error_condition & lhs, + const error_code & rhs ) + { + return !(lhs == rhs); + } + + // TODO: both of these may move elsewhere, but the LWG hasn't spoken yet. + + template <class charT, class traits> + inline std::basic_ostream<charT,traits>& + operator<< (std::basic_ostream<charT,traits>& os, error_code ec) + { + os << ec.category().name() << ':' << ec.value(); + return os; + } + + inline std::size_t hash_value( const error_code & ec ) + { + return static_cast<std::size_t>(ec.value()) + + reinterpret_cast<std::size_t>(&ec.category()); + } + + // make_* functions for errc::errc_t -----------------------------// + + namespace errc + { + // explicit conversion: + inline error_code make_error_code( errc_t e ) + { return error_code( e, get_generic_category() ); } + + // implicit conversion: + inline error_condition make_error_condition( errc_t e ) + { return error_condition( e, get_generic_category() ); } + } + + // error_category default implementation -------------------------------// + + inline error_condition error_category::default_error_condition( int ev ) const + { + return error_condition( ev, *this ); + } + + inline bool error_category::equivalent( int code, + const error_condition & condition ) const + { + return default_error_condition( code ) == condition; + } + + inline bool error_category::equivalent( const error_code & code, + int condition ) const + { + return *this == code.category() && code.value() == condition; + } + + // error_category implementation note: VC++ 8.0 objects to name() and + // message() being pure virtual functions. Thus these implementations. + inline const char * error_category::name() const + { + return "error: should never be called"; + } + + inline std::string error_category::message( int ) const + { + static std::string s("error: should never be called"); + return s; + } + + } // namespace system +} // namespace boost + +//#include <boost/config/abi_suffix.hpp> // pops abi_prefix.hpp pragmas + +# ifdef BOOST_ERROR_CODE_HEADER_ONLY +# include <boost/../libs/system/src/error_code.cpp> +# endif + +#endif // BOOST_ERROR_CODE_HPP + + diff --git a/ThirdParty/NRLib/boost/system/linux_error.hpp b/ThirdParty/NRLib/boost/system/linux_error.hpp new file mode 100644 index 0000000000..9be4fbd1cb --- /dev/null +++ b/ThirdParty/NRLib/boost/system/linux_error.hpp @@ -0,0 +1,110 @@ +// boost/system/linux_error.hpp -------------------------------------------// + +// Copyright Beman Dawes 2007 + +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See library home page at http://www.boost.org/libs/system + +#ifndef BOOST_LINUX_ERROR_HPP +#define BOOST_LINUX_ERROR_HPP + +// This header is effectively empty for compiles on operating systems where +// it is not applicable. + +#if defined(linux) || defined(__linux) || defined(__linux__) + +#include <boost/system/error_code.hpp> + +namespace boost +{ + namespace system + { + // To construct an error_code after a API error: + // + // error_code( errno, system_category ) + + // User code should use the portable "posix" enums for POSIX errors; this + // allows such code to be portable to non-POSIX systems. For the non-POSIX + // errno values that POSIX-based systems typically provide in addition to + // POSIX values, use the system specific enums below. + + namespace linux_error + { + enum linux_errno + { + advertise_error = EADV, + bad_exchange = EBADE, + bad_file_number = EBADFD, + bad_font_format = EBFONT, + bad_request_code = EBADRQC, + bad_request_descriptor = EBADR, + bad_slot = EBADSLT, + channel_range = ECHRNG, + communication_error = ECOMM, + dot_dot_error = EDOTDOT, + exchange_full = EXFULL, + host_down = EHOSTDOWN, + is_named_file_type= EISNAM, + key_expired = EKEYEXPIRED, + key_rejected = EKEYREJECTED, + key_revoked = EKEYREVOKED, + level2_halt= EL2HLT, + level2_no_syncronized= EL2NSYNC, + level3_halt = EL3HLT, + level3_reset = EL3RST, + link_range = ELNRNG, + medium_type = EMEDIUMTYPE, + no_anode= ENOANO, + no_block_device = ENOTBLK, + no_csi = ENOCSI, + no_key = ENOKEY, + no_medium = ENOMEDIUM, + no_network = ENONET, + no_package = ENOPKG, + not_avail = ENAVAIL, + not_named_file_type= ENOTNAM, + not_recoverable = ENOTRECOVERABLE, + not_unique = ENOTUNIQ, + owner_dead = EOWNERDEAD, + protocol_no_supported = EPFNOSUPPORT, + remote_address_changed = EREMCHG, + remote_io_error = EREMOTEIO, + remote_object = EREMOTE, + restart_needed = ERESTART, + shared_library_access = ELIBACC, + shared_library_bad = ELIBBAD, + shared_library_execute = ELIBEXEC, + shared_library_max_ = ELIBMAX, + shared_library_section= ELIBSCN, + shutdown = ESHUTDOWN, + socket_type_not_supported = ESOCKTNOSUPPORT, + srmount_error = ESRMNT, + stream_pipe_error = ESTRPIPE, + too_many_references = ETOOMANYREFS, + too_many_users = EUSERS, + unattached = EUNATCH, + unclean = EUCLEAN + }; + } // namespace linux_error + +# ifndef BOOST_SYSTEM_NO_DEPRECATED + namespace Linux = linux_error; +# endif + + template<> struct is_error_code_enum<linux_error::linux_errno> + { static const bool value = true; }; + + namespace linux_error + { + inline error_code make_error_code( linux_errno e ) + { return error_code( e, get_system_category() ); } + } + + } // namespace system +} // namespace boost + +#endif // Linux + +#endif // BOOST_LINUX_ERROR_HPP diff --git a/ThirdParty/NRLib/boost/system/module.mk b/ThirdParty/NRLib/boost/system/module.mk new file mode 100644 index 0000000000..d8d090c79a --- /dev/null +++ b/ThirdParty/NRLib/boost/system/module.mk @@ -0,0 +1 @@ +SRC += system/error_code.cpp diff --git a/ThirdParty/NRLib/boost/system/system_error.hpp b/ThirdParty/NRLib/boost/system/system_error.hpp new file mode 100644 index 0000000000..4091647352 --- /dev/null +++ b/ThirdParty/NRLib/boost/system/system_error.hpp @@ -0,0 +1,81 @@ +// Boost system_error.hpp --------------------------------------------------// + +// Copyright Beman Dawes 2006 + +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_SYSTEM_ERROR_HPP +#define BOOST_SYSTEM_ERROR_HPP + +#include <string> +#include <stdexcept> +#include <cassert> +#include <boost/system/error_code.hpp> + +namespace boost +{ + namespace system + { + // class system_error --------------------------------------------------// + + class system_error : public std::runtime_error + { + public: + system_error( error_code ec ) + : std::runtime_error(""), m_error_code(ec) {} + + system_error( error_code ec, const std::string & what_arg ) + : std::runtime_error(what_arg), m_error_code(ec) {} + + system_error( error_code ec, const char* what_arg ) + : std::runtime_error(what_arg), m_error_code(ec) {} + + system_error( int ev, const error_category & ecat ) + : std::runtime_error(""), m_error_code(ev,ecat) {} + + system_error( int ev, const error_category & ecat, + const std::string & what_arg ) + : std::runtime_error(what_arg), m_error_code(ev,ecat) {} + + system_error( int ev, const error_category & ecat, + const char * what_arg ) + : std::runtime_error(what_arg), m_error_code(ev,ecat) {} + + virtual ~system_error() throw() {} + + const error_code & code() const throw() { return m_error_code; } + const char * what() const throw(); + + private: + error_code m_error_code; + mutable std::string m_what; + }; + + // implementation ------------------------------------------------------// + + inline const char * system_error::what() const throw() + // see http://www.boost.org/more/error_handling.html for lazy build rationale + { + if ( m_what.empty() ) + { + try + { + m_what = this->std::runtime_error::what(); + if ( m_error_code ) + { + if ( !m_what.empty() ) m_what += ": "; + m_what += m_error_code.message(); + } + } + catch (...) { return std::runtime_error::what(); } + } + return m_what.c_str(); + } + + } // namespace system +} // namespace boost + +#endif // BOOST_SYSTEM_ERROR_HPP + + diff --git a/ThirdParty/NRLib/boost/system/windows_error.hpp b/ThirdParty/NRLib/boost/system/windows_error.hpp new file mode 100644 index 0000000000..b6d2f0ffc2 --- /dev/null +++ b/ThirdParty/NRLib/boost/system/windows_error.hpp @@ -0,0 +1,118 @@ +// boost/system/windows_error.hpp ------------------------------------------// + +// Copyright Beman Dawes 2007 + +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See library home page at http://www.boost.org/libs/system + +#ifndef BOOST_WINDOWS_ERROR_HPP +#define BOOST_WINDOWS_ERROR_HPP + +// This header is effectively empty for compiles on operating systems where +// it is not applicable. + +#include <boost/system/config.hpp> + +#ifdef BOOST_WINDOWS_API + +#include <boost/system/error_code.hpp> +#include <winerror.h> + +namespace boost +{ + namespace system + { + + // Microsoft Windows ---------------------------------------------------// + + // To construct an error_code after a API error: + // + // error_code( ::GetLastError(), system_category ) + + namespace windows_error + { + enum windows_error_code + { + success = 0, + // These names and values are based on Windows winerror.h + invalid_function = ERROR_INVALID_FUNCTION, + file_not_found = ERROR_FILE_NOT_FOUND, + path_not_found = ERROR_PATH_NOT_FOUND, + too_many_open_files = ERROR_TOO_MANY_OPEN_FILES, + access_denied = ERROR_ACCESS_DENIED, + invalid_handle = ERROR_INVALID_HANDLE, + arena_trashed = ERROR_ARENA_TRASHED, + not_enough_memory = ERROR_NOT_ENOUGH_MEMORY, + invalid_block = ERROR_INVALID_BLOCK, + bad_environment = ERROR_BAD_ENVIRONMENT, + bad_format = ERROR_BAD_FORMAT, + invalid_access = ERROR_INVALID_ACCESS, + outofmemory = ERROR_OUTOFMEMORY, + invalid_drive = ERROR_INVALID_DRIVE, + current_directory = ERROR_CURRENT_DIRECTORY, + not_same_device = ERROR_NOT_SAME_DEVICE, + no_more_files = ERROR_NO_MORE_FILES, + write_protect = ERROR_WRITE_PROTECT, + bad_unit = ERROR_BAD_UNIT, + not_ready = ERROR_NOT_READY, + bad_command = ERROR_BAD_COMMAND, + crc = ERROR_CRC, + bad_length = ERROR_BAD_LENGTH, + seek = ERROR_SEEK, + not_dos_disk = ERROR_NOT_DOS_DISK, + sector_not_found = ERROR_SECTOR_NOT_FOUND, + out_of_paper = ERROR_OUT_OF_PAPER, + write_fault = ERROR_WRITE_FAULT, + read_fault = ERROR_READ_FAULT, + gen_failure = ERROR_GEN_FAILURE, + sharing_violation = ERROR_SHARING_VIOLATION, + lock_violation = ERROR_LOCK_VIOLATION, + wrong_disk = ERROR_WRONG_DISK, + sharing_buffer_exceeded = ERROR_SHARING_BUFFER_EXCEEDED, + handle_eof = ERROR_HANDLE_EOF, + handle_disk_full= ERROR_HANDLE_DISK_FULL, + rem_not_list = ERROR_REM_NOT_LIST, + dup_name = ERROR_DUP_NAME, + bad_net_path = ERROR_BAD_NETPATH, + network_busy = ERROR_NETWORK_BUSY, + // ... + file_exists = ERROR_FILE_EXISTS, + cannot_make = ERROR_CANNOT_MAKE, + // ... + broken_pipe = ERROR_BROKEN_PIPE, + open_failed = ERROR_OPEN_FAILED, + buffer_overflow = ERROR_BUFFER_OVERFLOW, + disk_full= ERROR_DISK_FULL, + // ... + lock_failed = ERROR_LOCK_FAILED, + busy = ERROR_BUSY, + cancel_violation = ERROR_CANCEL_VIOLATION, + already_exists = ERROR_ALREADY_EXISTS + // ... + + // TODO: add more Windows errors + }; + + } // namespace windows + +# ifndef BOOST_SYSTEM_NO_DEPRECATED + namespace windows = windows_error; +# endif + + template<> struct is_error_code_enum<windows_error::windows_error_code> + { static const bool value = true; }; + + namespace windows_error + { + inline error_code make_error_code( windows_error_code e ) + { return error_code( e, get_system_category() ); } + } + + } // namespace system +} // namespace boost + +#endif // BOOST_WINDOWS_API + +#endif // BOOST_WINDOWS_ERROR_HPP diff --git a/ThirdParty/NRLib/nrlib/exception/exception.hpp b/ThirdParty/NRLib/nrlib/exception/exception.hpp new file mode 100644 index 0000000000..3580641760 --- /dev/null +++ b/ThirdParty/NRLib/nrlib/exception/exception.hpp @@ -0,0 +1,99 @@ +// $Id: exception.hpp 1107 2012-11-06 08:40:41Z perroe $ + +// Copyright (c) 2011, Norwegian Computing Center +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// • Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// • Redistributions in binary form must reproduce the above copyright notice, this list of +// conditions and the following disclaimer in the documentation and/or other materials +// provided with the distribution. +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT +// SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef NRLIB_EXCEPTION_HPP +#define NRLIB_EXCEPTION_HPP + +#include <exception> +#include <string> + +//Test: Information flows from external back to original? +//Test: And of course it flows downwards? + +namespace NRLib { + +class Exception : public std::exception +{ +public: + explicit Exception(const std::string& msg = "") : msg_(msg) { } + virtual ~Exception() throw() {} + virtual const char * what() const throw() {return msg_.c_str();} +private: + std::string msg_; +}; + +class IndexOutOfRange : public Exception +{ +public: + explicit IndexOutOfRange(const std::string& msg = "") + : Exception(msg) {} + + virtual ~IndexOutOfRange() throw() {} +}; + +class FFTError : public Exception +{ +public: + explicit FFTError(const std::string& msg = "") + : Exception(msg) {} + + virtual ~FFTError() throw() {} +}; + +class IOError : public Exception +{ +public: + explicit IOError(const std::string& msg = "") + : Exception(msg) {} + + virtual ~IOError() throw() {} +}; + +class FileFormatError : public IOError +{ +public: + explicit FileFormatError(const std::string& msg = "") + : IOError(msg) {} + + virtual ~FileFormatError() throw() {} +}; + +class EndOfFile : public IOError +{ +public: + explicit EndOfFile(const std::string& msg = "") + : IOError(msg) {} + + virtual ~EndOfFile() throw() {} +}; + +class JobCanceled : public Exception +{ +public: + explicit JobCanceled(const std::string& msg = "") + : Exception(msg) {} + + virtual ~JobCanceled() throw() {} +}; + +} + +#endif diff --git a/ThirdParty/NRLib/nrlib/grid/grid.hpp b/ThirdParty/NRLib/nrlib/grid/grid.hpp new file mode 100644 index 0000000000..74af04d0eb --- /dev/null +++ b/ThirdParty/NRLib/nrlib/grid/grid.hpp @@ -0,0 +1,271 @@ +// $Id: grid.hpp 882 2011-09-23 13:10:16Z perroe $ + +// Copyright (c) 2011, Norwegian Computing Center +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// • Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// • Redistributions in binary form must reproduce the above copyright notice, this list of +// conditions and the following disclaimer in the documentation and/or other materials +// provided with the distribution. +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT +// SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef NRLIB_GRID_HPP +#define NRLIB_GRID_HPP + +#include <cassert> +#include <sstream> +#include <vector> +#include <limits> + +//#include "../../../src/definitions.h" + +namespace NRLib { + +template<class A> +class Grid { +public: + typedef typename std::vector<A>::iterator iterator; + typedef typename std::vector<A>::const_iterator const_iterator; + typedef typename std::vector<A>::reference reference; + typedef typename std::vector<A>::const_reference const_reference; + + Grid(); + /// \param val Initial cell value. + Grid(size_t ni, size_t nj, size_t nk, const A& val = A()); + virtual ~Grid(); + + /// All values in the grid are erased when the grid is + /// resized. + /// \param val Initial cell value. + void Resize(size_t ni, size_t nj, size_t nk, const A& val = A()); + void GetAvgMinMax(A& avg, A& min, A& max); + void GetAvgMinMaxWithMissing(A& avg, A& min, A& max, A missing); + void LogTransform(A missing); + + inline reference operator()(size_t i, size_t j, size_t k); + inline reference operator()(size_t index); + inline reference GetValue(size_t i, size_t j, size_t k); + + inline const_reference operator()(size_t i, size_t j, size_t k) const; + inline const_reference operator()(size_t index) const; + inline const_reference GetValue(size_t i, size_t j, size_t k) const; + + iterator begin() {return( data_.begin()); } + iterator end() {return( data_.end()); } + + const_iterator begin() const { return(data_.begin()); } + const_iterator end() const { return(data_.end()); } + + size_t GetNI() const { return(ni_); } + size_t GetNJ() const { return(nj_); } + size_t GetNK() const { return(nk_); } + size_t GetN() const { return data_.size(); } + + inline size_t GetIndex(size_t i, size_t j, size_t k) const; + void GetIJK(size_t index, size_t &i, size_t &j, size_t &k) const; + void SetValue(size_t i, size_t j, size_t k, const A& value); + + void Swap(Grid<A>& other); + +private: + size_t ni_; + size_t nj_; + size_t nk_; + + /// The grid data, column-major ordering. + std::vector<A> data_; +}; + +template<class A> +Grid<A>::Grid() + : ni_(0), + nj_(0), + nk_(0), + data_() +{} + +template<class A> +Grid<A>::Grid(size_t ni, size_t nj, size_t nk, const A& val) + : ni_(ni), + nj_(nj), + nk_(nk), + data_(ni*nj*nk, val) +{} + +template<class A> +Grid<A>::~Grid() +{} + +template<class A> +void Grid<A>::Resize(size_t ni, size_t nj, size_t nk, const A& val) +{ + ni_ = ni; + nj_ = nj; + nk_ = nk; + + data_.resize(0); //To avoid copying of elements + data_.resize(ni_ * nj_ * nk_, val); +} + +template<class A> +void Grid<A>::GetAvgMinMax(A& avg, A& min, A& max) +{ + A sum = 0.0; + A value = 0.0; + max = -std::numeric_limits<A>::infinity(); + min = +std::numeric_limits<A>::infinity(); + + for(unsigned int i = 0; i < ni_; i++) { + for(unsigned int j = 0; j < nj_; j++) { + for(unsigned int k = 0; k < nk_; k++) { + value = data_[GetIndex(i, j, k)]; + sum += value; + + if(value > max) + max = value; + + if(value < min) + min = value; + + } + } + } + avg = sum /= GetN(); +} + +template<class A> +void Grid<A>::GetAvgMinMaxWithMissing(A& avg, A& min, A& max, A missing) +{ + A sum = 0.0; + A value = 0.0; + max = -std::numeric_limits<A>::infinity(); + min = +std::numeric_limits<A>::infinity(); + + unsigned int n = 0; + for(unsigned int i = 0; i < ni_; i++) { + for(unsigned int j = 0; j < nj_; j++) { + for(unsigned int k = 0; k < nk_; k++) { + value = data_[GetIndex(i, j, k)]; + if(value != missing) { + sum += value; + n++; + if(value > max) + max = value; + + if(value < min) + min = value; + } + } + } + } + avg = sum/static_cast<A>(n); +} + +template<class A> +void Grid<A>::LogTransform(A missing) +{ + for(size_t i = 0; i < ni_; i++) { + for(size_t j = 0; j < nj_; j++) { + for(size_t k = 0; k < nk_; k++) { + A value = data_[GetIndex(i, j, k)]; + if(value == missing || value <= 0.0) //First RMISSING + data_[GetIndex(i, j, k)] = 0.0; + else + data_[GetIndex(i, j, k)] = log(value); + } + } + } +} + +template<class A> +typename Grid<A>::reference Grid<A>::operator()(size_t i, size_t j, size_t k) +{ + return data_[GetIndex(i, j, k)]; +} + +template<class A> +typename Grid<A>::reference Grid<A>::operator()(size_t index) +{ + assert(index < GetN()); + + return data_[index]; +} + +template<class A> +typename Grid<A>::reference Grid<A>::GetValue(size_t i, size_t j, size_t k) +{ + return data_[GetIndex(i, j, k)]; +} + +template<class A> +typename Grid<A>::const_reference Grid<A>::operator()(size_t i, size_t j, size_t k) const +{ + return data_[GetIndex(i, j, k)]; +} + +template<class A> +typename Grid<A>::const_reference Grid<A>::operator()(size_t index) const +{ + assert(index < GetN()); + + return data_[index]; +} + +template<class A> +typename Grid<A>::const_reference Grid<A>::GetValue(size_t i, size_t j, size_t k) const +{ + return data_[GetIndex(i, j, k)]; +} + +template<class A> +size_t Grid<A>::GetIndex(size_t i, size_t j, size_t k) const +{ + assert(i < GetNI() && j < GetNJ() && k < GetNK()); + + return i + j*ni_ + k*ni_*nj_; +} + +template<class A> +void Grid<A>::GetIJK(size_t index, size_t &i, size_t &j, size_t &k) const +{ + assert(index < GetN()); + + i = index % ni_; + j = (index-i)/ni_ % nj_; + k = (index - j*ni_ - i)/ni_/nj_; +} + +template<class A> +void Grid<A>::SetValue(size_t i, size_t j, size_t k, const A& value) +{ + data_[GetIndex(i, j, k)] = value; +} + +template<class A> +void Grid<A>::Swap(NRLib::Grid<A> &other) +{ + std::swap(ni_, other.ni_); + std::swap(nj_, other.nj_); + std::swap(nk_, other.nk_); + data_.swap(other.data_); +} + +} +#endif + + + + + + + diff --git a/ThirdParty/NRLib/nrlib/grid/grid2d.hpp b/ThirdParty/NRLib/nrlib/grid/grid2d.hpp new file mode 100644 index 0000000000..6f661c9d4f --- /dev/null +++ b/ThirdParty/NRLib/nrlib/grid/grid2d.hpp @@ -0,0 +1,207 @@ +// $Id: grid2d.hpp 882 2011-09-23 13:10:16Z perroe $ + +// Copyright (c) 2011, Norwegian Computing Center +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// • Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// • Redistributions in binary form must reproduce the above copyright notice, this list of +// conditions and the following disclaimer in the documentation and/or other materials +// provided with the distribution. +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT +// SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef NRLIB_GRID2D_HPP +#define NRLIB_GRID2D_HPP + +#include <cassert> +#include <sstream> +#include <vector> + +namespace NRLib { + +template<class A> +class Grid2D { +public: + typedef typename std::vector<A>::iterator iterator; + typedef typename std::vector<A>::const_iterator const_iterator; + typedef typename std::vector<A>::reference reference; + typedef typename std::vector<A>::const_reference const_reference; + + Grid2D(); + /// \param val Initial cell value. + Grid2D(size_t ni, size_t nj, const A& val = A()); + virtual ~Grid2D(); + + /// All values in the grid are erased when the grid is + /// resized. + /// \param val Initial cell value. + virtual void Resize(size_t ni, size_t nj, const A& val = A()); + + inline reference operator()(size_t i, size_t j); + inline reference operator()(size_t index); + + inline const_reference operator()(size_t i, size_t j) const; + inline const_reference operator()(size_t index) const; + + iterator begin() { return data_.begin(); } + iterator end() { return data_.end(); } + + const_iterator begin() const { return data_.begin(); } + const_iterator end() const { return data_.end(); } + + size_t GetNI() const { return ni_; } + size_t GetNJ() const { return nj_; } + size_t GetN() const { return data_.size(); } + + inline size_t GetIndex(size_t i, size_t j) const; + void GetIJ(size_t index, size_t &i, size_t &j) const; + + bool IsValidIndex(int i, int j) const; + + void Swap(Grid2D<A>& other); + + A FindMin(A missingValue) const; + A FindMax(A missingValue) const; + +private: + size_t ni_; + size_t nj_; + /// The grid data, column-major ordering. + std::vector<A> data_; +}; + +template<class A> +Grid2D<A>::Grid2D() + : ni_(0), + nj_(0), + data_() +{} + +template<class A> +Grid2D<A>::Grid2D(size_t ni, size_t nj, const A& val) + : ni_(ni), + nj_(nj), + data_(ni*nj, val) +{} + +template<class A> +Grid2D<A>::~Grid2D() +{} + +template<class A> +void Grid2D<A>::Resize(size_t ni, size_t nj, const A& val) +{ + ni_ = ni; + nj_ = nj; + + data_.resize(0); //To avoid copying of elements + data_.resize(ni_ * nj_, val); +} + + +template<class A> +typename Grid2D<A>::reference Grid2D<A>::operator()(size_t i, size_t j) +{ + return(data_[GetIndex(i, j)]); +} + + +template<class A> +typename Grid2D<A>::reference Grid2D<A>::operator()(size_t index) +{ + assert(index < GetN()); + + return(data_[index]); +} + + +template<class A> +typename Grid2D<A>::const_reference Grid2D<A>::operator()(size_t i, size_t j) const +{ + return(data_[GetIndex(i, j)]); +} + + +template<class A> +typename Grid2D<A>::const_reference Grid2D<A>::operator()(size_t index) const +{ + assert(index < GetN()); + + return(data_[index]); +} + + +template<class A> +size_t Grid2D<A>::GetIndex(size_t i, size_t j) const +{ + assert(i < ni_); + assert(j < nj_); + + return(i+j*ni_); +} + +template<class A> +void Grid2D<A>::GetIJ(size_t index, size_t &i, size_t &j) const +{ + assert (index < GetN()); + + i = (index % ni_); + j = ((index-i)/ni_ % nj_); +} + + +template<class A> +bool Grid2D<A>::IsValidIndex(int i, int j) const +{ + if (i >= 0 && static_cast<size_t>(i) < ni_ && + j >= 0 && static_cast<size_t>(j) < nj_) + return true; + + return false; +} + + +template<class A> +void Grid2D<A>::Swap(NRLib::Grid2D<A> &other) +{ + std::swap(ni_, other.ni_); + std::swap(nj_, other.nj_); + data_.swap(other.data_); +} + +template<class A> +A Grid2D<A>::FindMin(A missingValue) const +{ + A minVal = (*this)(0); + typename std::vector<A>::const_iterator i; + for (i = this->begin(); i < this->end(); i++) { + if ((minVal == missingValue || (*i) < minVal) && (*i) != missingValue) + minVal = *i; + } + return minVal; +} + +template<class A> +A Grid2D<A>::FindMax(A missingValue) const +{ + A maxVal = (*this)(0); + typename std::vector<A>::const_iterator i; + for (i = this->begin(); i < this->end(); i++) { + if ((maxVal == missingValue || (*i) > maxVal) && (*i) != missingValue) + maxVal = *i; + } + return maxVal; +} + +} // namespace NRLib + +#endif // NRLIB_GRID2D_HPP diff --git a/ThirdParty/NRLib/nrlib/grid/grid4d.hpp b/ThirdParty/NRLib/nrlib/grid/grid4d.hpp new file mode 100644 index 0000000000..58929f72f3 --- /dev/null +++ b/ThirdParty/NRLib/nrlib/grid/grid4d.hpp @@ -0,0 +1,186 @@ +// $Id: grid4d.hpp 1142 2013-03-18 15:13:41Z hgolsen $ + +// Copyright (c) 2011, Norwegian Computing Center +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// • Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// • Redistributions in binary form must reproduce the above copyright notice, this list of +// conditions and the following disclaimer in the documentation and/or other materials +// provided with the distribution. +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT +// SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef NRLIB_GRID4D_HPP +#define NRLIB_GRID4D_HPP + +#include <cassert> +#include <sstream> +#include <vector> + +namespace NRLib { + +template<class A> +class Grid4D { +public: + typedef typename std::vector<A>::iterator iterator; + typedef typename std::vector<A>::const_iterator const_iterator; + typedef typename std::vector<A>::reference reference; + typedef typename std::vector<A>::const_reference const_reference; + + Grid4D(); + /// \param val Initial cell value. + Grid4D(size_t ni, size_t nj, size_t nk, size_t nl, const A& val = A()); + virtual ~Grid4D(); + + /// All values in the grid are erased when the grid is + /// resized. + /// \param val Initial cell value. + void Resize(size_t ni, size_t nj, size_t nk, size_t nl, const A& val = A()); + + inline reference operator()(size_t i, size_t j, size_t k, size_t l); + inline reference operator()(size_t index); + + inline const_reference operator()(size_t i, size_t j, size_t k, size_t l) const; + inline const_reference operator()(size_t index) const; + + iterator begin() {return( data_.begin()); } + iterator end() {return( data_.end()); } + + const_iterator begin() const { return(data_.begin()); } + const_iterator end() const { return(data_.end()); } + + size_t GetNI() const { return(ni_); } + size_t GetNJ() const { return(nj_); } + size_t GetNK() const { return(nk_); } + size_t GetNL() const { return(nl_); } + size_t GetN() const { return data_.size(); } + + inline size_t GetIndex(size_t i, size_t j, size_t k, size_t l) const; + void GetIJKL(size_t index, size_t &i, size_t &j, size_t &k, size_t &l) const; + + void Swap(Grid4D<A>& other); + +private: + size_t ni_; + size_t nj_; + size_t nk_; + size_t nl_; + + /// The grid data, column-major ordering. + std::vector<A> data_; +}; + +template<class A> +Grid4D<A>::Grid4D() + : ni_(0), + nj_(0), + nk_(0), + nl_(0), + data_() +{} + +template<class A> +Grid4D<A>::Grid4D(size_t ni, size_t nj, size_t nk, size_t nl, const A& val) + : ni_(ni), + nj_(nj), + nk_(nk), + nl_(nl), + data_(ni*nj*nk*nl, val) +{} + +template<class A> +Grid4D<A>::~Grid4D() +{} + +template<class A> +void Grid4D<A>::Resize(size_t ni, size_t nj, size_t nk, size_t nl, const A& val) +{ + ni_ = ni; + nj_ = nj; + nk_ = nk; + nl_ = nl; + + data_.resize(0); //To avoid copying of elements + data_.resize(ni_ * nj_ * nk_ * nl, val); +} + + +template<class A> +typename Grid4D<A>::reference Grid4D<A>::operator()(size_t i, size_t j, size_t k, size_t l) +{ + return data_[GetIndex(i, j, k, l)]; +} + + +template<class A> +typename Grid4D<A>::reference Grid4D<A>::operator()(size_t index) +{ + assert(index < GetN()); + + return data_[index]; +} + + +template<class A> +typename Grid4D<A>::const_reference Grid4D<A>::operator()(size_t i, size_t j, size_t k, size_t l) const +{ + return data_[GetIndex(i, j, k, l)]; +} + + +template<class A> +typename Grid4D<A>::const_reference Grid4D<A>::operator()(size_t index) const +{ + assert(index < GetN()); + + return data_[index]; +} + + +template<class A> +size_t Grid4D<A>::GetIndex(size_t i, size_t j, size_t k, size_t l) const +{ + assert(i < GetNI() && j < GetNJ() && k < GetNK() && l < GetNL()); + + return i + j*ni_ + k*ni_*nj_ + l*ni_*nj_*nk_; +} + +template<class A> +void Grid4D<A>::GetIJKL(size_t index, size_t &i, size_t &j, size_t &k, size_t &l) const +{ + assert(index < GetN()); + + i = index % ni_; + j = (index-i)/ni_ % nj_; + k = (index - j*ni_ - i)/ni_/nj_; + l = (index - k*ni_*nj_)/ni_/nj_/nk_; //? +} + +template<class A> +void Grid4D<A>::Swap(NRLib::Grid4D<A> &other) +{ + std::swap(ni_, other.ni_); + std::swap(nj_, other.nj_); + std::swap(nk_, other.nk_); + std::swap(nl_, other.nl_); + data_.swap(other.data_); +} + +} +#endif + + + + + + + diff --git a/ThirdParty/NRLib/nrlib/grid/grid5d.hpp b/ThirdParty/NRLib/nrlib/grid/grid5d.hpp new file mode 100644 index 0000000000..55db834a7a --- /dev/null +++ b/ThirdParty/NRLib/nrlib/grid/grid5d.hpp @@ -0,0 +1,193 @@ +// $Id: grid5d.hpp 1142 2013-03-18 15:13:41Z hgolsen $ + +// Copyright (c) 2011, Norwegian Computing Center +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// • Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// • Redistributions in binary form must reproduce the above copyright notice, this list of +// conditions and the following disclaimer in the documentation and/or other materials +// provided with the distribution. +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT +// SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef NRLIB_GRID5D_HPP +#define NRLIB_GRID5D_HPP + +#include <cassert> +#include <sstream> +#include <vector> + +namespace NRLib { + +template<class A> +class Grid5D { +public: + typedef typename std::vector<A>::iterator iterator; + typedef typename std::vector<A>::const_iterator const_iterator; + typedef typename std::vector<A>::reference reference; + typedef typename std::vector<A>::const_reference const_reference; + + Grid5D(); + /// \param val Initial cell value. + Grid5D(size_t ni, size_t nj, size_t nk, size_t nl, size_t nm, const A& val = A()); + virtual ~Grid5D(); + + /// All values in the grid are erased when the grid is + /// resized. + /// \param val Initial cell value. + void Resize(size_t ni, size_t nj, size_t nk, size_t nl, size_t nm, const A& val = A()); + + inline reference operator()(size_t i, size_t j, size_t k, size_t l, size_t m); + inline reference operator()(size_t index); + + inline const_reference operator()(size_t i, size_t j, size_t k, size_t l, size_t m) const; + inline const_reference operator()(size_t index) const; + + iterator begin() {return( data_.begin()); } + iterator end() {return( data_.end()); } + + const_iterator begin() const { return(data_.begin()); } + const_iterator end() const { return(data_.end()); } + + size_t GetNI() const { return(ni_); } + size_t GetNJ() const { return(nj_); } + size_t GetNK() const { return(nk_); } + size_t GetNL() const { return(nl_); } + size_t GetNM() const { return(nm_); } + size_t GetN() const { return data_.size(); } + + inline size_t GetIndex(size_t i, size_t j, size_t k, size_t l, size_t m) const; + void GetIJKLM(size_t index, size_t &i, size_t &j, size_t &k, size_t &l, size_t &m) const; + + void Swap(Grid5D<A>& other); + +private: + size_t ni_; + size_t nj_; + size_t nk_; + size_t nl_; + size_t nm_; + + /// The grid data, column-major ordering. + std::vector<A> data_; +}; + +template<class A> +Grid5D<A>::Grid5D() + : ni_(0), + nj_(0), + nk_(0), + nl_(0), + nm_(0), + data_() +{} + +template<class A> +Grid5D<A>::Grid5D(size_t ni, size_t nj, size_t nk, size_t nl, size_t nm, const A& val) + : ni_(ni), + nj_(nj), + nk_(nk), + nl_(nl), + nm_(nm), + data_(ni*nj*nk*nl*nm, val) +{} + +template<class A> +Grid5D<A>::~Grid5D() +{} + +template<class A> +void Grid5D<A>::Resize(size_t ni, size_t nj, size_t nk, size_t nl, size_t nm, const A& val) +{ + ni_ = ni; + nj_ = nj; + nk_ = nk; + nl_ = nl; + nm_ = nm + + data_.resize(0); //To avoid copying of elements + data_.resize(ni_ * nj_ * nk_ * nl * nm, val); +} + + +template<class A> +typename Grid5D<A>::reference Grid5D<A>::operator()(size_t i, size_t j, size_t k, size_t l, size_t m) +{ + return data_[GetIndex(i, j, k, l, m)]; +} + + +template<class A> +typename Grid5D<A>::reference Grid5D<A>::operator()(size_t index) +{ + assert(index < GetN()); + + return data_[index]; +} + + +template<class A> +typename Grid5D<A>::const_reference Grid5D<A>::operator()(size_t i, size_t j, size_t k, size_t l, size_t m) const +{ + return data_[GetIndex(i, j, k, l, m)]; +} + + +template<class A> +typename Grid5D<A>::const_reference Grid5D<A>::operator()(size_t index) const +{ + assert(index < GetN()); + + return data_[index]; +} + + +template<class A> +size_t Grid5D<A>::GetIndex(size_t i, size_t j, size_t k, size_t l, size_t m) const +{ + assert(i < GetNI() && j < GetNJ() && k < GetNK() && l < GetNL() && m < GetNM()); + + return i + j*ni_ + k*ni_*nj_ + l*ni_*nj_*nk_ + m*ni_*nj_*nk_*nl_; +} + +template<class A> +void Grid5D<A>::GetIJKLM(size_t index, size_t &i, size_t &j, size_t &k, size_t &l, size_t &m) const +{ + assert(index < GetN()); + + i = index % ni_; + j = (index-i)/ni_ % nj_; + k = (index - j*ni_ - i)/ni_/nj_; + l = (index - k*ni_*nj_)/ni_/nj_/nk_; //? + m = (index - m*ni_*nj_*nk_)/ni_/nj_/nk_/nl_; //? +} + +template<class A> +void Grid5D<A>::Swap(NRLib::Grid5D<A> &other) +{ + std::swap(ni_, other.ni_); + std::swap(nj_, other.nj_); + std::swap(nk_, other.nk_); + std::swap(nl_, other.nl_); + std::swap(nm_, other.nm_); + data_.swap(other.data_); +} + +} +#endif + + + + + + + diff --git a/ThirdParty/NRLib/nrlib/grid/module.mk b/ThirdParty/NRLib/nrlib/grid/module.mk new file mode 100644 index 0000000000..d6d908e733 --- /dev/null +++ b/ThirdParty/NRLib/nrlib/grid/module.mk @@ -0,0 +1 @@ +SRC += diff --git a/ThirdParty/NRLib/nrlib/iotools/fileio.cpp b/ThirdParty/NRLib/nrlib/iotools/fileio.cpp new file mode 100644 index 0000000000..609ddda984 --- /dev/null +++ b/ThirdParty/NRLib/nrlib/iotools/fileio.cpp @@ -0,0 +1,733 @@ +//$Id: fileio.cpp 1068 2012-09-18 11:21:53Z perroe $ + +// Copyright (c) 2011, Norwegian Computing Center +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// • Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// • Redistributions in binary form must reproduce the above copyright notice, this list of +// conditions and the following disclaimer in the documentation and/or other materials +// provided with the distribution. +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT +// SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include "fileio.hpp" + +#include "../exception/exception.hpp" +#include "stringtools.hpp" + +#define BOOST_FILESYSTEM_VERSION 2 +#include <boost/filesystem.hpp> + +#include <fstream> +#include <iostream> +#include <locale> +#include <sstream> +#include <string> + +using namespace NRLib::NRLibPrivate; +using namespace NRLib; + +const std::string format_desc[5] = {"storm_petro_binary", + "storm_petro_ascii", + "storm_facies_binary", + "storm_facies_ascii", + "NORSAR"}; + + +void NRLib::OpenRead(std::ifstream& stream, + const std::string& filename, + std::ios_base::openmode mode) +{ + namespace fs = boost::filesystem; + + try { + boost::filesystem::path file_path(filename); + if (!fs::exists(file_path)) { + throw IOError("Failed to open " + file_path.file_string() + " for reading: " + + "File does not exist."); + } + if (fs::is_directory(file_path)) { + throw IOError("Failed to open " + file_path.file_string() + " for reading: " + + " It is a directory."); + } + stream.open(file_path.file_string().c_str(), mode); + if (!stream) { + throw IOError("Failed to open " + file_path.file_string() + " for reading."); + } + } + catch (fs::filesystem_error& e) { + throw IOError("Failed to open " + filename + " for reading: " + e.what()); + } +} + + +void NRLib::OpenRead(std::fstream& stream, + const std::string& filename, + std::ios_base::openmode mode) +{ + namespace fs = boost::filesystem; + + try { + boost::filesystem::path file_path(filename); + if (!fs::exists(file_path)) { + throw IOError("Failed to open " + file_path.file_string() + " for reading: " + + "File does not exist."); + } + if (fs::is_directory(file_path)) { + throw IOError("Failed to open " + file_path.file_string() + " for reading: " + + " It is a directory."); + } + stream.open(file_path.file_string().c_str(), mode); + if (!stream) { + throw IOError("Failed to open " + file_path.file_string() + " for reading."); + } + } + catch (fs::filesystem_error& e) { + throw IOError("Failed to open " + filename + " for reading: " + e.what()); + } +} + + +void NRLib::OpenWrite(std::ofstream& stream, + const std::string& filename, + std::ios_base::openmode mode, + bool create_dir) +{ + namespace fs = boost::filesystem; + try { + fs::path file_path(filename); + fs::path dir = file_path.parent_path(); + if (fs::is_directory(file_path)) { + throw IOError("Failed to open " + file_path.file_string() + " for writing: " + + " It is a directory."); + } + if (!dir.empty()) { + if (!fs::exists(dir) && create_dir) { + create_directories(dir); + } + else if (!fs::exists(dir)) { + throw IOError("Failed to open " + file_path.file_string() + " for writing: " + + "Parent directory does not exist."); + } + } + stream.open(file_path.file_string().c_str(), mode); + if (!stream) { + throw IOError("Failed to open " + file_path.file_string() + " for writing."); + } + } + catch (fs::filesystem_error& e) { + throw IOError("Failed to open " + filename + " for writing: " + e.what()); + } +} + + +void NRLib::OpenWrite(std::fstream& stream, + const std::string& filename, + std::ios_base::openmode mode, + bool create_dir) +{ + namespace fs = boost::filesystem; + try { + fs::path file_path(filename); + fs::path dir = file_path.parent_path(); + if (fs::is_directory(file_path)) { + throw IOError("Failed to open " + file_path.file_string() + " for writing: " + + " It is a directory."); + } + if (!dir.empty()) { + if (!fs::exists(dir) && create_dir) { + create_directories(dir); + } + else if (!fs::exists(dir)) { + throw IOError("Failed to open " + file_path.file_string() + " for writing: " + + "Parent directory does not exist."); + } + } + stream.open(file_path.file_string().c_str(), mode); + if (!stream) { + throw IOError("Failed to open " + file_path.file_string() + " for writing."); + } + } + catch (fs::filesystem_error& e) { + throw IOError("Failed to open " + filename + " for writing: " + e.what()); + } +} + + +void NRLib::CopyFile(const std::string & from_path, + const std::string & to_path, + bool allow_overwrite) +{ + if (allow_overwrite) + RemoveFile(to_path); + else { + if (boost::filesystem::exists(to_path)) + throw IOError("Failed to open " + to_path + " for writing: The file already exists."); + } + + boost::filesystem::copy_file(from_path, to_path); +} + + +void NRLib::RemoveFile(const std::string & filename) +{ + if (boost::filesystem::exists(filename)) + boost::filesystem::remove(filename); +} + + +bool NRLib::FileExists(const std::string & filename) +{ + return boost::filesystem::exists(filename); +} + + +void NRLib::CreateDirIfNotExists(const std::string & filename) +{ + namespace fs = boost::filesystem; + + fs::path file_path(filename); + fs::path dir = file_path.parent_path(); + if (!dir.empty()){ + if (!fs::exists(dir)) + create_directories(dir); + } +} + +std::istream& NRLib::ReadNextToken(std::istream & stream, + std::string & s, + int & line_num) +{ + std::locale loc = std::locale(); + char c; + if (!stream.good()) { + stream.setstate(std::ifstream::failbit); + s = ""; + return stream; + } + while(stream.get(c) && std::isspace(c,loc) == true ) { + if (c == '\n') + line_num++; + } + if (stream.good()) { + s = c; + while(stream.get(c) && std::isspace(c, loc) == false) { + s = s+c; + } + } + if (stream.good() == true) // Do not insert anything at eof. + stream.putback(c); // Put back to make sure that line-numbers are OK. + return stream; +} + +void NRLib::DiscardRestOfLine(std::istream& stream, + int& line_num, + bool throw_if_non_whitespace) +{ + std::locale loc; + std::string s; + std::getline(stream, s); + line_num++; + if (throw_if_non_whitespace) { + std::string::iterator it = s.begin(); + while(it != s.end() && std::isspace(*it, loc)) + ++it; + if (it != s.end()) + throw IOError("Non-whitespace characters encountered."); + } +} + + +std::istream& NRLib::GetNextNonEmptyLine(std::istream & stream, + int & line_num, + std::string & line) +{ + while (std::getline(stream, line)) { + ++line_num; + if (line.find_first_not_of(Whitespace()) != std::string::npos) { + return stream; + } + } + line = ""; + return stream; +} + + +std::string NRLib::FindLastNonEmptyLine(std::istream & stream, const std::ios::pos_type & max_line_len) +{ + stream.seekg(0, std::ios::end); + std::ios::pos_type file_len = stream.tellg(); + std::ios::pos_type offset = std::min(file_len, max_line_len); + stream.seekg(static_cast<std::ios::off_type>(file_len) - offset); + + std::string line = ""; + std::string last_line = ""; + int dummy = 0; + while (GetNextNonEmptyLine(stream, dummy, line)) + { + last_line = line; + } + + return last_line; +} + + +void NRLib::SkipComments(std::istream & stream, + char comment_symbol, + int & line_num) +{ + std::locale loc = std::locale(); + + std::string line; + bool comment = true; + + while (comment == true && stream.good()) { + char c; + + while(stream.get(c) && std::isspace(c, loc)) { + if (c == '\n') + line_num++; + } + + if (c == comment_symbol) { + std::getline(stream, line); + line_num++; + } + else { + stream.unget(); + comment = false; + } + } +} + + +bool NRLib::CheckEndOfFile(std::istream& stream) +{ + char c; + stream >> c; + if (stream.eof()) { + return true; + } + else { + // printf("end of file? %s\n", c); + stream.putback(c); + return false; + } +} + + +unsigned long long +NRLib::FindFileSize(const std::string& filename) +{ + if ( !boost::filesystem::exists(filename) ) { + throw IOError("File " + filename + " does not exist."); + } + + return static_cast<unsigned long long>(boost::filesystem::file_size(filename)); +} + + +int NRLib::FindGridFileType(const std::string& filename ) +{ + unsigned long long length = FindFileSize(filename); + std::ifstream file(filename.c_str(), std::ios::in | std::ios::binary); + if (!file) { + throw IOError("Error opening " + filename); + } + + char buffer[3201]; + if (length > 161) { + file.read(buffer, 3200); + buffer[3200] = '\0'; + } + else { + file.read(buffer, static_cast<std::streamsize>(length)); + buffer[length] = '\0'; + } + + std::string stringbuffer = std::string(buffer); + std::istringstream i(stringbuffer); + std::string token; + i>>token; + + if (token == format_desc[STORM_PETRO_BINARY]) { + return STORM_PETRO_BINARY; + } + else if (token == format_desc[STORM_PETRO_ASCII]) { + return STORM_PETRO_ASCII; + } + else if (token == format_desc[STORM_FACIES_BINARY]) { + return STORM_FACIES_BINARY; + } + else if (token == format_desc[STORM_FACIES_ASCII]) { + return STORM_FACIES_ASCII; + } + else if (token == format_desc[SGRI]) { + //std::getline(i, token); + i>>token; + i>>token; + i>>token; + i>>token; + if(token == "v1.0" ||token == "v2.0" ) + return SGRI; + } + else if (NRLib::IsType<double>(token)) { + return PLAIN_ASCII; + } + else if (length>3200) //Check SEGY: Looking for EBCDIC header. + { + unsigned char * buf = reinterpret_cast<unsigned char *>(buffer); + std::vector<int> frequency(256,0); + int i; + for(i=0;i<3200;i++) + frequency[buf[i]]++; + + bool segy_ok = true; + int low_count = 0; + for(i=0;i<64;i++) + low_count += frequency[i]; + + if(low_count > 5) + segy_ok = false; + + i++; + for(;(i<256) && (segy_ok == true);i++) { + if(frequency[i] > frequency[64]) //Assumption is that EBCDIC 64 (space) is most common in header. + segy_ok = false; + } + if(segy_ok == true) + { + return SEGY; + } + } + return(UNKNOWN); +} + +void NRLib::WriteBinaryShort(std::ostream& stream, + short s, + Endianess file_format) +{ + char buffer[2]; + + switch (file_format) { + case END_BIG_ENDIAN: + WriteUInt16BE(buffer, static_cast<unsigned short>(s)); + break; + case END_LITTLE_ENDIAN: + WriteUInt16LE(buffer, static_cast<unsigned short>(s)); + break; + default: + throw Exception("Invalid file format."); + } + + if (!stream.write(buffer, 2)) { + throw Exception("Error writing to stream."); + } +} + + +short NRLib::ReadBinaryShort(std::istream& stream, + Endianess file_format) +{ + unsigned short us; + char buffer[2]; + + if (!stream.read(buffer, 2)) { + if(stream.eof()) + throw EndOfFile(); + else + throw Exception("Error reading from stream (a)."); + } + + switch (file_format) { + case END_BIG_ENDIAN: + ParseUInt16BE(buffer, us); + break; + case END_LITTLE_ENDIAN: + ParseUInt16LE(buffer, us); + break; + default: + throw Exception("Invalid file format."); + } + + return static_cast<short>(us); +} + + +void NRLib::WriteBinaryInt(std::ostream& stream, + int i, + Endianess file_format) +{ + char buffer[4]; + + switch (file_format) { + case END_BIG_ENDIAN: + WriteUInt32BE(buffer, static_cast<unsigned int>(i)); + break; + case END_LITTLE_ENDIAN: + WriteUInt32LE(buffer, static_cast<unsigned int>(i)); + break; + default: + throw Exception("Invalid file format."); + } + + if (!stream.write(buffer, 4)) { + throw Exception("Error writing to stream."); + } +} + + +int NRLib::ReadBinaryInt(std::istream& stream, + Endianess file_format) +{ + unsigned int ui; + char buffer[4]; + + if (!stream.read(buffer, 4)) { + if(stream.eof()) + throw EndOfFile(); + else + throw Exception("Error reading from stream (b)."); + } + + switch (file_format) { + case END_BIG_ENDIAN: + ParseUInt32BE(buffer, ui); + break; + case END_LITTLE_ENDIAN: + ParseUInt32LE(buffer, ui); + break; + default: + throw Exception("Invalid file format."); + } + + return static_cast<int>(ui); +} + + +void NRLib::WriteBinaryFloat(std::ostream& stream, + float f, + Endianess file_format) +{ + char buffer[4]; + + switch (file_format) { + case END_BIG_ENDIAN: + WriteIEEEFloatBE(buffer, f); + break; + case END_LITTLE_ENDIAN: + WriteIEEEFloatLE(buffer, f); + break; + default: + throw Exception("Invalid file format."); + } + + if (!stream.write(buffer, 4)) { + throw Exception("Error writing to stream."); + } +} + + +float NRLib::ReadBinaryFloat(std::istream& stream, + Endianess file_format) +{ + float f; + char buffer[4]; + + if (!stream.read(buffer, 4)) { + if(stream.eof()) + throw EndOfFile(); + else + throw Exception("Error reading from stream (c)."); + } + + switch (file_format) { + case END_BIG_ENDIAN: + ParseIEEEFloatBE(buffer, f); + break; + case END_LITTLE_ENDIAN: + ParseIEEEFloatLE(buffer, f); + break; + default: + throw Exception("Invalid file format."); + } + + return f; +} + + +void NRLib::WriteBinaryDouble(std::ostream& stream, + double d, + Endianess file_format) +{ + char buffer[8]; + + switch (file_format) { + case END_BIG_ENDIAN: + WriteIEEEDoubleBE(buffer, d); + break; + case END_LITTLE_ENDIAN: + WriteIEEEDoubleLE(buffer, d); + break; + default: + throw Exception("Invalid file format."); + } + + if (!stream.write(buffer, 8)) { + throw Exception("Error writing to stream."); + } +} + + +double NRLib::ReadBinaryDouble(std::istream& stream, + Endianess file_format) +{ + double d; + char buffer[8]; + + if (!stream.read(buffer, 8)) { + if(stream.eof()) + throw EndOfFile(); + else + throw Exception("Error reading from stream (d)."); + } + + switch (file_format) { + case END_BIG_ENDIAN: + ParseIEEEDoubleBE(buffer, d); + break; + case END_LITTLE_ENDIAN: + ParseIEEEDoubleLE(buffer, d); + break; + default: + throw Exception("Invalid file format."); + } + + return d; +} + + +void NRLib::WriteBinaryIbmFloat(std::ostream& stream, + float f, + Endianess file_format) +{ + char buffer[4]; + + switch (file_format) { + case END_BIG_ENDIAN: + WriteIBMFloatBE(buffer, f); + break; + case END_LITTLE_ENDIAN: + WriteIBMFloatLE(buffer, f); + break; + default: + throw Exception("Invalid file format."); + } + + if (!stream.write(buffer, 4)) { + throw Exception("Error writing to stream."); + } +} + + +float NRLib::ReadBinaryIbmFloat(std::istream& stream, + Endianess file_format) +{ + float f; + char buffer[4]; + + if (!stream.read(buffer, 4)) { + if(stream.eof()) + throw EndOfFile(); + else + throw Exception("Error reading from stream (e)."); + } + + switch (file_format) { + case END_BIG_ENDIAN: + ParseIBMFloatBE(buffer, f); + break; + case END_LITTLE_ENDIAN: + ParseIBMFloatLE(buffer, f); + break; + default: + throw Exception("Invalid file format."); + } + + return f; +} + +void NRLib::ReadNextQuoted(std::istream& stream, char quote, std::string& s, int& line) +{ + char c = 0; + + int found = 0; + while( found == 0 && !stream.eof() ){ + stream.get(c); + if (c == '\n'){ + line++; + } + if (c == quote){ + found++; + stream.get(c); + } + } + s =""; + while( found == 1 && !stream.eof() ) { + s = s+c; + stream.get(c); + if (c == '\n'){ + line++; + } + if (c == quote){ + found++; + } + } + if (s == "") //We are at end of file if nothing is read. + throw EndOfFile(); + +} + +bool +NRLib::IgnoreComment(std::ifstream& file, char chin){ + char ch; + do { + if(!file.get(ch)) { + throw Exception("Unexpected end of file."); + // NRLib::LogKit::LogMessage(NRLib::LogKit::Error, "Unexpected end of file. \n\n"); + // Havana::Exit(EXIT_FAILURE); + } + } while(isspace(ch)); + + std::string dummy; + if (ch == chin){ + getline(file, dummy); + return true; + } + else { + file.unget(); + return false; + } +} + + +int NRLib::Seek(FILE * file, long long offset, int origin) +{ + int ret; +#if defined(_MSC_VER) + ret = _fseeki64(file, offset, origin); +#else + ret = fseek(file, offset, origin); +#endif + return(ret); +} + diff --git a/ThirdParty/NRLib/nrlib/iotools/fileio.hpp b/ThirdParty/NRLib/nrlib/iotools/fileio.hpp new file mode 100644 index 0000000000..a8ef0d18e0 --- /dev/null +++ b/ThirdParty/NRLib/nrlib/iotools/fileio.hpp @@ -0,0 +1,1198 @@ +// $Id: fileio.hpp 1077 2012-09-24 12:56:09Z perroe $ + +// Copyright (c) 2011, Norwegian Computing Center +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// • Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// • Redistributions in binary form must reproduce the above copyright notice, this list of +// conditions and the following disclaimer in the documentation and/or other materials +// provided with the distribution. +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT +// SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef NRLIB_FILEIO_HPP +#define NRLIB_FILEIO_HPP + +#include <string> +#include <vector> +#include <iostream> + +#include <stdio.h> +#include <stdlib.h> + +#include "stringtools.hpp" +#include "../exception/exception.hpp" + +namespace NRLib { + enum Endianess {END_LITTLE_ENDIAN, + END_BIG_ENDIAN}; + enum GridFileFormat {UNKNOWN = -1, + STORM_PETRO_BINARY = 0, + STORM_PETRO_ASCII = 1, + STORM_FACIES_BINARY = 2, + STORM_FACIES_ASCII = 3, + SGRI = 4, + SEGY = 5, + PLAIN_ASCII = 6}; + + /// \brief Open file for reading. + void OpenRead(std::ifstream& stream, + const std::string& filename, + std::ios_base::openmode mode = std::ios_base::in); + void OpenRead(std::fstream& stream, + const std::string& filename, + std::ios_base::openmode mode = std::ios_base::in); + + /// \brief Open file for writing. + /// \param create_dir If true the directory is created if it does not exist. + void OpenWrite(std::ofstream& stream, + const std::string& filename, + std::ios_base::openmode mode = std::ios_base::out, + bool create_dir = true); + void OpenWrite(std::fstream& stream, + const std::string& filename , + std::ios_base::openmode mode= std::ios_base::out , + bool create_dir = true); + + void CopyFile(const std::string & from_path, + const std::string & to_path, + bool allow_overwrite); + + bool FileExists(const std::string& filename); + + void CreateDirIfNotExists(const std::string & filename); + + void RemoveFile(const std::string & filename); + + /// \brief Finds the size of a file. Throws IOError if file not found. + /// \return Size of file in bytes. + unsigned long long FindFileSize(const std::string & filename); + + /// \brief Find type of file, for 3D grid files. + /// \todo Move to a suitable place. + int FindGridFileType(const std::string& filename); + + // --------------------------------- + // ASCII read and write + // --------------------------------- + + /// \brief Reads and discard all characters until and including + /// next newline. + /// \param throw_if_non_whitespace If true, throw exception if non-whitespace + /// character is encountered. + void DiscardRestOfLine(std::istream& stream, + int& line_num, + bool throw_if_non_whitespace); + + /// \brief Gets the next line that not only contains whitespace. + /// Returns the stream. Stream will be bad if end-of-file is reached. + std::istream& GetNextNonEmptyLine(std::istream & stream, + int & line_num, + std::string & line); + + /// \brief Returns last non-empty line in file. + /// Stream will be at end of file. + /// \note Does not work on Windows for files larger than 2 GB. (Uses seekg + tellg) + std::string FindLastNonEmptyLine(std::istream & stream, + const std::ios::pos_type & max_line_len = 1000); + + /// \brief Returns next line that not only contains whitespace, or starts with the + /// given comment token. + /// \throws EndOfFile if end of file is reached before next non-empty line. + void SkipComments(std::istream & stream, + char comment_token, + int & line_num); + + /// \brief Check if end of file is reached. + /// Discards all whitespace before end of file or next token. + /// \return True if end of file is reached, else false. + bool CheckEndOfFile(std::istream& stream); + + /// \brief Read next white-space seperated token from file. + /// Updates line number when new line is read in. + /// If end of file is reached the state of stream is set to eof. + /// If ReadNextToken is called with a stream that is not good, the state + /// is set to fail. + std::istream& ReadNextToken(std::istream& stream, std::string& s, int& line); + + /// \brief Gets next token from file, and parses it as type T + /// Might be relatively slow, due to typechecking, and counting line + /// numbers. + /// \throws EndOfFile if end of file is reached. + /// \throws Exception if the token could not be parsed as the given type. + template <typename T> + T ReadNext(std::istream& stream, int& line); + + /// \brief Reads the next, possibly quoted, string. + void ReadNextQuoted(std::istream& stream, char quote, std::string& s, int& line); + + /// \brief Writes array + template <typename I> + void WriteAsciiArray(std::ostream& stream, + I begin, + I end, + int n_per_line = 6); + + /// \brief Gets sequence with elements of type T from input stream. + /// Might be relatively slow, due to typechecking, and counting line + /// numbers. + /// \note The container must already be big enough to read all n + /// elements. + template <typename I> + I ReadAsciiArray(std::istream& stream, I begin, size_t n, int& line); + + /// \brief Gets sequence with elements of type T from input stream. + /// Does no type checking, and does not count line numbers. + /// \note The container must already be big enough to read all n + /// elements. + template <typename I> + I ReadAsciiArrayFast(std::istream& stream, I begin, size_t n); + + /// \brief Gets sequence with elements of type T from input stream. + /// Does no type checking, and does not count line numbers. + /// Reads the rest of the file, and does no type checking at all. + /// If a double is attempted read as an int, the first integer part + /// of the double is read, while the fraction part is discarded. + /// For int, float or double this function is 10x as fast as + /// GetAsciiArrayFast on Windows. + /// \note The container must already be big enough to read all n + /// elements. + template <typename I> + I ReadAsciiArrayFastRestOfFile(std::istream& stream, I begin, size_t n); + + // --------------------------------- + // Binary read and write + // + // 2-byte integer + // --------------------------------- + + /// \brief Write a 2-byte integer to a binary file. + void WriteBinaryShort(std::ostream& stream, + short s, + Endianess number_representation = END_BIG_ENDIAN); + + /// \brief Read a 2-byte integer from a binary file. + short ReadBinaryShort(std::istream& stream, + Endianess number_representation = END_BIG_ENDIAN); + + /// \brief Write an array of binary 2-byte integers. + template<typename I> + void WriteBinaryShortArray(std::ostream& stream, + I begin, + I end, + Endianess number_representation = END_BIG_ENDIAN); + + /// \brief Read an array of binary 2-byte integers. + /// \note The container must already be big enough to read all n + /// elements. + template<typename I> + I ReadBinaryShortArray(std::istream& stream, + I begin, + size_t n, + Endianess number_representation = END_BIG_ENDIAN); + + // --------------------------------- + // 4-byte integer + // --------------------------------- + + /// \brief Write a 4-byte integer to a binary file. + void WriteBinaryInt(std::ostream& stream, + int i, + Endianess number_representation = END_BIG_ENDIAN); + + /// \brief Read a 4-byte integer from a binary file. + int ReadBinaryInt(std::istream& stream, + Endianess number_representation = END_BIG_ENDIAN); + + /// \brief Write an array of binary 4-byte integers. + template<typename I> + void WriteBinaryIntArray(std::ostream& stream, + I begin, + I end, + Endianess number_representation = END_BIG_ENDIAN); + + /// \brief Read an array of binary 4-byte integers. + /// \note The container must already be big enough to read all n + /// elements. + template<typename I> + I ReadBinaryIntArray(std::istream& stream, + I begin, + size_t n, + Endianess number_representation = END_BIG_ENDIAN); + + // --------------------------------- + // 4-byte IEEE floating point number + // --------------------------------- + + /// \brief Write a 4-byte float on standard IEEE format. + void WriteBinaryFloat(std::ostream& stream, + float f, + Endianess number_representation = END_BIG_ENDIAN); + + /// \brief Read a 4-byte float on standard IEEE format. + float ReadBinaryFloat(std::istream& stream, + Endianess number_representation = END_BIG_ENDIAN); + + /// \brief Write an array of 4-byte floats on standard IEEE format. + template<typename I> + void WriteBinaryFloatArray(std::ostream& stream, + I begin, + I end, + Endianess number_representation = END_BIG_ENDIAN); + + /// \brief Read an array of 4-byte floats on standard IEEE format. + /// \note The container must already be big enough to read all n + /// elements. + template<typename I> + I ReadBinaryFloatArray(std::istream& stream, + I begin, + size_t n, + Endianess number_representation = END_BIG_ENDIAN); + + // --------------------------------- + // 8-byte IEEE floating point number + // --------------------------------- + + /// \brief Write a 8-byte float on standard IEEE format. + void WriteBinaryDouble(std::ostream& stream, + double d, + Endianess number_representation = END_BIG_ENDIAN); + + /// \brief Read a 8-byte float on standard IEEE format. + double ReadBinaryDouble(std::istream& stream, + Endianess number_representation = END_BIG_ENDIAN); + + /// \brief Write an array of 8-byte floats on standard IEEE format. + template<typename I> + void WriteBinaryDoubleArray(std::ostream& stream, + I begin, + I end, + Endianess number_representation = END_BIG_ENDIAN); + + /// \brief Read an array of 8-byte floats on standard IEEE format. + /// \note The container must already be big enough to read all n + /// elements. + template<typename I> + I ReadBinaryDoubleArray(std::istream& stream, + I begin, + size_t n, + Endianess number_representation = END_BIG_ENDIAN); + + // --------------------------------- + // 4-byte IBM floating point number + // --------------------------------- + + /// \brief Write a 4-byte float on standard IEEE format. + void WriteBinaryIbmFloat(std::ostream& stream, + float f, + Endianess number_representation = END_BIG_ENDIAN); + + /// \brief Read a 4-byte float on standard IEEE format. + float ReadBinaryIbmFloat(std::istream& stream, + Endianess number_representation = END_BIG_ENDIAN); + + /// \brief Write an array of 4-byte floats on standard IEEE format. + template<typename I> + void WriteBinaryIbmFloatArray(std::ostream& stream, + I begin, + I end, + Endianess number_representation = END_BIG_ENDIAN); + + /// \brief Read an array of 4-byte floats on standard IEEE format. + /// \note The container must already be big enough to read all n + /// elements. + template<typename I> + I ReadBinaryIbmFloatArray(std::istream& stream, + I begin, + size_t n, + Endianess number_representation = END_BIG_ENDIAN); + +bool IgnoreComment(std::ifstream& file, + char chin); + + + // ---------------------------------------------------------- + // Generic seek-function. + // Requires FILE *, since streams fail after 2G on windows. + // ---------------------------------------------------------- + + /// Seek to given position in file, works for large files. + int Seek(FILE * file, long long offset, int origin); + + + // --------------------------------- + // Parsing of read data + // --------------------------------- + // The four ParseBE-functions here are needed by the SegY reader in a special case. + + /// Parse unsigned 32-bit integer from big-endian buffer. + inline void ParseInt16BE(const char* buffer, /*uint16_t*/ short& ui); + + /// Parse unsigned 32-bit integer from big-endian buffer. + inline void ParseInt32BE(const char* buffer, /*uint32_t*/ int& ui); + + /// Parse unsigned 32-bit integer from big-endian buffer. + inline void ParseUInt16BE(const char* buffer, /*uint16_t*/ unsigned short& ui); + + /// Parse unsigned 32-bit integer from big-endian buffer. + inline void ParseUInt32BE(const char* buffer, /*uint32_t*/ unsigned int& ui); + + /// Parse IEEE single-precision float from big-endian buffer. + inline void ParseIEEEFloatBE(const char* buffer, float& f); + + /// Parse IEEE double-precision float from big-endian buffer. + inline void ParseIBMFloatBE(const char* buffer, float& f); + +namespace NRLibPrivate { + /// \todo Use stdint.h if available. + // typedef unsigned int uint32_t; + // typedef unsigned long long uint64_t; + + union FloatAsInt { + /*uint32_t*/ unsigned int ui; + float f; + }; + + union DoubleAsLongLong { + /*uint64_t*/ unsigned long long ull; + double d; + }; + + + /// Parse unsigned 32-bit integer from little-endian buffer. + inline void ParseUInt16LE(const char* buffer, /*uint16_t*/ unsigned short& ui); + + /// Write unsigned 32-bit integer to big-endian buffer. + inline void WriteUInt16BE(char* buffer, /*uint16_t*/ unsigned short us); + + /// Write unsigned 32-bit integer to little-endian buffer. + inline void WriteUInt16LE(char* buffer, /*uint16_t*/ unsigned short us); + + /// Parse unsigned 32-bit integer from little-endian buffer. + inline void ParseUInt32LE(const char* buffer, /*uint32_t*/ unsigned int& ui); + + /// Write unsigned 32-bit integer to big-endian buffer. + inline void WriteUInt32BE(char* buffer, /*uint32_t*/ unsigned int ui); + + /// Write unsigned 32-bit integer to little-endian buffer. + inline void WriteUInt32LE(char* buffer, /*uint32_t*/ unsigned int ui); + + /// Parse IEEE single-precision float from little-endian buffer. + inline void ParseIEEEFloatLE(const char* buffer, float& f); + + /// Write IEEE single-precision float to big-endian buffer. + inline void WriteIEEEFloatBE(char* buffer, float f); + + /// Write IEEE single-precision float to little-endian buffer. + inline void WriteIEEEFloatLE(char* buffer, float f); + + /// Parse IEEE double-precision float from big-endian buffer. + inline void ParseIEEEDoubleBE(const char* buffer, double& d); + + /// Parse IEEE double-precision float from little-endian buffer. + inline void ParseIEEEDoubleLE(const char* buffer, double& d); + + /// Write IEEE double-precision float to big-endian buffer. + inline void WriteIEEEDoubleBE(char* buffer, double d); + + /// Write IEEE double-precision float to little-endian buffer. + inline void WriteIEEEDoubleLE(char* buffer, double d); + + /// Parse IEEE double-precision float from little-endian buffer. + inline void ParseIBMFloatLE(const char* buffer, float& f); + + /// Write IEEE double-precision float to big-endian buffer. + inline void WriteIBMFloatBE(char* buffer, float f); + + /// Write IEEE double-precision float to little-endian buffer. + inline void WriteIBMFloatLE(char* buffer, float f); +} // namespace NRLibPrivate + +} // namespace NRLib + + +// ========== INLINE AND TEMPLATE FUNCTION DEFINITIONS ========= + +namespace NRLib { // Needed to prevent gcc compilation error. + +template <> +inline std::string ReadNext<std::string>(std::istream& stream, int& line) +{ + std::string s; + ReadNextToken(stream, s, line); + if (s == "") + throw EndOfFile(); + return s; +} + + +template <typename T> +T ReadNext(std::istream& stream, int& line) +{ + std::string s; + ReadNextToken(stream, s, line); + if (s == "") + throw EndOfFile(); + return ParseType<T>(s); +} + + +} // namespace NRLib + + +template <typename I> +void NRLib::WriteAsciiArray(std::ostream& stream, + I begin, + I end, + int n_per_line) +{ + int count = 1; + for (I it = begin; it != end; ++it, ++count) { + stream << *it << ' '; + if (count % n_per_line == 0) { + stream << '\n'; + } + } +} + + +template <typename I> +I NRLib::ReadAsciiArray(std::istream& stream, I begin, size_t n, int& line) +{ + typedef typename std::iterator_traits<I>::value_type T; + for (size_t i = 0; i < n; ++i) { + *begin = ReadNext<T>(stream, line); + ++begin; + } + return begin; +} + + +template <typename I> +I NRLib::ReadAsciiArrayFast(std::istream& stream, I begin, size_t n) +{ + for (size_t i = 0; i < n; ++i) { + stream >> *begin; + ++begin; + if ( stream.eof() ) { + throw EndOfFile(); + } + if ( stream.fail() ) { + stream.clear(); + std::string nextToken; + stream >> nextToken; + throw Exception("Failure during reading element " + ToString(static_cast<unsigned int>(i)) + " of array. " + + "Next token is " + nextToken + "\n"); + } + } + return begin; +} + + +template <typename I> +I NRLib::ReadAsciiArrayFastRestOfFile(std::istream& stream, I begin, size_t n) +{ + std::streampos pos = stream.tellg(); + stream.seekg(0, std::ios_base::end); + std::streampos end = stream.tellg(); + stream.seekg(pos); + size_t len = static_cast<size_t>(end - pos); + std::string buffer(len, ' '); + stream.read(&buffer[0], len); + + return ParseAsciiArrayFast(buffer, begin, n); +} + + +template <typename I> +void NRLib::WriteBinaryShortArray(std::ostream& stream, + I begin, + I end, + NRLib::Endianess number_representation) +{ + using namespace NRLib::NRLibPrivate; + + typename I::difference_type n_char = 2*std::distance(begin, end); + std::vector<char> buffer(n_char); + + switch (number_representation) { + case END_BIG_ENDIAN: + for (int i = 0; begin != end; ++begin, ++i) { + WriteUInt16BE(&buffer[2*i], static_cast<unsigned short>(*begin)); + } + break; + case END_LITTLE_ENDIAN: + for (int i = 0; begin != end; ++begin, ++i) { + WriteUInt16LE(&buffer[2*i], static_cast<unsigned short>(*begin)); + } + break; + default: + throw Exception("Invalid number representation."); + } + + if (!stream.write(&buffer[0], static_cast<std::streamsize>(n_char))) { + throw Exception("Error writing to stream."); + } +} + + +template <typename I> +I NRLib::ReadBinaryShortArray(std::istream& stream, + I begin, + size_t n, + NRLib::Endianess number_representation) +{ + using namespace NRLib::NRLibPrivate; + + std::vector<char> buffer(2*n); + unsigned short us; + + if (!stream.read(&buffer[0], static_cast<std::streamsize>(2*n))) { + throw Exception("Error reading from stream (f)."); + } + + switch (number_representation) { + case END_BIG_ENDIAN: + for (size_t i = 0; i < n; ++i) { + ParseUInt16BE(&buffer[2*i], us); + *begin = static_cast<typename std::iterator_traits<I>::value_type>(us); + ++begin; + } + break; + case END_LITTLE_ENDIAN: + for (size_t i = 0; i < n; ++i) { + ParseUInt16LE(&buffer[2*i], us); + *begin = static_cast<typename std::iterator_traits<I>::value_type>(us); + ++begin; + } + break; + default: + throw Exception("Invalid number representation."); + } + + return begin; +} + + +template <typename I> +void NRLib::WriteBinaryIntArray(std::ostream& stream, + I begin, + I end, + NRLib::Endianess number_representation) +{ + using namespace NRLib::NRLibPrivate; + + typename I::difference_type n_char = 4*std::distance(begin, end); + std::vector<char> buffer(n_char); + + switch (number_representation) { + case END_BIG_ENDIAN: + for (int i = 0; begin != end; ++begin, ++i) { + WriteUInt32BE(&buffer[4*i], static_cast<unsigned int>(*begin)); + } + break; + case END_LITTLE_ENDIAN: + for (int i = 0; begin != end; ++begin, ++i) { + WriteUInt32LE(&buffer[4*i], static_cast<unsigned int>(*begin)); + } + break; + default: + throw Exception("Invalid number representation."); + } + + if (!stream.write(&buffer[0], static_cast<std::streamsize>(n_char))) { + throw Exception("Error writing to stream."); + } +} + + +template <typename I> +I NRLib::ReadBinaryIntArray(std::istream& stream, + I begin, + size_t n, + NRLib::Endianess number_representation) +{ + using namespace NRLib::NRLibPrivate; + + std::vector<char> buffer(4*n); + unsigned int ui; + + if (!stream.read(&buffer[0], static_cast<std::streamsize>(4*n))) { + throw Exception("Error reading from stream (g)."); + } + + switch (number_representation) { + case END_BIG_ENDIAN: + for (size_t i = 0; i < n; ++i) { + ParseUInt32BE(&buffer[4*i], ui); + *begin = static_cast<typename std::iterator_traits<I>::value_type>(ui); + ++begin; + } + break; + case END_LITTLE_ENDIAN: + for (size_t i = 0; i < n; ++i) { + ParseUInt32LE(&buffer[4*i], ui); + *begin = static_cast<typename std::iterator_traits<I>::value_type>(ui); + ++begin; + } + break; + default: + throw Exception("Invalid number representation."); + } + + return begin; +} + + +template <typename I> +void NRLib::WriteBinaryFloatArray(std::ostream& stream, + I begin, + I end, + NRLib::Endianess number_representation) +{ + using namespace NRLib::NRLibPrivate; + + typename I::difference_type n_char = 4*std::distance(begin, end); + std::vector<char> buffer(n_char); + + switch (number_representation) { + case END_BIG_ENDIAN: + for (int i = 0; begin != end; ++begin, ++i) { + WriteIEEEFloatBE(&buffer[4*i], *begin); + } + break; + case END_LITTLE_ENDIAN: + for (int i = 0; begin != end; ++begin, ++i) { + WriteIEEEFloatLE(&buffer[4*i], *begin); + } + break; + default: + throw Exception("Invalid number representation."); + } + + if (!stream.write(&buffer[0], static_cast<std::streamsize>(n_char))) { + throw Exception("Error writing to stream."); + } +} + +template <typename I> +I NRLib::ReadBinaryFloatArray(std::istream& stream, + I begin, + size_t n, + NRLib::Endianess number_representation) +{ + using namespace NRLib::NRLibPrivate; + + std::vector<char> buffer(4*n); + float f; + + if (!stream.read(&buffer[0], static_cast<std::streamsize>(4*n))) { + throw Exception("Error reading from stream (h)."); + } + + switch (number_representation) { + case END_BIG_ENDIAN: + for (size_t i = 0; i < n; ++i) { + ParseIEEEFloatBE(&buffer[4*i], f); + *begin = static_cast<typename std::iterator_traits<I>::value_type>(f); + ++begin; + } + break; + case END_LITTLE_ENDIAN: + for (size_t i = 0; i < n; ++i) { + ParseIEEEFloatLE(&buffer[4*i], f); + *begin = static_cast<typename std::iterator_traits<I>::value_type>(f); + ++begin; + } + break; + default: + throw Exception("Invalid number representation."); + } + + return begin; +} + + +template <typename I> +void NRLib::WriteBinaryDoubleArray(std::ostream& stream, + I begin, + I end, + NRLib::Endianess number_representation) +{ + using namespace NRLib::NRLibPrivate; + + typename I::difference_type n_char = 8*std::distance(begin, end); + std::vector<char> buffer(n_char); + + switch (number_representation) { + case END_BIG_ENDIAN: + for (int i = 0; begin != end; ++begin, ++i) { + WriteIEEEDoubleBE(&buffer[8*i], *begin); + } + break; + case END_LITTLE_ENDIAN: + for (int i = 0; begin != end; ++begin, ++i) { + WriteIEEEDoubleLE(&buffer[8*i], *begin); + } + break; + default: + throw Exception("Invalid number representation."); + } + + if (!stream.write(&buffer[0], static_cast<std::streamsize>(n_char))) { + throw Exception("Error writing to stream."); + } +} + + +template <typename I> +I NRLib::ReadBinaryDoubleArray(std::istream& stream, + I begin, + size_t n, + NRLib::Endianess number_representation) +{ + using namespace NRLib::NRLibPrivate; + + std::vector<char> buffer(8*n); + double d; + + if (!stream.read(&buffer[0], static_cast<std::streamsize>(8*n))) { + throw Exception("Error reading from stream (i)."); + } + + switch (number_representation) { + case END_BIG_ENDIAN: + for (size_t i = 0; i < n; ++i) { + ParseIEEEDoubleBE(&buffer[8*i], d); + *begin = static_cast<typename std::iterator_traits<I>::value_type>(d); + ++begin; + } + break; + case END_LITTLE_ENDIAN: + for (size_t i = 0; i < n; ++i) { + ParseIEEEDoubleLE(&buffer[8*i], d); + *begin = static_cast<typename std::iterator_traits<I>::value_type>(d); + ++begin; + } + break; + default: + throw Exception("Invalid number representation."); + } + + return begin; +} + + +template <typename I> +void NRLib::WriteBinaryIbmFloatArray(std::ostream& stream, + I begin, + I end, + NRLib::Endianess number_representation) +{ + using namespace NRLib::NRLibPrivate; + + typename I::difference_type n_char = 4*std::distance(begin, end); + std::vector<char> buffer(n_char); + + switch (number_representation) { + case END_BIG_ENDIAN: + for (int i = 0; begin != end; ++begin, ++i) { + WriteIBMFloatBE(&buffer[4*i], *begin); + } + break; + case END_LITTLE_ENDIAN: + for (int i = 0; begin != end; ++begin, ++i) { + WriteIBMFloatLE(&buffer[4*i], *begin); + } + break; + default: + throw Exception("Invalid number representation."); + } + + if (!stream.write(&buffer[0], static_cast<std::streamsize>(n_char))) { + throw Exception("Error writing to stream."); + } +} + + +template <typename I> +I NRLib::ReadBinaryIbmFloatArray(std::istream& stream, + I begin, + size_t n, + NRLib::Endianess number_representation) +{ + using namespace NRLib::NRLibPrivate; + + std::vector<char> buffer(4*n); + float f; + + std::string error; + if (!stream.read(&buffer[0], static_cast<std::streamsize>(4*n))) { + if (stream.eof()) + error = "Error reading binary IBM float array. Trying to read 4*" + NRLib::ToString(n) + " elements when end-of-file was reached.\n"; + else { + error = "Error reading binary IBM float array. Hardware error? Full disk?\n"; + } + } + + switch (number_representation) { + case END_BIG_ENDIAN: + for (size_t i = 0; i < n; ++i) { + ParseIBMFloatBE(&buffer[4*i], f); + *begin = f; + ++begin; + } + break; + case END_LITTLE_ENDIAN: + for (size_t i = 0; i < n; ++i) { + ParseIBMFloatLE(&buffer[4*i], f); + *begin = f; + ++begin; + } + break; + default: + error += "Invalid number representation. Cannot interpret bit stream as numbers"; + } + + if (error != "") { + throw Exception(error); + } + + return begin; +} + + +static const unsigned short smasks[2] = {0x00ff, 0xff00}; + +static const unsigned int masks[4] = +{0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000}; + +static const unsigned long long lmasks[8] = +{0x00000000000000ffULL, 0x000000000000ff00ULL, + 0x0000000000ff0000ULL, 0x00000000ff000000ULL, + 0x000000ff00000000ULL, 0x0000ff0000000000ULL, + 0x00ff000000000000ULL, 0xff00000000000000ULL}; + + +// ----------------- 16 bit integer --------------------- + +void NRLib::ParseInt16BE(const char* buffer, + /*uint16_t*/ short& us) +{ + us = static_cast<unsigned char>(buffer[0]); + us <<= 8; + us |= static_cast<unsigned char>(buffer[1]); +} + + +// ----------------- 16 bit integer --------------------- + +void NRLib::ParseUInt16BE(const char* buffer, + /*uint16_t*/ unsigned short& us) +{ + us = static_cast<unsigned char>(buffer[0]); + us <<= 8; + us |= static_cast<unsigned char>(buffer[1]); +} + + +void NRLib::NRLibPrivate::ParseUInt16LE(const char* buffer, + /*uint32_t*/ unsigned short& us) +{ + us = static_cast<unsigned char>(buffer[1]); + us <<= 8; + us |= static_cast<unsigned char>(buffer[0]); +} + + +void NRLib::NRLibPrivate::WriteUInt16BE(char* buffer, + /*uint32_t*/ unsigned short us) +{ + buffer[0] = static_cast<char>( (us & smasks[1]) >> 8 ); + buffer[1] = static_cast<char>( us & smasks[0] ); +} + + +void NRLib::NRLibPrivate::WriteUInt16LE(char* buffer, + /*uint32_t*/ unsigned short us) +{ + buffer[0] = static_cast<char>(us & smasks[0]); + buffer[1] = static_cast<char>( (us & smasks[1]) >> 8 ); +} + + +// ----------------- 32 bit integer --------------------- + + +void NRLib::ParseInt32BE(const char* buffer, + /*int32_t*/ int& ui) +{ + ui = static_cast<unsigned char>(buffer[0]); + for (int i = 1; i < 4; ++i) { + ui <<= 8; + ui |= static_cast<unsigned char>(buffer[i]); + } +} + +// -------------- 32 bit unsigned integer ----------------- + + +void NRLib::ParseUInt32BE(const char* buffer, + /*uint32_t*/ unsigned int& ui) +{ + ui = static_cast<unsigned char>(buffer[0]); + for (int i = 1; i < 4; ++i) { + ui <<= 8; + ui |= static_cast<unsigned char>(buffer[i]); + } +} + + +void NRLib::NRLibPrivate::ParseUInt32LE(const char* buffer, + /*uint32_t*/ unsigned int& ui) +{ + ui = static_cast<unsigned char>(buffer[3]); + for (int i = 1; i < 4; ++i) { + ui <<= 8; + ui |= static_cast<unsigned char>(buffer[3-i]); + } +} + + +void NRLib::NRLibPrivate::WriteUInt32BE(char* buffer, + /*uint32_t*/ unsigned int ui) +{ + buffer[0] = static_cast<char>( (ui & masks[3]) >> 24); + buffer[1] = static_cast<char>( (ui & masks[2]) >> 16 ); + buffer[2] = static_cast<char>( (ui & masks[1]) >> 8 ); + buffer[3] = static_cast<char>( ui & masks[0] ); +} + + +void NRLib::NRLibPrivate::WriteUInt32LE(char* buffer, + /*uint32_t*/ unsigned int ui) +{ + buffer[0] = static_cast<char>(ui & masks[0]); + buffer[1] = static_cast<char>( (ui & masks[1]) >> 8 ); + buffer[2] = static_cast<char>( (ui & masks[2]) >> 16 ); + buffer[3] = static_cast<char>( (ui & masks[3]) >> 24 ); +} + + +// ----------------- 32 bit IEEE floating point ------------------- + + +// Big endian number representation. +void NRLib::ParseIEEEFloatBE(const char* buffer, float& f) +{ + NRLibPrivate::FloatAsInt tmp; + tmp.ui = static_cast<unsigned char>(buffer[0]); + for (int i = 1; i < 4; ++i) { + tmp.ui <<= 8; + tmp.ui |= static_cast<unsigned char>(buffer[i]); + } + f = tmp.f; +} + +// Little endian number representation. +void NRLib::NRLibPrivate::ParseIEEEFloatLE(const char* buffer, float& f) +{ + FloatAsInt tmp; + tmp.ui = static_cast<unsigned char>(buffer[3]); + for (int i = 1; i < 4; ++i) { + tmp.ui <<= 8; + tmp.ui |= static_cast<unsigned char>(buffer[3-i]); + } + f = tmp.f; +} + + +// Big endian number representation. +void NRLib::NRLibPrivate::WriteIEEEFloatBE(char* buffer, float f) +{ + FloatAsInt tmp; + tmp.f = f; + buffer[0] = static_cast<char>( (tmp.ui & masks[3]) >> 24); + buffer[1] = static_cast<char>( (tmp.ui & masks[2]) >> 16 ); + buffer[2] = static_cast<char>( (tmp.ui & masks[1]) >> 8 ); + buffer[3] = static_cast<char>( tmp.ui & masks[0] ); +} + +// Little endian number representation. +void NRLib::NRLibPrivate::WriteIEEEFloatLE(char* buffer, float f) +{ + FloatAsInt tmp; + tmp.f = f; + buffer[0] = static_cast<char>(tmp.ui & masks[0]); + buffer[1] = static_cast<char>( (tmp.ui & masks[1]) >> 8 ); + buffer[2] = static_cast<char>( (tmp.ui & masks[2]) >> 16 ); + buffer[3] = static_cast<char>( (tmp.ui & masks[3]) >> 24 ); +} + + +// ----------------- 64 bit IEEE floating point -------------------- + + +// Big endian number representation. +void NRLib::NRLibPrivate::ParseIEEEDoubleBE(const char* buffer, double& d) +{ + DoubleAsLongLong tmp; + tmp.ull = static_cast<unsigned char>(buffer[0]); + for (int i = 1; i < 8; ++i) { + tmp.ull <<= 8; + tmp.ull |= static_cast<unsigned char>(buffer[i]); + } + d = tmp.d; +} + +// Little endian number representation. +void NRLib::NRLibPrivate::ParseIEEEDoubleLE(const char* buffer, double& d) +{ + DoubleAsLongLong tmp; + tmp.ull = static_cast<unsigned char>(buffer[7]); + for (int i = 1; i < 8; ++i) { + tmp.ull <<= 8; + tmp.ull |= static_cast<unsigned char>(buffer[7-i]); + } + d = tmp.d; +} + + +// Big endian number representation. +void NRLib::NRLibPrivate::WriteIEEEDoubleBE(char* buffer, double d) +{ + DoubleAsLongLong tmp; + tmp.d = d; + buffer[0] = static_cast<char>( (tmp.ull & lmasks[7]) >> 56); + buffer[1] = static_cast<char>( (tmp.ull & lmasks[6]) >> 48); + buffer[2] = static_cast<char>( (tmp.ull & lmasks[5]) >> 40); + buffer[3] = static_cast<char>( (tmp.ull & lmasks[4]) >> 32); + buffer[4] = static_cast<char>( (tmp.ull & lmasks[3]) >> 24); + buffer[5] = static_cast<char>( (tmp.ull & lmasks[2]) >> 16); + buffer[6] = static_cast<char>( (tmp.ull & lmasks[1]) >> 8 ); + buffer[7] = static_cast<char>( tmp.ull & lmasks[0] ); +} + +// Little endian number representation. +void NRLib::NRLibPrivate::WriteIEEEDoubleLE(char* buffer, double d) +{ + DoubleAsLongLong tmp; + tmp.d = d; + buffer[0] = static_cast<char>( tmp.ull & lmasks[0]); + buffer[1] = static_cast<char>( (tmp.ull & lmasks[1]) >> 8 ); + buffer[2] = static_cast<char>( (tmp.ull & lmasks[2]) >> 16); + buffer[3] = static_cast<char>( (tmp.ull & lmasks[3]) >> 24); + buffer[4] = static_cast<char>( (tmp.ull & lmasks[4]) >> 32); + buffer[5] = static_cast<char>( (tmp.ull & lmasks[5]) >> 40); + buffer[6] = static_cast<char>( (tmp.ull & lmasks[6]) >> 48); + buffer[7] = static_cast<char>( (tmp.ull & lmasks[7]) >> 56); +} + + +// ----------------- 32 bit IBM floating point ------------------- + +static unsigned int IEEEMAX = 0x7FFFFFFF; +static unsigned int IEMAXIB = 0x611FFFFF; +static unsigned int IEMINIB = 0x21200000; + + +/// Converts Ieee float (represented as 32-bit int) to IBM float. +static inline void Ibm2Ieee(/*uint32_t*/ unsigned int& in) +{ + static int it[8] = { 0x21800000, 0x21400000, 0x21000000, 0x21000000, + 0x20c00000, 0x20c00000, 0x20c00000, 0x20c00000 }; + static int mt[8] = { 8, 4, 2, 2, 1, 1, 1, 1 }; + /*uint32_t*/ unsigned int manthi, iexp, inabs; + int ix; + + manthi = in & 0x00ffffff; + ix = manthi >> 21; + iexp = ( ( in & 0x7f000000 ) - it[ix] ) << 1; + manthi = manthi * mt[ix] + iexp; + inabs = in & 0x7fffffff; + if ( inabs > IEMAXIB ) manthi = IEEEMAX; + manthi = manthi | ( in & 0x80000000 ); + in = ( inabs < IEMINIB ) ? 0 : manthi; +} + + +/// Converts Ieee float (represented as 32-bit int) to IBM float. +static inline void Ieee2Ibm ( /*uint32_t*/ unsigned int& in) +{ + static int it[4] = { 0x21200000, 0x21400000, 0x21800000, 0x22100000 }; + static int mt[4] = { 2, 4, 8, 1 }; + /*uint32_t*/ unsigned int manthi, iexp, ix; + + ix = ( in & 0x01800000 ) >> 23; + iexp = ( ( in & 0x7e000000 ) >> 1 ) + it[ix]; + manthi = ( mt[ix] * ( in & 0x007fffff) ) >> 3; + manthi = (manthi + iexp) | ( in & 0x80000000 ); + in = ( in & 0x7fffffff ) ? manthi : 0; +} + + +// Big endian number representation. +void NRLib::ParseIBMFloatBE(const char* buffer, float& f) +{ + NRLibPrivate::FloatAsInt tmp; + tmp.ui = static_cast<unsigned char>(buffer[0]); + for (int i = 1; i < 4; ++i) { + tmp.ui <<= 8; + tmp.ui |= static_cast<unsigned char>(buffer[i]); + } + + Ibm2Ieee(tmp.ui); + f = tmp.f; +} + + +// Little endian number representation. +void NRLib::NRLibPrivate::ParseIBMFloatLE(const char* buffer, float& f) +{ + FloatAsInt tmp; + tmp.ui = static_cast<unsigned char>(buffer[3]); + for (int i = 1; i < 4; ++i) { + tmp.ui <<= 8; + tmp.ui |= static_cast<unsigned char>(buffer[3-i]); + } + + Ibm2Ieee(tmp.ui); + f = tmp.f; +} + + +// Big endian number representation. +void NRLib::NRLibPrivate::WriteIBMFloatBE(char* buffer, float f) +{ + FloatAsInt tmp; + tmp.f = f; + Ieee2Ibm(tmp.ui); + buffer[0] = static_cast<char>( (tmp.ui & masks[3]) >> 24); + buffer[1] = static_cast<char>( (tmp.ui & masks[2]) >> 16 ); + buffer[2] = static_cast<char>( (tmp.ui & masks[1]) >> 8 ); + buffer[3] = static_cast<char>( tmp.ui & masks[0] ); +} + + +// Little endian number representation. +void NRLib::NRLibPrivate::WriteIBMFloatLE(char* buffer, float f) +{ + FloatAsInt tmp; + tmp.f = f; + Ieee2Ibm(tmp.ui); + buffer[0] = static_cast<char>(tmp.ui & masks[0]); + buffer[1] = static_cast<char>( (tmp.ui & masks[1]) >> 8 ); + buffer[2] = static_cast<char>( (tmp.ui & masks[2]) >> 16 ); + buffer[3] = static_cast<char>( (tmp.ui & masks[3]) >> 24 ); +} + +#endif // NRLIB_FILEIO_HPP diff --git a/ThirdParty/NRLib/nrlib/iotools/logkit.cpp b/ThirdParty/NRLib/nrlib/iotools/logkit.cpp new file mode 100644 index 0000000000..cdae8b85f8 --- /dev/null +++ b/ThirdParty/NRLib/nrlib/iotools/logkit.cpp @@ -0,0 +1,299 @@ +// $Id: logkit.cpp 1127 2012-12-04 12:54:33Z ulvmoen $ + +// Copyright (c) 2011, Norwegian Computing Center +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// • Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// • Redistributions in binary form must reproduce the above copyright notice, this list of +// conditions and the following disclaimer in the documentation and/or other materials +// provided with the distribution. +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT +// SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include <fstream> +#include <iostream> +#include <stdarg.h> + +#include "logkit.hpp" +#include "../exception/exception.hpp" + +using namespace NRLib; + +std::vector<LogStream*> LogKit::logstreams_(0); +int LogKit::screenLog_ = -1; +std::vector<BufferMessage *> * LogKit::buffer_ = NULL; + +// Making a long table to allow direct access. +std::vector<int> LogKit::n_messages_(65, 0); +std::vector<std::string> LogKit::prefix_(65, ""); + +void +LogKit::SetFileLog(const std::string & fileName, int levels, + bool includeNRLibLogging) +{ + std::ofstream * file = new std::ofstream(fileName.c_str()); + if (!(*file)) { + //NBNB-PAL: Tmp fix pfga. manglende feilhÃ¥ndtering (catch) + delete file; + printf("Could not open file %s\n",fileName.c_str()); + throw IOError("Error opening " + fileName); + } + LogStream * curStream; + if (includeNRLibLogging == true) + curStream = new LogStream(file, levels); + else { + std::vector<int> phaseLevels; + phaseLevels.push_back(0); //No logging in NRLib, phase 0. + phaseLevels.push_back(levels); //This will be used for all other phases. + curStream = new LogStream(file, phaseLevels); + } + logstreams_.push_back(curStream); + DumpBuffer(curStream); +} + +void +LogKit::SetFileLog(const std::string & fileName, const std::vector<int> & levels, bool ignore_general) { + std::ofstream * file = new std::ofstream(fileName.c_str()); + if (!(*file)) { + delete file; + throw IOError("Error opening " + fileName); + } + LogStream * curStream = new LogStream(file, levels, ignore_general); + logstreams_.push_back(curStream); + DumpBuffer(curStream); +} + +void +LogKit::SetFileLog(const std::string & fileName, int levels, int phase, bool ignore_general) { + std::ofstream * file = new std::ofstream(fileName.c_str()); + if (!(*file)) { + delete file; + throw IOError("Error opening " + fileName); + } + std::vector<int> phaseLevels(1000,0); + phaseLevels[phase] = levels; + LogStream * curStream = new LogStream(file, phaseLevels, ignore_general); + logstreams_.push_back(curStream); + DumpBuffer(curStream); +} + +void +LogKit::SetScreenLog(int levels, bool includeNRLibLogging) +{ + LogStream * curStream; + if (includeNRLibLogging == true) + curStream = new LogStream(NULL, levels); + else { + std::vector<int> phaseLevels; + phaseLevels.push_back(0); //No logging in NRLib, phase 0. + phaseLevels.push_back(levels); //This will be used for all other phases. + curStream = new LogStream(NULL, phaseLevels); + } + if (screenLog_ < 0) { + screenLog_ = static_cast<int>(logstreams_.size()); + logstreams_.push_back(curStream); + } + else { + delete logstreams_[screenLog_]; + logstreams_[screenLog_] = curStream; + } +} + +void +LogKit::SetScreenLog(const std::vector<int> & levels, bool ignore_general) { + LogStream * curStream = new LogStream(NULL, levels, ignore_general); + if (screenLog_ < 0) { + screenLog_ = static_cast<int>(logstreams_.size()); + logstreams_.push_back(curStream); + } + else { + delete logstreams_[screenLog_]; + logstreams_[screenLog_] = curStream; + } +} + + +void +LogKit::LogMessage(int level, const std::string & message) { + unsigned int i; + n_messages_[level]++; + std::string new_message = prefix_[level] + message; + for (i=0;i<logstreams_.size();i++) + logstreams_[i]->LogMessage(level, new_message); + SendToBuffer(level,-1,new_message); +} + +void +LogKit::LogMessage(int level, int phase, const std::string & message) { + unsigned int i; + n_messages_[level]++; + std::string new_message = prefix_[level] + message; + for (i=0;i<logstreams_.size();i++) + logstreams_[i]->LogMessage(level, phase, new_message); + SendToBuffer(level,phase,new_message); +} + +void +LogKit::LogFormatted(int level, std::string format, ...) { + va_list ap; + char message[5000]; + va_start(ap, format); + vsprintf(message, format.c_str(), ap); + va_end(ap); + LogMessage(level, std::string(message)); +} + +void +LogKit::LogFormatted(int level, int phase, std::string format, ...) { + va_list ap; + char message[1000]; + va_start(ap, format); + vsprintf(message, format.c_str(), ap); + va_end(ap); + LogMessage(level, phase, std::string(message)); +} + + +void +LogKit::EndLog() { + unsigned int i; + for (i=0;i<logstreams_.size();i++) + delete logstreams_[i]; + + if (buffer_ != NULL) + EndBuffering(); //Also deletes buffer. +} + +void +LogKit::StartBuffering() { + buffer_ = new std::vector<BufferMessage *>; +} + +void +LogKit::EndBuffering() { + if (buffer_ != NULL) { + for (unsigned int i=0;i<buffer_->size();i++) { + delete (*buffer_)[i]; + (*buffer_)[i] = NULL; + } + delete buffer_; + buffer_ = NULL; + } +} + +void +LogKit::SendToBuffer(int level, int phase, const std::string & message) { + if (buffer_ != NULL) { + BufferMessage * bm = new BufferMessage; + bm->level_ = level; + bm->phase_ = phase; + bm->text_ = message; + buffer_->push_back(bm); + } +} + +void +LogKit::DumpBuffer(LogStream *logstream) { + if (buffer_ != NULL) { + for (unsigned int i=0;i<buffer_->size();i++) { + if ((*buffer_)[i]->phase_ < 0) + logstream->LogMessage((*buffer_)[i]->level_, (*buffer_)[i]->text_); + else + logstream->LogMessage((*buffer_)[i]->level_, (*buffer_)[i]->phase_, (*buffer_)[i]->text_); + } + } +} + +void +LogKit::SetPrefix(const std::string & prefix, int level) { + prefix_[level] = prefix; +} + +void +LogKit::WriteHeader(const std::string & text, + MessageLevels logLevel) +{ + int width = 100; // Total width of header + std::string ruler(width,'*'); + std::string stars("*****"); + LogFormatted(logLevel,"\n"+ruler+"\n"); + int starLength = int(stars.length()); + int textLength = int(text.length()); + int blankLength = width - textLength - 2*starLength; + std::string blanks(blankLength/2,' '); + std::string center; + if(blankLength % 2) + center = stars + blanks + text + blanks + " " + stars; + else + center = stars + blanks + text + blanks +stars; + LogFormatted(logLevel,center+"\n"); + LogFormatted(logLevel,ruler+"\n"); +} + +LogStream::LogStream(std::ostream * logstream, int level) { + fullLevel_ = level; + if (logstream != NULL) { + logstream_ = logstream; + deleteStream = true; + } + else { + logstream_ = &(std::cout); + deleteStream = false; + } +} + +LogStream::LogStream(std::ostream * logstream, const std::vector<int> & levels, bool ignore_general) { + unsigned int i; + fullLevel_ = 0; + for (i=0;i<levels.size();i++) { + if(ignore_general == false) + fullLevel_ = (fullLevel_ | levels[i]); + levels_.push_back(levels[i]); + } + if (logstream != NULL) { + logstream_ = logstream; + deleteStream = true; + } + else { + logstream_ = &(std::cout); + deleteStream = false; + } +} + +LogStream::~LogStream() { + if (deleteStream == true) { + delete logstream_; + } +} + +void +LogStream::LogMessage(int level, const std::string & message) { + if ((level & fullLevel_) > 0) { + *logstream_ << message; + logstream_->flush(); + } +} + +void +LogStream::LogMessage(int level, int phase, const std::string & message) { + if (phase < static_cast<int>(levels_.size())) { + if ((level & levels_[phase]) > 0) { + *logstream_ << message; + logstream_->flush(); + } + } + else if ((level & fullLevel_) > 0) { + *logstream_ << message; + logstream_->flush(); + } +} + diff --git a/ThirdParty/NRLib/nrlib/iotools/logkit.hpp b/ThirdParty/NRLib/nrlib/iotools/logkit.hpp new file mode 100644 index 0000000000..d5d8e40309 --- /dev/null +++ b/ThirdParty/NRLib/nrlib/iotools/logkit.hpp @@ -0,0 +1,145 @@ +// $Id: logkit.hpp 1072 2012-09-18 13:53:37Z perroe $ + +// Copyright (c) 2011, Norwegian Computing Center +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// • Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// • Redistributions in binary form must reproduce the above copyright notice, this list of +// conditions and the following disclaimer in the documentation and/or other materials +// provided with the distribution. +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT +// SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef NRLIB_LOGKIT_H +#define NRLIB_LOGKIT_H + +#include<ostream> +#include<vector> +#include<string> + +namespace NRLib { + +class LogStream; +struct BufferMessage; + +/// Kit for logging of messages from program. +class LogKit { +public: + ///Philosophy: + ///A message has a level, determining the type of message, and a phase, + ///determining the stage in the program. Each stream has a level (which may + ///be a combination of basic levels) for each phase. If phase and flag + ///matches, the message is sent to the stream. A message without phase is + ///default sent to all streams that would send it in at least one phase. If + ///the ignore_general flag is set to true when generating a stream, that + ///stream will ignore messages without phase. + /// + ///The system can be used without bothering with phases. All NRLib logging + ///is phase 0 LOW. + /// + + ///Symbols for use when sending message level and parsing exact levels. + enum MessageLevels {Error = 1, Warning = 2, Low = 4, Medium = 8, High = 16, DebugLow = 32, DebugHigh = 64}; + + ///Symbols for use when parsing given level and lower. + enum LimitLevels {L_Error = 1, L_Warning = 3, L_Low = 7, L_Medium = 15, + L_High = 31, L_DebugLow = 63, L_DebugHigh = 127}; + + ///Set a file that logs independent of phase. + static void SetFileLog(const std::string & fileName, int levels, + bool includeNRLibLogging = true); + + ///Set a full phase dependent file log + static void SetFileLog(const std::string & fileName, + const std::vector<int> & levels, + bool ignore_general = false); + + ///Set single-phase file log, useful for debugging given phase. + static void SetFileLog(const std::string & fileName, + int levels, + int phase, + bool ignore_general = false); + + + ///Set a screen log independent of phase. + static void SetScreenLog(int levels, bool includeNRLibLogging = true); + + ///Set a full phase dependent screen log + static void SetScreenLog(const std::vector<int> & levels, bool ignore_general = false); + + + ///Send message independent of phase + static void LogMessage(int level, const std::string & message); + + ///Send message in given phase + static void LogMessage(int level, int phase, const std::string & message); + + ///Send message as c-style format string and arguments. + // Sending format as reference fails. + static void LogFormatted(int level, std::string format, ...); + + ///Send message as c-style format string and arguments. + static void LogFormatted(int level, int phase, std::string format, ...); + + + ///Close streams + static void EndLog(); + + ///Buffering allows temporary storage of messages for sending to files + ///opened later. When a file log is opened, the buffer is dumped to it. + ///EndBuffering should be called once all files are opened. + static void StartBuffering(); + static void EndBuffering(); + + static void SetPrefix(const std::string & prefix, int level); + static int GetNMessages(int level) { return n_messages_[level];} + static void WriteHeader(const std::string & text, MessageLevels logLevel = Low); + + +private: + static std::vector<LogStream *> logstreams_; + static int screenLog_; //Remembers which log is screen. + static std::vector<BufferMessage *> * buffer_; + static std::vector<int> n_messages_; + static std::vector<std::string> prefix_; + + static void SendToBuffer(int level, int phase, const std::string & message); + static void DumpBuffer(LogStream * logstream); +}; + +///Class LogStream is for internal use in LogKit only. +class LogStream { +public: + ///Convention: logstream = NULL means cout. + LogStream(std::ostream * logstream, int level); + LogStream(std::ostream * logstream, const std::vector<int> & levels, bool ignore_general = false); + ~LogStream(); + + void LogMessage(int level, const std::string & message); + void LogMessage(int level, int phase, const std::string & message); + +private: + std::ostream * logstream_; + std::vector<int> levels_; + int fullLevel_; + bool deleteStream; +}; + +struct BufferMessage { + std::string text_; + int phase_; + int level_; +}; + +} +#endif + diff --git a/ThirdParty/NRLib/nrlib/iotools/module.mk b/ThirdParty/NRLib/nrlib/iotools/module.mk new file mode 100644 index 0000000000..2a7e402a2d --- /dev/null +++ b/ThirdParty/NRLib/nrlib/iotools/module.mk @@ -0,0 +1,6 @@ +SRC += $(NRLIB_BASE_DIR)iotools/fileio.cpp \ + $(NRLIB_BASE_DIR)iotools/logkit.cpp \ + $(NRLIB_BASE_DIR)iotools/stringtools.cpp \ + $(NRLIB_BASE_DIR)iotools/tabularfile.cpp + +TEST_SRC += $(NRLIB_BASE_DIR)iotools/unittests/fileio_test.cpp diff --git a/ThirdParty/NRLib/nrlib/iotools/stringtools.cpp b/ThirdParty/NRLib/nrlib/iotools/stringtools.cpp new file mode 100644 index 0000000000..1e41f1153b --- /dev/null +++ b/ThirdParty/NRLib/nrlib/iotools/stringtools.cpp @@ -0,0 +1,190 @@ +// $Id: stringtools.cpp 1068 2012-09-18 11:21:53Z perroe $ + +// Copyright (c) 2011, Norwegian Computing Center +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// • Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// • Redistributions in binary form must reproduce the above copyright notice, this list of +// conditions and the following disclaimer in the documentation and/or other materials +// provided with the distribution. +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT +// SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include "stringtools.hpp" + +#include <algorithm> +#include <cctype> +#include <iostream> +#include <string> +#include <sstream> + +#define BOOST_FILESYSTEM_VERSION 2 +#include <boost/filesystem.hpp> + +using namespace NRLib; + +template <> +std::string NRLib::ParseType<std::string>(const std::string& s) +{ + return s; //Just to ensure that whitespace-containing strings survive. +} + + +std::string +NRLib::GetPath(const std::string& filename) +{ + boost::filesystem::path path(filename); + return path.parent_path().file_string(); +} + + +std::string +NRLib::GetExtension(const std::string& filename) +{ + boost::filesystem::path path(filename); + return path.extension(); +} + + +std::string +NRLib::RemovePath(const std::string& filename) +{ + boost::filesystem::path path(filename); + return path.filename(); +} + + +std::string +NRLib::PrependDir(const std::string& prefix, + const std::string& str) +{ + boost::filesystem::path path(prefix); + path /= str; + return path.file_string(); +} + + +std::string +NRLib::ReplaceExtension(const std::string& filename, + const std::string& extension) +{ + boost::filesystem::path file(filename); + file.replace_extension(extension); + return file.file_string(); +} + +std::string +NRLib::AddExtension(const std::string& filename, + const std::string& extension) +{ + std::string new_filename = filename + "." + extension; + return new_filename; +} + +std::string +NRLib::GetStem(const std::string& filename) +{ + boost::filesystem::path path(filename); + return path.stem(); +} + + +std::vector<std::string> +NRLib::GetTokens(const std::string& s) +{ + std::vector<std::string> v; + std::istringstream iss(s); + std::string tmp; + while(iss >> tmp) { + v.push_back(tmp); + } + return v; +} + +std::vector<std::string> +NRLib::GetQuotedTokens(const std::string& s) +{ + std::vector<std::string> v; + std::istringstream iss(s); + std::string tmp; + std::string char_tmp; + size_t quotation_last_position = 0; + while(iss >> tmp) { + char_tmp = tmp.substr(0, 1); + if (char_tmp != "\"") + v.push_back(tmp); + else{ + quotation_last_position = s.find_first_of("\"", quotation_last_position + 1); + size_t first_quotation_mark = quotation_last_position; + quotation_last_position = s.find_first_of("\"", quotation_last_position + 1); + size_t second_quotation_mark = quotation_last_position; + std::string quotation = s.substr(first_quotation_mark + 1, (second_quotation_mark - first_quotation_mark - 1)); + v.push_back(quotation); + if (char_tmp == tmp) + iss >> tmp; + while (tmp.substr((tmp.size() - 1), 1) != "\"") + iss >> tmp; + } + } + return v; +} + +void +NRLib::Substitute(std::string & text, + const std::string & out, + const std::string & in) +{ + std::string::size_type len = in.size(); + std::string::size_type pos = text.find(out); + while (pos != std::string::npos) { + text.replace(pos, len, in); + pos = text.find(out); + } +} + + +std::string +NRLib::Uppercase(const std::string& text) +{ + std::string out = text; + for (size_t i = 0; i < out.length(); ++i) + out[i] = static_cast<char>(std::toupper(out[i])); + return out; +} + +bool +NRLib::IsNumber(const std::string & s) +{ + std::istringstream inStream(s); + double inValue = 0.0; + if (inStream >> inValue) + return true; + else + return false; +} + +std::string +NRLib::Chomp(const std::string& s) +{ + std::string out = s; + + size_t first, last; + first = out.find_first_not_of(" "); + last = out.find_last_not_of(" "); + + out.erase(last + 1); + out.erase(0, first); + + return out; +} + + diff --git a/ThirdParty/NRLib/nrlib/iotools/stringtools.hpp b/ThirdParty/NRLib/nrlib/iotools/stringtools.hpp new file mode 100644 index 0000000000..8a2eb90bc6 --- /dev/null +++ b/ThirdParty/NRLib/nrlib/iotools/stringtools.hpp @@ -0,0 +1,218 @@ +// $Id: stringtools.hpp 1068 2012-09-18 11:21:53Z perroe $ + +// Copyright (c) 2011, Norwegian Computing Center +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// • Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// • Redistributions in binary form must reproduce the above copyright notice, this list of +// conditions and the following disclaimer in the documentation and/or other materials +// provided with the distribution. +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT +// SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef NRLIB_STRINGTOOLS_HPP +#define NRLIB_STRINGTOOLS_HPP + +#include <stdlib.h> // For atoi and atof + +#include <string> +#include <iomanip> +#include <vector> +#include <sstream> +#include <typeinfo> + +#include "../exception/exception.hpp" + +namespace NRLib { + std::vector<std::string> GetTokens(const std::string& s); + + std::vector<std::string> GetQuotedTokens(const std::string& s); + + /// OBS: Negative values are recognized as unsigned integers on Windows. + /// Works OK on Linux. (gcc 4.*) + template <typename T> + bool IsType(const std::string& s); + + /// OBS: Negative values are recognized as unsigned integers on Windows. + /// Works OK on Linux. (gcc 4.*) + template <typename T> + T ParseType(const std::string& s); + + /// If used in a template function, we may get string ot string parse. + /// Will not work with the version above, so handle special case. + template <> + std::string ParseType<std::string>(const std::string& s); + + /// \todo Replace precision with a format object. + template <typename T> + std::string ToString(const T obj, int precision=-99999); + + /// Not safe. Replaces whitespace in s with \0. + template <typename I> + I ParseAsciiArrayFast(std::string& s, I begin, size_t n); + + /// Get the path from a full file name. + std::string GetPath(const std::string& filename); + + /// Get the stem of the filename (filename without path and extension) + std::string GetStem(const std::string& filename); + + /// Get filename extension + std::string GetExtension(const std::string& filename); + + /// Get file name only (no path) from full file name. + std::string RemovePath(const std::string& filename); + + /// Prepend prefix to str. Returns str if prefix is empty, if str is empty + /// or if str is a complete path starting with /. + /// Adds '/' as directory seperator if missing. + std::string PrependDir(const std::string& prefix, + const std::string& str); + + /// Replace file extension. + std::string ReplaceExtension(const std::string& filename, + const std::string& extension); + + /// Add an extension to the filename. + std::string AddExtension(const std::string& filename, + const std::string& extension); + + /// In string text replace all occurences odf string "out" with string "in". + void Substitute(std::string & text, + const std::string & out, + const std::string & in); + + /// Return uppercase of input string. + std::string Uppercase(const std::string& text); + + bool IsNumber(const std::string & s); + + std::string Chomp(const std::string& s); + + /// String with different kinds of whitespace characters. + inline std::string Whitespace() { return " \t\n\r\f\v"; } + +namespace NRLibPrivate { + +template <class A> +class UnsafeParser +{ +public: + static A ParseType(const char* s) { + return NRLib::ParseType<A>(s); + } +}; + +template <> +class UnsafeParser<int> +{ +public: + static int ParseType(const char* s) { + return atoi(s); + } +}; + +template <> +class UnsafeParser<double> +{ +public: + static double ParseType(const char* s) { + return atof(s); + } +}; + +template <> +class UnsafeParser<float> +{ +public: + static double ParseType(const char* s) { + return static_cast<float>(atof(s)); + } +}; + + +} // namespace NRLibPrivate + +} // namespace NRLib + + +/// @todo Use correct exceptions. + +template <typename T> +bool NRLib::IsType(const std::string& s) +{ + std::istringstream i(s); + T x; + char c; + if (!(i >> x) || i.get(c)) + return false; + return true; +} + + +template <typename T> +T NRLib::ParseType(const std::string& s) +{ + std::istringstream i(s); + T x; + char c; + if (!(i >> x)) + throw Exception("Failed to convert \"" + s + "\" to " + typeid(T).name()); + if (i.get(c)) + throw Exception("Could not convert whole \"" + s + "\" to " + typeid(T).name()); + return x; +} + + +template <typename T> +std::string NRLib::ToString(const T obj, int precision) +{ + std::ostringstream o; + if (precision!=-99999) { + o << std::fixed << std::setprecision(precision); + } + if (!(o << obj)) { + throw Exception("Bad conversion."); + } + return o.str(); +} + + +template <typename I> +I NRLib::ParseAsciiArrayFast(std::string& s, I begin, size_t n) +{ + typedef typename std::iterator_traits<I>::value_type T; + std::string whitespace = " \n\r\f\t"; + + size_t pos = s.find_first_not_of(whitespace, 0); + size_t next_pos = s.find_first_of(whitespace, pos+1); + size_t i = 0; + while (i < n && pos != s.npos) { + if (next_pos != s.npos) { + s[next_pos] = '\0'; + } + *begin = NRLibPrivate::UnsafeParser<T>::ParseType(&s[pos]); + ++begin; + pos = s.find_first_not_of(whitespace, next_pos + 1); + next_pos = s.find_first_of(whitespace, pos + 1); + ++i; + } + + if (i != n) { + throw Exception("Not enough elements parsed from string."); + } + + return begin; +} + + +#endif // NRLIB_STRINGTOOLS_HPP diff --git a/ThirdParty/NRLib/nrlib/iotools/tabularfile.cpp b/ThirdParty/NRLib/nrlib/iotools/tabularfile.cpp new file mode 100644 index 0000000000..ee99086b60 --- /dev/null +++ b/ThirdParty/NRLib/nrlib/iotools/tabularfile.cpp @@ -0,0 +1,135 @@ +// $Id: tabularfile.cpp 1078 2012-09-25 11:13:53Z veralh $ + +// Copyright (c) 2011, Norwegian Computing Center +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// • Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// • Redistributions in binary form must reproduce the above copyright notice, this list of +// conditions and the following disclaimer in the documentation and/or other materials +// provided with the distribution. +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT +// SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include "tabularfile.hpp" + +#include <fstream> + +#include "fileio.hpp" + +#include "../exception/exception.hpp" + +namespace NRLib { + +TabularFile::TabularFile(const std::string& filename) +{ + size_t first_data_line, n_columns; + bool read_last_line; + std::string last_line; + if (!CheckFile(filename, first_data_line, n_columns, read_last_line, last_line)) + throw FileFormatError("The format of " + filename + " is not supported."); + + ReadFromFile(filename, first_data_line, n_columns, read_last_line); +} + + +TabularFile::TabularFile(const std::string & filename, + size_t first_data_line, + size_t n_columns, + bool read_last_line) +{ + ReadFromFile(filename, first_data_line, n_columns, read_last_line); +} + + +bool TabularFile::CheckFile(const std::string & filename, + size_t & first_data_line, + size_t & n_columns, + bool & read_last_line, + std::string & last_line) +{ + // Check if the last line of the file consists of data + // and make initial guess if the last line shoud be read (not reading when equal to 0 or -999) + std::ifstream in_file0; + OpenRead(in_file0, filename); + last_line = FindLastNonEmptyLine(in_file0); + std::vector<std::string> tokens = GetTokens(last_line); + read_last_line = true; + if (!IsType<double>(tokens[0])) { + read_last_line = false; + } + else { + for (size_t i = 0; i < tokens.size(); ++i) { + if (!IsType<double>(tokens[i])) + read_last_line = false; + else { + if(atof(tokens[i].c_str()) == 0.0 || atof(tokens[i].c_str()) == -999.0) + read_last_line = false; + } + } + } + std::ifstream in_file; + OpenRead(in_file, filename); + + int line_number = 0; + std::string line; + while (GetNextNonEmptyLine(in_file, line_number, line)) { + std::vector<std::string> tokens = GetTokens(line); + if (IsType<double>(tokens[0])) { + first_data_line = line_number; + n_columns = tokens.size(); + for (size_t i = 0; i < n_columns; ++i) { + if (!IsType<double>(tokens[i])) + return false; + } + return true; + } + } + return false; +} + + +void TabularFile::ReadFromFile(const std::string & filename, + size_t first_data_line, + size_t n_columns, + bool read_last_line) +{ + std::ifstream in_file; + OpenRead(in_file, filename); + std::string line; + + columns_.resize(n_columns); + std::vector<double> data(n_columns); + + // First line in file is line number 1. Read and discard up to first_data_line + for (size_t i = 1; i < first_data_line; ++i) { + std::getline(in_file, line); + } + std::string this_line, next_line; + std::getline(in_file, this_line); + while(std::getline(in_file, next_line)) { + ParseAsciiArrayFast(this_line, data.begin(), n_columns); + for (size_t i = 0; i < n_columns; ++i) { + columns_[i].push_back(data[i]); + } + this_line = next_line; + } + // Reading last line + if(read_last_line) { + ParseAsciiArrayFast(this_line, data.begin(), n_columns); + for (size_t i = 0; i < n_columns; ++i) { + columns_[i].push_back(data[i]); + } + } +} + + +} // namespace NRLib diff --git a/ThirdParty/NRLib/nrlib/iotools/tabularfile.hpp b/ThirdParty/NRLib/nrlib/iotools/tabularfile.hpp new file mode 100644 index 0000000000..e61d4722bc --- /dev/null +++ b/ThirdParty/NRLib/nrlib/iotools/tabularfile.hpp @@ -0,0 +1,70 @@ +// $Id: tabularfile.hpp 1078 2012-09-25 11:13:53Z veralh $ + +// Copyright (c) 2011, Norwegian Computing Center +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// • Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// • Redistributions in binary form must reproduce the above copyright notice, this list of +// conditions and the following disclaimer in the documentation and/or other materials +// provided with the distribution. +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT +// SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef NRLIB_IOTOOLS_TABULARFILE_HPP +#define NRLIB_IOTOOLS_TABULARFILE_HPP + +#include <cassert> +#include <string> +#include <vector> + +namespace NRLib { + +/// Class for files with tabular data, i.e. data values separated by a delimiter. +/// Currently only supports doubles separated by spaces with an optional text header. +class TabularFile +{ +public: + explicit TabularFile(const std::string& filename); + TabularFile(const std::string& filename, size_t first_data_line, size_t n_columns, bool read_last_line = true); + + /// Simple check of file. Just checks that the file contains tabular data. + /// \param[out] first_data_line Number of lines with header data. + static bool CheckFile(const std::string& filename, + size_t& first_data_line, + size_t& n_columns, + bool& read_last_line, + std::string& last_line); + + void ReadFromFile(const std::string& filename, + size_t first_data_line, + size_t n_columns, + bool read_last_line = true); + + size_t GetNColumns() const { return columns_.size(); } + + inline const std::vector<double>& GetColumn(size_t i) const; + +private: + std::vector<std::vector<double> > columns_; +}; + +// ========== INLINE FUNCTIONS ========= + +const std::vector<double>& TabularFile::GetColumn(size_t i) const +{ + assert(i < columns_.size()); + return columns_[i]; +} + +} // namespace NRLib + +#endif // NRLIB_IOTOOLS_TABULARFILE_HPP diff --git a/ThirdParty/NRLib/nrlib/stormgrid/module.mk b/ThirdParty/NRLib/nrlib/stormgrid/module.mk new file mode 100644 index 0000000000..a0468921c2 --- /dev/null +++ b/ThirdParty/NRLib/nrlib/stormgrid/module.mk @@ -0,0 +1,2 @@ +SRC += $(NRLIB_BASE_DIR)stormgrid/stormfaciesgrid.cpp \ + $(NRLIB_BASE_DIR)stormgrid/stormcontgrid.cpp \ No newline at end of file diff --git a/ThirdParty/NRLib/nrlib/stormgrid/stormcontgrid.cpp b/ThirdParty/NRLib/nrlib/stormgrid/stormcontgrid.cpp new file mode 100644 index 0000000000..727180a83f --- /dev/null +++ b/ThirdParty/NRLib/nrlib/stormgrid/stormcontgrid.cpp @@ -0,0 +1,788 @@ +// $Id: stormcontgrid.cpp 1190 2013-07-03 10:57:27Z ulvmoen $ + +// Copyright (c) 2011, Norwegian Computing Center +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// • Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// • Redistributions in binary form must reproduce the above copyright notice, this list of +// conditions and the following disclaimer in the documentation and/or other materials +// provided with the distribution. +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT +// SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include "stormcontgrid.hpp" +#include <cmath> +#include <fstream> +#include <math.h> +#include <locale> +#include <cassert> + +#include "../exception/exception.hpp" +#include "../iotools/fileio.hpp" +#include "../iotools/stringtools.hpp" +#include "../surface/surface.hpp" +#include "../surface/regularsurface.hpp" +#include "../surface/regularsurfacerotated.hpp" + +using namespace NRLib; + +const float STD_MISSING_CODE = -999.0F; +const std::string format_desc[2] = {"storm_petro_binary", + "storm_petro_ascii"}; + + +StormContGrid::StormContGrid(size_t nx, size_t ny, size_t nz) + : Grid<float>(nx, ny, nz, STD_MISSING_CODE) +{ + // Default values + file_format_ = STORM_BINARY; + missing_code_ = STD_MISSING_CODE; + zone_number_ = 0; + model_file_name_ = "ModelFile"; + variable_name_ = "UNKNOWN"; +} + +StormContGrid::StormContGrid(const Volume &vol, size_t nx, size_t ny, size_t nz) +:Volume(vol) +{ + file_format_ = STORM_BINARY; + missing_code_ = STD_MISSING_CODE; + zone_number_ = 0; + model_file_name_ = "ModelFile"; + variable_name_ = "UNKNOWN"; + Resize(nx,ny,nz); +} + +StormContGrid::StormContGrid(const Volume &vol, const Grid<float> & grid) +:Grid<float>(grid), + Volume(vol) +{ + file_format_ = STORM_BINARY; + missing_code_ = STD_MISSING_CODE; + zone_number_ = 0; + model_file_name_ = "ModelFile"; + variable_name_ = "UNKNOWN"; +} + +StormContGrid::StormContGrid(const std::string& filename, Endianess file_format) +{ + ReadFromFile(filename, true, file_format); +} + + +void StormContGrid::ReadFromFile(const std::string& filename, bool commonPath, Endianess number_representation) +{ + std::ifstream file; + OpenRead(file, filename, std::ios::in | std::ios::binary); + + std::string path = ""; + if (commonPath == true) + path = GetPath(filename); + + if (!file) { + throw new IOError("Error opening " + filename); + } + + // Current line number + int line = 0; + + // Header + try { + std::string token = ReadNext<std::string>(file, line); + if (token == format_desc[STORM_BINARY]) { + file_format_ = STORM_BINARY; + } + else if (token == format_desc[STORM_ASCII]) { + file_format_ = STORM_ASCII; + } + else if(token=="NORSAR") + { + std::string binfilename; + ReadSgriHeader(file, binfilename); + if (binfilename.empty()) + binfilename = NRLib::ReplaceExtension(filename, "Sgri"); + else + binfilename = path + "/" + binfilename; + std::ifstream binFile(binfilename.c_str(), std::ios::in | std::ios::binary); + if(!binFile) { + throw Exception("Error: Could not open Sgri binary file"+binfilename+"for reading.\n"); + return; + } + binFile.close(); + ReadSgriBinaryFile(binfilename); + file_format_ = STORM_BINARY; // when writing to file, use binary format. + zone_number_ = 0; + model_file_name_ = "ModelFile"; + variable_name_ = "UNKNOWN"; + return; + } + else { + throw FileFormatError("Unknown format: " + token); + } + + zone_number_ = ReadNext<int>(file, line); + model_file_name_ = ReadNext<std::string>(file, line); + missing_code_ = ReadNext<float>(file, line); + variable_name_ = ReadNext<std::string>(file, line); + + ReadVolumeFromFile(file, line, path); + + int nx = ReadNext<int>(file, line); + int ny = ReadNext<int>(file, line); + int nz = ReadNext<int>(file, line); + + Resize(nx, ny, nz); + + switch (file_format_) { + case STORM_BINARY: + DiscardRestOfLine(file, line, true); + ReadBinaryFloatArray(file, begin(), GetN(), number_representation); + break; + case STORM_ASCII: + ReadAsciiArrayFast(file, begin(), GetN()); + break; + default: + throw Exception("Bug in STORM grid parser: unknown fileformat"); + } + + try { + int n_barriers = ReadNext<int>(file, line); // line is now wrong. + if (n_barriers != 0) { + throw FileFormatError("Number of barriers greater than 0 found. " + "Only grids without barriers are supported."); + } + } + catch (EndOfFile& ) { + // Number of barriers not present in file. + } + } + catch (EndOfFile& ) { + throw FileFormatError("Unexcpected end of file found while parsing " + " \"" + filename + "\""); + } + catch (Exception& e) { + throw FileFormatError("Error parsing \"" + filename + "\" as a " + "STORM file : " + e.what()+"\n"); + } +} + + +void StormContGrid::WriteToFile(const std::string& filename, const std::string& predefinedHeader, bool plainAscii, Endianess file_format, bool remove_path) const +{ + std::ofstream file; + OpenWrite(file, filename, std::ios::out | std::ios::binary); + + //file.precision(14); + file.precision(4); + + // Header + if (predefinedHeader == "" && plainAscii==false) { + file << format_desc[file_format_] << "\n\n" + << zone_number_ << " " << model_file_name_ << " " + << missing_code_ << "\n\n" << variable_name_ << "\n\n" ; + + WriteVolumeToFile(file, filename, remove_path); + file << "\n"; + file << GetNI() << " " << GetNJ() << " " << GetNK() << "\n"; + } + else + file << predefinedHeader; + // Data + int n_data = 0; + switch (file_format_) { + case STORM_BINARY: + WriteBinaryFloatArray(file, begin(), end(), file_format); + break; + case STORM_ASCII: + for (const_iterator it = begin(); it != end(); ++it) { + file << *it << " "; + ++n_data; + if (n_data % 10 == 0) { + file << "\n"; + } + } + break; + default: + throw Exception("Unknown fileformat"); + } + + // Final 0 (Number of barriers) + if (plainAscii==false) + file << 0; +} + +void StormContGrid::WriteToSgriFile(const std::string & file_name, + const std::string & file_name_header, + const std::string & label, + double simbox_dz, + Endianess file_format) const +{ + // Header + double vert_scale = 0.001; + double hor_scale = 0.001; + + std::ofstream header_file; + NRLib::OpenWrite(header_file, file_name_header); + + header_file << "NORSAR General Grid Format v1.0\n"; + header_file << "3\n"; + header_file << "X (km)\n"; + header_file << "Y (km)\n"; + header_file << "T (s)\n"; + header_file << "FFT-grid\n"; + header_file << "1\n"; + header_file << label << std::endl; + header_file << "1 1 1\n"; + + double z_max = GetZMax(); + double z_min = GetZMin(); + +/* float dz = static_cast<float> (floor(simbox->getdz()+0.5)); //To have the same sampling as in SegY + if (dz == 0.0) + dz = 1.0; */ + float dz = static_cast<float> (simbox_dz); + int nz = static_cast<int> (ceil((z_max - z_min)/dz)); + int ny = static_cast<int>(GetNJ()); + int nx = static_cast<int>(GetNI()); + header_file << nx << " " << ny << " " << nz << std::endl; + header_file << std::setprecision(10); + header_file << GetDX()*hor_scale << " " << GetDY()*hor_scale << " " << dz*vert_scale << std::endl; + double x0 = GetXMin() + 0.5 * GetDX(); + double y0 = GetYMin() + 0.5 * GetDY(); + double z0 = z_min + 0.5 * dz; + header_file << x0*hor_scale << " " << y0*hor_scale << " " << z0*vert_scale << std::endl; + header_file << GetAngle() << " 0\n"; + header_file << missing_code_ << std::endl; + + //fName = fileName + IO::SuffixSgri(); + header_file << file_name << std::endl; + header_file << "0\n"; + + std::ofstream file; + OpenWrite(file, file_name, std::ios::out | std::ios::binary); + + file.precision(14); + + // Data + WriteBinaryFloatArray(file, begin(), end(), file_format); + + // Final 0 (Number of barriers) + file << 0; +} + + +/// \todo Common implementation with StormFaciesGrid +size_t StormContGrid::FindIndex(double x, double y, double z) const +{ + size_t i, j, k; + FindIndex(x, y, z, i, j, k); + return GetIndex(i, j, k); +} + +void StormContGrid::FindXYIndex(double x, double y, size_t& i_out, size_t& j_out) const +{ + double local_x, local_y; + + GlobalToLocalCoord(x, y, local_x, local_y); + + i_out = static_cast<size_t>(local_x / GetDX()); + j_out = static_cast<size_t>(local_y / GetDY()); + + if(i_out >= GetNI()) { + std::string text ="Trying to look up an xy-position outside grid. Index in x direction is too large.\n"; + text += " Index : "+ToString(i_out)+"\n"; + text += " Max : "+ToString(GetNI())+"\n"; + throw Exception(text); + } + if(j_out >= GetNJ()) { + std::string text ="Trying to look up an xy-position outside grid: Index in y direction is too large.\n"; + text += " Index : "+ToString(j_out)+"\n"; + text += " Max : "+ToString(GetNJ())+"\n"; + throw Exception(text); + } + if(local_x < 0.0) { + std::string text ="Trying to look up an xy-position outside grid: Local x-coordinate is too small ("+NRLib::ToString(local_x, 2)+").\n"; + throw Exception(text); + } + if(local_y < 0.0) { + std::string text ="Trying to look up an xy-position outside grid: Local y-coordinate is too small ("+NRLib::ToString(local_y, 2)+").\n"; + throw Exception(text); + } +} + +void StormContGrid::FindIndex(double x, double y, double z, size_t& i_out, size_t& j_out, size_t& k_out) const +{ + + FindXYIndex(x, y, i_out, j_out); + + double z_top = GetTopSurface().GetZ(x, y); + double z_bot = GetBotSurface().GetZ(x, y); + double dz = (z_bot - z_top) / GetNK(); + + if(z < z_top) + throw Exception("Z value is above top.\n"); + if(z > z_bot) + throw Exception("Z value is below bottom. \n"); + if (dz == 0) { + k_out = 0; + } + else { + k_out = static_cast<size_t>((z - z_top)/dz); + } + +} + + +void StormContGrid::FindZInterpolatedIndex(const double & x, + const double & y, + const double & z, + size_t & ind1, + size_t & ind2, + double & t) const +{ + + size_t i; + size_t j; + size_t k; + + FindXYIndex(x, y, i, j); + + double z_top = GetTopSurface().GetZ(x, y); + double z_bot = GetBotSurface().GetZ(x, y); + double dz = (z_bot - z_top) / GetNK(); + + if (z<=z_top+0.5*dz) { + k = 0; + t = missing_code_; + ind1 = GetIndex(i, j, k); + ind2 = 0; + } + else if (z>=z_bot-0.5*dz) { + k = GetNK()-1; + t = missing_code_; + ind1 = GetIndex(i, j, k); + ind2 = 0; + } + else { + k = static_cast<size_t>(floor(((z - z_top) / dz) - 0.5)); + t = (z-z_top)/dz - 0.5 - static_cast<double>(k); + ind1 = GetIndex(i, j, k); + ind2 = GetIndex(i, j, k+1); + } +} + +float StormContGrid::GetValueZInterpolatedFromIndex(const size_t & ind1, + const size_t & ind2, + const double & t) const +{ + float value; + + if (t == missing_code_) + value = (*this)(ind1); + + else { + float v1 = (*this) (ind1); + float v2 = (*this) (ind2); + + if(v1 != missing_code_) { + if(v2 != missing_code_) + value = static_cast<float>(v1*(1-t) + v2*t); + else + value = v1; + } + else + value = v2; //Ok even if v2 is missing, then both are missing so missing is result. + } + + return(value); +} + +double StormContGrid::GetValueZInterpolatedFromIndexNoMissing(const size_t & ind1, + const size_t & ind2, + const double & t) const +{ // Removed tests for missing from identical function + // GetValueZInterpolatedFromIndex to decrease computation time for multizone background model + double value; + + if (t == missing_code_) + value = (*this)(ind1); + + else { + float v1 = (*this) (ind1); + float v2 = (*this) (ind2); + + value = v1*(1-t) + v2*t; + } + + return(value); +} + +float StormContGrid::GetValueInterpolated(const int & i, + const int & j, + const float & k_value) const +{ + float value, val1, val2; + + int k1 = int(floor(k_value)); + val1 = GetValue(i, j, k1); + if (val1 == missing_code_) + return(missing_code_); + + int k2 = k1+1; + if (k1 == static_cast<int>(GetNK()-1)) + k2 = k1; + + val2 = GetValue(i, j, k2); + if (val2 == missing_code_) + return (val1); + + value = float(1.0-(k_value-k1))*val1+float(k_value-k1)*val2; + return(value); + +} + +float StormContGrid::GetValueZInterpolated(double x, double y, double z)const +{ + + size_t ind1; + size_t ind2; + double t; + + FindZInterpolatedIndex(x, y, z, ind1, ind2, t); + + float value = GetValueZInterpolatedFromIndex(ind1, ind2, t); + + return(value); +} + + +float StormContGrid::GetValueClosestInZ(double x, double y, double z)const +{ + double local_x, local_y; + GlobalToLocalCoord(x, y, local_x, local_y); + + size_t i = static_cast<size_t>(local_x / GetDX()); + size_t j = static_cast<size_t>(local_y / GetDY()); + double z_top = GetTopSurface().GetZ(x, y); + double z_bot = GetBotSurface().GetZ(x, y); + double dz = (z_bot - z_top) / GetNK(); + if (local_x < 0.0 || i >= GetNI() || local_y < 0.0 || j >= GetNJ()) + return(missing_code_); + + if (z<z_top+0.5*dz) + z = z_top+0.5*dz; + else if (z>z_bot+0.5*dz) + z = z_bot+0.5*dz; + + int zInd1 = static_cast<int>(floor((z-z_top)/dz)-0.5); + double t = (z-z_top)/dz - 0.5 - static_cast<double>(zInd1); + int zInd2 = zInd1+1; + float value = static_cast<float>((1-t)*(*this)(GetIndex(i,j,zInd1))+t*(*this)(GetIndex(i,j,zInd2))); + return(value); +} + + +void StormContGrid::FindCenterOfCell(size_t i, size_t j, size_t k, + double& x, double& y, double& z) const +{ + double xloc = (i+0.5)*GetDX(); + double yloc = (j+0.5)*GetDY(); + LocalToGlobalCoord(xloc, yloc, x, y); + double z_top = GetTopSurface().GetZ(x, y); + double z_bot = GetBotSurface().GetZ(x, y); + double dz = (z_bot - z_top) / GetNK(); + z = z_top + (k+0.5)*dz; +} + + +double StormContGrid::RecalculateLZ() +{ + double lz = 0; + for (size_t i = 0; i < GetNI(); ++i) { + for (size_t j = 0; j < GetNJ(); ++j) { + double x, y; + LocalToGlobalCoord(i * GetDX(), j * GetDY(), x, y); + lz = std::max(lz, GetBotSurface().GetZ(x, y) - + GetTopSurface().GetZ(x, y)); + } + } + return lz; +} + +void StormContGrid::ReadSgriHeader(std::ifstream &headerFile, std::string &binFileName) +{ + // std::ifstream headerFile(filename.c_str(), std::ios::in); //checkFileOpen performed previously + int i; + std::string tmpStr; + int dim; + //Reading record 1: Version header + getline(headerFile, tmpStr); + //Reading record 2: Grid dimension + headerFile >> dim; + if(dim!=3) + throw Exception("Wrong dimension of Sgri file. Must be 3."); + + getline(headerFile, tmpStr); + //Reading record 3 ... 3+dim: Axis labels + grid value label + std::vector<std::string> axisLabels(dim); + for (i=0; i<dim; i++) + getline(headerFile, axisLabels[i]); + getline(headerFile, tmpStr); + //int config = IMISSING; + + + //Reading record 4+dim: Number of grids + int nGrid; + headerFile >> nGrid; + if (nGrid < 1) { + throw Exception("Error: Number of grids read from sgri file must be >0"); + } + getline(headerFile, tmpStr); + //Reading record 5+dim ... 5+dim+ngrid-1: Grid labels + + for (i=0; i<nGrid; i++) + getline(headerFile, tmpStr); + + float *dValues1 = new float[dim]; + float *dValues2 = new float[dim]; + int *iValues = new int[dim]; + //Reading record 5+dim+ngrid: Scaling factor of grid values + for (i=0; i<dim; i++) + headerFile >> dValues1[i]; + getline(headerFile,tmpStr); + //Reading record 6+dim+ngrid: Number of samples in each dir. + for (i=0; i<dim; i++) + headerFile >> iValues[i]; + getline(headerFile,tmpStr); + //Reading record 7+dim+ngrid: Grid sampling in each dir. + for (i=0; i<dim; i++) { + headerFile >> dValues2[i]; + } + getline(headerFile,tmpStr); + //Reading record 8+dim+ngrid: First point coord. + float *minValues = new float[dim]; + for (i=0; i<dim; i++) + { + headerFile >> minValues[i]; + } + + int nX=1; + int nY=1; + int nZ=1; + double dX, dY, dZ; + // scaleX_ = dValues1[0]; + nX = iValues[0]; + dX = dValues2[0]; + // scaleY_ = dValues1[1]; + nY = iValues[1]; + dY = dValues2[1]; + // scaleZ_ = dValues1[2]; + nZ = iValues[2]; + dZ = dValues2[2]; + if (nX < 1) { + throw Exception("Error: Number of samples in X-dir must be >= 1.\n"); + } + if (nY < 1) { + throw Exception("Error: Number of samples in Y-dir must be >= 1.\n"); + } + if (nZ < 1) { + throw Exception("Error: Number of samples in Z-dir must be >= 1.\n"); + } + if (dX <= 0.0) { + throw Exception("Error: Grid sampling in X-dir must be > 0.0.\n"); + + } + if (dY <= 0.0) { + throw Exception("Error: Grid sampling in Y-dir must be > 0.0.\n"); + } + if (dZ <= 0.0) { + throw Exception("Error: Grid sampling in Z-dir must be > 0.0.\n"); + } + + double lx = nX*dX; + double ly = nY*dY; + //double lz = (nY-1)*dZ; + + double x_min = minValues[0]-0.5*dX; + double y_min = minValues[1]-0.5*dY; + // z0_ = -0.5f * (nZ-1)*dZ; + SetDimensions(x_min,y_min,lx, ly); + delete [] dValues1; + delete [] dValues2; + delete [] iValues; + Resize(nX,nY,nZ); + //Reading record 9+dim+ngrid: Angle of rotation + + double angle; + headerFile >> angle; + // SetAngle(angle*NRLib::PI/180.0); + SetAngle(angle); + double dipangle; + headerFile >> dipangle; + + if(dipangle==0) + { + ConstantSurface<double> z_top(minValues[2]-0.5*dZ); + ConstantSurface<double> z_bot(minValues[2]+nZ*dZ-0.5*dZ); + SetSurfaces(z_top,z_bot); + //z_top_ = new RegularSurface<double>(x_min_,y_min_,lx_,ly_,nX,nY,-0.5f*(nZ-1)*dZ); + // z_bot_ = new RegularSurface<double>(x_min_,y_min_,lx_,ly_,nX,nY, 0.5f*(nZ-1)*dZ); + } + else + { + + RegularSurfaceRotated<double> z_top(x_min,y_min,lx,ly,nX,nY,dipangle,minValues[2]-0.5*dZ); + RegularSurfaceRotated<double> z_bot(x_min,y_min,lx,ly,nX,nY,dipangle,minValues[2]+nZ*dZ-0.5*dZ); + /* int i,j; + for(i=0;i<nX;i++) + for(j=0;j<nY;j++) + { + (*z_top)(i,j)+=i*nX*tan(dipangle); + (*z_bot)(i,j)+=i*nX*tan(dipangle); + }*/ + SetSurfaces(z_top,z_bot); + } + delete [] minValues; + RecalculateLZ(); + //erosion_top_ = new ConstantSurface<double>(0.0); + //erosion_bot_ = new ConstantSurface<double>(0.0); + getline(headerFile, tmpStr); + //Reading record 10+dim+ngrid: Undef value + headerFile >> missing_code_; + getline(headerFile, tmpStr); + //Reading record 11+dim+ngrid: Filename of binary file. + getline(headerFile, tmpStr); + if (tmpStr.empty()) + binFileName = ""; + else { + std::locale loc; + int i = 0; + char c = tmpStr[i]; + while (!std::isspace(c,loc)) { + i++; + c = tmpStr[i]; + } + tmpStr.erase(tmpStr.begin()+i, tmpStr.end()); + binFileName = tmpStr; + } + //Reading record 12+dim+ngrid: Complex values + bool hasComplex; + headerFile >> hasComplex; + if (hasComplex != 0 ) { + throw Exception("Error: Can not read Sgri binary file. Complex values?"); + + } + //The remaining records are not relevant, stop reading + + +} +void StormContGrid::ReadSgriBinaryFile(const std::string& filename) +{ + std::ifstream binFile(filename.c_str(),std::ios::in | std::ios::binary); //Check opening of file before calling this function + try { + ReadBinaryFloatArray(binFile, begin(), GetN()); + } + catch (Exception& e) { + throw Exception("Error: Reading from binary sgri file " +filename + "." + e.what() +"\n"); + + } + + return; + +} + +void +StormContGrid::WriteCravaFile(const std::string & file_name, + double inline_0, + double crossline_0, + double il_step_x, + double il_step_y, + double xl_step_x, + double xl_step_y) +{ + try { + std::ofstream bin_file; + //std::string f_name = file_name + IO::SuffixCrava(); + NRLib::OpenWrite(bin_file, file_name, std::ios::out | std::ios::binary); + + std::string file_type = "crava_fftgrid_binary"; + bin_file << file_type << "\n"; + + NRLib::WriteBinaryDouble(bin_file, GetXMin()); + NRLib::WriteBinaryDouble(bin_file, GetYMin()); + NRLib::WriteBinaryDouble(bin_file, GetDX()); + NRLib::WriteBinaryDouble(bin_file, GetDY()); + NRLib::WriteBinaryInt(bin_file, static_cast<int>(GetNI())); + NRLib::WriteBinaryInt(bin_file, static_cast<int>(GetNJ())); + NRLib::WriteBinaryDouble(bin_file, inline_0); + NRLib::WriteBinaryDouble(bin_file, crossline_0); + NRLib::WriteBinaryDouble(bin_file, il_step_x); + NRLib::WriteBinaryDouble(bin_file, il_step_y); + NRLib::WriteBinaryDouble(bin_file, xl_step_x); + NRLib::WriteBinaryDouble(bin_file, xl_step_y); + NRLib::WriteBinaryDouble(bin_file, GetAngle()); + NRLib::WriteBinaryInt(bin_file, static_cast<int>(GetNI())); + NRLib::WriteBinaryInt(bin_file, static_cast<int>(GetNJ())); + NRLib::WriteBinaryInt(bin_file, static_cast<int>(GetNK())); + + //for(int i=0;i<rsize_;i++) + // NRLib::WriteBinaryFloat(binFile, rvalue_[i]); + + float value = 0.0f; + for (size_t i = 0; i < GetNI(); i++) { + for (size_t j = 0; j < GetNJ(); j++) { + for (size_t k = 0; k < GetNK(); k++) { + value = GetValue(i, j, k); + NRLib::WriteBinaryFloat(bin_file, value); + } + } + } + + bin_file.close(); + } + catch (NRLib::Exception & e) { + std::string message = "Error: "+std::string(e.what())+"\n"; + throw Exception(message); + } +} + +double StormContGrid::GetAvgRelThick(void) const +{ + double avgThick = 0.0f; + for (int i = 0 ; i < static_cast<int>(GetNI()); i++) { + for (int j = 0 ; j < static_cast<int>(GetNJ()) ; j++) { + avgThick += GetRelThick(i, j); + } + } + avgThick /= GetNI()*GetNJ(); + return avgThick; +} + +double StormContGrid::GetRelThick(int i, int j) const +{ + double rx = (static_cast<double>(i) + 0.5)*GetDX(); + double ry = (static_cast<double>(j) + 0.5)*GetDY(); + double x = rx*cos(GetAngle())-ry*sin(GetAngle()) + GetXMin(); + double y = rx*sin(GetAngle())+ry*cos(GetAngle()) + GetYMin(); + return(GetRelThick(x, y)); +} + +double StormContGrid::GetRelThick(double x, double y) const +{ + double relThick = 1; //Default value to be used outside grid. + double zTop = GetTopSurface().GetZ(x,y); + double zBot = GetBotSurface().GetZ(x,y); + if(GetTopSurface().IsMissing(zTop) == false && + GetBotSurface().IsMissing(zBot) == false) + relThick = (zBot-zTop)/GetLZ(); + return(relThick); +} diff --git a/ThirdParty/NRLib/nrlib/stormgrid/stormcontgrid.hpp b/ThirdParty/NRLib/nrlib/stormgrid/stormcontgrid.hpp new file mode 100644 index 0000000000..a00d1a1499 --- /dev/null +++ b/ThirdParty/NRLib/nrlib/stormgrid/stormcontgrid.hpp @@ -0,0 +1,152 @@ +// $Id: stormcontgrid.hpp 1190 2013-07-03 10:57:27Z ulvmoen $ + +// Copyright (c) 2011, Norwegian Computing Center +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// • Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// • Redistributions in binary form must reproduce the above copyright notice, this list of +// conditions and the following disclaimer in the documentation and/or other materials +// provided with the distribution. +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT +// SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef NRLIB_STORMCONTGRID_HPP +#define NRLIB_STORMCONTGRID_HPP + +#include <string> + +#include "../volume/volume.hpp" +#include "../grid/grid.hpp" +#include "../iotools/fileio.hpp" + +namespace NRLib { + class StormContGrid : public Grid<float>, public Volume { + public: + enum FileFormat {STORM_BINARY = 0, STORM_ASCII}; + + explicit StormContGrid(const std::string& filename, Endianess file_format = END_BIG_ENDIAN); + explicit StormContGrid(size_t nx = 0, size_t ny = 0, size_t nz = 0); + explicit StormContGrid(const Volume &vol, const Grid<float> & grid); + explicit StormContGrid(const Volume &vol, size_t nx = 0, size_t ny = 0, size_t nz = 0); + + void SetMissingCode(float missing_code) + { missing_code_ = missing_code; } + + float GetMissingCode() const + { return missing_code_; } + + bool IsMissing(float val) const + { return val == missing_code_; } + + void SetFormat(FileFormat format) + { file_format_ = format; } + + FileFormat GetFormat() const + { return file_format_; } + + void SetModelFileName(const std::string& filename) + { model_file_name_ = filename; } + + std::string GetModelFileName() const + { return model_file_name_; } + + void SetVariableName(const std::string& name) + { variable_name_ = name; } + + std::string GetVariableName() const + { return variable_name_; } + + void SetZoneNumber(int zone_number) + { zone_number_ = zone_number; } + + int GetZoneNumber() const + { return zone_number_; } + + /// Write to file. If predefinedHeader is not empty, this header is written instead + /// of standard, and surfaces are not written. + void WriteToFile(const std::string& filename, + const std::string& predefinedHeader = "", + bool plainAscii=false, + Endianess file_format = END_BIG_ENDIAN, + bool remove_path = true) const; + + void WriteToSgriFile(const std::string & file_name, + const std::string & file_name_header, + const std::string & label, + double simbox_dz, + Endianess file_format = END_BIG_ENDIAN) const; + + /// \throw IOError if the file can not be opened. + /// \throw FileFormatError if file format is not either storm_binary or storm_ascii, or if grid contains barriers. + void ReadFromFile(const std::string& filename, bool commonPath = true, Endianess file_format = END_BIG_ENDIAN); + + double GetDX() const { return GetLX() / GetNI(); } + double GetDY() const { return GetLY() / GetNJ(); } + size_t FindIndex(double x, double y, double z) const; + void FindIndex( double x, double y, double z, size_t& i_out, size_t& j_out, size_t& k_out) const; + void FindXYIndex(double x, double y, size_t& i_out, size_t& j_out) const; + + void FindZInterpolatedIndex(const double & x, + const double & y, + const double & z, + size_t & ind1, + size_t & ind2, + double & t) const; + + float GetValueZInterpolatedFromIndex(const size_t & ind1, + const size_t & ind2, + const double & t) const; + + double GetValueZInterpolatedFromIndexNoMissing(const size_t & ind1, + const size_t & ind2, + const double & t) const; + + float GetValueInterpolated(const int & i, + const int & j, + const float & k_value) const; + + double GetAvgRelThick() const; + + float GetValueZInterpolated(double x, double y, double z)const; + float GetValueClosestInZ(double x, double y, double z)const; + double GetZMin()const { return Volume::GetZMin(GetNI(), GetNJ()); } + double GetZMax()const { return Volume::GetZMax(GetNI(), GetNJ()); } + + void FindCenterOfCell(size_t i, size_t j, size_t k, + double& x, double& y, double& z) const; + + void WriteCravaFile(const std::string & file_name, + double inline_0, + double crossline_0, + double il_step_x, + double il_step_y, + double xl_step_x, + double xl_step_y); + + private: + double RecalculateLZ(); + void ReadSgriHeader(std::ifstream &headerFile, std::string &binFileName); + void ReadSgriBinaryFile(const std::string& filename); + + double GetRelThick(int i, int j) const; + double GetRelThick(double x, double y) const; + + FileFormat file_format_; + float missing_code_; + int zone_number_; + std::string model_file_name_; + std::string variable_name_; +}; + +} + +#endif // NRLIB_STORMCONTGRID_HPP diff --git a/ThirdParty/NRLib/nrlib/stormgrid/stormfaciesgrid.cpp b/ThirdParty/NRLib/nrlib/stormgrid/stormfaciesgrid.cpp new file mode 100644 index 0000000000..b5e978db77 --- /dev/null +++ b/ThirdParty/NRLib/nrlib/stormgrid/stormfaciesgrid.cpp @@ -0,0 +1,347 @@ +// $Id: stormfaciesgrid.cpp 882 2011-09-23 13:10:16Z perroe $ + +// Copyright (c) 2011, Norwegian Computing Center +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// • Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// • Redistributions in binary form must reproduce the above copyright notice, this list of +// conditions and the following disclaimer in the documentation and/or other materials +// provided with the distribution. +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT +// SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include "stormfaciesgrid.hpp" + +#include <fstream> + +#include "../exception/exception.hpp" +#include "../iotools/fileio.hpp" +#include "../iotools/stringtools.hpp" +#include "../surface/surface.hpp" + +using namespace NRLib; + +const int STD_MISSING_CODE = -999; +const std::string format_desc[2] = {"storm_facies_binary", + "storm_facies_ascii"}; + +StormFaciesGrid::StormFaciesGrid(const std::string& filename,Endianess file_format ) +{ + ReadFromFile(filename, true, file_format); +} + + +StormFaciesGrid::StormFaciesGrid(size_t nx, size_t ny, size_t nz) + : Grid<int>(nx, ny, nz, STD_MISSING_CODE) +{ + // Default values + file_format_ = STORM_BINARY; + missing_code_ = STD_MISSING_CODE; + zone_number_ = 0; + model_file_name_ = "ModelFile"; +} + +StormFaciesGrid::StormFaciesGrid(const Volume &vol, size_t nx, size_t ny, size_t nz) +:Volume(vol) +{ + file_format_ = STORM_BINARY; + missing_code_ = STD_MISSING_CODE; + zone_number_ = 0; + model_file_name_ = "ModelFile"; + Resize(nx,ny,nz); + +} + + +int StormFaciesGrid::GetFaciesCode(int body_index) const +{ + if (body_index < 0 || body_index >= static_cast<int>(body_facies_.size())) { + throw Exception("Body index " + ToString(body_index) + + " is outside the defined range [0, " + ToString(body_facies_.size()) ); + } + + return body_facies_[body_index]; +} + + +int StormFaciesGrid::GetFaciesFromCell(size_t cell_index) const +{ + return GetFaciesCode((*this)(cell_index)); +} + + +const std::string& StormFaciesGrid::GetFaciesName(int facies_code) const +{ + if (facies_code < 0 || facies_code >= static_cast<int>(facies_names_.size())) { + throw Exception("Body index " + ToString(facies_code) + " is outside " + + "the valid range [0, " + ToString(facies_names_.size()-1) + "]." ); + } + + return facies_names_[facies_code]; +} + +void StormFaciesGrid::SetBodyFacies(const std::vector<int>& body_facies) +{ + body_facies_ = body_facies; +} + +void StormFaciesGrid::SetFaciesNames(const std::vector<std::string>& facies_names) +{ + facies_names_ = facies_names; +} + + +void StormFaciesGrid::WriteToFile(const std::string& filename, Endianess file_format) const +{ + CheckConsistency(); + + std::ofstream file; + OpenWrite(file, filename, std::ios::out | std::ios::binary); + + file << format_desc[file_format_] << "\n\n" + << zone_number_ << " " << model_file_name_ << " " + << missing_code_ << "\n\n"; + + file << facies_names_.size() << "\n"; + /// \todo Print on several lines, if there are many facies. + for (size_t i = 0; i < facies_names_.size(); ++i) { + file << facies_names_[i] << " "; + } + file << "\n\n"; + + file << body_facies_.size() << "\n"; + for (size_t i = 0; i < body_facies_.size(); ++i) { + file << body_facies_[i] << " "; + } + file << "\n\n"; + + WriteVolumeToFile(file, filename); + file << "\n"; + file << GetNI() << " " << GetNJ() << " " << GetNK() << "\n"; + + // Data + int n_data = 0; + switch (file_format_) { + case STORM_BINARY: + WriteBinaryIntArray(file, begin(), end(), file_format); + break; + case STORM_ASCII: + for (const_iterator it = begin(); it != end(); ++it) { + file << *it << " "; + ++n_data; + if (n_data % 10 == 0) { + file << "\n"; + } + } + break; + default: + throw Exception("Unknown fileformat"); + } + + // Final 0 (Number of barriers) + file << 0; +} + + +void StormFaciesGrid::ReadFromFile(const std::string& filename, bool commonPath,Endianess file_format) +{ + std::ifstream file; + OpenRead(file, filename, std::ios::in | std::ios::binary); + + std::string path = ""; + if (commonPath == true) + path = GetPath(filename); + // Current line number + int line = 0; + + // Header + try { + std::string token = ReadNext<std::string>(file, line); + if (token == format_desc[STORM_BINARY]) { + file_format_ = STORM_BINARY; + } + else if (token == format_desc[STORM_ASCII]) { + file_format_ = STORM_ASCII; + } + else { + throw FileFormatError("Unknown format: " + token); + } + + zone_number_ = ReadNext<int>(file, line); + model_file_name_ = ReadNext<std::string>(file, line); + missing_code_ = ReadNext<int>(file, line); + + int size = ReadNext<int>(file, line); + facies_names_.resize(size); + for (int i = 0; i < size; ++i) { + facies_names_[i] = ReadNext<std::string>(file, line); + } + + size = ReadNext<int>(file, line); + body_facies_.resize(size); + for (int i = 0; i < size; ++i) { + body_facies_[i] = ReadNext<int>(file, line); + } + + ReadVolumeFromFile(file, line, path); + + int nx = ReadNext<int>(file, line); + int ny = ReadNext<int>(file, line); + int nz = ReadNext<int>(file, line); + + Resize(nx, ny, nz); + + switch (file_format_) { + case STORM_BINARY: + DiscardRestOfLine(file, line, true); + ReadBinaryIntArray(file, begin(), GetN(), file_format); + break; + case STORM_ASCII: + ReadAsciiArrayFast(file, begin(), GetN()); + break; + default: + throw Exception("Bug in STORM grid parser: unknown fileformat"); + } + + try { + int n_barriers = ReadNext<int>(file, line); // line is now wrong. + if (n_barriers != 0) { + throw FileFormatError("Number of barriers greater than 0 found. " + "Only grids without barriers are supported."); + } + } + catch (EndOfFile& ) { + // Number of barriers not present in file. + } + } + catch (EndOfFile& ) { + throw FileFormatError("Unexcpected end of file found while parsing " + " \"" + filename + "\""); + } + catch (Exception& e) { + throw FileFormatError("Error parsing \"" + filename + "\" as a " + "STORM file at line " + ToString(line) + ":" + e.what()); + } + + CheckConsistency(); +} + + +void StormFaciesGrid::CheckConsistency() const +{ + for (size_t i = 0; i < body_facies_.size(); ++i) { + if (body_facies_[i] < 0 || + body_facies_[i] >= static_cast<int>(facies_names_.size())) { + throw Exception("Consistency check failed: facies " + + ToString(body_facies_[i]) + " in body " + ToString(i) + + " is outside the valid range [0, " + + ToString(facies_names_.size()-1) + "]."); + } + } + + for (size_t ind = 0; ind < GetN(); ++ind) { + int body = (*this)(ind); + if ( !IsMissing(body) + && (body < 0 || body > static_cast<int>(body_facies_.size())) ) { + size_t i, j, k; + GetIJK(ind, i, j, k); + throw Exception("Consistency check failed: body number " + + ToString(body) + " in cell (" + ToString(i) + ", " + ToString(j) + + ", " + ToString(k) + ") is outside the valid range [0, " + + ToString(body_facies_.size()-1) + "]."); + } + } +} + +size_t StormFaciesGrid::FindIndex(double x, double y, double z) const +{ + size_t i, j, k; + FindIndex(x, y, z, i, j, k); + return GetIndex(i, j, k); +} + +void StormFaciesGrid::FindIndex(double x, double y, double z, size_t& i_out, size_t& j_out, size_t& k_out) const +{ + double local_x, local_y; + GlobalToLocalCoord(x, y, local_x, local_y); + + i_out = static_cast<size_t>(local_x / GetDX()); + j_out = static_cast<size_t>(local_y / GetDY()); + if(i_out >= GetNI()) + throw Exception("Index in x direction is too large.\n"); + if(j_out >= GetNJ()) + throw Exception("Index in y direction is too large.\n"); + double z_top = GetTopSurface().GetZ(x, y); + double z_bot = GetBotSurface().GetZ(x, y); + double dz = (z_bot - z_top) / GetNK(); + + if(z < z_top) + throw Exception("Z value is above top.\n"); + if(z > z_bot) + throw Exception("Z value is below bottom. \n"); + if (dz == 0) { + k_out = 0; + } + else { + k_out = static_cast<size_t>((z - z_top)/dz); + } + +} +/* +/// \todo Common implementation with StormContGrid +size_t StormFaciesGrid::FindIndex(double x, double y, double z) const +{ + double local_x, local_y; + GlobalToLocalCoord(x, y, local_x, local_y); + + size_t i = static_cast<size_t>(local_x / GetDX()); + size_t j = static_cast<size_t>(local_y / GetDY()); + double z_top = GetTopSurface().GetZ(x, y); + double z_bot = GetBotSurface().GetZ(x, y); + double dz = (z_bot - z_top) / GetNK(); + size_t k; + if (dz == 0) { + k = 0; + } + else { + k = static_cast<size_t>((z - z_top)/dz); + } + + return GetIndex(i, j, k); +} +*/ + +double StormFaciesGrid::RecalculateLZ() +{ + double lz = 0; + for (size_t i = 0; i < GetNI(); ++i) { + for (size_t j = 0; j < GetNJ(); ++j) { + double x, y; + LocalToGlobalCoord(i * GetDX(), j * GetDY(), x, y); + lz = std::max(lz, GetBotSurface().GetZ(x, y) - + GetTopSurface().GetZ(x, y)); + } + } + return lz; +} + +void StormFaciesGrid::FindCenterOfCell(size_t i, size_t j, size_t k, + double& x, double& y, double& z) const +{ + double xloc = (i+0.5)*GetDX(); + double yloc = (j+0.5)*GetDY(); + LocalToGlobalCoord(xloc, yloc, x, y); + double z_top = GetTopSurface().GetZ(x, y); + double z_bot = GetBotSurface().GetZ(x, y); + double dz = (z_bot - z_top) / GetNK(); + z = z_top + (k+0.5)*dz; +} diff --git a/ThirdParty/NRLib/nrlib/stormgrid/stormfaciesgrid.hpp b/ThirdParty/NRLib/nrlib/stormgrid/stormfaciesgrid.hpp new file mode 100644 index 0000000000..3be36b77c1 --- /dev/null +++ b/ThirdParty/NRLib/nrlib/stormgrid/stormfaciesgrid.hpp @@ -0,0 +1,97 @@ +// $Id: stormfaciesgrid.hpp 883 2011-09-26 09:17:05Z perroe $ + +// Copyright (c) 2011, Norwegian Computing Center +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// • Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// • Redistributions in binary form must reproduce the above copyright notice, this list of +// conditions and the following disclaimer in the documentation and/or other materials +// provided with the distribution. +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT +// SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef NRLIB_STORMFACIESGRID_HPP +#define NRLIB_STORMFACIESGRID_HPP + +#include "../volume/volume.hpp" +#include "../grid/grid.hpp" +#include "../iotools/fileio.hpp" + +namespace NRLib { + class StormFaciesGrid : public Grid<int>, public Volume { + public: + enum FileFormat {STORM_BINARY = 0, STORM_ASCII}; + + explicit StormFaciesGrid(const std::string& filename,Endianess file_format = END_BIG_ENDIAN); + explicit StormFaciesGrid(size_t nx = 0, size_t ny = 0, size_t nz = 0); + explicit StormFaciesGrid(const Volume &vol, size_t nx, size_t ny, size_t nz); + + void SetMissingCode(int missing_code) + { missing_code_ = missing_code; } + int GetMissingCode() const + { return missing_code_; } + bool IsMissing(int val) const + { return val == missing_code_; } + + void SetFormat(FileFormat format) + { file_format_ = format; } + + FileFormat GetFormat() const + { return file_format_; } + + void SetModelFileName(const std::string& filename) + { model_file_name_ = filename; } + + std::string GetModelFileName() const + { return model_file_name_; } + + void SetZoneNumber(int zone_number) + { zone_number_ = zone_number; } + + int GetZoneNumber() const + { return zone_number_; } + + int GetFaciesCode(int body_index) const; + int GetFaciesFromCell(size_t cell_index) const; + int GetFaciesFromCell(size_t i, size_t j, size_t k) const + { return GetFaciesFromCell(GetIndex(i, j, k)); } + const std::string& GetFaciesName(int facies_code) const; + void SetBodyFacies(const std::vector<int>& body_facies); + void SetFaciesNames(const std::vector<std::string>& facies_names); + + void WriteToFile(const std::string& filename, Endianess file_format = END_BIG_ENDIAN) const; + void ReadFromFile(const std::string& filename, bool commonPath = true, Endianess file_format = END_BIG_ENDIAN); + + /// \brief Check that all the facies value for each body, and the + /// body values inside the grid are inside the given range. + void CheckConsistency() const; + + double GetDX() const {return GetLX()/GetNI();} + double GetDY() const {return GetLY()/GetNJ();} + size_t FindIndex(double x, double y, double z) const; + void FindIndex( double x, double y, double z, size_t& i_out, size_t& j_out, size_t& k_out) const; + void FindCenterOfCell(size_t i, size_t j, size_t k, + double& x, double& y, double& z) const; + + private: + double RecalculateLZ(); + + FileFormat file_format_; + int missing_code_; + int zone_number_; + std::string model_file_name_; + std::vector<std::string> facies_names_; + std::vector<int> body_facies_; + }; +} + +#endif // NRLIB_STORMFACIESGRID_HPP diff --git a/ThirdParty/NRLib/nrlib/surface/module.mk b/ThirdParty/NRLib/nrlib/surface/module.mk new file mode 100644 index 0000000000..faaa86ef5c --- /dev/null +++ b/ThirdParty/NRLib/nrlib/surface/module.mk @@ -0,0 +1 @@ +SRC += $(NRLIB_BASE_DIR)surface/surfaceio.cpp diff --git a/ThirdParty/NRLib/nrlib/surface/regularsurface.hpp b/ThirdParty/NRLib/nrlib/surface/regularsurface.hpp new file mode 100644 index 0000000000..524d800fc3 --- /dev/null +++ b/ThirdParty/NRLib/nrlib/surface/regularsurface.hpp @@ -0,0 +1,883 @@ +// $Id: regularsurface.hpp 1196 2013-09-09 12:01:04Z perroe $ + +// Copyright (c) 2011, Norwegian Computing Center +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// • Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// • Redistributions in binary form must reproduce the above copyright notice, this list of +// conditions and the following disclaimer in the documentation and/or other materials +// provided with the distribution. +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT +// SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#ifndef NRLIB_REGULARSURFACE_HPP +#define NRLIB_REGULARSURFACE_HPP + +#include <algorithm> +#include <cmath> +#include <iostream> + +#include "surface.hpp" +#include "surfaceio.hpp" +#include "../grid/grid2d.hpp" +#include "../iotools/stringtools.hpp" + +namespace NRLib { + +/// Surface represented as a regular grid, where each of the grid cells +/// are modelled as bilinear surfaces. + +template <class A> +class RegularSurface : public Grid2D<A>, public Surface<A> { +public: + RegularSurface(); + + RegularSurface(double x0, double y0, double lx, double ly, size_t nx, size_t ny, + const A& value = A()); + + RegularSurface(double x0, double y0, double lx, double ly, Grid2D<A> grid); + + /// \brief Read surface file on given format. + /// \param filename File name. + /// \param format File format. If SURF_UNKNOWN we try to determine the format. + /// \throws IOError If we failed to open the file + /// \throws FileFormatError If we can not determine the file format, or the contents + /// of the file does not match the file format. + RegularSurface(const std::string & filename, + SurfaceFileFormat format = SURF_UNKNOWN); + + Surface<A>* Clone() const + { return new RegularSurface<A>(*this); } + + /// Return z. Returns missing if we are outside the grid. + /// Returns also values when not all grid cell corners are present, + /// e.g. when (x,y) is just outside the grid. + A GetZ(double x, double y) const; + + /// Return z. Returns missing if not all grid cell corners are present, + /// e.g. when (x,y) is just outside the grid. + A GetZInside(double x, double y) const; + + /// Checks if point is inside definition area for surface. + bool IsInsideSurface(double x, double y) const; + + bool EnclosesRectangle(double x_min, double x_max, + double y_min, double y_max) const; + + /// Sets all values on the surface to a constant value. + void Assign(A c) { + typename Grid2D<A>::iterator i; + for (i=this->begin();i<this->end();i++) + *i = c; + } + + void Add(A c) { + typename Grid2D<A>::iterator i; + for (i=this->begin();i<this->end();i++) + if (*i != missing_val_) + *i += c; + } + + void Subtract(A c) { + typename Grid2D<A>::iterator i; + for (i=this->begin();i<this->end();i++) + if (*i != missing_val_) + *i -= c; + } + + void Multiply(A c) { + typename Grid2D<A>::iterator i; + for (i=this->begin();i<this->end();i++) + if (*i != missing_val_) + *i *= c; + } + + ///The following routines are for binary operations with non-conform grids. + ///Missing areas will shrink. + ///Also works for identical definitions without missing, but is inefficient. + bool AddNonConform(const Surface<A> * s2); + bool SubtractNonConform(const Surface<A> * s2); + bool MultiplyNonConform(const Surface<A> * s2); + bool DivideNonConform(const Surface<A> *s2); + + A Min() const; + A MinNode(size_t &i, size_t &j) const; + A Max() const; + A MaxNode(size_t &i, size_t &j) const; + A Avg() const; + // n_nodes is number of nodes with non-missing values. + A Avg(int& n_nodes) const; + + /// Returns vector with the four corners around the point (x,y). + /// Fails if failOutside is false and either ni or nj is greater than 2^31. + /// \param[out] corners The corners of the cell containing (x,y) or missing_val_ if + /// the given corner is outside the grid, or does not have a valid + /// value. + inline void GetCorners(double x, + double y, + A corners[4]) const; + + /// Returns the arithmetic average of the up to 8 (non-missing)-values from neighbouring grid cells. + /// If no neighborud cells have non-missing values, missing is returned. + bool CreateNeighbourAvg(size_t i, size_t j); + + /// Gets the index to left of x. + /// The found index corresponds to the cell index. + inline size_t FindI(double x) const; + + /// Gets the index to left of x. + /// The found index corresponds to the cell index. + inline size_t FindJ(double y) const; + + /// Gets the index for the nearest point up, and to the left of + /// (x,y), the corner point with the lowest i and j values. + /// The found index corresponds to the cell index. + inline void FindIndex(double x, double y, size_t& i, size_t& j) const; + + // Find continuous index + void FindContIndex(double x, double y, double& i, double& j) const; + + /// Gets the index for the nearest point up, and to the left of + /// (x,y), the corner point with the lowest i and j values. + /// May give values outside the grid. + /// Fails if either ni or nj is greater than 2^31. + /// The found index corresponds to the cell index. + inline void FindGeneralIndex(double x, double y, int& i, int& j) const; + + /// Find nearest node. + /// Similar to FindIndex, but finds index of nearest node instead of cell index. + inline void FindNearestNodeIndex(double x, double y, size_t& i, size_t& j) const; + + double GetX(size_t i) const + { return x_min_ + i*dx_; } + + double GetY(size_t j) const + { return y_min_ + j*dy_; } + + void GetXY(size_t i, size_t j, double & x, double & y) const { + x = x_min_ + i*dx_; + y = y_min_ + j*dy_; + } + + void GetXY(size_t index, double & x, double & y) const { + size_t j = index / this->GetNI(); + size_t i = index - j*this->GetNI(); + GetXY(i, j, x, y); + } + + void GetNode(size_t index, double& x, double& y, double& z) const { + size_t i, j; + this->GetIJ(index, i, j); + GetNode(i, j, x, y, z); + } + + void GetNode(size_t i, size_t j, double& x, double& y, double& z) const { + GetXY(i, j, x, y); + z = (*this)(i, j); + } + + double GetXMin() const { return x_min_; } + double GetYMin() const { return y_min_; } + double GetXMax() const { return x_min_ + lx_; } + double GetYMax() const { return y_min_ + ly_; } + double GetDX() const { return dx_; } + double GetDY() const { return dy_; } + double GetLengthX() const { return lx_; } + double GetLengthY() const { return ly_; } + + void SetDimensions(double x_min, double y_min, + double lx, double ly); + + /// Resize grid. Overrides Grid2D's resize. + void Resize(size_t ni, size_t nj, const A& val = A()); + + /// Check if grid value is missing + bool IsMissing(A val) const { + return val == missing_val_; + } + + // Change names: + // IsMissing(A) ==> EqualsMissingValue(A) ?? + // IsMissingAt(i,j) ==> GetMissingAt(i,j) + // SetMissing(i,j) ==> SetMissingAt(i,j) + + /// Check if grid value is missing + bool IsMissingAt(size_t i, size_t j) const { + return (*this)(i, j) == missing_val_; + } + + /// Set missing + void SetMissing(size_t i, size_t j) { + (*this)(i, j) = missing_val_; + } + + A GetMissingValue() const { return missing_val_ ;} + void SetMissingValue(A missing_val) { missing_val_ = missing_val; } + + const std::string& GetName() const { return name_; } + void SetName(const std::string& name) { name_ = name; } + + /// \brief Read surface file on given format. + /// \param filename File name. + /// \param format File format. If SURF_UNKNOWN we try to determine the format. + /// \throws IOError If we failed to open the file + /// \throws FileFormatError If we can not determine the file format, or the contents + /// of the file does not match the file format. + void ReadFromFile(const std::string& filename, + SurfaceFileFormat format = SURF_UNKNOWN); + + void WriteToFile(const std::string& filename, + SurfaceFileFormat format = SURF_STORM_BINARY) const; + + void Swap(RegularSurface<A>& other); + +private: + double CellRelX(double x) const; + double CellRelY(double y) const; + + double x_min_; + double y_min_; + double lx_; + double ly_; + double dx_; + double dy_; + // double rotation_; + + /// Fault name. Usually obtained from filename. + std::string name_; + + /// Missing value + A missing_val_; + + inline static A GetBilinearZ(A corners[4], double u, double v); + /// Bilinear interpolation with missing corner. + inline A GetBilinearZMissingCorners(A corners[4], double u, double v) const; +}; + +// ==================== TEMPLATE IMPLEMENTATIONS ==================== + +template <class A> +RegularSurface<A>::RegularSurface() + : Grid2D<A>(0, 0), + x_min_(0), + y_min_(0), + lx_(0), + ly_(0), + dx_(0), + dy_(0), + missing_val_(static_cast<A>(-999.0)) +{} + + +template <class A> +RegularSurface<A>::RegularSurface(double x_min, double y_min, + double lx, double ly, + size_t nx, size_t ny, + const A& value) + : Grid2D<A>(nx, ny, value), + x_min_(x_min), + y_min_(y_min), + lx_(lx), + ly_(ly), + missing_val_(static_cast<A>(-999.0)) +{ + dx_ = (nx > 1) ? lx / (nx-1) : 1.0; + dy_ = (ny > 1) ? ly / (ny-1) : 1.0; +} + + +template <class A> +RegularSurface<A>::RegularSurface(double x_min, double y_min, + double lx, double ly, + Grid2D<A> grid) + : Grid2D<A>(grid), + x_min_(x_min), + y_min_(y_min), + lx_(lx), + ly_(ly), + missing_val_(static_cast<A>(-999.0)) +{ + size_t ni = grid.GetNI(); + size_t nj = grid.GetNJ(); + dx_ = (ni > 1) ? lx / (ni-1) : 1.0; + dy_ = (nj > 1) ? ly / (nj-1) : 1.0; +} + + +template <class A> +RegularSurface<A>::RegularSurface(const std::string& filename, + SurfaceFileFormat format) + : lx_(0.0), + ly_(0.0), + missing_val_(static_cast<A>(-999.0)) +{ + ReadFromFile(filename, format); +} + + +/// \todo Move to a more suitable location. +template <class A> +A RegularSurface<A>::GetBilinearZ(A corners[4], double u, double v) +{ + A a = corners[0]; + A b = corners[1] - a; + A c = corners[2] - a; + A d = corners[3] - a - b - c; + + return static_cast<A>(a + b*u + c*v + d*u*v); +} + + +template <class A> +A RegularSurface<A>::GetBilinearZMissingCorners(A corners[4], double u, double v) const +{ + double weights[4]; + + weights[0] = (1.0-u) * (1.0-v); + weights[1] = u * (1.0 - v); + weights[2] = (1.0-u) * v; + weights[3] = u * v; + + double sum = 0.0; + double sum_weights = 0.0; + + for (size_t i = 0; i < 4; ++i) { + if (!IsMissing(corners[i])) { + sum += weights[i] * corners[i]; + sum_weights += weights[i]; + } + } + + if (sum_weights == 0.0) { + return GetMissingValue(); + } + return static_cast<A>(sum / sum_weights); +} + + +template <class A> +A RegularSurface<A>::GetZ(double x, double y) const +{ + A corner[4]; + GetCorners(x, y, corner); + + int n_missing = 0; + + for (int pix = 0; pix < 4; pix++) + { + if (IsMissing(corner[pix])) + n_missing++; + } + + if (n_missing == 4) { + return(missing_val_); + } + else { + double x1 = CellRelX(x); + double y1 = CellRelY(y); + + if (n_missing == 0) { + return GetBilinearZ(corner, x1, y1); + } + else { + return GetBilinearZMissingCorners(corner, x1, y1); + } + } +} + + +template <class A> +A RegularSurface<A>::GetZInside(double x, double y) const +{ + A corner[4]; + GetCorners(x, y, corner); + + bool missing = false; + + int pix = 0; + while (pix < 4 && !missing) { + if (IsMissing(corner[pix])) + missing = true; + pix++; + } + + if (missing) + return(missing_val_); + else { + double x1 = CellRelX(x); + double y1 = CellRelY(y); + return GetBilinearZ(corner, x1, y1); + } +} + + +template <class A> +bool RegularSurface<A>::IsInsideSurface(double x, double y) const +{ + if (x < GetXMin() || x > GetXMax() || y < GetYMin() || y > GetYMax()) + return false; + return true; +} + + +template <class A> +bool RegularSurface<A>::AddNonConform(const Surface<A> * s2) +{ + for (size_t i = 0; i < this->GetN(); i++) { + if ((*this)(i) != missing_val_) { + double x, y, value; + GetXY(i, x, y); + value = s2->GetZ(x, y); + if (s2->IsMissing(value) == false) + (*this)(i) += value; + else + (*this)(i) = missing_val_; + } + } + return(true); +} + + +template <class A> +bool RegularSurface<A>::SubtractNonConform(const Surface<A> * s2) +{ + for (size_t i = 0; i < this->GetN(); i++) { + if ((*this)(i) != missing_val_) { + double x, y, value; + GetXY(i, x, y); + value = s2->GetZ(x, y); + if (s2->IsMissing(value) == false) + (*this)(i) -= value; + else + (*this)(i) = missing_val_; + } + } + return(true); +} + +template <class A> +bool RegularSurface<A>::MultiplyNonConform(const Surface<A> * s2) +{ + for (size_t i = 0; i < this->GetN(); i++) { + if ((*this)(i) != missing_val_) { + double x, y, value; + GetXY(i, x, y); + value = s2->GetZ(x, y); + if (s2->IsMissing(value) == false) + (*this)(i) *= value; + else + (*this)(i) = missing_val_; + } + } + return(true); +} + +template <class A> +bool RegularSurface<A>::DivideNonConform(const Surface<A> * s2) +{ + for (size_t i = 0; i < this->GetN(); i++) { + if ((*this)(i) != missing_val_) { + double x, y, value; + GetXY(i, x, y); + value = s2->GetZ(x, y); + if (s2->IsMissing(value) == false) + (*this)(i) /= value; + else + (*this)(i) = missing_val_; + } + } + return(true); +} + + +template <class A> +A RegularSurface<A>::Min() const +{ + A minVal = (*this)(0); + typename std::vector<A>::const_iterator i; + for (i = this->begin(); i < this->end(); i++) { + if ((IsMissing(minVal) || (*i) < minVal) && IsMissing(*i) == false) + minVal = *i; + } + return minVal; +} + +template <class A> +A RegularSurface<A>::MinNode(size_t &i, size_t &j) const +{ + A minVal = (*this)(0); + typename std::vector<A>::const_iterator it; + size_t min_index = 0; + for (it = this->begin(); it < this->end(); it++) { + if ((IsMissing(minVal) || (*it) < minVal) && IsMissing(*it) == false) { + minVal = *it; + min_index = static_cast<size_t> (it - this->begin()); + } + } + this->GetIJ(min_index, i, j); + return minVal; +} + +template <class A> +A RegularSurface<A>::Max() const +{ + A maxVal = (*this)(0); + typename std::vector<A>::const_iterator i; + for (i = this->begin(); i < this->end(); i++) { + if ((IsMissing(maxVal) || (*i) > maxVal) && IsMissing(*i) == false) + maxVal = *i; + } + return maxVal; +} + +template <class A> +A RegularSurface<A>::MaxNode(size_t &i, size_t &j) const +{ + A maxVal = (*this)(0); + typename std::vector<A>::const_iterator it; + size_t max_index = 0; + for (it = this->begin(); it < this->end(); it++) { + if ((IsMissing(maxVal) || (*it) > maxVal) && IsMissing(*it) == false) { + maxVal = *it; + max_index = static_cast<size_t> (it - this->begin()); + } + } + this->GetIJ(max_index, i, j); + return maxVal; +} + +template <class A> +A RegularSurface<A>::Avg() const +{ + int n; + return Avg(n); +} + + +template <class A> +A RegularSurface<A>::Avg(int& n_nodes) const +{ + A sum = static_cast<A>(0); + int count = 0; + typename std::vector<A>::const_iterator i; + for (i = this->begin(); i < this->end(); i++) { + if (!IsMissing(*i)) { + sum += *i; + count++; + } + } + double avg; + if (count > 0) + avg = sum / count; + else + avg = missing_val_; + + n_nodes = count; + return avg; +} + + +template <class A> +bool RegularSurface<A>::EnclosesRectangle(double x_min, double x_max, + double y_min, double y_max) const +{ + if (x_min < GetXMin() || x_max > GetXMax() || + y_min < GetYMin() || y_max > GetYMax()) { + return false; + } + + return true; +} + + +template <class A> +size_t RegularSurface<A>::FindI(double x) const +{ + assert (x >= GetXMin() && x <= GetXMax()); + return static_cast<size_t>( (x-GetXMin()) / GetDX() ); +} + + +template <class A> +size_t RegularSurface<A>::FindJ(double y) const +{ + assert (y >= GetYMin() && y <= GetYMax()); + return static_cast<size_t>( (y-GetYMin()) / GetDY() ); +} + + +template <class A> +void RegularSurface<A>::FindIndex(double x, double y, size_t& i, size_t& j) const +{ + assert(x >= GetXMin() && x <= GetXMax() && + y >= GetYMin() && y <= GetYMax()); + + i = static_cast<size_t>( (x-GetXMin()) / GetDX() ); + j = static_cast<size_t>( (y-GetYMin()) / GetDY() ); +} + + +template <class A> +void RegularSurface<A>::FindContIndex(double x, double y, double& i, double& j) const +{ + assert(x >= GetXMin() && x <= GetXMax() && + y >= GetYMin() && y <= GetYMax()); + + i = (x-GetXMin()) / GetDX() ; + j = (y-GetYMin()) / GetDY() ; +} + + +template <class A> +void RegularSurface<A>::FindGeneralIndex(double x, double y, int& i, int& j) const +{ + i = static_cast<int>(std::floor( (x-GetXMin()) / GetDX() )); + j = static_cast<int>(std::floor( (y-GetYMin()) / GetDY() )); +} + + +template <class A> +void RegularSurface<A>::FindNearestNodeIndex(double x, double y, size_t& i, size_t& j) const +{ + int tmp_i, tmp_j; + int ni = static_cast<int>(this->GetNI()); + int nj = static_cast<int>(this->GetNJ()); + FindGeneralIndex(x + 0.5*dx_, y + 0.5*dy_, tmp_i, tmp_j); + if (tmp_i < 0) + tmp_i = 0; + else if (tmp_i >= ni) + tmp_i = ni - 1; + + if (tmp_j < 0) + tmp_j = 0; + else if (tmp_j >= nj) + tmp_j = nj - 1; + + i = static_cast<size_t>(tmp_i); + j = static_cast<size_t>(tmp_j); +} + + +template <class A> +void RegularSurface<A>::GetCorners(double x, + double y, + A corners[4]) const +{ + int i, j; + int ni = static_cast<int>(this->GetNI()); + int nj = static_cast<int>(this->GetNJ()); + FindGeneralIndex(x, y, i , j); + + if (i+1 >= 0 && i < ni && j+1 >= 0 && j < nj) { + if (i >= 0 && j >= 0) + corners[0] = (*this)(i, j); + else + corners[0] = missing_val_; + if (i+1 < ni && j >= 0) + corners[1] = (*this)(i+1, j); + else + corners[1] = missing_val_; + if (i >= 0 && j+1 < nj) + corners[2] = (*this)(i, j+1); + else + corners[2] = missing_val_; + if (i+1 < ni && j+1 < nj) + corners[3] = (*this)(i+1, j+1); + else + corners[3] = missing_val_; + } + else { + corners[0] = missing_val_; + corners[1] = missing_val_; + corners[2] = missing_val_; + corners[3] = missing_val_; + } +} + + +template <class A> +bool RegularSurface<A>::CreateNeighbourAvg(size_t i, size_t j) +{ + double sum = 0.0; + int n = 0; + if (i > 0) { + if (j > 0) { + if (!IsMissingAt(i-1,j-1)) { + sum += (*this)(i-1,j-1); + n++; + } + } + if (j < this->GetNJ() - 1) { + if (!IsMissingAt(i-1,j+1)) { + sum += (*this)(i-1,j+1); + n++; + } + } + if (!IsMissingAt(i-1,j)) { + sum += (*this)(i-1,j); + n++; + } + } + if (i < this->GetNI() - 1) { + if (j > 0) { + if (!IsMissingAt(i+1,j-1)) { + sum += (*this)(i+1,j-1); + n++; + } + } + if (j < this->GetNJ() - 1) { + if (!IsMissingAt(i+1,j+1)) { + sum += (*this)(i+1,j+1); + n++; + } + } + if (!IsMissingAt(i+1,j)) { + sum += (*this)(i+1,j); + n++; + } + } + + if (j > 0) { + if (!IsMissingAt(i,j-1)) { + sum += (*this)(i,j-1); + n++; + } + } + if (j < this->GetNJ() - 1) { + if (!IsMissingAt(i,j+1)) { + sum += (*this)(i,j+1); + n++; + } + } + + double avg = missing_val_; + bool non_missing = false; + if (n > 0) { + avg = sum / n; + non_missing = true; + } + + (*this)(i,j) = avg; + return (non_missing); +} + + +template <class A> +void RegularSurface<A>::SetDimensions(double x_min, double y_min, + double lx, double ly) +{ + x_min_ = x_min; + y_min_ = y_min; + lx_ = lx; + ly_ = ly; + size_t ni = Grid2D<A>::GetNI(); + size_t nj = Grid2D<A>::GetNJ(); + dx_ = (ni > 1) ? lx / (ni - 1) : 1.0; + dy_ = (nj > 1) ? ly / (nj - 1) : 1.0; +} + + +template <class A> +void RegularSurface<A>::Resize(size_t nx, size_t ny, const A& value) +{ + Grid2D<A>::Resize(nx, ny, value); + dx_ = (nx > 1) ? lx_ / (nx-1) : 1.0; + dy_ = (ny > 1) ? ly_ / (ny-1) : 1.0; +} + + +template <class A> +void RegularSurface<A>::ReadFromFile(const std::string& filename, + SurfaceFileFormat format) +{ + if (format == SURF_UNKNOWN) { + format = FindSurfaceFileType(filename); + if (format == SURF_UNKNOWN) { + throw FileFormatError("Failed to determine file format for surface file: " + filename); + } + } + + double angle = 0.0; + + switch (format) { + case SURF_IRAP_CLASSIC_ASCII: + ReadIrapClassicAsciiSurf(filename, *this, angle); + break; + case SURF_STORM_BINARY: + ReadStormBinarySurf(filename, *this); + break; + case SURF_SGRI: + ReadSgriSurf(filename, *this, angle); + break; + default: + throw FileFormatError("Reading of file " + filename + " on format " + ToString(format) + + " as non-rotated grid is currently not supported."); + } + + if (angle != 0.0) { + throw FileFormatError("Error reading regular surface: " + filename + + ". Rotated grids are not supported."); + } +} + + +template <class A> +void RegularSurface<A>::WriteToFile(const std::string& filename, + SurfaceFileFormat format) const +{ + switch (format) { + case SURF_IRAP_CLASSIC_ASCII: + WriteIrapClassicAsciiSurf(*this, 0.0, filename); + break; + case SURF_STORM_BINARY: + WriteStormBinarySurf(*this, filename); + break; + default: + throw FileFormatError("Writing of surface to file " + filename + " on format " + + ToString(format) + " is currently not supported."); + } +} + + +template <class A> +double RegularSurface<A>::CellRelX(double x) const +{ + double i; + return std::modf((x-GetXMin())/GetDX(), &i); +} + + +template <class A> +double RegularSurface<A>::CellRelY(double y) const +{ + double j; + return std::modf((y-GetYMin())/GetDY(), &j); +} + + +template <class A> +void RegularSurface<A>::Swap(NRLib::RegularSurface<A> &other) +{ + Grid2D<A>::Swap(other); + std::swap(x_min_, other.x_min_); + std::swap(y_min_, other.y_min_); + std::swap(lx_, other.lx_); + std::swap(ly_, other.ly_); + std::swap(dx_, other.dx_); + std::swap(dy_, other.dy_); + std::swap(name_, other.name_); + std::swap(missing_val_, other.missing_val_); +} + + +} // namespace NRLib + +#endif // NRLIB_REGULARSURFACE_HPP diff --git a/ThirdParty/NRLib/nrlib/surface/regularsurfacerotated.hpp b/ThirdParty/NRLib/nrlib/surface/regularsurfacerotated.hpp new file mode 100644 index 0000000000..eb601e5378 --- /dev/null +++ b/ThirdParty/NRLib/nrlib/surface/regularsurfacerotated.hpp @@ -0,0 +1,595 @@ +// $Id: regularsurfacerotated.hpp 882 2011-09-23 13:10:16Z perroe $ + +// Copyright (c) 2011, Norwegian Computing Center +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// • Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// • Redistributions in binary form must reproduce the above copyright notice, this list of +// conditions and the following disclaimer in the documentation and/or other materials +// provided with the distribution. +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT +// SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef NRLIB_REGULARSURFACEROTATED_HPP +#define NRLIB_REGULARSURFACEROTATED_HPP + +#include "surface.hpp" +#include "regularsurface.hpp" +#include "../grid/grid2d.hpp" +#include "../iotools/stringtools.hpp" + +#include <cmath> +#include <algorithm> + +namespace NRLib { +template <class A> + +class RegularSurfaceRotated : public Surface<A> { +public: + RegularSurfaceRotated(); + + RegularSurfaceRotated(double x0, + double y0, + double lx, + double ly, + size_t nx, + size_t ny, + double angle, + const A& value = A()); + + RegularSurfaceRotated(const RegularSurface<A>& surface, double angle); + + RegularSurfaceRotated(double x0, double y0, double lx, double ly, Grid2D<A> grid, double angle); + + /// \brief Read surface file on given format. + /// \param filename File name. + /// \param format File format. If SURF_UNKNOWN we try to determine the format. + /// \throws IOError If we failed to open the file + /// \throws FileFormatError If we can not determine the file format, or the contents + /// of the file does not match the file format. + + RegularSurfaceRotated(std::string filename, + SurfaceFileFormat format = SURF_UNKNOWN, + double angle = 0.0, + double x_ref = 0.0, + double y_ref = 0.0, + double lx = 0.0, + double ly = 0.0, + int * ilxl_area = NULL, + double il0_ref = 0.0, + double xl0_ref = 0.0); + + Surface<A>* Clone() const + { return new RegularSurfaceRotated<A>(*this); } + + typedef typename std::vector<A>::iterator iterator; + iterator begin() { return surface_.begin(); } + iterator end() { return surface_.end(); } + + typedef typename std::vector<A>::const_iterator const_iterator; + const_iterator begin() const { return surface_.begin(); } + const_iterator end() const { return surface_.end(); } + + typedef typename std::vector<A>::reference reference; + inline reference operator()(size_t i, size_t j) { return surface_(i,j); } + inline reference operator()(size_t index) { return surface_(index); } + + typedef typename std::vector<A>::const_reference const_reference; + inline const_reference operator()(size_t i, size_t j) const { return surface_(i,j); } + inline const_reference operator()(size_t index) const { return surface_(index); } + + /// Return z. Returns missing if we are outside the grid. + /// Returns also values when not all grid cell corners are present, + /// e.g. when (x,y) is just outside the grid. + A GetZ(double x, double y) const; + + /// Return z. Returns missing if not all grid cell corners are present, + /// e.g. when (x,y) is just outside the grid. + A GetZInside(double x, double y) const; + + /// Checks if point is inside definition area for surface. + bool IsInsideSurface(double x, double y) const; + + bool EnclosesRectangle(double x_min, double x_max, + double y_min, double y_max) const; + +/// Sets all values on the surface to a constant value. + void Assign(A c) {surface_.Assign(c);} + + void Add(A c) { surface_.Add(c);} + + void Subtract(A c) {surface_.Subtract(c);} + + void Multiply(A c) {surface_.Multiply(c);} + + void GetXY(size_t i, size_t j, double & x, double & y) const; + + void GetXY(size_t index, double & x, double & y) const; + + double GetDX() const { return surface_.GetDX(); } + double GetDY() const { return surface_.GetDY(); } + double GetLengthX() const { return surface_.GetLengthX(); } + double GetLengthY() const { return surface_.GetLengthY(); } + + void SetDimensions(double x_min, double y_min, + double lx, double ly); + + /// Resize grid. Overrides Grid2D's resize. + void Resize(size_t ni, size_t nj, const A& val = A()); + + size_t GetNI() const { return surface_.GetNI(); } + size_t GetNJ() const { return surface_.GetNJ(); } + size_t GetN() const { return surface_.GetN(); } + + /// Check if grid value is missing + bool IsMissing(A val) const { return surface_.IsMissing(val); } + bool IsMissingAt(size_t i, size_t j) const { return surface_.IsMissingAt(i, j); } + void SetMissing(size_t i, size_t j) { surface_.SetMissing(i, j); } + + A Min() const { return surface_.Min(); } + A Max() const { return surface_.Max(); } + A Avg() const { return surface_.Avg(); } + A Avg(int& n_nodes) const { return surface_.Avg(n_nodes); } + + ///The following routines are for binary operations with non-conform grids. + ///Missing areas will shrink. + ///Also works for identical definitions without missing, but is inefficient. + bool AddNonConform(const Surface<A> * s2); + bool SubtractNonConform(const Surface<A> * s2); + bool MultiplyNonConform(const Surface<A> * s2); + bool DivideNonConform(const Surface<A> *s2); + + double GetXRef() const { return x_ref_; } + double GetYRef() const { return y_ref_; } + double GetXMin() const { return x_min_; } + double GetYMin() const { return y_min_; } + double GetXMax() const { return x_max_; } + double GetYMax() const { return y_max_; } + + RegularSurface<A> ResampleSurface() const ; + + double GetAngle() const { return angle_ ;} + void SetAngle(double angle) { angle_ = angle ;} + + A GetMissingValue() const { return surface_.GetMissingValue() ;} + void SetMissingValue(A missing_val) { surface_.SetMissingValue(missing_val); } + +// We do not want to use the following methods if possible +// RegularSurface<A> GetSurface() const {return surface_;} +// Grid2D<A> GetSurfaceGrid2D() const { return surface_;} + + const std::string& GetName() const { return surface_.GetName(); } + void SetName(const std::string& name) { surface_.SetName(name); } + + /// \brief Read surface file on given format. + /// \param filename File name. + /// \param format File format. If SURF_UNKNOWN we try to determine the format. + /// \throws IOError If we failed to open the file + /// \throws FileFormatError If we can not determine the file format, or the contents + /// of the file does not match the file format. + void ReadFromFile(std::string filename, + SurfaceFileFormat format = SURF_UNKNOWN, + double angle = 0.0, + double x_ref = 0.0, + double y_ref = 0.0, + double lx = 0.0, + double ly = 0.0, + int * ilxl_area = NULL, + double il0_ref = 0.0, + double xl0_ref = 0.0); + + /// \brief Write surface to file on given format. + /// If the file format does not support rotation, the resampled surface is written to file. + /// \throws IOError If we failed to open the file + void WriteToFile(const std::string& filename, + SurfaceFileFormat format = SURF_STORM_BINARY) const; + +private: + void GlobalToLocalCoord(double global_x, + double global_y, + double& local_x, + double& local_y) const; + void LocalToGlobalCoord(double local_x, + double local_y, + double& global_x, + double& global_y) const; + void CalculateMinMaxXY(); + RegularSurface<A> surface_; + + double angle_; + double x_ref_; + double y_ref_; + double x_min_; + double y_min_; + double x_max_; + double y_max_; + +}; + +// ==================== TEMPLATE IMPLEMENTATIONS ==================== + +template <class A> +RegularSurfaceRotated<A>::RegularSurfaceRotated() +:angle_(0), + x_ref_(0.0), + y_ref_(0.0) +{ + surface_ = RegularSurface<A>(); + CalculateMinMaxXY(); +} + + +template <class A> +RegularSurfaceRotated<A>::RegularSurfaceRotated(double x_min, double y_min, + double lx, double ly, + size_t nx, size_t ny, double angle, + const A& value) + : angle_(angle), + x_ref_(x_min), + y_ref_(y_min) +{ + surface_ = RegularSurface<A>(x_min, y_min, lx, ly, nx, ny, value); + CalculateMinMaxXY(); +} + +template <class A> +RegularSurfaceRotated<A>::RegularSurfaceRotated(const RegularSurface<A>& surface, double angle) + : angle_(angle) +{ + surface_ = surface; + x_ref_ = surface.GetXMin(); + y_ref_ = surface.GetYMin(); + CalculateMinMaxXY(); +} + +template <class A> +RegularSurfaceRotated<A>::RegularSurfaceRotated(double x_min, double y_min, + double lx, double ly, + Grid2D<A> grid, double angle) + : angle_(angle), + x_ref_(x_min), + y_ref_(y_min) +{ + surface_ = RegularSurface<A>(x_min, y_min, lx, ly, grid); + CalculateMinMaxXY(); +} + + +template <class A> +RegularSurfaceRotated<A>::RegularSurfaceRotated(std::string filename, + SurfaceFileFormat format, + double angle, + double x_ref, + double y_ref, + double lx, + double ly, + int * ilxl_area, + double il0_ref, + double xl0_ref) + +{ + ReadFromFile(filename, + format, + angle, + x_ref, + y_ref, + lx, + ly, + ilxl_area, + il0_ref, + xl0_ref); +} + + +template <class A> +void +RegularSurfaceRotated<A>::GlobalToLocalCoord(double global_x, + double global_y, + double& local_x, + double& local_y) const +{ + double x_rel = global_x - x_ref_; + double y_rel = global_y - y_ref_; + + local_x = std::cos(angle_)*x_rel + std::sin(angle_)*y_rel ; + local_y = - std::sin(angle_)*x_rel + std::cos(angle_)*y_rel ; +} + +template <class A> +void RegularSurfaceRotated<A>::LocalToGlobalCoord(double local_x, + double local_y, + double& global_x, + double& global_y) const +{ + global_x = std::cos(angle_)*local_x - std::sin(angle_)*local_y + x_ref_; + global_y = std::sin(angle_)*local_x + std::cos(angle_)*local_y + y_ref_; +} + +template <class A> +A RegularSurfaceRotated<A>::GetZ(double x, double y) const +{ + double local_x, local_y; + GlobalToLocalCoord(x, y, local_x, local_y); + A z = surface_.GetZ(local_x+x_ref_, local_y+y_ref_); + return z; +} +template <class A> +A RegularSurfaceRotated<A>::GetZInside(double x, double y) const +{ + double local_x, local_y; + GlobalToLocalCoord(x, y, local_x, local_y); + A z = surface_.GetZInside(local_x+x_ref_, local_y+y_ref_); + return z; +} +template <class A> +bool RegularSurfaceRotated<A>::IsInsideSurface(double x, double y) const +{ + double local_x, local_y; + GlobalToLocalCoord(x, y, local_x, local_y); + bool z = surface_.IsInsideSurface(local_x+x_ref_, local_y+y_ref_); + return z; + +} + +template <class A> +bool RegularSurfaceRotated<A>::AddNonConform(const Surface<A> * s2) +{ + A missing_val = surface_.GetMissingValue(); + for (size_t i = 0; i < this->GetN(); i++) { + if ((*this)(i) != missing_val) { + double x, y, value; + GetXY(i, x, y); + value = s2->GetZ(x, y); + if (s2->IsMissing(value) == false) + (*this)(i) += value; + else + (*this)(i) = missing_val; + } + } + return(true); +} + + +template <class A> +bool RegularSurfaceRotated<A>::SubtractNonConform(const Surface<A> * s2) +{ + A missing_val = surface_.GetMissingValue(); + for (size_t i = 0; i < this->GetN(); i++) { + if ((*this)(i) != missing_val) { + double x, y, value; + GetXY(i, x, y); + value = s2->GetZ(x, y); + if (s2->IsMissing(value) == false) + (*this)(i) -= value; + else + (*this)(i) = missing_val; + } + } + return(true); +} + +template <class A> +bool RegularSurfaceRotated<A>::MultiplyNonConform(const Surface<A> * s2) +{ + A missing_val = surface_.GetMissingValue(); + for (size_t i = 0; i < this->GetN(); i++) { + if ((*this)(i) != missing_val) { + double x, y, value; + GetXY(i, x, y); + value = s2->GetZ(x, y); + if (s2->IsMissing(value) == false) + (*this)(i) *= value; + else + (*this)(i) = missing_val; + } + } + return(true); +} + +template <class A> +bool RegularSurfaceRotated<A>::DivideNonConform(const Surface<A> * s2) +{ + A missing_val = surface_.GetMissingValue(); + for (size_t i = 0; i < this->GetN(); i++) { + if ((*this)(i) != missing_val) { + double x, y, value; + GetXY(i, x, y); + value = s2->GetZ(x, y); + if (s2->IsMissing(value) == false) + (*this)(i) /= value; + else + (*this)(i) = missing_val; + } + } + return(true); +} + +template <class A> +bool RegularSurfaceRotated<A>::EnclosesRectangle(double x_min, double x_max, + double y_min, double y_max) const +{ + if (x_min < GetXMin() || x_max > GetXMax() || + y_min < GetYMin() || y_max > GetYMax()) { + return false; + } + + return true; + +} + +template <class A> +void RegularSurfaceRotated<A>::CalculateMinMaxXY() +{ + std::vector<double> x(4); + std::vector<double> y(4); + + LocalToGlobalCoord(0, 0, x[0], y[0]); + LocalToGlobalCoord(surface_.GetLengthX(), 0, x[1], y[1]); + LocalToGlobalCoord(0, surface_.GetLengthY(), x[2], y[2]); + LocalToGlobalCoord(surface_.GetLengthX(), surface_.GetLengthY(), x[3], y[3]); + + x_min_ = *(std::min_element(x.begin(), x.end())); + y_min_ = *(std::min_element(y.begin(), y.end())); + x_max_ = *(std::max_element(x.begin(), x.end())); + y_max_ = *(std::max_element(y.begin(), y.end())); + +} + +template <class A> +void RegularSurfaceRotated<A>::SetDimensions(double x_min, double y_min, + double lx, double ly) +{ + surface_.SetDimensions(x_min, y_min, lx, ly); + + x_ref_ = x_min; + y_ref_ = y_min; + CalculateMinMaxXY(); +} + +template <class A> +void RegularSurfaceRotated<A>::Resize(size_t nx, size_t ny, const A& value) +{ + surface_.Resize(nx, ny, value); +} + + +template <class A> +void RegularSurfaceRotated<A>::GetXY(size_t i, size_t j, double & x, double & y) const +{ + double x_tmp, y_tmp; + surface_.GetXY(i,j,x_tmp,y_tmp); + + double x_loc = x_tmp - x_ref_; + double y_loc = y_tmp - y_ref_; + + LocalToGlobalCoord(x_loc,y_loc,x,y); +} + +template <class A> +void RegularSurfaceRotated<A>::GetXY(size_t index, double & x, double & y) const +{ + double x_tmp, y_tmp; + surface_.GetXY(index,x_tmp,y_tmp); + + double x_loc = x_tmp - x_ref_; + double y_loc = y_tmp - y_ref_; + + LocalToGlobalCoord(x_loc,y_loc,x,y); +} + +template <class A> +RegularSurface<A> RegularSurfaceRotated<A>::ResampleSurface() const +{ + double dx = surface_.GetDX()*cos(angle_); + double dy = surface_.GetDY()*cos(angle_); + int nx = int((x_max_-x_min_)/dx) + 1; + int ny = int((y_max_-y_min_)/dy) +1; + RegularSurface<A> surf(x_min_, y_min_, x_max_-x_min_, y_max_-y_min_, nx, ny, 0.0); + surf.SetMissingValue(GetMissingValue()); + A value; + double x,y; + int i,j; + for(i=0;i<nx;i++) + for(j=0;j<ny;j++) + { + x = x_min_ + i*dx; + y = y_min_ + j*dy; + value = GetZ(x,y); + surf(i,j) = value; + } + + return surf; +} + + +template <class A> +void RegularSurfaceRotated<A>::ReadFromFile(std::string filename, + SurfaceFileFormat format, + double segy_angle, + double x_ref, + double y_ref, + double lx, + double ly, + int * ilxl_area, + double il0_ref, + double xl0_ref) +{ + if (format == SURF_UNKNOWN) { + format = FindSurfaceFileType(filename); + if (format == SURF_UNKNOWN) { + throw FileFormatError("Failed to determine file format for surface file: " + filename); + } + } + + switch (format) { + case SURF_IRAP_CLASSIC_ASCII: + ReadIrapClassicAsciiSurf(filename, surface_, angle_); + break; + case SURF_STORM_BINARY: + ReadStormBinarySurf(filename, surface_); + angle_ = 0.0; + break; + case SURF_SGRI: + ReadSgriSurf(filename, surface_, angle_); + break; + case SURF_MULT_ASCII: + ReadMulticolumnAsciiSurf(filename, + surface_, + x_ref, + y_ref, + lx, + ly, + ilxl_area, + il0_ref, + xl0_ref); + angle_ = segy_angle; + break; + default: + throw FileFormatError("Reading of file " + filename + " on format " + ToString(format) + + " as a rotated grid is currently not supported."); + } + + x_ref_ = surface_.GetXMin(); + y_ref_ = surface_.GetYMin(); + + CalculateMinMaxXY(); +} + + +template <class A> +void RegularSurfaceRotated<A>::WriteToFile(const std::string& filename, + SurfaceFileFormat format) const +{ + switch (format) { + case SURF_IRAP_CLASSIC_ASCII: + WriteIrapClassicAsciiSurf(surface_, angle_, filename); + break; + case SURF_STORM_BINARY: + { + if (angle_ != 0.0) { + RegularSurface<A> resampled_surf = ResampleSurface(); + WriteStormBinarySurf(resampled_surf, filename); + } + else { + WriteStormBinarySurf(surface_, filename); + } + } + break; + default: + throw FileFormatError("Writing of surface to file " + filename + " on format " + + ToString(format) + " is currently not supported."); + } +} + + +} +#endif diff --git a/ThirdParty/NRLib/nrlib/surface/surface.hpp b/ThirdParty/NRLib/nrlib/surface/surface.hpp new file mode 100644 index 0000000000..8c3391b3ef --- /dev/null +++ b/ThirdParty/NRLib/nrlib/surface/surface.hpp @@ -0,0 +1,136 @@ +// $Id: surface.hpp 882 2011-09-23 13:10:16Z perroe $ + +// Copyright (c) 2011, Norwegian Computing Center +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// • Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// • Redistributions in binary form must reproduce the above copyright notice, this list of +// conditions and the following disclaimer in the documentation and/or other materials +// provided with the distribution. +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT +// SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef NRLIB_SURFACE_HPP +#define NRLIB_SURFACE_HPP + +#include <limits> + +namespace NRLib { + template <class A> + class Surface { + public: + virtual ~Surface(); + + /// \brief Generate a copy of the underlying object. + virtual Surface * Clone() const = 0; + + virtual A GetZ(double x, double y) const = 0; + + virtual bool EnclosesRectangle(double x_min, double x_max, + double y_min, double y_max) const = 0; + + virtual bool IsMissing(A) const { return(false) ;} + + virtual bool IsInsideSurface(double /*x*/, double /*y*/) const = 0; + + virtual void Add(A c) = 0; + + virtual void Multiply(A c) = 0; + + virtual A Min() const = 0; + virtual A Max() const = 0; + + virtual double GetXMin() const = 0; + virtual double GetYMin() const = 0; + virtual double GetXMax() const = 0; + virtual double GetYMax() const = 0; + + }; + + template <class A> + class ConstantSurface : public Surface<A> { + public: + ConstantSurface(A z); + + Surface<A>* Clone() const + { return new ConstantSurface(*this); } + + A GetZ() const { + return z_; + } + + bool IsInsideSurface(double /*x*/, double /*y*/) const {return(true);} + A GetZ(double /*x*/, double /*y*/) const + { return z_; } + + bool EnclosesRectangle(double /*x_min*/, double /*x_max*/, + double /*y_min*/, double /*y_max*/) const + { return true; } + + void Add(A c) { + z_ += c; + } + + void Multiply(A c) { + z_ *= c; + } + + A Min() const {return(z_);} + A Max() const {return(z_);} + + double GetXMin() const + { + if ( std::numeric_limits<double>::has_infinity ) + return -std::numeric_limits<double>::infinity(); + else + return -std::numeric_limits<double>::max(); + } + + double GetYMin() const + { + if ( std::numeric_limits<double>::has_infinity ) + return -std::numeric_limits<double>::infinity(); + else + return -std::numeric_limits<double>::max(); + } + + double GetXMax() const + { + if ( std::numeric_limits<double>::has_infinity ) + return(std::numeric_limits<double>::infinity()); + else + return std::numeric_limits<double>::max(); + } + + double GetYMax() const + { + if ( std::numeric_limits<double>::has_infinity ) + return(std::numeric_limits<double>::infinity()); + else + return std::numeric_limits<double>::max(); + } + + private: + A z_; + }; + + template <class A> + Surface<A>::~Surface() + {} + + template <class A> + ConstantSurface<A>::ConstantSurface(A z) + : z_(z) + {} +} // namespace NRLib + +#endif // NRLIB_SURFACE_HPP diff --git a/ThirdParty/NRLib/nrlib/surface/surfaceio.cpp b/ThirdParty/NRLib/nrlib/surface/surfaceio.cpp new file mode 100644 index 0000000000..ab9c69acfc --- /dev/null +++ b/ThirdParty/NRLib/nrlib/surface/surfaceio.cpp @@ -0,0 +1,325 @@ +// $Id: surfaceio.cpp 882 2011-09-23 13:10:16Z perroe $ + +// Copyright (c) 2011, Norwegian Computing Center +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// • Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// • Redistributions in binary form must reproduce the above copyright notice, this list of +// conditions and the following disclaimer in the documentation and/or other materials +// provided with the distribution. +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT +// SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include <cmath> +#include <fstream> +#include <string> + +#include "surfaceio.hpp" + +#include "regularsurface.hpp" +#include "regularsurfacerotated.hpp" +#include "surface.hpp" +#include "../exception/exception.hpp" +#include "../iotools/fileio.hpp" +#include "../iotools/stringtools.hpp" + +namespace NRLib { + +//const double IRAP_MISSING = 9999900.0; +//const double STORM_MISSING = -999.0; + + +namespace NRLibPrivate { +/// \todo Move to a suitable place +bool Equal(double a, double b) +{ + if ( fabs(a-b) <= 0.0001 * a ) { + return true; + } + return false; +} +} // namespace NRLibPrivate + +SurfaceFileFormat FindSurfaceFileType(const std::string& filename) +{ + std::ifstream file; + OpenRead(file, filename, std::ios::in | std::ios::binary); + + std::string first_token; + if (!(file >> first_token)) { + // Empty file. + return SURF_UNKNOWN; + } + + if (first_token == "-996") + return SURF_IRAP_CLASSIC_ASCII; + else if (first_token == "STORMGRID_BINARY") + return SURF_STORM_BINARY; + else if (first_token == "NORSAR") { + std::string token; + file >> token; + file >> token; + file >> token; + file >> token; + if(token == "v1.0" ||token == "v2.0" ) + return SURF_SGRI; + } + else if (IsType<double>(first_token)) { + file.seekg(0, std::ios_base::beg); + std::string line; + std::getline(file, line); + std::vector<std::string> tokens = GetTokens(line); + if (tokens.size() == 3) { + // Check last line of file. + file.seekg(0, std::ios_base::end); + std::streampos file_len = file.tellg(); + std::streampos offset = std::min(static_cast<std::streampos>(50), file_len); + file.seekg(-offset, std::ios_base::end); + + tokens.clear(); + + while (std::getline(file, line)) { + if (GetTokens(line).size() > 0) { + tokens = GetTokens(line); + } + } + + if (tokens.size() == 3) { + try { + if (ParseType<double>(tokens[0]) == 999.0 && + ParseType<double>(tokens[1]) == 999.0 && + ParseType<double>(tokens[2]) == 999.0) { + return SURF_RMS_POINTS_ASCII; + } + } + catch (Exception& ) { + // Do nothing - failed to parse tokens as doubles. + } + } + } + return SURF_UNKNOWN; + } + + //Try multicolum ascii + int dummy; + bool is_multicolumn_ascii = FindMulticolumnAsciiLine(filename, dummy); + + if (is_multicolumn_ascii == true) + return SURF_MULT_ASCII; + + return SURF_UNKNOWN; +} + + +std::string GetSurfFormatString(NRLib::SurfaceFileFormat format) +{ + switch (format) { + case SURF_UNKNOWN: + return "Unknown surface format"; + case SURF_IRAP_CLASSIC_ASCII: + return "IRAP classic ASCII"; + case SURF_STORM_BINARY: + return "Storm binary"; + case SURF_SGRI: + return "NORSAR SGRI"; + case SURF_RMS_POINTS_ASCII: + return "RMS XYZ point set surface"; + case SURF_MULT_ASCII: + return "Multicolumn ASCII"; + default: + throw Exception("Missing format description for format: " + ToString(format)); + } +} + + +std::vector<RegularSurfaceRotated<float> > +ReadMultipleSgriSurf(const std::string& filename, const std::vector<std::string> & labels) +{ + std::ifstream header_file; + OpenRead(header_file, filename.c_str(), std::ios::in | std::ios::binary); + int i, dim; + std::string tmp_str; + try { + //Reading record 1: Version header + getline(header_file, tmp_str); + //Reading record 2: Grid dimension + header_file >> dim; + if(dim!=2) + throw Exception("Wrong dimension of Sgri file. We expect a surface, dimension should be 2.\n"); + + getline(header_file, tmp_str); + //Reading record 3 ... 3+dim: Axis labels + grid value label + std::vector<std::string> axis_labels(dim); + std::string err_txt; + for (i=0; i<dim; i++) { + getline(header_file, axis_labels[i]); + if(labels.size() > static_cast<size_t>(i)) { + NRLib::Uppercase(axis_labels[i]); + NRLib::Uppercase(labels[i]); + if (axis_labels[i].find(labels[i]) == std::string::npos) + err_txt += "Wrong axis labels. Label for axis "+NRLib::ToString(i)+" should be '"+labels[i]+"'.\n"; + } + } + getline(header_file, tmp_str); + + //Reading record 4+dim: Number of grids + int n_grid; + header_file >> n_grid; + if (n_grid < 1) { + throw Exception("Error: Number of grids read from sgri file must be > 0"); + } + getline(header_file, tmp_str); + + //Reading record 5+dim ... 5+dim+ngrid-1: Grid labels + for (i=0; i<n_grid; i++) + getline(header_file, tmp_str); + + std::vector<float> d_values1(dim); + std::vector<float> d_values2(dim); + std::vector<int> i_values(dim); + //Reading record 5+dim+ngrid: Scaling factor of grid values + for (i=0; i<dim; i++) + header_file >> d_values1[i]; + getline(header_file,tmp_str); + //Reading record 6+dim+ngrid: Number of samples in each dir. + for (i=0; i<dim; i++) + header_file >> i_values[i]; + getline(header_file,tmp_str); + //Reading record 7+dim+ngrid: Grid sampling in each dir. + for (i=0; i<dim; i++) + header_file >> d_values2[i]; + + getline(header_file,tmp_str); + //Reading record 8+dim+ngrid: First point coord. + std::vector<float> min_values(dim); + for (i=0; i<dim; i++) + header_file >> min_values[i]; + + int nx=1; + int ny=1; + double dx, dy; + nx = i_values[0]; + dx = d_values2[0]; + ny = i_values[1]; + dy = d_values2[1]; + + if (nx < 1) + throw Exception("Error: Number of samples on first axis must be >= 1.\n"); + if (ny < 1) + throw Exception("Error: Number of samples on second axis must be >= 1.\n"); + + if (dx <= 0.0) + throw Exception("Error: Grid sampling on first axis must be > 0.0.\n"); + if (dy <= 0.0) + throw Exception("Error: Grid sampling on second axis must be > 0.0.\n"); + + double lx = (nx-1)*dx; + double ly = (ny-1)*dy; + + double x_min = min_values[0]-0.5*dx; + double y_min = min_values[1]-0.5*dy; + + double angle; + header_file >> angle; + + getline(header_file, tmp_str); + //Reading record 10+dim+ngrid: Undef value + float missing_code; + header_file >> missing_code; + + getline(header_file, tmp_str); + //Reading record 11+dim+ngrid: Filename of binary file + std::string bin_file_name; + getline(header_file, tmp_str); + if (!tmp_str.empty()) { + std::locale loc; + int i = 0; + char c = tmp_str[i]; + while (!std::isspace(c,loc)) { + i++; + c = tmp_str[i]; + } + tmp_str.erase(tmp_str.begin()+i, tmp_str.end()); + } + if (tmp_str.empty()) + bin_file_name = NRLib::ReplaceExtension(filename, "Sgri"); + else { + std::string path = GetPath(filename); + bin_file_name = path + "/" + tmp_str; + } + //Reading record 12+dim+ngrid: Complex values + bool has_complex; + header_file >> has_complex; + if (has_complex != 0 ) { + throw Exception("Error: Can not read Sgri binary file. Complex values?"); + } + + std::vector<RegularSurfaceRotated<float> > surfaces(n_grid); + std::ifstream bin_file; + OpenRead(bin_file, bin_file_name.c_str(), std::ios::in | std::ios::binary); + for (i=0; i<n_grid; i++) { + surfaces[i] = RegularSurfaceRotated<float>(x_min,y_min,lx,ly,nx,ny,angle,0.0f); + surfaces[i].SetMissingValue(missing_code); + ReadBinaryFloatArray(bin_file, surfaces[i].begin(), surfaces[i].GetN()); + } + + return surfaces; + } + catch (Exception& e) { + throw FileFormatError("Error parsing \"" + filename + "\" as a " + "Sgri surface file " + e.what() + "\n"); + } +} + +bool FindMulticolumnAsciiLine(const std::string& filename, int & header_start_line) +{ + //Contains five columns: X, Y, IL, CL, Attribute + //File starts with several information lines + std::ifstream file; + NRLib::OpenRead(file, filename); + int line = 0; + + //Find first line with five numbers + bool found_mult_ascii_line = false; + while (found_mult_ascii_line == false) { + + //Read line + std::string line_string; + std::getline(file, line_string); + std::vector<std::string> tokens = NRLib::GetTokens(line_string); + + //Check if the line has five number elements + if (tokens.size() == 5) { + for (int i = 0; i < 5; i++) { + if (!NRLib::IsNumber(tokens[i])) { + found_mult_ascii_line = false; + break; + } + else + found_mult_ascii_line = true; + } + } + + line++; + } + file.close(); + + header_start_line = line -2; + + return found_mult_ascii_line; +} + + +//void WritePointAsciiSurf(const RegularSurface<double>& surf, +// const std::string& filename); + +} // namespace NRLib diff --git a/ThirdParty/NRLib/nrlib/surface/surfaceio.hpp b/ThirdParty/NRLib/nrlib/surface/surfaceio.hpp new file mode 100644 index 0000000000..54bc929ad6 --- /dev/null +++ b/ThirdParty/NRLib/nrlib/surface/surfaceio.hpp @@ -0,0 +1,727 @@ +// $Id: surfaceio.hpp 1232 2014-01-13 12:22:40Z gudmundh $ + +// Copyright (c) 2011, Norwegian Computing Center +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// • Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// • Redistributions in binary form must reproduce the above copyright notice, this list of +// conditions and the following disclaimer in the documentation and/or other materials +// provided with the distribution. +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT +// SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef NRLIB_SURFACEIO_HPP +#define NRLIB_SURFACEIO_HPP + +#include <string> +#include <vector> +#include <locale> + +namespace NRLib { + template <class A> class RegularSurface; + template <class A> class RegularSurfaceRotated; + template <class A> class Grid2D; + + const double MULT_IRAP_MISSING = -999.25; + const double IRAP_MISSING = 9999900.0; + const double STORM_MISSING = -999.0; + + enum SurfaceFileFormat { + SURF_UNKNOWN, + SURF_IRAP_CLASSIC_ASCII, + SURF_STORM_BINARY, + SURF_SGRI, + SURF_RMS_POINTS_ASCII, + SURF_MULT_ASCII + // SURF_PLAIN_ASCII + // SURF_CPS3_ASCII + }; + + /// \brief Find type of file. + SurfaceFileFormat FindSurfaceFileType(const std::string& filename); + + /// \brief String describing file format + std::string GetSurfFormatString(SurfaceFileFormat format); + + template <class A> + void ReadStormBinarySurf(const std::string & filename, + RegularSurface<A> & surface); + + template <class A> + void ReadIrapClassicAsciiSurf(const std::string & filename, + RegularSurface<A> & surface, + double & angle); + + template <class A> + void ReadSgriSurf(const std::string & filename, + RegularSurface<A> & surface, + double & angle); + + // If labels is non-empty, the labels of the axes on the file are compared with these. Throws if mismatch. + std::vector<RegularSurfaceRotated<float> > ReadMultipleSgriSurf(const std::string& filename, + const std::vector<std::string> & labels); + + template <class A> + void ReadMulticolumnAsciiSurf(std::string filename, + RegularSurface<A> & surface, + double x_ref, + double y_ref, + double lx, + double ly, + int * ilxl_area, + double il0_ref, + double xl0_ref); + + template <class A> + void WriteIrapClassicAsciiSurf(const RegularSurface<A> & surf, + double angle, + const std::string & filename); + + template <class A> + void WriteStormBinarySurf(const RegularSurface<A> & surf, + const std::string & filename); + + bool FindMulticolumnAsciiLine(const std::string& filename, int & header_start_line); + + // void WritePointAsciiSurf(const RegularSurface<double>& surf, + // const std::string& filename); + + namespace NRLibPrivate { + /// \todo Move to a suitable place + bool Equal(double a, double b); + } + +} // namespace NRLib + + // ----------- TEMPLATE IMPLEMENTATIONS ---------------------- + +#include <fstream> +#include <string> + +#include "regularsurface.hpp" +#include "surface.hpp" +#include "../exception/exception.hpp" +#include "../math/constants.hpp" +#include "../iotools/fileio.hpp" +#include "../iotools/stringtools.hpp" + + +template<class A> +void NRLib::ReadStormBinarySurf(const std::string & filename, + RegularSurface<A> & surface) +{ + std::ifstream file; + OpenRead(file, filename.c_str(), std::ios::in | std::ios::binary); + + int line = 0; + + // Header + try { + std::string token = ReadNext<std::string>(file, line); + if (token != "STORMGRID_BINARY") { + throw FileFormatError("Error reading " + filename + ", file is not " + "in STORM binary format."); + } + + int ni = ReadNext<int>(file, line); + int nj = ReadNext<int>(file, line); + double dx = ReadNext<double>(file, line); + double dy = ReadNext<double>(file, line); + double x_min = ReadNext<double>(file, line); + double x_max = ReadNext<double>(file, line); + double y_min = ReadNext<double>(file, line); + double y_max = ReadNext<double>(file, line); + + double lx = x_max - x_min; + double ly = y_max - y_min; + + if (!NRLibPrivate::Equal(lx/(ni-1), dx)) { + throw FileFormatError("Inconsistent data in file. dx != lx/(nx-1)."); + } + if (!NRLibPrivate::Equal(ly/(nj-1), dy)) { + throw FileFormatError("Inconsistent data in file. dy != ly/(ny-1)."); + } + + surface.Resize(ni, nj); + surface.SetDimensions(x_min, y_min, lx, ly); + + DiscardRestOfLine(file, line, true); + ReadBinaryDoubleArray(file, surface.begin(), surface.GetN()); + + surface.SetMissingValue(static_cast<A>(STORM_MISSING)); + + if (!CheckEndOfFile(file)) { + throw FileFormatError("File too long."); + } + + surface.SetName(GetStem(filename)); + } + catch (EndOfFile& ) { + throw FileFormatError("Unexcpected end of file found while parsing " + " \"" + filename + "\""); + } + catch (Exception& e) { + throw FileFormatError("Error parsing \"" + filename + "\" as a " + "STORM surface file at line " + ToString(line) + ":" + e.what() + "\n"); + } +} + + +template <class A> +void NRLib::ReadIrapClassicAsciiSurf(const std::string & filename, + RegularSurface<A> & surface, + double & angle) +{ + std::ifstream file; + OpenRead(file, filename); + + int line = 0; + // Header + try { + ReadNext<int>(file, line); // -996 + int nj = ReadNext<int>(file, line); + double dx = ReadNext<double>(file, line); + double dy = ReadNext<double>(file, line); + // ----------- line shift -------------- + double x_min = ReadNext<double>(file, line); + double x_max = ReadNext<double>(file, line); + double y_min = ReadNext<double>(file, line); + double y_max = ReadNext<double>(file, line); + // ----------- line shift -------------- + int ni = ReadNext<int>(file, line); + angle = ReadNext<double>(file, line); + angle = NRLib::Degree*angle; + ReadNext<double>(file, line); // rotation origin - x + ReadNext<double>(file, line); // rotation origin - y + // ----------- line shift -------------- + ReadNext<int>(file, line); + ReadNext<int>(file, line); + ReadNext<int>(file, line); + ReadNext<int>(file, line); + ReadNext<int>(file, line); + ReadNext<int>(file, line); + ReadNext<int>(file, line); + //double lx = (ni-1)*dx; + //double ly = (nj-1)*dy; + double lx = (x_max - x_min)*cos(angle); + double ly = (y_max - y_min)*cos(angle); + + + if (!NRLibPrivate::Equal(lx/(ni-1), dx)) { + std::string text = "Inconsistent data in file. dx != lx/(nx-1).\n"; + text += "dx = "+NRLib::ToString(dx,2)+"\n"; + text += "lx = "+NRLib::ToString(lx,2)+"\n"; + text += "nx = "+NRLib::ToString(ni,0)+"\n"; + text += "lx/(nx-1) = "+NRLib::ToString(lx/(ni - 1),2); + throw FileFormatError(text); + } + if (!NRLibPrivate::Equal(ly/(nj-1), dy)) { + std::string text = "Inconsistent data in file. dy != ly/(ny-1).\n"; + text += "dy = "+NRLib::ToString(dy,2)+"\n"; + text += "ly = "+NRLib::ToString(ly,2)+"\n"; + text += "ny = "+NRLib::ToString(nj,0)+"\n"; + text += "ly/(ny-1) = "+NRLib::ToString(ly/(nj - 1),2); + throw FileFormatError(text); + } + + + surface.Resize(ni, nj); + surface.SetDimensions(x_min, y_min, lx, ly); + + ReadAsciiArrayFast(file, surface.begin(), surface.GetN()); + + surface.SetMissingValue(static_cast<A>(IRAP_MISSING)); + + surface.SetName(GetStem(filename)); + + if (!CheckEndOfFile(file)) { + throw FileFormatError("File too long."); + } + } + catch (EndOfFile& ) { + throw FileFormatError("Unexcpected end of file found while parsing " + " \"" + filename + "\""); + } + catch (Exception& e) { + throw FileFormatError("Error parsing \"" + filename + "\" as a " + "IRAP ASCII surface file at line " + ToString(line) + ":" + e.what() + "\n"); + } +} + + +template<class A> +void NRLib::ReadSgriSurf(const std::string & filename, + RegularSurface<A> & surface, + double & angle) +{ + std::ifstream header_file; + OpenRead(header_file, filename.c_str(), std::ios::in | std::ios::binary); + int i; + std::string tmp_str; + int dim; + try { + //Reading record 1: Version header + getline(header_file, tmp_str); + //Reading record 2: Grid dimension + header_file >> dim; + if(dim!=2) + throw Exception("Wrong dimension of Sgri file. We expect a surface, dimension should be 2.\n"); + + getline(header_file, tmp_str); + //Reading record 3 ... 3+dim: Axis labels + grid value label + std::vector<std::string> axis_labels(dim); + for (i=0; i<dim; i++) + getline(header_file, axis_labels[i]); + if (((axis_labels[0].find("X") == std::string::npos) && (axis_labels[0].find("x") == std::string::npos)) || + ((axis_labels[1].find("Y") == std::string::npos) && (axis_labels[1].find("y") == std::string::npos))) + throw Exception("Wrong axis labels. First axis should be x-axis, second axis should be y-axis.\n"); + // if((axis_labels[0]!="X" && axis_labels[0] !="x") || (axis_labels[1]!="Y" && axis_labels[1]!="y")) + // throw Exception("Wrong axis labels. First axis should be x-axis, second axis should be y-axis.\n"); + getline(header_file, tmp_str); + //int config = IMISSING; + + //Reading record 4+dim: Number of grids + int n_grid; + header_file >> n_grid; + if (n_grid < 1) { + throw Exception("Error: Number of grids read from sgri file must be >0"); + } + getline(header_file, tmp_str); + //Reading record 5+dim ... 5+dim+ngrid-1: Grid labels + + for (i=0; i<n_grid; i++) + getline(header_file, tmp_str); + + std::vector<float> d_values1(dim); + std::vector<float> d_values2(dim); + std::vector<int> i_values(dim); + //Reading record 5+dim+ngrid: Scaling factor of grid values + for (i=0; i<dim; i++) + header_file >> d_values1[i]; + getline(header_file,tmp_str); + //Reading record 6+dim+ngrid: Number of samples in each dir. + for (i=0; i<dim; i++) + header_file >> i_values[i]; + getline(header_file,tmp_str); + //Reading record 7+dim+ngrid: Grid sampling in each dir. + for (i=0; i<dim; i++) { + header_file >> d_values2[i]; + } + getline(header_file,tmp_str); + //Reading record 8+dim+ngrid: First point coord. + std::vector<float> min_values(dim); + for (i=0; i<dim; i++) + { + header_file >> min_values[i]; + } + int nx = 1; + int ny = 1; + + double dx, dy; + nx = i_values[0]; + dx = d_values2[0]; + ny = i_values[1]; + dy = d_values2[1]; + + if (nx < 1) { + throw Exception("Error: Number of samples in X-dir must be >= 1.\n"); + } + if (ny < 1) { + throw Exception("Error: Number of samples in Y-dir must be >= 1.\n"); + } + + if (dx <= 0.0) { + throw Exception("Error: Grid sampling in X-dir must be > 0.0.\n"); + + } + if (dy <= 0.0) { + throw Exception("Error: Grid sampling in Y-dir must be > 0.0.\n"); + } + + double lx = nx*dx; + double ly = ny*dy; + + double x_min = min_values[0]-0.5*dx; //In regular grid, these are at value; + double y_min = min_values[1]-0.5*dy; //in sgri, at corner of cell, hence move. + + header_file >> angle; + + surface.Resize(nx, ny, 0.0); + surface.SetDimensions(x_min, y_min, lx, ly); + + getline(header_file, tmp_str); + //Reading record 10+dim+ngrid: Undef value + float missing_code; + header_file >> missing_code; + surface.SetMissingValue(missing_code); + getline(header_file, tmp_str); + //Reading record 11+dim+ngrid: Filename of binary file + std::string bin_file_name; + getline(header_file, tmp_str); + if (!tmp_str.empty()) { + std::locale loc; + int i = 0; + char c = tmp_str[i]; + while (!std::isspace(c,loc)) { + i++; + c = tmp_str[i]; + } + tmp_str.erase(tmp_str.begin()+i, tmp_str.end()); + } + if (tmp_str.empty()) + bin_file_name = NRLib::ReplaceExtension(filename, "Sgri"); + else { + std::string path = GetPath(filename); + bin_file_name = path + "/" + tmp_str; + } + //Reading record 12+dim+ngrid: Complex values + bool has_complex; + header_file >> has_complex; + if (has_complex != 0 ) { + throw Exception("Error: Can not read Sgri binary file. Complex values?"); + } + + surface.SetName(GetStem(bin_file_name)); + + std::ifstream bin_file; + OpenRead(bin_file, bin_file_name, std::ios::in | std::ios::binary); + ReadBinaryFloatArray(bin_file, surface.begin(), surface.GetN()); + } + catch (Exception& e) { + throw FileFormatError("Error parsing \"" + filename + "\" as a " + "Sgri surface file " + e.what() + "\n"); + } +} + +template <class A> +void NRLib::ReadMulticolumnAsciiSurf(std::string filename, + RegularSurface<A> & surface, + double x_ref, + double y_ref, + double lx, + double ly, + int * ilxl_area, + double il0_ref, + double xl0_ref) +{ + + try { + //Create surface with area corresponding to segy-grid (ilxl_area), but use sampling from surface file + //il0_ref and xl0_ref are il/xl values at rotation corner, this is used to match IL/XL values from surface with segy + + int header_start_line; + bool is_multicolumn_ascii = false; + is_multicolumn_ascii = FindMulticolumnAsciiLine(filename, header_start_line); + + if (is_multicolumn_ascii == false) + throw Exception("Error: Did not recognize file as a multicolumns ascii file.\n"); + + std::ifstream file; + NRLib::OpenRead(file, filename); + int line = 0; + + for (int i = 0; i < header_start_line; i++) { + NRLib::DiscardRestOfLine(file, line, false); + } + + //Header line, contains X, Y, Z, Inline, Crossline + std::vector<std::string> variable_names(5); + variable_names[0] = NRLib::ReadNext<std::string>(file, line); + variable_names[1] = NRLib::ReadNext<std::string>(file, line); + variable_names[2] = NRLib::ReadNext<std::string>(file, line); + variable_names[3] = NRLib::ReadNext<std::string>(file, line); + variable_names[4] = NRLib::ReadNext<std::string>(file, line); + + std::vector<std::vector<double> > data(5); + + while (NRLib::CheckEndOfFile(file)==false) { + for (int i = 0; i < 5; i++) { + data[i].push_back(NRLib::ReadNext<double>(file, line)); + } + } + + int il_index = -1; + int xl_index = -1; + int x_index = -1; + int y_index = -1; + int z_index = -1; + for (int i = 0; i < 5; i++) { + if (variable_names[i] == "Inline" || variable_names[i] == "IL") + il_index = i; + if (variable_names[i] == "Crossline" || variable_names[i] == "XL") + xl_index = i; + if (variable_names[i] == "X" || variable_names[i] == "UTMX") + x_index = i; + if (variable_names[i] == "Y" || variable_names[i] == "UTMY") + y_index = i; + if (variable_names[i] == "Attribute" || variable_names[i] == "Z" || variable_names[i] == "TWT") + z_index = i; + } + + std::string err_txt = ""; + if (il_index == -1) + err_txt += "Could not find variable name for Inline in file " + filename +". (Tried Inline, IL).\n"; + if (xl_index == -1) + err_txt += "Could not find variable name for Crossline in file " + filename +". (Tried Crossline, XL).\n"; + if (x_index == -1) + err_txt += "Could not find variable name for X in file " + filename +". (Tried X, UTMX).\n"; + if (y_index == -1) + err_txt += "Could not find variable name for Y in file " + filename +". (Tried Y, UTMY).\n"; + if (z_index == -1) + err_txt += "Could not find variable name for Attribute in file " + filename +". (Tried Attribute, Z, TWT).\n"; + + if (err_txt != "") + throw Exception("Error when finding header information in " + filename + " :" + err_txt + "\n"); + + std::vector<double> il_vec = data[il_index]; + std::vector<double> xl_vec = data[xl_index]; + std::vector<double> x_vec = data[x_index]; + std::vector<double> y_vec = data[y_index]; + std::vector<double> z_vec = data[z_index]; + + //Find min and max IL/XL + std::vector<double> il_vec_sorted = il_vec; + std::sort(il_vec_sorted.begin(), il_vec_sorted.end()); + il_vec_sorted.erase(std::unique(il_vec_sorted.begin(), il_vec_sorted.end()), il_vec_sorted.end()); + + std::vector<double> xl_vec_sorted = xl_vec; + std::sort(xl_vec_sorted.begin(), xl_vec_sorted.end()); + xl_vec_sorted.erase(std::unique(xl_vec_sorted.begin(), xl_vec_sorted.end()), xl_vec_sorted.end()); + + int ni_file = static_cast<int>(il_vec_sorted.size()); + int nj_file = static_cast<int>(xl_vec_sorted.size()); + + int il_min_file = static_cast<int>(il_vec_sorted[0]); + int il_max_file = static_cast<int>(il_vec_sorted[ni_file-1]); + + int xl_min_file = static_cast<int>(xl_vec_sorted[0]); + int xl_max_file = static_cast<int>(xl_vec_sorted[nj_file-1]); + + int n = static_cast<int>(data[0].size()); + A missing = static_cast<A>(NRLib::MULT_IRAP_MISSING); + + NRLib::Grid2D<A> ilxl_grid_file(ni_file, nj_file, missing); + + int d_il_file = static_cast<int>((il_max_file - il_min_file) / (ni_file - 1)); + int d_xl_file = static_cast<int>((xl_max_file - xl_min_file) / (nj_file - 1)); + + for (int k = 0; k < n; k++) { + //Local IL/XL + int il_loc = (static_cast<int>(data[il_index][k]) - il_min_file)/d_il_file; + int xl_loc = (static_cast<int>(data[xl_index][k]) - xl_min_file)/d_xl_file; + + ilxl_grid_file(il_loc, xl_loc) = static_cast<A>(data[z_index][k]); + } + + //Check consistency between IL/XL sampling in surface and sampling of grid values + int t1 = 0; + int t2 = 0; + for (int i = 0; i < ni_file; i++) { + if (ilxl_grid_file(i,nj_file/2) != missing) { + t1 = i; + for (int k = t1+1; k < ni_file; k++) { + if (ilxl_grid_file(k,nj_file/2) != missing) { + t2 = k; + k = ni_file-1; + i = ni_file-1; + } + } + } + } + int diff_il = (t2 - t1)*d_il_file; + t1 = 0; + t2 = 0; + for (int j = 0; j < nj_file; j++) { + if (ilxl_grid_file(ni_file/2,j) != missing) { + t1 = j; + for (int k = t1+1; k < nj_file; k++) { + if (ilxl_grid_file(ni_file/2,k) != missing) { + t2 = k; + k = nj_file-1; + j = nj_file-1; + } + } + } + } + int diff_xl = (t2 - t1)*d_xl_file; + + if (diff_il != d_il_file) { + err_txt += "Found sampling of IL-values to be " + NRLib::ToString(d_il_file) + + ", but grid values are given with a IL-sampling of " + NRLib::ToString(diff_il) + ".\n"; + } + if (diff_xl != d_xl_file) { + err_txt += "Found sampling of XL-values to be " + NRLib::ToString(d_xl_file) + + ", but grid values are given with a XL-sampling of " + NRLib::ToString(diff_xl) + ".\n"; + } + + if (err_txt != "") + throw Exception(err_txt); + + int il_min_segy = ilxl_area[0]; + int il_max_segy = ilxl_area[1]; + int xl_min_segy = ilxl_area[2]; + int xl_max_segy = ilxl_area[3]; + int il_step_segy = ilxl_area[4]; + int xl_step_segy = ilxl_area[5]; + + //Create IL/XL surface as large as segy geometry, but with sampling from file + int n_il = (il_max_segy - il_min_segy)/d_il_file + 1; + int n_xl = (xl_max_segy - xl_min_segy)/d_xl_file + 1; + + //Find IL/XL of rotation corner + int il0_segy = static_cast<int>(il0_ref+0.5); + int xl0_segy = static_cast<int>(xl0_ref+0.5); + + // To ensure that the IL XL we find are existing traces + if (il0_segy < il_min_segy) + il0_segy -= (il0_segy - il_min_segy) % il_step_segy; + else if (il0_segy > il_max_segy) + il0_segy += (il_max_segy - il0_segy) % il_step_segy; + + if (xl0_segy < xl_min_segy) + xl0_segy -= (xl0_segy - xl_min_segy) % xl_step_segy; + else if (xl0_segy > xl_max_segy) + xl0_segy += (xl_max_segy - xl0_segy) % xl_step_segy; + + NRLib::Grid2D<A> surface_grid(n_il, n_xl, static_cast<A>(NRLib::MULT_IRAP_MISSING)); + int grid_i, grid_j; + for (int i = 0; i < n_il; i++) { + for (int j = 0; j < n_xl; j++) { + + //Global IL/XL of surface_grid + int il_glob = il_min_segy + i*d_il_file; + int xl_glob = xl_min_segy + j*d_xl_file; + + //Get corresponding IL/XL from file_grid + int il_loc_file = (il_glob - il_min_file)/d_il_file; + int xl_loc_file = (xl_glob - xl_min_file)/d_xl_file; + + //If surface is smaller than segy-grid, we set is as missing + A z; + if (il_loc_file < 0 || il_loc_file > ni_file-1 || xl_loc_file < 0 || xl_loc_file > nj_file-1) + z = missing; + else + z = ilxl_grid_file(il_loc_file, xl_loc_file); + + //Fill in correct corner + if (il0_segy == il_min_segy && xl0_segy == xl_min_segy) { + grid_i = i; + grid_j = j; + } + else if (il0_segy == il_max_segy && xl0_segy == xl_max_segy) { + grid_i = n_il - i - 1; + grid_j = n_xl - j - 1; + } + else if (il0_segy == il_min_segy && xl0_segy == xl_max_segy) { + grid_i = i; + grid_j = n_xl - j - 1; + } + else { //il0_segy == il_max_segy && xl0_segy == xl_min_segy + grid_i = n_il - i - 1; + grid_j = j; + } + + surface_grid(grid_i, grid_j) = z; + } + } + + surface = RegularSurface<A>(x_ref, y_ref, lx, ly, surface_grid); + surface.SetMissingValue(static_cast<A>(MULT_IRAP_MISSING)); + surface.SetName(GetStem(filename)); + } + catch (Exception& e) { + throw FileFormatError("Error parsing \"" + filename + "\" as a " + "Multicolumn ASCII file: \n" + e.what() + "\n"); + } + +} + + +template <class A> +void NRLib::WriteIrapClassicAsciiSurf(const RegularSurface<A> & surf, + double angle, + const std::string & filename) +{ + std::ofstream file; + OpenWrite(file, filename); + + file << std::fixed + << std::setprecision(6) + << -996 << " " + << surf.GetNJ() << " " + << surf.GetDX() << " " + << surf.GetDY() << "\n" + << std::setprecision(2) + << surf.GetXMin() << " " + << surf.GetXMax() << " " + << surf.GetYMin() << " " + << surf.GetYMax() << "\n" + << surf.GetNI() << " " + << std::setprecision(6) + << angle*180/NRLib::Pi << " " + << std::setprecision(2) + << surf.GetXMin() << " " + << surf.GetYMin() << "\n" + << " 0 0 0 0 0 0 0\n"; + + file.precision(6); + + if (surf.GetMissingValue() == IRAP_MISSING) { + for (size_t i = 0; i < surf.GetN(); i++) { + file << surf(i) << " "; + if((i+1) % 6 == 0) + file << "\n"; + } + } + else { + for (size_t i = 0; i < surf.GetN(); i++) { + if (surf.IsMissing(surf(i))) + file << IRAP_MISSING << " "; + else + file << surf(i) << " "; + if((i+1) % 6 == 0) + file << "\n"; + } + } + file.close(); +} + + +template <class A> +void NRLib::WriteStormBinarySurf(const RegularSurface<A> & surf, + const std::string & filename) +{ + std::ofstream file; + OpenWrite(file, filename.c_str(), std::ios::out | std::ios::binary); + + file.precision(14); + + file << "STORMGRID_BINARY\n\n" + << surf.GetNI() << " " << surf.GetNJ() << " " + << surf.GetDX() << " " << surf.GetDY() << "\n" + << surf.GetXMin() << " " << surf.GetXMax() << " " + << surf.GetYMin() << " " << surf.GetYMax() << "\n"; + + if (surf.GetMissingValue() == STORM_MISSING) { + // Purify *sometimes* claims a UMR for the call below. No-one understands why... + WriteBinaryDoubleArray(file, surf.begin(), surf.end()); + } + else { + std::vector<double> data(surf.GetN()); + std::copy(surf.begin(), surf.end(), data.begin()); + std::replace(data.begin(), data.end(), surf.GetMissingValue(), static_cast<A>(STORM_MISSING)); + WriteBinaryDoubleArray(file, data.begin(), data.end()); + } + file.close(); +} + +#endif // NRLIB_SURFACEIO_HPP diff --git a/ThirdParty/NRLib/nrlib/volume/module.mk b/ThirdParty/NRLib/nrlib/volume/module.mk new file mode 100644 index 0000000000..54f403d99e --- /dev/null +++ b/ThirdParty/NRLib/nrlib/volume/module.mk @@ -0,0 +1 @@ +SRC += $(NRLIB_BASE_DIR)volume/volume.cpp diff --git a/ThirdParty/NRLib/nrlib/volume/volume.cpp b/ThirdParty/NRLib/nrlib/volume/volume.cpp new file mode 100644 index 0000000000..e2bb7658e7 --- /dev/null +++ b/ThirdParty/NRLib/nrlib/volume/volume.cpp @@ -0,0 +1,592 @@ +// $Id: volume.cpp 1061 2012-09-13 09:09:57Z georgsen $ + +// Copyright (c) 2011, Norwegian Computing Center +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// • Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// • Redistributions in binary form must reproduce the above copyright notice, this list of +// conditions and the following disclaimer in the documentation and/or other materials +// provided with the distribution. +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT +// SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include "volume.hpp" + +#include <algorithm> +#include <cmath> +#include "../iotools/fileio.hpp" +#include "../iotools/stringtools.hpp" +#include "../math/constants.hpp" +#include "../surface/regularsurface.hpp" +#include "../surface/regularsurfacerotated.hpp" +#include "../surface/surface.hpp" +#include "../surface/surfaceio.hpp" + +using namespace NRLib; + +Volume::Volume() +{ + x_min_ = 0.0; + y_min_ = 0.0; + lx_ = 0.0; + ly_ = 0.0; + lz_ = 0.0; + angle_ = 0.0; + z_top_ = new ConstantSurface<double>(0.0); + z_bot_ = new ConstantSurface<double>(0.0); + tolerance_ = 1e-6; +} + +Volume::Volume(double x_min, double y_min, double z_min, double lx, double ly, double lz, double angle) +: x_min_(x_min), + y_min_(y_min), + lx_(lx), + ly_(ly), + lz_(lz), + angle_(angle) +{ + z_top_ = new ConstantSurface<double>(z_min); + z_bot_ = new ConstantSurface<double>(z_min+lz); + tolerance_ = 1e-6; +} + + +Volume::Volume(double x_min, + double y_min, + double lx, + double ly, + const Surface<double> & top, + const Surface<double> & bot, + double angle) +: x_min_(x_min), + y_min_(y_min), + lx_(lx), + ly_(ly), + angle_(angle) +{ + z_top_ = top.Clone(), + z_bot_ = bot.Clone(), + lz_ = RecalculateLZ(); + tolerance_ = 1e-6; +} + + +Volume::Volume(const Volume & volume) +{ + x_min_ = volume.x_min_; + y_min_ = volume.y_min_; + lx_ = volume.lx_; + ly_ = volume.ly_; + lz_ = volume.lz_; + angle_ = volume.angle_; + if (volume.z_top_ != 0) { + z_top_ = volume.z_top_->Clone(); + } + else { + z_top_ = 0; + } + if (volume.z_bot_ != 0) { + z_bot_ = volume.z_bot_->Clone(); + } + else { + z_bot_ = 0; + } + + tolerance_ = 1e-6; +} + + +Volume::~Volume() +{ + delete z_top_; + delete z_bot_; +} + + +Volume& Volume::operator=(const Volume& rhs) +{ + /// \todo Use "copy and swap" for exception safety. + + if (this == &rhs) return *this; + + x_min_ = rhs.x_min_; + y_min_ = rhs.y_min_; + lx_ = rhs.lx_; + ly_ = rhs.ly_; + lz_ = rhs.lz_; + angle_ = rhs.angle_; + tolerance_=rhs.tolerance_; + + delete z_top_; + if (rhs.z_top_ != 0) { + z_top_ = rhs.z_top_->Clone(); + } + else { + z_top_ = 0; + } + + delete z_bot_; + if (rhs.z_bot_ != 0) { + z_bot_ = rhs.z_bot_->Clone(); + } + else { + z_bot_ = 0; + } + + /* + delete erosion_top_; + if (rhs.erosion_top_ != 0) { + erosion_top_ = rhs.erosion_top_->Clone(); + } + else { + erosion_top_ = 0; + } + + delete erosion_bot_; + if (rhs.erosion_bot_ != 0) { + erosion_bot_ = rhs.erosion_bot_->Clone(); + } + else { + erosion_bot_ = 0; + } + */ + + return *this; +} + + +void Volume::SetDimensions(double x_min, double y_min, + double lx, double ly) +{ + x_min_ = x_min; + y_min_ = y_min; + lx_ = lx; + ly_ = ly; + + CheckSurfaces(); + lz_ = RecalculateLZ(); +} + +void Volume::SetAngle(double angle) +{ + angle_ = angle; + + CheckSurfaces(); + lz_ = RecalculateLZ(); +} + + +void Volume::SetSurfaces(const Surface<double>& top_surf, + const Surface<double>& bot_surf, + bool skip_check) +{ + delete z_top_; + z_top_ = top_surf.Clone(); + + delete z_bot_; + z_bot_ = bot_surf.Clone(); + + if ((lx_ > 0.0 || ly_ > 0.0 ) && skip_check == false) { //Make sure area is set, and we need to check + CheckSurfaces(); + } + + lz_ = RecalculateLZ(); +} + + +/* +void Volume::SetSurfaces(const Surface<double>& top_surf, + const Surface<double>& bot_surf) + //const Surface<double>& erosion_top, + //const Surface<double>& erosion_bot) +{ + delete z_top_; + z_top_ = top_surf.Clone(); + + delete z_bot_; + z_bot_ = bot_surf.Clone(); + + delete erosion_top_; + erosion_top_ = erosion_top.Clone(); + + delete erosion_bot_; + erosion_bot_ = erosion_bot.Clone(); + + if (lx_ > 0.0 || ly_ > 0.0 ) { //Check that area is set. + CheckSurfaces(); + } + + lz_ = RecalculateLZ(); +} +*/ + + +double +Volume::GetZMin(size_t nx, size_t ny) const +{ + return(GetTopZMin(nx, ny)); +} + +double +Volume::GetZMax(size_t nx, size_t ny) const +{ + return(GetBotZMax(nx, ny)); +} + +double +Volume::GetTopZMin(size_t nx, size_t ny) const +{ + return(GetZExtreme(nx,ny,z_top_,true)); +} + + +double +Volume::GetTopZMax(size_t nx, size_t ny) const +{ + return(GetZExtreme(nx,ny,z_top_,false)); +} + +double +Volume::GetBotZMin(size_t nx, size_t ny) const +{ + return(GetZExtreme(nx,ny,z_bot_,true)); +} + +double +Volume::GetBotZMax(size_t nx, size_t ny) const +{ + return(GetZExtreme(nx,ny,z_bot_,false)); +} + + +double +Volume::GetZExtreme(size_t nx, size_t ny, const Surface<double> * surf, bool getmin) const +{ + if (surf == NULL) + surf = z_top_; + double result; + if (lx_ > 0.0 || ly_ > 0.0 ) {//Check that area is set. + size_t i, j; + double di = lx_/static_cast<double>(nx); + double dj = ly_/static_cast<double>(ny); + double dxi = cos(angle_)*di; + double dyi = sin(angle_)*di; + double dxj = -sin(angle_)*dj; + double dyj = cos(angle_)*dj; + double x, y, z; + double x0 = x_min_+0.5*(dxi+dxj); //Cell center x + double y0 = y_min_+0.5*(dyi+dyj); //Cell center y + result = surf->GetZ(x0,y0); + for (j = 0; j < ny; j++) { + x = x0 + dxj*j; + y = y0 + dyj*j; + for (i = 0; i < nx; i++) { + z = surf->GetZ(x, y); + if (surf->IsMissing(z) == false && ( //Found actual value. + surf->IsMissing(result) == true || //Had no value + (getmin == true && z < result) || //Looking for min, found new. + (getmin == false && z > result))) //Looking for max, found new. + result = z; + x += dxi; + y+= dyi; + } + } + } + else { + if (getmin == true) + result = surf->Min(); + else + result = surf->Max(); + } + return(result); +} + +void +Volume::FindCenter(double & x, double & y, double & z) const +{ + x = GetXMin() + 0.5 * GetLX(); + y = GetYMin() + 0.5 * GetLY(); + z = 0.5 * (z_top_->GetZ(x,y) + z_bot_->GetZ(x,y)); +} + +// Writes surface to file if non-constant. Returns filename or +// surface level if surface is constant. +static std::string WriteSingleSurface(const Surface<double>* surf, + const std::string& grid_filename, + const std::string& surface_name, + bool remove_path +) +{ + if (surf == 0) { + return "0"; + } + + if (typeid(*surf) == typeid(ConstantSurface<double>)) { + return (ToString((dynamic_cast<const ConstantSurface<double>*>(surf))->GetZ())); + } + else if (typeid(*surf) == typeid(RegularSurface<double>)) { + std::string filename = grid_filename + surface_name; + /// \todo Fix this. + // std::string filename = MainPart(grid_filename) + surface_name + ".s"; + const RegularSurface<double>* rsurf + = dynamic_cast<const RegularSurface<double>*>(surf); + rsurf->WriteToFile(filename, SURF_STORM_BINARY); + if(remove_path) + return RemovePath(filename); + else + return filename; + } + else if (typeid(*surf) == typeid(RegularSurfaceRotated<double>)) { + std::string filename = grid_filename + surface_name; + /// \todo Fix this. + // std::string filename = MainPart(grid_filename) + surface_name + ".s"; + const RegularSurfaceRotated<double>* rsurf + = dynamic_cast<const RegularSurfaceRotated<double>*>(surf); + rsurf->WriteToFile(filename, SURF_STORM_BINARY); + if(remove_path) + return RemovePath(filename); + else + return filename; + } + else { + throw Exception("Bug: Trying to write unsupported surface type to file."); + } +} + + +void Volume::WriteVolumeToFile(std::ofstream& file, + const std::string& filename, bool remove_path) const +{ + file << x_min_ << " " << lx_ << " " << y_min_ << " " << ly_ << " " + << WriteSingleSurface(z_top_, filename, "_top", remove_path) << " " + << WriteSingleSurface(z_bot_, filename, "_bot", remove_path) << " " +// << WriteSingleSurface(erosion_top_, filename, "_erosion_top", remove_path) << " " +// << WriteSingleSurface(erosion_bot_, filename, "_erosion_bot", remove_path) << "\n" + << GetLZ() << " " << (180.0*angle_)/NRLib::Pi << "\n"; +} + + +void Volume::ReadVolumeFromFile(std::ifstream& file, int line, const std::string& path) +{ + x_min_ = ReadNext<double>(file, line); + lx_ = ReadNext<double>(file, line); + y_min_ = ReadNext<double>(file, line); + ly_ = ReadNext<double>(file, line); + bool topfile, botfile;//, toperofile, boterofile; + std::string token = ReadNext<std::string>(file, line); + delete z_top_; + z_top_ = NULL; + if (IsType<double>(token)) { + z_top_ = new ConstantSurface<double>(ParseType<double>(token)); + topfile = false; + } else { + std::string path_file_name = NRLib::PrependDir(path, token); + z_top_ = new RegularSurface<double>(path_file_name); + topfile = true; + } + token = ReadNext<std::string>(file, line); + delete z_bot_; + if (IsType<double>(token)) { + z_bot_ = new ConstantSurface<double>(ParseType<double>(token)); + botfile = false; + } else { + std::string path_file_name = NRLib::PrependDir(path, token); + z_bot_ = new RegularSurface<double>(path_file_name); + botfile = true; + } + token = ReadNext<std::string>(file, line); + /* + delete erosion_top_; + if (IsType<double>(token)) { + erosion_top_ = new ConstantSurface<double>(ParseType<double>(token)); + toperofile = false; + } else { + std::string path_file_name = NRLib::PrependDir(path, token); + erosion_top_ = new RegularSurface<double>(path_file_name); + toperofile = true; + }*/ + token = ReadNext<std::string>(file, line); + /* + delete erosion_bot_; + if (IsType<double>(token)) { + erosion_bot_ = new ConstantSurface<double>(ParseType<double>(token)); + boterofile = false; + } else { + std::string path_file_name = NRLib::PrependDir(path, token); + erosion_bot_ = new RegularSurface<double>(path_file_name); + boterofile = true; + } + */ + + lz_ = ReadNext<double>(file, line); + angle_ = (NRLib::Pi * ReadNext<double>(file, line)) / 180.0; + if(topfile == true){ + if (!CheckSurface(*z_top_)) { + throw Exception("The top surface does not fit with the volume."); + } + } + if(botfile == true){ + if (!CheckSurface(*z_bot_)) { + throw Exception("The bottom surface does not fit with the volume."); + } + } + /* + if(toperofile == true){ + if (!CheckSurface(*erosion_top_)) { + throw Exception("The erosion top surface does not fit with the volume."); + } + } + if(boterofile == true){ + if (!CheckSurface(*erosion_bot_)) { + throw Exception("The erosion bottom surface does not fit with the volume."); + } + } + */ + +} + + +void Volume::GlobalToLocalCoord(double global_x, + double global_y, + double& local_x, + double& local_y) const +{ + double x_rel = global_x - x_min_; + double y_rel = global_y - y_min_; + + local_x = std::cos(angle_)*x_rel + std::sin(angle_)*y_rel; + local_y = - std::sin(angle_)*x_rel + std::cos(angle_)*y_rel; +} + + +void Volume::LocalToGlobalCoord(double local_x, + double local_y, + double& global_x, + double& global_y) const +{ + global_x = std::cos(angle_)*local_x - std::sin(angle_)*local_y + x_min_; + global_y = std::sin(angle_)*local_x + std::cos(angle_)*local_y + y_min_; +} + + +double Volume::RecalculateLZ() +{ + double lz = 0.0; + if (lx_ > 0.0 || ly_ > 0.0) { //Only do if area is initialized. + // Just using a arbitary grid resolution. + int nx = 100; + int ny = 100; + + double dx = lx_ / nx; + double dy = ly_ / ny; + + double z_value_bot = 0.0; + double z_value_top = 0.0; + + for (int i = 0; i < nx; ++i) { + for (int j = 0; j < ny; ++j) { + double x, y; + LocalToGlobalCoord(dx * i, dy * j, x, y); + + z_value_bot = z_bot_->GetZ(x, y); + z_value_top = z_top_->GetZ(x, y); + + if (z_bot_->IsMissing(z_value_bot) == false && z_top_->IsMissing(z_value_top) == false) + lz = std::max(lz, z_bot_->GetZ(x, y) - z_top_->GetZ(x, y)); + } + } + } + return lz; +} + + +bool Volume::CheckSurface(const Surface<double>& surface) const +{ + std::vector<double> x(4); + std::vector<double> y(4); + + LocalToGlobalCoord( 0, 0, x[0], y[0]); + LocalToGlobalCoord(lx_, 0, x[1], y[1]); + LocalToGlobalCoord( 0, ly_, x[2], y[2]); + LocalToGlobalCoord(lx_, ly_, x[3], y[3]); + + double x_min = *(std::min_element(x.begin(), x.end())); + double y_min = *(std::min_element(y.begin(), y.end())); + double x_max = *(std::max_element(x.begin(), x.end())); + double y_max = *(std::max_element(y.begin(), y.end())); + + return surface.EnclosesRectangle(x_min, x_max, y_min, y_max); +} + + +bool Volume::CheckSurfaces() const +{ + if (!CheckSurface(*z_top_)) { + throw Exception("The top surface does not cover the volume."); + } + if (!CheckSurface(*z_bot_)) { + throw Exception("The bottom surface does not cover the volume."); + } + /* + if (erosion_top_ && !CheckSurface(*erosion_top_)) { + throw Exception("The erosion top surface does not cover the volume."); + } + if (erosion_bot_ && !CheckSurface(*erosion_bot_)) { + throw Exception("The erosion bottom surface does not cover the volume."); + } + */ + return true; +} + + +int Volume::IsInsideTolerance(double x, double y)const +{ + + double rx = (x-x_min_)*cos(angle_)+(y-y_min_)*sin(angle_); + double ry = -(x-x_min_)*sin(angle_) + (y-y_min_)*cos(angle_); + if (rx+tolerance_ < 0.0 || rx-tolerance_ > lx_ || ry+tolerance_ <0.0 || ry-tolerance_ > ly_) + return(0); + else + return(1); +} + + +int Volume::IsInside(double x, double y)const +{ + + double rx = (x-x_min_)*cos(angle_)+(y-y_min_)*sin(angle_); + double ry = -(x-x_min_)*sin(angle_) + (y-y_min_)*cos(angle_); + if (rx < 0.0 || rx > lx_ || ry <0.0 || ry > ly_) + return(0); + else + return(1); +} + + + +bool Volume::IsInside(double x, double y, double z)const +{ + if (IsInside(x, y) && + z > z_top_->GetZ(x, y) && z < z_bot_->GetZ(x, y)) { + return true; + } + return false; +} + +bool Volume::IsInsideZTolerance(double x, double y, double z, double tolerance)const +{ + if (IsInside(x, y) && + z > (z_top_->GetZ(x, y) - tolerance) && z < (z_bot_->GetZ(x, y) + tolerance)) { + return true; + } + return false; +} diff --git a/ThirdParty/NRLib/nrlib/volume/volume.hpp b/ThirdParty/NRLib/nrlib/volume/volume.hpp new file mode 100644 index 0000000000..692d3d6cfa --- /dev/null +++ b/ThirdParty/NRLib/nrlib/volume/volume.hpp @@ -0,0 +1,146 @@ +// $Id: volume.hpp 1061 2012-09-13 09:09:57Z georgsen $ + +// Copyright (c) 2011, Norwegian Computing Center +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// • Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// • Redistributions in binary form must reproduce the above copyright notice, this list of +// conditions and the following disclaimer in the documentation and/or other materials +// provided with the distribution. +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT +// SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef NRLIB_VOLUME_HPP +#define NRLIB_VOLUME_HPP + +#include <fstream> + +namespace NRLib { + template <class A> + class Surface; + + class Volume { + public: + Volume(); + Volume(double x_min, double y_min, double z_min, double lx, double ly, double lz, double angle); + + /// \brief Constructor with surfaces. + Volume(double x_min, + double y_min, + double lx, + double ly, + const Surface<double> & top, + const Surface<double> & bot, + double angle); + + Volume(const Volume& volume); + virtual ~Volume(); + Volume& operator=(const Volume& rhs); + + void SetDimensions(double x_min, double y_min, + double lx, double ly); + void SetAngle(double angle); + void SetTolerance(double tolerance){tolerance_=tolerance;} + double GetTolerance(){return tolerance_;} + + double GetXMin() const {return x_min_;} + double GetYMin() const {return y_min_;} + + /// \brief Get extreme values of z for volume, with nx, ny resolution. + double GetZMin(size_t nx, size_t ny) const; + double GetZMax(size_t nx, size_t ny) const; + + double GetLX() const {return lx_;} + double GetLY() const {return ly_;} + double GetAngle() const {return angle_;} + + /// \brief Maximum height of grid. + double GetLZ() const {return lz_;} + + /// rel_x and rel_y in [0,1]. + void GetXYFromRelative(double rel_x, double rel_y, double &x, double &y) const{ + LocalToGlobalCoord(rel_x*lx_, rel_y*ly_, x, y); + } + + /// \brief Get z-range for top and bottom surfaces, with nx, ny resolution. + double GetTopZMin(size_t nx, size_t ny) const; //Equal to GetZMin + double GetTopZMax(size_t nx, size_t ny) const; + double GetBotZMin(size_t nx, size_t ny) const; + double GetBotZMax(size_t nx, size_t ny) const; //Equal to GetZMax + + /// \brief Set surfaces. + void SetSurfaces(const Surface<double>& top_surf, + const Surface<double>& bot_surf, + bool skip_check = true); //Sometimes, we do not want an area cover check here. + + /* + void SetSurfaces(const Surface<double>& top_surf, + const Surface<double>& bot_surf); + const Surface<double>& erosion_top, + const Surface<double>& erosion_bot); + */ + + const Surface<double> & GetTopSurface() const {return *z_top_;} + const Surface<double> & GetBotSurface() const {return *z_bot_;} + //const Surface<double>& GetErosionTop() const {return *erosion_top_;} + //const Surface<double>& GetErosionBot() const {return *erosion_bot_;} + Surface<double> & GetTopSurface() {return *z_top_;} + Surface<double> & GetBotSurface() {return *z_bot_;} + + int IsInside(double x, double y) const; + bool IsInside(double x, double y, double z)const; + int IsInsideTolerance(double x, double y)const; + bool IsInsideZTolerance(double x, double y, double z, double tolerance) const; + + void FindCenter(double & x, double & y, double & z) const; + + /// \brief Checks if surface covers the whole volume. + bool CheckSurface(const Surface<double>& surface) const; + + protected: + /// \brief Reader and writer on storm-format. + /// \todo Maybe move to storm-specific files. + void WriteVolumeToFile(std::ofstream& file, + const std::string& filename, + bool remove_path = true) const; + void ReadVolumeFromFile(std::ifstream& file, int line, const std::string& path); + + /// \brief The local coorinates are (0,0) in (x_min, y_min), and + /// have the same orientation as the volume. + void GlobalToLocalCoord(double global_x, double global_y, + double& local_x, double& local_y) const; + + void LocalToGlobalCoord(double local_x, double local_y, + double& global_x, double& global_y) const; + + private: + virtual double RecalculateLZ(); + /// \brief Check all surfaces. + bool CheckSurfaces() const; + /// \brief Returns min or max of surface on nx by ny grid in volume. + double GetZExtreme(size_t nx, size_t ny, const Surface<double> * surf, bool getmin) const; + + double x_min_; + double y_min_; + double lx_; + double ly_; + double lz_; + Surface<double>* z_top_; + Surface<double>* z_bot_; + //Surface<double>* erosion_top_; + //Surface<double>* erosion_bot_; + double angle_; + double tolerance_; + }; +} // namespace NRLib + +#endif // NRLIB_VOLUME_HPP diff --git a/ThirdParty/NRLib/nrlib/well/laswell.cpp b/ThirdParty/NRLib/nrlib/well/laswell.cpp new file mode 100644 index 0000000000..48e90472b6 --- /dev/null +++ b/ThirdParty/NRLib/nrlib/well/laswell.cpp @@ -0,0 +1,612 @@ +// $Id: laswell.cpp 1245 2014-02-25 09:57:02Z hauge $ + +// Copyright (c) 2011, Norwegian Computing Center +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// • Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// • Redistributions in binary form must reproduce the above copyright notice, this list of +// conditions and the following disclaimer in the documentation and/or other materials +// provided with the distribution. +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT +// SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include <cassert> +#include <fstream> +#include <string> +#include <vector> +#include <math.h> + +#include "laswell.hpp" + +#include "../iotools/fileio.hpp" +#include "../iotools/stringtools.hpp" + +using namespace NRLib; + +LasWell::LasWell() : + version_("Unknown"), + wrap_(false), + comma_delimited_(false), + depth_unit_("Unknown"), + start_depth_(0), + stop_depth_(0), + depth_increment_(0) +{ +} + +LasWell::LasWell(const std::string & filename) : + version_("Unknown"), + wrap_(false), + comma_delimited_(false), + depth_unit_("Unknown"), + start_depth_(0), + stop_depth_(0), + depth_increment_(0) +{ + std::string err_txt; + std::ifstream fin; + try { + ReadHeader(filename, fin, err_txt); + if(err_txt == "") { + if(fin.eof() == false) + ReadLogs(fin, err_txt); + else + err_txt = "No log data found in well "+GetWellName()+"\n"; + } + } + catch(Exception & e) { + err_txt += e.what(); + } + if(fin.is_open()) + fin.close(); + if(err_txt != "") + throw(FileFormatError(err_txt)); + else { //Final initialisation of unset values + if(stop_depth_ == 0) + stop_depth_ = GetContMissing(); + if(depth_increment_ == 0) + depth_increment_ = GetContMissing(); + } + const std::map<std::string,std::vector<double> > & logs = GetContLog(); + std::map<std::string,std::vector<double> >::const_iterator it = logs.begin(); + int n_data = static_cast<int>(it->second.size()); + this->SetNumberOfData(n_data); +} + +void +LasWell::ReadHeader(const std::string & filename, + std::ifstream & fin, + std::string & err_txt) +{ + std::string well_name = NRLib::GetStem(filename); + SetWellName(well_name); + + fin.open(filename.c_str()); + + if (fin.is_open()) { + bool version_read = false; + bool well_read = false; + bool curve_read = false; + + std::string line; + getline (fin,line); // First log line + + bool end_of_header = false; + + while ( !fin.eof() && !end_of_header) { + line = NRLib::Chomp(line); + + if (line.empty()) { // Empty line, do nothing + getline (fin,line); + continue; + } + else if (line[0] == '#') { // Comment line, do nothing + getline (fin,line); + continue; + } + else if (line[0] == '~') { // Command trigger + if (line[1] == 'V') { + if(version_read == true) + err_txt += "~VERSION INFORMATION given more than once in file "+filename+".\n"; + else { + version_read = true; + ParseVersionInformation(fin, line, err_txt); + } + } + else if (line[1] == 'W') { + if(well_read == true) + err_txt += "~WELL INFORMATION given more than once in file "+filename+".\n"; + else { + well_read = true; + ParseWellInformation(fin, line, err_txt); + } + } + else if (line[1] == 'C') { + if(curve_read == true) + err_txt += "~CURVE INFORMATION given more than once in file "+filename+".\n"; + else{ + curve_read = true; + ParseCurveInformation(fin, line, err_txt); + } + } + else if (line[1] == 'P') + ParseInformation(parameter_info_, "~PARAMETER INFORMATION", fin, line, err_txt); + else if (line[1] == 'O') + ParseInformation(other_info_, "~OTHER INFORMATION", fin, line, err_txt); + else if (line[1] == 'A') + end_of_header = true; + else { + err_txt += "Invalid keyword \'~"+NRLib::ToString(line[1])+"\' has been encountered in LAS file "+filename+".\n"; + std::vector<std::string> junk_info; + ParseInformation(junk_info, "", fin, line, err_txt); + } + } + else { + err_txt = "Unexpected end of header in file " + filename + "\n"; + end_of_header = true; + } + } + if(curve_read == false) + err_txt += "No ~CURVE INFORMATION given in LAS file "+filename+".\n"; + if(well_read == false) + err_txt += "No ~WELL INFORMATION given in LAS file "+filename+".\n"; + if(version_read == false) + err_txt += "No ~VERSION INFORMATION given in LAS file "+filename+".\n"; + } + else { + err_txt = std::string(" Cannot open file ") + filename + std::string("\n"); + } +} + + +void +LasWell::ParseInformation(std::vector<std::string> & info, + const std::string & text, + std::ifstream & fin, + std::string & line, + std::string & err_txt) +{ + if (info.size() == 0) { + bool end_of_section = false; + while ( !fin.eof() && !end_of_section && err_txt == "") { + getline (fin,line); + line = NRLib::Chomp(line); + + if (line.size() == 0 || line[0] == '#') { + continue; + } + else if (line[0] == '~') { + end_of_section = true; + continue; + } + else { + info.push_back(line); + } + } + } + else { + err_txt += "There is more than one "+text+" section present in well "+GetWellName()+".\n"; + } +} + +void +LasWell::ParseVersionInformation(std::ifstream & fin, + std::string & line, + std::string & err_txt) +{ + bool end_of_section = false; + while (!fin.eof() && !end_of_section) { + getline (fin,line); + line = NRLib::Chomp(line); + if(line.size() == 0 || line[0] == '#') { + continue; + } + else if (line[0] == '~') { + end_of_section = true; + continue; + } + else { + std::string::size_type end_pos = line.find_first_of("."); + std::string token = NRLib::Chomp(line.substr(0, end_pos)); + std::string::size_type start_pos = end_pos; + start_pos = line.find_first_of(" ",start_pos); + end_pos = line.find_first_of(":",start_pos); + if(end_pos == std::string::npos) + err_txt += "Not enough items under keyword "+token+" under ~VERSION INOFRMATION in "+GetWellName()+".\n"; + else { + std::string value = NRLib::Chomp(line.substr(start_pos,end_pos-start_pos)); + if(token == "VERS") + version_ = value; + else if(token == "WRAP") { + if(value == "NO") + wrap_ = false; + else + wrap_ = true; + } + else if(token == "DLM") { + if(value == "COMMA") + comma_delimited_ = true; + } + else + version_info_.push_back(line); + } + } + } +} + +void +LasWell::ParseWellInformation(std::ifstream & fin, + std::string & line, + std::string & err_txt) +{ + bool end_of_section = false; + while (!fin.eof() && !end_of_section) { + getline (fin,line); + line = NRLib::Chomp(line); + + if(line.size() == 0 || line[0] == '#') { + continue; + } + else if (line[0] == '~') { + end_of_section = true; + continue; + } + else { + std::string::size_type end_pos = line.find_first_of("."); + std::string token = NRLib::Chomp(line.substr(0, end_pos)); + std::string::size_type start_pos = end_pos; + start_pos = line.find_first_of(" ",start_pos); + end_pos = line.find_first_of(":",start_pos); + if(end_pos == std::string::npos) + err_txt += "Not enough items under keyword "+token+" under ~WELL INOFRMATION in "+GetWellName()+".\n"; + else { + std::string value = NRLib::Chomp(line.substr(start_pos,end_pos-start_pos)); + ParseWellToken(token, value, line, err_txt); + } + } + } +} + +void +LasWell::ParseWellToken(const std::string & token, + const std::string & value, + const std::string & line, + std::string & err_txt) +{ + if(token == "WELL") { + if(value.empty() == false) + SetWellName(value); + } + + else if(token == "STRT" || token == "STOP" || token == "STEP" || + token == "NULL" || token == "XWELL" || token == "YWELL") + { + if(value.empty() == false) { //Do not set value if there is nothing to set. Do not trust missingcode, may change later. + try { + double val = NRLib::ParseType<double>(value); + if(token == "STRT") + start_depth_ = val; + else if(token == "STOP") + stop_depth_ = val; + else if(token == "STEP") + depth_increment_ = val; + else if(token == "NULL") + SetMissing(val); + else if(token == "XWELL") + SetXPos0(val); + else if(token == "YWELL") + SetYPos0(val); + } + catch(NRLib::Exception & e) { + err_txt += std::string(e.what())+" for keyword "+token+" under ~WELL INFORMATION in well "+GetWellName(); + } + } + } + else + well_info_.push_back(line); + +} + +void +LasWell::ParseCurveInformation(std::ifstream & fin, + std::string & line, + std::string & err_txt) +{ + bool end_of_section = false; + while (!fin.eof() && !end_of_section) { + getline (fin,line); + line = NRLib::Chomp(line); + + if(line.size() == 0 || line[0] == '#') { + continue; + } + else if (line[0] == '~') { + end_of_section = true; + continue; + } + else { + std::string::size_type end_pos = line.find_first_of("."); + std::string token = NRLib::Chomp(line.substr(0, end_pos)); + std::string::size_type start_pos = end_pos+1; + end_pos = line.find_first_of(" ",start_pos); + std::string unit = NRLib::Chomp(line.substr(start_pos, end_pos-start_pos)); + start_pos = line.find_first_of(":",start_pos); + if(start_pos == std::string::npos) + err_txt += "Not enough items under keyword "+token+" under ~CURVE INOFRMATION in "+GetWellName()+".\n"; + else { + log_name_.push_back(token); + log_unit_.push_back(unit); + logUnitMap_[token] = unit; + std::string comment = NRLib::Chomp(line.substr(start_pos+1)); + log_comment_.push_back(comment); + } + } + } + if(log_unit_.size() > 0) + depth_unit_ = log_unit_[0]; +} + + +void +LasWell::ReadLogs(std::ifstream & fin, + std::string & err_txt) +{ + std::string tmp_err_txt; + std::vector<std::vector<double> > log(log_name_.size()); + size_t n_data = 2000000000; //Anything more than this will easily give indexing problems, so ok upper limit. + bool n_data_given = false; + if(IsMissing(start_depth_) == false && IsMissing(stop_depth_) == false && IsMissing(depth_increment_) == false && + stop_depth_ > start_depth_ && depth_increment_ != 0) { + n_data_given = true; + n_data = static_cast<size_t>(floor(0.5+(stop_depth_ - start_depth_)/depth_increment_))+1; + for(size_t i=0;i<log.size();i++) + log[i].resize(n_data); + } + + std::string line; + size_t n_records = 0; + size_t n_errors = 0; + std::vector<std::string> record; + while(GetRecord(fin, log.size(), record) == true && n_errors < 5 && n_records < n_data) { + n_records++; + if(record.size() != log.size()) { + n_errors++; + tmp_err_txt += "Error in well "+GetWellName()+", record "+NRLib::ToString(n_records)+"("+log_name_[0]+"="+record[0] + +"?): Wrong number of items, found "+NRLib::ToString(record.size())+" when expecting "+NRLib::ToString(log.size())+".\n"; + } + else { + for(size_t i=0;i<log.size();i++) { + if(n_data_given == false) + log[i].push_back(0); + try { + log[i][n_records-1] = NRLib::ParseType<double>(record[i]); + } + catch(Exception & e) { + tmp_err_txt += "Error in well "+GetWellName()+", record "+NRLib::ToString(n_records)+"("+log_name_[0]+"="+record[0] + +"?), item "+NRLib::ToString(i+1)+": "+std::string(e.what()); + n_errors++; + } + } + } + } + while(GetRecord(fin, log.size(), record) == true) //Find actual record count. + n_records++; + if(n_errors >= 5) //Note intentional use of err_txt below, final error. + err_txt += tmp_err_txt +"Too many log errors found in well "+GetWellName()+". Stopped processing.\n"; + else if(tmp_err_txt == "" && n_records < n_data && n_data_given == true) { //Note intentional use of err_txt below, only this error has occured. + err_txt += "Wrong number of data records found in well "+GetWellName()+", found "+NRLib::ToString(n_records) + +" while expecting "+NRLib::ToString(n_data)+".\n"; + } + else { + for(size_t i=0;i<log.size();i++) { + AddContLog(log_name_[i],log[i]); + } + } +} + + +bool +LasWell::GetRecord(std:: ifstream & fin, + size_t n_items, + std::vector<std::string> & record) const +{ + std::string line; + while(line.empty()==true && fin.eof() == false) + getline(fin,line); + if(line.empty() == true) + return(false); + + NRLib::Substitute(line, ",", " "); //Makes comma delimited space delimited. + record = NRLib::GetTokens(line); + if(wrap_ == true) { + while(record.size() < n_items && fin.eof()==false) { + getline(fin,line); + NRLib::Substitute(line, ",", " "); //Makes comma delimited space delimited. + std::vector<std::string> items = GetTokens(line); + record.insert(record.end(), items.begin(), items.end()); + } + } + return(true); +} + +void LasWell::AddLog(const std::string & name, + const std::string & units, + const std::string & comment, + const std::vector<double> & log) +{ + Well::AddContLog(name, log); + log_name_.push_back(name); + log_unit_.push_back(units); + log_comment_.push_back(comment); +} + + +int calculatePrecision(double value) +{ + double absVal = fabs(value); + if (1e-16 < absVal && absVal < 1.0e3){ + int logVal = static_cast<int>(log(absVal)); + int numDigitsAfterPoint = abs(logVal - 6); + return numDigitsAfterPoint; + } + else{ + return 3; + } +} + +void LasWell::WriteToFile(const std::string & filename, + const std::vector<std::string> & comment_header) +{ + std::ofstream file; + OpenWrite(file, filename); + + // Comment header + for (size_t i = 0; i < comment_header.size(); ++i) { + file << "# " << comment_header[i] << "\n"; + } + file << "\n"; + + // Version information + file << "~Version information\n"; + WriteLasLine(file, "VERS", "", version_, ""); + WriteLasLine(file, "WRAP", "", (wrap_ ? "YES" : "NO"), ""); + for(size_t i=0;i<version_info_.size();i++) + file << version_info_[i] << "\n"; + file << "\n"; + + file.setf(std::ios_base::fixed); + file.precision(5); + + // Well information + file << "~Well information\n"; + WriteLasLine(file, "STRT", depth_unit_, start_depth_, ""); + WriteLasLine(file, "STOP", depth_unit_, stop_depth_, ""); + WriteLasLine(file, "STEP", depth_unit_, depth_increment_, ""); + WriteLasLine(file, "NULL", "", GetContMissing(), ""); + for(size_t i=0;i<well_info_.size();i++) + file << well_info_[i] << "\n"; + file << "\n"; + + if (GetNContLog() == 0) { + // No log data in file. + return; + } + + //Parameter information. Only what is read from file; may add Set-functions. + file << "~Parameter information\n"; + for(size_t i=0;i<parameter_info_.size();i++) + file << parameter_info_[i] << "\n"; + file << "\n"; + + + // Curve information + // LAS only supports continuous logs... + + file << "~Curve information\n"; + for (size_t i = 0; i < GetNContLog(); ++i) { + WriteLasLine(file, log_name_[i], log_unit_[i], "", log_comment_[i]); + } + file << "\n"; + + // Data section + file << "~Ascii\n"; + + std::vector<const std::vector<double> *> logs(GetNContLog()); + for (size_t i = 0; i < GetNContLog(); ++i) { + logs[i] = &(GetContLog(log_name_[i])); + } + + // We don't support wrapped output yet. + assert(wrap_ == false); + + file.precision(3); + for (size_t i = 0; i < logs[0]->size(); ++i) { + for (size_t j = 0; j < logs.size(); ++j) { + // Calculate a sensible precision. LAS does not support scientific notation + double value = (*logs[j])[i]; + int numDigitsAfterPoint = calculatePrecision(value); + + file.precision(numDigitsAfterPoint); + file << value << " "; + } + file << "\n"; + } +} + +void LasWell::WriteLasLine(std::ofstream & file, + const std::string & mnemonic, + const std::string & units, + const std::string & data, + const std::string & description) +{ + file << mnemonic << " ." << units << " " << data << " : " << description << "\n"; +} + + +void LasWell::WriteLasLine(std::ofstream & file, + const std::string & mnemonic, + const std::string & units, + double data, + const std::string & description) +{ + file << mnemonic << " ." << units << " " << data << " : " << description << "\n"; +} + +void LasWell::setDepthUnit(const std::string& depthUnit) +{ + depth_unit_ = depthUnit; +}; + +std::string LasWell::depthUnit() const +{ + return depth_unit_; +}; + +std::string LasWell::unitName(const std::string& logName) const +{ + std::map<std::string, std::string >::const_iterator it = logUnitMap_.find(logName); + if (it != logUnitMap_.end()) + { + return it->second; + } + + return ""; +}; + +void NRLib::LasWell::setVersionInfo(const std::string& versionInfo) +{ + version_ = versionInfo; +} + +void NRLib::LasWell::setStartDepth(double startDepth) +{ + start_depth_ = startDepth; +} + +void NRLib::LasWell::setStopDepth(double stopDepth) +{ + stop_depth_ = stopDepth; +} + +void NRLib::LasWell::addWellInfo(const std::string& parameter, const std::string& value) +{ + // Example of line formatting taken from the documentation + // WELL. aaaaaaaaaaaaaaaaaaaaa : WELL + // + + std::string info = parameter; + info += " . "; + info += value; + info += " :"; + + well_info_.push_back(info); +} diff --git a/ThirdParty/NRLib/nrlib/well/laswell.hpp b/ThirdParty/NRLib/nrlib/well/laswell.hpp new file mode 100644 index 0000000000..6ad1f4d915 --- /dev/null +++ b/ThirdParty/NRLib/nrlib/well/laswell.hpp @@ -0,0 +1,150 @@ +// $Id: laswell.hpp 1244 2014-02-24 15:57:16Z hauge $ + +// Copyright (c) 2011, Norwegian Computing Center +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// • Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// • Redistributions in binary form must reproduce the above copyright notice, this list of +// conditions and the following disclaimer in the documentation and/or other materials +// provided with the distribution. +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT +// SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef NRLIB_WELL_LASWELL_HPP +#define NRLIB_WELL_LASWELL_HPP + +#include <string> +#include <vector> + +#include "well.hpp" + +namespace NRLib { + +/// Support for the LAS well format. +/// Currently mainly LAS 2.0 is supported. Some LAS 3.0 support. +/// \sa{http://www.cwls.org/las_info.php} +class LasWell : public Well { +public: + enum DepthType { + Depth, + Time + }; + + // Default constructor added to be able to export from scratch + LasWell(); + + /// Constructor with relevant parameters. + LasWell(const std::string & filename); + + void AddLog(const std::string & name, + const std::string & units, + const std::string & comment, + const std::vector<double> & log); + + void WriteToFile(const std::string & filename, + const std::vector<std::string> & comment_header); + + void setDepthUnit(const std::string& depthUnit); + std::string depthUnit() const; + + std::string unitName(const std::string& logName) const; + + void setVersionInfo(const std::string& logName); + void setStartDepth(double startDepth); + void setStopDepth(double stopDepth); + + void addWellInfo(const std::string& parameter, const std::string& value); + +private: + void ReadHeader(const std::string & filename, + std::ifstream & fin, + std::string & err_txt); + + void ParseInformation(std::vector<std::string> & info, + const std::string & text, + std::ifstream & fin, + std::string & line, + std::string & err_txt); + + void ParseVersionInformation(std::ifstream & fin, + std::string & line, + std::string & err_txt); + + void ParseWellInformation(std::ifstream & fin, + std::string & line, + std::string & err_txt); + + void ParseWellToken(const std::string & token, + const std::string & value, + const std::string & line, + std::string & err_txt); + + void ParseCurveInformation(std::ifstream & fin, + std::string & line, + std::string & err_txt); + + void ReadLogs(std::ifstream & fin, + std::string & err_txt); + + bool GetRecord(std:: ifstream & fin, + size_t n_items, + std::vector<std::string> & record) const; + + void WriteLasLine(std::ofstream & file, + const std::string & mnemonic, + const std::string & units, + const std::string & data, + const std::string & description); + + void WriteLasLine(std::ofstream & file, + const std::string & mnemonic, + const std::string & units, + double data, + const std::string & description); + + /// Version ID. Possible version ID's include 1.2, 2.0 and 3.0. + std::string version_; + + /// True if wrap around mode is used. If wrap mode is used the depth value will be + /// on its own line and all lines of data will be no longer than 80 characters (including CR+LF). + bool wrap_; + + ///True if comma delimited file. + bool comma_delimited_; + + /// Possible depth units: + /// For logs in depth: M (meter), F (feet) or FT (feet) + /// For logs in time: S (seconds), MS (milliseconds), etc. + std::string depth_unit_; + + /// Depth of first depth sample. + double start_depth_; + /// Depth of last depth sample. + double stop_depth_; + /// Depth increment. 0 if the increment is not constant. + double depth_increment_; + + std::vector<std::string> log_name_; //Needed to preserve log order, may be important in LAS-files. + std::vector<std::string> log_unit_; + std::vector<std::string> log_comment_; + + std::vector<std::string> version_info_; //Unused version keywords, only read from file and rewritten. + std::vector<std::string> well_info_; //Unused well keywords, only read from file and rewritten. + std::vector<std::string> parameter_info_; //Not used, only read from file and rewritten. + std::vector<std::string> other_info_; //Not used, only read from file and rewritten. + + std::map<std::string, std::string> logUnitMap_; // Log name/unit map +}; + +} + +#endif // NRLIB_WELL_LASWELL_HPP diff --git a/ThirdParty/NRLib/nrlib/well/module.mk b/ThirdParty/NRLib/nrlib/well/module.mk new file mode 100644 index 0000000000..fb9332dc34 --- /dev/null +++ b/ThirdParty/NRLib/nrlib/well/module.mk @@ -0,0 +1,5 @@ +SRC += $(NRLIB_BASE_DIR)well/norsarwell.cpp \ + $(NRLIB_BASE_DIR)well/laswell.cpp \ + $(NRLIB_BASE_DIR)well/rmswell.cpp \ + $(NRLIB_BASE_DIR)well/well.cpp \ + $(NRLIB_BASE_DIR)well/welloperations.cpp diff --git a/ThirdParty/NRLib/nrlib/well/norsarwell.cpp b/ThirdParty/NRLib/nrlib/well/norsarwell.cpp new file mode 100644 index 0000000000..f053730d1f --- /dev/null +++ b/ThirdParty/NRLib/nrlib/well/norsarwell.cpp @@ -0,0 +1,339 @@ +// $Id: norsarwell.cpp 882 2011-09-23 13:10:16Z perroe $ + +// Copyright (c) 2011, Norwegian Computing Center +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// • Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// • Redistributions in binary form must reproduce the above copyright notice, this list of +// conditions and the following disclaimer in the documentation and/or other materials +// provided with the distribution. +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT +// SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include <fstream> +#include <iostream> +#include <string> +#include <stdlib.h> +#include <assert.h> +#include <math.h> +#include "norsarwell.hpp" +#include "../iotools/stringtools.hpp" +#include "../iotools/fileio.hpp" +//#include "src/definitions.h" + +using namespace NRLib; + +NorsarWell::NorsarWell(const std::string & filename) + : header_units_(8) +{ + std::ifstream file; + NRLib::OpenRead(file, filename); + std::string token; + getline(file, token); + if(token.find("[Version information]",0) > 0) + throw(FileFormatError("Found '"+token+"' instead of '[Version information]' on first line in file "+filename+".")); + + int line = 2; + ReadNext<std::string>(file, line); + version_ = ReadNext<std::string>(file, line); + if(version_ != "1000") + throw(FileFormatError("Found '"+version_+"' as version number in file "+filename+". Can only read version 1000.")); + + ReadNext<std::string>(file, line); + format_ = ReadNext<std::string>(file, line); + if(format_ != "ASCII") + throw(FileFormatError("Found '"+format_+"' as format in file "+filename+". Can only read ASCII format.")); + + ReadNext<std::string>(file, line); + ReadNext<std::string>(file, line); //Together with previous, reads '[Well information]' + + ReadNext<std::string>(file, line); //'MDMIN' + header_units_[0] = ReadNext<std::string>(file, line); //unit for MDMIN + md_min_ = ReadNext<double>(file, line); + DiscardRestOfLine(file, line, false); + + ReadNext<std::string>(file, line); //'MDMAX' + header_units_[1] = ReadNext<std::string>(file, line); //unit for MDMAX + md_max_ = ReadNext<double>(file, line); + DiscardRestOfLine(file, line, false); + + ReadNext<std::string>(file, line); //'MDMINSTEP' + header_units_[2] = ReadNext<std::string>(file, line); //unit for MDMINSTEP + md_min_step_ = ReadNext<double>(file, line); + DiscardRestOfLine(file, line, false); + + ReadNext<std::string>(file, line); //'MDMAXSTEP' + header_units_[3] = ReadNext<std::string>(file, line); //unit for MDMAXSTEP + md_max_step_ = ReadNext<double>(file, line); + DiscardRestOfLine(file, line, false); + + ReadNext<std::string>(file, line); //'UTMX' + header_units_[4] = ReadNext<std::string>(file, line); //unit for UTMX + xpos0_ = ReadNext<double>(file, line); + DiscardRestOfLine(file, line, false); + + ReadNext<std::string>(file, line); //'UTMY' + header_units_[5] = ReadNext<std::string>(file, line); //unit for UTMY + ypos0_ = ReadNext<double>(file, line); + DiscardRestOfLine(file, line, false); + + ReadNext<std::string>(file, line); //'EKB' + header_units_[6] = ReadNext<std::string>(file, line); //unit for EKB + ekb_ = ReadNext<double>(file, line); + DiscardRestOfLine(file, line, false); + + ReadNext<std::string>(file, line); //'UNDEFVAL' + header_units_[7] = ReadNext<std::string>(file, line); //unit for UNDEFVAL + SetMissing(ReadNext<double>(file, line)); + DiscardRestOfLine(file, line, false); + + ReadNext<std::string>(file, line); + ReadNext<std::string>(file, line); + ReadNext<std::string>(file, line); + ReadNext<std::string>(file, line); //Together with previous, reads '[Well track data information]' + + ReadNext<std::string>(file, line); //'NUMMD' + int n_track = ReadNext<int>(file,line); + DiscardRestOfLine(file, line, false); + + ReadNext<std::string>(file, line); //'NUMPAR' + int n_track_par = ReadNext<int>(file,line); + DiscardRestOfLine(file, line, false); + + typedef std::pair<std::string,std::string> unitpair; + + int track_MD = -1; + std::string name; + std::vector<std::string> log_name; + for(int i=0; i<n_track_par;i++) { + name = ReadNext<std::string>(file, line); //parameter + log_name.push_back(NRLib::Uppercase(name)); + if(name == "MD") + track_MD = i; + token = ReadNext<std::string>(file, line); //unit + units_.insert(unitpair(name,token)); + + DiscardRestOfLine(file, line, false); + } + if(track_MD < 0) + throw(FileFormatError("Could not find MD for track file in file '"+filename+"'.")); + + std::string track_filename = ReplaceExtension(filename, ".nwt"); + std::vector<std::vector<double> > track_logs = ReadLogs(track_filename, n_track_par, n_track,1); + + ReadNext<std::string>(file, line); + ReadNext<std::string>(file, line); + ReadNext<std::string>(file, line); + ReadNext<std::string>(file, line); //Together with previous, reads '[Well log data information]' + + std::string path = GetPath(filename); + std::string log_filename; + std::string log_section_name; + std::vector<std::vector<double> > log_logs; + int n_log, n_log_par, log_MD; + while(CheckEndOfFile(file) == false) { + ReadNext<std::string>(file, line); + log_section_name = ReadNext<std::string>(file, line); + ReadNext<std::string>(file, line); + log_filename = ReadNext<std::string>(file, line); + + ReadNext<std::string>(file, line); //'NUMMD' + n_log = ReadNext<int>(file,line); + DiscardRestOfLine(file, line, false); + + ReadNext<std::string>(file, line); //'NUMPAR' + n_log_par = ReadNext<int>(file,line); + DiscardRestOfLine(file, line, false); + + log_MD = -1; + for(int i=0; i<n_log_par;i++) { + name = ReadNext<std::string>(file, line); //parameter + if(name == "MD") + log_MD = i; + else + log_name.push_back(NRLib::Uppercase(name)); + token = ReadNext<std::string>(file, line); //unit + if(log_MD != i) + units_.insert(unitpair(name,token)); + DiscardRestOfLine(file, line, false); + } + if(log_MD < 0) + throw(FileFormatError("Could not find MD for logs '"+log_section_name+"' in file '"+filename+"'.")); + + log_filename = PrependDir(path, log_filename); + log_logs = ReadLogs(log_filename, n_log_par, n_log, 2); + + track_logs = MergeLogs(track_logs, track_MD, log_logs, log_MD); + } + + file.close(); + + for(int i=0;i<static_cast<int>(track_logs.size());i++) + AddContLog(log_name[i], track_logs[i]); + + // find n_data including WELLMISSING values + int n_data = static_cast<int>(GetContLog(log_name[0]).size()); + SetNumberOfData(n_data); + SetXPos0(xpos0_); + SetYPos0(ypos0_); +} + + +std::vector<std::vector<double> > +NorsarWell::ReadLogs(const std::string & filename, int n_col, int n_row, int skip_lines) +{ + std::ifstream file; + OpenRead(file, filename); + std::vector<std::vector<double> > result(n_col, std::vector<double>(n_row, 0)); + + int line = 1; + std::string token; + for(int i=0;i<skip_lines;i++) + DiscardRestOfLine(file, line, false); + + int baseline = line; + int i,j; //For use in error message. + + //int legal_data = 0; + + try { + for(i=0;i<n_row;i++) { + for(j=0;j<n_col;j++) + { + result[j][i] = ReadNext<double>(file, line); + if(line-i > baseline) { + std::string error = "Too few elements on line "+NRLib::ToString(line-1)+" in file "+filename+": Expected to read "+NRLib::ToString(n_col)+" elements, found only "+NRLib::ToString(j)+"."; + throw (NRLib::IOError(error)); + } + else if(line-i < baseline) { + while(line-i < baseline) { + j++; + ReadNext<double>(file, line); + } + std::string error = "Too many elements on line "+NRLib::ToString(line-1)+" in file "+filename+": Expected to read "+NRLib::ToString(n_col)+" elements, found "+NRLib::ToString(n_col+j)+"."; + throw (NRLib::IOError(error)); + } + } + //if(result[0][i] != WELLMISSING) //H [0] First? + // legal_data++; + } + } + catch (NRLib::EndOfFile) { + std::string error = "Unexpected end of file "+filename+": Expected to read "+NRLib::ToString(n_row*n_col)+"elements, found only "+NRLib::ToString(i*n_col+j)+"."; + throw (NRLib::IOError(error)); + } + + //this->SetNumberOfLegalData(legal_data); + + return(result); +} + + +std::vector<std::vector<double> > +NorsarWell::MergeLogs(const std::vector<std::vector<double> > & track_logs, int track_MD, + const std::vector<std::vector<double> > & log_logs, int log_MD) +{ + int nt = static_cast<int>(track_logs[0].size()); + int nl = static_cast<int>(log_logs[0].size()); + int n = nt; + if(nl > nt) + n = nl; //Minimum number of rows. + int nc = static_cast<int>(track_logs.size() + log_logs.size()) - 1; + std::vector<std::vector<double> > result(nc); + for(int i = 0; i < nc; i++) { + result[i].reserve(n); + } + + double depth_track, depth_log; + int ntl = static_cast<int>(track_logs.size()); + int nll = static_cast<int>(log_logs.size()); + int it = 0; //track counter + int il = 0; //log counter + + while(it < nt && il < nl) { + depth_track = track_logs[track_MD][it]; + depth_log = log_logs[log_MD][il]; + if(depth_track == depth_log) { //Lucky. + for(int i=0;i<ntl;i++) + result[i].push_back(track_logs[i][it]); + int mdp = 0; //Indicate whether md log is passed. This one is discarded, so index adjustment needed. + for(int i=0;i<nll;i++) { + if(i != log_MD) + result[i-mdp+ntl].push_back(log_logs[i][il]); + else + mdp = 1; + } + it++; + il++; + } + else if(depth_track < depth_log) { + for(int i=0;i<ntl;i++) + result[i].push_back(track_logs[i][it]); + for(int i=0;i<nll-1;i++) + result[i+ntl].push_back(GetContMissing()); + it++; + } + else { + for(int i=0;i<ntl;i++) { + if(i != track_MD) + result[i].push_back(GetContMissing()); + else + result[i].push_back(depth_log); //Always log MD, must take form log instead of track here. + } + int mdp = 0; //Indicate whether md log is passed. This one is discarded, so index adjustment needed. + for(int i=0;i<nll;i++) { + if(i != log_MD) + result[i-mdp+ntl].push_back(log_logs[i][il]); + else + mdp = 1; + } + il++; + } + } + + for(;it<nt;it++) { + for(int i=0;i<ntl;i++) + result[i].push_back(track_logs[i][it]); + for(int i=0;i<nll-1;i++) + result[i+ntl].push_back(GetContMissing()); + } + + for(;il<nl;il++) { + for(int i=0;i<ntl;i++) { + if(i != track_MD) + result[i].push_back(GetContMissing()); + else + result[i].push_back(log_logs[log_MD][il]); //Always log MD, must take form log instead of track here. + } + int mdp = 0; //Indicate whether md log is passed. This one is discarded, so index adjustment needed. + for(int i=0;i<nll;i++) { + if(i != log_MD) + result[i-mdp+ntl].push_back(log_logs[i][il]); + else + mdp = 1; + } + il++; + } + + return(result); +} + + +std::string +NorsarWell::GetLogUnit(const std::string & name) +{ + std::map<std::string,std::string>::iterator item = units_.find(name); + if(item == units_.end()) + return(""); + else + return(item->second); +} diff --git a/ThirdParty/NRLib/nrlib/well/norsarwell.hpp b/ThirdParty/NRLib/nrlib/well/norsarwell.hpp new file mode 100644 index 0000000000..56da0c2f65 --- /dev/null +++ b/ThirdParty/NRLib/nrlib/well/norsarwell.hpp @@ -0,0 +1,85 @@ +// $Id: norsarwell.hpp 883 2011-09-26 09:17:05Z perroe $ + +// Copyright (c) 2011, Norwegian Computing Center +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// • Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// • Redistributions in binary form must reproduce the above copyright notice, this list of +// conditions and the following disclaimer in the documentation and/or other materials +// provided with the distribution. +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT +// SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef NRLIB_NORSARWELL_HPP +#define NRLIB_NORSARWELL_HPP + +#include <vector> +#include <sstream> +#include <map> + +#include "../exception/exception.hpp" +#include "well.hpp" + + +namespace NRLib { + class NorsarWell : public Well + { + public: + /// Constructor + /// \param[in] filename Name of well file + NorsarWell(const std::string & filename); + + ///NBNB add when convenient + /* + /// Copy constructor + NorsarWell(Well *wellobj); + /// Write well to file + void WriteWell(const std::string& filename); + */ + + double GetXPosOrigin() {return(xpos0_);} + double GetYPosOrigin() {return(ypos0_);} + + std::string GetLogUnit(const std::string & name); + + private: + /// Version (currently only reading 1000) + std::string version_; + /// Format (currently only reading ascii) + std::string format_; + /// Minimum measured depth + double md_min_; + /// Maximum measured depth + double md_max_; + /// Minimum measured depth step + double md_min_step_; + /// Maximum measured depth step + double md_max_step_; + /// Original position + double xpos0_, ypos0_; + /// Kelly bushing elevation + double ekb_; + /// Units for the above, in order + std::vector<std::string> header_units_; + + /// Names and units of logs + std::map<std::string,std::string> units_; + + std::vector<std::vector<double> > ReadLogs(const std::string & filename, int n_col, int n_row, int skip_lines); + std::vector<std::vector<double> > MergeLogs(const std::vector<std::vector<double> > & track_logs, int track_MD, + const std::vector<std::vector<double> > & log_logs, int log_MD); + + }; + + +} +#endif diff --git a/ThirdParty/NRLib/nrlib/well/rmswell.cpp b/ThirdParty/NRLib/nrlib/well/rmswell.cpp new file mode 100644 index 0000000000..4046dd58f7 --- /dev/null +++ b/ThirdParty/NRLib/nrlib/well/rmswell.cpp @@ -0,0 +1,288 @@ +// $Id: rmswell.cpp 1194 2013-08-19 08:24:58Z anner $ + +// Copyright (c) 2011, Norwegian Computing Center +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// • Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// • Redistributions in binary form must reproduce the above copyright notice, this list of +// conditions and the following disclaimer in the documentation and/or other materials +// provided with the distribution. +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT +// SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include <fstream> +#include <sstream> +#include <string> +#include <iostream> +#include <stdio.h> +#include <stdlib.h> +#include <assert.h> +#include <math.h> +#include "rmswell.hpp" +#include "../iotools/stringtools.hpp" +#include "../iotools/fileio.hpp" + +using namespace NRLib; + + +RMSWell::RMSWell(const std::string& filename) +{ + std::ifstream file; + OpenRead(file, filename); + + size_t nlog; + std::string dummy; + getline(file,line1_); + getline(file,line2_); + int line = 0; + std::string token; + std::string wellName = ReadNext<std::string>(file, line); + SetWellName(wellName); + xpos0_ = ReadNext<double>(file, line); + ypos0_ = ReadNext<double>(file, line); // read wellname and positions + // getline(file,dummy);// Line may contain a dummy number + //-----line shift + DiscardRestOfLine(file, line, false); + nlog = ReadNext<int>(file, line); // read number of logs + DiscardRestOfLine(file, line, false); + lognames_.resize(nlog+3); + lognames_[0] = "X"; + lognames_[1] = "Y"; + lognames_[2] = "Z"; + + int ident; + std::string identstr; + size_t j(0); + size_t k(0); + isDiscrete_.resize(nlog+3); + unit_.resize(nlog); + scale_.resize(nlog); + isDiscrete_[0] = false; + isDiscrete_[1] = false; + isDiscrete_[2] = false; + for (size_t i = 0; i < nlog; i++) { + getline(file,dummy); + std::istringstream ist(dummy); + lognames_[i+3] = NRLib::Uppercase(ReadNext<std::string>(ist, line)); + + //token = ReadNext<std::string>(ist, line); //H Error if line only containts log-name (test_case 19). + ReadNextToken(ist, token, line); + + if (token != "") { + if (token=="DISC") { // discrete log + isDiscrete_[i+3] = true; + std::map<int, std::string> disc; + while(ReadNextToken(ist,token,line)) { + ident = ParseType<int>(token); + identstr = ReadNext<std::string>(ist, line); + disc.insert(std::pair<int, std::string> (ident, identstr)); + } + discnames_[lognames_[i+3]] = disc; + j++; + } + else { + isDiscrete_[i+3] = false; + unit_[k] = token; + scale_[k] = ReadNext<std::string>(ist, line); + k++; + } + } + else { + isDiscrete_[i+3] = false; + k++; + } + } + + size_t ndisc(j); + size_t ncont = nlog + 3 - ndisc; + std::vector<std::vector<int> > disclogs(ndisc); + std::vector<std::vector<double> > contlogs(ncont); + + int count = 0; + + while(NRLib::CheckEndOfFile(file)==false && getline(file,dummy)) { + count ++; + std::istringstream ist(dummy); + contlogs[0].push_back(ReadNext<double>(ist, line)); //x + contlogs[1].push_back(ReadNext<double>(ist, line)); //y + contlogs[2].push_back(ReadNext<double>(ist, line)); //z + + j = 0; + k = 3; + for (size_t i = 0; i < nlog; i++) { + if (isDiscrete_[i+3]) { + double dummy = ReadNext<double>(ist, line); //Double because of a problem with ReadNext<int> and facies on the form -9.9900000e+002 + if(IsMissing(dummy) == false) + disclogs[j].push_back(static_cast<int>(dummy)); + else + disclogs[j].push_back(GetIntMissing()); + + j++; + } + else { + contlogs[k].push_back(ReadNext<double>(ist, line)); + k++; + } + } + } + + AddContLog(lognames_[0], contlogs[0]); + AddContLog(lognames_[1], contlogs[1]); + AddContLog(lognames_[2], contlogs[2]); + j = 0; + k = 3; + for (size_t i = 0; i < nlog; i++) { + if (isDiscrete_[i+3]) { + AddDiscLog(lognames_[i+3], disclogs[j]); + j++; + } + else { + AddContLog(lognames_[i+3], contlogs[k]); + k++; + } + } + + // Find n_data including WELLMISSING values + int n_data = static_cast<int>(GetContLog(lognames_[0]).size()); + + this->SetNumberOfData(n_data); + SetXPos0(xpos0_); + SetYPos0(ypos0_); +} + + +RMSWell::RMSWell(const Well& wellobj) + : Well(wellobj) +{ + xpos0_ = GetContValue(0, "x"); + ypos0_ = GetContValue(0, "y"); + line1_ = "1.0"; + line2_ = "Undefined"; + size_t nlog = wellobj.GetNlog(); + lognames_.resize(nlog + 3); + lognames_[0] = "x"; + lognames_[1] = "y"; + lognames_[2] = "z"; + isDiscrete_.resize(nlog + 3); + isDiscrete_[0] = false; + isDiscrete_[1] = false; + isDiscrete_[2] = false; + size_t i = 0; + size_t k = 0; + + typedef std::map<std::string, std::vector<int> >::const_iterator CI; + std::map<std::string,std::vector<int> > disclog = wellobj.GetDiscLog(); + for (CI p = disclog.begin(); p != disclog.end(); ++p) { + lognames_[i+3] = p->first; + isDiscrete_[i+3] = true; + i++; + } + typedef std::map<std::string, std::vector<double> >::const_iterator CID; + std::map<std::string,std::vector<double> > contlog = wellobj.GetContLog(); + for (CID p = contlog.begin(); p != contlog.end(); ++p) { + if (p->first != "x" && p->first != "y" && p->first != "z") { + lognames_[i+3] = p->first; + isDiscrete_[i+3] = false; + i++; + k++; + } + } + + unit_.resize(k); + scale_.resize(k); + for (i = 0; i < k; i++) { + unit_[i] = "unit1"; + scale_[i] ="scale1"; + } + + size_t ndisc = nlog - k - 3; + std::vector<std::vector<int> > discvalues(ndisc); + i = 0; + size_t j; + size_t kk = 0; + bool found = false; + for (CI p = disclog.begin(); p != disclog.end(); ++p) { + while(wellobj.IsMissing((p->second)[kk])) + kk++; + discvalues[i].push_back((p->second)[kk]); + + for (j = kk + 1; j < p->second.size(); j++) { + for (k = 0; k < discvalues[i].size(); k++) + if ((p->second)[j] == discvalues[i][k]) + found = true; + if (found == false && (!wellobj.IsMissing((p->second)[j]))) + discvalues[i].push_back((p->second)[j]); + found = false; + } + } + ////Frode NB: Må se nøyere på dette. + typedef std::pair<int, std::string> pp; + std::string identstr; + for (CI p = disclog.begin(); p !=disclog.end(); ++p) { + std::string disc_name = p->first; + for (j = 0; j < p->second.size(); j++) { + std::string identstr = ToString(p->second[j]); + discnames_[disc_name].insert(pp(p->second[j], identstr)); + } + } +} + +const std::map<int, std::string> +RMSWell::GetDiscNames(const std::string& log_name) const +{ + return (discnames_.find(log_name)->second); +} + +void RMSWell::WriteToFile(const std::string& filename) +{ + std::ofstream file; + OpenWrite(file, filename, std::ios::out); + + file << line1_ << "\n" + << line2_ << "\n" + << std::setprecision(8) + << GetWellName() << " " << xpos0_ <<" " << ypos0_ << "\n" + << GetNlog() - 3 << "\n"; + + size_t k = 0; + std::map<std::string, std::map<int, std::string> >::iterator iter = discnames_.begin(); + typedef std::map<int, std::string>::const_iterator ci; + for (size_t i = 0; i < GetNlog(); i++) { + if (lognames_[i] != "x" && lognames_[i] != "y" && lognames_[i] != "z") { + file<< lognames_[i] << " "; + iter = discnames_.find(lognames_[i]); + if (isDiscrete_[i]==true) { + file << "DISC" << " "; + for (ci p = iter->second.begin(); p !=iter->second.end();++p) + file << p->first << " " << p->second << " "; + file << "\n"; + // ++iter; + } + else { + file<< unit_[k] << " " << scale_[k] <<"\n"; + k++; + } + } + } + file.precision(8); + size_t n = GetContLogLength(lognames_[0]); + for (size_t i = 0; i < n; i++) { + for (size_t j = 0; j < GetNlog(); j++) { + if (isDiscrete_[j]==true) + file << GetDiscValue(i, lognames_[j]) << " "; + else + file << GetContValue(i, lognames_[j]) << " "; + } + file << "\n"; + } + file.close(); +} diff --git a/ThirdParty/NRLib/nrlib/well/rmswell.hpp b/ThirdParty/NRLib/nrlib/well/rmswell.hpp new file mode 100644 index 0000000000..a29a58894b --- /dev/null +++ b/ThirdParty/NRLib/nrlib/well/rmswell.hpp @@ -0,0 +1,71 @@ +// $Id: rmswell.hpp 1068 2012-09-18 11:21:53Z perroe $ + +// Copyright (c) 2011, Norwegian Computing Center +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// • Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// • Redistributions in binary form must reproduce the above copyright notice, this list of +// conditions and the following disclaimer in the documentation and/or other materials +// provided with the distribution. +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT +// SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef NRLIB_RMSWELL_HPP +#define NRLIB_RMSWELL_HPP + +#include <vector> +#include <sstream> +#include <map> + +#include "../exception/exception.hpp" +#include "well.hpp" + + +namespace NRLib { + class RMSWell : public Well + { + public: + /// Constructor + /// \param[in] filename Name of well file + RMSWell(const std::string& filename); + /// Construct RMSWell from general well. + RMSWell(const Well& wellobj); + /// Get the discnames for discrete log with index + const std::map<int, std::string> GetDiscNames(const std::string& log_name) const; + /// Write well to file + void WriteToFile(const std::string& filename); + + //protected: + //void SetNumberOfData(int n_data) { Well::SetNumberOfData(n_data) ;} + + private: + /// Names for discrete logs + std::map<std::string, std::map<int, std::string> > discnames_; + double xpos0_, ypos0_; + /// First line of RMSwell file + std::string line1_; + /// Second line of RMSwell file + std::string line2_; + /// Name of logs + std::vector<std::string> lognames_; + /// Vector telling which logs are discrete + std::vector<bool> isDiscrete_; + /// Units for continuous logs + std::vector<std::string> unit_; + /// Scale for continuous logs + std::vector<std::string> scale_; + + }; + + +} +#endif diff --git a/ThirdParty/NRLib/nrlib/well/well.cpp b/ThirdParty/NRLib/nrlib/well/well.cpp new file mode 100644 index 0000000000..2ac4c98e17 --- /dev/null +++ b/ThirdParty/NRLib/nrlib/well/well.cpp @@ -0,0 +1,338 @@ +// $Id: well.cpp 882 2011-09-23 13:10:16Z perroe $ + +// Copyright (c) 2011, Norwegian Computing Center +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// • Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// • Redistributions in binary form must reproduce the above copyright notice, this list of +// conditions and the following disclaimer in the documentation and/or other materials +// provided with the distribution. +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT +// SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include <cassert> +#include <fstream> +#include <string> + +#include "well.hpp" +#include "norsarwell.hpp" +#include "laswell.hpp" +#include "rmswell.hpp" +#include "../iotools/stringtools.hpp" + +#include "nrlib/iotools/logkit.hpp" +#include "nrlib/iotools/stringtools.hpp" +#include "nrlib/surface/surface.hpp" +//#include "src/definitions.h" + +using namespace NRLib; + +Well::Well() +{ + well_rmissing_ = -999.0; + well_imissing_ = -999; +} + + +Well::Well(const std::string & name, + double rmissing, + int imissing) +{ + well_name_ = name; + well_rmissing_ = rmissing; + well_imissing_ = imissing; +} + + +Well::Well(const std::map<std::string,std::vector<double> > & cont_log, + const std::map<std::string,std::vector<int> > & disc_log, + const std::string & well_name) +{ + cont_log_ = cont_log; + disc_log_ = disc_log; + well_name_ = well_name; + well_rmissing_ = -999.0; + well_imissing_ = -999; +} + +Well::~Well() +{ +} + +Well * +Well::ReadWell(const std::string & file_name, + int & well_format) +{ + Well * well; + if(well_format == NORSAR || file_name.find(".nwh",0) != std::string::npos) { + well = new NorsarWell(file_name); + std::string name = NRLib::RemovePath(file_name); + well->SetWellName(NRLib::ReplaceExtension(name, "")); + well_format = NORSAR; + return(well); + } + if(well_format == LAS || file_name.find(".las",0) != std::string::npos) { + well = new LasWell(file_name); + well_format = LAS; + } + else { + well = new RMSWell(file_name); + well_format = RMS; + } + return(well); +} + +void +Well::AddContLog(const std::string& name, const std::vector<double>& log) +{ + cont_log_[name] = log; +} + +void +Well::AddContLogSeismicResolution(const std::string& name, const std::vector<double>& log) +{ + cont_log_seismic_resolution_[name] = log; +} + +void +Well::AddContLogBackgroundResolution(const std::string& name, const std::vector<double>& log) +{ + cont_log_background_resolution_[name] = log; +} + + +bool Well::HasDiscLog(const std::string& name) const{ + std::map<std::string, std::vector<int> >::const_iterator it = disc_log_.find(name); + if(it != disc_log_.end()){ + return true; + } + else{ + return false; + } +} + +bool +Well::HasContLog(const std::string& name) const +{ + //std::map<std::string, std::vector<double> >::const_iterator item = cont_log_.find(name); + if(cont_log_.find(name) != cont_log_.end()) + return true; + else + return false; +} + + +std::vector<double>& +Well::GetContLog(const std::string& name) +{ + std::map<std::string, std::vector<double> >::iterator item = cont_log_.find(name); + assert(item != cont_log_.end()); + return item->second; +} + +std::vector<double>& +Well::GetContLogSeismicResolution(const std::string& name) +{ + std::map<std::string, std::vector<double> >::iterator item = cont_log_seismic_resolution_.find(name); + assert(item != cont_log_.end()); + return item->second; +} + +std::vector<double>& +Well::GetContLogBackgroundResolution(const std::string& name) +{ + std::map<std::string, std::vector<double> >::iterator item = cont_log_background_resolution_.find(name); + assert(item != cont_log_.end()); + return item->second; +} + + +const std::vector<double>& +Well::GetContLog(const std::string& name) const +{ + std::map<std::string, std::vector<double> >::const_iterator item = cont_log_.find(name); + assert(item != cont_log_.end()); + return item->second; +} + +const std::vector<double>& +Well::GetContLogSeismicResolution(const std::string& name) const +{ + std::map<std::string, std::vector<double> >::const_iterator item = cont_log_seismic_resolution_.find(name); + assert(item != cont_log_seismic_resolution_.end()); + return item->second; +} + +const std::vector<double>& +Well::GetContLogBackgroundResolution(const std::string& name) const +{ + std::map<std::string, std::vector<double> >::const_iterator item = cont_log_background_resolution_.find(name); + assert(item != cont_log_background_resolution_.end()); + return item->second; +} + + +void +Well::RemoveContLog(const std::string& name) +{ + cont_log_.erase(name); +} + + +void +Well::AddDiscLog(const std::string& name, const std::vector<int>& log) +{ + disc_log_[name] = log; +} + + +std::vector<int> & +Well::GetDiscLog(const std::string& name) +{ + std::map<std::string, std::vector<int> >::iterator item = disc_log_.find(name); + assert(item != disc_log_.end()); + return item->second; +} + + +const std::vector<int> & +Well::GetDiscLog(const std::string& name) const +{ + std::map<std::string, std::vector<int> >::const_iterator item = disc_log_.find(name); + assert(item != disc_log_.end()); + return item->second; +} + + +void +Well::RemoveDiscLog(const std::string& name) +{ + disc_log_.erase(name); +} + +void +Well::MakeLogsUppercase() +{ + std::map<std::string, std::vector<int> > d_log; + std::map<std::string, std::vector<int> >::iterator d_item = disc_log_.begin(); + for(;d_item != disc_log_.end(); ++d_item) { + std::string u_name = NRLib::Uppercase(d_item->first); + d_log[u_name] = d_item->second; + } + disc_log_ = d_log; + + std::map<std::string, std::vector<double> > c_log; + std::map<std::string, std::vector<double> >::iterator c_item = cont_log_.begin(); + for(;c_item != cont_log_.end(); ++c_item) { + std::string u_name = NRLib::Uppercase(c_item->first); + c_log[u_name] = c_item->second; + } + cont_log_ = c_log; +} + +void Well::SetWellName(const std::string& wellname) +{ + well_name_ = wellname; +} + + +bool Well::IsMissing(double x)const +{ + if (x == well_rmissing_) + return true; + else + return false; +} + +bool Well::IsMissing(int n)const +{ + if (n == well_imissing_) + return true; + else + return false; +} + + +int Well::GetDiscValue(size_t index, const std::string& logname) const +{ + std::map<std::string, std::vector<int> >::const_iterator item = disc_log_.find(logname); + assert(item != disc_log_.end()); + const std::vector<int>& log = item->second; + assert(index < log.size()); + return log[index]; +} + + +double Well::GetContValue(size_t index, const std::string& logname) const +{ + std::map<std::string,std::vector<double> >::const_iterator item = cont_log_.find(logname); + assert(item != cont_log_.end()); + const std::vector<double>& log = item->second; + assert(index < log.size()); + return log[index]; +} + + +void Well::SetDiscValue(int value, size_t index, const std::string& logname) +{ + std::map<std::string,std::vector<int> >::iterator item = disc_log_.find(logname); + assert(item != disc_log_.end()); + assert(index < item->second.size()); + (item->second)[index] = value; +} + + +void Well::SetContValue(double value, size_t index, const std::string& logname) +{ + std::map<std::string,std::vector<double> >::iterator item = cont_log_.find(logname); + assert(item != cont_log_.end()); + assert(index < item->second.size()); + (item->second)[index] = value; +} + + +size_t Well::GetNlog() const +{ + return cont_log_.size() + disc_log_.size(); +} + + +size_t Well::GetNContLog() const +{ + return cont_log_.size(); +} + + +size_t Well::GetContLogLength(const std::string& logname) const +{ + std::map<std::string,std::vector<double> >::const_iterator item = cont_log_.find(logname); + assert(item != cont_log_.end()); + + return (item->second).size(); +} + +const std::map<int, std::string> +Well::GetDiscNames(const std::string& log_name) const +{ + std::map<std::string, std::vector<int> >::const_iterator item = disc_log_.find(log_name); + assert(item != disc_log_.end()); + const std::vector<int>& log = item->second; + std::map<int, std::string> name_map; + for(size_t i=0;i<log.size();i++) { + if(IsMissing(log[i]) == false) { + std::string name(NRLib::ToString(log[i])); + if(name_map.find(log[i]) == name_map.end()) + name_map.insert(std::pair<int, std::string> (log[i], name)); + } + } + return(name_map); +} diff --git a/ThirdParty/NRLib/nrlib/well/well.hpp b/ThirdParty/NRLib/nrlib/well/well.hpp new file mode 100644 index 0000000000..2f1920d0c5 --- /dev/null +++ b/ThirdParty/NRLib/nrlib/well/well.hpp @@ -0,0 +1,219 @@ +// $Id: well.hpp 883 2011-09-26 09:17:05Z perroe $ + +// Copyright (c) 2011, Norwegian Computing Center +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// • Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// • Redistributions in binary form must reproduce the above copyright notice, this list of +// conditions and the following disclaimer in the documentation and/or other materials +// provided with the distribution. +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT +// SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef NRLIB_WELL_HPP +#define NRLIB_WELL_HPP + +#include <vector> +#include <sstream> +#include <map> + +namespace NRLib { + class Well{ + public: + /// Default constructor + Well(); + + /// Construct well with given name and no logs. + Well(const std::string & name, + double rmissing = -999.0, + int imissing = -999); + + /// Construct well from file + Well(const std::string & file_name, + bool & read_ok, + const std::string & facies_log = ""); + + /// Constructor + /// \param[in] cont_log Continuous logs + /// \param[in] disc_log Discrete logs + /// \param[in] well_name + Well(const std::map<std::string, std::vector<double> > & cont_log, + const std::map<std::string, std::vector<int> > & disc_log, + const std::string & well_name); + + /// Destructor + virtual ~Well(); + + static Well * ReadWell(const std::string & file_name, + int & well_format); + + /// Check existence of discrete log + bool HasDiscLog(const std::string & name) const; + /// Check existence of continuous log + bool HasContLog(const std::string& name) const; + + /// Return continuous logs + std::vector<double> & GetContLog(const std::string& name); + std::vector<double> & GetContLogSeismicResolution(const std::string& name); + std::vector<double> & GetContLogBackgroundResolution(const std::string& name); + + /// Return continuous logs + const std::vector<double> & GetContLog(const std::string& name) const; + const std::vector<double> & GetContLogSeismicResolution(const std::string& name) const; + const std::vector<double> & GetContLogBackgroundResolution(const std::string& name) const; + + /// Return discrete logs + std::vector<int> & GetDiscLog(const std::string& name); + /// Return discrete logs + const std::vector<int> & GetDiscLog(const std::string& name) const; + + /// Add a continuous log + /// Replaces the log if there is already a log with the given name. + void AddContLog(const std::string& name, const std::vector<double>& log); + void AddContLogSeismicResolution(const std::string& name, const std::vector<double>& log); + void AddContLogBackgroundResolution(const std::string& name, const std::vector<double>& log); + /// Remove continuous log + /// Does nothing if there is no log with the given name. + void RemoveContLog(const std::string& name); + /// Add discrete log + /// Replaces the log if there is already a log with the given name. + void AddDiscLog(const std::string& name, const std::vector<int>& log); + /// Remove discrete log + /// Does nothing if there is no log with the given name. + void RemoveDiscLog(const std::string& name); + /// Change case of all logs to uppercase, to remove case sensitivity on log names + void MakeLogsUppercase(); + /// Set name of well + void SetWellName(const std::string& wellname); + /// + const std::string& GetWellName() const { return well_name_; }; + /// Return true if x is missing + bool IsMissing(double x) const; + /// Return true if n is missing + bool IsMissing(int n) const; + /// Check if deviated + bool IsDeviated() const { return is_deviated_; } + /// Return cont. missing value + double GetContMissing() const { return(well_rmissing_); } + /// Return number of time data + int GetNData(void) const { return n_data_ ;} + /// Return disc. missing value + int GetIntMissing() const { return(well_imissing_); } + /// Set deviated + void SetDeviated(bool b) {is_deviated_ = b ;} + /// Set missing values + void SetMissing(double value) {well_rmissing_ = value; well_imissing_ = static_cast<int>(value);} + /// Return discrete value at position index in log with name logname + /// Returns missing if there is no log with the given name, or index is out of range. + int GetDiscValue(size_t index, const std::string& logname) const; + /// Return continuous value at position index in log with name logname + /// Returns missing if there is no log with the given name, or index is out of range. + double GetContValue(size_t index, const std::string& logname) const; + /// Set value at position index in log with name logname + void SetDiscValue(int value, size_t index, const std::string& logname); + /// Set value at position index in log with name logname + void SetContValue(double value, size_t index, const std::string& logname); + /// Return total number of logs + size_t GetNlog() const; + /// Return number of discrete logs + size_t GetNContLog() const; + /// Return length of log with name logname + size_t GetContLogLength(const std::string& logname) const; + /// Return all continuous logs + const std::map<std::string,std::vector<double> > & GetContLog() const { return cont_log_; }; + const std::map<std::string,std::vector<double> > & GetContLogSeismicResolution() const { return cont_log_seismic_resolution_; }; + const std::map<std::string,std::vector<double> > & GetContLogBackgroundResolution() const { return cont_log_background_resolution_; }; + /// Return all discrete logs + const std::map<std::string,std::vector<int> > & GetDiscLog() const { return disc_log_; }; + /// Facies + int GetNFacies() const { return static_cast<int>(facies_map_.size()) ;} + /// Map integer log to facies name + const std::map<int, std::string> & GetFaciesMap() const { return facies_map_ ;} + + void SetXPos0(double x_pos0) { x_pos0_ = x_pos0 ;} + void SetYPos0(double y_pos0) { y_pos0_ = y_pos0 ;} + + double GetXPos0() { return x_pos0_ ;} + double GetYPos0() { return y_pos0_ ;} + + /// Set number of non-missing data + void SetNumberOfNonMissingData(int n_data_nonmissing) { n_data_nonmissing_ = n_data_nonmissing ;} + + /// Set number of data + void SetNumberOfData(int n_data) {n_data_ = n_data ;} + + void SetFaciesMappingFromDiscLog(const std::string & name) {facies_map_ = GetDiscNames(name);} + + virtual const std::map<int, std::string> GetDiscNames(const std::string& log_name) const; + + unsigned int GetNumberOfNonMissingData() const {return n_data_nonmissing_ ;} + + void SetUseForBackgroundTrend(int use_for_background_trend) { use_for_background_trend_ = use_for_background_trend ;} + void SetUseForFiltering(int use_for_filtering) { use_for_filtering_ = use_for_filtering ;} + void SetUseForFaciesProbabilities(int use_for_facies_probabilities) { use_for_facies_probabilities_ = use_for_facies_probabilities ;} + void SetUseForWaveletEstimation(int use_for_wavelet_estimation) { use_for_wavelet_estimation_ = use_for_wavelet_estimation ;} + void SetRealVsLog(int real_vs_log) { real_vs_log_ = real_vs_log ;} + void SetUseForRockPhysics(int use_for_rock_physics) { use_for_rock_physics_ = use_for_rock_physics ;} + + int GetUseForBackgroundTrend(void) const { return use_for_background_trend_ ;} + int GetUseForFiltering(void) const { return use_for_filtering_ ;} + int GetUseForFaciesProbabilities(void) const { return use_for_facies_probabilities_ ;} + int GetUseForWaveletEstimation(void) const { return use_for_wavelet_estimation_ ;} + int GetRealVsLog(void) const { return real_vs_log_ ;} + int GetUseForRockPhysics(void) const { return use_for_rock_physics_ ;} + + bool HasSyntheticVsLog(void) const { return(real_vs_log_)==0 ;} + + enum WELL_FILE_FORMAT {RMS=0, NORSAR = 1, LAS = 2}; + + protected: + // Number of time data including WELLMISSING values + unsigned int n_data_; + + // Number of data excluding WELLMISSING values + unsigned int n_data_nonmissing_; + + private: + /// Continuous logs + std::map<std::string,std::vector<double> > cont_log_; + /// Discrete logs + std::map<std::string,std::vector<int> > disc_log_; + /// Continuous logs + std::map<std::string,std::vector<double> > cont_log_seismic_resolution_; + /// Continuous logs + std::map<std::string,std::vector<double> > cont_log_background_resolution_; + /// Name of well + std::string well_name_; + /// Missing value for continous logs. + double well_rmissing_; + /// Missing value for discrete logs. + int well_imissing_; + /// Parameter from ModelGeneral + bool is_deviated_; + /// Facies variables + std::map<int, std::string> facies_map_; + + int use_for_background_trend_; //Uses the indicator enum from Modelsettings + int use_for_filtering_; //Uses the indicator enum from Modelsettings + int use_for_wavelet_estimation_; //Uses the indicator enum from Modelsettings + int use_for_facies_probabilities_; //Uses the indicator enum from Modelsettings + int real_vs_log_; //Uses the indicator enum from Modelsettings + int use_for_rock_physics_; //Uses the indicator enum from Modelsettings + + double x_pos0_; // x-coordinate from well file header + double y_pos0_; // y-coordinate from well file header + + }; + +} + +#endif diff --git a/ThirdParty/NRLib/nrlib/well/welloperations.cpp b/ThirdParty/NRLib/nrlib/well/welloperations.cpp new file mode 100644 index 0000000000..6cfae6e0cb --- /dev/null +++ b/ThirdParty/NRLib/nrlib/well/welloperations.cpp @@ -0,0 +1,25 @@ +// $Id: welloperations.cpp 882 2011-09-23 13:10:16Z perroe $ + +// Copyright (c) 2011, Norwegian Computing Center +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// • Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// • Redistributions in binary form must reproduce the above copyright notice, this list of +// conditions and the following disclaimer in the documentation and/or other materials +// provided with the distribution. +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT +// SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include "welloperations.hpp" + +using namespace NRLib; + diff --git a/ThirdParty/NRLib/nrlib/well/welloperations.hpp b/ThirdParty/NRLib/nrlib/well/welloperations.hpp new file mode 100644 index 0000000000..f348d22b6f --- /dev/null +++ b/ThirdParty/NRLib/nrlib/well/welloperations.hpp @@ -0,0 +1,168 @@ +// $Id: welloperations.hpp 883 2011-09-26 09:17:05Z perroe $ + +// Copyright (c) 2011, Norwegian Computing Center +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// • Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// • Redistributions in binary form must reproduce the above copyright notice, this list of +// conditions and the following disclaimer in the documentation and/or other materials +// provided with the distribution. +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT +// SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef NRLIB_WELLOPERATIONS_HPP +#define NRLIB_WELLOPERATIONS_HPP + +#include <string> +#include <iomanip> +#include <vector> +#include <sstream> + +#include "../exception/exception.hpp" +#include "well.hpp" +#include "rmswell.hpp" +#include "../stormgrid/stormcontgrid.hpp" +#include "../stormgrid/stormfaciesgrid.hpp" + +namespace NRLib { + /// Block the well into the grid. + /// Possible grids to use are StormContGrid and StormFaciesGrid + template <typename A> + void BlockWell(const NRLib::Well & well, + const A & grid, + NRLib::Well & blocked_well); +} + + +template <typename A> +void NRLib::BlockWell(const NRLib::Well & well, + const A & grid, + NRLib::Well & blocked_well) +{ + size_t i; + size_t loglength = well.GetContLogLength("x"); + std::vector<size_t> index(loglength); + double x, y, z; + + for (i = 0; i < loglength; i++) { + x = well.GetContValue(i, "x"); + y = well.GetContValue(i, "y"); + z = well.GetContValue(i, "z"); + index[i] = grid.FindIndex(x, y, z); + } + + std::vector<size_t> indexvalues; + indexvalues.push_back(index[0]); + bool found = false; + size_t k; + for (i = 0; i < loglength; i++) { + for (k = 0; k < indexvalues.size(); k++) + if (index[i] == indexvalues[k]) + found = true; + if (found == false) + indexvalues.push_back(index[i]); + found = false; + } + + size_t novalues = indexvalues.size(); + std::vector<int> no(novalues); + + for (i = 0; i < novalues; i++) { + no[i] = 0; + for (k = 0; k < loglength; k++) { + if (index[k] == indexvalues[i]) + no[i]++; + } + } + size_t ncont = well.GetNContLog(); + size_t ndisc = well.GetNlog() - ncont; + std::vector<std::vector<int> > disclogs(ndisc, std::vector<int>(novalues)); + std::vector<std::vector<int> > nodisc(ndisc, std::vector<int>(novalues)); + std::vector<std::vector<int> > nocont(ncont, std::vector<int>(novalues)); + std::vector<std::vector<double> > contlogs(ncont, std::vector<double>(novalues)); + for (k = 0; k < novalues; k++) { + for (i = 0; i < ncont; i++) { + contlogs[i][k] = 0.0; + nocont[i][k] = 0; + } + for (i = 0; i < ndisc; i++) { + disclogs[i][k] = 0; + nodisc[i][k] = 0; + } + } + std::vector<std::string> discnames(ndisc); + std::vector<std::string> contnames(ncont); + typedef std::map<std::string, std::vector<int> >::const_iterator CI; + const std::map<std::string,std::vector<int> >& disclog = well.GetDiscLog(); + i = 0; + for (CI p = disclog.begin(); p != disclog.end(); ++p) { + discnames[i] = p->first; + i++; + } + i = 0; + typedef std::map<std::string, std::vector<double> >::const_iterator CID; + const std::map<std::string,std::vector<double> >& contlog = well.GetContLog(); + for (CID p = contlog.begin(); p != contlog.end(); ++p) { + contnames[i] = p->first; + i++; + } + size_t j; + double valuec; + int valuei; + for (i = 0; i < loglength; i++) { + for (k = 0; k < novalues; k++) { + if (index[i] == indexvalues[k]) { + for (j = 0; j < ncont; j++) { + valuec = well.GetContValue(i, contnames[j]); + if (!well.IsMissing(valuec)) { + contlogs[j][k] += valuec; + nocont[j][k]++; + } + } + for (j = 0; j < ndisc; j++) { + valuei = well.GetDiscValue(i, discnames[j]); + if (!well.IsMissing(valuei)) { + disclogs[j][k] += valuei; + nodisc[j][k]++; + } + } + } + } + } + for (k = 0; k < novalues; k++) { + for (j = 0; j < ncont; j++) { + if (nocont[j][k] == 0) + contlogs[j][k] = well.GetContMissing(); + else + contlogs[j][k] /= nocont[j][k]; + } + for (j = 0; j < ndisc; j++) { + if (nodisc[j][k] == 0) + disclogs[j][k] = well.GetIntMissing(); + else + disclogs[j][k] /= nodisc[j][k]; + } + } + + std::map<std::string,std::vector<double> > contlognew; + for (i = 0; i < ncont; i++) { + contlognew[contnames[i]] = contlogs[i]; + } + std::map<std::string, std::vector<int> > disclognew; + for (i = 0; i < ndisc; i++) { + disclognew[discnames[i]] = disclogs[i]; + } + std::string well_name = well.GetWellName() + "blocked"; + blocked_well = Well(contlognew, disclognew, well_name); +} + +#endif diff --git a/ThirdParty/NRLib/well_UnitTests/Bean_A.las b/ThirdParty/NRLib/well_UnitTests/Bean_A.las new file mode 100644 index 0000000000..07f0791d5c --- /dev/null +++ b/ThirdParty/NRLib/well_UnitTests/Bean_A.las @@ -0,0 +1,10431 @@ +~Version Information Block + VERS. 2.00: CWLS LOG ASCII STANDARD - VERSION 2.000000 + WRAP. NO: One Line Per Depth Step +# +~Well Information Block +#MNEM.UNIT Data Information +#---------- ------------------------------------------ ---------------- + STRT.FT 100.0000: + STOP.FT 5300.0000: + STEP.FT 0.5000: + NULL. -999.2500: + COMP. : COMPANY + WELL. : WELL + FLD . : FIELD + CNTY. : COUNTY + STAT. : STATE + CTRY. : COUNTRY + SRVC. : SERVICE COMPANY + DATE. : DATE + API . : API NUMBER + UWI . : UWI NUMBER +# +~Curve Information Block +#MNEM.UNIT API CODE Curve Description +#---------- ------------- ------------------- + DEPT.FT : Depth in Feet + GR .GAPI : Gamma Ray + RHOB.G/C3 : Bulk Density +# +~A DEPTH GR RHOB + 100.000 59.449 2.705 + 100.500 59.449 2.705 + 101.000 61.024 2.703 + 101.500 61.024 2.697 + 102.000 61.811 2.670 + 102.500 61.811 2.668 + 103.000 61.811 2.668 + 103.500 61.922 2.671 + 104.000 59.356 2.664 + 104.500 57.615 2.664 + 105.000 57.021 2.664 + 105.500 57.056 2.663 + 106.000 57.807 2.662 + 106.500 59.438 2.642 + 107.000 60.948 2.640 + 107.500 61.006 2.640 + 108.000 61.036 2.644 + 108.500 61.001 2.649 + 109.000 61.176 2.648 + 109.500 61.956 2.652 + 110.000 60.861 2.639 + 110.500 59.249 2.630 + 111.000 59.501 2.627 + 111.500 59.741 2.625 + 112.000 63.713 2.624 + 112.500 66.573 2.615 + 113.000 68.681 2.605 + 113.500 70.952 2.600 + 114.000 71.756 2.600 + 114.500 71.226 2.600 + 115.000 71.301 2.600 + 115.500 71.121 2.601 + 116.000 70.398 2.589 + 116.500 70.517 2.583 + 117.000 70.485 2.580 + 117.500 70.451 2.577 + 118.000 70.430 2.580 + 118.500 68.789 2.597 + 119.000 67.369 2.604 + 119.500 63.578 2.611 + 120.000 61.751 2.628 + 120.500 61.072 2.642 + 121.000 62.136 2.644 + 121.500 64.348 2.644 + 122.000 67.510 2.640 + 122.500 72.426 2.631 + 123.000 73.699 2.621 + 123.500 73.084 2.593 + 124.000 69.305 2.578 + 124.500 66.794 2.552 + 125.000 62.101 2.544 + 125.500 58.760 2.548 + 126.000 57.139 2.586 + 126.500 57.710 2.616 + 127.000 60.129 2.638 + 127.500 61.237 2.638 + 128.000 59.456 2.631 + 128.500 57.071 2.631 + 129.000 54.999 2.632 + 129.500 54.044 2.643 + 130.000 52.381 2.654 + 130.500 52.386 2.661 + 131.000 52.278 2.663 + 131.500 53.273 2.664 + 132.000 57.455 2.660 + 132.500 59.763 2.656 + 133.000 60.415 2.650 + 133.500 61.086 2.642 + 134.000 61.014 2.635 + 134.500 61.030 2.634 + 135.000 61.034 2.642 + 135.500 61.020 2.648 + 136.000 61.037 2.669 + 136.500 61.015 2.676 + 137.000 61.010 2.676 + 137.500 61.182 2.672 + 138.000 62.024 2.663 + 138.500 62.670 2.649 + 139.000 62.591 2.644 + 139.500 62.429 2.637 + 140.000 61.671 2.639 + 140.500 60.323 2.642 + 141.000 60.273 2.648 + 141.500 60.203 2.652 + 142.000 60.246 2.655 + 142.500 59.937 2.656 + 143.000 60.217 2.654 + 143.500 60.606 2.650 + 144.000 60.926 2.651 + 144.500 61.285 2.656 + 145.000 61.884 2.656 + 145.500 62.457 2.653 + 146.000 62.525 2.649 + 146.500 62.119 2.640 + 147.000 61.542 2.633 + 147.500 60.606 2.624 + 148.000 59.023 2.610 + 148.500 57.344 2.582 + 149.000 56.551 2.568 + 149.500 56.864 2.492 + 150.000 57.688 2.427 + 150.500 58.507 2.364 + 151.000 59.189 2.285 + 151.500 59.734 2.245 + 152.000 60.239 2.211 + 152.500 60.825 2.464 + 153.000 61.363 2.628 + 153.500 61.614 2.615 + 154.000 61.621 2.651 + 154.500 61.569 2.663 + 155.000 61.483 2.649 + 155.500 61.450 2.643 + 156.000 61.752 2.641 + 156.500 62.374 2.645 + 157.000 62.891 2.649 + 157.500 63.151 2.658 + 158.000 63.432 2.660 + 158.500 63.718 2.658 + 159.000 63.771 2.656 + 159.500 64.096 2.651 + 160.000 65.697 2.638 + 160.500 68.543 2.603 + 161.000 71.503 2.600 + 161.500 74.045 2.591 + 162.000 76.663 2.582 + 162.500 79.332 2.562 + 163.000 80.939 2.567 + 163.500 80.813 2.586 + 164.000 79.665 2.633 + 164.500 78.508 2.636 + 165.000 77.528 2.641 + 165.500 76.601 2.640 + 166.000 76.165 2.631 + 166.500 76.663 2.621 + 167.000 77.522 2.620 + 167.500 77.919 2.623 + 168.000 78.306 2.628 + 168.500 79.489 2.648 + 169.000 80.203 2.648 + 169.500 77.957 2.662 + 170.000 72.977 2.657 + 170.500 68.742 2.655 + 171.000 67.403 2.650 + 171.500 66.925 2.643 + 172.000 64.335 2.628 + 172.500 60.031 2.634 + 173.000 57.168 2.656 + 173.500 57.746 2.662 + 174.000 60.707 2.672 + 174.500 63.437 2.672 + 175.000 63.968 2.667 + 175.500 61.870 2.666 + 176.000 58.207 2.667 + 176.500 55.004 2.673 + 177.000 53.860 2.676 + 177.500 54.611 2.683 + 178.000 55.996 2.685 + 178.500 57.543 2.682 + 179.000 59.552 2.681 + 179.500 61.454 2.683 + 180.000 61.965 2.687 + 180.500 60.998 2.693 + 181.000 59.805 2.704 + 181.500 59.102 2.707 + 182.000 58.502 2.704 + 182.500 57.684 2.684 + 183.000 56.819 2.672 + 183.500 56.119 2.669 + 184.000 55.727 2.668 + 184.500 55.531 2.669 + 185.000 54.911 2.659 + 185.500 53.821 2.656 + 186.000 54.007 2.656 + 186.500 57.177 2.662 + 187.000 62.115 2.662 + 187.500 65.719 2.658 + 188.000 66.961 2.653 + 188.500 67.593 2.646 + 189.000 68.963 2.635 + 189.500 70.556 2.620 + 190.000 71.820 2.618 + 190.500 72.992 2.640 + 191.000 73.952 2.658 + 191.500 74.414 2.668 + 192.000 75.197 2.660 + 192.500 77.388 2.651 + 193.000 80.469 2.656 + 193.500 82.931 2.659 + 194.000 84.495 2.662 + 194.500 86.103 2.677 + 195.000 87.974 2.676 + 195.500 89.040 2.668 + 196.000 89.903 2.651 + 196.500 85.835 2.636 + 197.000 85.376 2.634 + 197.500 83.468 2.632 + 198.000 82.990 2.625 + 198.500 80.411 2.611 + 199.000 80.279 2.605 + 199.500 78.718 2.603 + 200.000 75.484 2.603 + 200.500 64.300 2.604 + 201.000 61.725 2.617 + 201.500 60.243 2.628 + 202.000 58.596 2.662 + 202.500 59.195 2.672 + 203.000 61.277 2.682 + 203.500 62.603 2.693 + 204.000 63.448 2.708 + 204.500 63.226 2.711 + 205.000 62.477 2.707 + 205.500 61.025 2.699 + 206.000 61.159 2.695 + 206.500 58.254 2.688 + 207.000 57.211 2.686 + 207.500 55.524 2.678 + 208.000 55.705 2.674 + 208.500 56.345 2.666 + 209.000 56.338 2.662 + 209.500 55.700 2.658 + 210.000 54.575 2.664 + 210.500 50.974 2.673 + 211.000 49.222 2.678 + 211.500 47.701 2.677 + 212.000 47.066 2.679 + 212.500 46.851 2.677 + 213.000 48.243 2.677 + 213.500 49.943 2.676 + 214.000 53.468 2.681 + 214.500 59.431 2.680 + 215.000 67.636 2.680 + 215.500 69.604 2.678 + 216.000 72.187 2.676 + 216.500 75.090 2.670 + 217.000 75.173 2.666 + 217.500 74.667 2.662 + 218.000 74.489 2.656 + 218.500 75.887 2.646 + 219.000 75.965 2.640 + 219.500 76.163 2.637 + 220.000 76.856 2.633 + 220.500 76.656 2.626 + 221.000 77.606 2.626 + 221.500 78.382 2.623 + 222.000 78.893 2.620 + 222.500 79.824 2.617 + 223.000 79.885 2.616 + 223.500 79.817 2.616 + 224.000 76.847 2.624 + 224.500 74.422 2.636 + 225.000 70.446 2.650 + 225.500 69.293 2.658 + 226.000 67.988 2.659 + 226.500 66.758 2.658 + 227.000 65.534 2.658 + 227.500 64.290 2.658 + 228.000 63.058 2.656 + 228.500 61.801 2.652 + 229.000 60.623 2.649 + 229.500 59.310 2.642 + 230.000 57.793 2.631 + 230.500 55.011 2.619 + 231.000 53.467 2.622 + 231.500 53.148 2.635 + 232.000 53.093 2.649 + 232.500 55.554 2.655 + 233.000 58.046 2.654 + 233.500 60.373 2.650 + 234.000 61.049 2.643 + 234.500 61.031 2.632 + 235.000 60.995 2.629 + 235.500 61.077 2.631 + 236.000 61.086 2.630 + 236.500 62.497 2.632 + 237.000 63.299 2.633 + 237.500 64.834 2.632 + 238.000 65.594 2.630 + 238.500 65.743 2.619 + 239.000 65.702 2.617 + 239.500 64.063 2.612 + 240.000 63.390 2.613 + 240.500 63.319 2.609 + 241.000 63.956 2.602 + 241.500 64.963 2.600 + 242.000 65.850 2.595 + 242.500 65.725 2.584 + 243.000 65.812 2.569 + 243.500 65.027 2.560 + 244.000 63.951 2.516 + 244.500 62.981 2.433 + 245.000 61.655 2.378 + 245.500 57.701 2.213 + 246.000 55.262 2.125 + 246.500 54.032 2.329 + 247.000 53.894 2.386 + 247.500 53.951 2.587 + 248.000 54.358 2.663 + 248.500 58.742 2.680 + 249.000 59.604 2.671 + 249.500 60.942 2.664 + 250.000 62.057 2.661 + 250.500 63.191 2.649 + 251.000 64.370 2.639 + 251.500 65.514 2.638 + 252.000 66.668 2.648 + 252.500 67.820 2.661 + 253.000 68.973 2.660 + 253.500 70.127 2.654 + 254.000 71.280 2.643 + 254.500 72.433 2.616 + 255.000 73.587 2.612 + 255.500 74.740 2.608 + 256.000 75.893 2.605 + 256.500 77.047 2.602 + 257.000 78.200 2.599 + 257.500 79.353 2.597 + 258.000 80.507 2.597 + 258.500 81.660 2.594 + 259.000 82.813 2.595 + 259.500 83.967 2.601 + 260.000 85.120 2.610 + 260.500 86.273 2.628 + 261.000 87.427 2.635 + 261.500 88.580 2.642 + 262.000 89.733 2.648 + 262.500 90.887 2.644 + 263.000 92.040 2.644 + 263.500 93.193 2.647 + 264.000 94.347 2.645 + 264.500 95.500 2.656 + 265.000 96.653 2.660 + 265.500 97.807 2.668 + 266.000 98.960 2.673 + 266.500 100.113 2.677 + 267.000 101.267 2.677 + 267.500 102.420 2.678 + 268.000 103.573 2.661 + 268.500 104.727 2.634 + 269.000 105.880 2.626 + 269.500 107.033 2.624 + 270.000 108.187 2.621 + 270.500 109.340 2.617 + 271.000 110.493 2.611 + 271.500 111.647 2.607 + 272.000 112.800 2.604 + 272.500 113.953 2.603 + 273.000 115.106 2.608 + 273.500 116.260 2.620 + 274.000 117.413 2.634 + 274.500 118.566 2.649 + 275.000 119.720 2.653 + 275.500 120.873 2.658 + 276.000 122.026 2.663 + 276.500 123.180 2.661 + 277.000 124.333 2.653 + 277.500 125.486 2.656 + 278.000 126.640 2.661 + 278.500 127.793 2.661 + 279.000 128.944 2.650 + 279.500 130.091 2.645 + 280.000 131.262 2.642 + 280.500 132.382 2.655 + 281.000 133.534 2.658 + 281.500 134.796 2.661 + 282.000 135.643 2.659 + 282.500 138.707 2.637 + 283.000 140.794 2.623 + 283.500 144.377 2.613 + 284.000 147.152 2.613 + 284.500 151.290 2.615 + 285.000 157.679 2.614 + 285.500 160.447 2.611 + 286.000 164.393 2.602 + 286.500 167.219 2.598 + 287.000 172.945 2.593 + 287.500 175.457 2.591 + 288.000 176.906 2.588 + 288.500 176.868 2.586 + 289.000 175.211 2.585 + 289.500 171.750 2.591 + 290.000 171.230 2.592 + 290.500 172.125 2.592 + 291.000 177.652 2.585 + 291.500 180.814 2.579 + 292.000 180.291 2.577 + 292.500 177.553 2.575 + 293.000 170.042 2.576 + 293.500 167.162 2.576 + 294.000 163.688 2.586 + 294.500 146.869 2.594 + 295.000 139.320 2.606 + 295.500 136.590 2.605 + 296.000 131.711 2.607 + 296.500 131.921 2.607 + 297.000 132.753 2.607 + 297.500 136.403 2.601 + 298.000 138.034 2.597 + 298.500 138.044 2.600 + 299.000 137.171 2.608 + 299.500 134.837 2.613 + 300.000 136.901 2.617 + 300.500 138.431 2.619 + 301.000 136.760 2.611 + 301.500 135.659 2.608 + 302.000 134.153 2.603 + 302.500 133.422 2.602 + 303.000 133.425 2.606 + 303.500 134.069 2.607 + 304.000 136.418 2.607 + 304.500 138.334 2.610 + 305.000 139.403 2.611 + 305.500 143.190 2.613 + 306.000 147.375 2.609 + 306.500 154.380 2.603 + 307.000 156.489 2.599 + 307.500 162.194 2.587 + 308.000 166.309 2.583 + 308.500 167.831 2.577 + 309.000 169.842 2.571 + 309.500 172.228 2.565 + 310.000 181.382 2.557 + 310.500 185.428 2.548 + 311.000 185.588 2.543 + 311.500 183.825 2.542 + 312.000 183.760 2.548 + 312.500 178.432 2.558 + 313.000 174.248 2.558 + 313.500 168.177 2.558 + 314.000 165.327 2.568 + 314.500 151.769 2.579 + 315.000 148.534 2.582 + 315.500 144.807 2.585 + 316.000 141.030 2.586 + 316.500 137.731 2.603 + 317.000 137.218 2.608 + 317.500 135.971 2.608 + 318.000 133.092 2.605 + 318.500 129.064 2.601 + 319.000 124.673 2.601 + 319.500 122.755 2.606 + 320.000 117.472 2.613 + 320.500 116.945 2.619 + 321.000 117.571 2.614 + 321.500 119.253 2.609 + 322.000 119.312 2.607 + 322.500 118.888 2.604 + 323.000 116.927 2.603 + 323.500 110.450 2.603 + 324.000 108.253 2.610 + 324.500 107.149 2.615 + 325.000 106.883 2.619 + 325.500 108.988 2.613 + 326.000 117.486 2.609 + 326.500 125.935 2.599 + 327.000 127.072 2.599 + 327.500 128.834 2.603 + 328.000 132.906 2.609 + 328.500 136.101 2.618 + 329.000 142.489 2.618 + 329.500 147.088 2.617 + 330.000 153.479 2.611 + 330.500 163.043 2.605 + 331.000 168.349 2.592 + 331.500 172.189 2.587 + 332.000 174.422 2.577 + 332.500 174.403 2.560 + 333.000 174.461 2.546 + 333.500 175.296 2.538 + 334.000 177.623 2.532 + 334.500 177.720 2.528 + 335.000 176.199 2.525 + 335.500 174.546 2.521 + 336.000 164.822 2.520 + 336.500 153.641 2.530 + 337.000 139.875 2.538 + 337.500 128.856 2.550 + 338.000 116.331 2.561 + 338.500 105.580 2.571 + 339.000 100.782 2.566 + 339.500 100.581 2.554 + 340.000 100.584 2.545 + 340.500 100.872 2.537 + 341.000 100.994 2.529 + 341.500 100.249 2.521 + 342.000 96.864 2.514 + 342.500 95.492 2.527 + 343.000 94.176 2.544 + 343.500 93.330 2.557 + 344.000 90.802 2.572 + 344.500 91.776 2.588 + 345.000 92.579 2.597 + 345.500 92.529 2.599 + 346.000 92.444 2.600 + 346.500 93.158 2.601 + 347.000 93.316 2.606 + 347.500 93.401 2.616 + 348.000 92.458 2.623 + 348.500 90.064 2.633 + 349.000 88.633 2.635 + 349.500 87.702 2.639 + 350.000 87.479 2.643 + 350.500 83.785 2.645 + 351.000 77.718 2.655 + 351.500 71.663 2.664 + 352.000 66.188 2.672 + 352.500 64.212 2.686 + 353.000 62.522 2.698 + 353.500 62.738 2.701 + 354.000 67.049 2.703 + 354.500 75.472 2.699 + 355.000 84.741 2.698 + 355.500 90.683 2.702 + 356.000 93.503 2.707 + 356.500 90.052 2.703 + 357.000 88.824 2.699 + 357.500 85.734 2.691 + 358.000 83.365 2.683 + 358.500 80.873 2.682 + 359.000 80.519 2.682 + 359.500 80.716 2.681 + 360.000 84.947 2.681 + 360.500 88.615 2.683 + 361.000 91.487 2.681 + 361.500 94.096 2.683 + 362.000 96.833 2.689 + 362.500 100.428 2.694 + 363.000 103.304 2.691 + 363.500 104.435 2.687 + 364.000 106.664 2.680 + 364.500 107.298 2.685 + 365.000 107.546 2.696 + 365.500 107.387 2.699 + 366.000 107.573 2.699 + 366.500 102.385 2.696 + 367.000 101.235 2.695 + 367.500 100.952 2.695 + 368.000 102.579 2.697 + 368.500 104.274 2.701 + 369.000 104.243 2.703 + 369.500 104.999 2.702 + 370.000 105.099 2.696 + 370.500 105.126 2.700 + 371.000 105.262 2.704 + 371.500 103.613 2.713 + 372.000 101.059 2.722 + 372.500 100.335 2.721 + 373.000 99.613 2.719 + 373.500 97.205 2.716 + 374.000 96.953 2.715 + 374.500 95.511 2.716 + 375.000 95.806 2.723 + 375.500 97.145 2.722 + 376.000 99.609 2.721 + 376.500 102.126 2.714 + 377.000 104.917 2.711 + 377.500 105.604 2.706 + 378.000 106.608 2.701 + 378.500 106.730 2.697 + 379.000 107.250 2.698 + 379.500 107.699 2.701 + 380.000 108.194 2.706 + 380.500 108.670 2.708 + 381.000 109.147 2.706 + 381.500 109.634 2.704 + 382.000 110.112 2.703 + 382.500 110.603 2.701 + 383.000 111.078 2.699 + 383.500 111.437 2.699 + 384.000 111.449 2.699 + 384.500 111.288 2.695 + 385.000 109.680 2.693 + 385.500 105.762 2.693 + 386.000 103.095 2.693 + 386.500 99.305 2.699 + 387.000 98.264 2.699 + 387.500 96.363 2.703 + 388.000 100.162 2.703 + 388.500 98.450 2.695 + 389.000 93.143 2.695 + 389.500 89.979 2.693 + 390.000 89.283 2.695 + 390.500 89.288 2.698 + 391.000 89.741 2.695 + 391.500 91.384 2.693 + 392.000 94.171 2.699 + 392.500 99.032 2.706 + 393.000 108.089 2.709 + 393.500 110.943 2.705 + 394.000 111.394 2.698 + 394.500 110.998 2.692 + 395.000 109.374 2.689 + 395.500 109.008 2.691 + 396.000 109.020 2.696 + 396.500 107.486 2.701 + 397.000 107.559 2.703 + 397.500 107.935 2.703 + 398.000 111.758 2.703 + 398.500 112.308 2.703 + 399.000 113.113 2.703 + 399.500 112.822 2.705 + 400.000 111.875 2.704 + 400.500 109.804 2.703 + 401.000 108.391 2.701 + 401.500 108.272 2.701 + 402.000 108.245 2.704 + 402.500 108.542 2.710 + 403.000 108.617 2.705 + 403.500 108.680 2.701 + 404.000 108.616 2.700 + 404.500 108.567 2.697 + 405.000 108.656 2.697 + 405.500 108.709 2.697 + 406.000 108.550 2.699 + 406.500 108.561 2.701 + 407.000 109.452 2.697 + 407.500 111.233 2.694 + 408.000 112.904 2.686 + 408.500 113.584 2.687 + 409.000 113.449 2.692 + 409.500 113.130 2.693 + 410.000 112.675 2.695 + 410.500 111.702 2.695 + 411.000 110.319 2.695 + 411.500 109.314 2.692 + 412.000 109.379 2.690 + 412.500 110.400 2.689 + 413.000 111.541 2.687 + 413.500 111.892 2.685 + 414.000 111.060 2.681 + 414.500 109.278 2.679 + 415.000 107.170 2.677 + 415.500 105.462 2.676 + 416.000 104.664 2.673 + 416.500 104.794 2.673 + 417.000 105.444 2.673 + 417.500 106.142 2.673 + 418.000 106.612 2.673 + 418.500 106.741 2.673 + 419.000 106.426 2.672 + 419.500 105.631 2.672 + 420.000 104.491 2.672 + 420.500 103.201 2.672 + 421.000 101.747 2.672 + 421.500 100.058 2.671 + 422.000 98.532 2.671 + 422.500 97.811 2.671 + 423.000 97.862 2.671 + 423.500 98.077 2.671 + 424.000 98.230 2.670 + 424.500 98.124 2.670 + 425.000 96.578 2.670 + 425.500 92.613 2.670 + 426.000 87.575 2.670 + 426.500 84.164 2.669 + 427.000 83.424 2.669 + 427.500 84.368 2.669 + 428.000 86.042 2.669 + 428.500 88.090 2.669 + 429.000 89.959 2.668 + 429.500 91.292 2.668 + 430.000 92.551 2.668 + 430.500 94.062 2.668 + 431.000 95.330 2.668 + 431.500 96.108 2.667 + 432.000 96.983 2.667 + 432.500 98.320 2.667 + 433.000 99.784 2.667 + 433.500 101.097 2.667 + 434.000 102.277 2.666 + 434.500 103.173 2.666 + 435.000 103.680 2.666 + 435.500 104.272 2.666 + 436.000 105.635 2.666 + 436.500 107.970 2.665 + 437.000 110.666 2.665 + 437.500 112.522 2.665 + 438.000 113.012 2.665 + 438.500 113.432 2.665 + 439.000 115.133 2.664 + 439.500 116.524 2.664 + 440.000 114.508 2.664 + 440.500 109.412 2.664 + 441.000 105.313 2.664 + 441.500 104.630 2.663 + 442.000 105.703 2.663 + 442.500 106.521 2.663 + 443.000 107.379 2.663 + 443.500 108.745 2.663 + 444.000 109.583 2.662 + 444.500 109.014 2.662 + 445.000 107.592 2.662 + 445.500 106.161 2.662 + 446.000 104.921 2.662 + 446.500 103.847 2.661 + 447.000 103.033 2.661 + 447.500 102.503 2.661 + 448.000 102.223 2.661 + 448.500 102.369 2.661 + 449.000 103.418 2.660 + 449.500 105.467 2.660 + 450.000 107.289 2.660 + 450.500 106.881 2.659 + 451.000 103.902 2.658 + 451.500 100.672 2.657 + 452.000 99.454 2.654 + 452.500 99.681 2.654 + 453.000 99.327 2.655 + 453.500 98.060 2.657 + 454.000 97.261 2.661 + 454.500 97.629 2.666 + 455.000 98.512 2.676 + 455.500 99.285 2.678 + 456.000 99.971 2.683 + 456.500 100.624 2.686 + 457.000 100.976 2.685 + 457.500 100.748 2.683 + 458.000 99.975 2.677 + 458.500 99.105 2.671 + 459.000 98.715 2.670 + 459.500 98.945 2.668 + 460.000 99.694 2.665 + 460.500 99.946 2.662 + 461.000 100.547 2.659 + 461.500 100.390 2.653 + 462.000 100.348 2.650 + 462.500 100.408 2.640 + 463.000 100.445 2.638 + 463.500 99.672 2.635 + 464.000 98.047 2.624 + 464.500 96.387 2.603 + 465.000 95.498 2.587 + 465.500 94.696 2.576 + 466.000 95.569 2.551 + 466.500 93.197 2.513 + 467.000 91.606 2.486 + 467.500 91.776 2.490 + 468.000 91.657 2.525 + 468.500 92.276 2.625 + 469.000 93.341 2.656 + 469.500 94.099 2.670 + 470.000 94.708 2.682 + 470.500 95.005 2.688 + 471.000 95.872 2.692 + 471.500 95.427 2.691 + 472.000 96.914 2.684 + 472.500 95.615 2.668 + 473.000 94.461 2.663 + 473.500 94.184 2.655 + 474.000 92.809 2.653 + 474.500 92.606 2.656 + 475.000 92.296 2.661 + 475.500 93.785 2.669 + 476.000 94.881 2.676 + 476.500 96.475 2.673 + 477.000 96.493 2.668 + 477.500 95.813 2.661 + 478.000 95.257 2.655 + 478.500 94.833 2.658 + 479.000 94.927 2.660 + 479.500 94.161 2.657 + 480.000 93.597 2.657 + 480.500 93.286 2.656 + 481.000 93.300 2.654 + 481.500 93.730 2.650 + 482.000 94.916 2.648 + 482.500 95.597 2.646 + 483.000 96.947 2.647 + 483.500 98.277 2.650 + 484.000 99.709 2.663 + 484.500 100.868 2.674 + 485.000 102.865 2.675 + 485.500 103.668 2.672 + 486.000 105.145 2.670 + 486.500 104.660 2.665 + 487.000 101.142 2.654 + 487.500 98.605 2.652 + 488.000 83.572 2.658 + 488.500 70.662 2.664 + 489.000 56.470 2.664 + 489.500 53.287 2.654 + 490.000 44.509 2.647 + 490.500 31.557 2.603 + 491.000 26.658 2.587 + 491.500 25.399 2.587 + 492.000 25.492 2.594 + 492.500 25.539 2.613 + 493.000 24.701 2.621 + 493.500 27.049 2.627 + 494.000 28.138 2.627 + 494.500 31.170 2.631 + 495.000 31.242 2.632 + 495.500 31.392 2.633 + 496.000 30.581 2.634 + 496.500 28.621 2.637 + 497.000 27.407 2.638 + 497.500 25.619 2.633 + 498.000 25.631 2.630 + 498.500 25.581 2.623 + 499.000 25.428 2.619 + 499.500 24.591 2.619 + 500.000 23.733 2.622 + 500.500 23.031 2.622 + 501.000 24.647 2.622 + 501.500 25.824 2.619 + 502.000 26.625 2.619 + 502.500 27.165 2.625 + 503.000 27.275 2.630 + 503.500 25.871 2.633 + 504.000 23.405 2.632 + 504.500 21.581 2.628 + 505.000 20.476 2.627 + 505.500 19.549 2.633 + 506.000 19.719 2.639 + 506.500 19.737 2.651 + 507.000 21.083 2.665 + 507.500 22.466 2.672 + 508.000 23.261 2.669 + 508.500 23.447 2.658 + 509.000 23.604 2.652 + 509.500 24.238 2.652 + 510.000 24.870 2.651 + 510.500 24.682 2.649 + 511.000 23.633 2.643 + 511.500 21.567 2.632 + 512.000 18.678 2.628 + 512.500 15.800 2.625 + 513.000 12.660 2.627 + 513.500 13.082 2.629 + 514.000 13.819 2.631 + 514.500 14.864 2.633 + 515.000 16.011 2.634 + 515.500 17.059 2.635 + 516.000 18.149 2.637 + 516.500 19.258 2.648 + 517.000 20.069 2.650 + 517.500 20.050 2.655 + 518.000 20.177 2.658 + 518.500 19.405 2.662 + 519.000 19.381 2.666 + 519.500 18.638 2.668 + 520.000 18.495 2.666 + 520.500 18.500 2.662 + 521.000 18.621 2.660 + 521.500 19.370 2.660 + 522.000 19.429 2.660 + 522.500 20.060 2.657 + 523.000 20.712 2.653 + 523.500 20.919 2.650 + 524.000 22.598 2.643 + 524.500 25.095 2.640 + 525.000 26.563 2.638 + 525.500 27.834 2.638 + 526.000 28.600 2.639 + 526.500 30.270 2.644 + 527.000 30.505 2.647 + 527.500 31.175 2.640 + 528.000 33.253 2.635 + 528.500 33.416 2.625 + 529.000 33.417 2.624 + 529.500 32.482 2.628 + 530.000 33.332 2.634 + 530.500 32.395 2.647 + 531.000 31.886 2.653 + 531.500 32.000 2.652 + 532.000 32.798 2.649 + 532.500 32.677 2.643 + 533.000 32.288 2.637 + 533.500 31.505 2.634 + 534.000 31.179 2.636 + 534.500 31.067 2.634 + 535.000 31.079 2.632 + 535.500 31.480 2.625 + 536.000 32.577 2.624 + 536.500 34.694 2.626 + 537.000 36.034 2.631 + 537.500 37.004 2.634 + 538.000 38.037 2.638 + 538.500 38.055 2.647 + 539.000 37.164 2.650 + 539.500 36.954 2.648 + 540.000 37.617 2.640 + 540.500 38.049 2.634 + 541.000 38.135 2.628 + 541.500 38.416 2.633 + 542.000 38.643 2.637 + 542.500 39.117 2.641 + 543.000 38.809 2.646 + 543.500 38.003 2.654 + 544.000 38.954 2.653 + 544.500 38.941 2.653 + 545.000 41.104 2.649 + 545.500 41.454 2.644 + 546.000 39.907 2.638 + 546.500 38.990 2.632 + 547.000 38.805 2.626 + 547.500 37.978 2.630 + 548.000 37.059 2.631 + 548.500 36.793 2.640 + 549.000 37.387 2.646 + 549.500 38.085 2.649 + 550.000 38.570 2.648 + 550.500 40.243 2.648 + 551.000 41.145 2.648 + 551.500 41.405 2.647 + 552.000 41.378 2.643 + 552.500 41.117 2.639 + 553.000 40.470 2.640 + 553.500 39.103 2.642 + 554.000 37.972 2.642 + 554.500 35.019 2.640 + 555.000 34.459 2.636 + 555.500 34.096 2.627 + 556.000 33.069 2.622 + 556.500 33.790 2.611 + 557.000 35.735 2.612 + 557.500 36.496 2.619 + 558.000 38.099 2.623 + 558.500 37.567 2.631 + 559.000 37.249 2.634 + 559.500 36.474 2.632 + 560.000 36.893 2.633 + 560.500 37.562 2.628 + 561.000 38.584 2.624 + 561.500 38.987 2.624 + 562.000 36.936 2.625 + 562.500 35.374 2.627 + 563.000 32.729 2.626 + 563.500 31.098 2.622 + 564.000 30.143 2.619 + 564.500 31.121 2.614 + 565.000 32.395 2.615 + 565.500 34.519 2.618 + 566.000 35.679 2.618 + 566.500 37.588 2.615 + 567.000 37.554 2.614 + 567.500 37.530 2.620 + 568.000 35.710 2.626 + 568.500 31.008 2.634 + 569.000 27.430 2.631 + 569.500 25.286 2.631 + 570.000 24.701 2.628 + 570.500 24.898 2.631 + 571.000 27.630 2.630 + 571.500 33.558 2.627 + 572.000 34.097 2.625 + 572.500 35.132 2.625 + 573.000 35.126 2.626 + 573.500 34.355 2.630 + 574.000 34.428 2.630 + 574.500 35.248 2.634 + 575.000 36.217 2.634 + 575.500 37.189 2.639 + 576.000 38.198 2.642 + 576.500 39.080 2.624 + 577.000 38.934 2.619 + 577.500 39.058 2.609 + 578.000 38.349 2.608 + 578.500 38.219 2.614 + 579.000 37.527 2.619 + 579.500 35.313 2.623 + 580.000 34.499 2.619 + 580.500 33.618 2.606 + 581.000 33.383 2.600 + 581.500 34.117 2.601 + 582.000 34.253 2.611 + 582.500 34.164 2.615 + 583.000 33.146 2.613 + 583.500 30.593 2.610 + 584.000 26.769 2.608 + 584.500 23.031 2.605 + 585.000 21.635 2.595 + 585.500 21.021 2.570 + 586.000 20.823 2.557 + 586.500 21.416 2.566 + 587.000 21.665 2.573 + 587.500 21.877 2.591 + 588.000 22.190 2.599 + 588.500 22.769 2.594 + 589.000 23.490 2.593 + 589.500 23.567 2.599 + 590.000 22.780 2.602 + 590.500 24.381 2.603 + 591.000 25.868 2.605 + 591.500 26.650 2.612 + 592.000 27.527 2.615 + 592.500 30.446 2.618 + 593.000 31.665 2.615 + 593.500 32.751 2.613 + 594.000 33.562 2.608 + 594.500 34.015 2.600 + 595.000 34.272 2.600 + 595.500 34.411 2.605 + 596.000 35.148 2.612 + 596.500 36.318 2.618 + 597.000 35.899 2.617 + 597.500 36.448 2.604 + 598.000 37.279 2.602 + 598.500 37.966 2.600 + 599.000 38.389 2.601 + 599.500 40.701 2.605 + 600.000 41.436 2.610 + 600.500 41.251 2.613 + 601.000 41.481 2.611 + 601.500 40.221 2.608 + 602.000 38.431 2.612 + 602.500 37.418 2.614 + 603.000 35.231 2.619 + 603.500 34.067 2.623 + 604.000 33.207 2.622 + 604.500 32.497 2.618 + 605.000 31.817 2.615 + 605.500 31.853 2.610 + 606.000 32.306 2.609 + 606.500 32.638 2.607 + 607.000 33.229 2.609 + 607.500 34.154 2.613 + 608.000 34.104 2.615 + 608.500 35.541 2.620 + 609.000 35.819 2.622 + 609.500 35.851 2.624 + 610.000 35.789 2.625 + 610.500 36.029 2.626 + 611.000 36.617 2.627 + 611.500 37.132 2.629 + 612.000 38.268 2.629 + 612.500 39.004 2.627 + 613.000 41.249 2.621 + 613.500 40.085 2.613 + 614.000 39.202 2.613 + 614.500 38.922 2.618 + 615.000 38.971 2.616 + 615.500 39.029 2.617 + 616.000 38.952 2.617 + 616.500 38.828 2.620 + 617.000 38.186 2.623 + 617.500 37.423 2.626 + 618.000 36.460 2.633 + 618.500 34.928 2.634 + 619.000 34.302 2.633 + 619.500 33.547 2.631 + 620.000 34.186 2.630 + 620.500 35.639 2.630 + 621.000 36.431 2.630 + 621.500 37.264 2.630 + 622.000 39.054 2.631 + 622.500 38.286 2.631 + 623.000 38.027 2.631 + 623.500 37.565 2.633 + 624.000 37.721 2.634 + 624.500 38.913 2.635 + 625.000 38.906 2.639 + 625.500 38.895 2.640 + 626.000 38.042 2.638 + 626.500 37.382 2.635 + 627.000 36.773 2.633 + 627.500 37.470 2.630 + 628.000 37.399 2.632 + 628.500 37.385 2.636 + 629.000 37.289 2.641 + 629.500 36.505 2.649 + 630.000 36.615 2.650 + 630.500 36.778 2.650 + 631.000 35.650 2.642 + 631.500 36.086 2.636 + 632.000 35.813 2.632 + 632.500 35.281 2.630 + 633.000 35.004 2.634 + 633.500 34.997 2.640 + 634.000 35.161 2.642 + 634.500 34.258 2.648 + 635.000 33.202 2.648 + 635.500 32.661 2.650 + 636.000 32.292 2.650 + 636.500 32.157 2.648 + 637.000 31.139 2.644 + 637.500 29.569 2.640 + 638.000 29.588 2.642 + 638.500 29.493 2.644 + 639.000 29.343 2.643 + 639.500 28.851 2.640 + 640.000 29.770 2.639 + 640.500 30.134 2.634 + 641.000 30.170 2.634 + 641.500 30.764 2.637 + 642.000 30.087 2.640 + 642.500 29.814 2.653 + 643.000 30.395 2.656 + 643.500 30.207 2.652 + 644.000 29.320 2.649 + 644.500 30.122 2.648 + 645.000 29.366 2.651 + 645.500 30.006 2.652 + 646.000 30.070 2.650 + 646.500 30.338 2.646 + 647.000 30.416 2.644 + 647.500 30.161 2.641 + 648.000 30.782 2.639 + 648.500 28.659 2.644 + 649.000 26.882 2.644 + 649.500 24.371 2.641 + 650.000 24.093 2.641 + 650.500 23.403 2.636 + 651.000 23.174 2.634 + 651.500 23.311 2.636 + 652.000 22.527 2.632 + 652.500 23.077 2.630 + 653.000 23.066 2.626 + 653.500 22.257 2.623 + 654.000 21.371 2.621 + 654.500 21.447 2.614 + 655.000 21.589 2.609 + 655.500 22.506 2.609 + 656.000 22.585 2.611 + 656.500 23.387 2.620 + 657.000 24.831 2.625 + 657.500 25.607 2.628 + 658.000 26.499 2.628 + 658.500 27.935 2.622 + 659.000 27.819 2.615 + 659.500 28.642 2.616 + 660.000 28.727 2.616 + 660.500 28.771 2.613 + 661.000 28.744 2.610 + 661.500 28.716 2.613 + 662.000 28.804 2.617 + 662.500 28.161 2.619 + 663.000 27.262 2.617 + 663.500 25.439 2.615 + 664.000 24.798 2.614 + 664.500 24.911 2.609 + 665.000 26.133 2.609 + 665.500 27.398 2.612 + 666.000 27.517 2.622 + 666.500 30.237 2.629 + 667.000 30.197 2.628 + 667.500 30.320 2.624 + 668.000 30.483 2.614 + 668.500 29.297 2.611 + 669.000 30.850 2.618 + 669.500 31.743 2.623 + 670.000 33.407 2.640 + 670.500 34.376 2.651 + 671.000 35.014 2.656 + 671.500 35.895 2.655 + 672.000 36.038 2.652 + 672.500 35.942 2.642 + 673.000 34.988 2.646 + 673.500 34.124 2.653 + 674.000 32.686 2.670 + 674.500 31.078 2.672 + 675.000 29.863 2.673 + 675.500 29.020 2.669 + 676.000 27.460 2.666 + 676.500 27.154 2.664 + 677.000 27.122 2.662 + 677.500 27.164 2.656 + 678.000 27.842 2.651 + 678.500 29.339 2.649 + 679.000 28.881 2.648 + 679.500 30.192 2.656 + 680.000 28.713 2.655 + 680.500 27.102 2.646 + 681.000 26.391 2.636 + 681.500 25.727 2.634 + 682.000 25.627 2.635 + 682.500 25.537 2.639 + 683.000 25.530 2.638 + 683.500 26.522 2.638 + 684.000 28.092 2.641 + 684.500 27.913 2.646 + 685.000 28.087 2.650 + 685.500 28.971 2.649 + 686.000 29.737 2.645 + 686.500 30.506 2.640 + 687.000 31.184 2.642 + 687.500 31.134 2.642 + 688.000 30.330 2.642 + 688.500 29.010 2.640 + 689.000 27.450 2.642 + 689.500 27.017 2.648 + 690.000 26.295 2.650 + 690.500 26.337 2.650 + 691.000 26.987 2.650 + 691.500 27.335 2.648 + 692.000 27.515 2.647 + 692.500 26.456 2.645 + 693.000 26.353 2.642 + 693.500 26.543 2.644 + 694.000 27.282 2.644 + 694.500 27.923 2.647 + 695.000 27.213 2.648 + 695.500 28.780 2.643 + 696.000 31.670 2.638 + 696.500 33.263 2.636 + 697.000 34.223 2.632 + 697.500 34.203 2.634 + 698.000 35.620 2.632 + 698.500 31.979 2.630 + 699.000 31.748 2.628 + 699.500 31.667 2.626 + 700.000 31.393 2.625 + 700.500 32.660 2.623 + 701.000 33.429 2.621 + 701.500 35.789 2.621 + 702.000 36.882 2.623 + 702.500 41.717 2.623 + 703.000 42.021 2.626 + 703.500 43.053 2.626 + 704.000 42.810 2.628 + 704.500 40.966 2.630 + 705.000 38.325 2.636 + 705.500 37.735 2.640 + 706.000 38.353 2.638 + 706.500 41.081 2.635 + 707.000 41.268 2.634 + 707.500 42.864 2.635 + 708.000 42.881 2.645 + 708.500 42.822 2.652 + 709.000 41.396 2.654 + 709.500 41.377 2.650 + 710.000 41.204 2.648 + 710.500 40.436 2.650 + 711.000 41.172 2.651 + 711.500 41.930 2.649 + 712.000 42.196 2.650 + 712.500 39.188 2.633 + 713.000 35.891 2.633 + 713.500 32.495 2.633 + 714.000 30.301 2.635 + 714.500 26.742 2.624 + 715.000 25.670 2.607 + 715.500 24.598 2.601 + 716.000 24.837 2.599 + 716.500 22.545 2.601 + 717.000 20.889 2.605 + 717.500 19.331 2.614 + 718.000 19.322 2.621 + 718.500 19.284 2.617 + 719.000 19.207 2.608 + 719.500 20.066 2.599 + 720.000 21.023 2.599 + 720.500 20.068 2.598 + 721.000 19.181 2.597 + 721.500 19.399 2.596 + 722.000 18.612 2.600 + 722.500 18.592 2.601 + 723.000 17.857 2.605 + 723.500 17.568 2.601 + 724.000 16.758 2.596 + 724.500 17.881 2.587 + 725.000 19.428 2.577 + 725.500 19.321 2.575 + 726.000 19.087 2.576 + 726.500 20.508 2.575 + 727.000 19.952 2.581 + 727.500 22.395 2.587 + 728.000 24.035 2.590 + 728.500 24.824 2.596 + 729.000 25.578 2.601 + 729.500 26.454 2.604 + 730.000 26.397 2.606 + 730.500 26.356 2.605 + 731.000 26.416 2.602 + 731.500 26.396 2.598 + 732.000 26.210 2.597 + 732.500 25.447 2.595 + 733.000 24.029 2.593 + 733.500 22.389 2.596 + 734.000 21.644 2.599 + 734.500 20.892 2.597 + 735.000 20.006 2.581 + 735.500 20.037 2.580 + 736.000 20.196 2.577 + 736.500 19.386 2.575 + 737.000 19.232 2.573 + 737.500 17.745 2.577 + 738.000 17.791 2.578 + 738.500 17.615 2.580 + 739.000 18.341 2.581 + 739.500 18.513 2.583 + 740.000 18.651 2.588 + 740.500 19.376 2.594 + 741.000 19.365 2.594 + 741.500 20.273 2.591 + 742.000 19.401 2.587 + 742.500 19.160 2.589 + 743.000 18.395 2.590 + 743.500 18.537 2.593 + 744.000 18.539 2.592 + 744.500 18.373 2.591 + 745.000 19.188 2.588 + 745.500 19.377 2.585 + 746.000 20.720 2.585 + 746.500 21.499 2.584 + 747.000 21.746 2.581 + 747.500 23.177 2.577 + 748.000 23.190 2.576 + 748.500 23.291 2.579 + 749.000 23.048 2.582 + 749.500 22.269 2.587 + 750.000 21.044 2.591 + 750.500 20.258 2.592 + 751.000 20.057 2.585 + 751.500 20.052 2.579 + 752.000 20.110 2.576 + 752.500 20.068 2.573 + 753.000 19.923 2.570 + 753.500 19.198 2.567 + 754.000 19.364 2.570 + 754.500 19.176 2.578 + 755.000 19.926 2.579 + 755.500 20.240 2.579 + 756.000 20.908 2.579 + 756.500 21.406 2.579 + 757.000 22.234 2.581 + 757.500 23.053 2.586 + 758.000 23.807 2.593 + 758.500 24.595 2.608 + 759.000 25.442 2.608 + 759.500 25.564 2.609 + 760.000 25.766 2.609 + 760.500 26.480 2.610 + 761.000 26.577 2.616 + 761.500 27.559 2.623 + 762.000 29.322 2.628 + 762.500 33.027 2.628 + 763.000 34.060 2.629 + 763.500 36.307 2.628 + 764.000 39.949 2.635 + 764.500 43.165 2.641 + 765.000 42.918 2.637 + 765.500 42.867 2.628 + 766.000 42.484 2.620 + 766.500 42.071 2.621 + 767.000 42.118 2.624 + 767.500 42.249 2.625 + 768.000 43.266 2.627 + 768.500 47.385 2.628 + 769.000 50.158 2.628 + 769.500 52.865 2.633 + 770.000 54.296 2.638 + 770.500 57.542 2.638 + 771.000 60.827 2.638 + 771.500 63.127 2.638 + 772.000 66.641 2.638 + 772.500 70.820 2.642 + 773.000 73.842 2.648 + 773.500 79.236 2.655 + 774.000 84.339 2.660 + 774.500 93.004 2.674 + 775.000 95.848 2.675 + 775.500 95.500 2.675 + 776.000 91.503 2.669 + 776.500 87.222 2.668 + 777.000 81.902 2.666 + 777.500 79.895 2.666 + 778.000 73.247 2.668 + 778.500 67.641 2.664 + 779.000 61.195 2.660 + 779.500 58.585 2.658 + 780.000 54.895 2.655 + 780.500 51.699 2.658 + 781.000 51.575 2.658 + 781.500 51.546 2.654 + 782.000 51.503 2.650 + 782.500 52.207 2.644 + 783.000 52.799 2.642 + 783.500 54.350 2.642 + 784.000 53.165 2.642 + 784.500 51.532 2.646 + 785.000 50.527 2.648 + 785.500 50.030 2.648 + 786.000 49.879 2.645 + 786.500 53.056 2.642 + 787.000 55.997 2.639 + 787.500 59.598 2.632 + 788.000 60.052 2.626 + 788.500 61.257 2.628 + 789.000 58.215 2.618 + 789.500 57.545 2.612 + 790.000 52.829 2.609 + 790.500 50.970 2.611 + 791.000 46.157 2.625 + 791.500 43.198 2.631 + 792.000 37.861 2.639 + 792.500 31.141 2.644 + 793.000 26.931 2.646 + 793.500 26.222 2.646 + 794.000 25.206 2.642 + 794.500 24.085 2.639 + 795.000 23.307 2.636 + 795.500 21.228 2.631 + 796.000 20.246 2.627 + 796.500 20.004 2.623 + 797.000 20.125 2.619 + 797.500 20.086 2.619 + 798.000 19.757 2.619 + 798.500 18.288 2.622 + 799.000 16.906 2.622 + 799.500 15.943 2.617 + 800.000 15.237 2.602 + 800.500 15.482 2.592 + 801.000 14.665 2.589 + 801.500 14.645 2.590 + 802.000 13.901 2.593 + 802.500 13.789 2.597 + 803.000 13.741 2.603 + 803.500 13.795 2.611 + 804.000 13.739 2.619 + 804.500 14.340 2.623 + 805.000 15.092 2.625 + 805.500 16.318 2.625 + 806.000 18.127 2.624 + 806.500 20.117 2.626 + 807.000 21.526 2.629 + 807.500 21.669 2.628 + 808.000 21.674 2.628 + 808.500 21.641 2.621 + 809.000 21.520 2.619 + 809.500 21.380 2.616 + 810.000 21.234 2.617 + 810.500 21.094 2.619 + 811.000 20.953 2.629 + 811.500 20.813 2.635 + 812.000 20.673 2.637 + 812.500 20.533 2.637 + 813.000 20.393 2.636 + 813.500 20.253 2.636 + 814.000 20.113 2.636 + 814.500 19.973 2.634 + 815.000 19.833 2.637 + 815.500 19.693 2.645 + 816.000 19.553 2.644 + 816.500 19.413 2.642 + 817.000 19.273 2.631 + 817.500 19.133 2.626 + 818.000 18.993 2.624 + 818.500 18.853 2.627 + 819.000 18.713 2.637 + 819.500 18.573 2.642 + 820.000 18.433 2.648 + 820.500 18.293 2.652 + 821.000 18.153 2.658 + 821.500 18.013 2.665 + 822.000 17.873 2.665 + 822.500 17.733 2.669 + 823.000 17.593 2.670 + 823.500 17.453 2.669 + 824.000 17.313 2.667 + 824.500 17.173 2.668 + 825.000 17.033 2.677 + 825.500 16.893 2.678 + 826.000 16.753 2.678 + 826.500 16.613 2.678 + 827.000 16.473 2.676 + 827.500 16.333 2.672 + 828.000 16.193 2.671 + 828.500 16.053 2.666 + 829.000 15.913 2.658 + 829.500 15.773 2.651 + 830.000 15.633 2.648 + 830.500 15.493 2.644 + 831.000 15.353 2.644 + 831.500 15.213 2.646 + 832.000 15.073 2.649 + 832.500 14.933 2.650 + 833.000 14.793 2.652 + 833.500 14.652 2.656 + 834.000 14.509 2.658 + 834.500 14.375 2.662 + 835.000 14.230 2.667 + 835.500 14.072 2.667 + 836.000 13.988 2.662 + 836.500 13.760 2.654 + 837.000 14.290 2.649 + 837.500 15.626 2.648 + 838.000 16.142 2.647 + 838.500 16.714 2.657 + 839.000 17.561 2.664 + 839.500 17.722 2.664 + 840.000 17.772 2.664 + 840.500 17.149 2.662 + 841.000 16.341 2.662 + 841.500 15.402 2.662 + 842.000 13.885 2.661 + 842.500 13.781 2.670 + 843.000 16.054 2.679 + 843.500 17.015 2.681 + 844.000 16.295 2.682 + 844.500 16.414 2.680 + 845.000 18.009 2.683 + 845.500 18.559 2.683 + 846.000 18.412 2.680 + 846.500 19.146 2.674 + 847.000 19.792 2.670 + 847.500 21.295 2.667 + 848.000 22.314 2.667 + 848.500 22.458 2.664 + 849.000 22.365 2.662 + 849.500 20.815 2.660 + 850.000 19.674 2.662 + 850.500 19.169 2.664 + 851.000 19.961 2.665 + 851.500 20.041 2.665 + 852.000 20.103 2.666 + 852.500 20.234 2.664 + 853.000 20.874 2.666 + 853.500 21.487 2.666 + 854.000 21.623 2.667 + 854.500 21.755 2.668 + 855.000 21.012 2.671 + 855.500 20.878 2.679 + 856.000 20.699 2.683 + 856.500 19.999 2.677 + 857.000 20.145 2.675 + 857.500 19.997 2.672 + 858.000 20.672 2.670 + 858.500 20.969 2.668 + 859.000 20.230 2.669 + 859.500 19.927 2.672 + 860.000 19.199 2.680 + 860.500 19.302 2.690 + 861.000 19.317 2.696 + 861.500 19.372 2.698 + 862.000 20.731 2.701 + 862.500 21.470 2.695 + 863.000 21.667 2.695 + 863.500 21.688 2.693 + 864.000 21.623 2.693 + 864.500 21.658 2.691 + 865.000 21.756 2.688 + 865.500 20.799 2.683 + 866.000 20.651 2.677 + 866.500 20.815 2.669 + 867.000 21.040 2.662 + 867.500 20.124 2.661 + 868.000 19.917 2.658 + 868.500 17.698 2.667 + 869.000 17.527 2.667 + 869.500 17.624 2.668 + 870.000 18.892 2.668 + 870.500 20.234 2.674 + 871.000 20.048 2.674 + 871.500 19.398 2.677 + 872.000 17.759 2.677 + 872.500 17.808 2.678 + 873.000 17.062 2.674 + 873.500 16.925 2.671 + 874.000 16.947 2.666 + 874.500 16.862 2.664 + 875.000 17.492 2.665 + 875.500 18.504 2.670 + 876.000 19.279 2.672 + 876.500 18.871 2.671 + 877.000 18.608 2.672 + 877.500 18.355 2.672 + 878.000 18.062 2.671 + 878.500 17.777 2.666 + 879.000 17.535 2.660 + 879.500 17.229 2.659 + 880.000 16.876 2.647 + 880.500 17.880 2.644 + 881.000 19.435 2.646 + 881.500 19.247 2.649 + 882.000 19.392 2.655 + 882.500 18.479 2.654 + 883.000 17.588 2.652 + 883.500 16.219 2.652 + 884.000 16.051 2.650 + 884.500 15.095 2.650 + 885.000 14.374 2.651 + 885.500 13.571 2.656 + 886.000 12.804 2.667 + 886.500 12.014 2.674 + 887.000 13.034 2.670 + 887.500 14.103 2.667 + 888.000 16.139 2.668 + 888.500 18.337 2.674 + 889.000 20.092 2.679 + 889.500 21.563 2.685 + 890.000 21.730 2.691 + 890.500 21.083 2.693 + 891.000 19.959 2.684 + 891.500 15.914 2.679 + 892.000 13.786 2.682 + 892.500 12.354 2.689 + 893.000 11.730 2.691 + 893.500 11.969 2.685 + 894.000 12.743 2.677 + 894.500 13.695 2.668 + 895.000 12.765 2.661 + 895.500 13.470 2.662 + 896.000 13.890 2.665 + 896.500 16.059 2.669 + 897.000 16.932 2.670 + 897.500 18.016 2.675 + 898.000 20.192 2.679 + 898.500 20.789 2.681 + 899.000 21.530 2.679 + 899.500 21.698 2.674 + 900.000 22.679 2.672 + 900.500 23.601 2.670 + 901.000 24.066 2.674 + 901.500 24.199 2.677 + 902.000 24.350 2.683 + 902.500 22.245 2.686 + 903.000 21.671 2.682 + 903.500 20.851 2.675 + 904.000 21.333 2.669 + 904.500 23.438 2.668 + 905.000 23.351 2.677 + 905.500 24.559 2.682 + 906.000 25.924 2.681 + 906.500 25.531 2.665 + 907.000 25.611 2.663 + 907.500 26.132 2.662 + 908.000 26.984 2.667 + 908.500 27.419 2.670 + 909.000 27.825 2.669 + 909.500 27.631 2.674 + 910.000 27.459 2.681 + 910.500 27.444 2.676 + 911.000 28.642 2.671 + 911.500 28.831 2.666 + 912.000 29.798 2.665 + 912.500 30.366 2.669 + 913.000 30.257 2.674 + 913.500 30.367 2.684 + 914.000 30.432 2.688 + 914.500 31.171 2.691 + 915.000 31.321 2.689 + 915.500 31.810 2.690 + 916.000 32.364 2.686 + 916.500 30.525 2.677 + 917.000 28.743 2.673 + 917.500 27.124 2.670 + 918.000 26.106 2.669 + 918.500 26.367 2.665 + 919.000 27.478 2.665 + 919.500 28.647 2.669 + 920.000 28.372 2.673 + 920.500 26.788 2.683 + 921.000 26.127 2.684 + 921.500 24.601 2.678 + 922.000 23.859 2.677 + 922.500 23.035 2.666 + 923.000 23.656 2.670 + 923.500 24.392 2.678 + 924.000 27.347 2.687 + 924.500 29.034 2.691 + 925.000 30.890 2.685 + 925.500 32.064 2.679 + 926.000 32.787 2.680 + 926.500 35.093 2.679 + 927.000 35.891 2.674 + 927.500 35.163 2.668 + 928.000 35.604 2.669 + 928.500 34.664 2.671 + 929.000 33.294 2.672 + 929.500 32.258 2.674 + 930.000 30.979 2.673 + 930.500 27.291 2.673 + 931.000 22.711 2.671 + 931.500 21.856 2.673 + 932.000 21.761 2.674 + 932.500 21.737 2.676 + 933.000 21.654 2.674 + 933.500 22.535 2.668 + 934.000 23.004 2.664 + 934.500 23.487 2.666 + 935.000 23.193 2.666 + 935.500 23.515 2.675 + 936.000 24.763 2.686 + 936.500 25.255 2.701 + 937.000 26.246 2.703 + 937.500 26.645 2.703 + 938.000 26.549 2.703 + 938.500 24.352 2.695 + 939.000 22.200 2.688 + 939.500 21.546 2.682 + 940.000 23.652 2.681 + 940.500 21.796 2.683 + 941.000 21.509 2.682 + 941.500 21.280 2.680 + 942.000 21.740 2.681 + 942.500 23.246 2.683 + 943.000 24.059 2.687 + 943.500 25.670 2.683 + 944.000 27.274 2.684 + 944.500 29.052 2.685 + 945.000 29.520 2.691 + 945.500 30.137 2.691 + 946.000 31.317 2.688 + 946.500 30.243 2.683 + 947.000 29.916 2.678 + 947.500 30.363 2.675 + 948.000 30.315 2.672 + 948.500 30.294 2.667 + 949.000 30.560 2.669 + 949.500 31.067 2.670 + 950.000 31.834 2.673 + 950.500 32.323 2.676 + 951.000 34.331 2.677 + 951.500 34.024 2.679 + 952.000 36.465 2.678 + 952.500 36.130 2.680 + 953.000 36.667 2.681 + 953.500 37.018 2.680 + 954.000 36.642 2.683 + 954.500 36.013 2.689 + 955.000 35.633 2.690 + 955.500 35.092 2.685 + 956.000 36.438 2.682 + 956.500 35.661 2.680 + 957.000 36.001 2.680 + 957.500 34.661 2.679 + 958.000 33.063 2.683 + 958.500 33.677 2.694 + 959.000 34.051 2.700 + 959.500 34.320 2.705 + 960.000 34.256 2.704 + 960.500 34.107 2.701 + 961.000 33.248 2.702 + 961.500 32.526 2.699 + 962.000 31.028 2.700 + 962.500 28.009 2.679 + 963.000 26.598 2.669 + 963.500 25.648 2.665 + 964.000 26.230 2.664 + 964.500 26.340 2.664 + 965.000 26.425 2.666 + 965.500 26.348 2.669 + 966.000 26.230 2.670 + 966.500 24.078 2.675 + 967.000 21.574 2.680 + 967.500 21.948 2.683 + 968.000 22.094 2.684 + 968.500 25.638 2.680 + 969.000 27.593 2.682 + 969.500 28.833 2.686 + 970.000 28.467 2.690 + 970.500 28.099 2.694 + 971.000 27.712 2.694 + 971.500 26.538 2.693 + 972.000 26.383 2.687 + 972.500 26.211 2.684 + 973.000 27.373 2.680 + 973.500 28.280 2.679 + 974.000 31.167 2.681 + 974.500 33.741 2.680 + 975.000 36.938 2.682 + 975.500 39.722 2.687 + 976.000 45.028 2.688 + 976.500 48.875 2.686 + 977.000 51.338 2.679 + 977.500 51.720 2.672 + 978.000 50.257 2.666 + 978.500 48.490 2.661 + 979.000 48.538 2.660 + 979.500 50.152 2.660 + 980.000 52.365 2.666 + 980.500 52.323 2.669 + 981.000 52.365 2.668 + 981.500 52.473 2.670 + 982.000 51.588 2.669 + 982.500 50.548 2.673 + 983.000 49.940 2.678 + 983.500 47.768 2.682 + 984.000 46.199 2.681 + 984.500 43.766 2.681 + 985.000 41.987 2.682 + 985.500 38.014 2.685 + 986.000 37.381 2.689 + 986.500 35.851 2.689 + 987.000 35.690 2.688 + 987.500 35.010 2.685 + 988.000 34.391 2.681 + 988.500 34.334 2.678 + 989.000 33.572 2.676 + 989.500 33.477 2.678 + 990.000 33.426 2.677 + 990.500 33.485 2.673 + 991.000 33.369 2.671 + 991.500 34.083 2.670 + 992.000 34.185 2.673 + 992.500 34.982 2.674 + 993.000 36.589 2.672 + 993.500 40.268 2.672 + 994.000 44.193 2.673 + 994.500 51.328 2.675 + 995.000 55.199 2.674 + 995.500 58.661 2.672 + 996.000 58.578 2.669 + 996.500 56.765 2.657 + 997.000 55.110 2.655 + 997.500 51.104 2.656 + 998.000 48.838 2.661 + 998.500 42.911 2.670 + 999.000 44.021 2.668 + 999.500 45.591 2.663 + 1000.000 47.785 2.660 + 1000.500 57.598 2.666 + 1001.000 59.554 2.663 + 1001.500 60.597 2.660 + 1002.000 61.700 2.656 + 1002.500 63.431 2.651 + 1003.000 64.404 2.644 + 1003.500 63.527 2.639 + 1004.000 63.209 2.633 + 1004.500 62.650 2.637 + 1005.000 61.986 2.642 + 1005.500 61.444 2.648 + 1006.000 58.261 2.658 + 1006.500 54.439 2.663 + 1007.000 52.031 2.669 + 1007.500 51.503 2.671 + 1008.000 51.621 2.671 + 1008.500 51.528 2.670 + 1009.000 51.546 2.674 + 1009.500 51.736 2.671 + 1010.000 52.524 2.669 + 1010.500 53.790 2.670 + 1011.000 54.453 2.668 + 1011.500 55.408 2.669 + 1012.000 55.550 2.669 + 1012.500 56.700 2.668 + 1013.000 57.165 2.666 + 1013.500 58.622 2.664 + 1014.000 58.739 2.664 + 1014.500 59.233 2.669 + 1015.000 59.756 2.671 + 1015.500 61.055 2.673 + 1016.000 59.967 2.673 + 1016.500 59.464 2.669 + 1017.000 58.930 2.671 + 1017.500 57.528 2.673 + 1018.000 53.989 2.676 + 1018.500 49.251 2.679 + 1019.000 43.422 2.682 + 1019.500 39.152 2.683 + 1020.000 37.778 2.681 + 1020.500 34.792 2.677 + 1021.000 33.680 2.672 + 1021.500 32.925 2.664 + 1022.000 31.397 2.656 + 1022.500 28.109 2.654 + 1023.000 25.616 2.653 + 1023.500 24.844 2.661 + 1024.000 24.055 2.664 + 1024.500 24.755 2.663 + 1025.000 23.897 2.659 + 1025.500 23.941 2.659 + 1026.000 22.645 2.658 + 1026.500 21.828 2.669 + 1027.000 22.530 2.674 + 1027.500 24.068 2.676 + 1028.000 25.441 2.678 + 1028.500 26.015 2.665 + 1029.000 24.203 2.658 + 1029.500 23.958 2.654 + 1030.000 23.968 2.657 + 1030.500 22.885 2.672 + 1031.000 22.487 2.677 + 1031.500 23.707 2.672 + 1032.000 25.125 2.670 + 1032.500 30.696 2.664 + 1033.000 32.267 2.664 + 1033.500 34.149 2.666 + 1034.000 39.314 2.670 + 1034.500 42.947 2.669 + 1035.000 45.431 2.670 + 1035.500 46.817 2.668 + 1036.000 48.338 2.669 + 1036.500 48.910 2.671 + 1037.000 50.546 2.677 + 1037.500 50.732 2.680 + 1038.000 51.474 2.675 + 1038.500 51.539 2.667 + 1039.000 51.692 2.667 + 1039.500 50.844 2.668 + 1040.000 49.175 2.671 + 1040.500 47.825 2.674 + 1041.000 47.075 2.671 + 1041.500 45.944 2.669 + 1042.000 43.749 2.666 + 1042.500 43.201 2.664 + 1043.000 42.070 2.661 + 1043.500 41.317 2.658 + 1044.000 40.781 2.658 + 1044.500 39.788 2.655 + 1045.000 38.893 2.657 + 1045.500 38.807 2.660 + 1046.000 38.056 2.664 + 1046.500 36.736 2.668 + 1047.000 35.875 2.671 + 1047.500 34.983 2.671 + 1048.000 34.094 2.671 + 1048.500 32.550 2.666 + 1049.000 32.623 2.664 + 1049.500 33.285 2.664 + 1050.000 35.619 2.667 + 1050.500 37.396 2.674 + 1051.000 44.881 2.679 + 1051.500 46.933 2.683 + 1052.000 50.772 2.687 + 1052.500 50.909 2.688 + 1053.000 49.014 2.689 + 1053.500 47.045 2.683 + 1054.000 43.789 2.679 + 1054.500 43.784 2.676 + 1055.000 43.513 2.673 + 1055.500 42.863 2.673 + 1056.000 42.923 2.677 + 1056.500 42.780 2.679 + 1057.000 42.054 2.678 + 1057.500 41.985 2.679 + 1058.000 41.220 2.677 + 1058.500 39.189 2.672 + 1059.000 37.496 2.668 + 1059.500 37.203 2.663 + 1060.000 36.698 2.660 + 1060.500 35.214 2.660 + 1061.000 33.484 2.659 + 1061.500 29.615 2.658 + 1062.000 28.748 2.656 + 1062.500 28.689 2.653 + 1063.000 28.711 2.649 + 1063.500 28.906 2.648 + 1064.000 29.845 2.647 + 1064.500 31.804 2.650 + 1065.000 32.423 2.652 + 1065.500 32.813 2.652 + 1066.000 32.047 2.650 + 1066.500 31.737 2.649 + 1067.000 31.008 2.650 + 1067.500 31.148 2.654 + 1068.000 31.096 2.661 + 1068.500 31.094 2.667 + 1069.000 31.109 2.665 + 1069.500 31.098 2.660 + 1070.000 31.104 2.658 + 1070.500 31.106 2.655 + 1071.000 31.094 2.644 + 1071.500 31.134 2.644 + 1072.000 31.094 2.649 + 1072.500 30.986 2.661 + 1073.000 30.223 2.666 + 1073.500 30.323 2.670 + 1074.000 30.485 2.671 + 1074.500 28.605 2.673 + 1075.000 25.448 2.674 + 1075.500 21.896 2.674 + 1076.000 27.944 2.673 + 1076.500 27.788 2.670 + 1077.000 27.148 2.668 + 1077.500 26.780 2.668 + 1078.000 27.408 2.668 + 1078.500 28.562 2.678 + 1079.000 29.337 2.682 + 1079.500 29.880 2.684 + 1080.000 30.668 2.676 + 1080.500 30.690 2.664 + 1081.000 28.447 2.660 + 1081.500 24.725 2.656 + 1082.000 22.126 2.659 + 1082.500 21.656 2.668 + 1083.000 21.904 2.672 + 1083.500 21.698 2.670 + 1084.000 21.437 2.666 + 1084.500 21.611 2.662 + 1085.000 21.917 2.663 + 1085.500 22.290 2.668 + 1086.000 23.367 2.671 + 1086.500 25.504 2.676 + 1087.000 28.160 2.681 + 1087.500 30.547 2.685 + 1088.000 32.385 2.684 + 1088.500 33.760 2.675 + 1089.000 34.633 2.676 + 1089.500 34.904 2.676 + 1090.000 34.898 2.673 + 1090.500 35.122 2.671 + 1091.000 35.533 2.669 + 1091.500 35.578 2.670 + 1092.000 35.042 2.669 + 1092.500 34.305 2.665 + 1093.000 33.759 2.663 + 1093.500 33.478 2.660 + 1094.000 33.411 2.658 + 1094.500 33.465 2.658 + 1095.000 33.581 2.654 + 1095.500 33.934 2.653 + 1096.000 34.819 2.653 + 1096.500 36.191 2.653 + 1097.000 37.632 2.652 + 1097.500 38.835 2.653 + 1098.000 39.910 2.659 + 1098.500 41.147 2.669 + 1099.000 42.586 2.676 + 1099.500 43.776 2.678 + 1100.000 44.038 2.679 + 1100.500 43.143 2.681 + 1101.000 41.676 2.683 + 1101.500 40.545 2.688 + 1102.000 40.134 2.696 + 1102.500 39.984 2.703 + 1103.000 39.466 2.706 + 1103.500 38.847 2.706 + 1104.000 39.280 2.706 + 1104.500 41.361 2.705 + 1105.000 44.145 2.700 + 1105.500 46.090 2.694 + 1106.000 46.494 2.689 + 1106.500 45.480 2.687 + 1107.000 43.180 2.686 + 1107.500 39.631 2.687 + 1108.000 35.241 2.692 + 1108.500 30.846 2.699 + 1109.000 27.366 2.701 + 1109.500 25.353 2.700 + 1110.000 24.673 2.705 + 1110.500 24.664 2.721 + 1111.000 24.759 2.738 + 1111.500 24.750 2.740 + 1112.000 24.535 2.723 + 1112.500 24.085 2.700 + 1113.000 23.655 2.694 + 1113.500 23.510 2.718 + 1114.000 23.499 2.760 + 1114.500 23.331 2.794 + 1115.000 23.096 2.805 + 1115.500 23.079 2.802 + 1116.000 23.189 2.802 + 1116.500 23.016 2.808 + 1117.000 22.409 2.812 + 1117.500 21.687 2.810 + 1118.000 21.228 2.807 + 1118.500 21.045 2.809 + 1119.000 20.819 2.816 + 1119.500 20.404 2.826 + 1120.000 20.153 2.836 + 1120.500 20.453 2.841 + 1121.000 21.037 2.837 + 1121.500 21.320 2.830 + 1122.000 21.515 2.830 + 1122.500 22.548 2.840 + 1123.000 24.708 2.846 + 1123.500 27.130 2.838 + 1124.000 28.869 2.818 + 1124.500 29.690 2.801 + 1125.000 29.854 2.796 + 1125.500 30.178 2.798 + 1126.000 31.786 2.800 + 1126.500 34.386 2.799 + 1127.000 35.894 2.801 + 1127.500 35.775 2.798 + 1128.000 37.023 2.780 + 1128.500 41.864 2.753 + 1129.000 47.350 2.734 + 1129.500 48.811 2.727 + 1130.000 46.164 2.723 + 1130.500 43.089 2.719 + 1131.000 41.298 2.726 + 1131.500 39.431 2.742 + 1132.000 36.744 2.755 + 1132.500 34.343 2.757 + 1133.000 32.787 2.759 + 1133.500 30.966 2.766 + 1134.000 27.942 2.774 + 1134.500 24.642 2.782 + 1135.000 23.012 2.798 + 1135.500 23.666 2.814 + 1136.000 25.159 2.815 + 1136.500 26.235 2.801 + 1137.000 27.723 2.786 + 1137.500 30.680 2.781 + 1138.000 33.760 2.777 + 1138.500 34.633 2.775 + 1139.000 33.465 2.782 + 1139.500 32.648 2.803 + 1140.000 33.329 2.820 + 1140.500 34.399 2.818 + 1141.000 34.865 2.800 + 1141.500 35.117 2.780 + 1142.000 35.530 2.769 + 1142.500 35.522 2.769 + 1143.000 34.438 2.775 + 1143.500 32.424 2.782 + 1144.000 30.388 2.788 + 1144.500 29.584 2.790 + 1145.000 30.928 2.789 + 1145.500 33.934 2.786 + 1146.000 36.760 2.778 + 1146.500 37.845 2.765 + 1147.000 37.126 2.753 + 1147.500 35.567 2.748 + 1148.000 34.038 2.749 + 1148.500 32.699 2.752 + 1149.000 31.220 2.755 + 1149.500 29.804 2.761 + 1150.000 29.717 2.767 + 1150.500 31.825 2.771 + 1151.000 34.903 2.774 + 1151.500 36.708 2.781 + 1152.000 36.483 2.791 + 1152.500 35.204 2.802 + 1153.000 33.945 2.808 + 1153.500 33.353 2.808 + 1154.000 33.875 2.797 + 1154.500 35.135 2.782 + 1155.000 35.893 2.770 + 1155.500 35.505 2.764 + 1156.000 34.503 2.765 + 1156.500 33.228 2.774 + 1157.000 31.327 2.790 + 1157.500 29.100 2.802 + 1158.000 27.942 2.805 + 1158.500 28.855 2.803 + 1159.000 31.371 2.803 + 1159.500 34.076 2.801 + 1160.000 35.680 2.787 + 1160.500 35.597 2.769 + 1161.000 34.016 2.761 + 1161.500 31.522 2.770 + 1162.000 28.738 2.826 + 1162.500 26.487 2.814 + 1163.000 25.732 2.824 + 1163.500 26.752 2.819 + 1164.000 28.648 2.813 + 1164.500 30.229 2.802 + 1165.000 34.155 2.791 + 1165.500 32.331 2.777 + 1166.000 32.198 2.772 + 1166.500 31.724 2.775 + 1167.000 31.853 2.779 + 1167.500 32.730 2.780 + 1168.000 33.484 2.791 + 1168.500 33.424 2.796 + 1169.000 31.928 2.797 + 1169.500 31.911 2.791 + 1170.000 32.586 2.782 + 1170.500 34.071 2.780 + 1171.000 35.697 2.772 + 1171.500 36.492 2.767 + 1172.000 35.902 2.765 + 1172.500 34.618 2.745 + 1173.000 31.743 2.740 + 1173.500 30.077 2.743 + 1174.000 26.688 2.761 + 1174.500 24.058 2.790 + 1175.000 21.824 2.812 + 1175.500 21.650 2.826 + 1176.000 21.674 2.839 + 1176.500 21.602 2.849 + 1177.000 21.659 2.854 + 1177.500 21.790 2.854 + 1178.000 22.519 2.849 + 1178.500 22.410 2.839 + 1179.000 22.444 2.830 + 1179.500 22.449 2.808 + 1180.000 22.434 2.807 + 1180.500 22.439 2.810 + 1181.000 22.432 2.815 + 1181.500 22.419 2.821 + 1182.000 22.452 2.820 + 1182.500 22.389 2.829 + 1183.000 22.401 2.832 + 1183.500 23.208 2.842 + 1184.000 24.982 2.856 + 1184.500 31.186 2.864 + 1185.000 34.706 2.865 + 1185.500 38.625 2.862 + 1186.000 41.068 2.828 + 1186.500 42.281 2.799 + 1187.000 41.754 2.763 + 1187.500 39.043 2.750 + 1188.000 38.039 2.740 + 1188.500 37.115 2.745 + 1189.000 36.615 2.749 + 1189.500 36.710 2.759 + 1190.000 37.542 2.765 + 1190.500 38.071 2.769 + 1191.000 36.626 2.770 + 1191.500 35.124 2.759 + 1192.000 34.172 2.748 + 1192.500 32.432 2.748 + 1193.000 30.870 2.759 + 1193.500 29.634 2.774 + 1194.000 28.190 2.778 + 1194.500 26.381 2.793 + 1195.000 26.995 2.802 + 1195.500 28.462 2.793 + 1196.000 30.424 2.789 + 1196.500 31.762 2.753 + 1197.000 34.625 2.747 + 1197.500 36.064 2.744 + 1198.000 39.462 2.745 + 1198.500 42.020 2.752 + 1199.000 41.577 2.760 + 1199.500 40.864 2.766 + 1200.000 41.605 2.767 + 1200.500 42.006 2.764 + 1201.000 42.141 2.759 + 1201.500 41.989 2.757 + 1202.000 41.366 2.749 + 1202.500 40.513 2.742 + 1203.000 40.298 2.731 + 1203.500 38.152 2.733 + 1204.000 36.073 2.740 + 1204.500 33.761 2.754 + 1205.000 30.405 2.763 + 1205.500 28.110 2.770 + 1206.000 26.397 2.783 + 1206.500 27.096 2.795 + 1207.000 28.697 2.790 + 1207.500 30.997 2.777 + 1208.000 32.531 2.771 + 1208.500 32.604 2.769 + 1209.000 31.182 2.776 + 1209.500 31.042 2.781 + 1210.000 30.692 2.785 + 1210.500 33.150 2.778 + 1211.000 35.020 2.768 + 1211.500 36.848 2.768 + 1212.000 38.074 2.768 + 1212.500 40.326 2.782 + 1213.000 40.531 2.788 + 1213.500 40.857 2.786 + 1214.000 40.489 2.785 + 1214.500 37.807 2.787 + 1215.000 32.571 2.800 + 1215.500 30.369 2.810 + 1216.000 28.836 2.825 + 1216.500 30.417 2.832 + 1217.000 31.086 2.820 + 1217.500 31.739 2.813 + 1218.000 34.066 2.798 + 1218.500 36.454 2.779 + 1219.000 38.037 2.765 + 1219.500 39.110 2.749 + 1220.000 40.934 2.740 + 1220.500 40.712 2.732 + 1221.000 38.828 2.721 + 1221.500 38.027 2.710 + 1222.000 34.999 2.716 + 1222.500 34.332 2.722 + 1223.000 33.594 2.722 + 1223.500 33.428 2.718 + 1224.000 33.544 2.710 + 1224.500 32.843 2.707 + 1225.000 32.446 2.704 + 1225.500 32.473 2.714 + 1226.000 32.609 2.720 + 1226.500 33.266 2.733 + 1227.000 32.466 2.727 + 1227.500 32.700 2.721 + 1228.000 31.539 2.718 + 1228.500 31.384 2.713 + 1229.000 28.736 2.720 + 1229.500 27.956 2.720 + 1230.000 27.088 2.722 + 1230.500 25.948 2.722 + 1231.000 25.575 2.727 + 1231.500 25.805 2.729 + 1232.000 28.397 2.734 + 1232.500 30.536 2.753 + 1233.000 29.629 2.765 + 1233.500 27.240 2.784 + 1234.000 25.732 2.798 + 1234.500 22.876 2.826 + 1235.000 21.959 2.835 + 1235.500 22.451 2.822 + 1236.000 22.549 2.804 + 1236.500 23.948 2.786 + 1237.000 26.091 2.744 + 1237.500 28.900 2.739 + 1238.000 30.377 2.728 + 1238.500 33.085 2.728 + 1239.000 33.427 2.739 + 1239.500 33.546 2.750 + 1240.000 33.351 2.753 + 1240.500 31.845 2.752 + 1241.000 30.637 2.747 + 1241.500 30.298 2.743 + 1242.000 30.147 2.740 + 1242.500 30.018 2.734 + 1243.000 30.808 2.725 + 1243.500 30.281 2.721 + 1244.000 30.397 2.723 + 1244.500 29.293 2.737 + 1245.000 26.748 2.754 + 1245.500 26.047 2.761 + 1246.000 24.834 2.769 + 1246.500 23.357 2.794 + 1247.000 22.446 2.815 + 1247.500 21.791 2.828 + 1248.000 21.578 2.834 + 1248.500 22.274 2.833 + 1249.000 22.507 2.824 + 1249.500 24.021 2.817 + 1250.000 25.690 2.810 + 1250.500 28.526 2.804 + 1251.000 30.190 2.794 + 1251.500 30.537 2.789 + 1252.000 30.681 2.780 + 1252.500 31.246 2.775 + 1253.000 30.383 2.782 + 1253.500 30.404 2.793 + 1254.000 30.315 2.795 + 1254.500 32.408 2.794 + 1255.000 33.191 2.777 + 1255.500 34.326 2.765 + 1256.000 35.091 2.752 + 1256.500 34.927 2.751 + 1257.000 33.616 2.750 + 1257.500 32.889 2.752 + 1258.000 32.611 2.752 + 1258.500 32.759 2.750 + 1259.000 32.103 2.749 + 1259.500 31.627 2.737 + 1260.000 31.520 2.730 + 1260.500 30.085 2.728 + 1261.000 28.700 2.730 + 1261.500 26.307 2.747 + 1262.000 26.358 2.768 + 1262.500 27.286 2.810 + 1263.000 29.446 2.817 + 1263.500 32.350 2.819 + 1264.000 34.291 2.812 + 1264.500 35.196 2.793 + 1265.000 34.919 2.751 + 1265.500 35.710 2.756 + 1266.000 35.839 2.752 + 1266.500 35.858 2.747 + 1267.000 35.897 2.740 + 1267.500 35.113 2.733 + 1268.000 33.518 2.722 + 1268.500 31.119 2.703 + 1269.000 28.132 2.709 + 1269.500 25.034 2.729 + 1270.000 22.767 2.750 + 1270.500 16.757 2.774 + 1271.000 15.176 2.786 + 1271.500 15.936 2.792 + 1272.000 16.380 2.794 + 1272.500 18.421 2.718 + 1273.000 19.301 2.723 + 1273.500 21.222 2.724 + 1274.000 22.986 2.731 + 1274.500 28.912 2.786 + 1275.000 30.346 2.777 + 1275.500 31.162 2.770 + 1276.000 34.050 2.757 + 1276.500 35.123 2.786 + 1277.000 36.679 2.802 + 1277.500 36.501 2.801 + 1278.000 36.487 2.790 + 1278.500 33.574 2.788 + 1279.000 31.978 2.789 + 1279.500 31.681 2.790 + 1280.000 29.486 2.788 + 1280.500 29.598 2.782 + 1281.000 29.818 2.765 + 1281.500 31.018 2.754 + 1282.000 30.782 2.748 + 1282.500 30.335 2.723 + 1283.000 30.406 2.716 + 1283.500 29.639 2.728 + 1284.000 29.619 2.733 + 1284.500 28.885 2.778 + 1285.000 28.627 2.789 + 1285.500 27.503 2.790 + 1286.000 26.164 2.790 + 1286.500 25.058 2.803 + 1287.000 25.042 2.809 + 1287.500 22.580 2.812 + 1288.000 26.938 2.809 + 1288.500 32.201 2.796 + 1289.000 37.153 2.743 + 1289.500 38.223 2.737 + 1290.000 37.966 2.731 + 1290.500 33.931 2.730 + 1291.000 29.117 2.732 + 1291.500 27.390 2.740 + 1292.000 27.973 2.754 + 1292.500 29.264 2.778 + 1293.000 30.391 2.779 + 1293.500 30.465 2.776 + 1294.000 31.164 2.768 + 1294.500 31.018 2.756 + 1295.000 31.763 2.754 + 1295.500 34.026 2.755 + 1296.000 35.680 2.758 + 1296.500 38.598 2.754 + 1297.000 38.959 2.755 + 1297.500 39.082 2.760 + 1298.000 38.744 2.768 + 1298.500 38.068 2.775 + 1299.000 36.855 2.779 + 1299.500 37.538 2.781 + 1300.000 36.720 2.781 + 1300.500 35.233 2.776 + 1301.000 36.586 2.770 + 1301.500 36.496 2.770 + 1302.000 37.290 2.768 + 1302.500 37.241 2.768 + 1303.000 36.534 2.755 + 1303.500 35.782 2.747 + 1304.000 36.606 2.740 + 1304.500 35.214 2.735 + 1305.000 33.770 2.729 + 1305.500 31.786 2.721 + 1306.000 31.293 2.711 + 1306.500 29.203 2.702 + 1307.000 28.080 2.694 + 1307.500 26.213 2.690 + 1308.000 25.504 2.685 + 1308.500 25.032 2.680 + 1309.000 24.799 2.675 + 1309.500 25.570 2.669 + 1310.000 25.711 2.668 + 1310.500 26.460 2.670 + 1311.000 26.323 2.672 + 1311.500 27.039 2.675 + 1312.000 29.234 2.681 + 1312.500 30.154 2.690 + 1313.000 30.383 2.692 + 1313.500 30.216 2.691 + 1314.000 31.034 2.688 + 1314.500 30.476 2.687 + 1315.000 29.725 2.688 + 1315.500 27.354 2.694 + 1316.000 26.854 2.706 + 1316.500 25.697 2.719 + 1317.000 25.647 2.727 + 1317.500 27.248 2.729 + 1318.000 28.163 2.728 + 1318.500 28.665 2.724 + 1319.000 27.693 2.719 + 1319.500 26.829 2.713 + 1320.000 25.942 2.705 + 1320.500 25.267 2.697 + 1321.000 23.874 2.691 + 1321.500 23.943 2.691 + 1322.000 24.871 2.691 + 1322.500 25.136 2.689 + 1323.000 25.766 2.687 + 1323.500 26.720 2.687 + 1324.000 28.465 2.689 + 1324.500 31.247 2.691 + 1325.000 32.725 2.693 + 1325.500 35.188 2.693 + 1326.000 36.529 2.695 + 1326.500 37.261 2.697 + 1327.000 37.247 2.701 + 1327.500 33.840 2.706 + 1328.000 31.809 2.713 + 1328.500 26.727 2.752 + 1329.000 25.642 2.781 + 1329.500 25.354 2.784 + 1330.000 25.596 2.783 + 1330.500 26.935 2.783 + 1331.000 27.183 2.781 + 1331.500 28.664 2.776 + 1332.000 28.841 2.770 + 1332.500 29.794 2.744 + 1333.000 30.329 2.728 + 1333.500 30.833 2.719 + 1334.000 31.715 2.721 + 1334.500 32.131 2.732 + 1335.000 32.796 2.736 + 1335.500 33.992 2.740 + 1336.000 33.639 2.734 + 1336.500 35.463 2.720 + 1337.000 35.147 2.709 + 1337.500 35.775 2.711 + 1338.000 34.576 2.723 + 1338.500 34.951 2.728 + 1339.000 38.635 2.735 + 1339.500 40.110 2.740 + 1340.000 42.092 2.755 + 1340.500 42.152 2.755 + 1341.000 41.364 2.750 + 1341.500 40.143 2.742 + 1342.000 37.144 2.726 + 1342.500 35.026 2.710 + 1343.000 33.957 2.693 + 1343.500 33.190 2.685 + 1344.000 31.616 2.677 + 1344.500 30.729 2.676 + 1345.000 29.267 2.677 + 1345.500 26.353 2.677 + 1346.000 25.498 2.677 + 1346.500 22.082 2.683 + 1347.000 21.941 2.688 + 1347.500 21.343 2.695 + 1348.000 21.486 2.707 + 1348.500 21.571 2.713 + 1349.000 22.477 2.712 + 1349.500 23.132 2.706 + 1350.000 24.709 2.700 + 1350.500 24.849 2.695 + 1351.000 24.258 2.688 + 1351.500 24.770 2.681 + 1352.000 25.572 2.681 + 1352.500 26.774 2.683 + 1353.000 27.459 2.689 + 1353.500 28.203 2.693 + 1354.000 28.946 2.707 + 1354.500 29.019 2.712 + 1355.000 28.146 2.725 + 1355.500 27.051 2.730 + 1356.000 25.716 2.734 + 1356.500 25.551 2.739 + 1357.000 25.613 2.740 + 1357.500 27.791 2.733 + 1358.000 30.729 2.730 + 1358.500 34.682 2.725 + 1359.000 36.394 2.723 + 1359.500 36.693 2.723 + 1360.000 33.905 2.716 + 1360.500 29.106 2.703 + 1361.000 24.512 2.697 + 1361.500 20.652 2.690 + 1362.000 19.701 2.686 + 1362.500 21.129 2.685 + 1363.000 21.461 2.690 + 1363.500 20.900 2.692 + 1364.000 20.779 2.691 + 1364.500 22.270 2.699 + 1365.000 23.230 2.703 + 1365.500 25.617 2.703 + 1366.000 25.723 2.701 + 1366.500 26.501 2.699 + 1367.000 27.890 2.697 + 1367.500 28.020 2.694 + 1368.000 29.459 2.690 + 1368.500 31.810 2.689 + 1369.000 32.812 2.686 + 1369.500 34.242 2.683 + 1370.000 35.916 2.676 + 1370.500 36.679 2.670 + 1371.000 38.817 2.666 + 1371.500 40.733 2.666 + 1372.000 42.443 2.668 + 1372.500 43.595 2.670 + 1373.000 45.747 2.676 + 1373.500 46.713 2.680 + 1374.000 46.881 2.689 + 1374.500 46.862 2.698 + 1375.000 46.849 2.709 + 1375.500 46.867 2.714 + 1376.000 46.851 2.716 + 1376.500 46.866 2.720 + 1377.000 46.872 2.724 + 1377.500 46.821 2.722 + 1378.000 46.961 2.717 + 1378.500 46.266 2.708 + 1379.000 45.259 2.704 + 1379.500 42.764 2.709 + 1380.000 41.214 2.720 + 1380.500 37.237 2.723 + 1381.000 34.112 2.720 + 1381.500 28.687 2.711 + 1382.000 25.451 2.701 + 1382.500 22.324 2.690 + 1383.000 22.474 2.683 + 1383.500 22.520 2.674 + 1384.000 24.025 2.673 + 1384.500 25.333 2.678 + 1385.000 26.997 2.688 + 1385.500 28.046 2.691 + 1386.000 27.959 2.694 + 1386.500 27.927 2.686 + 1387.000 28.016 2.673 + 1387.500 27.880 2.667 + 1388.000 28.492 2.661 + 1388.500 27.124 2.662 + 1389.000 25.916 2.669 + 1389.500 25.874 2.676 + 1390.000 24.826 2.686 + 1390.500 23.412 2.690 + 1391.000 23.239 2.686 + 1391.500 23.238 2.676 + 1392.000 23.125 2.669 + 1392.500 24.021 2.670 + 1393.000 25.020 2.670 + 1393.500 25.665 2.671 + 1394.000 25.543 2.669 + 1394.500 25.610 2.673 + 1395.000 25.579 2.675 + 1395.500 25.571 2.685 + 1396.000 25.662 2.692 + 1396.500 24.864 2.695 + 1397.000 25.638 2.695 + 1397.500 26.264 2.693 + 1398.000 28.395 2.695 + 1398.500 31.886 2.694 + 1399.000 33.080 2.692 + 1399.500 34.644 2.689 + 1400.000 36.007 2.692 + 1400.500 35.015 2.687 + 1401.000 33.589 2.682 + 1401.500 32.292 2.681 + 1402.000 31.905 2.685 + 1402.500 31.880 2.686 + 1403.000 33.182 2.692 + 1403.500 34.217 2.691 + 1404.000 35.454 2.689 + 1404.500 36.781 2.691 + 1405.000 36.430 2.690 + 1405.500 37.521 2.687 + 1406.000 37.769 2.678 + 1406.500 38.344 2.671 + 1407.000 37.432 2.666 + 1407.500 35.812 2.666 + 1408.000 34.236 2.670 + 1408.500 31.034 2.676 + 1409.000 30.173 2.684 + 1409.500 27.072 2.683 + 1410.000 26.184 2.674 + 1410.500 22.888 2.665 + 1411.000 23.815 2.654 + 1411.500 24.643 2.656 + 1412.000 28.559 2.656 + 1412.500 33.722 2.661 + 1413.000 39.725 2.664 + 1413.500 44.642 2.666 + 1414.000 50.433 2.673 + 1414.500 50.898 2.675 + 1415.000 51.757 2.691 + 1415.500 51.443 2.693 + 1416.000 52.561 2.694 + 1416.500 55.145 2.691 + 1417.000 57.073 2.684 + 1417.500 59.294 2.679 + 1418.000 60.951 2.680 + 1418.500 61.052 2.692 + 1419.000 61.073 2.696 + 1419.500 60.300 2.705 + 1420.000 56.571 2.706 + 1420.500 53.005 2.696 + 1421.000 50.292 2.692 + 1421.500 49.283 2.690 + 1422.000 47.842 2.688 + 1422.500 45.530 2.685 + 1423.000 44.545 2.675 + 1423.500 43.510 2.671 + 1424.000 42.292 2.670 + 1424.500 41.063 2.675 + 1425.000 40.528 2.686 + 1425.500 40.575 2.686 + 1426.000 40.544 2.687 + 1426.500 40.226 2.679 + 1427.000 38.753 2.677 + 1427.500 37.464 2.674 + 1428.000 37.579 2.672 + 1428.500 38.649 2.669 + 1429.000 40.957 2.670 + 1429.500 41.428 2.670 + 1430.000 42.933 2.673 + 1430.500 44.857 2.674 + 1431.000 45.339 2.674 + 1431.500 46.221 2.674 + 1432.000 43.438 2.673 + 1432.500 38.252 2.674 + 1433.000 33.132 2.674 + 1433.500 31.706 2.676 + 1434.000 30.190 2.677 + 1434.500 30.466 2.681 + 1435.000 31.239 2.685 + 1435.500 32.699 2.683 + 1436.000 33.647 2.681 + 1436.500 34.354 2.675 + 1437.000 34.132 2.671 + 1437.500 34.964 2.673 + 1438.000 36.734 2.678 + 1438.500 37.375 2.678 + 1439.000 38.016 2.675 + 1439.500 38.330 2.668 + 1440.000 39.237 2.670 + 1440.500 40.039 2.678 + 1441.000 41.805 2.689 + 1441.500 42.798 2.699 + 1442.000 42.686 2.703 + 1442.500 42.271 2.702 + 1443.000 40.271 2.700 + 1443.500 40.277 2.694 + 1444.000 35.124 2.693 + 1444.500 33.621 2.693 + 1445.000 31.189 2.693 + 1445.500 30.325 2.702 + 1446.000 28.459 2.702 + 1446.500 20.740 2.733 + 1447.000 13.868 2.742 + 1447.500 9.696 2.738 + 1448.000 8.743 2.732 + 1448.500 7.288 2.715 + 1449.000 7.664 2.713 + 1449.500 8.329 2.710 + 1450.000 8.206 2.710 + 1450.500 8.272 2.702 + 1451.000 8.266 2.693 + 1451.500 8.262 2.686 + 1452.000 8.269 2.681 + 1452.500 8.266 2.683 + 1453.000 8.277 2.690 + 1453.500 8.251 2.702 + 1454.000 8.274 2.703 + 1454.500 8.393 2.705 + 1455.000 9.207 2.702 + 1455.500 8.376 2.690 + 1456.000 8.418 2.684 + 1456.500 9.161 2.678 + 1457.000 8.815 2.673 + 1457.500 8.584 2.672 + 1458.000 8.860 2.675 + 1458.500 9.034 2.685 + 1459.000 9.068 2.687 + 1459.500 9.233 2.689 + 1460.000 12.266 2.690 + 1460.500 18.275 2.691 + 1461.000 23.775 2.692 + 1461.500 28.988 2.695 + 1462.000 29.540 2.704 + 1462.500 31.103 2.705 + 1463.000 31.060 2.702 + 1463.500 31.145 2.694 + 1464.000 31.259 2.689 + 1464.500 31.979 2.683 + 1465.000 31.869 2.676 + 1465.500 31.893 2.673 + 1466.000 31.901 2.674 + 1466.500 31.892 2.674 + 1467.000 31.887 2.677 + 1467.500 31.902 2.677 + 1468.000 31.904 2.677 + 1468.500 31.756 2.677 + 1469.000 30.860 2.671 + 1469.500 30.198 2.670 + 1470.000 28.702 2.669 + 1470.500 27.663 2.668 + 1471.000 27.179 2.657 + 1471.500 27.193 2.645 + 1472.000 27.010 2.637 + 1472.500 26.124 2.641 + 1473.000 25.562 2.639 + 1473.500 25.640 2.635 + 1474.000 25.310 2.635 + 1474.500 26.076 2.636 + 1475.000 27.807 2.640 + 1475.500 26.837 2.649 + 1476.000 26.921 2.652 + 1476.500 26.101 2.651 + 1477.000 24.822 2.648 + 1477.500 24.082 2.647 + 1478.000 24.709 2.650 + 1478.500 24.538 2.651 + 1479.000 24.689 2.652 + 1479.500 24.017 2.649 + 1480.000 23.818 2.644 + 1480.500 23.021 2.631 + 1481.000 21.354 2.623 + 1481.500 20.652 2.622 + 1482.000 20.779 2.622 + 1482.500 15.531 2.620 + 1483.000 10.709 2.615 + 1483.500 4.960 2.610 + 1484.000 -0.326 2.586 + 1484.500 1.255 2.547 + 1485.000 3.704 2.486 + 1485.500 6.135 2.479 + 1486.000 8.544 2.512 + 1486.500 10.967 2.534 + 1487.000 13.391 2.551 + 1487.500 15.814 2.562 + 1488.000 18.247 2.577 + 1488.500 20.647 2.590 + 1489.000 23.078 2.603 + 1489.500 25.529 2.617 + 1490.000 27.765 2.630 + 1490.500 30.123 2.644 + 1491.000 30.267 2.652 + 1491.500 30.290 2.660 + 1492.000 28.761 2.660 + 1492.500 27.758 2.660 + 1493.000 27.185 2.662 + 1493.500 28.723 2.661 + 1494.000 30.973 2.664 + 1494.500 34.317 2.671 + 1495.000 37.048 2.678 + 1495.500 39.317 2.676 + 1496.000 40.509 2.669 + 1496.500 42.002 2.666 + 1497.000 42.308 2.666 + 1497.500 41.470 2.664 + 1498.000 40.340 2.666 + 1498.500 33.358 2.668 + 1499.000 29.809 2.674 + 1499.500 21.206 2.678 + 1500.000 21.641 2.680 + 1500.500 20.857 2.705 + 1501.000 21.396 2.715 + 1501.500 22.533 2.720 + 1502.000 22.319 2.698 + 1502.500 21.175 2.678 + 1503.000 19.048 2.674 + 1503.500 16.816 2.674 + 1504.000 15.553 2.676 + 1504.500 14.896 2.666 + 1505.000 15.294 2.662 + 1505.500 15.946 2.650 + 1506.000 16.927 2.647 + 1506.500 18.967 2.649 + 1507.000 20.924 2.652 + 1507.500 22.770 2.660 + 1508.000 23.196 2.668 + 1508.500 23.430 2.667 + 1509.000 22.938 2.663 + 1509.500 21.756 2.664 + 1510.000 20.718 2.668 + 1510.500 19.781 2.675 + 1511.000 19.166 2.671 + 1511.500 19.924 2.664 + 1512.000 20.220 2.662 + 1512.500 20.969 2.663 + 1513.000 20.822 2.669 + 1513.500 20.824 2.671 + 1514.000 20.951 2.669 + 1514.500 20.245 2.663 + 1515.000 20.272 2.659 + 1515.500 20.667 2.671 + 1516.000 21.102 2.678 + 1516.500 24.505 2.687 + 1517.000 28.336 2.690 + 1517.500 30.361 2.689 + 1518.000 31.782 2.683 + 1518.500 30.313 2.673 + 1519.000 29.670 2.670 + 1519.500 29.393 2.665 + 1520.000 28.426 2.662 + 1520.500 25.648 2.661 + 1521.000 21.671 2.667 + 1521.500 18.222 2.675 + 1522.000 16.033 2.675 + 1522.500 14.697 2.676 + 1523.000 14.083 2.671 + 1523.500 14.717 2.669 + 1524.000 16.354 2.672 + 1524.500 19.501 2.680 + 1525.000 20.284 2.684 + 1525.500 20.843 2.681 + 1526.000 21.325 2.673 + 1526.500 20.832 2.661 + 1527.000 20.300 2.651 + 1527.500 20.163 2.636 + 1528.000 21.025 2.632 + 1528.500 22.737 2.640 + 1529.000 25.628 2.664 + 1529.500 27.892 2.685 + 1530.000 28.618 2.684 + 1530.500 30.146 2.676 + 1531.000 32.162 2.668 + 1531.500 35.955 2.664 + 1532.000 38.780 2.664 + 1532.500 39.122 2.666 + 1533.000 37.398 2.668 + 1533.500 33.781 2.670 + 1534.000 29.978 2.672 + 1534.500 27.170 2.668 + 1535.000 25.414 2.670 + 1535.500 25.268 2.674 + 1536.000 24.804 2.678 + 1536.500 26.281 2.673 + 1537.000 26.965 2.665 + 1537.500 27.190 2.657 + 1538.000 27.060 2.651 + 1538.500 26.112 2.659 + 1539.000 25.467 2.670 + 1539.500 24.024 2.675 + 1540.000 22.425 2.675 + 1540.500 21.353 2.671 + 1541.000 20.132 2.671 + 1541.500 20.131 2.668 + 1542.000 20.116 2.660 + 1542.500 22.098 2.655 + 1543.000 26.009 2.663 + 1543.500 29.561 2.672 + 1544.000 32.762 2.678 + 1544.500 34.557 2.677 + 1545.000 32.974 2.671 + 1545.500 29.920 2.667 + 1546.000 26.251 2.656 + 1546.500 22.029 2.654 + 1547.000 20.694 2.657 + 1547.500 19.835 2.659 + 1548.000 21.048 2.660 + 1548.500 22.776 2.661 + 1549.000 25.346 2.663 + 1549.500 28.358 2.668 + 1550.000 28.758 2.675 + 1550.500 29.408 2.676 + 1551.000 28.896 2.680 + 1551.500 28.905 2.685 + 1552.000 29.715 2.688 + 1552.500 31.019 2.681 + 1553.000 33.315 2.670 + 1553.500 35.179 2.663 + 1554.000 37.513 2.657 + 1554.500 36.434 2.656 + 1555.000 34.122 2.657 + 1555.500 31.187 2.659 + 1556.000 29.537 2.661 + 1556.500 28.546 2.663 + 1557.000 29.404 2.666 + 1557.500 32.002 2.662 + 1558.000 33.900 2.660 + 1558.500 36.751 2.653 + 1559.000 38.083 2.660 + 1559.500 39.754 2.664 + 1560.000 40.389 2.675 + 1560.500 42.091 2.676 + 1561.000 42.272 2.665 + 1561.500 43.143 2.647 + 1562.000 43.897 2.649 + 1562.500 45.287 2.664 + 1563.000 46.522 2.689 + 1563.500 46.112 2.699 + 1564.000 42.709 2.696 + 1564.500 39.246 2.682 + 1565.000 35.868 2.681 + 1565.500 36.045 2.678 + 1566.000 36.781 2.659 + 1566.500 37.285 2.654 + 1567.000 36.450 2.650 + 1567.500 37.170 2.652 + 1568.000 37.856 2.653 + 1568.500 39.770 2.657 + 1569.000 42.568 2.674 + 1569.500 49.858 2.681 + 1570.000 59.187 2.693 + 1570.500 68.661 2.697 + 1571.000 75.211 2.699 + 1571.500 74.678 2.700 + 1572.000 72.858 2.705 + 1572.500 63.569 2.714 + 1573.000 57.740 2.718 + 1573.500 50.262 2.713 + 1574.000 47.891 2.706 + 1574.500 46.052 2.701 + 1575.000 46.745 2.694 + 1575.500 49.761 2.695 + 1576.000 57.103 2.697 + 1576.500 62.098 2.694 + 1577.000 66.993 2.687 + 1577.500 66.736 2.683 + 1578.000 63.284 2.692 + 1578.500 61.410 2.702 + 1579.000 60.979 2.719 + 1579.500 63.017 2.731 + 1580.000 65.461 2.747 + 1580.500 64.200 2.750 + 1581.000 61.503 2.752 + 1581.500 55.597 2.748 + 1582.000 52.130 2.746 + 1582.500 54.213 2.748 + 1583.000 57.339 2.748 + 1583.500 59.713 2.742 + 1584.000 58.189 2.736 + 1584.500 52.806 2.735 + 1585.000 51.563 2.741 + 1585.500 54.026 2.738 + 1586.000 57.474 2.728 + 1586.500 58.917 2.709 + 1587.000 56.766 2.703 + 1587.500 52.158 2.706 + 1588.000 50.351 2.723 + 1588.500 52.144 2.731 + 1589.000 56.655 2.733 + 1589.500 61.617 2.727 + 1590.000 69.361 2.707 + 1590.500 75.689 2.697 + 1591.000 81.117 2.690 + 1591.500 82.459 2.691 + 1592.000 83.459 2.694 + 1592.500 79.351 2.700 + 1593.000 73.014 2.711 + 1593.500 69.759 2.715 + 1594.000 69.262 2.734 + 1594.500 71.679 2.735 + 1595.000 72.983 2.735 + 1595.500 70.005 2.722 + 1596.000 66.906 2.719 + 1596.500 62.149 2.728 + 1597.000 60.776 2.734 + 1597.500 61.686 2.747 + 1598.000 63.081 2.748 + 1598.500 69.758 2.750 + 1599.000 72.037 2.746 + 1599.500 75.298 2.741 + 1600.000 74.886 2.714 + 1600.500 71.181 2.696 + 1601.000 69.047 2.698 + 1601.500 69.042 2.700 + 1602.000 71.090 2.702 + 1602.500 73.384 2.705 + 1603.000 73.628 2.713 + 1603.500 73.507 2.717 + 1604.000 72.680 2.721 + 1604.500 73.782 2.718 + 1605.000 76.082 2.711 + 1605.500 77.646 2.702 + 1606.000 79.758 2.695 + 1606.500 74.968 2.688 + 1607.000 70.240 2.687 + 1607.500 61.959 2.696 + 1608.000 56.927 2.702 + 1608.500 48.903 2.739 + 1609.000 48.953 2.753 + 1609.500 53.896 2.755 + 1610.000 58.620 2.749 + 1610.500 55.839 2.714 + 1611.000 52.353 2.692 + 1611.500 45.360 2.698 + 1612.000 43.741 2.699 + 1612.500 43.418 2.696 + 1613.000 43.399 2.684 + 1613.500 42.136 2.672 + 1614.000 40.756 2.669 + 1614.500 39.097 2.675 + 1615.000 36.599 2.684 + 1615.500 35.784 2.693 + 1616.000 34.275 2.691 + 1616.500 33.549 2.689 + 1617.000 30.536 2.687 + 1617.500 28.717 2.690 + 1618.000 25.389 2.694 + 1618.500 24.088 2.695 + 1619.000 22.998 2.687 + 1619.500 21.701 2.676 + 1620.000 19.650 2.666 + 1620.500 18.561 2.658 + 1621.000 21.050 2.656 + 1621.500 21.260 2.651 + 1622.000 21.717 2.648 + 1622.500 23.738 2.648 + 1623.000 27.035 2.649 + 1623.500 33.542 2.656 + 1624.000 37.912 2.666 + 1624.500 42.150 2.696 + 1625.000 41.237 2.701 + 1625.500 36.269 2.704 + 1626.000 31.881 2.702 + 1626.500 34.516 2.720 + 1627.000 50.182 2.739 + 1627.500 59.450 2.745 + 1628.000 68.173 2.725 + 1628.500 74.632 2.694 + 1629.000 73.500 2.698 + 1629.500 70.273 2.716 + 1630.000 67.382 2.728 + 1630.500 68.866 2.738 + 1631.000 72.137 2.741 + 1631.500 76.485 2.737 + 1632.000 76.938 2.732 + 1632.500 72.093 2.724 + 1633.000 67.091 2.707 + 1633.500 61.860 2.709 + 1634.000 61.401 2.712 + 1634.500 56.658 2.725 + 1635.000 52.585 2.732 + 1635.500 44.989 2.736 + 1636.000 40.842 2.738 + 1636.500 35.144 2.737 + 1637.000 32.516 2.734 + 1637.500 29.200 2.732 + 1638.000 27.110 2.733 + 1638.500 25.560 2.731 + 1639.000 24.513 2.725 + 1639.500 23.944 2.720 + 1640.000 24.281 2.720 + 1640.500 26.461 2.723 + 1641.000 27.765 2.717 + 1641.500 28.021 2.715 + 1642.000 27.536 2.709 + 1642.500 27.415 2.704 + 1643.000 27.249 2.700 + 1643.500 28.050 2.701 + 1644.000 28.103 2.702 + 1644.500 28.246 2.694 + 1645.000 27.517 2.684 + 1645.500 24.767 2.677 + 1646.000 22.292 2.678 + 1646.500 21.756 2.677 + 1647.000 21.888 2.673 + 1647.500 22.583 2.668 + 1648.000 22.924 2.668 + 1648.500 21.714 2.678 + 1649.000 22.227 2.682 + 1649.500 25.154 2.689 + 1650.000 27.550 2.696 + 1650.500 34.051 2.707 + 1651.000 38.851 2.723 + 1651.500 39.775 2.740 + 1652.000 39.912 2.746 + 1652.500 39.091 2.741 + 1653.000 39.016 2.736 + 1653.500 39.147 2.724 + 1654.000 39.837 2.718 + 1654.500 39.761 2.708 + 1655.000 39.935 2.697 + 1655.500 38.033 2.693 + 1656.000 34.982 2.696 + 1656.500 30.677 2.697 + 1657.000 28.633 2.699 + 1657.500 25.582 2.679 + 1658.000 23.948 2.669 + 1658.500 21.606 2.664 + 1659.000 21.718 2.675 + 1659.500 21.607 2.688 + 1660.000 21.540 2.690 + 1660.500 19.938 2.689 + 1661.000 18.540 2.685 + 1661.500 16.970 2.679 + 1662.000 16.403 2.670 + 1662.500 15.971 2.659 + 1663.000 15.337 2.656 + 1663.500 15.211 2.661 + 1664.000 16.416 2.666 + 1664.500 18.190 2.668 + 1665.000 21.798 2.664 + 1665.500 27.585 2.664 + 1666.000 39.522 2.668 + 1666.500 42.865 2.666 + 1667.000 46.947 2.662 + 1667.500 47.825 2.661 + 1668.000 46.534 2.664 + 1668.500 38.597 2.670 + 1669.000 30.988 2.673 + 1669.500 26.881 2.676 + 1670.000 24.692 2.677 + 1670.500 21.980 2.676 + 1671.000 20.897 2.672 + 1671.500 20.151 2.671 + 1672.000 19.992 2.669 + 1672.500 18.533 2.667 + 1673.000 18.473 2.672 + 1673.500 19.066 2.680 + 1674.000 19.935 2.694 + 1674.500 21.852 2.698 + 1675.000 24.736 2.696 + 1675.500 30.798 2.695 + 1676.000 35.412 2.697 + 1676.500 34.427 2.706 + 1677.000 30.513 2.702 + 1677.500 26.574 2.686 + 1678.000 23.280 2.678 + 1678.500 24.553 2.674 + 1679.000 27.013 2.670 + 1679.500 28.582 2.667 + 1680.000 29.304 2.666 + 1680.500 28.140 2.676 + 1681.000 26.493 2.681 + 1681.500 24.193 2.692 + 1682.000 23.886 2.691 + 1682.500 27.949 2.682 + 1683.000 32.937 2.680 + 1683.500 41.515 2.679 + 1684.000 45.648 2.679 + 1684.500 54.783 2.673 + 1685.000 52.911 2.673 + 1685.500 46.105 2.675 + 1686.000 39.466 2.672 + 1686.500 24.297 2.669 + 1687.000 21.063 2.672 + 1687.500 19.032 2.682 + 1688.000 21.505 2.686 + 1688.500 23.251 2.693 + 1689.000 21.905 2.695 + 1689.500 19.419 2.696 + 1690.000 17.739 2.694 + 1690.500 15.315 2.687 + 1691.000 12.970 2.685 + 1691.500 11.944 2.687 + 1692.000 11.346 2.686 + 1692.500 11.525 2.678 + 1693.000 12.321 2.681 + 1693.500 13.940 2.694 + 1694.000 16.045 2.702 + 1694.500 21.237 2.714 + 1695.000 25.597 2.718 + 1695.500 35.552 2.722 + 1696.000 41.732 2.726 + 1696.500 52.267 2.731 + 1697.000 55.701 2.727 + 1697.500 55.876 2.722 + 1698.000 54.767 2.724 + 1698.500 51.035 2.747 + 1699.000 50.900 2.761 + 1699.500 50.922 2.773 + 1700.000 48.667 2.773 + 1700.500 44.574 2.769 + 1701.000 39.235 2.768 + 1701.500 31.502 2.764 + 1702.000 26.934 2.754 + 1702.500 24.043 2.751 + 1703.000 24.546 2.756 + 1703.500 28.471 2.765 + 1704.000 34.178 2.772 + 1704.500 42.792 2.757 + 1705.000 48.144 2.751 + 1705.500 52.396 2.744 + 1706.000 53.207 2.734 + 1706.500 52.831 2.710 + 1707.000 51.710 2.699 + 1707.500 49.020 2.686 + 1708.000 46.005 2.689 + 1708.500 42.021 2.684 + 1709.000 39.636 2.678 + 1709.500 38.764 2.665 + 1710.000 37.738 2.659 + 1710.500 35.500 2.665 + 1711.000 35.492 2.676 + 1711.500 37.178 2.694 + 1712.000 38.603 2.712 + 1712.500 35.303 2.774 + 1713.000 30.668 2.792 + 1713.500 25.889 2.810 + 1714.000 22.521 2.822 + 1714.500 20.853 2.832 + 1715.000 19.433 2.839 + 1715.500 19.023 2.851 + 1716.000 18.395 2.861 + 1716.500 16.133 2.868 + 1717.000 14.090 2.876 + 1717.500 12.644 2.877 + 1718.000 12.290 2.877 + 1718.500 14.072 2.871 + 1719.000 19.026 2.839 + 1719.500 24.668 2.815 + 1720.000 35.543 2.788 + 1720.500 50.950 2.771 + 1721.000 58.682 2.755 + 1721.500 60.115 2.759 + 1722.000 54.837 2.785 + 1722.500 48.024 2.797 + 1723.000 45.872 2.799 + 1723.500 48.414 2.789 + 1724.000 51.849 2.776 + 1724.500 54.883 2.771 + 1725.000 54.293 2.769 + 1725.500 55.864 2.766 + 1726.000 57.912 2.758 + 1726.500 58.643 2.759 + 1727.000 55.018 2.754 + 1727.500 49.565 2.756 + 1728.000 42.737 2.765 + 1728.500 44.478 2.781 + 1729.000 49.999 2.781 + 1729.500 58.961 2.765 + 1730.000 67.034 2.730 + 1730.500 71.669 2.704 + 1731.000 66.805 2.687 + 1731.500 59.273 2.704 + 1732.000 58.152 2.723 + 1732.500 52.296 2.742 + 1733.000 52.128 2.753 + 1733.500 55.181 2.748 + 1734.000 61.511 2.743 + 1734.500 64.302 2.738 + 1735.000 76.518 2.736 + 1735.500 80.437 2.716 + 1736.000 78.628 2.705 + 1736.500 73.358 2.691 + 1737.000 59.332 2.699 + 1737.500 54.545 2.710 + 1738.000 49.275 2.717 + 1738.500 47.802 2.720 + 1739.000 47.214 2.716 + 1739.500 45.566 2.717 + 1740.000 43.241 2.715 + 1740.500 42.695 2.795 + 1741.000 44.715 2.789 + 1741.500 51.440 2.780 + 1742.000 59.763 2.762 + 1742.500 70.004 2.742 + 1743.000 78.296 2.741 + 1743.500 87.137 2.747 + 1744.000 91.190 2.748 + 1744.500 87.975 2.746 + 1745.000 68.682 2.732 + 1745.500 65.605 2.724 + 1746.000 58.749 2.720 + 1746.500 57.459 2.722 + 1747.000 57.267 2.728 + 1747.500 59.728 2.734 + 1748.000 61.133 2.739 + 1748.500 62.101 2.740 + 1749.000 53.025 2.742 + 1749.500 48.722 2.747 + 1750.000 47.422 2.748 + 1750.500 50.853 2.745 + 1751.000 52.068 2.745 + 1751.500 51.760 2.743 + 1752.000 48.302 2.766 + 1752.500 45.416 2.783 + 1753.000 43.712 2.793 + 1753.500 57.232 2.797 + 1754.000 62.611 2.789 + 1754.500 93.691 2.749 + 1755.000 102.555 2.706 + 1755.500 120.693 2.687 + 1756.000 123.686 2.678 + 1756.500 126.547 2.677 + 1757.000 123.686 2.681 + 1757.500 120.157 2.689 + 1758.000 117.498 2.699 + 1758.500 113.418 2.708 + 1759.000 111.507 2.714 + 1759.500 105.490 2.717 + 1760.000 100.523 2.718 + 1760.500 94.010 2.707 + 1761.000 91.904 2.699 + 1761.500 95.388 2.690 + 1762.000 100.850 2.686 + 1762.500 108.549 2.680 + 1763.000 106.682 2.675 + 1763.500 100.677 2.672 + 1764.000 94.875 2.673 + 1764.500 87.958 2.679 + 1765.000 83.831 2.695 + 1765.500 80.788 2.704 + 1766.000 75.882 2.709 + 1766.500 69.615 2.701 + 1767.000 66.580 2.706 + 1767.500 64.270 2.711 + 1768.000 69.516 2.716 + 1768.500 75.377 2.701 + 1769.000 78.765 2.692 + 1769.500 79.367 2.691 + 1770.000 71.952 2.710 + 1770.500 58.880 2.731 + 1771.000 53.364 2.748 + 1771.500 51.387 2.752 + 1772.000 52.284 2.748 + 1772.500 57.607 2.738 + 1773.000 65.696 2.739 + 1773.500 73.389 2.743 + 1774.000 82.908 2.746 + 1774.500 93.223 2.734 + 1775.000 98.433 2.708 + 1775.500 104.382 2.697 + 1776.000 104.993 2.695 + 1776.500 103.758 2.700 + 1777.000 104.269 2.701 + 1777.500 105.944 2.700 + 1778.000 107.500 2.698 + 1778.500 107.273 2.692 + 1779.000 106.580 2.687 + 1779.500 104.608 2.682 + 1780.000 99.895 2.686 + 1780.500 93.308 2.692 + 1781.000 84.016 2.698 + 1781.500 76.444 2.695 + 1782.000 79.154 2.690 + 1782.500 89.825 2.686 + 1783.000 94.417 2.682 + 1783.500 103.558 2.657 + 1784.000 104.578 2.662 + 1784.500 95.816 2.685 + 1785.000 79.318 2.698 + 1785.500 69.736 2.709 + 1786.000 70.943 2.739 + 1786.500 75.432 2.761 + 1787.000 80.256 2.745 + 1787.500 83.859 2.733 + 1788.000 87.007 2.713 + 1788.500 90.788 2.708 + 1789.000 94.118 2.702 + 1789.500 96.979 2.695 + 1790.000 99.594 2.687 + 1790.500 100.763 2.678 + 1791.000 99.656 2.670 + 1791.500 99.663 2.670 + 1792.000 95.129 2.676 + 1792.500 84.818 2.686 + 1793.000 80.416 2.694 + 1793.500 75.284 2.696 + 1794.000 72.156 2.693 + 1794.500 67.704 2.687 + 1795.000 66.781 2.695 + 1795.500 68.929 2.698 + 1796.000 75.015 2.701 + 1796.500 90.770 2.697 + 1797.000 100.225 2.693 + 1797.500 100.313 2.686 + 1798.000 101.838 2.678 + 1798.500 81.424 2.687 + 1799.000 68.752 2.701 + 1799.500 65.347 2.726 + 1800.000 69.368 2.745 + 1800.500 79.548 2.730 + 1801.000 87.803 2.712 + 1801.500 90.669 2.704 + 1802.000 95.128 2.701 + 1802.500 95.554 2.704 + 1803.000 95.821 2.707 + 1803.500 93.084 2.709 + 1804.000 90.198 2.716 + 1804.500 87.184 2.727 + 1805.000 84.627 2.731 + 1805.500 82.388 2.729 + 1806.000 80.939 2.727 + 1806.500 81.636 2.729 + 1807.000 81.182 2.729 + 1807.500 82.912 2.727 + 1808.000 85.235 2.722 + 1808.500 90.150 2.713 + 1809.000 93.542 2.704 + 1809.500 95.753 2.701 + 1810.000 98.234 2.698 + 1810.500 103.053 2.696 + 1811.000 96.853 2.688 + 1811.500 90.301 2.680 + 1812.000 77.144 2.678 + 1812.500 56.446 2.683 + 1813.000 58.039 2.685 + 1813.500 59.672 2.686 + 1814.000 63.896 2.688 + 1814.500 65.379 2.695 + 1815.000 65.771 2.702 + 1815.500 67.964 2.707 + 1816.000 70.217 2.711 + 1816.500 72.158 2.712 + 1817.000 70.753 2.739 + 1817.500 68.117 2.743 + 1818.000 65.014 2.764 + 1818.500 62.305 2.758 + 1819.000 58.574 2.743 + 1819.500 55.400 2.725 + 1820.000 52.299 2.708 + 1820.500 51.825 2.694 + 1821.000 50.878 2.698 + 1821.500 50.713 2.710 + 1822.000 52.143 2.734 + 1822.500 58.403 2.746 + 1823.000 65.736 2.734 + 1823.500 70.432 2.730 + 1824.000 70.219 2.731 + 1824.500 68.139 2.737 + 1825.000 68.347 2.746 + 1825.500 69.655 2.726 + 1826.000 70.650 2.716 + 1826.500 69.551 2.704 + 1827.000 63.900 2.703 + 1827.500 59.659 2.704 + 1828.000 56.876 2.716 + 1828.500 50.880 2.731 + 1829.000 45.035 2.743 + 1829.500 46.312 2.751 + 1830.000 50.478 2.761 + 1830.500 60.798 2.739 + 1831.000 68.057 2.715 + 1831.500 71.696 2.699 + 1832.000 71.788 2.698 + 1832.500 69.440 2.702 + 1833.000 69.764 2.712 + 1833.500 71.148 2.724 + 1834.000 79.498 2.729 + 1834.500 90.146 2.711 + 1835.000 98.692 2.695 + 1835.500 100.968 2.679 + 1836.000 105.223 2.678 + 1836.500 99.544 2.684 + 1837.000 82.004 2.704 + 1837.500 71.498 2.717 + 1838.000 64.519 2.738 + 1838.500 71.986 2.733 + 1839.000 73.769 2.715 + 1839.500 73.708 2.704 + 1840.000 72.370 2.702 + 1840.500 68.494 2.724 + 1841.000 64.789 2.740 + 1841.500 60.548 2.758 + 1842.000 56.418 2.764 + 1842.500 74.146 2.773 + 1843.000 87.356 2.761 + 1843.500 103.649 2.748 + 1844.000 111.819 2.722 + 1844.500 112.689 2.701 + 1845.000 101.888 2.705 + 1845.500 91.631 2.707 + 1846.000 87.698 2.716 + 1846.500 87.223 2.704 + 1847.000 93.849 2.702 + 1847.500 97.860 2.700 + 1848.000 99.145 2.714 + 1848.500 93.297 2.723 + 1849.000 88.270 2.724 + 1849.500 82.470 2.728 + 1850.000 75.770 2.729 + 1850.500 65.667 2.728 + 1851.000 57.822 2.733 + 1851.500 53.621 2.740 + 1852.000 53.042 2.740 + 1852.500 53.149 2.732 + 1853.000 52.253 2.712 + 1853.500 50.897 2.710 + 1854.000 49.527 2.709 + 1854.500 59.923 2.718 + 1855.000 72.067 2.726 + 1855.500 86.274 2.735 + 1856.000 99.885 2.734 + 1856.500 113.775 2.712 + 1857.000 125.508 2.697 + 1857.500 125.486 2.682 + 1858.000 119.820 2.681 + 1858.500 107.562 2.693 + 1859.000 98.278 2.703 + 1859.500 92.423 2.718 + 1860.000 84.839 2.715 + 1860.500 83.256 2.711 + 1861.000 82.159 2.716 + 1861.500 82.361 2.723 + 1862.000 82.146 2.729 + 1862.500 83.328 2.726 + 1863.000 85.798 2.708 + 1863.500 85.468 2.697 + 1864.000 84.256 2.691 + 1864.500 77.693 2.689 + 1865.000 68.815 2.714 + 1865.500 58.970 2.737 + 1866.000 55.148 2.763 + 1866.500 43.105 2.788 + 1867.000 36.676 2.807 + 1867.500 34.066 2.829 + 1868.000 32.597 2.815 + 1868.500 37.088 2.737 + 1869.000 42.848 2.707 + 1869.500 48.457 2.693 + 1870.000 55.832 2.692 + 1870.500 65.442 2.696 + 1871.000 71.437 2.708 + 1871.500 72.166 2.720 + 1872.000 72.377 2.722 + 1872.500 80.012 2.721 + 1873.000 91.123 2.721 + 1873.500 100.186 2.710 + 1874.000 102.575 2.693 + 1874.500 103.836 2.681 + 1875.000 107.051 2.692 + 1875.500 111.619 2.709 + 1876.000 115.242 2.714 + 1876.500 118.088 2.716 + 1877.000 119.953 2.695 + 1877.500 121.312 2.678 + 1878.000 122.532 2.675 + 1878.500 125.959 2.676 + 1879.000 127.347 2.681 + 1879.500 125.254 2.685 + 1880.000 110.491 2.688 + 1880.500 90.164 2.703 + 1881.000 78.758 2.720 + 1881.500 72.980 2.732 + 1882.000 75.224 2.730 + 1882.500 85.893 2.716 + 1883.000 101.138 2.702 + 1883.500 109.880 2.690 + 1884.000 109.834 2.683 + 1884.500 107.601 2.693 + 1885.000 102.776 2.696 + 1885.500 101.943 2.701 + 1886.000 100.737 2.700 + 1886.500 94.677 2.708 + 1887.000 76.312 2.733 + 1887.500 52.425 2.774 + 1888.000 46.366 2.822 + 1888.500 49.099 2.834 + 1889.000 57.881 2.830 + 1889.500 70.714 2.784 + 1890.000 88.246 2.768 + 1890.500 102.807 2.749 + 1891.000 105.308 2.729 + 1891.500 108.334 2.712 + 1892.000 108.857 2.706 + 1892.500 111.422 2.710 + 1893.000 111.552 2.707 + 1893.500 112.146 2.701 + 1894.000 110.080 2.696 + 1894.500 103.971 2.699 + 1895.000 100.379 2.698 + 1895.500 100.355 2.687 + 1896.000 100.529 2.676 + 1896.500 99.124 2.671 + 1897.000 95.602 2.679 + 1897.500 89.113 2.693 + 1898.000 85.483 2.700 + 1898.500 82.462 2.695 + 1899.000 81.538 2.687 + 1899.500 79.243 2.678 + 1900.000 74.352 2.676 + 1900.500 63.252 2.678 + 1901.000 55.306 2.681 + 1901.500 51.458 2.680 + 1902.000 48.364 2.674 + 1902.500 46.966 2.666 + 1903.000 45.375 2.664 + 1903.500 45.169 2.667 + 1904.000 45.938 2.671 + 1904.500 50.639 2.679 + 1905.000 59.978 2.683 + 1905.500 72.191 2.690 + 1906.000 82.014 2.695 + 1906.500 93.284 2.699 + 1907.000 95.505 2.699 + 1907.500 96.540 2.701 + 1908.000 95.301 2.701 + 1908.500 91.040 2.702 + 1909.000 85.823 2.701 + 1909.500 78.377 2.704 + 1910.000 72.889 2.707 + 1910.500 70.769 2.706 + 1911.000 69.543 2.704 + 1911.500 69.681 2.697 + 1912.000 69.764 2.700 + 1912.500 68.680 2.713 + 1913.000 66.561 2.718 + 1913.500 64.432 2.712 + 1914.000 62.280 2.700 + 1914.500 60.720 2.686 + 1915.000 58.926 2.677 + 1915.500 55.240 2.675 + 1916.000 52.959 2.678 + 1916.500 56.304 2.691 + 1917.000 60.202 2.706 + 1917.500 71.568 2.713 + 1918.000 74.923 2.709 + 1918.500 76.387 2.694 + 1919.000 72.985 2.683 + 1919.500 70.494 2.681 + 1920.000 70.292 2.685 + 1920.500 69.262 2.686 + 1921.000 63.839 2.687 + 1921.500 61.692 2.689 + 1922.000 52.920 2.701 + 1922.500 46.216 2.721 + 1923.000 43.682 2.728 + 1923.500 47.237 2.729 + 1924.000 52.016 2.721 + 1924.500 69.080 2.707 + 1925.000 96.552 2.703 + 1925.500 104.254 2.701 + 1926.000 107.399 2.697 + 1926.500 92.163 2.692 + 1927.000 85.257 2.699 + 1927.500 73.168 2.705 + 1928.000 70.348 2.709 + 1928.500 65.096 2.701 + 1929.000 63.655 2.690 + 1929.500 60.927 2.685 + 1930.000 58.774 2.679 + 1930.500 56.599 2.673 + 1931.000 57.163 2.666 + 1931.500 59.487 2.666 + 1932.000 61.330 2.667 + 1932.500 60.986 2.674 + 1933.000 60.642 2.683 + 1933.500 58.429 2.696 + 1934.000 56.005 2.700 + 1934.500 54.960 2.701 + 1935.000 56.277 2.701 + 1935.500 58.505 2.703 + 1936.000 59.531 2.703 + 1936.500 59.457 2.701 + 1937.000 58.751 2.698 + 1937.500 56.552 2.685 + 1938.000 54.454 2.675 + 1938.500 53.940 2.674 + 1939.000 55.439 2.685 + 1939.500 60.420 2.697 + 1940.000 66.829 2.697 + 1940.500 74.849 2.696 + 1941.000 72.546 2.689 + 1941.500 69.856 2.690 + 1942.000 66.895 2.697 + 1942.500 61.881 2.714 + 1943.000 57.664 2.738 + 1943.500 52.002 2.748 + 1944.000 49.975 2.739 + 1944.500 52.232 2.711 + 1945.000 57.859 2.702 + 1945.500 67.679 2.710 + 1946.000 71.772 2.718 + 1946.500 68.345 2.727 + 1947.000 62.515 2.726 + 1947.500 57.435 2.734 + 1948.000 51.997 2.749 + 1948.500 47.850 2.776 + 1949.000 48.914 2.775 + 1949.500 53.354 2.768 + 1950.000 62.567 2.757 + 1950.500 71.691 2.725 + 1951.000 86.519 2.706 + 1951.500 97.216 2.699 + 1952.000 112.013 2.689 + 1952.500 115.231 2.688 + 1953.000 117.253 2.689 + 1953.500 108.128 2.691 + 1954.000 90.913 2.695 + 1954.500 77.981 2.703 + 1955.000 76.464 2.718 + 1955.500 63.085 2.731 + 1956.000 55.420 2.746 + 1956.500 50.352 2.769 + 1957.000 47.308 2.779 + 1957.500 45.954 2.781 + 1958.000 47.832 2.784 + 1958.500 57.301 2.788 + 1959.000 67.851 2.777 + 1959.500 80.243 2.741 + 1960.000 90.257 2.718 + 1960.500 91.593 2.702 + 1961.000 84.740 2.716 + 1961.500 81.293 2.728 + 1962.000 72.963 2.733 + 1962.500 72.337 2.728 + 1963.000 64.087 2.713 + 1963.500 56.437 2.711 + 1964.000 49.573 2.710 + 1964.500 44.432 2.705 + 1965.000 42.113 2.688 + 1965.500 45.126 2.671 + 1966.000 46.906 2.667 + 1966.500 50.446 2.672 + 1967.000 52.918 2.677 + 1967.500 54.432 2.676 + 1968.000 52.823 2.674 + 1968.500 52.329 2.682 + 1969.000 52.348 2.686 + 1969.500 53.468 2.691 + 1970.000 54.537 2.693 + 1970.500 55.412 2.695 + 1971.000 60.297 2.693 + 1971.500 68.594 2.691 + 1972.000 82.680 2.704 + 1972.500 107.269 2.756 + 1973.000 128.026 2.748 + 1973.500 143.189 2.704 + 1974.000 154.674 2.643 + 1974.500 156.280 2.524 + 1975.000 153.700 2.471 + 1975.500 143.584 2.372 + 1976.000 137.181 2.351 + 1976.500 124.257 2.560 + 1977.000 110.709 2.602 + 1977.500 79.596 2.664 + 1978.000 72.217 2.684 + 1978.500 59.831 2.700 + 1979.000 55.248 2.697 + 1979.500 52.296 2.695 + 1980.000 52.367 2.697 + 1980.500 54.006 2.697 + 1981.000 56.867 2.693 + 1981.500 60.519 2.687 + 1982.000 67.538 2.681 + 1982.500 74.718 2.674 + 1983.000 80.123 2.671 + 1983.500 81.071 2.673 + 1984.000 78.922 2.675 + 1984.500 74.347 2.680 + 1985.000 71.271 2.693 + 1985.500 71.397 2.719 + 1986.000 72.745 2.730 + 1986.500 72.804 2.722 + 1987.000 72.447 2.712 + 1987.500 70.436 2.693 + 1988.000 67.485 2.682 + 1988.500 62.443 2.695 + 1989.000 61.539 2.692 + 1989.500 61.431 2.694 + 1990.000 63.864 2.692 + 1990.500 70.805 2.695 + 1991.000 79.466 2.698 + 1991.500 83.225 2.699 + 1992.000 87.278 2.695 + 1992.500 89.246 2.684 + 1993.000 89.000 2.679 + 1993.500 88.779 2.681 + 1994.000 88.700 2.685 + 1994.500 91.380 2.693 + 1995.000 94.388 2.700 + 1995.500 91.741 2.704 + 1996.000 87.792 2.710 + 1996.500 77.726 2.715 + 1997.000 73.397 2.708 + 1997.500 68.263 2.698 + 1998.000 62.952 2.693 + 1998.500 55.187 2.703 + 1999.000 53.003 2.703 + 1999.500 45.369 2.709 + 2000.000 47.248 2.709 + 2000.500 57.408 2.709 + 2001.000 69.023 2.700 + 2001.500 76.267 2.689 + 2002.000 81.161 2.678 + 2002.500 82.038 2.676 + 2003.000 79.670 2.681 + 2003.500 70.720 2.694 + 2004.000 66.084 2.702 + 2004.500 59.477 2.711 + 2005.000 57.327 2.708 + 2005.500 59.433 2.702 + 2006.000 63.905 2.699 + 2006.500 71.856 2.727 + 2007.000 80.075 2.744 + 2007.500 88.472 2.750 + 2008.000 95.479 2.746 + 2008.500 105.353 2.722 + 2009.000 110.067 2.712 + 2009.500 115.571 2.703 + 2010.000 113.753 2.700 + 2010.500 109.187 2.697 + 2011.000 98.689 2.700 + 2011.500 88.351 2.710 + 2012.000 85.397 2.714 + 2012.500 85.132 2.719 + 2013.000 103.049 2.705 + 2013.500 122.165 2.693 + 2014.000 132.218 2.680 + 2014.500 137.108 2.677 + 2015.000 125.796 2.677 + 2015.500 113.311 2.681 + 2016.000 105.191 2.694 + 2016.500 102.498 2.707 + 2017.000 107.095 2.711 + 2017.500 109.182 2.708 + 2018.000 118.110 2.693 + 2018.500 126.313 2.666 + 2019.000 133.565 2.643 + 2019.500 136.409 2.637 + 2020.000 132.942 2.638 + 2020.500 128.405 2.668 + 2021.000 113.991 2.677 + 2021.500 110.022 2.676 + 2022.000 109.936 2.667 + 2022.500 109.950 2.654 + 2023.000 107.332 2.649 + 2023.500 106.604 2.650 + 2024.000 107.469 2.652 + 2024.500 107.814 2.646 + 2025.000 106.923 2.636 + 2025.500 93.027 2.629 + 2026.000 73.566 2.630 + 2026.500 46.572 2.644 + 2027.000 40.051 2.653 + 2027.500 33.117 2.650 + 2028.000 31.607 2.643 + 2028.500 36.676 2.646 + 2029.000 42.257 2.654 + 2029.500 50.448 2.662 + 2030.000 52.905 2.669 + 2030.500 54.876 2.682 + 2031.000 56.899 2.689 + 2031.500 69.824 2.689 + 2032.000 82.437 2.687 + 2032.500 101.409 2.671 + 2033.000 117.317 2.657 + 2033.500 125.060 2.646 + 2034.000 129.080 2.646 + 2034.500 129.568 2.653 + 2035.000 129.741 2.658 + 2035.500 128.490 2.661 + 2036.000 126.443 2.662 + 2036.500 124.105 2.666 + 2037.000 122.373 2.664 + 2037.500 120.400 2.661 + 2038.000 113.771 2.653 + 2038.500 104.131 2.650 + 2039.000 91.893 2.636 + 2039.500 83.032 2.622 + 2040.000 82.212 2.610 + 2040.500 80.685 2.601 + 2041.000 89.537 2.607 + 2041.500 94.336 2.614 + 2042.000 94.770 2.621 + 2042.500 97.864 2.620 + 2043.000 100.997 2.616 + 2043.500 106.308 2.617 + 2044.000 114.161 2.619 + 2044.500 127.485 2.624 + 2045.000 132.554 2.626 + 2045.500 138.282 2.619 + 2046.000 141.358 2.614 + 2046.500 145.624 2.615 + 2047.000 148.289 2.646 + 2047.500 165.299 2.637 + 2048.000 183.015 2.667 + 2048.500 195.363 2.458 + 2049.000 196.579 2.465 + 2049.500 189.994 2.420 + 2050.000 176.633 2.424 + 2050.500 165.778 2.587 + 2051.000 156.681 2.610 + 2051.500 156.294 2.622 + 2052.000 155.994 2.640 + 2052.500 147.838 2.648 + 2053.000 137.529 2.644 + 2053.500 128.177 2.638 + 2054.000 108.708 2.632 + 2054.500 102.679 2.654 + 2055.000 93.294 2.670 + 2055.500 94.709 2.681 + 2056.000 99.548 2.689 + 2056.500 103.466 2.676 + 2057.000 104.354 2.669 + 2057.500 104.419 2.677 + 2058.000 103.694 2.681 + 2058.500 102.963 2.686 + 2059.000 102.194 2.690 + 2059.500 101.315 2.695 + 2060.000 101.104 2.701 + 2060.500 102.001 2.703 + 2061.000 104.513 2.707 + 2061.500 105.159 2.702 + 2062.000 107.484 2.695 + 2062.500 109.977 2.690 + 2063.000 113.224 2.697 + 2063.500 114.502 2.708 + 2064.000 116.621 2.719 + 2064.500 118.986 2.704 + 2065.000 117.263 2.697 + 2065.500 112.399 2.701 + 2066.000 100.705 2.717 + 2066.500 97.905 2.716 + 2067.000 96.373 2.711 + 2067.500 96.467 2.710 + 2068.000 98.261 2.708 + 2068.500 100.617 2.706 + 2069.000 102.073 2.699 + 2069.500 99.899 2.695 + 2070.000 98.472 2.695 + 2070.500 93.218 2.696 + 2071.000 90.896 2.688 + 2071.500 85.066 2.674 + 2072.000 75.976 2.669 + 2072.500 61.245 2.679 + 2073.000 61.317 2.686 + 2073.500 61.390 2.691 + 2074.000 65.273 2.697 + 2074.500 74.283 2.708 + 2075.000 76.691 2.708 + 2075.500 79.541 2.702 + 2076.000 83.805 2.696 + 2076.500 89.577 2.696 + 2077.000 104.922 2.697 + 2077.500 108.371 2.697 + 2078.000 115.972 2.699 + 2078.500 117.667 2.721 + 2079.000 119.486 2.733 + 2079.500 119.459 2.748 + 2080.000 118.455 2.732 + 2080.500 115.642 2.744 + 2081.000 112.611 2.535 + 2081.500 105.553 2.620 + 2082.000 99.762 2.644 + 2082.500 93.689 2.716 + 2083.000 93.081 2.725 + 2083.500 96.252 2.718 + 2084.000 101.482 2.716 + 2084.500 110.469 2.714 + 2085.000 114.275 2.709 + 2085.500 118.483 2.700 + 2086.000 121.527 2.682 + 2086.500 120.758 2.651 + 2087.000 120.613 2.656 + 2087.500 116.012 2.682 + 2088.000 113.732 2.700 + 2088.500 118.553 2.705 + 2089.000 123.852 2.701 + 2089.500 127.197 2.699 + 2090.000 129.412 2.693 + 2090.500 124.702 2.686 + 2091.000 119.376 2.682 + 2091.500 115.331 2.691 + 2092.000 111.717 2.697 + 2092.500 113.198 2.679 + 2093.000 118.529 2.661 + 2093.500 119.351 2.650 + 2094.000 119.788 2.651 + 2094.500 112.195 2.651 + 2095.000 106.783 2.652 + 2095.500 105.449 2.664 + 2096.000 109.050 2.677 + 2096.500 119.843 2.700 + 2097.000 119.529 2.714 + 2097.500 119.596 2.731 + 2098.000 110.420 2.733 + 2098.500 104.618 2.721 + 2099.000 106.575 2.714 + 2099.500 113.349 2.707 + 2100.000 121.383 2.703 + 2100.500 124.906 2.708 + 2101.000 125.573 2.703 + 2101.500 124.264 2.686 + 2102.000 119.572 2.678 + 2102.500 116.678 2.688 + 2103.000 117.085 2.695 + 2103.500 118.205 2.699 + 2104.000 120.906 2.689 + 2104.500 120.606 2.684 + 2105.000 119.958 2.680 + 2105.500 120.931 2.705 + 2106.000 122.210 2.718 + 2106.500 128.474 2.701 + 2107.000 133.674 2.673 + 2107.500 136.473 2.622 + 2108.000 135.925 2.634 + 2108.500 131.469 2.671 + 2109.000 127.592 2.687 + 2109.500 124.351 2.694 + 2110.000 121.775 2.690 + 2110.500 114.804 2.693 + 2111.000 110.092 2.702 + 2111.500 110.612 2.712 + 2112.000 111.994 2.696 + 2112.500 110.512 2.639 + 2113.000 108.003 2.636 + 2113.500 102.823 2.638 + 2114.000 90.082 2.656 + 2114.500 84.565 2.705 + 2115.000 80.622 2.713 + 2115.500 84.710 2.705 + 2116.000 87.885 2.698 + 2116.500 99.855 2.646 + 2117.000 105.938 2.630 + 2117.500 103.234 2.628 + 2118.000 95.807 2.679 + 2118.500 88.763 2.743 + 2119.000 86.930 2.694 + 2119.500 88.118 2.652 + 2120.000 91.591 2.637 + 2120.500 100.961 2.634 + 2121.000 110.388 2.644 + 2121.500 116.509 2.653 + 2122.000 117.923 2.649 + 2122.500 113.532 2.647 + 2123.000 109.714 2.647 + 2123.500 109.356 2.642 + 2124.000 109.778 2.617 + 2124.500 107.924 2.606 + 2125.000 102.249 2.609 + 2125.500 97.629 2.623 + 2126.000 96.583 2.636 + 2126.500 98.991 2.677 + 2127.000 100.019 2.673 + 2127.500 101.269 2.654 + 2128.000 100.295 2.620 + 2128.500 103.232 2.603 + 2129.000 101.121 2.602 + 2129.500 99.030 2.602 + 2130.000 92.476 2.616 + 2130.500 86.204 2.630 + 2131.000 83.364 2.634 + 2131.500 82.386 2.636 + 2132.000 83.392 2.637 + 2132.500 83.414 2.632 + 2133.000 78.588 2.626 + 2133.500 73.993 2.634 + 2134.000 72.514 2.636 + 2134.500 74.377 2.631 + 2135.000 83.320 2.620 + 2135.500 84.952 2.615 + 2136.000 86.781 2.622 + 2136.500 88.749 2.636 + 2137.000 90.472 2.652 + 2137.500 93.025 2.640 + 2138.000 94.037 2.627 + 2138.500 91.591 2.595 + 2139.000 84.796 2.593 + 2139.500 74.595 2.604 + 2140.000 73.080 2.627 + 2140.500 72.814 2.643 + 2141.000 72.819 2.662 + 2141.500 72.895 2.673 + 2142.000 75.169 2.690 + 2142.500 73.856 2.711 + 2143.000 71.427 2.697 + 2143.500 69.526 2.652 + 2144.000 67.235 2.634 + 2144.500 68.281 2.623 + 2145.000 70.540 2.614 + 2145.500 71.794 2.592 + 2146.000 72.849 2.585 + 2146.500 71.330 2.615 + 2147.000 68.720 2.631 + 2147.500 66.667 2.656 + 2148.000 66.400 2.646 + 2148.500 71.736 2.597 + 2149.000 75.699 2.553 + 2149.500 81.926 2.559 + 2150.000 82.326 2.568 + 2150.500 84.079 2.694 + 2151.000 86.130 2.684 + 2151.500 89.545 2.678 + 2152.000 91.043 2.660 + 2152.500 87.882 2.665 + 2153.000 81.783 2.680 + 2153.500 78.882 2.686 + 2154.000 74.847 2.680 + 2154.500 73.823 2.676 + 2155.000 72.916 2.685 + 2155.500 76.002 2.701 + 2156.000 82.244 2.711 + 2156.500 91.451 2.699 + 2157.000 93.661 2.675 + 2157.500 94.671 2.668 + 2158.000 91.739 2.664 + 2158.500 87.962 2.649 + 2159.000 86.520 2.611 + 2159.500 84.667 2.606 + 2160.000 82.806 2.626 + 2160.500 81.089 2.680 + 2161.000 79.764 2.692 + 2161.500 79.835 2.695 + 2162.000 79.604 2.693 + 2162.500 82.194 2.687 + 2163.000 84.272 2.688 + 2163.500 88.665 2.686 + 2164.000 89.792 2.683 + 2164.500 88.887 2.676 + 2165.000 84.446 2.677 + 2165.500 80.797 2.677 + 2166.000 79.361 2.677 + 2166.500 80.240 2.671 + 2167.000 82.307 2.654 + 2167.500 84.166 2.643 + 2168.000 87.255 2.662 + 2168.500 89.887 2.676 + 2169.000 90.192 2.683 + 2169.500 87.900 2.695 + 2170.000 86.069 2.719 + 2170.500 81.791 2.706 + 2171.000 80.220 2.666 + 2171.500 79.015 2.612 + 2172.000 79.059 2.591 + 2172.500 79.427 2.554 + 2173.000 76.174 2.543 + 2173.500 71.160 2.562 + 2174.000 67.157 2.602 + 2174.500 62.499 2.651 + 2175.000 60.747 2.641 + 2175.500 60.447 2.584 + 2176.000 61.015 2.489 + 2176.500 63.674 2.494 + 2177.000 64.797 2.490 + 2177.500 65.028 2.618 + 2178.000 63.999 2.650 + 2178.500 60.291 2.678 + 2179.000 60.360 2.677 + 2179.500 61.148 2.647 + 2180.000 63.388 2.643 + 2180.500 65.712 2.644 + 2181.000 67.845 2.651 + 2181.500 70.588 2.673 + 2182.000 74.856 2.690 + 2182.500 78.463 2.734 + 2183.000 77.863 2.660 + 2183.500 76.201 2.594 + 2184.000 74.506 2.575 + 2184.500 71.530 2.623 + 2185.000 69.007 2.657 + 2185.500 68.026 2.664 + 2186.000 68.665 2.651 + 2186.500 68.828 2.621 + 2187.000 66.679 2.618 + 2187.500 64.808 2.677 + 2188.000 62.095 2.695 + 2188.500 61.139 2.682 + 2189.000 61.181 2.668 + 2189.500 65.022 2.710 + 2190.000 73.217 2.695 + 2190.500 79.933 2.604 + 2191.000 81.555 2.577 + 2191.500 84.338 2.569 + 2192.000 82.563 2.610 + 2192.500 80.603 2.669 + 2193.000 80.624 2.679 + 2193.500 82.711 2.679 + 2194.000 89.640 2.677 + 2194.500 94.309 2.676 + 2195.000 95.532 2.671 + 2195.500 92.867 2.666 + 2196.000 89.273 2.658 + 2196.500 87.957 2.673 + 2197.000 92.384 2.689 + 2197.500 100.900 2.673 + 2198.000 107.638 2.625 + 2198.500 110.779 2.578 + 2199.000 108.695 2.596 + 2199.500 101.532 2.634 + 2200.000 98.989 2.671 + 2200.500 98.975 2.691 + 2201.000 99.368 2.680 + 2201.500 99.222 2.680 + 2202.000 91.961 2.684 + 2202.500 85.654 2.699 + 2203.000 84.711 2.684 + 2203.500 86.608 2.663 + 2204.000 90.551 2.637 + 2204.500 97.443 2.643 + 2205.000 100.941 2.652 + 2205.500 105.381 2.658 + 2206.000 111.423 2.653 + 2206.500 115.078 2.654 + 2207.000 117.226 2.641 + 2207.500 116.251 2.633 + 2208.000 113.532 2.620 + 2208.500 109.755 2.619 + 2209.000 102.942 2.641 + 2209.500 100.186 2.655 + 2210.000 98.801 2.671 + 2210.500 101.301 2.665 + 2211.000 101.499 2.647 + 2211.500 112.581 2.637 + 2212.000 114.690 2.636 + 2212.500 116.494 2.648 + 2213.000 113.130 2.661 + 2213.500 109.420 2.656 + 2214.000 105.754 2.651 + 2214.500 102.565 2.658 + 2215.000 101.462 2.655 + 2215.500 97.083 2.650 + 2216.000 96.781 2.649 + 2216.500 98.740 2.656 + 2217.000 100.944 2.663 + 2217.500 101.123 2.668 + 2218.000 98.371 2.682 + 2218.500 93.835 2.686 + 2219.000 92.558 2.683 + 2219.500 92.734 2.677 + 2220.000 94.201 2.674 + 2220.500 99.166 2.687 + 2221.000 103.735 2.676 + 2221.500 107.134 2.656 + 2222.000 107.951 2.588 + 2222.500 99.932 2.594 + 2223.000 93.708 2.630 + 2223.500 91.826 2.665 + 2224.000 94.487 2.687 + 2224.500 92.145 2.691 + 2225.000 89.175 2.696 + 2225.500 83.845 2.701 + 2226.000 84.374 2.703 + 2226.500 91.453 2.706 + 2227.000 94.787 2.704 + 2227.500 102.831 2.721 + 2228.000 103.631 2.724 + 2228.500 104.505 2.723 + 2229.000 104.414 2.721 + 2229.500 103.999 2.722 + 2230.000 106.947 2.723 + 2230.500 108.230 2.699 + 2231.000 108.616 2.678 + 2231.500 102.914 2.662 + 2232.000 98.783 2.665 + 2232.500 95.401 2.685 + 2233.000 94.109 2.704 + 2233.500 95.159 2.720 + 2234.000 97.942 2.735 + 2234.500 101.614 2.736 + 2235.000 104.204 2.731 + 2235.500 105.276 2.731 + 2236.000 104.607 2.734 + 2236.500 104.158 2.738 + 2237.000 107.936 2.731 + 2237.500 109.251 2.711 + 2238.000 108.117 2.695 + 2238.500 103.737 2.690 + 2239.000 98.105 2.701 + 2239.500 93.931 2.700 + 2240.000 84.146 2.695 + 2240.500 78.521 2.686 + 2241.000 72.254 2.681 + 2241.500 72.968 2.685 + 2242.000 76.817 2.696 + 2242.500 78.327 2.705 + 2243.000 78.410 2.700 + 2243.500 77.709 2.691 + 2244.000 77.774 2.682 + 2244.500 81.340 2.680 + 2245.000 84.412 2.681 + 2245.500 84.620 2.677 + 2246.000 81.934 2.675 + 2246.500 78.742 2.674 + 2247.000 79.461 2.679 + 2247.500 82.196 2.686 + 2248.000 89.550 2.690 + 2248.500 104.377 2.684 + 2249.000 112.687 2.678 + 2249.500 114.208 2.674 + 2250.000 117.062 2.673 + 2250.500 100.765 2.668 + 2251.000 91.304 2.671 + 2251.500 86.025 2.680 + 2252.000 76.805 2.688 + 2252.500 80.739 2.690 + 2253.000 79.837 2.694 + 2253.500 80.128 2.695 + 2254.000 80.397 2.697 + 2254.500 74.642 2.696 + 2255.000 72.815 2.695 + 2255.500 74.018 2.699 + 2256.000 75.495 2.704 + 2256.500 79.336 2.719 + 2257.000 79.054 2.723 + 2257.500 80.121 2.713 + 2258.000 79.162 2.699 + 2258.500 80.250 2.686 + 2259.000 83.186 2.691 + 2259.500 95.333 2.699 + 2260.000 108.661 2.707 + 2260.500 128.241 2.695 + 2261.000 127.498 2.689 + 2261.500 129.155 2.681 + 2262.000 122.720 2.662 + 2262.500 104.629 2.659 + 2263.000 98.590 2.669 + 2263.500 98.630 2.682 + 2264.000 98.877 2.681 + 2264.500 105.845 2.677 + 2265.000 114.483 2.673 + 2265.500 120.026 2.668 + 2266.000 124.562 2.671 + 2266.500 125.408 2.679 + 2267.000 124.679 2.718 + 2267.500 124.059 2.756 + 2268.000 125.424 2.738 + 2268.500 124.187 2.693 + 2269.000 121.154 2.653 + 2269.500 118.238 2.651 + 2270.000 113.420 2.686 + 2270.500 112.415 2.741 + 2271.000 114.426 2.708 + 2271.500 110.690 2.638 + 2272.000 110.393 2.581 + 2272.500 88.593 2.628 + 2273.000 79.752 2.694 + 2273.500 64.138 2.743 + 2274.000 64.806 2.772 + 2274.500 64.690 2.836 + 2275.000 79.607 2.840 + 2275.500 93.693 2.824 + 2276.000 110.390 2.745 + 2276.500 112.755 2.606 + 2277.000 113.475 2.619 + 2277.500 111.014 2.626 + 2278.000 102.927 2.631 + 2278.500 93.704 2.638 + 2279.000 85.611 2.643 + 2279.500 81.123 2.699 + 2280.000 70.792 2.792 + 2280.500 71.508 2.895 + 2281.000 71.828 2.864 + 2281.500 71.945 2.804 + 2282.000 72.158 2.769 + 2282.500 72.081 2.792 + 2283.000 70.348 2.800 + 2283.500 64.387 2.812 + 2284.000 52.805 2.788 + 2284.500 44.995 2.745 + 2285.000 42.650 2.742 + 2285.500 46.633 2.764 + 2286.000 51.849 2.795 + 2286.500 56.186 2.813 + 2287.000 56.325 2.814 + 2287.500 59.767 2.797 + 2288.000 60.151 2.771 + 2288.500 80.123 2.720 + 2289.000 85.973 2.706 + 2289.500 89.514 2.684 + 2290.000 89.899 2.682 + 2290.500 91.731 2.692 + 2291.000 93.247 2.705 + 2291.500 95.446 2.721 + 2292.000 91.850 2.722 + 2292.500 90.893 2.715 + 2293.000 89.999 2.704 + 2293.500 90.116 2.697 + 2294.000 89.172 2.684 + 2294.500 81.954 2.673 + 2295.000 75.415 2.673 + 2295.500 70.273 2.680 + 2296.000 66.731 2.702 + 2296.500 85.033 2.743 + 2297.000 103.953 2.734 + 2297.500 131.433 2.632 + 2298.000 137.544 2.598 + 2298.500 145.552 2.614 + 2299.000 144.601 2.638 + 2299.500 143.634 2.656 + 2300.000 141.302 2.657 + 2300.500 128.451 2.664 + 2301.000 112.634 2.682 + 2301.500 102.134 2.709 + 2302.000 95.298 2.743 + 2302.500 97.958 2.793 + 2303.000 104.519 2.759 + 2303.500 108.348 2.723 + 2304.000 118.055 2.693 + 2304.500 137.055 2.690 + 2305.000 140.071 2.696 + 2305.500 143.427 2.707 + 2306.000 145.393 2.710 + 2306.500 144.614 2.704 + 2307.000 141.663 2.701 + 2307.500 137.824 2.707 + 2308.000 138.164 2.712 + 2308.500 137.850 2.717 + 2309.000 141.126 2.714 + 2309.500 143.504 2.705 + 2310.000 149.539 2.704 + 2310.500 149.889 2.714 + 2311.000 150.040 2.717 + 2311.500 147.465 2.718 + 2312.000 145.335 2.710 + 2312.500 143.197 2.704 + 2313.000 142.877 2.703 + 2313.500 143.565 2.703 + 2314.000 144.856 2.702 + 2314.500 142.467 2.698 + 2315.000 140.321 2.700 + 2315.500 138.881 2.709 + 2316.000 138.359 2.716 + 2316.500 138.342 2.727 + 2317.000 136.786 2.728 + 2317.500 134.953 2.724 + 2318.000 131.710 2.712 + 2318.500 127.957 2.700 + 2319.000 126.522 2.688 + 2319.500 126.610 2.684 + 2320.000 128.808 2.680 + 2320.500 131.275 2.704 + 2321.000 132.860 2.717 + 2321.500 129.638 2.717 + 2322.000 126.325 2.717 + 2322.500 121.522 2.714 + 2323.000 121.151 2.704 + 2323.500 123.036 2.700 + 2324.000 123.867 2.704 + 2324.500 123.951 2.715 + 2325.000 126.415 2.716 + 2325.500 129.940 2.714 + 2326.000 135.765 2.701 + 2326.500 139.548 2.702 + 2327.000 142.213 2.708 + 2327.500 143.981 2.715 + 2328.000 143.544 2.721 + 2328.500 144.225 2.720 + 2329.000 143.667 2.717 + 2329.500 143.735 2.710 + 2330.000 144.253 2.702 + 2330.500 145.620 2.705 + 2331.000 146.788 2.713 + 2331.500 145.559 2.718 + 2332.000 141.287 2.719 + 2332.500 135.141 2.714 + 2333.000 130.449 2.711 + 2333.500 128.646 2.704 + 2334.000 129.084 2.694 + 2334.500 131.981 2.688 + 2335.000 133.972 2.688 + 2335.500 134.163 2.693 + 2336.000 136.015 2.695 + 2336.500 135.356 2.695 + 2337.000 138.235 2.695 + 2337.500 140.557 2.691 + 2338.000 146.334 2.680 + 2338.500 147.006 2.665 + 2339.000 146.894 2.670 + 2339.500 146.276 2.682 + 2340.000 145.846 2.694 + 2340.500 142.496 2.709 + 2341.000 141.141 2.717 + 2341.500 140.512 2.715 + 2342.000 140.538 2.711 + 2342.500 143.459 2.700 + 2343.000 147.345 2.696 + 2343.500 149.676 2.692 + 2344.000 151.606 2.692 + 2344.500 149.577 2.697 + 2345.000 147.703 2.705 + 2345.500 146.080 2.722 + 2346.000 143.533 2.733 + 2346.500 141.215 2.728 + 2347.000 143.106 2.720 + 2347.500 146.895 2.700 + 2348.000 148.483 2.702 + 2348.500 145.803 2.699 + 2349.000 144.412 2.700 + 2349.500 140.062 2.699 + 2350.000 140.566 2.703 + 2350.500 139.493 2.710 + 2351.000 139.027 2.717 + 2351.500 138.862 2.724 + 2352.000 140.390 2.717 + 2352.500 143.791 2.705 + 2353.000 146.024 2.701 + 2353.500 145.952 2.703 + 2354.000 144.548 2.706 + 2354.500 144.659 2.695 + 2355.000 145.516 2.685 + 2355.500 146.026 2.683 + 2356.000 146.641 2.693 + 2356.500 147.639 2.701 + 2357.000 148.448 2.708 + 2357.500 151.317 2.709 + 2358.000 153.066 2.710 + 2358.500 156.989 2.718 + 2359.000 157.183 2.719 + 2359.500 154.044 2.717 + 2360.000 153.399 2.710 + 2360.500 145.461 2.706 + 2361.000 142.152 2.710 + 2361.500 138.716 2.716 + 2362.000 139.210 2.721 + 2362.500 138.817 2.723 + 2363.000 144.069 2.727 + 2363.500 145.356 2.730 + 2364.000 146.862 2.731 + 2364.500 146.639 2.732 + 2365.000 145.400 2.732 + 2365.500 143.176 2.726 + 2366.000 142.915 2.719 + 2366.500 142.871 2.716 + 2367.000 143.029 2.715 + 2367.500 141.985 2.704 + 2368.000 140.090 2.698 + 2368.500 138.689 2.682 + 2369.000 138.251 2.675 + 2369.500 140.433 2.686 + 2370.000 142.047 2.702 + 2370.500 143.740 2.717 + 2371.000 144.484 2.713 + 2371.500 142.821 2.702 + 2372.000 140.237 2.695 + 2372.500 138.816 2.688 + 2373.000 139.695 2.680 + 2373.500 142.000 2.670 + 2374.000 142.745 2.671 + 2374.500 140.586 2.682 + 2375.000 139.964 2.698 + 2375.500 139.890 2.709 + 2376.000 141.177 2.717 + 2376.500 144.186 2.722 + 2377.000 146.015 2.725 + 2377.500 145.999 2.720 + 2378.000 146.657 2.712 + 2378.500 145.165 2.696 + 2379.000 144.505 2.685 + 2379.500 144.642 2.681 + 2380.000 145.184 2.679 + 2380.500 141.745 2.680 + 2381.000 138.542 2.683 + 2381.500 136.769 2.707 + 2382.000 135.460 2.718 + 2382.500 133.524 2.727 + 2383.000 132.396 2.723 + 2383.500 130.653 2.721 + 2384.000 129.527 2.719 + 2384.500 130.278 2.709 + 2385.000 131.945 2.695 + 2385.500 134.927 2.676 + 2386.000 137.308 2.680 + 2386.500 139.882 2.696 + 2387.000 141.590 2.694 + 2387.500 144.651 2.695 + 2388.000 143.604 2.696 + 2388.500 142.923 2.702 + 2389.000 143.026 2.703 + 2389.500 145.977 2.696 + 2390.000 147.674 2.694 + 2390.500 148.295 2.690 + 2391.000 147.563 2.695 + 2391.500 147.621 2.697 + 2392.000 147.794 2.697 + 2392.500 148.820 2.698 + 2393.000 150.070 2.695 + 2393.500 150.563 2.699 + 2394.000 150.826 2.706 + 2394.500 150.834 2.724 + 2395.000 150.536 2.729 + 2395.500 150.719 2.723 + 2396.000 151.824 2.714 + 2396.500 152.511 2.702 + 2397.000 151.566 2.699 + 2397.500 149.899 2.696 + 2398.000 149.051 2.695 + 2398.500 148.181 2.697 + 2399.000 147.504 2.699 + 2399.500 146.197 2.711 + 2400.000 142.973 2.701 + 2400.500 139.187 2.688 + 2401.000 133.902 2.678 + 2401.500 132.041 2.677 + 2402.000 132.242 2.684 + 2402.500 136.879 2.697 + 2403.000 138.943 2.706 + 2403.500 140.646 2.705 + 2404.000 143.708 2.700 + 2404.500 146.763 2.698 + 2405.000 147.807 2.707 + 2405.500 147.023 2.721 + 2406.000 146.060 2.725 + 2406.500 143.092 2.721 + 2407.000 143.003 2.722 + 2407.500 144.472 2.729 + 2408.000 146.521 2.727 + 2408.500 149.671 2.714 + 2409.000 147.717 2.710 + 2409.500 146.237 2.708 + 2410.000 145.449 2.702 + 2410.500 145.192 2.697 + 2411.000 146.046 2.693 + 2411.500 146.944 2.690 + 2412.000 146.841 2.694 + 2412.500 146.515 2.697 + 2413.000 145.439 2.700 + 2413.500 145.208 2.695 + 2414.000 145.848 2.694 + 2414.500 146.843 2.693 + 2415.000 147.727 2.695 + 2415.500 148.196 2.699 + 2416.000 146.123 2.708 + 2416.500 142.463 2.721 + 2417.000 139.796 2.718 + 2417.500 138.934 2.705 + 2418.000 137.349 2.697 + 2418.500 138.045 2.695 + 2419.000 139.782 2.704 + 2419.500 142.410 2.704 + 2420.000 143.710 2.699 + 2420.500 141.718 2.688 + 2421.000 139.869 2.682 + 2421.500 140.457 2.679 + 2422.000 141.495 2.677 + 2422.500 141.054 2.681 + 2423.000 143.091 2.691 + 2423.500 143.361 2.699 + 2424.000 144.630 2.703 + 2424.500 146.417 2.705 + 2425.000 147.018 2.702 + 2425.500 147.688 2.702 + 2426.000 147.643 2.711 + 2426.500 147.655 2.715 + 2427.000 147.501 2.715 + 2427.500 146.623 2.709 + 2428.000 146.013 2.700 + 2428.500 146.130 2.690 + 2429.000 145.983 2.687 + 2429.500 146.705 2.693 + 2430.000 146.829 2.691 + 2430.500 145.143 2.699 + 2431.000 143.881 2.709 + 2431.500 140.970 2.711 + 2432.000 140.763 2.704 + 2432.500 136.427 2.689 + 2433.000 132.341 2.686 + 2433.500 127.959 2.686 + 2434.000 123.293 2.694 + 2434.500 118.373 2.702 + 2435.000 119.146 2.700 + 2435.500 119.628 2.699 + 2436.000 122.967 2.687 + 2436.500 127.439 2.673 + 2437.000 130.559 2.677 + 2437.500 133.984 2.697 + 2438.000 137.060 2.707 + 2438.500 139.252 2.716 + 2439.000 140.171 2.712 + 2439.500 140.449 2.698 + 2440.000 140.575 2.683 + 2440.500 141.171 2.673 + 2441.000 141.300 2.680 + 2441.500 143.720 2.689 + 2442.000 144.372 2.693 + 2442.500 146.027 2.691 + 2443.000 145.319 2.689 + 2443.500 141.528 2.693 + 2444.000 139.165 2.701 + 2444.500 138.865 2.711 + 2445.000 139.706 2.717 + 2445.500 141.546 2.718 + 2446.000 142.850 2.724 + 2446.500 140.227 2.710 + 2447.000 138.123 2.704 + 2447.500 137.027 2.704 + 2448.000 138.850 2.704 + 2448.500 142.545 2.693 + 2449.000 143.726 2.688 + 2449.500 143.592 2.685 + 2450.000 142.108 2.690 + 2450.500 140.163 2.695 + 2451.000 140.368 2.699 + 2451.500 141.273 2.701 + 2452.000 145.025 2.707 + 2452.500 147.469 2.709 + 2453.000 148.646 2.710 + 2453.500 149.662 2.702 + 2454.000 150.923 2.697 + 2454.500 152.780 2.698 + 2455.000 153.903 2.699 + 2455.500 153.215 2.710 + 2456.000 151.806 2.712 + 2456.500 149.704 2.708 + 2457.000 148.611 2.706 + 2457.500 148.346 2.704 + 2458.000 149.198 2.698 + 2458.500 150.173 2.687 + 2459.000 151.495 2.679 + 2459.500 151.399 2.678 + 2460.000 150.598 2.678 + 2460.500 149.741 2.685 + 2461.000 149.259 2.689 + 2461.500 148.610 2.698 + 2462.000 148.210 2.704 + 2462.500 148.219 2.700 + 2463.000 150.248 2.691 + 2463.500 152.488 2.681 + 2464.000 152.858 2.679 + 2464.500 151.524 2.687 + 2465.000 150.911 2.699 + 2465.500 151.464 2.707 + 2466.000 151.482 2.713 + 2466.500 151.615 2.719 + 2467.000 149.351 2.721 + 2467.500 147.606 2.711 + 2468.000 146.560 2.685 + 2468.500 146.611 2.660 + 2469.000 147.380 2.662 + 2469.500 149.001 2.680 + 2470.000 150.249 2.694 + 2470.500 148.782 2.697 + 2471.000 147.637 2.700 + 2471.500 146.820 2.704 + 2472.000 146.100 2.707 + 2472.500 144.652 2.709 + 2473.000 141.674 2.709 + 2473.500 141.462 2.707 + 2474.000 141.061 2.706 + 2474.500 142.591 2.700 + 2475.000 140.736 2.696 + 2475.500 138.520 2.690 + 2476.000 138.000 2.689 + 2476.500 139.469 2.685 + 2477.000 142.214 2.683 + 2477.500 146.242 2.679 + 2478.000 148.472 2.678 + 2478.500 149.886 2.686 + 2479.000 149.854 2.699 + 2479.500 149.353 2.701 + 2480.000 149.404 2.701 + 2480.500 147.484 2.693 + 2481.000 146.084 2.689 + 2481.500 144.402 2.692 + 2482.000 143.794 2.697 + 2482.500 144.695 2.703 + 2483.000 145.935 2.711 + 2483.500 148.351 2.718 + 2484.000 149.306 2.721 + 2484.500 148.992 2.712 + 2485.000 148.453 2.707 + 2485.500 147.983 2.707 + 2486.000 148.165 2.722 + 2486.500 146.586 2.731 + 2487.000 145.433 2.728 + 2487.500 145.168 2.726 + 2488.000 146.215 2.726 + 2488.500 148.114 2.722 + 2489.000 151.454 2.716 + 2489.500 151.864 2.709 + 2490.000 152.038 2.709 + 2490.500 149.667 2.718 + 2491.000 148.518 2.718 + 2491.500 151.068 2.719 + 2492.000 153.667 2.717 + 2492.500 156.642 2.713 + 2493.000 155.601 2.709 + 2493.500 152.959 2.709 + 2494.000 149.610 2.713 + 2494.500 146.739 2.728 + 2495.000 146.971 2.735 + 2495.500 146.936 2.733 + 2496.000 148.752 2.727 + 2496.500 153.312 2.723 + 2497.000 155.620 2.725 + 2497.500 156.405 2.730 + 2498.000 156.034 2.730 + 2498.500 153.886 2.722 + 2499.000 152.042 2.715 + 2499.500 150.697 2.706 + 2500.000 150.350 2.703 + 2500.500 149.615 2.700 + 2501.000 148.471 2.706 + 2501.500 148.453 2.709 + 2502.000 148.055 2.708 + 2502.500 147.844 2.697 + 2503.000 149.534 2.687 + 2503.500 151.395 2.683 + 2504.000 152.571 2.684 + 2504.500 154.023 2.686 + 2505.000 154.701 2.691 + 2505.500 155.363 2.701 + 2506.000 155.329 2.704 + 2506.500 152.302 2.711 + 2507.000 150.058 2.710 + 2507.500 149.964 2.701 + 2508.000 150.567 2.685 + 2508.500 151.357 2.674 + 2509.000 152.307 2.685 + 2509.500 154.026 2.706 + 2510.000 154.836 2.712 + 2510.500 156.104 2.709 + 2511.000 155.470 2.707 + 2511.500 153.918 2.708 + 2512.000 150.652 2.715 + 2512.500 148.860 2.719 + 2513.000 147.488 2.714 + 2513.500 147.562 2.711 + 2514.000 148.350 2.711 + 2514.500 150.695 2.708 + 2515.000 153.854 2.700 + 2515.500 155.423 2.694 + 2516.000 155.478 2.681 + 2516.500 155.576 2.680 + 2517.000 154.993 2.679 + 2517.500 153.470 2.681 + 2518.000 153.384 2.688 + 2518.500 155.584 2.705 + 2519.000 156.955 2.714 + 2519.500 157.013 2.713 + 2520.000 155.520 2.703 + 2520.500 154.758 2.690 + 2521.000 154.915 2.696 + 2521.500 155.515 2.701 + 2522.000 156.003 2.713 + 2522.500 155.363 2.696 + 2523.000 155.692 2.678 + 2523.500 154.884 2.678 + 2524.000 153.737 2.687 + 2524.500 150.590 2.695 + 2525.000 149.826 2.704 + 2525.500 151.439 2.715 + 2526.000 152.605 2.725 + 2526.500 152.655 2.728 + 2527.000 151.736 2.714 + 2527.500 148.949 2.698 + 2528.000 146.252 2.694 + 2528.500 143.660 2.697 + 2529.000 144.021 2.706 + 2529.500 146.135 2.718 + 2530.000 147.239 2.720 + 2530.500 147.724 2.724 + 2531.000 147.035 2.704 + 2531.500 146.920 2.698 + 2532.000 148.256 2.701 + 2532.500 149.231 2.709 + 2533.000 150.053 2.707 + 2533.500 149.806 2.699 + 2534.000 147.461 2.683 + 2534.500 146.617 2.654 + 2535.000 146.823 2.634 + 2535.500 149.518 2.634 + 2536.000 150.893 2.655 + 2536.500 150.787 2.702 + 2537.000 150.721 2.710 + 2537.500 151.371 2.698 + 2538.000 152.408 2.685 + 2538.500 153.142 2.673 + 2539.000 153.762 2.674 + 2539.500 152.833 2.692 + 2540.000 151.858 2.709 + 2540.500 147.183 2.720 + 2541.000 142.824 2.719 + 2541.500 140.510 2.717 + 2542.000 138.884 2.710 + 2542.500 137.459 2.697 + 2543.000 135.722 2.687 + 2543.500 134.961 2.692 + 2544.000 135.000 2.734 + 2544.500 135.698 2.740 + 2545.000 138.064 2.725 + 2545.500 141.424 2.662 + 2546.000 142.027 2.621 + 2546.500 143.185 2.632 + 2547.000 142.950 2.663 + 2547.500 141.968 2.685 + 2548.000 141.445 2.700 + 2548.500 141.935 2.701 + 2549.000 142.289 2.698 + 2549.500 144.279 2.689 + 2550.000 143.421 2.696 + 2550.500 145.868 2.700 + 2551.000 147.437 2.702 + 2551.500 150.861 2.700 + 2552.000 153.713 2.688 + 2552.500 154.529 2.675 + 2553.000 154.722 2.683 + 2553.500 155.532 2.693 + 2554.000 156.242 2.709 + 2554.500 155.313 2.704 + 2555.000 154.512 2.696 + 2555.500 153.822 2.683 + 2556.000 152.359 2.677 + 2556.500 150.806 2.678 + 2557.000 149.192 2.695 + 2557.500 147.609 2.713 + 2558.000 146.125 2.717 + 2558.500 143.795 2.717 + 2559.000 142.900 2.723 + 2559.500 144.495 2.732 + 2560.000 146.819 2.730 + 2560.500 151.520 2.718 + 2561.000 152.611 2.715 + 2561.500 152.586 2.714 + 2562.000 152.391 2.716 + 2562.500 151.787 2.719 + 2563.000 150.903 2.724 + 2563.500 149.066 2.732 + 2564.000 148.483 2.735 + 2564.500 147.834 2.725 + 2565.000 149.330 2.699 + 2565.500 150.131 2.669 + 2566.000 150.811 2.662 + 2566.500 149.235 2.671 + 2567.000 149.379 2.677 + 2567.500 150.166 2.684 + 2568.000 149.184 2.709 + 2568.500 148.205 2.717 + 2569.000 147.567 2.719 + 2569.500 147.698 2.717 + 2570.000 147.469 2.711 + 2570.500 146.595 2.695 + 2571.000 146.110 2.695 + 2571.500 145.386 2.695 + 2572.000 145.984 2.696 + 2572.500 147.646 2.689 + 2573.000 148.626 2.683 + 2573.500 147.721 2.678 + 2574.000 146.891 2.676 + 2574.500 142.312 2.679 + 2575.000 142.645 2.693 + 2575.500 144.658 2.697 + 2576.000 147.779 2.711 + 2576.500 150.123 2.717 + 2577.000 148.704 2.719 + 2577.500 147.765 2.713 + 2578.000 146.100 2.685 + 2578.500 146.049 2.680 + 2579.000 146.666 2.684 + 2579.500 148.660 2.685 + 2580.000 150.298 2.684 + 2580.500 150.842 2.670 + 2581.000 149.987 2.670 + 2581.500 146.889 2.675 + 2582.000 145.311 2.682 + 2582.500 143.862 2.694 + 2583.000 145.493 2.700 + 2583.500 149.295 2.708 + 2584.000 151.544 2.711 + 2584.500 151.395 2.717 + 2585.000 150.558 2.741 + 2585.500 150.099 2.748 + 2586.000 151.046 2.750 + 2586.500 151.629 2.703 + 2587.000 151.541 2.694 + 2587.500 152.209 2.697 + 2588.000 154.518 2.704 + 2588.500 154.682 2.701 + 2589.000 152.345 2.696 + 2589.500 150.210 2.690 + 2590.000 148.657 2.695 + 2590.500 149.076 2.714 + 2591.000 149.168 2.723 + 2591.500 149.202 2.719 + 2592.000 147.286 2.708 + 2592.500 144.187 2.696 + 2593.000 142.201 2.694 + 2593.500 142.229 2.695 + 2594.000 143.603 2.699 + 2594.500 143.532 2.707 + 2595.000 142.756 2.704 + 2595.500 143.725 2.714 + 2596.000 144.624 2.719 + 2596.500 145.722 2.722 + 2597.000 146.829 2.714 + 2597.500 148.005 2.703 + 2598.000 149.167 2.699 + 2598.500 150.244 2.695 + 2599.000 151.447 2.695 + 2599.500 151.946 2.697 + 2600.000 152.991 2.704 + 2600.500 153.794 2.714 + 2601.000 152.473 2.713 + 2601.500 151.473 2.715 + 2602.000 149.895 2.717 + 2602.500 149.166 2.713 + 2603.000 147.010 2.706 + 2603.500 145.271 2.700 + 2604.000 143.608 2.701 + 2604.500 141.410 2.702 + 2605.000 140.733 2.702 + 2605.500 140.553 2.706 + 2606.000 139.797 2.711 + 2606.500 137.747 2.710 + 2607.000 135.685 2.697 + 2607.500 134.002 2.696 + 2608.000 137.850 2.688 + 2608.500 142.015 2.682 + 2609.000 144.342 2.679 + 2609.500 148.096 2.678 + 2610.000 149.243 2.677 + 2610.500 147.448 2.679 + 2611.000 147.036 2.683 + 2611.500 140.467 2.691 + 2612.000 132.926 2.689 + 2612.500 111.653 2.740 + 2613.000 101.108 2.766 + 2613.500 90.751 2.808 + 2614.000 83.172 2.821 + 2614.500 74.884 2.848 + 2615.000 66.845 2.879 + 2615.500 61.804 2.890 + 2616.000 59.785 2.890 + 2616.500 58.363 2.895 + 2617.000 59.380 2.906 + 2617.500 63.937 2.907 + 2618.000 68.969 2.902 + 2618.500 76.825 2.889 + 2619.000 86.493 2.851 + 2619.500 95.730 2.811 + 2620.000 104.474 2.798 + 2620.500 114.745 2.785 + 2621.000 120.503 2.758 + 2621.500 120.887 2.730 + 2622.000 113.778 2.729 + 2622.500 91.021 2.732 + 2623.000 73.035 2.742 + 2623.500 58.187 2.757 + 2624.000 54.452 2.776 + 2624.500 52.494 2.781 + 2625.000 51.593 2.744 + 2625.500 52.021 2.731 + 2626.000 53.595 2.731 + 2626.500 55.510 2.731 + 2627.000 56.573 2.729 + 2627.500 57.066 2.713 + 2628.000 59.025 2.703 + 2628.500 61.880 2.684 + 2629.000 70.549 2.677 + 2629.500 79.182 2.663 + 2630.000 91.758 2.656 + 2630.500 99.731 2.653 + 2631.000 101.633 2.664 + 2631.500 106.429 2.682 + 2632.000 108.713 2.689 + 2632.500 114.768 2.702 + 2633.000 114.572 2.713 + 2633.500 112.811 2.723 + 2634.000 108.166 2.726 + 2634.500 105.369 2.728 + 2635.000 104.529 2.732 + 2635.500 102.700 2.748 + 2636.000 98.158 2.777 + 2636.500 86.305 2.791 + 2637.000 74.724 2.792 + 2637.500 67.695 2.793 + 2638.000 61.243 2.797 + 2638.500 62.229 2.808 + 2639.000 68.450 2.840 + 2639.500 73.621 2.861 + 2640.000 75.572 2.850 + 2640.500 76.044 2.723 + 2641.000 75.773 2.675 + 2641.500 74.775 2.682 + 2642.000 72.057 2.703 + 2642.500 68.874 2.759 + 2643.000 64.417 2.774 + 2643.500 61.357 2.796 + 2644.000 59.230 2.820 + 2644.500 60.049 2.835 + 2645.000 61.420 2.840 + 2645.500 62.138 2.830 + 2646.000 62.251 2.802 + 2646.500 57.833 2.797 + 2647.000 56.199 2.796 + 2647.500 57.062 2.789 + 2648.000 59.711 2.788 + 2648.500 58.025 2.794 + 2649.000 56.033 2.788 + 2649.500 54.133 2.781 + 2650.000 53.017 2.775 + 2650.500 56.486 2.768 + 2651.000 59.873 2.767 + 2651.500 61.573 2.766 + 2652.000 62.954 2.761 + 2652.500 62.203 2.774 + 2653.000 62.575 2.784 + 2653.500 65.882 2.785 + 2654.000 76.062 2.779 + 2654.500 90.309 2.736 + 2655.000 102.513 2.705 + 2655.500 115.643 2.699 + 2656.000 116.662 2.704 + 2656.500 116.836 2.718 + 2657.000 115.835 2.718 + 2657.500 112.282 2.713 + 2658.000 107.859 2.711 + 2658.500 94.104 2.725 + 2659.000 89.155 2.728 + 2659.500 81.094 2.736 + 2660.000 78.087 2.744 + 2660.500 71.437 2.750 + 2661.000 65.941 2.752 + 2661.500 62.579 2.752 + 2662.000 66.906 2.753 + 2662.500 77.498 2.750 + 2663.000 88.797 2.745 + 2663.500 92.729 2.733 + 2664.000 95.486 2.704 + 2664.500 98.708 2.645 + 2665.000 100.194 2.631 + 2665.500 100.553 2.654 + 2666.000 101.673 2.710 + 2666.500 108.924 2.750 + 2667.000 117.265 2.734 + 2667.500 131.276 2.687 + 2668.000 136.097 2.671 + 2668.500 148.007 2.667 + 2669.000 151.096 2.687 + 2669.500 148.410 2.697 + 2670.000 137.209 2.705 + 2670.500 126.945 2.716 + 2671.000 119.934 2.737 + 2671.500 113.306 2.770 + 2672.000 108.199 2.799 + 2672.500 107.242 2.795 + 2673.000 108.956 2.779 + 2673.500 109.338 2.744 + 2674.000 107.145 2.706 + 2674.500 101.305 2.690 + 2675.000 98.118 2.685 + 2675.500 96.538 2.691 + 2676.000 96.213 2.706 + 2676.500 99.662 2.690 + 2677.000 100.808 2.669 + 2677.500 111.733 2.572 + 2678.000 112.529 2.509 + 2678.500 111.599 2.525 + 2679.000 104.770 2.555 + 2679.500 99.471 2.598 + 2680.000 97.694 2.635 + 2680.500 93.306 2.715 + 2681.000 88.966 2.742 + 2681.500 87.739 2.780 + 2682.000 91.022 2.750 + 2682.500 108.320 2.663 + 2683.000 121.671 2.599 + 2683.500 131.515 2.589 + 2684.000 143.534 2.583 + 2684.500 145.353 2.638 + 2685.000 145.993 2.656 + 2685.500 146.111 2.661 + 2686.000 145.824 2.659 + 2686.500 136.910 2.662 + 2687.000 127.402 2.665 + 2687.500 121.670 2.671 + 2688.000 117.954 2.674 + 2688.500 118.677 2.671 + 2689.000 123.491 2.664 + 2689.500 129.411 2.655 + 2690.000 132.449 2.609 + 2690.500 135.196 2.567 + 2691.000 137.932 2.557 + 2691.500 139.850 2.556 + 2692.000 139.429 2.585 + 2692.500 120.560 2.618 + 2693.000 98.103 2.639 + 2693.500 85.781 2.648 + 2694.000 66.307 2.642 + 2694.500 56.417 2.643 + 2695.000 57.666 2.633 + 2695.500 63.776 2.635 + 2696.000 66.542 2.633 + 2696.500 69.133 2.639 + 2697.000 68.437 2.640 + 2697.500 76.899 2.646 + 2698.000 90.391 2.649 + 2698.500 109.997 2.659 + 2699.000 115.670 2.658 + 2699.500 125.371 2.648 + 2700.000 133.743 2.641 + 2700.500 120.297 2.631 + 2701.000 99.998 2.623 + 2701.500 77.693 2.625 + 2702.000 54.462 2.636 + 2702.500 48.557 2.636 + 2703.000 37.131 2.619 + 2703.500 33.115 2.611 + 2704.000 36.311 2.618 + 2704.500 50.744 2.642 + 2705.000 58.969 2.660 + 2705.500 73.959 2.672 + 2706.000 85.397 2.676 + 2706.500 101.234 2.683 + 2707.000 114.319 2.689 + 2707.500 127.571 2.699 + 2708.000 139.839 2.703 + 2708.500 150.526 2.699 + 2709.000 153.637 2.699 + 2709.500 156.306 2.699 + 2710.000 156.434 2.697 + 2710.500 156.913 2.686 + 2711.000 157.733 2.669 + 2711.500 158.773 2.659 + 2712.000 158.589 2.656 + 2712.500 154.528 2.665 + 2713.000 150.456 2.674 + 2713.500 148.448 2.674 + 2714.000 147.769 2.671 + 2714.500 147.742 2.641 + 2715.000 151.069 2.618 + 2715.500 149.450 2.599 + 2716.000 151.134 2.595 + 2716.500 112.140 2.600 + 2717.000 93.223 2.606 + 2717.500 70.296 2.616 + 2718.000 65.559 2.640 + 2718.500 70.926 2.674 + 2719.000 73.590 2.666 + 2719.500 76.191 2.659 + 2720.000 69.844 2.610 + 2720.500 46.698 2.599 + 2721.000 40.028 2.590 + 2721.500 37.754 2.585 + 2722.000 40.196 2.581 + 2722.500 44.618 2.587 + 2723.000 53.098 2.604 + 2723.500 64.910 2.633 + 2724.000 74.472 2.676 + 2724.500 104.479 2.659 + 2725.000 130.567 2.647 + 2725.500 135.614 2.632 + 2726.000 137.283 2.613 + 2726.500 135.282 2.557 + 2727.000 134.642 2.590 + 2727.500 129.488 2.671 + 2728.000 127.336 2.692 + 2728.500 122.573 2.711 + 2729.000 118.600 2.663 + 2729.500 107.989 2.652 + 2730.000 108.604 2.647 + 2730.500 111.553 2.648 + 2731.000 111.834 2.645 + 2731.500 108.334 2.648 + 2732.000 94.196 2.662 + 2732.500 84.338 2.677 + 2733.000 86.539 2.675 + 2733.500 95.694 2.654 + 2734.000 132.134 2.616 + 2734.500 139.351 2.607 + 2735.000 143.640 2.603 + 2735.500 142.479 2.620 + 2736.000 140.388 2.626 + 2736.500 126.844 2.660 + 2737.000 122.262 2.652 + 2737.500 119.566 2.649 + 2738.000 125.238 2.648 + 2738.500 131.122 2.660 + 2739.000 133.175 2.671 + 2739.500 129.223 2.667 + 2740.000 126.739 2.670 + 2740.500 113.024 2.679 + 2741.000 103.483 2.684 + 2741.500 101.893 2.655 + 2742.000 98.926 2.638 + 2742.500 93.361 2.627 + 2743.000 79.384 2.645 + 2743.500 76.861 2.636 + 2744.000 76.211 2.624 + 2744.500 79.122 2.615 + 2745.000 91.215 2.614 + 2745.500 103.680 2.623 + 2746.000 108.725 2.633 + 2746.500 106.849 2.653 + 2747.000 106.178 2.658 + 2747.500 90.385 2.660 + 2748.000 85.252 2.659 + 2748.500 89.712 2.676 + 2749.000 100.280 2.670 + 2749.500 119.262 2.667 + 2750.000 133.343 2.605 + 2750.500 141.017 2.581 + 2751.000 141.335 2.589 + 2751.500 139.813 2.625 + 2752.000 136.307 2.652 + 2752.500 132.742 2.665 + 2753.000 123.307 2.665 + 2753.500 117.712 2.649 + 2754.000 112.324 2.639 + 2754.500 110.189 2.639 + 2755.000 109.182 2.640 + 2755.500 103.523 2.641 + 2756.000 97.586 2.641 + 2756.500 85.441 2.643 + 2757.000 71.895 2.636 + 2757.500 67.364 2.625 + 2758.000 59.479 2.617 + 2758.500 50.139 2.608 + 2759.000 49.902 2.600 + 2759.500 51.846 2.598 + 2760.000 54.636 2.596 + 2760.500 57.273 2.594 + 2761.000 52.571 2.598 + 2761.500 47.553 2.613 + 2762.000 42.069 2.622 + 2762.500 44.152 2.632 + 2763.000 48.355 2.620 + 2763.500 57.884 2.606 + 2764.000 68.974 2.599 + 2764.500 79.793 2.603 + 2765.000 80.739 2.622 + 2765.500 75.010 2.632 + 2766.000 62.695 2.636 + 2766.500 54.345 2.622 + 2767.000 52.633 2.608 + 2767.500 53.445 2.602 + 2768.000 60.067 2.612 + 2768.500 67.238 2.624 + 2769.000 67.684 2.640 + 2769.500 67.494 2.648 + 2770.000 62.274 2.638 + 2770.500 54.663 2.623 + 2771.000 51.156 2.609 + 2771.500 46.689 2.597 + 2772.000 40.080 2.585 + 2772.500 31.503 2.573 + 2773.000 28.274 2.584 + 2773.500 22.906 2.591 + 2774.000 21.512 2.594 + 2774.500 21.621 2.588 + 2775.000 21.574 2.587 + 2775.500 22.120 2.590 + 2776.000 21.493 2.596 + 2776.500 21.717 2.597 + 2777.000 21.924 2.590 + 2777.500 25.958 2.583 + 2778.000 31.305 2.581 + 2778.500 35.907 2.596 + 2779.000 37.360 2.607 + 2779.500 38.712 2.648 + 2780.000 39.295 2.643 + 2780.500 35.044 2.594 + 2781.000 31.700 2.572 + 2781.500 30.288 2.561 + 2782.000 34.361 2.584 + 2782.500 46.495 2.594 + 2783.000 62.387 2.610 + 2783.500 82.382 2.614 + 2784.000 109.500 2.661 + 2784.500 113.348 2.670 + 2785.000 112.897 2.670 + 2785.500 109.073 2.651 + 2786.000 100.284 2.637 + 2786.500 96.103 2.632 + 2787.000 92.276 2.634 + 2787.500 87.134 2.644 + 2788.000 80.270 2.649 + 2788.500 75.155 2.652 + 2789.000 68.148 2.642 + 2789.500 67.190 2.634 + 2790.000 66.099 2.621 + 2790.500 73.975 2.621 + 2791.000 79.326 2.623 + 2791.500 78.838 2.623 + 2792.000 74.184 2.621 + 2792.500 60.231 2.584 + 2793.000 69.877 2.559 + 2793.500 78.475 2.525 + 2794.000 87.687 2.479 + 2794.500 96.746 2.493 + 2795.000 106.413 2.541 + 2795.500 112.766 2.570 + 2796.000 121.043 2.517 + 2796.500 127.754 2.522 + 2797.000 131.639 2.553 + 2797.500 132.982 2.612 + 2798.000 134.572 2.665 + 2798.500 143.587 2.604 + 2799.000 143.363 2.565 + 2799.500 137.906 2.540 + 2800.000 120.558 2.541 + 2800.500 82.965 2.573 + 2801.000 67.671 2.599 + 2801.500 62.370 2.624 + 2802.000 65.192 2.653 + 2802.500 73.823 2.655 + 2803.000 79.232 2.652 + 2803.500 78.949 2.627 + 2804.000 79.036 2.619 + 2804.500 80.037 2.616 + 2805.000 80.594 2.613 + 2805.500 83.681 2.612 + 2806.000 86.281 2.617 + 2806.500 94.921 2.647 + 2807.000 101.031 2.653 + 2807.500 101.308 2.648 + 2808.000 91.692 2.634 + 2808.500 85.913 2.617 + 2809.000 95.085 2.581 + 2809.500 99.557 2.502 + 2810.000 113.307 2.454 + 2810.500 125.163 2.496 + 2811.000 104.705 2.519 + 2811.500 90.931 2.543 + 2812.000 74.591 2.577 + 2812.500 62.307 2.605 + 2813.000 61.196 2.615 + 2813.500 63.353 2.634 + 2814.000 63.792 2.655 + 2814.500 57.470 2.662 + 2815.000 50.421 2.639 + 2815.500 37.411 2.611 + 2816.000 33.030 2.603 + 2816.500 25.742 2.592 + 2817.000 23.333 2.586 + 2817.500 20.877 2.585 + 2818.000 20.482 2.585 + 2818.500 19.116 2.584 + 2819.000 19.286 2.583 + 2819.500 19.230 2.585 + 2820.000 19.532 2.589 + 2820.500 21.951 2.593 + 2821.000 25.555 2.597 + 2821.500 31.343 2.605 + 2822.000 38.478 2.617 + 2822.500 40.551 2.624 + 2823.000 43.112 2.622 + 2823.500 40.274 2.604 + 2824.000 37.273 2.596 + 2824.500 30.762 2.588 + 2825.000 30.658 2.597 + 2825.500 33.168 2.595 + 2826.000 35.523 2.594 + 2826.500 38.237 2.592 + 2827.000 40.779 2.610 + 2827.500 51.123 2.617 + 2828.000 54.573 2.619 + 2828.500 51.344 2.619 + 2829.000 33.268 2.600 + 2829.500 27.555 2.598 + 2830.000 30.225 2.599 + 2830.500 44.271 2.609 + 2831.000 56.881 2.618 + 2831.500 70.412 2.637 + 2832.000 90.605 2.648 + 2832.500 111.729 2.646 + 2833.000 121.364 2.636 + 2833.500 120.545 2.626 + 2834.000 100.860 2.615 + 2834.500 94.988 2.620 + 2835.000 80.778 2.628 + 2835.500 68.136 2.628 + 2836.000 55.934 2.623 + 2836.500 48.009 2.611 + 2837.000 29.787 2.599 + 2837.500 22.931 2.586 + 2838.000 18.666 2.579 + 2838.500 17.908 2.573 + 2839.000 14.391 2.569 + 2839.500 14.064 2.577 + 2840.000 12.998 2.585 + 2840.500 12.925 2.594 + 2841.000 12.939 2.595 + 2841.500 14.607 2.592 + 2842.000 16.132 2.595 + 2842.500 20.306 2.588 + 2843.000 26.896 2.575 + 2843.500 41.347 2.564 + 2844.000 59.373 2.385 + 2844.500 91.530 2.157 + 2845.000 97.241 2.094 + 2845.500 92.937 2.247 + 2846.000 85.689 2.462 + 2846.500 78.825 2.622 + 2847.000 74.830 2.616 + 2847.500 69.642 2.609 + 2848.000 64.178 2.600 + 2848.500 58.151 2.591 + 2849.000 53.109 2.589 + 2849.500 46.206 2.587 + 2850.000 42.942 2.587 + 2850.500 30.130 2.593 + 2851.000 17.972 2.599 + 2851.500 16.202 2.596 + 2852.000 14.638 2.585 + 2852.500 14.371 2.580 + 2853.000 13.647 2.578 + 2853.500 13.754 2.577 + 2854.000 13.981 2.578 + 2854.500 14.067 2.579 + 2855.000 14.863 2.583 + 2855.500 14.927 2.587 + 2856.000 16.351 2.587 + 2856.500 18.917 2.587 + 2857.000 19.277 2.584 + 2857.500 19.500 2.576 + 2858.000 20.223 2.566 + 2858.500 21.652 2.548 + 2859.000 23.106 2.542 + 2859.500 23.801 2.541 + 2860.000 23.932 2.576 + 2860.500 21.785 2.597 + 2861.000 21.555 2.598 + 2861.500 23.040 2.595 + 2862.000 24.683 2.589 + 2862.500 24.635 2.583 + 2863.000 21.921 2.583 + 2863.500 20.522 2.581 + 2864.000 19.304 2.574 + 2864.500 17.663 2.570 + 2865.000 16.328 2.565 + 2865.500 15.507 2.563 + 2866.000 15.335 2.567 + 2866.500 15.316 2.578 + 2867.000 15.381 2.585 + 2867.500 15.339 2.587 + 2868.000 15.190 2.585 + 2868.500 14.499 2.580 + 2869.000 14.673 2.577 + 2869.500 16.192 2.579 + 2870.000 17.369 2.585 + 2870.500 18.541 2.589 + 2871.000 19.451 2.593 + 2871.500 18.697 2.593 + 2872.000 17.662 2.590 + 2872.500 15.184 2.578 + 2873.000 14.445 2.571 + 2873.500 13.469 2.574 + 2874.000 13.437 2.590 + 2874.500 12.925 2.604 + 2875.000 12.997 2.605 + 2875.500 13.059 2.601 + 2876.000 12.330 2.598 + 2876.500 12.212 2.595 + 2877.000 12.308 2.579 + 2877.500 13.233 2.570 + 2878.000 13.976 2.565 + 2878.500 14.637 2.562 + 2879.000 14.495 2.551 + 2879.500 14.666 2.548 + 2880.000 14.065 2.552 + 2880.500 14.660 2.555 + 2881.000 14.525 2.565 + 2881.500 14.526 2.575 + 2882.000 15.227 2.592 + 2882.500 15.136 2.597 + 2883.000 14.606 2.593 + 2883.500 14.099 2.586 + 2884.000 14.590 2.574 + 2884.500 15.258 2.558 + 2885.000 16.335 2.564 + 2885.500 15.496 2.574 + 2886.000 15.207 2.577 + 2886.500 14.331 2.581 + 2887.000 13.578 2.583 + 2887.500 12.901 2.586 + 2888.000 13.186 2.582 + 2888.500 13.969 2.578 + 2889.000 14.576 2.579 + 2889.500 15.449 2.585 + 2890.000 17.658 2.592 + 2890.500 20.138 2.598 + 2891.000 20.243 2.593 + 2891.500 19.786 2.587 + 2892.000 18.532 2.575 + 2892.500 16.380 2.570 + 2893.000 14.404 2.573 + 2893.500 14.553 2.573 + 2894.000 14.629 2.572 + 2894.500 14.453 2.571 + 2895.000 14.738 2.584 + 2895.500 13.403 2.596 + 2896.000 13.906 2.599 + 2896.500 13.638 2.597 + 2897.000 14.348 2.593 + 2897.500 15.350 2.589 + 2898.000 16.376 2.580 + 2898.500 16.983 2.549 + 2899.000 16.895 2.529 + 2899.500 17.025 2.520 + 2900.000 18.591 2.535 + 2900.500 20.252 2.545 + 2901.000 21.569 2.579 + 2901.500 21.619 2.590 + 2902.000 21.681 2.604 + 2902.500 21.808 2.606 + 2903.000 22.481 2.604 + 2903.500 23.017 2.602 + 2904.000 23.754 2.620 + 2904.500 24.759 2.626 + 2905.000 24.203 2.626 + 2905.500 23.325 2.614 + 2906.000 21.663 2.586 + 2906.500 21.719 2.579 + 2907.000 21.567 2.589 + 2907.500 21.604 2.616 + 2908.000 22.823 2.616 + 2908.500 26.587 2.601 + 2909.000 28.592 2.598 + 2909.500 32.729 2.587 + 2910.000 35.194 2.587 + 2910.500 39.172 2.589 + 2911.000 36.495 2.585 + 2911.500 31.906 2.583 + 2912.000 25.804 2.583 + 2912.500 21.660 2.587 + 2913.000 20.648 2.595 + 2913.500 19.901 2.597 + 2914.000 20.934 2.599 + 2914.500 21.098 2.593 + 2915.000 20.815 2.587 + 2915.500 21.263 2.590 + 2916.000 22.551 2.592 + 2916.500 21.325 2.586 + 2917.000 24.624 2.581 + 2917.500 26.926 2.580 + 2918.000 28.276 2.592 + 2918.500 28.998 2.612 + 2919.000 29.230 2.618 + 2919.500 27.611 2.613 + 2920.000 25.593 2.609 + 2920.500 25.620 2.600 + 2921.000 24.020 2.597 + 2921.500 23.966 2.597 + 2922.000 22.411 2.596 + 2922.500 20.965 2.596 + 2923.000 20.881 2.595 + 2923.500 20.815 2.584 + 2924.000 20.927 2.574 + 2924.500 20.891 2.542 + 2925.000 22.414 2.530 + 2925.500 21.973 2.536 + 2926.000 22.054 2.548 + 2926.500 20.286 2.553 + 2927.000 19.293 2.551 + 2927.500 18.650 2.542 + 2928.000 20.117 2.534 + 2928.500 21.457 2.531 + 2929.000 21.668 2.535 + 2929.500 21.050 2.549 + 2930.000 20.786 2.551 + 2930.500 19.975 2.570 + 2931.000 22.078 2.579 + 2931.500 25.155 2.579 + 2932.000 50.744 2.579 + 2932.500 68.328 2.577 + 2933.000 65.594 2.577 + 2933.500 61.235 2.576 + 2934.000 38.527 2.571 + 2934.500 31.022 2.561 + 2935.000 23.334 2.552 + 2935.500 25.883 2.550 + 2936.000 26.649 2.551 + 2936.500 26.551 2.562 + 2937.000 25.472 2.573 + 2937.500 23.041 2.587 + 2938.000 21.975 2.589 + 2938.500 22.074 2.585 + 2939.000 22.475 2.584 + 2939.500 24.371 2.590 + 2940.000 26.687 2.603 + 2940.500 30.593 2.609 + 2941.000 33.130 2.609 + 2941.500 33.626 2.602 + 2942.000 32.352 2.597 + 2942.500 30.235 2.593 + 2943.000 26.923 2.578 + 2943.500 26.329 2.574 + 2944.000 27.086 2.577 + 2944.500 31.359 2.588 + 2945.000 35.280 2.593 + 2945.500 35.650 2.584 + 2946.000 34.639 2.575 + 2946.500 31.075 2.564 + 2947.000 28.756 2.563 + 2947.500 28.654 2.564 + 2948.000 32.451 2.567 + 2948.500 39.402 2.574 + 2949.000 41.426 2.574 + 2949.500 41.460 2.574 + 2950.000 39.638 2.572 + 2950.500 36.160 2.568 + 2951.000 35.174 2.566 + 2951.500 36.051 2.566 + 2952.000 36.452 2.573 + 2952.500 34.119 2.581 + 2953.000 33.059 2.578 + 2953.500 31.752 2.571 + 2954.000 30.937 2.562 + 2954.500 29.491 2.557 + 2955.000 28.175 2.554 + 2955.500 27.279 2.552 + 2956.000 27.481 2.549 + 2956.500 28.308 2.553 + 2957.000 28.843 2.560 + 2957.500 28.191 2.581 + 2958.000 25.873 2.588 + 2958.500 24.888 2.592 + 2959.000 26.694 2.593 + 2959.500 34.071 2.595 + 2960.000 37.142 2.595 + 2960.500 40.121 2.586 + 2961.000 37.034 2.563 + 2961.500 34.957 2.553 + 2962.000 35.206 2.560 + 2962.500 43.974 2.581 + 2963.000 51.184 2.589 + 2963.500 53.584 2.594 + 2964.000 51.298 2.595 + 2964.500 43.439 2.582 + 2965.000 34.956 2.565 + 2965.500 28.313 2.553 + 2966.000 27.236 2.551 + 2966.500 27.953 2.554 + 2967.000 29.399 2.563 + 2967.500 31.234 2.585 + 2968.000 31.968 2.607 + 2968.500 33.382 2.626 + 2969.000 33.599 2.625 + 2969.500 34.360 2.617 + 2970.000 34.132 2.600 + 2970.500 32.796 2.587 + 2971.000 32.301 2.587 + 2971.500 32.221 2.592 + 2972.000 30.932 2.600 + 2972.500 28.414 2.600 + 2973.000 24.951 2.597 + 2973.500 22.471 2.589 + 2974.000 22.254 2.579 + 2974.500 21.859 2.572 + 2975.000 21.077 2.570 + 2975.500 20.245 2.573 + 2976.000 19.658 2.576 + 2976.500 19.452 2.582 + 2977.000 19.418 2.585 + 2977.500 17.961 2.592 + 2978.000 17.789 2.598 + 2978.500 17.703 2.598 + 2979.000 19.254 2.589 + 2979.500 19.374 2.575 + 2980.000 20.251 2.570 + 2980.500 19.899 2.571 + 2981.000 21.281 2.578 + 2981.500 22.353 2.589 + 2982.000 22.332 2.594 + 2982.500 23.075 2.596 + 2983.000 21.641 2.586 + 2983.500 21.490 2.581 + 2984.000 19.282 2.583 + 2984.500 19.245 2.596 + 2985.000 19.840 2.597 + 2985.500 20.915 2.600 + 2986.000 22.572 2.601 + 2986.500 29.174 2.617 + 2987.000 32.611 2.619 + 2987.500 33.681 2.613 + 2988.000 32.571 2.611 + 2988.500 29.906 2.618 + 2989.000 31.764 2.624 + 2989.500 33.824 2.621 + 2990.000 33.101 2.612 + 2990.500 30.604 2.602 + 2991.000 29.769 2.595 + 2991.500 29.872 2.589 + 2992.000 38.909 2.595 + 2992.500 52.770 2.608 + 2993.000 62.767 2.615 + 2993.500 67.324 2.620 + 2994.000 70.953 2.626 + 2994.500 74.048 2.630 + 2995.000 76.462 2.621 + 2995.500 72.779 2.608 + 2996.000 62.996 2.600 + 2996.500 49.050 2.596 + 2997.000 37.633 2.589 + 2997.500 32.831 2.573 + 2998.000 29.910 2.571 + 2998.500 28.418 2.578 + 2999.000 29.718 2.581 + 2999.500 31.556 2.585 + 3000.000 33.410 2.585 + 3000.500 36.833 2.580 + 3001.000 39.310 2.593 + 3001.500 48.073 2.613 + 3002.000 53.552 2.633 + 3002.500 68.211 2.662 + 3003.000 75.540 2.711 + 3003.500 80.686 2.703 + 3004.000 85.307 2.671 + 3004.500 81.267 2.557 + 3005.000 64.535 2.558 + 3005.500 62.677 2.577 + 3006.000 50.074 2.610 + 3006.500 45.335 2.610 + 3007.000 38.277 2.601 + 3007.500 35.956 2.589 + 3008.000 29.469 2.572 + 3008.500 31.760 2.564 + 3009.000 34.188 2.564 + 3009.500 39.664 2.582 + 3010.000 41.843 2.594 + 3010.500 43.983 2.604 + 3011.000 45.246 2.610 + 3011.500 43.828 2.616 + 3012.000 39.964 2.609 + 3012.500 31.840 2.592 + 3013.000 29.763 2.575 + 3013.500 29.445 2.574 + 3014.000 34.185 2.578 + 3014.500 38.561 2.603 + 3015.000 38.701 2.621 + 3015.500 35.871 2.618 + 3016.000 33.557 2.616 + 3016.500 26.423 2.606 + 3017.000 26.650 2.604 + 3017.500 25.094 2.608 + 3018.000 22.907 2.609 + 3018.500 23.810 2.601 + 3019.000 25.015 2.598 + 3019.500 25.663 2.599 + 3020.000 25.559 2.600 + 3020.500 25.501 2.601 + 3021.000 26.317 2.600 + 3021.500 28.208 2.601 + 3022.000 29.537 2.604 + 3022.500 30.881 2.610 + 3023.000 32.660 2.613 + 3023.500 34.253 2.613 + 3024.000 33.599 2.607 + 3024.500 31.188 2.597 + 3025.000 29.297 2.589 + 3025.500 27.033 2.586 + 3026.000 26.364 2.585 + 3026.500 26.206 2.587 + 3027.000 25.542 2.589 + 3027.500 25.038 2.591 + 3028.000 24.811 2.596 + 3028.500 26.793 2.597 + 3029.000 27.855 2.589 + 3029.500 27.330 2.583 + 3030.000 27.016 2.580 + 3030.500 26.145 2.585 + 3031.000 27.400 2.591 + 3031.500 30.889 2.590 + 3032.000 34.161 2.582 + 3032.500 42.464 2.567 + 3033.000 49.787 2.572 + 3033.500 55.949 2.593 + 3034.000 54.096 2.597 + 3034.500 49.275 2.592 + 3035.000 39.092 2.590 + 3035.500 36.028 2.591 + 3036.000 32.234 2.590 + 3036.500 31.651 2.585 + 3037.000 34.873 2.589 + 3037.500 39.511 2.598 + 3038.000 54.750 2.598 + 3038.500 57.726 2.596 + 3039.000 56.929 2.596 + 3039.500 57.848 2.597 + 3040.000 58.181 2.607 + 3040.500 60.092 2.618 + 3041.000 60.026 2.619 + 3041.500 54.011 2.612 + 3042.000 44.305 2.608 + 3042.500 47.980 2.592 + 3043.000 55.154 2.579 + 3043.500 76.096 2.584 + 3044.000 94.317 2.620 + 3044.500 132.534 2.668 + 3045.000 136.460 2.684 + 3045.500 139.361 2.690 + 3046.000 141.632 2.684 + 3046.500 121.139 2.661 + 3047.000 116.320 2.658 + 3047.500 88.168 2.639 + 3048.000 91.160 2.632 + 3048.500 49.110 2.619 + 3049.000 46.747 2.621 + 3049.500 46.128 2.626 + 3050.000 44.545 2.626 + 3050.500 42.058 2.616 + 3051.000 39.932 2.610 + 3051.500 41.014 2.609 + 3052.000 49.095 2.611 + 3052.500 57.270 2.616 + 3053.000 65.495 2.623 + 3053.500 73.561 2.630 + 3054.000 81.955 2.632 + 3054.500 90.726 2.628 + 3055.000 96.235 2.621 + 3055.500 106.885 2.620 + 3056.000 119.939 2.631 + 3056.500 133.854 2.653 + 3057.000 135.179 2.686 + 3057.500 133.834 2.681 + 3058.000 129.050 2.671 + 3058.500 121.314 2.655 + 3059.000 118.785 2.652 + 3059.500 117.076 2.652 + 3060.000 118.109 2.665 + 3060.500 114.100 2.674 + 3061.000 112.164 2.678 + 3061.500 112.316 2.675 + 3062.000 114.080 2.669 + 3062.500 113.675 2.668 + 3063.000 110.675 2.657 + 3063.500 105.295 2.643 + 3064.000 103.314 2.630 + 3064.500 100.582 2.636 + 3065.000 99.902 2.652 + 3065.500 96.957 2.674 + 3066.000 91.788 2.668 + 3066.500 78.736 2.648 + 3067.000 59.858 2.641 + 3067.500 52.472 2.632 + 3068.000 49.928 2.630 + 3068.500 50.979 2.628 + 3069.000 51.470 2.634 + 3069.500 53.039 2.638 + 3070.000 58.910 2.634 + 3070.500 71.728 2.620 + 3071.000 94.130 2.622 + 3071.500 96.954 2.630 + 3072.000 119.920 2.639 + 3072.500 122.535 2.645 + 3073.000 123.530 2.644 + 3073.500 122.031 2.650 + 3074.000 116.087 2.654 + 3074.500 111.325 2.657 + 3075.000 97.841 2.649 + 3075.500 71.678 2.646 + 3076.000 59.134 2.634 + 3076.500 45.138 2.619 + 3077.000 38.757 2.609 + 3077.500 33.702 2.605 + 3078.000 32.362 2.600 + 3078.500 35.591 2.598 + 3079.000 41.802 2.596 + 3079.500 51.826 2.596 + 3080.000 99.650 2.620 + 3080.500 98.055 2.636 + 3081.000 98.394 2.638 + 3081.500 84.797 2.633 + 3082.000 80.879 2.629 + 3082.500 60.205 2.629 + 3083.000 58.642 2.626 + 3083.500 48.438 2.620 + 3084.000 38.988 2.598 + 3084.500 33.824 2.595 + 3085.000 27.290 2.595 + 3085.500 27.386 2.599 + 3086.000 26.966 2.613 + 3086.500 27.137 2.615 + 3087.000 27.232 2.614 + 3087.500 27.031 2.609 + 3088.000 30.055 2.598 + 3088.500 32.567 2.595 + 3089.000 37.444 2.596 + 3089.500 38.321 2.597 + 3090.000 38.865 2.602 + 3090.500 36.431 2.604 + 3091.000 34.285 2.606 + 3091.500 32.265 2.600 + 3092.000 30.448 2.597 + 3092.500 29.580 2.591 + 3093.000 27.837 2.591 + 3093.500 25.021 2.591 + 3094.000 24.232 2.586 + 3094.500 23.901 2.581 + 3095.000 24.123 2.579 + 3095.500 23.498 2.581 + 3096.000 23.983 2.584 + 3096.500 23.171 2.593 + 3097.000 24.617 2.597 + 3097.500 24.874 2.603 + 3098.000 23.923 2.604 + 3098.500 21.748 2.609 + 3099.000 20.629 2.605 + 3099.500 19.304 2.602 + 3100.000 19.335 2.603 + 3100.500 19.213 2.609 + 3101.000 19.858 2.609 + 3101.500 20.661 2.602 + 3102.000 21.531 2.602 + 3102.500 22.126 2.604 + 3103.000 23.440 2.612 + 3103.500 25.155 2.616 + 3104.000 26.655 2.612 + 3104.500 25.279 2.610 + 3105.000 24.998 2.583 + 3105.500 24.849 2.570 + 3106.000 24.425 2.556 + 3106.500 25.842 2.569 + 3107.000 25.521 2.574 + 3107.500 27.169 2.591 + 3108.000 27.189 2.595 + 3108.500 26.199 2.599 + 3109.000 24.309 2.597 + 3109.500 21.520 2.578 + 3110.000 20.790 2.568 + 3110.500 21.325 2.560 + 3111.000 23.221 2.571 + 3111.500 27.341 2.587 + 3112.000 30.023 2.584 + 3112.500 33.089 2.577 + 3113.000 31.775 2.563 + 3113.500 30.901 2.563 + 3114.000 30.309 2.577 + 3114.500 30.106 2.596 + 3115.000 29.955 2.602 + 3115.500 29.411 2.600 + 3116.000 29.626 2.588 + 3116.500 29.673 2.577 + 3117.000 32.009 2.578 + 3117.500 33.700 2.581 + 3118.000 36.489 2.607 + 3118.500 36.696 2.609 + 3119.000 37.843 2.596 + 3119.500 39.548 2.581 + 3120.000 40.036 2.586 + 3120.500 39.876 2.594 + 3121.000 38.136 2.600 + 3121.500 32.739 2.601 + 3122.000 28.302 2.601 + 3122.500 24.404 2.598 + 3123.000 24.956 2.597 + 3123.500 29.421 2.601 + 3124.000 34.452 2.605 + 3124.500 44.806 2.609 + 3125.000 58.598 2.620 + 3125.500 76.802 2.636 + 3126.000 99.664 2.654 + 3126.500 107.702 2.667 + 3127.000 102.163 2.660 + 3127.500 88.332 2.646 + 3128.000 64.601 2.639 + 3128.500 55.577 2.639 + 3129.000 48.660 2.623 + 3129.500 43.503 2.611 + 3130.000 42.840 2.581 + 3130.500 47.714 2.607 + 3131.000 53.094 2.625 + 3131.500 58.787 2.619 + 3132.000 67.198 2.610 + 3132.500 76.339 2.604 + 3133.000 84.674 2.617 + 3133.500 96.557 2.648 + 3134.000 102.174 2.690 + 3134.500 117.301 2.675 + 3135.000 109.252 2.608 + 3135.500 93.400 2.543 + 3136.000 81.203 2.526 + 3136.500 72.091 2.580 + 3137.000 75.767 2.609 + 3137.500 88.545 2.629 + 3138.000 93.262 2.673 + 3138.500 93.966 2.676 + 3139.000 90.061 2.638 + 3139.500 89.031 2.622 + 3140.000 94.274 2.656 + 3140.500 110.683 2.711 + 3141.000 129.317 2.643 + 3141.500 136.375 2.601 + 3142.000 139.959 2.540 + 3142.500 140.557 2.560 + 3143.000 139.643 2.644 + 3143.500 135.578 2.636 + 3144.000 132.258 2.685 + 3144.500 130.429 2.739 + 3145.000 130.373 2.757 + 3145.500 131.965 2.750 + 3146.000 131.274 2.726 + 3146.500 126.507 2.651 + 3147.000 116.437 2.656 + 3147.500 115.166 2.670 + 3148.000 113.602 2.687 + 3148.500 111.811 2.679 + 3149.000 109.986 2.645 + 3149.500 105.820 2.635 + 3150.000 101.518 2.632 + 3150.500 94.208 2.649 + 3151.000 90.116 2.668 + 3151.500 91.053 2.664 + 3152.000 91.703 2.654 + 3152.500 89.213 2.652 + 3153.000 85.100 2.648 + 3153.500 81.165 2.589 + 3154.000 79.891 2.564 + 3154.500 78.504 2.575 + 3155.000 75.088 2.606 + 3155.500 72.502 2.627 + 3156.000 74.385 2.632 + 3156.500 86.331 2.631 + 3157.000 111.214 2.630 + 3157.500 120.901 2.634 + 3158.000 127.522 2.645 + 3158.500 131.710 2.663 + 3159.000 130.119 2.679 + 3159.500 117.787 2.683 + 3160.000 109.269 2.682 + 3160.500 92.997 2.676 + 3161.000 88.230 2.672 + 3161.500 85.862 2.660 + 3162.000 84.002 2.644 + 3162.500 81.313 2.625 + 3163.000 81.934 2.627 + 3163.500 90.099 2.631 + 3164.000 102.738 2.632 + 3164.500 106.924 2.632 + 3165.000 103.519 2.631 + 3165.500 99.248 2.621 + 3166.000 100.650 2.554 + 3166.500 119.494 2.281 + 3167.000 126.338 2.207 + 3167.500 131.961 2.219 + 3168.000 130.789 2.404 + 3168.500 131.739 2.650 + 3169.000 134.832 2.642 + 3169.500 137.234 2.642 + 3170.000 138.938 2.640 + 3170.500 139.220 2.609 + 3171.000 137.258 2.541 + 3171.500 131.875 2.467 + 3172.000 126.623 2.423 + 3172.500 119.566 2.553 + 3173.000 113.588 2.625 + 3173.500 103.980 2.660 + 3174.000 97.061 2.641 + 3174.500 86.239 2.628 + 3175.000 86.005 2.648 + 3175.500 90.550 2.669 + 3176.000 96.120 2.700 + 3176.500 100.061 2.695 + 3177.000 105.413 2.649 + 3177.500 107.885 2.565 + 3178.000 113.833 2.578 + 3178.500 119.597 2.663 + 3179.000 121.001 2.668 + 3179.500 120.491 2.667 + 3180.000 118.628 2.669 + 3180.500 117.779 2.676 + 3181.000 118.810 2.682 + 3181.500 118.528 2.686 + 3182.000 109.751 2.682 + 3182.500 99.982 2.675 + 3183.000 98.013 2.665 + 3183.500 98.511 2.672 + 3184.000 101.642 2.642 + 3184.500 116.894 2.589 + 3185.000 120.009 2.593 + 3185.500 120.937 2.603 + 3186.000 111.949 2.625 + 3186.500 100.001 2.651 + 3187.000 98.211 2.661 + 3187.500 98.052 2.685 + 3188.000 107.088 2.653 + 3188.500 113.079 2.639 + 3189.000 121.901 2.670 + 3189.500 128.413 2.756 + 3190.000 132.923 2.752 + 3190.500 137.082 2.562 + 3191.000 138.453 2.433 + 3191.500 136.442 2.201 + 3192.000 123.884 2.219 + 3192.500 110.066 2.464 + 3193.000 108.002 2.521 + 3193.500 108.410 2.664 + 3194.000 110.560 2.560 + 3194.500 124.057 2.389 + 3195.000 136.711 2.343 + 3195.500 140.596 2.326 + 3196.000 141.436 2.391 + 3196.500 141.446 2.481 + 3197.000 139.120 2.391 + 3197.500 135.466 2.325 + 3198.000 132.982 2.242 + 3198.500 121.638 2.068 + 3199.000 112.482 2.158 + 3199.500 100.449 2.477 + 3200.000 102.886 2.552 + 3200.500 109.243 2.383 + 3201.000 117.836 2.168 + 3201.500 121.937 2.230 + 3202.000 125.005 2.636 + 3202.500 126.502 2.734 + 3203.000 128.675 2.689 + 3203.500 132.003 2.607 + 3204.000 136.772 2.619 + 3204.500 140.419 2.697 + 3205.000 141.058 2.711 + 3205.500 141.661 2.705 + 3206.000 140.684 2.603 + 3206.500 136.967 2.356 + 3207.000 127.844 2.279 + 3207.500 124.457 2.216 + 3208.000 114.364 2.224 + 3208.500 111.270 2.444 + 3209.000 105.872 2.560 + 3209.500 97.984 2.569 + 3210.000 88.554 2.603 + 3210.500 78.286 2.630 + 3211.000 63.993 2.623 + 3211.500 76.012 2.628 + 3212.000 102.011 2.446 + 3212.500 115.896 2.345 + 3213.000 141.833 2.304 + 3213.500 142.400 2.262 + 3214.000 134.751 2.212 + 3214.500 106.762 2.310 + 3215.000 96.284 2.460 + 3215.500 89.674 2.591 + 3216.000 89.282 2.672 + 3216.500 97.372 2.619 + 3217.000 103.772 2.562 + 3217.500 113.489 2.370 + 3218.000 121.899 2.415 + 3218.500 124.409 2.574 + 3219.000 125.247 2.635 + 3219.500 127.198 2.613 + 3220.000 127.157 2.565 + 3220.500 123.315 2.477 + 3221.000 118.837 2.423 + 3221.500 111.129 2.380 + 3222.000 107.385 2.501 + 3222.500 109.243 2.470 + 3223.000 112.454 2.413 + 3223.500 122.026 2.358 + 3224.000 125.973 2.333 + 3224.500 130.080 2.416 + 3225.000 129.826 2.441 + 3225.500 128.352 2.511 + 3226.000 127.611 2.647 + 3226.500 127.225 2.626 + 3227.000 126.425 2.471 + 3227.500 124.276 2.413 + 3228.000 119.783 2.445 + 3228.500 119.282 2.400 + 3229.000 119.763 2.305 + 3229.500 121.655 2.323 + 3230.000 123.428 2.365 + 3230.500 121.727 2.600 + 3231.000 114.278 2.589 + 3231.500 102.833 2.600 + 3232.000 97.366 2.608 + 3232.500 94.757 2.623 + 3233.000 95.285 2.645 + 3233.500 96.824 2.671 + 3234.000 98.928 2.710 + 3234.500 107.842 2.693 + 3235.000 124.707 2.635 + 3235.500 127.812 2.548 + 3236.000 133.944 2.467 + 3236.500 133.693 2.333 + 3237.000 126.721 2.354 + 3237.500 120.720 2.429 + 3238.000 117.539 2.549 + 3238.500 110.759 2.676 + 3239.000 110.668 2.669 + 3239.500 114.744 2.685 + 3240.000 123.099 2.689 + 3240.500 133.431 2.712 + 3241.000 139.178 2.730 + 3241.500 143.533 2.813 + 3242.000 144.707 2.817 + 3242.500 140.521 2.756 + 3243.000 137.185 2.655 + 3243.500 135.736 2.597 + 3244.000 137.536 2.568 + 3244.500 138.163 2.541 + 3245.000 135.584 2.545 + 3245.500 133.423 2.579 + 3246.000 130.496 2.588 + 3246.500 130.972 2.566 + 3247.000 131.707 2.511 + 3247.500 130.448 2.460 + 3248.000 128.608 2.428 + 3248.500 121.744 2.201 + 3249.000 120.030 2.301 + 3249.500 119.933 2.346 + 3250.000 121.326 2.567 + 3250.500 126.262 2.557 + 3251.000 131.683 2.483 + 3251.500 133.177 2.474 + 3252.000 134.849 2.445 + 3252.500 137.043 2.417 + 3253.000 132.821 2.340 + 3253.500 125.426 2.351 + 3254.000 112.524 2.461 + 3254.500 98.568 2.631 + 3255.000 93.838 2.633 + 3255.500 90.871 2.647 + 3256.000 93.232 2.646 + 3256.500 100.937 2.642 + 3257.000 105.522 2.644 + 3257.500 106.160 2.656 + 3258.000 102.677 2.663 + 3258.500 100.132 2.687 + 3259.000 101.531 2.716 + 3259.500 101.924 2.772 + 3260.000 119.478 2.789 + 3260.500 125.230 2.507 + 3261.000 123.656 2.416 + 3261.500 120.259 2.463 + 3262.000 113.927 2.539 + 3262.500 100.832 2.613 + 3263.000 91.789 2.631 + 3263.500 86.288 2.656 + 3264.000 84.115 2.669 + 3264.500 89.368 2.673 + 3265.000 94.604 2.668 + 3265.500 101.447 2.653 + 3266.000 96.993 2.648 + 3266.500 87.053 2.634 + 3267.000 75.558 2.655 + 3267.500 69.938 2.623 + 3268.000 83.370 2.568 + 3268.500 116.486 2.398 + 3269.000 127.085 2.161 + 3269.500 134.290 2.103 + 3270.000 137.409 2.197 + 3270.500 138.325 2.452 + 3271.000 141.148 2.517 + 3271.500 144.104 2.466 + 3272.000 143.597 2.448 + 3272.500 143.802 2.491 + 3273.000 143.915 2.495 + 3273.500 144.438 2.499 + 3274.000 144.968 2.499 + 3274.500 141.190 2.485 + 3275.000 140.497 2.409 + 3275.500 133.469 2.338 + 3276.000 124.950 2.254 + 3276.500 116.383 2.150 + 3277.000 106.311 2.383 + 3277.500 100.911 2.644 + 3278.000 105.471 2.746 + 3278.500 118.956 2.628 + 3279.000 132.252 2.450 + 3279.500 141.587 2.407 + 3280.000 144.878 2.448 + 3280.500 144.250 2.536 + 3281.000 143.002 2.487 + 3281.500 140.601 2.435 + 3282.000 139.355 2.387 + 3282.500 136.257 2.306 + 3283.000 132.607 2.438 + 3283.500 131.063 2.472 + 3284.000 131.670 2.508 + 3284.500 133.841 2.498 + 3285.000 129.911 2.382 + 3285.500 123.514 2.293 + 3286.000 117.513 2.305 + 3286.500 96.389 2.533 + 3287.000 71.979 2.609 + 3287.500 67.366 2.642 + 3288.000 63.573 2.652 + 3288.500 67.453 2.706 + 3289.000 77.126 2.697 + 3289.500 89.112 2.636 + 3290.000 109.993 2.568 + 3290.500 129.623 2.409 + 3291.000 138.710 2.369 + 3291.500 140.286 2.358 + 3292.000 139.964 2.384 + 3292.500 138.564 2.428 + 3293.000 136.953 2.476 + 3293.500 136.132 2.497 + 3294.000 133.724 2.535 + 3294.500 131.237 2.610 + 3295.000 127.207 2.605 + 3295.500 125.195 2.606 + 3296.000 125.427 2.604 + 3296.500 125.457 2.596 + 3297.000 127.168 2.616 + 3297.500 128.680 2.609 + 3298.000 130.405 2.614 + 3298.500 130.426 2.477 + 3299.000 129.558 2.446 + 3299.500 130.030 2.384 + 3300.000 129.850 2.377 + 3300.500 132.628 2.405 + 3301.000 135.389 2.509 + 3301.500 138.120 2.644 + 3302.000 141.860 2.605 + 3302.500 144.798 2.411 + 3303.000 148.454 2.338 + 3303.500 148.474 2.301 + 3304.000 146.686 2.240 + 3304.500 141.834 2.226 + 3305.000 138.424 2.234 + 3305.500 133.440 2.317 + 3306.000 127.929 2.393 + 3306.500 120.201 2.650 + 3307.000 116.472 2.740 + 3307.500 114.615 2.789 + 3308.000 121.583 2.791 + 3308.500 127.467 2.679 + 3309.000 133.255 2.558 + 3309.500 134.239 2.368 + 3310.000 133.977 2.223 + 3310.500 132.554 2.228 + 3311.000 131.755 2.360 + 3311.500 132.760 2.519 + 3312.000 133.522 2.513 + 3312.500 133.324 2.474 + 3313.000 132.265 2.536 + 3313.500 130.044 2.487 + 3314.000 128.561 2.472 + 3314.500 127.106 2.409 + 3315.000 128.199 2.526 + 3315.500 129.476 2.701 + 3316.000 131.368 2.631 + 3316.500 133.486 2.558 + 3317.000 135.436 2.516 + 3317.500 137.555 2.450 + 3318.000 137.573 2.562 + 3318.500 135.157 2.652 + 3319.000 132.623 2.693 + 3319.500 129.792 2.613 + 3320.000 127.704 2.601 + 3320.500 129.288 2.552 + 3321.000 132.555 2.564 + 3321.500 136.855 2.537 + 3322.000 138.233 2.474 + 3322.500 140.428 2.458 + 3323.000 140.468 2.506 + 3323.500 140.721 2.501 + 3324.000 139.549 2.480 + 3324.500 136.304 2.470 + 3325.000 134.265 2.432 + 3325.500 132.707 2.461 + 3326.000 131.351 2.521 + 3326.500 129.715 2.511 + 3327.000 123.180 2.395 + 3327.500 118.330 2.385 + 3328.000 109.561 2.517 + 3328.500 111.869 2.758 + 3329.000 118.075 2.601 + 3329.500 123.805 2.462 + 3330.000 123.442 2.274 + 3330.500 119.604 2.393 + 3331.000 116.316 2.546 + 3331.500 111.779 2.642 + 3332.000 109.506 2.666 + 3332.500 110.940 2.746 + 3333.000 113.567 2.789 + 3333.500 119.631 2.781 + 3334.000 126.744 2.750 + 3334.500 127.166 2.441 + 3335.000 125.656 2.391 + 3335.500 122.039 2.419 + 3336.000 117.985 2.434 + 3336.500 114.784 2.447 + 3337.000 114.400 2.471 + 3337.500 110.809 2.503 + 3338.000 105.824 2.558 + 3338.500 98.247 2.569 + 3339.000 95.431 2.582 + 3339.500 94.605 2.457 + 3340.000 94.724 2.328 + 3340.500 90.615 2.347 + 3341.000 87.143 2.382 + 3341.500 86.057 2.466 + 3342.000 86.758 2.482 + 3342.500 86.996 2.505 + 3343.000 85.851 2.564 + 3343.500 89.710 2.625 + 3344.000 94.351 2.696 + 3344.500 100.699 2.732 + 3345.000 109.087 2.778 + 3345.500 111.056 2.705 + 3346.000 122.954 2.545 + 3346.500 129.061 2.329 + 3347.000 133.761 2.371 + 3347.500 139.992 2.457 + 3348.000 142.653 2.552 + 3348.500 142.296 2.489 + 3349.000 138.439 2.399 + 3349.500 134.353 2.309 + 3350.000 128.575 2.209 + 3350.500 120.163 2.274 + 3351.000 114.810 2.373 + 3351.500 110.503 2.470 + 3352.000 111.310 2.707 + 3352.500 112.340 2.797 + 3353.000 117.795 2.746 + 3353.500 122.988 2.723 + 3354.000 128.524 2.689 + 3354.500 131.779 2.575 + 3355.000 131.188 2.508 + 3355.500 129.076 2.449 + 3356.000 128.115 2.389 + 3356.500 123.324 2.314 + 3357.000 121.091 2.320 + 3357.500 117.732 2.312 + 3358.000 115.022 2.405 + 3358.500 109.371 2.490 + 3359.000 109.788 2.613 + 3359.500 117.018 2.436 + 3360.000 120.985 2.209 + 3360.500 124.505 2.089 + 3361.000 124.359 2.161 + 3361.500 120.948 2.225 + 3362.000 116.935 2.193 + 3362.500 117.008 2.352 + 3363.000 121.107 2.503 + 3363.500 121.739 2.634 + 3364.000 120.563 2.626 + 3364.500 117.271 2.626 + 3365.000 113.295 2.644 + 3365.500 113.864 2.617 + 3366.000 114.579 2.577 + 3366.500 121.496 2.459 + 3367.000 123.680 2.348 + 3367.500 119.818 2.410 + 3368.000 111.889 2.499 + 3368.500 96.419 2.597 + 3369.000 98.094 2.636 + 3369.500 102.271 2.675 + 3370.000 106.305 2.680 + 3370.500 110.462 2.675 + 3371.000 112.778 2.655 + 3371.500 113.112 2.650 + 3372.000 109.113 2.660 + 3372.500 101.903 2.668 + 3373.000 98.631 2.682 + 3373.500 97.513 2.669 + 3374.000 91.928 2.646 + 3374.500 83.542 2.653 + 3375.000 75.048 2.663 + 3375.500 67.547 2.673 + 3376.000 64.661 2.667 + 3376.500 66.995 2.648 + 3377.000 74.517 2.633 + 3377.500 74.379 2.627 + 3378.000 70.959 2.626 + 3378.500 67.382 2.633 + 3379.000 69.208 2.667 + 3379.500 77.219 2.717 + 3380.000 98.364 2.741 + 3380.500 119.641 2.609 + 3381.000 122.590 2.386 + 3381.500 120.555 2.403 + 3382.000 117.134 2.374 + 3382.500 108.938 2.534 + 3383.000 99.798 2.554 + 3383.500 90.899 2.619 + 3384.000 84.416 2.640 + 3384.500 80.294 2.651 + 3385.000 76.421 2.651 + 3385.500 74.371 2.635 + 3386.000 73.215 2.627 + 3386.500 68.706 2.626 + 3387.000 67.845 2.628 + 3387.500 70.091 2.640 + 3388.000 72.622 2.653 + 3388.500 83.188 2.678 + 3389.000 85.899 2.664 + 3389.500 86.490 2.607 + 3390.000 88.459 2.564 + 3390.500 102.275 2.447 + 3391.000 118.134 2.164 + 3391.500 135.414 2.174 + 3392.000 138.320 2.282 + 3392.500 137.777 2.333 + 3393.000 135.093 2.376 + 3393.500 133.431 2.453 + 3394.000 130.978 2.531 + 3394.500 130.279 2.596 + 3395.000 129.964 2.606 + 3395.500 129.467 2.626 + 3396.000 128.812 2.637 + 3396.500 126.693 2.651 + 3397.000 125.653 2.664 + 3397.500 124.646 2.681 + 3398.000 124.994 2.692 + 3398.500 124.686 2.720 + 3399.000 122.833 2.714 + 3399.500 119.661 2.729 + 3400.000 103.058 2.607 + 3400.500 97.837 2.649 + 3401.000 90.614 2.656 + 3401.500 84.535 2.664 + 3402.000 83.126 2.672 + 3402.500 88.408 2.675 + 3403.000 96.504 2.681 + 3403.500 97.901 2.687 + 3404.000 103.102 2.686 + 3404.500 113.305 2.670 + 3405.000 118.885 2.656 + 3405.500 124.551 2.657 + 3406.000 124.874 2.660 + 3406.500 124.593 2.659 + 3407.000 121.587 2.655 + 3407.500 114.556 2.648 + 3408.000 102.460 2.646 + 3408.500 99.345 2.646 + 3409.000 101.231 2.644 + 3409.500 111.903 2.638 + 3410.000 120.755 2.637 + 3410.500 119.567 2.654 + 3411.000 117.241 2.666 + 3411.500 104.571 2.673 + 3412.000 99.119 2.679 + 3412.500 84.287 2.678 + 3413.000 84.266 2.645 + 3413.500 85.086 2.528 + 3414.000 86.246 2.468 + 3414.500 86.566 2.485 + 3415.000 80.710 2.582 + 3415.500 74.632 2.608 + 3416.000 77.191 2.646 + 3416.500 81.167 2.679 + 3417.000 94.803 2.638 + 3417.500 110.371 2.623 + 3418.000 117.474 2.555 + 3418.500 122.273 2.389 + 3419.000 122.339 2.335 + 3419.500 121.010 2.266 + 3420.000 119.631 2.365 + 3420.500 118.185 2.507 + 3421.000 116.219 2.560 + 3421.500 116.119 2.676 + 3422.000 116.300 2.685 + 3422.500 118.013 2.595 + 3423.000 123.491 2.477 + 3423.500 128.273 2.301 + 3424.000 128.581 2.321 + 3424.500 127.032 2.358 + 3425.000 124.923 2.541 + 3425.500 118.348 2.643 + 3426.000 108.320 2.660 + 3426.500 94.714 2.665 + 3427.000 88.413 2.667 + 3427.500 84.261 2.668 + 3428.000 88.991 2.666 + 3428.500 91.874 2.660 + 3429.000 92.766 2.658 + 3429.500 91.748 2.659 + 3430.000 89.096 2.656 + 3430.500 85.053 2.651 + 3431.000 83.055 2.650 + 3431.500 81.564 2.653 + 3432.000 81.800 2.663 + 3432.500 83.068 2.654 + 3433.000 83.025 2.646 + 3433.500 80.953 2.657 + 3434.000 79.633 2.653 + 3434.500 83.157 2.619 + 3435.000 96.877 2.539 + 3435.500 109.850 2.470 + 3436.000 119.784 2.522 + 3436.500 124.392 2.581 + 3437.000 133.663 2.639 + 3437.500 138.911 2.667 + 3438.000 141.500 2.673 + 3438.500 141.775 2.679 + 3439.000 135.444 2.678 + 3439.500 123.512 2.665 + 3440.000 104.305 2.649 + 3440.500 98.627 2.646 + 3441.000 106.327 2.651 + 3441.500 110.936 2.660 + 3442.000 118.708 2.662 + 3442.500 117.179 2.662 + 3443.000 108.780 2.663 + 3443.500 98.822 2.665 + 3444.000 93.750 2.661 + 3444.500 81.556 2.656 + 3445.000 74.078 2.658 + 3445.500 70.289 2.662 + 3446.000 66.153 2.664 + 3446.500 73.625 2.661 + 3447.000 78.858 2.656 + 3447.500 80.823 2.659 + 3448.000 81.255 2.677 + 3448.500 83.971 2.684 + 3449.000 93.038 2.664 + 3449.500 101.813 2.538 + 3450.000 106.010 2.426 + 3450.500 120.545 2.502 + 3451.000 118.899 2.580 + 3451.500 111.413 2.614 + 3452.000 105.097 2.627 + 3452.500 92.822 2.629 + 3453.000 93.742 2.618 + 3453.500 98.026 2.560 + 3454.000 104.189 2.362 + 3454.500 105.456 2.392 + 3455.000 97.244 2.400 + 3455.500 84.695 2.495 + 3456.000 74.751 2.599 + 3456.500 72.864 2.618 + 3457.000 67.184 2.626 + 3457.500 65.944 2.669 + 3458.000 70.545 2.700 + 3458.500 81.020 2.772 + 3459.000 94.415 2.728 + 3459.500 104.419 2.660 + 3460.000 110.519 2.620 + 3460.500 110.728 2.477 + 3461.000 107.963 2.305 + 3461.500 104.806 2.295 + 3462.000 94.835 2.418 + 3462.500 93.451 2.580 + 3463.000 93.204 2.610 + 3463.500 93.290 2.666 + 3464.000 89.365 2.675 + 3464.500 84.800 2.699 + 3465.000 84.827 2.709 + 3465.500 93.579 2.674 + 3466.000 103.240 2.579 + 3466.500 117.636 2.456 + 3467.000 121.475 2.381 + 3467.500 125.568 2.372 + 3468.000 126.527 2.493 + 3468.500 122.756 2.652 + 3469.000 115.727 2.640 + 3469.500 113.677 2.649 + 3470.000 111.795 2.496 + 3470.500 109.728 2.401 + 3471.000 108.610 2.362 + 3471.500 102.194 2.462 + 3472.000 97.249 2.297 + 3472.500 98.779 2.244 + 3473.000 112.873 2.185 + 3473.500 111.561 2.314 + 3474.000 106.731 2.542 + 3474.500 95.463 2.621 + 3475.000 95.219 2.632 + 3475.500 94.931 2.650 + 3476.000 94.698 2.683 + 3476.500 94.444 2.799 + 3477.000 94.519 2.789 + 3477.500 100.928 2.630 + 3478.000 106.479 2.474 + 3478.500 110.795 2.479 + 3479.000 110.691 2.528 + 3479.500 110.515 2.469 + 3480.000 110.378 2.223 + 3480.500 106.499 2.279 + 3481.000 102.751 2.367 + 3481.500 99.017 2.521 + 3482.000 99.784 2.548 + 3482.500 110.432 2.670 + 3483.000 114.157 2.656 + 3483.500 111.699 2.651 + 3484.000 103.417 2.658 + 3484.500 97.159 2.674 + 3485.000 90.645 2.673 + 3485.500 84.162 2.663 + 3486.000 78.929 2.664 + 3486.500 77.422 2.663 + 3487.000 66.075 2.656 + 3487.500 66.739 2.640 + 3488.000 65.864 2.600 + 3488.500 84.009 2.639 + 3489.000 92.522 2.653 + 3489.500 106.257 2.645 + 3490.000 110.404 2.614 + 3490.500 123.183 2.517 + 3491.000 125.854 2.527 + 3491.500 123.165 2.546 + 3492.000 119.776 2.562 + 3492.500 110.526 2.601 + 3493.000 99.670 2.631 + 3493.500 88.591 2.638 + 3494.000 77.695 2.628 + 3494.500 66.676 2.623 + 3495.000 56.146 2.625 + 3495.500 46.403 2.627 + 3496.000 44.347 2.628 + 3496.500 44.404 2.630 + 3497.000 44.436 2.632 + 3497.500 44.485 2.633 + 3498.000 44.796 2.637 + 3498.500 47.772 2.638 + 3499.000 48.747 2.636 + 3499.500 50.191 2.630 + 3500.000 48.774 2.623 + 3500.500 43.185 2.617 + 3501.000 42.904 2.620 + 3501.500 44.742 2.599 + 3502.000 50.434 2.582 + 3502.500 54.069 2.493 + 3503.000 53.152 2.472 + 3503.500 51.134 2.445 + 3504.000 48.458 2.451 + 3504.500 47.387 2.486 + 3505.000 48.164 2.537 + 3505.500 54.370 2.593 + 3506.000 61.841 2.631 + 3506.500 80.732 2.660 + 3507.000 97.980 2.654 + 3507.500 114.046 2.639 + 3508.000 115.478 2.597 + 3508.500 120.801 2.493 + 3509.000 123.937 2.428 + 3509.500 126.044 2.477 + 3510.000 127.740 2.595 + 3510.500 129.646 2.587 + 3511.000 131.438 2.568 + 3511.500 136.290 2.550 + 3512.000 139.386 2.542 + 3512.500 142.132 2.638 + 3513.000 142.949 2.630 + 3513.500 140.844 2.620 + 3514.000 135.113 2.593 + 3514.500 129.592 2.559 + 3515.000 121.822 2.552 + 3515.500 111.729 2.516 + 3516.000 101.790 2.520 + 3516.500 77.720 2.567 + 3517.000 64.310 2.583 + 3517.500 59.065 2.630 + 3518.000 53.475 2.664 + 3518.500 54.060 2.672 + 3519.000 53.872 2.670 + 3519.500 53.889 2.668 + 3520.000 55.910 2.660 + 3520.500 67.390 2.644 + 3521.000 76.527 2.636 + 3521.500 93.353 2.648 + 3522.000 102.269 2.648 + 3522.500 102.819 2.631 + 3523.000 100.530 2.584 + 3523.500 90.534 2.569 + 3524.000 87.839 2.695 + 3524.500 88.934 2.674 + 3525.000 98.906 2.619 + 3525.500 109.391 2.455 + 3526.000 107.192 2.468 + 3526.500 99.820 2.525 + 3527.000 95.210 2.617 + 3527.500 92.529 2.645 + 3528.000 83.775 2.659 + 3528.500 79.593 2.643 + 3529.000 73.656 2.627 + 3529.500 63.755 2.603 + 3530.000 54.459 2.607 + 3530.500 43.743 2.615 + 3531.000 44.122 2.616 + 3531.500 48.690 2.615 + 3532.000 53.288 2.620 + 3532.500 59.166 2.629 + 3533.000 60.150 2.621 + 3533.500 63.231 2.617 + 3534.000 65.831 2.633 + 3534.500 66.579 2.642 + 3535.000 62.358 2.639 + 3535.500 55.117 2.635 + 3536.000 52.147 2.630 + 3536.500 59.168 2.643 + 3537.000 64.902 2.720 + 3537.500 93.109 2.692 + 3538.000 105.153 2.606 + 3538.500 112.792 2.380 + 3539.000 107.662 2.301 + 3539.500 96.807 2.352 + 3540.000 90.887 2.417 + 3540.500 71.691 2.538 + 3541.000 71.728 2.565 + 3541.500 69.685 2.562 + 3542.000 64.846 2.567 + 3542.500 61.916 2.606 + 3543.000 58.749 2.613 + 3543.500 56.703 2.617 + 3544.000 58.272 2.618 + 3544.500 60.571 2.622 + 3545.000 61.796 2.634 + 3545.500 60.327 2.642 + 3546.000 59.422 2.646 + 3546.500 59.721 2.649 + 3547.000 60.418 2.661 + 3547.500 71.239 2.655 + 3548.000 83.887 2.607 + 3548.500 112.330 2.484 + 3549.000 116.077 2.477 + 3549.500 122.025 2.479 + 3550.000 126.346 2.544 + 3550.500 129.094 2.535 + 3551.000 129.396 2.476 + 3551.500 125.871 2.491 + 3552.000 112.510 2.542 + 3552.500 105.864 2.621 + 3553.000 99.058 2.654 + 3553.500 94.088 2.666 + 3554.000 78.641 2.670 + 3554.500 75.073 2.671 + 3555.000 75.216 2.671 + 3555.500 77.674 2.676 + 3556.000 85.283 2.689 + 3556.500 90.250 2.678 + 3557.000 87.801 2.632 + 3557.500 87.845 2.602 + 3558.000 88.387 2.643 + 3558.500 94.691 2.692 + 3559.000 103.867 2.548 + 3559.500 103.972 2.514 + 3560.000 103.028 2.244 + 3560.500 88.622 2.264 + 3561.000 79.608 2.505 + 3561.500 75.996 2.540 + 3562.000 75.187 2.620 + 3562.500 77.968 2.650 + 3563.000 79.611 2.668 + 3563.500 84.439 2.712 + 3564.000 90.696 2.744 + 3564.500 102.767 2.638 + 3565.000 102.212 2.566 + 3565.500 96.675 2.521 + 3566.000 90.752 2.601 + 3566.500 72.337 2.636 + 3567.000 63.527 2.636 + 3567.500 54.944 2.630 + 3568.000 53.275 2.624 + 3568.500 52.128 2.619 + 3569.000 52.453 2.614 + 3569.500 53.323 2.607 + 3570.000 52.477 2.611 + 3570.500 53.790 2.629 + 3571.000 54.790 2.634 + 3571.500 57.065 2.640 + 3572.000 58.775 2.639 + 3572.500 59.474 2.638 + 3573.000 59.014 2.642 + 3573.500 53.138 2.644 + 3574.000 49.385 2.644 + 3574.500 47.103 2.635 + 3575.000 46.446 2.626 + 3575.500 46.497 2.616 + 3576.000 50.382 2.609 + 3576.500 60.120 2.609 + 3577.000 79.182 2.617 + 3577.500 83.564 2.622 + 3578.000 79.634 2.637 + 3578.500 70.165 2.645 + 3579.000 62.895 2.658 + 3579.500 61.031 2.653 + 3580.000 61.813 2.650 + 3580.500 69.093 2.666 + 3581.000 84.787 2.699 + 3581.500 94.285 2.701 + 3582.000 101.998 2.662 + 3582.500 101.923 2.542 + 3583.000 98.473 2.533 + 3583.500 94.749 2.546 + 3584.000 84.989 2.576 + 3584.500 75.709 2.600 + 3585.000 65.159 2.630 + 3585.500 60.583 2.629 + 3586.000 54.389 2.626 + 3586.500 48.654 2.618 + 3587.000 46.670 2.612 + 3587.500 46.984 2.619 + 3588.000 49.258 2.625 + 3588.500 51.569 2.634 + 3589.000 54.090 2.634 + 3589.500 58.753 2.637 + 3590.000 58.653 2.638 + 3590.500 77.995 2.649 + 3591.000 92.218 2.659 + 3591.500 95.081 2.676 + 3592.000 94.705 2.676 + 3592.500 88.891 2.670 + 3593.000 85.967 2.664 + 3593.500 82.210 2.661 + 3594.000 80.858 2.658 + 3594.500 81.399 2.655 + 3595.000 83.398 2.658 + 3595.500 84.431 2.663 + 3596.000 84.436 2.664 + 3596.500 81.435 2.667 + 3597.000 77.183 2.671 + 3597.500 74.708 2.677 + 3598.000 73.816 2.677 + 3598.500 76.848 2.668 + 3599.000 81.160 2.668 + 3599.500 86.250 2.668 + 3600.000 94.519 2.680 + 3600.500 108.454 2.691 + 3601.000 118.534 2.700 + 3601.500 120.035 2.708 + 3602.000 114.640 2.676 + 3602.500 111.994 2.603 + 3603.000 95.940 2.552 + 3603.500 84.646 2.568 + 3604.000 71.525 2.637 + 3604.500 66.321 2.664 + 3605.000 67.522 2.666 + 3605.500 67.893 2.667 + 3606.000 71.574 2.666 + 3606.500 76.521 2.660 + 3607.000 80.480 2.650 + 3607.500 84.310 2.647 + 3608.000 87.037 2.646 + 3608.500 87.075 2.646 + 3609.000 87.554 2.646 + 3609.500 88.258 2.647 + 3610.000 85.569 2.646 + 3610.500 78.803 2.644 + 3611.000 73.123 2.636 + 3611.500 67.257 2.636 + 3612.000 61.539 2.636 + 3612.500 52.431 2.636 + 3613.000 48.375 2.636 + 3613.500 46.901 2.641 + 3614.000 49.657 2.646 + 3614.500 56.309 2.646 + 3615.000 67.475 2.644 + 3615.500 75.381 2.648 + 3616.000 78.239 2.651 + 3616.500 77.149 2.652 + 3617.000 78.128 2.651 + 3617.500 78.097 2.647 + 3618.000 75.820 2.640 + 3618.500 70.560 2.630 + 3619.000 68.906 2.630 + 3619.500 70.358 2.632 + 3620.000 71.411 2.640 + 3620.500 74.090 2.651 + 3621.000 76.563 2.652 + 3621.500 79.095 2.647 + 3622.000 81.428 2.642 + 3622.500 81.460 2.641 + 3623.000 81.640 2.652 + 3623.500 80.818 2.660 + 3624.000 80.846 2.678 + 3624.500 80.092 2.673 + 3625.000 79.403 2.662 + 3625.500 76.937 2.647 + 3626.000 71.199 2.642 + 3626.500 67.006 2.645 + 3627.000 60.450 2.648 + 3627.500 62.017 2.657 + 3628.000 65.128 2.660 + 3628.500 68.499 2.653 + 3629.000 71.503 2.650 + 3629.500 73.735 2.644 + 3630.000 74.584 2.646 + 3630.500 75.682 2.653 + 3631.000 75.593 2.654 + 3631.500 75.247 2.652 + 3632.000 74.362 2.633 + 3632.500 71.918 2.630 + 3633.000 70.648 2.641 + 3633.500 69.859 2.648 + 3634.000 69.650 2.668 + 3634.500 69.590 2.677 + 3635.000 70.554 2.691 + 3635.500 72.913 2.695 + 3636.000 74.338 2.688 + 3636.500 77.302 2.673 + 3637.000 79.150 2.656 + 3637.500 80.827 2.651 + 3638.000 81.336 2.656 + 3638.500 80.777 2.667 + 3639.000 79.545 2.672 + 3639.500 78.281 2.673 + 3640.000 77.405 2.677 + 3640.500 76.998 2.681 + 3641.000 76.834 2.679 + 3641.500 77.809 2.672 + 3642.000 78.776 2.658 + 3642.500 78.918 2.652 + 3643.000 81.466 2.649 + 3643.500 84.339 2.651 + 3644.000 97.475 2.653 + 3644.500 95.963 2.660 + 3645.000 92.302 2.661 + 3645.500 83.732 2.657 + 3646.000 79.522 2.653 + 3646.500 79.432 2.653 + 3647.000 81.656 2.652 + 3647.500 85.137 2.655 + 3648.000 84.399 2.666 + 3648.500 81.382 2.696 + 3649.000 81.378 2.698 + 3649.500 81.206 2.694 + 3650.000 81.405 2.675 + 3650.500 81.830 2.655 + 3651.000 79.347 2.655 + 3651.500 79.318 2.658 + 3652.000 79.704 2.666 + 3652.500 91.553 2.675 + 3653.000 102.311 2.680 + 3653.500 104.326 2.675 + 3654.000 103.764 2.675 + 3654.500 101.703 2.680 + 3655.000 101.020 2.689 + 3655.500 97.762 2.687 + 3656.000 92.365 2.683 + 3656.500 80.308 2.674 + 3657.000 80.509 2.677 + 3657.500 82.962 2.683 + 3658.000 99.231 2.683 + 3658.500 105.554 2.682 + 3659.000 112.805 2.678 + 3659.500 117.983 2.665 + 3660.000 119.509 2.666 + 3660.500 120.709 2.667 + 3661.000 120.911 2.668 + 3661.500 110.568 2.670 + 3662.000 96.568 2.673 + 3662.500 91.726 2.684 + 3663.000 92.691 2.681 + 3663.500 93.142 2.672 + 3664.000 97.786 2.666 + 3664.500 100.570 2.659 + 3665.000 101.125 2.654 + 3665.500 100.810 2.654 + 3666.000 97.495 2.654 + 3666.500 93.092 2.655 + 3667.000 87.629 2.677 + 3667.500 89.672 2.690 + 3668.000 93.698 2.761 + 3668.500 110.110 2.802 + 3669.000 118.407 2.779 + 3669.500 119.139 2.737 + 3670.000 105.980 2.675 + 3670.500 76.541 2.604 + 3671.000 78.918 2.615 + 3671.500 80.984 2.631 + 3672.000 102.366 2.632 + 3672.500 108.666 2.547 + 3673.000 115.660 2.418 + 3673.500 117.836 2.351 + 3674.000 116.418 2.406 + 3674.500 111.335 2.434 + 3675.000 105.721 2.512 + 3675.500 92.991 2.532 + 3676.000 86.735 2.614 + 3676.500 84.279 2.632 + 3677.000 83.632 2.642 + 3677.500 86.233 2.653 + 3678.000 87.301 2.676 + 3678.500 89.557 2.810 + 3679.000 92.248 2.826 + 3679.500 95.872 2.543 + 3680.000 101.330 2.352 + 3680.500 102.911 2.410 + 3681.000 102.279 2.516 + 3681.500 100.280 2.747 + 3682.000 99.689 2.658 + 3682.500 95.879 2.673 + 3683.000 94.079 2.680 + 3683.500 93.411 2.688 + 3684.000 93.181 2.683 + 3684.500 92.315 2.679 + 3685.000 91.596 2.668 + 3685.500 91.764 2.673 + 3686.000 92.571 2.688 + 3686.500 98.012 2.726 + 3687.000 101.380 2.704 + 3687.500 100.738 2.675 + 3688.000 95.592 2.598 + 3688.500 84.382 2.608 + 3689.000 82.389 2.627 + 3689.500 81.838 2.653 + 3690.000 84.159 2.662 + 3690.500 86.681 2.669 + 3691.000 89.194 2.660 + 3691.500 91.865 2.648 + 3692.000 95.194 2.657 + 3692.500 96.176 2.677 + 3693.000 91.811 2.684 + 3693.500 89.899 2.686 + 3694.000 81.805 2.672 + 3694.500 77.800 2.669 + 3695.000 74.216 2.696 + 3695.500 73.867 2.708 + 3696.000 77.130 2.752 + 3696.500 93.376 2.540 + 3697.000 99.704 2.597 + 3697.500 104.701 2.195 + 3698.000 108.532 2.293 + 3698.500 106.992 2.505 + 3699.000 106.084 2.595 + 3699.500 104.783 2.630 + 3700.000 104.048 2.650 + 3700.500 98.209 2.670 + 3701.000 97.318 2.679 + 3701.500 96.459 2.679 + 3702.000 93.345 2.662 + 3702.500 85.652 2.654 + 3703.000 81.269 2.650 + 3703.500 78.632 2.654 + 3704.000 76.323 2.676 + 3704.500 86.984 2.769 + 3705.000 96.781 2.751 + 3705.500 111.481 2.727 + 3706.000 112.578 2.650 + 3706.500 101.904 2.616 + 3707.000 89.932 2.638 + 3707.500 81.123 2.658 + 3708.000 75.104 2.666 + 3708.500 73.499 2.676 + 3709.000 73.817 2.686 + 3709.500 81.384 2.685 + 3710.000 86.126 2.675 + 3710.500 90.937 2.629 + 3711.000 95.054 2.632 + 3711.500 95.006 2.644 + 3712.000 94.743 2.654 + 3712.500 91.906 2.663 + 3713.000 88.609 2.669 + 3713.500 83.171 2.670 + 3714.000 81.282 2.655 + 3714.500 82.947 2.647 + 3715.000 87.743 2.655 + 3715.500 86.762 2.672 + 3716.000 84.182 2.680 + 3716.500 81.449 2.671 + 3717.000 86.362 2.667 + 3717.500 92.940 2.669 + 3718.000 95.808 2.676 + 3718.500 95.224 2.677 + 3719.000 89.358 2.668 + 3719.500 82.539 2.662 + 3720.000 80.621 2.656 + 3720.500 80.709 2.655 + 3721.000 81.553 2.654 + 3721.500 88.686 2.659 + 3722.000 97.140 2.668 + 3722.500 102.236 2.685 + 3723.000 101.362 2.687 + 3723.500 97.658 2.684 + 3724.000 92.599 2.670 + 3724.500 85.489 2.661 + 3725.000 83.931 2.657 + 3725.500 81.983 2.657 + 3726.000 78.750 2.692 + 3726.500 81.609 2.761 + 3727.000 84.359 2.798 + 3727.500 88.522 2.849 + 3728.000 91.266 2.735 + 3728.500 87.456 2.611 + 3729.000 77.180 2.598 + 3729.500 73.147 2.613 + 3730.000 70.824 2.632 + 3730.500 69.795 2.687 + 3731.000 74.426 2.740 + 3731.500 82.066 2.783 + 3732.000 102.690 2.793 + 3732.500 113.783 2.677 + 3733.000 116.888 2.518 + 3733.500 122.592 2.260 + 3734.000 123.378 2.194 + 3734.500 119.844 2.050 + 3735.000 106.764 2.277 + 3735.500 97.991 2.566 + 3736.000 95.260 2.613 + 3736.500 89.223 2.650 + 3737.000 83.687 2.652 + 3737.500 79.899 2.648 + 3738.000 76.560 2.645 + 3738.500 74.364 2.649 + 3739.000 74.844 2.659 + 3739.500 73.743 2.663 + 3740.000 70.793 2.660 + 3740.500 68.166 2.642 + 3741.000 66.358 2.644 + 3741.500 64.004 2.649 + 3742.000 63.438 2.654 + 3742.500 65.809 2.661 + 3743.000 71.937 2.669 + 3743.500 75.205 2.669 + 3744.000 76.888 2.665 + 3744.500 74.586 2.658 + 3745.000 73.705 2.657 + 3745.500 72.036 2.662 + 3746.000 72.172 2.665 + 3746.500 68.685 2.665 + 3747.000 65.531 2.656 + 3747.500 64.968 2.642 + 3748.000 67.659 2.636 + 3748.500 73.641 2.643 + 3749.000 77.569 2.652 + 3749.500 79.107 2.661 + 3750.000 79.337 2.665 + 3750.500 73.456 2.666 + 3751.000 71.296 2.668 + 3751.500 70.334 2.669 + 3752.000 71.234 2.658 + 3752.500 75.043 2.650 + 3753.000 77.371 2.647 + 3753.500 79.557 2.651 + 3754.000 80.767 2.657 + 3754.500 80.904 2.659 + 3755.000 81.063 2.660 + 3755.500 81.751 2.655 + 3756.000 82.426 2.652 + 3756.500 84.440 2.652 + 3757.000 86.290 2.651 + 3757.500 87.687 2.657 + 3758.000 89.489 2.658 + 3758.500 88.822 2.661 + 3759.000 86.371 2.667 + 3759.500 80.119 2.670 + 3760.000 77.542 2.668 + 3760.500 75.630 2.664 + 3761.000 74.570 2.667 + 3761.500 74.219 2.674 + 3762.000 73.730 2.691 + 3762.500 78.985 2.774 + 3763.000 87.859 2.757 + 3763.500 97.504 2.714 + 3764.000 104.365 2.537 + 3764.500 109.896 2.376 + 3765.000 108.036 2.380 + 3765.500 102.171 2.373 + 3766.000 98.437 2.404 + 3766.500 88.006 2.612 + 3767.000 81.485 2.606 + 3767.500 77.084 2.643 + 3768.000 75.024 2.635 + 3768.500 77.253 2.629 + 3769.000 78.607 2.632 + 3769.500 84.168 2.646 + 3770.000 95.359 2.659 + 3770.500 101.700 2.662 + 3771.000 103.029 2.658 + 3771.500 101.046 2.659 + 3772.000 98.224 2.661 + 3772.500 93.556 2.662 + 3773.000 88.576 2.660 + 3773.500 85.255 2.659 + 3774.000 79.300 2.657 + 3774.500 72.836 2.654 + 3775.000 64.599 2.638 + 3775.500 60.750 2.632 + 3776.000 59.213 2.634 + 3776.500 56.138 2.629 + 3777.000 53.589 2.626 + 3777.500 56.184 2.631 + 3778.000 60.728 2.637 + 3778.500 66.598 2.641 + 3779.000 67.286 2.637 + 3779.500 66.846 2.630 + 3780.000 64.702 2.627 + 3780.500 62.255 2.623 + 3781.000 61.179 2.623 + 3781.500 60.877 2.622 + 3782.000 62.750 2.624 + 3782.500 68.005 2.622 + 3783.000 72.788 2.622 + 3783.500 73.136 2.625 + 3784.000 72.422 2.637 + 3784.500 65.338 2.647 + 3785.000 60.129 2.635 + 3785.500 59.288 2.610 + 3786.000 60.284 2.597 + 3786.500 61.021 2.613 + 3787.000 60.576 2.625 + 3787.500 56.059 2.640 + 3788.000 54.776 2.660 + 3788.500 57.879 2.698 + 3789.000 61.350 2.696 + 3789.500 67.262 2.688 + 3790.000 68.188 2.662 + 3790.500 66.686 2.646 + 3791.000 63.526 2.650 + 3791.500 61.474 2.648 + 3792.000 61.410 2.643 + 3792.500 63.922 2.638 + 3793.000 67.236 2.642 + 3793.500 69.086 2.644 + 3794.000 70.774 2.648 + 3794.500 71.342 2.660 + 3795.000 71.079 2.666 + 3795.500 72.102 2.664 + 3796.000 71.386 2.663 + 3796.500 73.359 2.662 + 3797.000 74.418 2.662 + 3797.500 74.548 2.661 + 3798.000 73.063 2.659 + 3798.500 71.841 2.648 + 3799.000 70.388 2.645 + 3799.500 69.849 2.638 + 3800.000 70.169 2.641 + 3800.500 72.580 2.644 + 3801.000 74.950 2.640 + 3801.500 75.247 2.637 + 3802.000 74.500 2.646 + 3802.500 72.892 2.655 + 3803.000 72.940 2.675 + 3803.500 74.514 2.680 + 3804.000 77.079 2.684 + 3804.500 78.728 2.666 + 3805.000 80.634 2.662 + 3805.500 81.194 2.658 + 3806.000 81.768 2.664 + 3806.500 80.255 2.677 + 3807.000 78.794 2.670 + 3807.500 74.994 2.653 + 3808.000 75.306 2.650 + 3808.500 75.224 2.650 + 3809.000 74.413 2.653 + 3809.500 72.208 2.657 + 3810.000 71.215 2.663 + 3810.500 71.441 2.667 + 3811.000 72.125 2.658 + 3811.500 71.729 2.649 + 3812.000 69.700 2.640 + 3812.500 67.604 2.629 + 3813.000 67.244 2.628 + 3813.500 68.076 2.643 + 3814.000 68.975 2.659 + 3814.500 68.805 2.675 + 3815.000 67.292 2.664 + 3815.500 65.805 2.651 + 3816.000 66.631 2.646 + 3816.500 69.493 2.652 + 3817.000 71.722 2.650 + 3817.500 72.393 2.648 + 3818.000 69.127 2.646 + 3818.500 65.849 2.648 + 3819.000 62.353 2.648 + 3819.500 62.874 2.646 + 3820.000 65.812 2.644 + 3820.500 68.056 2.637 + 3821.000 69.691 2.636 + 3821.500 68.239 2.641 + 3822.000 66.832 2.644 + 3822.500 71.542 2.651 + 3823.000 75.215 2.656 + 3823.500 85.022 2.663 + 3824.000 89.162 2.669 + 3824.500 89.147 2.678 + 3825.000 86.921 2.680 + 3825.500 85.136 2.678 + 3826.000 86.121 2.676 + 3826.500 86.484 2.677 + 3827.000 83.884 2.679 + 3827.500 80.404 2.678 + 3828.000 76.914 2.672 + 3828.500 75.802 2.663 + 3829.000 74.408 2.656 + 3829.500 72.269 2.666 + 3830.000 71.696 2.672 + 3830.500 72.714 2.675 + 3831.000 75.353 2.669 + 3831.500 80.603 2.662 + 3832.000 82.511 2.662 + 3832.500 87.652 2.667 + 3833.000 90.213 2.669 + 3833.500 90.809 2.664 + 3834.000 86.269 2.658 + 3834.500 81.990 2.652 + 3835.000 77.192 2.661 + 3835.500 76.161 2.668 + 3836.000 75.933 2.668 + 3836.500 73.618 2.661 + 3837.000 71.069 2.656 + 3837.500 68.659 2.657 + 3838.000 68.298 2.662 + 3838.500 66.085 2.663 + 3839.000 64.207 2.654 + 3839.500 61.870 2.649 + 3840.000 61.289 2.648 + 3840.500 65.140 2.646 + 3841.000 67.275 2.646 + 3841.500 68.364 2.647 + 3842.000 68.784 2.646 + 3842.500 68.015 2.644 + 3843.000 65.761 2.632 + 3843.500 63.344 2.628 + 3844.000 62.705 2.630 + 3844.500 62.009 2.637 + 3845.000 61.699 2.659 + 3845.500 62.384 2.664 + 3846.000 62.951 2.674 + 3846.500 66.486 2.674 + 3847.000 69.013 2.667 + 3847.500 69.367 2.658 + 3848.000 70.749 2.654 + 3848.500 72.164 2.655 + 3849.000 72.752 2.660 + 3849.500 74.307 2.672 + 3850.000 77.284 2.682 + 3850.500 80.986 2.698 + 3851.000 84.645 2.700 + 3851.500 86.159 2.699 + 3852.000 85.076 2.698 + 3852.500 80.763 2.685 + 3853.000 75.639 2.674 + 3853.500 70.383 2.664 + 3854.000 67.025 2.663 + 3854.500 66.532 2.664 + 3855.000 66.794 2.665 + 3855.500 69.020 2.666 + 3856.000 71.862 2.666 + 3856.500 71.909 2.666 + 3857.000 72.183 2.668 + 3857.500 69.085 2.668 + 3858.000 68.052 2.675 + 3858.500 68.691 2.679 + 3859.000 71.519 2.675 + 3859.500 76.107 2.672 + 3860.000 78.557 2.667 + 3860.500 78.465 2.662 + 3861.000 76.568 2.661 + 3861.500 74.345 2.651 + 3862.000 75.312 2.645 + 3862.500 81.665 2.629 + 3863.000 83.037 2.627 + 3863.500 82.717 2.633 + 3864.000 79.374 2.646 + 3864.500 75.201 2.655 + 3865.000 72.083 2.656 + 3865.500 70.734 2.654 + 3866.000 70.140 2.651 + 3866.500 72.956 2.650 + 3867.000 72.691 2.652 + 3867.500 72.798 2.652 + 3868.000 71.190 2.658 + 3868.500 70.402 2.667 + 3869.000 70.472 2.682 + 3869.500 70.560 2.689 + 3870.000 69.679 2.693 + 3870.500 68.790 2.686 + 3871.000 68.998 2.673 + 3871.500 68.238 2.666 + 3872.000 68.131 2.658 + 3872.500 68.207 2.653 + 3873.000 69.030 2.650 + 3873.500 69.725 2.650 + 3874.000 70.234 2.650 + 3874.500 68.673 2.652 + 3875.000 67.079 2.652 + 3875.500 66.021 2.656 + 3876.000 64.968 2.656 + 3876.500 65.490 2.652 + 3877.000 64.761 2.649 + 3877.500 65.546 2.647 + 3878.000 64.586 2.642 + 3878.500 65.373 2.633 + 3879.000 67.972 2.627 + 3879.500 71.081 2.624 + 3880.000 74.460 2.626 + 3880.500 77.198 2.636 + 3881.000 79.045 2.644 + 3881.500 79.190 2.649 + 3882.000 78.712 2.650 + 3882.500 76.460 2.651 + 3883.000 76.028 2.651 + 3883.500 75.780 2.652 + 3884.000 76.884 2.660 + 3884.500 75.391 2.680 + 3885.000 75.122 2.685 + 3885.500 72.048 2.687 + 3886.000 71.244 2.674 + 3886.500 70.441 2.657 + 3887.000 72.126 2.651 + 3887.500 72.825 2.649 + 3888.000 71.197 2.648 + 3888.500 69.644 2.650 + 3889.000 68.966 2.655 + 3889.500 69.722 2.663 + 3890.000 69.729 2.664 + 3890.500 69.108 2.671 + 3891.000 70.052 2.682 + 3891.500 71.903 2.694 + 3892.000 75.664 2.701 + 3892.500 78.568 2.682 + 3893.000 81.348 2.671 + 3893.500 89.244 2.677 + 3894.000 95.421 2.689 + 3894.500 94.713 2.693 + 3895.000 91.858 2.688 + 3895.500 78.653 2.682 + 3896.000 74.789 2.679 + 3896.500 78.375 2.677 + 3897.000 86.354 2.680 + 3897.500 94.861 2.682 + 3898.000 102.227 2.682 + 3898.500 103.605 2.670 + 3899.000 101.597 2.665 + 3899.500 97.126 2.662 + 3900.000 87.048 2.659 + 3900.500 79.266 2.654 + 3901.000 66.950 2.650 + 3901.500 66.247 2.648 + 3902.000 64.447 2.644 + 3902.500 63.874 2.649 + 3903.000 65.689 2.649 + 3903.500 69.337 2.651 + 3904.000 75.520 2.660 + 3904.500 78.806 2.680 + 3905.000 85.090 2.688 + 3905.500 87.808 2.686 + 3906.000 90.789 2.674 + 3906.500 92.785 2.663 + 3907.000 89.160 2.661 + 3907.500 84.293 2.665 + 3908.000 68.025 2.668 + 3908.500 53.209 2.654 + 3909.000 54.887 2.646 + 3909.500 55.316 2.633 + 3910.000 66.033 2.538 + 3910.500 72.475 2.410 + 3911.000 73.066 2.378 + 3911.500 68.562 2.450 + 3912.000 64.845 2.529 + 3912.500 63.244 2.610 + 3913.000 65.187 2.657 + 3913.500 75.790 2.660 + 3914.000 79.999 2.666 + 3914.500 84.892 2.675 + 3915.000 86.108 2.675 + 3915.500 79.962 2.670 + 3916.000 75.858 2.668 + 3916.500 66.915 2.664 + 3917.000 68.222 2.651 + 3917.500 68.036 2.641 + 3918.000 71.599 2.631 + 3918.500 76.597 2.629 + 3919.000 79.389 2.629 + 3919.500 80.031 2.634 + 3920.000 77.837 2.642 + 3920.500 72.208 2.659 + 3921.000 69.496 2.669 + 3921.500 67.980 2.675 + 3922.000 68.776 2.679 + 3922.500 69.772 2.676 + 3923.000 67.377 2.665 + 3923.500 61.470 2.654 + 3924.000 57.790 2.652 + 3924.500 58.123 2.662 + 3925.000 57.977 2.675 + 3925.500 65.751 2.677 + 3926.000 69.945 2.671 + 3926.500 73.730 2.666 + 3927.000 72.945 2.677 + 3927.500 71.498 2.693 + 3928.000 69.702 2.698 + 3928.500 65.085 2.679 + 3929.000 59.785 2.649 + 3929.500 58.668 2.639 + 3930.000 62.585 2.640 + 3930.500 74.359 2.651 + 3931.000 79.206 2.652 + 3931.500 79.896 2.652 + 3932.000 72.573 2.649 + 3932.500 56.479 2.646 + 3933.000 57.204 2.641 + 3933.500 54.104 2.637 + 3934.000 67.042 2.647 + 3934.500 71.152 2.658 + 3935.000 78.748 2.649 + 3935.500 80.879 2.638 + 3936.000 79.805 2.627 + 3936.500 76.808 2.646 + 3937.000 67.313 2.650 + 3937.500 61.899 2.643 + 3938.000 55.357 2.640 + 3938.500 53.775 2.636 + 3939.000 55.736 2.633 + 3939.500 60.672 2.627 + 3940.000 64.316 2.627 + 3940.500 64.092 2.640 + 3941.000 60.683 2.650 + 3941.500 52.494 2.654 + 3942.000 47.617 2.654 + 3942.500 48.112 2.660 + 3943.000 50.499 2.665 + 3943.500 58.606 2.661 + 3944.000 61.432 2.651 + 3944.500 68.424 2.643 + 3945.000 70.378 2.640 + 3945.500 69.929 2.647 + 3946.000 66.734 2.646 + 3946.500 61.347 2.638 + 3947.000 60.879 2.635 + 3947.500 61.211 2.641 + 3948.000 63.327 2.646 + 3948.500 61.729 2.651 + 3949.000 60.926 2.647 + 3949.500 58.344 2.645 + 3950.000 56.259 2.645 + 3950.500 59.196 2.647 + 3951.000 61.766 2.647 + 3951.500 61.325 2.640 + 3952.000 59.831 2.634 + 3952.500 58.589 2.631 + 3953.000 57.811 2.636 + 3953.500 57.548 2.636 + 3954.000 58.453 2.639 + 3954.500 58.729 2.643 + 3955.000 60.977 2.650 + 3955.500 62.499 2.654 + 3956.000 68.281 2.658 + 3956.500 74.180 2.659 + 3957.000 76.461 2.666 + 3957.500 79.180 2.667 + 3958.000 79.416 2.662 + 3958.500 73.594 2.611 + 3959.000 69.124 2.580 + 3959.500 58.825 2.585 + 3960.000 51.704 2.605 + 3960.500 47.755 2.616 + 3961.000 49.103 2.618 + 3961.500 55.524 2.624 + 3962.000 64.732 2.627 + 3962.500 69.642 2.634 + 3963.000 67.356 2.636 + 3963.500 65.606 2.639 + 3964.000 64.208 2.643 + 3964.500 65.015 2.645 + 3965.000 67.988 2.646 + 3965.500 70.636 2.650 + 3966.000 73.034 2.649 + 3966.500 73.681 2.640 + 3967.000 72.814 2.635 + 3967.500 69.679 2.632 + 3968.000 67.259 2.649 + 3968.500 67.980 2.656 + 3969.000 68.341 2.644 + 3969.500 68.356 2.634 + 3970.000 67.285 2.622 + 3970.500 61.836 2.642 + 3971.000 61.304 2.646 + 3971.500 59.560 2.643 + 3972.000 59.835 2.629 + 3972.500 58.466 2.621 + 3973.000 58.092 2.617 + 3973.500 58.159 2.616 + 3974.000 59.646 2.617 + 3974.500 61.950 2.620 + 3975.000 62.633 2.618 + 3975.500 63.419 2.647 + 3976.000 65.572 2.711 + 3976.500 72.765 2.696 + 3977.000 79.052 2.633 + 3977.500 80.518 2.590 + 3978.000 77.906 2.557 + 3978.500 72.502 2.590 + 3979.000 69.108 2.616 + 3979.500 68.765 2.618 + 3980.000 64.319 2.626 + 3980.500 57.703 2.644 + 3981.000 54.961 2.635 + 3981.500 56.940 2.632 + 3982.000 62.235 2.629 + 3982.500 81.781 2.622 + 3983.000 88.309 2.622 + 3983.500 92.408 2.625 + 3984.000 89.743 2.658 + 3984.500 87.969 2.740 + 3985.000 90.063 2.717 + 3985.500 101.039 2.700 + 3986.000 111.292 2.480 + 3986.500 127.069 2.489 + 3987.000 126.677 2.502 + 3987.500 124.699 2.510 + 3988.000 113.289 2.487 + 3988.500 96.102 2.503 + 3989.000 75.650 2.654 + 3989.500 65.320 2.679 + 3990.000 57.771 2.747 + 3990.500 54.804 2.603 + 3991.000 54.415 2.515 + 3991.500 57.581 2.533 + 3992.000 62.375 2.580 + 3992.500 70.835 2.621 + 3993.000 76.931 2.634 + 3993.500 78.712 2.653 + 3994.000 79.135 2.660 + 3994.500 78.931 2.662 + 3995.000 76.595 2.659 + 3995.500 70.508 2.642 + 3996.000 67.151 2.625 + 3996.500 61.685 2.612 + 3997.000 60.177 2.617 + 3997.500 60.139 2.629 + 3998.000 60.132 2.628 + 3998.500 59.316 2.627 + 3999.000 59.558 2.624 + 3999.500 60.076 2.628 + 4000.000 63.068 2.630 + 4000.500 65.112 2.634 + 4001.000 64.587 2.640 + 4001.500 61.923 2.646 + 4002.000 59.958 2.649 + 4002.500 58.537 2.659 + 4003.000 56.588 2.660 + 4003.500 55.756 2.654 + 4004.000 54.877 2.637 + 4004.500 54.088 2.623 + 4005.000 53.937 2.617 + 4005.500 53.815 2.617 + 4006.000 54.972 2.625 + 4006.500 56.218 2.631 + 4007.000 57.762 2.637 + 4007.500 58.654 2.639 + 4008.000 58.710 2.640 + 4008.500 58.925 2.636 + 4009.000 60.344 2.629 + 4009.500 63.738 2.640 + 4010.000 67.784 2.646 + 4010.500 71.289 2.644 + 4011.000 73.759 2.640 + 4011.500 70.717 2.640 + 4012.000 66.796 2.640 + 4012.500 61.030 2.640 + 4013.000 55.638 2.640 + 4013.500 57.673 2.643 + 4014.000 60.026 2.646 + 4014.500 64.738 2.647 + 4015.000 66.893 2.649 + 4015.500 63.339 2.646 + 4016.000 59.563 2.644 + 4016.500 53.355 2.621 + 4017.000 50.949 2.603 + 4017.500 50.661 2.603 + 4018.000 51.311 2.619 + 4018.500 55.544 2.641 + 4019.000 59.091 2.653 + 4019.500 61.010 2.653 + 4020.000 61.739 2.654 + 4020.500 59.407 2.635 + 4021.000 52.557 2.623 + 4021.500 49.732 2.616 + 4022.000 49.374 2.618 + 4022.500 53.157 2.620 + 4023.000 53.490 2.621 + 4023.500 54.650 2.621 + 4024.000 54.915 2.621 + 4024.500 55.342 2.626 + 4025.000 59.861 2.637 + 4025.500 63.252 2.668 + 4026.000 69.648 2.677 + 4026.500 71.866 2.654 + 4027.000 70.046 2.623 + 4027.500 67.452 2.628 + 4028.000 69.050 2.636 + 4028.500 73.605 2.646 + 4029.000 73.393 2.647 + 4029.500 70.184 2.642 + 4030.000 65.425 2.635 + 4030.500 56.315 2.626 + 4031.000 47.531 2.608 + 4031.500 47.775 2.605 + 4032.000 47.888 2.603 + 4032.500 52.179 2.602 + 4033.000 59.250 2.620 + 4033.500 70.169 2.628 + 4034.000 95.443 2.621 + 4034.500 106.096 2.559 + 4035.000 114.880 2.558 + 4035.500 116.883 2.577 + 4036.000 120.285 2.638 + 4036.500 119.347 2.553 + 4037.000 119.613 2.405 + 4037.500 116.343 2.421 + 4038.000 111.569 2.396 + 4038.500 102.146 2.572 + 4039.000 93.079 2.563 + 4039.500 83.785 2.603 + 4040.000 80.114 2.626 + 4040.500 83.084 2.693 + 4041.000 89.357 2.684 + 4041.500 103.136 2.673 + 4042.000 111.949 2.639 + 4042.500 119.025 2.565 + 4043.000 118.173 2.551 + 4043.500 111.212 2.652 + 4044.000 97.995 2.642 + 4044.500 68.701 2.632 + 4045.000 63.911 2.623 + 4045.500 56.936 2.617 + 4046.000 58.110 2.621 + 4046.500 58.819 2.633 + 4047.000 58.271 2.645 + 4047.500 58.808 2.648 + 4048.000 61.905 2.659 + 4048.500 72.942 2.682 + 4049.000 76.521 2.701 + 4049.500 89.062 2.648 + 4050.000 97.084 2.655 + 4050.500 99.352 2.567 + 4051.000 111.562 2.753 + 4051.500 115.758 2.718 + 4052.000 117.975 2.644 + 4052.500 118.476 2.487 + 4053.000 106.398 2.422 + 4053.500 101.755 2.467 + 4054.000 88.542 2.527 + 4054.500 85.035 2.569 + 4055.000 77.947 2.632 + 4055.500 70.075 2.640 + 4056.000 62.910 2.625 + 4056.500 53.666 2.620 + 4057.000 51.824 2.621 + 4057.500 51.827 2.639 + 4058.000 51.055 2.659 + 4058.500 60.944 2.733 + 4059.000 64.477 2.686 + 4059.500 82.880 2.636 + 4060.000 78.710 2.426 + 4060.500 75.944 2.493 + 4061.000 71.889 2.600 + 4061.500 70.321 2.699 + 4062.000 74.344 2.621 + 4062.500 81.555 2.326 + 4063.000 78.314 2.099 + 4063.500 76.993 2.167 + 4064.000 59.556 2.336 + 4064.500 56.356 2.589 + 4065.000 53.455 2.605 + 4065.500 55.520 2.605 + 4066.000 60.817 2.605 + 4066.500 63.198 2.622 + 4067.000 72.364 2.646 + 4067.500 72.628 2.650 + 4068.000 73.557 2.650 + 4068.500 65.762 2.651 + 4069.000 65.659 2.644 + 4069.500 69.473 2.614 + 4070.000 75.767 2.552 + 4070.500 77.621 2.494 + 4071.000 75.621 2.487 + 4071.500 72.136 2.467 + 4072.000 66.046 2.450 + 4072.500 60.218 2.538 + 4073.000 57.601 2.600 + 4073.500 58.121 2.674 + 4074.000 67.307 2.670 + 4074.500 80.149 2.396 + 4075.000 96.534 2.411 + 4075.500 111.955 1.999 + 4076.000 115.794 2.287 + 4076.500 111.293 2.265 + 4077.000 104.847 2.566 + 4077.500 94.177 2.762 + 4078.000 99.347 2.766 + 4078.500 105.109 2.756 + 4079.000 111.560 2.724 + 4079.500 115.347 2.668 + 4080.000 112.813 2.511 + 4080.500 106.186 2.509 + 4081.000 101.227 2.530 + 4081.500 98.601 2.532 + 4082.000 102.846 2.468 + 4082.500 112.216 2.428 + 4083.000 115.551 2.407 + 4083.500 118.794 2.404 + 4084.000 120.786 2.408 + 4084.500 112.882 2.514 + 4085.000 104.881 2.541 + 4085.500 97.183 2.623 + 4086.000 90.550 2.713 + 4086.500 85.775 2.790 + 4087.000 90.826 2.788 + 4087.500 102.950 2.725 + 4088.000 108.789 2.704 + 4088.500 112.882 2.671 + 4089.000 117.807 2.656 + 4089.500 118.463 2.652 + 4090.000 119.230 2.649 + 4090.500 118.859 2.615 + 4091.000 115.347 2.543 + 4091.500 112.215 2.451 + 4092.000 102.132 2.487 + 4092.500 93.987 2.606 + 4093.000 81.043 2.650 + 4093.500 79.244 2.640 + 4094.000 77.679 2.638 + 4094.500 82.675 2.636 + 4095.000 86.667 2.630 + 4095.500 94.007 2.610 + 4096.000 95.126 2.581 + 4096.500 90.898 2.542 + 4097.000 76.312 2.547 + 4097.500 69.273 2.582 + 4098.000 61.503 2.613 + 4098.500 61.507 2.616 + 4099.000 67.843 2.610 + 4099.500 76.012 2.605 + 4100.000 74.204 2.604 + 4100.500 68.045 2.609 + 4101.000 61.606 2.622 + 4101.500 59.150 2.633 + 4102.000 59.257 2.645 + 4102.500 62.524 2.654 + 4103.000 62.697 2.637 + 4103.500 61.195 2.624 + 4104.000 62.391 2.630 + 4104.500 64.019 2.647 + 4105.000 64.224 2.642 + 4105.500 64.312 2.637 + 4106.000 65.050 2.635 + 4106.500 65.162 2.633 + 4107.000 65.441 2.653 + 4107.500 65.637 2.657 + 4108.000 64.585 2.653 + 4108.500 63.518 2.634 + 4109.000 63.172 2.618 + 4109.500 66.804 2.602 + 4110.000 70.454 2.598 + 4110.500 80.476 2.628 + 4111.000 78.448 2.646 + 4111.500 74.363 2.644 + 4112.000 64.929 2.620 + 4112.500 50.315 2.599 + 4113.000 43.068 2.605 + 4113.500 44.900 2.625 + 4114.000 52.506 2.628 + 4114.500 56.681 2.628 + 4115.000 59.589 2.624 + 4115.500 53.999 2.621 + 4116.000 50.262 2.622 + 4116.500 45.594 2.631 + 4117.000 57.015 2.630 + 4117.500 77.771 2.621 + 4118.000 88.772 2.599 + 4118.500 86.523 2.586 + 4119.000 82.142 2.594 + 4119.500 79.607 2.610 + 4120.000 83.115 2.623 + 4120.500 84.148 2.628 + 4121.000 82.815 2.640 + 4121.500 78.179 2.646 + 4122.000 64.220 2.640 + 4122.500 60.160 2.617 + 4123.000 57.362 2.600 + 4123.500 56.192 2.598 + 4124.000 51.350 2.595 + 4124.500 47.621 2.589 + 4125.000 46.265 2.591 + 4125.500 61.154 2.599 + 4126.000 69.774 2.608 + 4126.500 88.804 2.610 + 4127.000 95.879 2.603 + 4127.500 95.947 2.600 + 4128.000 87.774 2.598 + 4128.500 69.923 2.609 + 4129.000 63.739 2.618 + 4129.500 58.481 2.621 + 4130.000 58.610 2.618 + 4130.500 51.059 2.607 + 4131.000 45.351 2.612 + 4131.500 38.846 2.618 + 4132.000 36.151 2.620 + 4132.500 35.564 2.615 + 4133.000 35.162 2.606 + 4133.500 34.807 2.602 + 4134.000 39.796 2.596 + 4134.500 44.389 2.638 + 4135.000 62.079 2.666 + 4135.500 79.306 2.659 + 4136.000 105.791 2.572 + 4136.500 114.280 2.525 + 4137.000 124.408 2.576 + 4137.500 124.412 2.634 + 4138.000 125.545 2.680 + 4138.500 127.808 2.675 + 4139.000 127.556 2.668 + 4139.500 124.980 2.667 + 4140.000 115.245 2.665 + 4140.500 109.968 2.673 + 4141.000 95.979 2.638 + 4141.500 90.708 2.597 + 4142.000 78.197 2.563 + 4142.500 62.857 2.583 + 4143.000 64.920 2.603 + 4143.500 71.795 2.597 + 4144.000 84.422 2.584 + 4144.500 95.008 2.587 + 4145.000 95.455 2.606 + 4145.500 93.549 2.616 + 4146.000 93.526 2.625 + 4146.500 95.672 2.637 + 4147.000 95.615 2.654 + 4147.500 95.297 2.693 + 4148.000 94.734 2.686 + 4148.500 94.044 2.647 + 4149.000 95.428 2.637 + 4149.500 96.889 2.642 + 4150.000 112.220 2.646 + 4150.500 112.591 2.614 + 4151.000 112.732 2.589 + 4151.500 106.727 2.581 + 4152.000 103.136 2.607 + 4152.500 106.164 2.621 + 4153.000 109.984 2.636 + 4153.500 115.944 2.645 + 4154.000 117.802 2.652 + 4154.500 119.509 2.655 + 4155.000 119.220 2.661 + 4155.500 119.414 2.670 + 4156.000 121.064 2.698 + 4156.500 125.742 2.694 + 4157.000 128.957 2.684 + 4157.500 129.292 2.556 + 4158.000 128.039 2.479 + 4158.500 126.319 2.533 + 4159.000 124.918 2.627 + 4159.500 120.307 2.652 + 4160.000 112.920 2.652 + 4160.500 105.053 2.638 + 4161.000 92.348 2.630 + 4161.500 93.925 2.611 + 4162.000 96.260 2.579 + 4162.500 97.148 2.576 + 4163.000 97.632 2.604 + 4163.500 81.643 2.616 + 4164.000 76.511 2.636 + 4164.500 74.381 2.652 + 4165.000 80.499 2.662 + 4165.500 81.676 2.676 + 4166.000 76.892 2.676 + 4166.500 72.637 2.655 + 4167.000 60.429 2.646 + 4167.500 58.044 2.647 + 4168.000 60.026 2.643 + 4168.500 67.544 2.642 + 4169.000 72.910 2.635 + 4169.500 83.506 2.683 + 4170.000 96.782 2.677 + 4170.500 106.316 2.751 + 4171.000 109.440 2.597 + 4171.500 110.881 2.488 + 4172.000 109.396 2.521 + 4172.500 105.335 2.577 + 4173.000 102.551 2.627 + 4173.500 95.959 2.614 + 4174.000 84.351 2.597 + 4174.500 74.433 2.599 + 4175.000 65.003 2.599 + 4175.500 54.502 2.581 + 4176.000 47.532 2.569 + 4176.500 46.581 2.564 + 4177.000 53.215 2.578 + 4177.500 60.687 2.631 + 4178.000 69.635 2.714 + 4178.500 92.123 2.708 + 4179.000 92.218 2.667 + 4179.500 92.167 2.683 + 4180.000 94.861 2.733 + 4180.500 105.642 2.728 + 4181.000 115.291 2.661 + 4181.500 119.227 2.411 + 4182.000 115.427 2.359 + 4182.500 109.536 2.438 + 4183.000 107.025 2.431 + 4183.500 106.637 2.617 + 4184.000 106.749 2.668 + 4184.500 104.024 2.674 + 4185.000 101.496 2.654 + 4185.500 96.122 2.642 + 4186.000 92.023 2.642 + 4186.500 90.590 2.654 + 4187.000 96.969 2.650 + 4187.500 101.572 2.648 + 4188.000 111.307 2.653 + 4188.500 117.079 2.664 + 4189.000 119.774 2.650 + 4189.500 117.686 2.651 + 4190.000 117.408 2.680 + 4190.500 114.646 2.695 + 4191.000 110.966 2.667 + 4191.500 111.175 2.640 + 4192.000 113.278 2.621 + 4192.500 111.783 2.606 + 4193.000 109.675 2.566 + 4193.500 105.870 2.519 + 4194.000 99.230 2.477 + 4194.500 93.100 2.431 + 4195.000 87.903 2.492 + 4195.500 80.631 2.584 + 4196.000 75.638 2.631 + 4196.500 66.202 2.624 + 4197.000 65.822 2.628 + 4197.500 68.170 2.641 + 4198.000 79.679 2.667 + 4198.500 98.899 2.696 + 4199.000 103.382 2.686 + 4199.500 106.032 2.668 + 4200.000 106.191 2.664 + 4200.500 111.072 2.650 + 4201.000 113.899 2.588 + 4201.500 113.967 2.558 + 4202.000 107.736 2.546 + 4202.500 90.867 2.559 + 4203.000 84.021 2.598 + 4203.500 73.306 2.615 + 4204.000 71.985 2.636 + 4204.500 71.708 2.642 + 4205.000 78.226 2.649 + 4205.500 90.249 2.645 + 4206.000 97.780 2.660 + 4206.500 100.718 2.651 + 4207.000 96.399 2.641 + 4207.500 98.454 2.641 + 4208.000 105.825 2.647 + 4208.500 108.229 2.651 + 4209.000 110.451 2.652 + 4209.500 106.825 2.645 + 4210.000 86.906 2.636 + 4210.500 55.249 2.629 + 4211.000 51.796 2.622 + 4211.500 43.709 2.612 + 4212.000 43.346 2.597 + 4212.500 51.786 2.601 + 4213.000 64.125 2.607 + 4213.500 80.258 2.626 + 4214.000 92.554 2.640 + 4214.500 99.606 2.675 + 4215.000 105.733 2.693 + 4215.500 111.602 2.700 + 4216.000 112.147 2.700 + 4216.500 111.967 2.716 + 4217.000 112.333 2.722 + 4217.500 112.193 2.718 + 4218.000 112.899 2.697 + 4218.500 112.903 2.637 + 4219.000 111.763 2.576 + 4219.500 104.945 2.567 + 4220.000 100.280 2.584 + 4220.500 88.879 2.614 + 4221.000 90.680 2.618 + 4221.500 91.848 2.617 + 4222.000 94.209 2.617 + 4222.500 96.388 2.630 + 4223.000 97.000 2.637 + 4223.500 97.313 2.640 + 4224.000 93.828 2.634 + 4224.500 88.947 2.627 + 4225.000 88.650 2.647 + 4225.500 89.533 2.682 + 4226.000 100.595 2.713 + 4226.500 107.435 2.703 + 4227.000 105.269 2.666 + 4227.500 101.605 2.648 + 4228.000 97.340 2.631 + 4228.500 92.176 2.637 + 4229.000 95.054 2.649 + 4229.500 95.932 2.647 + 4230.000 99.170 2.637 + 4230.500 97.750 2.629 + 4231.000 106.589 2.623 + 4231.500 108.482 2.605 + 4232.000 112.569 2.569 + 4232.500 108.134 2.572 + 4233.000 99.791 2.603 + 4233.500 93.787 2.614 + 4234.000 86.432 2.604 + 4234.500 80.677 2.601 + 4235.000 77.162 2.609 + 4235.500 73.904 2.613 + 4236.000 70.588 2.619 + 4236.500 74.931 2.627 + 4237.000 84.975 2.639 + 4237.500 99.777 2.647 + 4238.000 106.597 2.608 + 4238.500 111.308 2.671 + 4239.000 110.708 2.714 + 4239.500 110.391 2.692 + 4240.000 112.254 2.666 + 4240.500 113.018 2.378 + 4241.000 112.348 2.160 + 4241.500 106.280 2.280 + 4242.000 102.128 2.473 + 4242.500 98.516 2.619 + 4243.000 90.940 2.641 + 4243.500 83.255 2.660 + 4244.000 81.291 2.670 + 4244.500 81.764 2.664 + 4245.000 88.264 2.668 + 4245.500 93.631 2.712 + 4246.000 95.827 2.824 + 4246.500 100.213 2.799 + 4247.000 108.875 2.725 + 4247.500 111.202 2.516 + 4248.000 113.236 2.522 + 4248.500 111.557 2.621 + 4249.000 109.801 2.616 + 4249.500 106.330 2.654 + 4250.000 106.945 2.685 + 4250.500 110.391 2.593 + 4251.000 120.299 2.411 + 4251.500 122.404 2.225 + 4252.000 121.636 2.105 + 4252.500 117.156 2.156 + 4253.000 112.344 2.575 + 4253.500 109.434 2.570 + 4254.000 106.862 2.564 + 4254.500 100.563 2.625 + 4255.000 94.049 2.645 + 4255.500 92.813 2.674 + 4256.000 92.123 2.672 + 4256.500 89.526 2.674 + 4257.000 88.830 2.681 + 4257.500 90.352 2.693 + 4258.000 92.751 2.697 + 4258.500 95.613 2.688 + 4259.000 98.576 2.673 + 4259.500 103.301 2.662 + 4260.000 109.001 2.658 + 4260.500 110.331 2.658 + 4261.000 107.561 2.653 + 4261.500 106.136 2.648 + 4262.000 104.995 2.642 + 4262.500 103.796 2.646 + 4263.000 105.711 2.661 + 4263.500 106.356 2.672 + 4264.000 105.745 2.676 + 4264.500 104.285 2.657 + 4265.000 103.705 2.646 + 4265.500 105.754 2.634 + 4266.000 106.355 2.634 + 4266.500 109.404 2.628 + 4267.000 108.893 2.604 + 4267.500 106.719 2.597 + 4268.000 102.547 2.602 + 4268.500 100.956 2.629 + 4269.000 102.680 2.648 + 4269.500 105.731 2.644 + 4270.000 107.261 2.644 + 4270.500 105.440 2.651 + 4271.000 100.038 2.657 + 4271.500 98.973 2.669 + 4272.000 98.832 2.673 + 4272.500 98.928 2.660 + 4273.000 102.019 2.649 + 4273.500 102.793 2.622 + 4274.000 101.910 2.620 + 4274.500 99.575 2.626 + 4275.000 99.765 2.607 + 4275.500 100.567 2.591 + 4276.000 99.645 2.598 + 4276.500 99.714 2.607 + 4277.000 99.812 2.637 + 4277.500 103.650 2.669 + 4278.000 104.638 2.697 + 4278.500 106.050 2.672 + 4279.000 105.638 2.648 + 4279.500 103.517 2.631 + 4280.000 103.639 2.636 + 4280.500 103.448 2.635 + 4281.000 104.192 2.615 + 4281.500 106.663 2.593 + 4282.000 109.249 2.605 + 4282.500 109.136 2.655 + 4283.000 107.470 2.666 + 4283.500 110.511 2.746 + 4284.000 115.093 2.732 + 4284.500 119.804 2.673 + 4285.000 119.532 2.620 + 4285.500 115.485 2.555 + 4286.000 113.353 2.546 + 4286.500 96.436 2.570 + 4287.000 91.231 2.598 + 4287.500 84.603 2.615 + 4288.000 80.876 2.635 + 4288.500 85.658 2.655 + 4289.000 95.368 2.668 + 4289.500 99.555 2.677 + 4290.000 101.925 2.675 + 4290.500 103.397 2.665 + 4291.000 102.593 2.647 + 4291.500 102.959 2.633 + 4292.000 102.049 2.623 + 4292.500 101.314 2.606 + 4293.000 95.346 2.613 + 4293.500 93.422 2.626 + 4294.000 93.809 2.640 + 4294.500 95.044 2.659 + 4295.000 98.709 2.708 + 4295.500 99.476 2.732 + 4296.000 99.905 2.692 + 4296.500 95.404 2.583 + 4297.000 93.201 2.590 + 4297.500 90.842 2.618 + 4298.000 91.246 2.652 + 4298.500 91.064 2.682 + 4299.000 91.744 2.678 + 4299.500 92.968 2.682 + 4300.000 97.528 2.700 + 4300.500 98.954 2.769 + 4301.000 99.337 2.836 + 4301.500 99.398 2.846 + 4302.000 100.268 2.826 + 4302.500 100.320 2.742 + 4303.000 98.689 2.691 + 4303.500 93.760 2.659 + 4304.000 90.766 2.692 + 4304.500 92.695 2.725 + 4305.000 93.341 2.749 + 4305.500 93.325 2.714 + 4306.000 94.731 2.688 + 4306.500 90.923 2.596 + 4307.000 83.870 2.642 + 4307.500 79.022 2.632 + 4308.000 79.308 2.638 + 4308.500 79.201 2.475 + 4309.000 80.176 2.477 + 4309.500 84.334 2.570 + 4310.000 92.459 2.626 + 4310.500 108.757 2.374 + 4311.000 113.857 2.303 + 4311.500 112.838 2.228 + 4312.000 105.013 2.354 + 4312.500 92.127 2.462 + 4313.000 87.327 2.456 + 4313.500 89.471 2.242 + 4314.000 91.528 2.148 + 4314.500 93.714 2.060 + 4315.000 90.957 2.085 + 4315.500 86.659 2.358 + 4316.000 73.286 2.344 + 4316.500 71.591 2.711 + 4317.000 73.553 2.703 + 4317.500 74.273 2.650 + 4318.000 77.538 2.593 + 4318.500 80.937 2.519 + 4319.000 89.002 2.470 + 4319.500 93.515 2.452 + 4320.000 89.298 2.436 + 4320.500 74.749 2.508 + 4321.000 69.432 2.584 + 4321.500 64.284 2.610 + 4322.000 68.502 2.642 + 4322.500 78.922 2.675 + 4323.000 80.148 2.698 + 4323.500 80.442 2.691 + 4324.000 84.537 2.677 + 4324.500 94.622 2.648 + 4325.000 96.806 2.634 + 4325.500 97.677 2.568 + 4326.000 100.792 2.525 + 4326.500 109.464 2.148 + 4327.000 117.200 1.999 + 4327.500 113.939 2.070 + 4328.000 107.588 2.146 + 4328.500 95.953 2.421 + 4329.000 98.361 2.492 + 4329.500 99.573 2.573 + 4330.000 97.622 2.692 + 4330.500 125.736 2.732 + 4331.000 134.052 2.709 + 4331.500 131.857 2.597 + 4332.000 130.864 2.511 + 4332.500 123.755 2.530 + 4333.000 119.482 2.587 + 4333.500 113.887 2.678 + 4334.000 111.104 2.797 + 4334.500 110.384 2.764 + 4335.000 112.237 2.610 + 4335.500 116.680 2.495 + 4336.000 114.643 2.289 + 4336.500 111.963 2.412 + 4337.000 112.711 2.552 + 4337.500 117.587 2.618 + 4338.000 119.663 2.593 + 4338.500 120.750 2.385 + 4339.000 123.171 2.332 + 4339.500 122.849 2.342 + 4340.000 125.952 2.505 + 4340.500 128.130 2.597 + 4341.000 129.849 2.550 + 4341.500 129.454 2.491 + 4342.000 129.178 2.430 + 4342.500 125.073 2.277 + 4343.000 121.870 2.246 + 4343.500 118.033 2.274 + 4344.000 112.378 2.348 + 4344.500 101.572 2.583 + 4345.000 98.669 2.676 + 4345.500 100.138 2.697 + 4346.000 99.415 2.666 + 4346.500 115.165 2.409 + 4347.000 121.932 2.347 + 4347.500 126.184 2.253 + 4348.000 125.436 2.152 + 4348.500 123.652 2.146 + 4349.000 123.449 2.336 + 4349.500 123.455 2.501 + 4350.000 124.586 2.597 + 4350.500 121.176 2.452 + 4351.000 116.752 2.505 + 4351.500 114.442 2.576 + 4352.000 112.228 2.665 + 4352.500 110.655 2.730 + 4353.000 107.001 2.726 + 4353.500 104.807 2.720 + 4354.000 104.380 2.661 + 4354.500 106.388 2.634 + 4355.000 109.081 2.621 + 4355.500 112.428 2.538 + 4356.000 115.051 2.454 + 4356.500 116.477 2.346 + 4357.000 116.317 2.407 + 4357.500 116.299 2.648 + 4358.000 117.035 2.732 + 4358.500 116.881 2.651 + 4359.000 116.860 2.590 + 4359.500 114.660 2.527 + 4360.000 112.804 2.502 + 4360.500 109.018 2.573 + 4361.000 107.673 2.648 + 4361.500 109.717 2.729 + 4362.000 113.275 2.767 + 4362.500 113.651 2.693 + 4363.000 111.312 2.550 + 4363.500 109.393 2.542 + 4364.000 108.522 2.554 + 4364.500 116.963 2.520 + 4365.000 120.058 2.500 + 4365.500 124.620 2.464 + 4366.000 124.377 2.469 + 4366.500 123.288 2.441 + 4367.000 119.629 2.360 + 4367.500 118.091 2.452 + 4368.000 100.759 2.498 + 4368.500 92.512 2.467 + 4369.000 91.607 2.361 + 4369.500 93.166 2.438 + 4370.000 94.161 2.663 + 4370.500 90.762 2.649 + 4371.000 88.673 2.559 + 4371.500 93.405 2.573 + 4372.000 99.089 2.629 + 4372.500 107.064 2.682 + 4373.000 108.307 2.692 + 4373.500 113.245 2.681 + 4374.000 114.939 2.681 + 4374.500 118.191 2.647 + 4375.000 116.306 2.606 + 4375.500 112.022 2.624 + 4376.000 106.001 2.615 + 4376.500 96.850 2.573 + 4377.000 95.876 2.586 + 4377.500 99.416 2.640 + 4378.000 106.746 2.803 + 4378.500 109.425 2.741 + 4379.000 110.853 2.549 + 4379.500 109.839 2.450 + 4380.000 109.755 2.421 + 4380.500 106.333 2.434 + 4381.000 105.270 2.473 + 4381.500 107.455 2.528 + 4382.000 112.227 2.599 + 4382.500 118.178 2.587 + 4383.000 119.069 2.572 + 4383.500 118.782 2.547 + 4384.000 117.435 2.520 + 4384.500 115.513 2.380 + 4385.000 114.463 2.422 + 4385.500 114.410 2.506 + 4386.000 112.069 2.628 + 4386.500 110.669 2.769 + 4387.000 109.965 2.762 + 4387.500 109.764 2.747 + 4388.000 108.379 2.698 + 4388.500 99.345 2.617 + 4389.000 95.533 2.575 + 4389.500 95.739 2.551 + 4390.000 96.129 2.563 + 4390.500 102.548 2.511 + 4391.000 108.822 2.504 + 4391.500 125.727 2.380 + 4392.000 127.005 2.394 + 4392.500 128.238 2.464 + 4393.000 126.993 2.657 + 4393.500 122.993 2.709 + 4394.000 113.256 2.749 + 4394.500 98.949 2.670 + 4395.000 95.847 2.540 + 4395.500 93.275 2.480 + 4396.000 90.830 2.502 + 4396.500 81.657 2.612 + 4397.000 78.950 2.610 + 4397.500 87.959 2.617 + 4398.000 102.226 2.630 + 4398.500 116.932 2.699 + 4399.000 119.581 2.719 + 4399.500 125.233 2.754 + 4400.000 127.556 2.791 + 4400.500 129.490 2.829 + 4401.000 128.908 2.799 + 4401.500 127.326 2.733 + 4402.000 126.379 2.628 + 4402.500 120.873 2.415 + 4403.000 116.606 2.309 + 4403.500 117.405 2.301 + 4404.000 120.501 2.244 + 4404.500 123.436 2.175 + 4405.000 124.948 2.189 + 4405.500 124.869 2.274 + 4406.000 124.702 2.297 + 4406.500 124.026 2.779 + 4407.000 122.491 2.789 + 4407.500 122.475 2.735 + 4408.000 120.394 2.705 + 4408.500 116.303 2.552 + 4409.000 106.050 2.456 + 4409.500 102.216 2.446 + 4410.000 97.109 2.438 + 4410.500 99.716 2.466 + 4411.000 108.141 2.699 + 4411.500 112.100 2.662 + 4412.000 119.068 2.587 + 4412.500 121.282 2.526 + 4413.000 122.464 2.550 + 4413.500 113.429 2.578 + 4414.000 115.181 2.559 + 4414.500 87.617 2.552 + 4415.000 81.233 2.650 + 4415.500 71.773 2.678 + 4416.000 73.964 2.686 + 4416.500 81.950 2.680 + 4417.000 97.347 2.682 + 4417.500 100.154 2.692 + 4418.000 110.449 2.700 + 4418.500 120.141 2.703 + 4419.000 125.779 2.697 + 4419.500 128.863 2.658 + 4420.000 129.376 2.608 + 4420.500 129.161 2.496 + 4421.000 127.667 2.366 + 4421.500 125.522 2.352 + 4422.000 123.808 2.360 + 4422.500 120.353 2.659 + 4423.000 117.711 2.637 + 4423.500 113.696 2.646 + 4424.000 112.978 2.616 + 4424.500 115.118 2.617 + 4425.000 115.420 2.661 + 4425.500 114.088 2.682 + 4426.000 112.248 2.713 + 4426.500 112.118 2.695 + 4427.000 112.413 2.625 + 4427.500 108.652 2.566 + 4428.000 102.700 2.518 + 4428.500 98.264 2.434 + 4429.000 98.656 2.321 + 4429.500 99.474 2.234 + 4430.000 98.672 2.223 + 4430.500 117.192 2.581 + 4431.000 115.470 2.662 + 4431.500 115.135 2.826 + 4432.000 113.940 2.826 + 4432.500 115.021 2.741 + 4433.000 117.915 2.625 + 4433.500 119.910 2.568 + 4434.000 123.939 2.603 + 4434.500 125.928 2.664 + 4435.000 123.483 2.693 + 4435.500 117.851 2.677 + 4436.000 111.345 2.632 + 4436.500 106.274 2.573 + 4437.000 98.789 2.582 + 4437.500 96.236 2.639 + 4438.000 97.332 2.703 + 4438.500 102.976 2.696 + 4439.000 107.470 2.651 + 4439.500 111.304 2.524 + 4440.000 113.134 2.471 + 4440.500 114.888 2.321 + 4441.000 113.708 2.346 + 4441.500 114.029 2.501 + 4442.000 108.186 2.677 + 4442.500 107.519 2.783 + 4443.000 107.749 2.895 + 4443.500 108.247 2.839 + 4444.000 107.689 2.799 + 4444.500 100.501 2.560 + 4445.000 97.380 2.505 + 4445.500 102.675 2.493 + 4446.000 103.284 2.495 + 4446.500 117.641 2.528 + 4447.000 122.919 2.571 + 4447.500 125.095 2.655 + 4448.000 125.474 2.695 + 4448.500 127.891 2.552 + 4449.000 129.348 2.599 + 4449.500 131.163 2.256 + 4450.000 131.868 2.126 + 4450.500 130.117 2.083 + 4451.000 128.201 2.283 + 4451.500 126.351 2.458 + 4452.000 125.254 2.750 + 4452.500 125.440 2.777 + 4453.000 125.609 2.775 + 4453.500 124.793 2.715 + 4454.000 121.996 2.674 + 4454.500 119.582 2.621 + 4455.000 116.774 2.581 + 4455.500 117.777 2.577 + 4456.000 118.624 2.574 + 4456.500 119.997 2.636 + 4457.000 119.609 2.650 + 4457.500 117.421 2.641 + 4458.000 117.121 2.637 + 4458.500 119.537 2.649 + 4459.000 121.229 2.661 + 4459.500 121.667 2.670 + 4460.000 121.324 2.674 + 4460.500 117.716 2.679 + 4461.000 115.770 2.683 + 4461.500 112.819 2.683 + 4462.000 110.475 2.682 + 4462.500 102.802 2.675 + 4463.000 100.879 2.667 + 4463.500 103.170 2.692 + 4464.000 108.712 2.729 + 4464.500 118.405 2.806 + 4465.000 122.378 2.751 + 4465.500 125.375 2.708 + 4466.000 125.551 2.669 + 4466.500 124.156 2.531 + 4467.000 123.950 2.451 + 4467.500 124.845 2.385 + 4468.000 125.969 2.552 + 4468.500 127.348 2.301 + 4469.000 126.605 2.332 + 4469.500 122.695 2.423 + 4470.000 117.306 2.491 + 4470.500 112.349 2.593 + 4471.000 108.470 2.601 + 4471.500 107.566 2.623 + 4472.000 108.293 2.646 + 4472.500 108.136 2.591 + 4473.000 107.317 2.534 + 4473.500 107.424 2.544 + 4474.000 106.024 2.599 + 4474.500 105.201 2.629 + 4475.000 105.972 2.618 + 4475.500 108.299 2.628 + 4476.000 110.853 2.644 + 4476.500 113.532 2.757 + 4477.000 114.626 2.778 + 4477.500 117.173 2.759 + 4478.000 119.545 2.729 + 4478.500 121.719 2.681 + 4479.000 122.820 2.670 + 4479.500 121.457 2.677 + 4480.000 120.160 2.548 + 4480.500 118.940 2.582 + 4481.000 121.011 2.572 + 4481.500 120.998 2.659 + 4482.000 119.542 2.625 + 4482.500 108.724 2.538 + 4483.000 106.561 2.526 + 4483.500 105.907 2.566 + 4484.000 107.805 2.624 + 4484.500 112.658 2.566 + 4485.000 114.774 2.401 + 4485.500 115.533 2.353 + 4486.000 115.288 2.396 + 4486.500 119.771 2.555 + 4487.000 121.821 2.595 + 4487.500 123.488 2.600 + 4488.000 122.388 2.604 + 4488.500 119.808 2.644 + 4489.000 117.020 2.691 + 4489.500 111.007 2.686 + 4490.000 108.866 2.669 + 4490.500 106.635 2.644 + 4491.000 110.247 2.636 + 4491.500 114.469 2.644 + 4492.000 119.511 2.616 + 4492.500 122.507 2.589 + 4493.000 123.891 2.625 + 4493.500 124.203 2.722 + 4494.000 125.031 2.763 + 4494.500 126.125 2.754 + 4495.000 125.390 2.697 + 4495.500 124.305 2.676 + 4496.000 123.180 2.653 + 4496.500 120.889 2.663 + 4497.000 120.358 2.676 + 4497.500 113.780 2.663 + 4498.000 110.563 2.542 + 4498.500 104.971 2.385 + 4499.000 105.812 2.399 + 4499.500 107.213 2.420 + 4500.000 111.727 2.482 + 4500.500 116.495 2.467 + 4501.000 121.208 2.473 + 4501.500 123.442 2.481 + 4502.000 125.011 2.475 + 4502.500 125.113 2.456 + 4503.000 120.047 2.497 + 4503.500 117.192 2.573 + 4504.000 112.645 2.695 + 4504.500 113.110 2.754 + 4505.000 113.593 2.711 + 4505.500 113.707 2.654 + 4506.000 114.334 2.636 + 4506.500 115.707 2.630 + 4507.000 117.445 2.628 + 4507.500 119.852 2.661 + 4508.000 120.610 2.686 + 4508.500 121.568 2.718 + 4509.000 121.072 2.640 + 4509.500 117.950 2.528 + 4510.000 115.031 2.481 + 4510.500 114.939 2.493 + 4511.000 116.495 2.628 + 4511.500 118.702 2.727 + 4512.000 115.774 2.721 + 4512.500 112.055 2.702 + 4513.000 112.297 2.648 + 4513.500 112.703 2.683 + 4514.000 113.977 2.803 + 4514.500 114.985 2.794 + 4515.000 115.314 2.647 + 4515.500 113.839 2.617 + 4516.000 113.883 2.686 + 4516.500 112.858 2.672 + 4517.000 110.372 2.648 + 4517.500 108.394 2.410 + 4518.000 108.151 2.366 + 4518.500 112.299 2.434 + 4519.000 117.405 2.535 + 4519.500 121.036 2.612 + 4520.000 122.496 2.637 + 4520.500 120.978 2.603 + 4521.000 120.357 2.540 + 4521.500 119.433 2.548 + 4522.000 119.339 2.579 + 4522.500 119.308 2.691 + 4523.000 120.398 2.673 + 4523.500 119.538 2.650 + 4524.000 118.662 2.628 + 4524.500 111.880 2.624 + 4525.000 112.268 2.612 + 4525.500 111.414 2.571 + 4526.000 110.234 2.559 + 4526.500 110.553 2.588 + 4527.000 109.781 2.656 + 4527.500 109.538 2.699 + 4528.000 110.667 2.699 + 4528.500 114.069 2.725 + 4529.000 118.766 2.726 + 4529.500 120.499 2.700 + 4530.000 121.043 2.693 + 4530.500 117.244 2.613 + 4531.000 114.482 2.634 + 4531.500 113.730 2.659 + 4532.000 114.025 2.687 + 4532.500 115.931 2.729 + 4533.000 118.044 2.715 + 4533.500 118.552 2.669 + 4534.000 118.561 2.553 + 4534.500 117.138 2.499 + 4535.000 115.551 2.539 + 4535.500 114.660 2.579 + 4536.000 114.436 2.591 + 4536.500 113.915 2.601 + 4537.000 116.416 2.623 + 4537.500 118.476 2.629 + 4538.000 118.786 2.598 + 4538.500 119.223 2.561 + 4539.000 119.301 2.574 + 4539.500 119.178 2.610 + 4540.000 117.993 2.639 + 4540.500 116.732 2.655 + 4541.000 114.811 2.684 + 4541.500 112.891 2.700 + 4542.000 112.536 2.695 + 4542.500 114.589 2.680 + 4543.000 114.805 2.652 + 4543.500 111.616 2.640 + 4544.000 106.305 2.634 + 4544.500 107.160 2.655 + 4545.000 108.661 2.687 + 4545.500 107.820 2.731 + 4546.000 104.302 2.743 + 4546.500 98.619 2.718 + 4547.000 97.029 2.704 + 4547.500 101.600 2.713 + 4548.000 102.056 2.742 + 4548.500 107.791 2.801 + 4549.000 110.549 2.709 + 4549.500 113.213 2.564 + 4550.000 113.510 2.315 + 4550.500 112.738 2.156 + 4551.000 111.180 2.297 + 4551.500 108.938 2.437 + 4552.000 102.409 2.546 + 4552.500 98.472 2.446 + 4553.000 92.938 2.521 + 4553.500 88.695 2.572 + 4554.000 93.609 2.668 + 4554.500 100.272 2.789 + 4555.000 108.515 2.775 + 4555.500 115.905 2.705 + 4556.000 120.972 2.615 + 4556.500 120.770 2.591 + 4557.000 120.442 2.501 + 4557.500 119.164 2.385 + 4558.000 114.527 2.146 + 4558.500 110.294 2.251 + 4559.000 110.636 2.474 + 4559.500 111.357 2.623 + 4560.000 111.327 2.675 + 4560.500 110.899 2.562 + 4561.000 107.918 2.552 + 4561.500 108.190 2.556 + 4562.000 107.324 2.607 + 4562.500 105.942 2.672 + 4563.000 105.950 2.685 + 4563.500 105.897 2.670 + 4564.000 106.469 2.675 + 4564.500 111.316 2.560 + 4565.000 114.004 2.566 + 4565.500 117.716 2.558 + 4566.000 118.946 2.660 + 4566.500 114.625 2.631 + 4567.000 113.637 2.507 + 4567.500 109.507 2.424 + 4568.000 109.978 2.322 + 4568.500 108.392 2.331 + 4569.000 108.385 2.446 + 4569.500 108.175 2.523 + 4570.000 107.981 2.600 + 4570.500 106.412 2.670 + 4571.000 105.826 2.652 + 4571.500 107.299 2.586 + 4572.000 109.137 2.483 + 4572.500 118.344 2.489 + 4573.000 118.952 2.610 + 4573.500 120.492 2.681 + 4574.000 118.854 2.710 + 4574.500 116.952 2.631 + 4575.000 113.067 2.518 + 4575.500 112.982 2.572 + 4576.000 114.278 2.643 + 4576.500 115.963 2.639 + 4577.000 114.597 2.623 + 4577.500 110.332 2.601 + 4578.000 106.928 2.626 + 4578.500 105.880 2.734 + 4579.000 108.851 2.748 + 4579.500 112.063 2.728 + 4580.000 114.260 2.664 + 4580.500 116.067 2.666 + 4581.000 116.139 2.722 + 4581.500 116.159 2.701 + 4582.000 116.124 2.719 + 4582.500 115.611 2.475 + 4583.000 112.564 2.414 + 4583.500 112.205 2.445 + 4584.000 112.275 2.510 + 4584.500 113.411 2.618 + 4585.000 114.881 2.606 + 4585.500 117.388 2.612 + 4586.000 118.579 2.628 + 4586.500 118.527 2.631 + 4587.000 118.480 2.561 + 4587.500 118.481 2.473 + 4588.000 116.997 2.385 + 4588.500 114.592 2.345 + 4589.000 113.741 2.466 + 4589.500 113.810 2.675 + 4590.000 112.975 2.697 + 4590.500 110.954 2.651 + 4591.000 109.212 2.673 + 4591.500 108.045 2.722 + 4592.000 108.723 2.706 + 4592.500 106.686 2.582 + 4593.000 106.956 2.584 + 4593.500 106.940 2.604 + 4594.000 107.737 2.626 + 4594.500 108.289 2.656 + 4595.000 109.048 2.672 + 4595.500 111.357 2.685 + 4596.000 113.879 2.675 + 4596.500 118.005 2.626 + 4597.000 118.323 2.608 + 4597.500 115.681 2.593 + 4598.000 112.964 2.595 + 4598.500 109.683 2.609 + 4599.000 109.704 2.616 + 4599.500 109.242 2.619 + 4600.000 108.938 2.622 + 4600.500 109.004 2.628 + 4601.000 110.127 2.632 + 4601.500 111.654 2.616 + 4602.000 117.955 2.553 + 4602.500 120.166 2.410 + 4603.000 122.038 2.427 + 4603.500 119.224 2.514 + 4604.000 118.788 2.582 + 4604.500 117.087 2.662 + 4605.000 118.168 2.650 + 4605.500 116.405 2.633 + 4606.000 115.234 2.624 + 4606.500 113.869 2.638 + 4607.000 114.284 2.650 + 4607.500 115.733 2.650 + 4608.000 116.246 2.639 + 4608.500 113.207 2.644 + 4609.000 109.789 2.644 + 4609.500 107.771 2.552 + 4610.000 106.373 2.498 + 4610.500 117.413 2.368 + 4611.000 119.893 2.386 + 4611.500 121.769 2.553 + 4612.000 122.137 2.656 + 4612.500 121.644 2.678 + 4613.000 119.123 2.671 + 4613.500 119.394 2.652 + 4614.000 119.178 2.664 + 4614.500 120.177 2.505 + 4615.000 119.936 2.426 + 4615.500 119.100 2.404 + 4616.000 115.102 2.412 + 4616.500 110.657 2.525 + 4617.000 106.985 2.619 + 4617.500 106.493 2.609 + 4618.000 109.229 2.319 + 4618.500 114.289 2.232 + 4619.000 118.376 2.136 + 4619.500 121.481 2.372 + 4620.000 125.063 2.617 + 4620.500 127.949 2.619 + 4621.000 127.794 2.625 + 4621.500 127.119 2.648 + 4622.000 127.223 2.660 + 4622.500 125.217 2.609 + 4623.000 122.548 2.507 + 4623.500 118.945 2.399 + 4624.000 116.192 2.268 + 4624.500 112.145 2.307 + 4625.000 110.272 2.352 + 4625.500 106.993 2.397 + 4626.000 97.608 2.423 + 4626.500 91.771 2.328 + 4627.000 98.302 2.287 + 4627.500 105.993 2.246 + 4628.000 108.062 2.421 + 4628.500 109.046 2.526 + 4629.000 107.742 2.503 + 4629.500 107.401 2.467 + 4630.000 103.929 2.474 + 4630.500 100.932 2.528 + 4631.000 97.092 2.538 + 4631.500 93.309 2.597 + 4632.000 102.275 2.735 + 4632.500 114.436 2.811 + 4633.000 119.649 2.811 + 4633.500 124.579 2.778 + 4634.000 124.964 2.678 + 4634.500 117.956 2.559 + 4635.000 114.686 2.575 + 4635.500 111.824 2.605 + 4636.000 113.642 2.566 + 4636.500 112.564 2.478 + 4637.000 111.240 2.392 + 4637.500 108.976 2.472 + 4638.000 107.702 2.579 + 4638.500 108.975 2.750 + 4639.000 111.177 2.694 + 4639.500 111.311 2.679 + 4640.000 111.815 2.647 + 4640.500 110.593 2.674 + 4641.000 112.924 2.634 + 4641.500 114.777 2.551 + 4642.000 116.217 2.439 + 4642.500 116.179 2.323 + 4643.000 113.366 2.383 + 4643.500 110.360 2.561 + 4644.000 106.041 2.638 + 4644.500 104.199 2.619 + 4645.000 104.937 2.553 + 4645.500 109.929 2.493 + 4646.000 114.491 2.426 + 4646.500 119.393 2.546 + 4647.000 120.887 2.560 + 4647.500 121.305 2.558 + 4648.000 121.355 2.407 + 4648.500 120.493 2.246 + 4649.000 118.502 2.332 + 4649.500 115.556 2.388 + 4650.000 111.032 2.403 + 4650.500 109.318 2.201 + 4651.000 111.506 2.238 + 4651.500 113.640 2.487 + 4652.000 116.097 2.732 + 4652.500 116.322 2.687 + 4653.000 114.841 2.646 + 4653.500 115.177 2.656 + 4654.000 119.301 2.681 + 4654.500 119.013 2.645 + 4655.000 120.637 2.625 + 4655.500 119.759 2.638 + 4656.000 120.159 2.665 + 4656.500 120.017 2.551 + 4657.000 116.868 2.504 + 4657.500 110.514 2.422 + 4658.000 107.149 2.427 + 4658.500 103.419 2.499 + 4659.000 101.723 2.565 + 4659.500 102.827 2.642 + 4660.000 105.379 2.708 + 4660.500 106.704 2.664 + 4661.000 107.851 2.492 + 4661.500 108.988 2.372 + 4662.000 110.636 2.354 + 4662.500 112.780 2.504 + 4663.000 114.755 2.601 + 4663.500 116.788 2.586 + 4664.000 118.977 2.506 + 4664.500 120.172 2.368 + 4665.000 120.047 2.287 + 4665.500 117.541 2.397 + 4666.000 114.526 2.653 + 4666.500 112.439 2.732 + 4667.000 112.298 2.668 + 4667.500 113.185 2.519 + 4668.000 116.813 2.470 + 4668.500 115.217 2.470 + 4669.000 114.427 2.638 + 4669.500 112.848 2.670 + 4670.000 110.879 2.660 + 4670.500 110.644 2.485 + 4671.000 111.015 2.446 + 4671.500 113.100 2.572 + 4672.000 113.872 2.644 + 4672.500 114.875 2.577 + 4673.000 115.807 2.562 + 4673.500 116.089 2.456 + 4674.000 114.520 2.444 + 4674.500 113.274 2.617 + 4675.000 113.312 2.752 + 4675.500 110.068 2.746 + 4676.000 108.260 2.730 + 4676.500 106.652 2.595 + 4677.000 105.300 2.541 + 4677.500 106.235 2.460 + 4678.000 106.136 2.392 + 4678.500 107.566 2.414 + 4679.000 110.862 2.492 + 4679.500 116.219 2.481 + 4680.000 120.051 2.445 + 4680.500 121.057 2.479 + 4681.000 119.700 2.519 + 4681.500 118.053 2.604 + 4682.000 115.580 2.599 + 4682.500 115.226 2.583 + 4683.000 114.312 2.597 + 4683.500 113.208 2.638 + 4684.000 109.979 2.668 + 4684.500 107.068 2.653 + 4685.000 104.769 2.639 + 4685.500 105.819 2.651 + 4686.000 107.262 2.749 + 4686.500 112.734 2.806 + 4687.000 114.600 2.824 + 4687.500 115.300 2.806 + 4688.000 114.373 2.746 + 4688.500 113.161 2.621 + 4689.000 112.448 2.607 + 4689.500 112.146 2.643 + 4690.000 112.048 2.662 + 4690.500 109.860 2.536 + 4691.000 109.367 2.480 + 4691.500 106.706 2.385 + 4692.000 104.644 2.504 + 4692.500 102.064 2.499 + 4693.000 104.662 2.540 + 4693.500 104.862 2.533 + 4694.000 107.209 2.558 + 4694.500 107.524 2.564 + 4695.000 107.618 2.537 + 4695.500 109.034 2.543 + 4696.000 109.010 2.572 + 4696.500 109.131 2.648 + 4697.000 108.938 2.656 + 4697.500 109.709 2.683 + 4698.000 110.019 2.670 + 4698.500 110.617 2.619 + 4699.000 111.582 2.593 + 4699.500 112.272 2.587 + 4700.000 111.676 2.660 + 4700.500 110.745 2.734 + 4701.000 109.881 2.743 + 4701.500 110.058 2.653 + 4702.000 108.726 2.635 + 4702.500 111.252 2.570 + 4703.000 114.215 2.619 + 4703.500 118.484 2.741 + 4704.000 121.252 2.741 + 4704.500 123.028 2.664 + 4705.000 119.822 2.625 + 4705.500 115.996 2.623 + 4706.000 114.045 2.624 + 4706.500 111.528 2.608 + 4707.000 112.365 2.595 + 4707.500 112.145 2.540 + 4708.000 109.662 2.439 + 4708.500 106.366 2.391 + 4709.000 104.447 2.396 + 4709.500 103.745 2.474 + 4710.000 103.215 2.617 + 4710.500 104.090 2.594 + 4711.000 105.748 2.527 + 4711.500 108.394 2.532 + 4712.000 110.675 2.525 + 4712.500 114.177 2.599 + 4713.000 113.704 2.648 + 4713.500 113.085 2.601 + 4714.000 111.320 2.583 + 4714.500 108.818 2.572 + 4715.000 106.415 2.586 + 4715.500 105.031 2.604 + 4716.000 105.215 2.641 + 4716.500 106.552 2.659 + 4717.000 107.297 2.650 + 4717.500 107.394 2.634 + 4718.000 108.256 2.640 + 4718.500 108.089 2.654 + 4719.000 111.189 2.621 + 4719.500 111.482 2.602 + 4720.000 114.422 2.673 + 4720.500 112.683 2.708 + 4721.000 108.734 2.761 + 4721.500 105.021 2.646 + 4722.000 101.241 2.588 + 4722.500 104.023 2.600 + 4723.000 106.861 2.642 + 4723.500 111.294 2.597 + 4724.000 114.930 2.562 + 4724.500 116.356 2.469 + 4725.000 114.865 2.580 + 4725.500 111.948 2.635 + 4726.000 112.000 2.671 + 4726.500 112.964 2.635 + 4727.000 115.296 2.520 + 4727.500 117.067 2.439 + 4728.000 117.500 2.445 + 4728.500 118.036 2.204 + 4729.000 119.201 2.249 + 4729.500 119.279 2.340 + 4730.000 119.187 2.379 + 4730.500 116.965 2.605 + 4731.000 115.070 2.592 + 4731.500 112.682 2.604 + 4732.000 113.612 2.649 + 4732.500 115.089 2.609 + 4733.000 117.329 2.502 + 4733.500 119.048 2.447 + 4734.000 119.105 2.408 + 4734.500 118.328 2.382 + 4735.000 117.380 2.517 + 4735.500 114.241 2.566 + 4736.000 112.856 2.589 + 4736.500 113.766 2.677 + 4737.000 117.211 2.664 + 4737.500 120.703 2.669 + 4738.000 120.761 2.685 + 4738.500 120.744 2.677 + 4739.000 115.625 2.633 + 4739.500 116.241 2.564 + 4740.000 118.636 2.572 + 4740.500 120.835 2.610 + 4741.000 119.521 2.598 + 4741.500 113.373 2.488 + 4742.000 109.087 2.498 + 4742.500 102.552 2.627 + 4743.000 102.675 2.722 + 4743.500 105.185 2.734 + 4744.000 108.339 2.673 + 4744.500 111.497 2.601 + 4745.000 117.932 2.562 + 4745.500 120.063 2.482 + 4746.000 122.667 2.437 + 4746.500 121.774 2.443 + 4747.000 120.403 2.585 + 4747.500 115.071 2.628 + 4748.000 111.099 2.662 + 4748.500 110.227 2.623 + 4749.000 113.816 2.592 + 4749.500 116.919 2.575 + 4750.000 118.865 2.570 + 4750.500 120.379 2.599 + 4751.000 120.052 2.615 + 4751.500 119.349 2.617 + 4752.000 118.667 2.613 + 4752.500 117.741 2.619 + 4753.000 114.638 2.610 + 4753.500 112.323 2.517 + 4754.000 110.311 2.325 + 4754.500 114.107 2.265 + 4755.000 116.867 2.378 + 4755.500 117.692 2.543 + 4756.000 117.254 2.617 + 4756.500 111.109 2.605 + 4757.000 109.134 2.511 + 4757.500 99.513 2.423 + 4758.000 101.113 2.311 + 4758.500 100.974 2.389 + 4759.000 107.823 2.458 + 4759.500 108.989 2.530 + 4760.000 108.466 2.542 + 4760.500 104.482 2.513 + 4761.000 103.815 2.560 + 4761.500 109.416 2.607 + 4762.000 112.227 2.658 + 4762.500 113.174 2.505 + 4763.000 109.759 2.272 + 4763.500 104.339 2.162 + 4764.000 100.408 2.187 + 4764.500 101.940 2.387 + 4765.000 106.142 2.403 + 4765.500 108.085 2.467 + 4766.000 108.838 2.480 + 4766.500 108.871 2.548 + 4767.000 106.577 2.561 + 4767.500 106.005 2.611 + 4768.000 107.316 2.654 + 4768.500 110.233 2.679 + 4769.000 113.563 2.660 + 4769.500 117.034 2.642 + 4770.000 118.760 2.607 + 4770.500 117.529 2.670 + 4771.000 116.400 2.683 + 4771.500 114.973 2.643 + 4772.000 113.473 2.553 + 4772.500 112.895 2.488 + 4773.000 111.474 2.519 + 4773.500 109.764 2.605 + 4774.000 107.964 2.630 + 4774.500 103.344 2.651 + 4775.000 101.755 2.673 + 4775.500 101.608 2.691 + 4776.000 103.614 2.700 + 4776.500 105.584 2.710 + 4777.000 109.333 2.728 + 4777.500 109.905 2.772 + 4778.000 109.176 2.767 + 4778.500 107.086 2.717 + 4779.000 107.508 2.704 + 4779.500 108.257 2.694 + 4780.000 107.804 2.702 + 4780.500 103.880 2.716 + 4781.000 103.534 2.712 + 4781.500 105.195 2.678 + 4782.000 106.580 2.633 + 4782.500 111.230 2.581 + 4783.000 111.650 2.586 + 4783.500 110.742 2.637 + 4784.000 110.647 2.628 + 4784.500 110.631 2.620 + 4785.000 111.062 2.592 + 4785.500 113.233 2.581 + 4786.000 114.600 2.497 + 4786.500 115.548 2.510 + 4787.000 114.968 2.561 + 4787.500 115.404 2.632 + 4788.000 116.134 2.608 + 4788.500 116.998 2.456 + 4789.000 115.153 2.434 + 4789.500 114.865 2.439 + 4790.000 113.841 2.472 + 4790.500 111.993 2.679 + 4791.000 110.803 2.672 + 4791.500 110.653 2.673 + 4792.000 109.562 2.582 + 4792.500 106.203 2.527 + 4793.000 104.100 2.488 + 4793.500 103.316 2.504 + 4794.000 108.132 2.544 + 4794.500 116.573 2.573 + 4795.000 120.218 2.550 + 4795.500 121.572 2.500 + 4796.000 120.953 2.451 + 4796.500 119.398 2.489 + 4797.000 118.797 2.508 + 4797.500 117.940 2.593 + 4798.000 116.470 2.605 + 4798.500 113.353 2.641 + 4799.000 112.887 2.662 + 4799.500 114.175 2.621 + 4800.000 115.892 2.582 + 4800.500 118.863 2.437 + 4801.000 118.041 2.478 + 4801.500 118.040 2.492 + 4802.000 118.484 2.528 + 4802.500 118.139 2.572 + 4803.000 117.649 2.557 + 4803.500 116.272 2.535 + 4804.000 116.646 2.505 + 4804.500 116.201 2.409 + 4805.000 117.186 2.419 + 4805.500 117.786 2.439 + 4806.000 117.722 2.539 + 4806.500 116.825 2.571 + 4807.000 114.709 2.511 + 4807.500 113.308 2.351 + 4808.000 113.012 2.148 + 4808.500 112.886 2.201 + 4809.000 113.621 2.232 + 4809.500 116.184 2.391 + 4810.000 118.141 2.477 + 4810.500 118.406 2.415 + 4811.000 119.085 2.377 + 4811.500 119.342 2.287 + 4812.000 119.564 2.262 + 4812.500 121.050 2.130 + 4813.000 120.359 2.206 + 4813.500 118.661 2.330 + 4814.000 117.446 2.455 + 4814.500 117.565 2.579 + 4815.000 119.309 2.632 + 4815.500 120.994 2.601 + 4816.000 121.127 2.531 + 4816.500 120.227 2.513 + 4817.000 119.026 2.436 + 4817.500 115.596 2.455 + 4818.000 115.415 2.480 + 4818.500 116.195 2.564 + 4819.000 121.115 2.624 + 4819.500 119.911 2.629 + 4820.000 117.082 2.622 + 4820.500 111.586 2.737 + 4821.000 109.028 2.729 + 4821.500 109.529 2.709 + 4822.000 110.545 2.701 + 4822.500 112.992 2.751 + 4823.000 115.739 2.766 + 4823.500 118.027 2.780 + 4824.000 118.490 2.738 + 4824.500 118.682 2.590 + 4825.000 119.575 2.590 + 4825.500 119.383 2.601 + 4826.000 118.179 2.732 + 4826.500 118.349 2.725 + 4827.000 120.964 2.737 + 4827.500 124.819 2.655 + 4828.000 126.498 2.619 + 4828.500 128.163 2.639 + 4829.000 125.535 2.687 + 4829.500 123.105 2.726 + 4830.000 123.533 2.724 + 4830.500 124.314 2.543 + 4831.000 123.355 2.505 + 4831.500 121.128 2.370 + 4832.000 117.386 2.335 + 4832.500 112.818 2.321 + 4833.000 110.238 2.345 + 4833.500 109.273 2.394 + 4834.000 109.625 2.483 + 4834.500 111.157 2.668 + 4835.000 110.759 2.612 + 4835.500 108.993 2.522 + 4836.000 106.733 2.408 + 4836.500 104.118 2.486 + 4837.000 106.243 2.615 + 4837.500 111.555 2.620 + 4838.000 114.791 2.563 + 4838.500 120.814 2.567 + 4839.000 122.334 2.586 + 4839.500 121.196 2.579 + 4840.000 118.922 2.535 + 4840.500 116.295 2.488 + 4841.000 114.687 2.501 + 4841.500 114.503 2.516 + 4842.000 117.686 2.546 + 4842.500 121.369 2.588 + 4843.000 124.190 2.576 + 4843.500 124.231 2.547 + 4844.000 119.798 2.475 + 4844.500 118.567 2.392 + 4845.000 115.301 2.339 + 4845.500 114.497 2.302 + 4846.000 115.440 2.287 + 4846.500 117.625 2.388 + 4847.000 117.871 2.465 + 4847.500 116.017 2.552 + 4848.000 116.269 2.618 + 4848.500 117.968 2.595 + 4849.000 118.235 2.552 + 4849.500 119.369 2.526 + 4850.000 119.856 2.535 + 4850.500 119.514 2.438 + 4851.000 117.122 2.395 + 4851.500 114.596 2.336 + 4852.000 112.237 2.337 + 4852.500 111.435 2.473 + 4853.000 110.803 2.592 + 4853.500 110.052 2.647 + 4854.000 109.093 2.622 + 4854.500 108.045 2.607 + 4855.000 108.843 2.631 + 4855.500 110.243 2.651 + 4856.000 114.228 2.642 + 4856.500 117.746 2.557 + 4857.000 118.468 2.478 + 4857.500 118.920 2.493 + 4858.000 117.042 2.526 + 4858.500 115.759 2.492 + 4859.000 116.889 2.467 + 4859.500 116.876 2.429 + 4860.000 116.859 2.422 + 4860.500 114.523 2.439 + 4861.000 115.324 2.534 + 4861.500 115.281 2.565 + 4862.000 115.083 2.735 + 4862.500 113.780 2.706 + 4863.000 114.788 2.600 + 4863.500 116.106 2.526 + 4864.000 117.710 2.428 + 4864.500 116.844 2.433 + 4865.000 116.064 2.582 + 4865.500 112.810 2.673 + 4866.000 112.539 2.695 + 4866.500 109.818 2.676 + 4867.000 111.531 2.657 + 4867.500 115.447 2.656 + 4868.000 118.001 2.652 + 4868.500 116.119 2.490 + 4869.000 110.014 2.446 + 4869.500 104.278 2.457 + 4870.000 101.397 2.547 + 4870.500 105.477 2.587 + 4871.000 108.144 2.595 + 4871.500 111.325 2.599 + 4872.000 111.073 2.608 + 4872.500 109.064 2.611 + 4873.000 106.870 2.584 + 4873.500 105.076 2.573 + 4874.000 104.186 2.563 + 4874.500 104.842 2.562 + 4875.000 107.112 2.547 + 4875.500 111.112 2.539 + 4876.000 113.719 2.534 + 4876.500 114.586 2.545 + 4877.000 115.139 2.558 + 4877.500 116.044 2.573 + 4878.000 117.983 2.587 + 4878.500 119.568 2.553 + 4879.000 120.172 2.531 + 4879.500 119.892 2.494 + 4880.000 118.913 2.415 + 4880.500 117.686 2.469 + 4881.000 117.063 2.464 + 4881.500 117.113 2.505 + 4882.000 118.185 2.480 + 4882.500 120.854 2.437 + 4883.000 121.875 2.354 + 4883.500 121.475 2.389 + 4884.000 120.472 2.431 + 4884.500 117.906 2.488 + 4885.000 115.027 2.479 + 4885.500 111.706 2.433 + 4886.000 108.528 2.406 + 4886.500 104.987 2.415 + 4887.000 105.911 2.451 + 4887.500 110.264 2.393 + 4888.000 114.475 2.368 + 4888.500 116.423 2.405 + 4889.000 115.395 2.460 + 4889.500 115.465 2.442 + 4890.000 114.883 2.377 + 4890.500 115.222 2.346 + 4891.000 115.136 2.380 + 4891.500 114.764 2.417 + 4892.000 114.693 2.433 + 4892.500 113.521 2.443 + 4893.000 112.667 2.464 + 4893.500 112.953 2.483 + 4894.000 112.033 2.478 + 4894.500 112.542 2.449 + 4895.000 111.403 2.406 + 4895.500 112.617 2.454 + 4896.000 113.261 2.539 + 4896.500 116.232 2.469 + 4897.000 119.713 2.475 + 4897.500 120.016 2.444 + 4898.000 118.816 2.417 + 4898.500 118.498 2.113 + 4899.000 116.502 2.125 + 4899.500 114.579 2.247 + 4900.000 112.964 2.394 + 4900.500 111.525 2.556 + 4901.000 110.884 2.626 + 4901.500 109.914 2.732 + 4902.000 109.843 2.779 + 4902.500 110.101 2.756 + 4903.000 111.748 2.709 + 4903.500 114.377 2.672 + 4904.000 118.150 2.689 + 4904.500 123.024 2.639 + 4905.000 123.325 2.648 + 4905.500 120.998 2.482 + 4906.000 115.084 2.401 + 4906.500 110.831 2.469 + 4907.000 111.059 2.528 + 4907.500 113.440 2.612 + 4908.000 114.188 2.602 + 4908.500 118.043 2.624 + 4909.000 118.491 2.534 + 4909.500 118.450 2.423 + 4910.000 119.094 2.250 + 4910.500 120.210 2.344 + 4911.000 121.175 2.562 + 4911.500 121.384 2.638 + 4912.000 119.508 2.666 + 4912.500 117.045 2.499 + 4913.000 115.676 2.374 + 4913.500 113.787 2.232 + 4914.000 113.350 2.242 + 4914.500 111.230 2.236 + 4915.000 109.079 2.209 + 4915.500 106.498 2.164 + 4916.000 105.907 2.142 + 4916.500 105.645 1.881 + 4917.000 108.072 1.993 + 4917.500 108.825 1.999 + 4918.000 110.928 2.321 + 4918.500 110.557 2.528 + 4919.000 113.218 2.681 + 4919.500 116.926 2.636 + 4920.000 121.984 2.475 + 4920.500 120.584 2.550 + 4921.000 118.862 2.305 + 4921.500 113.915 1.872 + 4922.000 111.485 1.828 + 4922.500 108.735 2.032 + 4923.000 107.580 2.007 + 4923.500 108.048 2.124 + 4924.000 108.333 2.252 + 4924.500 109.990 2.568 + 4925.000 113.302 2.630 + 4925.500 118.064 2.634 + 4926.000 118.935 2.615 + 4926.500 118.641 2.553 + 4927.000 117.074 2.517 + 4927.500 116.283 2.505 + 4928.000 116.449 2.447 + 4928.500 115.349 2.442 + 4929.000 114.381 2.518 + 4929.500 112.943 2.580 + 4930.000 112.148 2.516 + 4930.500 112.147 2.465 + 4931.000 112.967 2.407 + 4931.500 115.297 2.280 + 4932.000 116.921 2.294 + 4932.500 116.092 2.434 + 4933.000 115.953 2.495 + 4933.500 118.370 2.490 + 4934.000 120.100 2.479 + 4934.500 121.125 2.475 + 4935.000 119.473 2.458 + 4935.500 117.526 2.443 + 4936.000 115.977 2.230 + 4936.500 116.032 2.217 + 4937.000 115.298 2.305 + 4937.500 114.840 2.519 + 4938.000 113.990 2.628 + 4938.500 115.362 2.640 + 4939.000 117.048 2.621 + 4939.500 119.310 2.595 + 4940.000 119.114 2.558 + 4940.500 118.336 2.522 + 4941.000 116.823 2.526 + 4941.500 114.051 2.521 + 4942.000 113.360 2.566 + 4942.500 113.553 2.646 + 4943.000 113.619 2.663 + 4943.500 113.247 2.626 + 4944.000 114.538 2.555 + 4944.500 114.319 2.473 + 4945.000 113.641 2.409 + 4945.500 112.754 2.399 + 4946.000 112.478 2.384 + 4946.500 113.431 2.457 + 4947.000 113.810 2.611 + 4947.500 113.817 2.770 + 4948.000 113.758 2.733 + 4948.500 113.770 2.641 + 4949.000 113.852 2.642 + 4949.500 113.700 2.664 + 4950.000 113.576 2.691 + 4950.500 111.646 2.518 + 4951.000 109.817 2.513 + 4951.500 107.828 2.561 + 4952.000 106.067 2.679 + 4952.500 107.481 2.664 + 4953.000 112.900 2.671 + 4953.500 120.567 2.642 + 4954.000 127.793 2.647 + 4954.500 134.433 2.598 + 4955.000 134.658 2.564 + 4955.500 133.192 2.540 + 4956.000 130.249 2.338 + 4956.500 126.359 2.042 + 4957.000 123.030 2.056 + 4957.500 122.361 2.158 + 4958.000 121.468 2.581 + 4958.500 124.485 2.568 + 4959.000 124.855 2.497 + 4959.500 123.218 2.521 + 4960.000 119.939 2.591 + 4960.500 117.630 2.599 + 4961.000 114.610 2.609 + 4961.500 115.209 2.630 + 4962.000 115.509 2.658 + 4962.500 116.216 2.634 + 4963.000 116.102 2.586 + 4963.500 116.125 2.528 + 4964.000 116.133 2.555 + 4964.500 116.214 2.648 + 4965.000 115.343 2.649 + 4965.500 114.554 2.584 + 4966.000 116.381 2.533 + 4966.500 119.070 2.495 + 4967.000 123.357 2.568 + 4967.500 121.454 2.585 + 4968.000 120.815 2.491 + 4968.500 119.803 2.497 + 4969.000 119.174 2.514 + 4969.500 120.221 2.519 + 4970.000 119.489 2.498 + 4970.500 117.210 2.492 + 4971.000 114.918 2.491 + 4971.500 113.147 2.512 + 4972.000 114.844 2.466 + 4972.500 117.981 2.277 + 4973.000 120.214 2.333 + 4973.500 120.348 2.376 + 4974.000 119.441 2.558 + 4974.500 119.278 2.536 + 4975.000 120.169 2.400 + 4975.500 121.461 2.201 + 4976.000 122.565 1.998 + 4976.500 121.961 1.774 + 4977.000 121.611 1.993 + 4977.500 120.146 1.970 + 4978.000 119.501 2.423 + 4978.500 117.203 2.615 + 4979.000 118.418 2.583 + 4979.500 118.995 2.570 + 4980.000 119.929 2.458 + 4980.500 120.139 2.095 + 4981.000 120.131 2.128 + 4981.500 121.535 2.250 + 4982.000 122.490 2.425 + 4982.500 124.868 2.599 + 4983.000 124.571 2.550 + 4983.500 123.911 2.511 + 4984.000 122.516 2.526 + 4984.500 122.399 2.589 + 4985.000 120.883 2.536 + 4985.500 121.001 2.495 + 4986.000 120.041 2.466 + 4986.500 119.186 2.477 + 4987.000 119.469 2.524 + 4987.500 120.278 2.515 + 4988.000 121.420 2.473 + 4988.500 122.841 2.424 + 4989.000 123.767 2.321 + 4989.500 123.046 2.154 + 4990.000 124.178 2.003 + 4990.500 123.664 2.046 + 4991.000 122.623 2.138 + 4991.500 122.333 2.270 + 4992.000 122.417 2.342 + 4992.500 120.924 2.415 + 4993.000 120.667 2.385 + 4993.500 120.636 2.546 + 4994.000 121.354 2.562 + 4994.500 125.141 2.602 + 4995.000 125.928 2.623 + 4995.500 128.365 2.618 + 4996.000 131.366 2.590 + 4996.500 133.676 2.318 + 4997.000 132.693 2.242 + 4997.500 128.829 2.254 + 4998.000 127.895 2.302 + 4998.500 126.672 2.419 + 4999.000 128.343 2.498 + 4999.500 128.746 2.566 + 5000.000 129.821 2.651 + 5000.500 127.553 2.616 + 5001.000 125.918 2.498 + 5001.500 123.390 2.450 + 5002.000 120.971 2.424 + 5002.500 119.974 2.471 + 5003.000 120.108 2.391 + 5003.500 120.216 2.357 + 5004.000 120.779 2.263 + 5004.500 120.144 2.228 + 5005.000 120.439 2.301 + 5005.500 119.437 2.396 + 5006.000 119.061 2.452 + 5006.500 118.410 2.506 + 5007.000 116.438 2.564 + 5007.500 115.588 2.631 + 5008.000 114.657 2.673 + 5008.500 114.710 2.680 + 5009.000 116.027 2.686 + 5009.500 118.766 2.694 + 5010.000 121.059 2.714 + 5010.500 124.591 2.744 + 5011.000 124.092 2.696 + 5011.500 122.245 2.650 + 5012.000 120.669 2.589 + 5012.500 119.785 2.556 + 5013.000 119.126 2.516 + 5013.500 118.099 2.510 + 5014.000 116.874 2.532 + 5014.500 116.246 2.588 + 5015.000 114.456 2.604 + 5015.500 113.666 2.538 + 5016.000 113.869 2.506 + 5016.500 113.193 2.452 + 5017.000 112.323 2.558 + 5017.500 112.367 2.552 + 5018.000 113.117 2.563 + 5018.500 114.799 2.556 + 5019.000 115.443 2.649 + 5019.500 114.717 2.630 + 5020.000 114.556 2.544 + 5020.500 115.256 2.512 + 5021.000 118.184 2.590 + 5021.500 120.539 2.639 + 5022.000 124.065 2.615 + 5022.500 124.099 2.541 + 5023.000 120.582 2.475 + 5023.500 120.216 2.514 + 5024.000 119.857 2.556 + 5024.500 120.682 2.595 + 5025.000 119.421 2.654 + 5025.500 118.697 2.650 + 5026.000 118.741 2.658 + 5026.500 120.876 2.651 + 5027.000 124.119 2.664 + 5027.500 124.273 2.658 + 5028.000 123.300 2.603 + 5028.500 122.441 2.535 + 5029.000 121.874 2.495 + 5029.500 121.187 2.544 + 5030.000 120.509 2.605 + 5030.500 125.697 2.627 + 5031.000 127.914 2.641 + 5031.500 130.363 2.667 + 5032.000 128.667 2.668 + 5032.500 124.023 2.555 + 5033.000 122.990 2.562 + 5033.500 123.149 2.555 + 5034.000 124.179 2.612 + 5034.500 123.150 2.688 + 5035.000 120.740 2.678 + 5035.500 119.250 2.668 + 5036.000 118.574 2.670 + 5036.500 119.413 2.655 + 5037.000 119.103 2.634 + 5037.500 119.201 2.610 + 5038.000 119.662 2.658 + 5038.500 122.768 2.737 + 5039.000 124.920 2.760 + 5039.500 125.417 2.728 + 5040.000 124.523 2.676 + 5040.500 120.090 2.522 + 5041.000 119.363 2.502 + 5041.500 119.310 2.513 + 5042.000 120.836 2.627 + 5042.500 120.790 2.588 + 5043.000 120.955 2.503 + 5043.500 120.795 2.370 + 5044.000 121.129 2.398 + 5044.500 120.478 2.432 + 5045.000 119.179 2.474 + 5045.500 116.827 2.430 + 5046.000 116.241 2.385 + 5046.500 118.763 2.507 + 5047.000 119.333 2.379 + 5047.500 120.742 2.000 + 5048.000 121.875 1.995 + 5048.500 125.001 1.781 + 5049.000 126.208 1.999 + 5049.500 126.402 2.313 + 5050.000 123.383 2.319 + 5050.500 119.450 2.134 + 5051.000 117.650 2.190 + 5051.500 116.578 2.305 + 5052.000 117.117 2.392 + 5052.500 118.127 2.450 + 5053.000 119.088 2.546 + 5053.500 119.880 2.532 + 5054.000 120.057 2.475 + 5054.500 120.663 2.528 + 5055.000 121.535 2.550 + 5055.500 123.364 2.548 + 5056.000 124.229 2.546 + 5056.500 125.809 2.555 + 5057.000 126.551 2.576 + 5057.500 127.767 2.572 + 5058.000 128.505 2.560 + 5058.500 127.195 2.550 + 5059.000 122.512 2.565 + 5059.500 118.517 2.571 + 5060.000 116.846 2.520 + 5060.500 115.287 2.546 + 5061.000 117.144 2.591 + 5061.500 118.741 2.621 + 5062.000 120.068 2.599 + 5062.500 120.958 2.604 + 5063.000 120.864 2.636 + 5063.500 120.567 2.627 + 5064.000 119.096 2.642 + 5064.500 118.400 2.516 + 5065.000 117.859 2.395 + 5065.500 117.843 2.401 + 5066.000 119.279 2.324 + 5066.500 114.952 2.522 + 5067.000 117.116 2.512 + 5067.500 118.792 2.638 + 5068.000 120.584 2.493 + 5068.500 120.996 2.499 + 5069.000 121.053 2.358 + 5069.500 120.311 2.358 + 5070.000 118.596 2.425 + 5070.500 113.712 2.499 + 5071.000 110.351 2.601 + 5071.500 108.273 2.532 + 5072.000 109.086 2.332 + 5072.500 112.102 2.201 + 5073.000 113.789 2.081 + 5073.500 115.237 2.170 + 5074.000 115.145 2.301 + 5074.500 114.932 2.001 + 5075.000 114.959 2.006 + 5075.500 113.503 2.097 + 5076.000 114.985 2.191 + 5076.500 116.015 2.491 + 5077.000 116.111 2.442 + 5077.500 116.985 2.397 + 5078.000 119.407 2.274 + 5078.500 120.971 2.407 + 5079.000 123.190 2.542 + 5079.500 121.346 2.562 + 5080.000 119.918 2.519 + 5080.500 118.698 2.515 + 5081.000 117.927 2.531 + 5081.500 119.570 2.524 + 5082.000 118.530 2.518 + 5082.500 119.654 2.444 + 5083.000 119.886 2.488 + 5083.500 120.584 2.532 + 5084.000 116.804 2.521 + 5084.500 115.623 2.519 + 5085.000 113.004 2.500 + 5085.500 113.549 2.463 + 5086.000 112.894 2.475 + 5086.500 112.993 2.501 + 5087.000 113.382 2.569 + 5087.500 113.501 2.667 + 5088.000 114.528 2.628 + 5088.500 115.928 2.579 + 5089.000 115.223 2.581 + 5089.500 115.657 2.574 + 5090.000 116.500 2.538 + 5090.500 117.363 2.488 + 5091.000 118.244 2.501 + 5091.500 119.194 2.523 + 5092.000 119.959 2.567 + 5092.500 120.737 2.605 + 5093.000 119.517 2.633 + 5093.500 117.833 2.647 + 5094.000 117.579 2.651 + 5094.500 119.311 2.543 + 5095.000 120.189 2.387 + 5095.500 120.359 2.254 + 5096.000 121.691 2.228 + 5096.500 120.486 2.376 + 5097.000 120.785 2.586 + 5097.500 119.660 2.544 + 5098.000 118.394 2.489 + 5098.500 118.044 2.399 + 5099.000 117.326 2.431 + 5099.500 118.701 2.503 + 5100.000 119.839 2.601 + 5100.500 118.504 2.634 + 5101.000 118.603 2.638 + 5101.500 118.383 2.628 + 5102.000 119.304 2.564 + 5102.500 120.199 2.433 + 5103.000 119.898 2.334 + 5103.500 119.071 2.382 + 5104.000 117.933 2.455 + 5104.500 114.651 2.521 + 5105.000 112.665 2.661 + 5105.500 112.803 2.711 + 5106.000 114.569 2.710 + 5106.500 114.576 2.569 + 5107.000 114.315 2.431 + 5107.500 114.333 2.343 + 5108.000 114.885 2.384 + 5108.500 116.367 2.489 + 5109.000 115.180 2.478 + 5109.500 112.962 2.451 + 5110.000 110.982 2.487 + 5110.500 109.677 2.556 + 5111.000 111.384 2.539 + 5111.500 116.080 2.525 + 5112.000 120.506 2.393 + 5112.500 125.869 2.245 + 5113.000 123.840 2.162 + 5113.500 122.400 2.199 + 5114.000 119.895 2.337 + 5114.500 117.114 2.535 + 5115.000 113.730 2.667 + 5115.500 111.181 2.656 + 5116.000 110.355 2.634 + 5116.500 112.974 2.648 + 5117.000 115.370 2.640 + 5117.500 118.610 2.553 + 5118.000 119.382 2.535 + 5118.500 120.711 2.431 + 5119.000 121.681 2.403 + 5119.500 122.437 2.414 + 5120.000 120.937 2.441 + 5120.500 117.345 2.538 + 5121.000 113.413 2.619 + 5121.500 112.260 2.586 + 5122.000 113.088 2.550 + 5122.500 115.775 2.319 + 5123.000 119.524 2.326 + 5123.500 122.153 2.444 + 5124.000 126.688 2.381 + 5124.500 125.731 2.548 + 5125.000 124.413 2.274 + 5125.500 120.912 2.336 + 5126.000 119.300 2.564 + 5126.500 117.237 2.672 + 5127.000 117.012 2.672 + 5127.500 118.280 2.550 + 5128.000 118.889 2.550 + 5128.500 121.389 2.448 + 5129.000 129.214 2.564 + 5129.500 130.619 2.270 + 5130.000 130.675 2.181 + 5130.500 127.648 2.264 + 5131.000 121.085 2.372 + 5131.500 122.961 2.493 + 5132.000 122.339 2.730 + 5132.500 123.492 2.674 + 5133.000 124.677 2.550 + 5133.500 125.056 2.489 + 5134.000 127.214 2.417 + 5134.500 131.454 2.374 + 5135.000 133.985 2.297 + 5135.500 132.316 2.237 + 5136.000 129.869 2.199 + 5136.500 126.193 2.350 + 5137.000 124.828 2.466 + 5137.500 123.852 2.570 + 5138.000 124.290 2.638 + 5138.500 124.642 2.087 + 5139.000 124.217 1.993 + 5139.500 123.175 1.968 + 5140.000 122.553 1.995 + 5140.500 120.682 1.999 + 5141.000 120.111 2.083 + 5141.500 119.413 2.132 + 5142.000 119.333 2.391 + 5142.500 118.842 2.562 + 5143.000 118.751 2.617 + 5143.500 118.937 2.554 + 5144.000 120.321 2.317 + 5144.500 121.396 2.391 + 5145.000 124.883 2.230 + 5145.500 125.797 2.287 + 5146.000 125.612 2.301 + 5146.500 123.161 2.366 + 5147.000 123.922 2.364 + 5147.500 126.221 2.315 + 5148.000 128.016 2.197 + 5148.500 128.915 2.166 + 5149.000 130.371 2.126 + 5149.500 131.047 2.072 + 5150.000 129.465 2.070 + 5150.500 127.129 2.466 + 5151.000 127.998 2.428 + 5151.500 128.973 2.395 + 5152.000 129.579 2.377 + 5152.500 129.395 2.644 + 5153.000 128.126 2.715 + 5153.500 127.324 2.648 + 5154.000 127.060 2.570 + 5154.500 125.562 2.468 + 5155.000 123.990 2.456 + 5155.500 123.116 2.440 + 5156.000 123.831 2.407 + 5156.500 123.935 2.552 + 5157.000 125.272 2.649 + 5157.500 128.369 2.748 + 5158.000 129.420 2.757 + 5158.500 130.417 2.658 + 5159.000 125.718 2.573 + 5159.500 123.807 2.507 + 5160.000 123.305 2.542 + 5160.500 123.994 2.548 + 5161.000 122.609 2.511 + 5161.500 121.572 2.276 + 5162.000 121.889 2.001 + 5162.500 124.222 2.000 + 5163.000 123.310 1.998 + 5163.500 120.603 1.997 + 5164.000 118.793 1.995 + 5164.500 116.808 1.919 + 5165.000 116.971 1.952 + 5165.500 118.985 1.977 + 5166.000 120.726 2.001 + 5166.500 124.361 2.368 + 5167.000 127.848 2.472 + 5167.500 127.872 2.515 + 5168.000 128.098 2.283 + 5168.500 124.412 2.130 + 5169.000 122.654 2.117 + 5169.500 121.683 2.158 + 5170.000 121.702 2.370 + 5170.500 120.855 2.503 + 5171.000 123.095 2.503 + 5171.500 127.801 2.387 + 5172.000 134.211 2.309 + 5172.500 139.421 2.315 + 5173.000 138.868 2.470 + 5173.500 136.025 2.472 + 5174.000 135.156 2.464 + 5174.500 137.190 2.439 + 5175.000 134.426 2.449 + 5175.500 129.263 2.417 + 5176.000 127.400 2.193 + 5176.500 125.833 2.275 + 5177.000 125.582 2.085 + 5177.500 125.422 2.426 + 5178.000 126.300 2.540 + 5178.500 129.549 2.464 + 5179.000 134.794 2.356 + 5179.500 136.740 2.354 + 5180.000 141.730 2.414 + 5180.500 142.720 2.503 + 5181.000 143.120 2.607 + 5181.500 141.232 2.637 + 5182.000 138.124 2.626 + 5182.500 133.870 2.432 + 5183.000 131.878 2.375 + 5183.500 130.421 2.235 + 5184.000 130.535 2.155 + 5184.500 133.189 1.993 + 5185.000 136.797 1.995 + 5185.500 140.220 1.615 + 5186.000 135.901 1.652 + 5186.500 130.734 1.995 + 5187.000 125.338 2.172 + 5187.500 123.405 2.168 + 5188.000 121.613 1.995 + 5188.500 120.817 1.548 + 5189.000 120.819 1.893 + 5189.500 121.087 2.048 + 5190.000 123.065 2.266 + 5190.500 126.645 2.275 + 5191.000 131.491 2.285 + 5191.500 140.871 2.303 + 5192.000 152.858 2.368 + 5192.500 156.952 2.211 + 5193.000 150.632 2.099 + 5193.500 143.701 2.060 + 5194.000 130.853 2.134 + 5194.500 123.676 2.146 + 5195.000 123.154 2.058 + 5195.500 125.166 2.071 + 5196.000 126.481 2.106 + 5196.500 127.731 2.318 + 5197.000 126.383 2.310 + 5197.500 124.164 2.314 + 5198.000 123.184 2.282 + 5198.500 124.886 2.376 + 5199.000 125.825 2.398 + 5199.500 126.357 2.409 + 5200.000 127.022 2.400 + 5200.500 127.062 2.376 + 5201.000 127.852 2.283 + 5201.500 127.924 2.285 + 5202.000 127.827 2.302 + 5202.500 127.077 2.299 + 5203.000 127.288 2.281 + 5203.500 128.786 2.276 + 5204.000 130.767 2.372 + 5204.500 133.849 2.420 + 5205.000 134.405 2.456 + 5205.500 132.958 2.464 + 5206.000 130.386 2.409 + 5206.500 127.364 2.039 + 5207.000 126.441 1.921 + 5207.500 125.485 1.789 + 5208.000 125.560 1.599 + 5208.500 125.714 1.664 + 5209.000 124.390 1.623 + 5209.500 123.489 2.003 + 5210.000 124.724 2.064 + 5210.500 126.550 2.505 + 5211.000 128.440 2.726 + 5211.500 124.601 2.725 + 5212.000 120.241 2.624 + 5212.500 119.018 2.456 + 5213.000 120.725 2.505 + 5213.500 120.673 2.663 + 5214.000 121.478 2.725 + 5214.500 120.144 2.649 + 5215.000 120.165 2.594 + 5215.500 121.152 2.514 + 5216.000 121.573 2.444 + 5216.500 123.250 2.401 + 5217.000 124.995 2.499 + 5217.500 126.126 2.615 + 5218.000 127.199 2.777 + 5218.500 126.353 2.739 + 5219.000 125.314 2.642 + 5219.500 125.448 2.462 + 5220.000 127.447 2.367 + 5220.500 129.462 2.381 + 5221.000 129.419 2.358 + 5221.500 128.035 2.342 + 5222.000 128.670 2.409 + 5222.500 130.733 2.368 + 5223.000 131.832 2.632 + 5223.500 131.347 2.628 + 5224.000 127.665 2.540 + 5224.500 122.763 2.391 + 5225.000 120.763 2.426 + 5225.500 120.145 2.475 + 5226.000 119.374 2.489 + 5226.500 119.863 2.423 + 5227.000 120.588 2.373 + 5227.500 121.864 2.466 + 5228.000 123.468 2.459 + 5228.500 124.750 2.442 + 5229.000 125.905 2.433 + 5229.500 123.578 2.420 + 5230.000 121.429 2.457 + 5230.500 117.450 2.583 + 5231.000 113.890 2.658 + 5231.500 114.285 2.689 + 5232.000 116.233 2.701 + 5232.500 118.832 2.676 + 5233.000 120.103 2.577 + 5233.500 120.823 2.514 + 5234.000 121.588 2.473 + 5234.500 123.295 2.506 + 5235.000 124.219 2.501 + 5235.500 125.098 2.520 + 5236.000 127.640 2.509 + 5236.500 129.671 2.517 + 5237.000 129.447 2.450 + 5237.500 127.542 2.283 + 5238.000 125.915 2.391 + 5238.500 123.192 2.470 + 5239.000 120.934 2.456 + 5239.500 120.126 2.293 + 5240.000 119.429 2.207 + 5240.500 119.889 2.479 + 5241.000 119.048 2.462 + 5241.500 116.015 2.456 + 5242.000 114.509 2.332 + 5242.500 114.378 2.217 + 5243.000 116.043 2.413 + 5243.500 117.069 2.489 + 5244.000 118.382 2.472 + 5244.500 119.094 2.371 + 5245.000 120.788 2.309 + 5245.500 120.014 2.289 + 5246.000 119.301 2.392 + 5246.500 115.535 2.524 + 5247.000 114.924 2.507 + 5247.500 118.979 2.418 + 5248.000 126.853 2.378 + 5248.500 129.310 2.322 + 5249.000 124.192 2.332 + 5249.500 119.159 2.279 + 5250.000 118.643 2.229 + 5250.500 119.654 2.139 + 5251.000 123.580 2.140 + 5251.500 125.008 2.190 + 5252.000 123.380 2.263 + 5252.500 120.745 2.414 + 5253.000 120.882 2.480 + 5253.500 121.294 2.571 + 5254.000 121.781 2.679 + 5254.500 122.906 2.746 + 5255.000 123.260 2.744 + 5255.500 125.055 2.586 + 5256.000 127.311 2.489 + 5256.500 129.586 2.274 + 5257.000 128.659 2.158 + 5257.500 126.178 2.166 + 5258.000 125.603 2.240 + 5258.500 123.384 2.513 + 5259.000 123.969 2.674 + 5259.500 125.672 2.750 + 5260.000 126.589 2.705 + 5260.500 126.970 2.460 + 5261.000 124.690 2.485 + 5261.500 122.898 2.552 + 5262.000 120.750 2.697 + 5262.500 119.633 2.685 + 5263.000 117.025 2.501 + 5263.500 115.278 2.328 + 5264.000 115.431 2.501 + 5264.500 116.270 2.260 + 5265.000 116.719 2.462 + 5265.500 116.681 2.503 + 5266.000 117.111 2.477 + 5266.500 117.749 2.493 + 5267.000 118.270 2.493 + 5267.500 118.618 2.475 + 5268.000 121.289 2.375 + 5268.500 124.947 2.374 + 5269.000 125.495 2.533 + 5269.500 125.601 2.564 + 5270.000 125.591 2.555 + 5270.500 125.728 2.476 + 5271.000 126.663 2.487 + 5271.500 127.025 2.479 + 5272.000 126.063 2.504 + 5272.500 123.524 2.320 + 5273.000 122.819 2.358 + 5273.500 124.859 2.419 + 5274.000 126.654 2.459 + 5274.500 128.994 2.503 + 5275.000 128.728 2.459 + 5275.500 128.611 2.391 + 5276.000 131.994 2.444 + 5276.500 134.793 2.175 + 5277.000 135.927 2.181 + 5277.500 135.541 2.230 + 5278.000 133.576 2.362 + 5278.500 132.702 2.538 + 5279.000 131.775 2.514 + 5279.500 130.298 2.469 + 5280.000 130.877 2.401 + 5280.500 130.176 2.456 + 5281.000 130.345 2.503 + 5281.500 129.798 2.569 + 5282.000 129.374 2.590 + 5282.500 128.931 2.600 + 5283.000 128.700 2.599 + 5283.500 128.746 2.615 + 5284.000 128.779 2.620 + 5284.500 128.575 2.569 + 5285.000 130.262 2.511 + 5285.500 132.754 2.493 + 5286.000 133.398 2.558 + 5286.500 132.567 2.549 + 5287.000 132.744 2.409 + 5287.500 132.645 2.334 + 5288.000 132.612 2.275 + 5288.500 131.192 2.245 + 5289.000 130.473 2.233 + 5289.500 128.773 2.376 + 5290.000 128.539 2.449 + 5290.500 128.678 2.575 + 5291.000 129.553 2.556 + 5291.500 130.160 2.551 + 5292.000 130.306 2.553 + 5292.500 130.358 2.572 + 5293.000 130.198 2.582 + 5293.500 128.681 2.610 + 5294.000 127.103 2.631 + 5294.500 127.001 2.598 + 5295.000 124.678 2.441 + 5295.500 122.997 2.323 + 5296.000 119.910 2.276 + 5296.500 120.417 2.444 + 5297.000 120.440 2.612 + 5297.500 123.121 2.575 + 5298.000 124.670 2.514 + 5298.500 124.819 2.478 + 5299.000 124.693 2.485 + 5299.500 123.841 2.482 + 5300.000 124.699 2.482 diff --git a/ThirdParty/NRLib/well_UnitTests/Bean_B.las b/ThirdParty/NRLib/well_UnitTests/Bean_B.las new file mode 100644 index 0000000000..3c796b8c5c --- /dev/null +++ b/ThirdParty/NRLib/well_UnitTests/Bean_B.las @@ -0,0 +1,10331 @@ +~Version Information Block + VERS. 2.00: CWLS LOG ASCII STANDARD - VERSION 2.000000 + WRAP. NO: One Line Per Depth Step +# +~Well Information Block +#MNEM.UNIT Data Information +#---------- ------------------------------------------ ---------------- + STRT.FT 5300.0000: + STOP.FT 10450.0000: + STEP.FT 0.5000: + NULL. -999.2500: + COMP. : COMPANY + WELL. : WELL + FLD . : FIELD + CNTY. : COUNTY + STAT. : STATE + CTRY. : COUNTRY + SRVC. : SERVICE COMPANY + DATE. : DATE + API . : API NUMBER + UWI . : UWI NUMBER +# +~Curve Information Block +#MNEM.UNIT API CODE Curve Description +#---------- ------------- ------------------- + DEPT.FT : Depth in Feet + GR .GAPI : Gamma Ray + RHOB.G/C3 : Bulk Density +# +~A DEPTH GR RHOB + 5300.000 129.762 2.605 + 5300.500 129.762 2.653 + 5301.000 128.175 2.678 + 5301.500 126.587 2.678 + 5302.000 125.794 2.678 + 5302.500 126.587 2.561 + 5303.000 127.381 2.334 + 5303.500 127.622 2.340 + 5304.000 129.306 2.180 + 5304.500 130.543 2.103 + 5305.000 133.573 2.160 + 5305.500 136.556 2.320 + 5306.000 138.338 2.480 + 5306.500 136.664 2.564 + 5307.000 135.528 2.570 + 5307.500 134.526 2.578 + 5308.000 132.952 2.615 + 5308.500 132.536 2.595 + 5309.000 138.694 2.708 + 5309.500 141.471 2.721 + 5310.000 145.033 2.729 + 5310.500 146.303 2.751 + 5311.000 144.984 2.741 + 5311.500 142.668 2.691 + 5312.000 141.250 2.613 + 5312.500 140.303 2.493 + 5313.000 140.150 2.447 + 5313.500 139.476 2.520 + 5314.000 138.318 2.573 + 5314.500 137.530 2.569 + 5315.000 138.042 2.555 + 5315.500 135.073 2.457 + 5316.000 135.725 2.358 + 5316.500 132.649 2.034 + 5317.000 130.386 2.034 + 5317.500 129.521 2.125 + 5318.000 128.927 2.287 + 5318.500 130.580 2.430 + 5319.000 132.558 2.487 + 5319.500 139.172 2.507 + 5320.000 141.029 2.517 + 5320.500 146.205 2.570 + 5321.000 147.822 2.542 + 5321.500 143.831 2.425 + 5322.000 140.215 2.255 + 5322.500 137.839 2.270 + 5323.000 134.312 2.396 + 5323.500 133.423 2.387 + 5324.000 132.380 2.374 + 5324.500 131.452 2.277 + 5325.000 132.886 2.190 + 5325.500 132.885 2.293 + 5326.000 133.041 2.407 + 5326.500 131.441 2.475 + 5327.000 126.667 2.468 + 5327.500 125.401 2.482 + 5328.000 124.416 2.473 + 5328.500 123.575 2.483 + 5329.000 122.578 2.409 + 5329.500 121.622 2.452 + 5330.000 121.229 2.515 + 5330.500 120.106 2.506 + 5331.000 124.612 2.477 + 5331.500 127.517 2.442 + 5332.000 129.872 2.384 + 5332.500 129.597 2.409 + 5333.000 130.463 2.523 + 5333.500 130.404 2.494 + 5334.000 129.622 2.497 + 5334.500 128.181 2.516 + 5335.000 126.648 2.560 + 5335.500 125.003 2.631 + 5336.000 125.777 2.611 + 5336.500 126.720 2.408 + 5337.000 125.999 2.333 + 5337.500 124.666 2.362 + 5338.000 120.229 2.413 + 5338.500 117.360 2.490 + 5339.000 117.436 2.546 + 5339.500 122.438 2.626 + 5340.000 124.857 2.654 + 5340.500 125.338 2.497 + 5341.000 122.565 2.417 + 5341.500 121.222 2.401 + 5342.000 119.835 2.392 + 5342.500 130.142 2.308 + 5343.000 134.555 2.254 + 5343.500 134.779 2.199 + 5344.000 131.602 2.235 + 5344.500 125.739 2.452 + 5345.000 124.589 2.636 + 5345.500 123.205 2.614 + 5346.000 121.450 2.495 + 5346.500 118.711 2.527 + 5347.000 115.826 2.365 + 5347.500 114.614 2.453 + 5348.000 114.657 2.485 + 5348.500 114.536 2.495 + 5349.000 113.629 2.194 + 5349.500 111.415 2.221 + 5350.000 110.554 2.414 + 5350.500 109.863 2.473 + 5351.000 110.516 2.454 + 5351.500 111.192 2.434 + 5352.000 112.876 2.425 + 5352.500 115.188 2.445 + 5353.000 118.188 2.459 + 5353.500 119.939 2.466 + 5354.000 125.032 2.459 + 5354.500 130.075 2.472 + 5355.000 131.534 2.450 + 5355.500 130.382 2.410 + 5356.000 128.428 2.418 + 5356.500 126.469 2.467 + 5357.000 126.708 2.565 + 5357.500 126.387 2.558 + 5358.000 126.902 2.569 + 5358.500 122.308 2.565 + 5359.000 120.498 2.485 + 5359.500 117.164 2.438 + 5360.000 116.044 2.481 + 5360.500 114.279 2.517 + 5361.000 113.519 2.624 + 5361.500 110.549 2.609 + 5362.000 109.111 2.628 + 5362.500 108.238 2.622 + 5363.000 108.326 2.614 + 5363.500 108.334 2.605 + 5364.000 108.166 2.600 + 5364.500 107.325 2.603 + 5365.000 106.584 2.723 + 5365.500 107.635 2.786 + 5366.000 110.490 2.806 + 5366.500 116.174 2.692 + 5367.000 118.836 2.539 + 5367.500 118.275 2.548 + 5368.000 114.997 2.613 + 5368.500 114.534 2.641 + 5369.000 114.793 2.668 + 5369.500 116.238 2.641 + 5370.000 116.162 2.275 + 5370.500 114.764 2.005 + 5371.000 114.274 1.981 + 5371.500 110.636 2.003 + 5372.000 106.554 2.523 + 5372.500 100.475 2.454 + 5373.000 96.941 2.651 + 5373.500 93.007 2.658 + 5374.000 92.318 2.662 + 5374.500 93.003 2.668 + 5375.000 94.330 2.678 + 5375.500 95.190 2.676 + 5376.000 97.468 2.649 + 5376.500 97.616 2.641 + 5377.000 99.444 2.637 + 5377.500 99.559 2.677 + 5378.000 101.308 2.665 + 5378.500 100.875 2.649 + 5379.000 98.771 2.605 + 5379.500 93.827 2.586 + 5380.000 88.790 2.652 + 5380.500 90.427 2.643 + 5381.000 94.789 2.631 + 5381.500 99.842 2.618 + 5382.000 106.615 2.606 + 5382.500 108.175 2.607 + 5383.000 107.313 2.604 + 5383.500 106.756 2.581 + 5384.000 107.697 2.544 + 5384.500 105.476 2.555 + 5385.000 103.484 2.569 + 5385.500 101.066 2.622 + 5386.000 99.326 2.655 + 5386.500 99.499 2.651 + 5387.000 104.475 2.656 + 5387.500 108.952 2.652 + 5388.000 107.971 2.641 + 5388.500 105.776 2.531 + 5389.000 105.974 2.456 + 5389.500 106.054 2.438 + 5390.000 104.918 2.518 + 5390.500 103.591 2.601 + 5391.000 102.699 2.620 + 5391.500 103.630 2.625 + 5392.000 104.413 2.641 + 5392.500 106.664 2.652 + 5393.000 107.723 2.725 + 5393.500 108.783 2.743 + 5394.000 110.187 2.422 + 5394.500 112.670 2.471 + 5395.000 114.145 2.233 + 5395.500 111.348 2.261 + 5396.000 104.060 2.412 + 5396.500 91.914 2.627 + 5397.000 89.484 2.599 + 5397.500 92.736 2.566 + 5398.000 98.255 2.105 + 5398.500 106.545 2.113 + 5399.000 108.420 2.314 + 5399.500 109.138 2.227 + 5400.000 105.812 2.548 + 5400.500 103.043 2.637 + 5401.000 101.215 2.698 + 5401.500 99.769 2.777 + 5402.000 99.333 2.552 + 5402.500 101.735 2.471 + 5403.000 103.069 2.198 + 5403.500 105.012 2.208 + 5404.000 104.055 2.420 + 5404.500 101.288 2.576 + 5405.000 101.467 2.611 + 5405.500 99.096 2.605 + 5406.000 95.933 2.473 + 5406.500 98.158 2.117 + 5407.000 102.183 2.074 + 5407.500 108.271 2.304 + 5408.000 111.140 2.529 + 5408.500 112.437 2.613 + 5409.000 112.405 2.637 + 5409.500 111.416 2.597 + 5410.000 107.969 2.550 + 5410.500 101.892 2.621 + 5411.000 98.713 2.653 + 5411.500 94.627 2.672 + 5412.000 94.758 2.706 + 5412.500 95.744 2.003 + 5413.000 99.949 2.003 + 5413.500 101.828 1.942 + 5414.000 102.703 2.001 + 5414.500 101.837 2.170 + 5415.000 97.970 2.570 + 5415.500 94.585 2.643 + 5416.000 92.269 2.639 + 5416.500 92.660 2.529 + 5417.000 93.159 2.402 + 5417.500 90.663 2.324 + 5418.000 86.776 2.441 + 5418.500 81.391 2.542 + 5419.000 81.980 2.668 + 5419.500 83.974 2.658 + 5420.000 90.582 2.649 + 5420.500 97.313 2.452 + 5421.000 100.638 2.400 + 5421.500 99.964 2.284 + 5422.000 96.836 2.281 + 5422.500 90.926 2.454 + 5423.000 86.547 2.566 + 5423.500 82.564 2.698 + 5424.000 80.014 2.727 + 5424.500 80.176 2.801 + 5425.000 79.616 2.788 + 5425.500 80.624 2.815 + 5426.000 81.263 2.716 + 5426.500 82.252 2.633 + 5427.000 84.614 2.617 + 5427.500 88.550 2.601 + 5428.000 91.582 2.549 + 5428.500 89.858 2.491 + 5429.000 86.019 2.438 + 5429.500 83.945 2.496 + 5430.000 84.430 2.596 + 5430.500 89.024 2.577 + 5431.000 92.470 2.514 + 5431.500 94.932 2.512 + 5432.000 93.435 2.542 + 5432.500 91.963 2.661 + 5433.000 89.774 2.649 + 5433.500 87.312 2.555 + 5434.000 85.779 2.579 + 5434.500 84.388 2.651 + 5435.000 81.611 2.672 + 5435.500 77.783 2.693 + 5436.000 76.954 2.713 + 5436.500 81.665 2.687 + 5437.000 85.568 2.670 + 5437.500 89.268 2.561 + 5438.000 88.108 2.525 + 5438.500 86.984 2.445 + 5439.000 87.470 2.487 + 5439.500 88.517 2.475 + 5440.000 90.265 2.591 + 5440.500 89.926 2.735 + 5441.000 88.296 2.722 + 5441.500 84.024 2.716 + 5442.000 80.720 2.688 + 5442.500 79.804 2.648 + 5443.000 81.217 2.658 + 5443.500 84.719 2.659 + 5444.000 83.449 2.666 + 5444.500 81.861 2.673 + 5445.000 81.262 2.674 + 5445.500 82.207 2.666 + 5446.000 84.740 2.647 + 5446.500 87.404 2.633 + 5447.000 89.494 2.639 + 5447.500 91.379 2.675 + 5448.000 91.688 2.669 + 5448.500 91.088 2.640 + 5449.000 85.785 2.569 + 5449.500 79.254 2.578 + 5450.000 75.744 2.625 + 5450.500 72.393 2.659 + 5451.000 76.494 2.653 + 5451.500 79.902 2.644 + 5452.000 85.718 2.621 + 5452.500 83.882 2.626 + 5453.000 79.307 2.645 + 5453.500 76.164 2.651 + 5454.000 78.562 2.664 + 5454.500 82.959 2.658 + 5455.000 88.931 2.641 + 5455.500 95.657 2.609 + 5456.000 99.208 2.627 + 5456.500 102.850 2.352 + 5457.000 104.597 2.401 + 5457.500 101.019 2.435 + 5458.000 99.750 2.499 + 5458.500 100.315 2.595 + 5459.000 101.558 2.579 + 5459.500 106.641 2.472 + 5460.000 110.898 2.423 + 5460.500 115.501 2.403 + 5461.000 115.825 2.452 + 5461.500 116.004 2.496 + 5462.000 111.822 2.537 + 5462.500 106.293 2.529 + 5463.000 100.080 2.461 + 5463.500 96.788 2.445 + 5464.000 90.717 2.554 + 5464.500 90.123 2.652 + 5465.000 90.234 2.643 + 5465.500 93.261 2.470 + 5466.000 97.159 2.453 + 5466.500 98.821 2.532 + 5467.000 95.195 2.557 + 5467.500 91.385 2.629 + 5468.000 88.487 2.623 + 5468.500 86.563 2.653 + 5469.000 88.602 2.632 + 5469.500 93.171 2.523 + 5470.000 96.687 2.337 + 5470.500 97.156 2.360 + 5471.000 95.061 2.486 + 5471.500 92.346 2.574 + 5472.000 92.565 2.584 + 5472.500 95.135 2.605 + 5473.000 98.886 2.605 + 5473.500 99.770 2.600 + 5474.000 98.548 2.577 + 5474.500 94.947 2.496 + 5475.000 90.111 2.515 + 5475.500 86.544 2.510 + 5476.000 81.921 2.337 + 5476.500 76.453 2.445 + 5477.000 73.280 2.515 + 5477.500 73.895 2.581 + 5478.000 76.232 2.683 + 5478.500 82.576 2.699 + 5479.000 84.517 2.630 + 5479.500 84.686 2.527 + 5480.000 82.321 2.509 + 5480.500 77.857 2.643 + 5481.000 75.059 2.684 + 5481.500 74.737 2.679 + 5482.000 77.184 2.701 + 5482.500 81.273 2.520 + 5483.000 84.886 2.402 + 5483.500 87.040 2.284 + 5484.000 89.249 2.228 + 5484.500 89.204 2.189 + 5485.000 87.656 2.192 + 5485.500 88.652 2.413 + 5486.000 89.315 2.404 + 5486.500 93.621 2.623 + 5487.000 94.413 2.534 + 5487.500 96.284 2.503 + 5488.000 96.377 2.461 + 5488.500 96.334 2.507 + 5489.000 95.769 2.498 + 5489.500 99.008 2.477 + 5490.000 102.350 2.332 + 5490.500 100.730 2.264 + 5491.000 96.388 2.368 + 5491.500 90.555 2.489 + 5492.000 84.440 2.581 + 5492.500 84.397 2.588 + 5493.000 88.844 2.632 + 5493.500 92.055 2.622 + 5494.000 93.156 2.577 + 5494.500 91.839 2.548 + 5495.000 88.953 2.520 + 5495.500 82.353 2.551 + 5496.000 79.051 2.635 + 5496.500 69.196 2.530 + 5497.000 61.872 2.511 + 5497.500 56.828 2.498 + 5498.000 56.220 2.509 + 5498.500 58.964 2.524 + 5499.000 60.666 2.487 + 5499.500 61.812 2.471 + 5500.000 60.344 2.457 + 5500.500 58.891 2.473 + 5501.000 51.438 2.535 + 5501.500 49.180 2.627 + 5502.000 46.512 2.612 + 5502.500 44.690 2.581 + 5503.000 44.554 2.437 + 5503.500 45.658 2.346 + 5504.000 49.067 2.352 + 5504.500 54.650 2.447 + 5505.000 59.374 2.670 + 5505.500 60.818 2.582 + 5506.000 59.577 2.397 + 5506.500 51.047 2.456 + 5507.000 46.590 2.336 + 5507.500 43.975 2.357 + 5508.000 41.657 2.369 + 5508.500 39.987 2.416 + 5509.000 39.128 2.426 + 5509.500 37.550 2.446 + 5510.000 34.818 2.434 + 5510.500 33.049 2.493 + 5511.000 32.985 2.491 + 5511.500 35.521 2.481 + 5512.000 40.183 2.379 + 5512.500 42.445 2.271 + 5513.000 40.103 2.227 + 5513.500 37.166 2.221 + 5514.000 33.294 2.422 + 5514.500 32.053 2.631 + 5515.000 32.752 2.605 + 5515.500 35.923 2.523 + 5516.000 39.100 2.515 + 5516.500 41.433 2.716 + 5517.000 42.288 2.737 + 5517.500 44.591 2.723 + 5518.000 45.492 2.592 + 5518.500 45.604 2.574 + 5519.000 45.654 2.424 + 5519.500 43.517 2.375 + 5520.000 42.658 2.374 + 5520.500 42.448 2.460 + 5521.000 42.322 2.741 + 5521.500 43.819 2.737 + 5522.000 46.178 2.623 + 5522.500 48.013 2.629 + 5523.000 48.297 2.625 + 5523.500 49.533 2.566 + 5524.000 49.554 2.527 + 5524.500 50.007 2.478 + 5525.000 50.672 2.542 + 5525.500 51.345 2.635 + 5526.000 52.065 2.661 + 5526.500 49.566 2.702 + 5527.000 46.739 2.708 + 5527.500 41.725 2.697 + 5528.000 37.682 2.623 + 5528.500 34.126 2.494 + 5529.000 34.792 2.472 + 5529.500 35.978 2.469 + 5530.000 38.325 2.481 + 5530.500 39.594 2.515 + 5531.000 39.499 2.519 + 5531.500 39.589 2.531 + 5532.000 40.668 2.510 + 5532.500 39.749 2.564 + 5533.000 39.755 2.590 + 5533.500 39.360 2.609 + 5534.000 40.178 2.260 + 5534.500 40.061 2.295 + 5535.000 40.122 2.245 + 5535.500 40.860 2.222 + 5536.000 41.056 2.248 + 5536.500 41.882 2.406 + 5537.000 45.636 2.456 + 5537.500 48.087 2.601 + 5538.000 50.359 2.606 + 5538.500 48.354 2.584 + 5539.000 43.246 2.574 + 5539.500 40.018 2.561 + 5540.000 40.336 2.471 + 5540.500 40.361 2.444 + 5541.000 41.759 2.464 + 5541.500 42.568 2.497 + 5542.000 43.856 2.603 + 5542.500 42.865 2.615 + 5543.000 41.355 2.641 + 5543.500 40.796 2.662 + 5544.000 39.454 2.676 + 5544.500 38.340 2.704 + 5545.000 36.645 2.700 + 5545.500 35.429 2.706 + 5546.000 35.351 2.647 + 5546.500 35.139 2.586 + 5547.000 34.373 2.573 + 5547.500 35.311 2.709 + 5548.000 37.893 2.700 + 5548.500 39.389 2.709 + 5549.000 39.248 2.658 + 5549.500 38.569 2.579 + 5550.000 38.549 2.436 + 5550.500 39.081 2.459 + 5551.000 39.998 2.592 + 5551.500 41.516 2.621 + 5552.000 42.625 2.687 + 5552.500 44.198 2.619 + 5553.000 43.839 2.558 + 5553.500 43.277 2.474 + 5554.000 42.451 2.273 + 5554.500 42.065 2.190 + 5555.000 43.065 2.258 + 5555.500 44.607 2.292 + 5556.000 46.053 2.400 + 5556.500 47.307 2.388 + 5557.000 48.564 2.522 + 5557.500 47.594 2.517 + 5558.000 44.023 2.519 + 5558.500 40.626 2.529 + 5559.000 38.296 2.537 + 5559.500 35.663 2.529 + 5560.000 34.421 2.502 + 5560.500 33.951 2.547 + 5561.000 34.795 2.572 + 5561.500 37.358 2.621 + 5562.000 38.746 2.621 + 5562.500 39.428 2.596 + 5563.000 39.823 2.614 + 5563.500 39.223 2.665 + 5564.000 39.310 2.715 + 5564.500 39.972 2.678 + 5565.000 39.403 2.672 + 5565.500 39.351 2.686 + 5566.000 39.264 2.704 + 5566.500 42.161 2.708 + 5567.000 46.738 2.690 + 5567.500 48.797 2.628 + 5568.000 48.054 2.532 + 5568.500 44.780 2.455 + 5569.000 42.852 2.460 + 5569.500 43.179 2.504 + 5570.000 43.364 2.632 + 5570.500 43.631 2.626 + 5571.000 46.910 2.651 + 5571.500 47.040 2.652 + 5572.000 41.165 2.621 + 5572.500 39.118 2.595 + 5573.000 33.212 2.552 + 5573.500 35.145 2.523 + 5574.000 40.655 2.460 + 5574.500 44.969 2.434 + 5575.000 50.120 2.450 + 5575.500 54.076 2.610 + 5576.000 55.896 2.600 + 5576.500 53.217 2.761 + 5577.000 49.386 2.705 + 5577.500 46.137 2.655 + 5578.000 43.878 2.627 + 5578.500 41.919 2.569 + 5579.000 40.276 2.581 + 5579.500 41.407 2.532 + 5580.000 43.672 2.445 + 5580.500 44.874 2.408 + 5581.000 45.426 2.407 + 5581.500 45.808 2.432 + 5582.000 46.153 2.468 + 5582.500 45.871 2.567 + 5583.000 44.707 2.592 + 5583.500 42.486 2.581 + 5584.000 40.910 2.565 + 5584.500 40.469 2.471 + 5585.000 42.159 2.396 + 5585.500 42.619 2.451 + 5586.000 43.415 2.721 + 5586.500 42.539 2.670 + 5587.000 42.700 2.635 + 5587.500 42.840 2.650 + 5588.000 42.291 2.444 + 5588.500 41.581 2.456 + 5589.000 41.545 2.549 + 5589.500 40.771 2.582 + 5590.000 40.190 2.574 + 5590.500 40.093 2.616 + 5591.000 39.953 2.625 + 5591.500 41.028 2.618 + 5592.000 42.790 2.548 + 5592.500 43.233 2.523 + 5593.000 43.819 2.570 + 5593.500 44.681 2.601 + 5594.000 45.377 2.681 + 5594.500 46.373 2.752 + 5595.000 45.901 2.777 + 5595.500 44.699 2.754 + 5596.000 42.840 2.712 + 5596.500 40.812 2.434 + 5597.000 39.593 2.451 + 5597.500 39.245 2.399 + 5598.000 39.290 2.452 + 5598.500 39.277 2.493 + 5599.000 39.298 2.569 + 5599.500 39.275 2.642 + 5600.000 39.133 2.686 + 5600.500 38.853 2.745 + 5601.000 37.004 2.727 + 5601.500 35.936 2.695 + 5602.000 35.251 2.635 + 5602.500 37.005 2.607 + 5603.000 38.521 2.519 + 5603.500 39.362 2.526 + 5604.000 39.206 2.566 + 5604.500 38.777 2.632 + 5605.000 37.948 2.622 + 5605.500 38.593 2.534 + 5606.000 38.586 2.545 + 5606.500 39.324 2.578 + 5607.000 39.484 2.646 + 5607.500 39.739 2.650 + 5608.000 40.574 2.671 + 5608.500 44.864 2.670 + 5609.000 48.260 2.659 + 5609.500 49.805 2.629 + 5610.000 47.486 2.567 + 5610.500 37.705 2.534 + 5611.000 36.400 2.510 + 5611.500 36.112 2.515 + 5612.000 35.426 2.550 + 5612.500 35.368 2.571 + 5613.000 35.230 2.547 + 5613.500 35.033 2.515 + 5614.000 34.910 2.606 + 5614.500 36.392 2.649 + 5615.000 37.553 2.514 + 5615.500 39.824 2.392 + 5616.000 40.105 2.345 + 5616.500 39.514 2.627 + 5617.000 39.295 2.783 + 5617.500 39.501 2.763 + 5618.000 43.662 2.747 + 5618.500 45.827 2.658 + 5619.000 47.293 2.633 + 5619.500 46.498 2.546 + 5620.000 45.489 2.399 + 5620.500 43.703 2.367 + 5621.000 45.341 2.361 + 5621.500 45.960 2.365 + 5622.000 45.235 2.440 + 5622.500 44.641 2.542 + 5623.000 43.953 2.688 + 5623.500 44.075 2.704 + 5624.000 43.865 2.556 + 5624.500 43.349 2.290 + 5625.000 44.172 2.277 + 5625.500 46.218 2.241 + 5626.000 48.676 2.375 + 5626.500 52.032 2.595 + 5627.000 52.813 2.704 + 5627.500 52.758 2.653 + 5628.000 52.854 2.641 + 5628.500 52.150 2.609 + 5629.000 52.002 2.599 + 5629.500 51.913 2.542 + 5630.000 52.779 2.516 + 5630.500 53.645 2.554 + 5631.000 53.753 2.575 + 5631.500 54.408 2.524 + 5632.000 54.163 2.491 + 5632.500 51.767 2.375 + 5633.000 49.308 2.369 + 5633.500 46.288 2.343 + 5634.000 44.958 2.429 + 5634.500 44.861 2.492 + 5635.000 44.791 2.531 + 5635.500 44.826 2.547 + 5636.000 45.512 2.529 + 5636.500 47.648 2.520 + 5637.000 49.261 2.525 + 5637.500 49.559 2.518 + 5638.000 48.001 2.525 + 5638.500 46.927 2.564 + 5639.000 46.912 2.609 + 5639.500 48.096 2.581 + 5640.000 48.825 2.537 + 5640.500 49.245 2.452 + 5641.000 49.386 2.564 + 5641.500 51.378 2.559 + 5642.000 52.153 2.527 + 5642.500 52.850 2.508 + 5643.000 52.380 2.463 + 5643.500 49.941 2.559 + 5644.000 47.899 2.552 + 5644.500 43.952 2.492 + 5645.000 43.141 2.497 + 5645.500 42.298 2.506 + 5646.000 43.255 2.480 + 5646.500 45.017 2.734 + 5647.000 46.963 2.708 + 5647.500 47.935 2.675 + 5648.000 46.684 2.600 + 5648.500 44.399 2.517 + 5649.000 42.979 2.459 + 5649.500 42.531 2.456 + 5650.000 42.441 2.494 + 5650.500 44.573 2.549 + 5651.000 45.875 2.585 + 5651.500 48.013 2.617 + 5652.000 47.639 2.562 + 5652.500 46.146 2.450 + 5653.000 44.969 2.503 + 5653.500 44.857 2.537 + 5654.000 44.933 2.629 + 5654.500 45.923 2.658 + 5655.000 46.531 2.653 + 5655.500 45.300 2.649 + 5656.000 43.070 2.630 + 5656.500 43.208 2.596 + 5657.000 43.779 2.570 + 5657.500 43.103 2.568 + 5658.000 43.815 2.573 + 5658.500 45.262 2.611 + 5659.000 46.320 2.671 + 5659.500 48.165 2.700 + 5660.000 49.014 2.686 + 5660.500 51.084 2.642 + 5661.000 52.779 2.608 + 5661.500 52.630 2.594 + 5662.000 51.311 2.559 + 5662.500 48.406 2.619 + 5663.000 47.474 2.648 + 5663.500 47.241 2.635 + 5664.000 49.277 2.572 + 5664.500 50.334 2.496 + 5665.000 51.418 2.477 + 5665.500 50.487 2.490 + 5666.000 50.272 2.578 + 5666.500 49.489 2.567 + 5667.000 49.518 2.564 + 5667.500 48.690 2.529 + 5668.000 48.811 2.517 + 5668.500 49.058 2.607 + 5669.000 49.587 2.601 + 5669.500 52.398 2.618 + 5670.000 53.400 2.620 + 5670.500 55.959 2.439 + 5671.000 55.889 2.448 + 5671.500 51.575 2.441 + 5672.000 46.579 2.478 + 5672.500 40.731 2.498 + 5673.000 39.606 2.532 + 5673.500 40.689 2.547 + 5674.000 43.459 2.601 + 5674.500 46.532 2.568 + 5675.000 45.833 2.491 + 5675.500 44.072 2.524 + 5676.000 41.975 2.499 + 5676.500 41.698 2.698 + 5677.000 43.837 2.677 + 5677.500 45.716 2.649 + 5678.000 46.696 2.610 + 5678.500 46.458 2.600 + 5679.000 43.829 2.602 + 5679.500 43.022 2.618 + 5680.000 43.304 2.658 + 5680.500 45.048 2.693 + 5681.000 44.884 2.653 + 5681.500 46.292 2.595 + 5682.000 46.990 2.581 + 5682.500 47.838 2.599 + 5683.000 48.051 2.637 + 5683.500 48.158 2.741 + 5684.000 49.381 2.737 + 5684.500 50.792 2.629 + 5685.000 52.002 2.546 + 5685.500 52.905 2.488 + 5686.000 52.706 2.510 + 5686.500 52.863 2.504 + 5687.000 52.199 2.482 + 5687.500 51.223 2.526 + 5688.000 50.367 2.564 + 5688.500 51.961 2.679 + 5689.000 52.449 2.657 + 5689.500 52.830 2.628 + 5690.000 53.085 2.621 + 5690.500 52.226 2.542 + 5691.000 49.882 2.460 + 5691.500 50.967 2.456 + 5692.000 51.914 2.562 + 5692.500 51.974 2.553 + 5693.000 52.023 2.569 + 5693.500 51.825 2.491 + 5694.000 52.421 2.498 + 5694.500 48.645 2.424 + 5695.000 46.214 2.655 + 5695.500 44.758 2.675 + 5696.000 45.939 2.666 + 5696.500 46.358 2.553 + 5697.000 45.402 2.550 + 5697.500 46.358 2.544 + 5698.000 48.962 2.522 + 5698.500 52.016 2.495 + 5699.000 51.881 2.511 + 5699.500 50.471 2.580 + 5700.000 50.617 2.606 + 5700.500 51.703 2.325 + 5701.000 51.385 2.275 + 5701.500 51.050 2.293 + 5702.000 50.138 2.486 + 5702.500 49.569 2.477 + 5703.000 49.616 2.489 + 5703.500 49.598 2.531 + 5704.000 49.618 2.658 + 5704.500 49.518 2.677 + 5705.000 50.379 2.615 + 5705.500 51.438 2.526 + 5706.000 51.555 2.506 + 5706.500 49.901 2.553 + 5707.000 49.620 2.710 + 5707.500 50.913 2.711 + 5708.000 51.843 2.585 + 5708.500 52.050 2.472 + 5709.000 51.406 2.442 + 5709.500 50.258 2.427 + 5710.000 50.723 2.513 + 5710.500 51.635 2.507 + 5711.000 52.633 2.578 + 5711.500 52.692 2.572 + 5712.000 51.156 2.721 + 5712.500 49.675 2.754 + 5713.000 49.726 2.757 + 5713.500 51.003 2.783 + 5714.000 51.841 2.797 + 5714.500 51.985 2.638 + 5715.000 51.667 2.420 + 5715.500 50.150 2.431 + 5716.000 48.410 2.481 + 5716.500 46.981 2.516 + 5717.000 49.400 2.421 + 5717.500 54.796 2.382 + 5718.000 62.032 2.343 + 5718.500 67.497 2.325 + 5719.000 65.772 2.309 + 5719.500 62.183 2.300 + 5720.000 50.564 2.538 + 5720.500 40.776 2.643 + 5721.000 38.249 2.769 + 5721.500 38.627 2.763 + 5722.000 38.434 2.751 + 5722.500 40.591 2.635 + 5723.000 42.613 2.623 + 5723.500 45.580 2.751 + 5724.000 47.307 2.834 + 5724.500 49.646 2.812 + 5725.000 48.935 2.653 + 5725.500 46.527 2.429 + 5726.000 44.668 2.257 + 5726.500 42.492 2.249 + 5727.000 41.834 2.312 + 5727.500 42.439 2.363 + 5728.000 45.555 2.259 + 5728.500 56.182 1.997 + 5729.000 66.533 1.523 + 5729.500 77.690 1.381 + 5730.000 83.188 1.712 + 5730.500 66.951 2.032 + 5731.000 56.645 2.017 + 5731.500 47.365 2.466 + 5732.000 43.487 2.497 + 5732.500 42.397 2.529 + 5733.000 44.721 2.561 + 5733.500 47.785 2.584 + 5734.000 48.729 2.629 + 5734.500 50.606 2.653 + 5735.000 50.756 2.678 + 5735.500 51.213 2.655 + 5736.000 51.805 2.592 + 5736.500 51.812 2.576 + 5737.000 51.181 2.588 + 5737.500 48.851 2.603 + 5738.000 47.923 2.612 + 5738.500 46.478 2.639 + 5739.000 46.486 2.664 + 5739.500 46.351 2.720 + 5740.000 46.563 2.690 + 5740.500 45.652 2.597 + 5741.000 43.750 2.557 + 5741.500 40.872 2.529 + 5742.000 40.755 2.565 + 5742.500 42.114 2.581 + 5743.000 43.309 2.562 + 5743.500 43.062 2.534 + 5744.000 40.557 2.507 + 5744.500 38.697 2.532 + 5745.000 37.048 2.543 + 5745.500 36.656 2.532 + 5746.000 35.942 2.502 + 5746.500 35.233 2.376 + 5747.000 35.637 2.361 + 5747.500 39.030 2.415 + 5748.000 41.566 2.511 + 5748.500 45.871 2.540 + 5749.000 46.969 2.579 + 5749.500 47.343 2.618 + 5750.000 47.258 2.590 + 5750.500 47.755 2.578 + 5751.000 47.979 2.570 + 5751.500 48.774 2.564 + 5752.000 49.743 2.529 + 5752.500 48.545 2.498 + 5753.000 46.354 2.468 + 5753.500 40.692 2.518 + 5754.000 36.974 2.542 + 5754.500 34.712 2.669 + 5755.000 35.442 2.746 + 5755.500 36.309 2.733 + 5756.000 37.714 2.665 + 5756.500 40.835 2.393 + 5757.000 44.210 2.330 + 5757.500 48.807 2.399 + 5758.000 54.068 2.430 + 5758.500 71.095 2.477 + 5759.000 69.460 2.474 + 5759.500 65.726 2.460 + 5760.000 63.646 2.446 + 5760.500 62.992 2.388 + 5761.000 65.986 2.343 + 5761.500 68.090 2.301 + 5762.000 64.884 2.258 + 5762.500 55.933 2.400 + 5763.000 47.568 2.527 + 5763.500 46.542 2.708 + 5764.000 45.858 2.689 + 5764.500 46.354 2.613 + 5765.000 46.266 2.575 + 5765.500 45.564 2.558 + 5766.000 45.749 2.573 + 5766.500 47.041 2.563 + 5767.000 48.521 2.541 + 5767.500 50.377 2.514 + 5768.000 50.384 2.492 + 5768.500 47.717 2.432 + 5769.000 43.235 2.284 + 5769.500 41.207 2.313 + 5770.000 40.584 2.387 + 5770.500 43.445 2.520 + 5771.000 43.783 2.527 + 5771.500 43.983 2.551 + 5772.000 43.345 2.623 + 5772.500 43.342 2.709 + 5773.000 42.514 2.703 + 5773.500 40.920 2.702 + 5774.000 40.937 2.701 + 5774.500 40.921 2.681 + 5775.000 42.327 2.640 + 5775.500 43.215 2.617 + 5776.000 44.136 2.646 + 5776.500 44.039 2.739 + 5777.000 44.045 2.775 + 5777.500 44.012 2.763 + 5778.000 44.092 2.720 + 5778.500 43.305 2.700 + 5779.000 45.400 2.691 + 5779.500 46.155 2.639 + 5780.000 47.057 2.601 + 5780.500 46.173 2.538 + 5781.000 45.807 2.522 + 5781.500 47.197 2.527 + 5782.000 46.953 2.511 + 5782.500 44.930 2.635 + 5783.000 44.206 2.613 + 5783.500 44.120 2.579 + 5784.000 43.498 2.491 + 5784.500 44.877 2.480 + 5785.000 48.109 2.478 + 5785.500 48.206 2.475 + 5786.000 47.619 2.488 + 5786.500 45.153 2.553 + 5787.000 44.934 2.604 + 5787.500 44.409 2.615 + 5788.000 44.322 2.518 + 5788.500 43.414 2.539 + 5789.000 42.625 2.565 + 5789.500 42.594 2.602 + 5790.000 44.792 2.525 + 5790.500 48.067 2.445 + 5791.000 48.307 2.382 + 5791.500 47.201 2.396 + 5792.000 46.256 2.358 + 5792.500 44.949 2.796 + 5793.000 44.855 2.773 + 5793.500 44.817 2.649 + 5794.000 45.026 2.577 + 5794.500 45.620 2.613 + 5795.000 46.309 2.684 + 5795.500 45.801 2.679 + 5796.000 45.797 2.641 + 5796.500 46.477 2.635 + 5797.000 46.527 2.629 + 5797.500 45.546 2.615 + 5798.000 44.869 2.605 + 5798.500 42.035 2.633 + 5799.000 41.733 2.643 + 5799.500 41.446 2.654 + 5800.000 40.788 2.661 + 5800.500 40.985 2.607 + 5801.000 40.224 2.439 + 5801.500 39.893 2.321 + 5802.000 39.531 2.343 + 5802.500 38.616 2.389 + 5803.000 38.549 2.567 + 5803.500 38.385 2.558 + 5804.000 38.977 2.515 + 5804.500 38.365 2.462 + 5805.000 37.865 2.436 + 5805.500 37.038 2.416 + 5806.000 36.286 2.406 + 5806.500 34.996 2.550 + 5807.000 39.120 2.538 + 5807.500 43.515 2.378 + 5808.000 50.456 2.383 + 5808.500 53.045 2.319 + 5809.000 51.746 2.347 + 5809.500 49.868 2.318 + 5810.000 48.677 2.344 + 5810.500 47.207 2.378 + 5811.000 45.907 2.400 + 5811.500 44.530 2.472 + 5812.000 45.633 2.463 + 5812.500 53.845 2.456 + 5813.000 71.157 2.370 + 5813.500 79.481 2.199 + 5814.000 82.179 2.090 + 5814.500 77.786 2.234 + 5815.000 66.249 2.214 + 5815.500 57.717 2.531 + 5816.000 52.667 2.515 + 5816.500 45.047 2.473 + 5817.000 41.315 2.581 + 5817.500 38.623 2.721 + 5818.000 38.316 2.702 + 5818.500 37.568 2.658 + 5819.000 37.698 2.588 + 5819.500 37.710 2.523 + 5820.000 37.711 2.456 + 5820.500 39.955 2.454 + 5821.000 41.485 2.550 + 5821.500 41.875 2.645 + 5822.000 40.408 2.698 + 5822.500 39.249 2.775 + 5823.000 36.881 2.791 + 5823.500 36.257 2.806 + 5824.000 34.640 2.805 + 5824.500 33.723 2.795 + 5825.000 32.845 2.756 + 5825.500 32.941 2.752 + 5826.000 32.917 2.745 + 5826.500 32.998 2.655 + 5827.000 35.420 2.578 + 5827.500 39.069 2.589 + 5828.000 42.476 2.643 + 5828.500 43.254 2.660 + 5829.000 40.310 2.637 + 5829.500 36.818 2.530 + 5830.000 34.491 2.350 + 5830.500 35.618 2.398 + 5831.000 41.390 2.436 + 5831.500 49.931 2.426 + 5832.000 65.721 2.356 + 5832.500 63.944 2.395 + 5833.000 55.750 2.536 + 5833.500 49.257 2.597 + 5834.000 47.107 2.528 + 5834.500 46.606 2.450 + 5835.000 46.331 2.404 + 5835.500 45.071 2.402 + 5836.000 42.721 2.545 + 5836.500 43.824 2.592 + 5837.000 48.940 2.643 + 5837.500 54.973 2.529 + 5838.000 65.819 2.501 + 5838.500 72.342 2.581 + 5839.000 67.855 2.656 + 5839.500 56.315 2.718 + 5840.000 46.149 2.735 + 5840.500 32.453 2.611 + 5841.000 30.914 2.620 + 5841.500 29.603 2.550 + 5842.000 30.411 2.451 + 5842.500 33.922 2.515 + 5843.000 35.509 2.548 + 5843.500 36.801 2.589 + 5844.000 38.195 2.628 + 5844.500 39.351 2.643 + 5845.000 40.199 2.670 + 5845.500 41.616 2.684 + 5846.000 41.816 2.682 + 5846.500 43.193 2.648 + 5847.000 43.871 2.641 + 5847.500 43.557 2.634 + 5848.000 42.494 2.599 + 5848.500 43.003 2.591 + 5849.000 44.450 2.601 + 5849.500 48.345 2.603 + 5850.000 51.113 2.287 + 5850.500 55.339 1.993 + 5851.000 60.934 2.013 + 5851.500 60.063 1.984 + 5852.000 58.965 2.295 + 5852.500 57.289 2.416 + 5853.000 55.328 2.513 + 5853.500 54.466 2.495 + 5854.000 53.525 2.497 + 5854.500 55.129 2.422 + 5855.000 57.502 2.427 + 5855.500 60.054 2.416 + 5856.000 60.919 2.472 + 5856.500 61.615 2.526 + 5857.000 61.403 2.520 + 5857.500 62.708 2.507 + 5858.000 63.542 2.579 + 5858.500 61.437 2.682 + 5859.000 59.856 2.677 + 5859.500 57.094 2.659 + 5860.000 55.103 2.554 + 5860.500 53.603 2.558 + 5861.000 52.092 2.640 + 5861.500 51.845 2.625 + 5862.000 53.350 2.604 + 5862.500 55.145 2.599 + 5863.000 56.713 2.646 + 5863.500 56.593 2.651 + 5864.000 55.036 2.575 + 5864.500 52.848 2.500 + 5865.000 52.694 2.432 + 5865.500 53.975 2.426 + 5866.000 54.928 2.422 + 5866.500 53.442 2.426 + 5867.000 50.979 2.443 + 5867.500 48.682 2.438 + 5868.000 47.957 2.532 + 5868.500 48.024 2.550 + 5869.000 48.117 2.485 + 5869.500 49.568 2.252 + 5870.000 51.441 2.259 + 5870.500 52.095 2.388 + 5871.000 51.389 2.437 + 5871.500 51.039 2.505 + 5872.000 52.584 2.519 + 5872.500 53.726 2.583 + 5873.000 53.024 2.656 + 5873.500 52.008 2.649 + 5874.000 50.996 2.635 + 5874.500 52.000 2.498 + 5875.000 53.110 2.485 + 5875.500 52.894 2.487 + 5876.000 52.284 2.519 + 5876.500 46.246 2.512 + 5877.000 44.728 2.491 + 5877.500 45.372 2.487 + 5878.000 48.615 2.488 + 5878.500 52.370 2.515 + 5879.000 51.566 2.528 + 5879.500 50.159 2.544 + 5880.000 51.425 2.573 + 5880.500 52.986 2.555 + 5881.000 52.032 2.560 + 5881.500 50.377 2.601 + 5882.000 48.930 2.604 + 5882.500 48.443 2.569 + 5883.000 47.674 2.490 + 5883.500 45.693 2.558 + 5884.000 43.240 2.608 + 5884.500 43.294 2.666 + 5885.000 43.234 2.642 + 5885.500 43.184 2.589 + 5886.000 44.181 2.604 + 5886.500 45.819 2.695 + 5887.000 45.036 2.711 + 5887.500 43.656 2.716 + 5888.000 40.225 2.707 + 5888.500 39.289 2.656 + 5889.000 39.397 2.623 + 5889.500 40.495 2.557 + 5890.000 43.897 2.489 + 5890.500 47.359 2.498 + 5891.000 48.378 2.528 + 5891.500 47.259 2.626 + 5892.000 42.613 2.621 + 5892.500 36.311 2.640 + 5893.000 32.777 2.671 + 5893.500 33.250 2.696 + 5894.000 33.678 2.580 + 5894.500 34.305 2.392 + 5895.000 34.532 2.408 + 5895.500 34.674 2.367 + 5896.000 35.363 2.364 + 5896.500 35.323 2.415 + 5897.000 35.247 2.436 + 5897.500 35.859 2.517 + 5898.000 36.901 2.503 + 5898.500 37.879 2.614 + 5899.000 37.365 2.622 + 5899.500 37.496 2.599 + 5900.000 39.035 2.701 + 5900.500 47.223 2.721 + 5901.000 50.781 2.560 + 5901.500 48.489 2.535 + 5902.000 40.407 2.400 + 5902.500 33.519 2.319 + 5903.000 29.370 2.353 + 5903.500 28.132 2.352 + 5904.000 28.152 2.336 + 5904.500 28.166 2.395 + 5905.000 28.149 2.428 + 5905.500 28.159 2.520 + 5906.000 28.166 2.502 + 5906.500 28.170 2.444 + 5907.000 28.175 2.478 + 5907.500 28.175 2.469 + 5908.000 28.175 2.539 + 5908.500 28.175 2.573 + 5909.000 28.175 2.588 + 5909.500 28.175 2.590 + 5910.000 28.175 2.564 + 5910.500 28.174 2.464 + 5911.000 28.174 2.474 + 5911.500 28.178 2.457 + 5912.000 28.169 2.397 + 5912.500 28.175 2.346 + 5913.000 28.193 2.407 + 5913.500 28.114 2.517 + 5914.000 28.808 2.634 + 5914.500 28.837 2.642 + 5915.000 28.091 2.625 + 5915.500 28.177 2.615 + 5916.000 28.389 2.488 + 5916.500 28.405 2.473 + 5917.000 28.188 2.460 + 5917.500 28.043 2.447 + 5918.000 28.941 2.481 + 5918.500 28.281 2.556 + 5919.000 28.246 2.672 + 5919.500 28.228 2.642 + 5920.000 29.034 2.674 + 5920.500 26.529 2.123 + 5921.000 25.583 2.141 + 5921.500 24.859 2.141 + 5922.000 23.439 2.141 + 5922.500 23.517 2.034 + 5923.000 23.505 1.983 + 5923.500 26.409 1.971 + 5924.000 27.250 1.968 + 5924.500 29.034 1.988 + 5925.000 30.520 1.957 + 5925.500 32.122 1.934 + 5926.000 33.656 1.993 + 5926.500 32.979 1.998 + 5927.000 29.973 2.030 + 5927.500 26.395 2.123 + 5928.000 22.723 2.114 + 5928.500 20.204 2.082 + 5929.000 18.309 1.999 + 5929.500 16.471 1.979 + 5930.000 16.450 1.848 + 5930.500 18.012 1.854 + 5931.000 19.373 2.002 + 5931.500 19.303 1.995 + 5932.000 20.026 2.181 + 5932.500 18.733 2.166 + 5933.000 18.178 2.048 + 5933.500 18.995 1.990 + 5934.000 19.260 1.979 + 5934.500 22.917 1.966 + 5935.000 24.155 1.964 + 5935.500 27.214 1.980 + 5936.000 28.036 1.998 + 5936.500 27.503 2.031 + 5937.000 25.404 2.048 + 5937.500 22.543 2.059 + 5938.000 21.412 1.994 + 5938.500 24.326 1.964 + 5939.000 30.092 1.863 + 5939.500 34.556 1.839 + 5940.000 37.957 1.763 + 5940.500 33.492 1.862 + 5941.000 30.017 1.852 + 5941.500 25.260 2.043 + 5942.000 22.413 1.989 + 5942.500 20.156 2.059 + 5943.000 19.264 2.054 + 5943.500 18.600 2.075 + 5944.000 18.555 2.059 + 5944.500 19.285 2.040 + 5945.000 19.575 2.033 + 5945.500 20.563 2.032 + 5946.000 20.820 2.026 + 5946.500 20.144 2.015 + 5947.000 20.280 1.982 + 5947.500 20.243 1.925 + 5948.000 20.075 1.923 + 5948.500 19.174 1.890 + 5949.000 18.679 1.885 + 5949.500 18.131 1.885 + 5950.000 20.633 1.901 + 5950.500 22.787 1.903 + 5951.000 27.531 1.897 + 5951.500 30.650 1.863 + 5952.000 32.944 1.868 + 5952.500 32.193 1.861 + 5953.000 25.042 1.901 + 5953.500 19.935 1.927 + 5954.000 17.592 1.957 + 5954.500 16.705 1.937 + 5955.000 18.915 1.931 + 5955.500 19.048 1.926 + 5956.000 21.174 1.913 + 5956.500 21.819 1.903 + 5957.000 21.707 1.892 + 5957.500 20.803 1.882 + 5958.000 20.019 1.877 + 5958.500 19.412 1.877 + 5959.000 19.496 1.875 + 5959.500 19.181 1.873 + 5960.000 19.870 1.872 + 5960.500 21.819 1.895 + 5961.000 21.269 1.909 + 5961.500 20.358 1.932 + 5962.000 20.282 1.947 + 5962.500 19.626 1.982 + 5963.000 19.447 1.961 + 5963.500 19.178 1.948 + 5964.000 19.532 1.936 + 5964.500 21.330 1.919 + 5965.000 21.897 1.929 + 5965.500 21.255 1.915 + 5966.000 20.375 1.876 + 5966.500 20.680 2.008 + 5967.000 23.126 1.995 + 5967.500 26.539 2.035 + 5968.000 28.157 2.132 + 5968.500 27.482 2.099 + 5969.000 24.526 2.023 + 5969.500 20.600 1.989 + 5970.000 21.065 1.975 + 5970.500 19.241 1.954 + 5971.000 17.203 1.964 + 5971.500 17.710 1.978 + 5972.000 19.046 1.990 + 5972.500 18.498 1.987 + 5973.000 17.192 1.987 + 5973.500 17.042 1.989 + 5974.000 17.572 1.958 + 5974.500 18.532 1.887 + 5975.000 18.803 1.923 + 5975.500 19.525 1.944 + 5976.000 19.489 1.986 + 5976.500 18.754 2.043 + 5977.000 18.833 2.073 + 5977.500 17.299 2.071 + 5978.000 17.196 2.067 + 5978.500 16.309 2.073 + 5979.000 16.394 2.096 + 5979.500 15.732 2.116 + 5980.000 16.353 2.154 + 5980.500 15.872 2.225 + 5981.000 15.501 2.311 + 5981.500 15.414 2.329 + 5982.000 16.264 2.324 + 5982.500 17.105 2.273 + 5983.000 17.689 2.231 + 5983.500 17.643 2.201 + 5984.000 17.297 2.159 + 5984.500 16.744 2.147 + 5985.000 15.592 2.127 + 5985.500 15.458 2.169 + 5986.000 15.584 2.198 + 5986.500 16.448 2.237 + 5987.000 15.714 2.254 + 5987.500 16.392 2.276 + 5988.000 16.202 2.328 + 5988.500 16.150 2.287 + 5989.000 15.402 2.304 + 5989.500 15.338 2.218 + 5990.000 15.130 2.204 + 5990.500 16.008 2.243 + 5991.000 15.551 2.299 + 5991.500 16.376 2.317 + 5992.000 16.279 2.343 + 5992.500 15.635 2.287 + 5993.000 15.673 2.235 + 5993.500 16.202 2.205 + 5994.000 17.022 2.201 + 5994.500 16.371 2.214 + 5995.000 16.210 2.259 + 5995.500 15.379 2.265 + 5996.000 16.134 2.274 + 5996.500 15.401 2.311 + 5997.000 15.114 2.321 + 5997.500 13.999 2.335 + 5998.000 13.926 2.343 + 5998.500 13.519 2.363 + 5999.000 12.909 2.338 + 5999.500 12.833 2.370 + 6000.000 11.252 2.031 + 6000.500 11.979 2.086 + 6001.000 12.300 2.127 + 6001.500 12.272 2.280 + 6002.000 13.054 2.446 + 6002.500 13.987 2.659 + 6003.000 13.881 2.637 + 6003.500 13.754 2.598 + 6004.000 12.960 2.570 + 6004.500 13.224 2.664 + 6005.000 12.618 2.702 + 6005.500 13.072 2.710 + 6006.000 13.784 2.714 + 6006.500 13.227 2.696 + 6007.000 13.138 2.678 + 6007.500 12.397 2.664 + 6008.000 12.243 2.692 + 6008.500 10.735 2.692 + 6009.000 11.229 2.692 + 6009.500 11.632 2.688 + 6010.000 12.583 2.692 + 6010.500 13.137 2.694 + 6011.000 14.731 2.696 + 6011.500 16.073 2.693 + 6012.000 19.733 2.690 + 6012.500 20.729 2.690 + 6013.000 21.772 2.675 + 6013.500 21.244 2.651 + 6014.000 20.905 2.659 + 6014.500 19.908 2.696 + 6015.000 19.594 2.690 + 6015.500 18.216 2.679 + 6016.000 17.068 2.669 + 6016.500 16.417 2.682 + 6017.000 18.249 2.747 + 6017.500 18.736 2.765 + 6018.000 20.109 2.773 + 6018.500 19.664 2.768 + 6019.000 19.168 2.754 + 6019.500 17.976 2.737 + 6020.000 16.030 2.707 + 6020.500 14.513 2.708 + 6021.000 14.756 2.713 + 6021.500 14.647 2.720 + 6022.000 14.458 2.704 + 6022.500 14.080 2.685 + 6023.000 14.853 2.652 + 6023.500 18.502 2.642 + 6024.000 21.352 2.638 + 6024.500 26.689 2.677 + 6025.000 26.396 2.699 + 6025.500 24.779 2.704 + 6026.000 21.537 2.709 + 6026.500 20.119 2.732 + 6027.000 17.758 2.727 + 6027.500 15.736 2.712 + 6028.000 14.186 2.710 + 6028.500 13.790 2.696 + 6029.000 14.040 2.676 + 6029.500 13.317 2.644 + 6030.000 13.482 2.630 + 6030.500 9.823 2.638 + 6031.000 10.916 2.673 + 6031.500 11.207 2.670 + 6032.000 11.914 2.678 + 6032.500 9.770 2.626 + 6033.000 9.189 2.614 + 6033.500 8.456 2.599 + 6034.000 8.449 2.582 + 6034.500 9.445 2.575 + 6035.000 9.309 2.603 + 6035.500 8.969 2.615 + 6036.000 8.261 2.687 + 6036.500 8.158 2.712 + 6037.000 8.017 2.718 + 6037.500 9.136 2.696 + 6038.000 10.041 2.677 + 6038.500 9.861 2.622 + 6039.000 9.927 2.591 + 6039.500 10.092 2.575 + 6040.000 10.733 2.573 + 6040.500 11.330 2.612 + 6041.000 11.359 2.644 + 6041.500 10.663 2.645 + 6042.000 10.731 2.643 + 6042.500 10.702 2.656 + 6043.000 10.756 2.674 + 6043.500 11.640 2.689 + 6044.000 12.208 2.665 + 6044.500 11.263 2.617 + 6045.000 10.652 2.609 + 6045.500 10.756 2.655 + 6046.000 11.685 2.668 + 6046.500 11.743 2.663 + 6047.000 11.434 2.657 + 6047.500 11.536 2.662 + 6048.000 14.330 2.674 + 6048.500 18.807 2.694 + 6049.000 19.340 2.701 + 6049.500 20.268 2.708 + 6050.000 20.952 2.708 + 6050.500 22.028 2.709 + 6051.000 24.027 2.711 + 6051.500 25.913 2.717 + 6052.000 26.114 2.728 + 6052.500 25.183 2.740 + 6053.000 24.368 2.720 + 6053.500 24.464 2.705 + 6054.000 26.706 2.695 + 6054.500 27.472 2.698 + 6055.000 26.293 2.698 + 6055.500 22.093 2.694 + 6056.000 19.061 2.686 + 6056.500 16.082 2.672 + 6057.000 15.373 2.671 + 6057.500 15.988 2.684 + 6058.000 15.517 2.706 + 6058.500 16.332 2.747 + 6059.000 16.928 2.753 + 6059.500 16.840 2.763 + 6060.000 18.535 2.749 + 6060.500 17.259 2.678 + 6061.000 15.485 2.664 + 6061.500 14.360 2.645 + 6062.000 13.791 2.623 + 6062.500 12.477 2.631 + 6063.000 13.796 2.656 + 6063.500 16.254 2.715 + 6064.000 17.496 2.743 + 6064.500 17.973 2.722 + 6065.000 17.074 2.670 + 6065.500 16.357 2.651 + 6066.000 16.745 2.657 + 6066.500 16.332 2.677 + 6067.000 15.050 2.704 + 6067.500 14.522 2.713 + 6068.000 13.706 2.708 + 6068.500 12.150 2.701 + 6069.000 10.612 2.683 + 6069.500 9.042 2.659 + 6070.000 8.363 2.632 + 6070.500 8.569 2.626 + 6071.000 9.300 2.631 + 6071.500 7.740 2.654 + 6072.000 8.818 2.729 + 6072.500 9.482 2.729 + 6073.000 9.996 2.715 + 6073.500 12.010 2.660 + 6074.000 11.975 2.640 + 6074.500 12.967 2.640 + 6075.000 13.346 2.650 + 6075.500 14.892 2.664 + 6076.000 14.615 2.678 + 6076.500 14.591 2.680 + 6077.000 13.386 2.674 + 6077.500 13.893 2.675 + 6078.000 14.402 2.696 + 6078.500 13.220 2.703 + 6079.000 12.581 2.720 + 6079.500 11.729 2.715 + 6080.000 12.677 2.705 + 6080.500 11.778 2.692 + 6081.000 10.853 2.687 + 6081.500 10.019 2.684 + 6082.000 9.814 2.686 + 6082.500 9.004 2.709 + 6083.000 9.031 2.737 + 6083.500 8.195 2.773 + 6084.000 8.833 2.762 + 6084.500 9.753 2.751 + 6085.000 10.644 2.742 + 6085.500 11.024 2.711 + 6086.000 11.739 2.692 + 6086.500 11.718 2.675 + 6087.000 11.391 2.669 + 6087.500 10.509 2.675 + 6088.000 11.429 2.695 + 6088.500 11.539 2.687 + 6089.000 11.372 2.675 + 6089.500 11.674 2.659 + 6090.000 8.787 2.668 + 6090.500 9.648 2.680 + 6091.000 9.672 2.680 + 6091.500 9.495 2.684 + 6092.000 10.013 2.685 + 6092.500 9.845 2.674 + 6093.000 9.865 2.665 + 6093.500 9.288 2.681 + 6094.000 9.769 2.706 + 6094.500 9.838 2.711 + 6095.000 10.593 2.699 + 6095.500 10.665 2.697 + 6096.000 11.421 2.691 + 6096.500 13.021 2.719 + 6097.000 13.271 2.725 + 6097.500 13.884 2.715 + 6098.000 14.447 2.701 + 6098.500 13.013 2.692 + 6099.000 12.239 2.695 + 6099.500 12.393 2.700 + 6100.000 11.713 2.714 + 6100.500 12.509 2.704 + 6101.000 13.394 2.680 + 6101.500 13.854 2.686 + 6102.000 14.555 2.710 + 6102.500 14.710 2.764 + 6103.000 16.333 2.776 + 6103.500 15.482 2.769 + 6104.000 15.692 2.754 + 6104.500 14.174 2.733 + 6105.000 13.763 2.734 + 6105.500 14.967 2.737 + 6106.000 16.772 2.742 + 6106.500 19.776 2.717 + 6107.000 21.880 2.698 + 6107.500 22.503 2.690 + 6108.000 21.856 2.684 + 6108.500 21.211 2.686 + 6109.000 20.875 2.694 + 6109.500 20.738 2.703 + 6110.000 20.968 2.700 + 6110.500 19.704 2.690 + 6111.000 17.692 2.679 + 6111.500 15.338 2.671 + 6112.000 14.552 2.674 + 6112.500 14.840 2.678 + 6113.000 13.891 2.673 + 6113.500 14.550 2.670 + 6114.000 15.486 2.669 + 6114.500 20.227 2.678 + 6115.000 21.726 2.689 + 6115.500 23.347 2.692 + 6116.000 23.703 2.691 + 6116.500 21.222 2.680 + 6117.000 22.100 2.684 + 6117.500 21.925 2.701 + 6118.000 26.933 2.712 + 6118.500 29.582 2.719 + 6119.000 30.635 2.723 + 6119.500 30.449 2.726 + 6120.000 29.429 2.741 + 6120.500 28.291 2.746 + 6121.000 27.125 2.739 + 6121.500 26.852 2.725 + 6122.000 27.071 2.717 + 6122.500 30.511 2.714 + 6123.000 32.312 2.714 + 6123.500 33.964 2.713 + 6124.000 33.443 2.714 + 6124.500 31.303 2.727 + 6125.000 28.986 2.759 + 6125.500 25.559 2.761 + 6126.000 22.550 2.758 + 6126.500 20.533 2.754 + 6127.000 17.691 2.746 + 6127.500 18.732 2.738 + 6128.000 19.824 2.727 + 6128.500 24.500 2.700 + 6129.000 27.527 2.715 + 6129.500 28.174 2.731 + 6130.000 27.848 2.749 + 6130.500 20.233 2.776 + 6131.000 16.880 2.781 + 6131.500 14.581 2.766 + 6132.000 12.623 2.725 + 6132.500 12.273 2.684 + 6133.000 12.342 2.674 + 6133.500 12.191 2.670 + 6134.000 15.166 2.694 + 6134.500 14.852 2.720 + 6135.000 14.120 2.687 + 6135.500 13.760 2.658 + 6136.000 12.110 2.621 + 6136.500 9.897 2.648 + 6137.000 8.453 2.674 + 6137.500 8.996 2.702 + 6138.000 9.054 2.734 + 6138.500 9.705 2.760 + 6139.000 10.541 2.768 + 6139.500 10.761 2.758 + 6140.000 10.708 2.729 + 6140.500 10.536 2.526 + 6141.000 9.938 2.532 + 6141.500 9.158 2.512 + 6142.000 8.079 2.502 + 6142.500 7.477 2.491 + 6143.000 7.690 2.493 + 6143.500 9.037 2.557 + 6144.000 11.405 2.584 + 6144.500 12.388 2.594 + 6145.000 12.290 2.595 + 6145.500 12.309 2.602 + 6146.000 11.829 2.650 + 6146.500 10.252 2.677 + 6147.000 9.242 2.690 + 6147.500 7.534 2.684 + 6148.000 7.541 2.675 + 6148.500 8.554 2.647 + 6149.000 10.923 2.641 + 6149.500 9.082 2.635 + 6150.000 9.089 2.621 + 6150.500 7.613 2.601 + 6151.000 7.545 2.596 + 6151.500 7.529 2.604 + 6152.000 7.685 2.618 + 6152.500 8.415 2.623 + 6153.000 8.299 2.625 + 6153.500 8.326 2.630 + 6154.000 8.339 2.634 + 6154.500 8.342 2.618 + 6155.000 8.260 2.606 + 6155.500 9.052 2.539 + 6156.000 10.774 2.524 + 6156.500 11.584 2.552 + 6157.000 11.505 2.592 + 6157.500 11.414 2.610 + 6158.000 12.298 2.636 + 6158.500 13.938 2.667 + 6159.000 16.946 2.696 + 6159.500 16.963 2.724 + 6160.000 17.480 2.751 + 6160.500 16.370 2.761 + 6161.000 15.544 2.759 + 6161.500 16.573 2.749 + 6162.000 17.032 2.743 + 6162.500 17.633 2.726 + 6163.000 18.668 2.722 + 6163.500 19.448 2.735 + 6164.000 19.683 2.746 + 6164.500 17.429 2.735 + 6165.000 15.215 2.723 + 6165.500 13.776 2.713 + 6166.000 13.473 2.714 + 6166.500 13.849 2.735 + 6167.000 15.183 2.725 + 6167.500 16.993 2.714 + 6168.000 19.674 2.748 + 6168.500 22.189 2.759 + 6169.000 22.682 2.766 + 6169.500 22.428 2.765 + 6170.000 21.625 2.770 + 6170.500 21.324 2.719 + 6171.000 21.442 2.697 + 6171.500 20.171 2.688 + 6172.000 19.897 2.713 + 6172.500 16.843 2.731 + 6173.000 16.223 2.741 + 6173.500 16.295 2.741 + 6174.000 16.559 2.727 + 6174.500 17.975 2.694 + 6175.000 18.190 2.725 + 6175.500 18.780 2.735 + 6176.000 17.222 2.758 + 6176.500 14.224 2.770 + 6177.000 12.636 2.698 + 6177.500 12.316 2.733 + 6178.000 14.216 2.593 + 6178.500 17.016 2.603 + 6179.000 18.250 2.588 + 6179.500 17.045 2.596 + 6180.000 15.465 2.619 + 6180.500 13.929 2.684 + 6181.000 12.241 2.710 + 6181.500 11.292 2.725 + 6182.000 10.494 2.749 + 6182.500 9.854 2.719 + 6183.000 9.954 2.709 + 6183.500 9.952 2.697 + 6184.000 11.626 2.690 + 6184.500 12.408 2.682 + 6185.000 13.812 2.604 + 6185.500 13.444 2.534 + 6186.000 13.098 2.465 + 6186.500 12.548 2.412 + 6187.000 12.144 2.441 + 6187.500 11.398 2.479 + 6188.000 11.610 2.501 + 6188.500 10.921 2.472 + 6189.000 9.970 2.465 + 6189.500 9.283 2.458 + 6190.000 10.024 2.451 + 6190.500 10.687 2.445 + 6191.000 11.309 2.447 + 6191.500 11.227 2.472 + 6192.000 10.922 2.556 + 6192.500 11.491 2.572 + 6193.000 10.164 2.585 + 6193.500 9.798 2.586 + 6194.000 4.903 2.588 + 6194.500 6.644 2.634 + 6195.000 5.957 2.664 + 6195.500 6.230 2.712 + 6196.000 6.660 2.753 + 6196.500 7.491 2.715 + 6197.000 6.797 2.649 + 6197.500 7.412 2.654 + 6198.000 7.580 2.511 + 6198.500 7.155 2.527 + 6199.000 6.582 2.512 + 6199.500 5.214 2.580 + 6200.000 3.109 2.617 + 6200.500 6.044 2.637 + 6201.000 6.099 2.656 + 6201.500 5.832 2.666 + 6202.000 5.644 2.681 + 6202.500 6.113 2.696 + 6203.000 7.103 2.710 + 6203.500 7.403 2.713 + 6204.000 7.392 2.703 + 6204.500 6.512 2.650 + 6205.000 6.103 2.637 + 6205.500 6.219 2.641 + 6206.000 6.044 2.663 + 6206.500 6.867 2.680 + 6207.000 6.656 2.674 + 6207.500 7.191 2.652 + 6208.000 6.767 2.649 + 6208.500 6.159 2.662 + 6209.000 5.722 2.668 + 6209.500 5.504 2.677 + 6210.000 6.193 2.680 + 6210.500 7.228 2.679 + 6211.000 8.207 2.663 + 6211.500 8.256 2.643 + 6212.000 8.968 2.625 + 6212.500 9.218 2.632 + 6213.000 8.475 2.641 + 6213.500 8.309 2.645 + 6214.000 8.602 2.647 + 6214.500 7.880 2.634 + 6215.000 7.805 2.646 + 6215.500 7.657 2.664 + 6216.000 7.963 2.671 + 6216.500 8.094 2.664 + 6217.000 8.350 2.652 + 6217.500 8.872 2.656 + 6218.000 9.811 2.667 + 6218.500 9.326 2.676 + 6219.000 7.982 2.678 + 6219.500 8.084 2.688 + 6220.000 8.760 2.690 + 6220.500 9.188 2.682 + 6221.000 9.127 2.671 + 6221.500 9.080 2.651 + 6222.000 9.200 2.638 + 6222.500 8.679 2.650 + 6223.000 8.609 2.666 + 6223.500 8.260 2.641 + 6224.000 8.716 2.623 + 6224.500 8.787 2.593 + 6225.000 8.315 2.602 + 6225.500 8.121 2.625 + 6226.000 8.103 2.656 + 6226.500 8.404 2.680 + 6227.000 8.089 2.694 + 6227.500 8.113 2.724 + 6228.000 8.001 2.750 + 6228.500 7.854 2.747 + 6229.000 8.312 2.725 + 6229.500 7.063 2.718 + 6230.000 8.488 2.713 + 6230.500 6.691 2.721 + 6231.000 5.959 2.733 + 6231.500 6.633 2.746 + 6232.000 7.210 2.742 + 6232.500 6.944 2.713 + 6233.000 7.555 2.689 + 6233.500 7.596 2.692 + 6234.000 6.862 2.703 + 6234.500 7.200 2.712 + 6235.000 8.239 2.705 + 6235.500 7.773 2.698 + 6236.000 5.734 2.690 + 6236.500 6.293 2.683 + 6237.000 5.863 2.675 + 6237.500 5.949 2.665 + 6238.000 5.979 2.671 + 6238.500 5.932 2.689 + 6239.000 5.962 2.733 + 6239.500 5.940 2.738 + 6240.000 5.952 2.727 + 6240.500 5.995 2.716 + 6241.000 5.747 2.721 + 6241.500 5.497 2.729 + 6242.000 5.745 2.734 + 6242.500 5.996 2.720 + 6243.000 5.946 2.700 + 6243.500 5.946 2.689 + 6244.000 5.969 2.684 + 6244.500 5.667 2.682 + 6245.000 5.321 2.678 + 6245.500 6.173 2.653 + 6246.000 6.851 2.619 + 6246.500 6.624 2.550 + 6247.000 6.769 2.565 + 6247.500 6.328 2.605 + 6248.000 6.844 2.620 + 6248.500 6.820 2.671 + 6249.000 7.825 2.687 + 6249.500 7.009 2.698 + 6250.000 6.493 2.707 + 6250.500 6.228 2.725 + 6251.000 5.293 2.762 + 6251.500 5.150 2.777 + 6252.000 5.124 2.710 + 6252.500 5.426 2.637 + 6253.000 7.192 2.588 + 6253.500 6.790 2.599 + 6254.000 7.321 2.686 + 6254.500 5.997 2.705 + 6255.000 6.022 2.713 + 6255.500 5.922 2.692 + 6256.000 6.160 2.671 + 6256.500 6.370 2.710 + 6257.000 6.745 2.714 + 6257.500 6.108 2.719 + 6258.000 5.925 2.696 + 6258.500 6.020 2.671 + 6259.000 5.318 2.698 + 6259.500 5.133 2.719 + 6260.000 5.211 2.726 + 6260.500 4.532 2.732 + 6261.000 4.359 2.696 + 6261.500 4.325 2.688 + 6262.000 4.526 2.686 + 6262.500 5.390 2.717 + 6263.000 6.007 2.731 + 6263.500 5.897 2.734 + 6264.000 6.046 2.764 + 6264.500 5.306 2.770 + 6265.000 5.164 2.710 + 6265.500 5.136 2.680 + 6266.000 5.177 2.654 + 6266.500 5.147 2.673 + 6267.000 5.154 2.701 + 6267.500 5.189 2.706 + 6268.000 5.073 2.694 + 6268.500 5.809 2.651 + 6269.000 5.944 2.650 + 6269.500 5.976 2.644 + 6270.000 5.940 2.645 + 6270.500 5.956 2.648 + 6271.000 5.955 2.653 + 6271.500 5.951 2.671 + 6272.000 5.954 2.695 + 6272.500 5.952 2.706 + 6273.000 5.952 2.693 + 6273.500 5.952 2.687 + 6274.000 5.950 2.686 + 6274.500 5.951 2.690 + 6275.000 5.954 2.709 + 6275.500 5.943 2.713 + 6276.000 5.960 2.704 + 6276.500 5.983 2.686 + 6277.000 6.566 2.677 + 6277.500 7.135 2.677 + 6278.000 7.544 2.681 + 6278.500 7.537 2.681 + 6279.000 7.541 2.684 + 6279.500 7.546 2.695 + 6280.000 7.542 2.709 + 6280.500 7.529 2.716 + 6281.000 7.573 2.724 + 6281.500 7.513 2.737 + 6282.000 7.413 2.748 + 6282.500 6.694 2.748 + 6283.000 6.543 2.749 + 6283.500 6.492 2.732 + 6284.000 6.859 2.712 + 6284.500 6.067 2.650 + 6285.000 6.032 2.654 + 6285.500 5.430 2.660 + 6286.000 6.039 2.712 + 6286.500 5.925 2.733 + 6287.000 5.944 2.738 + 6287.500 5.801 2.730 + 6288.000 5.202 2.708 + 6288.500 6.222 2.657 + 6289.000 6.828 2.645 + 6289.500 7.201 2.631 + 6290.000 8.257 2.631 + 6290.500 8.728 2.631 + 6291.000 9.823 2.630 + 6291.500 9.906 2.621 + 6292.000 9.950 2.594 + 6292.500 9.907 2.590 + 6293.000 9.950 2.592 + 6293.500 9.893 2.595 + 6294.000 9.842 2.605 + 6294.500 8.426 2.628 + 6295.000 7.811 2.645 + 6295.500 6.922 2.651 + 6296.000 6.550 2.632 + 6296.500 8.193 2.645 + 6297.000 9.339 2.697 + 6297.500 9.987 2.722 + 6298.000 9.920 2.772 + 6298.500 9.321 2.735 + 6299.000 8.589 2.698 + 6299.500 7.670 2.667 + 6300.000 7.483 2.655 + 6300.500 11.477 2.562 + 6301.000 17.888 2.487 + 6301.500 18.872 2.382 + 6302.000 16.629 2.390 + 6302.500 14.226 2.447 + 6303.000 11.033 2.543 + 6303.500 10.739 2.594 + 6304.000 10.661 2.580 + 6304.500 10.762 2.554 + 6305.000 10.637 2.559 + 6305.500 14.001 2.607 + 6306.000 18.995 2.695 + 6306.500 24.492 2.705 + 6307.000 27.261 2.726 + 6307.500 25.128 2.730 + 6308.000 19.051 2.668 + 6308.500 15.638 2.441 + 6309.000 11.680 2.395 + 6309.500 11.516 2.406 + 6310.000 10.910 2.401 + 6310.500 10.666 2.556 + 6311.000 10.787 2.610 + 6311.500 11.590 2.619 + 6312.000 11.725 2.625 + 6312.500 14.993 2.628 + 6313.000 17.730 2.632 + 6313.500 21.537 2.633 + 6314.000 20.669 2.633 + 6314.500 20.008 2.633 + 6315.000 16.554 2.632 + 6315.500 13.903 2.623 + 6316.000 14.554 2.615 + 6316.500 14.662 2.601 + 6317.000 14.709 2.601 + 6317.500 14.684 2.602 + 6318.000 14.633 2.600 + 6318.500 14.649 2.609 + 6319.000 13.072 2.645 + 6319.500 13.084 2.700 + 6320.000 11.548 2.753 + 6320.500 11.260 2.744 + 6321.000 10.805 2.729 + 6321.500 12.220 2.706 + 6322.000 17.133 2.678 + 6322.500 22.323 2.674 + 6323.000 29.414 2.668 + 6323.500 34.596 2.652 + 6324.000 39.614 2.624 + 6324.500 42.657 2.663 + 6325.000 44.138 2.799 + 6325.500 39.739 2.874 + 6326.000 38.527 2.869 + 6326.500 20.234 2.740 + 6327.000 15.054 2.676 + 6327.500 12.675 2.630 + 6328.000 13.758 2.612 + 6328.500 15.966 2.565 + 6329.000 17.571 2.569 + 6329.500 17.244 2.584 + 6330.000 15.771 2.610 + 6330.500 13.661 2.639 + 6331.000 14.100 2.662 + 6331.500 14.757 2.669 + 6332.000 14.964 2.673 + 6332.500 16.038 2.670 + 6333.000 17.098 2.657 + 6333.500 18.196 2.633 + 6334.000 20.083 2.650 + 6334.500 21.497 2.706 + 6335.000 21.776 2.707 + 6335.500 22.527 2.719 + 6336.000 22.602 2.732 + 6336.500 22.660 2.726 + 6337.000 22.599 2.641 + 6337.500 22.696 2.568 + 6338.000 20.937 2.516 + 6338.500 18.399 2.569 + 6339.000 14.606 2.561 + 6339.500 13.751 2.540 + 6340.000 12.680 2.500 + 6340.500 12.668 2.567 + 6341.000 10.947 2.642 + 6341.500 10.761 2.684 + 6342.000 10.527 2.702 + 6342.500 11.911 2.693 + 6343.000 13.044 2.664 + 6343.500 15.502 2.567 + 6344.000 18.115 2.540 + 6344.500 22.238 2.599 + 6345.000 25.925 2.590 + 6345.500 25.740 2.650 + 6346.000 25.359 2.656 + 6346.500 21.046 2.590 + 6347.000 19.331 2.611 + 6347.500 18.367 2.623 + 6348.000 17.812 2.648 + 6348.500 17.933 2.613 + 6349.000 17.236 2.564 + 6349.500 17.170 2.579 + 6350.000 17.704 2.642 + 6350.500 15.354 2.679 + 6351.000 13.862 2.660 + 6351.500 13.088 2.644 + 6352.000 12.400 2.555 + 6352.500 13.207 2.503 + 6353.000 15.393 2.583 + 6353.500 16.058 2.654 + 6354.000 16.269 2.704 + 6354.500 14.035 2.720 + 6355.000 12.443 2.707 + 6355.500 11.735 2.640 + 6356.000 10.873 2.573 + 6356.500 10.673 2.542 + 6357.000 10.753 2.530 + 6357.500 10.152 2.556 + 6358.000 9.263 2.588 + 6358.500 9.119 2.654 + 6359.000 9.102 2.658 + 6359.500 9.116 2.672 + 6360.000 9.286 2.679 + 6360.500 10.120 2.692 + 6361.000 10.769 2.698 + 6361.500 10.809 2.702 + 6362.000 11.612 2.699 + 6362.500 11.471 2.677 + 6363.000 11.457 2.662 + 6363.500 11.657 2.658 + 6364.000 11.420 2.656 + 6364.500 17.276 2.667 + 6365.000 22.595 2.678 + 6365.500 23.067 2.690 + 6366.000 20.592 2.693 + 6366.500 16.246 2.660 + 6367.000 13.836 2.642 + 6367.500 12.532 2.634 + 6368.000 11.596 2.673 + 6368.500 11.382 2.748 + 6369.000 10.582 2.773 + 6369.500 10.576 2.774 + 6370.000 10.696 2.761 + 6370.500 12.949 2.683 + 6371.000 14.139 2.649 + 6371.500 17.219 2.594 + 6372.000 19.245 2.583 + 6372.500 19.392 2.634 + 6373.000 19.421 2.707 + 6373.500 16.521 2.775 + 6374.000 13.884 2.787 + 6374.500 14.122 2.748 + 6375.000 15.213 2.709 + 6375.500 18.854 2.679 + 6376.000 20.142 2.645 + 6376.500 21.825 2.622 + 6377.000 21.641 2.619 + 6377.500 20.943 2.672 + 6378.000 21.059 2.736 + 6378.500 21.263 2.750 + 6379.000 21.215 2.737 + 6379.500 21.120 2.716 + 6380.000 20.992 2.706 + 6380.500 23.019 2.772 + 6381.000 23.159 2.767 + 6381.500 23.271 2.799 + 6382.000 22.437 2.780 + 6382.500 19.480 2.656 + 6383.000 17.926 2.629 + 6383.500 16.438 2.532 + 6384.000 18.020 2.443 + 6384.500 22.648 2.451 + 6385.000 25.000 2.430 + 6385.500 26.414 2.566 + 6386.000 25.297 2.726 + 6386.500 23.724 2.716 + 6387.000 21.943 2.826 + 6387.500 20.187 2.840 + 6388.000 18.437 2.876 + 6388.500 16.696 2.852 + 6389.000 15.504 2.858 + 6389.500 14.435 2.743 + 6390.000 14.342 2.725 + 6390.500 13.682 2.700 + 6391.000 12.693 2.704 + 6391.500 11.378 2.628 + 6392.000 11.862 2.619 + 6392.500 13.706 2.602 + 6393.000 17.570 2.607 + 6393.500 19.785 2.639 + 6394.000 19.816 2.672 + 6394.500 18.595 2.688 + 6395.000 17.787 2.694 + 6395.500 16.812 2.655 + 6396.000 15.801 2.630 + 6396.500 15.638 2.592 + 6397.000 16.426 2.580 + 6397.500 17.678 2.682 + 6398.000 18.615 2.718 + 6398.500 19.660 2.751 + 6399.000 21.025 2.743 + 6399.500 22.438 2.747 + 6400.000 23.961 2.772 + 6400.500 24.838 2.724 + 6401.000 21.059 2.708 + 6401.500 19.106 2.703 + 6402.000 19.070 2.693 + 6402.500 19.421 2.725 + 6403.000 21.693 2.759 + 6403.500 21.860 2.782 + 6404.000 22.826 2.785 + 6404.500 21.976 2.760 + 6405.000 21.290 2.747 + 6405.500 20.373 2.734 + 6406.000 20.141 2.730 + 6406.500 19.257 2.731 + 6407.000 19.397 2.732 + 6407.500 16.272 2.713 + 6408.000 14.367 2.670 + 6408.500 12.056 2.665 + 6409.000 12.227 2.668 + 6409.500 13.524 2.715 + 6410.000 15.563 2.724 + 6410.500 18.430 2.715 + 6411.000 21.104 2.701 + 6411.500 25.308 2.700 + 6412.000 29.324 2.702 + 6412.500 29.300 2.772 + 6413.000 27.130 2.767 + 6413.500 23.006 2.695 + 6414.000 23.161 2.703 + 6414.500 18.921 2.628 + 6415.000 16.705 2.701 + 6415.500 15.386 2.739 + 6416.000 13.677 2.781 + 6416.500 12.788 2.671 + 6417.000 12.834 2.615 + 6417.500 13.254 2.566 + 6418.000 14.102 2.484 + 6418.500 14.830 2.476 + 6419.000 14.766 2.598 + 6419.500 15.715 2.645 + 6420.000 17.684 2.684 + 6420.500 19.761 2.710 + 6421.000 20.692 2.701 + 6421.500 23.145 2.684 + 6422.000 26.424 2.674 + 6422.500 27.023 2.690 + 6423.000 25.882 2.746 + 6423.500 22.091 2.757 + 6424.000 21.511 2.772 + 6424.500 19.116 2.759 + 6425.000 21.490 2.707 + 6425.500 22.656 2.704 + 6426.000 24.748 2.710 + 6426.500 22.503 2.724 + 6427.000 21.214 2.729 + 6427.500 20.457 2.735 + 6428.000 19.236 2.738 + 6428.500 20.207 2.752 + 6429.000 21.913 2.768 + 6429.500 23.230 2.764 + 6430.000 23.029 2.770 + 6430.500 18.471 2.686 + 6431.000 17.076 2.625 + 6431.500 15.800 2.576 + 6432.000 16.428 2.555 + 6432.500 15.834 2.589 + 6433.000 15.340 2.666 + 6433.500 15.722 2.671 + 6434.000 16.442 2.672 + 6434.500 17.473 2.677 + 6435.000 19.773 2.683 + 6435.500 20.442 2.681 + 6436.000 21.238 2.678 + 6436.500 22.547 2.752 + 6437.000 22.645 2.777 + 6437.500 22.015 2.802 + 6438.000 18.326 2.787 + 6438.500 13.646 2.727 + 6439.000 12.241 2.669 + 6439.500 14.142 2.601 + 6440.000 15.403 2.614 + 6440.500 17.095 2.668 + 6441.000 19.656 2.663 + 6441.500 22.110 2.691 + 6442.000 23.281 2.707 + 6442.500 23.538 2.747 + 6443.000 22.032 2.734 + 6443.500 20.825 2.717 + 6444.000 18.484 2.721 + 6444.500 16.430 2.715 + 6445.000 15.646 2.793 + 6445.500 15.395 2.799 + 6446.000 15.604 2.770 + 6446.500 14.339 2.581 + 6447.000 14.913 2.524 + 6447.500 15.486 2.557 + 6448.000 15.484 2.573 + 6448.500 15.443 2.634 + 6449.000 15.556 2.630 + 6449.500 14.863 2.589 + 6450.000 14.234 2.558 + 6450.500 13.438 2.573 + 6451.000 12.418 2.666 + 6451.500 12.315 2.661 + 6452.000 12.371 2.614 + 6452.500 14.216 2.619 + 6453.000 16.224 2.628 + 6453.500 16.296 2.679 + 6454.000 15.438 2.647 + 6454.500 13.948 2.528 + 6455.000 13.874 2.499 + 6455.500 16.099 2.416 + 6456.000 17.250 2.391 + 6456.500 19.100 2.590 + 6457.000 18.505 2.560 + 6457.500 18.544 2.676 + 6458.000 20.719 2.566 + 6458.500 21.763 2.544 + 6459.000 21.063 2.559 + 6459.500 19.632 2.655 + 6460.000 18.374 2.732 + 6460.500 16.951 2.745 + 6461.000 15.970 2.809 + 6461.500 13.809 2.797 + 6462.000 12.321 2.757 + 6462.500 11.310 2.620 + 6463.000 12.269 2.625 + 6463.500 13.959 2.609 + 6464.000 15.030 2.608 + 6464.500 18.154 2.678 + 6465.000 17.386 2.727 + 6465.500 14.322 2.744 + 6466.000 11.760 2.760 + 6466.500 10.873 2.767 + 6467.000 10.619 2.789 + 6467.500 11.498 2.775 + 6468.000 12.338 2.733 + 6468.500 12.847 2.698 + 6469.000 13.633 2.679 + 6469.500 15.358 2.678 + 6470.000 18.451 2.686 + 6470.500 19.195 2.721 + 6471.000 20.958 2.738 + 6471.500 21.606 2.762 + 6472.000 20.124 2.763 + 6472.500 19.552 2.782 + 6473.000 18.488 2.751 + 6473.500 19.285 2.732 + 6474.000 19.603 2.709 + 6474.500 20.471 2.673 + 6475.000 21.130 2.665 + 6475.500 20.237 2.680 + 6476.000 19.365 2.717 + 6476.500 19.292 2.724 + 6477.000 18.688 2.728 + 6477.500 19.772 2.742 + 6478.000 20.276 2.748 + 6478.500 22.305 2.780 + 6479.000 23.386 2.784 + 6479.500 24.330 2.782 + 6480.000 24.170 2.769 + 6480.500 23.779 2.739 + 6481.000 23.326 2.711 + 6481.500 22.819 2.627 + 6482.000 22.338 2.549 + 6482.500 21.850 2.413 + 6483.000 21.395 2.426 + 6483.500 20.889 2.414 + 6484.000 19.899 2.552 + 6484.500 20.229 2.706 + 6485.000 21.269 2.697 + 6485.500 24.273 2.727 + 6486.000 27.369 2.729 + 6486.500 29.648 2.721 + 6487.000 28.830 2.696 + 6487.500 26.495 2.688 + 6488.000 23.302 2.647 + 6488.500 21.631 2.608 + 6489.000 20.006 2.579 + 6489.500 18.657 2.526 + 6490.000 17.213 2.532 + 6490.500 16.617 2.601 + 6491.000 16.186 2.643 + 6491.500 16.983 2.647 + 6492.000 18.514 2.652 + 6492.500 19.446 2.691 + 6493.000 20.171 2.697 + 6493.500 19.937 2.723 + 6494.000 19.621 2.752 + 6494.500 19.028 2.766 + 6495.000 16.732 2.746 + 6495.500 15.403 2.731 + 6496.000 14.714 2.735 + 6496.500 14.057 2.621 + 6497.000 13.708 2.630 + 6497.500 15.129 2.525 + 6498.000 16.806 2.509 + 6498.500 19.455 2.570 + 6499.000 21.019 2.581 + 6499.500 23.070 2.596 + 6500.000 26.720 2.617 + 6500.500 27.818 2.644 + 6501.000 27.023 2.652 + 6501.500 24.727 2.666 + 6502.000 21.723 2.658 + 6502.500 21.946 2.780 + 6503.000 21.786 2.771 + 6503.500 21.812 2.725 + 6504.000 20.481 2.675 + 6504.500 18.590 2.671 + 6505.000 16.700 2.696 + 6505.500 14.884 2.700 + 6506.000 13.183 2.714 + 6506.500 13.077 2.694 + 6507.000 13.062 2.674 + 6507.500 13.259 2.659 + 6508.000 13.879 2.689 + 6508.500 14.454 2.675 + 6509.000 15.365 2.600 + 6509.500 17.111 2.552 + 6510.000 18.856 2.565 + 6510.500 20.051 2.612 + 6511.000 25.240 2.682 + 6511.500 27.311 2.739 + 6512.000 26.495 2.750 + 6512.500 23.445 2.764 + 6513.000 21.827 2.765 + 6513.500 20.103 2.767 + 6514.000 19.048 2.761 + 6514.500 16.433 2.725 + 6515.000 13.731 2.679 + 6515.500 10.671 2.604 + 6516.000 9.876 2.602 + 6516.500 9.973 2.593 + 6517.000 9.811 2.585 + 6517.500 12.250 2.581 + 6518.000 14.449 2.588 + 6518.500 20.757 2.655 + 6519.000 22.076 2.684 + 6519.500 21.845 2.714 + 6520.000 21.218 2.714 + 6520.500 17.804 2.753 + 6521.000 16.665 2.788 + 6521.500 14.643 2.773 + 6522.000 14.604 2.747 + 6522.500 15.481 2.708 + 6523.000 16.550 2.691 + 6523.500 19.542 2.698 + 6524.000 21.772 2.718 + 6524.500 24.568 2.706 + 6525.000 28.367 2.697 + 6525.500 29.665 2.706 + 6526.000 29.337 2.741 + 6526.500 24.671 2.750 + 6527.000 19.922 2.742 + 6527.500 15.004 2.733 + 6528.000 12.884 2.710 + 6528.500 12.134 2.702 + 6529.000 14.174 2.605 + 6529.500 16.578 2.598 + 6530.000 18.779 2.571 + 6530.500 25.003 2.667 + 6531.000 26.325 2.750 + 6531.500 26.724 2.780 + 6532.000 24.853 2.791 + 6532.500 21.546 2.796 + 6533.000 19.186 2.797 + 6533.500 18.632 2.804 + 6534.000 19.652 2.808 + 6534.500 19.955 2.752 + 6535.000 25.798 2.724 + 6535.500 27.566 2.706 + 6536.000 27.433 2.710 + 6536.500 24.170 2.739 + 6537.000 22.253 2.760 + 6537.500 20.848 2.772 + 6538.000 20.342 2.778 + 6538.500 17.368 2.779 + 6539.000 16.894 2.764 + 6539.500 14.653 2.721 + 6540.000 13.936 2.683 + 6540.500 12.026 2.652 + 6541.000 11.680 2.617 + 6541.500 13.747 2.619 + 6542.000 16.015 2.613 + 6542.500 20.339 2.627 + 6543.000 21.153 2.691 + 6543.500 20.204 2.709 + 6544.000 19.413 2.741 + 6544.500 19.403 2.746 + 6545.000 20.038 2.747 + 6545.500 20.873 2.747 + 6546.000 21.715 2.747 + 6546.500 24.019 2.755 + 6547.000 24.216 2.757 + 6547.500 21.163 2.756 + 6548.000 20.478 2.758 + 6548.500 15.887 2.746 + 6549.000 13.168 2.743 + 6549.500 12.494 2.709 + 6550.000 11.809 2.698 + 6550.500 12.059 2.751 + 6551.000 10.719 2.720 + 6551.500 10.617 2.665 + 6552.000 9.939 2.608 + 6552.500 11.453 2.569 + 6553.000 13.497 2.582 + 6553.500 15.487 2.601 + 6554.000 17.094 2.720 + 6554.500 18.363 2.734 + 6555.000 18.513 2.721 + 6555.500 18.847 2.726 + 6556.000 18.290 2.720 + 6556.500 19.452 2.776 + 6557.000 20.713 2.766 + 6557.500 22.092 2.723 + 6558.000 24.813 2.696 + 6558.500 25.610 2.671 + 6559.000 25.152 2.723 + 6559.500 23.407 2.742 + 6560.000 20.968 2.769 + 6560.500 17.808 2.733 + 6561.000 15.033 2.377 + 6561.500 15.769 2.340 + 6562.000 16.721 2.350 + 6562.500 20.589 2.519 + 6563.000 22.968 2.539 + 6563.500 27.202 2.572 + 6564.000 29.754 2.589 + 6564.500 32.466 2.684 + 6565.000 33.146 2.663 + 6565.500 31.448 2.656 + 6566.000 30.295 2.643 + 6566.500 25.929 2.631 + 6567.000 21.942 2.604 + 6567.500 19.248 2.564 + 6568.000 20.165 2.527 + 6568.500 22.356 2.567 + 6569.000 27.871 2.594 + 6569.500 28.659 2.669 + 6570.000 29.039 2.724 + 6570.500 26.761 2.820 + 6571.000 25.681 2.817 + 6571.500 24.521 2.724 + 6572.000 21.899 2.755 + 6572.500 16.754 2.625 + 6573.000 15.291 2.655 + 6573.500 14.501 2.651 + 6574.000 14.893 2.664 + 6574.500 15.548 2.605 + 6575.000 15.416 2.643 + 6575.500 15.464 2.501 + 6576.000 17.278 2.475 + 6576.500 18.663 2.604 + 6577.000 19.035 2.595 + 6577.500 17.512 2.627 + 6578.000 18.612 2.637 + 6578.500 18.827 2.646 + 6579.000 19.219 2.660 + 6579.500 21.672 2.659 + 6580.000 24.701 2.571 + 6580.500 32.720 2.604 + 6581.000 38.637 2.647 + 6581.500 41.787 2.692 + 6582.000 41.400 2.765 + 6582.500 41.068 2.752 + 6583.000 40.187 2.738 + 6583.500 37.655 2.723 + 6584.000 33.669 2.708 + 6584.500 24.529 2.774 + 6585.000 21.254 2.789 + 6585.500 17.558 2.798 + 6586.000 17.147 2.822 + 6586.500 17.058 2.783 + 6587.000 19.020 2.741 + 6587.500 21.367 2.676 + 6588.000 21.708 2.606 + 6588.500 20.362 2.532 + 6589.000 19.255 2.521 + 6589.500 19.109 2.544 + 6590.000 20.985 2.650 + 6590.500 22.694 2.675 + 6591.000 23.599 2.690 + 6591.500 24.771 2.703 + 6592.000 23.773 2.713 + 6592.500 22.496 2.711 + 6593.000 20.807 2.666 + 6593.500 19.049 2.650 + 6594.000 17.799 2.711 + 6594.500 19.389 2.737 + 6595.000 19.989 2.779 + 6595.500 20.819 2.771 + 6596.000 21.650 2.759 + 6596.500 21.930 2.753 + 6597.000 21.209 2.758 + 6597.500 20.257 2.764 + 6598.000 19.596 2.720 + 6598.500 19.234 2.633 + 6599.000 18.627 2.587 + 6599.500 19.843 2.568 + 6600.000 20.724 2.560 + 6600.500 21.103 2.626 + 6601.000 22.818 2.702 + 6601.500 24.495 2.762 + 6602.000 22.782 2.789 + 6602.500 21.036 2.772 + 6603.000 18.847 2.666 + 6603.500 14.793 2.648 + 6604.000 13.817 2.587 + 6604.500 14.288 2.620 + 6605.000 17.454 2.630 + 6605.500 20.872 2.643 + 6606.000 20.948 2.642 + 6606.500 21.126 2.653 + 6607.000 20.842 2.661 + 6607.500 20.620 2.641 + 6608.000 21.921 2.599 + 6608.500 20.770 2.556 + 6609.000 22.668 2.566 + 6609.500 22.365 2.589 + 6610.000 21.778 2.661 + 6610.500 21.349 2.719 + 6611.000 20.453 2.717 + 6611.500 19.637 2.702 + 6612.000 18.617 2.670 + 6612.500 15.534 2.589 + 6613.000 14.033 2.573 + 6613.500 13.784 2.569 + 6614.000 14.560 2.587 + 6614.500 14.585 2.673 + 6615.000 15.207 2.684 + 6615.500 14.514 2.691 + 6616.000 14.809 2.683 + 6616.500 14.063 2.661 + 6617.000 13.712 2.649 + 6617.500 15.337 2.642 + 6618.000 19.028 2.618 + 6618.500 22.977 2.629 + 6619.000 25.261 2.668 + 6619.500 26.814 2.701 + 6620.000 27.420 2.721 + 6620.500 25.203 2.734 + 6621.000 21.670 2.706 + 6621.500 20.834 2.632 + 6622.000 20.444 2.610 + 6622.500 19.500 2.577 + 6623.000 17.957 2.601 + 6623.500 17.961 2.602 + 6624.000 18.996 2.603 + 6624.500 20.883 2.615 + 6625.000 25.012 2.683 + 6625.500 28.590 2.729 + 6626.000 29.169 2.707 + 6626.500 26.310 2.699 + 6627.000 22.787 2.697 + 6627.500 17.846 2.698 + 6628.000 14.624 2.693 + 6628.500 13.075 2.689 + 6629.000 13.198 2.658 + 6629.500 15.112 2.644 + 6630.000 18.561 2.596 + 6630.500 20.928 2.629 + 6631.000 24.483 2.725 + 6631.500 31.788 2.742 + 6632.000 39.632 2.724 + 6632.500 43.440 2.736 + 6633.000 42.552 2.800 + 6633.500 40.690 2.865 + 6634.000 38.037 2.837 + 6634.500 31.879 2.776 + 6635.000 28.059 2.733 + 6635.500 25.132 2.735 + 6636.000 22.605 2.742 + 6636.500 27.052 2.764 + 6637.000 29.989 2.773 + 6637.500 34.091 2.781 + 6638.000 34.624 2.789 + 6638.500 32.977 2.795 + 6639.000 31.105 2.796 + 6639.500 29.762 2.796 + 6640.000 28.210 2.797 + 6640.500 26.997 2.794 + 6641.000 25.876 2.791 + 6641.500 25.882 2.788 + 6642.000 25.202 2.784 + 6642.500 24.083 2.773 + 6643.000 23.438 2.762 + 6643.500 24.181 2.715 + 6644.000 26.340 2.813 + 6644.500 25.962 2.827 + 6645.000 22.643 2.854 + 6645.500 19.901 2.853 + 6646.000 19.215 2.650 + 6646.500 21.021 2.659 + 6647.000 23.559 2.653 + 6647.500 28.918 2.720 + 6648.000 30.591 2.773 + 6648.500 30.546 2.797 + 6649.000 29.148 2.788 + 6649.500 27.734 2.770 + 6650.000 26.191 2.757 + 6650.500 24.888 2.728 + 6651.000 22.871 2.718 + 6651.500 22.684 2.717 + 6652.000 22.449 2.751 + 6652.500 23.342 2.768 + 6653.000 23.520 2.766 + 6653.500 24.159 2.753 + 6654.000 23.425 2.731 + 6654.500 21.976 2.694 + 6655.000 20.063 2.683 + 6655.500 17.131 2.636 + 6656.000 16.263 2.608 + 6656.500 14.031 2.633 + 6657.000 14.000 2.645 + 6657.500 13.732 2.663 + 6658.000 14.388 2.671 + 6658.500 13.793 2.679 + 6659.000 14.040 2.692 + 6659.500 14.909 2.704 + 6660.000 15.767 2.725 + 6660.500 18.548 2.690 + 6661.000 19.906 2.663 + 6661.500 20.003 2.659 + 6662.000 20.288 2.701 + 6662.500 20.325 2.753 + 6663.000 20.940 2.739 + 6663.500 20.941 2.697 + 6664.000 19.633 2.769 + 6664.500 18.649 2.757 + 6665.000 17.601 2.746 + 6665.500 17.624 2.665 + 6666.000 20.086 2.571 + 6666.500 21.349 2.578 + 6667.000 22.367 2.619 + 6667.500 21.820 2.661 + 6668.000 20.906 2.697 + 6668.500 19.433 2.699 + 6669.000 20.420 2.683 + 6669.500 21.973 2.675 + 6670.000 24.743 2.677 + 6670.500 27.488 2.675 + 6671.000 26.743 2.665 + 6671.500 25.875 2.660 + 6672.000 24.775 2.677 + 6672.500 26.244 2.757 + 6673.000 27.107 2.791 + 6673.500 26.331 2.811 + 6674.000 25.777 2.817 + 6674.500 26.058 2.818 + 6675.000 27.564 2.817 + 6675.500 27.509 2.790 + 6676.000 28.097 2.773 + 6676.500 29.594 2.802 + 6677.000 31.308 2.823 + 6677.500 32.772 2.885 + 6678.000 31.218 2.861 + 6678.500 26.952 2.768 + 6679.000 25.926 2.622 + 6679.500 26.822 2.626 + 6680.000 28.741 2.639 + 6680.500 28.939 2.728 + 6681.000 28.699 2.764 + 6681.500 27.370 2.791 + 6682.000 27.616 2.800 + 6682.500 28.252 2.813 + 6683.000 29.678 2.825 + 6683.500 29.609 2.857 + 6684.000 28.975 2.847 + 6684.500 27.928 2.801 + 6685.000 25.266 2.808 + 6685.500 22.092 2.799 + 6686.000 22.155 2.790 + 6686.500 19.567 2.739 + 6687.000 18.426 2.688 + 6687.500 17.186 2.645 + 6688.000 16.776 2.691 + 6688.500 23.363 2.810 + 6689.000 22.861 2.827 + 6689.500 33.780 2.832 + 6690.000 33.196 2.819 + 6690.500 32.933 2.774 + 6691.000 31.968 2.783 + 6691.500 31.937 2.806 + 6692.000 32.261 2.817 + 6692.500 33.604 2.836 + 6693.000 32.669 2.858 + 6693.500 31.130 2.801 + 6694.000 26.623 2.810 + 6694.500 21.098 2.738 + 6695.000 17.284 2.732 + 6695.500 16.264 2.722 + 6696.000 17.216 2.731 + 6696.500 17.075 2.767 + 6697.000 17.917 2.760 + 6697.500 16.509 2.730 + 6698.000 17.035 2.701 + 6698.500 15.935 2.657 + 6699.000 18.169 2.672 + 6699.500 21.293 2.705 + 6700.000 24.625 2.699 + 6700.500 28.395 2.678 + 6701.000 30.471 2.617 + 6701.500 31.893 2.593 + 6702.000 29.857 2.699 + 6702.500 27.235 2.779 + 6703.000 25.918 2.819 + 6703.500 26.537 2.822 + 6704.000 26.055 2.804 + 6704.500 24.237 2.789 + 6705.000 22.356 2.771 + 6705.500 21.093 2.746 + 6706.000 21.123 2.717 + 6706.500 20.364 2.689 + 6707.000 18.515 2.663 + 6707.500 17.722 2.633 + 6708.000 17.095 2.605 + 6708.500 19.502 2.574 + 6709.000 24.567 2.587 + 6709.500 29.679 2.626 + 6710.000 35.144 2.687 + 6710.500 43.713 2.741 + 6711.000 51.071 2.777 + 6711.500 53.285 2.799 + 6712.000 49.206 2.810 + 6712.500 35.347 2.820 + 6713.000 31.173 2.822 + 6713.500 25.993 2.814 + 6714.000 26.481 2.805 + 6714.500 29.777 2.769 + 6715.000 29.533 2.760 + 6715.500 26.245 2.764 + 6716.000 20.811 2.776 + 6716.500 19.314 2.798 + 6717.000 20.207 2.796 + 6717.500 21.686 2.808 + 6718.000 24.860 2.807 + 6718.500 27.376 2.802 + 6719.000 28.153 2.797 + 6719.500 27.511 2.798 + 6720.000 27.304 2.825 + 6720.500 25.414 2.839 + 6721.000 23.443 2.838 + 6721.500 22.029 2.783 + 6722.000 21.409 2.694 + 6722.500 20.334 2.684 + 6723.000 21.738 2.688 + 6723.500 23.147 2.753 + 6724.000 26.803 2.815 + 6724.500 33.047 2.813 + 6725.000 35.197 2.802 + 6725.500 33.202 2.783 + 6726.000 29.288 2.773 + 6726.500 22.691 2.789 + 6727.000 21.362 2.794 + 6727.500 20.680 2.796 + 6728.000 25.978 2.798 + 6728.500 30.152 2.804 + 6729.000 33.233 2.815 + 6729.500 32.795 2.805 + 6730.000 30.662 2.760 + 6730.500 27.023 2.752 + 6731.000 26.843 2.774 + 6731.500 31.348 2.790 + 6732.000 33.103 2.805 + 6732.500 30.615 2.824 + 6733.000 28.657 2.827 + 6733.500 23.959 2.835 + 6734.000 20.773 2.845 + 6734.500 16.830 2.871 + 6735.000 15.410 2.925 + 6735.500 17.289 2.960 + 6736.000 22.905 2.949 + 6736.500 31.163 2.955 + 6737.000 32.085 2.838 + 6737.500 31.718 2.830 + 6738.000 30.095 2.819 + 6738.500 29.745 2.815 + 6739.000 32.018 2.812 + 6739.500 34.435 2.806 + 6740.000 37.044 2.803 + 6740.500 38.573 2.798 + 6741.000 34.246 2.807 + 6741.500 28.983 2.823 + 6742.000 22.189 2.834 + 6742.500 20.784 2.844 + 6743.000 20.756 2.838 + 6743.500 23.222 2.821 + 6744.000 27.046 2.811 + 6744.500 32.868 2.792 + 6745.000 35.280 2.784 + 6745.500 34.273 2.784 + 6746.000 31.258 2.790 + 6746.500 26.842 2.810 + 6747.000 24.291 2.817 + 6747.500 23.699 2.826 + 6748.000 24.662 2.829 + 6748.500 27.414 2.836 + 6749.000 29.407 2.837 + 6749.500 32.219 2.840 + 6750.000 32.636 2.830 + 6750.500 33.383 2.792 + 6751.000 33.713 2.799 + 6751.500 36.523 2.799 + 6752.000 39.098 2.819 + 6752.500 39.204 2.859 + 6753.000 37.337 2.862 + 6753.500 32.691 2.849 + 6754.000 29.499 2.839 + 6754.500 26.423 2.827 + 6755.000 24.860 2.832 + 6755.500 27.214 2.830 + 6756.000 28.799 2.827 + 6756.500 28.825 2.816 + 6757.000 27.284 2.814 + 6757.500 24.986 2.815 + 6758.000 24.872 2.820 + 6758.500 26.744 2.820 + 6759.000 29.275 2.819 + 6759.500 29.870 2.818 + 6760.000 29.956 2.816 + 6760.500 31.381 2.810 + 6761.000 31.284 2.805 + 6761.500 33.709 2.794 + 6762.000 34.509 2.792 + 6762.500 35.446 2.795 + 6763.000 34.618 2.810 + 6763.500 32.951 2.843 + 6764.000 30.591 2.838 + 6764.500 27.643 2.836 + 6765.000 24.401 2.829 + 6765.500 23.349 2.825 + 6766.000 23.581 2.824 + 6766.500 26.084 2.826 + 6767.000 27.558 2.823 + 6767.500 26.717 2.822 + 6768.000 28.404 2.823 + 6768.500 30.825 2.826 + 6769.000 34.449 2.828 + 6769.500 36.797 2.830 + 6770.000 37.374 2.830 + 6770.500 36.256 2.831 + 6771.000 35.514 2.840 + 6771.500 35.187 2.857 + 6772.000 35.850 2.853 + 6772.500 34.758 2.826 + 6773.000 33.747 2.818 + 6773.500 34.555 2.814 + 6774.000 39.287 2.815 + 6774.500 48.996 2.822 + 6775.000 51.204 2.828 + 6775.500 47.743 2.830 + 6776.000 39.441 2.822 + 6776.500 29.938 2.813 + 6777.000 27.184 2.817 + 6777.500 25.986 2.821 + 6778.000 25.968 2.826 + 6778.500 24.388 2.832 + 6779.000 22.521 2.834 + 6779.500 22.477 2.828 + 6780.000 26.243 2.819 + 6780.500 29.750 2.814 + 6781.000 32.787 2.808 + 6781.500 35.142 2.795 + 6782.000 34.664 2.778 + 6782.500 34.562 2.788 + 6783.000 35.329 2.809 + 6783.500 37.376 2.830 + 6784.000 39.894 2.830 + 6784.500 38.057 2.820 + 6785.000 34.112 2.812 + 6785.500 28.766 2.814 + 6786.000 27.391 2.815 + 6786.500 26.686 2.816 + 6787.000 27.820 2.812 + 6787.500 30.567 2.814 + 6788.000 31.131 2.822 + 6788.500 31.267 2.830 + 6789.000 32.052 2.830 + 6789.500 31.599 2.830 + 6790.000 30.085 2.828 + 6790.500 28.415 2.816 + 6791.000 26.990 2.818 + 6791.500 27.373 2.825 + 6792.000 28.448 2.835 + 6792.500 31.370 2.830 + 6793.000 34.349 2.818 + 6793.500 36.822 2.798 + 6794.000 39.522 2.789 + 6794.500 37.292 2.771 + 6795.000 34.598 2.771 + 6795.500 31.916 2.782 + 6796.000 31.198 2.792 + 6796.500 30.619 2.808 + 6797.000 31.355 2.818 + 6797.500 32.161 2.820 + 6798.000 32.898 2.813 + 6798.500 33.542 2.795 + 6799.000 34.544 2.796 + 6799.500 36.857 2.796 + 6800.000 44.041 2.796 + 6800.500 45.317 2.796 + 6801.000 39.430 2.792 + 6801.500 33.428 2.792 + 6802.000 29.493 2.803 + 6802.500 23.507 2.825 + 6803.000 18.468 2.843 + 6803.500 16.116 2.868 + 6804.000 14.587 2.892 + 6804.500 15.528 2.891 + 6805.000 22.358 2.884 + 6805.500 28.174 2.850 + 6806.000 31.019 2.835 + 6806.500 36.143 2.815 + 6807.000 36.843 2.806 + 6807.500 37.076 2.792 + 6808.000 36.547 2.785 + 6808.500 35.083 2.784 + 6809.000 33.765 2.785 + 6809.500 32.265 2.788 + 6810.000 32.284 2.793 + 6810.500 35.078 2.796 + 6811.000 36.314 2.799 + 6811.500 36.762 2.800 + 6812.000 39.373 2.793 + 6812.500 42.586 2.785 + 6813.000 47.625 2.782 + 6813.500 50.198 2.784 + 6814.000 49.443 2.787 + 6814.500 40.878 2.796 + 6815.000 34.552 2.810 + 6815.500 29.970 2.807 + 6816.000 29.652 2.800 + 6816.500 23.558 2.794 + 6817.000 21.425 2.796 + 6817.500 20.214 2.800 + 6818.000 20.613 2.799 + 6818.500 23.689 2.797 + 6819.000 26.381 2.795 + 6819.500 30.449 2.794 + 6820.000 33.312 2.793 + 6820.500 38.005 2.790 + 6821.000 41.043 2.793 + 6821.500 44.979 2.794 + 6822.000 47.279 2.793 + 6822.500 46.430 2.779 + 6823.000 43.793 2.771 + 6823.500 41.696 2.770 + 6824.000 41.089 2.771 + 6824.500 37.697 2.779 + 6825.000 34.068 2.789 + 6825.500 31.553 2.793 + 6826.000 29.170 2.795 + 6826.500 28.176 2.798 + 6827.000 27.093 2.802 + 6827.500 26.434 2.795 + 6828.000 28.239 2.791 + 6828.500 33.255 2.781 + 6829.000 35.830 2.779 + 6829.500 40.889 2.778 + 6830.000 41.487 2.774 + 6830.500 43.063 2.774 + 6831.000 42.399 2.783 + 6831.500 39.893 2.803 + 6832.000 37.042 2.816 + 6832.500 35.392 2.818 + 6833.000 35.374 2.818 + 6833.500 34.739 2.824 + 6834.000 33.744 2.838 + 6834.500 35.285 2.843 + 6835.000 36.978 2.846 + 6835.500 37.768 2.836 + 6836.000 40.218 2.821 + 6836.500 40.939 2.804 + 6837.000 40.877 2.793 + 6837.500 40.876 2.795 + 6838.000 40.797 2.798 + 6838.500 39.808 2.798 + 6839.000 38.862 2.796 + 6839.500 35.846 2.796 + 6840.000 33.061 2.799 + 6840.500 31.133 2.805 + 6841.000 30.928 2.802 + 6841.500 31.136 2.798 + 6842.000 37.431 2.799 + 6842.500 43.949 2.809 + 6843.000 55.311 2.812 + 6843.500 60.190 2.808 + 6844.000 60.058 2.805 + 6844.500 49.022 2.814 + 6845.000 39.277 2.823 + 6845.500 30.793 2.828 + 6846.000 27.742 2.830 + 6846.500 26.006 2.835 + 6847.000 27.051 2.838 + 6847.500 27.590 2.839 + 6848.000 27.975 2.836 + 6848.500 27.304 2.822 + 6849.000 26.426 2.811 + 6849.500 24.219 2.810 + 6850.000 25.174 2.808 + 6850.500 21.900 2.806 + 6851.000 21.994 2.801 + 6851.500 23.545 2.799 + 6852.000 32.255 2.812 + 6852.500 42.486 2.831 + 6853.000 47.386 2.834 + 6853.500 45.499 2.829 + 6854.000 36.455 2.816 + 6854.500 27.825 2.798 + 6855.000 25.690 2.786 + 6855.500 26.120 2.786 + 6856.000 30.103 2.796 + 6856.500 35.822 2.807 + 6857.000 44.875 2.804 + 6857.500 49.084 2.797 + 6858.000 51.137 2.781 + 6858.500 43.171 2.779 + 6859.000 38.458 2.786 + 6859.500 35.556 2.799 + 6860.000 35.305 2.804 + 6860.500 34.336 2.806 + 6861.000 32.909 2.800 + 6861.500 33.548 2.788 + 6862.000 34.978 2.778 + 6862.500 38.013 2.775 + 6863.000 37.203 2.775 + 6863.500 35.330 2.793 + 6864.000 35.916 2.808 + 6864.500 43.066 2.827 + 6865.000 42.355 2.816 + 6865.500 51.797 2.796 + 6866.000 52.567 2.786 + 6866.500 53.529 2.793 + 6867.000 52.201 2.799 + 6867.500 49.849 2.799 + 6868.000 47.455 2.794 + 6868.500 39.083 2.786 + 6869.000 33.352 2.791 + 6869.500 29.855 2.796 + 6870.000 26.538 2.804 + 6870.500 30.577 2.802 + 6871.000 36.909 2.798 + 6871.500 45.337 2.795 + 6872.000 51.309 2.790 + 6872.500 52.867 2.783 + 6873.000 51.552 2.784 + 6873.500 48.539 2.785 + 6874.000 44.715 2.784 + 6874.500 38.191 2.780 + 6875.000 35.874 2.782 + 6875.500 31.606 2.790 + 6876.000 31.913 2.796 + 6876.500 35.412 2.819 + 6877.000 34.540 2.823 + 6877.500 32.303 2.824 + 6878.000 30.001 2.822 + 6878.500 27.556 2.822 + 6879.000 29.618 2.816 + 6879.500 34.638 2.803 + 6880.000 39.985 2.797 + 6880.500 44.434 2.796 + 6881.000 45.635 2.805 + 6881.500 46.575 2.822 + 6882.000 45.875 2.824 + 6882.500 42.715 2.830 + 6883.000 45.632 2.829 + 6883.500 49.442 2.823 + 6884.000 53.835 2.811 + 6884.500 56.099 2.800 + 6885.000 49.123 2.794 + 6885.500 41.776 2.788 + 6886.000 36.567 2.788 + 6886.500 32.358 2.792 + 6887.000 39.172 2.800 + 6887.500 44.536 2.804 + 6888.000 53.355 2.802 + 6888.500 55.162 2.795 + 6889.000 54.066 2.793 + 6889.500 51.146 2.795 + 6890.000 46.186 2.792 + 6890.500 35.933 2.778 + 6891.000 32.494 2.765 + 6891.500 35.061 2.763 + 6892.000 43.453 2.764 + 6892.500 57.068 2.782 + 6893.000 59.226 2.793 + 6893.500 56.725 2.798 + 6894.000 45.631 2.799 + 6894.500 29.346 2.805 + 6895.000 24.885 2.816 + 6895.500 21.157 2.839 + 6896.000 20.745 2.832 + 6896.500 21.853 2.820 + 6897.000 21.377 2.814 + 6897.500 21.245 2.814 + 6898.000 21.021 2.816 + 6898.500 21.016 2.834 + 6899.000 21.045 2.838 + 6899.500 21.004 2.846 + 6900.000 21.071 2.836 + 6900.500 20.500 2.816 + 6901.000 19.545 2.811 + 6901.500 19.941 2.816 + 6902.000 21.603 2.820 + 6902.500 22.691 2.824 + 6903.000 21.055 2.826 + 6903.500 20.837 2.832 + 6904.000 18.526 2.847 + 6904.500 19.596 2.855 + 6905.000 22.666 2.840 + 6905.500 27.108 2.813 + 6906.000 27.331 2.820 + 6906.500 27.621 2.840 + 6907.000 28.120 2.846 + 6907.500 28.923 2.847 + 6908.000 28.300 2.845 + 6908.500 28.088 2.843 + 6909.000 27.379 2.838 + 6909.500 28.898 2.831 + 6910.000 28.691 2.831 + 6910.500 26.013 2.835 + 6911.000 23.455 2.839 + 6911.500 22.594 2.839 + 6912.000 23.007 2.824 + 6912.500 27.737 2.818 + 6913.000 29.147 2.818 + 6913.500 29.915 2.830 + 6914.000 30.754 2.854 + 6914.500 31.636 2.857 + 6915.000 32.242 2.848 + 6915.500 29.294 2.817 + 6916.000 28.457 2.822 + 6916.500 23.628 2.826 + 6917.000 22.722 2.831 + 6917.500 22.427 2.832 + 6918.000 24.813 2.839 + 6918.500 23.311 2.845 + 6919.000 21.785 2.843 + 6919.500 21.032 2.831 + 6920.000 20.564 2.822 + 6920.500 20.187 2.828 + 6921.000 20.533 2.835 + 6921.500 19.429 2.833 + 6922.000 26.710 2.815 + 6922.500 29.965 2.785 + 6923.000 29.379 2.787 + 6923.500 24.941 2.798 + 6924.000 19.814 2.805 + 6924.500 19.895 2.837 + 6925.000 23.505 2.843 + 6925.500 27.955 2.844 + 6926.000 34.614 2.841 + 6926.500 39.882 2.839 + 6927.000 37.945 2.833 + 6927.500 32.509 2.827 + 6928.000 29.420 2.821 + 6928.500 26.586 2.812 + 6929.000 25.878 2.802 + 6929.500 24.881 2.809 + 6930.000 24.988 2.811 + 6930.500 24.972 2.839 + 6931.000 25.011 2.841 + 6931.500 24.978 2.844 + 6932.000 25.443 2.842 + 6932.500 30.390 2.842 + 6933.000 35.346 2.833 + 6933.500 36.960 2.823 + 6934.000 37.514 2.823 + 6934.500 33.376 2.830 + 6935.000 30.633 2.844 + 6935.500 27.713 2.850 + 6936.000 24.958 2.852 + 6936.500 23.799 2.845 + 6937.000 24.685 2.839 + 6937.500 26.476 2.821 + 6938.000 27.559 2.820 + 6938.500 29.723 2.818 + 6939.000 31.568 2.811 + 6939.500 33.737 2.806 + 6940.000 35.836 2.811 + 6940.500 40.897 2.833 + 6941.000 41.452 2.838 + 6941.500 40.727 2.836 + 6942.000 37.710 2.825 + 6942.500 36.808 2.816 + 6943.000 38.471 2.812 + 6943.500 42.597 2.815 + 6944.000 43.204 2.823 + 6944.500 41.475 2.829 + 6945.000 39.271 2.829 + 6945.500 35.099 2.826 + 6946.000 30.663 2.825 + 6946.500 25.371 2.822 + 6947.000 25.051 2.821 + 6947.500 24.893 2.826 + 6948.000 25.232 2.834 + 6948.500 25.196 2.851 + 6949.000 25.131 2.856 + 6949.500 25.954 2.853 + 6950.000 26.864 2.842 + 6950.500 27.304 2.831 + 6951.000 26.446 2.825 + 6951.500 24.680 2.817 + 6952.000 24.343 2.798 + 6952.500 25.229 2.793 + 6953.000 26.572 2.812 + 6953.500 26.581 2.821 + 6954.000 26.070 2.825 + 6954.500 24.943 2.825 + 6955.000 24.232 2.828 + 6955.500 21.549 2.834 + 6956.000 19.339 2.841 + 6956.500 15.853 2.841 + 6957.000 14.882 2.838 + 6957.500 14.493 2.827 + 6958.000 15.382 2.834 + 6958.500 19.963 2.852 + 6959.000 36.249 2.848 + 6959.500 45.249 2.839 + 6960.000 48.398 2.818 + 6960.500 42.751 2.803 + 6961.000 37.051 2.809 + 6961.500 33.139 2.816 + 6962.000 30.904 2.819 + 6962.500 36.478 2.835 + 6963.000 42.999 2.844 + 6963.500 44.949 2.846 + 6964.000 45.404 2.839 + 6964.500 42.407 2.827 + 6965.000 37.534 2.809 + 6965.500 35.294 2.807 + 6966.000 36.661 2.807 + 6966.500 39.661 2.808 + 6967.000 43.410 2.809 + 6967.500 47.796 2.813 + 6968.000 51.296 2.822 + 6968.500 47.219 2.832 + 6969.000 35.422 2.830 + 6969.500 28.254 2.824 + 6970.000 21.872 2.809 + 6970.500 20.319 2.786 + 6971.000 20.510 2.792 + 6971.500 21.942 2.812 + 6972.000 24.549 2.828 + 6972.500 27.904 2.845 + 6973.000 31.402 2.849 + 6973.500 32.158 2.853 + 6974.000 31.795 2.851 + 6974.500 26.276 2.835 + 6975.000 23.558 2.824 + 6975.500 21.439 2.819 + 6976.000 19.185 2.825 + 6976.500 18.370 2.824 + 6977.000 21.217 2.830 + 6977.500 27.254 2.831 + 6978.000 32.489 2.825 + 6978.500 38.780 2.807 + 6979.000 45.570 2.802 + 6979.500 44.061 2.805 + 6980.000 38.574 2.819 + 6980.500 28.416 2.845 + 6981.000 21.212 2.857 + 6981.500 17.865 2.862 + 6982.000 17.401 2.843 + 6982.500 18.871 2.827 + 6983.000 20.250 2.824 + 6983.500 21.117 2.824 + 6984.000 20.599 2.852 + 6984.500 19.790 2.848 + 6985.000 19.613 2.832 + 6985.500 20.488 2.804 + 6986.000 21.208 2.801 + 6986.500 21.996 2.802 + 6987.000 20.598 2.810 + 6987.500 17.601 2.816 + 6988.000 15.069 2.819 + 6988.500 11.828 2.812 + 6989.000 10.850 2.810 + 6989.500 10.674 2.803 + 6990.000 10.888 2.794 + 6990.500 13.223 2.779 + 6991.000 14.657 2.780 + 6991.500 18.784 2.784 + 6992.000 20.162 2.794 + 6992.500 22.713 2.811 + 6993.000 28.793 2.812 + 6993.500 32.197 2.812 + 6994.000 37.902 2.813 + 6994.500 41.792 2.817 + 6995.000 42.201 2.801 + 6995.500 44.137 2.793 + 6996.000 46.935 2.784 + 6996.500 55.619 2.781 + 6997.000 57.344 2.780 + 6997.500 57.665 2.780 + 6998.000 56.559 2.783 + 6998.500 53.763 2.795 + 6999.000 53.634 2.797 + 6999.500 55.138 2.794 + 7000.000 57.558 2.793 + 7000.500 52.420 2.794 + 7001.000 39.110 2.792 + 7001.500 30.511 2.797 + 7002.000 25.663 2.808 + 7002.500 21.938 2.820 + 7003.000 20.652 2.817 + 7003.500 20.173 2.812 + 7004.000 20.231 2.808 + 7004.500 20.297 2.810 + 7005.000 21.230 2.815 + 7005.500 21.955 2.833 + 7006.000 21.450 2.839 + 7006.500 24.414 2.844 + 7007.000 26.111 2.840 + 7007.500 31.801 2.833 + 7008.000 33.914 2.831 + 7008.500 39.799 2.828 + 7009.000 43.709 2.819 + 7009.500 46.618 2.808 + 7010.000 47.241 2.795 + 7010.500 45.083 2.791 + 7011.000 39.622 2.801 + 7011.500 32.574 2.810 + 7012.000 26.065 2.818 + 7012.500 23.298 2.823 + 7013.000 20.205 2.824 + 7013.500 18.747 2.828 + 7014.000 17.015 2.828 + 7014.500 17.076 2.837 + 7015.000 17.228 2.843 + 7015.500 18.150 2.844 + 7016.000 22.418 2.834 + 7016.500 26.169 2.805 + 7017.000 26.640 2.798 + 7017.500 26.762 2.808 + 7018.000 26.226 2.839 + 7018.500 31.593 2.870 + 7019.000 36.612 2.860 + 7019.500 39.622 2.843 + 7020.000 38.693 2.809 + 7020.500 34.572 2.810 + 7021.000 30.382 2.814 + 7021.500 28.383 2.821 + 7022.000 33.231 2.824 + 7022.500 42.024 2.824 + 7023.000 48.462 2.823 + 7023.500 51.074 2.816 + 7024.000 48.394 2.815 + 7024.500 36.132 2.812 + 7025.000 28.388 2.809 + 7025.500 24.223 2.799 + 7026.000 22.564 2.796 + 7026.500 25.142 2.797 + 7027.000 28.054 2.803 + 7027.500 34.300 2.807 + 7028.000 35.964 2.808 + 7028.500 33.065 2.806 + 7029.000 27.979 2.806 + 7029.500 25.006 2.809 + 7030.000 25.460 2.813 + 7030.500 29.280 2.820 + 7031.000 29.781 2.825 + 7031.500 27.504 2.821 + 7032.000 21.572 2.820 + 7032.500 19.762 2.821 + 7033.000 25.037 2.824 + 7033.500 30.038 2.824 + 7034.000 42.920 2.822 + 7034.500 51.327 2.819 + 7035.000 54.527 2.811 + 7035.500 51.448 2.808 + 7036.000 46.445 2.809 + 7036.500 33.573 2.818 + 7037.000 29.942 2.825 + 7037.500 29.470 2.830 + 7038.000 32.420 2.819 + 7038.500 35.504 2.797 + 7039.000 36.222 2.792 + 7039.500 37.474 2.796 + 7040.000 39.050 2.799 + 7040.500 40.973 2.802 + 7041.000 41.721 2.805 + 7041.500 41.783 2.799 + 7042.000 40.190 2.796 + 7042.500 34.286 2.805 + 7043.000 28.970 2.815 + 7043.500 28.530 2.820 + 7044.000 28.216 2.817 + 7044.500 36.387 2.798 + 7045.000 40.331 2.790 + 7045.500 39.768 2.794 + 7046.000 38.020 2.808 + 7046.500 24.313 2.826 + 7047.000 20.271 2.825 + 7047.500 17.014 2.822 + 7048.000 17.092 2.821 + 7048.500 16.240 2.822 + 7049.000 17.109 2.824 + 7049.500 17.844 2.824 + 7050.000 23.560 2.835 + 7050.500 31.532 2.836 + 7051.000 37.319 2.814 + 7051.500 39.362 2.810 + 7052.000 37.998 2.809 + 7052.500 26.142 2.819 + 7053.000 29.055 2.818 + 7053.500 34.906 2.815 + 7054.000 45.230 2.808 + 7054.500 45.420 2.814 + 7055.000 36.893 2.828 + 7055.500 25.258 2.833 + 7056.000 18.357 2.846 + 7056.500 15.986 2.841 + 7057.000 13.884 2.837 + 7057.500 18.242 2.836 + 7058.000 19.618 2.829 + 7058.500 21.273 2.820 + 7059.000 22.305 2.791 + 7059.500 26.397 2.794 + 7060.000 29.101 2.798 + 7060.500 31.580 2.799 + 7061.000 34.715 2.791 + 7061.500 32.706 2.781 + 7062.000 28.885 2.775 + 7062.500 26.518 2.807 + 7063.000 24.476 2.825 + 7063.500 24.656 2.858 + 7064.000 25.799 2.852 + 7064.500 30.858 2.837 + 7065.000 34.083 2.829 + 7065.500 34.744 2.825 + 7066.000 34.180 2.827 + 7066.500 37.282 2.826 + 7067.000 38.480 2.823 + 7067.500 39.227 2.830 + 7068.000 35.131 2.834 + 7068.500 30.506 2.831 + 7069.000 22.716 2.816 + 7069.500 21.734 2.807 + 7070.000 20.939 2.803 + 7070.500 21.035 2.813 + 7071.000 21.202 2.819 + 7071.500 25.184 2.812 + 7072.000 27.899 2.794 + 7072.500 32.380 2.795 + 7073.000 32.093 2.802 + 7073.500 32.120 2.810 + 7074.000 37.683 2.811 + 7074.500 44.918 2.808 + 7075.000 50.309 2.797 + 7075.500 49.791 2.790 + 7076.000 45.981 2.787 + 7076.500 39.886 2.801 + 7077.000 33.402 2.809 + 7077.500 32.503 2.827 + 7078.000 32.091 2.833 + 7078.500 35.797 2.825 + 7079.000 36.776 2.818 + 7079.500 38.580 2.825 + 7080.000 40.291 2.834 + 7080.500 43.482 2.840 + 7081.000 43.042 2.832 + 7081.500 38.912 2.832 + 7082.000 32.639 2.834 + 7082.500 23.530 2.843 + 7083.000 20.430 2.845 + 7083.500 16.878 2.848 + 7084.000 15.761 2.849 + 7084.500 14.230 2.859 + 7085.000 13.876 2.866 + 7085.500 17.178 2.866 + 7086.000 20.018 2.852 + 7086.500 24.576 2.831 + 7087.000 25.566 2.828 + 7087.500 26.683 2.834 + 7088.000 27.477 2.847 + 7088.500 29.656 2.847 + 7089.000 31.013 2.845 + 7089.500 32.195 2.846 + 7090.000 29.944 2.837 + 7090.500 25.763 2.836 + 7091.000 22.538 2.841 + 7091.500 18.935 2.844 + 7092.000 17.794 2.835 + 7092.500 18.498 2.831 + 7093.000 19.839 2.840 + 7093.500 25.762 2.845 + 7094.000 29.131 2.842 + 7094.500 26.168 2.835 + 7095.000 21.435 2.836 + 7095.500 19.628 2.834 + 7096.000 18.552 2.832 + 7096.500 16.304 2.830 + 7097.000 15.488 2.832 + 7097.500 15.508 2.838 + 7098.000 17.131 2.836 + 7098.500 18.735 2.831 + 7099.000 19.634 2.830 + 7099.500 20.525 2.830 + 7100.000 20.447 2.830 + 7100.500 19.629 2.830 + 7101.000 16.524 2.830 + 7101.500 15.444 2.829 + 7102.000 15.131 2.831 + 7102.500 18.472 2.836 + 7103.000 22.275 2.833 + 7103.500 24.830 2.831 + 7104.000 24.156 2.831 + 7104.500 22.338 2.846 + 7105.000 21.842 2.850 + 7105.500 26.092 2.855 + 7106.000 31.843 2.845 + 7106.500 43.682 2.825 + 7107.000 44.389 2.817 + 7107.500 43.485 2.811 + 7108.000 39.225 2.805 + 7108.500 32.077 2.804 + 7109.000 27.161 2.805 + 7109.500 24.320 2.809 + 7110.000 22.328 2.814 + 7110.500 20.917 2.814 + 7111.000 21.221 2.814 + 7111.500 23.452 2.815 + 7112.000 25.398 2.816 + 7112.500 29.067 2.847 + 7113.000 29.447 2.858 + 7113.500 29.950 2.883 + 7114.000 28.415 2.829 + 7114.500 25.357 2.823 + 7115.000 23.253 2.824 + 7115.500 23.659 2.870 + 7116.000 25.036 2.860 + 7116.500 30.362 2.820 + 7117.000 32.219 2.771 + 7117.500 30.593 2.733 + 7118.000 28.504 2.753 + 7118.500 24.179 2.824 + 7119.000 22.213 2.830 + 7119.500 21.306 2.845 + 7120.000 22.752 2.864 + 7120.500 29.237 2.859 + 7121.000 33.220 2.858 + 7121.500 35.235 2.856 + 7122.000 35.419 2.866 + 7122.500 34.120 2.883 + 7123.000 32.974 2.822 + 7123.500 31.361 2.787 + 7124.000 29.758 2.776 + 7124.500 30.340 2.815 + 7125.000 31.808 2.820 + 7125.500 34.662 2.819 + 7126.000 38.693 2.816 + 7126.500 42.945 2.820 + 7127.000 46.003 2.824 + 7127.500 47.458 2.834 + 7128.000 45.605 2.839 + 7128.500 40.968 2.846 + 7129.000 36.208 2.844 + 7129.500 33.261 2.817 + 7130.000 29.792 2.788 + 7130.500 22.633 2.761 + 7131.000 18.856 2.750 + 7131.500 15.470 2.761 + 7132.000 14.244 2.786 + 7132.500 13.870 2.810 + 7133.000 13.796 2.828 + 7133.500 13.752 2.832 + 7134.000 12.977 2.830 + 7134.500 13.076 2.834 + 7135.000 13.645 2.832 + 7135.500 16.222 2.841 + 7136.000 19.190 2.845 + 7136.500 22.304 2.849 + 7137.000 24.412 2.837 + 7137.500 27.342 2.826 + 7138.000 35.260 2.820 + 7138.500 48.278 2.803 + 7139.000 65.188 2.797 + 7139.500 74.192 2.810 + 7140.000 72.182 2.804 + 7140.500 42.717 2.786 + 7141.000 39.793 2.770 + 7141.500 25.383 2.765 + 7142.000 26.625 2.769 + 7142.500 27.414 2.818 + 7143.000 29.536 2.833 + 7143.500 32.017 2.814 + 7144.000 32.811 2.802 + 7144.500 33.229 2.798 + 7145.000 35.659 2.802 + 7145.500 39.173 2.800 + 7146.000 41.741 2.798 + 7146.500 39.826 2.797 + 7147.000 33.252 2.799 + 7147.500 32.212 2.814 + 7148.000 33.242 2.817 + 7148.500 38.722 2.825 + 7149.000 38.115 2.820 + 7149.500 34.427 2.819 + 7150.000 29.946 2.818 + 7150.500 28.319 2.816 + 7151.000 28.636 2.814 + 7151.500 29.164 2.812 + 7152.000 27.649 2.810 + 7152.500 27.407 2.809 + 7153.000 27.525 2.807 + 7153.500 30.682 2.808 + 7154.000 32.762 2.811 + 7154.500 31.261 2.814 + 7155.000 26.656 2.812 + 7155.500 22.555 2.812 + 7156.000 20.071 2.814 + 7156.500 19.429 2.818 + 7157.000 18.946 2.819 + 7157.500 17.924 2.826 + 7158.000 17.583 2.829 + 7158.500 15.569 2.833 + 7159.000 14.622 2.831 + 7159.500 13.673 2.829 + 7160.000 14.202 2.837 + 7160.500 18.936 2.845 + 7161.000 20.466 2.848 + 7161.500 26.863 2.847 + 7162.000 29.257 2.847 + 7162.500 34.069 2.843 + 7163.000 30.491 2.828 + 7163.500 26.463 2.824 + 7164.000 22.251 2.823 + 7164.500 19.204 2.828 + 7165.000 16.229 2.829 + 7165.500 16.280 2.829 + 7166.000 18.446 2.835 + 7166.500 20.429 2.843 + 7167.000 22.727 2.851 + 7167.500 28.202 2.851 + 7168.000 32.643 2.848 + 7168.500 40.047 2.840 + 7169.000 44.354 2.832 + 7169.500 44.650 2.819 + 7170.000 43.158 2.815 + 7170.500 35.397 2.810 + 7171.000 31.155 2.816 + 7171.500 25.630 2.817 + 7172.000 24.940 2.822 + 7172.500 25.855 2.831 + 7173.000 26.513 2.842 + 7173.500 28.928 2.842 + 7174.000 31.057 2.843 + 7174.500 36.105 2.843 + 7175.000 39.237 2.840 + 7175.500 40.477 2.836 + 7176.000 38.921 2.833 + 7176.500 34.428 2.833 + 7177.000 28.630 2.838 + 7177.500 23.959 2.847 + 7178.000 19.235 2.853 + 7178.500 17.236 2.848 + 7179.000 14.487 2.837 + 7179.500 13.505 2.828 + 7180.000 12.176 2.829 + 7180.500 12.271 2.833 + 7181.000 12.377 2.835 + 7181.500 11.791 2.830 + 7182.000 12.251 2.818 + 7182.500 11.167 2.812 + 7183.000 10.748 2.824 + 7183.500 10.138 2.837 + 7184.000 9.738 2.846 + 7184.500 11.270 2.843 + 7185.000 13.238 2.835 + 7185.500 15.718 2.835 + 7186.000 18.078 2.841 + 7186.500 19.719 2.848 + 7187.000 20.486 2.846 + 7187.500 21.067 2.842 + 7188.000 23.360 2.839 + 7188.500 24.223 2.831 + 7189.000 24.139 2.825 + 7189.500 22.560 2.814 + 7190.000 21.108 2.813 + 7190.500 21.214 2.819 + 7191.000 21.978 2.823 + 7191.500 25.388 2.826 + 7192.000 30.489 2.820 + 7192.500 38.255 2.808 + 7193.000 42.857 2.804 + 7193.500 46.679 2.806 + 7194.000 47.385 2.810 + 7194.500 43.616 2.808 + 7195.000 40.839 2.799 + 7195.500 37.568 2.797 + 7196.000 33.139 2.796 + 7196.500 23.743 2.799 + 7197.000 19.680 2.796 + 7197.500 16.954 2.794 + 7198.000 18.183 2.804 + 7198.500 24.606 2.830 + 7199.000 31.126 2.829 + 7199.500 43.945 2.825 + 7200.000 52.828 2.810 + 7200.500 55.623 2.795 + 7201.000 54.570 2.779 + 7201.500 51.058 2.777 + 7202.000 45.681 2.790 + 7202.500 35.970 2.801 + 7203.000 28.944 2.812 + 7203.500 26.344 2.815 + 7204.000 26.200 2.819 + 7204.500 24.984 2.812 + 7205.000 21.872 2.817 + 7205.500 20.025 2.817 + 7206.000 17.996 2.810 + 7206.500 16.729 2.801 + 7207.000 17.304 2.806 + 7207.500 17.536 2.818 + 7208.000 18.065 2.823 + 7208.500 18.505 2.841 + 7209.000 17.740 2.848 + 7209.500 15.691 2.855 + 7210.000 14.949 2.845 + 7210.500 16.009 2.830 + 7211.000 17.048 2.834 + 7211.500 19.518 2.830 + 7212.000 20.097 2.818 + 7212.500 24.394 2.796 + 7213.000 29.906 2.795 + 7213.500 35.140 2.798 + 7214.000 36.874 2.806 + 7214.500 31.770 2.814 + 7215.000 23.975 2.824 + 7215.500 20.319 2.834 + 7216.000 20.246 2.839 + 7216.500 20.424 2.839 + 7217.000 20.556 2.838 + 7217.500 19.349 2.838 + 7218.000 18.450 2.840 + 7218.500 17.815 2.840 + 7219.000 19.302 2.839 + 7219.500 21.121 2.837 + 7220.000 24.165 2.832 + 7220.500 25.858 2.822 + 7221.000 28.663 2.817 + 7221.500 32.630 2.816 + 7222.000 36.575 2.817 + 7222.500 34.184 2.821 + 7223.000 29.403 2.826 + 7223.500 20.132 2.842 + 7224.000 19.784 2.850 + 7224.500 17.249 2.851 + 7225.000 17.134 2.843 + 7225.500 17.975 2.829 + 7226.000 19.982 2.825 + 7226.500 23.475 2.826 + 7227.000 31.848 2.827 + 7227.500 38.674 2.827 + 7228.000 47.378 2.821 + 7228.500 49.690 2.814 + 7229.000 47.395 2.809 + 7229.500 44.619 2.812 + 7230.000 39.084 2.816 + 7230.500 32.853 2.821 + 7231.000 26.545 2.825 + 7231.500 23.373 2.829 + 7232.000 21.711 2.832 + 7232.500 22.069 2.830 + 7233.000 23.523 2.828 + 7233.500 23.631 2.820 + 7234.000 20.913 2.819 + 7234.500 21.248 2.825 + 7235.000 21.732 2.832 + 7235.500 22.241 2.832 + 7236.000 23.833 2.826 + 7236.500 25.037 2.807 + 7237.000 25.618 2.805 + 7237.500 25.580 2.811 + 7238.000 25.020 2.824 + 7238.500 24.395 2.841 + 7239.000 24.180 2.853 + 7239.500 24.204 2.863 + 7240.000 24.343 2.879 + 7240.500 25.192 2.874 + 7241.000 26.043 2.864 + 7241.500 26.746 2.843 + 7242.000 27.944 2.839 + 7242.500 29.579 2.836 + 7243.000 31.239 2.841 + 7243.500 31.853 2.843 + 7244.000 32.522 2.844 + 7244.500 26.468 2.835 + 7245.000 21.799 2.832 + 7245.500 20.901 2.833 + 7246.000 21.605 2.840 + 7246.500 22.108 2.848 + 7247.000 22.737 2.850 + 7247.500 23.350 2.848 + 7248.000 23.294 2.845 + 7248.500 23.743 2.843 + 7249.000 24.343 2.843 + 7249.500 26.457 2.838 + 7250.000 31.912 2.833 + 7250.500 45.503 2.823 + 7251.000 44.597 2.819 + 7251.500 41.474 2.820 + 7252.000 34.485 2.823 + 7252.500 25.118 2.830 + 7253.000 25.746 2.842 + 7253.500 28.089 2.843 + 7254.000 33.770 2.840 + 7254.500 41.834 2.821 + 7255.000 47.723 2.815 + 7255.500 54.111 2.806 + 7256.000 60.596 2.801 + 7256.500 63.551 2.800 + 7257.000 61.404 2.795 + 7257.500 57.724 2.794 + 7258.000 44.651 2.795 + 7258.500 29.114 2.830 + 7259.000 23.738 2.846 + 7259.500 17.525 2.851 + 7260.000 17.496 2.843 + 7260.500 13.281 2.825 + 7261.000 12.401 2.820 + 7261.500 11.424 2.820 + 7262.000 12.380 2.823 + 7262.500 12.334 2.829 + 7263.000 12.073 2.829 + 7263.500 13.162 2.826 + 7264.000 14.578 2.823 + 7264.500 19.022 2.820 + 7265.000 20.202 2.824 + 7265.500 22.765 2.832 + 7266.000 24.331 2.831 + 7266.500 27.127 2.828 + 7267.000 27.750 2.817 + 7267.500 26.440 2.811 + 7268.000 26.584 2.805 + 7268.500 25.097 2.803 + 7269.000 24.486 2.808 + 7269.500 23.481 2.814 + 7270.000 20.926 2.824 + 7270.500 17.240 2.844 + 7271.000 16.373 2.853 + 7271.500 17.049 2.856 + 7272.000 19.962 2.846 + 7272.500 21.501 2.821 + 7273.000 21.821 2.812 + 7273.500 21.919 2.814 + 7274.000 22.763 2.820 + 7274.500 24.341 2.826 + 7275.000 25.911 2.818 + 7275.500 30.691 2.810 + 7276.000 33.175 2.800 + 7276.500 38.526 2.809 + 7277.000 40.103 2.814 + 7277.500 42.582 2.819 + 7278.000 42.013 2.828 + 7278.500 40.924 2.834 + 7279.000 39.446 2.835 + 7279.500 37.737 2.829 + 7280.000 35.424 2.820 + 7280.500 31.247 2.814 + 7281.000 28.385 2.814 + 7281.500 23.625 2.816 + 7282.000 22.312 2.824 + 7282.500 20.258 2.826 + 7283.000 20.459 2.817 + 7283.500 22.072 2.804 + 7284.000 23.218 2.799 + 7284.500 26.281 2.800 + 7285.000 28.743 2.817 + 7285.500 31.092 2.825 + 7286.000 38.737 2.821 + 7286.500 45.348 2.802 + 7287.000 51.408 2.788 + 7287.500 52.992 2.782 + 7288.000 51.014 2.786 + 7288.500 47.457 2.799 + 7289.000 45.676 2.805 + 7289.500 45.727 2.812 + 7290.000 42.579 2.819 + 7290.500 38.597 2.826 + 7291.000 33.763 2.826 + 7291.500 33.116 2.817 + 7292.000 35.083 2.807 + 7292.500 43.460 2.802 + 7293.000 47.741 2.804 + 7293.500 48.643 2.807 + 7294.000 45.987 2.817 + 7294.500 34.862 2.824 + 7295.000 28.495 2.830 + 7295.500 23.904 2.835 + 7296.000 21.033 2.842 + 7296.500 21.605 2.847 + 7297.000 22.024 2.853 + 7297.500 22.676 2.841 + 7298.000 22.093 2.832 + 7298.500 20.139 2.827 + 7299.000 18.885 2.826 + 7299.500 17.786 2.829 + 7300.000 17.602 2.833 + 7300.500 17.265 2.831 + 7301.000 16.586 2.825 + 7301.500 16.272 2.823 + 7302.000 16.092 2.824 + 7302.500 17.554 2.827 + 7303.000 19.647 2.848 + 7303.500 20.386 2.852 + 7304.000 23.744 2.856 + 7304.500 27.260 2.845 + 7305.000 39.250 2.802 + 7305.500 44.261 2.796 + 7306.000 48.127 2.794 + 7306.500 39.666 2.792 + 7307.000 32.744 2.792 + 7307.500 25.076 2.796 + 7308.000 20.944 2.809 + 7308.500 19.191 2.812 + 7309.000 20.423 2.814 + 7309.500 21.885 2.816 + 7310.000 22.711 2.811 + 7310.500 24.017 2.803 + 7311.000 23.716 2.796 + 7311.500 23.213 2.799 + 7312.000 22.372 2.799 + 7312.500 23.135 2.804 + 7313.000 24.971 2.805 + 7313.500 27.027 2.809 + 7314.000 29.003 2.818 + 7314.500 32.037 2.821 + 7315.000 32.240 2.818 + 7315.500 30.552 2.809 + 7316.000 28.464 2.807 + 7316.500 23.913 2.822 + 7317.000 22.440 2.831 + 7317.500 20.800 2.842 + 7318.000 19.288 2.841 + 7318.500 17.257 2.836 + 7319.000 16.516 2.833 + 7319.500 17.150 2.827 + 7320.000 17.082 2.826 + 7320.500 17.509 2.829 + 7321.000 19.152 2.831 + 7321.500 20.880 2.830 + 7322.000 21.917 2.836 + 7322.500 25.491 2.843 + 7323.000 27.631 2.839 + 7323.500 26.269 2.820 + 7324.000 22.122 2.816 + 7324.500 19.854 2.822 + 7325.000 19.808 2.841 + 7325.500 26.931 2.841 + 7326.000 31.909 2.834 + 7326.500 39.293 2.829 + 7327.000 40.365 2.827 + 7327.500 34.001 2.829 + 7328.000 31.885 2.836 + 7328.500 33.748 2.824 + 7329.000 42.700 2.801 + 7329.500 52.180 2.790 + 7330.000 48.645 2.787 + 7330.500 35.574 2.785 + 7331.000 26.934 2.798 + 7331.500 22.052 2.820 + 7332.000 21.128 2.837 + 7332.500 22.334 2.842 + 7333.000 25.741 2.836 + 7333.500 27.643 2.829 + 7334.000 28.147 2.823 + 7334.500 26.169 2.823 + 7335.000 23.985 2.821 + 7335.500 22.482 2.827 + 7336.000 22.512 2.834 + 7336.500 22.024 2.830 + 7337.000 21.079 2.826 + 7337.500 20.047 2.819 + 7338.000 18.426 2.812 + 7338.500 16.815 2.815 + 7339.000 16.088 2.818 + 7339.500 16.971 2.823 + 7340.000 17.036 2.824 + 7340.500 17.683 2.825 + 7341.000 18.676 2.826 + 7341.500 21.469 2.825 + 7342.000 26.595 2.828 + 7342.500 32.652 2.839 + 7343.000 33.676 2.848 + 7343.500 31.531 2.843 + 7344.000 26.763 2.837 + 7344.500 19.954 2.839 + 7345.000 14.889 2.843 + 7345.500 15.153 2.849 + 7346.000 15.802 2.852 + 7346.500 17.977 2.850 + 7347.000 18.461 2.845 + 7347.500 20.645 2.837 + 7348.000 25.930 2.832 + 7348.500 31.446 2.830 + 7349.000 34.516 2.826 + 7349.500 41.797 2.824 + 7350.000 46.189 2.823 + 7350.500 48.094 2.819 + 7351.000 46.700 2.816 + 7351.500 43.979 2.814 + 7352.000 37.522 2.816 + 7352.500 28.425 2.827 + 7353.000 25.841 2.838 + 7353.500 25.890 2.848 + 7354.000 27.640 2.852 + 7354.500 30.910 2.846 + 7355.000 34.420 2.840 + 7355.500 36.693 2.832 + 7356.000 38.589 2.822 + 7356.500 38.061 2.814 + 7357.000 38.770 2.814 + 7357.500 44.147 2.816 + 7358.000 48.907 2.816 + 7358.500 50.767 2.818 + 7359.000 47.884 2.820 + 7359.500 40.799 2.822 + 7360.000 30.742 2.830 + 7360.500 17.629 2.835 + 7361.000 18.766 2.827 + 7361.500 18.772 2.819 + 7362.000 18.967 2.807 + 7362.500 20.225 2.802 + 7363.000 18.591 2.799 + 7363.500 20.521 2.806 + 7364.000 21.817 2.816 + 7364.500 23.221 2.829 + 7365.000 24.085 2.829 + 7365.500 24.080 2.826 + 7366.000 23.193 2.825 + 7366.500 22.414 2.821 + 7367.000 21.761 2.818 + 7367.500 21.848 2.816 + 7368.000 21.539 2.815 + 7368.500 20.253 2.827 + 7369.000 20.975 2.826 + 7369.500 22.746 2.824 + 7370.000 25.197 2.822 + 7370.500 27.594 2.827 + 7371.000 29.669 2.831 + 7371.500 28.197 2.829 + 7372.000 28.172 2.819 + 7372.500 27.391 2.810 + 7373.000 27.490 2.810 + 7373.500 28.453 2.816 + 7374.000 29.342 2.824 + 7374.500 32.446 2.831 + 7375.000 36.518 2.828 + 7375.500 41.613 2.817 + 7376.000 42.091 2.816 + 7376.500 41.276 2.818 + 7377.000 36.394 2.821 + 7377.500 34.360 2.820 + 7378.000 32.284 2.819 + 7378.500 30.552 2.815 + 7379.000 29.128 2.811 + 7379.500 29.329 2.808 + 7380.000 35.297 2.809 + 7380.500 44.406 2.820 + 7381.000 49.129 2.826 + 7381.500 52.033 2.833 + 7382.000 51.522 2.842 + 7382.500 46.911 2.840 + 7383.000 43.135 2.831 + 7383.500 38.539 2.823 + 7384.000 31.170 2.817 + 7384.500 25.226 2.817 + 7385.000 22.159 2.815 + 7385.500 20.719 2.802 + 7386.000 20.153 2.800 + 7386.500 20.402 2.800 + 7387.000 21.179 2.802 + 7387.500 21.867 2.805 + 7388.000 21.901 2.817 + 7388.500 22.604 2.826 + 7389.000 23.757 2.826 + 7389.500 25.555 2.819 + 7390.000 27.187 2.809 + 7390.500 31.805 2.810 + 7391.000 41.035 2.813 + 7391.500 49.666 2.826 + 7392.000 56.182 2.825 + 7392.500 63.088 2.826 + 7393.000 54.525 2.824 + 7393.500 44.907 2.825 + 7394.000 47.199 2.826 + 7394.500 53.425 2.824 + 7395.000 57.314 2.827 + 7395.500 57.579 2.831 + 7396.000 52.222 2.834 + 7396.500 39.908 2.841 + 7397.000 31.171 2.845 + 7397.500 22.900 2.854 + 7398.000 21.511 2.854 + 7398.500 19.957 2.846 + 7399.000 19.032 2.836 + 7399.500 17.716 2.818 + 7400.000 17.272 2.816 + 7400.500 15.426 2.813 + 7401.000 16.760 2.826 + 7401.500 19.493 2.841 + 7402.000 21.331 2.860 + 7402.500 21.675 2.850 + 7403.000 22.146 2.835 + 7403.500 22.529 2.821 + 7404.000 21.070 2.820 + 7404.500 19.321 2.821 + 7405.000 18.998 2.821 + 7405.500 19.231 2.817 + 7406.000 19.340 2.817 + 7406.500 20.719 2.821 + 7407.000 20.781 2.822 + 7407.500 22.666 2.824 + 7408.000 24.688 2.824 + 7408.500 31.784 2.823 + 7409.000 35.768 2.818 + 7409.500 43.113 2.811 + 7410.000 46.230 2.801 + 7410.500 58.409 2.800 + 7411.000 66.502 2.798 + 7411.500 69.423 2.798 + 7412.000 69.533 2.789 + 7412.500 68.495 2.779 + 7413.000 69.808 2.772 + 7413.500 68.456 2.769 + 7414.000 78.570 2.764 + 7414.500 100.361 2.745 + 7415.000 138.419 2.733 + 7415.500 136.678 2.732 + 7416.000 127.746 2.733 + 7416.500 45.815 2.778 + 7417.000 48.650 2.805 + 7417.500 24.894 2.832 + 7418.000 17.982 2.845 + 7418.500 13.899 2.848 + 7419.000 13.695 2.844 + 7419.500 13.652 2.834 + 7420.000 13.813 2.815 + 7420.500 16.126 2.807 + 7421.000 20.838 2.806 + 7421.500 25.709 2.808 + 7422.000 30.949 2.815 + 7422.500 33.724 2.825 + 7423.000 33.839 2.827 + 7423.500 31.921 2.822 + 7424.000 28.341 2.818 + 7424.500 27.353 2.816 + 7425.000 27.171 2.814 + 7425.500 29.332 2.812 + 7426.000 30.979 2.808 + 7426.500 38.443 2.802 + 7427.000 40.656 2.791 + 7427.500 45.488 2.788 + 7428.000 46.783 2.791 + 7428.500 47.684 2.794 + 7429.000 46.038 2.809 + 7429.500 41.397 2.827 + 7430.000 37.090 2.839 + 7430.500 35.304 2.833 + 7431.000 34.109 2.822 + 7431.500 34.940 2.806 + 7432.000 36.732 2.795 + 7432.500 35.237 2.796 + 7433.000 32.211 2.804 + 7433.500 30.507 2.818 + 7434.000 28.167 2.824 + 7434.500 26.265 2.828 + 7435.000 23.419 2.832 + 7435.500 22.595 2.835 + 7436.000 22.518 2.838 + 7436.500 25.552 2.833 + 7437.000 27.170 2.837 + 7437.500 30.521 2.841 + 7438.000 33.543 2.842 + 7438.500 39.352 2.831 + 7439.000 41.107 2.826 + 7439.500 43.108 2.816 + 7440.000 43.821 2.814 + 7440.500 41.596 2.817 + 7441.000 37.330 2.828 + 7441.500 33.255 2.838 + 7442.000 30.172 2.844 + 7442.500 26.890 2.841 + 7443.000 25.002 2.843 + 7443.500 23.232 2.846 + 7444.000 23.534 2.858 + 7444.500 22.761 2.861 + 7445.000 30.234 2.855 + 7445.500 33.759 2.840 + 7446.000 36.864 2.829 + 7446.500 37.967 2.835 + 7447.000 37.851 2.842 + 7447.500 35.615 2.845 + 7448.000 31.867 2.847 + 7448.500 26.753 2.845 + 7449.000 26.733 2.841 + 7449.500 28.426 2.828 + 7450.000 31.866 2.816 + 7450.500 38.024 2.806 + 7451.000 42.666 2.815 + 7451.500 48.926 2.819 + 7452.000 52.007 2.826 + 7452.500 54.312 2.826 + 7453.000 55.128 2.828 + 7453.500 54.945 2.828 + 7454.000 54.078 2.829 + 7454.500 49.439 2.817 + 7455.000 43.600 2.803 + 7455.500 37.864 2.801 + 7456.000 33.056 2.807 + 7456.500 28.011 2.822 + 7457.000 30.019 2.825 + 7457.500 34.363 2.818 + 7458.000 40.265 2.811 + 7458.500 49.693 2.797 + 7459.000 51.750 2.792 + 7459.500 51.804 2.791 + 7460.000 47.410 2.792 + 7460.500 43.477 2.788 + 7461.000 42.549 2.784 + 7461.500 43.374 2.785 + 7462.000 43.713 2.787 + 7462.500 47.262 2.792 + 7463.000 48.271 2.794 + 7463.500 47.956 2.796 + 7464.000 46.054 2.796 + 7464.500 43.459 2.793 + 7465.000 42.367 2.798 + 7465.500 41.666 2.812 + 7466.000 42.339 2.822 + 7466.500 45.460 2.824 + 7467.000 47.395 2.822 + 7467.500 45.636 2.818 + 7468.000 37.185 2.818 + 7468.500 25.017 2.814 + 7469.000 19.767 2.814 + 7469.500 18.422 2.814 + 7470.000 17.912 2.817 + 7470.500 20.675 2.827 + 7471.000 22.968 2.834 + 7471.500 25.259 2.832 + 7472.000 26.539 2.830 + 7472.500 28.120 2.830 + 7473.000 28.048 2.832 + 7473.500 26.769 2.828 + 7474.000 25.859 2.815 + 7474.500 24.791 2.805 + 7475.000 25.858 2.803 + 7475.500 26.774 2.815 + 7476.000 27.369 2.826 + 7476.500 25.903 2.823 + 7477.000 25.052 2.805 + 7477.500 23.974 2.797 + 7478.000 23.257 2.795 + 7478.500 24.258 2.798 + 7479.000 25.070 2.800 + 7479.500 24.950 2.812 + 7480.000 25.070 2.813 + 7480.500 24.428 2.814 + 7481.000 23.480 2.818 + 7481.500 22.759 2.820 + 7482.000 22.029 2.813 + 7482.500 23.389 2.809 + 7483.000 23.323 2.808 + 7483.500 23.334 2.803 + 7484.000 22.523 2.792 + 7484.500 22.465 2.796 + 7485.000 21.805 2.808 + 7485.500 21.261 2.822 + 7486.000 20.381 2.827 + 7486.500 20.354 2.831 + 7487.000 21.227 2.825 + 7487.500 22.263 2.815 + 7488.000 23.141 2.800 + 7488.500 24.601 2.800 + 7489.000 25.715 2.799 + 7489.500 25.859 2.806 + 7490.000 27.257 2.811 + 7490.500 25.529 2.823 + 7491.000 24.866 2.826 + 7491.500 23.904 2.824 + 7492.000 23.357 2.819 + 7492.500 22.411 2.819 + 7493.000 22.605 2.838 + 7493.500 23.618 2.848 + 7494.000 26.672 2.846 + 7494.500 36.931 2.836 + 7495.000 46.908 2.809 + 7495.500 54.016 2.795 + 7496.000 63.907 2.783 + 7496.500 65.489 2.783 + 7497.000 59.521 2.790 + 7497.500 52.967 2.798 + 7498.000 45.292 2.798 + 7498.500 40.542 2.797 + 7499.000 39.983 2.796 + 7499.500 40.324 2.798 + 7500.000 38.061 2.803 + 7500.500 34.377 2.813 + 7501.000 31.518 2.820 + 7501.500 31.282 2.822 + 7502.000 32.570 2.826 + 7502.500 35.027 2.832 + 7503.000 35.413 2.833 + 7503.500 34.606 2.831 + 7504.000 34.370 2.827 + 7504.500 37.568 2.818 + 7505.000 40.101 2.816 + 7505.500 40.589 2.817 + 7506.000 45.645 2.819 + 7506.500 61.170 2.802 + 7507.000 82.072 2.780 + 7507.500 90.778 2.766 + 7508.000 97.964 2.758 + 7508.500 86.005 2.766 + 7509.000 77.555 2.776 + 7509.500 68.681 2.779 + 7510.000 61.099 2.778 + 7510.500 39.227 2.784 + 7511.000 32.833 2.795 + 7511.500 31.158 2.796 + 7512.000 31.296 2.796 + 7512.500 30.330 2.796 + 7513.000 28.952 2.802 + 7513.500 29.095 2.806 + 7514.000 31.038 2.804 + 7514.500 33.943 2.790 + 7515.000 33.596 2.787 + 7515.500 30.672 2.786 + 7516.000 29.012 2.790 + 7516.500 22.698 2.813 + 7517.000 22.133 2.831 + 7517.500 22.848 2.852 + 7518.000 27.670 2.864 + 7518.500 39.862 2.859 + 7519.000 50.010 2.846 + 7519.500 55.688 2.830 + 7520.000 66.378 2.786 + 7520.500 47.346 2.718 + 7521.000 25.061 2.691 + 7521.500 16.942 2.703 + 7522.000 13.022 2.732 + 7522.500 12.213 2.764 + 7523.000 12.909 2.784 + 7523.500 13.147 2.790 + 7524.000 16.581 2.800 + 7524.500 19.671 2.809 + 7525.000 23.887 2.805 + 7525.500 24.647 2.802 + 7526.000 22.900 2.805 + 7526.500 18.362 2.812 + 7527.000 17.264 2.817 + 7527.500 16.270 2.811 + 7528.000 15.455 2.806 + 7528.500 20.681 2.800 + 7529.000 24.357 2.806 + 7529.500 34.409 2.808 + 7530.000 39.610 2.791 + 7530.500 49.111 2.778 + 7531.000 49.453 2.781 + 7531.500 48.789 2.797 + 7532.000 46.629 2.797 + 7532.500 40.585 2.790 + 7533.000 35.888 2.788 + 7533.500 32.850 2.791 + 7534.000 31.996 2.797 + 7534.500 32.667 2.794 + 7535.000 34.211 2.779 + 7535.500 34.570 2.767 + 7536.000 28.998 2.767 + 7536.500 23.052 2.782 + 7537.000 19.322 2.801 + 7537.500 17.444 2.811 + 7538.000 16.974 2.810 + 7538.500 16.973 2.810 + 7539.000 17.692 2.812 + 7539.500 17.286 2.817 + 7540.000 16.712 2.847 + 7540.500 16.220 2.853 + 7541.000 14.889 2.841 + 7541.500 14.068 2.832 + 7542.000 13.869 2.813 + 7542.500 16.877 2.803 + 7543.000 21.514 2.813 + 7543.500 29.511 2.798 + 7544.000 33.298 2.780 + 7544.500 33.057 2.700 + 7545.000 25.183 2.710 + 7545.500 18.947 2.732 + 7546.000 15.383 2.807 + 7546.500 12.770 2.841 + 7547.000 16.745 2.848 + 7547.500 20.285 2.830 + 7548.000 25.167 2.803 + 7548.500 32.008 2.788 + 7549.000 38.964 2.787 + 7549.500 40.312 2.787 + 7550.000 37.708 2.792 + 7550.500 32.521 2.796 + 7551.000 27.315 2.802 + 7551.500 21.437 2.799 + 7552.000 17.932 2.794 + 7552.500 13.673 2.787 + 7553.000 11.260 2.778 + 7553.500 11.489 2.749 + 7554.000 12.230 2.728 + 7554.500 14.248 2.725 + 7555.000 16.345 2.722 + 7555.500 17.327 2.739 + 7556.000 17.460 2.751 + 7556.500 19.257 2.766 + 7557.000 17.350 2.771 + 7557.500 17.876 2.785 + 7558.000 17.160 2.790 + 7558.500 17.088 2.802 + 7559.000 17.318 2.812 + 7559.500 19.011 2.821 + 7560.000 19.581 2.824 + 7560.500 21.326 2.813 + 7561.000 21.880 2.808 + 7561.500 21.623 2.805 + 7562.000 18.356 2.799 + 7562.500 13.832 2.782 + 7563.000 12.390 2.771 + 7563.500 11.690 2.772 + 7564.000 12.634 2.780 + 7564.500 13.315 2.798 + 7565.000 15.358 2.804 + 7565.500 16.114 2.805 + 7566.000 16.298 2.806 + 7566.500 17.885 2.823 + 7567.000 17.944 2.834 + 7567.500 20.390 2.836 + 7568.000 19.673 2.823 + 7568.500 20.310 2.801 + 7569.000 20.250 2.797 + 7569.500 19.742 2.794 + 7570.000 20.506 2.790 + 7570.500 22.725 2.786 + 7571.000 24.079 2.786 + 7571.500 24.840 2.792 + 7572.000 25.771 2.803 + 7572.500 29.714 2.823 + 7573.000 34.624 2.826 + 7573.500 36.246 2.821 + 7574.000 35.232 2.811 + 7574.500 28.315 2.808 + 7575.000 23.250 2.808 + 7575.500 16.965 2.808 + 7576.000 14.265 2.809 + 7576.500 12.460 2.810 + 7577.000 10.781 2.792 + 7577.500 10.694 2.770 + 7578.000 10.686 2.766 + 7578.500 10.698 2.784 + 7579.000 10.706 2.798 + 7579.500 10.694 2.813 + 7580.000 10.663 2.813 + 7580.500 10.077 2.816 + 7581.000 10.247 2.814 + 7581.500 10.782 2.817 + 7582.000 11.126 2.822 + 7582.500 13.940 2.827 + 7583.000 16.132 2.822 + 7583.500 17.403 2.820 + 7584.000 18.938 2.827 + 7584.500 17.789 2.832 + 7585.000 16.859 2.827 + 7585.500 16.064 2.813 + 7586.000 15.426 2.812 + 7586.500 15.485 2.816 + 7587.000 15.447 2.821 + 7587.500 15.496 2.822 + 7588.000 15.366 2.823 + 7588.500 16.042 2.829 + 7589.000 17.013 2.829 + 7589.500 18.505 2.827 + 7590.000 21.924 2.824 + 7590.500 26.851 2.811 + 7591.000 31.979 2.791 + 7591.500 38.830 2.772 + 7592.000 41.700 2.763 + 7592.500 43.444 2.773 + 7593.000 43.325 2.780 + 7593.500 42.610 2.784 + 7594.000 42.966 2.790 + 7594.500 44.398 2.794 + 7595.000 43.370 2.798 + 7595.500 41.014 2.802 + 7596.000 39.903 2.808 + 7596.500 40.912 2.812 + 7597.000 42.517 2.810 + 7597.500 48.657 2.787 + 7598.000 52.093 2.776 + 7598.500 51.304 2.774 + 7599.000 45.558 2.780 + 7599.500 39.642 2.795 + 7600.000 31.974 2.803 + 7600.500 17.556 2.815 + 7601.000 17.545 2.822 + 7601.500 17.105 2.818 + 7602.000 18.963 2.808 + 7602.500 23.677 2.798 + 7603.000 24.267 2.787 + 7603.500 20.789 2.786 + 7604.000 17.218 2.793 + 7604.500 12.211 2.798 + 7605.000 10.866 2.799 + 7605.500 10.276 2.802 + 7606.000 10.695 2.807 + 7606.500 11.277 2.818 + 7607.000 12.047 2.827 + 7607.500 12.944 2.833 + 7608.000 13.306 2.837 + 7608.500 13.335 2.883 + 7609.000 13.102 2.879 + 7609.500 12.987 2.873 + 7610.000 13.769 2.828 + 7610.500 13.904 2.812 + 7611.000 13.821 2.799 + 7611.500 14.525 2.816 + 7612.000 14.677 2.839 + 7612.500 14.583 2.803 + 7613.000 13.560 2.775 + 7613.500 13.075 2.732 + 7614.000 13.497 2.716 + 7614.500 16.364 2.736 + 7615.000 19.018 2.772 + 7615.500 21.986 2.799 + 7616.000 24.037 2.820 + 7616.500 28.325 2.841 + 7617.000 28.751 2.833 + 7617.500 28.959 2.801 + 7618.000 26.235 2.761 + 7618.500 21.863 2.778 + 7619.000 18.868 2.811 + 7619.500 16.030 2.818 + 7620.000 13.499 2.806 + 7620.500 10.359 2.797 + 7621.000 9.250 2.781 + 7621.500 8.536 2.759 + 7622.000 8.399 2.684 + 7622.500 9.138 2.689 + 7623.000 10.068 2.735 + 7623.500 13.613 2.749 + 7624.000 20.030 2.780 + 7624.500 21.836 2.768 + 7625.000 22.582 2.764 + 7625.500 21.691 2.772 + 7626.000 19.387 2.774 + 7626.500 17.995 2.760 + 7627.000 18.480 2.749 + 7627.500 21.795 2.765 + 7628.000 27.613 2.780 + 7628.500 30.434 2.823 + 7629.000 28.839 2.817 + 7629.500 24.295 2.809 + 7630.000 20.356 2.812 + 7630.500 18.649 2.820 + 7631.000 19.346 2.829 + 7631.500 18.570 2.833 + 7632.000 19.485 2.830 + 7632.500 24.036 2.814 + 7633.000 23.876 2.816 + 7633.500 23.401 2.819 + 7634.000 23.729 2.817 + 7634.500 25.071 2.803 + 7635.000 27.957 2.793 + 7635.500 29.828 2.790 + 7636.000 36.662 2.793 + 7636.500 40.101 2.800 + 7637.000 43.496 2.797 + 7637.500 45.782 2.792 + 7638.000 48.073 2.786 + 7638.500 48.056 2.781 + 7639.000 49.467 2.779 + 7639.500 50.576 2.776 + 7640.000 48.662 2.776 + 7640.500 45.321 2.776 + 7641.000 40.041 2.787 + 7641.500 28.991 2.797 + 7642.000 19.050 2.809 + 7642.500 15.398 2.808 + 7643.000 15.555 2.810 + 7643.500 17.426 2.816 + 7644.000 19.016 2.821 + 7644.500 20.225 2.822 + 7645.000 21.637 2.819 + 7645.500 22.505 2.816 + 7646.000 24.754 2.821 + 7646.500 27.848 2.830 + 7647.000 28.184 2.829 + 7647.500 28.162 2.821 + 7648.000 27.450 2.813 + 7648.500 24.333 2.813 + 7649.000 24.146 2.817 + 7649.500 22.514 2.820 + 7650.000 21.190 2.823 + 7650.500 20.779 2.810 + 7651.000 22.887 2.806 + 7651.500 24.423 2.808 + 7652.000 26.524 2.811 + 7652.500 27.084 2.804 + 7653.000 25.912 2.806 + 7653.500 25.785 2.816 + 7654.000 26.219 2.821 + 7654.500 25.723 2.819 + 7655.000 25.965 2.816 + 7655.500 26.558 2.807 + 7656.000 27.358 2.800 + 7656.500 29.883 2.794 + 7657.000 30.672 2.793 + 7657.500 32.186 2.795 + 7658.000 34.989 2.800 + 7658.500 49.365 2.817 + 7659.000 60.757 2.816 + 7659.500 73.664 2.805 + 7660.000 87.961 2.770 + 7660.500 73.409 2.744 + 7661.000 59.087 2.743 + 7661.500 44.366 2.765 + 7662.000 37.831 2.782 + 7662.500 28.227 2.794 + 7663.000 23.566 2.800 + 7663.500 21.947 2.808 + 7664.000 23.654 2.810 + 7664.500 36.756 2.796 + 7665.000 48.781 2.779 + 7665.500 59.743 2.757 + 7666.000 65.965 2.753 + 7666.500 42.857 2.752 + 7667.000 31.725 2.785 + 7667.500 20.042 2.795 + 7668.000 19.311 2.795 + 7668.500 18.080 2.795 + 7669.000 19.942 2.797 + 7669.500 20.155 2.802 + 7670.000 20.918 2.800 + 7670.500 24.924 2.796 + 7671.000 30.254 2.794 + 7671.500 36.177 2.794 + 7672.000 42.878 2.794 + 7672.500 47.685 2.787 + 7673.000 46.434 2.775 + 7673.500 44.334 2.775 + 7674.000 45.274 2.778 + 7674.500 50.727 2.782 + 7675.000 53.083 2.781 + 7675.500 59.779 2.770 + 7676.000 64.663 2.758 + 7676.500 70.255 2.732 + 7677.000 58.809 2.738 + 7677.500 42.901 2.751 + 7678.000 25.886 2.777 + 7678.500 16.835 2.806 + 7679.000 16.301 2.806 + 7679.500 17.222 2.797 + 7680.000 20.598 2.793 + 7680.500 24.250 2.791 + 7681.000 28.196 2.794 + 7681.500 33.933 2.800 + 7682.000 37.237 2.797 + 7682.500 38.391 2.793 + 7683.000 38.841 2.793 + 7683.500 31.367 2.798 + 7684.000 25.733 2.800 + 7684.500 25.486 2.794 + 7685.000 27.080 2.786 + 7685.500 39.611 2.782 + 7686.000 60.967 2.778 + 7686.500 71.169 2.774 + 7687.000 60.144 2.775 + 7687.500 43.619 2.775 + 7688.000 31.573 2.788 + 7688.500 21.201 2.791 + 7689.000 20.147 2.802 + 7689.500 19.938 2.804 + 7690.000 26.291 2.809 + 7690.500 39.564 2.805 + 7691.000 61.078 2.799 + 7691.500 64.496 2.778 + 7692.000 67.896 2.767 + 7692.500 48.169 2.777 + 7693.000 41.509 2.794 + 7693.500 34.580 2.798 + 7694.000 30.791 2.801 + 7694.500 25.940 2.797 + 7695.000 25.605 2.793 + 7695.500 24.804 2.789 + 7696.000 24.966 2.782 + 7696.500 25.179 2.773 + 7697.000 25.765 2.768 + 7697.500 31.039 2.769 + 7698.000 34.017 2.774 + 7698.500 45.028 2.790 + 7699.000 57.802 2.784 + 7699.500 61.215 2.769 + 7700.000 58.128 2.760 + 7700.500 52.931 2.746 + 7701.000 51.005 2.747 + 7701.500 52.038 2.759 + 7702.000 53.753 2.773 + 7702.500 57.996 2.769 + 7703.000 60.450 2.749 + 7703.500 60.314 2.747 + 7704.000 62.411 2.746 + 7704.500 44.445 2.749 + 7705.000 35.772 2.776 + 7705.500 23.451 2.802 + 7706.000 18.670 2.826 + 7706.500 13.994 2.831 + 7707.000 13.916 2.831 + 7707.500 14.688 2.816 + 7708.000 17.750 2.800 + 7708.500 26.942 2.789 + 7709.000 35.639 2.781 + 7709.500 36.256 2.785 + 7710.000 30.767 2.792 + 7710.500 24.919 2.816 + 7711.000 18.953 2.824 + 7711.500 17.211 2.828 + 7712.000 18.006 2.822 + 7712.500 19.622 2.828 + 7713.000 21.171 2.832 + 7713.500 21.283 2.834 + 7714.000 21.885 2.830 + 7714.500 21.469 2.824 + 7715.000 20.064 2.817 + 7715.500 18.520 2.823 + 7716.000 15.621 2.829 + 7716.500 11.807 2.840 + 7717.000 11.578 2.843 + 7717.500 11.325 2.844 + 7718.000 12.155 2.838 + 7718.500 12.283 2.835 + 7719.000 12.182 2.842 + 7719.500 12.987 2.862 + 7720.000 14.337 2.853 + 7720.500 17.742 2.836 + 7721.000 23.136 2.823 + 7721.500 33.554 2.805 + 7722.000 41.400 2.787 + 7722.500 55.774 2.770 + 7723.000 51.824 2.763 + 7723.500 41.287 2.768 + 7724.000 31.789 2.789 + 7724.500 20.761 2.803 + 7725.000 15.483 2.830 + 7725.500 12.148 2.844 + 7726.000 12.136 2.854 + 7726.500 12.048 2.850 + 7727.000 12.227 2.838 + 7727.500 12.338 2.828 + 7728.000 12.444 2.816 + 7728.500 12.927 2.810 + 7729.000 12.741 2.815 + 7729.500 12.130 2.824 + 7730.000 12.853 2.827 + 7730.500 12.166 2.828 + 7731.000 12.310 2.830 + 7731.500 12.312 2.831 + 7732.000 12.974 2.841 + 7732.500 16.855 2.844 + 7733.000 21.439 2.838 + 7733.500 28.597 2.834 + 7734.000 33.344 2.826 + 7734.500 34.351 2.819 + 7735.000 31.728 2.800 + 7735.500 29.835 2.803 + 7736.000 28.465 2.801 + 7736.500 32.515 2.813 + 7737.000 35.344 2.815 + 7737.500 37.014 2.812 + 7738.000 36.702 2.809 + 7738.500 39.801 2.810 + 7739.000 40.138 2.815 + 7739.500 39.068 2.819 + 7740.000 35.607 2.820 + 7740.500 28.416 2.818 + 7741.000 25.524 2.816 + 7741.500 24.990 2.817 + 7742.000 26.625 2.820 + 7742.500 28.008 2.814 + 7743.000 27.259 2.801 + 7743.500 26.469 2.794 + 7744.000 27.262 2.784 + 7744.500 29.728 2.791 + 7745.000 32.265 2.802 + 7745.500 33.354 2.813 + 7746.000 34.730 2.816 + 7746.500 35.941 2.818 + 7747.000 36.433 2.815 + 7747.500 35.765 2.807 + 7748.000 34.459 2.800 + 7748.500 32.142 2.794 + 7749.000 31.424 2.795 + 7749.500 28.976 2.793 + 7750.000 26.893 2.785 + 7750.500 25.535 2.781 + 7751.000 24.871 2.793 + 7751.500 24.387 2.796 + 7752.000 23.039 2.800 + 7752.500 20.781 2.800 + 7753.000 20.195 2.798 + 7753.500 20.294 2.805 + 7754.000 21.809 2.810 + 7754.500 24.130 2.813 + 7755.000 26.679 2.813 + 7755.500 30.518 2.814 + 7756.000 34.781 2.825 + 7756.500 41.944 2.835 + 7757.000 42.575 2.830 + 7757.500 39.419 2.813 + 7758.000 34.474 2.804 + 7758.500 23.896 2.802 + 7759.000 19.461 2.804 + 7759.500 19.247 2.810 + 7760.000 19.768 2.819 + 7760.500 22.953 2.828 + 7761.000 24.024 2.833 + 7761.500 23.404 2.826 + 7762.000 23.034 2.822 + 7762.500 25.156 2.822 + 7763.000 28.640 2.822 + 7763.500 31.871 2.824 + 7764.000 31.867 2.824 + 7764.500 31.620 2.823 + 7765.000 30.576 2.818 + 7765.500 29.897 2.810 + 7766.000 32.038 2.812 + 7766.500 36.057 2.812 + 7767.000 36.951 2.805 + 7767.500 35.000 2.802 + 7768.000 30.137 2.804 + 7768.500 27.153 2.821 + 7769.000 25.687 2.824 + 7769.500 32.020 2.826 + 7770.000 38.239 2.829 + 7770.500 42.433 2.806 + 7771.000 42.661 2.776 + 7771.500 36.249 2.766 + 7772.000 37.994 2.763 + 7772.500 45.738 2.763 + 7773.000 53.559 2.763 + 7773.500 63.416 2.760 + 7774.000 68.392 2.759 + 7774.500 66.445 2.761 + 7775.000 57.872 2.773 + 7775.500 48.796 2.786 + 7776.000 47.950 2.792 + 7776.500 43.915 2.785 + 7777.000 39.781 2.782 + 7777.500 30.115 2.785 + 7778.000 23.222 2.793 + 7778.500 22.038 2.809 + 7779.000 26.020 2.817 + 7779.500 29.540 2.823 + 7780.000 42.778 2.812 + 7780.500 60.129 2.783 + 7781.000 83.767 2.748 + 7781.500 79.232 2.736 + 7782.000 62.728 2.731 + 7782.500 41.096 2.753 + 7783.000 25.215 2.783 + 7783.500 25.387 2.801 + 7784.000 25.717 2.811 + 7784.500 26.353 2.815 + 7785.000 27.446 2.816 + 7785.500 33.720 2.823 + 7786.000 39.501 2.826 + 7786.500 41.794 2.816 + 7787.000 41.592 2.801 + 7787.500 37.864 2.795 + 7788.000 32.224 2.792 + 7788.500 27.022 2.794 + 7789.000 22.338 2.795 + 7789.500 20.882 2.802 + 7790.000 20.142 2.811 + 7790.500 23.124 2.814 + 7791.000 26.805 2.815 + 7791.500 24.781 2.808 + 7792.000 22.051 2.804 + 7792.500 20.422 2.814 + 7793.000 21.671 2.820 + 7793.500 23.041 2.819 + 7794.000 27.647 2.818 + 7794.500 30.103 2.818 + 7795.000 31.677 2.822 + 7795.500 34.369 2.833 + 7796.000 35.816 2.841 + 7796.500 41.063 2.830 + 7797.000 45.928 2.817 + 7797.500 57.730 2.808 + 7798.000 62.607 2.807 + 7798.500 73.550 2.797 + 7799.000 80.634 2.781 + 7799.500 83.572 2.768 + 7800.000 79.918 2.763 + 7800.500 51.195 2.760 + 7801.000 39.140 2.761 + 7801.500 35.142 2.762 + 7802.000 31.723 2.757 + 7802.500 34.243 2.801 + 7803.000 40.684 2.814 + 7803.500 38.690 2.814 + 7804.000 36.645 2.801 + 7804.500 26.504 2.793 + 7805.000 18.468 2.786 + 7805.500 14.127 2.808 + 7806.000 14.105 2.809 + 7806.500 15.830 2.838 + 7807.000 17.004 2.843 + 7807.500 18.525 2.842 + 7808.000 19.230 2.834 + 7808.500 19.563 2.828 + 7809.000 17.933 2.823 + 7809.500 15.536 2.815 + 7810.000 14.724 2.814 + 7810.500 13.380 2.820 + 7811.000 13.635 2.829 + 7811.500 15.198 2.832 + 7812.000 19.097 2.828 + 7812.500 22.896 2.812 + 7813.000 27.291 2.802 + 7813.500 31.727 2.803 + 7814.000 36.612 2.807 + 7814.500 40.041 2.818 + 7815.000 39.836 2.810 + 7815.500 36.668 2.800 + 7816.000 34.097 2.790 + 7816.500 29.961 2.790 + 7817.000 26.351 2.792 + 7817.500 21.391 2.800 + 7818.000 19.893 2.815 + 7818.500 14.955 2.829 + 7819.000 12.898 2.825 + 7819.500 11.381 2.821 + 7820.000 12.147 2.824 + 7820.500 13.817 2.848 + 7821.000 17.249 2.846 + 7821.500 17.797 2.835 + 7822.000 22.560 2.822 + 7822.500 26.670 2.818 + 7823.000 30.038 2.824 + 7823.500 27.967 2.831 + 7824.000 23.273 2.841 + 7824.500 20.636 2.845 + 7825.000 19.171 2.850 + 7825.500 20.148 2.848 + 7826.000 20.320 2.845 + 7826.500 22.396 2.828 + 7827.000 27.791 2.821 + 7827.500 36.807 2.805 + 7828.000 43.507 2.795 + 7828.500 47.067 2.790 + 7829.000 43.004 2.793 + 7829.500 37.879 2.811 + 7830.000 35.920 2.837 + 7830.500 32.221 2.845 + 7831.000 29.031 2.844 + 7831.500 28.094 2.836 + 7832.000 28.153 2.816 + 7832.500 28.347 2.810 + 7833.000 28.960 2.804 + 7833.500 29.589 2.801 + 7834.000 29.733 2.799 + 7834.500 29.853 2.803 + 7835.000 29.692 2.809 + 7835.500 29.646 2.798 + 7836.000 28.537 2.794 + 7836.500 25.367 2.792 + 7837.000 22.666 2.790 + 7837.500 22.631 2.792 + 7838.000 24.011 2.797 + 7838.500 23.290 2.805 + 7839.000 23.218 2.806 + 7839.500 22.325 2.805 + 7840.000 22.383 2.806 + 7840.500 24.312 2.807 + 7841.000 29.303 2.801 + 7841.500 34.943 2.796 + 7842.000 50.912 2.792 + 7842.500 61.208 2.786 + 7843.000 61.986 2.790 + 7843.500 52.500 2.799 + 7844.000 40.010 2.826 + 7844.500 26.791 2.818 + 7845.000 21.116 2.803 + 7845.500 20.159 2.803 + 7846.000 20.198 2.804 + 7846.500 19.251 2.819 + 7847.000 19.626 2.815 + 7847.500 21.173 2.806 + 7848.000 22.467 2.797 + 7848.500 24.820 2.794 + 7849.000 24.749 2.793 + 7849.500 24.071 2.791 + 7850.000 22.886 2.791 + 7850.500 25.559 2.799 + 7851.000 27.997 2.805 + 7851.500 28.222 2.804 + 7852.000 29.689 2.802 + 7852.500 30.484 2.800 + 7853.000 32.064 2.798 + 7853.500 34.458 2.796 + 7854.000 35.520 2.796 + 7854.500 33.645 2.782 + 7855.000 30.295 2.780 + 7855.500 28.006 2.781 + 7856.000 27.743 2.788 + 7856.500 28.643 2.826 + 7857.000 30.486 2.831 + 7857.500 31.177 2.836 + 7858.000 31.152 2.831 + 7858.500 30.601 2.815 + 7859.000 29.787 2.809 + 7859.500 28.649 2.806 + 7860.000 29.175 2.809 + 7860.500 31.436 2.811 + 7861.000 32.789 2.812 + 7861.500 33.488 2.813 + 7862.000 34.412 2.816 + 7862.500 34.394 2.816 + 7863.000 33.442 2.815 + 7863.500 31.060 2.800 + 7864.000 29.059 2.794 + 7864.500 26.804 2.797 + 7865.000 27.052 2.807 + 7865.500 29.271 2.803 + 7866.000 31.407 2.794 + 7866.500 30.746 2.795 + 7867.000 30.228 2.802 + 7867.500 31.038 2.823 + 7868.000 33.114 2.828 + 7868.500 35.488 2.813 + 7869.000 36.135 2.805 + 7869.500 36.191 2.802 + 7870.000 37.868 2.806 + 7870.500 40.151 2.799 + 7871.000 42.092 2.791 + 7871.500 41.513 2.788 + 7872.000 39.798 2.795 + 7872.500 34.845 2.805 + 7873.000 31.190 2.842 + 7873.500 29.752 2.840 + 7874.000 30.771 2.829 + 7874.500 29.831 2.821 + 7875.000 27.396 2.820 + 7875.500 24.571 2.816 + 7876.000 22.327 2.810 + 7876.500 21.993 2.811 + 7877.000 21.146 2.819 + 7877.500 16.515 2.840 + 7878.000 13.055 2.843 + 7878.500 10.548 2.843 + 7879.000 9.782 2.839 + 7879.500 10.501 2.839 + 7880.000 11.802 2.837 + 7880.500 15.434 2.828 + 7881.000 19.284 2.830 + 7881.500 21.938 2.831 + 7882.000 23.601 2.835 + 7882.500 24.908 2.835 + 7883.000 22.534 2.838 + 7883.500 20.993 2.842 + 7884.000 20.355 2.844 + 7884.500 20.820 2.846 + 7885.000 20.588 2.845 + 7885.500 24.154 2.844 + 7886.000 25.637 2.835 + 7886.500 25.449 2.827 + 7887.000 23.195 2.826 + 7887.500 20.911 2.827 + 7888.000 20.435 2.828 + 7888.500 22.092 2.822 + 7889.000 23.662 2.813 + 7889.500 26.785 2.804 + 7890.000 29.180 2.801 + 7890.500 31.938 2.809 + 7891.000 33.674 2.813 + 7891.500 36.184 2.806 + 7892.000 36.970 2.798 + 7892.500 36.760 2.802 + 7893.000 35.902 2.813 + 7893.500 34.649 2.820 + 7894.000 32.267 2.820 + 7894.500 31.129 2.813 + 7895.000 32.230 2.809 + 7895.500 33.161 2.807 + 7896.000 35.572 2.806 + 7896.500 38.777 2.820 + 7897.000 40.169 2.830 + 7897.500 40.690 2.832 + 7898.000 38.057 2.829 + 7898.500 32.954 2.827 + 7899.000 32.960 2.824 + 7899.500 33.379 2.822 + 7900.000 35.528 2.818 + 7900.500 38.637 2.810 + 7901.000 42.745 2.802 + 7901.500 43.305 2.794 + 7902.000 44.374 2.788 + 7902.500 42.939 2.782 + 7903.000 42.518 2.781 + 7903.500 42.936 2.779 + 7904.000 45.314 2.779 + 7904.500 49.312 2.777 + 7905.000 52.963 2.772 + 7905.500 54.088 2.773 + 7906.000 53.070 2.772 + 7906.500 43.495 2.781 + 7907.000 38.886 2.793 + 7907.500 30.030 2.798 + 7908.000 29.409 2.796 + 7908.500 27.194 2.830 + 7909.000 26.262 2.835 + 7909.500 23.921 2.837 + 7910.000 22.179 2.833 + 7910.500 18.942 2.821 + 7911.000 16.085 2.816 + 7911.500 15.279 2.817 + 7912.000 13.965 2.824 + 7912.500 12.108 2.829 + 7913.000 11.963 2.834 + 7913.500 13.389 2.836 + 7914.000 15.905 2.833 + 7914.500 18.525 2.826 + 7915.000 19.948 2.823 + 7915.500 24.124 2.817 + 7916.000 26.694 2.810 + 7916.500 33.552 2.794 + 7917.000 36.189 2.781 + 7917.500 37.007 2.778 + 7918.000 34.896 2.784 + 7918.500 30.420 2.795 + 7919.000 27.108 2.804 + 7919.500 23.163 2.811 + 7920.000 22.034 2.829 + 7920.500 21.190 2.843 + 7921.000 21.131 2.847 + 7921.500 22.640 2.792 + 7922.000 25.663 2.779 + 7922.500 25.769 2.774 + 7923.000 24.858 2.785 + 7923.500 21.501 2.807 + 7924.000 20.941 2.813 + 7924.500 20.219 2.807 + 7925.000 21.619 2.809 + 7925.500 23.426 2.809 + 7926.000 25.590 2.820 + 7926.500 29.896 2.823 + 7927.000 32.751 2.822 + 7927.500 34.587 2.818 + 7928.000 34.191 2.815 + 7928.500 32.603 2.814 + 7929.000 32.293 2.811 + 7929.500 31.422 2.801 + 7930.000 31.051 2.799 + 7930.500 26.330 2.794 + 7931.000 24.042 2.796 + 7931.500 22.468 2.799 + 7932.000 22.753 2.803 + 7932.500 26.456 2.819 + 7933.000 31.058 2.821 + 7933.500 35.776 2.820 + 7934.000 41.476 2.805 + 7934.500 43.711 2.791 + 7935.000 41.864 2.797 + 7935.500 38.116 2.803 + 7936.000 36.922 2.809 + 7936.500 36.785 2.813 + 7937.000 36.822 2.814 + 7937.500 32.956 2.815 + 7938.000 28.889 2.812 + 7938.500 27.175 2.805 + 7939.000 28.185 2.805 + 7939.500 31.456 2.810 + 7940.000 33.704 2.813 + 7940.500 34.301 2.814 + 7941.000 34.739 2.816 + 7941.500 35.471 2.818 + 7942.000 37.289 2.812 + 7942.500 38.843 2.795 + 7943.000 38.501 2.786 + 7943.500 37.878 2.784 + 7944.000 36.476 2.789 + 7944.500 34.125 2.812 + 7945.000 32.168 2.816 + 7945.500 29.764 2.803 + 7946.000 29.687 2.791 + 7946.500 23.105 2.797 + 7947.000 20.511 2.813 + 7947.500 14.765 2.825 + 7948.000 12.235 2.825 + 7948.500 11.492 2.824 + 7949.000 13.462 2.825 + 7949.500 18.167 2.831 + 7950.000 24.516 2.832 + 7950.500 32.581 2.836 + 7951.000 33.243 2.828 + 7951.500 33.646 2.817 + 7952.000 34.230 2.809 + 7952.500 35.777 2.805 + 7953.000 36.899 2.800 + 7953.500 38.468 2.794 + 7954.000 38.528 2.789 + 7954.500 40.816 2.778 + 7955.000 43.769 2.774 + 7955.500 42.970 2.778 + 7956.000 42.356 2.778 + 7956.500 40.975 2.774 + 7957.000 40.858 2.779 + 7957.500 41.539 2.779 + 7958.000 43.135 2.772 + 7958.500 40.716 2.793 + 7959.000 38.782 2.806 + 7959.500 33.987 2.821 + 7960.000 30.504 2.817 + 7960.500 25.462 2.805 + 7961.000 21.152 2.797 + 7961.500 19.478 2.797 + 7962.000 18.642 2.802 + 7962.500 20.642 2.814 + 7963.000 25.579 2.809 + 7963.500 32.469 2.781 + 7964.000 39.787 2.775 + 7964.500 39.838 2.754 + 7965.000 35.542 2.761 + 7965.500 31.812 2.782 + 7966.000 28.854 2.795 + 7966.500 28.178 2.807 + 7967.000 28.140 2.812 + 7967.500 28.821 2.812 + 7968.000 31.100 2.816 + 7968.500 31.908 2.820 + 7969.000 32.593 2.826 + 7969.500 32.062 2.825 + 7970.000 29.119 2.825 + 7970.500 26.775 2.811 + 7971.000 24.479 2.809 + 7971.500 23.335 2.809 + 7972.000 24.723 2.804 + 7972.500 28.102 2.798 + 7973.000 34.965 2.786 + 7973.500 42.374 2.770 + 7974.000 50.226 2.760 + 7974.500 47.634 2.758 + 7975.000 43.691 2.784 + 7975.500 35.716 2.806 + 7976.000 32.249 2.829 + 7976.500 31.779 2.869 + 7977.000 34.476 2.883 + 7977.500 35.416 2.873 + 7978.000 36.566 2.857 + 7978.500 30.415 2.798 + 7979.000 27.298 2.786 + 7979.500 26.512 2.776 + 7980.000 28.194 2.777 + 7980.500 31.660 2.781 + 7981.000 36.261 2.787 + 7981.500 37.938 2.794 + 7982.000 37.415 2.796 + 7982.500 39.114 2.795 + 7983.000 41.630 2.794 + 7983.500 47.066 2.793 + 7984.000 48.673 2.797 + 7984.500 47.828 2.801 + 7985.000 41.817 2.806 + 7985.500 38.863 2.807 + 7986.000 34.667 2.810 + 7986.500 31.292 2.820 + 7987.000 31.333 2.823 + 7987.500 31.355 2.815 + 7988.000 31.295 2.795 + 7988.500 28.617 2.794 + 7989.000 24.765 2.798 + 7989.500 24.242 2.807 + 7990.000 25.213 2.813 + 7990.500 29.948 2.808 + 7991.000 39.316 2.798 + 7991.500 39.920 2.796 + 7992.000 41.286 2.797 + 7992.500 33.824 2.803 + 7993.000 29.936 2.809 + 7993.500 29.037 2.822 + 7994.000 29.540 2.824 + 7994.500 35.508 2.817 + 7995.000 39.773 2.801 + 7995.500 43.870 2.798 + 7996.000 46.385 2.798 + 7996.500 48.109 2.798 + 7997.000 47.178 2.798 + 7997.500 46.236 2.799 + 7998.000 44.671 2.800 + 7998.500 41.236 2.798 + 7999.000 40.884 2.798 + 7999.500 41.611 2.799 + 8000.000 44.093 2.794 + 8000.500 46.450 2.783 + 8001.000 46.522 2.775 + 8001.500 42.791 2.773 + 8002.000 38.402 2.788 + 8002.500 31.271 2.807 + 8003.000 29.590 2.813 + 8003.500 31.620 2.805 + 8004.000 37.300 2.784 + 8004.500 44.833 2.775 + 8005.000 47.621 2.775 + 8005.500 37.598 2.783 + 8006.000 33.139 2.799 + 8006.500 32.130 2.804 + 8007.000 32.207 2.813 + 8007.500 33.000 2.818 + 8008.000 31.210 2.818 + 8008.500 28.539 2.814 + 8009.000 27.992 2.802 + 8009.500 30.391 2.794 + 8010.000 35.464 2.782 + 8010.500 35.567 2.772 + 8011.000 30.818 2.774 + 8011.500 25.279 2.783 + 8012.000 21.606 2.793 + 8012.500 24.568 2.824 + 8013.000 32.551 2.818 + 8013.500 39.575 2.800 + 8014.000 49.284 2.784 + 8014.500 46.600 2.765 + 8015.000 33.720 2.777 + 8015.500 28.502 2.804 + 8016.000 22.584 2.809 + 8016.500 23.649 2.829 + 8017.000 26.150 2.833 + 8017.500 28.222 2.833 + 8018.000 30.583 2.828 + 8018.500 32.293 2.815 + 8019.000 34.017 2.799 + 8019.500 41.363 2.792 + 8020.000 48.468 2.782 + 8020.500 55.982 2.775 + 8021.000 58.322 2.770 + 8021.500 57.810 2.769 + 8022.000 52.846 2.768 + 8022.500 48.254 2.786 + 8023.000 41.116 2.798 + 8023.500 33.942 2.807 + 8024.000 34.927 2.803 + 8024.500 42.480 2.787 + 8025.000 51.393 2.768 + 8025.500 61.327 2.757 + 8026.000 64.568 2.730 + 8026.500 49.316 2.746 + 8027.000 40.889 2.762 + 8027.500 33.724 2.792 + 8028.000 29.407 2.815 + 8028.500 22.948 2.823 + 8029.000 23.756 2.826 + 8029.500 24.070 2.811 + 8030.000 28.419 2.800 + 8030.500 31.364 2.798 + 8031.000 31.217 2.809 + 8031.500 27.607 2.830 + 8032.000 23.183 2.829 + 8032.500 21.171 2.817 + 8033.000 18.082 2.814 + 8033.500 17.211 2.821 + 8034.000 17.085 2.823 + 8034.500 16.942 2.824 + 8035.000 17.733 2.822 + 8035.500 17.829 2.825 + 8036.000 17.748 2.831 + 8036.500 16.823 2.829 + 8037.000 16.015 2.835 + 8037.500 15.502 2.842 + 8038.000 14.980 2.852 + 8038.500 15.557 2.866 + 8039.000 15.995 2.867 + 8039.500 18.758 2.865 + 8040.000 20.511 2.854 + 8040.500 21.681 2.818 + 8041.000 24.486 2.808 + 8041.500 24.695 2.803 + 8042.000 24.690 2.797 + 8042.500 21.877 2.802 + 8043.000 20.547 2.809 + 8043.500 18.484 2.817 + 8044.000 18.569 2.821 + 8044.500 19.513 2.815 + 8045.000 19.981 2.806 + 8045.500 20.845 2.797 + 8046.000 21.151 2.799 + 8046.500 22.504 2.808 + 8047.000 22.149 2.818 + 8047.500 21.951 2.822 + 8048.000 23.086 2.822 + 8048.500 22.999 2.820 + 8049.000 24.317 2.819 + 8049.500 26.320 2.816 + 8050.000 26.913 2.806 + 8050.500 27.628 2.790 + 8051.000 24.085 2.789 + 8051.500 21.241 2.790 + 8052.000 19.720 2.795 + 8052.500 20.818 2.808 + 8053.000 22.107 2.821 + 8053.500 24.601 2.839 + 8054.000 24.929 2.852 + 8054.500 25.621 2.848 + 8055.000 26.490 2.844 + 8055.500 25.849 2.827 + 8056.000 24.212 2.823 + 8056.500 21.954 2.815 + 8057.000 21.166 2.815 + 8057.500 19.526 2.816 + 8058.000 18.702 2.818 + 8058.500 17.172 2.826 + 8059.000 16.476 2.826 + 8059.500 16.095 2.821 + 8060.000 17.445 2.814 + 8060.500 18.702 2.802 + 8061.000 22.083 2.806 + 8061.500 27.382 2.807 + 8062.000 30.501 2.798 + 8062.500 33.593 2.793 + 8063.000 32.925 2.793 + 8063.500 30.058 2.798 + 8064.000 29.492 2.806 + 8064.500 32.326 2.815 + 8065.000 33.370 2.812 + 8065.500 34.533 2.808 + 8066.000 32.942 2.804 + 8066.500 31.234 2.800 + 8067.000 28.376 2.796 + 8067.500 25.826 2.793 + 8068.000 24.267 2.793 + 8068.500 21.826 2.810 + 8069.000 23.334 2.817 + 8069.500 24.453 2.815 + 8070.000 26.597 2.816 + 8070.500 26.306 2.801 + 8071.000 24.323 2.795 + 8071.500 24.071 2.790 + 8072.000 25.629 2.784 + 8072.500 27.428 2.794 + 8073.000 29.538 2.802 + 8073.500 30.597 2.804 + 8074.000 30.839 2.807 + 8074.500 30.091 2.812 + 8075.000 29.502 2.824 + 8075.500 27.864 2.840 + 8076.000 27.246 2.839 + 8076.500 26.000 2.838 + 8077.000 25.190 2.834 + 8077.500 24.760 2.830 + 8078.000 24.648 2.823 + 8078.500 26.086 2.802 + 8079.000 28.123 2.795 + 8079.500 30.369 2.788 + 8080.000 30.512 2.787 + 8080.500 30.042 2.788 + 8081.000 29.788 2.793 + 8081.500 31.647 2.798 + 8082.000 33.094 2.803 + 8082.500 34.399 2.797 + 8083.000 32.178 2.786 + 8083.500 28.031 2.786 + 8084.000 25.252 2.800 + 8084.500 21.753 2.811 + 8085.000 27.547 2.814 + 8085.500 30.801 2.813 + 8086.000 34.694 2.813 + 8086.500 38.825 2.814 + 8087.000 39.077 2.814 + 8087.500 40.165 2.812 + 8088.000 39.984 2.806 + 8088.500 42.947 2.793 + 8089.000 44.854 2.786 + 8089.500 44.268 2.782 + 8090.000 43.089 2.782 + 8090.500 38.064 2.786 + 8091.000 33.896 2.790 + 8091.500 29.012 2.792 + 8092.000 26.655 2.799 + 8092.500 25.870 2.804 + 8093.000 24.121 2.814 + 8093.500 23.300 2.816 + 8094.000 25.084 2.823 + 8094.500 30.121 2.828 + 8095.000 33.903 2.831 + 8095.500 34.511 2.827 + 8096.000 33.008 2.823 + 8096.500 30.785 2.820 + 8097.000 29.374 2.817 + 8097.500 28.141 2.816 + 8098.000 27.193 2.819 + 8098.500 25.465 2.831 + 8099.000 24.807 2.839 + 8099.500 23.914 2.843 + 8100.000 23.253 2.828 + 8100.500 23.013 2.814 + 8101.000 21.330 2.803 + 8101.500 22.434 2.803 + 8102.000 24.723 2.825 + 8102.500 32.156 2.839 + 8103.000 40.004 2.825 + 8103.500 41.365 2.777 + 8104.000 43.411 2.765 + 8104.500 36.271 2.772 + 8105.000 34.383 2.773 + 8105.500 39.196 2.763 + 8106.000 48.116 2.747 + 8106.500 53.057 2.747 + 8107.000 48.985 2.751 + 8107.500 38.178 2.768 + 8108.000 30.473 2.796 + 8108.500 20.597 2.807 + 8109.000 19.574 2.853 + 8109.500 19.582 2.848 + 8110.000 20.266 2.835 + 8110.500 20.194 2.816 + 8111.000 20.231 2.812 + 8111.500 20.135 2.812 + 8112.000 20.900 2.819 + 8112.500 20.971 2.828 + 8113.000 21.059 2.830 + 8113.500 21.243 2.818 + 8114.000 21.664 2.809 + 8114.500 23.837 2.801 + 8115.000 25.944 2.801 + 8115.500 28.372 2.797 + 8116.000 29.001 2.791 + 8116.500 28.480 2.791 + 8117.000 26.881 2.797 + 8117.500 24.164 2.812 + 8118.000 21.837 2.821 + 8118.500 19.525 2.820 + 8119.000 18.718 2.816 + 8119.500 19.725 2.816 + 8120.000 20.775 2.823 + 8120.500 24.122 2.816 + 8121.000 23.065 2.802 + 8121.500 20.509 2.789 + 8122.000 19.251 2.790 + 8122.500 18.611 2.795 + 8123.000 20.138 2.795 + 8123.500 21.154 2.794 + 8124.000 25.259 2.794 + 8124.500 30.443 2.788 + 8125.000 32.462 2.779 + 8125.500 33.968 2.776 + 8126.000 32.705 2.781 + 8126.500 29.512 2.791 + 8127.000 26.859 2.813 + 8127.500 26.770 2.820 + 8128.000 29.519 2.818 + 8128.500 33.222 2.815 + 8129.000 35.088 2.806 + 8129.500 34.529 2.809 + 8130.000 33.927 2.810 + 8130.500 33.325 2.814 + 8131.000 33.250 2.816 + 8131.500 32.954 2.814 + 8132.000 31.258 2.805 + 8132.500 30.509 2.798 + 8133.000 30.529 2.794 + 8133.500 31.300 2.799 + 8134.000 32.751 2.801 + 8134.500 33.691 2.805 + 8135.000 32.980 2.791 + 8135.500 31.175 2.777 + 8136.000 29.066 2.764 + 8136.500 25.866 2.767 + 8137.000 23.977 2.781 + 8137.500 23.272 2.790 + 8138.000 23.776 2.802 + 8138.500 24.646 2.815 + 8139.000 25.025 2.821 + 8139.500 26.604 2.806 + 8140.000 26.768 2.794 + 8140.500 28.367 2.800 + 8141.000 28.448 2.812 + 8141.500 30.126 2.819 + 8142.000 32.312 2.813 + 8142.500 32.460 2.808 + 8143.000 30.820 2.766 + 8143.500 28.695 2.745 + 8144.000 26.061 2.739 + 8144.500 23.116 2.752 + 8145.000 21.818 2.791 + 8145.500 22.749 2.789 + 8146.000 22.867 2.791 + 8146.500 26.774 2.804 + 8147.000 29.234 2.820 + 8147.500 32.107 2.833 + 8148.000 33.180 2.831 + 8148.500 33.832 2.817 + 8149.000 33.510 2.803 + 8149.500 32.937 2.795 + 8150.000 29.915 2.792 + 8150.500 25.800 2.793 + 8151.000 22.841 2.802 + 8151.500 21.940 2.810 + 8152.000 22.774 2.826 + 8152.500 26.233 2.854 + 8153.000 27.481 2.881 + 8153.500 29.454 2.854 + 8154.000 29.712 2.798 + 8154.500 27.495 2.791 + 8155.000 23.749 2.787 + 8155.500 20.970 2.822 + 8156.000 20.559 2.852 + 8156.500 22.308 2.856 + 8157.000 26.429 2.860 + 8157.500 33.125 2.838 + 8158.000 37.447 2.817 + 8158.500 41.039 2.788 + 8159.000 39.697 2.781 + 8159.500 41.397 2.774 + 8160.000 42.293 2.779 + 8160.500 42.561 2.795 + 8161.000 39.302 2.809 + 8161.500 35.359 2.811 + 8162.000 34.132 2.806 + 8162.500 36.075 2.796 + 8163.000 38.869 2.797 + 8163.500 41.064 2.796 + 8164.000 41.163 2.797 + 8164.500 39.947 2.801 + 8165.000 36.268 2.817 + 8165.500 32.308 2.827 + 8166.000 31.099 2.828 + 8166.500 28.902 2.797 + 8167.000 29.038 2.787 + 8167.500 29.069 2.785 + 8168.000 29.986 2.801 + 8168.500 30.582 2.823 + 8169.000 30.564 2.827 + 8169.500 30.021 2.825 + 8170.000 29.089 2.822 + 8170.500 29.577 2.813 + 8171.000 32.097 2.805 + 8171.500 32.989 2.792 + 8172.000 32.885 2.786 + 8172.500 30.702 2.790 + 8173.000 28.519 2.796 + 8173.500 26.317 2.811 + 8174.000 24.546 2.828 + 8174.500 26.689 2.833 + 8175.000 30.726 2.826 + 8175.500 34.743 2.809 + 8176.000 35.106 2.801 + 8176.500 30.864 2.788 + 8177.000 26.878 2.783 + 8177.500 22.338 2.785 + 8178.000 20.570 2.791 + 8178.500 17.676 2.798 + 8179.000 18.900 2.807 + 8179.500 20.217 2.824 + 8180.000 23.942 2.827 + 8180.500 28.520 2.830 + 8181.000 36.934 2.811 + 8181.500 41.439 2.798 + 8182.000 41.834 2.784 + 8182.500 41.033 2.783 + 8183.000 34.457 2.783 + 8183.500 31.078 2.795 + 8184.000 28.639 2.802 + 8184.500 27.534 2.818 + 8185.000 29.173 2.839 + 8185.500 35.408 2.828 + 8186.000 40.456 2.785 + 8186.500 42.948 2.777 + 8187.000 41.050 2.792 + 8187.500 38.748 2.802 + 8188.000 24.736 2.819 + 8188.500 21.129 2.814 + 8189.000 20.134 2.814 + 8189.500 19.428 2.811 + 8190.000 18.827 2.829 + 8190.500 20.865 2.845 + 8191.000 24.434 2.846 + 8191.500 27.021 2.842 + 8192.000 28.929 2.830 + 8192.500 31.347 2.819 + 8193.000 31.328 2.818 + 8193.500 29.324 2.817 + 8194.000 26.716 2.811 + 8194.500 22.554 2.801 + 8195.000 21.264 2.801 + 8195.500 22.755 2.805 + 8196.000 25.262 2.822 + 8196.500 30.979 2.829 + 8197.000 34.392 2.824 + 8197.500 41.838 2.807 + 8198.000 46.030 2.795 + 8198.500 55.075 2.782 + 8199.000 53.042 2.782 + 8199.500 45.826 2.781 + 8200.000 31.693 2.783 + 8200.500 22.595 2.812 + 8201.000 20.164 2.808 + 8201.500 19.777 2.806 + 8202.000 18.779 2.808 + 8202.500 17.724 2.810 + 8203.000 15.307 2.808 + 8203.500 14.545 2.808 + 8204.000 15.427 2.806 + 8204.500 19.810 2.828 + 8205.000 25.835 2.840 + 8205.500 28.741 2.833 + 8206.000 28.361 2.816 + 8206.500 25.575 2.801 + 8207.000 23.716 2.802 + 8207.500 23.530 2.798 + 8208.000 24.462 2.793 + 8208.500 25.084 2.777 + 8209.000 24.163 2.775 + 8209.500 21.180 2.782 + 8210.000 20.309 2.792 + 8210.500 16.562 2.800 + 8211.000 14.325 2.802 + 8211.500 16.133 2.802 + 8212.000 17.838 2.806 + 8212.500 22.297 2.829 + 8213.000 23.905 2.836 + 8213.500 24.817 2.829 + 8214.000 26.275 2.820 + 8214.500 36.013 2.802 + 8215.000 40.961 2.791 + 8215.500 43.850 2.756 + 8216.000 40.912 2.754 + 8216.500 32.768 2.765 + 8217.000 26.337 2.792 + 8217.500 25.319 2.815 + 8218.000 23.151 2.827 + 8218.500 24.495 2.828 + 8219.000 26.660 2.827 + 8219.500 28.168 2.833 + 8220.000 29.818 2.834 + 8220.500 28.541 2.825 + 8221.000 25.620 2.811 + 8221.500 22.088 2.806 + 8222.000 21.261 2.814 + 8222.500 20.938 2.827 + 8223.000 20.922 2.826 + 8223.500 20.092 2.821 + 8224.000 20.769 2.816 + 8224.500 24.998 2.810 + 8225.000 29.638 2.808 + 8225.500 32.561 2.812 + 8226.000 32.904 2.818 + 8226.500 32.868 2.836 + 8227.000 32.018 2.839 + 8227.500 32.364 2.834 + 8228.000 33.193 2.823 + 8228.500 35.616 2.807 + 8229.000 34.873 2.796 + 8229.500 33.894 2.791 + 8230.000 32.080 2.792 + 8230.500 31.381 2.797 + 8231.000 29.701 2.808 + 8231.500 31.939 2.810 + 8232.000 29.433 2.812 + 8232.500 27.458 2.814 + 8233.000 27.114 2.819 + 8233.500 26.117 2.827 + 8234.000 25.636 2.826 + 8234.500 24.811 2.820 + 8235.000 23.194 2.818 + 8235.500 21.736 2.818 + 8236.000 21.218 2.818 + 8236.500 20.932 2.817 + 8237.000 21.595 2.823 + 8237.500 21.980 2.828 + 8238.000 22.974 2.832 + 8238.500 27.002 2.837 + 8239.000 32.321 2.844 + 8239.500 40.729 2.844 + 8240.000 43.940 2.846 + 8240.500 47.735 2.801 + 8241.000 46.771 2.794 + 8241.500 43.666 2.795 + 8242.000 41.726 2.808 + 8242.500 35.142 2.826 + 8243.000 30.437 2.826 + 8243.500 28.194 2.820 + 8244.000 30.221 2.812 + 8244.500 34.253 2.802 + 8245.000 37.120 2.796 + 8245.500 41.148 2.794 + 8246.000 42.518 2.792 + 8246.500 44.475 2.797 + 8247.000 44.008 2.800 + 8247.500 43.437 2.795 + 8248.000 43.874 2.791 + 8248.500 45.049 2.800 + 8249.000 45.739 2.800 + 8249.500 45.700 2.798 + 8250.000 44.282 2.803 + 8250.500 42.124 2.804 + 8251.000 37.610 2.813 + 8251.500 39.228 2.816 + 8252.000 40.259 2.818 + 8252.500 41.946 2.816 + 8253.000 39.922 2.816 + 8253.500 38.479 2.815 + 8254.000 32.116 2.810 + 8254.500 31.726 2.801 + 8255.000 38.373 2.788 + 8255.500 43.227 2.788 + 8256.000 43.932 2.790 + 8256.500 39.058 2.800 + 8257.000 35.241 2.800 + 8257.500 35.335 2.798 + 8258.000 39.429 2.796 + 8258.500 40.890 2.796 + 8259.000 40.604 2.797 + 8259.500 38.283 2.800 + 8260.000 34.223 2.811 + 8260.500 32.089 2.820 + 8261.000 35.648 2.815 + 8261.500 39.796 2.810 + 8262.000 43.205 2.803 + 8262.500 44.159 2.801 + 8263.000 41.684 2.800 + 8263.500 37.391 2.804 + 8264.000 31.263 2.810 + 8264.500 28.807 2.809 + 8265.000 29.213 2.811 + 8265.500 37.725 2.810 + 8266.000 40.806 2.807 + 8266.500 41.172 2.800 + 8267.000 40.413 2.793 + 8267.500 32.852 2.792 + 8268.000 29.117 2.798 + 8268.500 25.186 2.804 + 8269.000 26.050 2.806 + 8269.500 25.923 2.805 + 8270.000 34.192 2.802 + 8270.500 47.043 2.799 + 8271.000 55.177 2.797 + 8271.500 53.568 2.797 + 8272.000 47.316 2.796 + 8272.500 43.406 2.794 + 8273.000 39.154 2.792 + 8273.500 35.715 2.794 + 8274.000 24.338 2.798 + 8274.500 21.165 2.808 + 8275.000 18.353 2.811 + 8275.500 19.097 2.810 + 8276.000 21.261 2.809 + 8276.500 27.791 2.808 + 8277.000 33.849 2.808 + 8277.500 36.548 2.797 + 8278.000 42.840 2.781 + 8278.500 44.922 2.778 + 8279.000 44.116 2.784 + 8279.500 41.478 2.803 + 8280.000 40.070 2.813 + 8280.500 36.044 2.820 + 8281.000 33.241 2.826 + 8281.500 31.377 2.826 + 8282.000 29.082 2.833 + 8282.500 28.191 2.846 + 8283.000 29.580 2.847 + 8283.500 30.413 2.834 + 8284.000 30.445 2.821 + 8284.500 31.201 2.814 + 8285.000 31.384 2.812 + 8285.500 30.591 2.809 + 8286.000 29.733 2.804 + 8286.500 32.303 2.795 + 8287.000 36.184 2.792 + 8287.500 42.758 2.790 + 8288.000 47.121 2.791 + 8288.500 44.403 2.792 + 8289.000 38.124 2.794 + 8289.500 32.460 2.794 + 8290.000 27.956 2.796 + 8290.500 31.708 2.796 + 8291.000 31.070 2.794 + 8291.500 31.521 2.789 + 8292.000 27.616 2.792 + 8292.500 24.916 2.798 + 8293.000 24.288 2.804 + 8293.500 29.104 2.804 + 8294.000 34.556 2.804 + 8294.500 39.641 2.794 + 8295.000 41.079 2.783 + 8295.500 41.611 2.774 + 8296.000 40.267 2.796 + 8296.500 33.683 2.805 + 8297.000 27.883 2.811 + 8297.500 28.186 2.813 + 8298.000 28.156 2.816 + 8298.500 28.128 2.812 + 8299.000 28.275 2.803 + 8299.500 30.940 2.796 + 8300.000 35.732 2.795 + 8300.500 53.764 2.792 + 8301.000 64.613 2.792 + 8301.500 71.060 2.797 + 8302.000 68.992 2.817 + 8302.500 54.427 2.824 + 8303.000 44.395 2.822 + 8303.500 37.188 2.816 + 8304.000 32.851 2.811 + 8304.500 30.878 2.812 + 8305.000 30.265 2.817 + 8305.500 32.616 2.818 + 8306.000 34.664 2.817 + 8306.500 39.837 2.810 + 8307.000 39.999 2.811 + 8307.500 37.529 2.812 + 8308.000 33.902 2.810 + 8308.500 30.885 2.801 + 8309.000 30.666 2.799 + 8309.500 29.974 2.799 + 8310.000 29.014 2.806 + 8310.500 24.438 2.810 + 8311.000 21.511 2.813 + 8311.500 20.379 2.821 + 8312.000 20.236 2.822 + 8312.500 20.380 2.815 + 8313.000 20.699 2.807 + 8313.500 20.400 2.806 + 8314.000 19.727 2.812 + 8314.500 15.991 2.828 + 8315.000 14.952 2.835 + 8315.500 13.893 2.842 + 8316.000 14.683 2.843 + 8316.500 17.919 2.835 + 8317.000 20.312 2.825 + 8317.500 21.570 2.816 + 8318.000 25.355 2.810 + 8318.500 29.631 2.813 + 8319.000 32.118 2.816 + 8319.500 34.671 2.813 + 8320.000 34.934 2.812 + 8320.500 32.748 2.800 + 8321.000 30.153 2.809 + 8321.500 27.652 2.827 + 8322.000 26.765 2.837 + 8322.500 24.683 2.832 + 8323.000 23.159 2.821 + 8323.500 22.503 2.812 + 8324.000 23.245 2.801 + 8324.500 24.026 2.792 + 8325.000 26.179 2.775 + 8325.500 26.704 2.768 + 8326.000 28.265 2.774 + 8326.500 27.535 2.813 + 8327.000 26.773 2.830 + 8327.500 26.649 2.828 + 8328.000 27.253 2.818 + 8328.500 28.017 2.784 + 8329.000 28.306 2.778 + 8329.500 29.170 2.776 + 8330.000 28.658 2.796 + 8330.500 30.886 2.800 + 8331.000 31.448 2.793 + 8331.500 30.627 2.778 + 8332.000 28.811 2.777 + 8332.500 26.909 2.787 + 8333.000 31.094 2.790 + 8333.500 37.187 2.794 + 8334.000 40.525 2.793 + 8334.500 40.298 2.799 + 8335.000 30.596 2.810 + 8335.500 26.573 2.836 + 8336.000 24.703 2.845 + 8336.500 24.170 2.841 + 8337.000 25.611 2.819 + 8337.500 31.579 2.807 + 8338.000 37.869 2.807 + 8338.500 44.471 2.804 + 8339.000 42.419 2.804 + 8339.500 38.277 2.804 + 8340.000 33.540 2.806 + 8340.500 32.300 2.802 + 8341.000 34.429 2.802 + 8341.500 37.939 2.805 + 8342.000 39.344 2.809 + 8342.500 38.611 2.816 + 8343.000 34.559 2.814 + 8343.500 30.691 2.813 + 8344.000 26.716 2.807 + 8344.500 25.011 2.806 + 8345.000 26.003 2.806 + 8345.500 27.329 2.806 + 8346.000 28.319 2.806 + 8346.500 24.751 2.802 + 8347.000 21.912 2.797 + 8347.500 20.142 2.798 + 8348.000 19.847 2.802 + 8348.500 21.939 2.811 + 8349.000 23.188 2.809 + 8349.500 24.195 2.809 + 8350.000 25.114 2.790 + 8350.500 26.730 2.785 + 8351.000 27.469 2.781 + 8351.500 25.795 2.782 + 8352.000 25.711 2.787 + 8352.500 22.715 2.802 + 8353.000 22.577 2.821 + 8353.500 22.348 2.825 + 8354.000 22.261 2.828 + 8354.500 22.174 2.824 + 8355.000 22.055 2.818 + 8355.500 21.775 2.808 + 8356.000 21.985 2.808 + 8356.500 18.274 2.824 + 8357.000 16.038 2.831 + 8357.500 14.404 2.831 + 8358.000 15.317 2.833 + 8358.500 21.898 2.812 + 8359.000 32.210 2.789 + 8359.500 45.961 2.768 + 8360.000 51.573 2.731 + 8360.500 49.983 2.727 + 8361.000 42.772 2.746 + 8361.500 39.935 2.791 + 8362.000 35.939 2.811 + 8362.500 34.156 2.818 + 8363.000 32.210 2.818 + 8363.500 29.726 2.822 + 8364.000 27.280 2.827 + 8364.500 26.398 2.834 + 8365.000 27.240 2.832 + 8365.500 27.511 2.827 + 8366.000 28.282 2.823 + 8366.500 28.041 2.819 + 8367.000 28.986 2.815 + 8367.500 29.966 2.810 + 8368.000 31.982 2.808 + 8368.500 32.960 2.817 + 8369.000 32.126 2.829 + 8369.500 30.282 2.824 + 8370.000 29.632 2.818 + 8370.500 26.805 2.796 + 8371.000 25.774 2.788 + 8371.500 24.833 2.788 + 8372.000 24.063 2.790 + 8372.500 20.203 2.807 + 8373.000 18.412 2.812 + 8373.500 15.189 2.818 + 8374.000 14.684 2.813 + 8374.500 15.169 2.805 + 8375.000 18.920 2.813 + 8375.500 21.776 2.822 + 8376.000 25.396 2.821 + 8376.500 28.493 2.804 + 8377.000 31.280 2.804 + 8377.500 32.402 2.806 + 8378.000 33.038 2.807 + 8378.500 32.663 2.806 + 8379.000 30.338 2.797 + 8379.500 28.250 2.804 + 8380.000 28.301 2.811 + 8380.500 29.813 2.817 + 8381.000 30.643 2.815 + 8381.500 30.561 2.814 + 8382.000 30.286 2.816 + 8382.500 28.609 2.832 + 8383.000 27.436 2.833 + 8383.500 25.394 2.835 + 8384.000 23.176 2.841 + 8384.500 20.592 2.844 + 8385.000 20.266 2.845 + 8385.500 20.193 2.837 + 8386.000 20.734 2.825 + 8386.500 24.914 2.805 + 8387.000 30.550 2.801 + 8387.500 33.798 2.800 + 8388.000 35.782 2.799 + 8388.500 29.909 2.810 + 8389.000 24.701 2.812 + 8389.500 21.593 2.812 + 8390.000 22.273 2.815 + 8390.500 25.203 2.830 + 8391.000 26.636 2.833 + 8391.500 29.740 2.830 + 8392.000 31.980 2.824 + 8392.500 31.712 2.822 + 8393.000 30.738 2.823 + 8393.500 29.677 2.827 + 8394.000 28.657 2.832 + 8394.500 27.670 2.828 + 8395.000 26.652 2.819 + 8395.500 25.492 2.820 + 8396.000 23.802 2.830 + 8396.500 21.818 2.839 + 8397.000 20.276 2.841 + 8397.500 20.320 2.845 + 8398.000 19.875 2.847 + 8398.500 21.168 2.844 + 8399.000 21.509 2.839 + 8399.500 22.455 2.835 + 8400.000 22.738 2.835 + 8400.500 23.090 2.840 + 8401.000 23.095 2.844 + 8401.500 21.731 2.840 + 8402.000 21.117 2.839 + 8402.500 20.111 2.846 + 8403.000 20.271 2.849 + 8403.500 20.505 2.855 + 8404.000 22.716 2.861 + 8404.500 26.129 2.848 + 8405.000 27.847 2.843 + 8405.500 23.852 2.830 + 8406.000 20.688 2.827 + 8406.500 17.255 2.819 + 8407.000 16.115 2.814 + 8407.500 14.747 2.817 + 8408.000 14.432 2.833 + 8408.500 15.490 2.852 + 8409.000 18.846 2.848 + 8409.500 23.266 2.830 + 8410.000 27.969 2.820 + 8410.500 31.353 2.803 + 8411.000 34.602 2.801 + 8411.500 33.887 2.800 + 8412.000 31.292 2.800 + 8412.500 27.657 2.805 + 8413.000 20.556 2.816 + 8413.500 19.324 2.832 + 8414.000 13.555 2.842 + 8414.500 13.580 2.834 + 8415.000 16.029 2.817 + 8415.500 19.077 2.819 + 8416.000 20.850 2.825 + 8416.500 24.626 2.842 + 8417.000 28.773 2.836 + 8417.500 32.081 2.816 + 8418.000 32.337 2.801 + 8418.500 32.382 2.796 + 8419.000 32.555 2.797 + 8419.500 33.354 2.798 + 8420.000 34.164 2.804 + 8420.500 33.196 2.814 + 8421.000 31.353 2.821 + 8421.500 29.745 2.823 + 8422.000 28.392 2.826 + 8422.500 27.113 2.823 + 8423.000 25.532 2.819 + 8423.500 26.950 2.820 + 8424.000 29.448 2.826 + 8424.500 32.029 2.833 + 8425.000 31.152 2.836 + 8425.500 26.492 2.826 + 8426.000 21.862 2.818 + 8426.500 21.122 2.817 + 8427.000 21.337 2.816 + 8427.500 28.159 2.812 + 8428.000 30.152 2.810 + 8428.500 37.208 2.814 + 8429.000 39.824 2.820 + 8429.500 41.819 2.822 + 8430.000 42.016 2.823 + 8430.500 35.543 2.834 + 8431.000 29.008 2.844 + 8431.500 27.151 2.848 + 8432.000 28.683 2.841 + 8432.500 30.809 2.828 + 8433.000 30.735 2.832 + 8433.500 29.118 2.841 + 8434.000 26.319 2.844 + 8434.500 23.838 2.833 + 8435.000 21.784 2.826 + 8435.500 18.227 2.826 + 8436.000 15.593 2.826 + 8436.500 12.082 2.824 + 8437.000 10.838 2.826 + 8437.500 10.761 2.824 + 8438.000 10.345 2.821 + 8438.500 13.269 2.792 + 8439.000 16.774 2.783 + 8439.500 20.833 2.778 + 8440.000 23.205 2.781 + 8440.500 26.125 2.801 + 8441.000 29.591 2.808 + 8441.500 30.325 2.810 + 8442.000 32.986 2.810 + 8442.500 34.852 2.810 + 8443.000 39.837 2.808 + 8443.500 41.067 2.803 + 8444.000 53.374 2.798 + 8444.500 63.623 2.801 + 8445.000 59.606 2.812 + 8445.500 47.721 2.828 + 8446.000 39.319 2.836 + 8446.500 27.511 2.842 + 8447.000 24.411 2.827 + 8447.500 24.800 2.816 + 8448.000 25.645 2.810 + 8448.500 28.098 2.812 + 8449.000 30.197 2.821 + 8449.500 34.565 2.831 + 8450.000 39.983 2.845 + 8450.500 49.315 2.840 + 8451.000 51.691 2.826 + 8451.500 53.034 2.810 + 8452.000 53.337 2.802 + 8452.500 48.355 2.799 + 8453.000 43.915 2.805 + 8453.500 43.230 2.812 + 8454.000 46.567 2.816 + 8454.500 53.527 2.816 + 8455.000 50.851 2.810 + 8455.500 43.780 2.807 + 8456.000 32.778 2.809 + 8456.500 28.545 2.822 + 8457.000 27.994 2.836 + 8457.500 28.416 2.845 + 8458.000 29.008 2.844 + 8458.500 28.849 2.834 + 8459.000 28.970 2.821 + 8459.500 29.916 2.807 + 8460.000 34.797 2.801 + 8460.500 42.631 2.801 + 8461.000 44.090 2.807 + 8461.500 43.961 2.816 + 8462.000 41.498 2.817 + 8462.500 30.011 2.828 + 8463.000 24.760 2.832 + 8463.500 22.214 2.834 + 8464.000 22.792 2.831 + 8464.500 22.571 2.819 + 8465.000 22.387 2.808 + 8465.500 21.804 2.803 + 8466.000 21.810 2.804 + 8466.500 23.956 2.824 + 8467.000 24.730 2.844 + 8467.500 25.552 2.855 + 8468.000 27.335 2.860 + 8468.500 29.835 2.846 + 8469.000 31.304 2.816 + 8469.500 31.339 2.803 + 8470.000 32.139 2.787 + 8470.500 31.227 2.794 + 8471.000 30.464 2.811 + 8471.500 28.853 2.831 + 8472.000 26.552 2.833 + 8472.500 24.637 2.821 + 8473.000 21.867 2.816 + 8473.500 20.671 2.818 + 8474.000 20.133 2.838 + 8474.500 23.087 2.850 + 8475.000 28.632 2.842 + 8475.500 37.585 2.823 + 8476.000 42.034 2.812 + 8476.500 39.772 2.818 + 8477.000 35.107 2.827 + 8477.500 29.238 2.838 + 8478.000 26.906 2.833 + 8478.500 24.613 2.811 + 8479.000 23.575 2.802 + 8479.500 22.282 2.801 + 8480.000 22.224 2.800 + 8480.500 23.375 2.827 + 8481.000 24.156 2.839 + 8481.500 24.160 2.849 + 8482.000 24.444 2.825 + 8482.500 24.431 2.793 + 8483.000 24.185 2.795 + 8483.500 24.191 2.811 + 8484.000 24.237 2.824 + 8484.500 24.185 2.840 + 8485.000 24.235 2.837 + 8485.500 24.224 2.834 + 8486.000 24.108 2.834 + 8486.500 24.479 2.852 + 8487.000 22.270 2.852 + 8487.500 21.676 2.842 + 8488.000 20.804 2.825 + 8488.500 19.483 2.820 + 8489.000 17.876 2.823 + 8489.500 16.859 2.826 + 8490.000 15.999 2.841 + 8490.500 18.288 2.855 + 8491.000 20.076 2.856 + 8491.500 22.862 2.846 + 8492.000 24.452 2.853 + 8492.500 24.843 2.904 + 8493.000 23.580 2.956 + 8493.500 22.310 2.997 + 8494.000 20.962 2.898 + 8494.500 20.147 2.705 + 8495.000 20.779 2.636 + 8495.500 21.611 2.580 + 8496.000 22.909 2.647 + 8496.500 25.255 2.740 + 8497.000 24.938 2.805 + 8497.500 24.984 2.806 + 8498.000 24.493 2.807 + 8498.500 25.284 2.817 + 8499.000 28.252 2.822 + 8499.500 28.261 2.829 + 8500.000 25.529 2.833 + 8500.500 18.932 2.838 + 8501.000 16.057 2.856 + 8501.500 13.909 2.867 + 8502.000 12.275 2.881 + 8502.500 12.203 2.768 + 8503.000 11.421 2.777 + 8503.500 11.594 2.780 + 8504.000 15.461 2.797 + 8504.500 17.066 2.790 + 8505.000 15.519 2.791 + 8505.500 15.570 2.798 + 8506.000 15.436 2.828 + 8506.500 17.620 2.850 + 8507.000 18.563 2.858 + 8507.500 20.100 2.859 + 8508.000 20.904 2.858 + 8508.500 21.013 2.845 + 8509.000 20.630 2.834 + 8509.500 17.641 2.822 + 8510.000 17.231 2.816 + 8510.500 18.253 2.815 + 8511.000 20.906 2.815 + 8511.500 24.528 2.818 + 8512.000 33.903 2.818 + 8512.500 38.202 2.818 + 8513.000 32.699 2.824 + 8513.500 27.261 2.832 + 8514.000 22.354 2.837 + 8514.500 19.472 2.838 + 8515.000 17.042 2.831 + 8515.500 17.157 2.836 + 8516.000 16.880 2.844 + 8516.500 18.946 2.859 + 8517.000 20.422 2.864 + 8517.500 29.360 2.852 + 8518.000 31.918 2.842 + 8518.500 39.360 2.837 + 8519.000 37.455 2.844 + 8519.500 32.456 2.848 + 8520.000 28.361 2.844 + 8520.500 24.263 2.832 + 8521.000 17.648 2.821 + 8521.500 15.550 2.822 + 8522.000 15.546 2.821 + 8522.500 15.657 2.822 + 8523.000 22.222 2.822 + 8523.500 28.215 2.823 + 8524.000 37.443 2.828 + 8524.500 37.451 2.831 + 8525.000 33.215 2.838 + 8525.500 25.821 2.837 + 8526.000 18.719 2.838 + 8526.500 17.555 2.832 + 8527.000 24.684 2.830 + 8527.500 27.266 2.823 + 8528.000 27.469 2.815 + 8528.500 25.834 2.801 + 8529.000 21.572 2.797 + 8529.500 19.579 2.795 + 8530.000 19.118 2.804 + 8530.500 20.395 2.817 + 8531.000 20.165 2.813 + 8531.500 20.180 2.801 + 8532.000 20.441 2.795 + 8532.500 21.450 2.799 + 8533.000 24.275 2.821 + 8533.500 24.182 2.837 + 8534.000 23.611 2.843 + 8534.500 23.457 2.839 + 8535.000 23.781 2.828 + 8535.500 26.116 2.816 + 8536.000 26.090 2.811 + 8536.500 20.543 2.822 + 8537.000 18.358 2.832 + 8537.500 17.931 2.834 + 8538.000 18.945 2.832 + 8538.500 21.802 2.834 + 8539.000 22.603 2.833 + 8539.500 22.638 2.830 + 8540.000 20.220 2.825 + 8540.500 17.244 2.820 + 8541.000 14.967 2.816 + 8541.500 14.540 2.813 + 8542.000 15.840 2.817 + 8542.500 16.924 2.823 + 8543.000 16.963 2.832 + 8543.500 15.966 2.841 + 8544.000 18.004 2.848 + 8544.500 21.519 2.847 + 8545.000 27.185 2.847 + 8545.500 32.526 2.832 + 8546.000 34.138 2.820 + 8546.500 31.005 2.809 + 8547.000 29.695 2.809 + 8547.500 29.721 2.813 + 8548.000 29.738 2.811 + 8548.500 30.010 2.826 + 8549.000 30.792 2.831 + 8549.500 33.990 2.838 + 8550.000 41.589 2.844 + 8550.500 47.050 2.836 + 8551.000 42.638 2.830 + 8551.500 39.893 2.830 + 8552.000 35.961 2.826 + 8552.500 30.768 2.828 + 8553.000 23.802 2.831 + 8553.500 22.748 2.841 + 8554.000 20.728 2.846 + 8554.500 20.220 2.828 + 8555.000 20.093 2.821 + 8555.500 20.713 2.823 + 8556.000 23.047 2.844 + 8556.500 28.941 2.828 + 8557.000 39.908 2.778 + 8557.500 43.066 2.668 + 8558.000 43.926 2.641 + 8558.500 40.763 2.717 + 8559.000 35.416 2.752 + 8559.500 32.412 2.798 + 8560.000 28.218 2.790 + 8560.500 27.357 2.787 + 8561.000 17.098 2.797 + 8561.500 16.102 2.808 + 8562.000 14.792 2.811 + 8562.500 14.682 2.815 + 8563.000 15.596 2.816 + 8563.500 15.437 2.824 + 8564.000 15.381 2.830 + 8564.500 16.201 2.830 + 8565.000 17.834 2.828 + 8565.500 18.234 2.825 + 8566.000 22.930 2.819 + 8566.500 24.255 2.811 + 8567.000 24.233 2.811 + 8567.500 22.321 2.816 + 8568.000 20.395 2.826 + 8568.500 19.475 2.831 + 8569.000 18.388 2.831 + 8569.500 16.255 2.841 + 8570.000 16.201 2.841 + 8570.500 17.046 2.842 + 8571.000 19.191 2.844 + 8571.500 21.465 2.857 + 8572.000 23.894 2.872 + 8572.500 25.060 2.872 + 8573.000 24.889 2.853 + 8573.500 22.609 2.838 + 8574.000 20.950 2.817 + 8574.500 18.475 2.817 + 8575.000 18.082 2.814 + 8575.500 19.990 2.818 + 8576.000 20.635 2.823 + 8576.500 23.204 2.825 + 8577.000 27.354 2.826 + 8577.500 29.136 2.830 + 8578.000 30.459 2.838 + 8578.500 25.687 2.849 + 8579.000 21.287 2.849 + 8579.500 19.702 2.846 + 8580.000 21.242 2.834 + 8580.500 28.126 2.824 + 8581.000 33.709 2.813 + 8581.500 34.424 2.815 + 8582.000 32.797 2.822 + 8582.500 25.855 2.842 + 8583.000 21.974 2.858 + 8583.500 17.915 2.845 + 8584.000 17.607 2.837 + 8584.500 19.242 2.810 + 8585.000 19.414 2.816 + 8585.500 21.047 2.822 + 8586.000 22.440 2.823 + 8586.500 25.477 2.828 + 8587.000 32.783 2.829 + 8587.500 43.097 2.824 + 8588.000 54.699 2.819 + 8588.500 60.250 2.819 + 8589.000 70.498 2.818 + 8589.500 49.892 2.812 + 8590.000 41.287 2.805 + 8590.500 33.283 2.801 + 8591.000 31.144 2.805 + 8591.500 30.399 2.816 + 8592.000 30.442 2.829 + 8592.500 27.944 2.846 + 8593.000 25.852 2.851 + 8593.500 23.656 2.856 + 8594.000 21.494 2.853 + 8594.500 19.268 2.854 + 8595.000 18.641 2.853 + 8595.500 18.686 2.843 + 8596.000 20.185 2.813 + 8596.500 20.193 2.797 + 8597.000 20.147 2.799 + 8597.500 20.968 2.813 + 8598.000 20.050 2.831 + 8598.500 19.659 2.842 + 8599.000 20.257 2.845 + 8599.500 21.513 2.859 + 8600.000 26.357 2.868 + 8600.500 33.496 2.862 + 8601.000 38.479 2.817 + 8601.500 40.549 2.804 + 8602.000 37.721 2.769 + 8602.500 32.938 2.782 + 8603.000 24.131 2.794 + 8603.500 22.813 2.808 + 8604.000 21.469 2.817 + 8604.500 24.127 2.818 + 8605.000 27.470 2.817 + 8605.500 27.271 2.810 + 8606.000 25.627 2.806 + 8606.500 24.085 2.801 + 8607.000 23.463 2.796 + 8607.500 24.855 2.796 + 8608.000 25.500 2.786 + 8608.500 24.299 2.791 + 8609.000 21.936 2.801 + 8609.500 20.924 2.810 + 8610.000 21.575 2.825 + 8610.500 23.659 2.832 + 8611.000 25.781 2.834 + 8611.500 26.603 2.833 + 8612.000 26.262 2.834 + 8612.500 23.260 2.819 + 8613.000 21.799 2.808 + 8613.500 20.034 2.814 + 8614.000 19.362 2.818 + 8614.500 20.043 2.813 + 8615.000 20.911 2.804 + 8615.500 23.232 2.798 + 8616.000 27.388 2.788 + 8616.500 30.816 2.779 + 8617.000 28.913 2.777 + 8617.500 26.214 2.775 + 8618.000 21.655 2.775 + 8618.500 21.531 2.773 + 8619.000 23.842 2.769 + 8619.500 28.089 2.764 + 8620.000 32.310 2.759 + 8620.500 31.909 2.768 + 8621.000 27.978 2.795 + 8621.500 21.673 2.817 + 8622.000 18.162 2.827 + 8622.500 13.713 2.830 + 8623.000 12.101 2.829 + 8623.500 11.474 2.827 + 8624.000 13.214 2.827 + 8624.500 16.428 2.831 + 8625.000 19.916 2.828 + 8625.500 21.912 2.820 + 8626.000 22.854 2.818 + 8626.500 23.330 2.815 + 8627.000 22.375 2.816 + 8627.500 21.971 2.825 + 8628.000 22.711 2.837 + 8628.500 22.532 2.841 + 8629.000 21.133 2.834 + 8629.500 20.378 2.818 + 8630.000 17.514 2.808 + 8630.500 13.881 2.798 + 8631.000 12.070 2.799 + 8631.500 10.858 2.811 + 8632.000 10.089 2.813 + 8632.500 9.899 2.812 + 8633.000 9.761 2.803 + 8633.500 10.598 2.802 + 8634.000 10.768 2.798 + 8634.500 12.238 2.799 + 8635.000 14.216 2.807 + 8635.500 18.486 2.801 + 8636.000 27.318 2.788 + 8636.500 32.833 2.779 + 8637.000 35.575 2.762 + 8637.500 33.236 2.770 + 8638.000 28.707 2.780 + 8638.500 20.177 2.806 + 8639.000 17.099 2.829 + 8639.500 14.784 2.836 + 8640.000 15.796 2.837 + 8640.500 18.857 2.839 + 8641.000 24.013 2.837 + 8641.500 28.732 2.838 + 8642.000 31.358 2.839 + 8642.500 29.096 2.843 + 8643.000 27.316 2.839 + 8643.500 26.501 2.836 + 8644.000 24.929 2.834 + 8644.500 26.338 2.832 + 8645.000 26.512 2.827 + 8645.500 27.051 2.835 + 8646.000 27.298 2.843 + 8646.500 28.192 2.836 + 8647.000 29.157 2.828 + 8647.500 30.462 2.809 + 8648.000 30.275 2.807 + 8648.500 28.240 2.810 + 8649.000 26.137 2.819 + 8649.500 24.830 2.830 + 8650.000 23.477 2.847 + 8650.500 23.400 2.853 + 8651.000 24.109 2.846 + 8651.500 25.641 2.840 + 8652.000 26.462 2.834 + 8652.500 29.109 2.825 + 8653.000 32.228 2.815 + 8653.500 32.431 2.802 + 8654.000 33.595 2.794 + 8654.500 33.826 2.784 + 8655.000 32.709 2.782 + 8655.500 30.117 2.782 + 8656.000 27.999 2.787 + 8656.500 25.714 2.799 + 8657.000 24.165 2.803 + 8657.500 23.323 2.815 + 8658.000 23.572 2.821 + 8658.500 24.234 2.834 + 8659.000 24.188 2.841 + 8659.500 24.043 2.842 + 8660.000 21.363 2.838 + 8660.500 24.313 2.826 + 8661.000 29.003 2.814 + 8661.500 33.574 2.802 + 8662.000 33.205 2.791 + 8662.500 32.656 2.787 + 8663.000 30.516 2.785 + 8663.500 27.655 2.797 + 8664.000 25.906 2.811 + 8664.500 21.193 2.837 + 8665.000 20.476 2.834 + 8665.500 20.414 2.832 + 8666.000 21.034 2.829 + 8666.500 21.001 2.823 + 8667.000 21.040 2.825 + 8667.500 21.126 2.828 + 8668.000 21.865 2.824 + 8668.500 20.206 2.817 + 8669.000 20.338 2.814 + 8669.500 20.507 2.815 + 8670.000 24.962 2.818 + 8670.500 27.910 2.819 + 8671.000 28.474 2.813 + 8671.500 30.272 2.806 + 8672.000 26.271 2.823 + 8672.500 20.510 2.837 + 8673.000 18.655 2.853 + 8673.500 16.982 2.852 + 8674.000 14.465 2.851 + 8674.500 13.918 2.841 + 8675.000 16.331 2.840 + 8675.500 20.114 2.842 + 8676.000 20.238 2.839 + 8676.500 19.661 2.831 + 8677.000 19.515 2.828 + 8677.500 21.023 2.828 + 8678.000 22.817 2.825 + 8678.500 23.819 2.818 + 8679.000 20.467 2.807 + 8679.500 18.462 2.801 + 8680.000 16.201 2.802 + 8680.500 15.508 2.806 + 8681.000 18.065 2.802 + 8681.500 20.217 2.800 + 8682.000 26.676 2.805 + 8682.500 28.377 2.820 + 8683.000 30.565 2.824 + 8683.500 30.567 2.816 + 8684.000 27.743 2.806 + 8684.500 22.496 2.802 + 8685.000 20.877 2.817 + 8685.500 19.529 2.831 + 8686.000 20.389 2.833 + 8686.500 24.189 2.835 + 8687.000 28.986 2.841 + 8687.500 32.478 2.842 + 8688.000 32.742 2.840 + 8688.500 28.358 2.834 + 8689.000 23.691 2.832 + 8689.500 21.694 2.836 + 8690.000 21.928 2.840 + 8690.500 25.670 2.849 + 8691.000 26.796 2.852 + 8691.500 27.246 2.843 + 8692.000 26.215 2.829 + 8692.500 24.641 2.815 + 8693.000 24.656 2.807 + 8693.500 24.684 2.808 + 8694.000 26.168 2.807 + 8694.500 27.868 2.800 + 8695.000 28.343 2.791 + 8695.500 29.263 2.796 + 8696.000 29.751 2.806 + 8696.500 29.735 2.841 + 8697.000 28.306 2.850 + 8697.500 25.621 2.850 + 8698.000 22.445 2.839 + 8698.500 20.382 2.819 + 8699.000 20.179 2.810 + 8699.500 19.254 2.805 + 8700.000 18.782 2.810 + 8700.500 20.254 2.822 + 8701.000 21.914 2.841 + 8701.500 22.112 2.853 + 8702.000 23.197 2.864 + 8702.500 25.870 2.834 + 8703.000 26.612 2.814 + 8703.500 27.196 2.807 + 8704.000 26.775 2.811 + 8704.500 22.068 2.816 + 8705.000 19.282 2.819 + 8705.500 18.625 2.827 + 8706.000 16.846 2.832 + 8706.500 19.550 2.845 + 8707.000 18.438 2.841 + 8707.500 16.401 2.837 + 8708.000 15.400 2.833 + 8708.500 13.062 2.833 + 8709.000 13.049 2.834 + 8709.500 13.842 2.834 + 8710.000 15.491 2.832 + 8710.500 18.961 2.832 + 8711.000 20.973 2.826 + 8711.500 22.797 2.818 + 8712.000 24.875 2.801 + 8712.500 26.174 2.802 + 8713.000 27.500 2.810 + 8713.500 27.974 2.820 + 8714.000 28.696 2.825 + 8714.500 29.261 2.840 + 8715.000 27.642 2.848 + 8715.500 25.012 2.849 + 8716.000 22.081 2.846 + 8716.500 20.402 2.831 + 8717.000 19.437 2.818 + 8717.500 19.471 2.798 + 8718.000 20.378 2.791 + 8718.500 20.381 2.797 + 8719.000 21.360 2.808 + 8719.500 22.907 2.811 + 8720.000 23.836 2.810 + 8720.500 26.239 2.807 + 8721.000 28.359 2.806 + 8721.500 27.890 2.800 + 8722.000 26.173 2.798 + 8722.500 23.523 2.798 + 8723.000 20.242 2.798 + 8723.500 19.358 2.805 + 8724.000 19.747 2.811 + 8724.500 21.990 2.820 + 8725.000 27.611 2.819 + 8725.500 32.225 2.813 + 8726.000 30.040 2.808 + 8726.500 26.773 2.806 + 8727.000 24.110 2.806 + 8727.500 22.409 2.808 + 8728.000 21.097 2.814 + 8728.500 21.860 2.813 + 8729.000 24.799 2.817 + 8729.500 24.894 2.816 + 8730.000 23.352 2.813 + 8730.500 22.536 2.811 + 8731.000 23.349 2.808 + 8731.500 24.883 2.816 + 8732.000 28.350 2.818 + 8732.500 31.697 2.816 + 8733.000 28.272 2.814 + 8733.500 23.418 2.809 + 8734.000 20.590 2.806 + 8734.500 19.689 2.789 + 8735.000 20.165 2.786 + 8735.500 19.657 2.794 + 8736.000 21.200 2.814 + 8736.500 23.426 2.813 + 8737.000 25.285 2.813 + 8737.500 23.377 2.835 + 8738.000 21.048 2.851 + 8738.500 16.708 2.828 + 8739.000 16.440 2.802 + 8739.500 16.447 2.795 + 8740.000 16.784 2.813 + 8740.500 16.924 2.828 + 8741.000 17.094 2.834 + 8741.500 17.321 2.835 + 8742.000 17.456 2.840 + 8742.500 17.702 2.844 + 8743.000 17.941 2.838 + 8743.500 17.647 2.827 + 8744.000 21.464 2.813 + 8744.500 25.170 2.814 + 8745.000 39.830 2.819 + 8745.500 44.314 2.817 + 8746.000 48.145 2.805 + 8746.500 43.396 2.799 + 8747.000 40.291 2.796 + 8747.500 33.339 2.809 + 8748.000 29.503 2.813 + 8748.500 25.941 2.815 + 8749.000 24.995 2.808 + 8749.500 24.582 2.808 + 8750.000 26.558 2.815 + 8750.500 29.207 2.827 + 8751.000 34.681 2.840 + 8751.500 39.568 2.849 + 8752.000 41.419 2.848 + 8752.500 41.210 2.834 + 8753.000 37.772 2.820 + 8753.500 33.101 2.814 + 8754.000 28.415 2.819 + 8754.500 23.486 2.833 + 8755.000 21.192 2.830 + 8755.500 20.101 2.821 + 8756.000 18.844 2.814 + 8756.500 15.888 2.813 + 8757.000 14.814 2.811 + 8757.500 14.942 2.805 + 8758.000 15.667 2.801 + 8758.500 16.306 2.813 + 8759.000 16.739 2.823 + 8759.500 18.128 2.842 + 8760.000 20.011 2.846 + 8760.500 21.127 2.851 + 8761.000 21.236 2.847 + 8761.500 22.324 2.844 + 8762.000 22.971 2.842 + 8762.500 21.752 2.850 + 8763.000 21.124 2.834 + 8763.500 19.992 2.815 + 8764.000 19.379 2.801 + 8764.500 19.504 2.798 + 8765.000 19.268 2.809 + 8765.500 18.496 2.816 + 8766.000 17.116 2.822 + 8766.500 16.044 2.829 + 8767.000 15.407 2.836 + 8767.500 15.507 2.842 + 8768.000 15.210 2.834 + 8768.500 14.740 2.811 + 8769.000 14.521 2.801 + 8769.500 15.939 2.794 + 8770.000 16.620 2.793 + 8770.500 17.516 2.797 + 8771.000 18.360 2.798 + 8771.500 18.859 2.798 + 8772.000 19.418 2.797 + 8772.500 20.110 2.801 + 8773.000 20.322 2.811 + 8773.500 21.688 2.814 + 8774.000 22.790 2.814 + 8774.500 23.347 2.810 + 8775.000 21.327 2.812 + 8775.500 19.716 2.812 + 8776.000 17.970 2.810 + 8776.500 19.276 2.802 + 8777.000 21.216 2.801 + 8777.500 24.880 2.807 + 8778.000 27.242 2.811 + 8778.500 28.053 2.812 + 8779.000 27.217 2.813 + 8779.500 26.536 2.821 + 8780.000 26.370 2.828 + 8780.500 30.058 2.831 + 8781.000 36.507 2.817 + 8781.500 42.353 2.804 + 8782.000 40.017 2.799 + 8782.500 38.858 2.801 + 8783.000 28.554 2.805 + 8783.500 23.507 2.816 + 8784.000 21.461 2.823 + 8784.500 26.840 2.822 + 8785.000 32.826 2.816 + 8785.500 34.965 2.813 + 8786.000 35.177 2.803 + 8786.500 33.132 2.798 + 8787.000 32.822 2.800 + 8787.500 32.694 2.811 + 8788.000 34.766 2.811 + 8788.500 36.564 2.812 + 8789.000 38.369 2.812 + 8789.500 39.969 2.810 + 8790.000 40.746 2.810 + 8790.500 39.488 2.812 + 8791.000 34.626 2.822 + 8791.500 32.619 2.824 + 8792.000 29.991 2.826 + 8792.500 26.892 2.819 + 8793.000 24.101 2.809 + 8793.500 22.575 2.804 + 8794.000 22.547 2.799 + 8794.500 21.494 2.807 + 8795.000 21.655 2.817 + 8795.500 24.216 2.837 + 8796.000 23.933 2.842 + 8796.500 27.882 2.833 + 8797.000 29.107 2.818 + 8797.500 29.801 2.805 + 8798.000 28.821 2.803 + 8798.500 30.458 2.811 + 8799.000 32.623 2.818 + 8799.500 33.889 2.826 + 8800.000 33.221 2.828 + 8800.500 31.340 2.829 + 8801.000 29.382 2.831 + 8801.500 29.116 2.832 + 8802.000 29.695 2.828 + 8802.500 28.811 2.821 + 8803.000 28.810 2.809 + 8803.500 29.237 2.799 + 8804.000 30.690 2.798 + 8804.500 31.213 2.802 + 8805.000 32.954 2.805 + 8805.500 34.432 2.806 + 8806.000 34.411 2.806 + 8806.500 32.956 2.799 + 8807.000 31.272 2.791 + 8807.500 30.498 2.786 + 8808.000 31.323 2.785 + 8808.500 37.434 2.790 + 8809.000 39.867 2.792 + 8809.500 40.616 2.794 + 8810.000 38.484 2.796 + 8810.500 38.649 2.801 + 8811.000 37.716 2.806 + 8811.500 37.095 2.802 + 8812.000 36.153 2.793 + 8812.500 34.551 2.794 + 8813.000 32.876 2.798 + 8813.500 31.809 2.812 + 8814.000 30.232 2.819 + 8814.500 29.705 2.817 + 8815.000 29.962 2.807 + 8815.500 28.239 2.796 + 8816.000 27.344 2.803 + 8816.500 24.528 2.814 + 8817.000 22.830 2.823 + 8817.500 23.996 2.830 + 8818.000 25.025 2.835 + 8818.500 25.336 2.827 + 8819.000 24.297 2.825 + 8819.500 22.602 2.833 + 8820.000 21.663 2.836 + 8820.500 20.593 2.840 + 8821.000 19.318 2.831 + 8821.500 19.678 2.828 + 8822.000 19.450 2.825 + 8822.500 19.533 2.818 + 8823.000 22.050 2.808 + 8823.500 24.244 2.795 + 8824.000 26.552 2.792 + 8824.500 27.663 2.794 + 8825.000 27.732 2.801 + 8825.500 26.610 2.812 + 8826.000 26.700 2.818 + 8826.500 23.782 2.822 + 8827.000 22.819 2.820 + 8827.500 20.343 2.807 + 8828.000 18.593 2.804 + 8828.500 20.086 2.807 + 8829.000 21.034 2.838 + 8829.500 21.053 2.845 + 8830.000 21.097 2.836 + 8830.500 22.612 2.816 + 8831.000 24.744 2.806 + 8831.500 26.807 2.804 + 8832.000 31.538 2.806 + 8832.500 38.440 2.800 + 8833.000 40.799 2.797 + 8833.500 40.972 2.794 + 8834.000 40.370 2.790 + 8834.500 36.541 2.784 + 8835.000 35.161 2.769 + 8835.500 34.154 2.768 + 8836.000 33.916 2.776 + 8836.500 30.102 2.793 + 8837.000 28.323 2.804 + 8837.500 23.614 2.811 + 8838.000 22.631 2.815 + 8838.500 22.498 2.816 + 8839.000 23.240 2.818 + 8839.500 25.073 2.819 + 8840.000 28.616 2.819 + 8840.500 31.419 2.806 + 8841.000 30.482 2.794 + 8841.500 29.032 2.786 + 8842.000 26.431 2.787 + 8842.500 23.281 2.800 + 8843.000 21.961 2.809 + 8843.500 21.283 2.816 + 8844.000 21.117 2.813 + 8844.500 21.468 2.807 + 8845.000 19.106 2.811 + 8845.500 19.286 2.818 + 8846.000 19.039 2.823 + 8846.500 18.843 2.829 + 8847.000 18.718 2.831 + 8847.500 18.529 2.832 + 8848.000 18.364 2.831 + 8848.500 18.192 2.837 + 8849.000 18.033 2.842 + 8849.500 17.874 2.841 + 8850.000 18.057 2.831 + 8850.500 18.255 2.819 + 8851.000 18.458 2.824 + 8851.500 18.638 2.825 + 8852.000 18.649 2.826 + 8852.500 18.637 2.820 + 8853.000 19.101 2.820 + 8853.500 19.682 2.822 + 8854.000 20.269 2.827 + 8854.500 21.227 2.839 + 8855.000 21.810 2.846 + 8855.500 24.571 2.846 + 8856.000 25.644 2.831 + 8856.500 26.600 2.812 + 8857.000 26.517 2.810 + 8857.500 24.990 2.819 + 8858.000 23.848 2.823 + 8858.500 22.390 2.826 + 8859.000 23.634 2.829 + 8859.500 25.057 2.836 + 8860.000 25.560 2.835 + 8860.500 23.273 2.826 + 8861.000 21.923 2.822 + 8861.500 23.139 2.824 + 8862.000 26.298 2.820 + 8862.500 31.844 2.810 + 8863.000 34.030 2.810 + 8863.500 31.787 2.818 + 8864.000 28.195 2.824 + 8864.500 22.062 2.824 + 8865.000 20.566 2.824 + 8865.500 19.215 2.827 + 8866.000 19.374 2.825 + 8866.500 20.861 2.814 + 8867.000 22.354 2.812 + 8867.500 25.654 2.819 + 8868.000 27.353 2.824 + 8868.500 26.535 2.818 + 8869.000 24.522 2.810 + 8869.500 21.949 2.810 + 8870.000 22.634 2.821 + 8870.500 22.978 2.828 + 8871.000 25.175 2.823 + 8871.500 23.986 2.819 + 8872.000 24.163 2.805 + 8872.500 22.730 2.793 + 8873.000 22.600 2.793 + 8873.500 22.497 2.800 + 8874.000 21.738 2.807 + 8874.500 21.658 2.821 + 8875.000 21.712 2.825 + 8875.500 22.693 2.817 + 8876.000 23.408 2.805 + 8876.500 23.924 2.802 + 8877.000 22.391 2.806 + 8877.500 21.838 2.823 + 8878.000 20.882 2.827 + 8878.500 19.910 2.822 + 8879.000 19.046 2.817 + 8879.500 18.419 2.811 + 8880.000 18.157 2.806 + 8880.500 18.119 2.804 + 8881.000 17.990 2.801 + 8881.500 18.449 2.798 + 8882.000 20.484 2.804 + 8882.500 21.925 2.821 + 8883.000 24.937 2.843 + 8883.500 28.654 2.848 + 8884.000 31.262 2.842 + 8884.500 31.743 2.824 + 8885.000 27.897 2.798 + 8885.500 24.732 2.801 + 8886.000 21.345 2.807 + 8886.500 22.485 2.820 + 8887.000 21.799 2.824 + 8887.500 21.186 2.821 + 8888.000 20.251 2.818 + 8888.500 17.410 2.825 + 8889.000 16.968 2.829 + 8889.500 16.131 2.837 + 8890.000 15.861 2.843 + 8890.500 14.712 2.849 + 8891.000 14.828 2.858 + 8891.500 15.648 2.861 + 8892.000 17.041 2.856 + 8892.500 18.544 2.844 + 8893.000 19.262 2.843 + 8893.500 21.078 2.844 + 8894.000 19.741 2.846 + 8894.500 20.087 2.840 + 8895.000 18.267 2.804 + 8895.500 17.735 2.808 + 8896.000 16.935 2.819 + 8896.500 17.726 2.846 + 8897.000 18.086 2.854 + 8897.500 18.411 2.845 + 8898.000 18.646 2.825 + 8898.500 18.495 2.815 + 8899.000 17.621 2.821 + 8899.500 17.027 2.830 + 8900.000 17.074 2.819 + 8900.500 17.005 2.807 + 8901.000 17.679 2.809 + 8901.500 18.710 2.821 + 8902.000 19.185 2.826 + 8902.500 20.074 2.828 + 8903.000 19.987 2.834 + 8903.500 19.554 2.837 + 8904.000 18.658 2.844 + 8904.500 19.485 2.838 + 8905.000 20.151 2.834 + 8905.500 21.750 2.823 + 8906.000 22.487 2.823 + 8906.500 23.499 2.830 + 8907.000 21.682 2.827 + 8907.500 18.858 2.814 + 8908.000 16.705 2.802 + 8908.500 16.212 2.788 + 8909.000 17.460 2.791 + 8909.500 17.202 2.796 + 8910.000 16.968 2.805 + 8910.500 15.844 2.818 + 8911.000 14.831 2.817 + 8911.500 14.736 2.808 + 8912.000 14.422 2.793 + 8912.500 14.292 2.802 + 8913.000 13.914 2.826 + 8913.500 13.259 2.842 + 8914.000 13.089 2.843 + 8914.500 13.190 2.816 + 8915.000 14.008 2.798 + 8915.500 13.850 2.793 + 8916.000 13.769 2.800 + 8916.500 14.791 2.815 + 8917.000 15.477 2.808 + 8917.500 17.616 2.800 + 8918.000 18.835 2.792 + 8918.500 21.370 2.787 + 8919.000 21.116 2.786 + 8919.500 21.661 2.787 + 8920.000 21.615 2.795 + 8920.500 20.712 2.802 + 8921.000 20.259 2.808 + 8921.500 20.371 2.817 + 8922.000 21.119 2.823 + 8922.500 21.682 2.834 + 8923.000 21.181 2.838 + 8923.500 20.625 2.832 + 8924.000 19.447 2.825 + 8924.500 19.147 2.817 + 8925.000 17.713 2.805 + 8925.500 17.876 2.796 + 8926.000 18.820 2.797 + 8926.500 21.918 2.810 + 8927.000 23.468 2.821 + 8927.500 24.290 2.821 + 8928.000 24.688 2.817 + 8928.500 25.722 2.802 + 8929.000 25.763 2.804 + 8929.500 25.659 2.806 + 8930.000 25.918 2.812 + 8930.500 26.177 2.816 + 8931.000 26.969 2.821 + 8931.500 27.981 2.826 + 8932.000 28.160 2.830 + 8932.500 26.435 2.830 + 8933.000 24.137 2.826 + 8933.500 22.441 2.816 + 8934.000 20.883 2.817 + 8934.500 21.051 2.838 + 8935.000 21.030 2.849 + 8935.500 21.077 2.851 + 8936.000 20.248 2.843 + 8936.500 19.434 2.844 + 8937.000 21.138 2.844 + 8937.500 21.810 2.839 + 8938.000 22.475 2.829 + 8938.500 22.456 2.826 + 8939.000 21.627 2.825 + 8939.500 20.958 2.824 + 8940.000 21.045 2.823 + 8940.500 21.049 2.821 + 8941.000 20.981 2.823 + 8941.500 21.555 2.833 + 8942.000 22.517 2.845 + 8942.500 22.806 2.844 + 8943.000 25.174 2.843 + 8943.500 26.139 2.825 + 8944.000 27.609 2.827 + 8944.500 28.869 2.826 + 8945.000 28.335 2.820 + 8945.500 26.491 2.815 + 8946.000 25.132 2.811 + 8946.500 22.515 2.809 + 8947.000 23.243 2.811 + 8947.500 22.747 2.817 + 8948.000 23.895 2.822 + 8948.500 25.443 2.832 + 8949.000 24.497 2.833 + 8949.500 24.535 2.850 + 8950.000 24.995 2.854 + 8950.500 23.676 2.853 + 8951.000 23.877 2.836 + 8951.500 24.074 2.829 + 8952.000 25.360 2.805 + 8952.500 24.869 2.814 + 8953.000 25.080 2.822 + 8953.500 24.160 2.830 + 8954.000 24.930 2.817 + 8954.500 26.657 2.808 + 8955.000 27.583 2.804 + 8955.500 28.405 2.806 + 8956.000 29.087 2.812 + 8956.500 27.928 2.815 + 8957.000 25.918 2.811 + 8957.500 25.156 2.809 + 8958.000 25.519 2.814 + 8958.500 26.587 2.817 + 8959.000 26.647 2.824 + 8959.500 25.946 2.819 + 8960.000 24.883 2.818 + 8960.500 22.228 2.815 + 8961.000 21.232 2.818 + 8961.500 22.592 2.824 + 8962.000 24.065 2.832 + 8962.500 24.815 2.834 + 8963.000 24.948 2.831 + 8963.500 23.371 2.827 + 8964.000 22.376 2.823 + 8964.500 21.661 2.816 + 8965.000 20.424 2.812 + 8965.500 19.593 2.817 + 8966.000 19.622 2.827 + 8966.500 20.198 2.837 + 8967.000 20.604 2.828 + 8967.500 21.651 2.826 + 8968.000 21.899 2.811 + 8968.500 21.171 2.801 + 8969.000 21.105 2.807 + 8969.500 20.372 2.815 + 8970.000 20.233 2.813 + 8970.500 19.719 2.811 + 8971.000 19.599 2.800 + 8971.500 20.232 2.807 + 8972.000 20.874 2.813 + 8972.500 21.920 2.842 + 8973.000 23.052 2.837 + 8973.500 24.206 2.837 + 8974.000 25.254 2.837 + 8974.500 25.814 2.841 + 8975.000 26.318 2.837 + 8975.500 27.234 2.835 + 8976.000 27.391 2.836 + 8976.500 27.397 2.832 + 8977.000 27.330 2.827 + 8977.500 27.385 2.815 + 8978.000 28.219 2.812 + 8978.500 32.714 2.821 + 8979.000 36.737 2.829 + 8979.500 37.856 2.826 + 8980.000 39.424 2.820 + 8980.500 40.043 2.802 + 8981.000 38.305 2.793 + 8981.500 34.226 2.786 + 8982.000 29.228 2.789 + 8982.500 23.648 2.802 + 8983.000 20.009 2.813 + 8983.500 20.132 2.826 + 8984.000 21.790 2.830 + 8984.500 21.834 2.833 + 8985.000 25.458 2.831 + 8985.500 24.767 2.830 + 8986.000 24.124 2.825 + 8986.500 22.036 2.813 + 8987.000 20.922 2.811 + 8987.500 23.054 2.815 + 8988.000 22.231 2.816 + 8988.500 18.894 2.812 + 8989.000 17.121 2.807 + 8989.500 14.836 2.808 + 8990.000 12.967 2.822 + 8990.500 12.847 2.825 + 8991.000 13.874 2.830 + 8991.500 18.500 2.834 + 8992.000 20.071 2.840 + 8992.500 20.360 2.846 + 8993.000 18.821 2.844 + 8993.500 15.152 2.844 + 8994.000 13.046 2.843 + 8994.500 12.232 2.844 + 8995.000 11.700 2.840 + 8995.500 11.529 2.837 + 8996.000 11.409 2.841 + 8996.500 11.541 2.852 + 8997.000 11.767 2.848 + 8997.500 13.242 2.845 + 8998.000 13.155 2.823 + 8998.500 14.131 2.830 + 8999.000 14.823 2.841 + 8999.500 16.203 2.842 + 9000.000 18.227 2.839 + 9000.500 20.224 2.827 + 9001.000 22.398 2.826 + 9001.500 25.380 2.822 + 9002.000 28.169 2.822 + 9002.500 31.124 2.826 + 9003.000 32.486 2.814 + 9003.500 31.471 2.793 + 9004.000 28.337 2.778 + 9004.500 23.745 2.779 + 9005.000 22.659 2.786 + 9005.500 24.234 2.792 + 9006.000 25.255 2.812 + 9006.500 25.812 2.833 + 9007.000 26.196 2.837 + 9007.500 25.701 2.836 + 9008.000 23.583 2.831 + 9008.500 21.623 2.827 + 9009.000 19.924 2.819 + 9009.500 19.224 2.818 + 9010.000 18.968 2.816 + 9010.500 20.081 2.822 + 9011.000 19.124 2.831 + 9011.500 20.619 2.834 + 9012.000 22.576 2.832 + 9012.500 27.529 2.815 + 9013.000 31.558 2.806 + 9013.500 36.288 2.799 + 9014.000 36.067 2.801 + 9014.500 33.098 2.801 + 9015.000 28.081 2.796 + 9015.500 26.779 2.799 + 9016.000 26.502 2.802 + 9016.500 24.936 2.804 + 9017.000 23.300 2.806 + 9017.500 20.960 2.808 + 9018.000 20.075 2.814 + 9018.500 21.075 2.812 + 9019.000 21.992 2.806 + 9019.500 25.079 2.806 + 9020.000 29.329 2.810 + 9020.500 33.389 2.815 + 9021.000 34.332 2.815 + 9021.500 30.215 2.810 + 9022.000 24.866 2.801 + 9022.500 19.520 2.800 + 9023.000 17.917 2.795 + 9023.500 16.367 2.788 + 9024.000 15.360 2.782 + 9024.500 13.620 2.783 + 9025.000 16.489 2.798 + 9025.500 17.516 2.808 + 9026.000 23.058 2.806 + 9026.500 27.791 2.804 + 9027.000 31.428 2.807 + 9027.500 34.744 2.811 + 9028.000 35.671 2.812 + 9028.500 35.676 2.812 + 9029.000 36.168 2.808 + 9029.500 36.139 2.803 + 9030.000 35.541 2.793 + 9030.500 32.532 2.799 + 9031.000 31.408 2.817 + 9031.500 30.540 2.812 + 9032.000 29.793 2.807 + 9032.500 28.428 2.801 + 9033.000 26.297 2.808 + 9033.500 22.509 2.819 + 9034.000 21.760 2.825 + 9034.500 21.090 2.826 + 9035.000 21.034 2.822 + 9035.500 21.012 2.810 + 9036.000 21.004 2.805 + 9036.500 20.392 2.800 + 9037.000 20.634 2.803 + 9037.500 21.068 2.800 + 9038.000 21.801 2.803 + 9038.500 21.828 2.805 + 9039.000 21.002 2.803 + 9039.500 18.667 2.810 + 9040.000 17.937 2.815 + 9040.500 17.162 2.826 + 9041.000 19.627 2.829 + 9041.500 20.343 2.819 + 9042.000 19.279 2.815 + 9042.500 17.697 2.812 + 9043.000 17.946 2.815 + 9043.500 18.184 2.815 + 9044.000 18.441 2.817 + 9044.500 19.002 2.818 + 9045.000 18.144 2.822 + 9045.500 17.108 2.816 + 9046.000 16.528 2.816 + 9046.500 16.465 2.816 + 9047.000 14.654 2.819 + 9047.500 13.104 2.820 + 9048.000 13.177 2.827 + 9048.500 10.865 2.834 + 9049.000 10.646 2.830 + 9049.500 9.772 2.826 + 9050.000 9.852 2.813 + 9050.500 8.727 2.817 + 9051.000 7.669 2.823 + 9051.500 7.529 2.825 + 9052.000 7.509 2.828 + 9052.500 7.679 2.827 + 9053.000 8.439 2.831 + 9053.500 8.198 2.831 + 9054.000 8.953 2.825 + 9054.500 9.175 2.815 + 9055.000 9.111 2.818 + 9055.500 10.719 2.819 + 9056.000 12.919 2.813 + 9056.500 18.924 2.798 + 9057.000 20.504 2.792 + 9057.500 24.801 2.803 + 9058.000 25.784 2.821 + 9058.500 25.517 2.824 + 9059.000 20.469 2.817 + 9059.500 18.748 2.807 + 9060.000 16.741 2.806 + 9060.500 13.665 2.808 + 9061.000 12.948 2.810 + 9061.500 12.201 2.820 + 9062.000 12.326 2.827 + 9062.500 12.279 2.846 + 9063.000 12.284 2.841 + 9063.500 12.462 2.825 + 9064.000 13.283 2.816 + 9064.500 14.032 2.802 + 9065.000 13.224 2.795 + 9065.500 12.970 2.787 + 9066.000 11.370 2.791 + 9066.500 9.151 2.804 + 9067.000 8.906 2.830 + 9067.500 9.057 2.850 + 9068.000 10.807 2.856 + 9068.500 16.064 2.851 + 9069.000 19.506 2.846 + 9069.500 22.489 2.791 + 9070.000 21.834 2.778 + 9070.500 16.465 2.761 + 9071.000 14.458 2.775 + 9071.500 12.122 2.794 + 9072.000 11.716 2.816 + 9072.500 11.076 2.838 + 9073.000 9.208 2.839 + 9073.500 8.083 2.829 + 9074.000 7.584 2.813 + 9074.500 8.732 2.803 + 9075.000 10.184 2.801 + 9075.500 10.865 2.809 + 9076.000 11.584 2.816 + 9076.500 11.445 2.819 + 9077.000 12.091 2.823 + 9077.500 12.277 2.822 + 9078.000 12.855 2.820 + 9078.500 14.976 2.821 + 9079.000 18.374 2.827 + 9079.500 20.351 2.823 + 9080.000 20.914 2.802 + 9080.500 20.254 2.796 + 9081.000 17.987 2.818 + 9081.500 16.040 2.824 + 9082.000 14.458 2.824 + 9082.500 13.174 2.818 + 9083.000 13.621 2.814 + 9083.500 14.851 2.816 + 9084.000 16.140 2.822 + 9084.500 16.546 2.823 + 9085.000 15.184 2.817 + 9085.500 12.434 2.815 + 9086.000 10.690 2.825 + 9086.500 9.808 2.835 + 9087.000 9.966 2.862 + 9087.500 9.873 2.851 + 9088.000 10.407 2.823 + 9088.500 9.469 2.807 + 9089.000 8.279 2.812 + 9089.500 7.823 2.822 + 9090.000 7.207 2.822 + 9090.500 9.518 2.820 + 9091.000 10.749 2.804 + 9091.500 15.254 2.811 + 9092.000 18.908 2.820 + 9092.500 23.345 2.818 + 9093.000 24.372 2.816 + 9093.500 23.314 2.817 + 9094.000 20.613 2.817 + 9094.500 18.011 2.822 + 9095.000 16.138 2.826 + 9095.500 16.287 2.825 + 9096.000 16.143 2.824 + 9096.500 13.050 2.818 + 9097.000 12.128 2.820 + 9097.500 11.428 2.837 + 9098.000 11.602 2.850 + 9098.500 13.022 2.847 + 9099.000 13.054 2.842 + 9099.500 13.116 2.835 + 9100.000 13.062 2.836 + 9100.500 13.181 2.833 + 9101.000 12.392 2.832 + 9101.500 12.779 2.837 + 9102.000 13.043 2.846 + 9102.500 13.657 2.855 + 9103.000 14.534 2.853 + 9103.500 14.646 2.847 + 9104.000 14.639 2.840 + 9104.500 14.898 2.830 + 9105.000 15.401 2.816 + 9105.500 18.230 2.813 + 9106.000 20.074 2.815 + 9106.500 26.972 2.792 + 9107.000 34.079 2.770 + 9107.500 41.149 2.730 + 9108.000 50.571 2.731 + 9108.500 54.588 2.751 + 9109.000 46.310 2.771 + 9109.500 38.547 2.792 + 9110.000 32.772 2.801 + 9110.500 26.770 2.813 + 9111.000 23.000 2.821 + 9111.500 20.768 2.820 + 9112.000 19.607 2.819 + 9112.500 19.430 2.827 + 9113.000 20.801 2.830 + 9113.500 21.596 2.842 + 9114.000 21.865 2.844 + 9114.500 21.242 2.844 + 9115.000 20.965 2.841 + 9115.500 22.168 2.834 + 9116.000 25.415 2.829 + 9116.500 31.463 2.820 + 9117.000 36.850 2.809 + 9117.500 42.385 2.796 + 9118.000 49.913 2.785 + 9118.500 55.617 2.767 + 9119.000 52.277 2.747 + 9119.500 47.729 2.744 + 9120.000 37.473 2.744 + 9120.500 23.837 2.777 + 9121.000 19.293 2.787 + 9121.500 15.762 2.816 + 9122.000 14.140 2.834 + 9122.500 15.599 2.840 + 9123.000 17.235 2.845 + 9123.500 19.774 2.848 + 9124.000 19.379 2.848 + 9124.500 21.942 2.839 + 9125.000 23.508 2.827 + 9125.500 31.355 2.810 + 9126.000 41.515 2.793 + 9126.500 59.569 2.780 + 9127.000 63.645 2.764 + 9127.500 65.966 2.752 + 9128.000 57.660 2.748 + 9128.500 46.292 2.745 + 9129.000 36.900 2.766 + 9129.500 32.530 2.795 + 9130.000 29.863 2.849 + 9130.500 25.173 2.846 + 9131.000 24.241 2.843 + 9131.500 23.866 2.826 + 9132.000 23.201 2.818 + 9132.500 21.642 2.797 + 9133.000 22.059 2.794 + 9133.500 23.326 2.791 + 9134.000 23.951 2.812 + 9134.500 24.360 2.831 + 9135.000 22.928 2.823 + 9135.500 21.589 2.816 + 9136.000 20.847 2.815 + 9136.500 22.565 2.797 + 9137.000 28.239 2.771 + 9137.500 33.836 2.764 + 9138.000 38.446 2.770 + 9138.500 32.956 2.811 + 9139.000 26.528 2.832 + 9139.500 20.253 2.836 + 9140.000 18.433 2.826 + 9140.500 17.683 2.810 + 9141.000 13.163 2.806 + 9141.500 13.265 2.812 + 9142.000 14.080 2.819 + 9142.500 14.429 2.821 + 9143.000 15.331 2.823 + 9143.500 15.491 2.821 + 9144.000 15.475 2.815 + 9144.500 15.473 2.803 + 9145.000 15.480 2.799 + 9145.500 15.448 2.797 + 9146.000 15.545 2.803 + 9146.500 14.813 2.818 + 9147.000 14.717 2.827 + 9147.500 14.567 2.826 + 9148.000 14.733 2.817 + 9148.500 15.111 2.800 + 9149.000 19.684 2.796 + 9149.500 21.809 2.794 + 9150.000 23.536 2.797 + 9150.500 26.314 2.802 + 9151.000 28.541 2.811 + 9151.500 30.873 2.820 + 9152.000 33.452 2.823 + 9152.500 34.550 2.821 + 9153.000 31.840 2.819 + 9153.500 28.983 2.816 + 9154.000 22.653 2.813 + 9154.500 20.015 2.801 + 9155.000 20.768 2.788 + 9155.500 22.852 2.777 + 9156.000 39.784 2.775 + 9156.500 44.027 2.777 + 9157.000 42.621 2.790 + 9157.500 38.577 2.798 + 9158.000 32.283 2.803 + 9158.500 29.229 2.793 + 9159.000 29.648 2.787 + 9159.500 31.382 2.785 + 9160.000 32.794 2.788 + 9160.500 35.867 2.795 + 9161.000 38.538 2.791 + 9161.500 37.167 2.775 + 9162.000 35.390 2.768 + 9162.500 35.101 2.772 + 9163.000 37.282 2.775 + 9163.500 42.508 2.771 + 9164.000 62.071 2.763 + 9164.500 70.887 2.756 + 9165.000 66.637 2.762 + 9165.500 48.807 2.778 + 9166.000 38.040 2.798 + 9166.500 28.413 2.808 + 9167.000 21.771 2.801 + 9167.500 22.277 2.794 + 9168.000 26.024 2.789 + 9168.500 26.380 2.797 + 9169.000 24.968 2.800 + 9169.500 23.419 2.801 + 9170.000 21.579 2.801 + 9170.500 20.118 2.807 + 9171.000 19.625 2.809 + 9171.500 20.243 2.812 + 9172.000 21.288 2.808 + 9172.500 25.957 2.783 + 9173.000 30.954 2.780 + 9173.500 31.149 2.791 + 9174.000 30.426 2.792 + 9174.500 26.762 2.792 + 9175.000 23.621 2.787 + 9175.500 19.280 2.799 + 9176.000 18.723 2.829 + 9176.500 20.264 2.843 + 9177.000 20.156 2.840 + 9177.500 21.902 2.832 + 9178.000 21.301 2.835 + 9178.500 21.843 2.844 + 9179.000 21.847 2.841 + 9179.500 20.121 2.834 + 9180.000 18.541 2.829 + 9180.500 14.161 2.815 + 9181.000 14.584 2.810 + 9181.500 14.098 2.806 + 9182.000 13.854 2.802 + 9182.500 13.305 2.809 + 9183.000 13.338 2.807 + 9183.500 14.819 2.798 + 9184.000 17.418 2.794 + 9184.500 20.546 2.795 + 9185.000 22.564 2.799 + 9185.500 25.517 2.805 + 9186.000 27.402 2.807 + 9186.500 26.747 2.795 + 9187.000 24.050 2.796 + 9187.500 20.989 2.793 + 9188.000 18.576 2.780 + 9188.500 16.976 2.761 + 9189.000 14.373 2.760 + 9189.500 12.810 2.770 + 9190.000 12.373 2.811 + 9190.500 12.565 2.823 + 9191.000 12.704 2.840 + 9191.500 12.948 2.843 + 9192.000 12.826 2.840 + 9192.500 15.076 2.824 + 9193.000 17.064 2.813 + 9193.500 16.995 2.807 + 9194.000 16.766 2.804 + 9194.500 13.231 2.818 + 9195.000 12.289 2.825 + 9195.500 10.853 2.830 + 9196.000 11.115 2.827 + 9196.500 15.002 2.817 + 9197.000 16.993 2.811 + 9197.500 22.123 2.798 + 9198.000 21.830 2.790 + 9198.500 19.629 2.787 + 9199.000 17.770 2.795 + 9199.500 18.616 2.804 + 9200.000 20.141 2.804 + 9200.500 22.940 2.797 + 9201.000 24.912 2.795 + 9201.500 25.979 2.795 + 9202.000 28.212 2.795 + 9202.500 37.379 2.800 + 9203.000 45.664 2.802 + 9203.500 49.937 2.797 + 9204.000 51.635 2.786 + 9204.500 50.275 2.770 + 9205.000 43.315 2.774 + 9205.500 35.832 2.792 + 9206.000 32.351 2.800 + 9206.500 16.538 2.824 + 9207.000 10.418 2.819 + 9207.500 8.961 2.820 + 9208.000 9.192 2.822 + 9208.500 8.984 2.822 + 9209.000 9.936 2.818 + 9209.500 12.356 2.816 + 9210.000 13.809 2.816 + 9210.500 16.205 2.816 + 9211.000 20.783 2.818 + 9211.500 24.252 2.816 + 9212.000 29.126 2.813 + 9212.500 37.005 2.803 + 9213.000 43.464 2.798 + 9213.500 42.384 2.796 + 9214.000 37.561 2.796 + 9214.500 31.359 2.812 + 9215.000 28.313 2.815 + 9215.500 26.763 2.812 + 9216.000 26.733 2.807 + 9216.500 22.792 2.800 + 9217.000 21.934 2.809 + 9217.500 20.333 2.816 + 9218.000 19.345 2.814 + 9218.500 29.161 2.780 + 9219.000 51.851 2.759 + 9219.500 73.805 2.747 + 9220.000 91.204 2.752 + 9220.500 79.064 2.767 + 9221.000 63.777 2.784 + 9221.500 49.034 2.797 + 9222.000 44.156 2.795 + 9222.500 41.200 2.796 + 9223.000 36.926 2.800 + 9223.500 27.251 2.809 + 9224.000 18.636 2.811 + 9224.500 16.123 2.818 + 9225.000 12.850 2.820 + 9225.500 15.538 2.818 + 9226.000 21.548 2.809 + 9226.500 31.924 2.789 + 9227.000 36.129 2.778 + 9227.500 39.474 2.776 + 9228.000 50.693 2.772 + 9228.500 60.927 2.777 + 9229.000 61.420 2.776 + 9229.500 65.885 2.768 + 9230.000 70.445 2.757 + 9230.500 79.169 2.735 + 9231.000 82.171 2.719 + 9231.500 80.068 2.721 + 9232.000 67.203 2.739 + 9232.500 54.389 2.784 + 9233.000 36.564 2.798 + 9233.500 32.172 2.816 + 9234.000 26.669 2.818 + 9234.500 20.605 2.816 + 9235.000 16.969 2.816 + 9235.500 15.494 2.818 + 9236.000 15.565 2.821 + 9236.500 19.212 2.824 + 9237.000 20.981 2.820 + 9237.500 22.527 2.818 + 9238.000 22.556 2.812 + 9238.500 21.147 2.806 + 9239.000 20.083 2.810 + 9239.500 16.922 2.819 + 9240.000 17.155 2.822 + 9240.500 15.930 2.821 + 9241.000 15.283 2.811 + 9241.500 14.736 2.818 + 9242.000 14.437 2.828 + 9242.500 14.433 2.837 + 9243.000 14.837 2.838 + 9243.500 15.600 2.833 + 9244.000 15.344 2.829 + 9244.500 16.199 2.824 + 9245.000 18.053 2.820 + 9245.500 20.123 2.814 + 9246.000 21.735 2.809 + 9246.500 23.907 2.786 + 9247.000 24.426 2.784 + 9247.500 22.265 2.787 + 9248.000 20.231 2.794 + 9248.500 16.437 2.811 + 9249.000 16.685 2.815 + 9249.500 18.122 2.826 + 9250.000 19.961 2.829 + 9250.500 28.892 2.817 + 9251.000 33.368 2.792 + 9251.500 35.293 2.780 + 9252.000 35.901 2.793 + 9252.500 39.857 2.809 + 9253.000 43.290 2.812 + 9253.500 42.956 2.798 + 9254.000 40.484 2.793 + 9254.500 36.262 2.793 + 9255.000 37.997 2.797 + 9255.500 42.101 2.795 + 9256.000 43.499 2.792 + 9256.500 45.212 2.786 + 9257.000 46.171 2.780 + 9257.500 49.944 2.771 + 9258.000 54.406 2.754 + 9258.500 71.849 2.741 + 9259.000 76.134 2.732 + 9259.500 83.204 2.737 + 9260.000 85.388 2.753 + 9260.500 56.026 2.771 + 9261.000 37.666 2.783 + 9261.500 24.232 2.794 + 9262.000 20.963 2.812 + 9262.500 22.978 2.821 + 9263.000 28.431 2.815 + 9263.500 30.513 2.798 + 9264.000 30.797 2.779 + 9264.500 24.929 2.751 + 9265.000 22.316 2.749 + 9265.500 23.017 2.752 + 9266.000 26.040 2.768 + 9266.500 34.517 2.776 + 9267.000 40.849 2.782 + 9267.500 48.608 2.739 + 9268.000 56.071 2.721 + 9268.500 61.683 2.660 + 9269.000 51.861 2.665 + 9269.500 45.346 2.662 + 9270.000 35.689 2.666 + 9270.500 30.277 2.679 + 9271.000 27.370 2.685 + 9271.500 25.714 2.693 + 9272.000 24.966 2.703 + 9272.500 31.763 2.710 + 9273.000 40.614 2.707 + 9273.500 50.793 2.696 + 9274.000 58.751 2.688 + 9274.500 61.113 2.691 + 9275.000 61.305 2.695 + 9275.500 62.819 2.704 + 9276.000 67.052 2.717 + 9276.500 68.254 2.736 + 9277.000 66.284 2.745 + 9277.500 57.283 2.773 + 9278.000 49.015 2.785 + 9278.500 39.532 2.799 + 9279.000 35.741 2.802 + 9279.500 36.504 2.809 + 9280.000 35.820 2.814 + 9280.500 29.537 2.813 + 9281.000 25.401 2.810 + 9281.500 23.854 2.807 + 9282.000 23.434 2.809 + 9282.500 25.117 2.812 + 9283.000 26.150 2.814 + 9283.500 29.221 2.814 + 9284.000 29.885 2.809 + 9284.500 30.662 2.806 + 9285.000 30.313 2.804 + 9285.500 29.536 2.800 + 9286.000 28.722 2.797 + 9286.500 27.847 2.796 + 9287.000 27.410 2.795 + 9287.500 26.928 2.807 + 9288.000 26.577 2.819 + 9288.500 24.405 2.821 + 9289.000 23.526 2.821 + 9289.500 21.311 2.824 + 9290.000 19.514 2.825 + 9290.500 17.406 2.837 + 9291.000 18.249 2.848 + 9291.500 22.011 2.849 + 9292.000 25.423 2.847 + 9292.500 32.985 2.840 + 9293.000 35.693 2.831 + 9293.500 38.933 2.827 + 9294.000 43.738 2.823 + 9294.500 53.290 2.808 + 9295.000 64.989 2.785 + 9295.500 71.343 2.761 + 9296.000 68.982 2.742 + 9296.500 58.120 2.735 + 9297.000 47.249 2.745 + 9297.500 35.303 2.774 + 9298.000 32.112 2.793 + 9298.500 30.490 2.823 + 9299.000 31.831 2.818 + 9299.500 40.420 2.802 + 9300.000 50.316 2.792 + 9300.500 60.540 2.746 + 9301.000 68.370 2.723 + 9301.500 65.940 2.719 + 9302.000 59.308 2.728 + 9302.500 57.469 2.756 + 9303.000 64.478 2.775 + 9303.500 68.257 2.775 + 9304.000 70.654 2.762 + 9304.500 64.905 2.751 + 9305.000 63.818 2.748 + 9305.500 56.860 2.751 + 9306.000 49.963 2.767 + 9306.500 39.935 2.787 + 9307.000 34.351 2.804 + 9307.500 27.429 2.816 + 9308.000 23.650 2.811 + 9308.500 24.237 2.805 + 9309.000 27.199 2.801 + 9309.500 30.349 2.802 + 9310.000 33.442 2.803 + 9310.500 36.787 2.794 + 9311.000 37.048 2.787 + 9311.500 34.568 2.790 + 9312.000 32.733 2.799 + 9312.500 25.327 2.813 + 9313.000 22.529 2.818 + 9313.500 19.287 2.823 + 9314.000 18.221 2.831 + 9314.500 18.904 2.836 + 9315.000 25.465 2.833 + 9315.500 31.807 2.824 + 9316.000 38.140 2.808 + 9316.500 40.121 2.780 + 9317.000 37.374 2.777 + 9317.500 35.334 2.777 + 9318.000 33.427 2.780 + 9318.500 28.545 2.785 + 9319.000 25.408 2.789 + 9319.500 21.695 2.800 + 9320.000 21.537 2.804 + 9320.500 21.038 2.809 + 9321.000 21.454 2.809 + 9321.500 21.848 2.806 + 9322.000 21.016 2.808 + 9322.500 20.150 2.812 + 9323.000 18.375 2.812 + 9323.500 17.608 2.817 + 9324.000 17.876 2.824 + 9324.500 19.661 2.837 + 9325.000 20.245 2.838 + 9325.500 20.129 2.830 + 9326.000 20.420 2.826 + 9326.500 18.425 2.823 + 9327.000 17.104 2.818 + 9327.500 17.478 2.802 + 9328.000 20.264 2.799 + 9328.500 26.113 2.792 + 9329.000 31.042 2.786 + 9329.500 36.608 2.777 + 9330.000 40.530 2.765 + 9330.500 41.581 2.755 + 9331.000 40.710 2.755 + 9331.500 37.895 2.769 + 9332.000 30.637 2.786 + 9332.500 27.360 2.774 + 9333.000 25.144 2.769 + 9333.500 22.463 2.769 + 9334.000 22.432 2.770 + 9334.500 20.819 2.780 + 9335.000 20.918 2.782 + 9335.500 20.135 2.796 + 9336.000 20.253 2.792 + 9336.500 20.247 2.782 + 9337.000 20.141 2.773 + 9337.500 21.056 2.724 + 9338.000 21.945 2.701 + 9338.500 23.550 2.695 + 9339.000 23.656 2.711 + 9339.500 22.847 2.716 + 9340.000 21.952 2.716 + 9340.500 21.030 2.703 + 9341.000 21.085 2.708 + 9341.500 21.175 2.728 + 9342.000 21.603 2.743 + 9342.500 19.932 2.769 + 9343.000 18.721 2.785 + 9343.500 17.121 2.796 + 9344.000 17.067 2.799 + 9344.500 17.283 2.794 + 9345.000 19.564 2.795 + 9345.500 20.898 2.812 + 9346.000 23.340 2.825 + 9346.500 24.205 2.832 + 9347.000 24.376 2.831 + 9347.500 22.893 2.832 + 9348.000 22.635 2.837 + 9348.500 22.602 2.844 + 9349.000 23.278 2.843 + 9349.500 24.960 2.838 + 9350.000 27.612 2.831 + 9350.500 32.940 2.826 + 9351.000 30.765 2.821 + 9351.500 24.824 2.816 + 9352.000 22.374 2.836 + 9352.500 20.211 2.855 + 9353.000 20.117 2.855 + 9353.500 21.674 2.832 + 9354.000 27.920 2.794 + 9354.500 30.335 2.799 + 9355.000 29.227 2.802 + 9355.500 28.599 2.820 + 9356.000 29.225 2.825 + 9356.500 33.729 2.827 + 9357.000 36.334 2.817 + 9357.500 37.902 2.807 + 9358.000 37.670 2.801 + 9358.500 37.645 2.801 + 9359.000 37.856 2.798 + 9359.500 37.145 2.807 + 9360.000 37.699 2.809 + 9360.500 34.992 2.816 + 9361.000 32.143 2.815 + 9361.500 29.532 2.815 + 9362.000 27.830 2.815 + 9362.500 30.321 2.814 + 9363.000 34.733 2.814 + 9363.500 36.780 2.822 + 9364.000 36.318 2.829 + 9364.500 30.570 2.841 + 9365.000 28.394 2.842 + 9365.500 28.067 2.836 + 9366.000 29.466 2.831 + 9366.500 31.971 2.830 + 9367.000 33.949 2.828 + 9367.500 35.405 2.826 + 9368.000 35.399 2.822 + 9368.500 34.399 2.811 + 9369.000 32.444 2.810 + 9369.500 31.479 2.808 + 9370.000 30.177 2.804 + 9370.500 30.188 2.796 + 9371.000 30.034 2.793 + 9371.500 35.767 2.787 + 9372.000 36.138 2.784 + 9372.500 32.021 2.784 + 9373.000 25.211 2.807 + 9373.500 20.474 2.811 + 9374.000 17.078 2.817 + 9374.500 16.013 2.816 + 9375.000 15.986 2.814 + 9375.500 16.884 2.812 + 9376.000 19.382 2.799 + 9376.500 20.419 2.778 + 9377.000 20.990 2.780 + 9377.500 19.883 2.784 + 9378.000 20.111 2.806 + 9378.500 22.029 2.828 + 9379.000 24.415 2.840 + 9379.500 26.587 2.836 + 9380.000 26.441 2.809 + 9380.500 27.590 2.787 + 9381.000 28.291 2.767 + 9381.500 29.904 2.727 + 9382.000 29.889 2.704 + 9382.500 28.302 2.708 + 9383.000 27.469 2.731 + 9383.500 25.854 2.770 + 9384.000 25.782 2.788 + 9384.500 25.780 2.798 + 9385.000 25.825 2.802 + 9385.500 25.609 2.803 + 9386.000 27.124 2.801 + 9386.500 30.363 2.783 + 9387.000 34.012 2.756 + 9387.500 36.464 2.708 + 9388.000 37.142 2.689 + 9388.500 39.442 2.671 + 9389.000 40.770 2.670 + 9389.500 40.437 2.694 + 9390.000 37.299 2.724 + 9390.500 32.291 2.752 + 9391.000 29.952 2.776 + 9391.500 26.539 2.800 + 9392.000 23.229 2.793 + 9392.500 21.847 2.775 + 9393.000 20.565 2.751 + 9393.500 19.584 2.742 + 9394.000 18.588 2.742 + 9394.500 19.178 2.733 + 9395.000 20.069 2.719 + 9395.500 20.582 2.714 + 9396.000 22.524 2.717 + 9396.500 25.831 2.738 + 9397.000 27.940 2.743 + 9397.500 28.180 2.745 + 9398.000 27.954 2.751 + 9398.500 24.484 2.795 + 9399.000 22.553 2.803 + 9399.500 19.496 2.809 + 9400.000 20.037 2.809 + 9400.500 19.617 2.809 + 9401.000 19.486 2.803 + 9401.500 21.094 2.782 + 9402.000 22.564 2.734 + 9402.500 24.142 2.660 + 9403.000 24.181 2.649 + 9403.500 24.215 2.655 + 9404.000 24.198 2.673 + 9404.500 24.206 2.677 + 9405.000 24.154 2.672 + 9405.500 24.832 2.670 + 9406.000 25.441 2.681 + 9406.500 27.242 2.700 + 9407.000 29.151 2.737 + 9407.500 33.495 2.772 + 9408.000 35.797 2.800 + 9408.500 36.297 2.820 + 9409.000 34.282 2.823 + 9409.500 30.667 2.824 + 9410.000 26.300 2.823 + 9410.500 23.059 2.839 + 9411.000 26.893 2.852 + 9411.500 31.295 2.849 + 9412.000 40.212 2.847 + 9412.500 45.950 2.841 + 9413.000 51.572 2.834 + 9413.500 49.585 2.829 + 9414.000 42.337 2.830 + 9414.500 36.520 2.850 + 9415.000 30.049 2.860 + 9415.500 29.006 2.868 + 9416.000 29.617 2.869 + 9416.500 30.260 2.854 + 9417.000 30.593 2.834 + 9417.500 30.161 2.814 + 9418.000 31.293 2.812 + 9418.500 38.873 2.814 + 9419.000 40.270 2.818 + 9419.500 40.180 2.818 + 9420.000 40.353 2.821 + 9420.500 42.273 2.818 + 9421.000 46.612 2.810 + 9421.500 49.473 2.799 + 9422.000 46.578 2.793 + 9422.500 38.924 2.822 + 9423.000 20.219 2.835 + 9423.500 19.702 2.841 + 9424.000 16.942 2.825 + 9424.500 18.270 2.737 + 9425.000 19.955 2.727 + 9425.500 21.641 2.717 + 9426.000 27.679 2.723 + 9426.500 38.337 2.761 + 9427.000 41.869 2.802 + 9427.500 40.291 2.825 + 9428.000 36.193 2.834 + 9428.500 30.658 2.852 + 9429.000 31.633 2.846 + 9429.500 34.914 2.850 + 9430.000 38.539 2.781 + 9430.500 43.025 2.751 + 9431.000 42.328 2.744 + 9431.500 44.085 2.750 + 9432.000 43.417 2.766 + 9432.500 40.872 2.792 + 9433.000 38.968 2.800 + 9433.500 35.613 2.810 + 9434.000 30.602 2.821 + 9434.500 25.325 2.830 + 9435.000 21.065 2.834 + 9435.500 19.536 2.834 + 9436.000 19.296 2.829 + 9436.500 20.738 2.797 + 9437.000 20.437 2.747 + 9437.500 19.617 2.695 + 9438.000 16.779 2.671 + 9438.500 14.442 2.678 + 9439.000 14.674 2.685 + 9439.500 14.842 2.693 + 9440.000 15.989 2.687 + 9440.500 18.722 2.670 + 9441.000 23.296 2.664 + 9441.500 27.863 2.660 + 9442.000 34.212 2.682 + 9442.500 41.201 2.700 + 9443.000 41.880 2.724 + 9443.500 38.917 2.741 + 9444.000 29.270 2.764 + 9444.500 21.584 2.792 + 9445.000 16.155 2.800 + 9445.500 14.745 2.810 + 9446.000 16.227 2.821 + 9446.500 20.104 2.827 + 9447.000 20.415 2.825 + 9447.500 20.479 2.828 + 9448.000 19.480 2.842 + 9448.500 17.106 2.874 + 9449.000 16.942 2.878 + 9449.500 16.662 2.867 + 9450.000 18.279 2.846 + 9450.500 19.698 2.773 + 9451.000 20.256 2.804 + 9451.500 20.239 2.814 + 9452.000 20.121 2.819 + 9452.500 21.603 2.818 + 9453.000 24.659 2.800 + 9453.500 28.023 2.799 + 9454.000 31.193 2.795 + 9454.500 34.205 2.787 + 9455.000 36.022 2.783 + 9455.500 37.856 2.775 + 9456.000 40.861 2.775 + 9456.500 33.025 2.776 + 9457.000 27.723 2.797 + 9457.500 22.641 2.805 + 9458.000 19.234 2.823 + 9458.500 14.489 2.840 + 9459.000 14.617 2.847 + 9459.500 16.916 2.851 + 9460.000 18.728 2.847 + 9460.500 20.296 2.827 + 9461.000 21.705 2.797 + 9461.500 22.123 2.777 + 9462.000 26.399 2.763 + 9462.500 29.658 2.771 + 9463.000 31.417 2.781 + 9463.500 30.641 2.790 + 9464.000 23.344 2.820 + 9464.500 18.181 2.833 + 9465.000 12.542 2.839 + 9465.500 10.830 2.836 + 9466.000 10.682 2.827 + 9466.500 10.866 2.817 + 9467.000 11.480 2.812 + 9467.500 12.119 2.812 + 9468.000 12.278 2.812 + 9468.500 12.149 2.819 + 9469.000 11.412 2.826 + 9469.500 11.584 2.830 + 9470.000 11.361 2.827 + 9470.500 15.321 2.814 + 9471.000 18.742 2.799 + 9471.500 22.952 2.791 + 9472.000 25.889 2.780 + 9472.500 24.148 2.783 + 9473.000 20.387 2.821 + 9473.500 16.576 2.836 + 9474.000 14.633 2.855 + 9474.500 11.775 2.861 + 9475.000 12.047 2.850 + 9475.500 12.283 2.832 + 9476.000 14.344 2.820 + 9476.500 15.466 2.838 + 9477.000 16.351 2.841 + 9477.500 16.248 2.831 + 9478.000 16.403 2.826 + 9478.500 17.130 2.787 + 9479.000 17.053 2.779 + 9479.500 16.176 2.777 + 9480.000 16.338 2.801 + 9480.500 16.956 2.824 + 9481.000 21.320 2.848 + 9481.500 23.082 2.864 + 9482.000 24.567 2.862 + 9482.500 22.420 2.822 + 9483.000 22.586 2.800 + 9483.500 21.088 2.790 + 9484.000 20.549 2.786 + 9484.500 18.838 2.844 + 9485.000 18.024 2.840 + 9485.500 19.482 2.834 + 9486.000 21.263 2.822 + 9486.500 24.784 2.795 + 9487.000 25.024 2.801 + 9487.500 25.735 2.801 + 9488.000 24.133 2.805 + 9488.500 22.291 2.808 + 9489.000 17.341 2.808 + 9489.500 15.537 2.808 + 9490.000 14.192 2.810 + 9490.500 13.428 2.819 + 9491.000 13.020 2.825 + 9491.500 13.145 2.828 + 9492.000 13.137 2.828 + 9492.500 15.228 2.819 + 9493.000 19.129 2.813 + 9493.500 22.130 2.802 + 9494.000 27.979 2.795 + 9494.500 28.509 2.775 + 9495.000 27.804 2.772 + 9495.500 28.393 2.782 + 9496.000 28.407 2.777 + 9496.500 37.279 2.759 + 9497.000 43.726 2.754 + 9497.500 53.447 2.753 + 9498.000 61.424 2.752 + 9498.500 63.172 2.746 + 9499.000 59.236 2.745 + 9499.500 51.796 2.748 + 9500.000 43.649 2.764 + 9500.500 27.853 2.785 + 9501.000 21.064 2.794 + 9501.500 19.261 2.813 + 9502.000 16.714 2.815 + 9502.500 18.577 2.807 + 9503.000 18.456 2.802 + 9503.500 18.818 2.807 + 9504.000 19.486 2.820 + 9504.500 19.593 2.843 + 9505.000 20.337 2.847 + 9505.500 21.896 2.847 + 9506.000 23.744 2.840 + 9506.500 28.188 2.820 + 9507.000 28.019 2.811 + 9507.500 26.183 2.812 + 9508.000 23.502 2.812 + 9508.500 20.290 2.803 + 9509.000 19.162 2.781 + 9509.500 20.957 2.746 + 9510.000 23.044 2.744 + 9510.500 31.945 2.698 + 9511.000 36.982 2.751 + 9511.500 37.829 2.787 + 9512.000 35.448 2.822 + 9512.500 26.015 2.830 + 9513.000 22.421 2.830 + 9513.500 21.526 2.828 + 9514.000 21.455 2.823 + 9514.500 20.416 2.816 + 9515.000 19.784 2.814 + 9515.500 17.857 2.808 + 9516.000 15.237 2.808 + 9516.500 13.019 2.813 + 9517.000 11.496 2.816 + 9517.500 10.613 2.822 + 9518.000 10.579 2.827 + 9518.500 9.810 2.830 + 9519.000 9.949 2.825 + 9519.500 9.476 2.819 + 9520.000 10.319 2.820 + 9520.500 13.182 2.827 + 9521.000 13.154 2.828 + 9521.500 15.316 2.821 + 9522.000 17.047 2.815 + 9522.500 16.313 2.808 + 9523.000 14.660 2.800 + 9523.500 12.952 2.791 + 9524.000 12.094 2.783 + 9524.500 11.406 2.782 + 9525.000 11.938 2.780 + 9525.500 12.220 2.766 + 9526.000 13.086 2.758 + 9526.500 14.059 2.755 + 9527.000 15.333 2.755 + 9527.500 16.468 2.772 + 9528.000 19.071 2.779 + 9528.500 21.982 2.807 + 9529.000 25.200 2.817 + 9529.500 26.188 2.816 + 9530.000 27.236 2.817 + 9530.500 27.665 2.818 + 9531.000 25.062 2.818 + 9531.500 23.682 2.813 + 9532.000 22.808 2.813 + 9532.500 22.265 2.816 + 9533.000 20.676 2.820 + 9533.500 19.714 2.825 + 9534.000 19.685 2.820 + 9534.500 19.492 2.819 + 9535.000 20.689 2.811 + 9535.500 21.474 2.803 + 9536.000 21.758 2.801 + 9536.500 20.667 2.802 + 9537.000 20.074 2.818 + 9537.500 17.384 2.829 + 9538.000 18.070 2.829 + 9538.500 19.362 2.830 + 9539.000 21.159 2.830 + 9539.500 21.784 2.826 + 9540.000 22.683 2.815 + 9540.500 21.821 2.806 + 9541.000 20.362 2.813 + 9541.500 20.073 2.829 + 9542.000 19.472 2.834 + 9542.500 18.131 2.824 + 9543.000 16.601 2.820 + 9543.500 14.909 2.818 + 9544.000 14.595 2.818 + 9544.500 13.690 2.823 + 9545.000 14.458 2.824 + 9545.500 15.532 2.822 + 9546.000 16.476 2.820 + 9546.500 19.297 2.824 + 9547.000 19.381 2.824 + 9547.500 19.509 2.817 + 9548.000 19.281 2.812 + 9548.500 18.566 2.800 + 9549.000 18.773 2.800 + 9549.500 19.414 2.798 + 9550.000 19.486 2.800 + 9550.500 20.335 2.812 + 9551.000 17.616 2.818 + 9551.500 17.117 2.824 + 9552.000 16.555 2.829 + 9552.500 16.228 2.834 + 9553.000 16.343 2.836 + 9553.500 17.723 2.836 + 9554.000 19.180 2.834 + 9554.500 23.492 2.828 + 9555.000 25.702 2.822 + 9555.500 29.538 2.816 + 9556.000 30.003 2.810 + 9556.500 31.652 2.798 + 9557.000 30.284 2.797 + 9557.500 27.180 2.797 + 9558.000 25.918 2.815 + 9558.500 24.309 2.819 + 9559.000 23.353 2.808 + 9559.500 21.559 2.806 + 9560.000 22.182 2.817 + 9560.500 20.922 2.831 + 9561.000 20.562 2.824 + 9561.500 21.296 2.815 + 9562.000 21.858 2.802 + 9562.500 23.405 2.802 + 9563.000 23.421 2.808 + 9563.500 24.915 2.816 + 9564.000 25.851 2.823 + 9564.500 28.256 2.815 + 9565.000 29.733 2.801 + 9565.500 29.595 2.793 + 9566.000 28.431 2.793 + 9566.500 26.403 2.797 + 9567.000 24.455 2.806 + 9567.500 24.309 2.810 + 9568.000 23.704 2.811 + 9568.500 23.676 2.812 + 9569.000 22.280 2.812 + 9569.500 21.639 2.812 + 9570.000 21.147 2.810 + 9570.500 22.404 2.806 + 9571.000 20.060 2.812 + 9571.500 24.166 2.815 + 9572.000 24.112 2.814 + 9572.500 24.265 2.801 + 9573.000 24.218 2.792 + 9573.500 25.886 2.769 + 9574.000 27.069 2.758 + 9574.500 29.236 2.763 + 9575.000 28.522 2.772 + 9575.500 27.645 2.784 + 9576.000 28.646 2.797 + 9576.500 29.831 2.798 + 9577.000 32.065 2.797 + 9577.500 33.161 2.794 + 9578.000 33.349 2.798 + 9578.500 31.709 2.801 + 9579.000 30.619 2.804 + 9579.500 28.438 2.805 + 9580.000 26.525 2.802 + 9580.500 24.364 2.791 + 9581.000 24.850 2.779 + 9581.500 27.791 2.744 + 9582.000 28.272 2.726 + 9582.500 29.104 2.709 + 9583.000 29.122 2.709 + 9583.500 29.701 2.705 + 9584.000 31.005 2.731 + 9584.500 31.465 2.747 + 9585.000 30.664 2.780 + 9585.500 28.564 2.790 + 9586.000 26.452 2.792 + 9586.500 25.576 2.789 + 9587.000 23.360 2.793 + 9587.500 21.782 2.787 + 9588.000 21.909 2.783 + 9588.500 22.174 2.781 + 9589.000 25.884 2.781 + 9589.500 28.935 2.774 + 9590.000 30.897 2.764 + 9590.500 28.483 2.750 + 9591.000 26.328 2.752 + 9591.500 24.889 2.779 + 9592.000 25.798 2.812 + 9592.500 29.419 2.820 + 9593.000 32.663 2.821 + 9593.500 35.908 2.820 + 9594.000 38.190 2.794 + 9594.500 41.496 2.778 + 9595.000 41.812 2.762 + 9595.500 37.510 2.766 + 9596.000 33.564 2.777 + 9596.500 30.065 2.787 + 9597.000 29.407 2.786 + 9597.500 27.453 2.785 + 9598.000 25.668 2.789 + 9598.500 23.398 2.800 + 9599.000 23.370 2.797 + 9599.500 24.133 2.794 + 9600.000 25.874 2.773 + 9600.500 28.250 2.753 + 9601.000 29.757 2.746 + 9601.500 30.544 2.743 + 9602.000 28.919 2.757 + 9602.500 27.392 2.771 + 9603.000 25.820 2.793 + 9603.500 25.943 2.798 + 9604.000 27.564 2.784 + 9604.500 33.726 2.759 + 9605.000 38.280 2.724 + 9605.500 42.012 2.708 + 9606.000 46.825 2.695 + 9606.500 51.106 2.681 + 9607.000 54.644 2.681 + 9607.500 60.139 2.680 + 9608.000 60.538 2.675 + 9608.500 57.626 2.671 + 9609.000 53.317 2.679 + 9609.500 50.160 2.693 + 9610.000 45.840 2.697 + 9610.500 43.904 2.692 + 9611.000 45.445 2.682 + 9611.500 47.398 2.672 + 9612.000 49.858 2.673 + 9612.500 51.423 2.677 + 9613.000 50.389 2.679 + 9613.500 48.241 2.677 + 9614.000 45.224 2.680 + 9614.500 38.431 2.692 + 9615.000 33.075 2.705 + 9615.500 32.657 2.723 + 9616.000 33.489 2.728 + 9616.500 37.833 2.725 + 9617.000 38.287 2.722 + 9617.500 37.340 2.725 + 9618.000 35.537 2.738 + 9618.500 33.870 2.746 + 9619.000 33.566 2.744 + 9619.500 34.468 2.742 + 9620.000 34.233 2.738 + 9620.500 34.745 2.734 + 9621.000 32.742 2.727 + 9621.500 29.738 2.724 + 9622.000 27.171 2.730 + 9622.500 27.177 2.735 + 9623.000 30.047 2.730 + 9623.500 34.615 2.718 + 9624.000 38.267 2.707 + 9624.500 40.922 2.702 + 9625.000 41.799 2.707 + 9625.500 41.661 2.731 + 9626.000 41.561 2.739 + 9626.500 40.684 2.754 + 9627.000 39.194 2.749 + 9627.500 34.401 2.744 + 9628.000 30.901 2.740 + 9628.500 27.842 2.730 + 9629.000 25.951 2.730 + 9629.500 24.957 2.732 + 9630.000 25.784 2.734 + 9630.500 26.934 2.735 + 9631.000 29.209 2.723 + 9631.500 35.516 2.710 + 9632.000 42.101 2.697 + 9632.500 56.740 2.680 + 9633.000 61.592 2.658 + 9633.500 66.003 2.648 + 9634.000 71.633 2.647 + 9634.500 73.475 2.658 + 9635.000 72.532 2.673 + 9635.500 70.770 2.678 + 9636.000 60.061 2.676 + 9636.500 54.085 2.668 + 9637.000 42.098 2.671 + 9637.500 40.635 2.687 + 9638.000 39.117 2.695 + 9638.500 38.525 2.707 + 9639.000 37.178 2.717 + 9639.500 35.336 2.734 + 9640.000 35.082 2.740 + 9640.500 35.335 2.746 + 9641.000 34.652 2.753 + 9641.500 32.822 2.763 + 9642.000 29.447 2.761 + 9642.500 27.601 2.754 + 9643.000 28.851 2.746 + 9643.500 29.651 2.744 + 9644.000 30.576 2.738 + 9644.500 29.751 2.728 + 9645.000 29.004 2.715 + 9645.500 28.226 2.704 + 9646.000 28.934 2.700 + 9646.500 28.271 2.691 + 9647.000 27.674 2.684 + 9647.500 24.412 2.677 + 9648.000 21.639 2.674 + 9648.500 20.118 2.680 + 9649.000 19.615 2.696 + 9649.500 19.509 2.692 + 9650.000 20.544 2.750 + 9650.500 23.409 2.773 + 9651.000 27.339 2.730 + 9651.500 31.647 2.696 + 9652.000 37.385 2.663 + 9652.500 41.086 2.668 + 9653.000 38.295 2.691 + 9653.500 37.137 2.699 + 9654.000 32.959 2.704 + 9654.500 28.589 2.696 + 9655.000 26.884 2.695 + 9655.500 25.136 2.711 + 9656.000 25.731 2.726 + 9656.500 26.621 2.744 + 9657.000 27.485 2.740 + 9657.500 27.389 2.740 + 9658.000 27.256 2.737 + 9658.500 28.097 2.745 + 9659.000 27.623 2.751 + 9659.500 26.895 2.753 + 9660.000 26.276 2.749 + 9660.500 22.615 2.742 + 9661.000 22.398 2.737 + 9661.500 22.020 2.732 + 9662.000 24.258 2.730 + 9662.500 26.061 2.735 + 9663.000 26.620 2.739 + 9663.500 26.566 2.749 + 9664.000 27.141 2.761 + 9664.500 27.895 2.783 + 9665.000 27.155 2.780 + 9665.500 26.526 2.781 + 9666.000 26.785 2.775 + 9666.500 27.536 2.748 + 9667.000 28.863 2.732 + 9667.500 28.930 2.726 + 9668.000 29.163 2.724 + 9668.500 29.846 2.727 + 9669.000 29.559 2.728 + 9669.500 28.826 2.723 + 9670.000 27.435 2.713 + 9670.500 26.942 2.701 + 9671.000 26.524 2.700 + 9671.500 28.780 2.703 + 9672.000 29.398 2.706 + 9672.500 30.970 2.712 + 9673.000 30.442 2.713 + 9673.500 30.628 2.715 + 9674.000 30.622 2.718 + 9674.500 29.716 2.726 + 9675.000 28.271 2.731 + 9675.500 26.024 2.735 + 9676.000 25.405 2.737 + 9676.500 25.360 2.738 + 9677.000 27.324 2.733 + 9677.500 27.970 2.722 + 9678.000 28.713 2.719 + 9678.500 29.922 2.703 + 9679.000 31.219 2.703 + 9679.500 32.043 2.708 + 9680.000 33.652 2.712 + 9680.500 33.204 2.706 + 9681.000 32.140 2.702 + 9681.500 29.910 2.702 + 9682.000 28.133 2.700 + 9682.500 28.962 2.702 + 9683.000 30.607 2.704 + 9683.500 33.637 2.704 + 9684.000 35.959 2.701 + 9684.500 39.307 2.700 + 9685.000 40.272 2.698 + 9685.500 41.112 2.694 + 9686.000 41.794 2.712 + 9686.500 40.883 2.734 + 9687.000 40.061 2.732 + 9687.500 39.342 2.726 + 9688.000 37.966 2.707 + 9688.500 36.229 2.701 + 9689.000 35.154 2.705 + 9689.500 33.814 2.715 + 9690.000 33.215 2.723 + 9690.500 32.264 2.739 + 9691.000 32.054 2.744 + 9691.500 32.747 2.732 + 9692.000 33.457 2.723 + 9692.500 34.896 2.703 + 9693.000 36.639 2.701 + 9693.500 39.180 2.695 + 9694.000 39.710 2.686 + 9694.500 40.669 2.673 + 9695.000 41.859 2.680 + 9695.500 40.845 2.694 + 9696.000 39.488 2.701 + 9696.500 35.912 2.730 + 9697.000 34.618 2.725 + 9697.500 34.886 2.722 + 9698.000 35.696 2.717 + 9698.500 36.535 2.713 + 9699.000 38.208 2.708 + 9699.500 39.910 2.704 + 9700.000 50.762 2.695 + 9700.500 67.509 2.687 + 9701.000 85.853 2.679 + 9701.500 93.220 2.673 + 9702.000 87.566 2.672 + 9702.500 65.142 2.675 + 9703.000 56.174 2.684 + 9703.500 51.404 2.684 + 9704.000 49.209 2.681 + 9704.500 49.525 2.676 + 9705.000 56.110 2.674 + 9705.500 58.940 2.676 + 9706.000 59.969 2.676 + 9706.500 62.305 2.676 + 9707.000 62.472 2.681 + 9707.500 60.063 2.689 + 9708.000 59.058 2.694 + 9708.500 59.133 2.693 + 9709.000 59.370 2.682 + 9709.500 59.928 2.668 + 9710.000 58.317 2.669 + 9710.500 57.221 2.668 + 9711.000 47.438 2.682 + 9711.500 45.305 2.694 + 9712.000 38.601 2.699 + 9712.500 34.233 2.691 + 9713.000 28.722 2.638 + 9713.500 26.445 2.548 + 9714.000 21.879 2.394 + 9714.500 21.353 2.403 + 9715.000 22.306 2.426 + 9715.500 24.583 2.542 + 9716.000 25.988 2.634 + 9716.500 25.200 2.670 + 9717.000 24.148 2.665 + 9717.500 21.631 2.615 + 9718.000 20.746 2.558 + 9718.500 19.253 2.567 + 9719.000 19.371 2.585 + 9719.500 18.620 2.643 + 9720.000 20.165 2.650 + 9720.500 21.361 2.659 + 9721.000 21.770 2.666 + 9721.500 22.478 2.678 + 9722.000 22.401 2.690 + 9722.500 25.260 2.691 + 9723.000 31.217 2.682 + 9723.500 37.576 2.661 + 9724.000 42.166 2.647 + 9724.500 47.067 2.647 + 9725.000 47.116 2.662 + 9725.500 44.886 2.683 + 9726.000 42.534 2.697 + 9726.500 40.271 2.702 + 9727.000 40.057 2.707 + 9727.500 38.595 2.715 + 9728.000 36.374 2.719 + 9728.500 34.206 2.718 + 9729.000 33.829 2.721 + 9729.500 36.188 2.725 + 9730.000 37.773 2.689 + 9730.500 40.271 2.690 + 9731.000 39.441 2.661 + 9731.500 35.682 2.629 + 9732.000 32.253 2.632 + 9732.500 33.002 2.639 + 9733.000 37.864 2.655 + 9733.500 41.351 2.667 + 9734.000 44.619 2.685 + 9734.500 47.643 2.700 + 9735.000 46.278 2.715 + 9735.500 41.884 2.719 + 9736.000 37.602 2.718 + 9736.500 29.716 2.705 + 9737.000 25.509 2.698 + 9737.500 26.781 2.692 + 9738.000 30.577 2.692 + 9738.500 38.418 2.696 + 9739.000 39.901 2.703 + 9739.500 40.306 2.724 + 9740.000 39.471 2.747 + 9740.500 31.518 2.771 + 9741.000 26.369 2.786 + 9741.500 26.734 2.787 + 9742.000 28.602 2.777 + 9742.500 31.357 2.757 + 9743.000 31.591 2.743 + 9743.500 31.205 2.717 + 9744.000 30.271 2.708 + 9744.500 32.227 2.719 + 9745.000 33.855 2.731 + 9745.500 33.711 2.727 + 9746.000 33.323 2.594 + 9746.500 31.009 2.599 + 9747.000 30.567 2.633 + 9747.500 30.586 2.653 + 9748.000 31.655 2.680 + 9748.500 30.007 2.695 + 9749.000 29.747 2.697 + 9749.500 29.790 2.700 + 9750.000 29.051 2.704 + 9750.500 27.537 2.706 + 9751.000 26.009 2.707 + 9751.500 23.621 2.702 + 9752.000 23.673 2.702 + 9752.500 28.581 2.703 + 9753.000 35.588 2.701 + 9753.500 42.397 2.696 + 9754.000 47.747 2.686 + 9754.500 45.475 2.705 + 9755.000 40.936 2.723 + 9755.500 31.813 2.743 + 9756.000 28.714 2.762 + 9756.500 22.191 2.774 + 9757.000 20.632 2.782 + 9757.500 18.861 2.796 + 9758.000 18.095 2.802 + 9758.500 17.175 2.801 + 9759.000 17.482 2.800 + 9759.500 17.889 2.798 + 9760.000 18.425 2.795 + 9760.500 18.813 2.798 + 9761.000 19.516 2.797 + 9761.500 19.498 2.797 + 9762.000 21.091 2.799 + 9762.500 19.184 2.803 + 9763.000 15.222 2.811 + 9763.500 14.576 2.817 + 9764.000 14.793 2.815 + 9764.500 16.940 2.804 + 9765.000 21.110 2.794 + 9765.500 24.254 2.793 + 9766.000 25.631 2.792 + 9766.500 25.895 2.798 + 9767.000 25.495 2.806 + 9767.500 25.083 2.805 + 9768.000 25.115 2.799 + 9768.500 30.213 2.796 + 9769.000 35.857 2.796 + 9769.500 42.228 2.791 + 9770.000 45.159 2.788 + 9770.500 48.885 2.749 + 9771.000 51.905 2.731 + 9771.500 53.476 2.722 + 9772.000 53.954 2.721 + 9772.500 50.564 2.717 + 9773.000 44.246 2.715 + 9773.500 37.672 2.732 + 9774.000 34.139 2.767 + 9774.500 30.411 2.777 + 9775.000 29.800 2.775 + 9775.500 32.265 2.765 + 9776.000 34.443 2.752 + 9776.500 36.535 2.734 + 9777.000 35.262 2.716 + 9777.500 29.283 2.707 + 9778.000 27.215 2.704 + 9778.500 31.658 2.730 + 9779.000 38.153 2.743 + 9779.500 43.841 2.752 + 9780.000 51.866 2.751 + 9780.500 56.960 2.747 + 9781.000 58.852 2.743 + 9781.500 59.860 2.754 + 9782.000 59.044 2.767 + 9782.500 53.698 2.750 + 9783.000 42.072 2.712 + 9783.500 34.369 2.672 + 9784.000 29.797 2.651 + 9784.500 30.317 2.660 + 9785.000 36.699 2.699 + 9785.500 41.429 2.713 + 9786.000 42.376 2.709 + 9786.500 42.474 2.702 + 9787.000 42.142 2.699 + 9787.500 43.312 2.707 + 9788.000 47.457 2.710 + 9788.500 53.466 2.705 + 9789.000 57.622 2.703 + 9789.500 61.643 2.708 + 9790.000 61.955 2.714 + 9790.500 52.645 2.723 + 9791.000 38.613 2.734 + 9791.500 35.229 2.743 + 9792.000 32.180 2.775 + 9792.500 34.958 2.808 + 9793.000 38.503 2.818 + 9793.500 37.708 2.798 + 9794.000 34.297 2.789 + 9794.500 30.652 2.794 + 9795.000 28.701 2.794 + 9795.500 28.330 2.795 + 9796.000 28.799 2.795 + 9796.500 31.255 2.791 + 9797.000 35.161 2.790 + 9797.500 39.493 2.779 + 9798.000 39.752 2.768 + 9798.500 35.317 2.722 + 9799.000 32.246 2.717 + 9799.500 29.514 2.712 + 9800.000 32.838 2.717 + 9800.500 38.637 2.724 + 9801.000 42.938 2.732 + 9801.500 43.784 2.739 + 9802.000 44.838 2.736 + 9802.500 46.374 2.726 + 9803.000 46.369 2.727 + 9803.500 46.689 2.732 + 9804.000 47.351 2.741 + 9804.500 45.897 2.744 + 9805.000 41.234 2.743 + 9805.500 39.218 2.731 + 9806.000 37.426 2.719 + 9806.500 38.945 2.710 + 9807.000 39.848 2.710 + 9807.500 40.778 2.710 + 9808.000 40.864 2.710 + 9808.500 40.858 2.707 + 9809.000 41.055 2.708 + 9809.500 40.054 2.711 + 9810.000 40.579 2.730 + 9810.500 36.545 2.735 + 9811.000 32.132 2.737 + 9811.500 24.432 2.735 + 9812.000 22.524 2.731 + 9812.500 20.831 2.729 + 9813.000 21.730 2.737 + 9813.500 23.412 2.749 + 9814.000 23.266 2.775 + 9814.500 23.376 2.773 + 9815.000 20.192 2.759 + 9815.500 18.227 2.736 + 9816.000 12.823 2.722 + 9816.500 12.247 2.722 + 9817.000 13.089 2.722 + 9817.500 14.072 2.743 + 9818.000 15.319 2.760 + 9818.500 18.341 2.781 + 9819.000 20.199 2.792 + 9819.500 21.806 2.798 + 9820.000 21.784 2.798 + 9820.500 21.706 2.798 + 9821.000 20.924 2.797 + 9821.500 21.233 2.793 + 9822.000 22.123 2.785 + 9822.500 24.358 2.771 + 9823.000 25.019 2.768 + 9823.500 24.991 2.776 + 9824.000 25.130 2.787 + 9824.500 24.240 2.811 + 9825.000 24.341 2.813 + 9825.500 21.979 2.821 + 9826.000 21.404 2.770 + 9826.500 19.358 2.791 + 9827.000 17.493 2.707 + 9827.500 15.650 2.709 + 9828.000 14.759 2.702 + 9828.500 14.580 2.706 + 9829.000 13.723 2.711 + 9829.500 14.101 2.705 + 9830.000 15.023 2.702 + 9830.500 16.943 2.703 + 9831.000 17.531 2.717 + 9831.500 16.944 2.738 + 9832.000 15.148 2.756 + 9832.500 12.719 2.775 + 9833.000 12.279 2.767 + 9833.500 12.337 2.767 + 9834.000 12.280 2.776 + 9834.500 12.271 2.802 + 9835.000 12.331 2.808 + 9835.500 12.301 2.793 + 9836.000 12.037 2.772 + 9836.500 12.264 2.742 + 9837.000 13.269 2.735 + 9837.500 14.473 2.742 + 9838.000 16.054 2.753 + 9838.500 17.638 2.761 + 9839.000 18.607 2.775 + 9839.500 18.867 2.785 + 9840.000 18.270 2.797 + 9840.500 20.932 2.806 + 9841.000 26.948 2.808 + 9841.500 26.197 2.808 + 9842.000 22.930 2.808 + 9842.500 19.291 2.805 + 9843.000 16.279 2.795 + 9843.500 15.489 2.787 + 9844.000 12.825 2.790 + 9844.500 12.914 2.803 + 9845.000 13.224 2.813 + 9845.500 14.024 2.825 + 9846.000 13.259 2.827 + 9846.500 12.525 2.803 + 9847.000 11.520 2.788 + 9847.500 10.549 2.749 + 9848.000 11.348 2.742 + 9848.500 11.509 2.718 + 9849.000 11.684 2.720 + 9849.500 12.291 2.720 + 9850.000 13.108 2.719 + 9850.500 14.946 2.729 + 9851.000 15.516 2.742 + 9851.500 16.240 2.757 + 9852.000 16.392 2.788 + 9852.500 17.038 2.807 + 9853.000 16.140 2.806 + 9853.500 16.312 2.807 + 9854.000 16.319 2.806 + 9854.500 16.049 2.809 + 9855.000 15.866 2.818 + 9855.500 15.348 2.828 + 9856.000 14.022 2.830 + 9856.500 13.862 2.824 + 9857.000 13.877 2.820 + 9857.500 14.095 2.827 + 9858.000 14.526 2.833 + 9858.500 14.255 2.842 + 9859.000 13.889 2.840 + 9859.500 13.856 2.833 + 9860.000 14.326 2.823 + 9860.500 13.909 2.814 + 9861.000 13.280 2.810 + 9861.500 13.025 2.824 + 9862.000 13.995 2.826 + 9862.500 15.653 2.840 + 9863.000 15.477 2.842 + 9863.500 14.727 2.842 + 9864.000 13.238 2.826 + 9864.500 12.467 2.801 + 9865.000 12.379 2.798 + 9865.500 13.852 2.810 + 9866.000 16.163 2.822 + 9866.500 19.399 2.832 + 9867.000 21.072 2.836 + 9867.500 21.777 2.838 + 9868.000 20.972 2.842 + 9868.500 20.439 2.836 + 9869.000 19.995 2.832 + 9869.500 18.243 2.830 + 9870.000 16.473 2.830 + 9870.500 15.212 2.833 + 9871.000 13.987 2.838 + 9871.500 13.371 2.843 + 9872.000 14.382 2.838 + 9872.500 15.392 2.826 + 9873.000 15.466 2.826 + 9873.500 15.471 2.824 + 9874.000 15.442 2.825 + 9874.500 15.678 2.829 + 9875.000 15.766 2.834 + 9875.500 15.443 2.836 + 9876.000 17.699 2.828 + 9876.500 19.531 2.821 + 9877.000 21.037 2.830 + 9877.500 21.133 2.845 + 9878.000 20.332 2.857 + 9878.500 18.996 2.853 + 9879.000 16.156 2.849 + 9879.500 15.033 2.858 + 9880.000 13.780 2.870 + 9880.500 11.994 2.821 + 9881.000 13.439 2.798 + 9881.500 13.933 2.794 + 9882.000 13.605 2.797 + 9882.500 16.020 2.811 + 9883.000 17.301 2.815 + 9883.500 20.420 2.814 + 9884.000 22.511 2.810 + 9884.500 22.543 2.817 + 9885.000 21.023 2.829 + 9885.500 19.261 2.846 + 9886.000 16.924 2.846 + 9886.500 17.802 2.834 + 9887.000 18.101 2.833 + 9887.500 20.074 2.838 + 9888.000 21.625 2.842 + 9888.500 22.998 2.831 + 9889.000 24.952 2.806 + 9889.500 24.716 2.801 + 9890.000 22.914 2.801 + 9890.500 22.157 2.816 + 9891.000 19.998 2.828 + 9891.500 20.288 2.836 + 9892.000 20.242 2.841 + 9892.500 20.180 2.842 + 9893.000 18.512 2.837 + 9893.500 17.712 2.834 + 9894.000 16.567 2.831 + 9894.500 16.522 2.841 + 9895.000 16.178 2.840 + 9895.500 16.461 2.836 + 9896.000 17.301 2.834 + 9896.500 20.161 2.844 + 9897.000 21.821 2.847 + 9897.500 22.742 2.842 + 9898.000 22.113 2.831 + 9898.500 20.592 2.823 + 9899.000 19.404 2.815 + 9899.500 16.811 2.795 + 9900.000 16.940 2.799 + 9900.500 18.020 2.804 + 9901.000 19.312 2.828 + 9901.500 20.076 2.841 + 9902.000 21.918 2.851 + 9902.500 20.431 2.849 + 9903.000 18.530 2.836 + 9903.500 15.918 2.821 + 9904.000 14.018 2.804 + 9904.500 14.381 2.801 + 9905.000 19.212 2.802 + 9905.500 24.543 2.808 + 9906.000 27.496 2.807 + 9906.500 28.290 2.803 + 9907.000 25.786 2.798 + 9907.500 22.618 2.793 + 9908.000 20.112 2.782 + 9908.500 19.335 2.768 + 9909.000 20.257 2.766 + 9909.500 21.040 2.777 + 9910.000 21.407 2.793 + 9910.500 19.564 2.805 + 9911.000 19.260 2.801 + 9911.500 18.078 2.798 + 9912.000 19.389 2.797 + 9912.500 20.296 2.803 + 9913.000 21.773 2.811 + 9913.500 22.108 2.819 + 9914.000 23.651 2.821 + 9914.500 24.774 2.820 + 9915.000 23.442 2.823 + 9915.500 22.063 2.826 + 9916.000 21.896 2.818 + 9916.500 23.435 2.788 + 9917.000 24.922 2.774 + 9917.500 27.274 2.772 + 9918.000 28.247 2.776 + 9918.500 27.587 2.783 + 9919.000 27.148 2.788 + 9919.500 26.740 2.795 + 9920.000 24.914 2.795 + 9920.500 24.445 2.798 + 9921.000 24.862 2.799 + 9921.500 24.414 2.819 + 9922.000 23.350 2.837 + 9922.500 21.992 2.850 + 9923.000 23.381 2.846 + 9923.500 24.942 2.832 + 9924.000 24.009 2.815 + 9924.500 20.699 2.780 + 9925.000 18.442 2.783 + 9925.500 16.491 2.792 + 9926.000 16.713 2.804 + 9926.500 16.533 2.810 + 9927.000 15.557 2.806 + 9927.500 14.923 2.806 + 9928.000 14.995 2.815 + 9928.500 19.705 2.818 + 9929.000 25.171 2.815 + 9929.500 29.057 2.801 + 9930.000 28.784 2.806 + 9930.500 26.567 2.819 + 9931.000 24.273 2.838 + 9931.500 21.887 2.844 + 9932.000 21.249 2.810 + 9932.500 20.951 2.792 + 9933.000 21.593 2.772 + 9933.500 22.607 2.750 + 9934.000 23.377 2.755 + 9934.500 21.760 2.773 + 9935.000 20.863 2.792 + 9935.500 21.629 2.795 + 9936.000 22.967 2.797 + 9936.500 25.198 2.798 + 9937.000 24.030 2.811 + 9937.500 18.151 2.821 + 9938.000 16.017 2.826 + 9938.500 13.221 2.825 + 9939.000 13.398 2.820 + 9939.500 15.654 2.820 + 9940.000 18.464 2.825 + 9940.500 20.768 2.833 + 9941.000 21.845 2.833 + 9941.500 20.293 2.831 + 9942.000 19.690 2.831 + 9942.500 17.099 2.835 + 9943.000 17.831 2.835 + 9943.500 18.263 2.832 + 9944.000 26.422 2.820 + 9944.500 28.433 2.810 + 9945.000 28.190 2.807 + 9945.500 28.144 2.822 + 9946.000 28.279 2.834 + 9946.500 27.544 2.835 + 9947.000 27.483 2.827 + 9947.500 26.530 2.831 + 9948.000 25.792 2.846 + 9948.500 23.173 2.856 + 9949.000 19.669 2.855 + 9949.500 15.975 2.847 + 9950.000 15.511 2.829 + 9950.500 15.846 2.816 + 9951.000 18.137 2.817 + 9951.500 19.353 2.820 + 9952.000 20.966 2.820 + 9952.500 21.598 2.818 + 9953.000 21.703 2.823 + 9953.500 23.980 2.824 + 9954.000 27.366 2.822 + 9954.500 30.682 2.812 + 9955.000 33.190 2.812 + 9955.500 31.842 2.819 + 9956.000 28.527 2.832 + 9956.500 23.617 2.837 + 9957.000 21.826 2.827 + 9957.500 20.673 2.820 + 9958.000 20.351 2.814 + 9958.500 21.166 2.814 + 9959.000 20.923 2.817 + 9959.500 21.476 2.828 + 9960.000 24.085 2.838 + 9960.500 29.230 2.837 + 9961.000 32.271 2.823 + 9961.500 31.438 2.809 + 9962.000 30.710 2.800 + 9962.500 27.643 2.815 + 9963.000 27.406 2.825 + 9963.500 27.786 2.828 + 9964.000 30.245 2.822 + 9964.500 34.501 2.810 + 9965.000 38.535 2.811 + 9965.500 39.345 2.820 + 9966.000 39.191 2.832 + 9966.500 37.438 2.832 + 9967.000 34.366 2.814 + 9967.500 32.841 2.799 + 9968.000 31.220 2.797 + 9968.500 31.140 2.816 + 9969.000 30.795 2.826 + 9969.500 30.532 2.826 + 9970.000 30.669 2.824 + 9970.500 26.938 2.824 + 9971.000 22.544 2.836 + 9971.500 19.334 2.842 + 9972.000 17.570 2.836 + 9972.500 16.989 2.816 + 9973.000 17.550 2.802 + 9973.500 18.618 2.803 + 9974.000 21.096 2.807 + 9974.500 27.705 2.808 + 9975.000 28.671 2.805 + 9975.500 29.165 2.794 + 9976.000 24.560 2.799 + 9976.500 19.482 2.806 + 9977.000 16.438 2.808 + 9977.500 13.795 2.812 + 9978.000 12.901 2.813 + 9978.500 14.054 2.810 + 9979.000 17.249 2.807 + 9979.500 20.639 2.811 + 9980.000 24.995 2.820 + 9980.500 28.542 2.825 + 9981.000 27.327 2.829 + 9981.500 24.149 2.835 + 9982.000 21.003 2.842 + 9982.500 14.357 2.842 + 9983.000 10.930 2.834 + 9983.500 9.085 2.822 + 9984.000 9.176 2.803 + 9984.500 9.059 2.798 + 9985.000 9.095 2.808 + 9985.500 9.284 2.821 + 9986.000 9.992 2.826 + 9986.500 11.596 2.826 + 9987.000 12.525 2.826 + 9987.500 15.263 2.830 + 9988.000 18.618 2.833 + 9988.500 22.177 2.833 + 9989.000 24.182 2.827 + 9989.500 24.044 2.821 + 9990.000 21.549 2.811 + 9990.500 17.473 2.815 + 9991.000 14.599 2.818 + 9991.500 12.163 2.825 + 9992.000 13.072 2.825 + 9992.500 13.056 2.823 + 9993.000 14.542 2.827 + 9993.500 15.837 2.838 + 9994.000 18.039 2.843 + 9994.500 21.892 2.829 + 9995.000 24.144 2.813 + 9995.500 28.164 2.807 + 9996.000 28.525 2.811 + 9996.500 23.901 2.820 + 9997.000 20.095 2.822 + 9997.500 16.996 2.812 + 9998.000 16.246 2.807 + 9998.500 16.911 2.799 + 9999.000 17.822 2.807 + 9999.500 18.622 2.815 + 10000.000 18.606 2.819 + 10000.500 18.337 2.822 + 10001.000 17.856 2.816 + 10001.500 19.048 2.806 + 10002.000 18.259 2.805 + 10002.500 18.984 2.812 + 10003.000 19.336 2.819 + 10003.500 18.517 2.831 + 10004.000 16.129 2.843 + 10004.500 13.816 2.844 + 10005.000 14.618 2.839 + 10005.500 17.566 2.825 + 10006.000 19.678 2.819 + 10006.500 20.861 2.808 + 10007.000 19.575 2.804 + 10007.500 19.148 2.801 + 10008.000 18.609 2.799 + 10008.500 18.225 2.806 + 10009.000 17.194 2.815 + 10009.500 17.188 2.822 + 10010.000 13.864 2.823 + 10010.500 15.525 2.820 + 10011.000 16.345 2.818 + 10011.500 15.724 2.818 + 10012.000 15.271 2.822 + 10012.500 14.455 2.832 + 10013.000 13.791 2.837 + 10013.500 14.115 2.842 + 10014.000 15.011 2.840 + 10014.500 16.857 2.837 + 10015.000 18.463 2.830 + 10015.500 17.759 2.827 + 10016.000 17.337 2.831 + 10016.500 14.286 2.839 + 10017.000 12.818 2.838 + 10017.500 12.790 2.835 + 10018.000 12.088 2.813 + 10018.500 13.521 2.805 + 10019.000 14.588 2.810 + 10019.500 16.037 2.822 + 10020.000 15.836 2.830 + 10020.500 17.134 2.834 + 10021.000 17.339 2.841 + 10021.500 19.746 2.839 + 10022.000 27.189 2.829 + 10022.500 35.219 2.791 + 10023.000 38.611 2.770 + 10023.500 39.912 2.766 + 10024.000 37.187 2.773 + 10024.500 31.722 2.796 + 10025.000 23.818 2.810 + 10025.500 18.430 2.829 + 10026.000 16.839 2.837 + 10026.500 16.503 2.838 + 10027.000 16.575 2.843 + 10027.500 21.557 2.843 + 10028.000 25.057 2.846 + 10028.500 31.031 2.831 + 10029.000 31.842 2.818 + 10029.500 32.890 2.815 + 10030.000 32.702 2.814 + 10030.500 30.360 2.818 + 10031.000 27.551 2.818 + 10031.500 23.142 2.822 + 10032.000 20.052 2.821 + 10032.500 19.213 2.817 + 10033.000 18.678 2.813 + 10033.500 20.307 2.816 + 10034.000 20.810 2.823 + 10034.500 18.485 2.840 + 10035.000 17.335 2.843 + 10035.500 16.445 2.844 + 10036.000 21.515 2.835 + 10036.500 30.021 2.813 + 10037.000 35.673 2.803 + 10037.500 36.048 2.791 + 10038.000 31.398 2.787 + 10038.500 23.159 2.795 + 10039.000 17.100 2.800 + 10039.500 18.932 2.810 + 10040.000 24.273 2.816 + 10040.500 35.493 2.821 + 10041.000 39.103 2.822 + 10041.500 42.370 2.815 + 10042.000 44.383 2.808 + 10042.500 47.581 2.797 + 10043.000 47.748 2.794 + 10043.500 45.298 2.797 + 10044.000 42.771 2.803 + 10044.500 28.355 2.831 + 10045.000 20.169 2.835 + 10045.500 17.399 2.829 + 10046.000 16.848 2.820 + 10046.500 20.325 2.820 + 10047.000 26.538 2.819 + 10047.500 33.564 2.806 + 10048.000 39.682 2.790 + 10048.500 38.465 2.778 + 10049.000 36.157 2.784 + 10049.500 32.064 2.793 + 10050.000 30.796 2.810 + 10050.500 30.816 2.832 + 10051.000 34.574 2.816 + 10051.500 36.346 2.808 + 10052.000 39.237 2.796 + 10052.500 35.506 2.804 + 10053.000 30.527 2.813 + 10053.500 28.103 2.821 + 10054.000 26.026 2.829 + 10054.500 28.474 2.810 + 10055.000 29.402 2.800 + 10055.500 28.981 2.794 + 10056.000 28.950 2.797 + 10056.500 29.461 2.798 + 10057.000 31.035 2.803 + 10057.500 31.345 2.809 + 10058.000 29.697 2.822 + 10058.500 28.683 2.838 + 10059.000 26.492 2.841 + 10059.500 25.063 2.843 + 10060.000 22.201 2.844 + 10060.500 16.372 2.825 + 10061.000 15.259 2.823 + 10061.500 14.493 2.817 + 10062.000 14.735 2.814 + 10062.500 21.500 2.823 + 10063.000 31.325 2.820 + 10063.500 38.253 2.816 + 10064.000 57.522 2.789 + 10064.500 93.293 2.744 + 10065.000 90.820 2.733 + 10065.500 84.216 2.743 + 10066.000 69.261 2.774 + 10066.500 29.455 2.790 + 10067.000 25.105 2.812 + 10067.500 21.101 2.821 + 10068.000 21.079 2.823 + 10068.500 21.060 2.820 + 10069.000 20.669 2.821 + 10069.500 20.100 2.824 + 10070.000 18.867 2.828 + 10070.500 19.755 2.836 + 10071.000 20.210 2.836 + 10071.500 22.598 2.829 + 10072.000 23.017 2.825 + 10072.500 39.785 2.820 + 10073.000 44.546 2.815 + 10073.500 46.558 2.799 + 10074.000 43.690 2.783 + 10074.500 34.739 2.777 + 10075.000 26.221 2.788 + 10075.500 21.292 2.815 + 10076.000 21.170 2.825 + 10076.500 24.417 2.831 + 10077.000 26.370 2.828 + 10077.500 27.055 2.817 + 10078.000 26.008 2.809 + 10078.500 22.244 2.810 + 10079.000 20.312 2.816 + 10079.500 17.851 2.829 + 10080.000 17.119 2.834 + 10080.500 19.519 2.837 + 10081.000 20.029 2.837 + 10081.500 24.019 2.831 + 10082.000 31.753 2.813 + 10082.500 38.520 2.799 + 10083.000 42.968 2.790 + 10083.500 51.857 2.781 + 10084.000 58.507 2.771 + 10084.500 68.280 2.760 + 10085.000 72.841 2.759 + 10085.500 82.209 2.757 + 10086.000 85.590 2.750 + 10086.500 87.625 2.735 + 10087.000 82.515 2.727 + 10087.500 78.087 2.725 + 10088.000 62.176 2.737 + 10088.500 49.787 2.755 + 10089.000 42.790 2.767 + 10089.500 32.368 2.774 + 10090.000 28.477 2.775 + 10090.500 30.301 2.777 + 10091.000 35.724 2.780 + 10091.500 41.122 2.786 + 10092.000 45.429 2.790 + 10092.500 52.471 2.782 + 10093.000 54.375 2.767 + 10093.500 59.609 2.753 + 10094.000 50.827 2.741 + 10094.500 46.201 2.755 + 10095.000 42.629 2.766 + 10095.500 41.543 2.771 + 10096.000 45.370 2.771 + 10096.500 52.815 2.760 + 10097.000 56.925 2.749 + 10097.500 59.137 2.748 + 10098.000 59.847 2.749 + 10098.500 52.505 2.767 + 10099.000 45.067 2.775 + 10099.500 40.683 2.784 + 10100.000 36.131 2.794 + 10100.500 29.334 2.801 + 10101.000 26.080 2.804 + 10101.500 24.380 2.798 + 10102.000 22.432 2.790 + 10102.500 20.250 2.790 + 10103.000 21.515 2.813 + 10103.500 25.484 2.823 + 10104.000 32.747 2.826 + 10104.500 37.189 2.826 + 10105.000 36.050 2.803 + 10105.500 32.656 2.809 + 10106.000 31.585 2.814 + 10106.500 39.128 2.793 + 10107.000 42.808 2.772 + 10107.500 63.420 2.753 + 10108.000 92.546 2.744 + 10108.500 101.376 2.725 + 10109.000 104.605 2.720 + 10109.500 104.096 2.702 + 10110.000 104.663 2.687 + 10110.500 97.677 2.682 + 10111.000 85.935 2.700 + 10111.500 80.236 2.716 + 10112.000 58.779 2.756 + 10112.500 50.502 2.776 + 10113.000 51.086 2.775 + 10113.500 55.707 2.770 + 10114.000 60.824 2.771 + 10114.500 60.974 2.767 + 10115.000 53.894 2.763 + 10115.500 42.954 2.773 + 10116.000 38.108 2.787 + 10116.500 28.254 2.818 + 10117.000 24.188 2.821 + 10117.500 21.552 2.822 + 10118.000 21.392 2.827 + 10118.500 24.405 2.829 + 10119.000 27.962 2.820 + 10119.500 29.580 2.797 + 10120.000 27.572 2.797 + 10120.500 24.146 2.803 + 10121.000 21.794 2.803 + 10121.500 20.864 2.800 + 10122.000 21.174 2.796 + 10122.500 23.223 2.804 + 10123.000 27.633 2.800 + 10123.500 28.842 2.789 + 10124.000 28.184 2.782 + 10124.500 24.131 2.791 + 10125.000 21.696 2.801 + 10125.500 21.400 2.797 + 10126.000 26.978 2.792 + 10126.500 35.494 2.778 + 10127.000 38.194 2.774 + 10127.500 35.549 2.778 + 10128.000 30.934 2.789 + 10128.500 26.913 2.811 + 10129.000 25.825 2.817 + 10129.500 24.265 2.821 + 10130.000 22.712 2.814 + 10130.500 22.347 2.802 + 10131.000 21.884 2.800 + 10131.500 23.544 2.798 + 10132.000 30.803 2.795 + 10132.500 36.096 2.784 + 10133.000 37.633 2.774 + 10133.500 33.673 2.771 + 10134.000 29.311 2.777 + 10134.500 26.014 2.804 + 10135.000 25.418 2.815 + 10135.500 27.546 2.814 + 10136.000 28.608 2.804 + 10136.500 33.009 2.793 + 10137.000 33.914 2.793 + 10137.500 32.217 2.798 + 10138.000 29.326 2.802 + 10138.500 25.561 2.811 + 10139.000 25.724 2.817 + 10139.500 23.256 2.828 + 10140.000 21.272 2.840 + 10140.500 18.676 2.853 + 10141.000 18.033 2.863 + 10141.500 20.228 2.864 + 10142.000 25.640 2.843 + 10142.500 35.720 2.810 + 10143.000 45.112 2.791 + 10143.500 48.558 2.773 + 10144.000 51.843 2.768 + 10144.500 52.694 2.774 + 10145.000 52.754 2.781 + 10145.500 52.892 2.771 + 10146.000 50.732 2.741 + 10146.500 49.610 2.697 + 10147.000 48.141 2.705 + 10147.500 40.976 2.746 + 10148.000 31.182 2.814 + 10148.500 19.405 2.861 + 10149.000 16.452 2.858 + 10149.500 15.624 2.856 + 10150.000 15.196 2.848 + 10150.500 14.636 2.840 + 10151.000 14.127 2.855 + 10151.500 13.702 2.865 + 10152.000 17.069 2.853 + 10152.500 20.980 2.845 + 10153.000 25.307 2.844 + 10153.500 26.091 2.839 + 10154.000 27.198 2.829 + 10154.500 25.742 2.822 + 10155.000 22.478 2.823 + 10155.500 18.638 2.831 + 10156.000 20.266 2.833 + 10156.500 32.235 2.799 + 10157.000 43.610 2.771 + 10157.500 50.593 2.751 + 10158.000 48.744 2.734 + 10158.500 36.859 2.760 + 10159.000 30.969 2.779 + 10159.500 31.599 2.781 + 10160.000 36.556 2.781 + 10160.500 51.858 2.774 + 10161.000 58.659 2.764 + 10161.500 57.046 2.763 + 10162.000 52.578 2.761 + 10162.500 48.893 2.757 + 10163.000 44.301 2.749 + 10163.500 42.387 2.749 + 10164.000 38.950 2.765 + 10164.500 32.694 2.787 + 10165.000 28.360 2.808 + 10165.500 27.524 2.814 + 10166.000 29.250 2.807 + 10166.500 33.519 2.800 + 10167.000 33.968 2.795 + 10167.500 27.107 2.802 + 10168.000 22.751 2.827 + 10168.500 18.257 2.837 + 10169.000 19.375 2.832 + 10169.500 20.094 2.817 + 10170.000 19.615 2.815 + 10170.500 19.264 2.822 + 10171.000 20.784 2.822 + 10171.500 22.842 2.820 + 10172.000 25.987 2.806 + 10172.500 27.533 2.798 + 10173.000 31.110 2.795 + 10173.500 36.275 2.781 + 10174.000 41.043 2.762 + 10174.500 46.402 2.750 + 10175.000 44.467 2.756 + 10175.500 36.685 2.785 + 10176.000 29.236 2.813 + 10176.500 19.088 2.831 + 10177.000 15.334 2.832 + 10177.500 14.501 2.835 + 10178.000 14.810 2.840 + 10178.500 17.978 2.848 + 10179.000 20.269 2.848 + 10179.500 23.521 2.841 + 10180.000 32.162 2.834 + 10180.500 40.435 2.826 + 10181.000 40.945 2.824 + 10181.500 42.050 2.822 + 10182.000 39.085 2.816 + 10182.500 24.820 2.828 + 10183.000 18.826 2.850 + 10183.500 17.774 2.864 + 10184.000 17.751 2.867 + 10184.500 21.519 2.847 + 10185.000 25.489 2.826 + 10185.500 27.229 2.815 + 10186.000 26.368 2.823 + 10186.500 23.837 2.835 + 10187.000 17.215 2.847 + 10187.500 13.202 2.861 + 10188.000 11.364 2.864 + 10188.500 11.381 2.865 + 10189.000 12.691 2.862 + 10189.500 13.945 2.855 + 10190.000 13.716 2.846 + 10190.500 12.044 2.841 + 10191.000 10.780 2.830 + 10191.500 9.610 2.828 + 10192.000 11.452 2.836 + 10192.500 15.164 2.845 + 10193.000 20.187 2.848 + 10193.500 20.809 2.847 + 10194.000 20.616 2.845 + 10194.500 19.560 2.844 + 10195.000 15.502 2.838 + 10195.500 15.083 2.836 + 10196.000 15.561 2.838 + 10196.500 15.436 2.844 + 10197.000 14.911 2.843 + 10197.500 14.246 2.834 + 10198.000 14.549 2.829 + 10198.500 15.966 2.825 + 10199.000 16.461 2.824 + 10199.500 20.752 2.816 + 10200.000 22.128 2.804 + 10200.500 22.509 2.793 + 10201.000 23.215 2.797 + 10201.500 22.628 2.807 + 10202.000 21.682 2.833 + 10202.500 20.417 2.844 + 10203.000 19.039 2.843 + 10203.500 15.908 2.841 + 10204.000 14.414 2.843 + 10204.500 13.648 2.854 + 10205.000 13.203 2.860 + 10205.500 14.222 2.835 + 10206.000 16.115 2.822 + 10206.500 17.579 2.800 + 10207.000 19.455 2.810 + 10207.500 21.159 2.817 + 10208.000 21.951 2.813 + 10208.500 23.430 2.807 + 10209.000 24.361 2.801 + 10209.500 21.639 2.800 + 10210.000 19.600 2.799 + 10210.500 16.008 2.801 + 10211.000 14.912 2.809 + 10211.500 14.781 2.816 + 10212.000 17.769 2.816 + 10212.500 19.731 2.811 + 10213.000 20.451 2.806 + 10213.500 21.095 2.800 + 10214.000 20.880 2.804 + 10214.500 19.410 2.821 + 10215.000 16.439 2.845 + 10215.500 16.252 2.850 + 10216.000 16.960 2.850 + 10216.500 16.090 2.851 + 10217.000 14.489 2.861 + 10217.500 13.032 2.861 + 10218.000 12.052 2.855 + 10218.500 12.022 2.839 + 10219.000 12.954 2.834 + 10219.500 15.414 2.821 + 10220.000 17.401 2.810 + 10220.500 20.823 2.794 + 10221.000 21.274 2.801 + 10221.500 18.152 2.811 + 10222.000 14.130 2.823 + 10222.500 14.052 2.814 + 10223.000 15.119 2.800 + 10223.500 16.280 2.795 + 10224.000 16.592 2.796 + 10224.500 15.273 2.806 + 10225.000 14.041 2.833 + 10225.500 12.600 2.881 + 10226.000 13.056 2.873 + 10226.500 14.540 2.851 + 10227.000 15.269 2.825 + 10227.500 16.175 2.816 + 10228.000 17.872 2.819 + 10228.500 17.116 2.822 + 10229.000 15.245 2.822 + 10229.500 12.650 2.817 + 10230.000 11.440 2.817 + 10230.500 12.870 2.820 + 10231.000 13.070 2.834 + 10231.500 15.317 2.847 + 10232.000 15.906 2.833 + 10232.500 19.755 2.825 + 10233.000 20.217 2.801 + 10233.500 19.840 2.793 + 10234.000 17.394 2.797 + 10234.500 13.909 2.813 + 10235.000 13.182 2.825 + 10235.500 12.859 2.824 + 10236.000 15.537 2.822 + 10236.500 19.532 2.822 + 10237.000 19.502 2.824 + 10237.500 19.957 2.824 + 10238.000 17.768 2.824 + 10238.500 16.090 2.824 + 10239.000 16.352 2.824 + 10239.500 16.163 2.824 + 10240.000 18.081 2.824 + 10240.500 21.867 2.824 + 10241.000 24.732 2.823 + 10241.500 25.957 2.822 + 10242.000 25.018 2.835 + 10242.500 21.805 2.842 + 10243.000 21.092 2.850 + 10243.500 20.328 2.853 + 10244.000 20.009 2.849 + 10244.500 16.120 2.842 + 10245.000 13.887 2.827 + 10245.500 12.350 2.819 + 10246.000 11.704 2.816 + 10246.500 11.642 2.824 + 10247.000 12.397 2.836 + 10247.500 13.879 2.845 + 10248.000 14.875 2.844 + 10248.500 15.390 2.842 + 10249.000 14.565 2.832 + 10249.500 14.841 2.825 + 10250.000 16.076 2.828 + 10250.500 18.400 2.831 + 10251.000 20.231 2.844 + 10251.500 20.134 2.855 + 10252.000 20.192 2.838 + 10252.500 16.861 2.814 + 10253.000 16.945 2.812 + 10253.500 19.402 2.814 + 10254.000 24.302 2.814 + 10254.500 34.480 2.813 + 10255.000 38.469 2.806 + 10255.500 40.836 2.802 + 10256.000 39.826 2.805 + 10256.500 35.671 2.811 + 10257.000 35.140 2.814 + 10257.500 35.425 2.815 + 10258.000 35.248 2.818 + 10258.500 29.858 2.822 + 10259.000 22.992 2.828 + 10259.500 17.586 2.835 + 10260.000 9.911 2.845 + 10260.500 13.160 2.865 + 10261.000 20.033 2.859 + 10261.500 21.283 2.851 + 10262.000 24.682 2.823 + 10262.500 27.869 2.796 + 10263.000 34.300 2.780 + 10263.500 40.457 2.780 + 10264.000 43.464 2.804 + 10264.500 40.379 2.820 + 10265.000 33.445 2.829 + 10265.500 23.284 2.824 + 10266.000 19.030 2.824 + 10266.500 14.103 2.830 + 10267.000 13.043 2.841 + 10267.500 13.214 2.841 + 10268.000 14.634 2.839 + 10268.500 16.211 2.825 + 10269.000 16.999 2.825 + 10269.500 16.922 2.823 + 10270.000 16.111 2.826 + 10270.500 14.480 2.828 + 10271.000 12.819 2.828 + 10271.500 12.353 2.824 + 10272.000 12.996 2.824 + 10272.500 14.063 2.821 + 10273.000 15.694 2.819 + 10273.500 15.412 2.821 + 10274.000 15.163 2.829 + 10274.500 13.782 2.830 + 10275.000 13.607 2.822 + 10275.500 12.239 2.817 + 10276.000 11.593 2.826 + 10276.500 12.524 2.844 + 10277.000 13.677 2.856 + 10277.500 14.482 2.862 + 10278.000 14.970 2.861 + 10278.500 14.710 2.850 + 10279.000 13.710 2.844 + 10279.500 12.555 2.835 + 10280.000 13.404 2.835 + 10280.500 14.460 2.834 + 10281.000 14.940 2.842 + 10281.500 16.278 2.844 + 10282.000 16.404 2.833 + 10282.500 14.297 2.826 + 10283.000 13.955 2.818 + 10283.500 13.813 2.816 + 10284.000 14.519 2.816 + 10284.500 14.687 2.819 + 10285.000 14.720 2.824 + 10285.500 14.551 2.826 + 10286.000 13.563 2.823 + 10286.500 13.716 2.822 + 10287.000 13.913 2.825 + 10287.500 13.723 2.828 + 10288.000 12.955 2.826 + 10288.500 11.515 2.826 + 10289.000 12.209 2.837 + 10289.500 12.190 2.846 + 10290.000 12.818 2.839 + 10290.500 13.964 2.832 + 10291.000 14.590 2.819 + 10291.500 14.423 2.815 + 10292.000 16.899 2.820 + 10292.500 16.989 2.819 + 10293.000 17.208 2.810 + 10293.500 16.465 2.808 + 10294.000 15.314 2.812 + 10294.500 13.843 2.834 + 10295.000 13.157 2.851 + 10295.500 13.806 2.858 + 10296.000 13.968 2.860 + 10296.500 14.616 2.851 + 10297.000 13.883 2.843 + 10297.500 13.194 2.830 + 10298.000 13.555 2.812 + 10298.500 13.559 2.799 + 10299.000 14.533 2.804 + 10299.500 15.279 2.808 + 10300.000 16.171 2.811 + 10300.500 17.567 2.812 + 10301.000 18.038 2.822 + 10301.500 18.598 2.833 + 10302.000 17.583 2.842 + 10302.500 16.962 2.837 + 10303.000 15.452 2.824 + 10303.500 13.905 2.820 + 10304.000 12.569 2.818 + 10304.500 12.572 2.828 + 10305.000 12.368 2.839 + 10305.500 13.717 2.845 + 10306.000 14.383 2.848 + 10306.500 13.789 2.850 + 10307.000 13.958 2.850 + 10307.500 13.885 2.856 + 10308.000 13.675 2.864 + 10308.500 13.661 2.872 + 10309.000 13.786 2.847 + 10309.500 12.951 2.813 + 10310.000 13.770 2.818 + 10310.500 13.817 2.827 + 10311.000 14.561 2.834 + 10311.500 14.503 2.836 + 10312.000 14.366 2.841 + 10312.500 15.225 2.841 + 10313.000 14.730 2.842 + 10313.500 15.621 2.837 + 10314.000 15.515 2.825 + 10314.500 14.503 2.817 + 10315.000 13.022 2.819 + 10315.500 12.508 2.823 + 10316.000 12.243 2.823 + 10316.500 12.769 2.828 + 10317.000 12.045 2.832 + 10317.500 12.042 2.832 + 10318.000 12.864 2.830 + 10318.500 13.930 2.822 + 10319.000 14.728 2.814 + 10319.500 15.199 2.810 + 10320.000 16.177 2.809 + 10320.500 15.746 2.819 + 10321.000 14.687 2.826 + 10321.500 13.640 2.813 + 10322.000 13.037 2.807 + 10322.500 13.114 2.813 + 10323.000 13.114 2.827 + 10323.500 13.054 2.841 + 10324.000 13.590 2.843 + 10324.500 14.941 2.850 + 10325.000 15.655 2.856 + 10325.500 16.207 2.863 + 10326.000 15.432 2.860 + 10326.500 14.716 2.850 + 10327.000 13.819 2.846 + 10327.500 13.999 2.844 + 10328.000 14.971 2.843 + 10328.500 15.642 2.840 + 10329.000 16.215 2.833 + 10329.500 14.817 2.830 + 10330.000 14.230 2.828 + 10330.500 14.496 2.841 + 10331.000 13.835 2.858 + 10331.500 13.801 2.857 + 10332.000 12.890 2.853 + 10332.500 13.844 2.839 + 10333.000 13.239 2.837 + 10333.500 13.093 2.833 + 10334.000 13.077 2.834 + 10334.500 13.224 2.834 + 10335.000 14.627 2.842 + 10335.500 16.872 2.836 + 10336.000 18.658 2.826 + 10336.500 17.881 2.834 + 10337.000 16.329 2.844 + 10337.500 14.219 2.854 + 10338.000 13.222 2.853 + 10338.500 13.624 2.839 + 10339.000 14.523 2.825 + 10339.500 14.790 2.822 + 10340.000 15.768 2.827 + 10340.500 14.009 2.840 + 10341.000 14.618 2.849 + 10341.500 14.715 2.854 + 10342.000 16.137 2.857 + 10342.500 17.097 2.855 + 10343.000 17.374 2.855 + 10343.500 16.262 2.856 + 10344.000 15.428 2.851 + 10344.500 14.736 2.847 + 10345.000 13.766 2.840 + 10345.500 14.456 2.833 + 10346.000 15.281 2.826 + 10346.500 16.228 2.815 + 10347.000 17.216 2.812 + 10347.500 16.573 2.815 + 10348.000 17.235 2.823 + 10348.500 18.506 2.834 + 10349.000 18.573 2.849 + 10349.500 17.152 2.862 + 10350.000 17.031 2.893 + 10350.500 16.568 2.876 + 10351.000 16.329 2.865 + 10351.500 17.829 2.851 + 10352.000 18.014 2.843 + 10352.500 19.914 2.836 + 10353.000 20.867 2.827 + 10353.500 21.186 2.822 + 10354.000 21.938 2.827 + 10354.500 21.815 2.840 + 10355.000 21.618 2.857 + 10355.500 21.642 2.866 + 10356.000 24.387 2.869 + 10356.500 28.379 2.864 + 10357.000 26.651 2.847 + 10357.500 23.963 2.830 + 10358.000 19.976 2.821 + 10358.500 19.158 2.822 + 10359.000 20.005 2.833 + 10359.500 20.902 2.838 + 10360.000 21.035 2.839 + 10360.500 21.787 2.824 + 10361.000 22.736 2.823 + 10361.500 23.191 2.818 + 10362.000 28.054 2.810 + 10362.500 30.402 2.792 + 10363.000 28.005 2.794 + 10363.500 21.557 2.809 + 10364.000 18.203 2.827 + 10364.500 13.828 2.841 + 10365.000 14.706 2.832 + 10365.500 15.524 2.812 + 10366.000 15.356 2.809 + 10366.500 13.842 2.812 + 10367.000 12.902 2.820 + 10367.500 13.715 2.820 + 10368.000 15.507 2.819 + 10368.500 21.490 2.819 + 10369.000 24.093 2.824 + 10369.500 23.057 2.830 + 10370.000 23.503 2.833 + 10370.500 21.356 2.839 + 10371.000 20.414 2.841 + 10371.500 16.386 2.852 + 10372.000 15.204 2.864 + 10372.500 12.895 2.867 + 10373.000 12.563 2.855 + 10373.500 14.211 2.842 + 10374.000 14.775 2.839 + 10374.500 16.156 2.836 + 10375.000 16.760 2.836 + 10375.500 17.757 2.834 + 10376.000 18.070 2.828 + 10376.500 18.420 2.826 + 10377.000 19.042 2.823 + 10377.500 19.015 2.821 + 10378.000 17.831 2.831 + 10378.500 15.306 2.843 + 10379.000 14.507 2.851 + 10379.500 16.128 2.846 + 10380.000 17.251 2.838 + 10380.500 17.974 2.823 + 10381.000 17.094 2.822 + 10381.500 16.950 2.823 + 10382.000 17.153 2.823 + 10382.500 20.251 2.819 + 10383.000 21.314 2.816 + 10383.500 24.031 2.816 + 10384.000 26.594 2.818 + 10384.500 27.065 2.819 + 10385.000 24.803 2.813 + 10385.500 20.730 2.810 + 10386.000 19.233 2.813 + 10386.500 16.226 2.819 + 10387.000 16.281 2.824 + 10387.500 20.728 2.823 + 10388.000 24.377 2.821 + 10388.500 35.879 2.813 + 10389.000 42.574 2.807 + 10389.500 46.355 2.796 + 10390.000 44.577 2.807 + 10390.500 29.753 2.827 + 10391.000 22.344 2.843 + 10391.500 18.576 2.857 + 10392.000 15.663 2.857 + 10392.500 16.638 2.851 + 10393.000 17.027 2.850 + 10393.500 18.815 2.849 + 10394.000 20.535 2.855 + 10394.500 22.860 2.856 + 10395.000 27.631 2.841 + 10395.500 31.531 2.830 + 10396.000 35.000 2.807 + 10396.500 35.450 2.817 + 10397.000 35.288 2.823 + 10397.500 37.945 2.820 + 10398.000 42.439 2.806 + 10398.500 43.524 2.793 + 10399.000 39.446 2.800 + 10399.500 29.695 2.813 + 10400.000 26.372 2.865 + 10400.500 20.518 2.877 + 10401.000 17.749 2.879 + 10401.500 17.884 2.867 + 10402.000 16.218 2.852 + 10402.500 16.178 2.836 + 10403.000 14.770 2.833 + 10403.500 14.565 2.834 + 10404.000 15.245 2.832 + 10404.500 18.899 2.822 + 10405.000 21.620 2.814 + 10405.500 28.737 2.798 + 10406.000 35.133 2.787 + 10406.500 39.544 2.769 + 10407.000 36.672 2.767 + 10407.500 28.878 2.785 + 10408.000 22.810 2.798 + 10408.500 15.986 2.816 + 10409.000 14.150 2.813 + 10409.500 12.908 2.813 + 10410.000 13.087 2.813 + 10410.500 13.648 2.826 + 10411.000 19.152 2.838 + 10411.500 22.237 2.839 + 10412.000 29.239 2.826 + 10412.500 33.870 2.810 + 10413.000 34.986 2.808 + 10413.500 28.181 2.817 + 10414.000 24.623 2.837 + 10414.500 20.797 2.855 + 10415.000 19.419 2.864 + 10415.500 19.285 2.860 + 10416.000 20.384 2.858 + 10416.500 20.149 2.857 + 10417.000 20.843 2.855 + 10417.500 21.040 2.844 + 10418.000 21.068 2.831 + 10418.500 20.887 2.817 + 10419.000 19.298 2.818 + 10419.500 17.139 2.826 + 10420.000 16.262 2.832 + 10420.500 16.079 2.842 + 10421.000 17.797 2.845 + 10421.500 20.243 2.853 + 10422.000 21.384 2.852 + 10422.500 26.855 2.846 + 10423.000 29.747 2.836 + 10423.500 29.546 2.826 + 10424.000 27.094 2.820 + 10424.500 22.851 2.823 + 10425.000 20.822 2.830 + 10425.500 19.535 2.841 + 10426.000 19.002 2.846 + 10426.500 17.750 2.870 + 10427.000 19.786 2.888 + 10427.500 25.404 2.900 + 10428.000 30.992 2.894 + 10428.500 31.237 2.866 + 10429.000 29.403 2.854 + 10429.500 24.689 2.849 + 10430.000 21.863 2.865 + 10430.500 18.833 2.890 + 10431.000 15.669 2.885 + 10431.500 14.674 2.876 + 10432.000 14.625 2.858 + 10432.500 13.867 2.848 + 10433.000 13.559 2.845 + 10433.500 13.207 2.850 + 10434.000 13.019 2.849 + 10434.500 13.617 2.847 + 10435.000 15.647 2.844 + 10435.500 18.723 2.841 + 10436.000 21.404 2.840 + 10436.500 23.420 2.823 + 10437.000 24.561 2.816 + 10437.500 25.410 2.813 + 10438.000 23.320 2.819 + 10438.500 18.178 2.826 + 10439.000 16.282 2.844 + 10439.500 14.722 2.849 + 10440.000 14.732 2.863 + 10440.500 14.636 2.855 + 10441.000 14.486 2.844 + 10441.500 13.824 2.848 + 10442.000 13.908 2.849 + 10442.500 15.435 2.854 + 10443.000 17.279 2.855 + 10443.500 19.245 2.841 + 10444.000 23.734 2.822 + 10444.500 29.146 2.818 + 10445.000 38.679 2.816 + 10445.500 48.123 2.805 + 10446.000 58.320 2.796 + 10446.500 63.662 2.782 + 10447.000 63.633 2.782 + 10447.500 60.985 2.787 + 10448.000 56.596 2.787 + 10448.500 45.236 2.791 + 10449.000 42.531 2.792 + 10449.500 36.269 2.791 + 10450.000 32.561 2.822 diff --git a/ThirdParty/NRLib/well_UnitTests/Bean_C.las b/ThirdParty/NRLib/well_UnitTests/Bean_C.las new file mode 100644 index 0000000000..de5d951794 --- /dev/null +++ b/ThirdParty/NRLib/well_UnitTests/Bean_C.las @@ -0,0 +1,11231 @@ +~Version Information Block + VERS. 2.00: CWLS LOG ASCII STANDARD - VERSION 2.000000 + WRAP. NO: One Line Per Depth Step +# +~Well Information Block +#MNEM.UNIT Data Information +#---------- ------------------------------------------ ---------------- + STRT.FT 10450.0000: + STOP.FT 16050.0000: + STEP.FT 0.5000: + NULL. -999.2500: + COMP. : COMPANY + WELL. : WELL + FLD . : FIELD + CNTY. : COUNTY + STAT. : STATE + CTRY. : COUNTRY + SRVC. : SERVICE COMPANY + DATE. : DATE + API . : API NUMBER + UWI . : UWI NUMBER +# +~Curve Information Block +#MNEM.UNIT API CODE Curve Description +#---------- ------------- ------------------- + DEPT.FT : Depth in Feet + GR .GAPI : Gamma Ray + RHOB.G/C3 : Bulk Density +# +~A DEPTH GR RHOB + 10450.000 24.706 2.836 + 10450.500 22.353 2.840 + 10451.000 20.784 2.840 + 10451.500 20.784 2.842 + 10452.000 24.706 2.842 + 10452.500 24.706 2.840 + 10453.000 22.353 2.836 + 10453.500 20.568 2.840 + 10454.000 19.946 2.830 + 10454.500 22.246 2.821 + 10455.000 28.099 2.814 + 10455.500 30.665 2.812 + 10456.000 32.842 2.812 + 10456.500 39.704 2.807 + 10457.000 40.162 2.805 + 10457.500 41.774 2.797 + 10458.000 41.505 2.790 + 10458.500 39.264 2.797 + 10459.000 36.435 2.805 + 10459.500 34.225 2.819 + 10460.000 34.276 2.830 + 10460.500 36.568 2.830 + 10461.000 37.436 2.825 + 10461.500 35.823 2.813 + 10462.000 32.202 2.810 + 10462.500 28.206 2.820 + 10463.000 28.556 2.832 + 10463.500 28.499 2.841 + 10464.000 28.405 2.846 + 10464.500 24.592 2.826 + 10465.000 24.185 2.821 + 10465.500 28.367 2.824 + 10466.000 36.284 2.849 + 10466.500 44.480 2.852 + 10467.000 47.056 2.846 + 10467.500 43.175 2.817 + 10468.000 36.898 2.806 + 10468.500 24.369 2.804 + 10469.000 21.400 2.804 + 10469.500 19.948 2.805 + 10470.000 20.474 2.804 + 10470.500 23.795 2.807 + 10471.000 24.564 2.808 + 10471.500 26.011 2.811 + 10472.000 26.229 2.816 + 10472.500 24.146 2.823 + 10473.000 22.010 2.822 + 10473.500 19.328 2.815 + 10474.000 17.409 2.804 + 10474.500 16.081 2.810 + 10475.000 17.221 2.820 + 10475.500 19.134 2.829 + 10476.000 21.981 2.839 + 10476.500 23.715 2.840 + 10477.000 24.234 2.833 + 10477.500 21.358 2.822 + 10478.000 19.044 2.820 + 10478.500 19.625 2.821 + 10479.000 22.828 2.824 + 10479.500 33.347 2.829 + 10480.000 42.179 2.837 + 10480.500 40.521 2.844 + 10481.000 39.595 2.847 + 10481.500 30.108 2.824 + 10482.000 26.818 2.818 + 10482.500 19.963 2.822 + 10483.000 19.929 2.828 + 10483.500 20.983 2.841 + 10484.000 23.798 2.844 + 10484.500 29.602 2.843 + 10485.000 30.894 2.842 + 10485.500 29.791 2.843 + 10486.000 28.644 2.842 + 10486.500 25.967 2.820 + 10487.000 25.658 2.814 + 10487.500 24.875 2.807 + 10488.000 24.074 2.814 + 10488.500 21.130 2.826 + 10489.000 20.385 2.836 + 10489.500 20.247 2.843 + 10490.000 19.967 2.847 + 10490.500 21.247 2.839 + 10491.000 21.550 2.834 + 10491.500 22.140 2.835 + 10492.000 24.753 2.840 + 10492.500 27.642 2.837 + 10493.000 31.996 2.819 + 10493.500 36.775 2.804 + 10494.000 41.345 2.796 + 10494.500 42.006 2.812 + 10495.000 38.926 2.822 + 10495.500 33.364 2.826 + 10496.000 29.700 2.827 + 10496.500 26.069 2.843 + 10497.000 25.746 2.852 + 10497.500 23.878 2.856 + 10498.000 22.794 2.849 + 10498.500 21.725 2.831 + 10499.000 20.665 2.831 + 10499.500 19.771 2.833 + 10500.000 21.720 2.840 + 10500.500 25.032 2.842 + 10501.000 27.208 2.835 + 10501.500 28.087 2.828 + 10502.000 27.884 2.826 + 10502.500 25.308 2.830 + 10503.000 24.105 2.832 + 10503.500 22.519 2.831 + 10504.000 21.433 2.832 + 10504.500 19.582 2.830 + 10505.000 18.161 2.828 + 10505.500 19.517 2.824 + 10506.000 20.129 2.821 + 10506.500 20.908 2.823 + 10507.000 20.207 2.828 + 10507.500 19.384 2.842 + 10508.000 18.978 2.854 + 10508.500 18.980 2.855 + 10509.000 19.232 2.851 + 10509.500 18.742 2.844 + 10510.000 16.892 2.843 + 10510.500 19.273 2.857 + 10511.000 19.541 2.853 + 10511.500 24.094 2.849 + 10512.000 24.898 2.839 + 10512.500 22.642 2.820 + 10513.000 21.602 2.824 + 10513.500 20.887 2.835 + 10514.000 20.975 2.839 + 10514.500 21.135 2.839 + 10515.000 20.191 2.836 + 10515.500 18.705 2.841 + 10516.000 15.913 2.866 + 10516.500 14.890 2.874 + 10517.000 14.460 2.870 + 10517.500 15.169 2.863 + 10518.000 16.228 2.847 + 10518.500 16.146 2.838 + 10519.000 17.287 2.828 + 10519.500 19.493 2.833 + 10520.000 20.706 2.836 + 10520.500 23.143 2.847 + 10521.000 22.801 2.852 + 10521.500 19.968 2.862 + 10522.000 17.485 2.865 + 10522.500 17.464 2.855 + 10523.000 19.777 2.850 + 10523.500 22.459 2.838 + 10524.000 24.079 2.832 + 10524.500 26.055 2.827 + 10525.000 26.021 2.827 + 10525.500 25.556 2.828 + 10526.000 25.508 2.831 + 10526.500 24.895 2.840 + 10527.000 21.892 2.844 + 10527.500 21.832 2.837 + 10528.000 24.118 2.831 + 10528.500 24.518 2.824 + 10529.000 23.752 2.825 + 10529.500 22.137 2.826 + 10530.000 20.962 2.825 + 10530.500 20.052 2.846 + 10531.000 21.654 2.852 + 10531.500 21.450 2.854 + 10532.000 27.282 2.838 + 10532.500 31.064 2.837 + 10533.000 33.219 2.839 + 10533.500 35.016 2.836 + 10534.000 34.769 2.834 + 10534.500 29.104 2.826 + 10535.000 25.544 2.832 + 10535.500 19.163 2.851 + 10536.000 17.911 2.857 + 10536.500 14.366 2.875 + 10537.000 13.696 2.872 + 10537.500 15.042 2.862 + 10538.000 16.216 2.851 + 10538.500 23.249 2.840 + 10539.000 32.822 2.837 + 10539.500 44.059 2.836 + 10540.000 60.065 2.826 + 10540.500 82.560 2.804 + 10541.000 82.885 2.773 + 10541.500 77.961 2.766 + 10542.000 57.346 2.794 + 10542.500 39.129 2.811 + 10543.000 24.958 2.850 + 10543.500 25.596 2.848 + 10544.000 23.206 2.849 + 10544.500 42.529 2.835 + 10545.000 54.889 2.824 + 10545.500 78.777 2.810 + 10546.000 100.510 2.781 + 10546.500 123.498 2.746 + 10547.000 120.226 2.710 + 10547.500 118.743 2.703 + 10548.000 95.088 2.707 + 10548.500 51.105 2.767 + 10549.000 36.484 2.798 + 10549.500 26.992 2.823 + 10550.000 22.379 2.837 + 10550.500 22.078 2.831 + 10551.000 26.563 2.824 + 10551.500 31.511 2.824 + 10552.000 34.923 2.824 + 10552.500 34.515 2.824 + 10553.000 32.956 2.826 + 10553.500 27.873 2.830 + 10554.000 25.325 2.830 + 10554.500 20.762 2.830 + 10555.000 19.154 2.828 + 10555.500 21.267 2.828 + 10556.000 20.965 2.825 + 10556.500 43.429 2.819 + 10557.000 53.150 2.813 + 10557.500 59.149 2.791 + 10558.000 53.576 2.780 + 10558.500 38.429 2.800 + 10559.000 30.058 2.822 + 10559.500 27.025 2.847 + 10560.000 28.851 2.842 + 10560.500 33.688 2.814 + 10561.000 35.346 2.809 + 10561.500 38.565 2.793 + 10562.000 39.525 2.788 + 10562.500 40.251 2.786 + 10563.000 41.174 2.785 + 10563.500 40.778 2.794 + 10564.000 38.038 2.810 + 10564.500 32.670 2.819 + 10565.000 30.026 2.822 + 10565.500 30.104 2.817 + 10566.000 31.889 2.799 + 10566.500 37.088 2.781 + 10567.000 43.832 2.732 + 10567.500 47.113 2.724 + 10568.000 51.217 2.724 + 10568.500 50.016 2.728 + 10569.000 45.772 2.728 + 10569.500 42.810 2.728 + 10570.000 39.553 2.733 + 10570.500 37.047 2.738 + 10571.000 38.048 2.732 + 10571.500 41.433 2.723 + 10572.000 42.246 2.724 + 10572.500 44.446 2.742 + 10573.000 45.522 2.746 + 10573.500 48.020 2.728 + 10574.000 49.164 2.711 + 10574.500 47.765 2.702 + 10575.000 42.882 2.704 + 10575.500 36.660 2.715 + 10576.000 31.068 2.733 + 10576.500 22.894 2.754 + 10577.000 20.640 2.775 + 10577.500 18.871 2.786 + 10578.000 20.806 2.787 + 10578.500 25.364 2.787 + 10579.000 28.965 2.794 + 10579.500 39.020 2.800 + 10580.000 52.733 2.806 + 10580.500 70.486 2.795 + 10581.000 93.141 2.774 + 10581.500 102.227 2.744 + 10582.000 103.460 2.731 + 10582.500 97.351 2.720 + 10583.000 89.728 2.723 + 10583.500 86.035 2.736 + 10584.000 78.447 2.746 + 10584.500 65.332 2.767 + 10585.000 53.611 2.782 + 10585.500 39.835 2.809 + 10586.000 34.053 2.825 + 10586.500 32.150 2.849 + 10587.000 36.475 2.852 + 10587.500 43.277 2.847 + 10588.000 50.122 2.831 + 10588.500 57.180 2.808 + 10589.000 59.724 2.796 + 10589.500 54.708 2.792 + 10590.000 44.721 2.793 + 10590.500 34.241 2.799 + 10591.000 27.736 2.808 + 10591.500 25.353 2.815 + 10592.000 27.343 2.820 + 10592.500 32.146 2.820 + 10593.000 38.397 2.816 + 10593.500 42.830 2.809 + 10594.000 46.863 2.799 + 10594.500 48.596 2.781 + 10595.000 45.146 2.779 + 10595.500 38.760 2.773 + 10596.000 34.895 2.772 + 10596.500 27.089 2.760 + 10597.000 22.870 2.751 + 10597.500 20.730 2.739 + 10598.000 21.248 2.731 + 10598.500 23.769 2.725 + 10599.000 26.732 2.723 + 10599.500 31.494 2.723 + 10600.000 43.762 2.725 + 10600.500 61.708 2.735 + 10601.000 73.117 2.741 + 10601.500 76.137 2.754 + 10602.000 68.754 2.772 + 10602.500 45.098 2.791 + 10603.000 29.585 2.791 + 10603.500 25.155 2.779 + 10604.000 21.661 2.759 + 10604.500 23.395 2.740 + 10605.000 23.865 2.738 + 10605.500 23.535 2.732 + 10606.000 23.147 2.726 + 10606.500 19.937 2.713 + 10607.000 18.712 2.715 + 10607.500 17.596 2.732 + 10608.000 14.692 2.739 + 10608.500 33.152 2.752 + 10609.000 43.125 2.743 + 10609.500 64.208 2.733 + 10610.000 61.257 2.727 + 10610.500 66.948 2.729 + 10611.000 46.246 2.733 + 10611.500 30.272 2.735 + 10612.000 24.933 2.729 + 10612.500 20.491 2.720 + 10613.000 20.232 2.717 + 10613.500 17.028 2.715 + 10614.000 15.183 2.714 + 10614.500 14.751 2.711 + 10615.000 15.522 2.707 + 10615.500 16.206 2.705 + 10616.000 16.768 2.713 + 10616.500 17.205 2.722 + 10617.000 19.467 2.726 + 10617.500 21.985 2.730 + 10618.000 23.637 2.745 + 10618.500 21.447 2.774 + 10619.000 18.673 2.778 + 10619.500 17.516 2.770 + 10620.000 18.295 2.748 + 10620.500 19.899 2.738 + 10621.000 20.879 2.746 + 10621.500 20.690 2.764 + 10622.000 20.958 2.786 + 10622.500 19.482 2.804 + 10623.000 19.218 2.814 + 10623.500 19.210 2.816 + 10624.000 19.069 2.805 + 10624.500 19.969 2.810 + 10625.000 19.482 2.837 + 10625.500 19.920 2.852 + 10626.000 22.911 2.856 + 10626.500 30.779 2.852 + 10627.000 36.276 2.843 + 10627.500 37.044 2.836 + 10628.000 34.350 2.829 + 10628.500 29.137 2.814 + 10629.000 27.198 2.808 + 10629.500 26.954 2.812 + 10630.000 25.553 2.820 + 10630.500 24.157 2.872 + 10631.000 23.182 2.866 + 10631.500 23.705 2.861 + 10632.000 24.529 2.853 + 10632.500 26.256 2.838 + 10633.000 27.316 2.830 + 10633.500 31.467 2.812 + 10634.000 37.710 2.805 + 10634.500 45.359 2.801 + 10635.000 48.432 2.787 + 10635.500 47.236 2.760 + 10636.000 43.456 2.735 + 10636.500 35.125 2.712 + 10637.000 30.177 2.708 + 10637.500 26.803 2.715 + 10638.000 25.636 2.721 + 10638.500 24.935 2.724 + 10639.000 24.569 2.726 + 10639.500 24.578 2.730 + 10640.000 27.583 2.732 + 10640.500 42.110 2.728 + 10641.000 49.058 2.729 + 10641.500 49.284 2.741 + 10642.000 42.748 2.770 + 10642.500 33.484 2.800 + 10643.000 28.471 2.807 + 10643.500 27.973 2.805 + 10644.000 27.771 2.784 + 10644.500 29.437 2.751 + 10645.000 28.698 2.738 + 10645.500 26.429 2.733 + 10646.000 24.625 2.731 + 10646.500 25.918 2.734 + 10647.000 27.781 2.738 + 10647.500 31.456 2.744 + 10648.000 32.554 2.749 + 10648.500 34.953 2.744 + 10649.000 35.463 2.744 + 10649.500 37.182 2.746 + 10650.000 37.205 2.742 + 10650.500 37.110 2.758 + 10651.000 32.849 2.775 + 10651.500 32.173 2.785 + 10652.000 30.168 2.783 + 10652.500 27.815 2.785 + 10653.000 26.268 2.789 + 10653.500 24.966 2.800 + 10654.000 24.369 2.805 + 10654.500 21.460 2.818 + 10655.000 19.533 2.832 + 10655.500 19.107 2.839 + 10656.000 19.920 2.832 + 10656.500 21.361 2.797 + 10657.000 20.555 2.800 + 10657.500 19.212 2.800 + 10658.000 15.998 2.818 + 10658.500 15.866 2.822 + 10659.000 16.681 2.819 + 10659.500 19.065 2.808 + 10660.000 20.913 2.806 + 10660.500 20.823 2.799 + 10661.000 19.755 2.798 + 10661.500 20.842 2.801 + 10662.000 22.538 2.804 + 10662.500 28.959 2.807 + 10663.000 31.464 2.814 + 10663.500 31.956 2.824 + 10664.000 33.268 2.829 + 10664.500 35.712 2.831 + 10665.000 38.162 2.810 + 10665.500 36.859 2.807 + 10666.000 34.271 2.807 + 10666.500 28.510 2.817 + 10667.000 26.198 2.814 + 10667.500 23.795 2.806 + 10668.000 21.513 2.806 + 10668.500 18.654 2.804 + 10669.000 19.628 2.803 + 10669.500 20.173 2.802 + 10670.000 21.044 2.809 + 10670.500 21.435 2.820 + 10671.000 21.127 2.825 + 10671.500 21.017 2.821 + 10672.000 21.605 2.813 + 10672.500 21.609 2.804 + 10673.000 21.050 2.800 + 10673.500 19.299 2.797 + 10674.000 17.381 2.801 + 10674.500 18.055 2.806 + 10675.000 18.730 2.812 + 10675.500 20.113 2.814 + 10676.000 19.988 2.814 + 10676.500 19.884 2.814 + 10677.000 20.120 2.816 + 10677.500 21.938 2.817 + 10678.000 25.023 2.822 + 10678.500 31.981 2.835 + 10679.000 39.183 2.838 + 10679.500 48.266 2.830 + 10680.000 50.287 2.821 + 10680.500 45.827 2.805 + 10681.000 38.654 2.795 + 10681.500 29.350 2.792 + 10682.000 21.024 2.790 + 10682.500 18.080 2.780 + 10683.000 16.042 2.782 + 10683.500 17.114 2.788 + 10684.000 18.400 2.808 + 10684.500 33.167 2.813 + 10685.000 41.188 2.808 + 10685.500 60.545 2.788 + 10686.000 64.004 2.777 + 10686.500 64.955 2.773 + 10687.000 59.057 2.777 + 10687.500 52.224 2.791 + 10688.000 30.866 2.812 + 10688.500 29.119 2.829 + 10689.000 27.533 2.826 + 10689.500 29.577 2.824 + 10690.000 32.531 2.825 + 10690.500 35.724 2.828 + 10691.000 37.586 2.825 + 10691.500 35.799 2.810 + 10692.000 34.529 2.809 + 10692.500 33.190 2.828 + 10693.000 33.462 2.842 + 10693.500 33.090 2.851 + 10694.000 32.386 2.846 + 10694.500 28.914 2.829 + 10695.000 26.837 2.823 + 10695.500 26.214 2.820 + 10696.000 26.518 2.831 + 10696.500 28.759 2.837 + 10697.000 29.455 2.849 + 10697.500 27.117 2.845 + 10698.000 25.445 2.822 + 10698.500 20.633 2.799 + 10699.000 18.929 2.798 + 10699.500 16.782 2.807 + 10700.000 16.308 2.815 + 10700.500 15.358 2.815 + 10701.000 15.840 2.800 + 10701.500 16.194 2.796 + 10702.000 18.707 2.795 + 10702.500 19.411 2.797 + 10703.000 22.481 2.807 + 10703.500 27.697 2.820 + 10704.000 38.174 2.837 + 10704.500 64.901 2.814 + 10705.000 85.587 2.778 + 10705.500 99.126 2.738 + 10706.000 97.183 2.731 + 10706.500 69.974 2.746 + 10707.000 54.200 2.759 + 10707.500 43.919 2.793 + 10708.000 30.353 2.810 + 10708.500 26.981 2.835 + 10709.000 24.100 2.835 + 10709.500 23.878 2.823 + 10710.000 24.834 2.823 + 10710.500 28.764 2.825 + 10711.000 32.429 2.829 + 10711.500 34.704 2.821 + 10712.000 35.667 2.811 + 10712.500 34.380 2.806 + 10713.000 35.974 2.810 + 10713.500 47.235 2.806 + 10714.000 55.946 2.797 + 10714.500 65.165 2.777 + 10715.000 61.508 2.760 + 10715.500 49.546 2.768 + 10716.000 41.114 2.779 + 10716.500 34.627 2.807 + 10717.000 31.990 2.817 + 10717.500 30.234 2.816 + 10718.000 29.496 2.808 + 10718.500 27.765 2.815 + 10719.000 26.227 2.824 + 10719.500 24.755 2.840 + 10720.000 24.770 2.842 + 10720.500 26.712 2.833 + 10721.000 28.489 2.803 + 10721.500 30.806 2.801 + 10722.000 32.299 2.800 + 10722.500 43.152 2.801 + 10723.000 52.442 2.797 + 10723.500 55.437 2.788 + 10724.000 53.902 2.789 + 10724.500 50.385 2.799 + 10725.000 48.819 2.803 + 10725.500 46.652 2.803 + 10726.000 44.264 2.802 + 10726.500 40.438 2.803 + 10727.000 38.141 2.805 + 10727.500 34.988 2.824 + 10728.000 33.206 2.839 + 10728.500 32.396 2.835 + 10729.000 31.158 2.810 + 10729.500 31.978 2.795 + 10730.000 32.756 2.802 + 10730.500 33.364 2.820 + 10731.000 33.620 2.820 + 10731.500 37.044 2.818 + 10732.000 41.143 2.811 + 10732.500 51.162 2.780 + 10733.000 49.544 2.747 + 10733.500 43.769 2.740 + 10734.000 41.900 2.741 + 10734.500 41.445 2.742 + 10735.000 44.083 2.723 + 10735.500 45.474 2.698 + 10736.000 47.531 2.694 + 10736.500 48.714 2.713 + 10737.000 47.642 2.743 + 10737.500 44.274 2.753 + 10738.000 39.763 2.771 + 10738.500 34.038 2.791 + 10739.000 34.010 2.795 + 10739.500 36.174 2.801 + 10740.000 41.232 2.803 + 10740.500 45.615 2.807 + 10741.000 43.802 2.811 + 10741.500 40.113 2.813 + 10742.000 39.743 2.816 + 10742.500 40.328 2.818 + 10743.000 40.669 2.820 + 10743.500 40.585 2.829 + 10744.000 35.288 2.837 + 10744.500 31.073 2.845 + 10745.000 26.362 2.840 + 10745.500 23.036 2.835 + 10746.000 21.183 2.834 + 10746.500 23.617 2.851 + 10747.000 25.426 2.859 + 10747.500 29.847 2.853 + 10748.000 34.060 2.837 + 10748.500 38.776 2.815 + 10749.000 39.811 2.808 + 10749.500 40.219 2.802 + 10750.000 38.421 2.803 + 10750.500 38.122 2.812 + 10751.000 33.147 2.816 + 10751.500 30.837 2.812 + 10752.000 25.058 2.813 + 10752.500 25.953 2.828 + 10753.000 29.116 2.834 + 10753.500 35.521 2.833 + 10754.000 40.503 2.826 + 10754.500 44.150 2.820 + 10755.000 43.996 2.818 + 10755.500 40.113 2.817 + 10756.000 35.401 2.815 + 10756.500 37.545 2.830 + 10757.000 40.912 2.837 + 10757.500 44.823 2.838 + 10758.000 49.485 2.829 + 10758.500 50.739 2.811 + 10759.000 47.714 2.807 + 10759.500 42.652 2.806 + 10760.000 41.504 2.803 + 10760.500 40.762 2.792 + 10761.000 44.514 2.781 + 10761.500 46.091 2.776 + 10762.000 46.849 2.776 + 10762.500 43.383 2.785 + 10763.000 38.838 2.791 + 10763.500 38.324 2.799 + 10764.000 35.277 2.803 + 10764.500 32.434 2.801 + 10765.000 30.198 2.801 + 10765.500 31.103 2.806 + 10766.000 35.353 2.808 + 10766.500 34.598 2.819 + 10767.000 34.013 2.821 + 10767.500 34.676 2.817 + 10768.000 36.147 2.818 + 10768.500 36.367 2.820 + 10769.000 34.929 2.817 + 10769.500 33.553 2.805 + 10770.000 34.311 2.799 + 10770.500 35.672 2.793 + 10771.000 35.412 2.785 + 10771.500 34.742 2.786 + 10772.000 34.539 2.796 + 10772.500 39.080 2.805 + 10773.000 43.474 2.815 + 10773.500 46.043 2.817 + 10774.000 48.232 2.815 + 10774.500 46.391 2.813 + 10775.000 44.117 2.810 + 10775.500 40.301 2.808 + 10776.000 39.005 2.805 + 10776.500 36.930 2.807 + 10777.000 38.917 2.813 + 10777.500 42.639 2.831 + 10778.000 45.118 2.835 + 10778.500 46.479 2.820 + 10779.000 45.667 2.808 + 10779.500 44.140 2.809 + 10780.000 42.557 2.805 + 10780.500 41.357 2.806 + 10781.000 43.224 2.812 + 10781.500 46.332 2.813 + 10782.000 47.946 2.814 + 10782.500 48.836 2.814 + 10783.000 52.116 2.806 + 10783.500 53.962 2.798 + 10784.000 54.228 2.781 + 10784.500 44.408 2.774 + 10785.000 34.529 2.765 + 10785.500 23.541 2.775 + 10786.000 21.111 2.785 + 10786.500 22.132 2.804 + 10787.000 25.624 2.818 + 10787.500 33.095 2.843 + 10788.000 37.805 2.854 + 10788.500 44.210 2.857 + 10789.000 44.888 2.845 + 10789.500 42.873 2.828 + 10790.000 40.763 2.812 + 10790.500 34.037 2.809 + 10791.000 28.308 2.812 + 10791.500 24.872 2.817 + 10792.000 23.268 2.818 + 10792.500 26.818 2.791 + 10793.000 31.314 2.776 + 10793.500 36.561 2.775 + 10794.000 37.410 2.782 + 10794.500 35.233 2.793 + 10795.000 30.352 2.810 + 10795.500 23.895 2.828 + 10796.000 20.190 2.834 + 10796.500 20.303 2.835 + 10797.000 21.468 2.832 + 10797.500 23.333 2.828 + 10798.000 24.942 2.826 + 10798.500 26.214 2.823 + 10799.000 31.105 2.820 + 10799.500 34.108 2.818 + 10800.000 34.003 2.815 + 10800.500 33.194 2.821 + 10801.000 32.977 2.831 + 10801.500 31.392 2.845 + 10802.000 26.906 2.850 + 10802.500 21.974 2.835 + 10803.000 20.100 2.819 + 10803.500 19.153 2.816 + 10804.000 19.235 2.824 + 10804.500 21.473 2.840 + 10805.000 24.998 2.854 + 10805.500 29.126 2.855 + 10806.000 31.757 2.853 + 10806.500 33.950 2.833 + 10807.000 34.490 2.823 + 10807.500 39.085 2.818 + 10808.000 42.783 2.819 + 10808.500 43.071 2.819 + 10809.000 40.599 2.816 + 10809.500 36.809 2.810 + 10810.000 39.396 2.808 + 10810.500 56.924 2.802 + 10811.000 61.571 2.787 + 10811.500 67.315 2.782 + 10812.000 63.837 2.785 + 10812.500 50.746 2.797 + 10813.000 50.200 2.798 + 10813.500 51.530 2.794 + 10814.000 53.538 2.793 + 10814.500 54.149 2.787 + 10815.000 51.166 2.782 + 10815.500 47.063 2.780 + 10816.000 39.873 2.782 + 10816.500 28.702 2.801 + 10817.000 22.219 2.811 + 10817.500 19.224 2.830 + 10818.000 19.890 2.844 + 10818.500 20.747 2.839 + 10819.000 23.739 2.825 + 10819.500 27.949 2.820 + 10820.000 27.925 2.820 + 10820.500 26.906 2.830 + 10821.000 24.466 2.836 + 10821.500 23.093 2.832 + 10822.000 25.106 2.824 + 10822.500 26.568 2.821 + 10823.000 29.291 2.826 + 10823.500 31.899 2.830 + 10824.000 29.138 2.830 + 10824.500 24.695 2.832 + 10825.000 24.759 2.832 + 10825.500 25.343 2.835 + 10826.000 28.150 2.838 + 10826.500 33.573 2.846 + 10827.000 36.439 2.847 + 10827.500 38.929 2.835 + 10828.000 38.846 2.827 + 10828.500 39.820 2.813 + 10829.000 41.373 2.813 + 10829.500 44.611 2.813 + 10830.000 45.994 2.809 + 10830.500 47.826 2.799 + 10831.000 54.722 2.789 + 10831.500 64.039 2.787 + 10832.000 88.743 2.779 + 10832.500 86.906 2.761 + 10833.000 84.755 2.767 + 10833.500 53.316 2.779 + 10834.000 40.605 2.804 + 10834.500 26.150 2.814 + 10835.000 23.764 2.821 + 10835.500 25.763 2.810 + 10836.000 31.918 2.813 + 10836.500 43.531 2.819 + 10837.000 50.890 2.818 + 10837.500 53.810 2.807 + 10838.000 52.405 2.804 + 10838.500 47.793 2.808 + 10839.000 40.157 2.820 + 10839.500 32.474 2.826 + 10840.000 27.848 2.825 + 10840.500 23.150 2.825 + 10841.000 28.651 2.822 + 10841.500 37.299 2.817 + 10842.000 48.836 2.802 + 10842.500 66.345 2.774 + 10843.000 71.231 2.759 + 10843.500 69.491 2.757 + 10844.000 64.848 2.764 + 10844.500 47.710 2.785 + 10845.000 40.553 2.800 + 10845.500 33.843 2.801 + 10846.000 31.169 2.799 + 10846.500 28.916 2.807 + 10847.000 28.079 2.812 + 10847.500 29.239 2.811 + 10848.000 29.555 2.800 + 10848.500 30.075 2.791 + 10849.000 29.619 2.783 + 10849.500 28.479 2.801 + 10850.000 28.769 2.807 + 10850.500 28.443 2.814 + 10851.000 29.877 2.814 + 10851.500 30.742 2.806 + 10852.000 31.529 2.806 + 10852.500 30.270 2.807 + 10853.000 28.127 2.810 + 10853.500 27.874 2.816 + 10854.000 30.196 2.819 + 10854.500 32.534 2.820 + 10855.000 32.336 2.823 + 10855.500 29.887 2.828 + 10856.000 25.831 2.841 + 10856.500 22.202 2.845 + 10857.000 20.908 2.837 + 10857.500 21.198 2.821 + 10858.000 22.338 2.813 + 10858.500 21.594 2.819 + 10859.000 23.089 2.827 + 10859.500 22.125 2.820 + 10860.000 24.006 2.811 + 10860.500 29.681 2.806 + 10861.000 32.709 2.808 + 10861.500 35.004 2.823 + 10862.000 35.215 2.827 + 10862.500 34.741 2.817 + 10863.000 39.242 2.809 + 10863.500 42.124 2.813 + 10864.000 50.592 2.821 + 10864.500 54.605 2.828 + 10865.000 53.819 2.832 + 10865.500 50.604 2.834 + 10866.000 45.217 2.828 + 10866.500 40.319 2.819 + 10867.000 37.837 2.814 + 10867.500 36.412 2.815 + 10868.000 36.466 2.812 + 10868.500 36.204 2.814 + 10869.000 34.091 2.817 + 10869.500 32.062 2.814 + 10870.000 31.021 2.814 + 10870.500 28.729 2.809 + 10871.000 27.996 2.808 + 10871.500 25.755 2.815 + 10872.000 23.114 2.821 + 10872.500 22.513 2.834 + 10873.000 21.860 2.833 + 10873.500 23.753 2.821 + 10874.000 27.069 2.808 + 10874.500 38.976 2.795 + 10875.000 50.992 2.799 + 10875.500 54.770 2.803 + 10876.000 52.767 2.819 + 10876.500 49.622 2.836 + 10877.000 45.932 2.829 + 10877.500 43.351 2.809 + 10878.000 39.833 2.798 + 10878.500 36.458 2.807 + 10879.000 32.967 2.821 + 10879.500 32.758 2.818 + 10880.000 30.946 2.816 + 10880.500 29.194 2.821 + 10881.000 27.912 2.841 + 10881.500 29.948 2.858 + 10882.000 33.617 2.863 + 10882.500 37.658 2.851 + 10883.000 40.031 2.838 + 10883.500 39.767 2.830 + 10884.000 37.382 2.825 + 10884.500 35.519 2.811 + 10885.000 34.951 2.805 + 10885.500 36.308 2.802 + 10886.000 36.526 2.800 + 10886.500 33.671 2.804 + 10887.000 30.727 2.804 + 10887.500 26.500 2.808 + 10888.000 27.201 2.811 + 10888.500 28.895 2.818 + 10889.000 39.086 2.817 + 10889.500 41.088 2.819 + 10890.000 53.082 2.815 + 10890.500 60.577 2.807 + 10891.000 63.352 2.788 + 10891.500 62.735 2.775 + 10892.000 54.185 2.774 + 10892.500 49.379 2.784 + 10893.000 42.063 2.802 + 10893.500 38.999 2.813 + 10894.000 38.642 2.820 + 10894.500 33.621 2.824 + 10895.000 34.978 2.822 + 10895.500 35.174 2.821 + 10896.000 38.650 2.822 + 10896.500 38.163 2.816 + 10897.000 33.570 2.811 + 10897.500 28.653 2.805 + 10898.000 27.096 2.806 + 10898.500 25.933 2.811 + 10899.000 28.375 2.821 + 10899.500 37.916 2.832 + 10900.000 58.565 2.833 + 10900.500 56.258 2.831 + 10901.000 55.942 2.825 + 10901.500 54.516 2.820 + 10902.000 42.304 2.818 + 10902.500 36.777 2.817 + 10903.000 27.159 2.816 + 10903.500 24.968 2.808 + 10904.000 20.861 2.801 + 10904.500 20.652 2.795 + 10905.000 21.415 2.797 + 10905.500 21.735 2.802 + 10906.000 22.625 2.824 + 10906.500 27.006 2.826 + 10907.000 29.895 2.827 + 10907.500 33.532 2.824 + 10908.000 35.031 2.828 + 10908.500 31.123 2.845 + 10909.000 27.130 2.851 + 10909.500 23.225 2.840 + 10910.000 23.220 2.832 + 10910.500 25.487 2.826 + 10911.000 26.410 2.824 + 10911.500 25.594 2.811 + 10912.000 23.050 2.802 + 10912.500 20.788 2.790 + 10913.000 20.802 2.818 + 10913.500 20.924 2.830 + 10914.000 21.680 2.847 + 10914.500 21.453 2.806 + 10915.000 22.233 2.799 + 10915.500 22.285 2.798 + 10916.000 21.395 2.803 + 10916.500 19.100 2.795 + 10917.000 17.615 2.785 + 10917.500 16.541 2.794 + 10918.000 16.140 2.808 + 10918.500 16.921 2.819 + 10919.000 18.622 2.820 + 10919.500 21.323 2.822 + 10920.000 26.908 2.823 + 10920.500 45.327 2.813 + 10921.000 59.361 2.806 + 10921.500 69.377 2.785 + 10922.000 73.777 2.777 + 10922.500 68.382 2.785 + 10923.000 63.302 2.797 + 10923.500 53.618 2.807 + 10924.000 46.907 2.808 + 10924.500 28.324 2.806 + 10925.000 25.265 2.805 + 10925.500 21.517 2.804 + 10926.000 20.801 2.815 + 10926.500 19.872 2.818 + 10927.000 20.015 2.815 + 10927.500 19.802 2.810 + 10928.000 21.337 2.808 + 10928.500 23.498 2.820 + 10929.000 25.796 2.828 + 10929.500 27.865 2.830 + 10930.000 31.100 2.826 + 10930.500 28.281 2.810 + 10931.000 24.684 2.801 + 10931.500 20.089 2.801 + 10932.000 18.762 2.801 + 10932.500 17.111 2.818 + 10933.000 16.163 2.827 + 10933.500 14.788 2.833 + 10934.000 15.064 2.832 + 10934.500 17.806 2.826 + 10935.000 18.401 2.823 + 10935.500 18.505 2.825 + 10936.000 18.394 2.827 + 10936.500 18.550 2.824 + 10937.000 19.328 2.823 + 10937.500 19.331 2.819 + 10938.000 19.991 2.817 + 10938.500 20.793 2.814 + 10939.000 21.634 2.818 + 10939.500 21.402 2.825 + 10940.000 20.841 2.830 + 10940.500 21.956 2.824 + 10941.000 23.934 2.818 + 10941.500 25.359 2.818 + 10942.000 26.921 2.824 + 10942.500 23.666 2.824 + 10943.000 19.961 2.819 + 10943.500 19.067 2.818 + 10944.000 21.110 2.816 + 10944.500 37.063 2.814 + 10945.000 44.841 2.813 + 10945.500 49.482 2.806 + 10946.000 48.400 2.802 + 10946.500 44.201 2.800 + 10947.000 38.508 2.804 + 10947.500 31.446 2.816 + 10948.000 27.756 2.817 + 10948.500 27.436 2.823 + 10949.000 27.510 2.823 + 10949.500 26.315 2.819 + 10950.000 20.945 2.804 + 10950.500 17.120 2.789 + 10951.000 19.209 2.787 + 10951.500 21.900 2.799 + 10952.000 27.578 2.813 + 10952.500 44.896 2.821 + 10953.000 56.074 2.809 + 10953.500 81.038 2.794 + 10954.000 78.384 2.772 + 10954.500 77.843 2.769 + 10955.000 63.118 2.778 + 10955.500 52.729 2.784 + 10956.000 48.554 2.793 + 10956.500 41.359 2.792 + 10957.000 40.341 2.782 + 10957.500 37.751 2.755 + 10958.000 36.295 2.742 + 10958.500 32.733 2.713 + 10959.000 30.824 2.712 + 10959.500 29.574 2.727 + 10960.000 31.137 2.727 + 10960.500 32.415 2.762 + 10961.000 29.980 2.756 + 10961.500 27.456 2.753 + 10962.000 25.468 2.753 + 10962.500 25.668 2.764 + 10963.000 37.239 2.775 + 10963.500 48.198 2.780 + 10964.000 53.850 2.782 + 10964.500 55.474 2.781 + 10965.000 54.843 2.779 + 10965.500 50.502 2.775 + 10966.000 49.178 2.772 + 10966.500 48.781 2.760 + 10967.000 42.751 2.757 + 10967.500 38.399 2.746 + 10968.000 35.750 2.746 + 10968.500 38.762 2.748 + 10969.000 39.921 2.752 + 10969.500 40.722 2.756 + 10970.000 27.239 2.759 + 10970.500 22.977 2.764 + 10971.000 25.098 2.765 + 10971.500 34.724 2.762 + 10972.000 43.425 2.766 + 10972.500 41.645 2.775 + 10973.000 31.656 2.804 + 10973.500 24.268 2.818 + 10974.000 23.633 2.819 + 10974.500 24.965 2.816 + 10975.000 26.127 2.818 + 10975.500 26.157 2.818 + 10976.000 26.781 2.811 + 10976.500 25.272 2.804 + 10977.000 23.099 2.801 + 10977.500 23.630 2.789 + 10978.000 24.516 2.783 + 10978.500 25.958 2.784 + 10979.000 34.728 2.798 + 10979.500 63.939 2.797 + 10980.000 77.911 2.774 + 10980.500 83.822 2.754 + 10981.000 82.909 2.755 + 10981.500 74.594 2.758 + 10982.000 62.894 2.778 + 10982.500 40.615 2.794 + 10983.000 35.186 2.819 + 10983.500 31.501 2.829 + 10984.000 33.824 2.839 + 10984.500 38.139 2.835 + 10985.000 40.276 2.815 + 10985.500 38.876 2.795 + 10986.000 32.086 2.785 + 10986.500 29.283 2.780 + 10987.000 24.111 2.781 + 10987.500 22.132 2.794 + 10988.000 22.136 2.807 + 10988.500 22.841 2.819 + 10989.000 27.835 2.816 + 10989.500 32.953 2.811 + 10990.000 38.529 2.808 + 10990.500 47.497 2.806 + 10991.000 53.604 2.804 + 10991.500 60.335 2.801 + 10992.000 61.564 2.799 + 10992.500 62.459 2.797 + 10993.000 62.858 2.789 + 10993.500 62.274 2.783 + 10994.000 61.640 2.778 + 10994.500 54.183 2.776 + 10995.000 45.255 2.783 + 10995.500 39.947 2.797 + 10996.000 40.497 2.814 + 10996.500 35.775 2.830 + 10997.000 37.819 2.831 + 10997.500 41.235 2.818 + 10998.000 47.081 2.803 + 10998.500 54.237 2.778 + 10999.000 61.441 2.775 + 10999.500 63.924 2.773 + 11000.000 55.543 2.784 + 11000.500 46.108 2.800 + 11001.000 31.187 2.808 + 11001.500 25.946 2.813 + 11002.000 24.573 2.813 + 11002.500 29.940 2.805 + 11003.000 31.507 2.808 + 11003.500 34.425 2.814 + 11004.000 37.705 2.816 + 11004.500 34.808 2.820 + 11005.000 30.756 2.824 + 11005.500 28.584 2.835 + 11006.000 27.999 2.845 + 11006.500 31.581 2.846 + 11007.000 36.348 2.834 + 11007.500 42.973 2.815 + 11008.000 41.194 2.802 + 11008.500 34.876 2.798 + 11009.000 27.455 2.793 + 11009.500 25.748 2.777 + 11010.000 25.365 2.771 + 11010.500 22.224 2.768 + 11011.000 19.042 2.769 + 11011.500 15.929 2.762 + 11012.000 15.604 2.755 + 11012.500 17.897 2.756 + 11013.000 29.401 2.765 + 11013.500 30.933 2.777 + 11014.000 38.191 2.784 + 11014.500 39.848 2.793 + 11015.000 42.374 2.794 + 11015.500 41.888 2.793 + 11016.000 42.251 2.795 + 11016.500 47.666 2.801 + 11017.000 54.712 2.801 + 11017.500 61.973 2.796 + 11018.000 63.657 2.789 + 11018.500 68.182 2.771 + 11019.000 72.885 2.757 + 11019.500 81.081 2.751 + 11020.000 84.624 2.755 + 11020.500 84.692 2.747 + 11021.000 81.614 2.731 + 11021.500 63.643 2.712 + 11022.000 49.591 2.707 + 11022.500 24.586 2.734 + 11023.000 20.716 2.755 + 11023.500 17.042 2.779 + 11024.000 14.201 2.800 + 11024.500 12.789 2.814 + 11025.000 13.546 2.814 + 11025.500 16.173 2.817 + 11026.000 20.096 2.820 + 11026.500 21.299 2.807 + 11027.000 31.750 2.800 + 11027.500 37.771 2.800 + 11028.000 42.924 2.801 + 11028.500 44.099 2.807 + 11029.000 44.635 2.769 + 11029.500 44.618 2.740 + 11030.000 43.933 2.728 + 11030.500 42.730 2.710 + 11031.000 41.675 2.698 + 11031.500 37.824 2.683 + 11032.000 34.914 2.683 + 11032.500 30.070 2.698 + 11033.000 28.859 2.736 + 11033.500 29.266 2.743 + 11034.000 32.409 2.738 + 11034.500 32.524 2.736 + 11035.000 31.880 2.735 + 11035.500 29.159 2.739 + 11036.000 25.853 2.741 + 11036.500 24.000 2.743 + 11037.000 23.974 2.743 + 11037.500 27.975 2.741 + 11038.000 44.289 2.735 + 11038.500 72.988 2.720 + 11039.000 101.183 2.710 + 11039.500 106.823 2.703 + 11040.000 113.676 2.709 + 11040.500 88.350 2.726 + 11041.000 72.251 2.758 + 11041.500 61.352 2.769 + 11042.000 50.748 2.782 + 11042.500 41.092 2.779 + 11043.000 41.399 2.778 + 11043.500 42.066 2.781 + 11044.000 44.383 2.787 + 11044.500 42.943 2.791 + 11045.000 40.175 2.784 + 11045.500 32.249 2.769 + 11046.000 26.746 2.748 + 11046.500 26.162 2.726 + 11047.000 27.024 2.720 + 11047.500 28.604 2.719 + 11048.000 30.133 2.723 + 11048.500 29.948 2.735 + 11049.000 29.979 2.749 + 11049.500 30.168 2.753 + 11050.000 29.348 2.745 + 11050.500 28.453 2.714 + 11051.000 27.472 2.712 + 11051.500 27.017 2.711 + 11052.000 26.590 2.723 + 11052.500 24.959 2.734 + 11053.000 24.627 2.739 + 11053.500 25.669 2.737 + 11054.000 28.375 2.732 + 11054.500 34.658 2.723 + 11055.000 41.207 2.716 + 11055.500 44.385 2.707 + 11056.000 44.891 2.703 + 11056.500 47.106 2.696 + 11057.000 48.111 2.695 + 11057.500 49.099 2.695 + 11058.000 49.712 2.700 + 11058.500 50.474 2.701 + 11059.000 50.943 2.698 + 11059.500 48.941 2.699 + 11060.000 45.066 2.705 + 11060.500 31.831 2.724 + 11061.000 28.949 2.731 + 11061.500 27.594 2.733 + 11062.000 28.443 2.727 + 11062.500 28.431 2.715 + 11063.000 27.912 2.706 + 11063.500 26.455 2.700 + 11064.000 26.373 2.707 + 11064.500 26.503 2.710 + 11065.000 31.843 2.737 + 11065.500 37.016 2.740 + 11066.000 40.366 2.741 + 11066.500 45.300 2.756 + 11067.000 46.376 2.771 + 11067.500 48.888 2.806 + 11068.000 49.809 2.819 + 11068.500 52.160 2.816 + 11069.000 52.609 2.811 + 11069.500 53.218 2.800 + 11070.000 54.347 2.796 + 11070.500 58.625 2.779 + 11071.000 66.966 2.768 + 11071.500 75.680 2.756 + 11072.000 85.260 2.744 + 11072.500 83.287 2.734 + 11073.000 74.361 2.741 + 11073.500 64.758 2.757 + 11074.000 43.518 2.793 + 11074.500 33.910 2.832 + 11075.000 32.329 2.839 + 11075.500 40.411 2.836 + 11076.000 47.425 2.826 + 11076.500 53.371 2.813 + 11077.000 58.462 2.801 + 11077.500 64.286 2.783 + 11078.000 70.035 2.773 + 11078.500 74.179 2.760 + 11079.000 74.942 2.758 + 11079.500 72.598 2.757 + 11080.000 68.174 2.760 + 11080.500 50.544 2.788 + 11081.000 39.643 2.799 + 11081.500 29.982 2.814 + 11082.000 24.857 2.820 + 11082.500 21.141 2.833 + 11083.000 34.874 2.831 + 11083.500 41.434 2.816 + 11084.000 57.857 2.794 + 11084.500 63.651 2.774 + 11085.000 61.191 2.773 + 11085.500 58.592 2.779 + 11086.000 57.684 2.785 + 11086.500 58.816 2.784 + 11087.000 59.880 2.783 + 11087.500 59.087 2.779 + 11088.000 55.983 2.774 + 11088.500 39.434 2.779 + 11089.000 37.445 2.785 + 11089.500 28.220 2.810 + 11090.000 23.555 2.853 + 11090.500 22.152 2.866 + 11091.000 21.242 2.868 + 11091.500 20.723 2.867 + 11092.000 18.353 2.865 + 11092.500 16.565 2.855 + 11093.000 15.982 2.848 + 11093.500 16.090 2.828 + 11094.000 16.055 2.826 + 11094.500 16.062 2.827 + 11095.000 15.978 2.853 + 11095.500 16.262 2.845 + 11096.000 16.219 2.836 + 11096.500 24.773 2.819 + 11097.000 28.223 2.819 + 11097.500 34.722 2.823 + 11098.000 36.414 2.826 + 11098.500 33.724 2.827 + 11099.000 30.420 2.832 + 11099.500 25.757 2.841 + 11100.000 26.784 2.836 + 11100.500 26.930 2.831 + 11101.000 27.173 2.825 + 11101.500 27.895 2.822 + 11102.000 27.125 2.825 + 11102.500 25.561 2.831 + 11103.000 25.671 2.832 + 11103.500 29.789 2.825 + 11104.000 31.587 2.818 + 11104.500 33.838 2.801 + 11105.000 32.370 2.795 + 11105.500 24.788 2.801 + 11106.000 16.451 2.812 + 11106.500 14.707 2.815 + 11107.000 14.055 2.817 + 11107.500 18.184 2.820 + 11108.000 20.846 2.820 + 11108.500 26.880 2.823 + 11109.000 39.550 2.814 + 11109.500 54.121 2.798 + 11110.000 69.380 2.783 + 11110.500 75.508 2.771 + 11111.000 64.070 2.782 + 11111.500 49.155 2.808 + 11112.000 36.333 2.839 + 11112.500 20.894 2.840 + 11113.000 15.593 2.840 + 11113.500 13.785 2.828 + 11114.000 14.089 2.826 + 11114.500 15.252 2.817 + 11115.000 21.295 2.818 + 11115.500 32.915 2.803 + 11116.000 57.121 2.786 + 11116.500 81.135 2.747 + 11117.000 88.055 2.744 + 11117.500 83.311 2.754 + 11118.000 75.381 2.776 + 11118.500 62.571 2.784 + 11119.000 54.048 2.788 + 11119.500 42.779 2.790 + 11120.000 34.736 2.799 + 11120.500 21.896 2.809 + 11121.000 21.155 2.813 + 11121.500 18.541 2.813 + 11122.000 15.923 2.813 + 11122.500 13.230 2.833 + 11123.000 12.265 2.834 + 11123.500 11.956 2.828 + 11124.000 11.287 2.823 + 11124.500 11.316 2.822 + 11125.000 12.083 2.832 + 11125.500 13.573 2.836 + 11126.000 14.703 2.836 + 11126.500 16.734 2.839 + 11127.000 17.605 2.842 + 11127.500 17.674 2.845 + 11128.000 17.966 2.844 + 11128.500 20.259 2.838 + 11129.000 26.158 2.831 + 11129.500 31.832 2.803 + 11130.000 38.667 2.788 + 11130.500 43.581 2.767 + 11131.000 41.621 2.777 + 11131.500 38.724 2.815 + 11132.000 26.522 2.841 + 11132.500 23.709 2.869 + 11133.000 24.543 2.864 + 11133.500 27.384 2.854 + 11134.000 29.996 2.846 + 11134.500 28.702 2.835 + 11135.000 25.420 2.831 + 11135.500 20.350 2.834 + 11136.000 17.016 2.852 + 11136.500 13.095 2.873 + 11137.000 12.297 2.889 + 11137.500 12.146 2.903 + 11138.000 12.128 2.910 + 11138.500 12.141 2.905 + 11139.000 12.126 2.880 + 11139.500 12.336 2.849 + 11140.000 13.080 2.838 + 11140.500 14.410 2.833 + 11141.000 14.503 2.833 + 11141.500 14.497 2.840 + 11142.000 14.428 2.849 + 11142.500 12.413 2.849 + 11143.000 10.002 2.848 + 11143.500 10.821 2.844 + 11144.000 13.234 2.838 + 11144.500 16.532 2.829 + 11145.000 19.702 2.818 + 11145.500 21.639 2.818 + 11146.000 20.143 2.822 + 11146.500 18.468 2.832 + 11147.000 16.856 2.835 + 11147.500 14.724 2.836 + 11148.000 13.090 2.838 + 11148.500 14.197 2.847 + 11149.000 14.750 2.856 + 11149.500 19.141 2.855 + 11150.000 23.142 2.848 + 11150.500 24.820 2.841 + 11151.000 25.100 2.837 + 11151.500 24.956 2.830 + 11152.000 28.236 2.819 + 11152.500 33.620 2.809 + 11153.000 40.405 2.804 + 11153.500 43.607 2.804 + 11154.000 43.710 2.802 + 11154.500 47.531 2.800 + 11155.000 48.838 2.794 + 11155.500 46.565 2.786 + 11156.000 41.055 2.785 + 11156.500 32.222 2.795 + 11157.000 26.087 2.806 + 11157.500 20.885 2.821 + 11158.000 17.781 2.828 + 11158.500 16.006 2.834 + 11159.000 16.763 2.830 + 11159.500 19.041 2.821 + 11160.000 22.364 2.818 + 11160.500 25.131 2.811 + 11161.000 27.674 2.806 + 11161.500 29.358 2.809 + 11162.000 29.536 2.815 + 11162.500 28.453 2.831 + 11163.000 26.165 2.830 + 11163.500 21.619 2.823 + 11164.000 17.780 2.812 + 11164.500 13.310 2.810 + 11165.000 13.140 2.817 + 11165.500 13.714 2.833 + 11166.000 14.529 2.835 + 11166.500 14.434 2.832 + 11167.000 15.039 2.825 + 11167.500 15.932 2.821 + 11168.000 16.320 2.820 + 11168.500 17.181 2.820 + 11169.000 19.443 2.825 + 11169.500 20.226 2.829 + 11170.000 26.664 2.825 + 11170.500 38.378 2.814 + 11171.000 41.418 2.803 + 11171.500 48.625 2.801 + 11172.000 56.557 2.792 + 11172.500 57.583 2.779 + 11173.000 46.894 2.780 + 11173.500 37.112 2.800 + 11174.000 25.325 2.830 + 11174.500 20.385 2.893 + 11175.000 18.272 2.899 + 11175.500 18.264 2.880 + 11176.000 20.138 2.866 + 11176.500 26.865 2.832 + 11177.000 32.322 2.814 + 11177.500 41.375 2.802 + 11178.000 49.440 2.776 + 11178.500 46.761 2.760 + 11179.000 43.430 2.775 + 11179.500 39.059 2.786 + 11180.000 31.165 2.824 + 11180.500 21.041 2.832 + 11181.000 20.143 2.832 + 11181.500 13.373 2.828 + 11182.000 13.202 2.829 + 11182.500 11.394 2.833 + 11183.000 11.276 2.830 + 11183.500 12.035 2.830 + 11184.000 14.323 2.834 + 11184.500 15.972 2.834 + 11185.000 16.069 2.825 + 11185.500 15.391 2.822 + 11186.000 13.615 2.825 + 11186.500 12.609 2.849 + 11187.000 14.160 2.865 + 11187.500 15.746 2.874 + 11188.000 27.168 2.861 + 11188.500 33.619 2.823 + 11189.000 57.618 2.789 + 11189.500 55.502 2.766 + 11190.000 49.834 2.771 + 11190.500 40.872 2.802 + 11191.000 34.324 2.838 + 11191.500 31.299 2.842 + 11192.000 29.664 2.835 + 11192.500 26.237 2.820 + 11193.000 23.675 2.818 + 11193.500 21.462 2.824 + 11194.000 19.945 2.829 + 11194.500 21.430 2.841 + 11195.000 25.316 2.841 + 11195.500 34.934 2.831 + 11196.000 52.625 2.823 + 11196.500 74.780 2.798 + 11197.000 73.172 2.783 + 11197.500 59.638 2.765 + 11198.000 46.710 2.770 + 11198.500 25.872 2.791 + 11199.000 22.189 2.792 + 11199.500 19.060 2.794 + 11200.000 15.959 2.800 + 11200.500 13.599 2.816 + 11201.000 13.061 2.835 + 11201.500 12.686 2.835 + 11202.000 12.608 2.836 + 11202.500 15.072 2.816 + 11203.000 19.136 2.813 + 11203.500 23.779 2.815 + 11204.000 32.956 2.832 + 11204.500 42.992 2.837 + 11205.000 41.045 2.826 + 11205.500 39.335 2.822 + 11206.000 29.569 2.812 + 11206.500 18.014 2.817 + 11207.000 14.406 2.821 + 11207.500 13.533 2.822 + 11208.000 13.677 2.818 + 11208.500 14.913 2.822 + 11209.000 15.968 2.826 + 11209.500 18.909 2.831 + 11210.000 22.385 2.830 + 11210.500 23.756 2.836 + 11211.000 24.628 2.841 + 11211.500 20.891 2.845 + 11212.000 18.240 2.839 + 11212.500 14.475 2.813 + 11213.000 15.474 2.802 + 11213.500 18.001 2.782 + 11214.000 23.422 2.791 + 11214.500 32.586 2.794 + 11215.000 34.179 2.799 + 11215.500 30.593 2.791 + 11216.000 26.830 2.779 + 11216.500 15.798 2.770 + 11217.000 12.886 2.759 + 11217.500 11.618 2.762 + 11218.000 13.013 2.771 + 11218.500 14.355 2.776 + 11219.000 15.814 2.787 + 11219.500 16.891 2.780 + 11220.000 18.444 2.771 + 11220.500 24.137 2.754 + 11221.000 25.553 2.750 + 11221.500 28.605 2.756 + 11222.000 29.623 2.770 + 11222.500 33.951 2.801 + 11223.000 34.933 2.801 + 11223.500 37.086 2.794 + 11224.000 36.874 2.800 + 11224.500 34.276 2.805 + 11225.000 31.777 2.810 + 11225.500 27.223 2.816 + 11226.000 23.123 2.822 + 11226.500 19.492 2.848 + 11227.000 15.230 2.887 + 11227.500 13.836 2.920 + 11228.000 13.470 2.927 + 11228.500 14.143 2.916 + 11229.000 15.972 2.894 + 11229.500 16.824 2.892 + 11230.000 17.724 2.883 + 11230.500 17.876 2.905 + 11231.000 20.237 2.916 + 11231.500 22.396 2.878 + 11232.000 24.720 2.871 + 11232.500 23.301 2.826 + 11233.000 21.315 2.818 + 11233.500 16.485 2.819 + 11234.000 15.260 2.825 + 11234.500 13.062 2.834 + 11235.000 13.075 2.834 + 11235.500 14.500 2.834 + 11236.000 16.218 2.834 + 11236.500 19.849 2.834 + 11237.000 22.451 2.843 + 11237.500 27.676 2.855 + 11238.000 33.269 2.855 + 11238.500 38.353 2.846 + 11239.000 37.705 2.817 + 11239.500 36.726 2.817 + 11240.000 36.330 2.827 + 11240.500 42.528 2.830 + 11241.000 42.551 2.839 + 11241.500 43.612 2.837 + 11242.000 43.734 2.838 + 11242.500 44.173 2.827 + 11243.000 57.476 2.796 + 11243.500 71.348 2.766 + 11244.000 83.178 2.736 + 11244.500 72.110 2.741 + 11245.000 62.858 2.763 + 11245.500 52.351 2.778 + 11246.000 49.951 2.805 + 11246.500 39.065 2.816 + 11247.000 33.729 2.833 + 11247.500 22.666 2.853 + 11248.000 18.234 2.883 + 11248.500 18.569 2.887 + 11249.000 21.604 2.874 + 11249.500 24.567 2.865 + 11250.000 28.025 2.862 + 11250.500 35.866 2.858 + 11251.000 39.917 2.852 + 11251.500 39.959 2.848 + 11252.000 38.973 2.838 + 11252.500 25.367 2.858 + 11253.000 21.541 2.870 + 11253.500 18.207 2.880 + 11254.000 15.061 2.843 + 11254.500 11.556 2.826 + 11255.000 10.530 2.826 + 11255.500 12.381 2.837 + 11256.000 13.802 2.844 + 11256.500 14.345 2.854 + 11257.000 16.119 2.867 + 11257.500 15.354 2.864 + 11258.000 15.354 2.862 + 11258.500 13.113 2.833 + 11259.000 12.862 2.827 + 11259.500 12.025 2.841 + 11260.000 12.202 2.867 + 11260.500 12.154 2.861 + 11261.000 12.140 2.852 + 11261.500 12.156 2.844 + 11262.000 12.152 2.835 + 11262.500 12.155 2.894 + 11263.000 12.126 2.912 + 11263.500 12.167 2.919 + 11264.000 12.182 2.903 + 11264.500 13.665 2.847 + 11265.000 14.003 2.844 + 11265.500 15.318 2.826 + 11266.000 16.404 2.924 + 11266.500 20.718 2.915 + 11267.000 26.657 2.900 + 11267.500 38.264 2.897 + 11268.000 49.241 2.786 + 11268.500 56.003 2.799 + 11269.000 51.175 2.801 + 11269.500 41.766 2.813 + 11270.000 33.179 2.805 + 11270.500 25.207 2.833 + 11271.000 19.939 2.825 + 11271.500 20.028 2.825 + 11272.000 17.569 2.819 + 11272.500 15.406 2.820 + 11273.000 14.385 2.825 + 11273.500 14.233 2.833 + 11274.000 14.932 2.850 + 11274.500 17.448 2.847 + 11275.000 19.286 2.837 + 11275.500 20.653 2.817 + 11276.000 20.635 2.813 + 11276.500 19.937 2.815 + 11277.000 20.029 2.820 + 11277.500 19.942 2.822 + 11278.000 20.745 2.822 + 11278.500 21.785 2.822 + 11279.000 22.766 2.823 + 11279.500 24.593 2.823 + 11280.000 27.137 2.821 + 11280.500 26.566 2.822 + 11281.000 25.407 2.820 + 11281.500 21.748 2.823 + 11282.000 20.724 2.822 + 11282.500 20.599 2.826 + 11283.000 20.875 2.828 + 11283.500 22.200 2.832 + 11284.000 23.088 2.839 + 11284.500 21.798 2.840 + 11285.000 19.854 2.833 + 11285.500 17.485 2.830 + 11286.000 16.303 2.826 + 11286.500 15.522 2.826 + 11287.000 16.312 2.816 + 11287.500 17.249 2.814 + 11288.000 20.162 2.816 + 11288.500 21.585 2.819 + 11289.000 24.235 2.825 + 11289.500 25.916 2.830 + 11290.000 27.195 2.837 + 11290.500 26.985 2.842 + 11291.000 27.768 2.832 + 11291.500 30.119 2.823 + 11292.000 32.746 2.805 + 11292.500 28.867 2.806 + 11293.000 25.495 2.813 + 11293.500 20.938 2.819 + 11294.000 19.479 2.810 + 11294.500 17.129 2.805 + 11295.000 16.160 2.804 + 11295.500 16.625 2.808 + 11296.000 18.211 2.816 + 11296.500 21.175 2.837 + 11297.000 23.417 2.849 + 11297.500 27.670 2.856 + 11298.000 27.065 2.848 + 11298.500 23.149 2.842 + 11299.000 19.962 2.836 + 11299.500 15.412 2.854 + 11300.000 14.011 2.876 + 11300.500 11.517 2.912 + 11301.000 9.815 2.906 + 11301.500 9.906 2.908 + 11302.000 9.244 2.899 + 11302.500 10.404 2.889 + 11303.000 11.755 2.883 + 11303.500 15.220 2.880 + 11304.000 18.724 2.880 + 11304.500 18.697 2.886 + 11305.000 17.156 2.890 + 11305.500 14.695 2.899 + 11306.000 13.109 2.906 + 11306.500 12.033 2.909 + 11307.000 12.214 2.904 + 11307.500 12.419 2.882 + 11308.000 14.086 2.873 + 11308.500 15.799 2.853 + 11309.000 16.085 2.858 + 11309.500 16.044 2.867 + 11310.000 14.470 2.888 + 11310.500 13.202 2.903 + 11311.000 11.394 2.901 + 11311.500 9.525 2.891 + 11312.000 8.279 2.886 + 11312.500 6.963 2.891 + 11313.000 6.540 2.902 + 11313.500 5.735 2.910 + 11314.000 5.855 2.914 + 11314.500 6.567 2.924 + 11315.000 7.102 2.922 + 11315.500 8.156 2.914 + 11316.000 8.430 2.896 + 11316.500 10.638 2.881 + 11317.000 12.858 2.861 + 11317.500 15.398 2.859 + 11318.000 17.015 2.867 + 11318.500 19.273 2.862 + 11319.000 20.754 2.859 + 11319.500 21.804 2.858 + 11320.000 22.353 2.857 + 11320.500 20.696 2.846 + 11321.000 20.052 2.834 + 11321.500 18.656 2.831 + 11322.000 16.842 2.837 + 11322.500 15.973 2.839 + 11323.000 14.273 2.822 + 11323.500 12.662 2.809 + 11324.000 11.515 2.818 + 11324.500 11.372 2.842 + 11325.000 11.625 2.861 + 11325.500 12.865 2.863 + 11326.000 12.839 2.855 + 11326.500 13.594 2.846 + 11327.000 13.116 2.828 + 11327.500 13.302 2.812 + 11328.000 14.461 2.801 + 11328.500 17.993 2.801 + 11329.000 21.325 2.810 + 11329.500 24.430 2.814 + 11330.000 25.211 2.810 + 11330.500 17.618 2.798 + 11331.000 14.257 2.790 + 11331.500 11.397 2.798 + 11332.000 11.365 2.802 + 11332.500 12.897 2.810 + 11333.000 14.954 2.803 + 11333.500 18.624 2.796 + 11334.000 20.184 2.663 + 11334.500 18.165 2.559 + 11335.000 14.880 2.544 + 11335.500 12.120 2.598 + 11336.000 9.663 2.732 + 11336.500 9.082 2.809 + 11337.000 10.028 2.849 + 11337.500 10.853 2.861 + 11338.000 11.189 2.860 + 11338.500 13.188 2.857 + 11339.000 14.416 2.850 + 11339.500 16.258 2.833 + 11340.000 16.727 2.808 + 11340.500 17.403 2.805 + 11341.000 18.851 2.807 + 11341.500 18.715 2.820 + 11342.000 19.659 2.834 + 11342.500 20.011 2.845 + 11343.000 20.200 2.852 + 11343.500 20.574 2.848 + 11344.000 20.527 2.849 + 11344.500 18.818 2.850 + 11345.000 15.443 2.857 + 11345.500 14.952 2.866 + 11346.000 14.077 2.897 + 11346.500 12.637 2.909 + 11347.000 13.423 2.901 + 11347.500 13.812 2.881 + 11348.000 14.529 2.865 + 11348.500 13.597 2.859 + 11349.000 13.410 2.857 + 11349.500 11.979 2.859 + 11350.000 11.673 2.857 + 11350.500 13.748 2.854 + 11351.000 15.945 2.849 + 11351.500 16.965 2.832 + 11352.000 16.773 2.790 + 11352.500 16.994 2.769 + 11353.000 13.377 2.773 + 11353.500 11.357 2.797 + 11354.000 10.349 2.826 + 11354.500 11.434 2.853 + 11355.000 12.317 2.834 + 11355.500 14.098 2.827 + 11356.000 16.733 2.819 + 11356.500 20.348 2.832 + 11357.000 22.291 2.836 + 11357.500 21.059 2.822 + 11358.000 20.135 2.810 + 11358.500 16.294 2.808 + 11359.000 14.499 2.809 + 11359.500 13.815 2.833 + 11360.000 14.217 2.848 + 11360.500 14.284 2.850 + 11361.000 14.555 2.850 + 11361.500 14.134 2.844 + 11362.000 15.946 2.843 + 11362.500 17.920 2.837 + 11363.000 20.753 2.828 + 11363.500 21.743 2.817 + 11364.000 22.478 2.799 + 11364.500 22.343 2.798 + 11365.000 21.773 2.807 + 11365.500 21.233 2.819 + 11366.000 20.830 2.824 + 11366.500 19.450 2.827 + 11367.000 17.345 2.828 + 11367.500 16.072 2.832 + 11368.000 15.263 2.834 + 11368.500 15.317 2.830 + 11369.000 17.267 2.822 + 11369.500 19.362 2.817 + 11370.000 21.300 2.818 + 11370.500 21.812 2.816 + 11371.000 21.088 2.815 + 11371.500 17.064 2.821 + 11372.000 15.016 2.824 + 11372.500 14.497 2.831 + 11373.000 13.907 2.831 + 11373.500 13.717 2.828 + 11374.000 13.850 2.826 + 11374.500 14.552 2.822 + 11375.000 14.489 2.817 + 11375.500 13.009 2.804 + 11376.000 12.883 2.784 + 11376.500 12.093 2.780 + 11377.000 13.670 2.788 + 11377.500 14.392 2.794 + 11378.000 15.981 2.797 + 11378.500 16.716 2.794 + 11379.000 16.623 2.797 + 11379.500 16.777 2.793 + 11380.000 16.037 2.790 + 11380.500 15.180 2.792 + 11381.000 13.938 2.802 + 11381.500 14.127 2.813 + 11382.000 13.118 2.817 + 11382.500 13.795 2.814 + 11383.000 13.124 2.808 + 11383.500 13.748 2.806 + 11384.000 14.337 2.811 + 11384.500 14.478 2.814 + 11385.000 14.600 2.816 + 11385.500 13.903 2.820 + 11386.000 13.134 2.825 + 11386.500 12.388 2.827 + 11387.000 11.964 2.826 + 11387.500 11.467 2.825 + 11388.000 12.308 2.823 + 11388.500 13.528 2.818 + 11389.000 14.245 2.814 + 11389.500 15.192 2.811 + 11390.000 15.345 2.814 + 11390.500 17.225 2.821 + 11391.000 18.598 2.827 + 11391.500 19.506 2.823 + 11392.000 18.931 2.814 + 11392.500 19.714 2.806 + 11393.000 15.085 2.815 + 11393.500 14.091 2.824 + 11394.000 12.818 2.832 + 11394.500 12.905 2.820 + 11395.000 12.957 2.803 + 11395.500 13.570 2.805 + 11396.000 15.291 2.807 + 11396.500 15.255 2.815 + 11397.000 14.872 2.816 + 11397.500 12.689 2.814 + 11398.000 13.047 2.809 + 11398.500 12.962 2.796 + 11399.000 14.679 2.790 + 11399.500 14.778 2.794 + 11400.000 16.530 2.797 + 11400.500 16.049 2.819 + 11401.000 14.420 2.821 + 11401.500 13.591 2.822 + 11402.000 14.355 2.827 + 11402.500 15.019 2.833 + 11403.000 15.973 2.835 + 11403.500 16.237 2.828 + 11404.000 16.845 2.824 + 11404.500 17.696 2.823 + 11405.000 18.501 2.822 + 11405.500 19.860 2.821 + 11406.000 19.263 2.817 + 11406.500 19.110 2.816 + 11407.000 16.041 2.821 + 11407.500 15.530 2.827 + 11408.000 15.738 2.831 + 11408.500 19.674 2.839 + 11409.000 20.353 2.844 + 11409.500 20.490 2.848 + 11410.000 19.143 2.848 + 11410.500 19.377 2.839 + 11411.000 16.428 2.829 + 11411.500 16.708 2.815 + 11412.000 16.388 2.809 + 11412.500 16.107 2.806 + 11413.000 15.964 2.806 + 11413.500 15.224 2.803 + 11414.000 15.096 2.792 + 11414.500 15.035 2.787 + 11415.000 15.384 2.792 + 11415.500 15.231 2.801 + 11416.000 15.735 2.804 + 11416.500 17.822 2.805 + 11417.000 18.535 2.798 + 11417.500 19.077 2.790 + 11418.000 14.948 2.784 + 11418.500 14.023 2.787 + 11419.000 13.601 2.800 + 11419.500 13.765 2.813 + 11420.000 13.732 2.814 + 11420.500 13.564 2.818 + 11421.000 12.852 2.820 + 11421.500 12.968 2.825 + 11422.000 12.930 2.826 + 11422.500 12.900 2.820 + 11423.000 13.004 2.818 + 11423.500 12.925 2.808 + 11424.000 14.530 2.803 + 11424.500 14.118 2.799 + 11425.000 15.670 2.800 + 11425.500 18.495 2.804 + 11426.000 20.541 2.808 + 11426.500 22.209 2.816 + 11427.000 21.656 2.812 + 11427.500 21.423 2.798 + 11428.000 19.096 2.785 + 11428.500 17.498 2.792 + 11429.000 15.778 2.805 + 11429.500 15.263 2.813 + 11430.000 15.311 2.824 + 11430.500 17.198 2.822 + 11431.000 18.892 2.812 + 11431.500 19.235 2.807 + 11432.000 19.228 2.806 + 11432.500 19.200 2.806 + 11433.000 19.003 2.806 + 11433.500 16.774 2.805 + 11434.000 17.842 2.804 + 11434.500 19.371 2.793 + 11435.000 19.144 2.785 + 11435.500 19.632 2.777 + 11436.000 19.543 2.780 + 11436.500 19.959 2.791 + 11437.000 20.939 2.802 + 11437.500 20.628 2.815 + 11438.000 21.607 2.813 + 11438.500 22.811 2.807 + 11439.000 25.600 2.803 + 11439.500 25.229 2.802 + 11440.000 24.565 2.802 + 11440.500 22.098 2.804 + 11441.000 19.718 2.800 + 11441.500 16.888 2.801 + 11442.000 16.696 2.802 + 11442.500 17.089 2.822 + 11443.000 19.427 2.833 + 11443.500 19.718 2.814 + 11444.000 20.610 2.737 + 11444.500 20.714 2.657 + 11445.000 19.735 2.672 + 11445.500 19.046 2.711 + 11446.000 18.469 2.734 + 11446.500 19.904 2.719 + 11447.000 20.299 2.697 + 11447.500 19.819 2.678 + 11448.000 18.976 2.670 + 11448.500 18.400 2.683 + 11449.000 18.589 2.726 + 11449.500 19.972 2.759 + 11450.000 20.755 2.749 + 11450.500 23.228 2.718 + 11451.000 24.710 2.619 + 11451.500 26.154 2.566 + 11452.000 26.231 2.535 + 11452.500 24.213 2.605 + 11453.000 21.092 2.692 + 11453.500 19.269 2.807 + 11454.000 16.790 2.794 + 11454.500 15.150 2.790 + 11455.000 15.217 2.787 + 11455.500 16.344 2.788 + 11456.000 18.932 2.805 + 11456.500 20.414 2.813 + 11457.000 21.738 2.820 + 11457.500 23.143 2.818 + 11458.000 24.125 2.805 + 11458.500 22.611 2.791 + 11459.000 20.693 2.787 + 11459.500 19.295 2.793 + 11460.000 18.078 2.806 + 11460.500 20.914 2.805 + 11461.000 20.757 2.804 + 11461.500 19.935 2.794 + 11462.000 17.391 2.781 + 11462.500 13.161 2.782 + 11463.000 10.550 2.786 + 11463.500 9.076 2.789 + 11464.000 9.087 2.792 + 11464.500 8.367 2.790 + 11465.000 8.383 2.782 + 11465.500 8.996 2.758 + 11466.000 9.804 2.747 + 11466.500 10.597 2.740 + 11467.000 10.575 2.742 + 11467.500 8.990 2.748 + 11468.000 9.478 2.740 + 11468.500 9.536 2.717 + 11469.000 9.823 2.700 + 11469.500 9.830 2.686 + 11470.000 10.476 2.682 + 11470.500 13.783 2.695 + 11471.000 15.759 2.711 + 11471.500 20.387 2.719 + 11472.000 21.265 2.725 + 11472.500 22.781 2.750 + 11473.000 21.405 2.760 + 11473.500 19.267 2.797 + 11474.000 18.683 2.810 + 11474.500 18.232 2.825 + 11475.000 20.185 2.820 + 11475.500 22.955 2.814 + 11476.000 29.960 2.825 + 11476.500 33.274 2.832 + 11477.000 33.357 2.821 + 11477.500 31.371 2.796 + 11478.000 28.548 2.737 + 11478.500 27.496 2.725 + 11479.000 28.434 2.733 + 11479.500 29.408 2.751 + 11480.000 28.060 2.783 + 11480.500 23.799 2.791 + 11481.000 19.936 2.790 + 11481.500 19.163 2.783 + 11482.000 19.404 2.782 + 11482.500 19.603 2.782 + 11483.000 20.189 2.783 + 11483.500 20.798 2.786 + 11484.000 20.841 2.806 + 11484.500 20.028 2.809 + 11485.000 19.082 2.820 + 11485.500 19.184 2.812 + 11486.000 17.726 2.793 + 11486.500 17.465 2.756 + 11487.000 17.470 2.748 + 11487.500 19.087 2.752 + 11488.000 20.404 2.771 + 11488.500 21.771 2.785 + 11489.000 22.496 2.786 + 11489.500 19.866 2.782 + 11490.000 19.774 2.779 + 11490.500 17.119 2.778 + 11491.000 17.892 2.779 + 11491.500 17.508 2.767 + 11492.000 17.417 2.747 + 11492.500 15.546 2.738 + 11493.000 14.542 2.742 + 11493.500 13.082 2.763 + 11494.000 12.421 2.777 + 11494.500 13.104 2.795 + 11495.000 15.155 2.801 + 11495.500 18.781 2.817 + 11496.000 23.048 2.833 + 11496.500 25.732 2.835 + 11497.000 25.465 2.819 + 11497.500 25.446 2.801 + 11498.000 25.680 2.799 + 11498.500 26.381 2.795 + 11499.000 26.038 2.792 + 11499.500 25.966 2.793 + 11500.000 27.472 2.795 + 11500.500 30.048 2.797 + 11501.000 32.373 2.799 + 11501.500 33.819 2.801 + 11502.000 33.975 2.804 + 11502.500 33.210 2.797 + 11503.000 31.050 2.787 + 11503.500 30.601 2.783 + 11504.000 29.622 2.785 + 11504.500 36.495 2.801 + 11505.000 39.894 2.805 + 11505.500 43.182 2.802 + 11506.000 42.106 2.796 + 11506.500 40.540 2.798 + 11507.000 39.625 2.803 + 11507.500 37.372 2.807 + 11508.000 33.670 2.809 + 11508.500 30.932 2.807 + 11509.000 29.432 2.801 + 11509.500 29.544 2.792 + 11510.000 29.176 2.788 + 11510.500 30.695 2.791 + 11511.000 30.423 2.798 + 11511.500 27.144 2.808 + 11512.000 24.464 2.808 + 11512.500 21.847 2.817 + 11513.000 22.197 2.822 + 11513.500 26.985 2.830 + 11514.000 32.522 2.830 + 11514.500 43.008 2.814 + 11515.000 48.656 2.804 + 11515.500 52.241 2.799 + 11516.000 53.772 2.798 + 11516.500 54.307 2.787 + 11517.000 54.025 2.772 + 11517.500 53.065 2.758 + 11518.000 51.351 2.759 + 11518.500 49.912 2.756 + 11519.000 49.280 2.758 + 11519.500 47.276 2.751 + 11520.000 45.824 2.748 + 11520.500 40.919 2.754 + 11521.000 40.620 2.762 + 11521.500 38.673 2.769 + 11522.000 35.649 2.770 + 11522.500 32.677 2.759 + 11523.000 31.037 2.752 + 11523.500 31.185 2.746 + 11524.000 31.783 2.740 + 11524.500 32.146 2.739 + 11525.000 31.755 2.745 + 11525.500 28.857 2.752 + 11526.000 26.158 2.750 + 11526.500 20.156 2.751 + 11527.000 17.540 2.753 + 11527.500 14.640 2.762 + 11528.000 14.649 2.793 + 11528.500 15.868 2.858 + 11529.000 19.560 2.867 + 11529.500 24.357 2.873 + 11530.000 27.350 2.848 + 11530.500 28.350 2.822 + 11531.000 27.583 2.810 + 11531.500 26.284 2.804 + 11532.000 26.489 2.800 + 11532.500 21.671 2.811 + 11533.000 17.617 2.822 + 11533.500 16.853 2.835 + 11534.000 15.762 2.835 + 11534.500 15.322 2.829 + 11535.000 15.383 2.828 + 11535.500 18.252 2.833 + 11536.000 26.592 2.844 + 11536.500 36.124 2.847 + 11537.000 41.080 2.839 + 11537.500 44.366 2.823 + 11538.000 45.521 2.810 + 11538.500 42.845 2.798 + 11539.000 38.270 2.792 + 11539.500 32.831 2.789 + 11540.000 27.526 2.785 + 11540.500 24.234 2.815 + 11541.000 24.720 2.835 + 11541.500 26.182 2.841 + 11542.000 27.942 2.836 + 11542.500 30.640 2.807 + 11543.000 32.929 2.794 + 11543.500 34.945 2.786 + 11544.000 35.802 2.779 + 11544.500 31.020 2.779 + 11545.000 27.004 2.796 + 11545.500 22.334 2.804 + 11546.000 20.648 2.813 + 11546.500 19.246 2.817 + 11547.000 19.816 2.821 + 11547.500 22.499 2.824 + 11548.000 26.236 2.819 + 11548.500 30.390 2.791 + 11549.000 29.920 2.778 + 11549.500 28.812 2.769 + 11550.000 25.731 2.784 + 11550.500 22.226 2.808 + 11551.000 20.597 2.820 + 11551.500 21.284 2.825 + 11552.000 22.944 2.830 + 11552.500 24.792 2.826 + 11553.000 27.760 2.816 + 11553.500 30.322 2.791 + 11554.000 30.919 2.784 + 11554.500 33.929 2.784 + 11555.000 35.817 2.798 + 11555.500 37.902 2.799 + 11556.000 36.516 2.788 + 11556.500 29.846 2.782 + 11557.000 24.559 2.787 + 11557.500 20.023 2.803 + 11558.000 19.071 2.808 + 11558.500 19.868 2.809 + 11559.000 18.378 2.809 + 11559.500 18.936 2.813 + 11560.000 19.012 2.832 + 11560.500 20.993 2.804 + 11561.000 21.746 2.777 + 11561.500 20.691 2.741 + 11562.000 19.773 2.725 + 11562.500 17.108 2.729 + 11563.000 16.261 2.731 + 11563.500 16.522 2.753 + 11564.000 18.184 2.773 + 11564.500 17.565 2.812 + 11565.000 15.899 2.749 + 11565.500 15.984 2.679 + 11566.000 15.343 2.638 + 11566.500 16.064 2.673 + 11567.000 15.182 2.703 + 11567.500 15.139 2.709 + 11568.000 14.522 2.690 + 11568.500 13.880 2.645 + 11569.000 13.717 2.609 + 11569.500 13.755 2.610 + 11570.000 13.133 2.634 + 11570.500 13.551 2.668 + 11571.000 13.494 2.677 + 11571.500 15.229 2.687 + 11572.000 15.724 2.700 + 11572.500 15.422 2.740 + 11573.000 14.164 2.762 + 11573.500 13.742 2.755 + 11574.000 15.880 2.748 + 11574.500 18.757 2.759 + 11575.000 19.843 2.776 + 11575.500 19.945 2.799 + 11576.000 20.037 2.818 + 11576.500 20.056 2.827 + 11577.000 21.075 2.832 + 11577.500 21.784 2.838 + 11578.000 24.578 2.844 + 11578.500 29.579 2.834 + 11579.000 36.994 2.819 + 11579.500 40.727 2.810 + 11580.000 41.954 2.805 + 11580.500 39.516 2.793 + 11581.000 37.177 2.788 + 11581.500 32.122 2.791 + 11582.000 29.149 2.795 + 11582.500 25.950 2.806 + 11583.000 26.438 2.809 + 11583.500 27.991 2.802 + 11584.000 30.146 2.792 + 11584.500 32.965 2.782 + 11585.000 34.906 2.787 + 11585.500 34.914 2.789 + 11586.000 33.742 2.787 + 11586.500 28.474 2.784 + 11587.000 26.159 2.790 + 11587.500 21.524 2.803 + 11588.000 19.529 2.824 + 11588.500 18.592 2.847 + 11589.000 16.692 2.848 + 11589.500 17.719 2.848 + 11590.000 19.021 2.849 + 11590.500 21.933 2.820 + 11591.000 21.426 2.792 + 11591.500 21.316 2.753 + 11592.000 19.695 2.742 + 11592.500 19.328 2.748 + 11593.000 18.770 2.750 + 11593.500 18.222 2.737 + 11594.000 17.696 2.728 + 11594.500 17.172 2.723 + 11595.000 16.097 2.720 + 11595.500 13.705 2.718 + 11596.000 12.742 2.718 + 11596.500 12.074 2.721 + 11597.000 12.136 2.724 + 11597.500 12.756 2.732 + 11598.000 14.616 2.742 + 11598.500 15.346 2.766 + 11599.000 15.150 2.768 + 11599.500 14.313 2.768 + 11600.000 15.606 2.754 + 11600.500 17.687 2.720 + 11601.000 19.040 2.733 + 11601.500 19.782 2.738 + 11602.000 20.208 2.752 + 11602.500 21.057 2.762 + 11603.000 23.757 2.765 + 11603.500 27.986 2.765 + 11604.000 30.738 2.753 + 11604.500 33.491 2.732 + 11605.000 33.084 2.726 + 11605.500 33.952 2.752 + 11606.000 35.461 2.780 + 11606.500 39.623 2.801 + 11607.000 40.459 2.801 + 11607.500 41.806 2.800 + 11608.000 41.242 2.791 + 11608.500 44.116 2.783 + 11609.000 40.956 2.783 + 11609.500 40.904 2.786 + 11610.000 32.640 2.805 + 11610.500 21.791 2.822 + 11611.000 20.759 2.826 + 11611.500 21.506 2.830 + 11612.000 22.353 2.828 + 11612.500 24.749 2.821 + 11613.000 23.969 2.809 + 11613.500 21.637 2.797 + 11614.000 20.147 2.792 + 11614.500 20.112 2.784 + 11615.000 21.059 2.785 + 11615.500 23.334 2.786 + 11616.000 30.229 2.795 + 11616.500 35.079 2.807 + 11617.000 35.222 2.814 + 11617.500 34.929 2.815 + 11618.000 32.437 2.808 + 11618.500 31.395 2.794 + 11619.000 30.223 2.781 + 11619.500 28.594 2.773 + 11620.000 27.672 2.776 + 11620.500 26.325 2.797 + 11621.000 27.043 2.809 + 11621.500 30.209 2.815 + 11622.000 31.098 2.796 + 11622.500 32.453 2.776 + 11623.000 32.594 2.783 + 11623.500 32.566 2.804 + 11624.000 31.939 2.799 + 11624.500 29.027 2.832 + 11625.000 27.511 2.807 + 11625.500 24.280 2.798 + 11626.000 24.066 2.787 + 11626.500 21.385 2.772 + 11627.000 27.986 2.757 + 11627.500 32.715 2.769 + 11628.000 36.439 2.774 + 11628.500 37.742 2.780 + 11629.000 37.349 2.783 + 11629.500 33.500 2.791 + 11630.000 29.321 2.801 + 11630.500 24.269 2.841 + 11631.000 20.742 2.815 + 11631.500 20.100 2.783 + 11632.000 21.560 2.740 + 11632.500 30.139 2.753 + 11633.000 30.615 2.772 + 11633.500 28.810 2.779 + 11634.000 23.524 2.781 + 11634.500 16.965 2.789 + 11635.000 15.255 2.805 + 11635.500 15.179 2.819 + 11636.000 17.366 2.843 + 11636.500 22.457 2.829 + 11637.000 27.170 2.802 + 11637.500 30.153 2.763 + 11638.000 30.141 2.746 + 11638.500 25.310 2.765 + 11639.000 20.343 2.784 + 11639.500 16.884 2.801 + 11640.000 15.196 2.805 + 11640.500 14.015 2.811 + 11641.000 15.850 2.804 + 11641.500 20.022 2.800 + 11642.000 24.430 2.783 + 11642.500 31.752 2.804 + 11643.000 34.693 2.810 + 11643.500 35.424 2.806 + 11644.000 35.837 2.800 + 11644.500 37.729 2.797 + 11645.000 39.856 2.791 + 11645.500 38.908 2.775 + 11646.000 34.895 2.772 + 11646.500 26.546 2.780 + 11647.000 22.578 2.780 + 11647.500 21.602 2.777 + 11648.000 22.170 2.775 + 11648.500 24.929 2.789 + 11649.000 26.127 2.803 + 11649.500 28.303 2.809 + 11650.000 31.733 2.803 + 11650.500 34.273 2.794 + 11651.000 33.269 2.783 + 11651.500 30.255 2.776 + 11652.000 24.594 2.772 + 11652.500 13.763 2.764 + 11653.000 13.663 2.753 + 11653.500 12.957 2.747 + 11654.000 12.717 2.731 + 11654.500 14.391 2.727 + 11655.000 15.155 2.732 + 11655.500 14.654 2.740 + 11656.000 14.129 2.746 + 11656.500 13.740 2.755 + 11657.000 12.017 2.750 + 11657.500 12.834 2.743 + 11658.000 13.275 2.728 + 11658.500 16.709 2.727 + 11659.000 19.921 2.730 + 11659.500 24.509 2.743 + 11660.000 34.089 2.763 + 11660.500 44.911 2.803 + 11661.000 50.684 2.793 + 11661.500 48.192 2.793 + 11662.000 44.449 2.793 + 11662.500 39.402 2.796 + 11663.000 41.012 2.798 + 11663.500 42.734 2.805 + 11664.000 46.888 2.799 + 11664.500 44.896 2.801 + 11665.000 41.685 2.817 + 11665.500 38.764 2.848 + 11666.000 36.994 2.871 + 11666.500 35.494 2.802 + 11667.000 33.516 2.737 + 11667.500 31.253 2.717 + 11668.000 30.387 2.730 + 11668.500 30.255 2.770 + 11669.000 33.950 2.789 + 11669.500 35.648 2.792 + 11670.000 57.265 2.785 + 11670.500 64.784 2.767 + 11671.000 66.303 2.763 + 11671.500 59.351 2.765 + 11672.000 57.632 2.774 + 11672.500 31.328 2.775 + 11673.000 21.102 2.764 + 11673.500 15.546 2.752 + 11674.000 14.308 2.755 + 11674.500 14.338 2.767 + 11675.000 15.554 2.774 + 11675.500 17.157 2.766 + 11676.000 24.949 2.766 + 11676.500 33.167 2.756 + 11677.000 38.554 2.755 + 11677.500 40.138 2.766 + 11678.000 40.567 2.773 + 11678.500 35.420 2.787 + 11679.000 28.482 2.798 + 11679.500 24.116 2.800 + 11680.000 21.642 2.798 + 11680.500 19.973 2.789 + 11681.000 20.021 2.789 + 11681.500 19.046 2.786 + 11682.000 18.276 2.777 + 11682.500 16.788 2.749 + 11683.000 16.025 2.743 + 11683.500 16.661 2.751 + 11684.000 19.007 2.766 + 11684.500 19.359 2.780 + 11685.000 20.041 2.778 + 11685.500 19.849 2.776 + 11686.000 16.840 2.782 + 11686.500 15.966 2.788 + 11687.000 17.650 2.786 + 11687.500 21.679 2.781 + 11688.000 25.279 2.776 + 11688.500 28.304 2.785 + 11689.000 25.330 2.786 + 11689.500 21.488 2.790 + 11690.000 19.105 2.793 + 11690.500 15.860 2.789 + 11691.000 12.794 2.783 + 11691.500 11.555 2.776 + 11692.000 10.777 2.772 + 11692.500 10.435 2.770 + 11693.000 11.253 2.780 + 11693.500 10.807 2.787 + 11694.000 10.887 2.795 + 11694.500 11.451 2.800 + 11695.000 12.362 2.802 + 11695.500 13.441 2.806 + 11696.000 14.782 2.807 + 11696.500 21.293 2.795 + 11697.000 25.239 2.789 + 11697.500 30.669 2.777 + 11698.000 31.396 2.771 + 11698.500 26.632 2.764 + 11699.000 23.376 2.759 + 11699.500 18.729 2.758 + 11700.000 17.226 2.764 + 11700.500 17.033 2.781 + 11701.000 14.906 2.787 + 11701.500 14.518 2.787 + 11702.000 14.504 2.770 + 11702.500 13.892 2.741 + 11703.000 13.649 2.749 + 11703.500 14.490 2.769 + 11704.000 15.298 2.785 + 11704.500 15.954 2.805 + 11705.000 15.916 2.806 + 11705.500 17.448 2.810 + 11706.000 19.138 2.807 + 11706.500 19.175 2.783 + 11707.000 19.241 2.774 + 11707.500 19.501 2.768 + 11708.000 23.330 2.769 + 11708.500 25.387 2.767 + 11709.000 27.756 2.759 + 11709.500 28.617 2.751 + 11710.000 28.795 2.737 + 11710.500 30.440 2.734 + 11711.000 35.631 2.743 + 11711.500 38.428 2.746 + 11712.000 45.795 2.744 + 11712.500 54.485 2.731 + 11713.000 58.210 2.723 + 11713.500 56.713 2.719 + 11714.000 51.497 2.716 + 11714.500 46.175 2.717 + 11715.000 44.231 2.717 + 11715.500 43.964 2.716 + 11716.000 43.143 2.714 + 11716.500 41.561 2.715 + 11717.000 40.261 2.718 + 11717.500 40.193 2.727 + 11718.000 40.080 2.732 + 11718.500 40.486 2.730 + 11719.000 40.400 2.727 + 11719.500 44.126 2.727 + 11720.000 46.711 2.735 + 11720.500 52.622 2.736 + 11721.000 57.751 2.738 + 11721.500 61.909 2.740 + 11722.000 65.275 2.740 + 11722.500 68.729 2.750 + 11723.000 64.028 2.753 + 11723.500 60.959 2.752 + 11724.000 54.119 2.755 + 11724.500 45.064 2.722 + 11725.000 39.203 2.706 + 11725.500 28.995 2.643 + 11726.000 25.772 2.572 + 11726.500 20.511 2.452 + 11727.000 19.153 2.369 + 11727.500 15.082 2.346 + 11728.000 13.692 2.385 + 11728.500 10.866 2.558 + 11729.000 9.307 2.788 + 11729.500 8.820 2.860 + 11730.000 8.783 2.873 + 11730.500 10.641 2.848 + 11731.000 11.165 2.847 + 11731.500 11.217 2.862 + 11732.000 11.160 2.868 + 11732.500 13.500 2.884 + 11733.000 14.277 2.875 + 11733.500 15.009 2.867 + 11734.000 14.389 2.867 + 11734.500 12.891 2.876 + 11735.000 11.952 2.887 + 11735.500 10.760 2.890 + 11736.000 10.645 2.882 + 11736.500 10.473 2.870 + 11737.000 11.227 2.872 + 11737.500 11.498 2.880 + 11738.000 12.372 2.882 + 11738.500 13.181 2.880 + 11739.000 13.823 2.877 + 11739.500 15.727 2.866 + 11740.000 16.637 2.859 + 11740.500 15.475 2.845 + 11741.000 14.534 2.842 + 11741.500 13.629 2.846 + 11742.000 13.608 2.850 + 11742.500 14.372 2.859 + 11743.000 14.505 2.869 + 11743.500 15.994 2.875 + 11744.000 19.147 2.881 + 11744.500 24.435 2.884 + 11745.000 33.079 2.879 + 11745.500 42.639 2.856 + 11746.000 52.895 2.825 + 11746.500 62.102 2.785 + 11747.000 63.194 2.778 + 11747.500 63.387 2.775 + 11748.000 61.643 2.773 + 11748.500 57.097 2.772 + 11749.000 54.315 2.779 + 11749.500 47.328 2.790 + 11750.000 33.976 2.794 + 11750.500 23.856 2.795 + 11751.000 20.804 2.788 + 11751.500 19.785 2.781 + 11752.000 18.534 2.792 + 11752.500 18.158 2.801 + 11753.000 20.338 2.812 + 11753.500 26.473 2.815 + 11754.000 35.755 2.817 + 11754.500 38.054 2.818 + 11755.000 40.711 2.813 + 11755.500 42.331 2.807 + 11756.000 45.326 2.801 + 11756.500 49.656 2.810 + 11757.000 51.347 2.814 + 11757.500 52.302 2.816 + 11758.000 51.521 2.817 + 11758.500 50.379 2.823 + 11759.000 50.085 2.828 + 11759.500 54.689 2.826 + 11760.000 68.590 2.820 + 11760.500 82.287 2.795 + 11761.000 81.521 2.774 + 11761.500 79.992 2.763 + 11762.000 73.690 2.770 + 11762.500 46.053 2.804 + 11763.000 54.172 2.847 + 11763.500 58.026 2.855 + 11764.000 72.492 2.841 + 11764.500 70.861 2.824 + 11765.000 49.555 2.829 + 11765.500 31.516 2.844 + 11766.000 21.880 2.866 + 11766.500 19.141 2.873 + 11767.000 20.381 2.850 + 11767.500 23.380 2.827 + 11768.000 27.267 2.817 + 11768.500 31.974 2.825 + 11769.000 26.575 2.845 + 11769.500 23.939 2.883 + 11770.000 22.672 2.898 + 11770.500 20.966 2.897 + 11771.000 20.950 2.887 + 11771.500 23.562 2.874 + 11772.000 29.914 2.879 + 11772.500 45.855 2.891 + 11773.000 56.202 2.896 + 11773.500 66.653 2.866 + 11774.000 68.957 2.852 + 11774.500 70.282 2.824 + 11775.000 73.394 2.834 + 11775.500 77.157 2.829 + 11776.000 88.473 2.813 + 11776.500 96.285 2.765 + 11777.000 94.117 2.751 + 11777.500 93.262 2.741 + 11778.000 80.334 2.743 + 11778.500 59.265 2.777 + 11779.000 49.734 2.799 + 11779.500 47.112 2.814 + 11780.000 46.880 2.823 + 11780.500 54.739 2.817 + 11781.000 56.253 2.797 + 11781.500 60.668 2.784 + 11782.000 68.502 2.778 + 11782.500 87.642 2.758 + 11783.000 86.408 2.743 + 11783.500 75.950 2.734 + 11784.000 55.317 2.738 + 11784.500 38.130 2.769 + 11785.000 32.793 2.789 + 11785.500 22.596 2.806 + 11786.000 21.713 2.806 + 11786.500 26.022 2.811 + 11787.000 34.783 2.810 + 11787.500 57.016 2.802 + 11788.000 84.848 2.788 + 11788.500 82.884 2.760 + 11789.000 86.085 2.755 + 11789.500 83.078 2.754 + 11790.000 114.179 2.758 + 11790.500 112.561 2.746 + 11791.000 116.571 2.727 + 11791.500 114.026 2.721 + 11792.000 106.024 2.718 + 11792.500 88.417 2.725 + 11793.000 84.859 2.734 + 11793.500 75.757 2.754 + 11794.000 61.690 2.773 + 11794.500 51.835 2.813 + 11795.000 48.216 2.835 + 11795.500 45.744 2.855 + 11796.000 45.022 2.857 + 11796.500 38.666 2.851 + 11797.000 37.837 2.848 + 11797.500 40.473 2.842 + 11798.000 43.316 2.832 + 11798.500 61.194 2.809 + 11799.000 66.036 2.795 + 11799.500 72.091 2.780 + 11800.000 81.160 2.768 + 11800.500 84.639 2.750 + 11801.000 84.507 2.738 + 11801.500 86.910 2.741 + 11802.000 72.232 2.755 + 11802.500 63.211 2.780 + 11803.000 44.980 2.803 + 11803.500 42.243 2.814 + 11804.000 34.208 2.829 + 11804.500 30.398 2.838 + 11805.000 29.217 2.840 + 11805.500 37.777 2.842 + 11806.000 47.233 2.839 + 11806.500 72.699 2.813 + 11807.000 86.556 2.793 + 11807.500 102.220 2.762 + 11808.000 123.957 2.740 + 11808.500 145.496 2.719 + 11809.000 149.297 2.697 + 11809.500 150.074 2.676 + 11810.000 137.086 2.673 + 11810.500 128.212 2.677 + 11811.000 120.027 2.684 + 11811.500 117.772 2.692 + 11812.000 113.395 2.695 + 11812.500 108.219 2.703 + 11813.000 90.758 2.706 + 11813.500 66.103 2.723 + 11814.000 49.264 2.742 + 11814.500 31.830 2.793 + 11815.000 32.839 2.827 + 11815.500 39.099 2.852 + 11816.000 48.248 2.866 + 11816.500 70.394 2.860 + 11817.000 82.172 2.807 + 11817.500 92.425 2.773 + 11818.000 83.903 2.745 + 11818.500 73.418 2.740 + 11819.000 63.363 2.753 + 11819.500 60.877 2.787 + 11820.000 75.223 2.799 + 11820.500 109.231 2.769 + 11821.000 111.543 2.736 + 11821.500 121.590 2.717 + 11822.000 123.691 2.710 + 11822.500 118.902 2.714 + 11823.000 118.081 2.722 + 11823.500 117.956 2.723 + 11824.000 118.976 2.718 + 11824.500 121.346 2.718 + 11825.000 118.012 2.720 + 11825.500 111.180 2.732 + 11826.000 107.615 2.745 + 11826.500 107.414 2.761 + 11827.000 115.570 2.758 + 11827.500 134.629 2.754 + 11828.000 144.828 2.739 + 11828.500 148.340 2.686 + 11829.000 137.138 2.689 + 11829.500 116.268 2.688 + 11830.000 96.803 2.700 + 11830.500 74.956 2.746 + 11831.000 70.684 2.754 + 11831.500 68.216 2.757 + 11832.000 69.833 2.769 + 11832.500 78.974 2.770 + 11833.000 81.887 2.762 + 11833.500 92.382 2.757 + 11834.000 104.813 2.756 + 11834.500 106.379 2.747 + 11835.000 112.903 2.738 + 11835.500 116.472 2.726 + 11836.000 129.244 2.701 + 11836.500 125.118 2.693 + 11837.000 121.540 2.698 + 11837.500 99.163 2.714 + 11838.000 90.824 2.732 + 11838.500 61.167 2.749 + 11839.000 59.754 2.760 + 11839.500 55.835 2.770 + 11840.000 55.029 2.775 + 11840.500 54.701 2.787 + 11841.000 52.937 2.790 + 11841.500 50.507 2.788 + 11842.000 49.885 2.784 + 11842.500 52.749 2.790 + 11843.000 60.891 2.790 + 11843.500 64.605 2.789 + 11844.000 64.574 2.781 + 11844.500 51.529 2.786 + 11845.000 50.234 2.791 + 11845.500 56.381 2.790 + 11846.000 64.548 2.773 + 11846.500 69.612 2.752 + 11847.000 67.392 2.755 + 11847.500 61.660 2.763 + 11848.000 55.561 2.783 + 11848.500 47.574 2.805 + 11849.000 44.034 2.803 + 11849.500 40.298 2.814 + 11850.000 32.740 2.823 + 11850.500 22.679 2.853 + 11851.000 19.106 2.859 + 11851.500 20.401 2.860 + 11852.000 21.541 2.857 + 11852.500 27.004 2.836 + 11853.000 32.790 2.813 + 11853.500 39.128 2.792 + 11854.000 41.584 2.786 + 11854.500 42.137 2.798 + 11855.000 44.460 2.809 + 11855.500 46.216 2.814 + 11856.000 49.004 2.810 + 11856.500 49.676 2.806 + 11857.000 49.465 2.807 + 11857.500 46.885 2.805 + 11858.000 45.476 2.805 + 11858.500 38.221 2.800 + 11859.000 34.669 2.798 + 11859.500 28.883 2.801 + 11860.000 25.720 2.807 + 11860.500 23.682 2.822 + 11861.000 21.441 2.821 + 11861.500 20.687 2.824 + 11862.000 21.349 2.828 + 11862.500 19.999 2.836 + 11863.000 20.142 2.830 + 11863.500 20.882 2.826 + 11864.000 20.732 2.827 + 11864.500 20.682 2.835 + 11865.000 17.153 2.837 + 11865.500 16.916 2.835 + 11866.000 16.682 2.834 + 11866.500 15.978 2.832 + 11867.000 18.388 2.838 + 11867.500 19.328 2.846 + 11868.000 20.775 2.848 + 11868.500 22.652 2.835 + 11869.000 24.838 2.819 + 11869.500 25.962 2.811 + 11870.000 29.601 2.807 + 11870.500 34.322 2.818 + 11871.000 40.738 2.831 + 11871.500 40.911 2.831 + 11872.000 39.580 2.829 + 11872.500 34.170 2.817 + 11873.000 30.661 2.816 + 11873.500 29.384 2.811 + 11874.000 30.666 2.808 + 11874.500 32.133 2.807 + 11875.000 33.744 2.806 + 11875.500 32.388 2.805 + 11876.000 30.268 2.805 + 11876.500 29.112 2.812 + 11877.000 26.836 2.819 + 11877.500 24.597 2.822 + 11878.000 23.873 2.821 + 11878.500 23.831 2.820 + 11879.000 24.073 2.810 + 11879.500 24.008 2.805 + 11880.000 25.053 2.802 + 11880.500 26.511 2.801 + 11881.000 36.188 2.800 + 11881.500 36.243 2.801 + 11882.000 36.111 2.798 + 11882.500 29.096 2.813 + 11883.000 26.971 2.821 + 11883.500 26.882 2.810 + 11884.000 27.361 2.805 + 11884.500 27.802 2.801 + 11885.000 27.851 2.798 + 11885.500 27.498 2.789 + 11886.000 28.197 2.770 + 11886.500 33.117 2.747 + 11887.000 35.957 2.741 + 11887.500 39.354 2.753 + 11888.000 37.622 2.768 + 11888.500 34.719 2.790 + 11889.000 33.679 2.788 + 11889.500 32.905 2.787 + 11890.000 36.986 2.793 + 11890.500 39.265 2.812 + 11891.000 39.905 2.812 + 11891.500 40.569 2.812 + 11892.000 41.085 2.807 + 11892.500 40.405 2.772 + 11893.000 42.093 2.763 + 11893.500 42.723 2.751 + 11894.000 43.014 2.749 + 11894.500 40.152 2.765 + 11895.000 38.092 2.769 + 11895.500 36.061 2.759 + 11896.000 34.986 2.744 + 11896.500 31.468 2.729 + 11897.000 31.035 2.731 + 11897.500 30.846 2.736 + 11898.000 30.967 2.736 + 11898.500 31.155 2.734 + 11899.000 32.044 2.735 + 11899.500 36.461 2.736 + 11900.000 39.683 2.737 + 11900.500 45.596 2.747 + 11901.000 48.198 2.759 + 11901.500 48.287 2.757 + 11902.000 48.244 2.747 + 11902.500 48.262 2.727 + 11903.000 47.981 2.721 + 11903.500 46.699 2.716 + 11904.000 44.472 2.715 + 11904.500 40.956 2.710 + 11905.000 39.772 2.710 + 11905.500 38.840 2.719 + 11906.000 35.619 2.724 + 11906.500 35.043 2.734 + 11907.000 34.025 2.731 + 11907.500 34.897 2.725 + 11908.000 34.334 2.719 + 11908.500 34.999 2.713 + 11909.000 35.207 2.718 + 11909.500 35.634 2.725 + 11910.000 36.948 2.733 + 11910.500 39.625 2.732 + 11911.000 40.023 2.717 + 11911.500 41.765 2.717 + 11912.000 43.546 2.723 + 11912.500 45.431 2.735 + 11913.000 45.871 2.734 + 11913.500 46.059 2.736 + 11914.000 46.855 2.746 + 11914.500 48.098 2.765 + 11915.000 48.606 2.766 + 11915.500 49.177 2.764 + 11916.000 48.120 2.752 + 11916.500 46.330 2.738 + 11917.000 45.172 2.736 + 11917.500 43.314 2.737 + 11918.000 41.933 2.740 + 11918.500 40.675 2.742 + 11919.000 40.486 2.741 + 11919.500 40.841 2.732 + 11920.000 41.641 2.719 + 11920.500 43.762 2.710 + 11921.000 45.146 2.717 + 11921.500 46.056 2.727 + 11922.000 46.640 2.730 + 11922.500 45.701 2.715 + 11923.000 46.517 2.709 + 11923.500 47.207 2.708 + 11924.000 48.123 2.715 + 11924.500 48.287 2.727 + 11925.000 49.038 2.741 + 11925.500 49.110 2.736 + 11926.000 50.032 2.729 + 11926.500 50.861 2.722 + 11927.000 50.739 2.724 + 11927.500 50.693 2.723 + 11928.000 49.839 2.719 + 11928.500 50.413 2.708 + 11929.000 51.255 2.703 + 11929.500 52.800 2.695 + 11930.000 55.664 2.696 + 11930.500 58.632 2.704 + 11931.000 61.039 2.713 + 11931.500 60.470 2.715 + 11932.000 60.321 2.716 + 11932.500 57.464 2.717 + 11933.000 56.667 2.715 + 11933.500 55.261 2.713 + 11934.000 54.229 2.705 + 11934.500 47.198 2.705 + 11935.000 41.199 2.707 + 11935.500 35.192 2.714 + 11936.000 33.941 2.721 + 11936.500 35.438 2.727 + 11937.000 40.285 2.730 + 11937.500 41.649 2.733 + 11938.000 43.109 2.733 + 11938.500 44.558 2.733 + 11939.000 45.799 2.731 + 11939.500 48.055 2.729 + 11940.000 51.944 2.726 + 11940.500 54.024 2.722 + 11941.000 54.894 2.720 + 11941.500 56.017 2.717 + 11942.000 58.712 2.714 + 11942.500 63.502 2.712 + 11943.000 67.020 2.713 + 11943.500 66.984 2.713 + 11944.000 63.247 2.710 + 11944.500 51.198 2.707 + 11945.000 48.014 2.708 + 11945.500 43.407 2.715 + 11946.000 43.428 2.724 + 11946.500 43.558 2.732 + 11947.000 43.498 2.734 + 11947.500 42.930 2.734 + 11948.000 43.053 2.733 + 11948.500 45.637 2.733 + 11949.000 47.468 2.732 + 11949.500 51.177 2.724 + 11950.000 58.387 2.701 + 11950.500 63.418 2.677 + 11951.000 61.267 2.682 + 11951.500 57.126 2.701 + 11952.000 51.462 2.715 + 11952.500 43.353 2.728 + 11953.000 39.503 2.735 + 11953.500 35.396 2.741 + 11954.000 31.572 2.751 + 11954.500 28.016 2.754 + 11955.000 26.387 2.752 + 11955.500 26.266 2.751 + 11956.000 25.928 2.750 + 11956.500 28.951 2.752 + 11957.000 30.848 2.753 + 11957.500 35.076 2.743 + 11958.000 38.476 2.736 + 11958.500 42.211 2.732 + 11959.000 44.281 2.733 + 11959.500 49.896 2.729 + 11960.000 53.241 2.728 + 11960.500 59.570 2.716 + 11961.000 64.258 2.710 + 11961.500 68.443 2.710 + 11962.000 70.584 2.709 + 11962.500 72.804 2.707 + 11963.000 72.470 2.705 + 11963.500 70.592 2.701 + 11964.000 68.046 2.690 + 11964.500 65.346 2.685 + 11965.000 64.672 2.690 + 11965.500 66.702 2.701 + 11966.000 67.897 2.705 + 11966.500 72.105 2.707 + 11967.000 74.266 2.703 + 11967.500 83.761 2.703 + 11968.000 90.316 2.702 + 11968.500 102.582 2.700 + 11969.000 113.780 2.701 + 11969.500 122.384 2.706 + 11970.000 121.574 2.706 + 11970.500 121.329 2.703 + 11971.000 120.566 2.698 + 11971.500 120.964 2.695 + 11972.000 121.804 2.693 + 11972.500 121.775 2.693 + 11973.000 120.514 2.695 + 11973.500 121.025 2.701 + 11974.000 124.393 2.703 + 11974.500 128.373 2.695 + 11975.000 128.521 2.675 + 11975.500 124.527 2.659 + 11976.000 119.902 2.657 + 11976.500 109.976 2.663 + 11977.000 108.431 2.671 + 11977.500 110.943 2.678 + 11978.000 120.131 2.682 + 11978.500 126.476 2.691 + 11979.000 127.517 2.697 + 11979.500 130.343 2.705 + 11980.000 133.229 2.711 + 11980.500 136.732 2.709 + 11981.000 139.285 2.704 + 11981.500 139.889 2.690 + 11982.000 151.706 2.675 + 11982.500 149.537 2.659 + 11983.000 148.138 2.663 + 11983.500 145.989 2.665 + 11984.000 145.996 2.661 + 11984.500 151.296 2.658 + 11985.000 156.874 2.657 + 11985.500 166.461 2.666 + 11986.000 172.980 2.669 + 11986.500 172.562 2.673 + 11987.000 173.392 2.672 + 11987.500 166.572 2.668 + 11988.000 155.124 2.663 + 11988.500 124.588 2.659 + 11989.000 119.486 2.657 + 11989.500 109.387 2.657 + 11990.000 100.125 2.662 + 11990.500 91.152 2.669 + 11991.000 82.493 2.685 + 11991.500 74.290 2.701 + 11992.000 59.712 2.741 + 11992.500 42.803 2.758 + 11993.000 37.149 2.769 + 11993.500 31.807 2.771 + 11994.000 29.234 2.775 + 11994.500 27.802 2.781 + 11995.000 25.520 2.782 + 11995.500 24.587 2.781 + 11996.000 24.479 2.780 + 11996.500 29.246 2.785 + 11997.000 35.582 2.789 + 11997.500 52.107 2.789 + 11998.000 74.765 2.785 + 11998.500 95.216 2.744 + 11999.000 125.803 2.718 + 11999.500 125.244 2.682 + 12000.000 128.553 2.653 + 12000.500 136.433 2.653 + 12001.000 144.953 2.659 + 12001.500 154.906 2.661 + 12002.000 165.245 2.661 + 12002.500 165.786 2.659 + 12003.000 167.368 2.657 + 12003.500 168.572 2.655 + 12004.000 166.932 2.655 + 12004.500 152.243 2.657 + 12005.000 136.134 2.657 + 12005.500 123.127 2.660 + 12006.000 105.692 2.672 + 12006.500 110.840 2.683 + 12007.000 128.367 2.683 + 12007.500 146.769 2.683 + 12008.000 165.252 2.681 + 12008.500 180.919 2.683 + 12009.000 186.719 2.683 + 12009.500 185.398 2.683 + 12010.000 176.759 2.683 + 12010.500 158.134 2.673 + 12011.000 149.285 2.672 + 12011.500 146.386 2.683 + 12012.000 144.524 2.690 + 12012.500 129.372 2.700 + 12013.000 109.830 2.700 + 12013.500 89.918 2.702 + 12014.000 69.712 2.705 + 12014.500 49.391 2.706 + 12015.000 39.407 2.717 + 12015.500 36.562 2.733 + 12016.000 34.238 2.749 + 12016.500 33.441 2.764 + 12017.000 35.721 2.768 + 12017.500 42.442 2.764 + 12018.000 48.179 2.758 + 12018.500 92.849 2.749 + 12019.000 113.760 2.742 + 12019.500 141.171 2.739 + 12020.000 166.879 2.725 + 12020.500 171.077 2.706 + 12021.000 168.797 2.691 + 12021.500 164.607 2.688 + 12022.000 156.653 2.689 + 12022.500 152.522 2.691 + 12023.000 157.597 2.691 + 12023.500 162.611 2.691 + 12024.000 160.547 2.689 + 12024.500 144.090 2.679 + 12025.000 123.037 2.677 + 12025.500 118.260 2.677 + 12026.000 144.486 2.679 + 12026.500 142.897 2.676 + 12027.000 145.274 2.662 + 12027.500 146.108 2.655 + 12028.000 147.917 2.654 + 12028.500 154.516 2.662 + 12029.000 159.657 2.665 + 12029.500 164.441 2.665 + 12030.000 171.413 2.662 + 12030.500 170.254 2.656 + 12031.000 166.288 2.659 + 12031.500 162.516 2.664 + 12032.000 161.314 2.672 + 12032.500 161.246 2.676 + 12033.000 160.231 2.685 + 12033.500 158.115 2.689 + 12034.000 158.822 2.696 + 12034.500 166.468 2.683 + 12035.000 173.691 2.678 + 12035.500 182.440 2.669 + 12036.000 184.425 2.666 + 12036.500 180.092 2.660 + 12037.000 172.288 2.662 + 12037.500 159.967 2.663 + 12038.000 157.820 2.665 + 12038.500 152.874 2.661 + 12039.000 149.989 2.652 + 12039.500 147.661 2.649 + 12040.000 145.813 2.649 + 12040.500 145.763 2.649 + 12041.000 145.771 2.650 + 12041.500 150.208 2.649 + 12042.000 156.334 2.649 + 12042.500 168.043 2.649 + 12043.000 172.080 2.653 + 12043.500 173.807 2.666 + 12044.000 171.415 2.678 + 12044.500 167.209 2.690 + 12045.000 162.098 2.700 + 12045.500 155.797 2.703 + 12046.000 142.912 2.695 + 12046.500 125.451 2.679 + 12047.000 112.615 2.666 + 12047.500 110.732 2.667 + 12048.000 114.688 2.669 + 12048.500 136.290 2.673 + 12049.000 154.227 2.675 + 12049.500 161.653 2.679 + 12050.000 162.554 2.682 + 12050.500 166.821 2.690 + 12051.000 162.208 2.692 + 12051.500 157.591 2.676 + 12052.000 145.997 2.657 + 12052.500 139.318 2.653 + 12053.000 133.895 2.666 + 12053.500 133.105 2.669 + 12054.000 129.864 2.684 + 12054.500 138.377 2.689 + 12055.000 141.458 2.689 + 12055.500 141.088 2.682 + 12056.000 136.532 2.679 + 12056.500 127.678 2.677 + 12057.000 129.552 2.683 + 12057.500 138.883 2.691 + 12058.000 143.284 2.691 + 12058.500 148.538 2.689 + 12059.000 142.695 2.691 + 12059.500 139.949 2.701 + 12060.000 131.918 2.705 + 12060.500 129.623 2.696 + 12061.000 126.283 2.689 + 12061.500 128.137 2.680 + 12062.000 129.701 2.680 + 12062.500 143.226 2.683 + 12063.000 143.901 2.687 + 12063.500 145.163 2.687 + 12064.000 150.103 2.689 + 12064.500 152.167 2.693 + 12065.000 154.936 2.689 + 12065.500 152.597 2.682 + 12066.000 151.707 2.673 + 12066.500 153.687 2.673 + 12067.000 155.265 2.681 + 12067.500 154.541 2.685 + 12068.000 151.170 2.687 + 12068.500 138.628 2.686 + 12069.000 132.500 2.687 + 12069.500 130.374 2.692 + 12070.000 136.634 2.694 + 12070.500 146.341 2.698 + 12071.000 150.612 2.701 + 12071.500 150.591 2.713 + 12072.000 145.862 2.721 + 12072.500 143.083 2.726 + 12073.000 144.794 2.734 + 12073.500 150.547 2.739 + 12074.000 156.167 2.750 + 12074.500 161.543 2.742 + 12075.000 161.432 2.727 + 12075.500 155.342 2.698 + 12076.000 150.276 2.684 + 12076.500 141.388 2.666 + 12077.000 141.001 2.666 + 12077.500 140.764 2.671 + 12078.000 139.915 2.679 + 12078.500 136.030 2.689 + 12079.000 129.964 2.689 + 12079.500 129.072 2.685 + 12080.000 132.416 2.671 + 12080.500 139.919 2.656 + 12081.000 145.575 2.655 + 12081.500 145.261 2.665 + 12082.000 145.235 2.677 + 12082.500 146.625 2.679 + 12083.000 149.795 2.678 + 12083.500 152.831 2.677 + 12084.000 154.765 2.675 + 12084.500 132.572 2.675 + 12085.000 124.157 2.677 + 12085.500 108.645 2.685 + 12086.000 90.376 2.695 + 12086.500 78.874 2.707 + 12087.000 73.070 2.718 + 12087.500 71.112 2.721 + 12088.000 69.461 2.718 + 12088.500 72.111 2.713 + 12089.000 73.485 2.708 + 12089.500 73.011 2.701 + 12090.000 72.026 2.699 + 12090.500 66.260 2.700 + 12091.000 64.072 2.705 + 12091.500 59.897 2.715 + 12092.000 58.239 2.720 + 12092.500 55.127 2.726 + 12093.000 53.678 2.721 + 12093.500 52.492 2.719 + 12094.000 47.758 2.722 + 12094.500 43.313 2.736 + 12095.000 39.506 2.750 + 12095.500 36.439 2.763 + 12096.000 33.892 2.786 + 12096.500 31.753 2.803 + 12097.000 31.801 2.805 + 12097.500 31.712 2.807 + 12098.000 31.802 2.806 + 12098.500 31.656 2.804 + 12099.000 32.403 2.800 + 12099.500 32.719 2.796 + 12100.000 33.168 2.797 + 12100.500 32.457 2.806 + 12101.000 30.931 2.808 + 12101.500 30.119 2.813 + 12102.000 30.129 2.818 + 12102.500 28.568 2.827 + 12103.000 27.004 2.833 + 12103.500 26.016 2.850 + 12104.000 25.905 2.852 + 12104.500 27.469 2.849 + 12105.000 30.835 2.829 + 12105.500 33.793 2.809 + 12106.000 34.706 2.798 + 12106.500 31.916 2.804 + 12107.000 30.178 2.804 + 12107.500 29.297 2.803 + 12108.000 28.602 2.803 + 12108.500 27.672 2.816 + 12109.000 26.909 2.829 + 12109.500 25.543 2.839 + 12110.000 25.937 2.839 + 12110.500 27.000 2.829 + 12111.000 28.058 2.819 + 12111.500 31.331 2.803 + 12112.000 33.235 2.803 + 12112.500 33.312 2.802 + 12113.000 33.874 2.798 + 12113.500 34.707 2.780 + 12114.000 38.312 2.758 + 12114.500 41.235 2.750 + 12115.000 42.981 2.754 + 12115.500 44.382 2.760 + 12116.000 46.967 2.753 + 12116.500 49.163 2.752 + 12117.000 49.337 2.750 + 12117.500 48.133 2.750 + 12118.000 46.035 2.751 + 12118.500 43.926 2.758 + 12119.000 41.879 2.775 + 12119.500 41.131 2.780 + 12120.000 41.222 2.787 + 12120.500 41.029 2.789 + 12121.000 42.420 2.798 + 12121.500 42.683 2.816 + 12122.000 41.127 2.819 + 12122.500 40.164 2.809 + 12123.000 39.564 2.797 + 12123.500 39.607 2.780 + 12124.000 40.135 2.773 + 12124.500 41.059 2.767 + 12125.000 41.000 2.772 + 12125.500 41.172 2.775 + 12126.000 41.085 2.770 + 12126.500 39.937 2.754 + 12127.000 37.456 2.751 + 12127.500 34.894 2.745 + 12128.000 32.691 2.735 + 12128.500 32.697 2.725 + 12129.000 31.845 2.742 + 12129.500 31.543 2.750 + 12130.000 31.528 2.764 + 12130.500 34.013 2.758 + 12131.000 39.114 2.748 + 12131.500 44.571 2.733 + 12132.000 46.625 2.730 + 12132.500 48.416 2.747 + 12133.000 48.973 2.769 + 12133.500 50.422 2.770 + 12134.000 51.076 2.767 + 12134.500 48.840 2.742 + 12135.000 47.675 2.731 + 12135.500 45.384 2.724 + 12136.000 43.958 2.722 + 12136.500 39.933 2.724 + 12137.000 38.240 2.730 + 12137.500 37.425 2.739 + 12138.000 37.057 2.747 + 12138.500 36.413 2.753 + 12139.000 35.796 2.758 + 12139.500 34.173 2.759 + 12140.000 34.097 2.751 + 12140.500 34.096 2.737 + 12141.000 34.226 2.735 + 12141.500 35.660 2.741 + 12142.000 37.620 2.746 + 12142.500 39.294 2.746 + 12143.000 39.747 2.747 + 12143.500 40.758 2.749 + 12144.000 43.071 2.751 + 12144.500 45.920 2.751 + 12145.000 45.848 2.751 + 12145.500 45.933 2.749 + 12146.000 45.684 2.749 + 12146.500 45.633 2.736 + 12147.000 45.933 2.731 + 12147.500 46.032 2.730 + 12148.000 46.746 2.732 + 12148.500 46.702 2.719 + 12149.000 45.615 2.709 + 12149.500 43.124 2.703 + 12150.000 41.548 2.703 + 12150.500 42.644 2.718 + 12151.000 43.348 2.742 + 12151.500 45.090 2.759 + 12152.000 45.172 2.790 + 12152.500 43.512 2.748 + 12153.000 39.683 2.721 + 12153.500 39.830 2.714 + 12154.000 40.267 2.722 + 12154.500 41.836 2.752 + 12155.000 42.733 2.760 + 12155.500 43.126 2.744 + 12156.000 41.606 2.733 + 12156.500 43.580 2.725 + 12157.000 46.273 2.730 + 12157.500 49.542 2.731 + 12158.000 49.735 2.728 + 12158.500 49.884 2.718 + 12159.000 49.929 2.719 + 12159.500 50.631 2.727 + 12160.000 50.981 2.732 + 12160.500 51.397 2.732 + 12161.000 51.268 2.712 + 12161.500 50.434 2.709 + 12162.000 50.647 2.710 + 12162.500 50.870 2.717 + 12163.000 52.243 2.721 + 12163.500 52.872 2.720 + 12164.000 53.821 2.721 + 12164.500 53.754 2.730 + 12165.000 54.210 2.734 + 12165.500 57.519 2.723 + 12166.000 58.634 2.709 + 12166.500 59.143 2.708 + 12167.000 57.826 2.709 + 12167.500 52.483 2.721 + 12168.000 49.594 2.745 + 12168.500 45.894 2.740 + 12169.000 45.935 2.713 + 12169.500 43.868 2.705 + 12170.000 41.668 2.704 + 12170.500 39.581 2.706 + 12171.000 37.413 2.705 + 12171.500 38.192 2.707 + 12172.000 39.564 2.719 + 12172.500 41.687 2.732 + 12173.000 43.465 2.752 + 12173.500 43.906 2.756 + 12174.000 44.928 2.772 + 12174.500 47.713 2.767 + 12175.000 50.416 2.750 + 12175.500 54.089 2.743 + 12176.000 54.203 2.736 + 12176.500 54.580 2.733 + 12177.000 54.528 2.734 + 12177.500 54.651 2.738 + 12178.000 55.394 2.741 + 12178.500 55.339 2.750 + 12179.000 57.248 2.751 + 12179.500 60.166 2.747 + 12180.000 61.054 2.743 + 12180.500 58.024 2.730 + 12181.000 54.643 2.727 + 12181.500 51.773 2.726 + 12182.000 45.223 2.739 + 12182.500 41.438 2.732 + 12183.000 39.358 2.714 + 12183.500 40.116 2.713 + 12184.000 42.269 2.714 + 12184.500 42.755 2.722 + 12185.000 42.120 2.724 + 12185.500 41.916 2.731 + 12186.000 43.263 2.736 + 12186.500 45.435 2.759 + 12187.000 50.405 2.758 + 12187.500 55.704 2.751 + 12188.000 61.947 2.735 + 12188.500 65.655 2.717 + 12189.000 64.544 2.705 + 12189.500 61.105 2.701 + 12190.000 57.463 2.718 + 12190.500 48.643 2.782 + 12191.000 40.372 2.827 + 12191.500 30.627 2.853 + 12192.000 28.077 2.875 + 12192.500 25.659 2.813 + 12193.000 23.900 2.755 + 12193.500 23.755 2.692 + 12194.000 23.004 2.670 + 12194.500 23.125 2.686 + 12195.000 23.166 2.719 + 12195.500 27.145 2.754 + 12196.000 28.247 2.778 + 12196.500 33.950 2.844 + 12197.000 35.464 2.849 + 12197.500 42.810 2.851 + 12198.000 45.586 2.828 + 12198.500 53.669 2.770 + 12199.000 56.001 2.744 + 12199.500 59.430 2.739 + 12200.000 58.556 2.752 + 12200.500 61.377 2.812 + 12201.000 64.628 2.804 + 12201.500 66.307 2.809 + 12202.000 68.020 2.813 + 12202.500 69.751 2.818 + 12203.000 67.868 2.832 + 12203.500 65.098 2.842 + 12204.000 62.224 2.858 + 12204.500 60.918 2.851 + 12205.000 60.737 2.827 + 12205.500 61.299 2.808 + 12206.000 61.995 2.799 + 12206.500 64.499 2.781 + 12207.000 66.318 2.766 + 12207.500 68.952 2.756 + 12208.000 70.336 2.755 + 12208.500 82.031 2.737 + 12209.000 89.539 2.719 + 12209.500 98.370 2.706 + 12210.000 105.976 2.701 + 12210.500 114.528 2.698 + 12211.000 116.333 2.701 + 12211.500 117.272 2.695 + 12212.000 118.832 2.695 + 12212.500 120.421 2.691 + 12213.000 122.212 2.691 + 12213.500 123.631 2.690 + 12214.000 122.929 2.696 + 12214.500 117.791 2.712 + 12215.000 115.229 2.732 + 12215.500 115.039 2.750 + 12216.000 118.187 2.751 + 12216.500 124.592 2.745 + 12217.000 128.331 2.731 + 12217.500 129.024 2.723 + 12218.000 128.346 2.718 + 12218.500 119.657 2.719 + 12219.000 110.969 2.721 + 12219.500 100.545 2.749 + 12220.000 102.361 2.750 + 12220.500 107.934 2.774 + 12221.000 117.790 2.777 + 12221.500 126.867 2.758 + 12222.000 129.948 2.749 + 12222.500 130.820 2.749 + 12223.000 131.484 2.791 + 12223.500 133.168 2.807 + 12224.000 134.146 2.806 + 12224.500 137.880 2.801 + 12225.000 139.721 2.805 + 12225.500 144.196 2.807 + 12226.000 146.189 2.802 + 12226.500 146.183 2.797 + 12227.000 146.328 2.762 + 12227.500 146.500 2.743 + 12228.000 148.612 2.739 + 12228.500 151.545 2.749 + 12229.000 156.386 2.772 + 12229.500 161.065 2.791 + 12230.000 167.645 2.796 + 12230.500 172.461 2.786 + 12231.000 176.462 2.757 + 12231.500 174.000 2.742 + 12232.000 170.658 2.741 + 12232.500 152.190 2.768 + 12233.000 139.610 2.777 + 12233.500 125.933 2.777 + 12234.000 115.028 2.774 + 12234.500 101.014 2.778 + 12235.000 97.162 2.782 + 12235.500 90.880 2.786 + 12236.000 86.817 2.792 + 12236.500 73.610 2.804 + 12237.000 60.763 2.809 + 12237.500 47.001 2.818 + 12238.000 41.853 2.829 + 12238.500 33.776 2.871 + 12239.000 30.573 2.935 + 12239.500 28.995 2.939 + 12240.000 28.543 2.929 + 12240.500 26.407 2.898 + 12241.000 25.447 2.907 + 12241.500 26.354 2.964 + 12242.000 34.247 2.992 + 12242.500 36.640 2.968 + 12243.000 50.676 2.869 + 12243.500 77.848 2.819 + 12244.000 114.154 2.760 + 12244.500 126.523 2.735 + 12245.000 135.369 2.767 + 12245.500 139.398 2.763 + 12246.000 138.763 2.755 + 12246.500 148.453 2.770 + 12247.000 161.406 2.777 + 12247.500 165.312 2.768 + 12248.000 165.497 2.758 + 12248.500 165.078 2.728 + 12249.000 164.917 2.729 + 12249.500 160.041 2.732 + 12250.000 153.227 2.733 + 12250.500 143.734 2.739 + 12251.000 133.776 2.745 + 12251.500 121.449 2.755 + 12252.000 106.536 2.769 + 12252.500 101.527 2.789 + 12253.000 99.084 2.790 + 12253.500 122.090 2.786 + 12254.000 138.410 2.780 + 12254.500 161.117 2.772 + 12255.000 171.628 2.770 + 12255.500 176.359 2.773 + 12256.000 179.608 2.770 + 12256.500 177.540 2.750 + 12257.000 170.253 2.730 + 12257.500 152.845 2.720 + 12258.000 146.666 2.710 + 12258.500 147.024 2.718 + 12259.000 149.961 2.759 + 12259.500 149.533 2.761 + 12260.000 119.114 2.767 + 12260.500 91.864 2.774 + 12261.000 81.988 2.780 + 12261.500 55.020 2.797 + 12262.000 46.610 2.805 + 12262.500 36.853 2.824 + 12263.000 36.668 2.849 + 12263.500 35.957 2.873 + 12264.000 35.650 2.878 + 12264.500 35.866 2.878 + 12265.000 37.165 2.875 + 12265.500 42.173 2.874 + 12266.000 44.131 2.871 + 12266.500 57.259 2.858 + 12267.000 66.197 2.853 + 12267.500 86.063 2.851 + 12268.000 115.254 2.842 + 12268.500 138.813 2.827 + 12269.000 170.605 2.805 + 12269.500 180.144 2.790 + 12270.000 177.669 2.776 + 12270.500 170.461 2.771 + 12271.000 144.330 2.770 + 12271.500 136.496 2.785 + 12272.000 126.406 2.796 + 12272.500 132.724 2.812 + 12273.000 149.729 2.766 + 12273.500 153.400 2.753 + 12274.000 151.413 2.734 + 12274.500 133.345 2.759 + 12275.000 121.530 2.792 + 12275.500 123.042 2.819 + 12276.000 138.426 2.821 + 12276.500 150.659 2.795 + 12277.000 155.896 2.785 + 12277.500 154.166 2.757 + 12278.000 150.682 2.739 + 12278.500 141.947 2.738 + 12279.000 141.871 2.746 + 12279.500 140.803 2.746 + 12280.000 153.592 2.744 + 12280.500 166.791 2.745 + 12281.000 168.039 2.745 + 12281.500 167.453 2.753 + 12282.000 164.116 2.757 + 12282.500 161.680 2.767 + 12283.000 162.248 2.760 + 12283.500 162.862 2.753 + 12284.000 162.049 2.751 + 12284.500 158.566 2.746 + 12285.000 156.040 2.743 + 12285.500 155.161 2.748 + 12286.000 163.241 2.774 + 12286.500 170.937 2.776 + 12287.000 175.851 2.783 + 12287.500 176.912 2.790 + 12288.000 173.893 2.864 + 12288.500 169.531 2.849 + 12289.000 166.180 2.775 + 12289.500 162.270 2.711 + 12290.000 156.940 2.703 + 12290.500 150.427 2.766 + 12291.000 144.401 2.795 + 12291.500 140.348 2.801 + 12292.000 137.298 2.796 + 12292.500 130.856 2.784 + 12293.000 127.333 2.775 + 12293.500 127.085 2.767 + 12294.000 132.486 2.768 + 12294.500 156.956 2.773 + 12295.000 172.435 2.763 + 12295.500 180.860 2.745 + 12296.000 181.270 2.720 + 12296.500 176.172 2.734 + 12297.000 171.994 2.751 + 12297.500 165.659 2.787 + 12298.000 162.296 2.795 + 12298.500 157.375 2.798 + 12299.000 153.528 2.794 + 12299.500 150.522 2.794 + 12300.000 119.018 2.781 + 12300.500 123.094 2.767 + 12301.000 130.398 2.775 + 12301.500 144.148 2.783 + 12302.000 150.751 2.797 + 12302.500 159.164 2.801 + 12303.000 169.412 2.806 + 12303.500 169.734 2.801 + 12304.000 172.299 2.792 + 12304.500 167.166 2.762 + 12305.000 153.933 2.755 + 12305.500 148.772 2.752 + 12306.000 142.328 2.754 + 12306.500 138.039 2.767 + 12307.000 132.676 2.778 + 12307.500 123.086 2.786 + 12308.000 128.123 2.785 + 12308.500 141.878 2.779 + 12309.000 143.569 2.775 + 12309.500 145.745 2.775 + 12310.000 140.215 2.778 + 12310.500 119.899 2.785 + 12311.000 119.868 2.799 + 12311.500 122.368 2.802 + 12312.000 138.773 2.792 + 12312.500 151.775 2.762 + 12313.000 151.928 2.730 + 12313.500 147.488 2.703 + 12314.000 145.197 2.694 + 12314.500 141.348 2.684 + 12315.000 135.078 2.691 + 12315.500 128.405 2.704 + 12316.000 127.316 2.706 + 12316.500 133.736 2.696 + 12317.000 140.094 2.686 + 12317.500 141.719 2.686 + 12318.000 141.657 2.697 + 12318.500 137.430 2.692 + 12319.000 139.003 2.686 + 12319.500 142.611 2.681 + 12320.000 148.048 2.682 + 12320.500 155.048 2.682 + 12321.000 159.906 2.668 + 12321.500 158.816 2.652 + 12322.000 159.844 2.648 + 12322.500 159.085 2.654 + 12323.000 159.053 2.657 + 12323.500 156.248 2.661 + 12324.000 151.186 2.671 + 12324.500 141.647 2.684 + 12325.000 137.344 2.681 + 12325.500 134.519 2.674 + 12326.000 133.327 2.674 + 12326.500 136.990 2.683 + 12327.000 144.421 2.681 + 12327.500 152.103 2.679 + 12328.000 157.049 2.684 + 12328.500 156.205 2.696 + 12329.000 149.674 2.707 + 12329.500 141.453 2.712 + 12330.000 140.124 2.717 + 12330.500 146.211 2.716 + 12331.000 153.484 2.697 + 12331.500 161.886 2.675 + 12332.000 166.393 2.666 + 12332.500 167.391 2.661 + 12333.000 164.492 2.680 + 12333.500 161.242 2.693 + 12334.000 157.893 2.695 + 12334.500 151.008 2.686 + 12335.000 151.775 2.681 + 12335.500 152.889 2.676 + 12336.000 155.892 2.671 + 12336.500 150.508 2.663 + 12337.000 145.467 2.663 + 12337.500 134.234 2.668 + 12338.000 132.164 2.676 + 12338.500 130.145 2.683 + 12339.000 132.029 2.685 + 12339.500 136.869 2.686 + 12340.000 139.492 2.682 + 12340.500 141.404 2.689 + 12341.000 142.261 2.693 + 12341.500 144.084 2.691 + 12342.000 149.917 2.679 + 12342.500 159.742 2.663 + 12343.000 165.143 2.657 + 12343.500 165.149 2.658 + 12344.000 154.803 2.666 + 12344.500 130.846 2.683 + 12345.000 107.764 2.689 + 12345.500 93.912 2.693 + 12346.000 84.166 2.699 + 12346.500 76.584 2.702 + 12347.000 70.822 2.707 + 12347.500 65.427 2.707 + 12348.000 66.167 2.705 + 12348.500 71.172 2.697 + 12349.000 73.645 2.693 + 12349.500 74.360 2.694 + 12350.000 73.652 2.704 + 12350.500 67.808 2.714 + 12351.000 61.888 2.720 + 12351.500 57.174 2.716 + 12352.000 52.185 2.709 + 12352.500 47.751 2.705 + 12353.000 40.174 2.701 + 12353.500 36.509 2.697 + 12354.000 35.630 2.692 + 12354.500 35.619 2.699 + 12355.000 38.651 2.707 + 12355.500 43.684 2.726 + 12356.000 46.921 2.731 + 12356.500 47.203 2.748 + 12357.000 48.130 2.752 + 12357.500 42.523 2.757 + 12358.000 38.767 2.757 + 12358.500 35.351 2.758 + 12359.000 36.042 2.758 + 12359.500 34.161 2.752 + 12360.000 33.419 2.752 + 12360.500 31.596 2.748 + 12361.000 33.472 2.737 + 12361.500 34.912 2.729 + 12362.000 38.304 2.717 + 12362.500 40.753 2.709 + 12363.000 42.816 2.713 + 12363.500 41.940 2.719 + 12364.000 41.058 2.725 + 12364.500 39.611 2.724 + 12365.000 39.773 2.722 + 12365.500 39.088 2.724 + 12366.000 39.467 2.725 + 12366.500 39.354 2.725 + 12367.000 39.655 2.722 + 12367.500 41.337 2.721 + 12368.000 42.141 2.724 + 12368.500 44.471 2.733 + 12369.000 46.021 2.736 + 12369.500 47.474 2.745 + 12370.000 48.666 2.750 + 12370.500 49.087 2.747 + 12371.000 46.923 2.723 + 12371.500 46.445 2.713 + 12372.000 46.025 2.708 + 12372.500 46.880 2.716 + 12373.000 47.567 2.729 + 12373.500 48.329 2.735 + 12374.000 49.114 2.737 + 12374.500 49.802 2.733 + 12375.000 50.586 2.726 + 12375.500 50.687 2.719 + 12376.000 52.045 2.713 + 12376.500 52.766 2.706 + 12377.000 54.185 2.697 + 12377.500 51.027 2.694 + 12378.000 48.684 2.695 + 12378.500 45.735 2.705 + 12379.000 44.263 2.714 + 12379.500 45.647 2.725 + 12380.000 51.527 2.736 + 12380.500 61.472 2.741 + 12381.000 65.975 2.741 + 12381.500 68.320 2.741 + 12382.000 71.410 2.738 + 12382.500 75.100 2.729 + 12383.000 78.373 2.710 + 12383.500 81.477 2.702 + 12384.000 83.718 2.694 + 12384.500 83.644 2.690 + 12385.000 82.434 2.686 + 12385.500 77.185 2.688 + 12386.000 73.806 2.692 + 12386.500 55.668 2.700 + 12387.000 49.539 2.708 + 12387.500 42.235 2.714 + 12388.000 37.910 2.720 + 12388.500 33.822 2.725 + 12389.000 32.500 2.726 + 12389.500 31.723 2.731 + 12390.000 31.287 2.736 + 12390.500 31.023 2.741 + 12391.000 30.314 2.743 + 12391.500 30.189 2.745 + 12392.000 30.145 2.744 + 12392.500 30.238 2.739 + 12393.000 30.098 2.732 + 12393.500 31.017 2.731 + 12394.000 32.648 2.733 + 12394.500 34.283 2.721 + 12395.000 38.568 2.715 + 12395.500 39.292 2.717 + 12396.000 40.219 2.721 + 12396.500 41.202 2.738 + 12397.000 42.735 2.741 + 12397.500 46.579 2.737 + 12398.000 47.894 2.732 + 12398.500 50.303 2.725 + 12399.000 49.778 2.724 + 12399.500 48.926 2.725 + 12400.000 48.999 2.725 + 12400.500 49.077 2.736 + 12401.000 49.018 2.740 + 12401.500 50.475 2.741 + 12402.000 53.967 2.733 + 12402.500 59.830 2.724 + 12403.000 64.346 2.716 + 12403.500 68.558 2.705 + 12404.000 72.510 2.698 + 12404.500 79.423 2.702 + 12405.000 81.866 2.708 + 12405.500 82.536 2.724 + 12406.000 81.672 2.728 + 12406.500 74.210 2.718 + 12407.000 68.265 2.708 + 12407.500 61.847 2.704 + 12408.000 51.692 2.708 + 12408.500 36.405 2.720 + 12409.000 33.037 2.729 + 12409.500 31.918 2.731 + 12410.000 31.128 2.733 + 12410.500 29.958 2.739 + 12411.000 31.062 2.739 + 12411.500 31.520 2.737 + 12412.000 32.166 2.730 + 12412.500 34.431 2.733 + 12413.000 35.678 2.735 + 12413.500 37.052 2.724 + 12414.000 38.657 2.718 + 12414.500 39.578 2.708 + 12415.000 38.716 2.712 + 12415.500 36.944 2.716 + 12416.000 36.216 2.718 + 12416.500 34.052 2.718 + 12417.000 32.482 2.722 + 12417.500 31.241 2.725 + 12418.000 29.166 2.733 + 12418.500 27.816 2.735 + 12419.000 29.064 2.728 + 12419.500 31.753 2.711 + 12420.000 36.712 2.705 + 12420.500 43.447 2.715 + 12421.000 50.543 2.732 + 12421.500 56.058 2.734 + 12422.000 60.938 2.733 + 12422.500 64.461 2.710 + 12423.000 65.547 2.701 + 12423.500 62.768 2.700 + 12424.000 57.130 2.703 + 12424.500 45.030 2.711 + 12425.000 38.018 2.723 + 12425.500 33.133 2.730 + 12426.000 30.818 2.733 + 12426.500 31.922 2.732 + 12427.000 36.376 2.732 + 12427.500 39.413 2.740 + 12428.000 43.614 2.747 + 12428.500 49.454 2.755 + 12429.000 53.720 2.755 + 12429.500 60.289 2.743 + 12430.000 60.326 2.729 + 12430.500 63.314 2.718 + 12431.000 60.633 2.707 + 12431.500 55.766 2.709 + 12432.000 48.503 2.714 + 12432.500 36.739 2.719 + 12433.000 36.878 2.715 + 12433.500 35.381 2.708 + 12434.000 38.437 2.708 + 12434.500 38.969 2.715 + 12435.000 41.713 2.720 + 12435.500 44.235 2.724 + 12436.000 47.074 2.726 + 12436.500 48.640 2.729 + 12437.000 49.120 2.736 + 12437.500 49.713 2.735 + 12438.000 49.781 2.723 + 12438.500 48.303 2.716 + 12439.000 48.125 2.714 + 12439.500 47.377 2.723 + 12440.000 46.839 2.735 + 12440.500 45.112 2.748 + 12441.000 45.670 2.743 + 12441.500 45.949 2.739 + 12442.000 45.511 2.733 + 12442.500 46.956 2.724 + 12443.000 47.982 2.719 + 12443.500 49.584 2.715 + 12444.000 51.135 2.709 + 12444.500 52.299 2.704 + 12445.000 53.924 2.702 + 12445.500 57.378 2.702 + 12446.000 62.735 2.706 + 12446.500 65.348 2.725 + 12447.000 63.638 2.735 + 12447.500 60.553 2.733 + 12448.000 54.127 2.723 + 12448.500 50.136 2.717 + 12449.000 49.594 2.728 + 12449.500 49.016 2.737 + 12450.000 48.346 2.736 + 12450.500 47.092 2.727 + 12451.000 47.132 2.715 + 12451.500 50.293 2.716 + 12452.000 57.936 2.724 + 12452.500 66.483 2.735 + 12453.000 70.331 2.741 + 12453.500 72.810 2.732 + 12454.000 74.558 2.718 + 12454.500 76.776 2.705 + 12455.000 77.463 2.702 + 12455.500 76.550 2.708 + 12456.000 74.660 2.711 + 12456.500 72.543 2.711 + 12457.000 67.743 2.716 + 12457.500 64.867 2.729 + 12458.000 53.668 2.736 + 12458.500 56.180 2.739 + 12459.000 45.013 2.736 + 12459.500 46.065 2.726 + 12460.000 48.554 2.734 + 12460.500 51.639 2.752 + 12461.000 54.465 2.757 + 12461.500 60.205 2.755 + 12462.000 66.572 2.747 + 12462.500 80.531 2.731 + 12463.000 89.708 2.735 + 12463.500 99.804 2.739 + 12464.000 109.725 2.737 + 12464.500 107.779 2.734 + 12465.000 104.235 2.722 + 12465.500 95.564 2.711 + 12466.000 84.761 2.708 + 12466.500 81.260 2.707 + 12467.000 82.585 2.707 + 12467.500 85.487 2.706 + 12468.000 86.508 2.705 + 12468.500 86.047 2.710 + 12469.000 86.108 2.717 + 12469.500 88.212 2.721 + 12470.000 87.614 2.718 + 12470.500 85.665 2.709 + 12471.000 81.522 2.709 + 12471.500 76.930 2.708 + 12472.000 78.063 2.706 + 12472.500 82.319 2.705 + 12473.000 86.056 2.705 + 12473.500 92.947 2.712 + 12474.000 88.570 2.720 + 12474.500 69.822 2.723 + 12475.000 56.291 2.719 + 12475.500 45.626 2.709 + 12476.000 43.502 2.707 + 12476.500 49.893 2.707 + 12477.000 55.994 2.704 + 12477.500 58.771 2.701 + 12478.000 55.594 2.702 + 12478.500 49.661 2.711 + 12479.000 42.671 2.733 + 12479.500 38.709 2.743 + 12480.000 35.237 2.763 + 12480.500 33.978 2.759 + 12481.000 34.289 2.750 + 12481.500 35.182 2.745 + 12482.000 37.305 2.741 + 12482.500 38.791 2.736 + 12483.000 45.501 2.732 + 12483.500 51.831 2.728 + 12484.000 52.228 2.723 + 12484.500 51.218 2.722 + 12485.000 49.085 2.728 + 12485.500 46.874 2.735 + 12486.000 44.209 2.733 + 12486.500 40.980 2.721 + 12487.000 39.552 2.720 + 12487.500 39.277 2.718 + 12488.000 40.651 2.722 + 12488.500 43.808 2.726 + 12489.000 46.562 2.724 + 12489.500 49.591 2.723 + 12490.000 50.628 2.721 + 12490.500 50.466 2.723 + 12491.000 49.672 2.726 + 12491.500 47.588 2.725 + 12492.000 46.745 2.734 + 12492.500 48.093 2.739 + 12493.000 51.232 2.744 + 12493.500 54.295 2.740 + 12494.000 54.855 2.739 + 12494.500 53.459 2.728 + 12495.000 52.358 2.725 + 12495.500 50.446 2.716 + 12496.000 49.191 2.706 + 12496.500 44.142 2.695 + 12497.000 42.078 2.696 + 12497.500 37.877 2.709 + 12498.000 35.285 2.718 + 12498.500 33.156 2.735 + 12499.000 33.383 2.738 + 12499.500 35.443 2.742 + 12500.000 38.263 2.734 + 12500.500 41.774 2.724 + 12501.000 44.994 2.714 + 12501.500 47.236 2.713 + 12502.000 51.842 2.710 + 12502.500 58.289 2.711 + 12503.000 61.619 2.712 + 12503.500 64.053 2.718 + 12504.000 63.236 2.725 + 12504.500 61.401 2.737 + 12505.000 60.166 2.736 + 12505.500 59.352 2.731 + 12506.000 59.426 2.714 + 12506.500 54.876 2.701 + 12507.000 52.237 2.701 + 12507.500 49.203 2.706 + 12508.000 48.209 2.714 + 12508.500 48.267 2.725 + 12509.000 47.704 2.734 + 12509.500 46.660 2.744 + 12510.000 42.865 2.747 + 12510.500 35.646 2.750 + 12511.000 27.406 2.755 + 12511.500 23.173 2.759 + 12512.000 21.138 2.758 + 12512.500 22.618 2.740 + 12513.000 28.903 2.728 + 12513.500 35.912 2.716 + 12514.000 43.635 2.715 + 12514.500 53.319 2.715 + 12515.000 60.048 2.709 + 12515.500 64.856 2.707 + 12516.000 67.058 2.705 + 12516.500 75.799 2.700 + 12517.000 78.752 2.694 + 12517.500 82.069 2.693 + 12518.000 80.672 2.693 + 12518.500 73.791 2.691 + 12519.000 69.844 2.685 + 12519.500 66.143 2.682 + 12520.000 65.515 2.680 + 12520.500 64.399 2.705 + 12521.000 63.723 2.716 + 12521.500 62.662 2.730 + 12522.000 62.473 2.733 + 12522.500 62.756 2.726 + 12523.000 67.071 2.719 + 12523.500 71.996 2.709 + 12524.000 76.554 2.713 + 12524.500 78.978 2.722 + 12525.000 76.907 2.730 + 12525.500 72.482 2.728 + 12526.000 69.303 2.715 + 12526.500 70.255 2.700 + 12527.000 72.934 2.687 + 12527.500 73.984 2.691 + 12528.000 73.727 2.704 + 12528.500 69.361 2.714 + 12529.000 69.562 2.720 + 12529.500 70.589 2.715 + 12530.000 73.304 2.710 + 12530.500 76.649 2.704 + 12531.000 74.370 2.703 + 12531.500 73.362 2.699 + 12532.000 53.796 2.699 + 12532.500 38.008 2.701 + 12533.000 28.229 2.702 + 12533.500 24.890 2.707 + 12534.000 25.508 2.708 + 12534.500 26.855 2.734 + 12535.000 29.901 2.745 + 12535.500 33.762 2.769 + 12536.000 34.950 2.762 + 12536.500 36.693 2.742 + 12537.000 36.390 2.736 + 12537.500 37.064 2.731 + 12538.000 38.800 2.732 + 12538.500 39.339 2.732 + 12539.000 39.459 2.736 + 12539.500 37.292 2.737 + 12540.000 36.115 2.740 + 12540.500 32.822 2.742 + 12541.000 34.820 2.741 + 12541.500 37.473 2.726 + 12542.000 40.956 2.720 + 12542.500 45.609 2.706 + 12543.000 51.202 2.707 + 12543.500 56.426 2.708 + 12544.000 60.099 2.708 + 12544.500 59.988 2.703 + 12545.000 57.949 2.703 + 12545.500 56.816 2.709 + 12546.000 57.517 2.711 + 12546.500 59.765 2.717 + 12547.000 60.067 2.716 + 12547.500 60.055 2.720 + 12548.000 58.760 2.720 + 12548.500 53.569 2.713 + 12549.000 52.370 2.708 + 12549.500 52.040 2.704 + 12550.000 50.832 2.703 + 12550.500 50.263 2.707 + 12551.000 48.348 2.717 + 12551.500 46.938 2.724 + 12552.000 42.880 2.733 + 12552.500 40.432 2.734 + 12553.000 36.674 2.735 + 12553.500 36.211 2.737 + 12554.000 34.721 2.745 + 12554.500 34.316 2.754 + 12555.000 33.947 2.758 + 12555.500 36.037 2.757 + 12556.000 41.503 2.757 + 12556.500 46.786 2.753 + 12557.000 51.784 2.750 + 12557.500 59.246 2.740 + 12558.000 63.012 2.733 + 12558.500 66.800 2.726 + 12559.000 63.351 2.719 + 12559.500 61.008 2.712 + 12560.000 58.525 2.707 + 12560.500 55.928 2.702 + 12561.000 53.819 2.705 + 12561.500 51.267 2.709 + 12562.000 47.657 2.712 + 12562.500 43.911 2.724 + 12563.000 42.178 2.733 + 12563.500 39.401 2.748 + 12564.000 36.242 2.752 + 12564.500 28.043 2.753 + 12565.000 24.023 2.752 + 12565.500 20.079 2.747 + 12566.000 23.667 2.743 + 12566.500 32.636 2.743 + 12567.000 41.685 2.742 + 12567.500 48.157 2.736 + 12568.000 60.486 2.717 + 12568.500 69.201 2.710 + 12569.000 70.826 2.715 + 12569.500 71.691 2.726 + 12570.000 75.514 2.727 + 12570.500 75.282 2.717 + 12571.000 71.913 2.700 + 12571.500 67.331 2.709 + 12572.000 64.697 2.713 + 12572.500 62.472 2.713 + 12573.000 60.885 2.714 + 12573.500 60.731 2.721 + 12574.000 60.840 2.731 + 12574.500 60.652 2.729 + 12575.000 60.827 2.724 + 12575.500 64.638 2.716 + 12576.000 73.496 2.714 + 12576.500 73.731 2.712 + 12577.000 71.836 2.713 + 12577.500 67.645 2.715 + 12578.000 66.156 2.718 + 12578.500 66.661 2.727 + 12579.000 70.275 2.742 + 12579.500 73.132 2.752 + 12580.000 73.364 2.751 + 12580.500 73.907 2.688 + 12581.000 74.920 2.693 + 12581.500 76.426 2.695 + 12582.000 77.559 2.704 + 12582.500 74.479 2.702 + 12583.000 67.382 2.683 + 12583.500 53.450 2.670 + 12584.000 41.507 2.674 + 12584.500 30.365 2.693 + 12585.000 27.302 2.711 + 12585.500 28.288 2.719 + 12586.000 31.027 2.726 + 12586.500 34.972 2.726 + 12587.000 37.655 2.733 + 12587.500 39.545 2.734 + 12588.000 40.118 2.739 + 12588.500 40.489 2.736 + 12589.000 39.917 2.734 + 12589.500 38.283 2.727 + 12590.000 38.223 2.726 + 12590.500 37.363 2.730 + 12591.000 36.199 2.737 + 12591.500 35.733 2.739 + 12592.000 37.392 2.737 + 12592.500 40.597 2.731 + 12593.000 45.367 2.727 + 12593.500 49.708 2.727 + 12594.000 54.787 2.730 + 12594.500 56.530 2.728 + 12595.000 56.327 2.721 + 12595.500 53.664 2.713 + 12596.000 51.937 2.707 + 12596.500 52.784 2.721 + 12597.000 54.445 2.729 + 12597.500 58.821 2.736 + 12598.000 60.945 2.737 + 12598.500 62.143 2.732 + 12599.000 62.420 2.722 + 12599.500 62.440 2.716 + 12600.000 63.038 2.716 + 12600.500 59.056 2.723 + 12601.000 56.551 2.731 + 12601.500 51.906 2.736 + 12602.000 50.637 2.737 + 12602.500 48.486 2.731 + 12603.000 47.689 2.723 + 12603.500 46.773 2.715 + 12604.000 46.647 2.712 + 12604.500 46.551 2.715 + 12605.000 45.661 2.720 + 12605.500 46.621 2.725 + 12606.000 46.263 2.721 + 12606.500 47.876 2.715 + 12607.000 47.545 2.709 + 12607.500 47.437 2.707 + 12608.000 47.617 2.707 + 12608.500 48.219 2.707 + 12609.000 48.879 2.708 + 12609.500 51.130 2.708 + 12610.000 53.311 2.701 + 12610.500 57.501 2.695 + 12611.000 60.204 2.692 + 12611.500 61.658 2.693 + 12612.000 61.029 2.702 + 12612.500 66.669 2.706 + 12613.000 69.839 2.706 + 12613.500 78.522 2.704 + 12614.000 82.854 2.697 + 12614.500 92.475 2.694 + 12615.000 105.197 2.717 + 12615.500 107.134 2.733 + 12616.000 111.359 2.738 + 12616.500 109.501 2.724 + 12617.000 103.886 2.685 + 12617.500 100.441 2.662 + 12618.000 96.909 2.656 + 12618.500 82.285 2.671 + 12619.000 75.328 2.687 + 12619.500 72.914 2.709 + 12620.000 74.519 2.727 + 12620.500 78.242 2.737 + 12621.000 83.370 2.713 + 12621.500 88.457 2.696 + 12622.000 94.315 2.668 + 12622.500 101.224 2.636 + 12623.000 105.820 2.614 + 12623.500 109.336 2.586 + 12624.000 104.108 2.567 + 12624.500 96.661 2.510 + 12625.000 77.753 2.459 + 12625.500 55.599 2.471 + 12626.000 43.703 2.503 + 12626.500 37.099 2.631 + 12627.000 35.706 2.691 + 12627.500 34.652 2.736 + 12628.000 32.073 2.786 + 12628.500 26.298 2.823 + 12629.000 22.841 2.845 + 12629.500 23.127 2.856 + 12630.000 30.486 2.858 + 12630.500 34.523 2.842 + 12631.000 46.113 2.839 + 12631.500 42.931 2.815 + 12632.000 70.021 2.800 + 12632.500 69.168 2.780 + 12633.000 64.661 2.775 + 12633.500 60.609 2.776 + 12634.000 60.443 2.790 + 12634.500 65.803 2.808 + 12635.000 69.062 2.801 + 12635.500 75.204 2.789 + 12636.000 75.582 2.773 + 12636.500 75.623 2.761 + 12637.000 75.796 2.747 + 12637.500 77.449 2.730 + 12638.000 82.741 2.719 + 12638.500 92.292 2.708 + 12639.000 104.762 2.707 + 12639.500 122.658 2.709 + 12640.000 129.723 2.714 + 12640.500 135.984 2.722 + 12641.000 140.363 2.731 + 12641.500 141.647 2.744 + 12642.000 143.666 2.744 + 12642.500 147.328 2.735 + 12643.000 148.176 2.731 + 12643.500 147.929 2.734 + 12644.000 145.804 2.741 + 12644.500 140.653 2.741 + 12645.000 139.203 2.740 + 12645.500 140.166 2.742 + 12646.000 142.416 2.734 + 12646.500 140.966 2.706 + 12647.000 136.316 2.699 + 12647.500 130.983 2.700 + 12648.000 130.938 2.708 + 12648.500 131.454 2.719 + 12649.000 131.207 2.718 + 12649.500 132.191 2.714 + 12650.000 118.866 2.721 + 12650.500 97.171 2.741 + 12651.000 76.886 2.772 + 12651.500 56.386 2.779 + 12652.000 45.014 2.799 + 12652.500 28.562 2.816 + 12653.000 25.745 2.832 + 12653.500 24.434 2.838 + 12654.000 23.958 2.849 + 12654.500 39.797 2.894 + 12655.000 44.483 2.919 + 12655.500 64.774 2.907 + 12656.000 77.927 2.896 + 12656.500 96.453 2.836 + 12657.000 102.322 2.790 + 12657.500 112.486 2.771 + 12658.000 118.119 2.765 + 12658.500 129.722 2.754 + 12659.000 140.451 2.737 + 12659.500 140.293 2.730 + 12660.000 120.979 2.709 + 12660.500 93.752 2.716 + 12661.000 65.674 2.764 + 12661.500 38.008 2.799 + 12662.000 19.681 2.836 + 12662.500 19.964 2.899 + 12663.000 24.699 2.919 + 12663.500 36.773 2.927 + 12664.000 48.061 2.918 + 12664.500 76.301 2.876 + 12665.000 85.051 2.850 + 12665.500 89.512 2.830 + 12666.000 96.867 2.817 + 12666.500 99.452 2.806 + 12667.000 97.014 2.804 + 12667.500 95.579 2.800 + 12668.000 102.627 2.796 + 12668.500 108.076 2.779 + 12669.000 111.057 2.764 + 12669.500 113.148 2.754 + 12670.000 106.611 2.748 + 12670.500 87.385 2.753 + 12671.000 69.719 2.765 + 12671.500 47.143 2.781 + 12672.000 42.211 2.802 + 12672.500 38.114 2.831 + 12673.000 41.565 2.832 + 12673.500 49.999 2.826 + 12674.000 86.484 2.823 + 12674.500 109.145 2.818 + 12675.000 134.185 2.795 + 12675.500 141.740 2.738 + 12676.000 145.230 2.701 + 12676.500 149.069 2.706 + 12677.000 159.806 2.728 + 12677.500 168.700 2.773 + 12678.000 174.507 2.755 + 12678.500 174.364 2.682 + 12679.000 170.564 2.612 + 12679.500 167.150 2.564 + 12680.000 165.807 2.519 + 12680.500 163.346 2.529 + 12681.000 160.996 2.538 + 12681.500 160.223 2.558 + 12682.000 160.395 2.569 + 12682.500 160.346 2.613 + 12683.000 160.426 2.638 + 12683.500 158.917 2.678 + 12684.000 158.179 2.693 + 12684.500 158.864 2.711 + 12685.000 165.470 2.717 + 12685.500 168.399 2.717 + 12686.000 163.289 2.705 + 12686.500 155.505 2.688 + 12687.000 140.239 2.689 + 12687.500 129.918 2.697 + 12688.000 122.830 2.707 + 12688.500 115.655 2.726 + 12689.000 114.590 2.735 + 12689.500 111.368 2.750 + 12690.000 105.722 2.753 + 12690.500 94.242 2.767 + 12691.000 84.415 2.775 + 12691.500 77.431 2.781 + 12692.000 56.392 2.794 + 12692.500 52.761 2.802 + 12693.000 52.406 2.813 + 12693.500 54.636 2.820 + 12694.000 58.567 2.825 + 12694.500 73.528 2.818 + 12695.000 92.230 2.810 + 12695.500 110.986 2.799 + 12696.000 128.901 2.783 + 12696.500 149.663 2.758 + 12697.000 160.172 2.740 + 12697.500 161.969 2.717 + 12698.000 163.578 2.718 + 12698.500 163.002 2.715 + 12699.000 161.058 2.707 + 12699.500 153.915 2.686 + 12700.000 144.332 2.677 + 12700.500 135.358 2.718 + 12701.000 131.814 2.734 + 12701.500 130.368 2.740 + 12702.000 124.680 2.723 + 12702.500 106.327 2.682 + 12703.000 84.710 2.654 + 12703.500 78.831 2.697 + 12704.000 54.671 2.764 + 12704.500 58.288 2.843 + 12705.000 79.657 2.856 + 12705.500 89.910 2.854 + 12706.000 104.697 2.840 + 12706.500 108.006 2.834 + 12707.000 108.911 2.836 + 12707.500 108.346 2.860 + 12708.000 117.487 2.902 + 12708.500 132.676 2.953 + 12709.000 145.039 2.935 + 12709.500 146.640 2.845 + 12710.000 149.936 2.730 + 12710.500 153.315 2.714 + 12711.000 154.019 2.763 + 12711.500 155.548 2.786 + 12712.000 155.336 2.773 + 12712.500 148.612 2.609 + 12713.000 146.243 2.613 + 12713.500 145.391 2.649 + 12714.000 147.323 2.725 + 12714.500 151.394 2.766 + 12715.000 155.960 2.754 + 12715.500 160.254 2.609 + 12716.000 163.450 2.522 + 12716.500 169.967 2.504 + 12717.000 174.587 2.571 + 12717.500 176.002 2.566 + 12718.000 174.131 2.584 + 12718.500 166.513 2.511 + 12719.000 162.811 2.264 + 12719.500 148.995 2.227 + 12720.000 135.235 2.306 + 12720.500 94.370 2.374 + 12721.000 98.572 2.696 + 12721.500 90.731 2.746 + 12722.000 86.365 2.763 + 12722.500 79.579 2.775 + 12723.000 61.754 2.791 + 12723.500 59.307 2.802 + 12724.000 58.453 2.804 + 12724.500 62.109 2.807 + 12725.000 71.306 2.804 + 12725.500 80.683 2.795 + 12726.000 90.413 2.765 + 12726.500 98.886 2.758 + 12727.000 98.945 2.735 + 12727.500 93.584 2.737 + 12728.000 88.933 2.740 + 12728.500 80.854 2.743 + 12729.000 91.383 2.758 + 12729.500 104.150 2.753 + 12730.000 115.722 2.751 + 12730.500 106.297 2.723 + 12731.000 85.252 2.714 + 12731.500 74.466 2.722 + 12732.000 61.272 2.746 + 12732.500 38.534 2.827 + 12733.000 31.890 2.852 + 12733.500 21.922 2.879 + 12734.000 22.293 2.881 + 12734.500 21.592 2.872 + 12735.000 21.840 2.855 + 12735.500 24.161 2.844 + 12736.000 23.676 2.840 + 12736.500 22.520 2.847 + 12737.000 21.795 2.855 + 12737.500 21.172 2.850 + 12738.000 19.738 2.847 + 12738.500 17.807 2.848 + 12739.000 19.213 2.856 + 12739.500 19.955 2.856 + 12740.000 20.714 2.858 + 12740.500 19.990 2.862 + 12741.000 18.941 2.862 + 12741.500 20.089 2.861 + 12742.000 24.351 2.858 + 12742.500 39.791 2.858 + 12743.000 54.264 2.853 + 12743.500 80.601 2.839 + 12744.000 106.137 2.803 + 12744.500 112.792 2.732 + 12745.000 92.833 2.705 + 12745.500 88.236 2.708 + 12746.000 77.492 2.725 + 12746.500 79.197 2.750 + 12747.000 87.192 2.773 + 12747.500 92.752 2.774 + 12748.000 87.481 2.773 + 12748.500 71.631 2.779 + 12749.000 72.414 2.786 + 12749.500 75.496 2.795 + 12750.000 79.747 2.790 + 12750.500 83.726 2.774 + 12751.000 68.490 2.760 + 12751.500 66.272 2.757 + 12752.000 63.680 2.762 + 12752.500 70.150 2.762 + 12753.000 73.719 2.754 + 12753.500 74.963 2.751 + 12754.000 71.056 2.745 + 12754.500 67.193 2.768 + 12755.000 66.134 2.776 + 12755.500 66.015 2.782 + 12756.000 68.844 2.771 + 12756.500 83.186 2.765 + 12757.000 90.405 2.747 + 12757.500 92.800 2.721 + 12758.000 97.220 2.730 + 12758.500 102.355 2.744 + 12759.000 107.469 2.749 + 12759.500 112.590 2.747 + 12760.000 117.682 2.706 + 12760.500 122.797 2.659 + 12761.000 126.766 2.660 + 12761.500 127.435 2.661 + 12762.000 128.131 2.662 + 12762.500 128.524 2.662 + 12763.000 129.120 2.657 + 12763.500 129.229 2.655 + 12764.000 128.435 2.652 + 12764.500 127.309 2.654 + 12765.000 126.380 2.659 + 12765.500 119.590 2.684 + 12766.000 109.340 2.723 + 12766.500 70.329 2.766 + 12767.000 41.280 2.785 + 12767.500 29.460 2.811 + 12768.000 18.988 2.830 + 12768.500 14.979 2.848 + 12769.000 14.090 2.852 + 12769.500 15.498 2.854 + 12770.000 16.858 2.846 + 12770.500 20.578 2.846 + 12771.000 22.445 2.853 + 12771.500 24.743 2.855 + 12772.000 24.525 2.852 + 12772.500 21.615 2.850 + 12773.000 19.312 2.852 + 12773.500 16.442 2.849 + 12774.000 15.939 2.835 + 12774.500 15.679 2.821 + 12775.000 17.833 2.808 + 12775.500 20.067 2.813 + 12776.000 21.524 2.814 + 12776.500 20.797 2.825 + 12777.000 19.477 2.825 + 12777.500 17.772 2.844 + 12778.000 16.840 2.849 + 12778.500 16.271 2.855 + 12779.000 15.525 2.854 + 12779.500 14.669 2.850 + 12780.000 14.576 2.840 + 12780.500 16.846 2.824 + 12781.000 19.249 2.807 + 12781.500 19.733 2.803 + 12782.000 19.491 2.799 + 12782.500 14.550 2.801 + 12783.000 13.106 2.809 + 12783.500 11.315 2.817 + 12784.000 11.371 2.818 + 12784.500 11.971 2.817 + 12785.000 12.132 2.814 + 12785.500 12.159 2.816 + 12786.000 12.740 2.826 + 12786.500 14.621 2.833 + 12787.000 16.372 2.860 + 12787.500 19.388 2.861 + 12788.000 22.534 2.856 + 12788.500 25.022 2.822 + 12789.000 23.573 2.826 + 12789.500 21.505 2.837 + 12790.000 20.100 2.839 + 12790.500 21.030 2.846 + 12791.000 21.797 2.850 + 12791.500 24.007 2.848 + 12792.000 24.949 2.844 + 12792.500 22.633 2.842 + 12793.000 20.327 2.841 + 12793.500 19.685 2.842 + 12794.000 18.099 2.842 + 12794.500 25.325 2.840 + 12795.000 28.030 2.834 + 12795.500 42.138 2.828 + 12796.000 43.271 2.822 + 12796.500 40.483 2.822 + 12797.000 34.979 2.822 + 12797.500 27.233 2.823 + 12798.000 22.857 2.853 + 12798.500 21.811 2.864 + 12799.000 29.602 2.864 + 12799.500 37.111 2.852 + 12800.000 45.941 2.839 + 12800.500 50.397 2.826 + 12801.000 34.819 2.808 + 12801.500 26.573 2.803 + 12802.000 20.405 2.829 + 12802.500 19.486 2.838 + 12803.000 27.275 2.840 + 12803.500 31.266 2.832 + 12804.000 88.967 2.817 + 12804.500 138.372 2.812 + 12805.000 170.582 2.786 + 12805.500 170.802 2.771 + 12806.000 174.335 2.753 + 12806.500 145.431 2.737 + 12807.000 101.109 2.709 + 12807.500 87.055 2.715 + 12808.000 73.551 2.734 + 12808.500 58.187 2.755 + 12809.000 58.081 2.770 + 12809.500 46.574 2.785 + 12810.000 42.816 2.807 + 12810.500 26.921 2.868 + 12811.000 25.328 2.873 + 12811.500 27.205 2.883 + 12812.000 32.463 2.904 + 12812.500 44.059 2.894 + 12813.000 49.620 2.884 + 12813.500 54.192 2.867 + 12814.000 53.616 2.855 + 12814.500 55.153 2.807 + 12815.000 57.931 2.814 + 12815.500 58.706 2.810 + 12816.000 54.226 2.795 + 12816.500 44.115 2.795 + 12817.000 43.964 2.801 + 12817.500 47.743 2.819 + 12818.000 62.574 2.814 + 12818.500 77.926 2.801 + 12819.000 82.262 2.790 + 12819.500 81.001 2.789 + 12820.000 70.395 2.791 + 12820.500 55.572 2.805 + 12821.000 42.930 2.806 + 12821.500 40.702 2.807 + 12822.000 40.035 2.809 + 12822.500 39.879 2.834 + 12823.000 65.145 2.830 + 12823.500 91.264 2.818 + 12824.000 163.369 2.812 + 12824.500 159.821 2.803 + 12825.000 156.945 2.739 + 12825.500 128.891 2.624 + 12826.000 101.475 2.662 + 12826.500 62.282 2.733 + 12827.000 59.106 2.761 + 12827.500 56.392 2.777 + 12828.000 108.126 2.808 + 12828.500 104.517 2.769 + 12829.000 113.809 2.752 + 12829.500 112.711 2.739 + 12830.000 100.262 2.708 + 12830.500 75.557 2.781 + 12831.000 63.237 2.842 + 12831.500 53.571 2.838 + 12832.000 53.716 2.838 + 12832.500 57.863 2.808 + 12833.000 60.869 2.802 + 12833.500 68.631 2.800 + 12834.000 81.690 2.795 + 12834.500 94.203 2.784 + 12835.000 99.807 2.769 + 12835.500 102.290 2.766 + 12836.000 109.529 2.766 + 12836.500 119.907 2.764 + 12837.000 132.031 2.752 + 12837.500 140.953 2.736 + 12838.000 143.907 2.717 + 12838.500 135.990 2.695 + 12839.000 106.617 2.699 + 12839.500 94.501 2.716 + 12840.000 62.587 2.717 + 12840.500 37.715 2.887 + 12841.000 28.753 2.877 + 12841.500 30.628 2.881 + 12842.000 34.237 2.881 + 12842.500 41.184 2.825 + 12843.000 44.145 2.830 + 12843.500 48.014 2.831 + 12844.000 48.454 2.832 + 12844.500 45.782 2.822 + 12845.000 43.426 2.816 + 12845.500 35.944 2.814 + 12846.000 33.755 2.819 + 12846.500 41.102 2.830 + 12847.000 60.397 2.830 + 12847.500 106.764 2.829 + 12848.000 122.089 2.810 + 12848.500 123.534 2.746 + 12849.000 102.978 2.744 + 12849.500 95.704 2.735 + 12850.000 71.144 2.751 + 12850.500 68.513 2.805 + 12851.000 67.634 2.798 + 12851.500 67.617 2.788 + 12852.000 65.144 2.767 + 12852.500 57.916 2.777 + 12853.000 49.242 2.806 + 12853.500 38.817 2.817 + 12854.000 32.746 2.836 + 12854.500 32.325 2.840 + 12855.000 31.176 2.835 + 12855.500 40.188 2.833 + 12856.000 56.733 2.829 + 12856.500 86.541 2.791 + 12857.000 115.978 2.777 + 12857.500 129.573 2.758 + 12858.000 126.597 2.733 + 12858.500 117.187 2.711 + 12859.000 100.373 2.718 + 12859.500 94.663 2.740 + 12860.000 83.026 2.754 + 12860.500 69.944 2.757 + 12861.000 56.660 2.764 + 12861.500 43.146 2.773 + 12862.000 29.538 2.796 + 12862.500 25.572 2.807 + 12863.000 26.010 2.830 + 12863.500 30.664 2.832 + 12864.000 30.803 2.836 + 12864.500 27.266 2.834 + 12865.000 23.869 2.834 + 12865.500 23.955 2.836 + 12866.000 25.105 2.836 + 12866.500 30.508 2.831 + 12867.000 41.323 2.829 + 12867.500 39.373 2.826 + 12868.000 52.499 2.824 + 12868.500 67.089 2.817 + 12869.000 61.172 2.809 + 12869.500 56.810 2.802 + 12870.000 26.040 2.811 + 12870.500 29.088 2.834 + 12871.000 35.026 2.843 + 12871.500 39.918 2.840 + 12872.000 65.180 2.824 + 12872.500 85.072 2.791 + 12873.000 115.520 2.751 + 12873.500 116.924 2.713 + 12874.000 108.425 2.711 + 12874.500 72.526 2.726 + 12875.000 75.651 2.760 + 12875.500 65.141 2.779 + 12876.000 62.948 2.783 + 12876.500 53.928 2.780 + 12877.000 51.509 2.767 + 12877.500 51.794 2.755 + 12878.000 54.662 2.746 + 12878.500 57.887 2.747 + 12879.000 57.333 2.751 + 12879.500 54.905 2.756 + 12880.000 52.762 2.755 + 12880.500 52.213 2.756 + 12881.000 52.134 2.750 + 12881.500 53.866 2.742 + 12882.000 54.918 2.729 + 12882.500 57.729 2.722 + 12883.000 57.467 2.722 + 12883.500 56.717 2.732 + 12884.000 57.429 2.739 + 12884.500 56.777 2.736 + 12885.000 56.177 2.730 + 12885.500 53.154 2.731 + 12886.000 50.657 2.730 + 12886.500 49.753 2.734 + 12887.000 49.928 2.735 + 12887.500 50.624 2.731 + 12888.000 50.709 2.728 + 12888.500 49.178 2.729 + 12889.000 47.412 2.733 + 12889.500 46.705 2.745 + 12890.000 46.229 2.754 + 12890.500 50.327 2.772 + 12891.000 54.889 2.763 + 12891.500 59.533 2.754 + 12892.000 58.292 2.738 + 12892.500 51.837 2.731 + 12893.000 44.072 2.737 + 12893.500 37.840 2.742 + 12894.000 32.340 2.747 + 12894.500 31.227 2.746 + 12895.000 30.779 2.746 + 12895.500 31.711 2.747 + 12896.000 35.679 2.746 + 12896.500 43.344 2.742 + 12897.000 48.373 2.732 + 12897.500 58.005 2.720 + 12898.000 65.113 2.720 + 12898.500 75.951 2.727 + 12899.000 80.339 2.731 + 12899.500 84.000 2.735 + 12900.000 86.251 2.737 + 12900.500 88.912 2.735 + 12901.000 89.778 2.730 + 12901.500 88.704 2.725 + 12902.000 84.865 2.721 + 12902.500 81.815 2.721 + 12903.000 78.745 2.719 + 12903.500 75.934 2.717 + 12904.000 73.499 2.713 + 12904.500 71.726 2.724 + 12905.000 70.097 2.732 + 12905.500 67.670 2.736 + 12906.000 64.260 2.749 + 12906.500 59.005 2.762 + 12907.000 55.586 2.768 + 12907.500 52.159 2.769 + 12908.000 50.279 2.766 + 12908.500 47.449 2.777 + 12909.000 47.216 2.783 + 12909.500 48.861 2.781 + 12910.000 48.777 2.762 + 12910.500 52.447 2.739 + 12911.000 52.192 2.734 + 12911.500 54.563 2.728 + 12912.000 55.086 2.726 + 12912.500 56.903 2.722 + 12913.000 53.983 2.720 + 12913.500 52.184 2.719 + 12914.000 50.688 2.712 + 12914.500 50.041 2.712 + 12915.000 49.699 2.719 + 12915.500 50.350 2.728 + 12916.000 51.506 2.731 + 12916.500 53.171 2.725 + 12917.000 52.174 2.711 + 12917.500 50.552 2.705 + 12918.000 49.115 2.706 + 12918.500 49.263 2.721 + 12919.000 49.760 2.730 + 12919.500 52.225 2.727 + 12920.000 52.636 2.721 + 12920.500 53.717 2.719 + 12921.000 52.312 2.722 + 12921.500 49.372 2.734 + 12922.000 46.621 2.737 + 12922.500 42.694 2.746 + 12923.000 42.770 2.745 + 12923.500 41.669 2.744 + 12924.000 41.415 2.742 + 12924.500 40.267 2.740 + 12925.000 40.429 2.737 + 12925.500 40.433 2.732 + 12926.000 39.774 2.731 + 12926.500 39.061 2.733 + 12927.000 38.237 2.736 + 12927.500 37.816 2.738 + 12928.000 39.370 2.742 + 12928.500 39.179 2.746 + 12929.000 39.020 2.743 + 12929.500 36.981 2.737 + 12930.000 37.393 2.738 + 12930.500 39.778 2.733 + 12931.000 42.001 2.732 + 12931.500 41.875 2.738 + 12932.000 41.705 2.748 + 12932.500 40.291 2.761 + 12933.000 40.284 2.766 + 12933.500 41.674 2.766 + 12934.000 41.981 2.767 + 12934.500 41.969 2.745 + 12935.000 41.854 2.739 + 12935.500 40.614 2.733 + 12936.000 38.892 2.744 + 12936.500 36.919 2.751 + 12937.000 36.249 2.750 + 12937.500 35.735 2.736 + 12938.000 34.904 2.721 + 12938.500 33.983 2.717 + 12939.000 34.214 2.721 + 12939.500 33.548 2.732 + 12940.000 34.845 2.736 + 12940.500 34.728 2.737 + 12941.000 35.922 2.725 + 12941.500 37.695 2.718 + 12942.000 39.185 2.717 + 12942.500 41.218 2.718 + 12943.000 42.716 2.725 + 12943.500 44.385 2.727 + 12944.000 45.214 2.729 + 12944.500 44.500 2.721 + 12945.000 43.737 2.720 + 12945.500 41.811 2.725 + 12946.000 41.697 2.728 + 12946.500 40.432 2.747 + 12947.000 41.048 2.752 + 12947.500 43.379 2.749 + 12948.000 45.344 2.744 + 12948.500 48.493 2.746 + 12949.000 49.190 2.746 + 12949.500 49.802 2.750 + 12950.000 50.365 2.750 + 12950.500 50.104 2.756 + 12951.000 49.704 2.760 + 12951.500 48.888 2.756 + 12952.000 49.210 2.751 + 12952.500 47.650 2.744 + 12953.000 46.483 2.738 + 12953.500 47.301 2.737 + 12954.000 48.234 2.733 + 12954.500 48.775 2.731 + 12955.000 46.865 2.730 + 12955.500 42.564 2.733 + 12956.000 40.444 2.736 + 12956.500 38.514 2.742 + 12957.000 36.924 2.740 + 12957.500 37.080 2.740 + 12958.000 37.331 2.738 + 12958.500 40.788 2.731 + 12959.000 43.207 2.727 + 12959.500 47.382 2.729 + 12960.000 48.848 2.735 + 12960.500 48.687 2.741 + 12961.000 46.099 2.748 + 12961.500 43.598 2.751 + 12962.000 39.946 2.753 + 12962.500 38.733 2.749 + 12963.000 37.168 2.736 + 12963.500 38.791 2.737 + 12964.000 40.908 2.734 + 12964.500 41.816 2.730 + 12965.000 42.892 2.731 + 12965.500 40.757 2.731 + 12966.000 40.659 2.729 + 12966.500 40.514 2.740 + 12967.000 41.178 2.748 + 12967.500 41.789 2.751 + 12968.000 41.985 2.750 + 12968.500 41.423 2.744 + 12969.000 40.547 2.725 + 12969.500 40.291 2.729 + 12970.000 41.018 2.730 + 12970.500 41.602 2.732 + 12971.000 41.981 2.729 + 12971.500 44.200 2.734 + 12972.000 45.691 2.741 + 12972.500 48.975 2.750 + 12973.000 50.703 2.764 + 12973.500 50.615 2.753 + 12974.000 50.589 2.749 + 12974.500 51.367 2.740 + 12975.000 52.032 2.729 + 12975.500 52.840 2.725 + 12976.000 53.082 2.721 + 12976.500 51.695 2.721 + 12977.000 50.869 2.717 + 12977.500 49.969 2.714 + 12978.000 51.348 2.719 + 12978.500 52.792 2.727 + 12979.000 53.663 2.744 + 12979.500 52.931 2.738 + 12980.000 52.252 2.730 + 12980.500 51.003 2.723 + 12981.000 49.233 2.716 + 12981.500 48.372 2.712 + 12982.000 48.158 2.706 + 12982.500 48.484 2.706 + 12983.000 50.239 2.716 + 12983.500 52.874 2.736 + 12984.000 57.541 2.745 + 12984.500 59.566 2.754 + 12985.000 67.668 2.745 + 12985.500 75.068 2.738 + 12986.000 78.146 2.729 + 12986.500 80.475 2.732 + 12987.000 82.270 2.734 + 12987.500 81.048 2.739 + 12988.000 79.902 2.749 + 12988.500 72.883 2.727 + 12989.000 68.601 2.714 + 12989.500 57.046 2.683 + 12990.000 52.655 2.679 + 12990.500 42.183 2.709 + 12991.000 35.777 2.725 + 12991.500 33.917 2.744 + 12992.000 32.286 2.753 + 12992.500 30.731 2.754 + 12993.000 31.610 2.756 + 12993.500 31.929 2.756 + 12994.000 32.447 2.759 + 12994.500 33.827 2.755 + 12995.000 34.103 2.751 + 12995.500 35.903 2.745 + 12996.000 36.757 2.739 + 12996.500 40.482 2.723 + 12997.000 41.294 2.715 + 12997.500 40.493 2.718 + 12998.000 40.355 2.735 + 12998.500 37.997 2.744 + 12999.000 36.070 2.741 + 12999.500 32.319 2.734 + 13000.000 30.958 2.731 + 13000.500 29.051 2.733 + 13001.000 28.770 2.738 + 13001.500 29.719 2.743 + 13002.000 29.838 2.750 + 13002.500 35.936 2.745 + 13003.000 40.855 2.747 + 13003.500 44.147 2.744 + 13004.000 50.758 2.737 + 13004.500 56.460 2.734 + 13005.000 59.026 2.728 + 13005.500 61.634 2.722 + 13006.000 64.691 2.712 + 13006.500 65.659 2.701 + 13007.000 63.912 2.703 + 13007.500 61.490 2.707 + 13008.000 45.509 2.731 + 13008.500 38.307 2.738 + 13009.000 33.914 2.741 + 13009.500 33.448 2.743 + 13010.000 34.851 2.756 + 13010.500 40.809 2.751 + 13011.000 44.505 2.744 + 13011.500 49.118 2.731 + 13012.000 56.753 2.730 + 13012.500 63.772 2.730 + 13013.000 67.943 2.729 + 13013.500 67.523 2.729 + 13014.000 62.778 2.733 + 13014.500 53.691 2.736 + 13015.000 40.640 2.740 + 13015.500 39.337 2.737 + 13016.000 37.302 2.736 + 13016.500 38.012 2.730 + 13017.000 39.999 2.725 + 13017.500 40.004 2.726 + 13018.000 41.770 2.728 + 13018.500 44.954 2.740 + 13019.000 45.168 2.747 + 13019.500 46.728 2.753 + 13020.000 47.768 2.753 + 13020.500 48.177 2.760 + 13021.000 49.384 2.773 + 13021.500 49.275 2.778 + 13022.000 48.389 2.776 + 13022.500 45.765 2.762 + 13023.000 44.207 2.756 + 13023.500 44.417 2.755 + 13024.000 45.639 2.753 + 13024.500 46.771 2.750 + 13025.000 47.663 2.744 + 13025.500 48.463 2.738 + 13026.000 48.799 2.736 + 13026.500 47.938 2.742 + 13027.000 47.324 2.743 + 13027.500 47.773 2.733 + 13028.000 48.520 2.723 + 13028.500 49.907 2.709 + 13029.000 50.646 2.706 + 13029.500 53.041 2.705 + 13030.000 54.229 2.709 + 13030.500 59.139 2.714 + 13031.000 62.175 2.715 + 13031.500 61.791 2.711 + 13032.000 59.895 2.718 + 13032.500 57.384 2.728 + 13033.000 55.362 2.747 + 13033.500 52.830 2.746 + 13034.000 51.054 2.733 + 13034.500 48.845 2.725 + 13035.000 49.753 2.717 + 13035.500 52.770 2.725 + 13036.000 56.209 2.733 + 13036.500 66.216 2.734 + 13037.000 73.166 2.734 + 13037.500 79.388 2.725 + 13038.000 80.586 2.721 + 13038.500 80.271 2.722 + 13039.000 80.762 2.726 + 13039.500 80.668 2.727 + 13040.000 79.548 2.721 + 13040.500 82.269 2.714 + 13041.000 73.268 2.707 + 13041.500 68.777 2.706 + 13042.000 58.063 2.708 + 13042.500 49.365 2.712 + 13043.000 46.302 2.722 + 13043.500 47.453 2.729 + 13044.000 50.131 2.733 + 13044.500 52.709 2.731 + 13045.000 56.362 2.728 + 13045.500 64.436 2.732 + 13046.000 68.948 2.734 + 13046.500 87.471 2.738 + 13047.000 100.530 2.741 + 13047.500 108.655 2.740 + 13048.000 111.131 2.735 + 13048.500 108.044 2.720 + 13049.000 104.099 2.714 + 13049.500 99.510 2.705 + 13050.000 93.618 2.700 + 13050.500 88.980 2.697 + 13051.000 86.585 2.701 + 13051.500 89.721 2.707 + 13052.000 91.970 2.714 + 13052.500 93.252 2.710 + 13053.000 93.211 2.710 + 13053.500 92.022 2.713 + 13054.000 89.818 2.714 + 13054.500 87.384 2.706 + 13055.000 84.153 2.695 + 13055.500 82.141 2.698 + 13056.000 82.106 2.703 + 13056.500 86.141 2.706 + 13057.000 88.203 2.706 + 13057.500 82.955 2.710 + 13058.000 79.544 2.714 + 13058.500 48.628 2.723 + 13059.000 50.522 2.727 + 13059.500 50.015 2.733 + 13060.000 52.934 2.739 + 13060.500 55.313 2.738 + 13061.000 57.803 2.735 + 13061.500 53.537 2.731 + 13062.000 49.974 2.731 + 13062.500 42.911 2.733 + 13063.000 40.536 2.739 + 13063.500 39.709 2.745 + 13064.000 39.683 2.755 + 13064.500 41.396 2.757 + 13065.000 42.766 2.750 + 13065.500 44.015 2.739 + 13066.000 45.804 2.726 + 13066.500 46.095 2.719 + 13067.000 46.564 2.715 + 13067.500 45.521 2.721 + 13068.000 43.579 2.734 + 13068.500 41.257 2.743 + 13069.000 40.298 2.752 + 13069.500 41.802 2.754 + 13070.000 44.454 2.745 + 13070.500 45.789 2.739 + 13071.000 48.574 2.724 + 13071.500 48.161 2.706 + 13072.000 47.970 2.696 + 13072.500 45.992 2.698 + 13073.000 45.127 2.705 + 13073.500 44.235 2.720 + 13074.000 44.513 2.729 + 13074.500 46.974 2.733 + 13075.000 48.845 2.732 + 13075.500 49.870 2.726 + 13076.000 49.888 2.718 + 13076.500 48.462 2.709 + 13077.000 46.790 2.714 + 13077.500 46.500 2.720 + 13078.000 48.052 2.725 + 13078.500 49.829 2.725 + 13079.000 50.714 2.724 + 13079.500 50.750 2.724 + 13080.000 51.817 2.724 + 13080.500 54.095 2.735 + 13081.000 54.080 2.742 + 13081.500 49.859 2.733 + 13082.000 46.539 2.713 + 13082.500 40.770 2.703 + 13083.000 38.959 2.702 + 13083.500 36.426 2.714 + 13084.000 36.890 2.721 + 13084.500 36.950 2.740 + 13085.000 38.746 2.745 + 13085.500 40.525 2.743 + 13086.000 43.029 2.736 + 13086.500 41.674 2.729 + 13087.000 47.376 2.725 + 13087.500 51.024 2.725 + 13088.000 55.412 2.731 + 13088.500 60.759 2.734 + 13089.000 64.506 2.730 + 13089.500 65.718 2.721 + 13090.000 66.341 2.711 + 13090.500 64.462 2.709 + 13091.000 62.321 2.710 + 13091.500 60.623 2.716 + 13092.000 58.674 2.723 + 13092.500 54.046 2.728 + 13093.000 50.510 2.727 + 13093.500 48.296 2.723 + 13094.000 45.682 2.723 + 13094.500 42.625 2.746 + 13095.000 41.399 2.757 + 13095.500 35.348 2.759 + 13096.000 32.305 2.758 + 13096.500 30.853 2.760 + 13097.000 35.596 2.760 + 13097.500 40.589 2.757 + 13098.000 54.915 2.752 + 13098.500 70.177 2.738 + 13099.000 79.354 2.723 + 13099.500 81.873 2.713 + 13100.000 79.736 2.711 + 13100.500 76.737 2.712 + 13101.000 70.934 2.713 + 13101.500 65.808 2.718 + 13102.000 60.430 2.726 + 13102.500 61.189 2.732 + 13103.000 61.975 2.738 + 13103.500 63.851 2.744 + 13104.000 64.486 2.756 + 13104.500 67.440 2.753 + 13105.000 70.787 2.742 + 13105.500 73.154 2.724 + 13106.000 73.278 2.716 + 13106.500 73.513 2.712 + 13107.000 74.381 2.718 + 13107.500 75.043 2.723 + 13108.000 76.405 2.724 + 13108.500 77.029 2.713 + 13109.000 77.813 2.705 + 13109.500 79.683 2.703 + 13110.000 78.650 2.709 + 13110.500 72.866 2.717 + 13111.000 63.189 2.723 + 13111.500 56.766 2.722 + 13112.000 48.567 2.714 + 13112.500 39.901 2.706 + 13113.000 35.411 2.702 + 13113.500 37.076 2.708 + 13114.000 38.642 2.718 + 13114.500 41.507 2.726 + 13115.000 42.726 2.725 + 13115.500 43.529 2.727 + 13116.000 44.244 2.732 + 13116.500 43.193 2.746 + 13117.000 41.480 2.745 + 13117.500 40.151 2.744 + 13118.000 39.021 2.745 + 13118.500 38.133 2.745 + 13119.000 37.999 2.741 + 13119.500 36.450 2.733 + 13120.000 36.215 2.728 + 13120.500 35.387 2.729 + 13121.000 36.567 2.729 + 13121.500 38.657 2.727 + 13122.000 37.764 2.726 + 13122.500 53.081 2.718 + 13123.000 56.405 2.714 + 13123.500 58.411 2.711 + 13124.000 59.679 2.716 + 13124.500 55.797 2.717 + 13125.000 52.493 2.720 + 13125.500 51.193 2.724 + 13126.000 51.973 2.733 + 13126.500 55.541 2.744 + 13127.000 58.278 2.750 + 13127.500 60.188 2.745 + 13128.000 62.552 2.739 + 13128.500 66.879 2.736 + 13129.000 69.270 2.729 + 13129.500 67.000 2.728 + 13130.000 63.231 2.745 + 13130.500 57.812 2.755 + 13131.000 53.000 2.755 + 13131.500 51.312 2.752 + 13132.000 51.357 2.743 + 13132.500 50.116 2.738 + 13133.000 48.201 2.731 + 13133.500 46.359 2.727 + 13134.000 45.898 2.722 + 13134.500 47.399 2.720 + 13135.000 49.825 2.727 + 13135.500 51.626 2.733 + 13136.000 52.257 2.737 + 13136.500 52.076 2.732 + 13137.000 52.035 2.720 + 13137.500 53.743 2.714 + 13138.000 55.675 2.709 + 13138.500 60.820 2.703 + 13139.000 61.187 2.700 + 13139.500 63.165 2.703 + 13140.000 64.183 2.710 + 13140.500 68.046 2.726 + 13141.000 70.893 2.724 + 13141.500 73.719 2.708 + 13142.000 95.325 2.708 + 13142.500 105.394 2.710 + 13143.000 119.276 2.721 + 13143.500 122.802 2.729 + 13144.000 125.053 2.731 + 13144.500 121.194 2.726 + 13145.000 115.620 2.716 + 13145.500 110.650 2.704 + 13146.000 105.314 2.700 + 13146.500 99.035 2.703 + 13147.000 93.472 2.705 + 13147.500 91.238 2.703 + 13148.000 91.568 2.703 + 13148.500 93.349 2.707 + 13149.000 98.674 2.707 + 13149.500 107.083 2.703 + 13150.000 113.469 2.714 + 13150.500 123.704 2.787 + 13151.000 123.126 2.765 + 13151.500 118.206 2.753 + 13152.000 108.757 2.698 + 13152.500 83.445 2.667 + 13153.000 63.789 2.677 + 13153.500 49.279 2.696 + 13154.000 42.041 2.708 + 13154.500 40.682 2.721 + 13155.000 40.835 2.739 + 13155.500 38.367 2.754 + 13156.000 35.439 2.766 + 13156.500 32.144 2.796 + 13157.000 32.093 2.816 + 13157.500 34.919 2.820 + 13158.000 40.928 2.820 + 13158.500 58.064 2.812 + 13159.000 66.279 2.809 + 13159.500 72.522 2.799 + 13160.000 72.783 2.786 + 13160.500 69.243 2.800 + 13161.000 67.988 2.810 + 13161.500 67.239 2.822 + 13162.000 65.979 2.827 + 13162.500 62.659 2.803 + 13163.000 62.402 2.792 + 13163.500 63.865 2.793 + 13164.000 67.075 2.800 + 13164.500 73.310 2.787 + 13165.000 75.979 2.770 + 13165.500 79.014 2.737 + 13166.000 81.948 2.731 + 13166.500 86.898 2.738 + 13167.000 95.810 2.749 + 13167.500 110.511 2.753 + 13168.000 125.170 2.749 + 13168.500 140.562 2.724 + 13169.000 151.049 2.695 + 13169.500 153.659 2.696 + 13170.000 151.626 2.712 + 13170.500 145.631 2.724 + 13171.000 140.048 2.733 + 13171.500 139.312 2.731 + 13172.000 142.261 2.729 + 13172.500 150.604 2.722 + 13173.000 152.506 2.700 + 13173.500 153.448 2.703 + 13174.000 152.570 2.721 + 13174.500 150.257 2.748 + 13175.000 150.283 2.754 + 13175.500 150.643 2.766 + 13176.000 152.269 2.802 + 13176.500 152.263 2.793 + 13177.000 149.082 2.766 + 13177.500 145.334 2.699 + 13178.000 140.904 2.686 + 13178.500 135.556 2.704 + 13179.000 133.435 2.720 + 13179.500 132.765 2.735 + 13180.000 127.989 2.735 + 13180.500 120.594 2.733 + 13181.000 113.333 2.730 + 13181.500 97.399 2.733 + 13182.000 79.485 2.736 + 13182.500 50.712 2.770 + 13183.000 37.065 2.801 + 13183.500 27.892 2.834 + 13184.000 26.543 2.854 + 13184.500 21.545 2.883 + 13185.000 18.460 2.909 + 13185.500 15.128 2.927 + 13186.000 14.853 2.938 + 13186.500 19.314 2.941 + 13187.000 30.388 2.930 + 13187.500 40.302 2.914 + 13188.000 80.875 2.867 + 13188.500 76.191 2.843 + 13189.000 80.291 2.811 + 13189.500 85.183 2.799 + 13190.000 90.113 2.788 + 13190.500 94.512 2.778 + 13191.000 97.227 2.779 + 13191.500 98.516 2.779 + 13192.000 100.712 2.784 + 13192.500 102.172 2.777 + 13193.000 106.758 2.764 + 13193.500 109.168 2.753 + 13194.000 113.660 2.753 + 13194.500 116.627 2.745 + 13195.000 116.861 2.738 + 13195.500 104.173 2.733 + 13196.000 94.113 2.737 + 13196.500 59.695 2.762 + 13197.000 45.746 2.780 + 13197.500 43.143 2.814 + 13198.000 45.903 2.829 + 13198.500 77.499 2.831 + 13199.000 92.241 2.830 + 13199.500 115.989 2.822 + 13200.000 150.523 2.742 + 13200.500 171.675 2.663 + 13201.000 168.191 2.640 + 13201.500 152.685 2.606 + 13202.000 127.749 2.615 + 13202.500 127.004 2.688 + 13203.000 122.355 2.762 + 13203.500 131.946 2.750 + 13204.000 142.363 2.816 + 13204.500 159.593 2.777 + 13205.000 163.878 2.715 + 13205.500 165.836 2.689 + 13206.000 166.001 2.665 + 13206.500 165.114 2.677 + 13207.000 165.747 2.689 + 13207.500 167.285 2.705 + 13208.000 168.475 2.702 + 13208.500 167.835 2.694 + 13209.000 162.854 2.685 + 13209.500 160.502 2.679 + 13210.000 137.985 2.683 + 13210.500 117.056 2.700 + 13211.000 113.038 2.721 + 13211.500 111.293 2.743 + 13212.000 108.878 2.763 + 13212.500 98.427 2.763 + 13213.000 85.441 2.754 + 13213.500 71.054 2.755 + 13214.000 65.816 2.749 + 13214.500 62.594 2.787 + 13215.000 75.257 2.812 + 13215.500 101.492 2.844 + 13216.000 111.877 2.848 + 13216.500 145.910 2.830 + 13217.000 154.750 2.825 + 13217.500 170.943 2.731 + 13218.000 173.493 2.694 + 13218.500 176.052 2.681 + 13219.000 178.223 2.686 + 13219.500 180.774 2.701 + 13220.000 180.734 2.710 + 13220.500 168.625 2.714 + 13221.000 158.882 2.724 + 13221.500 148.152 2.743 + 13222.000 136.814 2.763 + 13222.500 131.414 2.785 + 13223.000 122.778 2.788 + 13223.500 110.888 2.774 + 13224.000 92.173 2.768 + 13224.500 73.837 2.779 + 13225.000 64.625 2.795 + 13225.500 64.955 2.809 + 13226.000 67.426 2.817 + 13226.500 88.460 2.837 + 13227.000 100.474 2.846 + 13227.500 118.083 2.840 + 13228.000 122.647 2.813 + 13228.500 122.361 2.804 + 13229.000 119.059 2.794 + 13229.500 117.300 2.792 + 13230.000 121.690 2.801 + 13230.500 140.488 2.803 + 13231.000 143.469 2.800 + 13231.500 152.364 2.782 + 13232.000 155.146 2.743 + 13232.500 156.522 2.755 + 13233.000 156.830 2.782 + 13233.500 157.044 2.751 + 13234.000 154.968 2.737 + 13234.500 147.532 2.724 + 13235.000 141.427 2.715 + 13235.500 140.110 2.747 + 13236.000 140.115 2.764 + 13236.500 148.091 2.780 + 13237.000 156.568 2.790 + 13237.500 166.712 2.769 + 13238.000 173.604 2.728 + 13238.500 181.232 2.692 + 13239.000 182.683 2.674 + 13239.500 187.428 2.665 + 13240.000 190.635 2.633 + 13240.500 190.690 2.645 + 13241.000 187.826 2.656 + 13241.500 184.470 2.661 + 13242.000 180.584 2.626 + 13242.500 174.149 2.606 + 13243.000 166.502 2.666 + 13243.500 160.587 2.719 + 13244.000 146.870 2.706 + 13244.500 129.797 2.688 + 13245.000 110.629 2.668 + 13245.500 95.711 2.687 + 13246.000 71.954 2.719 + 13246.500 69.341 2.809 + 13247.000 63.425 2.803 + 13247.500 59.473 2.799 + 13248.000 55.015 2.797 + 13248.500 60.580 2.804 + 13249.000 66.230 2.801 + 13249.500 71.284 2.790 + 13250.000 92.740 2.777 + 13250.500 101.758 2.762 + 13251.000 109.686 2.737 + 13251.500 113.182 2.738 + 13252.000 114.035 2.732 + 13252.500 109.098 2.731 + 13253.000 87.765 2.731 + 13253.500 86.492 2.756 + 13254.000 82.967 2.770 + 13254.500 103.039 2.787 + 13255.000 122.258 2.759 + 13255.500 129.505 2.752 + 13256.000 131.109 2.719 + 13256.500 93.186 2.711 + 13257.000 100.197 2.710 + 13257.500 68.095 2.746 + 13258.000 58.778 2.764 + 13258.500 39.688 2.831 + 13259.000 33.873 2.849 + 13259.500 26.444 2.862 + 13260.000 23.883 2.859 + 13260.500 19.012 2.853 + 13261.000 17.288 2.850 + 13261.500 17.672 2.861 + 13262.000 17.553 2.872 + 13262.500 19.977 2.877 + 13263.000 35.756 2.869 + 13263.500 45.149 2.861 + 13264.000 86.766 2.815 + 13264.500 100.461 2.759 + 13265.000 117.669 2.735 + 13265.500 112.831 2.716 + 13266.000 87.893 2.708 + 13266.500 72.869 2.760 + 13267.000 44.655 2.801 + 13267.500 34.648 2.823 + 13268.000 29.062 2.833 + 13268.500 22.753 2.836 + 13269.000 21.598 2.840 + 13269.500 21.045 2.851 + 13270.000 20.888 2.857 + 13270.500 20.771 2.851 + 13271.000 20.751 2.845 + 13271.500 20.886 2.837 + 13272.000 20.079 2.839 + 13272.500 20.061 2.850 + 13273.000 20.243 2.852 + 13273.500 21.689 2.852 + 13274.000 21.850 2.852 + 13274.500 20.504 2.854 + 13275.000 17.438 2.855 + 13275.500 14.646 2.860 + 13276.000 14.543 2.866 + 13276.500 15.974 2.883 + 13277.000 18.231 2.880 + 13277.500 19.534 2.879 + 13278.000 26.105 2.872 + 13278.500 29.123 2.860 + 13279.000 46.645 2.858 + 13279.500 60.406 2.856 + 13280.000 89.516 2.829 + 13280.500 111.816 2.792 + 13281.000 110.186 2.761 + 13281.500 105.570 2.748 + 13282.000 92.878 2.754 + 13282.500 81.003 2.769 + 13283.000 76.843 2.782 + 13283.500 69.984 2.796 + 13284.000 67.897 2.806 + 13284.500 63.946 2.805 + 13285.000 62.424 2.796 + 13285.500 61.068 2.791 + 13286.000 59.992 2.785 + 13286.500 64.380 2.796 + 13287.000 66.638 2.816 + 13287.500 70.651 2.820 + 13288.000 74.089 2.820 + 13288.500 80.586 2.814 + 13289.000 93.123 2.808 + 13289.500 101.184 2.798 + 13290.000 101.116 2.777 + 13290.500 98.258 2.732 + 13291.000 100.985 2.721 + 13291.500 102.974 2.712 + 13292.000 103.973 2.700 + 13292.500 130.457 2.676 + 13293.000 127.397 2.661 + 13293.500 121.965 2.658 + 13294.000 120.246 2.666 + 13294.500 124.967 2.680 + 13295.000 130.812 2.683 + 13295.500 146.448 2.671 + 13296.000 150.736 2.665 + 13296.500 149.262 2.665 + 13297.000 138.391 2.666 + 13297.500 108.943 2.676 + 13298.000 96.757 2.692 + 13298.500 56.419 2.738 + 13299.000 46.018 2.781 + 13299.500 26.778 2.805 + 13300.000 22.618 2.818 + 13300.500 21.511 2.831 + 13301.000 19.622 2.846 + 13301.500 21.573 2.857 + 13302.000 22.275 2.862 + 13302.500 22.590 2.854 + 13303.000 19.330 2.837 + 13303.500 18.044 2.834 + 13304.000 15.181 2.832 + 13304.500 16.040 2.827 + 13305.000 16.329 2.822 + 13305.500 17.346 2.817 + 13306.000 18.148 2.813 + 13306.500 19.831 2.821 + 13307.000 20.762 2.828 + 13307.500 20.077 2.848 + 13308.000 17.380 2.854 + 13308.500 13.619 2.842 + 13309.000 13.138 2.825 + 13309.500 13.089 2.824 + 13310.000 14.015 2.832 + 13310.500 16.989 2.845 + 13311.000 19.573 2.861 + 13311.500 21.168 2.869 + 13312.000 22.426 2.858 + 13312.500 22.677 2.849 + 13313.000 21.837 2.826 + 13313.500 22.586 2.830 + 13314.000 23.295 2.832 + 13314.500 24.097 2.835 + 13315.000 24.730 2.836 + 13315.500 24.941 2.836 + 13316.000 23.897 2.837 + 13316.500 19.129 2.845 + 13317.000 18.216 2.850 + 13317.500 20.754 2.849 + 13318.000 28.423 2.844 + 13318.500 35.713 2.835 + 13319.000 33.294 2.830 + 13319.500 29.159 2.824 + 13320.000 24.266 2.829 + 13320.500 18.751 2.851 + 13321.000 18.584 2.869 + 13321.500 18.651 2.870 + 13322.000 29.550 2.857 + 13322.500 60.579 2.842 + 13323.000 82.008 2.822 + 13323.500 118.578 2.807 + 13324.000 142.506 2.792 + 13324.500 166.953 2.793 + 13325.000 182.519 2.793 + 13325.500 180.679 2.772 + 13326.000 156.307 2.715 + 13326.500 126.778 2.678 + 13327.000 98.464 2.711 + 13327.500 62.122 2.756 + 13328.000 52.373 2.819 + 13328.500 28.743 2.863 + 13329.000 28.040 2.875 + 13329.500 24.298 2.877 + 13330.000 29.285 2.872 + 13330.500 40.842 2.858 + 13331.000 47.845 2.848 + 13331.500 48.126 2.837 + 13332.000 51.426 2.830 + 13332.500 52.927 2.824 + 13333.000 52.978 2.821 + 13333.500 51.390 2.814 + 13334.000 48.510 2.808 + 13334.500 42.016 2.813 + 13335.000 43.655 2.832 + 13335.500 56.602 2.852 + 13336.000 75.776 2.859 + 13336.500 98.239 2.827 + 13337.000 105.227 2.793 + 13337.500 102.315 2.758 + 13338.000 85.274 2.767 + 13338.500 52.730 2.806 + 13339.000 34.684 2.823 + 13339.500 26.039 2.849 + 13340.000 23.574 2.856 + 13340.500 29.621 2.872 + 13341.000 34.304 2.883 + 13341.500 74.135 2.890 + 13342.000 104.956 2.871 + 13342.500 129.211 2.837 + 13343.000 151.238 2.786 + 13343.500 155.923 2.772 + 13344.000 139.773 2.735 + 13344.500 126.200 2.658 + 13345.000 72.797 2.631 + 13345.500 42.488 2.649 + 13346.000 49.231 2.711 + 13346.500 65.941 2.809 + 13347.000 83.697 2.823 + 13347.500 102.965 2.794 + 13348.000 120.829 2.767 + 13348.500 95.247 2.711 + 13349.000 81.231 2.723 + 13349.500 72.590 2.746 + 13350.000 69.921 2.776 + 13350.500 68.749 2.793 + 13351.000 67.332 2.796 + 13351.500 65.863 2.800 + 13352.000 63.294 2.802 + 13352.500 58.169 2.802 + 13353.000 50.452 2.803 + 13353.500 46.062 2.805 + 13354.000 37.056 2.809 + 13354.500 30.588 2.854 + 13355.000 26.331 2.874 + 13355.500 21.091 2.888 + 13356.000 21.062 2.897 + 13356.500 23.906 2.900 + 13357.000 45.271 2.900 + 13357.500 95.456 2.884 + 13358.000 77.799 2.860 + 13358.500 143.926 2.768 + 13359.000 137.846 2.780 + 13359.500 151.671 2.791 + 13360.000 155.894 2.784 + 13360.500 142.813 2.694 + 13361.000 101.405 2.645 + 13361.500 68.602 2.663 + 13362.000 47.426 2.692 + 13362.500 37.083 2.812 + 13363.000 41.125 2.848 + 13363.500 52.721 2.861 + 13364.000 69.030 2.851 + 13364.500 112.333 2.786 + 13365.000 124.366 2.760 + 13365.500 135.824 2.752 + 13366.000 121.195 2.748 + 13366.500 98.331 2.759 + 13367.000 64.503 2.778 + 13367.500 67.104 2.796 + 13368.000 73.133 2.793 + 13368.500 86.218 2.777 + 13369.000 93.126 2.759 + 13369.500 99.669 2.758 + 13370.000 109.415 2.757 + 13370.500 116.139 2.751 + 13371.000 125.283 2.742 + 13371.500 143.758 2.733 + 13372.000 150.157 2.728 + 13372.500 152.106 2.720 + 13373.000 146.670 2.717 + 13373.500 133.849 2.719 + 13374.000 83.463 2.736 + 13374.500 50.927 2.767 + 13375.000 37.287 2.818 + 13375.500 37.939 2.848 + 13376.000 39.698 2.861 + 13376.500 45.756 2.851 + 13377.000 48.587 2.836 + 13377.500 53.664 2.815 + 13378.000 57.099 2.808 + 13378.500 53.939 2.811 + 13379.000 51.889 2.821 + 13379.500 48.566 2.833 + 13380.000 41.467 2.845 + 13380.500 78.718 2.850 + 13381.000 107.715 2.837 + 13381.500 121.535 2.818 + 13382.000 120.621 2.786 + 13382.500 101.829 2.765 + 13383.000 75.693 2.786 + 13383.500 64.358 2.804 + 13384.000 62.800 2.813 + 13384.500 59.544 2.812 + 13385.000 53.455 2.806 + 13385.500 45.267 2.816 + 13386.000 39.456 2.831 + 13386.500 33.438 2.846 + 13387.000 32.018 2.851 + 13387.500 31.909 2.854 + 13388.000 34.247 2.850 + 13388.500 35.343 2.828 + 13389.000 56.237 2.808 + 13389.500 63.373 2.801 + 13390.000 82.330 2.792 + 13390.500 124.261 2.775 + 13391.000 128.643 2.749 + 13391.500 128.905 2.721 + 13392.000 128.894 2.711 + 13392.500 122.425 2.725 + 13393.000 102.591 2.738 + 13393.500 87.086 2.754 + 13394.000 79.825 2.765 + 13394.500 53.161 2.782 + 13395.000 44.395 2.796 + 13395.500 31.769 2.815 + 13396.000 27.967 2.825 + 13396.500 25.319 2.838 + 13397.000 25.960 2.841 + 13397.500 32.433 2.850 + 13398.000 34.476 2.856 + 13398.500 40.418 2.871 + 13399.000 40.004 2.871 + 13399.500 40.787 2.864 + 13400.000 39.141 2.858 + 13400.500 41.637 2.851 + 13401.000 47.223 2.842 + 13401.500 41.757 2.835 + 13402.000 93.571 2.814 + 13402.500 124.709 2.762 + 13403.000 181.244 2.730 + 13403.500 171.260 2.709 + 13404.000 188.002 2.700 + 13404.500 183.081 2.708 + 13405.000 169.929 2.728 + 13405.500 141.614 2.729 + 13406.000 114.869 2.724 + 13406.500 84.514 2.755 + 13407.000 80.339 2.779 + 13407.500 69.060 2.797 + 13408.000 55.311 2.793 + 13408.500 37.370 2.809 + 13409.000 28.551 2.812 + 13409.500 25.994 2.853 + 13410.000 25.450 2.852 + 13410.500 31.056 2.852 + 13411.000 39.626 2.842 + 13411.500 50.752 2.838 + 13412.000 56.160 2.838 + 13412.500 56.807 2.813 + 13413.000 58.593 2.803 + 13413.500 59.208 2.798 + 13414.000 57.028 2.798 + 13414.500 53.012 2.806 + 13415.000 44.677 2.841 + 13415.500 42.396 2.858 + 13416.000 50.676 2.873 + 13416.500 86.148 2.854 + 13417.000 99.632 2.800 + 13417.500 106.796 2.764 + 13418.000 100.591 2.742 + 13418.500 82.288 2.782 + 13419.000 47.040 2.829 + 13419.500 37.378 2.868 + 13420.000 33.861 2.891 + 13420.500 25.713 2.899 + 13421.000 30.484 2.907 + 13421.500 40.907 2.897 + 13422.000 58.398 2.886 + 13422.500 111.136 2.848 + 13423.000 125.243 2.802 + 13423.500 147.958 2.775 + 13424.000 157.767 2.745 + 13424.500 153.462 2.719 + 13425.000 105.862 2.698 + 13425.500 72.624 2.705 + 13426.000 54.935 2.725 + 13426.500 48.559 2.772 + 13427.000 44.951 2.807 + 13427.500 70.276 2.825 + 13428.000 82.265 2.827 + 13428.500 129.105 2.808 + 13429.000 134.317 2.765 + 13429.500 126.679 2.745 + 13430.000 117.306 2.737 + 13430.500 88.502 2.768 + 13431.000 66.696 2.800 + 13431.500 69.248 2.808 + 13432.000 81.771 2.803 + 13432.500 92.414 2.786 + 13433.000 109.435 2.753 + 13433.500 114.158 2.751 + 13434.000 117.692 2.745 + 13434.500 126.683 2.748 + 13435.000 138.869 2.757 + 13435.500 141.872 2.764 + 13436.000 147.560 2.767 + 13436.500 134.362 2.744 + 13437.000 104.041 2.730 + 13437.500 61.222 2.723 + 13438.000 43.086 2.773 + 13438.500 33.084 2.830 + 13439.000 29.731 2.871 + 13439.500 32.392 2.866 + 13440.000 34.506 2.850 + 13440.500 37.019 2.838 + 13441.000 36.407 2.828 + 13441.500 36.451 2.827 + 13442.000 39.069 2.823 + 13442.500 42.643 2.820 + 13443.000 46.369 2.812 + 13443.500 51.233 2.810 + 13444.000 55.407 2.814 + 13444.500 54.344 2.816 + 13445.000 51.685 2.818 + 13445.500 42.264 2.823 + 13446.000 37.505 2.835 + 13446.500 70.742 2.847 + 13447.000 101.533 2.857 + 13447.500 111.361 2.854 + 13448.000 101.676 2.860 + 13448.500 80.893 2.816 + 13449.000 71.166 2.804 + 13449.500 67.398 2.800 + 13450.000 64.051 2.792 + 13450.500 61.048 2.787 + 13451.000 52.318 2.781 + 13451.500 50.265 2.794 + 13452.000 42.649 2.809 + 13452.500 32.412 2.817 + 13453.000 31.558 2.817 + 13453.500 30.702 2.812 + 13454.000 37.184 2.814 + 13454.500 49.655 2.820 + 13455.000 63.367 2.826 + 13455.500 80.288 2.819 + 13456.000 103.474 2.806 + 13456.500 114.440 2.749 + 13457.000 112.101 2.732 + 13457.500 108.708 2.719 + 13458.000 103.669 2.717 + 13458.500 77.287 2.744 + 13459.000 63.150 2.758 + 13459.500 53.003 2.777 + 13460.000 38.522 2.785 + 13460.500 27.818 2.795 + 13461.000 30.151 2.818 + 13461.500 34.951 2.839 + 13462.000 41.752 2.844 + 13462.500 50.925 2.841 + 13463.000 42.733 2.825 + 13463.500 35.698 2.812 + 13464.000 29.391 2.814 + 13464.500 27.688 2.825 + 13465.000 26.823 2.868 + 13465.500 28.336 2.869 + 13466.000 35.983 2.865 + 13466.500 49.446 2.845 + 13467.000 61.621 2.819 + 13467.500 61.819 2.799 + 13468.000 62.784 2.773 + 13468.500 48.572 2.762 + 13469.000 40.258 2.766 + 13469.500 30.974 2.774 + 13470.000 26.121 2.816 + 13470.500 22.340 2.886 + 13471.000 20.553 2.907 + 13471.500 24.446 2.900 + 13472.000 31.131 2.896 + 13472.500 65.799 2.887 + 13473.000 69.608 2.885 + 13473.500 100.535 2.864 + 13474.000 113.700 2.838 + 13474.500 140.680 2.757 + 13475.000 136.834 2.735 + 13475.500 130.014 2.718 + 13476.000 136.326 2.713 + 13476.500 73.664 2.721 + 13477.000 78.968 2.766 + 13477.500 74.839 2.772 + 13478.000 79.775 2.778 + 13478.500 82.748 2.772 + 13479.000 82.538 2.762 + 13479.500 80.521 2.767 + 13480.000 76.584 2.775 + 13480.500 76.186 2.783 + 13481.000 74.293 2.786 + 13481.500 80.975 2.786 + 13482.000 87.627 2.785 + 13482.500 92.440 2.777 + 13483.000 92.295 2.772 + 13483.500 83.453 2.767 + 13484.000 77.571 2.763 + 13484.500 66.208 2.777 + 13485.000 59.861 2.796 + 13485.500 54.484 2.818 + 13486.000 53.892 2.826 + 13486.500 55.997 2.822 + 13487.000 58.371 2.817 + 13487.500 61.838 2.814 + 13488.000 67.973 2.814 + 13488.500 78.552 2.814 + 13489.000 92.812 2.810 + 13489.500 97.023 2.805 + 13490.000 98.159 2.808 + 13490.500 85.798 2.804 + 13491.000 84.105 2.801 + 13491.500 85.871 2.826 + 13492.000 116.310 2.878 + 13492.500 157.588 2.921 + 13493.000 183.462 2.835 + 13493.500 197.358 2.785 + 13494.000 192.727 2.683 + 13494.500 180.907 2.687 + 13495.000 177.591 2.684 + 13495.500 167.773 2.693 + 13496.000 162.638 2.701 + 13496.500 138.097 2.730 + 13497.000 98.260 2.762 + 13497.500 81.600 2.786 + 13498.000 74.808 2.836 + 13498.500 69.471 2.821 + 13499.000 64.787 2.813 + 13499.500 65.411 2.800 + 13500.000 68.414 2.776 + 13500.500 77.921 2.766 + 13501.000 86.276 2.761 + 13501.500 91.353 2.757 + 13502.000 94.533 2.757 + 13502.500 94.593 2.756 + 13503.000 92.481 2.778 + 13503.500 89.587 2.790 + 13504.000 87.902 2.797 + 13504.500 87.313 2.794 + 13505.000 86.688 2.783 + 13505.500 83.408 2.768 + 13506.000 80.516 2.759 + 13506.500 77.086 2.751 + 13507.000 77.069 2.744 + 13507.500 77.885 2.728 + 13508.000 79.096 2.717 + 13508.500 77.474 2.711 + 13509.000 77.368 2.710 + 13509.500 79.182 2.710 + 13510.000 82.502 2.684 + 13510.500 80.084 2.661 + 13511.000 77.657 2.693 + 13511.500 78.444 2.719 + 13512.000 84.599 2.762 + 13512.500 99.704 2.753 + 13513.000 102.269 2.746 + 13513.500 99.787 2.749 + 13514.000 92.327 2.763 + 13514.500 94.150 2.766 + 13515.000 105.214 2.764 + 13515.500 108.311 2.747 + 13516.000 99.113 2.742 + 13516.500 87.675 2.748 + 13517.000 60.519 2.775 + 13517.500 49.815 2.791 + 13518.000 32.118 2.817 + 13518.500 28.255 2.844 + 13519.000 23.416 2.841 + 13519.500 20.942 2.838 + 13520.000 19.070 2.838 + 13520.500 17.532 2.843 + 13521.000 17.564 2.848 + 13521.500 19.807 2.853 + 13522.000 21.706 2.849 + 13522.500 23.983 2.850 + 13523.000 23.708 2.837 + 13523.500 22.249 2.841 + 13524.000 21.475 2.842 + 13524.500 21.393 2.850 + 13525.000 26.528 2.851 + 13525.500 42.829 2.840 + 13526.000 60.542 2.822 + 13526.500 91.495 2.779 + 13527.000 102.680 2.762 + 13527.500 104.750 2.737 + 13528.000 89.486 2.731 + 13528.500 81.404 2.747 + 13529.000 75.456 2.752 + 13529.500 75.027 2.753 + 13530.000 74.872 2.751 + 13530.500 75.550 2.754 + 13531.000 77.177 2.757 + 13531.500 77.173 2.770 + 13532.000 77.198 2.785 + 13532.500 75.522 2.793 + 13533.000 74.837 2.785 + 13533.500 75.022 2.785 + 13534.000 74.345 2.782 + 13534.500 80.301 2.773 + 13535.000 90.093 2.741 + 13535.500 96.437 2.730 + 13536.000 100.247 2.729 + 13536.500 105.042 2.726 + 13537.000 108.910 2.727 + 13537.500 116.306 2.717 + 13538.000 121.222 2.713 + 13538.500 122.531 2.705 + 13539.000 122.458 2.700 + 13539.500 122.205 2.690 + 13540.000 123.814 2.674 + 13540.500 134.836 2.657 + 13541.000 144.893 2.651 + 13541.500 149.863 2.651 + 13542.000 155.498 2.659 + 13542.500 137.427 2.680 + 13543.000 101.607 2.705 + 13543.500 48.157 2.738 + 13544.000 26.622 2.787 + 13544.500 15.294 2.817 + 13545.000 15.789 2.823 + 13545.500 17.458 2.834 + 13546.000 18.556 2.836 + 13546.500 21.432 2.849 + 13547.000 20.980 2.856 + 13547.500 21.580 2.854 + 13548.000 20.434 2.851 + 13548.500 20.413 2.837 + 13549.000 22.681 2.833 + 13549.500 27.144 2.826 + 13550.000 24.927 2.822 + 13550.500 19.683 2.830 + 13551.000 17.251 2.837 + 13551.500 14.266 2.835 + 13552.000 14.043 2.827 + 13552.500 17.115 2.829 + 13553.000 22.048 2.841 + 13553.500 24.185 2.850 + 13554.000 25.552 2.851 + 13554.500 24.928 2.838 + 13555.000 25.543 2.832 + 13555.500 26.027 2.833 + 13556.000 26.779 2.837 + 13556.500 26.232 2.839 + 13557.000 26.299 2.827 + 13557.500 26.246 2.809 + 13558.000 26.325 2.800 + 13558.500 25.437 2.801 + 13559.000 24.006 2.810 + 13559.500 22.218 2.817 + 13560.000 23.166 2.818 + 13560.500 24.113 2.807 + 13561.000 33.690 2.800 + 13561.500 37.686 2.797 + 13562.000 39.635 2.801 + 13562.500 38.912 2.811 + 13563.000 25.075 2.815 + 13563.500 21.171 2.826 + 13564.000 20.231 2.839 + 13564.500 20.438 2.851 + 13565.000 43.834 2.847 + 13565.500 37.198 2.839 + 13566.000 93.357 2.817 + 13566.500 173.455 2.787 + 13567.000 167.598 2.749 + 13567.500 174.186 2.729 + 13568.000 171.938 2.723 + 13568.500 130.125 2.740 + 13569.000 114.932 2.745 + 13569.500 101.826 2.757 + 13570.000 78.261 2.768 + 13570.500 44.639 2.780 + 13571.000 37.879 2.787 + 13571.500 19.241 2.815 + 13572.000 24.111 2.842 + 13572.500 31.575 2.856 + 13573.000 37.906 2.853 + 13573.500 44.258 2.845 + 13574.000 51.052 2.827 + 13574.500 52.880 2.814 + 13575.000 54.506 2.806 + 13575.500 56.785 2.808 + 13576.000 56.626 2.806 + 13576.500 52.763 2.812 + 13577.000 47.062 2.823 + 13577.500 45.682 2.837 + 13578.000 54.195 2.832 + 13578.500 79.482 2.808 + 13579.000 88.302 2.796 + 13579.500 95.240 2.776 + 13580.000 93.811 2.776 + 13580.500 70.724 2.819 + 13581.000 49.061 2.842 + 13581.500 35.052 2.864 + 13582.000 30.564 2.883 + 13582.500 33.328 2.904 + 13583.000 51.311 2.908 + 13583.500 76.079 2.897 + 13584.000 128.935 2.903 + 13584.500 151.153 2.776 + 13585.000 163.803 2.757 + 13585.500 169.952 2.734 + 13586.000 163.693 2.688 + 13586.500 124.774 2.656 + 13587.000 101.185 2.682 + 13587.500 77.525 2.673 + 13588.000 52.449 2.760 + 13588.500 41.073 2.816 + 13589.000 43.358 2.840 + 13589.500 63.895 2.851 + 13590.000 95.799 2.806 + 13590.500 137.716 2.734 + 13591.000 129.104 2.719 + 13591.500 117.888 2.728 + 13592.000 108.118 2.740 + 13592.500 68.517 2.759 + 13593.000 71.189 2.773 + 13593.500 68.940 2.775 + 13594.000 75.200 2.778 + 13594.500 78.679 2.775 + 13595.000 103.017 2.761 + 13595.500 108.961 2.749 + 13596.000 118.368 2.736 + 13596.500 126.312 2.735 + 13597.000 132.644 2.739 + 13597.500 144.763 2.735 + 13598.000 151.535 2.728 + 13598.500 155.635 2.723 + 13599.000 147.123 2.719 + 13599.500 129.916 2.725 + 13600.000 80.985 2.801 + 13600.500 43.150 2.829 + 13601.000 33.655 2.867 + 13601.500 32.825 2.860 + 13602.000 31.394 2.865 + 13602.500 33.781 2.823 + 13603.000 39.776 2.806 + 13603.500 43.247 2.793 + 13604.000 46.287 2.772 + 13604.500 50.324 2.794 + 13605.000 54.943 2.800 + 13605.500 53.312 2.811 + 13606.000 45.618 2.815 + 13606.500 43.395 2.816 + 13607.000 47.731 2.813 + 13607.500 64.490 2.804 + 13608.000 88.164 2.788 + 13608.500 104.936 2.776 + 13609.000 91.660 2.774 + 13609.500 79.643 2.792 + 13610.000 67.140 2.804 + 13610.500 59.343 2.797 + 13611.000 46.356 2.797 + 13611.500 43.186 2.811 + 13612.000 37.098 2.820 + 13612.500 35.703 2.831 + 13613.000 35.975 2.834 + 13613.500 48.248 2.820 + 13614.000 43.486 2.815 + 13614.500 81.660 2.804 + 13615.000 94.055 2.780 + 13615.500 108.415 2.753 + 13616.000 123.879 2.739 + 13616.500 136.472 2.717 + 13617.000 134.889 2.715 + 13617.500 128.511 2.715 + 13618.000 106.296 2.727 + 13618.500 87.868 2.760 + 13619.000 52.005 2.791 + 13619.500 38.318 2.817 + 13620.000 35.664 2.830 + 13620.500 35.055 2.829 + 13621.000 52.685 2.815 + 13621.500 83.345 2.804 + 13622.000 78.525 2.774 + 13622.500 110.359 2.741 + 13623.000 137.130 2.728 + 13623.500 135.250 2.717 + 13624.000 143.038 2.710 + 13624.500 143.741 2.707 + 13625.000 133.992 2.715 + 13625.500 126.036 2.749 + 13626.000 110.623 2.763 + 13626.500 108.592 2.777 + 13627.000 86.068 2.781 + 13627.500 82.064 2.789 + 13628.000 73.167 2.796 + 13628.500 55.209 2.812 + 13629.000 42.868 2.824 + 13629.500 36.724 2.840 + 13630.000 28.999 2.845 + 13630.500 23.450 2.856 + 13631.000 20.841 2.854 + 13631.500 19.879 2.851 + 13632.000 19.966 2.835 + 13632.500 20.054 2.822 + 13633.000 19.731 2.818 + 13633.500 20.798 2.815 + 13634.000 22.482 2.816 + 13634.500 24.885 2.828 + 13635.000 35.745 2.832 + 13635.500 38.927 2.832 + 13636.000 38.115 2.832 + 13636.500 31.818 2.838 + 13637.000 27.501 2.846 + 13637.500 26.194 2.845 + 13638.000 26.685 2.842 + 13638.500 29.096 2.845 + 13639.000 30.206 2.846 + 13639.500 30.200 2.846 + 13640.000 30.286 2.844 + 13640.500 31.840 2.842 + 13641.000 33.354 2.841 + 13641.500 40.159 2.826 + 13642.000 47.518 2.811 + 13642.500 65.467 2.800 + 13643.000 69.801 2.799 + 13643.500 60.380 2.802 + 13644.000 54.855 2.817 + 13644.500 50.182 2.852 + 13645.000 44.788 2.861 + 13645.500 41.188 2.867 + 13646.000 40.432 2.872 + 13646.500 31.885 2.879 + 13647.000 30.074 2.877 + 13647.500 31.051 2.863 + 13648.000 33.463 2.851 + 13648.500 39.018 2.841 + 13649.000 39.496 2.836 + 13649.500 36.057 2.830 + 13650.000 30.950 2.830 + 13650.500 26.799 2.827 + 13651.000 25.451 2.822 + 13651.500 23.308 2.815 + 13652.000 22.989 2.814 + 13652.500 22.067 2.831 + 13653.000 22.514 2.843 + 13653.500 22.898 2.842 + 13654.000 27.787 2.834 + 13654.500 37.039 2.811 + 13655.000 47.910 2.803 + 13655.500 58.609 2.798 + 13656.000 61.325 2.794 + 13656.500 53.477 2.798 + 13657.000 44.646 2.800 + 13657.500 36.033 2.821 + 13658.000 35.191 2.838 + 13658.500 38.850 2.853 + 13659.000 40.154 2.849 + 13659.500 39.064 2.838 + 13660.000 33.365 2.834 + 13660.500 32.154 2.840 + 13661.000 38.817 2.845 + 13661.500 46.495 2.848 + 13662.000 51.725 2.854 + 13662.500 56.240 2.849 + 13663.000 60.018 2.830 + 13663.500 59.934 2.793 + 13664.000 57.796 2.780 + 13664.500 45.727 2.781 + 13665.000 43.404 2.801 + 13665.500 42.834 2.815 + 13666.000 53.308 2.805 + 13666.500 77.495 2.760 + 13667.000 114.287 2.739 + 13667.500 97.828 2.733 + 13668.000 75.554 2.761 + 13668.500 44.757 2.783 + 13669.000 45.564 2.811 + 13669.500 59.846 2.811 + 13670.000 67.103 2.782 + 13670.500 104.316 2.729 + 13671.000 115.277 2.670 + 13671.500 113.270 2.683 + 13672.000 100.887 2.690 + 13672.500 90.657 2.732 + 13673.000 80.995 2.740 + 13673.500 70.503 2.754 + 13674.000 67.893 2.774 + 13674.500 68.924 2.779 + 13675.000 80.282 2.803 + 13675.500 81.679 2.800 + 13676.000 83.770 2.787 + 13676.500 72.397 2.774 + 13677.000 61.176 2.775 + 13677.500 51.270 2.792 + 13678.000 50.018 2.831 + 13678.500 60.054 2.855 + 13679.000 63.605 2.842 + 13679.500 61.952 2.818 + 13680.000 49.712 2.807 + 13680.500 28.461 2.838 + 13681.000 29.174 2.851 + 13681.500 26.377 2.857 + 13682.000 27.023 2.854 + 13682.500 29.137 2.849 + 13683.000 28.439 2.845 + 13683.500 32.501 2.840 + 13684.000 38.552 2.832 + 13684.500 61.791 2.815 + 13685.000 73.319 2.794 + 13685.500 80.275 2.760 + 13686.000 76.893 2.744 + 13686.500 67.767 2.755 + 13687.000 66.661 2.783 + 13687.500 67.932 2.790 + 13688.000 69.714 2.791 + 13688.500 61.870 2.817 + 13689.000 49.909 2.832 + 13689.500 49.659 2.843 + 13690.000 46.630 2.837 + 13690.500 66.545 2.811 + 13691.000 89.632 2.787 + 13691.500 90.679 2.773 + 13692.000 87.223 2.770 + 13692.500 71.942 2.792 + 13693.000 64.523 2.813 + 13693.500 56.128 2.840 + 13694.000 56.352 2.854 + 13694.500 76.110 2.857 + 13695.000 90.876 2.835 + 13695.500 98.762 2.796 + 13696.000 103.558 2.762 + 13696.500 92.558 2.766 + 13697.000 76.736 2.795 + 13697.500 67.061 2.814 + 13698.000 52.592 2.823 + 13698.500 36.890 2.830 + 13699.000 34.659 2.838 + 13699.500 32.746 2.853 + 13700.000 35.706 2.858 + 13700.500 63.438 2.823 + 13701.000 71.482 2.798 + 13701.500 97.289 2.752 + 13702.000 111.343 2.714 + 13702.500 106.705 2.719 + 13703.000 64.685 2.730 + 13703.500 67.721 2.768 + 13704.000 41.226 2.818 + 13704.500 27.777 2.838 + 13705.000 20.349 2.844 + 13705.500 16.533 2.831 + 13706.000 14.642 2.820 + 13706.500 14.194 2.823 + 13707.000 14.789 2.828 + 13707.500 15.366 2.830 + 13708.000 15.328 2.824 + 13708.500 15.442 2.818 + 13709.000 16.175 2.816 + 13709.500 16.743 2.817 + 13710.000 18.588 2.820 + 13710.500 23.612 2.822 + 13711.000 30.448 2.818 + 13711.500 35.154 2.814 + 13712.000 36.608 2.814 + 13712.500 32.432 2.829 + 13713.000 24.349 2.840 + 13713.500 20.444 2.854 + 13714.000 19.679 2.854 + 13714.500 21.334 2.851 + 13715.000 24.952 2.843 + 13715.500 30.092 2.829 + 13716.000 32.342 2.825 + 13716.500 33.892 2.825 + 13717.000 34.047 2.828 + 13717.500 36.979 2.827 + 13718.000 39.181 2.822 + 13718.500 37.091 2.814 + 13719.000 31.847 2.812 + 13719.500 21.141 2.812 + 13720.000 21.438 2.812 + 13720.500 18.741 2.806 + 13721.000 19.319 2.803 + 13721.500 19.049 2.797 + 13722.000 18.408 2.798 + 13722.500 19.384 2.803 + 13723.000 20.386 2.827 + 13723.500 22.156 2.832 + 13724.000 27.115 2.827 + 13724.500 35.193 2.810 + 13725.000 43.218 2.802 + 13725.500 45.436 2.798 + 13726.000 43.497 2.796 + 13726.500 40.448 2.798 + 13727.000 32.789 2.811 + 13727.500 29.918 2.813 + 13728.000 21.788 2.814 + 13728.500 24.188 2.804 + 13729.000 31.965 2.794 + 13729.500 39.446 2.794 + 13730.000 47.029 2.796 + 13730.500 55.243 2.805 + 13731.000 57.126 2.812 + 13731.500 45.083 2.821 + 13732.000 30.010 2.827 + 13732.500 27.650 2.842 + 13733.000 19.971 2.852 + 13733.500 17.529 2.856 + 13734.000 14.638 2.858 + 13734.500 13.069 2.856 + 13735.000 11.496 2.853 + 13735.500 11.254 2.851 + 13736.000 11.779 2.842 + 13736.500 12.048 2.825 + 13737.000 13.117 2.809 + 13737.500 12.779 2.804 + 13738.000 13.526 2.805 + 13738.500 12.201 2.814 + 13739.000 12.063 2.820 + 13739.500 11.237 2.819 + 13740.000 11.419 2.821 + 13740.500 12.533 2.831 + 13741.000 12.925 2.842 + 13741.500 17.443 2.855 + 13742.000 19.641 2.857 + 13742.500 25.192 2.856 + 13743.000 26.891 2.851 + 13743.500 31.477 2.836 + 13744.000 33.424 2.826 + 13744.500 33.662 2.826 + 13745.000 32.446 2.826 + 13745.500 28.246 2.822 + 13746.000 25.123 2.818 + 13746.500 22.341 2.815 + 13747.000 22.598 2.819 + 13747.500 24.830 2.828 + 13748.000 25.729 2.827 + 13748.500 25.564 2.822 + 13749.000 24.440 2.821 + 13749.500 22.978 2.828 + 13750.000 22.525 2.833 + 13750.500 23.596 2.826 + 13751.000 24.058 2.816 + 13751.500 24.956 2.814 + 13752.000 25.732 2.818 + 13752.500 25.552 2.819 + 13753.000 24.828 2.821 + 13753.500 24.931 2.826 + 13754.000 24.236 2.835 + 13754.500 20.317 2.846 + 13755.000 19.216 2.850 + 13755.500 19.089 2.856 + 13756.000 19.335 2.854 + 13756.500 18.661 2.834 + 13757.000 17.477 2.829 + 13757.500 18.194 2.833 + 13758.000 19.350 2.839 + 13758.500 20.922 2.840 + 13759.000 21.500 2.830 + 13759.500 22.181 2.824 + 13760.000 23.063 2.826 + 13760.500 25.353 2.834 + 13761.000 26.537 2.831 + 13761.500 27.084 2.829 + 13762.000 26.736 2.822 + 13762.500 24.833 2.830 + 13763.000 24.103 2.837 + 13763.500 24.148 2.837 + 13764.000 27.957 2.830 + 13764.500 33.607 2.821 + 13765.000 40.317 2.825 + 13765.500 42.428 2.827 + 13766.000 46.228 2.819 + 13766.500 45.018 2.812 + 13767.000 43.317 2.802 + 13767.500 40.406 2.799 + 13768.000 39.587 2.801 + 13768.500 37.735 2.818 + 13769.000 36.904 2.817 + 13769.500 35.504 2.815 + 13770.000 33.965 2.813 + 13770.500 30.636 2.831 + 13771.000 27.667 2.846 + 13771.500 26.848 2.848 + 13772.000 26.106 2.844 + 13772.500 24.850 2.829 + 13773.000 24.148 2.817 + 13773.500 23.267 2.812 + 13774.000 23.283 2.817 + 13774.500 23.942 2.825 + 13775.000 24.309 2.831 + 13775.500 24.776 2.834 + 13776.000 23.658 2.834 + 13776.500 19.960 2.835 + 13777.000 18.461 2.831 + 13777.500 16.986 2.825 + 13778.000 16.768 2.820 + 13778.500 19.101 2.822 + 13779.000 20.011 2.826 + 13779.500 26.246 2.830 + 13780.000 31.887 2.828 + 13780.500 37.995 2.822 + 13781.000 36.581 2.817 + 13781.500 38.225 2.816 + 13782.000 23.713 2.815 + 13782.500 20.760 2.809 + 13783.000 21.755 2.806 + 13783.500 24.459 2.807 + 13784.000 26.186 2.816 + 13784.500 29.793 2.841 + 13785.000 30.078 2.848 + 13785.500 28.100 2.848 + 13786.000 26.384 2.834 + 13786.500 24.341 2.832 + 13787.000 29.073 2.830 + 13787.500 38.270 2.830 + 13788.000 50.706 2.823 + 13788.500 58.099 2.817 + 13789.000 57.894 2.806 + 13789.500 50.029 2.806 + 13790.000 31.063 2.808 + 13790.500 21.255 2.811 + 13791.000 15.363 2.812 + 13791.500 14.882 2.816 + 13792.000 13.904 2.823 + 13792.500 14.568 2.845 + 13793.000 15.379 2.846 + 13793.500 20.035 2.842 + 13794.000 23.867 2.840 + 13794.500 32.123 2.843 + 13795.000 33.869 2.838 + 13795.500 34.041 2.831 + 13796.000 32.850 2.825 + 13796.500 25.301 2.840 + 13797.000 25.746 2.850 + 13797.500 25.669 2.856 + 13798.000 25.887 2.851 + 13798.500 26.296 2.838 + 13799.000 25.529 2.836 + 13799.500 23.708 2.842 + 13800.000 22.212 2.844 + 13800.500 22.207 2.846 + 13801.000 21.361 2.848 + 13801.500 20.836 2.852 + 13802.000 23.311 2.857 + 13802.500 25.585 2.860 + 13803.000 27.996 2.853 + 13803.500 30.403 2.837 + 13804.000 32.820 2.823 + 13804.500 34.743 2.824 + 13805.000 35.457 2.836 + 13805.500 36.588 2.840 + 13806.000 38.923 2.845 + 13806.500 40.296 2.842 + 13807.000 40.437 2.837 + 13807.500 39.504 2.828 + 13808.000 37.723 2.813 + 13808.500 40.086 2.837 + 13809.000 45.180 2.851 + 13809.500 53.194 2.877 + 13810.000 56.710 2.885 + 13810.500 61.348 2.847 + 13811.000 61.416 2.824 + 13811.500 53.778 2.819 + 13812.000 49.010 2.828 + 13812.500 37.680 2.841 + 13813.000 30.670 2.843 + 13813.500 26.360 2.842 + 13814.000 25.332 2.842 + 13814.500 24.534 2.854 + 13815.000 25.463 2.856 + 13815.500 26.477 2.856 + 13816.000 27.112 2.857 + 13816.500 26.994 2.851 + 13817.000 27.113 2.855 + 13817.500 26.463 2.854 + 13818.000 25.749 2.837 + 13818.500 24.759 2.829 + 13819.000 25.296 2.819 + 13819.500 26.249 2.819 + 13820.000 28.388 2.816 + 13820.500 30.809 2.823 + 13821.000 30.948 2.829 + 13821.500 30.753 2.829 + 13822.000 29.207 2.821 + 13822.500 26.950 2.828 + 13823.000 23.966 2.840 + 13823.500 23.285 2.844 + 13824.000 23.068 2.840 + 13824.500 21.518 2.839 + 13825.000 20.056 2.852 + 13825.500 20.253 2.866 + 13826.000 20.311 2.875 + 13826.500 21.380 2.861 + 13827.000 22.137 2.854 + 13827.500 22.620 2.854 + 13828.000 22.432 2.855 + 13828.500 21.299 2.870 + 13829.000 20.697 2.879 + 13829.500 20.843 2.882 + 13830.000 20.810 2.876 + 13830.500 22.433 2.867 + 13831.000 23.890 2.869 + 13831.500 27.085 2.870 + 13832.000 29.890 2.865 + 13832.500 32.872 2.837 + 13833.000 32.428 2.829 + 13833.500 32.460 2.823 + 13834.000 32.428 2.832 + 13834.500 32.317 2.846 + 13835.000 32.277 2.849 + 13835.500 32.210 2.851 + 13836.000 32.142 2.844 + 13836.500 32.083 2.837 + 13837.000 32.019 2.840 + 13837.500 31.947 2.853 + 13838.000 31.907 2.864 + 13838.500 31.822 2.866 + 13839.000 31.659 2.864 + 13839.500 29.941 2.862 + 13840.000 29.013 2.849 + 13840.500 28.887 2.839 + 13841.000 30.216 2.835 + 13841.500 31.230 2.840 + 13842.000 31.838 2.845 + 13842.500 33.833 2.841 + 13843.000 34.801 2.844 + 13843.500 36.435 2.847 + 13844.000 36.419 2.855 + 13844.500 34.263 2.820 + 13845.000 32.751 2.825 + 13845.500 31.837 2.839 + 13846.000 31.903 2.843 + 13846.500 31.087 2.840 + 13847.000 30.695 2.832 + 13847.500 29.247 2.833 + 13848.000 29.442 2.843 + 13848.500 29.896 2.845 + 13849.000 30.923 2.843 + 13849.500 30.510 2.843 + 13850.000 30.914 2.854 + 13850.500 30.063 2.879 + 13851.000 30.384 2.883 + 13851.500 31.080 2.869 + 13852.000 30.944 2.852 + 13852.500 30.869 2.846 + 13853.000 29.956 2.853 + 13853.500 29.258 2.857 + 13854.000 27.981 2.869 + 13854.500 27.347 2.849 + 13855.000 26.296 2.836 + 13855.500 26.912 2.837 + 13856.000 27.077 2.861 + 13856.500 26.866 2.872 + 13857.000 26.623 2.875 + 13857.500 26.800 2.856 + 13858.000 27.634 2.847 + 13858.500 28.538 2.835 + 13859.000 28.554 2.837 + 13859.500 29.049 2.844 + 13860.000 29.329 2.856 + 13860.500 30.364 2.863 + 13861.000 29.929 2.869 + 13861.500 29.973 2.870 + 13862.000 30.382 2.870 + 13862.500 31.061 2.859 + 13863.000 30.991 2.847 + 13863.500 30.598 2.837 + 13864.000 29.990 2.832 + 13864.500 29.257 2.853 + 13865.000 27.950 2.871 + 13865.500 27.859 2.867 + 13866.000 27.787 2.851 + 13866.500 28.013 2.851 + 13867.000 28.829 2.859 + 13867.500 29.449 2.875 + 13868.000 29.546 2.869 + 13868.500 30.276 2.861 + 13869.000 30.633 2.847 + 13869.500 32.250 2.843 + 13870.000 32.727 2.835 + 13870.500 33.463 2.857 + 13871.000 33.090 2.868 + 13871.500 33.067 2.870 + 13872.000 33.379 2.873 + 13872.500 32.080 2.874 + 13873.000 31.017 2.864 + 13873.500 31.608 2.854 + 13874.000 32.019 2.846 + 13874.500 33.621 2.844 + 13875.000 32.130 2.842 + 13875.500 30.475 2.835 + 13876.000 30.091 2.812 + 13876.500 31.026 2.803 + 13877.000 31.889 2.837 + 13877.500 34.182 2.853 + 13878.000 34.973 2.869 + 13878.500 36.471 2.861 + 13879.000 36.105 2.856 + 13879.500 35.512 2.857 + 13880.000 34.622 2.866 + 13880.500 32.414 2.882 + 13881.000 31.754 2.876 + 13881.500 31.777 2.855 + 13882.000 31.725 2.852 + 13882.500 31.833 2.852 + 13883.000 31.208 2.858 + 13883.500 30.183 2.866 + 13884.000 29.241 2.868 + 13884.500 27.791 2.863 + 13885.000 26.969 2.861 + 13885.500 27.643 2.859 + 13886.000 28.363 2.853 + 13886.500 29.356 2.845 + 13887.000 28.795 2.842 + 13887.500 28.567 2.840 + 13888.000 29.234 2.839 + 13888.500 29.411 2.835 + 13889.000 29.460 2.838 + 13889.500 29.342 2.843 + 13890.000 29.976 2.852 + 13890.500 30.824 2.862 + 13891.000 31.013 2.872 + 13891.500 30.991 2.882 + 13892.000 30.928 2.890 + 13892.500 31.192 2.889 + 13893.000 31.974 2.877 + 13893.500 33.064 2.857 + 13894.000 32.515 2.848 + 13894.500 29.756 2.841 + 13895.000 27.844 2.847 + 13895.500 28.650 2.857 + 13896.000 29.479 2.866 + 13896.500 31.540 2.868 + 13897.000 31.723 2.855 + 13897.500 31.809 2.842 + 13898.000 31.592 2.834 + 13898.500 30.911 2.856 + 13899.000 31.011 2.858 + 13899.500 32.012 2.862 + 13900.000 32.875 2.861 + 13900.500 34.388 2.843 + 13901.000 34.961 2.828 + 13901.500 34.797 2.822 + 13902.000 35.536 2.820 + 13902.500 35.786 2.822 + 13903.000 36.629 2.827 + 13903.500 36.329 2.829 + 13904.000 37.041 2.827 + 13904.500 40.024 2.814 + 13905.000 42.125 2.805 + 13905.500 48.528 2.809 + 13906.000 52.304 2.820 + 13906.500 55.487 2.833 + 13907.000 54.870 2.837 + 13907.500 51.856 2.845 + 13908.000 49.796 2.854 + 13908.500 46.039 2.878 + 13909.000 43.669 2.855 + 13909.500 40.972 2.849 + 13910.000 40.227 2.842 + 13910.500 39.483 2.847 + 13911.000 40.156 2.853 + 13911.500 41.122 2.851 + 13912.000 42.944 2.845 + 13912.500 44.350 2.846 + 13913.000 43.408 2.849 + 13913.500 43.367 2.842 + 13914.000 42.826 2.839 + 13914.500 41.541 2.846 + 13915.000 40.568 2.847 + 13915.500 40.404 2.844 + 13916.000 39.523 2.848 + 13916.500 37.149 2.860 + 13917.000 36.348 2.867 + 13917.500 36.984 2.872 + 13918.000 38.784 2.877 + 13918.500 40.581 2.874 + 13919.000 40.394 2.863 + 13919.500 40.155 2.838 + 13920.000 40.186 2.847 + 13920.500 40.442 2.867 + 13921.000 40.422 2.882 + 13921.500 40.334 2.892 + 13922.000 40.643 2.897 + 13922.500 38.294 2.880 + 13923.000 34.904 2.869 + 13923.500 32.485 2.840 + 13924.000 29.940 2.834 + 13924.500 26.271 2.826 + 13925.000 24.287 2.844 + 13925.500 20.988 2.855 + 13926.000 19.991 2.873 + 13926.500 19.077 2.877 + 13927.000 19.833 2.866 + 13927.500 19.879 2.865 + 13928.000 18.778 2.864 + 13928.500 17.495 2.856 + 13929.000 16.744 2.843 + 13929.500 16.213 2.832 + 13930.000 16.991 2.828 + 13930.500 16.793 2.832 + 13931.000 16.824 2.842 + 13931.500 17.196 2.855 + 13932.000 18.846 2.858 + 13932.500 20.083 2.857 + 13933.000 20.205 2.849 + 13933.500 20.181 2.838 + 13934.000 20.499 2.839 + 13934.500 19.674 2.849 + 13935.000 19.861 2.874 + 13935.500 19.939 2.886 + 13936.000 20.186 2.894 + 13936.500 18.717 2.891 + 13937.000 18.214 2.881 + 13937.500 17.620 2.881 + 13938.000 18.007 2.880 + 13938.500 18.152 2.868 + 13939.000 18.376 2.844 + 13939.500 17.588 2.835 + 13940.000 16.648 2.835 + 13940.500 16.639 2.846 + 13941.000 17.028 2.855 + 13941.500 17.821 2.854 + 13942.000 19.255 2.860 + 13942.500 20.030 2.867 + 13943.000 20.032 2.895 + 13943.500 20.004 2.897 + 13944.000 19.776 2.874 + 13944.500 19.828 2.860 + 13945.000 19.922 2.849 + 13945.500 20.643 2.858 + 13946.000 20.990 2.866 + 13946.500 21.043 2.864 + 13947.000 20.642 2.858 + 13947.500 19.691 2.854 + 13948.000 19.663 2.854 + 13948.500 19.034 2.858 + 13949.000 18.379 2.863 + 13949.500 18.280 2.871 + 13950.000 17.941 2.872 + 13950.500 18.640 2.867 + 13951.000 19.987 2.851 + 13951.500 18.639 2.834 + 13952.000 16.133 2.829 + 13952.500 15.200 2.849 + 13953.000 15.405 2.860 + 13953.500 16.734 2.870 + 13954.000 17.862 2.876 + 13954.500 18.499 2.861 + 13955.000 18.400 2.851 + 13955.500 18.505 2.844 + 13956.000 19.664 2.842 + 13956.500 18.203 2.850 + 13957.000 17.007 2.852 + 13957.500 16.785 2.852 + 13958.000 16.891 2.852 + 13958.500 16.869 2.851 + 13959.000 16.710 2.855 + 13959.500 17.726 2.844 + 13960.000 18.641 2.831 + 13960.500 23.145 2.836 + 13961.000 23.892 2.847 + 13961.500 25.469 2.854 + 13962.000 27.627 2.854 + 13962.500 31.205 2.857 + 13963.000 36.684 2.867 + 13963.500 39.430 2.870 + 13964.000 41.234 2.866 + 13964.500 43.225 2.864 + 13965.000 44.118 2.864 + 13965.500 44.399 2.865 + 13966.000 42.644 2.862 + 13966.500 44.081 2.852 + 13967.000 44.349 2.845 + 13967.500 42.840 2.840 + 13968.000 41.426 2.840 + 13968.500 34.948 2.846 + 13969.000 30.509 2.852 + 13969.500 30.127 2.856 + 13970.000 28.559 2.860 + 13970.500 29.112 2.863 + 13971.000 27.533 2.862 + 13971.500 27.635 2.865 + 13972.000 24.018 2.879 + 13972.500 23.311 2.893 + 13973.000 23.162 2.888 + 13973.500 22.498 2.878 + 13974.000 22.258 2.877 + 13974.500 22.908 2.891 + 13975.000 23.714 2.893 + 13975.500 27.153 2.890 + 13976.000 30.482 2.878 + 13976.500 36.859 2.867 + 13977.000 40.603 2.860 + 13977.500 42.292 2.853 + 13978.000 45.155 2.838 + 13978.500 44.522 2.835 + 13979.000 41.957 2.841 + 13979.500 37.425 2.849 + 13980.000 31.559 2.854 + 13980.500 25.489 2.856 + 13981.000 22.401 2.853 + 13981.500 21.768 2.844 + 13982.000 21.989 2.843 + 13982.500 20.730 2.845 + 13983.000 21.280 2.852 + 13983.500 22.634 2.850 + 13984.000 25.281 2.826 + 13984.500 28.573 2.831 + 13985.000 30.380 2.842 + 13985.500 33.086 2.852 + 13986.000 35.131 2.862 + 13986.500 38.757 2.857 + 13987.000 39.327 2.846 + 13987.500 40.202 2.838 + 13988.000 41.119 2.842 + 13988.500 40.625 2.842 + 13989.000 39.719 2.837 + 13989.500 37.682 2.834 + 13990.000 36.390 2.830 + 13990.500 36.235 2.827 + 13991.000 36.418 2.828 + 13991.500 35.816 2.836 + 13992.000 34.194 2.841 + 13992.500 29.891 2.853 + 13993.000 28.375 2.851 + 13993.500 26.890 2.852 + 13994.000 25.245 2.846 + 13994.500 23.043 2.844 + 13995.000 20.277 2.844 + 13995.500 18.632 2.846 + 13996.000 16.359 2.846 + 13996.500 14.954 2.846 + 13997.000 14.571 2.846 + 13997.500 14.076 2.849 + 13998.000 14.424 2.840 + 13998.500 15.653 2.818 + 13999.000 16.913 2.805 + 13999.500 17.676 2.796 + 14000.000 18.110 2.800 + 14000.500 16.589 2.813 + 14001.000 15.563 2.832 + 14001.500 14.625 2.850 + 14002.000 14.345 2.857 + 14002.500 13.624 2.853 + 14003.000 13.821 2.852 + 14003.500 15.433 2.855 + 14004.000 17.819 2.866 + 14004.500 20.138 2.867 + 14005.000 20.832 2.859 + 14005.500 23.071 2.847 + 14006.000 25.027 2.841 + 14006.500 31.406 2.843 + 14007.000 33.549 2.844 + 14007.500 34.227 2.835 + 14008.000 32.250 2.823 + 14008.500 30.350 2.813 + 14009.000 28.751 2.824 + 14009.500 28.789 2.839 + 14010.000 29.414 2.840 + 14010.500 29.650 2.830 + 14011.000 27.339 2.816 + 14011.500 25.992 2.811 + 14012.000 23.587 2.822 + 14012.500 21.668 2.838 + 14013.000 20.259 2.855 + 14013.500 19.261 2.851 + 14014.000 20.183 2.851 + 14014.500 23.030 2.849 + 14015.000 26.318 2.845 + 14015.500 27.189 2.843 + 14016.000 28.231 2.841 + 14016.500 31.367 2.841 + 14017.000 35.468 2.843 + 14017.500 39.188 2.838 + 14018.000 40.251 2.832 + 14018.500 36.049 2.818 + 14019.000 32.721 2.814 + 14019.500 29.820 2.810 + 14020.000 27.988 2.798 + 14020.500 27.882 2.791 + 14021.000 27.068 2.802 + 14021.500 25.498 2.809 + 14022.000 23.042 2.828 + 14022.500 21.212 2.839 + 14023.000 20.763 2.838 + 14023.500 20.870 2.838 + 14024.000 25.341 2.847 + 14024.500 34.782 2.852 + 14025.000 41.856 2.855 + 14025.500 47.215 2.853 + 14026.000 48.130 2.851 + 14026.500 47.111 2.806 + 14027.000 46.370 2.790 + 14027.500 45.616 2.767 + 14028.000 43.712 2.776 + 14028.500 34.717 2.801 + 14029.000 31.499 2.802 + 14029.500 28.348 2.809 + 14030.000 25.124 2.821 + 14030.500 20.685 2.830 + 14031.000 26.381 2.836 + 14031.500 31.154 2.839 + 14032.000 32.855 2.843 + 14032.500 28.363 2.843 + 14033.000 23.009 2.837 + 14033.500 19.568 2.836 + 14034.000 19.198 2.832 + 14034.500 19.737 2.828 + 14035.000 25.565 2.824 + 14035.500 33.221 2.822 + 14036.000 37.791 2.820 + 14036.500 43.986 2.828 + 14037.000 46.782 2.832 + 14037.500 47.432 2.836 + 14038.000 50.648 2.835 + 14038.500 56.022 2.832 + 14039.000 59.352 2.832 + 14039.500 62.774 2.830 + 14040.000 67.744 2.828 + 14040.500 80.484 2.826 + 14041.000 79.253 2.823 + 14041.500 79.178 2.828 + 14042.000 75.191 2.830 + 14042.500 80.316 2.826 + 14043.000 88.567 2.820 + 14043.500 115.078 2.815 + 14044.000 111.354 2.802 + 14044.500 99.403 2.786 + 14045.000 68.576 2.780 + 14045.500 61.763 2.787 + 14046.000 57.039 2.796 + 14046.500 55.337 2.801 + 14047.000 58.928 2.801 + 14047.500 67.783 2.804 + 14048.000 89.586 2.802 + 14048.500 136.485 2.783 + 14049.000 131.089 2.770 + 14049.500 176.204 2.740 + 14050.000 184.448 2.713 + 14050.500 181.571 2.702 + 14051.000 155.835 2.702 + 14051.500 130.147 2.710 + 14052.000 84.096 2.743 + 14052.500 20.160 2.776 + 14053.000 22.349 2.825 + 14053.500 18.181 2.820 + 14054.000 19.100 2.822 + 14054.500 23.614 2.823 + 14055.000 28.465 2.818 + 14055.500 30.947 2.804 + 14056.000 30.984 2.800 + 14056.500 31.734 2.797 + 14057.000 33.985 2.792 + 14057.500 36.642 2.788 + 14058.000 35.171 2.789 + 14058.500 28.636 2.801 + 14059.000 29.731 2.811 + 14059.500 29.483 2.822 + 14060.000 30.517 2.832 + 14060.500 29.443 2.848 + 14061.000 27.983 2.865 + 14061.500 27.259 2.869 + 14062.000 27.006 2.862 + 14062.500 26.901 2.834 + 14063.000 26.447 2.817 + 14063.500 26.352 2.818 + 14064.000 25.318 2.833 + 14064.500 23.993 2.837 + 14065.000 24.013 2.843 + 14065.500 23.161 2.855 + 14066.000 21.754 2.874 + 14066.500 20.739 2.867 + 14067.000 19.859 2.843 + 14067.500 17.990 2.845 + 14068.000 17.150 2.845 + 14068.500 19.104 2.864 + 14069.000 19.210 2.867 + 14069.500 20.931 2.857 + 14070.000 21.616 2.850 + 14070.500 22.336 2.852 + 14071.000 23.240 2.873 + 14071.500 22.462 2.879 + 14072.000 22.301 2.889 + 14072.500 20.856 2.869 + 14073.000 20.831 2.858 + 14073.500 20.598 2.839 + 14074.000 19.950 2.833 + 14074.500 20.004 2.835 + 14075.000 19.855 2.854 + 14075.500 19.160 2.874 + 14076.000 18.756 2.889 + 14076.500 19.141 2.886 + 14077.000 19.710 2.882 + 14077.500 21.899 2.870 + 14078.000 22.914 2.868 + 14078.500 23.729 2.863 + 14079.000 24.638 2.858 + 14079.500 24.073 2.854 + 14080.000 23.925 2.854 + 14080.500 23.428 2.860 + 14081.000 22.494 2.869 + 14081.500 21.989 2.857 + 14082.000 21.516 2.856 + 14082.500 21.102 2.856 + 14083.000 20.642 2.864 + 14083.500 20.199 2.876 + 14084.000 19.757 2.880 + 14084.500 19.311 2.878 + 14085.000 18.867 2.876 + 14085.500 18.423 2.874 + 14086.000 17.979 2.873 + 14086.500 17.534 2.867 + 14087.000 17.090 2.866 + 14087.500 16.642 2.869 + 14088.000 16.200 2.873 + 14088.500 15.598 2.858 + 14089.000 14.928 2.851 + 14089.500 14.258 2.848 + 14090.000 13.717 2.846 + 14090.500 13.767 2.851 + 14091.000 13.697 2.867 + 14091.500 13.569 2.876 + 14092.000 12.941 2.854 + 14092.500 12.031 2.833 + 14093.000 11.396 2.838 + 14093.500 10.647 2.854 + 14094.000 10.807 2.876 + 14094.500 11.653 2.855 + 14095.000 13.638 2.851 + 14095.500 16.811 2.851 + 14096.000 18.469 2.851 + 14096.500 21.515 2.852 + 14097.000 23.332 2.856 + 14097.500 22.150 2.862 + 14098.000 20.231 2.864 + 14098.500 17.657 2.864 + 14099.000 15.586 2.864 + 14099.500 13.663 2.868 + 14100.000 16.594 2.881 + 14100.500 22.729 2.882 + 14101.000 51.995 2.870 + 14101.500 83.435 2.829 + 14102.000 98.457 2.794 + 14102.500 127.725 2.721 + 14103.000 134.216 2.720 + 14103.500 129.524 2.697 + 14104.000 120.363 2.703 + 14104.500 115.391 2.713 + 14105.000 114.994 2.724 + 14105.500 117.529 2.733 + 14106.000 118.311 2.744 + 14106.500 116.876 2.758 + 14107.000 115.449 2.756 + 14107.500 114.300 2.748 + 14108.000 111.174 2.736 + 14108.500 108.369 2.743 + 14109.000 106.936 2.752 + 14109.500 106.585 2.743 + 14110.000 100.999 2.734 + 14110.500 90.992 2.745 + 14111.000 81.607 2.770 + 14111.500 72.744 2.803 + 14112.000 67.688 2.818 + 14112.500 64.815 2.804 + 14113.000 63.882 2.796 + 14113.500 61.995 2.795 + 14114.000 60.489 2.802 + 14114.500 59.901 2.814 + 14115.000 60.204 2.815 + 14115.500 60.311 2.816 + 14116.000 64.939 2.789 + 14116.500 73.375 2.756 + 14117.000 74.112 2.750 + 14117.500 73.444 2.753 + 14118.000 71.864 2.763 + 14118.500 71.685 2.784 + 14119.000 71.896 2.786 + 14119.500 73.671 2.784 + 14120.000 74.250 2.784 + 14120.500 77.375 2.784 + 14121.000 81.080 2.778 + 14121.500 82.399 2.770 + 14122.000 86.495 2.770 + 14122.500 92.369 2.773 + 14123.000 98.351 2.778 + 14123.500 106.937 2.780 + 14124.000 116.975 2.783 + 14124.500 129.422 2.762 + 14125.000 132.685 2.744 + 14125.500 130.881 2.728 + 14126.000 126.637 2.727 + 14126.500 118.774 2.735 + 14127.000 93.785 2.745 + 14127.500 61.301 2.759 + 14128.000 50.322 2.799 + 14128.500 31.698 2.842 + 14129.000 24.828 2.857 + 14129.500 22.551 2.867 + 14130.000 21.285 2.870 + 14130.500 18.884 2.870 + 14131.000 17.793 2.875 + 14131.500 16.738 2.881 + 14132.000 15.944 2.882 + 14132.500 15.166 2.878 + 14133.000 15.328 2.876 + 14133.500 17.729 2.879 + 14134.000 19.297 2.880 + 14134.500 19.241 2.880 + 14135.000 19.226 2.860 + 14135.500 18.446 2.845 + 14136.000 17.940 2.842 + 14136.500 18.824 2.854 + 14137.000 19.524 2.870 + 14137.500 19.537 2.872 + 14138.000 19.864 2.866 + 14138.500 19.757 2.841 + 14139.000 19.959 2.834 + 14139.500 20.639 2.838 + 14140.000 20.840 2.840 + 14140.500 20.173 2.850 + 14141.000 19.980 2.856 + 14141.500 20.032 2.862 + 14142.000 19.856 2.871 + 14142.500 18.768 2.885 + 14143.000 18.323 2.886 + 14143.500 19.266 2.884 + 14144.000 19.834 2.880 + 14144.500 19.974 2.881 + 14145.000 20.051 2.879 + 14145.500 19.944 2.876 + 14146.000 20.078 2.864 + 14146.500 19.420 2.853 + 14147.000 19.116 2.845 + 14147.500 19.826 2.834 + 14148.000 20.243 2.840 + 14148.500 20.199 2.856 + 14149.000 19.990 2.861 + 14149.500 17.660 2.893 + 14150.000 16.764 2.899 + 14150.500 14.845 2.900 + 14151.000 15.169 2.883 + 14151.500 15.361 2.874 + 14152.000 16.828 2.865 + 14152.500 19.060 2.854 + 14153.000 20.044 2.859 + 14153.500 20.940 2.870 + 14154.000 24.698 2.881 + 14154.500 26.272 2.880 + 14155.000 27.229 2.869 + 14155.500 26.259 2.870 + 14156.000 25.327 2.874 + 14156.500 25.713 2.872 + 14157.000 26.563 2.868 + 14157.500 30.160 2.855 + 14158.000 31.768 2.850 + 14158.500 34.710 2.852 + 14159.000 38.267 2.855 + 14159.500 45.899 2.861 + 14160.000 57.941 2.858 + 14160.500 61.906 2.847 + 14161.000 82.800 2.821 + 14161.500 90.166 2.808 + 14162.000 93.484 2.795 + 14162.500 95.512 2.783 + 14163.000 100.794 2.768 + 14163.500 115.613 2.766 + 14164.000 126.932 2.797 + 14164.500 138.256 2.843 + 14165.000 149.108 2.908 + 14165.500 153.526 2.857 + 14166.000 158.037 2.837 + 14166.500 163.507 2.793 + 14167.000 158.249 2.828 + 14167.500 148.069 2.794 + 14168.000 149.643 2.770 + 14168.500 137.264 2.727 + 14169.000 123.827 2.713 + 14169.500 107.320 2.721 + 14170.000 89.838 2.729 + 14170.500 83.540 2.764 + 14171.000 93.079 2.801 + 14171.500 103.689 2.835 + 14172.000 122.088 2.859 + 14172.500 134.317 2.873 + 14173.000 132.635 2.837 + 14173.500 116.140 2.801 + 14174.000 105.644 2.741 + 14174.500 75.870 2.705 + 14175.000 69.902 2.774 + 14175.500 68.478 2.816 + 14176.000 69.792 2.859 + 14176.500 68.849 2.911 + 14177.000 66.087 2.892 + 14177.500 64.839 2.837 + 14178.000 64.608 2.817 + 14178.500 63.107 2.764 + 14179.000 61.417 2.763 + 14179.500 59.053 2.798 + 14180.000 56.385 2.807 + 14180.500 54.151 2.809 + 14181.000 51.725 2.809 + 14181.500 49.969 2.809 + 14182.000 52.582 2.827 + 14182.500 55.762 2.835 + 14183.000 60.173 2.842 + 14183.500 62.965 2.838 + 14184.000 64.238 2.838 + 14184.500 61.749 2.844 + 14185.000 59.845 2.856 + 14185.500 60.012 2.848 + 14186.000 60.034 2.840 + 14186.500 59.044 2.838 + 14187.000 58.483 2.841 + 14187.500 54.037 2.843 + 14188.000 52.464 2.850 + 14188.500 53.093 2.861 + 14189.000 53.605 2.861 + 14189.500 52.871 2.854 + 14190.000 52.290 2.854 + 14190.500 51.695 2.852 + 14191.000 51.607 2.849 + 14191.500 55.668 2.847 + 14192.000 60.085 2.839 + 14192.500 63.106 2.825 + 14193.000 71.353 2.828 + 14193.500 82.916 2.837 + 14194.000 107.309 2.900 + 14194.500 117.396 2.881 + 14195.000 122.079 2.806 + 14195.500 129.010 2.741 + 14196.000 130.525 2.702 + 14196.500 131.604 2.742 + 14197.000 131.290 2.766 + 14197.500 132.088 2.820 + 14198.000 132.282 2.827 + 14198.500 134.478 2.763 + 14199.000 134.433 2.731 + 14199.500 134.484 2.728 + 14200.000 133.710 2.742 + 14200.500 132.954 2.793 + 14201.000 133.433 2.805 + 14201.500 134.260 2.822 + 14202.000 134.935 2.841 + 14202.500 135.737 2.824 + 14203.000 145.938 2.761 + 14203.500 150.843 2.751 + 14204.000 160.388 2.752 + 14204.500 164.947 2.749 + 14205.000 165.702 2.727 + 14205.500 162.412 2.617 + 14206.000 150.467 2.637 + 14206.500 117.397 2.705 + 14207.000 105.784 2.744 + 14207.500 102.638 2.811 + 14208.000 86.210 2.847 + 14208.500 73.992 2.871 + 14209.000 71.856 2.876 + 14209.500 72.174 2.896 + 14210.000 82.861 2.901 + 14210.500 89.467 2.864 + 14211.000 94.672 2.828 + 14211.500 106.034 2.800 + 14212.000 109.886 2.742 + 14212.500 114.320 2.674 + 14213.000 117.062 2.671 + 14213.500 117.592 2.701 + 14214.000 124.552 2.749 + 14214.500 126.399 2.743 + 14215.000 129.900 2.743 + 14215.500 131.951 2.745 + 14216.000 140.891 2.772 + 14216.500 144.725 2.780 + 14217.000 151.968 2.783 + 14217.500 155.630 2.780 + 14218.000 158.504 2.780 + 14218.500 159.960 2.781 + 14219.000 153.974 2.785 + 14219.500 152.663 2.763 + 14220.000 116.146 2.752 + 14220.500 86.750 2.796 + 14221.000 79.779 2.809 + 14221.500 74.244 2.827 + 14222.000 64.045 2.831 + 14222.500 59.564 2.840 + 14223.000 55.523 2.850 + 14223.500 55.194 2.851 + 14224.000 55.777 2.868 + 14224.500 57.292 2.880 + 14225.000 65.247 2.875 + 14225.500 69.646 2.867 + 14226.000 92.406 2.822 + 14226.500 99.357 2.810 + 14227.000 106.573 2.787 + 14227.500 109.878 2.792 + 14228.000 115.484 2.797 + 14228.500 118.581 2.797 + 14229.000 121.438 2.776 + 14229.500 118.617 2.743 + 14230.000 118.826 2.732 + 14230.500 113.286 2.731 + 14231.000 110.627 2.741 + 14231.500 110.022 2.765 + 14232.000 107.079 2.777 + 14232.500 106.053 2.790 + 14233.000 105.372 2.789 + 14233.500 105.609 2.789 + 14234.000 106.260 2.790 + 14234.500 104.562 2.794 + 14235.000 102.639 2.795 + 14235.500 103.934 2.794 + 14236.000 115.722 2.791 + 14236.500 124.461 2.786 + 14237.000 132.444 2.787 + 14237.500 144.134 2.811 + 14238.000 141.103 2.799 + 14238.500 133.878 2.783 + 14239.000 119.993 2.747 + 14239.500 116.393 2.739 + 14240.000 110.832 2.755 + 14240.500 112.660 2.776 + 14241.000 116.255 2.783 + 14241.500 120.449 2.786 + 14242.000 126.244 2.790 + 14242.500 135.105 2.794 + 14243.000 143.829 2.790 + 14243.500 151.546 2.787 + 14244.000 159.020 2.773 + 14244.500 167.673 2.766 + 14245.000 172.474 2.769 + 14245.500 175.778 2.769 + 14246.000 176.977 2.756 + 14246.500 179.647 2.761 + 14247.000 181.181 2.793 + 14247.500 182.835 2.799 + 14248.000 180.449 2.807 + 14248.500 174.074 2.744 + 14249.000 169.156 2.709 + 14249.500 162.180 2.689 + 14250.000 159.220 2.695 + 14250.500 157.798 2.702 + 14251.000 158.141 2.719 + 14251.500 161.205 2.741 + 14252.000 172.867 2.762 + 14252.500 174.820 2.764 + 14253.000 177.564 2.749 + 14253.500 177.525 2.680 + 14254.000 178.087 2.574 + 14254.500 174.383 2.582 + 14255.000 171.423 2.620 + 14255.500 166.608 2.644 + 14256.000 161.602 2.696 + 14256.500 159.132 2.720 + 14257.000 160.354 2.696 + 14257.500 161.894 2.689 + 14258.000 164.396 2.699 + 14258.500 165.901 2.704 + 14259.000 166.328 2.699 + 14259.500 165.971 2.695 + 14260.000 166.127 2.741 + 14260.500 164.353 2.792 + 14261.000 163.479 2.786 + 14261.500 165.344 2.769 + 14262.000 166.722 2.767 + 14262.500 176.992 2.779 + 14263.000 182.471 2.773 + 14263.500 189.521 2.752 + 14264.000 191.614 2.704 + 14264.500 193.236 2.695 + 14265.000 191.711 2.735 + 14265.500 190.988 2.725 + 14266.000 191.041 2.871 + 14266.500 192.685 2.855 + 14267.000 193.526 2.837 + 14267.500 194.058 2.787 + 14268.000 192.540 2.758 + 14268.500 188.694 2.763 + 14269.000 186.673 2.766 + 14269.500 186.855 2.764 + 14270.000 187.385 2.759 + 14270.500 188.656 2.783 + 14271.000 187.650 2.788 + 14271.500 188.582 2.799 + 14272.000 190.128 2.783 + 14272.500 190.266 2.745 + 14273.000 188.894 2.707 + 14273.500 187.224 2.714 + 14274.000 185.995 2.786 + 14274.500 183.381 2.811 + 14275.000 182.114 2.807 + 14275.500 181.569 2.792 + 14276.000 181.464 2.783 + 14276.500 182.282 2.758 + 14277.000 181.569 2.716 + 14277.500 180.654 2.683 + 14278.000 181.447 2.651 + 14278.500 181.448 2.665 + 14279.000 182.320 2.781 + 14279.500 182.234 2.766 + 14280.000 182.588 2.778 + 14280.500 180.819 2.722 + 14281.000 182.197 2.701 + 14281.500 182.429 2.636 + 14282.000 181.764 2.555 + 14282.500 182.741 2.564 + 14283.000 181.719 2.579 + 14283.500 180.847 2.599 + 14284.000 180.172 2.604 + 14284.500 179.383 2.617 + 14285.000 179.174 2.627 + 14285.500 177.102 2.677 + 14286.000 174.393 2.708 + 14286.500 171.632 2.736 + 14287.000 168.644 2.728 + 14287.500 168.650 2.717 + 14288.000 172.198 2.704 + 14288.500 175.619 2.692 + 14289.000 179.069 2.680 + 14289.500 173.253 2.658 + 14290.000 171.074 2.673 + 14290.500 163.822 2.694 + 14291.000 166.420 2.734 + 14291.500 170.037 2.754 + 14292.000 172.865 2.723 + 14292.500 177.209 2.614 + 14293.000 179.090 2.544 + 14293.500 179.186 2.517 + 14294.000 179.316 2.630 + 14294.500 179.171 2.615 + 14295.000 179.796 2.610 + 14295.500 180.614 2.584 + 14296.000 179.628 2.592 + 14296.500 179.633 2.613 + 14297.000 174.013 2.637 + 14297.500 165.539 2.695 + 14298.000 159.793 2.730 + 14298.500 159.525 2.797 + 14299.000 159.573 2.781 + 14299.500 159.992 2.769 + 14300.000 160.322 2.753 + 14300.500 169.577 2.689 + 14301.000 172.428 2.656 + 14301.500 173.440 2.617 + 14302.000 169.351 2.636 + 14302.500 161.417 2.706 + 14303.000 159.828 2.712 + 14303.500 159.687 2.745 + 14304.000 162.550 2.749 + 14304.500 168.750 2.683 + 14305.000 173.563 2.665 + 14305.500 177.398 2.657 + 14306.000 180.087 2.667 + 14306.500 179.359 2.702 + 14307.000 178.946 2.730 + 14307.500 174.662 2.750 + 14308.000 165.712 2.739 + 14308.500 155.057 2.695 + 14309.000 146.645 2.699 + 14309.500 138.089 2.699 + 14310.000 122.371 2.736 + 14310.500 109.409 2.772 + 14311.000 109.262 2.780 + 14311.500 110.969 2.788 + 14312.000 114.653 2.798 + 14312.500 124.731 2.813 + 14313.000 133.094 2.816 + 14313.500 133.888 2.804 + 14314.000 134.170 2.783 + 14314.500 114.489 2.734 + 14315.000 104.102 2.747 + 14315.500 81.624 2.787 + 14316.000 65.547 2.822 + 14316.500 56.111 2.858 + 14317.000 52.344 2.857 + 14317.500 56.016 2.855 + 14318.000 53.678 2.852 + 14318.500 68.351 2.832 + 14319.000 86.048 2.814 + 14319.500 103.090 2.804 + 14320.000 150.245 2.762 + 14320.500 161.337 2.733 + 14321.000 165.614 2.727 + 14321.500 165.121 2.727 + 14322.000 164.319 2.739 + 14322.500 168.686 2.750 + 14323.000 170.727 2.749 + 14323.500 169.523 2.721 + 14324.000 166.688 2.637 + 14324.500 153.611 2.641 + 14325.000 146.435 2.657 + 14325.500 138.673 2.697 + 14326.000 130.086 2.749 + 14326.500 116.007 2.780 + 14327.000 108.036 2.775 + 14327.500 99.349 2.743 + 14328.000 84.808 2.705 + 14328.500 81.378 2.715 + 14329.000 80.735 2.779 + 14329.500 81.107 2.796 + 14330.000 86.742 2.819 + 14330.500 108.109 2.852 + 14331.000 112.364 2.847 + 14331.500 111.529 2.812 + 14332.000 110.633 2.777 + 14332.500 109.660 2.701 + 14333.000 117.773 2.712 + 14333.500 122.912 2.709 + 14334.000 158.096 2.693 + 14334.500 157.225 2.640 + 14335.000 159.576 2.597 + 14335.500 159.362 2.604 + 14336.000 159.721 2.635 + 14336.500 159.869 2.710 + 14337.000 160.484 2.790 + 14337.500 160.470 2.824 + 14338.000 159.210 2.851 + 14338.500 153.893 2.773 + 14339.000 150.690 2.734 + 14339.500 145.554 2.673 + 14340.000 142.102 2.646 + 14340.500 136.556 2.740 + 14341.000 134.093 2.728 + 14341.500 129.920 2.757 + 14342.000 124.717 2.734 + 14342.500 136.123 2.712 + 14343.000 142.867 2.692 + 14343.500 154.415 2.651 + 14344.000 158.420 2.577 + 14344.500 163.997 2.483 + 14345.000 148.916 2.489 + 14345.500 141.794 2.472 + 14346.000 128.044 2.433 + 14346.500 110.660 2.252 + 14347.000 98.909 2.279 + 14347.500 93.722 2.420 + 14348.000 91.545 2.554 + 14348.500 101.251 2.843 + 14349.000 107.297 2.836 + 14349.500 116.426 2.865 + 14350.000 124.913 2.864 + 14350.500 140.202 2.807 + 14351.000 156.578 2.682 + 14351.500 162.187 2.562 + 14352.000 144.212 2.487 + 14352.500 130.368 2.436 + 14353.000 117.282 2.462 + 14353.500 109.753 2.511 + 14354.000 100.301 2.571 + 14354.500 95.742 2.736 + 14355.000 88.889 2.800 + 14355.500 81.726 2.789 + 14356.000 78.121 2.826 + 14356.500 73.892 2.822 + 14357.000 75.671 2.804 + 14357.500 85.894 2.789 + 14358.000 86.789 2.783 + 14358.500 116.650 2.785 + 14359.000 114.191 2.786 + 14359.500 112.012 2.779 + 14360.000 87.610 2.781 + 14360.500 70.910 2.803 + 14361.000 68.600 2.810 + 14361.500 66.690 2.821 + 14362.000 64.774 2.824 + 14362.500 60.323 2.837 + 14363.000 51.891 2.842 + 14363.500 44.618 2.841 + 14364.000 39.436 2.840 + 14364.500 34.408 2.838 + 14365.000 31.495 2.840 + 14365.500 27.868 2.845 + 14366.000 24.909 2.846 + 14366.500 20.711 2.849 + 14367.000 18.666 2.856 + 14367.500 18.276 2.856 + 14368.000 19.452 2.848 + 14368.500 20.915 2.839 + 14369.000 20.534 2.823 + 14369.500 21.573 2.813 + 14370.000 22.639 2.799 + 14370.500 27.102 2.790 + 14371.000 33.252 2.794 + 14371.500 41.045 2.799 + 14372.000 52.655 2.802 + 14372.500 72.705 2.786 + 14373.000 87.790 2.770 + 14373.500 91.761 2.732 + 14374.000 102.036 2.707 + 14374.500 104.668 2.700 + 14375.000 107.738 2.703 + 14375.500 112.067 2.706 + 14376.000 114.199 2.720 + 14376.500 113.799 2.728 + 14377.000 110.118 2.737 + 14377.500 99.112 2.746 + 14378.000 94.364 2.780 + 14378.500 83.845 2.805 + 14379.000 78.888 2.807 + 14379.500 71.533 2.803 + 14380.000 65.391 2.801 + 14380.500 59.582 2.804 + 14381.000 56.848 2.804 + 14381.500 56.498 2.805 + 14382.000 57.015 2.802 + 14382.500 57.967 2.817 + 14383.000 59.857 2.835 + 14383.500 63.574 2.823 + 14384.000 69.656 2.808 + 14384.500 76.426 2.752 + 14385.000 82.722 2.761 + 14385.500 81.671 2.757 + 14386.000 79.367 2.771 + 14386.500 70.793 2.790 + 14387.000 67.632 2.789 + 14387.500 62.852 2.787 + 14388.000 75.147 2.771 + 14388.500 82.223 2.748 + 14389.000 98.046 2.730 + 14389.500 99.247 2.719 + 14390.000 114.451 2.705 + 14390.500 118.004 2.696 + 14391.000 117.924 2.707 + 14391.500 118.756 2.715 + 14392.000 121.396 2.714 + 14392.500 130.875 2.698 + 14393.000 136.551 2.675 + 14393.500 144.008 2.654 + 14394.000 155.492 2.669 + 14394.500 158.424 2.705 + 14395.000 156.056 2.719 + 14395.500 143.461 2.729 + 14396.000 120.649 2.724 + 14396.500 82.121 2.772 + 14397.000 72.398 2.800 + 14397.500 83.640 2.798 + 14398.000 81.723 2.785 + 14398.500 128.235 2.754 + 14399.000 165.144 2.714 + 14399.500 160.734 2.707 + 14400.000 164.300 2.730 + 14400.500 113.452 2.767 + 14401.000 95.740 2.794 + 14401.500 79.252 2.839 + 14402.000 54.712 2.852 + 14402.500 24.955 2.852 + 14403.000 15.575 2.838 + 14403.500 14.918 2.836 + 14404.000 14.297 2.839 + 14404.500 15.280 2.849 + 14405.000 18.532 2.860 + 14405.500 20.093 2.863 + 14406.000 20.794 2.862 + 14406.500 22.256 2.853 + 14407.000 23.204 2.857 + 14407.500 25.336 2.865 + 14408.000 25.439 2.871 + 14408.500 25.557 2.877 + 14409.000 24.874 2.882 + 14409.500 19.880 2.861 + 14410.000 15.114 2.850 + 14410.500 11.883 2.834 + 14411.000 11.421 2.829 + 14411.500 10.786 2.824 + 14412.000 10.445 2.828 + 14412.500 11.068 2.830 + 14413.000 10.612 2.830 + 14413.500 12.007 2.831 + 14414.000 13.234 2.837 + 14414.500 15.094 2.849 + 14415.000 16.896 2.856 + 14415.500 18.550 2.858 + 14416.000 19.838 2.859 + 14416.500 20.555 2.846 + 14417.000 21.429 2.844 + 14417.500 21.602 2.851 + 14418.000 21.580 2.858 + 14418.500 24.054 2.857 + 14419.000 26.094 2.856 + 14419.500 29.230 2.855 + 14420.000 30.270 2.852 + 14420.500 30.170 2.837 + 14421.000 30.257 2.835 + 14421.500 27.355 2.837 + 14422.000 24.911 2.844 + 14422.500 20.877 2.845 + 14423.000 19.292 2.836 + 14423.500 19.450 2.834 + 14424.000 19.836 2.834 + 14424.500 23.509 2.843 + 14425.000 25.014 2.854 + 14425.500 25.398 2.855 + 14426.000 26.643 2.855 + 14426.500 31.818 2.845 + 14427.000 40.575 2.838 + 14427.500 41.450 2.832 + 14428.000 38.872 2.832 + 14428.500 30.275 2.842 + 14429.000 17.295 2.852 + 14429.500 14.577 2.866 + 14430.000 11.778 2.873 + 14430.500 12.678 2.874 + 14431.000 13.743 2.868 + 14431.500 14.470 2.848 + 14432.000 14.408 2.852 + 14432.500 15.065 2.851 + 14433.000 16.158 2.839 + 14433.500 17.709 2.837 + 14434.000 18.752 2.836 + 14434.500 19.271 2.852 + 14435.000 19.311 2.859 + 14435.500 20.079 2.855 + 14436.000 20.345 2.846 + 14436.500 23.446 2.822 + 14437.000 25.790 2.822 + 14437.500 27.831 2.836 + 14438.000 29.496 2.847 + 14438.500 30.717 2.852 + 14439.000 32.410 2.854 + 14439.500 34.387 2.856 + 14440.000 37.323 2.863 + 14440.500 34.982 2.863 + 14441.000 30.584 2.856 + 14441.500 22.234 2.852 + 14442.000 15.700 2.832 + 14442.500 15.036 2.817 + 14443.000 16.089 2.839 + 14443.500 19.732 2.855 + 14444.000 21.608 2.871 + 14444.500 39.118 2.857 + 14445.000 49.601 2.843 + 14445.500 51.611 2.830 + 14446.000 48.346 2.820 + 14446.500 32.030 2.821 + 14447.000 23.837 2.825 + 14447.500 17.852 2.852 + 14448.000 16.463 2.871 + 14448.500 15.018 2.903 + 14449.000 14.425 2.898 + 14449.500 15.852 2.900 + 14450.000 21.076 2.900 + 14450.500 37.282 2.904 + 14451.000 67.845 2.884 + 14451.500 106.927 2.852 + 14452.000 139.480 2.826 + 14452.500 173.430 2.801 + 14453.000 177.309 2.770 + 14453.500 176.685 2.723 + 14454.000 173.602 2.666 + 14454.500 162.872 2.670 + 14455.000 151.434 2.682 + 14455.500 129.227 2.736 + 14456.000 110.212 2.756 + 14456.500 72.921 2.815 + 14457.000 55.952 2.827 + 14457.500 42.549 2.861 + 14458.000 32.712 2.856 + 14458.500 22.673 2.925 + 14459.000 23.056 2.929 + 14459.500 23.977 2.922 + 14460.000 24.661 2.912 + 14460.500 22.070 2.863 + 14461.000 20.626 2.854 + 14461.500 20.739 2.850 + 14462.000 21.160 2.854 + 14462.500 24.454 2.858 + 14463.000 32.808 2.857 + 14463.500 44.551 2.853 + 14464.000 51.276 2.848 + 14464.500 68.241 2.836 + 14465.000 71.326 2.824 + 14465.500 70.648 2.808 + 14466.000 65.721 2.800 + 14466.500 58.710 2.785 + 14467.000 42.089 2.811 + 14467.500 36.558 2.834 + 14468.000 48.010 2.875 + 14468.500 57.694 2.866 + 14469.000 77.960 2.822 + 14469.500 114.187 2.791 + 14470.000 112.402 2.767 + 14470.500 98.892 2.783 + 14471.000 77.977 2.801 + 14471.500 61.205 2.827 + 14472.000 46.778 2.837 + 14472.500 39.012 2.857 + 14473.000 27.026 2.884 + 14473.500 28.169 2.931 + 14474.000 35.689 2.940 + 14474.500 61.669 2.923 + 14475.000 69.868 2.872 + 14475.500 118.637 2.819 + 14476.000 143.990 2.794 + 14476.500 160.176 2.748 + 14477.000 152.968 2.668 + 14477.500 155.156 2.641 + 14478.000 102.365 2.609 + 14478.500 111.794 2.666 + 14479.000 51.458 2.730 + 14479.500 43.848 2.786 + 14480.000 39.115 2.812 + 14480.500 42.557 2.863 + 14481.000 48.182 2.860 + 14481.500 78.025 2.843 + 14482.000 94.608 2.816 + 14482.500 139.436 2.737 + 14483.000 140.061 2.722 + 14483.500 130.796 2.710 + 14484.000 117.610 2.722 + 14484.500 84.431 2.751 + 14485.000 75.027 2.789 + 14485.500 68.147 2.790 + 14486.000 60.065 2.794 + 14486.500 54.357 2.800 + 14487.000 53.127 2.792 + 14487.500 60.467 2.790 + 14488.000 68.920 2.720 + 14488.500 107.132 2.646 + 14489.000 128.137 2.590 + 14489.500 152.941 2.564 + 14490.000 148.837 2.573 + 14490.500 138.311 2.590 + 14491.000 120.449 2.636 + 14491.500 86.381 2.697 + 14492.000 61.502 2.761 + 14492.500 42.449 2.805 + 14493.000 41.541 2.854 + 14493.500 40.584 2.858 + 14494.000 46.486 2.876 + 14494.500 76.745 2.871 + 14495.000 104.057 2.791 + 14495.500 119.872 2.773 + 14496.000 154.683 2.744 + 14496.500 152.829 2.715 + 14497.000 143.626 2.716 + 14497.500 107.969 2.723 + 14498.000 110.980 2.748 + 14498.500 75.267 2.782 + 14499.000 70.039 2.806 + 14499.500 57.918 2.815 + 14500.000 57.678 2.813 + 14500.500 72.100 2.801 + 14501.000 84.959 2.788 + 14501.500 82.989 2.783 + 14502.000 108.741 2.791 + 14502.500 119.211 2.758 + 14503.000 118.407 2.727 + 14503.500 115.883 2.725 + 14504.000 114.959 2.737 + 14504.500 116.241 2.753 + 14505.000 126.166 2.756 + 14505.500 133.173 2.757 + 14506.000 142.315 2.756 + 14506.500 153.449 2.755 + 14507.000 159.282 2.750 + 14507.500 166.777 2.746 + 14508.000 163.983 2.747 + 14508.500 151.669 2.741 + 14509.000 133.344 2.740 + 14509.500 110.821 2.751 + 14510.000 77.930 2.759 + 14510.500 23.668 2.845 + 14511.000 26.327 2.880 + 14511.500 24.068 2.913 + 14512.000 27.608 2.918 + 14512.500 36.656 2.899 + 14513.000 40.959 2.870 + 14513.500 43.459 2.837 + 14514.000 45.125 2.826 + 14514.500 45.137 2.822 + 14515.000 47.453 2.826 + 14515.500 50.166 2.834 + 14516.000 52.391 2.836 + 14516.500 48.901 2.826 + 14517.000 44.754 2.811 + 14517.500 35.098 2.810 + 14518.000 28.799 2.830 + 14518.500 29.196 2.864 + 14519.000 33.396 2.874 + 14519.500 54.224 2.859 + 14520.000 86.084 2.828 + 14520.500 117.419 2.738 + 14521.000 116.252 2.726 + 14521.500 108.490 2.745 + 14522.000 80.312 2.775 + 14522.500 59.226 2.808 + 14523.000 61.501 2.812 + 14523.500 58.296 2.806 + 14524.000 58.909 2.806 + 14524.500 60.065 2.814 + 14525.000 55.356 2.829 + 14525.500 50.882 2.834 + 14526.000 46.823 2.838 + 14526.500 39.081 2.851 + 14527.000 35.379 2.856 + 14527.500 33.542 2.850 + 14528.000 33.779 2.836 + 14528.500 40.555 2.830 + 14529.000 48.230 2.830 + 14529.500 61.962 2.834 + 14530.000 79.017 2.827 + 14530.500 118.855 2.810 + 14531.000 116.798 2.792 + 14531.500 118.372 2.787 + 14532.000 99.881 2.800 + 14532.500 66.063 2.816 + 14533.000 51.643 2.821 + 14533.500 42.186 2.818 + 14534.000 31.123 2.822 + 14534.500 29.212 2.856 + 14535.000 29.409 2.903 + 14535.500 33.516 2.898 + 14536.000 37.318 2.887 + 14536.500 43.818 2.855 + 14537.000 45.649 2.865 + 14537.500 47.548 2.876 + 14538.000 47.433 2.880 + 14538.500 45.853 2.859 + 14539.000 45.529 2.849 + 14539.500 44.626 2.835 + 14540.000 45.916 2.834 + 14540.500 56.906 2.829 + 14541.000 70.932 2.814 + 14541.500 78.352 2.799 + 14542.000 98.597 2.782 + 14542.500 90.103 2.791 + 14543.000 67.788 2.806 + 14543.500 70.820 2.836 + 14544.000 35.460 2.879 + 14544.500 33.520 2.907 + 14545.000 25.350 2.901 + 14545.500 28.069 2.872 + 14546.000 31.632 2.857 + 14546.500 35.442 2.848 + 14547.000 36.804 2.845 + 14547.500 39.811 2.836 + 14548.000 42.970 2.828 + 14548.500 45.459 2.814 + 14549.000 46.532 2.808 + 14549.500 46.629 2.804 + 14550.000 46.740 2.805 + 14550.500 46.629 2.809 + 14551.000 46.653 2.814 + 14551.500 45.977 2.819 + 14552.000 45.931 2.840 + 14552.500 47.933 2.858 + 14553.000 49.775 2.853 + 14553.500 53.225 2.836 + 14554.000 54.342 2.818 + 14554.500 45.987 2.818 + 14555.000 35.533 2.824 + 14555.500 26.802 2.848 + 14556.000 18.177 2.857 + 14556.500 15.208 2.905 + 14557.000 13.553 2.925 + 14557.500 14.591 2.948 + 14558.000 19.211 2.958 + 14558.500 31.938 2.932 + 14559.000 47.612 2.907 + 14559.500 66.437 2.863 + 14560.000 80.091 2.798 + 14560.500 101.386 2.767 + 14561.000 97.231 2.751 + 14561.500 74.059 2.759 + 14562.000 65.293 2.805 + 14562.500 58.827 2.814 + 14563.000 55.069 2.811 + 14563.500 55.515 2.802 + 14564.000 55.274 2.802 + 14564.500 56.799 2.801 + 14565.000 58.779 2.795 + 14565.500 59.896 2.793 + 14566.000 60.868 2.803 + 14566.500 56.063 2.822 + 14567.000 51.211 2.843 + 14567.500 44.968 2.843 + 14568.000 40.067 2.842 + 14568.500 39.227 2.841 + 14569.000 37.828 2.839 + 14569.500 36.525 2.838 + 14570.000 35.425 2.837 + 14570.500 34.356 2.835 + 14571.000 33.120 2.834 + 14571.500 32.739 2.833 + 14572.000 33.527 2.831 + 14572.500 39.880 2.823 + 14573.000 44.491 2.824 + 14573.500 55.108 2.829 + 14574.000 59.185 2.842 + 14574.500 64.868 2.851 + 14575.000 63.092 2.841 + 14575.500 95.738 2.818 + 14576.000 109.497 2.788 + 14576.500 113.811 2.749 + 14577.000 106.864 2.730 + 14577.500 105.132 2.732 + 14578.000 97.575 2.746 + 14578.500 90.954 2.760 + 14579.000 84.064 2.756 + 14579.500 77.177 2.758 + 14580.000 70.436 2.767 + 14580.500 63.541 2.779 + 14581.000 56.614 2.783 + 14581.500 50.341 2.783 + 14582.000 42.195 2.790 + 14582.500 39.824 2.810 + 14583.000 40.912 2.828 + 14583.500 45.849 2.831 + 14584.000 51.177 2.823 + 14584.500 68.933 2.752 + 14585.000 81.316 2.720 + 14585.500 91.702 2.520 + 14586.000 99.451 2.473 + 14586.500 100.026 2.505 + 14587.000 94.274 2.585 + 14587.500 80.996 2.662 + 14588.000 78.246 2.728 + 14588.500 75.096 2.792 + 14589.000 79.499 2.839 + 14589.500 87.913 2.845 + 14590.000 97.341 2.809 + 14590.500 106.554 2.766 + 14591.000 115.674 2.697 + 14591.500 125.129 2.664 + 14592.000 134.837 2.592 + 14592.500 142.283 2.372 + 14593.000 142.241 2.330 + 14593.500 141.310 2.316 + 14594.000 139.283 2.169 + 14594.500 128.556 2.067 + 14595.000 119.871 2.084 + 14595.500 98.062 2.229 + 14596.000 78.686 2.399 + 14596.500 72.277 2.709 + 14597.000 71.709 2.753 + 14597.500 74.732 2.786 + 14598.000 78.562 2.780 + 14598.500 81.167 2.772 + 14599.000 85.705 2.750 + 14599.500 89.944 2.689 + 14600.000 112.099 2.614 + 14600.500 127.684 2.331 + 14601.000 139.029 2.221 + 14601.500 145.231 2.205 + 14602.000 148.062 2.188 + 14602.500 147.992 2.209 + 14603.000 147.670 2.236 + 14603.500 146.936 2.263 + 14604.000 142.716 2.255 + 14604.500 140.494 2.222 + 14605.000 137.592 2.246 + 14605.500 122.154 2.359 + 14606.000 95.310 2.491 + 14606.500 65.905 2.685 + 14607.000 62.334 2.749 + 14607.500 51.577 2.756 + 14608.000 46.463 2.756 + 14608.500 42.273 2.776 + 14609.000 27.059 2.799 + 14609.500 20.856 2.809 + 14610.000 17.495 2.820 + 14610.500 14.837 2.823 + 14611.000 12.860 2.824 + 14611.500 13.610 2.820 + 14612.000 13.948 2.820 + 14612.500 17.030 2.820 + 14613.000 18.595 2.818 + 14613.500 21.208 2.812 + 14614.000 22.877 2.810 + 14614.500 27.321 2.818 + 14615.000 28.349 2.820 + 14615.500 29.524 2.819 + 14616.000 30.981 2.799 + 14616.500 36.250 2.783 + 14617.000 44.952 2.776 + 14617.500 55.932 2.787 + 14618.000 62.766 2.821 + 14618.500 67.942 2.839 + 14619.000 75.710 2.844 + 14619.500 87.080 2.826 + 14620.000 93.405 2.811 + 14620.500 92.041 2.793 + 14621.000 87.416 2.781 + 14621.500 81.971 2.764 + 14622.000 81.968 2.757 + 14622.500 81.613 2.770 + 14623.000 79.310 2.780 + 14623.500 75.224 2.782 + 14624.000 70.297 2.780 + 14624.500 65.554 2.783 + 14625.000 61.627 2.805 + 14625.500 59.894 2.805 + 14626.000 62.181 2.803 + 14626.500 69.173 2.773 + 14627.000 77.671 2.759 + 14627.500 91.841 2.735 + 14628.000 101.118 2.726 + 14628.500 114.652 2.698 + 14629.000 112.586 2.668 + 14629.500 111.074 2.676 + 14630.000 110.726 2.692 + 14630.500 112.928 2.734 + 14631.000 120.680 2.710 + 14631.500 121.909 2.648 + 14632.000 118.506 2.544 + 14632.500 105.343 2.551 + 14633.000 93.132 2.582 + 14633.500 89.291 2.676 + 14634.000 91.211 2.700 + 14634.500 94.648 2.760 + 14635.000 95.252 2.758 + 14635.500 90.841 2.752 + 14636.000 87.944 2.741 + 14636.500 85.763 2.755 + 14637.000 83.419 2.813 + 14637.500 100.574 2.807 + 14638.000 128.334 2.811 + 14638.500 126.727 2.743 + 14639.000 123.188 2.653 + 14639.500 97.674 2.590 + 14640.000 80.310 2.595 + 14640.500 48.331 2.715 + 14641.000 52.438 2.776 + 14641.500 73.399 2.859 + 14642.000 88.742 2.851 + 14642.500 102.373 2.775 + 14643.000 93.459 2.726 + 14643.500 79.331 2.677 + 14644.000 69.379 2.721 + 14644.500 75.665 2.765 + 14645.000 86.605 2.762 + 14645.500 89.411 2.658 + 14646.000 90.649 2.603 + 14646.500 71.312 2.656 + 14647.000 64.932 2.695 + 14647.500 67.281 2.770 + 14648.000 59.660 2.863 + 14648.500 99.559 2.851 + 14649.000 91.622 2.807 + 14649.500 81.724 2.764 + 14650.000 63.341 2.754 + 14650.500 47.132 2.808 + 14651.000 40.423 2.829 + 14651.500 38.650 2.854 + 14652.000 36.513 2.870 + 14652.500 35.411 2.888 + 14653.000 33.751 2.888 + 14653.500 34.168 2.886 + 14654.000 37.252 2.882 + 14654.500 46.778 2.868 + 14655.000 55.113 2.854 + 14655.500 64.447 2.834 + 14656.000 69.426 2.819 + 14656.500 87.411 2.805 + 14657.000 94.240 2.795 + 14657.500 105.489 2.763 + 14658.000 110.127 2.752 + 14658.500 116.990 2.739 + 14659.000 119.985 2.735 + 14659.500 120.470 2.729 + 14660.000 120.263 2.710 + 14660.500 117.769 2.684 + 14661.000 112.282 2.674 + 14661.500 108.055 2.679 + 14662.000 104.102 2.688 + 14662.500 106.336 2.701 + 14663.000 108.790 2.709 + 14663.500 108.539 2.713 + 14664.000 107.066 2.714 + 14664.500 84.222 2.712 + 14665.000 61.306 2.709 + 14665.500 54.441 2.718 + 14666.000 52.698 2.735 + 14666.500 52.796 2.754 + 14667.000 52.898 2.752 + 14667.500 54.414 2.751 + 14668.000 62.126 2.750 + 14668.500 64.239 2.768 + 14669.000 72.024 2.779 + 14669.500 80.205 2.774 + 14670.000 87.829 2.762 + 14670.500 93.240 2.752 + 14671.000 98.029 2.741 + 14671.500 101.549 2.735 + 14672.000 104.060 2.732 + 14672.500 111.726 2.717 + 14673.000 114.608 2.704 + 14673.500 116.206 2.698 + 14674.000 117.214 2.700 + 14674.500 117.143 2.705 + 14675.000 117.814 2.704 + 14675.500 117.619 2.703 + 14676.000 120.369 2.705 + 14676.500 123.749 2.697 + 14677.000 125.145 2.685 + 14677.500 123.381 2.684 + 14678.000 121.037 2.691 + 14678.500 117.729 2.699 + 14679.000 114.235 2.697 + 14679.500 109.712 2.697 + 14680.000 107.092 2.701 + 14680.500 112.492 2.719 + 14681.000 114.695 2.744 + 14681.500 120.304 2.776 + 14682.000 124.176 2.769 + 14682.500 135.511 2.889 + 14683.000 141.792 2.859 + 14683.500 150.303 2.817 + 14684.000 158.142 2.760 + 14684.500 153.447 2.687 + 14685.000 145.466 2.614 + 14685.500 134.615 2.573 + 14686.000 120.227 2.580 + 14686.500 80.043 2.626 + 14687.000 62.423 2.682 + 14687.500 52.991 2.730 + 14688.000 43.793 2.767 + 14688.500 42.135 2.764 + 14689.000 48.260 2.756 + 14689.500 49.955 2.754 + 14690.000 50.343 2.753 + 14690.500 47.484 2.759 + 14691.000 44.924 2.773 + 14691.500 48.347 2.786 + 14692.000 60.292 2.799 + 14692.500 78.281 2.787 + 14693.000 83.772 2.773 + 14693.500 90.166 2.770 + 14694.000 84.026 2.774 + 14694.500 65.120 2.796 + 14695.000 47.220 2.813 + 14695.500 40.916 2.838 + 14696.000 34.452 2.844 + 14696.500 38.020 2.838 + 14697.000 39.335 2.840 + 14697.500 40.014 2.853 + 14698.000 38.895 2.863 + 14698.500 36.874 2.881 + 14699.000 34.268 2.878 + 14699.500 40.072 2.865 + 14700.000 42.496 2.853 + 14700.500 63.375 2.842 + 14701.000 81.064 2.833 + 14701.500 98.923 2.837 + 14702.000 119.029 2.853 + 14702.500 113.118 2.832 + 14703.000 102.350 2.781 + 14703.500 97.257 2.722 + 14704.000 94.649 2.727 + 14704.500 95.358 2.738 + 14705.000 98.882 2.733 + 14705.500 95.734 2.731 + 14706.000 80.246 2.753 + 14706.500 53.000 2.822 + 14707.000 50.825 2.847 + 14707.500 56.575 2.845 + 14708.000 87.418 2.833 + 14708.500 88.253 2.845 + 14709.000 99.037 2.864 + 14709.500 102.804 2.859 + 14710.000 89.560 2.808 + 14710.500 82.196 2.784 + 14711.000 64.168 2.787 + 14711.500 74.271 2.809 + 14712.000 115.200 2.834 + 14712.500 140.084 2.794 + 14713.000 142.512 2.765 + 14713.500 138.742 2.722 + 14714.000 129.885 2.716 + 14714.500 86.864 2.751 + 14715.000 82.429 2.786 + 14715.500 92.278 2.797 + 14716.000 107.639 2.791 + 14716.500 141.606 2.754 + 14717.000 139.736 2.745 + 14717.500 134.151 2.743 + 14718.000 117.740 2.750 + 14718.500 77.143 2.773 + 14719.000 60.538 2.817 + 14719.500 43.859 2.829 + 14720.000 40.383 2.836 + 14720.500 38.991 2.840 + 14721.000 37.752 2.846 + 14721.500 46.864 2.850 + 14722.000 43.799 2.848 + 14722.500 112.783 2.843 + 14723.000 106.813 2.828 + 14723.500 123.552 2.792 + 14724.000 110.277 2.767 + 14724.500 81.662 2.782 + 14725.000 67.875 2.830 + 14725.500 56.056 2.871 + 14726.000 43.226 2.886 + 14726.500 38.611 2.897 + 14727.000 35.834 2.901 + 14727.500 38.594 2.903 + 14728.000 55.293 2.913 + 14728.500 72.108 2.931 + 14729.000 84.108 2.900 + 14729.500 91.829 2.902 + 14730.000 107.830 2.846 + 14730.500 143.978 2.756 + 14731.000 152.463 2.768 + 14731.500 161.313 2.789 + 14732.000 170.493 2.804 + 14732.500 173.644 2.808 + 14733.000 137.749 2.791 + 14733.500 115.338 2.754 + 14734.000 90.830 2.739 + 14734.500 37.692 2.811 + 14735.000 39.448 2.858 + 14735.500 32.150 2.868 + 14736.000 49.797 2.873 + 14736.500 78.872 2.842 + 14737.000 106.731 2.802 + 14737.500 112.088 2.781 + 14738.000 109.636 2.773 + 14738.500 71.211 2.805 + 14739.000 62.380 2.815 + 14739.500 62.857 2.836 + 14740.000 100.075 2.856 + 14740.500 111.524 2.842 + 14741.000 114.860 2.827 + 14741.500 104.235 2.735 + 14742.000 91.921 2.707 + 14742.500 68.183 2.775 + 14743.000 62.902 2.799 + 14743.500 51.759 2.824 + 14744.000 54.191 2.828 + 14744.500 61.808 2.820 + 14745.000 63.479 2.814 + 14745.500 65.418 2.816 + 14746.000 67.262 2.816 + 14746.500 69.716 2.808 + 14747.000 73.715 2.793 + 14747.500 82.225 2.798 + 14748.000 95.267 2.829 + 14748.500 105.595 2.932 + 14749.000 104.367 2.924 + 14749.500 102.623 2.898 + 14750.000 69.878 2.807 + 14750.500 45.980 2.734 + 14751.000 38.343 2.792 + 14751.500 39.172 2.824 + 14752.000 50.229 2.811 + 14752.500 64.302 2.765 + 14753.000 91.511 2.648 + 14753.500 116.014 2.617 + 14754.000 112.517 2.645 + 14754.500 108.421 2.679 + 14755.000 74.261 2.754 + 14755.500 69.302 2.778 + 14756.000 65.358 2.842 + 14756.500 65.781 2.727 + 14757.000 68.454 2.693 + 14757.500 59.345 2.705 + 14758.000 50.869 2.766 + 14758.500 20.099 2.869 + 14759.000 22.213 2.864 + 14759.500 20.372 2.872 + 14760.000 20.972 2.871 + 14760.500 30.558 2.879 + 14761.000 33.034 2.886 + 14761.500 36.343 2.885 + 14762.000 38.589 2.885 + 14762.500 39.328 2.831 + 14763.000 39.664 2.809 + 14763.500 39.532 2.805 + 14764.000 40.260 2.819 + 14764.500 41.316 2.823 + 14765.000 43.224 2.835 + 14765.500 45.673 2.838 + 14766.000 49.780 2.849 + 14766.500 56.095 2.855 + 14767.000 53.722 2.856 + 14767.500 51.881 2.849 + 14768.000 44.702 2.840 + 14768.500 33.149 2.840 + 14769.000 27.010 2.858 + 14769.500 22.663 2.852 + 14770.000 20.799 2.845 + 14770.500 16.913 2.819 + 14771.000 15.751 2.821 + 14771.500 16.824 2.833 + 14772.000 20.141 2.843 + 14772.500 27.831 2.852 + 14773.000 33.302 2.852 + 14773.500 41.536 2.846 + 14774.000 46.130 2.842 + 14774.500 49.968 2.834 + 14775.000 54.996 2.829 + 14775.500 53.209 2.824 + 14776.000 48.329 2.827 + 14776.500 42.189 2.845 + 14777.000 33.789 2.860 + 14777.500 29.987 2.872 + 14778.000 29.221 2.869 + 14778.500 30.501 2.860 + 14779.000 32.926 2.855 + 14779.500 33.407 2.854 + 14780.000 34.053 2.854 + 14780.500 30.601 2.866 + 14781.000 27.495 2.872 + 14781.500 29.201 2.864 + 14782.000 31.905 2.840 + 14782.500 37.952 2.839 + 14783.000 39.947 2.841 + 14783.500 34.776 2.850 + 14784.000 32.226 2.855 + 14784.500 26.860 2.873 + 14785.000 24.853 2.879 + 14785.500 23.139 2.879 + 14786.000 22.907 2.864 + 14786.500 23.509 2.851 + 14787.000 24.551 2.850 + 14787.500 26.303 2.853 + 14788.000 25.830 2.851 + 14788.500 22.334 2.850 + 14789.000 17.679 2.851 + 14789.500 16.436 2.852 + 14790.000 18.735 2.864 + 14790.500 21.560 2.869 + 14791.000 28.432 2.862 + 14791.500 29.200 2.848 + 14792.000 28.764 2.840 + 14792.500 26.114 2.840 + 14793.000 23.020 2.838 + 14793.500 21.827 2.837 + 14794.000 22.609 2.839 + 14794.500 23.182 2.850 + 14795.000 24.699 2.855 + 14795.500 27.532 2.855 + 14796.000 30.217 2.854 + 14796.500 32.265 2.864 + 14797.000 32.321 2.873 + 14797.500 27.984 2.882 + 14798.000 24.658 2.877 + 14798.500 21.095 2.860 + 14799.000 20.906 2.856 + 14799.500 19.875 2.854 + 14800.000 19.803 2.862 + 14800.500 20.172 2.881 + 14801.000 20.483 2.879 + 14801.500 30.289 2.872 + 14802.000 42.628 2.855 + 14802.500 50.771 2.836 + 14803.000 56.171 2.816 + 14803.500 57.503 2.803 + 14804.000 58.872 2.796 + 14804.500 55.595 2.805 + 14805.000 48.965 2.819 + 14805.500 38.565 2.850 + 14806.000 27.733 2.851 + 14806.500 20.361 2.856 + 14807.000 19.946 2.852 + 14807.500 20.379 2.851 + 14808.000 25.770 2.837 + 14808.500 30.905 2.830 + 14809.000 34.287 2.832 + 14809.500 37.937 2.838 + 14810.000 34.788 2.832 + 14810.500 27.751 2.815 + 14811.000 25.741 2.811 + 14811.500 24.991 2.813 + 14812.000 26.857 2.816 + 14812.500 29.450 2.827 + 14813.000 30.819 2.833 + 14813.500 31.132 2.840 + 14814.000 30.203 2.845 + 14814.500 28.375 2.852 + 14815.000 26.638 2.851 + 14815.500 25.004 2.854 + 14816.000 24.234 2.843 + 14816.500 22.124 2.831 + 14817.000 22.403 2.828 + 14817.500 22.264 2.825 + 14818.000 23.756 2.824 + 14818.500 26.712 2.829 + 14819.000 30.963 2.850 + 14819.500 33.584 2.861 + 14820.000 34.753 2.867 + 14820.500 33.011 2.854 + 14821.000 32.545 2.843 + 14821.500 32.961 2.840 + 14822.000 33.973 2.840 + 14822.500 29.176 2.843 + 14823.000 25.950 2.855 + 14823.500 20.740 2.864 + 14824.000 20.831 2.862 + 14824.500 19.909 2.846 + 14825.000 19.870 2.839 + 14825.500 20.692 2.839 + 14826.000 21.097 2.844 + 14826.500 24.522 2.850 + 14827.000 26.180 2.853 + 14827.500 27.804 2.854 + 14828.000 28.005 2.841 + 14828.500 28.097 2.829 + 14829.000 26.705 2.821 + 14829.500 26.342 2.827 + 14830.000 28.635 2.832 + 14830.500 31.798 2.835 + 14831.000 35.537 2.843 + 14831.500 40.650 2.851 + 14832.000 41.030 2.854 + 14832.500 42.059 2.839 + 14833.000 41.342 2.834 + 14833.500 40.635 2.831 + 14834.000 39.938 2.835 + 14834.500 37.748 2.837 + 14835.000 34.958 2.827 + 14835.500 33.737 2.817 + 14836.000 32.342 2.814 + 14836.500 33.365 2.823 + 14837.000 34.730 2.839 + 14837.500 35.472 2.851 + 14838.000 35.890 2.854 + 14838.500 34.330 2.863 + 14839.000 34.204 2.868 + 14839.500 31.200 2.863 + 14840.000 29.369 2.855 + 14840.500 27.045 2.847 + 14841.000 25.759 2.844 + 14841.500 26.451 2.844 + 14842.000 28.370 2.842 + 14842.500 35.001 2.831 + 14843.000 41.240 2.830 + 14843.500 44.821 2.836 + 14844.000 50.846 2.849 + 14844.500 49.562 2.855 + 14845.000 48.310 2.846 + 14845.500 48.421 2.821 + 14846.000 48.008 2.811 + 14846.500 49.529 2.822 + 14847.000 49.900 2.826 + 14847.500 49.016 2.837 + 14848.000 46.427 2.839 + 14848.500 41.558 2.845 + 14849.000 41.753 2.848 + 14849.500 48.824 2.846 + 14850.000 52.312 2.844 + 14850.500 53.071 2.838 + 14851.000 51.851 2.840 + 14851.500 48.811 2.836 + 14852.000 47.455 2.824 + 14852.500 46.620 2.817 + 14853.000 46.626 2.828 + 14853.500 47.251 2.835 + 14854.000 47.974 2.854 + 14854.500 49.016 2.862 + 14855.000 47.867 2.859 + 14855.500 44.660 2.851 + 14856.000 42.768 2.841 + 14856.500 48.885 2.832 + 14857.000 48.872 2.833 + 14857.500 48.763 2.834 + 14858.000 46.138 2.835 + 14858.500 38.257 2.832 + 14859.000 35.970 2.839 + 14859.500 38.896 2.854 + 14860.000 47.325 2.863 + 14860.500 53.857 2.857 + 14861.000 50.610 2.852 + 14861.500 36.542 2.854 + 14862.000 29.775 2.860 + 14862.500 20.887 2.876 + 14863.000 16.183 2.878 + 14863.500 15.534 2.878 + 14864.000 20.198 2.870 + 14864.500 23.873 2.841 + 14865.000 29.672 2.824 + 14865.500 30.695 2.822 + 14866.000 28.908 2.831 + 14866.500 24.915 2.839 + 14867.000 26.564 2.840 + 14867.500 27.665 2.836 + 14868.000 30.267 2.827 + 14868.500 35.064 2.824 + 14869.000 38.121 2.819 + 14869.500 37.413 2.818 + 14870.000 34.083 2.819 + 14870.500 27.253 2.840 + 14871.000 21.823 2.853 + 14871.500 16.250 2.871 + 14872.000 15.466 2.863 + 14872.500 14.690 2.855 + 14873.000 14.400 2.843 + 14873.500 13.503 2.840 + 14874.000 14.393 2.837 + 14874.500 14.484 2.834 + 14875.000 14.544 2.829 + 14875.500 14.420 2.828 + 14876.000 15.144 2.837 + 14876.500 15.252 2.849 + 14877.000 15.300 2.848 + 14877.500 15.255 2.840 + 14878.000 15.166 2.834 + 14878.500 15.564 2.834 + 14879.000 16.222 2.837 + 14879.500 17.268 2.849 + 14880.000 31.048 2.859 + 14880.500 44.599 2.871 + 14881.000 53.886 2.874 + 14881.500 55.877 2.867 + 14882.000 53.306 2.860 + 14882.500 40.887 2.843 + 14883.000 31.602 2.843 + 14883.500 26.325 2.840 + 14884.000 24.257 2.841 + 14884.500 22.199 2.840 + 14885.000 20.592 2.839 + 14885.500 16.020 2.837 + 14886.000 15.993 2.841 + 14886.500 15.164 2.847 + 14887.000 15.466 2.851 + 14887.500 16.055 2.854 + 14888.000 17.219 2.858 + 14888.500 18.568 2.861 + 14889.000 18.414 2.855 + 14889.500 18.325 2.856 + 14890.000 17.025 2.861 + 14890.500 14.984 2.870 + 14891.000 13.601 2.872 + 14891.500 13.553 2.869 + 14892.000 12.924 2.868 + 14892.500 12.358 2.866 + 14893.000 12.101 2.857 + 14893.500 13.993 2.844 + 14894.000 16.157 2.838 + 14894.500 21.952 2.853 + 14895.000 24.296 2.870 + 14895.500 27.286 2.870 + 14896.000 28.623 2.851 + 14896.500 25.560 2.834 + 14897.000 23.366 2.826 + 14897.500 21.659 2.818 + 14898.000 21.547 2.809 + 14898.500 21.575 2.800 + 14899.000 21.708 2.806 + 14899.500 22.280 2.819 + 14900.000 21.953 2.844 + 14900.500 21.817 2.854 + 14901.000 21.589 2.843 + 14901.500 21.472 2.835 + 14902.000 20.746 2.830 + 14902.500 20.929 2.839 + 14903.000 21.768 2.855 + 14903.500 22.368 2.856 + 14904.000 21.712 2.854 + 14904.500 21.325 2.839 + 14905.000 20.192 2.836 + 14905.500 29.943 2.836 + 14906.000 32.148 2.842 + 14906.500 51.480 2.839 + 14907.000 58.480 2.835 + 14907.500 54.501 2.835 + 14908.000 46.773 2.829 + 14908.500 31.636 2.837 + 14909.000 27.860 2.847 + 14909.500 25.496 2.857 + 14910.000 23.314 2.859 + 14910.500 21.822 2.862 + 14911.000 21.353 2.861 + 14911.500 23.501 2.854 + 14912.000 30.430 2.844 + 14912.500 37.033 2.838 + 14913.000 38.595 2.834 + 14913.500 37.004 2.832 + 14914.000 34.736 2.832 + 14914.500 30.816 2.832 + 14915.000 28.193 2.834 + 14915.500 24.419 2.835 + 14916.000 22.289 2.829 + 14916.500 23.648 2.833 + 14917.000 26.291 2.839 + 14917.500 29.073 2.842 + 14918.000 31.665 2.840 + 14918.500 33.307 2.829 + 14919.000 32.714 2.823 + 14919.500 30.487 2.820 + 14920.000 29.303 2.827 + 14920.500 28.623 2.842 + 14921.000 28.593 2.852 + 14921.500 27.095 2.862 + 14922.000 24.605 2.866 + 14922.500 21.292 2.866 + 14923.000 20.830 2.854 + 14923.500 20.186 2.841 + 14924.000 19.864 2.831 + 14924.500 20.702 2.832 + 14925.000 20.133 2.835 + 14925.500 19.975 2.849 + 14926.000 20.742 2.857 + 14926.500 23.013 2.863 + 14927.000 25.317 2.862 + 14927.500 26.349 2.864 + 14928.000 26.156 2.861 + 14928.500 25.295 2.857 + 14929.000 26.538 2.854 + 14929.500 28.649 2.836 + 14930.000 29.395 2.821 + 14930.500 27.914 2.823 + 14931.000 27.980 2.828 + 14931.500 29.360 2.832 + 14932.000 30.946 2.844 + 14932.500 30.350 2.853 + 14933.000 28.787 2.862 + 14933.500 27.705 2.873 + 14934.000 27.995 2.877 + 14934.500 29.781 2.870 + 14935.000 33.248 2.859 + 14935.500 37.506 2.850 + 14936.000 37.822 2.834 + 14936.500 34.850 2.826 + 14937.000 29.660 2.826 + 14937.500 27.162 2.834 + 14938.000 27.728 2.846 + 14938.500 32.026 2.850 + 14939.000 36.469 2.852 + 14939.500 38.478 2.841 + 14940.000 33.965 2.832 + 14940.500 30.338 2.829 + 14941.000 25.409 2.839 + 14941.500 24.268 2.855 + 14942.000 25.269 2.857 + 14942.500 30.525 2.860 + 14943.000 36.456 2.857 + 14943.500 42.854 2.856 + 14944.000 46.078 2.851 + 14944.500 46.466 2.838 + 14945.000 46.782 2.817 + 14945.500 48.392 2.805 + 14946.000 49.171 2.799 + 14946.500 46.549 2.813 + 14947.000 41.993 2.822 + 14947.500 37.174 2.830 + 14948.000 30.869 2.829 + 14948.500 27.851 2.832 + 14949.000 27.153 2.835 + 14949.500 26.913 2.850 + 14950.000 26.857 2.859 + 14950.500 23.956 2.878 + 14951.000 22.494 2.878 + 14951.500 22.340 2.873 + 14952.000 23.740 2.866 + 14952.500 25.248 2.862 + 14953.000 24.951 2.853 + 14953.500 23.579 2.842 + 14954.000 21.689 2.835 + 14954.500 23.111 2.845 + 14955.000 24.349 2.849 + 14955.500 26.310 2.844 + 14956.000 27.179 2.840 + 14956.500 26.319 2.836 + 14957.000 24.528 2.832 + 14957.500 22.682 2.836 + 14958.000 21.238 2.846 + 14958.500 21.290 2.855 + 14959.000 22.047 2.851 + 14959.500 21.789 2.839 + 14960.000 21.647 2.824 + 14960.500 24.170 2.847 + 14961.000 29.278 2.862 + 14961.500 32.771 2.867 + 14962.000 37.709 2.867 + 14962.500 38.408 2.870 + 14963.000 32.204 2.870 + 14963.500 27.269 2.866 + 14964.000 21.504 2.855 + 14964.500 21.984 2.841 + 14965.000 22.098 2.831 + 14965.500 24.689 2.838 + 14966.000 26.873 2.852 + 14966.500 29.490 2.867 + 14967.000 36.117 2.862 + 14967.500 37.234 2.854 + 14968.000 37.671 2.850 + 14968.500 33.179 2.854 + 14969.000 25.917 2.856 + 14969.500 25.460 2.854 + 14970.000 25.575 2.849 + 14970.500 25.056 2.841 + 14971.000 24.841 2.836 + 14971.500 25.285 2.831 + 14972.000 25.566 2.826 + 14972.500 27.202 2.836 + 14973.000 30.063 2.847 + 14973.500 32.699 2.857 + 14974.000 34.947 2.860 + 14974.500 36.279 2.857 + 14975.000 36.330 2.854 + 14975.500 31.239 2.852 + 14976.000 29.543 2.850 + 14976.500 26.373 2.839 + 14977.000 27.338 2.826 + 14977.500 28.998 2.823 + 14978.000 30.866 2.822 + 14978.500 30.866 2.822 + 14979.000 29.170 2.823 + 14979.500 26.274 2.824 + 14980.000 24.867 2.824 + 14980.500 24.147 2.825 + 14981.000 23.820 2.826 + 14981.500 24.320 2.834 + 14982.000 24.051 2.842 + 14982.500 22.051 2.856 + 14983.000 20.952 2.852 + 14983.500 18.993 2.846 + 14984.000 20.524 2.839 + 14984.500 21.811 2.846 + 14985.000 26.719 2.850 + 14985.500 31.983 2.860 + 14986.000 36.302 2.866 + 14986.500 36.903 2.870 + 14987.000 32.659 2.867 + 14987.500 26.651 2.864 + 14988.000 24.821 2.863 + 14988.500 24.750 2.861 + 14989.000 26.342 2.859 + 14989.500 27.805 2.854 + 14990.000 29.899 2.847 + 14990.500 30.214 2.840 + 14991.000 28.886 2.838 + 14991.500 27.811 2.842 + 14992.000 27.078 2.848 + 14992.500 26.275 2.850 + 14993.000 25.081 2.852 + 14993.500 23.845 2.855 + 14994.000 23.376 2.848 + 14994.500 25.024 2.833 + 14995.000 28.373 2.834 + 14995.500 32.404 2.837 + 14996.000 37.131 2.836 + 14996.500 40.350 2.833 + 14997.000 39.518 2.834 + 14997.500 37.051 2.841 + 14998.000 34.227 2.846 + 14998.500 31.227 2.848 + 14999.000 29.849 2.847 + 14999.500 28.353 2.852 + 15000.000 26.796 2.869 + 15000.500 24.610 2.890 + 15001.000 23.802 2.892 + 15001.500 24.572 2.890 + 15002.000 26.860 2.883 + 15002.500 29.778 2.875 + 15003.000 33.871 2.864 + 15003.500 37.005 2.856 + 15004.000 39.201 2.853 + 15004.500 33.557 2.860 + 15005.000 31.130 2.859 + 15005.500 24.217 2.848 + 15006.000 20.765 2.837 + 15006.500 19.036 2.839 + 15007.000 16.621 2.847 + 15007.500 14.561 2.849 + 15008.000 15.579 2.847 + 15008.500 16.179 2.843 + 15009.000 18.952 2.846 + 15009.500 20.848 2.848 + 15010.000 23.871 2.846 + 15010.500 24.501 2.840 + 15011.000 24.106 2.840 + 15011.500 22.360 2.843 + 15012.000 20.942 2.848 + 15012.500 20.000 2.848 + 15013.000 19.244 2.846 + 15013.500 18.094 2.846 + 15014.000 15.821 2.849 + 15014.500 14.618 2.848 + 15015.000 13.935 2.845 + 15015.500 14.466 2.849 + 15016.000 13.864 2.851 + 15016.500 15.767 2.849 + 15017.000 18.554 2.851 + 15017.500 19.013 2.856 + 15018.000 20.865 2.864 + 15018.500 25.601 2.853 + 15019.000 33.341 2.847 + 15019.500 43.130 2.831 + 15020.000 50.888 2.834 + 15020.500 66.669 2.844 + 15021.000 96.554 2.851 + 15021.500 98.265 2.849 + 15022.000 95.204 2.835 + 15022.500 71.781 2.826 + 15023.000 56.246 2.828 + 15023.500 45.516 2.833 + 15024.000 40.918 2.840 + 15024.500 44.562 2.842 + 15025.000 44.901 2.844 + 15025.500 45.603 2.849 + 15026.000 38.583 2.852 + 15026.500 34.635 2.849 + 15027.000 28.556 2.849 + 15027.500 24.899 2.850 + 15028.000 21.079 2.852 + 15028.500 18.386 2.852 + 15029.000 16.023 2.852 + 15029.500 16.075 2.852 + 15030.000 16.418 2.855 + 15030.500 17.174 2.863 + 15031.000 16.394 2.865 + 15031.500 15.348 2.871 + 15032.000 14.266 2.872 + 15032.500 12.633 2.862 + 15033.000 12.119 2.860 + 15033.500 12.184 2.861 + 15034.000 12.138 2.870 + 15034.500 12.139 2.855 + 15035.000 12.304 2.851 + 15035.500 12.570 2.835 + 15036.000 12.825 2.834 + 15036.500 13.071 2.840 + 15037.000 13.326 2.841 + 15037.500 13.577 2.847 + 15038.000 13.811 2.847 + 15038.500 14.099 2.850 + 15039.000 14.322 2.855 + 15039.500 15.002 2.869 + 15040.000 15.954 2.870 + 15040.500 16.519 2.860 + 15041.000 18.754 2.848 + 15041.500 19.478 2.839 + 15042.000 18.878 2.838 + 15042.500 17.551 2.840 + 15043.000 16.715 2.840 + 15043.500 17.186 2.840 + 15044.000 18.329 2.840 + 15044.500 28.175 2.840 + 15045.000 33.499 2.836 + 15045.500 38.452 2.829 + 15046.000 52.659 2.834 + 15046.500 49.517 2.841 + 15047.000 47.300 2.835 + 15047.500 35.371 2.832 + 15048.000 28.834 2.833 + 15048.500 22.416 2.848 + 15049.000 20.974 2.849 + 15049.500 20.768 2.852 + 15050.000 20.932 2.855 + 15050.500 23.166 2.859 + 15051.000 23.046 2.860 + 15051.500 23.132 2.860 + 15052.000 23.182 2.860 + 15052.500 22.540 2.862 + 15053.000 22.318 2.856 + 15053.500 22.016 2.853 + 15054.000 20.720 2.852 + 15054.500 20.596 2.853 + 15055.000 21.481 2.856 + 15055.500 22.879 2.859 + 15056.000 28.123 2.865 + 15056.500 32.181 2.871 + 15057.000 39.238 2.871 + 15057.500 39.356 2.853 + 15058.000 39.574 2.838 + 15058.500 39.781 2.825 + 15059.000 39.420 2.808 + 15059.500 40.903 2.805 + 15060.000 41.240 2.811 + 15060.500 41.103 2.840 + 15061.000 39.104 2.839 + 15061.500 33.839 2.839 + 15062.000 33.541 2.836 + 15062.500 32.096 2.833 + 15063.000 31.155 2.837 + 15063.500 30.399 2.841 + 15064.000 30.130 2.846 + 15064.500 30.425 2.851 + 15065.000 27.980 2.856 + 15065.500 24.387 2.856 + 15066.000 21.016 2.856 + 15066.500 17.689 2.859 + 15067.000 15.300 2.865 + 15067.500 15.170 2.861 + 15068.000 15.894 2.853 + 15068.500 17.296 2.849 + 15069.000 19.420 2.850 + 15069.500 26.868 2.854 + 15070.000 25.117 2.856 + 15070.500 48.720 2.858 + 15071.000 46.347 2.856 + 15071.500 47.305 2.846 + 15072.000 41.482 2.838 + 15072.500 36.603 2.837 + 15073.000 35.448 2.848 + 15073.500 35.804 2.863 + 15074.000 34.553 2.864 + 15074.500 31.095 2.857 + 15075.000 31.301 2.848 + 15075.500 29.493 2.838 + 15076.000 31.756 2.825 + 15076.500 38.423 2.817 + 15077.000 40.737 2.826 + 15077.500 40.055 2.835 + 15078.000 37.058 2.842 + 15078.500 35.191 2.844 + 15079.000 33.048 2.840 + 15079.500 30.078 2.834 + 15080.000 28.592 2.824 + 15080.500 32.438 2.819 + 15081.000 38.687 2.824 + 15081.500 45.478 2.829 + 15082.000 46.660 2.836 + 15082.500 49.421 2.838 + 15083.000 49.069 2.830 + 15083.500 57.000 2.813 + 15084.000 73.662 2.807 + 15084.500 96.163 2.816 + 15085.000 106.321 2.824 + 15085.500 109.622 2.833 + 15086.000 96.330 2.838 + 15086.500 50.605 2.828 + 15087.000 42.736 2.821 + 15087.500 28.730 2.823 + 15088.000 20.276 2.830 + 15088.500 20.304 2.839 + 15089.000 21.178 2.838 + 15089.500 23.337 2.832 + 15090.000 24.586 2.830 + 15090.500 24.526 2.825 + 15091.000 24.831 2.820 + 15091.500 24.900 2.816 + 15092.000 31.382 2.814 + 15092.500 36.945 2.820 + 15093.000 41.675 2.843 + 15093.500 50.120 2.856 + 15094.000 52.544 2.866 + 15094.500 43.285 2.860 + 15095.000 39.539 2.849 + 15095.500 37.196 2.821 + 15096.000 35.859 2.830 + 15096.500 35.989 2.874 + 15097.000 39.232 2.879 + 15097.500 43.233 2.877 + 15098.000 47.067 2.862 + 15098.500 42.855 2.845 + 15099.000 40.278 2.838 + 15099.500 34.840 2.841 + 15100.000 29.301 2.857 + 15100.500 23.237 2.858 + 15101.000 19.533 2.855 + 15101.500 19.097 2.851 + 15102.000 17.588 2.849 + 15102.500 18.647 2.841 + 15103.000 20.090 2.829 + 15103.500 19.719 2.824 + 15104.000 17.540 2.825 + 15104.500 15.806 2.847 + 15105.000 14.708 2.861 + 15105.500 13.679 2.865 + 15106.000 14.459 2.849 + 15106.500 16.173 2.829 + 15107.000 17.546 2.827 + 15107.500 26.611 2.839 + 15108.000 39.091 2.848 + 15108.500 65.794 2.849 + 15109.000 63.553 2.841 + 15109.500 58.708 2.838 + 15110.000 50.429 2.853 + 15110.500 38.956 2.857 + 15111.000 34.702 2.854 + 15111.500 32.190 2.842 + 15112.000 30.381 2.813 + 15112.500 27.522 2.796 + 15113.000 28.061 2.799 + 15113.500 28.773 2.810 + 15114.000 30.022 2.825 + 15114.500 30.100 2.845 + 15115.000 28.722 2.855 + 15115.500 28.575 2.887 + 15116.000 29.187 2.880 + 15116.500 29.942 2.851 + 15117.000 30.804 2.827 + 15117.500 31.109 2.825 + 15118.000 32.742 2.821 + 15118.500 38.278 2.819 + 15119.000 40.421 2.818 + 15119.500 45.109 2.823 + 15120.000 50.426 2.825 + 15120.500 59.142 2.825 + 15121.000 60.512 2.810 + 15121.500 61.552 2.801 + 15122.000 62.448 2.803 + 15122.500 63.190 2.784 + 15123.000 62.518 2.786 + 15123.500 59.671 2.801 + 15124.000 57.865 2.806 + 15124.500 60.644 2.804 + 15125.000 63.720 2.796 + 15125.500 67.619 2.778 + 15126.000 72.871 2.795 + 15126.500 79.870 2.800 + 15127.000 81.591 2.797 + 15127.500 82.215 2.791 + 15128.000 83.609 2.784 + 15128.500 85.839 2.778 + 15129.000 87.002 2.774 + 15129.500 88.952 2.775 + 15130.000 95.010 2.781 + 15130.500 100.081 2.794 + 15131.000 99.359 2.805 + 15131.500 96.193 2.820 + 15132.000 92.028 2.832 + 15132.500 73.400 2.831 + 15133.000 62.123 2.820 + 15133.500 48.520 2.814 + 15134.000 39.156 2.827 + 15134.500 31.115 2.835 + 15135.000 29.335 2.850 + 15135.500 31.457 2.858 + 15136.000 32.432 2.869 + 15136.500 31.769 2.862 + 15137.000 29.974 2.853 + 15137.500 27.175 2.851 + 15138.000 31.790 2.855 + 15138.500 34.034 2.857 + 15139.000 37.027 2.854 + 15139.500 38.861 2.839 + 15140.000 34.208 2.838 + 15140.500 28.152 2.844 + 15141.000 25.680 2.856 + 15141.500 24.448 2.861 + 15142.000 23.773 2.848 + 15142.500 24.584 2.837 + 15143.000 24.676 2.824 + 15143.500 24.848 2.821 + 15144.000 25.557 2.827 + 15144.500 25.490 2.838 + 15145.000 25.408 2.849 + 15145.500 26.128 2.853 + 15146.000 26.261 2.854 + 15146.500 26.257 2.854 + 15147.000 26.275 2.854 + 15147.500 25.759 2.849 + 15148.000 24.875 2.836 + 15148.500 25.710 2.819 + 15149.000 28.457 2.821 + 15149.500 39.807 2.822 + 15150.000 42.679 2.821 + 15150.500 44.689 2.820 + 15151.000 44.737 2.816 + 15151.500 41.777 2.809 + 15152.000 36.971 2.814 + 15152.500 33.145 2.828 + 15153.000 30.677 2.850 + 15153.500 30.879 2.859 + 15154.000 28.009 2.868 + 15154.500 25.707 2.863 + 15155.000 25.297 2.856 + 15155.500 21.833 2.837 + 15156.000 18.959 2.820 + 15156.500 15.625 2.814 + 15157.000 15.229 2.815 + 15157.500 15.428 2.822 + 15158.000 16.506 2.830 + 15158.500 19.261 2.852 + 15159.000 19.789 2.857 + 15159.500 22.020 2.859 + 15160.000 23.688 2.849 + 15160.500 25.357 2.833 + 15161.000 26.392 2.832 + 15161.500 25.789 2.837 + 15162.000 23.678 2.850 + 15162.500 21.825 2.861 + 15163.000 17.023 2.856 + 15163.500 16.385 2.847 + 15164.000 16.075 2.844 + 15164.500 15.862 2.871 + 15165.000 15.185 2.891 + 15165.500 16.019 2.910 + 15166.000 16.932 2.895 + 15166.500 16.625 2.853 + 15167.000 16.370 2.814 + 15167.500 16.051 2.818 + 15168.000 16.156 2.822 + 15168.500 15.594 2.831 + 15169.000 16.164 2.824 + 15169.500 15.869 2.818 + 15170.000 15.203 2.825 + 15170.500 14.805 2.831 + 15171.000 14.414 2.838 + 15171.500 15.108 2.843 + 15172.000 16.327 2.849 + 15172.500 20.330 2.840 + 15173.000 20.872 2.833 + 15173.500 23.369 2.820 + 15174.000 24.753 2.819 + 15174.500 28.442 2.824 + 15175.000 31.840 2.827 + 15175.500 36.193 2.828 + 15176.000 43.670 2.822 + 15176.500 52.299 2.811 + 15177.000 59.963 2.802 + 15177.500 75.099 2.780 + 15178.000 88.850 2.755 + 15178.500 92.267 2.769 + 15179.000 89.221 2.800 + 15179.500 79.138 2.808 + 15180.000 69.563 2.808 + 15180.500 54.372 2.804 + 15181.000 36.706 2.801 + 15181.500 30.724 2.807 + 15182.000 26.793 2.817 + 15182.500 24.101 2.833 + 15183.000 23.922 2.842 + 15183.500 23.728 2.846 + 15184.000 25.834 2.845 + 15184.500 30.385 2.840 + 15185.000 32.597 2.827 + 15185.500 33.358 2.818 + 15186.000 31.510 2.816 + 15186.500 27.754 2.835 + 15187.000 25.863 2.853 + 15187.500 26.356 2.853 + 15188.000 26.268 2.846 + 15188.500 26.358 2.824 + 15189.000 25.139 2.818 + 15189.500 23.934 2.810 + 15190.000 22.039 2.803 + 15190.500 19.225 2.782 + 15191.000 18.324 2.782 + 15191.500 16.634 2.785 + 15192.000 15.205 2.795 + 15192.500 14.363 2.803 + 15193.000 15.584 2.811 + 15193.500 18.013 2.821 + 15194.000 18.844 2.830 + 15194.500 21.186 2.828 + 15195.000 23.101 2.827 + 15195.500 24.376 2.828 + 15196.000 25.624 2.826 + 15196.500 26.979 2.815 + 15197.000 28.269 2.805 + 15197.500 29.571 2.806 + 15198.000 30.881 2.816 + 15198.500 32.183 2.844 + 15199.000 33.488 2.847 + 15199.500 34.793 2.849 + 15200.000 36.098 2.839 + 15200.500 37.403 2.820 + 15201.000 38.708 2.814 + 15201.500 40.013 2.825 + 15202.000 41.318 2.837 + 15202.500 42.625 2.841 + 15203.000 43.937 2.835 + 15203.500 45.254 2.828 + 15204.000 46.542 2.816 + 15204.500 47.891 2.800 + 15205.000 49.183 2.804 + 15205.500 50.373 2.808 + 15206.000 51.965 2.813 + 15206.500 48.929 2.827 + 15207.000 43.377 2.834 + 15207.500 37.596 2.836 + 15208.000 34.178 2.836 + 15208.500 31.134 2.839 + 15209.000 30.950 2.841 + 15209.500 30.997 2.842 + 15210.000 30.886 2.837 + 15210.500 31.289 2.829 + 15211.000 31.777 2.821 + 15211.500 36.016 2.820 + 15212.000 36.669 2.821 + 15212.500 33.033 2.836 + 15213.000 27.306 2.843 + 15213.500 25.518 2.852 + 15214.000 22.797 2.853 + 15214.500 19.317 2.854 + 15215.000 18.254 2.854 + 15215.500 17.478 2.857 + 15216.000 17.849 2.854 + 15216.500 18.639 2.846 + 15217.000 19.068 2.835 + 15217.500 18.679 2.837 + 15218.000 20.034 2.846 + 15218.500 21.459 2.858 + 15219.000 22.913 2.862 + 15219.500 23.262 2.861 + 15220.000 24.332 2.859 + 15220.500 23.336 2.857 + 15221.000 21.659 2.856 + 15221.500 19.421 2.846 + 15222.000 20.097 2.835 + 15222.500 19.215 2.826 + 15223.000 19.419 2.827 + 15223.500 18.625 2.828 + 15224.000 20.774 2.839 + 15224.500 20.347 2.849 + 15225.000 19.710 2.848 + 15225.500 18.528 2.851 + 15226.000 18.465 2.852 + 15226.500 17.692 2.849 + 15227.000 16.744 2.834 + 15227.500 17.396 2.824 + 15228.000 18.266 2.820 + 15228.500 16.740 2.816 + 15229.000 15.941 2.814 + 15229.500 14.786 2.817 + 15230.000 14.948 2.825 + 15230.500 15.294 2.848 + 15231.000 15.202 2.865 + 15231.500 14.761 2.862 + 15232.000 14.823 2.856 + 15232.500 13.836 2.848 + 15233.000 13.719 2.851 + 15233.500 13.686 2.854 + 15234.000 13.822 2.862 + 15234.500 13.069 2.840 + 15235.000 12.918 2.817 + 15235.500 13.099 2.800 + 15236.000 13.934 2.806 + 15236.500 14.435 2.826 + 15237.000 13.721 2.834 + 15237.500 15.009 2.835 + 15238.000 15.340 2.825 + 15238.500 15.251 2.812 + 15239.000 15.166 2.819 + 15239.500 14.506 2.826 + 15240.000 13.747 2.829 + 15240.500 13.515 2.834 + 15241.000 13.636 2.846 + 15241.500 14.546 2.854 + 15242.000 15.482 2.863 + 15242.500 16.221 2.855 + 15243.000 15.441 2.856 + 15243.500 14.243 2.859 + 15244.000 13.589 2.861 + 15244.500 12.234 2.856 + 15245.000 12.297 2.842 + 15245.500 13.168 2.827 + 15246.000 13.915 2.826 + 15246.500 14.403 2.842 + 15247.000 13.607 2.843 + 15247.500 13.738 2.838 + 15248.000 13.623 2.838 + 15248.500 14.043 2.845 + 15249.000 14.990 2.855 + 15249.500 17.534 2.859 + 15250.000 22.881 2.859 + 15250.500 28.686 2.859 + 15251.000 38.968 2.848 + 15251.500 50.914 2.839 + 15252.000 66.802 2.816 + 15252.500 79.353 2.807 + 15253.000 85.915 2.797 + 15253.500 84.213 2.790 + 15254.000 81.099 2.783 + 15254.500 65.063 2.783 + 15255.000 47.378 2.792 + 15255.500 27.255 2.806 + 15256.000 24.171 2.814 + 15256.500 17.565 2.820 + 15257.000 16.427 2.820 + 15257.500 16.018 2.826 + 15258.000 15.836 2.827 + 15258.500 15.497 2.829 + 15259.000 15.354 2.831 + 15259.500 16.858 2.833 + 15260.000 18.251 2.847 + 15260.500 19.943 2.848 + 15261.000 20.676 2.850 + 15261.500 25.119 2.844 + 15262.000 28.681 2.837 + 15262.500 34.606 2.832 + 15263.000 42.818 2.838 + 15263.500 52.923 2.843 + 15264.000 66.932 2.854 + 15264.500 76.640 2.836 + 15265.000 81.803 2.805 + 15265.500 80.054 2.774 + 15266.000 77.256 2.779 + 15266.500 57.555 2.803 + 15267.000 39.608 2.822 + 15267.500 32.339 2.842 + 15268.000 24.807 2.836 + 15268.500 19.504 2.830 + 15269.000 19.030 2.831 + 15269.500 16.628 2.838 + 15270.000 16.353 2.844 + 15270.500 18.589 2.852 + 15271.000 19.982 2.857 + 15271.500 21.525 2.857 + 15272.000 23.637 2.845 + 15272.500 24.436 2.842 + 15273.000 25.362 2.840 + 15273.500 25.100 2.840 + 15274.000 24.351 2.838 + 15274.500 23.252 2.839 + 15275.000 23.426 2.846 + 15275.500 22.944 2.845 + 15276.000 26.700 2.840 + 15276.500 50.227 2.832 + 15277.000 65.150 2.814 + 15277.500 92.862 2.798 + 15278.000 90.767 2.762 + 15278.500 83.982 2.745 + 15279.000 76.597 2.774 + 15279.500 63.770 2.818 + 15280.000 51.881 2.867 + 15280.500 37.891 2.870 + 15281.000 39.499 2.855 + 15281.500 38.840 2.842 + 15282.000 38.049 2.820 + 15282.500 34.437 2.814 + 15283.000 29.174 2.812 + 15283.500 24.961 2.815 + 15284.000 22.173 2.834 + 15284.500 21.736 2.843 + 15285.000 22.858 2.846 + 15285.500 26.786 2.834 + 15286.000 30.214 2.817 + 15286.500 32.202 2.785 + 15287.000 28.316 2.782 + 15287.500 21.311 2.799 + 15288.000 16.151 2.856 + 15288.500 13.229 2.855 + 15289.000 13.115 2.846 + 15289.500 13.765 2.836 + 15290.000 14.279 2.830 + 15290.500 14.489 2.831 + 15291.000 14.557 2.845 + 15291.500 14.427 2.853 + 15292.000 15.067 2.871 + 15292.500 15.918 2.875 + 15293.000 16.101 2.866 + 15293.500 15.976 2.856 + 15294.000 14.904 2.846 + 15294.500 15.825 2.839 + 15295.000 17.729 2.831 + 15295.500 20.161 2.824 + 15296.000 22.419 2.819 + 15296.500 25.155 2.819 + 15297.000 26.606 2.820 + 15297.500 24.060 2.843 + 15298.000 21.482 2.848 + 15298.500 19.879 2.858 + 15299.000 19.105 2.851 + 15299.500 17.723 2.841 + 15300.000 17.668 2.836 + 15300.500 18.913 2.830 + 15301.000 21.834 2.823 + 15301.500 27.027 2.817 + 15302.000 40.695 2.802 + 15302.500 53.610 2.794 + 15303.000 56.686 2.785 + 15303.500 57.921 2.784 + 15304.000 60.358 2.793 + 15304.500 51.554 2.814 + 15305.000 39.949 2.828 + 15305.500 34.775 2.840 + 15306.000 28.964 2.839 + 15306.500 24.002 2.832 + 15307.000 23.919 2.828 + 15307.500 24.748 2.821 + 15308.000 27.830 2.817 + 15308.500 30.883 2.811 + 15309.000 36.473 2.815 + 15309.500 47.141 2.820 + 15310.000 45.764 2.820 + 15310.500 38.867 2.818 + 15311.000 22.813 2.821 + 15311.500 20.628 2.825 + 15312.000 16.931 2.827 + 15312.500 14.997 2.823 + 15313.000 15.875 2.825 + 15313.500 16.827 2.843 + 15314.000 17.984 2.861 + 15314.500 19.486 2.884 + 15315.000 20.035 2.879 + 15315.500 19.923 2.861 + 15316.000 20.545 2.851 + 15316.500 21.410 2.838 + 15317.000 21.669 2.837 + 15317.500 22.639 2.836 + 15318.000 23.331 2.837 + 15318.500 23.762 2.844 + 15319.000 26.661 2.850 + 15319.500 38.116 2.852 + 15320.000 43.895 2.844 + 15320.500 40.105 2.835 + 15321.000 35.890 2.830 + 15321.500 32.144 2.830 + 15322.000 24.182 2.830 + 15322.500 15.339 2.827 + 15323.000 13.741 2.830 + 15323.500 12.176 2.841 + 15324.000 11.283 2.856 + 15324.500 11.314 2.864 + 15325.000 11.895 2.860 + 15325.500 12.815 2.854 + 15326.000 12.854 2.850 + 15326.500 13.442 2.843 + 15327.000 12.836 2.832 + 15327.500 12.955 2.828 + 15328.000 13.539 2.814 + 15328.500 15.037 2.810 + 15329.000 16.067 2.813 + 15329.500 17.977 2.814 + 15330.000 19.132 2.814 + 15330.500 21.033 2.806 + 15331.000 24.893 2.804 + 15331.500 25.951 2.815 + 15332.000 34.101 2.843 + 15332.500 35.802 2.865 + 15333.000 54.079 2.860 + 15333.500 54.779 2.847 + 15334.000 59.581 2.829 + 15334.500 56.790 2.804 + 15335.000 39.565 2.810 + 15335.500 36.447 2.841 + 15336.000 28.519 2.854 + 15336.500 19.575 2.854 + 15337.000 15.120 2.848 + 15337.500 13.390 2.839 + 15338.000 13.063 2.834 + 15338.500 13.924 2.832 + 15339.000 14.651 2.835 + 15339.500 15.387 2.840 + 15340.000 14.697 2.846 + 15340.500 13.892 2.844 + 15341.000 13.682 2.841 + 15341.500 14.065 2.834 + 15342.000 15.325 2.840 + 15342.500 16.198 2.855 + 15343.000 15.728 2.867 + 15343.500 15.075 2.880 + 15344.000 14.451 2.878 + 15344.500 14.673 2.853 + 15345.000 15.370 2.845 + 15345.500 15.264 2.846 + 15346.000 15.272 2.845 + 15346.500 15.349 2.835 + 15347.000 15.366 2.827 + 15347.500 17.692 2.814 + 15348.000 19.283 2.811 + 15348.500 21.648 2.813 + 15349.000 20.960 2.816 + 15349.500 18.016 2.820 + 15350.000 15.699 2.823 + 15350.500 13.741 2.830 + 15351.000 11.411 2.847 + 15351.500 10.385 2.865 + 15352.000 9.806 2.874 + 15352.500 11.287 2.868 + 15353.000 11.884 2.864 + 15353.500 12.812 2.872 + 15354.000 12.818 2.885 + 15354.500 11.926 2.888 + 15355.000 11.194 2.875 + 15355.500 10.454 2.863 + 15356.000 11.272 2.856 + 15356.500 11.875 2.850 + 15357.000 12.190 2.850 + 15357.500 12.154 2.853 + 15358.000 12.087 2.863 + 15358.500 12.840 2.869 + 15359.000 14.361 2.865 + 15359.500 16.004 2.867 + 15360.000 17.606 2.871 + 15360.500 19.335 2.892 + 15361.000 20.030 2.891 + 15361.500 20.017 2.875 + 15362.000 19.608 2.862 + 15362.500 19.591 2.851 + 15363.000 19.855 2.853 + 15363.500 19.080 2.849 + 15364.000 19.504 2.842 + 15364.500 20.516 2.829 + 15365.000 21.564 2.824 + 15365.500 25.176 2.818 + 15366.000 28.916 2.816 + 15366.500 36.861 2.817 + 15367.000 46.371 2.827 + 15367.500 51.437 2.840 + 15368.000 55.335 2.854 + 15368.500 56.132 2.862 + 15369.000 53.987 2.857 + 15369.500 47.215 2.851 + 15370.000 44.097 2.838 + 15370.500 34.939 2.827 + 15371.000 31.135 2.826 + 15371.500 28.424 2.828 + 15372.000 31.446 2.846 + 15372.500 41.608 2.854 + 15373.000 57.680 2.858 + 15373.500 59.059 2.849 + 15374.000 59.922 2.826 + 15374.500 53.054 2.818 + 15375.000 40.423 2.831 + 15375.500 32.432 2.843 + 15376.000 27.105 2.846 + 15376.500 24.902 2.866 + 15377.000 19.936 2.869 + 15377.500 16.355 2.855 + 15378.000 14.801 2.836 + 15378.500 14.463 2.820 + 15379.000 14.311 2.816 + 15379.500 13.655 2.816 + 15380.000 13.736 2.815 + 15380.500 13.712 2.813 + 15381.000 13.716 2.813 + 15381.500 13.727 2.827 + 15382.000 13.719 2.840 + 15382.500 13.727 2.853 + 15383.000 13.719 2.866 + 15383.500 13.709 2.879 + 15384.000 13.760 2.885 + 15384.500 13.654 2.881 + 15385.000 14.279 2.870 + 15385.500 15.282 2.861 + 15386.000 16.304 2.855 + 15386.500 17.075 2.848 + 15387.000 17.832 2.844 + 15387.500 18.512 2.848 + 15388.000 18.391 2.852 + 15388.500 18.437 2.850 + 15389.000 18.571 2.852 + 15389.500 19.309 2.836 + 15390.000 19.082 2.832 + 15390.500 19.856 2.828 + 15391.000 19.986 2.820 + 15391.500 19.988 2.812 + 15392.000 20.200 2.804 + 15392.500 23.599 2.822 + 15393.000 31.886 2.828 + 15393.500 39.979 2.840 + 15394.000 40.695 2.841 + 15394.500 34.891 2.830 + 15395.000 30.749 2.824 + 15395.500 25.657 2.821 + 15396.000 19.119 2.824 + 15396.500 13.736 2.825 + 15397.000 10.777 2.828 + 15397.500 10.604 2.842 + 15398.000 10.507 2.869 + 15398.500 10.743 2.893 + 15399.000 11.308 2.888 + 15399.500 12.492 2.869 + 15400.000 13.823 2.853 + 15400.500 14.161 2.834 + 15401.000 15.804 2.826 + 15401.500 16.182 2.825 + 15402.000 17.546 2.817 + 15402.500 18.308 2.813 + 15403.000 20.118 2.819 + 15403.500 20.826 2.833 + 15404.000 20.848 2.849 + 15404.500 20.167 2.856 + 15405.000 20.005 2.863 + 15405.500 19.942 2.866 + 15406.000 19.342 2.861 + 15406.500 18.704 2.842 + 15407.000 18.483 2.837 + 15407.500 17.824 2.849 + 15408.000 16.942 2.851 + 15408.500 15.376 2.851 + 15409.000 15.187 2.833 + 15409.500 16.486 2.828 + 15410.000 17.412 2.833 + 15410.500 18.417 2.849 + 15411.000 19.978 2.854 + 15411.500 21.459 2.854 + 15412.000 21.517 2.857 + 15412.500 21.605 2.868 + 15413.000 21.426 2.872 + 15413.500 22.831 2.876 + 15414.000 25.354 2.874 + 15414.500 29.003 2.865 + 15415.000 39.143 2.849 + 15415.500 47.097 2.835 + 15416.000 58.876 2.822 + 15416.500 55.433 2.820 + 15417.000 44.053 2.831 + 15417.500 38.140 2.835 + 15418.000 28.420 2.840 + 15418.500 22.625 2.844 + 15419.000 14.418 2.864 + 15419.500 13.683 2.879 + 15420.000 13.389 2.886 + 15420.500 10.904 2.874 + 15421.000 10.573 2.856 + 15421.500 10.664 2.841 + 15422.000 11.614 2.838 + 15422.500 12.193 2.850 + 15423.000 12.125 2.851 + 15423.500 12.164 2.856 + 15424.000 12.146 2.864 + 15424.500 12.178 2.890 + 15425.000 11.793 2.888 + 15425.500 11.269 2.885 + 15426.000 11.936 2.870 + 15426.500 12.864 2.859 + 15427.000 14.616 2.852 + 15427.500 15.275 2.845 + 15428.000 16.027 2.842 + 15428.500 17.114 2.842 + 15429.000 17.972 2.840 + 15429.500 19.398 2.832 + 15430.000 19.286 2.831 + 15430.500 19.940 2.836 + 15431.000 19.344 2.852 + 15431.500 19.442 2.864 + 15432.000 19.262 2.862 + 15432.500 19.133 2.850 + 15433.000 19.003 2.850 + 15433.500 16.836 2.854 + 15434.000 16.842 2.856 + 15434.500 17.404 2.856 + 15435.000 18.384 2.852 + 15435.500 19.317 2.852 + 15436.000 19.284 2.854 + 15436.500 20.188 2.852 + 15437.000 21.769 2.843 + 15437.500 25.501 2.825 + 15438.000 29.408 2.810 + 15438.500 33.187 2.799 + 15439.000 36.146 2.801 + 15439.500 38.783 2.806 + 15440.000 39.930 2.813 + 15440.500 40.330 2.820 + 15441.000 40.945 2.818 + 15441.500 44.197 2.815 + 15442.000 48.051 2.827 + 15442.500 51.783 2.839 + 15443.000 53.167 2.833 + 15443.500 51.644 2.825 + 15444.000 48.551 2.821 + 15444.500 44.478 2.824 + 15445.000 43.215 2.833 + 15445.500 43.896 2.836 + 15446.000 44.490 2.834 + 15446.500 43.360 2.832 + 15447.000 41.269 2.832 + 15447.500 39.252 2.832 + 15448.000 37.316 2.832 + 15448.500 36.582 2.829 + 15449.000 40.181 2.828 + 15449.500 46.303 2.832 + 15450.000 50.087 2.838 + 15450.500 51.520 2.844 + 15451.000 41.012 2.851 + 15451.500 35.945 2.859 + 15452.000 26.491 2.873 + 15452.500 23.643 2.876 + 15453.000 18.149 2.871 + 15453.500 17.206 2.864 + 15454.000 16.585 2.849 + 15454.500 17.352 2.824 + 15455.000 22.452 2.808 + 15455.500 29.344 2.803 + 15456.000 44.025 2.803 + 15456.500 54.467 2.814 + 15457.000 51.959 2.825 + 15457.500 49.171 2.836 + 15458.000 41.179 2.840 + 15458.500 30.510 2.838 + 15459.000 25.838 2.838 + 15459.500 23.068 2.841 + 15460.000 23.209 2.846 + 15460.500 20.747 2.852 + 15461.000 19.490 2.853 + 15461.500 19.042 2.856 + 15462.000 18.381 2.860 + 15462.500 17.780 2.861 + 15463.000 16.791 2.857 + 15463.500 15.379 2.844 + 15464.000 14.389 2.833 + 15464.500 12.957 2.823 + 15465.000 13.278 2.835 + 15465.500 13.802 2.850 + 15466.000 14.423 2.850 + 15466.500 14.993 2.850 + 15467.000 15.570 2.853 + 15467.500 16.164 2.855 + 15468.000 16.730 2.858 + 15468.500 17.318 2.860 + 15469.000 17.932 2.860 + 15469.500 18.335 2.860 + 15470.000 18.806 2.856 + 15470.500 17.996 2.850 + 15471.000 17.019 2.835 + 15471.500 15.253 2.826 + 15472.000 13.967 2.824 + 15472.500 14.746 2.838 + 15473.000 15.356 2.854 + 15473.500 14.879 2.867 + 15474.000 14.028 2.861 + 15474.500 13.680 2.850 + 15475.000 13.747 2.824 + 15475.500 13.643 2.804 + 15476.000 14.305 2.796 + 15476.500 15.080 2.795 + 15477.000 15.782 2.808 + 15477.500 17.679 2.848 + 15478.000 20.670 2.866 + 15478.500 23.495 2.867 + 15479.000 26.109 2.848 + 15479.500 29.031 2.832 + 15480.000 32.119 2.823 + 15480.500 34.486 2.818 + 15481.000 39.574 2.818 + 15481.500 43.900 2.818 + 15482.000 46.707 2.825 + 15482.500 50.874 2.825 + 15483.000 52.327 2.817 + 15483.500 53.848 2.810 + 15484.000 50.960 2.818 + 15484.500 41.770 2.850 + 15485.000 36.930 2.862 + 15485.500 33.287 2.863 + 15486.000 23.787 2.851 + 15486.500 13.862 2.848 + 15487.000 13.826 2.842 + 15487.500 13.699 2.842 + 15488.000 13.254 2.847 + 15488.500 12.700 2.847 + 15489.000 12.083 2.839 + 15489.500 11.689 2.829 + 15490.000 12.054 2.820 + 15490.500 11.287 2.820 + 15491.000 10.577 2.844 + 15491.500 9.945 2.857 + 15492.000 9.168 2.867 + 15492.500 8.993 2.863 + 15493.000 9.093 2.853 + 15493.500 9.798 2.829 + 15494.000 9.762 2.821 + 15494.500 9.765 2.824 + 15495.000 9.878 2.834 + 15495.500 10.738 2.836 + 15496.000 11.982 2.840 + 15496.500 16.290 2.852 + 15497.000 19.691 2.871 + 15497.500 26.394 2.872 + 15498.000 30.420 2.862 + 15498.500 37.455 2.834 + 15499.000 42.274 2.837 + 15499.500 47.521 2.841 + 15500.000 50.613 2.839 + 15500.500 54.272 2.839 + 15501.000 55.319 2.838 + 15501.500 54.917 2.838 + 15502.000 51.928 2.841 + 15502.500 44.688 2.853 + 15503.000 40.423 2.855 + 15503.500 34.887 2.852 + 15504.000 30.675 2.854 + 15504.500 27.148 2.842 + 15505.000 26.136 2.834 + 15505.500 22.760 2.834 + 15506.000 21.695 2.839 + 15506.500 20.306 2.855 + 15507.000 19.019 2.869 + 15507.500 15.808 2.873 + 15508.000 14.586 2.874 + 15508.500 13.055 2.864 + 15509.000 12.194 2.859 + 15509.500 11.201 2.858 + 15510.000 11.874 2.860 + 15510.500 13.717 2.885 + 15511.000 16.003 2.894 + 15511.500 18.948 2.892 + 15512.000 20.107 2.887 + 15512.500 20.029 2.878 + 15513.000 19.553 2.869 + 15513.500 17.426 2.853 + 15514.000 17.724 2.847 + 15514.500 17.708 2.832 + 15515.000 17.033 2.825 + 15515.500 16.333 2.817 + 15516.000 15.457 2.817 + 15516.500 14.567 2.822 + 15517.000 13.079 2.833 + 15517.500 12.290 2.852 + 15518.000 12.230 2.854 + 15518.500 11.485 2.849 + 15519.000 11.389 2.826 + 15519.500 11.333 2.834 + 15520.000 11.366 2.861 + 15520.500 11.379 2.863 + 15521.000 11.336 2.853 + 15521.500 11.336 2.844 + 15522.000 12.189 2.842 + 15522.500 14.548 2.842 + 15523.000 16.972 2.843 + 15523.500 19.989 2.853 + 15524.000 20.141 2.856 + 15524.500 21.294 2.859 + 15525.000 23.870 2.854 + 15525.500 27.446 2.851 + 15526.000 30.924 2.841 + 15526.500 34.826 2.834 + 15527.000 34.888 2.831 + 15527.500 32.079 2.824 + 15528.000 31.093 2.826 + 15528.500 31.528 2.834 + 15529.000 32.585 2.851 + 15529.500 33.499 2.870 + 15530.000 34.297 2.877 + 15530.500 30.693 2.862 + 15531.000 28.034 2.852 + 15531.500 25.981 2.849 + 15532.000 24.689 2.854 + 15532.500 23.897 2.863 + 15533.000 23.513 2.863 + 15533.500 22.961 2.853 + 15534.000 21.691 2.845 + 15534.500 21.580 2.831 + 15535.000 21.455 2.830 + 15535.500 22.300 2.827 + 15536.000 23.926 2.823 + 15536.500 25.335 2.820 + 15537.000 26.033 2.817 + 15537.500 26.875 2.819 + 15538.000 27.648 2.823 + 15538.500 30.813 2.830 + 15539.000 33.981 2.830 + 15539.500 38.094 2.835 + 15540.000 39.856 2.848 + 15540.500 43.536 2.860 + 15541.000 45.357 2.839 + 15541.500 47.671 2.809 + 15542.000 48.360 2.801 + 15542.500 49.604 2.814 + 15543.000 51.083 2.825 + 15543.500 51.305 2.827 + 15544.000 52.105 2.810 + 15544.500 52.013 2.807 + 15545.000 52.861 2.811 + 15545.500 53.037 2.814 + 15546.000 53.780 2.792 + 15546.500 52.057 2.787 + 15547.000 51.221 2.806 + 15547.500 52.211 2.832 + 15548.000 53.194 2.846 + 15548.500 55.414 2.857 + 15549.000 54.440 2.848 + 15549.500 53.539 2.828 + 15550.000 52.896 2.834 + 15550.500 53.003 2.834 + 15551.000 52.766 2.836 + 15551.500 52.168 2.837 + 15552.000 51.084 2.827 + 15552.500 46.999 2.820 + 15553.000 43.518 2.823 + 15553.500 39.693 2.825 + 15554.000 39.366 2.835 + 15554.500 34.054 2.842 + 15555.000 30.724 2.849 + 15555.500 24.580 2.858 + 15556.000 21.114 2.862 + 15556.500 17.486 2.883 + 15557.000 15.448 2.892 + 15557.500 14.403 2.910 + 15558.000 14.269 2.915 + 15558.500 14.043 2.909 + 15559.000 12.661 2.897 + 15559.500 13.652 2.893 + 15560.000 13.846 2.888 + 15560.500 14.618 2.876 + 15561.000 14.285 2.865 + 15561.500 13.664 2.866 + 15562.000 14.020 2.866 + 15562.500 15.468 2.853 + 15563.000 15.339 2.850 + 15563.500 16.200 2.857 + 15564.000 16.152 2.863 + 15564.500 17.530 2.871 + 15565.000 19.186 2.867 + 15565.500 20.199 2.864 + 15566.000 20.877 2.859 + 15566.500 20.153 2.854 + 15567.000 20.202 2.849 + 15567.500 21.767 2.853 + 15568.000 24.448 2.857 + 15568.500 29.652 2.850 + 15569.000 32.481 2.831 + 15569.500 36.105 2.820 + 15570.000 39.783 2.830 + 15570.500 44.040 2.852 + 15571.000 46.643 2.838 + 15571.500 47.459 2.825 + 15572.000 49.097 2.782 + 15572.500 52.020 2.770 + 15573.000 52.411 2.780 + 15573.500 48.694 2.784 + 15574.000 42.058 2.788 + 15574.500 36.464 2.791 + 15575.000 32.009 2.801 + 15575.500 30.372 2.814 + 15576.000 29.074 2.818 + 15576.500 26.660 2.847 + 15577.000 24.111 2.858 + 15577.500 23.289 2.880 + 15578.000 21.730 2.871 + 15578.500 21.758 2.856 + 15579.000 20.026 2.847 + 15579.500 20.068 2.843 + 15580.000 21.674 2.852 + 15580.500 22.304 2.879 + 15581.000 22.997 2.907 + 15581.500 23.115 2.899 + 15582.000 23.166 2.885 + 15582.500 23.147 2.820 + 15583.000 23.069 2.819 + 15583.500 23.785 2.824 + 15584.000 23.890 2.831 + 15584.500 24.024 2.843 + 15585.000 23.255 2.845 + 15585.500 23.188 2.852 + 15586.000 23.043 2.852 + 15586.500 23.109 2.857 + 15587.000 21.783 2.858 + 15587.500 21.829 2.858 + 15588.000 21.979 2.852 + 15588.500 24.214 2.838 + 15589.000 25.379 2.824 + 15589.500 25.407 2.816 + 15590.000 25.608 2.816 + 15590.500 24.979 2.821 + 15591.000 25.728 2.817 + 15591.500 26.314 2.807 + 15592.000 26.254 2.804 + 15592.500 26.296 2.805 + 15593.000 26.269 2.809 + 15593.500 26.241 2.810 + 15594.000 26.386 2.814 + 15594.500 25.551 2.817 + 15595.000 26.142 2.820 + 15595.500 26.236 2.827 + 15596.000 26.323 2.835 + 15596.500 26.236 2.834 + 15597.000 26.811 2.824 + 15597.500 27.566 2.817 + 15598.000 27.030 2.818 + 15598.500 26.320 2.823 + 15599.000 25.568 2.830 + 15599.500 26.287 2.838 + 15600.000 26.864 2.834 + 15600.500 26.332 2.825 + 15601.000 27.117 2.822 + 15601.500 28.157 2.828 + 15602.000 29.802 2.836 + 15602.500 29.178 2.835 + 15603.000 28.423 2.832 + 15603.500 28.326 2.821 + 15604.000 29.346 2.820 + 15604.500 31.135 2.823 + 15605.000 31.674 2.824 + 15605.500 32.989 2.824 + 15606.000 33.920 2.822 + 15606.500 34.113 2.825 + 15607.000 32.613 2.826 + 15607.500 32.554 2.840 + 15608.000 32.613 2.845 + 15608.500 31.950 2.844 + 15609.000 31.086 2.824 + 15609.500 29.423 2.796 + 15610.000 29.987 2.781 + 15610.500 30.660 2.787 + 15611.000 30.157 2.804 + 15611.500 30.184 2.828 + 15612.000 30.729 2.834 + 15612.500 31.638 2.814 + 15613.000 31.767 2.803 + 15613.500 31.648 2.804 + 15614.000 30.885 2.816 + 15614.500 30.890 2.831 + 15615.000 30.060 2.829 + 15615.500 30.311 2.823 + 15616.000 29.705 2.819 + 15616.500 30.267 2.821 + 15617.000 30.161 2.823 + 15617.500 30.209 2.830 + 15618.000 30.054 2.841 + 15618.500 29.195 2.852 + 15619.000 28.411 2.851 + 15619.500 27.637 2.839 + 15620.000 27.640 2.836 + 15620.500 29.874 2.834 + 15621.000 31.556 2.831 + 15621.500 33.203 2.829 + 15622.000 33.868 2.826 + 15622.500 32.530 2.835 + 15623.000 31.186 2.838 + 15623.500 30.287 2.834 + 15624.000 30.436 2.825 + 15624.500 30.565 2.817 + 15625.000 30.976 2.816 + 15625.500 31.708 2.810 + 15626.000 32.695 2.810 + 15626.500 31.827 2.821 + 15627.000 30.467 2.850 + 15627.500 30.001 2.865 + 15628.000 29.298 2.869 + 15628.500 27.917 2.853 + 15629.000 27.754 2.842 + 15629.500 26.905 2.842 + 15630.000 27.363 2.845 + 15630.500 26.858 2.850 + 15631.000 26.054 2.842 + 15631.500 25.458 2.833 + 15632.000 25.472 2.824 + 15632.500 25.394 2.837 + 15633.000 24.564 2.848 + 15633.500 25.112 2.854 + 15634.000 25.331 2.844 + 15634.500 25.007 2.819 + 15635.000 25.752 2.820 + 15635.500 26.422 2.828 + 15636.000 27.132 2.843 + 15636.500 27.079 2.858 + 15637.000 26.974 2.862 + 15637.500 27.687 2.857 + 15638.000 27.935 2.854 + 15638.500 27.085 2.856 + 15639.000 26.010 2.859 + 15639.500 25.480 2.858 + 15640.000 25.264 2.855 + 15640.500 25.403 2.848 + 15641.000 24.532 2.855 + 15641.500 25.326 2.871 + 15642.000 26.084 2.871 + 15642.500 26.286 2.864 + 15643.000 26.479 2.840 + 15643.500 27.008 2.834 + 15644.000 27.741 2.832 + 15644.500 27.350 2.843 + 15645.000 27.247 2.853 + 15645.500 26.961 2.860 + 15646.000 27.176 2.868 + 15646.500 26.417 2.860 + 15647.000 26.119 2.844 + 15647.500 25.505 2.827 + 15648.000 26.620 2.826 + 15648.500 26.464 2.842 + 15649.000 26.242 2.852 + 15649.500 26.051 2.857 + 15650.000 25.584 2.858 + 15650.500 27.444 2.855 + 15651.000 27.394 2.848 + 15651.500 28.045 2.840 + 15652.000 29.356 2.822 + 15652.500 30.124 2.817 + 15653.000 29.429 2.824 + 15653.500 28.563 2.824 + 15654.000 28.406 2.820 + 15654.500 28.637 2.804 + 15655.000 28.727 2.807 + 15655.500 30.241 2.821 + 15656.000 31.178 2.836 + 15656.500 32.007 2.837 + 15657.000 32.434 2.834 + 15657.500 31.915 2.830 + 15658.000 31.776 2.830 + 15658.500 31.785 2.831 + 15659.000 31.621 2.837 + 15659.500 30.786 2.850 + 15660.000 29.735 2.854 + 15660.500 28.607 2.851 + 15661.000 27.812 2.842 + 15661.500 27.848 2.839 + 15662.000 27.080 2.847 + 15662.500 26.913 2.856 + 15663.000 26.182 2.863 + 15663.500 26.296 2.854 + 15664.000 26.737 2.842 + 15664.500 28.163 2.842 + 15665.000 27.845 2.852 + 15665.500 29.398 2.848 + 15666.000 30.221 2.838 + 15666.500 32.334 2.840 + 15667.000 32.599 2.843 + 15667.500 34.351 2.842 + 15668.000 36.993 2.835 + 15668.500 39.421 2.822 + 15669.000 39.102 2.820 + 15669.500 35.116 2.825 + 15670.000 33.465 2.828 + 15670.500 33.335 2.846 + 15671.000 33.276 2.856 + 15671.500 33.370 2.858 + 15672.000 33.210 2.865 + 15672.500 33.909 2.865 + 15673.000 34.344 2.856 + 15673.500 36.738 2.841 + 15674.000 41.286 2.826 + 15674.500 45.150 2.824 + 15675.000 54.276 2.813 + 15675.500 62.007 2.802 + 15676.000 59.669 2.789 + 15676.500 55.067 2.795 + 15677.000 47.281 2.802 + 15677.500 42.046 2.806 + 15678.000 40.231 2.806 + 15678.500 34.068 2.793 + 15679.000 32.390 2.791 + 15679.500 29.234 2.796 + 15680.000 27.218 2.799 + 15680.500 25.161 2.801 + 15681.000 23.734 2.824 + 15681.500 22.675 2.844 + 15682.000 24.540 2.861 + 15682.500 25.698 2.875 + 15683.000 27.108 2.910 + 15683.500 27.353 2.948 + 15684.000 30.177 2.953 + 15684.500 33.317 2.904 + 15685.000 38.328 2.822 + 15685.500 58.002 2.798 + 15686.000 65.981 2.806 + 15686.500 90.685 2.814 + 15687.000 92.614 2.804 + 15687.500 97.914 2.801 + 15688.000 103.197 2.827 + 15688.500 103.320 2.822 + 15689.000 98.286 2.761 + 15689.500 90.871 2.722 + 15690.000 84.986 2.761 + 15690.500 68.756 2.826 + 15691.000 65.863 2.842 + 15691.500 72.197 2.834 + 15692.000 89.128 2.807 + 15692.500 98.180 2.770 + 15693.000 114.430 2.737 + 15693.500 116.359 2.755 + 15694.000 121.285 2.766 + 15694.500 117.393 2.766 + 15695.000 99.003 2.759 + 15695.500 81.094 2.776 + 15696.000 62.887 2.826 + 15696.500 42.195 2.856 + 15697.000 36.926 2.858 + 15697.500 30.892 2.848 + 15698.000 25.452 2.844 + 15698.500 24.123 2.838 + 15699.000 24.157 2.837 + 15699.500 29.162 2.832 + 15700.000 32.635 2.832 + 15700.500 40.209 2.828 + 15701.000 40.829 2.816 + 15701.500 41.426 2.806 + 15702.000 39.016 2.812 + 15702.500 36.454 2.833 + 15703.000 37.107 2.855 + 15703.500 39.749 2.850 + 15704.000 49.681 2.822 + 15704.500 53.519 2.792 + 15705.000 53.255 2.789 + 15705.500 49.182 2.805 + 15706.000 40.393 2.823 + 15706.500 36.702 2.831 + 15707.000 35.521 2.827 + 15707.500 36.805 2.816 + 15708.000 43.980 2.809 + 15708.500 58.214 2.808 + 15709.000 60.135 2.815 + 15709.500 58.001 2.820 + 15710.000 54.056 2.816 + 15710.500 52.121 2.816 + 15711.000 50.016 2.821 + 15711.500 48.252 2.827 + 15712.000 48.261 2.826 + 15712.500 46.089 2.823 + 15713.000 45.438 2.820 + 15713.500 44.397 2.821 + 15714.000 43.891 2.832 + 15714.500 41.716 2.839 + 15715.000 41.465 2.841 + 15715.500 38.930 2.839 + 15716.000 36.966 2.847 + 15716.500 33.926 2.854 + 15717.000 32.613 2.858 + 15717.500 31.054 2.856 + 15718.000 28.512 2.837 + 15718.500 27.001 2.831 + 15719.000 26.430 2.830 + 15719.500 26.286 2.840 + 15720.000 26.208 2.842 + 15720.500 26.378 2.834 + 15721.000 25.581 2.824 + 15721.500 25.599 2.821 + 15722.000 24.820 2.833 + 15722.500 24.568 2.839 + 15723.000 23.826 2.832 + 15723.500 23.948 2.820 + 15724.000 23.766 2.831 + 15724.500 23.007 2.855 + 15725.000 23.292 2.857 + 15725.500 24.212 2.855 + 15726.000 24.644 2.848 + 15726.500 27.563 2.843 + 15727.000 30.060 2.833 + 15727.500 34.840 2.825 + 15728.000 35.856 2.822 + 15728.500 36.562 2.822 + 15729.000 36.312 2.816 + 15729.500 35.736 2.809 + 15730.000 36.604 2.814 + 15730.500 36.491 2.822 + 15731.000 36.219 2.825 + 15731.500 36.173 2.815 + 15732.000 37.553 2.807 + 15732.500 40.023 2.815 + 15733.000 40.355 2.836 + 15733.500 40.372 2.848 + 15734.000 40.552 2.864 + 15734.500 41.195 2.858 + 15735.000 41.853 2.852 + 15735.500 43.453 2.850 + 15736.000 45.898 2.848 + 15736.500 48.220 2.847 + 15737.000 50.381 2.834 + 15737.500 51.996 2.816 + 15738.000 55.917 2.800 + 15738.500 59.524 2.785 + 15739.000 66.339 2.797 + 15739.500 68.979 2.814 + 15740.000 76.717 2.808 + 15740.500 83.625 2.783 + 15741.000 85.037 2.738 + 15741.500 84.534 2.729 + 15742.000 74.899 2.720 + 15742.500 68.706 2.754 + 15743.000 62.908 2.780 + 15743.500 54.851 2.809 + 15744.000 47.794 2.831 + 15744.500 44.193 2.835 + 15745.000 41.988 2.836 + 15745.500 40.607 2.833 + 15746.000 39.829 2.833 + 15746.500 39.986 2.848 + 15747.000 38.009 2.852 + 15747.500 40.388 2.845 + 15748.000 40.721 2.836 + 15748.500 41.537 2.817 + 15749.000 42.295 2.812 + 15749.500 43.020 2.806 + 15750.000 43.752 2.815 + 15750.500 44.524 2.824 + 15751.000 45.134 2.833 + 15751.500 44.887 2.833 + 15752.000 45.919 2.844 + 15752.500 48.516 2.869 + 15753.000 55.890 2.875 + 15753.500 60.182 2.875 + 15754.000 67.056 2.827 + 15754.500 68.474 2.809 + 15755.000 71.244 2.783 + 15755.500 70.912 2.773 + 15756.000 71.086 2.755 + 15756.500 70.386 2.767 + 15757.000 70.548 2.788 + 15757.500 71.053 2.823 + 15758.000 71.961 2.849 + 15758.500 71.078 2.826 + 15759.000 70.995 2.796 + 15759.500 71.052 2.756 + 15760.000 70.068 2.767 + 15760.500 68.332 2.785 + 15761.000 67.675 2.802 + 15761.500 66.921 2.806 + 15762.000 67.808 2.806 + 15762.500 67.051 2.807 + 15763.000 66.102 2.810 + 15763.500 65.295 2.808 + 15764.000 64.368 2.811 + 15764.500 62.828 2.825 + 15765.000 62.420 2.845 + 15765.500 59.158 2.848 + 15766.000 55.966 2.832 + 15766.500 52.322 2.805 + 15767.000 50.701 2.807 + 15767.500 49.012 2.817 + 15768.000 48.881 2.837 + 15768.500 48.210 2.840 + 15769.000 47.608 2.831 + 15769.500 47.461 2.823 + 15770.000 47.471 2.829 + 15770.500 47.959 2.850 + 15771.000 48.235 2.862 + 15771.500 48.332 2.884 + 15772.000 47.573 2.879 + 15772.500 45.706 2.831 + 15773.000 41.331 2.786 + 15773.500 38.961 2.759 + 15774.000 33.365 2.753 + 15774.500 30.899 2.773 + 15775.000 30.208 2.779 + 15775.500 29.955 2.779 + 15776.000 29.101 2.791 + 15776.500 27.013 2.814 + 15777.000 25.442 2.827 + 15777.500 26.434 2.847 + 15778.000 29.161 2.832 + 15778.500 34.284 2.827 + 15779.000 35.794 2.821 + 15779.500 37.443 2.819 + 15780.000 36.774 2.813 + 15780.500 34.908 2.813 + 15781.000 32.594 2.824 + 15781.500 30.231 2.829 + 15782.000 28.043 2.834 + 15782.500 28.394 2.834 + 15783.000 29.768 2.835 + 15783.500 30.855 2.844 + 15784.000 31.047 2.855 + 15784.500 30.390 2.855 + 15785.000 29.688 2.854 + 15785.500 28.589 2.847 + 15786.000 27.535 2.837 + 15786.500 25.532 2.834 + 15787.000 25.033 2.828 + 15787.500 23.957 2.817 + 15788.000 22.502 2.818 + 15788.500 19.954 2.820 + 15789.000 20.057 2.822 + 15789.500 19.705 2.822 + 15790.000 19.364 2.826 + 15790.500 19.034 2.844 + 15791.000 18.651 2.866 + 15791.500 18.303 2.897 + 15792.000 18.018 2.886 + 15792.500 17.527 2.857 + 15793.000 18.310 2.849 + 15793.500 18.705 2.850 + 15794.000 20.188 2.867 + 15794.500 19.940 2.858 + 15795.000 20.003 2.843 + 15795.500 20.006 2.814 + 15796.000 20.062 2.808 + 15796.500 19.395 2.848 + 15797.000 18.405 2.865 + 15797.500 16.921 2.873 + 15798.000 16.911 2.868 + 15798.500 16.819 2.863 + 15799.000 16.865 2.868 + 15799.500 17.030 2.875 + 15800.000 17.292 2.873 + 15800.500 16.198 2.870 + 15801.000 16.022 2.870 + 15801.500 16.140 2.874 + 15802.000 15.647 2.876 + 15802.500 15.522 2.872 + 15803.000 15.297 2.861 + 15803.500 15.153 2.857 + 15804.000 16.008 2.869 + 15804.500 16.254 2.891 + 15805.000 18.472 2.901 + 15805.500 18.492 2.897 + 15806.000 19.439 2.874 + 15806.500 17.704 2.818 + 15807.000 15.327 2.849 + 15807.500 15.212 2.887 + 15808.000 15.953 2.924 + 15808.500 16.206 2.863 + 15809.000 16.900 2.787 + 15809.500 16.985 2.787 + 15810.000 15.563 2.815 + 15810.500 15.279 2.861 + 15811.000 15.390 2.901 + 15811.500 16.387 2.910 + 15812.000 19.065 2.920 + 15812.500 20.465 2.883 + 15813.000 23.618 2.842 + 15813.500 27.468 2.807 + 15814.000 28.316 2.798 + 15814.500 30.387 2.798 + 15815.000 32.795 2.798 + 15815.500 43.091 2.802 + 15816.000 61.273 2.804 + 15816.500 65.024 2.807 + 15817.000 62.070 2.800 + 15817.500 44.393 2.797 + 15818.000 32.762 2.784 + 15818.500 28.084 2.809 + 15819.000 18.140 2.824 + 15819.500 16.820 2.829 + 15820.000 14.134 2.832 + 15820.500 14.042 2.838 + 15821.000 12.599 2.843 + 15821.500 12.106 2.850 + 15822.000 12.142 2.848 + 15822.500 12.277 2.844 + 15823.000 13.170 2.837 + 15823.500 13.793 2.834 + 15824.000 14.748 2.836 + 15824.500 15.302 2.840 + 15825.000 15.415 2.839 + 15825.500 14.582 2.838 + 15826.000 15.092 2.841 + 15826.500 15.932 2.851 + 15827.000 15.956 2.854 + 15827.500 15.051 2.863 + 15828.000 14.542 2.867 + 15828.500 13.859 2.855 + 15829.000 13.795 2.847 + 15829.500 13.234 2.830 + 15830.000 13.373 2.825 + 15830.500 13.415 2.838 + 15831.000 13.013 2.884 + 15831.500 13.407 2.879 + 15832.000 13.059 2.868 + 15832.500 13.197 2.858 + 15833.000 13.002 2.857 + 15833.500 12.219 2.861 + 15834.000 12.782 2.860 + 15834.500 13.462 2.840 + 15835.000 14.395 2.812 + 15835.500 14.503 2.812 + 15836.000 14.568 2.818 + 15836.500 13.820 2.823 + 15837.000 12.179 2.827 + 15837.500 12.227 2.833 + 15838.000 12.249 2.850 + 15838.500 13.409 2.863 + 15839.000 13.403 2.864 + 15839.500 12.260 2.864 + 15840.000 12.212 2.863 + 15840.500 12.091 2.840 + 15841.000 12.203 2.829 + 15841.500 12.140 2.815 + 15842.000 12.004 2.811 + 15842.500 11.331 2.833 + 15843.000 11.294 2.850 + 15843.500 12.020 2.865 + 15844.000 12.278 2.865 + 15844.500 13.068 2.856 + 15845.000 12.879 2.851 + 15845.500 12.942 2.851 + 15846.000 13.119 2.854 + 15846.500 13.800 2.881 + 15847.000 13.548 2.893 + 15847.500 12.868 2.904 + 15848.000 12.992 2.894 + 15848.500 12.785 2.863 + 15849.000 11.911 2.855 + 15849.500 11.337 2.847 + 15850.000 11.434 2.841 + 15850.500 12.380 2.839 + 15851.000 13.598 2.839 + 15851.500 13.739 2.836 + 15852.000 14.540 2.857 + 15852.500 15.261 2.876 + 15853.000 13.855 2.906 + 15853.500 13.083 2.913 + 15854.000 12.950 2.908 + 15854.500 12.987 2.880 + 15855.000 15.298 2.864 + 15855.500 17.898 2.860 + 15856.000 20.577 2.862 + 15856.500 23.229 2.863 + 15857.000 25.850 2.863 + 15857.500 28.519 2.857 + 15858.000 31.206 2.846 + 15858.500 33.681 2.828 + 15859.000 36.491 2.819 + 15859.500 32.879 2.820 + 15860.000 28.209 2.831 + 15860.500 21.760 2.832 + 15861.000 20.162 2.833 + 15861.500 17.062 2.834 + 15862.000 15.614 2.834 + 15862.500 14.931 2.834 + 15863.000 15.525 2.828 + 15863.500 16.005 2.821 + 15864.000 17.273 2.817 + 15864.500 20.552 2.812 + 15865.000 24.409 2.806 + 15865.500 27.617 2.800 + 15866.000 30.096 2.798 + 15866.500 33.066 2.795 + 15867.000 34.874 2.794 + 15867.500 36.532 2.791 + 15868.000 38.491 2.788 + 15868.500 41.945 2.798 + 15869.000 49.984 2.812 + 15869.500 62.077 2.818 + 15870.000 63.943 2.827 + 15870.500 61.405 2.827 + 15871.000 54.313 2.826 + 15871.500 51.292 2.825 + 15872.000 46.863 2.823 + 15872.500 49.207 2.825 + 15873.000 50.792 2.827 + 15873.500 50.258 2.828 + 15874.000 45.622 2.825 + 15874.500 32.680 2.821 + 15875.000 30.023 2.819 + 15875.500 27.795 2.823 + 15876.000 27.022 2.829 + 15876.500 26.702 2.844 + 15877.000 26.019 2.840 + 15877.500 27.351 2.829 + 15878.000 28.846 2.816 + 15878.500 31.610 2.805 + 15879.000 31.244 2.810 + 15879.500 29.777 2.815 + 15880.000 29.098 2.852 + 15880.500 27.498 2.847 + 15881.000 27.074 2.835 + 15881.500 27.067 2.828 + 15882.000 27.115 2.815 + 15882.500 27.648 2.853 + 15883.000 27.196 2.868 + 15883.500 27.085 2.888 + 15884.000 26.944 2.884 + 15884.500 27.728 2.852 + 15885.000 27.815 2.832 + 15885.500 27.846 2.812 + 15886.000 28.013 2.809 + 15886.500 28.781 2.820 + 15887.000 30.427 2.834 + 15887.500 31.639 2.848 + 15888.000 31.583 2.848 + 15888.500 30.853 2.829 + 15889.000 29.452 2.810 + 15889.500 29.322 2.812 + 15890.000 29.164 2.817 + 15890.500 32.104 2.819 + 15891.000 33.970 2.820 + 15891.500 41.006 2.807 + 15892.000 43.474 2.799 + 15892.500 47.993 2.782 + 15893.000 53.923 2.779 + 15893.500 57.706 2.776 + 15894.000 59.820 2.774 + 15894.500 60.051 2.768 + 15895.000 61.599 2.766 + 15895.500 61.632 2.766 + 15896.000 61.085 2.767 + 15896.500 59.960 2.770 + 15897.000 57.118 2.775 + 15897.500 55.367 2.783 + 15898.000 49.585 2.788 + 15898.500 43.524 2.810 + 15899.000 37.263 2.824 + 15899.500 31.946 2.842 + 15900.000 28.594 2.873 + 15900.500 23.714 2.882 + 15901.000 20.822 2.867 + 15901.500 19.470 2.852 + 15902.000 17.959 2.837 + 15902.500 16.854 2.836 + 15903.000 15.958 2.836 + 15903.500 16.099 2.834 + 15904.000 16.044 2.830 + 15904.500 16.154 2.837 + 15905.000 15.429 2.845 + 15905.500 15.292 2.851 + 15906.000 15.347 2.852 + 15906.500 14.525 2.857 + 15907.000 13.637 2.861 + 15907.500 13.755 2.860 + 15908.000 13.716 2.854 + 15908.500 13.596 2.850 + 15909.000 12.851 2.853 + 15909.500 12.827 2.858 + 15910.000 12.069 2.860 + 15910.500 12.162 2.864 + 15911.000 12.140 2.876 + 15911.500 12.152 2.892 + 15912.000 11.963 2.901 + 15912.500 11.110 2.901 + 15913.000 12.408 2.904 + 15913.500 12.726 2.905 + 15914.000 17.479 2.904 + 15914.500 21.780 2.876 + 15915.000 36.179 2.849 + 15915.500 46.602 2.822 + 15916.000 54.274 2.808 + 15916.500 50.560 2.812 + 15917.000 46.837 2.844 + 15917.500 41.033 2.850 + 15918.000 36.640 2.859 + 15918.500 28.134 2.854 + 15919.000 27.672 2.844 + 15919.500 28.284 2.834 + 15920.000 29.210 2.829 + 15920.500 28.132 2.822 + 15921.000 27.818 2.818 + 15921.500 25.957 2.818 + 15922.000 27.375 2.822 + 15922.500 29.980 2.823 + 15923.000 30.206 2.819 + 15923.500 30.164 2.816 + 15924.000 28.504 2.817 + 15924.500 27.750 2.825 + 15925.000 26.336 2.825 + 15925.500 26.356 2.821 + 15926.000 25.612 2.816 + 15926.500 24.111 2.820 + 15927.000 23.236 2.847 + 15927.500 21.604 2.856 + 15928.000 21.582 2.868 + 15928.500 21.601 2.863 + 15929.000 21.400 2.863 + 15929.500 20.393 2.871 + 15930.000 19.121 2.873 + 15930.500 18.030 2.859 + 15931.000 18.833 2.853 + 15931.500 19.786 2.840 + 15932.000 19.898 2.836 + 15932.500 19.226 2.838 + 15933.000 20.088 2.834 + 15933.500 19.854 2.819 + 15934.000 20.624 2.814 + 15934.500 23.673 2.816 + 15935.000 28.574 2.820 + 15935.500 36.411 2.814 + 15936.000 41.314 2.804 + 15936.500 58.303 2.786 + 15937.000 69.748 2.772 + 15937.500 80.492 2.776 + 15938.000 76.716 2.788 + 15938.500 64.090 2.830 + 15939.000 66.464 2.837 + 15939.500 41.787 2.848 + 15940.000 37.608 2.852 + 15940.500 25.764 2.856 + 15941.000 20.798 2.856 + 15941.500 16.880 2.852 + 15942.000 13.729 2.849 + 15942.500 13.712 2.851 + 15943.000 12.149 2.852 + 15943.500 11.968 2.872 + 15944.000 11.830 2.884 + 15944.500 12.797 2.875 + 15945.000 13.402 2.856 + 15945.500 15.014 2.858 + 15946.000 15.442 2.852 + 15946.500 16.177 2.840 + 15947.000 16.103 2.828 + 15947.500 15.465 2.816 + 15948.000 15.412 2.822 + 15948.500 16.266 2.849 + 15949.000 14.809 2.851 + 15949.500 13.801 2.856 + 15950.000 13.549 2.861 + 15950.500 11.871 2.867 + 15951.000 11.513 2.877 + 15951.500 12.142 2.883 + 15952.000 12.924 2.883 + 15952.500 13.800 2.873 + 15953.000 13.574 2.853 + 15953.500 12.720 2.842 + 15954.000 12.020 2.809 + 15954.500 12.847 2.797 + 15955.000 13.224 2.792 + 15955.500 14.948 2.805 + 15956.000 16.092 2.811 + 15956.500 17.110 2.828 + 15957.000 17.554 2.843 + 15957.500 16.800 2.862 + 15958.000 16.252 2.870 + 15958.500 15.377 2.875 + 15959.000 15.183 2.860 + 15959.500 15.980 2.848 + 15960.000 16.041 2.843 + 15960.500 15.963 2.850 + 15961.000 15.251 2.852 + 15961.500 15.067 2.850 + 15962.000 14.945 2.837 + 15962.500 14.483 2.835 + 15963.000 14.299 2.855 + 15963.500 14.279 2.862 + 15964.000 14.798 2.865 + 15964.500 16.317 2.858 + 15965.000 15.410 2.853 + 15965.500 14.777 2.849 + 15966.000 13.785 2.836 + 15966.500 14.377 2.835 + 15967.000 14.419 2.836 + 15967.500 15.184 2.844 + 15968.000 15.235 2.852 + 15968.500 15.416 2.860 + 15969.000 14.618 2.862 + 15969.500 14.520 2.860 + 15970.000 14.654 2.850 + 15970.500 15.373 2.839 + 15971.000 15.230 2.828 + 15971.500 15.533 2.815 + 15972.000 15.539 2.823 + 15972.500 15.107 2.840 + 15973.000 14.303 2.840 + 15973.500 13.642 2.840 + 15974.000 14.466 2.837 + 15974.500 14.619 2.850 + 15975.000 15.346 2.859 + 15975.500 15.344 2.854 + 15976.000 14.581 2.849 + 15976.500 15.087 2.816 + 15977.000 15.999 2.817 + 15977.500 18.436 2.824 + 15978.000 21.029 2.835 + 15978.500 24.377 2.849 + 15979.000 31.011 2.856 + 15979.500 35.218 2.854 + 15980.000 39.881 2.848 + 15980.500 40.210 2.838 + 15981.000 37.665 2.838 + 15981.500 34.668 2.842 + 15982.000 31.649 2.849 + 15982.500 28.045 2.843 + 15983.000 26.348 2.834 + 15983.500 21.766 2.833 + 15984.000 17.841 2.835 + 15984.500 15.438 2.828 + 15985.000 13.155 2.829 + 15985.500 11.286 2.838 + 15986.000 13.542 2.844 + 15986.500 15.206 2.842 + 15987.000 21.526 2.837 + 15987.500 24.990 2.836 + 15988.000 30.089 2.842 + 15988.500 31.828 2.848 + 15989.000 32.675 2.870 + 15989.500 34.093 2.875 + 15990.000 36.365 2.868 + 15990.500 40.319 2.829 + 15991.000 43.842 2.816 + 15991.500 51.278 2.815 + 15992.000 57.343 2.835 + 15992.500 67.667 2.829 + 15993.000 63.800 2.817 + 15993.500 60.297 2.814 + 15994.000 55.785 2.812 + 15994.500 45.437 2.824 + 15995.000 40.514 2.830 + 15995.500 37.095 2.843 + 15996.000 32.773 2.854 + 15996.500 30.609 2.820 + 15997.000 28.517 2.802 + 15997.500 27.558 2.797 + 15998.000 26.994 2.800 + 15998.500 27.077 2.808 + 15999.000 27.018 2.818 + 15999.500 26.892 2.834 + 16000.000 26.120 2.851 + 16000.500 25.606 2.846 + 16001.000 25.586 2.819 + 16001.500 27.003 2.807 + 16002.000 29.936 2.814 + 16002.500 37.317 2.830 + 16003.000 41.776 2.842 + 16003.500 49.424 2.840 + 16004.000 58.533 2.839 + 16004.500 67.349 2.838 + 16005.000 65.903 2.832 + 16005.500 65.904 2.822 + 16006.000 64.018 2.819 + 16006.500 49.116 2.828 + 16007.000 41.827 2.837 + 16007.500 34.940 2.840 + 16008.000 31.851 2.839 + 16008.500 29.630 2.832 + 16009.000 28.823 2.825 + 16009.500 30.173 2.819 + 16010.000 31.806 2.819 + 16010.500 34.690 2.832 + 16011.000 37.690 2.842 + 16011.500 39.629 2.839 + 16012.000 41.313 2.835 + 16012.500 42.185 2.821 + 16013.000 44.449 2.820 + 16013.500 45.981 2.824 + 16014.000 48.243 2.822 + 16014.500 50.689 2.819 + 16015.000 51.680 2.813 + 16015.500 51.538 2.810 + 16016.000 52.121 2.804 + 16016.500 52.968 2.794 + 16017.000 53.808 2.780 + 16017.500 53.607 2.772 + 16018.000 52.075 2.772 + 16018.500 49.173 2.788 + 16019.000 49.213 2.809 + 16019.500 49.987 2.810 + 16020.000 50.352 2.810 + 16020.500 49.147 2.809 + 16021.000 50.743 2.803 + 16021.500 51.281 2.800 + 16022.000 51.908 2.790 + 16022.500 51.363 2.794 + 16023.000 52.332 2.798 + 16023.500 52.253 2.792 + 16024.000 50.935 2.784 + 16024.500 52.220 2.785 + 16025.000 53.788 2.796 + 16025.500 54.358 2.811 + 16026.000 54.456 2.823 + 16026.500 52.385 2.816 + 16027.000 50.341 2.799 + 16027.500 48.725 2.787 + 16028.000 48.471 2.771 + 16028.500 50.019 2.784 + 16029.000 49.745 2.814 + 16029.500 49.579 2.829 + 16030.000 49.292 2.833 + 16030.500 48.381 2.819 + 16031.000 48.954 2.805 + 16031.500 49.543 2.796 + 16032.000 49.835 2.792 + 16032.500 49.797 2.797 + 16033.000 49.809 2.802 + 16033.500 49.792 2.798 + 16034.000 50.011 2.795 + 16034.500 50.361 2.781 + 16035.000 50.408 2.778 + 16035.500 51.879 2.787 + 16036.000 52.150 2.805 + 16036.500 52.173 2.840 + 16037.000 52.203 2.855 + 16037.500 52.116 2.858 + 16038.000 51.812 2.850 + 16038.500 48.908 2.840 + 16039.000 49.146 2.834 + 16039.500 48.905 2.826 + 16040.000 49.650 2.821 + 16040.500 49.807 2.818 + 16041.000 49.825 2.827 + 16041.500 49.785 2.832 + 16042.000 49.811 2.825 + 16042.500 49.821 2.813 + 16043.000 49.827 2.771 + 16043.500 51.536 2.759 + 16044.000 49.117 2.745 + 16044.500 47.373 2.765 + 16045.000 47.331 2.780 + 16045.500 48.133 2.794 + 16046.000 48.336 2.796 + 16046.500 49.241 2.798 + 16047.000 50.157 2.801 + 16047.500 51.714 2.807 + 16048.000 51.277 2.808 + 16048.500 49.626 2.802 + 16049.000 49.826 2.802 + 16049.500 49.897 2.801 + 16050.000 49.142 2.799 diff --git a/ThirdParty/NRLib/well_UnitTests/CMakeLists.txt b/ThirdParty/NRLib/well_UnitTests/CMakeLists.txt new file mode 100644 index 0000000000..e833930a71 --- /dev/null +++ b/ThirdParty/NRLib/well_UnitTests/CMakeLists.txt @@ -0,0 +1,33 @@ +cmake_minimum_required (VERSION 2.8) + +project ( well_UnitTests ) + + +include_directories ( + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/.. + ${CMAKE_CURRENT_SOURCE_DIR}/../.. + + ${NR_well_SOURCE_DIR} +) + + +set( PROJECT_FILES + + well_UnitTests.cpp + ../../gtest/gtest-all.cc + + wellBasicTest.cpp +) + +# add the executable +add_executable (${PROJECT_NAME} + ${PROJECT_FILES} +) + +source_group("" FILES ${PROJECT_FILES}) + +target_link_libraries ( ${PROJECT_NAME} + NRLib +) + diff --git a/ThirdParty/NRLib/well_UnitTests/wellBasicTest.cpp b/ThirdParty/NRLib/well_UnitTests/wellBasicTest.cpp new file mode 100644 index 0000000000..bd4c6503fc --- /dev/null +++ b/ThirdParty/NRLib/well_UnitTests/wellBasicTest.cpp @@ -0,0 +1,41 @@ + +#include "gtest/gtest.h" + +#include "well.hpp" + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(WellBaseTest, ReadFromFile) +{ + std::string wellName = "C:/dev/projects/ResInsight/GitHub/NRWellProject/well_UnitTests/Bean_A.las"; + + int wellFormat = NRLib::Well::LAS; + NRLib::Well* well = NRLib::Well::ReadWell(wellName, wellFormat); + + std::cout << "Well name : " << well->GetWellName() << "\n"; + + std::cout << "Total number of logs : " << well->GetNlog() << "\n"; + + const std::map<std::string, std::vector<double> >& continuousLogs = well->GetContLog(); + + std::cout << "Continuous log names : " << "\n"; + + std::vector<std::string> names; + std::map<std::string, std::vector<double> >::const_iterator it; + for (it = continuousLogs.begin(); it != continuousLogs.end(); it++) + { + std::cout << " " << it->first << "data value count : " << it->second.size() << "\n"; + names.push_back(it->first); + } + + for (size_t i = 0; i < 20; i++) + { + for (size_t n = 0; n < names.size(); n++) + { + std::cout << "\t" << continuousLogs.at(names[n])[i]; + } + std::cout << "\n"; + } +} diff --git a/ThirdParty/NRLib/well_UnitTests/well_UnitTests.cpp b/ThirdParty/NRLib/well_UnitTests/well_UnitTests.cpp new file mode 100644 index 0000000000..be0fb9328d --- /dev/null +++ b/ThirdParty/NRLib/well_UnitTests/well_UnitTests.cpp @@ -0,0 +1,20 @@ + + +#include "gtest/gtest.h" +#include <stdio.h> +#include <iostream> +#include <string> + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +int main(int argc, char **argv) +{ + testing::InitGoogleTest(&argc, argv); + int result = RUN_ALL_TESTS(); + + char text[5]; + std::cin.getline(text, 5); + + return result; +} diff --git a/ThirdParty/Qwt/COPYING b/ThirdParty/Qwt/COPYING new file mode 100644 index 0000000000..9c01f7e212 --- /dev/null +++ b/ThirdParty/Qwt/COPYING @@ -0,0 +1,543 @@ + Qwt License + Version 1.0, January 1, 2003 + +The Qwt library and included programs are provided under the terms +of the GNU LESSER GENERAL PUBLIC LICENSE (LGPL) with the following +exceptions: + + 1. Widgets that are subclassed from Qwt widgets do not + constitute a derivative work. + + 2. Static linking of applications and widgets to the + Qwt library does not constitute a derivative work + and does not require the author to provide source + code for the application or widget, use the shared + Qwt libraries, or link their applications or + widgets against a user-supplied version of Qwt. + + If you link the application or widget to a modified + version of Qwt, then the changes to Qwt must be + provided under the terms of the LGPL in sections + 1, 2, and 4. + + 3. You do not have to provide a copy of the Qwt license + with programs that are linked to the Qwt library, nor + do you have to identify the Qwt license in your + program or documentation as required by section 6 + of the LGPL. + + + However, programs must still identify their use of Qwt. + The following example statement can be included in user + documentation to satisfy this requirement: + + [program/widget] is based in part on the work of + the Qwt project (http://qwt.sf.net). + +---------------------------------------------------------------------- + + + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + <one line to give the library's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + <signature of Ty Coon>, 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/ThirdParty/Qwt/INSTALL b/ThirdParty/Qwt/INSTALL new file mode 100644 index 0000000000..bafcbe039e --- /dev/null +++ b/ThirdParty/Qwt/INSTALL @@ -0,0 +1 @@ +see doc/html/qwtinstall.html diff --git a/ThirdParty/Qwt/README b/ThirdParty/Qwt/README new file mode 100644 index 0000000000..46ee34e418 --- /dev/null +++ b/ThirdParty/Qwt/README @@ -0,0 +1,34 @@ + +The Qwt Widget Library +---------------------- + + Qwt is an extension to the libraries of the Qt Project. + + The Qwt library contains widgets and components which are + primarily useful for technical and scientifical purposes. + It includes a 2-D plotting widget, different kinds of sliders, + and much more. + + Qwt is hosted at http://qwt.sf.net + +Installation +------------ + + Read INSTALL how to build and install Qwt. + +Copyright +--------- + + Qwt Widget Library + Copyright (C) 1997 Josef Wilgen + Copyright (C) 2002 Uwe Rathmann + + Qwt is published under the Qwt License, Version 1.0. + You should have received a copy of this licence in the file + COPYING. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + diff --git a/ThirdParty/Qwt/designer/designer.pro b/ThirdParty/Qwt/designer/designer.pro new file mode 100644 index 0000000000..c269e9da27 --- /dev/null +++ b/ThirdParty/Qwt/designer/designer.pro @@ -0,0 +1,132 @@ +################################################################ +# Qwt Widget Library +# Copyright (C) 1997 Josef Wilgen +# Copyright (C) 2002 Uwe Rathmann +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the Qwt License, Version 1.0 +################################################################ + +QWT_ROOT = $${PWD}/.. + +include ( $${QWT_ROOT}/qwtconfig.pri ) +include ( $${QWT_ROOT}/qwtbuild.pri ) +include ( $${QWT_ROOT}/qwtfunctions.pri ) + + +CONFIG( debug_and_release ) { + + # When building debug_and_release the designer plugin is built + # for release only. If you want to have a debug version it has to be + # done with "CONFIG += debug" only. + + message("debug_and_release: building the Qwt designer plugin in release mode only") + + CONFIG -= debug_and_release + CONFIG += release +} + +contains(QWT_CONFIG, QwtDesigner) { + + CONFIG += qt plugin + CONFIG += warn_on + + greaterThan(QT_MAJOR_VERSION, 4) { + + QT += designer + } + else { + + CONFIG += designer + } + + + TEMPLATE = lib + TARGET = qwt_designer_plugin + + DESTDIR = plugins/designer + + INCLUDEPATH += $${QWT_ROOT}/src + DEPENDPATH += $${QWT_ROOT}/src + + contains(QWT_CONFIG, QwtDll) { + + contains(QWT_CONFIG, QwtDesignerSelfContained) { + + QWT_CONFIG += include_src + } + + } else { + + # for linking against a static library the + # plugin will be self contained anyway + } + + contains(QWT_CONFIG, include_src) { + + # compile all qwt classes into the plugin + + include ( $${QWT_ROOT}/src/src.pri ) + + for( header, HEADERS) { + QWT_HEADERS += $${QWT_ROOT}/src/$${header} + } + + for( source, SOURCES ) { + QWT_SOURCES += $${QWT_ROOT}/src/$${source} + } + + HEADERS = $${QWT_HEADERS} + SOURCES = $${QWT_SOURCES} + + } else { + + # compile the path for finding the Qwt library + # into the plugin. Not supported on Windows ! + + QMAKE_RPATHDIR *= $${QWT_INSTALL_LIBS} + + contains(QWT_CONFIG, QwtFramework) { + + LIBS += -F$${QWT_ROOT}/lib + } + else { + + LIBS += -L$${QWT_ROOT}/lib + } + + qwtAddLibrary(qwt) + + contains(QWT_CONFIG, QwtDll) { + + win32 { + DEFINES += QT_DLL QWT_DLL + } + } + } + + !contains(QWT_CONFIG, QwtPlot) { + DEFINES += NO_QWT_PLOT + } + + !contains(QWT_CONFIG, QwtWidgets) { + DEFINES += NO_QWT_WIDGETS + } + + HEADERS += qwt_designer_plugin.h + SOURCES += qwt_designer_plugin.cpp + + contains(QWT_CONFIG, QwtPlot) { + + HEADERS += qwt_designer_plotdialog.h + SOURCES += qwt_designer_plotdialog.cpp + } + + RESOURCES += qwt_designer_plugin.qrc + + target.path = $${QWT_INSTALL_PLUGINS} + INSTALLS += target +} +else { + TEMPLATE = subdirs # do nothing +} diff --git a/ThirdParty/Qwt/designer/pixmaps/qwtanalogclock.png b/ThirdParty/Qwt/designer/pixmaps/qwtanalogclock.png new file mode 100644 index 0000000000..89f3451acc Binary files /dev/null and b/ThirdParty/Qwt/designer/pixmaps/qwtanalogclock.png differ diff --git a/ThirdParty/Qwt/designer/pixmaps/qwtcompass.png b/ThirdParty/Qwt/designer/pixmaps/qwtcompass.png new file mode 100644 index 0000000000..e1e54a11db Binary files /dev/null and b/ThirdParty/Qwt/designer/pixmaps/qwtcompass.png differ diff --git a/ThirdParty/Qwt/designer/pixmaps/qwtcounter.png b/ThirdParty/Qwt/designer/pixmaps/qwtcounter.png new file mode 100644 index 0000000000..1daddb63fd Binary files /dev/null and b/ThirdParty/Qwt/designer/pixmaps/qwtcounter.png differ diff --git a/ThirdParty/Qwt/designer/pixmaps/qwtdial.png b/ThirdParty/Qwt/designer/pixmaps/qwtdial.png new file mode 100644 index 0000000000..46f079c71c Binary files /dev/null and b/ThirdParty/Qwt/designer/pixmaps/qwtdial.png differ diff --git a/ThirdParty/Qwt/designer/pixmaps/qwtknob.png b/ThirdParty/Qwt/designer/pixmaps/qwtknob.png new file mode 100644 index 0000000000..2118dfa36a Binary files /dev/null and b/ThirdParty/Qwt/designer/pixmaps/qwtknob.png differ diff --git a/ThirdParty/Qwt/designer/pixmaps/qwtplot.png b/ThirdParty/Qwt/designer/pixmaps/qwtplot.png new file mode 100644 index 0000000000..8e1ca4ed50 Binary files /dev/null and b/ThirdParty/Qwt/designer/pixmaps/qwtplot.png differ diff --git a/ThirdParty/Qwt/designer/pixmaps/qwtscale.png b/ThirdParty/Qwt/designer/pixmaps/qwtscale.png new file mode 100644 index 0000000000..00a142122e Binary files /dev/null and b/ThirdParty/Qwt/designer/pixmaps/qwtscale.png differ diff --git a/ThirdParty/Qwt/designer/pixmaps/qwtslider.png b/ThirdParty/Qwt/designer/pixmaps/qwtslider.png new file mode 100644 index 0000000000..8e9316c215 Binary files /dev/null and b/ThirdParty/Qwt/designer/pixmaps/qwtslider.png differ diff --git a/ThirdParty/Qwt/designer/pixmaps/qwtthermo.png b/ThirdParty/Qwt/designer/pixmaps/qwtthermo.png new file mode 100644 index 0000000000..3b2bd50d86 Binary files /dev/null and b/ThirdParty/Qwt/designer/pixmaps/qwtthermo.png differ diff --git a/ThirdParty/Qwt/designer/pixmaps/qwtwheel.png b/ThirdParty/Qwt/designer/pixmaps/qwtwheel.png new file mode 100644 index 0000000000..c1f562cd59 Binary files /dev/null and b/ThirdParty/Qwt/designer/pixmaps/qwtwheel.png differ diff --git a/ThirdParty/Qwt/designer/pixmaps/qwtwidget.png b/ThirdParty/Qwt/designer/pixmaps/qwtwidget.png new file mode 100644 index 0000000000..cf72b754de Binary files /dev/null and b/ThirdParty/Qwt/designer/pixmaps/qwtwidget.png differ diff --git a/ThirdParty/Qwt/designer/qwt_designer_plotdialog.cpp b/ThirdParty/Qwt/designer/qwt_designer_plotdialog.cpp new file mode 100644 index 0000000000..1dba04e3e5 --- /dev/null +++ b/ThirdParty/Qwt/designer/qwt_designer_plotdialog.cpp @@ -0,0 +1,42 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#include <QLineEdit> +#include <QTabWidget> +#include <QHBoxLayout> +#include <QPushButton> +#include "qwt_designer_plotdialog.h" + +using namespace QwtDesignerPlugin; + +PlotDialog::PlotDialog( const QString &properties, QWidget *parent ): + QDialog( parent ) +{ + setWindowTitle( "Plot Properties" ); + + QLineEdit *lineEdit = new QLineEdit( properties ); + connect( lineEdit, SIGNAL( textChanged( const QString & ) ), + SIGNAL( edited( const QString & ) ) ); + + QTabWidget *tabWidget = new QTabWidget( this ); + tabWidget->addTab( lineEdit, "General" ); + + QPushButton *closeButton = new QPushButton( "Close" ); + connect( closeButton, SIGNAL( clicked() ), this, SLOT( accept() ) ); + + QHBoxLayout *buttonLayout = new QHBoxLayout; + buttonLayout->addStretch( 1 ); + buttonLayout->addWidget( closeButton ); + + QVBoxLayout *mainLayout = new QVBoxLayout; + mainLayout->addWidget( tabWidget ); + mainLayout->addLayout( buttonLayout ); + setLayout( mainLayout ); +} + diff --git a/ThirdParty/Qwt/designer/qwt_designer_plotdialog.h b/ThirdParty/Qwt/designer/qwt_designer_plotdialog.h new file mode 100644 index 0000000000..82f7f02ce9 --- /dev/null +++ b/ThirdParty/Qwt/designer/qwt_designer_plotdialog.h @@ -0,0 +1,31 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#ifndef QWT_DESIGNER_PLOTDIALOG_H +#define QWT_DESIGNER_PLOTDIALOG_H + +#include <QDialog> + +namespace QwtDesignerPlugin +{ + + class PlotDialog: public QDialog + { + Q_OBJECT + + public: + PlotDialog( const QString &properties, QWidget *parent = NULL ); + + Q_SIGNALS: + void edited( const QString& ); + }; + +} + +#endif diff --git a/ThirdParty/Qwt/designer/qwt_designer_plugin.cpp b/ThirdParty/Qwt/designer/qwt_designer_plugin.cpp new file mode 100644 index 0000000000..f46a11fa44 --- /dev/null +++ b/ThirdParty/Qwt/designer/qwt_designer_plugin.cpp @@ -0,0 +1,570 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#if defined(_MSC_VER) /* MSVC Compiler */ +#pragma warning ( disable : 4786 ) +#endif + +#include <qglobal.h> +#include <qaction.h> +#include <QtPlugin> +#include <QDesignerFormEditorInterface> +#include <QDesignerFormWindowInterface> +#include <QDesignerFormWindowCursorInterface> +#include <QExtensionManager> +#include <QErrorMessage> + +#include "qwt_designer_plugin.h" + +#ifndef NO_QWT_PLOT +#include "qwt_designer_plotdialog.h" +#include "qwt_plot.h" +#include "qwt_plot_canvas.h" +#include "qwt_scale_widget.h" +#endif + +#ifndef NO_QWT_WIDGETS +#include "qwt_counter.h" +#include "qwt_wheel.h" +#include "qwt_thermo.h" +#include "qwt_knob.h" +#include "qwt_slider.h" +#include "qwt_dial.h" +#include "qwt_dial_needle.h" +#include "qwt_analog_clock.h" +#include "qwt_compass.h" +#endif + +#include "qwt_text_label.h" + +using namespace QwtDesignerPlugin; + +CustomWidgetInterface::CustomWidgetInterface( QObject *parent ): + QObject( parent ), + d_isInitialized( false ) +{ +} + +bool CustomWidgetInterface::isContainer() const +{ + return false; +} + +bool CustomWidgetInterface::isInitialized() const +{ + return d_isInitialized; +} + +QIcon CustomWidgetInterface::icon() const +{ + return d_icon; +} + +QString CustomWidgetInterface::codeTemplate() const +{ + return d_codeTemplate; +} + +QString CustomWidgetInterface::domXml() const +{ + return d_domXml; +} + +QString CustomWidgetInterface::group() const +{ + return "Qwt Widgets"; +} + +QString CustomWidgetInterface::includeFile() const +{ + return d_include; +} + +QString CustomWidgetInterface::name() const +{ + return d_name; +} + +QString CustomWidgetInterface::toolTip() const +{ + return d_toolTip; +} + +QString CustomWidgetInterface::whatsThis() const +{ + return d_whatsThis; +} + +void CustomWidgetInterface::initialize( + QDesignerFormEditorInterface *formEditor ) +{ + if ( d_isInitialized ) + return; + + QExtensionManager *manager = formEditor->extensionManager(); + if ( manager ) + { + manager->registerExtensions( new TaskMenuFactory( manager ), + Q_TYPEID( QDesignerTaskMenuExtension ) ); + } + + d_isInitialized = true; +} + +#ifndef NO_QWT_PLOT + +PlotInterface::PlotInterface( QObject *parent ): + CustomWidgetInterface( parent ) +{ + d_name = "QwtPlot"; + d_include = "qwt_plot.h"; + d_icon = QPixmap( ":/pixmaps/qwtplot.png" ); + d_domXml = + "<widget class=\"QwtPlot\" name=\"qwtPlot\">\n" + " <property name=\"geometry\">\n" + " <rect>\n" + " <x>0</x>\n" + " <y>0</y>\n" + " <width>400</width>\n" + " <height>200</height>\n" + " </rect>\n" + " </property>\n" + "</widget>\n"; +} + +QWidget *PlotInterface::createWidget( QWidget *parent ) +{ + return new QwtPlot( parent ); +} + + +PlotCanvasInterface::PlotCanvasInterface( QObject *parent ): + CustomWidgetInterface( parent ) +{ + d_name = "QwtPlotCanvas"; + d_include = "qwt_plot_canvas.h"; + d_icon = QPixmap( ":/pixmaps/qwtplot.png" ); + d_domXml = + "<widget class=\"QwtPlotCanvas\" name=\"qwtPlotCanvas\">\n" + " <property name=\"geometry\">\n" + " <rect>\n" + " <x>0</x>\n" + " <y>0</y>\n" + " <width>400</width>\n" + " <height>200</height>\n" + " </rect>\n" + " </property>\n" + "</widget>\n"; +} + +QWidget *PlotCanvasInterface::createWidget( QWidget *parent ) +{ + return new QwtPlotCanvas( qobject_cast<QwtPlot *>( parent ) ); +} + +#endif + +#ifndef NO_QWT_WIDGETS + +AnalogClockInterface::AnalogClockInterface( QObject *parent ): + CustomWidgetInterface( parent ) +{ + d_name = "QwtAnalogClock"; + d_include = "qwt_analog_clock.h"; + d_icon = QPixmap( ":/pixmaps/qwtanalogclock.png" ); + d_domXml = + "<widget class=\"QwtAnalogClock\" name=\"AnalogClock\">\n" + " <property name=\"geometry\">\n" + " <rect>\n" + " <x>0</x>\n" + " <y>0</y>\n" + " <width>200</width>\n" + " <height>200</height>\n" + " </rect>\n" + " </property>\n" + " <property name=\"lineWidth\">\n" + " <number>4</number>\n" + " </property>\n" + "</widget>\n"; +} + +QWidget *AnalogClockInterface::createWidget( QWidget *parent ) +{ + return new QwtAnalogClock( parent ); +} + +#endif + +#ifndef NO_QWT_WIDGETS + +CompassInterface::CompassInterface( QObject *parent ): + CustomWidgetInterface( parent ) +{ + d_name = "QwtCompass"; + d_include = "qwt_compass.h"; + d_icon = QPixmap( ":/pixmaps/qwtcompass.png" ); + d_domXml = + "<widget class=\"QwtCompass\" name=\"Compass\">\n" + " <property name=\"geometry\">\n" + " <rect>\n" + " <x>0</x>\n" + " <y>0</y>\n" + " <width>200</width>\n" + " <height>200</height>\n" + " </rect>\n" + " </property>\n" + " <property name=\"lineWidth\">\n" + " <number>4</number>\n" + " </property>\n" + "</widget>\n"; +} + +QWidget *CompassInterface::createWidget( QWidget *parent ) +{ + QwtCompass *compass = new QwtCompass( parent ); + compass->setNeedle( new QwtCompassMagnetNeedle( + QwtCompassMagnetNeedle::TriangleStyle, + compass->palette().color( QPalette::Mid ), + compass->palette().color( QPalette::Dark ) ) ); + + return compass; +} + +#endif + +#ifndef NO_QWT_WIDGETS + +CounterInterface::CounterInterface( QObject *parent ): + CustomWidgetInterface( parent ) +{ + d_name = "QwtCounter"; + d_include = "qwt_counter.h"; + d_icon = QPixmap( ":/pixmaps/qwtcounter.png" ); + d_domXml = + "<widget class=\"QwtCounter\" name=\"Counter\">\n" + "</widget>\n"; +} + +QWidget *CounterInterface::createWidget( QWidget *parent ) +{ + return new QwtCounter( parent ); +} + +#endif + +#ifndef NO_QWT_WIDGETS + +DialInterface::DialInterface( QObject *parent ): + CustomWidgetInterface( parent ) +{ + d_name = "QwtDial"; + d_include = "qwt_dial.h"; + d_icon = QPixmap( ":/pixmaps/qwtdial.png" ); + d_domXml = + "<widget class=\"QwtDial\" name=\"Dial\">\n" + " <property name=\"geometry\">\n" + " <rect>\n" + " <x>0</x>\n" + " <y>0</y>\n" + " <width>200</width>\n" + " <height>200</height>\n" + " </rect>\n" + " </property>\n" + " <property name=\"lineWidth\">\n" + " <number>4</number>\n" + " </property>\n" + "</widget>\n"; +} + +QWidget *DialInterface::createWidget( QWidget *parent ) +{ + QwtDial *dial = new QwtDial( parent ); + dial->setNeedle( new QwtDialSimpleNeedle( + QwtDialSimpleNeedle::Arrow, true, + dial->palette().color( QPalette::Dark ), + dial->palette().color( QPalette::Mid ) ) ); + + return dial; +} + +#endif + +#ifndef NO_QWT_WIDGETS + +KnobInterface::KnobInterface( QObject *parent ): + CustomWidgetInterface( parent ) +{ + d_name = "QwtKnob"; + d_include = "qwt_knob.h"; + d_icon = QPixmap( ":/pixmaps/qwtknob.png" ); + d_domXml = + "<widget class=\"QwtKnob\" name=\"Knob\">\n" + " <property name=\"geometry\">\n" + " <rect>\n" + " <x>0</x>\n" + " <y>0</y>\n" + " <width>150</width>\n" + " <height>150</height>\n" + " </rect>\n" + " </property>\n" + "</widget>\n"; +} + +QWidget *KnobInterface::createWidget( QWidget *parent ) +{ + return new QwtKnob( parent ); +} + +#endif + +#ifndef NO_QWT_PLOT + +ScaleWidgetInterface::ScaleWidgetInterface( QObject *parent ): + CustomWidgetInterface( parent ) +{ + d_name = "QwtScaleWidget"; + d_include = "qwt_scale_widget.h"; + d_icon = QPixmap( ":/pixmaps/qwtscale.png" ); + d_domXml = + "<widget class=\"QwtScaleWidget\" name=\"ScaleWidget\">\n" + " <property name=\"geometry\">\n" + " <rect>\n" + " <x>0</x>\n" + " <y>0</y>\n" + " <width>60</width>\n" + " <height>250</height>\n" + " </rect>\n" + " </property>\n" + "</widget>\n"; +} + +QWidget *ScaleWidgetInterface::createWidget( QWidget *parent ) +{ + return new QwtScaleWidget( QwtScaleDraw::LeftScale, parent ); +} + +#endif + +#ifndef NO_QWT_WIDGETS + +SliderInterface::SliderInterface( QObject *parent ): + CustomWidgetInterface( parent ) +{ + d_name = "QwtSlider"; + d_include = "qwt_slider.h"; + d_icon = QPixmap( ":/pixmaps/qwtslider.png" ); + d_domXml = + "<widget class=\"QwtSlider\" name=\"Slider\">\n" + " <property name=\"geometry\">\n" + " <rect>\n" + " <x>0</x>\n" + " <y>0</y>\n" + " <width>60</width>\n" + " <height>250</height>\n" + " </rect>\n" + " </property>\n" + "</widget>\n"; +} + +QWidget *SliderInterface::createWidget( QWidget *parent ) +{ + return new QwtSlider( parent ); +} + +#endif + +TextLabelInterface::TextLabelInterface( QObject *parent ): + CustomWidgetInterface( parent ) +{ + d_name = "QwtTextLabel"; + d_include = "qwt_text_label.h"; + + d_icon = QPixmap( ":/pixmaps/qwtwidget.png" ); + d_domXml = + "<widget class=\"QwtTextLabel\" name=\"TextLabel\">\n" + " <property name=\"geometry\">\n" + " <rect>\n" + " <x>0</x>\n" + " <y>0</y>\n" + " <width>100</width>\n" + " <height>20</height>\n" + " </rect>\n" + " </property>\n" + "</widget>\n"; +} + +QWidget *TextLabelInterface::createWidget( QWidget *parent ) +{ + return new QwtTextLabel( QwtText( "Label" ), parent ); +} + +#ifndef NO_QWT_WIDGETS + +ThermoInterface::ThermoInterface( QObject *parent ): + CustomWidgetInterface( parent ) +{ + d_name = "QwtThermo"; + d_include = "qwt_thermo.h"; + d_icon = QPixmap( ":/pixmaps/qwtthermo.png" ); + d_domXml = + "<widget class=\"QwtThermo\" name=\"Thermo\">\n" + " <property name=\"geometry\">\n" + " <rect>\n" + " <x>0</x>\n" + " <y>0</y>\n" + " <width>60</width>\n" + " <height>250</height>\n" + " </rect>\n" + " </property>\n" + "</widget>\n"; +} + +QWidget *ThermoInterface::createWidget( QWidget *parent ) +{ + return new QwtThermo( parent ); +} + +#endif + +#ifndef NO_QWT_WIDGETS + +WheelInterface::WheelInterface( QObject *parent ): + CustomWidgetInterface( parent ) +{ + d_name = "QwtWheel"; + d_include = "qwt_wheel.h"; + d_icon = QPixmap( ":/pixmaps/qwtwheel.png" ); + d_domXml = + "<widget class=\"QwtWheel\" name=\"Wheel\">\n" + "</widget>\n"; +} + +QWidget *WheelInterface::createWidget( QWidget *parent ) +{ + return new QwtWheel( parent ); +} + +#endif + +CustomWidgetCollectionInterface::CustomWidgetCollectionInterface( + QObject *parent ): + QObject( parent ) +{ +#ifndef NO_QWT_PLOT + d_plugins.append( new PlotInterface( this ) ); + +#if 0 + // better not: the designer crashes TODO .. + d_plugins.append( new PlotCanvasInterface( this ) ); +#endif + + d_plugins.append( new ScaleWidgetInterface( this ) ); +#endif + +#ifndef NO_QWT_WIDGETS + d_plugins.append( new AnalogClockInterface( this ) ); + d_plugins.append( new CompassInterface( this ) ); + d_plugins.append( new CounterInterface( this ) ); + d_plugins.append( new DialInterface( this ) ); + d_plugins.append( new KnobInterface( this ) ); + d_plugins.append( new SliderInterface( this ) ); + d_plugins.append( new ThermoInterface( this ) ); + d_plugins.append( new WheelInterface( this ) ); +#endif + + d_plugins.append( new TextLabelInterface( this ) ); +} + +QList<QDesignerCustomWidgetInterface*> +CustomWidgetCollectionInterface::customWidgets( void ) const +{ + return d_plugins; +} + +TaskMenuFactory::TaskMenuFactory( QExtensionManager *parent ): + QExtensionFactory( parent ) +{ +} + +QObject *TaskMenuFactory::createExtension( + QObject *object, const QString &iid, QObject *parent ) const +{ + if ( iid == Q_TYPEID( QDesignerTaskMenuExtension ) ) + { +#ifndef NO_QWT_PLOT + if ( QwtPlot *plot = qobject_cast<QwtPlot*>( object ) ) + return new TaskMenuExtension( plot, parent ); +#endif +#ifndef NO_QWT_WIDGETS + if ( QwtDial *dial = qobject_cast<QwtDial*>( object ) ) + return new TaskMenuExtension( dial, parent ); +#endif + } + + return QExtensionFactory::createExtension( object, iid, parent ); +} + + +TaskMenuExtension::TaskMenuExtension( QWidget *widget, QObject *parent ): + QObject( parent ), + d_widget( widget ) +{ + d_editAction = new QAction( tr( "Edit Qwt Attributes ..." ), this ); + connect( d_editAction, SIGNAL( triggered() ), + this, SLOT( editProperties() ) ); +} + +QList<QAction *> TaskMenuExtension::taskActions() const +{ + QList<QAction *> list; + list.append( d_editAction ); + return list; +} + +QAction *TaskMenuExtension::preferredEditAction() const +{ + return d_editAction; +} + +void TaskMenuExtension::editProperties() +{ + const QVariant v = d_widget->property( "propertiesDocument" ); + if ( v.type() != QVariant::String ) + return; + +#ifndef NO_QWT_PLOT + QString properties = v.toString(); + + if ( qobject_cast<QwtPlot*>( d_widget ) ) + { + PlotDialog dialog( properties ); + connect( &dialog, SIGNAL( edited( const QString& ) ), + SLOT( applyProperties( const QString & ) ) ); + ( void )dialog.exec(); + return; + } +#endif + + static QErrorMessage *errorMessage = NULL; + if ( errorMessage == NULL ) + errorMessage = new QErrorMessage(); + errorMessage->showMessage( "Not implemented yet." ); +} + +void TaskMenuExtension::applyProperties( const QString &properties ) +{ + QDesignerFormWindowInterface *formWindow = + QDesignerFormWindowInterface::findFormWindow( d_widget ); + if ( formWindow && formWindow->cursor() ) + formWindow->cursor()->setProperty( "propertiesDocument", properties ); +} + +#if QT_VERSION < 0x050000 +Q_EXPORT_PLUGIN2( QwtDesignerPlugin, CustomWidgetCollectionInterface ) +#endif diff --git a/ThirdParty/Qwt/designer/qwt_designer_plugin.h b/ThirdParty/Qwt/designer/qwt_designer_plugin.h new file mode 100644 index 0000000000..c24e656008 --- /dev/null +++ b/ThirdParty/Qwt/designer/qwt_designer_plugin.h @@ -0,0 +1,248 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#ifndef QWT_DESIGNER_PLUGIN_H +#define QWT_DESIGNER_PLUGIN_H + +#include <QDesignerCustomWidgetInterface> +#include <QDesignerTaskMenuExtension> +#include <QExtensionFactory> + +namespace QwtDesignerPlugin +{ + class CustomWidgetInterface: public QObject, + public QDesignerCustomWidgetInterface + { + Q_OBJECT + Q_INTERFACES( QDesignerCustomWidgetInterface ) + + public: + CustomWidgetInterface( QObject *parent ); + + virtual bool isContainer() const; + virtual bool isInitialized() const; + virtual QIcon icon() const; + virtual QString codeTemplate() const; + virtual QString domXml() const; + virtual QString group() const; + virtual QString includeFile() const; + virtual QString name() const; + virtual QString toolTip() const; + virtual QString whatsThis() const; + virtual void initialize( QDesignerFormEditorInterface * ); + + protected: + QString d_name; + QString d_include; + QString d_toolTip; + QString d_whatsThis; + QString d_domXml; + QString d_codeTemplate; + QIcon d_icon; + + private: + bool d_isInitialized; + }; + + class CustomWidgetCollectionInterface: public QObject, + public QDesignerCustomWidgetCollectionInterface + { + Q_OBJECT + Q_INTERFACES( QDesignerCustomWidgetCollectionInterface ) + +#if QT_VERSION >= 0x050000 + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QDesignerCustomWidgetCollectionInterface" ) +#endif + + + public: + CustomWidgetCollectionInterface( QObject *parent = NULL ); + + virtual QList<QDesignerCustomWidgetInterface*> customWidgets() const; + + private: + QList<QDesignerCustomWidgetInterface*> d_plugins; + }; + +#ifndef NO_QWT_PLOT + class PlotInterface: public CustomWidgetInterface + { + Q_OBJECT + Q_INTERFACES( QDesignerCustomWidgetInterface ) + + public: + PlotInterface( QObject *parent ); + virtual QWidget *createWidget( QWidget *parent ); + }; + + class PlotCanvasInterface: public CustomWidgetInterface + { + Q_OBJECT + Q_INTERFACES( QDesignerCustomWidgetInterface ) + + public: + PlotCanvasInterface( QObject *parent ); + virtual QWidget *createWidget( QWidget *parent ); + }; +#endif + +#ifndef NO_QWT_WIDGETS + class AnalogClockInterface: public CustomWidgetInterface + { + Q_OBJECT + Q_INTERFACES( QDesignerCustomWidgetInterface ) + + public: + AnalogClockInterface( QObject *parent ); + virtual QWidget *createWidget( QWidget *parent ); + }; +#endif + +#ifndef NO_QWT_WIDGETS + class CompassInterface: public CustomWidgetInterface + { + Q_OBJECT + Q_INTERFACES( QDesignerCustomWidgetInterface ) + + public: + CompassInterface( QObject *parent ); + virtual QWidget *createWidget( QWidget *parent ); + }; +#endif + +#ifndef NO_QWT_WIDGETS + class CounterInterface: public CustomWidgetInterface + { + Q_OBJECT + Q_INTERFACES( QDesignerCustomWidgetInterface ) + + public: + CounterInterface( QObject *parent ); + virtual QWidget *createWidget( QWidget *parent ); + }; +#endif + +#ifndef NO_QWT_WIDGETS + class DialInterface: public CustomWidgetInterface + { + Q_OBJECT + Q_INTERFACES( QDesignerCustomWidgetInterface ) + + public: + DialInterface( QObject *parent ); + virtual QWidget *createWidget( QWidget *parent ); + }; +#endif + +#ifndef NO_QWT_WIDGETS + class KnobInterface: public CustomWidgetInterface + { + Q_OBJECT + Q_INTERFACES( QDesignerCustomWidgetInterface ) + + public: + KnobInterface( QObject *parent ); + virtual QWidget *createWidget( QWidget *parent ); + }; +#endif + +#ifndef NO_QWT_PLOT + class ScaleWidgetInterface: public CustomWidgetInterface + { + Q_OBJECT + Q_INTERFACES( QDesignerCustomWidgetInterface ) + + public: + ScaleWidgetInterface( QObject *parent ); + virtual QWidget *createWidget( QWidget *parent ); + }; +#endif + +#ifndef NO_QWT_WIDGETS + class SliderInterface: public CustomWidgetInterface + { + Q_OBJECT + Q_INTERFACES( QDesignerCustomWidgetInterface ) + + public: + SliderInterface( QObject *parent ); + virtual QWidget *createWidget( QWidget *parent ); + }; +#endif + + class TextLabelInterface: public CustomWidgetInterface + { + Q_OBJECT + Q_INTERFACES( QDesignerCustomWidgetInterface ) + + public: + TextLabelInterface( QObject *parent ); + virtual QWidget *createWidget( QWidget *parent ); + }; + +#ifndef NO_QWT_WIDGETS + class ThermoInterface: public CustomWidgetInterface + { + Q_OBJECT + Q_INTERFACES( QDesignerCustomWidgetInterface ) + + public: + ThermoInterface( QObject *parent ); + virtual QWidget *createWidget( QWidget *parent ); + }; +#endif + +#ifndef NO_QWT_WIDGETS + class WheelInterface: public CustomWidgetInterface + { + Q_OBJECT + Q_INTERFACES( QDesignerCustomWidgetInterface ) + + public: + WheelInterface( QObject *parent ); + virtual QWidget *createWidget( QWidget *parent ); + }; +#endif + + class TaskMenuFactory: public QExtensionFactory + { + Q_OBJECT + + public: + TaskMenuFactory( QExtensionManager *parent = 0 ); + + protected: + QObject *createExtension( QObject *object, + const QString &iid, QObject *parent ) const; + }; + + class TaskMenuExtension: public QObject, + public QDesignerTaskMenuExtension + { + Q_OBJECT + Q_INTERFACES( QDesignerTaskMenuExtension ) + + public: + TaskMenuExtension( QWidget *widget, QObject *parent ); + + QAction *preferredEditAction() const; + QList<QAction *> taskActions() const; + + private Q_SLOTS: + void editProperties(); + void applyProperties( const QString & ); + + private: + QAction *d_editAction; + QWidget *d_widget; + }; + +}; + +#endif diff --git a/ThirdParty/Qwt/designer/qwt_designer_plugin.qrc b/ThirdParty/Qwt/designer/qwt_designer_plugin.qrc new file mode 100644 index 0000000000..01e4ffc8f0 --- /dev/null +++ b/ThirdParty/Qwt/designer/qwt_designer_plugin.qrc @@ -0,0 +1,15 @@ +<!DOCTYPE RCC><RCC version="1.0"> + <qresource> + <file>pixmaps/qwtplot.png</file> + <file>pixmaps/qwtanalogclock.png</file> + <file>pixmaps/qwtcounter.png</file> + <file>pixmaps/qwtcompass.png</file> + <file>pixmaps/qwtdial.png</file> + <file>pixmaps/qwtknob.png</file> + <file>pixmaps/qwtscale.png</file> + <file>pixmaps/qwtslider.png</file> + <file>pixmaps/qwtthermo.png</file> + <file>pixmaps/qwtwheel.png</file> + <file>pixmaps/qwtwidget.png</file> + </qresource> +</RCC> diff --git a/ThirdParty/Qwt/doc/Doxyfile b/ThirdParty/Qwt/doc/Doxyfile new file mode 100644 index 0000000000..d1e55dd67a --- /dev/null +++ b/ThirdParty/Qwt/doc/Doxyfile @@ -0,0 +1,1799 @@ +# Doxyfile 1.8.1 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project. +# +# All text after a hash (#) is considered a comment and will be ignored. +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" "). + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# http://www.gnu.org/software/libiconv for the list of possible encodings. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or sequence of words) that should +# identify the project. Note that if you do not use Doxywizard you need +# to put quotes around the project name if it contains spaces. + +PROJECT_NAME = "Qwt User's Guide" + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = $(QWTVERSION) + +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewer +# a quick idea about the purpose of the project. Keep the description short. + +PROJECT_BRIEF = + +# With the PROJECT_LOGO tag one can specify an logo or icon that is +# included in the documentation. The maximum height of the logo should not +# exceed 55 pixels and the maximum width should not exceed 200 pixels. +# Doxygen will copy the logo to the output directory. + +PROJECT_LOGO = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, +# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, +# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English +# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, +# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, +# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = NO + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful if your file system +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like regular Qt-style comments +# (thus requiring an explicit @brief command for a brief description.) + +JAVADOC_AUTOBRIEF = NO + +# If the QT_AUTOBRIEF tag is set to YES then Doxygen will +# interpret the first line (until the first dot) of a Qt-style +# comment as the brief description. If set to NO, the comments +# will behave just like regular Qt-style comments (thus requiring +# an explicit \brief command for a brief description.) + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 4 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# This tag can be used to specify a number of word-keyword mappings (TCL only). +# A mapping has the form "name=value". For example adding +# "class=itcl::class" will allow you to use the command class in the +# itcl::class meaning. + +TCL_SUBST = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for +# Java. For instance, namespaces will be presented as packages, qualified +# scopes will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources only. Doxygen will then generate output that is more tailored for +# Fortran. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for +# VHDL. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given extension. +# Doxygen has a built-in mapping, but you can override or extend it using this +# tag. The format is ext=language, where ext is a file extension, and language +# is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C, +# C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make +# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C +# (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions +# you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. + +EXTENSION_MAPPING = + +# If MARKDOWN_SUPPORT is enabled (the default) then doxygen pre-processes all +# comments according to the Markdown format, which allows for more readable +# documentation. See http://daringfireball.net/projects/markdown/ for details. +# The output of markdown processing is further processed by doxygen, so you +# can mix doxygen, HTML, and XML commands with Markdown formatting. +# Disable only in case of backward compatibilities issues. + +MARKDOWN_SUPPORT = YES + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also makes the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. +# Doxygen will parse them like normal C++ but will assume all classes use public +# instead of private inheritance when no explicit protection keyword is present. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate getter +# and setter methods for a property. Setting this option to YES (the default) +# will make doxygen replace the get and set methods by a property in the +# documentation. This will only work if the methods are indeed getting or +# setting a simple type. If this is not the case, or you want to show the +# methods anyway, you should set this option to NO. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and +# unions are shown inside the group in which they are included (e.g. using +# @ingroup) instead of on a separate page (for HTML and Man pages) or +# section (for LaTeX and RTF). + +INLINE_GROUPED_CLASSES = NO + +# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and +# unions with only public data fields will be shown inline in the documentation +# of the scope in which they are defined (i.e. file, namespace, or group +# documentation), provided this scope is documented. If set to NO (the default), +# structs, classes, and unions are shown on a separate page (for HTML and Man +# pages) or section (for LaTeX and RTF). + +INLINE_SIMPLE_STRUCTS = NO + +# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum +# is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically +# be useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. + +TYPEDEF_HIDES_STRUCT = NO + +# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to +# determine which symbols to keep in memory and which to flush to disk. +# When the cache is full, less often used symbols will be written to disk. +# For small to medium size projects (<1000 input files) the default value is +# probably good enough. For larger projects a too small cache size can cause +# doxygen to be busy swapping symbols to and from disk most of the time +# causing a significant performance penalty. +# If the system has enough physical memory increasing the cache will improve the +# performance by keeping more symbols in memory. Note that the value works on +# a logarithmic scale so increasing the size by one will roughly double the +# memory usage. The cache size is given by this formula: +# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, +# corresponding to a cache size of 2^16 = 65536 symbols. + +SYMBOL_CACHE_SIZE = 0 + +# Similar to the SYMBOL_CACHE_SIZE the size of the symbol lookup cache can be +# set using LOOKUP_CACHE_SIZE. This cache is used to resolve symbols given +# their name and scope. Since this can be an expensive process and often the +# same symbol appear multiple times in the code, doxygen keeps a cache of +# pre-resolved symbols. If the cache is too small doxygen will become slower. +# If the cache is too large, memory is wasted. The cache size is given by this +# formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range is 0..9, the default is 0, +# corresponding to a cache size of 2^16 = 65536 symbols. + +LOOKUP_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = NO + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal scope will be included in the documentation. + +EXTRACT_PACKAGE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = NO + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base +# name of the file that contains the anonymous namespace. By default +# anonymous namespaces are hidden. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = NO + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen +# will list include files with double quotes in the documentation +# rather than with sharp brackets. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen +# will sort the (brief and detailed) documentation of class members so that +# constructors and destructors are listed first. If set to NO (the default) +# the constructors will appear in the respective orders defined by +# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. +# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO +# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. + +SORT_MEMBERS_CTORS_1ST = YES + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the +# hierarchy of group names into alphabetical order. If set to NO (the default) +# the group names will appear in their defined order. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to +# do proper type resolution of all parameters of a function it will reject a +# match between the prototype and the implementation of a member function even +# if there is only one candidate or it is obvious which candidate to choose +# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen +# will still accept a match between prototype and implementation in such cases. + +STRICT_PROTO_MATCHING = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = NO + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = NO + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = NO + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or macro consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and macros in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = NO + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. +# This will remove the Files entry from the Quick Index and from the +# Folder Tree View (if specified). The default is YES. + +SHOW_FILES = NO + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the +# Namespaces page. +# This will remove the Namespaces entry from the Quick Index +# and from the Folder Tree View (if specified). The default is YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command <command> <input-file>, where <command> is the value of +# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. The create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. +# You can optionally specify a file name after the option, if omitted +# DoxygenLayout.xml will be used as the name of the layout file. + +LAYOUT_FILE = + +# The CITE_BIB_FILES tag can be used to specify one or more bib files +# containing the references data. This must be a list of .bib files. The +# .bib extension is automatically appended if omitted. Using this command +# requires the bibtex tool to be installed. See also +# http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style +# of the bibliography can be controlled using LATEX_BIB_STYLE. To use this +# feature you need bibtex and perl available in the search path. + +CITE_BIB_FILES = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = YES + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# The WARN_NO_PARAMDOC option can be enabled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = YES + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = Doxygen.log + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = . \ + ../src \ + ../textengines/mathml + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is +# also the default input encoding. Doxygen uses libiconv (or the iconv built +# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for +# the list of possible encodings. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh +# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py +# *.f90 *.f *.for *.vhd *.vhdl + +FILE_PATTERNS = + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = NO + +# The EXCLUDE tag can be used to specify files and/or directories that should be +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. +# Note that relative paths are relative to the directory from which doxygen is +# run. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = qwt.h + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test + +EXCLUDE_SYMBOLS = \ + QwtMathMLDocument \ + QwtPainterCommand::PixmapData \ + QwtPainterCommand::ImageData \ + QwtPainterCommand::StateData + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = . + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = images + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command <filter> <input-file>, where <filter> +# is the value of the INPUT_FILTER tag, and <input-file> is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. +# If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. +# Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. +# The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty or if +# non of the patterns match the file name, INPUT_FILTER is applied. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) +# and it is also possible to disable source filtering for a specific pattern +# using *.ext= (so without naming a filter). This option only has effect when +# FILTER_SOURCE_FILES is enabled. + +FILTER_SOURCE_PATTERNS = + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = NO + +# If the REFERENCES_RELATION tag is set to YES +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = NO + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. +# Otherwise they will link to the documentation. + +REFERENCES_LINK_SOURCE = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = YES + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = Qwt \ + Q + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. Note that when using a custom header you are responsible +# for the proper inclusion of any scripts and style sheets that doxygen +# needs, which is dependent on the configuration options used. +# It is advised to generate a default header using "doxygen -w html +# header.html footer.html stylesheet.css YourConfigFile" and then modify +# that header. Note that the header is subject to change so you typically +# have to redo this when upgrading to a newer version of doxygen or when +# changing the value of configuration settings such as GENERATE_TREEVIEW! + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# style sheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the HTML output directory. Note +# that these files will be copied to the base HTML output directory. Use the +# $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +# files. In the HTML_STYLESHEET file, use the file name only. Also note that +# the files will be copied as-is; there are no commands or markers available. + +HTML_EXTRA_FILES = + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. +# Doxygen will adjust the colors in the style sheet and background images +# according to this color. Hue is specified as an angle on a colorwheel, +# see http://en.wikipedia.org/wiki/Hue for more information. +# For instance the value 0 represents red, 60 is yellow, 120 is green, +# 180 is cyan, 240 is blue, 300 purple, and 360 is red again. +# The allowed range is 0 to 359. + +HTML_COLORSTYLE_HUE = 220 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of +# the colors in the HTML output. For a value of 0 the output will use +# grayscales only. A value of 255 will produce the most vivid colors. + +HTML_COLORSTYLE_SAT = 100 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to +# the luminance component of the colors in the HTML output. Values below +# 100 gradually make the output lighter, whereas values above 100 make +# the output darker. The value divided by 100 is the actual gamma applied, +# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, +# and 100 does not change the gamma. + +HTML_COLORSTYLE_GAMMA = 80 + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting +# this to NO can help when comparing the output of multiple runs. + +HTML_TIMESTAMP = NO + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. + +HTML_DYNAMIC_SECTIONS = NO + +# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of +# entries shown in the various tree structured indices initially; the user +# can expand and collapse entries dynamically later on. Doxygen will expand +# the tree to such a level that at most the specified number of entries are +# visible (unless a fully collapsed tree already exceeds this amount). +# So setting the number of entries 1 will produce a full collapsed tree by +# default. 0 is a special value representing an infinite number of entries +# and will result in a full expanded tree by default. + +HTML_INDEX_NUM_ENTRIES = 100 + +# If the GENERATE_DOCSET tag is set to YES, additional index files +# will be generated that can be used as input for Apple's Xcode 3 +# integrated development environment, introduced with OSX 10.5 (Leopard). +# To create a documentation set, doxygen will generate a Makefile in the +# HTML output directory. Running make will produce the docset in that +# directory and running "make install" will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find +# it at startup. +# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html +# for more information. + +GENERATE_DOCSET = NO + +# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the +# feed. A documentation feed provides an umbrella under which multiple +# documentation sets from a single provider (such as a company or product suite) +# can be grouped. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that +# should uniquely identify the documentation set bundle. This should be a +# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen +# will append .docset to the name. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify +# the documentation publisher. This should be a reverse domain-name style +# string, e.g. com.mycompany.MyDocSet.documentation. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. + +DOCSET_PUBLISHER_NAME = Publisher + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING +# is used to encode HtmlHelp index (hhk), content (hhc) and project file +# content. + +CHM_INDEX_ENCODING = + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated +# that can be used as input for Qt's qhelpgenerator to generate a +# Qt Compressed Help (.qch) of the generated HTML documentation. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can +# be used to specify the file name of the resulting .qch file. +# The path specified is relative to the HTML output folder. + +QCH_FILE = qwtdoc.qch + +# The QHP_NAMESPACE tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#namespace + +QHP_NAMESPACE = net.sourceforge.qwt-svn + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#virtual-folders + +QHP_VIRTUAL_FOLDER = qwt-svn + +# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to +# add. For more information please see +# http://doc.trolltech.com/qthelpproject.html#custom-filters + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see +# <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters"> +# Qt Help Project / Custom Filters</a>. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's +# filter section matches. +# <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes"> +# Qt Help Project / Filter Attributes</a>. + +QHP_SECT_FILTER_ATTRS = + +# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can +# be used to specify the location of Qt's qhelpgenerator. +# If non-empty doxygen will try to run qhelpgenerator on the generated +# .qhp file. + +QHG_LOCATION = qhelpgenerator + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files +# will be generated, which together with the HTML files, form an Eclipse help +# plugin. To install this plugin and make it available under the help contents +# menu in Eclipse, the contents of the directory containing the HTML and XML +# files needs to be copied into the plugins directory of eclipse. The name of +# the directory within the plugins directory should be the same as +# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before +# the help appears. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have +# this name. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) +# at top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. Since the tabs have the same information as the +# navigation tree you can set this option to NO if you already set +# GENERATE_TREEVIEW to YES. + +DISABLE_INDEX = NO + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. +# If the tag value is set to YES, a side panel will be generated +# containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). +# Windows users are probably better off using the HTML help feature. +# Since the tree basically has the same information as the tab index you +# could consider to set DISABLE_INDEX to NO when enabling this option. + +GENERATE_TREEVIEW = NO + +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values +# (range [0,1..20]) that doxygen will group on one line in the generated HTML +# documentation. Note that a value of 0 will completely suppress the enum +# values from appearing in the overview section. + +ENUM_VALUES_PER_LINE = 4 + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open +# links to external symbols imported via tag files in a separate window. + +EXT_LINKS_IN_WINDOW = NO + +# Use this tag to change the font size of Latex formulas included +# as images in the HTML documentation. The default is 10. Note that +# when you change the font size after a successful doxygen run you need +# to manually remove any form_*.png images from the HTML output directory +# to force them to be regenerated. + +FORMULA_FONTSIZE = 10 + +# Use the FORMULA_TRANPARENT tag to determine whether or not the images +# generated for formulas are transparent PNGs. Transparent PNGs are +# not supported properly for IE 6.0, but are supported on all modern browsers. +# Note that when changing this option you need to delete any form_*.png files +# in the HTML output before the changes have effect. + +FORMULA_TRANSPARENT = YES + +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax +# (see http://www.mathjax.org) which uses client side Javascript for the +# rendering instead of using prerendered bitmaps. Use this if you do not +# have LaTeX installed or if you want to formulas look prettier in the HTML +# output. When enabled you may also need to install MathJax separately and +# configure the path to it using the MATHJAX_RELPATH option. + +USE_MATHJAX = NO + +# When MathJax is enabled you need to specify the location relative to the +# HTML output directory using the MATHJAX_RELPATH option. The destination +# directory should contain the MathJax.js script. For instance, if the mathjax +# directory is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to +# the MathJax Content Delivery Network so you can quickly see the result without +# installing MathJax. +# However, it is strongly recommended to install a local +# copy of MathJax from http://www.mathjax.org before deployment. + +MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest + +# The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension +# names that should be enabled during MathJax rendering. + +MATHJAX_EXTENSIONS = + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box +# for the HTML output. The underlying search engine uses javascript +# and DHTML and should work on any modern browser. Note that when using +# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets +# (GENERATE_DOCSET) there is already a search function so this one should +# typically be disabled. For large projects the javascript based search engine +# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. + +SEARCHENGINE = YES + +# When the SERVER_BASED_SEARCH tag is enabled the search engine will be +# implemented using a PHP enabled web server instead of at the web client +# using Javascript. Doxygen will generate the search PHP script and index +# file to put on the web server. The advantage of the server +# based approach is that it scales better to large projects and allows +# full text search. The disadvantages are that it is more difficult to setup +# and does not have live searching capabilities. + +SERVER_BASED_SEARCH = NO + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. +# Note that when enabling USE_PDFLATEX this option is only used for +# generating bitmaps for formulas in the HTML output, but not in the +# Makefile that is written to the output directory. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = YES + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4wide + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for +# the generated latex document. The footer should contain everything after +# the last chapter. If it is left blank doxygen will generate a +# standard footer. Notice: only use this tag if you know what you are doing! + +LATEX_FOOTER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = YES + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = YES + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +# If LATEX_SOURCE_CODE is set to YES then doxygen will include +# source code with syntax highlighting in the LaTeX output. +# Note that which sources are shown also depends on other settings +# such as SOURCE_BROWSER. + +LATEX_SOURCE_CODE = NO + +# The LATEX_BIB_STYLE tag can be used to specify the style to use for the +# bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See +# http://en.wikipedia.org/wiki/BibTeX for more info. + +LATEX_BIB_STYLE = plain + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load style sheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. +# This is useful +# if you want to understand what is going on. +# On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = YES + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = YES + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# pointed to by INCLUDE_PATH will be searched when a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = Q_PROPERTY(x)= + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition that +# overrules the definition found in the source code. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all references to function-like macros +# that are alone on a line, have an all uppercase name, and do not end with a +# semicolon, because these will confuse the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. For each +# tag file the location of the external documentation should be added. The +# format of a tag file without this location is as follows: +# +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths +# or URLs. Note that each tag file must have a unique name (where the name does +# NOT include the path). If a tag file is not located in the directory in which +# doxygen is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option also works with HAVE_DOT disabled, but it is recommended to +# install and use dot, since it yields more powerful graphs. + +CLASS_DIAGRAMS = YES + +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see +# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the +# documentation. The MSCGEN_PATH tag allows you to specify the directory where +# the mscgen tool resides. If left empty the tool is assumed to be found in the +# default search path. + +MSCGEN_PATH = + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = YES + +# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is +# allowed to run in parallel. When set to 0 (the default) doxygen will +# base this on the number of processors available in the system. You can set it +# explicitly to a value larger than 0 to get control over the balance +# between CPU load and processing speed. + +DOT_NUM_THREADS = 0 + +# By default doxygen will use the Helvetica font for all dot files that +# doxygen generates. When you want a differently looking font you can specify +# the font name using DOT_FONTNAME. You need to make sure dot is able to find +# the font, which can be done by putting it in a standard location or by setting +# the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the +# directory containing the font. + +DOT_FONTNAME = FreeSans + +# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. +# The default size is 10pt. + +DOT_FONTSIZE = 10 + +# By default doxygen will tell dot to use the Helvetica font. +# If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to +# set the path where dot can find it. + +DOT_FONTPATH = + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = NO + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If the UML_LOOK tag is enabled, the fields and methods are shown inside +# the class node. If there are many fields or methods and many nodes the +# graph may become too big to be useful. The UML_LIMIT_NUM_FIELDS +# threshold limits the number of items for each type to make the size more +# managable. Set this to 0 for no limit. Note that the threshold may be +# exceeded by 50% before the limit is enforced. + +UML_LIMIT_NUM_FIELDS = 10 + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = NO + +# If the CALL_GRAPH and HAVE_DOT options are set to YES then +# doxygen will generate a call dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable call graphs +# for selected functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then +# doxygen will generate a caller dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable caller +# graphs for selected functions only using the \callergraph command. + +CALLER_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will generate a graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are svg, png, jpg, or gif. +# If left blank png will be used. If you choose svg you need to set +# HTML_FILE_EXTENSION to xhtml in order to make the SVG files +# visible in IE 9+ (other browsers do not have this requirement). + +DOT_IMAGE_FORMAT = png + +# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to +# enable generation of interactive SVG images that allow zooming and panning. +# Note that this requires a modern browser other than Internet Explorer. +# Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you +# need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files +# visible. Older versions of IE do not have SVG support. + +INTERACTIVE_SVG = NO + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MSCFILE_DIRS tag can be used to specify one or more directories that +# contain msc files that are included in the documentation (see the +# \mscfile command). + +MSCFILE_DIRS = + +# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of +# nodes that will be shown in the graph. If the number of nodes in a graph +# becomes larger than this value, doxygen will truncate the graph, which is +# visualized by representing a node as a red box. Note that doxygen if the +# number of direct children of the root node in a graph is already larger than +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note +# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. + +DOT_GRAPH_MAX_NODES = 50 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that the size of a graph can be further restricted by +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, because dot on Windows does not +# seem to support this out of the box. Warning: Depending on the platform used, +# enabling this option may lead to badly anti-aliased labels on the edges of +# a graph (i.e. they become hard to read). + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES diff --git a/ThirdParty/Qwt/doc/articles/TODO b/ThirdParty/Qwt/doc/articles/TODO new file mode 100644 index 0000000000..373a767a56 --- /dev/null +++ b/ThirdParty/Qwt/doc/articles/TODO @@ -0,0 +1,8 @@ +1) Installation guides +2) QwtSeriesData + QAbstractModel +3) Navigation +4) Scales +5) Alive plots + sampling threads +6) Exporting + printing plots +7) Plot Items +8) Raster items diff --git a/ThirdParty/Qwt/doc/changes.dox b/ThirdParty/Qwt/doc/changes.dox new file mode 100644 index 0000000000..ee13a965f0 --- /dev/null +++ b/ThirdParty/Qwt/doc/changes.dox @@ -0,0 +1,306 @@ +/*! +\page qwtchangelog What's new in Qwt 6.1 + +\tableofcontents + +\section ITEMS New plot items + + - QwtPlotBarChart\n + Bar chart, see "examples/distrowatch" + + - QwtPlotMultiBarChart\n + Chart of grouped bars - stacked or aligned side by side. + See "examples/barchart" + + - QwtPlotTradingCurve\n + Candlestick or OHLC charts typically used to describe + price movements over time. See "examples/stockchart" + + - QwtPlotShapeItem\n + A plot item to display rectangles, circles, polygons and all + other type of shapes ( built from intersections or unifications ), + that can be expressed by a QPainterPath. See "examples/itemeditor" + + - QwtPlotLegendItem\n + A legend on the plot canvas. See "examples/legends" + + - QwtPlotZoneItem\n + A horizontal or vertical section + + - QwtPlotTextLabel\n + In opposite to a QwtPlotMarker the text is not aligned to a plot coordinate + but according to the geometry of the canvas ( f.e top/centered for a title ). + See "playground/curvetracker". + + +\section SCALES Scales beyond linear and logarithmic transformations + +QwtScaleTransformation has been replaced by QwtTransform and its derived classes: + + - QwtTransform + - QwtNullTransform + - QwtLogTransform + - QwtPowerTransform + +Individual transformations ( f.e. different scaling for special sections ) +can be implemented by overloading QwtTransform ( see playground/scaleengine ). + +QwtLinearScaleEngine and QwtLogScaleEngine are not limited to +base 10 anymore. + +\subsection DATETIME Datetime scales + +A set of a new classes for displaying datetime values: + + - QwtDate\n + A collection of methods to convert between QDateTime and doubles + + - QwtDateScaleEngine\n + A scale engine that aligns and finds ticks in terms of datetime units. + + - QwtDateScaleDraw\n + A scale draw mapping values to datetime strings. + +Scales for Qt::UTC and Qt::LocalTime are supported. + +\section CONTROLS Redesign of the dial and meter widgets + +Many parts of the class design of the dial and meter widgets were left over +from the 90s ( Qwt 0.2, Qt 1.1 ). + +The derivation tree is simpler and more logical: + + - QwtAbstractScale is a QWidget + - QwtAbstractSlider is a QwtAbstractScale. + ( for sliders without scales QAbstractSlider should be the base class ) + - QwtThermo is also a QwtAbstractScale + - QwtDial, QwtKnob, QwtSlider are derived from QwtAbstractSlider + - QwtCounter is derived from QWidget + +QwtDoubleRange has been removed. + +All classes use the terminology known from QAbstractSlider - as far as possible. +The extended \ref SCALES "system for scales" is completely supported. + +\section OPENGL Basic support for an OpenGL plot canvas + +QwtPlotGLCanvas offers the option to draw plot items using an +OpenGL paint engine ( QPaintEngine::OpenGL/OpenGL2 ), +This is not what could be implemented with native OpenGL, +but it offers hardware acceleration in environments, +where the raster paint engine is the only option. +( f.e Qt4/Windows, or Qt5 on all platforms ). + +QwtPlotGLCanvas is in an experimental state and is not recommended for average +use cases. + +\section LEGEND A new system for plot legends + +QwtLegend has been decoupled from QwtPlot and can be replaced by +application specific implementations. Plot items and the legend +exchange the information using QwtLegendData. + +QwtPlotLegendItem is a new plot item that displays a legend on the +plot canvas. + +The following examples demonstrate how to use the new system: + + - examples/legends\n + shows how to use the new legend system + - examples/stockchart\n + implementats a QTreeView with checkable items as legend + +\section GRAPHIC Off-screen paint device for vector graphics + +QwtGraphic can be copied like QImage or QPixmap but is scalable like QSvgGenerator. +It is implemented as a record/replay paint device like QPicture. + +\section OVERLAY QwtWidgetOverlay + +QwtWidgetOverlay is a base class for implementing widget overlays - primarily +used for use cases like graphical editors or running cursors for the plot canvas. + +The following examples show how to use overlays: + + - examples/itemeditor + - examples/curvetracker + +QwtPicker ( -> QwtPlotPicker, QwtPlotZoomer ) internally uses +QwtWidgetOverlay now, making it easier to implement individual rubber bands. + +\section SYMBOL QwtSymbol + +New symbol types have been introduced: + + - QwtSymbol::Path + - QwtSymbol::Pixmap + - QwtSymbol::Graphic + - QwtSymbol::SvgDocument + +QwtSymbol autodetect the most performant paint strategy for a paint device +what is in most situations using a QPixmap cache. + +QwtSymbol::setPinPoint() allows to align the symbol individually, f.e to the position +of the peak of an arrow. + +\section PLOTCURVE QwtPlotCurve + +Some optimizations that got lost with introducing the floating point +based render code with Qwt 6.0 have been reenabled. Other specific optimizations +have been added. + +New paint attributes: + + - QwtPlotCurve::FilterPoints + - QwtPlotCurve::MinimizeMemory + - QwtPlotCurve::ImageBuffer + +QwtPlotCurve::CacheSymbols has been removed, as caching is implemented +in QwtSymbol now. + +QwtPlotCurve::drawLines(), QwtPlotCurve::drawDots(), +QwtPlotCurve::drawSteps() and QwtPlotCurve::drawSticks() are virtual now. + +\section PLOT QwtPlot + +A footer similar to a title has been added. + +QwtPlot::ExternalLegend is obsolete with the +new \ref LEGEND "system for legends". The signals +QwtPlot::legendClicked(), QwtPlot::legendChecked() have been +removed. Applications need to connect to QwtLegend::clicked() +and QwtLegend::checked(). + +To support using an OpenGL canvas QwtPlot::setCanvas has been added. +This has 2 important implications for the application code: + + - QwtPlot::canvas() returns QWidget and needs to be casted, when + using methods of QwtPlotCanvas. + - QwtPlotCanvas can be created and assigned in application code, + what makes it possible to derive and overload methods. + +The initialization of a plot canvas with Qwt 6.1 will probably look like +this: + +\code + QwtPlotCanvas* canvas = new QwtPlotCanvas(); + canvas->setXY( ... ); + ... + + plot->setCanvas( canvas ); +\endcode + +To have a consistent API QwtPlot::setPlotLayout() has been added, + + +\section OTHER Other + +\subsection SCALEDIV QwtScaleDiv + +The following methods have been added: + + - QwtScaleDiv::inverted() + - QwtScaleDiv::bounded() + - QwtScaleDiv::isEmpty() + - QwtScaleDiv::isIncreasing() + - QDebug operator + +The following methods have been removed: + + - QwtScaleDiv::isValid(), QwtScaleDiv::invalidate()\n + The valid state was left over from early Qwt versions indicating + a state of the autoscaler. + +\subsection SCALEENGINE QwtScaleEngine + +The following methods have been added: + + - QwtScaleEngine::setBase() + - QwtScaleEngine::setTransformation() + +\subsection PLOTLAYOUT QwtPlotLayout + +The following flags have been added: + + - QwtPlotLayout::IgnoreTitle + - QwtPlotLayout::IgnoreFooter + - QwtPlotLayout::setAlignCanvasToScale() + +\subsection PLOTCANVAS QwtPlotCanvas + +Rounded borders ( like with style sheets ) can configured +using QwtPlotCanvas::setBorderRadius(); + +\subsection OTHERS Other changes + + - QwtWeedingCurveFitter\n + QwtWeedingCurveFitter::setChunkSize() has been added, with drastic + performance improvements for huge sets of points. + + - QwtPlotRenderer + The frame of the plot canvas can be rendered, what makes the result + even closer to WYSWYG. QwtPlotRenderer::exportTo() has been added. + + - QwtSystemClock + For Qt >= 4.9 QwtSystemClock uses QElapsedTimer internally. As it doesn't + support a similar feature, QwtSystemClock::precision() has been removed. + + - QwtPlotAbstractSeriesItem\n + QwtPlotAbstractSeriesItem has been split into QwtPlotSeriesItem + and QwtPlotAbstractSeriesStore. + + - QwtText\n + A metatype declaration has been added, so that QwtText can be used + with QVariant. + + - QwtEventPattern, QwtPanner, QwtMagnifier\n + Forgotten Qt3 leftovers have been fixed: int -> Qt::KeyboardModifiers + + - QPen Qt5/Qt4 incompatibility + The default pen width for Qt5 is 1, what makes it a non cosmetic. + To hide this nasty incompatibility several setPen() methods have been added + the build pens with a width 0. See QPen::isCosmetic(), + + - qwtUpperSampleIndex()\n + A binary search algorithm for sorted samples + + - QwtMatrixRasterData + QwtMatrixRasterData::setValue() has been added + + - QwtPicker + QwtPicker::rubberBandWidget(), QwtPicker::trackerWidget() have been replaced by + QwtPicker::rubberBandOverlay(), QwtPicker::trackerOverlay(). + QwtPicker::rubberBandMask() has been added. QwtPicker::pickRect() has been + replaced by QwtPicker::pickArea() + + - QwtPlotItem + QwtPlotItem::ItemInterest has been added. QwtPlotItem::setRenderThreadCount() + was shifted from QwtPlotRasterItem. + + - ... + +\section CLASSES Summary of the new classes + + - QwtAbstractLegend + - QwtDate + - QwtDateScaleDraw + - QwtDateScaleEngine + - QwtGraphic + - QwtLegendData + - QwtLegendLabel + - QwtPainterCommand + - QwtPixelMatrix + - QwtPlotAbstractBarChart + - QwtPlotBarChart + - QwtPlotMultiBarChart + - QwtPlotGLCanvas + - QwtPlotLegendItem + - QwtPlotShapeItem + - QwtPlotTextLabel + - QwtPlotTradingCurve + - QwtPlotZoneItem + - QwtPointData + - QwtPointMapper + - QwtTransform, QwtNullTransform, QwtLogTransform, QwtPowerTransform + - QwtWidgetOverlay +*/ diff --git a/ThirdParty/Qwt/doc/doc.pro b/ThirdParty/Qwt/doc/doc.pro new file mode 100644 index 0000000000..538d86dc04 --- /dev/null +++ b/ThirdParty/Qwt/doc/doc.pro @@ -0,0 +1,22 @@ +################################################################ +# Qwt Widget Library +# Copyright (C) 1997 Josef Wilgen +# Copyright (C) 2002 Uwe Rathmann +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the Qwt License, Version 1.0 +################################################################ + +# qmake project file for installing the documentation + +QWT_ROOT = $${PWD}/.. +include( $${QWT_ROOT}/qwtconfig.pri ) + +TEMPLATE = subdirs + +doc.files = $${QWT_ROOT}/doc/html +unix:doc.files += $${QWT_ROOT}/doc/man +doc.path = $${QWT_INSTALL_DOCS} + +INSTALLS = doc + diff --git a/ThirdParty/Qwt/doc/html/analogclock.png b/ThirdParty/Qwt/doc/html/analogclock.png new file mode 100644 index 0000000000..a4c5cc21a1 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/analogclock.png differ diff --git a/ThirdParty/Qwt/doc/html/annotated.html b/ThirdParty/Qwt/doc/html/annotated.html new file mode 100644 index 0000000000..56ddd9d209 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/annotated.html @@ -0,0 +1,234 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> +<meta http-equiv="X-UA-Compatible" content="IE=9"/> +<meta name="generator" content="Doxygen 1.8.3.1"/> +<title>Qwt User's Guide: Class List + + + + + + + + + +

+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + +
+ + + + +
+ +
+ +
+
+
Class List
+
+
+
Here are the classes, structs, unions and interfaces with brief descriptions:
+
[detail level 12]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
oCQwtAbstractLegendAbstract base class for legend widgets
oCQwtAbstractScaleAn abstract base class for widgets having a scale
oCQwtAbstractScaleDrawA abstract base class for drawing scales
oCQwtAbstractSeriesStoreBridge between QwtSeriesStore and QwtPlotSeriesItem
oCQwtAbstractSliderAn abstract base class for slider widgets with a scale
oCQwtAlphaColorMapQwtAlphaColorMap varies the alpha value of a color
oCQwtAnalogClockAn analog clock
oCQwtArraySeriesDataTemplate class for data, that is organized as QVector
oCQwtArrowButtonArrow Button
oCQwtClipperSome clipping algorithms
oCQwtColorMapQwtColorMap is used to map values into colors
oCQwtColumnRectDirected rectangle representing bounding rectangle and orientation of a column
oCQwtColumnSymbolA drawing primitive for columns
oCQwtCompassA Compass Widget
oCQwtCompassMagnetNeedleA magnet needle for compass widgets
oCQwtCompassRoseAbstract base class for a compass rose
oCQwtCompassScaleDrawA special scale draw made for QwtCompass
oCQwtCompassWindArrowAn indicator for the wind direction
oCQwtCounterThe Counter Widget
oCQwtCPointerDataData class containing two pointers to memory blocks of doubles
oCQwtCurveFitterAbstract base class for a curve fitter
oCQwtDateA collection of methods around date/time values
oCQwtDateScaleDrawA class for drawing datetime scales
oCQwtDateScaleEngineA scale engine for date/time values
oCQwtDialQwtDial class provides a rounded range control
oCQwtDialNeedleBase class for needles that can be used in a QwtDial
oCQwtDialSimpleNeedleA needle for dial widgets
oCQwtDynGridLayoutLays out widgets in a grid, adjusting the number of columns and rows to the current size
oCQwtEventPatternA collection of event patterns
oCQwtGraphicA paint device for scalable graphics
oCQwtIntervalA class representing an interval
oCQwtIntervalSampleA sample of the types (x1-x2, y) or (x, y1-y2)
oCQwtIntervalSeriesDataInterface for iterating over an array of intervals
oCQwtIntervalSymbolA drawing primitive for displaying an interval like an error bar
oCQwtKnobThe Knob Widget
oCQwtLegendThe legend widget
oCQwtLegendDataAttributes of an entry on a legend
oCQwtLegendLabelA widget representing something on a QwtLegend
oCQwtLinearColorMapQwtLinearColorMap builds a color map from color stops
oCQwtLinearScaleEngineA scale engine for linear scales
oCQwtLogScaleEngineA scale engine for logarithmic scales
oCQwtLogTransformLogarithmic transformation
oCQwtMagnifierQwtMagnifier provides zooming, by magnifying in steps
oCQwtMathMLTextEngineText Engine for the MathML renderer of the Qt solutions package
oCQwtMatrixRasterDataA class representing a matrix of values as raster data
oCQwtNullPaintDeviceA null paint device doing nothing
oCQwtNullTransformNull transformation
oCQwtOHLCSampleOpen-High-Low-Close sample used in financial charts
oCQwtPainterA collection of QPainter workarounds
oCQwtPainterCommand
oCQwtPannerQwtPanner provides panning of a widget
oCQwtPickerQwtPicker provides selections on a widget
oCQwtPickerClickPointMachineA state machine for point selections
oCQwtPickerClickRectMachineA state machine for rectangle selections
oCQwtPickerDragLineMachineA state machine for line selections
oCQwtPickerDragPointMachineA state machine for point selections
oCQwtPickerDragRectMachineA state machine for rectangle selections
oCQwtPickerMachineA state machine for QwtPicker selections
oCQwtPickerPolygonMachineA state machine for polygon selections
oCQwtPickerTrackerMachineA state machine for indicating mouse movements
oCQwtPixelMatrixA bit field corresponding to the pixels of a rectangle
oCQwtPlainTextEngineA text engine for plain texts
oCQwtPlotA 2-D plotting widget
oCQwtPlotAbstractBarChartAbstract base class for bar chart items
oCQwtPlotBarChartQwtPlotBarChart displays a series of a values as bars
oCQwtPlotCanvasCanvas of a QwtPlot
oCQwtPlotCurveA plot item, that represents a series of points
oCQwtPlotDictA dictionary for plot items
oCQwtPlotDirectPainterPainter object trying to paint incrementally
oCQwtPlotGLCanvasAn alternative canvas for a QwtPlot derived from QGLWidget
oCQwtPlotGridA class which draws a coordinate grid
oCQwtPlotHistogramQwtPlotHistogram represents a series of samples, where an interval is associated with a value ( $y = f([x1,x2])$ )
oCQwtPlotIntervalCurveQwtPlotIntervalCurve represents a series of samples, where each value is associated with an interval ( $[y1,y2] = f(x)$ )
oCQwtPlotItemBase class for items on the plot canvas
oCQwtPlotLayoutLayout engine for QwtPlot
oCQwtPlotLegendItemA class which draws a legend inside the plot canvas
oCQwtPlotMagnifierQwtPlotMagnifier provides zooming, by magnifying in steps
oCQwtPlotMarkerA class for drawing markers
oCQwtPlotMultiBarChartQwtPlotMultiBarChart displays a series of a samples that consist each of a set of values
oCQwtPlotPannerQwtPlotPanner provides panning of a plot canvas
oCQwtPlotPickerQwtPlotPicker provides selections on a plot canvas
oCQwtPlotRasterItemA class, which displays raster data
oCQwtPlotRendererRenderer for exporting a plot to a document, a printer or anything else, that is supported by QPainter/QPaintDevice
oCQwtPlotRescalerQwtPlotRescaler takes care of fixed aspect ratios for plot scales
oCQwtPlotScaleItemA class which draws a scale inside the plot canvas
oCQwtPlotSeriesItemBase class for plot items representing a series of samples
oCQwtPlotShapeItemA plot item, which displays any graphical shape, that can be defined by a QPainterPath
oCQwtPlotSpectroCurveCurve that displays 3D points as dots, where the z coordinate is mapped to a color
oCQwtPlotSpectrogramA plot item, which displays a spectrogram
oCQwtPlotSvgItemA plot item, which displays data in Scalable Vector Graphics (SVG) format
oCQwtPlotTextLabelA plot item, which displays a text label
oCQwtPlotTradingCurveQwtPlotTradingCurve illustrates movements in the price of a financial instrument over time
oCQwtPlotZoneItemA plot item, which displays a zone
oCQwtPlotZoomerQwtPlotZoomer provides stacked zooming for a plot widget
oCQwtPoint3DQwtPoint3D class defines a 3D point in double coordinates
oCQwtPoint3DSeriesDataInterface for iterating over an array of 3D points
oCQwtPointArrayDataInterface for iterating over two QVector<double> objects
oCQwtPointMapperA helper class for translating a series of points
oCQwtPointPolarA point in polar coordinates
oCQwtPointSeriesDataInterface for iterating over an array of points
oCQwtPowerTransformA transformation using pow()
oCQwtRasterDataQwtRasterData defines an interface to any type of raster data
oCQwtRichTextEngineA text engine for Qt rich texts
oCQwtRoundScaleDrawA class for drawing round scales
oCQwtSamplingThreadA thread collecting samples at regular intervals
oCQwtScaleArithmeticArithmetic including a tolerance
oCQwtScaleDivA class representing a scale division
oCQwtScaleDrawA class for drawing scales
oCQwtScaleEngineBase class for scale engines
oCQwtScaleMapA scale map
oCQwtScaleWidgetA Widget which contains a scale
oCQwtSeriesDataAbstract interface for iterating over samples
oCQwtSeriesStoreClass storing a QwtSeriesData object
oCQwtSetSampleA sample of the types (x1...xn, y) or (x, y1..yn)
oCQwtSetSeriesDataInterface for iterating over an array of samples
oCQwtSimpleCompassRoseA simple rose for QwtCompass
oCQwtSliderThe Slider Widget
oCQwtSplineA class for spline interpolation
oCQwtSplineCurveFitterA curve fitter using cubic splines
oCQwtSymbolA class for drawing symbols
oCQwtSyntheticPointDataSynthetic point data
oCQwtSystemClockQwtSystemClock provides high resolution clock time functions
oCQwtTextA class representing a text
oCQwtTextEngineAbstract base class for rendering text strings
oCQwtTextLabelA Widget which displays a QwtText
oCQwtThermoThe Thermometer Widget
oCQwtTradingChartData
oCQwtTransformA transformation between coordinate systems
oCQwtWeedingCurveFitterA curve fitter implementing Douglas and Peucker algorithm
oCQwtWheelThe Wheel Widget
\CQwtWidgetOverlayAn overlay for a widget
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/bc_s.png b/ThirdParty/Qwt/doc/html/bc_s.png new file mode 100644 index 0000000000..224b29aa98 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/bc_s.png differ diff --git a/ThirdParty/Qwt/doc/html/bdwn.png b/ThirdParty/Qwt/doc/html/bdwn.png new file mode 100644 index 0000000000..940a0b9504 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/bdwn.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_abstract_legend-members.html b/ThirdParty/Qwt/doc/html/class_qwt_abstract_legend-members.html new file mode 100644 index 0000000000..a3d4d1bcee --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_abstract_legend-members.html @@ -0,0 +1,106 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtAbstractLegend Member List
+
+
+ +

This is the complete list of members for QwtAbstractLegend, including all inherited members.

+ + + + + + + +
isEmpty() const =0QwtAbstractLegendpure virtual
QwtAbstractLegend(QWidget *parent=NULL)QwtAbstractLegendexplicit
renderLegend(QPainter *painter, const QRectF &rect, bool fillBackground) const =0QwtAbstractLegendpure virtual
scrollExtent(Qt::Orientation) const QwtAbstractLegendvirtual
updateLegend(const QVariant &itemInfo, const QList< QwtLegendData > &data)=0QwtAbstractLegendpure virtualslot
~QwtAbstractLegend()QwtAbstractLegendvirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_abstract_legend.html b/ThirdParty/Qwt/doc/html/class_qwt_abstract_legend.html new file mode 100644 index 0000000000..dd377bc497 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_abstract_legend.html @@ -0,0 +1,328 @@ + + + + + + +Qwt User's Guide: QwtAbstractLegend Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtAbstractLegend Class Referenceabstract
+
+
+ +

Abstract base class for legend widgets. + More...

+ +

#include <qwt_abstract_legend.h>

+
+Inheritance diagram for QwtAbstractLegend:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + +

+Public Slots

virtual void updateLegend (const QVariant &itemInfo, const QList< QwtLegendData > &data)=0
 Update the entries for a plot item. More...
 
+ + + + + + + + + + + + +

+Public Member Functions

 QwtAbstractLegend (QWidget *parent=NULL)
 
+virtual ~QwtAbstractLegend ()
 Destructor.
 
virtual void renderLegend (QPainter *painter, const QRectF &rect, bool fillBackground) const =0
 
virtual bool isEmpty () const =0
 
virtual int scrollExtent (Qt::Orientation) const
 
+

Detailed Description

+

Abstract base class for legend widgets.

+

Legends, that need to be under control of the QwtPlot layout system need to be derived from QwtAbstractLegend.

+
Note
Other type of legends can be implemented by connecting to the QwtPlot::legendDataChanged() signal. But as these legends are unknown to the plot layout system the layout code ( on screen and for QwtPlotRenderer ) need to be organized in application code.
+
See Also
QwtLegend
+

Constructor & Destructor Documentation

+ +
+
+ + + + + +
+ + + + + + + + +
QwtAbstractLegend::QwtAbstractLegend (QWidget * parent = NULL)
+
+explicit
+
+

Constructor

+
Parameters
+ + +
parentParent widget
+
+
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + +
virtual bool QwtAbstractLegend::isEmpty () const
+
+pure virtual
+
+
Returns
True, when no plot item is inserted
+ +

Implemented in QwtLegend.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
virtual void QwtAbstractLegend::renderLegend (QPainter * painter,
const QRectF & rect,
bool fillBackground 
) const
+
+pure virtual
+
+

Render the legend into a given rectangle.

+
Parameters
+ + + + +
painterPainter
rectBounding rectangle
fillBackgroundWhen true, fill rect with the widget background
+
+
+
See Also
renderLegend() is used by QwtPlotRenderer
+ +

Implemented in QwtLegend.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
int QwtAbstractLegend::scrollExtent (Qt::Orientation orientation) const
+
+virtual
+
+

Return the extent, that is needed for elements to scroll the legend ( usually scrollbars ),

+
Parameters
+ + +
orientationOrientation
+
+
+
Returns
Extent of the corresponding scroll element
+ +

Reimplemented in QwtLegend.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
virtual void QwtAbstractLegend::updateLegend (const QVariant & itemInfo,
const QList< QwtLegendData > & data 
)
+
+pure virtualslot
+
+ +

Update the entries for a plot item.

+
Parameters
+ + + +
itemInfoInfo about an item
dataList of legend entry attributes for the item
+
+
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_abstract_legend__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_abstract_legend__inherit__graph.map new file mode 100644 index 0000000000..dd08e4ee63 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_abstract_legend__inherit__graph.map @@ -0,0 +1,3 @@ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_abstract_legend__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_abstract_legend__inherit__graph.md5 new file mode 100644 index 0000000000..bcf1be9d9c --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_abstract_legend__inherit__graph.md5 @@ -0,0 +1 @@ +39d37a29ea51c617ddc88b24e921dd0e \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_abstract_legend__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_abstract_legend__inherit__graph.png new file mode 100644 index 0000000000..ff82ea6304 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_abstract_legend__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_abstract_scale-members.html b/ThirdParty/Qwt/doc/html/class_qwt_abstract_scale-members.html new file mode 100644 index 0000000000..092ead0f5c --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_abstract_scale-members.html @@ -0,0 +1,130 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtAbstractScale Member List
+
+
+ +

This is the complete list of members for QwtAbstractScale, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
abstractScaleDraw() const QwtAbstractScaleprotected
abstractScaleDraw()QwtAbstractScaleprotected
invTransform(int) const QwtAbstractScale
isInverted() const QwtAbstractScale
lowerBound() const QwtAbstractScale
maximum() const QwtAbstractScale
minimum() const QwtAbstractScale
QwtAbstractScale(QWidget *parent=NULL)QwtAbstractScale
rescale(double lowerBound, double upperBound, double stepSize)QwtAbstractScaleprotected
scaleChange()QwtAbstractScaleprotectedvirtual
scaleDiv() const QwtAbstractScale
scaleEngine() const QwtAbstractScale
scaleEngine()QwtAbstractScale
scaleMap() const QwtAbstractScale
scaleMaxMajor() const QwtAbstractScale
scaleMaxMinor() const QwtAbstractScale
scaleStepSize() const QwtAbstractScale
setAbstractScaleDraw(QwtAbstractScaleDraw *)QwtAbstractScaleprotected
setLowerBound(double value)QwtAbstractScale
setScale(double lowerBound, double upperBound)QwtAbstractScale
setScale(const QwtInterval &)QwtAbstractScale
setScale(const QwtScaleDiv &)QwtAbstractScale
setScaleEngine(QwtScaleEngine *)QwtAbstractScale
setScaleMaxMajor(int ticks)QwtAbstractScale
setScaleMaxMinor(int ticks)QwtAbstractScale
setScaleStepSize(double stepSize)QwtAbstractScale
setUpperBound(double value)QwtAbstractScale
transform(double) const QwtAbstractScale
upperBound() const QwtAbstractScale
~QwtAbstractScale()QwtAbstractScalevirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_abstract_scale.html b/ThirdParty/Qwt/doc/html/class_qwt_abstract_scale.html new file mode 100644 index 0000000000..15efc4a84d --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_abstract_scale.html @@ -0,0 +1,844 @@ + + + + + + +Qwt User's Guide: QwtAbstractScale Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtAbstractScale Class Reference
+
+
+ +

An abstract base class for widgets having a scale. + More...

+ +

#include <qwt_abstract_scale.h>

+
+Inheritance diagram for QwtAbstractScale:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 QwtAbstractScale (QWidget *parent=NULL)
 
+virtual ~QwtAbstractScale ()
 Destructor.
 
void setScale (double lowerBound, double upperBound)
 Specify a scale. More...
 
void setScale (const QwtInterval &)
 Specify a scale. More...
 
void setScale (const QwtScaleDiv &)
 Specify a scale. More...
 
const QwtScaleDivscaleDiv () const
 
void setLowerBound (double value)
 
double lowerBound () const
 
void setUpperBound (double value)
 
double upperBound () const
 
void setScaleStepSize (double stepSize)
 Set the step size used for calculating a scale division. More...
 
double scaleStepSize () const
 
void setScaleMaxMajor (int ticks)
 Set the maximum number of major tick intervals. More...
 
int scaleMaxMinor () const
 
void setScaleMaxMinor (int ticks)
 Set the maximum number of minor tick intervals. More...
 
int scaleMaxMajor () const
 
void setScaleEngine (QwtScaleEngine *)
 Set a scale engine. More...
 
const QwtScaleEnginescaleEngine () const
 
QwtScaleEnginescaleEngine ()
 
int transform (double) const
 
double invTransform (int) const
 
bool isInverted () const
 
double minimum () const
 
double maximum () const
 
const QwtScaleMapscaleMap () const
 
+ + + + + + + + + + + + + +

+Protected Member Functions

void rescale (double lowerBound, double upperBound, double stepSize)
 
void setAbstractScaleDraw (QwtAbstractScaleDraw *)
 Set a scale draw. More...
 
const QwtAbstractScaleDrawabstractScaleDraw () const
 
QwtAbstractScaleDrawabstractScaleDraw ()
 
+virtual void scaleChange ()
 Notify changed scale.
 
+

Detailed Description

+

An abstract base class for widgets having a scale.

+

The scale of an QwtAbstractScale is determined by a QwtScaleDiv definition, that contains the boundaries and the ticks of the scale. The scale is painted using a QwtScaleDraw object.

+

The scale division might be assigned explicitly - but usually it is calculated from the boundaries using a QwtScaleEngine.

+

The scale engine also decides the type of transformation of the scale ( linear, logarithmic ... ).

+

Constructor & Destructor Documentation

+ +
+
+ + + + + + + + +
QwtAbstractScale::QwtAbstractScale (QWidget * parent = NULL)
+
+

Constructor

+
Parameters
+ + +
parentParent widget
+
+
+

Creates a default QwtScaleDraw and a QwtLinearScaleEngine. The initial scale boundaries are set to [ 0.0, 100.0 ]

+

The scaleStepSize() is initialized to 0.0, scaleMaxMajor() to 5 and scaleMaxMajor to 3.

+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + +
const QwtAbstractScaleDraw * QwtAbstractScale::abstractScaleDraw () const
+
+protected
+
+
Returns
Scale draw
+
See Also
setAbstractScaleDraw()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
QwtAbstractScaleDraw * QwtAbstractScale::abstractScaleDraw ()
+
+protected
+
+
Returns
Scale draw
+
See Also
setAbstractScaleDraw()
+ +
+
+ +
+
+ + + + + + + + +
double QwtAbstractScale::invTransform (int value) const
+
+

Translate a widget coordinate into a scale value

+
Parameters
+ + +
valueWidget coordinate
+
+
+
Returns
Corresponding scale coordinate for value
+
See Also
scaleMap(), transform()
+ +
+
+ +
+
+ + + + + + + +
bool QwtAbstractScale::isInverted () const
+
+
Returns
True, when the scale is increasing in opposite direction to the widget coordinates
+ +
+
+ +
+
+ + + + + + + +
double QwtAbstractScale::lowerBound () const
+
+
Returns
Lower bound of the scale
+
See Also
setLowerBound(), setScale(), upperBound()
+ +
+
+ +
+
+ + + + + + + +
double QwtAbstractScale::maximum () const
+
+
Returns
The boundary with the larger value
+
See Also
minimum(), lowerBound(), upperBound()
+ +
+
+ +
+
+ + + + + + + +
double QwtAbstractScale::minimum () const
+
+
Returns
The boundary with the smaller value
+
See Also
maximum(), lowerBound(), upperBound()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
void QwtAbstractScale::rescale (double lowerBound,
double upperBound,
double stepSize 
)
+
+protected
+
+

Recalculate the scale division and update the scale.

+
Parameters
+ + + + +
lowerBoundLower limit of the scale interval
upperBoundUpper limit of the scale interval
stepSizeMajor step size
+
+
+
See Also
scaleChange()
+ +
+
+ +
+
+ + + + + + + +
const QwtScaleDiv & QwtAbstractScale::scaleDiv () const
+
+
Returns
Scale boundaries and positions of the ticks
+

The scale division might have been assigned explicitly or calculated implicitly by rescale().

+ +
+
+ +
+
+ + + + + + + +
const QwtScaleEngine * QwtAbstractScale::scaleEngine () const
+
+
Returns
Scale engine
+
See Also
setScaleEngine()
+ +
+
+ +
+
+ + + + + + + +
QwtScaleEngine * QwtAbstractScale::scaleEngine ()
+
+
Returns
Scale engine
+
See Also
setScaleEngine()
+ +
+
+ +
+
+ + + + + + + +
const QwtScaleMap & QwtAbstractScale::scaleMap () const
+
+
Returns
Map to translate between scale and widget coordinates
+ +
+
+ +
+
+ + + + + + + +
int QwtAbstractScale::scaleMaxMajor () const
+
+
Returns
Maximal number of major tick intervals
+
See Also
setScaleMaxMajor(), scaleMaxMinor()
+ +
+
+ +
+
+ + + + + + + +
int QwtAbstractScale::scaleMaxMinor () const
+
+
Returns
Maximal number of minor tick intervals
+
See Also
setScaleMaxMinor(), scaleMaxMajor()
+ +
+
+ +
+
+ + + + + + + +
double QwtAbstractScale::scaleStepSize () const
+
+
Returns
Hint for the step size of the scale
+
See Also
setScaleStepSize(), QwtScaleEngine::divideScale()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtAbstractScale::setAbstractScaleDraw (QwtAbstractScaleDrawscaleDraw)
+
+protected
+
+ +

Set a scale draw.

+

scaleDraw has to be created with new and will be deleted in the destructor or the next call of setAbstractScaleDraw().

+
See Also
abstractScaleDraw()
+ +
+
+ +
+
+ + + + + + + + +
void QwtAbstractScale::setLowerBound (double value)
+
+

Set the lower bound of the scale

+
Parameters
+ + +
valueLower bound
+
+
+
See Also
lowerBound(), setScale(), setUpperBound()
+
Note
For inverted scales the lower bound is greater than the upper bound
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtAbstractScale::setScale (double lowerBound,
double upperBound 
)
+
+ +

Specify a scale.

+

Define a scale by an interval

+

The ticks are calculated using scaleMaxMinor(), scaleMaxMajor() and scaleStepSize().

+
Parameters
+ + + +
lowerBoundlower limit of the scale interval
upperBoundupper limit of the scale interval
+
+
+
Note
For inverted scales the lower bound is greater than the upper bound
+ +
+
+ +
+
+ + + + + + + + +
void QwtAbstractScale::setScale (const QwtIntervalinterval)
+
+ +

Specify a scale.

+

Define a scale by an interval

+

The ticks are calculated using scaleMaxMinor(), scaleMaxMajor() and scaleStepSize().

+
Parameters
+ + +
intervalInterval
+
+
+ +
+
+ +
+
+ + + + + + + + +
void QwtAbstractScale::setScale (const QwtScaleDivscaleDiv)
+
+ +

Specify a scale.

+

scaleMaxMinor(), scaleMaxMajor() and scaleStepSize() and have no effect.

+
Parameters
+ + +
scaleDivScale division
+
+
+
See Also
setAutoScale()
+ +
+
+ +
+
+ + + + + + + + +
void QwtAbstractScale::setScaleEngine (QwtScaleEnginescaleEngine)
+
+ +

Set a scale engine.

+

The scale engine is responsible for calculating the scale division and provides a transformation between scale and widget coordinates.

+

scaleEngine has to be created with new and will be deleted in the destructor or the next call of setScaleEngine.

+ +
+
+ +
+
+ + + + + + + + +
void QwtAbstractScale::setScaleMaxMajor (int ticks)
+
+ +

Set the maximum number of major tick intervals.

+

The scale's major ticks are calculated automatically such that the number of major intervals does not exceed ticks.

+

The default value is 5.

+
Parameters
+ + +
ticksMaximal number of major ticks.
+
+
+
See Also
scaleMaxMajor(), setScaleMaxMinor(), setScaleStepSize(), QwtScaleEngine::divideInterval()
+ +
+
+ +
+
+ + + + + + + + +
void QwtAbstractScale::setScaleMaxMinor (int ticks)
+
+ +

Set the maximum number of minor tick intervals.

+

The scale's minor ticks are calculated automatically such that the number of minor intervals does not exceed ticks. The default value is 3.

+
Parameters
+ + +
ticksMaximal number of minor ticks.
+
+
+
See Also
scaleMaxMajor(), setScaleMaxMinor(), setScaleStepSize(), QwtScaleEngine::divideInterval()
+ +
+
+ +
+
+ + + + + + + + +
void QwtAbstractScale::setScaleStepSize (double stepSize)
+
+ +

Set the step size used for calculating a scale division.

+

The step size is hint for calculating the intervals for the major ticks of the scale. A value of 0.0 is interpreted as no hint.

+
Parameters
+ + +
stepSizeHint for the step size of the scale
+
+
+
See Also
scaleStepSize(), QwtScaleEngine::divideScale()
+
Note
Position and distance between the major ticks also depends on scaleMaxMajor().
+ +
+
+ +
+
+ + + + + + + + +
void QwtAbstractScale::setUpperBound (double value)
+
+

Set the upper bound of the scale

+
Parameters
+ + +
valueUpper bound
+
+
+
See Also
upperBound(), setScale(), setLowerBound()
+
Note
For inverted scales the lower bound is greater than the upper bound
+ +
+
+ +
+
+ + + + + + + + +
int QwtAbstractScale::transform (double value) const
+
+

Translate a scale value into a widget coordinate

+
Parameters
+ + +
valueScale value
+
+
+
Returns
Corresponding widget coordinate for value
+
See Also
scaleMap(), invTransform()
+ +
+
+ +
+
+ + + + + + + +
double QwtAbstractScale::upperBound () const
+
+
Returns
Upper bound of the scale
+
See Also
setUpperBound(), setScale(), lowerBound()
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_abstract_scale__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_abstract_scale__inherit__graph.map new file mode 100644 index 0000000000..876f658e28 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_abstract_scale__inherit__graph.map @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_abstract_scale__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_abstract_scale__inherit__graph.md5 new file mode 100644 index 0000000000..11d7c55a85 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_abstract_scale__inherit__graph.md5 @@ -0,0 +1 @@ +3b2e2f39bea5ad846e50370b0b75d083 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_abstract_scale__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_abstract_scale__inherit__graph.png new file mode 100644 index 0000000000..6e09ded424 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_abstract_scale__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_abstract_scale_draw-members.html b/ThirdParty/Qwt/doc/html/class_qwt_abstract_scale_draw-members.html new file mode 100644 index 0000000000..cad95b0745 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_abstract_scale_draw-members.html @@ -0,0 +1,131 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtAbstractScaleDraw Member List
+
+
+ +

This is the complete list of members for QwtAbstractScaleDraw, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Backbone enum valueQwtAbstractScaleDraw
draw(QPainter *, const QPalette &) const QwtAbstractScaleDrawvirtual
drawBackbone(QPainter *painter) const =0QwtAbstractScaleDrawprotectedpure virtual
drawLabel(QPainter *painter, double value) const =0QwtAbstractScaleDrawprotectedpure virtual
drawTick(QPainter *painter, double value, double len) const =0QwtAbstractScaleDrawprotectedpure virtual
enableComponent(ScaleComponent, bool enable=true)QwtAbstractScaleDraw
extent(const QFont &font) const =0QwtAbstractScaleDrawpure virtual
hasComponent(ScaleComponent) const QwtAbstractScaleDraw
invalidateCache()QwtAbstractScaleDrawprotected
label(double) const QwtAbstractScaleDrawvirtual
Labels enum valueQwtAbstractScaleDraw
maxTickLength() const QwtAbstractScaleDraw
minimumExtent() const QwtAbstractScaleDraw
penWidth() const QwtAbstractScaleDraw
QwtAbstractScaleDraw()QwtAbstractScaleDraw
ScaleComponent enum nameQwtAbstractScaleDraw
ScaleComponents typedefQwtAbstractScaleDraw
scaleDiv() const QwtAbstractScaleDraw
scaleMap() const QwtAbstractScaleDraw
scaleMap()QwtAbstractScaleDraw
setMinimumExtent(double)QwtAbstractScaleDraw
setPenWidth(int width)QwtAbstractScaleDraw
setScaleDiv(const QwtScaleDiv &s)QwtAbstractScaleDraw
setSpacing(double margin)QwtAbstractScaleDraw
setTickLength(QwtScaleDiv::TickType, double length)QwtAbstractScaleDraw
setTransformation(QwtTransform *)QwtAbstractScaleDraw
spacing() const QwtAbstractScaleDraw
tickLabel(const QFont &, double value) const QwtAbstractScaleDrawprotected
tickLength(QwtScaleDiv::TickType) const QwtAbstractScaleDraw
Ticks enum valueQwtAbstractScaleDraw
~QwtAbstractScaleDraw()QwtAbstractScaleDrawvirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_abstract_scale_draw.html b/ThirdParty/Qwt/doc/html/class_qwt_abstract_scale_draw.html new file mode 100644 index 0000000000..b69eac5df4 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_abstract_scale_draw.html @@ -0,0 +1,918 @@ + + + + + + +Qwt User's Guide: QwtAbstractScaleDraw Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtAbstractScaleDraw Class Referenceabstract
+
+
+ +

A abstract base class for drawing scales. + More...

+ +

#include <qwt_abstract_scale_draw.h>

+
+Inheritance diagram for QwtAbstractScaleDraw:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + +

+Public Types

enum  ScaleComponent { Backbone = 0x01, +Ticks = 0x02, +Labels = 0x04 + }
 
+typedef QFlags< ScaleComponentScaleComponents
 Scale components.
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 QwtAbstractScaleDraw ()
 Constructor. More...
 
+virtual ~QwtAbstractScaleDraw ()
 Destructor.
 
void setScaleDiv (const QwtScaleDiv &s)
 
const QwtScaleDivscaleDiv () const
 
void setTransformation (QwtTransform *)
 
const QwtScaleMapscaleMap () const
 
QwtScaleMapscaleMap ()
 
void enableComponent (ScaleComponent, bool enable=true)
 
bool hasComponent (ScaleComponent) const
 
void setTickLength (QwtScaleDiv::TickType, double length)
 
double tickLength (QwtScaleDiv::TickType) const
 
double maxTickLength () const
 
void setSpacing (double margin)
 Set the spacing between tick and labels. More...
 
double spacing () const
 Get the spacing. More...
 
void setPenWidth (int width)
 Specify the width of the scale pen. More...
 
int penWidth () const
 
virtual void draw (QPainter *, const QPalette &) const
 Draw the scale. More...
 
virtual QwtText label (double) const
 Convert a value into its representing label. More...
 
virtual double extent (const QFont &font) const =0
 
void setMinimumExtent (double)
 Set a minimum for the extent. More...
 
double minimumExtent () const
 
+ + + + + + + + + + + + +

+Protected Member Functions

virtual void drawTick (QPainter *painter, double value, double len) const =0
 
virtual void drawBackbone (QPainter *painter) const =0
 
virtual void drawLabel (QPainter *painter, double value) const =0
 
void invalidateCache ()
 
const QwtTexttickLabel (const QFont &, double value) const
 Convert a value into its representing label and cache it. More...
 
+

Detailed Description

+

A abstract base class for drawing scales.

+

QwtAbstractScaleDraw can be used to draw linear or logarithmic scales.

+

After a scale division has been specified as a QwtScaleDiv object using setScaleDiv(), the scale can be drawn with the draw() member.

+

Member Enumeration Documentation

+ +
+
+

Components of a scale

+
See Also
enableComponent(), hasComponent
+ + + + +
Enumerator
Backbone  +

Backbone = the line where the ticks are located.

+
Ticks  +

Ticks.

+
Labels  +

Labels.

+
+ +
+
+

Constructor & Destructor Documentation

+ +
+
+ + + + + + + +
QwtAbstractScaleDraw::QwtAbstractScaleDraw ()
+
+ +

Constructor.

+

The range of the scale is initialized to [0, 100], The spacing (distance between ticks and labels) is set to 4, the tick lengths are set to 4,6 and 8 pixels

+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void QwtAbstractScaleDraw::draw (QPainter * painter,
const QPalette & palette 
) const
+
+virtual
+
+ +

Draw the scale.

+
Parameters
+ + + +
painterThe painter
palettePalette, text color is used for the labels, foreground color for ticks and backbone
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
virtual void QwtAbstractScaleDraw::drawBackbone (QPainter * painter) const
+
+protectedpure virtual
+
+

Draws the baseline of the scale

+
Parameters
+ + +
painterPainter
+
+
+
See Also
drawTick(), drawLabel()
+ +

Implemented in QwtScaleDraw, and QwtRoundScaleDraw.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
virtual void QwtAbstractScaleDraw::drawLabel (QPainter * painter,
double value 
) const
+
+protectedpure virtual
+
+

Draws the label for a major scale tick

+
Parameters
+ + + +
painterPainter
valueValue
+
+
+
See Also
drawTick(), drawBackbone()
+ +

Implemented in QwtScaleDraw, and QwtRoundScaleDraw.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
virtual void QwtAbstractScaleDraw::drawTick (QPainter * painter,
double value,
double len 
) const
+
+protectedpure virtual
+
+

Draw a tick

+
Parameters
+ + + + +
painterPainter
valueValue of the tick
lenLength of the tick
+
+
+
See Also
drawBackbone(), drawLabel()
+ +

Implemented in QwtScaleDraw, and QwtRoundScaleDraw.

+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtAbstractScaleDraw::enableComponent (ScaleComponent component,
bool enable = true 
)
+
+

En/Disable a component of the scale

+
Parameters
+ + + +
componentScale component
enableOn/Off
+
+
+
See Also
hasComponent()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
virtual double QwtAbstractScaleDraw::extent (const QFont & font) const
+
+pure virtual
+
+

Calculate the extent

+

The extent is the distance from the baseline to the outermost pixel of the scale draw in opposite to its orientation. It is at least minimumExtent() pixels.

+
Parameters
+ + +
fontFont used for drawing the tick labels
+
+
+
Returns
Number of pixels
+
See Also
setMinimumExtent(), minimumExtent()
+ +

Implemented in QwtScaleDraw, and QwtRoundScaleDraw.

+ +
+
+ +
+
+ + + + + + + + +
bool QwtAbstractScaleDraw::hasComponent (ScaleComponent component) const
+
+

Check if a component is enabled

+
Parameters
+ + +
componentComponent type
+
+
+
Returns
true, when component is enabled
+
See Also
enableComponent()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void QwtAbstractScaleDraw::invalidateCache ()
+
+protected
+
+

Invalidate the cache used by tickLabel()

+

The cache is invalidated, when a new QwtScaleDiv is set. If the labels need to be changed. while the same QwtScaleDiv is set, invalidateCache() needs to be called manually.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
QwtText QwtAbstractScaleDraw::label (double value) const
+
+virtual
+
+ +

Convert a value into its representing label.

+

The value is converted to a plain text using QLocale().toString(value). This method is often overloaded by applications to have individual labels.

+
Parameters
+ + +
valueValue
+
+
+
Returns
Label string.
+ +

Reimplemented in QwtDateScaleDraw, and QwtCompassScaleDraw.

+ +
+
+ +
+
+ + + + + + + +
double QwtAbstractScaleDraw::maxTickLength () const
+
+
Returns
Length of the longest tick
+

Useful for layout calculations

+
See Also
tickLength(), setTickLength()
+ +
+
+ +
+
+ + + + + + + +
double QwtAbstractScaleDraw::minimumExtent () const
+
+

Get the minimum extent

+
Returns
Minimum extent
+
See Also
extent(), setMinimumExtent()
+ +
+
+ +
+
+ + + + + + + +
int QwtAbstractScaleDraw::penWidth () const
+
+
Returns
Scale pen width
+
See Also
setPenWidth()
+ +
+
+ +
+
+ + + + + + + +
const QwtScaleDiv & QwtAbstractScaleDraw::scaleDiv () const
+
+
Returns
scale division
+ +
+
+ +
+
+ + + + + + + +
const QwtScaleMap & QwtAbstractScaleDraw::scaleMap () const
+
+
Returns
Map how to translate between scale and pixel values
+ +
+
+ +
+
+ + + + + + + +
QwtScaleMap & QwtAbstractScaleDraw::scaleMap ()
+
+
Returns
Map how to translate between scale and pixel values
+ +
+
+ +
+
+ + + + + + + + +
void QwtAbstractScaleDraw::setMinimumExtent (double minExtent)
+
+ +

Set a minimum for the extent.

+

The extent is calculated from the components of the scale draw. In situations, where the labels are changing and the layout depends on the extent (f.e scrolling a scale), setting an upper limit as minimum extent will avoid jumps of the layout.

+
Parameters
+ + +
minExtentMinimum extent
+
+
+
See Also
extent(), minimumExtent()
+ +
+
+ +
+
+ + + + + + + + +
void QwtAbstractScaleDraw::setPenWidth (int width)
+
+ +

Specify the width of the scale pen.

+
Parameters
+ + +
widthPen width
+
+
+
See Also
penWidth()
+ +
+
+ +
+
+ + + + + + + + +
void QwtAbstractScaleDraw::setScaleDiv (const QwtScaleDivscaleDiv)
+
+

Change the scale division

+
Parameters
+ + +
scaleDivNew scale division
+
+
+ +
+
+ +
+
+ + + + + + + + +
void QwtAbstractScaleDraw::setSpacing (double spacing)
+
+ +

Set the spacing between tick and labels.

+

The spacing is the distance between ticks and labels. The default spacing is 4 pixels.

+
Parameters
+ + +
spacingSpacing
+
+
+
See Also
spacing()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtAbstractScaleDraw::setTickLength (QwtScaleDiv::TickType tickType,
double length 
)
+
+

Set the length of the ticks

+
Parameters
+ + + +
tickTypeTick type
lengthNew length
+
+
+
Warning
the length is limited to [0..1000]
+ +
+
+ +
+
+ + + + + + + + +
void QwtAbstractScaleDraw::setTransformation (QwtTransformtransformation)
+
+

Change the transformation of the scale

+
Parameters
+ + +
transformationNew scale transformation
+
+
+ +
+
+ +
+
+ + + + + + + +
double QwtAbstractScaleDraw::spacing () const
+
+ +

Get the spacing.

+

The spacing is the distance between ticks and labels. The default spacing is 4 pixels.

+
Returns
Spacing
+
See Also
setSpacing()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
const QwtText & QwtAbstractScaleDraw::tickLabel (const QFont & font,
double value 
) const
+
+protected
+
+ +

Convert a value into its representing label and cache it.

+

The conversion between value and label is called very often in the layout and painting code. Unfortunately the calculation of the label sizes might be slow (really slow for rich text in Qt4), so it's necessary to cache the labels.

+
Parameters
+ + + +
fontFont
valueValue
+
+
+
Returns
Tick label
+ +
+
+ +
+
+ + + + + + + + +
double QwtAbstractScaleDraw::tickLength (QwtScaleDiv::TickType tickType) const
+
+
Returns
Length of the ticks
+
See Also
setTickLength(), maxTickLength()
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_abstract_scale_draw__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_abstract_scale_draw__inherit__graph.map new file mode 100644 index 0000000000..da7ed231db --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_abstract_scale_draw__inherit__graph.map @@ -0,0 +1,6 @@ + + + + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_abstract_scale_draw__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_abstract_scale_draw__inherit__graph.md5 new file mode 100644 index 0000000000..a5ac5cfb26 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_abstract_scale_draw__inherit__graph.md5 @@ -0,0 +1 @@ +28ad076e86524685898ad64bfdc2565d \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_abstract_scale_draw__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_abstract_scale_draw__inherit__graph.png new file mode 100644 index 0000000000..00a03bf47f Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_abstract_scale_draw__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_abstract_series_store-members.html b/ThirdParty/Qwt/doc/html/class_qwt_abstract_series_store-members.html new file mode 100644 index 0000000000..793cdb47ca --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_abstract_series_store-members.html @@ -0,0 +1,105 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtAbstractSeriesStore Member List
+
+
+ +

This is the complete list of members for QwtAbstractSeriesStore, including all inherited members.

+ + + + + + +
dataChanged()=0QwtAbstractSeriesStoreprotectedpure virtual
dataRect() const =0QwtAbstractSeriesStoreprotectedpure virtual
dataSize() const =0QwtAbstractSeriesStoreprotectedpure virtual
setRectOfInterest(const QRectF &)=0QwtAbstractSeriesStoreprotectedpure virtual
~QwtAbstractSeriesStore()QwtAbstractSeriesStoreinlineprotectedvirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_abstract_series_store.html b/ThirdParty/Qwt/doc/html/class_qwt_abstract_series_store.html new file mode 100644 index 0000000000..b4097c4a4b --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_abstract_series_store.html @@ -0,0 +1,214 @@ + + + + + + +Qwt User's Guide: QwtAbstractSeriesStore Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtAbstractSeriesStore Class Referenceabstract
+
+
+ +

Bridge between QwtSeriesStore and QwtPlotSeriesItem. + More...

+ +

#include <qwt_series_store.h>

+
+Inheritance diagram for QwtAbstractSeriesStore:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + + + + + + + +

+Protected Member Functions

+virtual ~QwtAbstractSeriesStore ()
 Destructor.
 
+virtual void dataChanged ()=0
 dataChanged() indicates, that the series has been changed.
 
virtual void setRectOfInterest (const QRectF &)=0
 
virtual QRectF dataRect () const =0
 
virtual size_t dataSize () const =0
 
+

Detailed Description

+

Bridge between QwtSeriesStore and QwtPlotSeriesItem.

+

QwtAbstractSeriesStore is an abstract interface only to make it possible to isolate the template based methods ( QwtSeriesStore ) from the regular methods ( QwtPlotSeriesItem ) to make it possible to derive from QwtPlotSeriesItem without any hassle with templates.

+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + +
virtual QRectF QwtAbstractSeriesStore::dataRect () const
+
+protectedpure virtual
+
+
+ +
+
+ + + + + +
+ + + + + + + +
virtual size_t QwtAbstractSeriesStore::dataSize () const
+
+protectedpure virtual
+
+
+ +
+
+ + + + + +
+ + + + + + + + +
virtual void QwtAbstractSeriesStore::setRectOfInterest (const QRectF & )
+
+protectedpure virtual
+
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_abstract_series_store__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_abstract_series_store__inherit__graph.map new file mode 100644 index 0000000000..452c49b77b --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_abstract_series_store__inherit__graph.map @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_abstract_series_store__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_abstract_series_store__inherit__graph.md5 new file mode 100644 index 0000000000..c147943696 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_abstract_series_store__inherit__graph.md5 @@ -0,0 +1 @@ +32a41d080554023d7b726eeea972d82d \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_abstract_series_store__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_abstract_series_store__inherit__graph.png new file mode 100644 index 0000000000..99f5f5bcc1 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_abstract_series_store__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_abstract_slider-members.html b/ThirdParty/Qwt/doc/html/class_qwt_abstract_slider-members.html new file mode 100644 index 0000000000..41dc355806 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_abstract_slider-members.html @@ -0,0 +1,166 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtAbstractSlider Member List
+
+
+ +

This is the complete list of members for QwtAbstractSlider, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
abstractScaleDraw() const QwtAbstractScaleprotected
abstractScaleDraw()QwtAbstractScaleprotected
incrementedValue(double value, int stepCount) const QwtAbstractSliderprotected
incrementValue(int numSteps)QwtAbstractSliderprotected
invertedControls() const QwtAbstractSlider
invTransform(int) const QwtAbstractScale
isInverted() const QwtAbstractScale
isReadOnly() const QwtAbstractSlider
isScrollPosition(const QPoint &pos) const =0QwtAbstractSliderprotectedpure virtual
isTracking() const QwtAbstractSlider
isValid() const QwtAbstractSlider
keyPressEvent(QKeyEvent *)QwtAbstractSliderprotectedvirtual
lowerBound() const QwtAbstractScale
maximum() const QwtAbstractScale
minimum() const QwtAbstractScale
mouseMoveEvent(QMouseEvent *)QwtAbstractSliderprotectedvirtual
mousePressEvent(QMouseEvent *)QwtAbstractSliderprotectedvirtual
mouseReleaseEvent(QMouseEvent *)QwtAbstractSliderprotectedvirtual
pageSteps() const QwtAbstractSlider
QwtAbstractScale(QWidget *parent=NULL)QwtAbstractScale
QwtAbstractSlider(QWidget *parent=NULL)QwtAbstractSliderexplicit
rescale(double lowerBound, double upperBound, double stepSize)QwtAbstractScaleprotected
scaleChange()QwtAbstractSliderprotectedvirtual
scaleDiv() const QwtAbstractScale
scaleEngine() const QwtAbstractScale
scaleEngine()QwtAbstractScale
scaleMap() const QwtAbstractScale
scaleMaxMajor() const QwtAbstractScale
scaleMaxMinor() const QwtAbstractScale
scaleStepSize() const QwtAbstractScale
scrolledTo(const QPoint &pos) const =0QwtAbstractSliderprotectedpure virtual
setAbstractScaleDraw(QwtAbstractScaleDraw *)QwtAbstractScaleprotected
setInvertedControls(bool)QwtAbstractSlider
setLowerBound(double value)QwtAbstractScale
setPageSteps(uint)QwtAbstractSlider
setReadOnly(bool)QwtAbstractSlider
setScale(double lowerBound, double upperBound)QwtAbstractScale
setScale(const QwtInterval &)QwtAbstractScale
setScale(const QwtScaleDiv &)QwtAbstractScale
setScaleEngine(QwtScaleEngine *)QwtAbstractScale
setScaleMaxMajor(int ticks)QwtAbstractScale
setScaleMaxMinor(int ticks)QwtAbstractScale
setScaleStepSize(double stepSize)QwtAbstractScale
setSingleSteps(uint)QwtAbstractSlider
setStepAlignment(bool)QwtAbstractSlider
setTotalSteps(uint)QwtAbstractSlider
setTracking(bool)QwtAbstractSlider
setUpperBound(double value)QwtAbstractScale
setValid(bool)QwtAbstractSlider
setValue(double val)QwtAbstractSliderslot
setWrapping(bool)QwtAbstractSlider
singleSteps() const QwtAbstractSlider
sliderChange()QwtAbstractSliderprotectedvirtual
sliderMoved(double value)QwtAbstractSlidersignal
sliderPressed()QwtAbstractSlidersignal
sliderReleased()QwtAbstractSlidersignal
stepAlignment() const QwtAbstractSlider
totalSteps() const QwtAbstractSlider
transform(double) const QwtAbstractScale
upperBound() const QwtAbstractScale
value() const QwtAbstractSlider
valueChanged(double value)QwtAbstractSlidersignal
wheelEvent(QWheelEvent *)QwtAbstractSliderprotectedvirtual
wrapping() const QwtAbstractSlider
~QwtAbstractScale()QwtAbstractScalevirtual
~QwtAbstractSlider()QwtAbstractSlidervirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_abstract_slider.html b/ThirdParty/Qwt/doc/html/class_qwt_abstract_slider.html new file mode 100644 index 0000000000..4b3f1a84be --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_abstract_slider.html @@ -0,0 +1,1225 @@ + + + + + + +Qwt User's Guide: QwtAbstractSlider Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtAbstractSlider Class Referenceabstract
+
+
+ +

An abstract base class for slider widgets with a scale. + More...

+ +

#include <qwt_abstract_slider.h>

+
+Inheritance diagram for QwtAbstractSlider:
+
+
Inheritance graph
+ + +
[legend]
+ + + + +

+Public Slots

void setValue (double val)
 
+ + + + + + + + + + +

+Signals

void valueChanged (double value)
 Notify a change of value. More...
 
void sliderPressed ()
 
void sliderReleased ()
 
void sliderMoved (double value)
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 QwtAbstractSlider (QWidget *parent=NULL)
 Constructor. More...
 
+virtual ~QwtAbstractSlider ()
 Destructor.
 
void setValid (bool)
 
bool isValid () const
 
+double value () const
 Returns the current value.
 
void setWrapping (bool)
 
bool wrapping () const
 
void setTotalSteps (uint)
 Set the number of steps. More...
 
uint totalSteps () const
 
void setSingleSteps (uint)
 Set the number of steps for a single increment. More...
 
uint singleSteps () const
 
void setPageSteps (uint)
 Set the number of steps for a page increment. More...
 
uint pageSteps () const
 
void setStepAlignment (bool)
 Enable step alignment. More...
 
bool stepAlignment () const
 
void setTracking (bool)
 Enables or disables tracking. More...
 
bool isTracking () const
 
void setReadOnly (bool)
 
bool isReadOnly () const
 
void setInvertedControls (bool)
 
bool invertedControls () const
 
- Public Member Functions inherited from QwtAbstractScale
 QwtAbstractScale (QWidget *parent=NULL)
 
+virtual ~QwtAbstractScale ()
 Destructor.
 
void setScale (double lowerBound, double upperBound)
 Specify a scale. More...
 
void setScale (const QwtInterval &)
 Specify a scale. More...
 
void setScale (const QwtScaleDiv &)
 Specify a scale. More...
 
const QwtScaleDivscaleDiv () const
 
void setLowerBound (double value)
 
double lowerBound () const
 
void setUpperBound (double value)
 
double upperBound () const
 
void setScaleStepSize (double stepSize)
 Set the step size used for calculating a scale division. More...
 
double scaleStepSize () const
 
void setScaleMaxMajor (int ticks)
 Set the maximum number of major tick intervals. More...
 
int scaleMaxMinor () const
 
void setScaleMaxMinor (int ticks)
 Set the maximum number of minor tick intervals. More...
 
int scaleMaxMajor () const
 
void setScaleEngine (QwtScaleEngine *)
 Set a scale engine. More...
 
const QwtScaleEnginescaleEngine () const
 
QwtScaleEnginescaleEngine ()
 
int transform (double) const
 
double invTransform (int) const
 
bool isInverted () const
 
double minimum () const
 
double maximum () const
 
const QwtScaleMapscaleMap () const
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Protected Member Functions

virtual void mousePressEvent (QMouseEvent *)
 
virtual void mouseReleaseEvent (QMouseEvent *)
 
virtual void mouseMoveEvent (QMouseEvent *)
 
virtual void keyPressEvent (QKeyEvent *)
 
virtual void wheelEvent (QWheelEvent *)
 
virtual bool isScrollPosition (const QPoint &pos) const =0
 Determine what to do when the user presses a mouse button. More...
 
virtual double scrolledTo (const QPoint &pos) const =0
 Determine the value for a new position of the movable part of the slider. More...
 
void incrementValue (int numSteps)
 
virtual void scaleChange ()
 
+virtual void sliderChange ()
 Calling update()
 
double incrementedValue (double value, int stepCount) const
 
- Protected Member Functions inherited from QwtAbstractScale
void rescale (double lowerBound, double upperBound, double stepSize)
 
void setAbstractScaleDraw (QwtAbstractScaleDraw *)
 Set a scale draw. More...
 
const QwtAbstractScaleDrawabstractScaleDraw () const
 
QwtAbstractScaleDrawabstractScaleDraw ()
 
+

Detailed Description

+

An abstract base class for slider widgets with a scale.

+

A slider widget displays a value according to a scale. The class is designed as a common super class for widgets like QwtKnob, QwtDial and QwtSlider.

+

When the slider is nor readOnly() its value can be modified by keyboard, mouse and wheel inputs.

+

The range of the slider is divided into a number of steps from which the value increments according to user inputs depend. Only for linear scales the number of steps correspond with a fixed step size.

+

Constructor & Destructor Documentation

+ +
+
+ + + + + +
+ + + + + + + + +
QwtAbstractSlider::QwtAbstractSlider (QWidget * parent = NULL)
+
+explicit
+
+ +

Constructor.

+

The scale is initialized to [0.0, 100.0], the number of steps is set to 100 with 1 and 10 and single an page step sizes. Step alignment is enabled.

+

The initial value is invalid.

+
Parameters
+ + +
parentParent widget
+
+
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
double QwtAbstractSlider::incrementedValue (double value,
int stepCount 
) const
+
+protected
+
+

Increment a value

+
Parameters
+ + + +
valueValue
stepCountNumber of steps
+
+
+
Returns
Incremented value
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtAbstractSlider::incrementValue (int stepCount)
+
+protected
+
+

Increment the slider

+

The step size depends on the number of totalSteps()

+
Parameters
+ + +
stepCountNumber of steps
+
+
+
See Also
setTotalSteps(), incrementedValue()
+ +
+
+ +
+
+ + + + + + + +
bool QwtAbstractSlider::invertedControls () const
+
+
Returns
True, when the controls are inverted
+
See Also
setInvertedControls()
+ +
+
+ +
+
+ + + + + + + +
bool QwtAbstractSlider::isReadOnly () const
+
+

In read only mode the slider can't be controlled by mouse or keyboard.

+
Returns
true if read only
+
See Also
setReadOnly()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
virtual bool QwtAbstractSlider::isScrollPosition (const QPoint & pos) const
+
+protectedpure virtual
+
+ +

Determine what to do when the user presses a mouse button.

+
Parameters
+ + +
posMouse position
+
+
+
Return values
+ + +
True,whenpos is a valid scroll position
+
+
+
See Also
scrolledTo()
+ +

Implemented in QwtKnob, QwtDial, and QwtSlider.

+ +
+
+ +
+
+ + + + + + + +
bool QwtAbstractSlider::isTracking () const
+
+
Returns
True, when tracking has been enabled
+
See Also
setTracking()
+ +
+
+ +
+
+ + + + + + + +
bool QwtAbstractSlider::isValid () const
+
+
Returns
True, when the value is invalid
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtAbstractSlider::keyPressEvent (QKeyEvent * event)
+
+protectedvirtual
+
+

Handles key events

+

QwtAbstractSlider handles the following keys:

+ +
Parameters
+ + +
eventKey event
+
+
+
See Also
isReadOnly()
+ +

Reimplemented in QwtCompass.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtAbstractSlider::mouseMoveEvent (QMouseEvent * event)
+
+protectedvirtual
+
+

Mouse Move Event handler

+
Parameters
+ + +
eventMouse event
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtAbstractSlider::mousePressEvent (QMouseEvent * event)
+
+protectedvirtual
+
+

Mouse press event handler

+
Parameters
+ + +
eventMouse event
+
+
+ +

Reimplemented in QwtSlider.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtAbstractSlider::mouseReleaseEvent (QMouseEvent * event)
+
+protectedvirtual
+
+

Mouse Release Event handler

+
Parameters
+ + +
eventMouse event
+
+
+ +

Reimplemented in QwtSlider.

+ +
+
+ +
+
+ + + + + + + +
uint QwtAbstractSlider::pageSteps () const
+
+
Returns
Number of steps
+
See Also
setPageSteps(), totalSteps(), singleSteps()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void QwtAbstractSlider::scaleChange ()
+
+protectedvirtual
+
+

Update the slider according to modifications of the scale

+ +

Reimplemented from QwtAbstractScale.

+ +

Reimplemented in QwtDial, and QwtSlider.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
virtual double QwtAbstractSlider::scrolledTo (const QPoint & pos) const
+
+protectedpure virtual
+
+ +

Determine the value for a new position of the movable part of the slider.

+
Parameters
+ + +
posMouse position
+
+
+
Returns
Value for the mouse position
+
See Also
isScrollPosition()
+ +

Implemented in QwtKnob, QwtDial, and QwtSlider.

+ +
+
+ +
+
+ + + + + + + + +
void QwtAbstractSlider::setInvertedControls (bool on)
+
+

Invert wheel and key events

+

Usually scrolling the mouse wheel "up" and using keys like page up will increase the slider's value towards its maximum. When invertedControls() is enabled the value is scrolled towards its minimum.

+

Inverting the controls might be f.e. useful for a vertical slider with an inverted scale ( decreasing from top to bottom ).

+
Parameters
+ + +
onInvert controls, when true
+
+
+
See Also
invertedControls(), keyEvent(), wheelEvent()
+ +
+
+ +
+
+ + + + + + + + +
void QwtAbstractSlider::setPageSteps (uint stepCount)
+
+ +

Set the number of steps for a page increment.

+

The range of the slider is divided into a number of steps from which the value increments according to user inputs depend.

+
Parameters
+ + +
stepCountNumber of steps
+
+
+
See Also
pageSteps(), setTotalSteps(), setSingleSteps()
+ +
+
+ +
+
+ + + + + + + + +
void QwtAbstractSlider::setReadOnly (bool on)
+
+

En/Disable read only mode

+

In read only mode the slider can't be controlled by mouse or keyboard.

+
Parameters
+ + +
onEnables in case of true
+
+
+
See Also
isReadOnly()
+
Warning
The focus policy is set to Qt::StrongFocus or Qt::NoFocus
+ +
+
+ +
+
+ + + + + + + + +
void QwtAbstractSlider::setSingleSteps (uint stepCount)
+
+ +

Set the number of steps for a single increment.

+

The range of the slider is divided into a number of steps from which the value increments according to user inputs depend.

+
Parameters
+ + +
stepCountNumber of steps
+
+
+
See Also
singleSteps(), setTotalSteps(), setPageSteps()
+ +
+
+ +
+
+ + + + + + + + +
void QwtAbstractSlider::setStepAlignment (bool on)
+
+ +

Enable step alignment.

+

When step alignment is enabled values resulting from slider movements are aligned to the step size.

+
Parameters
+ + +
onEnable step alignment when true
+
+
+
See Also
stepAlignment()
+ +
+
+ +
+
+ + + + + + + + +
void QwtAbstractSlider::setTotalSteps (uint stepCount)
+
+ +

Set the number of steps.

+

The range of the slider is divided into a number of steps from which the value increments according to user inputs depend.

+

The default setting is 100.

+
Parameters
+ + +
stepCountNumber of steps
+
+
+
See Also
totalSteps(), setSingleSteps(), setPageSteps()
+ +
+
+ +
+
+ + + + + + + + +
void QwtAbstractSlider::setTracking (bool on)
+
+ +

Enables or disables tracking.

+

If tracking is enabled, the slider emits the valueChanged() signal while the movable part of the slider is being dragged. If tracking is disabled, the slider emits the valueChanged() signal only when the user releases the slider.

+

Tracking is enabled by default.

+
Parameters
+ + +
ontrue (enable) or false (disable) tracking.
+
+
+
See Also
isTracking(), sliderMoved()
+ +
+
+ +
+
+ + + + + + + + +
void QwtAbstractSlider::setValid (bool on)
+
+

Set the value to be valid/invalid

+
Parameters
+ + +
onWhen true, the value is invalidated
+
+
+
See Also
setValue()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtAbstractSlider::setValue (double value)
+
+slot
+
+

Set the slider to the specified value

+
Parameters
+ + +
valueNew value
+
+
+
See Also
setValid(), sliderChange(), valueChanged()
+ +
+
+ +
+
+ + + + + + + + +
void QwtAbstractSlider::setWrapping (bool on)
+
+

If wrapping is true stepping up from upperBound() value will take you to the minimum() value and vice versa.

+
Parameters
+ + +
onEn/Disable wrapping
+
+
+
See Also
wrapping()
+ +
+
+ +
+
+ + + + + + + +
uint QwtAbstractSlider::singleSteps () const
+
+
Returns
Number of steps
+
See Also
setSingleSteps(), totalSteps(), pageSteps()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtAbstractSlider::sliderMoved (double value)
+
+signal
+
+

This signal is emitted when the user moves the slider with the mouse.

+
Parameters
+ + +
valueNew value
+
+
+
See Also
valueChanged()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void QwtAbstractSlider::sliderPressed ()
+
+signal
+
+

This signal is emitted when the user presses the movable part of the slider.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void QwtAbstractSlider::sliderReleased ()
+
+signal
+
+

This signal is emitted when the user releases the movable part of the slider.

+ +
+
+ +
+
+ + + + + + + +
bool QwtAbstractSlider::stepAlignment () const
+
+
Returns
True, when step alignment is enabled
+
See Also
setStepAlignment()
+ +
+
+ +
+
+ + + + + + + +
uint QwtAbstractSlider::totalSteps () const
+
+
Returns
Number of steps
+
See Also
setTotalSteps(), singleSteps(), pageSteps()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtAbstractSlider::valueChanged (double value)
+
+signal
+
+ +

Notify a change of value.

+

When tracking is enabled (default setting), this signal will be emitted every time the value changes.

+
Parameters
+ + +
valueNew value
+
+
+
See Also
setTracking(), sliderMoved()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtAbstractSlider::wheelEvent (QWheelEvent * event)
+
+protectedvirtual
+
+

Wheel Event handler

+

In/decreases the value by s number of steps. The direction depends on the invertedControls() property.

+

When the control or shift modifier is pressed the wheel delta ( divided by 120 ) is mapped to an increment according to pageSteps(). Otherwise it is mapped to singleSteps().

+
Parameters
+ + +
eventWheel event
+
+
+ +

Reimplemented in QwtDial.

+ +
+
+ +
+
+ + + + + + + +
bool QwtAbstractSlider::wrapping () const
+
+
Returns
True, when wrapping is set
+
See Also
setWrapping()
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_abstract_slider__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_abstract_slider__inherit__graph.map new file mode 100644 index 0000000000..98db72154f --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_abstract_slider__inherit__graph.map @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_abstract_slider__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_abstract_slider__inherit__graph.md5 new file mode 100644 index 0000000000..fb1e9d2f97 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_abstract_slider__inherit__graph.md5 @@ -0,0 +1 @@ +64b96a3e49ab55c6f2dde07b031409c7 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_abstract_slider__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_abstract_slider__inherit__graph.png new file mode 100644 index 0000000000..6da82364de Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_abstract_slider__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_alpha_color_map-members.html b/ThirdParty/Qwt/doc/html/class_qwt_alpha_color_map-members.html new file mode 100644 index 0000000000..466c5d3cc1 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_alpha_color_map-members.html @@ -0,0 +1,113 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtAlphaColorMap Member List
+
+
+ +

This is the complete list of members for QwtAlphaColorMap, including all inherited members.

+ + + + + + + + + + + + + + +
color() const QwtAlphaColorMap
QwtColorMap::color(const QwtInterval &, double value) const QwtColorMapinline
colorTable(const QwtInterval &) const QwtColorMapvirtual
Format enum nameQwtColorMap
format() const QwtColorMapinline
Indexed enum valueQwtColorMap
QwtAlphaColorMap(const QColor &=QColor(Qt::gray))QwtAlphaColorMap
QwtColorMap(Format=QwtColorMap::RGB)QwtColorMap
RGB enum valueQwtColorMap
rgb(const QwtInterval &, double value) const QwtAlphaColorMapvirtual
setColor(const QColor &)QwtAlphaColorMap
~QwtAlphaColorMap()QwtAlphaColorMapvirtual
~QwtColorMap()QwtColorMapvirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_alpha_color_map.html b/ThirdParty/Qwt/doc/html/class_qwt_alpha_color_map.html new file mode 100644 index 0000000000..f6589cc4a0 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_alpha_color_map.html @@ -0,0 +1,267 @@ + + + + + + +Qwt User's Guide: QwtAlphaColorMap Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtAlphaColorMap Class Reference
+
+
+ +

QwtAlphaColorMap varies the alpha value of a color. + More...

+ +

#include <qwt_color_map.h>

+
+Inheritance diagram for QwtAlphaColorMap:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 QwtAlphaColorMap (const QColor &=QColor(Qt::gray))
 
+virtual ~QwtAlphaColorMap ()
 Destructor.
 
void setColor (const QColor &)
 
QColor color () const
 
virtual QRgb rgb (const QwtInterval &, double value) const
 Map a value of a given interval into a alpha value. More...
 
- Public Member Functions inherited from QwtColorMap
QwtColorMap (Format=QwtColorMap::RGB)
 Constructor.
 
+virtual ~QwtColorMap ()
 Destructor.
 
Format format () const
 
QColor color (const QwtInterval &, double value) const
 
virtual QVector< QRgb > colorTable (const QwtInterval &) const
 
+ + + + +

+Additional Inherited Members

- Public Types inherited from QwtColorMap
enum  Format { RGB, +Indexed + }
 
+

Detailed Description

+

QwtAlphaColorMap varies the alpha value of a color.

+

Constructor & Destructor Documentation

+ +
+
+ + + + + + + + +
QwtAlphaColorMap::QwtAlphaColorMap (const QColor & color = QColor( Qt::gray ))
+
+

Constructor

+
Parameters
+ + +
colorColor of the map
+
+
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + + + +
QColor QwtAlphaColorMap::color () const
+
+
Returns
the color
+
See Also
setColor()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
QRgb QwtAlphaColorMap::rgb (const QwtIntervalinterval,
double value 
) const
+
+virtual
+
+ +

Map a value of a given interval into a alpha value.

+

alpha := (value - interval.minValue()) / interval.width();

+
Parameters
+ + + +
intervalRange for all values
valueValue to map into a RGB value
+
+
+
Returns
RGB value, with an alpha value
+ +

Implements QwtColorMap.

+ +
+
+ +
+
+ + + + + + + + +
void QwtAlphaColorMap::setColor (const QColor & color)
+
+

Set the color

+
Parameters
+ + +
colorColor
+
+
+
See Also
color()
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_alpha_color_map__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_alpha_color_map__inherit__graph.map new file mode 100644 index 0000000000..e6244b6e92 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_alpha_color_map__inherit__graph.map @@ -0,0 +1,3 @@ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_alpha_color_map__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_alpha_color_map__inherit__graph.md5 new file mode 100644 index 0000000000..d705ce8906 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_alpha_color_map__inherit__graph.md5 @@ -0,0 +1 @@ +c1443bfa560aae4892b29ead158cb4c1 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_alpha_color_map__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_alpha_color_map__inherit__graph.png new file mode 100644 index 0000000000..e8bded36e2 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_alpha_color_map__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_analog_clock-members.html b/ThirdParty/Qwt/doc/html/class_qwt_analog_clock-members.html new file mode 100644 index 0000000000..7cedb2670f --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_analog_clock-members.html @@ -0,0 +1,220 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtAnalogClock Member List
+
+
+ +

This is the complete list of members for QwtAnalogClock, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
abstractScaleDraw() const QwtAbstractScaleprotected
abstractScaleDraw()QwtAbstractScaleprotected
boundingRect() const QwtDial
changeEvent(QEvent *)QwtDialprotectedvirtual
drawContents(QPainter *) const QwtDialprotectedvirtual
drawFocusIndicator(QPainter *) const QwtDialprotectedvirtual
drawFrame(QPainter *p)QwtDialprotectedvirtual
drawHand(QPainter *, Hand, const QPointF &, double radius, double direction, QPalette::ColorGroup) const QwtAnalogClockprotectedvirtual
drawNeedle(QPainter *, const QPointF &, double radius, double direction, QPalette::ColorGroup) const QwtAnalogClockprotectedvirtual
drawScale(QPainter *, const QPointF &center, double radius) const QwtDialprotectedvirtual
drawScaleContents(QPainter *painter, const QPointF &center, double radius) const QwtDialprotectedvirtual
frameShadow() const QwtDial
Hand enum nameQwtAnalogClock
hand(Hand) const QwtAnalogClock
hand(Hand)QwtAnalogClock
HourHand enum valueQwtAnalogClock
incrementedValue(double value, int stepCount) const QwtAbstractSliderprotected
incrementValue(int numSteps)QwtAbstractSliderprotected
innerRect() const QwtDial
invalidateCache()QwtDialprotected
invertedControls() const QwtAbstractSlider
invTransform(int) const QwtAbstractScale
isInverted() const QwtAbstractScale
isReadOnly() const QwtAbstractSlider
isScrollPosition(const QPoint &) const QwtDialprotectedvirtual
isTracking() const QwtAbstractSlider
isValid() const QwtAbstractSlider
keyPressEvent(QKeyEvent *)QwtAbstractSliderprotectedvirtual
lineWidth() const QwtDial
lowerBound() const QwtAbstractScale
maximum() const QwtAbstractScale
maxScaleArc() const QwtDial
minimum() const QwtAbstractScale
minimumSizeHint() const QwtDialvirtual
minScaleArc() const QwtDial
MinuteHand enum valueQwtAnalogClock
Mode enum nameQwtDial
mode() const QwtDial
mouseMoveEvent(QMouseEvent *)QwtAbstractSliderprotectedvirtual
mousePressEvent(QMouseEvent *)QwtAbstractSliderprotectedvirtual
mouseReleaseEvent(QMouseEvent *)QwtAbstractSliderprotectedvirtual
needle() const QwtDial
needle()QwtDial
NHands enum valueQwtAnalogClock
origin() const QwtDial
pageSteps() const QwtAbstractSlider
paintEvent(QPaintEvent *)QwtDialprotectedvirtual
Plain enum valueQwtDial
QwtAbstractScale(QWidget *parent=NULL)QwtAbstractScale
QwtAbstractSlider(QWidget *parent=NULL)QwtAbstractSliderexplicit
QwtAnalogClock(QWidget *parent=NULL)QwtAnalogClockexplicit
QwtDial(QWidget *parent=NULL)QwtDialexplicit
Raised enum valueQwtDial
rescale(double lowerBound, double upperBound, double stepSize)QwtAbstractScaleprotected
RotateNeedle enum valueQwtDial
RotateScale enum valueQwtDial
scaleChange()QwtDialprotectedvirtual
scaleDiv() const QwtAbstractScale
scaleDraw()QwtDial
scaleDraw() const QwtDial
scaleEngine() const QwtAbstractScale
scaleEngine()QwtAbstractScale
scaleInnerRect() const QwtDialvirtual
scaleMap() const QwtAbstractScale
scaleMaxMajor() const QwtAbstractScale
scaleMaxMinor() const QwtAbstractScale
scaleStepSize() const QwtAbstractScale
scrolledTo(const QPoint &) const QwtDialprotectedvirtual
SecondHand enum valueQwtAnalogClock
setAbstractScaleDraw(QwtAbstractScaleDraw *)QwtAbstractScaleprotected
setCurrentTime()QwtAnalogClockslot
setFrameShadow(Shadow)QwtDial
setHand(Hand, QwtDialNeedle *)QwtAnalogClock
setInvertedControls(bool)QwtAbstractSlider
setLineWidth(int)QwtDial
setLowerBound(double value)QwtAbstractScale
setMaxScaleArc(double min)QwtDial
setMinScaleArc(double min)QwtDial
setMode(Mode)QwtDial
setOrigin(double)QwtDialvirtual
setPageSteps(uint)QwtAbstractSlider
setReadOnly(bool)QwtAbstractSlider
setScale(double lowerBound, double upperBound)QwtAbstractScale
setScale(const QwtInterval &)QwtAbstractScale
setScale(const QwtScaleDiv &)QwtAbstractScale
setScaleArc(double min, double max)QwtDial
setScaleDraw(QwtRoundScaleDraw *)QwtDial
setScaleEngine(QwtScaleEngine *)QwtAbstractScale
setScaleMaxMajor(int ticks)QwtAbstractScale
setScaleMaxMinor(int ticks)QwtAbstractScale
setScaleStepSize(double stepSize)QwtAbstractScale
setSingleSteps(uint)QwtAbstractSlider
setStepAlignment(bool)QwtAbstractSlider
setTime(const QTime &)QwtAnalogClockslot
setTotalSteps(uint)QwtAbstractSlider
setTracking(bool)QwtAbstractSlider
setUpperBound(double value)QwtAbstractScale
setValid(bool)QwtAbstractSlider
setValue(double val)QwtAbstractSliderslot
setWrapping(bool)QwtAbstractSlider
Shadow enum nameQwtDial
singleSteps() const QwtAbstractSlider
sizeHint() const QwtDialvirtual
sliderChange()QwtDialprotectedvirtual
sliderMoved(double value)QwtAbstractSlidersignal
sliderPressed()QwtAbstractSlidersignal
sliderReleased()QwtAbstractSlidersignal
stepAlignment() const QwtAbstractSlider
Sunken enum valueQwtDial
totalSteps() const QwtAbstractSlider
transform(double) const QwtAbstractScale
upperBound() const QwtAbstractScale
value() const QwtAbstractSlider
valueChanged(double value)QwtAbstractSlidersignal
wheelEvent(QWheelEvent *)QwtDialprotectedvirtual
wrapping() const QwtAbstractSlider
~QwtAbstractScale()QwtAbstractScalevirtual
~QwtAbstractSlider()QwtAbstractSlidervirtual
~QwtAnalogClock()QwtAnalogClockvirtual
~QwtDial()QwtDialvirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_analog_clock.html b/ThirdParty/Qwt/doc/html/class_qwt_analog_clock.html new file mode 100644 index 0000000000..ffbc21f8ea --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_analog_clock.html @@ -0,0 +1,741 @@ + + + + + + +Qwt User's Guide: QwtAnalogClock Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+ +
+ +

An analog clock. + More...

+ +

#include <qwt_analog_clock.h>

+
+Inheritance diagram for QwtAnalogClock:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + + + + +

+Public Types

enum  Hand { SecondHand, +MinuteHand, +HourHand, +NHands + }
 
- Public Types inherited from QwtDial
enum  Shadow { Plain = QFrame::Plain, +Raised = QFrame::Raised, +Sunken = QFrame::Sunken + }
 Frame shadow. More...
 
enum  Mode { RotateNeedle, +RotateScale + }
 Mode controlling whether the needle or the scale is rotating. More...
 
+ + + + + + +

+Public Slots

+void setCurrentTime ()
 Set the current time.
 
void setTime (const QTime &)
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 QwtAnalogClock (QWidget *parent=NULL)
 
+virtual ~QwtAnalogClock ()
 Destructor.
 
void setHand (Hand, QwtDialNeedle *)
 
const QwtDialNeedlehand (Hand) const
 
QwtDialNeedlehand (Hand)
 
- Public Member Functions inherited from QwtDial
 QwtDial (QWidget *parent=NULL)
 Constructor. More...
 
+virtual ~QwtDial ()
 Destructor.
 
void setFrameShadow (Shadow)
 
Shadow frameShadow () const
 
void setLineWidth (int)
 
int lineWidth () const
 
void setMode (Mode)
 Change the mode of the dial. More...
 
Mode mode () const
 
void setScaleArc (double min, double max)
 
void setMinScaleArc (double min)
 
double minScaleArc () const
 
void setMaxScaleArc (double min)
 
double maxScaleArc () const
 
virtual void setOrigin (double)
 Change the origin. More...
 
double origin () const
 
void setNeedle (QwtDialNeedle *)
 
const QwtDialNeedleneedle () const
 
QwtDialNeedleneedle ()
 
QRect boundingRect () const
 
QRect innerRect () const
 
virtual QRect scaleInnerRect () const
 
virtual QSize sizeHint () const
 
virtual QSize minimumSizeHint () const
 
void setScaleDraw (QwtRoundScaleDraw *)
 
QwtRoundScaleDrawscaleDraw ()
 
const QwtRoundScaleDrawscaleDraw () const
 
- Public Member Functions inherited from QwtAbstractSlider
 QwtAbstractSlider (QWidget *parent=NULL)
 Constructor. More...
 
+virtual ~QwtAbstractSlider ()
 Destructor.
 
void setValid (bool)
 
bool isValid () const
 
+double value () const
 Returns the current value.
 
void setWrapping (bool)
 
bool wrapping () const
 
void setTotalSteps (uint)
 Set the number of steps. More...
 
uint totalSteps () const
 
void setSingleSteps (uint)
 Set the number of steps for a single increment. More...
 
uint singleSteps () const
 
void setPageSteps (uint)
 Set the number of steps for a page increment. More...
 
uint pageSteps () const
 
void setStepAlignment (bool)
 Enable step alignment. More...
 
bool stepAlignment () const
 
void setTracking (bool)
 Enables or disables tracking. More...
 
bool isTracking () const
 
void setReadOnly (bool)
 
bool isReadOnly () const
 
void setInvertedControls (bool)
 
bool invertedControls () const
 
- Public Member Functions inherited from QwtAbstractScale
 QwtAbstractScale (QWidget *parent=NULL)
 
+virtual ~QwtAbstractScale ()
 Destructor.
 
void setScale (double lowerBound, double upperBound)
 Specify a scale. More...
 
void setScale (const QwtInterval &)
 Specify a scale. More...
 
void setScale (const QwtScaleDiv &)
 Specify a scale. More...
 
const QwtScaleDivscaleDiv () const
 
void setLowerBound (double value)
 
double lowerBound () const
 
void setUpperBound (double value)
 
double upperBound () const
 
void setScaleStepSize (double stepSize)
 Set the step size used for calculating a scale division. More...
 
double scaleStepSize () const
 
void setScaleMaxMajor (int ticks)
 Set the maximum number of major tick intervals. More...
 
int scaleMaxMinor () const
 
void setScaleMaxMinor (int ticks)
 Set the maximum number of minor tick intervals. More...
 
int scaleMaxMajor () const
 
void setScaleEngine (QwtScaleEngine *)
 Set a scale engine. More...
 
const QwtScaleEnginescaleEngine () const
 
QwtScaleEnginescaleEngine ()
 
int transform (double) const
 
double invTransform (int) const
 
bool isInverted () const
 
double minimum () const
 
double maximum () const
 
const QwtScaleMapscaleMap () const
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Protected Member Functions

virtual void drawNeedle (QPainter *, const QPointF &, double radius, double direction, QPalette::ColorGroup) const
 Draw the needle. More...
 
virtual void drawHand (QPainter *, Hand, const QPointF &, double radius, double direction, QPalette::ColorGroup) const
 
- Protected Member Functions inherited from QwtDial
virtual void wheelEvent (QWheelEvent *)
 
virtual void paintEvent (QPaintEvent *)
 
virtual void changeEvent (QEvent *)
 
virtual void drawFrame (QPainter *p)
 
virtual void drawContents (QPainter *) const
 Draw the contents inside the frame. More...
 
virtual void drawFocusIndicator (QPainter *) const
 
void invalidateCache ()
 
virtual void drawScale (QPainter *, const QPointF &center, double radius) const
 
virtual void drawScaleContents (QPainter *painter, const QPointF &center, double radius) const
 
virtual double scrolledTo (const QPoint &) const
 Determine the value for a new position of the slider handle. More...
 
virtual bool isScrollPosition (const QPoint &) const
 Determine what to do when the user presses a mouse button. More...
 
+virtual void sliderChange ()
 Calling update()
 
virtual void scaleChange ()
 
- Protected Member Functions inherited from QwtAbstractSlider
virtual void mousePressEvent (QMouseEvent *)
 
virtual void mouseReleaseEvent (QMouseEvent *)
 
virtual void mouseMoveEvent (QMouseEvent *)
 
virtual void keyPressEvent (QKeyEvent *)
 
void incrementValue (int numSteps)
 
double incrementedValue (double value, int stepCount) const
 
- Protected Member Functions inherited from QwtAbstractScale
void rescale (double lowerBound, double upperBound, double stepSize)
 
void setAbstractScaleDraw (QwtAbstractScaleDraw *)
 Set a scale draw. More...
 
const QwtAbstractScaleDrawabstractScaleDraw () const
 
QwtAbstractScaleDrawabstractScaleDraw ()
 
+ + + + + + + + + + + +

+Additional Inherited Members

- Signals inherited from QwtAbstractSlider
void valueChanged (double value)
 Notify a change of value. More...
 
void sliderPressed ()
 
void sliderReleased ()
 
void sliderMoved (double value)
 
+

Detailed Description

+

An analog clock.

+
+analogclock.png +
+
Example
#include <qwt_analog_clock.h>
+
+
QwtAnalogClock *clock = new QwtAnalogClock(...);
+
clock->scaleDraw()->setPenWidth(3);
+
clock->setLineWidth(6);
+ +
clock->setTime();
+
+
// update the clock every second
+
QTimer *timer = new QTimer(clock);
+
timer->connect(timer, SIGNAL(timeout()), clock, SLOT(setCurrentTime()));
+
timer->start(1000);
+
+
Note
The examples/dials example shows how to use QwtAnalogClock.
+

Member Enumeration Documentation

+ +
+
+ + + + +
enum QwtAnalogClock::Hand
+
+

Hand type

+
See Also
setHand(), hand()
+ + + + + +
Enumerator
SecondHand  +

Needle displaying the seconds.

+
MinuteHand  +

Needle displaying the minutes.

+
HourHand  +

Needle displaying the hours.

+
NHands  +

Number of needles.

+
+ +
+
+

Constructor & Destructor Documentation

+ +
+
+ + + + + +
+ + + + + + + + +
QwtAnalogClock::QwtAnalogClock (QWidget * parent = NULL)
+
+explicit
+
+

Constructor

+
Parameters
+ + +
parentParent widget
+
+
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void QwtAnalogClock::drawHand (QPainter * painter,
Hand hd,
const QPointF & center,
double radius,
double direction,
QPalette::ColorGroup cg 
) const
+
+protectedvirtual
+
+

Draw a clock hand

+
Parameters
+ + + + + + + +
painterPainter
hdSpecify the type of hand
centerCenter of the clock
radiusMaximum length for the hands
directionDirection of the hand in degrees, counter clockwise
cgColorGroup
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void QwtAnalogClock::drawNeedle (QPainter * painter,
const QPointF & center,
double radius,
double dir,
QPalette::ColorGroup colorGroup 
) const
+
+protectedvirtual
+
+ +

Draw the needle.

+

A clock has no single needle but three hands instead. drawNeedle() translates value() into directions for the hands and calls drawHand().

+
Parameters
+ + + + + + +
painterPainter
centerCenter of the clock
radiusMaximum length for the hands
dirDummy, not used.
colorGroupColorGroup
+
+
+
See Also
drawHand()
+ +

Reimplemented from QwtDial.

+ +
+
+ +
+
+ + + + + + + + +
const QwtDialNeedle * QwtAnalogClock::hand (Hand hd) const
+
+
Returns
Clock hand
+
Parameters
+ + +
hdSpecifies the type of hand
+
+
+
See Also
setHand()
+ +
+
+ +
+
+ + + + + + + + +
QwtDialNeedle * QwtAnalogClock::hand (Hand hd)
+
+
Returns
Clock hand
+
Parameters
+ + +
hdSpecifies the type of hand
+
+
+
See Also
setHand()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtAnalogClock::setHand (Hand hand,
QwtDialNeedleneedle 
)
+
+

Set a clock hand

+
Parameters
+ + + +
handSpecifies the type of hand
needleHand
+
+
+
See Also
hand()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtAnalogClock::setTime (const QTime & time)
+
+slot
+
+

Set a time

+
Parameters
+ + +
timeTime to display
+
+
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_analog_clock__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_analog_clock__inherit__graph.map new file mode 100644 index 0000000000..466975ae3c --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_analog_clock__inherit__graph.map @@ -0,0 +1,5 @@ + + + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_analog_clock__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_analog_clock__inherit__graph.md5 new file mode 100644 index 0000000000..9188c9f656 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_analog_clock__inherit__graph.md5 @@ -0,0 +1 @@ +d16f210faff2a73e75d31facd3a94498 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_analog_clock__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_analog_clock__inherit__graph.png new file mode 100644 index 0000000000..ce65a8a368 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_analog_clock__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_array_series_data-members.html b/ThirdParty/Qwt/doc/html/class_qwt_array_series_data-members.html new file mode 100644 index 0000000000..252d3d2ec3 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_array_series_data-members.html @@ -0,0 +1,112 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtArraySeriesData< T > Member List
+
+
+ +

This is the complete list of members for QwtArraySeriesData< T >, including all inherited members.

+ + + + + + + + + + + + + +
boundingRect() const =0QwtSeriesData< T >pure virtual
d_boundingRectQwtSeriesData< T >mutableprotected
d_samplesQwtArraySeriesData< T >protected
QwtArraySeriesData()QwtArraySeriesData< T >
QwtArraySeriesData(const QVector< T > &samples)QwtArraySeriesData< T >
QwtSeriesData()QwtSeriesData< T >
sample(size_t index) const QwtArraySeriesData< T >virtual
samples() const QwtArraySeriesData< T >
setRectOfInterest(const QRectF &rect)QwtSeriesData< T >virtual
setSamples(const QVector< T > &samples)QwtArraySeriesData< T >
size() const QwtArraySeriesData< T >virtual
~QwtSeriesData()QwtSeriesData< T >virtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_array_series_data.html b/ThirdParty/Qwt/doc/html/class_qwt_array_series_data.html new file mode 100644 index 0000000000..af7d0fc26f --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_array_series_data.html @@ -0,0 +1,296 @@ + + + + + + +Qwt User's Guide: QwtArraySeriesData< T > Class Template Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtArraySeriesData< T > Class Template Reference
+
+
+ +

Template class for data, that is organized as QVector. + More...

+ +

#include <qwt_series_data.h>

+
+Inheritance diagram for QwtArraySeriesData< T >:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

QwtArraySeriesData ()
 Constructor.
 
 QwtArraySeriesData (const QVector< T > &samples)
 
void setSamples (const QVector< T > &samples)
 
const QVector< T > samples () const
 
virtual size_t size () const
 
virtual T sample (size_t index) const
 
- Public Member Functions inherited from QwtSeriesData< T >
QwtSeriesData ()
 Constructor.
 
+virtual ~QwtSeriesData ()
 Destructor.
 
virtual QRectF boundingRect () const =0
 
virtual void setRectOfInterest (const QRectF &rect)
 
+ + + + + + + + +

+Protected Attributes

+QVector< T > d_samples
 Vector of samples.
 
- Protected Attributes inherited from QwtSeriesData< T >
+QRectF d_boundingRect
 Can be used to cache a calculated bounding rectangle.
 
+

Detailed Description

+

template<typename T>
+class QwtArraySeriesData< T >

+ +

Template class for data, that is organized as QVector.

+

QVector uses implicit data sharing and can be passed around as argument efficiently.

+

Constructor & Destructor Documentation

+ +
+
+
+template<typename T>
+ + + + + + + + +
QwtArraySeriesData< T >::QwtArraySeriesData (const QVector< T > & samples)
+
+

Constructor

+
Parameters
+ + +
samplesArray of samples
+
+
+ +
+
+

Member Function Documentation

+ +
+
+
+template<typename T >
+ + + + + +
+ + + + + + + + +
T QwtArraySeriesData< T >::sample (size_t index) const
+
+virtual
+
+
Returns
Sample at a specific position
+
Parameters
+ + +
indexIndex
+
+
+
Returns
Sample at position index
+ +

Implements QwtSeriesData< T >.

+ +
+
+ +
+
+
+template<typename T >
+ + + + + + + +
const QVector< T > QwtArraySeriesData< T >::samples () const
+
+
Returns
Array of samples
+ +
+
+ +
+
+
+template<typename T>
+ + + + + + + + +
void QwtArraySeriesData< T >::setSamples (const QVector< T > & samples)
+
+

Assign an array of samples

+
Parameters
+ + +
samplesArray of samples
+
+
+ +
+
+ +
+
+
+template<typename T >
+ + + + + +
+ + + + + + + +
size_t QwtArraySeriesData< T >::size () const
+
+virtual
+
+
Returns
Number of samples
+ +

Implements QwtSeriesData< T >.

+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_array_series_data__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_array_series_data__inherit__graph.map new file mode 100644 index 0000000000..832b86ed6b --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_array_series_data__inherit__graph.map @@ -0,0 +1,3 @@ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_array_series_data__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_array_series_data__inherit__graph.md5 new file mode 100644 index 0000000000..e85bee33a0 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_array_series_data__inherit__graph.md5 @@ -0,0 +1 @@ +1f99bb19b192e2718a0ba3ef8dfbe804 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_array_series_data__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_array_series_data__inherit__graph.png new file mode 100644 index 0000000000..7c73cb9f83 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_array_series_data__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_arrow_button-members.html b/ThirdParty/Qwt/doc/html/class_qwt_arrow_button-members.html new file mode 100644 index 0000000000..46cc4fddfb --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_arrow_button-members.html @@ -0,0 +1,112 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtArrowButton Member List
+
+
+ +

This is the complete list of members for QwtArrowButton, including all inherited members.

+ + + + + + + + + + + + + +
arrowSize(Qt::ArrowType, const QSize &boundingSize) const QwtArrowButtonprotectedvirtual
arrowType() const QwtArrowButton
drawArrow(QPainter *, const QRect &, Qt::ArrowType) const QwtArrowButtonprotectedvirtual
drawButtonLabel(QPainter *p)QwtArrowButtonprotectedvirtual
keyPressEvent(QKeyEvent *)QwtArrowButtonprotectedvirtual
labelRect() const QwtArrowButtonprotectedvirtual
minimumSizeHint() const QwtArrowButtonvirtual
num() const QwtArrowButton
paintEvent(QPaintEvent *event)QwtArrowButtonprotectedvirtual
QwtArrowButton(int num, Qt::ArrowType, QWidget *parent=NULL)QwtArrowButtonexplicit
sizeHint() const QwtArrowButtonvirtual
~QwtArrowButton()QwtArrowButtonvirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_arrow_button.html b/ThirdParty/Qwt/doc/html/class_qwt_arrow_button.html new file mode 100644 index 0000000000..15926a3283 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_arrow_button.html @@ -0,0 +1,412 @@ + + + + + + +Qwt User's Guide: QwtArrowButton Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtArrowButton Class Reference
+
+
+ +

Arrow Button. + More...

+ +

#include <qwt_arrow_button.h>

+
+Inheritance diagram for QwtArrowButton:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + + + + + + + + + + + +

+Public Member Functions

 QwtArrowButton (int num, Qt::ArrowType, QWidget *parent=NULL)
 
+virtual ~QwtArrowButton ()
 Destructor.
 
+Qt::ArrowType arrowType () const
 The direction of the arrows.
 
+int num () const
 The number of arrows.
 
virtual QSize sizeHint () const
 
+virtual QSize minimumSizeHint () const
 Return a minimum size hint.
 
+ + + + + + + + + + + + + + + +

+Protected Member Functions

virtual void paintEvent (QPaintEvent *event)
 
virtual void drawButtonLabel (QPainter *p)
 Draw the button label. More...
 
virtual void drawArrow (QPainter *, const QRect &, Qt::ArrowType) const
 
virtual QRect labelRect () const
 
virtual QSize arrowSize (Qt::ArrowType, const QSize &boundingSize) const
 
+virtual void keyPressEvent (QKeyEvent *)
 autoRepeat for the space keys
 
+

Detailed Description

+

Arrow Button.

+

A push button with one or more filled triangles on its front. An Arrow button can have 1 to 3 arrows in a row, pointing up, down, left or right.

+

Constructor & Destructor Documentation

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
QwtArrowButton::QwtArrowButton (int num,
Qt::ArrowType arrowType,
QWidget * parent = NULL 
)
+
+explicit
+
+
Parameters
+ + + + +
numNumber of arrows
arrowTypesee Qt::ArrowType in the Qt docs.
parentParent widget
+
+
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
QSize QwtArrowButton::arrowSize (Qt::ArrowType arrowType,
const QSize & boundingSize 
) const
+
+protectedvirtual
+
+

Calculate the size for a arrow that fits into a rectangle of a given size

+
Parameters
+ + + +
arrowTypeArrow type
boundingSizeBounding size
+
+
+
Returns
Size of the arrow
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
void QwtArrowButton::drawArrow (QPainter * painter,
const QRect & r,
Qt::ArrowType arrowType 
) const
+
+protectedvirtual
+
+

Draw an arrow int a bounding rectangle

+
Parameters
+ + + + +
painterPainter
rRectangle where to paint the arrow
arrowTypeArrow type
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtArrowButton::drawButtonLabel (QPainter * painter)
+
+protectedvirtual
+
+ +

Draw the button label.

+
Parameters
+ + +
painterPainter
+
+
+
See Also
The Qt Manual for QPushButton
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
QRect QwtArrowButton::labelRect () const
+
+protectedvirtual
+
+
Returns
the bounding rectangle for the label
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtArrowButton::paintEvent (QPaintEvent * event)
+
+protectedvirtual
+
+

Paint event handler

+
Parameters
+ + +
eventPaint event
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
QSize QwtArrowButton::sizeHint () const
+
+virtual
+
+
Returns
a size hint
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_arrow_button__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_arrow_button__inherit__graph.map new file mode 100644 index 0000000000..2d9e759caa --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_arrow_button__inherit__graph.map @@ -0,0 +1,2 @@ + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_arrow_button__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_arrow_button__inherit__graph.md5 new file mode 100644 index 0000000000..de6f1008dc --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_arrow_button__inherit__graph.md5 @@ -0,0 +1 @@ +24617ad4f6e75a8180114576ee13df7a \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_arrow_button__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_arrow_button__inherit__graph.png new file mode 100644 index 0000000000..84c2b4d971 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_arrow_button__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_c_pointer_data-members.html b/ThirdParty/Qwt/doc/html/class_qwt_c_pointer_data-members.html new file mode 100644 index 0000000000..8f40e4a51e --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_c_pointer_data-members.html @@ -0,0 +1,110 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtCPointerData Member List
+
+
+ +

This is the complete list of members for QwtCPointerData, including all inherited members.

+ + + + + + + + + + + +
boundingRect() const QwtCPointerDatavirtual
d_boundingRectQwtSeriesData< QPointF >mutableprotected
QwtCPointerData(const double *x, const double *y, size_t size)QwtCPointerData
QwtSeriesData()QwtSeriesData< QPointF >
sample(size_t i) const QwtCPointerDatavirtual
setRectOfInterest(const QRectF &rect)QwtSeriesData< QPointF >virtual
size() const QwtCPointerDatavirtual
xData() const QwtCPointerData
yData() const QwtCPointerData
~QwtSeriesData()QwtSeriesData< QPointF >virtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_c_pointer_data.html b/ThirdParty/Qwt/doc/html/class_qwt_c_pointer_data.html new file mode 100644 index 0000000000..5bf8b8a1ab --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_c_pointer_data.html @@ -0,0 +1,316 @@ + + + + + + +Qwt User's Guide: QwtCPointerData Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtCPointerData Class Reference
+
+
+ +

Data class containing two pointers to memory blocks of doubles. + More...

+ +

#include <qwt_point_data.h>

+
+Inheritance diagram for QwtCPointerData:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 QwtCPointerData (const double *x, const double *y, size_t size)
 
virtual QRectF boundingRect () const
 Calculate the bounding rectangle. More...
 
virtual size_t size () const
 
virtual QPointF sample (size_t i) const
 
const double * xData () const
 
const double * yData () const
 
- Public Member Functions inherited from QwtSeriesData< QPointF >
QwtSeriesData ()
 Constructor.
 
+virtual ~QwtSeriesData ()
 Destructor.
 
virtual void setRectOfInterest (const QRectF &rect)
 
+ + + + + +

+Additional Inherited Members

- Protected Attributes inherited from QwtSeriesData< QPointF >
+QRectF d_boundingRect
 Can be used to cache a calculated bounding rectangle.
 
+

Detailed Description

+

Data class containing two pointers to memory blocks of doubles.

+

Constructor & Destructor Documentation

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
QwtCPointerData::QwtCPointerData (const double * x,
const double * y,
size_t size 
)
+
+

Constructor

+
Parameters
+ + + + +
xArray of x values
yArray of y values
sizeSize of the x and y arrays
+
+
+
Warning
The programmer must assure that the memory blocks referenced by the pointers remain valid during the lifetime of the QwtPlotCPointer object.
+
See Also
QwtPlotCurve::setData(), QwtPlotCurve::setRawSamples()
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + +
QRectF QwtCPointerData::boundingRect () const
+
+virtual
+
+ +

Calculate the bounding rectangle.

+

The bounding rectangle is calculated once by iterating over all points and is stored for all following requests.

+
Returns
Bounding rectangle
+ +

Implements QwtSeriesData< QPointF >.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
QPointF QwtCPointerData::sample (size_t index) const
+
+virtual
+
+

Return the sample at position i

+
Parameters
+ + +
indexIndex
+
+
+
Returns
Sample at position i
+ +

Implements QwtSeriesData< QPointF >.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
size_t QwtCPointerData::size () const
+
+virtual
+
+
Returns
Size of the data set
+ +

Implements QwtSeriesData< QPointF >.

+ +
+
+ +
+
+ + + + + + + +
const double * QwtCPointerData::xData () const
+
+
Returns
Array of the x-values
+ +
+
+ +
+
+ + + + + + + +
const double * QwtCPointerData::yData () const
+
+
Returns
Array of the y-values
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_c_pointer_data__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_c_pointer_data__inherit__graph.map new file mode 100644 index 0000000000..0c17ed48ac --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_c_pointer_data__inherit__graph.map @@ -0,0 +1,3 @@ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_c_pointer_data__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_c_pointer_data__inherit__graph.md5 new file mode 100644 index 0000000000..6b4814f3ec --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_c_pointer_data__inherit__graph.md5 @@ -0,0 +1 @@ +dea2ab8997528f94d658bcaaddf31e78 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_c_pointer_data__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_c_pointer_data__inherit__graph.png new file mode 100644 index 0000000000..f05c477380 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_c_pointer_data__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_clipper-members.html b/ThirdParty/Qwt/doc/html/class_qwt_clipper-members.html new file mode 100644 index 0000000000..233d89d280 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_clipper-members.html @@ -0,0 +1,104 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtClipper Member List
+
+
+ +

This is the complete list of members for QwtClipper, including all inherited members.

+ + + + + +
clipCircle(const QRectF &, const QPointF &, double radius)QwtClipperstatic
clipPolygon(const QRect &, const QPolygon &, bool closePolygon=false)QwtClipperstatic
clipPolygon(const QRectF &, const QPolygon &, bool closePolygon=false)QwtClipperstatic
clipPolygonF(const QRectF &, const QPolygonF &, bool closePolygon=false)QwtClipperstatic
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_clipper.html b/ThirdParty/Qwt/doc/html/class_qwt_clipper.html new file mode 100644 index 0000000000..7a0bb04043 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_clipper.html @@ -0,0 +1,321 @@ + + + + + + +Qwt User's Guide: QwtClipper Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtClipper Class Reference
+
+
+ +

Some clipping algorithms. + More...

+ +

#include <qwt_clipper.h>

+ + + + + + + + + + +

+Static Public Member Functions

static QPolygon clipPolygon (const QRect &, const QPolygon &, bool closePolygon=false)
 
static QPolygon clipPolygon (const QRectF &, const QPolygon &, bool closePolygon=false)
 
static QPolygonF clipPolygonF (const QRectF &, const QPolygonF &, bool closePolygon=false)
 
static QVector< QwtIntervalclipCircle (const QRectF &, const QPointF &, double radius)
 
+

Detailed Description

+

Some clipping algorithms.

+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
QVector< QwtInterval > QwtClipper::clipCircle (const QRectF & clipRect,
const QPointF & center,
double radius 
)
+
+static
+
+

Circle clipping

+

clipCircle() divides a circle into intervals of angles representing arcs of the circle. When the circle is completely inside the clip rectangle an interval [0.0, 2 * M_PI] is returned.

+
Parameters
+ + + + +
clipRectClip rectangle
centerCenter of the circle
radiusRadius of the circle
+
+
+
Returns
Arcs of the circle
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
QPolygon QwtClipper::clipPolygon (const QRect & clipRect,
const QPolygon & polygon,
bool closePolygon = false 
)
+
+static
+
+

Sutherland-Hodgman polygon clipping

+
Parameters
+ + + + +
clipRectClip rectangle
polygonPolygon
closePolygonTrue, when the polygon is closed
+
+
+
Returns
Clipped polygon
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
QPolygon QwtClipper::clipPolygon (const QRectF & clipRect,
const QPolygon & polygon,
bool closePolygon = false 
)
+
+static
+
+

Sutherland-Hodgman polygon clipping

+
Parameters
+ + + + +
clipRectClip rectangle
polygonPolygon
closePolygonTrue, when the polygon is closed
+
+
+
Returns
Clipped polygon
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
QPolygonF QwtClipper::clipPolygonF (const QRectF & clipRect,
const QPolygonF & polygon,
bool closePolygon = false 
)
+
+static
+
+

Sutherland-Hodgman polygon clipping

+
Parameters
+ + + + +
clipRectClip rectangle
polygonPolygon
closePolygonTrue, when the polygon is closed
+
+
+
Returns
Clipped polygon
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_color_map-members.html b/ThirdParty/Qwt/doc/html/class_qwt_color_map-members.html new file mode 100644 index 0000000000..8a75df2c2d --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_color_map-members.html @@ -0,0 +1,110 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtColorMap Member List
+
+
+ +

This is the complete list of members for QwtColorMap, including all inherited members.

+ + + + + + + + + + + +
color(const QwtInterval &, double value) const QwtColorMapinline
colorIndex(const QwtInterval &interval, double value) const =0QwtColorMappure virtual
colorTable(const QwtInterval &) const QwtColorMapvirtual
Format enum nameQwtColorMap
format() const QwtColorMapinline
Indexed enum valueQwtColorMap
QwtColorMap(Format=QwtColorMap::RGB)QwtColorMap
rgb(const QwtInterval &interval, double value) const =0QwtColorMappure virtual
RGB enum valueQwtColorMap
~QwtColorMap()QwtColorMapvirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_color_map.html b/ThirdParty/Qwt/doc/html/class_qwt_color_map.html new file mode 100644 index 0000000000..250ce5d80e --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_color_map.html @@ -0,0 +1,369 @@ + + + + + + +Qwt User's Guide: QwtColorMap Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtColorMap Class Referenceabstract
+
+
+ +

QwtColorMap is used to map values into colors. + More...

+ +

#include <qwt_color_map.h>

+
+Inheritance diagram for QwtColorMap:
+
+
Inheritance graph
+ + +
[legend]
+ + + + +

+Public Types

enum  Format { RGB, +Indexed + }
 
+ + + + + + + + + + + + + + + + + +

+Public Member Functions

QwtColorMap (Format=QwtColorMap::RGB)
 Constructor.
 
+virtual ~QwtColorMap ()
 Destructor.
 
Format format () const
 
virtual QRgb rgb (const QwtInterval &interval, double value) const =0
 
virtual unsigned char colorIndex (const QwtInterval &interval, double value) const =0
 
QColor color (const QwtInterval &, double value) const
 
virtual QVector< QRgb > colorTable (const QwtInterval &) const
 
+

Detailed Description

+

QwtColorMap is used to map values into colors.

+

For displaying 3D data on a 2D plane the 3rd dimension is often displayed using colors, like f.e in a spectrogram.

+

Each color map is optimized to return colors for only one of the following image formats:

+
    +
  • QImage::Format_Indexed8
    +
  • +
  • QImage::Format_ARGB32
    +
  • +
+
See Also
QwtPlotSpectrogram, QwtScaleWidget
+

Member Enumeration Documentation

+ +
+
+ + + + +
enum QwtColorMap::Format
+
+

Format for color mapping

+
See Also
rgb(), colorIndex(), colorTable()
+ + + +
Enumerator
RGB  +

The map is intended to map into RGB values.

+
Indexed  +

The map is intended to map into 8 bit values, that are indices into the color table.

+
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
QColor QwtColorMap::color (const QwtIntervalinterval,
double value 
) const
+
+inline
+
+

Map a value into a color

+
Parameters
+ + + +
intervalValid interval for values
valueValue
+
+
+
Returns
Color corresponding to value
+
Warning
This method is slow for Indexed color maps. If it is necessary to map many values, its better to get the color table once and find the color using colorIndex().
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
virtual unsigned char QwtColorMap::colorIndex (const QwtIntervalinterval,
double value 
) const
+
+pure virtual
+
+

Map a value of a given interval into a color index

+
Parameters
+ + + +
intervalRange for the values
valueValue
+
+
+
Returns
color index, corresponding to value
+ +

Implemented in QwtLinearColorMap.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
QVector< QRgb > QwtColorMap::colorTable (const QwtIntervalinterval) const
+
+virtual
+
+

Build and return a color map of 256 colors

+

The color table is needed for rendering indexed images in combination with using colorIndex().

+
Parameters
+ + +
intervalRange for the values
+
+
+
Returns
A color table, that can be used for a QImage
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
QwtColorMap::Format QwtColorMap::format () const
+
+inline
+
+
Returns
Intended format of the color map
+
See Also
Format
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
virtual QRgb QwtColorMap::rgb (const QwtIntervalinterval,
double value 
) const
+
+pure virtual
+
+

Map a value of a given interval into a RGB value.

+
Parameters
+ + + +
intervalRange for the values
valueValue
+
+
+
Returns
RGB value, corresponding to value
+ +

Implemented in QwtAlphaColorMap, and QwtLinearColorMap.

+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_color_map__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_color_map__inherit__graph.map new file mode 100644 index 0000000000..7ffbe1e900 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_color_map__inherit__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_color_map__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_color_map__inherit__graph.md5 new file mode 100644 index 0000000000..6cc9e6673a --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_color_map__inherit__graph.md5 @@ -0,0 +1 @@ +114438c4b2df17fe9e3995c6ef9d1490 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_color_map__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_color_map__inherit__graph.png new file mode 100644 index 0000000000..790848d6a2 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_color_map__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_column_rect-members.html b/ThirdParty/Qwt/doc/html/class_qwt_column_rect-members.html new file mode 100644 index 0000000000..982c244efb --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_column_rect-members.html @@ -0,0 +1,111 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtColumnRect Member List
+
+
+ +

This is the complete list of members for QwtColumnRect, including all inherited members.

+ + + + + + + + + + + + +
BottomToTop enum valueQwtColumnRect
directionQwtColumnRect
Direction enum nameQwtColumnRect
hIntervalQwtColumnRect
LeftToRight enum valueQwtColumnRect
orientation() const QwtColumnRectinline
QwtColumnRect()QwtColumnRectinline
RightToLeft enum valueQwtColumnRect
TopToBottom enum valueQwtColumnRect
toRect() const QwtColumnRectinline
vIntervalQwtColumnRect
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_column_rect.html b/ThirdParty/Qwt/doc/html/class_qwt_column_rect.html new file mode 100644 index 0000000000..2ad93c7b30 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_column_rect.html @@ -0,0 +1,224 @@ + + + + + + +Qwt User's Guide: QwtColumnRect Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtColumnRect Class Reference
+
+
+ +

Directed rectangle representing bounding rectangle and orientation of a column. + More...

+ +

#include <qwt_column_symbol.h>

+ + + + + +

+Public Types

enum  Direction { LeftToRight, +RightToLeft, +BottomToTop, +TopToBottom + }
 Direction of the column. More...
 
+ + + + + + + + +

+Public Member Functions

QwtColumnRect ()
 Build an rectangle with invalid intervals directed BottomToTop.
 
QRectF toRect () const
 
Qt::Orientation orientation () const
 
+ + + + + + + + + + +

+Public Attributes

+QwtInterval hInterval
 Interval for the horizontal coordinates.
 
+QwtInterval vInterval
 Interval for the vertical coordinates.
 
+Direction direction
 Direction.
 
+

Detailed Description

+

Directed rectangle representing bounding rectangle and orientation of a column.

+

Member Enumeration Documentation

+ +
+
+ + + + +
enum QwtColumnRect::Direction
+
+ +

Direction of the column.

+ + + + + +
Enumerator
LeftToRight  +

From left to right.

+
RightToLeft  +

From right to left.

+
BottomToTop  +

From bottom to top.

+
TopToBottom  +

From top to bottom.

+
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + +
Qt::Orientation QwtColumnRect::orientation () const
+
+inline
+
+
Returns
Orientation
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
QRectF QwtColumnRect::toRect () const
+
+inline
+
+
Returns
A normalized QRect built from the intervals
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_column_symbol-members.html b/ThirdParty/Qwt/doc/html/class_qwt_column_symbol-members.html new file mode 100644 index 0000000000..acd13a6f71 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_column_symbol-members.html @@ -0,0 +1,120 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtColumnSymbol Member List
+
+
+ +

This is the complete list of members for QwtColumnSymbol, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + +
Box enum valueQwtColumnSymbol
draw(QPainter *, const QwtColumnRect &) const QwtColumnSymbolvirtual
drawBox(QPainter *, const QwtColumnRect &) const QwtColumnSymbolprotected
FrameStyle enum nameQwtColumnSymbol
frameStyle() const QwtColumnSymbol
lineWidth() const QwtColumnSymbol
NoFrame enum valueQwtColumnSymbol
NoStyle enum valueQwtColumnSymbol
palette() const QwtColumnSymbol
Plain enum valueQwtColumnSymbol
QwtColumnSymbol(Style=NoStyle)QwtColumnSymbol
Raised enum valueQwtColumnSymbol
setFrameStyle(FrameStyle style)QwtColumnSymbol
setLineWidth(int width)QwtColumnSymbol
setPalette(const QPalette &)QwtColumnSymbol
setStyle(Style)QwtColumnSymbol
style() const QwtColumnSymbol
Style enum nameQwtColumnSymbol
UserStyle enum valueQwtColumnSymbol
~QwtColumnSymbol()QwtColumnSymbolvirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_column_symbol.html b/ThirdParty/Qwt/doc/html/class_qwt_column_symbol.html new file mode 100644 index 0000000000..a57ff7b287 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_column_symbol.html @@ -0,0 +1,482 @@ + + + + + + +Qwt User's Guide: QwtColumnSymbol Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+ +
+ +

A drawing primitive for columns. + More...

+ +

#include <qwt_column_symbol.h>

+ + + + + + +

+Public Types

enum  Style { NoStyle = -1, +Box, +UserStyle = 1000 + }
 
enum  FrameStyle { NoFrame, +Plain, +Raised + }
 
+ + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 QwtColumnSymbol (Style=NoStyle)
 
+virtual ~QwtColumnSymbol ()
 Destructor.
 
void setFrameStyle (FrameStyle style)
 
FrameStyle frameStyle () const
 
void setLineWidth (int width)
 
int lineWidth () const
 
void setPalette (const QPalette &)
 
const QPalette & palette () const
 
void setStyle (Style)
 
Style style () const
 
virtual void draw (QPainter *, const QwtColumnRect &) const
 
+ + + +

+Protected Member Functions

void drawBox (QPainter *, const QwtColumnRect &) const
 
+

Detailed Description

+

A drawing primitive for columns.

+

Member Enumeration Documentation

+ +
+
+ + + + +
enum QwtColumnSymbol::FrameStyle
+
+

Frame Style used in Box style().

+
See Also
Style, setFrameStyle(), frameStyle(), setStyle(), setPalette()
+ + + + +
Enumerator
NoFrame  +

No frame.

+
Plain  +

A plain frame style.

+
Raised  +

A raised frame style.

+
+ +
+
+ +
+
+ + + + +
enum QwtColumnSymbol::Style
+
+

Style

+
See Also
setStyle(), style()
+ + + + +
Enumerator
NoStyle  +

No Style, the symbol draws nothing.

+
Box  +

The column is painted with a frame depending on the frameStyle() and lineWidth() using the palette().

+
UserStyle  +

Styles >= QwtColumnSymbol::UserStyle are reserved for derived classes of QwtColumnSymbol that overload draw() with additional application specific symbol types.

+
+ +
+
+

Constructor & Destructor Documentation

+ +
+
+ + + + + + + + +
QwtColumnSymbol::QwtColumnSymbol (Style style = NoStyle)
+
+

Constructor

+
Parameters
+ + +
styleStyle of the symbol
+
+
+
See Also
setStyle(), style(), Style
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void QwtColumnSymbol::draw (QPainter * painter,
const QwtColumnRectrect 
) const
+
+virtual
+
+

Draw the symbol depending on its style.

+
Parameters
+ + + +
painterPainter
rectDirected rectangle
+
+
+
See Also
drawBox()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void QwtColumnSymbol::drawBox (QPainter * painter,
const QwtColumnRectrect 
) const
+
+protected
+
+

Draw the symbol when it is in Box style.

+
Parameters
+ + + +
painterPainter
rectDirected rectangle
+
+
+
See Also
draw()
+ +
+
+ +
+
+ + + + + + + +
QwtColumnSymbol::FrameStyle QwtColumnSymbol::frameStyle () const
+
+
Returns
Current frame style, that is used for the Box style.
+
See Also
setFrameStyle(), lineWidth(), setStyle()
+ +
+
+ +
+
+ + + + + + + +
int QwtColumnSymbol::lineWidth () const
+
+
Returns
Line width of the frame, that is used for the Box style.
+
See Also
setLineWidth(), frameStyle(), setStyle()
+ +
+
+ +
+
+ + + + + + + +
const QPalette & QwtColumnSymbol::palette () const
+
+
Returns
Current palette
+
See Also
setPalette()
+ +
+
+ +
+
+ + + + + + + + +
void QwtColumnSymbol::setFrameStyle (FrameStyle frameStyle)
+
+

Set the frame, that is used for the Box style.

+
Parameters
+ + +
frameStyleFrame style
+
+
+
See Also
frameStyle(), setLineWidth(), setStyle()
+ +
+
+ +
+
+ + + + + + + + +
void QwtColumnSymbol::setLineWidth (int width)
+
+

Set the line width of the frame, that is used for the Box style.

+
Parameters
+ + +
widthWidth
+
+
+
See Also
lineWidth(), setFrameStyle()
+ +
+
+ +
+
+ + + + + + + + +
void QwtColumnSymbol::setPalette (const QPalette & palette)
+
+

Assign a palette for the symbol

+
Parameters
+ + +
palettePalette
+
+
+
See Also
palette(), setStyle()
+ +
+
+ +
+
+ + + + + + + + +
void QwtColumnSymbol::setStyle (Style style)
+
+

Specify the symbol style

+
Parameters
+ + +
styleStyle
+
+
+
See Also
style(), setPalette()
+ +
+
+ +
+
+ + + + + + + +
QwtColumnSymbol::Style QwtColumnSymbol::style () const
+
+
Returns
Current symbol style
+
See Also
setStyle()
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_compass-members.html b/ThirdParty/Qwt/doc/html/class_qwt_compass-members.html new file mode 100644 index 0000000000..b39e9195f1 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_compass-members.html @@ -0,0 +1,214 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtCompass Member List
+
+
+ +

This is the complete list of members for QwtCompass, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
abstractScaleDraw() const QwtAbstractScaleprotected
abstractScaleDraw()QwtAbstractScaleprotected
boundingRect() const QwtDial
changeEvent(QEvent *)QwtDialprotectedvirtual
drawContents(QPainter *) const QwtDialprotectedvirtual
drawFocusIndicator(QPainter *) const QwtDialprotectedvirtual
drawFrame(QPainter *p)QwtDialprotectedvirtual
drawNeedle(QPainter *, const QPointF &, double radius, double direction, QPalette::ColorGroup) const QwtDialprotectedvirtual
drawRose(QPainter *, const QPointF &center, double radius, double north, QPalette::ColorGroup) const QwtCompassprotectedvirtual
drawScale(QPainter *, const QPointF &center, double radius) const QwtDialprotectedvirtual
drawScaleContents(QPainter *, const QPointF &center, double radius) const QwtCompassprotectedvirtual
frameShadow() const QwtDial
incrementedValue(double value, int stepCount) const QwtAbstractSliderprotected
incrementValue(int numSteps)QwtAbstractSliderprotected
innerRect() const QwtDial
invalidateCache()QwtDialprotected
invertedControls() const QwtAbstractSlider
invTransform(int) const QwtAbstractScale
isInverted() const QwtAbstractScale
isReadOnly() const QwtAbstractSlider
isScrollPosition(const QPoint &) const QwtDialprotectedvirtual
isTracking() const QwtAbstractSlider
isValid() const QwtAbstractSlider
keyPressEvent(QKeyEvent *)QwtCompassprotectedvirtual
lineWidth() const QwtDial
lowerBound() const QwtAbstractScale
maximum() const QwtAbstractScale
maxScaleArc() const QwtDial
minimum() const QwtAbstractScale
minimumSizeHint() const QwtDialvirtual
minScaleArc() const QwtDial
Mode enum nameQwtDial
mode() const QwtDial
mouseMoveEvent(QMouseEvent *)QwtAbstractSliderprotectedvirtual
mousePressEvent(QMouseEvent *)QwtAbstractSliderprotectedvirtual
mouseReleaseEvent(QMouseEvent *)QwtAbstractSliderprotectedvirtual
needle() const QwtDial
needle()QwtDial
origin() const QwtDial
pageSteps() const QwtAbstractSlider
paintEvent(QPaintEvent *)QwtDialprotectedvirtual
Plain enum valueQwtDial
QwtAbstractScale(QWidget *parent=NULL)QwtAbstractScale
QwtAbstractSlider(QWidget *parent=NULL)QwtAbstractSliderexplicit
QwtCompass(QWidget *parent=NULL)QwtCompassexplicit
QwtDial(QWidget *parent=NULL)QwtDialexplicit
Raised enum valueQwtDial
rescale(double lowerBound, double upperBound, double stepSize)QwtAbstractScaleprotected
rose() const QwtCompass
rose()QwtCompass
RotateNeedle enum valueQwtDial
RotateScale enum valueQwtDial
scaleChange()QwtDialprotectedvirtual
scaleDiv() const QwtAbstractScale
scaleDraw()QwtDial
scaleDraw() const QwtDial
scaleEngine() const QwtAbstractScale
scaleEngine()QwtAbstractScale
scaleInnerRect() const QwtDialvirtual
scaleMap() const QwtAbstractScale
scaleMaxMajor() const QwtAbstractScale
scaleMaxMinor() const QwtAbstractScale
scaleStepSize() const QwtAbstractScale
scrolledTo(const QPoint &) const QwtDialprotectedvirtual
setAbstractScaleDraw(QwtAbstractScaleDraw *)QwtAbstractScaleprotected
setFrameShadow(Shadow)QwtDial
setInvertedControls(bool)QwtAbstractSlider
setLineWidth(int)QwtDial
setLowerBound(double value)QwtAbstractScale
setMaxScaleArc(double min)QwtDial
setMinScaleArc(double min)QwtDial
setMode(Mode)QwtDial
setNeedle(QwtDialNeedle *)QwtDial
setOrigin(double)QwtDialvirtual
setPageSteps(uint)QwtAbstractSlider
setReadOnly(bool)QwtAbstractSlider
setRose(QwtCompassRose *rose)QwtCompass
setScale(double lowerBound, double upperBound)QwtAbstractScale
setScale(const QwtInterval &)QwtAbstractScale
setScale(const QwtScaleDiv &)QwtAbstractScale
setScaleArc(double min, double max)QwtDial
setScaleDraw(QwtRoundScaleDraw *)QwtDial
setScaleEngine(QwtScaleEngine *)QwtAbstractScale
setScaleMaxMajor(int ticks)QwtAbstractScale
setScaleMaxMinor(int ticks)QwtAbstractScale
setScaleStepSize(double stepSize)QwtAbstractScale
setSingleSteps(uint)QwtAbstractSlider
setStepAlignment(bool)QwtAbstractSlider
setTotalSteps(uint)QwtAbstractSlider
setTracking(bool)QwtAbstractSlider
setUpperBound(double value)QwtAbstractScale
setValid(bool)QwtAbstractSlider
setValue(double val)QwtAbstractSliderslot
setWrapping(bool)QwtAbstractSlider
Shadow enum nameQwtDial
singleSteps() const QwtAbstractSlider
sizeHint() const QwtDialvirtual
sliderChange()QwtDialprotectedvirtual
sliderMoved(double value)QwtAbstractSlidersignal
sliderPressed()QwtAbstractSlidersignal
sliderReleased()QwtAbstractSlidersignal
stepAlignment() const QwtAbstractSlider
Sunken enum valueQwtDial
totalSteps() const QwtAbstractSlider
transform(double) const QwtAbstractScale
upperBound() const QwtAbstractScale
value() const QwtAbstractSlider
valueChanged(double value)QwtAbstractSlidersignal
wheelEvent(QWheelEvent *)QwtDialprotectedvirtual
wrapping() const QwtAbstractSlider
~QwtAbstractScale()QwtAbstractScalevirtual
~QwtAbstractSlider()QwtAbstractSlidervirtual
~QwtCompass()QwtCompassvirtual
~QwtDial()QwtDialvirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_compass.html b/ThirdParty/Qwt/doc/html/class_qwt_compass.html new file mode 100644 index 0000000000..7d886b3677 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_compass.html @@ -0,0 +1,635 @@ + + + + + + +Qwt User's Guide: QwtCompass Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+ +
+ +

A Compass Widget. + More...

+ +

#include <qwt_compass.h>

+
+Inheritance diagram for QwtCompass:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 QwtCompass (QWidget *parent=NULL)
 Constructor. More...
 
+virtual ~QwtCompass ()
 Destructor.
 
void setRose (QwtCompassRose *rose)
 
const QwtCompassRoserose () const
 
QwtCompassRoserose ()
 
- Public Member Functions inherited from QwtDial
 QwtDial (QWidget *parent=NULL)
 Constructor. More...
 
+virtual ~QwtDial ()
 Destructor.
 
void setFrameShadow (Shadow)
 
Shadow frameShadow () const
 
void setLineWidth (int)
 
int lineWidth () const
 
void setMode (Mode)
 Change the mode of the dial. More...
 
Mode mode () const
 
void setScaleArc (double min, double max)
 
void setMinScaleArc (double min)
 
double minScaleArc () const
 
void setMaxScaleArc (double min)
 
double maxScaleArc () const
 
virtual void setOrigin (double)
 Change the origin. More...
 
double origin () const
 
void setNeedle (QwtDialNeedle *)
 
const QwtDialNeedleneedle () const
 
QwtDialNeedleneedle ()
 
QRect boundingRect () const
 
QRect innerRect () const
 
virtual QRect scaleInnerRect () const
 
virtual QSize sizeHint () const
 
virtual QSize minimumSizeHint () const
 
void setScaleDraw (QwtRoundScaleDraw *)
 
QwtRoundScaleDrawscaleDraw ()
 
const QwtRoundScaleDrawscaleDraw () const
 
- Public Member Functions inherited from QwtAbstractSlider
 QwtAbstractSlider (QWidget *parent=NULL)
 Constructor. More...
 
+virtual ~QwtAbstractSlider ()
 Destructor.
 
void setValid (bool)
 
bool isValid () const
 
+double value () const
 Returns the current value.
 
void setWrapping (bool)
 
bool wrapping () const
 
void setTotalSteps (uint)
 Set the number of steps. More...
 
uint totalSteps () const
 
void setSingleSteps (uint)
 Set the number of steps for a single increment. More...
 
uint singleSteps () const
 
void setPageSteps (uint)
 Set the number of steps for a page increment. More...
 
uint pageSteps () const
 
void setStepAlignment (bool)
 Enable step alignment. More...
 
bool stepAlignment () const
 
void setTracking (bool)
 Enables or disables tracking. More...
 
bool isTracking () const
 
void setReadOnly (bool)
 
bool isReadOnly () const
 
void setInvertedControls (bool)
 
bool invertedControls () const
 
- Public Member Functions inherited from QwtAbstractScale
 QwtAbstractScale (QWidget *parent=NULL)
 
+virtual ~QwtAbstractScale ()
 Destructor.
 
void setScale (double lowerBound, double upperBound)
 Specify a scale. More...
 
void setScale (const QwtInterval &)
 Specify a scale. More...
 
void setScale (const QwtScaleDiv &)
 Specify a scale. More...
 
const QwtScaleDivscaleDiv () const
 
void setLowerBound (double value)
 
double lowerBound () const
 
void setUpperBound (double value)
 
double upperBound () const
 
void setScaleStepSize (double stepSize)
 Set the step size used for calculating a scale division. More...
 
double scaleStepSize () const
 
void setScaleMaxMajor (int ticks)
 Set the maximum number of major tick intervals. More...
 
int scaleMaxMinor () const
 
void setScaleMaxMinor (int ticks)
 Set the maximum number of minor tick intervals. More...
 
int scaleMaxMajor () const
 
void setScaleEngine (QwtScaleEngine *)
 Set a scale engine. More...
 
const QwtScaleEnginescaleEngine () const
 
QwtScaleEnginescaleEngine ()
 
int transform (double) const
 
double invTransform (int) const
 
bool isInverted () const
 
double minimum () const
 
double maximum () const
 
const QwtScaleMapscaleMap () const
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Protected Member Functions

virtual void drawRose (QPainter *, const QPointF &center, double radius, double north, QPalette::ColorGroup) const
 
virtual void drawScaleContents (QPainter *, const QPointF &center, double radius) const
 
virtual void keyPressEvent (QKeyEvent *)
 
- Protected Member Functions inherited from QwtDial
virtual void wheelEvent (QWheelEvent *)
 
virtual void paintEvent (QPaintEvent *)
 
virtual void changeEvent (QEvent *)
 
virtual void drawFrame (QPainter *p)
 
virtual void drawContents (QPainter *) const
 Draw the contents inside the frame. More...
 
virtual void drawFocusIndicator (QPainter *) const
 
void invalidateCache ()
 
virtual void drawScale (QPainter *, const QPointF &center, double radius) const
 
virtual void drawNeedle (QPainter *, const QPointF &, double radius, double direction, QPalette::ColorGroup) const
 
virtual double scrolledTo (const QPoint &) const
 Determine the value for a new position of the slider handle. More...
 
virtual bool isScrollPosition (const QPoint &) const
 Determine what to do when the user presses a mouse button. More...
 
+virtual void sliderChange ()
 Calling update()
 
virtual void scaleChange ()
 
- Protected Member Functions inherited from QwtAbstractSlider
virtual void mousePressEvent (QMouseEvent *)
 
virtual void mouseReleaseEvent (QMouseEvent *)
 
virtual void mouseMoveEvent (QMouseEvent *)
 
void incrementValue (int numSteps)
 
double incrementedValue (double value, int stepCount) const
 
- Protected Member Functions inherited from QwtAbstractScale
void rescale (double lowerBound, double upperBound, double stepSize)
 
void setAbstractScaleDraw (QwtAbstractScaleDraw *)
 Set a scale draw. More...
 
const QwtAbstractScaleDrawabstractScaleDraw () const
 
QwtAbstractScaleDrawabstractScaleDraw ()
 
+ + + + + + + + + + + + + + + + + + + + + +

+Additional Inherited Members

- Public Types inherited from QwtDial
enum  Shadow { Plain = QFrame::Plain, +Raised = QFrame::Raised, +Sunken = QFrame::Sunken + }
 Frame shadow. More...
 
enum  Mode { RotateNeedle, +RotateScale + }
 Mode controlling whether the needle or the scale is rotating. More...
 
- Public Slots inherited from QwtAbstractSlider
void setValue (double val)
 
- Signals inherited from QwtAbstractSlider
void valueChanged (double value)
 Notify a change of value. More...
 
void sliderPressed ()
 
void sliderReleased ()
 
void sliderMoved (double value)
 
+

Detailed Description

+

A Compass Widget.

+

QwtCompass is a widget to display and enter directions. It consists of a scale, an optional needle and rose.

+
+dials1.png +
+
Note
The examples/dials example shows how to use QwtCompass.
+

Constructor & Destructor Documentation

+ +
+
+ + + + + +
+ + + + + + + + +
QwtCompass::QwtCompass (QWidget * parent = NULL)
+
+explicit
+
+ +

Constructor.

+
Parameters
+ + +
parentParent widget
+
+
+

Create a compass widget with a scale, no needle and no rose. The default origin is 270.0 with no valid value. It accepts mouse and keyboard inputs and has no step size. The default mode is QwtDial::RotateNeedle.

+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void QwtCompass::drawRose (QPainter * painter,
const QPointF & center,
double radius,
double north,
QPalette::ColorGroup cg 
) const
+
+protectedvirtual
+
+

Draw the compass rose

+
Parameters
+ + + + + + +
painterPainter
centerCenter of the compass
radiusof the circle, where to paint the rose
northDirection pointing north, in degrees counter clockwise
cgColor group
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
void QwtCompass::drawScaleContents (QPainter * painter,
const QPointF & center,
double radius 
) const
+
+protectedvirtual
+
+

Draw the contents of the scale

+
Parameters
+ + + + +
painterPainter
centerCenter of the content circle
radiusRadius of the content circle
+
+
+ +

Reimplemented from QwtDial.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtCompass::keyPressEvent (QKeyEvent * kev)
+
+protectedvirtual
+
+

Handles key events

+

Beside the keys described in QwtDial::keyPressEvent numbers from 1-9 (without 5) set the direction according to their position on the num pad.

+
See Also
isReadOnly()
+ +

Reimplemented from QwtAbstractSlider.

+ +
+
+ +
+
+ + + + + + + +
const QwtCompassRose * QwtCompass::rose () const
+
+
Returns
rose
+
See Also
setRose()
+ +
+
+ +
+
+ + + + + + + +
QwtCompassRose * QwtCompass::rose ()
+
+
Returns
rose
+
See Also
setRose()
+ +
+
+ +
+
+ + + + + + + + +
void QwtCompass::setRose (QwtCompassRoserose)
+
+

Set a rose for the compass

+
Parameters
+ + +
roseCompass rose
+
+
+
Warning
The rose will be deleted, when a different rose is set or in ~QwtCompass
+
See Also
rose()
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_compass__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_compass__inherit__graph.map new file mode 100644 index 0000000000..aec155b7a9 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_compass__inherit__graph.map @@ -0,0 +1,5 @@ + + + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_compass__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_compass__inherit__graph.md5 new file mode 100644 index 0000000000..4b5591aa43 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_compass__inherit__graph.md5 @@ -0,0 +1 @@ +f3474b509f8f0ccdfdc322b532c6e516 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_compass__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_compass__inherit__graph.png new file mode 100644 index 0000000000..ebec176a26 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_compass__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_compass_magnet_needle-members.html b/ThirdParty/Qwt/doc/html/class_qwt_compass_magnet_needle-members.html new file mode 100644 index 0000000000..5b091db1f2 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_compass_magnet_needle-members.html @@ -0,0 +1,111 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtCompassMagnetNeedle Member List
+
+
+ +

This is the complete list of members for QwtCompassMagnetNeedle, including all inherited members.

+ + + + + + + + + + + + +
draw(QPainter *painter, const QPointF &center, double length, double direction, QPalette::ColorGroup=QPalette::Active) const QwtDialNeedlevirtual
drawKnob(QPainter *, double width, const QBrush &, bool sunken) const QwtDialNeedleprotectedvirtual
drawNeedle(QPainter *, double length, QPalette::ColorGroup) const QwtCompassMagnetNeedleprotectedvirtual
palette() const QwtDialNeedle
QwtCompassMagnetNeedle(Style=TriangleStyle, const QColor &light=Qt::white, const QColor &dark=Qt::red)QwtCompassMagnetNeedle
QwtDialNeedle()QwtDialNeedle
setPalette(const QPalette &)QwtDialNeedlevirtual
Style enum nameQwtCompassMagnetNeedle
ThinStyle enum valueQwtCompassMagnetNeedle
TriangleStyle enum valueQwtCompassMagnetNeedle
~QwtDialNeedle()QwtDialNeedlevirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_compass_magnet_needle.html b/ThirdParty/Qwt/doc/html/class_qwt_compass_magnet_needle.html new file mode 100644 index 0000000000..f514413bae --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_compass_magnet_needle.html @@ -0,0 +1,243 @@ + + + + + + +Qwt User's Guide: QwtCompassMagnetNeedle Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtCompassMagnetNeedle Class Reference
+
+
+ +

A magnet needle for compass widgets. + More...

+ +

#include <qwt_dial_needle.h>

+
+Inheritance diagram for QwtCompassMagnetNeedle:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + +

+Public Types

enum  Style { TriangleStyle, +ThinStyle + }
 Style of the needle. More...
 
+ + + + + + + + + + + + + + + + + +

+Public Member Functions

QwtCompassMagnetNeedle (Style=TriangleStyle, const QColor &light=Qt::white, const QColor &dark=Qt::red)
 Constructor.
 
- Public Member Functions inherited from QwtDialNeedle
QwtDialNeedle ()
 Constructor.
 
+virtual ~QwtDialNeedle ()
 Destructor.
 
virtual void setPalette (const QPalette &)
 
const QPalette & palette () const
 
virtual void draw (QPainter *painter, const QPointF &center, double length, double direction, QPalette::ColorGroup=QPalette::Active) const
 
+ + + + + + + +

+Protected Member Functions

virtual void drawNeedle (QPainter *, double length, QPalette::ColorGroup) const
 
- Protected Member Functions inherited from QwtDialNeedle
+virtual void drawKnob (QPainter *, double width, const QBrush &, bool sunken) const
 Draw the knob.
 
+

Detailed Description

+

A magnet needle for compass widgets.

+

A magnet needle points to two opposite directions indicating north and south.

+

The following colors are used:

+
    +
  • QPalette::Light
    + Used for pointing south
  • +
  • QPalette::Dark
    + Used for pointing north
  • +
  • QPalette::Base
    + Knob (ThinStyle only)
  • +
+
See Also
QwtDial, QwtCompass
+

Member Enumeration Documentation

+ +
+
+ +

Style of the needle.

+ + + +
Enumerator
TriangleStyle  +

A needle with a triangular shape.

+
ThinStyle  +

A thin needle.

+
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
void QwtCompassMagnetNeedle::drawNeedle (QPainter * painter,
double length,
QPalette::ColorGroup colorGroup 
) const
+
+protectedvirtual
+
+

Draw the needle

+
Parameters
+ + + + +
painterPainter
lengthLength of the needle
colorGroupColor group, used for painting
+
+
+ +

Implements QwtDialNeedle.

+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_compass_magnet_needle__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_compass_magnet_needle__inherit__graph.map new file mode 100644 index 0000000000..55df14d70e --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_compass_magnet_needle__inherit__graph.map @@ -0,0 +1,3 @@ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_compass_magnet_needle__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_compass_magnet_needle__inherit__graph.md5 new file mode 100644 index 0000000000..d68ff4e349 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_compass_magnet_needle__inherit__graph.md5 @@ -0,0 +1 @@ +16e333e639ba76a7effc85625f501101 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_compass_magnet_needle__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_compass_magnet_needle__inherit__graph.png new file mode 100644 index 0000000000..347675df74 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_compass_magnet_needle__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_compass_rose-members.html b/ThirdParty/Qwt/doc/html/class_qwt_compass_rose-members.html new file mode 100644 index 0000000000..7e5050e889 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_compass_rose-members.html @@ -0,0 +1,104 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtCompassRose Member List
+
+
+ +

This is the complete list of members for QwtCompassRose, including all inherited members.

+ + + + + +
draw(QPainter *painter, const QPointF &center, double radius, double north, QPalette::ColorGroup colorGroup=QPalette::Active) const =0QwtCompassRosepure virtual
palette() const QwtCompassRoseinline
setPalette(const QPalette &p)QwtCompassRoseinlinevirtual
~QwtCompassRose()QwtCompassRoseinlinevirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_compass_rose.html b/ThirdParty/Qwt/doc/html/class_qwt_compass_rose.html new file mode 100644 index 0000000000..313e07655c --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_compass_rose.html @@ -0,0 +1,220 @@ + + + + + + +Qwt User's Guide: QwtCompassRose Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtCompassRose Class Referenceabstract
+
+
+ +

Abstract base class for a compass rose. + More...

+ +

#include <qwt_compass_rose.h>

+
+Inheritance diagram for QwtCompassRose:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + + + + + +

+Public Member Functions

+virtual ~QwtCompassRose ()
 Destructor.
 
+virtual void setPalette (const QPalette &p)
 Assign a palette.
 
const QPalette & palette () const
 
virtual void draw (QPainter *painter, const QPointF &center, double radius, double north, QPalette::ColorGroup colorGroup=QPalette::Active) const =0
 
+

Detailed Description

+

Abstract base class for a compass rose.

+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
virtual void QwtCompassRose::draw (QPainter * painter,
const QPointF & center,
double radius,
double north,
QPalette::ColorGroup colorGroup = QPalette::Active 
) const
+
+pure virtual
+
+

Draw the rose

+
Parameters
+ + + + + + +
painterPainter
centerCenter point
radiusRadius of the rose
northPosition
colorGroupColor group
+
+
+ +

Implemented in QwtSimpleCompassRose.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
const QPalette& QwtCompassRose::palette () const
+
+inline
+
+
Returns
Current palette
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_compass_rose__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_compass_rose__inherit__graph.map new file mode 100644 index 0000000000..aa0b600e8a --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_compass_rose__inherit__graph.map @@ -0,0 +1,3 @@ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_compass_rose__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_compass_rose__inherit__graph.md5 new file mode 100644 index 0000000000..7c4f61349c --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_compass_rose__inherit__graph.md5 @@ -0,0 +1 @@ +8d006b225309c3afaaed62e34fe68691 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_compass_rose__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_compass_rose__inherit__graph.png new file mode 100644 index 0000000000..5e71f40df7 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_compass_rose__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_compass_scale_draw-members.html b/ThirdParty/Qwt/doc/html/class_qwt_compass_scale_draw-members.html new file mode 100644 index 0000000000..3ae8f70dfe --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_compass_scale_draw-members.html @@ -0,0 +1,143 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtCompassScaleDraw Member List
+
+
+ +

This is the complete list of members for QwtCompassScaleDraw, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Backbone enum valueQwtAbstractScaleDraw
center() const QwtRoundScaleDraw
draw(QPainter *, const QPalette &) const QwtAbstractScaleDrawvirtual
drawBackbone(QPainter *) const QwtRoundScaleDrawprotectedvirtual
drawLabel(QPainter *, double val) const QwtRoundScaleDrawprotectedvirtual
drawTick(QPainter *, double val, double len) const QwtRoundScaleDrawprotectedvirtual
enableComponent(ScaleComponent, bool enable=true)QwtAbstractScaleDraw
extent(const QFont &) const QwtRoundScaleDrawvirtual
hasComponent(ScaleComponent) const QwtAbstractScaleDraw
invalidateCache()QwtAbstractScaleDrawprotected
label(double value) const QwtCompassScaleDrawvirtual
labelMap() const QwtCompassScaleDraw
Labels enum valueQwtAbstractScaleDraw
maxTickLength() const QwtAbstractScaleDraw
minimumExtent() const QwtAbstractScaleDraw
moveCenter(double x, double y)QwtRoundScaleDrawinline
moveCenter(const QPointF &)QwtRoundScaleDraw
penWidth() const QwtAbstractScaleDraw
QwtAbstractScaleDraw()QwtAbstractScaleDraw
QwtCompassScaleDraw()QwtCompassScaleDrawexplicit
QwtCompassScaleDraw(const QMap< double, QString > &map)QwtCompassScaleDrawexplicit
QwtRoundScaleDraw()QwtRoundScaleDraw
radius() const QwtRoundScaleDraw
ScaleComponent enum nameQwtAbstractScaleDraw
ScaleComponents typedefQwtAbstractScaleDraw
scaleDiv() const QwtAbstractScaleDraw
scaleMap() const QwtAbstractScaleDraw
scaleMap()QwtAbstractScaleDraw
setAngleRange(double angle1, double angle2)QwtRoundScaleDraw
setLabelMap(const QMap< double, QString > &map)QwtCompassScaleDraw
setMinimumExtent(double)QwtAbstractScaleDraw
setPenWidth(int width)QwtAbstractScaleDraw
setRadius(double radius)QwtRoundScaleDraw
setScaleDiv(const QwtScaleDiv &s)QwtAbstractScaleDraw
setSpacing(double margin)QwtAbstractScaleDraw
setTickLength(QwtScaleDiv::TickType, double length)QwtAbstractScaleDraw
setTransformation(QwtTransform *)QwtAbstractScaleDraw
spacing() const QwtAbstractScaleDraw
tickLabel(const QFont &, double value) const QwtAbstractScaleDrawprotected
tickLength(QwtScaleDiv::TickType) const QwtAbstractScaleDraw
Ticks enum valueQwtAbstractScaleDraw
~QwtAbstractScaleDraw()QwtAbstractScaleDrawvirtual
~QwtRoundScaleDraw()QwtRoundScaleDrawvirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_compass_scale_draw.html b/ThirdParty/Qwt/doc/html/class_qwt_compass_scale_draw.html new file mode 100644 index 0000000000..fb0b008ff0 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_compass_scale_draw.html @@ -0,0 +1,368 @@ + + + + + + +Qwt User's Guide: QwtCompassScaleDraw Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtCompassScaleDraw Class Reference
+
+
+ +

A special scale draw made for QwtCompass. + More...

+ +

#include <qwt_compass.h>

+
+Inheritance diagram for QwtCompassScaleDraw:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 QwtCompassScaleDraw ()
 Constructor. More...
 
 QwtCompassScaleDraw (const QMap< double, QString > &map)
 Constructor. More...
 
void setLabelMap (const QMap< double, QString > &map)
 Set a map, mapping values to labels. More...
 
QMap< double, QString > labelMap () const
 
virtual QwtText label (double value) const
 
- Public Member Functions inherited from QwtRoundScaleDraw
 QwtRoundScaleDraw ()
 Constructor. More...
 
+virtual ~QwtRoundScaleDraw ()
 Destructor.
 
void setRadius (double radius)
 
double radius () const
 
+void moveCenter (double x, double y)
 Move the center of the scale draw, leaving the radius unchanged.
 
void moveCenter (const QPointF &)
 
+QPointF center () const
 Get the center of the scale.
 
void setAngleRange (double angle1, double angle2)
 Adjust the baseline circle segment for round scales. More...
 
virtual double extent (const QFont &) const
 
- Public Member Functions inherited from QwtAbstractScaleDraw
 QwtAbstractScaleDraw ()
 Constructor. More...
 
+virtual ~QwtAbstractScaleDraw ()
 Destructor.
 
void setScaleDiv (const QwtScaleDiv &s)
 
const QwtScaleDivscaleDiv () const
 
void setTransformation (QwtTransform *)
 
const QwtScaleMapscaleMap () const
 
QwtScaleMapscaleMap ()
 
void enableComponent (ScaleComponent, bool enable=true)
 
bool hasComponent (ScaleComponent) const
 
void setTickLength (QwtScaleDiv::TickType, double length)
 
double tickLength (QwtScaleDiv::TickType) const
 
double maxTickLength () const
 
void setSpacing (double margin)
 Set the spacing between tick and labels. More...
 
double spacing () const
 Get the spacing. More...
 
void setPenWidth (int width)
 Specify the width of the scale pen. More...
 
int penWidth () const
 
virtual void draw (QPainter *, const QPalette &) const
 Draw the scale. More...
 
void setMinimumExtent (double)
 Set a minimum for the extent. More...
 
double minimumExtent () const
 
+ + + + + + + + + + + + + + +

+Additional Inherited Members

- Public Types inherited from QwtAbstractScaleDraw
enum  ScaleComponent { Backbone = 0x01, +Ticks = 0x02, +Labels = 0x04 + }
 
+typedef QFlags< ScaleComponentScaleComponents
 Scale components.
 
- Protected Member Functions inherited from QwtRoundScaleDraw
virtual void drawTick (QPainter *, double val, double len) const
 
virtual void drawBackbone (QPainter *) const
 
virtual void drawLabel (QPainter *, double val) const
 
+

Detailed Description

+

A special scale draw made for QwtCompass.

+

QwtCompassScaleDraw maps values to strings using a special map, that can be modified by the application

+

The default map consists of the labels N, NE, E, SE, S, SW, W, NW.

+
See Also
QwtCompass
+

Constructor & Destructor Documentation

+ +
+
+ + + + + +
+ + + + + + + +
QwtCompassScaleDraw::QwtCompassScaleDraw ()
+
+explicit
+
+ +

Constructor.

+

Initializes a label map for multiples of 45 degrees

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
QwtCompassScaleDraw::QwtCompassScaleDraw (const QMap< double, QString > & map)
+
+explicit
+
+ +

Constructor.

+
Parameters
+ + +
mapValue to label map
+
+
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + + +
QwtText QwtCompassScaleDraw::label (double value) const
+
+virtual
+
+

Map a value to a corresponding label

+
Parameters
+ + +
valueValue that will be mapped
+
+
+

label() looks in the labelMap() for a corresponding label for value or returns an null text.

+
Returns
Label, or QString::null
+
See Also
labelMap(), setLabelMap()
+ +

Reimplemented from QwtAbstractScaleDraw.

+ +
+
+ +
+
+ + + + + + + +
QMap< double, QString > QwtCompassScaleDraw::labelMap () const
+
+
Returns
map, mapping values to labels
+
See Also
setLabelMap()
+ +
+
+ +
+
+ + + + + + + + +
void QwtCompassScaleDraw::setLabelMap (const QMap< double, QString > & map)
+
+ +

Set a map, mapping values to labels.

+
Parameters
+ + +
mapValue to label map
+
+
+

The values of the major ticks are found by looking into this map. The default map consists of the labels N, NE, E, SE, S, SW, W, NW.

+
Warning
The map will have no effect for values that are no major tick values. Major ticks can be changed by QwtScaleDraw::setScale
+
See Also
labelMap(), scaleDraw(), setScale()
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_compass_scale_draw__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_compass_scale_draw__inherit__graph.map new file mode 100644 index 0000000000..49400e448f --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_compass_scale_draw__inherit__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_compass_scale_draw__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_compass_scale_draw__inherit__graph.md5 new file mode 100644 index 0000000000..86af689f59 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_compass_scale_draw__inherit__graph.md5 @@ -0,0 +1 @@ +ddef61bb22a4a7ef4d27d350aa7f9139 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_compass_scale_draw__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_compass_scale_draw__inherit__graph.png new file mode 100644 index 0000000000..2b988cd5b8 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_compass_scale_draw__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_compass_wind_arrow-members.html b/ThirdParty/Qwt/doc/html/class_qwt_compass_wind_arrow-members.html new file mode 100644 index 0000000000..b669b58c88 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_compass_wind_arrow-members.html @@ -0,0 +1,111 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtCompassWindArrow Member List
+
+
+ +

This is the complete list of members for QwtCompassWindArrow, including all inherited members.

+ + + + + + + + + + + + +
draw(QPainter *painter, const QPointF &center, double length, double direction, QPalette::ColorGroup=QPalette::Active) const QwtDialNeedlevirtual
drawKnob(QPainter *, double width, const QBrush &, bool sunken) const QwtDialNeedleprotectedvirtual
drawNeedle(QPainter *, double length, QPalette::ColorGroup) const QwtCompassWindArrowprotectedvirtual
palette() const QwtDialNeedle
QwtCompassWindArrow(Style, const QColor &light=Qt::white, const QColor &dark=Qt::gray)QwtCompassWindArrow
QwtDialNeedle()QwtDialNeedle
setPalette(const QPalette &)QwtDialNeedlevirtual
Style enum nameQwtCompassWindArrow
Style1 enum valueQwtCompassWindArrow
Style2 enum valueQwtCompassWindArrow
~QwtDialNeedle()QwtDialNeedlevirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_compass_wind_arrow.html b/ThirdParty/Qwt/doc/html/class_qwt_compass_wind_arrow.html new file mode 100644 index 0000000000..daca8a4161 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_compass_wind_arrow.html @@ -0,0 +1,280 @@ + + + + + + +Qwt User's Guide: QwtCompassWindArrow Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtCompassWindArrow Class Reference
+
+
+ +

An indicator for the wind direction. + More...

+ +

#include <qwt_dial_needle.h>

+
+Inheritance diagram for QwtCompassWindArrow:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + +

+Public Types

enum  Style { Style1, +Style2 + }
 Style of the arrow. More...
 
+ + + + + + + + + + + + + + + + +

+Public Member Functions

 QwtCompassWindArrow (Style, const QColor &light=Qt::white, const QColor &dark=Qt::gray)
 
- Public Member Functions inherited from QwtDialNeedle
QwtDialNeedle ()
 Constructor.
 
+virtual ~QwtDialNeedle ()
 Destructor.
 
virtual void setPalette (const QPalette &)
 
const QPalette & palette () const
 
virtual void draw (QPainter *painter, const QPointF &center, double length, double direction, QPalette::ColorGroup=QPalette::Active) const
 
+ + + + + + + +

+Protected Member Functions

virtual void drawNeedle (QPainter *, double length, QPalette::ColorGroup) const
 
- Protected Member Functions inherited from QwtDialNeedle
+virtual void drawKnob (QPainter *, double width, const QBrush &, bool sunken) const
 Draw the knob.
 
+

Detailed Description

+

An indicator for the wind direction.

+

QwtCompassWindArrow shows the direction where the wind comes from.

+
    +
  • QPalette::Light
    + Used for Style1, or the light half of Style2
  • +
  • QPalette::Dark
    + Used for the dark half of Style2
  • +
+
See Also
QwtDial, QwtCompass
+

Member Enumeration Documentation

+ +
+
+ + + + +
enum QwtCompassWindArrow::Style
+
+ +

Style of the arrow.

+ + + +
Enumerator
Style1  +

A needle pointing to the center.

+
Style2  +

A needle pointing to the center.

+
+ +
+
+

Constructor & Destructor Documentation

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
QwtCompassWindArrow::QwtCompassWindArrow (Style style,
const QColor & light = Qt::white,
const QColor & dark = Qt::gray 
)
+
+

Constructor

+
Parameters
+ + + + +
styleArrow style
lightLight color
darkDark color
+
+
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
void QwtCompassWindArrow::drawNeedle (QPainter * painter,
double length,
QPalette::ColorGroup colorGroup 
) const
+
+protectedvirtual
+
+

Draw the needle

+
Parameters
+ + + + +
painterPainter
lengthLength of the needle
colorGroupColor group, used for painting
+
+
+ +

Implements QwtDialNeedle.

+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_compass_wind_arrow__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_compass_wind_arrow__inherit__graph.map new file mode 100644 index 0000000000..e638cca8b3 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_compass_wind_arrow__inherit__graph.map @@ -0,0 +1,3 @@ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_compass_wind_arrow__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_compass_wind_arrow__inherit__graph.md5 new file mode 100644 index 0000000000..330c512f11 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_compass_wind_arrow__inherit__graph.md5 @@ -0,0 +1 @@ +43f440c6386c18c9e0f850506a470461 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_compass_wind_arrow__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_compass_wind_arrow__inherit__graph.png new file mode 100644 index 0000000000..9001721be8 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_compass_wind_arrow__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_counter-members.html b/ThirdParty/Qwt/doc/html/class_qwt_counter-members.html new file mode 100644 index 0000000000..c4c3383406 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_counter-members.html @@ -0,0 +1,138 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtCounter Member List
+
+
+ +

This is the complete list of members for QwtCounter, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Button enum nameQwtCounter
Button1 enum valueQwtCounter
Button2 enum valueQwtCounter
Button3 enum valueQwtCounter
ButtonCnt enum valueQwtCounter
buttonReleased(double value)QwtCountersignal
event(QEvent *)QwtCounterprotectedvirtual
incSteps(QwtCounter::Button btn) const QwtCounter
isReadOnly() const QwtCounter
isValid() const QwtCounter
keyPressEvent(QKeyEvent *)QwtCounterprotectedvirtual
maximum() const QwtCounter
minimum() const QwtCounter
numButtons() const QwtCounter
QwtCounter(QWidget *parent=NULL)QwtCounterexplicit
setIncSteps(QwtCounter::Button btn, int nSteps)QwtCounter
setMaximum(double max)QwtCounter
setMinimum(double min)QwtCounter
setNumButtons(int n)QwtCounter
setRange(double min, double max)QwtCounter
setReadOnly(bool)QwtCounter
setSingleStep(double s)QwtCounter
setStepButton1(int nSteps)QwtCounter
setStepButton2(int nSteps)QwtCounter
setStepButton3(int nSteps)QwtCounter
setValid(bool)QwtCounter
setValue(double)QwtCounterslot
setWrapping(bool)QwtCounter
singleStep() const QwtCounter
sizeHint() const QwtCountervirtual
stepButton1() const QwtCounter
stepButton2() const QwtCounter
stepButton3() const QwtCounter
value() const QwtCounter
valueChanged(double value)QwtCountersignal
wheelEvent(QWheelEvent *)QwtCounterprotectedvirtual
wrapping() const QwtCounter
~QwtCounter()QwtCountervirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_counter.html b/ThirdParty/Qwt/doc/html/class_qwt_counter.html new file mode 100644 index 0000000000..62ffddf169 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_counter.html @@ -0,0 +1,990 @@ + + + + + + +Qwt User's Guide: QwtCounter Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+ +
+ +

The Counter Widget. + More...

+ +

#include <qwt_counter.h>

+
+Inheritance diagram for QwtCounter:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + +

+Public Types

enum  Button { Button1, +Button2, +Button3, +ButtonCnt + }
 Button index. More...
 
+ + + + +

+Public Slots

void setValue (double)
 Set a new value without adjusting to the step raster. More...
 
+ + + + + +

+Signals

void buttonReleased (double value)
 
void valueChanged (double value)
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 QwtCounter (QWidget *parent=NULL)
 
+virtual ~QwtCounter ()
 Destructor.
 
void setValid (bool)
 
bool isValid () const
 
void setWrapping (bool)
 En/Disable wrapping. More...
 
bool wrapping () const
 
bool isReadOnly () const
 
void setReadOnly (bool)
 Allow/disallow the user to manually edit the value. More...
 
void setNumButtons (int n)
 
int numButtons () const
 
void setIncSteps (QwtCounter::Button btn, int nSteps)
 
int incSteps (QwtCounter::Button btn) const
 
+virtual QSize sizeHint () const
 A size hint.
 
double singleStep () const
 
void setSingleStep (double s)
 Set the step size of the counter. More...
 
void setRange (double min, double max)
 Set the minimum and maximum values. More...
 
double minimum () const
 
void setMinimum (double min)
 
double maximum () const
 
void setMaximum (double max)
 
void setStepButton1 (int nSteps)
 
+int stepButton1 () const
 returns the number of increment steps for button 1
 
void setStepButton2 (int nSteps)
 
+int stepButton2 () const
 returns the number of increment steps for button 2
 
void setStepButton3 (int nSteps)
 
+int stepButton3 () const
 returns the number of increment steps for button 3
 
double value () const
 
+ + + + + + + +

+Protected Member Functions

virtual bool event (QEvent *)
 
virtual void wheelEvent (QWheelEvent *)
 
virtual void keyPressEvent (QKeyEvent *)
 
+

Detailed Description

+

The Counter Widget.

+

A Counter consists of a label displaying a number and one ore more (up to three) push buttons on each side of the label which can be used to increment or decrement the counter's value.

+

A counter has a range from a minimum value to a maximum value and a step size. When the wrapping property is set the counter is circular.

+

The number of steps by which a button increments or decrements the value can be specified using setIncSteps(). The number of buttons can be changed with setNumButtons().

+

Example:

+
#include <qwt_counter.h>
+
+
QwtCounter *counter = new QwtCounter(parent);
+
+
counter->setRange(0.0, 100.0); // From 0.0 to 100
+
counter->setSingleStep( 1.0 ); // Step size 1.0
+
counter->setNumButtons(2); // Two buttons each side
+
counter->setIncSteps(QwtCounter::Button1, 1); // Button 1 increments 1 step
+
counter->setIncSteps(QwtCounter::Button2, 20); // Button 2 increments 20 steps
+
+
connect(counter, SIGNAL(valueChanged(double)), myClass, SLOT(newValue(double)));
+

Member Enumeration Documentation

+ +
+
+ + + + +
enum QwtCounter::Button
+
+ +

Button index.

+ + + + + +
Enumerator
Button1  +

Button intended for minor steps.

+
Button2  +

Button intended for medium steps.

+
Button3  +

Button intended for large steps.

+
ButtonCnt  +

Number of buttons.

+
+ +
+
+

Constructor & Destructor Documentation

+ +
+
+ + + + + +
+ + + + + + + + +
QwtCounter::QwtCounter (QWidget * parent = NULL)
+
+explicit
+
+

The counter is initialized with a range is set to [0.0, 1.0] with 0.01 as single step size. The value is invalid.

+

The default number of buttons is set to 2. The default increments are:

+
    +
  • Button 1: 1 step
  • +
  • Button 2: 10 steps
  • +
  • Button 3: 100 steps
  • +
+
Parameters
+ + +
parent
+
+
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + + +
void QwtCounter::buttonReleased (double value)
+
+signal
+
+

This signal is emitted when a button has been released

+
Parameters
+ + +
valueThe new value
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool QwtCounter::event (QEvent * event)
+
+protectedvirtual
+
+

Handle QEvent::PolishRequest events

+
Parameters
+ + +
eventEvent
+
+
+
Returns
see QWidget::event()
+ +
+
+ +
+
+ + + + + + + + +
int QwtCounter::incSteps (QwtCounter::Button button) const
+
+
Returns
The number of steps by which a specified button increments the value or 0 if the button is invalid.
+
Parameters
+ + +
buttonButton index
+
+
+
See Also
setIncSteps()
+ +
+
+ +
+
+ + + + + + + +
bool QwtCounter::isReadOnly () const
+
+
Returns
True, when the line line edit is read only. (default is no)
+
See Also
setReadOnly()
+ +
+
+ +
+
+ + + + + + + +
bool QwtCounter::isValid () const
+
+
Returns
True, if the value is valid
+
See Also
setValid(), setValue()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtCounter::keyPressEvent (QKeyEvent * event)
+
+protectedvirtual
+
+

Handle key events

+
    +
  • Ctrl + Qt::Key_Home
    + Step to minimum()
  • +
  • Ctrl + Qt::Key_End
    + Step to maximum()
  • +
  • Qt::Key_Up
    + Increment by incSteps(QwtCounter::Button1)
  • +
  • Qt::Key_Down
    + Decrement by incSteps(QwtCounter::Button1)
  • +
  • Qt::Key_PageUp
    + Increment by incSteps(QwtCounter::Button2)
  • +
  • Qt::Key_PageDown
    + Decrement by incSteps(QwtCounter::Button2)
  • +
  • Shift + Qt::Key_PageUp
    + Increment by incSteps(QwtCounter::Button3)
  • +
  • Shift + Qt::Key_PageDown
    + Decrement by incSteps(QwtCounter::Button3)
  • +
+
Parameters
+ + +
eventKey event
+
+
+ +
+
+ +
+
+ + + + + + + +
double QwtCounter::maximum () const
+
+
Returns
The maximum of the range
+
See Also
setRange(), setMaximum(), minimum()
+ +
+
+ +
+
+ + + + + + + +
double QwtCounter::minimum () const
+
+
Returns
The minimum of the range
+
See Also
setRange(), setMinimum(), maximum()
+ +
+
+ +
+
+ + + + + + + +
int QwtCounter::numButtons () const
+
+
Returns
The number of buttons on each side of the widget.
+
See Also
setNumButtons()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtCounter::setIncSteps (QwtCounter::Button button,
int numSteps 
)
+
+

Specify the number of steps by which the value is incremented or decremented when a specified button is pushed.

+
Parameters
+ + + +
buttonButton index
numStepsNumber of steps
+
+
+
See Also
incSteps()
+ +
+
+ +
+
+ + + + + + + + +
void QwtCounter::setMaximum (double value)
+
+

Set the maximum value of the range

+
Parameters
+ + +
valueMaximum value
+
+
+
See Also
setRange(), setMinimum(), maximum()
+ +
+
+ +
+
+ + + + + + + + +
void QwtCounter::setMinimum (double value)
+
+

Set the minimum value of the range

+
Parameters
+ + +
valueMinimum value
+
+
+
See Also
setRange(), setMaximum(), minimum()
+
Note
The maximum is adjusted if necessary to ensure that the range remains valid.
+ +
+
+ +
+
+ + + + + + + + +
void QwtCounter::setNumButtons (int numButtons)
+
+

Specify the number of buttons on each side of the label

+
Parameters
+ + +
numButtonsNumber of buttons
+
+
+
See Also
numButtons()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtCounter::setRange (double min,
double max 
)
+
+ +

Set the minimum and maximum values.

+

The maximum is adjusted if necessary to ensure that the range remains valid. The value might be modified to be inside of the range.

+
Parameters
+ + + +
minMinimum value
maxMaximum value
+
+
+
See Also
minimum(), maximum()
+ +
+
+ +
+
+ + + + + + + + +
void QwtCounter::setReadOnly (bool on)
+
+ +

Allow/disallow the user to manually edit the value.

+
Parameters
+ + +
onTrue disable editing
+
+
+
See Also
isReadOnly()
+ +
+
+ +
+
+ + + + + + + + +
void QwtCounter::setSingleStep (double stepSize)
+
+ +

Set the step size of the counter.

+

A value <= 0.0 disables stepping

+
Parameters
+ + +
stepSizeSingle step size
+
+
+
See Also
singleStep()
+ +
+
+ +
+
+ + + + + + + + +
void QwtCounter::setStepButton1 (int nSteps)
+
+

Set the number of increment steps for button 1

+
Parameters
+ + +
nStepsNumber of steps
+
+
+ +
+
+ +
+
+ + + + + + + + +
void QwtCounter::setStepButton2 (int nSteps)
+
+

Set the number of increment steps for button 2

+
Parameters
+ + +
nStepsNumber of steps
+
+
+ +
+
+ +
+
+ + + + + + + + +
void QwtCounter::setStepButton3 (int nSteps)
+
+

Set the number of increment steps for button 3

+
Parameters
+ + +
nStepsNumber of steps
+
+
+ +
+
+ +
+
+ + + + + + + + +
void QwtCounter::setValid (bool on)
+
+

Set the counter to be in valid/invalid state

+

When the counter is set to invalid, no numbers are displayed and the buttons are disabled.

+
Parameters
+ + +
onIf true the counter will be set as valid
+
+
+
See Also
setValue(), isValid()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtCounter::setValue (double value)
+
+slot
+
+ +

Set a new value without adjusting to the step raster.

+

The state of the counter is set to be valid.

+
Parameters
+ + +
valueNew value
+
+
+
See Also
isValid(), value(), valueChanged()
+
Warning
The value is clipped when it lies outside the range.
+ +
+
+ +
+
+ + + + + + + + +
void QwtCounter::setWrapping (bool on)
+
+ +

En/Disable wrapping.

+

If wrapping is true stepping up from maximum() value will take you to the minimum() value and vice versa.

+
Parameters
+ + +
onEn/Disable wrapping
+
+
+
See Also
wrapping()
+ +
+
+ +
+
+ + + + + + + +
double QwtCounter::singleStep () const
+
+
Returns
Single step size
+
See Also
setSingleStep()
+ +
+
+ +
+
+ + + + + + + +
double QwtCounter::value () const
+
+
Returns
Current value of the counter
+
See Also
setValue(), valueChanged()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtCounter::valueChanged (double value)
+
+signal
+
+

This signal is emitted when the counter's value has changed

+
Parameters
+ + +
valueThe new value
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtCounter::wheelEvent (QWheelEvent * event)
+
+protectedvirtual
+
+

Handle wheel events

+
Parameters
+ + +
eventWheel event
+
+
+ +
+
+ +
+
+ + + + + + + +
bool QwtCounter::wrapping () const
+
+
Returns
True, when wrapping is set
+
See Also
setWrapping()
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_counter__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_counter__inherit__graph.map new file mode 100644 index 0000000000..e7ac10d367 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_counter__inherit__graph.map @@ -0,0 +1,2 @@ + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_counter__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_counter__inherit__graph.md5 new file mode 100644 index 0000000000..e9d6c52225 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_counter__inherit__graph.md5 @@ -0,0 +1 @@ +5cbd094056176601b414a1174c147d63 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_counter__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_counter__inherit__graph.png new file mode 100644 index 0000000000..a5c4f30b37 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_counter__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_curve_fitter-members.html b/ThirdParty/Qwt/doc/html/class_qwt_curve_fitter-members.html new file mode 100644 index 0000000000..3b35bbad34 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_curve_fitter-members.html @@ -0,0 +1,103 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtCurveFitter Member List
+
+
+ +

This is the complete list of members for QwtCurveFitter, including all inherited members.

+ + + + +
fitCurve(const QPolygonF &polygon) const =0QwtCurveFitterpure virtual
QwtCurveFitter()QwtCurveFitterprotected
~QwtCurveFitter()QwtCurveFittervirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_curve_fitter.html b/ThirdParty/Qwt/doc/html/class_qwt_curve_fitter.html new file mode 100644 index 0000000000..b0a6dc624f --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_curve_fitter.html @@ -0,0 +1,167 @@ + + + + + + +Qwt User's Guide: QwtCurveFitter Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtCurveFitter Class Referenceabstract
+
+
+ +

Abstract base class for a curve fitter. + More...

+ +

#include <qwt_curve_fitter.h>

+
+Inheritance diagram for QwtCurveFitter:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + +

+Public Member Functions

+virtual ~QwtCurveFitter ()
 Destructor.
 
virtual QPolygonF fitCurve (const QPolygonF &polygon) const =0
 
+ + + + +

+Protected Member Functions

QwtCurveFitter ()
 Constructor.
 
+

Detailed Description

+

Abstract base class for a curve fitter.

+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + + +
virtual QPolygonF QwtCurveFitter::fitCurve (const QPolygonF & polygon) const
+
+pure virtual
+
+

Find a curve which has the best fit to a series of data points

+
Parameters
+ + +
polygonSeries of data points
+
+
+
Returns
Curve points
+ +

Implemented in QwtWeedingCurveFitter, and QwtSplineCurveFitter.

+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_curve_fitter__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_curve_fitter__inherit__graph.map new file mode 100644 index 0000000000..0164720bac --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_curve_fitter__inherit__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_curve_fitter__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_curve_fitter__inherit__graph.md5 new file mode 100644 index 0000000000..3b7ce566df --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_curve_fitter__inherit__graph.md5 @@ -0,0 +1 @@ +d1d796f73d689bc75e2c208f51d431e5 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_curve_fitter__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_curve_fitter__inherit__graph.png new file mode 100644 index 0000000000..45457ea550 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_curve_fitter__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_date-members.html b/ThirdParty/Qwt/doc/html/class_qwt_date-members.html new file mode 100644 index 0000000000..e8c620ca52 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_date-members.html @@ -0,0 +1,123 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtDate Member List
+
+
+ +

This is the complete list of members for QwtDate, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + +
ceil(const QDateTime &, IntervalType)QwtDatestatic
dateOfWeek0(int year, Week0Type)QwtDatestatic
Day enum valueQwtDate
FirstDay enum valueQwtDate
FirstThursday enum valueQwtDate
floor(const QDateTime &, IntervalType)QwtDatestatic
Hour enum valueQwtDate
IntervalType enum nameQwtDate
JulianDayForEpoch enum valueQwtDate
maxDate()QwtDatestatic
Millisecond enum valueQwtDate
minDate()QwtDatestatic
Minute enum valueQwtDate
Month enum valueQwtDate
Second enum valueQwtDate
toDateTime(double value, Qt::TimeSpec=Qt::UTC)QwtDatestatic
toDouble(const QDateTime &)QwtDatestatic
toString(const QDateTime &, const QString &format, Week0Type)QwtDatestatic
utcOffset(const QDateTime &)QwtDatestatic
Week enum valueQwtDate
Week0Type enum nameQwtDate
weekNumber(const QDate &, Week0Type)QwtDatestatic
Year enum valueQwtDate
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_date.html b/ThirdParty/Qwt/doc/html/class_qwt_date.html new file mode 100644 index 0000000000..9f8d6ec215 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_date.html @@ -0,0 +1,667 @@ + + + + + + +Qwt User's Guide: QwtDate Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtDate Class Reference
+
+
+ +

A collection of methods around date/time values. + More...

+ +

#include <qwt_date.h>

+ + + + + + + + +

+Public Types

enum  Week0Type { FirstThursday, +FirstDay + }
 
enum  IntervalType {
+  Millisecond, +Second, +Minute, +Hour, +
+  Day, +Week, +Month, +Year +
+ }
 
enum  { JulianDayForEpoch = 2440588 + }
 
+ + + + + + + + + + + + + + + + + + + + + + +

+Static Public Member Functions

static QDate minDate ()
 
static QDate maxDate ()
 
static QDateTime toDateTime (double value, Qt::TimeSpec=Qt::UTC)
 
static double toDouble (const QDateTime &)
 
static QDateTime ceil (const QDateTime &, IntervalType)
 
static QDateTime floor (const QDateTime &, IntervalType)
 
static QDate dateOfWeek0 (int year, Week0Type)
 Date of the first day of the first week for a year. More...
 
static int weekNumber (const QDate &, Week0Type)
 
static int utcOffset (const QDateTime &)
 
static QString toString (const QDateTime &, const QString &format, Week0Type)
 
+

Detailed Description

+

A collection of methods around date/time values.

+

Qt offers convenient classes for dealing with date/time values, but Qwt uses coordinate systems that are based on doubles. QwtDate offers methods to translate from QDateTime to double and v.v.

+

A double is interpreted as the number of milliseconds since 1970-01-01T00:00:00 Universal Coordinated Time - also known as "The Epoch".

+

While the range of the Julian day in Qt4 is limited to [0, MAX_INT], Qt5 stores it as qint64 offering a huge range of valid dates. As the significance of a double is below this ( assuming a fraction of 52 bits ) the translation is not bijective with rounding errors for dates very far from Epoch. For a resolution of 1 ms those start to happen for dates above the year 144683.

+

An axis for a date/time interval is expected to be aligned and divided in time/date units like seconds, minutes, ... QwtDate offers several algorithms that are needed to calculate these axes.

+
See Also
QwtDateScaleEngine, QwtDateScaleDraw, QDate, QTime
+

Member Enumeration Documentation

+ +
+
+ + + + +
anonymous enum
+
+ + +
Enumerator
JulianDayForEpoch  +

The Julian day of "The Epoch".

+
+ +
+
+ +
+
+ + + + +
enum QwtDate::IntervalType
+
+

Classification of an time interval

+

Time intervals needs to be classified to decide how to align and divide it.

+ + + + + + + + + +
Enumerator
Millisecond  +

The interval is related to milliseconds.

+
Second  +

The interval is related to seconds.

+
Minute  +

The interval is related to minutes.

+
Hour  +

The interval is related to hours.

+
Day  +

The interval is related to days.

+
Week  +

The interval is related to weeks.

+
Month  +

The interval is related to months.

+
Year  +

The interval is related to years.

+
+ +
+
+ +
+
+ + + + +
enum QwtDate::Week0Type
+
+

How to identify the first week of year differs between countries.

+ + + +
Enumerator
FirstThursday  +

According to ISO 8601 the first week of a year is defined as "the week with the year's first Thursday in it".

+

FirstThursday corresponds to the numbering that is implemented in QDate::weekNumber().

+
FirstDay  +

"The week with January 1.1 in it."

+

In the U.S. this definition is more common than FirstThursday.

+
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
QDateTime QwtDate::ceil (const QDateTime & dateTime,
IntervalType intervalType 
)
+
+static
+
+

Ceil a datetime according the interval type

+
Parameters
+ + + +
dateTimeDatetime value
intervalTypeInterval type, how to ceil. F.e. when intervalType = QwtDate::Months, the result will be ceiled to the next beginning of a month
+
+
+
Returns
Ceiled datetime
+
See Also
floor()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
QDate QwtDate::dateOfWeek0 (int year,
Week0Type type 
)
+
+static
+
+ +

Date of the first day of the first week for a year.

+

The first day of a week depends on the current locale ( QLocale::firstDayOfWeek() ).

+
Parameters
+ + + +
yearYear
typeOption how to identify the first week
+
+
+
Returns
First day of week 0
+
See Also
QLocale::firstDayOfWeek(), weekNumber()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
QDateTime QwtDate::floor (const QDateTime & dateTime,
IntervalType intervalType 
)
+
+static
+
+

Floor a datetime according the interval type

+
Parameters
+ + + +
dateTimeDatetime value
intervalTypeInterval type, how to ceil. F.e. when intervalType = QwtDate::Months, the result will be ceiled to the next beginning of a month
+
+
+
Returns
Floored datetime
+
See Also
floor()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
QDate QwtDate::maxDate ()
+
+static
+
+

Maximum for the supported date range

+

The range of valid dates depends on how QDate stores the Julian day internally.

+
    +
  • For Qt4 it is "Tue Jun 3 5874898"
  • +
  • For Qt5 it is "Tue Dec 31 2147483647"
  • +
+
Returns
maximum of the date range
+
See Also
minDate()
+
Note
The maximum differs between Qt4 and Qt5
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
QDate QwtDate::minDate ()
+
+static
+
+

Minimum for the supported date range

+

The range of valid dates depends on how QDate stores the Julian day internally.

+
    +
  • For Qt4 it is "Tue Jan 2 -4713"
  • +
  • For Qt5 it is "Thu Jan 1 -2147483648"
  • +
+
Returns
minimum of the date range
+
See Also
maxDate()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
QDateTime QwtDate::toDateTime (double value,
Qt::TimeSpec timeSpec = Qt::UTC 
)
+
+static
+
+

Translate from double to QDateTime

+
Parameters
+ + + +
valueNumber of milliseconds since the epoch, 1970-01-01T00:00:00 UTC
timeSpecTime specification
+
+
+
Returns
Datetime value
+
See Also
toDouble(), QDateTime::setMSecsSinceEpoch()
+
Note
The return datetime for Qt::OffsetFromUTC will be Qt::UTC
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
double QwtDate::toDouble (const QDateTime & dateTime)
+
+static
+
+

Translate from QDateTime to double

+
Parameters
+ + +
dateTimeDatetime value
+
+
+
Returns
Number of milliseconds since 1970-01-01T00:00:00 UTC has passed.
+
See Also
toDateTime(), QDateTime::toMSecsSinceEpoch()
+
Warning
For values very far below or above 1970-01-01 UTC rounding errors will happen due to the limited significance of a double.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
QString QwtDate::toString (const QDateTime & dateTime,
const QString & format,
Week0Type week0Type 
)
+
+static
+
+

Translate a datetime into a string

+

Beside the format expressions documented in QDateTime::toString() the following expressions are supported:

+
    +
  • w
    + week number: ( 1 - 53 )
  • +
  • ww
    + week number with a leading zero ( 01 - 53 )
  • +
+
Parameters
+ + + + +
dateTimeDatetime value
formatFormat string
week0TypeSpecification of week 0
+
+
+
Returns
Datetime string
+
See Also
QDateTime::toString(), weekNumber(), QwtDateScaleDraw
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
int QwtDate::utcOffset (const QDateTime & dateTime)
+
+static
+
+

Offset in seconds from Coordinated Universal Time

+

The offset depends on the time specification of dateTime:

+
    +
  • Qt::UTC 0, dateTime has no offset
  • +
  • Qt::OffsetFromUTC returns dateTime.utcOffset()
  • +
  • Qt::LocalTime: number of seconds from the UTC
  • +
+

For Qt::LocalTime the offset depends on the timezone and daylight savings.

+
Parameters
+ + +
dateTimeDatetime value
+
+
+
Returns
Offset in seconds
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
int QwtDate::weekNumber (const QDate & date,
Week0Type type 
)
+
+static
+
+

Find the week number of a date

+ + +
Parameters
+ + + +
dateDate
typeOption how to identify the first week
+
+
+
Returns
Week number, starting with 1
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_date_scale_draw-members.html b/ThirdParty/Qwt/doc/html/class_qwt_date_scale_draw-members.html new file mode 100644 index 0000000000..f86d6f5931 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_date_scale_draw-members.html @@ -0,0 +1,173 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtDateScaleDraw Member List
+
+
+ +

This is the complete list of members for QwtDateScaleDraw, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Alignment enum nameQwtScaleDraw
alignment() const QwtScaleDraw
Backbone enum valueQwtAbstractScaleDraw
BottomScale enum valueQwtScaleDraw
boundingLabelRect(const QFont &, double val) const QwtScaleDraw
dateFormat(QwtDate::IntervalType) const QwtDateScaleDraw
dateFormatOfDate(const QDateTime &, QwtDate::IntervalType) const QwtDateScaleDrawprotectedvirtual
draw(QPainter *, const QPalette &) const QwtAbstractScaleDrawvirtual
drawBackbone(QPainter *) const QwtScaleDrawprotectedvirtual
drawLabel(QPainter *, double val) const QwtScaleDrawprotectedvirtual
drawTick(QPainter *, double val, double len) const QwtScaleDrawprotectedvirtual
enableComponent(ScaleComponent, bool enable=true)QwtAbstractScaleDraw
extent(const QFont &) const QwtScaleDrawvirtual
getBorderDistHint(const QFont &, int &start, int &end) const QwtScaleDraw
hasComponent(ScaleComponent) const QwtAbstractScaleDraw
intervalType(const QwtScaleDiv &) const QwtDateScaleDrawprotectedvirtual
invalidateCache()QwtAbstractScaleDrawprotected
label(double) const QwtDateScaleDrawvirtual
labelAlignment() const QwtScaleDraw
labelPosition(double val) const QwtScaleDraw
labelRect(const QFont &, double val) const QwtScaleDraw
labelRotation() const QwtScaleDraw
Labels enum valueQwtAbstractScaleDraw
labelSize(const QFont &, double val) const QwtScaleDraw
labelTransformation(const QPointF &, const QSizeF &) const QwtScaleDrawprotected
LeftScale enum valueQwtScaleDraw
length() const QwtScaleDraw
maxLabelHeight(const QFont &) const QwtScaleDraw
maxLabelWidth(const QFont &) const QwtScaleDraw
maxTickLength() const QwtAbstractScaleDraw
minimumExtent() const QwtAbstractScaleDraw
minLabelDist(const QFont &) const QwtScaleDraw
minLength(const QFont &) const QwtScaleDraw
move(double x, double y)QwtScaleDrawinline
move(const QPointF &)QwtScaleDraw
orientation() const QwtScaleDraw
penWidth() const QwtAbstractScaleDraw
pos() const QwtScaleDraw
QwtAbstractScaleDraw()QwtAbstractScaleDraw
QwtDateScaleDraw(Qt::TimeSpec=Qt::LocalTime)QwtDateScaleDraw
QwtScaleDraw()QwtScaleDraw
RightScale enum valueQwtScaleDraw
ScaleComponent enum nameQwtAbstractScaleDraw
ScaleComponents typedefQwtAbstractScaleDraw
scaleDiv() const QwtAbstractScaleDraw
scaleMap() const QwtAbstractScaleDraw
scaleMap()QwtAbstractScaleDraw
setAlignment(Alignment)QwtScaleDraw
setDateFormat(QwtDate::IntervalType, const QString &)QwtDateScaleDraw
setLabelAlignment(Qt::Alignment)QwtScaleDraw
setLabelRotation(double rotation)QwtScaleDraw
setLength(double length)QwtScaleDraw
setMinimumExtent(double)QwtAbstractScaleDraw
setPenWidth(int width)QwtAbstractScaleDraw
setScaleDiv(const QwtScaleDiv &s)QwtAbstractScaleDraw
setSpacing(double margin)QwtAbstractScaleDraw
setTickLength(QwtScaleDiv::TickType, double length)QwtAbstractScaleDraw
setTimeSpec(Qt::TimeSpec)QwtDateScaleDraw
setTransformation(QwtTransform *)QwtAbstractScaleDraw
setUtcOffset(int seconds)QwtDateScaleDraw
setWeek0Type(QwtDate::Week0Type)QwtDateScaleDraw
spacing() const QwtAbstractScaleDraw
tickLabel(const QFont &, double value) const QwtAbstractScaleDrawprotected
tickLength(QwtScaleDiv::TickType) const QwtAbstractScaleDraw
Ticks enum valueQwtAbstractScaleDraw
timeSpec() const QwtDateScaleDraw
toDateTime(double) const QwtDateScaleDraw
TopScale enum valueQwtScaleDraw
utcOffset() const QwtDateScaleDraw
week0Type() const QwtDateScaleDraw
~QwtAbstractScaleDraw()QwtAbstractScaleDrawvirtual
~QwtDateScaleDraw()QwtDateScaleDrawvirtual
~QwtScaleDraw()QwtScaleDrawvirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_date_scale_draw.html b/ThirdParty/Qwt/doc/html/class_qwt_date_scale_draw.html new file mode 100644 index 0000000000..865ec4f987 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_date_scale_draw.html @@ -0,0 +1,653 @@ + + + + + + +Qwt User's Guide: QwtDateScaleDraw Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtDateScaleDraw Class Reference
+
+
+ +

A class for drawing datetime scales. + More...

+ +

#include <qwt_date_scale_draw.h>

+
+Inheritance diagram for QwtDateScaleDraw:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 QwtDateScaleDraw (Qt::TimeSpec=Qt::LocalTime)
 Constructor. More...
 
+virtual ~QwtDateScaleDraw ()
 Destructor.
 
void setDateFormat (QwtDate::IntervalType, const QString &)
 
QString dateFormat (QwtDate::IntervalType) const
 
void setTimeSpec (Qt::TimeSpec)
 
Qt::TimeSpec timeSpec () const
 
void setUtcOffset (int seconds)
 
int utcOffset () const
 
void setWeek0Type (QwtDate::Week0Type)
 
QwtDate::Week0Type week0Type () const
 
virtual QwtText label (double) const
 Convert a value into its representing label. More...
 
QDateTime toDateTime (double) const
 
- Public Member Functions inherited from QwtScaleDraw
 QwtScaleDraw ()
 Constructor. More...
 
+virtual ~QwtScaleDraw ()
 Destructor.
 
void getBorderDistHint (const QFont &, int &start, int &end) const
 Determine the minimum border distance. More...
 
int minLabelDist (const QFont &) const
 
int minLength (const QFont &) const
 
virtual double extent (const QFont &) const
 
void move (double x, double y)
 
void move (const QPointF &)
 Move the position of the scale. More...
 
void setLength (double length)
 
Alignment alignment () const
 
void setAlignment (Alignment)
 
Qt::Orientation orientation () const
 
QPointF pos () const
 
double length () const
 
void setLabelAlignment (Qt::Alignment)
 Change the label flags. More...
 
Qt::Alignment labelAlignment () const
 
void setLabelRotation (double rotation)
 
double labelRotation () const
 
int maxLabelHeight (const QFont &) const
 
int maxLabelWidth (const QFont &) const
 
QPointF labelPosition (double val) const
 
QRectF labelRect (const QFont &, double val) const
 
QSizeF labelSize (const QFont &, double val) const
 
QRect boundingLabelRect (const QFont &, double val) const
 Find the bounding rectangle for the label. More...
 
- Public Member Functions inherited from QwtAbstractScaleDraw
 QwtAbstractScaleDraw ()
 Constructor. More...
 
+virtual ~QwtAbstractScaleDraw ()
 Destructor.
 
void setScaleDiv (const QwtScaleDiv &s)
 
const QwtScaleDivscaleDiv () const
 
void setTransformation (QwtTransform *)
 
const QwtScaleMapscaleMap () const
 
QwtScaleMapscaleMap ()
 
void enableComponent (ScaleComponent, bool enable=true)
 
bool hasComponent (ScaleComponent) const
 
void setTickLength (QwtScaleDiv::TickType, double length)
 
double tickLength (QwtScaleDiv::TickType) const
 
double maxTickLength () const
 
void setSpacing (double margin)
 Set the spacing between tick and labels. More...
 
double spacing () const
 Get the spacing. More...
 
void setPenWidth (int width)
 Specify the width of the scale pen. More...
 
int penWidth () const
 
virtual void draw (QPainter *, const QPalette &) const
 Draw the scale. More...
 
void setMinimumExtent (double)
 Set a minimum for the extent. More...
 
double minimumExtent () const
 
+ + + + + + + + + + + + + + + + + + + + +

+Protected Member Functions

virtual QwtDate::IntervalType intervalType (const QwtScaleDiv &) const
 
virtual QString dateFormatOfDate (const QDateTime &, QwtDate::IntervalType) const
 
- Protected Member Functions inherited from QwtScaleDraw
QTransform labelTransformation (const QPointF &, const QSizeF &) const
 
virtual void drawTick (QPainter *, double val, double len) const
 
virtual void drawBackbone (QPainter *) const
 
virtual void drawLabel (QPainter *, double val) const
 
- Protected Member Functions inherited from QwtAbstractScaleDraw
void invalidateCache ()
 
const QwtTexttickLabel (const QFont &, double value) const
 Convert a value into its representing label and cache it. More...
 
+ + + + +

+Additional Inherited Members

- Public Types inherited from QwtScaleDraw
enum  Alignment { BottomScale, +TopScale, +LeftScale, +RightScale + }
 
+

Detailed Description

+

A class for drawing datetime scales.

+

QwtDateScaleDraw displays values as datetime labels. The format of the labels depends on the alignment of the major tick labels.

+

The default format strings are:

+
    +
  • Millisecond
    + "hh:mm:ss:zzz\nddd dd MMM yyyy"
  • +
  • Second
    + "hh:mm:ss\nddd dd MMM yyyy"
  • +
  • Minute
    + "hh:mm\nddd dd MMM yyyy"
  • +
  • Hour
    + "hh:mm\nddd dd MMM yyyy"
  • +
  • Day
    + "ddd dd MMM yyyy"
  • +
  • Week
    + "Www yyyy"
  • +
  • Month
    + "MMM yyyy"
  • +
  • Year
    + "yyyy"
  • +
+

The format strings can be modified using setDateFormat() or individually for each tick label by overloading dateFormatOfDate(),

+

Usually QwtDateScaleDraw is used in combination with QwtDateScaleEngine, that calculates scales for datetime intervals.

+
See Also
QwtDateScaleEngine, QwtPlot::setAxisScaleDraw()
+

Constructor & Destructor Documentation

+ +
+
+ + + + + + + + +
QwtDateScaleDraw::QwtDateScaleDraw (Qt::TimeSpec timeSpec = Qt::LocalTime)
+
+ +

Constructor.

+

The default setting is to display tick labels for the given time specification. The first week of a year is defined like for QwtDate::FirstThursday.

+
Parameters
+ + +
timeSpecTime specification
+
+
+
See Also
setTimeSpec(), setWeek0Type()
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + + + + +
QString QwtDateScaleDraw::dateFormat (QwtDate::IntervalType intervalType) const
+
+
Parameters
+ + +
intervalTypeInterval type
+
+
+
Returns
Default format string for an datetime interval type
+
See Also
setDateFormat(), dateFormatOfDate()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
QString QwtDateScaleDraw::dateFormatOfDate (const QDateTime & dateTime,
QwtDate::IntervalType intervalType 
) const
+
+protectedvirtual
+
+

Format string for the representation of a datetime

+

dateFormatOfDate() is intended to be overloaded for situations, where formats are individual for specific datetime values.

+

The default setting ignores dateTime and return the default format for the interval type.

+
Parameters
+ + + +
dateTimeDatetime value
intervalTypeInterval type
+
+
+
Returns
Format string
+
See Also
setDateFormat(), QwtDate::toString()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
QwtDate::IntervalType QwtDateScaleDraw::intervalType (const QwtScaleDivscaleDiv) const
+
+protectedvirtual
+
+

Find the less detailed datetime unit, where no rounding errors happen.

+
Parameters
+ + +
scaleDivScale division
+
+
+
Returns
Interval type
+
See Also
dateFormatOfDate()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
QwtText QwtDateScaleDraw::label (double value) const
+
+virtual
+
+ +

Convert a value into its representing label.

+

The value is converted to a datetime value using toDateTime() and converted to a plain text using QwtDate::toString().

+
Parameters
+ + +
valueValue
+
+
+
Returns
Label string.
+
See Also
dateFormatOfDate()
+ +

Reimplemented from QwtAbstractScaleDraw.

+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtDateScaleDraw::setDateFormat (QwtDate::IntervalType intervalType,
const QString & format 
)
+
+

Set the default format string for an datetime interval type

+
Parameters
+ + + +
intervalTypeInterval type
formatDefault format string
+
+
+
See Also
dateFormat(), dateFormatOfDate(), QwtDate::toString()
+ +
+
+ +
+
+ + + + + + + + +
void QwtDateScaleDraw::setTimeSpec (Qt::TimeSpec timeSpec)
+
+

Set the time specification used for the tick labels

+
Parameters
+ + +
timeSpecTime specification
+
+
+
See Also
timeSpec(), setUtcOffset(), toDateTime()
+ +
+
+ +
+
+ + + + + + + + +
void QwtDateScaleDraw::setUtcOffset (int seconds)
+
+

Set the offset in seconds from Coordinated Universal Time

+
Parameters
+ + +
secondsOffset in seconds
+
+
+
Note
The offset has no effect beside for the time specification Qt::OffsetFromUTC.
+
See Also
QDate::utcOffset(), setTimeSpec(), toDateTime()
+ +
+
+ +
+
+ + + + + + + + +
void QwtDateScaleDraw::setWeek0Type (QwtDate::Week0Type week0Type)
+
+

Sets how to identify the first week of a year.

+
Parameters
+ + +
week0TypeMode how to identify the first week of a year
+
+
+
See Also
week0Type().
+
Note
week0Type has no effect beside for intervals classified as QwtDate::Week.
+ +
+
+ +
+
+ + + + + + + +
Qt::TimeSpec QwtDateScaleDraw::timeSpec () const
+
+
Returns
Time specification used for the tick labels
+
See Also
setTimeSpec(), utcOffset(), toDateTime()
+ +
+
+ +
+
+ + + + + + + + +
QDateTime QwtDateScaleDraw::toDateTime (double value) const
+
+

Translate a double value into a QDateTime object.

+
Returns
QDateTime object initialized with timeSpec() and utcOffset().
+
See Also
timeSpec(), utcOffset(), QwtDate::toDateTime()
+ +
+
+ +
+
+ + + + + + + +
int QwtDateScaleDraw::utcOffset () const
+
+
Returns
Offset in seconds from Coordinated Universal Time
+
Note
The offset has no effect beside for the time specification Qt::OffsetFromUTC.
+
See Also
QDate::setUtcOffset(), setTimeSpec(), toDateTime()
+ +
+
+ +
+
+ + + + + + + +
QwtDate::Week0Type QwtDateScaleDraw::week0Type () const
+
+
Returns
Setting how to identify the first week of a year.
+
See Also
setWeek0Type()
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_date_scale_draw__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_date_scale_draw__inherit__graph.map new file mode 100644 index 0000000000..80f749cd73 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_date_scale_draw__inherit__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_date_scale_draw__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_date_scale_draw__inherit__graph.md5 new file mode 100644 index 0000000000..751e1c883c --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_date_scale_draw__inherit__graph.md5 @@ -0,0 +1 @@ +c5426f9f96dfd4a39efb0f2d9c5ccde5 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_date_scale_draw__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_date_scale_draw__inherit__graph.png new file mode 100644 index 0000000000..4e2002337a Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_date_scale_draw__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_date_scale_engine-members.html b/ThirdParty/Qwt/doc/html/class_qwt_date_scale_engine-members.html new file mode 100644 index 0000000000..a4f71db98c --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_date_scale_engine-members.html @@ -0,0 +1,147 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtDateScaleEngine Member List
+
+
+ +

This is the complete list of members for QwtDateScaleEngine, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
align(const QwtInterval &, double stepSize) const QwtLinearScaleEngineprotected
alignDate(const QDateTime &, double stepSize, QwtDate::IntervalType, bool up) const QwtDateScaleEngineprotectedvirtual
Attribute enum nameQwtScaleEngine
attributes() const QwtScaleEngine
Attributes typedefQwtScaleEngine
autoScale(int maxNumSteps, double &x1, double &x2, double &stepSize) const QwtDateScaleEnginevirtual
base() const QwtScaleEngine
buildInterval(double v) const QwtScaleEngineprotected
buildMajorTicks(const QwtInterval &interval, double stepSize) const QwtLinearScaleEngineprotected
buildMinorTicks(const QList< double > &majorTicks, int maxMinorSteps, double stepSize, QList< double > &minorTicks, QList< double > &mediumTicks) const QwtLinearScaleEngineprotected
buildTicks(const QwtInterval &, double stepSize, int maxMinSteps, QList< double > ticks[QwtScaleDiv::NTickTypes]) const QwtLinearScaleEngineprotected
contains(const QwtInterval &, double val) const QwtScaleEngineprotected
divideInterval(double interval, int numSteps) const QwtScaleEngineprotected
divideScale(double x1, double x2, int maxMajorSteps, int maxMinorSteps, double stepSize=0.0) const QwtDateScaleEnginevirtual
Floating enum valueQwtScaleEngine
IncludeReference enum valueQwtScaleEngine
intervalType(const QDateTime &, const QDateTime &, int maxSteps) const QwtDateScaleEnginevirtual
Inverted enum valueQwtScaleEngine
lowerMargin() const QwtScaleEngine
maxWeeks() const QwtDateScaleEngine
NoAttribute enum valueQwtScaleEngine
QwtDateScaleEngine(Qt::TimeSpec=Qt::LocalTime)QwtDateScaleEngine
QwtLinearScaleEngine(uint base=10)QwtLinearScaleEngine
QwtScaleEngine(uint base=10)QwtScaleEngineexplicit
reference() const QwtScaleEngine
setAttribute(Attribute, bool on=true)QwtScaleEngine
setAttributes(Attributes)QwtScaleEngine
setBase(uint base)QwtScaleEngine
setMargins(double lower, double upper)QwtScaleEngine
setMaxWeeks(int)QwtDateScaleEngine
setReference(double reference)QwtScaleEngine
setTimeSpec(Qt::TimeSpec)QwtDateScaleEngine
setTransformation(QwtTransform *)QwtScaleEngine
setUtcOffset(int seconds)QwtDateScaleEngine
setWeek0Type(QwtDate::Week0Type)QwtDateScaleEngine
strip(const QList< double > &, const QwtInterval &) const QwtScaleEngineprotected
Symmetric enum valueQwtScaleEngine
testAttribute(Attribute) const QwtScaleEngine
timeSpec() const QwtDateScaleEngine
toDateTime(double) const QwtDateScaleEngine
transformation() const QwtScaleEngine
upperMargin() const QwtScaleEngine
utcOffset() const QwtDateScaleEngine
week0Type() const QwtDateScaleEngine
~QwtDateScaleEngine()QwtDateScaleEnginevirtual
~QwtLinearScaleEngine()QwtLinearScaleEnginevirtual
~QwtScaleEngine()QwtScaleEnginevirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_date_scale_engine.html b/ThirdParty/Qwt/doc/html/class_qwt_date_scale_engine.html new file mode 100644 index 0000000000..e364bfa232 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_date_scale_engine.html @@ -0,0 +1,697 @@ + + + + + + +Qwt User's Guide: QwtDateScaleEngine Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtDateScaleEngine Class Reference
+
+
+ +

A scale engine for date/time values. + More...

+ +

#include <qwt_date_scale_engine.h>

+
+Inheritance diagram for QwtDateScaleEngine:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 QwtDateScaleEngine (Qt::TimeSpec=Qt::LocalTime)
 Constructor. More...
 
+virtual ~QwtDateScaleEngine ()
 Destructor.
 
void setTimeSpec (Qt::TimeSpec)
 
Qt::TimeSpec timeSpec () const
 
void setUtcOffset (int seconds)
 
int utcOffset () const
 
void setWeek0Type (QwtDate::Week0Type)
 
QwtDate::Week0Type week0Type () const
 
void setMaxWeeks (int)
 
int maxWeeks () const
 
virtual void autoScale (int maxNumSteps, double &x1, double &x2, double &stepSize) const
 
virtual QwtScaleDiv divideScale (double x1, double x2, int maxMajorSteps, int maxMinorSteps, double stepSize=0.0) const
 Calculate a scale division for a date/time interval. More...
 
virtual QwtDate::IntervalType intervalType (const QDateTime &, const QDateTime &, int maxSteps) const
 
QDateTime toDateTime (double) const
 
- Public Member Functions inherited from QwtLinearScaleEngine
 QwtLinearScaleEngine (uint base=10)
 
+virtual ~QwtLinearScaleEngine ()
 Destructor.
 
- Public Member Functions inherited from QwtScaleEngine
 QwtScaleEngine (uint base=10)
 
+virtual ~QwtScaleEngine ()
 Destructor.
 
void setBase (uint base)
 
uint base () const
 
void setAttribute (Attribute, bool on=true)
 
bool testAttribute (Attribute) const
 
void setAttributes (Attributes)
 
Attributes attributes () const
 
void setReference (double reference)
 Specify a reference point. More...
 
double reference () const
 
void setMargins (double lower, double upper)
 Specify margins at the scale's endpoints. More...
 
double lowerMargin () const
 
double upperMargin () const
 
void setTransformation (QwtTransform *)
 
QwtTransformtransformation () const
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

+Protected Member Functions

virtual QDateTime alignDate (const QDateTime &, double stepSize, QwtDate::IntervalType, bool up) const
 
- Protected Member Functions inherited from QwtLinearScaleEngine
QwtInterval align (const QwtInterval &, double stepSize) const
 Align an interval to a step size. More...
 
void buildTicks (const QwtInterval &, double stepSize, int maxMinSteps, QList< double > ticks[QwtScaleDiv::NTickTypes]) const
 Calculate ticks for an interval. More...
 
QList< double > buildMajorTicks (const QwtInterval &interval, double stepSize) const
 Calculate major ticks for an interval. More...
 
void buildMinorTicks (const QList< double > &majorTicks, int maxMinorSteps, double stepSize, QList< double > &minorTicks, QList< double > &mediumTicks) const
 Calculate minor/medium ticks for major ticks. More...
 
- Protected Member Functions inherited from QwtScaleEngine
bool contains (const QwtInterval &, double val) const
 
QList< double > strip (const QList< double > &, const QwtInterval &) const
 
double divideInterval (double interval, int numSteps) const
 
QwtInterval buildInterval (double v) const
 Build an interval around a value. More...
 
+ + + + + + + +

+Additional Inherited Members

- Public Types inherited from QwtScaleEngine
enum  Attribute {
+  NoAttribute = 0x00, +IncludeReference = 0x01, +Symmetric = 0x02, +Floating = 0x04, +
+  Inverted = 0x08 +
+ }
 
+typedef QFlags< AttributeAttributes
 Layout attributes.
 
+

Detailed Description

+

A scale engine for date/time values.

+

QwtDateScaleEngine builds scales from a time intervals. Together with QwtDateScaleDraw it can be used for axes according to date/time values.

+

Years, months, weeks, days, hours and minutes are organized in steps with non constant intervals. QwtDateScaleEngine classifies intervals and aligns the boundaries and tick positions according to this classification.

+

QwtDateScaleEngine supports representations depending on Qt::TimeSpec specifications. The valid range for scales is limited by the range of QDateTime, that differs between Qt4 and Qt5.

+

Datetime values are expected as the number of milliseconds since 1970-01-01T00:00:00 Universal Coordinated Time - also known as "The Epoch", that can be converted to QDateTime using QwtDate::toDateTime().

+
See Also
QwtDate, QwtPlot::setAxisScaleEngine(), QwtAbstractScale::setScaleEngine()
+

Constructor & Destructor Documentation

+ +
+
+ + + + + + + + +
QwtDateScaleEngine::QwtDateScaleEngine (Qt::TimeSpec timeSpec = Qt::LocalTime)
+
+ +

Constructor.

+

The engine is initialized to build scales for the given time specification. It classifies intervals > 4 weeks as >= Qt::Month. The first week of a year is defined like for QwtDate::FirstThursday.

+
Parameters
+ + +
timeSpecTime specification
+
+
+
See Also
setTimeSpec(), setMaxWeeks(), setWeek0Type()
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
QDateTime QwtDateScaleEngine::alignDate (const QDateTime & dateTime,
double stepSize,
QwtDate::IntervalType intervalType,
bool up 
) const
+
+protectedvirtual
+
+

Align a date/time value for a step size

+

For Qt::Day alignments there is no "natural day 0" - instead the first day of the year is used to avoid jumping major ticks positions when panning a scale. For other alignments ( f.e according to the first day of the month ) alignDate() has to be overloaded.

+
Parameters
+ + + + + +
dateTimeDate/time value
stepSizeStep size
intervalTypeInterval type
upWhen true dateTime is ceiled - otherwise it is floored
+
+
+
Returns
Aligned date/time value
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void QwtDateScaleEngine::autoScale (int maxNumSteps,
double & x1,
double & x2,
double & stepSize 
) const
+
+virtual
+
+

Align and divide an interval

+

The algorithm aligns and divides the interval into steps.

+

Datetime interval divisions are usually not equidistant and the calculated stepSize is can only be used as an approximation for the steps calculated by divideScale().

+
Parameters
+ + + + + +
maxNumStepsMax. number of steps
x1First limit of the interval (In/Out)
x2Second limit of the interval (In/Out)
stepSizeStep size (Out)
+
+
+
See Also
QwtScaleEngine::setAttribute()
+ +

Reimplemented from QwtLinearScaleEngine.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
QwtScaleDiv QwtDateScaleEngine::divideScale (double x1,
double x2,
int maxMajorSteps,
int maxMinorSteps,
double stepSize = 0.0 
) const
+
+virtual
+
+ +

Calculate a scale division for a date/time interval.

+
Parameters
+ + + + + + +
x1First interval limit
x2Second interval limit
maxMajorStepsMaximum for the number of major steps
maxMinorStepsMaximum number of minor steps
stepSizeStep size. If stepSize == 0, the scaleEngine calculates one.
+
+
+
Returns
Calculated scale division
+ +

Reimplemented from QwtLinearScaleEngine.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
QwtDate::IntervalType QwtDateScaleEngine::intervalType (const QDateTime & minDate,
const QDateTime & maxDate,
int maxSteps 
) const
+
+virtual
+
+

Classification of a date/time interval division

+
Parameters
+ + + + +
minDateMinimum ( = earlier ) of the interval
maxDateMaximum ( = later ) of the interval
maxStepsMaximum for the number of steps
+
+
+
Returns
Interval classification
+ +
+
+ +
+
+ + + + + + + +
int QwtDateScaleEngine::maxWeeks () const
+
+
Returns
Upper limit for the number of weeks, when an interval can be classified as Qt::Week.
+
See Also
setMaxWeeks(), week0Type()
+ +
+
+ +
+
+ + + + + + + + +
void QwtDateScaleEngine::setMaxWeeks (int weeks)
+
+

Set a upper limit for the number of weeks, when an interval can be classified as Qt::Week.

+

The default setting is 4 weeks.

+
Parameters
+ + +
weeksUpper limit for the number of weeks
+
+
+
Note
In business charts a year is often devided into weeks [1-52]
+
See Also
maxWeeks(), setWeek0Type()
+ +
+
+ +
+
+ + + + + + + + +
void QwtDateScaleEngine::setTimeSpec (Qt::TimeSpec timeSpec)
+
+

Set the time specification used by the engine

+
Parameters
+ + +
timeSpecTime specification
+
+
+
See Also
timeSpec(), setUtcOffset(), toDateTime()
+ +
+
+ +
+
+ + + + + + + + +
void QwtDateScaleEngine::setUtcOffset (int seconds)
+
+

Set the offset in seconds from Coordinated Universal Time

+
Parameters
+ + +
secondsOffset in seconds
+
+
+
Note
The offset has no effect beside for the time specification Qt::OffsetFromUTC.
+
See Also
QDate::utcOffset(), setTimeSpec(), toDateTime()
+ +
+
+ +
+
+ + + + + + + + +
void QwtDateScaleEngine::setWeek0Type (QwtDate::Week0Type week0Type)
+
+

Sets how to identify the first week of a year.

+
Parameters
+ + +
week0TypeMode how to identify the first week of a year
+
+
+
See Also
week0Type(), setMaxWeeks()
+
Note
week0Type has no effect beside for intervals classified as QwtDate::Week.
+ +
+
+ +
+
+ + + + + + + +
Qt::TimeSpec QwtDateScaleEngine::timeSpec () const
+
+
Returns
Time specification used by the engine
+
See Also
setTimeSpec(), utcOffset(), toDateTime()
+ +
+
+ +
+
+ + + + + + + + +
QDateTime QwtDateScaleEngine::toDateTime (double value) const
+
+

Translate a double value into a QDateTime object.

+

For QDateTime result is bounded by QwtDate::minDate() and QwtDate::maxDate()

+
Returns
QDateTime object initialized with timeSpec() and utcOffset().
+
See Also
timeSpec(), utcOffset(), QwtDate::toDateTime()
+ +
+
+ +
+
+ + + + + + + +
int QwtDateScaleEngine::utcOffset () const
+
+
Returns
Offset in seconds from Coordinated Universal Time
+
Note
The offset has no effect beside for the time specification Qt::OffsetFromUTC.
+
See Also
QDate::setUtcOffset(), setTimeSpec(), toDateTime()
+ +
+
+ +
+
+ + + + + + + +
QwtDate::Week0Type QwtDateScaleEngine::week0Type () const
+
+
Returns
Setting how to identify the first week of a year.
+
See Also
setWeek0Type(), maxWeeks()
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_date_scale_engine__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_date_scale_engine__inherit__graph.map new file mode 100644 index 0000000000..834997564d --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_date_scale_engine__inherit__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_date_scale_engine__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_date_scale_engine__inherit__graph.md5 new file mode 100644 index 0000000000..c2e3dd26ee --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_date_scale_engine__inherit__graph.md5 @@ -0,0 +1 @@ +3f2cddcbe3f2ab72e7b94e575f36e233 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_date_scale_engine__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_date_scale_engine__inherit__graph.png new file mode 100644 index 0000000000..8ff0a22ccf Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_date_scale_engine__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_dial-members.html b/ThirdParty/Qwt/doc/html/class_qwt_dial-members.html new file mode 100644 index 0000000000..6603e3986d --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_dial-members.html @@ -0,0 +1,208 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtDial Member List
+
+
+ +

This is the complete list of members for QwtDial, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
abstractScaleDraw() const QwtAbstractScaleprotected
abstractScaleDraw()QwtAbstractScaleprotected
boundingRect() const QwtDial
changeEvent(QEvent *)QwtDialprotectedvirtual
drawContents(QPainter *) const QwtDialprotectedvirtual
drawFocusIndicator(QPainter *) const QwtDialprotectedvirtual
drawFrame(QPainter *p)QwtDialprotectedvirtual
drawNeedle(QPainter *, const QPointF &, double radius, double direction, QPalette::ColorGroup) const QwtDialprotectedvirtual
drawScale(QPainter *, const QPointF &center, double radius) const QwtDialprotectedvirtual
drawScaleContents(QPainter *painter, const QPointF &center, double radius) const QwtDialprotectedvirtual
frameShadow() const QwtDial
incrementedValue(double value, int stepCount) const QwtAbstractSliderprotected
incrementValue(int numSteps)QwtAbstractSliderprotected
innerRect() const QwtDial
invalidateCache()QwtDialprotected
invertedControls() const QwtAbstractSlider
invTransform(int) const QwtAbstractScale
isInverted() const QwtAbstractScale
isReadOnly() const QwtAbstractSlider
isScrollPosition(const QPoint &) const QwtDialprotectedvirtual
isTracking() const QwtAbstractSlider
isValid() const QwtAbstractSlider
keyPressEvent(QKeyEvent *)QwtAbstractSliderprotectedvirtual
lineWidth() const QwtDial
lowerBound() const QwtAbstractScale
maximum() const QwtAbstractScale
maxScaleArc() const QwtDial
minimum() const QwtAbstractScale
minimumSizeHint() const QwtDialvirtual
minScaleArc() const QwtDial
mode() const QwtDial
Mode enum nameQwtDial
mouseMoveEvent(QMouseEvent *)QwtAbstractSliderprotectedvirtual
mousePressEvent(QMouseEvent *)QwtAbstractSliderprotectedvirtual
mouseReleaseEvent(QMouseEvent *)QwtAbstractSliderprotectedvirtual
needle() const QwtDial
needle()QwtDial
origin() const QwtDial
pageSteps() const QwtAbstractSlider
paintEvent(QPaintEvent *)QwtDialprotectedvirtual
Plain enum valueQwtDial
QwtAbstractScale(QWidget *parent=NULL)QwtAbstractScale
QwtAbstractSlider(QWidget *parent=NULL)QwtAbstractSliderexplicit
QwtDial(QWidget *parent=NULL)QwtDialexplicit
Raised enum valueQwtDial
rescale(double lowerBound, double upperBound, double stepSize)QwtAbstractScaleprotected
RotateNeedle enum valueQwtDial
RotateScale enum valueQwtDial
scaleChange()QwtDialprotectedvirtual
scaleDiv() const QwtAbstractScale
scaleDraw()QwtDial
scaleDraw() const QwtDial
scaleEngine() const QwtAbstractScale
scaleEngine()QwtAbstractScale
scaleInnerRect() const QwtDialvirtual
scaleMap() const QwtAbstractScale
scaleMaxMajor() const QwtAbstractScale
scaleMaxMinor() const QwtAbstractScale
scaleStepSize() const QwtAbstractScale
scrolledTo(const QPoint &) const QwtDialprotectedvirtual
setAbstractScaleDraw(QwtAbstractScaleDraw *)QwtAbstractScaleprotected
setFrameShadow(Shadow)QwtDial
setInvertedControls(bool)QwtAbstractSlider
setLineWidth(int)QwtDial
setLowerBound(double value)QwtAbstractScale
setMaxScaleArc(double min)QwtDial
setMinScaleArc(double min)QwtDial
setMode(Mode)QwtDial
setNeedle(QwtDialNeedle *)QwtDial
setOrigin(double)QwtDialvirtual
setPageSteps(uint)QwtAbstractSlider
setReadOnly(bool)QwtAbstractSlider
setScale(double lowerBound, double upperBound)QwtAbstractScale
setScale(const QwtInterval &)QwtAbstractScale
setScale(const QwtScaleDiv &)QwtAbstractScale
setScaleArc(double min, double max)QwtDial
setScaleDraw(QwtRoundScaleDraw *)QwtDial
setScaleEngine(QwtScaleEngine *)QwtAbstractScale
setScaleMaxMajor(int ticks)QwtAbstractScale
setScaleMaxMinor(int ticks)QwtAbstractScale
setScaleStepSize(double stepSize)QwtAbstractScale
setSingleSteps(uint)QwtAbstractSlider
setStepAlignment(bool)QwtAbstractSlider
setTotalSteps(uint)QwtAbstractSlider
setTracking(bool)QwtAbstractSlider
setUpperBound(double value)QwtAbstractScale
setValid(bool)QwtAbstractSlider
setValue(double val)QwtAbstractSliderslot
setWrapping(bool)QwtAbstractSlider
Shadow enum nameQwtDial
singleSteps() const QwtAbstractSlider
sizeHint() const QwtDialvirtual
sliderChange()QwtDialprotectedvirtual
sliderMoved(double value)QwtAbstractSlidersignal
sliderPressed()QwtAbstractSlidersignal
sliderReleased()QwtAbstractSlidersignal
stepAlignment() const QwtAbstractSlider
Sunken enum valueQwtDial
totalSteps() const QwtAbstractSlider
transform(double) const QwtAbstractScale
upperBound() const QwtAbstractScale
value() const QwtAbstractSlider
valueChanged(double value)QwtAbstractSlidersignal
wheelEvent(QWheelEvent *)QwtDialprotectedvirtual
wrapping() const QwtAbstractSlider
~QwtAbstractScale()QwtAbstractScalevirtual
~QwtAbstractSlider()QwtAbstractSlidervirtual
~QwtDial()QwtDialvirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_dial.html b/ThirdParty/Qwt/doc/html/class_qwt_dial.html new file mode 100644 index 0000000000..eb08bc216f --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_dial.html @@ -0,0 +1,1479 @@ + + + + + + +Qwt User's Guide: QwtDial Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+ +
+ +

QwtDial class provides a rounded range control. + More...

+ +

#include <qwt_dial.h>

+
+Inheritance diagram for QwtDial:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + +

+Public Types

enum  Shadow { Plain = QFrame::Plain, +Raised = QFrame::Raised, +Sunken = QFrame::Sunken + }
 Frame shadow. More...
 
enum  Mode { RotateNeedle, +RotateScale + }
 Mode controlling whether the needle or the scale is rotating. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 QwtDial (QWidget *parent=NULL)
 Constructor. More...
 
+virtual ~QwtDial ()
 Destructor.
 
void setFrameShadow (Shadow)
 
Shadow frameShadow () const
 
void setLineWidth (int)
 
int lineWidth () const
 
void setMode (Mode)
 Change the mode of the dial. More...
 
Mode mode () const
 
void setScaleArc (double min, double max)
 
void setMinScaleArc (double min)
 
double minScaleArc () const
 
void setMaxScaleArc (double min)
 
double maxScaleArc () const
 
virtual void setOrigin (double)
 Change the origin. More...
 
double origin () const
 
void setNeedle (QwtDialNeedle *)
 
const QwtDialNeedleneedle () const
 
QwtDialNeedleneedle ()
 
QRect boundingRect () const
 
QRect innerRect () const
 
virtual QRect scaleInnerRect () const
 
virtual QSize sizeHint () const
 
virtual QSize minimumSizeHint () const
 
void setScaleDraw (QwtRoundScaleDraw *)
 
QwtRoundScaleDrawscaleDraw ()
 
const QwtRoundScaleDrawscaleDraw () const
 
- Public Member Functions inherited from QwtAbstractSlider
 QwtAbstractSlider (QWidget *parent=NULL)
 Constructor. More...
 
+virtual ~QwtAbstractSlider ()
 Destructor.
 
void setValid (bool)
 
bool isValid () const
 
+double value () const
 Returns the current value.
 
void setWrapping (bool)
 
bool wrapping () const
 
void setTotalSteps (uint)
 Set the number of steps. More...
 
uint totalSteps () const
 
void setSingleSteps (uint)
 Set the number of steps for a single increment. More...
 
uint singleSteps () const
 
void setPageSteps (uint)
 Set the number of steps for a page increment. More...
 
uint pageSteps () const
 
void setStepAlignment (bool)
 Enable step alignment. More...
 
bool stepAlignment () const
 
void setTracking (bool)
 Enables or disables tracking. More...
 
bool isTracking () const
 
void setReadOnly (bool)
 
bool isReadOnly () const
 
void setInvertedControls (bool)
 
bool invertedControls () const
 
- Public Member Functions inherited from QwtAbstractScale
 QwtAbstractScale (QWidget *parent=NULL)
 
+virtual ~QwtAbstractScale ()
 Destructor.
 
void setScale (double lowerBound, double upperBound)
 Specify a scale. More...
 
void setScale (const QwtInterval &)
 Specify a scale. More...
 
void setScale (const QwtScaleDiv &)
 Specify a scale. More...
 
const QwtScaleDivscaleDiv () const
 
void setLowerBound (double value)
 
double lowerBound () const
 
void setUpperBound (double value)
 
double upperBound () const
 
void setScaleStepSize (double stepSize)
 Set the step size used for calculating a scale division. More...
 
double scaleStepSize () const
 
void setScaleMaxMajor (int ticks)
 Set the maximum number of major tick intervals. More...
 
int scaleMaxMinor () const
 
void setScaleMaxMinor (int ticks)
 Set the maximum number of minor tick intervals. More...
 
int scaleMaxMajor () const
 
void setScaleEngine (QwtScaleEngine *)
 Set a scale engine. More...
 
const QwtScaleEnginescaleEngine () const
 
QwtScaleEnginescaleEngine ()
 
int transform (double) const
 
double invTransform (int) const
 
bool isInverted () const
 
double minimum () const
 
double maximum () const
 
const QwtScaleMapscaleMap () const
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Protected Member Functions

virtual void wheelEvent (QWheelEvent *)
 
virtual void paintEvent (QPaintEvent *)
 
virtual void changeEvent (QEvent *)
 
virtual void drawFrame (QPainter *p)
 
virtual void drawContents (QPainter *) const
 Draw the contents inside the frame. More...
 
virtual void drawFocusIndicator (QPainter *) const
 
void invalidateCache ()
 
virtual void drawScale (QPainter *, const QPointF &center, double radius) const
 
virtual void drawScaleContents (QPainter *painter, const QPointF &center, double radius) const
 
virtual void drawNeedle (QPainter *, const QPointF &, double radius, double direction, QPalette::ColorGroup) const
 
virtual double scrolledTo (const QPoint &) const
 Determine the value for a new position of the slider handle. More...
 
virtual bool isScrollPosition (const QPoint &) const
 Determine what to do when the user presses a mouse button. More...
 
+virtual void sliderChange ()
 Calling update()
 
virtual void scaleChange ()
 
- Protected Member Functions inherited from QwtAbstractSlider
virtual void mousePressEvent (QMouseEvent *)
 
virtual void mouseReleaseEvent (QMouseEvent *)
 
virtual void mouseMoveEvent (QMouseEvent *)
 
virtual void keyPressEvent (QKeyEvent *)
 
void incrementValue (int numSteps)
 
double incrementedValue (double value, int stepCount) const
 
- Protected Member Functions inherited from QwtAbstractScale
void rescale (double lowerBound, double upperBound, double stepSize)
 
void setAbstractScaleDraw (QwtAbstractScaleDraw *)
 Set a scale draw. More...
 
const QwtAbstractScaleDrawabstractScaleDraw () const
 
QwtAbstractScaleDrawabstractScaleDraw ()
 
+ + + + + + + + + + + + + + +

+Additional Inherited Members

- Public Slots inherited from QwtAbstractSlider
void setValue (double val)
 
- Signals inherited from QwtAbstractSlider
void valueChanged (double value)
 Notify a change of value. More...
 
void sliderPressed ()
 
void sliderReleased ()
 
void sliderMoved (double value)
 
+

Detailed Description

+

QwtDial class provides a rounded range control.

+

QwtDial is intended as base class for dial widgets like speedometers, compass widgets, clocks ...

+
+dials2.png +
+

A dial contains a scale and a needle indicating the current value of the dial. Depending on Mode one of them is fixed and the other is rotating. If not isReadOnly() the dial can be rotated by dragging the mouse or using keyboard inputs (see QwtAbstractSlider::keyPressEvent()). A dial might be wrapping, what means a rotation below/above one limit continues on the other limit (f.e compass). The scale might cover any arc of the dial, its values are related to the origin() of the dial.

+

Often dials have to be updated very often according to values from external devices. For these high refresh rates QwtDial caches as much as possible. For derived classes it might be necessary to clear these caches manually according to attribute changes using invalidateCache().

+
See Also
QwtCompass, QwtAnalogClock, QwtDialNeedle
+
Note
The controls and dials examples shows different types of dials.
+
+QDial is more similar to QwtKnob than to QwtDial
+

Member Enumeration Documentation

+ +
+
+ + + + +
enum QwtDial::Mode
+
+ +

Mode controlling whether the needle or the scale is rotating.

+ + + +
Enumerator
RotateNeedle  +

The needle is rotating.

+
RotateScale  +

The needle is fixed, the scales are rotating.

+
+ +
+
+ +
+
+ + + + +
enum QwtDial::Shadow
+
+ +

Frame shadow.

+

Unfortunately it is not possible to use QFrame::Shadow as a property of a widget that is not derived from QFrame. The following enum is made for the designer only. It is safe to use QFrame::Shadow instead.

+ + + + +
Enumerator
Plain  +

QFrame::Plain.

+
Raised  +

QFrame::Raised.

+
Sunken  +

QFrame::Sunken.

+
+ +
+
+

Constructor & Destructor Documentation

+ +
+
+ + + + + +
+ + + + + + + + +
QwtDial::QwtDial (QWidget * parent = NULL)
+
+explicit
+
+ +

Constructor.

+
Parameters
+ + +
parentParent widget
+
+
+

Create a dial widget with no needle. The scale is initialized to [ 0.0, 360.0 ] and 360 steps ( QwtAbstractSlider::setTotalSteps() ). The origin of the scale is at 90°,

+

The value is set to 0.0.

+

The default mode is QwtDial::RotateNeedle.

+ +
+
+

Member Function Documentation

+ +
+
+ + + + + + + +
QRect QwtDial::boundingRect () const
+
+
Returns
bounding rectangle of the dial including the frame
+
See Also
setLineWidth(), scaleInnerRect(), innerRect()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtDial::changeEvent (QEvent * event)
+
+protectedvirtual
+
+

Change Event handler

+
Parameters
+ + +
eventChange event
+
+
+

Invalidates internal paint caches if necessary

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtDial::drawContents (QPainter * painter) const
+
+protectedvirtual
+
+ +

Draw the contents inside the frame.

+

QPalette::Window is the background color outside of the frame. QPalette::Base is the background color inside the frame. QPalette::WindowText is the background color inside the scale.

+
Parameters
+ + +
painterPainter
+
+
+
See Also
boundingRect(), innerRect(), scaleInnerRect(), QWidget::setPalette()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtDial::drawFocusIndicator (QPainter * painter) const
+
+protectedvirtual
+
+

Draw the focus indicator

+
Parameters
+ + +
painterPainter
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtDial::drawFrame (QPainter * painter)
+
+protectedvirtual
+
+

Draw the frame around the dial

+
Parameters
+ + +
painterPainter
+
+
+
See Also
lineWidth(), frameShadow()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void QwtDial::drawNeedle (QPainter * painter,
const QPointF & center,
double radius,
double direction,
QPalette::ColorGroup colorGroup 
) const
+
+protectedvirtual
+
+

Draw the needle

+
Parameters
+ + + + + + +
painterPainter
centerCenter of the dial
radiusLength for the needle
directionDirection of the needle in degrees, counter clockwise
colorGroupColorGroup
+
+
+ +

Reimplemented in QwtAnalogClock.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
void QwtDial::drawScale (QPainter * painter,
const QPointF & center,
double radius 
) const
+
+protectedvirtual
+
+

Draw the scale

+
Parameters
+ + + + +
painterPainter
centerCenter of the dial
radiusRadius of the scale
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
void QwtDial::drawScaleContents (QPainter * painter,
const QPointF & center,
double radius 
) const
+
+protectedvirtual
+
+

Draw the contents inside the scale

+

Paints nothing.

+
Parameters
+ + + + +
painterPainter
centerCenter of the contents circle
radiusRadius of the contents circle
+
+
+ +

Reimplemented in QwtCompass.

+ +
+
+ +
+
+ + + + + + + +
QwtDial::Shadow QwtDial::frameShadow () const
+
+
Returns
Frame shadow /sa setFrameShadow(), lineWidth(), QFrame::frameShadow()
+ +
+
+ +
+
+ + + + + + + +
QRect QwtDial::innerRect () const
+
+
Returns
bounding rectangle of the circle inside the frame
+
See Also
setLineWidth(), scaleInnerRect(), boundingRect()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void QwtDial::invalidateCache ()
+
+protected
+
+

Invalidate the internal caches used to speed up repainting

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool QwtDial::isScrollPosition (const QPoint & pos) const
+
+protectedvirtual
+
+ +

Determine what to do when the user presses a mouse button.

+
Parameters
+ + +
posMouse position
+
+
+
Return values
+ + +
True,whenthe inner circle contains pos
+
+
+
See Also
scrolledTo()
+ +

Implements QwtAbstractSlider.

+ +
+
+ +
+
+ + + + + + + +
int QwtDial::lineWidth () const
+
+
Returns
Line width of the frame
+
See Also
setLineWidth(), frameShadow(), lineWidth()
+ +
+
+ +
+
+ + + + + + + +
double QwtDial::maxScaleArc () const
+
+
Returns
Upper limit of the scale arc
+
See Also
setScaleArc()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
QSize QwtDial::minimumSizeHint () const
+
+virtual
+
+
Returns
Minimum size hint
+
See Also
sizeHint()
+ +
+
+ +
+
+ + + + + + + +
double QwtDial::minScaleArc () const
+
+
Returns
Lower limit of the scale arc
+
See Also
setScaleArc()
+ +
+
+ +
+
+ + + + + + + +
QwtDial::Mode QwtDial::mode () const
+
+
Returns
Mode of the dial.
+
See Also
setMode(), origin(), setScaleArc(), value()
+ +
+
+ +
+
+ + + + + + + +
const QwtDialNeedle * QwtDial::needle () const
+
+
Returns
needle
+
See Also
setNeedle()
+ +
+
+ +
+
+ + + + + + + +
QwtDialNeedle * QwtDial::needle ()
+
+
Returns
needle
+
See Also
setNeedle()
+ +
+
+ +
+
+ + + + + + + +
double QwtDial::origin () const
+
+

The origin is the angle where scale and needle is relative to.

+
Returns
Origin of the dial
+
See Also
setOrigin()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtDial::paintEvent (QPaintEvent * event)
+
+protectedvirtual
+
+

Paint the dial

+
Parameters
+ + +
eventPaint event
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void QwtDial::scaleChange ()
+
+protectedvirtual
+
+

Invalidate the internal caches and call QwtAbstractSlider::scaleChange()

+ +

Reimplemented from QwtAbstractSlider.

+ +
+
+ +
+
+ + + + + + + +
QwtRoundScaleDraw * QwtDial::scaleDraw ()
+
+
Returns
the scale draw
+ +
+
+ +
+
+ + + + + + + +
const QwtRoundScaleDraw * QwtDial::scaleDraw () const
+
+
Returns
the scale draw
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
QRect QwtDial::scaleInnerRect () const
+
+virtual
+
+
Returns
rectangle inside the scale
+
See Also
setLineWidth(), boundingRect(), innerRect()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
double QwtDial::scrolledTo (const QPoint & pos) const
+
+protectedvirtual
+
+ +

Determine the value for a new position of the slider handle.

+
Parameters
+ + +
posMouse position
+
+
+
Returns
Value for the mouse position
+
See Also
isScrollPosition()
+ +

Implements QwtAbstractSlider.

+ +
+
+ +
+
+ + + + + + + + +
void QwtDial::setFrameShadow (Shadow shadow)
+
+

Sets the frame shadow value from the frame style.

+
Parameters
+ + +
shadowFrame shadow
+
+
+
See Also
setLineWidth(), QFrame::setFrameShadow()
+ +
+
+ +
+
+ + + + + + + + +
void QwtDial::setLineWidth (int lineWidth)
+
+

Sets the line width of the frame

+
Parameters
+ + +
lineWidthLine width
+
+
+
See Also
setFrameShadow()
+ +
+
+ +
+
+ + + + + + + + +
void QwtDial::setMaxScaleArc (double max)
+
+

Set the upper limit for the scale arc

+
Parameters
+ + +
maxUpper limit of the scale arc
+
+
+
See Also
setScaleArc(), setMinScaleArc()
+ +
+
+ +
+
+ + + + + + + + +
void QwtDial::setMinScaleArc (double min)
+
+

Set the lower limit for the scale arc

+
Parameters
+ + +
minLower limit of the scale arc
+
+
+
See Also
setScaleArc(), setMaxScaleArc()
+ +
+
+ +
+
+ + + + + + + + +
void QwtDial::setMode (Mode mode)
+
+ +

Change the mode of the dial.

+
Parameters
+ + +
modeNew mode
+
+
+

In case of QwtDial::RotateNeedle the needle is rotating, in case of QwtDial::RotateScale, the needle points to origin() and the scale is rotating.

+

The default mode is QwtDial::RotateNeedle.

+
See Also
mode(), setValue(), setOrigin()
+ +
+
+ +
+
+ + + + + + + + +
void QwtDial::setNeedle (QwtDialNeedleneedle)
+
+

Set a needle for the dial

+
Parameters
+ + +
needleNeedle
+
+
+
Warning
The needle will be deleted, when a different needle is set or in ~QwtDial()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtDial::setOrigin (double origin)
+
+virtual
+
+ +

Change the origin.

+

The origin is the angle where scale and needle is relative to.

+
Parameters
+ + +
originNew origin
+
+
+
See Also
origin()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtDial::setScaleArc (double minArc,
double maxArc 
)
+
+

Change the arc of the scale

+
Parameters
+ + + +
minArcLower limit
maxArcUpper limit
+
+
+
See Also
minScaleArc(), maxScaleArc()
+ +
+
+ +
+
+ + + + + + + + +
void QwtDial::setScaleDraw (QwtRoundScaleDrawscaleDraw)
+
+

Set an individual scale draw

+

The motivation for setting a scale draw is often to overload QwtRoundScaleDraw::label() to return individual tick labels.

+
Parameters
+ + +
scaleDrawScale draw
+
+
+
Warning
The previous scale draw is deleted
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
QSize QwtDial::sizeHint () const
+
+virtual
+
+
Returns
Size hint
+
See Also
minimumSizeHint()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtDial::wheelEvent (QWheelEvent * event)
+
+protectedvirtual
+
+

Wheel Event handler

+
Parameters
+ + +
eventWheel event
+
+
+ +

Reimplemented from QwtAbstractSlider.

+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_dial__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_dial__inherit__graph.map new file mode 100644 index 0000000000..5bdf6f5c76 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_dial__inherit__graph.map @@ -0,0 +1,6 @@ + + + + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_dial__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_dial__inherit__graph.md5 new file mode 100644 index 0000000000..8bae7758d1 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_dial__inherit__graph.md5 @@ -0,0 +1 @@ +c23dbb9b5cc2f8e412f6cdbaf455adbb \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_dial__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_dial__inherit__graph.png new file mode 100644 index 0000000000..6a95a013de Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_dial__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_dial_needle-members.html b/ThirdParty/Qwt/doc/html/class_qwt_dial_needle-members.html new file mode 100644 index 0000000000..3a3f42bdd8 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_dial_needle-members.html @@ -0,0 +1,107 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtDialNeedle Member List
+
+
+ +

This is the complete list of members for QwtDialNeedle, including all inherited members.

+ + + + + + + + +
draw(QPainter *painter, const QPointF &center, double length, double direction, QPalette::ColorGroup=QPalette::Active) const QwtDialNeedlevirtual
drawKnob(QPainter *, double width, const QBrush &, bool sunken) const QwtDialNeedleprotectedvirtual
drawNeedle(QPainter *painter, double length, QPalette::ColorGroup colorGroup) const =0QwtDialNeedleprotectedpure virtual
palette() const QwtDialNeedle
QwtDialNeedle()QwtDialNeedle
setPalette(const QPalette &)QwtDialNeedlevirtual
~QwtDialNeedle()QwtDialNeedlevirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_dial_needle.html b/ThirdParty/Qwt/doc/html/class_qwt_dial_needle.html new file mode 100644 index 0000000000..78ff129c56 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_dial_needle.html @@ -0,0 +1,311 @@ + + + + + + +Qwt User's Guide: QwtDialNeedle Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtDialNeedle Class Referenceabstract
+
+
+ +

Base class for needles that can be used in a QwtDial. + More...

+ +

#include <qwt_dial_needle.h>

+
+Inheritance diagram for QwtDialNeedle:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + + + + + + + +

+Public Member Functions

QwtDialNeedle ()
 Constructor.
 
+virtual ~QwtDialNeedle ()
 Destructor.
 
virtual void setPalette (const QPalette &)
 
const QPalette & palette () const
 
virtual void draw (QPainter *painter, const QPointF &center, double length, double direction, QPalette::ColorGroup=QPalette::Active) const
 
+ + + + + + + +

+Protected Member Functions

virtual void drawNeedle (QPainter *painter, double length, QPalette::ColorGroup colorGroup) const =0
 Draw the needle. More...
 
+virtual void drawKnob (QPainter *, double width, const QBrush &, bool sunken) const
 Draw the knob.
 
+

Detailed Description

+

Base class for needles that can be used in a QwtDial.

+

QwtDialNeedle is a pointer that indicates a value by pointing to a specific direction.

+
See Also
QwtDial, QwtCompass
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void QwtDialNeedle::draw (QPainter * painter,
const QPointF & center,
double length,
double direction,
QPalette::ColorGroup colorGroup = QPalette::Active 
) const
+
+virtual
+
+

Draw the needle

+
Parameters
+ + + + + + +
painterPainter
centerCenter of the dial, start position for the needle
lengthLength of the needle
directionDirection of the needle, in degrees counter clockwise
colorGroupColor group, used for painting
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
virtual void QwtDialNeedle::drawNeedle (QPainter * painter,
double length,
QPalette::ColorGroup colorGroup 
) const
+
+protectedpure virtual
+
+ +

Draw the needle.

+

The origin of the needle is at position (0.0, 0.0 ) pointing in direction 0.0 ( = east ).

+

The painter is already initialized with translation and rotation.

+
Parameters
+ + + + +
painterPainter
lengthLength of the needle
colorGroupColor group, used for painting
+
+
+
See Also
setPalette(), palette()
+ +

Implemented in QwtCompassWindArrow, QwtCompassMagnetNeedle, and QwtDialSimpleNeedle.

+ +
+
+ +
+
+ + + + + + + +
const QPalette & QwtDialNeedle::palette () const
+
+
Returns
the palette of the needle.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtDialNeedle::setPalette (const QPalette & palette)
+
+virtual
+
+

Sets the palette for the needle.

+
Parameters
+ + +
paletteNew Palette
+
+
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_dial_needle__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_dial_needle__inherit__graph.map new file mode 100644 index 0000000000..944519c9b5 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_dial_needle__inherit__graph.map @@ -0,0 +1,5 @@ + + + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_dial_needle__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_dial_needle__inherit__graph.md5 new file mode 100644 index 0000000000..abd25bc02e --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_dial_needle__inherit__graph.md5 @@ -0,0 +1 @@ +f11a335911a5a56f4904ac602862c46e \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_dial_needle__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_dial_needle__inherit__graph.png new file mode 100644 index 0000000000..5345df9467 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_dial_needle__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_dial_simple_needle-members.html b/ThirdParty/Qwt/doc/html/class_qwt_dial_simple_needle-members.html new file mode 100644 index 0000000000..adffcd1960 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_dial_simple_needle-members.html @@ -0,0 +1,113 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtDialSimpleNeedle Member List
+
+
+ +

This is the complete list of members for QwtDialSimpleNeedle, including all inherited members.

+ + + + + + + + + + + + + + +
Arrow enum valueQwtDialSimpleNeedle
draw(QPainter *painter, const QPointF &center, double length, double direction, QPalette::ColorGroup=QPalette::Active) const QwtDialNeedlevirtual
drawKnob(QPainter *, double width, const QBrush &, bool sunken) const QwtDialNeedleprotectedvirtual
drawNeedle(QPainter *, double length, QPalette::ColorGroup) const QwtDialSimpleNeedleprotectedvirtual
palette() const QwtDialNeedle
QwtDialNeedle()QwtDialNeedle
QwtDialSimpleNeedle(Style, bool hasKnob=true, const QColor &mid=Qt::gray, const QColor &base=Qt::darkGray)QwtDialSimpleNeedle
Ray enum valueQwtDialSimpleNeedle
setPalette(const QPalette &)QwtDialNeedlevirtual
setWidth(double width)QwtDialSimpleNeedle
Style enum nameQwtDialSimpleNeedle
width() const QwtDialSimpleNeedle
~QwtDialNeedle()QwtDialNeedlevirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_dial_simple_needle.html b/ThirdParty/Qwt/doc/html/class_qwt_dial_simple_needle.html new file mode 100644 index 0000000000..8dfeed6ae4 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_dial_simple_needle.html @@ -0,0 +1,332 @@ + + + + + + +Qwt User's Guide: QwtDialSimpleNeedle Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtDialSimpleNeedle Class Reference
+
+
+ +

A needle for dial widgets. + More...

+ +

#include <qwt_dial_needle.h>

+
+Inheritance diagram for QwtDialSimpleNeedle:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + +

+Public Types

enum  Style { Arrow, +Ray + }
 Style of the needle. More...
 
+ + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 QwtDialSimpleNeedle (Style, bool hasKnob=true, const QColor &mid=Qt::gray, const QColor &base=Qt::darkGray)
 
void setWidth (double width)
 
double width () const
 
- Public Member Functions inherited from QwtDialNeedle
QwtDialNeedle ()
 Constructor.
 
+virtual ~QwtDialNeedle ()
 Destructor.
 
virtual void setPalette (const QPalette &)
 
const QPalette & palette () const
 
virtual void draw (QPainter *painter, const QPointF &center, double length, double direction, QPalette::ColorGroup=QPalette::Active) const
 
+ + + + + + + +

+Protected Member Functions

virtual void drawNeedle (QPainter *, double length, QPalette::ColorGroup) const
 
- Protected Member Functions inherited from QwtDialNeedle
+virtual void drawKnob (QPainter *, double width, const QBrush &, bool sunken) const
 Draw the knob.
 
+

Detailed Description

+

A needle for dial widgets.

+

The following colors are used:

+
    +
  • QPalette::Mid
    + Pointer
  • +
  • QPalette::Base
    + Knob
  • +
+
See Also
QwtDial, QwtCompass
+

Member Enumeration Documentation

+ +
+
+ + + + +
enum QwtDialSimpleNeedle::Style
+
+ +

Style of the needle.

+ + + +
Enumerator
Arrow  +

Arrow.

+
Ray  +

A straight line from the center.

+
+ +
+
+

Constructor & Destructor Documentation

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
QwtDialSimpleNeedle::QwtDialSimpleNeedle (Style style,
bool hasKnob = true,
const QColor & mid = Qt::gray,
const QColor & base = Qt::darkGray 
)
+
+

Constructor

+
Parameters
+ + + + + +
styleStyle
hasKnobWith/Without knob
midMiddle color
baseBase color
+
+
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
void QwtDialSimpleNeedle::drawNeedle (QPainter * painter,
double length,
QPalette::ColorGroup colorGroup 
) const
+
+protectedvirtual
+
+

Draw the needle

+
Parameters
+ + + + +
painterPainter
lengthLength of the needle
colorGroupColor group, used for painting
+
+
+ +

Implements QwtDialNeedle.

+ +
+
+ +
+
+ + + + + + + + +
void QwtDialSimpleNeedle::setWidth (double width)
+
+

Set the width of the needle

+
Parameters
+ + +
widthWidth
+
+
+
See Also
width()
+ +
+
+ +
+
+ + + + + + + +
double QwtDialSimpleNeedle::width () const
+
+
Returns
the width of the needle
+
See Also
setWidth()
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_dial_simple_needle__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_dial_simple_needle__inherit__graph.map new file mode 100644 index 0000000000..c53a106715 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_dial_simple_needle__inherit__graph.map @@ -0,0 +1,3 @@ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_dial_simple_needle__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_dial_simple_needle__inherit__graph.md5 new file mode 100644 index 0000000000..73d1f86c4a --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_dial_simple_needle__inherit__graph.md5 @@ -0,0 +1 @@ +efc66b4474ae0c248e681a7a0ad72100 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_dial_simple_needle__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_dial_simple_needle__inherit__graph.png new file mode 100644 index 0000000000..98c91b52a3 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_dial_simple_needle__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_dyn_grid_layout-members.html b/ThirdParty/Qwt/doc/html/class_qwt_dyn_grid_layout-members.html new file mode 100644 index 0000000000..7a18141cb7 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_dyn_grid_layout-members.html @@ -0,0 +1,125 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtDynGridLayout Member List
+
+
+ +

This is the complete list of members for QwtDynGridLayout, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
addItem(QLayoutItem *)QwtDynGridLayoutvirtual
columnsForWidth(int width) const QwtDynGridLayoutvirtual
count() const QwtDynGridLayoutvirtual
expandingDirections() const QwtDynGridLayoutvirtual
hasHeightForWidth() const QwtDynGridLayoutvirtual
heightForWidth(int) const QwtDynGridLayoutvirtual
invalidate()QwtDynGridLayoutvirtual
isEmpty() const QwtDynGridLayoutvirtual
itemAt(int index) const QwtDynGridLayoutvirtual
itemCount() const QwtDynGridLayout
layoutGrid(uint numCols, QVector< int > &rowHeight, QVector< int > &colWidth) const QwtDynGridLayoutprotected
layoutItems(const QRect &, uint numCols) const QwtDynGridLayout
maxColumns() const QwtDynGridLayout
maxItemWidth() const QwtDynGridLayoutvirtual
numColumns() const QwtDynGridLayout
numRows() const QwtDynGridLayout
QwtDynGridLayout(QWidget *, int margin=0, int space=-1)QwtDynGridLayoutexplicit
QwtDynGridLayout(int space=-1)QwtDynGridLayoutexplicit
setExpandingDirections(Qt::Orientations)QwtDynGridLayout
setGeometry(const QRect &rect)QwtDynGridLayoutvirtual
setMaxColumns(uint maxCols)QwtDynGridLayout
sizeHint() const QwtDynGridLayoutvirtual
stretchGrid(const QRect &rect, uint numCols, QVector< int > &rowHeight, QVector< int > &colWidth) const QwtDynGridLayoutprotected
takeAt(int index)QwtDynGridLayoutvirtual
~QwtDynGridLayout()QwtDynGridLayoutvirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_dyn_grid_layout.html b/ThirdParty/Qwt/doc/html/class_qwt_dyn_grid_layout.html new file mode 100644 index 0000000000..61800eb6c3 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_dyn_grid_layout.html @@ -0,0 +1,863 @@ + + + + + + +Qwt User's Guide: QwtDynGridLayout Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtDynGridLayout Class Reference
+
+
+ +

The QwtDynGridLayout class lays out widgets in a grid, adjusting the number of columns and rows to the current size. + More...

+ +

#include <qwt_dyngrid_layout.h>

+
+Inheritance diagram for QwtDynGridLayout:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 QwtDynGridLayout (QWidget *, int margin=0, int space=-1)
 
 QwtDynGridLayout (int space=-1)
 
+virtual ~QwtDynGridLayout ()
 Destructor.
 
+virtual void invalidate ()
 Invalidate all internal caches.
 
void setMaxColumns (uint maxCols)
 
uint maxColumns () const
 Return the upper limit for the number of columns. More...
 
uint numRows () const
 
uint numColumns () const
 
virtual void addItem (QLayoutItem *)
 Add an item to the next free position. More...
 
virtual QLayoutItem * itemAt (int index) const
 
virtual QLayoutItem * takeAt (int index)
 
virtual int count () const
 
void setExpandingDirections (Qt::Orientations)
 
virtual Qt::Orientations expandingDirections () const
 Returns whether this layout can make use of more space than sizeHint(). More...
 
QList< QRect > layoutItems (const QRect &, uint numCols) const
 
virtual int maxItemWidth () const
 
virtual void setGeometry (const QRect &rect)
 
virtual bool hasHeightForWidth () const
 
virtual int heightForWidth (int) const
 
virtual QSize sizeHint () const
 
virtual bool isEmpty () const
 
uint itemCount () const
 
virtual uint columnsForWidth (int width) const
 Calculate the number of columns for a given width. More...
 
+ + + + + +

+Protected Member Functions

void layoutGrid (uint numCols, QVector< int > &rowHeight, QVector< int > &colWidth) const
 
void stretchGrid (const QRect &rect, uint numCols, QVector< int > &rowHeight, QVector< int > &colWidth) const
 
+

Detailed Description

+

The QwtDynGridLayout class lays out widgets in a grid, adjusting the number of columns and rows to the current size.

+

QwtDynGridLayout takes the space it gets, divides it up into rows and columns, and puts each of the widgets it manages into the correct cell(s). It lays out as many number of columns as possible (limited by maxColumns()).

+

Constructor & Destructor Documentation

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
QwtDynGridLayout::QwtDynGridLayout (QWidget * parent,
int margin = 0,
int spacing = -1 
)
+
+explicit
+
+
Parameters
+ + + + +
parentParent widget
marginMargin
spacingSpacing
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
QwtDynGridLayout::QwtDynGridLayout (int spacing = -1)
+
+explicit
+
+
Parameters
+ + +
spacingSpacing
+
+
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + + +
void QwtDynGridLayout::addItem (QLayoutItem * item)
+
+virtual
+
+ +

Add an item to the next free position.

+
Parameters
+ + +
itemLayout item
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
uint QwtDynGridLayout::columnsForWidth (int width) const
+
+virtual
+
+ +

Calculate the number of columns for a given width.

+

The calculation tries to use as many columns as possible ( limited by maxColumns() )

+
Parameters
+ + +
widthAvailable width for all columns
+
+
+
Returns
Number of columns for a given width
+
See Also
maxColumns(), setMaxColumns()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
int QwtDynGridLayout::count () const
+
+virtual
+
+
Returns
Number of items in the layout
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
Qt::Orientations QwtDynGridLayout::expandingDirections () const
+
+virtual
+
+ +

Returns whether this layout can make use of more space than sizeHint().

+

A value of Qt::Vertical or Qt::Horizontal means that it wants to grow in only one dimension, while Qt::Vertical | Qt::Horizontal means that it wants to grow in both dimensions.

+
Returns
Orientations, where the layout expands
+
See Also
setExpandingDirections()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool QwtDynGridLayout::hasHeightForWidth () const
+
+virtual
+
+
Returns
true: QwtDynGridLayout implements heightForWidth().
+
See Also
heightForWidth()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
int QwtDynGridLayout::heightForWidth (int width) const
+
+virtual
+
+
Returns
The preferred height for this layout, given a width.
+
See Also
hasHeightForWidth()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool QwtDynGridLayout::isEmpty () const
+
+virtual
+
+
Returns
true if this layout is empty.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
QLayoutItem * QwtDynGridLayout::itemAt (int index) const
+
+virtual
+
+

Find the item at a specific index

+
Parameters
+ + +
indexIndex
+
+
+
Returns
Item at a specific index
+
See Also
takeAt()
+ +
+
+ +
+
+ + + + + + + +
uint QwtDynGridLayout::itemCount () const
+
+
Returns
number of layout items
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
void QwtDynGridLayout::layoutGrid (uint numColumns,
QVector< int > & rowHeight,
QVector< int > & colWidth 
) const
+
+protected
+
+

Calculate the dimensions for the columns and rows for a grid of numColumns columns.

+
Parameters
+ + + + +
numColumnsNumber of columns.
rowHeightArray where to fill in the calculated row heights.
colWidthArray where to fill in the calculated column widths.
+
+
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
QList< QRect > QwtDynGridLayout::layoutItems (const QRect & rect,
uint numColumns 
) const
+
+

Calculate the geometries of the layout items for a layout with numColumns columns and a given rectangle.

+
Parameters
+ + + +
rectRect where to place the items
numColumnsNumber of columns
+
+
+
Returns
item geometries
+ +
+
+ +
+
+ + + + + + + +
uint QwtDynGridLayout::maxColumns () const
+
+ +

Return the upper limit for the number of columns.

+

0 means unlimited, what is the default.

+
Returns
Upper limit for the number of columns
+
See Also
setMaxColumns()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
int QwtDynGridLayout::maxItemWidth () const
+
+virtual
+
+
Returns
the maximum width of all layout items
+ +
+
+ +
+
+ + + + + + + +
uint QwtDynGridLayout::numColumns () const
+
+
Returns
Number of columns of the current layout.
+
See Also
numRows()
+
Warning
The number of columns might change whenever the geometry changes
+ +
+
+ +
+
+ + + + + + + +
uint QwtDynGridLayout::numRows () const
+
+
Returns
Number of rows of the current layout.
+
See Also
numColumns()
+
Warning
The number of rows might change whenever the geometry changes
+ +
+
+ +
+
+ + + + + + + + +
void QwtDynGridLayout::setExpandingDirections (Qt::Orientations expanding)
+
+

Set whether this layout can make use of more space than sizeHint(). A value of Qt::Vertical or Qt::Horizontal means that it wants to grow in only one dimension, while Qt::Vertical | Qt::Horizontal means that it wants to grow in both dimensions. The default value is 0.

+
Parameters
+ + +
expandingOr'd orientations
+
+
+
See Also
expandingDirections()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtDynGridLayout::setGeometry (const QRect & rect)
+
+virtual
+
+

Reorganizes columns and rows and resizes managed items within a rectangle.

+
Parameters
+ + +
rectLayout geometry
+
+
+ +
+
+ +
+
+ + + + + + + + +
void QwtDynGridLayout::setMaxColumns (uint maxColumns)
+
+

Limit the number of columns.

+
Parameters
+ + +
maxColumnsupper limit, 0 means unlimited
+
+
+
See Also
maxColumns()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
QSize QwtDynGridLayout::sizeHint () const
+
+virtual
+
+

Return the size hint. If maxColumns() > 0 it is the size for a grid with maxColumns() columns, otherwise it is the size for a grid with only one row.

+
Returns
Size hint
+
See Also
maxColumns(), setMaxColumns()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void QwtDynGridLayout::stretchGrid (const QRect & rect,
uint numColumns,
QVector< int > & rowHeight,
QVector< int > & colWidth 
) const
+
+protected
+
+

Stretch columns in case of expanding() & QSizePolicy::Horizontal and rows in case of expanding() & QSizePolicy::Vertical to fill the entire rect. Rows and columns are stretched with the same factor.

+
Parameters
+ + + + + +
rectBounding rectangle
numColumnsNumber of columns
rowHeightArray to be filled with the calculated row heights
colWidthArray to be filled with the calculated column widths
+
+
+
See Also
setExpanding(), expanding()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
QLayoutItem * QwtDynGridLayout::takeAt (int index)
+
+virtual
+
+

Find the item at a specific index and remove it from the layout

+
Parameters
+ + +
indexIndex
+
+
+
Returns
Layout item, removed from the layout
+
See Also
itemAt()
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_dyn_grid_layout__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_dyn_grid_layout__inherit__graph.map new file mode 100644 index 0000000000..96051b3bd0 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_dyn_grid_layout__inherit__graph.map @@ -0,0 +1,2 @@ + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_dyn_grid_layout__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_dyn_grid_layout__inherit__graph.md5 new file mode 100644 index 0000000000..99cd60f4ef --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_dyn_grid_layout__inherit__graph.md5 @@ -0,0 +1 @@ +d098fddddef59b23ed29e4d1143d7519 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_dyn_grid_layout__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_dyn_grid_layout__inherit__graph.png new file mode 100644 index 0000000000..3c4a7e4a72 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_dyn_grid_layout__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_event_pattern-members.html b/ThirdParty/Qwt/doc/html/class_qwt_event_pattern-members.html new file mode 100644 index 0000000000..31b9b21b24 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_event_pattern-members.html @@ -0,0 +1,136 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtEventPattern Member List
+
+
+ +

This is the complete list of members for QwtEventPattern, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
initKeyPattern()QwtEventPattern
initMousePattern(int numButtons)QwtEventPattern
KeyAbort enum valueQwtEventPattern
KeyDown enum valueQwtEventPattern
KeyHome enum valueQwtEventPattern
KeyLeft enum valueQwtEventPattern
keyMatch(KeyPatternCode, const QKeyEvent *) const QwtEventPattern
keyMatch(const KeyPattern &, const QKeyEvent *) const QwtEventPatternprotectedvirtual
keyPattern() const QwtEventPattern
keyPattern()QwtEventPattern
KeyPatternCode enum nameQwtEventPattern
KeyPatternCount enum valueQwtEventPattern
KeyRedo enum valueQwtEventPattern
KeyRight enum valueQwtEventPattern
KeySelect1 enum valueQwtEventPattern
KeySelect2 enum valueQwtEventPattern
KeyUndo enum valueQwtEventPattern
KeyUp enum valueQwtEventPattern
mouseMatch(MousePatternCode, const QMouseEvent *) const QwtEventPattern
mouseMatch(const MousePattern &, const QMouseEvent *) const QwtEventPatternprotectedvirtual
mousePattern() const QwtEventPattern
mousePattern()QwtEventPattern
MousePatternCode enum nameQwtEventPattern
MousePatternCount enum valueQwtEventPattern
MouseSelect1 enum valueQwtEventPattern
MouseSelect2 enum valueQwtEventPattern
MouseSelect3 enum valueQwtEventPattern
MouseSelect4 enum valueQwtEventPattern
MouseSelect5 enum valueQwtEventPattern
MouseSelect6 enum valueQwtEventPattern
QwtEventPattern()QwtEventPattern
setKeyPattern(KeyPatternCode, int keyCode, Qt::KeyboardModifiers modifierCodes=Qt::NoModifier)QwtEventPattern
setKeyPattern(const QVector< KeyPattern > &)QwtEventPattern
setMousePattern(MousePatternCode, Qt::MouseButton button, Qt::KeyboardModifiers=Qt::NoModifier)QwtEventPattern
setMousePattern(const QVector< MousePattern > &)QwtEventPattern
~QwtEventPattern()QwtEventPatternvirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_event_pattern.html b/ThirdParty/Qwt/doc/html/class_qwt_event_pattern.html new file mode 100644 index 0000000000..de622b252e --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_event_pattern.html @@ -0,0 +1,709 @@ + + + + + + +Qwt User's Guide: QwtEventPattern Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+ +
+ +

A collection of event patterns. + More...

+ +

#include <qwt_event_pattern.h>

+
+Inheritance diagram for QwtEventPattern:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + +

+Classes

class  KeyPattern
 A pattern for key events. More...
 
class  MousePattern
 A pattern for mouse events. More...
 
+ + + + + + + +

+Public Types

enum  MousePatternCode {
+  MouseSelect1, +MouseSelect2, +MouseSelect3, +MouseSelect4, +
+  MouseSelect5, +MouseSelect6, +MousePatternCount +
+ }
 Symbolic mouse input codes. More...
 
enum  KeyPatternCode {
+  KeySelect1, +KeySelect2, +KeyAbort, +KeyLeft, +
+  KeyRight, +KeyUp, +KeyDown, +KeyRedo, +
+  KeyUndo, +KeyHome, +KeyPatternCount +
+ }
 Symbolic keyboard input codes. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 QwtEventPattern ()
 
+virtual ~QwtEventPattern ()
 Destructor.
 
void initMousePattern (int numButtons)
 
void initKeyPattern ()
 
void setMousePattern (MousePatternCode, Qt::MouseButton button, Qt::KeyboardModifiers=Qt::NoModifier)
 
void setKeyPattern (KeyPatternCode, int keyCode, Qt::KeyboardModifiers modifierCodes=Qt::NoModifier)
 
+void setMousePattern (const QVector< MousePattern > &)
 Change the mouse event patterns.
 
+void setKeyPattern (const QVector< KeyPattern > &)
 Change the key event patterns.
 
const QVector< MousePattern > & mousePattern () const
 
const QVector< KeyPattern > & keyPattern () const
 
QVector< MousePattern > & mousePattern ()
 
QVector< KeyPattern > & keyPattern ()
 
bool mouseMatch (MousePatternCode, const QMouseEvent *) const
 Compare a mouse event with an event pattern. More...
 
bool keyMatch (KeyPatternCode, const QKeyEvent *) const
 Compare a key event with an event pattern. More...
 
+ + + + + + + +

+Protected Member Functions

virtual bool mouseMatch (const MousePattern &, const QMouseEvent *) const
 Compare a mouse event with an event pattern. More...
 
virtual bool keyMatch (const KeyPattern &, const QKeyEvent *) const
 Compare a key event with an event pattern. More...
 
+

Detailed Description

+

A collection of event patterns.

+

QwtEventPattern introduces an level of indirection for mouse and keyboard inputs. Those are represented by symbolic names, so the application code can be configured by individual mappings.

+
See Also
QwtPicker, QwtPickerMachine, QwtPlotZoomer
+

Member Enumeration Documentation

+ +
+
+ +

Symbolic keyboard input codes.

+

Individual settings can be configured using setKeyPattern()

+
See Also
setKeyPattern(), setMousePattern()
+ + + + + + + + + + + + +
Enumerator
KeySelect1  +

Qt::Key_Return.

+
KeySelect2  +

Qt::Key_Space.

+
KeyAbort  +

Qt::Key_Escape.

+
KeyLeft  +

Qt::Key_Left.

+
KeyRight  +

Qt::Key_Right.

+
KeyUp  +

Qt::Key_Up.

+
KeyDown  +

Qt::Key_Down.

+
KeyRedo  +

Qt::Key_Plus.

+
KeyUndo  +

Qt::Key_Minus.

+
KeyHome  +

Qt::Key_Escape.

+
KeyPatternCount  +

Number of key patterns.

+
+ +
+
+ +
+
+ +

Symbolic mouse input codes.

+

QwtEventPattern implements 3 different settings for mice with 1, 2, or 3 buttons that can be activated using initMousePattern(). The default setting is for 3 button mice.

+

Individual settings can be configured using setMousePattern().

+
See Also
initMousePattern(), setMousePattern(), setKeyPattern()
+ + + + + + + + +
Enumerator
MouseSelect1  +

The default setting for 1, 2 and 3 button mice is:

+
    +
  • Qt::LeftButton
  • +
  • Qt::LeftButton
  • +
  • Qt::LeftButton
  • +
+
MouseSelect2  +

The default setting for 1, 2 and 3 button mice is:

+
    +
  • Qt::LeftButton + Qt::ControlModifier
  • +
  • Qt::RightButton
  • +
  • Qt::RightButton
  • +
+
MouseSelect3  +

The default setting for 1, 2 and 3 button mice is:

+
    +
  • Qt::LeftButton + Qt::AltModifier
  • +
  • Qt::LeftButton + Qt::AltModifier
  • +
  • Qt::MidButton
  • +
+
MouseSelect4  +

The default setting for 1, 2 and 3 button mice is:

+
    +
  • Qt::LeftButton + Qt::ShiftModifier
  • +
  • Qt::LeftButton + Qt::ShiftModifier
  • +
  • Qt::LeftButton + Qt::ShiftModifier
  • +
+
MouseSelect5  +

The default setting for 1, 2 and 3 button mice is:

+
    +
  • Qt::LeftButton + Qt::ControlButton | Qt::ShiftModifier
  • +
  • Qt::RightButton + Qt::ShiftModifier
  • +
  • Qt::RightButton + Qt::ShiftModifier
  • +
+
MouseSelect6  +

The default setting for 1, 2 and 3 button mice is:

+
    +
  • Qt::LeftButton + Qt::AltModifier + Qt::ShiftModifier
  • +
  • Qt::LeftButton + Qt::AltModifier | Qt::ShiftModifier
  • +
  • Qt::MidButton + Qt::ShiftModifier
  • +
+
MousePatternCount  +

Number of mouse patterns.

+
+ +
+
+

Constructor & Destructor Documentation

+ +
+
+ + + + + + + +
QwtEventPattern::QwtEventPattern ()
+
+

Constructor

+
See Also
MousePatternCode, KeyPatternCode
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + + + +
void QwtEventPattern::initKeyPattern ()
+
+

Set default mouse patterns.

+
See Also
KeyPatternCode
+ +
+
+ +
+
+ + + + + + + + +
void QwtEventPattern::initMousePattern (int numButtons)
+
+

Set default mouse patterns, depending on the number of mouse buttons

+
Parameters
+ + +
numButtonsNumber of mouse buttons ( <= 3 )
+
+
+
See Also
MousePatternCode
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
bool QwtEventPattern::keyMatch (KeyPatternCode code,
const QKeyEvent * event 
) const
+
+ +

Compare a key event with an event pattern.

+

A key event matches the pattern when both have the same key value and in the state value the same key flags (Qt::KeyButtonMask) are set.

+
Parameters
+ + + +
codeIndex of the event pattern
eventKey event
+
+
+
Returns
true if matches
+
See Also
mouseMatch()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool QwtEventPattern::keyMatch (const KeyPatternpattern,
const QKeyEvent * event 
) const
+
+protectedvirtual
+
+ +

Compare a key event with an event pattern.

+

A key event matches the pattern when both have the same key value and in the state value the same key flags (Qt::KeyButtonMask) are set.

+
Parameters
+ + + +
patternKey event pattern
eventKey event
+
+
+
Returns
true if matches
+
See Also
mouseMatch()
+ +
+
+ +
+
+ + + + + + + +
const QVector< QwtEventPattern::KeyPattern > & QwtEventPattern::keyPattern () const
+
+
Returns
Key pattern
+ +
+
+ +
+
+ + + + + + + +
QVector< QwtEventPattern::KeyPattern > & QwtEventPattern::keyPattern ()
+
+
Returns
Key pattern
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
bool QwtEventPattern::mouseMatch (MousePatternCode code,
const QMouseEvent * event 
) const
+
+ +

Compare a mouse event with an event pattern.

+

A mouse event matches the pattern when both have the same button value and in the state value the same key flags(Qt::KeyButtonMask) are set.

+
Parameters
+ + + +
codeIndex of the event pattern
eventMouse event
+
+
+
Returns
true if matches
+
See Also
keyMatch()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool QwtEventPattern::mouseMatch (const MousePatternpattern,
const QMouseEvent * event 
) const
+
+protectedvirtual
+
+ +

Compare a mouse event with an event pattern.

+

A mouse event matches the pattern when both have the same button value and in the state value the same key flags(Qt::KeyButtonMask) are set.

+
Parameters
+ + + +
patternMouse event pattern
eventMouse event
+
+
+
Returns
true if matches
+
See Also
keyMatch()
+ +
+
+ +
+
+ + + + + + + +
const QVector< QwtEventPattern::MousePattern > & QwtEventPattern::mousePattern () const
+
+
Returns
Mouse pattern
+ +
+
+ +
+
+ + + + + + + +
QVector< QwtEventPattern::MousePattern > & QwtEventPattern::mousePattern ()
+
+
Returns
Mouse pattern
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void QwtEventPattern::setKeyPattern (KeyPatternCode pattern,
int key,
Qt::KeyboardModifiers modifiers = Qt::NoModifier 
)
+
+

Change one key pattern

+
Parameters
+ + + + +
patternIndex of the pattern
keyKey
modifiersKeyboard modifiers
+
+
+
See Also
QKeyEvent
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void QwtEventPattern::setMousePattern (MousePatternCode pattern,
Qt::MouseButton button,
Qt::KeyboardModifiers modifiers = Qt::NoModifier 
)
+
+

Change one mouse pattern

+
Parameters
+ + + + +
patternIndex of the pattern
buttonButton
modifiersKeyboard modifiers
+
+
+
See Also
QMouseEvent
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_event_pattern_1_1_key_pattern-members.html b/ThirdParty/Qwt/doc/html/class_qwt_event_pattern_1_1_key_pattern-members.html new file mode 100644 index 0000000000..b2bfe1166b --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_event_pattern_1_1_key_pattern-members.html @@ -0,0 +1,107 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
QwtEventPattern::KeyPattern Member List
+
+
+ +

This is the complete list of members for QwtEventPattern::KeyPattern, including all inherited members.

+ + + + +
keyQwtEventPattern::KeyPattern
KeyPattern(int keyCode=Qt::Key_unknown, Qt::KeyboardModifiers modifierCodes=Qt::NoModifier)QwtEventPattern::KeyPatterninline
modifiersQwtEventPattern::KeyPattern
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_event_pattern_1_1_key_pattern.html b/ThirdParty/Qwt/doc/html/class_qwt_event_pattern_1_1_key_pattern.html new file mode 100644 index 0000000000..f1c7b3986a --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_event_pattern_1_1_key_pattern.html @@ -0,0 +1,131 @@ + + + + + + +Qwt User's Guide: QwtEventPattern::KeyPattern Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+ +
+
QwtEventPattern::KeyPattern Class Reference
+
+
+ +

A pattern for key events. + More...

+ +

#include <qwt_event_pattern.h>

+ + + + + +

+Public Member Functions

KeyPattern (int keyCode=Qt::Key_unknown, Qt::KeyboardModifiers modifierCodes=Qt::NoModifier)
 Constructor.
 
+ + + + + + + +

+Public Attributes

+int key
 Key code.
 
+Qt::KeyboardModifiers modifiers
 Modifiers.
 
+

Detailed Description

+

A pattern for key events.

+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_event_pattern_1_1_mouse_pattern-members.html b/ThirdParty/Qwt/doc/html/class_qwt_event_pattern_1_1_mouse_pattern-members.html new file mode 100644 index 0000000000..e163c18d2c --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_event_pattern_1_1_mouse_pattern-members.html @@ -0,0 +1,107 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+
+
QwtEventPattern::MousePattern Member List
+
+
+ +

This is the complete list of members for QwtEventPattern::MousePattern, including all inherited members.

+ + + + +
buttonQwtEventPattern::MousePattern
modifiersQwtEventPattern::MousePattern
MousePattern(Qt::MouseButton btn=Qt::NoButton, Qt::KeyboardModifiers modifierCodes=Qt::NoModifier)QwtEventPattern::MousePatterninline
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_event_pattern_1_1_mouse_pattern.html b/ThirdParty/Qwt/doc/html/class_qwt_event_pattern_1_1_mouse_pattern.html new file mode 100644 index 0000000000..dec8a80d6f --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_event_pattern_1_1_mouse_pattern.html @@ -0,0 +1,131 @@ + + + + + + +Qwt User's Guide: QwtEventPattern::MousePattern Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ + +
+
+ +
+
QwtEventPattern::MousePattern Class Reference
+
+
+ +

A pattern for mouse events. + More...

+ +

#include <qwt_event_pattern.h>

+ + + + + +

+Public Member Functions

MousePattern (Qt::MouseButton btn=Qt::NoButton, Qt::KeyboardModifiers modifierCodes=Qt::NoModifier)
 Constructor.
 
+ + + + + + + +

+Public Attributes

+Qt::MouseButton button
 Button.
 
+Qt::KeyboardModifiers modifiers
 Keyboard modifier.
 
+

Detailed Description

+

A pattern for mouse events.

+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_event_pattern__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_event_pattern__inherit__graph.map new file mode 100644 index 0000000000..510b824646 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_event_pattern__inherit__graph.map @@ -0,0 +1,5 @@ + + + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_event_pattern__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_event_pattern__inherit__graph.md5 new file mode 100644 index 0000000000..f9e0595358 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_event_pattern__inherit__graph.md5 @@ -0,0 +1 @@ +887680bd0bcc455d0c1691ca53ee1aa2 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_event_pattern__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_event_pattern__inherit__graph.png new file mode 100644 index 0000000000..1d93b2b98f Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_event_pattern__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_graphic-members.html b/ThirdParty/Qwt/doc/html/class_qwt_graphic-members.html new file mode 100644 index 0000000000..b67e697e2f --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_graphic-members.html @@ -0,0 +1,154 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtGraphic Member List
+
+
+ +

This is the complete list of members for QwtGraphic, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
boundingRect() const QwtGraphic
commands() const QwtGraphic
controlPointRect() const QwtGraphic
defaultSize() const QwtGraphic
drawEllipse(const QRectF &)QwtNullPaintDevicevirtual
drawEllipse(const QRect &)QwtNullPaintDevicevirtual
drawImage(const QRectF &, const QImage &, const QRectF &, Qt::ImageConversionFlags)QwtGraphicprotectedvirtual
drawLines(const QLine *, int)QwtNullPaintDevicevirtual
drawLines(const QLineF *, int)QwtNullPaintDevicevirtual
drawPath(const QPainterPath &)QwtGraphicprotectedvirtual
drawPixmap(const QRectF &, const QPixmap &, const QRectF &)QwtGraphicprotectedvirtual
drawPoints(const QPointF *, int)QwtNullPaintDevicevirtual
drawPoints(const QPoint *, int)QwtNullPaintDevicevirtual
drawPolygon(const QPointF *, int, QPaintEngine::PolygonDrawMode)QwtNullPaintDevicevirtual
drawPolygon(const QPoint *, int, QPaintEngine::PolygonDrawMode)QwtNullPaintDevicevirtual
drawRects(const QRect *, int)QwtNullPaintDevicevirtual
drawRects(const QRectF *, int)QwtNullPaintDevicevirtual
drawTextItem(const QPointF &, const QTextItem &)QwtNullPaintDevicevirtual
drawTiledPixmap(const QRectF &, const QPixmap &, const QPointF &s)QwtNullPaintDevicevirtual
isEmpty() const QwtGraphic
isNull() const QwtGraphic
metric(PaintDeviceMetric metric) const QwtNullPaintDevicevirtual
mode() const QwtNullPaintDevice
Mode enum nameQwtNullPaintDevice
NormalMode enum valueQwtNullPaintDevice
operator=(const QwtGraphic &)QwtGraphic
paintEngine() const QwtNullPaintDevicevirtual
PathMode enum valueQwtNullPaintDevice
PolygonPathMode enum valueQwtNullPaintDevice
QwtGraphic()QwtGraphic
QwtGraphic(const QwtGraphic &)QwtGraphic
QwtNullPaintDevice()QwtNullPaintDevice
render(QPainter *) const QwtGraphic
render(QPainter *, const QSizeF &, Qt::AspectRatioMode=Qt::IgnoreAspectRatio) const QwtGraphic
render(QPainter *, const QRectF &, Qt::AspectRatioMode=Qt::IgnoreAspectRatio) const QwtGraphic
render(QPainter *, const QPointF &, Qt::Alignment=Qt::AlignTop|Qt::AlignLeft) const QwtGraphic
RenderHint enum nameQwtGraphic
RenderHints typedefQwtGraphic
RenderPensUnscaled enum valueQwtGraphic
reset()QwtGraphic
scaledBoundingRect(double sx, double sy) const QwtGraphic
setCommands(QVector< QwtPainterCommand > &)QwtGraphic
setDefaultSize(const QSizeF &)QwtGraphic
setMode(Mode)QwtNullPaintDevice
setRenderHint(RenderHint, bool on=true)QwtGraphic
sizeMetrics() const QwtGraphicprotectedvirtual
testRenderHint(RenderHint) const QwtGraphic
toImage() const QwtGraphic
toImage(const QSize &, Qt::AspectRatioMode=Qt::IgnoreAspectRatio) const QwtGraphic
toPixmap() const QwtGraphic
toPixmap(const QSize &, Qt::AspectRatioMode=Qt::IgnoreAspectRatio) const QwtGraphic
updateState(const QPaintEngineState &state)QwtGraphicprotectedvirtual
~QwtGraphic()QwtGraphicvirtual
~QwtNullPaintDevice()QwtNullPaintDevicevirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_graphic.html b/ThirdParty/Qwt/doc/html/class_qwt_graphic.html new file mode 100644 index 0000000000..24165d4d5a --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_graphic.html @@ -0,0 +1,1173 @@ + + + + + + +Qwt User's Guide: QwtGraphic Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+ +
+ +

A paint device for scalable graphics. + More...

+ +

#include <qwt_graphic.h>

+
+Inheritance diagram for QwtGraphic:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + + + + +

+Public Types

enum  RenderHint { RenderPensUnscaled = 0x1 + }
 
typedef QFlags< RenderHintRenderHints
 Render hints. More...
 
- Public Types inherited from QwtNullPaintDevice
enum  Mode { NormalMode, +PolygonPathMode, +PathMode + }
 Render mode. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 QwtGraphic ()
 Constructor. More...
 
 QwtGraphic (const QwtGraphic &)
 Copy constructor. More...
 
+virtual ~QwtGraphic ()
 Destructor.
 
QwtGraphicoperator= (const QwtGraphic &)
 Assignment operator. More...
 
void reset ()
 Clear all stored commands. More...
 
bool isNull () const
 
bool isEmpty () const
 
void render (QPainter *) const
 Replay all recorded painter commands. More...
 
void render (QPainter *, const QSizeF &, Qt::AspectRatioMode=Qt::IgnoreAspectRatio) const
 Replay all recorded painter commands. More...
 
void render (QPainter *, const QRectF &, Qt::AspectRatioMode=Qt::IgnoreAspectRatio) const
 Replay all recorded painter commands. More...
 
void render (QPainter *, const QPointF &, Qt::Alignment=Qt::AlignTop|Qt::AlignLeft) const
 Replay all recorded painter commands. More...
 
QPixmap toPixmap () const
 Convert the graphic to a QPixmap. More...
 
QPixmap toPixmap (const QSize &, Qt::AspectRatioMode=Qt::IgnoreAspectRatio) const
 Convert the graphic to a QPixmap. More...
 
QImage toImage () const
 Convert the graphic to a QImage. More...
 
QImage toImage (const QSize &, Qt::AspectRatioMode=Qt::IgnoreAspectRatio) const
 Convert the graphic to a QImage. More...
 
QRectF scaledBoundingRect (double sx, double sy) const
 Calculate the target rectangle for scaling the graphic. More...
 
QRectF boundingRect () const
 
QRectF controlPointRect () const
 
const QVector
+< QwtPainterCommand > & 
commands () const
 
void setCommands (QVector< QwtPainterCommand > &)
 Append paint commands. More...
 
void setDefaultSize (const QSizeF &)
 Set a default size. More...
 
QSizeF defaultSize () const
 Default size. More...
 
void setRenderHint (RenderHint, bool on=true)
 
bool testRenderHint (RenderHint) const
 
- Public Member Functions inherited from QwtNullPaintDevice
QwtNullPaintDevice ()
 Constructor.
 
+virtual ~QwtNullPaintDevice ()
 Destructor.
 
void setMode (Mode)
 
Mode mode () const
 
+virtual QPaintEngine * paintEngine () const
 See QPaintDevice::paintEngine()
 
virtual int metric (PaintDeviceMetric metric) const
 
+virtual void drawRects (const QRect *, int)
 See QPaintEngine::drawRects()
 
+virtual void drawRects (const QRectF *, int)
 See QPaintEngine::drawRects()
 
+virtual void drawLines (const QLine *, int)
 See QPaintEngine::drawLines()
 
+virtual void drawLines (const QLineF *, int)
 See QPaintEngine::drawLines()
 
+virtual void drawEllipse (const QRectF &)
 See QPaintEngine::drawEllipse()
 
+virtual void drawEllipse (const QRect &)
 See QPaintEngine::drawEllipse()
 
+virtual void drawPoints (const QPointF *, int)
 See QPaintEngine::drawPoints()
 
+virtual void drawPoints (const QPoint *, int)
 See QPaintEngine::drawPoints()
 
+virtual void drawPolygon (const QPointF *, int, QPaintEngine::PolygonDrawMode)
 See QPaintEngine::drawPolygon()
 
+virtual void drawPolygon (const QPoint *, int, QPaintEngine::PolygonDrawMode)
 See QPaintEngine::drawPolygon()
 
+virtual void drawTextItem (const QPointF &, const QTextItem &)
 See QPaintEngine::drawTextItem()
 
+virtual void drawTiledPixmap (const QRectF &, const QPixmap &, const QPointF &s)
 See QPaintEngine::drawTiledPixmap()
 
+ + + + + + + + + + + + + + +

+Protected Member Functions

virtual QSize sizeMetrics () const
 
virtual void drawPath (const QPainterPath &)
 
virtual void drawPixmap (const QRectF &, const QPixmap &, const QRectF &)
 Store a pixmap command in the command list. More...
 
virtual void drawImage (const QRectF &, const QImage &, const QRectF &, Qt::ImageConversionFlags)
 Store a image command in the command list. More...
 
virtual void updateState (const QPaintEngineState &state)
 Store a state command in the command list. More...
 
+

Detailed Description

+

A paint device for scalable graphics.

+

QwtGraphic is the representation of a graphic that is tailored for scalability. Like QPicture it will be initialized by QPainter operations and replayed later to any target paint device.

+

While the usual image representations QImage and QPixmap are not scalable Qt offers two paint devices, that might be candidates for representing a vector graphic:

+
    +
  • QPicture
    + Unfortunately QPicture had been forgotten, when Qt4 introduced floating point based render engines. Its API is still on integers, what make it unusable for proper scaling.
  • +
+
    +
  • QSvgRenderer/QSvgGenerator
    + Unfortunately QSvgRenderer hides to much information about its nodes in internal APIs, that are necessary proper layout calculations. Also it is derived from QObject and can't be copied like QImage/QPixmap. Also QSvgRenderer/QSvgGenerator are no complete SVG implementations with a questionable future in Qt 5.
  • +
+

QwtGraphic maps all scalable drawing primitives to a QPainterPath and stores them together with the painter state changes ( pen, brush, transformation ... ) in a list of QwtPaintCommands. For being a complete QPaintDevice it also stores pixmaps or images, what is somehow against the idea of the class, because these objects can be scaled without a loss in quality.

+

The main issue about scaling a QwtGraphic object are the pens used for drawing the outlines of the painter paths. While non cosmetic pens ( QPen::isCosmetic() ) are scaled with the same ratio as the path, cosmetic pens have a fixed width. A graphic might have paths with different pens - cosmetic and non-cosmetic.

+

QwtGraphic caches 2 different rectangles:

+
    +
  • control point rectangle
    + The control point rectangle is the bounding rectangle of all control point rectangles of the painter paths, or the target rectangle of the pixmaps/images.
  • +
+
    +
  • bounding rectangle
    + The bounding rectangle extends the control point rectangle by what is needed for rendering the outline with an unscaled pen.
  • +
+

Because the offset for drawing the outline depends on the shape of the painter path ( the peak of a triangle is different than the flat side ) scaling with a fixed aspect ratio always needs to be calculated from the control point rectangle.

+
See Also
QwtPainterCommand
+

Member Typedef Documentation

+ +
+
+ + + + +
typedef QFlags<RenderHint> QwtGraphic::RenderHints
+
+ +

Render hints.

+

The default setting is to disable all hints

+ +
+
+

Member Enumeration Documentation

+ +
+
+ + + + +
enum QwtGraphic::RenderHint
+
+

Hint how to render a graphic

+
See Also
setRenderHint(), testRenderHint()
+ + +
Enumerator
RenderPensUnscaled  +

When RenderPensUnscaled is set non cosmetic pens are painted unscaled - like cosmetic pens. The difference to using cosmetic pens is, when the graphic is rendered to a document in a scalable vector format ( PDF, SVG ): the width of non cosmetic pens will be scaled by the document viewer.

+
+ +
+
+

Constructor & Destructor Documentation

+ +
+
+ + + + + + + +
QwtGraphic::QwtGraphic ()
+
+ +

Constructor.

+

Initializes a null graphic

+
See Also
isNull()
+ +
+
+ +
+
+ + + + + + + + +
QwtGraphic::QwtGraphic (const QwtGraphicother)
+
+ +

Copy constructor.

+
Parameters
+ + +
otherSource
+
+
+
See Also
operator=()
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + + + +
QRectF QwtGraphic::boundingRect () const
+
+

The bounding rectangle is the controlPointRect() extended by the areas needed for rendering the outlines with unscaled pens.

+
Returns
Bounding rectangle of the graphic
+
See Also
controlPointRect(), scaledBoundingRect()
+ +
+
+ +
+
+ + + + + + + +
const QVector< QwtPainterCommand > & QwtGraphic::commands () const
+
+
Returns
List of recorded paint commands
+
See Also
setCommands()
+ +
+
+ +
+
+ + + + + + + +
QRectF QwtGraphic::controlPointRect () const
+
+

The control point rectangle is the bounding rectangle of all control points of the paths and the target rectangles of the images/pixmaps.

+
Returns
Control point rectangle
+
See Also
boundingRect(), scaledBoundingRect()
+ +
+
+ +
+
+ + + + + + + +
QSizeF QwtGraphic::defaultSize () const
+
+ +

Default size.

+

When a non empty size has been assigned by setDefaultSize() this size will be returned. Otherwise the default size is the size of the bounding rectangle.

+

The default size is used in all methods rendering the graphic, where no size is explicitly specified.

+
Returns
Default size
+
See Also
setDefaultSize(), boundingRect()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void QwtGraphic::drawImage (const QRectF & rect,
const QImage & image,
const QRectF & subRect,
Qt::ImageConversionFlags flags 
)
+
+protectedvirtual
+
+ +

Store a image command in the command list.

+
Parameters
+ + + + + +
recttraget rectangle
imageImage to be painted
subRectReactangle of the pixmap to be painted
flagsImage conversion flags
+
+
+
See Also
QPaintEngine::drawImage()
+ +

Reimplemented from QwtNullPaintDevice.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtGraphic::drawPath (const QPainterPath & path)
+
+protectedvirtual
+
+

Store a path command in the command list

+
Parameters
+ + +
pathPainter path
+
+
+
See Also
QPaintEngine::drawPath()
+ +

Reimplemented from QwtNullPaintDevice.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
void QwtGraphic::drawPixmap (const QRectF & rect,
const QPixmap & pixmap,
const QRectF & subRect 
)
+
+protectedvirtual
+
+ +

Store a pixmap command in the command list.

+
Parameters
+ + + + +
recttarget rectangle
pixmapPixmap to be painted
subRectReactangle of the pixmap to be painted
+
+
+
See Also
QPaintEngine::drawPixmap()
+ +

Reimplemented from QwtNullPaintDevice.

+ +
+
+ +
+
+ + + + + + + +
bool QwtGraphic::isEmpty () const
+
+
Returns
True, when the bounding rectangle is empty
+
See Also
boundingRect(), isNull()
+ +
+
+ +
+
+ + + + + + + +
bool QwtGraphic::isNull () const
+
+
Returns
True, when no painter commands have been stored
+
See Also
isEmpty(), commands()
+ +
+
+ +
+
+ + + + + + + + +
QwtGraphic & QwtGraphic::operator= (const QwtGraphicother)
+
+ +

Assignment operator.

+
Parameters
+ + +
otherSource
+
+
+
Returns
A reference of this object
+ +
+
+ +
+
+ + + + + + + + +
void QwtGraphic::render (QPainter * painter) const
+
+ +

Replay all recorded painter commands.

+
Parameters
+ + +
painterQt painter
+
+
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void QwtGraphic::render (QPainter * painter,
const QSizeF & size,
Qt::AspectRatioMode aspectRatioMode = Qt::IgnoreAspectRatio 
) const
+
+ +

Replay all recorded painter commands.

+

The graphic is scaled to fit into the rectangle of the given size starting at ( 0, 0 ).

+
Parameters
+ + + + +
painterQt painter
sizeSize for the scaled graphic
aspectRatioModeMode how to scale - See Qt::AspectRatioMode
+
+
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void QwtGraphic::render (QPainter * painter,
const QRectF & rect,
Qt::AspectRatioMode aspectRatioMode = Qt::IgnoreAspectRatio 
) const
+
+ +

Replay all recorded painter commands.

+

The graphic is scaled to fit into the given rectangle

+
Parameters
+ + + + +
painterQt painter
rectRectangle for the scaled graphic
aspectRatioModeMode how to scale - See Qt::AspectRatioMode
+
+
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void QwtGraphic::render (QPainter * painter,
const QPointF & pos,
Qt::Alignment alignment = Qt::AlignTop | Qt::AlignLeft 
) const
+
+ +

Replay all recorded painter commands.

+

The graphic is scaled to the defaultSize() and aligned to a position.

+
Parameters
+ + + + +
painterQt painter
posReference point, where to render
alignmentFlags how to align the target rectangle to pos.
+
+
+ +
+
+ +
+
+ + + + + + + +
void QwtGraphic::reset ()
+
+ +

Clear all stored commands.

+
See Also
isNull()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
QRectF QwtGraphic::scaledBoundingRect (double sx,
double sy 
) const
+
+ +

Calculate the target rectangle for scaling the graphic.

+
Parameters
+ + + +
sxHorizontal scaling factor
syVertical scaling factor
+
+
+
Note
In case of paths that are painted with a cosmetic pen ( see QPen::isCosmetic() ) the target rectangle is different to multiplying the bounding rectangle.
+
Returns
Scaled bounding rectangle
+
See Also
boundingRect(), controlPointRect()
+ +
+
+ +
+
+ + + + + + + + +
void QwtGraphic::setCommands (QVector< QwtPainterCommand > & commands)
+
+ +

Append paint commands.

+
Parameters
+ + +
commandsPaint commands
+
+
+
See Also
commands()
+ +
+
+ +
+
+ + + + + + + + +
void QwtGraphic::setDefaultSize (const QSizeF & size)
+
+ +

Set a default size.

+

The default size is used in all methods rendering the graphic, where no size is explicitly specified. Assigning an empty size means, that the default size will be calculated from the bounding rectangle.

+

The default setting is an empty size.

+
Parameters
+ + +
sizeDefault size
+
+
+
See Also
defaultSize(), boundingRect()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtGraphic::setRenderHint (RenderHint hint,
bool on = true 
)
+
+

Toggle an render hint

+
Parameters
+ + + +
hintRender hint
ontrue/false
+
+
+
See Also
testRenderHint(), RenderHint
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
QSize QwtGraphic::sizeMetrics () const
+
+protectedvirtual
+
+
Returns
Ceiled defaultSize()
+ +

Implements QwtNullPaintDevice.

+ +
+
+ +
+
+ + + + + + + + +
bool QwtGraphic::testRenderHint (RenderHint hint) const
+
+

Test a render hint

+
Parameters
+ + +
hintRender hint
+
+
+
Returns
true/false
+
See Also
setRenderHint(), RenderHint
+ +
+
+ +
+
+ + + + + + + +
QImage QwtGraphic::toImage () const
+
+ +

Convert the graphic to a QImage.

+

All pixels of the image get initialized by 0 ( transparent ) before the graphic is scaled and rendered on it.

+

The format of the image is QImage::Format_ARGB32_Premultiplied.

+

The size of the image is the default size ( ceiled to integers ) of the graphic.

+
Returns
The graphic as image in default size
+
See Also
defaultSize(), toPixmap(), render()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
QImage QwtGraphic::toImage (const QSize & size,
Qt::AspectRatioMode aspectRatioMode = Qt::IgnoreAspectRatio 
) const
+
+ +

Convert the graphic to a QImage.

+

All pixels of the image get initialized by 0 ( transparent ) before the graphic is scaled and rendered on it.

+

The format of the image is QImage::Format_ARGB32_Premultiplied.

+
Parameters
+ + + +
sizeSize of the image
aspectRatioModeAspect ratio how to scale the graphic
+
+
+
Returns
The graphic as image
+
See Also
toPixmap(), render()
+ +
+
+ +
+
+ + + + + + + +
QPixmap QwtGraphic::toPixmap () const
+
+ +

Convert the graphic to a QPixmap.

+

All pixels of the pixmap get initialized by Qt::transparent before the graphic is scaled and rendered on it.

+

The size of the pixmap is the default size ( ceiled to integers ) of the graphic.

+
Returns
The graphic as pixmap in default size
+
See Also
defaultSize(), toImage(), render()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
QPixmap QwtGraphic::toPixmap (const QSize & size,
Qt::AspectRatioMode aspectRatioMode = Qt::IgnoreAspectRatio 
) const
+
+ +

Convert the graphic to a QPixmap.

+

All pixels of the pixmap get initialized by Qt::transparent before the graphic is scaled and rendered on it.

+
Parameters
+ + + +
sizeSize of the image
aspectRatioModeAspect ratio how to scale the graphic
+
+
+
Returns
The graphic as pixmap
+
See Also
toImage(), render()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtGraphic::updateState (const QPaintEngineState & state)
+
+protectedvirtual
+
+ +

Store a state command in the command list.

+
Parameters
+ + +
stateState to be stored
+
+
+
See Also
QPaintEngine::updateState()
+ +

Reimplemented from QwtNullPaintDevice.

+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_graphic__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_graphic__inherit__graph.map new file mode 100644 index 0000000000..32107524c1 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_graphic__inherit__graph.map @@ -0,0 +1,3 @@ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_graphic__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_graphic__inherit__graph.md5 new file mode 100644 index 0000000000..de66eedf70 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_graphic__inherit__graph.md5 @@ -0,0 +1 @@ +f4426c3f3bc137bfeaafe32310cbf683 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_graphic__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_graphic__inherit__graph.png new file mode 100644 index 0000000000..2df812a5dc Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_graphic__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_interval-members.html b/ThirdParty/Qwt/doc/html/class_qwt_interval-members.html new file mode 100644 index 0000000000..bd4cfd7619 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_interval-members.html @@ -0,0 +1,136 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtInterval Member List
+
+
+ +

This is the complete list of members for QwtInterval, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
BorderFlag enum nameQwtInterval
BorderFlags typedefQwtInterval
borderFlags() const QwtIntervalinline
contains(double value) const QwtInterval
ExcludeBorders enum valueQwtInterval
ExcludeMaximum enum valueQwtInterval
ExcludeMinimum enum valueQwtInterval
extend(double value) const QwtInterval
IncludeBorders enum valueQwtInterval
intersect(const QwtInterval &) const QwtInterval
intersects(const QwtInterval &) const QwtInterval
invalidate()QwtIntervalinline
inverted() const QwtInterval
isNull() const QwtIntervalinline
isValid() const QwtIntervalinline
limited(double minValue, double maxValue) const QwtInterval
maxValue() const QwtIntervalinline
minValue() const QwtIntervalinline
normalized() const QwtInterval
operator!=(const QwtInterval &) const QwtIntervalinline
operator&(const QwtInterval &) const QwtIntervalinline
operator&=(const QwtInterval &)QwtInterval
operator==(const QwtInterval &) const QwtIntervalinline
operator|(const QwtInterval &) const QwtIntervalinline
operator|(double) const QwtIntervalinline
operator|=(const QwtInterval &)QwtInterval
operator|=(double)QwtInterval
QwtInterval()QwtIntervalinline
QwtInterval(double minValue, double maxValue, BorderFlags=IncludeBorders)QwtIntervalinline
setBorderFlags(BorderFlags)QwtIntervalinline
setInterval(double minValue, double maxValue, BorderFlags=IncludeBorders)QwtIntervalinline
setMaxValue(double)QwtIntervalinline
setMinValue(double)QwtIntervalinline
symmetrize(double value) const QwtInterval
unite(const QwtInterval &) const QwtInterval
width() const QwtIntervalinline
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_interval.html b/ThirdParty/Qwt/doc/html/class_qwt_interval.html new file mode 100644 index 0000000000..72324acbb7 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_interval.html @@ -0,0 +1,1066 @@ + + + + + + +Qwt User's Guide: QwtInterval Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtInterval Class Reference
+
+
+ +

A class representing an interval. + More...

+ +

#include <qwt_interval.h>

+ + + + + + + +

+Public Types

enum  BorderFlag { IncludeBorders = 0x00, +ExcludeMinimum = 0x01, +ExcludeMaximum = 0x02, +ExcludeBorders = ExcludeMinimum | ExcludeMaximum + }
 
+typedef QFlags< BorderFlagBorderFlags
 Border flags.
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 QwtInterval ()
 Default Constructor. More...
 
 QwtInterval (double minValue, double maxValue, BorderFlags=IncludeBorders)
 
void setInterval (double minValue, double maxValue, BorderFlags=IncludeBorders)
 
QwtInterval normalized () const
 Normalize the limits of the interval. More...
 
QwtInterval inverted () const
 
QwtInterval limited (double minValue, double maxValue) const
 
bool operator== (const QwtInterval &) const
 Compare two intervals. More...
 
bool operator!= (const QwtInterval &) const
 Compare two intervals. More...
 
void setBorderFlags (BorderFlags)
 
BorderFlags borderFlags () const
 
double minValue () const
 
double maxValue () const
 
double width () const
 Return the width of an interval. More...
 
void setMinValue (double)
 
void setMaxValue (double)
 
bool contains (double value) const
 
bool intersects (const QwtInterval &) const
 Test if two intervals overlap. More...
 
QwtInterval intersect (const QwtInterval &) const
 Intersect 2 intervals. More...
 
+QwtInterval unite (const QwtInterval &) const
 Unite 2 intervals.
 
QwtInterval operator| (const QwtInterval &) const
 
QwtInterval operator& (const QwtInterval &) const
 Intersection of two intervals. More...
 
QwtIntervaloperator|= (const QwtInterval &)
 Unite this interval with the given interval. More...
 
QwtIntervaloperator&= (const QwtInterval &)
 Intersect this interval with the given interval. More...
 
QwtInterval extend (double value) const
 Extend the interval. More...
 
QwtInterval operator| (double) const
 
QwtIntervaloperator|= (double)
 
bool isValid () const
 
bool isNull () const
 
void invalidate ()
 
QwtInterval symmetrize (double value) const
 
+

Detailed Description

+

A class representing an interval.

+

The interval is represented by 2 doubles, the lower and the upper limit.

+

Member Enumeration Documentation

+ +
+
+ + + + +
enum QwtInterval::BorderFlag
+
+

Flag indicating if a border is included or excluded

+
See Also
setBorderFlags(), borderFlags()
+ + + + + +
Enumerator
IncludeBorders  +

Min/Max values are inside the interval.

+
ExcludeMinimum  +

Min value is not included in the interval.

+
ExcludeMaximum  +

Max value is not included in the interval.

+
ExcludeBorders  +

Min/Max values are not included in the interval.

+
+ +
+
+

Constructor & Destructor Documentation

+ +
+
+ + + + + +
+ + + + + + + +
QwtInterval::QwtInterval ()
+
+inline
+
+ +

Default Constructor.

+

Creates an invalid interval [0.0, -1.0]

+
See Also
setInterval(), isValid()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
QwtInterval::QwtInterval (double minValue,
double maxValue,
BorderFlags borderFlags = IncludeBorders 
)
+
+inline
+
+

Constructor

+

Build an interval with from min/max values

+
Parameters
+ + + + +
minValueMinimum value
maxValueMaximum value
borderFlagsInclude/Exclude borders
+
+
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + +
QwtInterval::BorderFlags QwtInterval::borderFlags () const
+
+inline
+
+
Returns
Border flags
+
See Also
setBorderFlags()
+ +
+
+ +
+
+ + + + + + + + +
bool QwtInterval::contains (double value) const
+
+

Test if a value is inside an interval

+
Parameters
+ + +
valueValue
+
+
+
Returns
true, if value >= minValue() && value <= maxValue()
+ +
+
+ +
+
+ + + + + + + + +
QwtInterval QwtInterval::extend (double value) const
+
+ +

Extend the interval.

+

If value is below minValue(), value becomes the lower limit. If value is above maxValue(), value becomes the upper limit.

+

extend() has no effect for invalid intervals

+
Parameters
+ + +
valueValue
+
+
+
Returns
extended interval
+
See Also
isValid()
+ +
+
+ +
+
+ + + + + + + + +
QwtInterval QwtInterval::intersect (const QwtIntervalother) const
+
+ +

Intersect 2 intervals.

+
Parameters
+ + +
otherInterval to be intersect with
+
+
+
Returns
Intersection
+ +
+
+ +
+
+ + + + + + + + +
bool QwtInterval::intersects (const QwtIntervalother) const
+
+ +

Test if two intervals overlap.

+
Parameters
+ + +
otherInterval
+
+
+
Returns
True, when the intervals are intersecting
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void QwtInterval::invalidate ()
+
+inline
+
+

Invalidate the interval

+

The limits are set to interval [0.0, -1.0]

+
See Also
isValid()
+ +
+
+ +
+
+ + + + + + + +
QwtInterval QwtInterval::inverted () const
+
+

Invert the limits of the interval

+
Returns
Inverted interval
+
See Also
normalized()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool QwtInterval::isNull () const
+
+inline
+
+
Returns
true, if isValid() && (minValue() >= maxValue())
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool QwtInterval::isValid () const
+
+inline
+
+

A interval is valid when minValue() <= maxValue(). In case of QwtInterval::ExcludeBorders it is true when minValue() < maxValue()

+
Returns
True, when the interval is valid
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
QwtInterval QwtInterval::limited (double lowerBound,
double upperBound 
) const
+
+

Limit the interval, keeping the border modes

+
Parameters
+ + + +
lowerBoundLower limit
upperBoundUpper limit
+
+
+
Returns
Limited interval
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
double QwtInterval::maxValue () const
+
+inline
+
+
Returns
Upper limit of the interval
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
double QwtInterval::minValue () const
+
+inline
+
+
Returns
Lower limit of the interval
+ +
+
+ +
+
+ + + + + + + +
QwtInterval QwtInterval::normalized () const
+
+ +

Normalize the limits of the interval.

+

If maxValue() < minValue() the limits will be inverted.

+
Returns
Normalized interval
+
See Also
isValid(), inverted()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool QwtInterval::operator!= (const QwtIntervalother) const
+
+inline
+
+ +

Compare two intervals.

+
Parameters
+ + +
otherInterval to compare with
+
+
+
Returns
True, when this and other are not equal
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
QwtInterval QwtInterval::operator& (const QwtIntervalother) const
+
+inline
+
+ +

Intersection of two intervals.

+
Parameters
+ + +
otherInterval to intersect with
+
+
+
Returns
Intersection of this and other
+
See Also
intersect()
+ +
+
+ +
+
+ + + + + + + + +
QwtInterval & QwtInterval::operator&= (const QwtIntervalother)
+
+ +

Intersect this interval with the given interval.

+
Parameters
+ + +
otherInterval to be intersected with
+
+
+
Returns
This interval
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool QwtInterval::operator== (const QwtIntervalother) const
+
+inline
+
+ +

Compare two intervals.

+
Parameters
+ + +
otherInterval to compare with
+
+
+
Returns
True, when this and other are equal
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
QwtInterval QwtInterval::operator| (const QwtIntervalother) const
+
+inline
+
+

Union of two intervals

+
Parameters
+ + +
otherInterval to unite with
+
+
+
Returns
Union of this and other
+
See Also
unite()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
QwtInterval QwtInterval::operator| (double value) const
+
+inline
+
+

Extend an interval

+
Parameters
+ + +
valueValue
+
+
+
Returns
Extended interval
+
See Also
extend()
+ +
+
+ +
+
+ + + + + + + + +
QwtInterval & QwtInterval::operator|= (const QwtIntervalother)
+
+ +

Unite this interval with the given interval.

+
Parameters
+ + +
otherInterval to be united with
+
+
+
Returns
This interval
+ +
+
+ +
+
+ + + + + + + + +
QwtInterval & QwtInterval::operator|= (double value)
+
+

Extend an interval

+
Parameters
+ + +
valueValue
+
+
+
Returns
Reference of the extended interval
+
See Also
extend()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtInterval::setBorderFlags (BorderFlags borderFlags)
+
+inline
+
+

Change the border flags

+
Parameters
+ + +
borderFlagsOr'd BorderMode flags
+
+
+
See Also
borderFlags()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
void QwtInterval::setInterval (double minValue,
double maxValue,
BorderFlags borderFlags = IncludeBorders 
)
+
+inline
+
+

Assign the limits of the interval

+
Parameters
+ + + + +
minValueMinimum value
maxValueMaximum value
borderFlagsInclude/Exclude borders
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtInterval::setMaxValue (double maxValue)
+
+inline
+
+

Assign the upper limit of the interval

+
Parameters
+ + +
maxValueMaximum value
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtInterval::setMinValue (double minValue)
+
+inline
+
+

Assign the lower limit of the interval

+
Parameters
+ + +
minValueMinimum value
+
+
+ +
+
+ +
+
+ + + + + + + + +
QwtInterval QwtInterval::symmetrize (double value) const
+
+

Adjust the limit that is closer to value, so that value becomes the center of the interval.

+
Parameters
+ + +
valueCenter
+
+
+
Returns
Interval with value as center
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
double QwtInterval::width () const
+
+inline
+
+ +

Return the width of an interval.

+

The width of invalid intervals is 0.0, otherwise the result is maxValue() - minValue().

+
Returns
Interval width
+
See Also
isValid()
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_interval_sample-members.html b/ThirdParty/Qwt/doc/html/class_qwt_interval_sample-members.html new file mode 100644 index 0000000000..72dcfe5356 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_interval_sample-members.html @@ -0,0 +1,107 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtIntervalSample Member List
+
+
+ +

This is the complete list of members for QwtIntervalSample, including all inherited members.

+ + + + + + + + +
intervalQwtIntervalSample
operator!=(const QwtIntervalSample &) const QwtIntervalSampleinline
operator==(const QwtIntervalSample &) const QwtIntervalSampleinline
QwtIntervalSample()QwtIntervalSampleinline
QwtIntervalSample(double, const QwtInterval &)QwtIntervalSampleinline
QwtIntervalSample(double value, double min, double max)QwtIntervalSampleinline
valueQwtIntervalSample
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_interval_sample.html b/ThirdParty/Qwt/doc/html/class_qwt_interval_sample.html new file mode 100644 index 0000000000..ce9c48ea93 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_interval_sample.html @@ -0,0 +1,166 @@ + + + + + + +Qwt User's Guide: QwtIntervalSample Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtIntervalSample Class Reference
+
+
+ +

A sample of the types (x1-x2, y) or (x, y1-y2) + More...

+ +

#include <qwt_samples.h>

+ + + + + + + + + + + + + + + + +

+Public Member Functions

 QwtIntervalSample ()
 
QwtIntervalSample (double, const QwtInterval &)
 Constructor.
 
QwtIntervalSample (double value, double min, double max)
 Constructor.
 
+bool operator== (const QwtIntervalSample &) const
 Compare operator.
 
+bool operator!= (const QwtIntervalSample &) const
 Compare operator.
 
+ + + + + + + +

+Public Attributes

+double value
 Value.
 
+QwtInterval interval
 Interval.
 
+

Detailed Description

+

A sample of the types (x1-x2, y) or (x, y1-y2)

+

Constructor & Destructor Documentation

+ +
+
+ + + + + +
+ + + + + + + +
QwtIntervalSample::QwtIntervalSample ()
+
+inline
+
+

Constructor The value is set to 0.0, the interval is invalid

+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_interval_series_data-members.html b/ThirdParty/Qwt/doc/html/class_qwt_interval_series_data-members.html new file mode 100644 index 0000000000..b6b5256ec6 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_interval_series_data-members.html @@ -0,0 +1,113 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtIntervalSeriesData Member List
+
+ + + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_interval_series_data.html b/ThirdParty/Qwt/doc/html/class_qwt_interval_series_data.html new file mode 100644 index 0000000000..8964cb23b5 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_interval_series_data.html @@ -0,0 +1,211 @@ + + + + + + +Qwt User's Guide: QwtIntervalSeriesData Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtIntervalSeriesData Class Reference
+
+
+ +

Interface for iterating over an array of intervals. + More...

+ +

#include <qwt_series_data.h>

+
+Inheritance diagram for QwtIntervalSeriesData:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 QwtIntervalSeriesData (const QVector< QwtIntervalSample > &=QVector< QwtIntervalSample >())
 
virtual QRectF boundingRect () const
 Calculate the bounding rectangle. More...
 
- Public Member Functions inherited from QwtArraySeriesData< QwtIntervalSample >
QwtArraySeriesData ()
 Constructor.
 
 QwtArraySeriesData (const QVector< QwtIntervalSample > &samples)
 
void setSamples (const QVector< QwtIntervalSample > &samples)
 
const QVector< QwtIntervalSamplesamples () const
 
virtual size_t size () const
 
virtual QwtIntervalSample sample (size_t index) const
 
- Public Member Functions inherited from QwtSeriesData< QwtIntervalSample >
QwtSeriesData ()
 Constructor.
 
+virtual ~QwtSeriesData ()
 Destructor.
 
virtual void setRectOfInterest (const QRectF &rect)
 
+ + + + + +

+Additional Inherited Members

- Protected Attributes inherited from QwtArraySeriesData< QwtIntervalSample >
+QVector< QwtIntervalSampled_samples
 Vector of samples.
 
+

Detailed Description

+

Interface for iterating over an array of intervals.

+

Constructor & Destructor Documentation

+ +
+
+ + + + + + + + +
QwtIntervalSeriesData::QwtIntervalSeriesData (const QVector< QwtIntervalSample > & samples = QVector<QwtIntervalSample>())
+
+

Constructor

+
Parameters
+ + +
samplesSamples
+
+
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + +
QRectF QwtIntervalSeriesData::boundingRect () const
+
+virtual
+
+ +

Calculate the bounding rectangle.

+

The bounding rectangle is calculated once by iterating over all points and is stored for all following requests.

+
Returns
Bounding rectangle
+ +

Implements QwtSeriesData< QwtIntervalSample >.

+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_interval_series_data__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_interval_series_data__inherit__graph.map new file mode 100644 index 0000000000..88fdd09b60 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_interval_series_data__inherit__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_interval_series_data__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_interval_series_data__inherit__graph.md5 new file mode 100644 index 0000000000..0503145905 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_interval_series_data__inherit__graph.md5 @@ -0,0 +1 @@ +689dd42c2aa242568a9baf0be221c321 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_interval_series_data__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_interval_series_data__inherit__graph.png new file mode 100644 index 0000000000..252749b3e6 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_interval_series_data__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_interval_symbol-members.html b/ThirdParty/Qwt/doc/html/class_qwt_interval_symbol-members.html new file mode 100644 index 0000000000..76af19741b --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_interval_symbol-members.html @@ -0,0 +1,121 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtIntervalSymbol Member List
+
+
+ +

This is the complete list of members for QwtIntervalSymbol, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + +
Bar enum valueQwtIntervalSymbol
Box enum valueQwtIntervalSymbol
brush() const QwtIntervalSymbol
draw(QPainter *, Qt::Orientation, const QPointF &from, const QPointF &to) const QwtIntervalSymbolvirtual
NoSymbol enum valueQwtIntervalSymbol
operator!=(const QwtIntervalSymbol &) const QwtIntervalSymbol
operator=(const QwtIntervalSymbol &)QwtIntervalSymbol
operator==(const QwtIntervalSymbol &) const QwtIntervalSymbol
pen() const QwtIntervalSymbol
QwtIntervalSymbol(Style=NoSymbol)QwtIntervalSymbol
QwtIntervalSymbol(const QwtIntervalSymbol &)QwtIntervalSymbol
setBrush(const QBrush &b)QwtIntervalSymbol
setPen(const QColor &, qreal width=0.0, Qt::PenStyle=Qt::SolidLine)QwtIntervalSymbol
setPen(const QPen &)QwtIntervalSymbol
setStyle(Style)QwtIntervalSymbol
setWidth(int)QwtIntervalSymbol
style() const QwtIntervalSymbol
Style enum nameQwtIntervalSymbol
UserSymbol enum valueQwtIntervalSymbol
width() const QwtIntervalSymbol
~QwtIntervalSymbol()QwtIntervalSymbolvirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_interval_symbol.html b/ThirdParty/Qwt/doc/html/class_qwt_interval_symbol.html new file mode 100644 index 0000000000..4a9a2acd33 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_interval_symbol.html @@ -0,0 +1,487 @@ + + + + + + +Qwt User's Guide: QwtIntervalSymbol Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtIntervalSymbol Class Reference
+
+
+ +

A drawing primitive for displaying an interval like an error bar. + More...

+ +

#include <qwt_interval_symbol.h>

+ + + + + +

+Public Types

enum  Style { NoSymbol = -1, +Bar, +Box, +UserSymbol = 1000 + }
 Symbol style. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 QwtIntervalSymbol (Style=NoSymbol)
 
QwtIntervalSymbol (const QwtIntervalSymbol &)
 Copy constructor.
 
+virtual ~QwtIntervalSymbol ()
 Destructor.
 
+QwtIntervalSymboloperator= (const QwtIntervalSymbol &)
 Assignment operator.
 
+bool operator== (const QwtIntervalSymbol &) const
 Compare two symbols.
 
+bool operator!= (const QwtIntervalSymbol &) const
 Compare two symbols.
 
void setWidth (int)
 
int width () const
 
void setBrush (const QBrush &b)
 Assign a brush. More...
 
const QBrush & brush () const
 
void setPen (const QColor &, qreal width=0.0, Qt::PenStyle=Qt::SolidLine)
 
void setPen (const QPen &)
 
const QPen & pen () const
 
void setStyle (Style)
 
Style style () const
 
virtual void draw (QPainter *, Qt::Orientation, const QPointF &from, const QPointF &to) const
 
+

Detailed Description

+

A drawing primitive for displaying an interval like an error bar.

+
See Also
QwtPlotIntervalCurve
+

Member Enumeration Documentation

+ +
+
+ + + + +
enum QwtIntervalSymbol::Style
+
+ +

Symbol style.

+ + + + + +
Enumerator
NoSymbol  +

No Style. The symbol cannot be drawn.

+
Bar  +

The symbol displays a line with caps at the beginning/end. The size of the caps depends on the symbol width().

+
Box  +

The symbol displays a plain rectangle using pen() and brush(). The size of the rectangle depends on the translated interval and the width(),

+
UserSymbol  +

Styles >= UserSymbol are reserved for derived classes of QwtIntervalSymbol that overload draw() with additional application specific symbol types.

+
+ +
+
+

Constructor & Destructor Documentation

+ +
+
+ + + + + + + + +
QwtIntervalSymbol::QwtIntervalSymbol (Style style = NoSymbol)
+
+

Constructor

+
Parameters
+ + +
styleStyle of the symbol
+
+
+
See Also
setStyle(), style(), Style
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + + + +
const QBrush & QwtIntervalSymbol::brush () const
+
+
Returns
Brush
+
See Also
setBrush()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void QwtIntervalSymbol::draw (QPainter * painter,
Qt::Orientation orientation,
const QPointF & from,
const QPointF & to 
) const
+
+virtual
+
+

Draw a symbol depending on its style

+
Parameters
+ + + + + +
painterPainter
orientationOrientation
fromStart point of the interval in target device coordinates
toEnd point of the interval in target device coordinates
+
+
+
See Also
setStyle()
+ +
+
+ +
+
+ + + + + + + +
const QPen & QwtIntervalSymbol::pen () const
+
+
Returns
Pen
+
See Also
setPen(), brush()
+ +
+
+ +
+
+ + + + + + + + +
void QwtIntervalSymbol::setBrush (const QBrush & brush)
+
+ +

Assign a brush.

+

The brush is used for the Box style.

+
Parameters
+ + +
brushBrush
+
+
+
See Also
brush()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void QwtIntervalSymbol::setPen (const QColor & color,
qreal width = 0.0,
Qt::PenStyle style = Qt::SolidLine 
)
+
+

Build and assign a pen

+

In Qt5 the default pen width is 1.0 ( 0.0 in Qt4 ) what makes it non cosmetic ( see QPen::isCosmetic() ). This method has been introduced to hide this incompatibility.

+
Parameters
+ + + + +
colorPen color
widthPen width
stylePen style
+
+
+
See Also
pen(), brush()
+ +
+
+ +
+
+ + + + + + + + +
void QwtIntervalSymbol::setPen (const QPen & pen)
+
+

Assign a pen

+
Parameters
+ + +
penPen
+
+
+
See Also
pen(), setBrush()
+ +
+
+ +
+
+ + + + + + + + +
void QwtIntervalSymbol::setStyle (Style style)
+
+

Specify the symbol style

+
Parameters
+ + +
styleStyle
+
+
+
See Also
style(), Style
+ +
+
+ +
+
+ + + + + + + + +
void QwtIntervalSymbol::setWidth (int width)
+
+

Specify the width of the symbol It is used depending on the style.

+
Parameters
+ + +
widthWidth
+
+
+
See Also
width(), setStyle()
+ +
+
+ +
+
+ + + + + + + +
QwtIntervalSymbol::Style QwtIntervalSymbol::style () const
+
+
Returns
Current symbol style
+
See Also
setStyle()
+ +
+
+ +
+
+ + + + + + + +
int QwtIntervalSymbol::width () const
+
+
Returns
Width of the symbol.
+
See Also
setWidth(), setStyle()
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_knob-members.html b/ThirdParty/Qwt/doc/html/class_qwt_knob-members.html new file mode 100644 index 0000000000..e85e8e28df --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_knob-members.html @@ -0,0 +1,207 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtKnob Member List
+
+
+ +

This is the complete list of members for QwtKnob, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
abstractScaleDraw() const QwtAbstractScaleprotected
abstractScaleDraw()QwtAbstractScaleprotected
alignment() const QwtKnob
borderWidth() const QwtKnob
changeEvent(QEvent *)QwtKnobprotectedvirtual
Dot enum valueQwtKnob
drawFocusIndicator(QPainter *) const QwtKnobprotectedvirtual
drawKnob(QPainter *, const QRectF &) const QwtKnobprotectedvirtual
drawMarker(QPainter *, const QRectF &, double arc) const QwtKnobprotectedvirtual
Flat enum valueQwtKnob
incrementedValue(double value, int stepCount) const QwtAbstractSliderprotected
incrementValue(int numSteps)QwtAbstractSliderprotected
invertedControls() const QwtAbstractSlider
invTransform(int) const QwtAbstractScale
isInverted() const QwtAbstractScale
isReadOnly() const QwtAbstractSlider
isScrollPosition(const QPoint &) const QwtKnobprotectedvirtual
isTracking() const QwtAbstractSlider
isValid() const QwtAbstractSlider
keyPressEvent(QKeyEvent *)QwtAbstractSliderprotectedvirtual
knobRect() const QwtKnob
KnobStyle enum nameQwtKnob
knobStyle() const QwtKnob
knobWidth() const QwtKnob
lowerBound() const QwtAbstractScale
markerSize() const QwtKnob
MarkerStyle enum nameQwtKnob
markerStyle() const QwtKnob
maximum() const QwtAbstractScale
minimum() const QwtAbstractScale
minimumSizeHint() const QwtKnobvirtual
mouseMoveEvent(QMouseEvent *)QwtAbstractSliderprotectedvirtual
mousePressEvent(QMouseEvent *)QwtAbstractSliderprotectedvirtual
mouseReleaseEvent(QMouseEvent *)QwtAbstractSliderprotectedvirtual
NoMarker enum valueQwtKnob
Notch enum valueQwtKnob
Nub enum valueQwtKnob
numTurns() const QwtKnob
pageSteps() const QwtAbstractSlider
paintEvent(QPaintEvent *)QwtKnobprotectedvirtual
QwtAbstractScale(QWidget *parent=NULL)QwtAbstractScale
QwtAbstractSlider(QWidget *parent=NULL)QwtAbstractSliderexplicit
QwtKnob(QWidget *parent=NULL)QwtKnobexplicit
Raised enum valueQwtKnob
rescale(double lowerBound, double upperBound, double stepSize)QwtAbstractScaleprotected
scaleChange()QwtAbstractSliderprotectedvirtual
scaleDiv() const QwtAbstractScale
scaleDraw() const QwtKnob
scaleDraw()QwtKnob
scaleEngine() const QwtAbstractScale
scaleEngine()QwtAbstractScale
scaleMap() const QwtAbstractScale
scaleMaxMajor() const QwtAbstractScale
scaleMaxMinor() const QwtAbstractScale
scaleStepSize() const QwtAbstractScale
scrolledTo(const QPoint &) const QwtKnobprotectedvirtual
setAbstractScaleDraw(QwtAbstractScaleDraw *)QwtAbstractScaleprotected
setAlignment(Qt::Alignment)QwtKnob
setBorderWidth(int bw)QwtKnob
setInvertedControls(bool)QwtAbstractSlider
setKnobStyle(KnobStyle)QwtKnob
setKnobWidth(int)QwtKnob
setLowerBound(double value)QwtAbstractScale
setMarkerSize(int)QwtKnob
setMarkerStyle(MarkerStyle)QwtKnob
setNumTurns(int)QwtKnob
setPageSteps(uint)QwtAbstractSlider
setReadOnly(bool)QwtAbstractSlider
setScale(double lowerBound, double upperBound)QwtAbstractScale
setScale(const QwtInterval &)QwtAbstractScale
setScale(const QwtScaleDiv &)QwtAbstractScale
setScaleDraw(QwtRoundScaleDraw *)QwtKnob
setScaleEngine(QwtScaleEngine *)QwtAbstractScale
setScaleMaxMajor(int ticks)QwtAbstractScale
setScaleMaxMinor(int ticks)QwtAbstractScale
setScaleStepSize(double stepSize)QwtAbstractScale
setSingleSteps(uint)QwtAbstractSlider
setStepAlignment(bool)QwtAbstractSlider
setTotalAngle(double angle)QwtKnob
setTotalSteps(uint)QwtAbstractSlider
setTracking(bool)QwtAbstractSlider
setUpperBound(double value)QwtAbstractScale
setValid(bool)QwtAbstractSlider
setValue(double val)QwtAbstractSliderslot
setWrapping(bool)QwtAbstractSlider
singleSteps() const QwtAbstractSlider
sizeHint() const QwtKnobvirtual
sliderChange()QwtAbstractSliderprotectedvirtual
sliderMoved(double value)QwtAbstractSlidersignal
sliderPressed()QwtAbstractSlidersignal
sliderReleased()QwtAbstractSlidersignal
stepAlignment() const QwtAbstractSlider
Styled enum valueQwtKnob
Sunken enum valueQwtKnob
Tick enum valueQwtKnob
totalAngle() const QwtKnob
totalSteps() const QwtAbstractSlider
transform(double) const QwtAbstractScale
Triangle enum valueQwtKnob
upperBound() const QwtAbstractScale
value() const QwtAbstractSlider
valueChanged(double value)QwtAbstractSlidersignal
wheelEvent(QWheelEvent *)QwtAbstractSliderprotectedvirtual
wrapping() const QwtAbstractSlider
~QwtAbstractScale()QwtAbstractScalevirtual
~QwtAbstractSlider()QwtAbstractSlidervirtual
~QwtKnob()QwtKnobvirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_knob.html b/ThirdParty/Qwt/doc/html/class_qwt_knob.html new file mode 100644 index 0000000000..78b259f040 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_knob.html @@ -0,0 +1,1186 @@ + + + + + + +Qwt User's Guide: QwtKnob Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+ +
+ +

The Knob Widget. + More...

+ +

#include <qwt_knob.h>

+
+Inheritance diagram for QwtKnob:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + +

+Public Types

enum  KnobStyle { Flat, +Raised, +Sunken, +Styled + }
 Style of the knob surface. More...
 
enum  MarkerStyle {
+  NoMarker = -1, +Tick, +Triangle, +Dot, +
+  Nub, +Notch +
+ }
 Marker type. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 QwtKnob (QWidget *parent=NULL)
 Constructor. More...
 
+virtual ~QwtKnob ()
 Destructor.
 
void setAlignment (Qt::Alignment)
 Set the alignment of the knob. More...
 
Qt::Alignment alignment () const
 
void setKnobWidth (int)
 Change the knob's width. More...
 
+int knobWidth () const
 Return the width of the knob.
 
void setNumTurns (int)
 Set the number of turns. More...
 
int numTurns () const
 
void setTotalAngle (double angle)
 Set the total angle by which the knob can be turned. More...
 
double totalAngle () const
 
void setKnobStyle (KnobStyle)
 Set the knob type. More...
 
KnobStyle knobStyle () const
 
void setBorderWidth (int bw)
 Set the knob's border width. More...
 
+int borderWidth () const
 Return the border width.
 
void setMarkerStyle (MarkerStyle)
 Set the marker type of the knob. More...
 
MarkerStyle markerStyle () const
 
void setMarkerSize (int)
 Set the size of the marker. More...
 
int markerSize () const
 
virtual QSize sizeHint () const
 
virtual QSize minimumSizeHint () const
 
void setScaleDraw (QwtRoundScaleDraw *)
 
const QwtRoundScaleDrawscaleDraw () const
 
QwtRoundScaleDrawscaleDraw ()
 
QRect knobRect () const
 
- Public Member Functions inherited from QwtAbstractSlider
 QwtAbstractSlider (QWidget *parent=NULL)
 Constructor. More...
 
+virtual ~QwtAbstractSlider ()
 Destructor.
 
void setValid (bool)
 
bool isValid () const
 
+double value () const
 Returns the current value.
 
void setWrapping (bool)
 
bool wrapping () const
 
void setTotalSteps (uint)
 Set the number of steps. More...
 
uint totalSteps () const
 
void setSingleSteps (uint)
 Set the number of steps for a single increment. More...
 
uint singleSteps () const
 
void setPageSteps (uint)
 Set the number of steps for a page increment. More...
 
uint pageSteps () const
 
void setStepAlignment (bool)
 Enable step alignment. More...
 
bool stepAlignment () const
 
void setTracking (bool)
 Enables or disables tracking. More...
 
bool isTracking () const
 
void setReadOnly (bool)
 
bool isReadOnly () const
 
void setInvertedControls (bool)
 
bool invertedControls () const
 
- Public Member Functions inherited from QwtAbstractScale
 QwtAbstractScale (QWidget *parent=NULL)
 
+virtual ~QwtAbstractScale ()
 Destructor.
 
void setScale (double lowerBound, double upperBound)
 Specify a scale. More...
 
void setScale (const QwtInterval &)
 Specify a scale. More...
 
void setScale (const QwtScaleDiv &)
 Specify a scale. More...
 
const QwtScaleDivscaleDiv () const
 
void setLowerBound (double value)
 
double lowerBound () const
 
void setUpperBound (double value)
 
double upperBound () const
 
void setScaleStepSize (double stepSize)
 Set the step size used for calculating a scale division. More...
 
double scaleStepSize () const
 
void setScaleMaxMajor (int ticks)
 Set the maximum number of major tick intervals. More...
 
int scaleMaxMinor () const
 
void setScaleMaxMinor (int ticks)
 Set the maximum number of minor tick intervals. More...
 
int scaleMaxMajor () const
 
void setScaleEngine (QwtScaleEngine *)
 Set a scale engine. More...
 
const QwtScaleEnginescaleEngine () const
 
QwtScaleEnginescaleEngine ()
 
int transform (double) const
 
double invTransform (int) const
 
bool isInverted () const
 
double minimum () const
 
double maximum () const
 
const QwtScaleMapscaleMap () const
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Protected Member Functions

virtual void paintEvent (QPaintEvent *)
 
virtual void changeEvent (QEvent *)
 
virtual void drawKnob (QPainter *, const QRectF &) const
 Draw the knob. More...
 
virtual void drawFocusIndicator (QPainter *) const
 
virtual void drawMarker (QPainter *, const QRectF &, double arc) const
 Draw the marker at the knob's front. More...
 
virtual double scrolledTo (const QPoint &) const
 Determine the value for a new position of the mouse. More...
 
virtual bool isScrollPosition (const QPoint &) const
 Determine what to do when the user presses a mouse button. More...
 
- Protected Member Functions inherited from QwtAbstractSlider
virtual void mousePressEvent (QMouseEvent *)
 
virtual void mouseReleaseEvent (QMouseEvent *)
 
virtual void mouseMoveEvent (QMouseEvent *)
 
virtual void keyPressEvent (QKeyEvent *)
 
virtual void wheelEvent (QWheelEvent *)
 
void incrementValue (int numSteps)
 
virtual void scaleChange ()
 
+virtual void sliderChange ()
 Calling update()
 
double incrementedValue (double value, int stepCount) const
 
- Protected Member Functions inherited from QwtAbstractScale
void rescale (double lowerBound, double upperBound, double stepSize)
 
void setAbstractScaleDraw (QwtAbstractScaleDraw *)
 Set a scale draw. More...
 
const QwtAbstractScaleDrawabstractScaleDraw () const
 
QwtAbstractScaleDrawabstractScaleDraw ()
 
+ + + + + + + + + + + + + + +

+Additional Inherited Members

- Public Slots inherited from QwtAbstractSlider
void setValue (double val)
 
- Signals inherited from QwtAbstractSlider
void valueChanged (double value)
 Notify a change of value. More...
 
void sliderPressed ()
 
void sliderReleased ()
 
void sliderMoved (double value)
 
+

Detailed Description

+

The Knob Widget.

+

The QwtKnob widget imitates look and behavior of a volume knob on a radio. It looks similar to QDial - not to QwtDial.

+

The value range of a knob might be divided into several turns.

+

The layout of the knob depends on the knobWidth().

+
    +
  • width > 0 The diameter of the knob is fixed and the knob is aligned according to the alignment() flags inside of the contentsRect().
  • +
+
    +
  • width <= 0 The knob is extended to the minimum of width/height of the contentsRect() and aligned in the other direction according to alignment().
  • +
+

Setting a fixed knobWidth() is helpful to align several knobs with different scale labels.

+
+knob.png +
+

Member Enumeration Documentation

+ +
+
+ + + + +
enum QwtKnob::KnobStyle
+
+ +

Style of the knob surface.

+

Depending on the KnobStyle the surface of the knob is filled from the brushes of the widget palette().

+
See Also
setKnobStyle(), knobStyle()
+ + + + + +
Enumerator
Flat  +

Fill the knob with a brush from QPalette::Button.

+
Raised  +

Build a gradient from QPalette::Midlight and QPalette::Button.

+
Sunken  +

Build a gradient from QPalette::Midlight, QPalette::Button and QPalette::Midlight

+
Styled  +

Build a radial gradient from QPalette::Button like it is used for QDial in various Qt styles.

+
+ +
+
+ +
+
+ + + + +
enum QwtKnob::MarkerStyle
+
+ +

Marker type.

+

The marker indicates the current value on the knob The default setting is a Notch marker.

+
See Also
setMarkerStyle(), setMarkerSize()
+ + + + + + + +
Enumerator
NoMarker  +

Don't paint any marker.

+
Tick  +

Paint a single tick in QPalette::ButtonText color.

+
Triangle  +

Paint a triangle in QPalette::ButtonText color.

+
Dot  +

Paint a circle in QPalette::ButtonText color.

+
Nub  +

Draw a raised ellipse with a gradient build from QPalette::Light and QPalette::Mid

+
Notch  +

Draw a sunken ellipse with a gradient build from QPalette::Light and QPalette::Mid

+
+ +
+
+

Constructor & Destructor Documentation

+ +
+
+ + + + + +
+ + + + + + + + +
QwtKnob::QwtKnob (QWidget * parent = NULL)
+
+explicit
+
+ +

Constructor.

+

Construct a knob with an angle of 270°. The style is QwtKnob::Raised and the marker style is QwtKnob::Notch. The width of the knob is set to 50 pixels.

+
Parameters
+ + +
parentParent widget
+
+
+
See Also
setTotalAngle()
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + + + +
Qt::Alignment QwtKnob::alignment () const
+
+
Returns
Alignment of the knob inside of contentsRect()
+
See Also
setAlignment(), knobWidth(), knobRect()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtKnob::changeEvent (QEvent * event)
+
+protectedvirtual
+
+

Handle QEvent::StyleChange and QEvent::FontChange;

+
Parameters
+ + +
eventChange event
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtKnob::drawFocusIndicator (QPainter * painter) const
+
+protectedvirtual
+
+

Draw the focus indicator

+
Parameters
+ + +
painterPainter
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void QwtKnob::drawKnob (QPainter * painter,
const QRectF & knobRect 
) const
+
+protectedvirtual
+
+ +

Draw the knob.

+
Parameters
+ + + +
painterpainter
knobRectBounding rectangle of the knob (without scale)
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
void QwtKnob::drawMarker (QPainter * painter,
const QRectF & rect,
double angle 
) const
+
+protectedvirtual
+
+ +

Draw the marker at the knob's front.

+
Parameters
+ + + + +
painterPainter
rectBounding rectangle of the knob without scale
angleAngle of the marker in degrees ( clockwise, 0 at the 12 o'clock position )
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool QwtKnob::isScrollPosition (const QPoint & pos) const
+
+protectedvirtual
+
+ +

Determine what to do when the user presses a mouse button.

+
Parameters
+ + +
posMouse position
+
+
+
Return values
+ + +
True,whenpos is inside the circle of the knob.
+
+
+
See Also
scrolledTo()
+ +

Implements QwtAbstractSlider.

+ +
+
+ +
+
+ + + + + + + +
QRect QwtKnob::knobRect () const
+
+

Calculate the bounding rectangle of the knob without the scale

+
Returns
Bounding rectangle of the knob
+
See Also
knobWidth(), alignment(), QWidget::contentsRect()
+ +
+
+ +
+
+ + + + + + + +
QwtKnob::KnobStyle QwtKnob::knobStyle () const
+
+
Returns
Marker type of the knob
+
See Also
setKnobStyle(), setBorderWidth()
+ +
+
+ +
+
+ + + + + + + +
int QwtKnob::markerSize () const
+
+
Returns
Marker size
+
See Also
setMarkerSize()
+ +
+
+ +
+
+ + + + + + + +
QwtKnob::MarkerStyle QwtKnob::markerStyle () const
+
+
Returns
Marker type of the knob
+
See Also
setMarkerStyle(), setMarkerSize()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
QSize QwtKnob::minimumSizeHint () const
+
+virtual
+
+
Returns
Minimum size hint
+
See Also
sizeHint()
+ +
+
+ +
+
+ + + + + + + +
int QwtKnob::numTurns () const
+
+
Returns
Number of turns.
+

When the total angle is below 360° numTurns() is ceiled to 1.

+
See Also
setNumTurns(), setTotalAngle(), totalAngle()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtKnob::paintEvent (QPaintEvent * event)
+
+protectedvirtual
+
+

Repaint the knob

+
Parameters
+ + +
eventPaint event
+
+
+ +
+
+ +
+
+ + + + + + + +
const QwtRoundScaleDraw * QwtKnob::scaleDraw () const
+
+
Returns
the scale draw of the knob
+
See Also
setScaleDraw()
+ +
+
+ +
+
+ + + + + + + +
QwtRoundScaleDraw * QwtKnob::scaleDraw ()
+
+
Returns
the scale draw of the knob
+
See Also
setScaleDraw()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
double QwtKnob::scrolledTo (const QPoint & pos) const
+
+protectedvirtual
+
+ +

Determine the value for a new position of the mouse.

+
Parameters
+ + +
posMouse position
+
+
+
Returns
Value for the mouse position
+
See Also
isScrollPosition()
+ +

Implements QwtAbstractSlider.

+ +
+
+ +
+
+ + + + + + + + +
void QwtKnob::setAlignment (Qt::Alignment alignment)
+
+ +

Set the alignment of the knob.

+

Similar to a QLabel::alignment() the flags decide how to align the knob inside of contentsRect().

+

The default setting is Qt::AlignCenter

+
Parameters
+ + +
alignmentOr'd alignment flags
+
+
+
See Also
alignment(), setKnobWidth(), knobRect()
+ +
+
+ +
+
+ + + + + + + + +
void QwtKnob::setBorderWidth (int borderWidth)
+
+ +

Set the knob's border width.

+
Parameters
+ + +
borderWidthnew border width
+
+
+ +
+
+ +
+
+ + + + + + + + +
void QwtKnob::setKnobStyle (KnobStyle knobStyle)
+
+ +

Set the knob type.

+
Parameters
+ + +
knobStyleKnob type
+
+
+
See Also
knobStyle(), setBorderWidth()
+ +
+
+ +
+
+ + + + + + + + +
void QwtKnob::setKnobWidth (int width)
+
+ +

Change the knob's width.

+

Setting a fixed value for the diameter of the knob is helpful for aligning several knobs in a row.

+
Parameters
+ + +
widthNew width
+
+
+
See Also
knobWidth(), setAlignment()
+
Note
Modifies the sizePolicy()
+ +
+
+ +
+
+ + + + + + + + +
void QwtKnob::setMarkerSize (int size)
+
+ +

Set the size of the marker.

+

When setting a size <= 0 the marker will automatically scaled to 40% of the radius of the knob.

+
See Also
markerSize(), markerStyle()
+ +
+
+ +
+
+ + + + + + + + +
void QwtKnob::setMarkerStyle (MarkerStyle markerStyle)
+
+ +

Set the marker type of the knob.

+
Parameters
+ + +
markerStyleMarker type
+
+
+
See Also
markerStyle(), setMarkerSize()
+ +
+
+ +
+
+ + + + + + + + +
void QwtKnob::setNumTurns (int numTurns)
+
+ +

Set the number of turns.

+

When numTurns > 1 the knob can be turned several times around its axis

+
    +
  • otherwise the total angle is floored to 360°.
  • +
+
See Also
numTurns(), totalAngle(), setTotalAngle()
+ +
+
+ +
+
+ + + + + + + + +
void QwtKnob::setScaleDraw (QwtRoundScaleDrawscaleDraw)
+
+

Change the scale draw of the knob

+

For changing the labels of the scales, it is necessary to derive from QwtRoundScaleDraw and overload QwtRoundScaleDraw::label().

+
See Also
scaleDraw()
+ +
+
+ +
+
+ + + + + + + + +
void QwtKnob::setTotalAngle (double angle)
+
+ +

Set the total angle by which the knob can be turned.

+
Parameters
+ + +
angleAngle in degrees.
+
+
+

The angle has to be between [10, 360] degrees. Angles above 360 ( so that the knob can be turned several times around its axis ) have to be set using setNumTurns().

+

The default angle is 270 degrees.

+
See Also
totalAngle(), setNumTurns()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
QSize QwtKnob::sizeHint () const
+
+virtual
+
+
Returns
sizeHint()
+ +
+
+ +
+
+ + + + + + + +
double QwtKnob::totalAngle () const
+
+
Returns
the total angle
+
See Also
setTotalAngle(), setNumTurns(), numTurns()
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_knob__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_knob__inherit__graph.map new file mode 100644 index 0000000000..e088280c75 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_knob__inherit__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_knob__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_knob__inherit__graph.md5 new file mode 100644 index 0000000000..8a6d12d7f6 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_knob__inherit__graph.md5 @@ -0,0 +1 @@ +a5843633807a000b04a46cbfd35a5e10 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_knob__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_knob__inherit__graph.png new file mode 100644 index 0000000000..e5b89bb817 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_knob__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_legend-members.html b/ThirdParty/Qwt/doc/html/class_qwt_legend-members.html new file mode 100644 index 0000000000..89b2938a73 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_legend-members.html @@ -0,0 +1,129 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtLegend Member List
+
+
+ +

This is the complete list of members for QwtLegend, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
checked(const QVariant &itemInfo, bool on, int index)QwtLegendsignal
clicked(const QVariant &itemInfo, int index)QwtLegendsignal
contentsWidget()QwtLegend
contentsWidget() const QwtLegend
createWidget(const QwtLegendData &) const QwtLegendprotectedvirtual
defaultItemMode() const QwtLegend
eventFilter(QObject *, QEvent *)QwtLegendvirtual
heightForWidth(int w) const QwtLegendvirtual
horizontalScrollBar() const QwtLegend
isEmpty() const QwtLegendvirtual
itemChecked(bool)QwtLegendprotectedslot
itemClicked()QwtLegendprotectedslot
itemInfo(const QWidget *) const QwtLegend
legendWidget(const QVariant &) const QwtLegend
legendWidgets(const QVariant &) const QwtLegend
maxColumns() const QwtLegend
QwtAbstractLegend(QWidget *parent=NULL)QwtAbstractLegendexplicit
QwtLegend(QWidget *parent=NULL)QwtLegendexplicit
renderItem(QPainter *, const QWidget *, const QRectF &, bool fillBackground) const QwtLegendvirtual
renderLegend(QPainter *, const QRectF &, bool fillBackground) const QwtLegendvirtual
scrollExtent(Qt::Orientation) const QwtLegendvirtual
setDefaultItemMode(QwtLegendData::Mode)QwtLegend
setMaxColumns(uint numColums)QwtLegend
sizeHint() const QwtLegendvirtual
updateLegend(const QVariant &, const QList< QwtLegendData > &)QwtLegendvirtualslot
updateWidget(QWidget *widget, const QwtLegendData &data)QwtLegendprotectedvirtual
verticalScrollBar() const QwtLegend
~QwtAbstractLegend()QwtAbstractLegendvirtual
~QwtLegend()QwtLegendvirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_legend.html b/ThirdParty/Qwt/doc/html/class_qwt_legend.html new file mode 100644 index 0000000000..c937a8eec0 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_legend.html @@ -0,0 +1,982 @@ + + + + + + +Qwt User's Guide: QwtLegend Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+ +
+ +

The legend widget. + More...

+ +

#include <qwt_legend.h>

+
+Inheritance diagram for QwtLegend:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + + +

+Public Slots

virtual void updateLegend (const QVariant &, const QList< QwtLegendData > &)
 Update the entries for an item. More...
 
- Public Slots inherited from QwtAbstractLegend
virtual void updateLegend (const QVariant &itemInfo, const QList< QwtLegendData > &data)=0
 Update the entries for a plot item. More...
 
+ + + + + +

+Signals

void clicked (const QVariant &itemInfo, int index)
 
void checked (const QVariant &itemInfo, bool on, int index)
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 QwtLegend (QWidget *parent=NULL)
 
+virtual ~QwtLegend ()
 Destructor.
 
void setMaxColumns (uint numColums)
 Set the maximum number of entries in a row. More...
 
uint maxColumns () const
 
void setDefaultItemMode (QwtLegendData::Mode)
 Set the default mode for legend labels. More...
 
QwtLegendData::Mode defaultItemMode () const
 
QWidget * contentsWidget ()
 
const QWidget * contentsWidget () const
 
QWidget * legendWidget (const QVariant &) const
 
QList< QWidget * > legendWidgets (const QVariant &) const
 
QVariant itemInfo (const QWidget *) const
 
virtual bool eventFilter (QObject *, QEvent *)
 
+virtual QSize sizeHint () const
 Return a size hint.
 
virtual int heightForWidth (int w) const
 
QScrollBar * horizontalScrollBar () const
 
QScrollBar * verticalScrollBar () const
 
virtual void renderLegend (QPainter *, const QRectF &, bool fillBackground) const
 
virtual void renderItem (QPainter *, const QWidget *, const QRectF &, bool fillBackground) const
 
virtual bool isEmpty () const
 
virtual int scrollExtent (Qt::Orientation) const
 
- Public Member Functions inherited from QwtAbstractLegend
 QwtAbstractLegend (QWidget *parent=NULL)
 
+virtual ~QwtAbstractLegend ()
 Destructor.
 
+ + + + + +

+Protected Slots

void itemClicked ()
 
void itemChecked (bool)
 
+ + + + + + + +

+Protected Member Functions

virtual QWidget * createWidget (const QwtLegendData &) const
 Create a widget to be inserted into the legend. More...
 
virtual void updateWidget (QWidget *widget, const QwtLegendData &data)
 Update the widget. More...
 
+

Detailed Description

+

The legend widget.

+

The QwtLegend widget is a tabular arrangement of legend items. Legend items might be any type of widget, but in general they will be a QwtLegendLabel.

+
See Also
QwtLegendLabel, QwtPlotItem, QwtPlot
+

Constructor & Destructor Documentation

+ +
+
+ + + + + +
+ + + + + + + + +
QwtLegend::QwtLegend (QWidget * parent = NULL)
+
+explicit
+
+

Constructor

+
Parameters
+ + +
parentParent widget
+
+
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
void QwtLegend::checked (const QVariant & itemInfo,
bool on,
int index 
)
+
+signal
+
+

A signal which is emitted when the user has clicked on a legend label, which is in QwtLegendData::Checkable mode

+
Parameters
+ + + + +
itemInfoInfo for the item of the selected legend label
indexIndex of the legend label in the list of widgets that are associated with the plot item
onTrue when the legend label is checked
+
+
+
Note
clicks are disabled as default
+
See Also
setDefaultItemMode(), defaultItemMode(), QwtPlot::itemToInfo()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void QwtLegend::clicked (const QVariant & itemInfo,
int index 
)
+
+signal
+
+

A signal which is emitted when the user has clicked on a legend label, which is in QwtLegendData::Clickable mode.

+
Parameters
+ + + +
itemInfoInfo for the item item of the selected legend item
indexIndex of the legend label in the list of widgets that are associated with the plot item
+
+
+
Note
clicks are disabled as default
+
See Also
setDefaultItemMode(), defaultItemMode(), QwtPlot::itemToInfo()
+ +
+
+ +
+
+ + + + + + + +
QWidget * QwtLegend::contentsWidget ()
+
+

The contents widget is the only child of the viewport of the internal QScrollArea and the parent widget of all legend items.

+
Returns
Container widget of the legend items
+ +
+
+ +
+
+ + + + + + + +
const QWidget * QwtLegend::contentsWidget () const
+
+

The contents widget is the only child of the viewport of the internal QScrollArea and the parent widget of all legend items.

+
Returns
Container widget of the legend items
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
QWidget * QwtLegend::createWidget (const QwtLegendDatadata) const
+
+protectedvirtual
+
+ +

Create a widget to be inserted into the legend.

+

The default implementation returns a QwtLegendLabel.

+
Parameters
+ + +
dataAttributes of the legend entry
+
+
+
Returns
Widget representing data on the legend
+
Note
updateWidget() will called soon after createWidget() with the same attributes.
+ +
+
+ +
+
+ + + + + + + +
QwtLegendData::Mode QwtLegend::defaultItemMode () const
+
+
Returns
Default item mode
+
See Also
setDefaultItemMode()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool QwtLegend::eventFilter (QObject * object,
QEvent * event 
)
+
+virtual
+
+

Handle QEvent::ChildRemoved andQEvent::LayoutRequest events for the contentsWidget().

+
Parameters
+ + + +
objectObject to be filtered
eventEvent
+
+
+
Returns
Forwarded to QwtAbstractLegend::eventFilter()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
int QwtLegend::heightForWidth (int width) const
+
+virtual
+
+
Returns
The preferred height, for a width.
+
Parameters
+ + +
widthWidth
+
+
+ +
+
+ +
+
+ + + + + + + +
QScrollBar * QwtLegend::horizontalScrollBar () const
+
+
Returns
Horizontal scrollbar
+
See Also
verticalScrollBar()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool QwtLegend::isEmpty () const
+
+virtual
+
+
Returns
True, when no item is inserted
+ +

Implements QwtAbstractLegend.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtLegend::itemChecked (bool on)
+
+protectedslot
+
+

Called internally when the legend has been checked Emits a checked() signal.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void QwtLegend::itemClicked ()
+
+protectedslot
+
+

Called internally when the legend has been clicked on. Emits a clicked() signal.

+ +
+
+ +
+
+ + + + + + + + +
QVariant QwtLegend::itemInfo (const QWidget * widget) const
+
+

Find the item that is associated to a widget

+
Parameters
+ + +
widgetWidget on the legend
+
+
+
Returns
Associated item info
+
See Also
legendWidget()
+ +
+
+ +
+
+ + + + + + + + +
QWidget * QwtLegend::legendWidget (const QVariant & itemInfo) const
+
+
Returns
First widget in the list of widgets associated to an item
+
Parameters
+ + +
itemInfoInfo about an item
+
+
+
See Also
itemInfo(), QwtPlot::itemToInfo()
+
Note
Almost all types of items have only one widget
+ +
+
+ +
+
+ + + + + + + + +
QList< QWidget * > QwtLegend::legendWidgets (const QVariant & itemInfo) const
+
+
Returns
List of widgets associated to a item
+
Parameters
+ + +
itemInfoInfo about an item
+
+
+
See Also
legendWidget(), itemInfo(), QwtPlot::itemToInfo()
+ +
+
+ +
+
+ + + + + + + +
uint QwtLegend::maxColumns () const
+
+
Returns
Maximum number of entries in a row
+
See Also
setMaxColumns(), QwtDynGridLayout::maxColumns()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void QwtLegend::renderItem (QPainter * painter,
const QWidget * widget,
const QRectF & rect,
bool fillBackground 
) const
+
+virtual
+
+

Render a legend entry into a given rectangle.

+
Parameters
+ + + + + +
painterPainter
widgetWidget representing a legend entry
rectBounding rectangle
fillBackgroundWhen true, fill rect with the widget background
+
+
+
Note
When widget is not derived from QwtLegendLabel renderItem does nothing beside the background
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
void QwtLegend::renderLegend (QPainter * painter,
const QRectF & rect,
bool fillBackground 
) const
+
+virtual
+
+

Render the legend into a given rectangle.

+
Parameters
+ + + + +
painterPainter
rectBounding rectangle
fillBackgroundWhen true, fill rect with the widget background
+
+
+
See Also
renderLegend() is used by QwtPlotRenderer - not by QwtLegend itself
+ +

Implements QwtAbstractLegend.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
int QwtLegend::scrollExtent (Qt::Orientation orientation) const
+
+virtual
+
+

Return the extent, that is needed for the scrollbars

+
Parameters
+ + +
orientationOrientation (
+
+
+
Returns
The width of the vertical scrollbar for Qt::Horizontal and v.v.
+ +

Reimplemented from QwtAbstractLegend.

+ +
+
+ +
+
+ + + + + + + + +
void QwtLegend::setDefaultItemMode (QwtLegendData::Mode mode)
+
+ +

Set the default mode for legend labels.

+

Legend labels will be constructed according to the attributes in a QwtLegendData object. When it doesn't contain a value for the QwtLegendData::ModeRole the label will be initialized with the default mode of the legend.

+
Parameters
+ + +
modeDefault item mode
+
+
+
See Also
itemMode(), QwtLegendData::value(), QwtPlotItem::legendData()
+
Note
Changing the mode doesn't have any effect on existing labels.
+ +
+
+ +
+
+ + + + + + + + +
void QwtLegend::setMaxColumns (uint numColums)
+
+ +

Set the maximum number of entries in a row.

+

F.e when the maximum is set to 1 all items are aligned vertically. 0 means unlimited

+
Parameters
+ + +
numColumsMaximum number of entries in a row
+
+
+
See Also
maxColumns(), QwtDynGridLayout::setMaxColumns()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void QwtLegend::updateLegend (const QVariant & itemInfo,
const QList< QwtLegendData > & data 
)
+
+virtualslot
+
+ +

Update the entries for an item.

+
Parameters
+ + + +
itemInfoInfo for an item
dataList of legend entry attributes for the item
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void QwtLegend::updateWidget (QWidget * widget,
const QwtLegendDatadata 
)
+
+protectedvirtual
+
+ +

Update the widget.

+
Parameters
+ + + +
widgetUsually a QwtLegendLabel
dataAttributes to be displayed
+
+
+
See Also
createWidget()
+
Note
When widget is no QwtLegendLabel updateWidget() does nothing.
+ +
+
+ +
+
+ + + + + + + +
QScrollBar * QwtLegend::verticalScrollBar () const
+
+
Returns
Vertical scrollbar
+
See Also
horizontalScrollBar()
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_legend__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_legend__inherit__graph.map new file mode 100644 index 0000000000..b066db02e0 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_legend__inherit__graph.map @@ -0,0 +1,3 @@ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_legend__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_legend__inherit__graph.md5 new file mode 100644 index 0000000000..8b43ed0a84 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_legend__inherit__graph.md5 @@ -0,0 +1 @@ +22dd7fb53893298a526933b109c37f34 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_legend__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_legend__inherit__graph.png new file mode 100644 index 0000000000..b5dab98e9b Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_legend__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_legend_data-members.html b/ThirdParty/Qwt/doc/html/class_qwt_legend_data-members.html new file mode 100644 index 0000000000..19c04fe62b --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_legend_data-members.html @@ -0,0 +1,120 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtLegendData Member List
+
+
+ +

This is the complete list of members for QwtLegendData, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + +
Checkable enum valueQwtLegendData
Clickable enum valueQwtLegendData
hasRole(int role) const QwtLegendData
icon() const QwtLegendData
IconRole enum value (defined in QwtLegendData)QwtLegendData
isValid() const QwtLegendData
mode() const QwtLegendData
Mode enum nameQwtLegendData
ModeRole enum value (defined in QwtLegendData)QwtLegendData
QwtLegendData()QwtLegendData
ReadOnly enum valueQwtLegendData
Role enum nameQwtLegendData
setValue(int role, const QVariant &)QwtLegendData
setValues(const QMap< int, QVariant > &)QwtLegendData
title() const QwtLegendData
TitleRole enum value (defined in QwtLegendData)QwtLegendData
UserRole enum value (defined in QwtLegendData)QwtLegendData
value(int role) const QwtLegendData
values() const QwtLegendData
~QwtLegendData()QwtLegendData
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_legend_data.html b/ThirdParty/Qwt/doc/html/class_qwt_legend_data.html new file mode 100644 index 0000000000..444ca54564 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_legend_data.html @@ -0,0 +1,372 @@ + + + + + + +Qwt User's Guide: QwtLegendData Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtLegendData Class Reference
+
+
+ +

Attributes of an entry on a legend. + More...

+ +

#include <qwt_legend_data.h>

+ + + + + + + + +

+Public Types

enum  Mode { ReadOnly, +Clickable, +Checkable + }
 Mode defining how a legend entry interacts. More...
 
enum  Role { ModeRole, +TitleRole, +IconRole, +UserRole = 32 + }
 Identifier how to interprete a QVariant.
 
+ + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

QwtLegendData ()
 Constructor.
 
~QwtLegendData ()
 Destructor.
 
void setValues (const QMap< int, QVariant > &)
 
const QMap< int, QVariant > & values () const
 
void setValue (int role, const QVariant &)
 
QVariant value (int role) const
 
bool hasRole (int role) const
 
bool isValid () const
 
QwtGraphic icon () const
 
QwtText title () const
 
Mode mode () const
 
+

Detailed Description

+

Attributes of an entry on a legend.

+

QwtLegendData is an abstract container ( like QAbstractModel ) to exchange attributes, that are only known between to the plot item and the legend.

+

By overloading QwtPlotItem::legendData() any other set of attributes could be used, that can be handled by a modified ( or completely different ) implementation of a legend.

+
See Also
QwtLegend, QwtPlotLegendItem
+
Note
The stockchart example implements a legend as a tree with checkable items
+

Member Enumeration Documentation

+ +
+
+ + + + +
enum QwtLegendData::Mode
+
+ +

Mode defining how a legend entry interacts.

+ + + + +
Enumerator
ReadOnly  +

The legend item is not interactive, like a label.

+
Clickable  +

The legend item is clickable, like a push button.

+
Checkable  +

The legend item is checkable, like a checkable button.

+
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + + + + +
bool QwtLegendData::hasRole (int role) const
+
+
Parameters
+ + +
roleAttribute role
+
+
+
Returns
True, when the internal map has an entry for role
+ +
+
+ +
+
+ + + + + + + +
QwtGraphic QwtLegendData::icon () const
+
+
Returns
Value of the IconRole attribute
+ +
+
+ +
+
+ + + + + + + +
bool QwtLegendData::isValid () const
+
+
Returns
True, when the internal map is empty
+ +
+
+ +
+
+ + + + + + + +
QwtLegendData::Mode QwtLegendData::mode () const
+
+
Returns
Value of the ModeRole attribute
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtLegendData::setValue (int role,
const QVariant & data 
)
+
+

Set an attribute value

+
Parameters
+ + + +
roleAttribute role
dataAttribute value
+
+
+
See Also
value()
+ +
+
+ +
+
+ + + + + + + + +
void QwtLegendData::setValues (const QMap< int, QVariant > & map)
+
+

Set the legend attributes

+

QwtLegendData actually is a QMap<int, QVariant> with some convenience interfaces

+
Parameters
+ + +
mapValues
+
+
+
See Also
values()
+ +
+
+ +
+
+ + + + + + + +
QwtText QwtLegendData::title () const
+
+
Returns
Value of the TitleRole attribute
+ +
+
+ +
+
+ + + + + + + + +
QVariant QwtLegendData::value (int role) const
+
+
Parameters
+ + +
roleAttribute role
+
+
+
Returns
Attribute value for a specific role
+ +
+
+ +
+
+ + + + + + + +
const QMap< int, QVariant > & QwtLegendData::values () const
+
+
Returns
Legend attributes
+
See Also
setValues()
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_legend_label-members.html b/ThirdParty/Qwt/doc/html/class_qwt_legend_label-members.html new file mode 100644 index 0000000000..2669ca5939 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_legend_label-members.html @@ -0,0 +1,142 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtLegendLabel Member List
+
+
+ +

This is the complete list of members for QwtLegendLabel, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
checked(bool)QwtLegendLabelsignal
clear()QwtTextLabelslot
clicked()QwtLegendLabelsignal
data() const QwtLegendLabel
drawContents(QPainter *)QwtTextLabelprotectedvirtual
drawText(QPainter *, const QRectF &)QwtTextLabelvirtual
heightForWidth(int) const QwtTextLabelvirtual
icon() const QwtLegendLabel
indent() const QwtTextLabel
isChecked() const QwtLegendLabel
isDown() const QwtLegendLabelprotected
itemMode() const QwtLegendLabel
keyPressEvent(QKeyEvent *)QwtLegendLabelprotectedvirtual
keyReleaseEvent(QKeyEvent *)QwtLegendLabelprotectedvirtual
margin() const QwtTextLabel
minimumSizeHint() const QwtTextLabelvirtual
mousePressEvent(QMouseEvent *)QwtLegendLabelprotectedvirtual
mouseReleaseEvent(QMouseEvent *)QwtLegendLabelprotectedvirtual
paintEvent(QPaintEvent *)QwtLegendLabelprotectedvirtual
plainText() const QwtTextLabel
pressed()QwtLegendLabelsignal
QwtLegendLabel(QWidget *parent=0)QwtLegendLabelexplicit
QwtTextLabel(QWidget *parent=NULL)QwtTextLabelexplicit
QwtTextLabel(const QwtText &, QWidget *parent=NULL)QwtTextLabelexplicit
released()QwtLegendLabelsignal
setChecked(bool on)QwtLegendLabelslot
setData(const QwtLegendData &)QwtLegendLabel
setDown(bool)QwtLegendLabelprotected
setIcon(const QPixmap &)QwtLegendLabel
setIndent(int)QwtTextLabel
setItemMode(QwtLegendData::Mode)QwtLegendLabel
setMargin(int)QwtTextLabel
setPlainText(const QString &)QwtTextLabel
setSpacing(int spacing)QwtLegendLabel
setText(const QwtText &)QwtLegendLabelvirtual
QwtTextLabel::setText(const QString &, QwtText::TextFormat textFormat=QwtText::AutoText)QwtTextLabelslot
sizeHint() const QwtLegendLabelvirtual
spacing() const QwtLegendLabel
text() const QwtTextLabel
textRect() const QwtTextLabel
~QwtLegendLabel()QwtLegendLabelvirtual
~QwtTextLabel()QwtTextLabelvirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_legend_label.html b/ThirdParty/Qwt/doc/html/class_qwt_legend_label.html new file mode 100644 index 0000000000..11d0a12fa2 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_legend_label.html @@ -0,0 +1,525 @@ + + + + + + +Qwt User's Guide: QwtLegendLabel Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+ +
+ +

A widget representing something on a QwtLegend. + More...

+ +

#include <qwt_legend_label.h>

+
+Inheritance diagram for QwtLegendLabel:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + + + +

+Public Slots

void setChecked (bool on)
 
- Public Slots inherited from QwtTextLabel
void setText (const QString &, QwtText::TextFormat textFormat=QwtText::AutoText)
 
+void clear ()
 Clear the text and all QwtText attributes.
 
+ + + + + + + + + + + + + +

+Signals

+void clicked ()
 Signal, when the legend item has been clicked.
 
+void pressed ()
 Signal, when the legend item has been pressed.
 
+void released ()
 Signal, when the legend item has been released.
 
+void checked (bool)
 Signal, when the legend item has been toggled.
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 QwtLegendLabel (QWidget *parent=0)
 
+virtual ~QwtLegendLabel ()
 Destructor.
 
void setData (const QwtLegendData &)
 
const QwtLegendDatadata () const
 
void setItemMode (QwtLegendData::Mode)
 
QwtLegendData::Mode itemMode () const
 
void setSpacing (int spacing)
 Change the spacing between icon and text. More...
 
int spacing () const
 
virtual void setText (const QwtText &)
 
void setIcon (const QPixmap &)
 
QPixmap icon () const
 
+virtual QSize sizeHint () const
 Return a size hint.
 
+bool isChecked () const
 Return true, if the item is checked.
 
- Public Member Functions inherited from QwtTextLabel
 QwtTextLabel (QWidget *parent=NULL)
 
 QwtTextLabel (const QwtText &, QWidget *parent=NULL)
 
+virtual ~QwtTextLabel ()
 Destructor.
 
void setPlainText (const QString &)
 
QString plainText () const
 
+const QwtTexttext () const
 Return the text.
 
+int indent () const
 Return label's text indent in pixels.
 
void setIndent (int)
 
+int margin () const
 Return label's text indent in pixels.
 
void setMargin (int)
 
+virtual QSize minimumSizeHint () const
 Return a minimum size hint.
 
virtual int heightForWidth (int) const
 
QRect textRect () const
 
+virtual void drawText (QPainter *, const QRectF &)
 Redraw the text.
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

+Protected Member Functions

+void setDown (bool)
 Set the item being down.
 
+bool isDown () const
 Return true, if the item is down.
 
+virtual void paintEvent (QPaintEvent *)
 Paint event.
 
+virtual void mousePressEvent (QMouseEvent *)
 Handle mouse press events.
 
+virtual void mouseReleaseEvent (QMouseEvent *)
 Handle mouse release events.
 
+virtual void keyPressEvent (QKeyEvent *)
 Handle key press events.
 
+virtual void keyReleaseEvent (QKeyEvent *)
 Handle key release events.
 
- Protected Member Functions inherited from QwtTextLabel
+virtual void drawContents (QPainter *)
 Redraw the text and focus indicator.
 
+

Detailed Description

+

A widget representing something on a QwtLegend.

+

Constructor & Destructor Documentation

+ +
+
+ + + + + +
+ + + + + + + + +
QwtLegendLabel::QwtLegendLabel (QWidget * parent = 0)
+
+explicit
+
+
Parameters
+ + +
parentParent widget
+
+
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + + + +
const QwtLegendData & QwtLegendLabel::data () const
+
+
Returns
Attributes of the label
+
See Also
setData(), QwtPlotItem::legendData()
+ +
+
+ +
+
+ + + + + + + +
QPixmap QwtLegendLabel::icon () const
+
+
Returns
Pixmap representing a plot item
+
See Also
setIcon()
+ +
+
+ +
+
+ + + + + + + +
QwtLegendData::Mode QwtLegendLabel::itemMode () const
+
+
Returns
Item mode
+
See Also
setItemMode()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtLegendLabel::setChecked (bool on)
+
+slot
+
+

Check/Uncheck a the item

+
Parameters
+ + +
oncheck/uncheck
+
+
+
See Also
setItemMode()
+ +
+
+ +
+
+ + + + + + + + +
void QwtLegendLabel::setData (const QwtLegendDatalegendData)
+
+

Set the attributes of the legend label

+
Parameters
+ + +
legendDataAttributes of the label
+
+
+
See Also
data()
+ +
+
+ +
+
+ + + + + + + + +
void QwtLegendLabel::setIcon (const QPixmap & icon)
+
+

Assign the icon

+
Parameters
+ + +
iconPixmap representing a plot item
+
+
+
See Also
icon(), QwtPlotItem::legendIcon()
+ +
+
+ +
+
+ + + + + + + + +
void QwtLegendLabel::setItemMode (QwtLegendData::Mode mode)
+
+

Set the item mode The default is QwtLegendData::ReadOnly

+
Parameters
+ + +
modeItem mode
+
+
+
See Also
itemMode()
+ +
+
+ +
+
+ + + + + + + + +
void QwtLegendLabel::setSpacing (int spacing)
+
+ +

Change the spacing between icon and text.

+
Parameters
+ + +
spacingSpacing
+
+
+
See Also
spacing(), QwtTextLabel::margin()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtLegendLabel::setText (const QwtTexttext)
+
+virtual
+
+

Set the text to the legend item

+
Parameters
+ + +
textText label
+
+
+
See Also
QwtTextLabel::text()
+ +

Reimplemented from QwtTextLabel.

+ +
+
+ +
+
+ + + + + + + +
int QwtLegendLabel::spacing () const
+
+
Returns
Spacing between icon and text
+
See Also
setSpacing(), QwtTextLabel::margin()
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_legend_label__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_legend_label__inherit__graph.map new file mode 100644 index 0000000000..dd49fdb052 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_legend_label__inherit__graph.map @@ -0,0 +1,3 @@ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_legend_label__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_legend_label__inherit__graph.md5 new file mode 100644 index 0000000000..1dd8036f22 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_legend_label__inherit__graph.md5 @@ -0,0 +1 @@ +46265e20154efad56c1227e2dd6fa6e2 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_legend_label__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_legend_label__inherit__graph.png new file mode 100644 index 0000000000..a9e743b9e2 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_legend_label__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_linear_color_map-members.html b/ThirdParty/Qwt/doc/html/class_qwt_linear_color_map-members.html new file mode 100644 index 0000000000..a52d9e1932 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_linear_color_map-members.html @@ -0,0 +1,123 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtLinearColorMap Member List
+
+
+ +

This is the complete list of members for QwtLinearColorMap, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + +
addColorStop(double value, const QColor &)QwtLinearColorMap
color(const QwtInterval &, double value) const QwtColorMapinline
color1() const QwtLinearColorMap
color2() const QwtLinearColorMap
colorIndex(const QwtInterval &, double value) const QwtLinearColorMapvirtual
colorStops() const QwtLinearColorMap
colorTable(const QwtInterval &) const QwtColorMapvirtual
FixedColors enum valueQwtLinearColorMap
Format enum nameQwtColorMap
format() const QwtColorMapinline
Indexed enum valueQwtColorMap
mode() const QwtLinearColorMap
Mode enum nameQwtLinearColorMap
QwtColorMap(Format=QwtColorMap::RGB)QwtColorMap
QwtLinearColorMap(QwtColorMap::Format=QwtColorMap::RGB)QwtLinearColorMap
QwtLinearColorMap(const QColor &from, const QColor &to, QwtColorMap::Format=QwtColorMap::RGB)QwtLinearColorMap
RGB enum valueQwtColorMap
rgb(const QwtInterval &, double value) const QwtLinearColorMapvirtual
ScaledColors enum valueQwtLinearColorMap
setColorInterval(const QColor &color1, const QColor &color2)QwtLinearColorMap
setMode(Mode)QwtLinearColorMap
~QwtColorMap()QwtColorMapvirtual
~QwtLinearColorMap()QwtLinearColorMapvirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_linear_color_map.html b/ThirdParty/Qwt/doc/html/class_qwt_linear_color_map.html new file mode 100644 index 0000000000..ec068b415e --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_linear_color_map.html @@ -0,0 +1,513 @@ + + + + + + +Qwt User's Guide: QwtLinearColorMap Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtLinearColorMap Class Reference
+
+
+ +

QwtLinearColorMap builds a color map from color stops. + More...

+ +

#include <qwt_color_map.h>

+
+Inheritance diagram for QwtLinearColorMap:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + +

+Public Types

enum  Mode { FixedColors, +ScaledColors + }
 
- Public Types inherited from QwtColorMap
enum  Format { RGB, +Indexed + }
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 QwtLinearColorMap (QwtColorMap::Format=QwtColorMap::RGB)
 
 QwtLinearColorMap (const QColor &from, const QColor &to, QwtColorMap::Format=QwtColorMap::RGB)
 
+virtual ~QwtLinearColorMap ()
 Destructor.
 
void setMode (Mode)
 Set the mode of the color map. More...
 
Mode mode () const
 
void setColorInterval (const QColor &color1, const QColor &color2)
 
void addColorStop (double value, const QColor &)
 
QVector< double > colorStops () const
 
QColor color1 () const
 
QColor color2 () const
 
virtual QRgb rgb (const QwtInterval &, double value) const
 
virtual unsigned char colorIndex (const QwtInterval &, double value) const
 Map a value of a given interval into a color index. More...
 
- Public Member Functions inherited from QwtColorMap
QwtColorMap (Format=QwtColorMap::RGB)
 Constructor.
 
+virtual ~QwtColorMap ()
 Destructor.
 
Format format () const
 
QColor color (const QwtInterval &, double value) const
 
virtual QVector< QRgb > colorTable (const QwtInterval &) const
 
+

Detailed Description

+

QwtLinearColorMap builds a color map from color stops.

+

A color stop is a color at a specific position. The valid range for the positions is [0.0, 1.0]. When mapping a value into a color it is translated into this interval according to mode().

+

Member Enumeration Documentation

+ +
+
+ + + + +
enum QwtLinearColorMap::Mode
+
+

Mode of color map

+
See Also
setMode(), mode()
+ + + +
Enumerator
FixedColors  +

Return the color from the next lower color stop.

+
ScaledColors  +

Interpolating the colors of the adjacent stops.

+
+ +
+
+

Constructor & Destructor Documentation

+ +
+
+ + + + + + + + +
QwtLinearColorMap::QwtLinearColorMap (QwtColorMap::Format format = QwtColorMap::RGB)
+
+

Build a color map with two stops at 0.0 and 1.0. The color at 0.0 is Qt::blue, at 1.0 it is Qt::yellow.

+
Parameters
+ + +
formatPreferred format of the color map
+
+
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
QwtLinearColorMap::QwtLinearColorMap (const QColor & color1,
const QColor & color2,
QwtColorMap::Format format = QwtColorMap::RGB 
)
+
+

Build a color map with two stops at 0.0 and 1.0.

+
Parameters
+ + + + +
color1Color used for the minimum value of the value interval
color2Color used for the maximum value of the value interval
formatPreferred format for the color map
+
+
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtLinearColorMap::addColorStop (double value,
const QColor & color 
)
+
+

Add a color stop

+

The value has to be in the range [0.0, 1.0]. F.e. a stop at position 17.0 for a range [10.0,20.0] must be passed as: (17.0 - 10.0) / (20.0 - 10.0)

+
Parameters
+ + + +
valueValue between [0.0, 1.0]
colorColor stop
+
+
+ +
+
+ +
+
+ + + + + + + +
QColor QwtLinearColorMap::color1 () const
+
+
Returns
the first color of the color range
+
See Also
setColorInterval()
+ +
+
+ +
+
+ + + + + + + +
QColor QwtLinearColorMap::color2 () const
+
+
Returns
the second color of the color range
+
See Also
setColorInterval()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
unsigned char QwtLinearColorMap::colorIndex (const QwtIntervalinterval,
double value 
) const
+
+virtual
+
+ +

Map a value of a given interval into a color index.

+
Parameters
+ + + +
intervalRange for all values
valueValue to map into a color index
+
+
+
Returns
Index, between 0 and 255
+ +

Implements QwtColorMap.

+ +
+
+ +
+
+ + + + + + + +
QVector< double > QwtLinearColorMap::colorStops () const
+
+
Returns
Positions of color stops in increasing order
+ +
+
+ +
+
+ + + + + + + +
QwtLinearColorMap::Mode QwtLinearColorMap::mode () const
+
+
Returns
Mode of the color map
+
See Also
setMode()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
QRgb QwtLinearColorMap::rgb (const QwtIntervalinterval,
double value 
) const
+
+virtual
+
+

Map a value of a given interval into a RGB value

+
Parameters
+ + + +
intervalRange for all values
valueValue to map into a RGB value
+
+
+
Returns
RGB value for value
+ +

Implements QwtColorMap.

+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtLinearColorMap::setColorInterval (const QColor & color1,
const QColor & color2 
)
+
+

Set the color range

+

Add stops at 0.0 and 1.0.

+
Parameters
+ + + +
color1Color used for the minimum value of the value interval
color2Color used for the maximum value of the value interval
+
+
+
See Also
color1(), color2()
+ +
+
+ +
+
+ + + + + + + + +
void QwtLinearColorMap::setMode (Mode mode)
+
+ +

Set the mode of the color map.

+

FixedColors means the color is calculated from the next lower color stop. ScaledColors means the color is calculated by interpolating the colors of the adjacent stops.

+
See Also
mode()
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_linear_color_map__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_linear_color_map__inherit__graph.map new file mode 100644 index 0000000000..070da4ca0b --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_linear_color_map__inherit__graph.map @@ -0,0 +1,3 @@ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_linear_color_map__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_linear_color_map__inherit__graph.md5 new file mode 100644 index 0000000000..a4bec050bc --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_linear_color_map__inherit__graph.md5 @@ -0,0 +1 @@ +654b78fe9fc7cf5ef338653cfb7deb11 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_linear_color_map__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_linear_color_map__inherit__graph.png new file mode 100644 index 0000000000..3ffae812ea Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_linear_color_map__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_linear_scale_engine-members.html b/ThirdParty/Qwt/doc/html/class_qwt_linear_scale_engine-members.html new file mode 100644 index 0000000000..70182396e7 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_linear_scale_engine-members.html @@ -0,0 +1,134 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtLinearScaleEngine Member List
+
+
+ +

This is the complete list of members for QwtLinearScaleEngine, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
align(const QwtInterval &, double stepSize) const QwtLinearScaleEngineprotected
Attribute enum nameQwtScaleEngine
Attributes typedefQwtScaleEngine
attributes() const QwtScaleEngine
autoScale(int maxSteps, double &x1, double &x2, double &stepSize) const QwtLinearScaleEnginevirtual
base() const QwtScaleEngine
buildInterval(double v) const QwtScaleEngineprotected
buildMajorTicks(const QwtInterval &interval, double stepSize) const QwtLinearScaleEngineprotected
buildMinorTicks(const QList< double > &majorTicks, int maxMinorSteps, double stepSize, QList< double > &minorTicks, QList< double > &mediumTicks) const QwtLinearScaleEngineprotected
buildTicks(const QwtInterval &, double stepSize, int maxMinSteps, QList< double > ticks[QwtScaleDiv::NTickTypes]) const QwtLinearScaleEngineprotected
contains(const QwtInterval &, double val) const QwtScaleEngineprotected
divideInterval(double interval, int numSteps) const QwtScaleEngineprotected
divideScale(double x1, double x2, int numMajorSteps, int numMinorSteps, double stepSize=0.0) const QwtLinearScaleEnginevirtual
Floating enum valueQwtScaleEngine
IncludeReference enum valueQwtScaleEngine
Inverted enum valueQwtScaleEngine
lowerMargin() const QwtScaleEngine
NoAttribute enum valueQwtScaleEngine
QwtLinearScaleEngine(uint base=10)QwtLinearScaleEngine
QwtScaleEngine(uint base=10)QwtScaleEngineexplicit
reference() const QwtScaleEngine
setAttribute(Attribute, bool on=true)QwtScaleEngine
setAttributes(Attributes)QwtScaleEngine
setBase(uint base)QwtScaleEngine
setMargins(double lower, double upper)QwtScaleEngine
setReference(double reference)QwtScaleEngine
setTransformation(QwtTransform *)QwtScaleEngine
strip(const QList< double > &, const QwtInterval &) const QwtScaleEngineprotected
Symmetric enum valueQwtScaleEngine
testAttribute(Attribute) const QwtScaleEngine
transformation() const QwtScaleEngine
upperMargin() const QwtScaleEngine
~QwtLinearScaleEngine()QwtLinearScaleEnginevirtual
~QwtScaleEngine()QwtScaleEnginevirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_linear_scale_engine.html b/ThirdParty/Qwt/doc/html/class_qwt_linear_scale_engine.html new file mode 100644 index 0000000000..5edd7458ed --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_linear_scale_engine.html @@ -0,0 +1,576 @@ + + + + + + +Qwt User's Guide: QwtLinearScaleEngine Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtLinearScaleEngine Class Reference
+
+
+ +

A scale engine for linear scales. + More...

+ +

#include <qwt_scale_engine.h>

+
+Inheritance diagram for QwtLinearScaleEngine:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 QwtLinearScaleEngine (uint base=10)
 
+virtual ~QwtLinearScaleEngine ()
 Destructor.
 
virtual void autoScale (int maxSteps, double &x1, double &x2, double &stepSize) const
 
virtual QwtScaleDiv divideScale (double x1, double x2, int numMajorSteps, int numMinorSteps, double stepSize=0.0) const
 Calculate a scale division for an interval. More...
 
- Public Member Functions inherited from QwtScaleEngine
 QwtScaleEngine (uint base=10)
 
+virtual ~QwtScaleEngine ()
 Destructor.
 
void setBase (uint base)
 
uint base () const
 
void setAttribute (Attribute, bool on=true)
 
bool testAttribute (Attribute) const
 
void setAttributes (Attributes)
 
Attributes attributes () const
 
void setReference (double reference)
 Specify a reference point. More...
 
double reference () const
 
void setMargins (double lower, double upper)
 Specify margins at the scale's endpoints. More...
 
double lowerMargin () const
 
double upperMargin () const
 
void setTransformation (QwtTransform *)
 
QwtTransformtransformation () const
 
+ + + + + + + + + + + + + + + + + + + + + + + +

+Protected Member Functions

QwtInterval align (const QwtInterval &, double stepSize) const
 Align an interval to a step size. More...
 
void buildTicks (const QwtInterval &, double stepSize, int maxMinSteps, QList< double > ticks[QwtScaleDiv::NTickTypes]) const
 Calculate ticks for an interval. More...
 
QList< double > buildMajorTicks (const QwtInterval &interval, double stepSize) const
 Calculate major ticks for an interval. More...
 
void buildMinorTicks (const QList< double > &majorTicks, int maxMinorSteps, double stepSize, QList< double > &minorTicks, QList< double > &mediumTicks) const
 Calculate minor/medium ticks for major ticks. More...
 
- Protected Member Functions inherited from QwtScaleEngine
bool contains (const QwtInterval &, double val) const
 
QList< double > strip (const QList< double > &, const QwtInterval &) const
 
double divideInterval (double interval, int numSteps) const
 
QwtInterval buildInterval (double v) const
 Build an interval around a value. More...
 
+ + + + + + + +

+Additional Inherited Members

- Public Types inherited from QwtScaleEngine
enum  Attribute {
+  NoAttribute = 0x00, +IncludeReference = 0x01, +Symmetric = 0x02, +Floating = 0x04, +
+  Inverted = 0x08 +
+ }
 
+typedef QFlags< AttributeAttributes
 Layout attributes.
 
+

Detailed Description

+

A scale engine for linear scales.

+

The step size will fit into the pattern $\left\{ 1,2,5\right\} \cdot 10^{n}$, where n is an integer.

+

Constructor & Destructor Documentation

+ +
+
+ + + + + + + + +
QwtLinearScaleEngine::QwtLinearScaleEngine (uint base = 10)
+
+

Constructor

+
Parameters
+ + +
baseBase of the scale engine
+
+
+
See Also
setBase()
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
QwtInterval QwtLinearScaleEngine::align (const QwtIntervalinterval,
double stepSize 
) const
+
+protected
+
+ +

Align an interval to a step size.

+

The limits of an interval are aligned that both are integer multiples of the step size.

+
Parameters
+ + + +
intervalInterval
stepSizeStep size
+
+
+
Returns
Aligned interval
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void QwtLinearScaleEngine::autoScale (int maxNumSteps,
double & x1,
double & x2,
double & stepSize 
) const
+
+virtual
+
+

Align and divide an interval

+
Parameters
+ + + + + +
maxNumStepsMax. number of steps
x1First limit of the interval (In/Out)
x2Second limit of the interval (In/Out)
stepSizeStep size (Out)
+
+
+
See Also
setAttribute()
+ +

Implements QwtScaleEngine.

+ +

Reimplemented in QwtDateScaleEngine.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
QList< double > QwtLinearScaleEngine::buildMajorTicks (const QwtIntervalinterval,
double stepSize 
) const
+
+protected
+
+ +

Calculate major ticks for an interval.

+
Parameters
+ + + +
intervalInterval
stepSizeStep size
+
+
+
Returns
Calculated ticks
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void QwtLinearScaleEngine::buildMinorTicks (const QList< double > & majorTicks,
int maxMinorSteps,
double stepSize,
QList< double > & minorTicks,
QList< double > & mediumTicks 
) const
+
+protected
+
+ +

Calculate minor/medium ticks for major ticks.

+
Parameters
+ + + + + + +
majorTicksMajor ticks
maxMinorStepsMaximum number of minor steps
stepSizeStep size
minorTicksArray to be filled with the calculated minor ticks
mediumTicksArray to be filled with the calculated medium ticks
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void QwtLinearScaleEngine::buildTicks (const QwtIntervalinterval,
double stepSize,
int maxMinorSteps,
QList< double > ticks[QwtScaleDiv::NTickTypes] 
) const
+
+protected
+
+ +

Calculate ticks for an interval.

+
Parameters
+ + + + + +
intervalInterval
stepSizeStep size
maxMinorStepsMaximum number of minor steps
ticksArrays to be filled with the calculated ticks
+
+
+
See Also
buildMajorTicks(), buildMinorTicks
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
QwtScaleDiv QwtLinearScaleEngine::divideScale (double x1,
double x2,
int maxMajorSteps,
int maxMinorSteps,
double stepSize = 0.0 
) const
+
+virtual
+
+ +

Calculate a scale division for an interval.

+
Parameters
+ + + + + + +
x1First interval limit
x2Second interval limit
maxMajorStepsMaximum for the number of major steps
maxMinorStepsMaximum number of minor steps
stepSizeStep size. If stepSize == 0, the engine calculates one.
+
+
+
Returns
Calculated scale division
+ +

Implements QwtScaleEngine.

+ +

Reimplemented in QwtDateScaleEngine.

+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_linear_scale_engine__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_linear_scale_engine__inherit__graph.map new file mode 100644 index 0000000000..c3a2c16c6d --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_linear_scale_engine__inherit__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_linear_scale_engine__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_linear_scale_engine__inherit__graph.md5 new file mode 100644 index 0000000000..fbcaa2944e --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_linear_scale_engine__inherit__graph.md5 @@ -0,0 +1 @@ +c486f45141912b9bd7ddf5bf6d7d8f96 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_linear_scale_engine__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_linear_scale_engine__inherit__graph.png new file mode 100644 index 0000000000..927b919bc4 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_linear_scale_engine__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_log_scale_engine-members.html b/ThirdParty/Qwt/doc/html/class_qwt_log_scale_engine-members.html new file mode 100644 index 0000000000..200a2be740 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_log_scale_engine-members.html @@ -0,0 +1,134 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtLogScaleEngine Member List
+
+
+ +

This is the complete list of members for QwtLogScaleEngine, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
align(const QwtInterval &, double stepSize) const QwtLogScaleEngineprotected
Attribute enum nameQwtScaleEngine
Attributes typedefQwtScaleEngine
attributes() const QwtScaleEngine
autoScale(int maxSteps, double &x1, double &x2, double &stepSize) const QwtLogScaleEnginevirtual
base() const QwtScaleEngine
buildInterval(double v) const QwtScaleEngineprotected
buildMajorTicks(const QwtInterval &interval, double stepSize) const QwtLogScaleEngineprotected
buildMinorTicks(const QList< double > &majorTicks, int maxMinorSteps, double stepSize, QList< double > &minorTicks, QList< double > &mediumTicks) const QwtLogScaleEngineprotected
buildTicks(const QwtInterval &, double stepSize, int maxMinSteps, QList< double > ticks[QwtScaleDiv::NTickTypes]) const QwtLogScaleEngineprotected
contains(const QwtInterval &, double val) const QwtScaleEngineprotected
divideInterval(double interval, int numSteps) const QwtScaleEngineprotected
divideScale(double x1, double x2, int numMajorSteps, int numMinorSteps, double stepSize=0.0) const QwtLogScaleEnginevirtual
Floating enum valueQwtScaleEngine
IncludeReference enum valueQwtScaleEngine
Inverted enum valueQwtScaleEngine
lowerMargin() const QwtScaleEngine
NoAttribute enum valueQwtScaleEngine
QwtLogScaleEngine(uint base=10)QwtLogScaleEngine
QwtScaleEngine(uint base=10)QwtScaleEngineexplicit
reference() const QwtScaleEngine
setAttribute(Attribute, bool on=true)QwtScaleEngine
setAttributes(Attributes)QwtScaleEngine
setBase(uint base)QwtScaleEngine
setMargins(double lower, double upper)QwtScaleEngine
setReference(double reference)QwtScaleEngine
setTransformation(QwtTransform *)QwtScaleEngine
strip(const QList< double > &, const QwtInterval &) const QwtScaleEngineprotected
Symmetric enum valueQwtScaleEngine
testAttribute(Attribute) const QwtScaleEngine
transformation() const QwtScaleEngine
upperMargin() const QwtScaleEngine
~QwtLogScaleEngine()QwtLogScaleEnginevirtual
~QwtScaleEngine()QwtScaleEnginevirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_log_scale_engine.html b/ThirdParty/Qwt/doc/html/class_qwt_log_scale_engine.html new file mode 100644 index 0000000000..7a196edec7 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_log_scale_engine.html @@ -0,0 +1,573 @@ + + + + + + +Qwt User's Guide: QwtLogScaleEngine Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtLogScaleEngine Class Reference
+
+
+ +

A scale engine for logarithmic scales. + More...

+ +

#include <qwt_scale_engine.h>

+
+Inheritance diagram for QwtLogScaleEngine:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 QwtLogScaleEngine (uint base=10)
 
+virtual ~QwtLogScaleEngine ()
 Destructor.
 
virtual void autoScale (int maxSteps, double &x1, double &x2, double &stepSize) const
 
virtual QwtScaleDiv divideScale (double x1, double x2, int numMajorSteps, int numMinorSteps, double stepSize=0.0) const
 Calculate a scale division for an interval. More...
 
- Public Member Functions inherited from QwtScaleEngine
 QwtScaleEngine (uint base=10)
 
+virtual ~QwtScaleEngine ()
 Destructor.
 
void setBase (uint base)
 
uint base () const
 
void setAttribute (Attribute, bool on=true)
 
bool testAttribute (Attribute) const
 
void setAttributes (Attributes)
 
Attributes attributes () const
 
void setReference (double reference)
 Specify a reference point. More...
 
double reference () const
 
void setMargins (double lower, double upper)
 Specify margins at the scale's endpoints. More...
 
double lowerMargin () const
 
double upperMargin () const
 
void setTransformation (QwtTransform *)
 
QwtTransformtransformation () const
 
+ + + + + + + + + + + + + + + + + + + + + + + +

+Protected Member Functions

QwtInterval align (const QwtInterval &, double stepSize) const
 Align an interval to a step size. More...
 
void buildTicks (const QwtInterval &, double stepSize, int maxMinSteps, QList< double > ticks[QwtScaleDiv::NTickTypes]) const
 Calculate ticks for an interval. More...
 
QList< double > buildMajorTicks (const QwtInterval &interval, double stepSize) const
 Calculate major ticks for an interval. More...
 
void buildMinorTicks (const QList< double > &majorTicks, int maxMinorSteps, double stepSize, QList< double > &minorTicks, QList< double > &mediumTicks) const
 Calculate minor/medium ticks for major ticks. More...
 
- Protected Member Functions inherited from QwtScaleEngine
bool contains (const QwtInterval &, double val) const
 
QList< double > strip (const QList< double > &, const QwtInterval &) const
 
double divideInterval (double interval, int numSteps) const
 
QwtInterval buildInterval (double v) const
 Build an interval around a value. More...
 
+ + + + + + + +

+Additional Inherited Members

- Public Types inherited from QwtScaleEngine
enum  Attribute {
+  NoAttribute = 0x00, +IncludeReference = 0x01, +Symmetric = 0x02, +Floating = 0x04, +
+  Inverted = 0x08 +
+ }
 
+typedef QFlags< AttributeAttributes
 Layout attributes.
 
+

Detailed Description

+

A scale engine for logarithmic scales.

+

The step size is measured in decades and the major step size will be adjusted to fit the pattern $\left\{ 1,2,3,5\right\} \cdot 10^{n}$, where n is a natural number including zero.

+
Warning
the step size as well as the margins are measured in decades.
+

Constructor & Destructor Documentation

+ +
+
+ + + + + + + + +
QwtLogScaleEngine::QwtLogScaleEngine (uint base = 10)
+
+

Constructor

+
Parameters
+ + +
baseBase of the scale engine
+
+
+
See Also
setBase()
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
QwtInterval QwtLogScaleEngine::align (const QwtIntervalinterval,
double stepSize 
) const
+
+protected
+
+ +

Align an interval to a step size.

+

The limits of an interval are aligned that both are integer multiples of the step size.

+
Parameters
+ + + +
intervalInterval
stepSizeStep size
+
+
+
Returns
Aligned interval
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void QwtLogScaleEngine::autoScale (int maxNumSteps,
double & x1,
double & x2,
double & stepSize 
) const
+
+virtual
+
+

Align and divide an interval

+
Parameters
+ + + + + +
maxNumStepsMax. number of steps
x1First limit of the interval (In/Out)
x2Second limit of the interval (In/Out)
stepSizeStep size (Out)
+
+
+
See Also
QwtScaleEngine::setAttribute()
+ +

Implements QwtScaleEngine.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
QList< double > QwtLogScaleEngine::buildMajorTicks (const QwtIntervalinterval,
double stepSize 
) const
+
+protected
+
+ +

Calculate major ticks for an interval.

+
Parameters
+ + + +
intervalInterval
stepSizeStep size
+
+
+
Returns
Calculated ticks
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void QwtLogScaleEngine::buildMinorTicks (const QList< double > & majorTicks,
int maxMinorSteps,
double stepSize,
QList< double > & minorTicks,
QList< double > & mediumTicks 
) const
+
+protected
+
+ +

Calculate minor/medium ticks for major ticks.

+
Parameters
+ + + + + + +
majorTicksMajor ticks
maxMinorStepsMaximum number of minor steps
stepSizeStep size
minorTicksArray to be filled with the calculated minor ticks
mediumTicksArray to be filled with the calculated medium ticks
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void QwtLogScaleEngine::buildTicks (const QwtIntervalinterval,
double stepSize,
int maxMinorSteps,
QList< double > ticks[QwtScaleDiv::NTickTypes] 
) const
+
+protected
+
+ +

Calculate ticks for an interval.

+
Parameters
+ + + + + +
intervalInterval
maxMinorStepsMaximum number of minor steps
stepSizeStep size
ticksArrays to be filled with the calculated ticks
+
+
+
See Also
buildMajorTicks(), buildMinorTicks
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
QwtScaleDiv QwtLogScaleEngine::divideScale (double x1,
double x2,
int maxMajorSteps,
int maxMinorSteps,
double stepSize = 0.0 
) const
+
+virtual
+
+ +

Calculate a scale division for an interval.

+
Parameters
+ + + + + + +
x1First interval limit
x2Second interval limit
maxMajorStepsMaximum for the number of major steps
maxMinorStepsMaximum number of minor steps
stepSizeStep size. If stepSize == 0, the engine calculates one.
+
+
+
Returns
Calculated scale division
+ +

Implements QwtScaleEngine.

+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_log_scale_engine__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_log_scale_engine__inherit__graph.map new file mode 100644 index 0000000000..1cc81bf7fd --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_log_scale_engine__inherit__graph.map @@ -0,0 +1,3 @@ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_log_scale_engine__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_log_scale_engine__inherit__graph.md5 new file mode 100644 index 0000000000..3db8a4c953 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_log_scale_engine__inherit__graph.md5 @@ -0,0 +1 @@ +586947a17192d6a66f9920b9e07e9515 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_log_scale_engine__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_log_scale_engine__inherit__graph.png new file mode 100644 index 0000000000..625e5338b3 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_log_scale_engine__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_log_transform-members.html b/ThirdParty/Qwt/doc/html/class_qwt_log_transform-members.html new file mode 100644 index 0000000000..b6440c580f --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_log_transform-members.html @@ -0,0 +1,110 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtLogTransform Member List
+
+
+ +

This is the complete list of members for QwtLogTransform, including all inherited members.

+ + + + + + + + + + + +
bounded(double value) const QwtLogTransformvirtual
copy() const QwtLogTransformvirtual
invTransform(double value) const QwtLogTransformvirtual
LogMaxQwtLogTransform
LogMinQwtLogTransform
QwtLogTransform()QwtLogTransform
QwtTransform()QwtTransform
transform(double value) const QwtLogTransformvirtual
~QwtLogTransform()QwtLogTransformvirtual
~QwtTransform()QwtTransformvirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_log_transform.html b/ThirdParty/Qwt/doc/html/class_qwt_log_transform.html new file mode 100644 index 0000000000..91de2517f2 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_log_transform.html @@ -0,0 +1,283 @@ + + + + + + +Qwt User's Guide: QwtLogTransform Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtLogTransform Class Reference
+
+
+ +

Logarithmic transformation. + More...

+ +

#include <qwt_transform.h>

+
+Inheritance diagram for QwtLogTransform:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

QwtLogTransform ()
 Constructor.
 
+virtual ~QwtLogTransform ()
 Destructor.
 
virtual double transform (double value) const
 
virtual double invTransform (double value) const
 
virtual double bounded (double value) const
 
virtual QwtTransformcopy () const
 
- Public Member Functions inherited from QwtTransform
QwtTransform ()
 Constructor.
 
+virtual ~QwtTransform ()
 Destructor.
 
+ + + + + + + +

+Public Attributes

+QT_STATIC_CONST double LogMin = 1.0e-150
 Smallest allowed value for logarithmic scales: 1.0e-150.
 
+QT_STATIC_CONST double LogMax = 1.0e150
 Largest allowed value for logarithmic scales: 1.0e150.
 
+

Detailed Description

+

Logarithmic transformation.

+

QwtLogTransform modifies the values using log() and exp().

+
Note
In the calculations of QwtScaleMap the base of the log function has no effect on the mapping. So QwtLogTransform can be used for log2(), log10() or any other logarithmic scale.
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + + +
double QwtLogTransform::bounded (double value) const
+
+virtual
+
+
Parameters
+ + +
valueValue to be bounded
+
+
+
Returns
qBound( LogMin, value, LogMax )
+ +

Reimplemented from QwtTransform.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
QwtTransform * QwtLogTransform::copy () const
+
+virtual
+
+
Returns
Clone of the transformation
+ +

Implements QwtTransform.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
double QwtLogTransform::invTransform (double value) const
+
+virtual
+
+
Parameters
+ + +
valueValue to be transformed
+
+
+
Returns
exp( value )
+ +

Implements QwtTransform.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
double QwtLogTransform::transform (double value) const
+
+virtual
+
+
Parameters
+ + +
valueValue to be transformed
+
+
+
Returns
log( value )
+ +

Implements QwtTransform.

+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_log_transform__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_log_transform__inherit__graph.map new file mode 100644 index 0000000000..52e0c825f1 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_log_transform__inherit__graph.map @@ -0,0 +1,3 @@ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_log_transform__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_log_transform__inherit__graph.md5 new file mode 100644 index 0000000000..6412dde877 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_log_transform__inherit__graph.md5 @@ -0,0 +1 @@ +5ff333438bf433ed76aed4523aed899b \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_log_transform__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_log_transform__inherit__graph.png new file mode 100644 index 0000000000..a7e83772dc Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_log_transform__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_magnifier-members.html b/ThirdParty/Qwt/doc/html/class_qwt_magnifier-members.html new file mode 100644 index 0000000000..a04e2d7d20 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_magnifier-members.html @@ -0,0 +1,128 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtMagnifier Member List
+
+
+ +

This is the complete list of members for QwtMagnifier, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
eventFilter(QObject *, QEvent *)QwtMagnifiervirtual
getMouseButton(Qt::MouseButton &, Qt::KeyboardModifiers &) const QwtMagnifier
getZoomInKey(int &key, Qt::KeyboardModifiers &) const QwtMagnifier
getZoomOutKey(int &key, Qt::KeyboardModifiers &) const QwtMagnifier
isEnabled() const QwtMagnifier
keyFactor() const QwtMagnifier
mouseFactor() const QwtMagnifier
parentWidget()QwtMagnifier
parentWidget() const QwtMagnifier
QwtMagnifier(QWidget *)QwtMagnifierexplicit
rescale(double factor)=0QwtMagnifierprotectedpure virtual
setEnabled(bool)QwtMagnifier
setKeyFactor(double)QwtMagnifier
setMouseButton(Qt::MouseButton, Qt::KeyboardModifiers=Qt::NoModifier)QwtMagnifier
setMouseFactor(double)QwtMagnifier
setWheelFactor(double)QwtMagnifier
setWheelModifiers(Qt::KeyboardModifiers)QwtMagnifier
setZoomInKey(int key, Qt::KeyboardModifiers=Qt::NoModifier)QwtMagnifier
setZoomOutKey(int key, Qt::KeyboardModifiers=Qt::NoModifier)QwtMagnifier
wheelFactor() const QwtMagnifier
wheelModifiers() const QwtMagnifier
widgetKeyPressEvent(QKeyEvent *)QwtMagnifierprotectedvirtual
widgetKeyReleaseEvent(QKeyEvent *)QwtMagnifierprotectedvirtual
widgetMouseMoveEvent(QMouseEvent *)QwtMagnifierprotectedvirtual
widgetMousePressEvent(QMouseEvent *)QwtMagnifierprotectedvirtual
widgetMouseReleaseEvent(QMouseEvent *)QwtMagnifierprotectedvirtual
widgetWheelEvent(QWheelEvent *)QwtMagnifierprotectedvirtual
~QwtMagnifier()QwtMagnifiervirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_magnifier.html b/ThirdParty/Qwt/doc/html/class_qwt_magnifier.html new file mode 100644 index 0000000000..0ef51e32d9 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_magnifier.html @@ -0,0 +1,943 @@ + + + + + + +Qwt User's Guide: QwtMagnifier Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtMagnifier Class Referenceabstract
+
+
+ +

QwtMagnifier provides zooming, by magnifying in steps. + More...

+ +

#include <qwt_magnifier.h>

+
+Inheritance diagram for QwtMagnifier:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 QwtMagnifier (QWidget *)
 
+virtual ~QwtMagnifier ()
 Destructor.
 
QWidget * parentWidget ()
 
const QWidget * parentWidget () const
 
void setEnabled (bool)
 En/disable the magnifier. More...
 
bool isEnabled () const
 
void setMouseFactor (double)
 Change the mouse factor. More...
 
double mouseFactor () const
 
void setMouseButton (Qt::MouseButton, Qt::KeyboardModifiers=Qt::NoModifier)
 
void getMouseButton (Qt::MouseButton &, Qt::KeyboardModifiers &) const
 
void setWheelFactor (double)
 Change the wheel factor. More...
 
double wheelFactor () const
 
void setWheelModifiers (Qt::KeyboardModifiers)
 
Qt::KeyboardModifiers wheelModifiers () const
 
void setKeyFactor (double)
 Change the key factor. More...
 
double keyFactor () const
 
void setZoomInKey (int key, Qt::KeyboardModifiers=Qt::NoModifier)
 
void getZoomInKey (int &key, Qt::KeyboardModifiers &) const
 Retrieve the settings of the zoom in key. More...
 
void setZoomOutKey (int key, Qt::KeyboardModifiers=Qt::NoModifier)
 
void getZoomOutKey (int &key, Qt::KeyboardModifiers &) const
 Retrieve the settings of the zoom out key. More...
 
virtual bool eventFilter (QObject *, QEvent *)
 Event filter. More...
 
+ + + + + + + + + + + + + + + +

+Protected Member Functions

virtual void rescale (double factor)=0
 
virtual void widgetMousePressEvent (QMouseEvent *)
 
virtual void widgetMouseReleaseEvent (QMouseEvent *)
 
virtual void widgetMouseMoveEvent (QMouseEvent *)
 
virtual void widgetWheelEvent (QWheelEvent *)
 
virtual void widgetKeyPressEvent (QKeyEvent *)
 
virtual void widgetKeyReleaseEvent (QKeyEvent *)
 
+

Detailed Description

+

QwtMagnifier provides zooming, by magnifying in steps.

+

Using QwtMagnifier a plot can be zoomed in/out in steps using keys, the mouse wheel or moving a mouse button in vertical direction.

+

Constructor & Destructor Documentation

+ +
+
+ + + + + +
+ + + + + + + + +
QwtMagnifier::QwtMagnifier (QWidget * parent)
+
+explicit
+
+

Constructor

+
Parameters
+ + +
parentWidget to be magnified
+
+
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool QwtMagnifier::eventFilter (QObject * object,
QEvent * event 
)
+
+virtual
+
+ +

Event filter.

+

When isEnabled() is true, the mouse events of the observed widget are filtered.

+
Parameters
+ + + +
objectObject to be filtered
eventEvent
+
+
+
Returns
Forwarded to QObject::eventFilter()
+
See Also
widgetMousePressEvent(), widgetMouseReleaseEvent(), widgetMouseMoveEvent(), widgetWheelEvent(), widgetKeyPressEvent() widgetKeyReleaseEvent()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtMagnifier::getMouseButton (Qt::MouseButton & button,
Qt::KeyboardModifiers & modifiers 
) const
+
+
See Also
setMouseButton()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtMagnifier::getZoomInKey (int & key,
Qt::KeyboardModifiers & modifiers 
) const
+
+ +

Retrieve the settings of the zoom in key.

+
Parameters
+ + + +
keyKey code, see Qt::Key
modifiersKeyboard modifiers
+
+
+
See Also
setZoomInKey()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtMagnifier::getZoomOutKey (int & key,
Qt::KeyboardModifiers & modifiers 
) const
+
+ +

Retrieve the settings of the zoom out key.

+
Parameters
+ + + +
keyKey code, see Qt::Key
modifiersKeyboard modifiers
+
+
+
See Also
setZoomOutKey()
+ +
+
+ +
+
+ + + + + + + +
bool QwtMagnifier::isEnabled () const
+
+
Returns
true when enabled, false otherwise
+
See Also
setEnabled(), eventFilter()
+ +
+
+ +
+
+ + + + + + + +
double QwtMagnifier::keyFactor () const
+
+
Returns
Key factor
+
See Also
setKeyFactor()
+ +
+
+ +
+
+ + + + + + + +
double QwtMagnifier::mouseFactor () const
+
+
Returns
Mouse factor
+
See Also
setMouseFactor()
+ +
+
+ +
+
+ + + + + + + +
QWidget * QwtMagnifier::parentWidget ()
+
+
Returns
Parent widget, where the rescaling happens
+ +
+
+ +
+
+ + + + + + + +
const QWidget * QwtMagnifier::parentWidget () const
+
+
Returns
Parent widget, where the rescaling happens
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
virtual void QwtMagnifier::rescale (double factor)
+
+protectedpure virtual
+
+

Rescale the parent widget

+
Parameters
+ + +
factorScale factor
+
+
+ +

Implemented in QwtPlotMagnifier.

+ +
+
+ +
+
+ + + + + + + + +
void QwtMagnifier::setEnabled (bool on)
+
+ +

En/disable the magnifier.

+

When enabled is true an event filter is installed for the observed widget, otherwise the event filter is removed.

+
Parameters
+ + +
ontrue or false
+
+
+
See Also
isEnabled(), eventFilter()
+ +
+
+ +
+
+ + + + + + + + +
void QwtMagnifier::setKeyFactor (double factor)
+
+ +

Change the key factor.

+

The key factor defines the ratio between the current range on the parent widget and the zoomed range for each key press of the zoom in/out keys. The default value is 0.9.

+
Parameters
+ + +
factorKey factor
+
+
+
See Also
keyFactor(), setZoomInKey(), setZoomOutKey(), setWheelFactor, setMouseFactor()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtMagnifier::setMouseButton (Qt::MouseButton button,
Qt::KeyboardModifiers modifiers = Qt::NoModifier 
)
+
+

Assign the mouse button, that is used for zooming in/out. The default value is Qt::RightButton.

+
Parameters
+ + + +
buttonButton
modifiersKeyboard modifiers
+
+
+
See Also
getMouseButton()
+ +
+
+ +
+
+ + + + + + + + +
void QwtMagnifier::setMouseFactor (double factor)
+
+ +

Change the mouse factor.

+

The mouse factor defines the ratio between the current range on the parent widget and the zoomed range for each vertical mouse movement. The default value is 0.95.

+
Parameters
+ + +
factorWheel factor
+
+
+
See Also
mouseFactor(), setMouseButton(), setWheelFactor(), setKeyFactor()
+ +
+
+ +
+
+ + + + + + + + +
void QwtMagnifier::setWheelFactor (double factor)
+
+ +

Change the wheel factor.

+

The wheel factor defines the ratio between the current range on the parent widget and the zoomed range for each step of the wheel.

+

Use values > 1 for magnification (i.e. 2.0) and values < 1 for scaling down (i.e. 1/2.0 = 0.5). You can use this feature for inverting the direction of the wheel.

+

The default value is 0.9.

+
Parameters
+ + +
factorWheel factor
+
+
+
See Also
wheelFactor(), setWheelButtonState(), setMouseFactor(), setKeyFactor()
+ +
+
+ +
+
+ + + + + + + + +
void QwtMagnifier::setWheelModifiers (Qt::KeyboardModifiers modifiers)
+
+

Assign keyboard modifiers for zooming in/out using the wheel. The default modifiers are Qt::NoModifiers.

+
Parameters
+ + +
modifiersKeyboard modifiers
+
+
+
See Also
wheelModifiers()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtMagnifier::setZoomInKey (int key,
Qt::KeyboardModifiers modifiers = Qt::NoModifier 
)
+
+

Assign the key, that is used for zooming in. The default combination is Qt::Key_Plus + Qt::NoModifier.

+
Parameters
+ + + +
key
modifiers
+
+
+
See Also
getZoomInKey(), setZoomOutKey()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtMagnifier::setZoomOutKey (int key,
Qt::KeyboardModifiers modifiers = Qt::NoModifier 
)
+
+

Assign the key, that is used for zooming out. The default combination is Qt::Key_Minus + Qt::NoModifier.

+
Parameters
+ + + +
key
modifiers
+
+
+
See Also
getZoomOutKey(), setZoomOutKey()
+ +
+
+ +
+
+ + + + + + + +
double QwtMagnifier::wheelFactor () const
+
+
Returns
Wheel factor
+
See Also
setWheelFactor()
+ +
+
+ +
+
+ + + + + + + +
Qt::KeyboardModifiers QwtMagnifier::wheelModifiers () const
+
+
Returns
Wheel modifiers
+
See Also
setWheelModifiers()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtMagnifier::widgetKeyPressEvent (QKeyEvent * keyEvent)
+
+protectedvirtual
+
+

Handle a key press event for the observed widget.

+
Parameters
+ + +
keyEventKey event
+
+
+
See Also
eventFilter(), widgetKeyReleaseEvent()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtMagnifier::widgetKeyReleaseEvent (QKeyEvent * keyEvent)
+
+protectedvirtual
+
+

Handle a key release event for the observed widget.

+
Parameters
+ + +
keyEventKey event
+
+
+
See Also
eventFilter(), widgetKeyReleaseEvent()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtMagnifier::widgetMouseMoveEvent (QMouseEvent * mouseEvent)
+
+protectedvirtual
+
+

Handle a mouse move event for the observed widget.

+
Parameters
+ + +
mouseEventMouse event
+
+
+
See Also
eventFilter(), widgetMousePressEvent(), widgetMouseReleaseEvent(),
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtMagnifier::widgetMousePressEvent (QMouseEvent * mouseEvent)
+
+protectedvirtual
+
+

Handle a mouse press event for the observed widget.

+
Parameters
+ + +
mouseEventMouse event
+
+
+
See Also
eventFilter(), widgetMouseReleaseEvent(), widgetMouseMoveEvent()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtMagnifier::widgetMouseReleaseEvent (QMouseEvent * mouseEvent)
+
+protectedvirtual
+
+

Handle a mouse release event for the observed widget.

+
Parameters
+ + +
mouseEventMouse event
+
+
+
See Also
eventFilter(), widgetMousePressEvent(), widgetMouseMoveEvent(),
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtMagnifier::widgetWheelEvent (QWheelEvent * wheelEvent)
+
+protectedvirtual
+
+

Handle a wheel event for the observed widget.

+
Parameters
+ + +
wheelEventWheel event
+
+
+
See Also
eventFilter()
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_magnifier__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_magnifier__inherit__graph.map new file mode 100644 index 0000000000..2e7d133eff --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_magnifier__inherit__graph.map @@ -0,0 +1,3 @@ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_magnifier__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_magnifier__inherit__graph.md5 new file mode 100644 index 0000000000..c34c0df802 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_magnifier__inherit__graph.md5 @@ -0,0 +1 @@ +bcdd0927f926770eb5975fce7761f905 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_magnifier__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_magnifier__inherit__graph.png new file mode 100644 index 0000000000..e27dea331e Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_magnifier__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_math_m_l_text_engine-members.html b/ThirdParty/Qwt/doc/html/class_qwt_math_m_l_text_engine-members.html new file mode 100644 index 0000000000..17d84ad862 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_math_m_l_text_engine-members.html @@ -0,0 +1,109 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtMathMLTextEngine Member List
+
+
+ +

This is the complete list of members for QwtMathMLTextEngine, including all inherited members.

+ + + + + + + + + + +
draw(QPainter *painter, const QRectF &rect, int flags, const QString &text) const QwtMathMLTextEnginevirtual
heightForWidth(const QFont &font, int flags, const QString &text, double width) const QwtMathMLTextEnginevirtual
mightRender(const QString &) const QwtMathMLTextEnginevirtual
QwtMathMLTextEngine()QwtMathMLTextEngine
QwtTextEngine()QwtTextEngineprotected
textMargins(const QFont &, const QString &, double &left, double &right, double &top, double &bottom) const QwtMathMLTextEnginevirtual
textSize(const QFont &font, int flags, const QString &text) const QwtMathMLTextEnginevirtual
~QwtMathMLTextEngine()QwtMathMLTextEnginevirtual
~QwtTextEngine()QwtTextEnginevirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_math_m_l_text_engine.html b/ThirdParty/Qwt/doc/html/class_qwt_math_m_l_text_engine.html new file mode 100644 index 0000000000..d73a75cb4c --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_math_m_l_text_engine.html @@ -0,0 +1,428 @@ + + + + + + +Qwt User's Guide: QwtMathMLTextEngine Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtMathMLTextEngine Class Reference
+
+
+ +

Text Engine for the MathML renderer of the Qt solutions package. + More...

+ +

#include <qwt_mathml_text_engine.h>

+
+Inheritance diagram for QwtMathMLTextEngine:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

QwtMathMLTextEngine ()
 Constructor.
 
+virtual ~QwtMathMLTextEngine ()
 Destructor.
 
virtual double heightForWidth (const QFont &font, int flags, const QString &text, double width) const
 
virtual QSizeF textSize (const QFont &font, int flags, const QString &text) const
 
virtual void draw (QPainter *painter, const QRectF &rect, int flags, const QString &text) const
 
virtual bool mightRender (const QString &) const
 
virtual void textMargins (const QFont &, const QString &, double &left, double &right, double &top, double &bottom) const
 
- Public Member Functions inherited from QwtTextEngine
+virtual ~QwtTextEngine ()
 Destructor.
 
+ + + + + +

+Additional Inherited Members

- Protected Member Functions inherited from QwtTextEngine
QwtTextEngine ()
 Constructor.
 
+

Detailed Description

+

Text Engine for the MathML renderer of the Qt solutions package.

+

To enable MathML support the following code needs to be added to the application:

+
#include <qwt_mathml_text_engine.h>
+
+QwtText::setTextEngine(QwtText::MathMLText, new QwtMathMLTextEngine());
See Also
QwtTextEngine, QwtText::setTextEngine
+
Warning
Unfortunately the MathML renderer doesn't support rotating of texts.
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void QwtMathMLTextEngine::draw (QPainter * painter,
const QRectF & rect,
int flags,
const QString & text 
) const
+
+virtual
+
+

Draw the text in a clipping rectangle

+
Parameters
+ + + + + +
painterPainter
rectClipping rectangle
flagsBitwise OR of the flags like in for QPainter::drawText
textText to be rendered
+
+
+ +

Implements QwtTextEngine.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
double QwtMathMLTextEngine::heightForWidth (const QFont & font,
int flags,
const QString & text,
double width 
) const
+
+virtual
+
+

Find the height for a given width

+
Parameters
+ + + + + +
fontFont of the text
flagsBitwise OR of the flags used like in QPainter::drawText
textText to be rendered
widthWidth
+
+
+
Returns
Calculated height
+ +

Implements QwtTextEngine.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool QwtMathMLTextEngine::mightRender (const QString & text) const
+
+virtual
+
+

Test if a string can be rendered by QwtMathMLTextEngine

+
Parameters
+ + +
textText to be tested
+
+
+
Returns
true, if text begins with "<math>".
+ +

Implements QwtTextEngine.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void QwtMathMLTextEngine::textMargins (const QFont & ,
const QString & ,
double & left,
double & right,
double & top,
double & bottom 
) const
+
+virtual
+
+

Return margins around the texts

+
Parameters
+ + + + + +
leftReturn 0
rightReturn 0
topReturn 0
bottomReturn 0
+
+
+ +

Implements QwtTextEngine.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
QSizeF QwtMathMLTextEngine::textSize (const QFont & font,
int flags,
const QString & text 
) const
+
+virtual
+
+

Returns the size, that is needed to render text

+
Parameters
+ + + + +
fontFont of the text
flagsBitwise OR of the flags used like in QPainter::drawText
textText to be rendered
+
+
+
Returns
Caluclated size
+ +

Implements QwtTextEngine.

+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_math_m_l_text_engine__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_math_m_l_text_engine__inherit__graph.map new file mode 100644 index 0000000000..4702d1051d --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_math_m_l_text_engine__inherit__graph.map @@ -0,0 +1,3 @@ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_math_m_l_text_engine__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_math_m_l_text_engine__inherit__graph.md5 new file mode 100644 index 0000000000..700f0737ff --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_math_m_l_text_engine__inherit__graph.md5 @@ -0,0 +1 @@ +a2c1266d79802e748ead1c5ce38510a6 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_math_m_l_text_engine__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_math_m_l_text_engine__inherit__graph.png new file mode 100644 index 0000000000..071f89a41d Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_math_m_l_text_engine__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_matrix_raster_data-members.html b/ThirdParty/Qwt/doc/html/class_qwt_matrix_raster_data-members.html new file mode 100644 index 0000000000..db25a57be9 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_matrix_raster_data-members.html @@ -0,0 +1,126 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtMatrixRasterData Member List
+
+
+ +

This is the complete list of members for QwtMatrixRasterData, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
BilinearInterpolation enum valueQwtMatrixRasterData
ConrecFlag enum nameQwtRasterData
ConrecFlags typedefQwtRasterData
ContourLines typedefQwtRasterData
contourLines(const QRectF &rect, const QSize &raster, const QList< double > &levels, ConrecFlags) const QwtRasterDatavirtual
discardRaster()QwtRasterDatavirtual
IgnoreAllVerticesOnLevel enum valueQwtRasterData
IgnoreOutOfRange enum valueQwtRasterData
initRaster(const QRectF &, const QSize &raster)QwtRasterDatavirtual
interval(Qt::Axis) const QwtRasterDatainline
NearestNeighbour enum valueQwtMatrixRasterData
numColumns() const QwtMatrixRasterData
numRows() const QwtMatrixRasterData
pixelHint(const QRectF &) const QwtMatrixRasterDatavirtual
QwtMatrixRasterData()QwtMatrixRasterData
QwtRasterData()QwtRasterData
resampleMode() const QwtMatrixRasterData
ResampleMode enum nameQwtMatrixRasterData
setInterval(Qt::Axis, const QwtInterval &)QwtMatrixRasterDatavirtual
setResampleMode(ResampleMode mode)QwtMatrixRasterData
setValue(int row, int col, double value)QwtMatrixRasterData
setValueMatrix(const QVector< double > &values, int numColumns)QwtMatrixRasterData
value(double x, double y) const QwtMatrixRasterDatavirtual
valueMatrix() const QwtMatrixRasterData
~QwtMatrixRasterData()QwtMatrixRasterDatavirtual
~QwtRasterData()QwtRasterDatavirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_matrix_raster_data.html b/ThirdParty/Qwt/doc/html/class_qwt_matrix_raster_data.html new file mode 100644 index 0000000000..d19f7ededa --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_matrix_raster_data.html @@ -0,0 +1,528 @@ + + + + + + +Qwt User's Guide: QwtMatrixRasterData Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtMatrixRasterData Class Reference
+
+
+ +

A class representing a matrix of values as raster data. + More...

+ +

#include <qwt_matrix_raster_data.h>

+
+Inheritance diagram for QwtMatrixRasterData:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + + + + + + + + +

+Public Types

enum  ResampleMode { NearestNeighbour, +BilinearInterpolation + }
 Resampling algorithm The default setting is NearestNeighbour;. More...
 
- Public Types inherited from QwtRasterData
enum  ConrecFlag { IgnoreAllVerticesOnLevel = 0x01, +IgnoreOutOfRange = 0x02 + }
 Flags to modify the contour algorithm. More...
 
+typedef QMap< double, QPolygonF > ContourLines
 Contour lines.
 
+typedef QFlags< ConrecFlagConrecFlags
 Flags to modify the contour algorithm.
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

QwtMatrixRasterData ()
 Constructor.
 
+virtual ~QwtMatrixRasterData ()
 Destructor.
 
void setResampleMode (ResampleMode mode)
 Set the resampling algorithm. More...
 
ResampleMode resampleMode () const
 
virtual void setInterval (Qt::Axis, const QwtInterval &)
 Assign the bounding interval for an axis. More...
 
void setValueMatrix (const QVector< double > &values, int numColumns)
 Assign a value matrix. More...
 
const QVector< double > valueMatrix () const
 
void setValue (int row, int col, double value)
 Change a single value in the matrix. More...
 
int numColumns () const
 
int numRows () const
 
virtual QRectF pixelHint (const QRectF &) const
 Calculate the pixel hint. More...
 
virtual double value (double x, double y) const
 
- Public Member Functions inherited from QwtRasterData
QwtRasterData ()
 Constructor.
 
+virtual ~QwtRasterData ()
 Destructor.
 
const QwtIntervalinterval (Qt::Axis) const
 
virtual void initRaster (const QRectF &, const QSize &raster)
 Initialize a raster. More...
 
virtual void discardRaster ()
 Discard a raster. More...
 
virtual ContourLines contourLines (const QRectF &rect, const QSize &raster, const QList< double > &levels, ConrecFlags) const
 
+

Detailed Description

+

A class representing a matrix of values as raster data.

+

QwtMatrixRasterData implements an interface for a matrix of equidistant values, that can be used by a QwtPlotRasterItem. It implements a couple of resampling algorithms, to provide values for positions, that or not on the value matrix.

+

Member Enumeration Documentation

+ +
+
+ +

Resampling algorithm The default setting is NearestNeighbour;.

+ + + +
Enumerator
NearestNeighbour  +

Return the value from the matrix, that is nearest to the the requested position.

+
BilinearInterpolation  +

Interpolate the value from the distances and values of the 4 surrounding values in the matrix,

+
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + + + +
int QwtMatrixRasterData::numColumns () const
+
+
Returns
Number of columns of the value matrix
+
See Also
valueMatrix(), numRows(), setValueMatrix()
+ +
+
+ +
+
+ + + + + + + +
int QwtMatrixRasterData::numRows () const
+
+
Returns
Number of rows of the value matrix
+
See Also
valueMatrix(), numColumns(), setValueMatrix()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
QRectF QwtMatrixRasterData::pixelHint (const QRectF & area) const
+
+virtual
+
+ +

Calculate the pixel hint.

+

pixelHint() returns the geometry of a pixel, that can be used to calculate the resolution and alignment of the plot item, that is representing the data.

+
    +
  • NearestNeighbour
    + pixelHint() returns the surrounding pixel of the top left value in the matrix.
  • +
+
    +
  • BilinearInterpolation
    + Returns an empty rectangle recommending to render in target device ( f.e. screen ) resolution.
  • +
+
Parameters
+ + +
areaRequested area, ignored
+
+
+
Returns
Calculated hint
+
See Also
ResampleMode, setMatrix(), setInterval()
+ +

Reimplemented from QwtRasterData.

+ +
+
+ +
+
+ + + + + + + +
QwtMatrixRasterData::ResampleMode QwtMatrixRasterData::resampleMode () const
+
+
Returns
resampling algorithm
+
See Also
setResampleMode(), value()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void QwtMatrixRasterData::setInterval (Qt::Axis axis,
const QwtIntervalinterval 
)
+
+virtual
+
+ +

Assign the bounding interval for an axis.

+

Setting the bounding intervals for the X/Y axis is mandatory to define the positions for the values of the value matrix. The interval in Z direction defines the possible range for the values in the matrix, what is f.e used by QwtPlotSpectrogram to map values to colors. The Z-interval might be the bounding interval of the values in the matrix, but usually it isn't. ( f.e a interval of 0.0-100.0 for values in percentage )

+
Parameters
+ + + +
axisX, Y or Z axis
intervalInterval
+
+
+
See Also
QwtRasterData::interval(), setValueMatrix()
+ +

Reimplemented from QwtRasterData.

+ +
+
+ +
+
+ + + + + + + + +
void QwtMatrixRasterData::setResampleMode (ResampleMode mode)
+
+ +

Set the resampling algorithm.

+
Parameters
+ + +
modeResampling mode
+
+
+
See Also
resampleMode(), value()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void QwtMatrixRasterData::setValue (int row,
int col,
double value 
)
+
+ +

Change a single value in the matrix.

+
Parameters
+ + + + +
rowRow index
colColumn index
valueNew value
+
+
+
See Also
value(), setValueMatrix()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtMatrixRasterData::setValueMatrix (const QVector< double > & values,
int numColumns 
)
+
+ +

Assign a value matrix.

+

The positions of the values are calculated by dividing the bounding rectangle of the X/Y intervals into equidistant rectangles ( pixels ). Each value corresponds to the center of a pixel.

+
Parameters
+ + + +
valuesVector of values
numColumnsNumber of columns
+
+
+
See Also
valueMatrix(), numColumns(), numRows(), setInterval()()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
double QwtMatrixRasterData::value (double x,
double y 
) const
+
+virtual
+
+
Returns
the value at a raster position
+
Parameters
+ + + +
xX value in plot coordinates
yY value in plot coordinates
+
+
+
See Also
ResampleMode
+ +

Implements QwtRasterData.

+ +
+
+ +
+
+ + + + + + + +
const QVector< double > QwtMatrixRasterData::valueMatrix () const
+
+
Returns
Value matrix
+
See Also
setValueMatrix(), numColumns(), numRows(), setInterval()
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_matrix_raster_data__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_matrix_raster_data__inherit__graph.map new file mode 100644 index 0000000000..de11268db1 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_matrix_raster_data__inherit__graph.map @@ -0,0 +1,3 @@ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_matrix_raster_data__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_matrix_raster_data__inherit__graph.md5 new file mode 100644 index 0000000000..0d11a15e14 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_matrix_raster_data__inherit__graph.md5 @@ -0,0 +1 @@ +7de2533ad4048e51a929420234ef1e64 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_matrix_raster_data__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_matrix_raster_data__inherit__graph.png new file mode 100644 index 0000000000..79e5b6cb2f Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_matrix_raster_data__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_null_paint_device-members.html b/ThirdParty/Qwt/doc/html/class_qwt_null_paint_device-members.html new file mode 100644 index 0000000000..0fd75a48df --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_null_paint_device-members.html @@ -0,0 +1,127 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtNullPaintDevice Member List
+
+
+ +

This is the complete list of members for QwtNullPaintDevice, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
drawEllipse(const QRectF &)QwtNullPaintDevicevirtual
drawEllipse(const QRect &)QwtNullPaintDevicevirtual
drawImage(const QRectF &, const QImage &, const QRectF &, Qt::ImageConversionFlags)QwtNullPaintDevicevirtual
drawLines(const QLine *, int)QwtNullPaintDevicevirtual
drawLines(const QLineF *, int)QwtNullPaintDevicevirtual
drawPath(const QPainterPath &)QwtNullPaintDevicevirtual
drawPixmap(const QRectF &, const QPixmap &, const QRectF &)QwtNullPaintDevicevirtual
drawPoints(const QPointF *, int)QwtNullPaintDevicevirtual
drawPoints(const QPoint *, int)QwtNullPaintDevicevirtual
drawPolygon(const QPointF *, int, QPaintEngine::PolygonDrawMode)QwtNullPaintDevicevirtual
drawPolygon(const QPoint *, int, QPaintEngine::PolygonDrawMode)QwtNullPaintDevicevirtual
drawRects(const QRect *, int)QwtNullPaintDevicevirtual
drawRects(const QRectF *, int)QwtNullPaintDevicevirtual
drawTextItem(const QPointF &, const QTextItem &)QwtNullPaintDevicevirtual
drawTiledPixmap(const QRectF &, const QPixmap &, const QPointF &s)QwtNullPaintDevicevirtual
metric(PaintDeviceMetric metric) const QwtNullPaintDevicevirtual
Mode enum nameQwtNullPaintDevice
mode() const QwtNullPaintDevice
NormalMode enum valueQwtNullPaintDevice
paintEngine() const QwtNullPaintDevicevirtual
PathMode enum valueQwtNullPaintDevice
PolygonPathMode enum valueQwtNullPaintDevice
QwtNullPaintDevice()QwtNullPaintDevice
setMode(Mode)QwtNullPaintDevice
sizeMetrics() const =0QwtNullPaintDeviceprotectedpure virtual
updateState(const QPaintEngineState &state)QwtNullPaintDevicevirtual
~QwtNullPaintDevice()QwtNullPaintDevicevirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_null_paint_device.html b/ThirdParty/Qwt/doc/html/class_qwt_null_paint_device.html new file mode 100644 index 0000000000..3d88d797f8 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_null_paint_device.html @@ -0,0 +1,358 @@ + + + + + + +Qwt User's Guide: QwtNullPaintDevice Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtNullPaintDevice Class Referenceabstract
+
+
+ +

A null paint device doing nothing. + More...

+ +

#include <qwt_null_paintdevice.h>

+
+Inheritance diagram for QwtNullPaintDevice:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + +

+Public Types

enum  Mode { NormalMode, +PolygonPathMode, +PathMode + }
 Render mode. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

QwtNullPaintDevice ()
 Constructor.
 
+virtual ~QwtNullPaintDevice ()
 Destructor.
 
void setMode (Mode)
 
Mode mode () const
 
+virtual QPaintEngine * paintEngine () const
 See QPaintDevice::paintEngine()
 
virtual int metric (PaintDeviceMetric metric) const
 
+virtual void drawRects (const QRect *, int)
 See QPaintEngine::drawRects()
 
+virtual void drawRects (const QRectF *, int)
 See QPaintEngine::drawRects()
 
+virtual void drawLines (const QLine *, int)
 See QPaintEngine::drawLines()
 
+virtual void drawLines (const QLineF *, int)
 See QPaintEngine::drawLines()
 
+virtual void drawEllipse (const QRectF &)
 See QPaintEngine::drawEllipse()
 
+virtual void drawEllipse (const QRect &)
 See QPaintEngine::drawEllipse()
 
+virtual void drawPath (const QPainterPath &)
 See QPaintEngine::drawPath()
 
+virtual void drawPoints (const QPointF *, int)
 See QPaintEngine::drawPoints()
 
+virtual void drawPoints (const QPoint *, int)
 See QPaintEngine::drawPoints()
 
+virtual void drawPolygon (const QPointF *, int, QPaintEngine::PolygonDrawMode)
 See QPaintEngine::drawPolygon()
 
+virtual void drawPolygon (const QPoint *, int, QPaintEngine::PolygonDrawMode)
 See QPaintEngine::drawPolygon()
 
+virtual void drawPixmap (const QRectF &, const QPixmap &, const QRectF &)
 See QPaintEngine::drawPixmap()
 
+virtual void drawTextItem (const QPointF &, const QTextItem &)
 See QPaintEngine::drawTextItem()
 
+virtual void drawTiledPixmap (const QRectF &, const QPixmap &, const QPointF &s)
 See QPaintEngine::drawTiledPixmap()
 
+virtual void drawImage (const QRectF &, const QImage &, const QRectF &, Qt::ImageConversionFlags)
 See QPaintEngine::drawImage()
 
+virtual void updateState (const QPaintEngineState &state)
 See QPaintEngine::updateState()
 
+ + + +

+Protected Member Functions

virtual QSize sizeMetrics () const =0
 
+

Detailed Description

+

A null paint device doing nothing.

+

Sometimes important layout/rendering geometries are not available or changeable from the public Qt class interface. ( f.e hidden in the style implementation ).

+

QwtNullPaintDevice can be used to manipulate or filter out this information by analyzing the stream of paint primitives.

+

F.e. QwtNullPaintDevice is used by QwtPlotCanvas to identify styled backgrounds with rounded corners.

+

Member Enumeration Documentation

+ +
+
+ + + + +
enum QwtNullPaintDevice::Mode
+
+ +

Render mode.

+
See Also
setMode(), mode()
+ + + + +
Enumerator
NormalMode  +

All vector graphic primitives are painted by the corresponding draw methods

+
PolygonPathMode  +

Vector graphic primitives ( beside polygons ) are mapped to a QPainterPath and are painted by drawPath. In PathMode mode only a few draw methods are called:

+ +
PathMode  +

Vector graphic primitives are mapped to a QPainterPath and are painted by drawPath. In PathMode mode only a few draw methods are called:

+ +
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + + +
int QwtNullPaintDevice::metric (PaintDeviceMetric deviceMetric) const
+
+virtual
+
+

See QPaintDevice::metric()

+
Parameters
+ + +
deviceMetricType of metric
+
+
+
Returns
Metric information for the given paint device metric.
+
See Also
sizeMetrics()
+ +
+
+ +
+
+ + + + + + + +
QwtNullPaintDevice::Mode QwtNullPaintDevice::mode () const
+
+
Returns
Render mode
+
See Also
setMode()
+ +
+
+ +
+
+ + + + + + + + +
void QwtNullPaintDevice::setMode (Mode mode)
+
+

Set the render mode

+
Parameters
+ + +
modeNew mode
+
+
+
See Also
mode()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
virtual QSize QwtNullPaintDevice::sizeMetrics () const
+
+protectedpure virtual
+
+
Returns
Size needed to implement metric()
+ +

Implemented in QwtGraphic.

+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_null_paint_device__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_null_paint_device__inherit__graph.map new file mode 100644 index 0000000000..0af713eeef --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_null_paint_device__inherit__graph.map @@ -0,0 +1,3 @@ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_null_paint_device__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_null_paint_device__inherit__graph.md5 new file mode 100644 index 0000000000..d9bbc08a5d --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_null_paint_device__inherit__graph.md5 @@ -0,0 +1 @@ +bfd18364750a5f481d0f7c9e1cf77730 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_null_paint_device__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_null_paint_device__inherit__graph.png new file mode 100644 index 0000000000..7188f0048b Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_null_paint_device__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_null_transform-members.html b/ThirdParty/Qwt/doc/html/class_qwt_null_transform-members.html new file mode 100644 index 0000000000..2d33282572 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_null_transform-members.html @@ -0,0 +1,108 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtNullTransform Member List
+
+
+ +

This is the complete list of members for QwtNullTransform, including all inherited members.

+ + + + + + + + + +
bounded(double value) const QwtTransformvirtual
copy() const QwtNullTransformvirtual
invTransform(double value) const QwtNullTransformvirtual
QwtNullTransform()QwtNullTransform
QwtTransform()QwtTransform
transform(double value) const QwtNullTransformvirtual
~QwtNullTransform()QwtNullTransformvirtual
~QwtTransform()QwtTransformvirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_null_transform.html b/ThirdParty/Qwt/doc/html/class_qwt_null_transform.html new file mode 100644 index 0000000000..e3cca08a90 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_null_transform.html @@ -0,0 +1,237 @@ + + + + + + +Qwt User's Guide: QwtNullTransform Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtNullTransform Class Reference
+
+
+ +

Null transformation. + More...

+ +

#include <qwt_transform.h>

+
+Inheritance diagram for QwtNullTransform:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

QwtNullTransform ()
 Constructor.
 
+virtual ~QwtNullTransform ()
 Destructor.
 
virtual double transform (double value) const
 
virtual double invTransform (double value) const
 
virtual QwtTransformcopy () const
 
- Public Member Functions inherited from QwtTransform
QwtTransform ()
 Constructor.
 
+virtual ~QwtTransform ()
 Destructor.
 
virtual double bounded (double value) const
 
+

Detailed Description

+

Null transformation.

+

QwtNullTransform returns the values unmodified.

+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + +
QwtTransform * QwtNullTransform::copy () const
+
+virtual
+
+
Returns
Clone of the transformation
+ +

Implements QwtTransform.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
double QwtNullTransform::invTransform (double value) const
+
+virtual
+
+
Parameters
+ + +
valueValue to be transformed
+
+
+
Returns
value unmodified
+ +

Implements QwtTransform.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
double QwtNullTransform::transform (double value) const
+
+virtual
+
+
Parameters
+ + +
valueValue to be transformed
+
+
+
Returns
value unmodified
+ +

Implements QwtTransform.

+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_null_transform__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_null_transform__inherit__graph.map new file mode 100644 index 0000000000..a43c88594b --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_null_transform__inherit__graph.map @@ -0,0 +1,3 @@ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_null_transform__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_null_transform__inherit__graph.md5 new file mode 100644 index 0000000000..453516ec68 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_null_transform__inherit__graph.md5 @@ -0,0 +1 @@ +325f800ef1a5b07d02c737b921c3b75d \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_null_transform__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_null_transform__inherit__graph.png new file mode 100644 index 0000000000..cf5d04539a Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_null_transform__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_o_h_l_c_sample-members.html b/ThirdParty/Qwt/doc/html/class_qwt_o_h_l_c_sample-members.html new file mode 100644 index 0000000000..09f624fc20 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_o_h_l_c_sample-members.html @@ -0,0 +1,108 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtOHLCSample Member List
+
+
+ +

This is the complete list of members for QwtOHLCSample, including all inherited members.

+ + + + + + + + + +
boundingInterval() const QwtOHLCSampleinline
closeQwtOHLCSample
highQwtOHLCSample
isValid() const QwtOHLCSampleinline
lowQwtOHLCSample
openQwtOHLCSample
QwtOHLCSample(double time=0.0, double open=0.0, double high=0.0, double low=0.0, double close=0.0)QwtOHLCSampleinline
timeQwtOHLCSample
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_o_h_l_c_sample.html b/ThirdParty/Qwt/doc/html/class_qwt_o_h_l_c_sample.html new file mode 100644 index 0000000000..667e2e1c24 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_o_h_l_c_sample.html @@ -0,0 +1,282 @@ + + + + + + +Qwt User's Guide: QwtOHLCSample Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtOHLCSample Class Reference
+
+
+ +

Open-High-Low-Close sample used in financial charts. + More...

+ +

#include <qwt_samples.h>

+ + + + + + + + + + +

+Public Member Functions

 QwtOHLCSample (double time=0.0, double open=0.0, double high=0.0, double low=0.0, double close=0.0)
 
QwtInterval boundingInterval () const
 Calculate the bounding interval of the OHLC values. More...
 
bool isValid () const
 Check if a sample is valid. More...
 
+ + + + + + + + + + + + + + + +

+Public Attributes

double time
 
+double open
 Opening price.
 
+double high
 Highest price.
 
+double low
 Lowest price.
 
+double close
 Closing price.
 
+

Detailed Description

+

Open-High-Low-Close sample used in financial charts.

+

In financial charts the movement of a price in a time interval is often represented by the opening/closing prices and the lowest/highest prices in this interval.

+
See Also
QwtTradingChartData
+

Constructor & Destructor Documentation

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
QwtOHLCSample::QwtOHLCSample (double t = 0.0,
double o = 0.0,
double h = 0.0,
double l = 0.0,
double c = 0.0 
)
+
+inline
+
+

Constructor

+
Parameters
+ + + + + + +
tTime value
oOpen value
hHigh value
lLow value
cClose value
+
+
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + +
QwtInterval QwtOHLCSample::boundingInterval () const
+
+inline
+
+ +

Calculate the bounding interval of the OHLC values.

+

For valid samples the limits of this interval are always low/high.

+
Returns
Bounding interval
+
See Also
isValid()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool QwtOHLCSample::isValid () const
+
+inline
+
+ +

Check if a sample is valid.

+

A sample is valid, when all of the following checks are true:

+
    +
  • low <= high
  • +
  • low <= open <= high
  • +
  • low <= close <= high
  • +
+
Returns
True, when the sample is valid
+ +
+
+

Member Data Documentation

+ +
+
+ + + + +
double QwtOHLCSample::time
+
+

Time of the sample, usually a number representing a specific interval - like a day.

+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_painter-members.html b/ThirdParty/Qwt/doc/html/class_qwt_painter-members.html new file mode 100644 index 0000000000..c2cb1b14fb --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_painter-members.html @@ -0,0 +1,145 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtPainter Member List
+
+
+ +

This is the complete list of members for QwtPainter, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
backingStore(QWidget *, const QSize &)QwtPainterstatic
drawBackgound(QPainter *painter, const QRectF &rect, const QWidget *widget)QwtPainterstatic
drawColorBar(QPainter *painter, const QwtColorMap &, const QwtInterval &, const QwtScaleMap &, Qt::Orientation, const QRectF &)QwtPainterstatic
drawEllipse(QPainter *, const QRectF &)QwtPainterstatic
drawFocusRect(QPainter *, const QWidget *)QwtPainterstatic
drawFocusRect(QPainter *, const QWidget *, const QRect &)QwtPainterstatic
drawFrame(QPainter *, const QRectF &rect, const QPalette &palette, QPalette::ColorRole foregroundRole, int lineWidth, int midLineWidth, int frameStyle)QwtPainterstatic
drawImage(QPainter *, const QRectF &, const QImage &)QwtPainterstatic
drawLine(QPainter *, double x1, double y1, double x2, double y2)QwtPainterinlinestatic
drawLine(QPainter *, const QPointF &p1, const QPointF &p2)QwtPainterstatic
drawLine(QPainter *, const QLineF &)QwtPainterinlinestatic
drawPath(QPainter *, const QPainterPath &)QwtPainterstatic
drawPie(QPainter *, const QRectF &r, int a, int alen)QwtPainterstatic
drawPixmap(QPainter *, const QRectF &, const QPixmap &)QwtPainterstatic
drawPoint(QPainter *, const QPoint &)QwtPainterstatic
drawPoint(QPainter *, double x, double y)QwtPainterinlinestatic
drawPoint(QPainter *, const QPointF &)QwtPainterstatic
drawPoints(QPainter *, const QPolygon &)QwtPainterinlinestatic
drawPoints(QPainter *, const QPoint *, int pointCount)QwtPainterstatic
drawPoints(QPainter *, const QPolygonF &)QwtPainterinlinestatic
drawPoints(QPainter *, const QPointF *, int pointCount)QwtPainterstatic
drawPolygon(QPainter *, const QPolygonF &)QwtPainterstatic
drawPolygon(QPainter *, const QPolygon &)QwtPainterstatic
drawPolyline(QPainter *, const QPolygonF &)QwtPainterstatic
drawPolyline(QPainter *, const QPointF *, int pointCount)QwtPainterstatic
drawPolyline(QPainter *, const QPolygon &)QwtPainterstatic
drawPolyline(QPainter *, const QPoint *, int pointCount)QwtPainterstatic
drawRect(QPainter *, double x, double y, double w, double h)QwtPainterstatic
drawRect(QPainter *, const QRectF &rect)QwtPainterstatic
drawRoundedFrame(QPainter *, const QRectF &, double xRadius, double yRadius, const QPalette &, int lineWidth, int frameStyle)QwtPainterstatic
drawRoundFrame(QPainter *, const QRectF &, const QPalette &, int lineWidth, int frameStyle)QwtPainterstatic
drawSimpleRichText(QPainter *, const QRectF &, int flags, const QTextDocument &)QwtPainterstatic
drawText(QPainter *, double x, double y, const QString &)QwtPainterstatic
drawText(QPainter *, const QPointF &, const QString &)QwtPainterstatic
drawText(QPainter *, double x, double y, double w, double h, int flags, const QString &)QwtPainterstatic
drawText(QPainter *, const QRectF &, int flags, const QString &)QwtPainterstatic
fillPixmap(const QWidget *, QPixmap &, const QPoint &offset=QPoint())QwtPainterstatic
fillRect(QPainter *, const QRectF &, const QBrush &)QwtPainterstatic
isAligning(QPainter *painter)QwtPainterstatic
isX11GraphicsSystem()QwtPainterstatic
polylineSplitting()QwtPainterinlinestatic
roundingAlignment()QwtPainterinlinestatic
roundingAlignment(QPainter *)QwtPainterinlinestatic
setPolylineSplitting(bool)QwtPainterstatic
setRoundingAlignment(bool)QwtPainterstatic
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_painter.html b/ThirdParty/Qwt/doc/html/class_qwt_painter.html new file mode 100644 index 0000000000..aae1613692 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_painter.html @@ -0,0 +1,946 @@ + + + + + + +Qwt User's Guide: QwtPainter Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtPainter Class Reference
+
+
+ +

A collection of QPainter workarounds. + More...

+ +

#include <qwt_painter.h>

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Static Public Member Functions

static void setPolylineSplitting (bool)
 En/Disable line splitting for the raster paint engine. More...
 
static bool polylineSplitting ()
 
static void setRoundingAlignment (bool)
 
static bool roundingAlignment ()
 
static bool roundingAlignment (QPainter *)
 
+static void drawText (QPainter *, double x, double y, const QString &)
 Wrapper for QPainter::drawText()
 
+static void drawText (QPainter *, const QPointF &, const QString &)
 Wrapper for QPainter::drawText()
 
+static void drawText (QPainter *, double x, double y, double w, double h, int flags, const QString &)
 Wrapper for QPainter::drawText()
 
+static void drawText (QPainter *, const QRectF &, int flags, const QString &)
 Wrapper for QPainter::drawText()
 
static void drawSimpleRichText (QPainter *, const QRectF &, int flags, const QTextDocument &)
 
+static void drawRect (QPainter *, double x, double y, double w, double h)
 Wrapper for QPainter::drawRect()
 
+static void drawRect (QPainter *, const QRectF &rect)
 Wrapper for QPainter::drawRect()
 
+static void fillRect (QPainter *, const QRectF &, const QBrush &)
 Wrapper for QPainter::fillRect()
 
+static void drawEllipse (QPainter *, const QRectF &)
 Wrapper for QPainter::drawEllipse()
 
+static void drawPie (QPainter *, const QRectF &r, int a, int alen)
 Wrapper for QPainter::drawPie()
 
+static void drawLine (QPainter *, double x1, double y1, double x2, double y2)
 Wrapper for QPainter::drawLine()
 
+static void drawLine (QPainter *, const QPointF &p1, const QPointF &p2)
 Wrapper for QPainter::drawLine()
 
+static void drawLine (QPainter *, const QLineF &)
 Wrapper for QPainter::drawLine()
 
+static void drawPolygon (QPainter *, const QPolygonF &)
 Wrapper for QPainter::drawPolygon()
 
+static void drawPolyline (QPainter *, const QPolygonF &)
 Wrapper for QPainter::drawPolyline()
 
+static void drawPolyline (QPainter *, const QPointF *, int pointCount)
 Wrapper for QPainter::drawPolyline()
 
+static void drawPolygon (QPainter *, const QPolygon &)
 Wrapper for QPainter::drawPolygon()
 
+static void drawPolyline (QPainter *, const QPolygon &)
 Wrapper for QPainter::drawPolyline()
 
+static void drawPolyline (QPainter *, const QPoint *, int pointCount)
 Wrapper for QPainter::drawPolyline()
 
+static void drawPoint (QPainter *, const QPoint &)
 Wrapper for QPainter::drawPoint()
 
+static void drawPoints (QPainter *, const QPolygon &)
 Wrapper for QPainter::drawPoints()
 
+static void drawPoints (QPainter *, const QPoint *, int pointCount)
 Wrapper for QPainter::drawPoints()
 
+static void drawPoint (QPainter *, double x, double y)
 Wrapper for QPainter::drawPoint()
 
+static void drawPoint (QPainter *, const QPointF &)
 Wrapper for QPainter::drawPoint()
 
+static void drawPoints (QPainter *, const QPolygonF &)
 Wrapper for QPainter::drawPoints()
 
+static void drawPoints (QPainter *, const QPointF *, int pointCount)
 Wrapper for QPainter::drawPoints()
 
+static void drawPath (QPainter *, const QPainterPath &)
 Wrapper for QPainter::drawPath()
 
+static void drawImage (QPainter *, const QRectF &, const QImage &)
 Wrapper for QPainter::drawImage()
 
+static void drawPixmap (QPainter *, const QRectF &, const QPixmap &)
 Wrapper for QPainter::drawPixmap()
 
static void drawRoundFrame (QPainter *, const QRectF &, const QPalette &, int lineWidth, int frameStyle)
 
static void drawRoundedFrame (QPainter *, const QRectF &, double xRadius, double yRadius, const QPalette &, int lineWidth, int frameStyle)
 
static void drawFrame (QPainter *, const QRectF &rect, const QPalette &palette, QPalette::ColorRole foregroundRole, int lineWidth, int midLineWidth, int frameStyle)
 
+static void drawFocusRect (QPainter *, const QWidget *)
 Draw a focus rectangle on a widget using its style.
 
+static void drawFocusRect (QPainter *, const QWidget *, const QRect &)
 Draw a focus rectangle on a widget using its style.
 
static void drawColorBar (QPainter *painter, const QwtColorMap &, const QwtInterval &, const QwtScaleMap &, Qt::Orientation, const QRectF &)
 
static bool isAligning (QPainter *painter)
 
static bool isX11GraphicsSystem ()
 
static void fillPixmap (const QWidget *, QPixmap &, const QPoint &offset=QPoint())
 
static void drawBackgound (QPainter *painter, const QRectF &rect, const QWidget *widget)
 
static QPixmap backingStore (QWidget *, const QSize &)
 
+

Detailed Description

+

A collection of QPainter workarounds.

+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
QPixmap QwtPainter::backingStore (QWidget * widget,
const QSize & size 
)
+
+static
+
+
Returns
A pixmap that can be used as backing store
+
Parameters
+ + + +
widgetWidget, for which the backinstore is intended
sizeSize of the pixmap
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPainter::drawBackgound (QPainter * painter,
const QRectF & rect,
const QWidget * widget 
)
+
+static
+
+

Fill rect with the background of a widget

+
Parameters
+ + + + +
painterPainter
rectRectangle to be filled
widgetWidget
+
+
+
See Also
QStyle::PE_Widget, QWidget::backgroundRole()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPainter::drawColorBar (QPainter * painter,
const QwtColorMapcolorMap,
const QwtIntervalinterval,
const QwtScaleMapscaleMap,
Qt::Orientation orientation,
const QRectF & rect 
)
+
+static
+
+

Draw a color bar into a rectangle

+
Parameters
+ + + + + + + +
painterPainter
colorMapColor map
intervalValue range
scaleMapScale map
orientationOrientation
rectTraget rectangle
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPainter::drawFrame (QPainter * painter,
const QRectF & rect,
const QPalette & palette,
QPalette::ColorRole foregroundRole,
int frameWidth,
int midLineWidth,
int frameStyle 
)
+
+static
+
+

Draw a rectangular frame

+
Parameters
+ + + + + + + + +
painterPainter
rectFrame rectangle
palettePalette
foregroundRoleForeground role used for QFrame::Plain
frameWidthFrame width
midLineWidthUsed for QFrame::Box
frameStylebitwise OR´ed value of QFrame::Shape and QFrame::Shadow
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPainter::drawRoundedFrame (QPainter * painter,
const QRectF & rect,
double xRadius,
double yRadius,
const QPalette & palette,
int lineWidth,
int frameStyle 
)
+
+static
+
+

Draw a rectangular frame with rounded borders

+
Parameters
+ + + + + + + + +
painterPainter
rectFrame rectangle
xRadiusx-radius of the ellipses defining the corners
yRadiusy-radius of the ellipses defining the corners
paletteQPalette::WindowText is used for plain borders QPalette::Dark and QPalette::Light for raised or sunken borders
lineWidthLine width
frameStylebitwise OR´ed value of QFrame::Shape and QFrame::Shadow
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPainter::drawRoundFrame (QPainter * painter,
const QRectF & rect,
const QPalette & palette,
int lineWidth,
int frameStyle 
)
+
+static
+
+

Draw a round frame

+
Parameters
+ + + + + + +
painterPainter
rectFrame rectangle
paletteQPalette::WindowText is used for plain borders QPalette::Dark and QPalette::Light for raised or sunken borders
lineWidthLine width
frameStylebitwise OR´ed value of QFrame::Shape and QFrame::Shadow
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPainter::drawSimpleRichText (QPainter * painter,
const QRectF & rect,
int flags,
const QTextDocument & text 
)
+
+static
+
+

Draw a text document into a rectangle

+
Parameters
+ + + + + +
painterPainter
rectTraget rectangle
flagsAlignments/Text flags, see QPainter::drawText()
textText document
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPainter::fillPixmap (const QWidget * widget,
QPixmap & pixmap,
const QPoint & offset = QPoint() 
)
+
+static
+
+

Fill a pixmap with the content of a widget

+

In Qt >= 5.0 QPixmap::fill() is a nop, in Qt 4.x it is buggy for backgrounds with gradients. Thus fillPixmap() offers an alternative implementation.

+
Parameters
+ + + + +
widgetWidget
pixmapPixmap to be filled
offsetOffset
+
+
+
See Also
QPixmap::fill()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool QwtPainter::isAligning (QPainter * painter)
+
+static
+
+

Check if the painter is using a paint engine, that aligns coordinates to integers. Today these are all paint engines beside QPaintEngine::Pdf and QPaintEngine::SVG.

+

If we have an integer based paint engine it is also checked if the painter has a transformation matrix, that rotates or scales.

+
Parameters
+ + +
painterPainter
+
+
+
Returns
true, when the painter is aligning
+
See Also
setRoundingAlignment()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool QwtPainter::isX11GraphicsSystem ()
+
+static
+
+

Check is the application is running with the X11 graphics system that has some special capabilities that can be used for incremental painting to a widget.

+
Returns
True, when the graphics system is X11
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool QwtPainter::polylineSplitting ()
+
+inlinestatic
+
+
Returns
True, when line splitting for the raster paint engine is enabled.
+
See Also
setPolylineSplitting()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool QwtPainter::roundingAlignment ()
+
+inlinestatic
+
+

Check whether coordinates should be rounded, before they are painted to a paint engine that rounds to integer values. For other paint engines ( PDF, SVG ), this flag has no effect.

+
Returns
True, when rounding is enabled
+
See Also
setRoundingAlignment(), isAligning()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool QwtPainter::roundingAlignment (QPainter * painter)
+
+inlinestatic
+
+
Returns
roundingAlignment() && isAligning(painter);
+
Parameters
+ + +
painterPainter
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtPainter::setPolylineSplitting (bool enable)
+
+static
+
+ +

En/Disable line splitting for the raster paint engine.

+

In some Qt versions the raster paint engine paints polylines of many points much faster when they are split in smaller chunks: f.e all supported Qt versions >= Qt 5.0 when drawing an antialiased polyline with a pen width >=2.

+

The default setting is true.

+
See Also
polylineSplitting()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtPainter::setRoundingAlignment (bool enable)
+
+static
+
+

Enable whether coordinates should be rounded, before they are painted to a paint engine that floors to integer values. For other paint engines this ( PDF, SVG ), this flag has no effect. QwtPainter stores this flag only, the rounding itself is done in the painting code ( f.e the plot items ).

+

The default setting is true.

+
See Also
roundingAlignment(), isAligning()
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_painter_command-members.html b/ThirdParty/Qwt/doc/html/class_qwt_painter_command-members.html new file mode 100644 index 0000000000..4c25c7bc80 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_painter_command-members.html @@ -0,0 +1,127 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtPainterCommand Member List
+
+
+ +

This is the complete list of members for QwtPainterCommand, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
d_imageData (defined in QwtPainterCommand)QwtPainterCommand
d_path (defined in QwtPainterCommand)QwtPainterCommand
d_pixmapData (defined in QwtPainterCommand)QwtPainterCommand
d_stateData (defined in QwtPainterCommand)QwtPainterCommand
Image enum valueQwtPainterCommand
imageData()QwtPainterCommand
imageData() const QwtPainterCommandinline
Invalid enum valueQwtPainterCommand
operator=(const QwtPainterCommand &)QwtPainterCommand
path()QwtPainterCommand
path() const QwtPainterCommandinline
Path enum valueQwtPainterCommand
Pixmap enum valueQwtPainterCommand
pixmapData()QwtPainterCommand
pixmapData() const QwtPainterCommandinline
QwtPainterCommand()QwtPainterCommand
QwtPainterCommand(const QwtPainterCommand &)QwtPainterCommand
QwtPainterCommand(const QPainterPath &)QwtPainterCommand
QwtPainterCommand(const QRectF &rect, const QPixmap &, const QRectF &subRect)QwtPainterCommand
QwtPainterCommand(const QRectF &rect, const QImage &, const QRectF &subRect, Qt::ImageConversionFlags)QwtPainterCommand
QwtPainterCommand(const QPaintEngineState &)QwtPainterCommand
State enum valueQwtPainterCommand
stateData()QwtPainterCommand
stateData() const QwtPainterCommandinline
Type enum nameQwtPainterCommand
type() const QwtPainterCommandinline
~QwtPainterCommand()QwtPainterCommand
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_painter_command.html b/ThirdParty/Qwt/doc/html/class_qwt_painter_command.html new file mode 100644 index 0000000000..531c177d97 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_painter_command.html @@ -0,0 +1,557 @@ + + + + + + +Qwt User's Guide: QwtPainterCommand Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtPainterCommand Class Reference
+
+
+ +

#include <qwt_painter_command.h>

+ + + + + + + + + + + +

+Classes

struct  ImageData
 Attributes how to paint a QImage.
 
struct  PixmapData
 Attributes how to paint a QPixmap.
 
struct  StateData
 Attributes of a state change.
 
+ + + + +

+Public Types

enum  Type {
+  Invalid = -1, +Path, +Pixmap, +Image, +
+  State +
+ }
 Type of the paint command. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

QwtPainterCommand ()
 Construct an invalid command.
 
 QwtPainterCommand (const QwtPainterCommand &)
 
QwtPainterCommand (const QPainterPath &)
 Copy constructor.
 
 QwtPainterCommand (const QRectF &rect, const QPixmap &, const QRectF &subRect)
 
 QwtPainterCommand (const QRectF &rect, const QImage &, const QRectF &subRect, Qt::ImageConversionFlags)
 
 QwtPainterCommand (const QPaintEngineState &)
 
~QwtPainterCommand ()
 Destructor.
 
QwtPainterCommandoperator= (const QwtPainterCommand &)
 
Type type () const
 
QPainterPath * path ()
 
const QPainterPath * path () const
 
PixmapData * pixmapData ()
 
const PixmapData * pixmapData () const
 
ImageData * imageData ()
 
const ImageData * imageData () const
 
StateData * stateData ()
 
const StateData * stateData () const
 
+

Detailed Description

+

QwtPainterCommand represents the attributes of a paint operation how it is used between QPainter and QPaintDevice

+

It is used by QwtGraphic to record and replay paint operations

+
See Also
QwtGraphic::commands()
+

Member Enumeration Documentation

+ +
+
+ + + + +
enum QwtPainterCommand::Type
+
+ +

Type of the paint command.

+ + + + + + +
Enumerator
Invalid  +

Invalid command.

+
Path  +

Draw a QPainterPath.

+
Pixmap  +

Draw a QPixmap.

+
Image  +

Draw a QImage.

+
State  +

QPainter state change.

+
+ +
+
+

Constructor & Destructor Documentation

+ +
+
+ + + + + + + + +
QwtPainterCommand::QwtPainterCommand (const QwtPainterCommandother)
+
+

Copy constructor

+
Parameters
+ + +
otherCommand to be copied
+
+
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
QwtPainterCommand::QwtPainterCommand (const QRectF & rect,
const QPixmap & pixmap,
const QRectF & subRect 
)
+
+

Constructor for Pixmap paint operation

+
Parameters
+ + + + +
rectTarget rectangle
pixmapPixmap
subRectRectangle inside the pixmap
+
+
+
See Also
QPainter::drawPixmap()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
QwtPainterCommand::QwtPainterCommand (const QRectF & rect,
const QImage & image,
const QRectF & subRect,
Qt::ImageConversionFlags flags 
)
+
+

Constructor for Image paint operation

+
Parameters
+ + + + + +
rectTarget rectangle
imageImage
subRectRectangle inside the image
flagsConversion flags
+
+
+
See Also
QPainter::drawImage()
+ +
+
+ +
+
+ + + + + + + + +
QwtPainterCommand::QwtPainterCommand (const QPaintEngineState & state)
+
+

Constructor for State paint operation

+
Parameters
+ + +
statePaint engine state
+
+
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + + + +
QwtPainterCommand::ImageData * QwtPainterCommand::imageData ()
+
+
Returns
Attributes how to paint a QImage
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
const QwtPainterCommand::ImageData * QwtPainterCommand::imageData () const
+
+inline
+
+
Returns
Attributes how to paint a QImage
+ +
+
+ +
+
+ + + + + + + + +
QwtPainterCommand & QwtPainterCommand::operator= (const QwtPainterCommandother)
+
+

Assignment operator

+
Parameters
+ + +
otherCommand to be copied
+
+
+
Returns
Modified command
+ +
+
+ +
+
+ + + + + + + +
QPainterPath * QwtPainterCommand::path ()
+
+
Returns
Painter path to be painted
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
const QPainterPath * QwtPainterCommand::path () const
+
+inline
+
+
Returns
Painter path to be painted
+ +
+
+ +
+
+ + + + + + + +
QwtPainterCommand::PixmapData * QwtPainterCommand::pixmapData ()
+
+
Returns
Attributes how to paint a QPixmap
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
const QwtPainterCommand::PixmapData * QwtPainterCommand::pixmapData () const
+
+inline
+
+
Returns
Attributes how to paint a QPixmap
+ +
+
+ +
+
+ + + + + + + +
QwtPainterCommand::StateData * QwtPainterCommand::stateData ()
+
+
Returns
Attributes of a state change
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
const QwtPainterCommand::StateData * QwtPainterCommand::stateData () const
+
+inline
+
+
Returns
Attributes of a state change
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
QwtPainterCommand::Type QwtPainterCommand::type () const
+
+inline
+
+
Returns
Type of the command
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_panner-members.html b/ThirdParty/Qwt/doc/html/class_qwt_panner-members.html new file mode 100644 index 0000000000..9c43af324a --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_panner-members.html @@ -0,0 +1,124 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtPanner Member List
+
+
+ +

This is the complete list of members for QwtPanner, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
contentsMask() const QwtPannerprotectedvirtual
cursor() const QwtPanner
eventFilter(QObject *, QEvent *)QwtPannervirtual
getAbortKey(int &key, Qt::KeyboardModifiers &) const QwtPanner
getMouseButton(Qt::MouseButton &button, Qt::KeyboardModifiers &) const QwtPanner
grab() const QwtPannerprotectedvirtual
isEnabled() const QwtPanner
isOrientationEnabled(Qt::Orientation) const QwtPanner
moved(int dx, int dy)QwtPannersignal
orientations() const QwtPanner
paintEvent(QPaintEvent *)QwtPannerprotectedvirtual
panned(int dx, int dy)QwtPannersignal
QwtPanner(QWidget *parent)QwtPanner
setAbortKey(int key, Qt::KeyboardModifiers=Qt::NoModifier)QwtPanner
setCursor(const QCursor &)QwtPanner
setEnabled(bool)QwtPanner
setMouseButton(Qt::MouseButton, Qt::KeyboardModifiers=Qt::NoModifier)QwtPanner
setOrientations(Qt::Orientations)QwtPanner
widgetKeyPressEvent(QKeyEvent *)QwtPannerprotectedvirtual
widgetKeyReleaseEvent(QKeyEvent *)QwtPannerprotectedvirtual
widgetMouseMoveEvent(QMouseEvent *)QwtPannerprotectedvirtual
widgetMousePressEvent(QMouseEvent *)QwtPannerprotectedvirtual
widgetMouseReleaseEvent(QMouseEvent *)QwtPannerprotectedvirtual
~QwtPanner()QwtPannervirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_panner.html b/ThirdParty/Qwt/doc/html/class_qwt_panner.html new file mode 100644 index 0000000000..670fdf5a33 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_panner.html @@ -0,0 +1,774 @@ + + + + + + +Qwt User's Guide: QwtPanner Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+ +
+ +

QwtPanner provides panning of a widget. + More...

+ +

#include <qwt_panner.h>

+
+Inheritance diagram for QwtPanner:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + +

+Signals

void panned (int dx, int dy)
 
void moved (int dx, int dy)
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 QwtPanner (QWidget *parent)
 
+virtual ~QwtPanner ()
 Destructor.
 
void setEnabled (bool)
 En/disable the panner. More...
 
bool isEnabled () const
 
void setMouseButton (Qt::MouseButton, Qt::KeyboardModifiers=Qt::NoModifier)
 
+void getMouseButton (Qt::MouseButton &button, Qt::KeyboardModifiers &) const
 Get mouse button and modifiers used for panning.
 
void setAbortKey (int key, Qt::KeyboardModifiers=Qt::NoModifier)
 
+void getAbortKey (int &key, Qt::KeyboardModifiers &) const
 Get the abort key and modifiers.
 
void setCursor (const QCursor &)
 
const QCursor cursor () const
 
void setOrientations (Qt::Orientations)
 
+Qt::Orientations orientations () const
 Return the orientation, where paning is enabled.
 
bool isOrientationEnabled (Qt::Orientation) const
 
virtual bool eventFilter (QObject *, QEvent *)
 Event filter. More...
 
+ + + + + + + + + + + + + + + + + + + +

+Protected Member Functions

virtual void widgetMousePressEvent (QMouseEvent *)
 
virtual void widgetMouseReleaseEvent (QMouseEvent *)
 
virtual void widgetMouseMoveEvent (QMouseEvent *)
 
virtual void widgetKeyPressEvent (QKeyEvent *)
 
virtual void widgetKeyReleaseEvent (QKeyEvent *)
 
virtual void paintEvent (QPaintEvent *)
 Paint event. More...
 
virtual QBitmap contentsMask () const
 Calculate a mask for the contents of the panned widget. More...
 
virtual QPixmap grab () const
 
+

Detailed Description

+

QwtPanner provides panning of a widget.

+

QwtPanner grabs the contents of a widget, that can be dragged in all directions. The offset between the start and the end position is emitted by the panned signal.

+

QwtPanner grabs the content of the widget into a pixmap and moves the pixmap around, without initiating any repaint events for the widget. Areas, that are not part of content are not painted while panning. This makes panning fast enough for widgets, where repaints are too slow for mouse movements.

+

For widgets, where repaints are very fast it might be better to implement panning manually by mapping mouse events into paint events.

+

Constructor & Destructor Documentation

+ +
+
+ + + + + + + + +
QwtPanner::QwtPanner (QWidget * parent)
+
+

Creates an panner that is enabled for the left mouse button.

+
Parameters
+ + +
parentParent widget to be panned
+
+
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + +
QBitmap QwtPanner::contentsMask () const
+
+protectedvirtual
+
+ +

Calculate a mask for the contents of the panned widget.

+

Sometimes only parts of the contents of a widget should be panned. F.e. for a widget with a styled background with rounded borders only the area inside of the border should be panned.

+
Returns
An empty bitmap, indicating no mask
+ +

Reimplemented in QwtPlotPanner.

+ +
+
+ +
+
+ + + + + + + +
const QCursor QwtPanner::cursor () const
+
+
Returns
Cursor that is active while panning
+
See Also
setCursor()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool QwtPanner::eventFilter (QObject * object,
QEvent * event 
)
+
+virtual
+
+ +

Event filter.

+

When isEnabled() is true mouse events of the observed widget are filtered.

+
Parameters
+ + + +
objectObject to be filtered
eventEvent
+
+
+
Returns
Always false, beside for paint events for the parent widget.
+
See Also
widgetMousePressEvent(), widgetMouseReleaseEvent(), widgetMouseMoveEvent()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
QPixmap QwtPanner::grab () const
+
+protectedvirtual
+
+

Grab the widget into a pixmap.

+
Returns
Grabbed pixmap
+ +

Reimplemented in QwtPlotPanner.

+ +
+
+ +
+
+ + + + + + + +
bool QwtPanner::isEnabled () const
+
+
Returns
true when enabled, false otherwise
+
See Also
setEnabled, eventFilter()
+ +
+
+ +
+
+ + + + + + + + +
bool QwtPanner::isOrientationEnabled (Qt::Orientation o) const
+
+
Returns
True if an orientation is enabled
+
See Also
orientations(), setOrientations()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void QwtPanner::moved (int dx,
int dy 
)
+
+signal
+
+

Signal emitted, while the widget moved, but panning is not finished.

+
Parameters
+ + + +
dxOffset in horizontal direction
dyOffset in vertical direction
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtPanner::paintEvent (QPaintEvent * pe)
+
+protectedvirtual
+
+ +

Paint event.

+

Repaint the grabbed pixmap on its current position and fill the empty spaces by the background of the parent widget.

+
Parameters
+ + +
pePaint event
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void QwtPanner::panned (int dx,
int dy 
)
+
+signal
+
+

Signal emitted, when panning is done

+
Parameters
+ + + +
dxOffset in horizontal direction
dyOffset in vertical direction
+
+
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtPanner::setAbortKey (int key,
Qt::KeyboardModifiers modifiers = Qt::NoModifier 
)
+
+

Change the abort key The defaults are Qt::Key_Escape and Qt::NoModifiers

+
Parameters
+ + + +
keyKey ( See Qt::Keycode )
modifiersKeyboard modifiers
+
+
+ +
+
+ +
+
+ + + + + + + + +
void QwtPanner::setCursor (const QCursor & cursor)
+
+

Change the cursor, that is active while panning The default is the cursor of the parent widget.

+
Parameters
+ + +
cursorNew cursor
+
+
+
See Also
setCursor()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPanner::setEnabled (bool on)
+
+ +

En/disable the panner.

+

When enabled is true an event filter is installed for the observed widget, otherwise the event filter is removed.

+
Parameters
+ + +
ontrue or false
+
+
+
See Also
isEnabled(), eventFilter()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtPanner::setMouseButton (Qt::MouseButton button,
Qt::KeyboardModifiers modifiers = Qt::NoModifier 
)
+
+

Change the mouse button and modifiers used for panning The defaults are Qt::LeftButton and Qt::NoModifier

+ +
+
+ +
+
+ + + + + + + + +
void QwtPanner::setOrientations (Qt::Orientations o)
+
+

Set the orientations, where panning is enabled The default value is in both directions: Qt::Horizontal | Qt::Vertical

+

/param o Orientation

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtPanner::widgetKeyPressEvent (QKeyEvent * keyEvent)
+
+protectedvirtual
+
+

Handle a key press event for the observed widget.

+
Parameters
+ + +
keyEventKey event
+
+
+
See Also
eventFilter(), widgetKeyReleaseEvent()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtPanner::widgetKeyReleaseEvent (QKeyEvent * keyEvent)
+
+protectedvirtual
+
+

Handle a key release event for the observed widget.

+
Parameters
+ + +
keyEventKey event
+
+
+
See Also
eventFilter(), widgetKeyReleaseEvent()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtPanner::widgetMouseMoveEvent (QMouseEvent * mouseEvent)
+
+protectedvirtual
+
+

Handle a mouse move event for the observed widget.

+
Parameters
+ + +
mouseEventMouse event
+
+
+
See Also
eventFilter(), widgetMousePressEvent(), widgetMouseReleaseEvent()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtPanner::widgetMousePressEvent (QMouseEvent * mouseEvent)
+
+protectedvirtual
+
+

Handle a mouse press event for the observed widget.

+
Parameters
+ + +
mouseEventMouse event
+
+
+
See Also
eventFilter(), widgetMouseReleaseEvent(), widgetMouseMoveEvent(),
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtPanner::widgetMouseReleaseEvent (QMouseEvent * mouseEvent)
+
+protectedvirtual
+
+

Handle a mouse release event for the observed widget.

+
Parameters
+ + +
mouseEventMouse event
+
+
+
See Also
eventFilter(), widgetMousePressEvent(), widgetMouseMoveEvent(),
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_panner__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_panner__inherit__graph.map new file mode 100644 index 0000000000..6c4bd5aea8 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_panner__inherit__graph.map @@ -0,0 +1,3 @@ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_panner__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_panner__inherit__graph.md5 new file mode 100644 index 0000000000..7b1ca1b9ce --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_panner__inherit__graph.md5 @@ -0,0 +1 @@ +ad62a46abb0b2f6f09862b3f96d83ba6 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_panner__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_panner__inherit__graph.png new file mode 100644 index 0000000000..65c0b9e2ab Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_panner__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_picker-members.html b/ThirdParty/Qwt/doc/html/class_qwt_picker-members.html new file mode 100644 index 0000000000..6a9baad08b --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_picker-members.html @@ -0,0 +1,213 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtPicker Member List
+
+
+ +

This is the complete list of members for QwtPicker, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
accept(QPolygon &) const QwtPickerprotectedvirtual
activated(bool on)QwtPickersignal
ActiveOnly enum valueQwtPicker
adjustedPoints(const QPolygon &) const QwtPickerprotectedvirtual
AlwaysOff enum valueQwtPicker
AlwaysOn enum valueQwtPicker
append(const QPoint &)QwtPickerprotectedvirtual
appended(const QPoint &pos)QwtPickersignal
begin()QwtPickerprotectedvirtual
changed(const QPolygon &selection)QwtPickersignal
CrossRubberBand enum valueQwtPicker
DisplayMode enum nameQwtPicker
drawRubberBand(QPainter *) const QwtPickervirtual
drawTracker(QPainter *) const QwtPickervirtual
EllipseRubberBand enum valueQwtPicker
end(bool ok=true)QwtPickerprotectedvirtual
eventFilter(QObject *, QEvent *)QwtPickervirtual
HLineRubberBand enum valueQwtPicker
initKeyPattern()QwtEventPattern
initMousePattern(int numButtons)QwtEventPattern
isActive() const QwtPicker
isEnabled() const QwtPicker
KeepSize enum valueQwtPicker
KeyAbort enum valueQwtEventPattern
KeyDown enum valueQwtEventPattern
KeyHome enum valueQwtEventPattern
KeyLeft enum valueQwtEventPattern
keyMatch(KeyPatternCode, const QKeyEvent *) const QwtEventPattern
keyMatch(const KeyPattern &, const QKeyEvent *) const QwtEventPatternprotectedvirtual
keyPattern() const QwtEventPattern
keyPattern()QwtEventPattern
KeyPatternCode enum nameQwtEventPattern
KeyPatternCount enum valueQwtEventPattern
KeyRedo enum valueQwtEventPattern
KeyRight enum valueQwtEventPattern
KeySelect1 enum valueQwtEventPattern
KeySelect2 enum valueQwtEventPattern
KeyUndo enum valueQwtEventPattern
KeyUp enum valueQwtEventPattern
mouseMatch(MousePatternCode, const QMouseEvent *) const QwtEventPattern
mouseMatch(const MousePattern &, const QMouseEvent *) const QwtEventPatternprotectedvirtual
mousePattern() const QwtEventPattern
mousePattern()QwtEventPattern
MousePatternCode enum nameQwtEventPattern
MousePatternCount enum valueQwtEventPattern
MouseSelect1 enum valueQwtEventPattern
MouseSelect2 enum valueQwtEventPattern
MouseSelect3 enum valueQwtEventPattern
MouseSelect4 enum valueQwtEventPattern
MouseSelect5 enum valueQwtEventPattern
MouseSelect6 enum valueQwtEventPattern
move(const QPoint &)QwtPickerprotectedvirtual
moved(const QPoint &pos)QwtPickersignal
NoRubberBand enum valueQwtPicker
parentWidget()QwtPicker
parentWidget() const QwtPicker
pickArea() const QwtPickervirtual
pickedPoints() const QwtPickerprotected
PolygonRubberBand enum valueQwtPicker
QwtEventPattern()QwtEventPattern
QwtPicker(QWidget *parent)QwtPickerexplicit
QwtPicker(RubberBand rubberBand, DisplayMode trackerMode, QWidget *)QwtPickerexplicit
RectRubberBand enum valueQwtPicker
remove()QwtPickerprotectedvirtual
removed(const QPoint &pos)QwtPickersignal
reset()QwtPickerprotectedvirtual
resizeMode() const QwtPicker
ResizeMode enum nameQwtPicker
RubberBand enum nameQwtPicker
rubberBand() const QwtPicker
rubberBandMask() const QwtPickervirtual
rubberBandOverlay() const QwtPickerprotected
rubberBandPen() const QwtPicker
selected(const QPolygon &polygon)QwtPickersignal
selection() const QwtPicker
setEnabled(bool)QwtPickerslot
setKeyPattern(KeyPatternCode, int keyCode, Qt::KeyboardModifiers modifierCodes=Qt::NoModifier)QwtEventPattern
setKeyPattern(const QVector< KeyPattern > &)QwtEventPattern
setMousePattern(MousePatternCode, Qt::MouseButton button, Qt::KeyboardModifiers=Qt::NoModifier)QwtEventPattern
setMousePattern(const QVector< MousePattern > &)QwtEventPattern
setResizeMode(ResizeMode)QwtPicker
setRubberBand(RubberBand)QwtPicker
setRubberBandPen(const QPen &)QwtPicker
setStateMachine(QwtPickerMachine *)QwtPicker
setTrackerFont(const QFont &)QwtPicker
setTrackerMode(DisplayMode)QwtPicker
setTrackerPen(const QPen &)QwtPicker
stateMachine() const QwtPicker
stateMachine()QwtPicker
Stretch enum valueQwtPicker
stretchSelection(const QSize &oldSize, const QSize &newSize)QwtPickerprotectedvirtual
trackerFont() const QwtPicker
trackerMode() const QwtPicker
trackerOverlay() const QwtPickerprotected
trackerPen() const QwtPicker
trackerPosition() const QwtPicker
trackerRect(const QFont &) const QwtPickervirtual
trackerText(const QPoint &pos) const QwtPickervirtual
transition(const QEvent *)QwtPickerprotectedvirtual
updateDisplay()QwtPickerprotectedvirtual
UserRubberBand enum valueQwtPicker
VLineRubberBand enum valueQwtPicker
widgetEnterEvent(QEvent *)QwtPickerprotectedvirtual
widgetKeyPressEvent(QKeyEvent *)QwtPickerprotectedvirtual
widgetKeyReleaseEvent(QKeyEvent *)QwtPickerprotectedvirtual
widgetLeaveEvent(QEvent *)QwtPickerprotectedvirtual
widgetMouseDoubleClickEvent(QMouseEvent *)QwtPickerprotectedvirtual
widgetMouseMoveEvent(QMouseEvent *)QwtPickerprotectedvirtual
widgetMousePressEvent(QMouseEvent *)QwtPickerprotectedvirtual
widgetMouseReleaseEvent(QMouseEvent *)QwtPickerprotectedvirtual
widgetWheelEvent(QWheelEvent *)QwtPickerprotectedvirtual
~QwtEventPattern()QwtEventPatternvirtual
~QwtPicker()QwtPickervirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_picker.html b/ThirdParty/Qwt/doc/html/class_qwt_picker.html new file mode 100644 index 0000000000..67a70242ab --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_picker.html @@ -0,0 +1,2137 @@ + + + + + + +Qwt User's Guide: QwtPicker Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+ +
+ +

QwtPicker provides selections on a widget. + More...

+ +

#include <qwt_picker.h>

+
+Inheritance diagram for QwtPicker:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + + + + + + + + + +

+Public Types

enum  RubberBand {
+  NoRubberBand = 0, +HLineRubberBand, +VLineRubberBand, +CrossRubberBand, +
+  RectRubberBand, +EllipseRubberBand, +PolygonRubberBand, +UserRubberBand = 100 +
+ }
 
enum  DisplayMode { AlwaysOff, +AlwaysOn, +ActiveOnly + }
 Display mode. More...
 
enum  ResizeMode { Stretch, +KeepSize + }
 
- Public Types inherited from QwtEventPattern
enum  MousePatternCode {
+  MouseSelect1, +MouseSelect2, +MouseSelect3, +MouseSelect4, +
+  MouseSelect5, +MouseSelect6, +MousePatternCount +
+ }
 Symbolic mouse input codes. More...
 
enum  KeyPatternCode {
+  KeySelect1, +KeySelect2, +KeyAbort, +KeyLeft, +
+  KeyRight, +KeyUp, +KeyDown, +KeyRedo, +
+  KeyUndo, +KeyHome, +KeyPatternCount +
+ }
 Symbolic keyboard input codes. More...
 
+ + + + +

+Public Slots

void setEnabled (bool)
 En/disable the picker. More...
 
+ + + + + + + + + + + + + +

+Signals

void activated (bool on)
 
void selected (const QPolygon &polygon)
 
void appended (const QPoint &pos)
 
void moved (const QPoint &pos)
 
void removed (const QPoint &pos)
 
void changed (const QPolygon &selection)
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 QwtPicker (QWidget *parent)
 
 QwtPicker (RubberBand rubberBand, DisplayMode trackerMode, QWidget *)
 
+virtual ~QwtPicker ()
 Destructor.
 
void setStateMachine (QwtPickerMachine *)
 
const QwtPickerMachinestateMachine () const
 
QwtPickerMachinestateMachine ()
 
void setRubberBand (RubberBand)
 
RubberBand rubberBand () const
 
void setTrackerMode (DisplayMode)
 Set the display mode of the tracker. More...
 
DisplayMode trackerMode () const
 
void setResizeMode (ResizeMode)
 Set the resize mode. More...
 
ResizeMode resizeMode () const
 
void setRubberBandPen (const QPen &)
 
QPen rubberBandPen () const
 
void setTrackerPen (const QPen &)
 
QPen trackerPen () const
 
void setTrackerFont (const QFont &)
 
QFont trackerFont () const
 
bool isEnabled () const
 
bool isActive () const
 
virtual bool eventFilter (QObject *, QEvent *)
 Event filter. More...
 
+QWidget * parentWidget ()
 Return the parent widget, where the selection happens.
 
+const QWidget * parentWidget () const
 Return the parent widget, where the selection happens.
 
virtual QPainterPath pickArea () const
 
virtual void drawRubberBand (QPainter *) const
 
virtual void drawTracker (QPainter *) const
 
virtual QRegion rubberBandMask () const
 
virtual QwtText trackerText (const QPoint &pos) const
 Return the label for a position. More...
 
QPoint trackerPosition () const
 
virtual QRect trackerRect (const QFont &) const
 
QPolygon selection () const
 
- Public Member Functions inherited from QwtEventPattern
 QwtEventPattern ()
 
+virtual ~QwtEventPattern ()
 Destructor.
 
void initMousePattern (int numButtons)
 
void initKeyPattern ()
 
void setMousePattern (MousePatternCode, Qt::MouseButton button, Qt::KeyboardModifiers=Qt::NoModifier)
 
void setKeyPattern (KeyPatternCode, int keyCode, Qt::KeyboardModifiers modifierCodes=Qt::NoModifier)
 
+void setMousePattern (const QVector< MousePattern > &)
 Change the mouse event patterns.
 
+void setKeyPattern (const QVector< KeyPattern > &)
 Change the key event patterns.
 
const QVector< MousePattern > & mousePattern () const
 
const QVector< KeyPattern > & keyPattern () const
 
QVector< MousePattern > & mousePattern ()
 
QVector< KeyPattern > & keyPattern ()
 
bool mouseMatch (MousePatternCode, const QMouseEvent *) const
 Compare a mouse event with an event pattern. More...
 
bool keyMatch (KeyPatternCode, const QKeyEvent *) const
 Compare a key event with an event pattern. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Protected Member Functions

virtual QPolygon adjustedPoints (const QPolygon &) const
 Map the pickedPoints() into a selection() More...
 
virtual void transition (const QEvent *)
 
virtual void begin ()
 
virtual void append (const QPoint &)
 
virtual void move (const QPoint &)
 
virtual void remove ()
 
virtual bool end (bool ok=true)
 Close a selection setting the state to inactive. More...
 
virtual bool accept (QPolygon &) const
 Validate and fix up the selection. More...
 
virtual void reset ()
 
virtual void widgetMousePressEvent (QMouseEvent *)
 
virtual void widgetMouseReleaseEvent (QMouseEvent *)
 
virtual void widgetMouseDoubleClickEvent (QMouseEvent *)
 
virtual void widgetMouseMoveEvent (QMouseEvent *)
 
virtual void widgetWheelEvent (QWheelEvent *)
 
virtual void widgetKeyPressEvent (QKeyEvent *)
 
virtual void widgetKeyReleaseEvent (QKeyEvent *)
 
virtual void widgetEnterEvent (QEvent *)
 
virtual void widgetLeaveEvent (QEvent *)
 
virtual void stretchSelection (const QSize &oldSize, const QSize &newSize)
 
+virtual void updateDisplay ()
 Update the state of rubber band and tracker label.
 
const QwtWidgetOverlayrubberBandOverlay () const
 
const QwtWidgetOverlaytrackerOverlay () const
 
const QPolygon & pickedPoints () const
 
- Protected Member Functions inherited from QwtEventPattern
virtual bool mouseMatch (const MousePattern &, const QMouseEvent *) const
 Compare a mouse event with an event pattern. More...
 
virtual bool keyMatch (const KeyPattern &, const QKeyEvent *) const
 Compare a key event with an event pattern. More...
 
+

Detailed Description

+

QwtPicker provides selections on a widget.

+

QwtPicker filters all enter, leave, mouse and keyboard events of a widget and translates them into an array of selected points.

+

The way how the points are collected depends on type of state machine that is connected to the picker. Qwt offers a couple of predefined state machines for selecting:

+ +

While these state machines cover the most common ways to collect points it is also possible to implement individual machines as well.

+

QwtPicker translates the picked points into a selection using the adjustedPoints() method. adjustedPoints() is intended to be reimplemented to fix up the selection according to application specific requirements. (F.e. when an application accepts rectangles of a fixed aspect ratio only.)

+

Optionally QwtPicker support the process of collecting points by a rubber band and tracker displaying a text for the current mouse position.

+
Example
#include <qwt_picker.h>
+#include <qwt_picker_machine.h>
+
+QwtPicker *picker = new QwtPicker(widget);
+picker->setStateMachine(new QwtPickerDragRectMachine);
+picker->setTrackerMode(QwtPicker::ActiveOnly);
+picker->setRubberBand(QwtPicker::RectRubberBand); 

+
+

The state machine triggers the following commands:

+
    +
  • begin()
    + Activate/Initialize the selection.
  • +
  • append()
    + Add a new point
  • +
  • move()
    + Change the position of the last point.
  • +
  • remove()
    + Remove the last point.
  • +
  • end()
    + Terminate the selection and call accept to validate the picked points.
  • +
+

The picker is active (isActive()), between begin() and end(). In active state the rubber band is displayed, and the tracker is visible in case of trackerMode is ActiveOnly or AlwaysOn.

+

The cursor can be moved using the arrow keys. All selections can be aborted using the abort key. (QwtEventPattern::KeyPatternCode)

+
Warning
In case of QWidget::NoFocus the focus policy of the observed widget is set to QWidget::WheelFocus and mouse tracking will be manipulated while the picker is active, or if trackerMode() is AlwayOn.
+

Member Enumeration Documentation

+ +
+
+ + + + +
enum QwtPicker::DisplayMode
+
+ +

Display mode.

+
See Also
setTrackerMode(), trackerMode(), isActive()
+ + + + +
Enumerator
AlwaysOff  +

Display never.

+
AlwaysOn  +

Display always.

+
ActiveOnly  +

Display only when the selection is active.

+
+ +
+
+ +
+
+ + + + +
enum QwtPicker::ResizeMode
+
+

Controls what to do with the selected points of an active selection when the observed widget is resized.

+

The default value is QwtPicker::Stretch.

+
See Also
setResizeMode()
+ + + +
Enumerator
Stretch  +

All points are scaled according to the new size,.

+
KeepSize  +

All points remain unchanged.

+
+ +
+
+ +
+
+ + + + +
enum QwtPicker::RubberBand
+
+

Rubber band style

+

The default value is QwtPicker::NoRubberBand.

+
See Also
setRubberBand(), rubberBand()
+ + + + + + + + + +
Enumerator
NoRubberBand  +

No rubberband.

+
HLineRubberBand  +

A horizontal line ( only for QwtPickerMachine::PointSelection )

+
VLineRubberBand  +

A vertical line ( only for QwtPickerMachine::PointSelection )

+
CrossRubberBand  +

A crosshair ( only for QwtPickerMachine::PointSelection )

+
RectRubberBand  +

A rectangle ( only for QwtPickerMachine::RectSelection )

+
EllipseRubberBand  +

An ellipse ( only for QwtPickerMachine::RectSelection )

+
PolygonRubberBand  +

A polygon ( only for QwtPickerMachine::PolygonSelection )

+
UserRubberBand  +

Values >= UserRubberBand can be used to define additional rubber bands.

+
+ +
+
+

Constructor & Destructor Documentation

+ +
+
+ + + + + +
+ + + + + + + + +
QwtPicker::QwtPicker (QWidget * parent)
+
+explicit
+
+

Constructor

+

Creates an picker that is enabled, but without a state machine. rubber band and tracker are disabled.

+
Parameters
+ + +
parentParent widget, that will be observed
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
QwtPicker::QwtPicker (RubberBand rubberBand,
DisplayMode trackerMode,
QWidget * parent 
)
+
+explicit
+
+

Constructor

+
Parameters
+ + + + +
rubberBandRubber band style
trackerModeTracker mode
parentParent widget, that will be observed
+
+
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + + +
bool QwtPicker::accept (QPolygon & selection) const
+
+protectedvirtual
+
+ +

Validate and fix up the selection.

+

Accepts all selections unmodified

+
Parameters
+ + +
selectionSelection to validate and fix up
+
+
+
Returns
true, when accepted, false otherwise
+ +

Reimplemented in QwtPlotZoomer.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtPicker::activated (bool on)
+
+signal
+
+

A signal indicating, when the picker has been activated. Together with setEnabled() it can be used to implement selections with more than one picker.

+
Parameters
+ + +
onTrue, when the picker has been activated
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
QPolygon QwtPicker::adjustedPoints (const QPolygon & points) const
+
+protectedvirtual
+
+ +

Map the pickedPoints() into a selection()

+

adjustedPoints() maps the points, that have been collected on the parentWidget() into a selection(). The default implementation simply returns the points unmodified.

+

The reason, why a selection() differs from the picked points depends on the application requirements. F.e. :

+
    +
  • A rectangular selection might need to have a specific aspect ratio only.
    +
  • +
  • A selection could accept non intersecting polygons only.
    +
  • +
  • ...
    +
  • +
+

The example below is for a rectangular selection, where the first point is the center of the selected rectangle.

+
Example
QPolygon MyPicker::adjustedPoints(const QPolygon &points) const
+{
+    QPolygon adjusted;
+    if ( points.size() == 2 )
+    {
+        const int width = qAbs(points[1].x() - points[0].x());
+        const int height = qAbs(points[1].y() - points[0].y());
+
+        QRect rect(0, 0, 2 * width, 2 * height);
+        rect.moveCenter(points[0]);
+
+        adjusted += rect.topLeft();
+        adjusted += rect.bottomRight();
+    }
+    return adjusted;
+}

+
+
Parameters
+ + +
pointsSelected points
+
+
+
Returns
Selected points unmodified
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtPicker::append (const QPoint & pos)
+
+protectedvirtual
+
+

Append a point to the selection and update rubber band and tracker. The appended() signal is emitted.

+
Parameters
+ + +
posAdditional point
+
+
+
See Also
isActive(), begin(), end(), move(), appended()
+ +

Reimplemented in QwtPlotPicker.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtPicker::appended (const QPoint & pos)
+
+signal
+
+

A signal emitted when a point has been appended to the selection

+
Parameters
+ + +
posPosition of the appended point.
+
+
+
See Also
append(). moved()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void QwtPicker::begin ()
+
+protectedvirtual
+
+

Open a selection setting the state to active

+
See Also
isActive(), end(), append(), move()
+ +

Reimplemented in QwtPlotZoomer.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtPicker::changed (const QPolygon & selection)
+
+signal
+
+

A signal emitted when the active selection has been changed. This might happen when the observed widget is resized.

+
Parameters
+ + +
selectionChanged selection
+
+
+
See Also
stretchSelection()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtPicker::drawRubberBand (QPainter * painter) const
+
+virtual
+
+

Draw a rubber band, depending on rubberBand()

+
Parameters
+ + +
painterPainter, initialized with a clip region
+
+
+
See Also
rubberBand(), RubberBand
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtPicker::drawTracker (QPainter * painter) const
+
+virtual
+
+

Draw the tracker

+
Parameters
+ + +
painterPainter
+
+
+
See Also
trackerRect(), trackerText()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool QwtPicker::end (bool ok = true)
+
+protectedvirtual
+
+ +

Close a selection setting the state to inactive.

+

The selection is validated and maybe fixed by accept().

+
Parameters
+ + +
okIf true, complete the selection and emit a selected signal otherwise discard the selection.
+
+
+
Returns
true if the selection is accepted, false otherwise
+
See Also
isActive(), begin(), append(), move(), selected(), accept()
+ +

Reimplemented in QwtPlotZoomer, and QwtPlotPicker.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool QwtPicker::eventFilter (QObject * object,
QEvent * event 
)
+
+virtual
+
+ +

Event filter.

+

When isEnabled() is true all events of the observed widget are filtered. Mouse and keyboard events are translated into widgetMouse- and widgetKey- and widgetWheel-events. Paint and Resize events are handled to keep rubber band and tracker up to date.

+
Parameters
+ + + +
objectObject to be filtered
eventEvent
+
+
+
Returns
Always false.
+
See Also
widgetEnterEvent(), widgetLeaveEvent(), widgetMousePressEvent(), widgetMouseReleaseEvent(), widgetMouseDoubleClickEvent(), widgetMouseMoveEvent(), widgetWheelEvent(), widgetKeyPressEvent(), widgetKeyReleaseEvent(), QObject::installEventFilter(), QObject::event()
+ +
+
+ +
+
+ + + + + + + +
bool QwtPicker::isActive () const
+
+

A picker is active between begin() and end().

+
Returns
true if the selection is active.
+ +
+
+ +
+
+ + + + + + + +
bool QwtPicker::isEnabled () const
+
+
Returns
true when enabled, false otherwise
+
See Also
setEnabled(), eventFilter()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtPicker::move (const QPoint & pos)
+
+protectedvirtual
+
+

Move the last point of the selection The moved() signal is emitted.

+
Parameters
+ + +
posNew position
+
+
+
See Also
isActive(), begin(), end(), append()
+ +

Reimplemented in QwtPlotPicker.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtPicker::moved (const QPoint & pos)
+
+signal
+
+

A signal emitted whenever the last appended point of the selection has been moved.

+
Parameters
+ + +
posPosition of the moved last point of the selection.
+
+
+
See Also
move(), appended()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
QPainterPath QwtPicker::pickArea () const
+
+virtual
+
+

Find the area of the observed widget, where selection might happen.

+
Returns
parentWidget()->contentsRect()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
const QPolygon & QwtPicker::pickedPoints () const
+
+protected
+
+

Return the points, that have been collected so far. The selection() is calculated from the pickedPoints() in adjustedPoints().

+
Returns
Picked points
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void QwtPicker::remove ()
+
+protectedvirtual
+
+

Remove the last point of the selection The removed() signal is emitted.

+
See Also
isActive(), begin(), end(), append(), move()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtPicker::removed (const QPoint & pos)
+
+signal
+
+

A signal emitted whenever the last appended point of the selection has been removed.

+
Parameters
+ + +
posPosition of the point, that has been removed
+
+
+
See Also
remove(), appended()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void QwtPicker::reset ()
+
+protectedvirtual
+
+

Reset the state machine and terminate ( end(false) ) the selection

+ +
+
+ +
+
+ + + + + + + +
QwtPicker::ResizeMode QwtPicker::resizeMode () const
+
+
Returns
Resize mode
+
See Also
setResizeMode(), ResizeMode
+ +
+
+ +
+
+ + + + + + + +
QwtPicker::RubberBand QwtPicker::rubberBand () const
+
+
Returns
Rubber band style
+
See Also
setRubberBand(), RubberBand, rubberBandPen()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
QRegion QwtPicker::rubberBandMask () const
+
+virtual
+
+

Calculate the mask for the rubber band overlay

+
Returns
Region for the mask
+
See Also
QWidget::setMask()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
const QwtWidgetOverlay * QwtPicker::rubberBandOverlay () const
+
+protected
+
+
Returns
Overlay displaying the rubber band
+ +
+
+ +
+
+ + + + + + + +
QPen QwtPicker::rubberBandPen () const
+
+
Returns
Rubber band pen
+
See Also
setRubberBandPen(), rubberBand()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtPicker::selected (const QPolygon & polygon)
+
+signal
+
+

A signal emitting the selected points, at the end of a selection.

+
Parameters
+ + +
polygonSelected points
+
+
+ +
+
+ +
+
+ + + + + + + +
QPolygon QwtPicker::selection () const
+
+
Returns
Selected points
+
See Also
pickedPoints(), adjustedPoints()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtPicker::setEnabled (bool enabled)
+
+slot
+
+ +

En/disable the picker.

+

When enabled is true an event filter is installed for the observed widget, otherwise the event filter is removed.

+
Parameters
+ + +
enabledtrue or false
+
+
+
See Also
isEnabled(), eventFilter()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPicker::setResizeMode (ResizeMode mode)
+
+ +

Set the resize mode.

+

The resize mode controls what to do with the selected points of an active selection when the observed widget is resized.

+

Stretch means the points are scaled according to the new size, KeepSize means the points remain unchanged.

+

The default mode is Stretch.

+
Parameters
+ + +
modeResize mode
+
+
+
See Also
resizeMode(), ResizeMode
+ +
+
+ +
+
+ + + + + + + + +
void QwtPicker::setRubberBand (RubberBand rubberBand)
+
+

Set the rubber band style

+
Parameters
+ + +
rubberBandRubber band style The default value is NoRubberBand.
+
+
+
See Also
rubberBand(), RubberBand, setRubberBandPen()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPicker::setRubberBandPen (const QPen & pen)
+
+

Set the pen for the rubberband

+
Parameters
+ + +
penRubber band pen
+
+
+
See Also
rubberBandPen(), setRubberBand()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPicker::setStateMachine (QwtPickerMachinestateMachine)
+
+

Set a state machine and delete the previous one

+
Parameters
+ + +
stateMachineState machine
+
+
+
See Also
stateMachine()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPicker::setTrackerFont (const QFont & font)
+
+

Set the font for the tracker

+
Parameters
+ + +
fontTracker font
+
+
+
See Also
trackerFont(), setTrackerMode(), setTrackerPen()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPicker::setTrackerMode (DisplayMode mode)
+
+ +

Set the display mode of the tracker.

+

A tracker displays information about current position of the cursor as a string. The display mode controls if the tracker has to be displayed whenever the observed widget has focus and cursor (AlwaysOn), never (AlwaysOff), or only when the selection is active (ActiveOnly).

+
Parameters
+ + +
modeTracker display mode
+
+
+
Warning
In case of AlwaysOn, mouseTracking will be enabled for the observed widget.
+
See Also
trackerMode(), DisplayMode
+ +
+
+ +
+
+ + + + + + + + +
void QwtPicker::setTrackerPen (const QPen & pen)
+
+

Set the pen for the tracker

+
Parameters
+ + +
penTracker pen
+
+
+
See Also
trackerPen(), setTrackerMode(), setTrackerFont()
+ +
+
+ +
+
+ + + + + + + +
const QwtPickerMachine * QwtPicker::stateMachine () const
+
+
Returns
Assigned state machine
+
See Also
setStateMachine()
+ +
+
+ +
+
+ + + + + + + +
QwtPickerMachine * QwtPicker::stateMachine ()
+
+
Returns
Assigned state machine
+
See Also
setStateMachine()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void QwtPicker::stretchSelection (const QSize & oldSize,
const QSize & newSize 
)
+
+protectedvirtual
+
+

Scale the selection by the ratios of oldSize and newSize The changed() signal is emitted.

+
Parameters
+ + + +
oldSizePrevious size
newSizeCurrent size
+
+
+
See Also
ResizeMode, setResizeMode(), resizeMode()
+ +
+
+ +
+
+ + + + + + + +
QFont QwtPicker::trackerFont () const
+
+
Returns
Tracker font
+
See Also
setTrackerFont(), trackerMode(), trackerPen()
+ +
+
+ +
+
+ + + + + + + +
QwtPicker::DisplayMode QwtPicker::trackerMode () const
+
+
Returns
Tracker display mode
+
See Also
setTrackerMode(), DisplayMode
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
const QwtWidgetOverlay * QwtPicker::trackerOverlay () const
+
+protected
+
+
Returns
Overlay displaying the tracker text
+ +
+
+ +
+
+ + + + + + + +
QPen QwtPicker::trackerPen () const
+
+
Returns
Tracker pen
+
See Also
setTrackerPen(), trackerMode(), trackerFont()
+ +
+
+ +
+
+ + + + + + + +
QPoint QwtPicker::trackerPosition () const
+
+
Returns
Current position of the tracker
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
QRect QwtPicker::trackerRect (const QFont & font) const
+
+virtual
+
+

Calculate the bounding rectangle for the tracker text from the current position of the tracker

+
Parameters
+ + +
fontFont of the tracker text
+
+
+
Returns
Bounding rectangle of the tracker text
+
See Also
trackerPosition()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
QwtText QwtPicker::trackerText (const QPoint & pos) const
+
+virtual
+
+ +

Return the label for a position.

+

In case of HLineRubberBand the label is the value of the y position, in case of VLineRubberBand the value of the x position. Otherwise the label contains x and y position separated by a ',' .

+

The format for the string conversion is "%d".

+
Parameters
+ + +
posPosition
+
+
+
Returns
Converted position as string
+ +

Reimplemented in QwtPlotPicker.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtPicker::transition (const QEvent * event)
+
+protectedvirtual
+
+

Passes an event to the state machine and executes the resulting commands. Append and Move commands use the current position of the cursor ( QCursor::pos() ).

+
Parameters
+ + +
eventEvent
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtPicker::widgetEnterEvent (QEvent * event)
+
+protectedvirtual
+
+

Handle a enter event for the observed widget.

+
Parameters
+ + +
eventQt event
+
+
+
See Also
eventFilter(), widgetMousePressEvent(), widgetMouseReleaseEvent(), widgetMouseDoubleClickEvent(), widgetWheelEvent(), widgetKeyPressEvent(), widgetKeyReleaseEvent()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtPicker::widgetKeyPressEvent (QKeyEvent * keyEvent)
+
+protectedvirtual
+
+

Handle a key press event for the observed widget.

+

Selections can be completely done by the keyboard. The arrow keys move the cursor, the abort key aborts a selection. All other keys are handled by the current state machine.

+
Parameters
+ + +
keyEventKey event
+
+
+
See Also
eventFilter(), widgetMousePressEvent(), widgetMouseReleaseEvent(), widgetMouseDoubleClickEvent(), widgetMouseMoveEvent(), widgetWheelEvent(), widgetKeyReleaseEvent(), stateMachine(), QwtEventPattern::KeyPatternCode
+ +

Reimplemented in QwtPlotZoomer.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtPicker::widgetKeyReleaseEvent (QKeyEvent * keyEvent)
+
+protectedvirtual
+
+

Handle a key release event for the observed widget.

+

Passes the event to the state machine.

+
Parameters
+ + +
keyEventKey event
+
+
+
See Also
eventFilter(), widgetMousePressEvent(), widgetMouseReleaseEvent(), widgetMouseDoubleClickEvent(), widgetMouseMoveEvent(), widgetWheelEvent(), widgetKeyPressEvent(), stateMachine()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtPicker::widgetLeaveEvent (QEvent * event)
+
+protectedvirtual
+
+

Handle a leave event for the observed widget.

+
Parameters
+ + +
eventQt event
+
+
+
See Also
eventFilter(), widgetMousePressEvent(), widgetMouseReleaseEvent(), widgetMouseDoubleClickEvent(), widgetWheelEvent(), widgetKeyPressEvent(), widgetKeyReleaseEvent()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtPicker::widgetMouseDoubleClickEvent (QMouseEvent * mouseEvent)
+
+protectedvirtual
+
+

Handle mouse double click event for the observed widget.

+
Parameters
+ + +
mouseEventMouse event
+
+
+
See Also
eventFilter(), widgetMousePressEvent(), widgetMouseReleaseEvent(), widgetMouseMoveEvent(), widgetWheelEvent(), widgetKeyPressEvent(), widgetKeyReleaseEvent()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtPicker::widgetMouseMoveEvent (QMouseEvent * mouseEvent)
+
+protectedvirtual
+
+

Handle a mouse move event for the observed widget.

+
Parameters
+ + +
mouseEventMouse event
+
+
+
See Also
eventFilter(), widgetMousePressEvent(), widgetMouseReleaseEvent(), widgetMouseDoubleClickEvent(), widgetWheelEvent(), widgetKeyPressEvent(), widgetKeyReleaseEvent()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtPicker::widgetMousePressEvent (QMouseEvent * mouseEvent)
+
+protectedvirtual
+
+

Handle a mouse press event for the observed widget.

+
Parameters
+ + +
mouseEventMouse event
+
+
+
See Also
eventFilter(), widgetMouseReleaseEvent(), widgetMouseDoubleClickEvent(), widgetMouseMoveEvent(), widgetWheelEvent(), widgetKeyPressEvent(), widgetKeyReleaseEvent()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtPicker::widgetMouseReleaseEvent (QMouseEvent * mouseEvent)
+
+protectedvirtual
+
+

Handle a mouse release event for the observed widget.

+
Parameters
+ + +
mouseEventMouse event
+
+
+
See Also
eventFilter(), widgetMousePressEvent(), widgetMouseDoubleClickEvent(), widgetMouseMoveEvent(), widgetWheelEvent(), widgetKeyPressEvent(), widgetKeyReleaseEvent()
+ +

Reimplemented in QwtPlotZoomer.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtPicker::widgetWheelEvent (QWheelEvent * wheelEvent)
+
+protectedvirtual
+
+

Handle a wheel event for the observed widget.

+

Move the last point of the selection in case of isActive() == true

+
Parameters
+ + +
wheelEventWheel event
+
+
+
See Also
eventFilter(), widgetMousePressEvent(), widgetMouseReleaseEvent(), widgetMouseDoubleClickEvent(), widgetMouseMoveEvent(), widgetKeyPressEvent(), widgetKeyReleaseEvent()
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_picker__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_picker__inherit__graph.map new file mode 100644 index 0000000000..f81b561712 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_picker__inherit__graph.map @@ -0,0 +1,5 @@ + + + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_picker__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_picker__inherit__graph.md5 new file mode 100644 index 0000000000..5261d720f3 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_picker__inherit__graph.md5 @@ -0,0 +1 @@ +97a1ecbd899d3ba9a4c445704bc75efc \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_picker__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_picker__inherit__graph.png new file mode 100644 index 0000000000..b9e9b318b0 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_picker__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_picker_click_point_machine-members.html b/ThirdParty/Qwt/doc/html/class_qwt_picker_click_point_machine-members.html new file mode 100644 index 0000000000..978813a7ed --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_picker_click_point_machine-members.html @@ -0,0 +1,119 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtPickerClickPointMachine Member List
+
+
+ +

This is the complete list of members for QwtPickerClickPointMachine, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + +
Append enum value (defined in QwtPickerMachine)QwtPickerMachine
Begin enum value (defined in QwtPickerMachine)QwtPickerMachine
Command enum nameQwtPickerMachine
End enum value (defined in QwtPickerMachine)QwtPickerMachine
Move enum value (defined in QwtPickerMachine)QwtPickerMachine
NoSelection enum valueQwtPickerMachine
PointSelection enum valueQwtPickerMachine
PolygonSelection enum valueQwtPickerMachine
QwtPickerClickPointMachine()QwtPickerClickPointMachine
QwtPickerMachine(SelectionType)QwtPickerMachine
RectSelection enum valueQwtPickerMachine
Remove enum value (defined in QwtPickerMachine)QwtPickerMachine
reset()QwtPickerMachine
selectionType() const QwtPickerMachine
SelectionType enum nameQwtPickerMachine
setState(int)QwtPickerMachine
state() const QwtPickerMachine
transition(const QwtEventPattern &, const QEvent *)QwtPickerClickPointMachinevirtual
~QwtPickerMachine()QwtPickerMachinevirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_picker_click_point_machine.html b/ThirdParty/Qwt/doc/html/class_qwt_picker_click_point_machine.html new file mode 100644 index 0000000000..70ff6a50e2 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_picker_click_point_machine.html @@ -0,0 +1,174 @@ + + + + + + +Qwt User's Guide: QwtPickerClickPointMachine Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtPickerClickPointMachine Class Reference
+
+
+ +

A state machine for point selections. + More...

+ +

#include <qwt_picker_machine.h>

+
+Inheritance diagram for QwtPickerClickPointMachine:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

QwtPickerClickPointMachine ()
 Constructor.
 
+virtual QList< Commandtransition (const QwtEventPattern &, const QEvent *)
 Transition.
 
- Public Member Functions inherited from QwtPickerMachine
QwtPickerMachine (SelectionType)
 Constructor.
 
+virtual ~QwtPickerMachine ()
 Destructor.
 
+void reset ()
 Set the current state to 0.
 
+int state () const
 Return the current state.
 
+void setState (int)
 Change the current state.
 
+SelectionType selectionType () const
 Return the selection type.
 
+ + + + + + + +

+Additional Inherited Members

- Public Types inherited from QwtPickerMachine
enum  SelectionType { NoSelection = -1, +PointSelection, +RectSelection, +PolygonSelection + }
 
enum  Command {
+  Begin, +Append, +Move, +Remove, +
+  End +
+ }
 Commands - the output of a state machine.
 
+

Detailed Description

+

A state machine for point selections.

+

Pressing QwtEventPattern::MouseSelect1 or QwtEventPattern::KeySelect1 selects a point.

+
See Also
QwtEventPattern::MousePatternCode, QwtEventPattern::KeyPatternCode
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_picker_click_point_machine__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_picker_click_point_machine__inherit__graph.map new file mode 100644 index 0000000000..4515f558c9 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_picker_click_point_machine__inherit__graph.map @@ -0,0 +1,3 @@ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_picker_click_point_machine__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_picker_click_point_machine__inherit__graph.md5 new file mode 100644 index 0000000000..666cddcaa3 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_picker_click_point_machine__inherit__graph.md5 @@ -0,0 +1 @@ +8e03a8e15c170ac86a2de2049121c649 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_picker_click_point_machine__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_picker_click_point_machine__inherit__graph.png new file mode 100644 index 0000000000..eed8d6a7a8 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_picker_click_point_machine__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_picker_click_rect_machine-members.html b/ThirdParty/Qwt/doc/html/class_qwt_picker_click_rect_machine-members.html new file mode 100644 index 0000000000..0ef33e5b27 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_picker_click_rect_machine-members.html @@ -0,0 +1,119 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtPickerClickRectMachine Member List
+
+
+ +

This is the complete list of members for QwtPickerClickRectMachine, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + +
Append enum value (defined in QwtPickerMachine)QwtPickerMachine
Begin enum value (defined in QwtPickerMachine)QwtPickerMachine
Command enum nameQwtPickerMachine
End enum value (defined in QwtPickerMachine)QwtPickerMachine
Move enum value (defined in QwtPickerMachine)QwtPickerMachine
NoSelection enum valueQwtPickerMachine
PointSelection enum valueQwtPickerMachine
PolygonSelection enum valueQwtPickerMachine
QwtPickerClickRectMachine()QwtPickerClickRectMachine
QwtPickerMachine(SelectionType)QwtPickerMachine
RectSelection enum valueQwtPickerMachine
Remove enum value (defined in QwtPickerMachine)QwtPickerMachine
reset()QwtPickerMachine
selectionType() const QwtPickerMachine
SelectionType enum nameQwtPickerMachine
setState(int)QwtPickerMachine
state() const QwtPickerMachine
transition(const QwtEventPattern &, const QEvent *)QwtPickerClickRectMachinevirtual
~QwtPickerMachine()QwtPickerMachinevirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_picker_click_rect_machine.html b/ThirdParty/Qwt/doc/html/class_qwt_picker_click_rect_machine.html new file mode 100644 index 0000000000..453f3e5571 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_picker_click_rect_machine.html @@ -0,0 +1,174 @@ + + + + + + +Qwt User's Guide: QwtPickerClickRectMachine Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtPickerClickRectMachine Class Reference
+
+
+ +

A state machine for rectangle selections. + More...

+ +

#include <qwt_picker_machine.h>

+
+Inheritance diagram for QwtPickerClickRectMachine:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

QwtPickerClickRectMachine ()
 Constructor.
 
+virtual QList< Commandtransition (const QwtEventPattern &, const QEvent *)
 Transition.
 
- Public Member Functions inherited from QwtPickerMachine
QwtPickerMachine (SelectionType)
 Constructor.
 
+virtual ~QwtPickerMachine ()
 Destructor.
 
+void reset ()
 Set the current state to 0.
 
+int state () const
 Return the current state.
 
+void setState (int)
 Change the current state.
 
+SelectionType selectionType () const
 Return the selection type.
 
+ + + + + + + +

+Additional Inherited Members

- Public Types inherited from QwtPickerMachine
enum  SelectionType { NoSelection = -1, +PointSelection, +RectSelection, +PolygonSelection + }
 
enum  Command {
+  Begin, +Append, +Move, +Remove, +
+  End +
+ }
 Commands - the output of a state machine.
 
+

Detailed Description

+

A state machine for rectangle selections.

+

Pressing QwtEventPattern::MouseSelect1 starts the selection, releasing it selects the first point. Pressing it again selects the second point and terminates the selection. Pressing QwtEventPattern::KeySelect1 also starts the selection, a second press selects the first point. A third one selects the second point and terminates the selection.

+
See Also
QwtEventPattern::MousePatternCode, QwtEventPattern::KeyPatternCode
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_picker_click_rect_machine__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_picker_click_rect_machine__inherit__graph.map new file mode 100644 index 0000000000..9fd6247a05 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_picker_click_rect_machine__inherit__graph.map @@ -0,0 +1,3 @@ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_picker_click_rect_machine__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_picker_click_rect_machine__inherit__graph.md5 new file mode 100644 index 0000000000..bda0a43de3 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_picker_click_rect_machine__inherit__graph.md5 @@ -0,0 +1 @@ +cbc66a42414b69017b04c0e8b6076975 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_picker_click_rect_machine__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_picker_click_rect_machine__inherit__graph.png new file mode 100644 index 0000000000..481bdfe8e5 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_picker_click_rect_machine__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_picker_drag_line_machine-members.html b/ThirdParty/Qwt/doc/html/class_qwt_picker_drag_line_machine-members.html new file mode 100644 index 0000000000..a2673bfe39 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_picker_drag_line_machine-members.html @@ -0,0 +1,119 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtPickerDragLineMachine Member List
+
+
+ +

This is the complete list of members for QwtPickerDragLineMachine, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + +
Append enum value (defined in QwtPickerMachine)QwtPickerMachine
Begin enum value (defined in QwtPickerMachine)QwtPickerMachine
Command enum nameQwtPickerMachine
End enum value (defined in QwtPickerMachine)QwtPickerMachine
Move enum value (defined in QwtPickerMachine)QwtPickerMachine
NoSelection enum valueQwtPickerMachine
PointSelection enum valueQwtPickerMachine
PolygonSelection enum valueQwtPickerMachine
QwtPickerDragLineMachine()QwtPickerDragLineMachine
QwtPickerMachine(SelectionType)QwtPickerMachine
RectSelection enum valueQwtPickerMachine
Remove enum value (defined in QwtPickerMachine)QwtPickerMachine
reset()QwtPickerMachine
selectionType() const QwtPickerMachine
SelectionType enum nameQwtPickerMachine
setState(int)QwtPickerMachine
state() const QwtPickerMachine
transition(const QwtEventPattern &, const QEvent *)QwtPickerDragLineMachinevirtual
~QwtPickerMachine()QwtPickerMachinevirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_picker_drag_line_machine.html b/ThirdParty/Qwt/doc/html/class_qwt_picker_drag_line_machine.html new file mode 100644 index 0000000000..2cc4556a58 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_picker_drag_line_machine.html @@ -0,0 +1,175 @@ + + + + + + +Qwt User's Guide: QwtPickerDragLineMachine Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtPickerDragLineMachine Class Reference
+
+
+ +

A state machine for line selections. + More...

+ +

#include <qwt_picker_machine.h>

+
+Inheritance diagram for QwtPickerDragLineMachine:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

QwtPickerDragLineMachine ()
 Constructor.
 
+virtual QList< Commandtransition (const QwtEventPattern &, const QEvent *)
 Transition.
 
- Public Member Functions inherited from QwtPickerMachine
QwtPickerMachine (SelectionType)
 Constructor.
 
+virtual ~QwtPickerMachine ()
 Destructor.
 
+void reset ()
 Set the current state to 0.
 
+int state () const
 Return the current state.
 
+void setState (int)
 Change the current state.
 
+SelectionType selectionType () const
 Return the selection type.
 
+ + + + + + + +

+Additional Inherited Members

- Public Types inherited from QwtPickerMachine
enum  SelectionType { NoSelection = -1, +PointSelection, +RectSelection, +PolygonSelection + }
 
enum  Command {
+  Begin, +Append, +Move, +Remove, +
+  End +
+ }
 Commands - the output of a state machine.
 
+

Detailed Description

+

A state machine for line selections.

+

Pressing QwtEventPattern::MouseSelect1 selects the first point, releasing it the second point. Pressing QwtEventPattern::KeySelect1 also selects the first point, a second press selects the second point and terminates the selection.

+

A common use case of QwtPickerDragLineMachine are pickers for distance measurements.

+
See Also
QwtEventPattern::MousePatternCode, QwtEventPattern::KeyPatternCode
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_picker_drag_line_machine__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_picker_drag_line_machine__inherit__graph.map new file mode 100644 index 0000000000..ec6a12f193 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_picker_drag_line_machine__inherit__graph.map @@ -0,0 +1,3 @@ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_picker_drag_line_machine__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_picker_drag_line_machine__inherit__graph.md5 new file mode 100644 index 0000000000..529f528fd7 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_picker_drag_line_machine__inherit__graph.md5 @@ -0,0 +1 @@ +3ab400d0705d75221d9616d60109205b \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_picker_drag_line_machine__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_picker_drag_line_machine__inherit__graph.png new file mode 100644 index 0000000000..8568083b6e Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_picker_drag_line_machine__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_picker_drag_point_machine-members.html b/ThirdParty/Qwt/doc/html/class_qwt_picker_drag_point_machine-members.html new file mode 100644 index 0000000000..3fe78899ed --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_picker_drag_point_machine-members.html @@ -0,0 +1,119 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtPickerDragPointMachine Member List
+
+
+ +

This is the complete list of members for QwtPickerDragPointMachine, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + +
Append enum value (defined in QwtPickerMachine)QwtPickerMachine
Begin enum value (defined in QwtPickerMachine)QwtPickerMachine
Command enum nameQwtPickerMachine
End enum value (defined in QwtPickerMachine)QwtPickerMachine
Move enum value (defined in QwtPickerMachine)QwtPickerMachine
NoSelection enum valueQwtPickerMachine
PointSelection enum valueQwtPickerMachine
PolygonSelection enum valueQwtPickerMachine
QwtPickerDragPointMachine()QwtPickerDragPointMachine
QwtPickerMachine(SelectionType)QwtPickerMachine
RectSelection enum valueQwtPickerMachine
Remove enum value (defined in QwtPickerMachine)QwtPickerMachine
reset()QwtPickerMachine
selectionType() const QwtPickerMachine
SelectionType enum nameQwtPickerMachine
setState(int)QwtPickerMachine
state() const QwtPickerMachine
transition(const QwtEventPattern &, const QEvent *)QwtPickerDragPointMachinevirtual
~QwtPickerMachine()QwtPickerMachinevirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_picker_drag_point_machine.html b/ThirdParty/Qwt/doc/html/class_qwt_picker_drag_point_machine.html new file mode 100644 index 0000000000..cf1969d981 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_picker_drag_point_machine.html @@ -0,0 +1,173 @@ + + + + + + +Qwt User's Guide: QwtPickerDragPointMachine Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtPickerDragPointMachine Class Reference
+
+
+ +

A state machine for point selections. + More...

+ +

#include <qwt_picker_machine.h>

+
+Inheritance diagram for QwtPickerDragPointMachine:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

QwtPickerDragPointMachine ()
 Constructor.
 
+virtual QList< Commandtransition (const QwtEventPattern &, const QEvent *)
 Transition.
 
- Public Member Functions inherited from QwtPickerMachine
QwtPickerMachine (SelectionType)
 Constructor.
 
+virtual ~QwtPickerMachine ()
 Destructor.
 
+void reset ()
 Set the current state to 0.
 
+int state () const
 Return the current state.
 
+void setState (int)
 Change the current state.
 
+SelectionType selectionType () const
 Return the selection type.
 
+ + + + + + + +

+Additional Inherited Members

- Public Types inherited from QwtPickerMachine
enum  SelectionType { NoSelection = -1, +PointSelection, +RectSelection, +PolygonSelection + }
 
enum  Command {
+  Begin, +Append, +Move, +Remove, +
+  End +
+ }
 Commands - the output of a state machine.
 
+

Detailed Description

+

A state machine for point selections.

+

Pressing QwtEventPattern::MouseSelect1 or QwtEventPattern::KeySelect1 starts the selection, releasing QwtEventPattern::MouseSelect1 or a second press of QwtEventPattern::KeySelect1 terminates it.

+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_picker_drag_point_machine__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_picker_drag_point_machine__inherit__graph.map new file mode 100644 index 0000000000..9d8d570475 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_picker_drag_point_machine__inherit__graph.map @@ -0,0 +1,3 @@ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_picker_drag_point_machine__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_picker_drag_point_machine__inherit__graph.md5 new file mode 100644 index 0000000000..efef912d37 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_picker_drag_point_machine__inherit__graph.md5 @@ -0,0 +1 @@ +b164ec38bec2aa12df5f2318cf2c7218 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_picker_drag_point_machine__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_picker_drag_point_machine__inherit__graph.png new file mode 100644 index 0000000000..b6d89ec5f9 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_picker_drag_point_machine__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_picker_drag_rect_machine-members.html b/ThirdParty/Qwt/doc/html/class_qwt_picker_drag_rect_machine-members.html new file mode 100644 index 0000000000..0c266c3b2f --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_picker_drag_rect_machine-members.html @@ -0,0 +1,119 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtPickerDragRectMachine Member List
+
+
+ +

This is the complete list of members for QwtPickerDragRectMachine, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + +
Append enum value (defined in QwtPickerMachine)QwtPickerMachine
Begin enum value (defined in QwtPickerMachine)QwtPickerMachine
Command enum nameQwtPickerMachine
End enum value (defined in QwtPickerMachine)QwtPickerMachine
Move enum value (defined in QwtPickerMachine)QwtPickerMachine
NoSelection enum valueQwtPickerMachine
PointSelection enum valueQwtPickerMachine
PolygonSelection enum valueQwtPickerMachine
QwtPickerDragRectMachine()QwtPickerDragRectMachine
QwtPickerMachine(SelectionType)QwtPickerMachine
RectSelection enum valueQwtPickerMachine
Remove enum value (defined in QwtPickerMachine)QwtPickerMachine
reset()QwtPickerMachine
selectionType() const QwtPickerMachine
SelectionType enum nameQwtPickerMachine
setState(int)QwtPickerMachine
state() const QwtPickerMachine
transition(const QwtEventPattern &, const QEvent *)QwtPickerDragRectMachinevirtual
~QwtPickerMachine()QwtPickerMachinevirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_picker_drag_rect_machine.html b/ThirdParty/Qwt/doc/html/class_qwt_picker_drag_rect_machine.html new file mode 100644 index 0000000000..9594f21ba9 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_picker_drag_rect_machine.html @@ -0,0 +1,174 @@ + + + + + + +Qwt User's Guide: QwtPickerDragRectMachine Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtPickerDragRectMachine Class Reference
+
+
+ +

A state machine for rectangle selections. + More...

+ +

#include <qwt_picker_machine.h>

+
+Inheritance diagram for QwtPickerDragRectMachine:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

QwtPickerDragRectMachine ()
 Constructor.
 
+virtual QList< Commandtransition (const QwtEventPattern &, const QEvent *)
 Transition.
 
- Public Member Functions inherited from QwtPickerMachine
QwtPickerMachine (SelectionType)
 Constructor.
 
+virtual ~QwtPickerMachine ()
 Destructor.
 
+void reset ()
 Set the current state to 0.
 
+int state () const
 Return the current state.
 
+void setState (int)
 Change the current state.
 
+SelectionType selectionType () const
 Return the selection type.
 
+ + + + + + + +

+Additional Inherited Members

- Public Types inherited from QwtPickerMachine
enum  SelectionType { NoSelection = -1, +PointSelection, +RectSelection, +PolygonSelection + }
 
enum  Command {
+  Begin, +Append, +Move, +Remove, +
+  End +
+ }
 Commands - the output of a state machine.
 
+

Detailed Description

+

A state machine for rectangle selections.

+

Pressing QwtEventPattern::MouseSelect1 selects the first point, releasing it the second point. Pressing QwtEventPattern::KeySelect1 also selects the first point, a second press selects the second point and terminates the selection.

+
See Also
QwtEventPattern::MousePatternCode, QwtEventPattern::KeyPatternCode
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_picker_drag_rect_machine__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_picker_drag_rect_machine__inherit__graph.map new file mode 100644 index 0000000000..0d31f5f5a4 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_picker_drag_rect_machine__inherit__graph.map @@ -0,0 +1,3 @@ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_picker_drag_rect_machine__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_picker_drag_rect_machine__inherit__graph.md5 new file mode 100644 index 0000000000..97a504f4c8 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_picker_drag_rect_machine__inherit__graph.md5 @@ -0,0 +1 @@ +b2b80bcc1944d0e1a2db4199a5b56693 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_picker_drag_rect_machine__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_picker_drag_rect_machine__inherit__graph.png new file mode 100644 index 0000000000..d6aa91474a Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_picker_drag_rect_machine__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_picker_machine-members.html b/ThirdParty/Qwt/doc/html/class_qwt_picker_machine-members.html new file mode 100644 index 0000000000..b1ca93c809 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_picker_machine-members.html @@ -0,0 +1,118 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtPickerMachine Member List
+
+
+ +

This is the complete list of members for QwtPickerMachine, including all inherited members.

+ + + + + + + + + + + + + + + + + + + +
Append enum value (defined in QwtPickerMachine)QwtPickerMachine
Begin enum value (defined in QwtPickerMachine)QwtPickerMachine
Command enum nameQwtPickerMachine
End enum value (defined in QwtPickerMachine)QwtPickerMachine
Move enum value (defined in QwtPickerMachine)QwtPickerMachine
NoSelection enum valueQwtPickerMachine
PointSelection enum valueQwtPickerMachine
PolygonSelection enum valueQwtPickerMachine
QwtPickerMachine(SelectionType)QwtPickerMachine
RectSelection enum valueQwtPickerMachine
Remove enum value (defined in QwtPickerMachine)QwtPickerMachine
reset()QwtPickerMachine
SelectionType enum nameQwtPickerMachine
selectionType() const QwtPickerMachine
setState(int)QwtPickerMachine
state() const QwtPickerMachine
transition(const QwtEventPattern &, const QEvent *)=0QwtPickerMachinepure virtual
~QwtPickerMachine()QwtPickerMachinevirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_picker_machine.html b/ThirdParty/Qwt/doc/html/class_qwt_picker_machine.html new file mode 100644 index 0000000000..b7ca97585a --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_picker_machine.html @@ -0,0 +1,198 @@ + + + + + + +Qwt User's Guide: QwtPickerMachine Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtPickerMachine Class Referenceabstract
+
+
+ +

A state machine for QwtPicker selections. + More...

+ +

#include <qwt_picker_machine.h>

+
+Inheritance diagram for QwtPickerMachine:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + +

+Public Types

enum  SelectionType { NoSelection = -1, +PointSelection, +RectSelection, +PolygonSelection + }
 
enum  Command {
+  Begin, +Append, +Move, +Remove, +
+  End +
+ }
 Commands - the output of a state machine.
 
+ + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

QwtPickerMachine (SelectionType)
 Constructor.
 
+virtual ~QwtPickerMachine ()
 Destructor.
 
+virtual QList< Commandtransition (const QwtEventPattern &, const QEvent *)=0
 Transition.
 
+void reset ()
 Set the current state to 0.
 
+int state () const
 Return the current state.
 
+void setState (int)
 Change the current state.
 
+SelectionType selectionType () const
 Return the selection type.
 
+

Detailed Description

+

A state machine for QwtPicker selections.

+

QwtPickerMachine accepts key and mouse events and translates them into selection commands.

+
See Also
QwtEventPattern::MousePatternCode, QwtEventPattern::KeyPatternCode
+

Member Enumeration Documentation

+ +
+
+

Type of a selection.

+
See Also
selectionType()
+ + + + + +
Enumerator
NoSelection  +

The state machine not usable for any type of selection.

+
PointSelection  +

The state machine is for selecting a single point.

+
RectSelection  +

The state machine is for selecting a rectangle (2 points).

+
PolygonSelection  +

The state machine is for selecting a polygon (many points).

+
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_picker_machine__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_picker_machine__inherit__graph.map new file mode 100644 index 0000000000..d2797c7bb5 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_picker_machine__inherit__graph.map @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_picker_machine__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_picker_machine__inherit__graph.md5 new file mode 100644 index 0000000000..032cdd8344 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_picker_machine__inherit__graph.md5 @@ -0,0 +1 @@ +9559b4cc88dcfc660a4b0a49d14882ba \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_picker_machine__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_picker_machine__inherit__graph.png new file mode 100644 index 0000000000..bd6d1448d2 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_picker_machine__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_picker_polygon_machine-members.html b/ThirdParty/Qwt/doc/html/class_qwt_picker_polygon_machine-members.html new file mode 100644 index 0000000000..a06d8cc1bc --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_picker_polygon_machine-members.html @@ -0,0 +1,119 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtPickerPolygonMachine Member List
+
+
+ +

This is the complete list of members for QwtPickerPolygonMachine, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + +
Append enum value (defined in QwtPickerMachine)QwtPickerMachine
Begin enum value (defined in QwtPickerMachine)QwtPickerMachine
Command enum nameQwtPickerMachine
End enum value (defined in QwtPickerMachine)QwtPickerMachine
Move enum value (defined in QwtPickerMachine)QwtPickerMachine
NoSelection enum valueQwtPickerMachine
PointSelection enum valueQwtPickerMachine
PolygonSelection enum valueQwtPickerMachine
QwtPickerMachine(SelectionType)QwtPickerMachine
QwtPickerPolygonMachine()QwtPickerPolygonMachine
RectSelection enum valueQwtPickerMachine
Remove enum value (defined in QwtPickerMachine)QwtPickerMachine
reset()QwtPickerMachine
selectionType() const QwtPickerMachine
SelectionType enum nameQwtPickerMachine
setState(int)QwtPickerMachine
state() const QwtPickerMachine
transition(const QwtEventPattern &, const QEvent *)QwtPickerPolygonMachinevirtual
~QwtPickerMachine()QwtPickerMachinevirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_picker_polygon_machine.html b/ThirdParty/Qwt/doc/html/class_qwt_picker_polygon_machine.html new file mode 100644 index 0000000000..6b31bbbe4b --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_picker_polygon_machine.html @@ -0,0 +1,174 @@ + + + + + + +Qwt User's Guide: QwtPickerPolygonMachine Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtPickerPolygonMachine Class Reference
+
+
+ +

A state machine for polygon selections. + More...

+ +

#include <qwt_picker_machine.h>

+
+Inheritance diagram for QwtPickerPolygonMachine:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

QwtPickerPolygonMachine ()
 Constructor.
 
+virtual QList< Commandtransition (const QwtEventPattern &, const QEvent *)
 Transition.
 
- Public Member Functions inherited from QwtPickerMachine
QwtPickerMachine (SelectionType)
 Constructor.
 
+virtual ~QwtPickerMachine ()
 Destructor.
 
+void reset ()
 Set the current state to 0.
 
+int state () const
 Return the current state.
 
+void setState (int)
 Change the current state.
 
+SelectionType selectionType () const
 Return the selection type.
 
+ + + + + + + +

+Additional Inherited Members

- Public Types inherited from QwtPickerMachine
enum  SelectionType { NoSelection = -1, +PointSelection, +RectSelection, +PolygonSelection + }
 
enum  Command {
+  Begin, +Append, +Move, +Remove, +
+  End +
+ }
 Commands - the output of a state machine.
 
+

Detailed Description

+

A state machine for polygon selections.

+

Pressing QwtEventPattern::MouseSelect1 or QwtEventPattern::KeySelect1 starts the selection and selects the first point, or appends a point. Pressing QwtEventPattern::MouseSelect2 or QwtEventPattern::KeySelect2 appends the last point and terminates the selection.

+
See Also
QwtEventPattern::MousePatternCode, QwtEventPattern::KeyPatternCode
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_picker_polygon_machine__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_picker_polygon_machine__inherit__graph.map new file mode 100644 index 0000000000..e53ec1a4ba --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_picker_polygon_machine__inherit__graph.map @@ -0,0 +1,3 @@ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_picker_polygon_machine__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_picker_polygon_machine__inherit__graph.md5 new file mode 100644 index 0000000000..fc3c79e93b --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_picker_polygon_machine__inherit__graph.md5 @@ -0,0 +1 @@ +144817e01310739b2f60b53480d67cb6 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_picker_polygon_machine__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_picker_polygon_machine__inherit__graph.png new file mode 100644 index 0000000000..1c383eb39c Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_picker_polygon_machine__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_picker_tracker_machine-members.html b/ThirdParty/Qwt/doc/html/class_qwt_picker_tracker_machine-members.html new file mode 100644 index 0000000000..24a488255f --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_picker_tracker_machine-members.html @@ -0,0 +1,119 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtPickerTrackerMachine Member List
+
+
+ +

This is the complete list of members for QwtPickerTrackerMachine, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + +
Append enum value (defined in QwtPickerMachine)QwtPickerMachine
Begin enum value (defined in QwtPickerMachine)QwtPickerMachine
Command enum nameQwtPickerMachine
End enum value (defined in QwtPickerMachine)QwtPickerMachine
Move enum value (defined in QwtPickerMachine)QwtPickerMachine
NoSelection enum valueQwtPickerMachine
PointSelection enum valueQwtPickerMachine
PolygonSelection enum valueQwtPickerMachine
QwtPickerMachine(SelectionType)QwtPickerMachine
QwtPickerTrackerMachine()QwtPickerTrackerMachine
RectSelection enum valueQwtPickerMachine
Remove enum value (defined in QwtPickerMachine)QwtPickerMachine
reset()QwtPickerMachine
selectionType() const QwtPickerMachine
SelectionType enum nameQwtPickerMachine
setState(int)QwtPickerMachine
state() const QwtPickerMachine
transition(const QwtEventPattern &, const QEvent *)QwtPickerTrackerMachinevirtual
~QwtPickerMachine()QwtPickerMachinevirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_picker_tracker_machine.html b/ThirdParty/Qwt/doc/html/class_qwt_picker_tracker_machine.html new file mode 100644 index 0000000000..c9b20d82c9 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_picker_tracker_machine.html @@ -0,0 +1,173 @@ + + + + + + +Qwt User's Guide: QwtPickerTrackerMachine Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtPickerTrackerMachine Class Reference
+
+
+ +

A state machine for indicating mouse movements. + More...

+ +

#include <qwt_picker_machine.h>

+
+Inheritance diagram for QwtPickerTrackerMachine:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

QwtPickerTrackerMachine ()
 Constructor.
 
+virtual QList< Commandtransition (const QwtEventPattern &, const QEvent *)
 Transition.
 
- Public Member Functions inherited from QwtPickerMachine
QwtPickerMachine (SelectionType)
 Constructor.
 
+virtual ~QwtPickerMachine ()
 Destructor.
 
+void reset ()
 Set the current state to 0.
 
+int state () const
 Return the current state.
 
+void setState (int)
 Change the current state.
 
+SelectionType selectionType () const
 Return the selection type.
 
+ + + + + + + +

+Additional Inherited Members

- Public Types inherited from QwtPickerMachine
enum  SelectionType { NoSelection = -1, +PointSelection, +RectSelection, +PolygonSelection + }
 
enum  Command {
+  Begin, +Append, +Move, +Remove, +
+  End +
+ }
 Commands - the output of a state machine.
 
+

Detailed Description

+

A state machine for indicating mouse movements.

+

QwtPickerTrackerMachine supports displaying information corresponding to mouse movements, but is not intended for selecting anything. Begin/End are related to Enter/Leave events.

+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_picker_tracker_machine__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_picker_tracker_machine__inherit__graph.map new file mode 100644 index 0000000000..5512595849 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_picker_tracker_machine__inherit__graph.map @@ -0,0 +1,3 @@ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_picker_tracker_machine__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_picker_tracker_machine__inherit__graph.md5 new file mode 100644 index 0000000000..5356283caa --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_picker_tracker_machine__inherit__graph.md5 @@ -0,0 +1 @@ +6baeea7823ef1e51c5f83a33ea6f7f98 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_picker_tracker_machine__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_picker_tracker_machine__inherit__graph.png new file mode 100644 index 0000000000..24836447bd Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_picker_tracker_machine__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_pixel_matrix-members.html b/ThirdParty/Qwt/doc/html/class_qwt_pixel_matrix-members.html new file mode 100644 index 0000000000..cf121bb613 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_pixel_matrix-members.html @@ -0,0 +1,107 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtPixelMatrix Member List
+
+
+ +

This is the complete list of members for QwtPixelMatrix, including all inherited members.

+ + + + + + + + +
index(int x, int y) const QwtPixelMatrixinline
QwtPixelMatrix(const QRect &rect)QwtPixelMatrix
rect() const QwtPixelMatrix
setRect(const QRect &rect)QwtPixelMatrix
testAndSetPixel(int x, int y, bool on)QwtPixelMatrixinline
testPixel(int x, int y) const QwtPixelMatrixinline
~QwtPixelMatrix()QwtPixelMatrix
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_pixel_matrix.html b/ThirdParty/Qwt/doc/html/class_qwt_pixel_matrix.html new file mode 100644 index 0000000000..372f28e0bc --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_pixel_matrix.html @@ -0,0 +1,344 @@ + + + + + + +Qwt User's Guide: QwtPixelMatrix Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtPixelMatrix Class Reference
+
+
+ +

A bit field corresponding to the pixels of a rectangle. + More...

+ +

#include <qwt_pixel_matrix.h>

+
+Inheritance diagram for QwtPixelMatrix:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 QwtPixelMatrix (const QRect &rect)
 Constructor. More...
 
~QwtPixelMatrix ()
 Destructor.
 
void setRect (const QRect &rect)
 
QRect rect () const
 
bool testPixel (int x, int y) const
 Test if a pixel has been set. More...
 
bool testAndSetPixel (int x, int y, bool on)
 Set a pixel and test if a pixel has been set before. More...
 
int index (int x, int y) const
 Calculate the index in the bit field corresponding to a position. More...
 
+

Detailed Description

+

A bit field corresponding to the pixels of a rectangle.

+

QwtPixelMatrix is intended to filter out duplicates in an unsorted array of points.

+

Constructor & Destructor Documentation

+ +
+
+ + + + + + + + +
QwtPixelMatrix::QwtPixelMatrix (const QRect & rect)
+
+ +

Constructor.

+
Parameters
+ + +
rectBounding rectangle for the matrix
+
+
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
int QwtPixelMatrix::index (int x,
int y 
) const
+
+inline
+
+ +

Calculate the index in the bit field corresponding to a position.

+
Parameters
+ + + +
xX-coordinate
yY-coordinate
+
+
+
Returns
Index, when rect() contains pos - otherwise -1.
+ +
+
+ +
+
+ + + + + + + +
QRect QwtPixelMatrix::rect () const
+
+
Returns
Bounding rectangle
+ +
+
+ +
+
+ + + + + + + + +
void QwtPixelMatrix::setRect (const QRect & rect)
+
+

Set the bounding rectangle of the matrix

+
Parameters
+ + +
rectBounding rectangle
+
+
+
Note
All bits are cleared
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
bool QwtPixelMatrix::testAndSetPixel (int x,
int y,
bool on 
)
+
+inline
+
+ +

Set a pixel and test if a pixel has been set before.

+
Parameters
+ + + + +
xX-coordinate
yY-coordinate
onSet/Clear the pixel
+
+
+
Returns
true, when pos is outside of rect(), or when the pixel was set before.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool QwtPixelMatrix::testPixel (int x,
int y 
) const
+
+inline
+
+ +

Test if a pixel has been set.

+
Parameters
+ + + +
xX-coordinate
yY-coordinate
+
+
+
Returns
true, when pos is outside of rect(), or when the pixel has already been set.
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_pixel_matrix__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_pixel_matrix__inherit__graph.map new file mode 100644 index 0000000000..b10e0a5b8b --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_pixel_matrix__inherit__graph.map @@ -0,0 +1,2 @@ + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_pixel_matrix__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_pixel_matrix__inherit__graph.md5 new file mode 100644 index 0000000000..1ed3f662cc --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_pixel_matrix__inherit__graph.md5 @@ -0,0 +1 @@ +e0961647723ed59b73dcc04b95d53c8a \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_pixel_matrix__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_pixel_matrix__inherit__graph.png new file mode 100644 index 0000000000..8fb8e1e0c0 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_pixel_matrix__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plain_text_engine-members.html b/ThirdParty/Qwt/doc/html/class_qwt_plain_text_engine-members.html new file mode 100644 index 0000000000..010ff17a67 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plain_text_engine-members.html @@ -0,0 +1,109 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtPlainTextEngine Member List
+
+
+ +

This is the complete list of members for QwtPlainTextEngine, including all inherited members.

+ + + + + + + + + + +
draw(QPainter *painter, const QRectF &rect, int flags, const QString &text) const QwtPlainTextEnginevirtual
heightForWidth(const QFont &font, int flags, const QString &text, double width) const QwtPlainTextEnginevirtual
mightRender(const QString &) const QwtPlainTextEnginevirtual
QwtPlainTextEngine()QwtPlainTextEngine
QwtTextEngine()QwtTextEngineprotected
textMargins(const QFont &, const QString &, double &left, double &right, double &top, double &bottom) const QwtPlainTextEnginevirtual
textSize(const QFont &font, int flags, const QString &text) const QwtPlainTextEnginevirtual
~QwtPlainTextEngine()QwtPlainTextEnginevirtual
~QwtTextEngine()QwtTextEnginevirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plain_text_engine.html b/ThirdParty/Qwt/doc/html/class_qwt_plain_text_engine.html new file mode 100644 index 0000000000..84359b8b27 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plain_text_engine.html @@ -0,0 +1,422 @@ + + + + + + +Qwt User's Guide: QwtPlainTextEngine Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtPlainTextEngine Class Reference
+
+
+ +

A text engine for plain texts. + More...

+ +

#include <qwt_text_engine.h>

+
+Inheritance diagram for QwtPlainTextEngine:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

QwtPlainTextEngine ()
 Constructor.
 
+virtual ~QwtPlainTextEngine ()
 Destructor.
 
virtual double heightForWidth (const QFont &font, int flags, const QString &text, double width) const
 
virtual QSizeF textSize (const QFont &font, int flags, const QString &text) const
 
virtual void draw (QPainter *painter, const QRectF &rect, int flags, const QString &text) const
 Draw the text in a clipping rectangle. More...
 
virtual bool mightRender (const QString &) const
 
virtual void textMargins (const QFont &, const QString &, double &left, double &right, double &top, double &bottom) const
 
- Public Member Functions inherited from QwtTextEngine
+virtual ~QwtTextEngine ()
 Destructor.
 
+ + + + + +

+Additional Inherited Members

- Protected Member Functions inherited from QwtTextEngine
QwtTextEngine ()
 Constructor.
 
+

Detailed Description

+

A text engine for plain texts.

+

QwtPlainTextEngine renders texts using the basic Qt classes QPainter and QFontMetrics.

+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPlainTextEngine::draw (QPainter * painter,
const QRectF & rect,
int flags,
const QString & text 
) const
+
+virtual
+
+ +

Draw the text in a clipping rectangle.

+

A wrapper for QPainter::drawText.

+
Parameters
+ + + + + +
painterPainter
rectClipping rectangle
flagsBitwise OR of the flags used like in QPainter::drawText
textText to be rendered
+
+
+ +

Implements QwtTextEngine.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
double QwtPlainTextEngine::heightForWidth (const QFont & font,
int flags,
const QString & text,
double width 
) const
+
+virtual
+
+

Find the height for a given width

+
Parameters
+ + + + + +
fontFont of the text
flagsBitwise OR of the flags used like in QPainter::drawText
textText to be rendered
widthWidth
+
+
+
Returns
Calculated height
+ +

Implements QwtTextEngine.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool QwtPlainTextEngine::mightRender (const QString & ) const
+
+virtual
+
+

Test if a string can be rendered by this text engine.

+
Returns
Always true. All texts can be rendered by QwtPlainTextEngine
+ +

Implements QwtTextEngine.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPlainTextEngine::textMargins (const QFont & font,
const QString & ,
double & left,
double & right,
double & top,
double & bottom 
) const
+
+virtual
+
+

Return margins around the texts

+
Parameters
+ + + + + + +
fontFont of the text
leftReturn 0
rightReturn 0
topReturn value for the top margin
bottomReturn value for the bottom margin
+
+
+ +

Implements QwtTextEngine.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
QSizeF QwtPlainTextEngine::textSize (const QFont & font,
int flags,
const QString & text 
) const
+
+virtual
+
+

Returns the size, that is needed to render text

+
Parameters
+ + + + +
fontFont of the text
flagsBitwise OR of the flags used like in QPainter::drawText
textText to be rendered
+
+
+
Returns
Caluclated size
+ +

Implements QwtTextEngine.

+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plain_text_engine__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_plain_text_engine__inherit__graph.map new file mode 100644 index 0000000000..59a9739ff0 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plain_text_engine__inherit__graph.map @@ -0,0 +1,3 @@ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plain_text_engine__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_plain_text_engine__inherit__graph.md5 new file mode 100644 index 0000000000..2898d962e3 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plain_text_engine__inherit__graph.md5 @@ -0,0 +1 @@ +6dd8200b09764c12cb1994058e270f89 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plain_text_engine__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_plain_text_engine__inherit__graph.png new file mode 100644 index 0000000000..b6c64ac6e4 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_plain_text_engine__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot-members.html b/ThirdParty/Qwt/doc/html/class_qwt_plot-members.html new file mode 100644 index 0000000000..a9f76cd679 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot-members.html @@ -0,0 +1,200 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtPlot Member List
+
+
+ +

This is the complete list of members for QwtPlot, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
applyProperties(const QString &)QwtPlot
autoDelete() const QwtPlotDict
autoRefresh()QwtPlotslot
autoReplot() const QwtPlot
Axis enum nameQwtPlot
axisAutoScale(int axisId) const QwtPlot
axisCnt enum valueQwtPlot
axisEnabled(int axisId) const QwtPlot
axisFont(int axisId) const QwtPlot
axisInterval(int axisId) const QwtPlot
axisMaxMajor(int axisId) const QwtPlot
axisMaxMinor(int axisId) const QwtPlot
axisScaleDiv(int axisId) const QwtPlot
axisScaleDraw(int axisId) const QwtPlot
axisScaleDraw(int axisId)QwtPlot
axisScaleEngine(int axisId)QwtPlot
axisScaleEngine(int axisId) const QwtPlot
axisStepSize(int axisId) const QwtPlot
axisTitle(int axisId) const QwtPlot
axisValid(int axisId)QwtPlotprotectedstatic
axisWidget(int axisId) const QwtPlot
axisWidget(int axisId)QwtPlot
BottomLegend enum valueQwtPlot
canvas()QwtPlot
canvas() const QwtPlot
canvasBackground() const QwtPlot
canvasMap(int axisId) const QwtPlotvirtual
detachItems(int rtti=QwtPlotItem::Rtti_PlotItem, bool autoDelete=true)QwtPlotDict
drawCanvas(QPainter *)QwtPlotvirtual
drawItems(QPainter *, const QRectF &, const QwtScaleMap maps[axisCnt]) const QwtPlotvirtual
enableAxis(int axisId, bool tf=true)QwtPlot
event(QEvent *)QwtPlotvirtual
eventFilter(QObject *, QEvent *)QwtPlotvirtual
footer() const QwtPlot
footerLabel()QwtPlot
footerLabel() const QwtPlot
getCanvasMarginsHint(const QwtScaleMap maps[], const QRectF &canvasRect, double &left, double &top, double &right, double &bottom) const QwtPlotvirtual
grabProperties() const QwtPlot
infoToItem(const QVariant &) const QwtPlotvirtual
insertItem(QwtPlotItem *)QwtPlotDictprotected
insertLegend(QwtAbstractLegend *, LegendPosition=QwtPlot::RightLegend, double ratio=-1.0)QwtPlot
invTransform(int axisId, int pos) const QwtPlot
itemAttached(QwtPlotItem *plotItem, bool on)QwtPlotsignal
itemList() const QwtPlotDict
itemList(int rtti) const QwtPlotDict
itemToInfo(QwtPlotItem *) const QwtPlotvirtual
LeftLegend enum valueQwtPlot
legend()QwtPlot
legend() const QwtPlot
legendDataChanged(const QVariant &itemInfo, const QList< QwtLegendData > &data)QwtPlotsignal
LegendPosition enum nameQwtPlot
minimumSizeHint() const QwtPlotvirtual
plotLayout()QwtPlot
plotLayout() const QwtPlot
QwtPlot(QWidget *=NULL)QwtPlotexplicit
QwtPlot(const QwtText &title, QWidget *=NULL)QwtPlotexplicit
QwtPlotDict()QwtPlotDictexplicit
QwtPlotItem (defined in QwtPlot)QwtPlotfriend
removeItem(QwtPlotItem *)QwtPlotDictprotected
replot()QwtPlotvirtualslot
resizeEvent(QResizeEvent *e)QwtPlotprotectedvirtual
RightLegend enum valueQwtPlot
setAutoDelete(bool)QwtPlotDict
setAutoReplot(bool=true)QwtPlot
setAxisAutoScale(int axisId, bool on=true)QwtPlot
setAxisFont(int axisId, const QFont &f)QwtPlot
setAxisLabelAlignment(int axisId, Qt::Alignment)QwtPlot
setAxisLabelRotation(int axisId, double rotation)QwtPlot
setAxisMaxMajor(int axisId, int maxMajor)QwtPlot
setAxisMaxMinor(int axisId, int maxMinor)QwtPlot
setAxisScale(int axisId, double min, double max, double step=0)QwtPlot
setAxisScaleDiv(int axisId, const QwtScaleDiv &)QwtPlot
setAxisScaleDraw(int axisId, QwtScaleDraw *)QwtPlot
setAxisScaleEngine(int axisId, QwtScaleEngine *)QwtPlot
setAxisTitle(int axisId, const QString &)QwtPlot
setAxisTitle(int axisId, const QwtText &)QwtPlot
setCanvas(QWidget *)QwtPlot
setCanvasBackground(const QBrush &)QwtPlot
setFooter(const QString &)QwtPlot
setFooter(const QwtText &t)QwtPlot
setPlotLayout(QwtPlotLayout *)QwtPlot
setTitle(const QString &)QwtPlot
setTitle(const QwtText &t)QwtPlot
sizeHint() const QwtPlotvirtual
title() const QwtPlot
titleLabel()QwtPlot
titleLabel() const QwtPlot
TopLegend enum valueQwtPlot
transform(int axisId, double value) const QwtPlot
updateAxes()QwtPlot
updateCanvasMargins()QwtPlot
updateLayout()QwtPlotvirtual
updateLegend()QwtPlot
updateLegend(const QwtPlotItem *)QwtPlot
xBottom enum valueQwtPlot
xTop enum valueQwtPlot
yLeft enum valueQwtPlot
yRight enum valueQwtPlot
~QwtPlot()QwtPlotvirtual
~QwtPlotDict()QwtPlotDictvirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot.html b/ThirdParty/Qwt/doc/html/class_qwt_plot.html new file mode 100644 index 0000000000..d207ec428e --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot.html @@ -0,0 +1,2625 @@ + + + + + + +Qwt User's Guide: QwtPlot Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+ +
+ +

A 2-D plotting widget. + More...

+ +

#include <qwt_plot.h>

+
+Inheritance diagram for QwtPlot:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + +

+Public Types

enum  Axis {
+  yLeft, +yRight, +xBottom, +xTop, +
+  axisCnt +
+ }
 Axis index. More...
 
enum  LegendPosition { LeftLegend, +RightLegend, +BottomLegend, +TopLegend + }
 
+ + + + + + + +

+Public Slots

virtual void replot ()
 Redraw the plot. More...
 
+void autoRefresh ()
 Replots the plot if autoReplot() is true.
 
+ + + + + +

+Signals

void itemAttached (QwtPlotItem *plotItem, bool on)
 
void legendDataChanged (const QVariant &itemInfo, const QList< QwtLegendData > &data)
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 QwtPlot (QWidget *=NULL)
 Constructor. More...
 
 QwtPlot (const QwtText &title, QWidget *=NULL)
 Constructor. More...
 
+virtual ~QwtPlot ()
 Destructor.
 
void applyProperties (const QString &)
 
QString grabProperties () const
 
void setAutoReplot (bool=true)
 Set or reset the autoReplot option. More...
 
bool autoReplot () const
 
void setPlotLayout (QwtPlotLayout *)
 Assign a new plot layout. More...
 
QwtPlotLayoutplotLayout ()
 
const QwtPlotLayoutplotLayout () const
 
void setTitle (const QString &)
 
void setTitle (const QwtText &t)
 
QwtText title () const
 
QwtTextLabeltitleLabel ()
 
const QwtTextLabeltitleLabel () const
 
void setFooter (const QString &)
 
void setFooter (const QwtText &t)
 
QwtText footer () const
 
QwtTextLabelfooterLabel ()
 
const QwtTextLabelfooterLabel () const
 
void setCanvas (QWidget *)
 Set the drawing canvas of the plot widget. More...
 
QWidget * canvas ()
 
const QWidget * canvas () const
 
void setCanvasBackground (const QBrush &)
 Change the background of the plotting area. More...
 
QBrush canvasBackground () const
 
virtual QwtScaleMap canvasMap (int axisId) const
 
double invTransform (int axisId, int pos) const
 
double transform (int axisId, double value) const
 Transform a value into a coordinate in the plotting region. More...
 
QwtScaleEngineaxisScaleEngine (int axisId)
 
const QwtScaleEngineaxisScaleEngine (int axisId) const
 
void setAxisScaleEngine (int axisId, QwtScaleEngine *)
 
void setAxisAutoScale (int axisId, bool on=true)
 Enable autoscaling for a specified axis. More...
 
bool axisAutoScale (int axisId) const
 
void enableAxis (int axisId, bool tf=true)
 Enable or disable a specified axis. More...
 
bool axisEnabled (int axisId) const
 
void setAxisFont (int axisId, const QFont &f)
 Change the font of an axis. More...
 
QFont axisFont (int axisId) const
 
void setAxisScale (int axisId, double min, double max, double step=0)
 Disable autoscaling and specify a fixed scale for a selected axis. More...
 
void setAxisScaleDiv (int axisId, const QwtScaleDiv &)
 Disable autoscaling and specify a fixed scale for a selected axis. More...
 
void setAxisScaleDraw (int axisId, QwtScaleDraw *)
 Set a scale draw. More...
 
double axisStepSize (int axisId) const
 Return the step size parameter that has been set in setAxisScale. More...
 
QwtInterval axisInterval (int axisId) const
 Return the current interval of the specified axis. More...
 
const QwtScaleDivaxisScaleDiv (int axisId) const
 Return the scale division of a specified axis. More...
 
const QwtScaleDrawaxisScaleDraw (int axisId) const
 Return the scale draw of a specified axis. More...
 
QwtScaleDrawaxisScaleDraw (int axisId)
 Return the scale draw of a specified axis. More...
 
const QwtScaleWidgetaxisWidget (int axisId) const
 
QwtScaleWidgetaxisWidget (int axisId)
 
void setAxisLabelAlignment (int axisId, Qt::Alignment)
 
void setAxisLabelRotation (int axisId, double rotation)
 
void setAxisTitle (int axisId, const QString &)
 Change the title of a specified axis. More...
 
void setAxisTitle (int axisId, const QwtText &)
 Change the title of a specified axis. More...
 
QwtText axisTitle (int axisId) const
 
void setAxisMaxMinor (int axisId, int maxMinor)
 
int axisMaxMinor (int axisId) const
 
void setAxisMaxMajor (int axisId, int maxMajor)
 
int axisMaxMajor (int axisId) const
 
void insertLegend (QwtAbstractLegend *, LegendPosition=QwtPlot::RightLegend, double ratio=-1.0)
 Insert a legend. More...
 
QwtAbstractLegendlegend ()
 
const QwtAbstractLegendlegend () const
 
void updateLegend ()
 
void updateLegend (const QwtPlotItem *)
 
virtual QSize sizeHint () const
 
+virtual QSize minimumSizeHint () const
 Return a minimum size hint.
 
virtual void updateLayout ()
 Adjust plot content to its current size. More...
 
virtual void drawCanvas (QPainter *)
 
void updateAxes ()
 Rebuild the axes scales. More...
 
void updateCanvasMargins ()
 Update the canvas margins. More...
 
virtual void getCanvasMarginsHint (const QwtScaleMap maps[], const QRectF &canvasRect, double &left, double &top, double &right, double &bottom) const
 Calculate the canvas margins. More...
 
virtual bool event (QEvent *)
 Adds handling of layout requests. More...
 
virtual bool eventFilter (QObject *, QEvent *)
 Event filter. More...
 
virtual void drawItems (QPainter *, const QRectF &, const QwtScaleMap maps[axisCnt]) const
 
virtual QVariant itemToInfo (QwtPlotItem *) const
 Build an information, that can be used to identify a plot item on the legend. More...
 
virtual QwtPlotIteminfoToItem (const QVariant &) const
 Identify the plot item according to an item info object, that has bee generated from itemToInfo(). More...
 
- Public Member Functions inherited from QwtPlotDict
 QwtPlotDict ()
 
virtual ~QwtPlotDict ()
 
void setAutoDelete (bool)
 
bool autoDelete () const
 
const QwtPlotItemList & itemList () const
 A QwtPlotItemList of all attached plot items. More...
 
QwtPlotItemList itemList (int rtti) const
 
void detachItems (int rtti=QwtPlotItem::Rtti_PlotItem, bool autoDelete=true)
 
+ + + + + + + + +

+Protected Member Functions

virtual void resizeEvent (QResizeEvent *e)
 
- Protected Member Functions inherited from QwtPlotDict
void insertItem (QwtPlotItem *)
 
void removeItem (QwtPlotItem *)
 
+ + + +

+Static Protected Member Functions

static bool axisValid (int axisId)
 
+ + + +

+Friends

+class QwtPlotItem
 
+

Detailed Description

+

A 2-D plotting widget.

+

QwtPlot is a widget for plotting two-dimensional graphs. An unlimited number of plot items can be displayed on its canvas. Plot items might be curves (QwtPlotCurve), markers (QwtPlotMarker), the grid (QwtPlotGrid), or anything else derived from QwtPlotItem. A plot can have up to four axes, with each plot item attached to an x- and a y axis. The scales at the axes can be explicitly set (QwtScaleDiv), or are calculated from the plot items, using algorithms (QwtScaleEngine) which can be configured separately for each axis.

+

The simpleplot example is a good starting point to see how to set up a plot widget.

+
+plot.png +
+
Example
The following example shows (schematically) the most simple way to use QwtPlot. By default, only the left and bottom axes are visible and their scales are computed automatically.
#include <qwt_plot.h>
+#include <qwt_plot_curve.h>
+
+QwtPlot *myPlot = new QwtPlot("Two Curves", parent);
+
+// add curves
+QwtPlotCurve *curve1 = new QwtPlotCurve("Curve 1");
+QwtPlotCurve *curve2 = new QwtPlotCurve("Curve 2");
+
+// connect or copy the data to the curves
+curve1->setData(...);
+curve2->setData(...);
+
+curve1->attach(myPlot);
+curve2->attach(myPlot);
+
+// finally, refresh the plot
+myPlot->replot();
+
+

Member Enumeration Documentation

+ +
+
+ + + + +
enum QwtPlot::Axis
+
+ +

Axis index.

+ + + + + + +
Enumerator
yLeft  +

Y axis left of the canvas.

+
yRight  +

Y axis right of the canvas.

+
xBottom  +

X axis below the canvas.

+
xTop  +

X axis above the canvas.

+
axisCnt  +

Number of axes.

+
+ +
+
+ +
+
+ + + + +
enum QwtPlot::LegendPosition
+
+

Position of the legend, relative to the canvas.

+
See Also
insertLegend()
+ + + + + +
Enumerator
LeftLegend  +

The legend will be left from the QwtPlot::yLeft axis.

+
RightLegend  +

The legend will be right from the QwtPlot::yRight axis.

+
BottomLegend  +

The legend will be below the footer.

+
TopLegend  +

The legend will be above the title.

+
+ +
+
+

Constructor & Destructor Documentation

+ +
+
+ + + + + +
+ + + + + + + + +
QwtPlot::QwtPlot (QWidget * parent = NULL)
+
+explicit
+
+ +

Constructor.

+
Parameters
+ + +
parentParent widget
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
QwtPlot::QwtPlot (const QwtTexttitle,
QWidget * parent = NULL 
)
+
+explicit
+
+ +

Constructor.

+
Parameters
+ + + +
titleTitle text
parentParent widget
+
+
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + + + + +
void QwtPlot::applyProperties (const QString & )
+
+

This method is intended for manipulating the plot widget from a specific editor in the Qwt designer plugin.

+
Warning
The plot editor has never been implemented.
+ +
+
+ +
+
+ + + + + + + +
bool QwtPlot::autoReplot () const
+
+
Returns
true if the autoReplot option is set.
+
See Also
setAutoReplot()
+ +
+
+ +
+
+ + + + + + + + +
bool QwtPlot::axisAutoScale (int axisId) const
+
+
Returns
True, if autoscaling is enabled
+
Parameters
+ + +
axisIdAxis index
+
+
+ +
+
+ +
+
+ + + + + + + + +
bool QwtPlot::axisEnabled (int axisId) const
+
+
Returns
True, if a specified axis is enabled
+
Parameters
+ + +
axisIdAxis index
+
+
+ +
+
+ +
+
+ + + + + + + + +
QFont QwtPlot::axisFont (int axisId) const
+
+
Returns
The font of the scale labels for a specified axis
+
Parameters
+ + +
axisIdAxis index
+
+
+ +
+
+ +
+
+ + + + + + + + +
QwtInterval QwtPlot::axisInterval (int axisId) const
+
+ +

Return the current interval of the specified axis.

+

This is only a convenience function for axisScaleDiv( axisId )->interval();

+
Parameters
+ + +
axisIdAxis index
+
+
+
Returns
Scale interval
+
See Also
QwtScaleDiv, axisScaleDiv()
+ +
+
+ +
+
+ + + + + + + + +
int QwtPlot::axisMaxMajor (int axisId) const
+
+
Returns
The maximum number of major ticks for a specified axis
+
Parameters
+ + +
axisIdAxis index
+
+
+
See Also
setAxisMaxMajor(), QwtScaleEngine::divideScale()
+ +
+
+ +
+
+ + + + + + + + +
int QwtPlot::axisMaxMinor (int axisId) const
+
+
Returns
the maximum number of minor ticks for a specified axis
+
Parameters
+ + +
axisIdAxis index
+
+
+
See Also
setAxisMaxMinor(), QwtScaleEngine::divideScale()
+ +
+
+ +
+
+ + + + + + + + +
const QwtScaleDiv & QwtPlot::axisScaleDiv (int axisId) const
+
+ +

Return the scale division of a specified axis.

+

axisScaleDiv(axisId).lowerBound(), axisScaleDiv(axisId).upperBound() are the current limits of the axis scale.

+
Parameters
+ + +
axisIdAxis index
+
+
+
Returns
Scale division
+
See Also
QwtScaleDiv, setAxisScaleDiv(), QwtScaleEngine::divideScale()
+ +
+
+ +
+
+ + + + + + + + +
const QwtScaleDraw * QwtPlot::axisScaleDraw (int axisId) const
+
+ +

Return the scale draw of a specified axis.

+
Parameters
+ + +
axisIdAxis index
+
+
+
Returns
Specified scaleDraw for axis, or NULL if axis is invalid.
+ +
+
+ +
+
+ + + + + + + + +
QwtScaleDraw * QwtPlot::axisScaleDraw (int axisId)
+
+ +

Return the scale draw of a specified axis.

+
Parameters
+ + +
axisIdAxis index
+
+
+
Returns
Specified scaleDraw for axis, or NULL if axis is invalid.
+ +
+
+ +
+
+ + + + + + + + +
QwtScaleEngine * QwtPlot::axisScaleEngine (int axisId)
+
+
Parameters
+ + +
axisIdAxis index
+
+
+
Returns
Scale engine for a specific axis
+ +
+
+ +
+
+ + + + + + + + +
const QwtScaleEngine * QwtPlot::axisScaleEngine (int axisId) const
+
+
Parameters
+ + +
axisIdAxis index
+
+
+
Returns
Scale engine for a specific axis
+ +
+
+ +
+
+ + + + + + + + +
double QwtPlot::axisStepSize (int axisId) const
+
+ +

Return the step size parameter that has been set in setAxisScale.

+

This doesn't need to be the step size of the current scale.

+
Parameters
+ + +
axisIdAxis index
+
+
+
Returns
step size parameter value
+
See Also
setAxisScale(), QwtScaleEngine::divideScale()
+ +
+
+ +
+
+ + + + + + + + +
QwtText QwtPlot::axisTitle (int axisId) const
+
+
Returns
Title of a specified axis
+
Parameters
+ + +
axisIdAxis index
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool QwtPlot::axisValid (int axisId)
+
+staticprotected
+
+
Returns
true if the specified axis exists, otherwise false
+
Parameters
+ + +
axisIdaxis index
+
+
+ +
+
+ +
+
+ + + + + + + + +
const QwtScaleWidget * QwtPlot::axisWidget (int axisId) const
+
+
Returns
Scale widget of the specified axis, or NULL if axisId is invalid.
+
Parameters
+ + +
axisIdAxis index
+
+
+ +
+
+ +
+
+ + + + + + + + +
QwtScaleWidget * QwtPlot::axisWidget (int axisId)
+
+
Returns
Scale widget of the specified axis, or NULL if axisId is invalid.
+
Parameters
+ + +
axisIdAxis index
+
+
+ +
+
+ +
+
+ + + + + + + +
QWidget * QwtPlot::canvas ()
+
+
Returns
the plot's canvas
+ +
+
+ +
+
+ + + + + + + +
const QWidget * QwtPlot::canvas () const
+
+
Returns
the plot's canvas
+ +
+
+ +
+
+ + + + + + + +
QBrush QwtPlot::canvasBackground () const
+
+

Nothing else than: canvas()->palette().brush( QPalette::Normal, QPalette::Window);

+
Returns
Background brush of the plotting area.
+
See Also
setCanvasBackground()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
QwtScaleMap QwtPlot::canvasMap (int axisId) const
+
+virtual
+
+
Parameters
+ + +
axisIdAxis
+
+
+
Returns
Map for the axis on the canvas. With this map pixel coordinates can translated to plot coordinates and vice versa.
+
See Also
QwtScaleMap, transform(), invTransform()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtPlot::drawCanvas (QPainter * painter)
+
+virtual
+
+

Redraw the canvas.

+
Parameters
+ + +
painterPainter used for drawing
+
+
+
Warning
drawCanvas calls drawItems what is also used for printing. Applications that like to add individual plot items better overload drawItems()
+
See Also
drawItems()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPlot::drawItems (QPainter * painter,
const QRectF & canvasRect,
const QwtScaleMap maps[axisCnt] 
) const
+
+virtual
+
+

Redraw the canvas items.

+
Parameters
+ + + + +
painterPainter used for drawing
canvasRectBounding rectangle where to paint
mapsQwtPlot::axisCnt maps, mapping between plot and paint device coordinates
+
+
+
Note
Usually canvasRect is contentsRect() of the plot canvas. Due to a bug in Qt this rectangle might be wrong for certain frame styles ( f.e QFrame::Box ) and it might be necessary to fix the margins manually using QWidget::setContentsMargins()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtPlot::enableAxis (int axisId,
bool tf = true 
)
+
+ +

Enable or disable a specified axis.

+

When an axis is disabled, this only means that it is not visible on the screen. Curves, markers and can be attached to disabled axes, and transformation of screen coordinates into values works as normal.

+

Only xBottom and yLeft are enabled by default.

+
Parameters
+ + + +
axisIdAxis index
tftrue (enabled) or false (disabled)
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool QwtPlot::event (QEvent * event)
+
+virtual
+
+ +

Adds handling of layout requests.

+
Parameters
+ + +
eventEvent
+
+
+
Returns
See QFrame::event()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool QwtPlot::eventFilter (QObject * object,
QEvent * event 
)
+
+virtual
+
+ +

Event filter.

+

The plot handles the following events for the canvas:

+
    +
  • QEvent::Resize The canvas margins might depend on its size
  • +
+
    +
  • QEvent::ContentsRectChange The layout needs to be recalculated
  • +
+
Parameters
+ + + +
objectObject to be filtered
eventEvent
+
+
+
Returns
See QFrame::eventFilter()
+
See Also
updateCanvasMargins(), updateLayout()
+ +
+
+ +
+
+ + + + + + + +
QwtText QwtPlot::footer () const
+
+
Returns
Text of the footer
+ +
+
+ +
+
+ + + + + + + +
QwtTextLabel * QwtPlot::footerLabel ()
+
+
Returns
Footer label widget.
+ +
+
+ +
+
+ + + + + + + +
const QwtTextLabel * QwtPlot::footerLabel () const
+
+
Returns
Footer label widget.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPlot::getCanvasMarginsHint (const QwtScaleMap maps[],
const QRectF & canvasRect,
double & left,
double & top,
double & right,
double & bottom 
) const
+
+virtual
+
+ +

Calculate the canvas margins.

+
Parameters
+ + + + + + + +
mapsQwtPlot::axisCnt maps, mapping between plot and paint device coordinates
canvasRectBounding rectangle where to paint
leftReturn parameter for the left margin
topReturn parameter for the top margin
rightReturn parameter for the right margin
bottomReturn parameter for the bottom margin
+
+
+

Plot items might indicate, that they need some extra space at the borders of the canvas by the QwtPlotItem::Margins flag.

+

updateCanvasMargins(), QwtPlotItem::getCanvasMarginHint()

+ +
+
+ +
+
+ + + + + + + +
QString QwtPlot::grabProperties () const
+
+

This method is intended for manipulating the plot widget from a specific editor in the Qwt designer plugin.

+
Returns
QString::null
+
Warning
The plot editor has never been implemented.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
QwtPlotItem * QwtPlot::infoToItem (const QVariant & itemInfo) const
+
+virtual
+
+ +

Identify the plot item according to an item info object, that has bee generated from itemToInfo().

+

The default implementation simply tries to unwrap a QwtPlotItem pointer:

+
if ( itemInfo.canConvert<QwtPlotItem *>() )
+
return qvariant_cast<QwtPlotItem *>( itemInfo );
+
Parameters
+ + +
itemInfoPlot item
+
+
+
Returns
A plot item, when successful, otherwise a NULL pointer.
+
See Also
itemToInfo()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPlot::insertLegend (QwtAbstractLegendlegend,
QwtPlot::LegendPosition pos = QwtPlot::RightLegend,
double ratio = -1.0 
)
+
+ +

Insert a legend.

+

If the position legend is QwtPlot::LeftLegend or QwtPlot::RightLegend the legend will be organized in one column from top to down. Otherwise the legend items will be placed in a table with a best fit number of columns from left to right.

+

insertLegend() will set the plot widget as parent for the legend. The legend will be deleted in the destructor of the plot or when another legend is inserted.

+

Legends, that are not inserted into the layout of the plot widget need to connect to the legendDataChanged() signal. Calling updateLegend() initiates this signal for an initial update. When the application code wants to implement its own layout this also needs to be done for rendering plots to a document ( see QwtPlotRenderer ).

+
Parameters
+ + + + +
legendLegend
posThe legend's position. For top/left position the number of columns will be limited to 1, otherwise it will be set to unlimited.
ratioRatio between legend and the bounding rectangle of title, canvas and axes. The legend will be shrunk if it would need more space than the given ratio. The ratio is limited to ]0.0 .. 1.0]. In case of <= 0.0 it will be reset to the default ratio. The default vertical/horizontal ratio is 0.33/0.5.
+
+
+
See Also
legend(), QwtPlotLayout::legendPosition(), QwtPlotLayout::setLegendPosition()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
double QwtPlot::invTransform (int axisId,
int pos 
) const
+
+

Transform the x or y coordinate of a position in the drawing region into a value.

+
Parameters
+ + + +
axisIdAxis index
posposition
+
+
+
Returns
Position as axis coordinate
+
Warning
The position can be an x or a y coordinate, depending on the specified axis.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void QwtPlot::itemAttached (QwtPlotItemplotItem,
bool on 
)
+
+signal
+
+

A signal indicating, that an item has been attached/detached

+
Parameters
+ + + +
plotItemPlot item
onAttached/Detached
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
QVariant QwtPlot::itemToInfo (QwtPlotItemplotItem) const
+
+virtual
+
+ +

Build an information, that can be used to identify a plot item on the legend.

+

The default implementation simply wraps the plot item into a QVariant object. When overloading itemToInfo() usually infoToItem() needs to reimplemeted too.

+
QVariant itemInfo;
+
qVariantSetValue( itemInfo, plotItem );
+
Parameters
+ + +
plotItemPlot item
+
+
+
Returns
Plot item embedded in a QVariant
+
See Also
infoToItem()
+ +
+
+ +
+
+ + + + + + + +
QwtAbstractLegend * QwtPlot::legend ()
+
+
Returns
the plot's legend
+
See Also
insertLegend()
+ +
+
+ +
+
+ + + + + + + +
const QwtAbstractLegend * QwtPlot::legend () const
+
+
Returns
the plot's legend
+
See Also
insertLegend()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void QwtPlot::legendDataChanged (const QVariant & itemInfo,
const QList< QwtLegendData > & data 
)
+
+signal
+
+

A signal with the attributes how to update the legend entries for a plot item.

+
Parameters
+ + + +
itemInfoInfo about a plot item, build from itemToInfo()
dataAttributes of the entries ( usually <= 1 ) for the plot item.
+
+
+
See Also
itemToInfo(), infoToItem(), QwtAbstractLegend::updateLegend()
+ +
+
+ +
+
+ + + + + + + +
QwtPlotLayout * QwtPlot::plotLayout ()
+
+
Returns
the plot's layout
+ +
+
+ +
+
+ + + + + + + +
const QwtPlotLayout * QwtPlot::plotLayout () const
+
+
Returns
the plot's layout
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void QwtPlot::replot ()
+
+virtualslot
+
+ +

Redraw the plot.

+

If the autoReplot option is not set (which is the default) or if any curves are attached to raw data, the plot has to be refreshed explicitly in order to make changes visible.

+
See Also
updateAxes(), setAutoReplot()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtPlot::resizeEvent (QResizeEvent * e)
+
+protectedvirtual
+
+

Resize and update internal layout

+
Parameters
+ + +
eResize event
+
+
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlot::setAutoReplot (bool tf = true)
+
+ +

Set or reset the autoReplot option.

+

If the autoReplot option is set, the plot will be updated implicitly by manipulating member functions. Since this may be time-consuming, it is recommended to leave this option switched off and call replot() explicitly if necessary.

+

The autoReplot option is set to false by default, which means that the user has to call replot() in order to make changes visible.

+
Parameters
+ + +
tftrue or false. Defaults to true.
+
+
+
See Also
replot()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtPlot::setAxisAutoScale (int axisId,
bool on = true 
)
+
+ +

Enable autoscaling for a specified axis.

+

This member function is used to switch back to autoscaling mode after a fixed scale has been set. Autoscaling is enabled by default.

+
Parameters
+ + + +
axisIdAxis index
onOn/Off
+
+
+
See Also
setAxisScale(), setAxisScaleDiv(), updateAxes()
+
Note
The autoscaling flag has no effect until updateAxes() is executed ( called by replot() ).
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtPlot::setAxisFont (int axisId,
const QFont & font 
)
+
+ +

Change the font of an axis.

+
Parameters
+ + + +
axisIdAxis index
fontFont
+
+
+
Warning
This function changes the font of the tick labels, not of the axis title.
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtPlot::setAxisLabelAlignment (int axisId,
Qt::Alignment alignment 
)
+
+

Change the alignment of the tick labels

+
Parameters
+ + + +
axisIdAxis index
alignmentOr'd Qt::AlignmentFlags see <qnamespace.h>
+
+
+
See Also
QwtScaleDraw::setLabelAlignment()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtPlot::setAxisLabelRotation (int axisId,
double rotation 
)
+
+

Rotate all tick labels

+
Parameters
+ + + +
axisIdAxis index
rotationAngle in degrees. When changing the label rotation, the label alignment might be adjusted too.
+
+
+
See Also
QwtScaleDraw::setLabelRotation(), setAxisLabelAlignment()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtPlot::setAxisMaxMajor (int axisId,
int maxMajor 
)
+
+

Set the maximum number of major scale intervals for a specified axis

+
Parameters
+ + + +
axisIdAxis index
maxMajorMaximum number of major steps
+
+
+
See Also
axisMaxMajor()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtPlot::setAxisMaxMinor (int axisId,
int maxMinor 
)
+
+

Set the maximum number of minor scale intervals for a specified axis

+
Parameters
+ + + +
axisIdAxis index
maxMinorMaximum number of minor steps
+
+
+
See Also
axisMaxMinor()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPlot::setAxisScale (int axisId,
double min,
double max,
double stepSize = 0 
)
+
+ +

Disable autoscaling and specify a fixed scale for a selected axis.

+

In updateAxes() the scale engine calculates a scale division from the specified parameters, that will be assigned to the scale widget. So updates of the scale widget usually happen delayed with the next replot.

+
Parameters
+ + + + + +
axisIdAxis index
minMinimum of the scale
maxMaximum of the scale
stepSizeMajor step size. If step == 0, the step size is calculated automatically using the maxMajor setting.
+
+
+
See Also
setAxisMaxMajor(), setAxisAutoScale(), axisStepSize(), QwtScaleEngine::divideScale()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtPlot::setAxisScaleDiv (int axisId,
const QwtScaleDivscaleDiv 
)
+
+ +

Disable autoscaling and specify a fixed scale for a selected axis.

+

The scale division will be stored locally only until the next call of updateAxes(). So updates of the scale widget usually happen delayed with the next replot.

+
Parameters
+ + + +
axisIdAxis index
scaleDivScale division
+
+
+
See Also
setAxisScale(), setAxisAutoScale()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtPlot::setAxisScaleDraw (int axisId,
QwtScaleDrawscaleDraw 
)
+
+ +

Set a scale draw.

+
Parameters
+ + + +
axisIdAxis index
scaleDrawObject responsible for drawing scales.
+
+
+

By passing scaleDraw it is possible to extend QwtScaleDraw functionality and let it take place in QwtPlot. Please note that scaleDraw has to be created with new and will be deleted by the corresponding QwtScale member ( like a child object ).

+
See Also
QwtScaleDraw, QwtScaleWidget
+
Warning
The attributes of scaleDraw will be overwritten by those of the previous QwtScaleDraw.
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtPlot::setAxisScaleEngine (int axisId,
QwtScaleEnginescaleEngine 
)
+
+

Change the scale engine for an axis

+
Parameters
+ + + +
axisIdAxis index
scaleEngineScale engine
+
+
+
See Also
axisScaleEngine()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtPlot::setAxisTitle (int axisId,
const QString & title 
)
+
+ +

Change the title of a specified axis.

+
Parameters
+ + + +
axisIdAxis index
titleaxis title
+
+
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtPlot::setAxisTitle (int axisId,
const QwtTexttitle 
)
+
+ +

Change the title of a specified axis.

+
Parameters
+ + + +
axisIdAxis index
titleAxis title
+
+
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlot::setCanvas (QWidget * canvas)
+
+ +

Set the drawing canvas of the plot widget.

+

QwtPlot invokes methods of the canvas as meta methods ( see QMetaObject ). In opposite to using conventional C++ techniques like virtual methods they allow to use canvas implementations that are derived from QWidget or QGLWidget.

+

The following meta methods could be implemented:

+
    +
  • replot() When the canvas doesn't offer a replot method, QwtPlot calls update() instead.
  • +
+
    +
  • borderPath() The border path is necessary to clip the content of the canvas When the canvas doesn't have any special border ( f.e rounded corners ) it is o.k. not to implement this method.
  • +
+

The default canvas is a QwtPlotCanvas

+
Parameters
+ + +
canvasCanvas Widget
+
+
+
See Also
canvas()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlot::setCanvasBackground (const QBrush & brush)
+
+ +

Change the background of the plotting area.

+

Sets brush to QPalette::Window of all color groups of the palette of the canvas. Using canvas()->setPalette() is a more powerful way to set these colors.

+
Parameters
+ + +
brushNew background brush
+
+
+
See Also
canvasBackground()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlot::setFooter (const QString & text)
+
+

Change the text the footer

+
Parameters
+ + +
textNew text of the footer
+
+
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlot::setFooter (const QwtTexttext)
+
+

Change the text the footer

+
Parameters
+ + +
textNew text of the footer
+
+
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlot::setPlotLayout (QwtPlotLayoutlayout)
+
+ +

Assign a new plot layout.

+
Parameters
+ + +
layoutLayout()
+
+
+
See Also
plotLayout()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlot::setTitle (const QString & title)
+
+

Change the plot's title

+
Parameters
+ + +
titleNew title
+
+
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlot::setTitle (const QwtTexttitle)
+
+

Change the plot's title

+
Parameters
+ + +
titleNew title
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
QSize QwtPlot::sizeHint () const
+
+virtual
+
+
Returns
Size hint for the plot widget
+
See Also
minimumSizeHint()
+ +
+
+ +
+
+ + + + + + + +
QwtText QwtPlot::title () const
+
+
Returns
Title of the plot
+ +
+
+ +
+
+ + + + + + + +
QwtTextLabel * QwtPlot::titleLabel ()
+
+
Returns
Title label widget.
+ +
+
+ +
+
+ + + + + + + +
const QwtTextLabel * QwtPlot::titleLabel () const
+
+
Returns
Title label widget.
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
double QwtPlot::transform (int axisId,
double value 
) const
+
+ +

Transform a value into a coordinate in the plotting region.

+
Parameters
+ + + +
axisIdAxis index
valuevalue
+
+
+
Returns
X or Y coordinate in the plotting region corresponding to the value.
+ +
+
+ +
+
+ + + + + + + +
void QwtPlot::updateAxes ()
+
+ +

Rebuild the axes scales.

+

In case of autoscaling the boundaries of a scale are calculated from the bounding rectangles of all plot items, having the QwtPlotItem::AutoScale flag enabled ( QwtScaleEngine::autoScale() ). Then a scale division is calculated ( QwtScaleEngine::didvideScale() ) and assigned to scale widget.

+

When the scale boundaries have been assigned with setAxisScale() a scale division is calculated ( QwtScaleEngine::didvideScale() ) for this interval and assigned to the scale widget.

+

When the scale has been set explicitly by setAxisScaleDiv() the locally stored scale division gets assigned to the scale widget.

+

The scale widget indicates modifications by emitting a QwtScaleWidget::scaleDivChanged() signal.

+

updateAxes() is usually called by replot().

+
See Also
setAxisAutoScale(), setAxisScale(), setAxisScaleDiv(), replot() QwtPlotItem::boundingRect()
+ +
+
+ +
+
+ + + + + + + +
void QwtPlot::updateCanvasMargins ()
+
+ +

Update the canvas margins.

+

Plot items might indicate, that they need some extra space at the borders of the canvas by the QwtPlotItem::Margins flag.

+

getCanvasMarginsHint(), QwtPlotItem::getCanvasMarginHint()

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void QwtPlot::updateLayout ()
+
+virtual
+
+ +

Adjust plot content to its current size.

+
See Also
resizeEvent()
+ +
+
+ +
+
+ + + + + + + +
void QwtPlot::updateLegend ()
+
+
+ +
+
+ + + + + + + + +
void QwtPlot::updateLegend (const QwtPlotItemplotItem)
+
+

Emit legendDataChanged() for a plot item

+
Parameters
+ + +
plotItemPlot item
+
+
+
See Also
QwtPlotItem::legendData(), legendDataChanged()
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_plot__inherit__graph.map new file mode 100644 index 0000000000..5a3b91e801 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot__inherit__graph.map @@ -0,0 +1,3 @@ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_plot__inherit__graph.md5 new file mode 100644 index 0000000000..3a33d03be7 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot__inherit__graph.md5 @@ -0,0 +1 @@ +c3f6628cffdf6d1d3e4724c8819d996a \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_plot__inherit__graph.png new file mode 100644 index 0000000000..02721c81e5 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_plot__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_abstract_bar_chart-members.html b/ThirdParty/Qwt/doc/html/class_qwt_plot_abstract_bar_chart-members.html new file mode 100644 index 0000000000..b49ce8d2f9 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_abstract_bar_chart-members.html @@ -0,0 +1,202 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtPlotAbstractBarChart Member List
+
+
+ +

This is the complete list of members for QwtPlotAbstractBarChart, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
attach(QwtPlot *plot)QwtPlotItem
AutoAdjustSamples enum valueQwtPlotAbstractBarChart
AutoScale enum valueQwtPlotItem
baseline() const QwtPlotAbstractBarChart
boundingRect() const QwtPlotSeriesItemvirtual
dataChanged()QwtPlotSeriesItemprotectedvirtual
dataRect() const =0QwtAbstractSeriesStoreprotectedpure virtual
dataSize() const =0QwtAbstractSeriesStoreprotectedpure virtual
defaultIcon(const QBrush &, const QSizeF &) const QwtPlotItemprotected
detach()QwtPlotItem
draw(QPainter *p, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &) const QwtPlotSeriesItemvirtual
drawSeries(QPainter *painter, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, int from, int to) const =0QwtPlotSeriesItempure virtual
FixedSampleSize enum valueQwtPlotAbstractBarChart
getCanvasMarginHint(const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, double &left, double &top, double &right, double &bottom) const QwtPlotAbstractBarChartvirtual
hide()QwtPlotItem
isVisible() const QwtPlotItem
ItemAttribute enum nameQwtPlotItem
ItemAttributes typedefQwtPlotItem
itemChanged()QwtPlotItemvirtual
ItemInterest enum nameQwtPlotItem
ItemInterests typedefQwtPlotItem
layoutHint() const QwtPlotAbstractBarChart
LayoutPolicy enum nameQwtPlotAbstractBarChart
layoutPolicy() const QwtPlotAbstractBarChart
Legend enum valueQwtPlotItem
legendChanged()QwtPlotItemvirtual
legendData() const QwtPlotItemvirtual
legendIcon(int index, const QSizeF &) const QwtPlotItemvirtual
legendIconSize() const QwtPlotItem
LegendInterest enum valueQwtPlotItem
margin() const QwtPlotAbstractBarChart
Margins enum valueQwtPlotItem
orientation() const QwtPlotSeriesItem
paintRect(const QwtScaleMap &, const QwtScaleMap &) const QwtPlotItem
plot() const QwtPlotItem
QwtPlotAbstractBarChart(const QwtText &title)QwtPlotAbstractBarChartexplicit
QwtPlotItem(const QwtText &title=QwtText())QwtPlotItemexplicit
QwtPlotSeriesItem(const QString &title=QString::null)QwtPlotSeriesItemexplicit
QwtPlotSeriesItem(const QwtText &title)QwtPlotSeriesItemexplicit
RenderAntialiased enum valueQwtPlotItem
RenderHint enum nameQwtPlotItem
RenderHints typedefQwtPlotItem
renderThreadCount() const QwtPlotItem
rtti() const QwtPlotItemvirtual
Rtti_PlotBarChart enum valueQwtPlotItem
Rtti_PlotCurve enum valueQwtPlotItem
Rtti_PlotGrid enum valueQwtPlotItem
Rtti_PlotHistogram enum valueQwtPlotItem
Rtti_PlotIntervalCurve enum valueQwtPlotItem
Rtti_PlotItem enum valueQwtPlotItem
Rtti_PlotLegend enum valueQwtPlotItem
Rtti_PlotMarker enum valueQwtPlotItem
Rtti_PlotMultiBarChart enum valueQwtPlotItem
Rtti_PlotScale enum valueQwtPlotItem
Rtti_PlotShape enum valueQwtPlotItem
Rtti_PlotSpectroCurve enum valueQwtPlotItem
Rtti_PlotSpectrogram enum valueQwtPlotItem
Rtti_PlotSVG enum valueQwtPlotItem
Rtti_PlotTextLabel enum valueQwtPlotItem
Rtti_PlotTradingCurve enum valueQwtPlotItem
Rtti_PlotUserItem enum valueQwtPlotItem
Rtti_PlotZone enum valueQwtPlotItem
RttiValues enum nameQwtPlotItem
sampleWidth(const QwtScaleMap &map, double canvasSize, double dataSize, double value) const QwtPlotAbstractBarChartprotected
ScaleInterest enum valueQwtPlotItem
scaleRect(const QwtScaleMap &, const QwtScaleMap &) const QwtPlotItem
ScaleSamplesToAxes enum valueQwtPlotAbstractBarChart
ScaleSampleToCanvas enum valueQwtPlotAbstractBarChart
setAxes(int xAxis, int yAxis)QwtPlotItem
setBaseline(double)QwtPlotAbstractBarChart
setItemAttribute(ItemAttribute, bool on=true)QwtPlotItem
setItemInterest(ItemInterest, bool on=true)QwtPlotItem
setLayoutHint(double)QwtPlotAbstractBarChart
setLayoutPolicy(LayoutPolicy)QwtPlotAbstractBarChart
setLegendIconSize(const QSize &)QwtPlotItem
setMargin(int)QwtPlotAbstractBarChart
setOrientation(Qt::Orientation)QwtPlotSeriesItem
setRectOfInterest(const QRectF &)=0QwtAbstractSeriesStoreprotectedpure virtual
setRenderHint(RenderHint, bool on=true)QwtPlotItem
setRenderThreadCount(uint numThreads)QwtPlotItem
setSpacing(int)QwtPlotAbstractBarChart
setTitle(const QString &title)QwtPlotItem
setTitle(const QwtText &title)QwtPlotItem
setVisible(bool)QwtPlotItemvirtual
setXAxis(int axis)QwtPlotItem
setYAxis(int axis)QwtPlotItem
setZ(double z)QwtPlotItem
show()QwtPlotItem
spacing() const QwtPlotAbstractBarChart
testItemAttribute(ItemAttribute) const QwtPlotItem
testItemInterest(ItemInterest) const QwtPlotItem
testRenderHint(RenderHint) const QwtPlotItem
title() const QwtPlotItem
updateLegend(const QwtPlotItem *, const QList< QwtLegendData > &)QwtPlotItemvirtual
updateScaleDiv(const QwtScaleDiv &, const QwtScaleDiv &)QwtPlotSeriesItemvirtual
xAxis() const QwtPlotItem
yAxis() const QwtPlotItem
z() const QwtPlotItem
~QwtAbstractSeriesStore()QwtAbstractSeriesStoreinlineprotectedvirtual
~QwtPlotAbstractBarChart()QwtPlotAbstractBarChartvirtual
~QwtPlotItem()QwtPlotItemvirtual
~QwtPlotSeriesItem()QwtPlotSeriesItemvirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_abstract_bar_chart.html b/ThirdParty/Qwt/doc/html/class_qwt_plot_abstract_bar_chart.html new file mode 100644 index 0000000000..295bf58793 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_abstract_bar_chart.html @@ -0,0 +1,721 @@ + + + + + + +Qwt User's Guide: QwtPlotAbstractBarChart Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtPlotAbstractBarChart Class Reference
+
+
+ +

Abstract base class for bar chart items. + More...

+ +

#include <qwt_plot_abstract_barchart.h>

+
+Inheritance diagram for QwtPlotAbstractBarChart:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + +

+Public Types

enum  LayoutPolicy { AutoAdjustSamples, +ScaleSamplesToAxes, +ScaleSampleToCanvas, +FixedSampleSize + }
 Mode how to calculate the bar width. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 QwtPlotAbstractBarChart (const QwtText &title)
 
+virtual ~QwtPlotAbstractBarChart ()
 Destructor.
 
void setLayoutPolicy (LayoutPolicy)
 
LayoutPolicy layoutPolicy () const
 
void setLayoutHint (double)
 
double layoutHint () const
 
void setSpacing (int)
 Set the spacing. More...
 
int spacing () const
 
void setMargin (int)
 Set the margin. More...
 
int margin () const
 
void setBaseline (double)
 Set the baseline. More...
 
double baseline () const
 
virtual void getCanvasMarginHint (const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, double &left, double &top, double &right, double &bottom) const
 Calculate a hint for the canvas margin. More...
 
- Public Member Functions inherited from QwtPlotSeriesItem
 QwtPlotSeriesItem (const QString &title=QString::null)
 
 QwtPlotSeriesItem (const QwtText &title)
 
+virtual ~QwtPlotSeriesItem ()
 Destructor.
 
void setOrientation (Qt::Orientation)
 
Qt::Orientation orientation () const
 
virtual void draw (QPainter *p, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &) const
 Draw the complete series. More...
 
virtual void drawSeries (QPainter *painter, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, int from, int to) const =0
 
virtual QRectF boundingRect () const
 
virtual void updateScaleDiv (const QwtScaleDiv &, const QwtScaleDiv &)
 Update the item to changes of the axes scale division. More...
 
- Public Member Functions inherited from QwtPlotItem
 QwtPlotItem (const QwtText &title=QwtText())
 
+virtual ~QwtPlotItem ()
 Destroy the QwtPlotItem.
 
void attach (QwtPlot *plot)
 Attach the item to a plot. More...
 
void detach ()
 This method detaches a QwtPlotItem from any QwtPlot it has been associated with. More...
 
+QwtPlotplot () const
 Return attached plot.
 
void setTitle (const QString &title)
 
void setTitle (const QwtText &title)
 
const QwtTexttitle () const
 
virtual int rtti () const
 
void setItemAttribute (ItemAttribute, bool on=true)
 
bool testItemAttribute (ItemAttribute) const
 
void setItemInterest (ItemInterest, bool on=true)
 
bool testItemInterest (ItemInterest) const
 
void setRenderHint (RenderHint, bool on=true)
 
bool testRenderHint (RenderHint) const
 
void setRenderThreadCount (uint numThreads)
 
uint renderThreadCount () const
 
void setLegendIconSize (const QSize &)
 
QSize legendIconSize () const
 
double z () const
 
void setZ (double z)
 Set the z value. More...
 
+void show ()
 Show the item.
 
+void hide ()
 Hide the item.
 
virtual void setVisible (bool)
 
bool isVisible () const
 
void setAxes (int xAxis, int yAxis)
 
void setXAxis (int axis)
 
+int xAxis () const
 Return xAxis.
 
void setYAxis (int axis)
 
+int yAxis () const
 Return yAxis.
 
virtual void itemChanged ()
 
virtual void legendChanged ()
 
virtual void updateLegend (const QwtPlotItem *, const QList< QwtLegendData > &)
 Update the item to changes of the legend info. More...
 
QRectF scaleRect (const QwtScaleMap &, const QwtScaleMap &) const
 Calculate the bounding scale rectangle of 2 maps. More...
 
QRectF paintRect (const QwtScaleMap &, const QwtScaleMap &) const
 Calculate the bounding paint rectangle of 2 maps. More...
 
virtual QList< QwtLegendDatalegendData () const
 Return all information, that is needed to represent the item on the legend. More...
 
virtual QwtGraphic legendIcon (int index, const QSizeF &) const
 
+ + + + + + + + + + + + + + + + + + + + + +

+Protected Member Functions

double sampleWidth (const QwtScaleMap &map, double canvasSize, double dataSize, double value) const
 
- Protected Member Functions inherited from QwtPlotSeriesItem
+virtual void dataChanged ()
 dataChanged() indicates, that the series has been changed.
 
- Protected Member Functions inherited from QwtPlotItem
QwtGraphic defaultIcon (const QBrush &, const QSizeF &) const
 Return a default icon from a brush. More...
 
- Protected Member Functions inherited from QwtAbstractSeriesStore
+virtual ~QwtAbstractSeriesStore ()
 Destructor.
 
virtual void setRectOfInterest (const QRectF &)=0
 
virtual QRectF dataRect () const =0
 
virtual size_t dataSize () const =0
 
+

Detailed Description

+

Abstract base class for bar chart items.

+

In opposite to almost all other plot items bar charts can't be displayed inside of their bounding rectangle and need a special API how to calculate the width of the bars and how they affect the layout of the attached plot.

+

Member Enumeration Documentation

+ +
+
+ +

Mode how to calculate the bar width.

+

setLayoutPolicy(), setLayoutHint(), barWidthHint()

+ + + + + +
Enumerator
AutoAdjustSamples  +

The sample width is calculated by dividing the bounding rectangle by the number of samples.

+
See Also
boundingRectangle()
+
Note
The layoutHint() is ignored
+
ScaleSamplesToAxes  +

layoutHint() defines an interval in axis coordinates

+
ScaleSampleToCanvas  +

The bar width is calculated by multiplying layoutHint() with the height or width of the canvas.

+
See Also
boundingRectangle()
+
FixedSampleSize  +

layoutHint() defines a fixed width in paint device coordinates.

+
+ +
+
+

Constructor & Destructor Documentation

+ +
+
+ + + + + +
+ + + + + + + + +
QwtPlotAbstractBarChart::QwtPlotAbstractBarChart (const QwtTexttitle)
+
+explicit
+
+

Constructor

+
Parameters
+ + +
titleTitle of the chart
+
+
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + + + +
double QwtPlotAbstractBarChart::baseline () const
+
+
Returns
Value for the origin of the bar chart
+
See Also
setBaseline(), QwtPlotSeriesItem::orientation()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPlotAbstractBarChart::getCanvasMarginHint (const QwtScaleMapxMap,
const QwtScaleMapyMap,
const QRectF & canvasRect,
double & left,
double & top,
double & right,
double & bottom 
) const
+
+virtual
+
+ +

Calculate a hint for the canvas margin.

+

Bar charts need to reserve some space for displaying the bars for the first and the last sample. The hint is calculated from the layoutHint() depending on the layoutPolicy().

+

The margins are in target device coordinates ( pixels on screen )

+
Parameters
+ + + + + + + + +
xMapMaps x-values into pixel coordinates.
yMapMaps y-values into pixel coordinates.
canvasRectContents rectangle of the canvas in painter coordinates
leftReturns the left margin
topReturns the top margin
rightReturns the right margin
bottomReturns the bottom margin
+
+
+
Returns
Margin
+
See Also
layoutPolicy(), layoutHint(), QwtPlotItem::Margins QwtPlot::getCanvasMarginsHint(), QwtPlot::updateCanvasMargins()
+ +

Reimplemented from QwtPlotItem.

+ +
+
+ +
+
+ + + + + + + +
double QwtPlotAbstractBarChart::layoutHint () const
+
+

The combination of layoutPolicy() and layoutHint() define how the width of the bars is calculated

+
Returns
Layout policy of the chart item
+
See Also
LayoutPolicy, setLayoutHint(), layoutPolicy()
+ +
+
+ +
+
+ + + + + + + +
QwtPlotAbstractBarChart::LayoutPolicy QwtPlotAbstractBarChart::layoutPolicy () const
+
+

The combination of layoutPolicy() and layoutHint() define how the width of the bars is calculated

+
Returns
Layout policy of the chart item
+
See Also
setLayoutPolicy(), layoutHint()
+ +
+
+ +
+
+ + + + + + + +
int QwtPlotAbstractBarChart::margin () const
+
+
Returns
Margin between the outmost bars and the contentsRect() of the canvas.
+
See Also
setMargin(), spacing()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
double QwtPlotAbstractBarChart::sampleWidth (const QwtScaleMapmap,
double canvasSize,
double boundingSize,
double value 
) const
+
+protected
+
+

Calculate the width for a sample in paint device coordinates

+
Parameters
+ + + + + +
mapScale map for the corresponding scale
canvasSizeSize of the canvas in paint device coordinates
boundingSizeBounding size of the chart in plot coordinates ( used in AutoAdjustSamples mode )
valueValue of the sample
+
+
+
Returns
Sample width
+
See Also
layoutPolicy(), layoutHint()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotAbstractBarChart::setBaseline (double value)
+
+ +

Set the baseline.

+

The baseline is the origin for the chart. Each bar is painted from the baseline in the direction of the sample value. In case of a horizontal orientation() the baseline is interpreted as x - otherwise as y - value.

+

The default value for the baseline is 0.

+
Parameters
+ + +
valueValue for the baseline
+
+
+
See Also
baseline(), QwtPlotSeriesItem::orientation()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotAbstractBarChart::setLayoutHint (double hint)
+
+

The combination of layoutPolicy() and layoutHint() define how the width of the bars is calculated

+
Parameters
+ + +
hintLayout hint
+
+
+
See Also
LayoutPolicy, layoutPolicy(), layoutHint()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotAbstractBarChart::setLayoutPolicy (LayoutPolicy policy)
+
+

The combination of layoutPolicy() and layoutHint() define how the width of the bars is calculated

+
Parameters
+ + +
policyLayout policy
+
+
+
See Also
layoutPolicy(), layoutHint()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotAbstractBarChart::setMargin (int margin)
+
+ +

Set the margin.

+

The margin is the distance between the outmost bars and the contentsRect() of the canvas. The default setting is 5 pixels.

+
Parameters
+ + +
marginMargin
+
+
+
See Also
spacing(), margin()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotAbstractBarChart::setSpacing (int spacing)
+
+ +

Set the spacing.

+

The spacing is the distance between 2 samples ( bars for QwtPlotBarChart or a group of bars for QwtPlotMultiBarChart ) in paint device coordinates.

+
See Also
spacing()
+ +
+
+ +
+
+ + + + + + + +
int QwtPlotAbstractBarChart::spacing () const
+
+
Returns
Spacing between 2 samples ( bars or groups of bars )
+
See Also
setSpacing(), margin()
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_abstract_bar_chart__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_plot_abstract_bar_chart__inherit__graph.map new file mode 100644 index 0000000000..e8279d3900 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_abstract_bar_chart__inherit__graph.map @@ -0,0 +1,7 @@ + + + + + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_abstract_bar_chart__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_plot_abstract_bar_chart__inherit__graph.md5 new file mode 100644 index 0000000000..5d6ca262b1 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_abstract_bar_chart__inherit__graph.md5 @@ -0,0 +1 @@ +fb3edfcc610d6d6a898050d28872c2b8 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_abstract_bar_chart__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_plot_abstract_bar_chart__inherit__graph.png new file mode 100644 index 0000000000..5b9f42463b Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_plot_abstract_bar_chart__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_bar_chart-members.html b/ThirdParty/Qwt/doc/html/class_qwt_plot_bar_chart-members.html new file mode 100644 index 0000000000..8e2b0497e1 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_bar_chart-members.html @@ -0,0 +1,229 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtPlotBarChart Member List
+
+
+ +

This is the complete list of members for QwtPlotBarChart, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
attach(QwtPlot *plot)QwtPlotItem
AutoAdjustSamples enum valueQwtPlotAbstractBarChart
AutoScale enum valueQwtPlotItem
barTitle(int sampleIndex) const QwtPlotBarChartvirtual
baseline() const QwtPlotAbstractBarChart
boundingRect() const QwtPlotBarChartvirtual
data()QwtSeriesStore< QPointF >
data() constQwtSeriesStore< QPointF >
dataChanged()QwtPlotSeriesItemprotectedvirtual
QwtPlotAbstractBarChart::dataRect() const =0QwtAbstractSeriesStoreprotectedpure virtual
QwtSeriesStore< QPointF >::dataRect() constQwtSeriesStore< QPointF >virtual
QwtPlotAbstractBarChart::dataSize() const =0QwtAbstractSeriesStoreprotectedpure virtual
QwtSeriesStore< QPointF >::dataSize() constQwtSeriesStore< QPointF >virtual
defaultIcon(const QBrush &, const QSizeF &) const QwtPlotItemprotected
detach()QwtPlotItem
draw(QPainter *p, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &) const QwtPlotSeriesItemvirtual
drawBar(QPainter *, int sampleIndex, const QPointF &point, const QwtColumnRect &) const QwtPlotBarChartprotectedvirtual
drawSample(QPainter *painter, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, const QwtInterval &boundingInterval, int index, const QPointF &sample) const QwtPlotBarChartprotectedvirtual
drawSeries(QPainter *painter, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, int from, int to) const QwtPlotBarChartvirtual
FixedSampleSize enum valueQwtPlotAbstractBarChart
getCanvasMarginHint(const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, double &left, double &top, double &right, double &bottom) const QwtPlotAbstractBarChartvirtual
hide()QwtPlotItem
isVisible() const QwtPlotItem
ItemAttribute enum nameQwtPlotItem
ItemAttributes typedefQwtPlotItem
itemChanged()QwtPlotItemvirtual
ItemInterest enum nameQwtPlotItem
ItemInterests typedefQwtPlotItem
layoutHint() const QwtPlotAbstractBarChart
LayoutPolicy enum nameQwtPlotAbstractBarChart
layoutPolicy() const QwtPlotAbstractBarChart
Legend enum valueQwtPlotItem
LegendBarTitles enum valueQwtPlotBarChart
legendChanged()QwtPlotItemvirtual
LegendChartTitle enum valueQwtPlotBarChart
legendData() const QwtPlotBarChartprotectedvirtual
legendIcon(int index, const QSizeF &) const QwtPlotBarChartprotectedvirtual
legendIconSize() const QwtPlotItem
LegendInterest enum valueQwtPlotItem
LegendMode enum nameQwtPlotBarChart
legendMode() const QwtPlotBarChart
margin() const QwtPlotAbstractBarChart
Margins enum valueQwtPlotItem
orientation() const QwtPlotSeriesItem
paintRect(const QwtScaleMap &, const QwtScaleMap &) const QwtPlotItem
plot() const QwtPlotItem
QwtPlotAbstractBarChart(const QwtText &title)QwtPlotAbstractBarChartexplicit
QwtPlotBarChart(const QString &title=QString::null)QwtPlotBarChartexplicit
QwtPlotBarChart(const QwtText &title)QwtPlotBarChartexplicit
QwtPlotItem(const QwtText &title=QwtText())QwtPlotItemexplicit
QwtPlotSeriesItem(const QString &title=QString::null)QwtPlotSeriesItemexplicit
QwtPlotSeriesItem(const QwtText &title)QwtPlotSeriesItemexplicit
QwtSeriesStore()QwtSeriesStore< QPointF >explicit
RenderAntialiased enum valueQwtPlotItem
RenderHint enum nameQwtPlotItem
RenderHints typedefQwtPlotItem
renderThreadCount() const QwtPlotItem
rtti() const QwtPlotBarChartvirtual
Rtti_PlotBarChart enum valueQwtPlotItem
Rtti_PlotCurve enum valueQwtPlotItem
Rtti_PlotGrid enum valueQwtPlotItem
Rtti_PlotHistogram enum valueQwtPlotItem
Rtti_PlotIntervalCurve enum valueQwtPlotItem
Rtti_PlotItem enum valueQwtPlotItem
Rtti_PlotLegend enum valueQwtPlotItem
Rtti_PlotMarker enum valueQwtPlotItem
Rtti_PlotMultiBarChart enum valueQwtPlotItem
Rtti_PlotScale enum valueQwtPlotItem
Rtti_PlotShape enum valueQwtPlotItem
Rtti_PlotSpectroCurve enum valueQwtPlotItem
Rtti_PlotSpectrogram enum valueQwtPlotItem
Rtti_PlotSVG enum valueQwtPlotItem
Rtti_PlotTextLabel enum valueQwtPlotItem
Rtti_PlotTradingCurve enum valueQwtPlotItem
Rtti_PlotUserItem enum valueQwtPlotItem
Rtti_PlotZone enum valueQwtPlotItem
RttiValues enum nameQwtPlotItem
sample(int index) constQwtSeriesStore< QPointF >
sampleWidth(const QwtScaleMap &map, double canvasSize, double dataSize, double value) const QwtPlotAbstractBarChartprotected
ScaleInterest enum valueQwtPlotItem
scaleRect(const QwtScaleMap &, const QwtScaleMap &) const QwtPlotItem
ScaleSamplesToAxes enum valueQwtPlotAbstractBarChart
ScaleSampleToCanvas enum valueQwtPlotAbstractBarChart
setAxes(int xAxis, int yAxis)QwtPlotItem
setBaseline(double)QwtPlotAbstractBarChart
setData(QwtSeriesData< QPointF > *series)QwtSeriesStore< QPointF >
setItemAttribute(ItemAttribute, bool on=true)QwtPlotItem
setItemInterest(ItemInterest, bool on=true)QwtPlotItem
setLayoutHint(double)QwtPlotAbstractBarChart
setLayoutPolicy(LayoutPolicy)QwtPlotAbstractBarChart
setLegendIconSize(const QSize &)QwtPlotItem
setLegendMode(LegendMode)QwtPlotBarChart
setMargin(int)QwtPlotAbstractBarChart
setOrientation(Qt::Orientation)QwtPlotSeriesItem
QwtPlotAbstractBarChart::setRectOfInterest(const QRectF &)=0QwtAbstractSeriesStoreprotectedpure virtual
QwtSeriesStore< QPointF >::setRectOfInterest(const QRectF &rect)QwtSeriesStore< QPointF >virtual
setRenderHint(RenderHint, bool on=true)QwtPlotItem
setRenderThreadCount(uint numThreads)QwtPlotItem
setSamples(const QVector< QPointF > &)QwtPlotBarChart
setSamples(const QVector< double > &)QwtPlotBarChart
setSamples(QwtSeriesData< QPointF > *series)QwtPlotBarChart
setSpacing(int)QwtPlotAbstractBarChart
setSymbol(QwtColumnSymbol *)QwtPlotBarChart
setTitle(const QString &title)QwtPlotItem
setTitle(const QwtText &title)QwtPlotItem
setVisible(bool)QwtPlotItemvirtual
setXAxis(int axis)QwtPlotItem
setYAxis(int axis)QwtPlotItem
setZ(double z)QwtPlotItem
show()QwtPlotItem
spacing() const QwtPlotAbstractBarChart
specialSymbol(int sampleIndex, const QPointF &) const QwtPlotBarChartvirtual
swapData(QwtSeriesData< QPointF > *series)QwtSeriesStore< QPointF >
symbol() const QwtPlotBarChart
testItemAttribute(ItemAttribute) const QwtPlotItem
testItemInterest(ItemInterest) const QwtPlotItem
testRenderHint(RenderHint) const QwtPlotItem
title() const QwtPlotItem
updateLegend(const QwtPlotItem *, const QList< QwtLegendData > &)QwtPlotItemvirtual
updateScaleDiv(const QwtScaleDiv &, const QwtScaleDiv &)QwtPlotSeriesItemvirtual
xAxis() const QwtPlotItem
yAxis() const QwtPlotItem
z() const QwtPlotItem
~QwtAbstractSeriesStore()QwtAbstractSeriesStoreinlineprotectedvirtual
~QwtPlotAbstractBarChart()QwtPlotAbstractBarChartvirtual
~QwtPlotBarChart()QwtPlotBarChartvirtual
~QwtPlotItem()QwtPlotItemvirtual
~QwtPlotSeriesItem()QwtPlotSeriesItemvirtual
~QwtSeriesStore()QwtSeriesStore< QPointF >
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_bar_chart.html b/ThirdParty/Qwt/doc/html/class_qwt_plot_bar_chart.html new file mode 100644 index 0000000000..2eaaac447d --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_bar_chart.html @@ -0,0 +1,1034 @@ + + + + + + +Qwt User's Guide: QwtPlotBarChart Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+ +
+ +

QwtPlotBarChart displays a series of a values as bars. + More...

+ +

#include <qwt_plot_barchart.h>

+
+Inheritance diagram for QwtPlotBarChart:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + + +

+Public Types

enum  LegendMode { LegendChartTitle, +LegendBarTitles + }
 Legend modes. More...
 
- Public Types inherited from QwtPlotAbstractBarChart
enum  LayoutPolicy { AutoAdjustSamples, +ScaleSamplesToAxes, +ScaleSampleToCanvas, +FixedSampleSize + }
 Mode how to calculate the bar width. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 QwtPlotBarChart (const QString &title=QString::null)
 
 QwtPlotBarChart (const QwtText &title)
 
+virtual ~QwtPlotBarChart ()
 Destructor.
 
virtual int rtti () const
 
void setSamples (const QVector< QPointF > &)
 
void setSamples (const QVector< double > &)
 
void setSamples (QwtSeriesData< QPointF > *series)
 
void setSymbol (QwtColumnSymbol *)
 Assign a symbol. More...
 
const QwtColumnSymbolsymbol () const
 
void setLegendMode (LegendMode)
 
LegendMode legendMode () const
 
virtual void drawSeries (QPainter *painter, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, int from, int to) const
 
virtual QRectF boundingRect () const
 
virtual QwtColumnSymbolspecialSymbol (int sampleIndex, const QPointF &) const
 
virtual QwtText barTitle (int sampleIndex) const
 Return the title of a bar. More...
 
- Public Member Functions inherited from QwtPlotAbstractBarChart
 QwtPlotAbstractBarChart (const QwtText &title)
 
+virtual ~QwtPlotAbstractBarChart ()
 Destructor.
 
void setLayoutPolicy (LayoutPolicy)
 
LayoutPolicy layoutPolicy () const
 
void setLayoutHint (double)
 
double layoutHint () const
 
void setSpacing (int)
 Set the spacing. More...
 
int spacing () const
 
void setMargin (int)
 Set the margin. More...
 
int margin () const
 
void setBaseline (double)
 Set the baseline. More...
 
double baseline () const
 
virtual void getCanvasMarginHint (const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, double &left, double &top, double &right, double &bottom) const
 Calculate a hint for the canvas margin. More...
 
- Public Member Functions inherited from QwtPlotSeriesItem
 QwtPlotSeriesItem (const QString &title=QString::null)
 
 QwtPlotSeriesItem (const QwtText &title)
 
+virtual ~QwtPlotSeriesItem ()
 Destructor.
 
void setOrientation (Qt::Orientation)
 
Qt::Orientation orientation () const
 
virtual void draw (QPainter *p, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &) const
 Draw the complete series. More...
 
virtual void updateScaleDiv (const QwtScaleDiv &, const QwtScaleDiv &)
 Update the item to changes of the axes scale division. More...
 
- Public Member Functions inherited from QwtPlotItem
 QwtPlotItem (const QwtText &title=QwtText())
 
+virtual ~QwtPlotItem ()
 Destroy the QwtPlotItem.
 
void attach (QwtPlot *plot)
 Attach the item to a plot. More...
 
void detach ()
 This method detaches a QwtPlotItem from any QwtPlot it has been associated with. More...
 
+QwtPlotplot () const
 Return attached plot.
 
void setTitle (const QString &title)
 
void setTitle (const QwtText &title)
 
const QwtTexttitle () const
 
void setItemAttribute (ItemAttribute, bool on=true)
 
bool testItemAttribute (ItemAttribute) const
 
void setItemInterest (ItemInterest, bool on=true)
 
bool testItemInterest (ItemInterest) const
 
void setRenderHint (RenderHint, bool on=true)
 
bool testRenderHint (RenderHint) const
 
void setRenderThreadCount (uint numThreads)
 
uint renderThreadCount () const
 
void setLegendIconSize (const QSize &)
 
QSize legendIconSize () const
 
double z () const
 
void setZ (double z)
 Set the z value. More...
 
+void show ()
 Show the item.
 
+void hide ()
 Hide the item.
 
virtual void setVisible (bool)
 
bool isVisible () const
 
void setAxes (int xAxis, int yAxis)
 
void setXAxis (int axis)
 
+int xAxis () const
 Return xAxis.
 
void setYAxis (int axis)
 
+int yAxis () const
 Return yAxis.
 
virtual void itemChanged ()
 
virtual void legendChanged ()
 
virtual void updateLegend (const QwtPlotItem *, const QList< QwtLegendData > &)
 Update the item to changes of the legend info. More...
 
QRectF scaleRect (const QwtScaleMap &, const QwtScaleMap &) const
 Calculate the bounding scale rectangle of 2 maps. More...
 
QRectF paintRect (const QwtScaleMap &, const QwtScaleMap &) const
 Calculate the bounding paint rectangle of 2 maps. More...
 
- Public Member Functions inherited from QwtSeriesStore< QPointF >
QwtSeriesStore ()
 Constructor The store contains no series.
 
~QwtSeriesStore ()
 Destructor.
 
void setData (QwtSeriesData< QPointF > *series)
 
QwtSeriesData< QPointF > * data ()
 
const QwtSeriesData< QPointF > * data () const
 
QPointF sample (int index) const
 
virtual size_t dataSize () const
 
virtual QRectF dataRect () const
 
virtual void setRectOfInterest (const QRectF &rect)
 
QwtSeriesData< QPointF > * swapData (QwtSeriesData< QPointF > *series)
 
+ + + + + + + + + + + + + + + + + + + + + + + + + +

+Protected Member Functions

virtual void drawSample (QPainter *painter, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, const QwtInterval &boundingInterval, int index, const QPointF &sample) const
 
virtual void drawBar (QPainter *, int sampleIndex, const QPointF &point, const QwtColumnRect &) const
 
QList< QwtLegendDatalegendData () const
 Return all information, that is needed to represent the item on the legend. More...
 
QwtGraphic legendIcon (int index, const QSizeF &) const
 
- Protected Member Functions inherited from QwtPlotAbstractBarChart
double sampleWidth (const QwtScaleMap &map, double canvasSize, double dataSize, double value) const
 
- Protected Member Functions inherited from QwtPlotSeriesItem
+virtual void dataChanged ()
 dataChanged() indicates, that the series has been changed.
 
- Protected Member Functions inherited from QwtPlotItem
QwtGraphic defaultIcon (const QBrush &, const QSizeF &) const
 Return a default icon from a brush. More...
 
- Protected Member Functions inherited from QwtAbstractSeriesStore
+virtual ~QwtAbstractSeriesStore ()
 Destructor.
 
+

Detailed Description

+

QwtPlotBarChart displays a series of a values as bars.

+

Each bar might be customized individually by implementing a specialSymbol(). Otherwise it is rendered using a default symbol.

+

Depending on its orientation() the bars are displayed horizontally or vertically. The bars cover the interval between the baseline() and the value.

+

By activating the LegendBarTitles mode each sample will have its own entry on the legend.

+

The most common use case of a bar chart is to display a list of y coordinates, where the x coordinate is simply the index in the list. But for other situations ( f.e. when values are related to dates ) it is also possible to set x coordinates explicitly.

+
See Also
QwtPlotMultiBarChart, QwtPlotHistogram, QwtPlotCurve::Sticks, QwtPlotSeriesItem::orientation(), QwtPlotAbstractBarChart::baseline()
+

Member Enumeration Documentation

+ +
+
+ + + + +
enum QwtPlotBarChart::LegendMode
+
+ +

Legend modes.

+

The default setting is QwtPlotBarChart::LegendChartTitle.

+
See Also
setLegendMode(), legendMode()
+ + + +
Enumerator
LegendChartTitle  +

One entry on the legend showing the default symbol and the title() of the chart

+
See Also
QwtPlotItem::title()
+
LegendBarTitles  +

One entry for each value showing the individual symbol of the corresponding bar and the bar title.

+
See Also
specialSymbol(), barTitle()
+
+ +
+
+

Constructor & Destructor Documentation

+ +
+
+ + + + + +
+ + + + + + + + +
QwtPlotBarChart::QwtPlotBarChart (const QString & title = QString::null)
+
+explicit
+
+

Constructor

+
Parameters
+ + +
titleTitle of the curve
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
QwtPlotBarChart::QwtPlotBarChart (const QwtTexttitle)
+
+explicit
+
+

Constructor

+
Parameters
+ + +
titleTitle of the curve
+
+
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + + +
QwtText QwtPlotBarChart::barTitle (int sampleIndex) const
+
+virtual
+
+ +

Return the title of a bar.

+

In LegendBarTitles mode the title is displayed on the legend entry corresponding to a bar.

+

The default implementation is a dummy, that is intended to be overloaded.

+
Parameters
+ + +
sampleIndexIndex of the bar
+
+
+
Returns
An empty text
+
See Also
LegendBarTitles
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
QRectF QwtPlotBarChart::boundingRect () const
+
+virtual
+
+
Returns
Bounding rectangle of all samples. For an empty series the rectangle is invalid.
+ +

Reimplemented from QwtPlotSeriesItem.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPlotBarChart::drawBar (QPainter * painter,
int sampleIndex,
const QPointF & sample,
const QwtColumnRectrect 
) const
+
+protectedvirtual
+
+

Draw a bar

+
Parameters
+ + + + + +
painterPainter
sampleIndexIndex of the sample represented by the bar
sampleValue of the sample
rectBounding rectangle of the bar
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPlotBarChart::drawSample (QPainter * painter,
const QwtScaleMapxMap,
const QwtScaleMapyMap,
const QRectF & canvasRect,
const QwtIntervalboundingInterval,
int index,
const QPointF & sample 
) const
+
+protectedvirtual
+
+

Draw a sample

+
Parameters
+ + + + + + + + +
painterPainter
xMapx map
yMapy map
canvasRectContents rect of the canvas
boundingIntervalBounding interval of sample values
indexIndex of the sample
sampleValue of the sample
+
+
+
See Also
drawSeries()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPlotBarChart::drawSeries (QPainter * painter,
const QwtScaleMapxMap,
const QwtScaleMapyMap,
const QRectF & canvasRect,
int from,
int to 
) const
+
+virtual
+
+

Draw an interval of the bar chart

+
Parameters
+ + + + + + + +
painterPainter
xMapMaps x-values into pixel coordinates.
yMapMaps y-values into pixel coordinates.
canvasRectContents rect of the canvas
fromIndex of the first point to be painted
toIndex of the last point to be painted. If to < 0 the curve will be painted to its last point.
+
+
+
See Also
drawSymbols()
+ +

Implements QwtPlotSeriesItem.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
QList< QwtLegendData > QwtPlotBarChart::legendData () const
+
+protectedvirtual
+
+ +

Return all information, that is needed to represent the item on the legend.

+

In case of LegendBarTitles an entry for each bar is returned, otherwise the chart is represented like any other plot item from its title() and the legendIcon().

+
Returns
Information, that is needed to represent the item on the legend
+
See Also
title(), setLegendMode(), barTitle(), QwtLegend, QwtPlotLegendItem
+ +

Reimplemented from QwtPlotItem.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
QwtGraphic QwtPlotBarChart::legendIcon (int index,
const QSizeF & size 
) const
+
+protectedvirtual
+
+
Returns
Icon representing a bar or the chart on the legend
+

When the legendMode() is LegendBarTitles the icon shows the bar corresponding to index - otherwise the bar displays the default symbol.

+
Parameters
+ + + +
indexIndex of the legend entry
sizeIcon size
+
+
+
See Also
setLegendMode(), drawBar(), QwtPlotItem::setLegendIconSize(), QwtPlotItem::legendData()
+ +

Reimplemented from QwtPlotItem.

+ +
+
+ +
+
+ + + + + + + +
QwtPlotBarChart::LegendMode QwtPlotBarChart::legendMode () const
+
+
Returns
Legend mode
+
See Also
setLegendMode()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
int QwtPlotBarChart::rtti () const
+
+virtual
+
+
Returns
QwtPlotItem::Rtti_PlotBarChart
+ +

Reimplemented from QwtPlotItem.

+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotBarChart::setLegendMode (LegendMode mode)
+
+

Set the mode that decides what to display on the legend

+

In case of LegendBarTitles barTitle() needs to be overloaded to return individual titles for each bar.

+
Parameters
+ + +
modeNew mode
+
+
+
See Also
legendMode(), legendData(), barTitle(), QwtPlotItem::ItemAttribute
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotBarChart::setSamples (const QVector< QPointF > & samples)
+
+

Initialize data with an array of points

+
Parameters
+ + +
samplesVector of points
+
+
+
Note
QVector is implicitly shared
+
+QPolygonF is derived from QVector<QPointF>
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotBarChart::setSamples (const QVector< double > & samples)
+
+

Initialize data with an array of doubles

+

The indices in the array are taken as x coordinate, while the doubles are interpreted as y values.

+
Parameters
+ + +
samplesVector of y coordinates
+
+
+
Note
QVector is implicitly shared
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotBarChart::setSamples (QwtSeriesData< QPointF > * data)
+
+

Assign a series of samples

+

setSamples() is just a wrapper for setData() without any additional value - beside that it is easier to find for the developer.

+
Parameters
+ + +
dataData
+
+
+
Warning
The item takes ownership of the data object, deleting it when its not used anymore.
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotBarChart::setSymbol (QwtColumnSymbolsymbol)
+
+ +

Assign a symbol.

+

The bar chart will take the ownership of the symbol, hence the previously set symbol will be delete by setting a new one. If symbol is NULL no symbol will be drawn.

+
Parameters
+ + +
symbolSymbol
+
+
+
See Also
symbol()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
QwtColumnSymbol * QwtPlotBarChart::specialSymbol (int sampleIndex,
const QPointF & sample 
) const
+
+virtual
+
+

Needs to be overloaded to return a non default symbol for a specific sample

+
Parameters
+ + + +
sampleIndexIndex of the sample represented by the bar
sampleValue of the sample
+
+
+
Returns
NULL, indicating to use the default symbol
+ +
+
+ +
+
+ + + + + + + +
const QwtColumnSymbol * QwtPlotBarChart::symbol () const
+
+
Returns
Current symbol or NULL, when no symbol has been assigned
+
See Also
setSymbol()
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_bar_chart__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_plot_bar_chart__inherit__graph.map new file mode 100644 index 0000000000..63921f3e81 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_bar_chart__inherit__graph.map @@ -0,0 +1,7 @@ + + + + + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_bar_chart__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_plot_bar_chart__inherit__graph.md5 new file mode 100644 index 0000000000..2cf7b758ca --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_bar_chart__inherit__graph.md5 @@ -0,0 +1 @@ +448939f6861a8d4cdf936fe99687d317 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_bar_chart__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_plot_bar_chart__inherit__graph.png new file mode 100644 index 0000000000..4b730cd317 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_plot_bar_chart__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_canvas-members.html b/ThirdParty/Qwt/doc/html/class_qwt_plot_canvas-members.html new file mode 100644 index 0000000000..4ebb4a40e7 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_canvas-members.html @@ -0,0 +1,130 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtPlotCanvas Member List
+
+
+ +

This is the complete list of members for QwtPlotCanvas, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
BackingStore enum valueQwtPlotCanvas
backingStore() const QwtPlotCanvas
borderPath(const QRect &) const QwtPlotCanvas
borderRadius() const QwtPlotCanvas
CanvasFocusIndicator enum valueQwtPlotCanvas
drawBorder(QPainter *)QwtPlotCanvasprotectedvirtual
drawFocusIndicator(QPainter *)QwtPlotCanvasprotectedvirtual
event(QEvent *)QwtPlotCanvasvirtual
focusIndicator() const QwtPlotCanvas
FocusIndicator enum nameQwtPlotCanvas
HackStyledBackground enum valueQwtPlotCanvas
ImmediatePaint enum valueQwtPlotCanvas
invalidateBackingStore()QwtPlotCanvas
ItemFocusIndicator enum valueQwtPlotCanvas
NoFocusIndicator enum valueQwtPlotCanvas
Opaque enum valueQwtPlotCanvas
PaintAttribute enum nameQwtPlotCanvas
PaintAttributes typedefQwtPlotCanvas
paintEvent(QPaintEvent *)QwtPlotCanvasprotectedvirtual
plot()QwtPlotCanvas
plot() const QwtPlotCanvas
QwtPlotCanvas(QwtPlot *=NULL)QwtPlotCanvasexplicit
replot()QwtPlotCanvasslot
resizeEvent(QResizeEvent *)QwtPlotCanvasprotectedvirtual
setBorderRadius(double)QwtPlotCanvas
setFocusIndicator(FocusIndicator)QwtPlotCanvas
setPaintAttribute(PaintAttribute, bool on=true)QwtPlotCanvas
testPaintAttribute(PaintAttribute) const QwtPlotCanvas
updateStyleSheetInfo()QwtPlotCanvasprotected
~QwtPlotCanvas()QwtPlotCanvasvirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_canvas.html b/ThirdParty/Qwt/doc/html/class_qwt_plot_canvas.html new file mode 100644 index 0000000000..59f0054547 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_canvas.html @@ -0,0 +1,661 @@ + + + + + + +Qwt User's Guide: QwtPlotCanvas Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+ +
+ +

Canvas of a QwtPlot. + More...

+ +

#include <qwt_plot_canvas.h>

+
+Inheritance diagram for QwtPlotCanvas:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + + + + +

+Public Types

enum  PaintAttribute { BackingStore = 1, +Opaque = 2, +HackStyledBackground = 4, +ImmediatePaint = 8 + }
 Paint attributes. More...
 
enum  FocusIndicator { NoFocusIndicator, +CanvasFocusIndicator, +ItemFocusIndicator + }
 Focus indicator The default setting is NoFocusIndicator. More...
 
+typedef QFlags< PaintAttributePaintAttributes
 Paint attributes.
 
+ + + +

+Public Slots

void replot ()
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 QwtPlotCanvas (QwtPlot *=NULL)
 Constructor. More...
 
+virtual ~QwtPlotCanvas ()
 Destructor.
 
+QwtPlotplot ()
 Return parent plot widget.
 
+const QwtPlotplot () const
 Return parent plot widget.
 
void setFocusIndicator (FocusIndicator)
 
FocusIndicator focusIndicator () const
 
void setBorderRadius (double)
 
double borderRadius () const
 
void setPaintAttribute (PaintAttribute, bool on=true)
 Changing the paint attributes. More...
 
bool testPaintAttribute (PaintAttribute) const
 
const QPixmap * backingStore () const
 
+void invalidateBackingStore ()
 Invalidate the internal backing store.
 
virtual bool event (QEvent *)
 
Q_INVOKABLE QPainterPath borderPath (const QRect &) const
 
+ + + + + + + + + + + + +

+Protected Member Functions

virtual void paintEvent (QPaintEvent *)
 
virtual void resizeEvent (QResizeEvent *)
 
virtual void drawFocusIndicator (QPainter *)
 
virtual void drawBorder (QPainter *)
 
+void updateStyleSheetInfo ()
 Update the cached information about the current style sheet.
 
+

Detailed Description

+

Canvas of a QwtPlot.

+

Canvas is the widget where all plot items are displayed

+
See Also
QwtPlot::setCanvas(), QwtPlotGLCanvas
+

Member Enumeration Documentation

+ +
+
+ +

Focus indicator The default setting is NoFocusIndicator.

+
See Also
setFocusIndicator(), focusIndicator(), paintFocus()
+ + + + +
Enumerator
NoFocusIndicator  +

Don't paint a focus indicator.

+
CanvasFocusIndicator  +

The focus is related to the complete canvas. Paint the focus indicator using paintFocus()

+
ItemFocusIndicator  +

The focus is related to an item (curve, point, ...) on the canvas. It is up to the application to display a focus indication using f.e. highlighting.

+
+ +
+
+ +
+
+ +

Paint attributes.

+

The default setting enables BackingStore and Opaque.

+
See Also
setPaintAttribute(), testPaintAttribute()
+ + + + + +
Enumerator
BackingStore  +

Paint double buffered reusing the content of the pixmap buffer when possible.

+

Using a backing store might improve the performance significantly, when working with widget overlays ( like rubber bands ). Disabling the cache might improve the performance for incremental paints (using QwtPlotDirectPainter ).

+
See Also
backingStore(), invalidateBackingStore()
+
Opaque  +

Try to fill the complete contents rectangle of the plot canvas.

+

When using styled backgrounds Qt assumes, that the canvas doesn't fill its area completely ( f.e because of rounded borders ) and fills the area below the canvas. When this is done with gradients it might result in a serious performance bottleneck - depending on the size.

+

When the Opaque attribute is enabled the canvas tries to identify the gaps with some heuristics and to fill those only.

+
Warning
Will not work for semitransparent backgrounds
+
HackStyledBackground  +

Try to improve painting of styled backgrounds.

+

QwtPlotCanvas supports the box model attributes for customizing the layout with style sheets. Unfortunately the design of Qt style sheets has no concept how to handle backgrounds with rounded corners - beside of padding.

+

When HackStyledBackground is enabled the plot canvas tries to separate the background from the background border by reverse engineering to paint the background before and the border after the plot items. In this order the border gets perfectly antialiased and you can avoid some pixel artifacts in the corners.

+
ImmediatePaint  +

When ImmediatePaint is set replot() calls repaint() instead of update().

+
See Also
replot(), QWidget::repaint(), QWidget::update()
+
+ +
+
+

Constructor & Destructor Documentation

+ +
+
+ + + + + +
+ + + + + + + + +
QwtPlotCanvas::QwtPlotCanvas (QwtPlotplot = NULL)
+
+explicit
+
+ +

Constructor.

+
Parameters
+ + +
plotParent plot widget
+
+
+
See Also
QwtPlot::setCanvas()
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + + + +
const QPixmap * QwtPlotCanvas::backingStore () const
+
+
Returns
Backing store, might be null
+ +
+
+ +
+
+ + + + + + + + +
QPainterPath QwtPlotCanvas::borderPath (const QRect & rect) const
+
+

Calculate the painter path for a styled or rounded border

+

When the canvas has no styled background or rounded borders the painter path is empty.

+
Parameters
+ + +
rectBounding rectangle of the canvas
+
+
+
Returns
Painter path, that can be used for clipping
+ +
+
+ +
+
+ + + + + + + +
double QwtPlotCanvas::borderRadius () const
+
+
Returns
Radius for the corners of the border frame
+
See Also
setBorderRadius()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtPlotCanvas::drawBorder (QPainter * painter)
+
+protectedvirtual
+
+

Draw the border of the plot canvas

+
Parameters
+ + +
painterPainter
+
+
+
See Also
setBorderRadius()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtPlotCanvas::drawFocusIndicator (QPainter * painter)
+
+protectedvirtual
+
+

Draw the focus indication

+
Parameters
+ + +
painterPainter
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool QwtPlotCanvas::event (QEvent * event)
+
+virtual
+
+

Qt event handler for QEvent::PolishRequest and QEvent::StyleChange

+
Parameters
+ + +
eventQt Event
+
+
+
Returns
See QFrame::event()
+ +
+
+ +
+
+ + + + + + + +
QwtPlotCanvas::FocusIndicator QwtPlotCanvas::focusIndicator () const
+
+
Returns
Focus indicator
+
See Also
FocusIndicator, setFocusIndicator()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtPlotCanvas::paintEvent (QPaintEvent * event)
+
+protectedvirtual
+
+

Paint event

+
Parameters
+ + +
eventPaint event
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void QwtPlotCanvas::replot ()
+
+slot
+
+

Invalidate the paint cache and repaint the canvas

+
See Also
invalidatePaintCache()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtPlotCanvas::resizeEvent (QResizeEvent * event)
+
+protectedvirtual
+
+

Resize event

+
Parameters
+ + +
eventResize event
+
+
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotCanvas::setBorderRadius (double radius)
+
+

Set the radius for the corners of the border frame

+
Parameters
+ + +
radiusRadius of a rounded corner
+
+
+
See Also
borderRadius()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotCanvas::setFocusIndicator (FocusIndicator focusIndicator)
+
+

Set the focus indicator

+
See Also
FocusIndicator, focusIndicator()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtPlotCanvas::setPaintAttribute (PaintAttribute attribute,
bool on = true 
)
+
+ +

Changing the paint attributes.

+
Parameters
+ + + +
attributePaint attribute
onOn/Off
+
+
+
See Also
testPaintAttribute(), backingStore()
+ +
+
+ +
+
+ + + + + + + + +
bool QwtPlotCanvas::testPaintAttribute (PaintAttribute attribute) const
+
+

Test whether a paint attribute is enabled

+
Parameters
+ + +
attributePaint attribute
+
+
+
Returns
true, when attribute is enabled
+
See Also
setPaintAttribute()
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_canvas__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_plot_canvas__inherit__graph.map new file mode 100644 index 0000000000..a7b30a9c8e --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_canvas__inherit__graph.map @@ -0,0 +1,2 @@ + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_canvas__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_plot_canvas__inherit__graph.md5 new file mode 100644 index 0000000000..b1b4d74014 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_canvas__inherit__graph.md5 @@ -0,0 +1 @@ +a7a3e1598838e1f10508556c21178526 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_canvas__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_plot_canvas__inherit__graph.png new file mode 100644 index 0000000000..eee9d5977d Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_plot_canvas__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_curve-members.html b/ThirdParty/Qwt/doc/html/class_qwt_plot_curve-members.html new file mode 100644 index 0000000000..5118817dfa --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_curve-members.html @@ -0,0 +1,258 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtPlotCurve Member List
+
+
+ +

This is the complete list of members for QwtPlotCurve, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
attach(QwtPlot *plot)QwtPlotItem
AutoScale enum valueQwtPlotItem
baseline() const QwtPlotCurve
boundingRect() const QwtPlotSeriesItemvirtual
brush() const QwtPlotCurve
ClipPolygons enum valueQwtPlotCurve
closePolyline(QPainter *, const QwtScaleMap &, const QwtScaleMap &, QPolygonF &) const QwtPlotCurveprotected
closestPoint(const QPoint &pos, double *dist=NULL) const QwtPlotCurve
CurveAttribute enum nameQwtPlotCurve
CurveAttributes typedefQwtPlotCurve
curveFitter() const QwtPlotCurve
CurveStyle enum nameQwtPlotCurve
data()QwtSeriesStore< QPointF >
data() constQwtSeriesStore< QPointF >
dataChanged()QwtPlotSeriesItemprotectedvirtual
QwtPlotSeriesItem::dataRect() const =0QwtAbstractSeriesStoreprotectedpure virtual
QwtSeriesStore< QPointF >::dataRect() constQwtSeriesStore< QPointF >virtual
QwtPlotSeriesItem::dataSize() const =0QwtAbstractSeriesStoreprotectedpure virtual
QwtSeriesStore< QPointF >::dataSize() constQwtSeriesStore< QPointF >virtual
defaultIcon(const QBrush &, const QSizeF &) const QwtPlotItemprotected
detach()QwtPlotItem
Dots enum valueQwtPlotCurve
draw(QPainter *p, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &) const QwtPlotSeriesItemvirtual
drawCurve(QPainter *p, int style, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, int from, int to) const QwtPlotCurveprotectedvirtual
drawDots(QPainter *p, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, int from, int to) const QwtPlotCurveprotectedvirtual
drawLines(QPainter *p, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, int from, int to) const QwtPlotCurveprotectedvirtual
drawSeries(QPainter *, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, int from, int to) const QwtPlotCurvevirtual
drawSteps(QPainter *p, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, int from, int to) const QwtPlotCurveprotectedvirtual
drawSticks(QPainter *p, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, int from, int to) const QwtPlotCurveprotectedvirtual
drawSymbols(QPainter *p, const QwtSymbol &, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, int from, int to) const QwtPlotCurveprotectedvirtual
fillCurve(QPainter *, const QwtScaleMap &, const QwtScaleMap &, const QRectF &canvasRect, QPolygonF &) const QwtPlotCurveprotectedvirtual
FilterPoints enum valueQwtPlotCurve
Fitted enum valueQwtPlotCurve
getCanvasMarginHint(const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasSize, double &left, double &top, double &right, double &bottom) const QwtPlotItemvirtual
hide()QwtPlotItem
ImageBuffer enum valueQwtPlotCurve
init()QwtPlotCurveprotected
Inverted enum valueQwtPlotCurve
isVisible() const QwtPlotItem
ItemAttribute enum nameQwtPlotItem
ItemAttributes typedefQwtPlotItem
itemChanged()QwtPlotItemvirtual
ItemInterest enum nameQwtPlotItem
ItemInterests typedefQwtPlotItem
Legend enum valueQwtPlotItem
LegendAttribute enum nameQwtPlotCurve
LegendAttributes typedefQwtPlotCurve
legendChanged()QwtPlotItemvirtual
legendData() const QwtPlotItemvirtual
legendIcon(int index, const QSizeF &) const QwtPlotCurvevirtual
legendIconSize() const QwtPlotItem
LegendInterest enum valueQwtPlotItem
LegendNoAttribute enum valueQwtPlotCurve
LegendShowBrush enum valueQwtPlotCurve
LegendShowLine enum valueQwtPlotCurve
LegendShowSymbol enum valueQwtPlotCurve
Lines enum valueQwtPlotCurve
Margins enum valueQwtPlotItem
maxXValue() const QwtPlotCurveinline
maxYValue() const QwtPlotCurveinline
MinimizeMemory enum valueQwtPlotCurve
minXValue() const QwtPlotCurveinline
minYValue() const QwtPlotCurveinline
NoCurve enum valueQwtPlotCurve
orientation() const QwtPlotSeriesItem
PaintAttribute enum nameQwtPlotCurve
PaintAttributes typedefQwtPlotCurve
paintRect(const QwtScaleMap &, const QwtScaleMap &) const QwtPlotItem
pen() const QwtPlotCurve
plot() const QwtPlotItem
QwtPlotCurve(const QString &title=QString::null)QwtPlotCurveexplicit
QwtPlotCurve(const QwtText &title)QwtPlotCurveexplicit
QwtPlotItem(const QwtText &title=QwtText())QwtPlotItemexplicit
QwtPlotSeriesItem(const QString &title=QString::null)QwtPlotSeriesItemexplicit
QwtPlotSeriesItem(const QwtText &title)QwtPlotSeriesItemexplicit
QwtSeriesStore()QwtSeriesStore< QPointF >explicit
RenderAntialiased enum valueQwtPlotItem
RenderHint enum nameQwtPlotItem
RenderHints typedefQwtPlotItem
renderThreadCount() const QwtPlotItem
rtti() const QwtPlotCurvevirtual
Rtti_PlotBarChart enum valueQwtPlotItem
Rtti_PlotCurve enum valueQwtPlotItem
Rtti_PlotGrid enum valueQwtPlotItem
Rtti_PlotHistogram enum valueQwtPlotItem
Rtti_PlotIntervalCurve enum valueQwtPlotItem
Rtti_PlotItem enum valueQwtPlotItem
Rtti_PlotLegend enum valueQwtPlotItem
Rtti_PlotMarker enum valueQwtPlotItem
Rtti_PlotMultiBarChart enum valueQwtPlotItem
Rtti_PlotScale enum valueQwtPlotItem
Rtti_PlotShape enum valueQwtPlotItem
Rtti_PlotSpectroCurve enum valueQwtPlotItem
Rtti_PlotSpectrogram enum valueQwtPlotItem
Rtti_PlotSVG enum valueQwtPlotItem
Rtti_PlotTextLabel enum valueQwtPlotItem
Rtti_PlotTradingCurve enum valueQwtPlotItem
Rtti_PlotUserItem enum valueQwtPlotItem
Rtti_PlotZone enum valueQwtPlotItem
RttiValues enum nameQwtPlotItem
sample(int index) constQwtSeriesStore< QPointF >
ScaleInterest enum valueQwtPlotItem
scaleRect(const QwtScaleMap &, const QwtScaleMap &) const QwtPlotItem
setAxes(int xAxis, int yAxis)QwtPlotItem
setBaseline(double)QwtPlotCurve
setBrush(const QBrush &)QwtPlotCurve
setCurveAttribute(CurveAttribute, bool on=true)QwtPlotCurve
setCurveFitter(QwtCurveFitter *)QwtPlotCurve
setData(QwtSeriesData< QPointF > *series)QwtSeriesStore< QPointF >
setItemAttribute(ItemAttribute, bool on=true)QwtPlotItem
setItemInterest(ItemInterest, bool on=true)QwtPlotItem
setLegendAttribute(LegendAttribute, bool on=true)QwtPlotCurve
setLegendIconSize(const QSize &)QwtPlotItem
setOrientation(Qt::Orientation)QwtPlotSeriesItem
setPaintAttribute(PaintAttribute, bool on=true)QwtPlotCurve
setPen(const QColor &, qreal width=0.0, Qt::PenStyle=Qt::SolidLine)QwtPlotCurve
setPen(const QPen &)QwtPlotCurve
setRawSamples(const double *xData, const double *yData, int size)QwtPlotCurve
QwtPlotSeriesItem::setRectOfInterest(const QRectF &)=0QwtAbstractSeriesStoreprotectedpure virtual
QwtSeriesStore< QPointF >::setRectOfInterest(const QRectF &rect)QwtSeriesStore< QPointF >virtual
setRenderHint(RenderHint, bool on=true)QwtPlotItem
setRenderThreadCount(uint numThreads)QwtPlotItem
setSamples(const double *xData, const double *yData, int size)QwtPlotCurve
setSamples(const QVector< double > &xData, const QVector< double > &yData)QwtPlotCurve
setSamples(const QVector< QPointF > &)QwtPlotCurve
setSamples(QwtSeriesData< QPointF > *)QwtPlotCurve
setStyle(CurveStyle style)QwtPlotCurve
setSymbol(QwtSymbol *)QwtPlotCurve
setTitle(const QString &title)QwtPlotItem
setTitle(const QwtText &title)QwtPlotItem
setVisible(bool)QwtPlotItemvirtual
setXAxis(int axis)QwtPlotItem
setYAxis(int axis)QwtPlotItem
setZ(double z)QwtPlotItem
show()QwtPlotItem
Steps enum valueQwtPlotCurve
Sticks enum valueQwtPlotCurve
style() const QwtPlotCurve
swapData(QwtSeriesData< QPointF > *series)QwtSeriesStore< QPointF >
symbol() const QwtPlotCurve
testCurveAttribute(CurveAttribute) const QwtPlotCurve
testItemAttribute(ItemAttribute) const QwtPlotItem
testItemInterest(ItemInterest) const QwtPlotItem
testLegendAttribute(LegendAttribute) const QwtPlotCurve
testPaintAttribute(PaintAttribute) const QwtPlotCurve
testRenderHint(RenderHint) const QwtPlotItem
title() const QwtPlotItem
updateLegend(const QwtPlotItem *, const QList< QwtLegendData > &)QwtPlotItemvirtual
updateScaleDiv(const QwtScaleDiv &, const QwtScaleDiv &)QwtPlotSeriesItemvirtual
UserCurve enum valueQwtPlotCurve
xAxis() const QwtPlotItem
yAxis() const QwtPlotItem
z() const QwtPlotItem
~QwtAbstractSeriesStore()QwtAbstractSeriesStoreinlineprotectedvirtual
~QwtPlotCurve()QwtPlotCurvevirtual
~QwtPlotItem()QwtPlotItemvirtual
~QwtPlotSeriesItem()QwtPlotSeriesItemvirtual
~QwtSeriesStore()QwtSeriesStore< QPointF >
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_curve.html b/ThirdParty/Qwt/doc/html/class_qwt_plot_curve.html new file mode 100644 index 0000000000..cd8c1f478e --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_curve.html @@ -0,0 +1,1994 @@ + + + + + + +Qwt User's Guide: QwtPlotCurve Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+ +
+ +

A plot item, that represents a series of points. + More...

+ +

#include <qwt_plot_curve.h>

+
+Inheritance diagram for QwtPlotCurve:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + + + + + + + + + + + + +

+Public Types

enum  CurveStyle {
+  NoCurve = -1, +Lines, +Sticks, +Steps, +
+  Dots, +UserCurve = 100 +
+ }
 
enum  CurveAttribute { Inverted = 0x01, +Fitted = 0x02 + }
 
enum  LegendAttribute { LegendNoAttribute = 0x00, +LegendShowLine = 0x01, +LegendShowSymbol = 0x02, +LegendShowBrush = 0x04 + }
 
enum  PaintAttribute { ClipPolygons = 0x01, +FilterPoints = 0x02, +MinimizeMemory = 0x04, +ImageBuffer = 0x08 + }
 
+typedef QFlags< CurveAttributeCurveAttributes
 Curve attributes.
 
+typedef QFlags< LegendAttributeLegendAttributes
 Legend attributes.
 
+typedef QFlags< PaintAttributePaintAttributes
 Paint attributes.
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 QwtPlotCurve (const QString &title=QString::null)
 
 QwtPlotCurve (const QwtText &title)
 
+virtual ~QwtPlotCurve ()
 Destructor.
 
virtual int rtti () const
 
void setPaintAttribute (PaintAttribute, bool on=true)
 
bool testPaintAttribute (PaintAttribute) const
 
void setLegendAttribute (LegendAttribute, bool on=true)
 
bool testLegendAttribute (LegendAttribute) const
 
void setRawSamples (const double *xData, const double *yData, int size)
 Initialize the data by pointing to memory blocks which are not managed by QwtPlotCurve. More...
 
void setSamples (const double *xData, const double *yData, int size)
 
void setSamples (const QVector< double > &xData, const QVector< double > &yData)
 Initialize data with x- and y-arrays (explicitly shared) More...
 
void setSamples (const QVector< QPointF > &)
 
void setSamples (QwtSeriesData< QPointF > *)
 
int closestPoint (const QPoint &pos, double *dist=NULL) const
 
+double minXValue () const
 boundingRect().left()
 
+double maxXValue () const
 boundingRect().right()
 
+double minYValue () const
 boundingRect().top()
 
+double maxYValue () const
 boundingRect().bottom()
 
void setCurveAttribute (CurveAttribute, bool on=true)
 
bool testCurveAttribute (CurveAttribute) const
 
void setPen (const QColor &, qreal width=0.0, Qt::PenStyle=Qt::SolidLine)
 
void setPen (const QPen &)
 
const QPen & pen () const
 
void setBrush (const QBrush &)
 Assign a brush. More...
 
const QBrush & brush () const
 
void setBaseline (double)
 Set the value of the baseline. More...
 
double baseline () const
 
void setStyle (CurveStyle style)
 
CurveStyle style () const
 
void setSymbol (QwtSymbol *)
 Assign a symbol. More...
 
const QwtSymbolsymbol () const
 
void setCurveFitter (QwtCurveFitter *)
 
QwtCurveFittercurveFitter () const
 
virtual void drawSeries (QPainter *, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, int from, int to) const
 
virtual QwtGraphic legendIcon (int index, const QSizeF &) const
 
- Public Member Functions inherited from QwtPlotSeriesItem
 QwtPlotSeriesItem (const QString &title=QString::null)
 
 QwtPlotSeriesItem (const QwtText &title)
 
+virtual ~QwtPlotSeriesItem ()
 Destructor.
 
void setOrientation (Qt::Orientation)
 
Qt::Orientation orientation () const
 
virtual void draw (QPainter *p, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &) const
 Draw the complete series. More...
 
virtual QRectF boundingRect () const
 
virtual void updateScaleDiv (const QwtScaleDiv &, const QwtScaleDiv &)
 Update the item to changes of the axes scale division. More...
 
- Public Member Functions inherited from QwtPlotItem
 QwtPlotItem (const QwtText &title=QwtText())
 
+virtual ~QwtPlotItem ()
 Destroy the QwtPlotItem.
 
void attach (QwtPlot *plot)
 Attach the item to a plot. More...
 
void detach ()
 This method detaches a QwtPlotItem from any QwtPlot it has been associated with. More...
 
+QwtPlotplot () const
 Return attached plot.
 
void setTitle (const QString &title)
 
void setTitle (const QwtText &title)
 
const QwtTexttitle () const
 
void setItemAttribute (ItemAttribute, bool on=true)
 
bool testItemAttribute (ItemAttribute) const
 
void setItemInterest (ItemInterest, bool on=true)
 
bool testItemInterest (ItemInterest) const
 
void setRenderHint (RenderHint, bool on=true)
 
bool testRenderHint (RenderHint) const
 
void setRenderThreadCount (uint numThreads)
 
uint renderThreadCount () const
 
void setLegendIconSize (const QSize &)
 
QSize legendIconSize () const
 
double z () const
 
void setZ (double z)
 Set the z value. More...
 
+void show ()
 Show the item.
 
+void hide ()
 Hide the item.
 
virtual void setVisible (bool)
 
bool isVisible () const
 
void setAxes (int xAxis, int yAxis)
 
void setXAxis (int axis)
 
+int xAxis () const
 Return xAxis.
 
void setYAxis (int axis)
 
+int yAxis () const
 Return yAxis.
 
virtual void itemChanged ()
 
virtual void legendChanged ()
 
virtual void getCanvasMarginHint (const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasSize, double &left, double &top, double &right, double &bottom) const
 Calculate a hint for the canvas margin. More...
 
virtual void updateLegend (const QwtPlotItem *, const QList< QwtLegendData > &)
 Update the item to changes of the legend info. More...
 
QRectF scaleRect (const QwtScaleMap &, const QwtScaleMap &) const
 Calculate the bounding scale rectangle of 2 maps. More...
 
QRectF paintRect (const QwtScaleMap &, const QwtScaleMap &) const
 Calculate the bounding paint rectangle of 2 maps. More...
 
virtual QList< QwtLegendDatalegendData () const
 Return all information, that is needed to represent the item on the legend. More...
 
- Public Member Functions inherited from QwtSeriesStore< QPointF >
QwtSeriesStore ()
 Constructor The store contains no series.
 
~QwtSeriesStore ()
 Destructor.
 
void setData (QwtSeriesData< QPointF > *series)
 
QwtSeriesData< QPointF > * data ()
 
const QwtSeriesData< QPointF > * data () const
 
QPointF sample (int index) const
 
virtual size_t dataSize () const
 
virtual QRectF dataRect () const
 
virtual void setRectOfInterest (const QRectF &rect)
 
QwtSeriesData< QPointF > * swapData (QwtSeriesData< QPointF > *series)
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Protected Member Functions

+void init ()
 Initialize internal members.
 
virtual void drawCurve (QPainter *p, int style, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, int from, int to) const
 Draw the line part (without symbols) of a curve interval. More...
 
virtual void drawSymbols (QPainter *p, const QwtSymbol &, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, int from, int to) const
 
virtual void drawLines (QPainter *p, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, int from, int to) const
 Draw lines. More...
 
virtual void drawSticks (QPainter *p, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, int from, int to) const
 
virtual void drawDots (QPainter *p, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, int from, int to) const
 
virtual void drawSteps (QPainter *p, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, int from, int to) const
 
virtual void fillCurve (QPainter *, const QwtScaleMap &, const QwtScaleMap &, const QRectF &canvasRect, QPolygonF &) const
 
void closePolyline (QPainter *, const QwtScaleMap &, const QwtScaleMap &, QPolygonF &) const
 Complete a polygon to be a closed polygon including the area between the original polygon and the baseline. More...
 
- Protected Member Functions inherited from QwtPlotSeriesItem
+virtual void dataChanged ()
 dataChanged() indicates, that the series has been changed.
 
- Protected Member Functions inherited from QwtPlotItem
QwtGraphic defaultIcon (const QBrush &, const QSizeF &) const
 Return a default icon from a brush. More...
 
- Protected Member Functions inherited from QwtAbstractSeriesStore
+virtual ~QwtAbstractSeriesStore ()
 Destructor.
 
+

Detailed Description

+

A plot item, that represents a series of points.

+

A curve is the representation of a series of points in the x-y plane. It supports different display styles, interpolation ( f.e. spline ) and symbols.

+
Usage
+
a) Assign curve properties
+
When a curve is created, it is configured to draw black solid lines with in QwtPlotCurve::Lines style and no symbols. You can change this by calling setPen(), setStyle() and setSymbol().
+
b) Connect/Assign data.
+
QwtPlotCurve gets its points using a QwtSeriesData object offering a bridge to the real storage of the points ( like QAbstractItemModel ). There are several convenience classes derived from QwtSeriesData, that also store the points inside ( like QStandardItemModel ). QwtPlotCurve also offers a couple of variations of setSamples(), that build QwtSeriesData objects from arrays internally.
+
c) Attach the curve to a plot
+
See QwtPlotItem::attach()
+
+
+
Example:
see examples/bode
+
See Also
QwtPointSeriesData, QwtSymbol, QwtScaleMap
+

Member Enumeration Documentation

+ +
+
+

Attribute for drawing the curve

+
See Also
setCurveAttribute(), testCurveAttribute(), curveFitter()
+ + + +
Enumerator
Inverted  +

For QwtPlotCurve::Steps only. Draws a step function from the right to the left.

+
Fitted  +

Only in combination with QwtPlotCurve::Lines A QwtCurveFitter tries to interpolate/smooth the curve, before it is painted.

+
Note
Curve fitting requires temporary memory for calculating coefficients and additional points. If painting in QwtPlotCurve::Fitted mode is slow it might be better to fit the points, before they are passed to QwtPlotCurve.
+
+ +
+
+ +
+
+ + + + +
enum QwtPlotCurve::CurveStyle
+
+

Curve styles.

+
See Also
setStyle(), style()
+ + + + + + + +
Enumerator
NoCurve  +

Don't draw a curve. Note: This doesn't affect the symbols.

+
Lines  +

Connect the points with straight lines. The lines might be interpolated depending on the 'Fitted' attribute. Curve fitting can be configured using setCurveFitter().

+
Sticks  +

Draw vertical or horizontal sticks ( depending on the orientation() ) from a baseline which is defined by setBaseline().

+
Steps  +

Connect the points with a step function. The step function is drawn from the left to the right or vice versa, depending on the QwtPlotCurve::Inverted attribute.

+
Dots  +

Draw dots at the locations of the data points. Note: This is different from a dotted line (see setPen()), and faster as a curve in QwtPlotCurve::NoStyle style and a symbol painting a point.

+
UserCurve  +

Styles >= QwtPlotCurve::UserCurve are reserved for derived classes of QwtPlotCurve that overload drawCurve() with additional application specific curve types.

+
+ +
+
+ +
+
+

Attributes how to represent the curve on the legend

+
See Also
setLegendAttribute(), testLegendAttribute(), QwtPlotItem::legendData(), legendIcon()
+ + + + + +
Enumerator
LegendNoAttribute  +

QwtPlotCurve tries to find a color representing the curve and paints a rectangle with it.

+
LegendShowLine  +

If the style() is not QwtPlotCurve::NoCurve a line is painted with the curve pen().

+
LegendShowSymbol  +

If the curve has a valid symbol it is painted.

+
LegendShowBrush  +

If the curve has a brush a rectangle filled with the curve brush() is painted.

+
+ +
+
+ +
+
+

Attributes to modify the drawing algorithm. The default setting enables ClipPolygons | FilterPoints

+
See Also
setPaintAttribute(), testPaintAttribute()
+ + + + + +
Enumerator
ClipPolygons  +

Clip polygons before painting them. In situations, where points are far outside the visible area (f.e when zooming deep) this might be a substantial improvement for the painting performance

+
FilterPoints  +

Tries to reduce the data that has to be painted, by sorting out duplicates, or paintings outside the visible area. Might have a notable impact on curves with many close points. Only a couple of very basic filtering algorithms are implemented.

+
MinimizeMemory  +

Minimize memory usage that is temporarily needed for the translated points, before they get painted. This might slow down the performance of painting

+
ImageBuffer  +

Render the points to a temporary image and paint the image. This is a very special optimization for Dots style, when having a huge amount of points. With a reasonable number of points QPainter::drawPoints() will be faster.

+
+ +
+
+

Constructor & Destructor Documentation

+ +
+
+ + + + + +
+ + + + + + + + +
QwtPlotCurve::QwtPlotCurve (const QString & title = QString::null)
+
+explicit
+
+

Constructor

+
Parameters
+ + +
titleTitle of the curve
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
QwtPlotCurve::QwtPlotCurve (const QwtTexttitle)
+
+explicit
+
+

Constructor

+
Parameters
+ + +
titleTitle of the curve
+
+
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + + + +
double QwtPlotCurve::baseline () const
+
+
Returns
Value of the baseline
+
See Also
setBaseline()
+ +
+
+ +
+
+ + + + + + + +
const QBrush & QwtPlotCurve::brush () const
+
+
Returns
Brush used to fill the area between lines and the baseline
+
See Also
setBrush(), setBaseline(), baseline()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPlotCurve::closePolyline (QPainter * painter,
const QwtScaleMapxMap,
const QwtScaleMapyMap,
QPolygonF & polygon 
) const
+
+protected
+
+ +

Complete a polygon to be a closed polygon including the area between the original polygon and the baseline.

+
Parameters
+ + + + + +
painterPainter
xMapX map
yMapY map
polygonPolygon to be completed
+
+
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
int QwtPlotCurve::closestPoint (const QPoint & pos,
double * dist = NULL 
) const
+
+

Find the closest curve point for a specific position

+
Parameters
+ + + +
posPosition, where to look for the closest curve point
distIf dist != NULL, closestPoint() returns the distance between the position and the closest curve point
+
+
+
Returns
Index of the closest curve point, or -1 if none can be found ( f.e when the curve has no points )
+
Note
closestPoint() implements a dumb algorithm, that iterates over all points
+ +
+
+ +
+
+ + + + + + + +
QwtCurveFitter * QwtPlotCurve::curveFitter () const
+
+

Get the curve fitter. If curve fitting is disabled NULL is returned.

+
Returns
Curve fitter
+
See Also
setCurveFitter(), Fitted
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPlotCurve::drawCurve (QPainter * painter,
int style,
const QwtScaleMapxMap,
const QwtScaleMapyMap,
const QRectF & canvasRect,
int from,
int to 
) const
+
+protectedvirtual
+
+ +

Draw the line part (without symbols) of a curve interval.

+
Parameters
+ + + + + + + + +
painterPainter
stylecurve style, see QwtPlotCurve::CurveStyle
xMapx map
yMapy map
canvasRectContents rectangle of the canvas
fromindex of the first point to be painted
toindex of the last point to be painted
+
+
+
See Also
draw(), drawDots(), drawLines(), drawSteps(), drawSticks()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPlotCurve::drawDots (QPainter * painter,
const QwtScaleMapxMap,
const QwtScaleMapyMap,
const QRectF & canvasRect,
int from,
int to 
) const
+
+protectedvirtual
+
+

Draw dots

+
Parameters
+ + + + + + + +
painterPainter
xMapx map
yMapy map
canvasRectContents rectangle of the canvas
fromindex of the first point to be painted
toindex of the last point to be painted
+
+
+
See Also
draw(), drawCurve(), drawSticks(), drawLines(), drawSteps()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPlotCurve::drawLines (QPainter * painter,
const QwtScaleMapxMap,
const QwtScaleMapyMap,
const QRectF & canvasRect,
int from,
int to 
) const
+
+protectedvirtual
+
+ +

Draw lines.

+

If the CurveAttribute Fitted is enabled a QwtCurveFitter tries to interpolate/smooth the curve, before it is painted.

+
Parameters
+ + + + + + + +
painterPainter
xMapx map
yMapy map
canvasRectContents rectangle of the canvas
fromindex of the first point to be painted
toindex of the last point to be painted
+
+
+
See Also
setCurveAttribute(), setCurveFitter(), draw(), drawLines(), drawDots(), drawSteps(), drawSticks()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPlotCurve::drawSeries (QPainter * painter,
const QwtScaleMapxMap,
const QwtScaleMapyMap,
const QRectF & canvasRect,
int from,
int to 
) const
+
+virtual
+
+

Draw an interval of the curve

+
Parameters
+ + + + + + + +
painterPainter
xMapMaps x-values into pixel coordinates.
yMapMaps y-values into pixel coordinates.
canvasRectContents rectangle of the canvas
fromIndex of the first point to be painted
toIndex of the last point to be painted. If to < 0 the curve will be painted to its last point.
+
+
+
See Also
drawCurve(), drawSymbols(),
+ +

Implements QwtPlotSeriesItem.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPlotCurve::drawSteps (QPainter * painter,
const QwtScaleMapxMap,
const QwtScaleMapyMap,
const QRectF & canvasRect,
int from,
int to 
) const
+
+protectedvirtual
+
+

Draw step function

+

The direction of the steps depends on Inverted attribute.

+
Parameters
+ + + + + + + +
painterPainter
xMapx map
yMapy map
canvasRectContents rectangle of the canvas
fromindex of the first point to be painted
toindex of the last point to be painted
+
+
+
See Also
CurveAttribute, setCurveAttribute(), draw(), drawCurve(), drawDots(), drawLines(), drawSticks()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPlotCurve::drawSticks (QPainter * painter,
const QwtScaleMapxMap,
const QwtScaleMapyMap,
const QRectF & canvasRect,
int from,
int to 
) const
+
+protectedvirtual
+
+

Draw sticks

+
Parameters
+ + + + + + + +
painterPainter
xMapx map
yMapy map
canvasRectContents rectangle of the canvas
fromindex of the first point to be painted
toindex of the last point to be painted
+
+
+
See Also
draw(), drawCurve(), drawDots(), drawLines(), drawSteps()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPlotCurve::drawSymbols (QPainter * painter,
const QwtSymbolsymbol,
const QwtScaleMapxMap,
const QwtScaleMapyMap,
const QRectF & canvasRect,
int from,
int to 
) const
+
+protectedvirtual
+
+

Draw symbols

+
Parameters
+ + + + + + + + +
painterPainter
symbolCurve symbol
xMapx map
yMapy map
canvasRectContents rectangle of the canvas
fromIndex of the first point to be painted
toIndex of the last point to be painted
+
+
+
See Also
setSymbol(), drawSeries(), drawCurve()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPlotCurve::fillCurve (QPainter * painter,
const QwtScaleMapxMap,
const QwtScaleMapyMap,
const QRectF & canvasRect,
QPolygonF & polygon 
) const
+
+protectedvirtual
+
+

Fill the area between the curve and the baseline with the curve brush

+
Parameters
+ + + + + + +
painterPainter
xMapx map
yMapy map
canvasRectContents rectangle of the canvas
polygonPolygon - will be modified !
+
+
+
See Also
setBrush(), setBaseline(), setStyle()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
QwtGraphic QwtPlotCurve::legendIcon (int index,
const QSizeF & size 
) const
+
+virtual
+
+
Returns
Icon representing the curve on the legend
+
Parameters
+ + + +
indexIndex of the legend entry ( ignored as there is only one )
sizeIcon size
+
+
+
See Also
QwtPlotItem::setLegendIconSize(), QwtPlotItem::legendData()
+ +

Reimplemented from QwtPlotItem.

+ +
+
+ +
+
+ + + + + + + +
const QPen & QwtPlotCurve::pen () const
+
+
Returns
Pen used to draw the lines
+
See Also
setPen(), brush()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
int QwtPlotCurve::rtti () const
+
+virtual
+
+
Returns
QwtPlotItem::Rtti_PlotCurve
+ +

Reimplemented from QwtPlotItem.

+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotCurve::setBaseline (double value)
+
+ +

Set the value of the baseline.

+

The baseline is needed for filling the curve with a brush or the Sticks drawing style.

+

The interpretation of the baseline depends on the orientation(). With Qt::Horizontal, the baseline is interpreted as a horizontal line at y = baseline(), with Qt::Vertical, it is interpreted as a vertical line at x = baseline().

+

The default value is 0.0.

+
Parameters
+ + +
valueValue of the baseline
+
+
+
See Also
baseline(), setBrush(), setStyle(), QwtPlotAbstractSeriesItem::orientation()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotCurve::setBrush (const QBrush & brush)
+
+ +

Assign a brush.

+

In case of brush.style() != QBrush::NoBrush and style() != QwtPlotCurve::Sticks the area between the curve and the baseline will be filled.

+

In case !brush.color().isValid() the area will be filled by pen.color(). The fill algorithm simply connects the first and the last curve point to the baseline. So the curve data has to be sorted (ascending or descending).

+
Parameters
+ + +
brushNew brush
+
+
+
See Also
brush(), setBaseline(), baseline()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtPlotCurve::setCurveAttribute (CurveAttribute attribute,
bool on = true 
)
+
+

Specify an attribute for drawing the curve

+
Parameters
+ + + +
attributeCurve attribute
onOn/Off
+
+
+

/sa testCurveAttribute(), setCurveFitter()

+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotCurve::setCurveFitter (QwtCurveFittercurveFitter)
+
+

Assign a curve fitter

+

The curve fitter "smooths" the curve points, when the Fitted CurveAttribute is set. setCurveFitter(NULL) also disables curve fitting.

+

The curve fitter operates on the translated points ( = widget coordinates) to be functional for logarithmic scales. Obviously this is less performant for fitting algorithms, that reduce the number of points.

+

For situations, where curve fitting is used to improve the performance of painting huge series of points it might be better to execute the fitter on the curve points once and to cache the result in the QwtSeriesData object.

+
Parameters
+ + +
curveFitter()Curve fitter
+
+
+
See Also
Fitted
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtPlotCurve::setLegendAttribute (LegendAttribute attribute,
bool on = true 
)
+
+

Specify an attribute how to draw the legend icon

+
Parameters
+ + + +
attributeAttribute
onOn/Off /sa testLegendAttribute(). legendIcon()
+
+
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtPlotCurve::setPaintAttribute (PaintAttribute attribute,
bool on = true 
)
+
+

Specify an attribute how to draw the curve

+
Parameters
+ + + +
attributePaint attribute
onOn/Off
+
+
+
See Also
testPaintAttribute()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPlotCurve::setPen (const QColor & color,
qreal width = 0.0,
Qt::PenStyle style = Qt::SolidLine 
)
+
+

Build and assign a pen

+

In Qt5 the default pen width is 1.0 ( 0.0 in Qt4 ) what makes it non cosmetic ( see QPen::isCosmetic() ). This method has been introduced to hide this incompatibility.

+
Parameters
+ + + + +
colorPen color
widthPen width
stylePen style
+
+
+
See Also
pen(), brush()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotCurve::setPen (const QPen & pen)
+
+

Assign a pen

+
Parameters
+ + +
penNew pen
+
+
+
See Also
pen(), brush()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPlotCurve::setRawSamples (const double * xData,
const double * yData,
int size 
)
+
+ +

Initialize the data by pointing to memory blocks which are not managed by QwtPlotCurve.

+

setRawSamples is provided for efficiency. It is important to keep the pointers during the lifetime of the underlying QwtCPointerData class.

+
Parameters
+ + + + +
xDatapointer to x data
yDatapointer to y data
sizesize of x and y
+
+
+
See Also
QwtCPointerData
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPlotCurve::setSamples (const double * xData,
const double * yData,
int size 
)
+
+

Set data by copying x- and y-values from specified memory blocks. Contrary to setRawSamples(), this function makes a 'deep copy' of the data.

+
Parameters
+ + + + +
xDatapointer to x values
yDatapointer to y values
sizesize of xData and yData
+
+
+
See Also
QwtPointArrayData
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtPlotCurve::setSamples (const QVector< double > & xData,
const QVector< double > & yData 
)
+
+ +

Initialize data with x- and y-arrays (explicitly shared)

+
Parameters
+ + + +
xDatax data
yDatay data
+
+
+
See Also
QwtPointArrayData
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotCurve::setSamples (const QVector< QPointF > & samples)
+
+

Initialize data with an array of points.

+
Parameters
+ + +
samplesVector of points
+
+
+
Note
QVector is implicitly shared
+
+QPolygonF is derived from QVector<QPointF>
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotCurve::setSamples (QwtSeriesData< QPointF > * data)
+
+

Assign a series of points

+

setSamples() is just a wrapper for setData() without any additional value - beside that it is easier to find for the developer.

+
Parameters
+ + +
dataData
+
+
+
Warning
The item takes ownership of the data object, deleting it when its not used anymore.
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotCurve::setStyle (CurveStyle style)
+
+

Set the curve's drawing style

+
Parameters
+ + +
styleCurve style
+
+
+
See Also
style()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotCurve::setSymbol (QwtSymbolsymbol)
+
+ +

Assign a symbol.

+

The curve will take the ownership of the symbol, hence the previously set symbol will be delete by setting a new one. If symbol is NULL no symbol will be drawn.

+
Parameters
+ + +
symbolSymbol
+
+
+
See Also
symbol()
+ +
+
+ +
+
+ + + + + + + +
QwtPlotCurve::CurveStyle QwtPlotCurve::style () const
+
+
Returns
Style of the curve
+
See Also
setStyle()
+ +
+
+ +
+
+ + + + + + + +
const QwtSymbol * QwtPlotCurve::symbol () const
+
+
Returns
Current symbol or NULL, when no symbol has been assigned
+
See Also
setSymbol()
+ +
+
+ +
+
+ + + + + + + + +
bool QwtPlotCurve::testCurveAttribute (CurveAttribute attribute) const
+
+
Returns
true, if attribute is enabled
+
See Also
setCurveAttribute()
+ +
+
+ +
+
+ + + + + + + + +
bool QwtPlotCurve::testLegendAttribute (LegendAttribute attribute) const
+
+
Returns
True, when attribute is enabled
+
See Also
setLegendAttribute()
+ +
+
+ +
+
+ + + + + + + + +
bool QwtPlotCurve::testPaintAttribute (PaintAttribute attribute) const
+
+
Returns
True, when attribute is enabled
+
See Also
setPaintAttribute()
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_curve__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_plot_curve__inherit__graph.map new file mode 100644 index 0000000000..67509e7933 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_curve__inherit__graph.map @@ -0,0 +1,6 @@ + + + + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_curve__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_plot_curve__inherit__graph.md5 new file mode 100644 index 0000000000..009db0f263 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_curve__inherit__graph.md5 @@ -0,0 +1 @@ +353733bbdac34e46547a346868e8af0f \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_curve__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_plot_curve__inherit__graph.png new file mode 100644 index 0000000000..bc50e0d524 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_plot_curve__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_dict-members.html b/ThirdParty/Qwt/doc/html/class_qwt_plot_dict-members.html new file mode 100644 index 0000000000..6dd64afb74 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_dict-members.html @@ -0,0 +1,109 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtPlotDict Member List
+
+
+ +

This is the complete list of members for QwtPlotDict, including all inherited members.

+ + + + + + + + + + +
autoDelete() const QwtPlotDict
detachItems(int rtti=QwtPlotItem::Rtti_PlotItem, bool autoDelete=true)QwtPlotDict
insertItem(QwtPlotItem *)QwtPlotDictprotected
itemList() const QwtPlotDict
itemList(int rtti) const QwtPlotDict
QwtPlotDict()QwtPlotDictexplicit
removeItem(QwtPlotItem *)QwtPlotDictprotected
setAutoDelete(bool)QwtPlotDict
~QwtPlotDict()QwtPlotDictvirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_dict.html b/ThirdParty/Qwt/doc/html/class_qwt_plot_dict.html new file mode 100644 index 0000000000..38f5a4dd9e --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_dict.html @@ -0,0 +1,374 @@ + + + + + + +Qwt User's Guide: QwtPlotDict Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+ +
+ +

A dictionary for plot items. + More...

+ +

#include <qwt_plot_dict.h>

+
+Inheritance diagram for QwtPlotDict:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + + + + + + + + + + +

+Public Member Functions

 QwtPlotDict ()
 
virtual ~QwtPlotDict ()
 
void setAutoDelete (bool)
 
bool autoDelete () const
 
const QwtPlotItemList & itemList () const
 A QwtPlotItemList of all attached plot items. More...
 
QwtPlotItemList itemList (int rtti) const
 
void detachItems (int rtti=QwtPlotItem::Rtti_PlotItem, bool autoDelete=true)
 
+ + + + + +

+Protected Member Functions

void insertItem (QwtPlotItem *)
 
void removeItem (QwtPlotItem *)
 
+

Detailed Description

+

A dictionary for plot items.

+

QwtPlotDict organizes plot items in increasing z-order. If autoDelete() is enabled, all attached items will be deleted in the destructor of the dictionary. QwtPlotDict can be used to get access to all QwtPlotItem items - or all items of a specific type - that are currently on the plot.

+
See Also
QwtPlotItem::attach(), QwtPlotItem::detach(), QwtPlotItem::z()
+

Constructor & Destructor Documentation

+ +
+
+ + + + + +
+ + + + + + + +
QwtPlotDict::QwtPlotDict ()
+
+explicit
+
+

Constructor

+

Auto deletion is enabled.

+
See Also
setAutoDelete(), QwtPlotItem::attach()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
QwtPlotDict::~QwtPlotDict ()
+
+virtual
+
+

Destructor

+

If autoDelete() is on, all attached items will be deleted

+
See Also
setAutoDelete(), autoDelete(), QwtPlotItem::attach()
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + + + +
bool QwtPlotDict::autoDelete () const
+
+
Returns
true if auto deletion is enabled
+
See Also
setAutoDelete(), insertItem()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtPlotDict::detachItems (int rtti = QwtPlotItem::Rtti_PlotItem,
bool autoDelete = true 
)
+
+

Detach items from the dictionary

+
Parameters
+ + + +
rttiIn case of QwtPlotItem::Rtti_PlotItem detach all items otherwise only those items of the type rtti.
autoDeleteIf true, delete all detached items
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtPlotDict::insertItem (QwtPlotItemitem)
+
+protected
+
+

Insert a plot item

+
Parameters
+ + +
itemPlotItem
+
+
+
See Also
removeItem()
+ +
+
+ +
+
+ + + + + + + +
const QwtPlotItemList & QwtPlotDict::itemList () const
+
+ +

A QwtPlotItemList of all attached plot items.

+

Use caution when iterating these lists, as removing/detaching an item will invalidate the iterator. Instead you can place pointers to objects to be removed in a removal list, and traverse that list later.

+
Returns
List of all attached plot items.
+ +
+
+ +
+
+ + + + + + + + +
QwtPlotItemList QwtPlotDict::itemList (int rtti) const
+
+
Returns
List of all attached plot items of a specific type.
+
Parameters
+ + +
rttiSee QwtPlotItem::RttiValues
+
+
+
See Also
QwtPlotItem::rtti()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtPlotDict::removeItem (QwtPlotItemitem)
+
+protected
+
+

Remove a plot item

+
Parameters
+ + +
itemPlotItem
+
+
+
See Also
insertItem()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotDict::setAutoDelete (bool autoDelete)
+
+

En/Disable Auto deletion

+

If Auto deletion is on all attached plot items will be deleted in the destructor of QwtPlotDict. The default value is on.

+
See Also
autoDelete(), insertItem()
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_dict__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_plot_dict__inherit__graph.map new file mode 100644 index 0000000000..9adb3a7a84 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_dict__inherit__graph.map @@ -0,0 +1,3 @@ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_dict__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_plot_dict__inherit__graph.md5 new file mode 100644 index 0000000000..d007ee8f1d --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_dict__inherit__graph.md5 @@ -0,0 +1 @@ +f186dd1af0efac70dc700aef0235f613 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_dict__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_plot_dict__inherit__graph.png new file mode 100644 index 0000000000..ce39851335 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_plot_dict__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_direct_painter-members.html b/ThirdParty/Qwt/doc/html/class_qwt_plot_direct_painter-members.html new file mode 100644 index 0000000000..234a576344 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_direct_painter-members.html @@ -0,0 +1,116 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtPlotDirectPainter Member List
+
+ + + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_direct_painter.html b/ThirdParty/Qwt/doc/html/class_qwt_plot_direct_painter.html new file mode 100644 index 0000000000..90b09d8e53 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_direct_painter.html @@ -0,0 +1,383 @@ + + + + + + +Qwt User's Guide: QwtPlotDirectPainter Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtPlotDirectPainter Class Reference
+
+
+ +

Painter object trying to paint incrementally. + More...

+ +

#include <qwt_plot_directpainter.h>

+
+Inheritance diagram for QwtPlotDirectPainter:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + +

+Public Types

enum  Attribute { AtomicPainter = 0x01, +FullRepaint = 0x02, +CopyBackingStore = 0x04 + }
 Paint attributes. More...
 
+typedef QFlags< AttributeAttributes
 Paint attributes.
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

QwtPlotDirectPainter (QObject *parent=NULL)
 Constructor.
 
+virtual ~QwtPlotDirectPainter ()
 Destructor.
 
void setAttribute (Attribute, bool on)
 
bool testAttribute (Attribute) const
 
void setClipping (bool)
 
bool hasClipping () const
 
void setClipRegion (const QRegion &)
 Assign a clip region and enable clipping. More...
 
QRegion clipRegion () const
 
void drawSeries (QwtPlotSeriesItem *, int from, int to)
 Draw a set of points of a seriesItem. More...
 
+void reset ()
 Close the internal QPainter.
 
+virtual bool eventFilter (QObject *, QEvent *)
 Event filter.
 
+

Detailed Description

+

Painter object trying to paint incrementally.

+

Often applications want to display samples while they are collected. When there are too many samples complete replots will be expensive to be processed in a collection cycle.

+

QwtPlotDirectPainter offers an API to paint subsets ( f.e all additions points ) without erasing/repainting the plot canvas.

+

On certain environments it might be important to calculate a proper clip region before painting. F.e. for Qt Embedded only the clipped part of the backing store will be copied to a ( maybe unaccelerated ) frame buffer.

+
Warning
Incremental painting will only help when no replot is triggered by another operation ( like changing scales ) and nothing needs to be erased.
+

Member Enumeration Documentation

+ +
+
+ +

Paint attributes.

+
See Also
setAttribute(), testAttribute(), drawSeries()
+ + + + +
Enumerator
AtomicPainter  +

Initializing a QPainter is an expensive operation. When AtomicPainter is set each call of drawSeries() opens/closes a temporary QPainter. Otherwise QwtPlotDirectPainter tries to use the same QPainter as long as possible.

+
FullRepaint  +

When FullRepaint is set the plot canvas is explicitly repainted after the samples have been rendered.

+
CopyBackingStore  +

When QwtPlotCanvas::BackingStore is enabled the painter has to paint to the backing store and the widget. In certain situations/environments it might be faster to paint to the backing store only and then copy the backing store to the canvas. This flag can also be useful for settings, where Qt fills the the clip region with the widget background.

+
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + + + +
QRegion QwtPlotDirectPainter::clipRegion () const
+
+
Returns
Currently set clip region.
+
See Also
setClipRegion(), setClipping(), hasClipping()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPlotDirectPainter::drawSeries (QwtPlotSeriesItemseriesItem,
int from,
int to 
)
+
+ +

Draw a set of points of a seriesItem.

+

When observing an measurement while it is running, new points have to be added to an existing seriesItem. drawSeries() can be used to display them avoiding a complete redraw of the canvas.

+

Setting plot()->canvas()->setAttribute(Qt::WA_PaintOutsidePaintEvent, true); will result in faster painting, if the paint engine of the canvas widget supports this feature.

+
Parameters
+ + + + +
seriesItemItem to be painted
fromIndex of the first point to be painted
toIndex of the last point to be painted. If to < 0 the series will be painted to its last point.
+
+
+ +
+
+ +
+
+ + + + + + + +
bool QwtPlotDirectPainter::hasClipping () const
+
+
Returns
true, when clipping is enabled
+
See Also
setClipping(), clipRegion(), setClipRegion()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtPlotDirectPainter::setAttribute (Attribute attribute,
bool on 
)
+
+

Change an attribute

+
Parameters
+ + + +
attributeAttribute to change
onOn/Off
+
+
+
See Also
Attribute, testAttribute()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotDirectPainter::setClipping (bool enable)
+
+

En/Disables clipping

+
Parameters
+ + +
enableEnables clipping is true, disable it otherwise
+
+
+
See Also
hasClipping(), clipRegion(), setClipRegion()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotDirectPainter::setClipRegion (const QRegion & region)
+
+ +

Assign a clip region and enable clipping.

+

Depending on the environment setting a proper clip region might improve the performance heavily. F.e. on Qt embedded only the clipped part of the backing store will be copied to a ( maybe unaccelerated ) frame buffer device.

+
Parameters
+ + +
regionClip region
+
+
+
See Also
clipRegion(), hasClipping(), setClipping()
+ +
+
+ +
+
+ + + + + + + + +
bool QwtPlotDirectPainter::testAttribute (Attribute attribute) const
+
+
Returns
True, when attribute is enabled
+
Parameters
+ + +
attributeAttribute to be tested
+
+
+
See Also
Attribute, setAttribute()
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_direct_painter__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_plot_direct_painter__inherit__graph.map new file mode 100644 index 0000000000..8ff2bcc600 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_direct_painter__inherit__graph.map @@ -0,0 +1,2 @@ + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_direct_painter__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_plot_direct_painter__inherit__graph.md5 new file mode 100644 index 0000000000..3b5e64949f --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_direct_painter__inherit__graph.md5 @@ -0,0 +1 @@ +c09abea6d8de23a768d3c2994cd0fe24 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_direct_painter__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_plot_direct_painter__inherit__graph.png new file mode 100644 index 0000000000..cfe2aa98b3 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_plot_direct_painter__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_g_l_canvas-members.html b/ThirdParty/Qwt/doc/html/class_qwt_plot_g_l_canvas-members.html new file mode 100644 index 0000000000..88c62abcd7 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_g_l_canvas-members.html @@ -0,0 +1,129 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtPlotGLCanvas Member List
+
+
+ +

This is the complete list of members for QwtPlotGLCanvas, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
borderPath(const QRect &) const QwtPlotGLCanvas
Box enum value (defined in QwtPlotGLCanvas)QwtPlotGLCanvas
drawBackground(QPainter *)QwtPlotGLCanvasprotectedvirtual
drawBorder(QPainter *)QwtPlotGLCanvasprotectedvirtual
drawItems(QPainter *)QwtPlotGLCanvasprotectedvirtual
event(QEvent *)QwtPlotGLCanvasvirtual
frameRect() const QwtPlotGLCanvas
frameShadow() const QwtPlotGLCanvas
frameShape() const QwtPlotGLCanvas
frameStyle() const QwtPlotGLCanvas
frameWidth() const QwtPlotGLCanvas
lineWidth() const QwtPlotGLCanvas
midLineWidth() const QwtPlotGLCanvas
NoFrame enum value (defined in QwtPlotGLCanvas)QwtPlotGLCanvas
paintEvent(QPaintEvent *)QwtPlotGLCanvasprotectedvirtual
Panel enum value (defined in QwtPlotGLCanvas)QwtPlotGLCanvas
Plain enum valueQwtPlotGLCanvas
QwtPlotGLCanvas(QwtPlot *=NULL)QwtPlotGLCanvasexplicit
Raised enum valueQwtPlotGLCanvas
replot()QwtPlotGLCanvasslot
setFrameShadow(Shadow)QwtPlotGLCanvas
setFrameShape(Shape)QwtPlotGLCanvas
setFrameStyle(int style)QwtPlotGLCanvas
setLineWidth(int)QwtPlotGLCanvas
setMidLineWidth(int)QwtPlotGLCanvas
Shadow enum nameQwtPlotGLCanvas
Shape enum nameQwtPlotGLCanvas
Sunken enum valueQwtPlotGLCanvas
~QwtPlotGLCanvas()QwtPlotGLCanvasvirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_g_l_canvas.html b/ThirdParty/Qwt/doc/html/class_qwt_plot_g_l_canvas.html new file mode 100644 index 0000000000..0040b8f928 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_g_l_canvas.html @@ -0,0 +1,687 @@ + + + + + + +Qwt User's Guide: QwtPlotGLCanvas Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+ +
+ +

An alternative canvas for a QwtPlot derived from QGLWidget. + More...

+ +

#include <qwt_plot_glcanvas.h>

+
+Inheritance diagram for QwtPlotGLCanvas:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + +

+Public Types

enum  Shadow { Plain = QFrame::Plain, +Raised = QFrame::Raised, +Sunken = QFrame::Sunken + }
 Frame shadow. More...
 
enum  Shape { NoFrame = QFrame::NoFrame, +Box = QFrame::Box, +Panel = QFrame::Panel + }
 Frame shape. More...
 
+ + + + +

+Public Slots

+void replot ()
 Calls repaint()
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 QwtPlotGLCanvas (QwtPlot *=NULL)
 Constructor. More...
 
+virtual ~QwtPlotGLCanvas ()
 Destructor.
 
void setFrameStyle (int style)
 
int frameStyle () const
 
void setFrameShadow (Shadow)
 
Shadow frameShadow () const
 
void setFrameShape (Shape)
 
Shape frameShape () const
 
void setLineWidth (int)
 
int lineWidth () const
 
void setMidLineWidth (int)
 
int midLineWidth () const
 
int frameWidth () const
 
QRect frameRect () const
 
Q_INVOKABLE QPainterPath borderPath (const QRect &) const
 
virtual bool event (QEvent *)
 
+ + + + + + + + + +

+Protected Member Functions

virtual void paintEvent (QPaintEvent *)
 
virtual void drawBackground (QPainter *)
 
virtual void drawBorder (QPainter *)
 
virtual void drawItems (QPainter *)
 
+

Detailed Description

+

An alternative canvas for a QwtPlot derived from QGLWidget.

+

QwtPlotGLCanvas implements the very basics to act as canvas inside of a QwtPlot widget. It might be extended to a full featured alternative to QwtPlotCanvas in a future version of Qwt.

+

Even if QwtPlotGLCanvas is not derived from QFrame it imitates its API. When using style sheets it supports the box model - beside backgrounds with rounded borders.

+
See Also
QwtPlot::setCanvas(), QwtPlotCanvas
+
Note
You might want to use the QPaintEngine::OpenGL paint engine ( see QGL::setPreferredPaintEngine() ). On a Linux test system QPaintEngine::OpenGL2 shows very basic problems ( wrong geometries of rectangles ) but also more advanced stuff like antialiasing doesn't work.
+
+Another way to introduce OpenGL rendering to Qwt is to use QGLPixelBuffer or QGLFramebufferObject. Both type of buffers can be converted into a QImage and used in combination with a regular QwtPlotCanvas.
+

Member Enumeration Documentation

+ +
+
+ + + + +
enum QwtPlotGLCanvas::Shadow
+
+ +

Frame shadow.

+

Unfortunately it is not possible to use QFrame::Shadow as a property of a widget that is not derived from QFrame. The following enum is made for the designer only. It is safe to use QFrame::Shadow instead.

+ + + + +
Enumerator
Plain  +

QFrame::Plain.

+
Raised  +

QFrame::Raised.

+
Sunken  +

QFrame::Sunken.

+
+ +
+
+ +
+
+ + + + +
enum QwtPlotGLCanvas::Shape
+
+ +

Frame shape.

+

Unfortunately it is not possible to use QFrame::Shape as a property of a widget that is not derived from QFrame. The following enum is made for the designer only. It is safe to use QFrame::Shadow instead.

+
Note
QFrame::StyledPanel and QFrame::WinPanel are unsuported and will be displayed as QFrame::Panel.
+ +
+
+

Constructor & Destructor Documentation

+ +
+
+ + + + + +
+ + + + + + + + +
QwtPlotGLCanvas::QwtPlotGLCanvas (QwtPlotplot = NULL)
+
+explicit
+
+ +

Constructor.

+
Parameters
+ + +
plotParent plot widget
+
+
+
See Also
QwtPlot::setCanvas()
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + + + + +
QPainterPath QwtPlotGLCanvas::borderPath (const QRect & rect) const
+
+
Returns
Empty path
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtPlotGLCanvas::drawBackground (QPainter * painter)
+
+protectedvirtual
+
+

Draw the background of the canvas

+
Parameters
+ + +
painterPainter
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtPlotGLCanvas::drawBorder (QPainter * painter)
+
+protectedvirtual
+
+

Draw the border of the canvas

+
Parameters
+ + +
painterPainter
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtPlotGLCanvas::drawItems (QPainter * painter)
+
+protectedvirtual
+
+

Draw the plot items

+
Parameters
+ + +
painterPainter
+
+
+
See Also
QwtPlot::drawCanvas()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool QwtPlotGLCanvas::event (QEvent * event)
+
+virtual
+
+

Qt event handler for QEvent::PolishRequest and QEvent::StyleChange

+
Parameters
+ + +
eventQt Event
+
+
+
Returns
See QGLWidget::event()
+ +
+
+ +
+
+ + + + + + + +
QRect QwtPlotGLCanvas::frameRect () const
+
+
Returns
The rectangle where the frame is drawn in.
+ +
+
+ +
+
+ + + + + + + +
QwtPlotGLCanvas::Shadow QwtPlotGLCanvas::frameShadow () const
+
+
Returns
Frame shadow
+
See Also
setFrameShadow(), QFrame::setFrameShadow()
+ +
+
+ +
+
+ + + + + + + +
QwtPlotGLCanvas::Shape QwtPlotGLCanvas::frameShape () const
+
+
Returns
Frame shape
+
See Also
setFrameShape(), QFrame::frameShape()
+ +
+
+ +
+
+ + + + + + + +
int QwtPlotGLCanvas::frameStyle () const
+
+
Returns
The bitwise OR between a frameShape() and a frameShadow()
+
See Also
setFrameStyle(), QFrame::frameStyle()
+ +
+
+ +
+
+ + + + + + + +
int QwtPlotGLCanvas::frameWidth () const
+
+
Returns
Frame width depending on the style, line width and midline width.
+ +
+
+ +
+
+ + + + + + + +
int QwtPlotGLCanvas::lineWidth () const
+
+
Returns
Line width of the frame
+
See Also
setLineWidth(), midLineWidth()
+ +
+
+ +
+
+ + + + + + + +
int QwtPlotGLCanvas::midLineWidth () const
+
+
Returns
Midline width of the frame
+
See Also
setMidLineWidth(), lineWidth()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtPlotGLCanvas::paintEvent (QPaintEvent * event)
+
+protectedvirtual
+
+

Paint event

+
Parameters
+ + +
eventPaint event
+
+
+
See Also
QwtPlot::drawCanvas()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotGLCanvas::setFrameShadow (Shadow shadow)
+
+

Set the frame shadow

+
Parameters
+ + +
shadowFrame shadow
+
+
+
See Also
frameShadow(), setFrameShape(), QFrame::setFrameShadow()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotGLCanvas::setFrameShape (Shape shape)
+
+

Set the frame shape

+
Parameters
+ + +
shapeFrame shape
+
+
+
See Also
frameShape(), setFrameShadow(), QFrame::frameShape()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotGLCanvas::setFrameStyle (int style)
+
+

Set the frame style

+
Parameters
+ + +
styleThe bitwise OR between a shape and a shadow.
+
+
+
See Also
frameStyle(), QFrame::setFrameStyle(), setFrameShadow(), setFrameShape()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotGLCanvas::setLineWidth (int width)
+
+

Set the frame line width

+

The default line width is 2 pixels.

+
Parameters
+ + +
widthLine width of the frame
+
+
+
See Also
lineWidth(), setMidLineWidth()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotGLCanvas::setMidLineWidth (int width)
+
+

Set the frame mid line width

+

The default midline width is 0 pixels.

+
Parameters
+ + +
widthMidline width of the frame
+
+
+
See Also
midLineWidth(), setLineWidth()
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_g_l_canvas__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_plot_g_l_canvas__inherit__graph.map new file mode 100644 index 0000000000..2b9a83bf81 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_g_l_canvas__inherit__graph.map @@ -0,0 +1,2 @@ + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_g_l_canvas__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_plot_g_l_canvas__inherit__graph.md5 new file mode 100644 index 0000000000..abb1fe8590 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_g_l_canvas__inherit__graph.md5 @@ -0,0 +1 @@ +fca0455183522e814e5ad933c7fc1319 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_g_l_canvas__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_plot_g_l_canvas__inherit__graph.png new file mode 100644 index 0000000000..6c3f427b91 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_plot_g_l_canvas__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_grid-members.html b/ThirdParty/Qwt/doc/html/class_qwt_plot_grid-members.html new file mode 100644 index 0000000000..52f3bcbf6e --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_grid-members.html @@ -0,0 +1,195 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtPlotGrid Member List
+
+
+ +

This is the complete list of members for QwtPlotGrid, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
attach(QwtPlot *plot)QwtPlotItem
AutoScale enum valueQwtPlotItem
boundingRect() const QwtPlotItemvirtual
defaultIcon(const QBrush &, const QSizeF &) const QwtPlotItemprotected
detach()QwtPlotItem
draw(QPainter *p, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &rect) const QwtPlotGridvirtual
enableX(bool tf)QwtPlotGrid
enableXMin(bool tf)QwtPlotGrid
enableY(bool tf)QwtPlotGrid
enableYMin(bool tf)QwtPlotGrid
getCanvasMarginHint(const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasSize, double &left, double &top, double &right, double &bottom) const QwtPlotItemvirtual
hide()QwtPlotItem
isVisible() const QwtPlotItem
ItemAttribute enum nameQwtPlotItem
ItemAttributes typedefQwtPlotItem
itemChanged()QwtPlotItemvirtual
ItemInterest enum nameQwtPlotItem
ItemInterests typedefQwtPlotItem
Legend enum valueQwtPlotItem
legendChanged()QwtPlotItemvirtual
legendData() const QwtPlotItemvirtual
legendIcon(int index, const QSizeF &) const QwtPlotItemvirtual
legendIconSize() const QwtPlotItem
LegendInterest enum valueQwtPlotItem
majorPen() const QwtPlotGrid
Margins enum valueQwtPlotItem
minorPen() const QwtPlotGrid
paintRect(const QwtScaleMap &, const QwtScaleMap &) const QwtPlotItem
plot() const QwtPlotItem
QwtPlotGrid()QwtPlotGridexplicit
QwtPlotItem(const QwtText &title=QwtText())QwtPlotItemexplicit
RenderAntialiased enum valueQwtPlotItem
RenderHint enum nameQwtPlotItem
RenderHints typedefQwtPlotItem
renderThreadCount() const QwtPlotItem
rtti() const QwtPlotGridvirtual
Rtti_PlotBarChart enum valueQwtPlotItem
Rtti_PlotCurve enum valueQwtPlotItem
Rtti_PlotGrid enum valueQwtPlotItem
Rtti_PlotHistogram enum valueQwtPlotItem
Rtti_PlotIntervalCurve enum valueQwtPlotItem
Rtti_PlotItem enum valueQwtPlotItem
Rtti_PlotLegend enum valueQwtPlotItem
Rtti_PlotMarker enum valueQwtPlotItem
Rtti_PlotMultiBarChart enum valueQwtPlotItem
Rtti_PlotScale enum valueQwtPlotItem
Rtti_PlotShape enum valueQwtPlotItem
Rtti_PlotSpectroCurve enum valueQwtPlotItem
Rtti_PlotSpectrogram enum valueQwtPlotItem
Rtti_PlotSVG enum valueQwtPlotItem
Rtti_PlotTextLabel enum valueQwtPlotItem
Rtti_PlotTradingCurve enum valueQwtPlotItem
Rtti_PlotUserItem enum valueQwtPlotItem
Rtti_PlotZone enum valueQwtPlotItem
RttiValues enum nameQwtPlotItem
ScaleInterest enum valueQwtPlotItem
scaleRect(const QwtScaleMap &, const QwtScaleMap &) const QwtPlotItem
setAxes(int xAxis, int yAxis)QwtPlotItem
setItemAttribute(ItemAttribute, bool on=true)QwtPlotItem
setItemInterest(ItemInterest, bool on=true)QwtPlotItem
setLegendIconSize(const QSize &)QwtPlotItem
setMajorPen(const QColor &, qreal width=0.0, Qt::PenStyle=Qt::SolidLine)QwtPlotGrid
setMajorPen(const QPen &)QwtPlotGrid
setMinorPen(const QColor &, qreal width=0.0, Qt::PenStyle=Qt::SolidLine)QwtPlotGrid
setMinorPen(const QPen &p)QwtPlotGrid
setPen(const QColor &, qreal width=0.0, Qt::PenStyle=Qt::SolidLine)QwtPlotGrid
setPen(const QPen &)QwtPlotGrid
setRenderHint(RenderHint, bool on=true)QwtPlotItem
setRenderThreadCount(uint numThreads)QwtPlotItem
setTitle(const QString &title)QwtPlotItem
setTitle(const QwtText &title)QwtPlotItem
setVisible(bool)QwtPlotItemvirtual
setXAxis(int axis)QwtPlotItem
setXDiv(const QwtScaleDiv &sx)QwtPlotGrid
setYAxis(int axis)QwtPlotItem
setYDiv(const QwtScaleDiv &sy)QwtPlotGrid
setZ(double z)QwtPlotItem
show()QwtPlotItem
testItemAttribute(ItemAttribute) const QwtPlotItem
testItemInterest(ItemInterest) const QwtPlotItem
testRenderHint(RenderHint) const QwtPlotItem
title() const QwtPlotItem
updateLegend(const QwtPlotItem *, const QList< QwtLegendData > &)QwtPlotItemvirtual
updateScaleDiv(const QwtScaleDiv &xMap, const QwtScaleDiv &yMap)QwtPlotGridvirtual
xAxis() const QwtPlotItem
xEnabled() const QwtPlotGrid
xMinEnabled() const QwtPlotGrid
xScaleDiv() const QwtPlotGrid
yAxis() const QwtPlotItem
yEnabled() const QwtPlotGrid
yMinEnabled() const QwtPlotGrid
yScaleDiv() const QwtPlotGrid
z() const QwtPlotItem
~QwtPlotGrid()QwtPlotGridvirtual
~QwtPlotItem()QwtPlotItemvirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_grid.html b/ThirdParty/Qwt/doc/html/class_qwt_plot_grid.html new file mode 100644 index 0000000000..644e3cca07 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_grid.html @@ -0,0 +1,950 @@ + + + + + + +Qwt User's Guide: QwtPlotGrid Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtPlotGrid Class Reference
+
+
+ +

A class which draws a coordinate grid. + More...

+ +

#include <qwt_plot_grid.h>

+
+Inheritance diagram for QwtPlotGrid:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

QwtPlotGrid ()
 Enables major grid, disables minor grid.
 
+virtual ~QwtPlotGrid ()
 Destructor.
 
virtual int rtti () const
 
void enableX (bool tf)
 Enable or disable vertical grid lines. More...
 
bool xEnabled () const
 
void enableY (bool tf)
 Enable or disable horizontal grid lines. More...
 
bool yEnabled () const
 
void enableXMin (bool tf)
 Enable or disable minor vertical grid lines. More...
 
bool xMinEnabled () const
 
void enableYMin (bool tf)
 Enable or disable minor horizontal grid lines. More...
 
bool yMinEnabled () const
 
void setXDiv (const QwtScaleDiv &sx)
 
const QwtScaleDivxScaleDiv () const
 
void setYDiv (const QwtScaleDiv &sy)
 
const QwtScaleDivyScaleDiv () const
 
void setPen (const QColor &, qreal width=0.0, Qt::PenStyle=Qt::SolidLine)
 
void setPen (const QPen &)
 
void setMajorPen (const QColor &, qreal width=0.0, Qt::PenStyle=Qt::SolidLine)
 
void setMajorPen (const QPen &)
 
const QPen & majorPen () const
 
void setMinorPen (const QColor &, qreal width=0.0, Qt::PenStyle=Qt::SolidLine)
 
void setMinorPen (const QPen &p)
 
const QPen & minorPen () const
 
virtual void draw (QPainter *p, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &rect) const
 Draw the grid. More...
 
virtual void updateScaleDiv (const QwtScaleDiv &xMap, const QwtScaleDiv &yMap)
 
- Public Member Functions inherited from QwtPlotItem
 QwtPlotItem (const QwtText &title=QwtText())
 
+virtual ~QwtPlotItem ()
 Destroy the QwtPlotItem.
 
void attach (QwtPlot *plot)
 Attach the item to a plot. More...
 
void detach ()
 This method detaches a QwtPlotItem from any QwtPlot it has been associated with. More...
 
+QwtPlotplot () const
 Return attached plot.
 
void setTitle (const QString &title)
 
void setTitle (const QwtText &title)
 
const QwtTexttitle () const
 
void setItemAttribute (ItemAttribute, bool on=true)
 
bool testItemAttribute (ItemAttribute) const
 
void setItemInterest (ItemInterest, bool on=true)
 
bool testItemInterest (ItemInterest) const
 
void setRenderHint (RenderHint, bool on=true)
 
bool testRenderHint (RenderHint) const
 
void setRenderThreadCount (uint numThreads)
 
uint renderThreadCount () const
 
void setLegendIconSize (const QSize &)
 
QSize legendIconSize () const
 
double z () const
 
void setZ (double z)
 Set the z value. More...
 
+void show ()
 Show the item.
 
+void hide ()
 Hide the item.
 
virtual void setVisible (bool)
 
bool isVisible () const
 
void setAxes (int xAxis, int yAxis)
 
void setXAxis (int axis)
 
+int xAxis () const
 Return xAxis.
 
void setYAxis (int axis)
 
+int yAxis () const
 Return yAxis.
 
virtual void itemChanged ()
 
virtual void legendChanged ()
 
virtual QRectF boundingRect () const
 
virtual void getCanvasMarginHint (const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasSize, double &left, double &top, double &right, double &bottom) const
 Calculate a hint for the canvas margin. More...
 
virtual void updateLegend (const QwtPlotItem *, const QList< QwtLegendData > &)
 Update the item to changes of the legend info. More...
 
QRectF scaleRect (const QwtScaleMap &, const QwtScaleMap &) const
 Calculate the bounding scale rectangle of 2 maps. More...
 
QRectF paintRect (const QwtScaleMap &, const QwtScaleMap &) const
 Calculate the bounding paint rectangle of 2 maps. More...
 
virtual QList< QwtLegendDatalegendData () const
 Return all information, that is needed to represent the item on the legend. More...
 
virtual QwtGraphic legendIcon (int index, const QSizeF &) const
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Additional Inherited Members

- Public Types inherited from QwtPlotItem
enum  RttiValues {
+  Rtti_PlotItem = 0, +Rtti_PlotGrid, +Rtti_PlotScale, +Rtti_PlotLegend, +
+  Rtti_PlotMarker, +Rtti_PlotCurve, +Rtti_PlotSpectroCurve, +Rtti_PlotIntervalCurve, +
+  Rtti_PlotHistogram, +Rtti_PlotSpectrogram, +Rtti_PlotSVG, +Rtti_PlotTradingCurve, +
+  Rtti_PlotBarChart, +Rtti_PlotMultiBarChart, +Rtti_PlotShape, +Rtti_PlotTextLabel, +
+  Rtti_PlotZone, +Rtti_PlotUserItem = 1000 +
+ }
 Runtime type information. More...
 
enum  ItemAttribute { Legend = 0x01, +AutoScale = 0x02, +Margins = 0x04 + }
 Plot Item Attributes. More...
 
enum  ItemInterest { ScaleInterest = 0x01, +LegendInterest = 0x02 + }
 Plot Item Interests. More...
 
enum  RenderHint { RenderAntialiased = 0x1 + }
 Render hints. More...
 
+typedef QFlags< ItemAttributeItemAttributes
 Plot Item Attributes.
 
+typedef QFlags< ItemInterestItemInterests
 Plot Item Interests.
 
+typedef QFlags< RenderHintRenderHints
 Render hints.
 
- Protected Member Functions inherited from QwtPlotItem
QwtGraphic defaultIcon (const QBrush &, const QSizeF &) const
 Return a default icon from a brush. More...
 
+

Detailed Description

+

A class which draws a coordinate grid.

+

The QwtPlotGrid class can be used to draw a coordinate grid. A coordinate grid consists of major and minor vertical and horizontal grid lines. The locations of the grid lines are determined by the X and Y scale divisions which can be assigned with setXDiv() and setYDiv(). The draw() member draws the grid within a bounding rectangle.

+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPlotGrid::draw (QPainter * painter,
const QwtScaleMapxMap,
const QwtScaleMapyMap,
const QRectF & canvasRect 
) const
+
+virtual
+
+ +

Draw the grid.

+

The grid is drawn into the bounding rectangle such that grid lines begin and end at the rectangle's borders. The X and Y maps are used to map the scale divisions into the drawing region screen.

+
Parameters
+ + + + + +
painterPainter
xMapX axis map
yMapY axis
canvasRectContents rectangle of the plot canvas
+
+
+ +

Implements QwtPlotItem.

+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotGrid::enableX (bool on)
+
+ +

Enable or disable vertical grid lines.

+
Parameters
+ + +
onEnable (true) or disable
+
+
+
See Also
Minor grid lines can be enabled or disabled with enableXMin()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotGrid::enableXMin (bool on)
+
+ +

Enable or disable minor vertical grid lines.

+
Parameters
+ + +
onEnable (true) or disable
+
+
+
See Also
enableX()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotGrid::enableY (bool on)
+
+ +

Enable or disable horizontal grid lines.

+
Parameters
+ + +
onEnable (true) or disable
+
+
+
See Also
Minor grid lines can be enabled or disabled with enableYMin()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotGrid::enableYMin (bool on)
+
+ +

Enable or disable minor horizontal grid lines.

+
Parameters
+ + +
onEnable (true) or disable
+
+
+
See Also
enableY()
+ +
+
+ +
+
+ + + + + + + +
const QPen & QwtPlotGrid::majorPen () const
+
+
Returns
the pen for the major grid lines
+
See Also
setMajorPen(), setMinorPen(), setPen()
+ +
+
+ +
+
+ + + + + + + +
const QPen & QwtPlotGrid::minorPen () const
+
+
Returns
the pen for the minor grid lines
+
See Also
setMinorPen(), setMajorPen(), setPen()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
int QwtPlotGrid::rtti () const
+
+virtual
+
+
Returns
QwtPlotItem::Rtti_PlotGrid
+ +

Reimplemented from QwtPlotItem.

+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPlotGrid::setMajorPen (const QColor & color,
qreal width = 0.0,
Qt::PenStyle style = Qt::SolidLine 
)
+
+

Build and assign a pen for both major grid lines

+

In Qt5 the default pen width is 1.0 ( 0.0 in Qt4 ) what makes it non cosmetic ( see QPen::isCosmetic() ). This method has been introduced to hide this incompatibility.

+
Parameters
+ + + + +
colorPen color
widthPen width
stylePen style
+
+
+
See Also
pen(), brush()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotGrid::setMajorPen (const QPen & pen)
+
+

Assign a pen for the major grid lines

+
Parameters
+ + +
penPen
+
+
+
See Also
majorPen(), setMinorPen(), setPen()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPlotGrid::setMinorPen (const QColor & color,
qreal width = 0.0,
Qt::PenStyle style = Qt::SolidLine 
)
+
+

Build and assign a pen for the minor grid lines

+

In Qt5 the default pen width is 1.0 ( 0.0 in Qt4 ) what makes it non cosmetic ( see QPen::isCosmetic() ). This method has been introduced to hide this incompatibility.

+
Parameters
+ + + + +
colorPen color
widthPen width
stylePen style
+
+
+
See Also
pen(), brush()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotGrid::setMinorPen (const QPen & pen)
+
+

Assign a pen for the minor grid lines

+
Parameters
+ + +
penPen
+
+
+
See Also
minorPen(), setMajorPen(), setPen()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPlotGrid::setPen (const QColor & color,
qreal width = 0.0,
Qt::PenStyle style = Qt::SolidLine 
)
+
+

Build and assign a pen for both major and minor grid lines

+

In Qt5 the default pen width is 1.0 ( 0.0 in Qt4 ) what makes it non cosmetic ( see QPen::isCosmetic() ). This method has been introduced to hide this incompatibility.

+
Parameters
+ + + + +
colorPen color
widthPen width
stylePen style
+
+
+
See Also
pen(), brush()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotGrid::setPen (const QPen & pen)
+
+

Assign a pen for both major and minor grid lines

+
Parameters
+ + +
penPen
+
+
+
See Also
setMajorPen(), setMinorPen()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotGrid::setXDiv (const QwtScaleDivscaleDiv)
+
+

Assign an x axis scale division

+
Parameters
+ + +
scaleDivScale division
+
+
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotGrid::setYDiv (const QwtScaleDivscaleDiv)
+
+

Assign a y axis division

+
Parameters
+ + +
scaleDivScale division
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void QwtPlotGrid::updateScaleDiv (const QwtScaleDivxScaleDiv,
const QwtScaleDivyScaleDiv 
)
+
+virtual
+
+

Update the grid to changes of the axes scale division

+
Parameters
+ + + +
xScaleDivScale division of the x-axis
yScaleDivScale division of the y-axis
+
+
+
See Also
QwtPlot::updateAxes()
+ +

Reimplemented from QwtPlotItem.

+ +
+
+ +
+
+ + + + + + + +
bool QwtPlotGrid::xEnabled () const
+
+
Returns
true if vertical grid lines are enabled
+
See Also
enableX()
+ +
+
+ +
+
+ + + + + + + +
bool QwtPlotGrid::xMinEnabled () const
+
+
Returns
true if minor vertical grid lines are enabled
+
See Also
enableXMin()
+ +
+
+ +
+
+ + + + + + + +
const QwtScaleDiv & QwtPlotGrid::xScaleDiv () const
+
+
Returns
the scale division of the x axis
+ +
+
+ +
+
+ + + + + + + +
bool QwtPlotGrid::yEnabled () const
+
+
Returns
true if horizontal grid lines are enabled
+
See Also
enableY()
+ +
+
+ +
+
+ + + + + + + +
bool QwtPlotGrid::yMinEnabled () const
+
+
Returns
true if minor horizontal grid lines are enabled
+
See Also
enableYMin()
+ +
+
+ +
+
+ + + + + + + +
const QwtScaleDiv & QwtPlotGrid::yScaleDiv () const
+
+
Returns
the scale division of the y axis
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_grid__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_plot_grid__inherit__graph.map new file mode 100644 index 0000000000..1104c29017 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_grid__inherit__graph.map @@ -0,0 +1,3 @@ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_grid__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_plot_grid__inherit__graph.md5 new file mode 100644 index 0000000000..2334663f9e --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_grid__inherit__graph.md5 @@ -0,0 +1 @@ +791f167e81a6e82931faa1a00f3a0138 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_grid__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_plot_grid__inherit__graph.png new file mode 100644 index 0000000000..06b4fa604d Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_plot_grid__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_histogram-members.html b/ThirdParty/Qwt/doc/html/class_qwt_plot_histogram-members.html new file mode 100644 index 0000000000..466a01b638 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_histogram-members.html @@ -0,0 +1,220 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtPlotHistogram Member List
+
+
+ +

This is the complete list of members for QwtPlotHistogram, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
attach(QwtPlot *plot)QwtPlotItem
AutoScale enum valueQwtPlotItem
baseline() const QwtPlotHistogram
boundingRect() const QwtPlotHistogramvirtual
brush() const QwtPlotHistogram
columnRect(const QwtIntervalSample &, const QwtScaleMap &, const QwtScaleMap &) const QwtPlotHistogramprotectedvirtual
Columns enum valueQwtPlotHistogram
data()QwtSeriesStore< QwtIntervalSample >
data() constQwtSeriesStore< QwtIntervalSample >
dataChanged()QwtPlotSeriesItemprotectedvirtual
QwtPlotSeriesItem::dataRect() const =0QwtAbstractSeriesStoreprotectedpure virtual
QwtSeriesStore< QwtIntervalSample >::dataRect() constQwtSeriesStore< QwtIntervalSample >virtual
QwtPlotSeriesItem::dataSize() const =0QwtAbstractSeriesStoreprotectedpure virtual
QwtSeriesStore< QwtIntervalSample >::dataSize() constQwtSeriesStore< QwtIntervalSample >virtual
defaultIcon(const QBrush &, const QSizeF &) const QwtPlotItemprotected
detach()QwtPlotItem
draw(QPainter *p, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &) const QwtPlotSeriesItemvirtual
drawColumn(QPainter *, const QwtColumnRect &, const QwtIntervalSample &) const QwtPlotHistogramprotectedvirtual
drawColumns(QPainter *, const QwtScaleMap &xMap, const QwtScaleMap &yMap, int from, int to) const QwtPlotHistogramprotected
drawLines(QPainter *, const QwtScaleMap &xMap, const QwtScaleMap &yMap, int from, int to) const QwtPlotHistogramprotected
drawOutline(QPainter *, const QwtScaleMap &xMap, const QwtScaleMap &yMap, int from, int to) const QwtPlotHistogramprotected
drawSeries(QPainter *p, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, int from, int to) const QwtPlotHistogramvirtual
getCanvasMarginHint(const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasSize, double &left, double &top, double &right, double &bottom) const QwtPlotItemvirtual
hide()QwtPlotItem
HistogramStyle enum nameQwtPlotHistogram
isVisible() const QwtPlotItem
ItemAttribute enum nameQwtPlotItem
ItemAttributes typedefQwtPlotItem
itemChanged()QwtPlotItemvirtual
ItemInterest enum nameQwtPlotItem
ItemInterests typedefQwtPlotItem
Legend enum valueQwtPlotItem
legendChanged()QwtPlotItemvirtual
legendData() const QwtPlotItemvirtual
legendIcon(int index, const QSizeF &) const QwtPlotHistogramvirtual
legendIconSize() const QwtPlotItem
LegendInterest enum valueQwtPlotItem
Lines enum valueQwtPlotHistogram
Margins enum valueQwtPlotItem
orientation() const QwtPlotSeriesItem
Outline enum valueQwtPlotHistogram
paintRect(const QwtScaleMap &, const QwtScaleMap &) const QwtPlotItem
pen() const QwtPlotHistogram
plot() const QwtPlotItem
QwtPlotHistogram(const QString &title=QString::null)QwtPlotHistogramexplicit
QwtPlotHistogram(const QwtText &title)QwtPlotHistogramexplicit
QwtPlotItem(const QwtText &title=QwtText())QwtPlotItemexplicit
QwtPlotSeriesItem(const QString &title=QString::null)QwtPlotSeriesItemexplicit
QwtPlotSeriesItem(const QwtText &title)QwtPlotSeriesItemexplicit
QwtSeriesStore()QwtSeriesStore< QwtIntervalSample >explicit
RenderAntialiased enum valueQwtPlotItem
RenderHint enum nameQwtPlotItem
RenderHints typedefQwtPlotItem
renderThreadCount() const QwtPlotItem
rtti() const QwtPlotHistogramvirtual
Rtti_PlotBarChart enum valueQwtPlotItem
Rtti_PlotCurve enum valueQwtPlotItem
Rtti_PlotGrid enum valueQwtPlotItem
Rtti_PlotHistogram enum valueQwtPlotItem
Rtti_PlotIntervalCurve enum valueQwtPlotItem
Rtti_PlotItem enum valueQwtPlotItem
Rtti_PlotLegend enum valueQwtPlotItem
Rtti_PlotMarker enum valueQwtPlotItem
Rtti_PlotMultiBarChart enum valueQwtPlotItem
Rtti_PlotScale enum valueQwtPlotItem
Rtti_PlotShape enum valueQwtPlotItem
Rtti_PlotSpectroCurve enum valueQwtPlotItem
Rtti_PlotSpectrogram enum valueQwtPlotItem
Rtti_PlotSVG enum valueQwtPlotItem
Rtti_PlotTextLabel enum valueQwtPlotItem
Rtti_PlotTradingCurve enum valueQwtPlotItem
Rtti_PlotUserItem enum valueQwtPlotItem
Rtti_PlotZone enum valueQwtPlotItem
RttiValues enum nameQwtPlotItem
sample(int index) constQwtSeriesStore< QwtIntervalSample >
ScaleInterest enum valueQwtPlotItem
scaleRect(const QwtScaleMap &, const QwtScaleMap &) const QwtPlotItem
setAxes(int xAxis, int yAxis)QwtPlotItem
setBaseline(double reference)QwtPlotHistogram
setBrush(const QBrush &)QwtPlotHistogram
setData(QwtSeriesData< QwtIntervalSample > *series)QwtSeriesStore< QwtIntervalSample >
setItemAttribute(ItemAttribute, bool on=true)QwtPlotItem
setItemInterest(ItemInterest, bool on=true)QwtPlotItem
setLegendIconSize(const QSize &)QwtPlotItem
setOrientation(Qt::Orientation)QwtPlotSeriesItem
setPen(const QColor &, qreal width=0.0, Qt::PenStyle=Qt::SolidLine)QwtPlotHistogram
setPen(const QPen &)QwtPlotHistogram
QwtPlotSeriesItem::setRectOfInterest(const QRectF &)=0QwtAbstractSeriesStoreprotectedpure virtual
QwtSeriesStore< QwtIntervalSample >::setRectOfInterest(const QRectF &rect)QwtSeriesStore< QwtIntervalSample >virtual
setRenderHint(RenderHint, bool on=true)QwtPlotItem
setRenderThreadCount(uint numThreads)QwtPlotItem
setSamples(const QVector< QwtIntervalSample > &)QwtPlotHistogram
setSamples(QwtSeriesData< QwtIntervalSample > *)QwtPlotHistogram
setStyle(HistogramStyle style)QwtPlotHistogram
setSymbol(const QwtColumnSymbol *)QwtPlotHistogram
setTitle(const QString &title)QwtPlotItem
setTitle(const QwtText &title)QwtPlotItem
setVisible(bool)QwtPlotItemvirtual
setXAxis(int axis)QwtPlotItem
setYAxis(int axis)QwtPlotItem
setZ(double z)QwtPlotItem
show()QwtPlotItem
style() const QwtPlotHistogram
swapData(QwtSeriesData< QwtIntervalSample > *series)QwtSeriesStore< QwtIntervalSample >
symbol() const QwtPlotHistogram
testItemAttribute(ItemAttribute) const QwtPlotItem
testItemInterest(ItemInterest) const QwtPlotItem
testRenderHint(RenderHint) const QwtPlotItem
title() const QwtPlotItem
updateLegend(const QwtPlotItem *, const QList< QwtLegendData > &)QwtPlotItemvirtual
updateScaleDiv(const QwtScaleDiv &, const QwtScaleDiv &)QwtPlotSeriesItemvirtual
UserStyle enum valueQwtPlotHistogram
xAxis() const QwtPlotItem
yAxis() const QwtPlotItem
z() const QwtPlotItem
~QwtAbstractSeriesStore()QwtAbstractSeriesStoreinlineprotectedvirtual
~QwtPlotHistogram()QwtPlotHistogramvirtual
~QwtPlotItem()QwtPlotItemvirtual
~QwtPlotSeriesItem()QwtPlotSeriesItemvirtual
~QwtSeriesStore()QwtSeriesStore< QwtIntervalSample >
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_histogram.html b/ThirdParty/Qwt/doc/html/class_qwt_plot_histogram.html new file mode 100644 index 0000000000..8053a647ec --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_histogram.html @@ -0,0 +1,1197 @@ + + + + + + +Qwt User's Guide: QwtPlotHistogram Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtPlotHistogram Class Reference
+
+
+ +

QwtPlotHistogram represents a series of samples, where an interval is associated with a value ( $y = f([x1,x2])$ ). + More...

+ +

#include <qwt_plot_histogram.h>

+
+Inheritance diagram for QwtPlotHistogram:
+
+
Inheritance graph
+ + +
[legend]
+ + + + +

+Public Types

enum  HistogramStyle { Outline, +Columns, +Lines, +UserStyle = 100 + }
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 QwtPlotHistogram (const QString &title=QString::null)
 
 QwtPlotHistogram (const QwtText &title)
 
+virtual ~QwtPlotHistogram ()
 Destructor.
 
virtual int rtti () const
 
void setPen (const QColor &, qreal width=0.0, Qt::PenStyle=Qt::SolidLine)
 
void setPen (const QPen &)
 
const QPen & pen () const
 
void setBrush (const QBrush &)
 
const QBrush & brush () const
 
void setSamples (const QVector< QwtIntervalSample > &)
 
void setSamples (QwtSeriesData< QwtIntervalSample > *)
 
void setBaseline (double reference)
 Set the value of the baseline. More...
 
double baseline () const
 
void setStyle (HistogramStyle style)
 
HistogramStyle style () const
 
void setSymbol (const QwtColumnSymbol *)
 Assign a symbol. More...
 
const QwtColumnSymbolsymbol () const
 
virtual void drawSeries (QPainter *p, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, int from, int to) const
 
virtual QRectF boundingRect () const
 
virtual QwtGraphic legendIcon (int index, const QSizeF &) const
 
- Public Member Functions inherited from QwtPlotSeriesItem
 QwtPlotSeriesItem (const QString &title=QString::null)
 
 QwtPlotSeriesItem (const QwtText &title)
 
+virtual ~QwtPlotSeriesItem ()
 Destructor.
 
void setOrientation (Qt::Orientation)
 
Qt::Orientation orientation () const
 
virtual void draw (QPainter *p, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &) const
 Draw the complete series. More...
 
virtual void updateScaleDiv (const QwtScaleDiv &, const QwtScaleDiv &)
 Update the item to changes of the axes scale division. More...
 
- Public Member Functions inherited from QwtPlotItem
 QwtPlotItem (const QwtText &title=QwtText())
 
+virtual ~QwtPlotItem ()
 Destroy the QwtPlotItem.
 
void attach (QwtPlot *plot)
 Attach the item to a plot. More...
 
void detach ()
 This method detaches a QwtPlotItem from any QwtPlot it has been associated with. More...
 
+QwtPlotplot () const
 Return attached plot.
 
void setTitle (const QString &title)
 
void setTitle (const QwtText &title)
 
const QwtTexttitle () const
 
void setItemAttribute (ItemAttribute, bool on=true)
 
bool testItemAttribute (ItemAttribute) const
 
void setItemInterest (ItemInterest, bool on=true)
 
bool testItemInterest (ItemInterest) const
 
void setRenderHint (RenderHint, bool on=true)
 
bool testRenderHint (RenderHint) const
 
void setRenderThreadCount (uint numThreads)
 
uint renderThreadCount () const
 
void setLegendIconSize (const QSize &)
 
QSize legendIconSize () const
 
double z () const
 
void setZ (double z)
 Set the z value. More...
 
+void show ()
 Show the item.
 
+void hide ()
 Hide the item.
 
virtual void setVisible (bool)
 
bool isVisible () const
 
void setAxes (int xAxis, int yAxis)
 
void setXAxis (int axis)
 
+int xAxis () const
 Return xAxis.
 
void setYAxis (int axis)
 
+int yAxis () const
 Return yAxis.
 
virtual void itemChanged ()
 
virtual void legendChanged ()
 
virtual void getCanvasMarginHint (const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasSize, double &left, double &top, double &right, double &bottom) const
 Calculate a hint for the canvas margin. More...
 
virtual void updateLegend (const QwtPlotItem *, const QList< QwtLegendData > &)
 Update the item to changes of the legend info. More...
 
QRectF scaleRect (const QwtScaleMap &, const QwtScaleMap &) const
 Calculate the bounding scale rectangle of 2 maps. More...
 
QRectF paintRect (const QwtScaleMap &, const QwtScaleMap &) const
 Calculate the bounding paint rectangle of 2 maps. More...
 
virtual QList< QwtLegendDatalegendData () const
 Return all information, that is needed to represent the item on the legend. More...
 
- Public Member Functions inherited from QwtSeriesStore< QwtIntervalSample >
QwtSeriesStore ()
 Constructor The store contains no series.
 
~QwtSeriesStore ()
 Destructor.
 
void setData (QwtSeriesData< QwtIntervalSample > *series)
 
QwtSeriesData
+< QwtIntervalSample > * 
data ()
 
const QwtSeriesData
+< QwtIntervalSample > * 
data () const
 
QwtIntervalSample sample (int index) const
 
virtual size_t dataSize () const
 
virtual QRectF dataRect () const
 
virtual void setRectOfInterest (const QRectF &rect)
 
QwtSeriesData
+< QwtIntervalSample > * 
swapData (QwtSeriesData< QwtIntervalSample > *series)
 
+ + + + + + + + + + + + + + + + + + + + + + + +

+Protected Member Functions

virtual QwtColumnRect columnRect (const QwtIntervalSample &, const QwtScaleMap &, const QwtScaleMap &) const
 
virtual void drawColumn (QPainter *, const QwtColumnRect &, const QwtIntervalSample &) const
 
void drawColumns (QPainter *, const QwtScaleMap &xMap, const QwtScaleMap &yMap, int from, int to) const
 
void drawOutline (QPainter *, const QwtScaleMap &xMap, const QwtScaleMap &yMap, int from, int to) const
 
void drawLines (QPainter *, const QwtScaleMap &xMap, const QwtScaleMap &yMap, int from, int to) const
 
- Protected Member Functions inherited from QwtPlotSeriesItem
+virtual void dataChanged ()
 dataChanged() indicates, that the series has been changed.
 
- Protected Member Functions inherited from QwtPlotItem
QwtGraphic defaultIcon (const QBrush &, const QSizeF &) const
 Return a default icon from a brush. More...
 
- Protected Member Functions inherited from QwtAbstractSeriesStore
+virtual ~QwtAbstractSeriesStore ()
 Destructor.
 
+

Detailed Description

+

QwtPlotHistogram represents a series of samples, where an interval is associated with a value ( $y = f([x1,x2])$ ).

+

The representation depends on the style() and an optional symbol() that is displayed for each interval.

+
Note
The term "histogram" is used in a different way in the areas of digital image processing and statistics. Wikipedia introduces the terms "image histogram" and "color histogram" to avoid confusions. While "image histograms" can be displayed by a QwtPlotCurve there is no applicable plot item for a "color histogram" yet.
+
See Also
QwtPlotBarChart, QwtPlotMultiBarChart
+

Member Enumeration Documentation

+ +
+
+

Histogram styles. The default style is QwtPlotHistogram::Columns.

+
See Also
setStyle(), style(), setSymbol(), symbol(), setBaseline()
+ + + + + +
Enumerator
Outline  +

Draw an outline around the area, that is build by all intervals using the pen() and fill it with the brush(). The outline style requires, that the intervals are in increasing order and not overlapping.

+
Columns  +

Draw a column for each interval. When a symbol() has been set the symbol is used otherwise the column is displayed as plain rectangle using pen() and brush().

+
Lines  +

Draw a simple line using the pen() for each interval.

+
UserStyle  +

Styles >= UserStyle are reserved for derived classes that overload drawSeries() with additional application specific ways to display a histogram.

+
+ +
+
+

Constructor & Destructor Documentation

+ +
+
+ + + + + +
+ + + + + + + + +
QwtPlotHistogram::QwtPlotHistogram (const QString & title = QString::null)
+
+explicit
+
+

Constructor

+
Parameters
+ + +
titleTitle of the histogram.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
QwtPlotHistogram::QwtPlotHistogram (const QwtTexttitle)
+
+explicit
+
+

Constructor

+
Parameters
+ + +
titleTitle of the histogram.
+
+
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + + + +
double QwtPlotHistogram::baseline () const
+
+
Returns
Value of the baseline
+
See Also
setBaseline()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
QRectF QwtPlotHistogram::boundingRect () const
+
+virtual
+
+
Returns
Bounding rectangle of all samples. For an empty series the rectangle is invalid.
+ +

Reimplemented from QwtPlotSeriesItem.

+ +
+
+ +
+
+ + + + + + + +
const QBrush & QwtPlotHistogram::brush () const
+
+
Returns
Brush used in a style() depending way.
+
See Also
setPen(), brush()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
QwtColumnRect QwtPlotHistogram::columnRect (const QwtIntervalSamplesample,
const QwtScaleMapxMap,
const QwtScaleMapyMap 
) const
+
+protectedvirtual
+
+

Calculate the area that is covered by a sample

+
Parameters
+ + + + +
sampleSample
xMapMaps x-values into pixel coordinates.
yMapMaps y-values into pixel coordinates.
+
+
+
Returns
Rectangle, that is covered by a sample
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPlotHistogram::drawColumn (QPainter * painter,
const QwtColumnRectrect,
const QwtIntervalSamplesample 
) const
+
+protectedvirtual
+
+

Draw a column for a sample in Columns style().

+

When a symbol() has been set the symbol is used otherwise the column is displayed as plain rectangle using pen() and brush().

+
Parameters
+ + + + +
painterPainter
rectRectangle where to paint the column in paint device coordinates
sampleSample to be displayed
+
+
+
Note
In applications, where different intervals need to be displayed in a different way ( f.e different colors or even using different symbols) it is recommended to overload drawColumn().
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPlotHistogram::drawColumns (QPainter * painter,
const QwtScaleMapxMap,
const QwtScaleMapyMap,
int from,
int to 
) const
+
+protected
+
+

Draw a histogram in Columns style()

+
Parameters
+ + + + + + +
painterPainter
xMapMaps x-values into pixel coordinates.
yMapMaps y-values into pixel coordinates.
fromIndex of the first sample to be painted
toIndex of the last sample to be painted. If to < 0 the histogram will be painted to its last point.
+
+
+
See Also
setStyle(), style(), setSymbol(), drawColumn()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPlotHistogram::drawLines (QPainter * painter,
const QwtScaleMapxMap,
const QwtScaleMapyMap,
int from,
int to 
) const
+
+protected
+
+

Draw a histogram in Lines style()

+
Parameters
+ + + + + + +
painterPainter
xMapMaps x-values into pixel coordinates.
yMapMaps y-values into pixel coordinates.
fromIndex of the first sample to be painted
toIndex of the last sample to be painted. If to < 0 the histogram will be painted to its last point.
+
+
+
See Also
setStyle(), style(), setPen()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPlotHistogram::drawOutline (QPainter * painter,
const QwtScaleMapxMap,
const QwtScaleMapyMap,
int from,
int to 
) const
+
+protected
+
+

Draw a histogram in Outline style()

+
Parameters
+ + + + + + +
painterPainter
xMapMaps x-values into pixel coordinates.
yMapMaps y-values into pixel coordinates.
fromIndex of the first sample to be painted
toIndex of the last sample to be painted. If to < 0 the histogram will be painted to its last point.
+
+
+
See Also
setStyle(), style()
+
Warning
The outline style requires, that the intervals are in increasing order and not overlapping.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPlotHistogram::drawSeries (QPainter * painter,
const QwtScaleMapxMap,
const QwtScaleMapyMap,
const QRectF & canvasRect,
int from,
int to 
) const
+
+virtual
+
+

Draw a subset of the histogram samples

+
Parameters
+ + + + + + + +
painterPainter
xMapMaps x-values into pixel coordinates.
yMapMaps y-values into pixel coordinates.
canvasRectContents rectangle of the canvas
fromIndex of the first sample to be painted
toIndex of the last sample to be painted. If to < 0 the series will be painted to its last sample.
+
+
+
See Also
drawOutline(), drawLines(), drawColumns
+ +

Implements QwtPlotSeriesItem.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
QwtGraphic QwtPlotHistogram::legendIcon (int index,
const QSizeF & size 
) const
+
+virtual
+
+

A plain rectangle without pen using the brush()

+
Parameters
+ + + +
indexIndex of the legend entry ( ignored as there is only one )
sizeIcon size
+
+
+
Returns
A graphic displaying the icon
+
See Also
QwtPlotItem::setLegendIconSize(), QwtPlotItem::legendData()
+ +

Reimplemented from QwtPlotItem.

+ +
+
+ +
+
+ + + + + + + +
const QPen & QwtPlotHistogram::pen () const
+
+
Returns
Pen used in a style() depending way.
+
See Also
setPen(), brush()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
int QwtPlotHistogram::rtti () const
+
+virtual
+
+
Returns
QwtPlotItem::Rtti_PlotHistogram
+ +

Reimplemented from QwtPlotItem.

+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotHistogram::setBaseline (double value)
+
+ +

Set the value of the baseline.

+

Each column representing an QwtIntervalSample is defined by its interval and the interval between baseline and the value of the sample.

+

The default value of the baseline is 0.0.

+
Parameters
+ + +
valueValue of the baseline
+
+
+
See Also
baseline()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotHistogram::setBrush (const QBrush & brush)
+
+

Assign a brush, that is used in a style() depending way.

+
Parameters
+ + +
brushNew brush
+
+
+
See Also
pen(), brush()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPlotHistogram::setPen (const QColor & color,
qreal width = 0.0,
Qt::PenStyle style = Qt::SolidLine 
)
+
+

Build and assign a pen

+

In Qt5 the default pen width is 1.0 ( 0.0 in Qt4 ) what makes it non cosmetic ( see QPen::isCosmetic() ). This method has been introduced to hide this incompatibility.

+
Parameters
+ + + + +
colorPen color
widthPen width
stylePen style
+
+
+
See Also
pen(), brush()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotHistogram::setPen (const QPen & pen)
+
+

Assign a pen, that is used in a style() depending way.

+
Parameters
+ + +
penNew pen
+
+
+
See Also
pen(), brush()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotHistogram::setSamples (const QVector< QwtIntervalSample > & samples)
+
+

Initialize data with an array of samples.

+
Parameters
+ + +
samplesVector of points
+
+
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotHistogram::setSamples (QwtSeriesData< QwtIntervalSample > * data)
+
+

Assign a series of samples

+

setSamples() is just a wrapper for setData() without any additional value - beside that it is easier to find for the developer.

+
Parameters
+ + +
dataData
+
+
+
Warning
The item takes ownership of the data object, deleting it when its not used anymore.
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotHistogram::setStyle (HistogramStyle style)
+
+

Set the histogram's drawing style

+
Parameters
+ + +
styleHistogram style
+
+
+
See Also
HistogramStyle, style()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotHistogram::setSymbol (const QwtColumnSymbolsymbol)
+
+ +

Assign a symbol.

+

In Column style an optional symbol can be assigned, that is responsible for displaying the rectangle that is defined by the interval and the distance between baseline() and value. When no symbol has been defined the area is displayed as plain rectangle using pen() and brush().

+
See Also
style(), symbol(), drawColumn(), pen(), brush()
+
Note
In applications, where different intervals need to be displayed in a different way ( f.e different colors or even using different symbols) it is recommended to overload drawColumn().
+ +
+
+ +
+
+ + + + + + + +
QwtPlotHistogram::HistogramStyle QwtPlotHistogram::style () const
+
+
Returns
Style of the histogram
+
See Also
HistogramStyle, setStyle()
+ +
+
+ +
+
+ + + + + + + +
const QwtColumnSymbol * QwtPlotHistogram::symbol () const
+
+
Returns
Current symbol or NULL, when no symbol has been assigned
+
See Also
setSymbol()
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_histogram__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_plot_histogram__inherit__graph.map new file mode 100644 index 0000000000..39bb301fe9 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_histogram__inherit__graph.map @@ -0,0 +1,6 @@ + + + + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_histogram__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_plot_histogram__inherit__graph.md5 new file mode 100644 index 0000000000..1f9e4b71cd --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_histogram__inherit__graph.md5 @@ -0,0 +1 @@ +574495c5f62b6d96105750d569ac7d82 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_histogram__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_plot_histogram__inherit__graph.png new file mode 100644 index 0000000000..dd4efa8fe1 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_plot_histogram__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_interval_curve-members.html b/ThirdParty/Qwt/doc/html/class_qwt_plot_interval_curve-members.html new file mode 100644 index 0000000000..acf45e8252 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_interval_curve-members.html @@ -0,0 +1,221 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtPlotIntervalCurve Member List
+
+
+ +

This is the complete list of members for QwtPlotIntervalCurve, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
attach(QwtPlot *plot)QwtPlotItem
AutoScale enum valueQwtPlotItem
boundingRect() const QwtPlotIntervalCurvevirtual
brush() const QwtPlotIntervalCurve
ClipPolygons enum valueQwtPlotIntervalCurve
ClipSymbol enum valueQwtPlotIntervalCurve
CurveStyle enum nameQwtPlotIntervalCurve
data()QwtSeriesStore< QwtIntervalSample >
data() constQwtSeriesStore< QwtIntervalSample >
dataChanged()QwtPlotSeriesItemprotectedvirtual
QwtPlotSeriesItem::dataRect() const =0QwtAbstractSeriesStoreprotectedpure virtual
QwtSeriesStore< QwtIntervalSample >::dataRect() constQwtSeriesStore< QwtIntervalSample >virtual
QwtPlotSeriesItem::dataSize() const =0QwtAbstractSeriesStoreprotectedpure virtual
QwtSeriesStore< QwtIntervalSample >::dataSize() constQwtSeriesStore< QwtIntervalSample >virtual
defaultIcon(const QBrush &, const QSizeF &) const QwtPlotItemprotected
detach()QwtPlotItem
draw(QPainter *p, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &) const QwtPlotSeriesItemvirtual
drawSeries(QPainter *p, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, int from, int to) const QwtPlotIntervalCurvevirtual
drawSymbols(QPainter *, const QwtIntervalSymbol &, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, int from, int to) const QwtPlotIntervalCurveprotectedvirtual
drawTube(QPainter *, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, int from, int to) const QwtPlotIntervalCurveprotectedvirtual
getCanvasMarginHint(const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasSize, double &left, double &top, double &right, double &bottom) const QwtPlotItemvirtual
hide()QwtPlotItem
init()QwtPlotIntervalCurveprotected
isVisible() const QwtPlotItem
ItemAttribute enum nameQwtPlotItem
ItemAttributes typedefQwtPlotItem
itemChanged()QwtPlotItemvirtual
ItemInterest enum nameQwtPlotItem
ItemInterests typedefQwtPlotItem
Legend enum valueQwtPlotItem
legendChanged()QwtPlotItemvirtual
legendData() const QwtPlotItemvirtual
legendIcon(int index, const QSizeF &) const QwtPlotIntervalCurvevirtual
legendIconSize() const QwtPlotItem
LegendInterest enum valueQwtPlotItem
Margins enum valueQwtPlotItem
NoCurve enum valueQwtPlotIntervalCurve
orientation() const QwtPlotSeriesItem
PaintAttribute enum nameQwtPlotIntervalCurve
PaintAttributes typedefQwtPlotIntervalCurve
paintRect(const QwtScaleMap &, const QwtScaleMap &) const QwtPlotItem
pen() const QwtPlotIntervalCurve
plot() const QwtPlotItem
QwtPlotIntervalCurve(const QString &title=QString::null)QwtPlotIntervalCurveexplicit
QwtPlotIntervalCurve(const QwtText &title)QwtPlotIntervalCurveexplicit
QwtPlotItem(const QwtText &title=QwtText())QwtPlotItemexplicit
QwtPlotSeriesItem(const QString &title=QString::null)QwtPlotSeriesItemexplicit
QwtPlotSeriesItem(const QwtText &title)QwtPlotSeriesItemexplicit
QwtSeriesStore()QwtSeriesStore< QwtIntervalSample >explicit
RenderAntialiased enum valueQwtPlotItem
RenderHint enum nameQwtPlotItem
RenderHints typedefQwtPlotItem
renderThreadCount() const QwtPlotItem
rtti() const QwtPlotIntervalCurvevirtual
Rtti_PlotBarChart enum valueQwtPlotItem
Rtti_PlotCurve enum valueQwtPlotItem
Rtti_PlotGrid enum valueQwtPlotItem
Rtti_PlotHistogram enum valueQwtPlotItem
Rtti_PlotIntervalCurve enum valueQwtPlotItem
Rtti_PlotItem enum valueQwtPlotItem
Rtti_PlotLegend enum valueQwtPlotItem
Rtti_PlotMarker enum valueQwtPlotItem
Rtti_PlotMultiBarChart enum valueQwtPlotItem
Rtti_PlotScale enum valueQwtPlotItem
Rtti_PlotShape enum valueQwtPlotItem
Rtti_PlotSpectroCurve enum valueQwtPlotItem
Rtti_PlotSpectrogram enum valueQwtPlotItem
Rtti_PlotSVG enum valueQwtPlotItem
Rtti_PlotTextLabel enum valueQwtPlotItem
Rtti_PlotTradingCurve enum valueQwtPlotItem
Rtti_PlotUserItem enum valueQwtPlotItem
Rtti_PlotZone enum valueQwtPlotItem
RttiValues enum nameQwtPlotItem
sample(int index) constQwtSeriesStore< QwtIntervalSample >
ScaleInterest enum valueQwtPlotItem
scaleRect(const QwtScaleMap &, const QwtScaleMap &) const QwtPlotItem
setAxes(int xAxis, int yAxis)QwtPlotItem
setBrush(const QBrush &)QwtPlotIntervalCurve
setData(QwtSeriesData< QwtIntervalSample > *series)QwtSeriesStore< QwtIntervalSample >
setItemAttribute(ItemAttribute, bool on=true)QwtPlotItem
setItemInterest(ItemInterest, bool on=true)QwtPlotItem
setLegendIconSize(const QSize &)QwtPlotItem
setOrientation(Qt::Orientation)QwtPlotSeriesItem
setPaintAttribute(PaintAttribute, bool on=true)QwtPlotIntervalCurve
setPen(const QColor &, qreal width=0.0, Qt::PenStyle=Qt::SolidLine)QwtPlotIntervalCurve
setPen(const QPen &)QwtPlotIntervalCurve
QwtPlotSeriesItem::setRectOfInterest(const QRectF &)=0QwtAbstractSeriesStoreprotectedpure virtual
QwtSeriesStore< QwtIntervalSample >::setRectOfInterest(const QRectF &rect)QwtSeriesStore< QwtIntervalSample >virtual
setRenderHint(RenderHint, bool on=true)QwtPlotItem
setRenderThreadCount(uint numThreads)QwtPlotItem
setSamples(const QVector< QwtIntervalSample > &)QwtPlotIntervalCurve
setSamples(QwtSeriesData< QwtIntervalSample > *)QwtPlotIntervalCurve
setStyle(CurveStyle style)QwtPlotIntervalCurve
setSymbol(const QwtIntervalSymbol *)QwtPlotIntervalCurve
setTitle(const QString &title)QwtPlotItem
setTitle(const QwtText &title)QwtPlotItem
setVisible(bool)QwtPlotItemvirtual
setXAxis(int axis)QwtPlotItem
setYAxis(int axis)QwtPlotItem
setZ(double z)QwtPlotItem
show()QwtPlotItem
style() const QwtPlotIntervalCurve
swapData(QwtSeriesData< QwtIntervalSample > *series)QwtSeriesStore< QwtIntervalSample >
symbol() const QwtPlotIntervalCurve
testItemAttribute(ItemAttribute) const QwtPlotItem
testItemInterest(ItemInterest) const QwtPlotItem
testPaintAttribute(PaintAttribute) const QwtPlotIntervalCurve
testRenderHint(RenderHint) const QwtPlotItem
title() const QwtPlotItem
Tube enum valueQwtPlotIntervalCurve
updateLegend(const QwtPlotItem *, const QList< QwtLegendData > &)QwtPlotItemvirtual
updateScaleDiv(const QwtScaleDiv &, const QwtScaleDiv &)QwtPlotSeriesItemvirtual
UserCurve enum valueQwtPlotIntervalCurve
xAxis() const QwtPlotItem
yAxis() const QwtPlotItem
z() const QwtPlotItem
~QwtAbstractSeriesStore()QwtAbstractSeriesStoreinlineprotectedvirtual
~QwtPlotIntervalCurve()QwtPlotIntervalCurvevirtual
~QwtPlotItem()QwtPlotItemvirtual
~QwtPlotSeriesItem()QwtPlotSeriesItemvirtual
~QwtSeriesStore()QwtSeriesStore< QwtIntervalSample >
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_interval_curve.html b/ThirdParty/Qwt/doc/html/class_qwt_plot_interval_curve.html new file mode 100644 index 0000000000..af75d5aef2 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_interval_curve.html @@ -0,0 +1,1090 @@ + + + + + + +Qwt User's Guide: QwtPlotIntervalCurve Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtPlotIntervalCurve Class Reference
+
+
+ +

QwtPlotIntervalCurve represents a series of samples, where each value is associated with an interval ( $[y1,y2] = f(x)$ ). + More...

+ +

#include <qwt_plot_intervalcurve.h>

+
+Inheritance diagram for QwtPlotIntervalCurve:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + + + +

+Public Types

enum  CurveStyle { NoCurve, +Tube, +UserCurve = 100 + }
 Curve styles. The default setting is QwtPlotIntervalCurve::Tube. More...
 
enum  PaintAttribute { ClipPolygons = 0x01, +ClipSymbol = 0x02 + }
 
+typedef QFlags< PaintAttributePaintAttributes
 Paint attributes.
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 QwtPlotIntervalCurve (const QString &title=QString::null)
 
 QwtPlotIntervalCurve (const QwtText &title)
 
+virtual ~QwtPlotIntervalCurve ()
 Destructor.
 
virtual int rtti () const
 
void setPaintAttribute (PaintAttribute, bool on=true)
 
bool testPaintAttribute (PaintAttribute) const
 
void setSamples (const QVector< QwtIntervalSample > &)
 
void setSamples (QwtSeriesData< QwtIntervalSample > *)
 
void setPen (const QColor &, qreal width=0.0, Qt::PenStyle=Qt::SolidLine)
 
void setPen (const QPen &)
 Assign a pen. More...
 
const QPen & pen () const
 
void setBrush (const QBrush &)
 
const QBrush & brush () const
 
void setStyle (CurveStyle style)
 
CurveStyle style () const
 
void setSymbol (const QwtIntervalSymbol *)
 
const QwtIntervalSymbolsymbol () const
 
virtual void drawSeries (QPainter *p, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, int from, int to) const
 
virtual QRectF boundingRect () const
 
virtual QwtGraphic legendIcon (int index, const QSizeF &) const
 
- Public Member Functions inherited from QwtPlotSeriesItem
 QwtPlotSeriesItem (const QString &title=QString::null)
 
 QwtPlotSeriesItem (const QwtText &title)
 
+virtual ~QwtPlotSeriesItem ()
 Destructor.
 
void setOrientation (Qt::Orientation)
 
Qt::Orientation orientation () const
 
virtual void draw (QPainter *p, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &) const
 Draw the complete series. More...
 
virtual void updateScaleDiv (const QwtScaleDiv &, const QwtScaleDiv &)
 Update the item to changes of the axes scale division. More...
 
- Public Member Functions inherited from QwtPlotItem
 QwtPlotItem (const QwtText &title=QwtText())
 
+virtual ~QwtPlotItem ()
 Destroy the QwtPlotItem.
 
void attach (QwtPlot *plot)
 Attach the item to a plot. More...
 
void detach ()
 This method detaches a QwtPlotItem from any QwtPlot it has been associated with. More...
 
+QwtPlotplot () const
 Return attached plot.
 
void setTitle (const QString &title)
 
void setTitle (const QwtText &title)
 
const QwtTexttitle () const
 
void setItemAttribute (ItemAttribute, bool on=true)
 
bool testItemAttribute (ItemAttribute) const
 
void setItemInterest (ItemInterest, bool on=true)
 
bool testItemInterest (ItemInterest) const
 
void setRenderHint (RenderHint, bool on=true)
 
bool testRenderHint (RenderHint) const
 
void setRenderThreadCount (uint numThreads)
 
uint renderThreadCount () const
 
void setLegendIconSize (const QSize &)
 
QSize legendIconSize () const
 
double z () const
 
void setZ (double z)
 Set the z value. More...
 
+void show ()
 Show the item.
 
+void hide ()
 Hide the item.
 
virtual void setVisible (bool)
 
bool isVisible () const
 
void setAxes (int xAxis, int yAxis)
 
void setXAxis (int axis)
 
+int xAxis () const
 Return xAxis.
 
void setYAxis (int axis)
 
+int yAxis () const
 Return yAxis.
 
virtual void itemChanged ()
 
virtual void legendChanged ()
 
virtual void getCanvasMarginHint (const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasSize, double &left, double &top, double &right, double &bottom) const
 Calculate a hint for the canvas margin. More...
 
virtual void updateLegend (const QwtPlotItem *, const QList< QwtLegendData > &)
 Update the item to changes of the legend info. More...
 
QRectF scaleRect (const QwtScaleMap &, const QwtScaleMap &) const
 Calculate the bounding scale rectangle of 2 maps. More...
 
QRectF paintRect (const QwtScaleMap &, const QwtScaleMap &) const
 Calculate the bounding paint rectangle of 2 maps. More...
 
virtual QList< QwtLegendDatalegendData () const
 Return all information, that is needed to represent the item on the legend. More...
 
- Public Member Functions inherited from QwtSeriesStore< QwtIntervalSample >
QwtSeriesStore ()
 Constructor The store contains no series.
 
~QwtSeriesStore ()
 Destructor.
 
void setData (QwtSeriesData< QwtIntervalSample > *series)
 
QwtSeriesData
+< QwtIntervalSample > * 
data ()
 
const QwtSeriesData
+< QwtIntervalSample > * 
data () const
 
QwtIntervalSample sample (int index) const
 
virtual size_t dataSize () const
 
virtual QRectF dataRect () const
 
virtual void setRectOfInterest (const QRectF &rect)
 
QwtSeriesData
+< QwtIntervalSample > * 
swapData (QwtSeriesData< QwtIntervalSample > *series)
 
+ + + + + + + + + + + + + + + + + + + + +

+Protected Member Functions

+void init ()
 Initialize internal members.
 
virtual void drawTube (QPainter *, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, int from, int to) const
 
virtual void drawSymbols (QPainter *, const QwtIntervalSymbol &, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, int from, int to) const
 
- Protected Member Functions inherited from QwtPlotSeriesItem
+virtual void dataChanged ()
 dataChanged() indicates, that the series has been changed.
 
- Protected Member Functions inherited from QwtPlotItem
QwtGraphic defaultIcon (const QBrush &, const QSizeF &) const
 Return a default icon from a brush. More...
 
- Protected Member Functions inherited from QwtAbstractSeriesStore
+virtual ~QwtAbstractSeriesStore ()
 Destructor.
 
+

Detailed Description

+

QwtPlotIntervalCurve represents a series of samples, where each value is associated with an interval ( $[y1,y2] = f(x)$ ).

+

The representation depends on the style() and an optional symbol() that is displayed for each interval. QwtPlotIntervalCurve might be used to display error bars or the area between 2 curves.

+

Member Enumeration Documentation

+ +
+
+ +

Curve styles. The default setting is QwtPlotIntervalCurve::Tube.

+
See Also
setStyle(), style()
+ + + + +
Enumerator
NoCurve  +

Don't draw a curve. Note: This doesn't affect the symbols.

+
Tube  +

Build 2 curves from the upper and lower limits of the intervals and draw them with the pen(). The area between the curves is filled with the brush().

+
UserCurve  +

Styles >= QwtPlotIntervalCurve::UserCurve are reserved for derived classes that overload drawSeries() with additional application specific curve types.

+
+ +
+
+ +
+
+

Attributes to modify the drawing algorithm.

+
See Also
setPaintAttribute(), testPaintAttribute()
+ + + +
Enumerator
ClipPolygons  +

Clip polygons before painting them. In situations, where points are far outside the visible area (f.e when zooming deep) this might be a substantial improvement for the painting performance.

+
ClipSymbol  +

Check if a symbol is on the plot canvas before painting it.

+
+ +
+
+

Constructor & Destructor Documentation

+ +
+
+ + + + + +
+ + + + + + + + +
QwtPlotIntervalCurve::QwtPlotIntervalCurve (const QString & title = QString::null)
+
+explicit
+
+

Constructor

+
Parameters
+ + +
titleTitle of the curve
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
QwtPlotIntervalCurve::QwtPlotIntervalCurve (const QwtTexttitle)
+
+explicit
+
+

Constructor

+
Parameters
+ + +
titleTitle of the curve
+
+
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + +
QRectF QwtPlotIntervalCurve::boundingRect () const
+
+virtual
+
+
Returns
Bounding rectangle of all samples. For an empty series the rectangle is invalid.
+ +

Reimplemented from QwtPlotSeriesItem.

+ +
+
+ +
+
+ + + + + + + +
const QBrush & QwtPlotIntervalCurve::brush () const
+
+
Returns
Brush used to fill the area in Tube style()
+
See Also
setBrush(), setStyle(), CurveStyle
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPlotIntervalCurve::drawSeries (QPainter * painter,
const QwtScaleMapxMap,
const QwtScaleMapyMap,
const QRectF & canvasRect,
int from,
int to 
) const
+
+virtual
+
+

Draw a subset of the samples

+
Parameters
+ + + + + + + +
painterPainter
xMapMaps x-values into pixel coordinates.
yMapMaps y-values into pixel coordinates.
canvasRectContents rectangle of the canvas
fromIndex of the first sample to be painted
toIndex of the last sample to be painted. If to < 0 the series will be painted to its last sample.
+
+
+
See Also
drawTube(), drawSymbols()
+ +

Implements QwtPlotSeriesItem.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPlotIntervalCurve::drawSymbols (QPainter * painter,
const QwtIntervalSymbolsymbol,
const QwtScaleMapxMap,
const QwtScaleMapyMap,
const QRectF & canvasRect,
int from,
int to 
) const
+
+protectedvirtual
+
+

Draw symbols for a subset of the samples

+
Parameters
+ + + + + + + + +
painterPainter
symbolInterval symbol
xMapx map
yMapy map
canvasRectContents rectangle of the canvas
fromIndex of the first sample to be painted
toIndex of the last sample to be painted
+
+
+
See Also
setSymbol(), drawSeries(), drawTube()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPlotIntervalCurve::drawTube (QPainter * painter,
const QwtScaleMapxMap,
const QwtScaleMapyMap,
const QRectF & canvasRect,
int from,
int to 
) const
+
+protectedvirtual
+
+

Draw a tube

+

Builds 2 curves from the upper and lower limits of the intervals and draws them with the pen(). The area between the curves is filled with the brush().

+
Parameters
+ + + + + + + +
painterPainter
xMapMaps x-values into pixel coordinates.
yMapMaps y-values into pixel coordinates.
canvasRectContents rectangle of the canvas
fromIndex of the first sample to be painted
toIndex of the last sample to be painted. If to < 0 the series will be painted to its last sample.
+
+
+
See Also
drawSeries(), drawSymbols()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
QwtGraphic QwtPlotIntervalCurve::legendIcon (int index,
const QSizeF & size 
) const
+
+virtual
+
+
Returns
Icon for the legend
+

In case of Tube style() the icon is a plain rectangle filled with the brush(). If a symbol is assigned it is scaled to size.

+
Parameters
+ + + +
indexIndex of the legend entry ( ignored as there is only one )
sizeIcon size
+
+
+
See Also
QwtPlotItem::setLegendIconSize(), QwtPlotItem::legendData()
+ +

Reimplemented from QwtPlotItem.

+ +
+
+ +
+
+ + + + + + + +
const QPen & QwtPlotIntervalCurve::pen () const
+
+
Returns
Pen used to draw the lines
+
See Also
setPen(), brush()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
int QwtPlotIntervalCurve::rtti () const
+
+virtual
+
+
Returns
QwtPlotItem::Rtti_PlotIntervalCurve
+ +

Reimplemented from QwtPlotItem.

+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotIntervalCurve::setBrush (const QBrush & brush)
+
+

Assign a brush.

+

The brush is used to fill the area in Tube style().

+
Parameters
+ + +
brushBrush
+
+
+
See Also
brush(), pen(), setStyle(), CurveStyle
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtPlotIntervalCurve::setPaintAttribute (PaintAttribute attribute,
bool on = true 
)
+
+

Specify an attribute how to draw the curve

+
Parameters
+ + + +
attributePaint attribute
onOn/Off
+
+
+
See Also
testPaintAttribute()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPlotIntervalCurve::setPen (const QColor & color,
qreal width = 0.0,
Qt::PenStyle style = Qt::SolidLine 
)
+
+

Build and assign a pen

+

In Qt5 the default pen width is 1.0 ( 0.0 in Qt4 ) what makes it non cosmetic ( see QPen::isCosmetic() ). This method has been introduced to hide this incompatibility.

+
Parameters
+ + + + +
colorPen color
widthPen width
stylePen style
+
+
+
See Also
pen(), brush()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotIntervalCurve::setPen (const QPen & pen)
+
+ +

Assign a pen.

+
Parameters
+ + +
penNew pen
+
+
+
See Also
pen(), brush()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotIntervalCurve::setSamples (const QVector< QwtIntervalSample > & samples)
+
+

Initialize data with an array of samples.

+
Parameters
+ + +
samplesVector of samples
+
+
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotIntervalCurve::setSamples (QwtSeriesData< QwtIntervalSample > * data)
+
+

Assign a series of samples

+

setSamples() is just a wrapper for setData() without any additional value - beside that it is easier to find for the developer.

+
Parameters
+ + +
dataData
+
+
+
Warning
The item takes ownership of the data object, deleting it when its not used anymore.
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotIntervalCurve::setStyle (CurveStyle style)
+
+

Set the curve's drawing style

+
Parameters
+ + +
styleCurve style
+
+
+
See Also
CurveStyle, style()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotIntervalCurve::setSymbol (const QwtIntervalSymbolsymbol)
+
+

Assign a symbol.

+
Parameters
+ + +
symbolSymbol
+
+
+
See Also
symbol()
+ +
+
+ +
+
+ + + + + + + +
QwtPlotIntervalCurve::CurveStyle QwtPlotIntervalCurve::style () const
+
+
Returns
Style of the curve
+
See Also
setStyle()
+ +
+
+ +
+
+ + + + + + + +
const QwtIntervalSymbol * QwtPlotIntervalCurve::symbol () const
+
+
Returns
Current symbol or NULL, when no symbol has been assigned
+
See Also
setSymbol()
+ +
+
+ +
+
+ + + + + + + + +
bool QwtPlotIntervalCurve::testPaintAttribute (PaintAttribute attribute) const
+
+
Returns
True, when attribute is enabled
+
See Also
PaintAttribute, setPaintAttribute()
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_interval_curve__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_plot_interval_curve__inherit__graph.map new file mode 100644 index 0000000000..787a8c364d --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_interval_curve__inherit__graph.map @@ -0,0 +1,6 @@ + + + + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_interval_curve__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_plot_interval_curve__inherit__graph.md5 new file mode 100644 index 0000000000..fc03607fff --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_interval_curve__inherit__graph.md5 @@ -0,0 +1 @@ +9cc7a0934769dbd20eb705b74d0037dd \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_interval_curve__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_plot_interval_curve__inherit__graph.png new file mode 100644 index 0000000000..820b1db622 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_plot_interval_curve__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_item-members.html b/ThirdParty/Qwt/doc/html/class_qwt_plot_item-members.html new file mode 100644 index 0000000000..3ce38d7457 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_item-members.html @@ -0,0 +1,173 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtPlotItem Member List
+
+
+ +

This is the complete list of members for QwtPlotItem, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
attach(QwtPlot *plot)QwtPlotItem
AutoScale enum valueQwtPlotItem
boundingRect() const QwtPlotItemvirtual
defaultIcon(const QBrush &, const QSizeF &) const QwtPlotItemprotected
detach()QwtPlotItem
draw(QPainter *painter, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect) const =0QwtPlotItempure virtual
getCanvasMarginHint(const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasSize, double &left, double &top, double &right, double &bottom) const QwtPlotItemvirtual
hide()QwtPlotItem
isVisible() const QwtPlotItem
ItemAttribute enum nameQwtPlotItem
ItemAttributes typedefQwtPlotItem
itemChanged()QwtPlotItemvirtual
ItemInterest enum nameQwtPlotItem
ItemInterests typedefQwtPlotItem
Legend enum valueQwtPlotItem
legendChanged()QwtPlotItemvirtual
legendData() const QwtPlotItemvirtual
legendIcon(int index, const QSizeF &) const QwtPlotItemvirtual
legendIconSize() const QwtPlotItem
LegendInterest enum valueQwtPlotItem
Margins enum valueQwtPlotItem
paintRect(const QwtScaleMap &, const QwtScaleMap &) const QwtPlotItem
plot() const QwtPlotItem
QwtPlotItem(const QwtText &title=QwtText())QwtPlotItemexplicit
RenderAntialiased enum valueQwtPlotItem
RenderHint enum nameQwtPlotItem
RenderHints typedefQwtPlotItem
renderThreadCount() const QwtPlotItem
rtti() const QwtPlotItemvirtual
Rtti_PlotBarChart enum valueQwtPlotItem
Rtti_PlotCurve enum valueQwtPlotItem
Rtti_PlotGrid enum valueQwtPlotItem
Rtti_PlotHistogram enum valueQwtPlotItem
Rtti_PlotIntervalCurve enum valueQwtPlotItem
Rtti_PlotItem enum valueQwtPlotItem
Rtti_PlotLegend enum valueQwtPlotItem
Rtti_PlotMarker enum valueQwtPlotItem
Rtti_PlotMultiBarChart enum valueQwtPlotItem
Rtti_PlotScale enum valueQwtPlotItem
Rtti_PlotShape enum valueQwtPlotItem
Rtti_PlotSpectroCurve enum valueQwtPlotItem
Rtti_PlotSpectrogram enum valueQwtPlotItem
Rtti_PlotSVG enum valueQwtPlotItem
Rtti_PlotTextLabel enum valueQwtPlotItem
Rtti_PlotTradingCurve enum valueQwtPlotItem
Rtti_PlotUserItem enum valueQwtPlotItem
Rtti_PlotZone enum valueQwtPlotItem
RttiValues enum nameQwtPlotItem
ScaleInterest enum valueQwtPlotItem
scaleRect(const QwtScaleMap &, const QwtScaleMap &) const QwtPlotItem
setAxes(int xAxis, int yAxis)QwtPlotItem
setItemAttribute(ItemAttribute, bool on=true)QwtPlotItem
setItemInterest(ItemInterest, bool on=true)QwtPlotItem
setLegendIconSize(const QSize &)QwtPlotItem
setRenderHint(RenderHint, bool on=true)QwtPlotItem
setRenderThreadCount(uint numThreads)QwtPlotItem
setTitle(const QString &title)QwtPlotItem
setTitle(const QwtText &title)QwtPlotItem
setVisible(bool)QwtPlotItemvirtual
setXAxis(int axis)QwtPlotItem
setYAxis(int axis)QwtPlotItem
setZ(double z)QwtPlotItem
show()QwtPlotItem
testItemAttribute(ItemAttribute) const QwtPlotItem
testItemInterest(ItemInterest) const QwtPlotItem
testRenderHint(RenderHint) const QwtPlotItem
title() const QwtPlotItem
updateLegend(const QwtPlotItem *, const QList< QwtLegendData > &)QwtPlotItemvirtual
updateScaleDiv(const QwtScaleDiv &, const QwtScaleDiv &)QwtPlotItemvirtual
xAxis() const QwtPlotItem
yAxis() const QwtPlotItem
z() const QwtPlotItem
~QwtPlotItem()QwtPlotItemvirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_item.html b/ThirdParty/Qwt/doc/html/class_qwt_plot_item.html new file mode 100644 index 0000000000..8e01aa1728 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_item.html @@ -0,0 +1,1582 @@ + + + + + + +Qwt User's Guide: QwtPlotItem Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtPlotItem Class Referenceabstract
+
+
+ +

Base class for items on the plot canvas. + More...

+ +

#include <qwt_plot_item.h>

+
+Inheritance diagram for QwtPlotItem:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + +

+Public Types

enum  RttiValues {
+  Rtti_PlotItem = 0, +Rtti_PlotGrid, +Rtti_PlotScale, +Rtti_PlotLegend, +
+  Rtti_PlotMarker, +Rtti_PlotCurve, +Rtti_PlotSpectroCurve, +Rtti_PlotIntervalCurve, +
+  Rtti_PlotHistogram, +Rtti_PlotSpectrogram, +Rtti_PlotSVG, +Rtti_PlotTradingCurve, +
+  Rtti_PlotBarChart, +Rtti_PlotMultiBarChart, +Rtti_PlotShape, +Rtti_PlotTextLabel, +
+  Rtti_PlotZone, +Rtti_PlotUserItem = 1000 +
+ }
 Runtime type information. More...
 
enum  ItemAttribute { Legend = 0x01, +AutoScale = 0x02, +Margins = 0x04 + }
 Plot Item Attributes. More...
 
enum  ItemInterest { ScaleInterest = 0x01, +LegendInterest = 0x02 + }
 Plot Item Interests. More...
 
enum  RenderHint { RenderAntialiased = 0x1 + }
 Render hints. More...
 
+typedef QFlags< ItemAttributeItemAttributes
 Plot Item Attributes.
 
+typedef QFlags< ItemInterestItemInterests
 Plot Item Interests.
 
+typedef QFlags< RenderHintRenderHints
 Render hints.
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 QwtPlotItem (const QwtText &title=QwtText())
 
+virtual ~QwtPlotItem ()
 Destroy the QwtPlotItem.
 
void attach (QwtPlot *plot)
 Attach the item to a plot. More...
 
void detach ()
 This method detaches a QwtPlotItem from any QwtPlot it has been associated with. More...
 
+QwtPlotplot () const
 Return attached plot.
 
void setTitle (const QString &title)
 
void setTitle (const QwtText &title)
 
const QwtTexttitle () const
 
virtual int rtti () const
 
void setItemAttribute (ItemAttribute, bool on=true)
 
bool testItemAttribute (ItemAttribute) const
 
void setItemInterest (ItemInterest, bool on=true)
 
bool testItemInterest (ItemInterest) const
 
void setRenderHint (RenderHint, bool on=true)
 
bool testRenderHint (RenderHint) const
 
void setRenderThreadCount (uint numThreads)
 
uint renderThreadCount () const
 
void setLegendIconSize (const QSize &)
 
QSize legendIconSize () const
 
double z () const
 
void setZ (double z)
 Set the z value. More...
 
+void show ()
 Show the item.
 
+void hide ()
 Hide the item.
 
virtual void setVisible (bool)
 
bool isVisible () const
 
void setAxes (int xAxis, int yAxis)
 
void setXAxis (int axis)
 
+int xAxis () const
 Return xAxis.
 
void setYAxis (int axis)
 
+int yAxis () const
 Return yAxis.
 
virtual void itemChanged ()
 
virtual void legendChanged ()
 
virtual void draw (QPainter *painter, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect) const =0
 Draw the item. More...
 
virtual QRectF boundingRect () const
 
virtual void getCanvasMarginHint (const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasSize, double &left, double &top, double &right, double &bottom) const
 Calculate a hint for the canvas margin. More...
 
virtual void updateScaleDiv (const QwtScaleDiv &, const QwtScaleDiv &)
 Update the item to changes of the axes scale division. More...
 
virtual void updateLegend (const QwtPlotItem *, const QList< QwtLegendData > &)
 Update the item to changes of the legend info. More...
 
QRectF scaleRect (const QwtScaleMap &, const QwtScaleMap &) const
 Calculate the bounding scale rectangle of 2 maps. More...
 
QRectF paintRect (const QwtScaleMap &, const QwtScaleMap &) const
 Calculate the bounding paint rectangle of 2 maps. More...
 
virtual QList< QwtLegendDatalegendData () const
 Return all information, that is needed to represent the item on the legend. More...
 
virtual QwtGraphic legendIcon (int index, const QSizeF &) const
 
+ + + + +

+Protected Member Functions

QwtGraphic defaultIcon (const QBrush &, const QSizeF &) const
 Return a default icon from a brush. More...
 
+

Detailed Description

+

Base class for items on the plot canvas.

+

A plot item is "something", that can be painted on the plot canvas, or only affects the scales of the plot widget. They can be categorized as:

+
    +
  • Representator
    + A "Representator" is an item that represents some sort of data on the plot canvas. The different representator classes are organized according to the characteristics of the data: +
  • +
+ +

Depending on the QwtPlotItem::ItemAttribute flags, an item is included into autoscaling or has an entry on the legend.

+

Before misusing the existing item classes it might be better to implement a new type of plot item ( don't implement a watermark as spectrogram ). Deriving a new type of QwtPlotItem primarily means to implement the YourPlotItem::draw() method.

+
See Also
The cpuplot example shows the implementation of additional plot items.
+

Member Enumeration Documentation

+ +
+
+ + + + +
enum QwtPlotItem::ItemAttribute
+
+ +

Plot Item Attributes.

+

Various aspects of a plot widget depend on the attributes of the attached plot items. If and how a single plot item participates in these updates depends on its attributes.

+
See Also
setItemAttribute(), testItemAttribute(), ItemInterest
+ + + + +
Enumerator
Legend  +

The item is represented on the legend.

+
AutoScale  +

The boundingRect() of the item is included in the autoscaling calculation as long as its width or height is >= 0.0.

+
Margins  +

The item needs extra space to display something outside its bounding rectangle.

+
See Also
getCanvasMarginHint()
+
+ +
+
+ +
+
+ + + + +
enum QwtPlotItem::ItemInterest
+
+ +

Plot Item Interests.

+

Plot items might depend on the situation of the corresponding plot widget. By enabling an interest the plot item will be notified, when the corresponding attribute of the plot widgets has changed.

+
See Also
setItemAttribute(), testItemAttribute(), ItemInterest
+ + + +
Enumerator
ScaleInterest  +

The item is interested in updates of the scales

+
See Also
updateScaleDiv()
+
LegendInterest  +

The item is interested in updates of the legend ( of other items ) This flag is intended for items, that want to implement a legend for displaying entries of other plot item.

+
Note
If the plot item wants to be represented on a legend enable QwtPlotItem::Legend instead.
+
See Also
updateLegend()
+
+ +
+
+ +
+
+ + + + +
enum QwtPlotItem::RenderHint
+
+ +

Render hints.

+ + +
Enumerator
RenderAntialiased  +

Enable antialiasing.

+
+ +
+
+ +
+
+ + + + +
enum QwtPlotItem::RttiValues
+
+ +

Runtime type information.

+

RttiValues is used to cast plot items, without having to enable runtime type information of the compiler.

+ + + + + + + + + + + + + + + + + + + +
Enumerator
Rtti_PlotItem  +

Unspecific value, that can be used, when it doesn't matter.

+
Rtti_PlotGrid  +

For QwtPlotGrid.

+
Rtti_PlotScale  +

For QwtPlotScaleItem.

+
Rtti_PlotLegend  +

For QwtPlotLegendItem.

+
Rtti_PlotMarker  +

For QwtPlotMarker.

+
Rtti_PlotCurve  +

For QwtPlotCurve.

+
Rtti_PlotSpectroCurve  +

For QwtPlotSpectroCurve.

+
Rtti_PlotIntervalCurve  +

For QwtPlotIntervalCurve.

+
Rtti_PlotHistogram  +

For QwtPlotHistogram.

+
Rtti_PlotSpectrogram  +

For QwtPlotSpectrogram.

+
Rtti_PlotSVG  +

For QwtPlotSvgItem.

+
Rtti_PlotTradingCurve  +

For QwtPlotTradingCurve.

+
Rtti_PlotBarChart  +

For QwtPlotBarChart.

+
Rtti_PlotMultiBarChart  +

For QwtPlotMultiBarChart.

+
Rtti_PlotShape  +

For QwtPlotShapeItem.

+
Rtti_PlotTextLabel  +

For QwtPlotTextLabel.

+
Rtti_PlotZone  +

For QwtPlotZoneItem.

+
Rtti_PlotUserItem  +

Values >= Rtti_PlotUserItem are reserved for plot items not implemented in the Qwt library.

+
+ +
+
+

Constructor & Destructor Documentation

+ +
+
+ + + + + +
+ + + + + + + + +
QwtPlotItem::QwtPlotItem (const QwtTexttitle = QwtText())
+
+explicit
+
+

Constructor

+
Parameters
+ + +
titleTitle of the item
+
+
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + + + + +
void QwtPlotItem::attach (QwtPlotplot)
+
+ +

Attach the item to a plot.

+

This method will attach a QwtPlotItem to the QwtPlot argument. It will first detach the QwtPlotItem from any plot from a previous call to attach (if necessary). If a NULL argument is passed, it will detach from any QwtPlot it was attached to.

+
Parameters
+ + +
plotPlot widget
+
+
+
See Also
detach()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
QRectF QwtPlotItem::boundingRect () const
+
+virtual
+
+
Returns
An invalid bounding rect: QRectF(1.0, 1.0, -2.0, -2.0)
+
Note
A width or height < 0.0 is ignored by the autoscaler
+ +

Reimplemented in QwtPlotTradingCurve, QwtPlotMarker, QwtPlotIntervalCurve, QwtPlotHistogram, QwtPlotRasterItem, QwtPlotShapeItem, QwtPlotBarChart, QwtPlotMultiBarChart, QwtPlotZoneItem, QwtPlotSeriesItem, and QwtPlotSvgItem.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
QwtGraphic QwtPlotItem::defaultIcon (const QBrush & brush,
const QSizeF & size 
) const
+
+protected
+
+ +

Return a default icon from a brush.

+

The default icon is a filled rectangle used in several derived classes as legendIcon().

+
Parameters
+ + + +
brushFill brush
sizeIcon size
+
+
+
Returns
A filled rectangle
+ +
+
+ +
+
+ + + + + + + +
void QwtPlotItem::detach ()
+
+ +

This method detaches a QwtPlotItem from any QwtPlot it has been associated with.

+

detach() is equivalent to calling attach( NULL )

+
See Also
attach()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
virtual void QwtPlotItem::draw (QPainter * painter,
const QwtScaleMapxMap,
const QwtScaleMapyMap,
const QRectF & canvasRect 
) const
+
+pure virtual
+
+ +

Draw the item.

+
Parameters
+ + + + + +
painterPainter
xMapMaps x-values into pixel coordinates.
yMapMaps y-values into pixel coordinates.
canvasRectContents rect of the canvas in painter coordinates
+
+
+ +

Implemented in QwtPlotMarker, QwtPlotLegendItem, QwtPlotRasterItem, QwtPlotShapeItem, QwtPlotSpectrogram, QwtPlotScaleItem, QwtPlotGrid, QwtPlotTextLabel, QwtPlotZoneItem, QwtPlotSvgItem, and QwtPlotSeriesItem.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPlotItem::getCanvasMarginHint (const QwtScaleMapxMap,
const QwtScaleMapyMap,
const QRectF & canvasRect,
double & left,
double & top,
double & right,
double & bottom 
) const
+
+virtual
+
+ +

Calculate a hint for the canvas margin.

+

When the QwtPlotItem::Margins flag is enabled the plot item indicates, that it needs some margins at the borders of the canvas. This is f.e. used by bar charts to reserve space for displaying the bars.

+

The margins are in target device coordinates ( pixels on screen )

+
Parameters
+ + + + + + + + +
xMapMaps x-values into pixel coordinates.
yMapMaps y-values into pixel coordinates.
canvasRectContents rectangle of the canvas in painter coordinates
leftReturns the left margin
topReturns the top margin
rightReturns the right margin
bottomReturns the bottom margin
+
+
+
Returns
The default implementation returns 0 for all margins
+
See Also
QwtPlot::getCanvasMarginsHint(), QwtPlot::updateCanvasMargins()
+ +

Reimplemented in QwtPlotAbstractBarChart.

+ +
+
+ +
+
+ + + + + + + +
bool QwtPlotItem::isVisible () const
+
+
Returns
true if visible
+
See Also
setVisible(), show(), hide()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void QwtPlotItem::itemChanged ()
+
+virtual
+
+

Update the legend and call QwtPlot::autoRefresh() for the parent plot.

+
See Also
QwtPlot::legendChanged(), QwtPlot::autoRefresh()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void QwtPlotItem::legendChanged ()
+
+virtual
+
+

Update the legend of the parent plot.

+
See Also
QwtPlot::updateLegend(), itemChanged()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
QList< QwtLegendData > QwtPlotItem::legendData () const
+
+virtual
+
+ +

Return all information, that is needed to represent the item on the legend.

+

Most items are represented by one entry on the legend showing an icon and a text, but f.e. QwtPlotMultiBarChart displays one entry for each bar.

+

QwtLegendData is basically a list of QVariants that makes it possible to overload and reimplement legendData() to return almost any type of information, that is understood by the receiver that acts as the legend.

+

The default implementation returns one entry with the title() of the item and the legendIcon().

+
Returns
Data, that is needed to represent the item on the legend
+
See Also
title(), legendIcon(), QwtLegend, QwtPlotLegendItem
+ +

Reimplemented in QwtPlotBarChart, and QwtPlotMultiBarChart.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
QwtGraphic QwtPlotItem::legendIcon (int index,
const QSizeF & size 
) const
+
+virtual
+
+
Returns
Icon representing the item on the legend
+

The default implementation returns an invalid icon

+
Parameters
+ + + +
indexIndex of the legend entry ( usually there is only one )
sizeIcon size
+
+
+
See Also
setLegendIconSize(), legendData()
+ +

Reimplemented in QwtPlotCurve, QwtPlotTradingCurve, QwtPlotMarker, QwtPlotIntervalCurve, QwtPlotHistogram, QwtPlotBarChart, QwtPlotShapeItem, and QwtPlotMultiBarChart.

+ +
+
+ +
+
+ + + + + + + +
QSize QwtPlotItem::legendIconSize () const
+
+
Returns
Legend icon size
+
See Also
setLegendIconSize(), legendIcon()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
QRectF QwtPlotItem::paintRect (const QwtScaleMapxMap,
const QwtScaleMapyMap 
) const
+
+ +

Calculate the bounding paint rectangle of 2 maps.

+
Parameters
+ + + +
xMapMaps x-values into pixel coordinates.
yMapMaps y-values into pixel coordinates.
+
+
+
Returns
Bounding paint rectangle of the scale maps, not normalized
+ +
+
+ +
+
+ + + + + + + +
uint QwtPlotItem::renderThreadCount () const
+
+
Returns
Number of threads to be used for rendering. If numThreads() is set to 0, the system specific ideal thread count is used.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
int QwtPlotItem::rtti () const
+
+virtual
+
+

Return rtti for the specific class represented. QwtPlotItem is simply a virtual interface class, and base classes will implement this method with specific rtti values so a user can differentiate them.

+

The rtti value is useful for environments, where the runtime type information is disabled and it is not possible to do a dynamic_cast<...>.

+
Returns
rtti value
+
See Also
RttiValues
+ +

Reimplemented in QwtPlotCurve, QwtPlotTradingCurve, QwtPlotShapeItem, QwtPlotSpectrogram, QwtPlotIntervalCurve, QwtPlotHistogram, QwtPlotMarker, QwtPlotBarChart, QwtPlotMultiBarChart, QwtPlotLegendItem, QwtPlotScaleItem, QwtPlotTextLabel, QwtPlotSpectroCurve, QwtPlotSvgItem, QwtPlotGrid, and QwtPlotZoneItem.

+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
QRectF QwtPlotItem::scaleRect (const QwtScaleMapxMap,
const QwtScaleMapyMap 
) const
+
+ +

Calculate the bounding scale rectangle of 2 maps.

+
Parameters
+ + + +
xMapMaps x-values into pixel coordinates.
yMapMaps y-values into pixel coordinates.
+
+
+
Returns
Bounding scale rect of the scale maps, not normalized
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtPlotItem::setAxes (int xAxis,
int yAxis 
)
+
+

Set X and Y axis

+

The item will painted according to the coordinates of its Axes.

+
Parameters
+ + + +
xAxisX Axis ( QwtPlot::xBottom or QwtPlot::xTop )
yAxisY Axis ( QwtPlot::yLeft or QwtPlot::yRight )
+
+
+
See Also
setXAxis(), setYAxis(), xAxis(), yAxis(), QwtPlot::Axis
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtPlotItem::setItemAttribute (ItemAttribute attribute,
bool on = true 
)
+
+

Toggle an item attribute

+
Parameters
+ + + +
attributeAttribute type
ontrue/false
+
+
+
See Also
testItemAttribute(), ItemInterest
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtPlotItem::setItemInterest (ItemInterest interest,
bool on = true 
)
+
+

Toggle an item interest

+
Parameters
+ + + +
interestInterest type
ontrue/false
+
+
+
See Also
testItemInterest(), ItemAttribute
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotItem::setLegendIconSize (const QSize & size)
+
+

Set the size of the legend icon

+

The default setting is 8x8 pixels

+
Parameters
+ + +
sizeSize
+
+
+
See Also
legendIconSize(), legendIcon()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtPlotItem::setRenderHint (RenderHint hint,
bool on = true 
)
+
+

Toggle an render hint

+
Parameters
+ + + +
hintRender hint
ontrue/false
+
+
+
See Also
testRenderHint(), RenderHint
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotItem::setRenderThreadCount (uint numThreads)
+
+

On multi core systems rendering of certain plot item ( f.e QwtPlotRasterItem ) can be done in parallel in several threads.

+

The default setting is set to 1.

+
Parameters
+ + +
numThreadsNumber of threads to be used for rendering. If numThreads is set to 0, the system specific ideal thread count is used.
+
+
+

The default thread count is 1 ( = no additional threads )

+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotItem::setTitle (const QString & title)
+
+

Set a new title

+
Parameters
+ + +
titleTitle
+
+
+
See Also
title()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotItem::setTitle (const QwtTexttitle)
+
+

Set a new title

+
Parameters
+ + +
titleTitle
+
+
+
See Also
title()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtPlotItem::setVisible (bool on)
+
+virtual
+
+

Show/Hide the item

+
Parameters
+ + +
onShow if true, otherwise hide
+
+
+
See Also
isVisible(), show(), hide()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotItem::setXAxis (int axis)
+
+

Set the X axis

+

The item will painted according to the coordinates its Axes.

+
Parameters
+ + +
axisX Axis ( QwtPlot::xBottom or QwtPlot::xTop )
+
+
+
See Also
setAxes(), setYAxis(), xAxis(), QwtPlot::Axis
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotItem::setYAxis (int axis)
+
+

Set the Y axis

+

The item will painted according to the coordinates its Axes.

+
Parameters
+ + +
axisY Axis ( QwtPlot::yLeft or QwtPlot::yRight )
+
+
+
See Also
setAxes(), setXAxis(), yAxis(), QwtPlot::Axis
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotItem::setZ (double z)
+
+ +

Set the z value.

+

Plot items are painted in increasing z-order.

+
Parameters
+ + +
zZ-value
+
+
+
See Also
z(), QwtPlotDict::itemList()
+ +
+
+ +
+
+ + + + + + + + +
bool QwtPlotItem::testItemAttribute (ItemAttribute attribute) const
+
+

Test an item attribute

+
Parameters
+ + +
attributeAttribute type
+
+
+
Returns
true/false
+
See Also
setItemAttribute(), ItemInterest
+ +
+
+ +
+
+ + + + + + + + +
bool QwtPlotItem::testItemInterest (ItemInterest interest) const
+
+

Test an item interest

+
Parameters
+ + +
interestInterest type
+
+
+
Returns
true/false
+
See Also
setItemInterest(), ItemAttribute
+ +
+
+ +
+
+ + + + + + + + +
bool QwtPlotItem::testRenderHint (RenderHint hint) const
+
+

Test a render hint

+
Parameters
+ + +
hintRender hint
+
+
+
Returns
true/false
+
See Also
setRenderHint(), RenderHint
+ +
+
+ +
+
+ + + + + + + +
const QwtText & QwtPlotItem::title () const
+
+
Returns
Title of the item
+
See Also
setTitle()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void QwtPlotItem::updateLegend (const QwtPlotItemitem,
const QList< QwtLegendData > & data 
)
+
+virtual
+
+ +

Update the item to changes of the legend info.

+

Plot items that want to display a legend ( not those, that want to be displayed on a legend ! ) will have to implement updateLegend().

+

updateLegend() is only called when the LegendInterest interest is enabled. The default implementation does nothing.

+
Parameters
+ + + +
itemPlot item to be displayed on a legend
dataAttributes how to display item on the legend
+
+
+
See Also
QwtPlotLegendItem
+
Note
Plot items, that want to be displayed on a legend need to enable the QwtPlotItem::Legend flag and to implement legendData() and legendIcon()
+ +

Reimplemented in QwtPlotLegendItem.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void QwtPlotItem::updateScaleDiv (const QwtScaleDivxScaleDiv,
const QwtScaleDivyScaleDiv 
)
+
+virtual
+
+ +

Update the item to changes of the axes scale division.

+

Update the item, when the axes of plot have changed. The default implementation does nothing, but items that depend on the scale division (like QwtPlotGrid()) have to reimplement updateScaleDiv()

+

updateScaleDiv() is only called when the ScaleInterest interest is enabled. The default implementation does nothing.

+
Parameters
+ + + +
xScaleDivScale division of the x-axis
yScaleDivScale division of the y-axis
+
+
+
See Also
QwtPlot::updateAxes(), ScaleInterest
+ +

Reimplemented in QwtPlotScaleItem, QwtPlotGrid, and QwtPlotSeriesItem.

+ +
+
+ +
+
+ + + + + + + +
double QwtPlotItem::z () const
+
+

Plot items are painted in increasing z-order.

+
Returns
setZ(), QwtPlotDict::itemList()
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_item__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_plot_item__inherit__graph.map new file mode 100644 index 0000000000..ab606b2d3d --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_item__inherit__graph.map @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_item__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_plot_item__inherit__graph.md5 new file mode 100644 index 0000000000..1984d38136 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_item__inherit__graph.md5 @@ -0,0 +1 @@ +528674c1feee00fcf6126f8fb42fec2a \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_item__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_plot_item__inherit__graph.png new file mode 100644 index 0000000000..4f4b749ae0 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_plot_item__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_layout-members.html b/ThirdParty/Qwt/doc/html/class_qwt_plot_layout-members.html new file mode 100644 index 0000000000..328252f5d7 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_layout-members.html @@ -0,0 +1,139 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtPlotLayout Member List
+
+
+ +

This is the complete list of members for QwtPlotLayout, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
activate(const QwtPlot *, const QRectF &rect, Options options=0x00)QwtPlotLayoutvirtual
alignCanvasToScale(int axisId) const QwtPlotLayout
alignLegend(const QRectF &canvasRect, const QRectF &legendRect) const QwtPlotLayoutprotected
AlignScales enum valueQwtPlotLayout
alignScales(Options options, QRectF &canvasRect, QRectF scaleRect[QwtPlot::axisCnt]) const QwtPlotLayoutprotected
canvasMargin(int axis) const QwtPlotLayout
canvasRect() const QwtPlotLayout
expandLineBreaks(Options options, const QRectF &rect, int &dimTitle, int &dimFooter, int dimAxes[QwtPlot::axisCnt]) const QwtPlotLayoutprotected
footerRect() const QwtPlotLayout
IgnoreFooter enum valueQwtPlotLayout
IgnoreFrames enum valueQwtPlotLayout
IgnoreLegend enum valueQwtPlotLayout
IgnoreScrollbars enum valueQwtPlotLayout
IgnoreTitle enum valueQwtPlotLayout
invalidate()QwtPlotLayoutvirtual
layoutLegend(Options options, const QRectF &) const QwtPlotLayoutprotected
legendPosition() const QwtPlotLayout
legendRatio() const QwtPlotLayout
legendRect() const QwtPlotLayout
minimumSizeHint(const QwtPlot *) const QwtPlotLayoutvirtual
Option enum nameQwtPlotLayout
Options typedefQwtPlotLayout
QwtPlotLayout()QwtPlotLayoutexplicit
scaleRect(int axis) const QwtPlotLayout
setAlignCanvasToScale(int axisId, bool)QwtPlotLayout
setAlignCanvasToScales(bool)QwtPlotLayout
setCanvasMargin(int margin, int axis=-1)QwtPlotLayout
setCanvasRect(const QRectF &)QwtPlotLayoutprotected
setFooterRect(const QRectF &)QwtPlotLayoutprotected
setLegendPosition(QwtPlot::LegendPosition pos, double ratio)QwtPlotLayout
setLegendPosition(QwtPlot::LegendPosition pos)QwtPlotLayout
setLegendRatio(double ratio)QwtPlotLayout
setLegendRect(const QRectF &)QwtPlotLayoutprotected
setScaleRect(int axis, const QRectF &)QwtPlotLayoutprotected
setSpacing(int)QwtPlotLayout
setTitleRect(const QRectF &)QwtPlotLayoutprotected
spacing() const QwtPlotLayout
titleRect() const QwtPlotLayout
~QwtPlotLayout()QwtPlotLayoutvirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_layout.html b/ThirdParty/Qwt/doc/html/class_qwt_plot_layout.html new file mode 100644 index 0000000000..f0caa6b3d0 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_layout.html @@ -0,0 +1,1125 @@ + + + + + + +Qwt User's Guide: QwtPlotLayout Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+ +
+ +

Layout engine for QwtPlot. + More...

+ +

#include <qwt_plot_layout.h>

+ + + + + + + +

+Public Types

enum  Option {
+  AlignScales = 0x01, +IgnoreScrollbars = 0x02, +IgnoreFrames = 0x04, +IgnoreLegend = 0x08, +
+  IgnoreTitle = 0x10, +IgnoreFooter = 0x20 +
+ }
 
+typedef QFlags< OptionOptions
 Layout options.
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

QwtPlotLayout ()
 Constructor.
 
+virtual ~QwtPlotLayout ()
 Destructor.
 
void setCanvasMargin (int margin, int axis=-1)
 
int canvasMargin (int axis) const
 
void setAlignCanvasToScales (bool)
 Set the align-canvas-to-axis-scales flag for all axes. More...
 
void setAlignCanvasToScale (int axisId, bool)
 
bool alignCanvasToScale (int axisId) const
 
void setSpacing (int)
 
int spacing () const
 
void setLegendPosition (QwtPlot::LegendPosition pos, double ratio)
 Specify the position of the legend. More...
 
void setLegendPosition (QwtPlot::LegendPosition pos)
 Specify the position of the legend. More...
 
QwtPlot::LegendPosition legendPosition () const
 
void setLegendRatio (double ratio)
 
double legendRatio () const
 
virtual QSize minimumSizeHint (const QwtPlot *) const
 
virtual void activate (const QwtPlot *, const QRectF &rect, Options options=0x00)
 Recalculate the geometry of all components. More...
 
virtual void invalidate ()
 
QRectF titleRect () const
 
QRectF footerRect () const
 
QRectF legendRect () const
 
QRectF scaleRect (int axis) const
 
QRectF canvasRect () const
 
+ + + + + + + + + + + + + + + + + + + + + + + + +

+Protected Member Functions

void setTitleRect (const QRectF &)
 Set the geometry for the title. More...
 
void setFooterRect (const QRectF &)
 Set the geometry for the footer. More...
 
void setLegendRect (const QRectF &)
 Set the geometry for the legend. More...
 
void setScaleRect (int axis, const QRectF &)
 Set the geometry for an axis. More...
 
void setCanvasRect (const QRectF &)
 Set the geometry for the canvas. More...
 
QRectF layoutLegend (Options options, const QRectF &) const
 
QRectF alignLegend (const QRectF &canvasRect, const QRectF &legendRect) const
 
void expandLineBreaks (Options options, const QRectF &rect, int &dimTitle, int &dimFooter, int dimAxes[QwtPlot::axisCnt]) const
 
void alignScales (Options options, QRectF &canvasRect, QRectF scaleRect[QwtPlot::axisCnt]) const
 
+

Detailed Description

+

Layout engine for QwtPlot.

+

It is used by the QwtPlot widget to organize its internal widgets or by QwtPlot::print() to render its content to a QPaintDevice like a QPrinter, QPixmap/QImage or QSvgRenderer.

+
See Also
QwtPlot::setPlotLayout()
+

Member Enumeration Documentation

+ +
+
+ + + + +
enum QwtPlotLayout::Option
+
+

Options to configure the plot layout engine

+
See Also
activate(), QwtPlotRenderer
+ + + + + + + +
Enumerator
AlignScales  +

Unused.

+
IgnoreScrollbars  +

Ignore the dimension of the scrollbars. There are no scrollbars, when the plot is not rendered to widgets.

+
IgnoreFrames  +

Ignore all frames.

+
IgnoreLegend  +

Ignore the legend.

+
IgnoreTitle  +

Ignore the title.

+
IgnoreFooter  +

Ignore the footer.

+
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPlotLayout::activate (const QwtPlotplot,
const QRectF & plotRect,
Options options = 0x00 
)
+
+virtual
+
+ +

Recalculate the geometry of all components.

+
Parameters
+ + + + +
plotPlot to be layout
plotRectRectangle where to place the components
optionsLayout options
+
+
+
See Also
invalidate(), titleRect(), footerRect() legendRect(), scaleRect(), canvasRect()
+ +
+
+ +
+
+ + + + + + + + +
bool QwtPlotLayout::alignCanvasToScale (int axisId) const
+
+

Return the align-canvas-to-axis-scales setting. The canvas may:

+
    +
  • extend beyond the axis scale ends to maximize its size
  • +
  • align with the axis scale ends to control its size.
  • +
+
Parameters
+ + +
axisIdAxis index
+
+
+
Returns
align-canvas-to-axis-scales setting
+
See Also
setAlignCanvasToScale(), setAlignCanvasToScale(), setCanvasMargin()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
QRectF QwtPlotLayout::alignLegend (const QRectF & canvasRect,
const QRectF & legendRect 
) const
+
+protected
+
+

Align the legend to the canvas

+
Parameters
+ + + +
canvasRectGeometry of the canvas
legendRectMaximum geometry for the legend
+
+
+
Returns
Geometry for the aligned legend
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPlotLayout::alignScales (Options options,
QRectF & canvasRect,
QRectF scaleRect[QwtPlot::axisCnt] 
) const
+
+protected
+
+

Align the ticks of the axis to the canvas borders using the empty corners.

+
Parameters
+ + + + +
optionsLayout options
canvasRectGeometry of the canvas ( IN/OUT )
scaleRectGeometries of the scales ( IN/OUT )
+
+
+
See Also
Options
+ +
+
+ +
+
+ + + + + + + + +
int QwtPlotLayout::canvasMargin (int axisId) const
+
+
Parameters
+ + +
axisIdAxis index
+
+
+
Returns
Margin around the scale tick borders
+
See Also
setCanvasMargin()
+ +
+
+ +
+
+ + + + + + + +
QRectF QwtPlotLayout::canvasRect () const
+
+
Returns
Geometry for the canvas
+
See Also
activate(), invalidate()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPlotLayout::expandLineBreaks (Options options,
const QRectF & rect,
int & dimTitle,
int & dimFooter,
int dimAxis[QwtPlot::axisCnt] 
) const
+
+protected
+
+

Expand all line breaks in text labels, and calculate the height of their widgets in orientation of the text.

+
Parameters
+ + + + + + +
optionsOptions how to layout the legend
rectBounding rectangle for title, footer, axes and canvas.
dimTitleExpanded height of the title widget
dimFooterExpanded height of the footer widget
dimAxisExpanded heights of the axis in axis orientation.
+
+
+
See Also
Options
+ +
+
+ +
+
+ + + + + + + +
QRectF QwtPlotLayout::footerRect () const
+
+
Returns
Geometry for the footer
+
See Also
activate(), invalidate()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void QwtPlotLayout::invalidate ()
+
+virtual
+
+

Invalidate the geometry of all components.

+
See Also
activate()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
QRectF QwtPlotLayout::layoutLegend (Options options,
const QRectF & rect 
) const
+
+protected
+
+

Find the geometry for the legend

+
Parameters
+ + + +
optionsOptions how to layout the legend
rectRectangle where to place the legend
+
+
+
Returns
Geometry for the legend
+
See Also
Options
+ +
+
+ +
+
+ + + + + + + +
QwtPlot::LegendPosition QwtPlotLayout::legendPosition () const
+
+
Returns
Position of the legend
+
See Also
setLegendPosition(), QwtPlot::setLegendPosition(), QwtPlot::legendPosition()
+ +
+
+ +
+
+ + + + + + + +
double QwtPlotLayout::legendRatio () const
+
+
Returns
The relative size of the legend in the plot.
+
See Also
setLegendPosition()
+ +
+
+ +
+
+ + + + + + + +
QRectF QwtPlotLayout::legendRect () const
+
+
Returns
Geometry for the legend
+
See Also
activate(), invalidate()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
QSize QwtPlotLayout::minimumSizeHint (const QwtPlotplot) const
+
+virtual
+
+
Returns
Minimum size hint
+
Parameters
+ + +
plotPlot widget
+
+
+
See Also
QwtPlot::minimumSizeHint()
+ +
+
+ +
+
+ + + + + + + + +
QRectF QwtPlotLayout::scaleRect (int axis) const
+
+
Parameters
+ + +
axisAxis index
+
+
+
Returns
Geometry for the scale
+
See Also
activate(), invalidate()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtPlotLayout::setAlignCanvasToScale (int axisId,
bool on 
)
+
+

Change the align-canvas-to-axis-scales setting. The canvas may:

+
    +
  • extend beyond the axis scale ends to maximize its size,
  • +
  • align with the axis scale ends to control its size.
  • +
+

The axisId parameter is somehow confusing as it identifies a border of the plot and not the axes, that are aligned. F.e when QwtPlot::yLeft is set, the left end of the the x-axes ( QwtPlot::xTop, QwtPlot::xBottom ) is aligned.

+
Parameters
+ + + +
axisIdAxis index
onNew align-canvas-to-axis-scales setting
+
+
+
See Also
setCanvasMargin(), alignCanvasToScale(), setAlignCanvasToScales()
+
Warning
In case of on == true canvasMargin() will have no effect
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotLayout::setAlignCanvasToScales (bool on)
+
+ +

Set the align-canvas-to-axis-scales flag for all axes.

+
Parameters
+ + +
onTrue/False
+
+
+
See Also
setAlignCanvasToScale(), alignCanvasToScale()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtPlotLayout::setCanvasMargin (int margin,
int axis = -1 
)
+
+

Change a margin of the canvas. The margin is the space above/below the scale ticks. A negative margin will be set to -1, excluding the borders of the scales.

+
Parameters
+ + + +
marginNew margin
axisOne of QwtPlot::Axis. Specifies where the position of the margin. -1 means margin at all borders.
+
+
+
See Also
canvasMargin()
+
Warning
The margin will have no effect when alignCanvasToScale() is true
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtPlotLayout::setCanvasRect (const QRectF & rect)
+
+protected
+
+ +

Set the geometry for the canvas.

+

This method is intended to be used from derived layouts overloading activate()

+
See Also
canvasRect(), activate()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtPlotLayout::setFooterRect (const QRectF & rect)
+
+protected
+
+ +

Set the geometry for the footer.

+

This method is intended to be used from derived layouts overloading activate()

+
See Also
footerRect(), activate()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtPlotLayout::setLegendPosition (QwtPlot::LegendPosition pos,
double ratio 
)
+
+ +

Specify the position of the legend.

+
Parameters
+ + + +
posThe legend's position.
ratioRatio between legend and the bounding rectangle of title, footer, canvas and axes. The legend will be shrunk if it would need more space than the given ratio. The ratio is limited to ]0.0 .. 1.0]. In case of <= 0.0 it will be reset to the default ratio. The default vertical/horizontal ratio is 0.33/0.5.
+
+
+
See Also
QwtPlot::setLegendPosition()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotLayout::setLegendPosition (QwtPlot::LegendPosition pos)
+
+ +

Specify the position of the legend.

+
Parameters
+ + +
posThe legend's position. Valid values are QwtPlot::LeftLegend, QwtPlot::RightLegend, QwtPlot::TopLegend, QwtPlot::BottomLegend.
+
+
+
See Also
QwtPlot::setLegendPosition()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotLayout::setLegendRatio (double ratio)
+
+

Specify the relative size of the legend in the plot

+
Parameters
+ + +
ratioRatio between legend and the bounding rectangle of title, footer, canvas and axes. The legend will be shrunk if it would need more space than the given ratio. The ratio is limited to ]0.0 .. 1.0]. In case of <= 0.0 it will be reset to the default ratio. The default vertical/horizontal ratio is 0.33/0.5.
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtPlotLayout::setLegendRect (const QRectF & rect)
+
+protected
+
+ +

Set the geometry for the legend.

+

This method is intended to be used from derived layouts overloading activate()

+
Parameters
+ + +
rectRectangle for the legend
+
+
+
See Also
legendRect(), activate()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void QwtPlotLayout::setScaleRect (int axis,
const QRectF & rect 
)
+
+protected
+
+ +

Set the geometry for an axis.

+

This method is intended to be used from derived layouts overloading activate()

+
Parameters
+ + + +
axisAxis index
rectRectangle for the scale
+
+
+
See Also
scaleRect(), activate()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotLayout::setSpacing (int spacing)
+
+

Change the spacing of the plot. The spacing is the distance between the plot components.

+
Parameters
+ + +
spacingNew spacing
+
+
+
See Also
setCanvasMargin(), spacing()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtPlotLayout::setTitleRect (const QRectF & rect)
+
+protected
+
+ +

Set the geometry for the title.

+

This method is intended to be used from derived layouts overloading activate()

+
See Also
titleRect(), activate()
+ +
+
+ +
+
+ + + + + + + +
int QwtPlotLayout::spacing () const
+
+
Returns
Spacing
+
See Also
margin(), setSpacing()
+ +
+
+ +
+
+ + + + + + + +
QRectF QwtPlotLayout::titleRect () const
+
+
Returns
Geometry for the title
+
See Also
activate(), invalidate()
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_legend_item-members.html b/ThirdParty/Qwt/doc/html/class_qwt_plot_legend_item-members.html new file mode 100644 index 0000000000..d96b4e8f88 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_legend_item-members.html @@ -0,0 +1,212 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtPlotLegendItem Member List
+
+
+ +

This is the complete list of members for QwtPlotLegendItem, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
alignment() const QwtPlotLegendItem
attach(QwtPlot *plot)QwtPlotItem
AutoScale enum valueQwtPlotItem
backgroundBrush() const QwtPlotLegendItem
BackgroundMode enum nameQwtPlotLegendItem
backgroundMode() const QwtPlotLegendItem
borderDistance() const QwtPlotLegendItem
borderPen() const QwtPlotLegendItem
borderRadius() const QwtPlotLegendItem
boundingRect() const QwtPlotItemvirtual
clearLegend()QwtPlotLegendItem
defaultIcon(const QBrush &, const QSizeF &) const QwtPlotItemprotected
detach()QwtPlotItem
draw(QPainter *p, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &rect) const QwtPlotLegendItemvirtual
drawBackground(QPainter *, const QRectF &rect) const QwtPlotLegendItemprotectedvirtual
drawLegendData(QPainter *painter, const QwtPlotItem *, const QwtLegendData &, const QRectF &) const QwtPlotLegendItemprotectedvirtual
font() const QwtPlotLegendItem
geometry(const QRectF &canvasRect) const QwtPlotLegendItemvirtual
getCanvasMarginHint(const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasSize, double &left, double &top, double &right, double &bottom) const QwtPlotItemvirtual
heightForWidth(const QwtLegendData &, int w) const QwtPlotLegendItemvirtual
hide()QwtPlotItem
isVisible() const QwtPlotItem
ItemAttribute enum nameQwtPlotItem
ItemAttributes typedefQwtPlotItem
ItemBackground enum valueQwtPlotLegendItem
itemChanged()QwtPlotItemvirtual
ItemInterest enum nameQwtPlotItem
ItemInterests typedefQwtPlotItem
itemMargin() const QwtPlotLegendItem
itemSpacing() const QwtPlotLegendItem
Legend enum valueQwtPlotItem
LegendBackground enum valueQwtPlotLegendItem
legendChanged()QwtPlotItemvirtual
legendData() const QwtPlotItemvirtual
legendGeometries(const QwtPlotItem *) const QwtPlotLegendItem
legendIcon(int index, const QSizeF &) const QwtPlotItemvirtual
legendIconSize() const QwtPlotItem
LegendInterest enum valueQwtPlotItem
margin() const QwtPlotLegendItem
Margins enum valueQwtPlotItem
maxColumns() const QwtPlotLegendItem
minimumSize(const QwtLegendData &) const QwtPlotLegendItemvirtual
paintRect(const QwtScaleMap &, const QwtScaleMap &) const QwtPlotItem
plot() const QwtPlotItem
plotItems() const QwtPlotLegendItem
QwtPlotItem(const QwtText &title=QwtText())QwtPlotItemexplicit
QwtPlotLegendItem()QwtPlotLegendItemexplicit
RenderAntialiased enum valueQwtPlotItem
RenderHint enum nameQwtPlotItem
RenderHints typedefQwtPlotItem
renderThreadCount() const QwtPlotItem
rtti() const QwtPlotLegendItemvirtual
Rtti_PlotBarChart enum valueQwtPlotItem
Rtti_PlotCurve enum valueQwtPlotItem
Rtti_PlotGrid enum valueQwtPlotItem
Rtti_PlotHistogram enum valueQwtPlotItem
Rtti_PlotIntervalCurve enum valueQwtPlotItem
Rtti_PlotItem enum valueQwtPlotItem
Rtti_PlotLegend enum valueQwtPlotItem
Rtti_PlotMarker enum valueQwtPlotItem
Rtti_PlotMultiBarChart enum valueQwtPlotItem
Rtti_PlotScale enum valueQwtPlotItem
Rtti_PlotShape enum valueQwtPlotItem
Rtti_PlotSpectroCurve enum valueQwtPlotItem
Rtti_PlotSpectrogram enum valueQwtPlotItem
Rtti_PlotSVG enum valueQwtPlotItem
Rtti_PlotTextLabel enum valueQwtPlotItem
Rtti_PlotTradingCurve enum valueQwtPlotItem
Rtti_PlotUserItem enum valueQwtPlotItem
Rtti_PlotZone enum valueQwtPlotItem
RttiValues enum nameQwtPlotItem
ScaleInterest enum valueQwtPlotItem
scaleRect(const QwtScaleMap &, const QwtScaleMap &) const QwtPlotItem
setAlignment(Qt::Alignment)QwtPlotLegendItem
setAxes(int xAxis, int yAxis)QwtPlotItem
setBackgroundBrush(const QBrush &)QwtPlotLegendItem
setBackgroundMode(BackgroundMode)QwtPlotLegendItem
setBorderDistance(int numPixels)QwtPlotLegendItem
setBorderPen(const QPen &)QwtPlotLegendItem
setBorderRadius(double)QwtPlotLegendItem
setFont(const QFont &)QwtPlotLegendItem
setItemAttribute(ItemAttribute, bool on=true)QwtPlotItem
setItemInterest(ItemInterest, bool on=true)QwtPlotItem
setItemMargin(int)QwtPlotLegendItem
setItemSpacing(int)QwtPlotLegendItem
setLegendIconSize(const QSize &)QwtPlotItem
setMargin(int)QwtPlotLegendItem
setMaxColumns(uint)QwtPlotLegendItem
setRenderHint(RenderHint, bool on=true)QwtPlotItem
setRenderThreadCount(uint numThreads)QwtPlotItem
setSpacing(int)QwtPlotLegendItem
setTextPen(const QPen &)QwtPlotLegendItem
setTitle(const QString &title)QwtPlotItem
setTitle(const QwtText &title)QwtPlotItem
setVisible(bool)QwtPlotItemvirtual
setXAxis(int axis)QwtPlotItem
setYAxis(int axis)QwtPlotItem
setZ(double z)QwtPlotItem
show()QwtPlotItem
spacing() const QwtPlotLegendItem
testItemAttribute(ItemAttribute) const QwtPlotItem
testItemInterest(ItemInterest) const QwtPlotItem
testRenderHint(RenderHint) const QwtPlotItem
textPen() const QwtPlotLegendItem
title() const QwtPlotItem
updateLegend(const QwtPlotItem *, const QList< QwtLegendData > &)QwtPlotLegendItemvirtual
updateScaleDiv(const QwtScaleDiv &, const QwtScaleDiv &)QwtPlotItemvirtual
xAxis() const QwtPlotItem
yAxis() const QwtPlotItem
z() const QwtPlotItem
~QwtPlotItem()QwtPlotItemvirtual
~QwtPlotLegendItem()QwtPlotLegendItemvirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_legend_item.html b/ThirdParty/Qwt/doc/html/class_qwt_plot_legend_item.html new file mode 100644 index 0000000000..40a843bc4f --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_legend_item.html @@ -0,0 +1,1321 @@ + + + + + + +Qwt User's Guide: QwtPlotLegendItem Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtPlotLegendItem Class Reference
+
+
+ +

A class which draws a legend inside the plot canvas. + More...

+ +

#include <qwt_plot_legenditem.h>

+
+Inheritance diagram for QwtPlotLegendItem:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Types

enum  BackgroundMode { LegendBackground, +ItemBackground + }
 Background mode. More...
 
- Public Types inherited from QwtPlotItem
enum  RttiValues {
+  Rtti_PlotItem = 0, +Rtti_PlotGrid, +Rtti_PlotScale, +Rtti_PlotLegend, +
+  Rtti_PlotMarker, +Rtti_PlotCurve, +Rtti_PlotSpectroCurve, +Rtti_PlotIntervalCurve, +
+  Rtti_PlotHistogram, +Rtti_PlotSpectrogram, +Rtti_PlotSVG, +Rtti_PlotTradingCurve, +
+  Rtti_PlotBarChart, +Rtti_PlotMultiBarChart, +Rtti_PlotShape, +Rtti_PlotTextLabel, +
+  Rtti_PlotZone, +Rtti_PlotUserItem = 1000 +
+ }
 Runtime type information. More...
 
enum  ItemAttribute { Legend = 0x01, +AutoScale = 0x02, +Margins = 0x04 + }
 Plot Item Attributes. More...
 
enum  ItemInterest { ScaleInterest = 0x01, +LegendInterest = 0x02 + }
 Plot Item Interests. More...
 
enum  RenderHint { RenderAntialiased = 0x1 + }
 Render hints. More...
 
+typedef QFlags< ItemAttributeItemAttributes
 Plot Item Attributes.
 
+typedef QFlags< ItemInterestItemInterests
 Plot Item Interests.
 
+typedef QFlags< RenderHintRenderHints
 Render hints.
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

QwtPlotLegendItem ()
 Constructor.
 
+virtual ~QwtPlotLegendItem ()
 Destructor.
 
virtual int rtti () const
 
void setAlignment (Qt::Alignment)
 Set the alignmnet. More...
 
Qt::Alignment alignment () const
 
void setMaxColumns (uint)
 Limit the number of columns. More...
 
uint maxColumns () const
 
void setMargin (int)
 Set the margin around legend items. More...
 
int margin () const
 
void setSpacing (int)
 Set the spacing between the legend items. More...
 
int spacing () const
 
void setItemMargin (int)
 
int itemMargin () const
 
void setItemSpacing (int)
 
int itemSpacing () const
 
void setFont (const QFont &)
 
QFont font () const
 
void setBorderDistance (int numPixels)
 Set the margin between the legend and the canvas border. More...
 
int borderDistance () const
 
void setBorderRadius (double)
 
double borderRadius () const
 
void setBorderPen (const QPen &)
 
QPen borderPen () const
 
void setBackgroundBrush (const QBrush &)
 Set the background brush. More...
 
QBrush backgroundBrush () const
 
void setBackgroundMode (BackgroundMode)
 Set the background mode. More...
 
BackgroundMode backgroundMode () const
 
void setTextPen (const QPen &)
 Set the pen for drawing text labels. More...
 
QPen textPen () const
 
virtual void draw (QPainter *p, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &rect) const
 
+void clearLegend ()
 Remove all items from the legend.
 
virtual void updateLegend (const QwtPlotItem *, const QList< QwtLegendData > &)
 
virtual QRect geometry (const QRectF &canvasRect) const
 
virtual QSize minimumSize (const QwtLegendData &) const
 
virtual int heightForWidth (const QwtLegendData &, int w) const
 
QList< const QwtPlotItem * > plotItems () const
 
QList< QRect > legendGeometries (const QwtPlotItem *) const
 
- Public Member Functions inherited from QwtPlotItem
 QwtPlotItem (const QwtText &title=QwtText())
 
+virtual ~QwtPlotItem ()
 Destroy the QwtPlotItem.
 
void attach (QwtPlot *plot)
 Attach the item to a plot. More...
 
void detach ()
 This method detaches a QwtPlotItem from any QwtPlot it has been associated with. More...
 
+QwtPlotplot () const
 Return attached plot.
 
void setTitle (const QString &title)
 
void setTitle (const QwtText &title)
 
const QwtTexttitle () const
 
void setItemAttribute (ItemAttribute, bool on=true)
 
bool testItemAttribute (ItemAttribute) const
 
void setItemInterest (ItemInterest, bool on=true)
 
bool testItemInterest (ItemInterest) const
 
void setRenderHint (RenderHint, bool on=true)
 
bool testRenderHint (RenderHint) const
 
void setRenderThreadCount (uint numThreads)
 
uint renderThreadCount () const
 
void setLegendIconSize (const QSize &)
 
QSize legendIconSize () const
 
double z () const
 
void setZ (double z)
 Set the z value. More...
 
+void show ()
 Show the item.
 
+void hide ()
 Hide the item.
 
virtual void setVisible (bool)
 
bool isVisible () const
 
void setAxes (int xAxis, int yAxis)
 
void setXAxis (int axis)
 
+int xAxis () const
 Return xAxis.
 
void setYAxis (int axis)
 
+int yAxis () const
 Return yAxis.
 
virtual void itemChanged ()
 
virtual void legendChanged ()
 
virtual QRectF boundingRect () const
 
virtual void getCanvasMarginHint (const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasSize, double &left, double &top, double &right, double &bottom) const
 Calculate a hint for the canvas margin. More...
 
virtual void updateScaleDiv (const QwtScaleDiv &, const QwtScaleDiv &)
 Update the item to changes of the axes scale division. More...
 
QRectF scaleRect (const QwtScaleMap &, const QwtScaleMap &) const
 Calculate the bounding scale rectangle of 2 maps. More...
 
QRectF paintRect (const QwtScaleMap &, const QwtScaleMap &) const
 Calculate the bounding paint rectangle of 2 maps. More...
 
virtual QList< QwtLegendDatalegendData () const
 Return all information, that is needed to represent the item on the legend. More...
 
virtual QwtGraphic legendIcon (int index, const QSizeF &) const
 
+ + + + + + + + + +

+Protected Member Functions

virtual void drawLegendData (QPainter *painter, const QwtPlotItem *, const QwtLegendData &, const QRectF &) const
 
virtual void drawBackground (QPainter *, const QRectF &rect) const
 
- Protected Member Functions inherited from QwtPlotItem
QwtGraphic defaultIcon (const QBrush &, const QSizeF &) const
 Return a default icon from a brush. More...
 
+

Detailed Description

+

A class which draws a legend inside the plot canvas.

+

QwtPlotLegendItem can be used to draw a inside the plot canvas. It can be used together with a QwtLegend or instead of it to have more space for the plot canvas.

+

In opposite to QwtLegend the legend item is not interactive. To identify mouse clicks on a legend item an event filter needs to be installed catching mouse events ob the plot canvas. The geometries of the legend items are available using legendGeometries().

+

The legend item is aligned to plot canvas according to its alignment() flags. It might have a background for the complete legend ( usually semi transparent ) or for each legend item.

+
Note
An external QwtLegend with a transparent background on top the plot canvas might be another option with a similar effect.
+

Member Enumeration Documentation

+ +
+
+ +

Background mode.

+

Depending on the mode the complete legend or each item might have an background.

+

The default setting is LegendBackground.

+
See Also
setBackgroundMode(), setBackgroundBrush(), drawBackground()
+ + + +
Enumerator
LegendBackground  +

The legend has a background.

+
ItemBackground  +

Each item has a background.

+
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + + + +
Qt::Alignment QwtPlotLegendItem::alignment () const
+
+
Returns
Alignment flags
+
See Also
setAlignment()
+ +
+
+ +
+
+ + + + + + + +
QBrush QwtPlotLegendItem::backgroundBrush () const
+
+
Returns
Brush is used to fill the background
+
See Also
setBackgroundBrush(), backgroundMode(), drawBackground()
+ +
+
+ +
+
+ + + + + + + +
QwtPlotLegendItem::BackgroundMode QwtPlotLegendItem::backgroundMode () const
+
+
Returns
backgroundMode
+
See Also
setBackgroundMode(), backgroundBrush(), drawBackground()
+ +
+
+ +
+
+ + + + + + + +
int QwtPlotLegendItem::borderDistance () const
+
+
Returns
Margin between the legend and the canvas border
+
See Also
margin()
+ +
+
+ +
+
+ + + + + + + +
QPen QwtPlotLegendItem::borderPen () const
+
+
Returns
Pen for drawing the border
+
See Also
setBorderPen(), backgroundBrush()
+ +
+
+ +
+
+ + + + + + + +
double QwtPlotLegendItem::borderRadius () const
+
+
Returns
Radius of the border
+
See Also
setBorderRadius(), setBorderPen()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPlotLegendItem::draw (QPainter * painter,
const QwtScaleMapxMap,
const QwtScaleMapyMap,
const QRectF & canvasRect 
) const
+
+virtual
+
+

Draw the legend

+
Parameters
+ + + + + +
painterPainter
xMapx Scale Map
yMapy Scale Map
canvasRectContents rectangle of the canvas in painter coordinates
+
+
+ +

Implements QwtPlotItem.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void QwtPlotLegendItem::drawBackground (QPainter * painter,
const QRectF & rect 
) const
+
+protectedvirtual
+
+

Draw a rounded rect

+
Parameters
+ + + +
painterPainter
rectBounding rectangle
+
+
+
See Also
setBorderRadius(), setBorderPen(), setBackgroundBrush(), setBackgroundMode()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPlotLegendItem::drawLegendData (QPainter * painter,
const QwtPlotItemplotItem,
const QwtLegendDatadata,
const QRectF & rect 
) const
+
+protectedvirtual
+
+

Draw an entry on the legend

+
Parameters
+ + + + + +
painterQt Painter
plotItemPlot item, represented by the entry
dataAttributes of the legend entry
rectBounding rectangle for the entry
+
+
+ +
+
+ +
+
+ + + + + + + +
QFont QwtPlotLegendItem::font () const
+
+
Returns
Font used for drawing the text label
+
See Also
setFont()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
QRect QwtPlotLegendItem::geometry (const QRectF & canvasRect) const
+
+virtual
+
+

Calculate the geometry of the legend on the canvas

+
Parameters
+ + +
canvasRectGeometry of the canvas
+
+
+
Returns
Geometry of the legend
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
int QwtPlotLegendItem::heightForWidth (const QwtLegendDatadata,
int width 
) const
+
+virtual
+
+
Returns
The preferred height, for a width.
+
Parameters
+ + + +
dataAttributes of the legend entry
widthWidth
+
+
+ +
+
+ +
+
+ + + + + + + +
int QwtPlotLegendItem::itemMargin () const
+
+
Returns
Margin around each item
+
See Also
setItemMargin(), itemSpacing(), margin(), spacing()
+ +
+
+ +
+
+ + + + + + + +
int QwtPlotLegendItem::itemSpacing () const
+
+
Returns
Spacing inside of each item
+
See Also
setItemSpacing(), itemMargin(), margin(), spacing()
+ +
+
+ +
+
+ + + + + + + + +
QList< QRect > QwtPlotLegendItem::legendGeometries (const QwtPlotItemplotItem) const
+
+
Returns
Geometries of the items of a plot item
+
Note
Usually a plot item has only one entry on the legend
+ +
+
+ +
+
+ + + + + + + +
int QwtPlotLegendItem::margin () const
+
+
Returns
Margin around the legend items
+
See Also
setMargin(), spacing(), itemMargin(), itemSpacing()
+ +
+
+ +
+
+ + + + + + + +
uint QwtPlotLegendItem::maxColumns () const
+
+
Returns
Maximum number of columns
+
See Also
maxColumns(), QwtDynGridLayout::maxColumns()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
QSize QwtPlotLegendItem::minimumSize (const QwtLegendDatadata) const
+
+virtual
+
+

Minimum size hint needed to display an entry

+
Parameters
+ + +
dataAttributes of the legend entry
+
+
+
Returns
Minimum size
+ +
+
+ +
+
+ + + + + + + +
QList< const QwtPlotItem * > QwtPlotLegendItem::plotItems () const
+
+
Returns
All plot items with an entry on the legend
+
Note
A plot item might have more than one entry on the legend
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
int QwtPlotLegendItem::rtti () const
+
+virtual
+
+
Returns
QwtPlotItem::Rtti_PlotLegend
+ +

Reimplemented from QwtPlotItem.

+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotLegendItem::setAlignment (Qt::Alignment alignment)
+
+ +

Set the alignmnet.

+

Alignment means the position of the legend relative to the geometry of the plot canvas.

+
Parameters
+ + +
alignmentAlignment flags
+
+
+
See Also
alignment(), setMaxColumns()
+
Note
To align a legend with many items horizontally the number of columns need to be limited
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotLegendItem::setBackgroundBrush (const QBrush & brush)
+
+ +

Set the background brush.

+

The brush is used to fill the background

+
Parameters
+ + +
brushBrush
+
+
+
See Also
backgroundBrush(), setBackgroundMode(), drawBackground()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotLegendItem::setBackgroundMode (BackgroundMode mode)
+
+ +

Set the background mode.

+

Depending on the mode the complete legend or each item might have an background.

+

The default setting is LegendBackground.

+
See Also
backgroundMode(), setBackgroundBrush(), drawBackground()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotLegendItem::setBorderDistance (int distance)
+
+ +

Set the margin between the legend and the canvas border.

+

The default setting for the margin is 10 pixels.

+
Parameters
+ + +
distanceMargin in pixels
+
+
+
See Also
setMargin()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotLegendItem::setBorderPen (const QPen & pen)
+
+

Set the pen for drawing the border

+
Parameters
+ + +
penBorder pen
+
+
+
See Also
borderPen(), setBackgroundBrush()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotLegendItem::setBorderRadius (double radius)
+
+

Set the radius for the border

+
Parameters
+ + +
radiusA value <= 0 defines a rectangular border
+
+
+
See Also
borderRadius(), setBorderPen()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotLegendItem::setFont (const QFont & font)
+
+

Change the font used for drawing the text label

+
Parameters
+ + +
fontLegend font
+
+
+
See Also
font()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotLegendItem::setItemMargin (int margin)
+
+

Set the margin around each item

+
Parameters
+ + +
marginMargin
+
+
+
See Also
itemMargin(), setItemSpacing(), setMargin(), setSpacing()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotLegendItem::setItemSpacing (int spacing)
+
+

Set the spacing inside of each item

+
Parameters
+ + +
spacingSpacing
+
+
+
See Also
itemSpacing(), setItemMargin(), setMargin(), setSpacing()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotLegendItem::setMargin (int margin)
+
+ +

Set the margin around legend items.

+

The default setting for the margin is 0.

+
Parameters
+ + +
marginMargin in pixels
+
+
+
See Also
margin(), setSpacing(), setItemMargin(), setItemSpacing
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotLegendItem::setMaxColumns (uint maxColumns)
+
+ +

Limit the number of columns.

+

When aligning the legend horizontally ( Qt::AlignLeft, Qt::AlignRight ) the number of columns needs to be limited to avoid, that the width of the legend grows with an increasing number of entries.

+
Parameters
+ + +
maxColumnsMaximum number of columns. 0 means unlimited.
+
+
+
See Also
maxColumns(), QwtDynGridLayout::setMaxColumns()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotLegendItem::setSpacing (int spacing)
+
+ +

Set the spacing between the legend items.

+
Parameters
+ + +
spacingSpacing in pixels
+
+
+
See Also
spacing(), setMargin()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotLegendItem::setTextPen (const QPen & pen)
+
+ +

Set the pen for drawing text labels.

+
Parameters
+ + +
penText pen
+
+
+
See Also
textPen(), setFont()
+ +
+
+ +
+
+ + + + + + + +
int QwtPlotLegendItem::spacing () const
+
+
Returns
Spacing between the legend items
+
See Also
setSpacing(), margin(), itemSpacing(), itemMargin()
+ +
+
+ +
+
+ + + + + + + +
QPen QwtPlotLegendItem::textPen () const
+
+
Returns
Pen for drawing text labels
+
See Also
setTextPen(), font()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void QwtPlotLegendItem::updateLegend (const QwtPlotItemplotItem,
const QList< QwtLegendData > & data 
)
+
+virtual
+
+

Update the legend items according to modifications of a plot item

+
Parameters
+ + + +
plotItemPlot item
dataAttributes of the legend entries
+
+
+ +

Reimplemented from QwtPlotItem.

+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_legend_item__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_plot_legend_item__inherit__graph.map new file mode 100644 index 0000000000..6b134b7d61 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_legend_item__inherit__graph.map @@ -0,0 +1,3 @@ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_legend_item__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_plot_legend_item__inherit__graph.md5 new file mode 100644 index 0000000000..26e790d4e8 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_legend_item__inherit__graph.md5 @@ -0,0 +1 @@ +59c27baeab8e458bd24527cb47a9e5b6 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_legend_item__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_plot_legend_item__inherit__graph.png new file mode 100644 index 0000000000..2221f2bce2 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_plot_legend_item__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_magnifier-members.html b/ThirdParty/Qwt/doc/html/class_qwt_plot_magnifier-members.html new file mode 100644 index 0000000000..853148aedd --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_magnifier-members.html @@ -0,0 +1,136 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtPlotMagnifier Member List
+
+
+ +

This is the complete list of members for QwtPlotMagnifier, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
canvas()QwtPlotMagnifier
canvas() const QwtPlotMagnifier
eventFilter(QObject *, QEvent *)QwtMagnifiervirtual
getMouseButton(Qt::MouseButton &, Qt::KeyboardModifiers &) const QwtMagnifier
getZoomInKey(int &key, Qt::KeyboardModifiers &) const QwtMagnifier
getZoomOutKey(int &key, Qt::KeyboardModifiers &) const QwtMagnifier
isAxisEnabled(int axis) const QwtPlotMagnifier
isEnabled() const QwtMagnifier
keyFactor() const QwtMagnifier
mouseFactor() const QwtMagnifier
parentWidget()QwtMagnifier
parentWidget() const QwtMagnifier
plot()QwtPlotMagnifier
plot() const QwtPlotMagnifier
QwtMagnifier(QWidget *)QwtMagnifierexplicit
QwtPlotMagnifier(QWidget *)QwtPlotMagnifierexplicit
rescale(double factor)QwtPlotMagnifierprotectedvirtual
setAxisEnabled(int axis, bool on)QwtPlotMagnifier
setEnabled(bool)QwtMagnifier
setKeyFactor(double)QwtMagnifier
setMouseButton(Qt::MouseButton, Qt::KeyboardModifiers=Qt::NoModifier)QwtMagnifier
setMouseFactor(double)QwtMagnifier
setWheelFactor(double)QwtMagnifier
setWheelModifiers(Qt::KeyboardModifiers)QwtMagnifier
setZoomInKey(int key, Qt::KeyboardModifiers=Qt::NoModifier)QwtMagnifier
setZoomOutKey(int key, Qt::KeyboardModifiers=Qt::NoModifier)QwtMagnifier
wheelFactor() const QwtMagnifier
wheelModifiers() const QwtMagnifier
widgetKeyPressEvent(QKeyEvent *)QwtMagnifierprotectedvirtual
widgetKeyReleaseEvent(QKeyEvent *)QwtMagnifierprotectedvirtual
widgetMouseMoveEvent(QMouseEvent *)QwtMagnifierprotectedvirtual
widgetMousePressEvent(QMouseEvent *)QwtMagnifierprotectedvirtual
widgetMouseReleaseEvent(QMouseEvent *)QwtMagnifierprotectedvirtual
widgetWheelEvent(QWheelEvent *)QwtMagnifierprotectedvirtual
~QwtMagnifier()QwtMagnifiervirtual
~QwtPlotMagnifier()QwtPlotMagnifiervirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_magnifier.html b/ThirdParty/Qwt/doc/html/class_qwt_plot_magnifier.html new file mode 100644 index 0000000000..c6bd9b8467 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_magnifier.html @@ -0,0 +1,347 @@ + + + + + + +Qwt User's Guide: QwtPlotMagnifier Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtPlotMagnifier Class Reference
+
+
+ +

QwtPlotMagnifier provides zooming, by magnifying in steps. + More...

+ +

#include <qwt_plot_magnifier.h>

+
+Inheritance diagram for QwtPlotMagnifier:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 QwtPlotMagnifier (QWidget *)
 
+virtual ~QwtPlotMagnifier ()
 Destructor.
 
void setAxisEnabled (int axis, bool on)
 En/Disable an axis. More...
 
bool isAxisEnabled (int axis) const
 
+QWidget * canvas ()
 Return observed plot canvas.
 
+const QWidget * canvas () const
 Return Observed plot canvas.
 
+QwtPlotplot ()
 Return plot widget, containing the observed plot canvas.
 
+const QwtPlotplot () const
 Return plot widget, containing the observed plot canvas.
 
- Public Member Functions inherited from QwtMagnifier
 QwtMagnifier (QWidget *)
 
+virtual ~QwtMagnifier ()
 Destructor.
 
QWidget * parentWidget ()
 
const QWidget * parentWidget () const
 
void setEnabled (bool)
 En/disable the magnifier. More...
 
bool isEnabled () const
 
void setMouseFactor (double)
 Change the mouse factor. More...
 
double mouseFactor () const
 
void setMouseButton (Qt::MouseButton, Qt::KeyboardModifiers=Qt::NoModifier)
 
void getMouseButton (Qt::MouseButton &, Qt::KeyboardModifiers &) const
 
void setWheelFactor (double)
 Change the wheel factor. More...
 
double wheelFactor () const
 
void setWheelModifiers (Qt::KeyboardModifiers)
 
Qt::KeyboardModifiers wheelModifiers () const
 
void setKeyFactor (double)
 Change the key factor. More...
 
double keyFactor () const
 
void setZoomInKey (int key, Qt::KeyboardModifiers=Qt::NoModifier)
 
void getZoomInKey (int &key, Qt::KeyboardModifiers &) const
 Retrieve the settings of the zoom in key. More...
 
void setZoomOutKey (int key, Qt::KeyboardModifiers=Qt::NoModifier)
 
void getZoomOutKey (int &key, Qt::KeyboardModifiers &) const
 Retrieve the settings of the zoom out key. More...
 
virtual bool eventFilter (QObject *, QEvent *)
 Event filter. More...
 
+ + + + + + + + + + + + + + + + +

+Protected Member Functions

virtual void rescale (double factor)
 
- Protected Member Functions inherited from QwtMagnifier
virtual void widgetMousePressEvent (QMouseEvent *)
 
virtual void widgetMouseReleaseEvent (QMouseEvent *)
 
virtual void widgetMouseMoveEvent (QMouseEvent *)
 
virtual void widgetWheelEvent (QWheelEvent *)
 
virtual void widgetKeyPressEvent (QKeyEvent *)
 
virtual void widgetKeyReleaseEvent (QKeyEvent *)
 
+

Detailed Description

+

QwtPlotMagnifier provides zooming, by magnifying in steps.

+

Using QwtPlotMagnifier a plot can be zoomed in/out in steps using keys, the mouse wheel or moving a mouse button in vertical direction.

+

Together with QwtPlotZoomer and QwtPlotPanner it is possible to implement individual and powerful navigation of the plot canvas.

+
See Also
QwtPlotZoomer, QwtPlotPanner, QwtPlot
+

Constructor & Destructor Documentation

+ +
+
+ + + + + +
+ + + + + + + + +
QwtPlotMagnifier::QwtPlotMagnifier (QWidget * canvas)
+
+explicit
+
+

Constructor

+
Parameters
+ + +
canvasPlot canvas to be magnified
+
+
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + + + + +
bool QwtPlotMagnifier::isAxisEnabled (int axis) const
+
+

Test if an axis is enabled

+
Parameters
+ + +
axisAxis, see QwtPlot::Axis
+
+
+
Returns
True, if the axis is enabled
+
See Also
setAxisEnabled()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtPlotMagnifier::rescale (double factor)
+
+protectedvirtual
+
+

Zoom in/out the axes scales

+
Parameters
+ + +
factorA value < 1.0 zooms in, a value > 1.0 zooms out.
+
+
+ +

Implements QwtMagnifier.

+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtPlotMagnifier::setAxisEnabled (int axis,
bool on 
)
+
+ +

En/Disable an axis.

+

Only Axes that are enabled will be zoomed. All other axes will remain unchanged.

+
Parameters
+ + + +
axisAxis, see QwtPlot::Axis
onOn/Off
+
+
+
See Also
isAxisEnabled()
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_magnifier__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_plot_magnifier__inherit__graph.map new file mode 100644 index 0000000000..fc000f33ca --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_magnifier__inherit__graph.map @@ -0,0 +1,3 @@ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_magnifier__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_plot_magnifier__inherit__graph.md5 new file mode 100644 index 0000000000..a66240afb8 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_magnifier__inherit__graph.md5 @@ -0,0 +1 @@ +be66098c4e922f503823c87aa6f6e65d \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_magnifier__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_plot_magnifier__inherit__graph.png new file mode 100644 index 0000000000..351eddedc7 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_plot_magnifier__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_marker-members.html b/ThirdParty/Qwt/doc/html/class_qwt_plot_marker-members.html new file mode 100644 index 0000000000..b6575bfb4e --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_marker-members.html @@ -0,0 +1,205 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtPlotMarker Member List
+
+
+ +

This is the complete list of members for QwtPlotMarker, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
attach(QwtPlot *plot)QwtPlotItem
AutoScale enum valueQwtPlotItem
boundingRect() const QwtPlotMarkervirtual
Cross enum valueQwtPlotMarker
defaultIcon(const QBrush &, const QSizeF &) const QwtPlotItemprotected
detach()QwtPlotItem
draw(QPainter *p, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &) const QwtPlotMarkervirtual
drawLabel(QPainter *, const QRectF &, const QPointF &) const QwtPlotMarkerprotectedvirtual
drawLines(QPainter *, const QRectF &, const QPointF &) const QwtPlotMarkerprotectedvirtual
getCanvasMarginHint(const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasSize, double &left, double &top, double &right, double &bottom) const QwtPlotItemvirtual
hide()QwtPlotItem
HLine enum valueQwtPlotMarker
isVisible() const QwtPlotItem
ItemAttribute enum nameQwtPlotItem
ItemAttributes typedefQwtPlotItem
itemChanged()QwtPlotItemvirtual
ItemInterest enum nameQwtPlotItem
ItemInterests typedefQwtPlotItem
label() const QwtPlotMarker
labelAlignment() const QwtPlotMarker
labelOrientation() const QwtPlotMarker
Legend enum valueQwtPlotItem
legendChanged()QwtPlotItemvirtual
legendData() const QwtPlotItemvirtual
legendIcon(int index, const QSizeF &) const QwtPlotMarkervirtual
legendIconSize() const QwtPlotItem
LegendInterest enum valueQwtPlotItem
linePen() const QwtPlotMarker
lineStyle() const QwtPlotMarker
LineStyle enum nameQwtPlotMarker
Margins enum valueQwtPlotItem
NoLine enum valueQwtPlotMarker
paintRect(const QwtScaleMap &, const QwtScaleMap &) const QwtPlotItem
plot() const QwtPlotItem
QwtPlotItem(const QwtText &title=QwtText())QwtPlotItemexplicit
QwtPlotMarker(const QString &title=QString::null)QwtPlotMarkerexplicit
QwtPlotMarker(const QwtText &title)QwtPlotMarkerexplicit
RenderAntialiased enum valueQwtPlotItem
RenderHint enum nameQwtPlotItem
RenderHints typedefQwtPlotItem
renderThreadCount() const QwtPlotItem
rtti() const QwtPlotMarkervirtual
Rtti_PlotBarChart enum valueQwtPlotItem
Rtti_PlotCurve enum valueQwtPlotItem
Rtti_PlotGrid enum valueQwtPlotItem
Rtti_PlotHistogram enum valueQwtPlotItem
Rtti_PlotIntervalCurve enum valueQwtPlotItem
Rtti_PlotItem enum valueQwtPlotItem
Rtti_PlotLegend enum valueQwtPlotItem
Rtti_PlotMarker enum valueQwtPlotItem
Rtti_PlotMultiBarChart enum valueQwtPlotItem
Rtti_PlotScale enum valueQwtPlotItem
Rtti_PlotShape enum valueQwtPlotItem
Rtti_PlotSpectroCurve enum valueQwtPlotItem
Rtti_PlotSpectrogram enum valueQwtPlotItem
Rtti_PlotSVG enum valueQwtPlotItem
Rtti_PlotTextLabel enum valueQwtPlotItem
Rtti_PlotTradingCurve enum valueQwtPlotItem
Rtti_PlotUserItem enum valueQwtPlotItem
Rtti_PlotZone enum valueQwtPlotItem
RttiValues enum nameQwtPlotItem
ScaleInterest enum valueQwtPlotItem
scaleRect(const QwtScaleMap &, const QwtScaleMap &) const QwtPlotItem
setAxes(int xAxis, int yAxis)QwtPlotItem
setItemAttribute(ItemAttribute, bool on=true)QwtPlotItem
setItemInterest(ItemInterest, bool on=true)QwtPlotItem
setLabel(const QwtText &)QwtPlotMarker
setLabelAlignment(Qt::Alignment)QwtPlotMarker
setLabelOrientation(Qt::Orientation)QwtPlotMarker
setLegendIconSize(const QSize &)QwtPlotItem
setLinePen(const QColor &, qreal width=0.0, Qt::PenStyle=Qt::SolidLine)QwtPlotMarker
setLinePen(const QPen &p)QwtPlotMarker
setLineStyle(LineStyle st)QwtPlotMarker
setRenderHint(RenderHint, bool on=true)QwtPlotItem
setRenderThreadCount(uint numThreads)QwtPlotItem
setSpacing(int)QwtPlotMarker
setSymbol(const QwtSymbol *)QwtPlotMarker
setTitle(const QString &title)QwtPlotItem
setTitle(const QwtText &title)QwtPlotItem
setValue(double, double)QwtPlotMarker
setValue(const QPointF &)QwtPlotMarker
setVisible(bool)QwtPlotItemvirtual
setXAxis(int axis)QwtPlotItem
setXValue(double)QwtPlotMarker
setYAxis(int axis)QwtPlotItem
setYValue(double)QwtPlotMarker
setZ(double z)QwtPlotItem
show()QwtPlotItem
spacing() const QwtPlotMarker
symbol() const QwtPlotMarker
testItemAttribute(ItemAttribute) const QwtPlotItem
testItemInterest(ItemInterest) const QwtPlotItem
testRenderHint(RenderHint) const QwtPlotItem
title() const QwtPlotItem
updateLegend(const QwtPlotItem *, const QList< QwtLegendData > &)QwtPlotItemvirtual
updateScaleDiv(const QwtScaleDiv &, const QwtScaleDiv &)QwtPlotItemvirtual
value() const QwtPlotMarker
VLine enum valueQwtPlotMarker
xAxis() const QwtPlotItem
xValue() const QwtPlotMarker
yAxis() const QwtPlotItem
yValue() const QwtPlotMarker
z() const QwtPlotItem
~QwtPlotItem()QwtPlotItemvirtual
~QwtPlotMarker()QwtPlotMarkervirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_marker.html b/ThirdParty/Qwt/doc/html/class_qwt_plot_marker.html new file mode 100644 index 0000000000..4d4044d0e4 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_marker.html @@ -0,0 +1,1005 @@ + + + + + + +Qwt User's Guide: QwtPlotMarker Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+ +
+ +

A class for drawing markers. + More...

+ +

#include <qwt_plot_marker.h>

+
+Inheritance diagram for QwtPlotMarker:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Types

enum  LineStyle { NoLine, +HLine, +VLine, +Cross + }
 
- Public Types inherited from QwtPlotItem
enum  RttiValues {
+  Rtti_PlotItem = 0, +Rtti_PlotGrid, +Rtti_PlotScale, +Rtti_PlotLegend, +
+  Rtti_PlotMarker, +Rtti_PlotCurve, +Rtti_PlotSpectroCurve, +Rtti_PlotIntervalCurve, +
+  Rtti_PlotHistogram, +Rtti_PlotSpectrogram, +Rtti_PlotSVG, +Rtti_PlotTradingCurve, +
+  Rtti_PlotBarChart, +Rtti_PlotMultiBarChart, +Rtti_PlotShape, +Rtti_PlotTextLabel, +
+  Rtti_PlotZone, +Rtti_PlotUserItem = 1000 +
+ }
 Runtime type information. More...
 
enum  ItemAttribute { Legend = 0x01, +AutoScale = 0x02, +Margins = 0x04 + }
 Plot Item Attributes. More...
 
enum  ItemInterest { ScaleInterest = 0x01, +LegendInterest = 0x02 + }
 Plot Item Interests. More...
 
enum  RenderHint { RenderAntialiased = 0x1 + }
 Render hints. More...
 
+typedef QFlags< ItemAttributeItemAttributes
 Plot Item Attributes.
 
+typedef QFlags< ItemInterestItemInterests
 Plot Item Interests.
 
+typedef QFlags< RenderHintRenderHints
 Render hints.
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

QwtPlotMarker (const QString &title=QString::null)
 Sets alignment to Qt::AlignCenter, and style to QwtPlotMarker::NoLine.
 
QwtPlotMarker (const QwtText &title)
 Sets alignment to Qt::AlignCenter, and style to QwtPlotMarker::NoLine.
 
+virtual ~QwtPlotMarker ()
 Destructor.
 
virtual int rtti () const
 
+double xValue () const
 Return x Value.
 
+double yValue () const
 Return y Value.
 
+QPointF value () const
 Return Value.
 
+void setXValue (double)
 Set X Value.
 
+void setYValue (double)
 Set Y Value.
 
+void setValue (double, double)
 Set Value.
 
+void setValue (const QPointF &)
 Set Value.
 
void setLineStyle (LineStyle st)
 Set the line style. More...
 
LineStyle lineStyle () const
 
void setLinePen (const QColor &, qreal width=0.0, Qt::PenStyle=Qt::SolidLine)
 
void setLinePen (const QPen &p)
 
const QPen & linePen () const
 
void setSymbol (const QwtSymbol *)
 Assign a symbol. More...
 
const QwtSymbolsymbol () const
 
void setLabel (const QwtText &)
 Set the label. More...
 
QwtText label () const
 
void setLabelAlignment (Qt::Alignment)
 Set the alignment of the label. More...
 
Qt::Alignment labelAlignment () const
 
void setLabelOrientation (Qt::Orientation)
 Set the orientation of the label. More...
 
Qt::Orientation labelOrientation () const
 
void setSpacing (int)
 Set the spacing. More...
 
int spacing () const
 
virtual void draw (QPainter *p, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &) const
 
virtual QRectF boundingRect () const
 
virtual QwtGraphic legendIcon (int index, const QSizeF &) const
 
- Public Member Functions inherited from QwtPlotItem
 QwtPlotItem (const QwtText &title=QwtText())
 
+virtual ~QwtPlotItem ()
 Destroy the QwtPlotItem.
 
void attach (QwtPlot *plot)
 Attach the item to a plot. More...
 
void detach ()
 This method detaches a QwtPlotItem from any QwtPlot it has been associated with. More...
 
+QwtPlotplot () const
 Return attached plot.
 
void setTitle (const QString &title)
 
void setTitle (const QwtText &title)
 
const QwtTexttitle () const
 
void setItemAttribute (ItemAttribute, bool on=true)
 
bool testItemAttribute (ItemAttribute) const
 
void setItemInterest (ItemInterest, bool on=true)
 
bool testItemInterest (ItemInterest) const
 
void setRenderHint (RenderHint, bool on=true)
 
bool testRenderHint (RenderHint) const
 
void setRenderThreadCount (uint numThreads)
 
uint renderThreadCount () const
 
void setLegendIconSize (const QSize &)
 
QSize legendIconSize () const
 
double z () const
 
void setZ (double z)
 Set the z value. More...
 
+void show ()
 Show the item.
 
+void hide ()
 Hide the item.
 
virtual void setVisible (bool)
 
bool isVisible () const
 
void setAxes (int xAxis, int yAxis)
 
void setXAxis (int axis)
 
+int xAxis () const
 Return xAxis.
 
void setYAxis (int axis)
 
+int yAxis () const
 Return yAxis.
 
virtual void itemChanged ()
 
virtual void legendChanged ()
 
virtual void getCanvasMarginHint (const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasSize, double &left, double &top, double &right, double &bottom) const
 Calculate a hint for the canvas margin. More...
 
virtual void updateScaleDiv (const QwtScaleDiv &, const QwtScaleDiv &)
 Update the item to changes of the axes scale division. More...
 
virtual void updateLegend (const QwtPlotItem *, const QList< QwtLegendData > &)
 Update the item to changes of the legend info. More...
 
QRectF scaleRect (const QwtScaleMap &, const QwtScaleMap &) const
 Calculate the bounding scale rectangle of 2 maps. More...
 
QRectF paintRect (const QwtScaleMap &, const QwtScaleMap &) const
 Calculate the bounding paint rectangle of 2 maps. More...
 
virtual QList< QwtLegendDatalegendData () const
 Return all information, that is needed to represent the item on the legend. More...
 
+ + + + + + + + + +

+Protected Member Functions

virtual void drawLines (QPainter *, const QRectF &, const QPointF &) const
 
virtual void drawLabel (QPainter *, const QRectF &, const QPointF &) const
 
- Protected Member Functions inherited from QwtPlotItem
QwtGraphic defaultIcon (const QBrush &, const QSizeF &) const
 Return a default icon from a brush. More...
 
+

Detailed Description

+

A class for drawing markers.

+

A marker can be a horizontal line, a vertical line, a symbol, a label or any combination of them, which can be drawn around a center point inside a bounding rectangle.

+

The setSymbol() member assigns a symbol to the marker. The symbol is drawn at the specified point.

+

With setLabel(), a label can be assigned to the marker. The setLabelAlignment() member specifies where the label is drawn. All the Align*-constants in Qt::AlignmentFlags (see Qt documentation) are valid. The interpretation of the alignment depends on the marker's line style. The alignment refers to the center point of the marker, which means, for example, that the label would be printed left above the center point if the alignment was set to Qt::AlignLeft | Qt::AlignTop.

+
Note
QwtPlotTextLabel is intended to align a text label according to the geometry of canvas ( unrelated to plot coordinates )
+

Member Enumeration Documentation

+ +
+
+ + + + +
enum QwtPlotMarker::LineStyle
+
+

Line styles.

+
See Also
setLineStyle(), lineStyle()
+ + + + + +
Enumerator
NoLine  +

No line.

+
HLine  +

A horizontal line.

+
VLine  +

A vertical line.

+
Cross  +

A crosshair.

+
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + +
QRectF QwtPlotMarker::boundingRect () const
+
+virtual
+
+
Returns
An invalid bounding rect: QRectF(1.0, 1.0, -2.0, -2.0)
+
Note
A width or height < 0.0 is ignored by the autoscaler
+ +

Reimplemented from QwtPlotItem.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPlotMarker::draw (QPainter * painter,
const QwtScaleMapxMap,
const QwtScaleMapyMap,
const QRectF & canvasRect 
) const
+
+virtual
+
+

Draw the marker

+
Parameters
+ + + + + +
painterPainter
xMapx Scale Map
yMapy Scale Map
canvasRectContents rectangle of the canvas in painter coordinates
+
+
+ +

Implements QwtPlotItem.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPlotMarker::drawLabel (QPainter * painter,
const QRectF & canvasRect,
const QPointF & pos 
) const
+
+protectedvirtual
+
+

Align and draw the text label of the marker

+
Parameters
+ + + + +
painterPainter
canvasRectContents rectangle of the canvas in painter coordinates
posPosition of the marker, translated into widget coordinates
+
+
+
See Also
drawLabel(), QwtSymbol::drawSymbol()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPlotMarker::drawLines (QPainter * painter,
const QRectF & canvasRect,
const QPointF & pos 
) const
+
+protectedvirtual
+
+

Draw the lines marker

+
Parameters
+ + + + +
painterPainter
canvasRectContents rectangle of the canvas in painter coordinates
posPosition of the marker, translated into widget coordinates
+
+
+
See Also
drawLabel(), QwtSymbol::drawSymbol()
+ +
+
+ +
+
+ + + + + + + +
QwtText QwtPlotMarker::label () const
+
+
Returns
the label
+
See Also
setLabel()
+ +
+
+ +
+
+ + + + + + + +
Qt::Alignment QwtPlotMarker::labelAlignment () const
+
+
Returns
the label alignment
+
See Also
setLabelAlignment(), setLabelOrientation()
+ +
+
+ +
+
+ + + + + + + +
Qt::Orientation QwtPlotMarker::labelOrientation () const
+
+
Returns
the label orientation
+
See Also
setLabelOrientation(), labelAlignment()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
QwtGraphic QwtPlotMarker::legendIcon (int index,
const QSizeF & size 
) const
+
+virtual
+
+
Returns
Icon representing the marker on the legend
+
Parameters
+ + + +
indexIndex of the legend entry ( usually there is only one )
sizeIcon size
+
+
+
See Also
setLegendIconSize(), legendData()
+ +

Reimplemented from QwtPlotItem.

+ +
+
+ +
+
+ + + + + + + +
const QPen & QwtPlotMarker::linePen () const
+
+
Returns
the line pen
+
See Also
setLinePen()
+ +
+
+ +
+
+ + + + + + + +
QwtPlotMarker::LineStyle QwtPlotMarker::lineStyle () const
+
+
Returns
the line style
+
See Also
setLineStyle()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
int QwtPlotMarker::rtti () const
+
+virtual
+
+
Returns
QwtPlotItem::Rtti_PlotMarker
+ +

Reimplemented from QwtPlotItem.

+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotMarker::setLabel (const QwtTextlabel)
+
+ +

Set the label.

+
Parameters
+ + +
labelLabel text
+
+
+
See Also
label()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotMarker::setLabelAlignment (Qt::Alignment align)
+
+ +

Set the alignment of the label.

+

In case of QwtPlotMarker::HLine the alignment is relative to the y position of the marker, but the horizontal flags correspond to the canvas rectangle. In case of QwtPlotMarker::VLine the alignment is relative to the x position of the marker, but the vertical flags correspond to the canvas rectangle.

+

In all other styles the alignment is relative to the marker's position.

+
Parameters
+ + +
alignAlignment.
+
+
+
See Also
labelAlignment(), labelOrientation()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotMarker::setLabelOrientation (Qt::Orientation orientation)
+
+ +

Set the orientation of the label.

+

When orientation is Qt::Vertical the label is rotated by 90.0 degrees ( from bottom to top ).

+
Parameters
+ + +
orientationOrientation of the label
+
+
+
See Also
labelOrientation(), setLabelAlignment()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPlotMarker::setLinePen (const QColor & color,
qreal width = 0.0,
Qt::PenStyle style = Qt::SolidLine 
)
+
+

Build and assign a line pen

+

In Qt5 the default pen width is 1.0 ( 0.0 in Qt4 ) what makes it non cosmetic ( see QPen::isCosmetic() ). This method has been introduced to hide this incompatibility.

+
Parameters
+ + + + +
colorPen color
widthPen width
stylePen style
+
+
+
See Also
pen(), brush()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotMarker::setLinePen (const QPen & pen)
+
+

Specify a pen for the line.

+
Parameters
+ + +
penNew pen
+
+
+
See Also
linePen()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotMarker::setLineStyle (LineStyle style)
+
+ +

Set the line style.

+
Parameters
+ + +
styleLine style.
+
+
+
See Also
lineStyle()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotMarker::setSpacing (int spacing)
+
+ +

Set the spacing.

+

When the label is not centered on the marker position, the spacing is the distance between the position and the label.

+
Parameters
+ + +
spacingSpacing
+
+
+
See Also
spacing(), setLabelAlignment()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotMarker::setSymbol (const QwtSymbolsymbol)
+
+ +

Assign a symbol.

+
Parameters
+ + +
symbolNew symbol
+
+
+
See Also
symbol()
+ +
+
+ +
+
+ + + + + + + +
int QwtPlotMarker::spacing () const
+
+
Returns
the spacing
+
See Also
setSpacing()
+ +
+
+ +
+
+ + + + + + + +
const QwtSymbol * QwtPlotMarker::symbol () const
+
+
Returns
the symbol
+
See Also
setSymbol(), QwtSymbol
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_marker__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_plot_marker__inherit__graph.map new file mode 100644 index 0000000000..765dd16a7a --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_marker__inherit__graph.map @@ -0,0 +1,3 @@ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_marker__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_plot_marker__inherit__graph.md5 new file mode 100644 index 0000000000..3d94770caa --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_marker__inherit__graph.md5 @@ -0,0 +1 @@ +db095671d5435440aa911c0cf11a4c00 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_marker__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_plot_marker__inherit__graph.png new file mode 100644 index 0000000000..22711c60f1 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_plot_marker__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_multi_bar_chart-members.html b/ThirdParty/Qwt/doc/html/class_qwt_plot_multi_bar_chart-members.html new file mode 100644 index 0000000000..78ae654fa0 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_multi_bar_chart-members.html @@ -0,0 +1,234 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtPlotMultiBarChart Member List
+
+
+ +

This is the complete list of members for QwtPlotMultiBarChart, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
attach(QwtPlot *plot)QwtPlotItem
AutoAdjustSamples enum valueQwtPlotAbstractBarChart
AutoScale enum valueQwtPlotItem
barTitles() const QwtPlotMultiBarChart
baseline() const QwtPlotAbstractBarChart
boundingRect() const QwtPlotMultiBarChartvirtual
ChartStyle enum nameQwtPlotMultiBarChart
data()QwtSeriesStore< QwtSetSample >
data() constQwtSeriesStore< QwtSetSample >
dataChanged()QwtPlotSeriesItemprotectedvirtual
QwtPlotAbstractBarChart::dataRect() const =0QwtAbstractSeriesStoreprotectedpure virtual
QwtSeriesStore< QwtSetSample >::dataRect() constQwtSeriesStore< QwtSetSample >virtual
QwtPlotAbstractBarChart::dataSize() const =0QwtAbstractSeriesStoreprotectedpure virtual
QwtSeriesStore< QwtSetSample >::dataSize() constQwtSeriesStore< QwtSetSample >virtual
defaultIcon(const QBrush &, const QSizeF &) const QwtPlotItemprotected
detach()QwtPlotItem
draw(QPainter *p, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &) const QwtPlotSeriesItemvirtual
drawBar(QPainter *, int sampleIndex, int barIndex, const QwtColumnRect &) const QwtPlotMultiBarChartprotectedvirtual
drawGroupedBars(QPainter *painter, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, int index, double sampleWidth, const QwtSetSample &sample) const QwtPlotMultiBarChartprotected
drawSample(QPainter *painter, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, const QwtInterval &boundingInterval, int index, const QwtSetSample &sample) const QwtPlotMultiBarChartprotectedvirtual
drawSeries(QPainter *painter, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, int from, int to) const QwtPlotMultiBarChartvirtual
drawStackedBars(QPainter *painter, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, int index, double sampleWidth, const QwtSetSample &sample) const QwtPlotMultiBarChartprotected
FixedSampleSize enum valueQwtPlotAbstractBarChart
getCanvasMarginHint(const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, double &left, double &top, double &right, double &bottom) const QwtPlotAbstractBarChartvirtual
Grouped enum valueQwtPlotMultiBarChart
hide()QwtPlotItem
isVisible() const QwtPlotItem
ItemAttribute enum nameQwtPlotItem
ItemAttributes typedefQwtPlotItem
itemChanged()QwtPlotItemvirtual
ItemInterest enum nameQwtPlotItem
ItemInterests typedefQwtPlotItem
layoutHint() const QwtPlotAbstractBarChart
layoutPolicy() const QwtPlotAbstractBarChart
LayoutPolicy enum nameQwtPlotAbstractBarChart
Legend enum valueQwtPlotItem
legendChanged()QwtPlotItemvirtual
legendData() const QwtPlotMultiBarChartvirtual
legendIcon(int index, const QSizeF &) const QwtPlotMultiBarChartvirtual
legendIconSize() const QwtPlotItem
LegendInterest enum valueQwtPlotItem
margin() const QwtPlotAbstractBarChart
Margins enum valueQwtPlotItem
orientation() const QwtPlotSeriesItem
paintRect(const QwtScaleMap &, const QwtScaleMap &) const QwtPlotItem
plot() const QwtPlotItem
QwtPlotAbstractBarChart(const QwtText &title)QwtPlotAbstractBarChartexplicit
QwtPlotItem(const QwtText &title=QwtText())QwtPlotItemexplicit
QwtPlotMultiBarChart(const QString &title=QString::null)QwtPlotMultiBarChartexplicit
QwtPlotMultiBarChart(const QwtText &title)QwtPlotMultiBarChartexplicit
QwtPlotSeriesItem(const QString &title=QString::null)QwtPlotSeriesItemexplicit
QwtPlotSeriesItem(const QwtText &title)QwtPlotSeriesItemexplicit
QwtSeriesStore()QwtSeriesStore< QwtSetSample >explicit
RenderAntialiased enum valueQwtPlotItem
RenderHint enum nameQwtPlotItem
RenderHints typedefQwtPlotItem
renderThreadCount() const QwtPlotItem
resetSymbolMap()QwtPlotMultiBarChart
rtti() const QwtPlotMultiBarChartvirtual
Rtti_PlotBarChart enum valueQwtPlotItem
Rtti_PlotCurve enum valueQwtPlotItem
Rtti_PlotGrid enum valueQwtPlotItem
Rtti_PlotHistogram enum valueQwtPlotItem
Rtti_PlotIntervalCurve enum valueQwtPlotItem
Rtti_PlotItem enum valueQwtPlotItem
Rtti_PlotLegend enum valueQwtPlotItem
Rtti_PlotMarker enum valueQwtPlotItem
Rtti_PlotMultiBarChart enum valueQwtPlotItem
Rtti_PlotScale enum valueQwtPlotItem
Rtti_PlotShape enum valueQwtPlotItem
Rtti_PlotSpectroCurve enum valueQwtPlotItem
Rtti_PlotSpectrogram enum valueQwtPlotItem
Rtti_PlotSVG enum valueQwtPlotItem
Rtti_PlotTextLabel enum valueQwtPlotItem
Rtti_PlotTradingCurve enum valueQwtPlotItem
Rtti_PlotUserItem enum valueQwtPlotItem
Rtti_PlotZone enum valueQwtPlotItem
RttiValues enum nameQwtPlotItem
sample(int index) constQwtSeriesStore< QwtSetSample >
sampleWidth(const QwtScaleMap &map, double canvasSize, double dataSize, double value) const QwtPlotAbstractBarChartprotected
ScaleInterest enum valueQwtPlotItem
scaleRect(const QwtScaleMap &, const QwtScaleMap &) const QwtPlotItem
ScaleSamplesToAxes enum valueQwtPlotAbstractBarChart
ScaleSampleToCanvas enum valueQwtPlotAbstractBarChart
setAxes(int xAxis, int yAxis)QwtPlotItem
setBarTitles(const QList< QwtText > &)QwtPlotMultiBarChart
setBaseline(double)QwtPlotAbstractBarChart
setData(QwtSeriesData< QwtSetSample > *series)QwtSeriesStore< QwtSetSample >
setItemAttribute(ItemAttribute, bool on=true)QwtPlotItem
setItemInterest(ItemInterest, bool on=true)QwtPlotItem
setLayoutHint(double)QwtPlotAbstractBarChart
setLayoutPolicy(LayoutPolicy)QwtPlotAbstractBarChart
setLegendIconSize(const QSize &)QwtPlotItem
setMargin(int)QwtPlotAbstractBarChart
setOrientation(Qt::Orientation)QwtPlotSeriesItem
QwtPlotAbstractBarChart::setRectOfInterest(const QRectF &)=0QwtAbstractSeriesStoreprotectedpure virtual
QwtSeriesStore< QwtSetSample >::setRectOfInterest(const QRectF &rect)QwtSeriesStore< QwtSetSample >virtual
setRenderHint(RenderHint, bool on=true)QwtPlotItem
setRenderThreadCount(uint numThreads)QwtPlotItem
setSamples(const QVector< QwtSetSample > &)QwtPlotMultiBarChart
setSamples(const QVector< QVector< double > > &)QwtPlotMultiBarChart
setSamples(QwtSeriesData< QwtSetSample > *)QwtPlotMultiBarChart
setSpacing(int)QwtPlotAbstractBarChart
setStyle(ChartStyle style)QwtPlotMultiBarChart
setSymbol(int barIndex, QwtColumnSymbol *symbol)QwtPlotMultiBarChart
setTitle(const QString &title)QwtPlotItem
setTitle(const QwtText &title)QwtPlotItem
setVisible(bool)QwtPlotItemvirtual
setXAxis(int axis)QwtPlotItem
setYAxis(int axis)QwtPlotItem
setZ(double z)QwtPlotItem
show()QwtPlotItem
spacing() const QwtPlotAbstractBarChart
specialSymbol(int sampleIndex, int valueIndex) const QwtPlotMultiBarChartprotectedvirtual
Stacked enum valueQwtPlotMultiBarChart
style() const QwtPlotMultiBarChart
swapData(QwtSeriesData< QwtSetSample > *series)QwtSeriesStore< QwtSetSample >
symbol(int barIndex) const QwtPlotMultiBarChart
symbol(int barIndex)QwtPlotMultiBarChartprotected
testItemAttribute(ItemAttribute) const QwtPlotItem
testItemInterest(ItemInterest) const QwtPlotItem
testRenderHint(RenderHint) const QwtPlotItem
title() const QwtPlotItem
updateLegend(const QwtPlotItem *, const QList< QwtLegendData > &)QwtPlotItemvirtual
updateScaleDiv(const QwtScaleDiv &, const QwtScaleDiv &)QwtPlotSeriesItemvirtual
xAxis() const QwtPlotItem
yAxis() const QwtPlotItem
z() const QwtPlotItem
~QwtAbstractSeriesStore()QwtAbstractSeriesStoreinlineprotectedvirtual
~QwtPlotAbstractBarChart()QwtPlotAbstractBarChartvirtual
~QwtPlotItem()QwtPlotItemvirtual
~QwtPlotMultiBarChart()QwtPlotMultiBarChartvirtual
~QwtPlotSeriesItem()QwtPlotSeriesItemvirtual
~QwtSeriesStore()QwtSeriesStore< QwtSetSample >
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_multi_bar_chart.html b/ThirdParty/Qwt/doc/html/class_qwt_plot_multi_bar_chart.html new file mode 100644 index 0000000000..a6165da839 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_multi_bar_chart.html @@ -0,0 +1,1271 @@ + + + + + + +Qwt User's Guide: QwtPlotMultiBarChart Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtPlotMultiBarChart Class Reference
+
+
+ +

QwtPlotMultiBarChart displays a series of a samples that consist each of a set of values. + More...

+ +

#include <qwt_plot_multi_barchart.h>

+
+Inheritance diagram for QwtPlotMultiBarChart:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + + +

+Public Types

enum  ChartStyle { Grouped, +Stacked + }
 Chart styles. More...
 
- Public Types inherited from QwtPlotAbstractBarChart
enum  LayoutPolicy { AutoAdjustSamples, +ScaleSamplesToAxes, +ScaleSampleToCanvas, +FixedSampleSize + }
 Mode how to calculate the bar width. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 QwtPlotMultiBarChart (const QString &title=QString::null)
 
 QwtPlotMultiBarChart (const QwtText &title)
 
+virtual ~QwtPlotMultiBarChart ()
 Destructor.
 
virtual int rtti () const
 
void setBarTitles (const QList< QwtText > &)
 Set the titles for the bars. More...
 
QList< QwtTextbarTitles () const
 
void setSamples (const QVector< QwtSetSample > &)
 
void setSamples (const QVector< QVector< double > > &)
 
void setSamples (QwtSeriesData< QwtSetSample > *)
 
void setStyle (ChartStyle style)
 
ChartStyle style () const
 
void setSymbol (int barIndex, QwtColumnSymbol *symbol)
 Add a symbol to the symbol map. More...
 
const QwtColumnSymbolsymbol (int barIndex) const
 
void resetSymbolMap ()
 
virtual void drawSeries (QPainter *painter, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, int from, int to) const
 
virtual QRectF boundingRect () const
 
virtual QList< QwtLegendDatalegendData () const
 
virtual QwtGraphic legendIcon (int index, const QSizeF &) const
 
- Public Member Functions inherited from QwtPlotAbstractBarChart
 QwtPlotAbstractBarChart (const QwtText &title)
 
+virtual ~QwtPlotAbstractBarChart ()
 Destructor.
 
void setLayoutPolicy (LayoutPolicy)
 
LayoutPolicy layoutPolicy () const
 
void setLayoutHint (double)
 
double layoutHint () const
 
void setSpacing (int)
 Set the spacing. More...
 
int spacing () const
 
void setMargin (int)
 Set the margin. More...
 
int margin () const
 
void setBaseline (double)
 Set the baseline. More...
 
double baseline () const
 
virtual void getCanvasMarginHint (const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, double &left, double &top, double &right, double &bottom) const
 Calculate a hint for the canvas margin. More...
 
- Public Member Functions inherited from QwtPlotSeriesItem
 QwtPlotSeriesItem (const QString &title=QString::null)
 
 QwtPlotSeriesItem (const QwtText &title)
 
+virtual ~QwtPlotSeriesItem ()
 Destructor.
 
void setOrientation (Qt::Orientation)
 
Qt::Orientation orientation () const
 
virtual void draw (QPainter *p, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &) const
 Draw the complete series. More...
 
virtual void updateScaleDiv (const QwtScaleDiv &, const QwtScaleDiv &)
 Update the item to changes of the axes scale division. More...
 
- Public Member Functions inherited from QwtPlotItem
 QwtPlotItem (const QwtText &title=QwtText())
 
+virtual ~QwtPlotItem ()
 Destroy the QwtPlotItem.
 
void attach (QwtPlot *plot)
 Attach the item to a plot. More...
 
void detach ()
 This method detaches a QwtPlotItem from any QwtPlot it has been associated with. More...
 
+QwtPlotplot () const
 Return attached plot.
 
void setTitle (const QString &title)
 
void setTitle (const QwtText &title)
 
const QwtTexttitle () const
 
void setItemAttribute (ItemAttribute, bool on=true)
 
bool testItemAttribute (ItemAttribute) const
 
void setItemInterest (ItemInterest, bool on=true)
 
bool testItemInterest (ItemInterest) const
 
void setRenderHint (RenderHint, bool on=true)
 
bool testRenderHint (RenderHint) const
 
void setRenderThreadCount (uint numThreads)
 
uint renderThreadCount () const
 
void setLegendIconSize (const QSize &)
 
QSize legendIconSize () const
 
double z () const
 
void setZ (double z)
 Set the z value. More...
 
+void show ()
 Show the item.
 
+void hide ()
 Hide the item.
 
virtual void setVisible (bool)
 
bool isVisible () const
 
void setAxes (int xAxis, int yAxis)
 
void setXAxis (int axis)
 
+int xAxis () const
 Return xAxis.
 
void setYAxis (int axis)
 
+int yAxis () const
 Return yAxis.
 
virtual void itemChanged ()
 
virtual void legendChanged ()
 
virtual void updateLegend (const QwtPlotItem *, const QList< QwtLegendData > &)
 Update the item to changes of the legend info. More...
 
QRectF scaleRect (const QwtScaleMap &, const QwtScaleMap &) const
 Calculate the bounding scale rectangle of 2 maps. More...
 
QRectF paintRect (const QwtScaleMap &, const QwtScaleMap &) const
 Calculate the bounding paint rectangle of 2 maps. More...
 
- Public Member Functions inherited from QwtSeriesStore< QwtSetSample >
QwtSeriesStore ()
 Constructor The store contains no series.
 
~QwtSeriesStore ()
 Destructor.
 
void setData (QwtSeriesData< QwtSetSample > *series)
 
QwtSeriesData< QwtSetSample > * data ()
 
const QwtSeriesData
+< QwtSetSample > * 
data () const
 
QwtSetSample sample (int index) const
 
virtual size_t dataSize () const
 
virtual QRectF dataRect () const
 
virtual void setRectOfInterest (const QRectF &rect)
 
QwtSeriesData< QwtSetSample > * swapData (QwtSeriesData< QwtSetSample > *series)
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Protected Member Functions

QwtColumnSymbolsymbol (int barIndex)
 
virtual QwtColumnSymbolspecialSymbol (int sampleIndex, int valueIndex) const
 Create a symbol for special values. More...
 
virtual void drawSample (QPainter *painter, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, const QwtInterval &boundingInterval, int index, const QwtSetSample &sample) const
 
virtual void drawBar (QPainter *, int sampleIndex, int barIndex, const QwtColumnRect &) const
 
void drawStackedBars (QPainter *painter, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, int index, double sampleWidth, const QwtSetSample &sample) const
 
void drawGroupedBars (QPainter *painter, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, int index, double sampleWidth, const QwtSetSample &sample) const
 
- Protected Member Functions inherited from QwtPlotAbstractBarChart
double sampleWidth (const QwtScaleMap &map, double canvasSize, double dataSize, double value) const
 
- Protected Member Functions inherited from QwtPlotSeriesItem
+virtual void dataChanged ()
 dataChanged() indicates, that the series has been changed.
 
- Protected Member Functions inherited from QwtPlotItem
QwtGraphic defaultIcon (const QBrush &, const QSizeF &) const
 Return a default icon from a brush. More...
 
- Protected Member Functions inherited from QwtAbstractSeriesStore
+virtual ~QwtAbstractSeriesStore ()
 Destructor.
 
+

Detailed Description

+

QwtPlotMultiBarChart displays a series of a samples that consist each of a set of values.

+

Each value is displayed as a bar, the bars of each set can be organized side by side or accumulated.

+

Each bar of a set is rendered by a QwtColumnSymbol, that is set by setSymbol(). The bars of different sets use the same symbols. Exceptions are possible by overloading specialSymbol() or overloading drawBar().

+

Depending on its orientation() the bars are displayed horizontally or vertically. The bars cover the interval between the baseline() and the value.

+

In opposite to most other plot items, QwtPlotMultiBarChart returns more than one entry for the legend - one for each symbol.

+
See Also
QwtPlotBarChart, QwtPlotHistogram QwtPlotSeriesItem::orientation(), QwtPlotAbstractBarChart::baseline()
+

Member Enumeration Documentation

+ +
+
+ +

Chart styles.

+

The default setting is QwtPlotMultiBarChart::Grouped.

+
See Also
setStyle(), style()
+ + + +
Enumerator
Grouped  +

The bars of a set are displayed side by side.

+
Stacked  +

The bars are displayed on top of each other accumulating to a single bar. All values of a set need to have the same sign.

+
+ +
+
+

Constructor & Destructor Documentation

+ +
+
+ + + + + +
+ + + + + + + + +
QwtPlotMultiBarChart::QwtPlotMultiBarChart (const QString & title = QString::null)
+
+explicit
+
+

Constructor

+
Parameters
+ + +
titleTitle of the chart
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
QwtPlotMultiBarChart::QwtPlotMultiBarChart (const QwtTexttitle)
+
+explicit
+
+

Constructor

+
Parameters
+ + +
titleTitle of the chart
+
+
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + + + +
QList< QwtText > QwtPlotMultiBarChart::barTitles () const
+
+
Returns
Bar titles
+
See Also
setBarTitles(), legendData()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
QRectF QwtPlotMultiBarChart::boundingRect () const
+
+virtual
+
+
Returns
Bounding rectangle of all samples. For an empty series the rectangle is invalid.
+ +

Reimplemented from QwtPlotSeriesItem.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPlotMultiBarChart::drawBar (QPainter * painter,
int sampleIndex,
int valueIndex,
const QwtColumnRectrect 
) const
+
+protectedvirtual
+
+

Draw a bar

+
Parameters
+ + + + + +
painterPainter
sampleIndexIndex of the sample - might be -1 when the bar is painted for the legend
valueIndexIndex of a value in a set
rectDirected target rectangle for the bar
+
+
+
See Also
drawSeries()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPlotMultiBarChart::drawGroupedBars (QPainter * painter,
const QwtScaleMapxMap,
const QwtScaleMapyMap,
const QRectF & canvasRect,
int index,
double sampleWidth,
const QwtSetSamplesample 
) const
+
+protected
+
+

Draw a grouped sample

+
Parameters
+ + + + + + + + +
painterPainter
xMapx map
yMapy map
canvasRectContents rectangle of the canvas
indexIndex of the sample to be painted
sampleWidthBoundng width for all bars of the smaple
sampleSample
+
+
+
See Also
drawSeries(), sampleWidth()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPlotMultiBarChart::drawSample (QPainter * painter,
const QwtScaleMapxMap,
const QwtScaleMapyMap,
const QRectF & canvasRect,
const QwtIntervalboundingInterval,
int index,
const QwtSetSamplesample 
) const
+
+protectedvirtual
+
+

Draw a sample

+
Parameters
+ + + + + + + + +
painterPainter
xMapx map
yMapy map
canvasRectContents rectangle of the canvas
boundingIntervalBounding interval of sample values
indexIndex of the sample to be painted
sampleSample value
+
+
+
See Also
drawSeries()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPlotMultiBarChart::drawSeries (QPainter * painter,
const QwtScaleMapxMap,
const QwtScaleMapyMap,
const QRectF & canvasRect,
int from,
int to 
) const
+
+virtual
+
+

Draw an interval of the bar chart

+
Parameters
+ + + + + + + +
painterPainter
xMapMaps x-values into pixel coordinates.
yMapMaps y-values into pixel coordinates.
canvasRectContents rectangle of the canvas
fromIndex of the first point to be painted
toIndex of the last point to be painted. If to < 0 the curve will be painted to its last point.
+
+
+
See Also
drawSymbols()
+ +

Implements QwtPlotSeriesItem.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPlotMultiBarChart::drawStackedBars (QPainter * painter,
const QwtScaleMapxMap,
const QwtScaleMapyMap,
const QRectF & canvasRect,
int index,
double sampleWidth,
const QwtSetSamplesample 
) const
+
+protected
+
+

Draw a stacked sample

+
Parameters
+ + + + + + + + +
painterPainter
xMapx map
yMapy map
canvasRectContents rectangle of the canvas
indexIndex of the sample to be painted
sampleWidthWidth of the bars
sampleSample
+
+
+
See Also
drawSeries(), sampleWidth()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
QList< QwtLegendData > QwtPlotMultiBarChart::legendData () const
+
+virtual
+
+
Returns
Information to be displayed on the legend
+

The chart is represented by a list of entries - one for each bar title. Each element contains a bar title and an icon showing its corresponding bar.

+
See Also
barTitles(), legendIcon(), legendIconSize()
+ +

Reimplemented from QwtPlotItem.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
QwtGraphic QwtPlotMultiBarChart::legendIcon (int index,
const QSizeF & size 
) const
+
+virtual
+
+
Returns
Icon for representing a bar on the legend
+
Parameters
+ + + +
indexIndex of the bar
sizeIcon size
+
+
+
Returns
An icon showing a bar
+
See Also
drawBar(), legendData()
+ +

Reimplemented from QwtPlotItem.

+ +
+
+ +
+
+ + + + + + + +
void QwtPlotMultiBarChart::resetSymbolMap ()
+
+

Remove all symbols from the symbol map

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
int QwtPlotMultiBarChart::rtti () const
+
+virtual
+
+
Returns
QwtPlotItem::Rtti_PlotBarChart
+ +

Reimplemented from QwtPlotItem.

+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotMultiBarChart::setBarTitles (const QList< QwtText > & titles)
+
+ +

Set the titles for the bars.

+

The titles are used for the legend.

+
Parameters
+ + +
titlesBar titles
+
+
+
See Also
barTitles(), legendData()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotMultiBarChart::setSamples (const QVector< QwtSetSample > & samples)
+
+

Initialize data with an array of samples.

+
Parameters
+ + +
samplesVector of points
+
+
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotMultiBarChart::setSamples (const QVector< QVector< double > > & samples)
+
+

Initialize data with an array of samples.

+
Parameters
+ + +
samplesVector of points
+
+
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotMultiBarChart::setSamples (QwtSeriesData< QwtSetSample > * data)
+
+

Assign a series of samples

+

setSamples() is just a wrapper for setData() without any additional value - beside that it is easier to find for the developer.

+
Parameters
+ + +
dataData
+
+
+
Warning
The item takes ownership of the data object, deleting it when its not used anymore.
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotMultiBarChart::setStyle (ChartStyle style)
+
+

Set the style of the chart

+
Parameters
+ + +
styleChart style
+
+
+
See Also
style()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtPlotMultiBarChart::setSymbol (int valueIndex,
QwtColumnSymbolsymbol 
)
+
+ +

Add a symbol to the symbol map.

+

Assign a default symbol for drawing the bar representing all values with the same index in a set.

+
Parameters
+ + + +
valueIndexIndex of a value in a set
symbolSymbol used for drawing a bar
+
+
+
See Also
symbol(), resetSymbolMap(), specialSymbol()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
QwtColumnSymbol * QwtPlotMultiBarChart::specialSymbol (int sampleIndex,
int valueIndex 
) const
+
+protectedvirtual
+
+ +

Create a symbol for special values.

+

Usually the symbols for displaying a bar are set by setSymbols() and common for all sets. By overloading specialSymbol() it is possible to create a temporary symbol() for displaying a special value.

+

The symbol has to be created by new each time specialSymbol() is called. As soon as the symbol is painted this symbol gets deleted.

+

When no symbol ( NULL ) is returned, the value will be displayed with the standard symbol that is used for all symbols with the same valueIndex.

+
Parameters
+ + + +
sampleIndexIndex of the sample
valueIndexIndex of the value in the set
+
+
+
Returns
NULL, meaning that the value is not special
+ +
+
+ +
+
+ + + + + + + +
QwtPlotMultiBarChart::ChartStyle QwtPlotMultiBarChart::style () const
+
+
Returns
Style of the chart
+
See Also
setStyle()
+ +
+
+ +
+
+ + + + + + + + +
const QwtColumnSymbol * QwtPlotMultiBarChart::symbol (int valueIndex) const
+
+

Find a symbol in the symbol map

+
Parameters
+ + +
valueIndexIndex of a value in a set
+
+
+
Returns
The symbol, that had been set by setSymbol() or NULL.
+
See Also
setSymbol(), specialSymbol(), drawBar()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
QwtColumnSymbol * QwtPlotMultiBarChart::symbol (int valueIndex)
+
+protected
+
+

Find a symbol in the symbol map

+
Parameters
+ + +
valueIndexIndex of a value in a set
+
+
+
Returns
The symbol, that had been set by setSymbol() or NULL.
+
See Also
setSymbol(), specialSymbol(), drawBar()
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_multi_bar_chart__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_plot_multi_bar_chart__inherit__graph.map new file mode 100644 index 0000000000..6565adf647 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_multi_bar_chart__inherit__graph.map @@ -0,0 +1,7 @@ + + + + + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_multi_bar_chart__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_plot_multi_bar_chart__inherit__graph.md5 new file mode 100644 index 0000000000..f8fc92101d --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_multi_bar_chart__inherit__graph.md5 @@ -0,0 +1 @@ +6b9fc09e6d7caae4c2022538ed6a010d \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_multi_bar_chart__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_plot_multi_bar_chart__inherit__graph.png new file mode 100644 index 0000000000..b68aacc3fc Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_plot_multi_bar_chart__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_panner-members.html b/ThirdParty/Qwt/doc/html/class_qwt_plot_panner-members.html new file mode 100644 index 0000000000..53c45e4a9b --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_panner-members.html @@ -0,0 +1,133 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtPlotPanner Member List
+
+
+ +

This is the complete list of members for QwtPlotPanner, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
canvas()QwtPlotPanner
canvas() const QwtPlotPanner
contentsMask() const QwtPlotPannerprotectedvirtual
cursor() const QwtPanner
eventFilter(QObject *, QEvent *)QwtPannervirtual
getAbortKey(int &key, Qt::KeyboardModifiers &) const QwtPanner
getMouseButton(Qt::MouseButton &button, Qt::KeyboardModifiers &) const QwtPanner
grab() const QwtPlotPannerprotectedvirtual
isAxisEnabled(int axis) const QwtPlotPanner
isEnabled() const QwtPanner
isOrientationEnabled(Qt::Orientation) const QwtPanner
moveCanvas(int dx, int dy)QwtPlotPannerprotectedvirtualslot
moved(int dx, int dy)QwtPannersignal
orientations() const QwtPanner
paintEvent(QPaintEvent *)QwtPannerprotectedvirtual
panned(int dx, int dy)QwtPannersignal
plot()QwtPlotPanner
plot() const QwtPlotPanner
QwtPanner(QWidget *parent)QwtPanner
QwtPlotPanner(QWidget *)QwtPlotPannerexplicit
setAbortKey(int key, Qt::KeyboardModifiers=Qt::NoModifier)QwtPanner
setAxisEnabled(int axis, bool on)QwtPlotPanner
setCursor(const QCursor &)QwtPanner
setEnabled(bool)QwtPanner
setMouseButton(Qt::MouseButton, Qt::KeyboardModifiers=Qt::NoModifier)QwtPanner
setOrientations(Qt::Orientations)QwtPanner
widgetKeyPressEvent(QKeyEvent *)QwtPannerprotectedvirtual
widgetKeyReleaseEvent(QKeyEvent *)QwtPannerprotectedvirtual
widgetMouseMoveEvent(QMouseEvent *)QwtPannerprotectedvirtual
widgetMousePressEvent(QMouseEvent *)QwtPannerprotectedvirtual
widgetMouseReleaseEvent(QMouseEvent *)QwtPannerprotectedvirtual
~QwtPanner()QwtPannervirtual
~QwtPlotPanner()QwtPlotPannervirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_panner.html b/ThirdParty/Qwt/doc/html/class_qwt_plot_panner.html new file mode 100644 index 0000000000..9cbc02ede8 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_panner.html @@ -0,0 +1,420 @@ + + + + + + +Qwt User's Guide: QwtPlotPanner Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+ +
+ +

QwtPlotPanner provides panning of a plot canvas. + More...

+ +

#include <qwt_plot_panner.h>

+
+Inheritance diagram for QwtPlotPanner:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 QwtPlotPanner (QWidget *)
 A panner for the canvas of a QwtPlot. More...
 
+virtual ~QwtPlotPanner ()
 Destructor.
 
+QWidget * canvas ()
 Return observed plot canvas.
 
+const QWidget * canvas () const
 Return Observed plot canvas.
 
+QwtPlotplot ()
 Return plot widget, containing the observed plot canvas.
 
+const QwtPlotplot () const
 Return plot widget, containing the observed plot canvas.
 
void setAxisEnabled (int axis, bool on)
 En/Disable an axis. More...
 
bool isAxisEnabled (int axis) const
 
- Public Member Functions inherited from QwtPanner
 QwtPanner (QWidget *parent)
 
+virtual ~QwtPanner ()
 Destructor.
 
void setEnabled (bool)
 En/disable the panner. More...
 
bool isEnabled () const
 
void setMouseButton (Qt::MouseButton, Qt::KeyboardModifiers=Qt::NoModifier)
 
+void getMouseButton (Qt::MouseButton &button, Qt::KeyboardModifiers &) const
 Get mouse button and modifiers used for panning.
 
void setAbortKey (int key, Qt::KeyboardModifiers=Qt::NoModifier)
 
+void getAbortKey (int &key, Qt::KeyboardModifiers &) const
 Get the abort key and modifiers.
 
void setCursor (const QCursor &)
 
const QCursor cursor () const
 
void setOrientations (Qt::Orientations)
 
+Qt::Orientations orientations () const
 Return the orientation, where paning is enabled.
 
bool isOrientationEnabled (Qt::Orientation) const
 
virtual bool eventFilter (QObject *, QEvent *)
 Event filter. More...
 
+ + + +

+Protected Slots

virtual void moveCanvas (int dx, int dy)
 
+ + + + + + + + + + + + + + + + + + + +

+Protected Member Functions

virtual QBitmap contentsMask () const
 
virtual QPixmap grab () const
 
- Protected Member Functions inherited from QwtPanner
virtual void widgetMousePressEvent (QMouseEvent *)
 
virtual void widgetMouseReleaseEvent (QMouseEvent *)
 
virtual void widgetMouseMoveEvent (QMouseEvent *)
 
virtual void widgetKeyPressEvent (QKeyEvent *)
 
virtual void widgetKeyReleaseEvent (QKeyEvent *)
 
virtual void paintEvent (QPaintEvent *)
 Paint event. More...
 
+ + + + + + +

+Additional Inherited Members

- Signals inherited from QwtPanner
void panned (int dx, int dy)
 
void moved (int dx, int dy)
 
+

Detailed Description

+

QwtPlotPanner provides panning of a plot canvas.

+

QwtPlotPanner is a panner for a plot canvas, that adjusts the scales of the axes after dropping the canvas on its new position.

+

Together with QwtPlotZoomer and QwtPlotMagnifier powerful ways of navigating on a QwtPlot widget can be implemented easily.

+
Note
The axes are not updated, while dragging the canvas
+
See Also
QwtPlotZoomer, QwtPlotMagnifier
+

Constructor & Destructor Documentation

+ +
+
+ + + + + +
+ + + + + + + + +
QwtPlotPanner::QwtPlotPanner (QWidget * canvas)
+
+explicit
+
+ +

A panner for the canvas of a QwtPlot.

+

The panner is enabled for all axes

+
Parameters
+ + +
canvasPlot canvas to pan, also the parent object
+
+
+
See Also
setAxisEnabled()
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + +
QBitmap QwtPlotPanner::contentsMask () const
+
+protectedvirtual
+
+

Calculate a mask from the border path of the canvas

+
Returns
Mask as bitmap
+
See Also
QwtPlotCanvas::borderPath()
+ +

Reimplemented from QwtPanner.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
QPixmap QwtPlotPanner::grab () const
+
+protectedvirtual
+
+
Returns
Pixmap with the content of the canvas
+ +

Reimplemented from QwtPanner.

+ +
+
+ +
+
+ + + + + + + + +
bool QwtPlotPanner::isAxisEnabled (int axis) const
+
+

Test if an axis is enabled

+
Parameters
+ + +
axisAxis, see QwtPlot::Axis
+
+
+
Returns
True, if the axis is enabled
+
See Also
setAxisEnabled(), moveCanvas()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void QwtPlotPanner::moveCanvas (int dx,
int dy 
)
+
+protectedvirtualslot
+
+

Adjust the enabled axes according to dx/dy

+
Parameters
+ + + +
dxPixel offset in x direction
dyPixel offset in y direction
+
+
+
See Also
QwtPanner::panned()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtPlotPanner::setAxisEnabled (int axis,
bool on 
)
+
+ +

En/Disable an axis.

+

Axes that are enabled will be synchronized to the result of panning. All other axes will remain unchanged.

+
Parameters
+ + + +
axisAxis, see QwtPlot::Axis
onOn/Off
+
+
+
See Also
isAxisEnabled(), moveCanvas()
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_panner__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_plot_panner__inherit__graph.map new file mode 100644 index 0000000000..e23d2ec6cc --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_panner__inherit__graph.map @@ -0,0 +1,3 @@ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_panner__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_plot_panner__inherit__graph.md5 new file mode 100644 index 0000000000..085bbabb0f --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_panner__inherit__graph.md5 @@ -0,0 +1 @@ +7220527bb5950f283e8c4d01ac55a642 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_panner__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_plot_panner__inherit__graph.png new file mode 100644 index 0000000000..64babdcf9a Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_plot_panner__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_picker-members.html b/ThirdParty/Qwt/doc/html/class_qwt_plot_picker-members.html new file mode 100644 index 0000000000..04d80c7fb1 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_picker-members.html @@ -0,0 +1,235 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtPlotPicker Member List
+
+
+ +

This is the complete list of members for QwtPlotPicker, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
accept(QPolygon &) const QwtPickerprotectedvirtual
activated(bool on)QwtPickersignal
ActiveOnly enum valueQwtPicker
adjustedPoints(const QPolygon &) const QwtPickerprotectedvirtual
AlwaysOff enum valueQwtPicker
AlwaysOn enum valueQwtPicker
append(const QPoint &)QwtPlotPickerprotectedvirtual
appended(const QPointF &pos)QwtPlotPickersignal
QwtPicker::appended(const QPoint &pos)QwtPickersignal
begin()QwtPickerprotectedvirtual
canvas()QwtPlotPicker
canvas() const QwtPlotPicker
changed(const QPolygon &selection)QwtPickersignal
CrossRubberBand enum valueQwtPicker
DisplayMode enum nameQwtPicker
drawRubberBand(QPainter *) const QwtPickervirtual
drawTracker(QPainter *) const QwtPickervirtual
EllipseRubberBand enum valueQwtPicker
end(bool ok=true)QwtPlotPickerprotectedvirtual
eventFilter(QObject *, QEvent *)QwtPickervirtual
HLineRubberBand enum valueQwtPicker
initKeyPattern()QwtEventPattern
initMousePattern(int numButtons)QwtEventPattern
invTransform(const QRect &) const QwtPlotPickerprotected
invTransform(const QPoint &) const QwtPlotPickerprotected
isActive() const QwtPicker
isEnabled() const QwtPicker
KeepSize enum valueQwtPicker
KeyAbort enum valueQwtEventPattern
KeyDown enum valueQwtEventPattern
KeyHome enum valueQwtEventPattern
KeyLeft enum valueQwtEventPattern
keyMatch(KeyPatternCode, const QKeyEvent *) const QwtEventPattern
keyMatch(const KeyPattern &, const QKeyEvent *) const QwtEventPatternprotectedvirtual
keyPattern() const QwtEventPattern
keyPattern()QwtEventPattern
KeyPatternCode enum nameQwtEventPattern
KeyPatternCount enum valueQwtEventPattern
KeyRedo enum valueQwtEventPattern
KeyRight enum valueQwtEventPattern
KeySelect1 enum valueQwtEventPattern
KeySelect2 enum valueQwtEventPattern
KeyUndo enum valueQwtEventPattern
KeyUp enum valueQwtEventPattern
mouseMatch(MousePatternCode, const QMouseEvent *) const QwtEventPattern
mouseMatch(const MousePattern &, const QMouseEvent *) const QwtEventPatternprotectedvirtual
mousePattern() const QwtEventPattern
mousePattern()QwtEventPattern
MousePatternCode enum nameQwtEventPattern
MousePatternCount enum valueQwtEventPattern
MouseSelect1 enum valueQwtEventPattern
MouseSelect2 enum valueQwtEventPattern
MouseSelect3 enum valueQwtEventPattern
MouseSelect4 enum valueQwtEventPattern
MouseSelect5 enum valueQwtEventPattern
MouseSelect6 enum valueQwtEventPattern
move(const QPoint &)QwtPlotPickerprotectedvirtual
moved(const QPointF &pos)QwtPlotPickersignal
QwtPicker::moved(const QPoint &pos)QwtPickersignal
NoRubberBand enum valueQwtPicker
parentWidget()QwtPicker
parentWidget() const QwtPicker
pickArea() const QwtPickervirtual
pickedPoints() const QwtPickerprotected
plot()QwtPlotPicker
plot() const QwtPlotPicker
PolygonRubberBand enum valueQwtPicker
QwtEventPattern()QwtEventPattern
QwtPicker(QWidget *parent)QwtPickerexplicit
QwtPicker(RubberBand rubberBand, DisplayMode trackerMode, QWidget *)QwtPickerexplicit
QwtPlotPicker(QWidget *canvas)QwtPlotPickerexplicit
QwtPlotPicker(int xAxis, int yAxis, QWidget *)QwtPlotPickerexplicit
QwtPlotPicker(int xAxis, int yAxis, RubberBand rubberBand, DisplayMode trackerMode, QWidget *)QwtPlotPickerexplicit
RectRubberBand enum valueQwtPicker
remove()QwtPickerprotectedvirtual
removed(const QPoint &pos)QwtPickersignal
reset()QwtPickerprotectedvirtual
ResizeMode enum nameQwtPicker
resizeMode() const QwtPicker
RubberBand enum nameQwtPicker
rubberBand() const QwtPicker
rubberBandMask() const QwtPickervirtual
rubberBandOverlay() const QwtPickerprotected
rubberBandPen() const QwtPicker
scaleRect() const QwtPlotPickerprotected
selected(const QPointF &pos)QwtPlotPickersignal
selected(const QRectF &rect)QwtPlotPickersignal
selected(const QVector< QPointF > &pa)QwtPlotPickersignal
QwtPicker::selected(const QPolygon &polygon)QwtPickersignal
selection() const QwtPicker
setAxis(int xAxis, int yAxis)QwtPlotPickervirtual
setEnabled(bool)QwtPickerslot
setKeyPattern(KeyPatternCode, int keyCode, Qt::KeyboardModifiers modifierCodes=Qt::NoModifier)QwtEventPattern
setKeyPattern(const QVector< KeyPattern > &)QwtEventPattern
setMousePattern(MousePatternCode, Qt::MouseButton button, Qt::KeyboardModifiers=Qt::NoModifier)QwtEventPattern
setMousePattern(const QVector< MousePattern > &)QwtEventPattern
setResizeMode(ResizeMode)QwtPicker
setRubberBand(RubberBand)QwtPicker
setRubberBandPen(const QPen &)QwtPicker
setStateMachine(QwtPickerMachine *)QwtPicker
setTrackerFont(const QFont &)QwtPicker
setTrackerMode(DisplayMode)QwtPicker
setTrackerPen(const QPen &)QwtPicker
stateMachine() const QwtPicker
stateMachine()QwtPicker
Stretch enum valueQwtPicker
stretchSelection(const QSize &oldSize, const QSize &newSize)QwtPickerprotectedvirtual
trackerFont() const QwtPicker
trackerMode() const QwtPicker
trackerOverlay() const QwtPickerprotected
trackerPen() const QwtPicker
trackerPosition() const QwtPicker
trackerRect(const QFont &) const QwtPickervirtual
trackerText(const QPoint &) const QwtPlotPickerprotectedvirtual
trackerTextF(const QPointF &) const QwtPlotPickerprotectedvirtual
transform(const QRectF &) const QwtPlotPickerprotected
transform(const QPointF &) const QwtPlotPickerprotected
transition(const QEvent *)QwtPickerprotectedvirtual
updateDisplay()QwtPickerprotectedvirtual
UserRubberBand enum valueQwtPicker
VLineRubberBand enum valueQwtPicker
widgetEnterEvent(QEvent *)QwtPickerprotectedvirtual
widgetKeyPressEvent(QKeyEvent *)QwtPickerprotectedvirtual
widgetKeyReleaseEvent(QKeyEvent *)QwtPickerprotectedvirtual
widgetLeaveEvent(QEvent *)QwtPickerprotectedvirtual
widgetMouseDoubleClickEvent(QMouseEvent *)QwtPickerprotectedvirtual
widgetMouseMoveEvent(QMouseEvent *)QwtPickerprotectedvirtual
widgetMousePressEvent(QMouseEvent *)QwtPickerprotectedvirtual
widgetMouseReleaseEvent(QMouseEvent *)QwtPickerprotectedvirtual
widgetWheelEvent(QWheelEvent *)QwtPickerprotectedvirtual
xAxis() const QwtPlotPicker
yAxis() const QwtPlotPicker
~QwtEventPattern()QwtEventPatternvirtual
~QwtPicker()QwtPickervirtual
~QwtPlotPicker()QwtPlotPickervirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_picker.html b/ThirdParty/Qwt/doc/html/class_qwt_plot_picker.html new file mode 100644 index 0000000000..827a00f677 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_picker.html @@ -0,0 +1,1115 @@ + + + + + + +Qwt User's Guide: QwtPlotPicker Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtPlotPicker Class Reference
+
+
+ +

QwtPlotPicker provides selections on a plot canvas. + More...

+ +

#include <qwt_plot_picker.h>

+
+Inheritance diagram for QwtPlotPicker:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + +

+Signals

void selected (const QPointF &pos)
 
void selected (const QRectF &rect)
 
void selected (const QVector< QPointF > &pa)
 
void appended (const QPointF &pos)
 
void moved (const QPointF &pos)
 
- Signals inherited from QwtPicker
void activated (bool on)
 
void selected (const QPolygon &polygon)
 
void appended (const QPoint &pos)
 
void moved (const QPoint &pos)
 
void removed (const QPoint &pos)
 
void changed (const QPolygon &selection)
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 QwtPlotPicker (QWidget *canvas)
 Create a plot picker. More...
 
+virtual ~QwtPlotPicker ()
 Destructor.
 
 QwtPlotPicker (int xAxis, int yAxis, QWidget *)
 
 QwtPlotPicker (int xAxis, int yAxis, RubberBand rubberBand, DisplayMode trackerMode, QWidget *)
 
virtual void setAxis (int xAxis, int yAxis)
 
+int xAxis () const
 Return x axis.
 
+int yAxis () const
 Return y axis.
 
QwtPlotplot ()
 
const QwtPlotplot () const
 
QWidget * canvas ()
 
const QWidget * canvas () const
 
- Public Member Functions inherited from QwtPicker
 QwtPicker (QWidget *parent)
 
 QwtPicker (RubberBand rubberBand, DisplayMode trackerMode, QWidget *)
 
+virtual ~QwtPicker ()
 Destructor.
 
void setStateMachine (QwtPickerMachine *)
 
const QwtPickerMachinestateMachine () const
 
QwtPickerMachinestateMachine ()
 
void setRubberBand (RubberBand)
 
RubberBand rubberBand () const
 
void setTrackerMode (DisplayMode)
 Set the display mode of the tracker. More...
 
DisplayMode trackerMode () const
 
void setResizeMode (ResizeMode)
 Set the resize mode. More...
 
ResizeMode resizeMode () const
 
void setRubberBandPen (const QPen &)
 
QPen rubberBandPen () const
 
void setTrackerPen (const QPen &)
 
QPen trackerPen () const
 
void setTrackerFont (const QFont &)
 
QFont trackerFont () const
 
bool isEnabled () const
 
bool isActive () const
 
virtual bool eventFilter (QObject *, QEvent *)
 Event filter. More...
 
+QWidget * parentWidget ()
 Return the parent widget, where the selection happens.
 
+const QWidget * parentWidget () const
 Return the parent widget, where the selection happens.
 
virtual QPainterPath pickArea () const
 
virtual void drawRubberBand (QPainter *) const
 
virtual void drawTracker (QPainter *) const
 
virtual QRegion rubberBandMask () const
 
QPoint trackerPosition () const
 
virtual QRect trackerRect (const QFont &) const
 
QPolygon selection () const
 
- Public Member Functions inherited from QwtEventPattern
 QwtEventPattern ()
 
+virtual ~QwtEventPattern ()
 Destructor.
 
void initMousePattern (int numButtons)
 
void initKeyPattern ()
 
void setMousePattern (MousePatternCode, Qt::MouseButton button, Qt::KeyboardModifiers=Qt::NoModifier)
 
void setKeyPattern (KeyPatternCode, int keyCode, Qt::KeyboardModifiers modifierCodes=Qt::NoModifier)
 
+void setMousePattern (const QVector< MousePattern > &)
 Change the mouse event patterns.
 
+void setKeyPattern (const QVector< KeyPattern > &)
 Change the key event patterns.
 
const QVector< MousePattern > & mousePattern () const
 
const QVector< KeyPattern > & keyPattern () const
 
QVector< MousePattern > & mousePattern ()
 
QVector< KeyPattern > & keyPattern ()
 
bool mouseMatch (MousePatternCode, const QMouseEvent *) const
 Compare a mouse event with an event pattern. More...
 
bool keyMatch (KeyPatternCode, const QKeyEvent *) const
 Compare a key event with an event pattern. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Protected Member Functions

QRectF scaleRect () const
 
QRectF invTransform (const QRect &) const
 
QRect transform (const QRectF &) const
 
QPointF invTransform (const QPoint &) const
 
QPoint transform (const QPointF &) const
 
virtual QwtText trackerText (const QPoint &) const
 
virtual QwtText trackerTextF (const QPointF &) const
 Translate a position into a position string. More...
 
virtual void move (const QPoint &)
 
virtual void append (const QPoint &)
 
virtual bool end (bool ok=true)
 
- Protected Member Functions inherited from QwtPicker
virtual QPolygon adjustedPoints (const QPolygon &) const
 Map the pickedPoints() into a selection() More...
 
virtual void transition (const QEvent *)
 
virtual void begin ()
 
virtual void remove ()
 
virtual bool accept (QPolygon &) const
 Validate and fix up the selection. More...
 
virtual void reset ()
 
virtual void widgetMousePressEvent (QMouseEvent *)
 
virtual void widgetMouseReleaseEvent (QMouseEvent *)
 
virtual void widgetMouseDoubleClickEvent (QMouseEvent *)
 
virtual void widgetMouseMoveEvent (QMouseEvent *)
 
virtual void widgetWheelEvent (QWheelEvent *)
 
virtual void widgetKeyPressEvent (QKeyEvent *)
 
virtual void widgetKeyReleaseEvent (QKeyEvent *)
 
virtual void widgetEnterEvent (QEvent *)
 
virtual void widgetLeaveEvent (QEvent *)
 
virtual void stretchSelection (const QSize &oldSize, const QSize &newSize)
 
+virtual void updateDisplay ()
 Update the state of rubber band and tracker label.
 
const QwtWidgetOverlayrubberBandOverlay () const
 
const QwtWidgetOverlaytrackerOverlay () const
 
const QPolygon & pickedPoints () const
 
- Protected Member Functions inherited from QwtEventPattern
virtual bool mouseMatch (const MousePattern &, const QMouseEvent *) const
 Compare a mouse event with an event pattern. More...
 
virtual bool keyMatch (const KeyPattern &, const QKeyEvent *) const
 Compare a key event with an event pattern. More...
 
+ + + + + + + + + + + + + +

+Additional Inherited Members

- Public Types inherited from QwtPicker
enum  RubberBand {
+  NoRubberBand = 0, +HLineRubberBand, +VLineRubberBand, +CrossRubberBand, +
+  RectRubberBand, +EllipseRubberBand, +PolygonRubberBand, +UserRubberBand = 100 +
+ }
 
enum  DisplayMode { AlwaysOff, +AlwaysOn, +ActiveOnly + }
 Display mode. More...
 
enum  ResizeMode { Stretch, +KeepSize + }
 
- Public Slots inherited from QwtPicker
void setEnabled (bool)
 En/disable the picker. More...
 
+

Detailed Description

+

QwtPlotPicker provides selections on a plot canvas.

+

QwtPlotPicker is a QwtPicker tailored for selections on a plot canvas. It is set to a x-Axis and y-Axis and translates all pixel coordinates into this coordinate system.

+

Constructor & Destructor Documentation

+ +
+
+ + + + + +
+ + + + + + + + +
QwtPlotPicker::QwtPlotPicker (QWidget * canvas)
+
+explicit
+
+ +

Create a plot picker.

+

The picker is set to those x- and y-axis of the plot that are enabled. If both or no x-axis are enabled, the picker is set to QwtPlot::xBottom. If both or no y-axis are enabled, it is set to QwtPlot::yLeft.

+
Parameters
+ + +
canvasPlot canvas to observe, also the parent object
+
+
+
See Also
QwtPlot::autoReplot(), QwtPlot::replot(), scaleRect()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
QwtPlotPicker::QwtPlotPicker (int xAxis,
int yAxis,
QWidget * canvas 
)
+
+explicit
+
+

Create a plot picker

+
Parameters
+ + + + +
xAxisSet the x axis of the picker
yAxisSet the y axis of the picker
canvasPlot canvas to observe, also the parent object
+
+
+
See Also
QwtPlot::autoReplot(), QwtPlot::replot(), scaleRect()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
QwtPlotPicker::QwtPlotPicker (int xAxis,
int yAxis,
RubberBand rubberBand,
DisplayMode trackerMode,
QWidget * canvas 
)
+
+explicit
+
+

Create a plot picker

+
Parameters
+ + + + + + +
xAxisX axis of the picker
yAxisY axis of the picker
rubberBandRubber band style
trackerModeTracker mode
canvasPlot canvas to observe, also the parent object
+
+
+
See Also
QwtPicker, QwtPicker::setSelectionFlags(), QwtPicker::setRubberBand(), QwtPicker::setTrackerMode
+
+QwtPlot::autoReplot(), QwtPlot::replot(), scaleRect()
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + + +
void QwtPlotPicker::append (const QPoint & pos)
+
+protectedvirtual
+
+

Append a point to the selection and update rubber band and tracker.

+
Parameters
+ + +
posAdditional point
+
+
+
See Also
isActive, begin(), end(), move(), appended()
+
Note
The appended(const QPoint &), appended(const QDoublePoint &) signals are emitted.
+ +

Reimplemented from QwtPicker.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtPlotPicker::appended (const QPointF & pos)
+
+signal
+
+

A signal emitted when a point has been appended to the selection

+
Parameters
+ + +
posPosition of the appended point.
+
+
+
See Also
append(). moved()
+ +
+
+ +
+
+ + + + + + + +
QWidget * QwtPlotPicker::canvas ()
+
+
Returns
Observed plot canvas
+ +
+
+ +
+
+ + + + + + + +
const QWidget * QwtPlotPicker::canvas () const
+
+
Returns
Observed plot canvas
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool QwtPlotPicker::end (bool ok = true)
+
+protectedvirtual
+
+

Close a selection setting the state to inactive.

+
Parameters
+ + +
okIf true, complete the selection and emit selected signals otherwise discard the selection.
+
+
+
Returns
True if the selection has been accepted, false otherwise
+ +

Reimplemented from QwtPicker.

+ +

Reimplemented in QwtPlotZoomer.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
QRectF QwtPlotPicker::invTransform (const QRect & rect) const
+
+protected
+
+

Translate a rectangle from pixel into plot coordinates

+
Returns
Rectangle in plot coordinates
+
See Also
transform()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
QPointF QwtPlotPicker::invTransform (const QPoint & pos) const
+
+protected
+
+

Translate a point from pixel into plot coordinates

+
Returns
Point in plot coordinates
+
See Also
transform()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtPlotPicker::move (const QPoint & pos)
+
+protectedvirtual
+
+

Move the last point of the selection

+
Parameters
+ + +
posNew position
+
+
+
See Also
isActive, begin(), end(), append()
+
Note
The moved(const QPoint &), moved(const QDoublePoint &) signals are emitted.
+ +

Reimplemented from QwtPicker.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtPlotPicker::moved (const QPointF & pos)
+
+signal
+
+

A signal emitted whenever the last appended point of the selection has been moved.

+
Parameters
+ + +
posPosition of the moved last point of the selection.
+
+
+
See Also
move(), appended()
+ +
+
+ +
+
+ + + + + + + +
QwtPlot * QwtPlotPicker::plot ()
+
+
Returns
Plot widget, containing the observed plot canvas
+ +
+
+ +
+
+ + + + + + + +
const QwtPlot * QwtPlotPicker::plot () const
+
+
Returns
Plot widget, containing the observed plot canvas
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
QRectF QwtPlotPicker::scaleRect () const
+
+protected
+
+
Returns
Normalized bounding rectangle of the axes
+
See Also
QwtPlot::autoReplot(), QwtPlot::replot().
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtPlotPicker::selected (const QPointF & pos)
+
+signal
+
+

A signal emitted in case of QwtPickerMachine::PointSelection.

+
Parameters
+ + +
posSelected point
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtPlotPicker::selected (const QRectF & rect)
+
+signal
+
+

A signal emitted in case of QwtPickerMachine::RectSelection.

+
Parameters
+ + +
rectSelected rectangle
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtPlotPicker::selected (const QVector< QPointF > & pa)
+
+signal
+
+

A signal emitting the selected points, at the end of a selection.

+
Parameters
+ + +
paSelected points
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void QwtPlotPicker::setAxis (int xAxis,
int yAxis 
)
+
+virtual
+
+

Set the x and y axes of the picker

+
Parameters
+ + + +
xAxisX axis
yAxisY axis
+
+
+ +

Reimplemented in QwtPlotZoomer.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
QwtText QwtPlotPicker::trackerText (const QPoint & pos) const
+
+protectedvirtual
+
+

Translate a pixel position into a position string

+
Parameters
+ + +
posPosition in pixel coordinates
+
+
+
Returns
Position string
+ +

Reimplemented from QwtPicker.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
QwtText QwtPlotPicker::trackerTextF (const QPointF & pos) const
+
+protectedvirtual
+
+ +

Translate a position into a position string.

+

In case of HLineRubberBand the label is the value of the y position, in case of VLineRubberBand the value of the x position. Otherwise the label contains x and y position separated by a ',' .

+

The format for the double to string conversion is "%.4f".

+
Parameters
+ + +
posPosition
+
+
+
Returns
Position string
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
QRect QwtPlotPicker::transform (const QRectF & rect) const
+
+protected
+
+

Translate a rectangle from plot into pixel coordinates

+
Returns
Rectangle in pixel coordinates
+
See Also
invTransform()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
QPoint QwtPlotPicker::transform (const QPointF & pos) const
+
+protected
+
+

Translate a point from plot into pixel coordinates

+
Returns
Point in pixel coordinates
+
See Also
invTransform()
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_picker__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_plot_picker__inherit__graph.map new file mode 100644 index 0000000000..dadc59858c --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_picker__inherit__graph.map @@ -0,0 +1,5 @@ + + + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_picker__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_plot_picker__inherit__graph.md5 new file mode 100644 index 0000000000..0384beef0b --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_picker__inherit__graph.md5 @@ -0,0 +1 @@ +2661c108f7cd464e471e8510cba8328a \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_picker__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_plot_picker__inherit__graph.png new file mode 100644 index 0000000000..2ec1455b6b Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_plot_picker__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_raster_item-members.html b/ThirdParty/Qwt/doc/html/class_qwt_plot_raster_item-members.html new file mode 100644 index 0000000000..e531fca387 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_raster_item-members.html @@ -0,0 +1,193 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtPlotRasterItem Member List
+
+
+ +

This is the complete list of members for QwtPlotRasterItem, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
alpha() const QwtPlotRasterItem
attach(QwtPlot *plot)QwtPlotItem
AutoScale enum valueQwtPlotItem
boundingRect() const QwtPlotRasterItemvirtual
CachePolicy enum nameQwtPlotRasterItem
cachePolicy() const QwtPlotRasterItem
defaultIcon(const QBrush &, const QSizeF &) const QwtPlotItemprotected
detach()QwtPlotItem
draw(QPainter *p, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &rect) const QwtPlotRasterItemvirtual
getCanvasMarginHint(const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasSize, double &left, double &top, double &right, double &bottom) const QwtPlotItemvirtual
hide()QwtPlotItem
imageMap(Qt::Orientation, const QwtScaleMap &map, const QRectF &area, const QSize &imageSize, double pixelSize) const QwtPlotRasterItemprotectedvirtual
interval(Qt::Axis) const QwtPlotRasterItemvirtual
invalidateCache()QwtPlotRasterItem
isVisible() const QwtPlotItem
ItemAttribute enum nameQwtPlotItem
ItemAttributes typedefQwtPlotItem
itemChanged()QwtPlotItemvirtual
ItemInterest enum nameQwtPlotItem
ItemInterests typedefQwtPlotItem
Legend enum valueQwtPlotItem
legendChanged()QwtPlotItemvirtual
legendData() const QwtPlotItemvirtual
legendIcon(int index, const QSizeF &) const QwtPlotItemvirtual
legendIconSize() const QwtPlotItem
LegendInterest enum valueQwtPlotItem
Margins enum valueQwtPlotItem
NoCache enum valueQwtPlotRasterItem
PaintAttribute enum nameQwtPlotRasterItem
PaintAttributes typedefQwtPlotRasterItem
PaintCache enum valueQwtPlotRasterItem
PaintInDeviceResolution enum valueQwtPlotRasterItem
paintRect(const QwtScaleMap &, const QwtScaleMap &) const QwtPlotItem
pixelHint(const QRectF &) const QwtPlotRasterItemvirtual
plot() const QwtPlotItem
QwtPlotItem(const QwtText &title=QwtText())QwtPlotItemexplicit
QwtPlotRasterItem(const QString &title=QString::null)QwtPlotRasterItemexplicit
QwtPlotRasterItem(const QwtText &title)QwtPlotRasterItemexplicit
RenderAntialiased enum valueQwtPlotItem
RenderHint enum nameQwtPlotItem
RenderHints typedefQwtPlotItem
renderImage(const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &area, const QSize &imageSize) const =0QwtPlotRasterItemprotectedpure virtual
renderThreadCount() const QwtPlotItem
rtti() const QwtPlotItemvirtual
Rtti_PlotBarChart enum valueQwtPlotItem
Rtti_PlotCurve enum valueQwtPlotItem
Rtti_PlotGrid enum valueQwtPlotItem
Rtti_PlotHistogram enum valueQwtPlotItem
Rtti_PlotIntervalCurve enum valueQwtPlotItem
Rtti_PlotItem enum valueQwtPlotItem
Rtti_PlotLegend enum valueQwtPlotItem
Rtti_PlotMarker enum valueQwtPlotItem
Rtti_PlotMultiBarChart enum valueQwtPlotItem
Rtti_PlotScale enum valueQwtPlotItem
Rtti_PlotShape enum valueQwtPlotItem
Rtti_PlotSpectroCurve enum valueQwtPlotItem
Rtti_PlotSpectrogram enum valueQwtPlotItem
Rtti_PlotSVG enum valueQwtPlotItem
Rtti_PlotTextLabel enum valueQwtPlotItem
Rtti_PlotTradingCurve enum valueQwtPlotItem
Rtti_PlotUserItem enum valueQwtPlotItem
Rtti_PlotZone enum valueQwtPlotItem
RttiValues enum nameQwtPlotItem
ScaleInterest enum valueQwtPlotItem
scaleRect(const QwtScaleMap &, const QwtScaleMap &) const QwtPlotItem
setAlpha(int alpha)QwtPlotRasterItem
setAxes(int xAxis, int yAxis)QwtPlotItem
setCachePolicy(CachePolicy)QwtPlotRasterItem
setItemAttribute(ItemAttribute, bool on=true)QwtPlotItem
setItemInterest(ItemInterest, bool on=true)QwtPlotItem
setLegendIconSize(const QSize &)QwtPlotItem
setPaintAttribute(PaintAttribute, bool on=true)QwtPlotRasterItem
setRenderHint(RenderHint, bool on=true)QwtPlotItem
setRenderThreadCount(uint numThreads)QwtPlotItem
setTitle(const QString &title)QwtPlotItem
setTitle(const QwtText &title)QwtPlotItem
setVisible(bool)QwtPlotItemvirtual
setXAxis(int axis)QwtPlotItem
setYAxis(int axis)QwtPlotItem
setZ(double z)QwtPlotItem
show()QwtPlotItem
testItemAttribute(ItemAttribute) const QwtPlotItem
testItemInterest(ItemInterest) const QwtPlotItem
testPaintAttribute(PaintAttribute) const QwtPlotRasterItem
testRenderHint(RenderHint) const QwtPlotItem
title() const QwtPlotItem
updateLegend(const QwtPlotItem *, const QList< QwtLegendData > &)QwtPlotItemvirtual
updateScaleDiv(const QwtScaleDiv &, const QwtScaleDiv &)QwtPlotItemvirtual
xAxis() const QwtPlotItem
yAxis() const QwtPlotItem
z() const QwtPlotItem
~QwtPlotItem()QwtPlotItemvirtual
~QwtPlotRasterItem()QwtPlotRasterItemvirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_raster_item.html b/ThirdParty/Qwt/doc/html/class_qwt_plot_raster_item.html new file mode 100644 index 0000000000..4bf185af5f --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_raster_item.html @@ -0,0 +1,837 @@ + + + + + + +Qwt User's Guide: QwtPlotRasterItem Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtPlotRasterItem Class Referenceabstract
+
+
+ +

A class, which displays raster data. + More...

+ +

#include <qwt_plot_rasteritem.h>

+
+Inheritance diagram for QwtPlotRasterItem:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Types

enum  CachePolicy { NoCache, +PaintCache + }
 Cache policy The default policy is NoCache. More...
 
enum  PaintAttribute { PaintInDeviceResolution = 1 + }
 
+typedef QFlags< PaintAttributePaintAttributes
 Paint attributes.
 
- Public Types inherited from QwtPlotItem
enum  RttiValues {
+  Rtti_PlotItem = 0, +Rtti_PlotGrid, +Rtti_PlotScale, +Rtti_PlotLegend, +
+  Rtti_PlotMarker, +Rtti_PlotCurve, +Rtti_PlotSpectroCurve, +Rtti_PlotIntervalCurve, +
+  Rtti_PlotHistogram, +Rtti_PlotSpectrogram, +Rtti_PlotSVG, +Rtti_PlotTradingCurve, +
+  Rtti_PlotBarChart, +Rtti_PlotMultiBarChart, +Rtti_PlotShape, +Rtti_PlotTextLabel, +
+  Rtti_PlotZone, +Rtti_PlotUserItem = 1000 +
+ }
 Runtime type information. More...
 
enum  ItemAttribute { Legend = 0x01, +AutoScale = 0x02, +Margins = 0x04 + }
 Plot Item Attributes. More...
 
enum  ItemInterest { ScaleInterest = 0x01, +LegendInterest = 0x02 + }
 Plot Item Interests. More...
 
enum  RenderHint { RenderAntialiased = 0x1 + }
 Render hints. More...
 
+typedef QFlags< ItemAttributeItemAttributes
 Plot Item Attributes.
 
+typedef QFlags< ItemInterestItemInterests
 Plot Item Interests.
 
+typedef QFlags< RenderHintRenderHints
 Render hints.
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

QwtPlotRasterItem (const QString &title=QString::null)
 Constructor.
 
QwtPlotRasterItem (const QwtText &title)
 Constructor.
 
+virtual ~QwtPlotRasterItem ()
 Destructor.
 
void setPaintAttribute (PaintAttribute, bool on=true)
 
bool testPaintAttribute (PaintAttribute) const
 
void setAlpha (int alpha)
 Set an alpha value for the raster data. More...
 
int alpha () const
 
void setCachePolicy (CachePolicy)
 
CachePolicy cachePolicy () const
 
void invalidateCache ()
 
virtual void draw (QPainter *p, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &rect) const
 Draw the raster data. More...
 
virtual QRectF pixelHint (const QRectF &) const
 Pixel hint. More...
 
virtual QwtInterval interval (Qt::Axis) const
 
virtual QRectF boundingRect () const
 
- Public Member Functions inherited from QwtPlotItem
 QwtPlotItem (const QwtText &title=QwtText())
 
+virtual ~QwtPlotItem ()
 Destroy the QwtPlotItem.
 
void attach (QwtPlot *plot)
 Attach the item to a plot. More...
 
void detach ()
 This method detaches a QwtPlotItem from any QwtPlot it has been associated with. More...
 
+QwtPlotplot () const
 Return attached plot.
 
void setTitle (const QString &title)
 
void setTitle (const QwtText &title)
 
const QwtTexttitle () const
 
virtual int rtti () const
 
void setItemAttribute (ItemAttribute, bool on=true)
 
bool testItemAttribute (ItemAttribute) const
 
void setItemInterest (ItemInterest, bool on=true)
 
bool testItemInterest (ItemInterest) const
 
void setRenderHint (RenderHint, bool on=true)
 
bool testRenderHint (RenderHint) const
 
void setRenderThreadCount (uint numThreads)
 
uint renderThreadCount () const
 
void setLegendIconSize (const QSize &)
 
QSize legendIconSize () const
 
double z () const
 
void setZ (double z)
 Set the z value. More...
 
+void show ()
 Show the item.
 
+void hide ()
 Hide the item.
 
virtual void setVisible (bool)
 
bool isVisible () const
 
void setAxes (int xAxis, int yAxis)
 
void setXAxis (int axis)
 
+int xAxis () const
 Return xAxis.
 
void setYAxis (int axis)
 
+int yAxis () const
 Return yAxis.
 
virtual void itemChanged ()
 
virtual void legendChanged ()
 
virtual void getCanvasMarginHint (const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasSize, double &left, double &top, double &right, double &bottom) const
 Calculate a hint for the canvas margin. More...
 
virtual void updateScaleDiv (const QwtScaleDiv &, const QwtScaleDiv &)
 Update the item to changes of the axes scale division. More...
 
virtual void updateLegend (const QwtPlotItem *, const QList< QwtLegendData > &)
 Update the item to changes of the legend info. More...
 
QRectF scaleRect (const QwtScaleMap &, const QwtScaleMap &) const
 Calculate the bounding scale rectangle of 2 maps. More...
 
QRectF paintRect (const QwtScaleMap &, const QwtScaleMap &) const
 Calculate the bounding paint rectangle of 2 maps. More...
 
virtual QList< QwtLegendDatalegendData () const
 Return all information, that is needed to represent the item on the legend. More...
 
virtual QwtGraphic legendIcon (int index, const QSizeF &) const
 
+ + + + + + + + + + + +

+Protected Member Functions

virtual QImage renderImage (const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &area, const QSize &imageSize) const =0
 Render an image. More...
 
virtual QwtScaleMap imageMap (Qt::Orientation, const QwtScaleMap &map, const QRectF &area, const QSize &imageSize, double pixelSize) const
 Calculate a scale map for painting to an image. More...
 
- Protected Member Functions inherited from QwtPlotItem
QwtGraphic defaultIcon (const QBrush &, const QSizeF &) const
 Return a default icon from a brush. More...
 
+

Detailed Description

+

A class, which displays raster data.

+

Raster data is a grid of pixel values, that can be represented as a QImage. It is used for many types of information like spectrograms, cartograms, geographical maps ...

+

Often a plot has several types of raster data organized in layers. ( f.e a geographical map, with weather statistics ). Using setAlpha() raster items can be stacked easily.

+

QwtPlotRasterItem is only implemented for images of the following formats: QImage::Format_Indexed8, QImage::Format_ARGB32.

+
See Also
QwtPlotSpectrogram
+

Member Enumeration Documentation

+ +
+
+ +

Cache policy The default policy is NoCache.

+ + + +
Enumerator
NoCache  +

renderImage() is called each time the item has to be repainted

+
PaintCache  +

renderImage() is called, whenever the image cache is not valid, or the scales, or the size of the canvas has changed.

+

This type of cache is useful for improving the performance of hide/show operations or manipulations of the alpha value. All other situations are handled by the canvas backing store.

+
+ +
+
+ +
+
+

Attributes to modify the drawing algorithm.

+
See Also
setPaintAttribute(), testPaintAttribute()
+ + +
Enumerator
PaintInDeviceResolution  +

When the image is rendered according to the data pixels ( QwtRasterData::pixelHint() ) it can be expanded to paint device resolution before it is passed to QPainter. The expansion algorithm rounds the pixel borders in the same way as the axis ticks, what is usually better than the scaling algorithm implemented in Qt. Disabling this flag might make sense, to reduce the size of a document/file. If this is possible for a document format depends on the implementation of the specific QPaintEngine.

+
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + + + +
int QwtPlotRasterItem::alpha () const
+
+
Returns
Alpha value of the raster item
+
See Also
setAlpha()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
QRectF QwtPlotRasterItem::boundingRect () const
+
+virtual
+
+
Returns
Bounding rectangle of the data
+
See Also
QwtPlotRasterItem::interval()
+ +

Reimplemented from QwtPlotItem.

+ +
+
+ +
+
+ + + + + + + +
QwtPlotRasterItem::CachePolicy QwtPlotRasterItem::cachePolicy () const
+
+
Returns
Cache policy
+
See Also
CachePolicy, setCachePolicy()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPlotRasterItem::draw (QPainter * painter,
const QwtScaleMapxMap,
const QwtScaleMapyMap,
const QRectF & canvasRect 
) const
+
+virtual
+
+ +

Draw the raster data.

+
Parameters
+ + + + + +
painterPainter
xMapX-Scale Map
yMapY-Scale Map
canvasRectContents rectangle of the plot canvas
+
+
+ +

Implements QwtPlotItem.

+ +

Reimplemented in QwtPlotSpectrogram.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
QwtScaleMap QwtPlotRasterItem::imageMap (Qt::Orientation orientation,
const QwtScaleMapmap,
const QRectF & area,
const QSize & imageSize,
double pixelSize 
) const
+
+protectedvirtual
+
+ +

Calculate a scale map for painting to an image.

+
Parameters
+ + + + + + +
orientationOrientation, Qt::Horizontal means a X axis
mapScale map for rendering the plot item
areaArea to be painted on the image
imageSizeImage size
pixelSizeWidth/Height of a data pixel
+
+
+
Returns
Calculated scale map
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
QwtInterval QwtPlotRasterItem::interval (Qt::Axis axis) const
+
+virtual
+
+
Returns
Bounding interval for an axis
+

This method is intended to be reimplemented by derived classes. The default implementation returns an invalid interval.

+
Parameters
+ + +
axisX, Y, or Z axis
+
+
+ +

Reimplemented in QwtPlotSpectrogram.

+ +
+
+ +
+
+ + + + + + + +
void QwtPlotRasterItem::invalidateCache ()
+
+

Invalidate the paint cache

+
See Also
setCachePolicy()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
QRectF QwtPlotRasterItem::pixelHint (const QRectF & area) const
+
+virtual
+
+ +

Pixel hint.

+

The geometry of a pixel is used to calculated the resolution and alignment of the rendered image.

+

Width and height of the hint need to be the horizontal and vertical distances between 2 neighbored points. The center of the hint has to be the position of any point ( it doesn't matter which one ).

+

Limiting the resolution of the image might significantly improve the performance and heavily reduce the amount of memory when rendering a QImage from the raster data.

+

The default implementation returns an empty rectangle (QRectF()), meaning, that the image will be rendered in target device ( f.e screen ) resolution.

+
Parameters
+ + +
areaIn most implementations the resolution of the data doesn't depend on the requested area.
+
+
+
Returns
Bounding rectangle of a pixel
+
See Also
render(), renderImage()
+ +

Reimplemented in QwtPlotSpectrogram.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
virtual QImage QwtPlotRasterItem::renderImage (const QwtScaleMapxMap,
const QwtScaleMapyMap,
const QRectF & area,
const QSize & imageSize 
) const
+
+protectedpure virtual
+
+ +

Render an image.

+

An implementation of render() might iterate over all pixels of imageRect. Each pixel has to be translated into the corresponding position in scale coordinates using the maps. This position can be used to look up a value in a implementation specific way and to map it into a color.

+
Parameters
+ + + + + +
xMapX-Scale Map
yMapY-Scale Map
areaRequested area for the image in scale coordinates
imageSizeRequested size of the image
+
+
+
Returns
Rendered image
+ +

Implemented in QwtPlotSpectrogram.

+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotRasterItem::setAlpha (int alpha)
+
+ +

Set an alpha value for the raster data.

+

Often a plot has several types of raster data organized in layers. ( f.e a geographical map, with weather statistics ). Using setAlpha() raster items can be stacked easily.

+

The alpha value is a value [0, 255] to control the transparency of the image. 0 represents a fully transparent color, while 255 represents a fully opaque color.

+
Parameters
+ + +
alphaAlpha value
+
+
+
    +
  • alpha >= 0
    + All alpha values of the pixels returned by renderImage() will be set to alpha, beside those with an alpha value of 0 (invalid pixels).
  • +
  • alpha < 0 The alpha values returned by renderImage() are not changed.
  • +
+

The default alpha value is -1.

+
See Also
alpha()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotRasterItem::setCachePolicy (QwtPlotRasterItem::CachePolicy policy)
+
+

Change the cache policy

+

The default policy is NoCache

+
Parameters
+ + +
policyCache policy
+
+
+
See Also
CachePolicy, cachePolicy()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtPlotRasterItem::setPaintAttribute (PaintAttribute attribute,
bool on = true 
)
+
+

Specify an attribute how to draw the raster item

+
Parameters
+ + + +
attributePaint attribute
onOn/Off /sa PaintAttribute, testPaintAttribute()
+
+
+ +
+
+ +
+
+ + + + + + + + +
bool QwtPlotRasterItem::testPaintAttribute (PaintAttribute attribute) const
+
+
Returns
True, when attribute is enabled
+
See Also
PaintAttribute, setPaintAttribute()
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_raster_item__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_plot_raster_item__inherit__graph.map new file mode 100644 index 0000000000..f07343871e --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_raster_item__inherit__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_raster_item__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_plot_raster_item__inherit__graph.md5 new file mode 100644 index 0000000000..9c2e459ba6 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_raster_item__inherit__graph.md5 @@ -0,0 +1 @@ +1a75aebb7005e2bc848ce0a23e6ef5dc \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_raster_item__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_plot_raster_item__inherit__graph.png new file mode 100644 index 0000000000..02b10328eb Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_plot_raster_item__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_renderer-members.html b/ThirdParty/Qwt/doc/html/class_qwt_plot_renderer-members.html new file mode 100644 index 0000000000..f32e2da0ce --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_renderer-members.html @@ -0,0 +1,134 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtPlotRenderer Member List
+
+
+ +

This is the complete list of members for QwtPlotRenderer, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DefaultLayout enum valueQwtPlotRenderer
DiscardBackground enum valueQwtPlotRenderer
DiscardCanvasBackground enum valueQwtPlotRenderer
DiscardCanvasFrame enum valueQwtPlotRenderer
DiscardFlag enum nameQwtPlotRenderer
discardFlags() const QwtPlotRenderer
DiscardFlags typedefQwtPlotRenderer
DiscardFooter enum valueQwtPlotRenderer
DiscardLegend enum valueQwtPlotRenderer
DiscardNone enum valueQwtPlotRenderer
DiscardTitle enum valueQwtPlotRenderer
exportTo(QwtPlot *, const QString &documentName, const QSizeF &sizeMM=QSizeF(300, 200), int resolution=85)QwtPlotRenderer
FrameWithScales enum valueQwtPlotRenderer
LayoutFlag enum nameQwtPlotRenderer
LayoutFlags typedefQwtPlotRenderer
layoutFlags() const QwtPlotRenderer
QwtPlotRenderer(QObject *=NULL)QwtPlotRendererexplicit
render(QwtPlot *, QPainter *, const QRectF &rect) const QwtPlotRenderervirtual
renderCanvas(const QwtPlot *, QPainter *, const QRectF &canvasRect, const QwtScaleMap *maps) const QwtPlotRenderervirtual
renderDocument(QwtPlot *, const QString &fileName, const QSizeF &sizeMM, int resolution=85)QwtPlotRenderer
renderDocument(QwtPlot *, const QString &fileName, const QString &format, const QSizeF &sizeMM, int resolution=85)QwtPlotRenderer
renderFooter(const QwtPlot *, QPainter *, const QRectF &) const QwtPlotRenderervirtual
renderLegend(const QwtPlot *, QPainter *, const QRectF &) const QwtPlotRenderervirtual
renderScale(const QwtPlot *, QPainter *, int axisId, int startDist, int endDist, int baseDist, const QRectF &) const QwtPlotRenderervirtual
renderTitle(const QwtPlot *, QPainter *, const QRectF &) const QwtPlotRenderervirtual
renderTo(QwtPlot *, QPrinter &) const QwtPlotRenderer
renderTo(QwtPlot *, QPaintDevice &p) const QwtPlotRenderer
setDiscardFlag(DiscardFlag flag, bool on=true)QwtPlotRenderer
setDiscardFlags(DiscardFlags flags)QwtPlotRenderer
setLayoutFlag(LayoutFlag flag, bool on=true)QwtPlotRenderer
setLayoutFlags(LayoutFlags flags)QwtPlotRenderer
testDiscardFlag(DiscardFlag flag) const QwtPlotRenderer
testLayoutFlag(LayoutFlag flag) const QwtPlotRenderer
~QwtPlotRenderer()QwtPlotRenderervirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_renderer.html b/ThirdParty/Qwt/doc/html/class_qwt_plot_renderer.html new file mode 100644 index 0000000000..ff0598dc99 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_renderer.html @@ -0,0 +1,1064 @@ + + + + + + +Qwt User's Guide: QwtPlotRenderer Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtPlotRenderer Class Reference
+
+
+ +

Renderer for exporting a plot to a document, a printer or anything else, that is supported by QPainter/QPaintDevice. + More...

+ +

#include <qwt_plot_renderer.h>

+
+Inheritance diagram for QwtPlotRenderer:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + + + + + + + +

+Public Types

enum  DiscardFlag {
+  DiscardNone = 0x00, +DiscardBackground = 0x01, +DiscardTitle = 0x02, +DiscardLegend = 0x04, +
+  DiscardCanvasBackground = 0x08, +DiscardFooter = 0x10, +DiscardCanvasFrame = 0x20 +
+ }
 Disard flags. More...
 
enum  LayoutFlag { DefaultLayout = 0x00, +FrameWithScales = 0x01 + }
 Layout flags. More...
 
+typedef QFlags< DiscardFlagDiscardFlags
 Disard flags.
 
+typedef QFlags< LayoutFlagLayoutFlags
 Layout flags.
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 QwtPlotRenderer (QObject *=NULL)
 
+virtual ~QwtPlotRenderer ()
 Destructor.
 
void setDiscardFlag (DiscardFlag flag, bool on=true)
 
bool testDiscardFlag (DiscardFlag flag) const
 
void setDiscardFlags (DiscardFlags flags)
 
DiscardFlags discardFlags () const
 
void setLayoutFlag (LayoutFlag flag, bool on=true)
 
bool testLayoutFlag (LayoutFlag flag) const
 
void setLayoutFlags (LayoutFlags flags)
 
LayoutFlags layoutFlags () const
 
void renderDocument (QwtPlot *, const QString &fileName, const QSizeF &sizeMM, int resolution=85)
 
void renderDocument (QwtPlot *, const QString &fileName, const QString &format, const QSizeF &sizeMM, int resolution=85)
 
void renderTo (QwtPlot *, QPrinter &) const
 Render the plot to a QPrinter. More...
 
void renderTo (QwtPlot *, QPaintDevice &p) const
 Render the plot to a QPaintDevice. More...
 
virtual void render (QwtPlot *, QPainter *, const QRectF &rect) const
 
virtual void renderTitle (const QwtPlot *, QPainter *, const QRectF &) const
 
virtual void renderFooter (const QwtPlot *, QPainter *, const QRectF &) const
 
virtual void renderScale (const QwtPlot *, QPainter *, int axisId, int startDist, int endDist, int baseDist, const QRectF &) const
 Paint a scale into a given rectangle. Paint the scale into a given rectangle. More...
 
virtual void renderCanvas (const QwtPlot *, QPainter *, const QRectF &canvasRect, const QwtScaleMap *maps) const
 
virtual void renderLegend (const QwtPlot *, QPainter *, const QRectF &) const
 
bool exportTo (QwtPlot *, const QString &documentName, const QSizeF &sizeMM=QSizeF(300, 200), int resolution=85)
 Execute a file dialog and render the plot to the selected file. More...
 
+

Detailed Description

+

Renderer for exporting a plot to a document, a printer or anything else, that is supported by QPainter/QPaintDevice.

+

Member Enumeration Documentation

+ +
+
+ +

Disard flags.

+ + + + + + + + +
Enumerator
DiscardNone  +

Render all components of the plot.

+
DiscardBackground  +

Don't render the background of the plot.

+
DiscardTitle  +

Don't render the title of the plot.

+
DiscardLegend  +

Don't render the legend of the plot.

+
DiscardCanvasBackground  +

Don't render the background of the canvas.

+
DiscardFooter  +

Don't render the footer of the plot.

+
DiscardCanvasFrame  +

Don't render the frame of the canvas

+
Note
This flag has no effect when using style sheets, where the frame is part of the background
+
+ +
+
+ +
+
+ + + + +
enum QwtPlotRenderer::LayoutFlag
+
+ +

Layout flags.

+
See Also
setLayoutFlag(), testLayoutFlag()
+ + + +
Enumerator
DefaultLayout  +

Use the default layout as on screen.

+
FrameWithScales  +

Instead of the scales a box is painted around the plot canvas, where the scale ticks are aligned to.

+
+ +
+
+

Constructor & Destructor Documentation

+ +
+
+ + + + + +
+ + + + + + + + +
QwtPlotRenderer::QwtPlotRenderer (QObject * parent = NULL)
+
+explicit
+
+

Constructor

+
Parameters
+ + +
parentParent object
+
+
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + + + +
QwtPlotRenderer::DiscardFlags QwtPlotRenderer::discardFlags () const
+
+
Returns
Flags, indicating what to discard from rendering
+
See Also
DiscardFlag, setDiscardFlags(), setDiscardFlag(), testDiscardFlag()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool QwtPlotRenderer::exportTo (QwtPlotplot,
const QString & documentName,
const QSizeF & sizeMM = QSizeF( 300, 200 ),
int resolution = 85 
)
+
+ +

Execute a file dialog and render the plot to the selected file.

+
Parameters
+ + + + + +
plotPlot widget
documentNameDefault document name
sizeMMSize for the document in millimeters.
resolutionResolution in dots per Inch (dpi)
+
+
+
Returns
True, when exporting was successful
+
See Also
renderDocument()
+ +
+
+ +
+
+ + + + + + + +
QwtPlotRenderer::LayoutFlags QwtPlotRenderer::layoutFlags () const
+
+
Returns
Layout flags
+
See Also
LayoutFlag, setLayoutFlags(), setLayoutFlag(), testLayoutFlag()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPlotRenderer::render (QwtPlotplot,
QPainter * painter,
const QRectF & plotRect 
) const
+
+virtual
+
+

Paint the contents of a QwtPlot instance into a given rectangle.

+
Parameters
+ + + + +
plotPlot to be rendered
painterPainter
plotRectBounding rectangle
+
+
+
See Also
renderDocument(), renderTo(), QwtPainter::setRoundingAlignment()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPlotRenderer::renderCanvas (const QwtPlotplot,
QPainter * painter,
const QRectF & canvasRect,
const QwtScaleMapmap 
) const
+
+virtual
+
+

Render the canvas into a given rectangle.

+
Parameters
+ + + + + +
plotPlot widget
painterPainter
mapMaps mapping between plot and paint device coordinates
canvasRectCanvas rectangle
+
+
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPlotRenderer::renderDocument (QwtPlotplot,
const QString & fileName,
const QSizeF & sizeMM,
int resolution = 85 
)
+
+

Render a plot to a file

+

The format of the document will be auto-detected from the suffix of the file name.

+
Parameters
+ + + + + +
plotPlot widget
fileNamePath of the file, where the document will be stored
sizeMMSize for the document in millimeters.
resolutionResolution in dots per Inch (dpi)
+
+
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPlotRenderer::renderDocument (QwtPlotplot,
const QString & fileName,
const QString & format,
const QSizeF & sizeMM,
int resolution = 85 
)
+
+

Render a plot to a file

+

Supported formats are:

+
    +
  • pdf
    + Portable Document Format PDF
  • +
  • ps
    + Postcript
  • +
  • svg
    + Scalable Vector Graphics SVG
  • +
  • all image formats supported by Qt
    + see QImageWriter::supportedImageFormats()
  • +
+

Scalable vector graphic formats like PDF or SVG are superior to raster graphics formats.

+
Parameters
+ + + + + + +
plotPlot widget
fileNamePath of the file, where the document will be stored
formatFormat for the document
sizeMMSize for the document in millimeters.
resolutionResolution in dots per Inch (dpi)
+
+
+
See Also
renderTo(), render(), QwtPainter::setRoundingAlignment()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPlotRenderer::renderFooter (const QwtPlotplot,
QPainter * painter,
const QRectF & rect 
) const
+
+virtual
+
+

Render the footer into a given rectangle.

+
Parameters
+ + + + +
plotPlot widget
painterPainter
rectBounding rectangle
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPlotRenderer::renderLegend (const QwtPlotplot,
QPainter * painter,
const QRectF & rect 
) const
+
+virtual
+
+

Render the legend into a given rectangle.

+
Parameters
+ + + + +
plotPlot widget
painterPainter
rectBounding rectangle
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPlotRenderer::renderScale (const QwtPlotplot,
QPainter * painter,
int axisId,
int startDist,
int endDist,
int baseDist,
const QRectF & rect 
) const
+
+virtual
+
+ +

Paint a scale into a given rectangle. Paint the scale into a given rectangle.

+
Parameters
+ + + + + + + + +
plotPlot widget
painterPainter
axisIdAxis
startDistStart border distance
endDistEnd border distance
baseDistBase distance
rectBounding rectangle
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPlotRenderer::renderTitle (const QwtPlotplot,
QPainter * painter,
const QRectF & rect 
) const
+
+virtual
+
+

Render the title into a given rectangle.

+
Parameters
+ + + + +
plotPlot widget
painterPainter
rectBounding rectangle
+
+
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtPlotRenderer::renderTo (QwtPlotplot,
QPrinter & printer 
) const
+
+ +

Render the plot to a QPrinter.

+

This function renders the contents of a QwtPlot instance to QPaintDevice object. The size is derived from the printer metrics.

+
Parameters
+ + + +
plotPlot to be rendered
printerPrinter to paint on
+
+
+
See Also
renderDocument(), render(), QwtPainter::setRoundingAlignment()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtPlotRenderer::renderTo (QwtPlotplot,
QPaintDevice & paintDevice 
) const
+
+ +

Render the plot to a QPaintDevice.

+

This function renders the contents of a QwtPlot instance to QPaintDevice object. The target rectangle is derived from its device metrics.

+
Parameters
+ + + +
plotPlot to be rendered
paintDevicedevice to paint on, f.e a QImage
+
+
+
See Also
renderDocument(), render(), QwtPainter::setRoundingAlignment()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtPlotRenderer::setDiscardFlag (DiscardFlag flag,
bool on = true 
)
+
+

Change a flag, indicating what to discard from rendering

+
Parameters
+ + + +
flagFlag to change
onOn/Off
+
+
+
See Also
DiscardFlag, testDiscardFlag(), setDiscardFlags(), discardFlags()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotRenderer::setDiscardFlags (DiscardFlags flags)
+
+

Set the flags, indicating what to discard from rendering

+
Parameters
+ + +
flagsFlags
+
+
+
See Also
DiscardFlag, setDiscardFlag(), testDiscardFlag(), discardFlags()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtPlotRenderer::setLayoutFlag (LayoutFlag flag,
bool on = true 
)
+
+

Change a layout flag

+
Parameters
+ + + +
flagFlag to change
onOn/Off
+
+
+
See Also
LayoutFlag, testLayoutFlag(), setLayoutFlags(), layoutFlags()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotRenderer::setLayoutFlags (LayoutFlags flags)
+
+

Set the layout flags

+
Parameters
+ + +
flagsFlags
+
+
+
See Also
LayoutFlag, setLayoutFlag(), testLayoutFlag(), layoutFlags()
+ +
+
+ +
+
+ + + + + + + + +
bool QwtPlotRenderer::testDiscardFlag (DiscardFlag flag) const
+
+
Returns
True, if flag is enabled.
+
Parameters
+ + +
flagFlag to be tested
+
+
+
See Also
DiscardFlag, setDiscardFlag(), setDiscardFlags(), discardFlags()
+ +
+
+ +
+
+ + + + + + + + +
bool QwtPlotRenderer::testLayoutFlag (LayoutFlag flag) const
+
+
Returns
True, if flag is enabled.
+
Parameters
+ + +
flagFlag to be tested
+
+
+
See Also
LayoutFlag, setLayoutFlag(), setLayoutFlags(), layoutFlags()
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_renderer__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_plot_renderer__inherit__graph.map new file mode 100644 index 0000000000..453b9e2d28 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_renderer__inherit__graph.map @@ -0,0 +1,2 @@ + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_renderer__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_plot_renderer__inherit__graph.md5 new file mode 100644 index 0000000000..89ba11dafc --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_renderer__inherit__graph.md5 @@ -0,0 +1 @@ +a20eec5ce20e4356d02f95de7e9e32a1 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_renderer__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_plot_renderer__inherit__graph.png new file mode 100644 index 0000000000..08fa07f540 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_plot_renderer__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_rescaler-members.html b/ThirdParty/Qwt/doc/html/class_qwt_plot_rescaler-members.html new file mode 100644 index 0000000000..76ea7c9c37 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_rescaler-members.html @@ -0,0 +1,138 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtPlotRescaler Member List
+
+
+ +

This is the complete list of members for QwtPlotRescaler, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
aspectRatio(int axis) const QwtPlotRescaler
canvas()QwtPlotRescaler
canvas() const QwtPlotRescaler
canvasResizeEvent(QResizeEvent *)QwtPlotRescalerprotectedvirtual
eventFilter(QObject *, QEvent *)QwtPlotRescalervirtual
ExpandBoth enum valueQwtPlotRescaler
ExpandDown enum valueQwtPlotRescaler
Expanding enum valueQwtPlotRescaler
expandingDirection(int axis) const QwtPlotRescaler
ExpandingDirection enum nameQwtPlotRescaler
expandInterval(const QwtInterval &, double width, ExpandingDirection) const QwtPlotRescalerprotected
expandScale(int axis, const QSize &oldSize, const QSize &newSize) const QwtPlotRescalerprotectedvirtual
ExpandUp enum valueQwtPlotRescaler
Fitting enum valueQwtPlotRescaler
Fixed enum valueQwtPlotRescaler
interval(int axis) const QwtPlotRescalerprotected
intervalHint(int axis) const QwtPlotRescaler
isEnabled() const QwtPlotRescaler
orientation(int axis) const QwtPlotRescalerprotected
plot()QwtPlotRescaler
plot() const QwtPlotRescaler
QwtPlotRescaler(QWidget *canvas, int referenceAxis=QwtPlot::xBottom, RescalePolicy=Expanding)QwtPlotRescalerexplicit
referenceAxis() const QwtPlotRescaler
rescale() const QwtPlotRescaler
rescale(const QSize &oldSize, const QSize &newSize) const QwtPlotRescalerprotectedvirtual
RescalePolicy enum nameQwtPlotRescaler
rescalePolicy() const QwtPlotRescaler
setAspectRatio(double ratio)QwtPlotRescaler
setAspectRatio(int axis, double ratio)QwtPlotRescaler
setEnabled(bool)QwtPlotRescaler
setExpandingDirection(ExpandingDirection)QwtPlotRescaler
setExpandingDirection(int axis, ExpandingDirection)QwtPlotRescaler
setIntervalHint(int axis, const QwtInterval &)QwtPlotRescaler
setReferenceAxis(int axis)QwtPlotRescaler
setRescalePolicy(RescalePolicy)QwtPlotRescaler
syncScale(int axis, const QwtInterval &reference, const QSize &size) const QwtPlotRescalerprotectedvirtual
updateScales(QwtInterval intervals[QwtPlot::axisCnt]) const QwtPlotRescalerprotectedvirtual
~QwtPlotRescaler()QwtPlotRescalervirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_rescaler.html b/ThirdParty/Qwt/doc/html/class_qwt_plot_rescaler.html new file mode 100644 index 0000000000..637bcb18e5 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_rescaler.html @@ -0,0 +1,1039 @@ + + + + + + +Qwt User's Guide: QwtPlotRescaler Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+ +
+ +

QwtPlotRescaler takes care of fixed aspect ratios for plot scales. + More...

+ +

#include <qwt_plot_rescaler.h>

+
+Inheritance diagram for QwtPlotRescaler:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + +

+Public Types

enum  RescalePolicy { Fixed, +Expanding, +Fitting + }
 
enum  ExpandingDirection { ExpandUp, +ExpandDown, +ExpandBoth + }
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 QwtPlotRescaler (QWidget *canvas, int referenceAxis=QwtPlot::xBottom, RescalePolicy=Expanding)
 
+virtual ~QwtPlotRescaler ()
 Destructor.
 
void setEnabled (bool)
 En/disable the rescaler. More...
 
bool isEnabled () const
 
void setRescalePolicy (RescalePolicy)
 
RescalePolicy rescalePolicy () const
 
void setExpandingDirection (ExpandingDirection)
 
void setExpandingDirection (int axis, ExpandingDirection)
 
ExpandingDirection expandingDirection (int axis) const
 
void setReferenceAxis (int axis)
 
int referenceAxis () const
 
void setAspectRatio (double ratio)
 
void setAspectRatio (int axis, double ratio)
 
double aspectRatio (int axis) const
 
void setIntervalHint (int axis, const QwtInterval &)
 
QwtInterval intervalHint (int axis) const
 
QWidget * canvas ()
 
const QWidget * canvas () const
 
QwtPlotplot ()
 
const QwtPlotplot () const
 
+virtual bool eventFilter (QObject *, QEvent *)
 Event filter for the plot canvas.
 
+void rescale () const
 Adjust the plot axes scales.
 
+ + + + + + + + + + + + + + + + + +

+Protected Member Functions

virtual void canvasResizeEvent (QResizeEvent *)
 
virtual void rescale (const QSize &oldSize, const QSize &newSize) const
 
virtual QwtInterval expandScale (int axis, const QSize &oldSize, const QSize &newSize) const
 
virtual QwtInterval syncScale (int axis, const QwtInterval &reference, const QSize &size) const
 
virtual void updateScales (QwtInterval intervals[QwtPlot::axisCnt]) const
 
Qt::Orientation orientation (int axis) const
 
QwtInterval interval (int axis) const
 
QwtInterval expandInterval (const QwtInterval &, double width, ExpandingDirection) const
 
+

Detailed Description

+

QwtPlotRescaler takes care of fixed aspect ratios for plot scales.

+

QwtPlotRescaler auto adjusts the axes of a QwtPlot according to fixed aspect ratios.

+

Member Enumeration Documentation

+ +
+
+

When rescalePolicy() is set to Expanding its direction depends on ExpandingDirection

+ + + + +
Enumerator
ExpandUp  +

The upper limit of the scale is adjusted.

+
ExpandDown  +

The lower limit of the scale is adjusted.

+
ExpandBoth  +

Both limits of the scale are adjusted.

+
+ +
+
+ +
+
+

The rescale policy defines how to rescale the reference axis and their depending axes.

+
See Also
ExpandingDirection, setIntervalHint()
+ + + + +
Enumerator
Fixed  +

The interval of the reference axis remains unchanged, when the geometry of the canvas changes. All other axes will be adjusted according to their aspect ratio.

+
Expanding  +

The interval of the reference axis will be shrunk/expanded, when the geometry of the canvas changes. All other axes will be adjusted according to their aspect ratio.

+

The interval, that is represented by one pixel is fixed.

+
Fitting  +

The intervals of the axes are calculated, so that all axes include their interval hint.

+
+ +
+
+

Constructor & Destructor Documentation

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
QwtPlotRescaler::QwtPlotRescaler (QWidget * canvas,
int referenceAxis = QwtPlot::xBottom,
RescalePolicy policy = Expanding 
)
+
+explicit
+
+

Constructor

+
Parameters
+ + + + +
canvasCanvas
referenceAxisReference axis, see RescalePolicy
policyRescale policy
+
+
+
See Also
setRescalePolicy(), setReferenceAxis()
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + + + + +
double QwtPlotRescaler::aspectRatio (int axis) const
+
+
Returns
Aspect ratio between an axis and the reference axis.
+
Parameters
+ + +
axisAxis index ( see QwtPlot::AxisId )
+
+
+
See Also
setAspectRatio()
+ +
+
+ +
+
+ + + + + + + +
QWidget * QwtPlotRescaler::canvas ()
+
+
Returns
plot canvas
+ +
+
+ +
+
+ + + + + + + +
const QWidget * QwtPlotRescaler::canvas () const
+
+
Returns
plot canvas
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtPlotRescaler::canvasResizeEvent (QResizeEvent * event)
+
+protectedvirtual
+
+

Event handler for resize events of the plot canvas

+
Parameters
+ + +
eventResize event
+
+
+
See Also
rescale()
+ +
+
+ +
+
+ + + + + + + + +
QwtPlotRescaler::ExpandingDirection QwtPlotRescaler::expandingDirection (int axis) const
+
+
Returns
Direction in which an axis should be expanded
+
Parameters
+ + +
axisAxis index ( see QwtPlot::AxisId )
+
+
+
See Also
setExpandingDirection()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
QwtInterval QwtPlotRescaler::expandInterval (const QwtIntervalinterval,
double width,
ExpandingDirection direction 
) const
+
+protected
+
+

Expand the interval

+
Parameters
+ + + + +
intervalInterval to be expanded
widthDistance to be added to the interval
directionDirection of the expand operation
+
+
+
Returns
Expanded interval
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
QwtInterval QwtPlotRescaler::expandScale (int axis,
const QSize & oldSize,
const QSize & newSize 
) const
+
+protectedvirtual
+
+

Calculate the new scale interval of a plot axis

+
Parameters
+ + + + +
axisAxis index ( see QwtPlot::AxisId )
oldSizePrevious size of the canvas
newSizeNew size of the canvas
+
+
+
Returns
Calculated new interval for the axis
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
QwtInterval QwtPlotRescaler::interval (int axis) const
+
+protected
+
+
Parameters
+ + +
axisAxis index ( see QwtPlot::AxisId )
+
+
+
Returns
Normalized interval of an axis
+ +
+
+ +
+
+ + + + + + + + +
QwtInterval QwtPlotRescaler::intervalHint (int axis) const
+
+
Parameters
+ + +
axisAxis, see QwtPlot::Axis
+
+
+
Returns
Interval hint
+
See Also
setIntervalHint(), RescalePolicy
+ +
+
+ +
+
+ + + + + + + +
bool QwtPlotRescaler::isEnabled () const
+
+
Returns
true when enabled, false otherwise
+
See Also
setEnabled, eventFilter()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
Qt::Orientation QwtPlotRescaler::orientation (int axis) const
+
+protected
+
+
Returns
Orientation of an axis
+
Parameters
+ + +
axisAxis index ( see QwtPlot::AxisId )
+
+
+ +
+
+ +
+
+ + + + + + + +
QwtPlot * QwtPlotRescaler::plot ()
+
+
Returns
plot widget
+ +
+
+ +
+
+ + + + + + + +
const QwtPlot * QwtPlotRescaler::plot () const
+
+
Returns
plot widget
+ +
+
+ +
+
+ + + + + + + +
int QwtPlotRescaler::referenceAxis () const
+
+
Returns
Reference axis ( see RescalePolicy )
+
See Also
setReferenceAxis()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void QwtPlotRescaler::rescale (const QSize & oldSize,
const QSize & newSize 
) const
+
+protectedvirtual
+
+

Adjust the plot axes scales

+
Parameters
+ + + +
oldSizePrevious size of the canvas
newSizeNew size of the canvas
+
+
+ +
+
+ +
+
+ + + + + + + +
QwtPlotRescaler::RescalePolicy QwtPlotRescaler::rescalePolicy () const
+
+
Returns
Rescale policy
+
See Also
setRescalePolicy()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotRescaler::setAspectRatio (double ratio)
+
+

Set the aspect ratio between the scale of the reference axis and the other scales. The default ratio is 1.0

+
Parameters
+ + +
ratioAspect ratio
+
+
+
See Also
aspectRatio()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtPlotRescaler::setAspectRatio (int axis,
double ratio 
)
+
+

Set the aspect ratio between the scale of the reference axis and another scale. The default ratio is 1.0

+
Parameters
+ + + +
axisAxis index ( see QwtPlot::AxisId )
ratioAspect ratio
+
+
+
See Also
aspectRatio()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotRescaler::setEnabled (bool on)
+
+ +

En/disable the rescaler.

+

When enabled is true an event filter is installed for the canvas, otherwise the event filter is removed.

+
Parameters
+ + +
ontrue or false
+
+
+
See Also
isEnabled(), eventFilter()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotRescaler::setExpandingDirection (ExpandingDirection direction)
+
+

Set the direction in which all axis should be expanded

+
Parameters
+ + +
directionDirection
+
+
+
See Also
expandingDirection()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtPlotRescaler::setExpandingDirection (int axis,
ExpandingDirection direction 
)
+
+

Set the direction in which an axis should be expanded

+
Parameters
+ + + +
axisAxis index ( see QwtPlot::AxisId )
directionDirection
+
+
+
See Also
expandingDirection()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtPlotRescaler::setIntervalHint (int axis,
const QwtIntervalinterval 
)
+
+

Set an interval hint for an axis

+

In Fitting mode, the hint is used as minimal interval that always needs to be displayed.

+
Parameters
+ + + +
axisAxis, see QwtPlot::Axis
intervalAxis
+
+
+
See Also
intervalHint(), RescalePolicy
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotRescaler::setReferenceAxis (int axis)
+
+

Set the reference axis ( see RescalePolicy )

+
Parameters
+ + +
axisAxis index ( QwtPlot::Axis )
+
+
+
See Also
referenceAxis()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotRescaler::setRescalePolicy (RescalePolicy policy)
+
+

Change the rescale policy

+
Parameters
+ + +
policyRescale policy
+
+
+
See Also
rescalePolicy()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
QwtInterval QwtPlotRescaler::syncScale (int axis,
const QwtIntervalreference,
const QSize & size 
) const
+
+protectedvirtual
+
+

Synchronize an axis scale according to the scale of the reference axis

+
Parameters
+ + + + +
axisAxis index ( see QwtPlot::AxisId )
referenceInterval of the reference axis
sizeSize of the canvas
+
+
+
Returns
New interval for axis
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtPlotRescaler::updateScales (QwtInterval intervals[QwtPlot::axisCnt]) const
+
+protectedvirtual
+
+

Update the axes scales

+
Parameters
+ + +
intervalsScale intervals
+
+
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_rescaler__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_plot_rescaler__inherit__graph.map new file mode 100644 index 0000000000..0a894d844d --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_rescaler__inherit__graph.map @@ -0,0 +1,2 @@ + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_rescaler__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_plot_rescaler__inherit__graph.md5 new file mode 100644 index 0000000000..d90ede4367 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_rescaler__inherit__graph.md5 @@ -0,0 +1 @@ +c4d3d609c8dfe83eb15d0d83ad3e0912 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_rescaler__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_plot_rescaler__inherit__graph.png new file mode 100644 index 0000000000..d80ba56b7c Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_plot_rescaler__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_scale_item-members.html b/ThirdParty/Qwt/doc/html/class_qwt_plot_scale_item-members.html new file mode 100644 index 0000000000..5214bf8768 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_scale_item-members.html @@ -0,0 +1,191 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtPlotScaleItem Member List
+
+
+ +

This is the complete list of members for QwtPlotScaleItem, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
attach(QwtPlot *plot)QwtPlotItem
AutoScale enum valueQwtPlotItem
borderDistance() const QwtPlotScaleItem
boundingRect() const QwtPlotItemvirtual
defaultIcon(const QBrush &, const QSizeF &) const QwtPlotItemprotected
detach()QwtPlotItem
draw(QPainter *p, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &rect) const QwtPlotScaleItemvirtual
font() const QwtPlotScaleItem
getCanvasMarginHint(const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasSize, double &left, double &top, double &right, double &bottom) const QwtPlotItemvirtual
hide()QwtPlotItem
isScaleDivFromAxis() const QwtPlotScaleItem
isVisible() const QwtPlotItem
ItemAttribute enum nameQwtPlotItem
ItemAttributes typedefQwtPlotItem
itemChanged()QwtPlotItemvirtual
ItemInterest enum nameQwtPlotItem
ItemInterests typedefQwtPlotItem
Legend enum valueQwtPlotItem
legendChanged()QwtPlotItemvirtual
legendData() const QwtPlotItemvirtual
legendIcon(int index, const QSizeF &) const QwtPlotItemvirtual
legendIconSize() const QwtPlotItem
LegendInterest enum valueQwtPlotItem
Margins enum valueQwtPlotItem
paintRect(const QwtScaleMap &, const QwtScaleMap &) const QwtPlotItem
palette() const QwtPlotScaleItem
plot() const QwtPlotItem
position() const QwtPlotScaleItem
QwtPlotItem(const QwtText &title=QwtText())QwtPlotItemexplicit
QwtPlotScaleItem(QwtScaleDraw::Alignment=QwtScaleDraw::BottomScale, const double pos=0.0)QwtPlotScaleItemexplicit
RenderAntialiased enum valueQwtPlotItem
RenderHint enum nameQwtPlotItem
RenderHints typedefQwtPlotItem
renderThreadCount() const QwtPlotItem
rtti() const QwtPlotScaleItemvirtual
Rtti_PlotBarChart enum valueQwtPlotItem
Rtti_PlotCurve enum valueQwtPlotItem
Rtti_PlotGrid enum valueQwtPlotItem
Rtti_PlotHistogram enum valueQwtPlotItem
Rtti_PlotIntervalCurve enum valueQwtPlotItem
Rtti_PlotItem enum valueQwtPlotItem
Rtti_PlotLegend enum valueQwtPlotItem
Rtti_PlotMarker enum valueQwtPlotItem
Rtti_PlotMultiBarChart enum valueQwtPlotItem
Rtti_PlotScale enum valueQwtPlotItem
Rtti_PlotShape enum valueQwtPlotItem
Rtti_PlotSpectroCurve enum valueQwtPlotItem
Rtti_PlotSpectrogram enum valueQwtPlotItem
Rtti_PlotSVG enum valueQwtPlotItem
Rtti_PlotTextLabel enum valueQwtPlotItem
Rtti_PlotTradingCurve enum valueQwtPlotItem
Rtti_PlotUserItem enum valueQwtPlotItem
Rtti_PlotZone enum valueQwtPlotItem
RttiValues enum nameQwtPlotItem
scaleDiv() const QwtPlotScaleItem
scaleDraw() const QwtPlotScaleItem
scaleDraw()QwtPlotScaleItem
ScaleInterest enum valueQwtPlotItem
scaleRect(const QwtScaleMap &, const QwtScaleMap &) const QwtPlotItem
setAlignment(QwtScaleDraw::Alignment)QwtPlotScaleItem
setAxes(int xAxis, int yAxis)QwtPlotItem
setBorderDistance(int numPixels)QwtPlotScaleItem
setFont(const QFont &)QwtPlotScaleItem
setItemAttribute(ItemAttribute, bool on=true)QwtPlotItem
setItemInterest(ItemInterest, bool on=true)QwtPlotItem
setLegendIconSize(const QSize &)QwtPlotItem
setPalette(const QPalette &)QwtPlotScaleItem
setPosition(double pos)QwtPlotScaleItem
setRenderHint(RenderHint, bool on=true)QwtPlotItem
setRenderThreadCount(uint numThreads)QwtPlotItem
setScaleDiv(const QwtScaleDiv &)QwtPlotScaleItem
setScaleDivFromAxis(bool on)QwtPlotScaleItem
setScaleDraw(QwtScaleDraw *)QwtPlotScaleItem
setTitle(const QString &title)QwtPlotItem
setTitle(const QwtText &title)QwtPlotItem
setVisible(bool)QwtPlotItemvirtual
setXAxis(int axis)QwtPlotItem
setYAxis(int axis)QwtPlotItem
setZ(double z)QwtPlotItem
show()QwtPlotItem
testItemAttribute(ItemAttribute) const QwtPlotItem
testItemInterest(ItemInterest) const QwtPlotItem
testRenderHint(RenderHint) const QwtPlotItem
title() const QwtPlotItem
updateLegend(const QwtPlotItem *, const QList< QwtLegendData > &)QwtPlotItemvirtual
updateScaleDiv(const QwtScaleDiv &, const QwtScaleDiv &)QwtPlotScaleItemvirtual
xAxis() const QwtPlotItem
yAxis() const QwtPlotItem
z() const QwtPlotItem
~QwtPlotItem()QwtPlotItemvirtual
~QwtPlotScaleItem()QwtPlotScaleItemvirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_scale_item.html b/ThirdParty/Qwt/doc/html/class_qwt_plot_scale_item.html new file mode 100644 index 0000000000..2eef911294 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_scale_item.html @@ -0,0 +1,783 @@ + + + + + + +Qwt User's Guide: QwtPlotScaleItem Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtPlotScaleItem Class Reference
+
+
+ +

A class which draws a scale inside the plot canvas. + More...

+ +

#include <qwt_plot_scaleitem.h>

+
+Inheritance diagram for QwtPlotScaleItem:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 QwtPlotScaleItem (QwtScaleDraw::Alignment=QwtScaleDraw::BottomScale, const double pos=0.0)
 Constructor for scale item at the position pos. More...
 
+virtual ~QwtPlotScaleItem ()
 Destructor.
 
virtual int rtti () const
 
void setScaleDiv (const QwtScaleDiv &)
 Assign a scale division. More...
 
const QwtScaleDivscaleDiv () const
 
void setScaleDivFromAxis (bool on)
 
bool isScaleDivFromAxis () const
 
void setPalette (const QPalette &)
 
QPalette palette () const
 
void setFont (const QFont &)
 
QFont font () const
 
void setScaleDraw (QwtScaleDraw *)
 Set a scale draw. More...
 
const QwtScaleDrawscaleDraw () const
 
QwtScaleDrawscaleDraw ()
 
void setPosition (double pos)
 
double position () const
 
void setBorderDistance (int numPixels)
 Align the scale to the canvas. More...
 
int borderDistance () const
 
void setAlignment (QwtScaleDraw::Alignment)
 
+virtual void draw (QPainter *p, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &rect) const
 Draw the scale.
 
virtual void updateScaleDiv (const QwtScaleDiv &, const QwtScaleDiv &)
 Update the item to changes of the axes scale division. More...
 
- Public Member Functions inherited from QwtPlotItem
 QwtPlotItem (const QwtText &title=QwtText())
 
+virtual ~QwtPlotItem ()
 Destroy the QwtPlotItem.
 
void attach (QwtPlot *plot)
 Attach the item to a plot. More...
 
void detach ()
 This method detaches a QwtPlotItem from any QwtPlot it has been associated with. More...
 
+QwtPlotplot () const
 Return attached plot.
 
void setTitle (const QString &title)
 
void setTitle (const QwtText &title)
 
const QwtTexttitle () const
 
void setItemAttribute (ItemAttribute, bool on=true)
 
bool testItemAttribute (ItemAttribute) const
 
void setItemInterest (ItemInterest, bool on=true)
 
bool testItemInterest (ItemInterest) const
 
void setRenderHint (RenderHint, bool on=true)
 
bool testRenderHint (RenderHint) const
 
void setRenderThreadCount (uint numThreads)
 
uint renderThreadCount () const
 
void setLegendIconSize (const QSize &)
 
QSize legendIconSize () const
 
double z () const
 
void setZ (double z)
 Set the z value. More...
 
+void show ()
 Show the item.
 
+void hide ()
 Hide the item.
 
virtual void setVisible (bool)
 
bool isVisible () const
 
void setAxes (int xAxis, int yAxis)
 
void setXAxis (int axis)
 
+int xAxis () const
 Return xAxis.
 
void setYAxis (int axis)
 
+int yAxis () const
 Return yAxis.
 
virtual void itemChanged ()
 
virtual void legendChanged ()
 
virtual QRectF boundingRect () const
 
virtual void getCanvasMarginHint (const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasSize, double &left, double &top, double &right, double &bottom) const
 Calculate a hint for the canvas margin. More...
 
virtual void updateLegend (const QwtPlotItem *, const QList< QwtLegendData > &)
 Update the item to changes of the legend info. More...
 
QRectF scaleRect (const QwtScaleMap &, const QwtScaleMap &) const
 Calculate the bounding scale rectangle of 2 maps. More...
 
QRectF paintRect (const QwtScaleMap &, const QwtScaleMap &) const
 Calculate the bounding paint rectangle of 2 maps. More...
 
virtual QList< QwtLegendDatalegendData () const
 Return all information, that is needed to represent the item on the legend. More...
 
virtual QwtGraphic legendIcon (int index, const QSizeF &) const
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Additional Inherited Members

- Public Types inherited from QwtPlotItem
enum  RttiValues {
+  Rtti_PlotItem = 0, +Rtti_PlotGrid, +Rtti_PlotScale, +Rtti_PlotLegend, +
+  Rtti_PlotMarker, +Rtti_PlotCurve, +Rtti_PlotSpectroCurve, +Rtti_PlotIntervalCurve, +
+  Rtti_PlotHistogram, +Rtti_PlotSpectrogram, +Rtti_PlotSVG, +Rtti_PlotTradingCurve, +
+  Rtti_PlotBarChart, +Rtti_PlotMultiBarChart, +Rtti_PlotShape, +Rtti_PlotTextLabel, +
+  Rtti_PlotZone, +Rtti_PlotUserItem = 1000 +
+ }
 Runtime type information. More...
 
enum  ItemAttribute { Legend = 0x01, +AutoScale = 0x02, +Margins = 0x04 + }
 Plot Item Attributes. More...
 
enum  ItemInterest { ScaleInterest = 0x01, +LegendInterest = 0x02 + }
 Plot Item Interests. More...
 
enum  RenderHint { RenderAntialiased = 0x1 + }
 Render hints. More...
 
+typedef QFlags< ItemAttributeItemAttributes
 Plot Item Attributes.
 
+typedef QFlags< ItemInterestItemInterests
 Plot Item Interests.
 
+typedef QFlags< RenderHintRenderHints
 Render hints.
 
- Protected Member Functions inherited from QwtPlotItem
QwtGraphic defaultIcon (const QBrush &, const QSizeF &) const
 Return a default icon from a brush. More...
 
+

Detailed Description

+

A class which draws a scale inside the plot canvas.

+

QwtPlotScaleItem can be used to draw an axis inside the plot canvas. It might by synchronized to one of the axis of the plot, but can also display its own ticks and labels.

+

It is allowed to synchronize the scale item with a disabled axis. In plots with vertical and horizontal scale items, it might be necessary to remove ticks at the intersections, by overloading updateScaleDiv().

+

The scale might be at a specific position (f.e 0.0) or it might be aligned to a canvas border.

+
Example
The following example shows how to replace the left axis, by a scale item at the x position 0.0.
QwtPlotScaleItem *scaleItem =
+    new QwtPlotScaleItem(QwtScaleDraw::RightScale, 0.0);
+scaleItem->setFont(plot->axisWidget(QwtPlot::yLeft)->font());
+scaleItem->attach(plot);
+
+plot->enableAxis(QwtPlot::yLeft, false);
+
+

Constructor & Destructor Documentation

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
QwtPlotScaleItem::QwtPlotScaleItem (QwtScaleDraw::Alignment alignment = QwtScaleDraw::BottomScale,
const double pos = 0.0 
)
+
+explicit
+
+ +

Constructor for scale item at the position pos.

+
Parameters
+ + + +
alignmentIn case of QwtScaleDraw::BottomScale or QwtScaleDraw::TopScale the scale item is corresponding to the xAxis(), otherwise it corresponds to the yAxis().
posx or y position, depending on the corresponding axis.
+
+
+
See Also
setPosition(), setAlignment()
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + + + +
int QwtPlotScaleItem::borderDistance () const
+
+
Returns
Distance from a canvas border
+
See Also
setBorderDistance(), setPosition()
+ +
+
+ +
+
+ + + + + + + +
QFont QwtPlotScaleItem::font () const
+
+
Returns
tick label font
+
See Also
setFont()
+ +
+
+ +
+
+ + + + + + + +
bool QwtPlotScaleItem::isScaleDivFromAxis () const
+
+
Returns
True, if the synchronization of the scale division with the corresponding axis is enabled.
+
See Also
setScaleDiv(), setScaleDivFromAxis()
+ +
+
+ +
+
+ + + + + + + +
QPalette QwtPlotScaleItem::palette () const
+
+
Returns
palette
+
See Also
setPalette()
+ +
+
+ +
+
+ + + + + + + +
double QwtPlotScaleItem::position () const
+
+
Returns
Position of the scale
+
See Also
setPosition(), setAlignment()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
int QwtPlotScaleItem::rtti () const
+
+virtual
+
+
Returns
QwtPlotItem::Rtti_PlotScale
+ +

Reimplemented from QwtPlotItem.

+ +
+
+ +
+
+ + + + + + + +
const QwtScaleDiv & QwtPlotScaleItem::scaleDiv () const
+
+
Returns
Scale division
+ +
+
+ +
+
+ + + + + + + +
const QwtScaleDraw * QwtPlotScaleItem::scaleDraw () const
+
+
Returns
Scale draw
+
See Also
setScaleDraw()
+ +
+
+ +
+
+ + + + + + + +
QwtScaleDraw * QwtPlotScaleItem::scaleDraw ()
+
+
Returns
Scale draw
+
See Also
setScaleDraw()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotScaleItem::setAlignment (QwtScaleDraw::Alignment alignment)
+
+

Change the alignment of the scale

+

The alignment sets the orientation of the scale and the position of the ticks:

+ +

For horizontal scales the position corresponds to QwtPlotItem::yAxis(), otherwise to QwtPlotItem::xAxis().

+
See Also
scaleDraw(), QwtScaleDraw::alignment(), setPosition()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotScaleItem::setBorderDistance (int distance)
+
+ +

Align the scale to the canvas.

+

If distance is >= 0 the scale will be aligned to a border of the contents rectangle of the canvas. If alignment() is QwtScaleDraw::LeftScale, the scale will be aligned to the right border, if it is QwtScaleDraw::TopScale it will be aligned to the bottom (and vice versa),

+

If distance is < 0 the scale will be at the position().

+
Parameters
+ + +
distanceNumber of pixels between the canvas border and the backbone of the scale.
+
+
+
See Also
setPosition(), borderDistance()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotScaleItem::setFont (const QFont & font)
+
+

Change the tick label font

+
See Also
font()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotScaleItem::setPalette (const QPalette & palette)
+
+

Set the palette

+
See Also
QwtAbstractScaleDraw::draw(), palette()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotScaleItem::setPosition (double pos)
+
+

Change the position of the scale

+

The position is interpreted as y value for horizontal axes and as x value for vertical axes.

+

The border distance is set to -1.

+
Parameters
+ + +
posNew position
+
+
+
See Also
position(), setAlignment()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotScaleItem::setScaleDiv (const QwtScaleDivscaleDiv)
+
+ +

Assign a scale division.

+

When assigning a scaleDiv the scale division won't be synchronized with the corresponding axis anymore.

+
Parameters
+ + +
scaleDivScale division
+
+
+
See Also
scaleDiv(), setScaleDivFromAxis(), isScaleDivFromAxis()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotScaleItem::setScaleDivFromAxis (bool on)
+
+

Enable/Disable the synchronization of the scale division with the corresponding axis.

+
Parameters
+ + +
ontrue/false
+
+
+
See Also
isScaleDivFromAxis()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotScaleItem::setScaleDraw (QwtScaleDrawscaleDraw)
+
+ +

Set a scale draw.

+
Parameters
+ + +
scaleDrawobject responsible for drawing scales.
+
+
+

The main use case for replacing the default QwtScaleDraw is to overload QwtAbstractScaleDraw::label, to replace or swallow tick labels.

+
See Also
scaleDraw()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void QwtPlotScaleItem::updateScaleDiv (const QwtScaleDivxScaleDiv,
const QwtScaleDivyScaleDiv 
)
+
+virtual
+
+ +

Update the item to changes of the axes scale division.

+

In case of isScaleDivFromAxis(), the scale draw is synchronized to the correspond axis.

+
Parameters
+ + + +
xScaleDivScale division of the x-axis
yScaleDivScale division of the y-axis
+
+
+
See Also
QwtPlot::updateAxes()
+ +

Reimplemented from QwtPlotItem.

+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_scale_item__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_plot_scale_item__inherit__graph.map new file mode 100644 index 0000000000..cf96572319 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_scale_item__inherit__graph.map @@ -0,0 +1,3 @@ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_scale_item__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_plot_scale_item__inherit__graph.md5 new file mode 100644 index 0000000000..80d497353e --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_scale_item__inherit__graph.md5 @@ -0,0 +1 @@ +c9853d6fec342a40ae32584d6557b28f \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_scale_item__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_plot_scale_item__inherit__graph.png new file mode 100644 index 0000000000..7b894c97fb Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_plot_scale_item__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_series_item-members.html b/ThirdParty/Qwt/doc/html/class_qwt_plot_series_item-members.html new file mode 100644 index 0000000000..b628ba4c90 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_series_item-members.html @@ -0,0 +1,184 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtPlotSeriesItem Member List
+
+
+ +

This is the complete list of members for QwtPlotSeriesItem, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
attach(QwtPlot *plot)QwtPlotItem
AutoScale enum valueQwtPlotItem
boundingRect() const QwtPlotSeriesItemvirtual
dataChanged()QwtPlotSeriesItemprotectedvirtual
dataRect() const =0QwtAbstractSeriesStoreprotectedpure virtual
dataSize() const =0QwtAbstractSeriesStoreprotectedpure virtual
defaultIcon(const QBrush &, const QSizeF &) const QwtPlotItemprotected
detach()QwtPlotItem
draw(QPainter *p, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &) const QwtPlotSeriesItemvirtual
drawSeries(QPainter *painter, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, int from, int to) const =0QwtPlotSeriesItempure virtual
getCanvasMarginHint(const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasSize, double &left, double &top, double &right, double &bottom) const QwtPlotItemvirtual
hide()QwtPlotItem
isVisible() const QwtPlotItem
ItemAttribute enum nameQwtPlotItem
ItemAttributes typedefQwtPlotItem
itemChanged()QwtPlotItemvirtual
ItemInterest enum nameQwtPlotItem
ItemInterests typedefQwtPlotItem
Legend enum valueQwtPlotItem
legendChanged()QwtPlotItemvirtual
legendData() const QwtPlotItemvirtual
legendIcon(int index, const QSizeF &) const QwtPlotItemvirtual
legendIconSize() const QwtPlotItem
LegendInterest enum valueQwtPlotItem
Margins enum valueQwtPlotItem
orientation() const QwtPlotSeriesItem
paintRect(const QwtScaleMap &, const QwtScaleMap &) const QwtPlotItem
plot() const QwtPlotItem
QwtPlotItem(const QwtText &title=QwtText())QwtPlotItemexplicit
QwtPlotSeriesItem(const QString &title=QString::null)QwtPlotSeriesItemexplicit
QwtPlotSeriesItem(const QwtText &title)QwtPlotSeriesItemexplicit
RenderAntialiased enum valueQwtPlotItem
RenderHint enum nameQwtPlotItem
RenderHints typedefQwtPlotItem
renderThreadCount() const QwtPlotItem
rtti() const QwtPlotItemvirtual
Rtti_PlotBarChart enum valueQwtPlotItem
Rtti_PlotCurve enum valueQwtPlotItem
Rtti_PlotGrid enum valueQwtPlotItem
Rtti_PlotHistogram enum valueQwtPlotItem
Rtti_PlotIntervalCurve enum valueQwtPlotItem
Rtti_PlotItem enum valueQwtPlotItem
Rtti_PlotLegend enum valueQwtPlotItem
Rtti_PlotMarker enum valueQwtPlotItem
Rtti_PlotMultiBarChart enum valueQwtPlotItem
Rtti_PlotScale enum valueQwtPlotItem
Rtti_PlotShape enum valueQwtPlotItem
Rtti_PlotSpectroCurve enum valueQwtPlotItem
Rtti_PlotSpectrogram enum valueQwtPlotItem
Rtti_PlotSVG enum valueQwtPlotItem
Rtti_PlotTextLabel enum valueQwtPlotItem
Rtti_PlotTradingCurve enum valueQwtPlotItem
Rtti_PlotUserItem enum valueQwtPlotItem
Rtti_PlotZone enum valueQwtPlotItem
RttiValues enum nameQwtPlotItem
ScaleInterest enum valueQwtPlotItem
scaleRect(const QwtScaleMap &, const QwtScaleMap &) const QwtPlotItem
setAxes(int xAxis, int yAxis)QwtPlotItem
setItemAttribute(ItemAttribute, bool on=true)QwtPlotItem
setItemInterest(ItemInterest, bool on=true)QwtPlotItem
setLegendIconSize(const QSize &)QwtPlotItem
setOrientation(Qt::Orientation)QwtPlotSeriesItem
setRectOfInterest(const QRectF &)=0QwtAbstractSeriesStoreprotectedpure virtual
setRenderHint(RenderHint, bool on=true)QwtPlotItem
setRenderThreadCount(uint numThreads)QwtPlotItem
setTitle(const QString &title)QwtPlotItem
setTitle(const QwtText &title)QwtPlotItem
setVisible(bool)QwtPlotItemvirtual
setXAxis(int axis)QwtPlotItem
setYAxis(int axis)QwtPlotItem
setZ(double z)QwtPlotItem
show()QwtPlotItem
testItemAttribute(ItemAttribute) const QwtPlotItem
testItemInterest(ItemInterest) const QwtPlotItem
testRenderHint(RenderHint) const QwtPlotItem
title() const QwtPlotItem
updateLegend(const QwtPlotItem *, const QList< QwtLegendData > &)QwtPlotItemvirtual
updateScaleDiv(const QwtScaleDiv &, const QwtScaleDiv &)QwtPlotSeriesItemvirtual
xAxis() const QwtPlotItem
yAxis() const QwtPlotItem
z() const QwtPlotItem
~QwtAbstractSeriesStore()QwtAbstractSeriesStoreinlineprotectedvirtual
~QwtPlotItem()QwtPlotItemvirtual
~QwtPlotSeriesItem()QwtPlotSeriesItemvirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_series_item.html b/ThirdParty/Qwt/doc/html/class_qwt_plot_series_item.html new file mode 100644 index 0000000000..fd50f0701c --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_series_item.html @@ -0,0 +1,626 @@ + + + + + + +Qwt User's Guide: QwtPlotSeriesItem Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtPlotSeriesItem Class Referenceabstract
+
+
+ +

Base class for plot items representing a series of samples. + More...

+ +

#include <qwt_plot_seriesitem.h>

+
+Inheritance diagram for QwtPlotSeriesItem:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 QwtPlotSeriesItem (const QString &title=QString::null)
 
 QwtPlotSeriesItem (const QwtText &title)
 
+virtual ~QwtPlotSeriesItem ()
 Destructor.
 
void setOrientation (Qt::Orientation)
 
Qt::Orientation orientation () const
 
virtual void draw (QPainter *p, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &) const
 Draw the complete series. More...
 
virtual void drawSeries (QPainter *painter, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, int from, int to) const =0
 
virtual QRectF boundingRect () const
 
virtual void updateScaleDiv (const QwtScaleDiv &, const QwtScaleDiv &)
 Update the item to changes of the axes scale division. More...
 
- Public Member Functions inherited from QwtPlotItem
 QwtPlotItem (const QwtText &title=QwtText())
 
+virtual ~QwtPlotItem ()
 Destroy the QwtPlotItem.
 
void attach (QwtPlot *plot)
 Attach the item to a plot. More...
 
void detach ()
 This method detaches a QwtPlotItem from any QwtPlot it has been associated with. More...
 
+QwtPlotplot () const
 Return attached plot.
 
void setTitle (const QString &title)
 
void setTitle (const QwtText &title)
 
const QwtTexttitle () const
 
virtual int rtti () const
 
void setItemAttribute (ItemAttribute, bool on=true)
 
bool testItemAttribute (ItemAttribute) const
 
void setItemInterest (ItemInterest, bool on=true)
 
bool testItemInterest (ItemInterest) const
 
void setRenderHint (RenderHint, bool on=true)
 
bool testRenderHint (RenderHint) const
 
void setRenderThreadCount (uint numThreads)
 
uint renderThreadCount () const
 
void setLegendIconSize (const QSize &)
 
QSize legendIconSize () const
 
double z () const
 
void setZ (double z)
 Set the z value. More...
 
+void show ()
 Show the item.
 
+void hide ()
 Hide the item.
 
virtual void setVisible (bool)
 
bool isVisible () const
 
void setAxes (int xAxis, int yAxis)
 
void setXAxis (int axis)
 
+int xAxis () const
 Return xAxis.
 
void setYAxis (int axis)
 
+int yAxis () const
 Return yAxis.
 
virtual void itemChanged ()
 
virtual void legendChanged ()
 
virtual void getCanvasMarginHint (const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasSize, double &left, double &top, double &right, double &bottom) const
 Calculate a hint for the canvas margin. More...
 
virtual void updateLegend (const QwtPlotItem *, const QList< QwtLegendData > &)
 Update the item to changes of the legend info. More...
 
QRectF scaleRect (const QwtScaleMap &, const QwtScaleMap &) const
 Calculate the bounding scale rectangle of 2 maps. More...
 
QRectF paintRect (const QwtScaleMap &, const QwtScaleMap &) const
 Calculate the bounding paint rectangle of 2 maps. More...
 
virtual QList< QwtLegendDatalegendData () const
 Return all information, that is needed to represent the item on the legend. More...
 
virtual QwtGraphic legendIcon (int index, const QSizeF &) const
 
+ + + + + + + + + + + + + + + + + + +

+Protected Member Functions

+virtual void dataChanged ()
 dataChanged() indicates, that the series has been changed.
 
- Protected Member Functions inherited from QwtPlotItem
QwtGraphic defaultIcon (const QBrush &, const QSizeF &) const
 Return a default icon from a brush. More...
 
- Protected Member Functions inherited from QwtAbstractSeriesStore
+virtual ~QwtAbstractSeriesStore ()
 Destructor.
 
virtual void setRectOfInterest (const QRectF &)=0
 
virtual QRectF dataRect () const =0
 
virtual size_t dataSize () const =0
 
+ + + + + + + + + + + + + + + + + + + + + + + +

+Additional Inherited Members

- Public Types inherited from QwtPlotItem
enum  RttiValues {
+  Rtti_PlotItem = 0, +Rtti_PlotGrid, +Rtti_PlotScale, +Rtti_PlotLegend, +
+  Rtti_PlotMarker, +Rtti_PlotCurve, +Rtti_PlotSpectroCurve, +Rtti_PlotIntervalCurve, +
+  Rtti_PlotHistogram, +Rtti_PlotSpectrogram, +Rtti_PlotSVG, +Rtti_PlotTradingCurve, +
+  Rtti_PlotBarChart, +Rtti_PlotMultiBarChart, +Rtti_PlotShape, +Rtti_PlotTextLabel, +
+  Rtti_PlotZone, +Rtti_PlotUserItem = 1000 +
+ }
 Runtime type information. More...
 
enum  ItemAttribute { Legend = 0x01, +AutoScale = 0x02, +Margins = 0x04 + }
 Plot Item Attributes. More...
 
enum  ItemInterest { ScaleInterest = 0x01, +LegendInterest = 0x02 + }
 Plot Item Interests. More...
 
enum  RenderHint { RenderAntialiased = 0x1 + }
 Render hints. More...
 
+typedef QFlags< ItemAttributeItemAttributes
 Plot Item Attributes.
 
+typedef QFlags< ItemInterestItemInterests
 Plot Item Interests.
 
+typedef QFlags< RenderHintRenderHints
 Render hints.
 
+

Detailed Description

+

Base class for plot items representing a series of samples.

+

Constructor & Destructor Documentation

+ +
+
+ + + + + +
+ + + + + + + + +
QwtPlotSeriesItem::QwtPlotSeriesItem (const QString & title = QString::null)
+
+explicit
+
+

Constructor

+
Parameters
+ + +
titleTitle of the curve
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
QwtPlotSeriesItem::QwtPlotSeriesItem (const QwtTexttitle)
+
+explicit
+
+

Constructor

+
Parameters
+ + +
titleTitle of the curve
+
+
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + +
QRectF QwtPlotSeriesItem::boundingRect () const
+
+virtual
+
+
Returns
An invalid bounding rect: QRectF(1.0, 1.0, -2.0, -2.0)
+
Note
A width or height < 0.0 is ignored by the autoscaler
+ +

Reimplemented from QwtPlotItem.

+ +

Reimplemented in QwtPlotTradingCurve, QwtPlotIntervalCurve, QwtPlotHistogram, QwtPlotBarChart, and QwtPlotMultiBarChart.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPlotSeriesItem::draw (QPainter * painter,
const QwtScaleMapxMap,
const QwtScaleMapyMap,
const QRectF & canvasRect 
) const
+
+virtual
+
+ +

Draw the complete series.

+
Parameters
+ + + + + +
painterPainter
xMapMaps x-values into pixel coordinates.
yMapMaps y-values into pixel coordinates.
canvasRectContents rectangle of the canvas
+
+
+ +

Implements QwtPlotItem.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
virtual void QwtPlotSeriesItem::drawSeries (QPainter * painter,
const QwtScaleMapxMap,
const QwtScaleMapyMap,
const QRectF & canvasRect,
int from,
int to 
) const
+
+pure virtual
+
+

Draw a subset of the samples

+
Parameters
+ + + + + + + +
painterPainter
xMapMaps x-values into pixel coordinates.
yMapMaps y-values into pixel coordinates.
canvasRectContents rectangle of the canvas
fromIndex of the first point to be painted
toIndex of the last point to be painted. If to < 0 the curve will be painted to its last point.
+
+
+ +

Implemented in QwtPlotCurve, QwtPlotTradingCurve, QwtPlotIntervalCurve, QwtPlotHistogram, QwtPlotBarChart, QwtPlotMultiBarChart, and QwtPlotSpectroCurve.

+ +
+
+ +
+
+ + + + + + + +
Qt::Orientation QwtPlotSeriesItem::orientation () const
+
+
Returns
Orientation of the plot item
+
See Also
setOrientation()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotSeriesItem::setOrientation (Qt::Orientation orientation)
+
+

Set the orientation of the item.

+

The orientation() might be used in specific way by a plot item. F.e. a QwtPlotCurve uses it to identify how to display the curve int QwtPlotCurve::Steps or QwtPlotCurve::Sticks style.

+
See Also
orientation()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void QwtPlotSeriesItem::updateScaleDiv (const QwtScaleDivxScaleDiv,
const QwtScaleDivyScaleDiv 
)
+
+virtual
+
+ +

Update the item to changes of the axes scale division.

+

Update the item, when the axes of plot have changed. The default implementation does nothing, but items that depend on the scale division (like QwtPlotGrid()) have to reimplement updateScaleDiv()

+

updateScaleDiv() is only called when the ScaleInterest interest is enabled. The default implementation does nothing.

+
Parameters
+ + + +
xScaleDivScale division of the x-axis
yScaleDivScale division of the y-axis
+
+
+
See Also
QwtPlot::updateAxes(), ScaleInterest
+ +

Reimplemented from QwtPlotItem.

+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_series_item__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_plot_series_item__inherit__graph.map new file mode 100644 index 0000000000..363201b074 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_series_item__inherit__graph.map @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_series_item__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_plot_series_item__inherit__graph.md5 new file mode 100644 index 0000000000..7680c3d05a --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_series_item__inherit__graph.md5 @@ -0,0 +1 @@ +c129da01bca20f6a1eb63a03f5b53707 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_series_item__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_plot_series_item__inherit__graph.png new file mode 100644 index 0000000000..0ac212c6dc Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_plot_series_item__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_shape_item-members.html b/ThirdParty/Qwt/doc/html/class_qwt_plot_shape_item-members.html new file mode 100644 index 0000000000..7e06cc11b1 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_shape_item-members.html @@ -0,0 +1,197 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtPlotShapeItem Member List
+
+
+ +

This is the complete list of members for QwtPlotShapeItem, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
attach(QwtPlot *plot)QwtPlotItem
AutoScale enum valueQwtPlotItem
boundingRect() const QwtPlotShapeItemvirtual
brush() const QwtPlotShapeItem
ClipPolygons enum valueQwtPlotShapeItem
defaultIcon(const QBrush &, const QSizeF &) const QwtPlotItemprotected
detach()QwtPlotItem
draw(QPainter *p, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &rect) const QwtPlotShapeItemvirtual
getCanvasMarginHint(const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasSize, double &left, double &top, double &right, double &bottom) const QwtPlotItemvirtual
hide()QwtPlotItem
isVisible() const QwtPlotItem
ItemAttribute enum nameQwtPlotItem
ItemAttributes typedefQwtPlotItem
itemChanged()QwtPlotItemvirtual
ItemInterest enum nameQwtPlotItem
ItemInterests typedefQwtPlotItem
Legend enum valueQwtPlotItem
legendChanged()QwtPlotItemvirtual
LegendColor enum valueQwtPlotShapeItem
legendData() const QwtPlotItemvirtual
legendIcon(int index, const QSizeF &) const QwtPlotShapeItemvirtual
legendIconSize() const QwtPlotItem
LegendInterest enum valueQwtPlotItem
LegendMode enum nameQwtPlotShapeItem
legendMode() const QwtPlotShapeItem
LegendShape enum valueQwtPlotShapeItem
Margins enum valueQwtPlotItem
PaintAttribute enum nameQwtPlotShapeItem
PaintAttributes typedefQwtPlotShapeItem
paintRect(const QwtScaleMap &, const QwtScaleMap &) const QwtPlotItem
pen() const QwtPlotShapeItem
plot() const QwtPlotItem
QwtPlotItem(const QwtText &title=QwtText())QwtPlotItemexplicit
QwtPlotShapeItem(const QString &title=QString::null)QwtPlotShapeItemexplicit
QwtPlotShapeItem(const QwtText &title)QwtPlotShapeItemexplicit
RenderAntialiased enum valueQwtPlotItem
RenderHint enum nameQwtPlotItem
RenderHints typedefQwtPlotItem
renderThreadCount() const QwtPlotItem
renderTolerance() const QwtPlotShapeItem
rtti() const QwtPlotShapeItemvirtual
Rtti_PlotBarChart enum valueQwtPlotItem
Rtti_PlotCurve enum valueQwtPlotItem
Rtti_PlotGrid enum valueQwtPlotItem
Rtti_PlotHistogram enum valueQwtPlotItem
Rtti_PlotIntervalCurve enum valueQwtPlotItem
Rtti_PlotItem enum valueQwtPlotItem
Rtti_PlotLegend enum valueQwtPlotItem
Rtti_PlotMarker enum valueQwtPlotItem
Rtti_PlotMultiBarChart enum valueQwtPlotItem
Rtti_PlotScale enum valueQwtPlotItem
Rtti_PlotShape enum valueQwtPlotItem
Rtti_PlotSpectroCurve enum valueQwtPlotItem
Rtti_PlotSpectrogram enum valueQwtPlotItem
Rtti_PlotSVG enum valueQwtPlotItem
Rtti_PlotTextLabel enum valueQwtPlotItem
Rtti_PlotTradingCurve enum valueQwtPlotItem
Rtti_PlotUserItem enum valueQwtPlotItem
Rtti_PlotZone enum valueQwtPlotItem
RttiValues enum nameQwtPlotItem
ScaleInterest enum valueQwtPlotItem
scaleRect(const QwtScaleMap &, const QwtScaleMap &) const QwtPlotItem
setAxes(int xAxis, int yAxis)QwtPlotItem
setBrush(const QBrush &)QwtPlotShapeItem
setItemAttribute(ItemAttribute, bool on=true)QwtPlotItem
setItemInterest(ItemInterest, bool on=true)QwtPlotItem
setLegendIconSize(const QSize &)QwtPlotItem
setLegendMode(LegendMode)QwtPlotShapeItem
setPaintAttribute(PaintAttribute, bool on=true)QwtPlotShapeItem
setPen(const QColor &, qreal width=0.0, Qt::PenStyle=Qt::SolidLine)QwtPlotShapeItem
setPen(const QPen &)QwtPlotShapeItem
setPolygon(const QPolygonF &)QwtPlotShapeItem
setRect(const QRectF &)QwtPlotShapeItem
setRenderHint(RenderHint, bool on=true)QwtPlotItem
setRenderThreadCount(uint numThreads)QwtPlotItem
setRenderTolerance(double)QwtPlotShapeItem
setShape(const QPainterPath &)QwtPlotShapeItem
setTitle(const QString &title)QwtPlotItem
setTitle(const QwtText &title)QwtPlotItem
setVisible(bool)QwtPlotItemvirtual
setXAxis(int axis)QwtPlotItem
setYAxis(int axis)QwtPlotItem
setZ(double z)QwtPlotItem
shape() const QwtPlotShapeItem
show()QwtPlotItem
testItemAttribute(ItemAttribute) const QwtPlotItem
testItemInterest(ItemInterest) const QwtPlotItem
testPaintAttribute(PaintAttribute) const QwtPlotShapeItem
testRenderHint(RenderHint) const QwtPlotItem
title() const QwtPlotItem
updateLegend(const QwtPlotItem *, const QList< QwtLegendData > &)QwtPlotItemvirtual
updateScaleDiv(const QwtScaleDiv &, const QwtScaleDiv &)QwtPlotItemvirtual
xAxis() const QwtPlotItem
yAxis() const QwtPlotItem
z() const QwtPlotItem
~QwtPlotItem()QwtPlotItemvirtual
~QwtPlotShapeItem()QwtPlotShapeItemvirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_shape_item.html b/ThirdParty/Qwt/doc/html/class_qwt_plot_shape_item.html new file mode 100644 index 0000000000..e22d241f8b --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_shape_item.html @@ -0,0 +1,956 @@ + + + + + + +Qwt User's Guide: QwtPlotShapeItem Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtPlotShapeItem Class Reference
+
+
+ +

A plot item, which displays any graphical shape, that can be defined by a QPainterPath. + More...

+ +

#include <qwt_plot_shapeitem.h>

+
+Inheritance diagram for QwtPlotShapeItem:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Types

enum  PaintAttribute { ClipPolygons = 0x01 + }
 
enum  LegendMode { LegendShape, +LegendColor + }
 Mode how to display the item on the legend. More...
 
+typedef QFlags< PaintAttributePaintAttributes
 Paint attributes.
 
- Public Types inherited from QwtPlotItem
enum  RttiValues {
+  Rtti_PlotItem = 0, +Rtti_PlotGrid, +Rtti_PlotScale, +Rtti_PlotLegend, +
+  Rtti_PlotMarker, +Rtti_PlotCurve, +Rtti_PlotSpectroCurve, +Rtti_PlotIntervalCurve, +
+  Rtti_PlotHistogram, +Rtti_PlotSpectrogram, +Rtti_PlotSVG, +Rtti_PlotTradingCurve, +
+  Rtti_PlotBarChart, +Rtti_PlotMultiBarChart, +Rtti_PlotShape, +Rtti_PlotTextLabel, +
+  Rtti_PlotZone, +Rtti_PlotUserItem = 1000 +
+ }
 Runtime type information. More...
 
enum  ItemAttribute { Legend = 0x01, +AutoScale = 0x02, +Margins = 0x04 + }
 Plot Item Attributes. More...
 
enum  ItemInterest { ScaleInterest = 0x01, +LegendInterest = 0x02 + }
 Plot Item Interests. More...
 
enum  RenderHint { RenderAntialiased = 0x1 + }
 Render hints. More...
 
+typedef QFlags< ItemAttributeItemAttributes
 Plot Item Attributes.
 
+typedef QFlags< ItemInterestItemInterests
 Plot Item Interests.
 
+typedef QFlags< RenderHintRenderHints
 Render hints.
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 QwtPlotShapeItem (const QString &title=QString::null)
 Constructor. More...
 
 QwtPlotShapeItem (const QwtText &title)
 Constructor. More...
 
+virtual ~QwtPlotShapeItem ()
 Destructor.
 
void setPaintAttribute (PaintAttribute, bool on=true)
 
bool testPaintAttribute (PaintAttribute) const
 
void setLegendMode (LegendMode)
 
LegendMode legendMode () const
 
void setRect (const QRectF &)
 Set a path built from a rectangle. More...
 
void setPolygon (const QPolygonF &)
 Set a path built from a polygon. More...
 
void setShape (const QPainterPath &)
 Set the shape to be displayed. More...
 
QPainterPath shape () const
 
void setPen (const QColor &, qreal width=0.0, Qt::PenStyle=Qt::SolidLine)
 
void setPen (const QPen &)
 Assign a pen. More...
 
QPen pen () const
 
void setBrush (const QBrush &)
 
QBrush brush () const
 
void setRenderTolerance (double)
 Set the tolerance for the weeding optimization. More...
 
double renderTolerance () const
 
+virtual QRectF boundingRect () const
 Bounding rectangle of the shape.
 
virtual void draw (QPainter *p, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &rect) const
 
virtual QwtGraphic legendIcon (int index, const QSizeF &) const
 
virtual int rtti () const
 
- Public Member Functions inherited from QwtPlotItem
 QwtPlotItem (const QwtText &title=QwtText())
 
+virtual ~QwtPlotItem ()
 Destroy the QwtPlotItem.
 
void attach (QwtPlot *plot)
 Attach the item to a plot. More...
 
void detach ()
 This method detaches a QwtPlotItem from any QwtPlot it has been associated with. More...
 
+QwtPlotplot () const
 Return attached plot.
 
void setTitle (const QString &title)
 
void setTitle (const QwtText &title)
 
const QwtTexttitle () const
 
void setItemAttribute (ItemAttribute, bool on=true)
 
bool testItemAttribute (ItemAttribute) const
 
void setItemInterest (ItemInterest, bool on=true)
 
bool testItemInterest (ItemInterest) const
 
void setRenderHint (RenderHint, bool on=true)
 
bool testRenderHint (RenderHint) const
 
void setRenderThreadCount (uint numThreads)
 
uint renderThreadCount () const
 
void setLegendIconSize (const QSize &)
 
QSize legendIconSize () const
 
double z () const
 
void setZ (double z)
 Set the z value. More...
 
+void show ()
 Show the item.
 
+void hide ()
 Hide the item.
 
virtual void setVisible (bool)
 
bool isVisible () const
 
void setAxes (int xAxis, int yAxis)
 
void setXAxis (int axis)
 
+int xAxis () const
 Return xAxis.
 
void setYAxis (int axis)
 
+int yAxis () const
 Return yAxis.
 
virtual void itemChanged ()
 
virtual void legendChanged ()
 
virtual void getCanvasMarginHint (const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasSize, double &left, double &top, double &right, double &bottom) const
 Calculate a hint for the canvas margin. More...
 
virtual void updateScaleDiv (const QwtScaleDiv &, const QwtScaleDiv &)
 Update the item to changes of the axes scale division. More...
 
virtual void updateLegend (const QwtPlotItem *, const QList< QwtLegendData > &)
 Update the item to changes of the legend info. More...
 
QRectF scaleRect (const QwtScaleMap &, const QwtScaleMap &) const
 Calculate the bounding scale rectangle of 2 maps. More...
 
QRectF paintRect (const QwtScaleMap &, const QwtScaleMap &) const
 Calculate the bounding paint rectangle of 2 maps. More...
 
virtual QList< QwtLegendDatalegendData () const
 Return all information, that is needed to represent the item on the legend. More...
 
+ + + + + +

+Additional Inherited Members

- Protected Member Functions inherited from QwtPlotItem
QwtGraphic defaultIcon (const QBrush &, const QSizeF &) const
 Return a default icon from a brush. More...
 
+

Detailed Description

+

A plot item, which displays any graphical shape, that can be defined by a QPainterPath.

+

A QPainterPath is a shape composed from intersecting and uniting regions, rectangles, ellipses or irregular areas defined by lines, and curves. QwtPlotShapeItem displays a shape with a pen and brush.

+

QwtPlotShapeItem offers a couple of optimizations like clipping or weeding. These algorithms need to convert the painter path into polygons that might be less performant for paths built from curves and ellipses.

+
See Also
QwtPlotZone
+

Member Enumeration Documentation

+ +
+
+ +

Mode how to display the item on the legend.

+ + + +
Enumerator
LegendShape  +

Display a scaled down version of the shape.

+
LegendColor  +

Display a filled rectangle.

+
+ +
+
+ +
+
+

Attributes to modify the drawing algorithm. The default disables all attributes

+
See Also
setPaintAttribute(), testPaintAttribute()
+ + +
Enumerator
ClipPolygons  +

Clip polygons before painting them. In situations, where points are far outside the visible area (f.e when zooming deep) this might be a substantial improvement for the painting performance

+

But polygon clipping will convert the painter path into polygons what might introduce a negative impact on the performance of paths composed from curves or ellipses.

+
+ +
+
+

Constructor & Destructor Documentation

+ +
+
+ + + + + +
+ + + + + + + + +
QwtPlotShapeItem::QwtPlotShapeItem (const QString & title = QString::null)
+
+explicit
+
+ +

Constructor.

+

Sets the following item attributes:

+ +
Parameters
+ + +
titleTitle
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
QwtPlotShapeItem::QwtPlotShapeItem (const QwtTexttitle)
+
+explicit
+
+ +

Constructor.

+

Sets the following item attributes:

+ +
Parameters
+ + +
titleTitle
+
+
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + + + +
QBrush QwtPlotShapeItem::brush () const
+
+
Returns
Brush used to fill the shape
+
See Also
setBrush(), pen()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPlotShapeItem::draw (QPainter * painter,
const QwtScaleMapxMap,
const QwtScaleMapyMap,
const QRectF & canvasRect 
) const
+
+virtual
+
+

Draw the shape item

+
Parameters
+ + + + + +
painterPainter
xMapX-Scale Map
yMapY-Scale Map
canvasRectContents rect of the plot canvas
+
+
+ +

Implements QwtPlotItem.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
QwtGraphic QwtPlotShapeItem::legendIcon (int index,
const QSizeF & size 
) const
+
+virtual
+
+
Returns
A rectangle filled with the color of the brush ( or the pen )
+
Parameters
+ + + +
indexIndex of the legend entry ( usually there is only one )
sizeIcon size
+
+
+
See Also
setLegendIconSize(), legendData()
+ +

Reimplemented from QwtPlotItem.

+ +
+
+ +
+
+ + + + + + + +
QwtPlotShapeItem::LegendMode QwtPlotShapeItem::legendMode () const
+
+
Returns
Mode how to represent the item on the legend
+
See Also
legendMode()
+ +
+
+ +
+
+ + + + + + + +
QPen QwtPlotShapeItem::pen () const
+
+
Returns
Pen used to draw the outline of the shape
+
See Also
setPen(), brush()
+ +
+
+ +
+
+ + + + + + + +
double QwtPlotShapeItem::renderTolerance () const
+
+
Returns
Tolerance for the weeding optimization
+
See Also
setRenderTolerance()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
int QwtPlotShapeItem::rtti () const
+
+virtual
+
+
Returns
QwtPlotItem::Rtti_PlotShape
+ +

Reimplemented from QwtPlotItem.

+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotShapeItem::setBrush (const QBrush & brush)
+
+

Assign a brush.

+

The brush is used to fill the path

+
Parameters
+ + +
brushBrush
+
+
+
See Also
brush(), pen()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotShapeItem::setLegendMode (LegendMode mode)
+
+

Set the mode how to represent the item on the legend

+
Parameters
+ + +
modeMode
+
+
+
See Also
legendMode()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtPlotShapeItem::setPaintAttribute (PaintAttribute attribute,
bool on = true 
)
+
+

Specify an attribute how to draw the shape

+
Parameters
+ + + +
attributePaint attribute
onOn/Off
+
+
+
See Also
testPaintAttribute()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPlotShapeItem::setPen (const QColor & color,
qreal width = 0.0,
Qt::PenStyle style = Qt::SolidLine 
)
+
+

Build and assign a pen

+

In Qt5 the default pen width is 1.0 ( 0.0 in Qt4 ) what makes it non cosmetic ( see QPen::isCosmetic() ). This method has been introduced to hide this incompatibility.

+
Parameters
+ + + + +
colorPen color
widthPen width
stylePen style
+
+
+
See Also
pen(), brush()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotShapeItem::setPen (const QPen & pen)
+
+ +

Assign a pen.

+

The pen is used to draw the outline of the shape

+
Parameters
+ + +
penPen
+
+
+
See Also
pen(), brush()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotShapeItem::setPolygon (const QPolygonF & polygon)
+
+ +

Set a path built from a polygon.

+
Parameters
+ + +
polygonPolygon
+
+
+
See Also
setShape(), setRect(), shape()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotShapeItem::setRect (const QRectF & rect)
+
+ +

Set a path built from a rectangle.

+
Parameters
+ + +
rectRectangle
+
+
+
See Also
setShape(), setPolygon(), shape()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotShapeItem::setRenderTolerance (double tolerance)
+
+ +

Set the tolerance for the weeding optimization.

+

After translating the shape into target device coordinate ( usually widget geometries ) the painter path can be simplified by a point weeding algorithm ( Douglas-Peucker ).

+

For shapes built from curves and ellipses weeding might have the opposite effect because they have to be expanded to polygons.

+
Parameters
+ + +
toleranceAccepted error when reducing the number of points A value <= 0.0 disables weeding.
+
+
+
See Also
renderTolerance(), QwtWeedingCurveFitter
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotShapeItem::setShape (const QPainterPath & shape)
+
+ +

Set the shape to be displayed.

+
Parameters
+ + +
shapeShape
+
+
+
See Also
setShape(), shape()
+ +
+
+ +
+
+ + + + + + + +
QPainterPath QwtPlotShapeItem::shape () const
+
+
Returns
Shape to be displayed
+
See Also
setShape()
+ +
+
+ +
+
+ + + + + + + + +
bool QwtPlotShapeItem::testPaintAttribute (PaintAttribute attribute) const
+
+
Returns
True, when attribute is enabled
+
See Also
setPaintAttribute()
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_shape_item__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_plot_shape_item__inherit__graph.map new file mode 100644 index 0000000000..c475b7712b --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_shape_item__inherit__graph.map @@ -0,0 +1,3 @@ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_shape_item__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_plot_shape_item__inherit__graph.md5 new file mode 100644 index 0000000000..31fa9720b9 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_shape_item__inherit__graph.md5 @@ -0,0 +1 @@ +3dd2b9255750d135e8d9110e4d06959c \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_shape_item__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_plot_shape_item__inherit__graph.png new file mode 100644 index 0000000000..4b26928871 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_plot_shape_item__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_spectro_curve-members.html b/ThirdParty/Qwt/doc/html/class_qwt_plot_spectro_curve-members.html new file mode 100644 index 0000000000..10b6f55400 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_spectro_curve-members.html @@ -0,0 +1,211 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtPlotSpectroCurve Member List
+
+
+ +

This is the complete list of members for QwtPlotSpectroCurve, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
attach(QwtPlot *plot)QwtPlotItem
AutoScale enum valueQwtPlotItem
boundingRect() const QwtPlotSeriesItemvirtual
ClipPoints enum valueQwtPlotSpectroCurve
colorMap() const QwtPlotSpectroCurve
colorRange() const QwtPlotSpectroCurve
data()QwtSeriesStore< QwtPoint3D >private
data() constQwtSeriesStore< QwtPoint3D >private
dataChanged()QwtPlotSeriesItemprotectedvirtual
QwtPlotSeriesItem::dataRect() const =0QwtAbstractSeriesStoreprotectedpure virtual
QwtSeriesStore< QwtPoint3D >::dataRect() constQwtSeriesStore< QwtPoint3D >privatevirtual
QwtPlotSeriesItem::dataSize() const =0QwtAbstractSeriesStoreprotectedpure virtual
QwtSeriesStore< QwtPoint3D >::dataSize() constQwtSeriesStore< QwtPoint3D >privatevirtual
defaultIcon(const QBrush &, const QSizeF &) const QwtPlotItemprotected
detach()QwtPlotItem
draw(QPainter *p, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &) const QwtPlotSeriesItemvirtual
drawDots(QPainter *, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, int from, int to) const QwtPlotSpectroCurveprotectedvirtual
drawSeries(QPainter *, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, int from, int to) const QwtPlotSpectroCurvevirtual
getCanvasMarginHint(const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasSize, double &left, double &top, double &right, double &bottom) const QwtPlotItemvirtual
hide()QwtPlotItem
isVisible() const QwtPlotItem
ItemAttribute enum nameQwtPlotItem
ItemAttributes typedefQwtPlotItem
itemChanged()QwtPlotItemvirtual
ItemInterest enum nameQwtPlotItem
ItemInterests typedefQwtPlotItem
Legend enum valueQwtPlotItem
legendChanged()QwtPlotItemvirtual
legendData() const QwtPlotItemvirtual
legendIcon(int index, const QSizeF &) const QwtPlotItemvirtual
legendIconSize() const QwtPlotItem
LegendInterest enum valueQwtPlotItem
Margins enum valueQwtPlotItem
orientation() const QwtPlotSeriesItem
PaintAttribute enum nameQwtPlotSpectroCurve
PaintAttributes typedefQwtPlotSpectroCurve
paintRect(const QwtScaleMap &, const QwtScaleMap &) const QwtPlotItem
penWidth() const QwtPlotSpectroCurve
plot() const QwtPlotItem
QwtPlotItem(const QwtText &title=QwtText())QwtPlotItemexplicit
QwtPlotSeriesItem(const QString &title=QString::null)QwtPlotSeriesItemexplicit
QwtPlotSeriesItem(const QwtText &title)QwtPlotSeriesItemexplicit
QwtPlotSpectroCurve(const QString &title=QString::null)QwtPlotSpectroCurveexplicit
QwtPlotSpectroCurve(const QwtText &title)QwtPlotSpectroCurveexplicit
QwtSeriesStore()QwtSeriesStore< QwtPoint3D >explicitprivate
RenderAntialiased enum valueQwtPlotItem
RenderHint enum nameQwtPlotItem
RenderHints typedefQwtPlotItem
renderThreadCount() const QwtPlotItem
rtti() const QwtPlotSpectroCurvevirtual
Rtti_PlotBarChart enum valueQwtPlotItem
Rtti_PlotCurve enum valueQwtPlotItem
Rtti_PlotGrid enum valueQwtPlotItem
Rtti_PlotHistogram enum valueQwtPlotItem
Rtti_PlotIntervalCurve enum valueQwtPlotItem
Rtti_PlotItem enum valueQwtPlotItem
Rtti_PlotLegend enum valueQwtPlotItem
Rtti_PlotMarker enum valueQwtPlotItem
Rtti_PlotMultiBarChart enum valueQwtPlotItem
Rtti_PlotScale enum valueQwtPlotItem
Rtti_PlotShape enum valueQwtPlotItem
Rtti_PlotSpectroCurve enum valueQwtPlotItem
Rtti_PlotSpectrogram enum valueQwtPlotItem
Rtti_PlotSVG enum valueQwtPlotItem
Rtti_PlotTextLabel enum valueQwtPlotItem
Rtti_PlotTradingCurve enum valueQwtPlotItem
Rtti_PlotUserItem enum valueQwtPlotItem
Rtti_PlotZone enum valueQwtPlotItem
RttiValues enum nameQwtPlotItem
sample(int index) constQwtSeriesStore< QwtPoint3D >private
ScaleInterest enum valueQwtPlotItem
scaleRect(const QwtScaleMap &, const QwtScaleMap &) const QwtPlotItem
setAxes(int xAxis, int yAxis)QwtPlotItem
setColorMap(QwtColorMap *)QwtPlotSpectroCurve
setColorRange(const QwtInterval &)QwtPlotSpectroCurve
setData(QwtSeriesData< QwtPoint3D > *series)QwtSeriesStore< QwtPoint3D >private
setItemAttribute(ItemAttribute, bool on=true)QwtPlotItem
setItemInterest(ItemInterest, bool on=true)QwtPlotItem
setLegendIconSize(const QSize &)QwtPlotItem
setOrientation(Qt::Orientation)QwtPlotSeriesItem
setPaintAttribute(PaintAttribute, bool on=true)QwtPlotSpectroCurve
setPenWidth(double width)QwtPlotSpectroCurve
QwtPlotSeriesItem::setRectOfInterest(const QRectF &)=0QwtAbstractSeriesStoreprotectedpure virtual
QwtSeriesStore< QwtPoint3D >::setRectOfInterest(const QRectF &rect)QwtSeriesStore< QwtPoint3D >privatevirtual
setRenderHint(RenderHint, bool on=true)QwtPlotItem
setRenderThreadCount(uint numThreads)QwtPlotItem
setSamples(const QVector< QwtPoint3D > &)QwtPlotSpectroCurve
setSamples(QwtSeriesData< QwtPoint3D > *)QwtPlotSpectroCurve
setTitle(const QString &title)QwtPlotItem
setTitle(const QwtText &title)QwtPlotItem
setVisible(bool)QwtPlotItemvirtual
setXAxis(int axis)QwtPlotItem
setYAxis(int axis)QwtPlotItem
setZ(double z)QwtPlotItem
show()QwtPlotItem
swapData(QwtSeriesData< QwtPoint3D > *series)QwtSeriesStore< QwtPoint3D >private
testItemAttribute(ItemAttribute) const QwtPlotItem
testItemInterest(ItemInterest) const QwtPlotItem
testPaintAttribute(PaintAttribute) const QwtPlotSpectroCurve
testRenderHint(RenderHint) const QwtPlotItem
title() const QwtPlotItem
updateLegend(const QwtPlotItem *, const QList< QwtLegendData > &)QwtPlotItemvirtual
updateScaleDiv(const QwtScaleDiv &, const QwtScaleDiv &)QwtPlotSeriesItemvirtual
xAxis() const QwtPlotItem
yAxis() const QwtPlotItem
z() const QwtPlotItem
~QwtAbstractSeriesStore()QwtAbstractSeriesStoreinlineprotectedvirtual
~QwtPlotItem()QwtPlotItemvirtual
~QwtPlotSeriesItem()QwtPlotSeriesItemvirtual
~QwtPlotSpectroCurve()QwtPlotSpectroCurvevirtual
~QwtSeriesStore()QwtSeriesStore< QwtPoint3D >private
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_spectro_curve.html b/ThirdParty/Qwt/doc/html/class_qwt_plot_spectro_curve.html new file mode 100644 index 0000000000..504991bfbf --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_spectro_curve.html @@ -0,0 +1,804 @@ + + + + + + +Qwt User's Guide: QwtPlotSpectroCurve Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtPlotSpectroCurve Class Reference
+
+
+ +

Curve that displays 3D points as dots, where the z coordinate is mapped to a color. + More...

+ +

#include <qwt_plot_spectrocurve.h>

+
+Inheritance diagram for QwtPlotSpectroCurve:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + +

+Public Types

enum  PaintAttribute { ClipPoints = 1 + }
 Paint attributes. More...
 
+typedef QFlags< PaintAttributePaintAttributes
 Paint attributes.
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 QwtPlotSpectroCurve (const QString &title=QString::null)
 
 QwtPlotSpectroCurve (const QwtText &title)
 
+virtual ~QwtPlotSpectroCurve ()
 Destructor.
 
virtual int rtti () const
 
void setPaintAttribute (PaintAttribute, bool on=true)
 
bool testPaintAttribute (PaintAttribute) const
 
void setSamples (const QVector< QwtPoint3D > &)
 
void setSamples (QwtSeriesData< QwtPoint3D > *)
 
void setColorMap (QwtColorMap *)
 
const QwtColorMapcolorMap () const
 
void setColorRange (const QwtInterval &)
 
QwtIntervalcolorRange () const
 
virtual void drawSeries (QPainter *, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, int from, int to) const
 
void setPenWidth (double width)
 
double penWidth () const
 
- Public Member Functions inherited from QwtPlotSeriesItem
 QwtPlotSeriesItem (const QString &title=QString::null)
 
 QwtPlotSeriesItem (const QwtText &title)
 
+virtual ~QwtPlotSeriesItem ()
 Destructor.
 
void setOrientation (Qt::Orientation)
 
Qt::Orientation orientation () const
 
virtual void draw (QPainter *p, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &) const
 Draw the complete series. More...
 
virtual QRectF boundingRect () const
 
virtual void updateScaleDiv (const QwtScaleDiv &, const QwtScaleDiv &)
 Update the item to changes of the axes scale division. More...
 
- Public Member Functions inherited from QwtPlotItem
 QwtPlotItem (const QwtText &title=QwtText())
 
+virtual ~QwtPlotItem ()
 Destroy the QwtPlotItem.
 
void attach (QwtPlot *plot)
 Attach the item to a plot. More...
 
void detach ()
 This method detaches a QwtPlotItem from any QwtPlot it has been associated with. More...
 
+QwtPlotplot () const
 Return attached plot.
 
void setTitle (const QString &title)
 
void setTitle (const QwtText &title)
 
const QwtTexttitle () const
 
void setItemAttribute (ItemAttribute, bool on=true)
 
bool testItemAttribute (ItemAttribute) const
 
void setItemInterest (ItemInterest, bool on=true)
 
bool testItemInterest (ItemInterest) const
 
void setRenderHint (RenderHint, bool on=true)
 
bool testRenderHint (RenderHint) const
 
void setRenderThreadCount (uint numThreads)
 
uint renderThreadCount () const
 
void setLegendIconSize (const QSize &)
 
QSize legendIconSize () const
 
double z () const
 
void setZ (double z)
 Set the z value. More...
 
+void show ()
 Show the item.
 
+void hide ()
 Hide the item.
 
virtual void setVisible (bool)
 
bool isVisible () const
 
void setAxes (int xAxis, int yAxis)
 
void setXAxis (int axis)
 
+int xAxis () const
 Return xAxis.
 
void setYAxis (int axis)
 
+int yAxis () const
 Return yAxis.
 
virtual void itemChanged ()
 
virtual void legendChanged ()
 
virtual void getCanvasMarginHint (const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasSize, double &left, double &top, double &right, double &bottom) const
 Calculate a hint for the canvas margin. More...
 
virtual void updateLegend (const QwtPlotItem *, const QList< QwtLegendData > &)
 Update the item to changes of the legend info. More...
 
QRectF scaleRect (const QwtScaleMap &, const QwtScaleMap &) const
 Calculate the bounding scale rectangle of 2 maps. More...
 
QRectF paintRect (const QwtScaleMap &, const QwtScaleMap &) const
 Calculate the bounding paint rectangle of 2 maps. More...
 
virtual QList< QwtLegendDatalegendData () const
 Return all information, that is needed to represent the item on the legend. More...
 
virtual QwtGraphic legendIcon (int index, const QSizeF &) const
 
+ + + + + + + + + + + + + + + +

+Protected Member Functions

virtual void drawDots (QPainter *, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, int from, int to) const
 
- Protected Member Functions inherited from QwtPlotSeriesItem
+virtual void dataChanged ()
 dataChanged() indicates, that the series has been changed.
 
- Protected Member Functions inherited from QwtPlotItem
QwtGraphic defaultIcon (const QBrush &, const QSizeF &) const
 Return a default icon from a brush. More...
 
- Protected Member Functions inherited from QwtAbstractSeriesStore
+virtual ~QwtAbstractSeriesStore ()
 Destructor.
 
+ + + + + + + + + + + + + + + + + + + + + + + + +

+Additional Inherited Members

- Private Member Functions inherited from QwtSeriesStore< QwtPoint3D >
QwtSeriesStore ()
 Constructor The store contains no series.
 
~QwtSeriesStore ()
 Destructor.
 
void setData (QwtSeriesData< QwtPoint3D > *series)
 
QwtSeriesData< QwtPoint3D > * data ()
 
const QwtSeriesData< QwtPoint3D > * data () const
 
QwtPoint3D sample (int index) const
 
virtual size_t dataSize () const
 
virtual QRectF dataRect () const
 
virtual void setRectOfInterest (const QRectF &rect)
 
QwtSeriesData< QwtPoint3D > * swapData (QwtSeriesData< QwtPoint3D > *series)
 
+

Detailed Description

+

Curve that displays 3D points as dots, where the z coordinate is mapped to a color.

+

Member Enumeration Documentation

+ +
+
+ +

Paint attributes.

+ + +
Enumerator
ClipPoints  +

Clip points outside the canvas rectangle.

+
+ +
+
+

Constructor & Destructor Documentation

+ +
+
+ + + + + +
+ + + + + + + + +
QwtPlotSpectroCurve::QwtPlotSpectroCurve (const QString & title = QString::null)
+
+explicit
+
+

Constructor

+
Parameters
+ + +
titleTitle of the curve
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
QwtPlotSpectroCurve::QwtPlotSpectroCurve (const QwtTexttitle)
+
+explicit
+
+

Constructor

+
Parameters
+ + +
titleTitle of the curve
+
+
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + + + +
const QwtColorMap * QwtPlotSpectroCurve::colorMap () const
+
+
Returns
Color Map used for mapping the intensity values to colors
+
See Also
setColorMap(), setColorRange(), QwtColorMap::color()
+ +
+
+ +
+
+ + + + + + + +
QwtInterval & QwtPlotSpectroCurve::colorRange () const
+
+
Returns
Value interval, that corresponds to the color map
+
See Also
setColorRange(), setColorMap(), QwtColorMap::color()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPlotSpectroCurve::drawDots (QPainter * painter,
const QwtScaleMapxMap,
const QwtScaleMapyMap,
const QRectF & canvasRect,
int from,
int to 
) const
+
+protectedvirtual
+
+

Draw a subset of the points

+
Parameters
+ + + + + + + +
painterPainter
xMapMaps x-values into pixel coordinates.
yMapMaps y-values into pixel coordinates.
canvasRectContents rectangle of the canvas
fromIndex of the first sample to be painted
toIndex of the last sample to be painted. If to < 0 the series will be painted to its last sample.
+
+
+
See Also
drawSeries()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPlotSpectroCurve::drawSeries (QPainter * painter,
const QwtScaleMapxMap,
const QwtScaleMapyMap,
const QRectF & canvasRect,
int from,
int to 
) const
+
+virtual
+
+

Draw a subset of the points

+
Parameters
+ + + + + + + +
painterPainter
xMapMaps x-values into pixel coordinates.
yMapMaps y-values into pixel coordinates.
canvasRectContents rectangle of the canvas
fromIndex of the first sample to be painted
toIndex of the last sample to be painted. If to < 0 the series will be painted to its last sample.
+
+
+
See Also
drawDots()
+ +

Implements QwtPlotSeriesItem.

+ +
+
+ +
+
+ + + + + + + +
double QwtPlotSpectroCurve::penWidth () const
+
+
Returns
Pen width used to draw a dot
+
See Also
setPenWidth()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
int QwtPlotSpectroCurve::rtti () const
+
+virtual
+
+
Returns
QwtPlotItem::Rtti_PlotSpectroCurve
+ +

Reimplemented from QwtPlotItem.

+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotSpectroCurve::setColorMap (QwtColorMapcolorMap)
+
+

Change the color map

+

Often it is useful to display the mapping between intensities and colors as an additional plot axis, showing a color bar.

+
Parameters
+ + +
colorMapColor Map
+
+
+
See Also
colorMap(), setColorRange(), QwtColorMap::color(), QwtScaleWidget::setColorBarEnabled(), QwtScaleWidget::setColorMap()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotSpectroCurve::setColorRange (const QwtIntervalinterval)
+
+

Set the value interval, that corresponds to the color map

+
Parameters
+ + +
intervalinterval.minValue() corresponds to 0.0, interval.maxValue() to 1.0 on the color map.
+
+
+
See Also
colorRange(), setColorMap(), QwtColorMap::color()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtPlotSpectroCurve::setPaintAttribute (PaintAttribute attribute,
bool on = true 
)
+
+

Specify an attribute how to draw the curve

+
Parameters
+ + + +
attributePaint attribute
onOn/Off /sa PaintAttribute, testPaintAttribute()
+
+
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotSpectroCurve::setPenWidth (double penWidth)
+
+

Assign a pen width

+
Parameters
+ + +
penWidthNew pen width
+
+
+
See Also
penWidth()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotSpectroCurve::setSamples (const QVector< QwtPoint3D > & samples)
+
+

Initialize data with an array of samples.

+
Parameters
+ + +
samplesVector of points
+
+
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotSpectroCurve::setSamples (QwtSeriesData< QwtPoint3D > * data)
+
+

Assign a series of samples

+

setSamples() is just a wrapper for setData() without any additional value - beside that it is easier to find for the developer.

+
Parameters
+ + +
dataData
+
+
+
Warning
The item takes ownership of the data object, deleting it when its not used anymore.
+ +
+
+ +
+
+ + + + + + + + +
bool QwtPlotSpectroCurve::testPaintAttribute (PaintAttribute attribute) const
+
+
Returns
True, when attribute is enabled
+
See Also
PaintAttribute, setPaintAttribute()
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_spectro_curve__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_plot_spectro_curve__inherit__graph.map new file mode 100644 index 0000000000..6fcb228742 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_spectro_curve__inherit__graph.map @@ -0,0 +1,6 @@ + + + + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_spectro_curve__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_plot_spectro_curve__inherit__graph.md5 new file mode 100644 index 0000000000..1f107acc71 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_spectro_curve__inherit__graph.md5 @@ -0,0 +1 @@ +23bc3f3406e7e9326d831de009343a29 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_spectro_curve__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_plot_spectro_curve__inherit__graph.png new file mode 100644 index 0000000000..5c037c68b5 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_plot_spectro_curve__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_spectrogram-members.html b/ThirdParty/Qwt/doc/html/class_qwt_plot_spectrogram-members.html new file mode 100644 index 0000000000..2283c5d942 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_spectrogram-members.html @@ -0,0 +1,218 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtPlotSpectrogram Member List
+
+
+ +

This is the complete list of members for QwtPlotSpectrogram, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
alpha() const QwtPlotRasterItem
attach(QwtPlot *plot)QwtPlotItem
AutoScale enum valueQwtPlotItem
boundingRect() const QwtPlotRasterItemvirtual
CachePolicy enum nameQwtPlotRasterItem
cachePolicy() const QwtPlotRasterItem
colorMap() const QwtPlotSpectrogram
contourLevels() const QwtPlotSpectrogram
ContourMode enum valueQwtPlotSpectrogram
contourPen(double level) const QwtPlotSpectrogramvirtual
contourRasterSize(const QRectF &, const QRect &) const QwtPlotSpectrogramprotectedvirtual
data() const QwtPlotSpectrogram
data()QwtPlotSpectrogram
defaultContourPen() const QwtPlotSpectrogram
defaultIcon(const QBrush &, const QSizeF &) const QwtPlotItemprotected
detach()QwtPlotItem
DisplayMode enum nameQwtPlotSpectrogram
DisplayModes typedefQwtPlotSpectrogram
draw(QPainter *p, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &rect) const QwtPlotSpectrogramvirtual
drawContourLines(QPainter *p, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QwtRasterData::ContourLines &lines) const QwtPlotSpectrogramprotectedvirtual
getCanvasMarginHint(const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasSize, double &left, double &top, double &right, double &bottom) const QwtPlotItemvirtual
hide()QwtPlotItem
imageMap(Qt::Orientation, const QwtScaleMap &map, const QRectF &area, const QSize &imageSize, double pixelSize) const QwtPlotRasterItemprotectedvirtual
ImageMode enum valueQwtPlotSpectrogram
interval(Qt::Axis) const QwtPlotSpectrogramvirtual
invalidateCache()QwtPlotRasterItem
isVisible() const QwtPlotItem
ItemAttribute enum nameQwtPlotItem
ItemAttributes typedefQwtPlotItem
itemChanged()QwtPlotItemvirtual
ItemInterest enum nameQwtPlotItem
ItemInterests typedefQwtPlotItem
Legend enum valueQwtPlotItem
legendChanged()QwtPlotItemvirtual
legendData() const QwtPlotItemvirtual
legendIcon(int index, const QSizeF &) const QwtPlotItemvirtual
legendIconSize() const QwtPlotItem
LegendInterest enum valueQwtPlotItem
Margins enum valueQwtPlotItem
NoCache enum valueQwtPlotRasterItem
PaintAttribute enum nameQwtPlotRasterItem
PaintAttributes typedefQwtPlotRasterItem
PaintCache enum valueQwtPlotRasterItem
PaintInDeviceResolution enum valueQwtPlotRasterItem
paintRect(const QwtScaleMap &, const QwtScaleMap &) const QwtPlotItem
pixelHint(const QRectF &) const QwtPlotSpectrogramvirtual
plot() const QwtPlotItem
QwtPlotItem(const QwtText &title=QwtText())QwtPlotItemexplicit
QwtPlotRasterItem(const QString &title=QString::null)QwtPlotRasterItemexplicit
QwtPlotRasterItem(const QwtText &title)QwtPlotRasterItemexplicit
QwtPlotSpectrogram(const QString &title=QString::null)QwtPlotSpectrogramexplicit
RenderAntialiased enum valueQwtPlotItem
renderContourLines(const QRectF &rect, const QSize &raster) const QwtPlotSpectrogramprotectedvirtual
RenderHint enum nameQwtPlotItem
RenderHints typedefQwtPlotItem
renderImage(const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &area, const QSize &imageSize) const QwtPlotSpectrogramprotectedvirtual
renderThreadCount() const QwtPlotItem
renderTile(const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRect &imageRect, QImage *image) const QwtPlotSpectrogramprotected
rtti() const QwtPlotSpectrogramvirtual
Rtti_PlotBarChart enum valueQwtPlotItem
Rtti_PlotCurve enum valueQwtPlotItem
Rtti_PlotGrid enum valueQwtPlotItem
Rtti_PlotHistogram enum valueQwtPlotItem
Rtti_PlotIntervalCurve enum valueQwtPlotItem
Rtti_PlotItem enum valueQwtPlotItem
Rtti_PlotLegend enum valueQwtPlotItem
Rtti_PlotMarker enum valueQwtPlotItem
Rtti_PlotMultiBarChart enum valueQwtPlotItem
Rtti_PlotScale enum valueQwtPlotItem
Rtti_PlotShape enum valueQwtPlotItem
Rtti_PlotSpectroCurve enum valueQwtPlotItem
Rtti_PlotSpectrogram enum valueQwtPlotItem
Rtti_PlotSVG enum valueQwtPlotItem
Rtti_PlotTextLabel enum valueQwtPlotItem
Rtti_PlotTradingCurve enum valueQwtPlotItem
Rtti_PlotUserItem enum valueQwtPlotItem
Rtti_PlotZone enum valueQwtPlotItem
RttiValues enum nameQwtPlotItem
ScaleInterest enum valueQwtPlotItem
scaleRect(const QwtScaleMap &, const QwtScaleMap &) const QwtPlotItem
setAlpha(int alpha)QwtPlotRasterItem
setAxes(int xAxis, int yAxis)QwtPlotItem
setCachePolicy(CachePolicy)QwtPlotRasterItem
setColorMap(QwtColorMap *)QwtPlotSpectrogram
setConrecFlag(QwtRasterData::ConrecFlag, bool on)QwtPlotSpectrogram
setContourLevels(const QList< double > &)QwtPlotSpectrogram
setData(QwtRasterData *data)QwtPlotSpectrogram
setDefaultContourPen(const QColor &, qreal width=0.0, Qt::PenStyle=Qt::SolidLine)QwtPlotSpectrogram
setDefaultContourPen(const QPen &)QwtPlotSpectrogram
setDisplayMode(DisplayMode, bool on=true)QwtPlotSpectrogram
setItemAttribute(ItemAttribute, bool on=true)QwtPlotItem
setItemInterest(ItemInterest, bool on=true)QwtPlotItem
setLegendIconSize(const QSize &)QwtPlotItem
setPaintAttribute(PaintAttribute, bool on=true)QwtPlotRasterItem
setRenderHint(RenderHint, bool on=true)QwtPlotItem
setRenderThreadCount(uint numThreads)QwtPlotItem
setTitle(const QString &title)QwtPlotItem
setTitle(const QwtText &title)QwtPlotItem
setVisible(bool)QwtPlotItemvirtual
setXAxis(int axis)QwtPlotItem
setYAxis(int axis)QwtPlotItem
setZ(double z)QwtPlotItem
show()QwtPlotItem
testConrecFlag(QwtRasterData::ConrecFlag) const QwtPlotSpectrogram
testDisplayMode(DisplayMode) const QwtPlotSpectrogram
testItemAttribute(ItemAttribute) const QwtPlotItem
testItemInterest(ItemInterest) const QwtPlotItem
testPaintAttribute(PaintAttribute) const QwtPlotRasterItem
testRenderHint(RenderHint) const QwtPlotItem
title() const QwtPlotItem
updateLegend(const QwtPlotItem *, const QList< QwtLegendData > &)QwtPlotItemvirtual
updateScaleDiv(const QwtScaleDiv &, const QwtScaleDiv &)QwtPlotItemvirtual
xAxis() const QwtPlotItem
yAxis() const QwtPlotItem
z() const QwtPlotItem
~QwtPlotItem()QwtPlotItemvirtual
~QwtPlotRasterItem()QwtPlotRasterItemvirtual
~QwtPlotSpectrogram()QwtPlotSpectrogramvirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_spectrogram.html b/ThirdParty/Qwt/doc/html/class_qwt_plot_spectrogram.html new file mode 100644 index 0000000000..ce5a30bf28 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_spectrogram.html @@ -0,0 +1,1276 @@ + + + + + + +Qwt User's Guide: QwtPlotSpectrogram Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtPlotSpectrogram Class Reference
+
+
+ +

A plot item, which displays a spectrogram. + More...

+ +

#include <qwt_plot_spectrogram.h>

+
+Inheritance diagram for QwtPlotSpectrogram:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Types

enum  DisplayMode { ImageMode = 0x01, +ContourMode = 0x02 + }
 
+typedef QFlags< DisplayModeDisplayModes
 Display modes.
 
- Public Types inherited from QwtPlotRasterItem
enum  CachePolicy { NoCache, +PaintCache + }
 Cache policy The default policy is NoCache. More...
 
enum  PaintAttribute { PaintInDeviceResolution = 1 + }
 
+typedef QFlags< PaintAttributePaintAttributes
 Paint attributes.
 
- Public Types inherited from QwtPlotItem
enum  RttiValues {
+  Rtti_PlotItem = 0, +Rtti_PlotGrid, +Rtti_PlotScale, +Rtti_PlotLegend, +
+  Rtti_PlotMarker, +Rtti_PlotCurve, +Rtti_PlotSpectroCurve, +Rtti_PlotIntervalCurve, +
+  Rtti_PlotHistogram, +Rtti_PlotSpectrogram, +Rtti_PlotSVG, +Rtti_PlotTradingCurve, +
+  Rtti_PlotBarChart, +Rtti_PlotMultiBarChart, +Rtti_PlotShape, +Rtti_PlotTextLabel, +
+  Rtti_PlotZone, +Rtti_PlotUserItem = 1000 +
+ }
 Runtime type information. More...
 
enum  ItemAttribute { Legend = 0x01, +AutoScale = 0x02, +Margins = 0x04 + }
 Plot Item Attributes. More...
 
enum  ItemInterest { ScaleInterest = 0x01, +LegendInterest = 0x02 + }
 Plot Item Interests. More...
 
enum  RenderHint { RenderAntialiased = 0x1 + }
 Render hints. More...
 
+typedef QFlags< ItemAttributeItemAttributes
 Plot Item Attributes.
 
+typedef QFlags< ItemInterestItemInterests
 Plot Item Interests.
 
+typedef QFlags< RenderHintRenderHints
 Render hints.
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 QwtPlotSpectrogram (const QString &title=QString::null)
 
+virtual ~QwtPlotSpectrogram ()
 Destructor.
 
void setDisplayMode (DisplayMode, bool on=true)
 
bool testDisplayMode (DisplayMode) const
 
void setData (QwtRasterData *data)
 
const QwtRasterDatadata () const
 
QwtRasterDatadata ()
 
void setColorMap (QwtColorMap *)
 
const QwtColorMapcolorMap () const
 
virtual QwtInterval interval (Qt::Axis) const
 
virtual QRectF pixelHint (const QRectF &) const
 Pixel hint. More...
 
void setDefaultContourPen (const QColor &, qreal width=0.0, Qt::PenStyle=Qt::SolidLine)
 
void setDefaultContourPen (const QPen &)
 Set the default pen for the contour lines. More...
 
QPen defaultContourPen () const
 
virtual QPen contourPen (double level) const
 Calculate the pen for a contour line. More...
 
void setConrecFlag (QwtRasterData::ConrecFlag, bool on)
 
bool testConrecFlag (QwtRasterData::ConrecFlag) const
 
void setContourLevels (const QList< double > &)
 
QList< double > contourLevels () const
 
virtual int rtti () const
 
virtual void draw (QPainter *p, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &rect) const
 Draw the spectrogram. More...
 
- Public Member Functions inherited from QwtPlotRasterItem
QwtPlotRasterItem (const QString &title=QString::null)
 Constructor.
 
QwtPlotRasterItem (const QwtText &title)
 Constructor.
 
+virtual ~QwtPlotRasterItem ()
 Destructor.
 
void setPaintAttribute (PaintAttribute, bool on=true)
 
bool testPaintAttribute (PaintAttribute) const
 
void setAlpha (int alpha)
 Set an alpha value for the raster data. More...
 
int alpha () const
 
void setCachePolicy (CachePolicy)
 
CachePolicy cachePolicy () const
 
void invalidateCache ()
 
virtual QRectF boundingRect () const
 
- Public Member Functions inherited from QwtPlotItem
 QwtPlotItem (const QwtText &title=QwtText())
 
+virtual ~QwtPlotItem ()
 Destroy the QwtPlotItem.
 
void attach (QwtPlot *plot)
 Attach the item to a plot. More...
 
void detach ()
 This method detaches a QwtPlotItem from any QwtPlot it has been associated with. More...
 
+QwtPlotplot () const
 Return attached plot.
 
void setTitle (const QString &title)
 
void setTitle (const QwtText &title)
 
const QwtTexttitle () const
 
void setItemAttribute (ItemAttribute, bool on=true)
 
bool testItemAttribute (ItemAttribute) const
 
void setItemInterest (ItemInterest, bool on=true)
 
bool testItemInterest (ItemInterest) const
 
void setRenderHint (RenderHint, bool on=true)
 
bool testRenderHint (RenderHint) const
 
void setRenderThreadCount (uint numThreads)
 
uint renderThreadCount () const
 
void setLegendIconSize (const QSize &)
 
QSize legendIconSize () const
 
double z () const
 
void setZ (double z)
 Set the z value. More...
 
+void show ()
 Show the item.
 
+void hide ()
 Hide the item.
 
virtual void setVisible (bool)
 
bool isVisible () const
 
void setAxes (int xAxis, int yAxis)
 
void setXAxis (int axis)
 
+int xAxis () const
 Return xAxis.
 
void setYAxis (int axis)
 
+int yAxis () const
 Return yAxis.
 
virtual void itemChanged ()
 
virtual void legendChanged ()
 
virtual void getCanvasMarginHint (const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasSize, double &left, double &top, double &right, double &bottom) const
 Calculate a hint for the canvas margin. More...
 
virtual void updateScaleDiv (const QwtScaleDiv &, const QwtScaleDiv &)
 Update the item to changes of the axes scale division. More...
 
virtual void updateLegend (const QwtPlotItem *, const QList< QwtLegendData > &)
 Update the item to changes of the legend info. More...
 
QRectF scaleRect (const QwtScaleMap &, const QwtScaleMap &) const
 Calculate the bounding scale rectangle of 2 maps. More...
 
QRectF paintRect (const QwtScaleMap &, const QwtScaleMap &) const
 Calculate the bounding paint rectangle of 2 maps. More...
 
virtual QList< QwtLegendDatalegendData () const
 Return all information, that is needed to represent the item on the legend. More...
 
virtual QwtGraphic legendIcon (int index, const QSizeF &) const
 
+ + + + + + + + + + + + + + + + + + + + + + +

+Protected Member Functions

virtual QImage renderImage (const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &area, const QSize &imageSize) const
 Render an image from data and color map. More...
 
virtual QSize contourRasterSize (const QRectF &, const QRect &) const
 Return the raster to be used by the CONREC contour algorithm. More...
 
virtual QwtRasterData::ContourLines renderContourLines (const QRectF &rect, const QSize &raster) const
 
virtual void drawContourLines (QPainter *p, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QwtRasterData::ContourLines &lines) const
 
void renderTile (const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRect &imageRect, QImage *image) const
 Render a tile of an image. More...
 
- Protected Member Functions inherited from QwtPlotRasterItem
virtual QwtScaleMap imageMap (Qt::Orientation, const QwtScaleMap &map, const QRectF &area, const QSize &imageSize, double pixelSize) const
 Calculate a scale map for painting to an image. More...
 
- Protected Member Functions inherited from QwtPlotItem
QwtGraphic defaultIcon (const QBrush &, const QSizeF &) const
 Return a default icon from a brush. More...
 
+

Detailed Description

+

A plot item, which displays a spectrogram.

+

A spectrogram displays 3-dimensional data, where the 3rd dimension ( the intensity ) is displayed using colors. The colors are calculated from the values using a color map.

+

On multi-core systems the performance of the image composition can often be improved by dividing the area into tiles - each of them rendered in a different thread ( see QwtPlotItem::setRenderThreadCount() ).

+

In ContourMode contour lines are painted for the contour levels.

+
+spectrogram3.png +
+
See Also
QwtRasterData, QwtColorMap, QwtPlotItem::setRenderThreadCount()
+

Member Enumeration Documentation

+ +
+
+

The display mode controls how the raster data will be represented.

+
See Also
setDisplayMode(), testDisplayMode()
+ + + +
Enumerator
ImageMode  +

The values are mapped to colors using a color map.

+
ContourMode  +

The data is displayed using contour lines.

+
+ +
+
+

Constructor & Destructor Documentation

+ +
+
+ + + + + +
+ + + + + + + + +
QwtPlotSpectrogram::QwtPlotSpectrogram (const QString & title = QString::null)
+
+explicit
+
+

Sets the following item attributes:

+ +

The z value is initialized by 8.0.

+
Parameters
+ + +
titleTitle
+
+
+
See Also
QwtPlotItem::setItemAttribute(), QwtPlotItem::setZ()
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + + + +
const QwtColorMap * QwtPlotSpectrogram::colorMap () const
+
+
Returns
Color Map used for mapping the intensity values to colors
+
See Also
setColorMap()
+ +
+
+ +
+
+ + + + + + + +
QList< double > QwtPlotSpectrogram::contourLevels () const
+
+
Returns
Levels of the contour lines.
+

The levels are sorted in increasing order.

+
See Also
contourLevels(), renderContourLines(), QwtRasterData::contourLines()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
QPen QwtPlotSpectrogram::contourPen (double level) const
+
+virtual
+
+ +

Calculate the pen for a contour line.

+

The color of the pen is the color for level calculated by the color map

+
Parameters
+ + +
levelContour level
+
+
+
Returns
Pen for the contour line
+
Note
contourPen is only used if defaultContourPen().style() == Qt::NoPen
+
See Also
setDefaultContourPen(), setColorMap(), setContourLevels()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
QSize QwtPlotSpectrogram::contourRasterSize (const QRectF & area,
const QRect & rect 
) const
+
+protectedvirtual
+
+ +

Return the raster to be used by the CONREC contour algorithm.

+

A larger size will improve the precision of the CONREC algorithm, but will slow down the time that is needed to calculate the lines.

+

The default implementation returns rect.size() / 2 bounded to the resolution depending on pixelSize().

+
Parameters
+ + + +
areaRectangle, where to calculate the contour lines
rectRectangle in pixel coordinates, where to paint the contour lines
+
+
+
Returns
Raster to be used by the CONREC contour algorithm.
+
Note
The size will be bounded to rect.size().
+
See Also
drawContourLines(), QwtRasterData::contourLines()
+ +
+
+ +
+
+ + + + + + + +
const QwtRasterData * QwtPlotSpectrogram::data () const
+
+
Returns
Spectrogram data
+
See Also
setData()
+ +
+
+ +
+
+ + + + + + + +
QwtRasterData * QwtPlotSpectrogram::data ()
+
+
Returns
Spectrogram data
+
See Also
setData()
+ +
+
+ +
+
+ + + + + + + +
QPen QwtPlotSpectrogram::defaultContourPen () const
+
+
Returns
Default contour pen
+
See Also
setDefaultContourPen()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPlotSpectrogram::draw (QPainter * painter,
const QwtScaleMapxMap,
const QwtScaleMapyMap,
const QRectF & canvasRect 
) const
+
+virtual
+
+ +

Draw the spectrogram.

+
Parameters
+ + + + + +
painterPainter
xMapMaps x-values into pixel coordinates.
yMapMaps y-values into pixel coordinates.
canvasRectContents rectangle of the canvas in painter coordinates
+
+
+
See Also
setDisplayMode(), renderImage(), QwtPlotRasterItem::draw(), drawContourLines()
+ +

Reimplemented from QwtPlotRasterItem.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPlotSpectrogram::drawContourLines (QPainter * painter,
const QwtScaleMapxMap,
const QwtScaleMapyMap,
const QwtRasterData::ContourLinescontourLines 
) const
+
+protectedvirtual
+
+

Paint the contour lines

+
Parameters
+ + + + + +
painterPainter
xMapMaps x-values into pixel coordinates.
yMapMaps y-values into pixel coordinates.
contourLinesContour lines
+
+
+
See Also
renderContourLines(), defaultContourPen(), contourPen()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
QwtInterval QwtPlotSpectrogram::interval (Qt::Axis axis) const
+
+virtual
+
+
Returns
Bounding interval for an axis
+

The default implementation returns the interval of the associated raster data object.

+
Parameters
+ + +
axisX, Y, or Z axis
+
+
+
See Also
QwtRasterData::interval()
+ +

Reimplemented from QwtPlotRasterItem.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
QRectF QwtPlotSpectrogram::pixelHint (const QRectF & area) const
+
+virtual
+
+ +

Pixel hint.

+

The geometry of a pixel is used to calculated the resolution and alignment of the rendered image.

+

The default implementation returns data()->pixelHint( rect );

+
Parameters
+ + +
areaIn most implementations the resolution of the data doesn't depend on the requested area.
+
+
+
Returns
Bounding rectangle of a pixel
+
See Also
QwtPlotRasterItem::pixelHint(), QwtRasterData::pixelHint(), render(), renderImage()
+ +

Reimplemented from QwtPlotRasterItem.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
QwtRasterData::ContourLines QwtPlotSpectrogram::renderContourLines (const QRectF & rect,
const QSize & raster 
) const
+
+protectedvirtual
+
+

Calculate contour lines

+
Parameters
+ + + +
rectRectangle, where to calculate the contour lines
rasterRaster, used by the CONREC algorithm
+
+
+
Returns
Calculated contour lines
+
See Also
contourLevels(), setConrecFlag(), QwtRasterData::contourLines()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
QImage QwtPlotSpectrogram::renderImage (const QwtScaleMapxMap,
const QwtScaleMapyMap,
const QRectF & area,
const QSize & imageSize 
) const
+
+protectedvirtual
+
+ +

Render an image from data and color map.

+

For each pixel of area the value is mapped into a color.

+
Parameters
+ + + + + +
xMapX-Scale Map
yMapY-Scale Map
areaRequested area for the image in scale coordinates
imageSizeSize of the requested image
+
+
+
Returns
A QImage::Format_Indexed8 or QImage::Format_ARGB32 depending on the color map.
+
See Also
QwtRasterData::value(), QwtColorMap::rgb(), QwtColorMap::colorIndex()
+ +

Implements QwtPlotRasterItem.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPlotSpectrogram::renderTile (const QwtScaleMapxMap,
const QwtScaleMapyMap,
const QRect & tile,
QImage * image 
) const
+
+protected
+
+ +

Render a tile of an image.

+

Rendering in tiles can be used to composite an image in parallel threads.

+
Parameters
+ + + + + +
xMapX-Scale Map
yMapY-Scale Map
tileGeometry of the tile in image coordinates
imageImage to be rendered
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
int QwtPlotSpectrogram::rtti () const
+
+virtual
+
+
Returns
QwtPlotItem::Rtti_PlotSpectrogram
+ +

Reimplemented from QwtPlotItem.

+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotSpectrogram::setColorMap (QwtColorMapcolorMap)
+
+

Change the color map

+

Often it is useful to display the mapping between intensities and colors as an additional plot axis, showing a color bar.

+
Parameters
+ + +
colorMapColor Map
+
+
+
See Also
colorMap(), QwtScaleWidget::setColorBarEnabled(), QwtScaleWidget::setColorMap()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtPlotSpectrogram::setConrecFlag (QwtRasterData::ConrecFlag flag,
bool on 
)
+
+

Modify an attribute of the CONREC algorithm, used to calculate the contour lines.

+
Parameters
+ + + +
flagCONREC flag
onOn/Off
+
+
+
See Also
testConrecFlag(), renderContourLines(), QwtRasterData::contourLines()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotSpectrogram::setContourLevels (const QList< double > & levels)
+
+

Set the levels of the contour lines

+
Parameters
+ + +
levelsValues of the contour levels
+
+
+
See Also
contourLevels(), renderContourLines(), QwtRasterData::contourLines()
+
Note
contourLevels returns the same levels but sorted.
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotSpectrogram::setData (QwtRasterDatadata)
+
+

Set the data to be displayed

+
Parameters
+ + +
dataSpectrogram Data
+
+
+
See Also
data()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPlotSpectrogram::setDefaultContourPen (const QColor & color,
qreal width = 0.0,
Qt::PenStyle style = Qt::SolidLine 
)
+
+

Build and assign the default pen for the contour lines

+

In Qt5 the default pen width is 1.0 ( 0.0 in Qt4 ) what makes it non cosmetic ( see QPen::isCosmetic() ). This method has been introduced to hide this incompatibility.

+
Parameters
+ + + + +
colorPen color
widthPen width
stylePen style
+
+
+
See Also
pen(), brush()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotSpectrogram::setDefaultContourPen (const QPen & pen)
+
+ +

Set the default pen for the contour lines.

+

If the spectrogram has a valid default contour pen a contour line is painted using the default contour pen. Otherwise (pen.style() == Qt::NoPen) the pen is calculated for each contour level using contourPen().

+
See Also
defaultContourPen(), contourPen()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtPlotSpectrogram::setDisplayMode (DisplayMode mode,
bool on = true 
)
+
+

The display mode controls how the raster data will be represented.

+
Parameters
+ + + +
modeDisplay mode
onOn/Off
+
+
+

The default setting enables ImageMode.

+
See Also
DisplayMode, displayMode()
+ +
+
+ +
+
+ + + + + + + + +
bool QwtPlotSpectrogram::testConrecFlag (QwtRasterData::ConrecFlag flag) const
+
+

Test an attribute of the CONREC algorithm, used to calculate the contour lines.

+
Parameters
+ + +
flagCONREC flag
+
+
+
Returns
true, is enabled
+

The default setting enables QwtRasterData::IgnoreAllVerticesOnLevel

+
See Also
setConrecClag(), renderContourLines(), QwtRasterData::contourLines()
+ +
+
+ +
+
+ + + + + + + + +
bool QwtPlotSpectrogram::testDisplayMode (DisplayMode mode) const
+
+

The display mode controls how the raster data will be represented.

+
Parameters
+ + +
modeDisplay mode
+
+
+
Returns
true if mode is enabled
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_spectrogram__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_plot_spectrogram__inherit__graph.map new file mode 100644 index 0000000000..b2c9d98faa --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_spectrogram__inherit__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_spectrogram__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_plot_spectrogram__inherit__graph.md5 new file mode 100644 index 0000000000..71bfaaa3c1 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_spectrogram__inherit__graph.md5 @@ -0,0 +1 @@ +47589ec3b69fa3113c39746dc1af9e8e \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_spectrogram__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_plot_spectrogram__inherit__graph.png new file mode 100644 index 0000000000..1950749cd3 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_plot_spectrogram__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_svg_item-members.html b/ThirdParty/Qwt/doc/html/class_qwt_plot_svg_item-members.html new file mode 100644 index 0000000000..4caa5a1a68 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_svg_item-members.html @@ -0,0 +1,182 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtPlotSvgItem Member List
+
+
+ +

This is the complete list of members for QwtPlotSvgItem, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
attach(QwtPlot *plot)QwtPlotItem
AutoScale enum valueQwtPlotItem
boundingRect() const QwtPlotSvgItemvirtual
defaultIcon(const QBrush &, const QSizeF &) const QwtPlotItemprotected
detach()QwtPlotItem
draw(QPainter *p, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &rect) const QwtPlotSvgItemvirtual
getCanvasMarginHint(const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasSize, double &left, double &top, double &right, double &bottom) const QwtPlotItemvirtual
hide()QwtPlotItem
isVisible() const QwtPlotItem
ItemAttribute enum nameQwtPlotItem
ItemAttributes typedefQwtPlotItem
itemChanged()QwtPlotItemvirtual
ItemInterest enum nameQwtPlotItem
ItemInterests typedefQwtPlotItem
Legend enum valueQwtPlotItem
legendChanged()QwtPlotItemvirtual
legendData() const QwtPlotItemvirtual
legendIcon(int index, const QSizeF &) const QwtPlotItemvirtual
legendIconSize() const QwtPlotItem
LegendInterest enum valueQwtPlotItem
loadData(const QRectF &, const QByteArray &)QwtPlotSvgItem
loadFile(const QRectF &, const QString &fileName)QwtPlotSvgItem
Margins enum valueQwtPlotItem
paintRect(const QwtScaleMap &, const QwtScaleMap &) const QwtPlotItem
plot() const QwtPlotItem
QwtPlotItem(const QwtText &title=QwtText())QwtPlotItemexplicit
QwtPlotSvgItem(const QString &title=QString::null)QwtPlotSvgItemexplicit
QwtPlotSvgItem(const QwtText &title)QwtPlotSvgItemexplicit
render(QPainter *painter, const QRectF &viewBox, const QRectF &rect) const QwtPlotSvgItemprotected
RenderAntialiased enum valueQwtPlotItem
renderer() const QwtPlotSvgItemprotected
renderer()QwtPlotSvgItemprotected
RenderHint enum nameQwtPlotItem
RenderHints typedefQwtPlotItem
renderThreadCount() const QwtPlotItem
rtti() const QwtPlotSvgItemvirtual
Rtti_PlotBarChart enum valueQwtPlotItem
Rtti_PlotCurve enum valueQwtPlotItem
Rtti_PlotGrid enum valueQwtPlotItem
Rtti_PlotHistogram enum valueQwtPlotItem
Rtti_PlotIntervalCurve enum valueQwtPlotItem
Rtti_PlotItem enum valueQwtPlotItem
Rtti_PlotLegend enum valueQwtPlotItem
Rtti_PlotMarker enum valueQwtPlotItem
Rtti_PlotMultiBarChart enum valueQwtPlotItem
Rtti_PlotScale enum valueQwtPlotItem
Rtti_PlotShape enum valueQwtPlotItem
Rtti_PlotSpectroCurve enum valueQwtPlotItem
Rtti_PlotSpectrogram enum valueQwtPlotItem
Rtti_PlotSVG enum valueQwtPlotItem
Rtti_PlotTextLabel enum valueQwtPlotItem
Rtti_PlotTradingCurve enum valueQwtPlotItem
Rtti_PlotUserItem enum valueQwtPlotItem
Rtti_PlotZone enum valueQwtPlotItem
RttiValues enum nameQwtPlotItem
ScaleInterest enum valueQwtPlotItem
scaleRect(const QwtScaleMap &, const QwtScaleMap &) const QwtPlotItem
setAxes(int xAxis, int yAxis)QwtPlotItem
setItemAttribute(ItemAttribute, bool on=true)QwtPlotItem
setItemInterest(ItemInterest, bool on=true)QwtPlotItem
setLegendIconSize(const QSize &)QwtPlotItem
setRenderHint(RenderHint, bool on=true)QwtPlotItem
setRenderThreadCount(uint numThreads)QwtPlotItem
setTitle(const QString &title)QwtPlotItem
setTitle(const QwtText &title)QwtPlotItem
setVisible(bool)QwtPlotItemvirtual
setXAxis(int axis)QwtPlotItem
setYAxis(int axis)QwtPlotItem
setZ(double z)QwtPlotItem
show()QwtPlotItem
testItemAttribute(ItemAttribute) const QwtPlotItem
testItemInterest(ItemInterest) const QwtPlotItem
testRenderHint(RenderHint) const QwtPlotItem
title() const QwtPlotItem
updateLegend(const QwtPlotItem *, const QList< QwtLegendData > &)QwtPlotItemvirtual
updateScaleDiv(const QwtScaleDiv &, const QwtScaleDiv &)QwtPlotItemvirtual
viewBox(const QRectF &area) const QwtPlotSvgItemprotected
xAxis() const QwtPlotItem
yAxis() const QwtPlotItem
z() const QwtPlotItem
~QwtPlotItem()QwtPlotItemvirtual
~QwtPlotSvgItem()QwtPlotSvgItemvirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_svg_item.html b/ThirdParty/Qwt/doc/html/class_qwt_plot_svg_item.html new file mode 100644 index 0000000000..acd8afa577 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_svg_item.html @@ -0,0 +1,672 @@ + + + + + + +Qwt User's Guide: QwtPlotSvgItem Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtPlotSvgItem Class Reference
+
+
+ +

A plot item, which displays data in Scalable Vector Graphics (SVG) format. + More...

+ +

#include <qwt_plot_svgitem.h>

+
+Inheritance diagram for QwtPlotSvgItem:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 QwtPlotSvgItem (const QString &title=QString::null)
 Constructor. More...
 
 QwtPlotSvgItem (const QwtText &title)
 Constructor. More...
 
+virtual ~QwtPlotSvgItem ()
 Destructor.
 
bool loadFile (const QRectF &, const QString &fileName)
 
bool loadData (const QRectF &, const QByteArray &)
 
+virtual QRectF boundingRect () const
 Bounding rectangle of the item.
 
virtual void draw (QPainter *p, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &rect) const
 
virtual int rtti () const
 
- Public Member Functions inherited from QwtPlotItem
 QwtPlotItem (const QwtText &title=QwtText())
 
+virtual ~QwtPlotItem ()
 Destroy the QwtPlotItem.
 
void attach (QwtPlot *plot)
 Attach the item to a plot. More...
 
void detach ()
 This method detaches a QwtPlotItem from any QwtPlot it has been associated with. More...
 
+QwtPlotplot () const
 Return attached plot.
 
void setTitle (const QString &title)
 
void setTitle (const QwtText &title)
 
const QwtTexttitle () const
 
void setItemAttribute (ItemAttribute, bool on=true)
 
bool testItemAttribute (ItemAttribute) const
 
void setItemInterest (ItemInterest, bool on=true)
 
bool testItemInterest (ItemInterest) const
 
void setRenderHint (RenderHint, bool on=true)
 
bool testRenderHint (RenderHint) const
 
void setRenderThreadCount (uint numThreads)
 
uint renderThreadCount () const
 
void setLegendIconSize (const QSize &)
 
QSize legendIconSize () const
 
double z () const
 
void setZ (double z)
 Set the z value. More...
 
+void show ()
 Show the item.
 
+void hide ()
 Hide the item.
 
virtual void setVisible (bool)
 
bool isVisible () const
 
void setAxes (int xAxis, int yAxis)
 
void setXAxis (int axis)
 
+int xAxis () const
 Return xAxis.
 
void setYAxis (int axis)
 
+int yAxis () const
 Return yAxis.
 
virtual void itemChanged ()
 
virtual void legendChanged ()
 
virtual void getCanvasMarginHint (const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasSize, double &left, double &top, double &right, double &bottom) const
 Calculate a hint for the canvas margin. More...
 
virtual void updateScaleDiv (const QwtScaleDiv &, const QwtScaleDiv &)
 Update the item to changes of the axes scale division. More...
 
virtual void updateLegend (const QwtPlotItem *, const QList< QwtLegendData > &)
 Update the item to changes of the legend info. More...
 
QRectF scaleRect (const QwtScaleMap &, const QwtScaleMap &) const
 Calculate the bounding scale rectangle of 2 maps. More...
 
QRectF paintRect (const QwtScaleMap &, const QwtScaleMap &) const
 Calculate the bounding paint rectangle of 2 maps. More...
 
virtual QList< QwtLegendDatalegendData () const
 Return all information, that is needed to represent the item on the legend. More...
 
virtual QwtGraphic legendIcon (int index, const QSizeF &) const
 
+ + + + + + + + + + + + + +

+Protected Member Functions

const QSvgRenderer & renderer () const
 
QSvgRenderer & renderer ()
 
void render (QPainter *painter, const QRectF &viewBox, const QRectF &rect) const
 
QRectF viewBox (const QRectF &area) const
 
- Protected Member Functions inherited from QwtPlotItem
QwtGraphic defaultIcon (const QBrush &, const QSizeF &) const
 Return a default icon from a brush. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + +

+Additional Inherited Members

- Public Types inherited from QwtPlotItem
enum  RttiValues {
+  Rtti_PlotItem = 0, +Rtti_PlotGrid, +Rtti_PlotScale, +Rtti_PlotLegend, +
+  Rtti_PlotMarker, +Rtti_PlotCurve, +Rtti_PlotSpectroCurve, +Rtti_PlotIntervalCurve, +
+  Rtti_PlotHistogram, +Rtti_PlotSpectrogram, +Rtti_PlotSVG, +Rtti_PlotTradingCurve, +
+  Rtti_PlotBarChart, +Rtti_PlotMultiBarChart, +Rtti_PlotShape, +Rtti_PlotTextLabel, +
+  Rtti_PlotZone, +Rtti_PlotUserItem = 1000 +
+ }
 Runtime type information. More...
 
enum  ItemAttribute { Legend = 0x01, +AutoScale = 0x02, +Margins = 0x04 + }
 Plot Item Attributes. More...
 
enum  ItemInterest { ScaleInterest = 0x01, +LegendInterest = 0x02 + }
 Plot Item Interests. More...
 
enum  RenderHint { RenderAntialiased = 0x1 + }
 Render hints. More...
 
+typedef QFlags< ItemAttributeItemAttributes
 Plot Item Attributes.
 
+typedef QFlags< ItemInterestItemInterests
 Plot Item Interests.
 
+typedef QFlags< RenderHintRenderHints
 Render hints.
 
+

Detailed Description

+

A plot item, which displays data in Scalable Vector Graphics (SVG) format.

+

SVG images are often used to display maps

+

Constructor & Destructor Documentation

+ +
+
+ + + + + +
+ + + + + + + + +
QwtPlotSvgItem::QwtPlotSvgItem (const QString & title = QString::null)
+
+explicit
+
+ +

Constructor.

+

Sets the following item attributes:

+ +
Parameters
+ + +
titleTitle
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
QwtPlotSvgItem::QwtPlotSvgItem (const QwtTexttitle)
+
+explicit
+
+ +

Constructor.

+

Sets the following item attributes:

+ +
Parameters
+ + +
titleTitle
+
+
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPlotSvgItem::draw (QPainter * painter,
const QwtScaleMapxMap,
const QwtScaleMapyMap,
const QRectF & canvasRect 
) const
+
+virtual
+
+

Draw the SVG item

+
Parameters
+ + + + + +
painterPainter
xMapX-Scale Map
yMapY-Scale Map
canvasRectContents rect of the plot canvas
+
+
+ +

Implements QwtPlotItem.

+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
bool QwtPlotSvgItem::loadData (const QRectF & rect,
const QByteArray & data 
)
+
+

Load SVG data

+
Parameters
+ + + +
rectBounding rectangle
datain SVG format
+
+
+
Returns
true, if the SVG data could be loaded
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
bool QwtPlotSvgItem::loadFile (const QRectF & rect,
const QString & fileName 
)
+
+

Load a SVG file

+
Parameters
+ + + +
rectBounding rectangle
fileNameSVG file name
+
+
+
Returns
true, if the SVG file could be loaded
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPlotSvgItem::render (QPainter * painter,
const QRectF & viewBox,
const QRectF & rect 
) const
+
+protected
+
+

Render the SVG data

+
Parameters
+ + + + +
painterPainter
viewBoxView Box, see QSvgRenderer::viewBox()
rectTarget rectangle on the paint device
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
const QSvgRenderer & QwtPlotSvgItem::renderer () const
+
+protected
+
+
Returns
Renderer used to render the SVG data
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
QSvgRenderer & QwtPlotSvgItem::renderer ()
+
+protected
+
+
Returns
Renderer used to render the SVG data
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
int QwtPlotSvgItem::rtti () const
+
+virtual
+
+
Returns
QwtPlotItem::Rtti_PlotSVG
+ +

Reimplemented from QwtPlotItem.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
QRectF QwtPlotSvgItem::viewBox (const QRectF & rect) const
+
+protected
+
+

Calculate the view box from rect and boundingRect().

+
Parameters
+ + +
rectRectangle in scale coordinates
+
+
+
Returns
View box, see QSvgRenderer::viewBox()
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_svg_item__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_plot_svg_item__inherit__graph.map new file mode 100644 index 0000000000..4fbf84c3e2 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_svg_item__inherit__graph.map @@ -0,0 +1,3 @@ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_svg_item__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_plot_svg_item__inherit__graph.md5 new file mode 100644 index 0000000000..3555d7aa1a --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_svg_item__inherit__graph.md5 @@ -0,0 +1 @@ +5a51963d6e26e52f8db39b61e28cc9bd \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_svg_item__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_plot_svg_item__inherit__graph.png new file mode 100644 index 0000000000..52e2446500 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_plot_svg_item__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_text_label-members.html b/ThirdParty/Qwt/doc/html/class_qwt_plot_text_label-members.html new file mode 100644 index 0000000000..d02d81f90b --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_text_label-members.html @@ -0,0 +1,181 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtPlotTextLabel Member List
+
+
+ +

This is the complete list of members for QwtPlotTextLabel, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
attach(QwtPlot *plot)QwtPlotItem
AutoScale enum valueQwtPlotItem
boundingRect() const QwtPlotItemvirtual
defaultIcon(const QBrush &, const QSizeF &) const QwtPlotItemprotected
detach()QwtPlotItem
draw(QPainter *, const QwtScaleMap &, const QwtScaleMap &, const QRectF &) const QwtPlotTextLabelprotectedvirtual
getCanvasMarginHint(const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasSize, double &left, double &top, double &right, double &bottom) const QwtPlotItemvirtual
hide()QwtPlotItem
invalidateCache()QwtPlotTextLabelprotected
isVisible() const QwtPlotItem
ItemAttribute enum nameQwtPlotItem
ItemAttributes typedefQwtPlotItem
itemChanged()QwtPlotItemvirtual
ItemInterest enum nameQwtPlotItem
ItemInterests typedefQwtPlotItem
Legend enum valueQwtPlotItem
legendChanged()QwtPlotItemvirtual
legendData() const QwtPlotItemvirtual
legendIcon(int index, const QSizeF &) const QwtPlotItemvirtual
legendIconSize() const QwtPlotItem
LegendInterest enum valueQwtPlotItem
margin() const QwtPlotTextLabel
Margins enum valueQwtPlotItem
paintRect(const QwtScaleMap &, const QwtScaleMap &) const QwtPlotItem
plot() const QwtPlotItem
QwtPlotItem(const QwtText &title=QwtText())QwtPlotItemexplicit
QwtPlotTextLabel()QwtPlotTextLabel
RenderAntialiased enum valueQwtPlotItem
RenderHint enum nameQwtPlotItem
RenderHints typedefQwtPlotItem
renderThreadCount() const QwtPlotItem
rtti() const QwtPlotTextLabelvirtual
Rtti_PlotBarChart enum valueQwtPlotItem
Rtti_PlotCurve enum valueQwtPlotItem
Rtti_PlotGrid enum valueQwtPlotItem
Rtti_PlotHistogram enum valueQwtPlotItem
Rtti_PlotIntervalCurve enum valueQwtPlotItem
Rtti_PlotItem enum valueQwtPlotItem
Rtti_PlotLegend enum valueQwtPlotItem
Rtti_PlotMarker enum valueQwtPlotItem
Rtti_PlotMultiBarChart enum valueQwtPlotItem
Rtti_PlotScale enum valueQwtPlotItem
Rtti_PlotShape enum valueQwtPlotItem
Rtti_PlotSpectroCurve enum valueQwtPlotItem
Rtti_PlotSpectrogram enum valueQwtPlotItem
Rtti_PlotSVG enum valueQwtPlotItem
Rtti_PlotTextLabel enum valueQwtPlotItem
Rtti_PlotTradingCurve enum valueQwtPlotItem
Rtti_PlotUserItem enum valueQwtPlotItem
Rtti_PlotZone enum valueQwtPlotItem
RttiValues enum nameQwtPlotItem
ScaleInterest enum valueQwtPlotItem
scaleRect(const QwtScaleMap &, const QwtScaleMap &) const QwtPlotItem
setAxes(int xAxis, int yAxis)QwtPlotItem
setItemAttribute(ItemAttribute, bool on=true)QwtPlotItem
setItemInterest(ItemInterest, bool on=true)QwtPlotItem
setLegendIconSize(const QSize &)QwtPlotItem
setMargin(int margin)QwtPlotTextLabel
setRenderHint(RenderHint, bool on=true)QwtPlotItem
setRenderThreadCount(uint numThreads)QwtPlotItem
setText(const QwtText &)QwtPlotTextLabel
setTitle(const QString &title)QwtPlotItem
setTitle(const QwtText &title)QwtPlotItem
setVisible(bool)QwtPlotItemvirtual
setXAxis(int axis)QwtPlotItem
setYAxis(int axis)QwtPlotItem
setZ(double z)QwtPlotItem
show()QwtPlotItem
testItemAttribute(ItemAttribute) const QwtPlotItem
testItemInterest(ItemInterest) const QwtPlotItem
testRenderHint(RenderHint) const QwtPlotItem
text() const QwtPlotTextLabel
textRect(const QRectF &, const QSizeF &) const QwtPlotTextLabelvirtual
title() const QwtPlotItem
updateLegend(const QwtPlotItem *, const QList< QwtLegendData > &)QwtPlotItemvirtual
updateScaleDiv(const QwtScaleDiv &, const QwtScaleDiv &)QwtPlotItemvirtual
xAxis() const QwtPlotItem
yAxis() const QwtPlotItem
z() const QwtPlotItem
~QwtPlotItem()QwtPlotItemvirtual
~QwtPlotTextLabel()QwtPlotTextLabelvirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_text_label.html b/ThirdParty/Qwt/doc/html/class_qwt_plot_text_label.html new file mode 100644 index 0000000000..c45d7e331a --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_text_label.html @@ -0,0 +1,566 @@ + + + + + + +Qwt User's Guide: QwtPlotTextLabel Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtPlotTextLabel Class Reference
+
+
+ +

A plot item, which displays a text label. + More...

+ +

#include <qwt_plot_textlabel.h>

+
+Inheritance diagram for QwtPlotTextLabel:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 QwtPlotTextLabel ()
 Constructor. More...
 
+virtual ~QwtPlotTextLabel ()
 Destructor.
 
virtual int rtti () const
 
void setText (const QwtText &)
 
QwtText text () const
 
void setMargin (int margin)
 
int margin () const
 
virtual QRectF textRect (const QRectF &, const QSizeF &) const
 Align the text label. More...
 
- Public Member Functions inherited from QwtPlotItem
 QwtPlotItem (const QwtText &title=QwtText())
 
+virtual ~QwtPlotItem ()
 Destroy the QwtPlotItem.
 
void attach (QwtPlot *plot)
 Attach the item to a plot. More...
 
void detach ()
 This method detaches a QwtPlotItem from any QwtPlot it has been associated with. More...
 
+QwtPlotplot () const
 Return attached plot.
 
void setTitle (const QString &title)
 
void setTitle (const QwtText &title)
 
const QwtTexttitle () const
 
void setItemAttribute (ItemAttribute, bool on=true)
 
bool testItemAttribute (ItemAttribute) const
 
void setItemInterest (ItemInterest, bool on=true)
 
bool testItemInterest (ItemInterest) const
 
void setRenderHint (RenderHint, bool on=true)
 
bool testRenderHint (RenderHint) const
 
void setRenderThreadCount (uint numThreads)
 
uint renderThreadCount () const
 
void setLegendIconSize (const QSize &)
 
QSize legendIconSize () const
 
double z () const
 
void setZ (double z)
 Set the z value. More...
 
+void show ()
 Show the item.
 
+void hide ()
 Hide the item.
 
virtual void setVisible (bool)
 
bool isVisible () const
 
void setAxes (int xAxis, int yAxis)
 
void setXAxis (int axis)
 
+int xAxis () const
 Return xAxis.
 
void setYAxis (int axis)
 
+int yAxis () const
 Return yAxis.
 
virtual void itemChanged ()
 
virtual void legendChanged ()
 
virtual QRectF boundingRect () const
 
virtual void getCanvasMarginHint (const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasSize, double &left, double &top, double &right, double &bottom) const
 Calculate a hint for the canvas margin. More...
 
virtual void updateScaleDiv (const QwtScaleDiv &, const QwtScaleDiv &)
 Update the item to changes of the axes scale division. More...
 
virtual void updateLegend (const QwtPlotItem *, const QList< QwtLegendData > &)
 Update the item to changes of the legend info. More...
 
QRectF scaleRect (const QwtScaleMap &, const QwtScaleMap &) const
 Calculate the bounding scale rectangle of 2 maps. More...
 
QRectF paintRect (const QwtScaleMap &, const QwtScaleMap &) const
 Calculate the bounding paint rectangle of 2 maps. More...
 
virtual QList< QwtLegendDatalegendData () const
 Return all information, that is needed to represent the item on the legend. More...
 
virtual QwtGraphic legendIcon (int index, const QSizeF &) const
 
+ + + + + + + + + + +

+Protected Member Functions

virtual void draw (QPainter *, const QwtScaleMap &, const QwtScaleMap &, const QRectF &) const
 
+void invalidateCache ()
 Invalidate all internal cache.
 
- Protected Member Functions inherited from QwtPlotItem
QwtGraphic defaultIcon (const QBrush &, const QSizeF &) const
 Return a default icon from a brush. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + +

+Additional Inherited Members

- Public Types inherited from QwtPlotItem
enum  RttiValues {
+  Rtti_PlotItem = 0, +Rtti_PlotGrid, +Rtti_PlotScale, +Rtti_PlotLegend, +
+  Rtti_PlotMarker, +Rtti_PlotCurve, +Rtti_PlotSpectroCurve, +Rtti_PlotIntervalCurve, +
+  Rtti_PlotHistogram, +Rtti_PlotSpectrogram, +Rtti_PlotSVG, +Rtti_PlotTradingCurve, +
+  Rtti_PlotBarChart, +Rtti_PlotMultiBarChart, +Rtti_PlotShape, +Rtti_PlotTextLabel, +
+  Rtti_PlotZone, +Rtti_PlotUserItem = 1000 +
+ }
 Runtime type information. More...
 
enum  ItemAttribute { Legend = 0x01, +AutoScale = 0x02, +Margins = 0x04 + }
 Plot Item Attributes. More...
 
enum  ItemInterest { ScaleInterest = 0x01, +LegendInterest = 0x02 + }
 Plot Item Interests. More...
 
enum  RenderHint { RenderAntialiased = 0x1 + }
 Render hints. More...
 
+typedef QFlags< ItemAttributeItemAttributes
 Plot Item Attributes.
 
+typedef QFlags< ItemInterestItemInterests
 Plot Item Interests.
 
+typedef QFlags< RenderHintRenderHints
 Render hints.
 
+

Detailed Description

+

A plot item, which displays a text label.

+

QwtPlotTextLabel displays a text label aligned to the plot canvas.

+

In opposite to QwtPlotMarker the position of the label is unrelated to plot coordinates.

+

As drawing a text is an expensive operation the label is cached in a pixmap to speed up replots.

+
Example
The following code shows how to add a title.
+
    QwtText title( "Plot Title" );
+    title.setRenderFlags( Qt::AlignHCenter | Qt::AlignTop );
+
+    QFont font;
+    font.setBold( true );
+    title.setFont( font );
+
+    QwtPlotTextLabel *titleItem = new QwtPlotTextLabel();
+    titleItem->setText( title );
+    titleItem->attach( this );
+
See Also
QwtPlotMarker
+

Constructor & Destructor Documentation

+ +
+
+ + + + + + + +
QwtPlotTextLabel::QwtPlotTextLabel ()
+
+ +

Constructor.

+

Initializes an text label with an empty text

+

Sets the following item attributes:

+ +

The z value is initialized by 150

+
See Also
QwtPlotItem::setItemAttribute(), QwtPlotItem::setZ()
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPlotTextLabel::draw (QPainter * painter,
const QwtScaleMapxMap,
const QwtScaleMapyMap,
const QRectF & canvasRect 
) const
+
+protectedvirtual
+
+

Draw the text label

+
Parameters
+ + + + + +
painterPainter
xMapx Scale Map
yMapy Scale Map
canvasRectContents rectangle of the canvas in painter coordinates
+
+
+
See Also
textRect()
+ +

Implements QwtPlotItem.

+ +
+
+ +
+
+ + + + + + + +
int QwtPlotTextLabel::margin () const
+
+
Returns
Margin added to the contentsMargins() of the canvas
+
See Also
setMargin()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
int QwtPlotTextLabel::rtti () const
+
+virtual
+
+
Returns
QwtPlotItem::Rtti_PlotTextLabel
+ +

Reimplemented from QwtPlotItem.

+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotTextLabel::setMargin (int margin)
+
+

Set the margin

+

The margin is the distance between the contentsRect() of the plot canvas and the rectangle where the label can be displayed.

+
Parameters
+ + +
marginMargin
+
+
+
See Also
margin(), textRect()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotTextLabel::setText (const QwtTexttext)
+
+

Set the text

+

The label will be aligned to the plot canvas according to the alignment flags of text.

+
Parameters
+ + +
textText to be displayed
+
+
+
See Also
text(), QwtText::renderFlags()
+ +
+
+ +
+
+ + + + + + + +
QwtText QwtPlotTextLabel::text () const
+
+
Returns
Text to be displayed
+
See Also
setText()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
QRectF QwtPlotTextLabel::textRect (const QRectF & rect,
const QSizeF & textSize 
) const
+
+virtual
+
+ +

Align the text label.

+
Parameters
+ + + +
rectCanvas rectangle with margins subtracted
textSizeSize required to draw the text
+
+
+
Returns
A rectangle aligned according the the alignment flags of the text.
+
See Also
setMargin(), QwtText::renderFlags(), QwtText::textSize()
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_text_label__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_plot_text_label__inherit__graph.map new file mode 100644 index 0000000000..1a5a836af5 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_text_label__inherit__graph.map @@ -0,0 +1,3 @@ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_text_label__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_plot_text_label__inherit__graph.md5 new file mode 100644 index 0000000000..d3e81bcf19 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_text_label__inherit__graph.md5 @@ -0,0 +1 @@ +b1f72f600aaada2508db1e5aefc4d54c \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_text_label__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_plot_text_label__inherit__graph.png new file mode 100644 index 0000000000..97510c5da7 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_plot_text_label__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_trading_curve-members.html b/ThirdParty/Qwt/doc/html/class_qwt_plot_trading_curve-members.html new file mode 100644 index 0000000000..6697f40807 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_trading_curve-members.html @@ -0,0 +1,231 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtPlotTradingCurve Member List
+
+
+ +

This is the complete list of members for QwtPlotTradingCurve, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
attach(QwtPlot *plot)QwtPlotItem
AutoScale enum valueQwtPlotItem
Bar enum valueQwtPlotTradingCurve
boundingRect() const QwtPlotTradingCurvevirtual
CandleStick enum valueQwtPlotTradingCurve
ClipSymbols enum valueQwtPlotTradingCurve
data()QwtSeriesStore< QwtOHLCSample >private
data() constQwtSeriesStore< QwtOHLCSample >private
dataChanged()QwtPlotSeriesItemprotectedvirtual
QwtPlotSeriesItem::dataRect() const =0QwtAbstractSeriesStoreprotectedpure virtual
QwtSeriesStore< QwtOHLCSample >::dataRect() constQwtSeriesStore< QwtOHLCSample >privatevirtual
QwtPlotSeriesItem::dataSize() const =0QwtAbstractSeriesStoreprotectedpure virtual
QwtSeriesStore< QwtOHLCSample >::dataSize() constQwtSeriesStore< QwtOHLCSample >privatevirtual
Decreasing enum valueQwtPlotTradingCurve
defaultIcon(const QBrush &, const QSizeF &) const QwtPlotItemprotected
detach()QwtPlotItem
Direction enum nameQwtPlotTradingCurve
draw(QPainter *p, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &) const QwtPlotSeriesItemvirtual
drawBar(QPainter *painter, const QwtOHLCSample &, Qt::Orientation, bool inverted, double width) const QwtPlotTradingCurveprotected
drawCandleStick(QPainter *, const QwtOHLCSample &, Qt::Orientation, double width) const QwtPlotTradingCurveprotected
drawSeries(QPainter *painter, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, int from, int to) const QwtPlotTradingCurvevirtual
drawSymbols(QPainter *, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, int from, int to) const QwtPlotTradingCurveprotectedvirtual
drawUserSymbol(QPainter *, SymbolStyle, const QwtOHLCSample &, Qt::Orientation, bool inverted, double width) const QwtPlotTradingCurveprotectedvirtual
getCanvasMarginHint(const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasSize, double &left, double &top, double &right, double &bottom) const QwtPlotItemvirtual
hide()QwtPlotItem
Increasing enum valueQwtPlotTradingCurve
init()QwtPlotTradingCurveprotected
isVisible() const QwtPlotItem
ItemAttribute enum nameQwtPlotItem
ItemAttributes typedefQwtPlotItem
itemChanged()QwtPlotItemvirtual
ItemInterest enum nameQwtPlotItem
ItemInterests typedefQwtPlotItem
Legend enum valueQwtPlotItem
legendChanged()QwtPlotItemvirtual
legendData() const QwtPlotItemvirtual
legendIcon(int index, const QSizeF &) const QwtPlotTradingCurvevirtual
legendIconSize() const QwtPlotItem
LegendInterest enum valueQwtPlotItem
Margins enum valueQwtPlotItem
maxSymbolWidth() const QwtPlotTradingCurve
minSymbolWidth() const QwtPlotTradingCurve
NoSymbol enum valueQwtPlotTradingCurve
orientation() const QwtPlotSeriesItem
PaintAttribute enum nameQwtPlotTradingCurve
PaintAttributes typedefQwtPlotTradingCurve
paintRect(const QwtScaleMap &, const QwtScaleMap &) const QwtPlotItem
plot() const QwtPlotItem
QwtPlotItem(const QwtText &title=QwtText())QwtPlotItemexplicit
QwtPlotSeriesItem(const QString &title=QString::null)QwtPlotSeriesItemexplicit
QwtPlotSeriesItem(const QwtText &title)QwtPlotSeriesItemexplicit
QwtPlotTradingCurve(const QString &title=QString::null)QwtPlotTradingCurveexplicit
QwtPlotTradingCurve(const QwtText &title)QwtPlotTradingCurveexplicit
QwtSeriesStore()QwtSeriesStore< QwtOHLCSample >explicitprivate
RenderAntialiased enum valueQwtPlotItem
RenderHint enum nameQwtPlotItem
RenderHints typedefQwtPlotItem
renderThreadCount() const QwtPlotItem
rtti() const QwtPlotTradingCurvevirtual
Rtti_PlotBarChart enum valueQwtPlotItem
Rtti_PlotCurve enum valueQwtPlotItem
Rtti_PlotGrid enum valueQwtPlotItem
Rtti_PlotHistogram enum valueQwtPlotItem
Rtti_PlotIntervalCurve enum valueQwtPlotItem
Rtti_PlotItem enum valueQwtPlotItem
Rtti_PlotLegend enum valueQwtPlotItem
Rtti_PlotMarker enum valueQwtPlotItem
Rtti_PlotMultiBarChart enum valueQwtPlotItem
Rtti_PlotScale enum valueQwtPlotItem
Rtti_PlotShape enum valueQwtPlotItem
Rtti_PlotSpectroCurve enum valueQwtPlotItem
Rtti_PlotSpectrogram enum valueQwtPlotItem
Rtti_PlotSVG enum valueQwtPlotItem
Rtti_PlotTextLabel enum valueQwtPlotItem
Rtti_PlotTradingCurve enum valueQwtPlotItem
Rtti_PlotUserItem enum valueQwtPlotItem
Rtti_PlotZone enum valueQwtPlotItem
RttiValues enum nameQwtPlotItem
sample(int index) constQwtSeriesStore< QwtOHLCSample >private
scaledSymbolWidth(const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect) const QwtPlotTradingCurveprotectedvirtual
ScaleInterest enum valueQwtPlotItem
scaleRect(const QwtScaleMap &, const QwtScaleMap &) const QwtPlotItem
setAxes(int xAxis, int yAxis)QwtPlotItem
setData(QwtSeriesData< QwtOHLCSample > *series)QwtSeriesStore< QwtOHLCSample >private
setItemAttribute(ItemAttribute, bool on=true)QwtPlotItem
setItemInterest(ItemInterest, bool on=true)QwtPlotItem
setLegendIconSize(const QSize &)QwtPlotItem
setMaxSymbolWidth(double)QwtPlotTradingCurve
setMinSymbolWidth(double)QwtPlotTradingCurve
setOrientation(Qt::Orientation)QwtPlotSeriesItem
setPaintAttribute(PaintAttribute, bool on=true)QwtPlotTradingCurve
QwtPlotSeriesItem::setRectOfInterest(const QRectF &)=0QwtAbstractSeriesStoreprotectedpure virtual
QwtSeriesStore< QwtOHLCSample >::setRectOfInterest(const QRectF &rect)QwtSeriesStore< QwtOHLCSample >privatevirtual
setRenderHint(RenderHint, bool on=true)QwtPlotItem
setRenderThreadCount(uint numThreads)QwtPlotItem
setSamples(const QVector< QwtOHLCSample > &)QwtPlotTradingCurve
setSamples(QwtSeriesData< QwtOHLCSample > *)QwtPlotTradingCurve
setSymbolBrush(Direction, const QBrush &)QwtPlotTradingCurve
setSymbolExtent(double width)QwtPlotTradingCurve
setSymbolPen(const QColor &, qreal width=0.0, Qt::PenStyle=Qt::SolidLine)QwtPlotTradingCurve
setSymbolPen(const QPen &)QwtPlotTradingCurve
setSymbolStyle(SymbolStyle style)QwtPlotTradingCurve
setTitle(const QString &title)QwtPlotItem
setTitle(const QwtText &title)QwtPlotItem
setVisible(bool)QwtPlotItemvirtual
setXAxis(int axis)QwtPlotItem
setYAxis(int axis)QwtPlotItem
setZ(double z)QwtPlotItem
show()QwtPlotItem
swapData(QwtSeriesData< QwtOHLCSample > *series)QwtSeriesStore< QwtOHLCSample >private
symbolBrush(Direction) const QwtPlotTradingCurve
symbolExtent() const QwtPlotTradingCurve
symbolPen() const QwtPlotTradingCurve
SymbolStyle enum nameQwtPlotTradingCurve
symbolStyle() const QwtPlotTradingCurve
testItemAttribute(ItemAttribute) const QwtPlotItem
testItemInterest(ItemInterest) const QwtPlotItem
testPaintAttribute(PaintAttribute) const QwtPlotTradingCurve
testRenderHint(RenderHint) const QwtPlotItem
title() const QwtPlotItem
updateLegend(const QwtPlotItem *, const QList< QwtLegendData > &)QwtPlotItemvirtual
updateScaleDiv(const QwtScaleDiv &, const QwtScaleDiv &)QwtPlotSeriesItemvirtual
UserSymbol enum valueQwtPlotTradingCurve
xAxis() const QwtPlotItem
yAxis() const QwtPlotItem
z() const QwtPlotItem
~QwtAbstractSeriesStore()QwtAbstractSeriesStoreinlineprotectedvirtual
~QwtPlotItem()QwtPlotItemvirtual
~QwtPlotSeriesItem()QwtPlotSeriesItemvirtual
~QwtPlotTradingCurve()QwtPlotTradingCurvevirtual
~QwtSeriesStore()QwtSeriesStore< QwtOHLCSample >private
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_trading_curve.html b/ThirdParty/Qwt/doc/html/class_qwt_plot_trading_curve.html new file mode 100644 index 0000000000..138d498231 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_trading_curve.html @@ -0,0 +1,1410 @@ + + + + + + +Qwt User's Guide: QwtPlotTradingCurve Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtPlotTradingCurve Class Reference
+
+
+ +

QwtPlotTradingCurve illustrates movements in the price of a financial instrument over time. + More...

+ +

#include <qwt_plot_tradingcurve.h>

+
+Inheritance diagram for QwtPlotTradingCurve:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + + + + + + +

+Public Types

enum  SymbolStyle { NoSymbol = -1, +Bar, +CandleStick, +UserSymbol = 100 + }
 Symbol styles. More...
 
enum  Direction { Increasing, +Decreasing + }
 Direction of a price movement. More...
 
enum  PaintAttribute { ClipSymbols = 0x01 + }
 
+typedef QFlags< PaintAttributePaintAttributes
 Paint attributes.
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 QwtPlotTradingCurve (const QString &title=QString::null)
 
 QwtPlotTradingCurve (const QwtText &title)
 
+virtual ~QwtPlotTradingCurve ()
 Destructor.
 
virtual int rtti () const
 
void setPaintAttribute (PaintAttribute, bool on=true)
 
bool testPaintAttribute (PaintAttribute) const
 
void setSamples (const QVector< QwtOHLCSample > &)
 
void setSamples (QwtSeriesData< QwtOHLCSample > *)
 
void setSymbolStyle (SymbolStyle style)
 
SymbolStyle symbolStyle () const
 
void setSymbolPen (const QColor &, qreal width=0.0, Qt::PenStyle=Qt::SolidLine)
 
void setSymbolPen (const QPen &)
 Set the symbol pen. More...
 
QPen symbolPen () const
 
void setSymbolBrush (Direction, const QBrush &)
 
QBrush symbolBrush (Direction) const
 
void setSymbolExtent (double width)
 Set the extent of the symbol. More...
 
double symbolExtent () const
 
void setMinSymbolWidth (double)
 
double minSymbolWidth () const
 
void setMaxSymbolWidth (double)
 
double maxSymbolWidth () const
 
virtual void drawSeries (QPainter *painter, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, int from, int to) const
 
virtual QRectF boundingRect () const
 
virtual QwtGraphic legendIcon (int index, const QSizeF &) const
 
- Public Member Functions inherited from QwtPlotSeriesItem
 QwtPlotSeriesItem (const QString &title=QString::null)
 
 QwtPlotSeriesItem (const QwtText &title)
 
+virtual ~QwtPlotSeriesItem ()
 Destructor.
 
void setOrientation (Qt::Orientation)
 
Qt::Orientation orientation () const
 
virtual void draw (QPainter *p, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &) const
 Draw the complete series. More...
 
virtual void updateScaleDiv (const QwtScaleDiv &, const QwtScaleDiv &)
 Update the item to changes of the axes scale division. More...
 
- Public Member Functions inherited from QwtPlotItem
 QwtPlotItem (const QwtText &title=QwtText())
 
+virtual ~QwtPlotItem ()
 Destroy the QwtPlotItem.
 
void attach (QwtPlot *plot)
 Attach the item to a plot. More...
 
void detach ()
 This method detaches a QwtPlotItem from any QwtPlot it has been associated with. More...
 
+QwtPlotplot () const
 Return attached plot.
 
void setTitle (const QString &title)
 
void setTitle (const QwtText &title)
 
const QwtTexttitle () const
 
void setItemAttribute (ItemAttribute, bool on=true)
 
bool testItemAttribute (ItemAttribute) const
 
void setItemInterest (ItemInterest, bool on=true)
 
bool testItemInterest (ItemInterest) const
 
void setRenderHint (RenderHint, bool on=true)
 
bool testRenderHint (RenderHint) const
 
void setRenderThreadCount (uint numThreads)
 
uint renderThreadCount () const
 
void setLegendIconSize (const QSize &)
 
QSize legendIconSize () const
 
double z () const
 
void setZ (double z)
 Set the z value. More...
 
+void show ()
 Show the item.
 
+void hide ()
 Hide the item.
 
virtual void setVisible (bool)
 
bool isVisible () const
 
void setAxes (int xAxis, int yAxis)
 
void setXAxis (int axis)
 
+int xAxis () const
 Return xAxis.
 
void setYAxis (int axis)
 
+int yAxis () const
 Return yAxis.
 
virtual void itemChanged ()
 
virtual void legendChanged ()
 
virtual void getCanvasMarginHint (const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasSize, double &left, double &top, double &right, double &bottom) const
 Calculate a hint for the canvas margin. More...
 
virtual void updateLegend (const QwtPlotItem *, const QList< QwtLegendData > &)
 Update the item to changes of the legend info. More...
 
QRectF scaleRect (const QwtScaleMap &, const QwtScaleMap &) const
 Calculate the bounding scale rectangle of 2 maps. More...
 
QRectF paintRect (const QwtScaleMap &, const QwtScaleMap &) const
 Calculate the bounding paint rectangle of 2 maps. More...
 
virtual QList< QwtLegendDatalegendData () const
 Return all information, that is needed to represent the item on the legend. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Protected Member Functions

+void init ()
 Initialize internal members.
 
virtual void drawSymbols (QPainter *, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, int from, int to) const
 
virtual void drawUserSymbol (QPainter *, SymbolStyle, const QwtOHLCSample &, Qt::Orientation, bool inverted, double width) const
 Draw a symbol for a symbol style >= UserSymbol. More...
 
void drawBar (QPainter *painter, const QwtOHLCSample &, Qt::Orientation, bool inverted, double width) const
 Draw a bar. More...
 
void drawCandleStick (QPainter *, const QwtOHLCSample &, Qt::Orientation, double width) const
 Draw a candle stick. More...
 
virtual double scaledSymbolWidth (const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect) const
 
- Protected Member Functions inherited from QwtPlotSeriesItem
+virtual void dataChanged ()
 dataChanged() indicates, that the series has been changed.
 
- Protected Member Functions inherited from QwtPlotItem
QwtGraphic defaultIcon (const QBrush &, const QSizeF &) const
 Return a default icon from a brush. More...
 
- Protected Member Functions inherited from QwtAbstractSeriesStore
+virtual ~QwtAbstractSeriesStore ()
 Destructor.
 
+ + + + + + + + + + + + + + + + + + + + + + + + +

+Additional Inherited Members

- Private Member Functions inherited from QwtSeriesStore< QwtOHLCSample >
QwtSeriesStore ()
 Constructor The store contains no series.
 
~QwtSeriesStore ()
 Destructor.
 
void setData (QwtSeriesData< QwtOHLCSample > *series)
 
QwtSeriesData< QwtOHLCSample > * data ()
 
const QwtSeriesData
+< QwtOHLCSample > * 
data () const
 
QwtOHLCSample sample (int index) const
 
virtual size_t dataSize () const
 
virtual QRectF dataRect () const
 
virtual void setRectOfInterest (const QRectF &rect)
 
QwtSeriesData< QwtOHLCSample > * swapData (QwtSeriesData< QwtOHLCSample > *series)
 
+

Detailed Description

+

QwtPlotTradingCurve illustrates movements in the price of a financial instrument over time.

+

QwtPlotTradingCurve supports candlestick or bar ( OHLC ) charts that are used in the domain of technical analysis.

+

While the length ( height or width depending on orientation() ) of each symbol depends on the corresponding OHLC sample the size of the other dimension can be controlled using:

+ +

The extent is a size in scale coordinates, so that the symbol width is increasing when the plot is zoomed in. Minimum/Maximum width is in widget coordinates independent from the zoom level. When setting the minimum and maximum to the same value, the width of the symbol is fixed.

+

Member Enumeration Documentation

+ +
+
+ +

Direction of a price movement.

+ + + +
Enumerator
Increasing  +

The closing price is higher than the opening price.

+
Decreasing  +

The closing price is lower than the opening price.

+
+ +
+
+ +
+
+

Attributes to modify the drawing algorithm.

+
See Also
setPaintAttribute(), testPaintAttribute()
+ + +
Enumerator
ClipSymbols  +

Check if a symbol is on the plot canvas before painting it.

+
+ +
+
+ +
+
+ +

Symbol styles.

+

The default setting is QwtPlotSeriesItem::CandleStick.

+
See Also
setSymbolStyle(), symbolStyle()
+ + + + + +
Enumerator
NoSymbol  +

Nothing is displayed.

+
Bar  +

A line on the chart shows the price range (the highest and lowest prices) over one unit of time, e.g. one day or one hour. Tick marks project from each side of the line indicating the opening and closing price.

+
CandleStick  +

The range between opening/closing price are displayed as a filled box. The fill brush depends on the direction of the price movement. The box is connected to the highest/lowest values by lines.

+
UserSymbol  +

SymbolTypes >= UserSymbol are displayed by drawUserSymbol(), that needs to be overloaded and implemented in derived curve classes.

+
See Also
drawUserSymbol()
+
+ +
+
+

Constructor & Destructor Documentation

+ +
+
+ + + + + +
+ + + + + + + + +
QwtPlotTradingCurve::QwtPlotTradingCurve (const QString & title = QString::null)
+
+explicit
+
+

Constructor

+
Parameters
+ + +
titleTitle of the curve
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
QwtPlotTradingCurve::QwtPlotTradingCurve (const QwtTexttitle)
+
+explicit
+
+

Constructor

+
Parameters
+ + +
titleTitle of the curve
+
+
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + +
QRectF QwtPlotTradingCurve::boundingRect () const
+
+virtual
+
+
Returns
Bounding rectangle of all samples. For an empty series the rectangle is invalid.
+ +

Reimplemented from QwtPlotSeriesItem.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPlotTradingCurve::drawBar (QPainter * painter,
const QwtOHLCSamplesample,
Qt::Orientation orientation,
bool inverted,
double width 
) const
+
+protected
+
+ +

Draw a bar.

+
Parameters
+ + + + + + +
painterQt painter, initialized with pen/brush
sampleSample, already translated into paint device coordinates
orientationVertical or horizontal
invertedWhen inverted is false the open tick is painted to the left/top, otherwise it is painted right/bottom. The close tick is painted in the opposite direction of the open tick. painted in the opposite d opposite direction.
widthWidth or height of the candle, depending on the orientation
+
+
+
See Also
Bar
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPlotTradingCurve::drawCandleStick (QPainter * painter,
const QwtOHLCSamplesample,
Qt::Orientation orientation,
double width 
) const
+
+protected
+
+ +

Draw a candle stick.

+
Parameters
+ + + + + +
painterQt painter, initialized with pen/brush
sampleSamples already translated into paint device coordinates
orientationVertical or horizontal
widthWidth or height of the candle, depending on the orientation
+
+
+
See Also
CandleStick
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPlotTradingCurve::drawSeries (QPainter * painter,
const QwtScaleMapxMap,
const QwtScaleMapyMap,
const QRectF & canvasRect,
int from,
int to 
) const
+
+virtual
+
+

Draw an interval of the curve

+
Parameters
+ + + + + + + +
painterPainter
xMapMaps x-values into pixel coordinates.
yMapMaps y-values into pixel coordinates.
canvasRectContents rectangle of the canvas
fromIndex of the first point to be painted
toIndex of the last point to be painted. If to < 0 the curve will be painted to its last point.
+
+
+
See Also
drawSymbols()
+ +

Implements QwtPlotSeriesItem.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPlotTradingCurve::drawSymbols (QPainter * painter,
const QwtScaleMapxMap,
const QwtScaleMapyMap,
const QRectF & canvasRect,
int from,
int to 
) const
+
+protectedvirtual
+
+

Draw symbols

+
Parameters
+ + + + + + + +
painterPainter
xMapx map
yMapy map
canvasRectContents rectangle of the canvas
fromIndex of the first point to be painted
toIndex of the last point to be painted
+
+
+
See Also
drawSeries()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPlotTradingCurve::drawUserSymbol (QPainter * painter,
SymbolStyle symbolStyle,
const QwtOHLCSamplesample,
Qt::Orientation orientation,
bool inverted,
double symbolWidth 
) const
+
+protectedvirtual
+
+ +

Draw a symbol for a symbol style >= UserSymbol.

+

The implementation does nothing and is intended to be overloaded

+
Parameters
+ + + + + + + +
painterQt painter, initialized with pen/brush
symbolStyleSymbol style
sampleSamples already translated into paint device coordinates
orientationVertical or horizontal
invertedTrue, when the opposite scale ( Qt::Vertical: x, Qt::Horizontal: y ) is increasing in the opposite direction as QPainter coordinates.
symbolWidthWidth of the symbol in paint device coordinates
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
QwtGraphic QwtPlotTradingCurve::legendIcon (int index,
const QSizeF & size 
) const
+
+virtual
+
+
Returns
A rectangle filled with the color of the symbol pen
+
Parameters
+ + + +
indexIndex of the legend entry ( usually there is only one )
sizeIcon size
+
+
+
See Also
setLegendIconSize(), legendData()
+ +

Reimplemented from QwtPlotItem.

+ +
+
+ +
+
+ + + + + + + +
double QwtPlotTradingCurve::maxSymbolWidth () const
+
+
Returns
Maximum for the symbol width
+
See Also
setMaxSymbolWidth(), minSymbolWidth(), symbolExtent()
+ +
+
+ +
+
+ + + + + + + +
double QwtPlotTradingCurve::minSymbolWidth () const
+
+
Returns
Minmum for the symbol width
+
See Also
setMinSymbolWidth(), maxSymbolWidth(), symbolExtent()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
int QwtPlotTradingCurve::rtti () const
+
+virtual
+
+
Returns
QwtPlotItem::Rtti_PlotTradingCurve
+ +

Reimplemented from QwtPlotItem.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
double QwtPlotTradingCurve::scaledSymbolWidth (const QwtScaleMapxMap,
const QwtScaleMapyMap,
const QRectF & canvasRect 
) const
+
+protectedvirtual
+
+

Calculate the symbol width in paint coordinates

+

The width is calculated by scaling the symbol extent into paint device coordinates bounded by the minimum/maximum symbol width.

+
Parameters
+ + + + +
xMapMaps x-values into pixel coordinates.
yMapMaps y-values into pixel coordinates.
canvasRectContents rectangle of the canvas
+
+
+
Returns
Symbol width in paint coordinates
+
See Also
symbolExtent(), minSymbolWidth(), maxSymbolWidth()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotTradingCurve::setMaxSymbolWidth (double width)
+
+

Set a maximum for the symbol width

+

A value <= 0.0 means an unlimited width

+
Parameters
+ + +
widthWidth in paint device coordinates
+
+
+
See Also
maxSymbolWidth(), setMinSymbolWidth(), setSymbolExtent()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotTradingCurve::setMinSymbolWidth (double width)
+
+

Set a minimum for the symbol width

+
Parameters
+ + +
widthWidth in paint device coordinates
+
+
+
See Also
minSymbolWidth(), setMaxSymbolWidth(), setSymbolExtent()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtPlotTradingCurve::setPaintAttribute (PaintAttribute attribute,
bool on = true 
)
+
+

Specify an attribute how to draw the curve

+
Parameters
+ + + +
attributePaint attribute
onOn/Off
+
+
+
See Also
testPaintAttribute()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotTradingCurve::setSamples (const QVector< QwtOHLCSample > & samples)
+
+

Initialize data with an array of samples.

+
Parameters
+ + +
samplesVector of samples
+
+
+
See Also
QwtPlotSeriesItem::setData()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotTradingCurve::setSamples (QwtSeriesData< QwtOHLCSample > * data)
+
+

Assign a series of samples

+

setSamples() is just a wrapper for setData() without any additional value - beside that it is easier to find for the developer.

+
Parameters
+ + +
dataData
+
+
+
Warning
The item takes ownership of the data object, deleting it when its not used anymore.
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtPlotTradingCurve::setSymbolBrush (Direction direction,
const QBrush & brush 
)
+
+

Set the symbol brush

+
Parameters
+ + + +
directionDirection type
brushBrush used to fill the body of all candlestick symbols with the direction
+
+
+
See Also
symbolBrush(), setSymbolPen()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotTradingCurve::setSymbolExtent (double extent)
+
+ +

Set the extent of the symbol.

+

The width of the symbol is given in scale coordinates. When painting a symbol the width is scaled into paint device coordinates by scaledSymbolWidth(). The scaled width is bounded by minSymbolWidth(), maxSymbolWidth()

+
Parameters
+ + +
extentSymbol width in scale coordinates
+
+
+
See Also
symbolExtent(), scaledSymbolWidth(), setMinSymbolWidth(), setMaxSymbolWidth()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPlotTradingCurve::setSymbolPen (const QColor & color,
qreal width = 0.0,
Qt::PenStyle style = Qt::SolidLine 
)
+
+

Build and assign the symbol pen

+

In Qt5 the default pen width is 1.0 ( 0.0 in Qt4 ) what makes it non cosmetic ( see QPen::isCosmetic() ). This method has been introduced to hide this incompatibility.

+
Parameters
+ + + + +
colorPen color
widthPen width
stylePen style
+
+
+
See Also
pen(), brush()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotTradingCurve::setSymbolPen (const QPen & pen)
+
+ +

Set the symbol pen.

+

The symbol pen is used for rendering the lines of the bar or candlestick symbols

+
See Also
symbolPen(), setSymbolBrush()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotTradingCurve::setSymbolStyle (SymbolStyle style)
+
+

Set the symbol style

+
Parameters
+ + +
styleSymbol style
+
+
+
See Also
symbolStyle(), setSymbolExtent(), setSymbolPen(), setSymbolBrush()
+ +
+
+ +
+
+ + + + + + + + +
QBrush QwtPlotTradingCurve::symbolBrush (Direction direction) const
+
+
Parameters
+ + +
direction
+
+
+
Returns
Brush used to fill the body of all candlestick symbols with the direction
+
See Also
setSymbolPen(), symbolBrush()
+ +
+
+ +
+
+ + + + + + + +
double QwtPlotTradingCurve::symbolExtent () const
+
+
Returns
Extent of a symbol in scale coordinates
+
See Also
setSymbolExtent(), scaledSymbolWidth(), minSymbolWidth(), maxSymbolWidth()
+ +
+
+ +
+
+ + + + + + + +
QPen QwtPlotTradingCurve::symbolPen () const
+
+
Returns
Symbol pen
+
See Also
setSymbolPen(), symbolBrush()
+ +
+
+ +
+
+ + + + + + + +
QwtPlotTradingCurve::SymbolStyle QwtPlotTradingCurve::symbolStyle () const
+
+
Returns
Symbol style
+
See Also
setSymbolStyle(), symbolExtent(), symbolPen(), symbolBrush()
+ +
+
+ +
+
+ + + + + + + + +
bool QwtPlotTradingCurve::testPaintAttribute (PaintAttribute attribute) const
+
+
Returns
True, when attribute is enabled
+
See Also
PaintAttribute, setPaintAttribute()
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_trading_curve__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_plot_trading_curve__inherit__graph.map new file mode 100644 index 0000000000..bd88ae438c --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_trading_curve__inherit__graph.map @@ -0,0 +1,6 @@ + + + + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_trading_curve__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_plot_trading_curve__inherit__graph.md5 new file mode 100644 index 0000000000..f44c80a38b --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_trading_curve__inherit__graph.md5 @@ -0,0 +1 @@ +9d8911679bbec31b5e8c2b2e9c7c966a \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_trading_curve__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_plot_trading_curve__inherit__graph.png new file mode 100644 index 0000000000..60d9ad3146 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_plot_trading_curve__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_zone_item-members.html b/ThirdParty/Qwt/doc/html/class_qwt_plot_zone_item-members.html new file mode 100644 index 0000000000..f111146555 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_zone_item-members.html @@ -0,0 +1,185 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtPlotZoneItem Member List
+
+
+ +

This is the complete list of members for QwtPlotZoneItem, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
attach(QwtPlot *plot)QwtPlotItem
AutoScale enum valueQwtPlotItem
boundingRect() const QwtPlotZoneItemvirtual
brush() const QwtPlotZoneItem
defaultIcon(const QBrush &, const QSizeF &) const QwtPlotItemprotected
detach()QwtPlotItem
draw(QPainter *, const QwtScaleMap &, const QwtScaleMap &, const QRectF &) const QwtPlotZoneItemvirtual
getCanvasMarginHint(const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasSize, double &left, double &top, double &right, double &bottom) const QwtPlotItemvirtual
hide()QwtPlotItem
interval() const QwtPlotZoneItem
isVisible() const QwtPlotItem
ItemAttribute enum nameQwtPlotItem
ItemAttributes typedefQwtPlotItem
itemChanged()QwtPlotItemvirtual
ItemInterest enum nameQwtPlotItem
ItemInterests typedefQwtPlotItem
Legend enum valueQwtPlotItem
legendChanged()QwtPlotItemvirtual
legendData() const QwtPlotItemvirtual
legendIcon(int index, const QSizeF &) const QwtPlotItemvirtual
legendIconSize() const QwtPlotItem
LegendInterest enum valueQwtPlotItem
Margins enum valueQwtPlotItem
orientation()QwtPlotZoneItem
paintRect(const QwtScaleMap &, const QwtScaleMap &) const QwtPlotItem
pen() const QwtPlotZoneItem
plot() const QwtPlotItem
QwtPlotItem(const QwtText &title=QwtText())QwtPlotItemexplicit
QwtPlotZoneItem()QwtPlotZoneItemexplicit
RenderAntialiased enum valueQwtPlotItem
RenderHint enum nameQwtPlotItem
RenderHints typedefQwtPlotItem
renderThreadCount() const QwtPlotItem
rtti() const QwtPlotZoneItemvirtual
Rtti_PlotBarChart enum valueQwtPlotItem
Rtti_PlotCurve enum valueQwtPlotItem
Rtti_PlotGrid enum valueQwtPlotItem
Rtti_PlotHistogram enum valueQwtPlotItem
Rtti_PlotIntervalCurve enum valueQwtPlotItem
Rtti_PlotItem enum valueQwtPlotItem
Rtti_PlotLegend enum valueQwtPlotItem
Rtti_PlotMarker enum valueQwtPlotItem
Rtti_PlotMultiBarChart enum valueQwtPlotItem
Rtti_PlotScale enum valueQwtPlotItem
Rtti_PlotShape enum valueQwtPlotItem
Rtti_PlotSpectroCurve enum valueQwtPlotItem
Rtti_PlotSpectrogram enum valueQwtPlotItem
Rtti_PlotSVG enum valueQwtPlotItem
Rtti_PlotTextLabel enum valueQwtPlotItem
Rtti_PlotTradingCurve enum valueQwtPlotItem
Rtti_PlotUserItem enum valueQwtPlotItem
Rtti_PlotZone enum valueQwtPlotItem
RttiValues enum nameQwtPlotItem
ScaleInterest enum valueQwtPlotItem
scaleRect(const QwtScaleMap &, const QwtScaleMap &) const QwtPlotItem
setAxes(int xAxis, int yAxis)QwtPlotItem
setBrush(const QBrush &)QwtPlotZoneItem
setInterval(double min, double max)QwtPlotZoneItem
setInterval(const QwtInterval &)QwtPlotZoneItem
setItemAttribute(ItemAttribute, bool on=true)QwtPlotItem
setItemInterest(ItemInterest, bool on=true)QwtPlotItem
setLegendIconSize(const QSize &)QwtPlotItem
setOrientation(Qt::Orientation)QwtPlotZoneItem
setPen(const QColor &, qreal width=0.0, Qt::PenStyle=Qt::SolidLine)QwtPlotZoneItem
setPen(const QPen &)QwtPlotZoneItem
setRenderHint(RenderHint, bool on=true)QwtPlotItem
setRenderThreadCount(uint numThreads)QwtPlotItem
setTitle(const QString &title)QwtPlotItem
setTitle(const QwtText &title)QwtPlotItem
setVisible(bool)QwtPlotItemvirtual
setXAxis(int axis)QwtPlotItem
setYAxis(int axis)QwtPlotItem
setZ(double z)QwtPlotItem
show()QwtPlotItem
testItemAttribute(ItemAttribute) const QwtPlotItem
testItemInterest(ItemInterest) const QwtPlotItem
testRenderHint(RenderHint) const QwtPlotItem
title() const QwtPlotItem
updateLegend(const QwtPlotItem *, const QList< QwtLegendData > &)QwtPlotItemvirtual
updateScaleDiv(const QwtScaleDiv &, const QwtScaleDiv &)QwtPlotItemvirtual
xAxis() const QwtPlotItem
yAxis() const QwtPlotItem
z() const QwtPlotItem
~QwtPlotItem()QwtPlotItemvirtual
~QwtPlotZoneItem()QwtPlotZoneItemvirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_zone_item.html b/ThirdParty/Qwt/doc/html/class_qwt_plot_zone_item.html new file mode 100644 index 0000000000..e732ae67fe --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_zone_item.html @@ -0,0 +1,706 @@ + + + + + + +Qwt User's Guide: QwtPlotZoneItem Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtPlotZoneItem Class Reference
+
+
+ +

A plot item, which displays a zone. + More...

+ +

#include <qwt_plot_zoneitem.h>

+
+Inheritance diagram for QwtPlotZoneItem:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 QwtPlotZoneItem ()
 Constructor. More...
 
+virtual ~QwtPlotZoneItem ()
 Destructor.
 
virtual int rtti () const
 
void setOrientation (Qt::Orientation)
 Set the orientation of the zone. More...
 
Qt::Orientation orientation ()
 
void setInterval (double min, double max)
 
void setInterval (const QwtInterval &)
 
QwtInterval interval () const
 
void setPen (const QColor &, qreal width=0.0, Qt::PenStyle=Qt::SolidLine)
 
void setPen (const QPen &)
 Assign a pen. More...
 
const QPen & pen () const
 
void setBrush (const QBrush &)
 Assign a brush. More...
 
const QBrush & brush () const
 
virtual void draw (QPainter *, const QwtScaleMap &, const QwtScaleMap &, const QRectF &) const
 
virtual QRectF boundingRect () const
 
- Public Member Functions inherited from QwtPlotItem
 QwtPlotItem (const QwtText &title=QwtText())
 
+virtual ~QwtPlotItem ()
 Destroy the QwtPlotItem.
 
void attach (QwtPlot *plot)
 Attach the item to a plot. More...
 
void detach ()
 This method detaches a QwtPlotItem from any QwtPlot it has been associated with. More...
 
+QwtPlotplot () const
 Return attached plot.
 
void setTitle (const QString &title)
 
void setTitle (const QwtText &title)
 
const QwtTexttitle () const
 
void setItemAttribute (ItemAttribute, bool on=true)
 
bool testItemAttribute (ItemAttribute) const
 
void setItemInterest (ItemInterest, bool on=true)
 
bool testItemInterest (ItemInterest) const
 
void setRenderHint (RenderHint, bool on=true)
 
bool testRenderHint (RenderHint) const
 
void setRenderThreadCount (uint numThreads)
 
uint renderThreadCount () const
 
void setLegendIconSize (const QSize &)
 
QSize legendIconSize () const
 
double z () const
 
void setZ (double z)
 Set the z value. More...
 
+void show ()
 Show the item.
 
+void hide ()
 Hide the item.
 
virtual void setVisible (bool)
 
bool isVisible () const
 
void setAxes (int xAxis, int yAxis)
 
void setXAxis (int axis)
 
+int xAxis () const
 Return xAxis.
 
void setYAxis (int axis)
 
+int yAxis () const
 Return yAxis.
 
virtual void itemChanged ()
 
virtual void legendChanged ()
 
virtual void getCanvasMarginHint (const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasSize, double &left, double &top, double &right, double &bottom) const
 Calculate a hint for the canvas margin. More...
 
virtual void updateScaleDiv (const QwtScaleDiv &, const QwtScaleDiv &)
 Update the item to changes of the axes scale division. More...
 
virtual void updateLegend (const QwtPlotItem *, const QList< QwtLegendData > &)
 Update the item to changes of the legend info. More...
 
QRectF scaleRect (const QwtScaleMap &, const QwtScaleMap &) const
 Calculate the bounding scale rectangle of 2 maps. More...
 
QRectF paintRect (const QwtScaleMap &, const QwtScaleMap &) const
 Calculate the bounding paint rectangle of 2 maps. More...
 
virtual QList< QwtLegendDatalegendData () const
 Return all information, that is needed to represent the item on the legend. More...
 
virtual QwtGraphic legendIcon (int index, const QSizeF &) const
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Additional Inherited Members

- Public Types inherited from QwtPlotItem
enum  RttiValues {
+  Rtti_PlotItem = 0, +Rtti_PlotGrid, +Rtti_PlotScale, +Rtti_PlotLegend, +
+  Rtti_PlotMarker, +Rtti_PlotCurve, +Rtti_PlotSpectroCurve, +Rtti_PlotIntervalCurve, +
+  Rtti_PlotHistogram, +Rtti_PlotSpectrogram, +Rtti_PlotSVG, +Rtti_PlotTradingCurve, +
+  Rtti_PlotBarChart, +Rtti_PlotMultiBarChart, +Rtti_PlotShape, +Rtti_PlotTextLabel, +
+  Rtti_PlotZone, +Rtti_PlotUserItem = 1000 +
+ }
 Runtime type information. More...
 
enum  ItemAttribute { Legend = 0x01, +AutoScale = 0x02, +Margins = 0x04 + }
 Plot Item Attributes. More...
 
enum  ItemInterest { ScaleInterest = 0x01, +LegendInterest = 0x02 + }
 Plot Item Interests. More...
 
enum  RenderHint { RenderAntialiased = 0x1 + }
 Render hints. More...
 
+typedef QFlags< ItemAttributeItemAttributes
 Plot Item Attributes.
 
+typedef QFlags< ItemInterestItemInterests
 Plot Item Interests.
 
+typedef QFlags< RenderHintRenderHints
 Render hints.
 
- Protected Member Functions inherited from QwtPlotItem
QwtGraphic defaultIcon (const QBrush &, const QSizeF &) const
 Return a default icon from a brush. More...
 
+

Detailed Description

+

A plot item, which displays a zone.

+

A horizontal zone highlights an interval of the y axis - a vertical zone an interval of the x axis - and is unbounded in the opposite direction. It is filled with a brush and its border lines are optionally displayed with a pen.

+
Note
For displaying an area that is bounded for x and y coordinates use QwtPlotShapeItem
+

Constructor & Destructor Documentation

+ +
+
+ + + + + +
+ + + + + + + +
QwtPlotZoneItem::QwtPlotZoneItem ()
+
+explicit
+
+ +

Constructor.

+

Initializes the zone with no pen and a semi transparent gray brush

+

Sets the following item attributes:

+ +

The z value is initialized by 5

+
See Also
QwtPlotItem::setItemAttribute(), QwtPlotItem::setZ()
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + +
QRectF QwtPlotZoneItem::boundingRect () const
+
+virtual
+
+

The bounding rectangle is build from the interval in one direction and something invalid for the opposite direction.

+
Returns
An invalid rectangle with valid boundaries in one direction
+ +

Reimplemented from QwtPlotItem.

+ +
+
+ +
+
+ + + + + + + +
const QBrush & QwtPlotZoneItem::brush () const
+
+
Returns
Brush used to fill the zone
+
See Also
setPen(), brush()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPlotZoneItem::draw (QPainter * painter,
const QwtScaleMapxMap,
const QwtScaleMapyMap,
const QRectF & canvasRect 
) const
+
+virtual
+
+

Draw the zone

+
Parameters
+ + + + + +
painterPainter
xMapx Scale Map
yMapy Scale Map
canvasRectContents rectangle of the canvas in painter coordinates
+
+
+ +

Implements QwtPlotItem.

+ +
+
+ +
+
+ + + + + + + +
QwtInterval QwtPlotZoneItem::interval () const
+
+
Returns
Zone interval
+
See Also
setInterval(), orientation()
+ +
+
+ +
+
+ + + + + + + +
Qt::Orientation QwtPlotZoneItem::orientation ()
+
+
Returns
Orientation of the zone
+
See Also
setOrientation()
+ +
+
+ +
+
+ + + + + + + +
const QPen & QwtPlotZoneItem::pen () const
+
+
Returns
Pen used to draw the border lines
+
See Also
setPen(), brush()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
int QwtPlotZoneItem::rtti () const
+
+virtual
+
+
Returns
QwtPlotItem::Rtti_PlotZone
+ +

Reimplemented from QwtPlotItem.

+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotZoneItem::setBrush (const QBrush & brush)
+
+ +

Assign a brush.

+

The brush is used to fill the zone

+
Parameters
+ + +
brushBrush
+
+
+
See Also
pen(), setBrush()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtPlotZoneItem::setInterval (double min,
double max 
)
+
+

Set the interval of the zone

+

For a horizontal zone the interval is related to the y axis, for a vertical zone it is related to the x axis.

+
Parameters
+ + + +
minMinimum of the interval
maxMaximum of the interval
+
+
+
See Also
interval(), setOrientation()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotZoneItem::setInterval (const QwtIntervalinterval)
+
+

Set the interval of the zone

+

For a horizontal zone the interval is related to the y axis, for a vertical zone it is related to the x axis.

+
Parameters
+ + +
intervalZone interval
+
+
+
See Also
interval(), setOrientation()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotZoneItem::setOrientation (Qt::Orientation orientation)
+
+ +

Set the orientation of the zone.

+

A horizontal zone highlights an interval of the y axis, a vertical zone of the x axis. It is unbounded in the opposite direction.

+
See Also
orientation(), QwtPlotItem::setAxes()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void QwtPlotZoneItem::setPen (const QColor & color,
qreal width = 0.0,
Qt::PenStyle style = Qt::SolidLine 
)
+
+

Build and assign a pen

+

In Qt5 the default pen width is 1.0 ( 0.0 in Qt4 ) what makes it non cosmetic ( see QPen::isCosmetic() ). This method has been introduced to hide this incompatibility.

+
Parameters
+ + + + +
colorPen color
widthPen width
stylePen style
+
+
+
See Also
pen(), brush()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotZoneItem::setPen (const QPen & pen)
+
+ +

Assign a pen.

+

The pen is used to draw the border lines of the zone

+
Parameters
+ + +
penPen
+
+
+
See Also
pen(), setBrush()
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_zone_item__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_plot_zone_item__inherit__graph.map new file mode 100644 index 0000000000..ab715c3038 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_zone_item__inherit__graph.map @@ -0,0 +1,3 @@ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_zone_item__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_plot_zone_item__inherit__graph.md5 new file mode 100644 index 0000000000..aa1597e407 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_zone_item__inherit__graph.md5 @@ -0,0 +1 @@ +afe6bb9ca865ef9ebae71d08162c68df \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_zone_item__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_plot_zone_item__inherit__graph.png new file mode 100644 index 0000000000..46f137991b Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_plot_zone_item__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_zoomer-members.html b/ThirdParty/Qwt/doc/html/class_qwt_plot_zoomer-members.html new file mode 100644 index 0000000000..83fd2cd8e7 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_zoomer-members.html @@ -0,0 +1,254 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtPlotZoomer Member List
+
+
+ +

This is the complete list of members for QwtPlotZoomer, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
accept(QPolygon &) const QwtPlotZoomerprotectedvirtual
activated(bool on)QwtPickersignal
ActiveOnly enum valueQwtPicker
adjustedPoints(const QPolygon &) const QwtPickerprotectedvirtual
AlwaysOff enum valueQwtPicker
AlwaysOn enum valueQwtPicker
append(const QPoint &)QwtPlotPickerprotectedvirtual
appended(const QPointF &pos)QwtPlotPickersignal
QwtPicker::appended(const QPoint &pos)QwtPickersignal
begin()QwtPlotZoomerprotectedvirtual
canvas()QwtPlotPicker
canvas() const QwtPlotPicker
changed(const QPolygon &selection)QwtPickersignal
CrossRubberBand enum valueQwtPicker
DisplayMode enum nameQwtPicker
drawRubberBand(QPainter *) const QwtPickervirtual
drawTracker(QPainter *) const QwtPickervirtual
EllipseRubberBand enum valueQwtPicker
end(bool ok=true)QwtPlotZoomerprotectedvirtual
eventFilter(QObject *, QEvent *)QwtPickervirtual
HLineRubberBand enum valueQwtPicker
initKeyPattern()QwtEventPattern
initMousePattern(int numButtons)QwtEventPattern
invTransform(const QRect &) const QwtPlotPickerprotected
invTransform(const QPoint &) const QwtPlotPickerprotected
isActive() const QwtPicker
isEnabled() const QwtPicker
KeepSize enum valueQwtPicker
KeyAbort enum valueQwtEventPattern
KeyDown enum valueQwtEventPattern
KeyHome enum valueQwtEventPattern
KeyLeft enum valueQwtEventPattern
keyMatch(KeyPatternCode, const QKeyEvent *) const QwtEventPattern
keyMatch(const KeyPattern &, const QKeyEvent *) const QwtEventPatternprotectedvirtual
keyPattern() const QwtEventPattern
keyPattern()QwtEventPattern
KeyPatternCode enum nameQwtEventPattern
KeyPatternCount enum valueQwtEventPattern
KeyRedo enum valueQwtEventPattern
KeyRight enum valueQwtEventPattern
KeySelect1 enum valueQwtEventPattern
KeySelect2 enum valueQwtEventPattern
KeyUndo enum valueQwtEventPattern
KeyUp enum valueQwtEventPattern
maxStackDepth() const QwtPlotZoomer
minZoomSize() const QwtPlotZoomerprotectedvirtual
mouseMatch(MousePatternCode, const QMouseEvent *) const QwtEventPattern
mouseMatch(const MousePattern &, const QMouseEvent *) const QwtEventPatternprotectedvirtual
mousePattern() const QwtEventPattern
mousePattern()QwtEventPattern
MousePatternCode enum nameQwtEventPattern
MousePatternCount enum valueQwtEventPattern
MouseSelect1 enum valueQwtEventPattern
MouseSelect2 enum valueQwtEventPattern
MouseSelect3 enum valueQwtEventPattern
MouseSelect4 enum valueQwtEventPattern
MouseSelect5 enum valueQwtEventPattern
MouseSelect6 enum valueQwtEventPattern
move(const QPoint &)QwtPlotPickerprotectedvirtual
moveBy(double x, double y)QwtPlotZoomerslot
moved(const QPointF &pos)QwtPlotPickersignal
QwtPicker::moved(const QPoint &pos)QwtPickersignal
moveTo(const QPointF &)QwtPlotZoomervirtualslot
NoRubberBand enum valueQwtPicker
parentWidget()QwtPicker
parentWidget() const QwtPicker
pickArea() const QwtPickervirtual
pickedPoints() const QwtPickerprotected
plot()QwtPlotPicker
plot() const QwtPlotPicker
PolygonRubberBand enum valueQwtPicker
QwtEventPattern()QwtEventPattern
QwtPicker(QWidget *parent)QwtPickerexplicit
QwtPicker(RubberBand rubberBand, DisplayMode trackerMode, QWidget *)QwtPickerexplicit
QwtPlotPicker(QWidget *canvas)QwtPlotPickerexplicit
QwtPlotPicker(int xAxis, int yAxis, QWidget *)QwtPlotPickerexplicit
QwtPlotPicker(int xAxis, int yAxis, RubberBand rubberBand, DisplayMode trackerMode, QWidget *)QwtPlotPickerexplicit
QwtPlotZoomer(QWidget *, bool doReplot=true)QwtPlotZoomerexplicit
QwtPlotZoomer(int xAxis, int yAxis, QWidget *, bool doReplot=true)QwtPlotZoomerexplicit
RectRubberBand enum valueQwtPicker
remove()QwtPickerprotectedvirtual
removed(const QPoint &pos)QwtPickersignal
rescale()QwtPlotZoomerprotectedvirtual
reset()QwtPickerprotectedvirtual
ResizeMode enum nameQwtPicker
resizeMode() const QwtPicker
RubberBand enum nameQwtPicker
rubberBand() const QwtPicker
rubberBandMask() const QwtPickervirtual
rubberBandOverlay() const QwtPickerprotected
rubberBandPen() const QwtPicker
scaleRect() const QwtPlotPickerprotected
selected(const QPointF &pos)QwtPlotPickersignal
selected(const QRectF &rect)QwtPlotPickersignal
selected(const QVector< QPointF > &pa)QwtPlotPickersignal
QwtPicker::selected(const QPolygon &polygon)QwtPickersignal
selection() const QwtPicker
setAxis(int xAxis, int yAxis)QwtPlotZoomervirtual
setEnabled(bool)QwtPickerslot
setKeyPattern(KeyPatternCode, int keyCode, Qt::KeyboardModifiers modifierCodes=Qt::NoModifier)QwtEventPattern
setKeyPattern(const QVector< KeyPattern > &)QwtEventPattern
setMaxStackDepth(int)QwtPlotZoomer
setMousePattern(MousePatternCode, Qt::MouseButton button, Qt::KeyboardModifiers=Qt::NoModifier)QwtEventPattern
setMousePattern(const QVector< MousePattern > &)QwtEventPattern
setResizeMode(ResizeMode)QwtPicker
setRubberBand(RubberBand)QwtPicker
setRubberBandPen(const QPen &)QwtPicker
setStateMachine(QwtPickerMachine *)QwtPicker
setTrackerFont(const QFont &)QwtPicker
setTrackerMode(DisplayMode)QwtPicker
setTrackerPen(const QPen &)QwtPicker
setZoomBase(bool doReplot=true)QwtPlotZoomervirtual
setZoomBase(const QRectF &)QwtPlotZoomervirtual
setZoomStack(const QStack< QRectF > &, int zoomRectIndex=-1)QwtPlotZoomer
stateMachine() const QwtPicker
stateMachine()QwtPicker
Stretch enum valueQwtPicker
stretchSelection(const QSize &oldSize, const QSize &newSize)QwtPickerprotectedvirtual
trackerFont() const QwtPicker
trackerMode() const QwtPicker
trackerOverlay() const QwtPickerprotected
trackerPen() const QwtPicker
trackerPosition() const QwtPicker
trackerRect(const QFont &) const QwtPickervirtual
trackerText(const QPoint &) const QwtPlotPickerprotectedvirtual
trackerTextF(const QPointF &) const QwtPlotPickerprotectedvirtual
transform(const QRectF &) const QwtPlotPickerprotected
transform(const QPointF &) const QwtPlotPickerprotected
transition(const QEvent *)QwtPickerprotectedvirtual
updateDisplay()QwtPickerprotectedvirtual
UserRubberBand enum valueQwtPicker
VLineRubberBand enum valueQwtPicker
widgetEnterEvent(QEvent *)QwtPickerprotectedvirtual
widgetKeyPressEvent(QKeyEvent *)QwtPlotZoomerprotectedvirtual
widgetKeyReleaseEvent(QKeyEvent *)QwtPickerprotectedvirtual
widgetLeaveEvent(QEvent *)QwtPickerprotectedvirtual
widgetMouseDoubleClickEvent(QMouseEvent *)QwtPickerprotectedvirtual
widgetMouseMoveEvent(QMouseEvent *)QwtPickerprotectedvirtual
widgetMousePressEvent(QMouseEvent *)QwtPickerprotectedvirtual
widgetMouseReleaseEvent(QMouseEvent *)QwtPlotZoomerprotectedvirtual
widgetWheelEvent(QWheelEvent *)QwtPickerprotectedvirtual
xAxis() const QwtPlotPicker
yAxis() const QwtPlotPicker
zoom(const QRectF &)QwtPlotZoomervirtualslot
zoom(int up)QwtPlotZoomervirtualslot
zoomBase() const QwtPlotZoomer
zoomed(const QRectF &rect)QwtPlotZoomersignal
zoomRect() const QwtPlotZoomer
zoomRectIndex() const QwtPlotZoomer
zoomStack() const QwtPlotZoomer
~QwtEventPattern()QwtEventPatternvirtual
~QwtPicker()QwtPickervirtual
~QwtPlotPicker()QwtPlotPickervirtual
~QwtPlotZoomer() (defined in QwtPlotZoomer)QwtPlotZoomervirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_zoomer.html b/ThirdParty/Qwt/doc/html/class_qwt_plot_zoomer.html new file mode 100644 index 0000000000..9b9ecff0e8 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_zoomer.html @@ -0,0 +1,1211 @@ + + + + + + +Qwt User's Guide: QwtPlotZoomer Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+ +
+ +

QwtPlotZoomer provides stacked zooming for a plot widget. + More...

+ +

#include <qwt_plot_zoomer.h>

+
+Inheritance diagram for QwtPlotZoomer:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + + + + + +

+Public Slots

void moveBy (double x, double y)
 
virtual void moveTo (const QPointF &)
 
virtual void zoom (const QRectF &)
 Zoom in. More...
 
virtual void zoom (int up)
 Zoom in or out. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Signals

void zoomed (const QRectF &rect)
 
- Signals inherited from QwtPlotPicker
void selected (const QPointF &pos)
 
void selected (const QRectF &rect)
 
void selected (const QVector< QPointF > &pa)
 
void appended (const QPointF &pos)
 
void moved (const QPointF &pos)
 
- Signals inherited from QwtPicker
void activated (bool on)
 
void selected (const QPolygon &polygon)
 
void appended (const QPoint &pos)
 
void moved (const QPoint &pos)
 
void removed (const QPoint &pos)
 
void changed (const QPolygon &selection)
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 QwtPlotZoomer (QWidget *, bool doReplot=true)
 Create a zoomer for a plot canvas. More...
 
 QwtPlotZoomer (int xAxis, int yAxis, QWidget *, bool doReplot=true)
 Create a zoomer for a plot canvas. More...
 
virtual void setZoomBase (bool doReplot=true)
 
virtual void setZoomBase (const QRectF &)
 Set the initial size of the zoomer. More...
 
QRectF zoomBase () const
 
QRectF zoomRect () const
 
virtual void setAxis (int xAxis, int yAxis)
 
void setMaxStackDepth (int)
 Limit the number of recursive zoom operations to depth. More...
 
int maxStackDepth () const
 
const QStack< QRectF > & zoomStack () const
 
void setZoomStack (const QStack< QRectF > &, int zoomRectIndex=-1)
 Assign a zoom stack. More...
 
uint zoomRectIndex () const
 
- Public Member Functions inherited from QwtPlotPicker
 QwtPlotPicker (QWidget *canvas)
 Create a plot picker. More...
 
+virtual ~QwtPlotPicker ()
 Destructor.
 
 QwtPlotPicker (int xAxis, int yAxis, QWidget *)
 
 QwtPlotPicker (int xAxis, int yAxis, RubberBand rubberBand, DisplayMode trackerMode, QWidget *)
 
+int xAxis () const
 Return x axis.
 
+int yAxis () const
 Return y axis.
 
QwtPlotplot ()
 
const QwtPlotplot () const
 
QWidget * canvas ()
 
const QWidget * canvas () const
 
- Public Member Functions inherited from QwtPicker
 QwtPicker (QWidget *parent)
 
 QwtPicker (RubberBand rubberBand, DisplayMode trackerMode, QWidget *)
 
+virtual ~QwtPicker ()
 Destructor.
 
void setStateMachine (QwtPickerMachine *)
 
const QwtPickerMachinestateMachine () const
 
QwtPickerMachinestateMachine ()
 
void setRubberBand (RubberBand)
 
RubberBand rubberBand () const
 
void setTrackerMode (DisplayMode)
 Set the display mode of the tracker. More...
 
DisplayMode trackerMode () const
 
void setResizeMode (ResizeMode)
 Set the resize mode. More...
 
ResizeMode resizeMode () const
 
void setRubberBandPen (const QPen &)
 
QPen rubberBandPen () const
 
void setTrackerPen (const QPen &)
 
QPen trackerPen () const
 
void setTrackerFont (const QFont &)
 
QFont trackerFont () const
 
bool isEnabled () const
 
bool isActive () const
 
virtual bool eventFilter (QObject *, QEvent *)
 Event filter. More...
 
+QWidget * parentWidget ()
 Return the parent widget, where the selection happens.
 
+const QWidget * parentWidget () const
 Return the parent widget, where the selection happens.
 
virtual QPainterPath pickArea () const
 
virtual void drawRubberBand (QPainter *) const
 
virtual void drawTracker (QPainter *) const
 
virtual QRegion rubberBandMask () const
 
QPoint trackerPosition () const
 
virtual QRect trackerRect (const QFont &) const
 
QPolygon selection () const
 
- Public Member Functions inherited from QwtEventPattern
 QwtEventPattern ()
 
+virtual ~QwtEventPattern ()
 Destructor.
 
void initMousePattern (int numButtons)
 
void initKeyPattern ()
 
void setMousePattern (MousePatternCode, Qt::MouseButton button, Qt::KeyboardModifiers=Qt::NoModifier)
 
void setKeyPattern (KeyPatternCode, int keyCode, Qt::KeyboardModifiers modifierCodes=Qt::NoModifier)
 
+void setMousePattern (const QVector< MousePattern > &)
 Change the mouse event patterns.
 
+void setKeyPattern (const QVector< KeyPattern > &)
 Change the key event patterns.
 
const QVector< MousePattern > & mousePattern () const
 
const QVector< KeyPattern > & keyPattern () const
 
QVector< MousePattern > & mousePattern ()
 
QVector< KeyPattern > & keyPattern ()
 
bool mouseMatch (MousePatternCode, const QMouseEvent *) const
 Compare a mouse event with an event pattern. More...
 
bool keyMatch (KeyPatternCode, const QKeyEvent *) const
 Compare a key event with an event pattern. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Protected Member Functions

virtual void rescale ()
 
virtual QSizeF minZoomSize () const
 Limit zooming by a minimum rectangle. More...
 
virtual void widgetMouseReleaseEvent (QMouseEvent *)
 
virtual void widgetKeyPressEvent (QKeyEvent *)
 
virtual void begin ()
 
virtual bool end (bool ok=true)
 
virtual bool accept (QPolygon &) const
 Check and correct a selected rectangle. More...
 
- Protected Member Functions inherited from QwtPlotPicker
QRectF scaleRect () const
 
QRectF invTransform (const QRect &) const
 
QRect transform (const QRectF &) const
 
QPointF invTransform (const QPoint &) const
 
QPoint transform (const QPointF &) const
 
virtual QwtText trackerText (const QPoint &) const
 
virtual QwtText trackerTextF (const QPointF &) const
 Translate a position into a position string. More...
 
virtual void move (const QPoint &)
 
virtual void append (const QPoint &)
 
- Protected Member Functions inherited from QwtPicker
virtual QPolygon adjustedPoints (const QPolygon &) const
 Map the pickedPoints() into a selection() More...
 
virtual void transition (const QEvent *)
 
virtual void remove ()
 
virtual void reset ()
 
virtual void widgetMousePressEvent (QMouseEvent *)
 
virtual void widgetMouseDoubleClickEvent (QMouseEvent *)
 
virtual void widgetMouseMoveEvent (QMouseEvent *)
 
virtual void widgetWheelEvent (QWheelEvent *)
 
virtual void widgetKeyReleaseEvent (QKeyEvent *)
 
virtual void widgetEnterEvent (QEvent *)
 
virtual void widgetLeaveEvent (QEvent *)
 
virtual void stretchSelection (const QSize &oldSize, const QSize &newSize)
 
+virtual void updateDisplay ()
 Update the state of rubber band and tracker label.
 
const QwtWidgetOverlayrubberBandOverlay () const
 
const QwtWidgetOverlaytrackerOverlay () const
 
const QPolygon & pickedPoints () const
 
- Protected Member Functions inherited from QwtEventPattern
virtual bool mouseMatch (const MousePattern &, const QMouseEvent *) const
 Compare a mouse event with an event pattern. More...
 
virtual bool keyMatch (const KeyPattern &, const QKeyEvent *) const
 Compare a key event with an event pattern. More...
 
+ + + + + + + + + +

+Additional Inherited Members

- Public Types inherited from QwtPicker
enum  RubberBand {
+  NoRubberBand = 0, +HLineRubberBand, +VLineRubberBand, +CrossRubberBand, +
+  RectRubberBand, +EllipseRubberBand, +PolygonRubberBand, +UserRubberBand = 100 +
+ }
 
enum  DisplayMode { AlwaysOff, +AlwaysOn, +ActiveOnly + }
 Display mode. More...
 
enum  ResizeMode { Stretch, +KeepSize + }
 
+

Detailed Description

+

QwtPlotZoomer provides stacked zooming for a plot widget.

+

QwtPlotZoomer selects rectangles from user inputs ( mouse or keyboard ) translates them into plot coordinates and adjusts the axes to them. The selection is supported by a rubber band and optionally by displaying the coordinates of the current mouse position.

+

Zooming can be repeated as often as possible, limited only by maxStackDepth() or minZoomSize(). Each rectangle is pushed on a stack.

+

The default setting how to select rectangles is a QwtPickerDragRectMachine with the following bindings:

+
    +
  • QwtEventPattern::MouseSelect1
    + The first point of the zoom rectangle is selected by a mouse press, the second point from the position, where the mouse is released.
  • +
+ + +

To traverse the zoom stack the following bindings are used:

+ + + +

The setKeyPattern() and setMousePattern() functions can be used to configure the zoomer actions. The following example shows, how to configure the 'I' and 'O' keys for zooming in and out one position on the zoom stack. The "Home" key is used to "unzoom" the plot.

+
zoomer = new QwtPlotZoomer( plot );
+
zoomer->setKeyPattern( QwtEventPattern::KeyRedo, Qt::Key_I, Qt::ShiftModifier );
+
zoomer->setKeyPattern( QwtEventPattern::KeyUndo, Qt::Key_O, Qt::ShiftModifier );
+
zoomer->setKeyPattern( QwtEventPattern::KeyHome, Qt::Key_Home );
+

QwtPlotZoomer is tailored for plots with one x and y axis, but it is allowed to attach a second QwtPlotZoomer ( without rubber band and tracker ) for the other axes.

+
Note
The realtime example includes an derived zoomer class that adds scrollbars to the plot canvas.
+
See Also
QwtPlotPanner, QwtPlotMagnifier
+

Constructor & Destructor Documentation

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
QwtPlotZoomer::QwtPlotZoomer (QWidget * canvas,
bool doReplot = true 
)
+
+explicit
+
+ +

Create a zoomer for a plot canvas.

+

The zoomer is set to those x- and y-axis of the parent plot of the canvas that are enabled. If both or no x-axis are enabled, the picker is set to QwtPlot::xBottom. If both or no y-axis are enabled, it is set to QwtPlot::yLeft.

+

The zoomer is initialized with a QwtPickerDragRectMachine, the tracker mode is set to QwtPicker::ActiveOnly and the rubber band is set to QwtPicker::RectRubberBand

+
Parameters
+ + + +
canvasPlot canvas to observe, also the parent object
doReplotCall QwtPlot::replot() for the attached plot before initializing the zoomer with its scales. This might be necessary, when the plot is in a state with pending scale changes.
+
+
+
See Also
QwtPlot::autoReplot(), QwtPlot::replot(), setZoomBase()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
QwtPlotZoomer::QwtPlotZoomer (int xAxis,
int yAxis,
QWidget * canvas,
bool doReplot = true 
)
+
+explicit
+
+ +

Create a zoomer for a plot canvas.

+

The zoomer is initialized with a QwtPickerDragRectMachine, the tracker mode is set to QwtPicker::ActiveOnly and the rubber band is set to QwtPicker;;RectRubberBand

+
Parameters
+ + + + + +
xAxisX axis of the zoomer
yAxisY axis of the zoomer
canvasPlot canvas to observe, also the parent object
doReplotCall QwtPlot::replot() for the attached plot before initializing the zoomer with its scales. This might be necessary, when the plot is in a state with pending scale changes.
+
+
+
See Also
QwtPlot::autoReplot(), QwtPlot::replot(), setZoomBase()
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + + +
bool QwtPlotZoomer::accept (QPolygon & pa) const
+
+protectedvirtual
+
+ +

Check and correct a selected rectangle.

+

Reject rectangles with a height or width < 2, otherwise expand the selected rectangle to a minimum size of 11x11 and accept it.

+
Returns
true If the rectangle is accepted, or has been changed to an accepted one.
+ +

Reimplemented from QwtPicker.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void QwtPlotZoomer::begin ()
+
+protectedvirtual
+
+

Rejects selections, when the stack depth is too deep, or the zoomed rectangle is minZoomSize().

+
See Also
minZoomSize(), maxStackDepth()
+ +

Reimplemented from QwtPicker.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool QwtPlotZoomer::end (bool ok = true)
+
+protectedvirtual
+
+

Expand the selected rectangle to minZoomSize() and zoom in if accepted.

+
Parameters
+ + +
okIf true, complete the selection and emit selected signals otherwise discard the selection.
+
+
+
See Also
accept(), minZoomSize()
+
Returns
True if the selection has been accepted, false otherwise
+ +

Reimplemented from QwtPlotPicker.

+ +
+
+ +
+
+ + + + + + + +
int QwtPlotZoomer::maxStackDepth () const
+
+
Returns
Maximal depth of the zoom stack.
+
See Also
setMaxStackDepth()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
QSizeF QwtPlotZoomer::minZoomSize () const
+
+protectedvirtual
+
+ +

Limit zooming by a minimum rectangle.

+
Returns
zoomBase().width() / 10e4, zoomBase().height() / 10e4
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void QwtPlotZoomer::moveBy (double dx,
double dy 
)
+
+slot
+
+

Move the current zoom rectangle.

+
Parameters
+ + + +
dxX offset
dyY offset
+
+
+
Note
The changed rectangle is limited by the zoom base
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtPlotZoomer::moveTo (const QPointF & pos)
+
+virtualslot
+
+

Move the the current zoom rectangle.

+
Parameters
+ + +
posNew position
+
+
+
See Also
QRectF::moveTo()
+
Note
The changed rectangle is limited by the zoom base
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void QwtPlotZoomer::rescale ()
+
+protectedvirtual
+
+

Adjust the observed plot to zoomRect()

+
Note
Initiates QwtPlot::replot()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void QwtPlotZoomer::setAxis (int xAxis,
int yAxis 
)
+
+virtual
+
+

Reinitialize the axes, and set the zoom base to their scales.

+
Parameters
+ + + +
xAxisX axis
yAxisY axis
+
+
+ +

Reimplemented from QwtPlotPicker.

+ +
+
+ +
+
+ + + + + + + + +
void QwtPlotZoomer::setMaxStackDepth (int depth)
+
+ +

Limit the number of recursive zoom operations to depth.

+

A value of -1 set the depth to unlimited, 0 disables zooming. If the current zoom rectangle is below depth, the plot is unzoomed.

+
Parameters
+ + +
depthMaximum for the stack depth
+
+
+
See Also
maxStackDepth()
+
Note
depth doesn't include the zoom base, so zoomStack().count() might be maxStackDepth() + 1.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtPlotZoomer::setZoomBase (bool doReplot = true)
+
+virtual
+
+

Reinitialized the zoom stack with scaleRect() as base.

+
Parameters
+ + +
doReplotCall QwtPlot::replot() for the attached plot before initializing the zoomer with its scales. This might be necessary, when the plot is in a state with pending scale changes.
+
+
+
See Also
zoomBase(), scaleRect() QwtPlot::autoReplot(), QwtPlot::replot().
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtPlotZoomer::setZoomBase (const QRectF & base)
+
+virtual
+
+ +

Set the initial size of the zoomer.

+

base is united with the current scaleRect() and the zoom stack is reinitialized with it as zoom base. plot is zoomed to scaleRect().

+
Parameters
+ + +
baseZoom base
+
+
+
See Also
zoomBase(), scaleRect()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtPlotZoomer::setZoomStack (const QStack< QRectF > & zoomStack,
int zoomRectIndex = -1 
)
+
+ +

Assign a zoom stack.

+

In combination with other types of navigation it might be useful to modify to manipulate the complete zoom stack.

+
Parameters
+ + + +
zoomStackNew zoom stack
zoomRectIndexIndex of the current position of zoom stack. In case of -1 the current position is at the top of the stack.
+
+
+
Note
The zoomed signal might be emitted.
+
See Also
zoomStack(), zoomRectIndex()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtPlotZoomer::widgetKeyPressEvent (QKeyEvent * ke)
+
+protectedvirtual
+
+

Qt::Key_Plus zooms in, Qt::Key_Minus zooms out one position on the zoom stack, Qt::Key_Escape zooms out to the zoom base.

+

Changes the current position on the stack, but doesn't pop any rectangle.

+
Note
The keys codes can be changed, using QwtEventPattern::setKeyPattern: 3, 4, 5
+ +

Reimplemented from QwtPicker.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtPlotZoomer::widgetMouseReleaseEvent (QMouseEvent * me)
+
+protectedvirtual
+
+

Qt::MidButton zooms out one position on the zoom stack, Qt::RightButton to the zoom base.

+

Changes the current position on the stack, but doesn't pop any rectangle.

+
Note
The mouse events can be changed, using QwtEventPattern::setMousePattern: 2, 1
+ +

Reimplemented from QwtPicker.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtPlotZoomer::zoom (const QRectF & rect)
+
+virtualslot
+
+ +

Zoom in.

+

Clears all rectangles above the current position of the zoom stack and pushes the normalized rectangle on it.

+
Note
If the maximal stack depth is reached, zoom is ignored.
+
+The zoomed signal is emitted.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtPlotZoomer::zoom (int offset)
+
+virtualslot
+
+ +

Zoom in or out.

+

Activate a rectangle on the zoom stack with an offset relative to the current position. Negative values of offset will zoom out, positive zoom in. A value of 0 zooms out to the zoom base.

+
Parameters
+ + +
offsetOffset relative to the current position of the zoom stack.
+
+
+
Note
The zoomed signal is emitted.
+
See Also
zoomRectIndex()
+ +
+
+ +
+
+ + + + + + + +
QRectF QwtPlotZoomer::zoomBase () const
+
+
Returns
Initial rectangle of the zoomer
+
See Also
setZoomBase(), zoomRect()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtPlotZoomer::zoomed (const QRectF & rect)
+
+signal
+
+

A signal emitting the zoomRect(), when the plot has been zoomed in or out.

+
Parameters
+ + +
rectCurrent zoom rectangle.
+
+
+ +
+
+ +
+
+ + + + + + + +
QRectF QwtPlotZoomer::zoomRect () const
+
+
Returns
Rectangle at the current position on the zoom stack.
+
See Also
zoomRectIndex(), scaleRect().
+ +
+
+ +
+
+ + + + + + + +
uint QwtPlotZoomer::zoomRectIndex () const
+
+
Returns
Index of current position of zoom stack.
+ +
+
+ +
+
+ + + + + + + +
const QStack< QRectF > & QwtPlotZoomer::zoomStack () const
+
+
Returns
The zoom stack. zoomStack()[0] is the zoom base, zoomStack()[1] the first zoomed rectangle.
+
See Also
setZoomStack(), zoomRectIndex()
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_zoomer__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_plot_zoomer__inherit__graph.map new file mode 100644 index 0000000000..985e8a11c9 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_zoomer__inherit__graph.map @@ -0,0 +1,5 @@ + + + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_zoomer__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_plot_zoomer__inherit__graph.md5 new file mode 100644 index 0000000000..c0cfd94a7a --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_plot_zoomer__inherit__graph.md5 @@ -0,0 +1 @@ +3c6f8c610335fb8b1c1a47756e3400c6 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_plot_zoomer__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_plot_zoomer__inherit__graph.png new file mode 100644 index 0000000000..dc0d7b30f6 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_plot_zoomer__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_point3_d-members.html b/ThirdParty/Qwt/doc/html/class_qwt_point3_d-members.html new file mode 100644 index 0000000000..d1359df8f7 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_point3_d-members.html @@ -0,0 +1,117 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtPoint3D Member List
+
+
+ +

This is the complete list of members for QwtPoint3D, including all inherited members.

+ + + + + + + + + + + + + + + + + + +
isNull() const QwtPoint3Dinline
operator!=(const QwtPoint3D &) const QwtPoint3Dinline
operator==(const QwtPoint3D &) const QwtPoint3Dinline
QwtPoint3D()QwtPoint3Dinline
QwtPoint3D(double x, double y, double z)QwtPoint3Dinline
QwtPoint3D(const QwtPoint3D &)QwtPoint3Dinline
QwtPoint3D(const QPointF &)QwtPoint3Dinline
rx()QwtPoint3Dinline
ry()QwtPoint3Dinline
rz()QwtPoint3Dinline
setX(double x)QwtPoint3Dinline
setY(double y)QwtPoint3Dinline
setZ(double y)QwtPoint3Dinline
toPoint() const QwtPoint3Dinline
x() const QwtPoint3Dinline
y() const QwtPoint3Dinline
z() const QwtPoint3Dinline
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_point3_d.html b/ThirdParty/Qwt/doc/html/class_qwt_point3_d.html new file mode 100644 index 0000000000..abb27977dc --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_point3_d.html @@ -0,0 +1,473 @@ + + + + + + +Qwt User's Guide: QwtPoint3D Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtPoint3D Class Reference
+
+
+ +

QwtPoint3D class defines a 3D point in double coordinates. + More...

+ +

#include <qwt_point_3d.h>

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 QwtPoint3D ()
 
QwtPoint3D (double x, double y, double z)
 Constructs a point with coordinates specified by x, y and z.
 
 QwtPoint3D (const QwtPoint3D &)
 
 QwtPoint3D (const QPointF &)
 
bool isNull () const
 
double x () const
 
double y () const
 
double z () const
 
double & rx ()
 
double & ry ()
 
double & rz ()
 
+void setX (double x)
 Sets the x-coordinate of the point to the value specified by x.
 
+void setY (double y)
 Sets the y-coordinate of the point to the value specified by y.
 
+void setZ (double y)
 Sets the z-coordinate of the point to the value specified by z.
 
QPointF toPoint () const
 
bool operator== (const QwtPoint3D &) const
 
bool operator!= (const QwtPoint3D &) const
 
+

Detailed Description

+

QwtPoint3D class defines a 3D point in double coordinates.

+

Constructor & Destructor Documentation

+ +
+
+ + + + + +
+ + + + + + + +
QwtPoint3D::QwtPoint3D ()
+
+inline
+
+

Constructs a null point.

+
See Also
isNull()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
QwtPoint3D::QwtPoint3D (const QwtPoint3Dother)
+
+inline
+
+

Copy constructor. Constructs a point using the values of the point specified.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
QwtPoint3D::QwtPoint3D (const QPointF & other)
+
+inline
+
+

Constructs a point with x and y coordinates from a 2D point, and a z coordinate of 0.

+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + +
bool QwtPoint3D::isNull () const
+
+inline
+
+
Returns
True if the point is null; otherwise returns false.
+

A point is considered to be null if x, y and z-coordinates are equal to zero.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool QwtPoint3D::operator!= (const QwtPoint3Dother) const
+
+inline
+
+
Returns
True if this rect and other are different; otherwise returns false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool QwtPoint3D::operator== (const QwtPoint3Dother) const
+
+inline
+
+
Returns
True, if this point and other are equal; otherwise returns false.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
double & QwtPoint3D::rx ()
+
+inline
+
+
Returns
A reference to the x-coordinate of the point.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
double & QwtPoint3D::ry ()
+
+inline
+
+
Returns
A reference to the y-coordinate of the point.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
double & QwtPoint3D::rz ()
+
+inline
+
+
Returns
A reference to the z-coordinate of the point.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
QPointF QwtPoint3D::toPoint () const
+
+inline
+
+
Returns
2D point, where the z coordinate is dropped.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
double QwtPoint3D::x () const
+
+inline
+
+
Returns
The x-coordinate of the point.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
double QwtPoint3D::y () const
+
+inline
+
+
Returns
The y-coordinate of the point.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
double QwtPoint3D::z () const
+
+inline
+
+
Returns
The z-coordinate of the point.
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_point3_d_series_data-members.html b/ThirdParty/Qwt/doc/html/class_qwt_point3_d_series_data-members.html new file mode 100644 index 0000000000..4d45c57a05 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_point3_d_series_data-members.html @@ -0,0 +1,113 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtPoint3DSeriesData Member List
+
+
+ +

This is the complete list of members for QwtPoint3DSeriesData, including all inherited members.

+ + + + + + + + + + + + + + +
boundingRect() const QwtPoint3DSeriesDatavirtual
d_boundingRectQwtSeriesData< QwtPoint3D >mutableprotected
d_samplesQwtArraySeriesData< QwtPoint3D >protected
QwtArraySeriesData()QwtArraySeriesData< QwtPoint3D >
QwtArraySeriesData(const QVector< QwtPoint3D > &samples)QwtArraySeriesData< QwtPoint3D >
QwtPoint3DSeriesData(const QVector< QwtPoint3D > &=QVector< QwtPoint3D >())QwtPoint3DSeriesData
QwtSeriesData()QwtSeriesData< QwtPoint3D >
sample(size_t index) constQwtArraySeriesData< QwtPoint3D >virtual
samples() constQwtArraySeriesData< QwtPoint3D >
setRectOfInterest(const QRectF &rect)QwtSeriesData< QwtPoint3D >virtual
setSamples(const QVector< QwtPoint3D > &samples)QwtArraySeriesData< QwtPoint3D >
size() constQwtArraySeriesData< QwtPoint3D >virtual
~QwtSeriesData()QwtSeriesData< QwtPoint3D >virtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_point3_d_series_data.html b/ThirdParty/Qwt/doc/html/class_qwt_point3_d_series_data.html new file mode 100644 index 0000000000..6b5590dc5a --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_point3_d_series_data.html @@ -0,0 +1,211 @@ + + + + + + +Qwt User's Guide: QwtPoint3DSeriesData Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtPoint3DSeriesData Class Reference
+
+
+ +

Interface for iterating over an array of 3D points. + More...

+ +

#include <qwt_series_data.h>

+
+Inheritance diagram for QwtPoint3DSeriesData:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 QwtPoint3DSeriesData (const QVector< QwtPoint3D > &=QVector< QwtPoint3D >())
 
virtual QRectF boundingRect () const
 Calculate the bounding rectangle. More...
 
- Public Member Functions inherited from QwtArraySeriesData< QwtPoint3D >
QwtArraySeriesData ()
 Constructor.
 
 QwtArraySeriesData (const QVector< QwtPoint3D > &samples)
 
void setSamples (const QVector< QwtPoint3D > &samples)
 
const QVector< QwtPoint3Dsamples () const
 
virtual size_t size () const
 
virtual QwtPoint3D sample (size_t index) const
 
- Public Member Functions inherited from QwtSeriesData< QwtPoint3D >
QwtSeriesData ()
 Constructor.
 
+virtual ~QwtSeriesData ()
 Destructor.
 
virtual void setRectOfInterest (const QRectF &rect)
 
+ + + + + +

+Additional Inherited Members

- Protected Attributes inherited from QwtArraySeriesData< QwtPoint3D >
+QVector< QwtPoint3Dd_samples
 Vector of samples.
 
+

Detailed Description

+

Interface for iterating over an array of 3D points.

+

Constructor & Destructor Documentation

+ +
+
+ + + + + + + + +
QwtPoint3DSeriesData::QwtPoint3DSeriesData (const QVector< QwtPoint3D > & samples = QVector<QwtPoint3D>())
+
+

Constructor

+
Parameters
+ + +
samplesSamples
+
+
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + +
QRectF QwtPoint3DSeriesData::boundingRect () const
+
+virtual
+
+ +

Calculate the bounding rectangle.

+

The bounding rectangle is calculated once by iterating over all points and is stored for all following requests.

+
Returns
Bounding rectangle
+ +

Implements QwtSeriesData< QwtPoint3D >.

+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_point3_d_series_data__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_point3_d_series_data__inherit__graph.map new file mode 100644 index 0000000000..d8b7997f9c --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_point3_d_series_data__inherit__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_point3_d_series_data__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_point3_d_series_data__inherit__graph.md5 new file mode 100644 index 0000000000..bd75332f90 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_point3_d_series_data__inherit__graph.md5 @@ -0,0 +1 @@ +33cbec7aafb493332274e675e0b1a538 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_point3_d_series_data__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_point3_d_series_data__inherit__graph.png new file mode 100644 index 0000000000..aa681e31b8 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_point3_d_series_data__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_point_array_data-members.html b/ThirdParty/Qwt/doc/html/class_qwt_point_array_data-members.html new file mode 100644 index 0000000000..49f60a3116 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_point_array_data-members.html @@ -0,0 +1,111 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtPointArrayData Member List
+
+
+ +

This is the complete list of members for QwtPointArrayData, including all inherited members.

+ + + + + + + + + + + + +
boundingRect() const QwtPointArrayDatavirtual
d_boundingRectQwtSeriesData< QPointF >mutableprotected
QwtPointArrayData(const QVector< double > &x, const QVector< double > &y)QwtPointArrayData
QwtPointArrayData(const double *x, const double *y, size_t size)QwtPointArrayData
QwtSeriesData()QwtSeriesData< QPointF >
sample(size_t i) const QwtPointArrayDatavirtual
setRectOfInterest(const QRectF &rect)QwtSeriesData< QPointF >virtual
size() const QwtPointArrayDatavirtual
xData() const QwtPointArrayData
yData() const QwtPointArrayData
~QwtSeriesData()QwtSeriesData< QPointF >virtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_point_array_data.html b/ThirdParty/Qwt/doc/html/class_qwt_point_array_data.html new file mode 100644 index 0000000000..3c317b4bad --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_point_array_data.html @@ -0,0 +1,352 @@ + + + + + + +Qwt User's Guide: QwtPointArrayData Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtPointArrayData Class Reference
+
+
+ +

Interface for iterating over two QVector<double> objects. + More...

+ +

#include <qwt_point_data.h>

+
+Inheritance diagram for QwtPointArrayData:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 QwtPointArrayData (const QVector< double > &x, const QVector< double > &y)
 
 QwtPointArrayData (const double *x, const double *y, size_t size)
 
virtual QRectF boundingRect () const
 Calculate the bounding rectangle. More...
 
virtual size_t size () const
 
virtual QPointF sample (size_t i) const
 
const QVector< double > & xData () const
 
const QVector< double > & yData () const
 
- Public Member Functions inherited from QwtSeriesData< QPointF >
QwtSeriesData ()
 Constructor.
 
+virtual ~QwtSeriesData ()
 Destructor.
 
virtual void setRectOfInterest (const QRectF &rect)
 
+ + + + + +

+Additional Inherited Members

- Protected Attributes inherited from QwtSeriesData< QPointF >
+QRectF d_boundingRect
 Can be used to cache a calculated bounding rectangle.
 
+

Detailed Description

+

Interface for iterating over two QVector<double> objects.

+

Constructor & Destructor Documentation

+ +
+
+ + + + + + + + + + + + + + + + + + +
QwtPointArrayData::QwtPointArrayData (const QVector< double > & x,
const QVector< double > & y 
)
+
+

Constructor

+
Parameters
+ + + +
xArray of x values
yArray of y values
+
+
+
See Also
QwtPlotCurve::setData(), QwtPlotCurve::setSamples()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
QwtPointArrayData::QwtPointArrayData (const double * x,
const double * y,
size_t size 
)
+
+

Constructor

+
Parameters
+ + + + +
xArray of x values
yArray of y values
sizeSize of the x and y arrays
+
+
+
See Also
QwtPlotCurve::setData(), QwtPlotCurve::setSamples()
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + +
QRectF QwtPointArrayData::boundingRect () const
+
+virtual
+
+ +

Calculate the bounding rectangle.

+

The bounding rectangle is calculated once by iterating over all points and is stored for all following requests.

+
Returns
Bounding rectangle
+ +

Implements QwtSeriesData< QPointF >.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
QPointF QwtPointArrayData::sample (size_t index) const
+
+virtual
+
+

Return the sample at position i

+
Parameters
+ + +
indexIndex
+
+
+
Returns
Sample at position i
+ +

Implements QwtSeriesData< QPointF >.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
size_t QwtPointArrayData::size () const
+
+virtual
+
+
Returns
Size of the data set
+ +

Implements QwtSeriesData< QPointF >.

+ +
+
+ +
+
+ + + + + + + +
const QVector< double > & QwtPointArrayData::xData () const
+
+
Returns
Array of the x-values
+ +
+
+ +
+
+ + + + + + + +
const QVector< double > & QwtPointArrayData::yData () const
+
+
Returns
Array of the y-values
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_point_array_data__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_point_array_data__inherit__graph.map new file mode 100644 index 0000000000..f73e8de24e --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_point_array_data__inherit__graph.map @@ -0,0 +1,3 @@ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_point_array_data__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_point_array_data__inherit__graph.md5 new file mode 100644 index 0000000000..af1f7dbd86 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_point_array_data__inherit__graph.md5 @@ -0,0 +1 @@ +b79c399091d6cef4fa6f8863ab0322dd \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_point_array_data__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_point_array_data__inherit__graph.png new file mode 100644 index 0000000000..682c0b0459 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_point_array_data__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_point_mapper-members.html b/ThirdParty/Qwt/doc/html/class_qwt_point_mapper-members.html new file mode 100644 index 0000000000..f166695b3b --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_point_mapper-members.html @@ -0,0 +1,117 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtPointMapper Member List
+
+
+ +

This is the complete list of members for QwtPointMapper, including all inherited members.

+ + + + + + + + + + + + + + + + + + +
boundingRect() const QwtPointMapper
flags() const QwtPointMapper
QwtPointMapper()QwtPointMapper
RoundPoints enum valueQwtPointMapper
setBoundingRect(const QRectF &)QwtPointMapper
setFlag(TransformationFlag, bool on=true)QwtPointMapper
setFlags(TransformationFlags)QwtPointMapper
testFlag(TransformationFlag) const QwtPointMapper
toImage(const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QwtSeriesData< QPointF > *series, int from, int to, const QPen &, bool antialiased, uint numThreads) const QwtPointMapper
toPoints(const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QwtSeriesData< QPointF > *series, int from, int to) const QwtPointMapper
toPointsF(const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QwtSeriesData< QPointF > *series, int from, int to) const QwtPointMapper
toPolygon(const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QwtSeriesData< QPointF > *series, int from, int to) const QwtPointMapper
toPolygonF(const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QwtSeriesData< QPointF > *series, int from, int to) const QwtPointMapper
TransformationFlag enum nameQwtPointMapper
TransformationFlags typedefQwtPointMapper
WeedOutPoints enum valueQwtPointMapper
~QwtPointMapper()QwtPointMapper
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_point_mapper.html b/ThirdParty/Qwt/doc/html/class_qwt_point_mapper.html new file mode 100644 index 0000000000..a40c9ddb2f --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_point_mapper.html @@ -0,0 +1,674 @@ + + + + + + +Qwt User's Guide: QwtPointMapper Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtPointMapper Class Reference
+
+
+ +

A helper class for translating a series of points. + More...

+ +

#include <qwt_point_mapper.h>

+ + + + + + + + +

+Public Types

enum  TransformationFlag { RoundPoints = 0x01, +WeedOutPoints = 0x02 + }
 Flags affecting the transformation process. More...
 
typedef QFlags
+< TransformationFlag
TransformationFlags
 Flags affecting the transformation process. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

QwtPointMapper ()
 Constructor.
 
~QwtPointMapper ()
 Destructor.
 
void setFlags (TransformationFlags)
 
TransformationFlags flags () const
 
void setFlag (TransformationFlag, bool on=true)
 
bool testFlag (TransformationFlag) const
 
void setBoundingRect (const QRectF &)
 
QRectF boundingRect () const
 
QPolygonF toPolygonF (const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QwtSeriesData< QPointF > *series, int from, int to) const
 Translate a series of points into a QPolygonF. More...
 
QPolygon toPolygon (const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QwtSeriesData< QPointF > *series, int from, int to) const
 Translate a series of points into a QPolygon. More...
 
QPolygon toPoints (const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QwtSeriesData< QPointF > *series, int from, int to) const
 Translate a series of points into a QPolygon. More...
 
QPolygonF toPointsF (const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QwtSeriesData< QPointF > *series, int from, int to) const
 Translate a series into a QPolygonF. More...
 
QImage toImage (const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QwtSeriesData< QPointF > *series, int from, int to, const QPen &, bool antialiased, uint numThreads) const
 Translate a series into a QImage. More...
 
+

Detailed Description

+

A helper class for translating a series of points.

+

QwtPointMapper is a collection of methods and optimizations for translating a series of points into paint device coordinates. It is used by QwtPlotCurve but might also be useful for similar plot items displaying a QwtSeriesData<QPointF>.

+

Member Typedef Documentation

+ +
+
+ +

Flags affecting the transformation process.

+
See Also
setFlag(), setFlags()
+ +
+
+

Member Enumeration Documentation

+ +
+
+ +

Flags affecting the transformation process.

+
See Also
setFlag(), setFlags()
+ + + +
Enumerator
RoundPoints  +

Round points to integer values.

+
WeedOutPoints  +

Try to remove points, that are translated to the same position.

+
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + + + +
QRectF QwtPointMapper::boundingRect () const
+
+
Returns
Bounding rectangle
+
See Also
setBoundingRect()
+ +
+
+ +
+
+ + + + + + + +
QwtPointMapper::TransformationFlags QwtPointMapper::flags () const
+
+
Returns
Flags affecting the transformation process
+
See Also
setFlags(), setFlag()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPointMapper::setBoundingRect (const QRectF & rect)
+
+

Set a bounding rectangle for the point mapping algorithm

+

A valid bounding rectangle can be used for optimizations

+
Parameters
+ + +
rectBounding rectangle
+
+
+
See Also
boundingRect()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtPointMapper::setFlag (TransformationFlag flag,
bool on = true 
)
+
+

Modify a flag affecting the transformation process

+
Parameters
+ + + +
flagFlag type
onValue
+
+
+
See Also
flag(), setFlags()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPointMapper::setFlags (TransformationFlags flags)
+
+

Set the flags affecting the transformation process

+
Parameters
+ + +
flagsFlags
+
+
+
See Also
flags(), setFlag()
+ +
+
+ +
+
+ + + + + + + + +
bool QwtPointMapper::testFlag (TransformationFlag flag) const
+
+
Returns
True, when the flag is set
+
Parameters
+ + +
flagFlag type
+
+
+
See Also
setFlag(), setFlags()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
QImage QwtPointMapper::toImage (const QwtScaleMapxMap,
const QwtScaleMapyMap,
const QwtSeriesData< QPointF > * series,
int from,
int to,
const QPen & pen,
bool antialiased,
uint numThreads 
) const
+
+ +

Translate a series into a QImage.

+
Parameters
+ + + + + + + + + +
xMapx map
yMapy map
seriesSeries of points to be mapped
fromIndex of the first point to be painted
toIndex of the last point to be painted
penPen used for drawing a point of the image, where a point is mapped to
antialiasedTrue, when the dots should be displayed antialiased
numThreadsNumber of threads to be used for rendering. If numThreads is set to 0, the system specific ideal thread count is used.
+
+
+
Returns
Image displaying the series
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
QPolygon QwtPointMapper::toPoints (const QwtScaleMapxMap,
const QwtScaleMapyMap,
const QwtSeriesData< QPointF > * series,
int from,
int to 
) const
+
+ +

Translate a series of points into a QPolygon.

+
    +
  • WeedOutPoints & boundingRect().isValid() All points that are mapped to the same position will be one point. Points outside of the bounding rectangle are ignored.
  • +
+
    +
  • WeedOutPoints & !boundingRect().isValid() All consecutive points that are mapped to the same position will one point
  • +
+
    +
  • !WeedOutPoints & boundingRect().isValid() Points outside of the bounding rectangle are ignored.
  • +
+
Parameters
+ + + + + + +
xMapx map
yMapy map
seriesSeries of points to be mapped
fromIndex of the first point to be painted
toIndex of the last point to be painted
+
+
+
Returns
Translated polygon
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
QPolygonF QwtPointMapper::toPointsF (const QwtScaleMapxMap,
const QwtScaleMapyMap,
const QwtSeriesData< QPointF > * series,
int from,
int to 
) const
+
+ +

Translate a series into a QPolygonF.

+
    +
  • WeedOutPoints & RoundPoints & boundingRect().isValid() All points that are mapped to the same position will be one point. Points outside of the bounding rectangle are ignored.
  • +
+
    +
  • WeedOutPoints & RoundPoints & !boundingRect().isValid() All consecutive points that are mapped to the same position will one point
  • +
+
    +
  • WeedOutPoints & !RoundPoints All consecutive points that are mapped to the same position will one point
  • +
+
    +
  • !WeedOutPoints & boundingRect().isValid() Points outside of the bounding rectangle are ignored.
  • +
+

When RoundPoints is set all points are rounded to integers but returned as PolygonF - what only makes sense when the further processing of the values need a QPolygonF.

+
Parameters
+ + + + + + +
xMapx map
yMapy map
seriesSeries of points to be mapped
fromIndex of the first point to be painted
toIndex of the last point to be painted
+
+
+
Returns
Translated polygon
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
QPolygon QwtPointMapper::toPolygon (const QwtScaleMapxMap,
const QwtScaleMapyMap,
const QwtSeriesData< QPointF > * series,
int from,
int to 
) const
+
+ +

Translate a series of points into a QPolygon.

+

When the WeedOutPoints flag is enabled consecutive points, that are mapped to the same position will be one point.

+
Parameters
+ + + + + + +
xMapx map
yMapy map
seriesSeries of points to be mapped
fromIndex of the first point to be painted
toIndex of the last point to be painted
+
+
+
Returns
Translated polygon
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
QPolygonF QwtPointMapper::toPolygonF (const QwtScaleMapxMap,
const QwtScaleMapyMap,
const QwtSeriesData< QPointF > * series,
int from,
int to 
) const
+
+ +

Translate a series of points into a QPolygonF.

+

When the WeedOutPoints flag is enabled consecutive points, that are mapped to the same position will be one point.

+

When RoundPoints is set all points are rounded to integers but returned as PolygonF - what only makes sense when the further processing of the values need a QPolygonF.

+
Parameters
+ + + + + + +
xMapx map
yMapy map
seriesSeries of points to be mapped
fromIndex of the first point to be painted
toIndex of the last point to be painted
+
+
+
Returns
Translated polygon
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_point_polar-members.html b/ThirdParty/Qwt/doc/html/class_qwt_point_polar-members.html new file mode 100644 index 0000000000..4b7d78cb43 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_point_polar-members.html @@ -0,0 +1,117 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtPointPolar Member List
+
+
+ +

This is the complete list of members for QwtPointPolar, including all inherited members.

+ + + + + + + + + + + + + + + + + + +
azimuth() const QwtPointPolarinline
isNull() const QwtPointPolarinline
isValid() const QwtPointPolarinline
normalized() const QwtPointPolar
operator!=(const QwtPointPolar &) const QwtPointPolar
operator==(const QwtPointPolar &) const QwtPointPolar
QwtPointPolar()QwtPointPolarinline
QwtPointPolar(double azimuth, double radius)QwtPointPolarinline
QwtPointPolar(const QwtPointPolar &)QwtPointPolarinline
QwtPointPolar(const QPointF &)QwtPointPolar
radius() const QwtPointPolarinline
rAzimuth()QwtPointPolarinline
rRadius()QwtPointPolarinline
setAzimuth(double)QwtPointPolarinline
setPoint(const QPointF &)QwtPointPolar
setRadius(double)QwtPointPolarinline
toPoint() const QwtPointPolar
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_point_polar.html b/ThirdParty/Qwt/doc/html/class_qwt_point_polar.html new file mode 100644 index 0000000000..505ab54675 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_point_polar.html @@ -0,0 +1,388 @@ + + + + + + +Qwt User's Guide: QwtPointPolar Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtPointPolar Class Reference
+
+
+ +

A point in polar coordinates. + More...

+ +

#include <qwt_point_polar.h>

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 QwtPointPolar ()
 
 QwtPointPolar (double azimuth, double radius)
 
 QwtPointPolar (const QwtPointPolar &)
 
 QwtPointPolar (const QPointF &)
 
void setPoint (const QPointF &)
 
QPointF toPoint () const
 
+bool isValid () const
 Returns true if radius() >= 0.0.
 
+bool isNull () const
 Returns true if radius() >= 0.0.
 
+double radius () const
 Returns the radius.
 
+double azimuth () const
 Returns the azimuth.
 
+double & rRadius ()
 Returns the radius.
 
+double & rAzimuth ()
 Returns the azimuth.
 
+void setRadius (double)
 Sets the radius to radius.
 
+void setAzimuth (double)
 Sets the atimuth to atimuth.
 
bool operator== (const QwtPointPolar &) const
 Compare 2 points. More...
 
bool operator!= (const QwtPointPolar &) const
 
QwtPointPolar normalized () const
 
+

Detailed Description

+

A point in polar coordinates.

+

In polar coordinates a point is determined by an angle and a distance. See http://en.wikipedia.org/wiki/Polar_coordinate_system

+

Constructor & Destructor Documentation

+ +
+
+ + + + + +
+ + + + + + + +
QwtPointPolar::QwtPointPolar ()
+
+inline
+
+

Constructs a null point, with a radius and azimuth set to 0.0.

+
See Also
QPointF::isNull()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
QwtPointPolar::QwtPointPolar (double azimuth,
double radius 
)
+
+inline
+
+

Constructs a point with coordinates specified by radius and azimuth.

+
Parameters
+ + + +
azimuthAzimuth
radiusRadius
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
QwtPointPolar::QwtPointPolar (const QwtPointPolarother)
+
+inline
+
+

Constructs a point using the values of the point specified.

+
Parameters
+ + +
otherOther point
+
+
+ +
+
+ +
+
+ + + + + + + + +
QwtPointPolar::QwtPointPolar (const QPointF & p)
+
+

Convert and assign values from a point in Cartesian coordinates

+
Parameters
+ + +
pPoint in Cartesian coordinates
+
+
+
See Also
setPoint(), toPoint()
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + + + +
QwtPointPolar QwtPointPolar::normalized () const
+
+

Normalize radius and azimuth

+

When the radius is < 0.0 it is set to 0.0. The azimuth is a value >= 0.0 and < 2 * M_PI.

+
Returns
Normalized point
+ +
+
+ +
+
+ + + + + + + + +
bool QwtPointPolar::operator!= (const QwtPointPolarother) const
+
+

Compare 2 points

+

Two points are equal to each other if radius and azimuth-coordinates are the same. Points are not equal, when the azimuth differs, but other.azimuth() == azimuth() % (2 * PI).

+
Returns
True if the point is not equal to other; otherwise return false.
+
See Also
normalized()
+ +
+
+ +
+
+ + + + + + + + +
bool QwtPointPolar::operator== (const QwtPointPolarother) const
+
+ +

Compare 2 points.

+

Two points are equal to each other if radius and azimuth-coordinates are the same. Points are not equal, when the azimuth differs, but other.azimuth() == azimuth() % (2 * PI).

+
Returns
True if the point is equal to other; otherwise return false.
+
See Also
normalized()
+ +
+
+ +
+
+ + + + + + + + +
void QwtPointPolar::setPoint (const QPointF & p)
+
+

Convert and assign values from a point in Cartesian coordinates

+
Parameters
+ + +
pPoint in Cartesian coordinates
+
+
+ +
+
+ +
+
+ + + + + + + +
QPointF QwtPointPolar::toPoint () const
+
+

Convert and return values in Cartesian coordinates

+
Returns
Converted point in Cartesian coordinates
+
Note
Invalid or null points will be returned as QPointF(0.0, 0.0)
+
See Also
isValid(), isNull()
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_point_series_data-members.html b/ThirdParty/Qwt/doc/html/class_qwt_point_series_data-members.html new file mode 100644 index 0000000000..18ac1a8d36 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_point_series_data-members.html @@ -0,0 +1,113 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtPointSeriesData Member List
+
+
+ +

This is the complete list of members for QwtPointSeriesData, including all inherited members.

+ + + + + + + + + + + + + + +
boundingRect() const QwtPointSeriesDatavirtual
d_boundingRectQwtSeriesData< QPointF >mutableprotected
d_samplesQwtArraySeriesData< QPointF >protected
QwtArraySeriesData()QwtArraySeriesData< QPointF >
QwtArraySeriesData(const QVector< QPointF > &samples)QwtArraySeriesData< QPointF >
QwtPointSeriesData(const QVector< QPointF > &=QVector< QPointF >())QwtPointSeriesData
QwtSeriesData()QwtSeriesData< QPointF >
sample(size_t index) constQwtArraySeriesData< QPointF >virtual
samples() constQwtArraySeriesData< QPointF >
setRectOfInterest(const QRectF &rect)QwtSeriesData< QPointF >virtual
setSamples(const QVector< QPointF > &samples)QwtArraySeriesData< QPointF >
size() constQwtArraySeriesData< QPointF >virtual
~QwtSeriesData()QwtSeriesData< QPointF >virtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_point_series_data.html b/ThirdParty/Qwt/doc/html/class_qwt_point_series_data.html new file mode 100644 index 0000000000..bc350f4599 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_point_series_data.html @@ -0,0 +1,211 @@ + + + + + + +Qwt User's Guide: QwtPointSeriesData Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtPointSeriesData Class Reference
+
+
+ +

Interface for iterating over an array of points. + More...

+ +

#include <qwt_series_data.h>

+
+Inheritance diagram for QwtPointSeriesData:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 QwtPointSeriesData (const QVector< QPointF > &=QVector< QPointF >())
 
virtual QRectF boundingRect () const
 Calculate the bounding rectangle. More...
 
- Public Member Functions inherited from QwtArraySeriesData< QPointF >
QwtArraySeriesData ()
 Constructor.
 
 QwtArraySeriesData (const QVector< QPointF > &samples)
 
void setSamples (const QVector< QPointF > &samples)
 
const QVector< QPointF > samples () const
 
virtual size_t size () const
 
virtual QPointF sample (size_t index) const
 
- Public Member Functions inherited from QwtSeriesData< QPointF >
QwtSeriesData ()
 Constructor.
 
+virtual ~QwtSeriesData ()
 Destructor.
 
virtual void setRectOfInterest (const QRectF &rect)
 
+ + + + + +

+Additional Inherited Members

- Protected Attributes inherited from QwtArraySeriesData< QPointF >
+QVector< QPointF > d_samples
 Vector of samples.
 
+

Detailed Description

+

Interface for iterating over an array of points.

+

Constructor & Destructor Documentation

+ +
+
+ + + + + + + + +
QwtPointSeriesData::QwtPointSeriesData (const QVector< QPointF > & samples = QVector<QPointF>())
+
+

Constructor

+
Parameters
+ + +
samplesSamples
+
+
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + +
QRectF QwtPointSeriesData::boundingRect () const
+
+virtual
+
+ +

Calculate the bounding rectangle.

+

The bounding rectangle is calculated once by iterating over all points and is stored for all following requests.

+
Returns
Bounding rectangle
+ +

Implements QwtSeriesData< QPointF >.

+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_point_series_data__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_point_series_data__inherit__graph.map new file mode 100644 index 0000000000..90ebd8cc71 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_point_series_data__inherit__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_point_series_data__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_point_series_data__inherit__graph.md5 new file mode 100644 index 0000000000..fca41adf91 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_point_series_data__inherit__graph.md5 @@ -0,0 +1 @@ +1791698182335fbabbd92aff85571c72 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_point_series_data__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_point_series_data__inherit__graph.png new file mode 100644 index 0000000000..25e8f0d23d Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_point_series_data__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_power_transform-members.html b/ThirdParty/Qwt/doc/html/class_qwt_power_transform-members.html new file mode 100644 index 0000000000..1145ec2dea --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_power_transform-members.html @@ -0,0 +1,108 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtPowerTransform Member List
+
+
+ +

This is the complete list of members for QwtPowerTransform, including all inherited members.

+ + + + + + + + + +
bounded(double value) const QwtTransformvirtual
copy() const QwtPowerTransformvirtual
invTransform(double value) const QwtPowerTransformvirtual
QwtPowerTransform(double exponent)QwtPowerTransform
QwtTransform()QwtTransform
transform(double value) const QwtPowerTransformvirtual
~QwtPowerTransform()QwtPowerTransformvirtual
~QwtTransform()QwtTransformvirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_power_transform.html b/ThirdParty/Qwt/doc/html/class_qwt_power_transform.html new file mode 100644 index 0000000000..cb13b1a654 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_power_transform.html @@ -0,0 +1,259 @@ + + + + + + +Qwt User's Guide: QwtPowerTransform Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtPowerTransform Class Reference
+
+
+ +

A transformation using pow() + More...

+ +

#include <qwt_transform.h>

+
+Inheritance diagram for QwtPowerTransform:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 QwtPowerTransform (double exponent)
 
+virtual ~QwtPowerTransform ()
 Destructor.
 
virtual double transform (double value) const
 
virtual double invTransform (double value) const
 
virtual QwtTransformcopy () const
 
- Public Member Functions inherited from QwtTransform
QwtTransform ()
 Constructor.
 
+virtual ~QwtTransform ()
 Destructor.
 
virtual double bounded (double value) const
 
+

Detailed Description

+

A transformation using pow()

+

QwtPowerTransform preserves the sign of a value. F.e. a transformation with a factor of 2 transforms a value of -3 to -9 and v.v. Thus QwtPowerTransform can be used for scales including negative values.

+

Constructor & Destructor Documentation

+ +
+
+ + + + + + + + +
QwtPowerTransform::QwtPowerTransform (double exponent)
+
+

Constructor

+
Parameters
+ + +
exponentExponent
+
+
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + +
QwtTransform * QwtPowerTransform::copy () const
+
+virtual
+
+
Returns
Clone of the transformation
+ +

Implements QwtTransform.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
double QwtPowerTransform::invTransform (double value) const
+
+virtual
+
+
Parameters
+ + +
valueValue to be transformed
+
+
+
Returns
Inverse exponentiation preserving the sign
+ +

Implements QwtTransform.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
double QwtPowerTransform::transform (double value) const
+
+virtual
+
+
Parameters
+ + +
valueValue to be transformed
+
+
+
Returns
Exponentiation preserving the sign
+ +

Implements QwtTransform.

+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_power_transform__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_power_transform__inherit__graph.map new file mode 100644 index 0000000000..094ac22f72 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_power_transform__inherit__graph.map @@ -0,0 +1,3 @@ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_power_transform__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_power_transform__inherit__graph.md5 new file mode 100644 index 0000000000..bccb6d6991 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_power_transform__inherit__graph.md5 @@ -0,0 +1 @@ +cd9f70d12aba8c906f8d5f156ed1d796 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_power_transform__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_power_transform__inherit__graph.png new file mode 100644 index 0000000000..8893632edd Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_power_transform__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_raster_data-members.html b/ThirdParty/Qwt/doc/html/class_qwt_raster_data-members.html new file mode 100644 index 0000000000..efe4876402 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_raster_data-members.html @@ -0,0 +1,114 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtRasterData Member List
+
+
+ +

This is the complete list of members for QwtRasterData, including all inherited members.

+ + + + + + + + + + + + + + + +
ConrecFlag enum nameQwtRasterData
ConrecFlags typedefQwtRasterData
ContourLines typedefQwtRasterData
contourLines(const QRectF &rect, const QSize &raster, const QList< double > &levels, ConrecFlags) const QwtRasterDatavirtual
discardRaster()QwtRasterDatavirtual
IgnoreAllVerticesOnLevel enum valueQwtRasterData
IgnoreOutOfRange enum valueQwtRasterData
initRaster(const QRectF &, const QSize &raster)QwtRasterDatavirtual
interval(Qt::Axis) const QwtRasterDatainline
pixelHint(const QRectF &) const QwtRasterDatavirtual
QwtRasterData()QwtRasterData
setInterval(Qt::Axis, const QwtInterval &)QwtRasterDatavirtual
value(double x, double y) const =0QwtRasterDatapure virtual
~QwtRasterData()QwtRasterDatavirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_raster_data.html b/ThirdParty/Qwt/doc/html/class_qwt_raster_data.html new file mode 100644 index 0000000000..2428c3a7c9 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_raster_data.html @@ -0,0 +1,473 @@ + + + + + + +Qwt User's Guide: QwtRasterData Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtRasterData Class Referenceabstract
+
+
+ +

QwtRasterData defines an interface to any type of raster data. + More...

+ +

#include <qwt_raster_data.h>

+
+Inheritance diagram for QwtRasterData:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + + + + +

+Public Types

enum  ConrecFlag { IgnoreAllVerticesOnLevel = 0x01, +IgnoreOutOfRange = 0x02 + }
 Flags to modify the contour algorithm. More...
 
+typedef QMap< double, QPolygonF > ContourLines
 Contour lines.
 
+typedef QFlags< ConrecFlagConrecFlags
 Flags to modify the contour algorithm.
 
+ + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

QwtRasterData ()
 Constructor.
 
+virtual ~QwtRasterData ()
 Destructor.
 
virtual void setInterval (Qt::Axis, const QwtInterval &)
 
const QwtIntervalinterval (Qt::Axis) const
 
virtual QRectF pixelHint (const QRectF &) const
 Pixel hint. More...
 
virtual void initRaster (const QRectF &, const QSize &raster)
 Initialize a raster. More...
 
virtual void discardRaster ()
 Discard a raster. More...
 
virtual double value (double x, double y) const =0
 
virtual ContourLines contourLines (const QRectF &rect, const QSize &raster, const QList< double > &levels, ConrecFlags) const
 
+

Detailed Description

+

QwtRasterData defines an interface to any type of raster data.

+

QwtRasterData is an abstract interface, that is used by QwtPlotRasterItem to find the values at the pixels of its raster.

+

Often a raster item is used to display values from a matrix. Then the derived raster data class needs to implement some sort of resampling, that maps the raster of the matrix into the requested raster of the raster item ( depending on resolution and scales of the canvas ).

+

Member Enumeration Documentation

+ +
+
+ + + + +
enum QwtRasterData::ConrecFlag
+
+ +

Flags to modify the contour algorithm.

+ + + +
Enumerator
IgnoreAllVerticesOnLevel  +

Ignore all vertices on the same level.

+
IgnoreOutOfRange  +

Ignore all values, that are out of range.

+
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
QwtRasterData::ContourLines QwtRasterData::contourLines (const QRectF & rect,
const QSize & raster,
const QList< double > & levels,
ConrecFlags flags 
) const
+
+virtual
+
+

Calculate contour lines

+
Parameters
+ + + + + +
rectBounding rectangle for the contour lines
rasterNumber of data pixels of the raster data
levelsList of limits, where to insert contour lines
flagsFlags to customize the contouring algorithm
+
+
+
Returns
Calculated contour lines
+

An adaption of CONREC, a simple contouring algorithm. http://local.wasp.uwa.edu.au/~pbourke/papers/conrec/

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void QwtRasterData::discardRaster ()
+
+virtual
+
+ +

Discard a raster.

+

After the composition of an image QwtPlotSpectrogram calls discardRaster().

+

The default implementation does nothing, but if data has been loaded in initRaster(), it could deleted now.

+
See Also
initRaster(), value()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void QwtRasterData::initRaster (const QRectF & area,
const QSize & raster 
)
+
+virtual
+
+ +

Initialize a raster.

+

Before the composition of an image QwtPlotSpectrogram calls initRaster(), announcing the area and its resolution that will be requested.

+

The default implementation does nothing, but for data sets that are stored in files, it might be good idea to reimplement initRaster(), where the data is resampled and loaded into memory.

+
Parameters
+ + + +
areaArea of the raster
rasterNumber of horizontal and vertical pixels
+
+
+
See Also
initRaster(), value()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
const QwtInterval & QwtRasterData::interval (Qt::Axis axis) const
+
+inline
+
+
Returns
Bounding interval for a axis
+
See Also
setInterval
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
QRectF QwtRasterData::pixelHint (const QRectF & area) const
+
+virtual
+
+ +

Pixel hint.

+

pixelHint() returns the geometry of a pixel, that can be used to calculate the resolution and alignment of the plot item, that is representing the data.

+

Width and height of the hint need to be the horizontal and vertical distances between 2 neighbored points. The center of the hint has to be the position of any point ( it doesn't matter which one ).

+

An empty hint indicates, that there are values for any detail level.

+

Limiting the resolution of the image might significantly improve the performance and heavily reduce the amount of memory when rendering a QImage from the raster data.

+

The default implementation returns an empty rectangle recommending to render in target device ( f.e. screen ) resolution.

+
Parameters
+ + +
areaIn most implementations the resolution of the data doesn't depend on the requested area.
+
+
+
Returns
Bounding rectangle of a pixel
+ +

Reimplemented in QwtMatrixRasterData.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void QwtRasterData::setInterval (Qt::Axis axis,
const QwtIntervalinterval 
)
+
+virtual
+
+

Set the bounding interval for the x, y or z coordinates.

+
Parameters
+ + + +
axisAxis
intervalBounding interval
+
+
+
See Also
interval()
+ +

Reimplemented in QwtMatrixRasterData.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
virtual double QwtRasterData::value (double x,
double y 
) const
+
+pure virtual
+
+
Returns
the value at a raster position
+
Parameters
+ + + +
xX value in plot coordinates
yY value in plot coordinates
+
+
+ +

Implemented in QwtMatrixRasterData.

+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_raster_data__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_raster_data__inherit__graph.map new file mode 100644 index 0000000000..ffe905af28 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_raster_data__inherit__graph.map @@ -0,0 +1,3 @@ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_raster_data__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_raster_data__inherit__graph.md5 new file mode 100644 index 0000000000..3c7c8a0fe0 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_raster_data__inherit__graph.md5 @@ -0,0 +1 @@ +e61f7475608efbb3c6297c39c4c59689 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_raster_data__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_raster_data__inherit__graph.png new file mode 100644 index 0000000000..8728c34041 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_raster_data__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_rich_text_engine-members.html b/ThirdParty/Qwt/doc/html/class_qwt_rich_text_engine-members.html new file mode 100644 index 0000000000..696891b97b --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_rich_text_engine-members.html @@ -0,0 +1,108 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtRichTextEngine Member List
+
+
+ +

This is the complete list of members for QwtRichTextEngine, including all inherited members.

+ + + + + + + + + +
draw(QPainter *painter, const QRectF &rect, int flags, const QString &text) const QwtRichTextEnginevirtual
heightForWidth(const QFont &font, int flags, const QString &text, double width) const QwtRichTextEnginevirtual
mightRender(const QString &) const QwtRichTextEnginevirtual
QwtRichTextEngine()QwtRichTextEngine
QwtTextEngine()QwtTextEngineprotected
textMargins(const QFont &, const QString &, double &left, double &right, double &top, double &bottom) const QwtRichTextEnginevirtual
textSize(const QFont &font, int flags, const QString &text) const QwtRichTextEnginevirtual
~QwtTextEngine()QwtTextEnginevirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_rich_text_engine.html b/ThirdParty/Qwt/doc/html/class_qwt_rich_text_engine.html new file mode 100644 index 0000000000..d3a665e4cf --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_rich_text_engine.html @@ -0,0 +1,420 @@ + + + + + + +Qwt User's Guide: QwtRichTextEngine Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtRichTextEngine Class Reference
+
+
+ +

A text engine for Qt rich texts. + More...

+ +

#include <qwt_text_engine.h>

+
+Inheritance diagram for QwtRichTextEngine:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + + + + + + + + + + + + +

+Public Member Functions

QwtRichTextEngine ()
 Constructor.
 
virtual double heightForWidth (const QFont &font, int flags, const QString &text, double width) const
 
virtual QSizeF textSize (const QFont &font, int flags, const QString &text) const
 
virtual void draw (QPainter *painter, const QRectF &rect, int flags, const QString &text) const
 
virtual bool mightRender (const QString &) const
 
virtual void textMargins (const QFont &, const QString &, double &left, double &right, double &top, double &bottom) const
 
- Public Member Functions inherited from QwtTextEngine
+virtual ~QwtTextEngine ()
 Destructor.
 
+ + + + + +

+Additional Inherited Members

- Protected Member Functions inherited from QwtTextEngine
QwtTextEngine ()
 Constructor.
 
+

Detailed Description

+

A text engine for Qt rich texts.

+

QwtRichTextEngine renders Qt rich texts using the classes of the Scribe framework of Qt.

+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void QwtRichTextEngine::draw (QPainter * painter,
const QRectF & rect,
int flags,
const QString & text 
) const
+
+virtual
+
+

Draw the text in a clipping rectangle

+
Parameters
+ + + + + +
painterPainter
rectClipping rectangle
flagsBitwise OR of the flags like in for QPainter::drawText()
textText to be rendered
+
+
+ +

Implements QwtTextEngine.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
double QwtRichTextEngine::heightForWidth (const QFont & font,
int flags,
const QString & text,
double width 
) const
+
+virtual
+
+

Find the height for a given width

+
Parameters
+ + + + + +
fontFont of the text
flagsBitwise OR of the flags used like in QPainter::drawText()
textText to be rendered
widthWidth
+
+
+
Returns
Calculated height
+ +

Implements QwtTextEngine.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool QwtRichTextEngine::mightRender (const QString & text) const
+
+virtual
+
+

Test if a string can be rendered by this text engine

+
Parameters
+ + +
textText to be tested
+
+
+
Returns
Qt::mightBeRichText(text);
+ +

Implements QwtTextEngine.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void QwtRichTextEngine::textMargins (const QFont & ,
const QString & ,
double & left,
double & right,
double & top,
double & bottom 
) const
+
+virtual
+
+

Return margins around the texts

+
Parameters
+ + + + + +
leftReturn 0
rightReturn 0
topReturn 0
bottomReturn 0
+
+
+ +

Implements QwtTextEngine.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
QSizeF QwtRichTextEngine::textSize (const QFont & font,
int flags,
const QString & text 
) const
+
+virtual
+
+

Returns the size, that is needed to render text

+
Parameters
+ + + + +
fontFont of the text
flagsBitwise OR of the flags used like in QPainter::drawText()
textText to be rendered
+
+
+
Returns
Caluclated size
+ +

Implements QwtTextEngine.

+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_rich_text_engine__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_rich_text_engine__inherit__graph.map new file mode 100644 index 0000000000..b39f355b2a --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_rich_text_engine__inherit__graph.map @@ -0,0 +1,3 @@ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_rich_text_engine__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_rich_text_engine__inherit__graph.md5 new file mode 100644 index 0000000000..416577be90 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_rich_text_engine__inherit__graph.md5 @@ -0,0 +1 @@ +c267cbdf3ad463ef1e17ab20cf5c2b84 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_rich_text_engine__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_rich_text_engine__inherit__graph.png new file mode 100644 index 0000000000..5d0ec9884f Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_rich_text_engine__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_round_scale_draw-members.html b/ThirdParty/Qwt/doc/html/class_qwt_round_scale_draw-members.html new file mode 100644 index 0000000000..2dd7f5ca1e --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_round_scale_draw-members.html @@ -0,0 +1,139 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtRoundScaleDraw Member List
+
+
+ +

This is the complete list of members for QwtRoundScaleDraw, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Backbone enum valueQwtAbstractScaleDraw
center() const QwtRoundScaleDraw
draw(QPainter *, const QPalette &) const QwtAbstractScaleDrawvirtual
drawBackbone(QPainter *) const QwtRoundScaleDrawprotectedvirtual
drawLabel(QPainter *, double val) const QwtRoundScaleDrawprotectedvirtual
drawTick(QPainter *, double val, double len) const QwtRoundScaleDrawprotectedvirtual
enableComponent(ScaleComponent, bool enable=true)QwtAbstractScaleDraw
extent(const QFont &) const QwtRoundScaleDrawvirtual
hasComponent(ScaleComponent) const QwtAbstractScaleDraw
invalidateCache()QwtAbstractScaleDrawprotected
label(double) const QwtAbstractScaleDrawvirtual
Labels enum valueQwtAbstractScaleDraw
maxTickLength() const QwtAbstractScaleDraw
minimumExtent() const QwtAbstractScaleDraw
moveCenter(double x, double y)QwtRoundScaleDrawinline
moveCenter(const QPointF &)QwtRoundScaleDraw
penWidth() const QwtAbstractScaleDraw
QwtAbstractScaleDraw()QwtAbstractScaleDraw
QwtRoundScaleDraw()QwtRoundScaleDraw
radius() const QwtRoundScaleDraw
ScaleComponent enum nameQwtAbstractScaleDraw
ScaleComponents typedefQwtAbstractScaleDraw
scaleDiv() const QwtAbstractScaleDraw
scaleMap() const QwtAbstractScaleDraw
scaleMap()QwtAbstractScaleDraw
setAngleRange(double angle1, double angle2)QwtRoundScaleDraw
setMinimumExtent(double)QwtAbstractScaleDraw
setPenWidth(int width)QwtAbstractScaleDraw
setRadius(double radius)QwtRoundScaleDraw
setScaleDiv(const QwtScaleDiv &s)QwtAbstractScaleDraw
setSpacing(double margin)QwtAbstractScaleDraw
setTickLength(QwtScaleDiv::TickType, double length)QwtAbstractScaleDraw
setTransformation(QwtTransform *)QwtAbstractScaleDraw
spacing() const QwtAbstractScaleDraw
tickLabel(const QFont &, double value) const QwtAbstractScaleDrawprotected
tickLength(QwtScaleDiv::TickType) const QwtAbstractScaleDraw
Ticks enum valueQwtAbstractScaleDraw
~QwtAbstractScaleDraw()QwtAbstractScaleDrawvirtual
~QwtRoundScaleDraw()QwtRoundScaleDrawvirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_round_scale_draw.html b/ThirdParty/Qwt/doc/html/class_qwt_round_scale_draw.html new file mode 100644 index 0000000000..66135df8ca --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_round_scale_draw.html @@ -0,0 +1,526 @@ + + + + + + +Qwt User's Guide: QwtRoundScaleDraw Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtRoundScaleDraw Class Reference
+
+
+ +

A class for drawing round scales. + More...

+ +

#include <qwt_round_scale_draw.h>

+
+Inheritance diagram for QwtRoundScaleDraw:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 QwtRoundScaleDraw ()
 Constructor. More...
 
+virtual ~QwtRoundScaleDraw ()
 Destructor.
 
void setRadius (double radius)
 
double radius () const
 
+void moveCenter (double x, double y)
 Move the center of the scale draw, leaving the radius unchanged.
 
void moveCenter (const QPointF &)
 
+QPointF center () const
 Get the center of the scale.
 
void setAngleRange (double angle1, double angle2)
 Adjust the baseline circle segment for round scales. More...
 
virtual double extent (const QFont &) const
 
- Public Member Functions inherited from QwtAbstractScaleDraw
 QwtAbstractScaleDraw ()
 Constructor. More...
 
+virtual ~QwtAbstractScaleDraw ()
 Destructor.
 
void setScaleDiv (const QwtScaleDiv &s)
 
const QwtScaleDivscaleDiv () const
 
void setTransformation (QwtTransform *)
 
const QwtScaleMapscaleMap () const
 
QwtScaleMapscaleMap ()
 
void enableComponent (ScaleComponent, bool enable=true)
 
bool hasComponent (ScaleComponent) const
 
void setTickLength (QwtScaleDiv::TickType, double length)
 
double tickLength (QwtScaleDiv::TickType) const
 
double maxTickLength () const
 
void setSpacing (double margin)
 Set the spacing between tick and labels. More...
 
double spacing () const
 Get the spacing. More...
 
void setPenWidth (int width)
 Specify the width of the scale pen. More...
 
int penWidth () const
 
virtual void draw (QPainter *, const QPalette &) const
 Draw the scale. More...
 
virtual QwtText label (double) const
 Convert a value into its representing label. More...
 
void setMinimumExtent (double)
 Set a minimum for the extent. More...
 
double minimumExtent () const
 
+ + + + + + + + + + + + + +

+Protected Member Functions

virtual void drawTick (QPainter *, double val, double len) const
 
virtual void drawBackbone (QPainter *) const
 
virtual void drawLabel (QPainter *, double val) const
 
- Protected Member Functions inherited from QwtAbstractScaleDraw
void invalidateCache ()
 
const QwtTexttickLabel (const QFont &, double value) const
 Convert a value into its representing label and cache it. More...
 
+ + + + + + + +

+Additional Inherited Members

- Public Types inherited from QwtAbstractScaleDraw
enum  ScaleComponent { Backbone = 0x01, +Ticks = 0x02, +Labels = 0x04 + }
 
+typedef QFlags< ScaleComponentScaleComponents
 Scale components.
 
+

Detailed Description

+

A class for drawing round scales.

+

QwtRoundScaleDraw can be used to draw round scales. The circle segment can be adjusted by setAngleRange(). The geometry of the scale can be specified with moveCenter() and setRadius().

+

After a scale division has been specified as a QwtScaleDiv object using QwtAbstractScaleDraw::setScaleDiv(const QwtScaleDiv &s), the scale can be drawn with the QwtAbstractScaleDraw::draw() member.

+

Constructor & Destructor Documentation

+ +
+
+ + + + + + + +
QwtRoundScaleDraw::QwtRoundScaleDraw ()
+
+ +

Constructor.

+

The range of the scale is initialized to [0, 100], The center is set to (50, 50) with a radius of 50. The angle range is set to [-135, 135].

+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + + +
void QwtRoundScaleDraw::drawBackbone (QPainter * painter) const
+
+protectedvirtual
+
+

Draws the baseline of the scale

+
Parameters
+ + +
painterPainter
+
+
+
See Also
drawTick(), drawLabel()
+ +

Implements QwtAbstractScaleDraw.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void QwtRoundScaleDraw::drawLabel (QPainter * painter,
double value 
) const
+
+protectedvirtual
+
+

Draws the label for a major scale tick

+
Parameters
+ + + +
painterPainter
valueValue
+
+
+
See Also
drawTick(), drawBackbone()
+ +

Implements QwtAbstractScaleDraw.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
void QwtRoundScaleDraw::drawTick (QPainter * painter,
double value,
double len 
) const
+
+protectedvirtual
+
+

Draw a tick

+
Parameters
+ + + + +
painterPainter
valueValue of the tick
lenLenght of the tick
+
+
+
See Also
drawBackbone(), drawLabel()
+ +

Implements QwtAbstractScaleDraw.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
double QwtRoundScaleDraw::extent (const QFont & font) const
+
+virtual
+
+

Calculate the extent of the scale

+

The extent is the distance between the baseline to the outermost pixel of the scale draw. radius() + extent() is an upper limit for the radius of the bounding circle.

+
Parameters
+ + +
fontFont used for painting the labels
+
+
+
Returns
Calculated extent
+
See Also
setMinimumExtent(), minimumExtent()
+
Warning
The implemented algorithm is not too smart and calculates only an upper limit, that might be a few pixels too large
+ +

Implements QwtAbstractScaleDraw.

+ +
+
+ +
+
+ + + + + + + + +
void QwtRoundScaleDraw::moveCenter (const QPointF & center)
+
+

Move the center of the scale draw, leaving the radius unchanged

+
Parameters
+ + +
centerNew center
+
+
+
See Also
setRadius()
+ +
+
+ +
+
+ + + + + + + +
double QwtRoundScaleDraw::radius () const
+
+

Get the radius

+

Radius is the radius of the backbone without ticks and labels.

+
Returns
Radius of the scale
+
See Also
setRadius(), extent()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtRoundScaleDraw::setAngleRange (double angle1,
double angle2 
)
+
+ +

Adjust the baseline circle segment for round scales.

+

The baseline will be drawn from min(angle1,angle2) to max(angle1, angle2). The default setting is [ -135, 135 ]. An angle of 0 degrees corresponds to the 12 o'clock position, and positive angles count in a clockwise direction.

+
Parameters
+ + + +
angle1
angle2boundaries of the angle interval in degrees.
+
+
+
Warning
    +
  • +The angle range is limited to [-360, 360] degrees. Angles exceeding this range will be clipped.
  • +
  • +For angles more or equal than 360 degrees above or below min(angle1, angle2), scale marks will not be drawn.
  • +
  • +If you need a counterclockwise scale, use QwtScaleDiv::setInterval()
  • +
+
+ +
+
+ +
+
+ + + + + + + + +
void QwtRoundScaleDraw::setRadius (double radius)
+
+

Change of radius the scale

+

Radius is the radius of the backbone without ticks and labels.

+
Parameters
+ + +
radiusNew Radius
+
+
+
See Also
moveCenter()
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_round_scale_draw__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_round_scale_draw__inherit__graph.map new file mode 100644 index 0000000000..382aaef275 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_round_scale_draw__inherit__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_round_scale_draw__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_round_scale_draw__inherit__graph.md5 new file mode 100644 index 0000000000..8186c96990 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_round_scale_draw__inherit__graph.md5 @@ -0,0 +1 @@ +1210f6f01b914b22a46c0c4555899c07 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_round_scale_draw__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_round_scale_draw__inherit__graph.png new file mode 100644 index 0000000000..3c15734173 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_round_scale_draw__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_sampling_thread-members.html b/ThirdParty/Qwt/doc/html/class_qwt_sampling_thread-members.html new file mode 100644 index 0000000000..d6fbc6478e --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_sampling_thread-members.html @@ -0,0 +1,108 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtSamplingThread Member List
+
+
+ +

This is the complete list of members for QwtSamplingThread, including all inherited members.

+ + + + + + + + + +
elapsed() const QwtSamplingThread
interval() const QwtSamplingThread
QwtSamplingThread(QObject *parent=NULL)QwtSamplingThreadexplicitprotected
run()QwtSamplingThreadprotectedvirtual
sample(double elapsed)=0QwtSamplingThreadprotectedpure virtual
setInterval(double interval)QwtSamplingThreadslot
stop()QwtSamplingThreadslot
~QwtSamplingThread()QwtSamplingThreadvirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_sampling_thread.html b/ThirdParty/Qwt/doc/html/class_qwt_sampling_thread.html new file mode 100644 index 0000000000..7b3d81eb4e --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_sampling_thread.html @@ -0,0 +1,297 @@ + + + + + + +Qwt User's Guide: QwtSamplingThread Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtSamplingThread Class Referenceabstract
+
+
+ +

A thread collecting samples at regular intervals. + More...

+ +

#include <qwt_sampling_thread.h>

+
+Inheritance diagram for QwtSamplingThread:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + +

+Public Slots

void setInterval (double interval)
 
void stop ()
 
+ + + + + + + + +

+Public Member Functions

+virtual ~QwtSamplingThread ()
 Destructor.
 
double interval () const
 
double elapsed () const
 
+ + + + + + + + +

+Protected Member Functions

QwtSamplingThread (QObject *parent=NULL)
 Constructor.
 
virtual void run ()
 
virtual void sample (double elapsed)=0
 
+

Detailed Description

+

A thread collecting samples at regular intervals.

+

Continuous signals are converted into a discrete signal by collecting samples at regular intervals. A discrete signal can be displayed by a QwtPlotSeriesItem on a QwtPlot widget.

+

QwtSamplingThread starts a thread calling periodically sample(), to collect and store ( or emit ) a single sample.

+
See Also
QwtPlotCurve, QwtPlotSeriesItem
+

Member Function Documentation

+ +
+
+ + + + + + + +
double QwtSamplingThread::elapsed () const
+
+
Returns
Time (in ms) since the thread was started
+
See Also
QThread::start(), run()
+ +
+
+ +
+
+ + + + + + + +
double QwtSamplingThread::interval () const
+
+
Returns
Interval (in ms), between 2 calls of sample()
+
See Also
setInterval()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void QwtSamplingThread::run ()
+
+protectedvirtual
+
+

Loop collecting samples started from QThread::start()

+
See Also
stop()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
virtual void QwtSamplingThread::sample (double elapsed)
+
+protectedpure virtual
+
+

Collect a sample

+
Parameters
+ + +
elapsedTime since the thread was started in milliseconds
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtSamplingThread::setInterval (double interval)
+
+slot
+
+

Change the interval (in ms), when sample() is called. The default interval is 1000.0 ( = 1s )

+
Parameters
+ + +
intervalInterval
+
+
+
See Also
interval()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void QwtSamplingThread::stop ()
+
+slot
+
+

Terminate the collecting thread

+
See Also
QThread::start(), run()
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_sampling_thread__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_sampling_thread__inherit__graph.map new file mode 100644 index 0000000000..27385b89ce --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_sampling_thread__inherit__graph.map @@ -0,0 +1,2 @@ + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_sampling_thread__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_sampling_thread__inherit__graph.md5 new file mode 100644 index 0000000000..2e5e263864 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_sampling_thread__inherit__graph.md5 @@ -0,0 +1 @@ +9b1f4580198413c2a43938640c733d6b \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_sampling_thread__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_sampling_thread__inherit__graph.png new file mode 100644 index 0000000000..d8e9284b5e Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_sampling_thread__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_scale_arithmetic-members.html b/ThirdParty/Qwt/doc/html/class_qwt_scale_arithmetic-members.html new file mode 100644 index 0000000000..e2c5fd2ed7 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_scale_arithmetic-members.html @@ -0,0 +1,104 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtScaleArithmetic Member List
+
+
+ +

This is the complete list of members for QwtScaleArithmetic, including all inherited members.

+ + + + + +
ceilEps(double value, double intervalSize)QwtScaleArithmeticstatic
divideEps(double interval, double steps)QwtScaleArithmeticstatic
divideInterval(double interval, int numSteps, uint base)QwtScaleArithmeticstatic
floorEps(double value, double intervalSize)QwtScaleArithmeticstatic
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_scale_arithmetic.html b/ThirdParty/Qwt/doc/html/class_qwt_scale_arithmetic.html new file mode 100644 index 0000000000..63fcf0507d --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_scale_arithmetic.html @@ -0,0 +1,304 @@ + + + + + + +Qwt User's Guide: QwtScaleArithmetic Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtScaleArithmetic Class Reference
+
+
+ +

Arithmetic including a tolerance. + More...

+ +

#include <qwt_scale_engine.h>

+ + + + + + + + + + + +

+Static Public Member Functions

static double ceilEps (double value, double intervalSize)
 
static double floorEps (double value, double intervalSize)
 
static double divideEps (double interval, double steps)
 Divide an interval into steps. More...
 
static double divideInterval (double interval, int numSteps, uint base)
 
+

Detailed Description

+

Arithmetic including a tolerance.

+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
double QwtScaleArithmetic::ceilEps (double value,
double intervalSize 
)
+
+static
+
+

Ceil a value, relative to an interval

+
Parameters
+ + + +
valueValue to be ceiled
intervalSizeInterval size
+
+
+
Returns
Rounded value
+
See Also
floorEps()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
double QwtScaleArithmetic::divideEps (double intervalSize,
double numSteps 
)
+
+static
+
+ +

Divide an interval into steps.

+

$stepSize = (intervalSize - intervalSize * 10e^{-6}) / numSteps$

+
Parameters
+ + + +
intervalSizeInterval size
numStepsNumber of steps
+
+
+
Returns
Step size
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
double QwtScaleArithmetic::divideInterval (double intervalSize,
int numSteps,
uint base 
)
+
+static
+
+

Calculate a step size for a given interval

+
Parameters
+ + + + +
intervalSizeInterval size
numStepsNumber of steps
baseBase for the division ( usually 10 )
+
+
+
Returns
Calculated step size
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
double QwtScaleArithmetic::floorEps (double value,
double intervalSize 
)
+
+static
+
+

Floor a value, relative to an interval

+
Parameters
+ + + +
valueValue to be floored
intervalSizeInterval size
+
+
+
Returns
Rounded value
+
See Also
floorEps()
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_scale_div-members.html b/ThirdParty/Qwt/doc/html/class_qwt_scale_div-members.html new file mode 100644 index 0000000000..0bd526942b --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_scale_div-members.html @@ -0,0 +1,128 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtScaleDiv Member List
+
+
+ +

This is the complete list of members for QwtScaleDiv, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bounded(double lowerBound, double upperBound) const QwtScaleDiv
contains(double value) const QwtScaleDiv
interval() const QwtScaleDiv
invert()QwtScaleDiv
inverted() const QwtScaleDiv
isEmpty() const QwtScaleDiv
isIncreasing() const QwtScaleDiv
lowerBound() const QwtScaleDiv
MajorTick enum valueQwtScaleDiv
MediumTick enum valueQwtScaleDiv
MinorTick enum valueQwtScaleDiv
NoTick enum valueQwtScaleDiv
NTickTypes enum valueQwtScaleDiv
operator!=(const QwtScaleDiv &) const QwtScaleDiv
operator==(const QwtScaleDiv &) const QwtScaleDiv
QwtScaleDiv(double lowerBound=0.0, double upperBound=0.0)QwtScaleDivexplicit
QwtScaleDiv(const QwtInterval &, QList< double >[NTickTypes])QwtScaleDivexplicit
QwtScaleDiv(double lowerBound, double upperBound, QList< double >[NTickTypes])QwtScaleDivexplicit
QwtScaleDiv(double lowerBound, double upperBound, const QList< double > &minorTicks, const QList< double > &mediumTicks, const QList< double > &majorTicks)QwtScaleDivexplicit
range() const QwtScaleDiv
setInterval(double lowerBound, double upperBound)QwtScaleDiv
setInterval(const QwtInterval &)QwtScaleDiv
setLowerBound(double)QwtScaleDiv
setTicks(int tickType, const QList< double > &)QwtScaleDiv
setUpperBound(double)QwtScaleDiv
ticks(int tickType) const QwtScaleDiv
TickType enum nameQwtScaleDiv
upperBound() const QwtScaleDiv
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_scale_div.html b/ThirdParty/Qwt/doc/html/class_qwt_scale_div.html new file mode 100644 index 0000000000..a4bf2bc3bc --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_scale_div.html @@ -0,0 +1,775 @@ + + + + + + +Qwt User's Guide: QwtScaleDiv Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtScaleDiv Class Reference
+
+
+ +

A class representing a scale division. + More...

+ +

#include <qwt_scale_div.h>

+ + + + + +

+Public Types

enum  TickType {
+  NoTick = -1, +MinorTick, +MediumTick, +MajorTick, +
+  NTickTypes +
+ }
 Scale tick types. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 QwtScaleDiv (double lowerBound=0.0, double upperBound=0.0)
 
 QwtScaleDiv (const QwtInterval &, QList< double >[NTickTypes])
 
 QwtScaleDiv (double lowerBound, double upperBound, QList< double >[NTickTypes])
 
 QwtScaleDiv (double lowerBound, double upperBound, const QList< double > &minorTicks, const QList< double > &mediumTicks, const QList< double > &majorTicks)
 
bool operator== (const QwtScaleDiv &) const
 Equality operator. More...
 
bool operator!= (const QwtScaleDiv &) const
 Inequality. More...
 
void setInterval (double lowerBound, double upperBound)
 
void setInterval (const QwtInterval &)
 
QwtInterval interval () const
 
void setLowerBound (double)
 
double lowerBound () const
 
void setUpperBound (double)
 
double upperBound () const
 
double range () const
 
bool contains (double value) const
 
void setTicks (int tickType, const QList< double > &)
 
QList< double > ticks (int tickType) const
 
+bool isEmpty () const
 Check if the scale division is empty( lowerBound() == upperBound() )
 
+bool isIncreasing () const
 Check if the scale division is increasing( lowerBound() <= upperBound() )
 
void invert ()
 
QwtScaleDiv inverted () const
 
QwtScaleDiv bounded (double lowerBound, double upperBound) const
 
+

Detailed Description

+

A class representing a scale division.

+

A Qwt scale is defined by its boundaries and 3 list for the positions of the major, medium and minor ticks.

+

The upperLimit() might be smaller than the lowerLimit() to indicate inverted scales.

+

Scale divisions can be calculated from a QwtScaleEngine.

+
See Also
QwtScaleEngine::divideScale(), QwtPlot::setAxisScaleDiv(), QwtAbstractSlider::setScaleDiv()
+

Member Enumeration Documentation

+ +
+
+ + + + +
enum QwtScaleDiv::TickType
+
+ +

Scale tick types.

+ + + + + + +
Enumerator
NoTick  +

No ticks.

+
MinorTick  +

Minor ticks.

+
MediumTick  +

Medium ticks.

+
MajorTick  +

Major ticks.

+
NTickTypes  +

Number of valid tick types.

+
+ +
+
+

Constructor & Destructor Documentation

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
QwtScaleDiv::QwtScaleDiv (double lowerBound = 0.0,
double upperBound = 0.0 
)
+
+explicit
+
+

Construct a division without ticks

+
Parameters
+ + + +
lowerBoundFirst boundary
upperBoundSecond boundary
+
+
+
Note
lowerBound might be greater than upperBound for inverted scales
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
QwtScaleDiv::QwtScaleDiv (const QwtIntervalinterval,
QList< double > ticks[NTickTypes] 
)
+
+explicit
+
+

Construct a scale division

+
Parameters
+ + + +
intervalInterval
ticksList of major, medium and minor ticks
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
QwtScaleDiv::QwtScaleDiv (double lowerBound,
double upperBound,
QList< double > ticks[NTickTypes] 
)
+
+explicit
+
+

Construct a scale division

+
Parameters
+ + + + +
lowerBoundFirst boundary
upperBoundSecond boundary
ticksList of major, medium and minor ticks
+
+
+
Note
lowerBound might be greater than upperBound for inverted scales
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
QwtScaleDiv::QwtScaleDiv (double lowerBound,
double upperBound,
const QList< double > & minorTicks,
const QList< double > & mediumTicks,
const QList< double > & majorTicks 
)
+
+explicit
+
+

Construct a scale division

+
Parameters
+ + + + + + +
lowerBoundFirst boundary
upperBoundSecond boundary
minorTicksList of minor ticks
mediumTicksList medium ticks
majorTicksList of major ticks
+
+
+
Note
lowerBound might be greater than upperBound for inverted scales
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + + + + + + + + + + + + + + +
QwtScaleDiv QwtScaleDiv::bounded (double lowerBound,
double upperBound 
) const
+
+

Return a scale division with an interval [lowerBound, upperBound] where all ticks outside this interval are removed

+
Parameters
+ + + +
lowerBoundLower bound
upperBoundUpper bound
+
+
+
Returns
Scale division with all ticks inside of the given interval
+
Note
lowerBound might be greater than upperBound for inverted scales
+ +
+
+ +
+
+ + + + + + + + +
bool QwtScaleDiv::contains (double value) const
+
+

Return if a value is between lowerBound() and upperBound()

+
Parameters
+ + +
valueValue
+
+
+
Returns
true/false
+ +
+
+ +
+
+ + + + + + + +
QwtInterval QwtScaleDiv::interval () const
+
+
Returns
lowerBound -> upperBound
+ +
+
+ +
+
+ + + + + + + +
void QwtScaleDiv::invert ()
+
+

Invert the scale division

+
See Also
inverted()
+ +
+
+ +
+
+ + + + + + + +
QwtScaleDiv QwtScaleDiv::inverted () const
+
+
Returns
A scale division with inverted boundaries and ticks
+
See Also
invert()
+ +
+
+ +
+
+ + + + + + + +
double QwtScaleDiv::lowerBound () const
+
+
Returns
First boundary
+
See Also
upperBound()
+ +
+
+ +
+
+ + + + + + + + +
bool QwtScaleDiv::operator!= (const QwtScaleDivother) const
+
+ +

Inequality.

+
Returns
true if this instance is not equal to other
+ +
+
+ +
+
+ + + + + + + + +
bool QwtScaleDiv::operator== (const QwtScaleDivother) const
+
+ +

Equality operator.

+
Returns
true if this instance is equal to other
+ +
+
+ +
+
+ + + + + + + +
double QwtScaleDiv::range () const
+
+
Returns
upperBound() - lowerBound()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtScaleDiv::setInterval (double lowerBound,
double upperBound 
)
+
+

Change the interval

+
Parameters
+ + + +
lowerBoundFirst boundary
upperBoundSecond boundary
+
+
+
Note
lowerBound might be greater than upperBound for inverted scales
+ +
+
+ +
+
+ + + + + + + + +
void QwtScaleDiv::setInterval (const QwtIntervalinterval)
+
+

Change the interval

+
Parameters
+ + +
intervalInterval
+
+
+ +
+
+ +
+
+ + + + + + + + +
void QwtScaleDiv::setLowerBound (double lowerBound)
+
+

Set the first boundary

+
Parameters
+ + +
lowerBoundFirst boundary
+
+
+
See Also
lowerBiound(), setUpperBound()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtScaleDiv::setTicks (int type,
const QList< double > & ticks 
)
+
+

Assign ticks

+
Parameters
+ + + +
typeMinorTick, MediumTick or MajorTick
ticksValues of the tick positions
+
+
+ +
+
+ +
+
+ + + + + + + + +
void QwtScaleDiv::setUpperBound (double upperBound)
+
+

Set the second boundary

+
Parameters
+ + +
upperBoundSecond boundary
+
+
+
See Also
upperBound(), setLowerBound()
+ +
+
+ +
+
+ + + + + + + + +
QList< double > QwtScaleDiv::ticks (int type) const
+
+

Return a list of ticks

+
Parameters
+ + +
typeMinorTick, MediumTick or MajorTick
+
+
+
Returns
Tick list
+ +
+
+ +
+
+ + + + + + + +
double QwtScaleDiv::upperBound () const
+
+
Returns
upper bound
+
See Also
lowerBound()
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_scale_draw-members.html b/ThirdParty/Qwt/doc/html/class_qwt_scale_draw-members.html new file mode 100644 index 0000000000..42f42b2669 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_scale_draw-members.html @@ -0,0 +1,160 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtScaleDraw Member List
+
+
+ +

This is the complete list of members for QwtScaleDraw, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Alignment enum nameQwtScaleDraw
alignment() const QwtScaleDraw
Backbone enum valueQwtAbstractScaleDraw
BottomScale enum valueQwtScaleDraw
boundingLabelRect(const QFont &, double val) const QwtScaleDraw
draw(QPainter *, const QPalette &) const QwtAbstractScaleDrawvirtual
drawBackbone(QPainter *) const QwtScaleDrawprotectedvirtual
drawLabel(QPainter *, double val) const QwtScaleDrawprotectedvirtual
drawTick(QPainter *, double val, double len) const QwtScaleDrawprotectedvirtual
enableComponent(ScaleComponent, bool enable=true)QwtAbstractScaleDraw
extent(const QFont &) const QwtScaleDrawvirtual
getBorderDistHint(const QFont &, int &start, int &end) const QwtScaleDraw
hasComponent(ScaleComponent) const QwtAbstractScaleDraw
invalidateCache()QwtAbstractScaleDrawprotected
label(double) const QwtAbstractScaleDrawvirtual
labelAlignment() const QwtScaleDraw
labelPosition(double val) const QwtScaleDraw
labelRect(const QFont &, double val) const QwtScaleDraw
labelRotation() const QwtScaleDraw
Labels enum valueQwtAbstractScaleDraw
labelSize(const QFont &, double val) const QwtScaleDraw
labelTransformation(const QPointF &, const QSizeF &) const QwtScaleDrawprotected
LeftScale enum valueQwtScaleDraw
length() const QwtScaleDraw
maxLabelHeight(const QFont &) const QwtScaleDraw
maxLabelWidth(const QFont &) const QwtScaleDraw
maxTickLength() const QwtAbstractScaleDraw
minimumExtent() const QwtAbstractScaleDraw
minLabelDist(const QFont &) const QwtScaleDraw
minLength(const QFont &) const QwtScaleDraw
move(double x, double y)QwtScaleDrawinline
move(const QPointF &)QwtScaleDraw
orientation() const QwtScaleDraw
penWidth() const QwtAbstractScaleDraw
pos() const QwtScaleDraw
QwtAbstractScaleDraw()QwtAbstractScaleDraw
QwtScaleDraw()QwtScaleDraw
RightScale enum valueQwtScaleDraw
ScaleComponent enum nameQwtAbstractScaleDraw
ScaleComponents typedefQwtAbstractScaleDraw
scaleDiv() const QwtAbstractScaleDraw
scaleMap() const QwtAbstractScaleDraw
scaleMap()QwtAbstractScaleDraw
setAlignment(Alignment)QwtScaleDraw
setLabelAlignment(Qt::Alignment)QwtScaleDraw
setLabelRotation(double rotation)QwtScaleDraw
setLength(double length)QwtScaleDraw
setMinimumExtent(double)QwtAbstractScaleDraw
setPenWidth(int width)QwtAbstractScaleDraw
setScaleDiv(const QwtScaleDiv &s)QwtAbstractScaleDraw
setSpacing(double margin)QwtAbstractScaleDraw
setTickLength(QwtScaleDiv::TickType, double length)QwtAbstractScaleDraw
setTransformation(QwtTransform *)QwtAbstractScaleDraw
spacing() const QwtAbstractScaleDraw
tickLabel(const QFont &, double value) const QwtAbstractScaleDrawprotected
tickLength(QwtScaleDiv::TickType) const QwtAbstractScaleDraw
Ticks enum valueQwtAbstractScaleDraw
TopScale enum valueQwtScaleDraw
~QwtAbstractScaleDraw()QwtAbstractScaleDrawvirtual
~QwtScaleDraw()QwtScaleDrawvirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_scale_draw.html b/ThirdParty/Qwt/doc/html/class_qwt_scale_draw.html new file mode 100644 index 0000000000..e4742f46bd --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_scale_draw.html @@ -0,0 +1,1087 @@ + + + + + + +Qwt User's Guide: QwtScaleDraw Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+ +
+ +

A class for drawing scales. + More...

+ +

#include <qwt_scale_draw.h>

+
+Inheritance diagram for QwtScaleDraw:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + + + +

+Public Types

enum  Alignment { BottomScale, +TopScale, +LeftScale, +RightScale + }
 
- Public Types inherited from QwtAbstractScaleDraw
enum  ScaleComponent { Backbone = 0x01, +Ticks = 0x02, +Labels = 0x04 + }
 
+typedef QFlags< ScaleComponentScaleComponents
 Scale components.
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 QwtScaleDraw ()
 Constructor. More...
 
+virtual ~QwtScaleDraw ()
 Destructor.
 
void getBorderDistHint (const QFont &, int &start, int &end) const
 Determine the minimum border distance. More...
 
int minLabelDist (const QFont &) const
 
int minLength (const QFont &) const
 
virtual double extent (const QFont &) const
 
void move (double x, double y)
 
void move (const QPointF &)
 Move the position of the scale. More...
 
void setLength (double length)
 
Alignment alignment () const
 
void setAlignment (Alignment)
 
Qt::Orientation orientation () const
 
QPointF pos () const
 
double length () const
 
void setLabelAlignment (Qt::Alignment)
 Change the label flags. More...
 
Qt::Alignment labelAlignment () const
 
void setLabelRotation (double rotation)
 
double labelRotation () const
 
int maxLabelHeight (const QFont &) const
 
int maxLabelWidth (const QFont &) const
 
QPointF labelPosition (double val) const
 
QRectF labelRect (const QFont &, double val) const
 
QSizeF labelSize (const QFont &, double val) const
 
QRect boundingLabelRect (const QFont &, double val) const
 Find the bounding rectangle for the label. More...
 
- Public Member Functions inherited from QwtAbstractScaleDraw
 QwtAbstractScaleDraw ()
 Constructor. More...
 
+virtual ~QwtAbstractScaleDraw ()
 Destructor.
 
void setScaleDiv (const QwtScaleDiv &s)
 
const QwtScaleDivscaleDiv () const
 
void setTransformation (QwtTransform *)
 
const QwtScaleMapscaleMap () const
 
QwtScaleMapscaleMap ()
 
void enableComponent (ScaleComponent, bool enable=true)
 
bool hasComponent (ScaleComponent) const
 
void setTickLength (QwtScaleDiv::TickType, double length)
 
double tickLength (QwtScaleDiv::TickType) const
 
double maxTickLength () const
 
void setSpacing (double margin)
 Set the spacing between tick and labels. More...
 
double spacing () const
 Get the spacing. More...
 
void setPenWidth (int width)
 Specify the width of the scale pen. More...
 
int penWidth () const
 
virtual void draw (QPainter *, const QPalette &) const
 Draw the scale. More...
 
virtual QwtText label (double) const
 Convert a value into its representing label. More...
 
void setMinimumExtent (double)
 Set a minimum for the extent. More...
 
double minimumExtent () const
 
+ + + + + + + + + + + + + + + +

+Protected Member Functions

QTransform labelTransformation (const QPointF &, const QSizeF &) const
 
virtual void drawTick (QPainter *, double val, double len) const
 
virtual void drawBackbone (QPainter *) const
 
virtual void drawLabel (QPainter *, double val) const
 
- Protected Member Functions inherited from QwtAbstractScaleDraw
void invalidateCache ()
 
const QwtTexttickLabel (const QFont &, double value) const
 Convert a value into its representing label and cache it. More...
 
+

Detailed Description

+

A class for drawing scales.

+

QwtScaleDraw can be used to draw linear or logarithmic scales. A scale has a position, an alignment and a length, which can be specified . The labels can be rotated and aligned to the ticks using setLabelRotation() and setLabelAlignment().

+

After a scale division has been specified as a QwtScaleDiv object using QwtAbstractScaleDraw::setScaleDiv(const QwtScaleDiv &s), the scale can be drawn with the QwtAbstractScaleDraw::draw() member.

+

Member Enumeration Documentation

+ +
+
+ + + + +
enum QwtScaleDraw::Alignment
+
+

Alignment of the scale draw

+
See Also
setAlignment(), alignment()
+ + + + + +
Enumerator
BottomScale  +

The scale is below.

+
TopScale  +

The scale is above.

+
LeftScale  +

The scale is left.

+
RightScale  +

The scale is right.

+
+ +
+
+

Constructor & Destructor Documentation

+ +
+
+ + + + + + + +
QwtScaleDraw::QwtScaleDraw ()
+
+ +

Constructor.

+

The range of the scale is initialized to [0, 100], The position is at (0, 0) with a length of 100. The orientation is QwtAbstractScaleDraw::Bottom.

+ +
+
+

Member Function Documentation

+ +
+
+ + + + + + + +
QwtScaleDraw::Alignment QwtScaleDraw::alignment () const
+
+

Return alignment of the scale

+
See Also
setAlignment()
+
Returns
Alignment of the scale
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
QRect QwtScaleDraw::boundingLabelRect (const QFont & font,
double value 
) const
+
+ +

Find the bounding rectangle for the label.

+

The coordinates of the rectangle are absolute ( calculated from pos() ). in direction of the tick.

+
Parameters
+ + + +
fontFont used for painting
valueValue
+
+
+
Returns
Bounding rectangle
+
See Also
labelRect()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtScaleDraw::drawBackbone (QPainter * painter) const
+
+protectedvirtual
+
+

Draws the baseline of the scale

+
Parameters
+ + +
painterPainter
+
+
+
See Also
drawTick(), drawLabel()
+ +

Implements QwtAbstractScaleDraw.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void QwtScaleDraw::drawLabel (QPainter * painter,
double value 
) const
+
+protectedvirtual
+
+

Draws the label for a major scale tick

+
Parameters
+ + + +
painterPainter
valueValue
+
+
+
See Also
drawTick(), drawBackbone(), boundingLabelRect()
+ +

Implements QwtAbstractScaleDraw.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
void QwtScaleDraw::drawTick (QPainter * painter,
double value,
double len 
) const
+
+protectedvirtual
+
+

Draw a tick

+
Parameters
+ + + + +
painterPainter
valueValue of the tick
lenLength of the tick
+
+
+
See Also
drawBackbone(), drawLabel()
+ +

Implements QwtAbstractScaleDraw.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
double QwtScaleDraw::extent (const QFont & font) const
+
+virtual
+
+

Calculate the width/height that is needed for a vertical/horizontal scale.

+

The extent is calculated from the pen width of the backbone, the major tick length, the spacing and the maximum width/height of the labels.

+
Parameters
+ + +
fontFont used for painting the labels
+
+
+
Returns
Extent
+
See Also
minLength()
+ +

Implements QwtAbstractScaleDraw.

+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void QwtScaleDraw::getBorderDistHint (const QFont & font,
int & start,
int & end 
) const
+
+ +

Determine the minimum border distance.

+

This member function returns the minimum space needed to draw the mark labels at the scale's endpoints.

+
Parameters
+ + + + +
fontFont
startStart border distance
endEnd border distance
+
+
+ +
+
+ +
+
+ + + + + + + +
Qt::Alignment QwtScaleDraw::labelAlignment () const
+
+
Returns
the label flags
+
See Also
setLabelAlignment(), labelRotation()
+ +
+
+ +
+
+ + + + + + + + +
QPointF QwtScaleDraw::labelPosition (double value) const
+
+

Find the position, where to paint a label

+

The position has a distance that depends on the length of the ticks in direction of the alignment().

+
Parameters
+ + +
valueValue
+
+
+
Returns
Position, where to paint a label
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
QRectF QwtScaleDraw::labelRect (const QFont & font,
double value 
) const
+
+

Find the bounding rectangle for the label. The coordinates of the rectangle are relative to spacing + tick length from the backbone in direction of the tick.

+
Parameters
+ + + +
fontFont used for painting
valueValue
+
+
+
Returns
Bounding rectangle that is needed to draw a label
+ +
+
+ +
+
+ + + + + + + +
double QwtScaleDraw::labelRotation () const
+
+
Returns
the label rotation
+
See Also
setLabelRotation(), labelAlignment()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
QSizeF QwtScaleDraw::labelSize (const QFont & font,
double value 
) const
+
+

Calculate the size that is needed to draw a label

+
Parameters
+ + + +
fontLabel font
valueValue
+
+
+
Returns
Size that is needed to draw a label
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
QTransform QwtScaleDraw::labelTransformation (const QPointF & pos,
const QSizeF & size 
) const
+
+protected
+
+

Calculate the transformation that is needed to paint a label depending on its alignment and rotation.

+
Parameters
+ + + +
posPosition where to paint the label
sizeSize of the label
+
+
+
Returns
Transformation matrix
+
See Also
setLabelAlignment(), setLabelRotation()
+ +
+
+ +
+
+ + + + + + + +
double QwtScaleDraw::length () const
+
+
Returns
the length of the backbone
+
See Also
setLength(), pos()
+ +
+
+ +
+
+ + + + + + + + +
int QwtScaleDraw::maxLabelHeight (const QFont & font) const
+
+
Parameters
+ + +
fontFont
+
+
+
Returns
the maximum height of a label
+ +
+
+ +
+
+ + + + + + + + +
int QwtScaleDraw::maxLabelWidth (const QFont & font) const
+
+
Parameters
+ + +
fontFont
+
+
+
Returns
the maximum width of a label
+ +
+
+ +
+
+ + + + + + + + +
int QwtScaleDraw::minLabelDist (const QFont & font) const
+
+

Determine the minimum distance between two labels, that is necessary that the texts don't overlap.

+
Parameters
+ + +
fontFont
+
+
+
Returns
The maximum width of a label
+
See Also
getBorderDistHint()
+ +
+
+ +
+
+ + + + + + + + +
int QwtScaleDraw::minLength (const QFont & font) const
+
+

Calculate the minimum length that is needed to draw the scale

+
Parameters
+ + +
fontFont used for painting the labels
+
+
+
Returns
Minimum length that is needed to draw the scale
+
See Also
extent()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void QwtScaleDraw::move (double x,
double y 
)
+
+inline
+
+

Move the position of the scale

+
Parameters
+ + + +
xX coordinate
yY coordinate
+
+
+
See Also
move(const QPointF &)
+ +
+
+ +
+
+ + + + + + + + +
void QwtScaleDraw::move (const QPointF & pos)
+
+ +

Move the position of the scale.

+

The meaning of the parameter pos depends on the alignment:

+
+
QwtScaleDraw::LeftScale
+
The origin is the topmost point of the backbone. The backbone is a vertical line. Scale marks and labels are drawn at the left of the backbone.
+
QwtScaleDraw::RightScale
+
The origin is the topmost point of the backbone. The backbone is a vertical line. Scale marks and labels are drawn at the right of the backbone.
+
QwtScaleDraw::TopScale
+
The origin is the leftmost point of the backbone. The backbone is a horizontal line. Scale marks and labels are drawn above the backbone.
+
QwtScaleDraw::BottomScale
+
The origin is the leftmost point of the backbone. The backbone is a horizontal line Scale marks and labels are drawn below the backbone.
+
+
Parameters
+ + +
posOrigin of the scale
+
+
+
See Also
pos(), setLength()
+ +
+
+ +
+
+ + + + + + + +
Qt::Orientation QwtScaleDraw::orientation () const
+
+

Return the orientation

+

TopScale, BottomScale are horizontal (Qt::Horizontal) scales, LeftScale, RightScale are vertical (Qt::Vertical) scales.

+
Returns
Orientation of the scale
+
See Also
alignment()
+ +
+
+ +
+
+ + + + + + + +
QPointF QwtScaleDraw::pos () const
+
+
Returns
Origin of the scale
+
See Also
move(), length()
+ +
+
+ +
+
+ + + + + + + + +
void QwtScaleDraw::setAlignment (Alignment align)
+
+

Set the alignment of the scale

+
Parameters
+ + +
alignAlignment of the scale
+
+
+

The default alignment is QwtScaleDraw::BottomScale

+
See Also
alignment()
+ +
+
+ +
+
+ + + + + + + + +
void QwtScaleDraw::setLabelAlignment (Qt::Alignment alignment)
+
+ +

Change the label flags.

+

Labels are aligned to the point tick length + spacing away from the backbone.

+

The alignment is relative to the orientation of the label text. In case of an flags of 0 the label will be aligned depending on the orientation of the scale:

+
QwtScaleDraw::TopScale: Qt::AlignHCenter | Qt::AlignTop\n
+QwtScaleDraw::BottomScale: Qt::AlignHCenter | Qt::AlignBottom\n
+QwtScaleDraw::LeftScale: Qt::AlignLeft | Qt::AlignVCenter\n
+QwtScaleDraw::RightScale: Qt::AlignRight | Qt::AlignVCenter\n
+

Changing the alignment is often necessary for rotated labels.

+
Parameters
+ + +
alignmentOr'd Qt::AlignmentFlags see <qnamespace.h>
+
+
+
See Also
setLabelRotation(), labelRotation(), labelAlignment()
+
Warning
The various alignments might be confusing. The alignment of the label is not the alignment of the scale and is not the alignment of the flags ( QwtText::flags() ) returned from QwtAbstractScaleDraw::label().
+ +
+
+ +
+
+ + + + + + + + +
void QwtScaleDraw::setLabelRotation (double rotation)
+
+

Rotate all labels.

+

When changing the rotation, it might be necessary to adjust the label flags too. Finding a useful combination is often the result of try and error.

+
Parameters
+ + +
rotationAngle in degrees. When changing the label rotation, the label flags often needs to be adjusted too.
+
+
+
See Also
setLabelAlignment(), labelRotation(), labelAlignment().
+ +
+
+ +
+
+ + + + + + + + +
void QwtScaleDraw::setLength (double length)
+
+

Set the length of the backbone.

+

The length doesn't include the space needed for overlapping labels.

+
Parameters
+ + +
lengthLength of the backbone
+
+
+
See Also
move(), minLabelDist()
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_scale_draw__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_scale_draw__inherit__graph.map new file mode 100644 index 0000000000..b7d1e35024 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_scale_draw__inherit__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_scale_draw__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_scale_draw__inherit__graph.md5 new file mode 100644 index 0000000000..505d7e1257 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_scale_draw__inherit__graph.md5 @@ -0,0 +1 @@ +44b56a6cb8aef2cd0b2e13320f539a5e \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_scale_draw__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_scale_draw__inherit__graph.png new file mode 100644 index 0000000000..d44483db70 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_scale_draw__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_scale_engine-members.html b/ThirdParty/Qwt/doc/html/class_qwt_scale_engine-members.html new file mode 100644 index 0000000000..eeb1af672e --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_scale_engine-members.html @@ -0,0 +1,128 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtScaleEngine Member List
+
+
+ +

This is the complete list of members for QwtScaleEngine, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Attribute enum nameQwtScaleEngine
Attributes typedefQwtScaleEngine
attributes() const QwtScaleEngine
autoScale(int maxNumSteps, double &x1, double &x2, double &stepSize) const =0QwtScaleEnginepure virtual
base() const QwtScaleEngine
buildInterval(double v) const QwtScaleEngineprotected
contains(const QwtInterval &, double val) const QwtScaleEngineprotected
divideInterval(double interval, int numSteps) const QwtScaleEngineprotected
divideScale(double x1, double x2, int maxMajorSteps, int maxMinorSteps, double stepSize=0.0) const =0QwtScaleEnginepure virtual
Floating enum valueQwtScaleEngine
IncludeReference enum valueQwtScaleEngine
Inverted enum valueQwtScaleEngine
lowerMargin() const QwtScaleEngine
NoAttribute enum valueQwtScaleEngine
QwtScaleEngine(uint base=10)QwtScaleEngineexplicit
reference() const QwtScaleEngine
setAttribute(Attribute, bool on=true)QwtScaleEngine
setAttributes(Attributes)QwtScaleEngine
setBase(uint base)QwtScaleEngine
setMargins(double lower, double upper)QwtScaleEngine
setReference(double reference)QwtScaleEngine
setTransformation(QwtTransform *)QwtScaleEngine
strip(const QList< double > &, const QwtInterval &) const QwtScaleEngineprotected
Symmetric enum valueQwtScaleEngine
testAttribute(Attribute) const QwtScaleEngine
transformation() const QwtScaleEngine
upperMargin() const QwtScaleEngine
~QwtScaleEngine()QwtScaleEnginevirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_scale_engine.html b/ThirdParty/Qwt/doc/html/class_qwt_scale_engine.html new file mode 100644 index 0000000000..b63879feca --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_scale_engine.html @@ -0,0 +1,850 @@ + + + + + + +Qwt User's Guide: QwtScaleEngine Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtScaleEngine Class Referenceabstract
+
+
+ +

Base class for scale engines. + More...

+ +

#include <qwt_scale_engine.h>

+
+Inheritance diagram for QwtScaleEngine:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + +

+Public Types

enum  Attribute {
+  NoAttribute = 0x00, +IncludeReference = 0x01, +Symmetric = 0x02, +Floating = 0x04, +
+  Inverted = 0x08 +
+ }
 
+typedef QFlags< AttributeAttributes
 Layout attributes.
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 QwtScaleEngine (uint base=10)
 
+virtual ~QwtScaleEngine ()
 Destructor.
 
void setBase (uint base)
 
uint base () const
 
void setAttribute (Attribute, bool on=true)
 
bool testAttribute (Attribute) const
 
void setAttributes (Attributes)
 
Attributes attributes () const
 
void setReference (double reference)
 Specify a reference point. More...
 
double reference () const
 
void setMargins (double lower, double upper)
 Specify margins at the scale's endpoints. More...
 
double lowerMargin () const
 
double upperMargin () const
 
virtual void autoScale (int maxNumSteps, double &x1, double &x2, double &stepSize) const =0
 
virtual QwtScaleDiv divideScale (double x1, double x2, int maxMajorSteps, int maxMinorSteps, double stepSize=0.0) const =0
 Calculate a scale division. More...
 
void setTransformation (QwtTransform *)
 
QwtTransformtransformation () const
 
+ + + + + + + + + + +

+Protected Member Functions

bool contains (const QwtInterval &, double val) const
 
QList< double > strip (const QList< double > &, const QwtInterval &) const
 
double divideInterval (double interval, int numSteps) const
 
QwtInterval buildInterval (double v) const
 Build an interval around a value. More...
 
+

Detailed Description

+

Base class for scale engines.

+

A scale engine tries to find "reasonable" ranges and step sizes for scales.

+

The layout of the scale can be varied with setAttribute().

+

Qwt offers implementations for logarithmic and linear scales.

+

Member Enumeration Documentation

+ +
+
+ + + + +
enum QwtScaleEngine::Attribute
+
+

Layout attributes

+
See Also
setAttribute(), testAttribute(), reference(), lowerMargin(), upperMargin()
+ + + + + + +
Enumerator
NoAttribute  +

No attributes.

+
IncludeReference  +

Build a scale which includes the reference() value.

+
Symmetric  +

Build a scale which is symmetric to the reference() value.

+
Floating  +

The endpoints of the scale are supposed to be equal the outmost included values plus the specified margins (see setMargins()). If this attribute is not set, the endpoints of the scale will be integer multiples of the step size.

+
Inverted  +

Turn the scale upside down.

+
+ +
+
+

Constructor & Destructor Documentation

+ +
+
+ + + + + +
+ + + + + + + + +
QwtScaleEngine::QwtScaleEngine (uint base = 10)
+
+explicit
+
+

Constructor

+
Parameters
+ + +
baseBase of the scale engine
+
+
+
See Also
setBase()
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + + + +
QwtScaleEngine::Attributes QwtScaleEngine::attributes () const
+
+
Returns
Scale attributes
+
See Also
Attribute, setAttributes(), testAttribute()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
virtual void QwtScaleEngine::autoScale (int maxNumSteps,
double & x1,
double & x2,
double & stepSize 
) const
+
+pure virtual
+
+

Align and divide an interval

+
Parameters
+ + + + + +
maxNumStepsMax. number of steps
x1First limit of the interval (In/Out)
x2Second limit of the interval (In/Out)
stepSizeStep size (Return value)
+
+
+ +

Implemented in QwtLogScaleEngine, QwtLinearScaleEngine, and QwtDateScaleEngine.

+ +
+
+ +
+
+ + + + + + + +
uint QwtScaleEngine::base () const
+
+
Returns
base Base of the scale engine
+
See Also
setBase()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
QwtInterval QwtScaleEngine::buildInterval (double value) const
+
+protected
+
+ +

Build an interval around a value.

+

In case of v == 0.0 the interval is [-0.5, 0.5], otherwide it is [0.5 * v, 1.5 * v]

+
Parameters
+ + +
valueInitial value
+
+
+
Returns
Calculated interval
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool QwtScaleEngine::contains (const QwtIntervalinterval,
double value 
) const
+
+protected
+
+

Check if an interval "contains" a value

+
Parameters
+ + + +
intervalInterval
valueValue
+
+
+
Returns
True, when the value is inside the interval
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
double QwtScaleEngine::divideInterval (double intervalSize,
int numSteps 
) const
+
+protected
+
+

Calculate a step size for an interval size

+
Parameters
+ + + +
intervalSizeInterval size
numStepsNumber of steps
+
+
+
Returns
Step size
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
virtual QwtScaleDiv QwtScaleEngine::divideScale (double x1,
double x2,
int maxMajorSteps,
int maxMinorSteps,
double stepSize = 0.0 
) const
+
+pure virtual
+
+ +

Calculate a scale division.

+
Parameters
+ + + + + + +
x1First interval limit
x2Second interval limit
maxMajorStepsMaximum for the number of major steps
maxMinorStepsMaximum number of minor steps
stepSizeStep size. If stepSize == 0.0, the scaleEngine calculates one.
+
+
+
Returns
Calculated scale division
+ +

Implemented in QwtLogScaleEngine, QwtLinearScaleEngine, and QwtDateScaleEngine.

+ +
+
+ +
+
+ + + + + + + +
double QwtScaleEngine::lowerMargin () const
+
+
Returns
the margin at the lower end of the scale The default margin is 0.
+
See Also
setMargins()
+ +
+
+ +
+
+ + + + + + + +
double QwtScaleEngine::reference () const
+
+
Returns
the reference value
+
See Also
setReference(), setAttribute()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtScaleEngine::setAttribute (Attribute attribute,
bool on = true 
)
+
+

Change a scale attribute

+
Parameters
+ + + +
attributeAttribute to change
onOn/Off
+
+
+
See Also
Attribute, testAttribute()
+ +
+
+ +
+
+ + + + + + + + +
void QwtScaleEngine::setAttributes (Attributes attributes)
+
+

Change the scale attribute

+
Parameters
+ + +
attributesSet scale attributes
+
+
+
See Also
Attribute, attributes()
+ +
+
+ +
+
+ + + + + + + + +
void QwtScaleEngine::setBase (uint base)
+
+

Set the base of the scale engine

+

While a base of 10 is what 99.9% of all applications need certain scales might need a different base: f.e 2

+

The default setting is 10

+
Parameters
+ + +
baseBase of the engine
+
+
+
See Also
base()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtScaleEngine::setMargins (double lower,
double upper 
)
+
+ +

Specify margins at the scale's endpoints.

+
Parameters
+ + + +
lowerminimum distance between the scale's lower boundary and the smallest enclosed value
upperminimum distance between the scale's upper boundary and the greatest enclosed value
+
+
+

Margins can be used to leave a minimum amount of space between the enclosed intervals and the boundaries of the scale.

+
Warning
+
+
See Also
upperMargin(), lowerMargin()
+ +
+
+ +
+
+ + + + + + + + +
void QwtScaleEngine::setReference (double r)
+
+ +

Specify a reference point.

+
Parameters
+ + +
rnew reference value
+
+
+

The reference point is needed if options IncludeReference or Symmetric are active. Its default value is 0.0.

+
See Also
Attribute
+ +
+
+ +
+
+ + + + + + + + +
void QwtScaleEngine::setTransformation (QwtTransformtransform)
+
+

Assign a transformation

+
Parameters
+ + +
transformTransformation
+
+
+

The transformation object is used as factory for clones that are returned by transformation()

+

The scale engine takes ownership of the transformation.

+
See Also
QwtTransform::copy(), transformation()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
QList< double > QwtScaleEngine::strip (const QList< double > & ticks,
const QwtIntervalinterval 
) const
+
+protected
+
+

Remove ticks from a list, that are not inside an interval

+
Parameters
+ + + +
ticksTick list
intervalInterval
+
+
+
Returns
Stripped tick list
+ +
+
+ +
+
+ + + + + + + + +
bool QwtScaleEngine::testAttribute (Attribute attribute) const
+
+
Returns
True, if attribute is enabled.
+
Parameters
+ + +
attributeAttribute to be tested
+
+
+
See Also
Attribute, setAttribute()
+ +
+
+ +
+
+ + + + + + + +
QwtTransform * QwtScaleEngine::transformation () const
+
+

Create and return a clone of the transformation of the engine. When the engine has no special transformation NULL is returned, indicating no transformation.

+
Returns
A clone of the transfomation
+
See Also
setTransformation()
+ +
+
+ +
+
+ + + + + + + +
double QwtScaleEngine::upperMargin () const
+
+
Returns
the margin at the upper end of the scale The default margin is 0.
+
See Also
setMargins()
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_scale_engine__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_scale_engine__inherit__graph.map new file mode 100644 index 0000000000..a9b5039d8a --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_scale_engine__inherit__graph.map @@ -0,0 +1,5 @@ + + + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_scale_engine__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_scale_engine__inherit__graph.md5 new file mode 100644 index 0000000000..31b0659929 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_scale_engine__inherit__graph.md5 @@ -0,0 +1 @@ +e31f9596675ee7d52b863fd19a5c80c3 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_scale_engine__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_scale_engine__inherit__graph.png new file mode 100644 index 0000000000..49c4cfd969 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_scale_engine__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_scale_map-members.html b/ThirdParty/Qwt/doc/html/class_qwt_scale_map-members.html new file mode 100644 index 0000000000..9350391499 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_scale_map-members.html @@ -0,0 +1,121 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtScaleMap Member List
+
+
+ +

This is the complete list of members for QwtScaleMap, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + +
invTransform(double p) const QwtScaleMapinline
invTransform(const QwtScaleMap &, const QwtScaleMap &, const QRectF &)QwtScaleMapstatic
invTransform(const QwtScaleMap &, const QwtScaleMap &, const QPointF &)QwtScaleMapstatic
isInverting() const QwtScaleMapinline
operator=(const QwtScaleMap &)QwtScaleMap
p1() const QwtScaleMapinline
p2() const QwtScaleMapinline
pDist() const QwtScaleMapinline
QwtScaleMap()QwtScaleMap
QwtScaleMap(const QwtScaleMap &)QwtScaleMap
s1() const QwtScaleMapinline
s2() const QwtScaleMapinline
sDist() const QwtScaleMapinline
setPaintInterval(double p1, double p2)QwtScaleMap
setScaleInterval(double s1, double s2)QwtScaleMap
setTransformation(QwtTransform *)QwtScaleMap
transform(double s) const QwtScaleMapinline
transform(const QwtScaleMap &, const QwtScaleMap &, const QRectF &)QwtScaleMapstatic
transform(const QwtScaleMap &, const QwtScaleMap &, const QPointF &)QwtScaleMapstatic
transformation() const QwtScaleMap
~QwtScaleMap()QwtScaleMap
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_scale_map.html b/ThirdParty/Qwt/doc/html/class_qwt_scale_map.html new file mode 100644 index 0000000000..3f3381ca3a --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_scale_map.html @@ -0,0 +1,729 @@ + + + + + + +Qwt User's Guide: QwtScaleMap Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+ +
+ +

A scale map. + More...

+ +

#include <qwt_scale_map.h>

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 QwtScaleMap ()
 Constructor. More...
 
QwtScaleMap (const QwtScaleMap &)
 Copy constructor.
 
 ~QwtScaleMap ()
 
+QwtScaleMapoperator= (const QwtScaleMap &)
 Assignment operator.
 
void setTransformation (QwtTransform *)
 
+const QwtTransformtransformation () const
 Get the transformation.
 
void setPaintInterval (double p1, double p2)
 Specify the borders of the paint device interval. More...
 
void setScaleInterval (double s1, double s2)
 Specify the borders of the scale interval. More...
 
double transform (double s) const
 
double invTransform (double p) const
 
double p1 () const
 
double p2 () const
 
double s1 () const
 
double s2 () const
 
double pDist () const
 
double sDist () const
 
bool isInverting () const
 
+ + + + + + + + + +

+Static Public Member Functions

static QRectF transform (const QwtScaleMap &, const QwtScaleMap &, const QRectF &)
 
static QRectF invTransform (const QwtScaleMap &, const QwtScaleMap &, const QRectF &)
 
static QPointF transform (const QwtScaleMap &, const QwtScaleMap &, const QPointF &)
 
static QPointF invTransform (const QwtScaleMap &, const QwtScaleMap &, const QPointF &)
 
+

Detailed Description

+

A scale map.

+

QwtScaleMap offers transformations from the coordinate system of a scale into the linear coordinate system of a paint device and vice versa.

+

Constructor & Destructor Documentation

+ +
+
+ + + + + + + +
QwtScaleMap::QwtScaleMap ()
+
+ +

Constructor.

+

The scale and paint device intervals are both set to [0,1].

+ +
+
+ +
+
+ + + + + + + +
QwtScaleMap::~QwtScaleMap ()
+
+

Destructor

+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + + +
double QwtScaleMap::invTransform (double p) const
+
+inline
+
+

Transform an paint device value into a value in the interval of the scale.

+
Parameters
+ + +
pValue relative to the coordinates of the paint device
+
+
+
Returns
Transformed value
+
See Also
transform()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
QRectF QwtScaleMap::invTransform (const QwtScaleMapxMap,
const QwtScaleMapyMap,
const QRectF & rect 
)
+
+static
+
+

Transform a rectangle from paint to scale coordinates

+
Parameters
+ + + + +
xMapX map
yMapY map
rectRectangle in paint coordinates
+
+
+
Returns
Rectangle in scale coordinates
+
See Also
transform()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
QPointF QwtScaleMap::invTransform (const QwtScaleMapxMap,
const QwtScaleMapyMap,
const QPointF & pos 
)
+
+static
+
+

Transform a rectangle from paint to scale coordinates

+
Parameters
+ + + + +
xMapX map
yMapY map
posPosition in paint coordinates
+
+
+
Returns
Position in scale coordinates
+
See Also
transform()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool QwtScaleMap::isInverting () const
+
+inline
+
+
Returns
True, when ( p1() < p2() ) != ( s1() < s2() )
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
double QwtScaleMap::p1 () const
+
+inline
+
+
Returns
First border of the paint interval
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
double QwtScaleMap::p2 () const
+
+inline
+
+
Returns
Second border of the paint interval
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
double QwtScaleMap::pDist () const
+
+inline
+
+
Returns
qwtAbs(p2() - p1())
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
double QwtScaleMap::s1 () const
+
+inline
+
+
Returns
First border of the scale interval
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
double QwtScaleMap::s2 () const
+
+inline
+
+
Returns
Second border of the scale interval
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
double QwtScaleMap::sDist () const
+
+inline
+
+
Returns
qwtAbs(s2() - s1())
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtScaleMap::setPaintInterval (double p1,
double p2 
)
+
+ +

Specify the borders of the paint device interval.

+
Parameters
+ + + +
p1first border
p2second border
+
+
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtScaleMap::setScaleInterval (double s1,
double s2 
)
+
+ +

Specify the borders of the scale interval.

+
Parameters
+ + + +
s1first border
s2second border
+
+
+
Warning
scales might be aligned to transformation depending boundaries
+ +
+
+ +
+
+ + + + + + + + +
void QwtScaleMap::setTransformation (QwtTransformtransform)
+
+

Initialize the map with a transformation

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
double QwtScaleMap::transform (double s) const
+
+inline
+
+

Transform a point related to the scale interval into an point related to the interval of the paint device

+
Parameters
+ + +
sValue relative to the coordinates of the scale
+
+
+
Returns
Transformed value
+
See Also
invTransform()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
QRectF QwtScaleMap::transform (const QwtScaleMapxMap,
const QwtScaleMapyMap,
const QRectF & rect 
)
+
+static
+
+

Transform a rectangle from scale to paint coordinates

+
Parameters
+ + + + +
xMapX map
yMapY map
rectRectangle in scale coordinates
+
+
+
Returns
Rectangle in paint coordinates
+
See Also
invTransform()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
QPointF QwtScaleMap::transform (const QwtScaleMapxMap,
const QwtScaleMapyMap,
const QPointF & pos 
)
+
+static
+
+

Transform a point from scale to paint coordinates

+
Parameters
+ + + + +
xMapX map
yMapY map
posPosition in scale coordinates
+
+
+
Returns
Position in paint coordinates
+
See Also
invTransform()
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_scale_widget-members.html b/ThirdParty/Qwt/doc/html/class_qwt_scale_widget-members.html new file mode 100644 index 0000000000..d8ef4561cb --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_scale_widget-members.html @@ -0,0 +1,150 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtScaleWidget Member List
+
+
+ +

This is the complete list of members for QwtScaleWidget, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
alignment() const QwtScaleWidget
colorBarInterval() const QwtScaleWidget
colorBarRect(const QRectF &) const QwtScaleWidget
colorBarWidth() const QwtScaleWidget
colorMap() const QwtScaleWidget
dimForLength(int length, const QFont &scaleFont) const QwtScaleWidget
draw(QPainter *p) const QwtScaleWidgetprotected
drawColorBar(QPainter *painter, const QRectF &) const QwtScaleWidget
drawTitle(QPainter *painter, QwtScaleDraw::Alignment, const QRectF &rect) const QwtScaleWidget
endBorderDist() const QwtScaleWidget
getBorderDistHint(int &start, int &end) const QwtScaleWidget
getMinBorderDist(int &start, int &end) const QwtScaleWidget
isColorBarEnabled() const QwtScaleWidget
LayoutFlag enum nameQwtScaleWidget
LayoutFlags typedefQwtScaleWidget
layoutScale(bool update=true)QwtScaleWidgetprotected
margin() const QwtScaleWidget
minimumSizeHint() const QwtScaleWidgetvirtual
paintEvent(QPaintEvent *)QwtScaleWidgetprotectedvirtual
QwtScaleWidget(QWidget *parent=NULL)QwtScaleWidgetexplicit
QwtScaleWidget(QwtScaleDraw::Alignment, QWidget *parent=NULL)QwtScaleWidgetexplicit
resizeEvent(QResizeEvent *)QwtScaleWidgetprotectedvirtual
scaleChange()QwtScaleWidgetprotected
scaleDivChanged()QwtScaleWidgetsignal
scaleDraw() const QwtScaleWidget
scaleDraw()QwtScaleWidget
setAlignment(QwtScaleDraw::Alignment)QwtScaleWidget
setBorderDist(int start, int end)QwtScaleWidget
setColorBarEnabled(bool)QwtScaleWidget
setColorBarWidth(int)QwtScaleWidget
setColorMap(const QwtInterval &, QwtColorMap *)QwtScaleWidget
setLabelAlignment(Qt::Alignment)QwtScaleWidget
setLabelRotation(double rotation)QwtScaleWidget
setLayoutFlag(LayoutFlag, bool on)QwtScaleWidget
setMargin(int)QwtScaleWidget
setMinBorderDist(int start, int end)QwtScaleWidget
setScaleDiv(const QwtScaleDiv &sd)QwtScaleWidget
setScaleDraw(QwtScaleDraw *)QwtScaleWidget
setSpacing(int td)QwtScaleWidget
setTitle(const QString &title)QwtScaleWidget
setTitle(const QwtText &title)QwtScaleWidget
setTransformation(QwtTransform *)QwtScaleWidget
sizeHint() const QwtScaleWidgetvirtual
spacing() const QwtScaleWidget
startBorderDist() const QwtScaleWidget
testLayoutFlag(LayoutFlag) const QwtScaleWidget
title() const QwtScaleWidget
titleHeightForWidth(int width) const QwtScaleWidget
TitleInverted enum valueQwtScaleWidget
~QwtScaleWidget()QwtScaleWidgetvirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_scale_widget.html b/ThirdParty/Qwt/doc/html/class_qwt_scale_widget.html new file mode 100644 index 0000000000..62ec3561d1 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_scale_widget.html @@ -0,0 +1,1376 @@ + + + + + + +Qwt User's Guide: QwtScaleWidget Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+ +
+ +

A Widget which contains a scale. + More...

+ +

#include <qwt_scale_widget.h>

+
+Inheritance diagram for QwtScaleWidget:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + +

+Public Types

enum  LayoutFlag { TitleInverted = 1 + }
 Layout flags of the title. More...
 
+typedef QFlags< LayoutFlagLayoutFlags
 Layout flags of the title.
 
+ + + + +

+Signals

+void scaleDivChanged ()
 Signal emitted, whenever the scale division changes.
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 QwtScaleWidget (QWidget *parent=NULL)
 Create a scale with the position QwtScaleWidget::Left. More...
 
 QwtScaleWidget (QwtScaleDraw::Alignment, QWidget *parent=NULL)
 Constructor. More...
 
+virtual ~QwtScaleWidget ()
 Destructor.
 
void setTitle (const QString &title)
 
void setTitle (const QwtText &title)
 
QwtText title () const
 
void setLayoutFlag (LayoutFlag, bool on)
 
bool testLayoutFlag (LayoutFlag) const
 
void setBorderDist (int start, int end)
 
int startBorderDist () const
 
int endBorderDist () const
 
void getBorderDistHint (int &start, int &end) const
 Calculate a hint for the border distances. More...
 
void getMinBorderDist (int &start, int &end) const
 
void setMinBorderDist (int start, int end)
 
void setMargin (int)
 Specify the margin to the colorBar/base line. More...
 
int margin () const
 
void setSpacing (int td)
 Specify the distance between color bar, scale and title. More...
 
int spacing () const
 
void setScaleDiv (const QwtScaleDiv &sd)
 Assign a scale division. More...
 
void setTransformation (QwtTransform *)
 
void setScaleDraw (QwtScaleDraw *)
 
const QwtScaleDrawscaleDraw () const
 
QwtScaleDrawscaleDraw ()
 
void setLabelAlignment (Qt::Alignment)
 Change the alignment for the labels. More...
 
void setLabelRotation (double rotation)
 Change the rotation for the labels. See QwtScaleDraw::setLabelRotation(). More...
 
void setColorBarEnabled (bool)
 
bool isColorBarEnabled () const
 
void setColorBarWidth (int)
 
int colorBarWidth () const
 
void setColorMap (const QwtInterval &, QwtColorMap *)
 
QwtInterval colorBarInterval () const
 
const QwtColorMapcolorMap () const
 
virtual QSize sizeHint () const
 
virtual QSize minimumSizeHint () const
 
int titleHeightForWidth (int width) const
 Find the height of the title for a given width. More...
 
int dimForLength (int length, const QFont &scaleFont) const
 Find the minimum dimension for a given length. dim is the height, length the width seen in direction of the title. More...
 
void drawColorBar (QPainter *painter, const QRectF &) const
 
void drawTitle (QPainter *painter, QwtScaleDraw::Alignment, const QRectF &rect) const
 
void setAlignment (QwtScaleDraw::Alignment)
 
QwtScaleDraw::Alignment alignment () const
 
QRectF colorBarRect (const QRectF &) const
 
+ + + + + + + + + + + + + + +

+Protected Member Functions

+virtual void paintEvent (QPaintEvent *)
 paintEvent
 
virtual void resizeEvent (QResizeEvent *)
 
+void draw (QPainter *p) const
 draw the scale
 
void scaleChange ()
 Notify a change of the scale. More...
 
void layoutScale (bool update=true)
 
+

Detailed Description

+

A Widget which contains a scale.

+

This Widget can be used to decorate composite widgets with a scale.

+

Member Enumeration Documentation

+ +
+
+ + + + +
enum QwtScaleWidget::LayoutFlag
+
+ +

Layout flags of the title.

+ + +
Enumerator
TitleInverted  +

The title of vertical scales is painted from top to bottom. Otherwise it is painted from bottom to top.

+
+ +
+
+

Constructor & Destructor Documentation

+ +
+
+ + + + + +
+ + + + + + + + +
QwtScaleWidget::QwtScaleWidget (QWidget * parent = NULL)
+
+explicit
+
+ +

Create a scale with the position QwtScaleWidget::Left.

+
Parameters
+ + +
parentParent widget
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
QwtScaleWidget::QwtScaleWidget (QwtScaleDraw::Alignment align,
QWidget * parent = NULL 
)
+
+explicit
+
+ +

Constructor.

+
Parameters
+ + + +
alignAlignment.
parentParent widget
+
+
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + + + +
QwtScaleDraw::Alignment QwtScaleWidget::alignment () const
+
+
Returns
position
+
See Also
setPosition()
+ +
+
+ +
+
+ + + + + + + +
QwtInterval QwtScaleWidget::colorBarInterval () const
+
+
Returns
Value interval for the color bar
+
See Also
setColorMap(), colorMap()
+ +
+
+ +
+
+ + + + + + + + +
QRectF QwtScaleWidget::colorBarRect (const QRectF & rect) const
+
+

Calculate the the rectangle for the color bar

+
Parameters
+ + +
rectBounding rectangle for all components of the scale
+
+
+
Returns
Rectangle for the color bar
+ +
+
+ +
+
+ + + + + + + +
int QwtScaleWidget::colorBarWidth () const
+
+
Returns
Width of the color bar
+
See Also
setColorBarEnabled(), setColorBarEnabled()
+ +
+
+ +
+
+ + + + + + + +
const QwtColorMap * QwtScaleWidget::colorMap () const
+
+
Returns
Color map
+
See Also
setColorMap(), colorBarInterval()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
int QwtScaleWidget::dimForLength (int length,
const QFont & scaleFont 
) const
+
+ +

Find the minimum dimension for a given length. dim is the height, length the width seen in direction of the title.

+
Parameters
+ + + +
lengthwidth for horizontal, height for vertical scales
scaleFontFont of the scale
+
+
+
Returns
height for horizontal, width for vertical scales
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtScaleWidget::drawColorBar (QPainter * painter,
const QRectF & rect 
) const
+
+

Draw the color bar of the scale widget

+
Parameters
+ + + +
painterPainter
rectBounding rectangle for the color bar
+
+
+
See Also
setColorBarEnabled()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void QwtScaleWidget::drawTitle (QPainter * painter,
QwtScaleDraw::Alignment align,
const QRectF & rect 
) const
+
+

Rotate and paint a title according to its position into a given rectangle.

+
Parameters
+ + + + +
painterPainter
alignAlignment
rectBounding rectangle
+
+
+ +
+
+ +
+
+ + + + + + + +
int QwtScaleWidget::endBorderDist () const
+
+
Returns
end border distance
+
See Also
setBorderDist()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtScaleWidget::getBorderDistHint (int & start,
int & end 
) const
+
+ +

Calculate a hint for the border distances.

+

This member function calculates the distance of the scale's endpoints from the widget borders which is required for the mark labels to fit into the widget. The maximum of this distance an the minimum border distance is returned.

+
Parameters
+ + + +
startReturn parameter for the border width at the beginning of the scale
endReturn parameter for the border width at the end of the scale
+
+
+
Warning
    +
  • +The minimum border distance depends on the font.
  • +
+
+
See Also
setMinBorderDist(), getMinBorderDist(), setBorderDist()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtScaleWidget::getMinBorderDist (int & start,
int & end 
) const
+
+

Get the minimum value for the distances of the scale's endpoints from the widget borders.

+
Parameters
+ + + +
startReturn parameter for the border width at the beginning of the scale
endReturn parameter for the border width at the end of the scale
+
+
+
See Also
setMinBorderDist(), getBorderDistHint()
+ +
+
+ +
+
+ + + + + + + +
bool QwtScaleWidget::isColorBarEnabled () const
+
+
Returns
true, when the color bar is enabled
+
See Also
setColorBarEnabled(), setColorBarWidth()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtScaleWidget::layoutScale (bool update_geometry = true)
+
+protected
+
+

Recalculate the scale's geometry and layout based on the current geometry and fonts.

+
Parameters
+ + +
update_geometryNotify the layout system and call update to redraw the scale
+
+
+ +
+
+ +
+
+ + + + + + + +
int QwtScaleWidget::margin () const
+
+
Returns
margin
+
See Also
setMargin()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
QSize QwtScaleWidget::minimumSizeHint () const
+
+virtual
+
+
Returns
a minimum size hint
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtScaleWidget::resizeEvent (QResizeEvent * event)
+
+protectedvirtual
+
+

Event handler for resize events

+
Parameters
+ + +
eventResize event
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void QwtScaleWidget::scaleChange ()
+
+protected
+
+ +

Notify a change of the scale.

+

This virtual function can be overloaded by derived classes. The default implementation updates the geometry and repaints the widget.

+ +
+
+ +
+
+ + + + + + + +
const QwtScaleDraw * QwtScaleWidget::scaleDraw () const
+
+
Returns
scaleDraw of this scale
+
See Also
setScaleDraw(), QwtScaleDraw::setScaleDraw()
+ +
+
+ +
+
+ + + + + + + +
QwtScaleDraw * QwtScaleWidget::scaleDraw ()
+
+
Returns
scaleDraw of this scale
+
See Also
QwtScaleDraw::setScaleDraw()
+ +
+
+ +
+
+ + + + + + + + +
void QwtScaleWidget::setAlignment (QwtScaleDraw::Alignment alignment)
+
+

Change the alignment

+
Parameters
+ + +
alignmentNew alignment
+
+
+
See Also
alignment()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtScaleWidget::setBorderDist (int dist1,
int dist2 
)
+
+

Specify distances of the scale's endpoints from the widget's borders. The actual borders will never be less than minimum border distance.

+
Parameters
+ + + +
dist1Left or top Distance
dist2Right or bottom distance
+
+
+
See Also
borderDist()
+ +
+
+ +
+
+ + + + + + + + +
void QwtScaleWidget::setColorBarEnabled (bool on)
+
+

En/disable a color bar associated to the scale

+
See Also
isColorBarEnabled(), setColorBarWidth()
+ +
+
+ +
+
+ + + + + + + + +
void QwtScaleWidget::setColorBarWidth (int width)
+
+

Set the width of the color bar

+
Parameters
+ + +
widthWidth
+
+
+
See Also
colorBarWidth(), setColorBarEnabled()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtScaleWidget::setColorMap (const QwtIntervalinterval,
QwtColorMapcolorMap 
)
+
+

Set the color map and value interval, that are used for displaying the color bar.

+
Parameters
+ + + +
intervalValue interval
colorMapColor map
+
+
+
See Also
colorMap(), colorBarInterval()
+ +
+
+ +
+
+ + + + + + + + +
void QwtScaleWidget::setLabelAlignment (Qt::Alignment alignment)
+
+ +

Change the alignment for the labels.

+
See Also
QwtScaleDraw::setLabelAlignment(), setLabelRotation()
+ +
+
+ +
+
+ + + + + + + + +
void QwtScaleWidget::setLabelRotation (double rotation)
+
+ +

Change the rotation for the labels. See QwtScaleDraw::setLabelRotation().

+
Parameters
+ + +
rotationRotation
+
+
+
See Also
QwtScaleDraw::setLabelRotation(), setLabelFlags()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtScaleWidget::setLayoutFlag (LayoutFlag flag,
bool on 
)
+
+

Toggle an layout flag

+
Parameters
+ + + +
flagLayout flag
ontrue/false
+
+
+
See Also
testLayoutFlag(), LayoutFlag
+ +
+
+ +
+
+ + + + + + + + +
void QwtScaleWidget::setMargin (int margin)
+
+ +

Specify the margin to the colorBar/base line.

+
Parameters
+ + +
marginMargin
+
+
+
See Also
margin()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtScaleWidget::setMinBorderDist (int start,
int end 
)
+
+

Set a minimum value for the distances of the scale's endpoints from the widget borders. This is useful to avoid that the scales are "jumping", when the tick labels or their positions change often.

+
Parameters
+ + + +
startMinimum for the start border
endMinimum for the end border
+
+
+
See Also
getMinBorderDist(), getBorderDistHint()
+ +
+
+ +
+
+ + + + + + + + +
void QwtScaleWidget::setScaleDiv (const QwtScaleDivscaleDiv)
+
+ +

Assign a scale division.

+

The scale division determines where to set the tick marks.

+
Parameters
+ + +
scaleDivScale Division
+
+
+
See Also
For more information about scale divisions, see QwtScaleDiv.
+ +
+
+ +
+
+ + + + + + + + +
void QwtScaleWidget::setScaleDraw (QwtScaleDrawscaleDraw)
+
+

Set a scale draw

+

scaleDraw has to be created with new and will be deleted in ~QwtScaleWidget() or the next call of setScaleDraw(). scaleDraw will be initialized with the attributes of the previous scaleDraw object.

+
Parameters
+ + +
scaleDrawScaleDraw object
+
+
+
See Also
scaleDraw()
+ +
+
+ +
+
+ + + + + + + + +
void QwtScaleWidget::setSpacing (int spacing)
+
+ +

Specify the distance between color bar, scale and title.

+
Parameters
+ + +
spacingSpacing
+
+
+
See Also
spacing()
+ +
+
+ +
+
+ + + + + + + + +
void QwtScaleWidget::setTitle (const QString & title)
+
+

Give title new text contents

+
Parameters
+ + +
titleNew title
+
+
+
See Also
title(), setTitle(const QwtText &);
+ +
+
+ +
+
+ + + + + + + + +
void QwtScaleWidget::setTitle (const QwtTexttitle)
+
+

Give title new text contents

+
Parameters
+ + +
titleNew title
+
+
+
See Also
title()
+
Warning
The title flags are interpreted in direction of the label, AlignTop, AlignBottom can't be set as the title will always be aligned to the scale.
+ +
+
+ +
+
+ + + + + + + + +
void QwtScaleWidget::setTransformation (QwtTransformtransformation)
+
+

Set the transformation

+
Parameters
+ + +
transformationTransformation
+
+
+
See Also
QwtAbstractScaleDraw::scaleDraw(), QwtScaleMap
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
QSize QwtScaleWidget::sizeHint () const
+
+virtual
+
+
Returns
a size hint
+ +
+
+ +
+
+ + + + + + + +
int QwtScaleWidget::spacing () const
+
+
Returns
distance between scale and title
+
See Also
setMargin()
+ +
+
+ +
+
+ + + + + + + +
int QwtScaleWidget::startBorderDist () const
+
+
Returns
start border distance
+
See Also
setBorderDist()
+ +
+
+ +
+
+ + + + + + + + +
bool QwtScaleWidget::testLayoutFlag (LayoutFlag flag) const
+
+

Test a layout flag

+
Parameters
+ + +
flagLayout flag
+
+
+
Returns
true/false
+
See Also
setLayoutFlag(), LayoutFlag
+ +
+
+ +
+
+ + + + + + + +
QwtText QwtScaleWidget::title () const
+
+
Returns
title
+
See Also
setTitle()
+ +
+
+ +
+
+ + + + + + + + +
int QwtScaleWidget::titleHeightForWidth (int width) const
+
+ +

Find the height of the title for a given width.

+
Parameters
+ + +
widthWidth
+
+
+
Returns
height Height
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_scale_widget__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_scale_widget__inherit__graph.map new file mode 100644 index 0000000000..4d59abd389 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_scale_widget__inherit__graph.map @@ -0,0 +1,2 @@ + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_scale_widget__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_scale_widget__inherit__graph.md5 new file mode 100644 index 0000000000..f3ecb57f5a --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_scale_widget__inherit__graph.md5 @@ -0,0 +1 @@ +ecd9aaffd4c26f9aedc15d273f988771 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_scale_widget__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_scale_widget__inherit__graph.png new file mode 100644 index 0000000000..279417f7aa Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_scale_widget__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_series_data-members.html b/ThirdParty/Qwt/doc/html/class_qwt_series_data-members.html new file mode 100644 index 0000000000..dcf29e1e27 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_series_data-members.html @@ -0,0 +1,107 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtSeriesData< T > Member List
+
+
+ +

This is the complete list of members for QwtSeriesData< T >, including all inherited members.

+ + + + + + + + +
boundingRect() const =0QwtSeriesData< T >pure virtual
d_boundingRectQwtSeriesData< T >mutableprotected
QwtSeriesData()QwtSeriesData< T >
sample(size_t i) const =0QwtSeriesData< T >pure virtual
setRectOfInterest(const QRectF &rect)QwtSeriesData< T >virtual
size() const =0QwtSeriesData< T >pure virtual
~QwtSeriesData()QwtSeriesData< T >virtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_series_data.html b/ThirdParty/Qwt/doc/html/class_qwt_series_data.html new file mode 100644 index 0000000000..73aa54bbda --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_series_data.html @@ -0,0 +1,292 @@ + + + + + + +Qwt User's Guide: QwtSeriesData< T > Class Template Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtSeriesData< T > Class Template Referenceabstract
+
+
+ +

Abstract interface for iterating over samples. + More...

+ +

#include <qwt_series_data.h>

+
+Inheritance diagram for QwtSeriesData< T >:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + + + + + + + + + +

+Public Member Functions

QwtSeriesData ()
 Constructor.
 
+virtual ~QwtSeriesData ()
 Destructor.
 
virtual size_t size () const =0
 
virtual T sample (size_t i) const =0
 
virtual QRectF boundingRect () const =0
 
virtual void setRectOfInterest (const QRectF &rect)
 
+ + + + +

+Protected Attributes

+QRectF d_boundingRect
 Can be used to cache a calculated bounding rectangle.
 
+

Detailed Description

+

template<typename T>
+class QwtSeriesData< T >

+ +

Abstract interface for iterating over samples.

+

Qwt offers several implementations of the QwtSeriesData API, but in situations, where data of an application specific format needs to be displayed, without having to copy it, it is recommended to implement an individual data access.

+

A subclass of QwtSeriesData<QPointF> must implement:

+
    +
  • size()
    + Should return number of data points.
  • +
+
    +
  • sample()
    + Should return values x and y values of the sample at specific position as QPointF object.
  • +
+
    +
  • boundingRect()
    + Should return the bounding rectangle of the data series. It is used for autoscaling and might help certain algorithms for displaying the data. You can use qwtBoundingRect() for an implementation but often it is possible to implement a more efficient algorithm depending on the characteristics of the series. The member d_boundingRect is intended for caching the calculated rectangle.
  • +
+

Member Function Documentation

+ +
+
+
+template<typename T>
+ + + + + +
+ + + + + + + +
virtual QRectF QwtSeriesData< T >::boundingRect () const
+
+pure virtual
+
+

Calculate the bounding rect of all samples

+

The bounding rect is necessary for autoscaling and can be used for a couple of painting optimizations.

+

qwtBoundingRect(...) offers slow implementations iterating over the samples. For large sets it is recommended to implement something faster f.e. by caching the bounding rectangle.

+
Returns
Bounding rectangle
+ +

Implemented in QwtTradingChartData, QwtSetSeriesData, QwtIntervalSeriesData, QwtPoint3DSeriesData, QwtPointSeriesData, QwtSyntheticPointData, QwtCPointerData, and QwtPointArrayData.

+ +
+
+ +
+
+
+template<typename T>
+ + + + + +
+ + + + + + + + +
virtual T QwtSeriesData< T >::sample (size_t i) const
+
+pure virtual
+
+
+ +
+
+
+template<typename T >
+ + + + + +
+ + + + + + + + +
void QwtSeriesData< T >::setRectOfInterest (const QRectF & rect)
+
+virtual
+
+

Set a the "rect of interest"

+

QwtPlotSeriesItem defines the current area of the plot canvas as "rectangle of interest" ( QwtPlotSeriesItem::updateScaleDiv() ). It can be used to implement different levels of details.

+

The default implementation does nothing.

+
Parameters
+ + +
rectRectangle of interest
+
+
+ +

Reimplemented in QwtSyntheticPointData.

+ +
+
+ +
+
+
+template<typename T>
+ + + + + +
+ + + + + + + +
virtual size_t QwtSeriesData< T >::size () const
+
+pure virtual
+
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_series_data__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_series_data__inherit__graph.map new file mode 100644 index 0000000000..04000a9082 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_series_data__inherit__graph.map @@ -0,0 +1,3 @@ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_series_data__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_series_data__inherit__graph.md5 new file mode 100644 index 0000000000..096bac25ec --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_series_data__inherit__graph.md5 @@ -0,0 +1 @@ +abc4ab06e827aff713331f4730b81e37 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_series_data__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_series_data__inherit__graph.png new file mode 100644 index 0000000000..a56dcb7631 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_series_data__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_series_store-members.html b/ThirdParty/Qwt/doc/html/class_qwt_series_store-members.html new file mode 100644 index 0000000000..82c6ba63d6 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_series_store-members.html @@ -0,0 +1,112 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtSeriesStore< T > Member List
+
+
+ +

This is the complete list of members for QwtSeriesStore< T >, including all inherited members.

+ + + + + + + + + + + + + +
data()QwtSeriesStore< T >inline
data() const QwtSeriesStore< T >inline
dataChanged()=0QwtAbstractSeriesStoreprotectedpure virtual
dataRect() const QwtSeriesStore< T >virtual
dataSize() const QwtSeriesStore< T >virtual
QwtSeriesStore()QwtSeriesStore< T >explicit
sample(int index) const QwtSeriesStore< T >inline
setData(QwtSeriesData< T > *series)QwtSeriesStore< T >
setRectOfInterest(const QRectF &rect)QwtSeriesStore< T >virtual
swapData(QwtSeriesData< T > *series)QwtSeriesStore< T >
~QwtAbstractSeriesStore()QwtAbstractSeriesStoreinlineprotectedvirtual
~QwtSeriesStore()QwtSeriesStore< T >
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_series_store.html b/ThirdParty/Qwt/doc/html/class_qwt_series_store.html new file mode 100644 index 0000000000..891f4c0ebf --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_series_store.html @@ -0,0 +1,391 @@ + + + + + + +Qwt User's Guide: QwtSeriesStore< T > Class Template Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtSeriesStore< T > Class Template Reference
+
+
+ +

Class storing a QwtSeriesData object. + More...

+ +

#include <qwt_series_store.h>

+
+Inheritance diagram for QwtSeriesStore< T >:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

QwtSeriesStore ()
 Constructor The store contains no series.
 
~QwtSeriesStore ()
 Destructor.
 
void setData (QwtSeriesData< T > *series)
 
QwtSeriesData< T > * data ()
 
const QwtSeriesData< T > * data () const
 
sample (int index) const
 
virtual size_t dataSize () const
 
virtual QRectF dataRect () const
 
virtual void setRectOfInterest (const QRectF &rect)
 
QwtSeriesData< T > * swapData (QwtSeriesData< T > *series)
 
+ + + + + + + + +

+Additional Inherited Members

- Protected Member Functions inherited from QwtAbstractSeriesStore
+virtual ~QwtAbstractSeriesStore ()
 Destructor.
 
+virtual void dataChanged ()=0
 dataChanged() indicates, that the series has been changed.
 
+

Detailed Description

+

template<typename T>
+class QwtSeriesStore< T >

+ +

Class storing a QwtSeriesData object.

+

QwtSeriesStore and QwtPlotSeriesItem are intended as base classes for all plot items iterating over a series of samples. Both classes share a virtual base class ( QwtAbstractSeriesStore ) to bridge between them.

+

QwtSeriesStore offers the template based part for the plot item API, so that QwtPlotSeriesItem can be derived without any hassle with templates.

+

Member Function Documentation

+ +
+
+
+template<typename T >
+ + + + + +
+ + + + + + + +
QwtSeriesData< T > * QwtSeriesStore< T >::data ()
+
+inline
+
+
Returns
the the series data
+ +
+
+ +
+
+
+template<typename T >
+ + + + + +
+ + + + + + + +
const QwtSeriesData< T > * QwtSeriesStore< T >::data () const
+
+inline
+
+
Returns
the the series data
+ +
+
+ +
+
+
+template<typename T >
+ + + + + +
+ + + + + + + +
QRectF QwtSeriesStore< T >::dataRect () const
+
+virtual
+
+
Returns
Bounding rectangle of the series or an invalid rectangle, when no series is stored
+
See Also
QwtSeriesData<T>::boundingRect()
+ +

Implements QwtAbstractSeriesStore.

+ +
+
+ +
+
+
+template<typename T >
+ + + + + +
+ + + + + + + +
size_t QwtSeriesStore< T >::dataSize () const
+
+virtual
+
+
Returns
Number of samples of the series
+
See Also
setData(), QwtSeriesData<T>::size()
+ +

Implements QwtAbstractSeriesStore.

+ +
+
+ +
+
+
+template<typename T >
+ + + + + +
+ + + + + + + + +
T QwtSeriesStore< T >::sample (int index) const
+
+inline
+
+
Parameters
+ + +
indexIndex
+
+
+
Returns
Sample at position index
+ +
+
+ +
+
+
+template<typename T>
+ + + + + + + + +
void QwtSeriesStore< T >::setData (QwtSeriesData< T > * series)
+
+

Assign a series of samples

+
Parameters
+ + +
seriesData
+
+
+
Warning
The item takes ownership of the data object, deleting it when its not used anymore.
+ +
+
+ +
+
+
+template<typename T >
+ + + + + +
+ + + + + + + + +
void QwtSeriesStore< T >::setRectOfInterest (const QRectF & rect)
+
+virtual
+
+

Set a the "rect of interest" for the series

+
Parameters
+ + +
rectRectangle of interest
+
+
+
See Also
QwtSeriesData<T>::setRectOfInterest()
+ +

Implements QwtAbstractSeriesStore.

+ +
+
+ +
+
+
+template<typename T>
+ + + + + + + + +
QwtSeriesData< T > * QwtSeriesStore< T >::swapData (QwtSeriesData< T > * series)
+
+

Replace a series without deleting the previous one

+
Parameters
+ + +
seriesNew series
+
+
+
Returns
Previously assigned series
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_series_store__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_series_store__inherit__graph.map new file mode 100644 index 0000000000..c49df21d1d --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_series_store__inherit__graph.map @@ -0,0 +1,3 @@ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_series_store__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_series_store__inherit__graph.md5 new file mode 100644 index 0000000000..e0201298f4 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_series_store__inherit__graph.md5 @@ -0,0 +1 @@ +b1f5c34ef6e2d7f2982cbb11075922d7 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_series_store__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_series_store__inherit__graph.png new file mode 100644 index 0000000000..e9026ca8d2 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_series_store__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_set_sample-members.html b/ThirdParty/Qwt/doc/html/class_qwt_set_sample-members.html new file mode 100644 index 0000000000..cc6ee4c82b --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_set_sample-members.html @@ -0,0 +1,107 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtSetSample Member List
+
+
+ +

This is the complete list of members for QwtSetSample, including all inherited members.

+ + + + + + + + +
added() const QwtSetSampleinline
operator!=(const QwtSetSample &other) const QwtSetSampleinline
operator==(const QwtSetSample &other) const QwtSetSampleinline
QwtSetSample()QwtSetSampleinline
QwtSetSample(double, const QVector< double > &=QVector< double >())QwtSetSampleinline
setQwtSetSample
valueQwtSetSample
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_set_sample.html b/ThirdParty/Qwt/doc/html/class_qwt_set_sample.html new file mode 100644 index 0000000000..79c1dd9177 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_set_sample.html @@ -0,0 +1,229 @@ + + + + + + +Qwt User's Guide: QwtSetSample Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtSetSample Class Reference
+
+
+ +

A sample of the types (x1...xn, y) or (x, y1..yn) + More...

+ +

#include <qwt_samples.h>

+ + + + + + + + + + + + + + +

+Public Member Functions

 QwtSetSample ()
 
 QwtSetSample (double, const QVector< double > &=QVector< double >())
 
+bool operator== (const QwtSetSample &other) const
 Compare operator.
 
+bool operator!= (const QwtSetSample &other) const
 Compare operator.
 
double added () const
 
+ + + + + + + +

+Public Attributes

+double value
 value
 
+QVector< double > set
 Vector of values associated to value.
 
+

Detailed Description

+

A sample of the types (x1...xn, y) or (x, y1..yn)

+

Constructor & Destructor Documentation

+ +
+
+ + + + + +
+ + + + + + + +
QwtSetSample::QwtSetSample ()
+
+inline
+
+

Constructor The value is set to 0.0

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
QwtSetSample::QwtSetSample (double v,
const QVector< double > & s = QVector<double>() 
)
+
+inline
+
+

Constructor

+
Parameters
+ + + +
vValue
sSet of values
+
+
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + +
double QwtSetSample::added () const
+
+inline
+
+
Returns
All values of the set added
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_set_series_data-members.html b/ThirdParty/Qwt/doc/html/class_qwt_set_series_data-members.html new file mode 100644 index 0000000000..6d99178fee --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_set_series_data-members.html @@ -0,0 +1,113 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtSetSeriesData Member List
+
+
+ +

This is the complete list of members for QwtSetSeriesData, including all inherited members.

+ + + + + + + + + + + + + + +
boundingRect() const QwtSetSeriesDatavirtual
d_boundingRectQwtSeriesData< QwtSetSample >mutableprotected
d_samplesQwtArraySeriesData< QwtSetSample >protected
QwtArraySeriesData()QwtArraySeriesData< QwtSetSample >
QwtArraySeriesData(const QVector< QwtSetSample > &samples)QwtArraySeriesData< QwtSetSample >
QwtSeriesData()QwtSeriesData< QwtSetSample >
QwtSetSeriesData(const QVector< QwtSetSample > &=QVector< QwtSetSample >())QwtSetSeriesData
sample(size_t index) constQwtArraySeriesData< QwtSetSample >virtual
samples() constQwtArraySeriesData< QwtSetSample >
setRectOfInterest(const QRectF &rect)QwtSeriesData< QwtSetSample >virtual
setSamples(const QVector< QwtSetSample > &samples)QwtArraySeriesData< QwtSetSample >
size() constQwtArraySeriesData< QwtSetSample >virtual
~QwtSeriesData()QwtSeriesData< QwtSetSample >virtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_set_series_data.html b/ThirdParty/Qwt/doc/html/class_qwt_set_series_data.html new file mode 100644 index 0000000000..929f4e7e67 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_set_series_data.html @@ -0,0 +1,211 @@ + + + + + + +Qwt User's Guide: QwtSetSeriesData Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtSetSeriesData Class Reference
+
+
+ +

Interface for iterating over an array of samples. + More...

+ +

#include <qwt_series_data.h>

+
+Inheritance diagram for QwtSetSeriesData:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 QwtSetSeriesData (const QVector< QwtSetSample > &=QVector< QwtSetSample >())
 
virtual QRectF boundingRect () const
 Calculate the bounding rectangle. More...
 
- Public Member Functions inherited from QwtArraySeriesData< QwtSetSample >
QwtArraySeriesData ()
 Constructor.
 
 QwtArraySeriesData (const QVector< QwtSetSample > &samples)
 
void setSamples (const QVector< QwtSetSample > &samples)
 
const QVector< QwtSetSamplesamples () const
 
virtual size_t size () const
 
virtual QwtSetSample sample (size_t index) const
 
- Public Member Functions inherited from QwtSeriesData< QwtSetSample >
QwtSeriesData ()
 Constructor.
 
+virtual ~QwtSeriesData ()
 Destructor.
 
virtual void setRectOfInterest (const QRectF &rect)
 
+ + + + + +

+Additional Inherited Members

- Protected Attributes inherited from QwtArraySeriesData< QwtSetSample >
+QVector< QwtSetSampled_samples
 Vector of samples.
 
+

Detailed Description

+

Interface for iterating over an array of samples.

+

Constructor & Destructor Documentation

+ +
+
+ + + + + + + + +
QwtSetSeriesData::QwtSetSeriesData (const QVector< QwtSetSample > & samples = QVector<QwtSetSample>())
+
+

Constructor

+
Parameters
+ + +
samplesSamples
+
+
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + +
QRectF QwtSetSeriesData::boundingRect () const
+
+virtual
+
+ +

Calculate the bounding rectangle.

+

The bounding rectangle is calculated once by iterating over all points and is stored for all following requests.

+
Returns
Bounding rectangle
+ +

Implements QwtSeriesData< QwtSetSample >.

+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_set_series_data__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_set_series_data__inherit__graph.map new file mode 100644 index 0000000000..a2e87c3d7f --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_set_series_data__inherit__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_set_series_data__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_set_series_data__inherit__graph.md5 new file mode 100644 index 0000000000..193f1b9f88 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_set_series_data__inherit__graph.md5 @@ -0,0 +1 @@ +bcf0c51187a42db9c028037f00eba81e \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_set_series_data__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_set_series_data__inherit__graph.png new file mode 100644 index 0000000000..cc5d704f08 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_set_series_data__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_simple_compass_rose-members.html b/ThirdParty/Qwt/doc/html/class_qwt_simple_compass_rose-members.html new file mode 100644 index 0000000000..a96375cd18 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_simple_compass_rose-members.html @@ -0,0 +1,115 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtSimpleCompassRose Member List
+
+
+ +

This is the complete list of members for QwtSimpleCompassRose, including all inherited members.

+ + + + + + + + + + + + + + + + +
draw(QPainter *, const QPointF &center, double radius, double north, QPalette::ColorGroup=QPalette::Active) const QwtSimpleCompassRosevirtual
drawRose(QPainter *, const QPalette &, const QPointF &center, double radius, double origin, double width, int numThorns, int numThornLevels, double shrinkFactor)QwtSimpleCompassRosestatic
numThornLevels() const QwtSimpleCompassRose
numThorns() const QwtSimpleCompassRose
palette() const QwtCompassRoseinline
QwtSimpleCompassRose(int numThorns=8, int numThornLevels=-1)QwtSimpleCompassRose
setNumThornLevels(int count)QwtSimpleCompassRose
setNumThorns(int count)QwtSimpleCompassRose
setPalette(const QPalette &p)QwtCompassRoseinlinevirtual
setShrinkFactor(double factor)QwtSimpleCompassRose
setWidth(double w)QwtSimpleCompassRose
shrinkFactor() const QwtSimpleCompassRose
width() const QwtSimpleCompassRose
~QwtCompassRose()QwtCompassRoseinlinevirtual
~QwtSimpleCompassRose()QwtSimpleCompassRosevirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_simple_compass_rose.html b/ThirdParty/Qwt/doc/html/class_qwt_simple_compass_rose.html new file mode 100644 index 0000000000..8a9f07eef5 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_simple_compass_rose.html @@ -0,0 +1,514 @@ + + + + + + +Qwt User's Guide: QwtSimpleCompassRose Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtSimpleCompassRose Class Reference
+
+
+ +

A simple rose for QwtCompass. + More...

+ +

#include <qwt_compass_rose.h>

+
+Inheritance diagram for QwtSimpleCompassRose:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 QwtSimpleCompassRose (int numThorns=8, int numThornLevels=-1)
 
+virtual ~QwtSimpleCompassRose ()
 Destructor.
 
void setWidth (double w)
 
double width () const
 
void setNumThorns (int count)
 
int numThorns () const
 
void setNumThornLevels (int count)
 
int numThornLevels () const
 
void setShrinkFactor (double factor)
 
double shrinkFactor () const
 
virtual void draw (QPainter *, const QPointF &center, double radius, double north, QPalette::ColorGroup=QPalette::Active) const
 
- Public Member Functions inherited from QwtCompassRose
+virtual ~QwtCompassRose ()
 Destructor.
 
+virtual void setPalette (const QPalette &p)
 Assign a palette.
 
const QPalette & palette () const
 
+ + + +

+Static Public Member Functions

static void drawRose (QPainter *, const QPalette &, const QPointF &center, double radius, double origin, double width, int numThorns, int numThornLevels, double shrinkFactor)
 
+

Detailed Description

+

A simple rose for QwtCompass.

+

Constructor & Destructor Documentation

+ +
+
+ + + + + + + + + + + + + + + + + + +
QwtSimpleCompassRose::QwtSimpleCompassRose (int numThorns = 8,
int numThornLevels = -1 
)
+
+

Constructor

+
Parameters
+ + + +
numThornsNumber of thorns
numThornLevelsNumber of thorn levels
+
+
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void QwtSimpleCompassRose::draw (QPainter * painter,
const QPointF & center,
double radius,
double north,
QPalette::ColorGroup cg = QPalette::Active 
) const
+
+virtual
+
+

Draw the rose

+
Parameters
+ + + + + + +
painterPainter
centerCenter point
radiusRadius of the rose
northPosition
cgColor group
+
+
+ +

Implements QwtCompassRose.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void QwtSimpleCompassRose::drawRose (QPainter * painter,
const QPalette & palette,
const QPointF & center,
double radius,
double north,
double width,
int numThorns,
int numThornLevels,
double shrinkFactor 
)
+
+static
+
+

Draw the rose

+
Parameters
+ + + + + + + + + + +
painterPainter
palettePalette
centerCenter of the rose
radiusRadius of the rose
northPosition pointing to north
widthWidth of the rose
numThornsNumber of thorns
numThornLevelsNumber of thorn levels
shrinkFactorFactor to shrink the thorns with each level
+
+
+ +
+
+ +
+
+ + + + + + + +
int QwtSimpleCompassRose::numThornLevels () const
+
+
Returns
Number of thorn levels
+
See Also
setNumThorns(), setNumThornLevels()
+ +
+
+ +
+
+ + + + + + + +
int QwtSimpleCompassRose::numThorns () const
+
+
Returns
Number of thorns
+
See Also
setNumThorns(), setNumThornLevels()
+ +
+
+ +
+
+ + + + + + + + +
void QwtSimpleCompassRose::setNumThornLevels (int numThornLevels)
+
+

Set the of thorns levels

+
Parameters
+ + +
numThornLevelsNumber of thorns levels
+
+
+
See Also
setNumThorns(), numThornLevels()
+ +
+
+ +
+
+ + + + + + + + +
void QwtSimpleCompassRose::setNumThorns (int numThorns)
+
+

Set the number of thorns on one level The number is aligned to a multiple of 4, with a minimum of 4

+
Parameters
+ + +
numThornsNumber of thorns
+
+
+
See Also
numThorns(), setNumThornLevels()
+ +
+
+ +
+
+ + + + + + + + +
void QwtSimpleCompassRose::setShrinkFactor (double factor)
+
+

Set the Factor how to shrink the thorns with each level The default value is 0.9.

+
Parameters
+ + +
factorShrink factor
+
+
+
See Also
shrinkFactor()
+ +
+
+ +
+
+ + + + + + + + +
void QwtSimpleCompassRose::setWidth (double width)
+
+

Set the width of the rose heads. Lower value make thinner heads. The range is limited from 0.03 to 0.4.

+
Parameters
+ + +
widthWidth
+
+
+ +
+
+ +
+
+ + + + + + + +
double QwtSimpleCompassRose::shrinkFactor () const
+
+
Returns
Factor how to shrink the thorns with each level
+
See Also
setShrinkFactor()
+ +
+
+ +
+
+ + + + + + + +
double QwtSimpleCompassRose::width () const
+
+
Returns
Width of the rose
+
See Also
setWidth()
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_simple_compass_rose__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_simple_compass_rose__inherit__graph.map new file mode 100644 index 0000000000..d68733a1b8 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_simple_compass_rose__inherit__graph.map @@ -0,0 +1,3 @@ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_simple_compass_rose__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_simple_compass_rose__inherit__graph.md5 new file mode 100644 index 0000000000..ed14a0d007 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_simple_compass_rose__inherit__graph.md5 @@ -0,0 +1 @@ +15907025ecd9dd27feca73b0e939df87 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_simple_compass_rose__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_simple_compass_rose__inherit__graph.png new file mode 100644 index 0000000000..f24df35aaa Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_simple_compass_rose__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_slider-members.html b/ThirdParty/Qwt/doc/html/class_qwt_slider-members.html new file mode 100644 index 0000000000..220a0a0e59 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_slider-members.html @@ -0,0 +1,201 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtSlider Member List
+
+
+ +

This is the complete list of members for QwtSlider, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
abstractScaleDraw() const QwtAbstractScaleprotected
abstractScaleDraw()QwtAbstractScaleprotected
borderWidth() const QwtSlider
changeEvent(QEvent *)QwtSliderprotectedvirtual
drawHandle(QPainter *, const QRect &, int pos) const QwtSliderprotectedvirtual
drawSlider(QPainter *, const QRect &) const QwtSliderprotectedvirtual
handleRect() const QwtSliderprotected
handleSize() const QwtSlider
hasGroove() const QwtSlider
hasTrough() const QwtSlider
incrementedValue(double value, int stepCount) const QwtAbstractSliderprotected
incrementValue(int numSteps)QwtAbstractSliderprotected
invertedControls() const QwtAbstractSlider
invTransform(int) const QwtAbstractScale
isInverted() const QwtAbstractScale
isReadOnly() const QwtAbstractSlider
isScrollPosition(const QPoint &) const QwtSliderprotectedvirtual
isTracking() const QwtAbstractSlider
isValid() const QwtAbstractSlider
keyPressEvent(QKeyEvent *)QwtAbstractSliderprotectedvirtual
LeadingScale enum valueQwtSlider
lowerBound() const QwtAbstractScale
maximum() const QwtAbstractScale
minimum() const QwtAbstractScale
minimumSizeHint() const QwtSlidervirtual
mouseMoveEvent(QMouseEvent *)QwtAbstractSliderprotectedvirtual
mousePressEvent(QMouseEvent *)QwtSliderprotectedvirtual
mouseReleaseEvent(QMouseEvent *)QwtSliderprotectedvirtual
NoScale enum valueQwtSlider
orientation() const QwtSlider
pageSteps() const QwtAbstractSlider
paintEvent(QPaintEvent *)QwtSliderprotectedvirtual
QwtAbstractScale(QWidget *parent=NULL)QwtAbstractScale
QwtAbstractSlider(QWidget *parent=NULL)QwtAbstractSliderexplicit
QwtSlider(QWidget *parent=NULL)QwtSliderexplicit
QwtSlider(Qt::Orientation, QWidget *parent=NULL)QwtSliderexplicit
rescale(double lowerBound, double upperBound, double stepSize)QwtAbstractScaleprotected
resizeEvent(QResizeEvent *)QwtSliderprotectedvirtual
scaleChange()QwtSliderprotectedvirtual
scaleDiv() const QwtAbstractScale
scaleDraw() const QwtSlider
scaleEngine() const QwtAbstractScale
scaleEngine()QwtAbstractScale
scaleMap() const QwtAbstractScale
scaleMaxMajor() const QwtAbstractScale
scaleMaxMinor() const QwtAbstractScale
ScalePosition enum nameQwtSlider
scalePosition() const QwtSlider
scaleStepSize() const QwtAbstractScale
scrolledTo(const QPoint &) const QwtSliderprotectedvirtual
setAbstractScaleDraw(QwtAbstractScaleDraw *)QwtAbstractScaleprotected
setBorderWidth(int bw)QwtSlider
setGroove(bool)QwtSlider
setHandleSize(const QSize &)QwtSlider
setInvertedControls(bool)QwtAbstractSlider
setLowerBound(double value)QwtAbstractScale
setOrientation(Qt::Orientation)QwtSlider
setPageSteps(uint)QwtAbstractSlider
setReadOnly(bool)QwtAbstractSlider
setScale(double lowerBound, double upperBound)QwtAbstractScale
setScale(const QwtInterval &)QwtAbstractScale
setScale(const QwtScaleDiv &)QwtAbstractScale
setScaleDraw(QwtScaleDraw *)QwtSlider
setScaleEngine(QwtScaleEngine *)QwtAbstractScale
setScaleMaxMajor(int ticks)QwtAbstractScale
setScaleMaxMinor(int ticks)QwtAbstractScale
setScalePosition(ScalePosition)QwtSlider
setScaleStepSize(double stepSize)QwtAbstractScale
setSingleSteps(uint)QwtAbstractSlider
setSpacing(int)QwtSlider
setStepAlignment(bool)QwtAbstractSlider
setTotalSteps(uint)QwtAbstractSlider
setTracking(bool)QwtAbstractSlider
setTrough(bool)QwtSlider
setUpdateInterval(int)QwtSlider
setUpperBound(double value)QwtAbstractScale
setValid(bool)QwtAbstractSlider
setValue(double val)QwtAbstractSliderslot
setWrapping(bool)QwtAbstractSlider
singleSteps() const QwtAbstractSlider
sizeHint() const QwtSlidervirtual
sliderChange()QwtAbstractSliderprotectedvirtual
sliderMoved(double value)QwtAbstractSlidersignal
sliderPressed()QwtAbstractSlidersignal
sliderRect() const QwtSliderprotected
sliderReleased()QwtAbstractSlidersignal
spacing() const QwtSlider
stepAlignment() const QwtAbstractSlider
timerEvent(QTimerEvent *)QwtSliderprotectedvirtual
totalSteps() const QwtAbstractSlider
TrailingScale enum valueQwtSlider
transform(double) const QwtAbstractScale
updateInterval() const QwtSlider
upperBound() const QwtAbstractScale
value() const QwtAbstractSlider
valueChanged(double value)QwtAbstractSlidersignal
wheelEvent(QWheelEvent *)QwtAbstractSliderprotectedvirtual
wrapping() const QwtAbstractSlider
~QwtAbstractScale()QwtAbstractScalevirtual
~QwtAbstractSlider()QwtAbstractSlidervirtual
~QwtSlider()QwtSlidervirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_slider.html b/ThirdParty/Qwt/doc/html/class_qwt_slider.html new file mode 100644 index 0000000000..26f1debc21 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_slider.html @@ -0,0 +1,1320 @@ + + + + + + +Qwt User's Guide: QwtSlider Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+ +
+ +

The Slider Widget. + More...

+ +

#include <qwt_slider.h>

+
+Inheritance diagram for QwtSlider:
+
+
Inheritance graph
+ + +
[legend]
+ + + + +

+Public Types

enum  ScalePosition { NoScale, +LeadingScale, +TrailingScale + }
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 QwtSlider (QWidget *parent=NULL)
 
 QwtSlider (Qt::Orientation, QWidget *parent=NULL)
 
+virtual ~QwtSlider ()
 Destructor.
 
void setOrientation (Qt::Orientation)
 Set the orientation. More...
 
Qt::Orientation orientation () const
 
void setScalePosition (ScalePosition)
 Change the position of the scale. More...
 
ScalePosition scalePosition () const
 
void setTrough (bool)
 
bool hasTrough () const
 
void setGroove (bool)
 
bool hasGroove () const
 
void setHandleSize (const QSize &)
 Set the slider's handle size. More...
 
QSize handleSize () const
 
void setBorderWidth (int bw)
 Change the slider's border width. More...
 
int borderWidth () const
 
void setSpacing (int)
 Change the spacing between trough and scale. More...
 
int spacing () const
 
virtual QSize sizeHint () const
 
virtual QSize minimumSizeHint () const
 
void setScaleDraw (QwtScaleDraw *)
 Set a scale draw. More...
 
const QwtScaleDrawscaleDraw () const
 
void setUpdateInterval (int)
 Specify the update interval for automatic scrolling. More...
 
int updateInterval () const
 
- Public Member Functions inherited from QwtAbstractSlider
 QwtAbstractSlider (QWidget *parent=NULL)
 Constructor. More...
 
+virtual ~QwtAbstractSlider ()
 Destructor.
 
void setValid (bool)
 
bool isValid () const
 
+double value () const
 Returns the current value.
 
void setWrapping (bool)
 
bool wrapping () const
 
void setTotalSteps (uint)
 Set the number of steps. More...
 
uint totalSteps () const
 
void setSingleSteps (uint)
 Set the number of steps for a single increment. More...
 
uint singleSteps () const
 
void setPageSteps (uint)
 Set the number of steps for a page increment. More...
 
uint pageSteps () const
 
void setStepAlignment (bool)
 Enable step alignment. More...
 
bool stepAlignment () const
 
void setTracking (bool)
 Enables or disables tracking. More...
 
bool isTracking () const
 
void setReadOnly (bool)
 
bool isReadOnly () const
 
void setInvertedControls (bool)
 
bool invertedControls () const
 
- Public Member Functions inherited from QwtAbstractScale
 QwtAbstractScale (QWidget *parent=NULL)
 
+virtual ~QwtAbstractScale ()
 Destructor.
 
void setScale (double lowerBound, double upperBound)
 Specify a scale. More...
 
void setScale (const QwtInterval &)
 Specify a scale. More...
 
void setScale (const QwtScaleDiv &)
 Specify a scale. More...
 
const QwtScaleDivscaleDiv () const
 
void setLowerBound (double value)
 
double lowerBound () const
 
void setUpperBound (double value)
 
double upperBound () const
 
void setScaleStepSize (double stepSize)
 Set the step size used for calculating a scale division. More...
 
double scaleStepSize () const
 
void setScaleMaxMajor (int ticks)
 Set the maximum number of major tick intervals. More...
 
int scaleMaxMinor () const
 
void setScaleMaxMinor (int ticks)
 Set the maximum number of minor tick intervals. More...
 
int scaleMaxMajor () const
 
void setScaleEngine (QwtScaleEngine *)
 Set a scale engine. More...
 
const QwtScaleEnginescaleEngine () const
 
QwtScaleEnginescaleEngine ()
 
int transform (double) const
 
double invTransform (int) const
 
bool isInverted () const
 
double minimum () const
 
double maximum () const
 
const QwtScaleMapscaleMap () const
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Protected Member Functions

virtual double scrolledTo (const QPoint &) const
 Determine the value for a new position of the slider handle. More...
 
virtual bool isScrollPosition (const QPoint &) const
 Determine what to do when the user presses a mouse button. More...
 
virtual void drawSlider (QPainter *, const QRect &) const
 
virtual void drawHandle (QPainter *, const QRect &, int pos) const
 
virtual void mousePressEvent (QMouseEvent *)
 
virtual void mouseReleaseEvent (QMouseEvent *)
 
virtual void resizeEvent (QResizeEvent *)
 
virtual void paintEvent (QPaintEvent *)
 
virtual void changeEvent (QEvent *)
 
virtual void timerEvent (QTimerEvent *)
 
+virtual void scaleChange ()
 Notify changed scale.
 
QRect sliderRect () const
 
QRect handleRect () const
 
- Protected Member Functions inherited from QwtAbstractSlider
virtual void mouseMoveEvent (QMouseEvent *)
 
virtual void keyPressEvent (QKeyEvent *)
 
virtual void wheelEvent (QWheelEvent *)
 
void incrementValue (int numSteps)
 
+virtual void sliderChange ()
 Calling update()
 
double incrementedValue (double value, int stepCount) const
 
- Protected Member Functions inherited from QwtAbstractScale
void rescale (double lowerBound, double upperBound, double stepSize)
 
void setAbstractScaleDraw (QwtAbstractScaleDraw *)
 Set a scale draw. More...
 
const QwtAbstractScaleDrawabstractScaleDraw () const
 
QwtAbstractScaleDrawabstractScaleDraw ()
 
+ + + + + + + + + + + + + + +

+Additional Inherited Members

- Public Slots inherited from QwtAbstractSlider
void setValue (double val)
 
- Signals inherited from QwtAbstractSlider
void valueChanged (double value)
 Notify a change of value. More...
 
void sliderPressed ()
 
void sliderReleased ()
 
void sliderMoved (double value)
 
+

Detailed Description

+

The Slider Widget.

+

QwtSlider is a slider widget which operates on an interval of type double. Its position is related to a scale showing the current value.

+

The slider can be customized by having a through, a groove - or both.

+
+sliders.png +
+

Member Enumeration Documentation

+ +
+
+ + + + +
enum QwtSlider::ScalePosition
+
+

Position of the scale

+
See Also
QwtSlider(), setScalePosition(), setOrientation()
+ + + + +
Enumerator
NoScale  +

The slider has no scale.

+
LeadingScale  +

The scale is right of a vertical or below a horizontal slider.

+
TrailingScale  +

The scale is left of a vertical or above a horizontal slider.

+
+ +
+
+

Constructor & Destructor Documentation

+ +
+
+ + + + + +
+ + + + + + + + +
QwtSlider::QwtSlider (QWidget * parent = NULL)
+
+explicit
+
+

Construct vertical slider in QwtSlider::Trough style with a scale to the left.

+

The scale is initialized to [0.0, 100.0] and the value set to 0.0.

+
Parameters
+ + +
parentParent widget
+
+
+
See Also
setOrientation(), setScalePosition(), setBackgroundStyle()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
QwtSlider::QwtSlider (Qt::Orientation orientation,
QWidget * parent = NULL 
)
+
+explicit
+
+

Construct a slider in QwtSlider::Trough style

+

When orientation is Qt::Vertical the scale will be aligned to the left - otherwise at the the top of the slider.

+

The scale is initialized to [0.0, 100.0] and the value set to 0.0.

+
Parameters
+ + + +
parentParent widget
orientationOrientation of the slider.
+
+
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + + + +
int QwtSlider::borderWidth () const
+
+
Returns
the border width.
+
See Also
setBorderWidth()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtSlider::changeEvent (QEvent * event)
+
+protectedvirtual
+
+

Handles QEvent::StyleChange and QEvent::FontChange events

+
Parameters
+ + +
eventChange event
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
void QwtSlider::drawHandle (QPainter * painter,
const QRect & handleRect,
int pos 
) const
+
+protectedvirtual
+
+

Draw the thumb at a position

+
Parameters
+ + + + +
painterPainter
handleRectBounding rectangle of the handle
posPosition of the handle marker in widget coordinates
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void QwtSlider::drawSlider (QPainter * painter,
const QRect & sliderRect 
) const
+
+protectedvirtual
+
+

Draw the slider into the specified rectangle.

+
Parameters
+ + + +
painterPainter
sliderRectBounding rectangle of the slider
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
QRect QwtSlider::handleRect () const
+
+protected
+
+
Returns
Bounding rectangle of the slider handle
+ +
+
+ +
+
+ + + + + + + +
QSize QwtSlider::handleSize () const
+
+
Returns
Size of the handle.
+
See Also
setHandleSize()
+ +
+
+ +
+
+ + + + + + + +
bool QwtSlider::hasGroove () const
+
+
Returns
True, when the groove is visisble
+
See Also
setGroove(), hasTrough()
+ +
+
+ +
+
+ + + + + + + +
bool QwtSlider::hasTrough () const
+
+
Returns
True, when the trough is visisble
+
See Also
setTrough(), hasGroove()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool QwtSlider::isScrollPosition (const QPoint & pos) const
+
+protectedvirtual
+
+ +

Determine what to do when the user presses a mouse button.

+
Parameters
+ + +
posMouse position
+
+
+
Return values
+ + +
True,whenhandleRect() contains pos
+
+
+
See Also
scrolledTo()
+ +

Implements QwtAbstractSlider.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
QSize QwtSlider::minimumSizeHint () const
+
+virtual
+
+
Returns
Minimum size hint
+
See Also
sizeHint()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtSlider::mousePressEvent (QMouseEvent * event)
+
+protectedvirtual
+
+

Mouse press event handler

+
Parameters
+ + +
eventMouse event
+
+
+ +

Reimplemented from QwtAbstractSlider.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtSlider::mouseReleaseEvent (QMouseEvent * event)
+
+protectedvirtual
+
+

Mouse release event handler

+
Parameters
+ + +
eventMouse event
+
+
+ +

Reimplemented from QwtAbstractSlider.

+ +
+
+ +
+
+ + + + + + + +
Qt::Orientation QwtSlider::orientation () const
+
+
Returns
Orientation
+
See Also
setOrientation()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtSlider::paintEvent (QPaintEvent * event)
+
+protectedvirtual
+
+

Qt paint event handler

+
Parameters
+ + +
eventPaint event
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtSlider::resizeEvent (QResizeEvent * event)
+
+protectedvirtual
+
+

Qt resize event handler

+
Parameters
+ + +
eventResize event
+
+
+ +
+
+ +
+
+ + + + + + + +
const QwtScaleDraw * QwtSlider::scaleDraw () const
+
+
Returns
the scale draw of the slider
+
See Also
setScaleDraw()
+ +
+
+ +
+
+ + + + + + + +
QwtSlider::ScalePosition QwtSlider::scalePosition () const
+
+
Returns
Position of the scale
+
See Also
setScalePosition()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
double QwtSlider::scrolledTo (const QPoint & pos) const
+
+protectedvirtual
+
+ +

Determine the value for a new position of the slider handle.

+
Parameters
+ + +
posMouse position
+
+
+
Returns
Value for the mouse position
+
See Also
isScrollPosition()
+ +

Implements QwtAbstractSlider.

+ +
+
+ +
+
+ + + + + + + + +
void QwtSlider::setBorderWidth (int width)
+
+ +

Change the slider's border width.

+

The border width is used for drawing the slider handle and the trough.

+
Parameters
+ + +
widthBorder width
+
+
+
See Also
borderWidth()
+ +
+
+ +
+
+ + + + + + + + +
void QwtSlider::setGroove (bool on)
+
+

En/Disable the groove

+

The slider can be cutomized by showing a groove for the handle.

+
Parameters
+ + +
onWhen true, the groove is visible
+
+
+
See Also
hasGroove(), setThrough()
+ +
+
+ +
+
+ + + + + + + + +
void QwtSlider::setHandleSize (const QSize & size)
+
+ +

Set the slider's handle size.

+

When the size is empty the slider handle will be painted with a default size depending on its orientation() and backgroundStyle().

+
Parameters
+ + +
sizeNew size
+
+
+
See Also
handleSize()
+ +
+
+ +
+
+ + + + + + + + +
void QwtSlider::setOrientation (Qt::Orientation orientation)
+
+ +

Set the orientation.

+
Parameters
+ + +
orientationAllowed values are Qt::Horizontal and Qt::Vertical.
+
+
+
See Also
orientation(), scalePosition()
+ +
+
+ +
+
+ + + + + + + + +
void QwtSlider::setScaleDraw (QwtScaleDrawscaleDraw)
+
+ +

Set a scale draw.

+

For changing the labels of the scales, it is necessary to derive from QwtScaleDraw and overload QwtScaleDraw::label().

+
Parameters
+ + +
scaleDrawScaleDraw object, that has to be created with new and will be deleted in ~QwtSlider() or the next call of setScaleDraw().
+
+
+
See Also
scaleDraw()
+ +
+
+ +
+
+ + + + + + + + +
void QwtSlider::setScalePosition (ScalePosition scalePosition)
+
+ +

Change the position of the scale.

+
Parameters
+ + +
scalePositionPosition of the scale.
+
+
+
See Also
ScalePosition, scalePosition()
+ +
+
+ +
+
+ + + + + + + + +
void QwtSlider::setSpacing (int spacing)
+
+ +

Change the spacing between trough and scale.

+

A spacing of 0 means, that the backbone of the scale is covered by the trough.

+

The default setting is 4 pixels.

+
Parameters
+ + +
spacingNumber of pixels
+
+
+
See Also
spacing();
+ +
+
+ +
+
+ + + + + + + + +
void QwtSlider::setTrough (bool on)
+
+

En/Disable the trough

+

The slider can be cutomized by showing a trough for the handle.

+
Parameters
+ + +
onWhen true, the groove is visible
+
+
+
See Also
hasTrough(), setGroove()
+ +
+
+ +
+
+ + + + + + + + +
void QwtSlider::setUpdateInterval (int interval)
+
+ +

Specify the update interval for automatic scrolling.

+

The minimal accepted value is 50 ms.

+
Parameters
+ + +
intervalUpdate interval in milliseconds
+
+
+
See Also
setUpdateInterval()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
QSize QwtSlider::sizeHint () const
+
+virtual
+
+
Returns
minimumSizeHint()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
QRect QwtSlider::sliderRect () const
+
+protected
+
+
Returns
Bounding rectangle of the slider - without the scale
+ +
+
+ +
+
+ + + + + + + +
int QwtSlider::spacing () const
+
+
Returns
Number of pixels between slider and scale
+
See Also
setSpacing()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtSlider::timerEvent (QTimerEvent * event)
+
+protectedvirtual
+
+

Timer event handler

+

Handles the timer, when the mouse stays pressed inside the sliderRect().

+
Parameters
+ + +
eventMouse event
+
+
+ +
+
+ +
+
+ + + + + + + +
int QwtSlider::updateInterval () const
+
+
Returns
Update interval in milliseconds for automatic scrolling
+
See Also
setUpdateInterval()
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_slider__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_slider__inherit__graph.map new file mode 100644 index 0000000000..3c72204318 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_slider__inherit__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_slider__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_slider__inherit__graph.md5 new file mode 100644 index 0000000000..7baffc5c14 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_slider__inherit__graph.md5 @@ -0,0 +1 @@ +2b872b8de6241bbe79b28c3945c69992 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_slider__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_slider__inherit__graph.png new file mode 100644 index 0000000000..d512caa800 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_slider__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_spline-members.html b/ThirdParty/Qwt/doc/html/class_qwt_spline-members.html new file mode 100644 index 0000000000..5a7dbce718 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_spline-members.html @@ -0,0 +1,119 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtSpline Member List
+
+
+ +

This is the complete list of members for QwtSpline, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + +
buildNaturalSpline(const QPolygonF &)QwtSplineprotected
buildPeriodicSpline(const QPolygonF &)QwtSplineprotected
coefficientsA() const QwtSpline
coefficientsB() const QwtSpline
coefficientsC() const QwtSpline
isValid() const QwtSpline
Natural enum valueQwtSpline
operator=(const QwtSpline &)QwtSpline
Periodic enum valueQwtSpline
points() const QwtSpline
QwtSpline()QwtSpline
QwtSpline(const QwtSpline &)QwtSpline
reset()QwtSpline
setPoints(const QPolygonF &points)QwtSpline
setSplineType(SplineType)QwtSpline
splineType() const QwtSpline
SplineType enum nameQwtSpline
value(double x) const QwtSpline
~QwtSpline()QwtSpline
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_spline.html b/ThirdParty/Qwt/doc/html/class_qwt_spline.html new file mode 100644 index 0000000000..c4539c6bf3 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_spline.html @@ -0,0 +1,478 @@ + + + + + + +Qwt User's Guide: QwtSpline Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+ +
+ +

A class for spline interpolation. + More...

+ +

#include <qwt_spline.h>

+ + + + + +

+Public Types

enum  SplineType { Natural, +Periodic + }
 Spline type. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

QwtSpline ()
 Constructor.
 
 QwtSpline (const QwtSpline &)
 
~QwtSpline ()
 Destructor.
 
QwtSplineoperator= (const QwtSpline &)
 
void setSplineType (SplineType)
 
SplineType splineType () const
 
bool setPoints (const QPolygonF &points)
 Calculate the spline coefficients. More...
 
QPolygonF points () const
 
+void reset ()
 Free allocated memory and set size to 0.
 
+bool isValid () const
 True if valid.
 
double value (double x) const
 
const QVector< double > & coefficientsA () const
 
const QVector< double > & coefficientsB () const
 
const QVector< double > & coefficientsC () const
 
+ + + + + + + +

+Protected Member Functions

bool buildNaturalSpline (const QPolygonF &)
 Determines the coefficients for a natural spline. More...
 
bool buildPeriodicSpline (const QPolygonF &)
 Determines the coefficients for a periodic spline. More...
 
+

Detailed Description

+

A class for spline interpolation.

+

The QwtSpline class is used for cubical spline interpolation. Two types of splines, natural and periodic, are supported.

+
Usage:
    +
  1. +First call setPoints() to determine the spline coefficients for a tabulated function y(x).
  2. +
  3. +After the coefficients have been set up, the interpolated function value for an argument x can be determined by calling QwtSpline::value().
  4. +
+
+
Example:
#include <qwt_spline.h>
+
+
QPolygonF interpolate(const QPolygonF& points, int numValues)
+
{
+
QwtSpline spline;
+
if ( !spline.setPoints(points) )
+
return points;
+
+
QPolygonF interpolatedPoints(numValues);
+
+
const double delta =
+
(points[numPoints - 1].x() - points[0].x()) / (points.size() - 1);
+
for(i = 0; i < points.size(); i++) / interpolate
+
{
+
const double x = points[0].x() + i * delta;
+
interpolatedPoints[i].setX(x);
+
interpolatedPoints[i].setY(spline.value(x));
+
}
+
return interpolatedPoints;
+
}
+
+

Member Enumeration Documentation

+ +
+
+ + + + +
enum QwtSpline::SplineType
+
+ +

Spline type.

+ + + +
Enumerator
Natural  +

A natural spline.

+
Periodic  +

A periodic spline.

+
+ +
+
+

Constructor & Destructor Documentation

+ +
+
+ + + + + + + + +
QwtSpline::QwtSpline (const QwtSplineother)
+
+

Copy constructor

+
Parameters
+ + +
otherSpline used for initialization
+
+
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + + +
bool QwtSpline::buildNaturalSpline (const QPolygonF & points)
+
+protected
+
+ +

Determines the coefficients for a natural spline.

+
Returns
true if successful
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
bool QwtSpline::buildPeriodicSpline (const QPolygonF & points)
+
+protected
+
+ +

Determines the coefficients for a periodic spline.

+
Returns
true if successful
+ +
+
+ +
+
+ + + + + + + +
const QVector< double > & QwtSpline::coefficientsA () const
+
+
Returns
A coefficients
+ +
+
+ +
+
+ + + + + + + +
const QVector< double > & QwtSpline::coefficientsB () const
+
+
Returns
B coefficients
+ +
+
+ +
+
+ + + + + + + +
const QVector< double > & QwtSpline::coefficientsC () const
+
+
Returns
C coefficients
+ +
+
+ +
+
+ + + + + + + + +
QwtSpline & QwtSpline::operator= (const QwtSplineother)
+
+

Assignment operator

+
Parameters
+ + +
otherSpline used for initialization
+
+
+
Returns
*this
+ +
+
+ +
+
+ + + + + + + +
QPolygonF QwtSpline::points () const
+
+
Returns
Points, that have been by setPoints()
+ +
+
+ +
+
+ + + + + + + + +
bool QwtSpline::setPoints (const QPolygonF & points)
+
+ +

Calculate the spline coefficients.

+

Depending on the value of periodic, this function will determine the coefficients for a natural or a periodic spline and store them internally.

+
Parameters
+ + +
pointsPoints
+
+
+
Returns
true if successful
+
Warning
The sequence of x (but not y) values has to be strictly monotone increasing, which means points[i].x() < points[i+1].x(). If this is not the case, the function will return false
+ +
+
+ +
+
+ + + + + + + + +
void QwtSpline::setSplineType (SplineType splineType)
+
+

Select the algorithm used for calculating the spline

+
Parameters
+ + +
splineTypeSpline type
+
+
+
See Also
splineType()
+ +
+
+ +
+
+ + + + + + + +
QwtSpline::SplineType QwtSpline::splineType () const
+
+
Returns
the spline type
+
See Also
setSplineType()
+ +
+
+ +
+
+ + + + + + + + +
double QwtSpline::value (double x) const
+
+

Calculate the interpolated function value corresponding to a given argument x.

+
Parameters
+ + +
xCoordinate
+
+
+
Returns
Interpolated coordinate
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_spline_curve_fitter-members.html b/ThirdParty/Qwt/doc/html/class_qwt_spline_curve_fitter-members.html new file mode 100644 index 0000000000..e4e597fbfb --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_spline_curve_fitter-members.html @@ -0,0 +1,116 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtSplineCurveFitter Member List
+
+ + + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_spline_curve_fitter.html b/ThirdParty/Qwt/doc/html/class_qwt_spline_curve_fitter.html new file mode 100644 index 0000000000..e46fd6de66 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_spline_curve_fitter.html @@ -0,0 +1,365 @@ + + + + + + +Qwt User's Guide: QwtSplineCurveFitter Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtSplineCurveFitter Class Reference
+
+
+ +

A curve fitter using cubic splines. + More...

+ +

#include <qwt_curve_fitter.h>

+
+Inheritance diagram for QwtSplineCurveFitter:
+
+
Inheritance graph
+ + +
[legend]
+ + + + +

+Public Types

enum  FitMode { Auto, +Spline, +ParametricSpline + }
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

QwtSplineCurveFitter ()
 Constructor.
 
+virtual ~QwtSplineCurveFitter ()
 Destructor.
 
void setFitMode (FitMode)
 
FitMode fitMode () const
 
void setSpline (const QwtSpline &)
 
const QwtSplinespline () const
 
QwtSplinespline ()
 
void setSplineSize (int size)
 
int splineSize () const
 
virtual QPolygonF fitCurve (const QPolygonF &) const
 
- Public Member Functions inherited from QwtCurveFitter
+virtual ~QwtCurveFitter ()
 Destructor.
 
+ + + + + +

+Additional Inherited Members

- Protected Member Functions inherited from QwtCurveFitter
QwtCurveFitter ()
 Constructor.
 
+

Detailed Description

+

A curve fitter using cubic splines.

+

Member Enumeration Documentation

+ +
+
+

Spline type The default setting is Auto

+
See Also
setFitMode(), FitMode()
+ + + + +
Enumerator
Auto  +

Use the default spline algorithm for polygons with increasing x values ( p[i-1] < p[i] ), otherwise use a parametric spline algorithm.

+
Spline  +

Use a default spline algorithm.

+
ParametricSpline  +

Use a parametric spline algorithm.

+
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + + +
QPolygonF QwtSplineCurveFitter::fitCurve (const QPolygonF & points) const
+
+virtual
+
+

Find a curve which has the best fit to a series of data points

+
Parameters
+ + +
pointsSeries of data points
+
+
+
Returns
Curve points
+ +

Implements QwtCurveFitter.

+ +
+
+ +
+
+ + + + + + + +
QwtSplineCurveFitter::FitMode QwtSplineCurveFitter::fitMode () const
+
+
Returns
Mode representing a spline algorithm
+
See Also
setFitMode()
+ +
+
+ +
+
+ + + + + + + + +
void QwtSplineCurveFitter::setFitMode (FitMode mode)
+
+

Select the algorithm used for building the spline

+
Parameters
+ + +
modeMode representing a spline algorithm
+
+
+
See Also
fitMode()
+ +
+
+ +
+
+ + + + + + + + +
void QwtSplineCurveFitter::setSpline (const QwtSplinespline)
+
+

Assign a spline

+
Parameters
+ + +
splineSpline
+
+
+
See Also
spline()
+ +
+
+ +
+
+ + + + + + + + +
void QwtSplineCurveFitter::setSplineSize (int splineSize)
+
+

Assign a spline size ( has to be at least 10 points )

+
Parameters
+ + +
splineSizeSpline size
+
+
+
See Also
splineSize()
+ +
+
+ +
+
+ + + + + + + +
const QwtSpline & QwtSplineCurveFitter::spline () const
+
+
Returns
Spline
+
See Also
setSpline()
+ +
+
+ +
+
+ + + + + + + +
QwtSpline & QwtSplineCurveFitter::spline ()
+
+
Returns
Spline
+
See Also
setSpline()
+ +
+
+ +
+
+ + + + + + + +
int QwtSplineCurveFitter::splineSize () const
+
+
Returns
Spline size
+
See Also
setSplineSize()
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_spline_curve_fitter__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_spline_curve_fitter__inherit__graph.map new file mode 100644 index 0000000000..36a7516792 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_spline_curve_fitter__inherit__graph.map @@ -0,0 +1,3 @@ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_spline_curve_fitter__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_spline_curve_fitter__inherit__graph.md5 new file mode 100644 index 0000000000..407f8076f7 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_spline_curve_fitter__inherit__graph.md5 @@ -0,0 +1 @@ +7cc37bb83ff3a9fdcee15b8679518661 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_spline_curve_fitter__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_spline_curve_fitter__inherit__graph.png new file mode 100644 index 0000000000..2dbc5d5412 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_spline_curve_fitter__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_symbol-members.html b/ThirdParty/Qwt/doc/html/class_qwt_symbol-members.html new file mode 100644 index 0000000000..5203baffd4 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_symbol-members.html @@ -0,0 +1,161 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtSymbol Member List
+
+
+ +

This is the complete list of members for QwtSymbol, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
AutoCache enum valueQwtSymbol
boundingRect() const QwtSymbolvirtual
brush() const QwtSymbol
Cache enum valueQwtSymbol
CachePolicy enum nameQwtSymbol
cachePolicy() const QwtSymbol
Cross enum valueQwtSymbol
Diamond enum valueQwtSymbol
drawSymbol(QPainter *, const QRectF &) const QwtSymbol
drawSymbol(QPainter *, const QPointF &) const QwtSymbolinline
drawSymbols(QPainter *, const QPolygonF &) const QwtSymbolinline
drawSymbols(QPainter *, const QPointF *, int numPoints) const QwtSymbol
DTriangle enum valueQwtSymbol
Ellipse enum valueQwtSymbol
Graphic enum valueQwtSymbol
graphic() const QwtSymbol
Hexagon enum valueQwtSymbol
HLine enum valueQwtSymbol
invalidateCache()QwtSymbol
isPinPointEnabled() const QwtSymbol
LTriangle enum valueQwtSymbol
NoCache enum valueQwtSymbol
NoSymbol enum valueQwtSymbol
Path enum valueQwtSymbol
path() const QwtSymbol
pen() const QwtSymbol
pinPoint() const QwtSymbol
Pixmap enum valueQwtSymbol
pixmap() const QwtSymbol
QwtSymbol(Style=NoSymbol)QwtSymbol
QwtSymbol(Style, const QBrush &, const QPen &, const QSize &)QwtSymbol
QwtSymbol(const QPainterPath &, const QBrush &, const QPen &)QwtSymbol
Rect enum valueQwtSymbol
renderSymbols(QPainter *, const QPointF *, int numPoints) const QwtSymbolprotectedvirtual
RTriangle enum valueQwtSymbol
setBrush(const QBrush &b)QwtSymbol
setCachePolicy(CachePolicy)QwtSymbol
setColor(const QColor &)QwtSymbolvirtual
setGraphic(const QwtGraphic &)QwtSymbol
setPath(const QPainterPath &)QwtSymbol
setPen(const QColor &, qreal width=0.0, Qt::PenStyle=Qt::SolidLine)QwtSymbol
setPen(const QPen &)QwtSymbol
setPinPoint(const QPointF &pos, bool enable=true)QwtSymbol
setPinPointEnabled(bool)QwtSymbol
setPixmap(const QPixmap &)QwtSymbol
setSize(const QSize &)QwtSymbol
setSize(int width, int height=-1)QwtSymbol
setStyle(Style)QwtSymbol
setSvgDocument(const QByteArray &)QwtSymbol
size() const QwtSymbol
Star1 enum valueQwtSymbol
Star2 enum valueQwtSymbol
style() const QwtSymbol
Style enum nameQwtSymbol
SvgDocument enum valueQwtSymbol
Triangle enum valueQwtSymbol
UserStyle enum valueQwtSymbol
UTriangle enum valueQwtSymbol
VLine enum valueQwtSymbol
XCross enum valueQwtSymbol
~QwtSymbol()QwtSymbolvirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_symbol.html b/ThirdParty/Qwt/doc/html/class_qwt_symbol.html new file mode 100644 index 0000000000..c161ab7f00 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_symbol.html @@ -0,0 +1,1334 @@ + + + + + + +Qwt User's Guide: QwtSymbol Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+ +
+ +

A class for drawing symbols. + More...

+ +

#include <qwt_symbol.h>

+ + + + + + +

+Public Types

enum  Style {
+  NoSymbol = -1, +Ellipse, +Rect, +Diamond, +
+  Triangle, +DTriangle, +UTriangle, +LTriangle, +
+  RTriangle, +Cross, +XCross, +HLine, +
+  VLine, +Star1, +Star2, +Hexagon, +
+  Path, +Pixmap, +Graphic, +SvgDocument, +
+  UserStyle = 1000 +
+ }
 
enum  CachePolicy { NoCache, +Cache, +AutoCache + }
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 QwtSymbol (Style=NoSymbol)
 
 QwtSymbol (Style, const QBrush &, const QPen &, const QSize &)
 Constructor. More...
 
 QwtSymbol (const QPainterPath &, const QBrush &, const QPen &)
 Constructor. More...
 
+virtual ~QwtSymbol ()
 Destructor.
 
void setCachePolicy (CachePolicy)
 
CachePolicy cachePolicy () const
 
void setSize (const QSize &)
 
void setSize (int width, int height=-1)
 Specify the symbol's size. More...
 
const QSize & size () const
 
void setPinPoint (const QPointF &pos, bool enable=true)
 Set and enable a pin point. More...
 
QPointF pinPoint () const
 
void setPinPointEnabled (bool)
 
bool isPinPointEnabled () const
 
virtual void setColor (const QColor &)
 Set the color of the symbol. More...
 
void setBrush (const QBrush &b)
 Assign a brush. More...
 
const QBrush & brush () const
 
void setPen (const QColor &, qreal width=0.0, Qt::PenStyle=Qt::SolidLine)
 
void setPen (const QPen &)
 
const QPen & pen () const
 
void setStyle (Style)
 
Style style () const
 
void setPath (const QPainterPath &)
 Set a painter path as symbol. More...
 
const QPainterPath & path () const
 
void setPixmap (const QPixmap &)
 
const QPixmap & pixmap () const
 
void setGraphic (const QwtGraphic &)
 
const QwtGraphicgraphic () const
 
void setSvgDocument (const QByteArray &)
 
void drawSymbol (QPainter *, const QRectF &) const
 Draw the symbol into a rectangle. More...
 
void drawSymbol (QPainter *, const QPointF &) const
 Draw the symbol at a specified position. More...
 
void drawSymbols (QPainter *, const QPolygonF &) const
 Draw symbols at the specified points. More...
 
void drawSymbols (QPainter *, const QPointF *, int numPoints) const
 
virtual QRect boundingRect () const
 
void invalidateCache ()
 
+ + + +

+Protected Member Functions

virtual void renderSymbols (QPainter *, const QPointF *, int numPoints) const
 
+

Detailed Description

+

A class for drawing symbols.

+

Member Enumeration Documentation

+ +
+
+ + + + +
enum QwtSymbol::CachePolicy
+
+

Depending on the render engine and the complexity of the symbol shape it might be faster to render the symbol to a pixmap and to paint this pixmap.

+

F.e. the raster paint engine is a pure software renderer where in cache mode a draw operation usually ends in raster operation with the the backing store, that are usually faster, than the algorithms for rendering polygons. But the opposite can be expected for graphic pipelines that can make use of hardware acceleration.

+

The default setting is AutoCache

+
See Also
setCachePolicy(), cachePolicy()
+
Note
The policy has no effect, when the symbol is painted to a vector graphics format ( PDF, SVG ).
+
Warning
Since Qt 4.8 raster is the default backend on X11
+ + + + +
Enumerator
NoCache  +

Don't use a pixmap cache.

+
Cache  +

Always use a pixmap cache.

+
AutoCache  +

Use a cache when one of the following conditions is true:

+
    +
  • The symbol is rendered with the software renderer ( QPaintEngine::Raster )
  • +
+
+ +
+
+ +
+
+ + + + +
enum QwtSymbol::Style
+
+

Symbol Style

+
See Also
setStyle(), style()
+ + + + + + + + + + + + + + + + + + + + + + +
Enumerator
NoSymbol  +

No Style. The symbol cannot be drawn.

+
Ellipse  +

Ellipse or circle.

+
Rect  +

Rectangle.

+
Diamond  +

Diamond.

+
Triangle  +

Triangle pointing upwards.

+
DTriangle  +

Triangle pointing downwards.

+
UTriangle  +

Triangle pointing upwards.

+
LTriangle  +

Triangle pointing left.

+
RTriangle  +

Triangle pointing right.

+
Cross  +

Cross (+)

+
XCross  +

Diagonal cross (X)

+
HLine  +

Horizontal line.

+
VLine  +

Vertical line.

+
Star1  +

X combined with +.

+
Star2  +

Six-pointed star.

+
Hexagon  +

Hexagon.

+
Path  +

The symbol is represented by a painter path, where the origin ( 0, 0 ) of the path coordinate system is mapped to the position of the symbol.

+
See Also
setPath(), path()
+
Pixmap  +

The symbol is represented by a pixmap. The pixmap is centered or aligned to its pin point.

+
See Also
setPinPoint()
+
Graphic  +

The symbol is represented by a graphic. The graphic is centered or aligned to its pin point.

+
See Also
setPinPoint()
+
SvgDocument  +

The symbol is represented by a SVG graphic. The graphic is centered or aligned to its pin point.

+
See Also
setPinPoint()
+
UserStyle  +

Styles >= QwtSymbol::UserSymbol are reserved for derived classes of QwtSymbol that overload drawSymbols() with additional application specific symbol types.

+
+ +
+
+

Constructor & Destructor Documentation

+ +
+
+ + + + + + + + +
QwtSymbol::QwtSymbol (Style style = NoSymbol)
+
+

Default Constructor

+
Parameters
+ + +
styleSymbol Style
+
+
+

The symbol is constructed with gray interior, black outline with zero width, no size and style 'NoSymbol'.

+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
QwtSymbol::QwtSymbol (QwtSymbol::Style style,
const QBrush & brush,
const QPen & pen,
const QSize & size 
)
+
+ +

Constructor.

+
Parameters
+ + + + + +
styleSymbol Style
brushbrush to fill the interior
penoutline pen
sizesize
+
+
+
See Also
setStyle(), setBrush(), setPen(), setSize()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
QwtSymbol::QwtSymbol (const QPainterPath & path,
const QBrush & brush,
const QPen & pen 
)
+
+ +

Constructor.

+

The symbol gets initialized by a painter path. The style is set to QwtSymbol::Path, the size is set to empty ( the path is displayed unscaled ).

+
Parameters
+ + + + +
pathpainter path
brushbrush to fill the interior
penoutline pen
+
+
+
See Also
setPath(), setBrush(), setPen(), setSize()
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + +
QRect QwtSymbol::boundingRect () const
+
+virtual
+
+

Calculate the bounding rectangle for a symbol at position (0,0).

+
Returns
Bounding rectangle
+ +
+
+ +
+
+ + + + + + + +
const QBrush & QwtSymbol::brush () const
+
+
Returns
Brush
+
See Also
setBrush()
+ +
+
+ +
+
+ + + + + + + +
QwtSymbol::CachePolicy QwtSymbol::cachePolicy () const
+
+
Returns
Cache policy
+
See Also
CachePolicy, setCachePolicy()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtSymbol::drawSymbol (QPainter * painter,
const QRectF & rect 
) const
+
+ +

Draw the symbol into a rectangle.

+

The symbol is painted centered and scaled into the target rectangle. It is always painted uncached and the pin point is ignored.

+

This method is primarily intended for drawing a symbol to the legend.

+
Parameters
+ + + +
painterPainter
rectTarget rectangle for the symbol
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void QwtSymbol::drawSymbol (QPainter * painter,
const QPointF & pos 
) const
+
+inline
+
+ +

Draw the symbol at a specified position.

+
Parameters
+ + + +
painterPainter
posPosition of the symbol in screen coordinates
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void QwtSymbol::drawSymbols (QPainter * painter,
const QPolygonF & points 
) const
+
+inline
+
+ +

Draw symbols at the specified points.

+
Parameters
+ + + +
painterPainter
pointsPositions of the symbols in screen coordinates
+
+
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void QwtSymbol::drawSymbols (QPainter * painter,
const QPointF * points,
int numPoints 
) const
+
+

Render an array of symbols

+

Painting several symbols is more effective than drawing symbols one by one, as a couple of layout calculations and setting of pen/brush can be done once for the complete array.

+
Parameters
+ + + + +
painterPainter
pointsArray of points
numPointsNumber of points
+
+
+ +
+
+ +
+
+ + + + + + + +
const QwtGraphic & QwtSymbol::graphic () const
+
+
Returns
Assigned graphic
+
See Also
setGraphic()
+ +
+
+ +
+
+ + + + + + + +
void QwtSymbol::invalidateCache ()
+
+

Invalidate the cached symbol pixmap

+

The symbol invalidates its cache, whenever an attribute is changed that has an effect ob how to display a symbol. In case of derived classes with individual styles ( >= QwtSymbol::UserStyle ) it might be necessary to call invalidateCache() for attributes that are relevant for this style.

+
See Also
CachePolicy, setCachePolicy(), drawSymbols()
+ +
+
+ +
+
+ + + + + + + +
bool QwtSymbol::isPinPointEnabled () const
+
+
Returns
True, when the pin point translation is enabled
+
See Also
setPinPoint(), setPinPointEnabled()
+ +
+
+ +
+
+ + + + + + + +
const QPainterPath & QwtSymbol::path () const
+
+
Returns
Painter path for displaying the symbol
+
See Also
setPath()
+ +
+
+ +
+
+ + + + + + + +
const QPen & QwtSymbol::pen () const
+
+
Returns
Pen
+
See Also
setPen(), brush()
+ +
+
+ +
+
+ + + + + + + +
QPointF QwtSymbol::pinPoint () const
+
+
Returns
Pin point
+
See Also
setPinPoint(), setPinPointEnabled()
+ +
+
+ +
+
+ + + + + + + +
const QPixmap & QwtSymbol::pixmap () const
+
+
Returns
Assigned pixmap
+
See Also
setPixmap()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
void QwtSymbol::renderSymbols (QPainter * painter,
const QPointF * points,
int numPoints 
) const
+
+protectedvirtual
+
+

Render the symbol to series of points

+
Parameters
+ + + + +
painterQt painter
pointsPositions of the symbols
numPointsNumber of points
+
+
+ +
+
+ +
+
+ + + + + + + + +
void QwtSymbol::setBrush (const QBrush & brush)
+
+ +

Assign a brush.

+

The brush is used to draw the interior of the symbol.

+
Parameters
+ + +
brushBrush
+
+
+
See Also
brush()
+ +
+
+ +
+
+ + + + + + + + +
void QwtSymbol::setCachePolicy (QwtSymbol::CachePolicy policy)
+
+

Change the cache policy

+

The default policy is AutoCache

+
Parameters
+ + +
policyCache policy
+
+
+
See Also
CachePolicy, cachePolicy()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtSymbol::setColor (const QColor & color)
+
+virtual
+
+ +

Set the color of the symbol.

+

Change the color of the brush for symbol types with a filled area. For all other symbol types the color will be assigned to the pen.

+
Parameters
+ + +
colorColor
+
+
+
See Also
setBrush(), setPen(), brush(), pen()
+ +
+
+ +
+
+ + + + + + + + +
void QwtSymbol::setGraphic (const QwtGraphicgraphic)
+
+

Set a graphic as symbol

+
Parameters
+ + +
graphicGraphic
+
+
+
See Also
graphic(), setPixmap()
+
Note
the style() is set to QwtSymbol::Graphic
+
+brush() and pen() have no effect
+ +
+
+ +
+
+ + + + + + + + +
void QwtSymbol::setPath (const QPainterPath & path)
+
+ +

Set a painter path as symbol.

+

The symbol is represented by a painter path, where the origin ( 0, 0 ) of the path coordinate system is mapped to the position of the symbol.

+

When the symbol has valid size the painter path gets scaled to fit into the size. Otherwise the symbol size depends on the bounding rectangle of the path.

+

The following code defines a symbol drawing an arrow:

+
#include <qwt_symbol.h>
+
+QwtSymbol *symbol = new QwtSymbol();
+
+QPen pen( Qt::black, 2 );
+pen.setJoinStyle( Qt::MiterJoin );
+
+symbol->setPen( pen );
+symbol->setBrush( Qt::red );
+
+QPainterPath path;
+path.moveTo( 0, 8 );
+path.lineTo( 0, 5 );
+path.lineTo( -3, 5 );
+path.lineTo( 0, 0 );
+path.lineTo( 3, 5 );
+path.lineTo( 0, 5 );
+
+QTransform transform;
+transform.rotate( -30.0 );
+path = transform.map( path );
+
+symbol->setPath( path );
+symbol->setPinPoint( QPointF( 0.0, 0.0 ) );
+
+setSize( 10, 14 );
+
Parameters
+ + +
pathPainter path
+
+
+
Note
The style is implicitely set to QwtSymbol::Path.
+
See Also
path(), setSize()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void QwtSymbol::setPen (const QColor & color,
qreal width = 0.0,
Qt::PenStyle style = Qt::SolidLine 
)
+
+

Build and assign a pen

+

In Qt5 the default pen width is 1.0 ( 0.0 in Qt4 ) what makes it non cosmetic ( see QPen::isCosmetic() ). This method has been introduced to hide this incompatibility.

+
Parameters
+ + + + +
colorPen color
widthPen width
stylePen style
+
+
+
See Also
pen(), brush()
+ +
+
+ +
+
+ + + + + + + + +
void QwtSymbol::setPen (const QPen & pen)
+
+

Assign a pen

+

The pen is used to draw the symbol's outline.

+
Parameters
+ + +
penPen
+
+
+
See Also
pen(), setBrush()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtSymbol::setPinPoint (const QPointF & pos,
bool enable = true 
)
+
+ +

Set and enable a pin point.

+

The position of a complex symbol is not always aligned to its center ( f.e an arrow, where the peak points to a position ). The pin point defines the position inside of a Pixmap, Graphic, SvgDocument or PainterPath symbol where the represented point has to be aligned to.

+
Parameters
+ + + +
posPosition
enableEn/Disable the pin point alignment
+
+
+
See Also
pinPoint(), setPinPointEnabled()
+ +
+
+ +
+
+ + + + + + + + +
void QwtSymbol::setPinPointEnabled (bool on)
+
+

En/Disable the pin point alignment

+
Parameters
+ + +
onEnabled, when on is true
+
+
+
See Also
setPinPoint(), isPinPointEnabled()
+ +
+
+ +
+
+ + + + + + + + +
void QwtSymbol::setPixmap (const QPixmap & pixmap)
+
+

Set a pixmap as symbol

+
Parameters
+ + +
pixmapPixmap
+
+
+
See Also
pixmap(), setGraphic()
+
Note
the style() is set to QwtSymbol::Pixmap
+
+brush() and pen() have no effect
+ +
+
+ +
+
+ + + + + + + + +
void QwtSymbol::setSize (const QSize & size)
+
+

Set the symbol's size

+
Parameters
+ + +
sizeSize
+
+
+
See Also
size()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtSymbol::setSize (int width,
int height = -1 
)
+
+ +

Specify the symbol's size.

+

If the 'h' parameter is left out or less than 0, and the 'w' parameter is greater than or equal to 0, the symbol size will be set to (w,w).

+
Parameters
+ + + +
widthWidth
heightHeight (defaults to -1)
+
+
+
See Also
size()
+ +
+
+ +
+
+ + + + + + + + +
void QwtSymbol::setStyle (QwtSymbol::Style style)
+
+

Specify the symbol style

+
Parameters
+ + +
styleStyle
+
+
+
See Also
style()
+ +
+
+ +
+
+ + + + + + + + +
void QwtSymbol::setSvgDocument (const QByteArray & svgDocument)
+
+

Set a SVG icon as symbol

+
Parameters
+ + +
svgDocumentSVG icon
+
+
+
See Also
setGraphic(), setPixmap()
+
Note
the style() is set to QwtSymbol::SvgDocument
+
+brush() and pen() have no effect
+ +
+
+ +
+
+ + + + + + + +
const QSize & QwtSymbol::size () const
+
+
Returns
Size
+
See Also
setSize()
+ +
+
+ +
+
+ + + + + + + +
QwtSymbol::Style QwtSymbol::style () const
+
+
Returns
Current symbol style
+
See Also
setStyle()
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_synthetic_point_data-members.html b/ThirdParty/Qwt/doc/html/class_qwt_synthetic_point_data-members.html new file mode 100644 index 0000000000..6f0f82e1b9 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_synthetic_point_data-members.html @@ -0,0 +1,114 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtSyntheticPointData Member List
+
+
+ +

This is the complete list of members for QwtSyntheticPointData, including all inherited members.

+ + + + + + + + + + + + + + + +
boundingRect() const QwtSyntheticPointDatavirtual
d_boundingRectQwtSeriesData< QPointF >mutableprotected
interval() const QwtSyntheticPointData
QwtSeriesData()QwtSeriesData< QPointF >
QwtSyntheticPointData(size_t size, const QwtInterval &=QwtInterval())QwtSyntheticPointData
rectOfInterest() const QwtSyntheticPointData
sample(size_t i) const QwtSyntheticPointDatavirtual
setInterval(const QwtInterval &)QwtSyntheticPointData
setRectOfInterest(const QRectF &)QwtSyntheticPointDatavirtual
setSize(size_t size)QwtSyntheticPointData
size() const QwtSyntheticPointDatavirtual
x(uint index) const QwtSyntheticPointDatavirtual
y(double x) const =0QwtSyntheticPointDatapure virtual
~QwtSeriesData()QwtSeriesData< QPointF >virtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_synthetic_point_data.html b/ThirdParty/Qwt/doc/html/class_qwt_synthetic_point_data.html new file mode 100644 index 0000000000..0044fd09b5 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_synthetic_point_data.html @@ -0,0 +1,503 @@ + + + + + + +Qwt User's Guide: QwtSyntheticPointData Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtSyntheticPointData Class Referenceabstract
+
+
+ +

Synthetic point data. + More...

+ +

#include <qwt_point_data.h>

+
+Inheritance diagram for QwtSyntheticPointData:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 QwtSyntheticPointData (size_t size, const QwtInterval &=QwtInterval())
 
void setSize (size_t size)
 
virtual size_t size () const
 
void setInterval (const QwtInterval &)
 
QwtInterval interval () const
 
virtual QRectF boundingRect () const
 Calculate the bounding rectangle. More...
 
virtual QPointF sample (size_t i) const
 
virtual double y (double x) const =0
 
virtual double x (uint index) const
 
virtual void setRectOfInterest (const QRectF &)
 
QRectF rectOfInterest () const
 
- Public Member Functions inherited from QwtSeriesData< QPointF >
QwtSeriesData ()
 Constructor.
 
+virtual ~QwtSeriesData ()
 Destructor.
 
+ + + + + +

+Additional Inherited Members

- Protected Attributes inherited from QwtSeriesData< QPointF >
+QRectF d_boundingRect
 Can be used to cache a calculated bounding rectangle.
 
+

Detailed Description

+

Synthetic point data.

+

QwtSyntheticPointData provides a fixed number of points for an interval. The points are calculated in equidistant steps in x-direction.

+

If the interval is invalid, the points are calculated for the "rectangle of interest", what normally is the displayed area on the plot canvas. In this mode you get different levels of detail, when zooming in/out.

+
Example
+

The following example shows how to implement a sinus curve.

+
#include <cmath>
+
#include <qwt_series_data.h>
+
#include <qwt_plot_curve.h>
+
#include <qwt_plot.h>
+
#include <qapplication.h>
+
+
class SinusData: public QwtSyntheticPointData
+
{
+
public:
+
SinusData():
+ +
{
+
}
+
+
virtual double y( double x ) const
+
{
+
return qSin( x );
+
}
+
};
+
+
int main(int argc, char **argv)
+
{
+
QApplication a( argc, argv );
+
+
QwtPlot plot;
+
plot.setAxisScale( QwtPlot::xBottom, 0.0, 10.0 );
+
plot.setAxisScale( QwtPlot::yLeft, -1.0, 1.0 );
+
+
QwtPlotCurve *curve = new QwtPlotCurve( "y = sin(x)" );
+
curve->setData( new SinusData() );
+
curve->attach( &plot );
+
+
plot.show();
+
return a.exec();
+
}
+

Constructor & Destructor Documentation

+ +
+
+ + + + + + + + + + + + + + + + + + +
QwtSyntheticPointData::QwtSyntheticPointData (size_t size,
const QwtIntervalinterval = QwtInterval() 
)
+
+

Constructor

+
Parameters
+ + + +
sizeNumber of points
intervalBounding interval for the points
+
+
+
See Also
setInterval(), setSize()
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + +
QRectF QwtSyntheticPointData::boundingRect () const
+
+virtual
+
+ +

Calculate the bounding rectangle.

+

This implementation iterates over all points, what could often be implemented much faster using the characteristics of the series. When there are many points it is recommended to overload and reimplement this method using the characteristics of the series ( if possible ).

+
Returns
Bounding rectangle
+ +

Implements QwtSeriesData< QPointF >.

+ +
+
+ +
+
+ + + + + + + +
QwtInterval QwtSyntheticPointData::interval () const
+
+
Returns
Bounding interval
+
See Also
setInterval(), size()
+ +
+
+ +
+
+ + + + + + + +
QRectF QwtSyntheticPointData::rectOfInterest () const
+
+
Returns
"rectangle of interest"
+
See Also
setRectOfInterest()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
QPointF QwtSyntheticPointData::sample (size_t index) const
+
+virtual
+
+

Calculate the point from an index

+
Parameters
+ + +
indexIndex
+
+
+
Returns
QPointF(x(index), y(x(index)));
+
Warning
For invalid indices ( index < 0 || index >= size() ) (0, 0) is returned.
+ +

Implements QwtSeriesData< QPointF >.

+ +
+
+ +
+
+ + + + + + + + +
void QwtSyntheticPointData::setInterval (const QwtIntervalinterval)
+
+

Set the bounding interval

+
Parameters
+ + +
intervalInterval
+
+
+
See Also
interval(), setSize()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtSyntheticPointData::setRectOfInterest (const QRectF & rect)
+
+virtual
+
+

Set a the "rectangle of interest"

+

QwtPlotSeriesItem defines the current area of the plot canvas as "rect of interest" ( QwtPlotSeriesItem::updateScaleDiv() ).

+

If interval().isValid() == false the x values are calculated in the interval rect.left() -> rect.right().

+
See Also
rectOfInterest()
+ +

Reimplemented from QwtSeriesData< QPointF >.

+ +
+
+ +
+
+ + + + + + + + +
void QwtSyntheticPointData::setSize (size_t size)
+
+

Change the number of points

+
Parameters
+ + +
sizeNumber of points
+
+
+
See Also
size(), setInterval()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
size_t QwtSyntheticPointData::size () const
+
+virtual
+
+
Returns
Number of points
+
See Also
setSize(), interval()
+ +

Implements QwtSeriesData< QPointF >.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
double QwtSyntheticPointData::x (uint index) const
+
+virtual
+
+

Calculate a x-value from an index

+

x values are calculated by dividing an interval into equidistant steps. If !interval().isValid() the interval is calculated from the "rectangle of interest".

+
Parameters
+ + +
indexIndex of the requested point
+
+
+
Returns
Calculated x coordinate
+
See Also
interval(), rectOfInterest(), y()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
virtual double QwtSyntheticPointData::y (double x) const
+
+pure virtual
+
+

Calculate a y value for a x value

+
Parameters
+ + +
xx value
+
+
+
Returns
Corresponding y value
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_synthetic_point_data__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_synthetic_point_data__inherit__graph.map new file mode 100644 index 0000000000..87a4a867d6 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_synthetic_point_data__inherit__graph.map @@ -0,0 +1,3 @@ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_synthetic_point_data__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_synthetic_point_data__inherit__graph.md5 new file mode 100644 index 0000000000..1a3b6dc023 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_synthetic_point_data__inherit__graph.md5 @@ -0,0 +1 @@ +0870554a4889e8ac532b7e8836786b12 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_synthetic_point_data__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_synthetic_point_data__inherit__graph.png new file mode 100644 index 0000000000..5ee1657049 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_synthetic_point_data__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_system_clock-members.html b/ThirdParty/Qwt/doc/html/class_qwt_system_clock-members.html new file mode 100644 index 0000000000..76498bdd18 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_system_clock-members.html @@ -0,0 +1,106 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtSystemClock Member List
+
+
+ +

This is the complete list of members for QwtSystemClock, including all inherited members.

+ + + + + + + +
elapsed() const QwtSystemClock
isNull() const QwtSystemClock
QwtSystemClock()QwtSystemClock
restart()QwtSystemClock
start()QwtSystemClock
~QwtSystemClock()QwtSystemClockvirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_system_clock.html b/ThirdParty/Qwt/doc/html/class_qwt_system_clock.html new file mode 100644 index 0000000000..c33ba6a5bc --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_system_clock.html @@ -0,0 +1,196 @@ + + + + + + +Qwt User's Guide: QwtSystemClock Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtSystemClock Class Reference
+
+
+ +

QwtSystemClock provides high resolution clock time functions. + More...

+ +

#include <qwt_system_clock.h>

+ + + + + + + + + + + + + + + + +

+Public Member Functions

QwtSystemClock ()
 Constructs a null clock object.
 
+virtual ~QwtSystemClock ()
 Destructor.
 
bool isNull () const
 
void start ()
 
double restart ()
 
double elapsed () const
 
+

Detailed Description

+

QwtSystemClock provides high resolution clock time functions.

+

Sometimes the resolution offered by QTime ( millisecond ) is not accurate enough for implementing time measurements ( f.e. sampling ). QwtSystemClock offers a subset of the QTime functionality using higher resolution timers ( if possible ).

+

Precision and time intervals are multiples of milliseconds (ms).

+
Note
The implementation uses high-resolution performance counter on Windows, mach_absolute_time() on the Mac or POSIX timers on other systems. If none is available it falls back on QTimer.
+

Member Function Documentation

+ +
+
+ + + + + + + +
double QwtSystemClock::elapsed () const
+
+
Returns
Number of milliseconds that have elapsed since the last time start() or restart() was called or 0.0 for null clocks.
+ +
+
+ +
+
+ + + + + + + +
bool QwtSystemClock::isNull () const
+
+
Returns
true if the clock has never been started.
+ +
+
+ +
+
+ + + + + + + +
double QwtSystemClock::restart ()
+
+

Set the start time to the current time

+
Returns
Time, that is elapsed since the previous start time.
+ +
+
+ +
+
+ + + + + + + +
void QwtSystemClock::start ()
+
+

Sets the start time to the current time.

+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_text-members.html b/ThirdParty/Qwt/doc/html/class_qwt_text-members.html new file mode 100644 index 0000000000..27f9202205 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_text-members.html @@ -0,0 +1,149 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtText Member List
+
+
+ +

This is the complete list of members for QwtText, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
AutoText enum valueQwtText
backgroundBrush() const QwtText
borderPen() const QwtText
borderRadius() const QwtText
color() const QwtText
draw(QPainter *painter, const QRectF &rect) const QwtText
font() const QwtText
heightForWidth(double width, const QFont &=QFont()) const QwtText
isEmpty() const QwtTextinline
isNull() const QwtTextinline
LayoutAttribute enum nameQwtText
LayoutAttributes typedefQwtText
MathMLText enum valueQwtText
MinimumLayout enum valueQwtText
operator!=(const QwtText &) const QwtText
operator=(const QwtText &)QwtText
operator==(const QwtText &) const QwtText
OtherFormat enum valueQwtText
PaintAttribute enum nameQwtText
PaintAttributes typedefQwtText
PaintBackground enum valueQwtText
PaintUsingTextColor enum valueQwtText
PaintUsingTextFont enum valueQwtText
PlainText enum valueQwtText
QwtText(const QString &=QString::null, TextFormat textFormat=AutoText)QwtText
QwtText(const QwtText &)QwtText
renderFlags() const QwtText
RichText enum valueQwtText
setBackgroundBrush(const QBrush &)QwtText
setBorderPen(const QPen &)QwtText
setBorderRadius(double)QwtText
setColor(const QColor &)QwtText
setFont(const QFont &)QwtText
setLayoutAttribute(LayoutAttribute, bool on=true)QwtText
setPaintAttribute(PaintAttribute, bool on=true)QwtText
setRenderFlags(int flags)QwtText
setText(const QString &, QwtText::TextFormat textFormat=AutoText)QwtText
setTextEngine(QwtText::TextFormat, QwtTextEngine *)QwtTextstatic
testLayoutAttribute(LayoutAttribute) const QwtText
testPaintAttribute(PaintAttribute) const QwtText
text() const QwtText
textEngine(const QString &text, QwtText::TextFormat=AutoText)QwtTextstatic
textEngine(QwtText::TextFormat)QwtTextstatic
TeXText enum valueQwtText
TextFormat enum nameQwtText
textSize(const QFont &=QFont()) const QwtText
usedColor(const QColor &) const QwtText
usedFont(const QFont &) const QwtText
~QwtText()QwtText
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_text.html b/ThirdParty/Qwt/doc/html/class_qwt_text.html new file mode 100644 index 0000000000..f1b5b5d0ff --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_text.html @@ -0,0 +1,1081 @@ + + + + + + +Qwt User's Guide: QwtText Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+ +
+ +

A class representing a text. + More...

+ +

#include <qwt_text.h>

+ + + + + + + + + + + + + + + + + +

+Public Types

enum  TextFormat {
+  AutoText = 0, +PlainText, +RichText, +MathMLText, +
+  TeXText, +OtherFormat = 100 +
+ }
 Text format. More...
 
enum  PaintAttribute { PaintUsingTextFont = 0x01, +PaintUsingTextColor = 0x02, +PaintBackground = 0x04 + }
 Paint Attributes. More...
 
enum  LayoutAttribute { MinimumLayout = 0x01 + }
 Layout Attributes The layout attributes affects some aspects of the layout of the text. More...
 
+typedef QFlags< PaintAttributePaintAttributes
 Paint attributes.
 
+typedef QFlags< LayoutAttributeLayoutAttributes
 Layout attributes.
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 QwtText (const QString &=QString::null, TextFormat textFormat=AutoText)
 
QwtText (const QwtText &)
 Copy constructor.
 
~QwtText ()
 Destructor.
 
+QwtTextoperator= (const QwtText &)
 Assignment operator.
 
+bool operator== (const QwtText &) const
 Relational operator.
 
+bool operator!= (const QwtText &) const
 Relational operator.
 
void setText (const QString &, QwtText::TextFormat textFormat=AutoText)
 
QString text () const
 
bool isNull () const
 
bool isEmpty () const
 
void setFont (const QFont &)
 
+QFont font () const
 Return the font.
 
QFont usedFont (const QFont &) const
 
void setRenderFlags (int flags)
 Change the render flags. More...
 
int renderFlags () const
 
void setColor (const QColor &)
 
+QColor color () const
 Return the pen color, used for painting the text.
 
QColor usedColor (const QColor &) const
 
void setBorderRadius (double)
 
double borderRadius () const
 
void setBorderPen (const QPen &)
 
QPen borderPen () const
 
void setBackgroundBrush (const QBrush &)
 
QBrush backgroundBrush () const
 
void setPaintAttribute (PaintAttribute, bool on=true)
 
bool testPaintAttribute (PaintAttribute) const
 
void setLayoutAttribute (LayoutAttribute, bool on=true)
 
bool testLayoutAttribute (LayoutAttribute) const
 
double heightForWidth (double width, const QFont &=QFont()) const
 
QSizeF textSize (const QFont &=QFont()) const
 
void draw (QPainter *painter, const QRectF &rect) const
 
+ + + + + + + + +

+Static Public Member Functions

static const QwtTextEnginetextEngine (const QString &text, QwtText::TextFormat=AutoText)
 
static const QwtTextEnginetextEngine (QwtText::TextFormat)
 Find the text engine for a text format. More...
 
static void setTextEngine (QwtText::TextFormat, QwtTextEngine *)
 
+

Detailed Description

+

A class representing a text.

+

A QwtText is a text including a set of attributes how to render it.

+
    +
  • Format
    + A text might include control sequences (f.e tags) describing how to render it. Each format (f.e MathML, TeX, Qt Rich Text) has its own set of control sequences, that can be handles by a special QwtTextEngine for this format.
  • +
  • Background
    + A text might have a background, defined by a QPen and QBrush to improve its visibility. The corners of the background might be rounded.
  • +
  • Font
    + A text might have an individual font.
  • +
  • Color
    + A text might have an individual color.
  • +
  • Render Flags
    + Flags from Qt::AlignmentFlag and Qt::TextFlag used like in QPainter::drawText().
  • +
+
See Also
QwtTextEngine, QwtTextLabel
+

Member Enumeration Documentation

+ +
+
+ + + + +
enum QwtText::LayoutAttribute
+
+ +

Layout Attributes The layout attributes affects some aspects of the layout of the text.

+ + +
Enumerator
MinimumLayout  +

Layout the text without its margins. This mode is useful if a text needs to be aligned accurately, like the tick labels of a scale. If QwtTextEngine::textMargins is not implemented for the format of the text, MinimumLayout has no effect.

+
+ +
+
+ +
+
+ + + + +
enum QwtText::PaintAttribute
+
+ +

Paint Attributes.

+

Font and color and background are optional attributes of a QwtText. The paint attributes hold the information, if they are set.

+ + + + +
Enumerator
PaintUsingTextFont  +

The text has an individual font.

+
PaintUsingTextColor  +

The text has an individual color.

+
PaintBackground  +

The text has an individual background.

+
+ +
+
+ +
+
+ + + + +
enum QwtText::TextFormat
+
+ +

Text format.

+

The text format defines the QwtTextEngine, that is used to render the text.

+
See Also
QwtTextEngine, setTextEngine()
+ + + + + + + +
Enumerator
AutoText  +

The text format is determined using QwtTextEngine::mightRender() for all available text engines in increasing order > PlainText. If none of the text engines can render the text is rendered like QwtText::PlainText.

+
PlainText  +

Draw the text as it is, using a QwtPlainTextEngine.

+
RichText  +

Use the Scribe framework (Qt Rich Text) to render the text.

+
MathMLText  +
      Use a MathML (http://en.wikipedia.org/wiki/MathML) render engine
+      to display the text. The Qwt MathML extension offers such an engine
+      based on the MathML renderer of the Qt solutions package. 
+      To enable MathML support the following code needs to be added to the
+      application:
+
QwtText::setTextEngine(QwtText::MathMLText, new QwtMathMLTextEngine()); 
TeXText  +

Use a TeX (http://en.wikipedia.org/wiki/TeX) render engine to display the text ( not implemented yet ).

+
OtherFormat  +

The number of text formats can be extended using setTextEngine. Formats >= QwtText::OtherFormat are not used by Qwt.

+
+ +
+
+

Constructor & Destructor Documentation

+ +
+
+ + + + + + + + + + + + + + + + + + +
QwtText::QwtText (const QString & text = QString::null,
QwtText::TextFormat textFormat = AutoText 
)
+
+

Constructor

+
Parameters
+ + + +
textText content
textFormatText format
+
+
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + + + +
QBrush QwtText::backgroundBrush () const
+
+
Returns
Background brush
+
See Also
setBackgroundBrush(), borderPen()
+ +
+
+ +
+
+ + + + + + + +
QPen QwtText::borderPen () const
+
+
Returns
Background pen
+
See Also
setBorderPen(), backgroundBrush()
+ +
+
+ +
+
+ + + + + + + +
double QwtText::borderRadius () const
+
+
Returns
Radius for the corners of the border frame
+
See Also
setBorderRadius(), borderPen(), backgroundBrush()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtText::draw (QPainter * painter,
const QRectF & rect 
) const
+
+

Draw a text into a rectangle

+
Parameters
+ + + +
painterPainter
rectRectangle
+
+
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
double QwtText::heightForWidth (double width,
const QFont & defaultFont = QFont() 
) const
+
+

Find the height for a given width

+
Parameters
+ + + +
defaultFontFont, used for the calculation if the text has no font
widthWidth
+
+
+
Returns
Calculated height
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool QwtText::isEmpty () const
+
+inline
+
+
Returns
text().isEmpty()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
bool QwtText::isNull () const
+
+inline
+
+
Returns
text().isNull()
+ +
+
+ +
+
+ + + + + + + +
int QwtText::renderFlags () const
+
+
Returns
Render flags
+
See Also
setRenderFlags()
+ +
+
+ +
+
+ + + + + + + + +
void QwtText::setBackgroundBrush (const QBrush & brush)
+
+

Set the background brush

+
Parameters
+ + +
brushBackground brush
+
+
+
See Also
backgroundBrush(), setBorderPen()
+ +
+
+ +
+
+ + + + + + + + +
void QwtText::setBorderPen (const QPen & pen)
+
+

Set the background pen

+
Parameters
+ + +
penBackground pen
+
+
+
See Also
borderPen(), setBackgroundBrush()
+ +
+
+ +
+
+ + + + + + + + +
void QwtText::setBorderRadius (double radius)
+
+

Set the radius for the corners of the border frame

+
Parameters
+ + +
radiusRadius of a rounded corner
+
+
+
See Also
borderRadius(), setBorderPen(), setBackgroundBrush()
+ +
+
+ +
+
+ + + + + + + + +
void QwtText::setColor (const QColor & color)
+
+

Set the pen color used for drawing the text.

+
Parameters
+ + +
colorColor
+
+
+
Note
Setting the color might have no effect, when the text contains control sequences for setting colors.
+ +
+
+ +
+
+ + + + + + + + +
void QwtText::setFont (const QFont & font)
+
+

Set the font.

+
Parameters
+ + +
fontFont
+
+
+
Note
Setting the font might have no effect, when the text contains control sequences for setting fonts.
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtText::setLayoutAttribute (LayoutAttribute attribute,
bool on = true 
)
+
+

Change a layout attribute

+
Parameters
+ + + +
attributeLayout attribute
onOn/Off
+
+
+
See Also
testLayoutAttribute()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtText::setPaintAttribute (PaintAttribute attribute,
bool on = true 
)
+
+

Change a paint attribute

+
Parameters
+ + + +
attributePaint attribute
onOn/Off
+
+
+
Note
Used by setFont(), setColor(), setBorderPen() and setBackgroundBrush()
+
See Also
testPaintAttribute()
+ +
+
+ +
+
+ + + + + + + + +
void QwtText::setRenderFlags (int renderFlags)
+
+ +

Change the render flags.

+

The default setting is Qt::AlignCenter

+
Parameters
+ + +
renderFlagsBitwise OR of the flags used like in QPainter::drawText()
+
+
+
See Also
renderFlags(), QwtTextEngine::draw()
+
Note
Some renderFlags might have no effect, depending on the text format.
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtText::setText (const QString & text,
QwtText::TextFormat textFormat = AutoText 
)
+
+

Assign a new text content

+
Parameters
+ + + +
textText content
textFormatText format
+
+
+
See Also
text()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void QwtText::setTextEngine (QwtText::TextFormat format,
QwtTextEngineengine 
)
+
+static
+
+

Assign/Replace a text engine for a text format

+

With setTextEngine it is possible to extend Qwt with other types of text formats.

+

For QwtText::PlainText it is not allowed to assign a engine == NULL.

+
Parameters
+ + + +
formatText format
engineText engine
+
+
+
See Also
QwtMathMLTextEngine
+
Warning
Using QwtText::AutoText does nothing.
+ +
+
+ +
+
+ + + + + + + + +
bool QwtText::testLayoutAttribute (LayoutAttribute attribute) const
+
+

Test a layout attribute

+
Parameters
+ + +
attributeLayout attribute
+
+
+
Returns
true, if attribute is enabled
+
See Also
setLayoutAttribute()
+ +
+
+ +
+
+ + + + + + + + +
bool QwtText::testPaintAttribute (PaintAttribute attribute) const
+
+

Test a paint attribute

+
Parameters
+ + +
attributePaint attribute
+
+
+
Returns
true, if attribute is enabled
+
See Also
setPaintAttribute()
+ +
+
+ +
+
+ + + + + + + +
QString QwtText::text () const
+
+
Returns
Text as QString.
+
See Also
setText()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
const QwtTextEngine * QwtText::textEngine (const QString & text,
QwtText::TextFormat format = AutoText 
)
+
+static
+
+

Find the text engine for a text format

+

In case of QwtText::AutoText the first text engine (beside QwtPlainTextEngine) is returned, where QwtTextEngine::mightRender returns true. If there is none QwtPlainTextEngine is returned.

+

If no text engine is registered for the format QwtPlainTextEngine is returnd.

+
Parameters
+ + + +
textText, needed in case of AutoText
formatText format
+
+
+
Returns
Corresponding text engine
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
const QwtTextEngine * QwtText::textEngine (QwtText::TextFormat format)
+
+static
+
+ +

Find the text engine for a text format.

+

textEngine can be used to find out if a text format is supported.

+
Parameters
+ + +
formatText format
+
+
+
Returns
The text engine, or NULL if no engine is available.
+ +
+
+ +
+
+ + + + + + + + +
QSizeF QwtText::textSize (const QFont & defaultFont = QFont()) const
+
+

Find the height for a given width

+
Parameters
+ + +
defaultFontFont, used for the calculation if the text has no font
+
+
+
Returns
Calculated height
+

Returns the size, that is needed to render text

+
Parameters
+ + +
defaultFontFont of the text
+
+
+
Returns
Caluclated size
+ +
+
+ +
+
+ + + + + + + + +
QColor QwtText::usedColor (const QColor & defaultColor) const
+
+

Return the color of the text, if it has one. Otherwise return defaultColor.

+
Parameters
+ + +
defaultColorDefault color
+
+
+
Returns
Color used for drawing the text
+
See Also
setColor(), color(), PaintAttributes
+ +
+
+ +
+
+ + + + + + + + +
QFont QwtText::usedFont (const QFont & defaultFont) const
+
+

Return the font of the text, if it has one. Otherwise return defaultFont.

+
Parameters
+ + +
defaultFontDefault font
+
+
+
Returns
Font used for drawing the text
+
See Also
setFont(), font(), PaintAttributes
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_text_engine-members.html b/ThirdParty/Qwt/doc/html/class_qwt_text_engine-members.html new file mode 100644 index 0000000000..0ff67c19de --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_text_engine-members.html @@ -0,0 +1,107 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtTextEngine Member List
+
+
+ +

This is the complete list of members for QwtTextEngine, including all inherited members.

+ + + + + + + + +
draw(QPainter *painter, const QRectF &rect, int flags, const QString &text) const =0QwtTextEnginepure virtual
heightForWidth(const QFont &font, int flags, const QString &text, double width) const =0QwtTextEnginepure virtual
mightRender(const QString &text) const =0QwtTextEnginepure virtual
QwtTextEngine()QwtTextEngineprotected
textMargins(const QFont &font, const QString &text, double &left, double &right, double &top, double &bottom) const =0QwtTextEnginepure virtual
textSize(const QFont &font, int flags, const QString &text) const =0QwtTextEnginepure virtual
~QwtTextEngine()QwtTextEnginevirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_text_engine.html b/ThirdParty/Qwt/doc/html/class_qwt_text_engine.html new file mode 100644 index 0000000000..0768c669b4 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_text_engine.html @@ -0,0 +1,420 @@ + + + + + + +Qwt User's Guide: QwtTextEngine Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtTextEngine Class Referenceabstract
+
+
+ +

Abstract base class for rendering text strings. + More...

+ +

#include <qwt_text_engine.h>

+
+Inheritance diagram for QwtTextEngine:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + + + + + + + + +

+Public Member Functions

+virtual ~QwtTextEngine ()
 Destructor.
 
virtual double heightForWidth (const QFont &font, int flags, const QString &text, double width) const =0
 
virtual QSizeF textSize (const QFont &font, int flags, const QString &text) const =0
 
virtual bool mightRender (const QString &text) const =0
 
virtual void textMargins (const QFont &font, const QString &text, double &left, double &right, double &top, double &bottom) const =0
 
virtual void draw (QPainter *painter, const QRectF &rect, int flags, const QString &text) const =0
 
+ + + + +

+Protected Member Functions

QwtTextEngine ()
 Constructor.
 
+

Detailed Description

+

Abstract base class for rendering text strings.

+

A text engine is responsible for rendering texts for a specific text format. They are used by QwtText to render a text.

+

QwtPlainTextEngine and QwtRichTextEngine are part of the Qwt library. The implementation of QwtMathMLTextEngine uses code from the Qt solution package. Because of license implications it is built into a separate library.

+
See Also
QwtText::setTextEngine()
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
virtual void QwtTextEngine::draw (QPainter * painter,
const QRectF & rect,
int flags,
const QString & text 
) const
+
+pure virtual
+
+

Draw the text in a clipping rectangle

+
Parameters
+ + + + + +
painterPainter
rectClipping rectangle
flagsBitwise OR of the flags like in for QPainter::drawText()
textText to be rendered
+
+
+ +

Implemented in QwtRichTextEngine, QwtPlainTextEngine, and QwtMathMLTextEngine.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
virtual double QwtTextEngine::heightForWidth (const QFont & font,
int flags,
const QString & text,
double width 
) const
+
+pure virtual
+
+

Find the height for a given width

+
Parameters
+ + + + + +
fontFont of the text
flagsBitwise OR of the flags used like in QPainter::drawText
textText to be rendered
widthWidth
+
+
+
Returns
Calculated height
+ +

Implemented in QwtRichTextEngine, QwtPlainTextEngine, and QwtMathMLTextEngine.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
virtual bool QwtTextEngine::mightRender (const QString & text) const
+
+pure virtual
+
+

Test if a string can be rendered by this text engine

+
Parameters
+ + +
textText to be tested
+
+
+
Returns
true, if it can be rendered
+ +

Implemented in QwtRichTextEngine, QwtPlainTextEngine, and QwtMathMLTextEngine.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
virtual void QwtTextEngine::textMargins (const QFont & font,
const QString & text,
double & left,
double & right,
double & top,
double & bottom 
) const
+
+pure virtual
+
+

Return margins around the texts

+

The textSize might include margins around the text, like QFontMetrics::descent(). In situations where texts need to be aligned in detail, knowing these margins might improve the layout calculations.

+
Parameters
+ + + + + + + +
fontFont of the text
textText to be rendered
leftReturn value for the left margin
rightReturn value for the right margin
topReturn value for the top margin
bottomReturn value for the bottom margin
+
+
+ +

Implemented in QwtRichTextEngine, QwtPlainTextEngine, and QwtMathMLTextEngine.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
virtual QSizeF QwtTextEngine::textSize (const QFont & font,
int flags,
const QString & text 
) const
+
+pure virtual
+
+

Returns the size, that is needed to render text

+
Parameters
+ + + + +
fontFont of the text
flagsBitwise OR of the flags like in for QPainter::drawText
textText to be rendered
+
+
+
Returns
Calculated size
+ +

Implemented in QwtRichTextEngine, QwtPlainTextEngine, and QwtMathMLTextEngine.

+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_text_engine__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_text_engine__inherit__graph.map new file mode 100644 index 0000000000..354ba4f5e9 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_text_engine__inherit__graph.map @@ -0,0 +1,5 @@ + + + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_text_engine__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_text_engine__inherit__graph.md5 new file mode 100644 index 0000000000..ea4fe568f7 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_text_engine__inherit__graph.md5 @@ -0,0 +1 @@ +5a22f85d963bad8fae8d31551f732072 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_text_engine__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_text_engine__inherit__graph.png new file mode 100644 index 0000000000..1ef9fa283c Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_text_engine__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_text_label-members.html b/ThirdParty/Qwt/doc/html/class_qwt_text_label-members.html new file mode 100644 index 0000000000..e002f07cbe --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_text_label-members.html @@ -0,0 +1,120 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtTextLabel Member List
+
+
+ +

This is the complete list of members for QwtTextLabel, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + +
clear()QwtTextLabelslot
drawContents(QPainter *)QwtTextLabelprotectedvirtual
drawText(QPainter *, const QRectF &)QwtTextLabelvirtual
heightForWidth(int) const QwtTextLabelvirtual
indent() const QwtTextLabel
margin() const QwtTextLabel
minimumSizeHint() const QwtTextLabelvirtual
paintEvent(QPaintEvent *e)QwtTextLabelprotectedvirtual
plainText() const QwtTextLabel
QwtTextLabel(QWidget *parent=NULL)QwtTextLabelexplicit
QwtTextLabel(const QwtText &, QWidget *parent=NULL)QwtTextLabelexplicit
setIndent(int)QwtTextLabel
setMargin(int)QwtTextLabel
setPlainText(const QString &)QwtTextLabel
setText(const QString &, QwtText::TextFormat textFormat=QwtText::AutoText)QwtTextLabelslot
setText(const QwtText &)QwtTextLabelvirtualslot
sizeHint() const QwtTextLabelvirtual
text() const QwtTextLabel
textRect() const QwtTextLabel
~QwtTextLabel()QwtTextLabelvirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_text_label.html b/ThirdParty/Qwt/doc/html/class_qwt_text_label.html new file mode 100644 index 0000000000..6958538bb4 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_text_label.html @@ -0,0 +1,498 @@ + + + + + + +Qwt User's Guide: QwtTextLabel Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+ +
+ +

A Widget which displays a QwtText. + More...

+ +

#include <qwt_text_label.h>

+
+Inheritance diagram for QwtTextLabel:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + + +

+Public Slots

void setText (const QString &, QwtText::TextFormat textFormat=QwtText::AutoText)
 
virtual void setText (const QwtText &)
 
+void clear ()
 Clear the text and all QwtText attributes.
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 QwtTextLabel (QWidget *parent=NULL)
 
 QwtTextLabel (const QwtText &, QWidget *parent=NULL)
 
+virtual ~QwtTextLabel ()
 Destructor.
 
void setPlainText (const QString &)
 
QString plainText () const
 
+const QwtTexttext () const
 Return the text.
 
+int indent () const
 Return label's text indent in pixels.
 
void setIndent (int)
 
+int margin () const
 Return label's text indent in pixels.
 
void setMargin (int)
 
+virtual QSize sizeHint () const
 Return label's margin in pixels.
 
+virtual QSize minimumSizeHint () const
 Return a minimum size hint.
 
virtual int heightForWidth (int) const
 
QRect textRect () const
 
+virtual void drawText (QPainter *, const QRectF &)
 Redraw the text.
 
+ + + + + + +

+Protected Member Functions

virtual void paintEvent (QPaintEvent *e)
 
+virtual void drawContents (QPainter *)
 Redraw the text and focus indicator.
 
+

Detailed Description

+

A Widget which displays a QwtText.

+

Constructor & Destructor Documentation

+ +
+
+ + + + + +
+ + + + + + + + +
QwtTextLabel::QwtTextLabel (QWidget * parent = NULL)
+
+explicit
+
+

Constructs an empty label.

+
Parameters
+ + +
parentParent widget
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
QwtTextLabel::QwtTextLabel (const QwtTexttext,
QWidget * parent = NULL 
)
+
+explicit
+
+

Constructs a label that displays the text, text

+
Parameters
+ + + +
parentParent widget
textText
+
+
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + + +
int QwtTextLabel::heightForWidth (int width) const
+
+virtual
+
+
Parameters
+ + +
widthWidth
+
+
+
Returns
Preferred height for this widget, given the width.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtTextLabel::paintEvent (QPaintEvent * event)
+
+protectedvirtual
+
+

Qt paint event

+
Parameters
+ + +
eventPaint event
+
+
+ +

Reimplemented in QwtLegendLabel.

+ +
+
+ +
+
+ + + + + + + +
QString QwtTextLabel::plainText () const
+
+

Interface for the designer plugin

+
Returns
Text as plain text
+
See Also
setPlainText(), text()
+ +
+
+ +
+
+ + + + + + + + +
void QwtTextLabel::setIndent (int indent)
+
+

Set label's text indent in pixels

+
Parameters
+ + +
indentIndentation in pixels
+
+
+ +
+
+ +
+
+ + + + + + + + +
void QwtTextLabel::setMargin (int margin)
+
+

Set label's margin in pixels

+
Parameters
+ + +
marginMargin in pixels
+
+
+ +
+
+ +
+
+ + + + + + + + +
void QwtTextLabel::setPlainText (const QString & text)
+
+

Interface for the designer plugin - does the same as setText()

+
See Also
plainText()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void QwtTextLabel::setText (const QString & text,
QwtText::TextFormat textFormat = QwtText::AutoText 
)
+
+slot
+
+

Change the label's text, keeping all other QwtText attributes

+
Parameters
+ + + +
textNew text
textFormatFormat of text
+
+
+
See Also
QwtText
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtTextLabel::setText (const QwtTexttext)
+
+virtualslot
+
+

Change the label's text

+
Parameters
+ + +
textNew text
+
+
+ +

Reimplemented in QwtLegendLabel.

+ +
+
+ +
+
+ + + + + + + +
QRect QwtTextLabel::textRect () const
+
+

Calculate geometry for the text in widget coordinates

+
Returns
Geometry for the text
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_text_label__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_text_label__inherit__graph.map new file mode 100644 index 0000000000..b1caa2d966 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_text_label__inherit__graph.map @@ -0,0 +1,3 @@ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_text_label__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_text_label__inherit__graph.md5 new file mode 100644 index 0000000000..69a673d97e --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_text_label__inherit__graph.md5 @@ -0,0 +1 @@ +eb2a1e273f42f3ecb0715de8afe87ebe \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_text_label__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_text_label__inherit__graph.png new file mode 100644 index 0000000000..ddfe79ee39 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_text_label__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_thermo-members.html b/ThirdParty/Qwt/doc/html/class_qwt_thermo-members.html new file mode 100644 index 0000000000..f7bbc2620b --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_thermo-members.html @@ -0,0 +1,181 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtThermo Member List
+
+
+ +

This is the complete list of members for QwtThermo, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
abstractScaleDraw() const QwtAbstractScaleprotected
abstractScaleDraw()QwtAbstractScaleprotected
alarmBrush() const QwtThermo
alarmEnabled() const QwtThermo
alarmLevel() const QwtThermo
alarmRect(const QRect &) const QwtThermoprotected
borderWidth() const QwtThermo
changeEvent(QEvent *)QwtThermoprotectedvirtual
colorMap()QwtThermo
colorMap() const QwtThermo
drawLiquid(QPainter *, const QRect &) const QwtThermoprotectedvirtual
fillBrush() const QwtThermo
fillRect(const QRect &) const QwtThermoprotected
invTransform(int) const QwtAbstractScale
isInverted() const QwtAbstractScale
LeadingScale enum valueQwtThermo
lowerBound() const QwtAbstractScale
maximum() const QwtAbstractScale
minimum() const QwtAbstractScale
minimumSizeHint() const QwtThermovirtual
NoScale enum valueQwtThermo
orientation() const QwtThermo
origin() const QwtThermo
OriginCustom enum valueQwtThermo
OriginMaximum enum valueQwtThermo
OriginMinimum enum valueQwtThermo
originMode() const QwtThermo
OriginMode enum nameQwtThermo
paintEvent(QPaintEvent *)QwtThermoprotectedvirtual
pipeRect() const QwtThermoprotected
pipeWidth() const QwtThermo
QwtAbstractScale(QWidget *parent=NULL)QwtAbstractScale
QwtThermo(QWidget *parent=NULL)QwtThermoexplicit
rangeFlags() const QwtThermo
rescale(double lowerBound, double upperBound, double stepSize)QwtAbstractScaleprotected
resizeEvent(QResizeEvent *)QwtThermoprotectedvirtual
scaleChange()QwtThermoprotectedvirtual
scaleDiv() const QwtAbstractScale
scaleDraw() const QwtThermo
scaleDraw()QwtThermoprotected
scaleEngine() const QwtAbstractScale
scaleEngine()QwtAbstractScale
scaleMap() const QwtAbstractScale
scaleMaxMajor() const QwtAbstractScale
scaleMaxMinor() const QwtAbstractScale
ScalePosition enum nameQwtThermo
scalePosition() const QwtThermo
scaleStepSize() const QwtAbstractScale
setAbstractScaleDraw(QwtAbstractScaleDraw *)QwtAbstractScaleprotected
setAlarmBrush(const QBrush &b)QwtThermo
setAlarmEnabled(bool tf)QwtThermo
setAlarmLevel(double v)QwtThermo
setBorderWidth(int w)QwtThermo
setColorMap(QwtColorMap *)QwtThermo
setFillBrush(const QBrush &b)QwtThermo
setLowerBound(double value)QwtAbstractScale
setOrientation(Qt::Orientation)QwtThermo
setOrigin(double)QwtThermo
setOriginMode(OriginMode)QwtThermo
setPipeWidth(int w)QwtThermo
setRangeFlags(QwtInterval::BorderFlags)QwtThermo
setScale(double lowerBound, double upperBound)QwtAbstractScale
setScale(const QwtInterval &)QwtAbstractScale
setScale(const QwtScaleDiv &)QwtAbstractScale
setScaleDraw(QwtScaleDraw *)QwtThermo
setScaleEngine(QwtScaleEngine *)QwtAbstractScale
setScaleMaxMajor(int ticks)QwtAbstractScale
setScaleMaxMinor(int ticks)QwtAbstractScale
setScalePosition(ScalePosition)QwtThermo
setScaleStepSize(double stepSize)QwtAbstractScale
setSpacing(int)QwtThermo
setUpperBound(double value)QwtAbstractScale
setValue(double val)QwtThermovirtualslot
sizeHint() const QwtThermovirtual
spacing() const QwtThermo
TrailingScale enum valueQwtThermo
transform(double) const QwtAbstractScale
upperBound() const QwtAbstractScale
value() const QwtThermo
~QwtAbstractScale()QwtAbstractScalevirtual
~QwtThermo()QwtThermovirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_thermo.html b/ThirdParty/Qwt/doc/html/class_qwt_thermo.html new file mode 100644 index 0000000000..9642d34f3d --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_thermo.html @@ -0,0 +1,1361 @@ + + + + + + +Qwt User's Guide: QwtThermo Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+ +
+ +

The Thermometer Widget. + More...

+ +

#include <qwt_thermo.h>

+
+Inheritance diagram for QwtThermo:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + +

+Public Types

enum  ScalePosition { NoScale, +LeadingScale, +TrailingScale + }
 
enum  OriginMode { OriginMinimum, +OriginMaximum, +OriginCustom + }
 
+ + + +

+Public Slots

virtual void setValue (double val)
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 QwtThermo (QWidget *parent=NULL)
 
+virtual ~QwtThermo ()
 Destructor.
 
void setOrientation (Qt::Orientation)
 Set the orientation. More...
 
Qt::Orientation orientation () const
 
void setScalePosition (ScalePosition)
 Change the position of the scale. More...
 
ScalePosition scalePosition () const
 
void setSpacing (int)
 Change the spacing between pipe and scale. More...
 
int spacing () const
 
void setBorderWidth (int w)
 
int borderWidth () const
 
void setOriginMode (OriginMode)
 Change how the origin is determined. More...
 
OriginMode originMode () const
 
void setOrigin (double)
 Specifies the custom origin. More...
 
double origin () const
 
void setFillBrush (const QBrush &b)
 Change the brush of the liquid. More...
 
QBrush fillBrush () const
 
void setAlarmBrush (const QBrush &b)
 Specify the liquid brush above the alarm threshold. More...
 
QBrush alarmBrush () const
 
void setAlarmLevel (double v)
 
double alarmLevel () const
 
void setAlarmEnabled (bool tf)
 Enable or disable the alarm threshold. More...
 
bool alarmEnabled () const
 
void setColorMap (QwtColorMap *)
 Assign a color map for the fill color. More...
 
QwtColorMapcolorMap ()
 
const QwtColorMapcolorMap () const
 
void setPipeWidth (int w)
 
int pipeWidth () const
 
void setRangeFlags (QwtInterval::BorderFlags)
 Exclude/Include min/max values. More...
 
QwtInterval::BorderFlags rangeFlags () const
 
+double value () const
 Return the value.
 
virtual QSize sizeHint () const
 
virtual QSize minimumSizeHint () const
 
void setScaleDraw (QwtScaleDraw *)
 Set a scale draw. More...
 
const QwtScaleDrawscaleDraw () const
 
- Public Member Functions inherited from QwtAbstractScale
 QwtAbstractScale (QWidget *parent=NULL)
 
+virtual ~QwtAbstractScale ()
 Destructor.
 
void setScale (double lowerBound, double upperBound)
 Specify a scale. More...
 
void setScale (const QwtInterval &)
 Specify a scale. More...
 
void setScale (const QwtScaleDiv &)
 Specify a scale. More...
 
const QwtScaleDivscaleDiv () const
 
void setLowerBound (double value)
 
double lowerBound () const
 
void setUpperBound (double value)
 
double upperBound () const
 
void setScaleStepSize (double stepSize)
 Set the step size used for calculating a scale division. More...
 
double scaleStepSize () const
 
void setScaleMaxMajor (int ticks)
 Set the maximum number of major tick intervals. More...
 
int scaleMaxMinor () const
 
void setScaleMaxMinor (int ticks)
 Set the maximum number of minor tick intervals. More...
 
int scaleMaxMajor () const
 
void setScaleEngine (QwtScaleEngine *)
 Set a scale engine. More...
 
const QwtScaleEnginescaleEngine () const
 
QwtScaleEnginescaleEngine ()
 
int transform (double) const
 
double invTransform (int) const
 
bool isInverted () const
 
double minimum () const
 
double maximum () const
 
const QwtScaleMapscaleMap () const
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Protected Member Functions

virtual void drawLiquid (QPainter *, const QRect &) const
 
+virtual void scaleChange ()
 Notify a scale change.
 
virtual void paintEvent (QPaintEvent *)
 
virtual void resizeEvent (QResizeEvent *)
 
virtual void changeEvent (QEvent *)
 
QwtScaleDrawscaleDraw ()
 
QRect pipeRect () const
 
QRect fillRect (const QRect &) const
 Calculate the filled rectangle of the pipe. More...
 
QRect alarmRect (const QRect &) const
 Calculate the alarm rectangle of the pipe. More...
 
- Protected Member Functions inherited from QwtAbstractScale
void rescale (double lowerBound, double upperBound, double stepSize)
 
void setAbstractScaleDraw (QwtAbstractScaleDraw *)
 Set a scale draw. More...
 
const QwtAbstractScaleDrawabstractScaleDraw () const
 
QwtAbstractScaleDrawabstractScaleDraw ()
 
+

Detailed Description

+

The Thermometer Widget.

+

QwtThermo is a widget which displays a value in an interval. It supports:

+
    +
  • a horizontal or vertical layout;
  • +
  • a range;
  • +
  • a scale;
  • +
  • an alarm level.
  • +
+
+sysinfo.png +
+

The fill colors might be calculated from an optional color map If no color map has been assigned QwtThermo uses the following colors/brushes from the widget palette:

+
    +
  • QPalette::Base Background of the pipe
  • +
  • QPalette::ButtonText Fill brush below the alarm level
  • +
  • QPalette::Highlight Fill brush for the values above the alarm level
  • +
  • QPalette::WindowText For the axis of the scale
  • +
  • QPalette::Text For the labels of the scale
  • +
+

Member Enumeration Documentation

+ +
+
+ + + + +
enum QwtThermo::OriginMode
+
+

Origin mode. This property specifies where the beginning of the liquid is placed.

+
See Also
setOriginMode(), setOrigin()
+ + + + +
Enumerator
OriginMinimum  +

The origin is the minimum of the scale.

+
OriginMaximum  +

The origin is the maximum of the scale.

+
OriginCustom  +

The origin is specified using the origin() property.

+
+ +
+
+ +
+
+ + + + +
enum QwtThermo::ScalePosition
+
+

Position of the scale

+
See Also
setScalePosition(), setOrientation()
+ + + + +
Enumerator
NoScale  +

The slider has no scale.

+
LeadingScale  +

The scale is right of a vertical or below of a horizontal slider.

+
TrailingScale  +

The scale is left of a vertical or above of a horizontal slider.

+
+ +
+
+

Constructor & Destructor Documentation

+ +
+
+ + + + + +
+ + + + + + + + +
QwtThermo::QwtThermo (QWidget * parent = NULL)
+
+explicit
+
+

Constructor

+
Parameters
+ + +
parentParent widget
+
+
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + + + +
QBrush QwtThermo::alarmBrush () const
+
+
Returns
Liquid brush ( QPalette::Highlight ) above the alarm threshold.
+
See Also
setAlarmBrush(), QWidget::palette()
+
Warning
The alarm threshold has no effect, when a color map has been assigned
+ +
+
+ +
+
+ + + + + + + +
bool QwtThermo::alarmEnabled () const
+
+
Returns
True, when the alarm threshold is enabled.
+
Warning
The alarm threshold has no effect, when a color map has been assigned
+ +
+
+ +
+
+ + + + + + + +
double QwtThermo::alarmLevel () const
+
+
Returns
Alarm threshold.
+
See Also
setAlarmLevel()
+
Warning
The alarm threshold has no effect, when a color map has been assigned
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
QRect QwtThermo::alarmRect (const QRect & fillRect) const
+
+protected
+
+ +

Calculate the alarm rectangle of the pipe.

+
Parameters
+ + +
fillRectFilled rectangle in the pipe
+
+
+
Returns
Rectangle to be filled with the alarm brush
+
See Also
pipeRect(), fillRect(), alarmLevel(), alarmBrush()
+ +
+
+ +
+
+ + + + + + + +
int QwtThermo::borderWidth () const
+
+
Returns
Border width of the thermometer pipe.
+
See Also
setBorderWidth()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtThermo::changeEvent (QEvent * event)
+
+protectedvirtual
+
+

Qt change event handler

+
Parameters
+ + +
eventEvent
+
+
+ +
+
+ +
+
+ + + + + + + +
QwtColorMap * QwtThermo::colorMap ()
+
+
Returns
Color map for the fill color
+
Warning
The alarm threshold has no effect, when a color map has been assigned
+ +
+
+ +
+
+ + + + + + + +
const QwtColorMap * QwtThermo::colorMap () const
+
+
Returns
Color map for the fill color
+
Warning
The alarm threshold has no effect, when a color map has been assigned
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void QwtThermo::drawLiquid (QPainter * painter,
const QRect & pipeRect 
) const
+
+protectedvirtual
+
+

Redraw the liquid in thermometer pipe.

+
Parameters
+ + + +
painterPainter
pipeRectBounding rectangle of the pipe without borders
+
+
+ +
+
+ +
+
+ + + + + + + +
QBrush QwtThermo::fillBrush () const
+
+
Returns
Liquid ( QPalette::ButtonText ) brush.
+
See Also
setFillBrush(), QWidget::palette()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
QRect QwtThermo::fillRect (const QRect & pipeRect) const
+
+protected
+
+ +

Calculate the filled rectangle of the pipe.

+
Parameters
+ + +
pipeRectRectangle of the pipe
+
+
+
Returns
Rectangle to be filled ( fill and alarm brush )
+
See Also
pipeRect(), alarmRect()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
QSize QwtThermo::minimumSizeHint () const
+
+virtual
+
+
Returns
Minimum size hint
+
Warning
The return value depends on the font and the scale.
+
See Also
sizeHint()
+ +
+
+ +
+
+ + + + + + + +
Qt::Orientation QwtThermo::orientation () const
+
+
Returns
Orientation
+
See Also
setOrientation()
+ +
+
+ +
+
+ + + + + + + +
double QwtThermo::origin () const
+
+
Returns
Origin of the thermo, when OriginCustom is enabled
+
See Also
setOrigin(), setOriginMode(), originMode()
+ +
+
+ +
+
+ + + + + + + +
QwtThermo::OriginMode QwtThermo::originMode () const
+
+
Returns
Mode, how the origin is determined.
+
See Also
setOriginMode(), serOrigin(), origin()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtThermo::paintEvent (QPaintEvent * event)
+
+protectedvirtual
+
+

Paint event handler

+
Parameters
+ + +
eventPaint event
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
QRect QwtThermo::pipeRect () const
+
+protected
+
+
Returns
Bounding rectangle of the pipe ( without borders ) in widget coordinates
+ +
+
+ +
+
+ + + + + + + +
int QwtThermo::pipeWidth () const
+
+
Returns
Width of the pipe.
+
See Also
setPipeWidth()
+ +
+
+ +
+
+ + + + + + + +
QwtInterval::BorderFlags QwtThermo::rangeFlags () const
+
+
Returns
Range flags
+
See Also
setRangeFlags()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtThermo::resizeEvent (QResizeEvent * event)
+
+protectedvirtual
+
+

Resize event handler

+
Parameters
+ + +
eventResize event
+
+
+ +
+
+ +
+
+ + + + + + + +
const QwtScaleDraw * QwtThermo::scaleDraw () const
+
+
Returns
the scale draw of the thermo
+
See Also
setScaleDraw()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
QwtScaleDraw * QwtThermo::scaleDraw ()
+
+protected
+
+
Returns
the scale draw of the thermo
+
See Also
setScaleDraw()
+ +
+
+ +
+
+ + + + + + + +
QwtThermo::ScalePosition QwtThermo::scalePosition () const
+
+
Returns
Scale position.
+
See Also
setScalePosition()
+ +
+
+ +
+
+ + + + + + + + +
void QwtThermo::setAlarmBrush (const QBrush & brush)
+
+ +

Specify the liquid brush above the alarm threshold.

+

Changes the QPalette::Highlight brush of the palette.

+
Parameters
+ + +
brushNew brush.
+
+
+
See Also
alarmBrush(), QWidget::setPalette()
+
Warning
The alarm threshold has no effect, when a color map has been assigned
+ +
+
+ +
+
+ + + + + + + + +
void QwtThermo::setAlarmEnabled (bool on)
+
+ +

Enable or disable the alarm threshold.

+
Parameters
+ + +
ontrue (disabled) or false (enabled)
+
+
+
Warning
The alarm threshold has no effect, when a color map has been assigned
+ +
+
+ +
+
+ + + + + + + + +
void QwtThermo::setAlarmLevel (double level)
+
+

Specify the alarm threshold.

+
Parameters
+ + +
levelAlarm threshold
+
+
+
See Also
alarmLevel()
+
Warning
The alarm threshold has no effect, when a color map has been assigned
+ +
+
+ +
+
+ + + + + + + + +
void QwtThermo::setBorderWidth (int width)
+
+

Set the border width of the pipe.

+
Parameters
+ + +
widthBorder width
+
+
+
See Also
borderWidth()
+ +
+
+ +
+
+ + + + + + + + +
void QwtThermo::setColorMap (QwtColorMapcolorMap)
+
+ +

Assign a color map for the fill color.

+
Parameters
+ + +
colorMapColor map
+
+
+
Warning
The alarm threshold has no effect, when a color map has been assigned
+ +
+
+ +
+
+ + + + + + + + +
void QwtThermo::setFillBrush (const QBrush & brush)
+
+ +

Change the brush of the liquid.

+

Changes the QPalette::ButtonText brush of the palette.

+
Parameters
+ + +
brushNew brush.
+
+
+
See Also
fillBrush(), QWidget::setPalette()
+ +
+
+ +
+
+ + + + + + + + +
void QwtThermo::setOrientation (Qt::Orientation orientation)
+
+ +

Set the orientation.

+
Parameters
+ + +
orientationAllowed values are Qt::Horizontal and Qt::Vertical.
+
+
+
See Also
orientation(), scalePosition()
+ +
+
+ +
+
+ + + + + + + + +
void QwtThermo::setOrigin (double origin)
+
+ +

Specifies the custom origin.

+

If originMode is set to OriginCustom this property controls where the liquid starts.

+
Parameters
+ + +
originNew origin level
+
+
+
See Also
setOriginMode(), originMode(), origin()
+ +
+
+ +
+
+ + + + + + + + +
void QwtThermo::setOriginMode (OriginMode m)
+
+ +

Change how the origin is determined.

+
See Also
originMode(), serOrigin(), origin()
+ +
+
+ +
+
+ + + + + + + + +
void QwtThermo::setPipeWidth (int width)
+
+

Change the width of the pipe.

+
Parameters
+ + +
widthWidth of the pipe
+
+
+
See Also
pipeWidth()
+ +
+
+ +
+
+ + + + + + + + +
void QwtThermo::setRangeFlags (QwtInterval::BorderFlags flags)
+
+ +

Exclude/Include min/max values.

+

According to the flags minValue() and maxValue() are included/excluded from the pipe. In case of an excluded value the corresponding tick is painted 1 pixel off of the pipeRect().

+

F.e. when a minimum of 0.0 has to be displayed as an empty pipe the minValue() needs to be excluded.

+
Parameters
+ + +
flagsRange flags
+
+
+
See Also
rangeFlags()
+ +
+
+ +
+
+ + + + + + + + +
void QwtThermo::setScaleDraw (QwtScaleDrawscaleDraw)
+
+ +

Set a scale draw.

+

For changing the labels of the scales, it is necessary to derive from QwtScaleDraw and overload QwtScaleDraw::label().

+
Parameters
+ + +
scaleDrawScaleDraw object, that has to be created with new and will be deleted in ~QwtThermo() or the next call of setScaleDraw().
+
+
+ +
+
+ +
+
+ + + + + + + + +
void QwtThermo::setScalePosition (ScalePosition scalePosition)
+
+ +

Change the position of the scale.

+
Parameters
+ + +
scalePositionPosition of the scale.
+
+
+
See Also
ScalePosition, scalePosition()
+ +
+
+ +
+
+ + + + + + + + +
void QwtThermo::setSpacing (int spacing)
+
+ +

Change the spacing between pipe and scale.

+

A spacing of 0 means, that the backbone of the scale is below the pipe.

+

The default setting is 3 pixels.

+
Parameters
+ + +
spacingNumber of pixels
+
+
+
See Also
spacing();
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtThermo::setValue (double value)
+
+virtualslot
+
+

Set the current value.

+
Parameters
+ + +
valueNew Value
+
+
+
See Also
value()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
QSize QwtThermo::sizeHint () const
+
+virtual
+
+
Returns
the minimum size hint
+
See Also
minimumSizeHint()
+ +
+
+ +
+
+ + + + + + + +
int QwtThermo::spacing () const
+
+
Returns
Number of pixels between pipe and scale
+
See Also
setSpacing()
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_thermo__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_thermo__inherit__graph.map new file mode 100644 index 0000000000..86922dfc19 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_thermo__inherit__graph.map @@ -0,0 +1,3 @@ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_thermo__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_thermo__inherit__graph.md5 new file mode 100644 index 0000000000..9270a03f4a --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_thermo__inherit__graph.md5 @@ -0,0 +1 @@ +990541a66cf0df269060a35b4f2c67af \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_thermo__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_thermo__inherit__graph.png new file mode 100644 index 0000000000..8c3e36c33f Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_thermo__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_trading_chart_data-members.html b/ThirdParty/Qwt/doc/html/class_qwt_trading_chart_data-members.html new file mode 100644 index 0000000000..806c0022ea --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_trading_chart_data-members.html @@ -0,0 +1,113 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtTradingChartData Member List
+
+ + + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_trading_chart_data.html b/ThirdParty/Qwt/doc/html/class_qwt_trading_chart_data.html new file mode 100644 index 0000000000..20819ef766 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_trading_chart_data.html @@ -0,0 +1,208 @@ + + + + + + +Qwt User's Guide: QwtTradingChartData Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtTradingChartData Class Reference
+
+
+ +

#include <qwt_series_data.h>

+
+Inheritance diagram for QwtTradingChartData:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 QwtTradingChartData (const QVector< QwtOHLCSample > &=QVector< QwtOHLCSample >())
 
virtual QRectF boundingRect () const
 Calculate the bounding rectangle. More...
 
- Public Member Functions inherited from QwtArraySeriesData< QwtOHLCSample >
QwtArraySeriesData ()
 Constructor.
 
 QwtArraySeriesData (const QVector< QwtOHLCSample > &samples)
 
void setSamples (const QVector< QwtOHLCSample > &samples)
 
const QVector< QwtOHLCSamplesamples () const
 
virtual size_t size () const
 
virtual QwtOHLCSample sample (size_t index) const
 
- Public Member Functions inherited from QwtSeriesData< QwtOHLCSample >
QwtSeriesData ()
 Constructor.
 
+virtual ~QwtSeriesData ()
 Destructor.
 
virtual void setRectOfInterest (const QRectF &rect)
 
+ + + + + +

+Additional Inherited Members

- Protected Attributes inherited from QwtArraySeriesData< QwtOHLCSample >
+QVector< QwtOHLCSampled_samples
 Vector of samples.
 
+

Detailed Description

+

Interface for iterating over an array of OHLC samples

+

Constructor & Destructor Documentation

+ +
+
+ + + + + + + + +
QwtTradingChartData::QwtTradingChartData (const QVector< QwtOHLCSample > & samples = QVector<QwtOHLCSample>())
+
+

Constructor

+
Parameters
+ + +
samplesSamples
+
+
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + +
QRectF QwtTradingChartData::boundingRect () const
+
+virtual
+
+ +

Calculate the bounding rectangle.

+

The bounding rectangle is calculated once by iterating over all points and is stored for all following requests.

+
Returns
Bounding rectangle
+ +

Implements QwtSeriesData< QwtOHLCSample >.

+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_trading_chart_data__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_trading_chart_data__inherit__graph.map new file mode 100644 index 0000000000..86561762d1 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_trading_chart_data__inherit__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_trading_chart_data__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_trading_chart_data__inherit__graph.md5 new file mode 100644 index 0000000000..bb3ff302de --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_trading_chart_data__inherit__graph.md5 @@ -0,0 +1 @@ +210c8411ba1bf149e88bf9dbf6cd87c6 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_trading_chart_data__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_trading_chart_data__inherit__graph.png new file mode 100644 index 0000000000..59082e5e46 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_trading_chart_data__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_transform-members.html b/ThirdParty/Qwt/doc/html/class_qwt_transform-members.html new file mode 100644 index 0000000000..138bf4ed95 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_transform-members.html @@ -0,0 +1,106 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtTransform Member List
+
+
+ +

This is the complete list of members for QwtTransform, including all inherited members.

+ + + + + + + +
bounded(double value) const QwtTransformvirtual
copy() const =0QwtTransformpure virtual
invTransform(double value) const =0QwtTransformpure virtual
QwtTransform()QwtTransform
transform(double value) const =0QwtTransformpure virtual
~QwtTransform()QwtTransformvirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_transform.html b/ThirdParty/Qwt/doc/html/class_qwt_transform.html new file mode 100644 index 0000000000..4b319d2442 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_transform.html @@ -0,0 +1,253 @@ + + + + + + +Qwt User's Guide: QwtTransform Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtTransform Class Referenceabstract
+
+
+ +

A transformation between coordinate systems. + More...

+ +

#include <qwt_transform.h>

+
+Inheritance diagram for QwtTransform:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + + + + + + + + + + +

+Public Member Functions

QwtTransform ()
 Constructor.
 
+virtual ~QwtTransform ()
 Destructor.
 
virtual double bounded (double value) const
 
virtual double transform (double value) const =0
 
virtual double invTransform (double value) const =0
 
+virtual QwtTransformcopy () const =0
 Virtualized copy operation.
 
+

Detailed Description

+

A transformation between coordinate systems.

+

QwtTransform manipulates values, when being mapped between the scale and the paint device coordinate system.

+

A transformation consists of 2 methods:

+
    +
  • transform
  • +
  • invTransform
  • +
+

where one is is the inverse function of the other.

+

When p1, p2 are the boundaries of the paint device coordinates and s1, s2 the boundaries of the scale, QwtScaleMap uses the following calculations:

+
    +
  • p = p1 + ( p2 - p1 ) * ( T( s ) - T( s1 ) / ( T( s2 ) - T( s1 ) );
  • +
  • s = invT ( T( s1 ) + ( T( s2 ) - T( s1 ) ) * ( p - p1 ) / ( p2 - p1 ) );
  • +
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + + +
double QwtTransform::bounded (double value) const
+
+virtual
+
+

Modify value to be a valid value for the transformation. The default implementation does nothing.

+
Parameters
+ + +
valueValue to be bounded
+
+
+
Returns
value unmodified
+ +

Reimplemented in QwtLogTransform.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
virtual double QwtTransform::invTransform (double value) const
+
+pure virtual
+
+

Inverse transformation function

+
Parameters
+ + +
valueValue
+
+
+
Returns
Modified value
+
See Also
transform()
+ +

Implemented in QwtPowerTransform, QwtLogTransform, and QwtNullTransform.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
virtual double QwtTransform::transform (double value) const
+
+pure virtual
+
+

Transformation function

+
Parameters
+ + +
valueValue
+
+
+
Returns
Modified value
+
See Also
invTransform()
+ +

Implemented in QwtPowerTransform, QwtLogTransform, and QwtNullTransform.

+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_transform__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_transform__inherit__graph.map new file mode 100644 index 0000000000..cfc34e2f81 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_transform__inherit__graph.map @@ -0,0 +1,5 @@ + + + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_transform__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_transform__inherit__graph.md5 new file mode 100644 index 0000000000..036fef5fed --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_transform__inherit__graph.md5 @@ -0,0 +1 @@ +ebac7deac51b5ec0c2c7c0a8800cdff8 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_transform__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_transform__inherit__graph.png new file mode 100644 index 0000000000..5ce5f4bd4c Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_transform__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_weeding_curve_fitter-members.html b/ThirdParty/Qwt/doc/html/class_qwt_weeding_curve_fitter-members.html new file mode 100644 index 0000000000..99b361c39e --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_weeding_curve_fitter-members.html @@ -0,0 +1,109 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtWeedingCurveFitter Member List
+
+
+ +

This is the complete list of members for QwtWeedingCurveFitter, including all inherited members.

+ + + + + + + + + + +
chunkSize() const QwtWeedingCurveFitter
fitCurve(const QPolygonF &) const QwtWeedingCurveFittervirtual
QwtCurveFitter()QwtCurveFitterprotected
QwtWeedingCurveFitter(double tolerance=1.0)QwtWeedingCurveFitter
setChunkSize(uint)QwtWeedingCurveFitter
setTolerance(double)QwtWeedingCurveFitter
tolerance() const QwtWeedingCurveFitter
~QwtCurveFitter()QwtCurveFittervirtual
~QwtWeedingCurveFitter()QwtWeedingCurveFittervirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_weeding_curve_fitter.html b/ThirdParty/Qwt/doc/html/class_qwt_weeding_curve_fitter.html new file mode 100644 index 0000000000..639a61320b --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_weeding_curve_fitter.html @@ -0,0 +1,295 @@ + + + + + + +Qwt User's Guide: QwtWeedingCurveFitter Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtWeedingCurveFitter Class Reference
+
+
+ +

A curve fitter implementing Douglas and Peucker algorithm. + More...

+ +

#include <qwt_curve_fitter.h>

+
+Inheritance diagram for QwtWeedingCurveFitter:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 QwtWeedingCurveFitter (double tolerance=1.0)
 
+virtual ~QwtWeedingCurveFitter ()
 Destructor.
 
void setTolerance (double)
 
double tolerance () const
 
void setChunkSize (uint)
 
uint chunkSize () const
 
virtual QPolygonF fitCurve (const QPolygonF &) const
 
- Public Member Functions inherited from QwtCurveFitter
+virtual ~QwtCurveFitter ()
 Destructor.
 
+ + + + + +

+Additional Inherited Members

- Protected Member Functions inherited from QwtCurveFitter
QwtCurveFitter ()
 Constructor.
 
+

Detailed Description

+

A curve fitter implementing Douglas and Peucker algorithm.

+

The purpose of the Douglas and Peucker algorithm is that given a 'curve' composed of line segments to find a curve not too dissimilar but that has fewer points. The algorithm defines 'too dissimilar' based on the maximum distance (tolerance) between the original curve and the smoothed curve.

+

The runtime of the algorithm increases non linear ( worst case O( n*n ) ) and might be very slow for huge polygons. To avoid performance issues it might be useful to split the polygon ( setChunkSize() ) and to run the algorithm for these smaller parts. The disadvantage of having no interpolation at the borders is for most use cases irrelevant.

+

The smoothed curve consists of a subset of the points that defined the original curve.

+

In opposite to QwtSplineCurveFitter the Douglas and Peucker algorithm reduces the number of points. By adjusting the tolerance parameter according to the axis scales QwtSplineCurveFitter can be used to implement different level of details to speed up painting of curves of many points.

+

Constructor & Destructor Documentation

+ +
+
+ + + + + + + + +
QwtWeedingCurveFitter::QwtWeedingCurveFitter (double tolerance = 1.0)
+
+

Constructor

+
Parameters
+ + +
toleranceTolerance
+
+
+
See Also
setTolerance(), tolerance()
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + + + +
uint QwtWeedingCurveFitter::chunkSize () const
+
+
Returns
Maximum for the number of points passed to a run of the algorithm - or 0, when unlimited
+
See Also
setChunkSize()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
QPolygonF QwtWeedingCurveFitter::fitCurve (const QPolygonF & points) const
+
+virtual
+
+
Parameters
+ + +
pointsSeries of data points
+
+
+
Returns
Curve points
+ +

Implements QwtCurveFitter.

+ +
+
+ +
+
+ + + + + + + + +
void QwtWeedingCurveFitter::setChunkSize (uint numPoints)
+
+

Limit the number of points passed to a run of the algorithm

+

The runtime of the Douglas Peucker algorithm increases non linear with the number of points. For a chunk size > 0 the polygon is split into pieces passed to the algorithm one by one.

+
Parameters
+ + +
numPointsMaximum for the number of points passed to the algorithm
+
+
+
See Also
chunkSize()
+ +
+
+ +
+
+ + + + + + + + +
void QwtWeedingCurveFitter::setTolerance (double tolerance)
+
+

Assign the tolerance

+

The tolerance is the maximum distance, that is acceptable between the original curve and the smoothed curve.

+

Increasing the tolerance will reduce the number of the resulting points.

+
Parameters
+ + +
toleranceTolerance
+
+
+
See Also
tolerance()
+ +
+
+ +
+
+ + + + + + + +
double QwtWeedingCurveFitter::tolerance () const
+
+
Returns
Tolerance
+
See Also
setTolerance()
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_weeding_curve_fitter__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_weeding_curve_fitter__inherit__graph.map new file mode 100644 index 0000000000..96fb79dde0 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_weeding_curve_fitter__inherit__graph.map @@ -0,0 +1,3 @@ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_weeding_curve_fitter__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_weeding_curve_fitter__inherit__graph.md5 new file mode 100644 index 0000000000..9d737bbd3e --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_weeding_curve_fitter__inherit__graph.md5 @@ -0,0 +1 @@ +56594c1ee27b6b2202b9c9d58a28529a \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_weeding_curve_fitter__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_weeding_curve_fitter__inherit__graph.png new file mode 100644 index 0000000000..f1e0fb4df8 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_weeding_curve_fitter__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_wheel-members.html b/ThirdParty/Qwt/doc/html/class_qwt_wheel-members.html new file mode 100644 index 0000000000..45f9059dca --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_wheel-members.html @@ -0,0 +1,157 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtWheel Member List
+
+
+ +

This is the complete list of members for QwtWheel, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
borderWidth() const QwtWheel
drawTicks(QPainter *, const QRectF &)QwtWheelprotectedvirtual
drawWheelBackground(QPainter *, const QRectF &)QwtWheelprotectedvirtual
isInverted() const QwtWheel
isTracking() const QwtWheel
keyPressEvent(QKeyEvent *)QwtWheelprotectedvirtual
mass() const QwtWheel
maximum() const QwtWheel
minimum() const QwtWheel
minimumSizeHint() const QwtWheelprotectedvirtual
mouseMoveEvent(QMouseEvent *)QwtWheelprotectedvirtual
mousePressEvent(QMouseEvent *)QwtWheelprotectedvirtual
mouseReleaseEvent(QMouseEvent *)QwtWheelprotectedvirtual
orientation() const QwtWheel
pageStepCount() const QwtWheel
paintEvent(QPaintEvent *)QwtWheelprotectedvirtual
QwtWheel(QWidget *parent=NULL)QwtWheelexplicit
setBorderWidth(int)QwtWheel
setInverted(bool tf)QwtWheel
setMass(double)QwtWheelslot
setMaximum(double max)QwtWheel
setMinimum(double min)QwtWheel
setOrientation(Qt::Orientation)QwtWheel
setPageStepCount(int)QwtWheel
setRange(double vmin, double vmax)QwtWheel
setSingleStep(double)QwtWheel
setStepAlignment(bool on)QwtWheel
setTickCount(int)QwtWheel
setTotalAngle(double)QwtWheelslot
setTracking(bool enable)QwtWheel
setUpdateInterval(int)QwtWheel
setValue(double)QwtWheelslot
setViewAngle(double)QwtWheelslot
setWheelBorderWidth(int)QwtWheel
setWheelWidth(int)QwtWheel
setWrapping(bool tf)QwtWheel
singleStep() const QwtWheel
sizeHint() const QwtWheelprotectedvirtual
stepAlignment() const QwtWheel
stopFlying()QwtWheelprotected
tickCount() const QwtWheel
timerEvent(QTimerEvent *)QwtWheelprotectedvirtual
totalAngle() const QwtWheel
updateInterval() const QwtWheel
value() const QwtWheel
valueAt(const QPoint &) const QwtWheelprotectedvirtual
valueChanged(double value)QwtWheelsignal
viewAngle() const QwtWheel
wheelBorderWidth() const QwtWheel
wheelEvent(QWheelEvent *)QwtWheelprotectedvirtual
wheelMoved(double value)QwtWheelsignal
wheelPressed()QwtWheelsignal
wheelRect() const QwtWheelprotected
wheelReleased()QwtWheelsignal
wheelWidth() const QwtWheel
wrapping() const QwtWheel
~QwtWheel()QwtWheelvirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_wheel.html b/ThirdParty/Qwt/doc/html/class_qwt_wheel.html new file mode 100644 index 0000000000..0dcd061505 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_wheel.html @@ -0,0 +1,1679 @@ + + + + + + +Qwt User's Guide: QwtWheel Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+ +
+ +

The Wheel Widget. + More...

+ +

#include <qwt_wheel.h>

+
+Inheritance diagram for QwtWheel:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + + + + + + + +

+Public Slots

void setValue (double)
 Set a new value without adjusting to the step raster. More...
 
void setTotalAngle (double)
 Set the total angle which the wheel can be turned. More...
 
void setViewAngle (double)
 Specify the visible portion of the wheel. More...
 
void setMass (double)
 Set the slider's mass for flywheel effect. More...
 
+ + + + + + + + + + +

+Signals

void valueChanged (double value)
 Notify a change of value. More...
 
void wheelPressed ()
 
void wheelReleased ()
 
void wheelMoved (double value)
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

QwtWheel (QWidget *parent=NULL)
 Constructor.
 
+virtual ~QwtWheel ()
 Destructor.
 
double value () const
 
void setOrientation (Qt::Orientation)
 Set the wheel's orientation. More...
 
Qt::Orientation orientation () const
 
double totalAngle () const
 
double viewAngle () const
 
void setTickCount (int)
 Adjust the number of grooves in the wheel's surface. More...
 
int tickCount () const
 
void setWheelWidth (int)
 Set the width of the wheel. More...
 
int wheelWidth () const
 
void setWheelBorderWidth (int)
 Set the wheel border width of the wheel. More...
 
int wheelBorderWidth () const
 
void setBorderWidth (int)
 Set the border width. More...
 
int borderWidth () const
 
void setInverted (bool tf)
 En/Disable inverted appearance. More...
 
bool isInverted () const
 
void setWrapping (bool tf)
 En/Disable wrapping. More...
 
bool wrapping () const
 
void setSingleStep (double)
 Set the step size of the counter. More...
 
double singleStep () const
 
void setPageStepCount (int)
 Set the page step count. More...
 
int pageStepCount () const
 
void setStepAlignment (bool on)
 En/Disable step alignment. More...
 
bool stepAlignment () const
 
void setRange (double vmin, double vmax)
 Set the minimum and maximum values. More...
 
void setMinimum (double min)
 
double minimum () const
 
void setMaximum (double max)
 
double maximum () const
 
void setUpdateInterval (int)
 Specify the update interval when the wheel is flying. More...
 
int updateInterval () const
 
void setTracking (bool enable)
 En/Disable tracking. More...
 
bool isTracking () const
 
double mass () const
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Protected Member Functions

virtual void paintEvent (QPaintEvent *)
 Qt Paint Event. More...
 
virtual void mousePressEvent (QMouseEvent *)
 Mouse press event handler. More...
 
virtual void mouseReleaseEvent (QMouseEvent *)
 Mouse Release Event handler. More...
 
virtual void mouseMoveEvent (QMouseEvent *)
 Mouse Move Event handler. More...
 
virtual void keyPressEvent (QKeyEvent *)
 
virtual void wheelEvent (QWheelEvent *)
 Handle wheel events. More...
 
virtual void timerEvent (QTimerEvent *)
 Qt timer event. More...
 
+void stopFlying ()
 Stop the flying movement of the wheel.
 
QRect wheelRect () const
 
virtual QSize sizeHint () const
 
virtual QSize minimumSizeHint () const
 
virtual void drawTicks (QPainter *, const QRectF &)
 
virtual void drawWheelBackground (QPainter *, const QRectF &)
 
virtual double valueAt (const QPoint &) const
 
+

Detailed Description

+

The Wheel Widget.

+

The wheel widget can be used to change values over a very large range in very small steps. Using the setMass() member, it can be configured as a flying wheel.

+

The default range of the wheel is [0.0, 100.0]

+
See Also
The radio example.
+

Member Function Documentation

+ +
+
+ + + + + + + +
int QwtWheel::borderWidth () const
+
+
Returns
Border width
+
See Also
setBorderWidth()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void QwtWheel::drawTicks (QPainter * painter,
const QRectF & rect 
)
+
+protectedvirtual
+
+

Draw the Wheel's ticks

+
Parameters
+ + + +
painterPainter
rectGeometry for the wheel
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void QwtWheel::drawWheelBackground (QPainter * painter,
const QRectF & rect 
)
+
+protectedvirtual
+
+

Draw the Wheel's background gradient

+
Parameters
+ + + +
painterPainter
rectGeometry for the wheel
+
+
+ +
+
+ +
+
+ + + + + + + +
bool QwtWheel::isInverted () const
+
+
Returns
True, when the wheel is inverted
+
See Also
setInverted()
+ +
+
+ +
+
+ + + + + + + +
bool QwtWheel::isTracking () const
+
+
Returns
True, when tracking is enabled
+
See Also
setTracking(), valueChanged(), wheelMoved()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtWheel::keyPressEvent (QKeyEvent * event)
+
+protectedvirtual
+
+

Handle key events

+ + +
    +
  • Qt::Key_Up
    + In case of a horizontal or not inverted vertical wheel the value will be incremented by the step size. For an inverted vertical wheel the value will be decremented by the step size.
  • +
+
    +
  • Qt::Key_Down
    + In case of a horizontal or not inverted vertical wheel the value will be decremented by the step size. For an inverted vertical wheel the value will be incremented by the step size.
  • +
+
    +
  • Qt::Key_PageUp
    + The value will be incremented by pageStepSize() * singleStepSize().
  • +
+
    +
  • Qt::Key_PageDown
    + The value will be decremented by pageStepSize() * singleStepSize().
  • +
+
Parameters
+ + +
eventKey event
+
+
+ +
+
+ +
+
+ + + + + + + +
double QwtWheel::mass () const
+
+
Returns
mass
+
See Also
setMass()
+ +
+
+ +
+
+ + + + + + + +
double QwtWheel::maximum () const
+
+
Returns
The maximum of the range
+
See Also
setRange(), setMaximum(), minimum()
+ +
+
+ +
+
+ + + + + + + +
double QwtWheel::minimum () const
+
+
Returns
The minimum of the range
+
See Also
setRange(), setMinimum(), maximum()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
QSize QwtWheel::minimumSizeHint () const
+
+protectedvirtual
+
+
Returns
Minimum size hint
+
Warning
The return value is based on the wheel width.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtWheel::mouseMoveEvent (QMouseEvent * event)
+
+protectedvirtual
+
+ +

Mouse Move Event handler.

+

Turn the wheel according to the mouse position

+
Parameters
+ + +
eventMouse event
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtWheel::mousePressEvent (QMouseEvent * event)
+
+protectedvirtual
+
+ +

Mouse press event handler.

+

Start movement of the wheel.

+
Parameters
+ + +
eventMouse event
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtWheel::mouseReleaseEvent (QMouseEvent * event)
+
+protectedvirtual
+
+ +

Mouse Release Event handler.

+

When the wheel has no mass the movement of the wheel stops, otherwise it starts flying.

+
Parameters
+ + +
eventMouse event
+
+
+ +
+
+ +
+
+ + + + + + + +
Qt::Orientation QwtWheel::orientation () const
+
+
Returns
Orientation
+
See Also
setOrientation()
+ +
+
+ +
+
+ + + + + + + +
int QwtWheel::pageStepCount () const
+
+
Returns
Page step count
+
See Also
setPageStepCount(), singleStep()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtWheel::paintEvent (QPaintEvent * event)
+
+protectedvirtual
+
+ +

Qt Paint Event.

+
Parameters
+ + +
eventPaint event
+
+
+ +
+
+ +
+
+ + + + + + + + +
void QwtWheel::setBorderWidth (int width)
+
+ +

Set the border width.

+

The border defaults to 2.

+
Parameters
+ + +
widthBorder width
+
+
+
See Also
borderWidth()
+ +
+
+ +
+
+ + + + + + + + +
void QwtWheel::setInverted (bool on)
+
+ +

En/Disable inverted appearance.

+

An inverted wheel increases its values in the opposite direction. The direction of an inverted horizontal wheel will be from right to left an inverted vertical wheel will increase from bottom to top.

+
Parameters
+ + +
onEn/Disable inverted appearance
+
+
+
See Also
isInverted()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtWheel::setMass (double mass)
+
+slot
+
+ +

Set the slider's mass for flywheel effect.

+

If the slider's mass is greater then 0, it will continue to move after the mouse button has been released. Its speed decreases with time at a rate depending on the slider's mass. A large mass means that it will continue to move for a long time.

+

Derived widgets may overload this function to make it public.

+
Parameters
+ + +
massNew mass in kg
+
+
+
See Also
mass()
+ +
+
+ +
+
+ + + + + + + + +
void QwtWheel::setMaximum (double value)
+
+

Set the maximum value of the range

+
Parameters
+ + +
valueMaximum value
+
+
+
See Also
setRange(), setMinimum(), maximum()
+ +
+
+ +
+
+ + + + + + + + +
void QwtWheel::setMinimum (double value)
+
+

Set the minimum value of the range

+
Parameters
+ + +
valueMinimum value
+
+
+
See Also
setRange(), setMaximum(), minimum()
+
Note
The maximum is adjusted if necessary to ensure that the range remains valid.
+ +
+
+ +
+
+ + + + + + + + +
void QwtWheel::setOrientation (Qt::Orientation orientation)
+
+ +

Set the wheel's orientation.

+

The default orientation is Qt::Horizontal.

+
Parameters
+ + +
orientationQt::Horizontal or Qt::Vertical.
+
+
+
See Also
orientation()
+ +
+
+ +
+
+ + + + + + + + +
void QwtWheel::setPageStepCount (int count)
+
+ +

Set the page step count.

+

pageStepCount is a multiplicator for the single step size that typically corresponds to the user pressing PageUp or PageDown.

+

A value of 0 disables page stepping.

+

The default value is 1.

+
Parameters
+ + +
countMultiplicator for the single step size
+
+
+
See Also
pageStepCount(), setSingleStep()
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void QwtWheel::setRange (double min,
double max 
)
+
+ +

Set the minimum and maximum values.

+

The maximum is adjusted if necessary to ensure that the range remains valid. The value might be modified to be inside of the range.

+
Parameters
+ + + +
minMinimum value
maxMaximum value
+
+
+
See Also
minimum(), maximum()
+ +
+
+ +
+
+ + + + + + + + +
void QwtWheel::setSingleStep (double stepSize)
+
+ +

Set the step size of the counter.

+

A value <= 0.0 disables stepping

+
Parameters
+ + +
stepSizeSingle step size
+
+
+
See Also
singleStep(), setPageStepCount()
+ +
+
+ +
+
+ + + + + + + + +
void QwtWheel::setStepAlignment (bool on)
+
+ +

En/Disable step alignment.

+

When step alignment is enabled value changes initiated by user input ( mouse, keyboard, wheel ) are aligned to the multiples of the single step.

+
Parameters
+ + +
onOn/Off
+
+
+
See Also
stepAlignment(), setSingleStep()
+ +
+
+ +
+
+ + + + + + + + +
void QwtWheel::setTickCount (int count)
+
+ +

Adjust the number of grooves in the wheel's surface.

+

The number of grooves is limited to 6 <= count <= 50. Values outside this range will be clipped. The default value is 10.

+
Parameters
+ + +
countNumber of grooves per 360 degrees
+
+
+
See Also
tickCount()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtWheel::setTotalAngle (double angle)
+
+slot
+
+ +

Set the total angle which the wheel can be turned.

+

One full turn of the wheel corresponds to an angle of 360 degrees. A total angle of n*360 degrees means that the wheel has to be turned n times around its axis to get from the minimum value to the maximum value.

+

The default setting of the total angle is 360 degrees.

+
Parameters
+ + +
angletotal angle in degrees
+
+
+
See Also
totalAngle()
+ +
+
+ +
+
+ + + + + + + + +
void QwtWheel::setTracking (bool enable)
+
+ +

En/Disable tracking.

+

If tracking is enabled (the default), the wheel emits the valueChanged() signal while the wheel is moving. If tracking is disabled, the wheel emits the valueChanged() signal only when the wheel movement is terminated.

+

The wheelMoved() signal is emitted regardless id tracking is enabled or not.

+
Parameters
+ + +
enableOn/Off
+
+
+
See Also
isTracking()
+ +
+
+ +
+
+ + + + + + + + +
void QwtWheel::setUpdateInterval (int interval)
+
+ +

Specify the update interval when the wheel is flying.

+

Default and minimum value is 50 ms.

+
Parameters
+ + +
intervalInterval in milliseconds
+
+
+
See Also
updateInterval(), setMass(), setTracking()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtWheel::setValue (double value)
+
+slot
+
+ +

Set a new value without adjusting to the step raster.

+
Parameters
+ + +
valueNew value
+
+
+
See Also
value(), valueChanged()
+
Warning
The value is clipped when it lies outside the range.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtWheel::setViewAngle (double angle)
+
+slot
+
+ +

Specify the visible portion of the wheel.

+

You may use this function for fine-tuning the appearance of the wheel. The default value is 175 degrees. The value is limited from 10 to 175 degrees.

+
Parameters
+ + +
angleVisible angle in degrees
+
+
+
See Also
viewAngle(), setTotalAngle()
+ +
+
+ +
+
+ + + + + + + + +
void QwtWheel::setWheelBorderWidth (int borderWidth)
+
+ +

Set the wheel border width of the wheel.

+

The wheel border must not be smaller than 1 and is limited in dependence on the wheel's size. Values outside the allowed range will be clipped.

+

The wheel border defaults to 2.

+
Parameters
+ + +
borderWidthBorder width
+
+
+
See Also
internalBorder()
+ +
+
+ +
+
+ + + + + + + + +
void QwtWheel::setWheelWidth (int width)
+
+ +

Set the width of the wheel.

+

Corresponds to the wheel height for horizontal orientation, and the wheel width for vertical orientation.

+
Parameters
+ + +
widththe wheel's width
+
+
+
See Also
wheelWidth()
+ +
+
+ +
+
+ + + + + + + + +
void QwtWheel::setWrapping (bool on)
+
+ +

En/Disable wrapping.

+

If wrapping is true stepping up from maximum() value will take you to the minimum() value and vice versa.

+
Parameters
+ + +
onEn/Disable wrapping
+
+
+
See Also
wrapping()
+ +
+
+ +
+
+ + + + + + + +
double QwtWheel::singleStep () const
+
+
Returns
Single step size
+
See Also
setSingleStep()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
QSize QwtWheel::sizeHint () const
+
+protectedvirtual
+
+
Returns
a size hint
+ +
+
+ +
+
+ + + + + + + +
bool QwtWheel::stepAlignment () const
+
+
Returns
True, when the step alignment is enabled
+
See Also
setStepAlignment(), singleStep()
+ +
+
+ +
+
+ + + + + + + +
int QwtWheel::tickCount () const
+
+
Returns
Number of grooves in the wheel's surface.
+
See Also
setTickCnt()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtWheel::timerEvent (QTimerEvent * event)
+
+protectedvirtual
+
+ +

Qt timer event.

+

The flying wheel effect is implemented using a timer

+
Parameters
+ + +
eventTimer event
+
+
+
See Also
updateInterval()
+ +
+
+ +
+
+ + + + + + + +
double QwtWheel::totalAngle () const
+
+
Returns
Total angle which the wheel can be turned.
+
See Also
setTotalAngle()
+ +
+
+ +
+
+ + + + + + + +
int QwtWheel::updateInterval () const
+
+
Returns
Update interval when the wheel is flying
+
See Also
setUpdateInterval(), mass(), isTracking()
+ +
+
+ +
+
+ + + + + + + +
double QwtWheel::value () const
+
+
Returns
Current value of the wheel
+
See Also
setValue(), valueChanged()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
double QwtWheel::valueAt (const QPoint & pos) const
+
+protectedvirtual
+
+

Determine the value corresponding to a specified point

+
Parameters
+ + +
posPosition
+
+
+
Returns
Value corresponding to pos
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtWheel::valueChanged (double value)
+
+signal
+
+ +

Notify a change of value.

+

When tracking is enabled this signal will be emitted every time the value changes.

+
Parameters
+ + +
valuenew value
+
+
+
See Also
setTracking()
+ +
+
+ +
+
+ + + + + + + +
double QwtWheel::viewAngle () const
+
+
Returns
Visible portion of the wheel
+
See Also
setViewAngle(), totalAngle()
+ +
+
+ +
+
+ + + + + + + +
int QwtWheel::wheelBorderWidth () const
+
+
Returns
Wheel border width
+
See Also
setWheelBorderWidth()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtWheel::wheelEvent (QWheelEvent * event)
+
+protectedvirtual
+
+ +

Handle wheel events.

+

In/Decrement the value

+
Parameters
+ + +
eventWheel event
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtWheel::wheelMoved (double value)
+
+signal
+
+

This signal is emitted when the user moves the wheel with the mouse.

+
Parameters
+ + +
valuenew value
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void QwtWheel::wheelPressed ()
+
+signal
+
+

This signal is emitted when the user presses the the wheel with the mouse

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
QRect QwtWheel::wheelRect () const
+
+protected
+
+
Returns
Rectangle of the wheel without the outer border
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void QwtWheel::wheelReleased ()
+
+signal
+
+

This signal is emitted when the user releases the mouse

+ +
+
+ +
+
+ + + + + + + +
int QwtWheel::wheelWidth () const
+
+
Returns
Width of the wheel
+
See Also
setWheelWidth()
+ +
+
+ +
+
+ + + + + + + +
bool QwtWheel::wrapping () const
+
+
Returns
True, when wrapping is set
+
See Also
setWrapping()
+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_wheel__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_wheel__inherit__graph.map new file mode 100644 index 0000000000..a6b0b4cef7 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_wheel__inherit__graph.map @@ -0,0 +1,2 @@ + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_wheel__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_wheel__inherit__graph.md5 new file mode 100644 index 0000000000..aca3d81eb3 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_wheel__inherit__graph.md5 @@ -0,0 +1 @@ +40ea6b9c298867a3dea4212889edb801 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_wheel__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_wheel__inherit__graph.png new file mode 100644 index 0000000000..5d09ad0523 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_wheel__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/class_qwt_widget_overlay-members.html b/ThirdParty/Qwt/doc/html/class_qwt_widget_overlay-members.html new file mode 100644 index 0000000000..8a29cd2fa6 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_widget_overlay-members.html @@ -0,0 +1,120 @@ + + + + + + +Qwt User's Guide: Member List + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
QwtWidgetOverlay Member List
+
+
+ +

This is the complete list of members for QwtWidgetOverlay, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + +
AlphaMask enum valueQwtWidgetOverlay
AutoRenderMode enum valueQwtWidgetOverlay
CopyAlphaMask enum valueQwtWidgetOverlay
DrawOverlay enum valueQwtWidgetOverlay
drawOverlay(QPainter *painter) const =0QwtWidgetOverlayprotectedpure virtual
eventFilter(QObject *, QEvent *)QwtWidgetOverlayvirtual
MaskHint enum valueQwtWidgetOverlay
maskHint() const QwtWidgetOverlayprotectedvirtual
MaskMode enum nameQwtWidgetOverlay
maskMode() const QwtWidgetOverlay
NoMask enum valueQwtWidgetOverlay
paintEvent(QPaintEvent *event)QwtWidgetOverlayprotectedvirtual
QwtWidgetOverlay(QWidget *)QwtWidgetOverlay
RenderMode enum nameQwtWidgetOverlay
renderMode() const QwtWidgetOverlay
resizeEvent(QResizeEvent *event)QwtWidgetOverlayprotectedvirtual
setMaskMode(MaskMode)QwtWidgetOverlay
setRenderMode(RenderMode)QwtWidgetOverlay
updateOverlay()QwtWidgetOverlay
~QwtWidgetOverlay()QwtWidgetOverlayvirtual
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_widget_overlay.html b/ThirdParty/Qwt/doc/html/class_qwt_widget_overlay.html new file mode 100644 index 0000000000..3b6a904302 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_widget_overlay.html @@ -0,0 +1,538 @@ + + + + + + +Qwt User's Guide: QwtWidgetOverlay Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + + +
+ +
+ +
+
+ +
+
QwtWidgetOverlay Class Referenceabstract
+
+
+ +

An overlay for a widget. + More...

+ +

#include <qwt_widget_overlay.h>

+
+Inheritance diagram for QwtWidgetOverlay:
+
+
Inheritance graph
+ + +
[legend]
+ + + + + + + + +

+Public Types

enum  MaskMode { NoMask, +MaskHint, +AlphaMask + }
 Mask mode. More...
 
enum  RenderMode { AutoRenderMode, +CopyAlphaMask, +DrawOverlay + }
 Render mode. More...
 
+ + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 QwtWidgetOverlay (QWidget *)
 Constructor. More...
 
+virtual ~QwtWidgetOverlay ()
 Destructor.
 
void setMaskMode (MaskMode)
 Specify how to find the mask for the overlay. More...
 
MaskMode maskMode () const
 
void setRenderMode (RenderMode)
 
RenderMode renderMode () const
 
void updateOverlay ()
 
virtual bool eventFilter (QObject *, QEvent *)
 Event filter. More...
 
+ + + + + + + + + + +

+Protected Member Functions

virtual void paintEvent (QPaintEvent *event)
 
virtual void resizeEvent (QResizeEvent *event)
 
virtual QRegion maskHint () const
 Calculate an approximation for the mask. More...
 
virtual void drawOverlay (QPainter *painter) const =0
 
+

Detailed Description

+

An overlay for a widget.

+

The main use case of an widget overlay is to avoid heavy repaint operation of the widget below.

+

F.e. in combination with the plot canvas an overlay avoid replots as the content of the canvas can be restored from its backing store.

+

QwtWidgetOverlay is an abstract base class. Deriving classes are supposed to reimplement the following methods:

+ +

Internally QwtPlotPicker uses overlays for displaying the rubber band and the tracker text.

+
See Also
QwtPlotCanvas::BackingStore
+

Member Enumeration Documentation

+ +
+
+ + + + +
enum QwtWidgetOverlay::MaskMode
+
+ +

Mask mode.

+

When using masks the widget below gets paint events for the masked regions of the overlay only. Otherwise Qt triggers full repaints. On less powerful hardware ( f.e embedded systems ) - or when using the raster paint engine on a remote desktop - bit blitting is a noticeable operation, that needs to be avoided.

+

If and how to mask depends on how expensive the calculation of the mask is and how many pixels can be excluded by the mask.

+

The default setting is MaskHint.

+
See Also
setMaskMode(), maskMode()
+ + + + +
Enumerator
NoMask  +

Don't use a mask.

+
MaskHint  +

Use maskHint() as mask.

+

For many situations a fast approximation is good enough and it is not necessary to build a more detailed mask ( f.e the bounding rectangle of a text ).

+
AlphaMask  +

Calculate a mask by checking the alpha values.

+

Sometimes it is not possible to give a fast approximation and the mask needs to be calculated by drawing the overlay and testing the result.

+

When a valid maskHint() is available only pixels inside this approximation are checked.

+
+ +
+
+ +
+
+ +

Render mode.

+

For calculating the alpha mask the overlay has already been painted to a temporary QImage. Instead of rendering the overlay twice this buffer can be copied for drawing the overlay.

+

On graphic systems using the raster paint engine ( QWS, Windows ) it means usually copying some memory only. On X11 it results in an expensive operation building a pixmap and for simple overlays it might not be recommended.

+
Note
The render mode has no effect, when maskMode() != AlphaMask.
+ + + + +
Enumerator
AutoRenderMode  +

Copy the buffer, when using the raster paint engine.

+
CopyAlphaMask  +

Always copy the buffer.

+
DrawOverlay  +

Never copy the buffer.

+
+ +
+
+

Constructor & Destructor Documentation

+ +
+
+ + + + + + + + +
QwtWidgetOverlay::QwtWidgetOverlay (QWidget * widget)
+
+ +

Constructor.

+
Parameters
+ + +
widgetParent widget, where the overlay is aligned to
+
+
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + + +
virtual void QwtWidgetOverlay::drawOverlay (QPainter * painter) const
+
+protectedpure virtual
+
+

Draw the widget overlay

+
Parameters
+ + +
painterPainter
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool QwtWidgetOverlay::eventFilter (QObject * object,
QEvent * event 
)
+
+virtual
+
+ +

Event filter.

+

Resize the overlay according to the size of the parent widget.

+
Parameters
+ + + +
objectObject to be filtered
eventEvent
+
+
+
Returns
See QObject::eventFilter()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
QRegion QwtWidgetOverlay::maskHint () const
+
+protectedvirtual
+
+ +

Calculate an approximation for the mask.

+
    +
  • MaskHint The hint is used as mask.
  • +
+
    +
  • AlphaMask The hint is used to speed up the algorithm for calculating a mask from non transparent pixels
  • +
+
    +
  • NoMask The hint is unused.
  • +
+

The default implementation returns an invalid region indicating no hint.

+
Returns
Hint for the mask
+ +
+
+ +
+
+ + + + + + + +
QwtWidgetOverlay::MaskMode QwtWidgetOverlay::maskMode () const
+
+
Returns
Mode how to find the mask for the overlay
+
See Also
setMaskMode()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtWidgetOverlay::paintEvent (QPaintEvent * event)
+
+protectedvirtual
+
+

Paint event

+
Parameters
+ + +
eventPaint event
+
+
+
See Also
drawOverlay()
+ +
+
+ +
+
+ + + + + + + +
QwtWidgetOverlay::RenderMode QwtWidgetOverlay::renderMode () const
+
+
Returns
Render mode
+
See Also
RenderMode, setRenderMode()
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void QwtWidgetOverlay::resizeEvent (QResizeEvent * event)
+
+protectedvirtual
+
+

Resize event

+
Parameters
+ + +
eventResize event
+
+
+ +
+
+ +
+
+ + + + + + + + +
void QwtWidgetOverlay::setMaskMode (MaskMode mode)
+
+ +

Specify how to find the mask for the overlay.

+
Parameters
+ + +
modeNew mode
+
+
+
See Also
maskMode()
+ +
+
+ +
+
+ + + + + + + + +
void QwtWidgetOverlay::setRenderMode (RenderMode mode)
+
+

Set the render mode

+
Parameters
+ + +
modeRender mode
+
+
+
See Also
RenderMode, renderMode()
+ +
+
+ +
+
+ + + + + + + +
void QwtWidgetOverlay::updateOverlay ()
+
+

Recalculate the mask and repaint the overlay

+ +
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_widget_overlay__inherit__graph.map b/ThirdParty/Qwt/doc/html/class_qwt_widget_overlay__inherit__graph.map new file mode 100644 index 0000000000..35b05235ea --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_widget_overlay__inherit__graph.map @@ -0,0 +1,2 @@ + + diff --git a/ThirdParty/Qwt/doc/html/class_qwt_widget_overlay__inherit__graph.md5 b/ThirdParty/Qwt/doc/html/class_qwt_widget_overlay__inherit__graph.md5 new file mode 100644 index 0000000000..960c96752c --- /dev/null +++ b/ThirdParty/Qwt/doc/html/class_qwt_widget_overlay__inherit__graph.md5 @@ -0,0 +1 @@ +d8a3404f8e07a59e532ca052bb998669 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/class_qwt_widget_overlay__inherit__graph.png b/ThirdParty/Qwt/doc/html/class_qwt_widget_overlay__inherit__graph.png new file mode 100644 index 0000000000..ef9d592c4e Binary files /dev/null and b/ThirdParty/Qwt/doc/html/class_qwt_widget_overlay__inherit__graph.png differ diff --git a/ThirdParty/Qwt/doc/html/classes.html b/ThirdParty/Qwt/doc/html/classes.html new file mode 100644 index 0000000000..ee318a3ecd --- /dev/null +++ b/ThirdParty/Qwt/doc/html/classes.html @@ -0,0 +1,153 @@ + + + + + + +Qwt User's Guide: Class Index + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + +
+ + + + +
+ +
+ +
+
+
Class Index
+
+
+
A | C | D | E | G | I | K | L | M | N | O | P | R | S | T | W
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  A  
+
QwtDynGridLayout   QwtNullTransform   QwtPlotLegendItem   QwtScaleArithmetic   
  E  
+
  O  
+
QwtPlotMagnifier   QwtScaleDiv   
QwtAbstractLegend   QwtPlotMarker   QwtScaleDraw   
QwtAbstractScale   QwtEventPattern   QwtOHLCSample   QwtPlotMultiBarChart   QwtScaleEngine   
QwtAbstractScaleDraw   
  G  
+
  P  
+
QwtPlotPanner   QwtScaleMap   
QwtAbstractSeriesStore   QwtPlotPicker   QwtScaleWidget   
QwtAbstractSlider   QwtGraphic   QwtPainter   QwtPlotRasterItem   QwtSeriesData   
QwtAlphaColorMap   
  I  
+
QwtPainterCommand   QwtPlotRenderer   QwtSeriesStore   
QwtAnalogClock   QwtPanner   QwtPlotRescaler   QwtSetSample   
QwtArraySeriesData   QwtInterval   QwtPicker   QwtPlotScaleItem   QwtSetSeriesData   
QwtArrowButton   QwtIntervalSample   QwtPickerClickPointMachine   QwtPlotSeriesItem   QwtSimpleCompassRose   
  C  
+
QwtIntervalSeriesData   QwtPickerClickRectMachine   QwtPlotShapeItem   QwtSlider   
QwtIntervalSymbol   QwtPickerDragLineMachine   QwtPlotSpectroCurve   QwtSpline   
QwtClipper   
  K  
+
QwtPickerDragPointMachine   QwtPlotSpectrogram   QwtSplineCurveFitter   
QwtColorMap   QwtPickerDragRectMachine   QwtPlotSvgItem   QwtSymbol   
QwtColumnRect   QwtEventPattern::KeyPattern   QwtPickerMachine   QwtPlotTextLabel   QwtSyntheticPointData   
QwtColumnSymbol   QwtKnob   QwtPickerPolygonMachine   QwtPlotTradingCurve   QwtSystemClock   
QwtCompass   
  L  
+
QwtPickerTrackerMachine   QwtPlotZoneItem   
  T  
+
QwtCompassMagnetNeedle   QwtPixelMatrix   QwtPlotZoomer   
QwtCompassRose   QwtLegend   QwtPlainTextEngine   QwtPoint3D   QwtText   
QwtCompassScaleDraw   QwtLegendData   QwtPlot   QwtPoint3DSeriesData   QwtTextEngine   
QwtCompassWindArrow   QwtLegendLabel   QwtPlotAbstractBarChart   QwtPointArrayData   QwtTextLabel   
QwtCounter   QwtLinearColorMap   QwtPlotBarChart   QwtPointMapper   QwtThermo   
QwtCPointerData   QwtLinearScaleEngine   QwtPlotCanvas   QwtPointPolar   QwtTradingChartData   
QwtCurveFitter   QwtLogScaleEngine   QwtPlotCurve   QwtPointSeriesData   QwtTransform   
  D  
+
QwtLogTransform   QwtPlotDict   QwtPowerTransform   
  W  
+
  M  
+
QwtPlotDirectPainter   
  R  
+
QwtDate   QwtPlotGLCanvas   QwtWeedingCurveFitter   
QwtDateScaleDraw   QwtMagnifier   QwtPlotGrid   QwtRasterData   QwtWheel   
QwtDateScaleEngine   QwtMathMLTextEngine   QwtPlotHistogram   QwtRichTextEngine   QwtWidgetOverlay   
QwtDial   QwtMatrixRasterData   QwtPlotIntervalCurve   QwtRoundScaleDraw   
QwtDialNeedle   QwtEventPattern::MousePattern   QwtPlotItem   
  S  
+
QwtDialSimpleNeedle   
  N  
+
QwtPlotLayout   
QwtSamplingThread   
QwtNullPaintDevice   
+
A | C | D | E | G | I | K | L | M | N | O | P | R | S | T | W
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/closed.png b/ThirdParty/Qwt/doc/html/closed.png new file mode 100644 index 0000000000..98cc2c909d Binary files /dev/null and b/ThirdParty/Qwt/doc/html/closed.png differ diff --git a/ThirdParty/Qwt/doc/html/controlscreenshots.html b/ThirdParty/Qwt/doc/html/controlscreenshots.html new file mode 100644 index 0000000000..2cc7824a39 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/controlscreenshots.html @@ -0,0 +1,104 @@ + + + + + + +Qwt User's Guide: Dials, Compasses, Knobs, Wheels, Sliders, Thermos + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ +
+
+
+
Dials, Compasses, Knobs, Wheels, Sliders, Thermos
+
+
+
+radio.png +
+
+sliders.png +
+
+dials1.png +
+
+dials2.png +
+
+sysinfo.png +
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/cpuplot.png b/ThirdParty/Qwt/doc/html/cpuplot.png new file mode 100644 index 0000000000..0f1bfc3628 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/cpuplot.png differ diff --git a/ThirdParty/Qwt/doc/html/curves.png b/ThirdParty/Qwt/doc/html/curves.png new file mode 100644 index 0000000000..e24c81c962 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/curves.png differ diff --git a/ThirdParty/Qwt/doc/html/curvescreenshots.html b/ThirdParty/Qwt/doc/html/curvescreenshots.html new file mode 100644 index 0000000000..24072b2def --- /dev/null +++ b/ThirdParty/Qwt/doc/html/curvescreenshots.html @@ -0,0 +1,104 @@ + + + + + + +Qwt User's Guide: Curve Plots + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ +
+
+
+
Curve Plots
+
+
+
+plot.png +
+
+sinus.png +
+
+cpuplot.png +
+
+graph.png +
+
+curves.png +
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/dials1.png b/ThirdParty/Qwt/doc/html/dials1.png new file mode 100644 index 0000000000..690c663d62 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/dials1.png differ diff --git a/ThirdParty/Qwt/doc/html/dials2.png b/ThirdParty/Qwt/doc/html/dials2.png new file mode 100644 index 0000000000..59d1a611dc Binary files /dev/null and b/ThirdParty/Qwt/doc/html/dials2.png differ diff --git a/ThirdParty/Qwt/doc/html/dir_06d3aa943e68e822334d93a35d8d6e04.html b/ThirdParty/Qwt/doc/html/dir_06d3aa943e68e822334d93a35d8d6e04.html new file mode 100644 index 0000000000..0dda22e7e2 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/dir_06d3aa943e68e822334d93a35d8d6e04.html @@ -0,0 +1,112 @@ + + + + + + +Qwt User's Guide: mathml Directory Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
mathml Directory Reference
+
+
+
+Directory dependency graph for mathml:
+
+
mathml
+ + +
+ + + + + + + + + + +

+Files

file  qwt_mathml_text_engine.cpp
 
file  qwt_mathml_text_engine.h [code]
 
file  qwt_mml_document.cpp
 
file  qwt_mml_document.h [code]
 
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/dir_06d3aa943e68e822334d93a35d8d6e04_dep.map b/ThirdParty/Qwt/doc/html/dir_06d3aa943e68e822334d93a35d8d6e04_dep.map new file mode 100644 index 0000000000..78e256a2f4 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/dir_06d3aa943e68e822334d93a35d8d6e04_dep.map @@ -0,0 +1,4 @@ + + + + diff --git a/ThirdParty/Qwt/doc/html/dir_06d3aa943e68e822334d93a35d8d6e04_dep.md5 b/ThirdParty/Qwt/doc/html/dir_06d3aa943e68e822334d93a35d8d6e04_dep.md5 new file mode 100644 index 0000000000..81dd9bf35a --- /dev/null +++ b/ThirdParty/Qwt/doc/html/dir_06d3aa943e68e822334d93a35d8d6e04_dep.md5 @@ -0,0 +1 @@ +73c21324eb0853e9b6458a551bf9959c \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/dir_06d3aa943e68e822334d93a35d8d6e04_dep.png b/ThirdParty/Qwt/doc/html/dir_06d3aa943e68e822334d93a35d8d6e04_dep.png new file mode 100644 index 0000000000..2f5a100b52 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/dir_06d3aa943e68e822334d93a35d8d6e04_dep.png differ diff --git a/ThirdParty/Qwt/doc/html/dir_9ccb36e974cdad92d68e40b0bc8a6a19.html b/ThirdParty/Qwt/doc/html/dir_9ccb36e974cdad92d68e40b0bc8a6a19.html new file mode 100644 index 0000000000..cc07523230 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/dir_9ccb36e974cdad92d68e40b0bc8a6a19.html @@ -0,0 +1,488 @@ + + + + + + +Qwt User's Guide: src Directory Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
src Directory Reference
+
+
+
+Directory dependency graph for src:
+
+
src
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Files

file  qwt_abstract_legend.cpp
 
file  qwt_abstract_legend.h [code]
 
file  qwt_abstract_scale.cpp
 
file  qwt_abstract_scale.h [code]
 
file  qwt_abstract_scale_draw.cpp
 
file  qwt_abstract_scale_draw.h [code]
 
file  qwt_abstract_slider.cpp
 
file  qwt_abstract_slider.h [code]
 
file  qwt_analog_clock.cpp
 
file  qwt_analog_clock.h [code]
 
file  qwt_arrow_button.cpp
 
file  qwt_arrow_button.h [code]
 
file  qwt_clipper.cpp
 
file  qwt_clipper.h [code]
 
file  qwt_color_map.cpp
 
file  qwt_color_map.h [code]
 
file  qwt_column_symbol.cpp
 
file  qwt_column_symbol.h [code]
 
file  qwt_compass.cpp
 
file  qwt_compass.h [code]
 
file  qwt_compass_rose.cpp
 
file  qwt_compass_rose.h [code]
 
file  qwt_compat.h [code]
 
file  qwt_counter.cpp
 
file  qwt_counter.h [code]
 
file  qwt_curve_fitter.cpp
 
file  qwt_curve_fitter.h [code]
 
file  qwt_date.cpp
 
file  qwt_date.h [code]
 
file  qwt_date_scale_draw.cpp
 
file  qwt_date_scale_draw.h [code]
 
file  qwt_date_scale_engine.cpp
 
file  qwt_date_scale_engine.h [code]
 
file  qwt_dial.cpp
 
file  qwt_dial.h [code]
 
file  qwt_dial_needle.cpp
 
file  qwt_dial_needle.h [code]
 
file  qwt_dyngrid_layout.cpp
 
file  qwt_dyngrid_layout.h [code]
 
file  qwt_event_pattern.cpp
 
file  qwt_event_pattern.h [code]
 
file  qwt_global.h [code]
 
file  qwt_graphic.cpp
 
file  qwt_graphic.h [code]
 
file  qwt_interval.cpp
 
file  qwt_interval.h [code]
 
file  qwt_interval_symbol.cpp
 
file  qwt_interval_symbol.h [code]
 
file  qwt_knob.cpp
 
file  qwt_knob.h [code]
 
file  qwt_legend.cpp
 
file  qwt_legend.h [code]
 
file  qwt_legend_data.cpp
 
file  qwt_legend_data.h [code]
 
file  qwt_legend_label.cpp
 
file  qwt_legend_label.h [code]
 
file  qwt_magnifier.cpp
 
file  qwt_magnifier.h [code]
 
file  qwt_math.cpp
 
file  qwt_math.h [code]
 
file  qwt_matrix_raster_data.cpp
 
file  qwt_matrix_raster_data.h [code]
 
file  qwt_null_paintdevice.cpp
 
file  qwt_null_paintdevice.h [code]
 
file  qwt_painter.cpp
 
file  qwt_painter.h [code]
 
file  qwt_painter_command.cpp
 
file  qwt_painter_command.h [code]
 
file  qwt_panner.cpp
 
file  qwt_panner.h [code]
 
file  qwt_picker.cpp
 
file  qwt_picker.h [code]
 
file  qwt_picker_machine.cpp
 
file  qwt_picker_machine.h [code]
 
file  qwt_pixel_matrix.cpp
 
file  qwt_pixel_matrix.h [code]
 
file  qwt_plot.cpp
 
file  qwt_plot.h [code]
 
file  qwt_plot_abstract_barchart.cpp
 
file  qwt_plot_abstract_barchart.h [code]
 
file  qwt_plot_axis.cpp
 
file  qwt_plot_barchart.cpp
 
file  qwt_plot_barchart.h [code]
 
file  qwt_plot_canvas.cpp
 
file  qwt_plot_canvas.h [code]
 
file  qwt_plot_curve.cpp
 
file  qwt_plot_curve.h [code]
 
file  qwt_plot_dict.cpp
 
file  qwt_plot_dict.h [code]
 
file  qwt_plot_directpainter.cpp
 
file  qwt_plot_directpainter.h [code]
 
file  qwt_plot_glcanvas.cpp
 
file  qwt_plot_glcanvas.h [code]
 
file  qwt_plot_grid.cpp
 
file  qwt_plot_grid.h [code]
 
file  qwt_plot_histogram.cpp
 
file  qwt_plot_histogram.h [code]
 
file  qwt_plot_intervalcurve.cpp
 
file  qwt_plot_intervalcurve.h [code]
 
file  qwt_plot_item.cpp
 
file  qwt_plot_item.h [code]
 
file  qwt_plot_layout.cpp
 
file  qwt_plot_layout.h [code]
 
file  qwt_plot_legenditem.cpp
 
file  qwt_plot_legenditem.h [code]
 
file  qwt_plot_magnifier.cpp
 
file  qwt_plot_magnifier.h [code]
 
file  qwt_plot_marker.cpp
 
file  qwt_plot_marker.h [code]
 
file  qwt_plot_multi_barchart.cpp
 
file  qwt_plot_multi_barchart.h [code]
 
file  qwt_plot_panner.cpp
 
file  qwt_plot_panner.h [code]
 
file  qwt_plot_picker.cpp
 
file  qwt_plot_picker.h [code]
 
file  qwt_plot_rasteritem.cpp
 
file  qwt_plot_rasteritem.h [code]
 
file  qwt_plot_renderer.cpp
 
file  qwt_plot_renderer.h [code]
 
file  qwt_plot_rescaler.cpp
 
file  qwt_plot_rescaler.h [code]
 
file  qwt_plot_scaleitem.cpp
 
file  qwt_plot_scaleitem.h [code]
 
file  qwt_plot_seriesitem.cpp
 
file  qwt_plot_seriesitem.h [code]
 
file  qwt_plot_shapeitem.cpp
 
file  qwt_plot_shapeitem.h [code]
 
file  qwt_plot_spectrocurve.cpp
 
file  qwt_plot_spectrocurve.h [code]
 
file  qwt_plot_spectrogram.cpp
 
file  qwt_plot_spectrogram.h [code]
 
file  qwt_plot_svgitem.cpp
 
file  qwt_plot_svgitem.h [code]
 
file  qwt_plot_textlabel.cpp
 
file  qwt_plot_textlabel.h [code]
 
file  qwt_plot_tradingcurve.cpp
 
file  qwt_plot_tradingcurve.h [code]
 
file  qwt_plot_xml.cpp
 
file  qwt_plot_zoneitem.cpp
 
file  qwt_plot_zoneitem.h [code]
 
file  qwt_plot_zoomer.cpp
 
file  qwt_plot_zoomer.h [code]
 
file  qwt_point_3d.cpp
 
file  qwt_point_3d.h [code]
 
file  qwt_point_data.cpp
 
file  qwt_point_data.h [code]
 
file  qwt_point_mapper.cpp
 
file  qwt_point_mapper.h [code]
 
file  qwt_point_polar.cpp
 
file  qwt_point_polar.h [code]
 
file  qwt_raster_data.cpp
 
file  qwt_raster_data.h [code]
 
file  qwt_round_scale_draw.cpp
 
file  qwt_round_scale_draw.h [code]
 
file  qwt_samples.h [code]
 
file  qwt_sampling_thread.cpp
 
file  qwt_sampling_thread.h [code]
 
file  qwt_scale_div.cpp
 
file  qwt_scale_div.h [code]
 
file  qwt_scale_draw.cpp
 
file  qwt_scale_draw.h [code]
 
file  qwt_scale_engine.cpp
 
file  qwt_scale_engine.h [code]
 
file  qwt_scale_map.cpp
 
file  qwt_scale_map.h [code]
 
file  qwt_scale_widget.cpp
 
file  qwt_scale_widget.h [code]
 
file  qwt_series_data.cpp
 
file  qwt_series_data.h [code]
 
file  qwt_series_store.h [code]
 
file  qwt_slider.cpp
 
file  qwt_slider.h [code]
 
file  qwt_spline.cpp
 
file  qwt_spline.h [code]
 
file  qwt_symbol.cpp
 
file  qwt_symbol.h [code]
 
file  qwt_system_clock.cpp
 
file  qwt_system_clock.h [code]
 
file  qwt_text.cpp
 
file  qwt_text.h [code]
 
file  qwt_text_engine.cpp
 
file  qwt_text_engine.h [code]
 
file  qwt_text_label.cpp
 
file  qwt_text_label.h [code]
 
file  qwt_thermo.cpp
 
file  qwt_thermo.h [code]
 
file  qwt_transform.cpp
 
file  qwt_transform.h [code]
 
file  qwt_wheel.cpp
 
file  qwt_wheel.h [code]
 
file  qwt_widget_overlay.cpp
 
file  qwt_widget_overlay.h [code]
 
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/dir_9ccb36e974cdad92d68e40b0bc8a6a19_dep.map b/ThirdParty/Qwt/doc/html/dir_9ccb36e974cdad92d68e40b0bc8a6a19_dep.map new file mode 100644 index 0000000000..c5faacd70a --- /dev/null +++ b/ThirdParty/Qwt/doc/html/dir_9ccb36e974cdad92d68e40b0bc8a6a19_dep.map @@ -0,0 +1,3 @@ + + + diff --git a/ThirdParty/Qwt/doc/html/dir_9ccb36e974cdad92d68e40b0bc8a6a19_dep.md5 b/ThirdParty/Qwt/doc/html/dir_9ccb36e974cdad92d68e40b0bc8a6a19_dep.md5 new file mode 100644 index 0000000000..70740e8fe0 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/dir_9ccb36e974cdad92d68e40b0bc8a6a19_dep.md5 @@ -0,0 +1 @@ +fe215eb9996da9204dd3debb91f704d7 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/dir_9ccb36e974cdad92d68e40b0bc8a6a19_dep.png b/ThirdParty/Qwt/doc/html/dir_9ccb36e974cdad92d68e40b0bc8a6a19_dep.png new file mode 100644 index 0000000000..3f81f7b7d9 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/dir_9ccb36e974cdad92d68e40b0bc8a6a19_dep.png differ diff --git a/ThirdParty/Qwt/doc/html/dir_d71481910ae6010efd2d807d0acbed8c.html b/ThirdParty/Qwt/doc/html/dir_d71481910ae6010efd2d807d0acbed8c.html new file mode 100644 index 0000000000..7a17eb675a --- /dev/null +++ b/ThirdParty/Qwt/doc/html/dir_d71481910ae6010efd2d807d0acbed8c.html @@ -0,0 +1,106 @@ + + + + + + +Qwt User's Guide: textengines Directory Reference + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
textengines Directory Reference
+
+
+
+Directory dependency graph for textengines:
+
+
textengines
+ + +
+ + + + +

+Directories

directory  mathml
 
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/dir_d71481910ae6010efd2d807d0acbed8c_dep.map b/ThirdParty/Qwt/doc/html/dir_d71481910ae6010efd2d807d0acbed8c_dep.map new file mode 100644 index 0000000000..16b139bcac --- /dev/null +++ b/ThirdParty/Qwt/doc/html/dir_d71481910ae6010efd2d807d0acbed8c_dep.map @@ -0,0 +1,4 @@ + + + + diff --git a/ThirdParty/Qwt/doc/html/dir_d71481910ae6010efd2d807d0acbed8c_dep.md5 b/ThirdParty/Qwt/doc/html/dir_d71481910ae6010efd2d807d0acbed8c_dep.md5 new file mode 100644 index 0000000000..c18cb48183 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/dir_d71481910ae6010efd2d807d0acbed8c_dep.md5 @@ -0,0 +1 @@ +9e41c198a9df784d6315bbd19f2f4867 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/dir_d71481910ae6010efd2d807d0acbed8c_dep.png b/ThirdParty/Qwt/doc/html/dir_d71481910ae6010efd2d807d0acbed8c_dep.png new file mode 100644 index 0000000000..e09de43333 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/dir_d71481910ae6010efd2d807d0acbed8c_dep.png differ diff --git a/ThirdParty/Qwt/doc/html/doxygen.css b/ThirdParty/Qwt/doc/html/doxygen.css new file mode 100644 index 0000000000..dabaff2fd8 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/doxygen.css @@ -0,0 +1,1184 @@ +/* The standard CSS for doxygen 1.8.3.1 */ + +body, table, div, p, dl { + font: 400 14px/19px Roboto,sans-serif; +} + +/* @group Heading Levels */ + +h1.groupheader { + font-size: 150%; +} + +.title { + font-size: 150%; + font-weight: bold; + margin: 10px 2px; +} + +h2.groupheader { + border-bottom: 1px solid #879ECB; + color: #354C7B; + font-size: 150%; + font-weight: normal; + margin-top: 1.75em; + padding-top: 8px; + padding-bottom: 4px; + width: 100%; +} + +h3.groupheader { + font-size: 100%; +} + +h1, h2, h3, h4, h5, h6 { + -webkit-transition: text-shadow 0.5s linear; + -moz-transition: text-shadow 0.5s linear; + -ms-transition: text-shadow 0.5s linear; + -o-transition: text-shadow 0.5s linear; + transition: text-shadow 0.5s linear; + margin-right: 15px; +} + +h1.glow, h2.glow, h3.glow, h4.glow, h5.glow, h6.glow { + text-shadow: 0 0 15px cyan; +} + +dt { + font-weight: bold; +} + +div.multicol { + -moz-column-gap: 1em; + -webkit-column-gap: 1em; + -moz-column-count: 3; + -webkit-column-count: 3; +} + +p.startli, p.startdd, p.starttd { + margin-top: 2px; +} + +p.endli { + margin-bottom: 0px; +} + +p.enddd { + margin-bottom: 4px; +} + +p.endtd { + margin-bottom: 2px; +} + +/* @end */ + +caption { + font-weight: bold; +} + +span.legend { + font-size: 70%; + text-align: center; +} + +h3.version { + font-size: 90%; + text-align: center; +} + +div.qindex, div.navtab{ + background-color: #EBEFF6; + border: 1px solid #A3B4D7; + text-align: center; +} + +div.qindex, div.navpath { + width: 100%; + line-height: 140%; +} + +div.navtab { + margin-right: 15px; +} + +/* @group Link Styling */ + +a { + color: #3D578C; + font-weight: normal; + text-decoration: none; +} + +.contents a:visited { + color: #4665A2; +} + +a:hover { + text-decoration: underline; +} + +a.qindex { + font-weight: bold; +} + +a.qindexHL { + font-weight: bold; + background-color: #9CAFD4; + color: #ffffff; + border: 1px double #869DCA; +} + +.contents a.qindexHL:visited { + color: #ffffff; +} + +a.el { + font-weight: bold; +} + +a.elRef { +} + +a.code, a.code:visited { + color: #4665A2; +} + +a.codeRef, a.codeRef:visited { + color: #4665A2; +} + +/* @end */ + +dl.el { + margin-left: -1cm; +} + +pre.fragment { + border: 1px solid #C4CFE5; + background-color: #FBFCFD; + padding: 4px 6px; + margin: 4px 8px 4px 2px; + overflow: auto; + word-wrap: break-word; + font-size: 9pt; + line-height: 125%; + font-family: monospace, fixed; + font-size: 105%; +} + +div.fragment { + padding: 4px; + margin: 4px; + background-color: #FBFCFD; + border: 1px solid #C4CFE5; +} + +div.line { + font-family: monospace, fixed; + font-size: 13px; + min-height: 13px; + line-height: 1.0; + text-wrap: unrestricted; + white-space: -moz-pre-wrap; /* Moz */ + white-space: -pre-wrap; /* Opera 4-6 */ + white-space: -o-pre-wrap; /* Opera 7 */ + white-space: pre-wrap; /* CSS3 */ + word-wrap: break-word; /* IE 5.5+ */ + text-indent: -53px; + padding-left: 53px; + padding-bottom: 0px; + margin: 0px; + -webkit-transition-property: background-color, box-shadow; + -webkit-transition-duration: 0.5s; + -moz-transition-property: background-color, box-shadow; + -moz-transition-duration: 0.5s; + -ms-transition-property: background-color, box-shadow; + -ms-transition-duration: 0.5s; + -o-transition-property: background-color, box-shadow; + -o-transition-duration: 0.5s; + transition-property: background-color, box-shadow; + transition-duration: 0.5s; +} + +div.line.glow { + background-color: cyan; + box-shadow: 0 0 10px cyan; +} + + +span.lineno { + padding-right: 4px; + text-align: right; + border-right: 2px solid #0F0; + background-color: #E8E8E8; + white-space: pre; +} +span.lineno a { + background-color: #D8D8D8; +} + +span.lineno a:hover { + background-color: #C8C8C8; +} + +div.ah { + background-color: black; + font-weight: bold; + color: #ffffff; + margin-bottom: 3px; + margin-top: 3px; + padding: 0.2em; + border: solid thin #333; + border-radius: 0.5em; + -webkit-border-radius: .5em; + -moz-border-radius: .5em; + box-shadow: 2px 2px 3px #999; + -webkit-box-shadow: 2px 2px 3px #999; + -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px; + background-image: -webkit-gradient(linear, left top, left bottom, from(#eee), to(#000),color-stop(0.3, #444)); + background-image: -moz-linear-gradient(center top, #eee 0%, #444 40%, #000); +} + +div.groupHeader { + margin-left: 16px; + margin-top: 12px; + font-weight: bold; +} + +div.groupText { + margin-left: 16px; + font-style: italic; +} + +body { + background-color: white; + color: black; + margin: 0; +} + +div.contents { + margin-top: 10px; + margin-left: 12px; + margin-right: 8px; +} + +td.indexkey { + background-color: #EBEFF6; + font-weight: bold; + border: 1px solid #C4CFE5; + margin: 2px 0px 2px 0; + padding: 2px 10px; + white-space: nowrap; + vertical-align: top; +} + +td.indexvalue { + background-color: #EBEFF6; + border: 1px solid #C4CFE5; + padding: 2px 10px; + margin: 2px 0px; +} + +tr.memlist { + background-color: #EEF1F7; +} + +p.formulaDsp { + text-align: center; +} + +img.formulaDsp { + +} + +img.formulaInl { + vertical-align: middle; +} + +div.center { + text-align: center; + margin-top: 0px; + margin-bottom: 0px; + padding: 0px; +} + +div.center img { + border: 0px; +} + +address.footer { + text-align: right; + padding-right: 12px; +} + +img.footer { + border: 0px; + vertical-align: middle; +} + +/* @group Code Colorization */ + +span.keyword { + color: #008000 +} + +span.keywordtype { + color: #604020 +} + +span.keywordflow { + color: #e08000 +} + +span.comment { + color: #800000 +} + +span.preprocessor { + color: #806020 +} + +span.stringliteral { + color: #002080 +} + +span.charliteral { + color: #008080 +} + +span.vhdldigit { + color: #ff00ff +} + +span.vhdlchar { + color: #000000 +} + +span.vhdlkeyword { + color: #700070 +} + +span.vhdllogic { + color: #ff0000 +} + +blockquote { + background-color: #F7F8FB; + border-left: 2px solid #9CAFD4; + margin: 0 24px 0 4px; + padding: 0 12px 0 16px; +} + +/* @end */ + +/* +.search { + color: #003399; + font-weight: bold; +} + +form.search { + margin-bottom: 0px; + margin-top: 0px; +} + +input.search { + font-size: 75%; + color: #000080; + font-weight: normal; + background-color: #e8eef2; +} +*/ + +td.tiny { + font-size: 75%; +} + +.dirtab { + padding: 4px; + border-collapse: collapse; + border: 1px solid #A3B4D7; +} + +th.dirtab { + background: #EBEFF6; + font-weight: bold; +} + +hr { + height: 0px; + border: none; + border-top: 1px solid #4A6AAA; +} + +hr.footer { + height: 1px; +} + +/* @group Member Descriptions */ + +table.memberdecls { + border-spacing: 0px; + padding: 0px; +} + +.memberdecls td, .fieldtable tr { + -webkit-transition-property: background-color, box-shadow; + -webkit-transition-duration: 0.5s; + -moz-transition-property: background-color, box-shadow; + -moz-transition-duration: 0.5s; + -ms-transition-property: background-color, box-shadow; + -ms-transition-duration: 0.5s; + -o-transition-property: background-color, box-shadow; + -o-transition-duration: 0.5s; + transition-property: background-color, box-shadow; + transition-duration: 0.5s; +} + +.memberdecls td.glow, .fieldtable tr.glow { + background-color: cyan; + box-shadow: 0 0 15px cyan; +} + +.mdescLeft, .mdescRight, +.memItemLeft, .memItemRight, +.memTemplItemLeft, .memTemplItemRight, .memTemplParams { + background-color: #F9FAFC; + border: none; + margin: 4px; + padding: 1px 0 0 8px; +} + +.mdescLeft, .mdescRight { + padding: 0px 8px 4px 8px; + color: #555; +} + +.memSeparator { + border-bottom: 1px solid #DEE4F0; + line-height: 1px; + margin: 0px; + padding: 0px; +} + +.memItemLeft, .memTemplItemLeft { + white-space: nowrap; +} + +.memItemRight { + width: 100%; +} + +.memTemplParams { + color: #4665A2; + white-space: nowrap; + font-size: 80%; +} + +/* @end */ + +/* @group Member Details */ + +/* Styles for detailed member documentation */ + +.memtemplate { + font-size: 80%; + color: #4665A2; + font-weight: normal; + margin-left: 9px; +} + +.memnav { + background-color: #EBEFF6; + border: 1px solid #A3B4D7; + text-align: center; + margin: 2px; + margin-right: 15px; + padding: 2px; +} + +.mempage { + width: 100%; +} + +.memitem { + padding: 0; + margin-bottom: 10px; + margin-right: 5px; + -webkit-transition: box-shadow 0.5s linear; + -moz-transition: box-shadow 0.5s linear; + -ms-transition: box-shadow 0.5s linear; + -o-transition: box-shadow 0.5s linear; + transition: box-shadow 0.5s linear; + display: table !important; + width: 100%; +} + +.memitem.glow { + box-shadow: 0 0 15px cyan; +} + +.memname { + font-weight: bold; + margin-left: 6px; +} + +.memname td { + vertical-align: bottom; +} + +.memproto, dl.reflist dt { + border-top: 1px solid #A8B8D9; + border-left: 1px solid #A8B8D9; + border-right: 1px solid #A8B8D9; + padding: 6px 0px 6px 0px; + color: #253555; + font-weight: bold; + text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); + background-image:url('nav_f.png'); + background-repeat:repeat-x; + background-color: #E2E8F2; + /* opera specific markup */ + box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + border-top-right-radius: 4px; + border-top-left-radius: 4px; + /* firefox specific markup */ + -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px; + -moz-border-radius-topright: 4px; + -moz-border-radius-topleft: 4px; + /* webkit specific markup */ + -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + -webkit-border-top-right-radius: 4px; + -webkit-border-top-left-radius: 4px; + +} + +.memdoc, dl.reflist dd { + border-bottom: 1px solid #A8B8D9; + border-left: 1px solid #A8B8D9; + border-right: 1px solid #A8B8D9; + padding: 6px 10px 2px 10px; + background-color: #FBFCFD; + border-top-width: 0; + background-image:url('nav_g.png'); + background-repeat:repeat-x; + background-color: #FFFFFF; + /* opera specific markup */ + border-bottom-left-radius: 4px; + border-bottom-right-radius: 4px; + box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + /* firefox specific markup */ + -moz-border-radius-bottomleft: 4px; + -moz-border-radius-bottomright: 4px; + -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px; + /* webkit specific markup */ + -webkit-border-bottom-left-radius: 4px; + -webkit-border-bottom-right-radius: 4px; + -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); +} + +dl.reflist dt { + padding: 5px; +} + +dl.reflist dd { + margin: 0px 0px 10px 0px; + padding: 5px; +} + +.paramkey { + text-align: right; +} + +.paramtype { + white-space: nowrap; +} + +.paramname { + color: #602020; + white-space: nowrap; +} +.paramname em { + font-style: normal; +} +.paramname code { + line-height: 14px; +} + +.params, .retval, .exception, .tparams { + margin-left: 0px; + padding-left: 0px; +} + +.params .paramname, .retval .paramname { + font-weight: bold; + vertical-align: top; +} + +.params .paramtype { + font-style: italic; + vertical-align: top; +} + +.params .paramdir { + font-family: "courier new",courier,monospace; + vertical-align: top; +} + +table.mlabels { + border-spacing: 0px; +} + +td.mlabels-left { + width: 100%; + padding: 0px; +} + +td.mlabels-right { + vertical-align: bottom; + padding: 0px; + white-space: nowrap; +} + +span.mlabels { + margin-left: 8px; +} + +span.mlabel { + background-color: #728DC1; + border-top:1px solid #5373B4; + border-left:1px solid #5373B4; + border-right:1px solid #C4CFE5; + border-bottom:1px solid #C4CFE5; + text-shadow: none; + color: white; + margin-right: 4px; + padding: 2px 3px; + border-radius: 3px; + font-size: 7pt; + white-space: nowrap; + vertical-align: middle; +} + + + +/* @end */ + +/* these are for tree view when not used as main index */ + +div.directory { + margin: 10px 0px; + border-top: 1px solid #A8B8D9; + border-bottom: 1px solid #A8B8D9; + width: 100%; +} + +.directory table { + border-collapse:collapse; +} + +.directory td { + margin: 0px; + padding: 0px; + vertical-align: top; +} + +.directory td.entry { + white-space: nowrap; + padding-right: 6px; +} + +.directory td.entry a { + outline:none; +} + +.directory td.entry a img { + border: none; +} + +.directory td.desc { + width: 100%; + padding-left: 6px; + padding-right: 6px; + padding-top: 3px; + border-left: 1px solid rgba(0,0,0,0.05); +} + +.directory tr.even { + padding-left: 6px; + background-color: #F7F8FB; +} + +.directory img { + vertical-align: -30%; +} + +.directory .levels { + white-space: nowrap; + width: 100%; + text-align: right; + font-size: 9pt; +} + +.directory .levels span { + cursor: pointer; + padding-left: 2px; + padding-right: 2px; + color: #3D578C; +} + +div.dynheader { + margin-top: 8px; + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +address { + font-style: normal; + color: #2A3D61; +} + +table.doxtable { + border-collapse:collapse; + margin-top: 4px; + margin-bottom: 4px; +} + +table.doxtable td, table.doxtable th { + border: 1px solid #2D4068; + padding: 3px 7px 2px; +} + +table.doxtable th { + background-color: #374F7F; + color: #FFFFFF; + font-size: 110%; + padding-bottom: 4px; + padding-top: 5px; +} + +table.fieldtable { + /*width: 100%;*/ + margin-bottom: 10px; + border: 1px solid #A8B8D9; + border-spacing: 0px; + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + border-radius: 4px; + -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px; + -webkit-box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15); + box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15); +} + +.fieldtable td, .fieldtable th { + padding: 3px 7px 2px; +} + +.fieldtable td.fieldtype, .fieldtable td.fieldname { + white-space: nowrap; + border-right: 1px solid #A8B8D9; + border-bottom: 1px solid #A8B8D9; + vertical-align: top; +} + +.fieldtable td.fieldname { + padding-top: 5px; +} + +.fieldtable td.fielddoc { + border-bottom: 1px solid #A8B8D9; + /*width: 100%;*/ +} + +.fieldtable td.fielddoc p:first-child { + margin-top: 2px; +} + +.fieldtable td.fielddoc p:last-child { + margin-bottom: 2px; +} + +.fieldtable tr:last-child td { + border-bottom: none; +} + +.fieldtable th { + background-image:url('nav_f.png'); + background-repeat:repeat-x; + background-color: #E2E8F2; + font-size: 90%; + color: #253555; + padding-bottom: 4px; + padding-top: 5px; + text-align:left; + -moz-border-radius-topleft: 4px; + -moz-border-radius-topright: 4px; + -webkit-border-top-left-radius: 4px; + -webkit-border-top-right-radius: 4px; + border-top-left-radius: 4px; + border-top-right-radius: 4px; + border-bottom: 1px solid #A8B8D9; +} + + +.tabsearch { + top: 0px; + left: 10px; + height: 36px; + background-image: url('tab_b.png'); + z-index: 101; + overflow: hidden; + font-size: 13px; +} + +.navpath ul +{ + font-size: 11px; + background-image:url('tab_b.png'); + background-repeat:repeat-x; + background-position: 0 -5px; + height:30px; + line-height:30px; + color:#8AA0CC; + border:solid 1px #C2CDE4; + overflow:hidden; + margin:0px; + padding:0px; +} + +.navpath li +{ + list-style-type:none; + float:left; + padding-left:10px; + padding-right:15px; + background-image:url('bc_s.png'); + background-repeat:no-repeat; + background-position:right; + color:#364D7C; +} + +.navpath li.navelem a +{ + height:32px; + display:block; + text-decoration: none; + outline: none; + color: #283A5D; + font-family: 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif; + text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); + text-decoration: none; +} + +.navpath li.navelem a:hover +{ + color:#6884BD; +} + +.navpath li.footer +{ + list-style-type:none; + float:right; + padding-left:10px; + padding-right:15px; + background-image:none; + background-repeat:no-repeat; + background-position:right; + color:#364D7C; + font-size: 8pt; +} + + +div.summary +{ + float: right; + font-size: 8pt; + padding-right: 5px; + width: 50%; + text-align: right; +} + +div.summary a +{ + white-space: nowrap; +} + +div.ingroups +{ + font-size: 8pt; + width: 50%; + text-align: left; +} + +div.ingroups a +{ + white-space: nowrap; +} + +div.header +{ + background-image:url('nav_h.png'); + background-repeat:repeat-x; + background-color: #F9FAFC; + margin: 0px; + border-bottom: 1px solid #C4CFE5; +} + +div.headertitle +{ + padding: 5px 5px 5px 10px; +} + +dl +{ + padding: 0 0 0 10px; +} + +/* dl.note, dl.warning, dl.attention, dl.pre, dl.post, dl.invariant, dl.deprecated, dl.todo, dl.test, dl.bug */ +dl.section +{ + margin-left: 0px; + padding-left: 0px; +} + +dl.note +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #D0C000; +} + +dl.warning, dl.attention +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #FF0000; +} + +dl.pre, dl.post, dl.invariant +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #00D000; +} + +dl.deprecated +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #505050; +} + +dl.todo +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #00C0E0; +} + +dl.test +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #3030E0; +} + +dl.bug +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #C08050; +} + +dl.section dd { + margin-bottom: 6px; +} + + +#projectlogo +{ + text-align: center; + vertical-align: bottom; + border-collapse: separate; +} + +#projectlogo img +{ + border: 0px none; +} + +#projectname +{ + font: 300% Tahoma, Arial,sans-serif; + margin: 0px; + padding: 2px 0px; +} + +#projectbrief +{ + font: 120% Tahoma, Arial,sans-serif; + margin: 0px; + padding: 0px; +} + +#projectnumber +{ + font: 50% Tahoma, Arial,sans-serif; + margin: 0px; + padding: 0px; +} + +#titlearea +{ + padding: 0px; + margin: 0px; + width: 100%; + border-bottom: 1px solid #5373B4; +} + +.image +{ + text-align: center; +} + +.dotgraph +{ + text-align: center; +} + +.mscgraph +{ + text-align: center; +} + +.caption +{ + font-weight: bold; +} + +div.zoom +{ + border: 1px solid #90A5CE; +} + +dl.citelist { + margin-bottom:50px; +} + +dl.citelist dt { + color:#334975; + float:left; + font-weight:bold; + margin-right:10px; + padding:5px; +} + +dl.citelist dd { + margin:2px 0; + padding:5px 0; +} + +div.toc { + padding: 14px 25px; + background-color: #F4F6FA; + border: 1px solid #D8DFEE; + border-radius: 7px 7px 7px 7px; + float: right; + height: auto; + margin: 0 20px 10px 10px; + width: 200px; +} + +div.toc li { + background: url("bdwn.png") no-repeat scroll 0 5px transparent; + font: 10px/1.2 Verdana,DejaVu Sans,Geneva,sans-serif; + margin-top: 5px; + padding-left: 10px; + padding-top: 2px; +} + +div.toc h3 { + font: bold 12px/1.2 Arial,FreeSans,sans-serif; + color: #4665A2; + border-bottom: 0 none; + margin: 0; +} + +div.toc ul { + list-style: none outside none; + border: medium none; + padding: 0px; +} + +div.toc li.level1 { + margin-left: 0px; +} + +div.toc li.level2 { + margin-left: 15px; +} + +div.toc li.level3 { + margin-left: 30px; +} + +div.toc li.level4 { + margin-left: 45px; +} + +.inherit_header { + font-weight: bold; + color: gray; + cursor: pointer; + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.inherit_header td { + padding: 6px 0px 2px 5px; +} + +.inherit { + display: none; +} + +tr.heading h2 { + margin-top: 12px; + margin-bottom: 4px; +} + +@media print +{ + #top { display: none; } + #side-nav { display: none; } + #nav-path { display: none; } + body { overflow:visible; } + h1, h2, h3, h4, h5, h6 { page-break-after: avoid; } + .summary { display: none; } + .memitem { page-break-inside: avoid; } + #doc-content + { + margin-left:0 !important; + height:auto !important; + width:auto !important; + overflow:inherit; + display:inline; + } +} + diff --git a/ThirdParty/Qwt/doc/html/doxygen.png b/ThirdParty/Qwt/doc/html/doxygen.png new file mode 100644 index 0000000000..3ff17d807f Binary files /dev/null and b/ThirdParty/Qwt/doc/html/doxygen.png differ diff --git a/ThirdParty/Qwt/doc/html/dynsections.js b/ThirdParty/Qwt/doc/html/dynsections.js new file mode 100644 index 0000000000..ed092c7f63 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/dynsections.js @@ -0,0 +1,97 @@ +function toggleVisibility(linkObj) +{ + var base = $(linkObj).attr('id'); + var summary = $('#'+base+'-summary'); + var content = $('#'+base+'-content'); + var trigger = $('#'+base+'-trigger'); + var src=$(trigger).attr('src'); + if (content.is(':visible')===true) { + content.hide(); + summary.show(); + $(linkObj).addClass('closed').removeClass('opened'); + $(trigger).attr('src',src.substring(0,src.length-8)+'closed.png'); + } else { + content.show(); + summary.hide(); + $(linkObj).removeClass('closed').addClass('opened'); + $(trigger).attr('src',src.substring(0,src.length-10)+'open.png'); + } + return false; +} + +function updateStripes() +{ + $('table.directory tr'). + removeClass('even').filter(':visible:even').addClass('even'); +} +function toggleLevel(level) +{ + $('table.directory tr').each(function(){ + var l = this.id.split('_').length-1; + var i = $('#img'+this.id.substring(3)); + var a = $('#arr'+this.id.substring(3)); + if (l + + + + + +Qwt User's Guide: Class Members + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + +
+ + + + +
+ +
+ +
+
Here is a list of all documented class members with links to the class documentation for each member:
+ +

- a -

+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/functions_0x62.html b/ThirdParty/Qwt/doc/html/functions_0x62.html new file mode 100644 index 0000000000..1f80c61992 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/functions_0x62.html @@ -0,0 +1,316 @@ + + + + + + +Qwt User's Guide: Class Members + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + +
+ + + + +
+ +
+ +
+
Here is a list of all documented class members with links to the class documentation for each member:
+ +

- b -

+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/functions_0x63.html b/ThirdParty/Qwt/doc/html/functions_0x63.html new file mode 100644 index 0000000000..6b4affb462 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/functions_0x63.html @@ -0,0 +1,433 @@ + + + + + + +Qwt User's Guide: Class Members + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + +
+ + + + +
+ +
+ +
+
Here is a list of all documented class members with links to the class documentation for each member:
+ +

- c -

+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/functions_0x64.html b/ThirdParty/Qwt/doc/html/functions_0x64.html new file mode 100644 index 0000000000..339eb0d662 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/functions_0x64.html @@ -0,0 +1,583 @@ + + + + + + +Qwt User's Guide: Class Members + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + +
+ + + + +
+ +
+ +
+
Here is a list of all documented class members with links to the class documentation for each member:
+ +

- d -

+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/functions_0x65.html b/ThirdParty/Qwt/doc/html/functions_0x65.html new file mode 100644 index 0000000000..e3ac24b148 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/functions_0x65.html @@ -0,0 +1,242 @@ + + + + + + +Qwt User's Guide: Class Members + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + +
+ + + + +
+ +
+ +
+
Here is a list of all documented class members with links to the class documentation for each member:
+ +

- e -

+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/functions_0x66.html b/ThirdParty/Qwt/doc/html/functions_0x66.html new file mode 100644 index 0000000000..2f01d0cde6 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/functions_0x66.html @@ -0,0 +1,252 @@ + + + + + + +Qwt User's Guide: Class Members + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + +
+ + + + +
+ +
+ +
+
Here is a list of all documented class members with links to the class documentation for each member:
+ +

- f -

+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/functions_0x67.html b/ThirdParty/Qwt/doc/html/functions_0x67.html new file mode 100644 index 0000000000..166a03b430 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/functions_0x67.html @@ -0,0 +1,186 @@ + + + + + + +Qwt User's Guide: Class Members + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + +
+ + + + +
+ +
+ +
+
Here is a list of all documented class members with links to the class documentation for each member:
+ +

- g -

+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/functions_0x68.html b/ThirdParty/Qwt/doc/html/functions_0x68.html new file mode 100644 index 0000000000..10bc83ed90 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/functions_0x68.html @@ -0,0 +1,212 @@ + + + + + + +Qwt User's Guide: Class Members + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + +
+ + + + +
+ +
+ +
+
Here is a list of all documented class members with links to the class documentation for each member:
+ +

- h -

+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/functions_0x69.html b/ThirdParty/Qwt/doc/html/functions_0x69.html new file mode 100644 index 0000000000..253ff50aa5 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/functions_0x69.html @@ -0,0 +1,457 @@ + + + + + + +Qwt User's Guide: Class Members + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + +
+ + + + +
+ +
+ +
+
Here is a list of all documented class members with links to the class documentation for each member:
+ +

- i -

+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/functions_0x6a.html b/ThirdParty/Qwt/doc/html/functions_0x6a.html new file mode 100644 index 0000000000..940cc5c8ab --- /dev/null +++ b/ThirdParty/Qwt/doc/html/functions_0x6a.html @@ -0,0 +1,140 @@ + + + + + + +Qwt User's Guide: Class Members + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + +
+ + + + +
+ +
+ +
+
Here is a list of all documented class members with links to the class documentation for each member:
+ +

- j -

+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/functions_0x6b.html b/ThirdParty/Qwt/doc/html/functions_0x6b.html new file mode 100644 index 0000000000..a8f80aa2a9 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/functions_0x6b.html @@ -0,0 +1,217 @@ + + + + + + +Qwt User's Guide: Class Members + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + +
+ + + + +
+ +
+ +
+
Here is a list of all documented class members with links to the class documentation for each member:
+ +

- k -

+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/functions_0x6c.html b/ThirdParty/Qwt/doc/html/functions_0x6c.html new file mode 100644 index 0000000000..03caf1f6bc --- /dev/null +++ b/ThirdParty/Qwt/doc/html/functions_0x6c.html @@ -0,0 +1,391 @@ + + + + + + +Qwt User's Guide: Class Members + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + +
+ + + + +
+ +
+ +
+
Here is a list of all documented class members with links to the class documentation for each member:
+ +

- l -

+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/functions_0x6d.html b/ThirdParty/Qwt/doc/html/functions_0x6d.html new file mode 100644 index 0000000000..c74e1f8cf4 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/functions_0x6d.html @@ -0,0 +1,416 @@ + + + + + + +Qwt User's Guide: Class Members + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + +
+ + + + +
+ +
+ +
+
Here is a list of all documented class members with links to the class documentation for each member:
+ +

- m -

+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/functions_0x6e.html b/ThirdParty/Qwt/doc/html/functions_0x6e.html new file mode 100644 index 0000000000..e9454ef200 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/functions_0x6e.html @@ -0,0 +1,241 @@ + + + + + + +Qwt User's Guide: Class Members + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + +
+ + + + +
+ +
+ +
+
Here is a list of all documented class members with links to the class documentation for each member:
+ +

- n -

+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/functions_0x6f.html b/ThirdParty/Qwt/doc/html/functions_0x6f.html new file mode 100644 index 0000000000..115828a8af --- /dev/null +++ b/ThirdParty/Qwt/doc/html/functions_0x6f.html @@ -0,0 +1,230 @@ + + + + + + +Qwt User's Guide: Class Members + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + +
+ + + + +
+ +
+ +
+
Here is a list of all documented class members with links to the class documentation for each member:
+ +

- o -

+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/functions_0x70.html b/ThirdParty/Qwt/doc/html/functions_0x70.html new file mode 100644 index 0000000000..0b5fa0c53d --- /dev/null +++ b/ThirdParty/Qwt/doc/html/functions_0x70.html @@ -0,0 +1,491 @@ + + + + + + +Qwt User's Guide: Class Members + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + +
+ + + + +
+ +
+ +
+
Here is a list of all documented class members with links to the class documentation for each member:
+ +

- p -

+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/functions_0x72.html b/ThirdParty/Qwt/doc/html/functions_0x72.html new file mode 100644 index 0000000000..39b95834be --- /dev/null +++ b/ThirdParty/Qwt/doc/html/functions_0x72.html @@ -0,0 +1,478 @@ + + + + + + +Qwt User's Guide: Class Members + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + +
+ + + + +
+ +
+ +
+
Here is a list of all documented class members with links to the class documentation for each member:
+ +

- r -

+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/functions_0x73.html b/ThirdParty/Qwt/doc/html/functions_0x73.html new file mode 100644 index 0000000000..a2ec37c5dd --- /dev/null +++ b/ThirdParty/Qwt/doc/html/functions_0x73.html @@ -0,0 +1,1592 @@ + + + + + + +Qwt User's Guide: Class Members + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + +
+ + + + +
+ +
+ +
+
Here is a list of all documented class members with links to the class documentation for each member:
+ +

- s -

+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/functions_0x74.html b/ThirdParty/Qwt/doc/html/functions_0x74.html new file mode 100644 index 0000000000..c70d460c45 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/functions_0x74.html @@ -0,0 +1,435 @@ + + + + + + +Qwt User's Guide: Class Members + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + +
+ + + + +
+ +
+ +
+
Here is a list of all documented class members with links to the class documentation for each member:
+ +

- t -

+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/functions_0x75.html b/ThirdParty/Qwt/doc/html/functions_0x75.html new file mode 100644 index 0000000000..1503ccedd3 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/functions_0x75.html @@ -0,0 +1,222 @@ + + + + + + +Qwt User's Guide: Class Members + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + +
+ + + + +
+ +
+ +
+
Here is a list of all documented class members with links to the class documentation for each member:
+ +

- u -

+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/functions_0x76.html b/ThirdParty/Qwt/doc/html/functions_0x76.html new file mode 100644 index 0000000000..eddc2e6fab --- /dev/null +++ b/ThirdParty/Qwt/doc/html/functions_0x76.html @@ -0,0 +1,183 @@ + + + + + + +Qwt User's Guide: Class Members + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + +
+ + + + +
+ +
+ +
+
Here is a list of all documented class members with links to the class documentation for each member:
+ +

- v -

+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/functions_0x77.html b/ThirdParty/Qwt/doc/html/functions_0x77.html new file mode 100644 index 0000000000..a90d3649f3 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/functions_0x77.html @@ -0,0 +1,243 @@ + + + + + + +Qwt User's Guide: Class Members + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + +
+ + + + +
+ +
+ +
+
Here is a list of all documented class members with links to the class documentation for each member:
+ +

- w -

+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/functions_0x78.html b/ThirdParty/Qwt/doc/html/functions_0x78.html new file mode 100644 index 0000000000..c8d2d3fda9 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/functions_0x78.html @@ -0,0 +1,170 @@ + + + + + + +Qwt User's Guide: Class Members + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + +
+ + + + +
+ +
+ +
+
Here is a list of all documented class members with links to the class documentation for each member:
+ +

- x -

+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/functions_0x79.html b/ThirdParty/Qwt/doc/html/functions_0x79.html new file mode 100644 index 0000000000..9db9e7d736 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/functions_0x79.html @@ -0,0 +1,170 @@ + + + + + + +Qwt User's Guide: Class Members + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + +
+ + + + +
+ +
+ +
+
Here is a list of all documented class members with links to the class documentation for each member:
+ +

- y -

+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/functions_0x7a.html b/ThirdParty/Qwt/doc/html/functions_0x7a.html new file mode 100644 index 0000000000..39bee03425 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/functions_0x7a.html @@ -0,0 +1,159 @@ + + + + + + +Qwt User's Guide: Class Members + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + +
+ + + + +
+ +
+ +
+
Here is a list of all documented class members with links to the class documentation for each member:
+ +

- z -

+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/functions_0x7e.html b/ThirdParty/Qwt/doc/html/functions_0x7e.html new file mode 100644 index 0000000000..be8de611e2 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/functions_0x7e.html @@ -0,0 +1,428 @@ + + + + + + +Qwt User's Guide: Class Members + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + +
+ + + + +
+ +
+ +
+
Here is a list of all documented class members with links to the class documentation for each member:
+ +

- ~ -

+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/functions_enum.html b/ThirdParty/Qwt/doc/html/functions_enum.html new file mode 100644 index 0000000000..4bfff1d3d9 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/functions_enum.html @@ -0,0 +1,403 @@ + + + + + + +Qwt User's Guide: Class Members - Enumerations + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + +
+ + + + +
+ +
+ +
+  + +

- a -

+ + +

- b -

+ + +

- c -

+ + +

- d -

+ + +

- e -

+ + +

- f -

+ + +

- h -

+ + +

- i -

+ + +

- k -

+ + +

- l -

+ + +

- m -

+ + +

- o -

+ + +

- p -

+ + +

- r -

+ + +

- s -

+ + +

- t -

+ + +

- w -

+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/functions_eval.html b/ThirdParty/Qwt/doc/html/functions_eval.html new file mode 100644 index 0000000000..ca389153eb --- /dev/null +++ b/ThirdParty/Qwt/doc/html/functions_eval.html @@ -0,0 +1,177 @@ + + + + + + +Qwt User's Guide: Class Members - Enumerator + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + +
+ + + + +
+ +
+ +
+  + +

- a -

+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/functions_eval_0x62.html b/ThirdParty/Qwt/doc/html/functions_eval_0x62.html new file mode 100644 index 0000000000..f580cfec62 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/functions_eval_0x62.html @@ -0,0 +1,173 @@ + + + + + + +Qwt User's Guide: Class Members - Enumerator + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + +
+ + + + +
+ +
+ +
+  + +

- b -

+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/functions_eval_0x63.html b/ThirdParty/Qwt/doc/html/functions_eval_0x63.html new file mode 100644 index 0000000000..74e6ddef9a --- /dev/null +++ b/ThirdParty/Qwt/doc/html/functions_eval_0x63.html @@ -0,0 +1,183 @@ + + + + + + +Qwt User's Guide: Class Members - Enumerator + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + +
+ + + + +
+ +
+ +
+  + +

- c -

+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/functions_eval_0x64.html b/ThirdParty/Qwt/doc/html/functions_eval_0x64.html new file mode 100644 index 0000000000..e54ec4cf5f --- /dev/null +++ b/ThirdParty/Qwt/doc/html/functions_eval_0x64.html @@ -0,0 +1,180 @@ + + + + + + +Qwt User's Guide: Class Members - Enumerator + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + +
+ + + + +
+ +
+ +
+  + +

- d -

+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/functions_eval_0x65.html b/ThirdParty/Qwt/doc/html/functions_eval_0x65.html new file mode 100644 index 0000000000..56b5d9b21d --- /dev/null +++ b/ThirdParty/Qwt/doc/html/functions_eval_0x65.html @@ -0,0 +1,162 @@ + + + + + + +Qwt User's Guide: Class Members - Enumerator + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + +
+ + + + +
+ +
+ +
+  + +

- e -

+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/functions_eval_0x66.html b/ThirdParty/Qwt/doc/html/functions_eval_0x66.html new file mode 100644 index 0000000000..b9bcaa0462 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/functions_eval_0x66.html @@ -0,0 +1,171 @@ + + + + + + +Qwt User's Guide: Class Members - Enumerator + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + +
+ + + + +
+ +
+ +
+  + +

- f -

+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/functions_eval_0x67.html b/ThirdParty/Qwt/doc/html/functions_eval_0x67.html new file mode 100644 index 0000000000..1dfe1cf269 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/functions_eval_0x67.html @@ -0,0 +1,141 @@ + + + + + + +Qwt User's Guide: Class Members - Enumerator + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + +
+ + + + +
+ +
+ +
+  + +

- g -

+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/functions_eval_0x68.html b/ThirdParty/Qwt/doc/html/functions_eval_0x68.html new file mode 100644 index 0000000000..25bdbcc8ba --- /dev/null +++ b/ThirdParty/Qwt/doc/html/functions_eval_0x68.html @@ -0,0 +1,154 @@ + + + + + + +Qwt User's Guide: Class Members - Enumerator + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + +
+ + + + +
+ +
+ +
+  + +

- h -

+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/functions_eval_0x69.html b/ThirdParty/Qwt/doc/html/functions_eval_0x69.html new file mode 100644 index 0000000000..63ed666458 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/functions_eval_0x69.html @@ -0,0 +1,193 @@ + + + + + + +Qwt User's Guide: Class Members - Enumerator + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + +
+ + + + +
+ +
+ +
+  + +

- i -

+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/functions_eval_0x6a.html b/ThirdParty/Qwt/doc/html/functions_eval_0x6a.html new file mode 100644 index 0000000000..8910d6a4ce --- /dev/null +++ b/ThirdParty/Qwt/doc/html/functions_eval_0x6a.html @@ -0,0 +1,138 @@ + + + + + + +Qwt User's Guide: Class Members - Enumerator + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + +
+ + + + +
+ +
+ +
+  + +

- j -

+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/functions_eval_0x6b.html b/ThirdParty/Qwt/doc/html/functions_eval_0x6b.html new file mode 100644 index 0000000000..6a794a2ef0 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/functions_eval_0x6b.html @@ -0,0 +1,171 @@ + + + + + + +Qwt User's Guide: Class Members - Enumerator + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + +
+ + + + +
+ +
+ +
+  + +

- k -

+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/functions_eval_0x6c.html b/ThirdParty/Qwt/doc/html/functions_eval_0x6c.html new file mode 100644 index 0000000000..e824f34262 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/functions_eval_0x6c.html @@ -0,0 +1,191 @@ + + + + + + +Qwt User's Guide: Class Members - Enumerator + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + +
+ + + + +
+ +
+ +
+  + +

- l -

+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/functions_eval_0x6d.html b/ThirdParty/Qwt/doc/html/functions_eval_0x6d.html new file mode 100644 index 0000000000..a5332315b7 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/functions_eval_0x6d.html @@ -0,0 +1,192 @@ + + + + + + +Qwt User's Guide: Class Members - Enumerator + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + +
+ + + + +
+ +
+ +
+  + +

- m -

+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/functions_eval_0x6e.html b/ThirdParty/Qwt/doc/html/functions_eval_0x6e.html new file mode 100644 index 0000000000..4e02f90603 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/functions_eval_0x6e.html @@ -0,0 +1,203 @@ + + + + + + +Qwt User's Guide: Class Members - Enumerator + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + +
+ + + + +
+ +
+ +
+  + +

- n -

+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/functions_eval_0x6f.html b/ThirdParty/Qwt/doc/html/functions_eval_0x6f.html new file mode 100644 index 0000000000..f471122299 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/functions_eval_0x6f.html @@ -0,0 +1,153 @@ + + + + + + +Qwt User's Guide: Class Members - Enumerator + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + +
+ + + + +
+ +
+ +
+  + +

- o -

+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/functions_eval_0x70.html b/ThirdParty/Qwt/doc/html/functions_eval_0x70.html new file mode 100644 index 0000000000..4cc253074f --- /dev/null +++ b/ThirdParty/Qwt/doc/html/functions_eval_0x70.html @@ -0,0 +1,187 @@ + + + + + + +Qwt User's Guide: Class Members - Enumerator + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + +
+ + + + +
+ +
+ +
+  + +

- p -

+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/functions_eval_0x72.html b/ThirdParty/Qwt/doc/html/functions_eval_0x72.html new file mode 100644 index 0000000000..9173d83403 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/functions_eval_0x72.html @@ -0,0 +1,243 @@ + + + + + + +Qwt User's Guide: Class Members - Enumerator + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + +
+ + + + +
+ +
+ +
+  + +

- r -

+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/functions_eval_0x73.html b/ThirdParty/Qwt/doc/html/functions_eval_0x73.html new file mode 100644 index 0000000000..3f752724e8 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/functions_eval_0x73.html @@ -0,0 +1,197 @@ + + + + + + +Qwt User's Guide: Class Members - Enumerator + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + +
+ + + + +
+ +
+ +
+  + +

- s -

+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/functions_eval_0x74.html b/ThirdParty/Qwt/doc/html/functions_eval_0x74.html new file mode 100644 index 0000000000..5b6e9f3cdf --- /dev/null +++ b/ThirdParty/Qwt/doc/html/functions_eval_0x74.html @@ -0,0 +1,173 @@ + + + + + + +Qwt User's Guide: Class Members - Enumerator + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + +
+ + + + +
+ +
+ +
+  + +

- t -

+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/functions_eval_0x75.html b/ThirdParty/Qwt/doc/html/functions_eval_0x75.html new file mode 100644 index 0000000000..5aac986b74 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/functions_eval_0x75.html @@ -0,0 +1,154 @@ + + + + + + +Qwt User's Guide: Class Members - Enumerator + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + +
+ + + + +
+ +
+ +
+  + +

- u -

+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/functions_eval_0x76.html b/ThirdParty/Qwt/doc/html/functions_eval_0x76.html new file mode 100644 index 0000000000..dbf04bddb5 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/functions_eval_0x76.html @@ -0,0 +1,142 @@ + + + + + + +Qwt User's Guide: Class Members - Enumerator + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + +
+ + + + +
+ +
+ +
+  + +

- v -

+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/functions_eval_0x77.html b/ThirdParty/Qwt/doc/html/functions_eval_0x77.html new file mode 100644 index 0000000000..141532ba70 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/functions_eval_0x77.html @@ -0,0 +1,141 @@ + + + + + + +Qwt User's Guide: Class Members - Enumerator + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + +
+ + + + +
+ +
+ +
+  + +

- w -

+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/functions_eval_0x78.html b/ThirdParty/Qwt/doc/html/functions_eval_0x78.html new file mode 100644 index 0000000000..e3f31488fb --- /dev/null +++ b/ThirdParty/Qwt/doc/html/functions_eval_0x78.html @@ -0,0 +1,144 @@ + + + + + + +Qwt User's Guide: Class Members - Enumerator + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + +
+ + + + +
+ +
+ +
+  + +

- x -

+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/functions_eval_0x79.html b/ThirdParty/Qwt/doc/html/functions_eval_0x79.html new file mode 100644 index 0000000000..5fa9abdcdd --- /dev/null +++ b/ThirdParty/Qwt/doc/html/functions_eval_0x79.html @@ -0,0 +1,144 @@ + + + + + + +Qwt User's Guide: Class Members - Enumerator + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + +
+ + + + +
+ +
+ +
+  + +

- y -

+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/functions_func.html b/ThirdParty/Qwt/doc/html/functions_func.html new file mode 100644 index 0000000000..533f65f78b --- /dev/null +++ b/ThirdParty/Qwt/doc/html/functions_func.html @@ -0,0 +1,305 @@ + + + + + + +Qwt User's Guide: Class Members - Functions + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + +
+ + + + +
+ +
+ +
+  + +

- a -

+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/functions_func_0x62.html b/ThirdParty/Qwt/doc/html/functions_func_0x62.html new file mode 100644 index 0000000000..19c967a3d0 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/functions_func_0x62.html @@ -0,0 +1,262 @@ + + + + + + +Qwt User's Guide: Class Members - Functions + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + +
+ + + + +
+ +
+ +
+  + +

- b -

+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/functions_func_0x63.html b/ThirdParty/Qwt/doc/html/functions_func_0x63.html new file mode 100644 index 0000000000..a99e5c7116 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/functions_func_0x63.html @@ -0,0 +1,352 @@ + + + + + + +Qwt User's Guide: Class Members - Functions + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + +
+ + + + +
+ +
+ +
+  + +

- c -

+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/functions_func_0x64.html b/ThirdParty/Qwt/doc/html/functions_func_0x64.html new file mode 100644 index 0000000000..0ca0d77d04 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/functions_func_0x64.html @@ -0,0 +1,512 @@ + + + + + + +Qwt User's Guide: Class Members - Functions + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + +
+ + + + +
+ +
+ +
+  + +

- d -

+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/functions_func_0x65.html b/ThirdParty/Qwt/doc/html/functions_func_0x65.html new file mode 100644 index 0000000000..f50696bb6d --- /dev/null +++ b/ThirdParty/Qwt/doc/html/functions_func_0x65.html @@ -0,0 +1,211 @@ + + + + + + +Qwt User's Guide: Class Members - Functions + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + +
+ + + + +
+ +
+ +
+  + +

- e -

+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/functions_func_0x66.html b/ThirdParty/Qwt/doc/html/functions_func_0x66.html new file mode 100644 index 0000000000..9293779233 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/functions_func_0x66.html @@ -0,0 +1,203 @@ + + + + + + +Qwt User's Guide: Class Members - Functions + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + +
+ + + + +
+ +
+ +
+  + +

- f -

+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/functions_func_0x67.html b/ThirdParty/Qwt/doc/html/functions_func_0x67.html new file mode 100644 index 0000000000..80412b868a --- /dev/null +++ b/ThirdParty/Qwt/doc/html/functions_func_0x67.html @@ -0,0 +1,179 @@ + + + + + + +Qwt User's Guide: Class Members - Functions + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + +
+ + + + +
+ +
+ +
+  + +

- g -

+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/functions_func_0x68.html b/ThirdParty/Qwt/doc/html/functions_func_0x68.html new file mode 100644 index 0000000000..12d4b15e1c --- /dev/null +++ b/ThirdParty/Qwt/doc/html/functions_func_0x68.html @@ -0,0 +1,180 @@ + + + + + + +Qwt User's Guide: Class Members - Functions + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + +
+ + + + +
+ +
+ +
+  + +

- h -

+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/functions_func_0x69.html b/ThirdParty/Qwt/doc/html/functions_func_0x69.html new file mode 100644 index 0000000000..339c1a2147 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/functions_func_0x69.html @@ -0,0 +1,382 @@ + + + + + + +Qwt User's Guide: Class Members - Functions + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + +
+ + + + +
+ +
+ +
+  + +

- i -

+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/functions_func_0x6b.html b/ThirdParty/Qwt/doc/html/functions_func_0x6b.html new file mode 100644 index 0000000000..36fb8b47e6 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/functions_func_0x6b.html @@ -0,0 +1,171 @@ + + + + + + +Qwt User's Guide: Class Members - Functions + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + +
+ + + + +
+ +
+ +
+  + +

- k -

+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/functions_func_0x6c.html b/ThirdParty/Qwt/doc/html/functions_func_0x6c.html new file mode 100644 index 0000000000..cc8008ae9f --- /dev/null +++ b/ThirdParty/Qwt/doc/html/functions_func_0x6c.html @@ -0,0 +1,290 @@ + + + + + + +Qwt User's Guide: Class Members - Functions + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + +
+ + + + +
+ +
+ +
+  + +

- l -

+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/functions_func_0x6d.html b/ThirdParty/Qwt/doc/html/functions_func_0x6d.html new file mode 100644 index 0000000000..472560aa38 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/functions_func_0x6d.html @@ -0,0 +1,338 @@ + + + + + + +Qwt User's Guide: Class Members - Functions + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + +
+ + + + +
+ +
+ +
+  + +

- m -

+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/functions_func_0x6e.html b/ThirdParty/Qwt/doc/html/functions_func_0x6e.html new file mode 100644 index 0000000000..62b0de8729 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/functions_func_0x6e.html @@ -0,0 +1,172 @@ + + + + + + +Qwt User's Guide: Class Members - Functions + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + +
+ + + + +
+ +
+ +
+  + +

- n -

+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/functions_func_0x6f.html b/ThirdParty/Qwt/doc/html/functions_func_0x6f.html new file mode 100644 index 0000000000..cd88cb0dee --- /dev/null +++ b/ThirdParty/Qwt/doc/html/functions_func_0x6f.html @@ -0,0 +1,199 @@ + + + + + + +Qwt User's Guide: Class Members - Functions + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + +
+ + + + +
+ +
+ +
+  + +

- o -

+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/functions_func_0x70.html b/ThirdParty/Qwt/doc/html/functions_func_0x70.html new file mode 100644 index 0000000000..ef8000f11a --- /dev/null +++ b/ThirdParty/Qwt/doc/html/functions_func_0x70.html @@ -0,0 +1,417 @@ + + + + + + +Qwt User's Guide: Class Members - Functions + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + +
+ + + + +
+ +
+ +
+  + +

- p -

+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/functions_func_0x72.html b/ThirdParty/Qwt/doc/html/functions_func_0x72.html new file mode 100644 index 0000000000..48d086e233 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/functions_func_0x72.html @@ -0,0 +1,341 @@ + + + + + + +Qwt User's Guide: Class Members - Functions + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + +
+ + + + +
+ +
+ +
+  + +

- r -

+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/functions_func_0x73.html b/ThirdParty/Qwt/doc/html/functions_func_0x73.html new file mode 100644 index 0000000000..38d436f121 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/functions_func_0x73.html @@ -0,0 +1,1487 @@ + + + + + + +Qwt User's Guide: Class Members - Functions + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + +
+ + + + +
+ +
+ +
+  + +

- s -

+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/functions_func_0x74.html b/ThirdParty/Qwt/doc/html/functions_func_0x74.html new file mode 100644 index 0000000000..76ceb4c8a3 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/functions_func_0x74.html @@ -0,0 +1,379 @@ + + + + + + +Qwt User's Guide: Class Members - Functions + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + +
+ + + + +
+ +
+ +
+  + +

- t -

+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/functions_func_0x75.html b/ThirdParty/Qwt/doc/html/functions_func_0x75.html new file mode 100644 index 0000000000..08fc89d8ca --- /dev/null +++ b/ThirdParty/Qwt/doc/html/functions_func_0x75.html @@ -0,0 +1,202 @@ + + + + + + +Qwt User's Guide: Class Members - Functions + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + +
+ + + + +
+ +
+ +
+  + +

- u -

+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/functions_func_0x76.html b/ThirdParty/Qwt/doc/html/functions_func_0x76.html new file mode 100644 index 0000000000..dc5366d4cb --- /dev/null +++ b/ThirdParty/Qwt/doc/html/functions_func_0x76.html @@ -0,0 +1,170 @@ + + + + + + +Qwt User's Guide: Class Members - Functions + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + +
+ + + + +
+ +
+ +
+  + +

- v -

+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/functions_func_0x77.html b/ThirdParty/Qwt/doc/html/functions_func_0x77.html new file mode 100644 index 0000000000..5c380c9934 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/functions_func_0x77.html @@ -0,0 +1,233 @@ + + + + + + +Qwt User's Guide: Class Members - Functions + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + +
+ + + + +
+ +
+ +
+  + +

- w -

+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/functions_func_0x78.html b/ThirdParty/Qwt/doc/html/functions_func_0x78.html new file mode 100644 index 0000000000..531507ad69 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/functions_func_0x78.html @@ -0,0 +1,160 @@ + + + + + + +Qwt User's Guide: Class Members - Functions + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + +
+ + + + +
+ +
+ +
+  + +

- x -

+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/functions_func_0x79.html b/ThirdParty/Qwt/doc/html/functions_func_0x79.html new file mode 100644 index 0000000000..015402c434 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/functions_func_0x79.html @@ -0,0 +1,160 @@ + + + + + + +Qwt User's Guide: Class Members - Functions + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + +
+ + + + +
+ +
+ +
+  + +

- y -

+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/functions_func_0x7a.html b/ThirdParty/Qwt/doc/html/functions_func_0x7a.html new file mode 100644 index 0000000000..bafc040b40 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/functions_func_0x7a.html @@ -0,0 +1,158 @@ + + + + + + +Qwt User's Guide: Class Members - Functions + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + +
+ + + + +
+ +
+ +
+  + +

- z -

+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/functions_func_0x7e.html b/ThirdParty/Qwt/doc/html/functions_func_0x7e.html new file mode 100644 index 0000000000..a6f56369a2 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/functions_func_0x7e.html @@ -0,0 +1,427 @@ + + + + + + +Qwt User's Guide: Class Members - Functions + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + +
+ + + + +
+ +
+ +
+  + +

- ~ -

+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/functions_type.html b/ThirdParty/Qwt/doc/html/functions_type.html new file mode 100644 index 0000000000..c6312ca195 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/functions_type.html @@ -0,0 +1,166 @@ + + + + + + +Qwt User's Guide: Class Members - Typedefs + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + +
+ + + + +
+ +
+ +
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/functions_vars.html b/ThirdParty/Qwt/doc/html/functions_vars.html new file mode 100644 index 0000000000..fd1ed00309 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/functions_vars.html @@ -0,0 +1,161 @@ + + + + + + +Qwt User's Guide: Class Members - Variables + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + +
+ + + + +
+ +
+ +
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/graph.png b/ThirdParty/Qwt/doc/html/graph.png new file mode 100644 index 0000000000..55f05b876d Binary files /dev/null and b/ThirdParty/Qwt/doc/html/graph.png differ diff --git a/ThirdParty/Qwt/doc/html/graph_legend.html b/ThirdParty/Qwt/doc/html/graph_legend.html new file mode 100644 index 0000000000..0ccff6e6d0 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/graph_legend.html @@ -0,0 +1,153 @@ + + + + + + +Qwt User's Guide: Graph Legend + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + +
+ + + + +
+ +
+ +
+
+
Graph Legend
+
+
+

This page explains how to interpret the graphs that are generated by doxygen.

+

Consider the following example:

+
/*! Invisible class because of truncation */
+
class Invisible { };
+
+
/*! Truncated class, inheritance relation is hidden */
+
class Truncated : public Invisible { };
+
+
/* Class not documented with doxygen comments */
+
class Undocumented { };
+
+
/*! Class that is inherited using public inheritance */
+
class PublicBase : public Truncated { };
+
+
/*! A template class */
+
template<class T> class Templ { };
+
+
/*! Class that is inherited using protected inheritance */
+
class ProtectedBase { };
+
+
/*! Class that is inherited using private inheritance */
+
class PrivateBase { };
+
+
/*! Class that is used by the Inherited class */
+
class Used { };
+
+
/*! Super class that inherits a number of other classes */
+
class Inherited : public PublicBase,
+
protected ProtectedBase,
+
private PrivateBase,
+
public Undocumented,
+
public Templ<int>
+
{
+
private:
+
Used *m_usedClass;
+
};
+

This will result in the following graph:

+
+ +
+

The boxes in the above graph have the following meaning:

+
    +
  • +A filled gray box represents the struct or class for which the graph is generated.
  • +
  • +A box with a black border denotes a documented struct or class.
  • +
  • +A box with a grey border denotes an undocumented struct or class.
  • +
  • +A box with a red border denotes a documented struct or class forwhich not all inheritance/containment relations are shown. A graph is truncated if it does not fit within the specified boundaries.
  • +
+

The arrows have the following meaning:

+
    +
  • +A dark blue arrow is used to visualize a public inheritance relation between two classes.
  • +
  • +A dark green arrow is used for protected inheritance.
  • +
  • +A dark red arrow is used for private inheritance.
  • +
  • +A purple dashed arrow is used if a class is contained or used by another class. The arrow is labeled with the variable(s) through which the pointed class or struct is accessible.
  • +
  • +A yellow dashed arrow denotes a relation between a template instance and the template class it was instantiated from. The arrow is labeled with the template parameters of the instance.
  • +
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/graph_legend.md5 b/ThirdParty/Qwt/doc/html/graph_legend.md5 new file mode 100644 index 0000000000..2f2b0c86ff --- /dev/null +++ b/ThirdParty/Qwt/doc/html/graph_legend.md5 @@ -0,0 +1 @@ +6ba764f90c0f7463ae4482bca4fe18ee \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/graph_legend.png b/ThirdParty/Qwt/doc/html/graph_legend.png new file mode 100644 index 0000000000..b43d23e6ef Binary files /dev/null and b/ThirdParty/Qwt/doc/html/graph_legend.png differ diff --git a/ThirdParty/Qwt/doc/html/hierarchy.html b/ThirdParty/Qwt/doc/html/hierarchy.html new file mode 100644 index 0000000000..fd962b1461 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/hierarchy.html @@ -0,0 +1,270 @@ + + + + + + +Qwt User's Guide: Class Hierarchy + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + +
+ + + + +
+ +
+ +
+
+
Class Hierarchy
+
+
+
+

Go to the graphical class hierarchy

+This inheritance list is sorted roughly, but not completely, alphabetically:
+
[detail level 12345]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
oCQwtEventPattern::KeyPatternA pattern for key events
oCQwtEventPattern::MousePatternA pattern for mouse events
oCQBitArray
oCQFrame
oCQGLWidget
oCQLayout
oCQObject
oCQPaintDevice
oCQPushButton
oCQThread
oCQWidget
oCQwtAbstractScaleDrawA abstract base class for drawing scales
oCQwtAbstractSeriesStoreBridge between QwtSeriesStore and QwtPlotSeriesItem
oCQwtClipperSome clipping algorithms
oCQwtColorMapQwtColorMap is used to map values into colors
oCQwtColumnRectDirected rectangle representing bounding rectangle and orientation of a column
oCQwtColumnSymbolA drawing primitive for columns
oCQwtCompassRoseAbstract base class for a compass rose
oCQwtCurveFitterAbstract base class for a curve fitter
oCQwtDateA collection of methods around date/time values
oCQwtDialNeedleBase class for needles that can be used in a QwtDial
oCQwtEventPatternA collection of event patterns
oCQwtIntervalA class representing an interval
oCQwtIntervalSampleA sample of the types (x1-x2, y) or (x, y1-y2)
oCQwtIntervalSymbolA drawing primitive for displaying an interval like an error bar
oCQwtLegendDataAttributes of an entry on a legend
oCQwtOHLCSampleOpen-High-Low-Close sample used in financial charts
oCQwtPainterA collection of QPainter workarounds
oCQwtPainterCommand
oCQwtPickerMachineA state machine for QwtPicker selections
oCQwtPlotDictA dictionary for plot items
oCQwtPlotItemBase class for items on the plot canvas
oCQwtPlotLayoutLayout engine for QwtPlot
oCQwtPoint3DQwtPoint3D class defines a 3D point in double coordinates
oCQwtPointMapperA helper class for translating a series of points
oCQwtPointPolarA point in polar coordinates
oCQwtRasterDataQwtRasterData defines an interface to any type of raster data
oCQwtScaleArithmeticArithmetic including a tolerance
oCQwtScaleDivA class representing a scale division
oCQwtScaleEngineBase class for scale engines
oCQwtScaleMapA scale map
oCQwtSeriesData< T >Abstract interface for iterating over samples
oCQwtSeriesData< QPointF >
oCQwtSeriesData< QwtIntervalSample >
oCQwtSeriesData< QwtOHLCSample >
oCQwtSeriesData< QwtPoint3D >
oCQwtSeriesData< QwtSetSample >
oCQwtSetSampleA sample of the types (x1...xn, y) or (x, y1..yn)
oCQwtSplineA class for spline interpolation
oCQwtSymbolA class for drawing symbols
oCQwtSystemClockQwtSystemClock provides high resolution clock time functions
oCQwtTextA class representing a text
oCQwtTextEngineAbstract base class for rendering text strings
\CQwtTransformA transformation between coordinate systems
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/histogram.png b/ThirdParty/Qwt/doc/html/histogram.png new file mode 100644 index 0000000000..234bd482a8 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/histogram.png differ diff --git a/ThirdParty/Qwt/doc/html/histogramscreenshots.html b/ThirdParty/Qwt/doc/html/histogramscreenshots.html new file mode 100644 index 0000000000..69895909f0 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/histogramscreenshots.html @@ -0,0 +1,92 @@ + + + + + + +Qwt User's Guide: Histogram + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ +
+
+
+
Histogram
+
+
+
+histogram.png +
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/index.html b/ThirdParty/Qwt/doc/html/index.html new file mode 100644 index 0000000000..63dc191d30 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/index.html @@ -0,0 +1,156 @@ + + + + + + +Qwt User's Guide: Qwt - Qt Widgets for Technical Applications + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + +
+ + + + +
+ +
+ +
+
+
Qwt - Qt Widgets for Technical Applications
+
+
+

The Qwt library contains GUI Components and utility classes which are primarily useful for programs with a technical background. Beside a framework for 2D plots it provides scales, sliders, dials, compasses, thermometers, wheels and knobs to control or display values, arrays, or ranges of type double.

+
+plot.png +
+

+License

+

Qwt is distributed under the terms of the Qwt License, Version 1.0.

+

+Platforms

+

Qwt 6.1 might be usable in all environments where you find Qt. It is compatible with Qt4 ( >= 4.4 ) and Qt5.

+

+What's new

+

Read the summary of the most important changes.

+

+Screenshots

+ +

+Downloads

+

Stable releases or prereleases are available at the Qwt project page.

+

For getting a snapshot with all bugfixes for the latest 5.2 release:

+
svn checkout svn://svn.code.sf.net/p/qwt/code/branches/qwt-5.2
+

For getting a snapshot with all bugfixes for the latest 6.1 release:

+
svn checkout svn://svn.code.sf.net/p/qwt/code/branches/qwt-6.1
+

For getting a development snapshot from the SVN repository:

+
svn checkout svn://svn.code.sf.net/p/qwt/code/trunk/qwt
+

+Installation

+

Qwt doesn't distribute binary packages, but today all major Linux distributors offer one. Note, that these packages often don't include the examples.

+

When no binary packages are available ( f.e. on Windows ) Qwt needs to be compiled and installed on the target system.

+

+Support

+
    +
  • Mailing list
    + For all kind of Qwt related questions use the Qwt mailing list.
    + If you prefer newsgroups use the mail to news gateway of Gmane.
  • +
+
    +
  • Forum
    + Qt Centre is a great resource for Qt related questions. It has a sub forum, that is dedicated to Qwt related questions.
  • +
+
    +
  • Individual support
    + If you are looking for individual support, or need someone who implements your Qwt component/application contact suppo.nosp@m.rt@q.nosp@m.wt-pr.nosp@m.ojec.nosp@m.t.org. Sending requests to this address without a good reason for not using public support channels might be silently ignored.
  • +
+

+Related Projects

+

QwtPolar, a polar plot widget.
+ QwtPlot3D, an OpenGL 3D plot widget.
+

+

+Donations

+

Sourceforge offers a Donation System via PayPal. You can use it, if you like to support the development of Qwt.

+

+Credits:

+
Authors:
Uwe Rathmann, Josef Wilgen ( <= Qwt 0.2 )
+
Project admin:
Uwe Rathmann <rathm.nosp@m.ann@.nosp@m.users.nosp@m..sou.nosp@m.rcefo.nosp@m.rge..nosp@m.net>
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/index.qhp b/ThirdParty/Qwt/doc/html/index.qhp new file mode 100644 index 0000000000..51e0356581 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/index.qhp @@ -0,0 +1,8789 @@ + + + net.sourceforge.qwt-svn + qwt-svn + + doxygen + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + tabs.css + tab_a.png + tab_b.png + tab_h.png + tab_s.png + nav_h.png + nav_f.png + bc_s.png + doxygen.png + closed.png + open.png + bdwn.png + sync_on.png + sync_off.png + ftv2blank.png + ftv2doc.png + ftv2folderclosed.png + ftv2folderopen.png + ftv2ns.png + ftv2mo.png + ftv2cl.png + ftv2lastnode.png + ftv2link.png + ftv2mlastnode.png + ftv2mnode.png + ftv2node.png + ftv2plastnode.png + ftv2pnode.png + ftv2vertline.png + ftv2splitbar.png + doxygen.css + /search/mag_sel.png + /search/search_l.png + /search/search_m.png + /search/search_r.png + /search/close.png + search/search.css + search/search.js + qwt__abstract__legend_8h_source.html + qwt__abstract__scale_8h_source.html + qwt__abstract__scale__draw_8h_source.html + qwt__abstract__slider_8h_source.html + qwt__analog__clock_8h_source.html + qwt__arrow__button_8h_source.html + qwt__clipper_8h_source.html + qwt__color__map_8h_source.html + qwt__column__symbol_8h_source.html + qwt__compass_8h_source.html + qwt__compass__rose_8h_source.html + qwt__compat_8h_source.html + qwt__counter_8h_source.html + qwt__curve__fitter_8h_source.html + qwt__date_8h_source.html + qwt__date__scale__draw_8h_source.html + qwt__date__scale__engine_8h_source.html + qwt__dial_8h_source.html + qwt__dial__needle_8h_source.html + qwt__dyngrid__layout_8h_source.html + qwt__event__pattern_8h_source.html + qwt__global_8h_source.html + qwt__graphic_8h_source.html + qwt__interval_8h_source.html + qwt__interval__symbol_8h_source.html + qwt__knob_8h_source.html + qwt__legend_8h_source.html + qwt__legend__data_8h_source.html + qwt__legend__label_8h_source.html + qwt__magnifier_8h_source.html + qwt__math_8h_source.html + qwt__mathml__text__engine_8h_source.html + qwt__matrix__raster__data_8h_source.html + qwt__mml__document_8h_source.html + qwt__null__paintdevice_8h_source.html + qwt__painter_8h_source.html + qwt__painter__command_8h_source.html + qwt__panner_8h_source.html + qwt__picker_8h_source.html + qwt__picker__machine_8h_source.html + qwt__pixel__matrix_8h_source.html + qwt__plot_8h_source.html + qwt__plot__abstract__barchart_8h_source.html + qwt__plot__barchart_8h_source.html + qwt__plot__canvas_8h_source.html + qwt__plot__curve_8h_source.html + qwt__plot__dict_8h_source.html + qwt__plot__directpainter_8h_source.html + qwt__plot__glcanvas_8h_source.html + qwt__plot__grid_8h_source.html + qwt__plot__histogram_8h_source.html + qwt__plot__intervalcurve_8h_source.html + qwt__plot__item_8h_source.html + qwt__plot__layout_8h_source.html + qwt__plot__legenditem_8h_source.html + qwt__plot__magnifier_8h_source.html + qwt__plot__marker_8h_source.html + qwt__plot__multi__barchart_8h_source.html + qwt__plot__panner_8h_source.html + qwt__plot__picker_8h_source.html + qwt__plot__rasteritem_8h_source.html + qwt__plot__renderer_8h_source.html + qwt__plot__rescaler_8h_source.html + qwt__plot__scaleitem_8h_source.html + qwt__plot__seriesitem_8h_source.html + qwt__plot__shapeitem_8h_source.html + qwt__plot__spectrocurve_8h_source.html + qwt__plot__spectrogram_8h_source.html + qwt__plot__svgitem_8h_source.html + qwt__plot__textlabel_8h_source.html + qwt__plot__tradingcurve_8h_source.html + qwt__plot__zoneitem_8h_source.html + qwt__plot__zoomer_8h_source.html + qwt__point__3d_8h_source.html + qwt__point__data_8h_source.html + qwt__point__mapper_8h_source.html + qwt__point__polar_8h_source.html + qwt__raster__data_8h_source.html + qwt__round__scale__draw_8h_source.html + qwt__samples_8h_source.html + qwt__sampling__thread_8h_source.html + qwt__scale__div_8h_source.html + qwt__scale__draw_8h_source.html + qwt__scale__engine_8h_source.html + qwt__scale__map_8h_source.html + qwt__scale__widget_8h_source.html + qwt__series__data_8h_source.html + qwt__series__store_8h_source.html + qwt__slider_8h_source.html + qwt__spline_8h_source.html + qwt__symbol_8h_source.html + qwt__system__clock_8h_source.html + qwt__text_8h_source.html + qwt__text__engine_8h_source.html + qwt__text__label_8h_source.html + qwt__thermo_8h_source.html + qwt__transform_8h_source.html + qwt__wheel_8h_source.html + qwt__widget__overlay_8h_source.html + qwtchangelog.html + qwtinstall.html + qwtlicense.html + curvescreenshots.html + plot.png + sinus.png + cpuplot.png + graph.png + curves.png + scatterscreenshots.html + scatterplot.png + spectrogramscreenshots.html + spectrogram1.png + spectrogram2.png + spectrogram3.png + histogramscreenshots.html + histogram.png + controlscreenshots.html + radio.png + sliders.png + dials1.png + dials2.png + sysinfo.png + class_qwt_abstract_legend.html + class_qwt_abstract_legend__inherit__graph.png + class_qwt_abstract_legend__inherit__graph.png + class_qwt_abstract_legend-members.html + class_qwt_abstract_scale.html + class_qwt_abstract_scale__inherit__graph.png + class_qwt_abstract_scale__inherit__graph.png + class_qwt_abstract_scale-members.html + class_qwt_abstract_scale_draw.html + class_qwt_abstract_scale_draw__inherit__graph.png + class_qwt_abstract_scale_draw__inherit__graph.png + class_qwt_abstract_scale_draw-members.html + class_qwt_abstract_series_store.html + class_qwt_abstract_series_store__inherit__graph.png + class_qwt_abstract_series_store__inherit__graph.png + class_qwt_abstract_series_store-members.html + class_qwt_abstract_slider.html + class_qwt_abstract_slider__inherit__graph.png + class_qwt_abstract_slider__inherit__graph.png + class_qwt_abstract_slider-members.html + class_qwt_alpha_color_map.html + class_qwt_alpha_color_map__inherit__graph.png + class_qwt_alpha_color_map__inherit__graph.png + class_qwt_alpha_color_map-members.html + class_qwt_analog_clock.html + class_qwt_analog_clock__inherit__graph.png + class_qwt_analog_clock__inherit__graph.png + analogclock.png + class_qwt_analog_clock-members.html + class_qwt_array_series_data.html + class_qwt_array_series_data__inherit__graph.png + class_qwt_array_series_data__inherit__graph.png + class_qwt_array_series_data-members.html + class_qwt_arrow_button.html + class_qwt_arrow_button__inherit__graph.png + class_qwt_arrow_button__inherit__graph.png + class_qwt_arrow_button-members.html + class_qwt_clipper.html + class_qwt_clipper-members.html + class_qwt_color_map.html + class_qwt_color_map__inherit__graph.png + class_qwt_color_map__inherit__graph.png + class_qwt_color_map-members.html + class_qwt_column_rect.html + class_qwt_column_rect-members.html + class_qwt_column_symbol.html + class_qwt_column_symbol-members.html + class_qwt_compass.html + class_qwt_compass__inherit__graph.png + class_qwt_compass__inherit__graph.png + dials1.png + class_qwt_compass-members.html + class_qwt_compass_magnet_needle.html + class_qwt_compass_magnet_needle__inherit__graph.png + class_qwt_compass_magnet_needle__inherit__graph.png + class_qwt_compass_magnet_needle-members.html + class_qwt_compass_rose.html + class_qwt_compass_rose__inherit__graph.png + class_qwt_compass_rose__inherit__graph.png + class_qwt_compass_rose-members.html + class_qwt_compass_scale_draw.html + class_qwt_compass_scale_draw__inherit__graph.png + class_qwt_compass_scale_draw__inherit__graph.png + class_qwt_compass_scale_draw-members.html + class_qwt_compass_wind_arrow.html + class_qwt_compass_wind_arrow__inherit__graph.png + class_qwt_compass_wind_arrow__inherit__graph.png + class_qwt_compass_wind_arrow-members.html + class_qwt_counter.html + class_qwt_counter__inherit__graph.png + class_qwt_counter__inherit__graph.png + class_qwt_counter-members.html + class_qwt_c_pointer_data.html + class_qwt_c_pointer_data__inherit__graph.png + class_qwt_c_pointer_data__inherit__graph.png + class_qwt_c_pointer_data-members.html + class_qwt_curve_fitter.html + class_qwt_curve_fitter__inherit__graph.png + class_qwt_curve_fitter__inherit__graph.png + class_qwt_curve_fitter-members.html + class_qwt_date.html + class_qwt_date-members.html + class_qwt_date_scale_draw.html + class_qwt_date_scale_draw__inherit__graph.png + class_qwt_date_scale_draw__inherit__graph.png + class_qwt_date_scale_draw-members.html + class_qwt_date_scale_engine.html + class_qwt_date_scale_engine__inherit__graph.png + class_qwt_date_scale_engine__inherit__graph.png + class_qwt_date_scale_engine-members.html + class_qwt_dial.html + class_qwt_dial__inherit__graph.png + class_qwt_dial__inherit__graph.png + dials2.png + class_qwt_dial-members.html + class_qwt_dial_needle.html + class_qwt_dial_needle__inherit__graph.png + class_qwt_dial_needle__inherit__graph.png + class_qwt_dial_needle-members.html + class_qwt_dial_simple_needle.html + class_qwt_dial_simple_needle__inherit__graph.png + class_qwt_dial_simple_needle__inherit__graph.png + class_qwt_dial_simple_needle-members.html + class_qwt_dyn_grid_layout.html + class_qwt_dyn_grid_layout__inherit__graph.png + class_qwt_dyn_grid_layout__inherit__graph.png + class_qwt_dyn_grid_layout-members.html + class_qwt_event_pattern.html + class_qwt_event_pattern__inherit__graph.png + class_qwt_event_pattern__inherit__graph.png + class_qwt_event_pattern-members.html + class_qwt_event_pattern_1_1_key_pattern.html + class_qwt_event_pattern_1_1_key_pattern-members.html + class_qwt_event_pattern_1_1_mouse_pattern.html + class_qwt_event_pattern_1_1_mouse_pattern-members.html + class_qwt_graphic.html + class_qwt_graphic__inherit__graph.png + class_qwt_graphic__inherit__graph.png + class_qwt_graphic-members.html + class_qwt_interval.html + class_qwt_interval-members.html + class_qwt_interval_sample.html + class_qwt_interval_sample-members.html + class_qwt_interval_series_data.html + class_qwt_interval_series_data__inherit__graph.png + class_qwt_interval_series_data__inherit__graph.png + class_qwt_interval_series_data-members.html + class_qwt_interval_symbol.html + class_qwt_interval_symbol-members.html + class_qwt_knob.html + class_qwt_knob__inherit__graph.png + class_qwt_knob__inherit__graph.png + knob.png + class_qwt_knob-members.html + class_qwt_legend.html + class_qwt_legend__inherit__graph.png + class_qwt_legend__inherit__graph.png + class_qwt_legend-members.html + class_qwt_legend_data.html + class_qwt_legend_data-members.html + class_qwt_legend_label.html + class_qwt_legend_label__inherit__graph.png + class_qwt_legend_label__inherit__graph.png + class_qwt_legend_label-members.html + class_qwt_linear_color_map.html + class_qwt_linear_color_map__inherit__graph.png + class_qwt_linear_color_map__inherit__graph.png + class_qwt_linear_color_map-members.html + class_qwt_linear_scale_engine.html + class_qwt_linear_scale_engine__inherit__graph.png + class_qwt_linear_scale_engine__inherit__graph.png + class_qwt_linear_scale_engine-members.html + class_qwt_log_scale_engine.html + class_qwt_log_scale_engine__inherit__graph.png + class_qwt_log_scale_engine__inherit__graph.png + class_qwt_log_scale_engine-members.html + class_qwt_log_transform.html + class_qwt_log_transform__inherit__graph.png + class_qwt_log_transform__inherit__graph.png + class_qwt_log_transform-members.html + class_qwt_magnifier.html + class_qwt_magnifier__inherit__graph.png + class_qwt_magnifier__inherit__graph.png + class_qwt_magnifier-members.html + class_qwt_math_m_l_text_engine.html + class_qwt_math_m_l_text_engine__inherit__graph.png + class_qwt_math_m_l_text_engine__inherit__graph.png + class_qwt_math_m_l_text_engine-members.html + class_qwt_matrix_raster_data.html + class_qwt_matrix_raster_data__inherit__graph.png + class_qwt_matrix_raster_data__inherit__graph.png + class_qwt_matrix_raster_data-members.html + class_qwt_null_paint_device.html + class_qwt_null_paint_device__inherit__graph.png + class_qwt_null_paint_device__inherit__graph.png + class_qwt_null_paint_device-members.html + class_qwt_null_transform.html + class_qwt_null_transform__inherit__graph.png + class_qwt_null_transform__inherit__graph.png + class_qwt_null_transform-members.html + class_qwt_o_h_l_c_sample.html + class_qwt_o_h_l_c_sample-members.html + class_qwt_painter.html + class_qwt_painter-members.html + class_qwt_painter_command.html + class_qwt_painter_command-members.html + class_qwt_panner.html + class_qwt_panner__inherit__graph.png + class_qwt_panner__inherit__graph.png + class_qwt_panner-members.html + class_qwt_picker.html + class_qwt_picker__inherit__graph.png + class_qwt_picker__inherit__graph.png + class_qwt_picker-members.html + class_qwt_picker_click_point_machine.html + class_qwt_picker_click_point_machine__inherit__graph.png + class_qwt_picker_click_point_machine__inherit__graph.png + class_qwt_picker_click_point_machine-members.html + class_qwt_picker_click_rect_machine.html + class_qwt_picker_click_rect_machine__inherit__graph.png + class_qwt_picker_click_rect_machine__inherit__graph.png + class_qwt_picker_click_rect_machine-members.html + class_qwt_picker_drag_line_machine.html + class_qwt_picker_drag_line_machine__inherit__graph.png + class_qwt_picker_drag_line_machine__inherit__graph.png + class_qwt_picker_drag_line_machine-members.html + class_qwt_picker_drag_point_machine.html + class_qwt_picker_drag_point_machine__inherit__graph.png + class_qwt_picker_drag_point_machine__inherit__graph.png + class_qwt_picker_drag_point_machine-members.html + class_qwt_picker_drag_rect_machine.html + class_qwt_picker_drag_rect_machine__inherit__graph.png + class_qwt_picker_drag_rect_machine__inherit__graph.png + class_qwt_picker_drag_rect_machine-members.html + class_qwt_picker_machine.html + class_qwt_picker_machine__inherit__graph.png + class_qwt_picker_machine__inherit__graph.png + class_qwt_picker_machine-members.html + class_qwt_picker_polygon_machine.html + class_qwt_picker_polygon_machine__inherit__graph.png + class_qwt_picker_polygon_machine__inherit__graph.png + class_qwt_picker_polygon_machine-members.html + class_qwt_picker_tracker_machine.html + class_qwt_picker_tracker_machine__inherit__graph.png + class_qwt_picker_tracker_machine__inherit__graph.png + class_qwt_picker_tracker_machine-members.html + class_qwt_pixel_matrix.html + class_qwt_pixel_matrix__inherit__graph.png + class_qwt_pixel_matrix__inherit__graph.png + class_qwt_pixel_matrix-members.html + class_qwt_plain_text_engine.html + class_qwt_plain_text_engine__inherit__graph.png + class_qwt_plain_text_engine__inherit__graph.png + class_qwt_plain_text_engine-members.html + class_qwt_plot.html + class_qwt_plot__inherit__graph.png + class_qwt_plot__inherit__graph.png + plot.png + class_qwt_plot-members.html + class_qwt_plot_abstract_bar_chart.html + class_qwt_plot_abstract_bar_chart__inherit__graph.png + class_qwt_plot_abstract_bar_chart__inherit__graph.png + class_qwt_plot_abstract_bar_chart-members.html + class_qwt_plot_bar_chart.html + class_qwt_plot_bar_chart__inherit__graph.png + class_qwt_plot_bar_chart__inherit__graph.png + class_qwt_plot_bar_chart-members.html + class_qwt_plot_canvas.html + class_qwt_plot_canvas__inherit__graph.png + class_qwt_plot_canvas__inherit__graph.png + class_qwt_plot_canvas-members.html + class_qwt_plot_curve.html + class_qwt_plot_curve__inherit__graph.png + class_qwt_plot_curve__inherit__graph.png + class_qwt_plot_curve-members.html + class_qwt_plot_dict.html + class_qwt_plot_dict__inherit__graph.png + class_qwt_plot_dict__inherit__graph.png + class_qwt_plot_dict-members.html + class_qwt_plot_direct_painter.html + class_qwt_plot_direct_painter__inherit__graph.png + class_qwt_plot_direct_painter__inherit__graph.png + class_qwt_plot_direct_painter-members.html + class_qwt_plot_g_l_canvas.html + class_qwt_plot_g_l_canvas__inherit__graph.png + class_qwt_plot_g_l_canvas__inherit__graph.png + class_qwt_plot_g_l_canvas-members.html + class_qwt_plot_grid.html + class_qwt_plot_grid__inherit__graph.png + class_qwt_plot_grid__inherit__graph.png + class_qwt_plot_grid-members.html + class_qwt_plot_histogram.html + class_qwt_plot_histogram__inherit__graph.png + class_qwt_plot_histogram__inherit__graph.png + class_qwt_plot_histogram-members.html + class_qwt_plot_interval_curve.html + class_qwt_plot_interval_curve__inherit__graph.png + class_qwt_plot_interval_curve__inherit__graph.png + class_qwt_plot_interval_curve-members.html + class_qwt_plot_item.html + class_qwt_plot_item__inherit__graph.png + class_qwt_plot_item__inherit__graph.png + class_qwt_plot_item-members.html + class_qwt_plot_layout.html + class_qwt_plot_layout-members.html + class_qwt_plot_legend_item.html + class_qwt_plot_legend_item__inherit__graph.png + class_qwt_plot_legend_item__inherit__graph.png + class_qwt_plot_legend_item-members.html + class_qwt_plot_magnifier.html + class_qwt_plot_magnifier__inherit__graph.png + class_qwt_plot_magnifier__inherit__graph.png + class_qwt_plot_magnifier-members.html + class_qwt_plot_marker.html + class_qwt_plot_marker__inherit__graph.png + class_qwt_plot_marker__inherit__graph.png + class_qwt_plot_marker-members.html + class_qwt_plot_multi_bar_chart.html + class_qwt_plot_multi_bar_chart__inherit__graph.png + class_qwt_plot_multi_bar_chart__inherit__graph.png + class_qwt_plot_multi_bar_chart-members.html + class_qwt_plot_panner.html + class_qwt_plot_panner__inherit__graph.png + class_qwt_plot_panner__inherit__graph.png + class_qwt_plot_panner-members.html + class_qwt_plot_picker.html + class_qwt_plot_picker__inherit__graph.png + class_qwt_plot_picker__inherit__graph.png + class_qwt_plot_picker-members.html + class_qwt_plot_raster_item.html + class_qwt_plot_raster_item__inherit__graph.png + class_qwt_plot_raster_item__inherit__graph.png + class_qwt_plot_raster_item-members.html + class_qwt_plot_renderer.html + class_qwt_plot_renderer__inherit__graph.png + class_qwt_plot_renderer__inherit__graph.png + class_qwt_plot_renderer-members.html + class_qwt_plot_rescaler.html + class_qwt_plot_rescaler__inherit__graph.png + class_qwt_plot_rescaler__inherit__graph.png + class_qwt_plot_rescaler-members.html + class_qwt_plot_scale_item.html + class_qwt_plot_scale_item__inherit__graph.png + class_qwt_plot_scale_item__inherit__graph.png + class_qwt_plot_scale_item-members.html + class_qwt_plot_series_item.html + class_qwt_plot_series_item__inherit__graph.png + class_qwt_plot_series_item__inherit__graph.png + class_qwt_plot_series_item-members.html + class_qwt_plot_shape_item.html + class_qwt_plot_shape_item__inherit__graph.png + class_qwt_plot_shape_item__inherit__graph.png + class_qwt_plot_shape_item-members.html + class_qwt_plot_spectro_curve.html + class_qwt_plot_spectro_curve__inherit__graph.png + class_qwt_plot_spectro_curve__inherit__graph.png + class_qwt_plot_spectro_curve-members.html + class_qwt_plot_spectrogram.html + class_qwt_plot_spectrogram__inherit__graph.png + class_qwt_plot_spectrogram__inherit__graph.png + spectrogram3.png + class_qwt_plot_spectrogram-members.html + class_qwt_plot_svg_item.html + class_qwt_plot_svg_item__inherit__graph.png + class_qwt_plot_svg_item__inherit__graph.png + class_qwt_plot_svg_item-members.html + class_qwt_plot_text_label.html + class_qwt_plot_text_label__inherit__graph.png + class_qwt_plot_text_label__inherit__graph.png + class_qwt_plot_text_label-members.html + class_qwt_plot_trading_curve.html + class_qwt_plot_trading_curve__inherit__graph.png + class_qwt_plot_trading_curve__inherit__graph.png + class_qwt_plot_trading_curve-members.html + class_qwt_plot_zone_item.html + class_qwt_plot_zone_item__inherit__graph.png + class_qwt_plot_zone_item__inherit__graph.png + class_qwt_plot_zone_item-members.html + class_qwt_plot_zoomer.html + class_qwt_plot_zoomer__inherit__graph.png + class_qwt_plot_zoomer__inherit__graph.png + class_qwt_plot_zoomer-members.html + class_qwt_point3_d.html + class_qwt_point3_d-members.html + class_qwt_point3_d_series_data.html + class_qwt_point3_d_series_data__inherit__graph.png + class_qwt_point3_d_series_data__inherit__graph.png + class_qwt_point3_d_series_data-members.html + class_qwt_point_array_data.html + class_qwt_point_array_data__inherit__graph.png + class_qwt_point_array_data__inherit__graph.png + class_qwt_point_array_data-members.html + class_qwt_point_mapper.html + class_qwt_point_mapper-members.html + class_qwt_point_polar.html + class_qwt_point_polar-members.html + class_qwt_point_series_data.html + class_qwt_point_series_data__inherit__graph.png + class_qwt_point_series_data__inherit__graph.png + class_qwt_point_series_data-members.html + class_qwt_power_transform.html + class_qwt_power_transform__inherit__graph.png + class_qwt_power_transform__inherit__graph.png + class_qwt_power_transform-members.html + class_qwt_raster_data.html + class_qwt_raster_data__inherit__graph.png + class_qwt_raster_data__inherit__graph.png + class_qwt_raster_data-members.html + class_qwt_rich_text_engine.html + class_qwt_rich_text_engine__inherit__graph.png + class_qwt_rich_text_engine__inherit__graph.png + class_qwt_rich_text_engine-members.html + class_qwt_round_scale_draw.html + class_qwt_round_scale_draw__inherit__graph.png + class_qwt_round_scale_draw__inherit__graph.png + class_qwt_round_scale_draw-members.html + class_qwt_sampling_thread.html + class_qwt_sampling_thread__inherit__graph.png + class_qwt_sampling_thread__inherit__graph.png + class_qwt_sampling_thread-members.html + class_qwt_scale_arithmetic.html + class_qwt_scale_arithmetic-members.html + class_qwt_scale_div.html + class_qwt_scale_div-members.html + class_qwt_scale_draw.html + class_qwt_scale_draw__inherit__graph.png + class_qwt_scale_draw__inherit__graph.png + class_qwt_scale_draw-members.html + class_qwt_scale_engine.html + class_qwt_scale_engine__inherit__graph.png + class_qwt_scale_engine__inherit__graph.png + class_qwt_scale_engine-members.html + class_qwt_scale_map.html + class_qwt_scale_map-members.html + class_qwt_scale_widget.html + class_qwt_scale_widget__inherit__graph.png + class_qwt_scale_widget__inherit__graph.png + class_qwt_scale_widget-members.html + class_qwt_series_data.html + class_qwt_series_data__inherit__graph.png + class_qwt_series_data__inherit__graph.png + class_qwt_series_data-members.html + class_qwt_series_store.html + class_qwt_series_store__inherit__graph.png + class_qwt_series_store__inherit__graph.png + class_qwt_series_store-members.html + class_qwt_set_sample.html + class_qwt_set_sample-members.html + class_qwt_set_series_data.html + class_qwt_set_series_data__inherit__graph.png + class_qwt_set_series_data__inherit__graph.png + class_qwt_set_series_data-members.html + class_qwt_simple_compass_rose.html + class_qwt_simple_compass_rose__inherit__graph.png + class_qwt_simple_compass_rose__inherit__graph.png + class_qwt_simple_compass_rose-members.html + class_qwt_slider.html + class_qwt_slider__inherit__graph.png + class_qwt_slider__inherit__graph.png + sliders.png + class_qwt_slider-members.html + class_qwt_spline.html + class_qwt_spline-members.html + class_qwt_spline_curve_fitter.html + class_qwt_spline_curve_fitter__inherit__graph.png + class_qwt_spline_curve_fitter__inherit__graph.png + class_qwt_spline_curve_fitter-members.html + class_qwt_symbol.html + class_qwt_symbol-members.html + class_qwt_synthetic_point_data.html + class_qwt_synthetic_point_data__inherit__graph.png + class_qwt_synthetic_point_data__inherit__graph.png + class_qwt_synthetic_point_data-members.html + class_qwt_system_clock.html + class_qwt_system_clock-members.html + class_qwt_text.html + class_qwt_text-members.html + class_qwt_text_engine.html + class_qwt_text_engine__inherit__graph.png + class_qwt_text_engine__inherit__graph.png + class_qwt_text_engine-members.html + class_qwt_text_label.html + class_qwt_text_label__inherit__graph.png + class_qwt_text_label__inherit__graph.png + class_qwt_text_label-members.html + class_qwt_thermo.html + class_qwt_thermo__inherit__graph.png + class_qwt_thermo__inherit__graph.png + sysinfo.png + class_qwt_thermo-members.html + class_qwt_trading_chart_data.html + class_qwt_trading_chart_data__inherit__graph.png + class_qwt_trading_chart_data__inherit__graph.png + class_qwt_trading_chart_data-members.html + class_qwt_transform.html + class_qwt_transform__inherit__graph.png + class_qwt_transform__inherit__graph.png + class_qwt_transform-members.html + class_qwt_weeding_curve_fitter.html + class_qwt_weeding_curve_fitter__inherit__graph.png + class_qwt_weeding_curve_fitter__inherit__graph.png + class_qwt_weeding_curve_fitter-members.html + class_qwt_wheel.html + class_qwt_wheel__inherit__graph.png + class_qwt_wheel__inherit__graph.png + class_qwt_wheel-members.html + class_qwt_widget_overlay.html + class_qwt_widget_overlay__inherit__graph.png + class_qwt_widget_overlay__inherit__graph.png + class_qwt_widget_overlay-members.html + graph_legend.png + graph_legend.html + dir_06d3aa943e68e822334d93a35d8d6e04.html + dir_06d3aa943e68e822334d93a35d8d6e04_dep.png + dir_06d3aa943e68e822334d93a35d8d6e04_dep.png + dir_9ccb36e974cdad92d68e40b0bc8a6a19.html + dir_9ccb36e974cdad92d68e40b0bc8a6a19_dep.png + dir_9ccb36e974cdad92d68e40b0bc8a6a19_dep.png + dir_d71481910ae6010efd2d807d0acbed8c.html + dir_d71481910ae6010efd2d807d0acbed8c_dep.png + dir_d71481910ae6010efd2d807d0acbed8c_dep.png + form_0.png + form_1.png + form_2.png + form_3.png + form_4.png + form_5.png + index.html + plot.png + plot.png + pages.html + annotated.html + classes.html + hierarchy.html + inherits.html + inherit_graph_0.png + inherit_graph_1.png + inherit_graph_2.png + inherit_graph_3.png + inherit_graph_4.png + inherit_graph_5.png + inherit_graph_6.png + inherit_graph_7.png + inherit_graph_8.png + inherit_graph_9.png + inherit_graph_10.png + inherit_graph_11.png + inherit_graph_12.png + inherit_graph_13.png + inherit_graph_14.png + inherit_graph_15.png + inherit_graph_16.png + inherit_graph_17.png + inherit_graph_18.png + inherit_graph_19.png + inherit_graph_20.png + inherit_graph_21.png + inherit_graph_22.png + inherit_graph_23.png + inherit_graph_24.png + inherit_graph_25.png + inherit_graph_26.png + inherit_graph_27.png + inherit_graph_28.png + inherit_graph_29.png + inherit_graph_30.png + inherit_graph_31.png + inherit_graph_32.png + inherit_graph_33.png + inherit_graph_34.png + inherit_graph_35.png + inherit_graph_36.png + inherit_graph_37.png + inherit_graph_38.png + inherit_graph_39.png + inherit_graph_40.png + inherit_graph_41.png + inherit_graph_42.png + inherit_graph_43.png + inherit_graph_44.png + inherit_graph_45.png + inherit_graph_46.png + inherit_graph_47.png + inherit_graph_48.png + inherit_graph_49.png + inherit_graph_50.png + functions.html + functions_0x62.html + functions_0x63.html + functions_0x64.html + functions_0x65.html + functions_0x66.html + functions_0x67.html + functions_0x68.html + functions_0x69.html + functions_0x6a.html + functions_0x6b.html + functions_0x6c.html + functions_0x6d.html + functions_0x6e.html + functions_0x6f.html + functions_0x70.html + functions_0x72.html + functions_0x73.html + functions_0x74.html + functions_0x75.html + functions_0x76.html + functions_0x77.html + functions_0x78.html + functions_0x79.html + functions_0x7a.html + functions_0x7e.html + functions_func.html + functions_func_0x62.html + functions_func_0x63.html + functions_func_0x64.html + functions_func_0x65.html + functions_func_0x66.html + functions_func_0x67.html + functions_func_0x68.html + functions_func_0x69.html + functions_func_0x6b.html + functions_func_0x6c.html + functions_func_0x6d.html + functions_func_0x6e.html + functions_func_0x6f.html + functions_func_0x70.html + functions_func_0x72.html + functions_func_0x73.html + functions_func_0x74.html + functions_func_0x75.html + functions_func_0x76.html + functions_func_0x77.html + functions_func_0x78.html + functions_func_0x79.html + functions_func_0x7a.html + functions_func_0x7e.html + functions_vars.html + functions_type.html + functions_enum.html + functions_eval.html + functions_eval_0x62.html + functions_eval_0x63.html + functions_eval_0x64.html + functions_eval_0x65.html + functions_eval_0x66.html + functions_eval_0x67.html + functions_eval_0x68.html + functions_eval_0x69.html + functions_eval_0x6a.html + functions_eval_0x6b.html + functions_eval_0x6c.html + functions_eval_0x6d.html + functions_eval_0x6e.html + functions_eval_0x6f.html + functions_eval_0x70.html + functions_eval_0x72.html + functions_eval_0x73.html + functions_eval_0x74.html + functions_eval_0x75.html + functions_eval_0x76.html + functions_eval_0x77.html + functions_eval_0x78.html + functions_eval_0x79.html + + + diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_0.map b/ThirdParty/Qwt/doc/html/inherit_graph_0.map new file mode 100644 index 0000000000..b006f8250e --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_0.map @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_0.md5 b/ThirdParty/Qwt/doc/html/inherit_graph_0.md5 new file mode 100644 index 0000000000..1171f50145 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_0.md5 @@ -0,0 +1 @@ +b4e2c1b6b1529fd256b952ecc94de395 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_0.png b/ThirdParty/Qwt/doc/html/inherit_graph_0.png new file mode 100644 index 0000000000..f6deeeddb8 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/inherit_graph_0.png differ diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_1.map b/ThirdParty/Qwt/doc/html/inherit_graph_1.map new file mode 100644 index 0000000000..bc7b99d04d --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_1.map @@ -0,0 +1,7 @@ + + + + + + + diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_1.md5 b/ThirdParty/Qwt/doc/html/inherit_graph_1.md5 new file mode 100644 index 0000000000..740d064df7 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_1.md5 @@ -0,0 +1 @@ +c934241c01740b9e34b4655a03af925e \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_1.png b/ThirdParty/Qwt/doc/html/inherit_graph_1.png new file mode 100644 index 0000000000..1cca0b877b Binary files /dev/null and b/ThirdParty/Qwt/doc/html/inherit_graph_1.png differ diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_10.map b/ThirdParty/Qwt/doc/html/inherit_graph_10.map new file mode 100644 index 0000000000..91bb99f19c --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_10.map @@ -0,0 +1,6 @@ + + + + + + diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_10.md5 b/ThirdParty/Qwt/doc/html/inherit_graph_10.md5 new file mode 100644 index 0000000000..7354ba2ed0 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_10.md5 @@ -0,0 +1 @@ +82eb10d478e8fbdee4e180788c215c50 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_10.png b/ThirdParty/Qwt/doc/html/inherit_graph_10.png new file mode 100644 index 0000000000..b72630aa93 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/inherit_graph_10.png differ diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_11.map b/ThirdParty/Qwt/doc/html/inherit_graph_11.map new file mode 100644 index 0000000000..6f1292e78e --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_11.map @@ -0,0 +1,3 @@ + + + diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_11.md5 b/ThirdParty/Qwt/doc/html/inherit_graph_11.md5 new file mode 100644 index 0000000000..4311c96477 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_11.md5 @@ -0,0 +1 @@ +8bc335890074e958169abeb503a2bb7e \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_11.png b/ThirdParty/Qwt/doc/html/inherit_graph_11.png new file mode 100644 index 0000000000..50d1d703cd Binary files /dev/null and b/ThirdParty/Qwt/doc/html/inherit_graph_11.png differ diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_12.map b/ThirdParty/Qwt/doc/html/inherit_graph_12.map new file mode 100644 index 0000000000..9db760b629 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_12.map @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_12.md5 b/ThirdParty/Qwt/doc/html/inherit_graph_12.md5 new file mode 100644 index 0000000000..9f88b41697 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_12.md5 @@ -0,0 +1 @@ +960e2562b125d3534dc92ac2975376a5 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_12.png b/ThirdParty/Qwt/doc/html/inherit_graph_12.png new file mode 100644 index 0000000000..ca7a6088c4 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/inherit_graph_12.png differ diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_13.map b/ThirdParty/Qwt/doc/html/inherit_graph_13.map new file mode 100644 index 0000000000..74d10d20cc --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_13.map @@ -0,0 +1,3 @@ + + + diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_13.md5 b/ThirdParty/Qwt/doc/html/inherit_graph_13.md5 new file mode 100644 index 0000000000..d91adf23d7 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_13.md5 @@ -0,0 +1 @@ +81f862b6b1ae38995259542f91fcc2be \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_13.png b/ThirdParty/Qwt/doc/html/inherit_graph_13.png new file mode 100644 index 0000000000..58b9780e5c Binary files /dev/null and b/ThirdParty/Qwt/doc/html/inherit_graph_13.png differ diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_14.map b/ThirdParty/Qwt/doc/html/inherit_graph_14.map new file mode 100644 index 0000000000..c9c67c25d1 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_14.map @@ -0,0 +1,3 @@ + + + diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_14.md5 b/ThirdParty/Qwt/doc/html/inherit_graph_14.md5 new file mode 100644 index 0000000000..5ef3df80cc --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_14.md5 @@ -0,0 +1 @@ +56b11ab2ae584c18ff01d8dcdda9a924 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_14.png b/ThirdParty/Qwt/doc/html/inherit_graph_14.png new file mode 100644 index 0000000000..47dc36b081 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/inherit_graph_14.png differ diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_15.map b/ThirdParty/Qwt/doc/html/inherit_graph_15.map new file mode 100644 index 0000000000..6f3925a98e --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_15.map @@ -0,0 +1,3 @@ + + + diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_15.md5 b/ThirdParty/Qwt/doc/html/inherit_graph_15.md5 new file mode 100644 index 0000000000..f85ca09977 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_15.md5 @@ -0,0 +1 @@ +416578b0481d8ed8693ae2ce47bd46d1 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_15.png b/ThirdParty/Qwt/doc/html/inherit_graph_15.png new file mode 100644 index 0000000000..e2224282dd Binary files /dev/null and b/ThirdParty/Qwt/doc/html/inherit_graph_15.png differ diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_16.map b/ThirdParty/Qwt/doc/html/inherit_graph_16.map new file mode 100644 index 0000000000..32393af622 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_16.map @@ -0,0 +1,3 @@ + + + diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_16.md5 b/ThirdParty/Qwt/doc/html/inherit_graph_16.md5 new file mode 100644 index 0000000000..3dc7094f77 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_16.md5 @@ -0,0 +1 @@ +6b5ee75180a7c1e14ecfbd08e99c8c84 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_16.png b/ThirdParty/Qwt/doc/html/inherit_graph_16.png new file mode 100644 index 0000000000..ffa83c5eff Binary files /dev/null and b/ThirdParty/Qwt/doc/html/inherit_graph_16.png differ diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_17.map b/ThirdParty/Qwt/doc/html/inherit_graph_17.map new file mode 100644 index 0000000000..2ca6e1e70c --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_17.map @@ -0,0 +1,3 @@ + + + diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_17.md5 b/ThirdParty/Qwt/doc/html/inherit_graph_17.md5 new file mode 100644 index 0000000000..7830dd708b --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_17.md5 @@ -0,0 +1 @@ +b0f5c618a4a15da48d6e6da38932196c \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_17.png b/ThirdParty/Qwt/doc/html/inherit_graph_17.png new file mode 100644 index 0000000000..fecd633c03 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/inherit_graph_17.png differ diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_18.map b/ThirdParty/Qwt/doc/html/inherit_graph_18.map new file mode 100644 index 0000000000..5f46c6e313 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_18.map @@ -0,0 +1,3 @@ + + + diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_18.md5 b/ThirdParty/Qwt/doc/html/inherit_graph_18.md5 new file mode 100644 index 0000000000..937b4f6c63 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_18.md5 @@ -0,0 +1 @@ +74e9077a43325aedba83a633c67f6815 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_18.png b/ThirdParty/Qwt/doc/html/inherit_graph_18.png new file mode 100644 index 0000000000..ac540df763 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/inherit_graph_18.png differ diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_19.map b/ThirdParty/Qwt/doc/html/inherit_graph_19.map new file mode 100644 index 0000000000..b75d596769 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_19.map @@ -0,0 +1,4 @@ + + + + diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_19.md5 b/ThirdParty/Qwt/doc/html/inherit_graph_19.md5 new file mode 100644 index 0000000000..a8bd3d4799 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_19.md5 @@ -0,0 +1 @@ +7c973584f6af703f67082224cd66da74 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_19.png b/ThirdParty/Qwt/doc/html/inherit_graph_19.png new file mode 100644 index 0000000000..378701496b Binary files /dev/null and b/ThirdParty/Qwt/doc/html/inherit_graph_19.png differ diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_2.map b/ThirdParty/Qwt/doc/html/inherit_graph_2.map new file mode 100644 index 0000000000..a84a3a3e9e --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_2.map @@ -0,0 +1,3 @@ + + + diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_2.md5 b/ThirdParty/Qwt/doc/html/inherit_graph_2.md5 new file mode 100644 index 0000000000..b6743cf3b6 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_2.md5 @@ -0,0 +1 @@ +a34edcebcc64449610b7261042b714b4 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_2.png b/ThirdParty/Qwt/doc/html/inherit_graph_2.png new file mode 100644 index 0000000000..a1ca10902b Binary files /dev/null and b/ThirdParty/Qwt/doc/html/inherit_graph_2.png differ diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_20.map b/ThirdParty/Qwt/doc/html/inherit_graph_20.map new file mode 100644 index 0000000000..3589522bd5 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_20.map @@ -0,0 +1,3 @@ + + + diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_20.md5 b/ThirdParty/Qwt/doc/html/inherit_graph_20.md5 new file mode 100644 index 0000000000..ff733031d6 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_20.md5 @@ -0,0 +1 @@ +fefec1357ed82f66b3f70b4b9d23c99f \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_20.png b/ThirdParty/Qwt/doc/html/inherit_graph_20.png new file mode 100644 index 0000000000..c8ddc6d496 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/inherit_graph_20.png differ diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_21.map b/ThirdParty/Qwt/doc/html/inherit_graph_21.map new file mode 100644 index 0000000000..8affde177b --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_21.map @@ -0,0 +1,3 @@ + + + diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_21.md5 b/ThirdParty/Qwt/doc/html/inherit_graph_21.md5 new file mode 100644 index 0000000000..fdd3a07b75 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_21.md5 @@ -0,0 +1 @@ +91216bfef8ea5d6c035ba5742d05bcd7 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_21.png b/ThirdParty/Qwt/doc/html/inherit_graph_21.png new file mode 100644 index 0000000000..3441c2d6a5 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/inherit_graph_21.png differ diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_22.map b/ThirdParty/Qwt/doc/html/inherit_graph_22.map new file mode 100644 index 0000000000..b32a4547c2 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_22.map @@ -0,0 +1,3 @@ + + + diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_22.md5 b/ThirdParty/Qwt/doc/html/inherit_graph_22.md5 new file mode 100644 index 0000000000..235cbc1427 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_22.md5 @@ -0,0 +1 @@ +d2293c65ce45154c8484ca3b0d5db5a1 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_22.png b/ThirdParty/Qwt/doc/html/inherit_graph_22.png new file mode 100644 index 0000000000..24e4b9b217 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/inherit_graph_22.png differ diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_23.map b/ThirdParty/Qwt/doc/html/inherit_graph_23.map new file mode 100644 index 0000000000..67ab96572d --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_23.map @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_23.md5 b/ThirdParty/Qwt/doc/html/inherit_graph_23.md5 new file mode 100644 index 0000000000..de3cb02130 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_23.md5 @@ -0,0 +1 @@ +8b1d63c0d6703eb553aa600ef1648003 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_23.png b/ThirdParty/Qwt/doc/html/inherit_graph_23.png new file mode 100644 index 0000000000..b59f521f36 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/inherit_graph_23.png differ diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_24.map b/ThirdParty/Qwt/doc/html/inherit_graph_24.map new file mode 100644 index 0000000000..e01067770d --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_24.map @@ -0,0 +1,3 @@ + + + diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_24.md5 b/ThirdParty/Qwt/doc/html/inherit_graph_24.md5 new file mode 100644 index 0000000000..f328b4b037 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_24.md5 @@ -0,0 +1 @@ +7cde1923b30a8ce24ecbedf2a3d08a75 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_24.png b/ThirdParty/Qwt/doc/html/inherit_graph_24.png new file mode 100644 index 0000000000..e48e37bb95 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/inherit_graph_24.png differ diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_25.map b/ThirdParty/Qwt/doc/html/inherit_graph_25.map new file mode 100644 index 0000000000..cb92d8c9fa --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_25.map @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_25.md5 b/ThirdParty/Qwt/doc/html/inherit_graph_25.md5 new file mode 100644 index 0000000000..dbd80b5bc4 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_25.md5 @@ -0,0 +1 @@ +9c92194ca015429ba2d1f17e69d895fc \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_25.png b/ThirdParty/Qwt/doc/html/inherit_graph_25.png new file mode 100644 index 0000000000..a21427aaa2 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/inherit_graph_25.png differ diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_26.map b/ThirdParty/Qwt/doc/html/inherit_graph_26.map new file mode 100644 index 0000000000..ccbccf9e2f --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_26.map @@ -0,0 +1,3 @@ + + + diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_26.md5 b/ThirdParty/Qwt/doc/html/inherit_graph_26.md5 new file mode 100644 index 0000000000..d48a5e4d91 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_26.md5 @@ -0,0 +1 @@ +0c828da280b9e1c8817824be95c30bdc \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_26.png b/ThirdParty/Qwt/doc/html/inherit_graph_26.png new file mode 100644 index 0000000000..395674b6b7 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/inherit_graph_26.png differ diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_27.map b/ThirdParty/Qwt/doc/html/inherit_graph_27.map new file mode 100644 index 0000000000..56c3cb6540 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_27.map @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_27.md5 b/ThirdParty/Qwt/doc/html/inherit_graph_27.md5 new file mode 100644 index 0000000000..b5804c6ef7 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_27.md5 @@ -0,0 +1 @@ +53f2f5141b1e8b86a48c1394062bc1d9 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_27.png b/ThirdParty/Qwt/doc/html/inherit_graph_27.png new file mode 100644 index 0000000000..006ab910a0 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/inherit_graph_27.png differ diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_28.map b/ThirdParty/Qwt/doc/html/inherit_graph_28.map new file mode 100644 index 0000000000..1756bd2faf --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_28.map @@ -0,0 +1,3 @@ + + + diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_28.md5 b/ThirdParty/Qwt/doc/html/inherit_graph_28.md5 new file mode 100644 index 0000000000..6da9c39757 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_28.md5 @@ -0,0 +1 @@ +f6c8a3a7107418406786314471e8833c \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_28.png b/ThirdParty/Qwt/doc/html/inherit_graph_28.png new file mode 100644 index 0000000000..bacfc48335 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/inherit_graph_28.png differ diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_29.map b/ThirdParty/Qwt/doc/html/inherit_graph_29.map new file mode 100644 index 0000000000..4a97afdd1a --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_29.map @@ -0,0 +1,3 @@ + + + diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_29.md5 b/ThirdParty/Qwt/doc/html/inherit_graph_29.md5 new file mode 100644 index 0000000000..829dcb689a --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_29.md5 @@ -0,0 +1 @@ +f873dcdea9cac66beae78fcbecea131f \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_29.png b/ThirdParty/Qwt/doc/html/inherit_graph_29.png new file mode 100644 index 0000000000..3db22cf2a0 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/inherit_graph_29.png differ diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_3.map b/ThirdParty/Qwt/doc/html/inherit_graph_3.map new file mode 100644 index 0000000000..52c503943b --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_3.map @@ -0,0 +1,3 @@ + + + diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_3.md5 b/ThirdParty/Qwt/doc/html/inherit_graph_3.md5 new file mode 100644 index 0000000000..8dc4f9c5b1 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_3.md5 @@ -0,0 +1 @@ +8a6be7c247997819c9f2b40205826915 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_3.png b/ThirdParty/Qwt/doc/html/inherit_graph_3.png new file mode 100644 index 0000000000..79082c2712 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/inherit_graph_3.png differ diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_30.map b/ThirdParty/Qwt/doc/html/inherit_graph_30.map new file mode 100644 index 0000000000..e8c22c0922 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_30.map @@ -0,0 +1,3 @@ + + + diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_30.md5 b/ThirdParty/Qwt/doc/html/inherit_graph_30.md5 new file mode 100644 index 0000000000..7e74511824 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_30.md5 @@ -0,0 +1 @@ +02c24ab81da235f3fbd874c3b9cd01c8 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_30.png b/ThirdParty/Qwt/doc/html/inherit_graph_30.png new file mode 100644 index 0000000000..f7cb825120 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/inherit_graph_30.png differ diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_31.map b/ThirdParty/Qwt/doc/html/inherit_graph_31.map new file mode 100644 index 0000000000..35ea4d318b --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_31.map @@ -0,0 +1,3 @@ + + + diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_31.md5 b/ThirdParty/Qwt/doc/html/inherit_graph_31.md5 new file mode 100644 index 0000000000..9892efb48c --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_31.md5 @@ -0,0 +1 @@ +20975738c04f24ed68d559a9b6e8afb5 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_31.png b/ThirdParty/Qwt/doc/html/inherit_graph_31.png new file mode 100644 index 0000000000..85033ed447 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/inherit_graph_31.png differ diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_32.map b/ThirdParty/Qwt/doc/html/inherit_graph_32.map new file mode 100644 index 0000000000..2756c13442 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_32.map @@ -0,0 +1,4 @@ + + + + diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_32.md5 b/ThirdParty/Qwt/doc/html/inherit_graph_32.md5 new file mode 100644 index 0000000000..93b67e9891 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_32.md5 @@ -0,0 +1 @@ +c33f975cf322b0eb76785a35c2ac489d \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_32.png b/ThirdParty/Qwt/doc/html/inherit_graph_32.png new file mode 100644 index 0000000000..2d2ccac734 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/inherit_graph_32.png differ diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_33.map b/ThirdParty/Qwt/doc/html/inherit_graph_33.map new file mode 100644 index 0000000000..9f3c160592 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_33.map @@ -0,0 +1,3 @@ + + + diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_33.md5 b/ThirdParty/Qwt/doc/html/inherit_graph_33.md5 new file mode 100644 index 0000000000..c7926c1508 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_33.md5 @@ -0,0 +1 @@ +55353982c4a38f5678a5f453a9bdf419 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_33.png b/ThirdParty/Qwt/doc/html/inherit_graph_33.png new file mode 100644 index 0000000000..31ce89c8f7 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/inherit_graph_33.png differ diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_34.map b/ThirdParty/Qwt/doc/html/inherit_graph_34.map new file mode 100644 index 0000000000..50454a3afb --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_34.map @@ -0,0 +1,3 @@ + + + diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_34.md5 b/ThirdParty/Qwt/doc/html/inherit_graph_34.md5 new file mode 100644 index 0000000000..ff591c600d --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_34.md5 @@ -0,0 +1 @@ +6e249247efdb52d3d6b9dd3d1974f026 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_34.png b/ThirdParty/Qwt/doc/html/inherit_graph_34.png new file mode 100644 index 0000000000..4170a7dfe0 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/inherit_graph_34.png differ diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_35.map b/ThirdParty/Qwt/doc/html/inherit_graph_35.map new file mode 100644 index 0000000000..3e06a9aff2 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_35.map @@ -0,0 +1,3 @@ + + + diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_35.md5 b/ThirdParty/Qwt/doc/html/inherit_graph_35.md5 new file mode 100644 index 0000000000..8fad47ac0e --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_35.md5 @@ -0,0 +1 @@ +5fea7d7eb8b178a733635d03a2684e30 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_35.png b/ThirdParty/Qwt/doc/html/inherit_graph_35.png new file mode 100644 index 0000000000..29952caf2f Binary files /dev/null and b/ThirdParty/Qwt/doc/html/inherit_graph_35.png differ diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_36.map b/ThirdParty/Qwt/doc/html/inherit_graph_36.map new file mode 100644 index 0000000000..49df365ceb --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_36.map @@ -0,0 +1,6 @@ + + + + + + diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_36.md5 b/ThirdParty/Qwt/doc/html/inherit_graph_36.md5 new file mode 100644 index 0000000000..548d8a7b37 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_36.md5 @@ -0,0 +1 @@ +a4025a78d4873dda3d2d49d958ed6425 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_36.png b/ThirdParty/Qwt/doc/html/inherit_graph_36.png new file mode 100644 index 0000000000..72c64df79d Binary files /dev/null and b/ThirdParty/Qwt/doc/html/inherit_graph_36.png differ diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_37.map b/ThirdParty/Qwt/doc/html/inherit_graph_37.map new file mode 100644 index 0000000000..236c744731 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_37.map @@ -0,0 +1,3 @@ + + + diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_37.md5 b/ThirdParty/Qwt/doc/html/inherit_graph_37.md5 new file mode 100644 index 0000000000..0aca2de509 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_37.md5 @@ -0,0 +1 @@ +a9bf6907e641d0cd5a7470cd3da6c14b \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_37.png b/ThirdParty/Qwt/doc/html/inherit_graph_37.png new file mode 100644 index 0000000000..bd3d88150e Binary files /dev/null and b/ThirdParty/Qwt/doc/html/inherit_graph_37.png differ diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_38.map b/ThirdParty/Qwt/doc/html/inherit_graph_38.map new file mode 100644 index 0000000000..baf058973a --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_38.map @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_38.md5 b/ThirdParty/Qwt/doc/html/inherit_graph_38.md5 new file mode 100644 index 0000000000..2f578d53cb --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_38.md5 @@ -0,0 +1 @@ +f03acf9e50306dad9e56255a5ca2bfe4 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_38.png b/ThirdParty/Qwt/doc/html/inherit_graph_38.png new file mode 100644 index 0000000000..cd824536b0 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/inherit_graph_38.png differ diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_39.map b/ThirdParty/Qwt/doc/html/inherit_graph_39.map new file mode 100644 index 0000000000..2786adaa84 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_39.map @@ -0,0 +1,5 @@ + + + + + diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_39.md5 b/ThirdParty/Qwt/doc/html/inherit_graph_39.md5 new file mode 100644 index 0000000000..1940c1be0c --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_39.md5 @@ -0,0 +1 @@ +c507b98e0b4ed720687551d07d670d2d \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_39.png b/ThirdParty/Qwt/doc/html/inherit_graph_39.png new file mode 100644 index 0000000000..76dcc790c1 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/inherit_graph_39.png differ diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_4.map b/ThirdParty/Qwt/doc/html/inherit_graph_4.map new file mode 100644 index 0000000000..82183ed1d8 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_4.map @@ -0,0 +1,5 @@ + + + + + diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_4.md5 b/ThirdParty/Qwt/doc/html/inherit_graph_4.md5 new file mode 100644 index 0000000000..cde634619a --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_4.md5 @@ -0,0 +1 @@ +d67e50722948f345488e19632243db1e \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_4.png b/ThirdParty/Qwt/doc/html/inherit_graph_4.png new file mode 100644 index 0000000000..673ea066c0 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/inherit_graph_4.png differ diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_40.map b/ThirdParty/Qwt/doc/html/inherit_graph_40.map new file mode 100644 index 0000000000..e01b9eda06 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_40.map @@ -0,0 +1,5 @@ + + + + + diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_40.md5 b/ThirdParty/Qwt/doc/html/inherit_graph_40.md5 new file mode 100644 index 0000000000..ba17dfb96a --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_40.md5 @@ -0,0 +1 @@ +90fbb7427819d9e5f07fe93fd8bbeb0c \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_40.png b/ThirdParty/Qwt/doc/html/inherit_graph_40.png new file mode 100644 index 0000000000..a670ed6849 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/inherit_graph_40.png differ diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_41.map b/ThirdParty/Qwt/doc/html/inherit_graph_41.map new file mode 100644 index 0000000000..755ec74e84 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_41.map @@ -0,0 +1,5 @@ + + + + + diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_41.md5 b/ThirdParty/Qwt/doc/html/inherit_graph_41.md5 new file mode 100644 index 0000000000..af11c37074 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_41.md5 @@ -0,0 +1 @@ +03029a295bfcb00cbbad32138fb464f6 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_41.png b/ThirdParty/Qwt/doc/html/inherit_graph_41.png new file mode 100644 index 0000000000..fac2e23f60 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/inherit_graph_41.png differ diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_42.map b/ThirdParty/Qwt/doc/html/inherit_graph_42.map new file mode 100644 index 0000000000..aee166b817 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_42.map @@ -0,0 +1,5 @@ + + + + + diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_42.md5 b/ThirdParty/Qwt/doc/html/inherit_graph_42.md5 new file mode 100644 index 0000000000..2b608079a6 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_42.md5 @@ -0,0 +1 @@ +3822233b21a3ad4f97fc5b3096eb1cb5 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_42.png b/ThirdParty/Qwt/doc/html/inherit_graph_42.png new file mode 100644 index 0000000000..f473b292bc Binary files /dev/null and b/ThirdParty/Qwt/doc/html/inherit_graph_42.png differ diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_43.map b/ThirdParty/Qwt/doc/html/inherit_graph_43.map new file mode 100644 index 0000000000..d0cca8f06a --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_43.map @@ -0,0 +1,4 @@ + + + + diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_43.md5 b/ThirdParty/Qwt/doc/html/inherit_graph_43.md5 new file mode 100644 index 0000000000..85533a3f08 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_43.md5 @@ -0,0 +1 @@ +602d0e023e46b4b6dfd2e3fad2eebea2 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_43.png b/ThirdParty/Qwt/doc/html/inherit_graph_43.png new file mode 100644 index 0000000000..9616b652f3 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/inherit_graph_43.png differ diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_44.map b/ThirdParty/Qwt/doc/html/inherit_graph_44.map new file mode 100644 index 0000000000..306ed95cad --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_44.map @@ -0,0 +1,3 @@ + + + diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_44.md5 b/ThirdParty/Qwt/doc/html/inherit_graph_44.md5 new file mode 100644 index 0000000000..cbe6d13421 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_44.md5 @@ -0,0 +1 @@ +06fee2a807377cd055f1fad97080d014 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_44.png b/ThirdParty/Qwt/doc/html/inherit_graph_44.png new file mode 100644 index 0000000000..aee72d361c Binary files /dev/null and b/ThirdParty/Qwt/doc/html/inherit_graph_44.png differ diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_45.map b/ThirdParty/Qwt/doc/html/inherit_graph_45.map new file mode 100644 index 0000000000..71c742f136 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_45.map @@ -0,0 +1,3 @@ + + + diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_45.md5 b/ThirdParty/Qwt/doc/html/inherit_graph_45.md5 new file mode 100644 index 0000000000..4c5ea54251 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_45.md5 @@ -0,0 +1 @@ +0afca757492ff1903cbee3219032924e \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_45.png b/ThirdParty/Qwt/doc/html/inherit_graph_45.png new file mode 100644 index 0000000000..6c46a300d6 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/inherit_graph_45.png differ diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_46.map b/ThirdParty/Qwt/doc/html/inherit_graph_46.map new file mode 100644 index 0000000000..4e63e6b557 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_46.map @@ -0,0 +1,3 @@ + + + diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_46.md5 b/ThirdParty/Qwt/doc/html/inherit_graph_46.md5 new file mode 100644 index 0000000000..3b6268cdbb --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_46.md5 @@ -0,0 +1 @@ +766b19e41c5033faf38e6681ffbb844f \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_46.png b/ThirdParty/Qwt/doc/html/inherit_graph_46.png new file mode 100644 index 0000000000..6c39422cc0 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/inherit_graph_46.png differ diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_47.map b/ThirdParty/Qwt/doc/html/inherit_graph_47.map new file mode 100644 index 0000000000..7c9a0937d8 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_47.map @@ -0,0 +1,3 @@ + + + diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_47.md5 b/ThirdParty/Qwt/doc/html/inherit_graph_47.md5 new file mode 100644 index 0000000000..03e9f97953 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_47.md5 @@ -0,0 +1 @@ +01ab098d2b60c64618fa2dccdb275a79 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_47.png b/ThirdParty/Qwt/doc/html/inherit_graph_47.png new file mode 100644 index 0000000000..524351fadd Binary files /dev/null and b/ThirdParty/Qwt/doc/html/inherit_graph_47.png differ diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_48.map b/ThirdParty/Qwt/doc/html/inherit_graph_48.map new file mode 100644 index 0000000000..37c55d9a50 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_48.map @@ -0,0 +1,3 @@ + + + diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_48.md5 b/ThirdParty/Qwt/doc/html/inherit_graph_48.md5 new file mode 100644 index 0000000000..a1aa51fcae --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_48.md5 @@ -0,0 +1 @@ +f30848d258bc1761cc3b54de3146a69f \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_48.png b/ThirdParty/Qwt/doc/html/inherit_graph_48.png new file mode 100644 index 0000000000..3aa7835b70 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/inherit_graph_48.png differ diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_49.map b/ThirdParty/Qwt/doc/html/inherit_graph_49.map new file mode 100644 index 0000000000..1ccc2cd1fb --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_49.map @@ -0,0 +1,6 @@ + + + + + + diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_49.md5 b/ThirdParty/Qwt/doc/html/inherit_graph_49.md5 new file mode 100644 index 0000000000..55d12465f7 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_49.md5 @@ -0,0 +1 @@ +72074ee97f49e1e3c68de17315cb2cc6 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_49.png b/ThirdParty/Qwt/doc/html/inherit_graph_49.png new file mode 100644 index 0000000000..3b2ba204aa Binary files /dev/null and b/ThirdParty/Qwt/doc/html/inherit_graph_49.png differ diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_5.map b/ThirdParty/Qwt/doc/html/inherit_graph_5.map new file mode 100644 index 0000000000..49628d2057 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_5.map @@ -0,0 +1,3 @@ + + + diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_5.md5 b/ThirdParty/Qwt/doc/html/inherit_graph_5.md5 new file mode 100644 index 0000000000..3147930cb5 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_5.md5 @@ -0,0 +1 @@ +f58c60d750a72c09fdccf4885e645b4e \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_5.png b/ThirdParty/Qwt/doc/html/inherit_graph_5.png new file mode 100644 index 0000000000..d43960fb0e Binary files /dev/null and b/ThirdParty/Qwt/doc/html/inherit_graph_5.png differ diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_50.map b/ThirdParty/Qwt/doc/html/inherit_graph_50.map new file mode 100644 index 0000000000..4349a34ac9 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_50.map @@ -0,0 +1,6 @@ + + + + + + diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_50.md5 b/ThirdParty/Qwt/doc/html/inherit_graph_50.md5 new file mode 100644 index 0000000000..56086820e5 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_50.md5 @@ -0,0 +1 @@ +d2ae20acf9424d0fd0e5c1e5b793323c \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_50.png b/ThirdParty/Qwt/doc/html/inherit_graph_50.png new file mode 100644 index 0000000000..7600cba323 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/inherit_graph_50.png differ diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_6.map b/ThirdParty/Qwt/doc/html/inherit_graph_6.map new file mode 100644 index 0000000000..b0c3f8795f --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_6.map @@ -0,0 +1,3 @@ + + + diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_6.md5 b/ThirdParty/Qwt/doc/html/inherit_graph_6.md5 new file mode 100644 index 0000000000..bf7c4c6de2 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_6.md5 @@ -0,0 +1 @@ +671ebd80a1018ebcc00038157b148806 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_6.png b/ThirdParty/Qwt/doc/html/inherit_graph_6.png new file mode 100644 index 0000000000..133d9c02f1 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/inherit_graph_6.png differ diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_7.map b/ThirdParty/Qwt/doc/html/inherit_graph_7.map new file mode 100644 index 0000000000..33eb914bf6 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_7.map @@ -0,0 +1,4 @@ + + + + diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_7.md5 b/ThirdParty/Qwt/doc/html/inherit_graph_7.md5 new file mode 100644 index 0000000000..75df6240a4 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_7.md5 @@ -0,0 +1 @@ +715f91bd55a14aa0161748173dc06271 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_7.png b/ThirdParty/Qwt/doc/html/inherit_graph_7.png new file mode 100644 index 0000000000..99bf0552d3 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/inherit_graph_7.png differ diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_8.map b/ThirdParty/Qwt/doc/html/inherit_graph_8.map new file mode 100644 index 0000000000..4d86f63d3b --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_8.map @@ -0,0 +1,5 @@ + + + + + diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_8.md5 b/ThirdParty/Qwt/doc/html/inherit_graph_8.md5 new file mode 100644 index 0000000000..47dcf6606a --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_8.md5 @@ -0,0 +1 @@ +53d07babe896e1d59c3f39ad64911d84 \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_8.png b/ThirdParty/Qwt/doc/html/inherit_graph_8.png new file mode 100644 index 0000000000..d9284e5575 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/inherit_graph_8.png differ diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_9.map b/ThirdParty/Qwt/doc/html/inherit_graph_9.map new file mode 100644 index 0000000000..faf307c081 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_9.map @@ -0,0 +1,3 @@ + + + diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_9.md5 b/ThirdParty/Qwt/doc/html/inherit_graph_9.md5 new file mode 100644 index 0000000000..2f8cbc9479 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherit_graph_9.md5 @@ -0,0 +1 @@ +8d69df8e90fe935289c4013e2afc64df \ No newline at end of file diff --git a/ThirdParty/Qwt/doc/html/inherit_graph_9.png b/ThirdParty/Qwt/doc/html/inherit_graph_9.png new file mode 100644 index 0000000000..df3c85054c Binary files /dev/null and b/ThirdParty/Qwt/doc/html/inherit_graph_9.png differ diff --git a/ThirdParty/Qwt/doc/html/inherits.html b/ThirdParty/Qwt/doc/html/inherits.html new file mode 100644 index 0000000000..185a283dc5 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/inherits.html @@ -0,0 +1,305 @@ + + + + + + +Qwt User's Guide: Class Hierarchy + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + +
+ + + + +
+ +
+ +
+
+
Class Hierarchy
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/jquery.js b/ThirdParty/Qwt/doc/html/jquery.js new file mode 100644 index 0000000000..63939e76dd --- /dev/null +++ b/ThirdParty/Qwt/doc/html/jquery.js @@ -0,0 +1,8 @@ +/*! jQuery v1.7.1 jquery.com | jquery.org/license */ +(function(a,b){function cy(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cv(a){if(!ck[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){cl||(cl=c.createElement("iframe"),cl.frameBorder=cl.width=cl.height=0),b.appendChild(cl);if(!cm||!cl.createElement)cm=(cl.contentWindow||cl.contentDocument).document,cm.write((c.compatMode==="CSS1Compat"?"":"")+""),cm.close();d=cm.createElement(a),cm.body.appendChild(d),e=f.css(d,"display"),b.removeChild(cl)}ck[a]=e}return ck[a]}function cu(a,b){var c={};f.each(cq.concat.apply([],cq.slice(0,b)),function(){c[this]=a});return c}function ct(){cr=b}function cs(){setTimeout(ct,0);return cr=f.now()}function cj(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ci(){try{return new a.XMLHttpRequest}catch(b){}}function cc(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g0){if(c!=="border")for(;g=0===c})}function S(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function K(){return!0}function J(){return!1}function n(a,b,c){var d=b+"defer",e=b+"queue",g=b+"mark",h=f._data(a,d);h&&(c==="queue"||!f._data(a,e))&&(c==="mark"||!f._data(a,g))&&setTimeout(function(){!f._data(a,e)&&!f._data(a,g)&&(f.removeData(a,d,!0),h.fire())},0)}function m(a){for(var b in a){if(b==="data"&&f.isEmptyObject(a[b]))continue;if(b!=="toJSON")return!1}return!0}function l(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(k,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNumeric(d)?parseFloat(d):j.test(d)?f.parseJSON(d):d}catch(g){}f.data(a,c,d)}else d=b}return d}function h(a){var b=g[a]={},c,d;a=a.split(/\s+/);for(c=0,d=a.length;c)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,n=/^[\],:{}\s]*$/,o=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,p=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,q=/(?:^|:|,)(?:\s*\[)+/g,r=/(webkit)[ \/]([\w.]+)/,s=/(opera)(?:.*version)?[ \/]([\w.]+)/,t=/(msie) ([\w.]+)/,u=/(mozilla)(?:.*? rv:([\w.]+))?/,v=/-([a-z]|[0-9])/ig,w=/^-ms-/,x=function(a,b){return(b+"").toUpperCase()},y=d.userAgent,z,A,B,C=Object.prototype.toString,D=Object.prototype.hasOwnProperty,E=Array.prototype.push,F=Array.prototype.slice,G=String.prototype.trim,H=Array.prototype.indexOf,I={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=m.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.7.1",length:0,size:function(){return this.length},toArray:function(){return F.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?E.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),A.add(a);return this},eq:function(a){a=+a;return a===-1?this.slice(a):this.slice(a,a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(F.apply(this,arguments),"slice",F.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:E,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j0)return;A.fireWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").off("ready")}},bindReady:function(){if(!A){A=e.Callbacks("once memory");if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",B,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",B),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&J()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a&&typeof a=="object"&&"setInterval"in a},isNumeric:function(a){return!isNaN(parseFloat(a))&&isFinite(a)},type:function(a){return a==null?String(a):I[C.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;try{if(a.constructor&&!D.call(a,"constructor")&&!D.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||D.call(a,d)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw new Error(a)},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(n.test(b.replace(o,"@").replace(p,"]").replace(q,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(c){var d,f;try{a.DOMParser?(f=new DOMParser,d=f.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(g){d=b}(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&e.error("Invalid XML: "+c);return d},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(w,"ms-").replace(v,x)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i1?i.call(arguments,0):b,j.notifyWith(k,e)}}function l(a){return function(c){b[a]=arguments.length>1?i.call(arguments,0):c,--g||j.resolveWith(j,b)}}var b=i.call(arguments,0),c=0,d=b.length,e=Array(d),g=d,h=d,j=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred(),k=j.promise();if(d>1){for(;c
a",d=q.getElementsByTagName("*"),e=q.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=q.getElementsByTagName("input")[0],b={leadingWhitespace:q.firstChild.nodeType===3,tbody:!q.getElementsByTagName("tbody").length,htmlSerialize:!!q.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,checkOn:i.value==="on",optSelected:h.selected,getSetAttribute:q.className!=="t",enctype:!!c.createElement("form").enctype,html5Clone:c.createElement("nav").cloneNode(!0).outerHTML!=="<:nav>",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0},i.checked=!0,b.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,b.optDisabled=!h.disabled;try{delete q.test}catch(s){b.deleteExpando=!1}!q.addEventListener&&q.attachEvent&&q.fireEvent&&(q.attachEvent("onclick",function(){b.noCloneEvent=!1}),q.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),b.radioValue=i.value==="t",i.setAttribute("checked","checked"),q.appendChild(i),k=c.createDocumentFragment(),k.appendChild(q.lastChild),b.checkClone=k.cloneNode(!0).cloneNode(!0).lastChild.checked,b.appendChecked=i.checked,k.removeChild(i),k.appendChild(q),q.innerHTML="",a.getComputedStyle&&(j=c.createElement("div"),j.style.width="0",j.style.marginRight="0",q.style.width="2px",q.appendChild(j),b.reliableMarginRight=(parseInt((a.getComputedStyle(j,null)||{marginRight:0}).marginRight,10)||0)===0);if(q.attachEvent)for(o in{submit:1,change:1,focusin:1})n="on"+o,p=n in q,p||(q.setAttribute(n,"return;"),p=typeof q[n]=="function"),b[o+"Bubbles"]=p;k.removeChild(q),k=g=h=j=q=i=null,f(function(){var a,d,e,g,h,i,j,k,m,n,o,r=c.getElementsByTagName("body")[0];!r||(j=1,k="position:absolute;top:0;left:0;width:1px;height:1px;margin:0;",m="visibility:hidden;border:0;",n="style='"+k+"border:5px solid #000;padding:0;'",o="
"+""+"
",a=c.createElement("div"),a.style.cssText=m+"width:0;height:0;position:static;top:0;margin-top:"+j+"px",r.insertBefore(a,r.firstChild),q=c.createElement("div"),a.appendChild(q),q.innerHTML="
t
",l=q.getElementsByTagName("td"),p=l[0].offsetHeight===0,l[0].style.display="",l[1].style.display="none",b.reliableHiddenOffsets=p&&l[0].offsetHeight===0,q.innerHTML="",q.style.width=q.style.paddingLeft="1px",f.boxModel=b.boxModel=q.offsetWidth===2,typeof q.style.zoom!="undefined"&&(q.style.display="inline",q.style.zoom=1,b.inlineBlockNeedsLayout=q.offsetWidth===2,q.style.display="",q.innerHTML="
",b.shrinkWrapBlocks=q.offsetWidth!==2),q.style.cssText=k+m,q.innerHTML=o,d=q.firstChild,e=d.firstChild,h=d.nextSibling.firstChild.firstChild,i={doesNotAddBorder:e.offsetTop!==5,doesAddBorderForTableAndCells:h.offsetTop===5},e.style.position="fixed",e.style.top="20px",i.fixedPosition=e.offsetTop===20||e.offsetTop===15,e.style.position=e.style.top="",d.style.overflow="hidden",d.style.position="relative",i.subtractsBorderForOverflowNotVisible=e.offsetTop===-5,i.doesNotIncludeMarginInBodyOffset=r.offsetTop!==j,r.removeChild(a),q=a=null,f.extend(b,i))});return b}();var j=/^(?:\{.*\}|\[.*\])$/,k=/([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!m(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g,h,i,j=f.expando,k=typeof c=="string",l=a.nodeType,m=l?f.cache:a,n=l?a[j]:a[j]&&j,o=c==="events";if((!n||!m[n]||!o&&!e&&!m[n].data)&&k&&d===b)return;n||(l?a[j]=n=++f.uuid:n=j),m[n]||(m[n]={},l||(m[n].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?m[n]=f.extend(m[n],c):m[n].data=f.extend(m[n].data,c);g=h=m[n],e||(h.data||(h.data={}),h=h.data),d!==b&&(h[f.camelCase(c)]=d);if(o&&!h[c])return g.events;k?(i=h[c],i==null&&(i=h[f.camelCase(c)])):i=h;return i}},removeData:function(a,b,c){if(!!f.acceptData(a)){var d,e,g,h=f.expando,i=a.nodeType,j=i?f.cache:a,k=i?a[h]:h;if(!j[k])return;if(b){d=c?j[k]:j[k].data;if(d){f.isArray(b)||(b in d?b=[b]:(b=f.camelCase(b),b in d?b=[b]:b=b.split(" ")));for(e=0,g=b.length;e-1)return!0;return!1},val:function(a){var c,d,e,g=this[0];{if(!!arguments.length){e=f.isFunction(a);return this.each(function(d){var g=f(this),h;if(this.nodeType===1){e?h=a.call(this,d,g.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.nodeName.toLowerCase()]||f.valHooks[this.type];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}if(g){c=f.valHooks[g.nodeName.toLowerCase()]||f.valHooks[g.type];if(c&&"get"in c&&(d=c.get(g,"value"))!==b)return d;d=g.value;return typeof d=="string"?d.replace(q,""):d==null?"":d}}}}),f.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c,d,e,g=a.selectedIndex,h=[],i=a.options,j=a.type==="select-one";if(g<0)return null;c=j?g:0,d=j?g+1:i.length;for(;c=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attr:function(a,c,d,e){var g,h,i,j=a.nodeType;if(!!a&&j!==3&&j!==8&&j!==2){if(e&&c in f.attrFn)return f(a)[c](d);if(typeof a.getAttribute=="undefined")return f.prop(a,c,d);i=j!==1||!f.isXMLDoc(a),i&&(c=c.toLowerCase(),h=f.attrHooks[c]||(u.test(c)?x:w));if(d!==b){if(d===null){f.removeAttr(a,c);return}if(h&&"set"in h&&i&&(g=h.set(a,d,c))!==b)return g;a.setAttribute(c,""+d);return d}if(h&&"get"in h&&i&&(g=h.get(a,c))!==null)return g;g=a.getAttribute(c);return g===null?b:g}},removeAttr:function(a,b){var c,d,e,g,h=0;if(b&&a.nodeType===1){d=b.toLowerCase().split(p),g=d.length;for(;h=0}})});var z=/^(?:textarea|input|select)$/i,A=/^([^\.]*)?(?:\.(.+))?$/,B=/\bhover(\.\S+)?\b/,C=/^key/,D=/^(?:mouse|contextmenu)|click/,E=/^(?:focusinfocus|focusoutblur)$/,F=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,G=function(a){var b=F.exec(a);b&&(b[1]=(b[1]||"").toLowerCase(),b[3]=b[3]&&new RegExp("(?:^|\\s)"+b[3]+"(?:\\s|$)"));return b},H=function(a,b){var c=a.attributes||{};return(!b[1]||a.nodeName.toLowerCase()===b[1])&&(!b[2]||(c.id||{}).value===b[2])&&(!b[3]||b[3].test((c["class"]||{}).value))},I=function(a){return f.event.special.hover?a:a.replace(B,"mouseenter$1 mouseleave$1")}; +f.event={add:function(a,c,d,e,g){var h,i,j,k,l,m,n,o,p,q,r,s;if(!(a.nodeType===3||a.nodeType===8||!c||!d||!(h=f._data(a)))){d.handler&&(p=d,d=p.handler),d.guid||(d.guid=f.guid++),j=h.events,j||(h.events=j={}),i=h.handle,i||(h.handle=i=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.dispatch.apply(i.elem,arguments):b},i.elem=a),c=f.trim(I(c)).split(" ");for(k=0;k=0&&(h=h.slice(0,-1),k=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.shift(),i.sort());if((!e||f.event.customEvent[h])&&!f.event.global[h])return;c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.isTrigger=!0,c.exclusive=k,c.namespace=i.join("."),c.namespace_re=c.namespace?new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)"):null,o=h.indexOf(":")<0?"on"+h:"";if(!e){j=f.cache;for(l in j)j[l].events&&j[l].events[h]&&f.event.trigger(c,d,j[l].handle.elem,!0);return}c.result=b,c.target||(c.target=e),d=d!=null?f.makeArray(d):[],d.unshift(c),p=f.event.special[h]||{};if(p.trigger&&p.trigger.apply(e,d)===!1)return;r=[[e,p.bindType||h]];if(!g&&!p.noBubble&&!f.isWindow(e)){s=p.delegateType||h,m=E.test(s+h)?e:e.parentNode,n=null;for(;m;m=m.parentNode)r.push([m,s]),n=m;n&&n===e.ownerDocument&&r.push([n.defaultView||n.parentWindow||a,s])}for(l=0;le&&i.push({elem:this,matches:d.slice(e)});for(j=0;j0?this.on(b,null,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0),C.test(b)&&(f.event.fixHooks[b]=f.event.keyHooks),D.test(b)&&(f.event.fixHooks[b]=f.event.mouseHooks)}),function(){function x(a,b,c,e,f,g){for(var h=0,i=e.length;h0){k=j;break}}j=j[a]}e[h]=k}}}function w(a,b,c,e,f,g){for(var h=0,i=e.length;h+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d="sizcache"+(Math.random()+"").replace(".",""),e=0,g=Object.prototype.toString,h=!1,i=!0,j=/\\/g,k=/\r\n/g,l=/\W/;[0,0].sort(function(){i=!1;return 0});var m=function(b,d,e,f){e=e||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return e;var i,j,k,l,n,q,r,t,u=!0,v=m.isXML(d),w=[],x=b;do{a.exec(""),i=a.exec(x);if(i){x=i[3],w.push(i[1]);if(i[2]){l=i[3];break}}}while(i);if(w.length>1&&p.exec(b))if(w.length===2&&o.relative[w[0]])j=y(w[0]+w[1],d,f);else{j=o.relative[w[0]]?[d]:m(w.shift(),d);while(w.length)b=w.shift(),o.relative[b]&&(b+=w.shift()),j=y(b,j,f)}else{!f&&w.length>1&&d.nodeType===9&&!v&&o.match.ID.test(w[0])&&!o.match.ID.test(w[w.length-1])&&(n=m.find(w.shift(),d,v),d=n.expr?m.filter(n.expr,n.set)[0]:n.set[0]);if(d){n=f?{expr:w.pop(),set:s(f)}:m.find(w.pop(),w.length===1&&(w[0]==="~"||w[0]==="+")&&d.parentNode?d.parentNode:d,v),j=n.expr?m.filter(n.expr,n.set):n.set,w.length>0?k=s(j):u=!1;while(w.length)q=w.pop(),r=q,o.relative[q]?r=w.pop():q="",r==null&&(r=d),o.relative[q](k,r,v)}else k=w=[]}k||(k=j),k||m.error(q||b);if(g.call(k)==="[object Array]")if(!u)e.push.apply(e,k);else if(d&&d.nodeType===1)for(t=0;k[t]!=null;t++)k[t]&&(k[t]===!0||k[t].nodeType===1&&m.contains(d,k[t]))&&e.push(j[t]);else for(t=0;k[t]!=null;t++)k[t]&&k[t].nodeType===1&&e.push(j[t]);else s(k,e);l&&(m(l,h,e,f),m.uniqueSort(e));return e};m.uniqueSort=function(a){if(u){h=i,a.sort(u);if(h)for(var b=1;b0},m.find=function(a,b,c){var d,e,f,g,h,i;if(!a)return[];for(e=0,f=o.order.length;e":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!l.test(b)){b=b.toLowerCase();for(;e=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(j,"")},TAG:function(a,b){return a[1].replace(j,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||m.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&m.error(a[0]);a[0]=e++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(j,"");!f&&o.attrMap[g]&&(a[1]=o.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(j,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=m(b[3],null,null,c);else{var g=m.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(o.match.POS.test(b[0])||o.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!m(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return bc[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=o.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||n([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||!!a.nodeName&&a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=m.attr?m.attr(a,c):o.attrHandle[c]?o.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":!f&&m.attr?d!=null:f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=o.setFilters[e];if(f)return f(a,c,b,d)}}},p=o.match.POS,q=function(a,b){return"\\"+(b-0+1)};for(var r in o.match)o.match[r]=new RegExp(o.match[r].source+/(?![^\[]*\])(?![^\(]*\))/.source),o.leftMatch[r]=new RegExp(/(^(?:.|\r|\n)*?)/.source+o.match[r].source.replace(/\\(\d+)/g,q));var s=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(t){s=function(a,b){var c=0,d=b||[];if(g.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var e=a.length;c",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(o.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},o.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(o.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(o.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=m,b=c.createElement("div"),d="__sizzle__";b.innerHTML="

";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){m=function(b,e,f,g){e=e||c;if(!g&&!m.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return s(e.getElementsByTagName(b),f);if(h[2]&&o.find.CLASS&&e.getElementsByClassName)return s(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return s([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return s([],f);if(i.id===h[3])return s([i],f)}try{return s(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var k=e,l=e.getAttribute("id"),n=l||d,p=e.parentNode,q=/^\s*[+~]/.test(b);l?n=n.replace(/'/g,"\\$&"):e.setAttribute("id",n),q&&p&&(e=e.parentNode);try{if(!q||p)return s(e.querySelectorAll("[id='"+n+"'] "+b),f)}catch(r){}finally{l||k.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)m[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}m.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!m.isXML(a))try{if(e||!o.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return m(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="
";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;o.order.splice(1,0,"CLASS"),o.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?m.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?m.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:m.contains=function(){return!1},m.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var y=function(a,b,c){var d,e=[],f="",g=b.nodeType?[b]:b;while(d=o.match.PSEUDO.exec(a))f+=d[0],a=a.replace(o.match.PSEUDO,"");a=o.relative[a]?a+"*":a;for(var h=0,i=g.length;h0)for(h=g;h=0:f.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h=1;while(g&&g.ownerDocument&&g!==b){for(d=0;d-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a)return this[0]&&this[0].parentNode?this.prevAll().length:-1;if(typeof a=="string")return f.inArray(this[0],f(a));return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(S(c[0])||S(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling(a.parentNode.firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c);L.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!R[a]?f.unique(e):e,(this.length>1||N.test(d))&&M.test(a)&&(e=e.reverse());return this.pushStack(e,a,P.call(arguments).join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var V="abbr|article|aside|audio|canvas|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",W=/ jQuery\d+="(?:\d+|null)"/g,X=/^\s+/,Y=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,Z=/<([\w:]+)/,$=/",""],legend:[1,"
","
"],thead:[1,"","
"],tr:[2,"","
"],td:[3,"","
"],col:[2,"","
"],area:[1,"",""],_default:[0,"",""]},bh=U(c);bg.optgroup=bg.option,bg.tbody=bg.tfoot=bg.colgroup=bg.caption=bg.thead,bg.th=bg.td,f.support.htmlSerialize||(bg._default=[1,"div
","
"]),f.fn.extend({text:function(a){if(f.isFunction(a))return this.each(function(b){var c=f(this);c.text(a.call(this,b,c.text()))});if(typeof a!="object"&&a!==b)return this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a));return f.text(this)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=f.isFunction(a);return this.each(function(c){f(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f.clean(arguments);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,f.clean(arguments));return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")), +f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function() +{for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){if(a===b)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(W,""):null;if(typeof a=="string"&&!ba.test(a)&&(f.support.leadingWhitespace||!X.test(a))&&!bg[(Z.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Y,"<$1>");try{for(var c=0,d=this.length;c1&&l0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d,e,g,h=f.support.html5Clone||!bc.test("<"+a.nodeName)?a.cloneNode(!0):bo(a);if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bk(a,h),d=bl(a),e=bl(h);for(g=0;d[g];++g)e[g]&&bk(d[g],e[g])}if(b){bj(a,h);if(c){d=bl(a),e=bl(h);for(g=0;d[g];++g)bj(d[g],e[g])}}d=e=null;return h},clean:function(a,b,d,e){var g;b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);var h=[],i;for(var j=0,k;(k=a[j])!=null;j++){typeof k=="number"&&(k+="");if(!k)continue;if(typeof k=="string")if(!_.test(k))k=b.createTextNode(k);else{k=k.replace(Y,"<$1>");var l=(Z.exec(k)||["",""])[1].toLowerCase(),m=bg[l]||bg._default,n=m[0],o=b.createElement("div");b===c?bh.appendChild(o):U(b).appendChild(o),o.innerHTML=m[1]+k+m[2];while(n--)o=o.lastChild;if(!f.support.tbody){var p=$.test(k),q=l==="table"&&!p?o.firstChild&&o.firstChild.childNodes:m[1]===""&&!p?o.childNodes:[];for(i=q.length-1;i>=0;--i)f.nodeName(q[i],"tbody")&&!q[i].childNodes.length&&q[i].parentNode.removeChild(q[i])}!f.support.leadingWhitespace&&X.test(k)&&o.insertBefore(b.createTextNode(X.exec(k)[0]),o.firstChild),k=o.childNodes}var r;if(!f.support.appendChecked)if(k[0]&&typeof (r=k.length)=="number")for(i=0;i=0)return b+"px"}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return br.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=f.isNumeric(b)?"alpha(opacity="+b*100+")":"",g=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&f.trim(g.replace(bq,""))===""){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bq.test(g)?g.replace(bq,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){var c;f.swap(a,{display:"inline-block"},function(){b?c=bz(a,"margin-right","marginRight"):c=a.style.marginRight});return c}})}),c.defaultView&&c.defaultView.getComputedStyle&&(bA=function(a,b){var c,d,e;b=b.replace(bs,"-$1").toLowerCase(),(d=a.ownerDocument.defaultView)&&(e=d.getComputedStyle(a,null))&&(c=e.getPropertyValue(b),c===""&&!f.contains(a.ownerDocument.documentElement,a)&&(c=f.style(a,b)));return c}),c.documentElement.currentStyle&&(bB=function(a,b){var c,d,e,f=a.currentStyle&&a.currentStyle[b],g=a.style;f===null&&g&&(e=g[b])&&(f=e),!bt.test(f)&&bu.test(f)&&(c=g.left,d=a.runtimeStyle&&a.runtimeStyle.left,d&&(a.runtimeStyle.left=a.currentStyle.left),g.left=b==="fontSize"?"1em":f||0,f=g.pixelLeft+"px",g.left=c,d&&(a.runtimeStyle.left=d));return f===""?"auto":f}),bz=bA||bB,f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style&&a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)});var bD=/%20/g,bE=/\[\]$/,bF=/\r?\n/g,bG=/#.*$/,bH=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bI=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bJ=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,bK=/^(?:GET|HEAD)$/,bL=/^\/\//,bM=/\?/,bN=/)<[^<]*)*<\/script>/gi,bO=/^(?:select|textarea)/i,bP=/\s+/,bQ=/([?&])_=[^&]*/,bR=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bS=f.fn.load,bT={},bU={},bV,bW,bX=["*/"]+["*"];try{bV=e.href}catch(bY){bV=c.createElement("a"),bV.href="",bV=bV.href}bW=bR.exec(bV.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bS)return bS.apply(this,arguments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var g=a.slice(e,a.length);a=a.slice(0,e)}var h="GET";c&&(f.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=f.param(c,f.ajaxSettings.traditional),h="POST"));var i=this;f.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?f("
").append(c.replace(bN,"")).find(g):c)),d&&i.each(d,[c,b,a])}});return this},serialize:function(){return f.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?f.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bO.test(this.nodeName)||bI.test(this.type))}).map(function(a,b){var c=f(this).val();return c==null?null:f.isArray(c)?f.map(c,function(a,c){return{name:b.name,value:a.replace(bF,"\r\n")}}):{name:b.name,value:c.replace(bF,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.on(b,a)}}),f.each(["get","post"],function(a,c){f[c]=function(a,d,e,g){f.isFunction(d)&&(g=g||e,e=d,d=b);return f.ajax({type:c,url:a,data:d,success:e,dataType:g})}}),f.extend({getScript:function(a,c){return f.get(a,b,c,"script")},getJSON:function(a,b,c){return f.get(a,b,c,"json")},ajaxSetup:function(a,b){b?b_(a,f.ajaxSettings):(b=a,a=f.ajaxSettings),b_(a,b);return a},ajaxSettings:{url:bV,isLocal:bJ.test(bW[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":bX},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":f.parseJSON,"text xml":f.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:bZ(bT),ajaxTransport:bZ(bU),ajax:function(a,c){function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.readyState=a>0?4:0;var o,r,u,w=c,x=l?cb(d,v,l):b,y,z;if(a>=200&&a<300||a===304){if(d.ifModified){if(y=v.getResponseHeader("Last-Modified"))f.lastModified[k]=y;if(z=v.getResponseHeader("Etag"))f.etag[k]=z}if(a===304)w="notmodified",o=!0;else try{r=cc(d,x),w="success",o=!0}catch(A){w="parsererror",u=A}}else{u=w;if(!w||a)w="error",a<0&&(a=0)}v.status=a,v.statusText=""+(c||w),o?h.resolveWith(e,[r,w,v]):h.rejectWith(e,[v,w,u]),v.statusCode(j),j=b,t&&g.trigger("ajax"+(o?"Success":"Error"),[v,d,o?r:u]),i.fireWith(e,[v,w]),t&&(g.trigger("ajaxComplete",[v,d]),--f.active||f.event.trigger("ajaxStop"))}}typeof a=="object"&&(c=a,a=b),c=c||{};var d=f.ajaxSetup({},c),e=d.context||d,g=e!==d&&(e.nodeType||e instanceof f)?f(e):f.event,h=f.Deferred(),i=f.Callbacks("once memory"),j=d.statusCode||{},k,l={},m={},n,o,p,q,r,s=0,t,u,v={readyState:0,setRequestHeader:function(a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this},getAllResponseHeaders:function(){return s===2?n:null},getResponseHeader:function(a){var c;if(s===2){if(!o){o={};while(c=bH.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){s||(d.mimeType=a);return this},abort:function(a){a=a||"abort",p&&p.abort(a),w(0,a);return this}};h.promise(v),v.success=v.done,v.error=v.fail,v.complete=i.add,v.statusCode=function(a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this},d.url=((a||d.url)+"").replace(bG,"").replace(bL,bW[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bP),d.crossDomain==null&&(r=bR.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bW[1]&&r[2]==bW[2]&&(r[3]||(r[1]==="http:"?80:443))==(bW[3]||(bW[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),b$(bT,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bK.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bM.test(d.url)?"&":"?")+d.data,delete d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bQ,"$1_="+x);d.url=y+(y===d.url?(bM.test(d.url)?"&":"?")+"_="+x:"")}}(d.data&&d.hasContent&&d.contentType!==!1||c.contentType)&&v.setRequestHeader("Content-Type",d.contentType),d.ifModified&&(k=k||d.url,f.lastModified[k]&&v.setRequestHeader("If-Modified-Since",f.lastModified[k]),f.etag[k]&&v.setRequestHeader("If-None-Match",f.etag[k])),v.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(d.dataTypes[0]!=="*"?", "+bX+"; q=0.01":""):d.accepts["*"]);for(u in d.headers)v.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(d.beforeSend.call(e,v,d)===!1||s===2)){v.abort();return!1}for(u in{success:1,error:1,complete:1})v[u](d[u]);p=b$(bU,d,c,v);if(!p)w(-1,"No Transport");else{v.readyState=1,t&&g.trigger("ajaxSend",[v,d]),d.async&&d.timeout>0&&(q=setTimeout(function(){v.abort("timeout")},d.timeout));try{s=1,p.send(l,w)}catch(z){if(s<2)w(-1,z);else throw z}}return v},param:function(a,c){var d=[],e=function(a,b){b=f.isFunction(b)?b():b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=f.ajaxSettings.traditional);if(f.isArray(a)||a.jquery&&!f.isPlainObject(a))f.each(a,function(){e(this.name,this.value)});else for(var g in a)ca(g,a[g],c,e);return d.join("&").replace(bD,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var cd=f.now(),ce=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+cd++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=b.contentType==="application/x-www-form-urlencoded"&&typeof b.data=="string";if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(ce.test(b.url)||e&&ce.test(b.data))){var g,h=b.jsonpCallback=f.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2";b.jsonp!==!1&&(j=j.replace(ce,l),b.url===j&&(e&&(k=k.replace(ce,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},d.always(function(){a[h]=i,g&&f.isFunction(i)&&a[h](g[0])}),b.converters["script json"]=function(){g||f.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),f.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){f.globalEval(a);return a}}}),f.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),f.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(c||!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var cf=a.ActiveXObject?function(){for(var a in ch)ch[a](0,1)}:!1,cg=0,ch;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ci()||cj()}:ci,function(a){f.extend(f.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(f.ajaxSettings.xhr()),f.support.ajax&&f.ajaxTransport(function(c) +{if(!c.crossDomain||f.support.cors){var d;return{send:function(e,g){var h=c.xhr(),i,j;c.username?h.open(c.type,c.url,c.async,c.username,c.password):h.open(c.type,c.url,c.async);if(c.xhrFields)for(j in c.xhrFields)h[j]=c.xhrFields[j];c.mimeType&&h.overrideMimeType&&h.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(j in e)h.setRequestHeader(j,e[j])}catch(k){}h.send(c.hasContent&&c.data||null),d=function(a,e){var j,k,l,m,n;try{if(d&&(e||h.readyState===4)){d=b,i&&(h.onreadystatechange=f.noop,cf&&delete ch[i]);if(e)h.readyState!==4&&h.abort();else{j=h.status,l=h.getAllResponseHeaders(),m={},n=h.responseXML,n&&n.documentElement&&(m.xml=n),m.text=h.responseText;try{k=h.statusText}catch(o){k=""}!j&&c.isLocal&&!c.crossDomain?j=m.text?200:404:j===1223&&(j=204)}}}catch(p){e||g(-1,p)}m&&g(j,k,m,l)},!c.async||h.readyState===4?d():(i=++cg,cf&&(ch||(ch={},f(a).unload(cf)),ch[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var ck={},cl,cm,cn=/^(?:toggle|show|hide)$/,co=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,cp,cq=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],cr;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(cu("show",3),a,b,c);for(var g=0,h=this.length;g=i.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),i.animatedProperties[this.prop]=!0;for(b in i.animatedProperties)i.animatedProperties[b]!==!0&&(g=!1);if(g){i.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){h.style["overflow"+b]=i.overflow[a]}),i.hide&&f(h).hide();if(i.hide||i.show)for(b in i.animatedProperties)f.style(h,b,i.orig[b]),f.removeData(h,"fxshow"+b,!0),f.removeData(h,"toggle"+b,!0);d=i.complete,d&&(i.complete=!1,d.call(h))}return!1}i.duration==Infinity?this.now=e:(c=e-this.startTime,this.state=c/i.duration,this.pos=f.easing[i.animatedProperties[this.prop]](this.state,c,0,1,i.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){var a,b=f.timers,c=0;for(;c-1,k={},l={},m,n;j?(l=e.position(),m=l.top,n=l.left):(m=parseFloat(h)||0,n=parseFloat(i)||0),f.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):e.css(k)}},f.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),d=cx.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(f.css(a,"marginTop"))||0,c.left-=parseFloat(f.css(a,"marginLeft"))||0,d.top+=parseFloat(f.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(f.css(b[0],"borderLeftWidth"))||0;return{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&!cx.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each(["Left","Top"],function(a,c){var d="scroll"+c;f.fn[d]=function(c){var e,g;if(c===b){e=this[0];if(!e)return null;g=cy(e);return g?"pageXOffset"in g?g[a?"pageYOffset":"pageXOffset"]:f.support.boxModel&&g.document.documentElement[d]||g.document.body[d]:e[d]}return this.each(function(){g=cy(this),g?g.scrollTo(a?f(g).scrollLeft():c,a?c:f(g).scrollTop()):this[d]=c})}}),f.each(["Height","Width"],function(a,c){var d=c.toLowerCase();f.fn["inner"+c]=function(){var a=this[0];return a?a.style?parseFloat(f.css(a,d,"padding")):this[d]():null},f.fn["outer"+c]=function(a){var b=this[0];return b?b.style?parseFloat(f.css(b,d,a?"margin":"border")):this[d]():null},f.fn[d]=function(a){var e=this[0];if(!e)return a==null?null:this;if(f.isFunction(a))return this.each(function(b){var c=f(this);c[d](a.call(this,b,c[d]()))});if(f.isWindow(e)){var g=e.document.documentElement["client"+c],h=e.document.body;return e.document.compatMode==="CSS1Compat"&&g||h&&h["client"+c]||g}if(e.nodeType===9)return Math.max(e.documentElement["client"+c],e.body["scroll"+c],e.documentElement["scroll"+c],e.body["offset"+c],e.documentElement["offset"+c]);if(a===b){var i=f.css(e,d),j=parseFloat(i);return f.isNumeric(j)?j:i}return this.css(d,typeof a=="string"?a:a+"px")}}),a.jQuery=a.$=f,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return f})})(window); diff --git a/ThirdParty/Qwt/doc/html/knob.png b/ThirdParty/Qwt/doc/html/knob.png new file mode 100644 index 0000000000..f76089f6e2 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/knob.png differ diff --git a/ThirdParty/Qwt/doc/html/nav_f.png b/ThirdParty/Qwt/doc/html/nav_f.png new file mode 100644 index 0000000000..72a58a529e Binary files /dev/null and b/ThirdParty/Qwt/doc/html/nav_f.png differ diff --git a/ThirdParty/Qwt/doc/html/nav_g.png b/ThirdParty/Qwt/doc/html/nav_g.png new file mode 100644 index 0000000000..2093a237a9 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/nav_g.png differ diff --git a/ThirdParty/Qwt/doc/html/nav_h.png b/ThirdParty/Qwt/doc/html/nav_h.png new file mode 100644 index 0000000000..33389b101d Binary files /dev/null and b/ThirdParty/Qwt/doc/html/nav_h.png differ diff --git a/ThirdParty/Qwt/doc/html/open.png b/ThirdParty/Qwt/doc/html/open.png new file mode 100644 index 0000000000..30f75c7efe Binary files /dev/null and b/ThirdParty/Qwt/doc/html/open.png differ diff --git a/ThirdParty/Qwt/doc/html/pages.html b/ThirdParty/Qwt/doc/html/pages.html new file mode 100644 index 0000000000..a00f30fbda --- /dev/null +++ b/ThirdParty/Qwt/doc/html/pages.html @@ -0,0 +1,101 @@ + + + + + + +Qwt User's Guide: Related Pages + + + + + + + + + +
+
+
+ + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+ + + + + + + + + + +
+ +
+ +
+
+
Related Pages
+
+ + + + + diff --git a/ThirdParty/Qwt/doc/html/plot.png b/ThirdParty/Qwt/doc/html/plot.png new file mode 100644 index 0000000000..d0881034df Binary files /dev/null and b/ThirdParty/Qwt/doc/html/plot.png differ diff --git a/ThirdParty/Qwt/doc/html/qwt__abstract__legend_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__abstract__legend_8h_source.html new file mode 100644 index 0000000000..d61e3648aa --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__abstract__legend_8h_source.html @@ -0,0 +1,134 @@ + + + + + + +Qwt User's Guide: qwt_abstract_legend.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_abstract_legend.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_ABSTRACT_LEGEND_H
+
11 #define QWT_ABSTRACT_LEGEND_H
+
12 
+
13 #include "qwt_global.h"
+
14 #include "qwt_legend_data.h"
+
15 #include <qframe.h>
+
16 #include <qlist.h>
+
17 
+
18 class QVariant;
+
19 
+
34 class QWT_EXPORT QwtAbstractLegend : public QFrame
+
35 {
+
36  Q_OBJECT
+
37 
+
38 public:
+
39  explicit QwtAbstractLegend( QWidget *parent = NULL );
+
40  virtual ~QwtAbstractLegend();
+
41 
+
51  virtual void renderLegend( QPainter *painter,
+
52  const QRectF &rect, bool fillBackground ) const = 0;
+
53 
+
55  virtual bool isEmpty() const = 0;
+
56 
+
57  virtual int scrollExtent( Qt::Orientation ) const;
+
58 
+
59 public Q_SLOTS:
+
60 
+
67  virtual void updateLegend( const QVariant &itemInfo,
+
68  const QList<QwtLegendData> &data ) = 0;
+
69 };
+
70 
+
71 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__abstract__scale_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__abstract__scale_8h_source.html new file mode 100644 index 0000000000..9d37e0dfbe --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__abstract__scale_8h_source.html @@ -0,0 +1,184 @@ + + + + + + +Qwt User's Guide: qwt_abstract_scale.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_abstract_scale.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_ABSTRACT_SCALE_H
+
11 #define QWT_ABSTRACT_SCALE_H
+
12 
+
13 #include "qwt_global.h"
+
14 #include <qwidget.h>
+
15 
+
16 class QwtScaleEngine;
+ +
18 class QwtScaleDiv;
+
19 class QwtScaleMap;
+
20 class QwtInterval;
+
21 
+
36 class QWT_EXPORT QwtAbstractScale: public QWidget
+
37 {
+
38  Q_OBJECT
+
39 
+
40  Q_PROPERTY( double lowerBound READ lowerBound WRITE setLowerBound )
+
41  Q_PROPERTY( double upperBound READ upperBound WRITE setUpperBound )
+
42 
+
43  Q_PROPERTY( int scaleMaxMajor READ scaleMaxMajor WRITE setScaleMaxMajor )
+
44  Q_PROPERTY( int scaleMaxMinor READ scaleMaxMinor WRITE setScaleMaxMinor )
+
45 
+
46  Q_PROPERTY( double scaleStepSize READ scaleStepSize WRITE setScaleStepSize )
+
47 
+
48 public:
+
49  QwtAbstractScale( QWidget *parent = NULL );
+
50  virtual ~QwtAbstractScale();
+
51 
+
52  void setScale( double lowerBound, double upperBound );
+
53  void setScale( const QwtInterval & );
+
54  void setScale( const QwtScaleDiv & );
+
55 
+
56  const QwtScaleDiv& scaleDiv() const;
+
57 
+
58  void setLowerBound( double value );
+
59  double lowerBound() const;
+
60 
+
61  void setUpperBound( double value );
+
62  double upperBound() const;
+
63 
+
64  void setScaleStepSize( double stepSize );
+
65  double scaleStepSize() const;
+
66 
+
67  void setScaleMaxMajor( int ticks );
+
68  int scaleMaxMinor() const;
+
69 
+
70  void setScaleMaxMinor( int ticks );
+
71  int scaleMaxMajor() const;
+
72 
+
73  void setScaleEngine( QwtScaleEngine * );
+
74  const QwtScaleEngine *scaleEngine() const;
+
75  QwtScaleEngine *scaleEngine();
+
76 
+
77  int transform( double ) const;
+
78  double invTransform( int ) const;
+
79 
+
80  bool isInverted() const;
+
81 
+
82  double minimum() const;
+
83  double maximum() const;
+
84 
+
85  const QwtScaleMap &scaleMap() const;
+
86 
+
87 protected:
+
88  void rescale( double lowerBound,
+
89  double upperBound, double stepSize );
+
90 
+
91  void setAbstractScaleDraw( QwtAbstractScaleDraw * );
+
92 
+
93  const QwtAbstractScaleDraw *abstractScaleDraw() const;
+
94  QwtAbstractScaleDraw *abstractScaleDraw();
+
95 
+
96  virtual void scaleChange();
+
97 
+
98 private:
+
99  void updateScaleDraw();
+
100 
+
101  class PrivateData;
+
102  PrivateData *d_data;
+
103 };
+
104 
+
105 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__abstract__scale__draw_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__abstract__scale__draw_8h_source.html new file mode 100644 index 0000000000..9ca21b4c81 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__abstract__scale__draw_8h_source.html @@ -0,0 +1,183 @@ + + + + + + +Qwt User's Guide: qwt_abstract_scale_draw.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_abstract_scale_draw.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_ABSTRACT_SCALE_DRAW_H
+
11 #define QWT_ABSTRACT_SCALE_DRAW_H
+
12 
+
13 #include "qwt_global.h"
+
14 #include "qwt_scale_div.h"
+
15 #include "qwt_text.h"
+
16 
+
17 class QPalette;
+
18 class QPainter;
+
19 class QFont;
+
20 class QwtTransform;
+
21 class QwtScaleMap;
+
22 
+
31 class QWT_EXPORT QwtAbstractScaleDraw
+
32 {
+
33 public:
+
34 
+ +
40  {
+
42  Backbone = 0x01,
+
43 
+
45  Ticks = 0x02,
+
46 
+
48  Labels = 0x04
+
49  };
+
50 
+
52  typedef QFlags<ScaleComponent> ScaleComponents;
+
53 
+ +
55  virtual ~QwtAbstractScaleDraw();
+
56 
+
57  void setScaleDiv( const QwtScaleDiv &s );
+
58  const QwtScaleDiv& scaleDiv() const;
+
59 
+
60  void setTransformation( QwtTransform * );
+
61  const QwtScaleMap &scaleMap() const;
+
62  QwtScaleMap &scaleMap();
+
63 
+
64  void enableComponent( ScaleComponent, bool enable = true );
+
65  bool hasComponent( ScaleComponent ) const;
+
66 
+
67  void setTickLength( QwtScaleDiv::TickType, double length );
+
68  double tickLength( QwtScaleDiv::TickType ) const;
+
69  double maxTickLength() const;
+
70 
+
71  void setSpacing( double margin );
+
72  double spacing() const;
+
73 
+
74  void setPenWidth( int width );
+
75  int penWidth() const;
+
76 
+
77  virtual void draw( QPainter *, const QPalette & ) const;
+
78 
+
79  virtual QwtText label( double ) const;
+
80 
+
93  virtual double extent( const QFont &font ) const = 0;
+
94 
+
95  void setMinimumExtent( double );
+
96  double minimumExtent() const;
+
97 
+
98 protected:
+
108  virtual void drawTick( QPainter *painter, double value, double len ) const = 0;
+
109 
+
116  virtual void drawBackbone( QPainter *painter ) const = 0;
+
117 
+
126  virtual void drawLabel( QPainter *painter, double value ) const = 0;
+
127 
+
128  void invalidateCache();
+
129  const QwtText &tickLabel( const QFont &, double value ) const;
+
130 
+
131 private:
+ +
133  QwtAbstractScaleDraw &operator=( const QwtAbstractScaleDraw & );
+
134 
+
135  class PrivateData;
+
136  PrivateData *d_data;
+
137 };
+
138 
+
139 Q_DECLARE_OPERATORS_FOR_FLAGS( QwtAbstractScaleDraw::ScaleComponents )
+
140 
+
141 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__abstract__slider_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__abstract__slider_8h_source.html new file mode 100644 index 0000000000..fd1dc3f7bb --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__abstract__slider_8h_source.html @@ -0,0 +1,201 @@ + + + + + + +Qwt User's Guide: qwt_abstract_slider.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_abstract_slider.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_ABSTRACT_SLIDER_H
+
11 #define QWT_ABSTRACT_SLIDER_H
+
12 
+
13 #include "qwt_global.h"
+
14 #include "qwt_abstract_scale.h"
+
15 
+
32 class QWT_EXPORT QwtAbstractSlider: public QwtAbstractScale
+
33 {
+
34  Q_OBJECT
+
35 
+
36  Q_PROPERTY( double value READ value WRITE setValue )
+
37 
+
38  Q_PROPERTY( uint totalSteps READ totalSteps WRITE setTotalSteps )
+
39  Q_PROPERTY( uint singleSteps READ singleSteps WRITE setSingleSteps )
+
40  Q_PROPERTY( uint pageSteps READ pageSteps WRITE setPageSteps )
+
41  Q_PROPERTY( bool stepAlignment READ stepAlignment WRITE setStepAlignment )
+
42 
+
43  Q_PROPERTY( bool readOnly READ isReadOnly WRITE setReadOnly )
+
44  Q_PROPERTY( bool tracking READ isTracking WRITE setTracking )
+
45  Q_PROPERTY( bool wrapping READ wrapping WRITE setWrapping )
+
46 
+
47  Q_PROPERTY( bool invertedControls READ invertedControls WRITE setInvertedControls )
+
48 
+
49 public:
+
50  explicit QwtAbstractSlider( QWidget *parent = NULL );
+
51  virtual ~QwtAbstractSlider();
+
52 
+
53  void setValid( bool );
+
54  bool isValid() const;
+
55 
+
56  double value() const;
+
57 
+
58  void setWrapping( bool );
+
59  bool wrapping() const;
+
60 
+
61  void setTotalSteps( uint );
+
62  uint totalSteps() const;
+
63 
+
64  void setSingleSteps( uint );
+
65  uint singleSteps() const;
+
66 
+
67  void setPageSteps( uint );
+
68  uint pageSteps() const;
+
69 
+
70  void setStepAlignment( bool );
+
71  bool stepAlignment() const;
+
72 
+
73  void setTracking( bool );
+
74  bool isTracking() const;
+
75 
+
76  void setReadOnly( bool );
+
77  bool isReadOnly() const;
+
78 
+
79  void setInvertedControls( bool );
+
80  bool invertedControls() const;
+
81 
+
82 public Q_SLOTS:
+
83  void setValue( double val );
+
84 
+
85 Q_SIGNALS:
+
86 
+
97  void valueChanged( double value );
+
98 
+
103  void sliderPressed();
+
104 
+
109  void sliderReleased();
+
110 
+
119  void sliderMoved( double value );
+
120 
+
121 protected:
+
122  virtual void mousePressEvent( QMouseEvent * );
+
123  virtual void mouseReleaseEvent( QMouseEvent * );
+
124  virtual void mouseMoveEvent( QMouseEvent * );
+
125  virtual void keyPressEvent( QKeyEvent * );
+
126  virtual void wheelEvent( QWheelEvent * );
+
127 
+
136  virtual bool isScrollPosition( const QPoint &pos ) const = 0;
+
137 
+
147  virtual double scrolledTo( const QPoint &pos ) const = 0;
+
148 
+
149  void incrementValue( int numSteps );
+
150 
+
151  virtual void scaleChange();
+
152 
+
153 protected:
+
154  virtual void sliderChange();
+
155 
+
156  double incrementedValue(
+
157  double value, int stepCount ) const;
+
158 
+
159 private:
+
160  double alignedValue( double ) const;
+
161  double boundedValue( double ) const;
+
162 
+
163  class PrivateData;
+
164  PrivateData *d_data;
+
165 };
+
166 
+
167 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__analog__clock_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__analog__clock_8h_source.html new file mode 100644 index 0000000000..e6be63a7cd --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__analog__clock_8h_source.html @@ -0,0 +1,153 @@ + + + + + + +Qwt User's Guide: qwt_analog_clock.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_analog_clock.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_ANALOG_CLOCK_H
+
11 #define QWT_ANALOG_CLOCK_H
+
12 
+
13 #include "qwt_global.h"
+
14 #include "qwt_dial.h"
+
15 #include "qwt_dial_needle.h"
+
16 #include <qdatetime.h>
+
17 
+
43 class QWT_EXPORT QwtAnalogClock: public QwtDial
+
44 {
+
45  Q_OBJECT
+
46 
+
47 public:
+
52  enum Hand
+
53  {
+ +
56 
+ +
59 
+ +
62 
+
64  NHands
+
65  };
+
66 
+
67  explicit QwtAnalogClock( QWidget* parent = NULL );
+
68  virtual ~QwtAnalogClock();
+
69 
+
70  void setHand( Hand, QwtDialNeedle * );
+
71 
+
72  const QwtDialNeedle *hand( Hand ) const;
+
73  QwtDialNeedle *hand( Hand );
+
74 
+
75 public Q_SLOTS:
+
76  void setCurrentTime();
+
77  void setTime( const QTime & );
+
78 
+
79 protected:
+
80  virtual void drawNeedle( QPainter *, const QPointF &,
+
81  double radius, double direction, QPalette::ColorGroup ) const;
+
82 
+
83  virtual void drawHand( QPainter *, Hand, const QPointF &,
+
84  double radius, double direction, QPalette::ColorGroup ) const;
+
85 
+
86 private:
+
87  // use setHand instead
+
88  void setNeedle( QwtDialNeedle * );
+
89 
+
90  QwtDialNeedle *d_hand[NHands];
+
91 };
+
92 
+
93 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__arrow__button_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__arrow__button_8h_source.html new file mode 100644 index 0000000000..7bd47311d0 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__arrow__button_8h_source.html @@ -0,0 +1,138 @@ + + + + + + +Qwt User's Guide: qwt_arrow_button.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_arrow_button.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_ARROW_BUTTON_H
+
11 #define QWT_ARROW_BUTTON_H
+
12 
+
13 #include "qwt_global.h"
+
14 #include <qpushbutton.h>
+
15 
+
23 class QWT_EXPORT QwtArrowButton : public QPushButton
+
24 {
+
25 public:
+
26  explicit QwtArrowButton ( int num, Qt::ArrowType, QWidget *parent = NULL );
+
27  virtual ~QwtArrowButton();
+
28 
+
29  Qt::ArrowType arrowType() const;
+
30  int num() const;
+
31 
+
32  virtual QSize sizeHint() const;
+
33  virtual QSize minimumSizeHint() const;
+
34 
+
35 protected:
+
36  virtual void paintEvent( QPaintEvent *event );
+
37 
+
38  virtual void drawButtonLabel( QPainter *p );
+
39  virtual void drawArrow( QPainter *,
+
40  const QRect &, Qt::ArrowType ) const;
+
41  virtual QRect labelRect() const;
+
42  virtual QSize arrowSize( Qt::ArrowType,
+
43  const QSize &boundingSize ) const;
+
44 
+
45  virtual void keyPressEvent( QKeyEvent * );
+
46 
+
47 private:
+
48  class PrivateData;
+
49  PrivateData *d_data;
+
50 };
+
51 
+
52 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__clipper_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__clipper_8h_source.html new file mode 100644 index 0000000000..c69cca8491 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__clipper_8h_source.html @@ -0,0 +1,129 @@ + + + + + + +Qwt User's Guide: qwt_clipper.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_clipper.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_CLIPPER_H
+
11 #define QWT_CLIPPER_H
+
12 
+
13 #include "qwt_global.h"
+
14 #include "qwt_interval.h"
+
15 #include <qpolygon.h>
+
16 #include <qvector.h>
+
17 
+
18 class QRect;
+
19 class QRectF;
+
20 
+
25 class QWT_EXPORT QwtClipper
+
26 {
+
27 public:
+
28  static QPolygon clipPolygon( const QRect &,
+
29  const QPolygon &, bool closePolygon = false );
+
30  static QPolygon clipPolygon( const QRectF &,
+
31  const QPolygon &, bool closePolygon = false );
+
32 
+
33  static QPolygonF clipPolygonF( const QRectF &,
+
34  const QPolygonF &, bool closePolygon = false );
+
35 
+
36  static QVector<QwtInterval> clipCircle(
+
37  const QRectF &, const QPointF &, double radius );
+
38 };
+
39 
+
40 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__color__map_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__color__map_8h_source.html new file mode 100644 index 0000000000..b701cd4f42 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__color__map_8h_source.html @@ -0,0 +1,222 @@ + + + + + + +Qwt User's Guide: qwt_color_map.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_color_map.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_COLOR_MAP_H
+
11 #define QWT_COLOR_MAP_H
+
12 
+
13 #include "qwt_global.h"
+
14 #include "qwt_interval.h"
+
15 #include <qcolor.h>
+
16 #include <qvector.h>
+
17 
+
33 class QWT_EXPORT QwtColorMap
+
34 {
+
35 public:
+
41  enum Format
+
42  {
+
44  RGB,
+
45 
+
50  Indexed
+
51  };
+
52 
+
53  QwtColorMap( Format = QwtColorMap::RGB );
+
54  virtual ~QwtColorMap();
+
55 
+
56  Format format() const;
+
57 
+
65  virtual QRgb rgb( const QwtInterval &interval,
+
66  double value ) const = 0;
+
67 
+
75  virtual unsigned char colorIndex(
+
76  const QwtInterval &interval, double value ) const = 0;
+
77 
+
78  QColor color( const QwtInterval &, double value ) const;
+
79  virtual QVector<QRgb> colorTable( const QwtInterval & ) const;
+
80 
+
81 private:
+
82  Format d_format;
+
83 };
+
84 
+
92 class QWT_EXPORT QwtLinearColorMap: public QwtColorMap
+
93 {
+
94 public:
+
99  enum Mode
+
100  {
+ +
103 
+
105  ScaledColors
+
106  };
+
107 
+ +
109  QwtLinearColorMap( const QColor &from, const QColor &to,
+ +
111 
+
112  virtual ~QwtLinearColorMap();
+
113 
+
114  void setMode( Mode );
+
115  Mode mode() const;
+
116 
+
117  void setColorInterval( const QColor &color1, const QColor &color2 );
+
118  void addColorStop( double value, const QColor& );
+
119  QVector<double> colorStops() const;
+
120 
+
121  QColor color1() const;
+
122  QColor color2() const;
+
123 
+
124  virtual QRgb rgb( const QwtInterval &, double value ) const;
+
125  virtual unsigned char colorIndex(
+
126  const QwtInterval &, double value ) const;
+
127 
+
128  class ColorStops;
+
129 
+
130 private:
+
131  // Disabled copy constructor and operator=
+ +
133  QwtLinearColorMap &operator=( const QwtLinearColorMap & );
+
134 
+
135  class PrivateData;
+
136  PrivateData *d_data;
+
137 };
+
138 
+
142 class QWT_EXPORT QwtAlphaColorMap: public QwtColorMap
+
143 {
+
144 public:
+
145  QwtAlphaColorMap( const QColor & = QColor( Qt::gray ) );
+
146  virtual ~QwtAlphaColorMap();
+
147 
+
148  void setColor( const QColor & );
+
149  QColor color() const;
+
150 
+
151  virtual QRgb rgb( const QwtInterval &, double value ) const;
+
152 
+
153 private:
+ +
155  QwtAlphaColorMap &operator=( const QwtAlphaColorMap & );
+
156 
+
157  virtual unsigned char colorIndex(
+
158  const QwtInterval &, double value ) const;
+
159 
+
160  class PrivateData;
+
161  PrivateData *d_data;
+
162 };
+
163 
+
164 
+
177 inline QColor QwtColorMap::color(
+
178  const QwtInterval &interval, double value ) const
+
179 {
+
180  if ( d_format == RGB )
+
181  {
+
182  return QColor( rgb( interval, value ) );
+
183  }
+
184  else
+
185  {
+
186  const unsigned int index = colorIndex( interval, value );
+
187  return colorTable( interval )[index]; // slow
+
188  }
+
189 }
+
190 
+ +
196 {
+
197  return d_format;
+
198 }
+
199 
+
200 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__column__symbol_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__column__symbol_8h_source.html new file mode 100644 index 0000000000..ddd3cbcccb --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__column__symbol_8h_source.html @@ -0,0 +1,217 @@ + + + + + + +Qwt User's Guide: qwt_column_symbol.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_column_symbol.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_COLUMN_SYMBOL_H
+
11 #define QWT_COLUMN_SYMBOL_H
+
12 
+
13 #include "qwt_global.h"
+
14 #include "qwt_interval.h"
+
15 #include <qpen.h>
+
16 #include <qsize.h>
+
17 #include <qrect.h>
+
18 
+
19 class QPainter;
+
20 class QPalette;
+
21 class QRect;
+
22 class QwtText;
+
23 
+
28 class QWT_EXPORT QwtColumnRect
+
29 {
+
30 public:
+
32  enum Direction
+
33  {
+ +
36 
+ +
39 
+ +
42 
+
44  TopToBottom
+
45  };
+
46 
+ +
49  direction( BottomToTop )
+
50  {
+
51  }
+
52 
+
54  QRectF toRect() const
+
55  {
+
56  QRectF r( hInterval.minValue(), vInterval.minValue(),
+
57  hInterval.maxValue() - hInterval.minValue(),
+
58  vInterval.maxValue() - vInterval.minValue() );
+
59  r = r.normalized();
+
60 
+
61  if ( hInterval.borderFlags() & QwtInterval::ExcludeMinimum )
+
62  r.adjust( 1, 0, 0, 0 );
+
63  if ( hInterval.borderFlags() & QwtInterval::ExcludeMaximum )
+
64  r.adjust( 0, 0, -1, 0 );
+
65  if ( vInterval.borderFlags() & QwtInterval::ExcludeMinimum )
+
66  r.adjust( 0, 1, 0, 0 );
+
67  if ( vInterval.borderFlags() & QwtInterval::ExcludeMaximum )
+
68  r.adjust( 0, 0, 0, -1 );
+
69 
+
70  return r;
+
71  }
+
72 
+
74  Qt::Orientation orientation() const
+
75  {
+
76  if ( direction == LeftToRight || direction == RightToLeft )
+
77  return Qt::Horizontal;
+
78 
+
79  return Qt::Vertical;
+
80  }
+
81 
+ +
84 
+ +
87 
+ +
90 };
+
91 
+
93 class QWT_EXPORT QwtColumnSymbol
+
94 {
+
95 public:
+
100  enum Style
+
101  {
+
103  NoStyle = -1,
+
104 
+ +
110 
+
116  UserStyle = 1000
+
117  };
+
118 
+ +
124  {
+ +
127 
+ +
130 
+
132  Raised
+
133  };
+
134 
+
135 public:
+
136  QwtColumnSymbol( Style = NoStyle );
+
137  virtual ~QwtColumnSymbol();
+
138 
+
139  void setFrameStyle( FrameStyle style );
+
140  FrameStyle frameStyle() const;
+
141 
+
142  void setLineWidth( int width );
+
143  int lineWidth() const;
+
144 
+
145  void setPalette( const QPalette & );
+
146  const QPalette &palette() const;
+
147 
+
148  void setStyle( Style );
+
149  Style style() const;
+
150 
+
151  virtual void draw( QPainter *, const QwtColumnRect & ) const;
+
152 
+
153 protected:
+
154  void drawBox( QPainter *, const QwtColumnRect & ) const;
+
155 
+
156 private:
+
157  class PrivateData;
+
158  PrivateData* d_data;
+
159 };
+
160 
+
161 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__compass_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__compass_8h_source.html new file mode 100644 index 0000000000..ee07168b1e --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__compass_8h_source.html @@ -0,0 +1,155 @@ + + + + + + +Qwt User's Guide: qwt_compass.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_compass.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_COMPASS_H
+
11 #define QWT_COMPASS_H 1
+
12 
+
13 #include "qwt_global.h"
+
14 #include "qwt_dial.h"
+
15 #include "qwt_round_scale_draw.h"
+
16 #include <qstring.h>
+
17 #include <qmap.h>
+
18 
+
19 class QwtCompassRose;
+
20 
+
31 class QWT_EXPORT QwtCompassScaleDraw: public QwtRoundScaleDraw
+
32 {
+
33 public:
+
34  explicit QwtCompassScaleDraw();
+
35  explicit QwtCompassScaleDraw( const QMap<double, QString> &map );
+
36 
+
37  void setLabelMap( const QMap<double, QString> &map );
+
38  QMap<double, QString> labelMap() const;
+
39 
+
40  virtual QwtText label( double value ) const;
+
41 
+
42 private:
+
43  QMap<double, QString> d_labelMap;
+
44 };
+
45 
+
57 class QWT_EXPORT QwtCompass: public QwtDial
+
58 {
+
59  Q_OBJECT
+
60 
+
61 public:
+
62  explicit QwtCompass( QWidget* parent = NULL );
+
63  virtual ~QwtCompass();
+
64 
+
65  void setRose( QwtCompassRose *rose );
+
66  const QwtCompassRose *rose() const;
+
67  QwtCompassRose *rose();
+
68 
+
69 protected:
+
70  virtual void drawRose( QPainter *, const QPointF &center,
+
71  double radius, double north, QPalette::ColorGroup ) const;
+
72 
+
73  virtual void drawScaleContents( QPainter *,
+
74  const QPointF &center, double radius ) const;
+
75 
+
76  virtual void keyPressEvent( QKeyEvent * );
+
77 
+
78 private:
+
79  class PrivateData;
+
80  PrivateData *d_data;
+
81 };
+
82 
+
83 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__compass__rose_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__compass__rose_8h_source.html new file mode 100644 index 0000000000..dde6c6ba5a --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__compass__rose_8h_source.html @@ -0,0 +1,164 @@ + + + + + + +Qwt User's Guide: qwt_compass_rose.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_compass_rose.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_COMPASS_ROSE_H
+
11 #define QWT_COMPASS_ROSE_H 1
+
12 
+
13 #include "qwt_global.h"
+
14 #include <qpalette.h>
+
15 
+
16 class QPainter;
+
17 
+
21 class QWT_EXPORT QwtCompassRose
+
22 {
+
23 public:
+
25  virtual ~QwtCompassRose() {};
+
26 
+
28  virtual void setPalette( const QPalette &p )
+
29  {
+
30  d_palette = p;
+
31  }
+
32 
+
34  const QPalette &palette() const
+
35  {
+
36  return d_palette;
+
37  }
+
38 
+
48  virtual void draw( QPainter *painter,
+
49  const QPointF &center, double radius, double north,
+
50  QPalette::ColorGroup colorGroup = QPalette::Active ) const = 0;
+
51 
+
52 private:
+
53  QPalette d_palette;
+
54 };
+
55 
+
59 class QWT_EXPORT QwtSimpleCompassRose: public QwtCompassRose
+
60 {
+
61 public:
+
62  QwtSimpleCompassRose( int numThorns = 8, int numThornLevels = -1 );
+
63  virtual ~QwtSimpleCompassRose();
+
64 
+
65  void setWidth( double w );
+
66  double width() const;
+
67 
+
68  void setNumThorns( int count );
+
69  int numThorns() const;
+
70 
+
71  void setNumThornLevels( int count );
+
72  int numThornLevels() const;
+
73 
+
74  void setShrinkFactor( double factor );
+
75  double shrinkFactor() const;
+
76 
+
77  virtual void draw( QPainter *, const QPointF &center, double radius,
+
78  double north, QPalette::ColorGroup = QPalette::Active ) const;
+
79 
+
80  static void drawRose( QPainter *, const QPalette &,
+
81  const QPointF &center, double radius, double origin, double width,
+
82  int numThorns, int numThornLevels, double shrinkFactor );
+
83 
+
84 private:
+
85  class PrivateData;
+
86  PrivateData *d_data;
+
87 };
+
88 
+
89 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__compat_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__compat_8h_source.html new file mode 100644 index 0000000000..34db054192 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__compat_8h_source.html @@ -0,0 +1,135 @@ + + + + + + +Qwt User's Guide: qwt_compat.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_compat.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef _QWT_COMPAT_H_
+
11 #define _QWT_COMPAT_H_
+
12 
+
13 #include "qwt_global.h"
+
14 #include "qwt_interval.h"
+
15 #include "qwt_point_3d.h"
+
16 #include <qlist.h>
+
17 #include <qvector.h>
+
18 #include <qpoint.h>
+
19 #include <qsize.h>
+
20 #include <qrect.h>
+
21 #include <qpolygon.h>
+
22 
+
23 // A couple of definition for Qwt5 compatibility
+
24 
+
25 #define qwtMax qMax
+
26 #define qwtMin qMin
+
27 #define qwtAbs qAbs
+
28 #define qwtRound qRound
+
29 
+
30 #define QwtArray QVector
+
31 
+
32 typedef QList<double> QwtValueList;
+
33 typedef QPointF QwtDoublePoint;
+
34 typedef QSizeF QwtDoubleSize;
+
35 typedef QRectF QwtDoubleRect;
+
36 
+
37 typedef QPolygon QwtPolygon;
+
38 typedef QPolygonF QwtPolygonF;
+ + +
41 
+
42 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__counter_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__counter_8h_source.html new file mode 100644 index 0000000000..84ca81d0c1 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__counter_8h_source.html @@ -0,0 +1,209 @@ + + + + + + +Qwt User's Guide: qwt_counter.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_counter.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_COUNTER_H
+
11 #define QWT_COUNTER_H
+
12 
+
13 #include "qwt_global.h"
+
14 #include <qwidget.h>
+
15 
+
48 class QWT_EXPORT QwtCounter : public QWidget
+
49 {
+
50  Q_OBJECT
+
51 
+
52  Q_PROPERTY( double value READ value WRITE setValue )
+
53  Q_PROPERTY( double minimum READ minimum WRITE setMinimum )
+
54  Q_PROPERTY( double maximum READ maximum WRITE setMaximum )
+
55  Q_PROPERTY( double singleStep READ singleStep WRITE setSingleStep )
+
56 
+
57  Q_PROPERTY( int numButtons READ numButtons WRITE setNumButtons )
+
58  Q_PROPERTY( int stepButton1 READ stepButton1 WRITE setStepButton1 )
+
59  Q_PROPERTY( int stepButton2 READ stepButton2 WRITE setStepButton2 )
+
60  Q_PROPERTY( int stepButton3 READ stepButton3 WRITE setStepButton3 )
+
61 
+
62  Q_PROPERTY( bool readOnly READ isReadOnly WRITE setReadOnly )
+
63  Q_PROPERTY( bool wrapping READ wrapping WRITE setWrapping )
+
64 
+
65 public:
+
67  enum Button
+
68  {
+ +
71 
+ +
74 
+ +
77 
+
79  ButtonCnt
+
80  };
+
81 
+
82  explicit QwtCounter( QWidget *parent = NULL );
+
83  virtual ~QwtCounter();
+
84 
+
85  void setValid( bool );
+
86  bool isValid() const;
+
87 
+
88  void setWrapping( bool );
+
89  bool wrapping() const;
+
90 
+
91  bool isReadOnly() const;
+
92  void setReadOnly( bool );
+
93 
+
94  void setNumButtons( int n );
+
95  int numButtons() const;
+
96 
+
97  void setIncSteps( QwtCounter::Button btn, int nSteps );
+
98  int incSteps( QwtCounter::Button btn ) const;
+
99 
+
100  virtual QSize sizeHint() const;
+
101 
+
102  double singleStep() const;
+
103  void setSingleStep( double s );
+
104 
+
105  void setRange( double min, double max );
+
106 
+
107  double minimum() const;
+
108  void setMinimum( double min );
+
109 
+
110  double maximum() const;
+
111  void setMaximum( double max );
+
112 
+
113  void setStepButton1( int nSteps );
+
114  int stepButton1() const;
+
115 
+
116  void setStepButton2( int nSteps );
+
117  int stepButton2() const;
+
118 
+
119  void setStepButton3( int nSteps );
+
120  int stepButton3() const;
+
121 
+
122  double value() const;
+
123 
+
124 public Q_SLOTS:
+
125  void setValue( double );
+
126 
+
127 
+
128 Q_SIGNALS:
+
133  void buttonReleased ( double value );
+
134 
+
139  void valueChanged ( double value );
+
140 
+
141 protected:
+
142  virtual bool event( QEvent * );
+
143  virtual void wheelEvent( QWheelEvent * );
+
144  virtual void keyPressEvent( QKeyEvent * );
+
145 
+
146 private Q_SLOTS:
+
147  void btnReleased();
+
148  void btnClicked();
+
149  void textChanged();
+
150 
+
151 private:
+
152  void incrementValue( int numSteps );
+
153  void initCounter();
+
154  void updateButtons();
+
155  void showNumber( double );
+
156 
+
157  class PrivateData;
+
158  PrivateData *d_data;
+
159 };
+
160 
+
161 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__curve__fitter_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__curve__fitter_8h_source.html new file mode 100644 index 0000000000..578e14420c --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__curve__fitter_8h_source.html @@ -0,0 +1,185 @@ + + + + + + +Qwt User's Guide: qwt_curve_fitter.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_curve_fitter.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_CURVE_FITTER_H
+
11 #define QWT_CURVE_FITTER_H
+
12 
+
13 #include "qwt_global.h"
+
14 #include <qpolygon.h>
+
15 #include <qrect.h>
+
16 
+
17 class QwtSpline;
+
18 
+
22 class QWT_EXPORT QwtCurveFitter
+
23 {
+
24 public:
+
25  virtual ~QwtCurveFitter();
+
26 
+
33  virtual QPolygonF fitCurve( const QPolygonF &polygon ) const = 0;
+
34 
+
35 protected:
+ +
37 
+
38 private:
+
39  QwtCurveFitter( const QwtCurveFitter & );
+
40  QwtCurveFitter &operator=( const QwtCurveFitter & );
+
41 };
+
42 
+
46 class QWT_EXPORT QwtSplineCurveFitter: public QwtCurveFitter
+
47 {
+
48 public:
+
54  enum FitMode
+
55  {
+ +
62 
+ +
65 
+
67  ParametricSpline
+
68  };
+
69 
+ +
71  virtual ~QwtSplineCurveFitter();
+
72 
+
73  void setFitMode( FitMode );
+
74  FitMode fitMode() const;
+
75 
+
76  void setSpline( const QwtSpline& );
+
77  const QwtSpline &spline() const;
+
78  QwtSpline &spline();
+
79 
+
80  void setSplineSize( int size );
+
81  int splineSize() const;
+
82 
+
83  virtual QPolygonF fitCurve( const QPolygonF & ) const;
+
84 
+
85 private:
+
86  QPolygonF fitSpline( const QPolygonF & ) const;
+
87  QPolygonF fitParametric( const QPolygonF & ) const;
+
88 
+
89  class PrivateData;
+
90  PrivateData *d_data;
+
91 };
+
92 
+
116 class QWT_EXPORT QwtWeedingCurveFitter: public QwtCurveFitter
+
117 {
+
118 public:
+
119  QwtWeedingCurveFitter( double tolerance = 1.0 );
+
120  virtual ~QwtWeedingCurveFitter();
+
121 
+
122  void setTolerance( double );
+
123  double tolerance() const;
+
124 
+
125  void setChunkSize( uint );
+
126  uint chunkSize() const;
+
127 
+
128  virtual QPolygonF fitCurve( const QPolygonF & ) const;
+
129 
+
130 private:
+
131  virtual QPolygonF simplify( const QPolygonF & ) const;
+
132 
+
133  class Line;
+
134 
+
135  class PrivateData;
+
136  PrivateData *d_data;
+
137 };
+
138 
+
139 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__date_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__date_8h_source.html new file mode 100644 index 0000000000..a6548ef232 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__date_8h_source.html @@ -0,0 +1,163 @@ + + + + + + +Qwt User's Guide: qwt_date.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_date.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef _QWT_DATE_H_
+
11 #define _QWT_DATE_H_
+
12 
+
13 #include "qwt_global.h"
+
14 #include <qdatetime.h>
+
15 
+
42 class QWT_EXPORT QwtDate
+
43 {
+
44 public:
+
49  enum Week0Type
+
50  {
+ +
59 
+
66  FirstDay
+
67  };
+
68 
+ +
76  {
+ +
79 
+ +
82 
+ +
85 
+ +
88 
+
90  Day,
+
91 
+ +
94 
+ +
97 
+
99  Year
+
100  };
+
101 
+
102  enum
+
103  {
+
105  JulianDayForEpoch = 2440588
+
106  };
+
107 
+
108  static QDate minDate();
+
109  static QDate maxDate();
+
110 
+
111  static QDateTime toDateTime( double value,
+
112  Qt::TimeSpec = Qt::UTC );
+
113 
+
114  static double toDouble( const QDateTime & );
+
115 
+
116  static QDateTime ceil( const QDateTime &, IntervalType );
+
117  static QDateTime floor( const QDateTime &, IntervalType );
+
118 
+
119  static QDate dateOfWeek0( int year, Week0Type );
+
120  static int weekNumber( const QDate &, Week0Type );
+
121 
+
122  static int utcOffset( const QDateTime & );
+
123 
+
124  static QString toString( const QDateTime &,
+
125  const QString & format, Week0Type );
+
126 };
+
127 
+
128 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__date__scale__draw_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__date__scale__draw_8h_source.html new file mode 100644 index 0000000000..bba4b7d2b1 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__date__scale__draw_8h_source.html @@ -0,0 +1,135 @@ + + + + + + +Qwt User's Guide: qwt_date_scale_draw.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_date_scale_draw.h
+
+
+
1 #ifndef _QWT_DATE_SCALE_DRAW_H_
+
2 #define _QWT_DATE_SCALE_DRAW_H_ 1
+
3 
+
4 #include "qwt_global.h"
+
5 #include "qwt_scale_draw.h"
+
6 #include "qwt_date.h"
+
7 
+
43 class QWT_EXPORT QwtDateScaleDraw: public QwtScaleDraw
+
44 {
+
45 public:
+
46  QwtDateScaleDraw( Qt::TimeSpec = Qt::LocalTime );
+
47  virtual ~QwtDateScaleDraw();
+
48 
+
49  void setDateFormat( QwtDate::IntervalType, const QString & );
+
50  QString dateFormat( QwtDate::IntervalType ) const;
+
51 
+
52  void setTimeSpec( Qt::TimeSpec );
+
53  Qt::TimeSpec timeSpec() const;
+
54 
+
55  void setUtcOffset( int seconds );
+
56  int utcOffset() const;
+
57 
+
58  void setWeek0Type( QwtDate::Week0Type );
+
59  QwtDate::Week0Type week0Type() const;
+
60 
+
61  virtual QwtText label( double ) const;
+
62 
+
63  QDateTime toDateTime( double ) const;
+
64 
+
65 protected:
+
66  virtual QwtDate::IntervalType
+
67  intervalType( const QwtScaleDiv & ) const;
+
68 
+
69  virtual QString dateFormatOfDate( const QDateTime &,
+
70  QwtDate::IntervalType ) const;
+
71 
+
72 private:
+
73  class PrivateData;
+
74  PrivateData *d_data;
+
75 };
+
76 
+
77 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__date__scale__engine_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__date__scale__engine_8h_source.html new file mode 100644 index 0000000000..d2eb53b3d2 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__date__scale__engine_8h_source.html @@ -0,0 +1,145 @@ + + + + + + +Qwt User's Guide: qwt_date_scale_engine.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_date_scale_engine.h
+
+
+
1 #ifndef _QWT_DATE_SCALE_ENGINE_H_
+
2 #define _QWT_DATE_SCALE_ENGINE_H_ 1
+
3 
+
4 #include "qwt_date.h"
+
5 #include "qwt_scale_engine.h"
+
6 
+
32 class QWT_EXPORT QwtDateScaleEngine: public QwtLinearScaleEngine
+
33 {
+
34 public:
+
35  QwtDateScaleEngine( Qt::TimeSpec = Qt::LocalTime );
+
36  virtual ~QwtDateScaleEngine();
+
37 
+
38  void setTimeSpec( Qt::TimeSpec );
+
39  Qt::TimeSpec timeSpec() const;
+
40 
+
41  void setUtcOffset( int seconds );
+
42  int utcOffset() const;
+
43 
+
44  void setWeek0Type( QwtDate::Week0Type );
+
45  QwtDate::Week0Type week0Type() const;
+
46 
+
47  void setMaxWeeks( int );
+
48  int maxWeeks() const;
+
49 
+
50  virtual void autoScale( int maxNumSteps,
+
51  double &x1, double &x2, double &stepSize ) const;
+
52 
+
53  virtual QwtScaleDiv divideScale(
+
54  double x1, double x2,
+
55  int maxMajorSteps, int maxMinorSteps,
+
56  double stepSize = 0.0 ) const;
+
57 
+
58  virtual QwtDate::IntervalType intervalType(
+
59  const QDateTime &, const QDateTime &, int maxSteps ) const;
+
60 
+
61  QDateTime toDateTime( double ) const;
+
62 
+
63 protected:
+
64  virtual QDateTime alignDate( const QDateTime &, double stepSize,
+
65  QwtDate::IntervalType, bool up ) const;
+
66 
+
67 private:
+
68  QwtScaleDiv buildScaleDiv( const QDateTime &, const QDateTime &,
+
69  int maxMajorSteps, int maxMinorSteps,
+
70  QwtDate::IntervalType ) const;
+
71 
+
72 private:
+
73  class PrivateData;
+
74  PrivateData *d_data;
+
75 };
+
76 
+
77 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__dial_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__dial_8h_source.html new file mode 100644 index 0000000000..a35da18b40 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__dial_8h_source.html @@ -0,0 +1,220 @@ + + + + + + +Qwt User's Guide: qwt_dial.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_dial.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_DIAL_H
+
11 #define QWT_DIAL_H 1
+
12 
+
13 #include "qwt_global.h"
+
14 #include "qwt_abstract_slider.h"
+
15 #include "qwt_abstract_scale_draw.h"
+
16 #include <qframe.h>
+
17 #include <qpalette.h>
+
18 
+
19 class QwtDialNeedle;
+
20 class QwtRoundScaleDraw;
+
21 
+
49 class QWT_EXPORT QwtDial: public QwtAbstractSlider
+
50 {
+
51  Q_OBJECT
+
52 
+
53  Q_ENUMS( Shadow Mode Direction )
+
54 
+
55  Q_PROPERTY( int lineWidth READ lineWidth WRITE setLineWidth )
+
56  Q_PROPERTY( Shadow frameShadow READ frameShadow WRITE setFrameShadow )
+
57  Q_PROPERTY( Mode mode READ mode WRITE setMode )
+
58  Q_PROPERTY( double origin READ origin WRITE setOrigin )
+
59  Q_PROPERTY( double minScaleArc READ minScaleArc WRITE setMinScaleArc )
+
60  Q_PROPERTY( double maxScaleArc READ maxScaleArc WRITE setMaxScaleArc )
+
61 
+
62 public:
+
63 
+
72  enum Shadow
+
73  {
+
75  Plain = QFrame::Plain,
+
76 
+
78  Raised = QFrame::Raised,
+
79 
+
81  Sunken = QFrame::Sunken
+
82  };
+
83 
+
85  enum Mode
+
86  {
+ +
89 
+
91  RotateScale
+
92  };
+
93 
+
94  explicit QwtDial( QWidget *parent = NULL );
+
95  virtual ~QwtDial();
+
96 
+
97  void setFrameShadow( Shadow );
+
98  Shadow frameShadow() const;
+
99 
+
100  void setLineWidth( int );
+
101  int lineWidth() const;
+
102 
+
103  void setMode( Mode );
+
104  Mode mode() const;
+
105 
+
106  void setScaleArc( double min, double max );
+
107 
+
108  void setMinScaleArc( double min );
+
109  double minScaleArc() const;
+
110 
+
111  void setMaxScaleArc( double min );
+
112  double maxScaleArc() const;
+
113 
+
114  virtual void setOrigin( double );
+
115  double origin() const;
+
116 
+
117  void setNeedle( QwtDialNeedle * );
+
118  const QwtDialNeedle *needle() const;
+
119  QwtDialNeedle *needle();
+
120 
+
121  QRect boundingRect() const;
+
122  QRect innerRect() const;
+
123 
+
124  virtual QRect scaleInnerRect() const;
+
125 
+
126  virtual QSize sizeHint() const;
+
127  virtual QSize minimumSizeHint() const;
+
128 
+
129  void setScaleDraw( QwtRoundScaleDraw * );
+
130 
+
131  QwtRoundScaleDraw *scaleDraw();
+
132  const QwtRoundScaleDraw *scaleDraw() const;
+
133 
+
134 protected:
+
135  virtual void wheelEvent( QWheelEvent * );
+
136  virtual void paintEvent( QPaintEvent * );
+
137  virtual void changeEvent( QEvent * );
+
138 
+
139  virtual void drawFrame( QPainter *p );
+
140  virtual void drawContents( QPainter * ) const;
+
141  virtual void drawFocusIndicator( QPainter * ) const;
+
142 
+
143  void invalidateCache();
+
144 
+
145  virtual void drawScale( QPainter *,
+
146  const QPointF &center, double radius ) const;
+
147 
+
148  virtual void drawScaleContents( QPainter *painter,
+
149  const QPointF &center, double radius ) const;
+
150 
+
151  virtual void drawNeedle( QPainter *, const QPointF &,
+
152  double radius, double direction, QPalette::ColorGroup ) const;
+
153 
+
154  virtual double scrolledTo( const QPoint & ) const;
+
155  virtual bool isScrollPosition( const QPoint & ) const;
+
156 
+
157  virtual void sliderChange();
+
158  virtual void scaleChange();
+
159 
+
160 private:
+
161  void setAngleRange( double angle, double span );
+
162  void drawNeedle( QPainter * ) const;
+
163 
+
164  class PrivateData;
+
165  PrivateData *d_data;
+
166 };
+
167 
+
168 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__dial__needle_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__dial__needle_8h_source.html new file mode 100644 index 0000000000..01a879eaaa --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__dial__needle_8h_source.html @@ -0,0 +1,204 @@ + + + + + + +Qwt User's Guide: qwt_dial_needle.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_dial_needle.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_DIAL_NEEDLE_H
+
11 #define QWT_DIAL_NEEDLE_H 1
+
12 
+
13 #include "qwt_global.h"
+
14 #include <qpalette.h>
+
15 
+
16 class QPainter;
+
17 class QPoint;
+
18 
+
28 class QWT_EXPORT QwtDialNeedle
+
29 {
+
30 public:
+
31  QwtDialNeedle();
+
32  virtual ~QwtDialNeedle();
+
33 
+
34  virtual void setPalette( const QPalette & );
+
35  const QPalette &palette() const;
+
36 
+
37  virtual void draw( QPainter *painter, const QPointF &center,
+
38  double length, double direction,
+
39  QPalette::ColorGroup = QPalette::Active ) const;
+
40 
+
41 protected:
+
57  virtual void drawNeedle( QPainter *painter,
+
58  double length, QPalette::ColorGroup colorGroup ) const = 0;
+
59 
+
60  virtual void drawKnob( QPainter *, double width,
+
61  const QBrush &, bool sunken ) const;
+
62 
+
63 private:
+
64  QPalette d_palette;
+
65 };
+
66 
+
80 class QWT_EXPORT QwtDialSimpleNeedle: public QwtDialNeedle
+
81 {
+
82 public:
+
84  enum Style
+
85  {
+ +
88 
+
90  Ray
+
91  };
+
92 
+
93  QwtDialSimpleNeedle( Style, bool hasKnob = true,
+
94  const QColor &mid = Qt::gray, const QColor &base = Qt::darkGray );
+
95 
+
96  void setWidth( double width );
+
97  double width() const;
+
98 
+
99 protected:
+
100  virtual void drawNeedle( QPainter *, double length,
+
101  QPalette::ColorGroup ) const;
+
102 
+
103 private:
+
104  Style d_style;
+
105  bool d_hasKnob;
+
106  double d_width;
+
107 };
+
108 
+
126 class QWT_EXPORT QwtCompassMagnetNeedle: public QwtDialNeedle
+
127 {
+
128 public:
+
130  enum Style
+
131  {
+ +
134 
+
136  ThinStyle
+
137  };
+
138 
+
139  QwtCompassMagnetNeedle( Style = TriangleStyle,
+
140  const QColor &light = Qt::white, const QColor &dark = Qt::red );
+
141 
+
142 protected:
+
143  virtual void drawNeedle( QPainter *,
+
144  double length, QPalette::ColorGroup ) const;
+
145 
+
146 private:
+
147  Style d_style;
+
148 };
+
149 
+
163 class QWT_EXPORT QwtCompassWindArrow: public QwtDialNeedle
+
164 {
+
165 public:
+
167  enum Style
+
168  {
+ +
171 
+
173  Style2
+
174  };
+
175 
+
176  QwtCompassWindArrow( Style, const QColor &light = Qt::white,
+
177  const QColor &dark = Qt::gray );
+
178 
+
179 protected:
+
180  virtual void drawNeedle( QPainter *,
+
181  double length, QPalette::ColorGroup ) const;
+
182 
+
183 private:
+
184  Style d_style;
+
185 };
+
186 
+
187 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__dyngrid__layout_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__dyngrid__layout_8h_source.html new file mode 100644 index 0000000000..f17440874d --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__dyngrid__layout_8h_source.html @@ -0,0 +1,167 @@ + + + + + + +Qwt User's Guide: qwt_dyngrid_layout.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_dyngrid_layout.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_DYNGRID_LAYOUT_H
+
11 #define QWT_DYNGRID_LAYOUT_H
+
12 
+
13 #include "qwt_global.h"
+
14 #include <qlayout.h>
+
15 #include <qsize.h>
+
16 #include <qlist.h>
+
17 
+
27 class QWT_EXPORT QwtDynGridLayout : public QLayout
+
28 {
+
29  Q_OBJECT
+
30 public:
+
31  explicit QwtDynGridLayout( QWidget *, int margin = 0, int space = -1 );
+
32  explicit QwtDynGridLayout( int space = -1 );
+
33 
+
34  virtual ~QwtDynGridLayout();
+
35 
+
36  virtual void invalidate();
+
37 
+
38  void setMaxColumns( uint maxCols );
+
39  uint maxColumns() const;
+
40 
+
41  uint numRows () const;
+
42  uint numColumns () const;
+
43 
+
44  virtual void addItem( QLayoutItem * );
+
45 
+
46  virtual QLayoutItem *itemAt( int index ) const;
+
47  virtual QLayoutItem *takeAt( int index );
+
48  virtual int count() const;
+
49 
+
50  void setExpandingDirections( Qt::Orientations );
+
51  virtual Qt::Orientations expandingDirections() const;
+
52  QList<QRect> layoutItems( const QRect &, uint numCols ) const;
+
53 
+
54  virtual int maxItemWidth() const;
+
55 
+
56  virtual void setGeometry( const QRect &rect );
+
57 
+
58  virtual bool hasHeightForWidth() const;
+
59  virtual int heightForWidth( int ) const;
+
60 
+
61  virtual QSize sizeHint() const;
+
62 
+
63  virtual bool isEmpty() const;
+
64  uint itemCount() const;
+
65 
+
66  virtual uint columnsForWidth( int width ) const;
+
67 
+
68 protected:
+
69 
+
70  void layoutGrid( uint numCols,
+
71  QVector<int>& rowHeight, QVector<int>& colWidth ) const;
+
72  void stretchGrid( const QRect &rect, uint numCols,
+
73  QVector<int>& rowHeight, QVector<int>& colWidth ) const;
+
74 
+
75 private:
+
76  void init();
+
77  int maxRowWidth( int numCols ) const;
+
78 
+
79  class PrivateData;
+
80  PrivateData *d_data;
+
81 };
+
82 
+
83 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__event__pattern_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__event__pattern_8h_source.html new file mode 100644 index 0000000000..c38d7971d5 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__event__pattern_8h_source.html @@ -0,0 +1,241 @@ + + + + + + +Qwt User's Guide: qwt_event_pattern.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_event_pattern.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_EVENT_PATTERN
+
11 #define QWT_EVENT_PATTERN 1
+
12 
+
13 #include "qwt_global.h"
+
14 #include <qnamespace.h>
+
15 #include <qvector.h>
+
16 
+
17 class QMouseEvent;
+
18 class QKeyEvent;
+
19 
+
29 class QWT_EXPORT QwtEventPattern
+
30 {
+
31 public:
+ +
45  {
+ +
54 
+ +
63 
+ +
72 
+ +
81 
+ +
90 
+ +
99 
+
101  MousePatternCount
+
102  };
+
103 
+ +
112  {
+ +
115 
+ +
118 
+ +
121 
+ +
124 
+ +
127 
+ +
130 
+ +
133 
+ +
136 
+ +
139 
+ +
142 
+
144  KeyPatternCount
+
145  };
+
146 
+ +
149  {
+
150  public:
+
152  MousePattern( Qt::MouseButton btn = Qt::NoButton,
+
153  Qt::KeyboardModifiers modifierCodes = Qt::NoModifier ):
+
154  button( btn ),
+
155  modifiers( modifierCodes )
+
156  {
+
157  }
+
158 
+
160  Qt::MouseButton button;
+
161 
+
163  Qt::KeyboardModifiers modifiers;
+
164  };
+
165 
+ +
168  {
+
169  public:
+
171  KeyPattern( int keyCode = Qt::Key_unknown,
+
172  Qt::KeyboardModifiers modifierCodes = Qt::NoModifier ):
+
173  key( keyCode ),
+
174  modifiers( modifierCodes )
+
175  {
+
176  }
+
177 
+
179  int key;
+
180 
+
182  Qt::KeyboardModifiers modifiers;
+
183  };
+
184 
+
185  QwtEventPattern();
+
186  virtual ~QwtEventPattern();
+
187 
+
188  void initMousePattern( int numButtons );
+
189  void initKeyPattern();
+
190 
+
191  void setMousePattern( MousePatternCode, Qt::MouseButton button,
+
192  Qt::KeyboardModifiers = Qt::NoModifier );
+
193 
+
194  void setKeyPattern( KeyPatternCode, int keyCode,
+
195  Qt::KeyboardModifiers modifierCodes = Qt::NoModifier );
+
196 
+
197  void setMousePattern( const QVector<MousePattern> & );
+
198  void setKeyPattern( const QVector<KeyPattern> & );
+
199 
+
200  const QVector<MousePattern> &mousePattern() const;
+
201  const QVector<KeyPattern> &keyPattern() const;
+
202 
+
203  QVector<MousePattern> &mousePattern();
+
204  QVector<KeyPattern> &keyPattern();
+
205 
+
206  bool mouseMatch( MousePatternCode, const QMouseEvent * ) const;
+
207  bool keyMatch( KeyPatternCode, const QKeyEvent * ) const;
+
208 
+
209 protected:
+
210  virtual bool mouseMatch( const MousePattern &, const QMouseEvent * ) const;
+
211  virtual bool keyMatch( const KeyPattern &, const QKeyEvent * ) const;
+
212 
+
213 private:
+
214 
+
215 #if defined(_MSC_VER)
+
216 #pragma warning(push)
+
217 #pragma warning(disable: 4251)
+
218 #endif
+
219  QVector<MousePattern> d_mousePattern;
+
220  QVector<KeyPattern> d_keyPattern;
+
221 #if defined(_MSC_VER)
+
222 #pragma warning(pop)
+
223 #endif
+
224 };
+
225 
+
227 inline bool operator==( QwtEventPattern::MousePattern b1,
+ +
229 {
+
230  return b1.button == b2.button && b1.modifiers == b2.modifiers;
+
231 }
+
232 
+
234 inline bool operator==( QwtEventPattern::KeyPattern b1,
+ +
236 {
+
237  return b1.key == b2.key && b1.modifiers == b2.modifiers;
+
238 }
+
239 
+
240 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__global_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__global_8h_source.html new file mode 100644 index 0000000000..8071017874 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__global_8h_source.html @@ -0,0 +1,134 @@ + + + + + + +Qwt User's Guide: qwt_global.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_global.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_GLOBAL_H
+
11 #define QWT_GLOBAL_H
+
12 
+
13 #include <qglobal.h>
+
14 
+
15 // QWT_VERSION is (major << 16) + (minor << 8) + patch.
+
16 
+
17 #define QWT_VERSION 0x060100
+
18 #define QWT_VERSION_STR "6.1.0"
+
19 
+
20 #if defined(_MSC_VER) /* MSVC Compiler */
+
21 /* template-class specialization 'identifier' is already instantiated */
+
22 #pragma warning(disable: 4660)
+
23 /* inherits via dominance */
+
24 #pragma warning(disable: 4250)
+
25 #endif // _MSC_VER
+
26 
+
27 #ifdef QWT_DLL
+
28 
+
29 #if defined(QWT_MAKEDLL) // create a Qwt DLL library
+
30 #define QWT_EXPORT Q_DECL_EXPORT
+
31 #else // use a Qwt DLL library
+
32 #define QWT_EXPORT Q_DECL_IMPORT
+
33 #endif
+
34 
+
35 #endif // QWT_DLL
+
36 
+
37 #ifndef QWT_EXPORT
+
38 #define QWT_EXPORT
+
39 #endif
+
40 
+
41 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__graphic_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__graphic_8h_source.html new file mode 100644 index 0000000000..de6eac535e --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__graphic_8h_source.html @@ -0,0 +1,195 @@ + + + + + + +Qwt User's Guide: qwt_graphic.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_graphic.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_GRAPHIC_H
+
11 #define QWT_GRAPHIC_H
+
12 
+
13 #include "qwt_global.h"
+
14 #include "qwt_null_paintdevice.h"
+
15 #include <qmetatype.h>
+
16 #include <qimage.h>
+
17 #include <qpixmap.h>
+
18 
+
19 class QwtPainterCommand;
+
20 
+
76 class QWT_EXPORT QwtGraphic: public QwtNullPaintDevice
+
77 {
+
78 public:
+ +
84  {
+
93  RenderPensUnscaled = 0x1
+
94  };
+
95 
+
101  typedef QFlags<RenderHint> RenderHints;
+
102 
+
103  QwtGraphic();
+
104  QwtGraphic( const QwtGraphic & );
+
105 
+
106  virtual ~QwtGraphic();
+
107 
+
108  QwtGraphic& operator=( const QwtGraphic & );
+
109 
+
110  void reset();
+
111 
+
112  bool isNull() const;
+
113  bool isEmpty() const;
+
114 
+
115  void render( QPainter * ) const;
+
116 
+
117  void render( QPainter *, const QSizeF &,
+
118  Qt::AspectRatioMode = Qt::IgnoreAspectRatio ) const;
+
119 
+
120  void render( QPainter *, const QRectF &,
+
121  Qt::AspectRatioMode = Qt::IgnoreAspectRatio ) const;
+
122 
+
123  void render( QPainter *, const QPointF &,
+
124  Qt::Alignment = Qt::AlignTop | Qt::AlignLeft ) const;
+
125 
+
126  QPixmap toPixmap() const;
+
127  QPixmap toPixmap( const QSize &,
+
128  Qt::AspectRatioMode = Qt::IgnoreAspectRatio ) const;
+
129 
+
130  QImage toImage() const;
+
131  QImage toImage( const QSize &,
+
132  Qt::AspectRatioMode = Qt::IgnoreAspectRatio ) const;
+
133 
+
134  QRectF scaledBoundingRect( double sx, double sy ) const;
+
135 
+
136  QRectF boundingRect() const;
+
137  QRectF controlPointRect() const;
+
138 
+
139  const QVector< QwtPainterCommand > &commands() const;
+
140  void setCommands( QVector< QwtPainterCommand > & );
+
141 
+
142  void setDefaultSize( const QSizeF & );
+
143  QSizeF defaultSize() const;
+
144 
+
145  void setRenderHint( RenderHint, bool on = true );
+
146  bool testRenderHint( RenderHint ) const;
+
147 
+
148 protected:
+
149  virtual QSize sizeMetrics() const;
+
150 
+
151  virtual void drawPath( const QPainterPath & );
+
152 
+
153  virtual void drawPixmap( const QRectF &,
+
154  const QPixmap &, const QRectF & );
+
155 
+
156  virtual void drawImage( const QRectF &,
+
157  const QImage &, const QRectF &, Qt::ImageConversionFlags );
+
158 
+
159  virtual void updateState( const QPaintEngineState &state );
+
160 
+
161 private:
+
162  void updateBoundingRect( const QRectF & );
+
163  void updateControlPointRect( const QRectF & );
+
164 
+
165  class PathInfo;
+
166 
+
167  class PrivateData;
+
168  PrivateData *d_data;
+
169 };
+
170 
+
171 Q_DECLARE_OPERATORS_FOR_FLAGS( QwtGraphic::RenderHints )
+
172 Q_DECLARE_METATYPE( QwtGraphic )
+
173 
+
174 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__interval_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__interval_8h_source.html new file mode 100644 index 0000000000..3a87c8bbfc --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__interval_8h_source.html @@ -0,0 +1,296 @@ + + + + + + +Qwt User's Guide: qwt_interval.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_interval.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_INTERVAL_H
+
11 #define QWT_INTERVAL_H
+
12 
+
13 #include "qwt_global.h"
+
14 #include <qmetatype.h>
+
15 
+
16 #ifndef QT_NO_DEBUG_STREAM
+
17 #include <qdebug.h>
+
18 #endif
+
19 
+
26 class QWT_EXPORT QwtInterval
+
27 {
+
28 public:
+ +
34  {
+
36  IncludeBorders = 0x00,
+
37 
+
39  ExcludeMinimum = 0x01,
+
40 
+
42  ExcludeMaximum = 0x02,
+
43 
+
45  ExcludeBorders = ExcludeMinimum | ExcludeMaximum
+
46  };
+
47 
+
49  typedef QFlags<BorderFlag> BorderFlags;
+
50 
+
51  QwtInterval();
+
52  QwtInterval( double minValue, double maxValue,
+
53  BorderFlags = IncludeBorders );
+
54 
+
55  void setInterval( double minValue, double maxValue,
+
56  BorderFlags = IncludeBorders );
+
57 
+
58  QwtInterval normalized() const;
+
59  QwtInterval inverted() const;
+
60  QwtInterval limited( double minValue, double maxValue ) const;
+
61 
+
62  bool operator==( const QwtInterval & ) const;
+
63  bool operator!=( const QwtInterval & ) const;
+
64 
+
65  void setBorderFlags( BorderFlags );
+
66  BorderFlags borderFlags() const;
+
67 
+
68  double minValue() const;
+
69  double maxValue() const;
+
70 
+
71  double width() const;
+
72 
+
73  void setMinValue( double );
+
74  void setMaxValue( double );
+
75 
+
76  bool contains( double value ) const;
+
77 
+
78  bool intersects( const QwtInterval & ) const;
+
79  QwtInterval intersect( const QwtInterval & ) const;
+
80  QwtInterval unite( const QwtInterval & ) const;
+
81 
+
82  QwtInterval operator|( const QwtInterval & ) const;
+
83  QwtInterval operator&( const QwtInterval & ) const;
+
84 
+
85  QwtInterval &operator|=( const QwtInterval & );
+
86  QwtInterval &operator&=( const QwtInterval & );
+
87 
+
88  QwtInterval extend( double value ) const;
+
89  QwtInterval operator|( double ) const;
+
90  QwtInterval &operator|=( double );
+
91 
+
92  bool isValid() const;
+
93  bool isNull() const;
+
94  void invalidate();
+
95 
+
96  QwtInterval symmetrize( double value ) const;
+
97 
+
98 private:
+
99  double d_minValue;
+
100  double d_maxValue;
+
101  BorderFlags d_borderFlags;
+
102 };
+
103 
+
104 Q_DECLARE_TYPEINFO(QwtInterval, Q_MOVABLE_TYPE);
+
105 
+ +
113  d_minValue( 0.0 ),
+
114  d_maxValue( -1.0 ),
+
115  d_borderFlags( IncludeBorders )
+
116 {
+
117 }
+
118 
+ +
129  double minValue, double maxValue, BorderFlags borderFlags ):
+
130  d_minValue( minValue ),
+
131  d_maxValue( maxValue ),
+
132  d_borderFlags( borderFlags )
+
133 {
+
134 }
+
135 
+ +
144  double minValue, double maxValue, BorderFlags borderFlags )
+
145 {
+
146  d_minValue = minValue;
+
147  d_maxValue = maxValue;
+
148  d_borderFlags = borderFlags;
+
149 }
+
150 
+
157 inline void QwtInterval::setBorderFlags( BorderFlags borderFlags )
+
158 {
+
159  d_borderFlags = borderFlags;
+
160 }
+
161 
+ +
167 {
+
168  return d_borderFlags;
+
169 }
+
170 
+
176 inline void QwtInterval::setMinValue( double minValue )
+
177 {
+
178  d_minValue = minValue;
+
179 }
+
180 
+
186 inline void QwtInterval::setMaxValue( double maxValue )
+
187 {
+
188  d_maxValue = maxValue;
+
189 }
+
190 
+
192 inline double QwtInterval::minValue() const
+
193 {
+
194  return d_minValue;
+
195 }
+
196 
+
198 inline double QwtInterval::maxValue() const
+
199 {
+
200  return d_maxValue;
+
201 }
+
202 
+
210 inline bool QwtInterval::isValid() const
+
211 {
+
212  if ( ( d_borderFlags & ExcludeBorders ) == 0 )
+
213  return d_minValue <= d_maxValue;
+
214  else
+
215  return d_minValue < d_maxValue;
+
216 }
+
217 
+
227 inline double QwtInterval::width() const
+
228 {
+
229  return isValid() ? ( d_maxValue - d_minValue ) : 0.0;
+
230 }
+
231 
+ +
241  const QwtInterval &other ) const
+
242 {
+
243  return intersect( other );
+
244 }
+
245 
+ +
255  const QwtInterval &other ) const
+
256 {
+
257  return unite( other );
+
258 }
+
259 
+
266 inline bool QwtInterval::operator==( const QwtInterval &other ) const
+
267 {
+
268  return ( d_minValue == other.d_minValue ) &&
+
269  ( d_maxValue == other.d_maxValue ) &&
+
270  ( d_borderFlags == other.d_borderFlags );
+
271 }
+
278 inline bool QwtInterval::operator!=( const QwtInterval &other ) const
+
279 {
+
280  return ( !( *this == other ) );
+
281 }
+
282 
+
290 inline QwtInterval QwtInterval::operator|( double value ) const
+
291 {
+
292  return extend( value );
+
293 }
+
294 
+
296 inline bool QwtInterval::isNull() const
+
297 {
+
298  return isValid() && d_minValue >= d_maxValue;
+
299 }
+
300 
+ +
308 {
+
309  d_minValue = 0.0;
+
310  d_maxValue = -1.0;
+
311 }
+
312 
+
313 Q_DECLARE_OPERATORS_FOR_FLAGS( QwtInterval::BorderFlags )
+
314 Q_DECLARE_METATYPE( QwtInterval )
+
315 
+
316 #ifndef QT_NO_DEBUG_STREAM
+
317 QWT_EXPORT QDebug operator<<( QDebug, const QwtInterval & );
+
318 #endif
+
319 
+
320 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__interval__symbol_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__interval__symbol_8h_source.html new file mode 100644 index 0000000000..d7bd19448d --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__interval__symbol_8h_source.html @@ -0,0 +1,159 @@ + + + + + + +Qwt User's Guide: qwt_interval_symbol.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_interval_symbol.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_INTERVAL_SYMBOL_H
+
11 #define QWT_INTERVAL_SYMBOL_H
+
12 
+
13 #include "qwt_global.h"
+
14 #include <qpen.h>
+
15 #include <qsize.h>
+
16 
+
17 class QPainter;
+
18 class QRect;
+
19 class QPointF;
+
20 
+
26 class QWT_EXPORT QwtIntervalSymbol
+
27 {
+
28 public:
+
30  enum Style
+
31  {
+
33  NoSymbol = -1,
+
34 
+
39  Bar,
+
40 
+
46  Box,
+
47 
+
53  UserSymbol = 1000
+
54  };
+
55 
+
56 public:
+
57  QwtIntervalSymbol( Style = NoSymbol );
+ +
59  virtual ~QwtIntervalSymbol();
+
60 
+
61  QwtIntervalSymbol &operator=( const QwtIntervalSymbol & );
+
62  bool operator==( const QwtIntervalSymbol & ) const;
+
63  bool operator!=( const QwtIntervalSymbol & ) const;
+
64 
+
65  void setWidth( int );
+
66  int width() const;
+
67 
+
68  void setBrush( const QBrush& b );
+
69  const QBrush& brush() const;
+
70 
+
71  void setPen( const QColor &, qreal width = 0.0, Qt::PenStyle = Qt::SolidLine );
+
72  void setPen( const QPen & );
+
73  const QPen& pen() const;
+
74 
+
75  void setStyle( Style );
+
76  Style style() const;
+
77 
+
78  virtual void draw( QPainter *, Qt::Orientation,
+
79  const QPointF& from, const QPointF& to ) const;
+
80 
+
81 private:
+
82 
+
83  class PrivateData;
+
84  PrivateData* d_data;
+
85 };
+
86 
+
87 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__knob_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__knob_8h_source.html new file mode 100644 index 0000000000..3c9965c04a --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__knob_8h_source.html @@ -0,0 +1,209 @@ + + + + + + +Qwt User's Guide: qwt_knob.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_knob.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_KNOB_H
+
11 #define QWT_KNOB_H
+
12 
+
13 #include "qwt_global.h"
+
14 #include "qwt_abstract_slider.h"
+
15 
+
16 class QwtRoundScaleDraw;
+
17 
+
42 class QWT_EXPORT QwtKnob: public QwtAbstractSlider
+
43 {
+
44  Q_OBJECT
+
45 
+
46  Q_ENUMS ( KnobStyle MarkerStyle )
+
47 
+
48  Q_PROPERTY( KnobStyle knobStyle READ knobStyle WRITE setKnobStyle )
+
49  Q_PROPERTY( int knobWidth READ knobWidth WRITE setKnobWidth )
+
50  Q_PROPERTY( Qt::Alignment alignment READ alignment WRITE setAlignment )
+
51  Q_PROPERTY( double totalAngle READ totalAngle WRITE setTotalAngle )
+
52  Q_PROPERTY( int numTurns READ numTurns WRITE setNumTurns )
+
53  Q_PROPERTY( MarkerStyle markerStyle READ markerStyle WRITE setMarkerStyle )
+
54  Q_PROPERTY( int markerSize READ markerSize WRITE setMarkerSize )
+
55  Q_PROPERTY( int borderWidth READ borderWidth WRITE setBorderWidth )
+
56 
+
57 public:
+
66  enum KnobStyle
+
67  {
+ +
70 
+ +
73 
+ +
79 
+
84  Styled
+
85  };
+
86 
+
95  enum MarkerStyle
+
96  {
+
98  NoMarker = -1,
+
99 
+ +
102 
+ +
105 
+
107  Dot,
+
108 
+
113  Nub,
+
114 
+
119  Notch
+
120  };
+
121 
+
122  explicit QwtKnob( QWidget* parent = NULL );
+
123  virtual ~QwtKnob();
+
124 
+
125  void setAlignment( Qt::Alignment );
+
126  Qt::Alignment alignment() const;
+
127 
+
128  void setKnobWidth( int );
+
129  int knobWidth() const;
+
130 
+
131  void setNumTurns( int );
+
132  int numTurns() const;
+
133 
+
134  void setTotalAngle ( double angle );
+
135  double totalAngle() const;
+
136 
+
137  void setKnobStyle( KnobStyle );
+
138  KnobStyle knobStyle() const;
+
139 
+
140  void setBorderWidth( int bw );
+
141  int borderWidth() const;
+
142 
+
143  void setMarkerStyle( MarkerStyle );
+
144  MarkerStyle markerStyle() const;
+
145 
+
146  void setMarkerSize( int );
+
147  int markerSize() const;
+
148 
+
149  virtual QSize sizeHint() const;
+
150  virtual QSize minimumSizeHint() const;
+
151 
+
152  void setScaleDraw( QwtRoundScaleDraw * );
+
153 
+
154  const QwtRoundScaleDraw *scaleDraw() const;
+
155  QwtRoundScaleDraw *scaleDraw();
+
156 
+
157  QRect knobRect() const;
+
158 
+
159 protected:
+
160  virtual void paintEvent( QPaintEvent * );
+
161  virtual void changeEvent( QEvent * );
+
162 
+
163  virtual void drawKnob( QPainter *, const QRectF & ) const;
+
164 
+
165  virtual void drawFocusIndicator( QPainter * ) const;
+
166 
+
167  virtual void drawMarker( QPainter *,
+
168  const QRectF &, double arc ) const;
+
169 
+
170  virtual double scrolledTo( const QPoint & ) const;
+
171  virtual bool isScrollPosition( const QPoint & ) const;
+
172 
+
173 private:
+
174  class PrivateData;
+
175  PrivateData *d_data;
+
176 };
+
177 
+
178 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__legend_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__legend_8h_source.html new file mode 100644 index 0000000000..d9d2973d4f --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__legend_8h_source.html @@ -0,0 +1,175 @@ + + + + + + +Qwt User's Guide: qwt_legend.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_legend.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_LEGEND_H
+
11 #define QWT_LEGEND_H
+
12 
+
13 #include "qwt_global.h"
+
14 #include "qwt_abstract_legend.h"
+
15 #include <qvariant.h>
+
16 
+
17 class QScrollBar;
+
18 
+
29 class QWT_EXPORT QwtLegend : public QwtAbstractLegend
+
30 {
+
31  Q_OBJECT
+
32 
+
33 public:
+
34  explicit QwtLegend( QWidget *parent = NULL );
+
35  virtual ~QwtLegend();
+
36 
+
37  void setMaxColumns( uint numColums );
+
38  uint maxColumns() const;
+
39 
+
40  void setDefaultItemMode( QwtLegendData::Mode );
+
41  QwtLegendData::Mode defaultItemMode() const;
+
42 
+
43  QWidget *contentsWidget();
+
44  const QWidget *contentsWidget() const;
+
45 
+
46  QWidget *legendWidget( const QVariant & ) const;
+
47  QList<QWidget *> legendWidgets( const QVariant & ) const;
+
48 
+
49  QVariant itemInfo( const QWidget * ) const;
+
50 
+
51  virtual bool eventFilter( QObject *, QEvent * );
+
52 
+
53  virtual QSize sizeHint() const;
+
54  virtual int heightForWidth( int w ) const;
+
55 
+
56  QScrollBar *horizontalScrollBar() const;
+
57  QScrollBar *verticalScrollBar() const;
+
58 
+
59  virtual void renderLegend( QPainter *,
+
60  const QRectF &, bool fillBackground ) const;
+
61 
+
62  virtual void renderItem( QPainter *,
+
63  const QWidget *, const QRectF &, bool fillBackground ) const;
+
64 
+
65  virtual bool isEmpty() const;
+
66  virtual int scrollExtent( Qt::Orientation ) const;
+
67 
+
68 Q_SIGNALS:
+
81  void clicked( const QVariant &itemInfo, int index );
+
82 
+
96  void checked( const QVariant &itemInfo, bool on, int index );
+
97 
+
98 public Q_SLOTS:
+
99  virtual void updateLegend( const QVariant &,
+
100  const QList<QwtLegendData> & );
+
101 
+
102 protected Q_SLOTS:
+
103  void itemClicked();
+
104  void itemChecked( bool );
+
105 
+
106 protected:
+
107  virtual QWidget *createWidget( const QwtLegendData & ) const;
+
108  virtual void updateWidget( QWidget *widget, const QwtLegendData &data );
+
109 
+
110 private:
+
111  void updateTabOrder();
+
112 
+
113  class PrivateData;
+
114  PrivateData *d_data;
+
115 };
+
116 
+
117 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__legend__data_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__legend__data_8h_source.html new file mode 100644 index 0000000000..771830a6e3 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__legend__data_8h_source.html @@ -0,0 +1,160 @@ + + + + + + +Qwt User's Guide: qwt_legend_data.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_legend_data.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_LEGEND_DATA_H
+
11 #define QWT_LEGEND_DATA_H
+
12 
+
13 #include "qwt_global.h"
+
14 #include "qwt_text.h"
+
15 #include "qwt_graphic.h"
+
16 #include <qvariant.h>
+
17 #include <qpixmap.h>
+
18 #include <qmap.h>
+
19 
+
35 class QWT_EXPORT QwtLegendData
+
36 {
+
37 public:
+
39  enum Mode
+
40  {
+ +
43 
+ +
46 
+
48  Checkable
+
49  };
+
50 
+
52  enum Role
+
53  {
+
54  // The value is a Mode
+
55  ModeRole,
+
56 
+
57  // The value is a title
+
58  TitleRole,
+
59 
+
60  // The value is an icon
+
61  IconRole,
+
62 
+
63  // Values < UserRole are reserved for internal use
+
64  UserRole = 32
+
65  };
+
66 
+
67  QwtLegendData();
+
68  ~QwtLegendData();
+
69 
+
70  void setValues( const QMap<int, QVariant> & );
+
71  const QMap<int, QVariant> &values() const;
+
72 
+
73  void setValue( int role, const QVariant & );
+
74  QVariant value( int role ) const;
+
75 
+
76  bool hasRole( int role ) const;
+
77  bool isValid() const;
+
78 
+
79  QwtGraphic icon() const;
+
80  QwtText title() const;
+
81  Mode mode() const;
+
82 
+
83 private:
+
84  QMap<int, QVariant> d_map;
+
85 };
+
86 
+
87 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__legend__label_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__legend__label_8h_source.html new file mode 100644 index 0000000000..7851d4a1f9 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__legend__label_8h_source.html @@ -0,0 +1,166 @@ + + + + + + +Qwt User's Guide: qwt_legend_label.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_legend_label.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_LEGEND_LABEL_H
+
11 #define QWT_LEGEND_LABEL_H
+
12 
+
13 #include "qwt_global.h"
+
14 #include "qwt_legend_data.h"
+
15 #include "qwt_text.h"
+
16 #include "qwt_text_label.h"
+
17 #include <qpixmap.h>
+
18 
+
19 class QwtLegendData;
+
20 
+
24 class QWT_EXPORT QwtLegendLabel: public QwtTextLabel
+
25 {
+
26  Q_OBJECT
+
27 public:
+
28  explicit QwtLegendLabel( QWidget *parent = 0 );
+
29  virtual ~QwtLegendLabel();
+
30 
+
31  void setData( const QwtLegendData & );
+
32  const QwtLegendData &data() const;
+
33 
+
34  void setItemMode( QwtLegendData::Mode );
+
35  QwtLegendData::Mode itemMode() const;
+
36 
+
37  void setSpacing( int spacing );
+
38  int spacing() const;
+
39 
+
40  virtual void setText( const QwtText & );
+
41 
+
42  void setIcon( const QPixmap & );
+
43  QPixmap icon() const;
+
44 
+
45  virtual QSize sizeHint() const;
+
46 
+
47  bool isChecked() const;
+
48 
+
49 public Q_SLOTS:
+
50  void setChecked( bool on );
+
51 
+
52 Q_SIGNALS:
+
54  void clicked();
+
55 
+
57  void pressed();
+
58 
+
60  void released();
+
61 
+
63  void checked( bool );
+
64 
+
65 protected:
+
66  void setDown( bool );
+
67  bool isDown() const;
+
68 
+
69  virtual void paintEvent( QPaintEvent * );
+
70  virtual void mousePressEvent( QMouseEvent * );
+
71  virtual void mouseReleaseEvent( QMouseEvent * );
+
72  virtual void keyPressEvent( QKeyEvent * );
+
73  virtual void keyReleaseEvent( QKeyEvent * );
+
74 
+
75 private:
+
76  class PrivateData;
+
77  PrivateData *d_data;
+
78 };
+
79 
+
80 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__magnifier_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__magnifier_8h_source.html new file mode 100644 index 0000000000..ab34a012ed --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__magnifier_8h_source.html @@ -0,0 +1,169 @@ + + + + + + +Qwt User's Guide: qwt_magnifier.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_magnifier.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_MAGNIFIER_H
+
11 #define QWT_MAGNIFIER_H 1
+
12 
+
13 #include "qwt_global.h"
+
14 #include <qobject.h>
+
15 
+
16 class QWidget;
+
17 class QMouseEvent;
+
18 class QWheelEvent;
+
19 class QKeyEvent;
+
20 
+
27 class QWT_EXPORT QwtMagnifier: public QObject
+
28 {
+
29  Q_OBJECT
+
30 
+
31 public:
+
32  explicit QwtMagnifier( QWidget * );
+
33  virtual ~QwtMagnifier();
+
34 
+
35  QWidget *parentWidget();
+
36  const QWidget *parentWidget() const;
+
37 
+
38  void setEnabled( bool );
+
39  bool isEnabled() const;
+
40 
+
41  // mouse
+
42  void setMouseFactor( double );
+
43  double mouseFactor() const;
+
44 
+
45  void setMouseButton( Qt::MouseButton, Qt::KeyboardModifiers = Qt::NoModifier );
+
46  void getMouseButton( Qt::MouseButton &, Qt::KeyboardModifiers & ) const;
+
47 
+
48  // mouse wheel
+
49  void setWheelFactor( double );
+
50  double wheelFactor() const;
+
51 
+
52  void setWheelModifiers( Qt::KeyboardModifiers );
+
53  Qt::KeyboardModifiers wheelModifiers() const;
+
54 
+
55  // keyboard
+
56  void setKeyFactor( double );
+
57  double keyFactor() const;
+
58 
+
59  void setZoomInKey( int key, Qt::KeyboardModifiers = Qt::NoModifier );
+
60  void getZoomInKey( int &key, Qt::KeyboardModifiers & ) const;
+
61 
+
62  void setZoomOutKey( int key, Qt::KeyboardModifiers = Qt::NoModifier );
+
63  void getZoomOutKey( int &key, Qt::KeyboardModifiers & ) const;
+
64 
+
65  virtual bool eventFilter( QObject *, QEvent * );
+
66 
+
67 protected:
+
72  virtual void rescale( double factor ) = 0;
+
73 
+
74  virtual void widgetMousePressEvent( QMouseEvent * );
+
75  virtual void widgetMouseReleaseEvent( QMouseEvent * );
+
76  virtual void widgetMouseMoveEvent( QMouseEvent * );
+
77  virtual void widgetWheelEvent( QWheelEvent * );
+
78  virtual void widgetKeyPressEvent( QKeyEvent * );
+
79  virtual void widgetKeyReleaseEvent( QKeyEvent * );
+
80 
+
81 private:
+
82  class PrivateData;
+
83  PrivateData *d_data;
+
84 };
+
85 
+
86 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__math_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__math_8h_source.html new file mode 100644 index 0000000000..7b91e9c731 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__math_8h_source.html @@ -0,0 +1,226 @@ + + + + + + +Qwt User's Guide: qwt_math.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_math.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_MATH_H
+
11 #define QWT_MATH_H
+
12 
+
13 #include "qwt_global.h"
+
14 
+
15 #if defined(_MSC_VER)
+
16 /*
+
17  Microsoft says:
+
18 
+
19  Define _USE_MATH_DEFINES before including math.h to expose these macro
+
20  definitions for common math constants. These are placed under an #ifdef
+
21  since these commonly-defined names are not part of the C/C++ standards.
+
22 */
+
23 #define _USE_MATH_DEFINES 1
+
24 #endif
+
25 
+
26 #include <qmath.h>
+
27 #include "qwt_global.h"
+
28 
+
29 #ifndef M_PI_2
+
30 // For Qt <= 4.8.4 M_PI_2 is not known by MinGW-w64
+
31 // when compiling with -std=c++11
+
32 #define M_PI_2 (1.57079632679489661923)
+
33 #endif
+
34 
+
35 #ifndef LOG_MIN
+
36 
+
37 #define LOG_MIN 1.0e-100
+
38 #endif
+
39 
+
40 #ifndef LOG_MAX
+
41 
+
42 #define LOG_MAX 1.0e100
+
43 #endif
+
44 
+
45 QWT_EXPORT double qwtGetMin( const double *array, int size );
+
46 QWT_EXPORT double qwtGetMax( const double *array, int size );
+
47 
+
48 QWT_EXPORT double qwtNormalizeRadians( double radians );
+
49 QWT_EXPORT double qwtNormalizeDegrees( double degrees );
+
50 
+
63 inline int qwtFuzzyCompare( double value1, double value2, double intervalSize )
+
64 {
+
65  const double eps = qAbs( 1.0e-6 * intervalSize );
+
66 
+
67  if ( value2 - value1 > eps )
+
68  return -1;
+
69 
+
70  if ( value1 - value2 > eps )
+
71  return 1;
+
72 
+
73  return 0;
+
74 }
+
75 
+
76 
+
77 inline bool qwtFuzzyGreaterOrEqual( double d1, double d2 )
+
78 {
+
79  return ( d1 >= d2 ) || qFuzzyCompare( d1, d2 );
+
80 }
+
81 
+
82 inline bool qwtFuzzyLessOrEqual( double d1, double d2 )
+
83 {
+
84  return ( d1 <= d2 ) || qFuzzyCompare( d1, d2 );
+
85 }
+
86 
+
88 inline int qwtSign( double x )
+
89 {
+
90  if ( x > 0.0 )
+
91  return 1;
+
92  else if ( x < 0.0 )
+
93  return ( -1 );
+
94  else
+
95  return 0;
+
96 }
+
97 
+
99 inline double qwtSqr( double x )
+
100 {
+
101  return x * x;
+
102 }
+
103 
+
105 inline double qwtFastAtan( double x )
+
106 {
+
107  if ( x < -1.0 )
+
108  return -M_PI_2 - x / ( x * x + 0.28 );
+
109 
+
110  if ( x > 1.0 )
+
111  return M_PI_2 - x / ( x * x + 0.28 );
+
112 
+
113  return x / ( 1.0 + x * x * 0.28 );
+
114 }
+
115 
+
117 inline double qwtFastAtan2( double y, double x )
+
118 {
+
119  if ( x > 0 )
+
120  return qwtFastAtan( y / x );
+
121 
+
122  if ( x < 0 )
+
123  {
+
124  const double d = qwtFastAtan( y / x );
+
125  return ( y >= 0 ) ? d + M_PI : d - M_PI;
+
126  }
+
127 
+
128  if ( y < 0.0 )
+
129  return -M_PI_2;
+
130 
+
131  if ( y > 0.0 )
+
132  return M_PI_2;
+
133 
+
134  return 0.0;
+
135 }
+
136 
+
137 // Translate degrees into radians
+
138 inline double qwtRadians( double degrees )
+
139 {
+
140  return degrees * M_PI / 180.0;
+
141 }
+
142 
+
143 // Translate radians into degrees
+
144 inline double qwtDegrees( double degrees )
+
145 {
+
146  return degrees * 180.0 / M_PI;
+
147 }
+
148 
+
149 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__mathml__text__engine_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__mathml__text__engine_8h_source.html new file mode 100644 index 0000000000..f07fd1a0c7 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__mathml__text__engine_8h_source.html @@ -0,0 +1,131 @@ + + + + + + +Qwt User's Guide: qwt_mathml_text_engine.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_mathml_text_engine.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2003 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 // vim: expandtab
+
11 
+
12 #ifndef QWT_MATHML_TEXT_ENGINE_H
+
13 #define QWT_MATHML_TEXT_ENGINE_H 1
+
14 
+
15 #include "qwt_text_engine.h"
+
16 
+
32 class QWT_EXPORT QwtMathMLTextEngine: public QwtTextEngine
+
33 {
+
34 public:
+ +
36  virtual ~QwtMathMLTextEngine();
+
37 
+
38  virtual double heightForWidth( const QFont &font, int flags,
+
39  const QString &text, double width ) const;
+
40 
+
41  virtual QSizeF textSize( const QFont &font, int flags,
+
42  const QString &text ) const;
+
43 
+
44  virtual void draw( QPainter *painter, const QRectF &rect,
+
45  int flags, const QString &text ) const;
+
46 
+
47  virtual bool mightRender( const QString & ) const;
+
48 
+
49  virtual void textMargins( const QFont &, const QString &,
+
50  double &left, double &right, double &top, double &bottom ) const;
+
51 };
+
52 
+
53 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__matrix__raster__data_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__matrix__raster__data_8h_source.html new file mode 100644 index 0000000000..e07bbe62ff --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__matrix__raster__data_8h_source.html @@ -0,0 +1,147 @@ + + + + + + +Qwt User's Guide: qwt_matrix_raster_data.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_matrix_raster_data.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_MATRIX_RASTER_DATA_H
+
11 #define QWT_MATRIX_RASTER_DATA_H 1
+
12 
+
13 #include "qwt_global.h"
+
14 #include "qwt_raster_data.h"
+
15 #include <qvector.h>
+
16 
+
25 class QWT_EXPORT QwtMatrixRasterData: public QwtRasterData
+
26 {
+
27 public:
+ +
33  {
+ +
39 
+
44  BilinearInterpolation
+
45  };
+
46 
+ +
48  virtual ~QwtMatrixRasterData();
+
49 
+
50  void setResampleMode(ResampleMode mode);
+
51  ResampleMode resampleMode() const;
+
52 
+
53  virtual void setInterval( Qt::Axis, const QwtInterval & );
+
54 
+
55  void setValueMatrix( const QVector<double> &values, int numColumns );
+
56  const QVector<double> valueMatrix() const;
+
57 
+
58  void setValue( int row, int col, double value );
+
59 
+
60  int numColumns() const;
+
61  int numRows() const;
+
62 
+
63  virtual QRectF pixelHint( const QRectF & ) const;
+
64 
+
65  virtual double value( double x, double y ) const;
+
66 
+
67 private:
+
68  void update();
+
69 
+
70  class PrivateData;
+
71  PrivateData *d_data;
+
72 };
+
73 
+
74 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__mml__document_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__mml__document_8h_source.html new file mode 100644 index 0000000000..5a5d89a582 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__mml__document_8h_source.html @@ -0,0 +1,138 @@ + + + + + + +Qwt User's Guide: qwt_mml_document.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_mml_document.h
+
+
+
1 #ifndef _QWT_MML_DOCUMENT_H_
+
2 #define _QWT_MML_DOCUMENT_H_ 1
+
3 
+
4 #include <qwt_global.h>
+
5 #include <QString>
+
6 
+
7 class QPainter;
+
8 class QPoint;
+
9 
+
10 class QwtMmlDocument;
+
11 
+
12 class QWT_EXPORT QwtMathMLDocument
+
13 {
+
14 public:
+
15  enum MmlFont
+
16  {
+
17  NormalFont,
+
18  FrakturFont,
+
19  SansSerifFont,
+
20  ScriptFont,
+
21  MonospaceFont,
+
22  DoublestruckFont
+
23  };
+
24 
+
25  QwtMathMLDocument();
+
26  ~QwtMathMLDocument();
+
27 
+
28  void clear();
+
29 
+
30  bool setContent( QString text, QString *errorMsg = 0,
+
31  int *errorLine = 0, int *errorColumn = 0 );
+
32  void paint( QPainter *p, const QPoint &pos ) const;
+
33  QSize size() const;
+
34 
+
35  QString fontName( MmlFont type ) const;
+
36  void setFontName( MmlFont type, const QString &name );
+
37 
+
38  int baseFontPointSize() const;
+
39  void setBaseFontPointSize( int size );
+
40 
+
41 private:
+
42  QwtMmlDocument *m_doc;
+
43 };
+
44 
+
45 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__null__paintdevice_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__null__paintdevice_8h_source.html new file mode 100644 index 0000000000..968dc3ccf1 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__null__paintdevice_8h_source.html @@ -0,0 +1,176 @@ + + + + + + +Qwt User's Guide: qwt_null_paintdevice.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_null_paintdevice.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_NULL_PAINT_DEVICE_H
+
11 #define QWT_NULL_PAINT_DEVICE_H 1
+
12 
+
13 #include "qwt_global.h"
+
14 #include <qpaintdevice.h>
+
15 #include <qpaintengine.h>
+
16 
+
31 class QWT_EXPORT QwtNullPaintDevice: public QPaintDevice
+
32 {
+
33 public:
+
39  enum Mode
+
40  {
+ +
46 
+ +
58 
+
68  PathMode
+
69  };
+
70 
+ +
72  virtual ~QwtNullPaintDevice();
+
73 
+
74  void setMode( Mode );
+
75  Mode mode() const;
+
76 
+
77  virtual QPaintEngine *paintEngine() const;
+
78 
+
79  virtual int metric( PaintDeviceMetric metric ) const;
+
80 
+
81  virtual void drawRects(const QRect *, int );
+
82  virtual void drawRects(const QRectF *, int );
+
83 
+
84  virtual void drawLines(const QLine *, int );
+
85  virtual void drawLines(const QLineF *, int );
+
86 
+
87  virtual void drawEllipse(const QRectF &);
+
88  virtual void drawEllipse(const QRect &);
+
89 
+
90  virtual void drawPath(const QPainterPath &);
+
91 
+
92  virtual void drawPoints(const QPointF *, int );
+
93  virtual void drawPoints(const QPoint *, int );
+
94 
+
95  virtual void drawPolygon(
+
96  const QPointF *, int , QPaintEngine::PolygonDrawMode );
+
97 
+
98  virtual void drawPolygon(
+
99  const QPoint *, int , QPaintEngine::PolygonDrawMode );
+
100 
+
101  virtual void drawPixmap(const QRectF &,
+
102  const QPixmap &, const QRectF &);
+
103 
+
104  virtual void drawTextItem(const QPointF &, const QTextItem &);
+
105 
+
106  virtual void drawTiledPixmap(const QRectF &,
+
107  const QPixmap &, const QPointF &s);
+
108 
+
109  virtual void drawImage(const QRectF &,
+
110  const QImage &, const QRectF &, Qt::ImageConversionFlags );
+
111 
+
112  virtual void updateState( const QPaintEngineState &state );
+
113 
+
114 protected:
+
116  virtual QSize sizeMetrics() const = 0;
+
117 
+
118 private:
+
119  class PaintEngine;
+
120  PaintEngine *d_engine;
+
121 
+
122  class PrivateData;
+
123  PrivateData *d_data;
+
124 };
+
125 
+
126 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__painter_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__painter_8h_source.html new file mode 100644 index 0000000000..7f461f95de --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__painter_8h_source.html @@ -0,0 +1,257 @@ + + + + + + +Qwt User's Guide: qwt_painter.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_painter.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_PAINTER_H
+
11 #define QWT_PAINTER_H
+
12 
+
13 #include "qwt_global.h"
+
14 
+
15 #include <qpoint.h>
+
16 #include <qrect.h>
+
17 #include <qpen.h>
+
18 #include <qline.h>
+
19 #include <qpalette.h>
+
20 
+
21 class QPainter;
+
22 class QBrush;
+
23 class QColor;
+
24 class QWidget;
+
25 class QPolygonF;
+
26 class QRectF;
+
27 class QImage;
+
28 class QPixmap;
+
29 class QwtScaleMap;
+
30 class QwtColorMap;
+
31 class QwtInterval;
+
32 
+
33 class QTextDocument;
+
34 class QPainterPath;
+
35 
+
39 class QWT_EXPORT QwtPainter
+
40 {
+
41 public:
+
42  static void setPolylineSplitting( bool );
+
43  static bool polylineSplitting();
+
44 
+
45  static void setRoundingAlignment( bool );
+
46  static bool roundingAlignment();
+
47  static bool roundingAlignment(QPainter *);
+
48 
+
49  static void drawText( QPainter *, double x, double y, const QString & );
+
50  static void drawText( QPainter *, const QPointF &, const QString & );
+
51  static void drawText( QPainter *, double x, double y, double w, double h,
+
52  int flags, const QString & );
+
53  static void drawText( QPainter *, const QRectF &,
+
54  int flags, const QString & );
+
55 
+
56 #ifndef QT_NO_RICHTEXT
+
57  static void drawSimpleRichText( QPainter *, const QRectF &,
+
58  int flags, const QTextDocument & );
+
59 #endif
+
60 
+
61  static void drawRect( QPainter *, double x, double y, double w, double h );
+
62  static void drawRect( QPainter *, const QRectF &rect );
+
63  static void fillRect( QPainter *, const QRectF &, const QBrush & );
+
64 
+
65  static void drawEllipse( QPainter *, const QRectF & );
+
66  static void drawPie( QPainter *, const QRectF & r, int a, int alen );
+
67 
+
68  static void drawLine( QPainter *, double x1, double y1, double x2, double y2 );
+
69  static void drawLine( QPainter *, const QPointF &p1, const QPointF &p2 );
+
70  static void drawLine( QPainter *, const QLineF & );
+
71 
+
72  static void drawPolygon( QPainter *, const QPolygonF & );
+
73  static void drawPolyline( QPainter *, const QPolygonF & );
+
74  static void drawPolyline( QPainter *, const QPointF *, int pointCount );
+
75 
+
76  static void drawPolygon( QPainter *, const QPolygon & );
+
77  static void drawPolyline( QPainter *, const QPolygon & );
+
78  static void drawPolyline( QPainter *, const QPoint *, int pointCount );
+
79 
+
80  static void drawPoint( QPainter *, const QPoint & );
+
81  static void drawPoints( QPainter *, const QPolygon & );
+
82  static void drawPoints( QPainter *, const QPoint *, int pointCount );
+
83 
+
84  static void drawPoint( QPainter *, double x, double y );
+
85  static void drawPoint( QPainter *, const QPointF & );
+
86  static void drawPoints( QPainter *, const QPolygonF & );
+
87  static void drawPoints( QPainter *, const QPointF *, int pointCount );
+
88 
+
89  static void drawPath( QPainter *, const QPainterPath & );
+
90  static void drawImage( QPainter *, const QRectF &, const QImage & );
+
91  static void drawPixmap( QPainter *, const QRectF &, const QPixmap & );
+
92 
+
93  static void drawRoundFrame( QPainter *,
+
94  const QRectF &, const QPalette &, int lineWidth, int frameStyle );
+
95 
+
96  static void drawRoundedFrame( QPainter *,
+
97  const QRectF &, double xRadius, double yRadius,
+
98  const QPalette &, int lineWidth, int frameStyle );
+
99 
+
100  static void drawFrame( QPainter *, const QRectF &rect,
+
101  const QPalette &palette, QPalette::ColorRole foregroundRole,
+
102  int lineWidth, int midLineWidth, int frameStyle );
+
103 
+
104  static void drawFocusRect( QPainter *, const QWidget * );
+
105  static void drawFocusRect( QPainter *, const QWidget *, const QRect & );
+
106 
+
107  static void drawColorBar( QPainter *painter,
+
108  const QwtColorMap &, const QwtInterval &,
+
109  const QwtScaleMap &, Qt::Orientation, const QRectF & );
+
110 
+
111  static bool isAligning( QPainter *painter );
+
112  static bool isX11GraphicsSystem();
+
113 
+
114  static void fillPixmap( const QWidget *,
+
115  QPixmap &, const QPoint &offset = QPoint() );
+
116 
+
117  static void drawBackgound( QPainter *painter,
+
118  const QRectF &rect, const QWidget *widget );
+
119 
+
120  static QPixmap backingStore( QWidget *, const QSize & );
+
121 
+
122 private:
+
123  static bool d_polylineSplitting;
+
124  static bool d_roundingAlignment;
+
125 };
+
126 
+
128 inline void QwtPainter::drawPoint( QPainter *painter, double x, double y )
+
129 {
+
130  QwtPainter::drawPoint( painter, QPointF( x, y ) );
+
131 }
+
132 
+
134 inline void QwtPainter::drawPoints( QPainter *painter, const QPolygon &polygon )
+
135 {
+
136  drawPoints( painter, polygon.data(), polygon.size() );
+
137 }
+
138 
+
140 inline void QwtPainter::drawPoints( QPainter *painter, const QPolygonF &polygon )
+
141 {
+
142  drawPoints( painter, polygon.data(), polygon.size() );
+
143 }
+
144 
+
146 inline void QwtPainter::drawLine( QPainter *painter,
+
147  double x1, double y1, double x2, double y2 )
+
148 {
+
149  QwtPainter::drawLine( painter, QPointF( x1, y1 ), QPointF( x2, y2 ) );
+
150 }
+
151 
+
153 inline void QwtPainter::drawLine( QPainter *painter, const QLineF &line )
+
154 {
+
155  QwtPainter::drawLine( painter, line.p1(), line.p2() );
+
156 }
+
157 
+ +
163 {
+
164  return d_polylineSplitting;
+
165 }
+
166 
+ +
176 {
+
177  return d_roundingAlignment;
+
178 }
+
179 
+
184 inline bool QwtPainter::roundingAlignment(QPainter *painter)
+
185 {
+
186  return d_roundingAlignment && isAligning(painter);
+
187 }
+
188 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__painter__command_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__painter__command_8h_source.html new file mode 100644 index 0000000000..a3a9d3d122 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__painter__command_8h_source.html @@ -0,0 +1,243 @@ + + + + + + +Qwt User's Guide: qwt_painter_command.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_painter_command.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_PAINTER_COMMAND_H
+
11 #define QWT_PAINTER_COMMAND_H
+
12 
+
13 #include "qwt_global.h"
+
14 #include <qpaintengine.h>
+
15 #include <qpixmap.h>
+
16 #include <qimage.h>
+
17 #include <qpolygon.h>
+
18 
+
19 class QPainterPath;
+
20 
+
30 class QWT_EXPORT QwtPainterCommand
+
31 {
+
32 public:
+
34  enum Type
+
35  {
+
37  Invalid = -1,
+
38 
+ +
41 
+ +
44 
+ +
47 
+
49  State
+
50  };
+
51 
+
53  struct PixmapData
+
54  {
+
55  QRectF rect;
+
56  QPixmap pixmap;
+
57  QRectF subRect;
+
58  };
+
59 
+
61  struct ImageData
+
62  {
+
63  QRectF rect;
+
64  QImage image;
+
65  QRectF subRect;
+
66  Qt::ImageConversionFlags flags;
+
67  };
+
68 
+
70  struct StateData
+
71  {
+
72  QPaintEngine::DirtyFlags flags;
+
73 
+
74  QPen pen;
+
75  QBrush brush;
+
76  QPointF brushOrigin;
+
77  QBrush backgroundBrush;
+
78  Qt::BGMode backgroundMode;
+
79  QFont font;
+
80  QMatrix matrix;
+
81  QTransform transform;
+
82 
+
83  Qt::ClipOperation clipOperation;
+
84  QRegion clipRegion;
+
85  QPainterPath clipPath;
+
86  bool isClipEnabled;
+
87 
+
88  QPainter::RenderHints renderHints;
+
89  QPainter::CompositionMode compositionMode;
+
90  qreal opacity;
+
91  };
+
92 
+ + +
95 
+
96  QwtPainterCommand( const QPainterPath & );
+
97 
+
98  QwtPainterCommand( const QRectF &rect,
+
99  const QPixmap &, const QRectF& subRect );
+
100 
+
101  QwtPainterCommand( const QRectF &rect,
+
102  const QImage &, const QRectF& subRect,
+
103  Qt::ImageConversionFlags );
+
104 
+
105  QwtPainterCommand( const QPaintEngineState & );
+
106 
+ +
108 
+
109  QwtPainterCommand &operator=(const QwtPainterCommand & );
+
110 
+
111  Type type() const;
+
112 
+
113  QPainterPath *path();
+
114  const QPainterPath *path() const;
+
115 
+
116  PixmapData* pixmapData();
+
117  const PixmapData* pixmapData() const;
+
118 
+
119  ImageData* imageData();
+
120  const ImageData* imageData() const;
+
121 
+
122  StateData* stateData();
+
123  const StateData* stateData() const;
+
124 
+
125 private:
+
126  void copy( const QwtPainterCommand & );
+
127  void reset();
+
128 
+
129  Type d_type;
+
130 
+
131  union
+
132  {
+
133  QPainterPath *d_path;
+
134  PixmapData *d_pixmapData;
+
135  ImageData *d_imageData;
+
136  StateData *d_stateData;
+
137  };
+
138 };
+
139 
+ +
142 {
+
143  return d_type;
+
144 }
+
145 
+
147 inline const QPainterPath *QwtPainterCommand::path() const
+
148 {
+
149  return d_path;
+
150 }
+
151 
+
153 inline const QwtPainterCommand::PixmapData*
+ +
155 {
+
156  return d_pixmapData;
+
157 }
+
158 
+
160 inline const QwtPainterCommand::ImageData *
+ +
162 {
+
163  return d_imageData;
+
164 }
+
165 
+
167 inline const QwtPainterCommand::StateData *
+ +
169 {
+
170  return d_stateData;
+
171 }
+
172 
+
173 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__panner_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__panner_8h_source.html new file mode 100644 index 0000000000..22a7d05893 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__panner_8h_source.html @@ -0,0 +1,167 @@ + + + + + + +Qwt User's Guide: qwt_panner.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_panner.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_PANNER_H
+
11 #define QWT_PANNER_H 1
+
12 
+
13 #include "qwt_global.h"
+
14 #include <qwidget.h>
+
15 #include <qpixmap.h>
+
16 
+
17 class QCursor;
+
18 
+
35 class QWT_EXPORT QwtPanner: public QWidget
+
36 {
+
37  Q_OBJECT
+
38 
+
39 public:
+
40  QwtPanner( QWidget* parent );
+
41  virtual ~QwtPanner();
+
42 
+
43  void setEnabled( bool );
+
44  bool isEnabled() const;
+
45 
+
46  void setMouseButton( Qt::MouseButton,
+
47  Qt::KeyboardModifiers = Qt::NoModifier );
+
48  void getMouseButton( Qt::MouseButton &button,
+
49  Qt::KeyboardModifiers & ) const;
+
50 
+
51  void setAbortKey( int key, Qt::KeyboardModifiers = Qt::NoModifier );
+
52  void getAbortKey( int &key, Qt::KeyboardModifiers & ) const;
+
53 
+
54  void setCursor( const QCursor & );
+
55  const QCursor cursor() const;
+
56 
+
57  void setOrientations( Qt::Orientations );
+
58  Qt::Orientations orientations() const;
+
59 
+
60  bool isOrientationEnabled( Qt::Orientation ) const;
+
61 
+
62  virtual bool eventFilter( QObject *, QEvent * );
+
63 
+
64 Q_SIGNALS:
+
71  void panned( int dx, int dy );
+
72 
+
80  void moved( int dx, int dy );
+
81 
+
82 protected:
+
83  virtual void widgetMousePressEvent( QMouseEvent * );
+
84  virtual void widgetMouseReleaseEvent( QMouseEvent * );
+
85  virtual void widgetMouseMoveEvent( QMouseEvent * );
+
86  virtual void widgetKeyPressEvent( QKeyEvent * );
+
87  virtual void widgetKeyReleaseEvent( QKeyEvent * );
+
88 
+
89  virtual void paintEvent( QPaintEvent * );
+
90 
+
91  virtual QBitmap contentsMask() const;
+
92  virtual QPixmap grab() const;
+
93 
+
94 private:
+
95 #ifndef QT_NO_CURSOR
+
96  void showCursor( bool );
+
97 #endif
+
98 
+
99  class PrivateData;
+
100  PrivateData *d_data;
+
101 };
+
102 
+
103 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__picker_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__picker_8h_source.html new file mode 100644 index 0000000000..35a31cf039 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__picker_8h_source.html @@ -0,0 +1,281 @@ + + + + + + +Qwt User's Guide: qwt_picker.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_picker.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_PICKER
+
11 #define QWT_PICKER 1
+
12 
+
13 #include "qwt_global.h"
+
14 #include "qwt_text.h"
+
15 #include "qwt_event_pattern.h"
+
16 #include <qobject.h>
+
17 #include <qpen.h>
+
18 #include <qfont.h>
+
19 #include <qrect.h>
+
20 #include <qpainterpath.h>
+
21 
+
22 class QWidget;
+
23 class QMouseEvent;
+
24 class QWheelEvent;
+
25 class QKeyEvent;
+
26 class QwtPickerMachine;
+
27 class QwtWidgetOverlay;
+
28 
+
95 class QWT_EXPORT QwtPicker: public QObject, public QwtEventPattern
+
96 {
+
97  Q_OBJECT
+
98 
+ +
100 
+
101  Q_PROPERTY( bool isEnabled READ isEnabled WRITE setEnabled )
+
102  Q_PROPERTY( ResizeMode resizeMode READ resizeMode WRITE setResizeMode )
+
103 
+
104  Q_PROPERTY( DisplayMode trackerMode READ trackerMode WRITE setTrackerMode )
+
105  Q_PROPERTY( QPen trackerPen READ trackerPen WRITE setTrackerPen )
+
106  Q_PROPERTY( QFont trackerFont READ trackerFont WRITE setTrackerFont )
+
107 
+
108  Q_PROPERTY( RubberBand rubberBand READ rubberBand WRITE setRubberBand )
+
109  Q_PROPERTY( QPen rubberBandPen READ rubberBandPen WRITE setRubberBandPen )
+
110 
+
111 public:
+ +
120  {
+
122  NoRubberBand = 0,
+
123 
+ +
126 
+ +
129 
+ +
132 
+ +
135 
+ +
138 
+ +
141 
+
146  UserRubberBand = 100
+
147  };
+
148 
+ +
154  {
+ +
157 
+ +
160 
+
162  ActiveOnly
+
163  };
+
164 
+
173  enum ResizeMode
+
174  {
+ +
177 
+
179  KeepSize
+
180  };
+
181 
+
182  explicit QwtPicker( QWidget *parent );
+
183  explicit QwtPicker( RubberBand rubberBand,
+
184  DisplayMode trackerMode, QWidget * );
+
185 
+
186  virtual ~QwtPicker();
+
187 
+
188  void setStateMachine( QwtPickerMachine * );
+
189  const QwtPickerMachine *stateMachine() const;
+
190  QwtPickerMachine *stateMachine();
+
191 
+
192  void setRubberBand( RubberBand );
+
193  RubberBand rubberBand() const;
+
194 
+
195  void setTrackerMode( DisplayMode );
+
196  DisplayMode trackerMode() const;
+
197 
+
198  void setResizeMode( ResizeMode );
+
199  ResizeMode resizeMode() const;
+
200 
+
201  void setRubberBandPen( const QPen & );
+
202  QPen rubberBandPen() const;
+
203 
+
204  void setTrackerPen( const QPen & );
+
205  QPen trackerPen() const;
+
206 
+
207  void setTrackerFont( const QFont & );
+
208  QFont trackerFont() const;
+
209 
+
210  bool isEnabled() const;
+
211  bool isActive() const;
+
212 
+
213  virtual bool eventFilter( QObject *, QEvent * );
+
214 
+
215  QWidget *parentWidget();
+
216  const QWidget *parentWidget() const;
+
217 
+
218  virtual QPainterPath pickArea() const;
+
219 
+
220  virtual void drawRubberBand( QPainter * ) const;
+
221  virtual void drawTracker( QPainter * ) const;
+
222 
+
223  virtual QRegion rubberBandMask() const;
+
224 
+
225  virtual QwtText trackerText( const QPoint &pos ) const;
+
226  QPoint trackerPosition() const;
+
227  virtual QRect trackerRect( const QFont & ) const;
+
228 
+
229  QPolygon selection() const;
+
230 
+
231 public Q_SLOTS:
+
232  void setEnabled( bool );
+
233 
+
234 Q_SIGNALS:
+
242  void activated( bool on );
+
243 
+
250  void selected( const QPolygon &polygon );
+
251 
+
258  void appended( const QPoint &pos );
+
259 
+
267  void moved( const QPoint &pos );
+
268 
+
276  void removed( const QPoint &pos );
+
284  void changed( const QPolygon &selection );
+
285 
+
286 protected:
+
287  virtual QPolygon adjustedPoints( const QPolygon & ) const;
+
288 
+
289  virtual void transition( const QEvent * );
+
290 
+
291  virtual void begin();
+
292  virtual void append( const QPoint & );
+
293  virtual void move( const QPoint & );
+
294  virtual void remove();
+
295  virtual bool end( bool ok = true );
+
296 
+
297  virtual bool accept( QPolygon & ) const;
+
298  virtual void reset();
+
299 
+
300  virtual void widgetMousePressEvent( QMouseEvent * );
+
301  virtual void widgetMouseReleaseEvent( QMouseEvent * );
+
302  virtual void widgetMouseDoubleClickEvent( QMouseEvent * );
+
303  virtual void widgetMouseMoveEvent( QMouseEvent * );
+
304  virtual void widgetWheelEvent( QWheelEvent * );
+
305  virtual void widgetKeyPressEvent( QKeyEvent * );
+
306  virtual void widgetKeyReleaseEvent( QKeyEvent * );
+
307  virtual void widgetEnterEvent( QEvent * );
+
308  virtual void widgetLeaveEvent( QEvent * );
+
309 
+
310  virtual void stretchSelection( const QSize &oldSize,
+
311  const QSize &newSize );
+
312 
+
313  virtual void updateDisplay();
+
314 
+
315  const QwtWidgetOverlay *rubberBandOverlay() const;
+
316  const QwtWidgetOverlay *trackerOverlay() const;
+
317 
+
318  const QPolygon &pickedPoints() const;
+
319 
+
320 private:
+
321  void init( QWidget *, RubberBand rubberBand, DisplayMode trackerMode );
+
322 
+
323  void setMouseTracking( bool );
+
324 
+
325  class PrivateData;
+
326  PrivateData *d_data;
+
327 };
+
328 
+
329 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__picker__machine_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__picker__machine_8h_source.html new file mode 100644 index 0000000000..300170982c --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__picker__machine_8h_source.html @@ -0,0 +1,215 @@ + + + + + + +Qwt User's Guide: qwt_picker_machine.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_picker_machine.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_PICKER_MACHINE
+
11 #define QWT_PICKER_MACHINE 1
+
12 
+
13 #include "qwt_global.h"
+
14 #include <qlist.h>
+
15 
+
16 class QEvent;
+
17 class QwtEventPattern;
+
18 
+
28 class QWT_EXPORT QwtPickerMachine
+
29 {
+
30 public:
+ +
36  {
+
38  NoSelection = -1,
+
39 
+ +
42 
+ +
45 
+
47  PolygonSelection
+
48  };
+
49 
+
51  enum Command
+
52  {
+
53  Begin,
+
54  Append,
+
55  Move,
+
56  Remove,
+
57  End
+
58  };
+
59 
+
60  QwtPickerMachine( SelectionType );
+
61  virtual ~QwtPickerMachine();
+
62 
+
64  virtual QList<Command> transition(
+
65  const QwtEventPattern &, const QEvent * ) = 0;
+
66  void reset();
+
67 
+
68  int state() const;
+
69  void setState( int );
+
70 
+
71  SelectionType selectionType() const;
+
72 
+
73 private:
+
74  const SelectionType d_selectionType;
+
75  int d_state;
+
76 };
+
77 
+
85 class QWT_EXPORT QwtPickerTrackerMachine: public QwtPickerMachine
+
86 {
+
87 public:
+ +
89 
+
90  virtual QList<Command> transition(
+
91  const QwtEventPattern &, const QEvent * );
+
92 };
+
93 
+ +
103 {
+
104 public:
+ +
106 
+
107  virtual QList<Command> transition(
+
108  const QwtEventPattern &, const QEvent * );
+
109 };
+
110 
+ +
119 {
+
120 public:
+ +
122 
+
123  virtual QList<Command> transition(
+
124  const QwtEventPattern &, const QEvent * );
+
125 };
+
126 
+ +
141 {
+
142 public:
+ +
144 
+
145  virtual QList<Command> transition(
+
146  const QwtEventPattern &, const QEvent * );
+
147 };
+
148 
+ +
162 {
+
163 public:
+ +
165 
+
166  virtual QList<Command> transition(
+
167  const QwtEventPattern &, const QEvent * );
+
168 };
+
169 
+ +
186 {
+
187 public:
+ +
189 
+
190  virtual QList<Command> transition(
+
191  const QwtEventPattern &, const QEvent * );
+
192 };
+
193 
+ +
206 {
+
207 public:
+ +
209 
+
210  virtual QList<Command> transition(
+
211  const QwtEventPattern &, const QEvent * );
+
212 };
+
213 
+
214 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__pixel__matrix_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__pixel__matrix_8h_source.html new file mode 100644 index 0000000000..0903fb56dd --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__pixel__matrix_8h_source.html @@ -0,0 +1,159 @@ + + + + + + +Qwt User's Guide: qwt_pixel_matrix.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_pixel_matrix.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2003 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_PIXEL_MATRIX_H
+
11 #define QWT_PIXEL_MATRIX_H
+
12 
+
13 #include "qwt_global.h"
+
14 #include <qbitarray.h>
+
15 #include <qrect.h>
+
16 
+
23 class QWT_EXPORT QwtPixelMatrix: public QBitArray
+
24 {
+
25 public:
+
26  QwtPixelMatrix( const QRect& rect );
+
27  ~QwtPixelMatrix();
+
28 
+
29  void setRect( const QRect& rect );
+
30  QRect rect() const;
+
31 
+
32  bool testPixel( int x, int y ) const;
+
33  bool testAndSetPixel( int x, int y, bool on );
+
34 
+
35  int index( int x, int y ) const;
+
36 
+
37 private:
+
38  QRect d_rect;
+
39 };
+
40 
+
50 inline bool QwtPixelMatrix::testPixel( int x, int y ) const
+
51 {
+
52  const int idx = index( x, y );
+
53  return ( idx >= 0 ) ? testBit( idx ) : true;
+
54 }
+
55 
+
66 inline bool QwtPixelMatrix::testAndSetPixel( int x, int y, bool on )
+
67 {
+
68  const int idx = index( x, y );
+
69  if ( idx < 0 )
+
70  return true;
+
71 
+
72  const bool onBefore = testBit( idx );
+
73  setBit( idx, on );
+
74 
+
75  return onBefore;
+
76 }
+
77 
+
85 inline int QwtPixelMatrix::index( int x, int y ) const
+
86 {
+
87  const int dx = x - d_rect.x();
+
88  if ( dx < 0 || dx >= d_rect.width() )
+
89  return -1;
+
90 
+
91  const int dy = y - d_rect.y();
+
92  if ( dy < 0 || dy >= d_rect.height() )
+
93  return -1;
+
94 
+
95  return dy * d_rect.width() + dx;
+
96 }
+
97 
+
98 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__plot_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__plot_8h_source.html new file mode 100644 index 0000000000..084e93a7b4 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__plot_8h_source.html @@ -0,0 +1,330 @@ + + + + + + +Qwt User's Guide: qwt_plot.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_plot.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_PLOT_H
+
11 #define QWT_PLOT_H
+
12 
+
13 #include "qwt_global.h"
+
14 #include "qwt_text.h"
+
15 #include "qwt_plot_dict.h"
+
16 #include "qwt_scale_map.h"
+
17 #include "qwt_interval.h"
+
18 #include <qframe.h>
+
19 #include <qlist.h>
+
20 #include <qvariant.h>
+
21 
+
22 class QwtPlotLayout;
+
23 class QwtAbstractLegend;
+
24 class QwtScaleWidget;
+
25 class QwtScaleEngine;
+
26 class QwtScaleDiv;
+
27 class QwtScaleDraw;
+
28 class QwtTextLabel;
+
29 
+
74 class QWT_EXPORT QwtPlot: public QFrame, public QwtPlotDict
+
75 {
+
76  Q_OBJECT
+
77 
+
78  Q_PROPERTY( QBrush canvasBackground
+
79  READ canvasBackground WRITE setCanvasBackground )
+
80  Q_PROPERTY( bool autoReplot READ autoReplot WRITE setAutoReplot )
+
81 
+
82 #if 0
+
83  // This property is intended to configure the plot
+
84  // widget from a special dialog in the deigner plugin.
+
85  // Disabled until such a dialog has been implemented.
+
86 
+
87  Q_PROPERTY( QString propertiesDocument
+
88  READ grabProperties WRITE applyProperties )
+
89 #endif
+
90 
+
91 public:
+
93  enum Axis
+
94  {
+ +
97 
+ +
100 
+ +
103 
+ +
106 
+
108  axisCnt
+
109  };
+
110 
+ +
117  {
+ +
120 
+ +
123 
+ +
126 
+
128  TopLegend
+
129  };
+
130 
+
131  explicit QwtPlot( QWidget * = NULL );
+
132  explicit QwtPlot( const QwtText &title, QWidget * = NULL );
+
133 
+
134  virtual ~QwtPlot();
+
135 
+
136  void applyProperties( const QString & );
+
137  QString grabProperties() const;
+
138 
+
139  void setAutoReplot( bool = true );
+
140  bool autoReplot() const;
+
141 
+
142  // Layout
+
143 
+
144  void setPlotLayout( QwtPlotLayout * );
+
145 
+
146  QwtPlotLayout *plotLayout();
+
147  const QwtPlotLayout *plotLayout() const;
+
148 
+
149  // Title
+
150 
+
151  void setTitle( const QString & );
+
152  void setTitle( const QwtText &t );
+
153  QwtText title() const;
+
154 
+
155  QwtTextLabel *titleLabel();
+
156  const QwtTextLabel *titleLabel() const;
+
157 
+
158  // Footer
+
159 
+
160  void setFooter( const QString & );
+
161  void setFooter( const QwtText &t );
+
162  QwtText footer() const;
+
163 
+
164  QwtTextLabel *footerLabel();
+
165  const QwtTextLabel *footerLabel() const;
+
166 
+
167  // Canvas
+
168 
+
169  void setCanvas( QWidget * );
+
170 
+
171  QWidget *canvas();
+
172  const QWidget *canvas() const;
+
173 
+
174  void setCanvasBackground( const QBrush & );
+
175  QBrush canvasBackground() const;
+
176 
+
177  virtual QwtScaleMap canvasMap( int axisId ) const;
+
178 
+
179  double invTransform( int axisId, int pos ) const;
+
180  double transform( int axisId, double value ) const;
+
181 
+
182  // Axes
+
183 
+
184  QwtScaleEngine *axisScaleEngine( int axisId );
+
185  const QwtScaleEngine *axisScaleEngine( int axisId ) const;
+
186  void setAxisScaleEngine( int axisId, QwtScaleEngine * );
+
187 
+
188  void setAxisAutoScale( int axisId, bool on = true );
+
189  bool axisAutoScale( int axisId ) const;
+
190 
+
191  void enableAxis( int axisId, bool tf = true );
+
192  bool axisEnabled( int axisId ) const;
+
193 
+
194  void setAxisFont( int axisId, const QFont &f );
+
195  QFont axisFont( int axisId ) const;
+
196 
+
197  void setAxisScale( int axisId, double min, double max, double step = 0 );
+
198  void setAxisScaleDiv( int axisId, const QwtScaleDiv & );
+
199  void setAxisScaleDraw( int axisId, QwtScaleDraw * );
+
200 
+
201  double axisStepSize( int axisId ) const;
+
202  QwtInterval axisInterval( int axisId ) const;
+
203 
+
204  const QwtScaleDiv &axisScaleDiv( int axisId ) const;
+
205 
+
206  const QwtScaleDraw *axisScaleDraw( int axisId ) const;
+
207  QwtScaleDraw *axisScaleDraw( int axisId );
+
208 
+
209  const QwtScaleWidget *axisWidget( int axisId ) const;
+
210  QwtScaleWidget *axisWidget( int axisId );
+
211 
+
212  void setAxisLabelAlignment( int axisId, Qt::Alignment );
+
213  void setAxisLabelRotation( int axisId, double rotation );
+
214 
+
215  void setAxisTitle( int axisId, const QString & );
+
216  void setAxisTitle( int axisId, const QwtText & );
+
217  QwtText axisTitle( int axisId ) const;
+
218 
+
219  void setAxisMaxMinor( int axisId, int maxMinor );
+
220  int axisMaxMinor( int axisId ) const;
+
221 
+
222  void setAxisMaxMajor( int axisId, int maxMajor );
+
223  int axisMaxMajor( int axisId ) const;
+
224 
+
225  // Legend
+
226 
+
227  void insertLegend( QwtAbstractLegend *,
+
228  LegendPosition = QwtPlot::RightLegend, double ratio = -1.0 );
+
229 
+
230  QwtAbstractLegend *legend();
+
231  const QwtAbstractLegend *legend() const;
+
232 
+
233  void updateLegend();
+
234  void updateLegend( const QwtPlotItem * );
+
235 
+
236  // Misc
+
237 
+
238  virtual QSize sizeHint() const;
+
239  virtual QSize minimumSizeHint() const;
+
240 
+
241  virtual void updateLayout();
+
242  virtual void drawCanvas( QPainter * );
+
243 
+
244  void updateAxes();
+
245  void updateCanvasMargins();
+
246 
+
247  virtual void getCanvasMarginsHint(
+
248  const QwtScaleMap maps[], const QRectF &canvasRect,
+
249  double &left, double &top, double &right, double &bottom) const;
+
250 
+
251  virtual bool event( QEvent * );
+
252  virtual bool eventFilter( QObject *, QEvent * );
+
253 
+
254  virtual void drawItems( QPainter *, const QRectF &,
+
255  const QwtScaleMap maps[axisCnt] ) const;
+
256 
+
257  virtual QVariant itemToInfo( QwtPlotItem * ) const;
+
258  virtual QwtPlotItem *infoToItem( const QVariant & ) const;
+
259 
+
260 Q_SIGNALS:
+
267  void itemAttached( QwtPlotItem *plotItem, bool on );
+
268 
+
279  void legendDataChanged( const QVariant &itemInfo,
+
280  const QList<QwtLegendData> &data );
+
281 
+
282 public Q_SLOTS:
+
283  virtual void replot();
+
284  void autoRefresh();
+
285 
+
286 protected:
+
287  static bool axisValid( int axisId );
+
288 
+
289  virtual void resizeEvent( QResizeEvent *e );
+
290 
+
291 private Q_SLOTS:
+
292  void updateLegendItems( const QVariant &itemInfo,
+
293  const QList<QwtLegendData> &data );
+
294 
+
295 private:
+
296  friend class QwtPlotItem;
+
297  void attachItem( QwtPlotItem *, bool );
+
298 
+
299  void initAxesData();
+
300  void deleteAxesData();
+
301  void updateScaleDiv();
+
302 
+
303  void initPlot( const QwtText &title );
+
304 
+
305  class AxisData;
+
306  AxisData *d_axisData[axisCnt];
+
307 
+
308  class PrivateData;
+
309  PrivateData *d_data;
+
310 };
+
311 
+
312 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__plot__abstract__barchart_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__plot__abstract__barchart_8h_source.html new file mode 100644 index 0000000000..bb07fbf0e5 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__plot__abstract__barchart_8h_source.html @@ -0,0 +1,158 @@ + + + + + + +Qwt User's Guide: qwt_plot_abstract_barchart.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_plot_abstract_barchart.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_PLOT_ABSTRACT_BAR_CHART_H
+
11 #define QWT_PLOT_ABSTRACT_BAR_CHART_H
+
12 
+
13 #include "qwt_global.h"
+
14 #include "qwt_plot_seriesitem.h"
+
15 #include "qwt_series_data.h"
+
16 
+ +
26 {
+
27 public:
+ +
34  {
+ +
43 
+ +
48 
+ +
56 
+
60  FixedSampleSize
+
61  };
+
62 
+
63  explicit QwtPlotAbstractBarChart( const QwtText &title );
+
64  virtual ~QwtPlotAbstractBarChart();
+
65 
+
66  void setLayoutPolicy( LayoutPolicy );
+
67  LayoutPolicy layoutPolicy() const;
+
68 
+
69  void setLayoutHint( double );
+
70  double layoutHint() const;
+
71 
+
72  void setSpacing( int );
+
73  int spacing() const;
+
74 
+
75  void setMargin( int );
+
76  int margin() const;
+
77 
+
78  void setBaseline( double );
+
79  double baseline() const;
+
80 
+
81  virtual void getCanvasMarginHint(
+
82  const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+
83  const QRectF &canvasRect,
+
84  double &left, double &top, double &right, double &bottom) const;
+
85 
+
86 
+
87 protected:
+
88  double sampleWidth( const QwtScaleMap &map,
+
89  double canvasSize, double dataSize,
+
90  double value ) const;
+
91 
+
92 private:
+
93  class PrivateData;
+
94  PrivateData *d_data;
+
95 };
+
96 
+
97 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__plot__barchart_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__plot__barchart_8h_source.html new file mode 100644 index 0000000000..d3ced74164 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__plot__barchart_8h_source.html @@ -0,0 +1,172 @@ + + + + + + +Qwt User's Guide: qwt_plot_barchart.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_plot_barchart.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_PLOT_BAR_CHART_H
+
11 #define QWT_PLOT_BAR_CHART_H
+
12 
+
13 #include "qwt_global.h"
+
14 #include "qwt_plot_abstract_barchart.h"
+
15 #include "qwt_series_data.h"
+
16 
+
17 class QwtColumnRect;
+
18 class QwtColumnSymbol;
+
19 
+
41 class QWT_EXPORT QwtPlotBarChart:
+
42  public QwtPlotAbstractBarChart, public QwtSeriesStore<QPointF>
+
43 {
+
44 public:
+ +
52  {
+ +
60 
+
67  LegendBarTitles
+
68  };
+
69 
+
70  explicit QwtPlotBarChart( const QString &title = QString::null );
+
71  explicit QwtPlotBarChart( const QwtText &title );
+
72 
+
73  virtual ~QwtPlotBarChart();
+
74 
+
75  virtual int rtti() const;
+
76 
+
77  void setSamples( const QVector<QPointF> & );
+
78  void setSamples( const QVector<double> & );
+
79  void setSamples( QwtSeriesData<QPointF> *series );
+
80 
+
81  void setSymbol( QwtColumnSymbol * );
+
82  const QwtColumnSymbol *symbol() const;
+
83 
+
84  void setLegendMode( LegendMode );
+
85  LegendMode legendMode() const;
+
86 
+
87  virtual void drawSeries( QPainter *painter,
+
88  const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+
89  const QRectF &canvasRect, int from, int to ) const;
+
90 
+
91  virtual QRectF boundingRect() const;
+
92 
+
93  virtual QwtColumnSymbol *specialSymbol(
+
94  int sampleIndex, const QPointF& ) const;
+
95 
+
96  virtual QwtText barTitle( int sampleIndex ) const;
+
97 
+
98 protected:
+
99  virtual void drawSample( QPainter *painter,
+
100  const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+
101  const QRectF &canvasRect, const QwtInterval &boundingInterval,
+
102  int index, const QPointF& sample ) const;
+
103 
+
104  virtual void drawBar( QPainter *,
+
105  int sampleIndex, const QPointF& point,
+
106  const QwtColumnRect & ) const;
+
107 
+
108  QList<QwtLegendData> legendData() const;
+
109  QwtGraphic legendIcon( int index, const QSizeF & ) const;
+
110 
+
111 private:
+
112  void init();
+
113 
+
114  class PrivateData;
+
115  PrivateData *d_data;
+
116 };
+
117 
+
118 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__plot__canvas_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__plot__canvas_8h_source.html new file mode 100644 index 0000000000..2dbd0c228b --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__plot__canvas_8h_source.html @@ -0,0 +1,186 @@ + + + + + + +Qwt User's Guide: qwt_plot_canvas.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_plot_canvas.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_PLOT_CANVAS_H
+
11 #define QWT_PLOT_CANVAS_H
+
12 
+
13 #include "qwt_global.h"
+
14 #include <qframe.h>
+
15 #include <qpainterpath.h>
+
16 
+
17 class QwtPlot;
+
18 class QPixmap;
+
19 
+
27 class QWT_EXPORT QwtPlotCanvas : public QFrame
+
28 {
+
29  Q_OBJECT
+
30 
+
31  Q_PROPERTY( double borderRadius READ borderRadius WRITE setBorderRadius )
+
32 
+
33 public:
+
34 
+ +
43  {
+
55  BackingStore = 1,
+
56 
+
72  Opaque = 2,
+
73 
+
89  HackStyledBackground = 4,
+
90 
+
97  ImmediatePaint = 8
+
98  };
+
99 
+
101  typedef QFlags<PaintAttribute> PaintAttributes;
+
102 
+ +
110  {
+ +
113 
+ +
119 
+
125  ItemFocusIndicator
+
126  };
+
127 
+
128  explicit QwtPlotCanvas( QwtPlot * = NULL );
+
129  virtual ~QwtPlotCanvas();
+
130 
+
131  QwtPlot *plot();
+
132  const QwtPlot *plot() const;
+
133 
+
134  void setFocusIndicator( FocusIndicator );
+
135  FocusIndicator focusIndicator() const;
+
136 
+
137  void setBorderRadius( double );
+
138  double borderRadius() const;
+
139 
+
140  void setPaintAttribute( PaintAttribute, bool on = true );
+
141  bool testPaintAttribute( PaintAttribute ) const;
+
142 
+
143  const QPixmap *backingStore() const;
+
144  void invalidateBackingStore();
+
145 
+
146  virtual bool event( QEvent * );
+
147 
+
148  Q_INVOKABLE QPainterPath borderPath( const QRect & ) const;
+
149 
+
150 public Q_SLOTS:
+
151  void replot();
+
152 
+
153 protected:
+
154  virtual void paintEvent( QPaintEvent * );
+
155  virtual void resizeEvent( QResizeEvent * );
+
156 
+
157  virtual void drawFocusIndicator( QPainter * );
+
158  virtual void drawBorder( QPainter * );
+
159 
+
160  void updateStyleSheetInfo();
+
161 
+
162 private:
+
163  void drawCanvas( QPainter *, bool withBackground );
+
164 
+
165  class PrivateData;
+
166  PrivateData *d_data;
+
167 };
+
168 
+
169 Q_DECLARE_OPERATORS_FOR_FLAGS( QwtPlotCanvas::PaintAttributes )
+
170 
+
171 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__plot__curve_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__plot__curve_8h_source.html new file mode 100644 index 0000000000..4a6d85f7dc --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__plot__curve_8h_source.html @@ -0,0 +1,293 @@ + + + + + + +Qwt User's Guide: qwt_plot_curve.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_plot_curve.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_PLOT_CURVE_H
+
11 #define QWT_PLOT_CURVE_H
+
12 
+
13 #include "qwt_global.h"
+
14 #include "qwt_plot_seriesitem.h"
+
15 #include "qwt_series_data.h"
+
16 #include "qwt_text.h"
+
17 #include <qpen.h>
+
18 #include <qstring.h>
+
19 
+
20 class QPainter;
+
21 class QPolygonF;
+
22 class QwtScaleMap;
+
23 class QwtSymbol;
+
24 class QwtCurveFitter;
+
25 
+
55 class QWT_EXPORT QwtPlotCurve:
+
56  public QwtPlotSeriesItem, public QwtSeriesStore<QPointF>
+
57 {
+
58 public:
+ +
64  {
+
68  NoCurve = -1,
+
69 
+ +
76 
+ +
82 
+ +
89 
+ +
97 
+
103  UserCurve = 100
+
104  };
+
105 
+ +
111  {
+
116  Inverted = 0x01,
+
117 
+
128  Fitted = 0x02
+
129  };
+
130 
+
132  typedef QFlags<CurveAttribute> CurveAttributes;
+
133 
+ +
142  {
+
147  LegendNoAttribute = 0x00,
+
148 
+
153  LegendShowLine = 0x01,
+
154 
+
158  LegendShowSymbol = 0x02,
+
159 
+
164  LegendShowBrush = 0x04
+
165  };
+
166 
+
168  typedef QFlags<LegendAttribute> LegendAttributes;
+
169 
+ +
177  {
+
183  ClipPolygons = 0x01,
+
184 
+
191  FilterPoints = 0x02,
+
192 
+
198  MinimizeMemory = 0x04,
+
199 
+
207  ImageBuffer = 0x08
+
208  };
+
209 
+
211  typedef QFlags<PaintAttribute> PaintAttributes;
+
212 
+
213  explicit QwtPlotCurve( const QString &title = QString::null );
+
214  explicit QwtPlotCurve( const QwtText &title );
+
215 
+
216  virtual ~QwtPlotCurve();
+
217 
+
218  virtual int rtti() const;
+
219 
+
220  void setPaintAttribute( PaintAttribute, bool on = true );
+
221  bool testPaintAttribute( PaintAttribute ) const;
+
222 
+
223  void setLegendAttribute( LegendAttribute, bool on = true );
+
224  bool testLegendAttribute( LegendAttribute ) const;
+
225 
+
226 #ifndef QWT_NO_COMPAT
+
227  void setRawSamples( const double *xData, const double *yData, int size );
+
228  void setSamples( const double *xData, const double *yData, int size );
+
229  void setSamples( const QVector<double> &xData, const QVector<double> &yData );
+
230 #endif
+
231  void setSamples( const QVector<QPointF> & );
+
232  void setSamples( QwtSeriesData<QPointF> * );
+
233 
+
234  int closestPoint( const QPoint &pos, double *dist = NULL ) const;
+
235 
+
236  double minXValue() const;
+
237  double maxXValue() const;
+
238  double minYValue() const;
+
239  double maxYValue() const;
+
240 
+
241  void setCurveAttribute( CurveAttribute, bool on = true );
+
242  bool testCurveAttribute( CurveAttribute ) const;
+
243 
+
244  void setPen( const QColor &, qreal width = 0.0, Qt::PenStyle = Qt::SolidLine );
+
245  void setPen( const QPen & );
+
246  const QPen &pen() const;
+
247 
+
248  void setBrush( const QBrush & );
+
249  const QBrush &brush() const;
+
250 
+
251  void setBaseline( double );
+
252  double baseline() const;
+
253 
+
254  void setStyle( CurveStyle style );
+
255  CurveStyle style() const;
+
256 
+
257  void setSymbol( QwtSymbol * );
+
258  const QwtSymbol *symbol() const;
+
259 
+
260  void setCurveFitter( QwtCurveFitter * );
+
261  QwtCurveFitter *curveFitter() const;
+
262 
+
263  virtual void drawSeries( QPainter *,
+
264  const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+
265  const QRectF &canvasRect, int from, int to ) const;
+
266 
+
267  virtual QwtGraphic legendIcon( int index, const QSizeF & ) const;
+
268 
+
269 protected:
+
270 
+
271  void init();
+
272 
+
273  virtual void drawCurve( QPainter *p, int style,
+
274  const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+
275  const QRectF &canvasRect, int from, int to ) const;
+
276 
+
277  virtual void drawSymbols( QPainter *p, const QwtSymbol &,
+
278  const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+
279  const QRectF &canvasRect, int from, int to ) const;
+
280 
+
281  virtual void drawLines( QPainter *p,
+
282  const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+
283  const QRectF &canvasRect, int from, int to ) const;
+
284 
+
285  virtual void drawSticks( QPainter *p,
+
286  const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+
287  const QRectF &canvasRect, int from, int to ) const;
+
288 
+
289  virtual void drawDots( QPainter *p,
+
290  const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+
291  const QRectF &canvasRect, int from, int to ) const;
+
292 
+
293  virtual void drawSteps( QPainter *p,
+
294  const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+
295  const QRectF &canvasRect, int from, int to ) const;
+
296 
+
297  virtual void fillCurve( QPainter *,
+
298  const QwtScaleMap &, const QwtScaleMap &,
+
299  const QRectF &canvasRect, QPolygonF & ) const;
+
300 
+
301  void closePolyline( QPainter *,
+
302  const QwtScaleMap &, const QwtScaleMap &, QPolygonF & ) const;
+
303 
+
304 private:
+
305  class PrivateData;
+
306  PrivateData *d_data;
+
307 };
+
308 
+
310 inline double QwtPlotCurve::minXValue() const
+
311 {
+
312  return boundingRect().left();
+
313 }
+
314 
+
316 inline double QwtPlotCurve::maxXValue() const
+
317 {
+
318  return boundingRect().right();
+
319 }
+
320 
+
322 inline double QwtPlotCurve::minYValue() const
+
323 {
+
324  return boundingRect().top();
+
325 }
+
326 
+
328 inline double QwtPlotCurve::maxYValue() const
+
329 {
+
330  return boundingRect().bottom();
+
331 }
+
332 
+
333 Q_DECLARE_OPERATORS_FOR_FLAGS( QwtPlotCurve::PaintAttributes )
+
334 Q_DECLARE_OPERATORS_FOR_FLAGS( QwtPlotCurve::LegendAttributes )
+
335 Q_DECLARE_OPERATORS_FOR_FLAGS( QwtPlotCurve::CurveAttributes )
+
336 
+
337 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__plot__dict_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__plot__dict_8h_source.html new file mode 100644 index 0000000000..3444ad4e6c --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__plot__dict_8h_source.html @@ -0,0 +1,137 @@ + + + + + + +Qwt User's Guide: qwt_plot_dict.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_plot_dict.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
11 #ifndef QWT_PLOT_DICT
+
12 #define QWT_PLOT_DICT
+
13 
+
14 #include "qwt_global.h"
+
15 #include "qwt_plot_item.h"
+
16 #include <qlist.h>
+
17 
+
20 typedef QList<QwtPlotItem *> QwtPlotItemList;
+
21 typedef QList<QwtPlotItem *>::ConstIterator QwtPlotItemIterator;
+
22 
+
34 class QWT_EXPORT QwtPlotDict
+
35 {
+
36 public:
+
37  explicit QwtPlotDict();
+
38  virtual ~QwtPlotDict();
+
39 
+
40  void setAutoDelete( bool );
+
41  bool autoDelete() const;
+
42 
+
43  const QwtPlotItemList& itemList() const;
+
44  QwtPlotItemList itemList( int rtti ) const;
+
45 
+
46  void detachItems( int rtti = QwtPlotItem::Rtti_PlotItem,
+
47  bool autoDelete = true );
+
48 
+
49 protected:
+
50  void insertItem( QwtPlotItem * );
+
51  void removeItem( QwtPlotItem * );
+
52 
+
53 private:
+
54  class PrivateData;
+
55  PrivateData *d_data;
+
56 };
+
57 
+
58 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__plot__directpainter_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__plot__directpainter_8h_source.html new file mode 100644 index 0000000000..cecd30fe5a --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__plot__directpainter_8h_source.html @@ -0,0 +1,150 @@ + + + + + + +Qwt User's Guide: qwt_plot_directpainter.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_plot_directpainter.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_PLOT_DIRECT_PAINTER_H
+
11 #define QWT_PLOT_DIRECT_PAINTER_H
+
12 
+
13 #include "qwt_global.h"
+
14 #include <qobject.h>
+
15 
+
16 class QRegion;
+
17 class QwtPlotSeriesItem;
+
18 
+
39 class QWT_EXPORT QwtPlotDirectPainter: public QObject
+
40 {
+
41 public:
+
46  enum Attribute
+
47  {
+
54  AtomicPainter = 0x01,
+
55 
+
60  FullRepaint = 0x02,
+
61 
+
70  CopyBackingStore = 0x04
+
71  };
+
72 
+
74  typedef QFlags<Attribute> Attributes;
+
75 
+
76  QwtPlotDirectPainter( QObject *parent = NULL );
+
77  virtual ~QwtPlotDirectPainter();
+
78 
+
79  void setAttribute( Attribute, bool on );
+
80  bool testAttribute( Attribute ) const;
+
81 
+
82  void setClipping( bool );
+
83  bool hasClipping() const;
+
84 
+
85  void setClipRegion( const QRegion & );
+
86  QRegion clipRegion() const;
+
87 
+
88  void drawSeries( QwtPlotSeriesItem *, int from, int to );
+
89  void reset();
+
90 
+
91  virtual bool eventFilter( QObject *, QEvent * );
+
92 
+
93 private:
+
94  class PrivateData;
+
95  PrivateData *d_data;
+
96 };
+
97 
+
98 Q_DECLARE_OPERATORS_FOR_FLAGS( QwtPlotDirectPainter::Attributes )
+
99 
+
100 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__plot__glcanvas_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__plot__glcanvas_8h_source.html new file mode 100644 index 0000000000..1a768c3980 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__plot__glcanvas_8h_source.html @@ -0,0 +1,183 @@ + + + + + + +Qwt User's Guide: qwt_plot_glcanvas.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_plot_glcanvas.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_PLOT_GLCANVAS_H
+
11 #define QWT_PLOT_GLCANVAS_H
+
12 
+
13 #include "qwt_global.h"
+
14 #include <qframe.h>
+
15 #include <qgl.h>
+
16 
+
17 class QwtPlot;
+
18 
+
43 class QWT_EXPORT QwtPlotGLCanvas: public QGLWidget
+
44 {
+
45  Q_OBJECT
+
46 
+
47  Q_ENUMS( Shape Shadow )
+
48 
+
49  Q_PROPERTY( Shadow frameShadow READ frameShadow WRITE setFrameShadow )
+
50  Q_PROPERTY( Shape frameShape READ frameShape WRITE setFrameShape )
+
51  Q_PROPERTY( int lineWidth READ lineWidth WRITE setLineWidth )
+
52  Q_PROPERTY( int midLineWidth READ midLineWidth WRITE setMidLineWidth )
+
53  Q_PROPERTY( int frameWidth READ frameWidth )
+
54  Q_PROPERTY( QRect frameRect READ frameRect DESIGNABLE false )
+
55 
+
56 public:
+
65  enum Shadow
+
66  {
+
68  Plain = QFrame::Plain,
+
69 
+
71  Raised = QFrame::Raised,
+
72 
+
74  Sunken = QFrame::Sunken
+
75  };
+
76 
+
88  enum Shape
+
89  {
+
90  NoFrame = QFrame::NoFrame,
+
91 
+
92  Box = QFrame::Box,
+
93  Panel = QFrame::Panel
+
94  };
+
95 
+
96  explicit QwtPlotGLCanvas( QwtPlot * = NULL );
+
97  virtual ~QwtPlotGLCanvas();
+
98 
+
99  void setFrameStyle( int style );
+
100  int frameStyle() const;
+
101 
+
102  void setFrameShadow( Shadow );
+
103  Shadow frameShadow() const;
+
104 
+
105  void setFrameShape( Shape );
+
106  Shape frameShape() const;
+
107 
+
108  void setLineWidth( int );
+
109  int lineWidth() const;
+
110 
+
111  void setMidLineWidth( int );
+
112  int midLineWidth() const;
+
113 
+
114  int frameWidth() const;
+
115  QRect frameRect() const;
+
116 
+
117  Q_INVOKABLE QPainterPath borderPath( const QRect & ) const;
+
118 
+
119  virtual bool event( QEvent * );
+
120 
+
121 public Q_SLOTS:
+
122  void replot();
+
123 
+
124 protected:
+
125  virtual void paintEvent( QPaintEvent * );
+
126 
+
127  virtual void drawBackground( QPainter * );
+
128  virtual void drawBorder( QPainter * );
+
129  virtual void drawItems( QPainter * );
+
130 
+
131 private:
+
132  class PrivateData;
+
133  PrivateData *d_data;
+
134 };
+
135 
+
136 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__plot__grid_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__plot__grid_8h_source.html new file mode 100644 index 0000000000..7afe5a4fa2 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__plot__grid_8h_source.html @@ -0,0 +1,168 @@ + + + + + + +Qwt User's Guide: qwt_plot_grid.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_plot_grid.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_PLOT_GRID_H
+
11 #define QWT_PLOT_GRID_H
+
12 
+
13 #include "qwt_global.h"
+
14 #include "qwt_plot_item.h"
+
15 #include "qwt_scale_div.h"
+
16 
+
17 class QPainter;
+
18 class QPen;
+
19 class QwtScaleMap;
+
20 class QwtScaleDiv;
+
21 
+
34 class QWT_EXPORT QwtPlotGrid: public QwtPlotItem
+
35 {
+
36 public:
+
37  explicit QwtPlotGrid();
+
38  virtual ~QwtPlotGrid();
+
39 
+
40  virtual int rtti() const;
+
41 
+
42  void enableX( bool tf );
+
43  bool xEnabled() const;
+
44 
+
45  void enableY( bool tf );
+
46  bool yEnabled() const;
+
47 
+
48  void enableXMin( bool tf );
+
49  bool xMinEnabled() const;
+
50 
+
51  void enableYMin( bool tf );
+
52  bool yMinEnabled() const;
+
53 
+
54  void setXDiv( const QwtScaleDiv &sx );
+
55  const QwtScaleDiv &xScaleDiv() const;
+
56 
+
57  void setYDiv( const QwtScaleDiv &sy );
+
58  const QwtScaleDiv &yScaleDiv() const;
+
59 
+
60  void setPen( const QColor &, qreal width = 0.0, Qt::PenStyle = Qt::SolidLine );
+
61  void setPen( const QPen & );
+
62 
+
63  void setMajorPen( const QColor &, qreal width = 0.0, Qt::PenStyle = Qt::SolidLine );
+
64  void setMajorPen( const QPen & );
+
65  const QPen& majorPen() const;
+
66 
+
67  void setMinorPen( const QColor &, qreal width = 0.0, Qt::PenStyle = Qt::SolidLine );
+
68  void setMinorPen( const QPen &p );
+
69  const QPen& minorPen() const;
+
70 
+
71  virtual void draw( QPainter *p,
+
72  const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+
73  const QRectF &rect ) const;
+
74 
+
75  virtual void updateScaleDiv(
+
76  const QwtScaleDiv &xMap, const QwtScaleDiv &yMap );
+
77 
+
78 private:
+
79  void drawLines( QPainter *painter, const QRectF &,
+
80  Qt::Orientation orientation, const QwtScaleMap &,
+
81  const QList<double> & ) const;
+
82 
+
83  class PrivateData;
+
84  PrivateData *d_data;
+
85 };
+
86 
+
87 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__plot__histogram_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__plot__histogram_8h_source.html new file mode 100644 index 0000000000..179e52a5dc --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__plot__histogram_8h_source.html @@ -0,0 +1,191 @@ + + + + + + +Qwt User's Guide: qwt_plot_histogram.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_plot_histogram.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_PLOT_HISTOGRAM_H
+
11 #define QWT_PLOT_HISTOGRAM_H
+
12 
+
13 #include "qwt_global.h"
+
14 #include "qwt_plot_seriesitem.h"
+
15 #include "qwt_column_symbol.h"
+
16 #include <qcolor.h>
+
17 #include <qvector.h>
+
18 
+
19 class QwtIntervalData;
+
20 class QString;
+
21 class QPolygonF;
+
22 
+
39 class QWT_EXPORT QwtPlotHistogram:
+
40  public QwtPlotSeriesItem, public QwtSeriesStore<QwtIntervalSample>
+
41 {
+
42 public:
+ +
50  {
+ +
58 
+ +
65 
+ +
70 
+
76  UserStyle = 100
+
77  };
+
78 
+
79  explicit QwtPlotHistogram( const QString &title = QString::null );
+
80  explicit QwtPlotHistogram( const QwtText &title );
+
81  virtual ~QwtPlotHistogram();
+
82 
+
83  virtual int rtti() const;
+
84 
+
85  void setPen( const QColor &, qreal width = 0.0, Qt::PenStyle = Qt::SolidLine );
+
86  void setPen( const QPen & );
+
87  const QPen &pen() const;
+
88 
+
89  void setBrush( const QBrush & );
+
90  const QBrush &brush() const;
+
91 
+
92  void setSamples( const QVector<QwtIntervalSample> & );
+
93  void setSamples( QwtSeriesData<QwtIntervalSample> * );
+
94 
+
95  void setBaseline( double reference );
+
96  double baseline() const;
+
97 
+
98  void setStyle( HistogramStyle style );
+
99  HistogramStyle style() const;
+
100 
+
101  void setSymbol( const QwtColumnSymbol * );
+
102  const QwtColumnSymbol *symbol() const;
+
103 
+
104  virtual void drawSeries( QPainter *p,
+
105  const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+
106  const QRectF &canvasRect, int from, int to ) const;
+
107 
+
108  virtual QRectF boundingRect() const;
+
109 
+
110  virtual QwtGraphic legendIcon( int index, const QSizeF & ) const;
+
111 
+
112 protected:
+
113  virtual QwtColumnRect columnRect( const QwtIntervalSample &,
+
114  const QwtScaleMap &, const QwtScaleMap & ) const;
+
115 
+
116  virtual void drawColumn( QPainter *, const QwtColumnRect &,
+
117  const QwtIntervalSample & ) const;
+
118 
+
119  void drawColumns( QPainter *,
+
120  const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+
121  int from, int to ) const;
+
122 
+
123  void drawOutline( QPainter *,
+
124  const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+
125  int from, int to ) const;
+
126 
+
127  void drawLines( QPainter *,
+
128  const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+
129  int from, int to ) const;
+
130 
+
131 private:
+
132  void init();
+
133  void flushPolygon( QPainter *, double baseLine, QPolygonF & ) const;
+
134 
+
135  class PrivateData;
+
136  PrivateData *d_data;
+
137 };
+
138 
+
139 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__plot__intervalcurve_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__plot__intervalcurve_8h_source.html new file mode 100644 index 0000000000..f7c8fa9391 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__plot__intervalcurve_8h_source.html @@ -0,0 +1,187 @@ + + + + + + +Qwt User's Guide: qwt_plot_intervalcurve.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_plot_intervalcurve.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_PLOT_INTERVAL_CURVE_H
+
11 #define QWT_PLOT_INTERVAL_CURVE_H
+
12 
+
13 #include "qwt_global.h"
+
14 #include "qwt_plot_seriesitem.h"
+
15 #include "qwt_series_data.h"
+
16 
+
17 class QwtIntervalSymbol;
+
18 
+
27 class QWT_EXPORT QwtPlotIntervalCurve:
+
28  public QwtPlotSeriesItem, public QwtSeriesStore<QwtIntervalSample>
+
29 {
+
30 public:
+ +
38  {
+ +
43 
+ +
50 
+
56  UserCurve = 100
+
57  };
+
58 
+ +
64  {
+
70  ClipPolygons = 0x01,
+
71 
+
73  ClipSymbol = 0x02
+
74  };
+
75 
+
77  typedef QFlags<PaintAttribute> PaintAttributes;
+
78 
+
79  explicit QwtPlotIntervalCurve( const QString &title = QString::null );
+
80  explicit QwtPlotIntervalCurve( const QwtText &title );
+
81 
+
82  virtual ~QwtPlotIntervalCurve();
+
83 
+
84  virtual int rtti() const;
+
85 
+
86  void setPaintAttribute( PaintAttribute, bool on = true );
+
87  bool testPaintAttribute( PaintAttribute ) const;
+
88 
+
89  void setSamples( const QVector<QwtIntervalSample> & );
+
90  void setSamples( QwtSeriesData<QwtIntervalSample> * );
+
91 
+
92  void setPen( const QColor &, qreal width = 0.0, Qt::PenStyle = Qt::SolidLine );
+
93  void setPen( const QPen & );
+
94  const QPen &pen() const;
+
95 
+
96  void setBrush( const QBrush & );
+
97  const QBrush &brush() const;
+
98 
+
99  void setStyle( CurveStyle style );
+
100  CurveStyle style() const;
+
101 
+
102  void setSymbol( const QwtIntervalSymbol * );
+
103  const QwtIntervalSymbol *symbol() const;
+
104 
+
105  virtual void drawSeries( QPainter *p,
+
106  const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+
107  const QRectF &canvasRect, int from, int to ) const;
+
108 
+
109  virtual QRectF boundingRect() const;
+
110 
+
111  virtual QwtGraphic legendIcon( int index, const QSizeF & ) const;
+
112 
+
113 protected:
+
114 
+
115  void init();
+
116 
+
117  virtual void drawTube( QPainter *,
+
118  const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+
119  const QRectF &canvasRect, int from, int to ) const;
+
120 
+
121  virtual void drawSymbols( QPainter *, const QwtIntervalSymbol &,
+
122  const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+
123  const QRectF &canvasRect, int from, int to ) const;
+
124 
+
125 private:
+
126  class PrivateData;
+
127  PrivateData *d_data;
+
128 };
+
129 
+
130 Q_DECLARE_OPERATORS_FOR_FLAGS( QwtPlotIntervalCurve::PaintAttributes )
+
131 
+
132 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__plot__item_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__plot__item_8h_source.html new file mode 100644 index 0000000000..b8407abb4a --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__plot__item_8h_source.html @@ -0,0 +1,278 @@ + + + + + + +Qwt User's Guide: qwt_plot_item.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_plot_item.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_PLOT_ITEM_H
+
11 #define QWT_PLOT_ITEM_H
+
12 
+
13 #include "qwt_global.h"
+
14 #include "qwt_text.h"
+
15 #include "qwt_legend_data.h"
+
16 #include "qwt_graphic.h"
+
17 #include <qrect.h>
+
18 #include <qlist.h>
+
19 #include <qmetatype.h>
+
20 
+
21 class QPainter;
+
22 class QwtScaleMap;
+
23 class QwtScaleDiv;
+
24 class QwtPlot;
+
25 
+
64 class QWT_EXPORT QwtPlotItem
+
65 {
+
66 public:
+ +
74  {
+
76  Rtti_PlotItem = 0,
+
77 
+ +
80 
+ +
83 
+ +
86 
+ +
89 
+ +
92 
+ +
95 
+ +
98 
+ +
101 
+ +
104 
+ +
107 
+ +
110 
+ +
113 
+ +
116 
+ +
119 
+ +
122 
+ +
125 
+
130  Rtti_PlotUserItem = 1000
+
131  };
+
132 
+ +
143  {
+
145  Legend = 0x01,
+
146 
+
152  AutoScale = 0x02,
+
153 
+
159  Margins = 0x04
+
160  };
+
161 
+
163  typedef QFlags<ItemAttribute> ItemAttributes;
+
164 
+ +
176  {
+
181  ScaleInterest = 0x01,
+
182 
+
193  LegendInterest = 0x02
+
194  };
+
195 
+
197  typedef QFlags<ItemInterest> ItemInterests;
+
198 
+ +
201  {
+
203  RenderAntialiased = 0x1
+
204  };
+
205 
+
207  typedef QFlags<RenderHint> RenderHints;
+
208 
+
209  explicit QwtPlotItem( const QwtText &title = QwtText() );
+
210  virtual ~QwtPlotItem();
+
211 
+
212  void attach( QwtPlot *plot );
+
213  void detach();
+
214 
+
215  QwtPlot *plot() const;
+
216 
+
217  void setTitle( const QString &title );
+
218  void setTitle( const QwtText &title );
+
219  const QwtText &title() const;
+
220 
+
221  virtual int rtti() const;
+
222 
+
223  void setItemAttribute( ItemAttribute, bool on = true );
+
224  bool testItemAttribute( ItemAttribute ) const;
+
225 
+
226  void setItemInterest( ItemInterest, bool on = true );
+
227  bool testItemInterest( ItemInterest ) const;
+
228 
+
229  void setRenderHint( RenderHint, bool on = true );
+
230  bool testRenderHint( RenderHint ) const;
+
231 
+
232  void setRenderThreadCount( uint numThreads );
+
233  uint renderThreadCount() const;
+
234 
+
235  void setLegendIconSize( const QSize & );
+
236  QSize legendIconSize() const;
+
237 
+
238  double z() const;
+
239  void setZ( double z );
+
240 
+
241  void show();
+
242  void hide();
+
243  virtual void setVisible( bool );
+
244  bool isVisible () const;
+
245 
+
246  void setAxes( int xAxis, int yAxis );
+
247 
+
248  void setXAxis( int axis );
+
249  int xAxis() const;
+
250 
+
251  void setYAxis( int axis );
+
252  int yAxis() const;
+
253 
+
254  virtual void itemChanged();
+
255  virtual void legendChanged();
+
256 
+
265  virtual void draw( QPainter *painter,
+
266  const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+
267  const QRectF &canvasRect ) const = 0;
+
268 
+
269  virtual QRectF boundingRect() const;
+
270 
+
271  virtual void getCanvasMarginHint(
+
272  const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+
273  const QRectF &canvasSize,
+
274  double &left, double &top, double &right, double &bottom) const;
+
275 
+
276  virtual void updateScaleDiv(
+
277  const QwtScaleDiv&, const QwtScaleDiv& );
+
278 
+
279  virtual void updateLegend( const QwtPlotItem *,
+
280  const QList<QwtLegendData> & );
+
281 
+
282  QRectF scaleRect( const QwtScaleMap &, const QwtScaleMap & ) const;
+
283  QRectF paintRect( const QwtScaleMap &, const QwtScaleMap & ) const;
+
284 
+
285  virtual QList<QwtLegendData> legendData() const;
+
286 
+
287  virtual QwtGraphic legendIcon( int index, const QSizeF & ) const;
+
288 
+
289 protected:
+
290  QwtGraphic defaultIcon( const QBrush &, const QSizeF & ) const;
+
291 
+
292 private:
+
293  // Disabled copy constructor and operator=
+
294  QwtPlotItem( const QwtPlotItem & );
+
295  QwtPlotItem &operator=( const QwtPlotItem & );
+
296 
+
297  class PrivateData;
+
298  PrivateData *d_data;
+
299 };
+
300 
+
301 Q_DECLARE_OPERATORS_FOR_FLAGS( QwtPlotItem::ItemAttributes )
+
302 Q_DECLARE_OPERATORS_FOR_FLAGS( QwtPlotItem::ItemInterests )
+
303 Q_DECLARE_OPERATORS_FOR_FLAGS( QwtPlotItem::RenderHints )
+
304 
+
305 Q_DECLARE_METATYPE( QwtPlotItem * )
+
306 
+
307 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__plot__layout_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__plot__layout_8h_source.html new file mode 100644 index 0000000000..e645757abf --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__plot__layout_8h_source.html @@ -0,0 +1,191 @@ + + + + + + +Qwt User's Guide: qwt_plot_layout.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_plot_layout.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_PLOT_LAYOUT_H
+
11 #define QWT_PLOT_LAYOUT_H
+
12 
+
13 #include "qwt_global.h"
+
14 #include "qwt_plot.h"
+
15 
+
26 class QWT_EXPORT QwtPlotLayout
+
27 {
+
28 public:
+
33  enum Option
+
34  {
+
36  AlignScales = 0x01,
+
37 
+
42  IgnoreScrollbars = 0x02,
+
43 
+
45  IgnoreFrames = 0x04,
+
46 
+
48  IgnoreLegend = 0x08,
+
49 
+
51  IgnoreTitle = 0x10,
+
52 
+
54  IgnoreFooter = 0x20
+
55  };
+
56 
+
58  typedef QFlags<Option> Options;
+
59 
+
60  explicit QwtPlotLayout();
+
61  virtual ~QwtPlotLayout();
+
62 
+
63  void setCanvasMargin( int margin, int axis = -1 );
+
64  int canvasMargin( int axis ) const;
+
65 
+
66  void setAlignCanvasToScales( bool );
+
67 
+
68  void setAlignCanvasToScale( int axisId, bool );
+
69  bool alignCanvasToScale( int axisId ) const;
+
70 
+
71  void setSpacing( int );
+
72  int spacing() const;
+
73 
+
74  void setLegendPosition( QwtPlot::LegendPosition pos, double ratio );
+
75  void setLegendPosition( QwtPlot::LegendPosition pos );
+
76  QwtPlot::LegendPosition legendPosition() const;
+
77 
+
78  void setLegendRatio( double ratio );
+
79  double legendRatio() const;
+
80 
+
81  virtual QSize minimumSizeHint( const QwtPlot * ) const;
+
82 
+
83  virtual void activate( const QwtPlot *,
+
84  const QRectF &rect, Options options = 0x00 );
+
85 
+
86  virtual void invalidate();
+
87 
+
88  QRectF titleRect() const;
+
89  QRectF footerRect() const;
+
90  QRectF legendRect() const;
+
91  QRectF scaleRect( int axis ) const;
+
92  QRectF canvasRect() const;
+
93 
+
94  class LayoutData;
+
95 
+
96 protected:
+
97 
+
98  void setTitleRect( const QRectF & );
+
99  void setFooterRect( const QRectF & );
+
100  void setLegendRect( const QRectF & );
+
101  void setScaleRect( int axis, const QRectF & );
+
102  void setCanvasRect( const QRectF & );
+
103 
+
104  QRectF layoutLegend( Options options, const QRectF & ) const;
+
105  QRectF alignLegend( const QRectF &canvasRect,
+
106  const QRectF &legendRect ) const;
+
107 
+
108  void expandLineBreaks( Options options, const QRectF &rect,
+
109  int &dimTitle, int &dimFooter, int dimAxes[QwtPlot::axisCnt] ) const;
+
110 
+
111  void alignScales( Options options, QRectF &canvasRect,
+
112  QRectF scaleRect[QwtPlot::axisCnt] ) const;
+
113 
+
114 private:
+
115  class PrivateData;
+
116 
+
117  PrivateData *d_data;
+
118 };
+
119 
+
120 Q_DECLARE_OPERATORS_FOR_FLAGS( QwtPlotLayout::Options )
+
121 
+
122 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__plot__legenditem_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__plot__legenditem_8h_source.html new file mode 100644 index 0000000000..1fdb8ca122 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__plot__legenditem_8h_source.html @@ -0,0 +1,194 @@ + + + + + + +Qwt User's Guide: qwt_plot_legenditem.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_plot_legenditem.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_PLOT_LEGEND_ITEM_H
+
11 #define QWT_PLOT_LEGEND_ITEM_H
+
12 
+
13 #include "qwt_global.h"
+
14 #include "qwt_plot_item.h"
+
15 #include "qwt_legend_data.h"
+
16 
+
17 class QFont;
+
18 
+
42 class QWT_EXPORT QwtPlotLegendItem: public QwtPlotItem
+
43 {
+
44 public:
+ +
56  {
+ +
59 
+
61  ItemBackground
+
62  };
+
63 
+
64  explicit QwtPlotLegendItem();
+
65  virtual ~QwtPlotLegendItem();
+
66 
+
67  virtual int rtti() const;
+
68 
+
69  void setAlignment( Qt::Alignment );
+
70  Qt::Alignment alignment() const;
+
71 
+
72  void setMaxColumns( uint );
+
73  uint maxColumns() const;
+
74 
+
75  void setMargin( int );
+
76  int margin() const;
+
77 
+
78  void setSpacing( int );
+
79  int spacing() const;
+
80 
+
81  void setItemMargin( int );
+
82  int itemMargin() const;
+
83 
+
84  void setItemSpacing( int );
+
85  int itemSpacing() const;
+
86 
+
87  void setFont( const QFont& );
+
88  QFont font() const;
+
89 
+
90  void setBorderDistance( int numPixels );
+
91  int borderDistance() const;
+
92 
+
93  void setBorderRadius( double );
+
94  double borderRadius() const;
+
95 
+
96  void setBorderPen( const QPen & );
+
97  QPen borderPen() const;
+
98 
+
99  void setBackgroundBrush( const QBrush & );
+
100  QBrush backgroundBrush() const;
+
101 
+
102  void setBackgroundMode( BackgroundMode );
+
103  BackgroundMode backgroundMode() const;
+
104 
+
105  void setTextPen( const QPen & );
+
106  QPen textPen() const;
+
107 
+
108  virtual void draw( QPainter *p,
+
109  const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+
110  const QRectF &rect ) const;
+
111 
+
112  void clearLegend();
+
113 
+
114  virtual void updateLegend( const QwtPlotItem *,
+
115  const QList<QwtLegendData> & );
+
116 
+
117  virtual QRect geometry( const QRectF &canvasRect ) const;
+
118 
+
119  virtual QSize minimumSize( const QwtLegendData & ) const;
+
120  virtual int heightForWidth( const QwtLegendData &, int w ) const;
+
121 
+
122  QList< const QwtPlotItem * > plotItems() const;
+
123  QList< QRect > legendGeometries( const QwtPlotItem * ) const;
+
124 
+
125 protected:
+
126  virtual void drawLegendData( QPainter *painter,
+
127  const QwtPlotItem *, const QwtLegendData &, const QRectF & ) const;
+
128 
+
129  virtual void drawBackground( QPainter *, const QRectF &rect ) const;
+
130 
+
131 private:
+
132  class PrivateData;
+
133  PrivateData *d_data;
+
134 };
+
135 
+
136 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__plot__magnifier_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__plot__magnifier_8h_source.html new file mode 100644 index 0000000000..afb2aa1f0e --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__plot__magnifier_8h_source.html @@ -0,0 +1,136 @@ + + + + + + +Qwt User's Guide: qwt_plot_magnifier.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_plot_magnifier.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_PLOT_MAGNIFIER_H
+
11 #define QWT_PLOT_MAGNIFIER_H 1
+
12 
+
13 #include "qwt_global.h"
+
14 #include "qwt_magnifier.h"
+
15 
+
16 class QwtPlot;
+
17 
+
29 class QWT_EXPORT QwtPlotMagnifier: public QwtMagnifier
+
30 {
+
31  Q_OBJECT
+
32 
+
33 public:
+
34  explicit QwtPlotMagnifier( QWidget * );
+
35  virtual ~QwtPlotMagnifier();
+
36 
+
37  void setAxisEnabled( int axis, bool on );
+
38  bool isAxisEnabled( int axis ) const;
+
39 
+
40  QWidget *canvas();
+
41  const QWidget *canvas() const;
+
42 
+
43  QwtPlot *plot();
+
44  const QwtPlot *plot() const;
+
45 
+
46 protected:
+
47  virtual void rescale( double factor );
+
48 
+
49 private:
+
50  class PrivateData;
+
51  PrivateData *d_data;
+
52 };
+
53 
+
54 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__plot__marker_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__plot__marker_8h_source.html new file mode 100644 index 0000000000..661c2684f5 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__plot__marker_8h_source.html @@ -0,0 +1,191 @@ + + + + + + +Qwt User's Guide: qwt_plot_marker.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_plot_marker.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_PLOT_MARKER_H
+
11 #define QWT_PLOT_MARKER_H
+
12 
+
13 #include <qpen.h>
+
14 #include <qfont.h>
+
15 #include <qstring.h>
+
16 #include <qbrush.h>
+
17 #include "qwt_global.h"
+
18 #include "qwt_plot_item.h"
+
19 
+
20 class QRectF;
+
21 class QwtText;
+
22 class QwtSymbol;
+
23 
+
48 class QWT_EXPORT QwtPlotMarker: public QwtPlotItem
+
49 {
+
50 public:
+
51 
+
56  enum LineStyle
+
57  {
+ +
60 
+ +
63 
+ +
66 
+
68  Cross
+
69  };
+
70 
+
71  explicit QwtPlotMarker( const QString &title = QString::null );
+
72  explicit QwtPlotMarker( const QwtText &title );
+
73 
+
74  virtual ~QwtPlotMarker();
+
75 
+
76  virtual int rtti() const;
+
77 
+
78  double xValue() const;
+
79  double yValue() const;
+
80  QPointF value() const;
+
81 
+
82  void setXValue( double );
+
83  void setYValue( double );
+
84  void setValue( double, double );
+
85  void setValue( const QPointF & );
+
86 
+
87  void setLineStyle( LineStyle st );
+
88  LineStyle lineStyle() const;
+
89 
+
90  void setLinePen( const QColor &, qreal width = 0.0, Qt::PenStyle = Qt::SolidLine );
+
91  void setLinePen( const QPen &p );
+
92  const QPen &linePen() const;
+
93 
+
94  void setSymbol( const QwtSymbol * );
+
95  const QwtSymbol *symbol() const;
+
96 
+
97  void setLabel( const QwtText& );
+
98  QwtText label() const;
+
99 
+
100  void setLabelAlignment( Qt::Alignment );
+
101  Qt::Alignment labelAlignment() const;
+
102 
+
103  void setLabelOrientation( Qt::Orientation );
+
104  Qt::Orientation labelOrientation() const;
+
105 
+
106  void setSpacing( int );
+
107  int spacing() const;
+
108 
+
109  virtual void draw( QPainter *p,
+
110  const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+
111  const QRectF & ) const;
+
112 
+
113  virtual QRectF boundingRect() const;
+
114 
+
115  virtual QwtGraphic legendIcon( int index, const QSizeF & ) const;
+
116 
+
117 protected:
+
118  virtual void drawLines( QPainter *,
+
119  const QRectF &, const QPointF & ) const;
+
120 
+
121  virtual void drawLabel( QPainter *,
+
122  const QRectF &, const QPointF & ) const;
+
123 
+
124 private:
+
125 
+
126  class PrivateData;
+
127  PrivateData *d_data;
+
128 };
+
129 
+
130 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__plot__multi__barchart_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__plot__multi__barchart_8h_source.html new file mode 100644 index 0000000000..6bdafd2f6a --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__plot__multi__barchart_8h_source.html @@ -0,0 +1,187 @@ + + + + + + +Qwt User's Guide: qwt_plot_multi_barchart.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_plot_multi_barchart.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_PLOT_BAR_CHART_H
+
11 #define QWT_PLOT_BAR_CHART_H
+
12 
+
13 #include "qwt_global.h"
+
14 #include "qwt_plot_abstract_barchart.h"
+
15 #include "qwt_series_data.h"
+
16 
+
17 class QwtColumnRect;
+
18 class QwtColumnSymbol;
+
19 
+
41 class QWT_EXPORT QwtPlotMultiBarChart:
+
42  public QwtPlotAbstractBarChart, public QwtSeriesStore<QwtSetSample>
+
43 {
+
44 public:
+ +
52  {
+ +
55 
+
61  Stacked
+
62  };
+
63 
+
64  explicit QwtPlotMultiBarChart( const QString &title = QString::null );
+
65  explicit QwtPlotMultiBarChart( const QwtText &title );
+
66 
+
67  virtual ~QwtPlotMultiBarChart();
+
68 
+
69  virtual int rtti() const;
+
70 
+
71  void setBarTitles( const QList<QwtText> & );
+
72  QList<QwtText> barTitles() const;
+
73 
+
74  void setSamples( const QVector<QwtSetSample> & );
+
75  void setSamples( const QVector< QVector<double> > & );
+
76  void setSamples( QwtSeriesData<QwtSetSample> * );
+
77 
+
78  void setStyle( ChartStyle style );
+
79  ChartStyle style() const;
+
80 
+
81  void setSymbol( int barIndex, QwtColumnSymbol *symbol );
+
82  const QwtColumnSymbol *symbol( int barIndex ) const;
+
83 
+
84  void resetSymbolMap();
+
85 
+
86  virtual void drawSeries( QPainter *painter,
+
87  const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+
88  const QRectF &canvasRect, int from, int to ) const;
+
89 
+
90  virtual QRectF boundingRect() const;
+
91 
+
92  virtual QList<QwtLegendData> legendData() const;
+
93 
+
94  virtual QwtGraphic legendIcon( int index, const QSizeF & ) const;
+
95 
+
96 protected:
+
97  QwtColumnSymbol *symbol( int barIndex );
+
98 
+
99  virtual QwtColumnSymbol *specialSymbol(
+
100  int sampleIndex, int valueIndex ) const;
+
101 
+
102  virtual void drawSample( QPainter *painter,
+
103  const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+
104  const QRectF &canvasRect, const QwtInterval &boundingInterval,
+
105  int index, const QwtSetSample& sample ) const;
+
106 
+
107  virtual void drawBar( QPainter *, int sampleIndex,
+
108  int barIndex, const QwtColumnRect & ) const;
+
109 
+
110  void drawStackedBars( QPainter *painter,
+
111  const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+
112  const QRectF &canvasRect, int index,
+
113  double sampleWidth, const QwtSetSample& sample ) const;
+
114 
+
115  void drawGroupedBars( QPainter *painter,
+
116  const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+
117  const QRectF &canvasRect, int index,
+
118  double sampleWidth, const QwtSetSample& sample ) const;
+
119 
+
120 private:
+
121  void init();
+
122 
+
123  class PrivateData;
+
124  PrivateData *d_data;
+
125 };
+
126 
+
127 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__plot__panner_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__plot__panner_8h_source.html new file mode 100644 index 0000000000..ac4d00f145 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__plot__panner_8h_source.html @@ -0,0 +1,140 @@ + + + + + + +Qwt User's Guide: qwt_plot_panner.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_plot_panner.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_PLOT_PANNER_H
+
11 #define QWT_PLOT_PANNER_H 1
+
12 
+
13 #include "qwt_global.h"
+
14 #include "qwt_panner.h"
+
15 
+
16 class QwtPlot;
+
17 
+
31 class QWT_EXPORT QwtPlotPanner: public QwtPanner
+
32 {
+
33  Q_OBJECT
+
34 
+
35 public:
+
36  explicit QwtPlotPanner( QWidget * );
+
37  virtual ~QwtPlotPanner();
+
38 
+
39  QWidget *canvas();
+
40  const QWidget *canvas() const;
+
41 
+
42  QwtPlot *plot();
+
43  const QwtPlot *plot() const;
+
44 
+
45  void setAxisEnabled( int axis, bool on );
+
46  bool isAxisEnabled( int axis ) const;
+
47 
+
48 protected Q_SLOTS:
+
49  virtual void moveCanvas( int dx, int dy );
+
50 
+
51 protected:
+
52  virtual QBitmap contentsMask() const;
+
53  virtual QPixmap grab() const;
+
54 
+
55 private:
+
56  class PrivateData;
+
57  PrivateData *d_data;
+
58 };
+
59 
+
60 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__plot__picker_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__plot__picker_8h_source.html new file mode 100644 index 0000000000..1ef79165a0 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__plot__picker_8h_source.html @@ -0,0 +1,169 @@ + + + + + + +Qwt User's Guide: qwt_plot_picker.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_plot_picker.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_PLOT_PICKER_H
+
11 #define QWT_PLOT_PICKER_H
+
12 
+
13 #include "qwt_global.h"
+
14 #include "qwt_picker.h"
+
15 #include <qvector.h>
+
16 
+
17 class QwtPlot;
+
18 
+
27 class QWT_EXPORT QwtPlotPicker: public QwtPicker
+
28 {
+
29  Q_OBJECT
+
30 
+
31 public:
+
32  explicit QwtPlotPicker( QWidget *canvas );
+
33  virtual ~QwtPlotPicker();
+
34 
+
35  explicit QwtPlotPicker( int xAxis, int yAxis, QWidget * );
+
36 
+
37  explicit QwtPlotPicker( int xAxis, int yAxis,
+
38  RubberBand rubberBand, DisplayMode trackerMode, QWidget * );
+
39 
+
40  virtual void setAxis( int xAxis, int yAxis );
+
41 
+
42  int xAxis() const;
+
43  int yAxis() const;
+
44 
+
45  QwtPlot *plot();
+
46  const QwtPlot *plot() const;
+
47 
+
48  QWidget *canvas();
+
49  const QWidget *canvas() const;
+
50 
+
51 Q_SIGNALS:
+
52 
+
57  void selected( const QPointF &pos );
+
58 
+
63  void selected( const QRectF &rect );
+
64 
+
71  void selected( const QVector<QPointF> &pa );
+
72 
+
79  void appended( const QPointF &pos );
+
80 
+
88  void moved( const QPointF &pos );
+
89 
+
90 protected:
+
91  QRectF scaleRect() const;
+
92 
+
93  QRectF invTransform( const QRect & ) const;
+
94  QRect transform( const QRectF & ) const;
+
95 
+
96  QPointF invTransform( const QPoint & ) const;
+
97  QPoint transform( const QPointF & ) const;
+
98 
+
99  virtual QwtText trackerText( const QPoint & ) const;
+
100  virtual QwtText trackerTextF( const QPointF & ) const;
+
101 
+
102  virtual void move( const QPoint & );
+
103  virtual void append( const QPoint & );
+
104  virtual bool end( bool ok = true );
+
105 
+
106 private:
+
107  int d_xAxis;
+
108  int d_yAxis;
+
109 };
+
110 
+
111 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__plot__rasteritem_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__plot__rasteritem_8h_source.html new file mode 100644 index 0000000000..e1781e31b2 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__plot__rasteritem_8h_source.html @@ -0,0 +1,180 @@ + + + + + + +Qwt User's Guide: qwt_plot_rasteritem.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_plot_rasteritem.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_PLOT_RASTERITEM_H
+
11 #define QWT_PLOT_RASTERITEM_H
+
12 
+
13 #include "qwt_global.h"
+
14 #include "qwt_plot_item.h"
+
15 #include "qwt_interval.h"
+
16 #include <qglobal.h>
+
17 #include <qstring.h>
+
18 #include <qimage.h>
+
19 
+
37 class QWT_EXPORT QwtPlotRasterItem: public QwtPlotItem
+
38 {
+
39 public:
+ +
45  {
+ +
50 
+
59  PaintCache
+
60  };
+
61 
+ +
67  {
+
80  PaintInDeviceResolution = 1
+
81  };
+
82 
+
84  typedef QFlags<PaintAttribute> PaintAttributes;
+
85 
+
86  explicit QwtPlotRasterItem( const QString& title = QString::null );
+
87  explicit QwtPlotRasterItem( const QwtText& title );
+
88  virtual ~QwtPlotRasterItem();
+
89 
+
90  void setPaintAttribute( PaintAttribute, bool on = true );
+
91  bool testPaintAttribute( PaintAttribute ) const;
+
92 
+
93  void setAlpha( int alpha );
+
94  int alpha() const;
+
95 
+
96  void setCachePolicy( CachePolicy );
+
97  CachePolicy cachePolicy() const;
+
98 
+
99  void invalidateCache();
+
100 
+
101  virtual void draw( QPainter *p,
+
102  const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+
103  const QRectF &rect ) const;
+
104 
+
105  virtual QRectF pixelHint( const QRectF & ) const;
+
106 
+
107  virtual QwtInterval interval(Qt::Axis) const;
+
108  virtual QRectF boundingRect() const;
+
109 
+
110 protected:
+
127  virtual QImage renderImage( const QwtScaleMap &xMap,
+
128  const QwtScaleMap &yMap, const QRectF &area,
+
129  const QSize &imageSize ) const = 0;
+
130 
+
131  virtual QwtScaleMap imageMap( Qt::Orientation,
+
132  const QwtScaleMap &map, const QRectF &area,
+
133  const QSize &imageSize, double pixelSize) const;
+
134 
+
135 private:
+ +
137  QwtPlotRasterItem &operator=( const QwtPlotRasterItem & );
+
138 
+
139  void init();
+
140 
+
141  QImage compose( const QwtScaleMap &, const QwtScaleMap &,
+
142  const QRectF &imageArea, const QRectF &paintRect,
+
143  const QSize &imageSize, bool doCache) const;
+
144 
+
145 
+
146  class PrivateData;
+
147  PrivateData *d_data;
+
148 };
+
149 
+
150 Q_DECLARE_OPERATORS_FOR_FLAGS( QwtPlotRasterItem::PaintAttributes )
+
151 
+
152 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__plot__renderer_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__plot__renderer_8h_source.html new file mode 100644 index 0000000000..c389109528 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__plot__renderer_8h_source.html @@ -0,0 +1,234 @@ + + + + + + +Qwt User's Guide: qwt_plot_renderer.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_plot_renderer.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_PLOT_RENDERER_H
+
11 #define QWT_PLOT_RENDERER_H
+
12 
+
13 #include "qwt_global.h"
+
14 #include <qobject.h>
+
15 #include <qsize.h>
+
16 
+
17 class QwtPlot;
+
18 class QwtScaleMap;
+
19 class QRectF;
+
20 class QPainter;
+
21 class QPaintDevice;
+
22 
+
23 #ifndef QT_NO_PRINTER
+
24 class QPrinter;
+
25 #endif
+
26 
+
27 #ifndef QWT_NO_SVG
+
28 #ifdef QT_SVG_LIB
+
29 class QSvgGenerator;
+
30 #endif
+
31 #endif
+
32 
+
37 class QWT_EXPORT QwtPlotRenderer: public QObject
+
38 {
+
39  Q_OBJECT
+
40 
+
41 public:
+ +
44  {
+
46  DiscardNone = 0x00,
+
47 
+
49  DiscardBackground = 0x01,
+
50 
+
52  DiscardTitle = 0x02,
+
53 
+
55  DiscardLegend = 0x04,
+
56 
+
58  DiscardCanvasBackground = 0x08,
+
59 
+
61  DiscardFooter = 0x10,
+
62 
+
70  DiscardCanvasFrame = 0x20
+
71 
+
72  };
+
73 
+
75  typedef QFlags<DiscardFlag> DiscardFlags;
+
76 
+ +
82  {
+
84  DefaultLayout = 0x00,
+
85 
+
90  FrameWithScales = 0x01
+
91  };
+
92 
+
94  typedef QFlags<LayoutFlag> LayoutFlags;
+
95 
+
96  explicit QwtPlotRenderer( QObject * = NULL );
+
97  virtual ~QwtPlotRenderer();
+
98 
+
99  void setDiscardFlag( DiscardFlag flag, bool on = true );
+
100  bool testDiscardFlag( DiscardFlag flag ) const;
+
101 
+
102  void setDiscardFlags( DiscardFlags flags );
+
103  DiscardFlags discardFlags() const;
+
104 
+
105  void setLayoutFlag( LayoutFlag flag, bool on = true );
+
106  bool testLayoutFlag( LayoutFlag flag ) const;
+
107 
+
108  void setLayoutFlags( LayoutFlags flags );
+
109  LayoutFlags layoutFlags() const;
+
110 
+
111  void renderDocument( QwtPlot *, const QString &fileName,
+
112  const QSizeF &sizeMM, int resolution = 85 );
+
113 
+
114  void renderDocument( QwtPlot *,
+
115  const QString &fileName, const QString &format,
+
116  const QSizeF &sizeMM, int resolution = 85 );
+
117 
+
118 #ifndef QWT_NO_SVG
+
119 #ifdef QT_SVG_LIB
+
120 #if QT_VERSION >= 0x040500
+
121  void renderTo( QwtPlot *, QSvgGenerator & ) const;
+
122 #endif
+
123 #endif
+
124 #endif
+
125 
+
126 #ifndef QT_NO_PRINTER
+
127  void renderTo( QwtPlot *, QPrinter & ) const;
+
128 #endif
+
129 
+
130  void renderTo( QwtPlot *, QPaintDevice &p ) const;
+
131 
+
132  virtual void render( QwtPlot *,
+
133  QPainter *, const QRectF &rect ) const;
+
134 
+
135  virtual void renderTitle( const QwtPlot *,
+
136  QPainter *, const QRectF & ) const;
+
137 
+
138  virtual void renderFooter( const QwtPlot *,
+
139  QPainter *, const QRectF & ) const;
+
140 
+
141  virtual void renderScale( const QwtPlot *, QPainter *,
+
142  int axisId, int startDist, int endDist,
+
143  int baseDist, const QRectF & ) const;
+
144 
+
145  virtual void renderCanvas( const QwtPlot *,
+
146  QPainter *, const QRectF &canvasRect,
+
147  const QwtScaleMap* maps ) const;
+
148 
+
149  virtual void renderLegend(
+
150  const QwtPlot *, QPainter *, const QRectF & ) const;
+
151 
+
152  bool exportTo( QwtPlot *, const QString &documentName,
+
153  const QSizeF &sizeMM = QSizeF( 300, 200 ), int resolution = 85 );
+
154 
+
155 private:
+
156  void buildCanvasMaps( const QwtPlot *,
+
157  const QRectF &, QwtScaleMap maps[] ) const;
+
158 
+
159  bool updateCanvasMargins( QwtPlot *,
+
160  const QRectF &, const QwtScaleMap maps[] ) const;
+
161 
+
162 private:
+
163  class PrivateData;
+
164  PrivateData *d_data;
+
165 };
+
166 
+
167 Q_DECLARE_OPERATORS_FOR_FLAGS( QwtPlotRenderer::DiscardFlags )
+
168 Q_DECLARE_OPERATORS_FOR_FLAGS( QwtPlotRenderer::LayoutFlags )
+
169 
+
170 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__plot__rescaler_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__plot__rescaler_8h_source.html new file mode 100644 index 0000000000..0d2306cb6d --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__plot__rescaler_8h_source.html @@ -0,0 +1,198 @@ + + + + + + +Qwt User's Guide: qwt_plot_rescaler.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_plot_rescaler.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_PLOT_RESCALER_H
+
11 #define QWT_PLOT_RESCALER_H 1
+
12 
+
13 #include "qwt_global.h"
+
14 #include "qwt_interval.h"
+
15 #include "qwt_plot.h"
+
16 #include <qobject.h>
+
17 
+
18 class QwtPlot;
+
19 class QResizeEvent;
+
20 
+
28 class QWT_EXPORT QwtPlotRescaler: public QObject
+
29 {
+
30 public:
+ +
38  {
+ +
45 
+ +
55 
+
60  Fitting
+
61  };
+
62 
+ +
68  {
+ +
71 
+ +
74 
+
76  ExpandBoth
+
77  };
+
78 
+
79  explicit QwtPlotRescaler( QWidget *canvas,
+
80  int referenceAxis = QwtPlot::xBottom,
+
81  RescalePolicy = Expanding );
+
82 
+
83  virtual ~QwtPlotRescaler();
+
84 
+
85  void setEnabled( bool );
+
86  bool isEnabled() const;
+
87 
+
88  void setRescalePolicy( RescalePolicy );
+
89  RescalePolicy rescalePolicy() const;
+
90 
+
91  void setExpandingDirection( ExpandingDirection );
+
92  void setExpandingDirection( int axis, ExpandingDirection );
+
93  ExpandingDirection expandingDirection( int axis ) const;
+
94 
+
95  void setReferenceAxis( int axis );
+
96  int referenceAxis() const;
+
97 
+
98  void setAspectRatio( double ratio );
+
99  void setAspectRatio( int axis, double ratio );
+
100  double aspectRatio( int axis ) const;
+
101 
+
102  void setIntervalHint( int axis, const QwtInterval& );
+
103  QwtInterval intervalHint( int axis ) const;
+
104 
+
105  QWidget *canvas();
+
106  const QWidget *canvas() const;
+
107 
+
108  QwtPlot *plot();
+
109  const QwtPlot *plot() const;
+
110 
+
111  virtual bool eventFilter( QObject *, QEvent * );
+
112 
+
113  void rescale() const;
+
114 
+
115 protected:
+
116  virtual void canvasResizeEvent( QResizeEvent * );
+
117 
+
118  virtual void rescale( const QSize &oldSize, const QSize &newSize ) const;
+
119  virtual QwtInterval expandScale(
+
120  int axis, const QSize &oldSize, const QSize &newSize ) const;
+
121 
+
122  virtual QwtInterval syncScale(
+
123  int axis, const QwtInterval& reference,
+
124  const QSize &size ) const;
+
125 
+
126  virtual void updateScales(
+
127  QwtInterval intervals[QwtPlot::axisCnt] ) const;
+
128 
+
129  Qt::Orientation orientation( int axis ) const;
+
130  QwtInterval interval( int axis ) const;
+
131  QwtInterval expandInterval( const QwtInterval &,
+
132  double width, ExpandingDirection ) const;
+
133 
+
134 private:
+
135  double pixelDist( int axis, const QSize & ) const;
+
136 
+
137  class AxisData;
+
138  class PrivateData;
+
139  PrivateData *d_data;
+
140 };
+
141 
+
142 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__plot__scaleitem_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__plot__scaleitem_8h_source.html new file mode 100644 index 0000000000..565514a715 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__plot__scaleitem_8h_source.html @@ -0,0 +1,159 @@ + + + + + + +Qwt User's Guide: qwt_plot_scaleitem.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_plot_scaleitem.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_PLOT_SCALE_ITEM_H
+
11 #define QWT_PLOT_SCALE_ITEM_H
+
12 
+
13 #include "qwt_global.h"
+
14 #include "qwt_plot_item.h"
+
15 #include "qwt_scale_draw.h"
+
16 
+
17 class QPalette;
+
18 
+
47 class QWT_EXPORT QwtPlotScaleItem: public QwtPlotItem
+
48 {
+
49 public:
+
50  explicit QwtPlotScaleItem(
+ +
52  const double pos = 0.0 );
+
53 
+
54  virtual ~QwtPlotScaleItem();
+
55 
+
56  virtual int rtti() const;
+
57 
+
58  void setScaleDiv( const QwtScaleDiv& );
+
59  const QwtScaleDiv& scaleDiv() const;
+
60 
+
61  void setScaleDivFromAxis( bool on );
+
62  bool isScaleDivFromAxis() const;
+
63 
+
64  void setPalette( const QPalette & );
+
65  QPalette palette() const;
+
66 
+
67  void setFont( const QFont& );
+
68  QFont font() const;
+
69 
+
70  void setScaleDraw( QwtScaleDraw * );
+
71 
+
72  const QwtScaleDraw *scaleDraw() const;
+
73  QwtScaleDraw *scaleDraw();
+
74 
+
75  void setPosition( double pos );
+
76  double position() const;
+
77 
+
78  void setBorderDistance( int numPixels );
+
79  int borderDistance() const;
+
80 
+
81  void setAlignment( QwtScaleDraw::Alignment );
+
82 
+
83  virtual void draw( QPainter *p,
+
84  const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+
85  const QRectF &rect ) const;
+
86 
+
87  virtual void updateScaleDiv( const QwtScaleDiv &, const QwtScaleDiv & );
+
88 
+
89 private:
+
90  class PrivateData;
+
91  PrivateData *d_data;
+
92 };
+
93 
+
94 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__plot__seriesitem_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__plot__seriesitem_8h_source.html new file mode 100644 index 0000000000..72c0c0c9eb --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__plot__seriesitem_8h_source.html @@ -0,0 +1,145 @@ + + + + + + +Qwt User's Guide: qwt_plot_seriesitem.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_plot_seriesitem.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_PLOT_SERIES_ITEM_H
+
11 #define QWT_PLOT_SERIES_ITEM_H
+
12 
+
13 #include "qwt_global.h"
+
14 #include "qwt_plot_item.h"
+
15 #include "qwt_scale_div.h"
+
16 #include "qwt_series_data.h"
+
17 #include "qwt_series_store.h"
+
18 
+
22 class QWT_EXPORT QwtPlotSeriesItem: public QwtPlotItem,
+
23  public virtual QwtAbstractSeriesStore
+
24 {
+
25 public:
+
26  explicit QwtPlotSeriesItem( const QString &title = QString::null );
+
27  explicit QwtPlotSeriesItem( const QwtText &title );
+
28 
+
29  virtual ~QwtPlotSeriesItem();
+
30 
+
31  void setOrientation( Qt::Orientation );
+
32  Qt::Orientation orientation() const;
+
33 
+
34  virtual void draw( QPainter *p,
+
35  const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+
36  const QRectF & ) const;
+
37 
+
49  virtual void drawSeries( QPainter *painter,
+
50  const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+
51  const QRectF &canvasRect, int from, int to ) const = 0;
+
52 
+
53  virtual QRectF boundingRect() const;
+
54 
+
55  virtual void updateScaleDiv(
+
56  const QwtScaleDiv &, const QwtScaleDiv & );
+
57 
+
58 protected:
+
59  virtual void dataChanged();
+
60 
+
61 private:
+
62  class PrivateData;
+
63  PrivateData *d_data;
+
64 };
+
65 
+
66 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__plot__shapeitem_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__plot__shapeitem_8h_source.html new file mode 100644 index 0000000000..60e682d413 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__plot__shapeitem_8h_source.html @@ -0,0 +1,171 @@ + + + + + + +Qwt User's Guide: qwt_plot_shapeitem.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_plot_shapeitem.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_PLOT_SHAPE_ITEM_H
+
11 #define QWT_PLOT_SHAPE_ITEM_H
+
12 
+
13 #include "qwt_global.h"
+
14 #include "qwt_plot_item.h"
+
15 #include <qpainterpath.h>
+
16 
+
31 class QWT_EXPORT QwtPlotShapeItem: public QwtPlotItem
+
32 {
+
33 public:
+ +
41  {
+
51  ClipPolygons = 0x01,
+
52  };
+
53 
+
55  typedef QFlags<PaintAttribute> PaintAttributes;
+
56 
+ +
59  {
+ +
62 
+
64  LegendColor
+
65  };
+
66 
+
67  explicit QwtPlotShapeItem( const QString &title = QString::null );
+
68  explicit QwtPlotShapeItem( const QwtText &title );
+
69 
+
70  virtual ~QwtPlotShapeItem();
+
71 
+
72  void setPaintAttribute( PaintAttribute, bool on = true );
+
73  bool testPaintAttribute( PaintAttribute ) const;
+
74 
+
75  void setLegendMode( LegendMode );
+
76  LegendMode legendMode() const;
+
77 
+
78  void setRect( const QRectF & );
+
79  void setPolygon( const QPolygonF & );
+
80 
+
81  void setShape( const QPainterPath & );
+
82  QPainterPath shape() const;
+
83 
+
84  void setPen( const QColor &, qreal width = 0.0, Qt::PenStyle = Qt::SolidLine );
+
85  void setPen( const QPen & );
+
86  QPen pen() const;
+
87 
+
88  void setBrush( const QBrush & );
+
89  QBrush brush() const;
+
90 
+
91  void setRenderTolerance( double );
+
92  double renderTolerance() const;
+
93 
+
94  virtual QRectF boundingRect() const;
+
95 
+
96  virtual void draw( QPainter *p,
+
97  const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+
98  const QRectF &rect ) const;
+
99 
+
100  virtual QwtGraphic legendIcon( int index, const QSizeF & ) const;
+
101 
+
102  virtual int rtti() const;
+
103 
+
104 private:
+
105  void init();
+
106 
+
107  class PrivateData;
+
108  PrivateData *d_data;
+
109 };
+
110 
+
111 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__plot__spectrocurve_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__plot__spectrocurve_8h_source.html new file mode 100644 index 0000000000..e22476b0bb --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__plot__spectrocurve_8h_source.html @@ -0,0 +1,165 @@ + + + + + + +Qwt User's Guide: qwt_plot_spectrocurve.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_plot_spectrocurve.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_PLOT_CURVE_3D_H
+
11 #define QWT_PLOT_CURVE_3D_H
+
12 
+
13 #include "qwt_global.h"
+
14 #include "qwt_plot_seriesitem.h"
+
15 #include "qwt_series_data.h"
+
16 
+
17 class QwtSymbol;
+
18 class QwtColorMap;
+
19 
+
24 class QWT_EXPORT QwtPlotSpectroCurve:
+
25  public QwtPlotSeriesItem, QwtSeriesStore<QwtPoint3D>
+
26 {
+
27 public:
+ +
30  {
+
32  ClipPoints = 1
+
33  };
+
34 
+
36  typedef QFlags<PaintAttribute> PaintAttributes;
+
37 
+
38  explicit QwtPlotSpectroCurve( const QString &title = QString::null );
+
39  explicit QwtPlotSpectroCurve( const QwtText &title );
+
40 
+
41  virtual ~QwtPlotSpectroCurve();
+
42 
+
43  virtual int rtti() const;
+
44 
+
45  void setPaintAttribute( PaintAttribute, bool on = true );
+
46  bool testPaintAttribute( PaintAttribute ) const;
+
47 
+
48  void setSamples( const QVector<QwtPoint3D> & );
+
49  void setSamples( QwtSeriesData<QwtPoint3D> * );
+
50 
+
51 
+
52  void setColorMap( QwtColorMap * );
+
53  const QwtColorMap *colorMap() const;
+
54 
+
55  void setColorRange( const QwtInterval & );
+
56  QwtInterval & colorRange() const;
+
57 
+
58  virtual void drawSeries( QPainter *,
+
59  const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+
60  const QRectF &canvasRect, int from, int to ) const;
+
61 
+
62  void setPenWidth(double width);
+
63  double penWidth() const;
+
64 
+
65 protected:
+
66  virtual void drawDots( QPainter *,
+
67  const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+
68  const QRectF &canvasRect, int from, int to ) const;
+
69 
+
70 private:
+
71  void init();
+
72 
+
73  class PrivateData;
+
74  PrivateData *d_data;
+
75 };
+
76 
+
77 Q_DECLARE_OPERATORS_FOR_FLAGS( QwtPlotSpectroCurve::PaintAttributes )
+
78 
+
79 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__plot__spectrogram_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__plot__spectrogram_8h_source.html new file mode 100644 index 0000000000..7af8e5434f --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__plot__spectrogram_8h_source.html @@ -0,0 +1,185 @@ + + + + + + +Qwt User's Guide: qwt_plot_spectrogram.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_plot_spectrogram.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_PLOT_SPECTROGRAM_H
+
11 #define QWT_PLOT_SPECTROGRAM_H
+
12 
+
13 #include "qwt_global.h"
+
14 #include "qwt_raster_data.h"
+
15 #include "qwt_plot_rasteritem.h"
+
16 #include <qlist.h>
+
17 
+
18 class QwtColorMap;
+
19 
+
38 class QWT_EXPORT QwtPlotSpectrogram: public QwtPlotRasterItem
+
39 {
+
40 public:
+ +
47  {
+
49  ImageMode = 0x01,
+
50 
+
52  ContourMode = 0x02
+
53  };
+
54 
+
56  typedef QFlags<DisplayMode> DisplayModes;
+
57 
+
58  explicit QwtPlotSpectrogram( const QString &title = QString::null );
+
59  virtual ~QwtPlotSpectrogram();
+
60 
+
61  void setDisplayMode( DisplayMode, bool on = true );
+
62  bool testDisplayMode( DisplayMode ) const;
+
63 
+
64  void setData( QwtRasterData *data );
+
65  const QwtRasterData *data() const;
+
66  QwtRasterData *data();
+
67 
+
68  void setColorMap( QwtColorMap * );
+
69  const QwtColorMap *colorMap() const;
+
70 
+
71  virtual QwtInterval interval(Qt::Axis) const;
+
72  virtual QRectF pixelHint( const QRectF & ) const;
+
73 
+
74  void setDefaultContourPen( const QColor &,
+
75  qreal width = 0.0, Qt::PenStyle = Qt::SolidLine );
+
76  void setDefaultContourPen( const QPen & );
+
77  QPen defaultContourPen() const;
+
78 
+
79  virtual QPen contourPen( double level ) const;
+
80 
+
81  void setConrecFlag( QwtRasterData::ConrecFlag, bool on );
+
82  bool testConrecFlag( QwtRasterData::ConrecFlag ) const;
+
83 
+
84  void setContourLevels( const QList<double> & );
+
85  QList<double> contourLevels() const;
+
86 
+
87  virtual int rtti() const;
+
88 
+
89  virtual void draw( QPainter *p,
+
90  const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+
91  const QRectF &rect ) const;
+
92 
+
93 protected:
+
94  virtual QImage renderImage(
+
95  const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+
96  const QRectF &area, const QSize &imageSize ) const;
+
97 
+
98  virtual QSize contourRasterSize(
+
99  const QRectF &, const QRect & ) const;
+
100 
+
101  virtual QwtRasterData::ContourLines renderContourLines(
+
102  const QRectF &rect, const QSize &raster ) const;
+
103 
+
104  virtual void drawContourLines( QPainter *p,
+
105  const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+
106  const QwtRasterData::ContourLines& lines ) const;
+
107 
+
108  void renderTile( const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+
109  const QRect &imageRect, QImage *image ) const;
+
110 
+
111 private:
+
112  class PrivateData;
+
113  PrivateData *d_data;
+
114 };
+
115 
+
116 Q_DECLARE_OPERATORS_FOR_FLAGS( QwtPlotSpectrogram::DisplayModes )
+
117 
+
118 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__plot__svgitem_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__plot__svgitem_8h_source.html new file mode 100644 index 0000000000..e4bd18e609 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__plot__svgitem_8h_source.html @@ -0,0 +1,147 @@ + + + + + + +Qwt User's Guide: qwt_plot_svgitem.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_plot_svgitem.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_PLOT_SVGITEM_H
+
11 #define QWT_PLOT_SVGITEM_H
+
12 
+
13 #include "qwt_global.h"
+
14 #include "qwt_plot_item.h"
+
15 #include <qstring.h>
+
16 
+
17 class QSvgRenderer;
+
18 class QByteArray;
+
19 
+
27 class QWT_EXPORT QwtPlotSvgItem: public QwtPlotItem
+
28 {
+
29 public:
+
30  explicit QwtPlotSvgItem( const QString& title = QString::null );
+
31  explicit QwtPlotSvgItem( const QwtText& title );
+
32  virtual ~QwtPlotSvgItem();
+
33 
+
34  bool loadFile( const QRectF&, const QString &fileName );
+
35  bool loadData( const QRectF&, const QByteArray & );
+
36 
+
37  virtual QRectF boundingRect() const;
+
38 
+
39  virtual void draw( QPainter *p,
+
40  const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+
41  const QRectF &rect ) const;
+
42 
+
43  virtual int rtti() const;
+
44 
+
45 protected:
+
46  const QSvgRenderer &renderer() const;
+
47  QSvgRenderer &renderer();
+
48 
+
49  void render( QPainter *painter,
+
50  const QRectF &viewBox, const QRectF &rect ) const;
+
51 
+
52  QRectF viewBox( const QRectF &area ) const;
+
53 
+
54 private:
+
55  void init();
+
56 
+
57  class PrivateData;
+
58  PrivateData *d_data;
+
59 };
+
60 
+
61 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__plot__textlabel_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__plot__textlabel_8h_source.html new file mode 100644 index 0000000000..76871747ba --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__plot__textlabel_8h_source.html @@ -0,0 +1,138 @@ + + + + + + +Qwt User's Guide: qwt_plot_textlabel.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_plot_textlabel.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_PLOT_TEXT_LABEL_H
+
11 #define QWT_PLOT_TEXT_LABEL_H 1
+
12 
+
13 #include "qwt_global.h"
+
14 #include "qwt_plot_item.h"
+
15 #include "qwt_text.h"
+
16 
+
47 class QWT_EXPORT QwtPlotTextLabel: public QwtPlotItem
+
48 {
+
49 public:
+ +
51  virtual ~QwtPlotTextLabel();
+
52 
+
53  virtual int rtti() const;
+
54 
+
55  void setText( const QwtText & );
+
56  QwtText text() const;
+
57 
+
58  void setMargin( int margin );
+
59  int margin() const;
+
60 
+
61  virtual QRectF textRect( const QRectF &, const QSizeF & ) const;
+
62 
+
63 protected:
+
64  virtual void draw( QPainter *,
+
65  const QwtScaleMap &, const QwtScaleMap &,
+
66  const QRectF &) const;
+
67 
+
68  void invalidateCache();
+
69 
+
70 private:
+
71  class PrivateData;
+
72  PrivateData *d_data;
+
73 };
+
74 
+
75 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__plot__tradingcurve_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__plot__tradingcurve_8h_source.html new file mode 100644 index 0000000000..b89a56eb36 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__plot__tradingcurve_8h_source.html @@ -0,0 +1,209 @@ + + + + + + +Qwt User's Guide: qwt_plot_tradingcurve.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_plot_tradingcurve.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_PLOT_TRADING_CURVE_H
+
11 #define QWT_PLOT_TRADING_CURVE_H
+
12 
+
13 #include "qwt_global.h"
+
14 #include "qwt_plot_seriesitem.h"
+
15 #include "qwt_series_data.h"
+
16 
+
38 class QWT_EXPORT QwtPlotTradingCurve:
+
39  public QwtPlotSeriesItem, QwtSeriesStore<QwtOHLCSample>
+
40 {
+
41 public:
+ +
49  {
+
51  NoSymbol = -1,
+
52 
+
59  Bar,
+
60 
+ +
68 
+
76  UserSymbol = 100
+
77  };
+
78 
+
82  enum Direction
+
83  {
+ +
86 
+
88  Decreasing
+
89  };
+
90 
+ +
96  {
+
98  ClipSymbols = 0x01
+
99  };
+
100 
+
102  typedef QFlags<PaintAttribute> PaintAttributes;
+
103 
+
104  explicit QwtPlotTradingCurve( const QString &title = QString::null );
+
105  explicit QwtPlotTradingCurve( const QwtText &title );
+
106 
+
107  virtual ~QwtPlotTradingCurve();
+
108 
+
109  virtual int rtti() const;
+
110 
+
111  void setPaintAttribute( PaintAttribute, bool on = true );
+
112  bool testPaintAttribute( PaintAttribute ) const;
+
113 
+
114  void setSamples( const QVector<QwtOHLCSample> & );
+
115  void setSamples( QwtSeriesData<QwtOHLCSample> * );
+
116 
+
117  void setSymbolStyle( SymbolStyle style );
+
118  SymbolStyle symbolStyle() const;
+
119 
+
120  void setSymbolPen( const QColor &,
+
121  qreal width = 0.0, Qt::PenStyle = Qt::SolidLine );
+
122  void setSymbolPen( const QPen & );
+
123  QPen symbolPen() const;
+
124 
+
125  void setSymbolBrush( Direction, const QBrush & );
+
126  QBrush symbolBrush( Direction ) const;
+
127 
+
128  void setSymbolExtent( double width );
+
129  double symbolExtent() const;
+
130 
+
131  void setMinSymbolWidth( double );
+
132  double minSymbolWidth() const;
+
133 
+
134  void setMaxSymbolWidth( double );
+
135  double maxSymbolWidth() const;
+
136 
+
137  virtual void drawSeries( QPainter *painter,
+
138  const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+
139  const QRectF &canvasRect, int from, int to ) const;
+
140 
+
141  virtual QRectF boundingRect() const;
+
142 
+
143  virtual QwtGraphic legendIcon( int index, const QSizeF & ) const;
+
144 
+
145 protected:
+
146 
+
147  void init();
+
148 
+
149  virtual void drawSymbols( QPainter *,
+
150  const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+
151  const QRectF &canvasRect, int from, int to ) const;
+
152 
+
153  virtual void drawUserSymbol( QPainter *,
+
154  SymbolStyle, const QwtOHLCSample &,
+
155  Qt::Orientation, bool inverted, double width ) const;
+
156 
+
157  void drawBar( QPainter *painter, const QwtOHLCSample &,
+
158  Qt::Orientation, bool inverted, double width ) const;
+
159 
+
160  void drawCandleStick( QPainter *, const QwtOHLCSample &,
+
161  Qt::Orientation, double width ) const;
+
162 
+
163  virtual double scaledSymbolWidth(
+
164  const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+
165  const QRectF &canvasRect ) const;
+
166 
+
167 private:
+
168  class PrivateData;
+
169  PrivateData *d_data;
+
170 };
+
171 
+
172 Q_DECLARE_OPERATORS_FOR_FLAGS( QwtPlotTradingCurve::PaintAttributes )
+
173 
+
174 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__plot__zoneitem_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__plot__zoneitem_8h_source.html new file mode 100644 index 0000000000..beec2d2182 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__plot__zoneitem_8h_source.html @@ -0,0 +1,147 @@ + + + + + + +Qwt User's Guide: qwt_plot_zoneitem.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_plot_zoneitem.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_PLOT_ZONE_ITEM_H
+
11 #define QWT_PLOT_ZONE_ITEM_H
+
12 
+
13 #include "qwt_global.h"
+
14 #include "qwt_plot_item.h"
+
15 #include "qwt_interval.h"
+
16 
+
17 class QPen;
+
18 class QBrush;
+
19 
+
31 class QWT_EXPORT QwtPlotZoneItem:
+
32  public QwtPlotItem
+
33 {
+
34 public:
+
35  explicit QwtPlotZoneItem();
+
36  virtual ~QwtPlotZoneItem();
+
37 
+
38  virtual int rtti() const;
+
39 
+
40  void setOrientation( Qt::Orientation );
+
41  Qt::Orientation orientation();
+
42 
+
43  void setInterval( double min, double max );
+
44  void setInterval( const QwtInterval & );
+
45  QwtInterval interval() const;
+
46 
+
47  void setPen( const QColor &, qreal width = 0.0, Qt::PenStyle = Qt::SolidLine );
+
48  void setPen( const QPen & );
+
49  const QPen &pen() const;
+
50 
+
51  void setBrush( const QBrush & );
+
52  const QBrush &brush() const;
+
53 
+
54  virtual void draw( QPainter *,
+
55  const QwtScaleMap &, const QwtScaleMap &,
+
56  const QRectF &) const;
+
57 
+
58  virtual QRectF boundingRect() const;
+
59 
+
60 private:
+
61  class PrivateData;
+
62  PrivateData *d_data;
+
63 };
+
64 
+
65 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__plot__zoomer_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__plot__zoomer_8h_source.html new file mode 100644 index 0000000000..69440e0648 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__plot__zoomer_8h_source.html @@ -0,0 +1,166 @@ + + + + + + +Qwt User's Guide: qwt_plot_zoomer.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_plot_zoomer.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_PLOT_ZOOMER_H
+
11 #define QWT_PLOT_ZOOMER_H
+
12 
+
13 #include "qwt_global.h"
+
14 #include "qwt_plot_picker.h"
+
15 #include <qstack.h>
+
16 
+
77 class QWT_EXPORT QwtPlotZoomer: public QwtPlotPicker
+
78 {
+
79  Q_OBJECT
+
80 public:
+
81  explicit QwtPlotZoomer( QWidget *, bool doReplot = true );
+
82  explicit QwtPlotZoomer( int xAxis, int yAxis,
+
83  QWidget *, bool doReplot = true );
+
84 
+
85  virtual ~QwtPlotZoomer();
+
86 
+
87  virtual void setZoomBase( bool doReplot = true );
+
88  virtual void setZoomBase( const QRectF & );
+
89 
+
90  QRectF zoomBase() const;
+
91  QRectF zoomRect() const;
+
92 
+
93  virtual void setAxis( int xAxis, int yAxis );
+
94 
+
95  void setMaxStackDepth( int );
+
96  int maxStackDepth() const;
+
97 
+
98  const QStack<QRectF> &zoomStack() const;
+
99  void setZoomStack( const QStack<QRectF> &,
+
100  int zoomRectIndex = -1 );
+
101 
+
102  uint zoomRectIndex() const;
+
103 
+
104 public Q_SLOTS:
+
105  void moveBy( double x, double y );
+
106  virtual void moveTo( const QPointF & );
+
107 
+
108  virtual void zoom( const QRectF & );
+
109  virtual void zoom( int up );
+
110 
+
111 Q_SIGNALS:
+
119  void zoomed( const QRectF &rect );
+
120 
+
121 protected:
+
122  virtual void rescale();
+
123 
+
124  virtual QSizeF minZoomSize() const;
+
125 
+
126  virtual void widgetMouseReleaseEvent( QMouseEvent * );
+
127  virtual void widgetKeyPressEvent( QKeyEvent * );
+
128 
+
129  virtual void begin();
+
130  virtual bool end( bool ok = true );
+
131  virtual bool accept( QPolygon & ) const;
+
132 
+
133 private:
+
134  void init( bool doReplot );
+
135 
+
136  class PrivateData;
+
137  PrivateData *d_data;
+
138 };
+
139 
+
140 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__point__3d_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__point__3d_8h_source.html new file mode 100644 index 0000000000..b70cb75f1f --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__point__3d_8h_source.html @@ -0,0 +1,244 @@ + + + + + + +Qwt User's Guide: qwt_point_3d.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_point_3d.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
11 #ifndef QWT_POINT_3D_H
+
12 #define QWT_POINT_3D_H 1
+
13 
+
14 #include "qwt_global.h"
+
15 #include <qpoint.h>
+
16 #ifndef QT_NO_DEBUG_STREAM
+
17 #include <qdebug.h>
+
18 #endif
+
19 
+
24 class QWT_EXPORT QwtPoint3D
+
25 {
+
26 public:
+
27  QwtPoint3D();
+
28  QwtPoint3D( double x, double y, double z );
+
29  QwtPoint3D( const QwtPoint3D & );
+
30  QwtPoint3D( const QPointF & );
+
31 
+
32  bool isNull() const;
+
33 
+
34  double x() const;
+
35  double y() const;
+
36  double z() const;
+
37 
+
38  double &rx();
+
39  double &ry();
+
40  double &rz();
+
41 
+
42  void setX( double x );
+
43  void setY( double y );
+
44  void setZ( double y );
+
45 
+
46  QPointF toPoint() const;
+
47 
+
48  bool operator==( const QwtPoint3D & ) const;
+
49  bool operator!=( const QwtPoint3D & ) const;
+
50 
+
51 private:
+
52  double d_x;
+
53  double d_y;
+
54  double d_z;
+
55 };
+
56 
+
57 Q_DECLARE_TYPEINFO(QwtPoint3D, Q_MOVABLE_TYPE);
+
58 
+
59 #ifndef QT_NO_DEBUG_STREAM
+
60 QWT_EXPORT QDebug operator<<( QDebug, const QwtPoint3D & );
+
61 #endif
+
62 
+ +
68  d_x( 0.0 ),
+
69  d_y( 0.0 ),
+
70  d_z( 0.0 )
+
71 {
+
72 }
+
73 
+
75 inline QwtPoint3D::QwtPoint3D( double x, double y, double z = 0.0 ):
+
76  d_x( x ),
+
77  d_y( y ),
+
78  d_z( z )
+
79 {
+
80 }
+
81 
+
86 inline QwtPoint3D::QwtPoint3D( const QwtPoint3D &other ):
+
87  d_x( other.d_x ),
+
88  d_y( other.d_y ),
+
89  d_z( other.d_z )
+
90 {
+
91 }
+
92 
+
97 inline QwtPoint3D::QwtPoint3D( const QPointF &other ):
+
98  d_x( other.x() ),
+
99  d_y( other.y() ),
+
100  d_z( 0.0 )
+
101 {
+
102 }
+
103 
+
110 inline bool QwtPoint3D::isNull() const
+
111 {
+
112  return d_x == 0.0 && d_y == 0.0 && d_z == 0.0;
+
113 }
+
114 
+
116 inline double QwtPoint3D::x() const
+
117 {
+
118  return d_x;
+
119 }
+
120 
+
122 inline double QwtPoint3D::y() const
+
123 {
+
124  return d_y;
+
125 }
+
126 
+
128 inline double QwtPoint3D::z() const
+
129 {
+
130  return d_z;
+
131 }
+
132 
+
134 inline double &QwtPoint3D::rx()
+
135 {
+
136  return d_x;
+
137 }
+
138 
+
140 inline double &QwtPoint3D::ry()
+
141 {
+
142  return d_y;
+
143 }
+
144 
+
146 inline double &QwtPoint3D::rz()
+
147 {
+
148  return d_z;
+
149 }
+
150 
+
152 inline void QwtPoint3D::setX( double x )
+
153 {
+
154  d_x = x;
+
155 }
+
156 
+
158 inline void QwtPoint3D::setY( double y )
+
159 {
+
160  d_y = y;
+
161 }
+
162 
+
164 inline void QwtPoint3D::setZ( double z )
+
165 {
+
166  d_z = z;
+
167 }
+
168 
+
172 inline QPointF QwtPoint3D::toPoint() const
+
173 {
+
174  return QPointF( d_x, d_y );
+
175 }
+
176 
+
178 inline bool QwtPoint3D::operator==( const QwtPoint3D &other ) const
+
179 {
+
180  return ( d_x == other.d_x ) && ( d_y == other.d_y ) && ( d_z == other.d_z );
+
181 }
+
182 
+
184 inline bool QwtPoint3D::operator!=( const QwtPoint3D &other ) const
+
185 {
+
186  return !operator==( other );
+
187 }
+
188 
+
189 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__point__data_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__point__data_8h_source.html new file mode 100644 index 0000000000..b8e8b937b5 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__point__data_8h_source.html @@ -0,0 +1,174 @@ + + + + + + +Qwt User's Guide: qwt_point_data.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_point_data.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_POINT_DATA_H
+
11 #define QWT_POINT_DATA_H 1
+
12 
+
13 #include "qwt_global.h"
+
14 #include "qwt_series_data.h"
+
15 
+
19 class QWT_EXPORT QwtPointArrayData: public QwtSeriesData<QPointF>
+
20 {
+
21 public:
+
22  QwtPointArrayData( const QVector<double> &x, const QVector<double> &y );
+
23  QwtPointArrayData( const double *x, const double *y, size_t size );
+
24 
+
25  virtual QRectF boundingRect() const;
+
26 
+
27  virtual size_t size() const;
+
28  virtual QPointF sample( size_t i ) const;
+
29 
+
30  const QVector<double> &xData() const;
+
31  const QVector<double> &yData() const;
+
32 
+
33 private:
+
34  QVector<double> d_x;
+
35  QVector<double> d_y;
+
36 };
+
37 
+
41 class QWT_EXPORT QwtCPointerData: public QwtSeriesData<QPointF>
+
42 {
+
43 public:
+
44  QwtCPointerData( const double *x, const double *y, size_t size );
+
45 
+
46  virtual QRectF boundingRect() const;
+
47  virtual size_t size() const;
+
48  virtual QPointF sample( size_t i ) const;
+
49 
+
50  const double *xData() const;
+
51  const double *yData() const;
+
52 
+
53 private:
+
54  const double *d_x;
+
55  const double *d_y;
+
56  size_t d_size;
+
57 };
+
58 
+
112 class QWT_EXPORT QwtSyntheticPointData: public QwtSeriesData<QPointF>
+
113 {
+
114 public:
+
115  QwtSyntheticPointData( size_t size,
+
116  const QwtInterval & = QwtInterval() );
+
117 
+
118  void setSize( size_t size );
+
119  virtual size_t size() const;
+
120 
+
121  void setInterval( const QwtInterval& );
+
122  QwtInterval interval() const;
+
123 
+
124  virtual QRectF boundingRect() const;
+
125  virtual QPointF sample( size_t i ) const;
+
126 
+
133  virtual double y( double x ) const = 0;
+
134  virtual double x( uint index ) const;
+
135 
+
136  virtual void setRectOfInterest( const QRectF & );
+
137  QRectF rectOfInterest() const;
+
138 
+
139 private:
+
140  size_t d_size;
+
141  QwtInterval d_interval;
+
142  QRectF d_rectOfInterest;
+
143  QwtInterval d_intervalOfInterest;
+
144 };
+
145 
+
146 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__point__mapper_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__point__mapper_8h_source.html new file mode 100644 index 0000000000..71872d9580 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__point__mapper_8h_source.html @@ -0,0 +1,161 @@ + + + + + + +Qwt User's Guide: qwt_point_mapper.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_point_mapper.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2003 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_POINT_MAPPER_H
+
11 #define QWT_POINT_MAPPER_H
+
12 
+
13 #include "qwt_global.h"
+
14 #include "qwt_series_data.h"
+
15 #include <qimage.h>
+
16 
+
17 class QwtScaleMap;
+
18 class QPolygonF;
+
19 class QPolygon;
+
20 
+
29 class QWT_EXPORT QwtPointMapper
+
30 {
+
31 public:
+ +
37  {
+
39  RoundPoints = 0x01,
+
40 
+
45  WeedOutPoints = 0x02
+
46  };
+
47 
+
52  typedef QFlags<TransformationFlag> TransformationFlags;
+
53 
+ +
55  ~QwtPointMapper();
+
56 
+
57  void setFlags( TransformationFlags );
+
58  TransformationFlags flags() const;
+
59 
+
60  void setFlag( TransformationFlag, bool on = true );
+
61  bool testFlag( TransformationFlag ) const;
+
62 
+
63  void setBoundingRect( const QRectF & );
+
64  QRectF boundingRect() const;
+
65 
+
66  QPolygonF toPolygonF( const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+
67  const QwtSeriesData<QPointF> *series, int from, int to ) const;
+
68 
+
69  QPolygon toPolygon( const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+
70  const QwtSeriesData<QPointF> *series, int from, int to ) const;
+
71 
+
72  QPolygon toPoints( const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+
73  const QwtSeriesData<QPointF> *series, int from, int to ) const;
+
74 
+
75  QPolygonF toPointsF( const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+
76  const QwtSeriesData<QPointF> *series, int from, int to ) const;
+
77 
+
78  QImage toImage( const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+
79  const QwtSeriesData<QPointF> *series, int from, int to,
+
80  const QPen &, bool antialiased, uint numThreads ) const;
+
81 
+
82 private:
+
83  class PrivateData;
+
84  PrivateData *d_data;
+
85 };
+
86 
+
87 Q_DECLARE_OPERATORS_FOR_FLAGS( QwtPointMapper::TransformationFlags )
+
88 
+
89 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__point__polar_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__point__polar_8h_source.html new file mode 100644 index 0000000000..b76f61e330 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__point__polar_8h_source.html @@ -0,0 +1,264 @@ + + + + + + +Qwt User's Guide: qwt_point_polar.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_point_polar.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
11 #ifndef _QWT_POINT_POLAR_H_
+
12 #define _QWT_POINT_POLAR_H_ 1
+
13 
+
14 #include "qwt_global.h"
+
15 #include "qwt_math.h"
+
16 #include <qpoint.h>
+
17 #ifndef QT_NO_DEBUG_STREAM
+
18 #include <qdebug.h>
+
19 #endif
+
20 
+
28 class QWT_EXPORT QwtPointPolar
+
29 {
+
30 public:
+
31  QwtPointPolar();
+
32  QwtPointPolar( double azimuth, double radius );
+
33  QwtPointPolar( const QwtPointPolar & );
+
34  QwtPointPolar( const QPointF & );
+
35 
+
36  void setPoint( const QPointF & );
+
37  QPointF toPoint() const;
+
38 
+
39  bool isValid() const;
+
40  bool isNull() const;
+
41 
+
42  double radius() const;
+
43  double azimuth() const;
+
44 
+
45  double &rRadius();
+
46  double &rAzimuth();
+
47 
+
48  void setRadius( double );
+
49  void setAzimuth( double );
+
50 
+
51  bool operator==( const QwtPointPolar & ) const;
+
52  bool operator!=( const QwtPointPolar & ) const;
+
53 
+
54  QwtPointPolar normalized() const;
+
55 
+
56 private:
+
57  double d_azimuth;
+
58  double d_radius;
+
59 };
+
60 
+ +
66  d_azimuth( 0.0 ),
+
67  d_radius( 0.0 )
+
68 {
+
69 }
+
70 
+
77 inline QwtPointPolar::QwtPointPolar( double azimuth, double radius ):
+
78  d_azimuth( azimuth ),
+
79  d_radius( radius )
+
80 {
+
81 }
+
82 
+ +
88  d_azimuth( other.d_azimuth ),
+
89  d_radius( other.d_radius )
+
90 {
+
91 }
+
92 
+
94 inline bool QwtPointPolar::isValid() const
+
95 {
+
96  return d_radius >= 0.0;
+
97 }
+
98 
+
100 inline bool QwtPointPolar::isNull() const
+
101 {
+
102  return d_radius == 0.0;
+
103 }
+
104 
+
106 inline double QwtPointPolar::radius() const
+
107 {
+
108  return d_radius;
+
109 }
+
110 
+
112 inline double QwtPointPolar::azimuth() const
+
113 {
+
114  return d_azimuth;
+
115 }
+
116 
+
118 inline double &QwtPointPolar::rRadius()
+
119 {
+
120  return d_radius;
+
121 }
+
122 
+
124 inline double &QwtPointPolar::rAzimuth()
+
125 {
+
126  return d_azimuth;
+
127 }
+
128 
+
130 inline void QwtPointPolar::setRadius( double radius )
+
131 {
+
132  d_radius = radius;
+
133 }
+
134 
+
136 inline void QwtPointPolar::setAzimuth( double azimuth )
+
137 {
+
138  d_azimuth = azimuth;
+
139 }
+
140 
+
141 #ifndef QT_NO_DEBUG_STREAM
+
142 QWT_EXPORT QDebug operator<<( QDebug, const QwtPointPolar & );
+
143 #endif
+
144 
+
145 inline QPoint qwtPolar2Pos( const QPoint &pole,
+
146  double radius, double angle )
+
147 {
+
148  const double x = pole.x() + radius * qCos( angle );
+
149  const double y = pole.y() - radius * qSin( angle );
+
150 
+
151  return QPoint( qRound( x ), qRound( y ) );
+
152 }
+
153 
+
154 inline QPoint qwtDegree2Pos( const QPoint &pole,
+
155  double radius, double angle )
+
156 {
+
157  return qwtPolar2Pos( pole, radius, angle / 180.0 * M_PI );
+
158 }
+
159 
+
160 inline QPointF qwtPolar2Pos( const QPointF &pole,
+
161  double radius, double angle )
+
162 {
+
163  const double x = pole.x() + radius * qCos( angle );
+
164  const double y = pole.y() - radius * qSin( angle );
+
165 
+
166  return QPointF( x, y);
+
167 }
+
168 
+
169 inline QPointF qwtDegree2Pos( const QPointF &pole,
+
170  double radius, double angle )
+
171 {
+
172  return qwtPolar2Pos( pole, radius, angle / 180.0 * M_PI );
+
173 }
+
174 
+
175 inline QPointF qwtFastPolar2Pos( const QPointF &pole,
+
176  double radius, double angle )
+
177 {
+
178 #if QT_VERSION < 0x040601
+
179  const double x = pole.x() + radius * ::cos( angle );
+
180  const double y = pole.y() - radius * ::sin( angle );
+
181 #else
+
182  const double x = pole.x() + radius * qFastCos( angle );
+
183  const double y = pole.y() - radius * qFastSin( angle );
+
184 #endif
+
185 
+
186  return QPointF( x, y);
+
187 }
+
188 
+
189 inline QPointF qwtFastDegree2Pos( const QPointF &pole,
+
190  double radius, double angle )
+
191 {
+
192  return qwtFastPolar2Pos( pole, radius, angle / 180.0 * M_PI );
+
193 }
+
194 
+
195 inline QwtPointPolar qwtFastPos2Polar( const QPointF &pos )
+
196 {
+
197  return QwtPointPolar( qwtFastAtan2( pos.y(), pos.x() ),
+
198  qSqrt( qwtSqr( pos.x() ) + qwtSqr( pos.y() ) ) );
+
199 }
+
200 
+
201 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__raster__data_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__raster__data_8h_source.html new file mode 100644 index 0000000000..93ff6c7da0 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__raster__data_8h_source.html @@ -0,0 +1,163 @@ + + + + + + +Qwt User's Guide: qwt_raster_data.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_raster_data.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_RASTER_DATA_H
+
11 #define QWT_RASTER_DATA_H 1
+
12 
+
13 #include "qwt_global.h"
+
14 #include "qwt_interval.h"
+
15 #include <qmap.h>
+
16 #include <qlist.h>
+
17 #include <qpolygon.h>
+
18 
+
19 class QwtScaleMap;
+
20 
+
32 class QWT_EXPORT QwtRasterData
+
33 {
+
34 public:
+
36  typedef QMap<double, QPolygonF> ContourLines;
+
37 
+ +
40  {
+
42  IgnoreAllVerticesOnLevel = 0x01,
+
43 
+
45  IgnoreOutOfRange = 0x02
+
46  };
+
47 
+
49  typedef QFlags<ConrecFlag> ConrecFlags;
+
50 
+
51  QwtRasterData();
+
52  virtual ~QwtRasterData();
+
53 
+
54  virtual void setInterval( Qt::Axis, const QwtInterval & );
+
55  const QwtInterval &interval(Qt::Axis) const;
+
56 
+
57  virtual QRectF pixelHint( const QRectF & ) const;
+
58 
+
59  virtual void initRaster( const QRectF &, const QSize& raster );
+
60  virtual void discardRaster();
+
61 
+
67  virtual double value( double x, double y ) const = 0;
+
68 
+
69  virtual ContourLines contourLines( const QRectF &rect,
+
70  const QSize &raster, const QList<double> &levels,
+
71  ConrecFlags ) const;
+
72 
+
73  class Contour3DPoint;
+
74  class ContourPlane;
+
75 
+
76 private:
+
77  // Disabled copy constructor and operator=
+
78  QwtRasterData( const QwtRasterData & );
+
79  QwtRasterData &operator=( const QwtRasterData & );
+
80 
+
81  QwtInterval d_intervals[3];
+
82 };
+
83 
+
88 inline const QwtInterval &QwtRasterData::interval( Qt::Axis axis) const
+
89 {
+
90  return d_intervals[axis];
+
91 }
+
92 
+
93 Q_DECLARE_OPERATORS_FOR_FLAGS( QwtRasterData::ConrecFlags )
+
94 
+
95 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__round__scale__draw_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__round__scale__draw_8h_source.html new file mode 100644 index 0000000000..19a3f65443 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__round__scale__draw_8h_source.html @@ -0,0 +1,145 @@ + + + + + + +Qwt User's Guide: qwt_round_scale_draw.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_round_scale_draw.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_ROUND_SCALE_DRAW_H
+
11 #define QWT_ROUND_SCALE_DRAW_H
+
12 
+
13 #include "qwt_global.h"
+
14 #include "qwt_abstract_scale_draw.h"
+
15 #include <qpoint.h>
+
16 
+
30 class QWT_EXPORT QwtRoundScaleDraw: public QwtAbstractScaleDraw
+
31 {
+
32 public:
+ +
34  virtual ~QwtRoundScaleDraw();
+
35 
+
36  void setRadius( double radius );
+
37  double radius() const;
+
38 
+
39  void moveCenter( double x, double y );
+
40  void moveCenter( const QPointF & );
+
41  QPointF center() const;
+
42 
+
43  void setAngleRange( double angle1, double angle2 );
+
44 
+
45  virtual double extent( const QFont & ) const;
+
46 
+
47 protected:
+
48  virtual void drawTick( QPainter *, double val, double len ) const;
+
49  virtual void drawBackbone( QPainter * ) const;
+
50  virtual void drawLabel( QPainter *, double val ) const;
+
51 
+
52 private:
+ +
54  QwtRoundScaleDraw &operator=( const QwtRoundScaleDraw &other );
+
55 
+
56  class PrivateData;
+
57  PrivateData *d_data;
+
58 };
+
59 
+
61 inline void QwtRoundScaleDraw::moveCenter( double x, double y )
+
62 {
+
63  moveCenter( QPointF( x, y ) );
+
64 }
+
65 
+
66 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__samples_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__samples_8h_source.html new file mode 100644 index 0000000000..37cc900270 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__samples_8h_source.html @@ -0,0 +1,260 @@ + + + + + + +Qwt User's Guide: qwt_samples.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_samples.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_SAMPLES_H
+
11 #define QWT_SAMPLES_H 1
+
12 
+
13 #include "qwt_global.h"
+
14 #include "qwt_interval.h"
+
15 #include <qvector.h>
+
16 #include <qrect.h>
+
17 
+
19 class QWT_EXPORT QwtIntervalSample
+
20 {
+
21 public:
+ +
23  QwtIntervalSample( double, const QwtInterval & );
+
24  QwtIntervalSample( double value, double min, double max );
+
25 
+
26  bool operator==( const QwtIntervalSample & ) const;
+
27  bool operator!=( const QwtIntervalSample & ) const;
+
28 
+
30  double value;
+
31 
+ +
34 };
+
35 
+ +
41  value( 0.0 )
+
42 {
+
43 }
+
44 
+ +
47  double v, const QwtInterval &intv ):
+
48  value( v ),
+
49  interval( intv )
+
50 {
+
51 }
+
52 
+ +
55  double v, double min, double max ):
+
56  value( v ),
+
57  interval( min, max )
+
58 {
+
59 }
+
60 
+ +
63  const QwtIntervalSample &other ) const
+
64 {
+
65  return value == other.value && interval == other.interval;
+
66 }
+
67 
+ +
70  const QwtIntervalSample &other ) const
+
71 {
+
72  return !( *this == other );
+
73 }
+
74 
+
76 class QWT_EXPORT QwtSetSample
+
77 {
+
78 public:
+
79  QwtSetSample();
+
80  QwtSetSample( double, const QVector<double> & = QVector<double>() );
+
81 
+
82  bool operator==( const QwtSetSample &other ) const;
+
83  bool operator!=( const QwtSetSample &other ) const;
+
84 
+
85  double added() const;
+
86 
+
88  double value;
+
89 
+
91  QVector<double> set;
+
92 };
+
93 
+ +
99  value( 0.0 )
+
100 {
+
101 }
+
102 
+
109 inline QwtSetSample::QwtSetSample( double v, const QVector< double > &s ):
+
110  value( v ),
+
111  set( s )
+
112 {
+
113 }
+
114 
+
116 inline bool QwtSetSample::operator==( const QwtSetSample &other ) const
+
117 {
+
118  return value == other.value && set == other.set;
+
119 }
+
120 
+
122 inline bool QwtSetSample::operator!=( const QwtSetSample &other ) const
+
123 {
+
124  return !( *this == other );
+
125 }
+
126 
+
128 inline double QwtSetSample::added() const
+
129 {
+
130  double y = 0.0;
+
131  for ( int i = 0; i < set.size(); i++ )
+
132  y += set[i];
+
133 
+
134  return y;
+
135 }
+
136 
+
146 class QWT_EXPORT QwtOHLCSample
+
147 {
+
148 public:
+
149  QwtOHLCSample( double time = 0.0,
+
150  double open = 0.0, double high = 0.0,
+
151  double low = 0.0, double close = 0.0 );
+
152 
+
153  QwtInterval boundingInterval() const;
+
154 
+
155  bool isValid() const;
+
156 
+
161  double time;
+
162 
+
164  double open;
+
165 
+
167  double high;
+
168 
+
170  double low;
+
171 
+
173  double close;
+
174 };
+
175 
+
176 
+ +
187  double o, double h, double l, double c ):
+
188  time( t ),
+
189  open( o ),
+
190  high( h ),
+
191  low( l ),
+
192  close( c )
+
193 {
+
194 }
+
195 
+
207 inline bool QwtOHLCSample::isValid() const
+
208 {
+
209  return ( low <= high )
+
210  && ( open >= low )
+
211  && ( open <= high )
+
212  && ( close >= low )
+
213  && ( close <= high );
+
214 }
+
215 
+ +
225 {
+
226  double minY = open;
+
227  minY = qMin( minY, high );
+
228  minY = qMin( minY, low );
+
229  minY = qMin( minY, close );
+
230 
+
231  double maxY = open;
+
232  maxY = qMax( maxY, high );
+
233  maxY = qMax( maxY, low );
+
234  maxY = qMax( maxY, close );
+
235 
+
236  return QwtInterval( minY, maxY );
+
237 }
+
238 
+
239 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__sampling__thread_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__sampling__thread_8h_source.html new file mode 100644 index 0000000000..ddabc53058 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__sampling__thread_8h_source.html @@ -0,0 +1,126 @@ + + + + + + +Qwt User's Guide: qwt_sampling_thread.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_sampling_thread.h
+
+
+
1 #ifndef _QWT_SAMPLING_THREAD_H_
+
2 #define _QWT_SAMPLING_THREAD_H_
+
3 
+
4 #include "qwt_global.h"
+
5 #include <qthread.h>
+
6 
+
19 class QWT_EXPORT QwtSamplingThread: public QThread
+
20 {
+
21  Q_OBJECT
+
22 
+
23 public:
+
24  virtual ~QwtSamplingThread();
+
25 
+
26  double interval() const;
+
27  double elapsed() const;
+
28 
+
29 public Q_SLOTS:
+
30  void setInterval( double interval );
+
31  void stop();
+
32 
+
33 protected:
+
34  explicit QwtSamplingThread( QObject *parent = NULL );
+
35 
+
36  virtual void run();
+
37 
+
43  virtual void sample( double elapsed ) = 0;
+
44 
+
45 private:
+
46  class PrivateData;
+
47  PrivateData *d_data;
+
48 };
+
49 
+
50 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__scale__div_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__scale__div_8h_source.html new file mode 100644 index 0000000000..24aa64234d --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__scale__div_8h_source.html @@ -0,0 +1,182 @@ + + + + + + +Qwt User's Guide: qwt_scale_div.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_scale_div.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_SCALE_DIV_H
+
11 #define QWT_SCALE_DIV_H
+
12 
+
13 #include "qwt_global.h"
+
14 #include "qwt_interval.h"
+
15 #include <qlist.h>
+
16 
+
17 #ifndef QT_NO_DEBUG_STREAM
+
18 #include <qdebug.h>
+
19 #endif
+
20 
+
36 class QWT_EXPORT QwtScaleDiv
+
37 {
+
38 public:
+
40  enum TickType
+
41  {
+
43  NoTick = -1,
+
44 
+ +
47 
+ +
50 
+ +
53 
+
55  NTickTypes
+
56  };
+
57 
+
58  explicit QwtScaleDiv( double lowerBound = 0.0,
+
59  double upperBound = 0.0 );
+
60 
+
61  explicit QwtScaleDiv( const QwtInterval &, QList<double>[NTickTypes] );
+
62 
+
63  explicit QwtScaleDiv( double lowerBound, double upperBound,
+
64  QList<double>[NTickTypes] );
+
65 
+
66  explicit QwtScaleDiv( double lowerBound, double upperBound,
+
67  const QList<double> &minorTicks, const QList<double> &mediumTicks,
+
68  const QList<double> &majorTicks );
+
69 
+
70  bool operator==( const QwtScaleDiv & ) const;
+
71  bool operator!=( const QwtScaleDiv & ) const;
+
72 
+
73  void setInterval( double lowerBound, double upperBound );
+
74  void setInterval( const QwtInterval & );
+
75  QwtInterval interval() const;
+
76 
+
77  void setLowerBound( double );
+
78  double lowerBound() const;
+
79 
+
80  void setUpperBound( double );
+
81  double upperBound() const;
+
82 
+
83  double range() const;
+
84 
+
85  bool contains( double value ) const;
+
86 
+
87  void setTicks( int tickType, const QList<double> & );
+
88  QList<double> ticks( int tickType ) const;
+
89 
+
90  bool isEmpty() const;
+
91  bool isIncreasing() const;
+
92 
+
93  void invert();
+
94  QwtScaleDiv inverted() const;
+
95 
+
96  QwtScaleDiv bounded( double lowerBound, double upperBound ) const;
+
97 
+
98 private:
+
99  double d_lowerBound;
+
100  double d_upperBound;
+
101  QList<double> d_ticks[NTickTypes];
+
102 };
+
103 
+
104 Q_DECLARE_TYPEINFO( QwtScaleDiv, Q_MOVABLE_TYPE );
+
105 
+
106 #ifndef QT_NO_DEBUG_STREAM
+
107 QWT_EXPORT QDebug operator<<( QDebug, const QwtScaleDiv & );
+
108 #endif
+
109 
+
110 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__scale__draw_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__scale__draw_8h_source.html new file mode 100644 index 0000000000..bc8de2d403 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__scale__draw_8h_source.html @@ -0,0 +1,185 @@ + + + + + + +Qwt User's Guide: qwt_scale_draw.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_scale_draw.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_SCALE_DRAW_H
+
11 #define QWT_SCALE_DRAW_H
+
12 
+
13 #include "qwt_global.h"
+
14 #include "qwt_abstract_scale_draw.h"
+
15 #include <qpoint.h>
+
16 #include <qrect.h>
+
17 #include <qtransform.h>
+
18 
+
31 class QWT_EXPORT QwtScaleDraw: public QwtAbstractScaleDraw
+
32 {
+
33 public:
+
38  enum Alignment
+
39  {
+ +
42 
+ +
45 
+ +
48 
+
50  RightScale
+
51  };
+
52 
+
53  QwtScaleDraw();
+
54  virtual ~QwtScaleDraw();
+
55 
+
56  void getBorderDistHint( const QFont &, int &start, int &end ) const;
+
57  int minLabelDist( const QFont & ) const;
+
58 
+
59  int minLength( const QFont & ) const;
+
60  virtual double extent( const QFont & ) const;
+
61 
+
62  void move( double x, double y );
+
63  void move( const QPointF & );
+
64  void setLength( double length );
+
65 
+
66  Alignment alignment() const;
+
67  void setAlignment( Alignment );
+
68 
+
69  Qt::Orientation orientation() const;
+
70 
+
71  QPointF pos() const;
+
72  double length() const;
+
73 
+
74  void setLabelAlignment( Qt::Alignment );
+
75  Qt::Alignment labelAlignment() const;
+
76 
+
77  void setLabelRotation( double rotation );
+
78  double labelRotation() const;
+
79 
+
80  int maxLabelHeight( const QFont & ) const;
+
81  int maxLabelWidth( const QFont & ) const;
+
82 
+
83  QPointF labelPosition( double val ) const;
+
84 
+
85  QRectF labelRect( const QFont &, double val ) const;
+
86  QSizeF labelSize( const QFont &, double val ) const;
+
87 
+
88  QRect boundingLabelRect( const QFont &, double val ) const;
+
89 
+
90 protected:
+
91  QTransform labelTransformation( const QPointF &, const QSizeF & ) const;
+
92 
+
93  virtual void drawTick( QPainter *, double val, double len ) const;
+
94  virtual void drawBackbone( QPainter * ) const;
+
95  virtual void drawLabel( QPainter *, double val ) const;
+
96 
+
97 private:
+
98  QwtScaleDraw( const QwtScaleDraw & );
+
99  QwtScaleDraw &operator=( const QwtScaleDraw &other );
+
100 
+
101  void updateMap();
+
102 
+
103  class PrivateData;
+
104  PrivateData *d_data;
+
105 };
+
106 
+
115 inline void QwtScaleDraw::move( double x, double y )
+
116 {
+
117  move( QPointF( x, y ) );
+
118 }
+
119 
+
120 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__scale__engine_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__scale__engine_8h_source.html new file mode 100644 index 0000000000..2ee086d37f --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__scale__engine_8h_source.html @@ -0,0 +1,243 @@ + + + + + + +Qwt User's Guide: qwt_scale_engine.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_scale_engine.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_SCALE_ENGINE_H
+
11 #define QWT_SCALE_ENGINE_H
+
12 
+
13 #include "qwt_global.h"
+
14 #include "qwt_scale_div.h"
+
15 #include "qwt_interval.h"
+
16 
+
17 class QwtTransform;
+
18 
+
22 class QWT_EXPORT QwtScaleArithmetic
+
23 {
+
24 public:
+
25  static double ceilEps( double value, double intervalSize );
+
26  static double floorEps( double value, double intervalSize );
+
27 
+
28  static double divideEps( double interval, double steps );
+
29 
+
30  static double divideInterval( double interval,
+
31  int numSteps, uint base );
+
32 };
+
33 
+
45 class QWT_EXPORT QwtScaleEngine
+
46 {
+
47 public:
+
54  enum Attribute
+
55  {
+
57  NoAttribute = 0x00,
+
58 
+
60  IncludeReference = 0x01,
+
61 
+
63  Symmetric = 0x02,
+
64 
+
72  Floating = 0x04,
+
73 
+
75  Inverted = 0x08
+
76  };
+
77 
+
79  typedef QFlags<Attribute> Attributes;
+
80 
+
81  explicit QwtScaleEngine( uint base = 10 );
+
82  virtual ~QwtScaleEngine();
+
83 
+
84  void setBase( uint base );
+
85  uint base() const;
+
86 
+
87  void setAttribute( Attribute, bool on = true );
+
88  bool testAttribute( Attribute ) const;
+
89 
+
90  void setAttributes( Attributes );
+
91  Attributes attributes() const;
+
92 
+
93  void setReference( double reference );
+
94  double reference() const;
+
95 
+
96  void setMargins( double lower, double upper );
+
97  double lowerMargin() const;
+
98  double upperMargin() const;
+
99 
+
108  virtual void autoScale( int maxNumSteps,
+
109  double &x1, double &x2, double &stepSize ) const = 0;
+
110 
+
123  virtual QwtScaleDiv divideScale( double x1, double x2,
+
124  int maxMajorSteps, int maxMinorSteps,
+
125  double stepSize = 0.0 ) const = 0;
+
126 
+
127  void setTransformation( QwtTransform * );
+
128  QwtTransform *transformation() const;
+
129 
+
130 protected:
+
131  bool contains( const QwtInterval &, double val ) const;
+
132  QList<double> strip( const QList<double>&, const QwtInterval & ) const;
+
133 
+
134  double divideInterval( double interval, int numSteps ) const;
+
135 
+
136  QwtInterval buildInterval( double v ) const;
+
137 
+
138 private:
+
139  class PrivateData;
+
140  PrivateData *d_data;
+
141 };
+
142 
+
150 class QWT_EXPORT QwtLinearScaleEngine: public QwtScaleEngine
+
151 {
+
152 public:
+
153  QwtLinearScaleEngine( uint base = 10 );
+
154  virtual ~QwtLinearScaleEngine();
+
155 
+
156  virtual void autoScale( int maxSteps,
+
157  double &x1, double &x2, double &stepSize ) const;
+
158 
+
159  virtual QwtScaleDiv divideScale( double x1, double x2,
+
160  int numMajorSteps, int numMinorSteps,
+
161  double stepSize = 0.0 ) const;
+
162 
+
163 
+
164 protected:
+
165  QwtInterval align( const QwtInterval&, double stepSize ) const;
+
166 
+
167  void buildTicks(
+
168  const QwtInterval &, double stepSize, int maxMinSteps,
+
169  QList<double> ticks[QwtScaleDiv::NTickTypes] ) const;
+
170 
+
171  QList<double> buildMajorTicks(
+
172  const QwtInterval &interval, double stepSize ) const;
+
173 
+
174  void buildMinorTicks( const QList<double>& majorTicks,
+
175  int maxMinorSteps, double stepSize,
+
176  QList<double> &minorTicks, QList<double> &mediumTicks ) const;
+
177 };
+
178 
+
190 class QWT_EXPORT QwtLogScaleEngine: public QwtScaleEngine
+
191 {
+
192 public:
+
193  QwtLogScaleEngine( uint base = 10 );
+
194  virtual ~QwtLogScaleEngine();
+
195 
+
196  virtual void autoScale( int maxSteps,
+
197  double &x1, double &x2, double &stepSize ) const;
+
198 
+
199  virtual QwtScaleDiv divideScale( double x1, double x2,
+
200  int numMajorSteps, int numMinorSteps,
+
201  double stepSize = 0.0 ) const;
+
202 
+
203 protected:
+
204  QwtInterval align( const QwtInterval&, double stepSize ) const;
+
205 
+
206  void buildTicks(
+
207  const QwtInterval &, double stepSize, int maxMinSteps,
+
208  QList<double> ticks[QwtScaleDiv::NTickTypes] ) const;
+
209 
+
210  QList<double> buildMajorTicks(
+
211  const QwtInterval &interval, double stepSize ) const;
+
212 
+
213  void buildMinorTicks( const QList<double>& majorTicks,
+
214  int maxMinorSteps, double stepSize,
+
215  QList<double> &minorTicks, QList<double> &mediumTicks ) const;
+
216 };
+
217 
+
218 Q_DECLARE_OPERATORS_FOR_FLAGS( QwtScaleEngine::Attributes )
+
219 
+
220 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__scale__map_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__scale__map_8h_source.html new file mode 100644 index 0000000000..44a25157b8 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__scale__map_8h_source.html @@ -0,0 +1,224 @@ + + + + + + +Qwt User's Guide: qwt_scale_map.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_scale_map.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_SCALE_MAP_H
+
11 #define QWT_SCALE_MAP_H
+
12 
+
13 #include "qwt_global.h"
+
14 #include "qwt_transform.h"
+
15 #include <qrect.h>
+
16 
+
17 #ifndef QT_NO_DEBUG_STREAM
+
18 #include <qdebug.h>
+
19 #endif
+
20 
+
21 class QRectF;
+
22 
+
30 class QWT_EXPORT QwtScaleMap
+
31 {
+
32 public:
+
33  QwtScaleMap();
+
34  QwtScaleMap( const QwtScaleMap& );
+
35 
+
36  ~QwtScaleMap();
+
37 
+
38  QwtScaleMap &operator=( const QwtScaleMap & );
+
39 
+
40  void setTransformation( QwtTransform * );
+
41  const QwtTransform *transformation() const;
+
42 
+
43  void setPaintInterval( double p1, double p2 );
+
44  void setScaleInterval( double s1, double s2 );
+
45 
+
46  double transform( double s ) const;
+
47  double invTransform( double p ) const;
+
48 
+
49  double p1() const;
+
50  double p2() const;
+
51 
+
52  double s1() const;
+
53  double s2() const;
+
54 
+
55  double pDist() const;
+
56  double sDist() const;
+
57 
+
58  static QRectF transform( const QwtScaleMap &,
+
59  const QwtScaleMap &, const QRectF & );
+
60  static QRectF invTransform( const QwtScaleMap &,
+
61  const QwtScaleMap &, const QRectF & );
+
62 
+
63  static QPointF transform( const QwtScaleMap &,
+
64  const QwtScaleMap &, const QPointF & );
+
65  static QPointF invTransform( const QwtScaleMap &,
+
66  const QwtScaleMap &, const QPointF & );
+
67 
+
68  bool isInverting() const;
+
69 
+
70 private:
+
71  void updateFactor();
+
72 
+
73  double d_s1, d_s2; // scale interval boundaries
+
74  double d_p1, d_p2; // paint device interval boundaries
+
75 
+
76  double d_cnv; // conversion factor
+
77  double d_ts1;
+
78 
+
79  QwtTransform *d_transform;
+
80 };
+
81 
+
85 inline double QwtScaleMap::s1() const
+
86 {
+
87  return d_s1;
+
88 }
+
89 
+
93 inline double QwtScaleMap::s2() const
+
94 {
+
95  return d_s2;
+
96 }
+
97 
+
101 inline double QwtScaleMap::p1() const
+
102 {
+
103  return d_p1;
+
104 }
+
105 
+
109 inline double QwtScaleMap::p2() const
+
110 {
+
111  return d_p2;
+
112 }
+
113 
+
117 inline double QwtScaleMap::pDist() const
+
118 {
+
119  return qAbs( d_p2 - d_p1 );
+
120 }
+
121 
+
125 inline double QwtScaleMap::sDist() const
+
126 {
+
127  return qAbs( d_s2 - d_s1 );
+
128 }
+
129 
+
139 inline double QwtScaleMap::transform( double s ) const
+
140 {
+
141  if ( d_transform )
+
142  s = d_transform->transform( s );
+
143 
+
144  return d_p1 + ( s - d_ts1 ) * d_cnv;
+
145 }
+
146 
+
156 inline double QwtScaleMap::invTransform( double p ) const
+
157 {
+
158  double s = d_ts1 + ( p - d_p1 ) / d_cnv;
+
159  if ( d_transform )
+
160  s = d_transform->invTransform( s );
+
161 
+
162  return s;
+
163 }
+
164 
+
166 inline bool QwtScaleMap::isInverting() const
+
167 {
+
168  return ( ( d_p1 < d_p2 ) != ( d_s1 < d_s2 ) );
+
169 }
+
170 
+
171 #ifndef QT_NO_DEBUG_STREAM
+
172 QWT_EXPORT QDebug operator<<( QDebug, const QwtScaleMap & );
+
173 #endif
+
174 
+
175 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__scale__widget_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__scale__widget_8h_source.html new file mode 100644 index 0000000000..469ddd0b27 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__scale__widget_8h_source.html @@ -0,0 +1,215 @@ + + + + + + +Qwt User's Guide: qwt_scale_widget.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_scale_widget.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_SCALE_WIDGET_H
+
11 #define QWT_SCALE_WIDGET_H
+
12 
+
13 #include "qwt_global.h"
+
14 #include "qwt_text.h"
+
15 #include "qwt_scale_draw.h"
+
16 #include <qwidget.h>
+
17 #include <qfont.h>
+
18 #include <qcolor.h>
+
19 #include <qstring.h>
+
20 
+
21 class QPainter;
+
22 class QwtTransform;
+
23 class QwtScaleDiv;
+
24 class QwtColorMap;
+
25 
+
33 class QWT_EXPORT QwtScaleWidget : public QWidget
+
34 {
+
35  Q_OBJECT
+
36 
+
37 public:
+ +
40  {
+
45  TitleInverted = 1
+
46  };
+
47 
+
49  typedef QFlags<LayoutFlag> LayoutFlags;
+
50 
+
51  explicit QwtScaleWidget( QWidget *parent = NULL );
+
52  explicit QwtScaleWidget( QwtScaleDraw::Alignment, QWidget *parent = NULL );
+
53  virtual ~QwtScaleWidget();
+
54 
+
55 Q_SIGNALS:
+
57  void scaleDivChanged();
+
58 
+
59 public:
+
60  void setTitle( const QString &title );
+
61  void setTitle( const QwtText &title );
+
62  QwtText title() const;
+
63 
+
64  void setLayoutFlag( LayoutFlag, bool on );
+
65  bool testLayoutFlag( LayoutFlag ) const;
+
66 
+
67  void setBorderDist( int start, int end );
+
68  int startBorderDist() const;
+
69  int endBorderDist() const;
+
70 
+
71  void getBorderDistHint( int &start, int &end ) const;
+
72 
+
73  void getMinBorderDist( int &start, int &end ) const;
+
74  void setMinBorderDist( int start, int end );
+
75 
+
76  void setMargin( int );
+
77  int margin() const;
+
78 
+
79  void setSpacing( int td );
+
80  int spacing() const;
+
81 
+
82  void setScaleDiv( const QwtScaleDiv &sd );
+
83  void setTransformation( QwtTransform * );
+
84 
+
85  void setScaleDraw( QwtScaleDraw * );
+
86  const QwtScaleDraw *scaleDraw() const;
+
87  QwtScaleDraw *scaleDraw();
+
88 
+
89  void setLabelAlignment( Qt::Alignment );
+
90  void setLabelRotation( double rotation );
+
91 
+
92  void setColorBarEnabled( bool );
+
93  bool isColorBarEnabled() const;
+
94 
+
95  void setColorBarWidth( int );
+
96  int colorBarWidth() const;
+
97 
+
98  void setColorMap( const QwtInterval &, QwtColorMap * );
+
99 
+
100  QwtInterval colorBarInterval() const;
+
101  const QwtColorMap *colorMap() const;
+
102 
+
103  virtual QSize sizeHint() const;
+
104  virtual QSize minimumSizeHint() const;
+
105 
+
106  int titleHeightForWidth( int width ) const;
+
107  int dimForLength( int length, const QFont &scaleFont ) const;
+
108 
+
109  void drawColorBar( QPainter *painter, const QRectF & ) const;
+
110  void drawTitle( QPainter *painter, QwtScaleDraw::Alignment,
+
111  const QRectF &rect ) const;
+
112 
+
113  void setAlignment( QwtScaleDraw::Alignment );
+
114  QwtScaleDraw::Alignment alignment() const;
+
115 
+
116  QRectF colorBarRect( const QRectF& ) const;
+
117 
+
118 protected:
+
119  virtual void paintEvent( QPaintEvent * );
+
120  virtual void resizeEvent( QResizeEvent * );
+
121 
+
122  void draw( QPainter *p ) const;
+
123 
+
124  void scaleChange();
+
125  void layoutScale( bool update = true );
+
126 
+
127 private:
+
128  void initScale( QwtScaleDraw::Alignment );
+
129 
+
130  class PrivateData;
+
131  PrivateData *d_data;
+
132 };
+
133 
+
134 Q_DECLARE_OPERATORS_FOR_FLAGS( QwtScaleWidget::LayoutFlags )
+
135 
+
136 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__series__data_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__series__data_8h_source.html new file mode 100644 index 0000000000..9bcc2d9d5a --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__series__data_8h_source.html @@ -0,0 +1,301 @@ + + + + + + +Qwt User's Guide: qwt_series_data.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_series_data.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_SERIES_DATA_H
+
11 #define QWT_SERIES_DATA_H 1
+
12 
+
13 #include "qwt_global.h"
+
14 #include "qwt_samples.h"
+
15 #include "qwt_point_3d.h"
+
16 #include "qwt_point_polar.h"
+
17 #include <qvector.h>
+
18 #include <qrect.h>
+
19 
+
46 template <typename T>
+ +
48 {
+
49 public:
+
51  QwtSeriesData();
+
52 
+
54  virtual ~QwtSeriesData();
+
55 
+
57  virtual size_t size() const = 0;
+
58 
+
64  virtual T sample( size_t i ) const = 0;
+
65 
+
78  virtual QRectF boundingRect() const = 0;
+
79 
+
91  virtual void setRectOfInterest( const QRectF &rect );
+
92 
+
93 protected:
+
95  mutable QRectF d_boundingRect;
+
96 
+
97 private:
+
98  QwtSeriesData<T> &operator=( const QwtSeriesData<T> & );
+
99 };
+
100 
+
101 template <typename T>
+ +
103  d_boundingRect( 0.0, 0.0, -1.0, -1.0 )
+
104 {
+
105 }
+
106 
+
107 template <typename T>
+ +
109 {
+
110 }
+
111 
+
112 template <typename T>
+ +
114 {
+
115 }
+
116 
+
123 template <typename T>
+ +
125 {
+
126 public:
+ +
129 
+
134  QwtArraySeriesData( const QVector<T> &samples );
+
135 
+
140  void setSamples( const QVector<T> &samples );
+
141 
+
143  const QVector<T> samples() const;
+
144 
+
146  virtual size_t size() const;
+
147 
+
154  virtual T sample( size_t index ) const;
+
155 
+
156 protected:
+
158  QVector<T> d_samples;
+
159 };
+
160 
+
161 template <typename T>
+ +
163 {
+
164 }
+
165 
+
166 template <typename T>
+
167 QwtArraySeriesData<T>::QwtArraySeriesData( const QVector<T> &samples ):
+
168  d_samples( samples )
+
169 {
+
170 }
+
171 
+
172 template <typename T>
+
173 void QwtArraySeriesData<T>::setSamples( const QVector<T> &samples )
+
174 {
+
175  QwtSeriesData<T>::d_boundingRect = QRectF( 0.0, 0.0, -1.0, -1.0 );
+
176  d_samples = samples;
+
177 }
+
178 
+
179 template <typename T>
+
180 const QVector<T> QwtArraySeriesData<T>::samples() const
+
181 {
+
182  return d_samples;
+
183 }
+
184 
+
185 template <typename T>
+ +
187 {
+
188  return d_samples.size();
+
189 }
+
190 
+
191 template <typename T>
+
192 T QwtArraySeriesData<T>::sample( size_t i ) const
+
193 {
+
194  return d_samples[ static_cast<int>( i ) ];
+
195 }
+
196 
+
198 class QWT_EXPORT QwtPointSeriesData: public QwtArraySeriesData<QPointF>
+
199 {
+
200 public:
+ +
202  const QVector<QPointF> & = QVector<QPointF>() );
+
203 
+
204  virtual QRectF boundingRect() const;
+
205 };
+
206 
+
208 class QWT_EXPORT QwtPoint3DSeriesData: public QwtArraySeriesData<QwtPoint3D>
+
209 {
+
210 public:
+ +
212  const QVector<QwtPoint3D> & = QVector<QwtPoint3D>() );
+
213  virtual QRectF boundingRect() const;
+
214 };
+
215 
+
217 class QWT_EXPORT QwtIntervalSeriesData: public QwtArraySeriesData<QwtIntervalSample>
+
218 {
+
219 public:
+ +
221  const QVector<QwtIntervalSample> & = QVector<QwtIntervalSample>() );
+
222 
+
223  virtual QRectF boundingRect() const;
+
224 };
+
225 
+
227 class QWT_EXPORT QwtSetSeriesData: public QwtArraySeriesData<QwtSetSample>
+
228 {
+
229 public:
+ +
231  const QVector<QwtSetSample> & = QVector<QwtSetSample>() );
+
232 
+
233  virtual QRectF boundingRect() const;
+
234 };
+
235 
+
239 class QWT_EXPORT QwtTradingChartData: public QwtArraySeriesData<QwtOHLCSample>
+
240 {
+
241 public:
+ +
243  const QVector<QwtOHLCSample> & = QVector<QwtOHLCSample>() );
+
244 
+
245  virtual QRectF boundingRect() const;
+
246 };
+
247 
+
248 QWT_EXPORT QRectF qwtBoundingRect(
+
249  const QwtSeriesData<QPointF> &, int from = 0, int to = -1 );
+
250 
+
251 QWT_EXPORT QRectF qwtBoundingRect(
+
252  const QwtSeriesData<QwtPoint3D> &, int from = 0, int to = -1 );
+
253 
+
254 QWT_EXPORT QRectF qwtBoundingRect(
+
255  const QwtSeriesData<QwtPointPolar> &, int from = 0, int to = -1 );
+
256 
+
257 QWT_EXPORT QRectF qwtBoundingRect(
+
258  const QwtSeriesData<QwtIntervalSample> &, int from = 0, int to = -1 );
+
259 
+
260 QWT_EXPORT QRectF qwtBoundingRect(
+
261  const QwtSeriesData<QwtSetSample> &, int from = 0, int to = -1 );
+
262 
+
263 QWT_EXPORT QRectF qwtBoundingRect(
+
264  const QwtSeriesData<QwtOHLCSample> &, int from = 0, int to = -1 );
+
265 
+
324 template <typename T, typename LessThan>
+
325 inline int qwtUpperSampleIndex( const QwtSeriesData<T> &series,
+
326  double value, LessThan lessThan )
+
327 {
+
328  const int indexMax = series.size() - 1;
+
329 
+
330  if ( indexMax < 0 || !lessThan( value, series.sample( indexMax ) ) )
+
331  return -1;
+
332 
+
333  int indexMin = 0;
+
334  int n = indexMax;
+
335 
+
336  while ( n > 0 )
+
337  {
+
338  const int half = n >> 1;
+
339  const int indexMid = indexMin + half;
+
340 
+
341  if ( lessThan( value, series.sample( indexMid ) ) )
+
342  {
+
343  n = half;
+
344  }
+
345  else
+
346  {
+
347  indexMin = indexMid + 1;
+
348  n -= half + 1;
+
349  }
+
350  }
+
351 
+
352  return indexMin;
+
353 }
+
354 
+
355 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__series__store_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__series__store_8h_source.html new file mode 100644 index 0000000000..c792d5506d --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__series__store_8h_source.html @@ -0,0 +1,226 @@ + + + + + + +Qwt User's Guide: qwt_series_store.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_series_store.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_SERIES_STORE_H
+
11 #define QWT_SERIES_STORE_H
+
12 
+
13 #include "qwt_global.h"
+
14 #include "qwt_series_data.h"
+
15 
+ +
25 {
+
26 protected:
+ +
29 
+
31  virtual void dataChanged() = 0;
+
32 
+
37  virtual void setRectOfInterest( const QRectF & ) = 0;
+
38 
+
40  virtual QRectF dataRect() const = 0;
+
41 
+
43  virtual size_t dataSize() const = 0;
+
44 };
+
45 
+
56 template <typename T>
+ +
58 {
+
59 public:
+
64  explicit QwtSeriesStore<T>();
+
65 
+ +
68 
+
76  void setData( QwtSeriesData<T> *series );
+
77 
+ +
80 
+
82  const QwtSeriesData<T> *data() const;
+
83 
+
88  T sample( int index ) const;
+
89 
+
94  virtual size_t dataSize() const;
+
95 
+
102  virtual QRectF dataRect() const;
+
103 
+
110  virtual void setRectOfInterest( const QRectF &rect );
+
111 
+ +
119 
+
120 private:
+
121  QwtSeriesData<T> *d_series;
+
122 };
+
123 
+
124 template <typename T>
+ +
126  d_series( NULL )
+
127 {
+
128 }
+
129 
+
130 template <typename T>
+ +
132 {
+
133  delete d_series;
+
134 }
+
135 
+
136 template <typename T>
+ +
138 {
+
139  return d_series;
+
140 }
+
141 
+
142 template <typename T>
+ +
144 {
+
145  return d_series;
+
146 }
+
147 
+
148 template <typename T>
+
149 inline T QwtSeriesStore<T>::sample( int index ) const
+
150 {
+
151  return d_series ? d_series->sample( index ) : T();
+
152 }
+
153 
+
154 template <typename T>
+ +
156 {
+
157  if ( d_series != series )
+
158  {
+
159  delete d_series;
+
160  d_series = series;
+
161  dataChanged();
+
162  }
+
163 }
+
164 
+
165 template <typename T>
+ +
167 {
+
168  if ( d_series == NULL )
+
169  return 0;
+
170 
+
171  return d_series->size();
+
172 }
+
173 
+
174 template <typename T>
+ +
176 {
+
177  if ( d_series == NULL )
+
178  return QRectF( 1.0, 1.0, -2.0, -2.0 ); // invalid
+
179 
+
180  return d_series->boundingRect();
+
181 }
+
182 
+
183 template <typename T>
+
184 void QwtSeriesStore<T>::setRectOfInterest( const QRectF &rect )
+
185 {
+
186  if ( d_series )
+
187  d_series->setRectOfInterest( rect );
+
188 }
+
189 
+
190 template <typename T>
+ +
192 {
+
193  QwtSeriesData<T> * swappedSeries = d_series;
+
194  d_series = series;
+
195 
+
196  return swappedSeries;
+
197 }
+
198 
+
199 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__slider_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__slider_8h_source.html new file mode 100644 index 0000000000..7a9531c0c1 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__slider_8h_source.html @@ -0,0 +1,204 @@ + + + + + + +Qwt User's Guide: qwt_slider.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_slider.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_SLIDER_H
+
11 #define QWT_SLIDER_H
+
12 
+
13 #include "qwt_global.h"
+
14 #include "qwt_abstract_slider.h"
+
15 
+
16 class QwtScaleDraw;
+
17 
+
30 class QWT_EXPORT QwtSlider: public QwtAbstractSlider
+
31 {
+
32  Q_OBJECT
+
33 
+
34  Q_ENUMS( ScalePosition BackgroundStyle )
+
35 
+
36  Q_PROPERTY( Qt::Orientation orientation
+
37  READ orientation WRITE setOrientation )
+
38  Q_PROPERTY( ScalePosition scalePosition READ scalePosition
+
39  WRITE setScalePosition )
+
40 
+
41  Q_PROPERTY( bool trough READ hasTrough WRITE setTrough )
+
42  Q_PROPERTY( bool groove READ hasGroove WRITE setGroove )
+
43 
+
44  Q_PROPERTY( QSize handleSize READ handleSize WRITE setHandleSize )
+
45  Q_PROPERTY( int borderWidth READ borderWidth WRITE setBorderWidth )
+
46  Q_PROPERTY( int spacing READ spacing WRITE setSpacing )
+
47 
+
48 public:
+
49 
+ +
55  {
+ +
58 
+ +
61 
+
63  TrailingScale
+
64  };
+
65 
+
66  explicit QwtSlider( QWidget *parent = NULL );
+
67  explicit QwtSlider( Qt::Orientation, QWidget *parent = NULL );
+
68 
+
69  virtual ~QwtSlider();
+
70 
+
71  void setOrientation( Qt::Orientation );
+
72  Qt::Orientation orientation() const;
+
73 
+
74  void setScalePosition( ScalePosition );
+
75  ScalePosition scalePosition() const;
+
76 
+
77  void setTrough( bool );
+
78  bool hasTrough() const;
+
79 
+
80  void setGroove( bool );
+
81  bool hasGroove() const;
+
82 
+
83  void setHandleSize( const QSize & );
+
84  QSize handleSize() const;
+
85 
+
86  void setBorderWidth( int bw );
+
87  int borderWidth() const;
+
88 
+
89  void setSpacing( int );
+
90  int spacing() const;
+
91 
+
92  virtual QSize sizeHint() const;
+
93  virtual QSize minimumSizeHint() const;
+
94 
+
95  void setScaleDraw( QwtScaleDraw * );
+
96  const QwtScaleDraw *scaleDraw() const;
+
97 
+
98  void setUpdateInterval( int );
+
99  int updateInterval() const;
+
100 
+
101 protected:
+
102  virtual double scrolledTo( const QPoint & ) const;
+
103  virtual bool isScrollPosition( const QPoint & ) const;
+
104 
+
105  virtual void drawSlider ( QPainter *, const QRect & ) const;
+
106  virtual void drawHandle( QPainter *, const QRect &, int pos ) const;
+
107 
+
108  virtual void mousePressEvent( QMouseEvent * );
+
109  virtual void mouseReleaseEvent( QMouseEvent * );
+
110  virtual void resizeEvent( QResizeEvent * );
+
111  virtual void paintEvent ( QPaintEvent * );
+
112  virtual void changeEvent( QEvent * );
+
113  virtual void timerEvent( QTimerEvent * );
+
114 
+
115  virtual void scaleChange();
+
116 
+
117  QRect sliderRect() const;
+
118  QRect handleRect() const;
+
119 
+
120 private:
+
121  QwtScaleDraw *scaleDraw();
+
122 
+
123  void layoutSlider( bool );
+
124  void initSlider( Qt::Orientation );
+
125 
+
126  class PrivateData;
+
127  PrivateData *d_data;
+
128 };
+
129 
+
130 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__spline_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__spline_8h_source.html new file mode 100644 index 0000000000..eb2e7356f2 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__spline_8h_source.html @@ -0,0 +1,151 @@ + + + + + + +Qwt User's Guide: qwt_spline.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_spline.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_SPLINE_H
+
11 #define QWT_SPLINE_H
+
12 
+
13 #include "qwt_global.h"
+
14 #include <qpolygon.h>
+
15 #include <qvector.h>
+
16 
+
57 class QWT_EXPORT QwtSpline
+
58 {
+
59 public:
+ +
62  {
+ +
65 
+
67  Periodic
+
68  };
+
69 
+
70  QwtSpline();
+
71  QwtSpline( const QwtSpline & );
+
72 
+
73  ~QwtSpline();
+
74 
+
75  QwtSpline &operator=( const QwtSpline & );
+
76 
+
77  void setSplineType( SplineType );
+
78  SplineType splineType() const;
+
79 
+
80  bool setPoints( const QPolygonF& points );
+
81  QPolygonF points() const;
+
82 
+
83  void reset();
+
84 
+
85  bool isValid() const;
+
86  double value( double x ) const;
+
87 
+
88  const QVector<double> &coefficientsA() const;
+
89  const QVector<double> &coefficientsB() const;
+
90  const QVector<double> &coefficientsC() const;
+
91 
+
92 protected:
+
93  bool buildNaturalSpline( const QPolygonF & );
+
94  bool buildPeriodicSpline( const QPolygonF & );
+
95 
+
96 private:
+
97  class PrivateData;
+
98  PrivateData *d_data;
+
99 };
+
100 
+
101 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__symbol_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__symbol_8h_source.html new file mode 100644 index 0000000000..67dad11eb3 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__symbol_8h_source.html @@ -0,0 +1,258 @@ + + + + + + +Qwt User's Guide: qwt_symbol.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_symbol.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_SYMBOL_H
+
11 #define QWT_SYMBOL_H
+
12 
+
13 #include "qwt_global.h"
+
14 #include <qpolygon.h>
+
15 
+
16 class QPainter;
+
17 class QRect;
+
18 class QSize;
+
19 class QBrush;
+
20 class QPen;
+
21 class QColor;
+
22 class QPointF;
+
23 class QPolygonF;
+
24 class QPainterPath;
+
25 class QPixmap;
+
26 class QByteArray;
+
27 class QwtGraphic;
+
28 
+
30 class QWT_EXPORT QwtSymbol
+
31 {
+
32 public:
+
37  enum Style
+
38  {
+
40  NoSymbol = -1,
+
41 
+ +
44 
+ +
47 
+ +
50 
+ +
53 
+ +
56 
+ +
59 
+ +
62 
+ +
65 
+ +
68 
+ +
71 
+ +
74 
+ +
77 
+ +
80 
+ +
83 
+ +
86 
+ +
95 
+ +
103 
+ +
111 
+ +
119 
+
125  UserStyle = 1000
+
126  };
+
127 
+ +
150  {
+ +
153 
+ +
156 
+
163  AutoCache
+
164  };
+
165 
+
166 public:
+
167  QwtSymbol( Style = NoSymbol );
+
168  QwtSymbol( Style, const QBrush &, const QPen &, const QSize & );
+
169  QwtSymbol( const QPainterPath &, const QBrush &, const QPen & );
+
170 
+
171  virtual ~QwtSymbol();
+
172 
+
173  void setCachePolicy( CachePolicy );
+
174  CachePolicy cachePolicy() const;
+
175 
+
176  void setSize( const QSize & );
+
177  void setSize( int width, int height = -1 );
+
178  const QSize& size() const;
+
179 
+
180  void setPinPoint( const QPointF &pos, bool enable = true );
+
181  QPointF pinPoint() const;
+
182 
+
183  void setPinPointEnabled( bool );
+
184  bool isPinPointEnabled() const;
+
185 
+
186  virtual void setColor( const QColor & );
+
187 
+
188  void setBrush( const QBrush& b );
+
189  const QBrush& brush() const;
+
190 
+
191  void setPen( const QColor &, qreal width = 0.0, Qt::PenStyle = Qt::SolidLine );
+
192  void setPen( const QPen & );
+
193  const QPen& pen() const;
+
194 
+
195  void setStyle( Style );
+
196  Style style() const;
+
197 
+
198  void setPath( const QPainterPath & );
+
199  const QPainterPath &path() const;
+
200 
+
201  void setPixmap( const QPixmap & );
+
202  const QPixmap &pixmap() const;
+
203 
+
204  void setGraphic( const QwtGraphic & );
+
205  const QwtGraphic &graphic() const;
+
206 
+
207 #ifndef QWT_NO_SVG
+
208  void setSvgDocument( const QByteArray & );
+
209 #endif
+
210 
+
211  void drawSymbol( QPainter *, const QRectF & ) const;
+
212  void drawSymbol( QPainter *, const QPointF & ) const;
+
213  void drawSymbols( QPainter *, const QPolygonF & ) const;
+
214  void drawSymbols( QPainter *,
+
215  const QPointF *, int numPoints ) const;
+
216 
+
217  virtual QRect boundingRect() const;
+
218  void invalidateCache();
+
219 
+
220 protected:
+
221  virtual void renderSymbols( QPainter *,
+
222  const QPointF *, int numPoints ) const;
+
223 
+
224 private:
+
225  // Disabled copy constructor and operator=
+
226  QwtSymbol( const QwtSymbol & );
+
227  QwtSymbol &operator=( const QwtSymbol & );
+
228 
+
229  class PrivateData;
+
230  PrivateData *d_data;
+
231 };
+
232 
+ +
240  QPainter *painter, const QPointF &pos ) const
+
241 {
+
242  drawSymbols( painter, &pos, 1 );
+
243 }
+
244 
+ +
253  QPainter *painter, const QPolygonF &points ) const
+
254 {
+
255  drawSymbols( painter, points.data(), points.size() );
+
256 }
+
257 
+
258 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__system__clock_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__system__clock_8h_source.html new file mode 100644 index 0000000000..c129609438 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__system__clock_8h_source.html @@ -0,0 +1,125 @@ + + + + + + +Qwt User's Guide: qwt_system_clock.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_system_clock.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_SYSTEM_CLOCK_H
+
11 #define QWT_SYSTEM_CLOCK_H
+
12 
+
13 #include "qwt_global.h"
+
14 
+
30 class QWT_EXPORT QwtSystemClock
+
31 {
+
32 public:
+ +
34  virtual ~QwtSystemClock();
+
35 
+
36  bool isNull() const;
+
37 
+
38  void start();
+
39  double restart();
+
40  double elapsed() const;
+
41 
+
42 private:
+
43  class PrivateData;
+
44  PrivateData *d_data;
+
45 };
+
46 
+
47 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__text_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__text_8h_source.html new file mode 100644 index 0000000000..37c7e37e85 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__text_8h_source.html @@ -0,0 +1,235 @@ + + + + + + +Qwt User's Guide: qwt_text.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_text.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2003 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_TEXT_H
+
11 #define QWT_TEXT_H
+
12 
+
13 #include "qwt_global.h"
+
14 #include <qstring.h>
+
15 #include <qsize.h>
+
16 #include <qfont.h>
+
17 #include <qmetatype.h>
+
18 
+
19 class QColor;
+
20 class QPen;
+
21 class QBrush;
+
22 class QRectF;
+
23 class QPainter;
+
24 class QwtTextEngine;
+
25 
+
51 class QWT_EXPORT QwtText
+
52 {
+
53 public:
+
54 
+ +
65  {
+
72  AutoText = 0,
+
73 
+ +
76 
+ +
79 
+ +
89 
+ +
95 
+
100  OtherFormat = 100
+
101  };
+
102 
+ +
110  {
+
112  PaintUsingTextFont = 0x01,
+
113 
+
115  PaintUsingTextColor = 0x02,
+
116 
+
118  PaintBackground = 0x04
+
119  };
+
120 
+
122  typedef QFlags<PaintAttribute> PaintAttributes;
+
123 
+ +
129  {
+
136  MinimumLayout = 0x01
+
137  };
+
138 
+
140  typedef QFlags<LayoutAttribute> LayoutAttributes;
+
141 
+
142  QwtText( const QString & = QString::null,
+
143  TextFormat textFormat = AutoText );
+
144  QwtText( const QwtText & );
+
145  ~QwtText();
+
146 
+
147  QwtText &operator=( const QwtText & );
+
148 
+
149  bool operator==( const QwtText & ) const;
+
150  bool operator!=( const QwtText & ) const;
+
151 
+
152  void setText( const QString &,
+
153  QwtText::TextFormat textFormat = AutoText );
+
154  QString text() const;
+
155 
+
156  bool isNull() const;
+
157  bool isEmpty() const;
+
158 
+
159  void setFont( const QFont & );
+
160  QFont font() const;
+
161 
+
162  QFont usedFont( const QFont & ) const;
+
163 
+
164  void setRenderFlags( int flags );
+
165  int renderFlags() const;
+
166 
+
167  void setColor( const QColor & );
+
168  QColor color() const;
+
169 
+
170  QColor usedColor( const QColor & ) const;
+
171 
+
172  void setBorderRadius( double );
+
173  double borderRadius() const;
+
174 
+
175  void setBorderPen( const QPen & );
+
176  QPen borderPen() const;
+
177 
+
178  void setBackgroundBrush( const QBrush & );
+
179  QBrush backgroundBrush() const;
+
180 
+
181  void setPaintAttribute( PaintAttribute, bool on = true );
+
182  bool testPaintAttribute( PaintAttribute ) const;
+
183 
+
184  void setLayoutAttribute( LayoutAttribute, bool on = true );
+
185  bool testLayoutAttribute( LayoutAttribute ) const;
+
186 
+
187  double heightForWidth( double width, const QFont & = QFont() ) const;
+
188  QSizeF textSize( const QFont & = QFont() ) const;
+
189 
+
190  void draw( QPainter *painter, const QRectF &rect ) const;
+
191 
+
192  static const QwtTextEngine *textEngine(
+
193  const QString &text, QwtText::TextFormat = AutoText );
+
194 
+
195  static const QwtTextEngine *textEngine( QwtText::TextFormat );
+
196  static void setTextEngine( QwtText::TextFormat, QwtTextEngine * );
+
197 
+
198 private:
+
199  class PrivateData;
+
200  PrivateData *d_data;
+
201 
+
202  class LayoutCache;
+
203  LayoutCache *d_layoutCache;
+
204 };
+
205 
+
207 inline bool QwtText::isNull() const
+
208 {
+
209  return text().isNull();
+
210 }
+
211 
+
213 inline bool QwtText::isEmpty() const
+
214 {
+
215  return text().isEmpty();
+
216 }
+
217 
+
218 Q_DECLARE_OPERATORS_FOR_FLAGS( QwtText::PaintAttributes )
+
219 Q_DECLARE_OPERATORS_FOR_FLAGS( QwtText::LayoutAttributes )
+
220 
+
221 Q_DECLARE_METATYPE( QwtText )
+
222 
+
223 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__text__engine_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__text__engine_8h_source.html new file mode 100644 index 0000000000..dff17e555f --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__text__engine_8h_source.html @@ -0,0 +1,191 @@ + + + + + + +Qwt User's Guide: qwt_text_engine.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_text_engine.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2003 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_TEXT_ENGINE_H
+
11 #define QWT_TEXT_ENGINE_H 1
+
12 
+
13 #include "qwt_global.h"
+
14 #include <qsize.h>
+
15 
+
16 class QFont;
+
17 class QRectF;
+
18 class QString;
+
19 class QPainter;
+
20 
+
35 class QWT_EXPORT QwtTextEngine
+
36 {
+
37 public:
+
38  virtual ~QwtTextEngine();
+
39 
+
50  virtual double heightForWidth( const QFont &font, int flags,
+
51  const QString &text, double width ) const = 0;
+
52 
+
62  virtual QSizeF textSize( const QFont &font, int flags,
+
63  const QString &text ) const = 0;
+
64 
+
71  virtual bool mightRender( const QString &text ) const = 0;
+
72 
+
88  virtual void textMargins( const QFont &font, const QString &text,
+
89  double &left, double &right, double &top, double &bottom ) const = 0;
+
90 
+
99  virtual void draw( QPainter *painter, const QRectF &rect,
+
100  int flags, const QString &text ) const = 0;
+
101 
+
102 protected:
+
103  QwtTextEngine();
+
104 };
+
105 
+
106 
+
113 class QWT_EXPORT QwtPlainTextEngine: public QwtTextEngine
+
114 {
+
115 public:
+ +
117  virtual ~QwtPlainTextEngine();
+
118 
+
119  virtual double heightForWidth( const QFont &font, int flags,
+
120  const QString &text, double width ) const;
+
121 
+
122  virtual QSizeF textSize( const QFont &font, int flags,
+
123  const QString &text ) const;
+
124 
+
125  virtual void draw( QPainter *painter, const QRectF &rect,
+
126  int flags, const QString &text ) const;
+
127 
+
128  virtual bool mightRender( const QString & ) const;
+
129 
+
130  virtual void textMargins( const QFont &, const QString &,
+
131  double &left, double &right, double &top, double &bottom ) const;
+
132 
+
133 private:
+
134  class PrivateData;
+
135  PrivateData *d_data;
+
136 };
+
137 
+
138 
+
139 #ifndef QT_NO_RICHTEXT
+
140 
+
147 class QWT_EXPORT QwtRichTextEngine: public QwtTextEngine
+
148 {
+
149 public:
+ +
151 
+
152  virtual double heightForWidth( const QFont &font, int flags,
+
153  const QString &text, double width ) const;
+
154 
+
155  virtual QSizeF textSize( const QFont &font, int flags,
+
156  const QString &text ) const;
+
157 
+
158  virtual void draw( QPainter *painter, const QRectF &rect,
+
159  int flags, const QString &text ) const;
+
160 
+
161  virtual bool mightRender( const QString & ) const;
+
162 
+
163  virtual void textMargins( const QFont &, const QString &,
+
164  double &left, double &right, double &top, double &bottom ) const;
+
165 
+
166 private:
+
167  QString taggedText( const QString &, int flags ) const;
+
168 };
+
169 
+
170 #endif // !QT_NO_RICHTEXT
+
171 
+
172 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__text__label_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__text__label_8h_source.html new file mode 100644 index 0000000000..fe3ddad88c --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__text__label_8h_source.html @@ -0,0 +1,166 @@ + + + + + + +Qwt User's Guide: qwt_text_label.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_text_label.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_TEXT_LABEL_H
+
11 #define QWT_TEXT_LABEL_H
+
12 
+
13 #include "qwt_global.h"
+
14 #include "qwt_text.h"
+
15 #include <qframe.h>
+
16 
+
17 class QString;
+
18 class QPaintEvent;
+
19 class QPainter;
+
20 
+
25 class QWT_EXPORT QwtTextLabel : public QFrame
+
26 {
+
27  Q_OBJECT
+
28 
+
29  Q_PROPERTY( int indent READ indent WRITE setIndent )
+
30  Q_PROPERTY( int margin READ margin WRITE setMargin )
+
31  Q_PROPERTY( QString plainText READ plainText WRITE setPlainText )
+
32 
+
33 public:
+
34  explicit QwtTextLabel( QWidget *parent = NULL );
+
35  explicit QwtTextLabel( const QwtText &, QWidget *parent = NULL );
+
36  virtual ~QwtTextLabel();
+
37 
+
38  void setPlainText( const QString & );
+
39  QString plainText() const;
+
40 
+
41 public Q_SLOTS:
+
42  void setText( const QString &,
+ +
44  virtual void setText( const QwtText & );
+
45 
+
46  void clear();
+
47 
+
48 public:
+
49  const QwtText &text() const;
+
50 
+
51  int indent() const;
+
52  void setIndent( int );
+
53 
+
54  int margin() const;
+
55  void setMargin( int );
+
56 
+
57  virtual QSize sizeHint() const;
+
58  virtual QSize minimumSizeHint() const;
+
59  virtual int heightForWidth( int ) const;
+
60 
+
61  QRect textRect() const;
+
62 
+
63  virtual void drawText( QPainter *, const QRectF & );
+
64 
+
65 protected:
+
66  virtual void paintEvent( QPaintEvent *e );
+
67  virtual void drawContents( QPainter * );
+
68 
+
69 private:
+
70  void init();
+
71  int defaultIndent() const;
+
72 
+
73  class PrivateData;
+
74  PrivateData *d_data;
+
75 };
+
76 
+
77 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__thermo_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__thermo_8h_source.html new file mode 100644 index 0000000000..b31cd116dd --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__thermo_8h_source.html @@ -0,0 +1,229 @@ + + + + + + +Qwt User's Guide: qwt_thermo.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_thermo.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_THERMO_H
+
11 #define QWT_THERMO_H
+
12 
+
13 #include "qwt_global.h"
+
14 #include "qwt_abstract_scale.h"
+
15 #include "qwt_interval.h"
+
16 
+
17 class QwtScaleDraw;
+
18 class QwtColorMap;
+
19 
+
46 class QWT_EXPORT QwtThermo: public QwtAbstractScale
+
47 {
+
48  Q_OBJECT
+
49 
+
50  Q_ENUMS( ScalePosition )
+
51  Q_ENUMS( OriginMode )
+
52 
+
53  Q_PROPERTY( Qt::Orientation orientation
+
54  READ orientation WRITE setOrientation )
+
55  Q_PROPERTY( ScalePosition scalePosition
+
56  READ scalePosition WRITE setScalePosition )
+
57  Q_PROPERTY( OriginMode originMode READ originMode WRITE setOriginMode )
+
58 
+
59  Q_PROPERTY( bool alarmEnabled READ alarmEnabled WRITE setAlarmEnabled )
+
60  Q_PROPERTY( double alarmLevel READ alarmLevel WRITE setAlarmLevel )
+
61  Q_PROPERTY( double origin READ origin WRITE setOrigin )
+
62  Q_PROPERTY( int spacing READ spacing WRITE setSpacing )
+
63  Q_PROPERTY( int borderWidth READ borderWidth WRITE setBorderWidth )
+
64  Q_PROPERTY( int pipeWidth READ pipeWidth WRITE setPipeWidth )
+
65  Q_PROPERTY( double value READ value WRITE setValue )
+
66 
+
67 public:
+
68 
+ +
74  {
+ +
77 
+ +
80 
+
82  TrailingScale
+
83  };
+
84 
+ +
92  {
+ +
95 
+ +
98 
+
100  OriginCustom
+
101  };
+
102 
+
103  explicit QwtThermo( QWidget *parent = NULL );
+
104  virtual ~QwtThermo();
+
105 
+
106  void setOrientation( Qt::Orientation );
+
107  Qt::Orientation orientation() const;
+
108 
+
109  void setScalePosition( ScalePosition );
+
110  ScalePosition scalePosition() const;
+
111 
+
112  void setSpacing( int );
+
113  int spacing() const;
+
114 
+
115  void setBorderWidth( int w );
+
116  int borderWidth() const;
+
117 
+
118  void setOriginMode( OriginMode );
+
119  OriginMode originMode() const;
+
120 
+
121  void setOrigin( double );
+
122  double origin() const;
+
123 
+
124  void setFillBrush( const QBrush &b );
+
125  QBrush fillBrush() const;
+
126 
+
127  void setAlarmBrush( const QBrush &b );
+
128  QBrush alarmBrush() const;
+
129 
+
130  void setAlarmLevel( double v );
+
131  double alarmLevel() const;
+
132 
+
133  void setAlarmEnabled( bool tf );
+
134  bool alarmEnabled() const;
+
135 
+
136  void setColorMap( QwtColorMap * );
+
137  QwtColorMap *colorMap();
+
138  const QwtColorMap *colorMap() const;
+
139 
+
140  void setPipeWidth( int w );
+
141  int pipeWidth() const;
+
142 
+
143  void setRangeFlags( QwtInterval::BorderFlags );
+
144  QwtInterval::BorderFlags rangeFlags() const;
+
145 
+
146  double value() const;
+
147 
+
148  virtual QSize sizeHint() const;
+
149  virtual QSize minimumSizeHint() const;
+
150 
+
151  void setScaleDraw( QwtScaleDraw * );
+
152  const QwtScaleDraw *scaleDraw() const;
+
153 
+
154 public Q_SLOTS:
+
155  virtual void setValue( double val );
+
156 
+
157 protected:
+
158  virtual void drawLiquid( QPainter *, const QRect & ) const;
+
159  virtual void scaleChange();
+
160 
+
161  virtual void paintEvent( QPaintEvent * );
+
162  virtual void resizeEvent( QResizeEvent * );
+
163  virtual void changeEvent( QEvent * );
+
164 
+
165  QwtScaleDraw *scaleDraw();
+
166 
+
167  QRect pipeRect() const;
+
168  QRect fillRect( const QRect & ) const;
+
169  QRect alarmRect( const QRect & ) const;
+
170 
+
171 private:
+
172  void layoutThermo( bool );
+
173 
+
174  class PrivateData;
+
175  PrivateData *d_data;
+
176 };
+
177 
+
178 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__transform_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__transform_8h_source.html new file mode 100644 index 0000000000..9ea57aec7b --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__transform_8h_source.html @@ -0,0 +1,166 @@ + + + + + + +Qwt User's Guide: qwt_transform.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_transform.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_TRANSFORM_H
+
11 #define QWT_TRANSFORM_H
+
12 
+
13 #include "qwt_global.h"
+
14 
+
35 class QWT_EXPORT QwtTransform
+
36 {
+
37 public:
+
38  QwtTransform();
+
39  virtual ~QwtTransform();
+
40 
+
45  virtual double bounded( double value ) const;
+
46 
+
55  virtual double transform( double value ) const = 0;
+
56 
+
65  virtual double invTransform( double value ) const = 0;
+
66 
+
68  virtual QwtTransform *copy() const = 0;
+
69 };
+
70 
+
77 class QWT_EXPORT QwtNullTransform: public QwtTransform
+
78 {
+
79 public:
+ +
81  virtual ~QwtNullTransform();
+
82 
+
83  virtual double transform( double value ) const;
+
84  virtual double invTransform( double value ) const;
+
85 
+
86  virtual QwtTransform *copy() const;
+
87 };
+
97 class QWT_EXPORT QwtLogTransform: public QwtTransform
+
98 {
+
99 public:
+
100  QwtLogTransform();
+
101  virtual ~QwtLogTransform();
+
102 
+
103  virtual double transform( double value ) const;
+
104  virtual double invTransform( double value ) const;
+
105 
+
106  virtual double bounded( double value ) const;
+
107 
+
108  virtual QwtTransform *copy() const;
+
109 
+
110  QT_STATIC_CONST double LogMin;
+
111  QT_STATIC_CONST double LogMax;
+
112 };
+
113 
+
122 class QWT_EXPORT QwtPowerTransform: public QwtTransform
+
123 {
+
124 public:
+
125  QwtPowerTransform( double exponent );
+
126  virtual ~QwtPowerTransform();
+
127 
+
128  virtual double transform( double value ) const;
+
129  virtual double invTransform( double value ) const;
+
130 
+
131  virtual QwtTransform *copy() const;
+
132 
+
133 private:
+
134  const double d_exponent;
+
135 };
+
136 
+
137 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__wheel_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__wheel_8h_source.html new file mode 100644 index 0000000000..c83c88037d --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__wheel_8h_source.html @@ -0,0 +1,238 @@ + + + + + + +Qwt User's Guide: qwt_wheel.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_wheel.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_WHEEL_H
+
11 #define QWT_WHEEL_H
+
12 
+
13 #include "qwt_global.h"
+
14 #include <qwidget.h>
+
15 
+
27 class QWT_EXPORT QwtWheel: public QWidget
+
28 {
+
29  Q_OBJECT
+
30 
+
31  Q_PROPERTY( Qt::Orientation orientation
+
32  READ orientation WRITE setOrientation )
+
33 
+
34  Q_PROPERTY( double value READ value WRITE setValue )
+
35  Q_PROPERTY( double minimum READ minimum WRITE setMinimum )
+
36  Q_PROPERTY( double maximum READ maximum WRITE setMaximum )
+
37 
+
38  Q_PROPERTY( double singleStep READ singleStep WRITE setSingleStep )
+
39  Q_PROPERTY( int pageStepCount READ pageStepCount WRITE setPageStepCount )
+
40  Q_PROPERTY( bool stepAlignment READ stepAlignment WRITE setStepAlignment )
+
41 
+
42  Q_PROPERTY( bool tracking READ isTracking WRITE setTracking )
+
43  Q_PROPERTY( bool wrapping READ wrapping WRITE setWrapping )
+
44  Q_PROPERTY( bool inverted READ isInverted WRITE setInverted )
+
45 
+
46  Q_PROPERTY( double mass READ mass WRITE setMass )
+
47  Q_PROPERTY( int updateInterval READ updateInterval WRITE setUpdateInterval )
+
48 
+
49  Q_PROPERTY( double totalAngle READ totalAngle WRITE setTotalAngle )
+
50  Q_PROPERTY( double viewAngle READ viewAngle WRITE setViewAngle )
+
51  Q_PROPERTY( int tickCount READ tickCount WRITE setTickCount )
+
52  Q_PROPERTY( int wheelWidth READ wheelWidth WRITE setWheelWidth )
+
53  Q_PROPERTY( int borderWidth READ borderWidth WRITE setBorderWidth )
+
54  Q_PROPERTY( int wheelBorderWidth READ wheelBorderWidth WRITE setWheelBorderWidth )
+
55 
+
56 public:
+
57  explicit QwtWheel( QWidget *parent = NULL );
+
58  virtual ~QwtWheel();
+
59 
+
60  double value() const;
+
61 
+
62  void setOrientation( Qt::Orientation );
+
63  Qt::Orientation orientation() const;
+
64 
+
65  double totalAngle() const;
+
66  double viewAngle() const;
+
67 
+
68  void setTickCount( int );
+
69  int tickCount() const;
+
70 
+
71  void setWheelWidth( int );
+
72  int wheelWidth() const;
+
73 
+
74  void setWheelBorderWidth( int );
+
75  int wheelBorderWidth() const;
+
76 
+
77  void setBorderWidth( int );
+
78  int borderWidth() const;
+
79 
+
80  void setInverted( bool tf );
+
81  bool isInverted() const;
+
82 
+
83  void setWrapping( bool tf );
+
84  bool wrapping() const;
+
85 
+
86  void setSingleStep( double );
+
87  double singleStep() const;
+
88 
+
89  void setPageStepCount( int );
+
90  int pageStepCount() const;
+
91 
+
92  void setStepAlignment( bool on );
+
93  bool stepAlignment() const;
+
94 
+
95  void setRange( double vmin, double vmax );
+
96 
+
97  void setMinimum( double min );
+
98  double minimum() const;
+
99 
+
100  void setMaximum( double max );
+
101  double maximum() const;
+
102 
+
103  void setUpdateInterval( int );
+
104  int updateInterval() const;
+
105 
+
106  void setTracking( bool enable );
+
107  bool isTracking() const;
+
108 
+
109  double mass() const;
+
110 
+
111 public Q_SLOTS:
+
112  void setValue( double );
+
113  void setTotalAngle ( double );
+
114  void setViewAngle( double );
+
115  void setMass( double );
+
116 
+
117 Q_SIGNALS:
+
118 
+
128  void valueChanged( double value );
+
129 
+
134  void wheelPressed();
+
135 
+
139  void wheelReleased();
+
140 
+
147  void wheelMoved( double value );
+
148 
+
149 protected:
+
150  virtual void paintEvent( QPaintEvent * );
+
151  virtual void mousePressEvent( QMouseEvent * );
+
152  virtual void mouseReleaseEvent( QMouseEvent * );
+
153  virtual void mouseMoveEvent( QMouseEvent * );
+
154  virtual void keyPressEvent( QKeyEvent * );
+
155  virtual void wheelEvent( QWheelEvent * );
+
156  virtual void timerEvent( QTimerEvent * );
+
157 
+
158  void stopFlying();
+
159 
+
160  QRect wheelRect() const;
+
161 
+
162  virtual QSize sizeHint() const;
+
163  virtual QSize minimumSizeHint() const;
+
164 
+
165  virtual void drawTicks( QPainter *, const QRectF & );
+
166  virtual void drawWheelBackground( QPainter *, const QRectF & );
+
167 
+
168  virtual double valueAt( const QPoint & ) const;
+
169 
+
170 private:
+
171  double alignedValue( double ) const;
+
172  double boundedValue( double ) const;
+
173 
+
174  class PrivateData;
+
175  PrivateData *d_data;
+
176 };
+
177 
+
178 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwt__widget__overlay_8h_source.html b/ThirdParty/Qwt/doc/html/qwt__widget__overlay_8h_source.html new file mode 100644 index 0000000000..2846a62230 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwt__widget__overlay_8h_source.html @@ -0,0 +1,163 @@ + + + + + + +Qwt User's Guide: qwt_widget_overlay.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ + +
+
+
+
qwt_widget_overlay.h
+
+
+
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+
2  * Qwt Widget Library
+
3  * Copyright (C) 1997 Josef Wilgen
+
4  * Copyright (C) 2002 Uwe Rathmann
+
5  *
+
6  * This library is free software; you can redistribute it and/or
+
7  * modify it under the terms of the Qwt License, Version 1.0
+
8  *****************************************************************************/
+
9 
+
10 #ifndef QWT_WIDGET_OVERLAY_H
+
11 #define QWT_WIDGET_OVERLAY_H
+
12 
+
13 #include "qwt_global.h"
+
14 #include <qwidget.h>
+
15 #include <qregion.h>
+
16 
+
17 class QPainter;
+
18 
+
40 class QWT_EXPORT QwtWidgetOverlay: public QWidget
+
41 {
+
42 public:
+
60  enum MaskMode
+
61  {
+ +
64 
+ +
73 
+
84  AlphaMask
+
85  };
+
86 
+ +
103  {
+ +
106 
+ +
109 
+
111  DrawOverlay
+
112  };
+
113 
+
114  QwtWidgetOverlay( QWidget* );
+
115  virtual ~QwtWidgetOverlay();
+
116 
+
117  void setMaskMode( MaskMode );
+
118  MaskMode maskMode() const;
+
119 
+
120  void setRenderMode( RenderMode );
+
121  RenderMode renderMode() const;
+
122 
+
123  void updateOverlay();
+
124 
+
125  virtual bool eventFilter( QObject *, QEvent *);
+
126 
+
127 protected:
+
128  virtual void paintEvent( QPaintEvent* event );
+
129  virtual void resizeEvent( QResizeEvent* event );
+
130 
+
131  virtual QRegion maskHint() const;
+
132 
+
137  virtual void drawOverlay( QPainter *painter ) const = 0;
+
138 
+
139 private:
+
140  void updateMask();
+
141  void draw( QPainter * ) const;
+
142 
+
143 private:
+
144  class PrivateData;
+
145  PrivateData *d_data;
+
146 };
+
147 
+
148 #endif
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwtchangelog.html b/ThirdParty/Qwt/doc/html/qwtchangelog.html new file mode 100644 index 0000000000..7000703111 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwtchangelog.html @@ -0,0 +1,351 @@ + + + + + + +Qwt User's Guide: What's new in Qwt 6.1 + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ +
+
+
+
What's new in Qwt 6.1
+
+
+ +

+New plot items

+ +
    +
  • QwtPlotMultiBarChart
    + Chart of grouped bars - stacked or aligned side by side. See "examples/barchart"
  • +
+
    +
  • QwtPlotTradingCurve
    + Candlestick or OHLC charts typically used to describe price movements over time. See "examples/stockchart"
  • +
+
    +
  • QwtPlotShapeItem
    + A plot item to display rectangles, circles, polygons and all other type of shapes ( built from intersections or unifications ), that can be expressed by a QPainterPath. See "examples/itemeditor"
  • +
+ + +
    +
  • QwtPlotTextLabel
    + In opposite to a QwtPlotMarker the text is not aligned to a plot coordinate but according to the geometry of the canvas ( f.e top/centered for a title ). See "playground/curvetracker".
  • +
+

+Scales beyond linear and logarithmic transformations

+

QwtScaleTransformation has been replaced by QwtTransform and its derived classes:

+ +

Individual transformations ( f.e. different scaling for special sections ) can be implemented by overloading QwtTransform ( see playground/scaleengine ).

+

QwtLinearScaleEngine and QwtLogScaleEngine are not limited to base 10 anymore.

+

+Datetime scales

+

A set of a new classes for displaying datetime values:

+
    +
  • QwtDate
    + A collection of methods to convert between QDateTime and doubles
  • +
+
    +
  • QwtDateScaleEngine
    + A scale engine that aligns and finds ticks in terms of datetime units.
  • +
+ +

Scales for Qt::UTC and Qt::LocalTime are supported.

+

+Redesign of the dial and meter widgets

+

Many parts of the class design of the dial and meter widgets were left over from the 90s ( Qwt 0.2, Qt 1.1 ).

+

The derivation tree is simpler and more logical:

+ +

QwtDoubleRange has been removed.

+

All classes use the terminology known from QAbstractSlider - as far as possible. The extended system for scales is completely supported.

+

+Basic support for an OpenGL plot canvas

+

QwtPlotGLCanvas offers the option to draw plot items using an OpenGL paint engine ( QPaintEngine::OpenGL/OpenGL2 ), This is not what could be implemented with native OpenGL, but it offers hardware acceleration in environments, where the raster paint engine is the only option. ( f.e Qt4/Windows, or Qt5 on all platforms ).

+

QwtPlotGLCanvas is in an experimental state and is not recommended for average use cases.

+

+A new system for plot legends

+

QwtLegend has been decoupled from QwtPlot and can be replaced by application specific implementations. Plot items and the legend exchange the information using QwtLegendData.

+

QwtPlotLegendItem is a new plot item that displays a legend on the plot canvas.

+

The following examples demonstrate how to use the new system:

+
    +
  • examples/legends
    + shows how to use the new legend system
  • +
  • examples/stockchart
    + implementats a QTreeView with checkable items as legend
  • +
+

+Off-screen paint device for vector graphics

+

QwtGraphic can be copied like QImage or QPixmap but is scalable like QSvgGenerator. It is implemented as a record/replay paint device like QPicture.

+

+QwtWidgetOverlay

+

QwtWidgetOverlay is a base class for implementing widget overlays - primarily used for use cases like graphical editors or running cursors for the plot canvas.

+

The following examples show how to use overlays:

+
    +
  • examples/itemeditor
  • +
  • examples/curvetracker
  • +
+

QwtPicker ( -> QwtPlotPicker, QwtPlotZoomer ) internally uses QwtWidgetOverlay now, making it easier to implement individual rubber bands.

+

+QwtSymbol

+

New symbol types have been introduced:

+ +

QwtSymbol autodetect the most performant paint strategy for a paint device what is in most situations using a QPixmap cache.

+

QwtSymbol::setPinPoint() allows to align the symbol individually, f.e to the position of the peak of an arrow.

+

+QwtPlotCurve

+

Some optimizations that got lost with introducing the floating point based render code with Qwt 6.0 have been reenabled. Other specific optimizations have been added.

+

New paint attributes:

+ +

QwtPlotCurve::CacheSymbols has been removed, as caching is implemented in QwtSymbol now.

+

QwtPlotCurve::drawLines(), QwtPlotCurve::drawDots(), QwtPlotCurve::drawSteps() and QwtPlotCurve::drawSticks() are virtual now.

+

+QwtPlot

+

A footer similar to a title has been added.

+

QwtPlot::ExternalLegend is obsolete with the new system for legends. The signals QwtPlot::legendClicked(), QwtPlot::legendChecked() have been removed. Applications need to connect to QwtLegend::clicked() and QwtLegend::checked().

+

To support using an OpenGL canvas QwtPlot::setCanvas has been added. This has 2 important implications for the application code:

+
    +
  • QwtPlot::canvas() returns QWidget and needs to be casted, when using methods of QwtPlotCanvas.
  • +
  • QwtPlotCanvas can be created and assigned in application code, what makes it possible to derive and overload methods.
  • +
+

The initialization of a plot canvas with Qwt 6.1 will probably look like this:

+
QwtPlotCanvas* canvas = new QwtPlotCanvas();
+
canvas->setXY( ... );
+
...
+
+
plot->setCanvas( canvas );
+

To have a consistent API QwtPlot::setPlotLayout() has been added,

+

+Other

+

+QwtScaleDiv

+

The following methods have been added:

+ +

The following methods have been removed:

+
    +
  • QwtScaleDiv::isValid(), QwtScaleDiv::invalidate()
    + The valid state was left over from early Qwt versions indicating a state of the autoscaler.
  • +
+

+QwtScaleEngine

+

The following methods have been added:

+ +

+QwtPlotLayout

+

The following flags have been added:

+ +

+QwtPlotCanvas

+

Rounded borders ( like with style sheets ) can configured using QwtPlotCanvas::setBorderRadius();

+

+Other changes

+ + +
    +
  • QwtSystemClock For Qt >= 4.9 QwtSystemClock uses QElapsedTimer internally. As it doesn't support a similar feature, QwtSystemClock::precision() has been removed.
  • +
+
    +
  • QwtPlotAbstractSeriesItem
    + QwtPlotAbstractSeriesItem has been split into QwtPlotSeriesItem and QwtPlotAbstractSeriesStore.
  • +
+
    +
  • QwtText
    + A metatype declaration has been added, so that QwtText can be used with QVariant.
  • +
+ +
    +
  • QPen Qt5/Qt4 incompatibility The default pen width for Qt5 is 1, what makes it a non cosmetic. To hide this nasty incompatibility several setPen() methods have been added the build pens with a width 0. See QPen::isCosmetic(),
  • +
+
    +
  • qwtUpperSampleIndex()
    + A binary search algorithm for sorted samples
  • +
+ + + +
    +
  • ...
  • +
+

+Summary of the new classes

+ +
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwtinstall.html b/ThirdParty/Qwt/doc/html/qwtinstall.html new file mode 100644 index 0000000000..6b56a7b370 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwtinstall.html @@ -0,0 +1,283 @@ + + + + + + +Qwt User's Guide: Installing Qwt + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ +
+
+
+
Installing Qwt
+
+
+ +

+Download

+

Stable Qwt releases are available from the Qwt project page.

+

Qwt-6.1.0 consists of 4 files:

+
    +
  • qwt-6.1.0.zip
    + Zip file with the Qwt sources and the html documentation for Windows
  • +
+
    +
  • qwt-6.1.0.tar.bz2
    + Compressed tar file with the Qwt sources and the html documentation for UNIX systems ( Linux, Mac, ... )
  • +
+
    +
  • qwt-6.1.0.pdf
    + Qwt documentation as PDF document.
  • +
+
    +
  • qwt-6.1.0.qch
    + Qwt documentation as Qt Compressed Help document, that can be loaded into the Qt Assistant or Creator. In the Qt Creator context sensitive help will be available like for Qt classes.
  • +
+

Precompiled Qwt Designer plugins, that are compatible with some binary packages of the Qt Creator:

+
    +
  • qwtdesigner-6.1.0-*.zip
  • +
+

+Installing Qwt

+

Beside headers, libraries and the html version of the class documentation a proper Qwt installation contains a Designer plugin and a Qwt features file for building applications using Qwt.

+

All files will be copied to an installation directory, that is configurable by editing qwtconfig.pri. Its default settings is:

+
    +
  • Windows
    + C:\Qwt-6.1.0
  • +
+
    +
  • Unix like systems
    + /usr/local/qwt-6.1.0
  • +
+

For the rest of the document this install path will be written as ${QWT_ROOT} and needs to be replaced by the real path in all commands below.

+

It is not unlikely, to have more than one installation of Qwt on the same system. F.e for using the Qwt Designer plugin in the Qt Creator a version of Qwt is necessary with the same Qt and compiler combination, that had been used for building the Qt Creator ( see "Help->About Qt Creator ..." ).

+

Installing Qwt is done in 3 steps, that are quite common on UNIX systems.

+
    +
  1. Configuration
    + In the configuration step all parameters are set to control how to build and install Qwt
  2. +
  3. Build
    + In the build step binaries are built from the source files.
  4. +
  5. Installation
    + The installation copies and rearranges all files that are necessary to build Qwt applications to a target directory.
  6. +
+

The installation doesn't modify the system beside copying files to a directory in a proper way. After removing build and installation directories the system is in the same state as it was before.

+

+Configuration

+

Configuring Qwt has to be done by editing the Project files used for building:

+
    +
  • qwtbuild.pri
    + qwtbuild.pri contains settings for how to build Qwt. All settings of this file are only for building Qwt itself and doesn't have an impact on how an application using Qwt is built. Usually its default settings doesn't need to be modified.
  • +
+
    +
  • qwtconfig.pri
    + qwtconfig.pri defines what modules of Qwt will be built and where to install them. qwtconfig.pri gets installed together with the Qwt features file qwt.prf and all its settings are known to project files for building Qwt applications.
  • +
+

In qwtconfig.pri the meaning of each option is explained in detail - it's worth reading it before running into problems later.

+

+Build and installation

+

The Qt Creator is a graphical frontend for calling qmake/make and - technically - it could be used for building and installing Qwt. But as this way requires a lot more understanding of details the following step by step instructions are for the easier way using the command line.

+

+Unix-like systems

+

The first step before creating the Makefile is to check that the correct version of qmake is used. F.e. on older Linux distribution you often find a Qt3 qmake and in the path.

+

The default setting of qmake is to generate a makefile that builds Qwt for the same environment where the version of qmake has been built for. So creating a makefile usually means something like:

+
cd qwt-6.1.0
+
/usr/local/Qt-5.0.1/bin/qmake qwt.pro
+

The generated Makefile includes all paths related to the chosen Qt version and the next step is:

+
make
+

( On multicore systems you can speed up building the Qwt libraries with running several jobs simultaneously: f.e. "make -j4" on a dual core. )

+

Finally you have to install everything below the directories you have specified in qwtconfig.pri. Usually this is one of the system directories ( /usr/local, /opt, ... ) where you don't have write permission and then the installation needs to be done as root:

+
sudo make install
+

( On systems where sudo is not supported you can do the same with: su -c "make install" )

+

+Windows

+

Qt packages offer a command line interface, that can be found in the Qt application menu: f.e "All Programs -> Qt -> Command Prompt". It is not mandatory to use it, but probably the easiest way as it offers an environment, where everything is initialized for a version of Qt ( f.e qmake is in the PATH ).

+

Creating a makefile usually means something like:

+
cd qwt-6.1.0
+
qmake qwt.pro
+

The generated makefile includes all paths related to the chosen Qt version.

+

+MinGW

+

For MinGW builds the name of the make tool is "mingw32-make"

+
mingw32-make
+

( On multicore systems you can speed up building the Qwt libraries with running several jobs simultaneously: "mingw32-make -j" )

+

Finally you have to install everything below the directories you have specified in qwtconfig.pri.

+
mingw32-make install
+

+MSVC

+

For MSVC builds the name of the make tool is "nmake". Alternatively it is possible to use "jom" ( http://qt-project.org/wiki/jom ), that is usually included in a Qt Creator package.

+
nmake
+

Finally you have to install everything below the directories you have specified in qwtconfig.pri.

+
nmake install
+

+Qwt and the Qt tool chain

+

+Designer plugin

+

The Designer plugin and the corresponding Qwt library ( if the plugin has not been built self containing ) have to be compatible with Qt version of the application loading it ( usually the Qt Creator ) - what is often a different version of the Qt libraries you want to build your application with. F.e on Windows the Qt Creator is usually built with a MSVC compiler - even if included in a MinGW package !

+

To help Qt Designer/Creator with locating the Qwt Designer plugin you have to set the environment variable QT_PLUGIN_PATH, modify qt.conf - or install the plugin to one of the application default paths.

+

The Qt documentation explains all options in detail:

+ +

F.e. on a Linux system you could add the following lines to .bashrc:

+
QT_PLUGIN_PATH="${QWT_ROOT}/plugins:$QT_PLUGIN_PATH"
+
export QT_PLUGIN_PATH
+

When the plugin has not been built including the Qwt library ( see QwtDesignerSelfContained in qwtconfig.pri ) the Qt Designer/Creator also needs to locate the Qwt libraries. On Unix systems the path to the installed library is compiled into the plugin ( see rpath, ldd ), but on Windows the Qt Creator needs to be configured ( ( Running a Qwt application ) in the same way as for any application using Qwt.

+

In case of problems the diagnostics of Qt Creator and Designer are very limited ( usually none ), but setting the environment variable QT_DEBUG_PLUGINS might help. In the Qt Creator it is possible to check which plugins were loaded successfully and for certain problems it also lists those that were recognized but failed ( Tools > Form Editor > About Qt Designer Plugins ).

+

+Online Help

+

The Qwt class documentation can be loaded into the Qt Creator:

+
    +
  • open the settings dialog from the Tools->Options menu
  • +
  • raise the tab "Help->Documentation".
  • +
  • press the Add button and select qwt-6.1.0.qch.
  • +
+

Now the context sensitive help ( F1 ) works for Qwt classes.

+

For browsing the documentation in the Qt Assistant:

+
    +
  • open the settings dialog from the Edit->Preferences menu
  • +
  • raise the tab Documentation.
  • +
  • press the Add button and select qwt-6.1.0.qch.
  • +
+

+Building a Qwt application

+

All flags and settings that are necessary to compile and link an application using Qwt can be found in the file ${QWT_ROOT}/features/qwt.prf.

+

When using qmake it can included from the application project file in 2 different ways:

+
    +
  • Adding Qwt as qmake feature
    +
    + When using the qmake feature mechanism you can bind a special version of qmake to a special installation of Qwt without having to add this dependency to the application project. How to add Qwt as feature is documented in the qmake docs.

    +

    After adding Qwt as a feature f.e on Linux as a persistent property ....

    +
    qmake -set QMAKEFEATURES ${QWT_ROOT}/features
    +

    .. the following line can be added to the application project file:

    +
    CONFIG += qwt
    +
  • +
+
    +
  • Including qwt.prf in the application project file
    +
    + Instead of using qwt.prf as qmake feature it can be included from the application project file:
    +
    +
    include ( ${QWT_ROOT}/features/qwt.prf )
    +

    + The advantage of using a direct include is, that all settings of qwt.prf are known to the application project file ( qmake features are included after the application project file has been parsed ) and it can be implemented depending on - f.e. settings made in qwtconfig.pri.
  • +
+

On Unix platforms it is possible to link a runtime path into the executable, so that the location of the Qwt libraries can be found without having to configure a runtime environment:

+ +

+Running a Qwt application

+

When using Qwt as shared library ( DLL ) the dynamic linker has to find it according to the rules of the operating system.

+

+Windows

+

The only reasonable way to configure the runtime environment - without having to copy the Qwt libraries around - is to modify the PATH variable. F.e. this could be done by adding the following line to some batch file:

+
set PATH=%PATH%;${QWT_ROOT}\lib
+

+GNU/Linux

+

Read the documentation about:

+
    +
  • ldconfig
  • +
  • /etc/ld.so.conf
  • +
  • LD_LIBRARY_PATH
  • +
+

Using the ldd command a configuration can be tested.

+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/qwtlicense.html b/ThirdParty/Qwt/doc/html/qwtlicense.html new file mode 100644 index 0000000000..b798594d69 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/qwtlicense.html @@ -0,0 +1,632 @@ + + + + + + +Qwt User's Guide: Qwt License, Version 1.0 + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ +
+
+
+
Qwt License, Version 1.0
+
+
+
Qwt License
+
Version 1.0, January 1, 2003
+
+
The Qwt library and included programs are provided under the terms
+
of the GNU LESSER GENERAL PUBLIC LICENSE (LGPL) with the following
+
exceptions:
+
+
1. Widgets that are subclassed from Qwt widgets do not
+
constitute a derivative work.
+
+
2. Static linking of applications and widgets to the
+
Qwt library does not constitute a derivative work
+
and does not require the author to provide source
+
code for the application or widget, use the shared
+
Qwt libraries, or link their applications or
+
widgets against a user-supplied version of Qwt.
+
+
If you link the application or widget to a modified
+
version of Qwt, then the changes to Qwt must be
+
provided under the terms of the LGPL in sections
+
1, 2, and 4.
+
+
3. You do not have to provide a copy of the Qwt license
+
with programs that are linked to the Qwt library, nor
+
do you have to identify the Qwt license in your
+
program or documentation as required by section 6
+
of the LGPL.
+
+
+
However, programs must still identify their use of Qwt.
+
The following example statement can be included in user
+
documentation to satisfy this requirement:
+
+
[program/widget] is based in part on the work of
+
the Qwt project (http://qwt.sf.net).
+
+
----------------------------------------------------------------------
+
+
+
GNU LESSER GENERAL PUBLIC LICENSE
+
Version 2.1, February 1999
+
+
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
Everyone is permitted to copy and distribute verbatim copies
+
of this license document, but changing it is not allowed.
+
+
[This is the first released version of the Lesser GPL. It also counts
+
as the successor of the GNU Library Public License, version 2, hence
+
the version number 2.1.]
+
+
Preamble
+
+
The licenses for most software are designed to take away your
+
freedom to share and change it. By contrast, the GNU General Public
+
Licenses are intended to guarantee your freedom to share and change
+
free software--to make sure the software is free for all its users.
+
+
This license, the Lesser General Public License, applies to some
+
specially designated software packages--typically libraries--of the
+
Free Software Foundation and other authors who decide to use it. You
+
can use it too, but we suggest you first think carefully about whether
+
this license or the ordinary General Public License is the better
+
strategy to use in any particular case, based on the explanations below.
+
+
When we speak of free software, we are referring to freedom of use,
+
not price. Our General Public Licenses are designed to make sure that
+
you have the freedom to distribute copies of free software (and charge
+
for this service if you wish); that you receive source code or can get
+
it if you want it; that you can change the software and use pieces of
+
it in new free programs; and that you are informed that you can do
+
these things.
+
+
To protect your rights, we need to make restrictions that forbid
+
distributors to deny you these rights or to ask you to surrender these
+
rights. These restrictions translate to certain responsibilities for
+
you if you distribute copies of the library or if you modify it.
+
+
For example, if you distribute copies of the library, whether gratis
+
or for a fee, you must give the recipients all the rights that we gave
+
you. You must make sure that they, too, receive or can get the source
+
code. If you link other code with the library, you must provide
+
complete object files to the recipients, so that they can relink them
+
with the library after making changes to the library and recompiling
+
it. And you must show them these terms so they know their rights.
+
+
We protect your rights with a two-step method: (1) we copyright the
+
library, and (2) we offer you this license, which gives you legal
+
permission to copy, distribute and/or modify the library.
+
+
To protect each distributor, we want to make it very clear that
+
there is no warranty for the free library. Also, if the library is
+
modified by someone else and passed on, the recipients should know
+
that what they have is not the original version, so that the original
+
author's reputation will not be affected by problems that might be
+
introduced by others.
+
+
Finally, software patents pose a constant threat to the existence of
+
any free program. We wish to make sure that a company cannot
+
effectively restrict the users of a free program by obtaining a
+
restrictive license from a patent holder. Therefore, we insist that
+
any patent license obtained for a version of the library must be
+
consistent with the full freedom of use specified in this license.
+
+
Most GNU software, including some libraries, is covered by the
+
ordinary GNU General Public License. This license, the GNU Lesser
+
General Public License, applies to certain designated libraries, and
+
is quite different from the ordinary General Public License. We use
+
this license for certain libraries in order to permit linking those
+
libraries into non-free programs.
+
+
When a program is linked with a library, whether statically or using
+
a shared library, the combination of the two is legally speaking a
+
combined work, a derivative of the original library. The ordinary
+
General Public License therefore permits such linking only if the
+
entire combination fits its criteria of freedom. The Lesser General
+
Public License permits more lax criteria for linking other code with
+
the library.
+
+
We call this license the "Lesser" General Public License because it
+
does Less to protect the user's freedom than the ordinary General
+
Public License. It also provides other free software developers Less
+
of an advantage over competing non-free programs. These disadvantages
+
are the reason we use the ordinary General Public License for many
+
libraries. However, the Lesser license provides advantages in certain
+
special circumstances.
+
+
For example, on rare occasions, there may be a special need to
+
encourage the widest possible use of a certain library, so that it becomes
+
a de-facto standard. To achieve this, non-free programs must be
+
allowed to use the library. A more frequent case is that a free
+
library does the same job as widely used non-free libraries. In this
+
case, there is little to gain by limiting the free library to free
+
software only, so we use the Lesser General Public License.
+
+
In other cases, permission to use a particular library in non-free
+
programs enables a greater number of people to use a large body of
+
free software. For example, permission to use the GNU C Library in
+
non-free programs enables many more people to use the whole GNU
+
operating system, as well as its variant, the GNU/Linux operating
+
system.
+
+
Although the Lesser General Public License is Less protective of the
+
users' freedom, it does ensure that the user of a program that is
+
linked with the Library has the freedom and the wherewithal to run
+
that program using a modified version of the Library.
+
+
The precise terms and conditions for copying, distribution and
+
modification follow. Pay close attention to the difference between a
+
"work based on the library" and a "work that uses the library". The
+
former contains code derived from the library, whereas the latter must
+
be combined with the library in order to run.
+
+
GNU LESSER GENERAL PUBLIC LICENSE
+
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+
0. This License Agreement applies to any software library or other
+
program which contains a notice placed by the copyright holder or
+
other authorized party saying it may be distributed under the terms of
+
this Lesser General Public License (also called "this License").
+
Each licensee is addressed as "you".
+
+
A "library" means a collection of software functions and/or data
+
prepared so as to be conveniently linked with application programs
+
(which use some of those functions and data) to form executables.
+
+
The "Library", below, refers to any such software library or work
+
which has been distributed under these terms. A "work based on the
+
Library" means either the Library or any derivative work under
+
copyright law: that is to say, a work containing the Library or a
+
portion of it, either verbatim or with modifications and/or translated
+
straightforwardly into another language. (Hereinafter, translation is
+
included without limitation in the term "modification".)
+
+
"Source code" for a work means the preferred form of the work for
+
making modifications to it. For a library, complete source code means
+
all the source code for all modules it contains, plus any associated
+
interface definition files, plus the scripts used to control compilation
+
and installation of the library.
+
+
Activities other than copying, distribution and modification are not
+
covered by this License; they are outside its scope. The act of
+
running a program using the Library is not restricted, and output from
+
such a program is covered only if its contents constitute a work based
+
on the Library (independent of the use of the Library in a tool for
+
writing it). Whether that is true depends on what the Library does
+
and what the program that uses the Library does.
+
+
1. You may copy and distribute verbatim copies of the Library's
+
complete source code as you receive it, in any medium, provided that
+
you conspicuously and appropriately publish on each copy an
+
appropriate copyright notice and disclaimer of warranty; keep intact
+
all the notices that refer to this License and to the absence of any
+
warranty; and distribute a copy of this License along with the
+
Library.
+
+
You may charge a fee for the physical act of transferring a copy,
+
and you may at your option offer warranty protection in exchange for a
+
fee.
+
+
2. You may modify your copy or copies of the Library or any portion
+
of it, thus forming a work based on the Library, and copy and
+
distribute such modifications or work under the terms of Section 1
+
above, provided that you also meet all of these conditions:
+
+
a) The modified work must itself be a software library.
+
+
b) You must cause the files modified to carry prominent notices
+
stating that you changed the files and the date of any change.
+
+
c) You must cause the whole of the work to be licensed at no
+
charge to all third parties under the terms of this License.
+
+
d) If a facility in the modified Library refers to a function or a
+
table of data to be supplied by an application program that uses
+
the facility, other than as an argument passed when the facility
+
is invoked, then you must make a good faith effort to ensure that,
+
in the event an application does not supply such function or
+
table, the facility still operates, and performs whatever part of
+
its purpose remains meaningful.
+
+
(For example, a function in a library to compute square roots has
+
a purpose that is entirely well-defined independent of the
+
application. Therefore, Subsection 2d requires that any
+
application-supplied function or table used by this function must
+
be optional: if the application does not supply it, the square
+
root function must still compute square roots.)
+
+
These requirements apply to the modified work as a whole. If
+
identifiable sections of that work are not derived from the Library,
+
and can be reasonably considered independent and separate works in
+
themselves, then this License, and its terms, do not apply to those
+
sections when you distribute them as separate works. But when you
+
distribute the same sections as part of a whole which is a work based
+
on the Library, the distribution of the whole must be on the terms of
+
this License, whose permissions for other licensees extend to the
+
entire whole, and thus to each and every part regardless of who wrote
+
it.
+
+
Thus, it is not the intent of this section to claim rights or contest
+
your rights to work written entirely by you; rather, the intent is to
+
exercise the right to control the distribution of derivative or
+
collective works based on the Library.
+
+
In addition, mere aggregation of another work not based on the Library
+
with the Library (or with a work based on the Library) on a volume of
+
a storage or distribution medium does not bring the other work under
+
the scope of this License.
+
+
3. You may opt to apply the terms of the ordinary GNU General Public
+
License instead of this License to a given copy of the Library. To do
+
this, you must alter all the notices that refer to this License, so
+
that they refer to the ordinary GNU General Public License, version 2,
+
instead of to this License. (If a newer version than version 2 of the
+
ordinary GNU General Public License has appeared, then you can specify
+
that version instead if you wish.) Do not make any other change in
+
these notices.
+
+
Once this change is made in a given copy, it is irreversible for
+
that copy, so the ordinary GNU General Public License applies to all
+
subsequent copies and derivative works made from that copy.
+
+
This option is useful when you wish to copy part of the code of
+
the Library into a program that is not a library.
+
+
4. You may copy and distribute the Library (or a portion or
+
derivative of it, under Section 2) in object code or executable form
+
under the terms of Sections 1 and 2 above provided that you accompany
+
it with the complete corresponding machine-readable source code, which
+
must be distributed under the terms of Sections 1 and 2 above on a
+
medium customarily used for software interchange.
+
+
If distribution of object code is made by offering access to copy
+
from a designated place, then offering equivalent access to copy the
+
source code from the same place satisfies the requirement to
+
distribute the source code, even though third parties are not
+
compelled to copy the source along with the object code.
+
+
5. A program that contains no derivative of any portion of the
+
Library, but is designed to work with the Library by being compiled or
+
linked with it, is called a "work that uses the Library". Such a
+
work, in isolation, is not a derivative work of the Library, and
+
therefore falls outside the scope of this License.
+
+
However, linking a "work that uses the Library" with the Library
+
creates an executable that is a derivative of the Library (because it
+
contains portions of the Library), rather than a "work that uses the
+
library". The executable is therefore covered by this License.
+
Section 6 states terms for distribution of such executables.
+
+
When a "work that uses the Library" uses material from a header file
+
that is part of the Library, the object code for the work may be a
+
derivative work of the Library even though the source code is not.
+
Whether this is true is especially significant if the work can be
+
linked without the Library, or if the work is itself a library. The
+
threshold for this to be true is not precisely defined by law.
+
+
If such an object file uses only numerical parameters, data
+
structure layouts and accessors, and small macros and small inline
+
functions (ten lines or less in length), then the use of the object
+
file is unrestricted, regardless of whether it is legally a derivative
+
work. (Executables containing this object code plus portions of the
+
Library will still fall under Section 6.)
+
+
Otherwise, if the work is a derivative of the Library, you may
+
distribute the object code for the work under the terms of Section 6.
+
Any executables containing that work also fall under Section 6,
+
whether or not they are linked directly with the Library itself.
+
+
6. As an exception to the Sections above, you may also combine or
+
link a "work that uses the Library" with the Library to produce a
+
work containing portions of the Library, and distribute that work
+
under terms of your choice, provided that the terms permit
+
modification of the work for the customer's own use and reverse
+
engineering for debugging such modifications.
+
+
You must give prominent notice with each copy of the work that the
+
Library is used in it and that the Library and its use are covered by
+
this License. You must supply a copy of this License. If the work
+
during execution displays copyright notices, you must include the
+
copyright notice for the Library among them, as well as a reference
+
directing the user to the copy of this License. Also, you must do one
+
of these things:
+
+
a) Accompany the work with the complete corresponding
+
machine-readable source code for the Library including whatever
+
changes were used in the work (which must be distributed under
+
Sections 1 and 2 above); and, if the work is an executable linked
+
with the Library, with the complete machine-readable "work that
+
uses the Library", as object code and/or source code, so that the
+
user can modify the Library and then relink to produce a modified
+
executable containing the modified Library. (It is understood
+
that the user who changes the contents of definitions files in the
+
Library will not necessarily be able to recompile the application
+
to use the modified definitions.)
+
+
b) Use a suitable shared library mechanism for linking with the
+
Library. A suitable mechanism is one that (1) uses at run time a
+
copy of the library already present on the user's computer system,
+
rather than copying library functions into the executable, and (2)
+
will operate properly with a modified version of the library, if
+
the user installs one, as long as the modified version is
+
interface-compatible with the version that the work was made with.
+
+
c) Accompany the work with a written offer, valid for at
+
least three years, to give the same user the materials
+
specified in Subsection 6a, above, for a charge no more
+
than the cost of performing this distribution.
+
+
d) If distribution of the work is made by offering access to copy
+
from a designated place, offer equivalent access to copy the above
+
specified materials from the same place.
+
+
e) Verify that the user has already received a copy of these
+
materials or that you have already sent this user a copy.
+
+
For an executable, the required form of the "work that uses the
+
Library" must include any data and utility programs needed for
+
reproducing the executable from it. However, as a special exception,
+
the materials to be distributed need not include anything that is
+
normally distributed (in either source or binary form) with the major
+
components (compiler, kernel, and so on) of the operating system on
+
which the executable runs, unless that component itself accompanies
+
the executable.
+
+
It may happen that this requirement contradicts the license
+
restrictions of other proprietary libraries that do not normally
+
accompany the operating system. Such a contradiction means you cannot
+
use both them and the Library together in an executable that you
+
distribute.
+
+
7. You may place library facilities that are a work based on the
+
Library side-by-side in a single library together with other library
+
facilities not covered by this License, and distribute such a combined
+
library, provided that the separate distribution of the work based on
+
the Library and of the other library facilities is otherwise
+
permitted, and provided that you do these two things:
+
+
a) Accompany the combined library with a copy of the same work
+
based on the Library, uncombined with any other library
+
facilities. This must be distributed under the terms of the
+
Sections above.
+
+
b) Give prominent notice with the combined library of the fact
+
that part of it is a work based on the Library, and explaining
+
where to find the accompanying uncombined form of the same work.
+
+
8. You may not copy, modify, sublicense, link with, or distribute
+
the Library except as expressly provided under this License. Any
+
attempt otherwise to copy, modify, sublicense, link with, or
+
distribute the Library is void, and will automatically terminate your
+
rights under this License. However, parties who have received copies,
+
or rights, from you under this License will not have their licenses
+
terminated so long as such parties remain in full compliance.
+
+
9. You are not required to accept this License, since you have not
+
signed it. However, nothing else grants you permission to modify or
+
distribute the Library or its derivative works. These actions are
+
prohibited by law if you do not accept this License. Therefore, by
+
modifying or distributing the Library (or any work based on the
+
Library), you indicate your acceptance of this License to do so, and
+
all its terms and conditions for copying, distributing or modifying
+
the Library or works based on it.
+
+
10. Each time you redistribute the Library (or any work based on the
+
Library), the recipient automatically receives a license from the
+
original licensor to copy, distribute, link with or modify the Library
+
subject to these terms and conditions. You may not impose any further
+
restrictions on the recipients' exercise of the rights granted herein.
+
You are not responsible for enforcing compliance by third parties with
+
this License.
+
+
11. If, as a consequence of a court judgment or allegation of patent
+
infringement or for any other reason (not limited to patent issues),
+
conditions are imposed on you (whether by court order, agreement or
+
otherwise) that contradict the conditions of this License, they do not
+
excuse you from the conditions of this License. If you cannot
+
distribute so as to satisfy simultaneously your obligations under this
+
License and any other pertinent obligations, then as a consequence you
+
may not distribute the Library at all. For example, if a patent
+
license would not permit royalty-free redistribution of the Library by
+
all those who receive copies directly or indirectly through you, then
+
the only way you could satisfy both it and this License would be to
+
refrain entirely from distribution of the Library.
+
+
If any portion of this section is held invalid or unenforceable under any
+
particular circumstance, the balance of the section is intended to apply,
+
and the section as a whole is intended to apply in other circumstances.
+
+
It is not the purpose of this section to induce you to infringe any
+
patents or other property right claims or to contest validity of any
+
such claims; this section has the sole purpose of protecting the
+
integrity of the free software distribution system which is
+
implemented by public license practices. Many people have made
+
generous contributions to the wide range of software distributed
+
through that system in reliance on consistent application of that
+
system; it is up to the author/donor to decide if he or she is willing
+
to distribute software through any other system and a licensee cannot
+
impose that choice.
+
+
This section is intended to make thoroughly clear what is believed to
+
be a consequence of the rest of this License.
+
+
12. If the distribution and/or use of the Library is restricted in
+
certain countries either by patents or by copyrighted interfaces, the
+
original copyright holder who places the Library under this License may add
+
an explicit geographical distribution limitation excluding those countries,
+
so that distribution is permitted only in or among countries not thus
+
excluded. In such case, this License incorporates the limitation as if
+
written in the body of this License.
+
+
13. The Free Software Foundation may publish revised and/or new
+
versions of the Lesser General Public License from time to time.
+
Such new versions will be similar in spirit to the present version,
+
but may differ in detail to address new problems or concerns.
+
+
Each version is given a distinguishing version number. If the Library
+
specifies a version number of this License which applies to it and
+
"any later version", you have the option of following the terms and
+
conditions either of that version or of any later version published by
+
the Free Software Foundation. If the Library does not specify a
+
license version number, you may choose any version ever published by
+
the Free Software Foundation.
+
+
14. If you wish to incorporate parts of the Library into other free
+
programs whose distribution conditions are incompatible with these,
+
write to the author to ask for permission. For software which is
+
copyrighted by the Free Software Foundation, write to the Free
+
Software Foundation; we sometimes make exceptions for this. Our
+
decision will be guided by the two goals of preserving the free status
+
of all derivatives of our free software and of promoting the sharing
+
and reuse of software generally.
+
+
NO WARRANTY
+
+
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+
DAMAGES.
+
+
END OF TERMS AND CONDITIONS
+
+
How to Apply These Terms to Your New Libraries
+
+
If you develop a new library, and you want it to be of the greatest
+
possible use to the public, we recommend making it free software that
+
everyone can redistribute and change. You can do so by permitting
+
redistribution under these terms (or, alternatively, under the terms of the
+
ordinary General Public License).
+
+
To apply these terms, attach the following notices to the library. It is
+
safest to attach them to the start of each source file to most effectively
+
convey the exclusion of warranty; and each file should have at least the
+
"copyright" line and a pointer to where the full notice is found.
+
+
<one line to give the library's name and a brief idea of what it does.>
+
Copyright (C) <year> <name of author>
+
+
This library is free software; you can redistribute it and/or
+
modify it under the terms of the GNU Lesser General Public
+
License as published by the Free Software Foundation; either
+
version 2.1 of the License, or (at your option) any later version.
+
+
This library is distributed in the hope that it will be useful,
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+
Lesser General Public License for more details.
+
+
You should have received a copy of the GNU Lesser General Public
+
License along with this library; if not, write to the Free Software
+
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
Also add information on how to contact you by electronic and paper mail.
+
+
You should also get your employer (if you work as a programmer) or your
+
school, if any, to sign a "copyright disclaimer" for the library, if
+
necessary. Here is a sample; alter the names:
+
+
Yoyodyne, Inc., hereby disclaims all copyright interest in the
+
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+
<signature of Ty Coon>, 1 April 1990
+
Ty Coon, President of Vice
+
+
That's all there is to it!
+
+
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/radio.png b/ThirdParty/Qwt/doc/html/radio.png new file mode 100644 index 0000000000..dff1e14d96 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/radio.png differ diff --git a/ThirdParty/Qwt/doc/html/scatterplot.png b/ThirdParty/Qwt/doc/html/scatterplot.png new file mode 100644 index 0000000000..fd157f0b24 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/scatterplot.png differ diff --git a/ThirdParty/Qwt/doc/html/scatterscreenshots.html b/ThirdParty/Qwt/doc/html/scatterscreenshots.html new file mode 100644 index 0000000000..4ac4847d11 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/scatterscreenshots.html @@ -0,0 +1,92 @@ + + + + + + +Qwt User's Guide: Scatter Plot + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ +
+
+
+
Scatter Plot
+
+
+
+scatterplot.png +
+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/search/all_61.html b/ThirdParty/Qwt/doc/html/search/all_61.html new file mode 100644 index 0000000000..f85089b559 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/all_61.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/all_61.js b/ThirdParty/Qwt/doc/html/search/all_61.js new file mode 100644 index 0000000000..1fb7ca78a0 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/all_61.js @@ -0,0 +1,62 @@ +var searchData= +[ + ['abstractscaledraw',['abstractScaleDraw',['../class_qwt_abstract_scale.html#ab3c5f30892792e5ca3d84f4409ef6216',1,'QwtAbstractScale::abstractScaleDraw() const '],['../class_qwt_abstract_scale.html#aa61afdff037ef745a6dad686537cdb96',1,'QwtAbstractScale::abstractScaleDraw()']]], + ['accept',['accept',['../class_qwt_picker.html#a2c93d65c27fadf2f2522e81f04358604',1,'QwtPicker::accept()'],['../class_qwt_plot_zoomer.html#afe2a439f5085602e97c403d451561dd5',1,'QwtPlotZoomer::accept()']]], + ['activate',['activate',['../class_qwt_plot_layout.html#af940812bf4a9d94dac534734168d4ac8',1,'QwtPlotLayout']]], + ['activated',['activated',['../class_qwt_picker.html#a89a2c67a355d6b9bc54348e2f25fe139',1,'QwtPicker']]], + ['activeonly',['ActiveOnly',['../class_qwt_picker.html#a01be4d404ffc3a7b238b0d0aaeb66b93a973f3446b39ea41b5dc3b31593ecb64a',1,'QwtPicker']]], + ['addcolorstop',['addColorStop',['../class_qwt_linear_color_map.html#aa7162a034e882e752c15051439bb2c99',1,'QwtLinearColorMap']]], + ['added',['added',['../class_qwt_set_sample.html#ab9c619f327e1bf3feca7f96d0ba44c24',1,'QwtSetSample']]], + ['additem',['addItem',['../class_qwt_dyn_grid_layout.html#a3ac3ace65c84e16fba7fe83cd795eea1',1,'QwtDynGridLayout']]], + ['adjustedpoints',['adjustedPoints',['../class_qwt_picker.html#ad09e8d2241f23b05377155c2f86010f5',1,'QwtPicker']]], + ['alarmbrush',['alarmBrush',['../class_qwt_thermo.html#a103f3f7f66d71931e7af95605c03028b',1,'QwtThermo']]], + ['alarmenabled',['alarmEnabled',['../class_qwt_thermo.html#a98d686ce15953eecd774e6c1dbb75286',1,'QwtThermo']]], + ['alarmlevel',['alarmLevel',['../class_qwt_thermo.html#a5ed8270840b7e23c539fdd67c3b6b846',1,'QwtThermo']]], + ['alarmrect',['alarmRect',['../class_qwt_thermo.html#acec691cc665beed149c6559e666d55e6',1,'QwtThermo']]], + ['align',['align',['../class_qwt_linear_scale_engine.html#a433918756a04fb25f29ed53f5d20bfd4',1,'QwtLinearScaleEngine::align()'],['../class_qwt_log_scale_engine.html#a9f0b3b6855c6fd4eda0855078b480206',1,'QwtLogScaleEngine::align()']]], + ['aligncanvastoscale',['alignCanvasToScale',['../class_qwt_plot_layout.html#a12544e8300be44585bb2b4963e909e77',1,'QwtPlotLayout']]], + ['aligndate',['alignDate',['../class_qwt_date_scale_engine.html#aba0a765afc53e8be743a8c4fc5bcca21',1,'QwtDateScaleEngine']]], + ['alignlegend',['alignLegend',['../class_qwt_plot_layout.html#a38c8c706367c67e36664bf901fd14f36',1,'QwtPlotLayout']]], + ['alignment',['alignment',['../class_qwt_knob.html#a8434f82e42972a470b59ef9296880c28',1,'QwtKnob::alignment()'],['../class_qwt_plot_legend_item.html#a33fd4ca3a52bdc4cf046103c1fc797b3',1,'QwtPlotLegendItem::alignment()'],['../class_qwt_scale_draw.html#ad0425d29e919f60021322b178661b6e5',1,'QwtScaleDraw::alignment()'],['../class_qwt_scale_widget.html#a96c6c060e258e21e609a0f99e59c5e33',1,'QwtScaleWidget::alignment()'],['../class_qwt_scale_draw.html#acd7ceeeac592ef08530788580b461c66',1,'QwtScaleDraw::Alignment()']]], + ['alignscales',['AlignScales',['../class_qwt_plot_layout.html#ad0d2d60e86a4c69ec105524041d5221daf92cc90a2b68a8788a813807d379b95a',1,'QwtPlotLayout::AlignScales()'],['../class_qwt_plot_layout.html#a7d1690e687b2bff56fdccdca39e7b326',1,'QwtPlotLayout::alignScales(Options options, QRectF &canvasRect, QRectF scaleRect[QwtPlot::axisCnt]) const ']]], + ['alpha',['alpha',['../class_qwt_plot_raster_item.html#a96b2faa0bc0fe086bff1abe72bcb2016',1,'QwtPlotRasterItem']]], + ['alphamask',['AlphaMask',['../class_qwt_widget_overlay.html#a413679fb15e072d5a404f237062b75fca263c0fea842a8d4957ded6f5e47f734e',1,'QwtWidgetOverlay']]], + ['alwaysoff',['AlwaysOff',['../class_qwt_picker.html#a01be4d404ffc3a7b238b0d0aaeb66b93a94fcf579dddb78a1c88fd4136d3a673a',1,'QwtPicker']]], + ['alwayson',['AlwaysOn',['../class_qwt_picker.html#a01be4d404ffc3a7b238b0d0aaeb66b93a07a7513aa69633c1a3b04fdbfe4674e0',1,'QwtPicker']]], + ['append',['append',['../class_qwt_picker.html#a5dd2e0ce6b2a6cc50e345ec13aef9255',1,'QwtPicker::append()'],['../class_qwt_plot_picker.html#a86a68e8ea235b9514084b729c75803ea',1,'QwtPlotPicker::append()']]], + ['appended',['appended',['../class_qwt_picker.html#ad52219271a7c8efab35ded14ac89827a',1,'QwtPicker::appended()'],['../class_qwt_plot_picker.html#a558f8fdf8645e202bd5324b766b445f7',1,'QwtPlotPicker::appended()']]], + ['applyproperties',['applyProperties',['../class_qwt_plot.html#ae7e93c7112d16cbd299cf3cbc0bf9f9f',1,'QwtPlot']]], + ['arrow',['Arrow',['../class_qwt_dial_simple_needle.html#ad28821489e04f1fd942e5bebc8a60584a27ace220f0a5c6abd061c85bbdc9a663',1,'QwtDialSimpleNeedle']]], + ['arrowsize',['arrowSize',['../class_qwt_arrow_button.html#a544fc12a1756eb2b703ab9a2903240cb',1,'QwtArrowButton']]], + ['arrowtype',['arrowType',['../class_qwt_arrow_button.html#a0a2a1b7dfff38ef00a0495fcb61d21a4',1,'QwtArrowButton']]], + ['aspectratio',['aspectRatio',['../class_qwt_plot_rescaler.html#a896b940761b437516043695d2687dd1c',1,'QwtPlotRescaler']]], + ['atomicpainter',['AtomicPainter',['../class_qwt_plot_direct_painter.html#a38f72175526a1a748d311763707cf934a95bfb017daa98b23665c1de06e8bd8e5',1,'QwtPlotDirectPainter']]], + ['attach',['attach',['../class_qwt_plot_item.html#aeb2f676533ccae3436bf578824e2165e',1,'QwtPlotItem']]], + ['attribute',['Attribute',['../class_qwt_plot_direct_painter.html#a38f72175526a1a748d311763707cf934',1,'QwtPlotDirectPainter::Attribute()'],['../class_qwt_scale_engine.html#a7548418e0896d75eec164bfa2ba3ff5f',1,'QwtScaleEngine::Attribute()']]], + ['attributes',['Attributes',['../class_qwt_plot_direct_painter.html#a26a66587377067b3bc0539274370693f',1,'QwtPlotDirectPainter::Attributes()'],['../class_qwt_scale_engine.html#a798f5f1420019d33baa799d26bca0255',1,'QwtScaleEngine::Attributes()'],['../class_qwt_scale_engine.html#a044961cfa3be3ac86d49610c3881df08',1,'QwtScaleEngine::attributes() const ']]], + ['auto',['Auto',['../class_qwt_spline_curve_fitter.html#a8c5e6858f885b5691c30092a950879a8ae19b8325da178d410cf10b04ed5a5df6',1,'QwtSplineCurveFitter']]], + ['autoadjustsamples',['AutoAdjustSamples',['../class_qwt_plot_abstract_bar_chart.html#ae1db0e1606747ef46c863c54c210e53aa6d8801b5f08318c9be2441ca4bb15a96',1,'QwtPlotAbstractBarChart']]], + ['autocache',['AutoCache',['../class_qwt_symbol.html#adda2e2c0e5234692adbc530552efd549acaa219da83872a5ea6bec535667037b5',1,'QwtSymbol']]], + ['autodelete',['autoDelete',['../class_qwt_plot_dict.html#a10dfae8b454fa4258b0372366013507a',1,'QwtPlotDict']]], + ['autorefresh',['autoRefresh',['../class_qwt_plot.html#aea78ab565d05b69b8730a4af2a11f07e',1,'QwtPlot']]], + ['autorendermode',['AutoRenderMode',['../class_qwt_widget_overlay.html#aaa8358f3b841b733d69e62aa645783d8a831530722d8dc0e42aabfbcacbb6ecc6',1,'QwtWidgetOverlay']]], + ['autoreplot',['autoReplot',['../class_qwt_plot.html#af14053ca41be0f9c6f820ed3c4379831',1,'QwtPlot']]], + ['autoscale',['AutoScale',['../class_qwt_plot_item.html#ae0fabcdd35f4818ce5bbe019b0eed062a9de83e2ad8a88796a36a11ef8b033a48',1,'QwtPlotItem::AutoScale()'],['../class_qwt_date_scale_engine.html#a6c7e5c416ff4a1d3cd5f029793a31c34',1,'QwtDateScaleEngine::autoScale()'],['../class_qwt_scale_engine.html#aa27323d6d9d5348bd253a61b45e4785b',1,'QwtScaleEngine::autoScale()'],['../class_qwt_linear_scale_engine.html#ad0f1d825e70eb7a1deb15875a8093cff',1,'QwtLinearScaleEngine::autoScale()'],['../class_qwt_log_scale_engine.html#a5020a25dde6a7d4dbf16012445c4cc81',1,'QwtLogScaleEngine::autoScale()']]], + ['autotext',['AutoText',['../class_qwt_text.html#a63e0d6a59a427a37ed0bfa71b782fd76a0645d333081ec9e3574c98f510c284a1',1,'QwtText']]], + ['axis',['Axis',['../class_qwt_plot.html#a81df699dcf9dde0752c0726b5f31e271',1,'QwtPlot']]], + ['axisautoscale',['axisAutoScale',['../class_qwt_plot.html#a112a1bc0b4f7132b10bc5b4efae45686',1,'QwtPlot']]], + ['axiscnt',['axisCnt',['../class_qwt_plot.html#a81df699dcf9dde0752c0726b5f31e271aea62036dfd48ee0f9450718592614892',1,'QwtPlot']]], + ['axisenabled',['axisEnabled',['../class_qwt_plot.html#aac5107a1ec8836b53f084a5b1bb8cc43',1,'QwtPlot']]], + ['axisfont',['axisFont',['../class_qwt_plot.html#a637e2261d7722f00b2ce2bacadca8ffa',1,'QwtPlot']]], + ['axisinterval',['axisInterval',['../class_qwt_plot.html#ab4c5ab07abc1252a325d8ba2627ab5d3',1,'QwtPlot']]], + ['axismaxmajor',['axisMaxMajor',['../class_qwt_plot.html#a250fdf9506a71857d183983823a491d4',1,'QwtPlot']]], + ['axismaxminor',['axisMaxMinor',['../class_qwt_plot.html#adbe9b0fcfaf8a5baa49a3cb4ed425b42',1,'QwtPlot']]], + ['axisscalediv',['axisScaleDiv',['../class_qwt_plot.html#a8b5b2d9bc11dd893fe6b09c94c228a81',1,'QwtPlot']]], + ['axisscaledraw',['axisScaleDraw',['../class_qwt_plot.html#a2ff0d0733c0ce8bb275cfde23bf9736c',1,'QwtPlot::axisScaleDraw(int axisId) const '],['../class_qwt_plot.html#abbb49f1730c3ea9f636c032f81e5a87e',1,'QwtPlot::axisScaleDraw(int axisId)']]], + ['axisscaleengine',['axisScaleEngine',['../class_qwt_plot.html#a619b65bb95090ab5a528e33a5014ae4f',1,'QwtPlot::axisScaleEngine(int axisId)'],['../class_qwt_plot.html#a3e29973bcd6c879056ad655de8f667d8',1,'QwtPlot::axisScaleEngine(int axisId) const ']]], + ['axisstepsize',['axisStepSize',['../class_qwt_plot.html#a6f5fa5348dec97f2531f7ec58e727bee',1,'QwtPlot']]], + ['axistitle',['axisTitle',['../class_qwt_plot.html#a7807148d386457345025571e2a8e0983',1,'QwtPlot']]], + ['axisvalid',['axisValid',['../class_qwt_plot.html#ac02c033b024a4ecbefcf1b0e93c91205',1,'QwtPlot']]], + ['axiswidget',['axisWidget',['../class_qwt_plot.html#a6b495d9b17962be6e098026441a1f7b8',1,'QwtPlot::axisWidget(int axisId) const '],['../class_qwt_plot.html#ae3386e1d38f70864c4c019c0eb6a3d9d',1,'QwtPlot::axisWidget(int axisId)']]], + ['azimuth',['azimuth',['../class_qwt_point_polar.html#afac65de2dca25b0b6a6c5fb917fff424',1,'QwtPointPolar']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/all_62.html b/ThirdParty/Qwt/doc/html/search/all_62.html new file mode 100644 index 0000000000..f25fa2c88c --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/all_62.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/all_62.js b/ThirdParty/Qwt/doc/html/search/all_62.js new file mode 100644 index 0000000000..455d3c0c66 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/all_62.js @@ -0,0 +1,42 @@ +var searchData= +[ + ['backbone',['Backbone',['../class_qwt_abstract_scale_draw.html#a26215d06a4d48adf401d0aa05d4193c5a61a6c4f4dec2b089edfb655e2b21c3a2',1,'QwtAbstractScaleDraw']]], + ['backgroundbrush',['backgroundBrush',['../class_qwt_plot_legend_item.html#a7c3ab70e6df9d2c3bad203f7c505ae0c',1,'QwtPlotLegendItem::backgroundBrush()'],['../class_qwt_text.html#a46bb4836482e4fe554f5079871343ba6',1,'QwtText::backgroundBrush()']]], + ['backgroundmode',['BackgroundMode',['../class_qwt_plot_legend_item.html#a26f5e39bb332d42f9dde96fa788960cc',1,'QwtPlotLegendItem::BackgroundMode()'],['../class_qwt_plot_legend_item.html#a550f9c49a2905e90ab7c6459105b43b2',1,'QwtPlotLegendItem::backgroundMode() const ']]], + ['backingstore',['backingStore',['../class_qwt_painter.html#ad1acc33fc6d94791852d9c07d7e1e94e',1,'QwtPainter::backingStore()'],['../class_qwt_plot_canvas.html#aa46dfe9b0d4a3a1d81ef1fca66c2093c',1,'QwtPlotCanvas::backingStore() const '],['../class_qwt_plot_canvas.html#a76066290edb594a71ee09be564563b0fa7b88a46e1414f6d904aa494c89d064f3',1,'QwtPlotCanvas::BackingStore()']]], + ['bar',['Bar',['../class_qwt_interval_symbol.html#a8fe960fd50b3ad08765ef8bb632ad77ea1e4120af73e888e2edf05798d906e934',1,'QwtIntervalSymbol::Bar()'],['../class_qwt_plot_trading_curve.html#af1ca10dd8c3f1ef662d40fc8a113b44aa151b8fa49a6da794fc18563b32f26e37',1,'QwtPlotTradingCurve::Bar()']]], + ['bartitle',['barTitle',['../class_qwt_plot_bar_chart.html#a346fd4fbd04c48f3e28dff985820aea2',1,'QwtPlotBarChart']]], + ['bartitles',['barTitles',['../class_qwt_plot_multi_bar_chart.html#ab07fa887580b77358b787e1ec52c9c3a',1,'QwtPlotMultiBarChart']]], + ['base',['base',['../class_qwt_scale_engine.html#a5bfe4467f5b311b3879253b0a4470a2c',1,'QwtScaleEngine']]], + ['baseline',['baseline',['../class_qwt_plot_abstract_bar_chart.html#a89a0209b5af6036b0d17ffdb8659121b',1,'QwtPlotAbstractBarChart::baseline()'],['../class_qwt_plot_curve.html#a93e390b172c5fa9ffd534aeb2d572c0e',1,'QwtPlotCurve::baseline()'],['../class_qwt_plot_histogram.html#a1e15762e54960e7b1de75b542e8024bd',1,'QwtPlotHistogram::baseline()']]], + ['begin',['begin',['../class_qwt_picker.html#a49cb19aea451e275c5d376235e5a1d83',1,'QwtPicker::begin()'],['../class_qwt_plot_zoomer.html#aa54bb05797c0468c0f8de4217dce24dd',1,'QwtPlotZoomer::begin()']]], + ['bilinearinterpolation',['BilinearInterpolation',['../class_qwt_matrix_raster_data.html#a3c8def5d9ae452bd82e6c4b71b480209a6f25a9f1f27cb94525ce39df487af13f',1,'QwtMatrixRasterData']]], + ['borderdistance',['borderDistance',['../class_qwt_plot_legend_item.html#abd3614864cb8a2870c5e94aaa2e09875',1,'QwtPlotLegendItem::borderDistance()'],['../class_qwt_plot_scale_item.html#a3200035a9dd88e07f154ef4289a952c2',1,'QwtPlotScaleItem::borderDistance()']]], + ['borderflag',['BorderFlag',['../class_qwt_interval.html#a3a4b4e49495108c660fc07a62af7ac54',1,'QwtInterval']]], + ['borderflags',['BorderFlags',['../class_qwt_interval.html#a678a26fcaa91cca596d9aebcbf5776c9',1,'QwtInterval::BorderFlags()'],['../class_qwt_interval.html#a885306d2a8538fe37c1446853aa18018',1,'QwtInterval::borderFlags() const ']]], + ['borderpath',['borderPath',['../class_qwt_plot_canvas.html#a924b8de928d2c1c6eea611306b3e7170',1,'QwtPlotCanvas::borderPath()'],['../class_qwt_plot_g_l_canvas.html#a09dbce4a8649eaa31910cb51147d2b41',1,'QwtPlotGLCanvas::borderPath()']]], + ['borderpen',['borderPen',['../class_qwt_plot_legend_item.html#aef9f3986e55bfd53513b7c45fad240f3',1,'QwtPlotLegendItem::borderPen()'],['../class_qwt_text.html#ae06c3ab1a6396962e4035e7ec1452db6',1,'QwtText::borderPen()']]], + ['borderradius',['borderRadius',['../class_qwt_plot_canvas.html#a76b086055480789c4410eb114789fe2e',1,'QwtPlotCanvas::borderRadius()'],['../class_qwt_plot_legend_item.html#a2dc0926a766161c962c396b63cbc2778',1,'QwtPlotLegendItem::borderRadius()'],['../class_qwt_text.html#a21b879281d4e07f5ffe6e4465c176dc1',1,'QwtText::borderRadius()']]], + ['borderwidth',['borderWidth',['../class_qwt_knob.html#a3e19de6a4762aeaf2b95266b20961574',1,'QwtKnob::borderWidth()'],['../class_qwt_slider.html#aacc125aac3a5d593a4834957de28469c',1,'QwtSlider::borderWidth()'],['../class_qwt_thermo.html#aa3e9ce551b041571bdc2688930cf553c',1,'QwtThermo::borderWidth()'],['../class_qwt_wheel.html#a2bb051e6a069283c574b7ea278bbb96f',1,'QwtWheel::borderWidth()']]], + ['bottomlegend',['BottomLegend',['../class_qwt_plot.html#a31aacb65b5c049dde8c34a0d8482661ba8b863705308d89b388732f186be15fb5',1,'QwtPlot']]], + ['bottomscale',['BottomScale',['../class_qwt_scale_draw.html#acd7ceeeac592ef08530788580b461c66a0e16389e135da75f06117d1ee3ef765f',1,'QwtScaleDraw']]], + ['bottomtotop',['BottomToTop',['../class_qwt_column_rect.html#a70bb2c6f1f8dabe3bc00793740e0908baa5f0a56f1bd041136476d4ad40ae56f0',1,'QwtColumnRect']]], + ['bounded',['bounded',['../class_qwt_scale_div.html#a9b73d97caf5ee1020d4d5f60716d4274',1,'QwtScaleDiv::bounded()'],['../class_qwt_transform.html#a2703fc5855720201f46ed9404271a527',1,'QwtTransform::bounded()'],['../class_qwt_log_transform.html#ab98c0508df005438dea8baa6c512b799',1,'QwtLogTransform::bounded()']]], + ['boundinginterval',['boundingInterval',['../class_qwt_o_h_l_c_sample.html#ae706a8617d441a416278e95f0688122b',1,'QwtOHLCSample']]], + ['boundinglabelrect',['boundingLabelRect',['../class_qwt_scale_draw.html#a364846c2b4be817c9a645bd226cdd6e7',1,'QwtScaleDraw']]], + ['boundingrect',['boundingRect',['../class_qwt_dial.html#a0d52d45d3a693e66d5799e285efdd34d',1,'QwtDial::boundingRect()'],['../class_qwt_graphic.html#a9c164c590611ddea0973db2917f65690',1,'QwtGraphic::boundingRect()'],['../class_qwt_plot_bar_chart.html#a004aec33aa7412c0d8fc23a94cf2e1e0',1,'QwtPlotBarChart::boundingRect()'],['../class_qwt_plot_histogram.html#a683686684263a384cd609c484330bb1f',1,'QwtPlotHistogram::boundingRect()'],['../class_qwt_plot_interval_curve.html#ae4b1140a52682976bb5946a772b7da7c',1,'QwtPlotIntervalCurve::boundingRect()'],['../class_qwt_plot_item.html#aec3c408e14af30b82b52c1197310eb21',1,'QwtPlotItem::boundingRect()'],['../class_qwt_plot_marker.html#a270ada9e0a68dcfd5cf0f7629af898a2',1,'QwtPlotMarker::boundingRect()'],['../class_qwt_plot_multi_bar_chart.html#a598ffecdc85925d084ac4346a675bc4b',1,'QwtPlotMultiBarChart::boundingRect()'],['../class_qwt_plot_raster_item.html#ad96073173caf80301e108a6d8b0648e9',1,'QwtPlotRasterItem::boundingRect()'],['../class_qwt_plot_series_item.html#a7a0fffd64c5416a8f18df00ab8a90ea3',1,'QwtPlotSeriesItem::boundingRect()'],['../class_qwt_plot_shape_item.html#a79d76e0b482abd8124f0226a15c1d3c0',1,'QwtPlotShapeItem::boundingRect()'],['../class_qwt_plot_svg_item.html#af358905da83fb1c67631b7fba9539daa',1,'QwtPlotSvgItem::boundingRect()'],['../class_qwt_plot_trading_curve.html#a1d0d5becf5adfce57f2083e73e32b6fb',1,'QwtPlotTradingCurve::boundingRect()'],['../class_qwt_plot_zone_item.html#a293eb96989d4678ec82ede787d0b4583',1,'QwtPlotZoneItem::boundingRect()'],['../class_qwt_point_array_data.html#a2d8b421115ba860e9d12a2266eeaef3b',1,'QwtPointArrayData::boundingRect()'],['../class_qwt_c_pointer_data.html#aecc3e98a3b2c4350212fa7b9e97110aa',1,'QwtCPointerData::boundingRect()'],['../class_qwt_synthetic_point_data.html#a89296d373856825047f48e86d7731b0a',1,'QwtSyntheticPointData::boundingRect()'],['../class_qwt_point_mapper.html#a1dd7644e312d7d05ae238759470180d4',1,'QwtPointMapper::boundingRect()'],['../class_qwt_series_data.html#aedb969ba51a27d88d26ad7f7cb1c2c7f',1,'QwtSeriesData::boundingRect()'],['../class_qwt_point_series_data.html#ad5cf93cd9f518be6b0d910982cabd96d',1,'QwtPointSeriesData::boundingRect()'],['../class_qwt_point3_d_series_data.html#a94ea1834516a2a484712723b5c9625ca',1,'QwtPoint3DSeriesData::boundingRect()'],['../class_qwt_interval_series_data.html#afd9a41faed021eddcc1a9a36d15350d2',1,'QwtIntervalSeriesData::boundingRect()'],['../class_qwt_set_series_data.html#a63aef8f3405883ab886b06cd27aabe7c',1,'QwtSetSeriesData::boundingRect()'],['../class_qwt_trading_chart_data.html#ae39ddc18e1669fb0be87ff6be92c1a96',1,'QwtTradingChartData::boundingRect()'],['../class_qwt_symbol.html#af7904c7e672fb871dd4b2eb852a745c5',1,'QwtSymbol::boundingRect()']]], + ['box',['Box',['../class_qwt_column_symbol.html#aaace508375eef3ee23ed6c47b1d65ef2ad21d1b393a2474a1caa6a9d83daa8f21',1,'QwtColumnSymbol::Box()'],['../class_qwt_interval_symbol.html#a8fe960fd50b3ad08765ef8bb632ad77eaf4f31197926c38dcc0377bb75ed5e6e1',1,'QwtIntervalSymbol::Box()']]], + ['brush',['brush',['../class_qwt_interval_symbol.html#a925cdf560cbeb857ad4c2176b552aacc',1,'QwtIntervalSymbol::brush()'],['../class_qwt_plot_curve.html#a72b678ebb8e4821c1f85351292ce5697',1,'QwtPlotCurve::brush()'],['../class_qwt_plot_histogram.html#ae72360d1812a8137a0c7ee6b6a5ebebd',1,'QwtPlotHistogram::brush()'],['../class_qwt_plot_interval_curve.html#ad4aaae77788ba7bafd87ca8ec1970901',1,'QwtPlotIntervalCurve::brush()'],['../class_qwt_plot_shape_item.html#a5ab8814c57a33fa4bf8250515e85a237',1,'QwtPlotShapeItem::brush()'],['../class_qwt_plot_zone_item.html#a1c8e23cf9d0558749126891cc0584675',1,'QwtPlotZoneItem::brush()'],['../class_qwt_symbol.html#a7260c1fa79009661cd0723e6c2b9ef87',1,'QwtSymbol::brush()']]], + ['buildinterval',['buildInterval',['../class_qwt_scale_engine.html#ac9d1a77655b633ee4f165eb5c43a4374',1,'QwtScaleEngine']]], + ['buildmajorticks',['buildMajorTicks',['../class_qwt_linear_scale_engine.html#a00844c641535d54074f235d1fe3430f5',1,'QwtLinearScaleEngine::buildMajorTicks()'],['../class_qwt_log_scale_engine.html#a7918a44fcf0e308f23a687610778bbeb',1,'QwtLogScaleEngine::buildMajorTicks()']]], + ['buildminorticks',['buildMinorTicks',['../class_qwt_linear_scale_engine.html#ae65f6964ee4bd4bfa19ebf1134eb9d69',1,'QwtLinearScaleEngine::buildMinorTicks()'],['../class_qwt_log_scale_engine.html#adf9985e35cbacb8ba48378c3781a2071',1,'QwtLogScaleEngine::buildMinorTicks()']]], + ['buildnaturalspline',['buildNaturalSpline',['../class_qwt_spline.html#a1cdf09e841dd6a721eb788914273c484',1,'QwtSpline']]], + ['buildperiodicspline',['buildPeriodicSpline',['../class_qwt_spline.html#a8184717f8c018e69fabd1e33ac68ef19',1,'QwtSpline']]], + ['buildticks',['buildTicks',['../class_qwt_linear_scale_engine.html#a7d6a7687ea03a3ce9cde3478f7f21146',1,'QwtLinearScaleEngine::buildTicks()'],['../class_qwt_log_scale_engine.html#a5ab57d233a5722d74426f4c7c5f1b9a9',1,'QwtLogScaleEngine::buildTicks()']]], + ['button',['Button',['../class_qwt_counter.html#a027cfd91946ca9a19a1d606411e0f374',1,'QwtCounter::Button()'],['../class_qwt_event_pattern_1_1_mouse_pattern.html#ade5b5bdb3bf76814f003c02ea11c5924',1,'QwtEventPattern::MousePattern::button()']]], + ['button1',['Button1',['../class_qwt_counter.html#a027cfd91946ca9a19a1d606411e0f374a1b29fe43c7d59986eb5854ddaf6f7179',1,'QwtCounter']]], + ['button2',['Button2',['../class_qwt_counter.html#a027cfd91946ca9a19a1d606411e0f374a6015e556fcb8c4d45126dee5435b478d',1,'QwtCounter']]], + ['button3',['Button3',['../class_qwt_counter.html#a027cfd91946ca9a19a1d606411e0f374a30b64d40b31283807f1a4f3d57af0e74',1,'QwtCounter']]], + ['buttoncnt',['ButtonCnt',['../class_qwt_counter.html#a027cfd91946ca9a19a1d606411e0f374aca8e93a2d129f7cc91f54f5f4da20c5f',1,'QwtCounter']]], + ['buttonreleased',['buttonReleased',['../class_qwt_counter.html#a694ed7277e137e44bccc5918b4c15ecc',1,'QwtCounter']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/all_63.html b/ThirdParty/Qwt/doc/html/search/all_63.html new file mode 100644 index 0000000000..e7f34db586 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/all_63.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/all_63.js b/ThirdParty/Qwt/doc/html/search/all_63.js new file mode 100644 index 0000000000..6a4c6b47e3 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/all_63.js @@ -0,0 +1,80 @@ +var searchData= +[ + ['cache',['Cache',['../class_qwt_symbol.html#adda2e2c0e5234692adbc530552efd549af9c909c7a68dd83785c85a0083dcf796',1,'QwtSymbol']]], + ['cachepolicy',['cachePolicy',['../class_qwt_plot_raster_item.html#ac953db5d88084f416b4dbc3ca8a323f3',1,'QwtPlotRasterItem::cachePolicy()'],['../class_qwt_symbol.html#a7ee06a50e28aacecfb7df83f63c22a41',1,'QwtSymbol::cachePolicy()'],['../class_qwt_plot_raster_item.html#a94929fc4c31c3dab75ee5adcac2d57b0',1,'QwtPlotRasterItem::CachePolicy()'],['../class_qwt_symbol.html#adda2e2c0e5234692adbc530552efd549',1,'QwtSymbol::CachePolicy()']]], + ['candlestick',['CandleStick',['../class_qwt_plot_trading_curve.html#af1ca10dd8c3f1ef662d40fc8a113b44aa647559431e0ec4404de12dfd0c324482',1,'QwtPlotTradingCurve']]], + ['canvas',['canvas',['../class_qwt_plot.html#a53f836bb4ec09c766e3d871ea4be28f7',1,'QwtPlot::canvas()'],['../class_qwt_plot.html#ad8a2c2c9739c1bc8b61b7dc191809f67',1,'QwtPlot::canvas() const '],['../class_qwt_plot_magnifier.html#a833e0c42a9ffdc92a60a1d1b0828b8ec',1,'QwtPlotMagnifier::canvas()'],['../class_qwt_plot_magnifier.html#a435c1df676fcfcc27206e2746137aadf',1,'QwtPlotMagnifier::canvas() const '],['../class_qwt_plot_panner.html#a372898a83f51e2b85aadb92f893d6235',1,'QwtPlotPanner::canvas()'],['../class_qwt_plot_panner.html#abac1d0855829801a7afa02064f023950',1,'QwtPlotPanner::canvas() const '],['../class_qwt_plot_picker.html#ad2a03a80f35826ed6256f039da2b4bf2',1,'QwtPlotPicker::canvas()'],['../class_qwt_plot_picker.html#a8cded1988abdd15b190f73ab2bb42842',1,'QwtPlotPicker::canvas() const '],['../class_qwt_plot_rescaler.html#ad4aa9bf81032b822b848774ee21142ce',1,'QwtPlotRescaler::canvas()'],['../class_qwt_plot_rescaler.html#ae324f6b86350254e1623853bf9ad9f77',1,'QwtPlotRescaler::canvas() const ']]], + ['canvasbackground',['canvasBackground',['../class_qwt_plot.html#a8e2efd0e10ae3b72773b5ab78f67375c',1,'QwtPlot']]], + ['canvasfocusindicator',['CanvasFocusIndicator',['../class_qwt_plot_canvas.html#a89b44e4c28038a674ce211fe9ac2d7bea884899cc2fa5cb416e73fe3e7aba2271',1,'QwtPlotCanvas']]], + ['canvasmap',['canvasMap',['../class_qwt_plot.html#aff5efd21f11ec91fb8f791799cb4db2f',1,'QwtPlot']]], + ['canvasmargin',['canvasMargin',['../class_qwt_plot_layout.html#aacf659495ecc45367eacf5f4b2aeca7d',1,'QwtPlotLayout']]], + ['canvasrect',['canvasRect',['../class_qwt_plot_layout.html#ad117328fb4ce4041bb2bb16a0392d416',1,'QwtPlotLayout']]], + ['canvasresizeevent',['canvasResizeEvent',['../class_qwt_plot_rescaler.html#a5490a4a1b576b1118c095cc54810e2aa',1,'QwtPlotRescaler']]], + ['ceil',['ceil',['../class_qwt_date.html#ab4d7b043971e13a97a8b5f9edb5eee02',1,'QwtDate']]], + ['ceileps',['ceilEps',['../class_qwt_scale_arithmetic.html#a86da4fc0928457d03201d8b520d7d816',1,'QwtScaleArithmetic']]], + ['center',['center',['../class_qwt_round_scale_draw.html#ae3d163159f0771bc05958faf798a1500',1,'QwtRoundScaleDraw']]], + ['changed',['changed',['../class_qwt_picker.html#ae47a68e89fdd72be75d4d2b92672319e',1,'QwtPicker']]], + ['changeevent',['changeEvent',['../class_qwt_dial.html#a7ba6373fff91cbc545d29c480bf80359',1,'QwtDial::changeEvent()'],['../class_qwt_knob.html#abccdba2f96c353ecc004adfcb19d2db9',1,'QwtKnob::changeEvent()'],['../class_qwt_slider.html#a89e8ecbeb21511a88016e31aa5c12a58',1,'QwtSlider::changeEvent()'],['../class_qwt_thermo.html#abb6858178fa0361ce9c4775944b96352',1,'QwtThermo::changeEvent()']]], + ['chartstyle',['ChartStyle',['../class_qwt_plot_multi_bar_chart.html#ac67e03008156171c2dd19de4a46eacee',1,'QwtPlotMultiBarChart']]], + ['checkable',['Checkable',['../class_qwt_legend_data.html#aaa33cc8e6aec17440df5d4c38d7545b7a250e05444c9927d83d3815d9f5593917',1,'QwtLegendData']]], + ['checked',['checked',['../class_qwt_legend.html#ae54179a767337c154beaa826c57dda87',1,'QwtLegend::checked()'],['../class_qwt_legend_label.html#a248d0836578ccf15fe56f2fee603e981',1,'QwtLegendLabel::checked()']]], + ['chunksize',['chunkSize',['../class_qwt_weeding_curve_fitter.html#a280b4984a2b2c67f9863bb27e2bb3ed3',1,'QwtWeedingCurveFitter']]], + ['clear',['clear',['../class_qwt_text_label.html#a6674cebd85cf692d154f967887547e11',1,'QwtTextLabel']]], + ['clearlegend',['clearLegend',['../class_qwt_plot_legend_item.html#ad5bf74d642b8a0ccfcc1a278442f94e9',1,'QwtPlotLegendItem']]], + ['clickable',['Clickable',['../class_qwt_legend_data.html#aaa33cc8e6aec17440df5d4c38d7545b7a39077c66db9fe2faf4d85a6f9266583f',1,'QwtLegendData']]], + ['clicked',['clicked',['../class_qwt_legend.html#a26619e20d875f1e8c666b982a897244b',1,'QwtLegend::clicked()'],['../class_qwt_legend_label.html#ae37056322967eddf53dbbd94748faa63',1,'QwtLegendLabel::clicked()']]], + ['clipcircle',['clipCircle',['../class_qwt_clipper.html#ab36605186b4a1c411fccb3b68cf1724a',1,'QwtClipper']]], + ['clippoints',['ClipPoints',['../class_qwt_plot_spectro_curve.html#af6d4c6ae392f3f521db710484a059625ab8586d2301ec1e0888f852bca84c2501',1,'QwtPlotSpectroCurve']]], + ['clippolygon',['clipPolygon',['../class_qwt_clipper.html#ab42cda85c068194ae0c60f66ecd12022',1,'QwtClipper::clipPolygon(const QRect &, const QPolygon &, bool closePolygon=false)'],['../class_qwt_clipper.html#adc4aa63cfb8b7ed97311b117f2613f0d',1,'QwtClipper::clipPolygon(const QRectF &, const QPolygon &, bool closePolygon=false)']]], + ['clippolygonf',['clipPolygonF',['../class_qwt_clipper.html#ab7f737adc53ccd730934197359de3c95',1,'QwtClipper']]], + ['clippolygons',['ClipPolygons',['../class_qwt_plot_curve.html#a96db1b854c63bfbc452c943251a11b66a26f9aa8ae434aa94b4049b9908995abf',1,'QwtPlotCurve::ClipPolygons()'],['../class_qwt_plot_interval_curve.html#a3deaf543802d69a38961f9e944bfad95aac1361651d57a0df1a079f30849e72a1',1,'QwtPlotIntervalCurve::ClipPolygons()'],['../class_qwt_plot_shape_item.html#aaa78031ce7ab1b8e713bc05da05a4631a21854077548e55943dc8f9f208960442',1,'QwtPlotShapeItem::ClipPolygons()']]], + ['clipregion',['clipRegion',['../class_qwt_plot_direct_painter.html#a62f4330f5be1386ef69ed5754aa16678',1,'QwtPlotDirectPainter']]], + ['clipsymbol',['ClipSymbol',['../class_qwt_plot_interval_curve.html#a3deaf543802d69a38961f9e944bfad95a9b164d29534731bbd3d34717baf399ca',1,'QwtPlotIntervalCurve']]], + ['clipsymbols',['ClipSymbols',['../class_qwt_plot_trading_curve.html#afc40b9bee1371ebce4a7f3853fee7968a8bcf035ef95b4c4f95fa78a3459a4c2c',1,'QwtPlotTradingCurve']]], + ['close',['close',['../class_qwt_o_h_l_c_sample.html#a7627b9a618065a82e96e651406f4fac4',1,'QwtOHLCSample']]], + ['closepolyline',['closePolyline',['../class_qwt_plot_curve.html#abada791559395b278f9dc4478dffcc6f',1,'QwtPlotCurve']]], + ['closestpoint',['closestPoint',['../class_qwt_plot_curve.html#a47620cb8ca3940f7007f8fb990d614f6',1,'QwtPlotCurve']]], + ['coefficientsa',['coefficientsA',['../class_qwt_spline.html#abbc5c1cf6016fc57050f379250da031e',1,'QwtSpline']]], + ['coefficientsb',['coefficientsB',['../class_qwt_spline.html#a1de897d6cc2d0d8dac840d15d0bb603e',1,'QwtSpline']]], + ['coefficientsc',['coefficientsC',['../class_qwt_spline.html#a27d51429a7447b18a8f05a44b3418f89',1,'QwtSpline']]], + ['color',['color',['../class_qwt_color_map.html#a35f74175e963d18e451a9fd4421ede1f',1,'QwtColorMap::color()'],['../class_qwt_alpha_color_map.html#a4a706714abbd4d82a9a2201a9ecf7aaf',1,'QwtAlphaColorMap::color()'],['../class_qwt_text.html#a8904020d2a906c4c66d8515ba47820fe',1,'QwtText::color()']]], + ['color1',['color1',['../class_qwt_linear_color_map.html#a3ab5066b01409f58e4ad0425474b1530',1,'QwtLinearColorMap']]], + ['color2',['color2',['../class_qwt_linear_color_map.html#a9fa696fff9ec599f0c305f73345ecab3',1,'QwtLinearColorMap']]], + ['colorbarinterval',['colorBarInterval',['../class_qwt_scale_widget.html#a45d81f98abea564eca1ec72dd56edaae',1,'QwtScaleWidget']]], + ['colorbarrect',['colorBarRect',['../class_qwt_scale_widget.html#a5271d10cf0e6097a243aa62beb784c02',1,'QwtScaleWidget']]], + ['colorbarwidth',['colorBarWidth',['../class_qwt_scale_widget.html#aa5877851d15888977621bfe86b945984',1,'QwtScaleWidget']]], + ['colorindex',['colorIndex',['../class_qwt_color_map.html#a762baa2edca8773ec09e0c1c5df2cf04',1,'QwtColorMap::colorIndex()'],['../class_qwt_linear_color_map.html#aa69528213eb7d484466f095c8a9a6efe',1,'QwtLinearColorMap::colorIndex()']]], + ['colormap',['colorMap',['../class_qwt_plot_spectro_curve.html#a901a8ee5d6aa7b6e41eadf8f1bdc1e03',1,'QwtPlotSpectroCurve::colorMap()'],['../class_qwt_plot_spectrogram.html#ac1f691f612643bae921cbc108f8d2b5e',1,'QwtPlotSpectrogram::colorMap()'],['../class_qwt_scale_widget.html#aacbe3acb087a109d9df21062bf5f1726',1,'QwtScaleWidget::colorMap()'],['../class_qwt_thermo.html#a8d9285fdda3f6f26fc0d9aa35b5f021e',1,'QwtThermo::colorMap()'],['../class_qwt_thermo.html#a00e16d590b76602a85ef7bf32533e945',1,'QwtThermo::colorMap() const ']]], + ['colorrange',['colorRange',['../class_qwt_plot_spectro_curve.html#aa495f44361e659e5fd83882e21e56542',1,'QwtPlotSpectroCurve']]], + ['colorstops',['colorStops',['../class_qwt_linear_color_map.html#afaafe752db9de97ec6fba163515f51dd',1,'QwtLinearColorMap']]], + ['colortable',['colorTable',['../class_qwt_color_map.html#a4ccc23356e058783071b06dee437b6d7',1,'QwtColorMap']]], + ['columnrect',['columnRect',['../class_qwt_plot_histogram.html#abbda48a6dc315904e0adb94ee4caf569',1,'QwtPlotHistogram']]], + ['columns',['Columns',['../class_qwt_plot_histogram.html#a3ba21c3aef994daf7b848ccf71b0dbc5a9cd056b6b9881b07c625756488487362',1,'QwtPlotHistogram']]], + ['columnsforwidth',['columnsForWidth',['../class_qwt_dyn_grid_layout.html#adf7cc1acc36b41086fb4815633473901',1,'QwtDynGridLayout']]], + ['command',['Command',['../class_qwt_picker_machine.html#a3a8d3d4c107ce5f8351e4cbdd38c43f7',1,'QwtPickerMachine']]], + ['commands',['commands',['../class_qwt_graphic.html#a9f188c3bbe1cf8b3b24c82c0fd222029',1,'QwtGraphic']]], + ['conrecflag',['ConrecFlag',['../class_qwt_raster_data.html#ac0053b66315fde6f0a9a69c40d7c5dcc',1,'QwtRasterData']]], + ['conrecflags',['ConrecFlags',['../class_qwt_raster_data.html#a8101f4a0c71813d49fcdc73a457c4874',1,'QwtRasterData']]], + ['contains',['contains',['../class_qwt_interval.html#a862ee5d96ed32b991a0bbeed0e836560',1,'QwtInterval::contains()'],['../class_qwt_scale_div.html#ae0c34d8ffac04ab14d1bfaf06cf2b43b',1,'QwtScaleDiv::contains()'],['../class_qwt_scale_engine.html#a36acba98650d011f784641fa4ac43f87',1,'QwtScaleEngine::contains()']]], + ['contentsmask',['contentsMask',['../class_qwt_panner.html#a665cd319422766cdf9cacb96498b0c22',1,'QwtPanner::contentsMask()'],['../class_qwt_plot_panner.html#a01af550a710be3ca051610eda7f979e3',1,'QwtPlotPanner::contentsMask()']]], + ['contentswidget',['contentsWidget',['../class_qwt_legend.html#aa52edeceb553ae703516c984f34d7ab7',1,'QwtLegend::contentsWidget()'],['../class_qwt_legend.html#acd680c0f17f4184e10a3d3136b9836f5',1,'QwtLegend::contentsWidget() const ']]], + ['contourlevels',['contourLevels',['../class_qwt_plot_spectrogram.html#a850b6b098d5859ee96e6f7cd9e05509f',1,'QwtPlotSpectrogram']]], + ['contourlines',['ContourLines',['../class_qwt_raster_data.html#adc6679160a229992f0870a2b784985f3',1,'QwtRasterData::ContourLines()'],['../class_qwt_raster_data.html#a1fa90434ddeeeeaacb80657e49af8fe1',1,'QwtRasterData::contourLines(const QRectF &rect, const QSize &raster, const QList< double > &levels, ConrecFlags) const ']]], + ['contourmode',['ContourMode',['../class_qwt_plot_spectrogram.html#a7f4904fe68b442d0f93040ea1fa1d062a64e86465a6d48ad80c4baadb144f9cf8',1,'QwtPlotSpectrogram']]], + ['contourpen',['contourPen',['../class_qwt_plot_spectrogram.html#a9c5c16fcda0422739c5393e42be5af37',1,'QwtPlotSpectrogram']]], + ['contourrastersize',['contourRasterSize',['../class_qwt_plot_spectrogram.html#aa8baf22cfbfe9a0470fd17a251f7a8da',1,'QwtPlotSpectrogram']]], + ['controlpointrect',['controlPointRect',['../class_qwt_graphic.html#a42a6f02cc28b842c5eda6eabe7847439',1,'QwtGraphic']]], + ['copy',['copy',['../class_qwt_transform.html#aae011ee4205fa4391459766d88971809',1,'QwtTransform::copy()'],['../class_qwt_null_transform.html#af1770baa6d9b7a4f86e872bc55d6f899',1,'QwtNullTransform::copy()'],['../class_qwt_log_transform.html#a16c5031b6e252462b0e611d4a54b55f5',1,'QwtLogTransform::copy()'],['../class_qwt_power_transform.html#a1c3833f1f275ac298b3986cddc67055e',1,'QwtPowerTransform::copy()']]], + ['copyalphamask',['CopyAlphaMask',['../class_qwt_widget_overlay.html#aaa8358f3b841b733d69e62aa645783d8a923e121c1d01bb72deb897a6f913aaf5',1,'QwtWidgetOverlay']]], + ['copybackingstore',['CopyBackingStore',['../class_qwt_plot_direct_painter.html#a38f72175526a1a748d311763707cf934a8b04f057d6223852a87bdd319dcf4711',1,'QwtPlotDirectPainter']]], + ['count',['count',['../class_qwt_dyn_grid_layout.html#a9a74593721ef1eba3d70275c36500ff6',1,'QwtDynGridLayout']]], + ['createwidget',['createWidget',['../class_qwt_legend.html#ac978d104d5d844cce177fac40ec56329',1,'QwtLegend']]], + ['cross',['Cross',['../class_qwt_plot_marker.html#a297efa835423bfa5a870bbc8ff1c623ba5014eec17204ed4b0cec35e7322696d2',1,'QwtPlotMarker::Cross()'],['../class_qwt_symbol.html#a62f457952470c2076962e83ef2c24d2fab75eff873d34264d84a55cb94b603fef',1,'QwtSymbol::Cross()']]], + ['crossrubberband',['CrossRubberBand',['../class_qwt_picker.html#ab36c79d8ff20aba5b778d2823c1f7894a1b90615892fec7ff6bb3352ce887b097',1,'QwtPicker']]], + ['cursor',['cursor',['../class_qwt_panner.html#a05a9ded33442da7f18c30bd06d45b55b',1,'QwtPanner']]], + ['curveattribute',['CurveAttribute',['../class_qwt_plot_curve.html#a38064f7de6f026a49db782c365f872c3',1,'QwtPlotCurve']]], + ['curveattributes',['CurveAttributes',['../class_qwt_plot_curve.html#a43f465d035a5125d582768944287c70c',1,'QwtPlotCurve']]], + ['curvefitter',['curveFitter',['../class_qwt_plot_curve.html#aaf299522e4ad972996c781aacc940d31',1,'QwtPlotCurve']]], + ['curve_20plots',['Curve Plots',['../curvescreenshots.html',1,'']]], + ['curvestyle',['CurveStyle',['../class_qwt_plot_curve.html#a15998aa80a11ba6ba80eebabaf773f70',1,'QwtPlotCurve::CurveStyle()'],['../class_qwt_plot_interval_curve.html#aaef834575b923e1b317f4a86b2d97cd2',1,'QwtPlotIntervalCurve::CurveStyle()']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/all_64.html b/ThirdParty/Qwt/doc/html/search/all_64.html new file mode 100644 index 0000000000..360601fa72 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/all_64.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/all_64.js b/ThirdParty/Qwt/doc/html/search/all_64.js new file mode 100644 index 0000000000..7868d2c387 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/all_64.js @@ -0,0 +1,114 @@ +var searchData= +[ + ['dials_2c_20compasses_2c_20knobs_2c_20wheels_2c_20sliders_2c_20thermos',['Dials, Compasses, Knobs, Wheels, Sliders, Thermos',['../controlscreenshots.html',1,'']]], + ['d_5fboundingrect',['d_boundingRect',['../class_qwt_series_data.html#a24fbbcb0baa0c728117d2e6764d00414',1,'QwtSeriesData']]], + ['d_5fsamples',['d_samples',['../class_qwt_array_series_data.html#a86ccb32fa8c9b3bb9cb92b6040b0c490',1,'QwtArraySeriesData']]], + ['data',['data',['../class_qwt_legend_label.html#a98ce3be22571bece709a828b3d18c770',1,'QwtLegendLabel::data()'],['../class_qwt_plot_spectrogram.html#a52d6090388ad9ff1117f3c4075903814',1,'QwtPlotSpectrogram::data() const '],['../class_qwt_plot_spectrogram.html#a4082962ff60af18a5212ea160f7b55ba',1,'QwtPlotSpectrogram::data()'],['../class_qwt_series_store.html#aae258d330c8d1bd2057b1f0bc13700f9',1,'QwtSeriesStore::data()'],['../class_qwt_series_store.html#afa10ec8a1ed48eb1955481bef8af6995',1,'QwtSeriesStore::data() const ']]], + ['datachanged',['dataChanged',['../class_qwt_plot_series_item.html#a8eaf7453ca8b3e8f522433149ba4c80d',1,'QwtPlotSeriesItem::dataChanged()'],['../class_qwt_abstract_series_store.html#ad95aac5e145cec2871e873c16f5f83b9',1,'QwtAbstractSeriesStore::dataChanged()']]], + ['datarect',['dataRect',['../class_qwt_abstract_series_store.html#a23d498a9d5bb10cb573db55650551a2c',1,'QwtAbstractSeriesStore::dataRect()'],['../class_qwt_series_store.html#a2acffb18573253acfb30cbedacf8c711',1,'QwtSeriesStore::dataRect()']]], + ['datasize',['dataSize',['../class_qwt_abstract_series_store.html#aa68ed8e5ce3da6b18826d8f95be86ad6',1,'QwtAbstractSeriesStore::dataSize()'],['../class_qwt_series_store.html#a1a3b9719889a0d7b85baf24b3dbf964f',1,'QwtSeriesStore::dataSize()']]], + ['dateformat',['dateFormat',['../class_qwt_date_scale_draw.html#aeb431d5113c2342b073d9faa4e65b5fb',1,'QwtDateScaleDraw']]], + ['dateformatofdate',['dateFormatOfDate',['../class_qwt_date_scale_draw.html#a00852822746e3999949b313c8cfd8550',1,'QwtDateScaleDraw']]], + ['dateofweek0',['dateOfWeek0',['../class_qwt_date.html#abb91fb441a254337d5445ad4bab1a662',1,'QwtDate']]], + ['day',['Day',['../class_qwt_date.html#ad037b999a51cae4d9ab36bf8e7859587a1d503616cab082a9c741be881cc0a813',1,'QwtDate']]], + ['decreasing',['Decreasing',['../class_qwt_plot_trading_curve.html#ab9136d2f1a4dc34dd09a0c03e809b4afacd9a36ba360db4449bf40928d1652d83',1,'QwtPlotTradingCurve']]], + ['defaultcontourpen',['defaultContourPen',['../class_qwt_plot_spectrogram.html#a0b5964a44f4c0ed0139681c6873ada73',1,'QwtPlotSpectrogram']]], + ['defaulticon',['defaultIcon',['../class_qwt_plot_item.html#af5264c9dcd9d1ec503bc1d46c10adc83',1,'QwtPlotItem']]], + ['defaultitemmode',['defaultItemMode',['../class_qwt_legend.html#a7ac3f2399fcf55dc35c1aa83abef4ac8',1,'QwtLegend']]], + ['defaultlayout',['DefaultLayout',['../class_qwt_plot_renderer.html#a111b4db55d3f620a33e75f6b398e4b4aa7aeaacf4750595de6774ad45ba170c5d',1,'QwtPlotRenderer']]], + ['defaultsize',['defaultSize',['../class_qwt_graphic.html#a588a284d40d45baa31d27e7131076d92',1,'QwtGraphic']]], + ['detach',['detach',['../class_qwt_plot_item.html#ab2bbee6dbe36a5f1d0ce853ac66716a6',1,'QwtPlotItem']]], + ['detachitems',['detachItems',['../class_qwt_plot_dict.html#acb2e402e05c693433ed7e84696fbdfc0',1,'QwtPlotDict']]], + ['diamond',['Diamond',['../class_qwt_symbol.html#a62f457952470c2076962e83ef2c24d2fa952136b2f18abfe1b4712ce9de84dbf4',1,'QwtSymbol']]], + ['dimforlength',['dimForLength',['../class_qwt_scale_widget.html#aa3c1f2f5e60ebb8f6fb42297dfe8881b',1,'QwtScaleWidget']]], + ['direction',['Direction',['../class_qwt_column_rect.html#a70bb2c6f1f8dabe3bc00793740e0908b',1,'QwtColumnRect::Direction()'],['../class_qwt_plot_trading_curve.html#ab9136d2f1a4dc34dd09a0c03e809b4af',1,'QwtPlotTradingCurve::Direction()'],['../class_qwt_column_rect.html#aa630854df28955f2ee91c94524b079d7',1,'QwtColumnRect::direction()']]], + ['discardbackground',['DiscardBackground',['../class_qwt_plot_renderer.html#a34d2aa9911e93cb7871e6ce4210e41cda8520c4587d5b11708b5b314936a07288',1,'QwtPlotRenderer']]], + ['discardcanvasbackground',['DiscardCanvasBackground',['../class_qwt_plot_renderer.html#a34d2aa9911e93cb7871e6ce4210e41cdab9bb1a51c26e57f6c2b7e650c6edab03',1,'QwtPlotRenderer']]], + ['discardcanvasframe',['DiscardCanvasFrame',['../class_qwt_plot_renderer.html#a34d2aa9911e93cb7871e6ce4210e41cda081e5228ec807e75df243a8ad31f2871',1,'QwtPlotRenderer']]], + ['discardflag',['DiscardFlag',['../class_qwt_plot_renderer.html#a34d2aa9911e93cb7871e6ce4210e41cd',1,'QwtPlotRenderer']]], + ['discardflags',['discardFlags',['../class_qwt_plot_renderer.html#ac0965a5084598e011ef1eb5c0d12347f',1,'QwtPlotRenderer::discardFlags() const '],['../class_qwt_plot_renderer.html#aa61638c08ef926c0148dd12c9f830b2d',1,'QwtPlotRenderer::DiscardFlags()']]], + ['discardfooter',['DiscardFooter',['../class_qwt_plot_renderer.html#a34d2aa9911e93cb7871e6ce4210e41cda1c61c6c040ce707dcf1cd51f92040d1e',1,'QwtPlotRenderer']]], + ['discardlegend',['DiscardLegend',['../class_qwt_plot_renderer.html#a34d2aa9911e93cb7871e6ce4210e41cdac20500aed74824fbea6c3b0d057a482a',1,'QwtPlotRenderer']]], + ['discardnone',['DiscardNone',['../class_qwt_plot_renderer.html#a34d2aa9911e93cb7871e6ce4210e41cdaf2b5ab01146a2e3f85454741465f1f16',1,'QwtPlotRenderer']]], + ['discardraster',['discardRaster',['../class_qwt_raster_data.html#a369a5f525814bf569e01f88fbd8ddb5b',1,'QwtRasterData']]], + ['discardtitle',['DiscardTitle',['../class_qwt_plot_renderer.html#a34d2aa9911e93cb7871e6ce4210e41cda2866f5a7d38cbfb34431b95c8dc952e1',1,'QwtPlotRenderer']]], + ['displaymode',['DisplayMode',['../class_qwt_picker.html#a01be4d404ffc3a7b238b0d0aaeb66b93',1,'QwtPicker::DisplayMode()'],['../class_qwt_plot_spectrogram.html#a7f4904fe68b442d0f93040ea1fa1d062',1,'QwtPlotSpectrogram::DisplayMode()']]], + ['displaymodes',['DisplayModes',['../class_qwt_plot_spectrogram.html#a245a6d1281abe84d177d61be0698db55',1,'QwtPlotSpectrogram']]], + ['divideeps',['divideEps',['../class_qwt_scale_arithmetic.html#ae5f0415105b2a97cccb93f3da9ddaead',1,'QwtScaleArithmetic']]], + ['divideinterval',['divideInterval',['../class_qwt_scale_arithmetic.html#a9d03952650f73dd7a797791ddcfa91d7',1,'QwtScaleArithmetic::divideInterval()'],['../class_qwt_scale_engine.html#aff30158c5ccfee78f4c3e01c0fb5f4de',1,'QwtScaleEngine::divideInterval()']]], + ['dividescale',['divideScale',['../class_qwt_date_scale_engine.html#a335b9e9e2875492ce59befe31247c017',1,'QwtDateScaleEngine::divideScale()'],['../class_qwt_scale_engine.html#ab85442ced7cf3a39e5ad25f8cb80dea4',1,'QwtScaleEngine::divideScale()'],['../class_qwt_linear_scale_engine.html#aafed94c688e67c95a6ecf18e8bb522ab',1,'QwtLinearScaleEngine::divideScale()'],['../class_qwt_log_scale_engine.html#a883cc249cfcc290675af84960e4eccaf',1,'QwtLogScaleEngine::divideScale()']]], + ['dot',['Dot',['../class_qwt_knob.html#a7254d94e76a74228637931fb75939b95a298324d95eafb4e99717a35b81b0b704',1,'QwtKnob']]], + ['dots',['Dots',['../class_qwt_plot_curve.html#a15998aa80a11ba6ba80eebabaf773f70ac30a3c76d19bc69fc69bed68fc154838',1,'QwtPlotCurve']]], + ['draw',['draw',['../class_qwt_abstract_scale_draw.html#aca3c3a7499112f52616d0ee8518fa5a6',1,'QwtAbstractScaleDraw::draw()'],['../class_qwt_column_symbol.html#a647960f89c1f2f8524789d7ad90482d8',1,'QwtColumnSymbol::draw()'],['../class_qwt_compass_rose.html#ad974a3035da51a9cfb36fa04eb1c40a6',1,'QwtCompassRose::draw()'],['../class_qwt_simple_compass_rose.html#aa7541cd32c88b222731da37588e67bf3',1,'QwtSimpleCompassRose::draw()'],['../class_qwt_dial_needle.html#a425085086c4a8c7baff10b161616ee42',1,'QwtDialNeedle::draw()'],['../class_qwt_interval_symbol.html#aa13043e1d35361d8d259717a6579dadc',1,'QwtIntervalSymbol::draw()'],['../class_qwt_plot_grid.html#a9534a18db4f70b798bbbee2e50e0458d',1,'QwtPlotGrid::draw()'],['../class_qwt_plot_item.html#a0b0d6589d5db81ce72e6b33c4fbb21f9',1,'QwtPlotItem::draw()'],['../class_qwt_plot_legend_item.html#a6ce9e0ea057705582e31d3f6ea44ff16',1,'QwtPlotLegendItem::draw()'],['../class_qwt_plot_marker.html#abfd653364d9feeac09cd7ba77a650e3b',1,'QwtPlotMarker::draw()'],['../class_qwt_plot_raster_item.html#a2bb321c1ddc67b96a54a266ba27e6fe0',1,'QwtPlotRasterItem::draw()'],['../class_qwt_plot_scale_item.html#a2eef74cfd6007faf8b6e146277c82661',1,'QwtPlotScaleItem::draw()'],['../class_qwt_plot_series_item.html#af64601a32413f6f4928ceccc4934737e',1,'QwtPlotSeriesItem::draw()'],['../class_qwt_plot_shape_item.html#ab548f8daef8a2ae4184486bb1c4a47cf',1,'QwtPlotShapeItem::draw()'],['../class_qwt_plot_spectrogram.html#a92bafff167caeef9e1e4a6e652c0c5d4',1,'QwtPlotSpectrogram::draw()'],['../class_qwt_plot_svg_item.html#a83a95b772cc79f9a1590e0c4fe73d39c',1,'QwtPlotSvgItem::draw()'],['../class_qwt_plot_text_label.html#adfb623425eb95dcfe6fb18c661d04ebe',1,'QwtPlotTextLabel::draw()'],['../class_qwt_plot_zone_item.html#a02dfffe85a5578c6bbac0889f4739317',1,'QwtPlotZoneItem::draw()'],['../class_qwt_scale_widget.html#aab7267f2a3137b94a508a655bfaf4fd4',1,'QwtScaleWidget::draw()'],['../class_qwt_text.html#a01efd3ff82db2018b742265e0b7e4ece',1,'QwtText::draw()'],['../class_qwt_text_engine.html#ad727f58f9eebfec86369e7f2e5bf6a59',1,'QwtTextEngine::draw()'],['../class_qwt_plain_text_engine.html#a5fc2780c10ac2fb41aec91223b60fac7',1,'QwtPlainTextEngine::draw()'],['../class_qwt_rich_text_engine.html#a8f345540be2a90db3ce5a252ec443ce7',1,'QwtRichTextEngine::draw()'],['../class_qwt_math_m_l_text_engine.html#a4a347e3f7ac8fa7f57c4fcf62e4f2b36',1,'QwtMathMLTextEngine::draw()']]], + ['drawarrow',['drawArrow',['../class_qwt_arrow_button.html#aba724cf7e2f7e640b2e4f5c08f37d125',1,'QwtArrowButton']]], + ['drawbackbone',['drawBackbone',['../class_qwt_abstract_scale_draw.html#a15994a6033e689c3acdb8d83ae4f2a1c',1,'QwtAbstractScaleDraw::drawBackbone()'],['../class_qwt_round_scale_draw.html#a83ed97e96011d331939a3031df29f115',1,'QwtRoundScaleDraw::drawBackbone()'],['../class_qwt_scale_draw.html#aa53015c17e2abb01b179473cc488f20c',1,'QwtScaleDraw::drawBackbone()']]], + ['drawbackgound',['drawBackgound',['../class_qwt_painter.html#a726b908df4fd65a15e0d7ec3862947bc',1,'QwtPainter']]], + ['drawbackground',['drawBackground',['../class_qwt_plot_g_l_canvas.html#a7d829159155bff3fe206101914feeb26',1,'QwtPlotGLCanvas::drawBackground()'],['../class_qwt_plot_legend_item.html#ac72275134c687efc56304e2e74917174',1,'QwtPlotLegendItem::drawBackground()']]], + ['drawbar',['drawBar',['../class_qwt_plot_bar_chart.html#ad13634e3e2957f6a006eab2b5f56e828',1,'QwtPlotBarChart::drawBar()'],['../class_qwt_plot_multi_bar_chart.html#aa9f7a6f48b0d85937fd8d943aa89d91e',1,'QwtPlotMultiBarChart::drawBar()'],['../class_qwt_plot_trading_curve.html#a6a1b0150bbd4550c60e43bb7f74c6b3f',1,'QwtPlotTradingCurve::drawBar()']]], + ['drawborder',['drawBorder',['../class_qwt_plot_canvas.html#a4d415010a4baa09fa3b3edfcc6e5e4e7',1,'QwtPlotCanvas::drawBorder()'],['../class_qwt_plot_g_l_canvas.html#a9dc8018e6144788fe75dfc62206c1fe4',1,'QwtPlotGLCanvas::drawBorder()']]], + ['drawbox',['drawBox',['../class_qwt_column_symbol.html#a7f7951e3c38927c25f21dd8c3d47372a',1,'QwtColumnSymbol']]], + ['drawbuttonlabel',['drawButtonLabel',['../class_qwt_arrow_button.html#afc342cb3eaa01afe5aa897b3fd6aa7c2',1,'QwtArrowButton']]], + ['drawcandlestick',['drawCandleStick',['../class_qwt_plot_trading_curve.html#a66d576ebb06b9775729716d43164ab1a',1,'QwtPlotTradingCurve']]], + ['drawcanvas',['drawCanvas',['../class_qwt_plot.html#add1b88d8312e2671652d23f8181f2433',1,'QwtPlot']]], + ['drawcolorbar',['drawColorBar',['../class_qwt_painter.html#ae1009209978e5bb3f390905b81fb699f',1,'QwtPainter::drawColorBar()'],['../class_qwt_scale_widget.html#a6fe4349dce606498a417021e99b65fbf',1,'QwtScaleWidget::drawColorBar()']]], + ['drawcolumn',['drawColumn',['../class_qwt_plot_histogram.html#a4fe5a32387898f50c95e57603f092d2b',1,'QwtPlotHistogram']]], + ['drawcolumns',['drawColumns',['../class_qwt_plot_histogram.html#a53ef2324fd2bc187eb76dfb76c61f426',1,'QwtPlotHistogram']]], + ['drawcontents',['drawContents',['../class_qwt_dial.html#a9c567a9ce20120f3094a3d21ad26874a',1,'QwtDial::drawContents()'],['../class_qwt_text_label.html#ab1d6c248f451517a32c626372670ab51',1,'QwtTextLabel::drawContents()']]], + ['drawcontourlines',['drawContourLines',['../class_qwt_plot_spectrogram.html#aebd2c5ee80b3131138d4a55096962912',1,'QwtPlotSpectrogram']]], + ['drawcurve',['drawCurve',['../class_qwt_plot_curve.html#a9a1188e6abab05ed66ee7aebfc3d3679',1,'QwtPlotCurve']]], + ['drawdots',['drawDots',['../class_qwt_plot_curve.html#a9d5c81d3340aebf2ab8cf0dfee7e9c81',1,'QwtPlotCurve::drawDots()'],['../class_qwt_plot_spectro_curve.html#af6f48a0334d5646e2def2b3bfd16754c',1,'QwtPlotSpectroCurve::drawDots()']]], + ['drawellipse',['drawEllipse',['../class_qwt_null_paint_device.html#a36dbf087d462f077808f7d0a4611e572',1,'QwtNullPaintDevice::drawEllipse(const QRectF &)'],['../class_qwt_null_paint_device.html#a3a58da653add416644b1ad4e6567871e',1,'QwtNullPaintDevice::drawEllipse(const QRect &)'],['../class_qwt_painter.html#a0cce52b66d249859ff71e41edb3637ad',1,'QwtPainter::drawEllipse()']]], + ['drawfocusindicator',['drawFocusIndicator',['../class_qwt_dial.html#a1fce41a19c2e368fe90551e29c4de076',1,'QwtDial::drawFocusIndicator()'],['../class_qwt_knob.html#a89fc69b6f0d5ad4a4e99220db07721fd',1,'QwtKnob::drawFocusIndicator()'],['../class_qwt_plot_canvas.html#a4dc526ac5186fe253a158a392bbb4f40',1,'QwtPlotCanvas::drawFocusIndicator()']]], + ['drawfocusrect',['drawFocusRect',['../class_qwt_painter.html#aad72e955692b37a06547a6c0d62817b0',1,'QwtPainter::drawFocusRect(QPainter *, const QWidget *)'],['../class_qwt_painter.html#a3f6b853fa4a54712ea2ca20a9aa2f106',1,'QwtPainter::drawFocusRect(QPainter *, const QWidget *, const QRect &)']]], + ['drawframe',['drawFrame',['../class_qwt_dial.html#ad4534ebd8e4a792edbad3e16c25be7ca',1,'QwtDial::drawFrame()'],['../class_qwt_painter.html#ac0a433548dcb808cb88a93e7e2379ff4',1,'QwtPainter::drawFrame()']]], + ['drawgroupedbars',['drawGroupedBars',['../class_qwt_plot_multi_bar_chart.html#a2a3e582ab5ac2a4f7110fdf9f51a1959',1,'QwtPlotMultiBarChart']]], + ['drawhand',['drawHand',['../class_qwt_analog_clock.html#a62cbacb57c60c7584ba30f340ed575a1',1,'QwtAnalogClock']]], + ['drawhandle',['drawHandle',['../class_qwt_slider.html#a924e3fc8a885f72837379fdc29da2d20',1,'QwtSlider']]], + ['drawimage',['drawImage',['../class_qwt_graphic.html#a7055541b0d141c475b507ce3ad861f87',1,'QwtGraphic::drawImage()'],['../class_qwt_null_paint_device.html#a6a18a677959e446b34419d398d4fc4c7',1,'QwtNullPaintDevice::drawImage()'],['../class_qwt_painter.html#a2825f068a54e21e885235235daac3ec7',1,'QwtPainter::drawImage()']]], + ['drawitems',['drawItems',['../class_qwt_plot.html#a97be5b6d98b88053883cc26e4cedec8e',1,'QwtPlot::drawItems()'],['../class_qwt_plot_g_l_canvas.html#a0b385f2230b2abddf85882dbdfd89a34',1,'QwtPlotGLCanvas::drawItems()']]], + ['drawknob',['drawKnob',['../class_qwt_dial_needle.html#aaca9572717a1db10b1b6609571024688',1,'QwtDialNeedle::drawKnob()'],['../class_qwt_knob.html#a5ebc1ef5761b8db6d67820fc14cb89d5',1,'QwtKnob::drawKnob()']]], + ['drawlabel',['drawLabel',['../class_qwt_abstract_scale_draw.html#aa78dc8bf05a0224450c947af54128d8d',1,'QwtAbstractScaleDraw::drawLabel()'],['../class_qwt_plot_marker.html#a528aa01fd96e43829afc817433da49d4',1,'QwtPlotMarker::drawLabel()'],['../class_qwt_round_scale_draw.html#ad45ba2c90ac205bb9405c028d6498c0f',1,'QwtRoundScaleDraw::drawLabel()'],['../class_qwt_scale_draw.html#afc02a11a03efde4ea239d77c4d7711f4',1,'QwtScaleDraw::drawLabel()']]], + ['drawlegenddata',['drawLegendData',['../class_qwt_plot_legend_item.html#a4c9c3d7babfbaf5a7d09050d766d3987',1,'QwtPlotLegendItem']]], + ['drawline',['drawLine',['../class_qwt_painter.html#ad90ed35a673adb9767046c05b605bcf5',1,'QwtPainter::drawLine(QPainter *, double x1, double y1, double x2, double y2)'],['../class_qwt_painter.html#a8f4ebba74be8858ca43e50fac363468c',1,'QwtPainter::drawLine(QPainter *, const QPointF &p1, const QPointF &p2)'],['../class_qwt_painter.html#af31427d37c1cfd4ddc84e013086a77e1',1,'QwtPainter::drawLine(QPainter *, const QLineF &)']]], + ['drawlines',['drawLines',['../class_qwt_null_paint_device.html#a3a8c7d120fb6d1aa8617037e34df1cf3',1,'QwtNullPaintDevice::drawLines(const QLine *, int)'],['../class_qwt_null_paint_device.html#aa69ee4a20a2d5ff7f11b24db212bc636',1,'QwtNullPaintDevice::drawLines(const QLineF *, int)'],['../class_qwt_plot_curve.html#a20948ab52983ee8c2058b2b2689e97a0',1,'QwtPlotCurve::drawLines()'],['../class_qwt_plot_histogram.html#aa42318d0547aca1fff650a0025168890',1,'QwtPlotHistogram::drawLines()'],['../class_qwt_plot_marker.html#a4f0ebfc835da7397ee823860cfac62ca',1,'QwtPlotMarker::drawLines()']]], + ['drawliquid',['drawLiquid',['../class_qwt_thermo.html#ab9cca3cab3a8950b66e14b995b86beb8',1,'QwtThermo']]], + ['drawmarker',['drawMarker',['../class_qwt_knob.html#a2b0523757918e335fe444df702972f3e',1,'QwtKnob']]], + ['drawneedle',['drawNeedle',['../class_qwt_analog_clock.html#ac243e3acb6ba8edd73c24918e170f529',1,'QwtAnalogClock::drawNeedle()'],['../class_qwt_dial.html#ad287b8e8d3f5453c9f7a317d40d35162',1,'QwtDial::drawNeedle()'],['../class_qwt_dial_needle.html#a1e4fee366fec1838edc18890d9957f2b',1,'QwtDialNeedle::drawNeedle()'],['../class_qwt_dial_simple_needle.html#a0eff8832707ff968d17eddf478d6a771',1,'QwtDialSimpleNeedle::drawNeedle()'],['../class_qwt_compass_magnet_needle.html#aa052d929a09bfc6d487a973b2221d44d',1,'QwtCompassMagnetNeedle::drawNeedle()'],['../class_qwt_compass_wind_arrow.html#a4e3b612f2de83ff416e34f62c1f0fd6c',1,'QwtCompassWindArrow::drawNeedle()']]], + ['drawoutline',['drawOutline',['../class_qwt_plot_histogram.html#a9984abfbec9121b8026e9c7103ebec4b',1,'QwtPlotHistogram']]], + ['drawoverlay',['drawOverlay',['../class_qwt_widget_overlay.html#abb69235d3eba71b6dde354c668dd2611',1,'QwtWidgetOverlay::drawOverlay(QPainter *painter) const =0'],['../class_qwt_widget_overlay.html#aaa8358f3b841b733d69e62aa645783d8ab4b3bfef277a5231f8632a6800a256d8',1,'QwtWidgetOverlay::DrawOverlay()']]], + ['drawpath',['drawPath',['../class_qwt_graphic.html#ab505a5efa0f4ba0494460d4671a7bf21',1,'QwtGraphic::drawPath()'],['../class_qwt_null_paint_device.html#a1df889689ff1e29a0f864be5ac809ada',1,'QwtNullPaintDevice::drawPath()'],['../class_qwt_painter.html#a22cff4eba018aee6680c43347e92238d',1,'QwtPainter::drawPath()']]], + ['drawpie',['drawPie',['../class_qwt_painter.html#af3a38d38e0909523dbac12cd93ba3122',1,'QwtPainter']]], + ['drawpixmap',['drawPixmap',['../class_qwt_graphic.html#a888ea196dec4fab9eb4acd4d535ec730',1,'QwtGraphic::drawPixmap()'],['../class_qwt_null_paint_device.html#a1a0a2f22ea26bdf74becd5e5813f8f6f',1,'QwtNullPaintDevice::drawPixmap()'],['../class_qwt_painter.html#aec25b066b31a967de60d645c58ed7557',1,'QwtPainter::drawPixmap()']]], + ['drawpoint',['drawPoint',['../class_qwt_painter.html#ab2e88f78d51387c661a9e10352ab945c',1,'QwtPainter::drawPoint(QPainter *, const QPoint &)'],['../class_qwt_painter.html#a1e65c0e2436e253de937e164d365aa5f',1,'QwtPainter::drawPoint(QPainter *, double x, double y)'],['../class_qwt_painter.html#a9b0ef616fc27c84dc7ee3cab5449a313',1,'QwtPainter::drawPoint(QPainter *, const QPointF &)']]], + ['drawpoints',['drawPoints',['../class_qwt_null_paint_device.html#a5b0b40aed4fa6b4b193834cf89af2a3e',1,'QwtNullPaintDevice::drawPoints(const QPointF *, int)'],['../class_qwt_null_paint_device.html#a89f89b7398be0e9c3c24cdf7e37803e2',1,'QwtNullPaintDevice::drawPoints(const QPoint *, int)'],['../class_qwt_painter.html#a0e1bddfd725ea95f628c491149c2deba',1,'QwtPainter::drawPoints(QPainter *, const QPolygon &)'],['../class_qwt_painter.html#a1f268ec257dbd52a7aca59c5c2ea3f98',1,'QwtPainter::drawPoints(QPainter *, const QPoint *, int pointCount)'],['../class_qwt_painter.html#a1a854725b6ff657557e678575dc56357',1,'QwtPainter::drawPoints(QPainter *, const QPolygonF &)'],['../class_qwt_painter.html#af5fa718b25a9b4df10ddb7e1270a4289',1,'QwtPainter::drawPoints(QPainter *, const QPointF *, int pointCount)']]], + ['drawpolygon',['drawPolygon',['../class_qwt_null_paint_device.html#ad8ccc7d13b3ed6011c4f986210912d02',1,'QwtNullPaintDevice::drawPolygon(const QPointF *, int, QPaintEngine::PolygonDrawMode)'],['../class_qwt_null_paint_device.html#a9bd92d6203a0c7ad70a529d59d685eb1',1,'QwtNullPaintDevice::drawPolygon(const QPoint *, int, QPaintEngine::PolygonDrawMode)'],['../class_qwt_painter.html#a2fff1088059c230864ac1eff90d8e975',1,'QwtPainter::drawPolygon(QPainter *, const QPolygonF &)'],['../class_qwt_painter.html#a67bd336cc96329e2d0e717574892c84c',1,'QwtPainter::drawPolygon(QPainter *, const QPolygon &)']]], + ['drawpolyline',['drawPolyline',['../class_qwt_painter.html#a60ab9909e9eac196c022b1ec6200d198',1,'QwtPainter::drawPolyline(QPainter *, const QPolygonF &)'],['../class_qwt_painter.html#a2aac8306cd6863887db1f2987eb0eced',1,'QwtPainter::drawPolyline(QPainter *, const QPointF *, int pointCount)'],['../class_qwt_painter.html#a4846eb8406cc49435013e41e4debacdc',1,'QwtPainter::drawPolyline(QPainter *, const QPolygon &)'],['../class_qwt_painter.html#a479d20a9aed2dee2ccdd735c6e77bc58',1,'QwtPainter::drawPolyline(QPainter *, const QPoint *, int pointCount)']]], + ['drawrect',['drawRect',['../class_qwt_painter.html#a0779e2b85c7d04547933574fd2021193',1,'QwtPainter::drawRect(QPainter *, double x, double y, double w, double h)'],['../class_qwt_painter.html#a838b9cc65ae98ecb40d62ed4281a37b7',1,'QwtPainter::drawRect(QPainter *, const QRectF &rect)']]], + ['drawrects',['drawRects',['../class_qwt_null_paint_device.html#a1ea5ece663be08bacd9b1b46230b5cbc',1,'QwtNullPaintDevice::drawRects(const QRect *, int)'],['../class_qwt_null_paint_device.html#a78163254e4793afc26b1752178964336',1,'QwtNullPaintDevice::drawRects(const QRectF *, int)']]], + ['drawrose',['drawRose',['../class_qwt_compass.html#a3cc1a7d06b9d6be235024a19ff0c6a25',1,'QwtCompass::drawRose()'],['../class_qwt_simple_compass_rose.html#a914bb202a844f0b11a18a0296e170025',1,'QwtSimpleCompassRose::drawRose()']]], + ['drawroundedframe',['drawRoundedFrame',['../class_qwt_painter.html#a00b91696b5dc3264b54c99e436616804',1,'QwtPainter']]], + ['drawroundframe',['drawRoundFrame',['../class_qwt_painter.html#a388f68022ef77dbdae9d700e104f0976',1,'QwtPainter']]], + ['drawrubberband',['drawRubberBand',['../class_qwt_picker.html#a4848b0a4ca94d4160fdcf29c73982bef',1,'QwtPicker']]], + ['drawsample',['drawSample',['../class_qwt_plot_bar_chart.html#a0080d33e4a30cd941c09b22249836099',1,'QwtPlotBarChart::drawSample()'],['../class_qwt_plot_multi_bar_chart.html#a548e1f1b4319abf03f1995dc25ad40be',1,'QwtPlotMultiBarChart::drawSample()']]], + ['drawscale',['drawScale',['../class_qwt_dial.html#ad93f277c9cca98580be853a13abd7cd4',1,'QwtDial']]], + ['drawscalecontents',['drawScaleContents',['../class_qwt_compass.html#a562e9358a830106f9d219a4fa8af3540',1,'QwtCompass::drawScaleContents()'],['../class_qwt_dial.html#a06b36d64377e54dac8812b4c4c0bf263',1,'QwtDial::drawScaleContents()']]], + ['drawseries',['drawSeries',['../class_qwt_plot_bar_chart.html#aa5a140241884fbeee3d41bdb0964a71c',1,'QwtPlotBarChart::drawSeries()'],['../class_qwt_plot_curve.html#aea90af49da5296087499e06ae1e35c9e',1,'QwtPlotCurve::drawSeries()'],['../class_qwt_plot_direct_painter.html#aacc2e1d79dd410cb1a4404fbc00290bd',1,'QwtPlotDirectPainter::drawSeries()'],['../class_qwt_plot_histogram.html#a588eb9f56482fe8669c4d6eaa2db09e2',1,'QwtPlotHistogram::drawSeries()'],['../class_qwt_plot_interval_curve.html#add274e6e29ff2df9b6961f3ed5ebcd5e',1,'QwtPlotIntervalCurve::drawSeries()'],['../class_qwt_plot_multi_bar_chart.html#a8b8058db564f8d5cb674afe224c4a584',1,'QwtPlotMultiBarChart::drawSeries()'],['../class_qwt_plot_series_item.html#af6c8091544081ff72723270cc7c8f139',1,'QwtPlotSeriesItem::drawSeries()'],['../class_qwt_plot_spectro_curve.html#a04529b82d2acbcf9fc8f66da73bae8e9',1,'QwtPlotSpectroCurve::drawSeries()'],['../class_qwt_plot_trading_curve.html#a36a3770784f70ef0e52fee3ad7ea055e',1,'QwtPlotTradingCurve::drawSeries()']]], + ['drawsimplerichtext',['drawSimpleRichText',['../class_qwt_painter.html#a1a44fdbb66452b38d57369a485da3971',1,'QwtPainter']]], + ['drawslider',['drawSlider',['../class_qwt_slider.html#a5e45e9ca42fdf659d89011bddd8ff779',1,'QwtSlider']]], + ['drawstackedbars',['drawStackedBars',['../class_qwt_plot_multi_bar_chart.html#acee8ee9034c64559598c2e6fcace60a5',1,'QwtPlotMultiBarChart']]], + ['drawsteps',['drawSteps',['../class_qwt_plot_curve.html#aa55bd22c153a15b7cba082c499536602',1,'QwtPlotCurve']]], + ['drawsticks',['drawSticks',['../class_qwt_plot_curve.html#a732c4a8b905be4f635d8558b6d959b52',1,'QwtPlotCurve']]], + ['drawsymbol',['drawSymbol',['../class_qwt_symbol.html#a4ad34a14ca9650c53530fd540d921fe8',1,'QwtSymbol::drawSymbol(QPainter *, const QRectF &) const '],['../class_qwt_symbol.html#a3403db40a12f2f79f79616cf858ecb1f',1,'QwtSymbol::drawSymbol(QPainter *, const QPointF &) const ']]], + ['drawsymbols',['drawSymbols',['../class_qwt_plot_curve.html#ad734862538617112beb6a59cc06ed3b5',1,'QwtPlotCurve::drawSymbols()'],['../class_qwt_plot_interval_curve.html#a54682faaed2110816fe874cad37142b7',1,'QwtPlotIntervalCurve::drawSymbols()'],['../class_qwt_plot_trading_curve.html#a3b330a144768322218ac6b996d4ac802',1,'QwtPlotTradingCurve::drawSymbols()'],['../class_qwt_symbol.html#a249740d6f7e6315e3de0ce6f7ad7020d',1,'QwtSymbol::drawSymbols(QPainter *, const QPolygonF &) const '],['../class_qwt_symbol.html#a18c1e4716c4ebc92a28becc86de4d429',1,'QwtSymbol::drawSymbols(QPainter *, const QPointF *, int numPoints) const ']]], + ['drawtext',['drawText',['../class_qwt_painter.html#a7b32c7e2937f7beea38728b9ce445860',1,'QwtPainter::drawText(QPainter *, double x, double y, const QString &)'],['../class_qwt_painter.html#a60048491773b3eb7aac5b984a4bd9730',1,'QwtPainter::drawText(QPainter *, const QPointF &, const QString &)'],['../class_qwt_painter.html#a90fd62c3862e9f4543eda02279f75f10',1,'QwtPainter::drawText(QPainter *, double x, double y, double w, double h, int flags, const QString &)'],['../class_qwt_painter.html#a2866de24c2d7ddb88ee5919d09cad03f',1,'QwtPainter::drawText(QPainter *, const QRectF &, int flags, const QString &)'],['../class_qwt_text_label.html#af1e33db74ecf9c4e7aff158db65404c2',1,'QwtTextLabel::drawText()']]], + ['drawtextitem',['drawTextItem',['../class_qwt_null_paint_device.html#a9c0566fc34422c4bd61534cebfb95d63',1,'QwtNullPaintDevice']]], + ['drawtick',['drawTick',['../class_qwt_abstract_scale_draw.html#a31791e80bf07d23adbe500740aac5a58',1,'QwtAbstractScaleDraw::drawTick()'],['../class_qwt_round_scale_draw.html#aff2f18e7e7cac42805724ab5b0f2aad7',1,'QwtRoundScaleDraw::drawTick()'],['../class_qwt_scale_draw.html#a84badd947ddc95a462ec20fe64922b36',1,'QwtScaleDraw::drawTick()']]], + ['drawticks',['drawTicks',['../class_qwt_wheel.html#aba74d0e494f6e590ac1deac60a66a68e',1,'QwtWheel']]], + ['drawtiledpixmap',['drawTiledPixmap',['../class_qwt_null_paint_device.html#a256a8a39d0f32fb210c4561fe1b3f867',1,'QwtNullPaintDevice']]], + ['drawtitle',['drawTitle',['../class_qwt_scale_widget.html#a7daf1650daa5503342721dda62d72243',1,'QwtScaleWidget']]], + ['drawtracker',['drawTracker',['../class_qwt_picker.html#a74c471c27ced5e7a5d59455bcd7d8290',1,'QwtPicker']]], + ['drawtube',['drawTube',['../class_qwt_plot_interval_curve.html#ae5522b27d49da7a99f8b01b577fa153e',1,'QwtPlotIntervalCurve']]], + ['drawusersymbol',['drawUserSymbol',['../class_qwt_plot_trading_curve.html#a02a8e52cb0b6c4d103ae616f00546cf3',1,'QwtPlotTradingCurve']]], + ['drawwheelbackground',['drawWheelBackground',['../class_qwt_wheel.html#a2c4fc6e5e04cd5623a035fd9581d395f',1,'QwtWheel']]], + ['dtriangle',['DTriangle',['../class_qwt_symbol.html#a62f457952470c2076962e83ef2c24d2fad8ea4408d80512825a2700b4968f1715',1,'QwtSymbol']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/all_65.html b/ThirdParty/Qwt/doc/html/search/all_65.html new file mode 100644 index 0000000000..c2f4fcd94f --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/all_65.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/all_65.js b/ThirdParty/Qwt/doc/html/search/all_65.js new file mode 100644 index 0000000000..126defd021 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/all_65.js @@ -0,0 +1,31 @@ +var searchData= +[ + ['elapsed',['elapsed',['../class_qwt_sampling_thread.html#a27ebf049b4fc423bdb172d9036eb6683',1,'QwtSamplingThread::elapsed()'],['../class_qwt_system_clock.html#a0baae39a5a9d4f4e8bf3a8bd308a6dad',1,'QwtSystemClock::elapsed()']]], + ['ellipse',['Ellipse',['../class_qwt_symbol.html#a62f457952470c2076962e83ef2c24d2fa09e1d50ec759311a76c158f69149fa44',1,'QwtSymbol']]], + ['ellipserubberband',['EllipseRubberBand',['../class_qwt_picker.html#ab36c79d8ff20aba5b778d2823c1f7894a6a548d259f7f04ae868419431883e7ef',1,'QwtPicker']]], + ['enableaxis',['enableAxis',['../class_qwt_plot.html#ab644f7a0a0566ff776c89cc225ce37d7',1,'QwtPlot']]], + ['enablecomponent',['enableComponent',['../class_qwt_abstract_scale_draw.html#af975410588db6103f281e49d0b43c6a6',1,'QwtAbstractScaleDraw']]], + ['enablex',['enableX',['../class_qwt_plot_grid.html#aba4de91f74f86e172e080fa62765bba8',1,'QwtPlotGrid']]], + ['enablexmin',['enableXMin',['../class_qwt_plot_grid.html#a4106c58c9d463bd4ccd94e215cc246bb',1,'QwtPlotGrid']]], + ['enabley',['enableY',['../class_qwt_plot_grid.html#a0172d8af861495a94aa856af26ad786d',1,'QwtPlotGrid']]], + ['enableymin',['enableYMin',['../class_qwt_plot_grid.html#a21b26d5b6b0745ecdec12d6bdeb8ecb4',1,'QwtPlotGrid']]], + ['end',['end',['../class_qwt_picker.html#ad258c518257cf2f52326905a36efb0c4',1,'QwtPicker::end()'],['../class_qwt_plot_picker.html#a9fceb663542b6f9b0a358e9419406423',1,'QwtPlotPicker::end()'],['../class_qwt_plot_zoomer.html#ac7d10eb27858ccfebebecab5d69ecbb3',1,'QwtPlotZoomer::end()']]], + ['endborderdist',['endBorderDist',['../class_qwt_scale_widget.html#a314a2aff4b7629db21b45c8f74b3ae0b',1,'QwtScaleWidget']]], + ['event',['event',['../class_qwt_counter.html#ad855f1cec9068fd73cce5e2e29fb5771',1,'QwtCounter::event()'],['../class_qwt_plot.html#af40d1bfdd9b6cd94e9981db8b254b961',1,'QwtPlot::event()'],['../class_qwt_plot_canvas.html#ab7f160c99d7d408a979ebe2acae951bc',1,'QwtPlotCanvas::event()'],['../class_qwt_plot_g_l_canvas.html#a9345f69cd3c96c5cb4bdcc3d056de8dd',1,'QwtPlotGLCanvas::event()']]], + ['eventfilter',['eventFilter',['../class_qwt_legend.html#ade86e158b8254fe76d42e85f9808c827',1,'QwtLegend::eventFilter()'],['../class_qwt_magnifier.html#ae7f4c0ad7631501cec17abe31695281f',1,'QwtMagnifier::eventFilter()'],['../class_qwt_panner.html#a06b8eea86d4dcbe361c4af41a263f2cb',1,'QwtPanner::eventFilter()'],['../class_qwt_picker.html#ac149f9cb8fb068f31871e1fe450c376e',1,'QwtPicker::eventFilter()'],['../class_qwt_plot.html#a8c40a5ccc1b0fc18f29796ddc05b27f6',1,'QwtPlot::eventFilter()'],['../class_qwt_plot_direct_painter.html#ab421bd757679b61f1dcfde2991500ab2',1,'QwtPlotDirectPainter::eventFilter()'],['../class_qwt_plot_rescaler.html#a2a6809f3940b9114a1faed30f6edc3d0',1,'QwtPlotRescaler::eventFilter()'],['../class_qwt_widget_overlay.html#a460de4766c71c6977478eddff3546066',1,'QwtWidgetOverlay::eventFilter()']]], + ['excludeborders',['ExcludeBorders',['../class_qwt_interval.html#a3a4b4e49495108c660fc07a62af7ac54afc7d2a399b311a1cc8026681410fc22c',1,'QwtInterval']]], + ['excludemaximum',['ExcludeMaximum',['../class_qwt_interval.html#a3a4b4e49495108c660fc07a62af7ac54a70e70e65956ae319e507bc38b792c434',1,'QwtInterval']]], + ['excludeminimum',['ExcludeMinimum',['../class_qwt_interval.html#a3a4b4e49495108c660fc07a62af7ac54aa7fde04c41d882187bb13f0104da7240',1,'QwtInterval']]], + ['expandboth',['ExpandBoth',['../class_qwt_plot_rescaler.html#a1c314e9513cef076a79381111aa67585a3dfb8208dfb62200761e4221763db033',1,'QwtPlotRescaler']]], + ['expanddown',['ExpandDown',['../class_qwt_plot_rescaler.html#a1c314e9513cef076a79381111aa67585a856d9a1fe75ed6398a1b3c4b60f3fbfd',1,'QwtPlotRescaler']]], + ['expanding',['Expanding',['../class_qwt_plot_rescaler.html#a6a614b832876a7641cb5410ba81d9d6aac0b9db1ea3c5666792c2a9813ca5d7e1',1,'QwtPlotRescaler']]], + ['expandingdirection',['expandingDirection',['../class_qwt_plot_rescaler.html#aadeb316249fa679323252140ff241176',1,'QwtPlotRescaler::expandingDirection(int axis) const '],['../class_qwt_plot_rescaler.html#a1c314e9513cef076a79381111aa67585',1,'QwtPlotRescaler::ExpandingDirection()']]], + ['expandingdirections',['expandingDirections',['../class_qwt_dyn_grid_layout.html#a1340bdbdaf09f79ac9e80f96f1b8b106',1,'QwtDynGridLayout']]], + ['expandinterval',['expandInterval',['../class_qwt_plot_rescaler.html#ad3da887bf71befccf1f3094da448a502',1,'QwtPlotRescaler']]], + ['expandlinebreaks',['expandLineBreaks',['../class_qwt_plot_layout.html#a36aa9335a907f8f20a59a63cc7e0d78c',1,'QwtPlotLayout']]], + ['expandscale',['expandScale',['../class_qwt_plot_rescaler.html#ae3eb4d18dcd9ace4b7eb0bd05216c957',1,'QwtPlotRescaler']]], + ['expandup',['ExpandUp',['../class_qwt_plot_rescaler.html#a1c314e9513cef076a79381111aa67585a10adc202ca84a06179b905db6802668c',1,'QwtPlotRescaler']]], + ['exportto',['exportTo',['../class_qwt_plot_renderer.html#ac1912ef59ba1a3085f87c0ab49cbcd8b',1,'QwtPlotRenderer']]], + ['extend',['extend',['../class_qwt_interval.html#a484665e4af4ea42583b3224c10d1d9c3',1,'QwtInterval']]], + ['extent',['extent',['../class_qwt_abstract_scale_draw.html#a87e21208e981457cde501054319c77e7',1,'QwtAbstractScaleDraw::extent()'],['../class_qwt_round_scale_draw.html#a786fd49ec94ab51bb75d7a2f495b2727',1,'QwtRoundScaleDraw::extent()'],['../class_qwt_scale_draw.html#a1fa0cebc2b8f69dce72b0514ad7653f0',1,'QwtScaleDraw::extent()']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/all_66.html b/ThirdParty/Qwt/doc/html/search/all_66.html new file mode 100644 index 0000000000..a9ac881c03 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/all_66.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/all_66.js b/ThirdParty/Qwt/doc/html/search/all_66.js new file mode 100644 index 0000000000..9ede82e111 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/all_66.js @@ -0,0 +1,35 @@ +var searchData= +[ + ['fillbrush',['fillBrush',['../class_qwt_thermo.html#a3b109fe9027813e4e1b5ffa080a90046',1,'QwtThermo']]], + ['fillcurve',['fillCurve',['../class_qwt_plot_curve.html#a599d88770d6fafa5ae4edb75fd5d445f',1,'QwtPlotCurve']]], + ['fillpixmap',['fillPixmap',['../class_qwt_painter.html#ab3207c4d8ee4ce7fd472f8faefb93657',1,'QwtPainter']]], + ['fillrect',['fillRect',['../class_qwt_painter.html#a8f5561421bf2d1c1093059f1b7bba7ba',1,'QwtPainter::fillRect()'],['../class_qwt_thermo.html#a3226e3ca8266e16d8c90bae5c9f5a3d2',1,'QwtThermo::fillRect()']]], + ['filterpoints',['FilterPoints',['../class_qwt_plot_curve.html#a96db1b854c63bfbc452c943251a11b66af09c1c6ec8c8198124f0e41c391f8391',1,'QwtPlotCurve']]], + ['firstday',['FirstDay',['../class_qwt_date.html#ab915db512c556a4666ada4fbfccfce1eab5c50b8108f8c4535201c0c590a598d6',1,'QwtDate']]], + ['firstthursday',['FirstThursday',['../class_qwt_date.html#ab915db512c556a4666ada4fbfccfce1ea82971cd90d670fe3048ad8c377379c1d',1,'QwtDate']]], + ['fitcurve',['fitCurve',['../class_qwt_curve_fitter.html#afa9bf5b328aa553229e204533a60fec0',1,'QwtCurveFitter::fitCurve()'],['../class_qwt_spline_curve_fitter.html#a14d64180d7777d0cd9c2adf81e120140',1,'QwtSplineCurveFitter::fitCurve()'],['../class_qwt_weeding_curve_fitter.html#aa316dc6c60ae0d0c74ef0bc0fc239f0b',1,'QwtWeedingCurveFitter::fitCurve()']]], + ['fitmode',['FitMode',['../class_qwt_spline_curve_fitter.html#a8c5e6858f885b5691c30092a950879a8',1,'QwtSplineCurveFitter::FitMode()'],['../class_qwt_spline_curve_fitter.html#a473468f2151839f3290975f6b18f1c4f',1,'QwtSplineCurveFitter::fitMode() const ']]], + ['fitted',['Fitted',['../class_qwt_plot_curve.html#a38064f7de6f026a49db782c365f872c3a583f7bc6ca4d5245fa82757f4bddea1b',1,'QwtPlotCurve']]], + ['fitting',['Fitting',['../class_qwt_plot_rescaler.html#a6a614b832876a7641cb5410ba81d9d6aa30a43b11d9df23f66110b65d1e249db1',1,'QwtPlotRescaler']]], + ['fixed',['Fixed',['../class_qwt_plot_rescaler.html#a6a614b832876a7641cb5410ba81d9d6aab8f9ce10c092bee12de74b05a46b6e9c',1,'QwtPlotRescaler']]], + ['fixedcolors',['FixedColors',['../class_qwt_linear_color_map.html#ac8c5f1991f533b1d25a9a0a0874b7d54a564b5243ab2c5e4c972a6b645234c651',1,'QwtLinearColorMap']]], + ['fixedsamplesize',['FixedSampleSize',['../class_qwt_plot_abstract_bar_chart.html#ae1db0e1606747ef46c863c54c210e53aa17d33062f0a9e6c38e43a0c51ba778e5',1,'QwtPlotAbstractBarChart']]], + ['flags',['flags',['../class_qwt_point_mapper.html#aeb3ce1915222fab8a6e2ab83acd90f93',1,'QwtPointMapper']]], + ['flat',['Flat',['../class_qwt_knob.html#addd00357b45752377aec83a3ab7208bea1dea5fdd408692d0efacc3edf8ca9454',1,'QwtKnob']]], + ['floating',['Floating',['../class_qwt_scale_engine.html#a7548418e0896d75eec164bfa2ba3ff5fa2158d4b3596e7d4a00375821fc0d20c3',1,'QwtScaleEngine']]], + ['floor',['floor',['../class_qwt_date.html#a1b350f22a57b44b529bc4de740dbe213',1,'QwtDate']]], + ['flooreps',['floorEps',['../class_qwt_scale_arithmetic.html#a924d97f2e5db236f43f4d65e430e09c1',1,'QwtScaleArithmetic']]], + ['focusindicator',['FocusIndicator',['../class_qwt_plot_canvas.html#a89b44e4c28038a674ce211fe9ac2d7be',1,'QwtPlotCanvas::FocusIndicator()'],['../class_qwt_plot_canvas.html#a0e9653bdf8c62299dbc3551ac7e5ec51',1,'QwtPlotCanvas::focusIndicator() const ']]], + ['font',['font',['../class_qwt_plot_legend_item.html#a040a9645b326123adde3ae0fe0bd3250',1,'QwtPlotLegendItem::font()'],['../class_qwt_plot_scale_item.html#ada859305224f3eec06e23dc7c3ce8f9c',1,'QwtPlotScaleItem::font()'],['../class_qwt_text.html#a76db41eeae98fbfa0933a38328a240ac',1,'QwtText::font()']]], + ['footer',['footer',['../class_qwt_plot.html#ad6898e29b51becca48e62a83f7d45034',1,'QwtPlot']]], + ['footerlabel',['footerLabel',['../class_qwt_plot.html#a613b07505a881a7e85a868effa1f5a96',1,'QwtPlot::footerLabel()'],['../class_qwt_plot.html#a5e0d7d488fa3aafcb10f3ef53d037f35',1,'QwtPlot::footerLabel() const ']]], + ['footerrect',['footerRect',['../class_qwt_plot_layout.html#ae782fe2075ad7e8b902b2deae317e96f',1,'QwtPlotLayout']]], + ['format',['format',['../class_qwt_color_map.html#a436802833ae1d4694f376655bc3d75be',1,'QwtColorMap::format() const '],['../class_qwt_color_map.html#a9e5570790910fa3894887bca7dc5a670',1,'QwtColorMap::Format()']]], + ['framerect',['frameRect',['../class_qwt_plot_g_l_canvas.html#a0288ef4d408f6f270fedb895436acc89',1,'QwtPlotGLCanvas']]], + ['frameshadow',['frameShadow',['../class_qwt_dial.html#a49e37bd4da2ed2b846bba75c79a04fbc',1,'QwtDial::frameShadow()'],['../class_qwt_plot_g_l_canvas.html#a331133679651f7d08cfad03b7d723691',1,'QwtPlotGLCanvas::frameShadow()']]], + ['frameshape',['frameShape',['../class_qwt_plot_g_l_canvas.html#a06d846c980148c1b258baea8ba0b2d68',1,'QwtPlotGLCanvas']]], + ['framestyle',['FrameStyle',['../class_qwt_column_symbol.html#a4b97f7748370447559a11a5adeb70e44',1,'QwtColumnSymbol::FrameStyle()'],['../class_qwt_column_symbol.html#a9e13ae8a8b07556ee2de672c7067606a',1,'QwtColumnSymbol::frameStyle() const '],['../class_qwt_plot_g_l_canvas.html#ae5e8b391cd2ec58d0483a4dd7db5f395',1,'QwtPlotGLCanvas::frameStyle()']]], + ['framewidth',['frameWidth',['../class_qwt_plot_g_l_canvas.html#a39bc67f5fd7c4adb8ac5f5a4e43d9d68',1,'QwtPlotGLCanvas']]], + ['framewithscales',['FrameWithScales',['../class_qwt_plot_renderer.html#a111b4db55d3f620a33e75f6b398e4b4aac81f7d56880ac4c03aaeab489c863a63',1,'QwtPlotRenderer']]], + ['fullrepaint',['FullRepaint',['../class_qwt_plot_direct_painter.html#a38f72175526a1a748d311763707cf934a133cb5ae512ffa0f0633c9d7bd423ff4',1,'QwtPlotDirectPainter']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/all_67.html b/ThirdParty/Qwt/doc/html/search/all_67.html new file mode 100644 index 0000000000..747fb512ce --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/all_67.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/all_67.js b/ThirdParty/Qwt/doc/html/search/all_67.js new file mode 100644 index 0000000000..0c1cc591f0 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/all_67.js @@ -0,0 +1,16 @@ +var searchData= +[ + ['geometry',['geometry',['../class_qwt_plot_legend_item.html#a526803d997725b68ca96cc9b9f911d49',1,'QwtPlotLegendItem']]], + ['getabortkey',['getAbortKey',['../class_qwt_panner.html#ae50b8bc2a17a480a50f39ddb96128cad',1,'QwtPanner']]], + ['getborderdisthint',['getBorderDistHint',['../class_qwt_scale_draw.html#ab6c5d65a109b63b2dd62984d38a4df0e',1,'QwtScaleDraw::getBorderDistHint()'],['../class_qwt_scale_widget.html#a57ca1a6a87417a732e0b1e66ac2a3493',1,'QwtScaleWidget::getBorderDistHint()']]], + ['getcanvasmarginhint',['getCanvasMarginHint',['../class_qwt_plot_abstract_bar_chart.html#aade3c92c2fcbbfdef47b810cdb2d4d90',1,'QwtPlotAbstractBarChart::getCanvasMarginHint()'],['../class_qwt_plot_item.html#a46b0d88f7667e0e93dee5253c8be001f',1,'QwtPlotItem::getCanvasMarginHint()']]], + ['getcanvasmarginshint',['getCanvasMarginsHint',['../class_qwt_plot.html#aa1cd126530e6b9db28714476035487ac',1,'QwtPlot']]], + ['getminborderdist',['getMinBorderDist',['../class_qwt_scale_widget.html#a2927a7cb5157b86c580d7ebed4dc4e7c',1,'QwtScaleWidget']]], + ['getmousebutton',['getMouseButton',['../class_qwt_magnifier.html#afc4efee268edb053630283b067933998',1,'QwtMagnifier::getMouseButton()'],['../class_qwt_panner.html#af75b070c58163f106f50d311ad1af1d0',1,'QwtPanner::getMouseButton()']]], + ['getzoominkey',['getZoomInKey',['../class_qwt_magnifier.html#abf357e6493dba55f478fb89e4c312131',1,'QwtMagnifier']]], + ['getzoomoutkey',['getZoomOutKey',['../class_qwt_magnifier.html#a06ae0b904538c8d21e070212e007dbf3',1,'QwtMagnifier']]], + ['grab',['grab',['../class_qwt_panner.html#ad854755a61d2cb9c9666889bdbbe9859',1,'QwtPanner::grab()'],['../class_qwt_plot_panner.html#a03b494d36d5adbe1b05aa3acbbf37f8b',1,'QwtPlotPanner::grab()']]], + ['grabproperties',['grabProperties',['../class_qwt_plot.html#afd1c65720e19e50aa083dabd5bbf88e8',1,'QwtPlot']]], + ['graphic',['graphic',['../class_qwt_symbol.html#ad7f3af9937686813ffa9264d578a33f2',1,'QwtSymbol::graphic() const '],['../class_qwt_symbol.html#a62f457952470c2076962e83ef2c24d2faa24a49671ffa302f19f28a5c56c6ec0e',1,'QwtSymbol::Graphic()']]], + ['grouped',['Grouped',['../class_qwt_plot_multi_bar_chart.html#ac67e03008156171c2dd19de4a46eaceeac112d35b99385c204f4b4fc91c602e60',1,'QwtPlotMultiBarChart']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/all_68.html b/ThirdParty/Qwt/doc/html/search/all_68.html new file mode 100644 index 0000000000..dec41d62ef --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/all_68.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/all_68.js b/ThirdParty/Qwt/doc/html/search/all_68.js new file mode 100644 index 0000000000..fc7da0337d --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/all_68.js @@ -0,0 +1,25 @@ +var searchData= +[ + ['hackstyledbackground',['HackStyledBackground',['../class_qwt_plot_canvas.html#a76066290edb594a71ee09be564563b0fa2a2fee2c1807f8306850e15977bacb70',1,'QwtPlotCanvas']]], + ['hand',['Hand',['../class_qwt_analog_clock.html#acd8f7e963ae073120684de46821f2cfe',1,'QwtAnalogClock::Hand()'],['../class_qwt_analog_clock.html#ab390561b0856eef0d2bb80bdff0fb204',1,'QwtAnalogClock::hand(Hand) const '],['../class_qwt_analog_clock.html#abb93bf8255bc00ef160165385bb6adce',1,'QwtAnalogClock::hand(Hand)']]], + ['handlerect',['handleRect',['../class_qwt_slider.html#a69df4f26e88b911c0dcf28d41987550a',1,'QwtSlider']]], + ['handlesize',['handleSize',['../class_qwt_slider.html#a56cf54a5b406530e8d3a5986626ba000',1,'QwtSlider']]], + ['hasclipping',['hasClipping',['../class_qwt_plot_direct_painter.html#a8d6b8b273b4e74181cd7ed5fdaf0bb7e',1,'QwtPlotDirectPainter']]], + ['hascomponent',['hasComponent',['../class_qwt_abstract_scale_draw.html#a95d74d9eaa5520754295efb33a4db50f',1,'QwtAbstractScaleDraw']]], + ['hasgroove',['hasGroove',['../class_qwt_slider.html#aeb2f0f70d1fb6358022805e3f1a0ae9d',1,'QwtSlider']]], + ['hasheightforwidth',['hasHeightForWidth',['../class_qwt_dyn_grid_layout.html#ae8867d543d54d5da9657c55b3c329d8e',1,'QwtDynGridLayout']]], + ['hasrole',['hasRole',['../class_qwt_legend_data.html#ae615eb3d1a3d88cc25dc0ed6dea70a72',1,'QwtLegendData']]], + ['hastrough',['hasTrough',['../class_qwt_slider.html#a3ff426a41b4daa6406315cd302d59032',1,'QwtSlider']]], + ['heightforwidth',['heightForWidth',['../class_qwt_dyn_grid_layout.html#afa3fd53b485e9f1ed90796ff923466f1',1,'QwtDynGridLayout::heightForWidth()'],['../class_qwt_legend.html#a273ec258209c42f57b154ff4da61e1d0',1,'QwtLegend::heightForWidth()'],['../class_qwt_plot_legend_item.html#af4b16cf1966e4c2bc96ba173501ef66f',1,'QwtPlotLegendItem::heightForWidth()'],['../class_qwt_text.html#a29f7064fa8825d30e0b7b7b740d2df9f',1,'QwtText::heightForWidth()'],['../class_qwt_text_engine.html#aee891b14d90c817b8c73d551f623cc17',1,'QwtTextEngine::heightForWidth()'],['../class_qwt_plain_text_engine.html#a9190bdcb6ed447a5bc056ad8304ad58b',1,'QwtPlainTextEngine::heightForWidth()'],['../class_qwt_rich_text_engine.html#ab19cc5ad4ae33aaffc6aaf5d58b93b19',1,'QwtRichTextEngine::heightForWidth()'],['../class_qwt_text_label.html#ade1867a2c9308f2235cfacf675fa1d4c',1,'QwtTextLabel::heightForWidth()'],['../class_qwt_math_m_l_text_engine.html#a3d5b7c9be31d9282b4c86c8ec3f4c8df',1,'QwtMathMLTextEngine::heightForWidth()']]], + ['hexagon',['Hexagon',['../class_qwt_symbol.html#a62f457952470c2076962e83ef2c24d2fa8bf81a46e1ee93ea3d8d8c8990b72f36',1,'QwtSymbol']]], + ['hide',['hide',['../class_qwt_plot_item.html#a1faea017baa2492416a13e6bc3c144aa',1,'QwtPlotItem']]], + ['high',['high',['../class_qwt_o_h_l_c_sample.html#a4b23c1c6250364d4c58b6fc23ac1cdff',1,'QwtOHLCSample']]], + ['hinterval',['hInterval',['../class_qwt_column_rect.html#a16a24ece2aa70fc763d08e220608d63a',1,'QwtColumnRect']]], + ['histogram',['Histogram',['../histogramscreenshots.html',1,'']]], + ['histogramstyle',['HistogramStyle',['../class_qwt_plot_histogram.html#a3ba21c3aef994daf7b848ccf71b0dbc5',1,'QwtPlotHistogram']]], + ['hline',['HLine',['../class_qwt_plot_marker.html#a297efa835423bfa5a870bbc8ff1c623ba4439b2f358352a4cf6414b0ea4861609',1,'QwtPlotMarker::HLine()'],['../class_qwt_symbol.html#a62f457952470c2076962e83ef2c24d2fa3bc949e0e38ccaf908bb58c7c177f7f6',1,'QwtSymbol::HLine()']]], + ['hlinerubberband',['HLineRubberBand',['../class_qwt_picker.html#ab36c79d8ff20aba5b778d2823c1f7894a9f3ab0ea1294b4eb2cae7b919ce0ffb0',1,'QwtPicker']]], + ['horizontalscrollbar',['horizontalScrollBar',['../class_qwt_legend.html#a40dab44d47921da18a925e8fcc8d6870',1,'QwtLegend']]], + ['hour',['Hour',['../class_qwt_date.html#ad037b999a51cae4d9ab36bf8e7859587a8e7a2f91f89423e446bfdaa1e01ebd2f',1,'QwtDate']]], + ['hourhand',['HourHand',['../class_qwt_analog_clock.html#acd8f7e963ae073120684de46821f2cfea1e8f73f647c5a95ca062a8d63376982a',1,'QwtAnalogClock']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/all_69.html b/ThirdParty/Qwt/doc/html/search/all_69.html new file mode 100644 index 0000000000..192e4bab2a --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/all_69.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/all_69.js b/ThirdParty/Qwt/doc/html/search/all_69.js new file mode 100644 index 0000000000..9e05c222c6 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/all_69.js @@ -0,0 +1,87 @@ +var searchData= +[ + ['icon',['icon',['../class_qwt_legend_data.html#a3a4e20d33c2eb8bec1e8ef9b943de74c',1,'QwtLegendData::icon()'],['../class_qwt_legend_label.html#a6fc6cdbd1b4b9db2de354cbe533e1c2a',1,'QwtLegendLabel::icon()']]], + ['ignoreallverticesonlevel',['IgnoreAllVerticesOnLevel',['../class_qwt_raster_data.html#ac0053b66315fde6f0a9a69c40d7c5dccafd2f6337e825201a247408f033713c92',1,'QwtRasterData']]], + ['ignorefooter',['IgnoreFooter',['../class_qwt_plot_layout.html#ad0d2d60e86a4c69ec105524041d5221da132d4fc728c0826a269a143f2d655215',1,'QwtPlotLayout']]], + ['ignoreframes',['IgnoreFrames',['../class_qwt_plot_layout.html#ad0d2d60e86a4c69ec105524041d5221da9036bf7de40018a2f12d456a04949c6b',1,'QwtPlotLayout']]], + ['ignorelegend',['IgnoreLegend',['../class_qwt_plot_layout.html#ad0d2d60e86a4c69ec105524041d5221daa7237e2be1e8fc41a8b3156b57b95ed3',1,'QwtPlotLayout']]], + ['ignoreoutofrange',['IgnoreOutOfRange',['../class_qwt_raster_data.html#ac0053b66315fde6f0a9a69c40d7c5dcca18e8d1de171dd43cc957c279eb03d32c',1,'QwtRasterData']]], + ['ignorescrollbars',['IgnoreScrollbars',['../class_qwt_plot_layout.html#ad0d2d60e86a4c69ec105524041d5221da813736a8e614f8f24db773081642b74c',1,'QwtPlotLayout']]], + ['ignoretitle',['IgnoreTitle',['../class_qwt_plot_layout.html#ad0d2d60e86a4c69ec105524041d5221da00feaacfa819204f09074fc9b128b22c',1,'QwtPlotLayout']]], + ['image',['Image',['../class_qwt_painter_command.html#a6619a454c4332c02412611467935b7baab7dfdaa4ca3c9e6d57bdb27f5dd27669',1,'QwtPainterCommand']]], + ['imagebuffer',['ImageBuffer',['../class_qwt_plot_curve.html#a96db1b854c63bfbc452c943251a11b66a5e80434a35db4325ef8cdcb4dcb52282',1,'QwtPlotCurve']]], + ['imagedata',['imageData',['../class_qwt_painter_command.html#acb12c36d4b9df791bd4f2089e6c147d9',1,'QwtPainterCommand::imageData()'],['../class_qwt_painter_command.html#a60eed873d4177b3ebf3180ddf3893b3e',1,'QwtPainterCommand::imageData() const ']]], + ['imagemap',['imageMap',['../class_qwt_plot_raster_item.html#a9feb834f9e40cdff11d8cd6ad74fda10',1,'QwtPlotRasterItem']]], + ['imagemode',['ImageMode',['../class_qwt_plot_spectrogram.html#a7f4904fe68b442d0f93040ea1fa1d062ac9696cad413e4a11a4721779728fb9e3',1,'QwtPlotSpectrogram']]], + ['immediatepaint',['ImmediatePaint',['../class_qwt_plot_canvas.html#a76066290edb594a71ee09be564563b0fa91fb95b7ec380cc5d517195c2ae6368f',1,'QwtPlotCanvas']]], + ['includeborders',['IncludeBorders',['../class_qwt_interval.html#a3a4b4e49495108c660fc07a62af7ac54ad8a550b5eb1062cd84bcba22c60e5e60',1,'QwtInterval']]], + ['includereference',['IncludeReference',['../class_qwt_scale_engine.html#a7548418e0896d75eec164bfa2ba3ff5fad29dea0ac58c4675ac009620b0857984',1,'QwtScaleEngine']]], + ['increasing',['Increasing',['../class_qwt_plot_trading_curve.html#ab9136d2f1a4dc34dd09a0c03e809b4afa0d39ddffe160060a5c99ff5324d227d8',1,'QwtPlotTradingCurve']]], + ['incrementedvalue',['incrementedValue',['../class_qwt_abstract_slider.html#af4ee11b0a966af2d9fbd9feb240cb857',1,'QwtAbstractSlider']]], + ['incrementvalue',['incrementValue',['../class_qwt_abstract_slider.html#aa31fe73942c4cae17bce9e5cae36bd55',1,'QwtAbstractSlider']]], + ['incsteps',['incSteps',['../class_qwt_counter.html#a9c81b37e547358cc588311d941649de1',1,'QwtCounter']]], + ['indent',['indent',['../class_qwt_text_label.html#a56d1c5c770efd4f829f33d0b42f00c9b',1,'QwtTextLabel']]], + ['index',['index',['../class_qwt_pixel_matrix.html#a786989b4ff383d7939edbba31c89178d',1,'QwtPixelMatrix']]], + ['indexed',['Indexed',['../class_qwt_color_map.html#a9e5570790910fa3894887bca7dc5a670a304cb055c004223ca77f1a4cbbf27ea2',1,'QwtColorMap']]], + ['infotoitem',['infoToItem',['../class_qwt_plot.html#a067fb3bbf8fb60921831bad7066605dc',1,'QwtPlot']]], + ['init',['init',['../class_qwt_plot_curve.html#a7afecd61327d56ddc76687d119e92b5d',1,'QwtPlotCurve::init()'],['../class_qwt_plot_interval_curve.html#a98d9de9cc61e59e24d72e4f459b4b321',1,'QwtPlotIntervalCurve::init()'],['../class_qwt_plot_trading_curve.html#a9fdb6082069ae913ed988137da1d57dd',1,'QwtPlotTradingCurve::init()']]], + ['initkeypattern',['initKeyPattern',['../class_qwt_event_pattern.html#a91c1acb96b5c3849b9518206290f7da8',1,'QwtEventPattern']]], + ['initmousepattern',['initMousePattern',['../class_qwt_event_pattern.html#ab885e0f266fd5b574ccbc6272225f486',1,'QwtEventPattern']]], + ['initraster',['initRaster',['../class_qwt_raster_data.html#a64f5bf40b6138cc66719a56555c03589',1,'QwtRasterData']]], + ['innerrect',['innerRect',['../class_qwt_dial.html#a258643394b1fb9b02ecd573d49a2abb6',1,'QwtDial']]], + ['insertitem',['insertItem',['../class_qwt_plot_dict.html#a36a00709420eb4f54b046e64561d5186',1,'QwtPlotDict']]], + ['insertlegend',['insertLegend',['../class_qwt_plot.html#a022a535ad11bebeaf9204a4fb8c4c430',1,'QwtPlot']]], + ['intersect',['intersect',['../class_qwt_interval.html#aa4df23450ffa012e1fedd13509402483',1,'QwtInterval']]], + ['intersects',['intersects',['../class_qwt_interval.html#a46a768a591a9a600f9885bd15a60da5b',1,'QwtInterval']]], + ['interval',['interval',['../class_qwt_interval_sample.html#a264492c8f0ad3cec0b9d4d58b9a97236',1,'QwtIntervalSample::interval()'],['../class_qwt_plot_raster_item.html#a0ffa377f71d05a0d3d077e040b08c357',1,'QwtPlotRasterItem::interval()'],['../class_qwt_plot_rescaler.html#a52a1d762ba0add0a49c632a735d624c1',1,'QwtPlotRescaler::interval()'],['../class_qwt_plot_spectrogram.html#a958a45464b5946aff31b7d28b7cfb5f9',1,'QwtPlotSpectrogram::interval()'],['../class_qwt_plot_zone_item.html#ac35ff886b2313394fee77b2126d59d1a',1,'QwtPlotZoneItem::interval()'],['../class_qwt_synthetic_point_data.html#acd5ffffb670778cfd714bc915615851e',1,'QwtSyntheticPointData::interval()'],['../class_qwt_raster_data.html#a8423d051697f975150b3b555bfcac8b9',1,'QwtRasterData::interval()'],['../class_qwt_sampling_thread.html#a4a2f5038c02c8cad5ebc1fae01480e73',1,'QwtSamplingThread::interval()'],['../class_qwt_scale_div.html#a00fa69fed58c7a8ce6c855bb4df799f0',1,'QwtScaleDiv::interval()']]], + ['intervalhint',['intervalHint',['../class_qwt_plot_rescaler.html#a9bd02f1786d7503bd0d3e973799739ce',1,'QwtPlotRescaler']]], + ['intervaltype',['intervalType',['../class_qwt_date_scale_draw.html#a7afcabca6cedf6f764a3a853eb143e1a',1,'QwtDateScaleDraw::intervalType()'],['../class_qwt_date_scale_engine.html#ab813083a22cd7e001bd68c9e2a9685bc',1,'QwtDateScaleEngine::intervalType()'],['../class_qwt_date.html#ad037b999a51cae4d9ab36bf8e7859587',1,'QwtDate::IntervalType()']]], + ['invalid',['Invalid',['../class_qwt_painter_command.html#a6619a454c4332c02412611467935b7baa501f44c9ca82165fd3c76fd3f50d07dd',1,'QwtPainterCommand']]], + ['invalidate',['invalidate',['../class_qwt_dyn_grid_layout.html#acb55e24d5bc569c9822110d538e3a82e',1,'QwtDynGridLayout::invalidate()'],['../class_qwt_interval.html#a66c1d4ed7836dfbf3c6e851479ff32cf',1,'QwtInterval::invalidate()'],['../class_qwt_plot_layout.html#a44ce72879951571ffe4daa95be0ec242',1,'QwtPlotLayout::invalidate()']]], + ['invalidatebackingstore',['invalidateBackingStore',['../class_qwt_plot_canvas.html#adafbfa908b2d3b6cf9c20aa6cf9abe27',1,'QwtPlotCanvas']]], + ['invalidatecache',['invalidateCache',['../class_qwt_abstract_scale_draw.html#a4ed95cd23c5d779c1b05aa5295409aa6',1,'QwtAbstractScaleDraw::invalidateCache()'],['../class_qwt_dial.html#a8308ea7345348c683cd957de2ef5ca91',1,'QwtDial::invalidateCache()'],['../class_qwt_plot_raster_item.html#a547ce4d8d031b230226cfbd509ef65b5',1,'QwtPlotRasterItem::invalidateCache()'],['../class_qwt_plot_text_label.html#ac498a144d548eddd4209da5979815c76',1,'QwtPlotTextLabel::invalidateCache()'],['../class_qwt_symbol.html#a781dee5e5db701df592378eb71d84088',1,'QwtSymbol::invalidateCache()']]], + ['invert',['invert',['../class_qwt_scale_div.html#a1ea38d52d5836fd4376f480180973786',1,'QwtScaleDiv']]], + ['inverted',['inverted',['../class_qwt_interval.html#ac55c2cc97b9f7973cb3fab4536f48486',1,'QwtInterval::inverted()'],['../class_qwt_scale_div.html#a3e35d44b9b41656fb3b241a9b11ddaa4',1,'QwtScaleDiv::inverted()'],['../class_qwt_plot_curve.html#a38064f7de6f026a49db782c365f872c3af7790b4716576fd0641ec393f476bc46',1,'QwtPlotCurve::Inverted()'],['../class_qwt_scale_engine.html#a7548418e0896d75eec164bfa2ba3ff5fa2f3985208684d394319320b8e67ea062',1,'QwtScaleEngine::Inverted()']]], + ['invertedcontrols',['invertedControls',['../class_qwt_abstract_slider.html#a3bc58490cd1f5a8ed5e86dec2a60586a',1,'QwtAbstractSlider']]], + ['invtransform',['invTransform',['../class_qwt_abstract_scale.html#a7907d116b784dea443ba50c43113c053',1,'QwtAbstractScale::invTransform()'],['../class_qwt_plot.html#ab98066e62e3a9f574f8f1d482974ef5c',1,'QwtPlot::invTransform()'],['../class_qwt_plot_picker.html#a259fb95f14eef08b24ba454d9b51d084',1,'QwtPlotPicker::invTransform(const QRect &) const '],['../class_qwt_plot_picker.html#a0e02acfa2bed42ab691bc0a50d39727b',1,'QwtPlotPicker::invTransform(const QPoint &) const '],['../class_qwt_scale_map.html#a9f973f23b61ed18dd7598255078bd837',1,'QwtScaleMap::invTransform(double p) const '],['../class_qwt_scale_map.html#a8fe572f224a14672684fd929c55568f8',1,'QwtScaleMap::invTransform(const QwtScaleMap &, const QwtScaleMap &, const QRectF &)'],['../class_qwt_scale_map.html#a08dc05a17283c531e2c1d79fd52bc56a',1,'QwtScaleMap::invTransform(const QwtScaleMap &, const QwtScaleMap &, const QPointF &)'],['../class_qwt_transform.html#a5cfb0a329b8418028baf6974b188d76b',1,'QwtTransform::invTransform()'],['../class_qwt_null_transform.html#aa52cc18dcd1d0cd37a950fb71ef68a1c',1,'QwtNullTransform::invTransform()'],['../class_qwt_log_transform.html#a7c9e1e11e9708aecef2df4dac0c7d56b',1,'QwtLogTransform::invTransform()'],['../class_qwt_power_transform.html#aae19e2002b08ab09ed177d8ff6753f82',1,'QwtPowerTransform::invTransform()']]], + ['isactive',['isActive',['../class_qwt_picker.html#af825f383c74928d1541f139e102983f9',1,'QwtPicker']]], + ['isaligning',['isAligning',['../class_qwt_painter.html#a5d62fd1bd470fa0d42b7b2e06504a581',1,'QwtPainter']]], + ['isaxisenabled',['isAxisEnabled',['../class_qwt_plot_magnifier.html#acb4c33465bdd3c19c07ea3fa836c1f8d',1,'QwtPlotMagnifier::isAxisEnabled()'],['../class_qwt_plot_panner.html#a30fc7de4bede9f191a96df42f86e704b',1,'QwtPlotPanner::isAxisEnabled()']]], + ['ischecked',['isChecked',['../class_qwt_legend_label.html#a60e810de6309544227293b70a2f225ce',1,'QwtLegendLabel']]], + ['iscolorbarenabled',['isColorBarEnabled',['../class_qwt_scale_widget.html#a0572bc26f5b99654067b916001bce582',1,'QwtScaleWidget']]], + ['isdown',['isDown',['../class_qwt_legend_label.html#a1693d4581c50054acdcf8c810548e6b0',1,'QwtLegendLabel']]], + ['isempty',['isEmpty',['../class_qwt_abstract_legend.html#a9904720ba92daf03d0e5d8559cc5cdfe',1,'QwtAbstractLegend::isEmpty()'],['../class_qwt_dyn_grid_layout.html#a755f41277b43417d6b719704dc2c0d29',1,'QwtDynGridLayout::isEmpty()'],['../class_qwt_graphic.html#ab733c7e707f29adc80676059ade5de50',1,'QwtGraphic::isEmpty()'],['../class_qwt_legend.html#a6ff50cb1e388a7da2a59709eef83be20',1,'QwtLegend::isEmpty()'],['../class_qwt_scale_div.html#a76e4ef37b52fcf224de98a913635fdf6',1,'QwtScaleDiv::isEmpty()'],['../class_qwt_text.html#a25843b1120b648752ed5be2247ebe43f',1,'QwtText::isEmpty()']]], + ['isenabled',['isEnabled',['../class_qwt_magnifier.html#a65552cac613ceac77e51b8deca522509',1,'QwtMagnifier::isEnabled()'],['../class_qwt_panner.html#a7b0bae829d1ee12208ab8722d52d15a1',1,'QwtPanner::isEnabled()'],['../class_qwt_picker.html#a984299a27421d57291bb84c8c08df4e5',1,'QwtPicker::isEnabled()'],['../class_qwt_plot_rescaler.html#afdafabbb963aa5b13ce4a6bae33958da',1,'QwtPlotRescaler::isEnabled()']]], + ['isincreasing',['isIncreasing',['../class_qwt_scale_div.html#ab4623880c2c2f789fdc3a9f5e6058484',1,'QwtScaleDiv']]], + ['isinverted',['isInverted',['../class_qwt_abstract_scale.html#a3d46b81ff8b0ace8cc5b64a4984a63f6',1,'QwtAbstractScale::isInverted()'],['../class_qwt_wheel.html#ab48b28394d4bfedcc877cac45f2fd540',1,'QwtWheel::isInverted()']]], + ['isinverting',['isInverting',['../class_qwt_scale_map.html#aee1376468f91fa74715a0cad6cf1f6dc',1,'QwtScaleMap']]], + ['isnull',['isNull',['../class_qwt_graphic.html#a1b764ed0f9855aea3d7957e9bea54648',1,'QwtGraphic::isNull()'],['../class_qwt_interval.html#ac5e85b71e18fa43c92984e08c4549830',1,'QwtInterval::isNull()'],['../class_qwt_point3_d.html#a4542223c75e50afac7124cd44ca9c900',1,'QwtPoint3D::isNull()'],['../class_qwt_point_polar.html#a73d21f582ee5960011300598e17fab00',1,'QwtPointPolar::isNull()'],['../class_qwt_system_clock.html#a5432c09607488f9bb7e3d7592518efb1',1,'QwtSystemClock::isNull()'],['../class_qwt_text.html#afdf53f75d1b8ce6f2f0b00df59fa0177',1,'QwtText::isNull()']]], + ['isorientationenabled',['isOrientationEnabled',['../class_qwt_panner.html#ac1117576e69a4f32d24ef5ec81da7bbd',1,'QwtPanner']]], + ['ispinpointenabled',['isPinPointEnabled',['../class_qwt_symbol.html#aa0e0393dbd5df4f6a01c8a69ffc0203f',1,'QwtSymbol']]], + ['isreadonly',['isReadOnly',['../class_qwt_abstract_slider.html#a040fd1fd03592c524314bf4b5539608d',1,'QwtAbstractSlider::isReadOnly()'],['../class_qwt_counter.html#af6e5c64758c6b320a55e04fcb0188e67',1,'QwtCounter::isReadOnly()']]], + ['isscaledivfromaxis',['isScaleDivFromAxis',['../class_qwt_plot_scale_item.html#a05c89366c36fb0417e76b1a93d1ef93c',1,'QwtPlotScaleItem']]], + ['isscrollposition',['isScrollPosition',['../class_qwt_abstract_slider.html#ae674fc01201ec3ae4964838ef539c88e',1,'QwtAbstractSlider::isScrollPosition()'],['../class_qwt_dial.html#ab88967335d1269331b2e4b329a9a0ffe',1,'QwtDial::isScrollPosition()'],['../class_qwt_knob.html#ae82446b733a33dcbceee356683dff29c',1,'QwtKnob::isScrollPosition()'],['../class_qwt_slider.html#a01cce62d0609ebb6c95deb53d9f05785',1,'QwtSlider::isScrollPosition()']]], + ['istracking',['isTracking',['../class_qwt_abstract_slider.html#a476e7638818d5d22cb6f68d17d11ba97',1,'QwtAbstractSlider::isTracking()'],['../class_qwt_wheel.html#a2a8e72ae875c699d285698ae4fb79731',1,'QwtWheel::isTracking()']]], + ['isvalid',['isValid',['../class_qwt_abstract_slider.html#a87c750f098cb5f70306a7908339cb88e',1,'QwtAbstractSlider::isValid()'],['../class_qwt_counter.html#a0a6d0889d8d9e4fd956e4f3882fb319e',1,'QwtCounter::isValid()'],['../class_qwt_interval.html#af7ddb2347a4b5ed2205f84372e41c99e',1,'QwtInterval::isValid()'],['../class_qwt_legend_data.html#a4f77fc2e39d6187fb58aeb964049b4c6',1,'QwtLegendData::isValid()'],['../class_qwt_point_polar.html#ad1f8c93359d28322b6e3eeb9758a66f2',1,'QwtPointPolar::isValid()'],['../class_qwt_o_h_l_c_sample.html#a882c50b7c38caccb3486602a414dcd8e',1,'QwtOHLCSample::isValid()'],['../class_qwt_spline.html#a8eb42cf7f0f81bb7b7b885466f8ebbbf',1,'QwtSpline::isValid()']]], + ['isvisible',['isVisible',['../class_qwt_plot_item.html#aeaf8eeb5f080017e181a5d7be798d789',1,'QwtPlotItem']]], + ['isx11graphicssystem',['isX11GraphicsSystem',['../class_qwt_painter.html#af352ad92f1c1dc8cfee0f3d799e2e26e',1,'QwtPainter']]], + ['itemat',['itemAt',['../class_qwt_dyn_grid_layout.html#adbec8dc847c4159d0765c8f0dd80d148',1,'QwtDynGridLayout']]], + ['itemattached',['itemAttached',['../class_qwt_plot.html#a09e33984e3d5635475ef218ac0bd85eb',1,'QwtPlot']]], + ['itemattribute',['ItemAttribute',['../class_qwt_plot_item.html#ae0fabcdd35f4818ce5bbe019b0eed062',1,'QwtPlotItem']]], + ['itemattributes',['ItemAttributes',['../class_qwt_plot_item.html#af356dc13c7838c7437334e199a356764',1,'QwtPlotItem']]], + ['itembackground',['ItemBackground',['../class_qwt_plot_legend_item.html#a26f5e39bb332d42f9dde96fa788960ccad59a658b42182dab97057e923887e7c8',1,'QwtPlotLegendItem']]], + ['itemchanged',['itemChanged',['../class_qwt_plot_item.html#ad956fdbce5b0721abccce6d09fe4d5ce',1,'QwtPlotItem']]], + ['itemchecked',['itemChecked',['../class_qwt_legend.html#a19429ac46c36ca12531779099476ac8a',1,'QwtLegend']]], + ['itemclicked',['itemClicked',['../class_qwt_legend.html#a9e0e1b18a6d18b113802935bb6135921',1,'QwtLegend']]], + ['itemcount',['itemCount',['../class_qwt_dyn_grid_layout.html#ad7df7a3f47055041d6dd5ab1c4c660e0',1,'QwtDynGridLayout']]], + ['itemfocusindicator',['ItemFocusIndicator',['../class_qwt_plot_canvas.html#a89b44e4c28038a674ce211fe9ac2d7bea5a56f0e29a38350abdcef18c3e583115',1,'QwtPlotCanvas']]], + ['iteminfo',['itemInfo',['../class_qwt_legend.html#abd89da0c3ad3d9587ad35b63b424a73b',1,'QwtLegend']]], + ['iteminterest',['ItemInterest',['../class_qwt_plot_item.html#affbc42460ace9ac725fa825a3f8bfb66',1,'QwtPlotItem']]], + ['iteminterests',['ItemInterests',['../class_qwt_plot_item.html#a6a0c870664f074f342422859638c1228',1,'QwtPlotItem']]], + ['itemlist',['itemList',['../class_qwt_plot_dict.html#a9cbb1c5c22de93594b7e2524af108f55',1,'QwtPlotDict::itemList() const '],['../class_qwt_plot_dict.html#a0979adc53ad5ecf5e4a93aa9b5a4df38',1,'QwtPlotDict::itemList(int rtti) const ']]], + ['itemmargin',['itemMargin',['../class_qwt_plot_legend_item.html#a7024ac39e0a9ce5b003089191c78b93d',1,'QwtPlotLegendItem']]], + ['itemmode',['itemMode',['../class_qwt_legend_label.html#a2c9266255b3d1cf1fb95394e62bc6cc2',1,'QwtLegendLabel']]], + ['itemspacing',['itemSpacing',['../class_qwt_plot_legend_item.html#a2a57286be83056770ec7971ff885e393',1,'QwtPlotLegendItem']]], + ['itemtoinfo',['itemToInfo',['../class_qwt_plot.html#a8f12d09af448489f705faecdaee5d8c2',1,'QwtPlot']]], + ['installing_20qwt',['Installing Qwt',['../qwtinstall.html',1,'']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/all_6a.html b/ThirdParty/Qwt/doc/html/search/all_6a.html new file mode 100644 index 0000000000..6d8c91cd3a --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/all_6a.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/all_6a.js b/ThirdParty/Qwt/doc/html/search/all_6a.js new file mode 100644 index 0000000000..2913a65112 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/all_6a.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['juliandayforepoch',['JulianDayForEpoch',['../class_qwt_date.html#af636fffdebea2e4463fc32461b1217e0aed8ee8f3dbc5b7a5e953b3ec51a79108',1,'QwtDate']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/all_6b.html b/ThirdParty/Qwt/doc/html/search/all_6b.html new file mode 100644 index 0000000000..d70dca0160 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/all_6b.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/all_6b.js b/ThirdParty/Qwt/doc/html/search/all_6b.js new file mode 100644 index 0000000000..3b750e1df0 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/all_6b.js @@ -0,0 +1,26 @@ +var searchData= +[ + ['keepsize',['KeepSize',['../class_qwt_picker.html#ab3c894deed026f392496dd07809a6fd3ae873df582534c398b2f753763b0eb780',1,'QwtPicker']]], + ['key',['key',['../class_qwt_event_pattern_1_1_key_pattern.html#af13072b058c3abbb591450b82f049dd6',1,'QwtEventPattern::KeyPattern']]], + ['keyabort',['KeyAbort',['../class_qwt_event_pattern.html#a8fb57ceb9982d5583a1bf568e37d3007a5b73ad3186285f5aaf2030a50a3fb5a4',1,'QwtEventPattern']]], + ['keydown',['KeyDown',['../class_qwt_event_pattern.html#a8fb57ceb9982d5583a1bf568e37d3007a00c2d782ca962ee6bcda1c4a3649d1e7',1,'QwtEventPattern']]], + ['keyfactor',['keyFactor',['../class_qwt_magnifier.html#a98706c848275b06d2830a8dbe053c9a3',1,'QwtMagnifier']]], + ['keyhome',['KeyHome',['../class_qwt_event_pattern.html#a8fb57ceb9982d5583a1bf568e37d3007a4cba7de2850f874988cbaa38a236ecb2',1,'QwtEventPattern']]], + ['keyleft',['KeyLeft',['../class_qwt_event_pattern.html#a8fb57ceb9982d5583a1bf568e37d3007abaf3cd86d773c8e47a2c670b65d6ec95',1,'QwtEventPattern']]], + ['keymatch',['keyMatch',['../class_qwt_event_pattern.html#ab4be2d84b3d73ff05d6c19f6fd9f75bc',1,'QwtEventPattern::keyMatch(KeyPatternCode, const QKeyEvent *) const '],['../class_qwt_event_pattern.html#ac2748e712cbfa8ce9eb12a3364b862de',1,'QwtEventPattern::keyMatch(const KeyPattern &, const QKeyEvent *) const ']]], + ['keypattern',['KeyPattern',['../class_qwt_event_pattern_1_1_key_pattern.html',1,'QwtEventPattern']]], + ['keypattern',['KeyPattern',['../class_qwt_event_pattern_1_1_key_pattern.html#ac52d2d39d519c750194462c8da4c8ec2',1,'QwtEventPattern::KeyPattern::KeyPattern()'],['../class_qwt_event_pattern.html#a3c8dfef92d0808da60d0f7b094ba7f26',1,'QwtEventPattern::keyPattern() const '],['../class_qwt_event_pattern.html#a9d8ea5b5ffea570c1fed4c8ca8e5cfff',1,'QwtEventPattern::keyPattern()']]], + ['keypatterncode',['KeyPatternCode',['../class_qwt_event_pattern.html#a8fb57ceb9982d5583a1bf568e37d3007',1,'QwtEventPattern']]], + ['keypatterncount',['KeyPatternCount',['../class_qwt_event_pattern.html#a8fb57ceb9982d5583a1bf568e37d3007aca9b018d7ae0f2342779e91df7ddcdd3',1,'QwtEventPattern']]], + ['keypressevent',['keyPressEvent',['../class_qwt_abstract_slider.html#ab6d1105f82e8a44ea75661135ba88c85',1,'QwtAbstractSlider::keyPressEvent()'],['../class_qwt_arrow_button.html#a17612daa99344272c4de1313a5c67b02',1,'QwtArrowButton::keyPressEvent()'],['../class_qwt_compass.html#ad4f31e6837ea045834fe67d192a4209d',1,'QwtCompass::keyPressEvent()'],['../class_qwt_counter.html#aafdc19bff96fcafc4b8ed8e3bf7bf07b',1,'QwtCounter::keyPressEvent()'],['../class_qwt_legend_label.html#a801059fdc196563ca28fd22fb3675024',1,'QwtLegendLabel::keyPressEvent()'],['../class_qwt_wheel.html#a29c6b09213126e9e14c853e13108e262',1,'QwtWheel::keyPressEvent()']]], + ['keyredo',['KeyRedo',['../class_qwt_event_pattern.html#a8fb57ceb9982d5583a1bf568e37d3007a2c8d72876cd9435ee018e9cf8fa2ff26',1,'QwtEventPattern']]], + ['keyreleaseevent',['keyReleaseEvent',['../class_qwt_legend_label.html#aed12dffa845db6538f15cb45077cfb76',1,'QwtLegendLabel']]], + ['keyright',['KeyRight',['../class_qwt_event_pattern.html#a8fb57ceb9982d5583a1bf568e37d3007a607bbbf235ba79f6e36a25c6d7d27c53',1,'QwtEventPattern']]], + ['keyselect1',['KeySelect1',['../class_qwt_event_pattern.html#a8fb57ceb9982d5583a1bf568e37d3007a32afc68b8e31079c00666a251d0b9c25',1,'QwtEventPattern']]], + ['keyselect2',['KeySelect2',['../class_qwt_event_pattern.html#a8fb57ceb9982d5583a1bf568e37d3007acfd4f64d5b3b29214e51afcc56ea7eaf',1,'QwtEventPattern']]], + ['keyundo',['KeyUndo',['../class_qwt_event_pattern.html#a8fb57ceb9982d5583a1bf568e37d3007a76cf851373169fbc588109c1eccca33a',1,'QwtEventPattern']]], + ['keyup',['KeyUp',['../class_qwt_event_pattern.html#a8fb57ceb9982d5583a1bf568e37d3007a010af73c06629f6c53daf69fad5b6efe',1,'QwtEventPattern']]], + ['knobrect',['knobRect',['../class_qwt_knob.html#ad4bf9ef0988ac377577b21319e498231',1,'QwtKnob']]], + ['knobstyle',['knobStyle',['../class_qwt_knob.html#a6f8ec8b610b500990dff31f370cab8ba',1,'QwtKnob::knobStyle() const '],['../class_qwt_knob.html#addd00357b45752377aec83a3ab7208be',1,'QwtKnob::KnobStyle()']]], + ['knobwidth',['knobWidth',['../class_qwt_knob.html#aa9470eed740c7175c7ccfc4406eb5fc2',1,'QwtKnob']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/all_6c.html b/ThirdParty/Qwt/doc/html/search/all_6c.html new file mode 100644 index 0000000000..ae8bc48da3 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/all_6c.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/all_6c.js b/ThirdParty/Qwt/doc/html/search/all_6c.js new file mode 100644 index 0000000000..ba2e7a5c59 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/all_6c.js @@ -0,0 +1,66 @@ +var searchData= +[ + ['label',['label',['../class_qwt_abstract_scale_draw.html#a4ff88bc827dd6c6ca9298de13483b61f',1,'QwtAbstractScaleDraw::label()'],['../class_qwt_compass_scale_draw.html#acb6bfc20d538242fec35b6902dcb8ab1',1,'QwtCompassScaleDraw::label()'],['../class_qwt_date_scale_draw.html#a16207bc20afaaf6959f11cf0343da82c',1,'QwtDateScaleDraw::label()'],['../class_qwt_plot_marker.html#acf81c4a657fd772cf7c5387a19ab6793',1,'QwtPlotMarker::label()']]], + ['labelalignment',['labelAlignment',['../class_qwt_plot_marker.html#a16415f05a235642e2b93df9e4685d68e',1,'QwtPlotMarker::labelAlignment()'],['../class_qwt_scale_draw.html#ad024fd550ecc3816ee8886417794aae2',1,'QwtScaleDraw::labelAlignment()']]], + ['labelmap',['labelMap',['../class_qwt_compass_scale_draw.html#a92c0f162873b8ccd7bcf814f82b39819',1,'QwtCompassScaleDraw']]], + ['labelorientation',['labelOrientation',['../class_qwt_plot_marker.html#ab3be191bccfa7e668cc2ae8303c43c18',1,'QwtPlotMarker']]], + ['labelposition',['labelPosition',['../class_qwt_scale_draw.html#af0993dc0226ca63a2994f48ef6198c48',1,'QwtScaleDraw']]], + ['labelrect',['labelRect',['../class_qwt_arrow_button.html#ae32f665bfa6ab478e4ba7fd068bb3088',1,'QwtArrowButton::labelRect()'],['../class_qwt_scale_draw.html#a61ed70aef675f8694b4888f02c8ae83c',1,'QwtScaleDraw::labelRect()']]], + ['labelrotation',['labelRotation',['../class_qwt_scale_draw.html#a614f18b99f53e6a6282c39f95388face',1,'QwtScaleDraw']]], + ['labels',['Labels',['../class_qwt_abstract_scale_draw.html#a26215d06a4d48adf401d0aa05d4193c5ad2709d7efbb6f1618f0a8a3b6cafae96',1,'QwtAbstractScaleDraw']]], + ['labelsize',['labelSize',['../class_qwt_scale_draw.html#a49352345ab223395b7ff95c82b92c819',1,'QwtScaleDraw']]], + ['labeltransformation',['labelTransformation',['../class_qwt_scale_draw.html#a0efa1e4675c85b3187aa69220d135dc4',1,'QwtScaleDraw']]], + ['layoutattribute',['LayoutAttribute',['../class_qwt_text.html#a0953aabc098f410dba89bbada47f2e5a',1,'QwtText']]], + ['layoutattributes',['LayoutAttributes',['../class_qwt_text.html#aadd451b81d506c5bbefdddb8a100b9a3',1,'QwtText']]], + ['layoutflag',['LayoutFlag',['../class_qwt_plot_renderer.html#a111b4db55d3f620a33e75f6b398e4b4a',1,'QwtPlotRenderer::LayoutFlag()'],['../class_qwt_scale_widget.html#a95903255246c9da84e7388b567354c8f',1,'QwtScaleWidget::LayoutFlag()']]], + ['layoutflags',['layoutFlags',['../class_qwt_plot_renderer.html#a0989c9a2b03069418d1f097d14dd1b0b',1,'QwtPlotRenderer::layoutFlags() const '],['../class_qwt_plot_renderer.html#a20cf36bbea6b03a023d34c25b8b4b295',1,'QwtPlotRenderer::LayoutFlags()'],['../class_qwt_scale_widget.html#a19dcd8adcfd10fe26e021fa47e22b843',1,'QwtScaleWidget::LayoutFlags()']]], + ['layoutgrid',['layoutGrid',['../class_qwt_dyn_grid_layout.html#aab4aede7957a5a84403cb88da387d8dc',1,'QwtDynGridLayout']]], + ['layouthint',['layoutHint',['../class_qwt_plot_abstract_bar_chart.html#a0fad5758160f0a84467771c44cd88675',1,'QwtPlotAbstractBarChart']]], + ['layoutitems',['layoutItems',['../class_qwt_dyn_grid_layout.html#a0fe5c2a70d1086036fac2487cc982341',1,'QwtDynGridLayout']]], + ['layoutlegend',['layoutLegend',['../class_qwt_plot_layout.html#ae5eebbda9691833dfb5d2aa6a193f131',1,'QwtPlotLayout']]], + ['layoutpolicy',['layoutPolicy',['../class_qwt_plot_abstract_bar_chart.html#a940affbba9565ae4e5b2a6d61ef1cd8c',1,'QwtPlotAbstractBarChart::layoutPolicy() const '],['../class_qwt_plot_abstract_bar_chart.html#ae1db0e1606747ef46c863c54c210e53a',1,'QwtPlotAbstractBarChart::LayoutPolicy()']]], + ['layoutscale',['layoutScale',['../class_qwt_scale_widget.html#a5964a55d1572ea775eae3ca93a755358',1,'QwtScaleWidget']]], + ['leadingscale',['LeadingScale',['../class_qwt_slider.html#a120d984d7c519578eed88c4fe97cb1a7a0822eb6df854223a53d2ff95d6070c5d',1,'QwtSlider::LeadingScale()'],['../class_qwt_thermo.html#a4d7af32d29d1cc18e23b9143cf7ad498acda60ddfe6178199553941b75ad927a0',1,'QwtThermo::LeadingScale()']]], + ['leftlegend',['LeftLegend',['../class_qwt_plot.html#a31aacb65b5c049dde8c34a0d8482661ba38b51536a196582bd1f7658c0828eb18',1,'QwtPlot']]], + ['leftscale',['LeftScale',['../class_qwt_scale_draw.html#acd7ceeeac592ef08530788580b461c66af2a8239964381f18dbd08d4a93a7fa23',1,'QwtScaleDraw']]], + ['lefttoright',['LeftToRight',['../class_qwt_column_rect.html#a70bb2c6f1f8dabe3bc00793740e0908ba3cde7a99f22f5d897ed4b963731256a6',1,'QwtColumnRect']]], + ['legend',['Legend',['../class_qwt_plot_item.html#ae0fabcdd35f4818ce5bbe019b0eed062a4e377b54bd879c60a95162b6a9e9e176',1,'QwtPlotItem::Legend()'],['../class_qwt_plot.html#ab45dd6bc980376d0ba648fefb87103f8',1,'QwtPlot::legend()'],['../class_qwt_plot.html#aa82dbb3bae37e660a7707640b99ca29e',1,'QwtPlot::legend() const ']]], + ['legendattribute',['LegendAttribute',['../class_qwt_plot_curve.html#a6c1ac1ca99c06598c4044dd2ceeb9fd7',1,'QwtPlotCurve']]], + ['legendattributes',['LegendAttributes',['../class_qwt_plot_curve.html#aa9b27e27ddc27466eed70485e690daa6',1,'QwtPlotCurve']]], + ['legendbackground',['LegendBackground',['../class_qwt_plot_legend_item.html#a26f5e39bb332d42f9dde96fa788960cca638235bb73b0f3b34d0aba92842ec8e1',1,'QwtPlotLegendItem']]], + ['legendbartitles',['LegendBarTitles',['../class_qwt_plot_bar_chart.html#a5648ff170b563218111d022993b1d6a3a1d24c89de2f25180a0814d80f8b54c8e',1,'QwtPlotBarChart']]], + ['legendchanged',['legendChanged',['../class_qwt_plot_item.html#a3967414c7542e267d0c2793f02be7241',1,'QwtPlotItem']]], + ['legendcharttitle',['LegendChartTitle',['../class_qwt_plot_bar_chart.html#a5648ff170b563218111d022993b1d6a3afff608b4bdd6b57ab86204c13d58f504',1,'QwtPlotBarChart']]], + ['legendcolor',['LegendColor',['../class_qwt_plot_shape_item.html#a2cf398a73f125044df9b83ba421c47cda5798347f022bcd9f66c0bb2c8a9534c3',1,'QwtPlotShapeItem']]], + ['legenddata',['legendData',['../class_qwt_plot_bar_chart.html#aab363d4fbe516f7e2db3796a93745e83',1,'QwtPlotBarChart::legendData()'],['../class_qwt_plot_item.html#a584b37b42cb2c63424cedade1f4d7221',1,'QwtPlotItem::legendData()'],['../class_qwt_plot_multi_bar_chart.html#aaa178e1310e20219976db52c8beea2e5',1,'QwtPlotMultiBarChart::legendData()']]], + ['legenddatachanged',['legendDataChanged',['../class_qwt_plot.html#acf7bcea83713f73e5914325c50a1c22b',1,'QwtPlot']]], + ['legendgeometries',['legendGeometries',['../class_qwt_plot_legend_item.html#aca33e96eaa79ad4e220a52c9c25fa224',1,'QwtPlotLegendItem']]], + ['legendicon',['legendIcon',['../class_qwt_plot_bar_chart.html#a9563e64873ecf0589adae350b0ba5240',1,'QwtPlotBarChart::legendIcon()'],['../class_qwt_plot_curve.html#a2ac863876e1e2a7f30f6d4fbc9ca677e',1,'QwtPlotCurve::legendIcon()'],['../class_qwt_plot_histogram.html#a541b2532b9437979b35f78a44ac5ff3e',1,'QwtPlotHistogram::legendIcon()'],['../class_qwt_plot_interval_curve.html#ac7ad3b7a2a70aef77c15a75101c36bf4',1,'QwtPlotIntervalCurve::legendIcon()'],['../class_qwt_plot_item.html#ab192921c0d3c94832c6f617716a6b275',1,'QwtPlotItem::legendIcon()'],['../class_qwt_plot_marker.html#afd4de898e8615b6cec8c6f090b585c1b',1,'QwtPlotMarker::legendIcon()'],['../class_qwt_plot_multi_bar_chart.html#a9200443a4ff8b88041136b2292d63965',1,'QwtPlotMultiBarChart::legendIcon()'],['../class_qwt_plot_shape_item.html#aacaaf2fb5cc5011d0c7164a26c1af2df',1,'QwtPlotShapeItem::legendIcon()'],['../class_qwt_plot_trading_curve.html#ad88db48643d8119e8077a0b2c9dad0f1',1,'QwtPlotTradingCurve::legendIcon()']]], + ['legendiconsize',['legendIconSize',['../class_qwt_plot_item.html#a3239ad2b425382e153e80cc393dd4fc2',1,'QwtPlotItem']]], + ['legendinterest',['LegendInterest',['../class_qwt_plot_item.html#affbc42460ace9ac725fa825a3f8bfb66afcc4ef45e6613104ccc2b9f7988e4d22',1,'QwtPlotItem']]], + ['legendmode',['LegendMode',['../class_qwt_plot_bar_chart.html#a5648ff170b563218111d022993b1d6a3',1,'QwtPlotBarChart::LegendMode()'],['../class_qwt_plot_shape_item.html#a2cf398a73f125044df9b83ba421c47cd',1,'QwtPlotShapeItem::LegendMode()'],['../class_qwt_plot_bar_chart.html#a9caca23828aea1b5fb4907bb42f4cffb',1,'QwtPlotBarChart::legendMode()'],['../class_qwt_plot_shape_item.html#ad7a855b061225ffd312415c3ace9a0a0',1,'QwtPlotShapeItem::legendMode()']]], + ['legendnoattribute',['LegendNoAttribute',['../class_qwt_plot_curve.html#a6c1ac1ca99c06598c4044dd2ceeb9fd7a5ca8291c000cca41c082035610b08a67',1,'QwtPlotCurve']]], + ['legendposition',['legendPosition',['../class_qwt_plot_layout.html#a6351a18b76e22d9e83d682d203599afc',1,'QwtPlotLayout::legendPosition()'],['../class_qwt_plot.html#a31aacb65b5c049dde8c34a0d8482661b',1,'QwtPlot::LegendPosition()']]], + ['legendratio',['legendRatio',['../class_qwt_plot_layout.html#a6d5d4e568ad74010742e1fdcfc1c7672',1,'QwtPlotLayout']]], + ['legendrect',['legendRect',['../class_qwt_plot_layout.html#a638c809e0612ab1ee67d0f3a25600289',1,'QwtPlotLayout']]], + ['legendshape',['LegendShape',['../class_qwt_plot_shape_item.html#a2cf398a73f125044df9b83ba421c47cdac1d32e3ca5a234638e8bc46d2dd86e38',1,'QwtPlotShapeItem']]], + ['legendshowbrush',['LegendShowBrush',['../class_qwt_plot_curve.html#a6c1ac1ca99c06598c4044dd2ceeb9fd7a20cd7f91d61c44b05c49bffd930646be',1,'QwtPlotCurve']]], + ['legendshowline',['LegendShowLine',['../class_qwt_plot_curve.html#a6c1ac1ca99c06598c4044dd2ceeb9fd7a7eb8387acab6a10a95219634c97c266f',1,'QwtPlotCurve']]], + ['legendshowsymbol',['LegendShowSymbol',['../class_qwt_plot_curve.html#a6c1ac1ca99c06598c4044dd2ceeb9fd7a5902a8ff0c4c7f1080dd4e2bd5eb29be',1,'QwtPlotCurve']]], + ['legendwidget',['legendWidget',['../class_qwt_legend.html#a232dcbd75b79304983b92956b576a8a6',1,'QwtLegend']]], + ['legendwidgets',['legendWidgets',['../class_qwt_legend.html#a999f58842126639610f3131fdb750358',1,'QwtLegend']]], + ['length',['length',['../class_qwt_scale_draw.html#a82f2a2d25d4ecc2a781a252ef9515704',1,'QwtScaleDraw']]], + ['limited',['limited',['../class_qwt_interval.html#a7ba77698fdc61495ff4fbbaf3095184b',1,'QwtInterval']]], + ['linepen',['linePen',['../class_qwt_plot_marker.html#a744b2aa104fa41d2f09c6658749c2d72',1,'QwtPlotMarker']]], + ['lines',['Lines',['../class_qwt_plot_curve.html#a15998aa80a11ba6ba80eebabaf773f70a8914d88bcd5f680e7091469fed67c9ba',1,'QwtPlotCurve::Lines()'],['../class_qwt_plot_histogram.html#a3ba21c3aef994daf7b848ccf71b0dbc5a62b3af66b59203102394dbe1711a7a58',1,'QwtPlotHistogram::Lines()']]], + ['linestyle',['LineStyle',['../class_qwt_plot_marker.html#a297efa835423bfa5a870bbc8ff1c623b',1,'QwtPlotMarker::LineStyle()'],['../class_qwt_plot_marker.html#a9afac9382c6e482ea0181048b155e287',1,'QwtPlotMarker::lineStyle() const ']]], + ['linewidth',['lineWidth',['../class_qwt_column_symbol.html#afe6850ba90ade0fdf61edd203e49206d',1,'QwtColumnSymbol::lineWidth()'],['../class_qwt_dial.html#afb583edf70364eb562bf84686b60a9b7',1,'QwtDial::lineWidth()'],['../class_qwt_plot_g_l_canvas.html#af171f7b3727852df3062a975251eb976',1,'QwtPlotGLCanvas::lineWidth()']]], + ['loaddata',['loadData',['../class_qwt_plot_svg_item.html#a9e611f0c845289ddfb9758fa4479e719',1,'QwtPlotSvgItem']]], + ['loadfile',['loadFile',['../class_qwt_plot_svg_item.html#aca9592f3d3dca512b7970851b159cf57',1,'QwtPlotSvgItem']]], + ['logmax',['LogMax',['../class_qwt_log_transform.html#ae5b7d96e9a765986cf1fc4b4c1fc7915',1,'QwtLogTransform']]], + ['logmin',['LogMin',['../class_qwt_log_transform.html#ad16ce32a68b714955412dc8b1b8f6622',1,'QwtLogTransform']]], + ['low',['low',['../class_qwt_o_h_l_c_sample.html#aedac8489a18dfae092c010360c53ad7d',1,'QwtOHLCSample']]], + ['lowerbound',['lowerBound',['../class_qwt_abstract_scale.html#a093b44d00c18164c2814c3b999066dc7',1,'QwtAbstractScale::lowerBound()'],['../class_qwt_scale_div.html#a7b9b339170625553fbb488c7877372d0',1,'QwtScaleDiv::lowerBound()']]], + ['lowermargin',['lowerMargin',['../class_qwt_scale_engine.html#a0cbcd5c35a8796baf8307bba19991bab',1,'QwtScaleEngine']]], + ['ltriangle',['LTriangle',['../class_qwt_symbol.html#a62f457952470c2076962e83ef2c24d2fa228f6d48261e8b6bc9981370ae65f5e5',1,'QwtSymbol']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/all_6d.html b/ThirdParty/Qwt/doc/html/search/all_6d.html new file mode 100644 index 0000000000..ee90718ff2 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/all_6d.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/all_6d.js b/ThirdParty/Qwt/doc/html/search/all_6d.js new file mode 100644 index 0000000000..0ee40288ed --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/all_6d.js @@ -0,0 +1,75 @@ +var searchData= +[ + ['majorpen',['majorPen',['../class_qwt_plot_grid.html#a7a3ff3aed415e3f2315514ae798f433e',1,'QwtPlotGrid']]], + ['majortick',['MajorTick',['../class_qwt_scale_div.html#af21aedaa886dd5e067cf63505838736cadda390d4186a0ff20ece95d986c1ae60',1,'QwtScaleDiv']]], + ['margin',['margin',['../class_qwt_plot_abstract_bar_chart.html#af82ec574a3c6031d35c423b54afcfde6',1,'QwtPlotAbstractBarChart::margin()'],['../class_qwt_plot_legend_item.html#ac146ccfb6e0f3c85bed5d2a898a5ffc8',1,'QwtPlotLegendItem::margin()'],['../class_qwt_plot_text_label.html#a259ab949f5434091f34fe71b12ec72ab',1,'QwtPlotTextLabel::margin()'],['../class_qwt_scale_widget.html#a4827906c3f11825d479c6e493c8e1b4c',1,'QwtScaleWidget::margin()'],['../class_qwt_text_label.html#ab754bebe50bc0e713cde9ba58bf6c3c8',1,'QwtTextLabel::margin()']]], + ['margins',['Margins',['../class_qwt_plot_item.html#ae0fabcdd35f4818ce5bbe019b0eed062a56ea00cf43b862667dec2ac727307d4d',1,'QwtPlotItem']]], + ['markersize',['markerSize',['../class_qwt_knob.html#a502582b7f31df549e07664e874607a1e',1,'QwtKnob']]], + ['markerstyle',['markerStyle',['../class_qwt_knob.html#af7d2aaab6614c8e49974823333215bf7',1,'QwtKnob::markerStyle() const '],['../class_qwt_knob.html#a7254d94e76a74228637931fb75939b95',1,'QwtKnob::MarkerStyle()']]], + ['maskhint',['maskHint',['../class_qwt_widget_overlay.html#ad5c0592969220c56494be3034e5a83de',1,'QwtWidgetOverlay::maskHint() const '],['../class_qwt_widget_overlay.html#a413679fb15e072d5a404f237062b75fcaa3c2ba9dd41304c6a6524ee5f7c70540',1,'QwtWidgetOverlay::MaskHint()']]], + ['maskmode',['maskMode',['../class_qwt_widget_overlay.html#a161e7b6614b8e4ab0377eba9ce8a3f5a',1,'QwtWidgetOverlay::maskMode() const '],['../class_qwt_widget_overlay.html#a413679fb15e072d5a404f237062b75fc',1,'QwtWidgetOverlay::MaskMode()']]], + ['mass',['mass',['../class_qwt_wheel.html#a55de1496f0eef04da9bc293306a40df6',1,'QwtWheel']]], + ['mathmltext',['MathMLText',['../class_qwt_text.html#a63e0d6a59a427a37ed0bfa71b782fd76abf479897e4514198246a0b232a597caf',1,'QwtText']]], + ['maxcolumns',['maxColumns',['../class_qwt_dyn_grid_layout.html#a06b418089a233555dd3354d98b712c3e',1,'QwtDynGridLayout::maxColumns()'],['../class_qwt_legend.html#ade4944cabe8f165bb1c218155a2ef251',1,'QwtLegend::maxColumns()'],['../class_qwt_plot_legend_item.html#addf073d47a835cf50dce684667a377ba',1,'QwtPlotLegendItem::maxColumns()']]], + ['maxdate',['maxDate',['../class_qwt_date.html#af82ba26011550602f1adb61da53bd830',1,'QwtDate']]], + ['maximum',['maximum',['../class_qwt_abstract_scale.html#a92d1f793aa5dc3c18f96448d43bd255e',1,'QwtAbstractScale::maximum()'],['../class_qwt_counter.html#a82dead63dd6b56056251b84848ab1b75',1,'QwtCounter::maximum()'],['../class_qwt_wheel.html#a5f79673a9ba7e8cbf47f5f88e5367a32',1,'QwtWheel::maximum()']]], + ['maxitemwidth',['maxItemWidth',['../class_qwt_dyn_grid_layout.html#a74ebb14c4b4fae32354d3824bf29c93e',1,'QwtDynGridLayout']]], + ['maxlabelheight',['maxLabelHeight',['../class_qwt_scale_draw.html#ab5fcdcbb4c3fe419e48efd3068ecd3e4',1,'QwtScaleDraw']]], + ['maxlabelwidth',['maxLabelWidth',['../class_qwt_scale_draw.html#ab0c4ee29e81cee70e8a491e5ff80b8ff',1,'QwtScaleDraw']]], + ['maxscalearc',['maxScaleArc',['../class_qwt_dial.html#a9d7a976894700e616126d41a312f999d',1,'QwtDial']]], + ['maxstackdepth',['maxStackDepth',['../class_qwt_plot_zoomer.html#ac0d39d53af224cbeda37e0417d084dab',1,'QwtPlotZoomer']]], + ['maxsymbolwidth',['maxSymbolWidth',['../class_qwt_plot_trading_curve.html#a73fd6f5b6555ac4789930b5a908732ca',1,'QwtPlotTradingCurve']]], + ['maxticklength',['maxTickLength',['../class_qwt_abstract_scale_draw.html#afac6ad0e98fefd9d103366726542a055',1,'QwtAbstractScaleDraw']]], + ['maxvalue',['maxValue',['../class_qwt_interval.html#aac7cffc81147c07efc4a95c2e6222a1a',1,'QwtInterval']]], + ['maxweeks',['maxWeeks',['../class_qwt_date_scale_engine.html#a1e1168602421de588ec7c5615100e22f',1,'QwtDateScaleEngine']]], + ['maxxvalue',['maxXValue',['../class_qwt_plot_curve.html#a2428e72e84b23a9442ae48fe4540c17f',1,'QwtPlotCurve']]], + ['maxyvalue',['maxYValue',['../class_qwt_plot_curve.html#a135a412978bf646716b37b0ac8528665',1,'QwtPlotCurve']]], + ['mediumtick',['MediumTick',['../class_qwt_scale_div.html#af21aedaa886dd5e067cf63505838736ca42fbe3ad54900057e75225ff5e68cc4a',1,'QwtScaleDiv']]], + ['metric',['metric',['../class_qwt_null_paint_device.html#a014f8bf4ba5f58df3d17747e09d8f539',1,'QwtNullPaintDevice']]], + ['midlinewidth',['midLineWidth',['../class_qwt_plot_g_l_canvas.html#af4d70838d3af7c8521fe313b813c347e',1,'QwtPlotGLCanvas']]], + ['mightrender',['mightRender',['../class_qwt_text_engine.html#a98316f2f6f4f50216ceffbe9babe2901',1,'QwtTextEngine::mightRender()'],['../class_qwt_plain_text_engine.html#ae7bd7417f0173e2d35fe1bf7a514ec9b',1,'QwtPlainTextEngine::mightRender()'],['../class_qwt_rich_text_engine.html#a42da46eee5fbda55e34b18c64b0b5e0b',1,'QwtRichTextEngine::mightRender()'],['../class_qwt_math_m_l_text_engine.html#a59ca5842c32fd12cfd2aeeef5c985600',1,'QwtMathMLTextEngine::mightRender()']]], + ['millisecond',['Millisecond',['../class_qwt_date.html#ad037b999a51cae4d9ab36bf8e7859587a4e1d45d6382c27689a30adc11186d4f1',1,'QwtDate']]], + ['mindate',['minDate',['../class_qwt_date.html#a9ab1845543957472c2c6529ad03ef98d',1,'QwtDate']]], + ['minimizememory',['MinimizeMemory',['../class_qwt_plot_curve.html#a96db1b854c63bfbc452c943251a11b66a154c720d852e71b7909adf5e56a3500d',1,'QwtPlotCurve']]], + ['minimum',['minimum',['../class_qwt_abstract_scale.html#ac71c042246a7bb684c1b41c0204b6f14',1,'QwtAbstractScale::minimum()'],['../class_qwt_counter.html#aa653ae82690f6ea0ba1b3fb9081ce67a',1,'QwtCounter::minimum()'],['../class_qwt_wheel.html#a88e7f5245b579d112a516cbd447e07f3',1,'QwtWheel::minimum()']]], + ['minimumextent',['minimumExtent',['../class_qwt_abstract_scale_draw.html#a563f102ef1370ecdfdc47133fb0c78ec',1,'QwtAbstractScaleDraw']]], + ['minimumlayout',['MinimumLayout',['../class_qwt_text.html#a0953aabc098f410dba89bbada47f2e5aa35990c4c74747580e9357d490ebce42f',1,'QwtText']]], + ['minimumsize',['minimumSize',['../class_qwt_plot_legend_item.html#ad80478871117dc788d13cbef58759b4e',1,'QwtPlotLegendItem']]], + ['minimumsizehint',['minimumSizeHint',['../class_qwt_arrow_button.html#a5bc3817732a253bb214a94d1c76508ce',1,'QwtArrowButton::minimumSizeHint()'],['../class_qwt_dial.html#a21e46fa17a55b938c027ec7b4b97d157',1,'QwtDial::minimumSizeHint()'],['../class_qwt_knob.html#a03d014cd8d025bfeab6e004c53ab6e5b',1,'QwtKnob::minimumSizeHint()'],['../class_qwt_plot.html#a5a17d0ea2e9a977d48045e742f5b8cfd',1,'QwtPlot::minimumSizeHint()'],['../class_qwt_plot_layout.html#a068a12c510998760c727a095f5b055fe',1,'QwtPlotLayout::minimumSizeHint()'],['../class_qwt_scale_widget.html#aee41cd1b3eff4cf06559e7a36baee5a5',1,'QwtScaleWidget::minimumSizeHint()'],['../class_qwt_slider.html#a1cc878ed8746de2ea7c33a88f1c4652c',1,'QwtSlider::minimumSizeHint()'],['../class_qwt_text_label.html#a75ed6482ddb21e4f67ad9272f2ce66bb',1,'QwtTextLabel::minimumSizeHint()'],['../class_qwt_thermo.html#a7bdc0a01f646b3cacda48bffc7c2057d',1,'QwtThermo::minimumSizeHint()'],['../class_qwt_wheel.html#a668397451f5ad7b2a78d01d9e7141bcf',1,'QwtWheel::minimumSizeHint()']]], + ['minlabeldist',['minLabelDist',['../class_qwt_scale_draw.html#a1e60d584f563933afba119d443ba5b32',1,'QwtScaleDraw']]], + ['minlength',['minLength',['../class_qwt_scale_draw.html#a2fbdde2e1263664069e2e5f9a1fc9266',1,'QwtScaleDraw']]], + ['minorpen',['minorPen',['../class_qwt_plot_grid.html#a69000abf9f7b8b8d7d6ba605b38d5f67',1,'QwtPlotGrid']]], + ['minortick',['MinorTick',['../class_qwt_scale_div.html#af21aedaa886dd5e067cf63505838736ca6af9f3b95636a6fdebb4824c6db0ab9e',1,'QwtScaleDiv']]], + ['minscalearc',['minScaleArc',['../class_qwt_dial.html#a1725682984aff88ef891966225c06030',1,'QwtDial']]], + ['minsymbolwidth',['minSymbolWidth',['../class_qwt_plot_trading_curve.html#a1903b1b153f85394e26831ffa708c471',1,'QwtPlotTradingCurve']]], + ['minute',['Minute',['../class_qwt_date.html#ad037b999a51cae4d9ab36bf8e7859587a7c9073c66b2628adbe772ac4c1a678ef',1,'QwtDate']]], + ['minutehand',['MinuteHand',['../class_qwt_analog_clock.html#acd8f7e963ae073120684de46821f2cfea024c7bee0110b50aad1bfffe6f468744',1,'QwtAnalogClock']]], + ['minvalue',['minValue',['../class_qwt_interval.html#a173c9193bd16f99589db60326df04310',1,'QwtInterval']]], + ['minxvalue',['minXValue',['../class_qwt_plot_curve.html#a20c92bfce270e71893cdfa465781017b',1,'QwtPlotCurve']]], + ['minyvalue',['minYValue',['../class_qwt_plot_curve.html#a09f7aac646f0e534c2540d61a027b856',1,'QwtPlotCurve']]], + ['minzoomsize',['minZoomSize',['../class_qwt_plot_zoomer.html#aca5523ed1676ca733fdaf7484a8b4499',1,'QwtPlotZoomer']]], + ['mode',['mode',['../class_qwt_linear_color_map.html#a9ec309df6ec88472a63b14ac2c692c96',1,'QwtLinearColorMap::mode()'],['../class_qwt_dial.html#afd95a47735c0cfe963dfacd1a6a36a6f',1,'QwtDial::mode()'],['../class_qwt_legend_data.html#a7cd0c8df579edddf8abfe6c7a87af07f',1,'QwtLegendData::mode()'],['../class_qwt_null_paint_device.html#ab8dd2303c06d6cbfa5f4c0fa442eb493',1,'QwtNullPaintDevice::mode()'],['../class_qwt_linear_color_map.html#ac8c5f1991f533b1d25a9a0a0874b7d54',1,'QwtLinearColorMap::Mode()'],['../class_qwt_dial.html#a7376f53193014b91643350e6e6bc85ad',1,'QwtDial::Mode()'],['../class_qwt_legend_data.html#aaa33cc8e6aec17440df5d4c38d7545b7',1,'QwtLegendData::Mode()'],['../class_qwt_null_paint_device.html#a1e605d04e468e2e7fc45c639251a053a',1,'QwtNullPaintDevice::Mode()']]], + ['modifiers',['modifiers',['../class_qwt_event_pattern_1_1_mouse_pattern.html#ad12c724aac7bba9f16540c604dc108f9',1,'QwtEventPattern::MousePattern::modifiers()'],['../class_qwt_event_pattern_1_1_key_pattern.html#a1db88ed291d4ba49fa84e32e86fa10d1',1,'QwtEventPattern::KeyPattern::modifiers()']]], + ['month',['Month',['../class_qwt_date.html#ad037b999a51cae4d9ab36bf8e7859587a0ab43f35f1bdbae7536be2be0455700a',1,'QwtDate']]], + ['mousefactor',['mouseFactor',['../class_qwt_magnifier.html#a49348534d3cd7fe37a4a7cb6c3bbff8d',1,'QwtMagnifier']]], + ['mousematch',['mouseMatch',['../class_qwt_event_pattern.html#a4cf45668d0706d6dcb1108d549e061c0',1,'QwtEventPattern::mouseMatch(MousePatternCode, const QMouseEvent *) const '],['../class_qwt_event_pattern.html#a091006f03b17d638a84ab0211e5c39de',1,'QwtEventPattern::mouseMatch(const MousePattern &, const QMouseEvent *) const ']]], + ['mousemoveevent',['mouseMoveEvent',['../class_qwt_abstract_slider.html#a05ffec4c6b43909ecec148121a618f40',1,'QwtAbstractSlider::mouseMoveEvent()'],['../class_qwt_wheel.html#a1c7445264de07cacf72ec942e189713b',1,'QwtWheel::mouseMoveEvent()']]], + ['mousepattern',['MousePattern',['../class_qwt_event_pattern_1_1_mouse_pattern.html',1,'QwtEventPattern']]], + ['mousepattern',['MousePattern',['../class_qwt_event_pattern_1_1_mouse_pattern.html#a4233e9620cdad92c498a5271cd32bcf6',1,'QwtEventPattern::MousePattern::MousePattern()'],['../class_qwt_event_pattern.html#a40f66b9b22867b5066d92e9c3f629a81',1,'QwtEventPattern::mousePattern() const '],['../class_qwt_event_pattern.html#a141107868ed1c9cf1b34046873234390',1,'QwtEventPattern::mousePattern()']]], + ['mousepatterncode',['MousePatternCode',['../class_qwt_event_pattern.html#af48dc808ac5e125eeed41a4c0285d1ea',1,'QwtEventPattern']]], + ['mousepatterncount',['MousePatternCount',['../class_qwt_event_pattern.html#af48dc808ac5e125eeed41a4c0285d1eaa01bd637c7b7c0fbb80c013f8a935e562',1,'QwtEventPattern']]], + ['mousepressevent',['mousePressEvent',['../class_qwt_abstract_slider.html#a8a9ac5817d109ccbec208b65772cacf5',1,'QwtAbstractSlider::mousePressEvent()'],['../class_qwt_legend_label.html#a2890c885c9665c7cfe630f7471337cb2',1,'QwtLegendLabel::mousePressEvent()'],['../class_qwt_slider.html#aa326b252e90615537cd6633a5423f6c4',1,'QwtSlider::mousePressEvent()'],['../class_qwt_wheel.html#abf4ec8ed08f66034a9940dbb828703ac',1,'QwtWheel::mousePressEvent()']]], + ['mousereleaseevent',['mouseReleaseEvent',['../class_qwt_abstract_slider.html#aef54140a399f52c01cd9e82abf862783',1,'QwtAbstractSlider::mouseReleaseEvent()'],['../class_qwt_legend_label.html#a4b2c6badfcb25aea68fe3e72b134339e',1,'QwtLegendLabel::mouseReleaseEvent()'],['../class_qwt_slider.html#a801960c694bfd1dc6dcd8099553be7d7',1,'QwtSlider::mouseReleaseEvent()'],['../class_qwt_wheel.html#a0af92c432374d99d371ecd5570ea038e',1,'QwtWheel::mouseReleaseEvent()']]], + ['mouseselect1',['MouseSelect1',['../class_qwt_event_pattern.html#af48dc808ac5e125eeed41a4c0285d1eaa5875976eba018ca30eb30ba92986d270',1,'QwtEventPattern']]], + ['mouseselect2',['MouseSelect2',['../class_qwt_event_pattern.html#af48dc808ac5e125eeed41a4c0285d1eaac4185682db6cfd9c59955eb4cf052fd1',1,'QwtEventPattern']]], + ['mouseselect3',['MouseSelect3',['../class_qwt_event_pattern.html#af48dc808ac5e125eeed41a4c0285d1eaaa52e3aa1f4f6e57e22ffe9208f0dd1e3',1,'QwtEventPattern']]], + ['mouseselect4',['MouseSelect4',['../class_qwt_event_pattern.html#af48dc808ac5e125eeed41a4c0285d1eaa7cf49ee566862c3778e3d47096138f3b',1,'QwtEventPattern']]], + ['mouseselect5',['MouseSelect5',['../class_qwt_event_pattern.html#af48dc808ac5e125eeed41a4c0285d1eaac735f981781895836d0d9475ac3cae87',1,'QwtEventPattern']]], + ['mouseselect6',['MouseSelect6',['../class_qwt_event_pattern.html#af48dc808ac5e125eeed41a4c0285d1eaaf8f83e3d9c9a5d639a4290c6b124ddd9',1,'QwtEventPattern']]], + ['move',['move',['../class_qwt_picker.html#a59d92670978f200edb61e429afa06542',1,'QwtPicker::move()'],['../class_qwt_plot_picker.html#a7a979d23cd4d398e309409e76635bcf4',1,'QwtPlotPicker::move()'],['../class_qwt_scale_draw.html#a15f91bdd71ec87abe618e00cf18aa3f1',1,'QwtScaleDraw::move(double x, double y)'],['../class_qwt_scale_draw.html#a61f1b2112eb1fdd2bdeef429f7fc24d9',1,'QwtScaleDraw::move(const QPointF &)']]], + ['moveby',['moveBy',['../class_qwt_plot_zoomer.html#ac66b3eac03db212812198637f4e233ca',1,'QwtPlotZoomer']]], + ['movecanvas',['moveCanvas',['../class_qwt_plot_panner.html#aab045140de3e38d316593388da9231bd',1,'QwtPlotPanner']]], + ['movecenter',['moveCenter',['../class_qwt_round_scale_draw.html#af7e08b85826c5e1e5b1762fa07830107',1,'QwtRoundScaleDraw::moveCenter(double x, double y)'],['../class_qwt_round_scale_draw.html#a7be4951c2998474a79e4f1d621ea412a',1,'QwtRoundScaleDraw::moveCenter(const QPointF &)']]], + ['moved',['moved',['../class_qwt_panner.html#aa45ae2f4d6d20a83783898dd86d0b595',1,'QwtPanner::moved()'],['../class_qwt_picker.html#adddb4800c1dac0ba807e731f45d40742',1,'QwtPicker::moved()'],['../class_qwt_plot_picker.html#a4a35d30f1c4c4f80c49e3c6647b34e12',1,'QwtPlotPicker::moved()']]], + ['moveto',['moveTo',['../class_qwt_plot_zoomer.html#a40853271ba53bb66f9cf744ab69c1b13',1,'QwtPlotZoomer']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/all_6e.html b/ThirdParty/Qwt/doc/html/search/all_6e.html new file mode 100644 index 0000000000..e0fd7653a0 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/all_6e.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/all_6e.js b/ThirdParty/Qwt/doc/html/search/all_6e.js new file mode 100644 index 0000000000..7264231c17 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/all_6e.js @@ -0,0 +1,33 @@ +var searchData= +[ + ['natural',['Natural',['../class_qwt_spline.html#a2bd2bda128f82acd596348eb8d64231ca506b78ec81ab6d56a4bbce891490c857',1,'QwtSpline']]], + ['nearestneighbour',['NearestNeighbour',['../class_qwt_matrix_raster_data.html#a3c8def5d9ae452bd82e6c4b71b480209acaa0a9e3b8afd376472d6a587a3f9873',1,'QwtMatrixRasterData']]], + ['needle',['needle',['../class_qwt_dial.html#a58ed8cf5aae56c44427b25f691f69b5c',1,'QwtDial::needle() const '],['../class_qwt_dial.html#abbf494e72f6244e4ec88211354c739a4',1,'QwtDial::needle()']]], + ['nhands',['NHands',['../class_qwt_analog_clock.html#acd8f7e963ae073120684de46821f2cfea004c9f49b4271e02f350bccd21235ecd',1,'QwtAnalogClock']]], + ['noattribute',['NoAttribute',['../class_qwt_scale_engine.html#a7548418e0896d75eec164bfa2ba3ff5fa617f0da0b90080be49b79dbaaab191f8',1,'QwtScaleEngine']]], + ['nocache',['NoCache',['../class_qwt_plot_raster_item.html#a94929fc4c31c3dab75ee5adcac2d57b0a758ccf247c4ae50d4ffd090ef3a6058e',1,'QwtPlotRasterItem::NoCache()'],['../class_qwt_symbol.html#adda2e2c0e5234692adbc530552efd549ac0f276939fbf44c89e93b3a3870abb18',1,'QwtSymbol::NoCache()']]], + ['nocurve',['NoCurve',['../class_qwt_plot_curve.html#a15998aa80a11ba6ba80eebabaf773f70a0b6dcf16619a08af39437d6b6a234c9c',1,'QwtPlotCurve::NoCurve()'],['../class_qwt_plot_interval_curve.html#aaef834575b923e1b317f4a86b2d97cd2a40f2eb25abeed9eb2af1b4c4c0f56c15',1,'QwtPlotIntervalCurve::NoCurve()']]], + ['nofocusindicator',['NoFocusIndicator',['../class_qwt_plot_canvas.html#a89b44e4c28038a674ce211fe9ac2d7bea8578c1bdcba0a05d5d0b89aeb35a040d',1,'QwtPlotCanvas']]], + ['noframe',['NoFrame',['../class_qwt_column_symbol.html#a4b97f7748370447559a11a5adeb70e44a11a035d598228e1498b98153e3e9e043',1,'QwtColumnSymbol']]], + ['noline',['NoLine',['../class_qwt_plot_marker.html#a297efa835423bfa5a870bbc8ff1c623ba5407403ea223539c7cac264a9fff5fe0',1,'QwtPlotMarker']]], + ['nomarker',['NoMarker',['../class_qwt_knob.html#a7254d94e76a74228637931fb75939b95af12a242c58b244547abb48ef284246f6',1,'QwtKnob']]], + ['nomask',['NoMask',['../class_qwt_widget_overlay.html#a413679fb15e072d5a404f237062b75fca58d7a0858b0aa58407bf598c907636fd',1,'QwtWidgetOverlay']]], + ['normalized',['normalized',['../class_qwt_interval.html#a662aa6c6f7d575c72023eb32c0974508',1,'QwtInterval::normalized()'],['../class_qwt_point_polar.html#a2544921fb33e7601444223572243ed6a',1,'QwtPointPolar::normalized()']]], + ['normalmode',['NormalMode',['../class_qwt_null_paint_device.html#a1e605d04e468e2e7fc45c639251a053aa2ad991b2edd425baa217eb90ed9930f7',1,'QwtNullPaintDevice']]], + ['norubberband',['NoRubberBand',['../class_qwt_picker.html#ab36c79d8ff20aba5b778d2823c1f7894abe995b2c285314bf9fc459581e100934',1,'QwtPicker']]], + ['noscale',['NoScale',['../class_qwt_slider.html#a120d984d7c519578eed88c4fe97cb1a7a49899c3cf9ad1d8f45046824ecbfc6a4',1,'QwtSlider::NoScale()'],['../class_qwt_thermo.html#a4d7af32d29d1cc18e23b9143cf7ad498a54c98c1e9500e24a5f92e71a7020acbd',1,'QwtThermo::NoScale()']]], + ['noselection',['NoSelection',['../class_qwt_picker_machine.html#a24a9faf12cfa5746eee839a2c0bb937da326bcc03f7a99aa5970d875f3db46888',1,'QwtPickerMachine']]], + ['nostyle',['NoStyle',['../class_qwt_column_symbol.html#aaace508375eef3ee23ed6c47b1d65ef2a3c16d900e0dcfc18f174f4120136cb5b',1,'QwtColumnSymbol']]], + ['nosymbol',['NoSymbol',['../class_qwt_interval_symbol.html#a8fe960fd50b3ad08765ef8bb632ad77ea48e0d047b9988e77067a11f784556019',1,'QwtIntervalSymbol::NoSymbol()'],['../class_qwt_plot_trading_curve.html#af1ca10dd8c3f1ef662d40fc8a113b44aaffbe8e09731b6296d7534149c63a39b3',1,'QwtPlotTradingCurve::NoSymbol()'],['../class_qwt_symbol.html#a62f457952470c2076962e83ef2c24d2fac3089b3993834683204a7bda52e763d3',1,'QwtSymbol::NoSymbol()']]], + ['notch',['Notch',['../class_qwt_knob.html#a7254d94e76a74228637931fb75939b95a9ea483f1087c1f6b1ac215b5f146c7c3',1,'QwtKnob']]], + ['notick',['NoTick',['../class_qwt_scale_div.html#af21aedaa886dd5e067cf63505838736ca9f64c3f9efef05e3020903a54331c4ac',1,'QwtScaleDiv']]], + ['nticktypes',['NTickTypes',['../class_qwt_scale_div.html#af21aedaa886dd5e067cf63505838736ca86796bbf72d5eb7162a924ba27ce6553',1,'QwtScaleDiv']]], + ['nub',['Nub',['../class_qwt_knob.html#a7254d94e76a74228637931fb75939b95a1bf9be6c73beec7768d62f101d81a851',1,'QwtKnob']]], + ['num',['num',['../class_qwt_arrow_button.html#a09ae0f534912a14155233d7f431ffb2e',1,'QwtArrowButton']]], + ['numbuttons',['numButtons',['../class_qwt_counter.html#ac160c5e7a1c7f858b7f52ff0904ea142',1,'QwtCounter']]], + ['numcolumns',['numColumns',['../class_qwt_dyn_grid_layout.html#a968ad0c13f353d4fc62c7c097eb024fe',1,'QwtDynGridLayout::numColumns()'],['../class_qwt_matrix_raster_data.html#adbc9f8a45969a2673d2c0791ff7834b3',1,'QwtMatrixRasterData::numColumns()']]], + ['numrows',['numRows',['../class_qwt_dyn_grid_layout.html#ad3f387078e5e78b66b452c72e99923c2',1,'QwtDynGridLayout::numRows()'],['../class_qwt_matrix_raster_data.html#aaffe172692947226e0521798302dede7',1,'QwtMatrixRasterData::numRows()']]], + ['numthornlevels',['numThornLevels',['../class_qwt_simple_compass_rose.html#a8fa418ee344d934d556fa5719cd5ece5',1,'QwtSimpleCompassRose']]], + ['numthorns',['numThorns',['../class_qwt_simple_compass_rose.html#a7c3270789e94e94b8d515b04372bfe0b',1,'QwtSimpleCompassRose']]], + ['numturns',['numTurns',['../class_qwt_knob.html#aabeeacaf8f2c526f74eacbb043f4cfa3',1,'QwtKnob']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/all_6f.html b/ThirdParty/Qwt/doc/html/search/all_6f.html new file mode 100644 index 0000000000..5e86b030d2 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/all_6f.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/all_6f.js b/ThirdParty/Qwt/doc/html/search/all_6f.js new file mode 100644 index 0000000000..7e431c7b4f --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/all_6f.js @@ -0,0 +1,23 @@ +var searchData= +[ + ['opaque',['Opaque',['../class_qwt_plot_canvas.html#a76066290edb594a71ee09be564563b0fa1d10fbb2b1fc3323e8597597684b1f9f',1,'QwtPlotCanvas']]], + ['open',['open',['../class_qwt_o_h_l_c_sample.html#a71b133fe8f7676b2ff7b17e39d669f95',1,'QwtOHLCSample']]], + ['operator_21_3d',['operator!=',['../class_qwt_interval.html#a4c1cb8360a05c1875f7957f00d3bdf16',1,'QwtInterval::operator!=()'],['../class_qwt_interval_symbol.html#a89737a98021a7ebf3eddd79469257411',1,'QwtIntervalSymbol::operator!=()'],['../class_qwt_point3_d.html#a38b3c81b7dfce567dfc2993db1aa6d74',1,'QwtPoint3D::operator!=()'],['../class_qwt_point_polar.html#af85df99741e28fbe6bdee96df42fb448',1,'QwtPointPolar::operator!=()'],['../class_qwt_interval_sample.html#a17e9ce13c70d8f5e369ee8ba6aec6e41',1,'QwtIntervalSample::operator!=()'],['../class_qwt_set_sample.html#a0b96a0b525bbf4aab51a406502c4734c',1,'QwtSetSample::operator!=()'],['../class_qwt_scale_div.html#a6bbd302e0628a5131f7d7c0c2e03f7d8',1,'QwtScaleDiv::operator!=()'],['../class_qwt_text.html#a092326f250d2b865ad93f16462d9fc9f',1,'QwtText::operator!=()']]], + ['operator_26',['operator&',['../class_qwt_interval.html#a87091a809fb14d2321240be47bb9cbe1',1,'QwtInterval']]], + ['operator_26_3d',['operator&=',['../class_qwt_interval.html#a31b75687b9d2e1931ec82f61cc644222',1,'QwtInterval']]], + ['operator_3d',['operator=',['../class_qwt_graphic.html#a56504c5384e140d199f73c6e729408ec',1,'QwtGraphic::operator=()'],['../class_qwt_interval_symbol.html#a49558f59372b7e69143f1ff49c5bfad8',1,'QwtIntervalSymbol::operator=()'],['../class_qwt_painter_command.html#a08dc6d9612be3a2e3abf2366935e7370',1,'QwtPainterCommand::operator=()'],['../class_qwt_scale_map.html#a3f55ef14f8874e626380fcf92b096791',1,'QwtScaleMap::operator=()'],['../class_qwt_spline.html#a8a597c34477dd4b5298db2d445b4e596',1,'QwtSpline::operator=()'],['../class_qwt_text.html#ad4a8678071c7e114c47a21f1f78cca37',1,'QwtText::operator=()']]], + ['operator_3d_3d',['operator==',['../class_qwt_interval.html#aec5aa21ab413fb5bfaa3360fae02e6b2',1,'QwtInterval::operator==()'],['../class_qwt_interval_symbol.html#a1fa66bf16cecbcc6a2a95d8484dbc0d3',1,'QwtIntervalSymbol::operator==()'],['../class_qwt_point3_d.html#aaafd119aea020d1e7e44360fd1172c22',1,'QwtPoint3D::operator==()'],['../class_qwt_point_polar.html#af59f940ff7d63de71044a8bba6d749db',1,'QwtPointPolar::operator==()'],['../class_qwt_interval_sample.html#a3ef77fe5326a1fdd4b0428b3093a0e25',1,'QwtIntervalSample::operator==()'],['../class_qwt_set_sample.html#a76859b776c7501b04c50197fe9e6c97e',1,'QwtSetSample::operator==()'],['../class_qwt_scale_div.html#a82c3bdbcb4263636a4e8f62a752553b4',1,'QwtScaleDiv::operator==()'],['../class_qwt_text.html#a0a7fba648ad898d751de60e9a6d7802f',1,'QwtText::operator==()']]], + ['operator_7c',['operator|',['../class_qwt_interval.html#ac6c5c7837821811f8b0748c529f137a6',1,'QwtInterval::operator|(const QwtInterval &) const '],['../class_qwt_interval.html#ae0671b0b9422d5da3a103cbd7c938484',1,'QwtInterval::operator|(double) const ']]], + ['operator_7c_3d',['operator|=',['../class_qwt_interval.html#a980e6449437b689893bd8ec7370e91e0',1,'QwtInterval::operator|=(const QwtInterval &)'],['../class_qwt_interval.html#a86a2785d0fc6860e15cfc277c14e7a09',1,'QwtInterval::operator|=(double)']]], + ['option',['Option',['../class_qwt_plot_layout.html#ad0d2d60e86a4c69ec105524041d5221d',1,'QwtPlotLayout']]], + ['options',['Options',['../class_qwt_plot_layout.html#aa43457184903f3aaa58e6e073622ef52',1,'QwtPlotLayout']]], + ['orientation',['orientation',['../class_qwt_column_rect.html#a8bb5221efc769ef7f474e1f1795de4b6',1,'QwtColumnRect::orientation()'],['../class_qwt_plot_rescaler.html#a5afb70d8dc928dedcb7daa3f95e7d506',1,'QwtPlotRescaler::orientation()'],['../class_qwt_plot_series_item.html#a2f97f0885d3f7adc7a9d484e741d2a76',1,'QwtPlotSeriesItem::orientation()'],['../class_qwt_plot_zone_item.html#a3543471c711b64a48f9f3eb672c24efc',1,'QwtPlotZoneItem::orientation()'],['../class_qwt_scale_draw.html#a06bf10d73aa03c16394a85fa70a7a3b1',1,'QwtScaleDraw::orientation()'],['../class_qwt_slider.html#a66ee353b1f2545db9bbbaea176c04251',1,'QwtSlider::orientation()'],['../class_qwt_thermo.html#aa15057791c2c884f0dc0fc77ff807d5f',1,'QwtThermo::orientation()'],['../class_qwt_wheel.html#acf5ccef9b918ef811698b5b619ec0d29',1,'QwtWheel::orientation()']]], + ['orientations',['orientations',['../class_qwt_panner.html#a4e7a195ed909f18d33a05b1b7c1f0930',1,'QwtPanner']]], + ['origin',['origin',['../class_qwt_dial.html#a5d7a8b9094bcc3fb82b31c3ac9ad706d',1,'QwtDial::origin()'],['../class_qwt_thermo.html#acb7ff196b2a792c40d07137fdff6d05f',1,'QwtThermo::origin()']]], + ['origincustom',['OriginCustom',['../class_qwt_thermo.html#a932d866dd7782cc56cd7fc3e5abb3183ad086bebe6a48967d8d078f0c27ee993f',1,'QwtThermo']]], + ['originmaximum',['OriginMaximum',['../class_qwt_thermo.html#a932d866dd7782cc56cd7fc3e5abb3183aa67de5780557c0c2ca93c45059ae932a',1,'QwtThermo']]], + ['originminimum',['OriginMinimum',['../class_qwt_thermo.html#a932d866dd7782cc56cd7fc3e5abb3183ae45b6edabbd2a63aa1551b7ed9b10f76',1,'QwtThermo']]], + ['originmode',['originMode',['../class_qwt_thermo.html#abd2a6f3b600c3354d7321b6187296e38',1,'QwtThermo::originMode() const '],['../class_qwt_thermo.html#a932d866dd7782cc56cd7fc3e5abb3183',1,'QwtThermo::OriginMode()']]], + ['otherformat',['OtherFormat',['../class_qwt_text.html#a63e0d6a59a427a37ed0bfa71b782fd76ad69e3155611ef96eb14ed0cfeb69fd3d',1,'QwtText']]], + ['outline',['Outline',['../class_qwt_plot_histogram.html#a3ba21c3aef994daf7b848ccf71b0dbc5ab6ef3ed19f600d5d67d34eedf4cf33a9',1,'QwtPlotHistogram']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/all_70.html b/ThirdParty/Qwt/doc/html/search/all_70.html new file mode 100644 index 0000000000..799c1a277d --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/all_70.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/all_70.js b/ThirdParty/Qwt/doc/html/search/all_70.js new file mode 100644 index 0000000000..677c622fbb --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/all_70.js @@ -0,0 +1,49 @@ +var searchData= +[ + ['p1',['p1',['../class_qwt_scale_map.html#ac1ca2f9b4643d27fde693cc98bca0cd7',1,'QwtScaleMap']]], + ['p2',['p2',['../class_qwt_scale_map.html#acf404215292b10bd46b1089d2452b8e9',1,'QwtScaleMap']]], + ['pagestepcount',['pageStepCount',['../class_qwt_wheel.html#a2ffc984ae772de07b27ba73d35af7f74',1,'QwtWheel']]], + ['pagesteps',['pageSteps',['../class_qwt_abstract_slider.html#a29adb20551bf586cff0c2b074d5c1e50',1,'QwtAbstractSlider']]], + ['paintattribute',['PaintAttribute',['../class_qwt_plot_canvas.html#a76066290edb594a71ee09be564563b0f',1,'QwtPlotCanvas::PaintAttribute()'],['../class_qwt_plot_curve.html#a96db1b854c63bfbc452c943251a11b66',1,'QwtPlotCurve::PaintAttribute()'],['../class_qwt_plot_interval_curve.html#a3deaf543802d69a38961f9e944bfad95',1,'QwtPlotIntervalCurve::PaintAttribute()'],['../class_qwt_plot_raster_item.html#a75ac68ea258b8612e8a1893e845394ee',1,'QwtPlotRasterItem::PaintAttribute()'],['../class_qwt_plot_shape_item.html#aaa78031ce7ab1b8e713bc05da05a4631',1,'QwtPlotShapeItem::PaintAttribute()'],['../class_qwt_plot_spectro_curve.html#af6d4c6ae392f3f521db710484a059625',1,'QwtPlotSpectroCurve::PaintAttribute()'],['../class_qwt_plot_trading_curve.html#afc40b9bee1371ebce4a7f3853fee7968',1,'QwtPlotTradingCurve::PaintAttribute()'],['../class_qwt_text.html#a9739e47ea489e690f121e4b1d27ae24e',1,'QwtText::PaintAttribute()']]], + ['paintattributes',['PaintAttributes',['../class_qwt_plot_canvas.html#ac007a0126efb62443e52905d3157102d',1,'QwtPlotCanvas::PaintAttributes()'],['../class_qwt_plot_curve.html#a39ba40485087294c775a367d859b6237',1,'QwtPlotCurve::PaintAttributes()'],['../class_qwt_plot_interval_curve.html#a1fa99e81e5c1b687aec620e9b8746d6c',1,'QwtPlotIntervalCurve::PaintAttributes()'],['../class_qwt_plot_raster_item.html#a6bde441d571c4943da01765dec2d4b4a',1,'QwtPlotRasterItem::PaintAttributes()'],['../class_qwt_plot_shape_item.html#af4ab987535185011cf4e5587094a5b40',1,'QwtPlotShapeItem::PaintAttributes()'],['../class_qwt_plot_spectro_curve.html#a78b3bf4c7d055f2f00bd371e9ddc4f2f',1,'QwtPlotSpectroCurve::PaintAttributes()'],['../class_qwt_plot_trading_curve.html#a284bcaa3994148bda302e5fec17467d8',1,'QwtPlotTradingCurve::PaintAttributes()'],['../class_qwt_text.html#a0d239ca5c8e0cd3c748325ad453bb13f',1,'QwtText::PaintAttributes()']]], + ['paintbackground',['PaintBackground',['../class_qwt_text.html#a9739e47ea489e690f121e4b1d27ae24ea77dd66b2a65e9998d9803672791e1456',1,'QwtText']]], + ['paintcache',['PaintCache',['../class_qwt_plot_raster_item.html#a94929fc4c31c3dab75ee5adcac2d57b0a3bfb74bebbfe1ccabe1d6654fee7c56d',1,'QwtPlotRasterItem']]], + ['paintengine',['paintEngine',['../class_qwt_null_paint_device.html#a2058b09c918ed674ef1977d11d869b03',1,'QwtNullPaintDevice']]], + ['paintevent',['paintEvent',['../class_qwt_arrow_button.html#ad9bdd4ed2e655aa19929ab436ec8ab45',1,'QwtArrowButton::paintEvent()'],['../class_qwt_dial.html#a11e50d714b9decb0f5d34e5acdde970d',1,'QwtDial::paintEvent()'],['../class_qwt_knob.html#aac9eb31c18408aaa224f5ad040631384',1,'QwtKnob::paintEvent()'],['../class_qwt_legend_label.html#a03649851d343dbd2c4128e9e50def6b7',1,'QwtLegendLabel::paintEvent()'],['../class_qwt_panner.html#acd76ea518bd9267a45115d2c6ce19353',1,'QwtPanner::paintEvent()'],['../class_qwt_plot_canvas.html#aa8f1516817c578efd407d8dd574170ec',1,'QwtPlotCanvas::paintEvent()'],['../class_qwt_plot_g_l_canvas.html#aa0bf3be03e9545b78da74844e6f4eb91',1,'QwtPlotGLCanvas::paintEvent()'],['../class_qwt_scale_widget.html#ab3d4d32fb92fbef360841f74d469f2a9',1,'QwtScaleWidget::paintEvent()'],['../class_qwt_slider.html#a128624c8babc95f5a631dfe3112d2d2b',1,'QwtSlider::paintEvent()'],['../class_qwt_text_label.html#aff00274ee1c860530920b4feaca02393',1,'QwtTextLabel::paintEvent()'],['../class_qwt_thermo.html#a7ae9fe53b0b0925d88fd9e1e4eb026f7',1,'QwtThermo::paintEvent()'],['../class_qwt_wheel.html#a8856da1dadb2a7b73e8bd75a1e981ea3',1,'QwtWheel::paintEvent()'],['../class_qwt_widget_overlay.html#ac75689d1294c175540253bb72ea70496',1,'QwtWidgetOverlay::paintEvent()']]], + ['paintindeviceresolution',['PaintInDeviceResolution',['../class_qwt_plot_raster_item.html#a75ac68ea258b8612e8a1893e845394eea77b139d4d7327465408fe06ec98dbc0d',1,'QwtPlotRasterItem']]], + ['paintrect',['paintRect',['../class_qwt_plot_item.html#afa05b98fd7ea65ca1ffcb04bb6b4326d',1,'QwtPlotItem']]], + ['paintusingtextcolor',['PaintUsingTextColor',['../class_qwt_text.html#a9739e47ea489e690f121e4b1d27ae24ea1aa48cee0a54089820e77600cf93dc4b',1,'QwtText']]], + ['paintusingtextfont',['PaintUsingTextFont',['../class_qwt_text.html#a9739e47ea489e690f121e4b1d27ae24eac12e48f17fd02a6bc1840c61c4862a65',1,'QwtText']]], + ['palette',['palette',['../class_qwt_column_symbol.html#afe13154e29f882e77fedf8bbc3280f7e',1,'QwtColumnSymbol::palette()'],['../class_qwt_compass_rose.html#ab2e5c2a4a27c40a175458b96d89394e8',1,'QwtCompassRose::palette()'],['../class_qwt_dial_needle.html#a8b3c915032389261e07cc983b433166c',1,'QwtDialNeedle::palette()'],['../class_qwt_plot_scale_item.html#a6e48f16a93b7e7dcb98c6bfda3b11c2e',1,'QwtPlotScaleItem::palette()']]], + ['panned',['panned',['../class_qwt_panner.html#ae9ce78e6f9ae73317af29b2dc5df7372',1,'QwtPanner']]], + ['parametricspline',['ParametricSpline',['../class_qwt_spline_curve_fitter.html#a8c5e6858f885b5691c30092a950879a8a877f71e694ae9a2e33533a3fb5065c66',1,'QwtSplineCurveFitter']]], + ['parentwidget',['parentWidget',['../class_qwt_magnifier.html#a56b7ad2366a7f908c38bc2a994acde16',1,'QwtMagnifier::parentWidget()'],['../class_qwt_magnifier.html#a7ea89693ca6ebd6376838d4ab107bf5a',1,'QwtMagnifier::parentWidget() const '],['../class_qwt_picker.html#ada0c12257e006f0066d22c3eb83f667e',1,'QwtPicker::parentWidget()'],['../class_qwt_picker.html#a250dc5daf40a049f8db1f7ed730802d3',1,'QwtPicker::parentWidget() const ']]], + ['path',['Path',['../class_qwt_painter_command.html#a6619a454c4332c02412611467935b7baa8f98e03699c40458ed0c2007dca698ca',1,'QwtPainterCommand::Path()'],['../class_qwt_symbol.html#a62f457952470c2076962e83ef2c24d2faa3cc8fec7843b850f3cde81a6b04394c',1,'QwtSymbol::Path()'],['../class_qwt_painter_command.html#a19fa09138a8775e721817d4ca309f5ac',1,'QwtPainterCommand::path()'],['../class_qwt_painter_command.html#a09296ca1e32fb283149cb9edf5f38550',1,'QwtPainterCommand::path() const '],['../class_qwt_symbol.html#aa17d051c735f55441ce62c7043428b90',1,'QwtSymbol::path()']]], + ['pathmode',['PathMode',['../class_qwt_null_paint_device.html#a1e605d04e468e2e7fc45c639251a053aa6dd94a051e9b1bab414cc819f2878e65',1,'QwtNullPaintDevice']]], + ['pdist',['pDist',['../class_qwt_scale_map.html#af364d4fa10db6f5dbc93d6ce763e603f',1,'QwtScaleMap']]], + ['pen',['pen',['../class_qwt_interval_symbol.html#a5945eb2b656f12451d02721b9068441d',1,'QwtIntervalSymbol::pen()'],['../class_qwt_plot_curve.html#a778aafd1385ce833821751d0a8635cef',1,'QwtPlotCurve::pen()'],['../class_qwt_plot_histogram.html#a51727f20a46a48afbbc7f76a8ea6ec84',1,'QwtPlotHistogram::pen()'],['../class_qwt_plot_interval_curve.html#a942952ad07550f271a57db4cf5211ea8',1,'QwtPlotIntervalCurve::pen()'],['../class_qwt_plot_shape_item.html#a5c54cacd19217ca62583cc8890b7219a',1,'QwtPlotShapeItem::pen()'],['../class_qwt_plot_zone_item.html#aab5bb31db1e30d9c1fa3cc3fea71ec0f',1,'QwtPlotZoneItem::pen()'],['../class_qwt_symbol.html#a2fe55b71735bcaca3e931b65b9b1ed13',1,'QwtSymbol::pen()']]], + ['penwidth',['penWidth',['../class_qwt_abstract_scale_draw.html#a8933b8da6332a6d4badfa83e67b74865',1,'QwtAbstractScaleDraw::penWidth()'],['../class_qwt_plot_spectro_curve.html#a81a531d89ac21d25e86a958822720f38',1,'QwtPlotSpectroCurve::penWidth()']]], + ['periodic',['Periodic',['../class_qwt_spline.html#a2bd2bda128f82acd596348eb8d64231ca500c12cdbdef35c62e9fab86c5727acb',1,'QwtSpline']]], + ['pickarea',['pickArea',['../class_qwt_picker.html#accba1f639a7e0a0fa978bf638b5f7500',1,'QwtPicker']]], + ['pickedpoints',['pickedPoints',['../class_qwt_picker.html#a9e10695cd170fe335c6959de8d1298a1',1,'QwtPicker']]], + ['pinpoint',['pinPoint',['../class_qwt_symbol.html#ab107489def28441f21fd9166de795cb6',1,'QwtSymbol']]], + ['piperect',['pipeRect',['../class_qwt_thermo.html#a3359ca7488990dab26b182448b38395b',1,'QwtThermo']]], + ['pipewidth',['pipeWidth',['../class_qwt_thermo.html#aae17760ab12807624b63b6caeae5f3d0',1,'QwtThermo']]], + ['pixelhint',['pixelHint',['../class_qwt_matrix_raster_data.html#a7a9034de8037af500e4f737f54591358',1,'QwtMatrixRasterData::pixelHint()'],['../class_qwt_plot_raster_item.html#a03a69bfe7d3d125ba4f580d1ecd5e2f4',1,'QwtPlotRasterItem::pixelHint()'],['../class_qwt_plot_spectrogram.html#a9b06ef6a2526da8715615d07fdb31a95',1,'QwtPlotSpectrogram::pixelHint()'],['../class_qwt_raster_data.html#ad1ce58351804760d1ba1e7efe97d39d6',1,'QwtRasterData::pixelHint()']]], + ['pixmap',['pixmap',['../class_qwt_symbol.html#a60f679d9fdadfd0b96aacbd5ce8ebcc0',1,'QwtSymbol::pixmap()'],['../class_qwt_painter_command.html#a6619a454c4332c02412611467935b7baa02455f25a984a7dde5992e748af34487',1,'QwtPainterCommand::Pixmap()'],['../class_qwt_symbol.html#a62f457952470c2076962e83ef2c24d2fa45c8273247748316e5dd359b2d00216c',1,'QwtSymbol::Pixmap()']]], + ['pixmapdata',['pixmapData',['../class_qwt_painter_command.html#aa85782270cf4ba4c9c20036e5e9780b3',1,'QwtPainterCommand::pixmapData()'],['../class_qwt_painter_command.html#a8dbf9778808df8c2b489c38382914260',1,'QwtPainterCommand::pixmapData() const ']]], + ['plain',['Plain',['../class_qwt_column_symbol.html#a4b97f7748370447559a11a5adeb70e44a2841bca1e2a5d94fbfc5a51787460be1',1,'QwtColumnSymbol::Plain()'],['../class_qwt_dial.html#a7472124cb120352e8538430ab48c2386a8d0cdae56d44bcd25574d7e432498d86',1,'QwtDial::Plain()'],['../class_qwt_plot_g_l_canvas.html#a6ce3b3cb6888443dfadca2399a632830a2d5a783769032359be64ff1d1a6c9143',1,'QwtPlotGLCanvas::Plain()']]], + ['plaintext',['plainText',['../class_qwt_text_label.html#a6c50b70fa29335c07e5633a316e05e48',1,'QwtTextLabel::plainText()'],['../class_qwt_text.html#a63e0d6a59a427a37ed0bfa71b782fd76aa6810f6d3c785c202d2507c601b97787',1,'QwtText::PlainText()']]], + ['plot',['plot',['../class_qwt_plot_canvas.html#a1b720b99dc1b686f58e789b13f339f63',1,'QwtPlotCanvas::plot()'],['../class_qwt_plot_canvas.html#a72550d1af1b5fb4caca5269c3d5891f9',1,'QwtPlotCanvas::plot() const '],['../class_qwt_plot_item.html#a4c99653a14a49ad94d466168d06e97b9',1,'QwtPlotItem::plot()'],['../class_qwt_plot_magnifier.html#ae0197fb4f393e149585ff62f8e29cea6',1,'QwtPlotMagnifier::plot()'],['../class_qwt_plot_magnifier.html#a2cc4ae00009f34f54880aea9e9837826',1,'QwtPlotMagnifier::plot() const '],['../class_qwt_plot_panner.html#ae52375921bfacc3e17d3db45858b1485',1,'QwtPlotPanner::plot()'],['../class_qwt_plot_panner.html#a2401ae1ff1e40b1ee4c7a997a895d2be',1,'QwtPlotPanner::plot() const '],['../class_qwt_plot_picker.html#ac5906d5fe7543f3db7808da44d8197a9',1,'QwtPlotPicker::plot()'],['../class_qwt_plot_picker.html#a88103b56426ff2a5fb8713ae8ab2d191',1,'QwtPlotPicker::plot() const '],['../class_qwt_plot_rescaler.html#aca7a946dd53744e4640be383cd161a7c',1,'QwtPlotRescaler::plot()'],['../class_qwt_plot_rescaler.html#ae49ce39ba8c7670bd8f70cf9078d96d5',1,'QwtPlotRescaler::plot() const ']]], + ['plotitems',['plotItems',['../class_qwt_plot_legend_item.html#ada1609304901c61024548ee37d824e7a',1,'QwtPlotLegendItem']]], + ['plotlayout',['plotLayout',['../class_qwt_plot.html#a9156b14a6f67f6279a16fea063ce1d14',1,'QwtPlot::plotLayout()'],['../class_qwt_plot.html#a6abb53bb19d8e931ba49bf439779f0ac',1,'QwtPlot::plotLayout() const ']]], + ['points',['points',['../class_qwt_spline.html#a14694e61052933921eda629062554d22',1,'QwtSpline']]], + ['pointselection',['PointSelection',['../class_qwt_picker_machine.html#a24a9faf12cfa5746eee839a2c0bb937dae65a34cc1ca5d818eb65c05b2484d855',1,'QwtPickerMachine']]], + ['polygonpathmode',['PolygonPathMode',['../class_qwt_null_paint_device.html#a1e605d04e468e2e7fc45c639251a053aad26aa1be0859afe98851b8ee170ca0a7',1,'QwtNullPaintDevice']]], + ['polygonrubberband',['PolygonRubberBand',['../class_qwt_picker.html#ab36c79d8ff20aba5b778d2823c1f7894a8b78b6221f2808abe027569c790f0945',1,'QwtPicker']]], + ['polygonselection',['PolygonSelection',['../class_qwt_picker_machine.html#a24a9faf12cfa5746eee839a2c0bb937dac74671ee5ba5d6fd0410f71db1aa3b97',1,'QwtPickerMachine']]], + ['polylinesplitting',['polylineSplitting',['../class_qwt_painter.html#a831cf0efa8a0869ab79307495d7e4590',1,'QwtPainter']]], + ['pos',['pos',['../class_qwt_scale_draw.html#a31b1a37c24d4a1f8f2e834b0b7c9a815',1,'QwtScaleDraw']]], + ['position',['position',['../class_qwt_plot_scale_item.html#a7228e5fc436e1cfb403c38974b781185',1,'QwtPlotScaleItem']]], + ['pressed',['pressed',['../class_qwt_legend_label.html#ae3c6cdfa7a6390c3f4152fc78c701cdd',1,'QwtLegendLabel']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/all_71.html b/ThirdParty/Qwt/doc/html/search/all_71.html new file mode 100644 index 0000000000..e9d391f66e --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/all_71.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/all_71.js b/ThirdParty/Qwt/doc/html/search/all_71.js new file mode 100644 index 0000000000..b0d99163c3 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/all_71.js @@ -0,0 +1,151 @@ +var searchData= +[ + ['qwt_20_2d_20qt_20widgets_20for_20technical_20applications',['Qwt - Qt Widgets for Technical Applications',['../index.html',1,'']]], + ['qwtabstractlegend',['QwtAbstractLegend',['../class_qwt_abstract_legend.html',1,'QwtAbstractLegend'],['../class_qwt_abstract_legend.html#a77092d06decd579fcde5c90875c3830b',1,'QwtAbstractLegend::QwtAbstractLegend()']]], + ['qwtabstractscale',['QwtAbstractScale',['../class_qwt_abstract_scale.html',1,'QwtAbstractScale'],['../class_qwt_abstract_scale.html#a97fff64367cdbe7bc8dc56c41d5faf9e',1,'QwtAbstractScale::QwtAbstractScale()']]], + ['qwtabstractscaledraw',['QwtAbstractScaleDraw',['../class_qwt_abstract_scale_draw.html',1,'QwtAbstractScaleDraw'],['../class_qwt_abstract_scale_draw.html#a19c944664a2e36f06ae71b745fbd442e',1,'QwtAbstractScaleDraw::QwtAbstractScaleDraw()']]], + ['qwtabstractseriesstore',['QwtAbstractSeriesStore',['../class_qwt_abstract_series_store.html',1,'']]], + ['qwtabstractslider',['QwtAbstractSlider',['../class_qwt_abstract_slider.html',1,'QwtAbstractSlider'],['../class_qwt_abstract_slider.html#af539373e763744c295f90b919fc37870',1,'QwtAbstractSlider::QwtAbstractSlider()']]], + ['qwtalphacolormap',['QwtAlphaColorMap',['../class_qwt_alpha_color_map.html',1,'QwtAlphaColorMap'],['../class_qwt_alpha_color_map.html#af78213a5ff1ebef8a8d4447b0987bf32',1,'QwtAlphaColorMap::QwtAlphaColorMap()']]], + ['qwtanalogclock',['QwtAnalogClock',['../class_qwt_analog_clock.html',1,'QwtAnalogClock'],['../class_qwt_analog_clock.html#af52a1110f1db89c162f49a23772745b9',1,'QwtAnalogClock::QwtAnalogClock()']]], + ['qwtarrayseriesdata',['QwtArraySeriesData',['../class_qwt_array_series_data.html',1,'QwtArraySeriesData< T >'],['../class_qwt_array_series_data.html#a3cb14bbe2b27bf8d49994d80e8eab3ee',1,'QwtArraySeriesData::QwtArraySeriesData()'],['../class_qwt_array_series_data.html#a4bb811309027ac378a2dcc50ff9ef829',1,'QwtArraySeriesData::QwtArraySeriesData(const QVector< T > &samples)']]], + ['qwtarrayseriesdata_3c_20qpointf_20_3e',['QwtArraySeriesData< QPointF >',['../class_qwt_array_series_data.html',1,'']]], + ['qwtarrayseriesdata_3c_20qwtintervalsample_20_3e',['QwtArraySeriesData< QwtIntervalSample >',['../class_qwt_array_series_data.html',1,'']]], + ['qwtarrayseriesdata_3c_20qwtohlcsample_20_3e',['QwtArraySeriesData< QwtOHLCSample >',['../class_qwt_array_series_data.html',1,'']]], + ['qwtarrayseriesdata_3c_20qwtpoint3d_20_3e',['QwtArraySeriesData< QwtPoint3D >',['../class_qwt_array_series_data.html',1,'']]], + ['qwtarrayseriesdata_3c_20qwtsetsample_20_3e',['QwtArraySeriesData< QwtSetSample >',['../class_qwt_array_series_data.html',1,'']]], + ['qwtarrowbutton',['QwtArrowButton',['../class_qwt_arrow_button.html',1,'QwtArrowButton'],['../class_qwt_arrow_button.html#ab0ad5aefdd56db10976796be717671e9',1,'QwtArrowButton::QwtArrowButton()']]], + ['qwtclipper',['QwtClipper',['../class_qwt_clipper.html',1,'']]], + ['qwtcolormap',['QwtColorMap',['../class_qwt_color_map.html',1,'QwtColorMap'],['../class_qwt_color_map.html#a2ab0a6041ea6d37c0609ca2e3bd976ca',1,'QwtColorMap::QwtColorMap()']]], + ['qwtcolumnrect',['QwtColumnRect',['../class_qwt_column_rect.html',1,'QwtColumnRect'],['../class_qwt_column_rect.html#ad3eeebc150334ee9393d7aff4f33c873',1,'QwtColumnRect::QwtColumnRect()']]], + ['qwtcolumnsymbol',['QwtColumnSymbol',['../class_qwt_column_symbol.html',1,'QwtColumnSymbol'],['../class_qwt_column_symbol.html#a78d6b04908f7f814cdc07c3ae704b329',1,'QwtColumnSymbol::QwtColumnSymbol()']]], + ['qwtcompass',['QwtCompass',['../class_qwt_compass.html',1,'QwtCompass'],['../class_qwt_compass.html#a05357e2950a3dc534e68e3c21f6c6b94',1,'QwtCompass::QwtCompass()']]], + ['qwtcompassmagnetneedle',['QwtCompassMagnetNeedle',['../class_qwt_compass_magnet_needle.html',1,'QwtCompassMagnetNeedle'],['../class_qwt_compass_magnet_needle.html#a3422e6490d44c527289bafdcceecd741',1,'QwtCompassMagnetNeedle::QwtCompassMagnetNeedle()']]], + ['qwtcompassrose',['QwtCompassRose',['../class_qwt_compass_rose.html',1,'']]], + ['qwtcompassscaledraw',['QwtCompassScaleDraw',['../class_qwt_compass_scale_draw.html',1,'QwtCompassScaleDraw'],['../class_qwt_compass_scale_draw.html#af5454a1e7d4d511e43c91f008fe65c06',1,'QwtCompassScaleDraw::QwtCompassScaleDraw()'],['../class_qwt_compass_scale_draw.html#ab8f8902087f6ba6428d637395451adfa',1,'QwtCompassScaleDraw::QwtCompassScaleDraw(const QMap< double, QString > &map)']]], + ['qwtcompasswindarrow',['QwtCompassWindArrow',['../class_qwt_compass_wind_arrow.html',1,'QwtCompassWindArrow'],['../class_qwt_compass_wind_arrow.html#a1b5931f43dd7e72fc5a3e2c9b509769d',1,'QwtCompassWindArrow::QwtCompassWindArrow()']]], + ['qwtcounter',['QwtCounter',['../class_qwt_counter.html',1,'QwtCounter'],['../class_qwt_counter.html#aee94cdbaf1f3d22e110fd3535dbca34a',1,'QwtCounter::QwtCounter()']]], + ['qwtcpointerdata',['QwtCPointerData',['../class_qwt_c_pointer_data.html',1,'QwtCPointerData'],['../class_qwt_c_pointer_data.html#a795b86d69226d1aabf9356848da6c083',1,'QwtCPointerData::QwtCPointerData()']]], + ['qwtcurvefitter',['QwtCurveFitter',['../class_qwt_curve_fitter.html',1,'QwtCurveFitter'],['../class_qwt_curve_fitter.html#ad804660017ae0f3ede604470724b3df3',1,'QwtCurveFitter::QwtCurveFitter()']]], + ['qwtdate',['QwtDate',['../class_qwt_date.html',1,'']]], + ['qwtdatescaledraw',['QwtDateScaleDraw',['../class_qwt_date_scale_draw.html',1,'QwtDateScaleDraw'],['../class_qwt_date_scale_draw.html#adbee23e84bc296b09f5a6d54252b75ba',1,'QwtDateScaleDraw::QwtDateScaleDraw()']]], + ['qwtdatescaleengine',['QwtDateScaleEngine',['../class_qwt_date_scale_engine.html',1,'QwtDateScaleEngine'],['../class_qwt_date_scale_engine.html#a7eb99ee3e701d6f8467b1e9c8c248b9b',1,'QwtDateScaleEngine::QwtDateScaleEngine()']]], + ['qwtdial',['QwtDial',['../class_qwt_dial.html',1,'QwtDial'],['../class_qwt_dial.html#a910ad090ceb51587c965d9a2c9db8f60',1,'QwtDial::QwtDial()']]], + ['qwtdialneedle',['QwtDialNeedle',['../class_qwt_dial_needle.html',1,'QwtDialNeedle'],['../class_qwt_dial_needle.html#aef3af79632ce784bc4d7332f6e269a1f',1,'QwtDialNeedle::QwtDialNeedle()']]], + ['qwtdialsimpleneedle',['QwtDialSimpleNeedle',['../class_qwt_dial_simple_needle.html',1,'QwtDialSimpleNeedle'],['../class_qwt_dial_simple_needle.html#a5f16b9298ecd293360a3ccf91d3dbfbb',1,'QwtDialSimpleNeedle::QwtDialSimpleNeedle()']]], + ['qwtdyngridlayout',['QwtDynGridLayout',['../class_qwt_dyn_grid_layout.html',1,'QwtDynGridLayout'],['../class_qwt_dyn_grid_layout.html#a2079ddcba8442ef9f386556dd9cb8cc6',1,'QwtDynGridLayout::QwtDynGridLayout(QWidget *, int margin=0, int space=-1)'],['../class_qwt_dyn_grid_layout.html#a05d45c0928702e37da3497626b0f7c93',1,'QwtDynGridLayout::QwtDynGridLayout(int space=-1)']]], + ['qwteventpattern',['QwtEventPattern',['../class_qwt_event_pattern.html',1,'QwtEventPattern'],['../class_qwt_event_pattern.html#a1236c9239a3d8281d66b255ad18f7ee2',1,'QwtEventPattern::QwtEventPattern()']]], + ['qwtgraphic',['QwtGraphic',['../class_qwt_graphic.html',1,'QwtGraphic'],['../class_qwt_graphic.html#a45805a4faf2247ae42ccee21f37dabd2',1,'QwtGraphic::QwtGraphic()'],['../class_qwt_graphic.html#a12bf98d94b68b344e9e4f97c0a15f649',1,'QwtGraphic::QwtGraphic(const QwtGraphic &)']]], + ['qwtinterval',['QwtInterval',['../class_qwt_interval.html',1,'QwtInterval'],['../class_qwt_interval.html#acd8699b69f46bcea31fa225d1425add3',1,'QwtInterval::QwtInterval()'],['../class_qwt_interval.html#a6c48e99ff0a44784a4084dd8b1bc3fec',1,'QwtInterval::QwtInterval(double minValue, double maxValue, BorderFlags=IncludeBorders)']]], + ['qwtintervalsample',['QwtIntervalSample',['../class_qwt_interval_sample.html',1,'QwtIntervalSample'],['../class_qwt_interval_sample.html#a9f1259560f2628f8d32a648076c09d23',1,'QwtIntervalSample::QwtIntervalSample()'],['../class_qwt_interval_sample.html#a1e17c77625481f0987ed0bc7f461499c',1,'QwtIntervalSample::QwtIntervalSample(double, const QwtInterval &)'],['../class_qwt_interval_sample.html#a02e2490f2bbc671a1a771c53ab2889da',1,'QwtIntervalSample::QwtIntervalSample(double value, double min, double max)']]], + ['qwtintervalseriesdata',['QwtIntervalSeriesData',['../class_qwt_interval_series_data.html',1,'QwtIntervalSeriesData'],['../class_qwt_interval_series_data.html#ae85a2103d690c67f0e17aab94884bb79',1,'QwtIntervalSeriesData::QwtIntervalSeriesData()']]], + ['qwtintervalsymbol',['QwtIntervalSymbol',['../class_qwt_interval_symbol.html',1,'QwtIntervalSymbol'],['../class_qwt_interval_symbol.html#a40c03c5b54dc3c4a69cf1dc88bf25893',1,'QwtIntervalSymbol::QwtIntervalSymbol(Style=NoSymbol)'],['../class_qwt_interval_symbol.html#a7a4ddf7e61445833f39105614ebd77c1',1,'QwtIntervalSymbol::QwtIntervalSymbol(const QwtIntervalSymbol &)']]], + ['qwtknob',['QwtKnob',['../class_qwt_knob.html',1,'QwtKnob'],['../class_qwt_knob.html#a767e89f3d4875da7d2074050572e0556',1,'QwtKnob::QwtKnob()']]], + ['qwtlegend',['QwtLegend',['../class_qwt_legend.html',1,'QwtLegend'],['../class_qwt_legend.html#adf5a64070a546eaac36fc9afac56b7fb',1,'QwtLegend::QwtLegend()']]], + ['qwtlegenddata',['QwtLegendData',['../class_qwt_legend_data.html',1,'QwtLegendData'],['../class_qwt_legend_data.html#a519e4f01583d051e4b2458ab9dfcb196',1,'QwtLegendData::QwtLegendData()']]], + ['qwtlegendlabel',['QwtLegendLabel',['../class_qwt_legend_label.html',1,'QwtLegendLabel'],['../class_qwt_legend_label.html#a557315a25a130c2608a2f63613096ab9',1,'QwtLegendLabel::QwtLegendLabel()']]], + ['qwt_20license_2c_20version_201_2e0',['Qwt License, Version 1.0',['../qwtlicense.html',1,'']]], + ['qwtlinearcolormap',['QwtLinearColorMap',['../class_qwt_linear_color_map.html',1,'QwtLinearColorMap'],['../class_qwt_linear_color_map.html#a0ef6a29bb027017aad89a4c4a4b07019',1,'QwtLinearColorMap::QwtLinearColorMap(QwtColorMap::Format=QwtColorMap::RGB)'],['../class_qwt_linear_color_map.html#ae591cf441db15a021c25d0b58bfa7a5e',1,'QwtLinearColorMap::QwtLinearColorMap(const QColor &from, const QColor &to, QwtColorMap::Format=QwtColorMap::RGB)']]], + ['qwtlinearscaleengine',['QwtLinearScaleEngine',['../class_qwt_linear_scale_engine.html',1,'QwtLinearScaleEngine'],['../class_qwt_linear_scale_engine.html#a989e6f0fabe43934f1ed7c0ca290ab03',1,'QwtLinearScaleEngine::QwtLinearScaleEngine()']]], + ['qwtlogscaleengine',['QwtLogScaleEngine',['../class_qwt_log_scale_engine.html',1,'QwtLogScaleEngine'],['../class_qwt_log_scale_engine.html#a68f89f870f918c2ecc56d8d2b0074a3a',1,'QwtLogScaleEngine::QwtLogScaleEngine()']]], + ['qwtlogtransform',['QwtLogTransform',['../class_qwt_log_transform.html',1,'QwtLogTransform'],['../class_qwt_log_transform.html#ae38156a50ab292af9638a78a374c30ff',1,'QwtLogTransform::QwtLogTransform()']]], + ['qwtmagnifier',['QwtMagnifier',['../class_qwt_magnifier.html',1,'QwtMagnifier'],['../class_qwt_magnifier.html#aa11b927c72e0421570a137f0fa1cfb7b',1,'QwtMagnifier::QwtMagnifier()']]], + ['qwtmathmltextengine',['QwtMathMLTextEngine',['../class_qwt_math_m_l_text_engine.html',1,'QwtMathMLTextEngine'],['../class_qwt_math_m_l_text_engine.html#af88b085974808e0497d120044672f721',1,'QwtMathMLTextEngine::QwtMathMLTextEngine()']]], + ['qwtmatrixrasterdata',['QwtMatrixRasterData',['../class_qwt_matrix_raster_data.html',1,'QwtMatrixRasterData'],['../class_qwt_matrix_raster_data.html#a3e80514459cc6aab03cfd839da53e45e',1,'QwtMatrixRasterData::QwtMatrixRasterData()']]], + ['qwtnullpaintdevice',['QwtNullPaintDevice',['../class_qwt_null_paint_device.html',1,'QwtNullPaintDevice'],['../class_qwt_null_paint_device.html#a7fc0a16619aba83241eab7ecb83c80ca',1,'QwtNullPaintDevice::QwtNullPaintDevice()']]], + ['qwtnulltransform',['QwtNullTransform',['../class_qwt_null_transform.html',1,'QwtNullTransform'],['../class_qwt_null_transform.html#a0e5ec82fc1aef04b684108ff8334dd1e',1,'QwtNullTransform::QwtNullTransform()']]], + ['qwtohlcsample',['QwtOHLCSample',['../class_qwt_o_h_l_c_sample.html',1,'QwtOHLCSample'],['../class_qwt_o_h_l_c_sample.html#ad4056581f619e0a36d854fc5bb4341ef',1,'QwtOHLCSample::QwtOHLCSample()']]], + ['qwtpainter',['QwtPainter',['../class_qwt_painter.html',1,'']]], + ['qwtpaintercommand',['QwtPainterCommand',['../class_qwt_painter_command.html',1,'QwtPainterCommand'],['../class_qwt_painter_command.html#a0a3ce67b97475d9ff41c26542d216e22',1,'QwtPainterCommand::QwtPainterCommand()'],['../class_qwt_painter_command.html#aa67dd2e6a432635c101295de585ffdcd',1,'QwtPainterCommand::QwtPainterCommand(const QwtPainterCommand &)'],['../class_qwt_painter_command.html#a8648ff991175d5f06bae6b04df06bd03',1,'QwtPainterCommand::QwtPainterCommand(const QPainterPath &)'],['../class_qwt_painter_command.html#a7dae6c078fdb8d173358e988f06e2163',1,'QwtPainterCommand::QwtPainterCommand(const QRectF &rect, const QPixmap &, const QRectF &subRect)'],['../class_qwt_painter_command.html#a3830b0c0f920588107a3acc1ab05853b',1,'QwtPainterCommand::QwtPainterCommand(const QRectF &rect, const QImage &, const QRectF &subRect, Qt::ImageConversionFlags)'],['../class_qwt_painter_command.html#adcd99c908be8b5e57dee2f7dbed73dc3',1,'QwtPainterCommand::QwtPainterCommand(const QPaintEngineState &)']]], + ['qwtpanner',['QwtPanner',['../class_qwt_panner.html',1,'QwtPanner'],['../class_qwt_panner.html#af5482be26d69a64c3880653265240736',1,'QwtPanner::QwtPanner()']]], + ['qwtpicker',['QwtPicker',['../class_qwt_picker.html',1,'QwtPicker'],['../class_qwt_picker.html#af9a5f4b0e4b37e2f323e801aa9dd6fe1',1,'QwtPicker::QwtPicker(QWidget *parent)'],['../class_qwt_picker.html#ac04e38a178229292cfff4f3110ffbe5e',1,'QwtPicker::QwtPicker(RubberBand rubberBand, DisplayMode trackerMode, QWidget *)']]], + ['qwtpickerclickpointmachine',['QwtPickerClickPointMachine',['../class_qwt_picker_click_point_machine.html',1,'QwtPickerClickPointMachine'],['../class_qwt_picker_click_point_machine.html#aa4bab7db982c16270176957451db1d8e',1,'QwtPickerClickPointMachine::QwtPickerClickPointMachine()']]], + ['qwtpickerclickrectmachine',['QwtPickerClickRectMachine',['../class_qwt_picker_click_rect_machine.html',1,'QwtPickerClickRectMachine'],['../class_qwt_picker_click_rect_machine.html#ac154f2cb83e86f8b5d9d410c53b4bdb4',1,'QwtPickerClickRectMachine::QwtPickerClickRectMachine()']]], + ['qwtpickerdraglinemachine',['QwtPickerDragLineMachine',['../class_qwt_picker_drag_line_machine.html',1,'QwtPickerDragLineMachine'],['../class_qwt_picker_drag_line_machine.html#acf3157352ff3d68fdd000e8a944467b3',1,'QwtPickerDragLineMachine::QwtPickerDragLineMachine()']]], + ['qwtpickerdragpointmachine',['QwtPickerDragPointMachine',['../class_qwt_picker_drag_point_machine.html',1,'QwtPickerDragPointMachine'],['../class_qwt_picker_drag_point_machine.html#af534289d12a39eeb9b52402b61967fac',1,'QwtPickerDragPointMachine::QwtPickerDragPointMachine()']]], + ['qwtpickerdragrectmachine',['QwtPickerDragRectMachine',['../class_qwt_picker_drag_rect_machine.html',1,'QwtPickerDragRectMachine'],['../class_qwt_picker_drag_rect_machine.html#a49ce41d12442bc295578c0682cb38682',1,'QwtPickerDragRectMachine::QwtPickerDragRectMachine()']]], + ['qwtpickermachine',['QwtPickerMachine',['../class_qwt_picker_machine.html',1,'QwtPickerMachine'],['../class_qwt_picker_machine.html#ab27bc3f70d48aa145db9ebbfdba34e15',1,'QwtPickerMachine::QwtPickerMachine()']]], + ['qwtpickerpolygonmachine',['QwtPickerPolygonMachine',['../class_qwt_picker_polygon_machine.html',1,'QwtPickerPolygonMachine'],['../class_qwt_picker_polygon_machine.html#ab6da61726ca16c06a1d9c02f067492c6',1,'QwtPickerPolygonMachine::QwtPickerPolygonMachine()']]], + ['qwtpickertrackermachine',['QwtPickerTrackerMachine',['../class_qwt_picker_tracker_machine.html',1,'QwtPickerTrackerMachine'],['../class_qwt_picker_tracker_machine.html#a730ee0927456e192f777c225277b3fe0',1,'QwtPickerTrackerMachine::QwtPickerTrackerMachine()']]], + ['qwtpixelmatrix',['QwtPixelMatrix',['../class_qwt_pixel_matrix.html',1,'QwtPixelMatrix'],['../class_qwt_pixel_matrix.html#aa197eddf30db429ab267db2a875e7d71',1,'QwtPixelMatrix::QwtPixelMatrix()']]], + ['qwtplaintextengine',['QwtPlainTextEngine',['../class_qwt_plain_text_engine.html',1,'QwtPlainTextEngine'],['../class_qwt_plain_text_engine.html#a0ad29b2229a879afe49b546704eb7079',1,'QwtPlainTextEngine::QwtPlainTextEngine()']]], + ['qwtplot',['QwtPlot',['../class_qwt_plot.html',1,'QwtPlot'],['../class_qwt_plot.html#acde7121614da027e9a1dbc4591613ca7',1,'QwtPlot::QwtPlot(QWidget *=NULL)'],['../class_qwt_plot.html#a3c9b10d39c181991f24eab1828ad68a5',1,'QwtPlot::QwtPlot(const QwtText &title, QWidget *=NULL)']]], + ['qwtplotabstractbarchart',['QwtPlotAbstractBarChart',['../class_qwt_plot_abstract_bar_chart.html',1,'QwtPlotAbstractBarChart'],['../class_qwt_plot_abstract_bar_chart.html#a1eed4138383e5f0d118d518fd0255711',1,'QwtPlotAbstractBarChart::QwtPlotAbstractBarChart()']]], + ['qwtplotbarchart',['QwtPlotBarChart',['../class_qwt_plot_bar_chart.html',1,'QwtPlotBarChart'],['../class_qwt_plot_bar_chart.html#abc94e8caf46d58726de297d00a09575d',1,'QwtPlotBarChart::QwtPlotBarChart(const QString &title=QString::null)'],['../class_qwt_plot_bar_chart.html#a99bf404571a13a0f9a4e3a01cbe69d8a',1,'QwtPlotBarChart::QwtPlotBarChart(const QwtText &title)']]], + ['qwtplotcanvas',['QwtPlotCanvas',['../class_qwt_plot_canvas.html',1,'QwtPlotCanvas'],['../class_qwt_plot_canvas.html#a8b0cd76cd283f8f35331dfc7543cbf89',1,'QwtPlotCanvas::QwtPlotCanvas()']]], + ['qwtplotcurve',['QwtPlotCurve',['../class_qwt_plot_curve.html',1,'QwtPlotCurve'],['../class_qwt_plot_curve.html#ac7d2d9e21ee3e054b51fb954cf95c820',1,'QwtPlotCurve::QwtPlotCurve(const QString &title=QString::null)'],['../class_qwt_plot_curve.html#a3bcaa88363509f4bc1ad92bee498f203',1,'QwtPlotCurve::QwtPlotCurve(const QwtText &title)']]], + ['qwtplotdict',['QwtPlotDict',['../class_qwt_plot_dict.html',1,'QwtPlotDict'],['../class_qwt_plot_dict.html#a0ee364450834ac63f4cbd5baab82d15f',1,'QwtPlotDict::QwtPlotDict()']]], + ['qwtplotdirectpainter',['QwtPlotDirectPainter',['../class_qwt_plot_direct_painter.html',1,'QwtPlotDirectPainter'],['../class_qwt_plot_direct_painter.html#af9e6e2056afd4db4c081e4b04d5c9a85',1,'QwtPlotDirectPainter::QwtPlotDirectPainter()']]], + ['qwtplotglcanvas',['QwtPlotGLCanvas',['../class_qwt_plot_g_l_canvas.html',1,'QwtPlotGLCanvas'],['../class_qwt_plot_g_l_canvas.html#adc7704723f078ff57243a2e2fc217832',1,'QwtPlotGLCanvas::QwtPlotGLCanvas()']]], + ['qwtplotgrid',['QwtPlotGrid',['../class_qwt_plot_grid.html',1,'QwtPlotGrid'],['../class_qwt_plot_grid.html#a43001238f3024c15baa8ae61b29ae170',1,'QwtPlotGrid::QwtPlotGrid()']]], + ['qwtplothistogram',['QwtPlotHistogram',['../class_qwt_plot_histogram.html',1,'QwtPlotHistogram'],['../class_qwt_plot_histogram.html#ada0642611a7edc4ea3beac45428fd786',1,'QwtPlotHistogram::QwtPlotHistogram(const QString &title=QString::null)'],['../class_qwt_plot_histogram.html#a5c0973a9425655be4218298706d25f38',1,'QwtPlotHistogram::QwtPlotHistogram(const QwtText &title)']]], + ['qwtplotintervalcurve',['QwtPlotIntervalCurve',['../class_qwt_plot_interval_curve.html',1,'QwtPlotIntervalCurve'],['../class_qwt_plot_interval_curve.html#af5bfe837aec8dc8884394ca7813a8d41',1,'QwtPlotIntervalCurve::QwtPlotIntervalCurve(const QString &title=QString::null)'],['../class_qwt_plot_interval_curve.html#ab7d0884ffb900fc453d621580f348c0e',1,'QwtPlotIntervalCurve::QwtPlotIntervalCurve(const QwtText &title)']]], + ['qwtplotitem',['QwtPlotItem',['../class_qwt_plot_item.html',1,'QwtPlotItem'],['../class_qwt_plot_item.html#a5d892ac856fb9176515c5f2d806161dc',1,'QwtPlotItem::QwtPlotItem()']]], + ['qwtplotlayout',['QwtPlotLayout',['../class_qwt_plot_layout.html',1,'QwtPlotLayout'],['../class_qwt_plot_layout.html#ac89596fb2a3d3a92901f124821045a47',1,'QwtPlotLayout::QwtPlotLayout()']]], + ['qwtplotlegenditem',['QwtPlotLegendItem',['../class_qwt_plot_legend_item.html',1,'QwtPlotLegendItem'],['../class_qwt_plot_legend_item.html#a5e647b9936095cde8193214d6a89b07f',1,'QwtPlotLegendItem::QwtPlotLegendItem()']]], + ['qwtplotmagnifier',['QwtPlotMagnifier',['../class_qwt_plot_magnifier.html',1,'QwtPlotMagnifier'],['../class_qwt_plot_magnifier.html#a6edabe11a02cae3ae8e8adaa9013d109',1,'QwtPlotMagnifier::QwtPlotMagnifier()']]], + ['qwtplotmarker',['QwtPlotMarker',['../class_qwt_plot_marker.html',1,'QwtPlotMarker'],['../class_qwt_plot_marker.html#a0333be3f54ed6096e8efdeadf1809f7a',1,'QwtPlotMarker::QwtPlotMarker(const QString &title=QString::null)'],['../class_qwt_plot_marker.html#a230b1a284a58732e02fd65678a14c455',1,'QwtPlotMarker::QwtPlotMarker(const QwtText &title)']]], + ['qwtplotmultibarchart',['QwtPlotMultiBarChart',['../class_qwt_plot_multi_bar_chart.html',1,'QwtPlotMultiBarChart'],['../class_qwt_plot_multi_bar_chart.html#a8e5a1a75c21f52f53a588a80f95d0317',1,'QwtPlotMultiBarChart::QwtPlotMultiBarChart(const QString &title=QString::null)'],['../class_qwt_plot_multi_bar_chart.html#a5e663f9492a0aff79e171997d779ffb4',1,'QwtPlotMultiBarChart::QwtPlotMultiBarChart(const QwtText &title)']]], + ['qwtplotpanner',['QwtPlotPanner',['../class_qwt_plot_panner.html',1,'QwtPlotPanner'],['../class_qwt_plot_panner.html#a94d661c312edbf7ef094dd32dff57d44',1,'QwtPlotPanner::QwtPlotPanner()']]], + ['qwtplotpicker',['QwtPlotPicker',['../class_qwt_plot_picker.html',1,'QwtPlotPicker'],['../class_qwt_plot_picker.html#ab63357cd493d0fa388193d515cb8bd38',1,'QwtPlotPicker::QwtPlotPicker(QWidget *canvas)'],['../class_qwt_plot_picker.html#ae8ae9704219d3874a4a20cb27cbe0665',1,'QwtPlotPicker::QwtPlotPicker(int xAxis, int yAxis, QWidget *)'],['../class_qwt_plot_picker.html#ad8d6d7be79511db92ad2ca0af70ea824',1,'QwtPlotPicker::QwtPlotPicker(int xAxis, int yAxis, RubberBand rubberBand, DisplayMode trackerMode, QWidget *)']]], + ['qwtplotrasteritem',['QwtPlotRasterItem',['../class_qwt_plot_raster_item.html',1,'QwtPlotRasterItem'],['../class_qwt_plot_raster_item.html#a2149c1d6b71c607027345a9a51ef3314',1,'QwtPlotRasterItem::QwtPlotRasterItem(const QString &title=QString::null)'],['../class_qwt_plot_raster_item.html#af487c6abc8e95200d4537d1373f96be5',1,'QwtPlotRasterItem::QwtPlotRasterItem(const QwtText &title)']]], + ['qwtplotrenderer',['QwtPlotRenderer',['../class_qwt_plot_renderer.html',1,'QwtPlotRenderer'],['../class_qwt_plot_renderer.html#aa265be7e2873a28dbb4f1788020cebe6',1,'QwtPlotRenderer::QwtPlotRenderer()']]], + ['qwtplotrescaler',['QwtPlotRescaler',['../class_qwt_plot_rescaler.html',1,'QwtPlotRescaler'],['../class_qwt_plot_rescaler.html#a4bef342d0a571af31685c2ff88def5d5',1,'QwtPlotRescaler::QwtPlotRescaler()']]], + ['qwtplotscaleitem',['QwtPlotScaleItem',['../class_qwt_plot_scale_item.html',1,'QwtPlotScaleItem'],['../class_qwt_plot_scale_item.html#a9d093fc9de7d423435f455c110d4605d',1,'QwtPlotScaleItem::QwtPlotScaleItem()']]], + ['qwtplotseriesitem',['QwtPlotSeriesItem',['../class_qwt_plot_series_item.html',1,'QwtPlotSeriesItem'],['../class_qwt_plot_series_item.html#a2c5f7667a8040b76454c1f70062dd010',1,'QwtPlotSeriesItem::QwtPlotSeriesItem(const QString &title=QString::null)'],['../class_qwt_plot_series_item.html#ada75c34290dbd2b12a199a70dbc0f2b9',1,'QwtPlotSeriesItem::QwtPlotSeriesItem(const QwtText &title)']]], + ['qwtplotshapeitem',['QwtPlotShapeItem',['../class_qwt_plot_shape_item.html',1,'QwtPlotShapeItem'],['../class_qwt_plot_shape_item.html#a0b2979ee8b1956ea4db4c0fc89b9c978',1,'QwtPlotShapeItem::QwtPlotShapeItem(const QString &title=QString::null)'],['../class_qwt_plot_shape_item.html#a33fb91a92c34c58c48d3de1ee278bbc7',1,'QwtPlotShapeItem::QwtPlotShapeItem(const QwtText &title)']]], + ['qwtplotspectrocurve',['QwtPlotSpectroCurve',['../class_qwt_plot_spectro_curve.html',1,'QwtPlotSpectroCurve'],['../class_qwt_plot_spectro_curve.html#aa02c00eb35a6f08ab11091ef66c737cd',1,'QwtPlotSpectroCurve::QwtPlotSpectroCurve(const QString &title=QString::null)'],['../class_qwt_plot_spectro_curve.html#a78170049ecb2b6681a107abf26783bd7',1,'QwtPlotSpectroCurve::QwtPlotSpectroCurve(const QwtText &title)']]], + ['qwtplotspectrogram',['QwtPlotSpectrogram',['../class_qwt_plot_spectrogram.html',1,'QwtPlotSpectrogram'],['../class_qwt_plot_spectrogram.html#ae90c0431be329ecbefc7ed9ac77f5ed6',1,'QwtPlotSpectrogram::QwtPlotSpectrogram()']]], + ['qwtplotsvgitem',['QwtPlotSvgItem',['../class_qwt_plot_svg_item.html',1,'QwtPlotSvgItem'],['../class_qwt_plot_svg_item.html#a3b6e505f0ef1d9e40030db2a8b60762e',1,'QwtPlotSvgItem::QwtPlotSvgItem(const QString &title=QString::null)'],['../class_qwt_plot_svg_item.html#ac750a4ff902302ab485971fcea6bee38',1,'QwtPlotSvgItem::QwtPlotSvgItem(const QwtText &title)']]], + ['qwtplottextlabel',['QwtPlotTextLabel',['../class_qwt_plot_text_label.html',1,'QwtPlotTextLabel'],['../class_qwt_plot_text_label.html#a19466cb637c30cfce5abfe024cbc3e3a',1,'QwtPlotTextLabel::QwtPlotTextLabel()']]], + ['qwtplottradingcurve',['QwtPlotTradingCurve',['../class_qwt_plot_trading_curve.html',1,'QwtPlotTradingCurve'],['../class_qwt_plot_trading_curve.html#a0a46b6269279e2c96b253d241025b13f',1,'QwtPlotTradingCurve::QwtPlotTradingCurve(const QString &title=QString::null)'],['../class_qwt_plot_trading_curve.html#aa8359acb3760cc9f8ccc8ab10d10262f',1,'QwtPlotTradingCurve::QwtPlotTradingCurve(const QwtText &title)']]], + ['qwtplotzoneitem',['QwtPlotZoneItem',['../class_qwt_plot_zone_item.html',1,'QwtPlotZoneItem'],['../class_qwt_plot_zone_item.html#aa63ced2cda200381e887a6a9e28a03b5',1,'QwtPlotZoneItem::QwtPlotZoneItem()']]], + ['qwtplotzoomer',['QwtPlotZoomer',['../class_qwt_plot_zoomer.html',1,'QwtPlotZoomer'],['../class_qwt_plot_zoomer.html#a1f77745e104b4a6300ebf1c6c3412b7e',1,'QwtPlotZoomer::QwtPlotZoomer(QWidget *, bool doReplot=true)'],['../class_qwt_plot_zoomer.html#a9fd8927796071ce7ab63341db5e0f1ed',1,'QwtPlotZoomer::QwtPlotZoomer(int xAxis, int yAxis, QWidget *, bool doReplot=true)']]], + ['qwtpoint3d',['QwtPoint3D',['../class_qwt_point3_d.html',1,'QwtPoint3D'],['../class_qwt_point3_d.html#acd7ec5a157397ce719225592b32cc510',1,'QwtPoint3D::QwtPoint3D()'],['../class_qwt_point3_d.html#a33b9fa088b750e1f4ded65c23fb62868',1,'QwtPoint3D::QwtPoint3D(double x, double y, double z)'],['../class_qwt_point3_d.html#a3847545c69e11d4c33891c5d9218afee',1,'QwtPoint3D::QwtPoint3D(const QwtPoint3D &)'],['../class_qwt_point3_d.html#a6747ac88e709543e57fc285e84181f49',1,'QwtPoint3D::QwtPoint3D(const QPointF &)']]], + ['qwtpoint3dseriesdata',['QwtPoint3DSeriesData',['../class_qwt_point3_d_series_data.html',1,'QwtPoint3DSeriesData'],['../class_qwt_point3_d_series_data.html#a4410e3dea4acccfdde70eb1f99829c16',1,'QwtPoint3DSeriesData::QwtPoint3DSeriesData()']]], + ['qwtpointarraydata',['QwtPointArrayData',['../class_qwt_point_array_data.html',1,'QwtPointArrayData'],['../class_qwt_point_array_data.html#a33044621333635f861b3945faf29cdc1',1,'QwtPointArrayData::QwtPointArrayData(const QVector< double > &x, const QVector< double > &y)'],['../class_qwt_point_array_data.html#ad83a51f37e5d626b60695baf3f0fd6fd',1,'QwtPointArrayData::QwtPointArrayData(const double *x, const double *y, size_t size)']]], + ['qwtpointmapper',['QwtPointMapper',['../class_qwt_point_mapper.html',1,'QwtPointMapper'],['../class_qwt_point_mapper.html#a6e5eabb9c1af9b035023376fa2e1c472',1,'QwtPointMapper::QwtPointMapper()']]], + ['qwtpointpolar',['QwtPointPolar',['../class_qwt_point_polar.html',1,'QwtPointPolar'],['../class_qwt_point_polar.html#a365875acf86a9f052e12784b5f2f7d44',1,'QwtPointPolar::QwtPointPolar()'],['../class_qwt_point_polar.html#af1c77f9730d441937e52ff5beee04975',1,'QwtPointPolar::QwtPointPolar(double azimuth, double radius)'],['../class_qwt_point_polar.html#ae5cd7e8ab0505672748f779c9668fe29',1,'QwtPointPolar::QwtPointPolar(const QwtPointPolar &)'],['../class_qwt_point_polar.html#a269241ca9f94f641063fe896cdd77165',1,'QwtPointPolar::QwtPointPolar(const QPointF &)']]], + ['qwtpointseriesdata',['QwtPointSeriesData',['../class_qwt_point_series_data.html',1,'QwtPointSeriesData'],['../class_qwt_point_series_data.html#aee91c50c88699839f7f5e720a23b9d3a',1,'QwtPointSeriesData::QwtPointSeriesData()']]], + ['qwtpowertransform',['QwtPowerTransform',['../class_qwt_power_transform.html',1,'QwtPowerTransform'],['../class_qwt_power_transform.html#af29ae09162f70bdf81bc5a6fabcb84ba',1,'QwtPowerTransform::QwtPowerTransform()']]], + ['qwtrasterdata',['QwtRasterData',['../class_qwt_raster_data.html',1,'QwtRasterData'],['../class_qwt_raster_data.html#a0fc20e05a794c0dc85f6ae5719566588',1,'QwtRasterData::QwtRasterData()']]], + ['qwtrichtextengine',['QwtRichTextEngine',['../class_qwt_rich_text_engine.html',1,'QwtRichTextEngine'],['../class_qwt_rich_text_engine.html#aa4c1d5a1ee88d7406ba1d6453005b46a',1,'QwtRichTextEngine::QwtRichTextEngine()']]], + ['qwtroundscaledraw',['QwtRoundScaleDraw',['../class_qwt_round_scale_draw.html',1,'QwtRoundScaleDraw'],['../class_qwt_round_scale_draw.html#a9c44d19488567825d826528b701587c8',1,'QwtRoundScaleDraw::QwtRoundScaleDraw()']]], + ['qwtsamplingthread',['QwtSamplingThread',['../class_qwt_sampling_thread.html',1,'QwtSamplingThread'],['../class_qwt_sampling_thread.html#afb02e4696306d5211b4b6470410afbfc',1,'QwtSamplingThread::QwtSamplingThread()']]], + ['qwtscalearithmetic',['QwtScaleArithmetic',['../class_qwt_scale_arithmetic.html',1,'']]], + ['qwtscalediv',['QwtScaleDiv',['../class_qwt_scale_div.html',1,'QwtScaleDiv'],['../class_qwt_scale_div.html#a724dd19a63de442c0eb493308649ff19',1,'QwtScaleDiv::QwtScaleDiv(double lowerBound=0.0, double upperBound=0.0)'],['../class_qwt_scale_div.html#abdc25d9fe6b2efdd76a60f363a7c719c',1,'QwtScaleDiv::QwtScaleDiv(const QwtInterval &, QList< double >[NTickTypes])'],['../class_qwt_scale_div.html#a7326c0f401dee07c2a2661166daf24ae',1,'QwtScaleDiv::QwtScaleDiv(double lowerBound, double upperBound, QList< double >[NTickTypes])'],['../class_qwt_scale_div.html#a1c011f6d8ac4832b69b447d870a8f735',1,'QwtScaleDiv::QwtScaleDiv(double lowerBound, double upperBound, const QList< double > &minorTicks, const QList< double > &mediumTicks, const QList< double > &majorTicks)']]], + ['qwtscaledraw',['QwtScaleDraw',['../class_qwt_scale_draw.html',1,'QwtScaleDraw'],['../class_qwt_scale_draw.html#adbd01ba8d7f19fb3122f917b1c74145b',1,'QwtScaleDraw::QwtScaleDraw()']]], + ['qwtscaleengine',['QwtScaleEngine',['../class_qwt_scale_engine.html',1,'QwtScaleEngine'],['../class_qwt_scale_engine.html#a4ad501667558e5095d36cc190d12790d',1,'QwtScaleEngine::QwtScaleEngine()']]], + ['qwtscalemap',['QwtScaleMap',['../class_qwt_scale_map.html',1,'QwtScaleMap'],['../class_qwt_scale_map.html#a9576a2e19c0be1d036fee344ab68f542',1,'QwtScaleMap::QwtScaleMap()'],['../class_qwt_scale_map.html#a579bc766106d98edd7153e62ea77a19b',1,'QwtScaleMap::QwtScaleMap(const QwtScaleMap &)']]], + ['qwtscalewidget',['QwtScaleWidget',['../class_qwt_scale_widget.html',1,'QwtScaleWidget'],['../class_qwt_scale_widget.html#addfd5f0802f85f8abee1d3ff7a1617d6',1,'QwtScaleWidget::QwtScaleWidget(QWidget *parent=NULL)'],['../class_qwt_scale_widget.html#a13c0c28d56a9e44a81990c7c3fbb96e5',1,'QwtScaleWidget::QwtScaleWidget(QwtScaleDraw::Alignment, QWidget *parent=NULL)']]], + ['qwtseriesdata',['QwtSeriesData',['../class_qwt_series_data.html',1,'QwtSeriesData< T >'],['../class_qwt_series_data.html#a3f075340d18fb112a342d74716eb8d9c',1,'QwtSeriesData::QwtSeriesData()']]], + ['qwtseriesdata_3c_20qpointf_20_3e',['QwtSeriesData< QPointF >',['../class_qwt_series_data.html',1,'']]], + ['qwtseriesdata_3c_20qwtintervalsample_20_3e',['QwtSeriesData< QwtIntervalSample >',['../class_qwt_series_data.html',1,'']]], + ['qwtseriesdata_3c_20qwtohlcsample_20_3e',['QwtSeriesData< QwtOHLCSample >',['../class_qwt_series_data.html',1,'']]], + ['qwtseriesdata_3c_20qwtpoint3d_20_3e',['QwtSeriesData< QwtPoint3D >',['../class_qwt_series_data.html',1,'']]], + ['qwtseriesdata_3c_20qwtsetsample_20_3e',['QwtSeriesData< QwtSetSample >',['../class_qwt_series_data.html',1,'']]], + ['qwtseriesstore',['QwtSeriesStore',['../class_qwt_series_store.html',1,'QwtSeriesStore< T >'],['../class_qwt_series_store.html#aa23545f522f87da936c0f095ee07c80e',1,'QwtSeriesStore::QwtSeriesStore()']]], + ['qwtseriesstore_3c_20qpointf_20_3e',['QwtSeriesStore< QPointF >',['../class_qwt_series_store.html',1,'']]], + ['qwtseriesstore_3c_20qwtintervalsample_20_3e',['QwtSeriesStore< QwtIntervalSample >',['../class_qwt_series_store.html',1,'']]], + ['qwtseriesstore_3c_20qwtohlcsample_20_3e',['QwtSeriesStore< QwtOHLCSample >',['../class_qwt_series_store.html',1,'']]], + ['qwtseriesstore_3c_20qwtpoint3d_20_3e',['QwtSeriesStore< QwtPoint3D >',['../class_qwt_series_store.html',1,'']]], + ['qwtseriesstore_3c_20qwtsetsample_20_3e',['QwtSeriesStore< QwtSetSample >',['../class_qwt_series_store.html',1,'']]], + ['qwtsetsample',['QwtSetSample',['../class_qwt_set_sample.html',1,'QwtSetSample'],['../class_qwt_set_sample.html#af506c3484b65d5de2b6042755066ff81',1,'QwtSetSample::QwtSetSample()'],['../class_qwt_set_sample.html#af0bbb11cf7ed592107a4baf052290035',1,'QwtSetSample::QwtSetSample(double, const QVector< double > &=QVector< double >())']]], + ['qwtsetseriesdata',['QwtSetSeriesData',['../class_qwt_set_series_data.html',1,'QwtSetSeriesData'],['../class_qwt_set_series_data.html#ae28991355a06876fcd14d760771e431b',1,'QwtSetSeriesData::QwtSetSeriesData()']]], + ['qwtsimplecompassrose',['QwtSimpleCompassRose',['../class_qwt_simple_compass_rose.html',1,'QwtSimpleCompassRose'],['../class_qwt_simple_compass_rose.html#a66cc98efe5717eaf11fb0e713cd1aa21',1,'QwtSimpleCompassRose::QwtSimpleCompassRose()']]], + ['qwtslider',['QwtSlider',['../class_qwt_slider.html',1,'QwtSlider'],['../class_qwt_slider.html#a6012d14e7a24752fca8828e1e1bedaa4',1,'QwtSlider::QwtSlider(QWidget *parent=NULL)'],['../class_qwt_slider.html#a5a4132613bc376adeabfedfe2f6bd02a',1,'QwtSlider::QwtSlider(Qt::Orientation, QWidget *parent=NULL)']]], + ['qwtspline',['QwtSpline',['../class_qwt_spline.html',1,'QwtSpline'],['../class_qwt_spline.html#a5d1e0ba35c637a88c66d9e4cbaf36e93',1,'QwtSpline::QwtSpline()'],['../class_qwt_spline.html#a2e42391f76d0b3091bf7754239f3ff0d',1,'QwtSpline::QwtSpline(const QwtSpline &)']]], + ['qwtsplinecurvefitter',['QwtSplineCurveFitter',['../class_qwt_spline_curve_fitter.html',1,'QwtSplineCurveFitter'],['../class_qwt_spline_curve_fitter.html#a98ae80240b254df85dcc44e1f3e4e830',1,'QwtSplineCurveFitter::QwtSplineCurveFitter()']]], + ['qwtsymbol',['QwtSymbol',['../class_qwt_symbol.html',1,'QwtSymbol'],['../class_qwt_symbol.html#a710105d32ed915db46e4dbddc9cf6dc4',1,'QwtSymbol::QwtSymbol(Style=NoSymbol)'],['../class_qwt_symbol.html#a3fb872dc1cf5841df25ad6cba7fe9329',1,'QwtSymbol::QwtSymbol(Style, const QBrush &, const QPen &, const QSize &)'],['../class_qwt_symbol.html#aae936c253af0c441d19181d01b20b4a9',1,'QwtSymbol::QwtSymbol(const QPainterPath &, const QBrush &, const QPen &)']]], + ['qwtsyntheticpointdata',['QwtSyntheticPointData',['../class_qwt_synthetic_point_data.html',1,'QwtSyntheticPointData'],['../class_qwt_synthetic_point_data.html#ad2980a20669d9703046e9ded9cacf496',1,'QwtSyntheticPointData::QwtSyntheticPointData()']]], + ['qwtsystemclock',['QwtSystemClock',['../class_qwt_system_clock.html',1,'QwtSystemClock'],['../class_qwt_system_clock.html#a384e20d6049376575bf28306154854fd',1,'QwtSystemClock::QwtSystemClock()']]], + ['qwttext',['QwtText',['../class_qwt_text.html',1,'QwtText'],['../class_qwt_text.html#a91439964ad1150c136dcaa113a648ecf',1,'QwtText::QwtText(const QString &=QString::null, TextFormat textFormat=AutoText)'],['../class_qwt_text.html#af88b42733c420574fa76b2d58b965313',1,'QwtText::QwtText(const QwtText &)']]], + ['qwttextengine',['QwtTextEngine',['../class_qwt_text_engine.html',1,'QwtTextEngine'],['../class_qwt_text_engine.html#a97c5ef76ee920ab0f19e178e85017d9d',1,'QwtTextEngine::QwtTextEngine()']]], + ['qwttextlabel',['QwtTextLabel',['../class_qwt_text_label.html',1,'QwtTextLabel'],['../class_qwt_text_label.html#a95e022e766f4b9675f451482be7d654a',1,'QwtTextLabel::QwtTextLabel(QWidget *parent=NULL)'],['../class_qwt_text_label.html#a1a44e38b02bb398d315affe02bb4ea69',1,'QwtTextLabel::QwtTextLabel(const QwtText &, QWidget *parent=NULL)']]], + ['qwtthermo',['QwtThermo',['../class_qwt_thermo.html',1,'QwtThermo'],['../class_qwt_thermo.html#a1d5bb3608c29cd8d104f22f0ffe31098',1,'QwtThermo::QwtThermo()']]], + ['qwttradingchartdata',['QwtTradingChartData',['../class_qwt_trading_chart_data.html',1,'QwtTradingChartData'],['../class_qwt_trading_chart_data.html#abfe5df45f8a6313b68e93715c7bbfb7b',1,'QwtTradingChartData::QwtTradingChartData()']]], + ['qwttransform',['QwtTransform',['../class_qwt_transform.html',1,'QwtTransform'],['../class_qwt_transform.html#aa1fa1ab21d0fc01e06d3a6e462008d0b',1,'QwtTransform::QwtTransform()']]], + ['qwtweedingcurvefitter',['QwtWeedingCurveFitter',['../class_qwt_weeding_curve_fitter.html',1,'QwtWeedingCurveFitter'],['../class_qwt_weeding_curve_fitter.html#a7deb4d070a329cbdee454023194898a7',1,'QwtWeedingCurveFitter::QwtWeedingCurveFitter()']]], + ['qwtwheel',['QwtWheel',['../class_qwt_wheel.html',1,'QwtWheel'],['../class_qwt_wheel.html#a98fc47123aac47168b5d98a73b87d0a7',1,'QwtWheel::QwtWheel()']]], + ['qwtwidgetoverlay',['QwtWidgetOverlay',['../class_qwt_widget_overlay.html',1,'QwtWidgetOverlay'],['../class_qwt_widget_overlay.html#afeb3615cf79bee41bbae21f3b92b924d',1,'QwtWidgetOverlay::QwtWidgetOverlay()']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/all_72.html b/ThirdParty/Qwt/doc/html/search/all_72.html new file mode 100644 index 0000000000..347b9f6660 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/all_72.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/all_72.js b/ThirdParty/Qwt/doc/html/search/all_72.js new file mode 100644 index 0000000000..1058242b20 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/all_72.js @@ -0,0 +1,92 @@ +var searchData= +[ + ['radius',['radius',['../class_qwt_point_polar.html#ab629fcfb36f0f29df45b256c6bddf194',1,'QwtPointPolar::radius()'],['../class_qwt_round_scale_draw.html#ac5fba54e87a8bdcf01f909b5fe60ac1e',1,'QwtRoundScaleDraw::radius()']]], + ['raised',['Raised',['../class_qwt_column_symbol.html#a4b97f7748370447559a11a5adeb70e44a078f2b7db1cee79e83878fcc869df62e',1,'QwtColumnSymbol::Raised()'],['../class_qwt_dial.html#a7472124cb120352e8538430ab48c2386a4054b8890d1f837387762b4a12157847',1,'QwtDial::Raised()'],['../class_qwt_knob.html#addd00357b45752377aec83a3ab7208bea998504d08713af8a9af0d2cbe0aaf8df',1,'QwtKnob::Raised()'],['../class_qwt_plot_g_l_canvas.html#a6ce3b3cb6888443dfadca2399a632830a51c9540f673ec613857453927dc084cf',1,'QwtPlotGLCanvas::Raised()']]], + ['range',['range',['../class_qwt_scale_div.html#abe63aa19b346a4683ab19bf59a5bb37c',1,'QwtScaleDiv']]], + ['rangeflags',['rangeFlags',['../class_qwt_thermo.html#a3b05d842b667cf8724f8a900f0d05b34',1,'QwtThermo']]], + ['ray',['Ray',['../class_qwt_dial_simple_needle.html#ad28821489e04f1fd942e5bebc8a60584a580980e68ef26fc7d35962cf6f12a4b2',1,'QwtDialSimpleNeedle']]], + ['razimuth',['rAzimuth',['../class_qwt_point_polar.html#ae509330927d54dbc7cf65fae42083fce',1,'QwtPointPolar']]], + ['readonly',['ReadOnly',['../class_qwt_legend_data.html#aaa33cc8e6aec17440df5d4c38d7545b7add4342fbe2d82828b9ef7031c1b41a0b',1,'QwtLegendData']]], + ['rect',['rect',['../class_qwt_pixel_matrix.html#a05162507dc01b9616ef4b6b079786599',1,'QwtPixelMatrix::rect()'],['../class_qwt_symbol.html#a62f457952470c2076962e83ef2c24d2fa3c5d3b8c39e11cc10c6f0c8176bbd235',1,'QwtSymbol::Rect()']]], + ['rectofinterest',['rectOfInterest',['../class_qwt_synthetic_point_data.html#a00ead6b5e6cbc06d87af6edaa518d05f',1,'QwtSyntheticPointData']]], + ['rectrubberband',['RectRubberBand',['../class_qwt_picker.html#ab36c79d8ff20aba5b778d2823c1f7894ae4dc32fb99b4fe2058bb594ab5e8c70a',1,'QwtPicker']]], + ['rectselection',['RectSelection',['../class_qwt_picker_machine.html#a24a9faf12cfa5746eee839a2c0bb937da9f540e78958e8e238240584120e8af1d',1,'QwtPickerMachine']]], + ['reference',['reference',['../class_qwt_scale_engine.html#a5962458870865df797e84e3bd6badf02',1,'QwtScaleEngine']]], + ['referenceaxis',['referenceAxis',['../class_qwt_plot_rescaler.html#ae495168aec756dd617a5ad0c24e0eede',1,'QwtPlotRescaler']]], + ['released',['released',['../class_qwt_legend_label.html#a6e5dc9325dfed28651c8b40f17ba73af',1,'QwtLegendLabel']]], + ['remove',['remove',['../class_qwt_picker.html#a217ae414d4967e66def863b019194661',1,'QwtPicker']]], + ['removed',['removed',['../class_qwt_picker.html#ae43005f819fc423da4bad205d99e4d1e',1,'QwtPicker']]], + ['removeitem',['removeItem',['../class_qwt_plot_dict.html#abd0227e8b888b40b4e62a23f6040c6cd',1,'QwtPlotDict']]], + ['render',['render',['../class_qwt_graphic.html#a0bad97fa44e9270ba8bc66a370025a9f',1,'QwtGraphic::render(QPainter *) const '],['../class_qwt_graphic.html#af4d9626a5bb93bc83273f202e273b764',1,'QwtGraphic::render(QPainter *, const QSizeF &, Qt::AspectRatioMode=Qt::IgnoreAspectRatio) const '],['../class_qwt_graphic.html#afb45aff5460002a670ad7fabeae8d1d4',1,'QwtGraphic::render(QPainter *, const QRectF &, Qt::AspectRatioMode=Qt::IgnoreAspectRatio) const '],['../class_qwt_graphic.html#aa44399acb7c639a0a84dc427b59a3169',1,'QwtGraphic::render(QPainter *, const QPointF &, Qt::Alignment=Qt::AlignTop|Qt::AlignLeft) const '],['../class_qwt_plot_renderer.html#a44ff336a2d3d955ac17b1daa5fca3c31',1,'QwtPlotRenderer::render()'],['../class_qwt_plot_svg_item.html#a333715a1c09bdb07f3eb57d2272f2b90',1,'QwtPlotSvgItem::render()']]], + ['renderantialiased',['RenderAntialiased',['../class_qwt_plot_item.html#abe0e8a39aceef9a600b73e02550a9704ae0c9811915d496eaacbd749724647f13',1,'QwtPlotItem']]], + ['rendercanvas',['renderCanvas',['../class_qwt_plot_renderer.html#adbf07b9b77766b507dbe16791556b02c',1,'QwtPlotRenderer']]], + ['rendercontourlines',['renderContourLines',['../class_qwt_plot_spectrogram.html#aad79c66b4ab2b64f368378691f562b56',1,'QwtPlotSpectrogram']]], + ['renderdocument',['renderDocument',['../class_qwt_plot_renderer.html#a9e6c72105a0a6533a1a43efea91f62d9',1,'QwtPlotRenderer::renderDocument(QwtPlot *, const QString &fileName, const QSizeF &sizeMM, int resolution=85)'],['../class_qwt_plot_renderer.html#a983cfb85dc7896deedcda562141e8225',1,'QwtPlotRenderer::renderDocument(QwtPlot *, const QString &fileName, const QString &format, const QSizeF &sizeMM, int resolution=85)']]], + ['renderer',['renderer',['../class_qwt_plot_svg_item.html#a64d8e932edaaa7ffd5820be216eecadb',1,'QwtPlotSvgItem::renderer() const '],['../class_qwt_plot_svg_item.html#a7263211f1f91f669d9abd8e6dd9529a3',1,'QwtPlotSvgItem::renderer()']]], + ['renderflags',['renderFlags',['../class_qwt_text.html#a59c6bf54af867ce5632a07117fe442e1',1,'QwtText']]], + ['renderfooter',['renderFooter',['../class_qwt_plot_renderer.html#a9eb95db72559d1820c38fd6f772c7b4b',1,'QwtPlotRenderer']]], + ['renderhint',['RenderHint',['../class_qwt_graphic.html#a3f87dcc606b131ed6c3cfeead1d6de03',1,'QwtGraphic::RenderHint()'],['../class_qwt_plot_item.html#abe0e8a39aceef9a600b73e02550a9704',1,'QwtPlotItem::RenderHint()']]], + ['renderhints',['RenderHints',['../class_qwt_graphic.html#ac239a34c1c3fe47a3a57b70331c0d2fa',1,'QwtGraphic::RenderHints()'],['../class_qwt_plot_item.html#a40cf900701d3a68948b00316689616d1',1,'QwtPlotItem::RenderHints()']]], + ['renderimage',['renderImage',['../class_qwt_plot_raster_item.html#a1738b36c0e6e4073f3ad6629e7923f74',1,'QwtPlotRasterItem::renderImage()'],['../class_qwt_plot_spectrogram.html#a99fa9694347e6f06240538af88385ca6',1,'QwtPlotSpectrogram::renderImage()']]], + ['renderitem',['renderItem',['../class_qwt_legend.html#ad2f7db6a681a11d2af7a960a8db931f5',1,'QwtLegend']]], + ['renderlegend',['renderLegend',['../class_qwt_abstract_legend.html#a2fe1ac5ac1448e4d86b7437505214d9c',1,'QwtAbstractLegend::renderLegend()'],['../class_qwt_legend.html#aacc94e890b12b745619c02749628b6ce',1,'QwtLegend::renderLegend()'],['../class_qwt_plot_renderer.html#adbf1706f778a88d7db5304adde93b02a',1,'QwtPlotRenderer::renderLegend()']]], + ['rendermode',['RenderMode',['../class_qwt_widget_overlay.html#aaa8358f3b841b733d69e62aa645783d8',1,'QwtWidgetOverlay::RenderMode()'],['../class_qwt_widget_overlay.html#a33b227f98d26b0f1d4f2a0d5e9a6d99c',1,'QwtWidgetOverlay::renderMode() const ']]], + ['renderpensunscaled',['RenderPensUnscaled',['../class_qwt_graphic.html#a3f87dcc606b131ed6c3cfeead1d6de03ab70056f66aa75fb24c834cb3da7b0133',1,'QwtGraphic']]], + ['renderscale',['renderScale',['../class_qwt_plot_renderer.html#a3242670daa59fe5ba7b8b4d60339d3a1',1,'QwtPlotRenderer']]], + ['rendersymbols',['renderSymbols',['../class_qwt_symbol.html#ae72f15c4142dd2de7a361768c17e5560',1,'QwtSymbol']]], + ['renderthreadcount',['renderThreadCount',['../class_qwt_plot_item.html#acb8a2fce65770739fc263fd1fb19fcf3',1,'QwtPlotItem']]], + ['rendertile',['renderTile',['../class_qwt_plot_spectrogram.html#a122ad763c5195de93cac900bd3bcb112',1,'QwtPlotSpectrogram']]], + ['rendertitle',['renderTitle',['../class_qwt_plot_renderer.html#af793ca09c4f337fae62bfae962c8ade2',1,'QwtPlotRenderer']]], + ['renderto',['renderTo',['../class_qwt_plot_renderer.html#afa913f7f77dc04ab9fe0030df79c9806',1,'QwtPlotRenderer::renderTo(QwtPlot *, QPrinter &) const '],['../class_qwt_plot_renderer.html#a1501f42510d7f5c144d67baac5d129b5',1,'QwtPlotRenderer::renderTo(QwtPlot *, QPaintDevice &p) const ']]], + ['rendertolerance',['renderTolerance',['../class_qwt_plot_shape_item.html#aad8a52abd8293e8c01c07b5116db7970',1,'QwtPlotShapeItem']]], + ['replot',['replot',['../class_qwt_plot.html#a7b094e29b8e92b00e36517d0d7633c4b',1,'QwtPlot::replot()'],['../class_qwt_plot_canvas.html#a1548423348c29001ee2b6fd1c0f9f033',1,'QwtPlotCanvas::replot()'],['../class_qwt_plot_g_l_canvas.html#af2bf82a971fcea76dab92da15a859c67',1,'QwtPlotGLCanvas::replot()']]], + ['resamplemode',['resampleMode',['../class_qwt_matrix_raster_data.html#af4edef83d2862640893552b8f20ed725',1,'QwtMatrixRasterData::resampleMode() const '],['../class_qwt_matrix_raster_data.html#a3c8def5d9ae452bd82e6c4b71b480209',1,'QwtMatrixRasterData::ResampleMode()']]], + ['rescale',['rescale',['../class_qwt_abstract_scale.html#a647e6458305a0967077f4b1f03811c14',1,'QwtAbstractScale::rescale()'],['../class_qwt_magnifier.html#a5c3d5bda10412a50bd403afe84e2ccee',1,'QwtMagnifier::rescale()'],['../class_qwt_plot_magnifier.html#a271ae5ad42c3dd12812246d2dee687ea',1,'QwtPlotMagnifier::rescale()'],['../class_qwt_plot_rescaler.html#afd6783b36fa0a2f61b481bffc5f33251',1,'QwtPlotRescaler::rescale() const '],['../class_qwt_plot_rescaler.html#a6c609a90c617ddddb5c0e282ceeeeeac',1,'QwtPlotRescaler::rescale(const QSize &oldSize, const QSize &newSize) const '],['../class_qwt_plot_zoomer.html#a0d0f90bbd5fe99d5231b3cee00fffabe',1,'QwtPlotZoomer::rescale()']]], + ['rescalepolicy',['rescalePolicy',['../class_qwt_plot_rescaler.html#adceb6d094c1db33c1ef23e18e1b49185',1,'QwtPlotRescaler::rescalePolicy() const '],['../class_qwt_plot_rescaler.html#a6a614b832876a7641cb5410ba81d9d6a',1,'QwtPlotRescaler::RescalePolicy()']]], + ['reset',['reset',['../class_qwt_graphic.html#a441f351c6578deab715126586dd1ca21',1,'QwtGraphic::reset()'],['../class_qwt_picker.html#a0e50f7be7182e81607bf1625dcdff6eb',1,'QwtPicker::reset()'],['../class_qwt_picker_machine.html#ace6daa55324a8daab3839cf8ba677a93',1,'QwtPickerMachine::reset()'],['../class_qwt_plot_direct_painter.html#a895bf1ebfd772a2200dc09bed596cf4d',1,'QwtPlotDirectPainter::reset()'],['../class_qwt_spline.html#afc52fd49e7f00d57a0336059fae299c0',1,'QwtSpline::reset()']]], + ['resetsymbolmap',['resetSymbolMap',['../class_qwt_plot_multi_bar_chart.html#a2fac8a87796eb02ca1418ea806c0abb4',1,'QwtPlotMultiBarChart']]], + ['resizeevent',['resizeEvent',['../class_qwt_plot.html#aa4d5f73681880b9770bb6a604c415987',1,'QwtPlot::resizeEvent()'],['../class_qwt_plot_canvas.html#a1d4a1508bef7b417c3414c345bd60022',1,'QwtPlotCanvas::resizeEvent()'],['../class_qwt_scale_widget.html#a9072385d42de47fec634989134d1cd98',1,'QwtScaleWidget::resizeEvent()'],['../class_qwt_slider.html#a1f65d6ce5f8ed94e0a632edcd68a51f9',1,'QwtSlider::resizeEvent()'],['../class_qwt_thermo.html#a31ea86c3ab9c6925752dc8d6215fd9f0',1,'QwtThermo::resizeEvent()'],['../class_qwt_widget_overlay.html#a1ec8de0015c9b823fd304d9febb580ca',1,'QwtWidgetOverlay::resizeEvent()']]], + ['resizemode',['ResizeMode',['../class_qwt_picker.html#ab3c894deed026f392496dd07809a6fd3',1,'QwtPicker::ResizeMode()'],['../class_qwt_picker.html#a684032c8aea570b069da2f8193760df9',1,'QwtPicker::resizeMode() const ']]], + ['restart',['restart',['../class_qwt_system_clock.html#a6be327dd133c1d7ecccfb95050eef7b9',1,'QwtSystemClock']]], + ['rgb',['rgb',['../class_qwt_color_map.html#aaed0bb47b6379696c588732348438136',1,'QwtColorMap::rgb()'],['../class_qwt_linear_color_map.html#ac031babccc90d8c857c707d0841ba1eb',1,'QwtLinearColorMap::rgb()'],['../class_qwt_alpha_color_map.html#a2f0ce2bdaecf7e74b635b8433ed733d5',1,'QwtAlphaColorMap::rgb()'],['../class_qwt_color_map.html#a9e5570790910fa3894887bca7dc5a670a663473fd836d9a84fe48ae1755de326a',1,'QwtColorMap::RGB()']]], + ['richtext',['RichText',['../class_qwt_text.html#a63e0d6a59a427a37ed0bfa71b782fd76a88f7eee487ce6f7769b67494623d8b79',1,'QwtText']]], + ['rightlegend',['RightLegend',['../class_qwt_plot.html#a31aacb65b5c049dde8c34a0d8482661ba5273f8002504c24f9dae6ce09b08f03c',1,'QwtPlot']]], + ['rightscale',['RightScale',['../class_qwt_scale_draw.html#acd7ceeeac592ef08530788580b461c66a84d42042d94ae7726395ceb578225e1e',1,'QwtScaleDraw']]], + ['righttoleft',['RightToLeft',['../class_qwt_column_rect.html#a70bb2c6f1f8dabe3bc00793740e0908bac08f1153f84950e62d369cc7b7011b5e',1,'QwtColumnRect']]], + ['role',['Role',['../class_qwt_legend_data.html#a55bd21943c804101d956250ca43f93f9',1,'QwtLegendData']]], + ['rose',['rose',['../class_qwt_compass.html#a7405a44d947e16f53b11dea4544d7683',1,'QwtCompass::rose() const '],['../class_qwt_compass.html#a99477d676bd866acd1a418615cba423b',1,'QwtCompass::rose()']]], + ['rotateneedle',['RotateNeedle',['../class_qwt_dial.html#a7376f53193014b91643350e6e6bc85adacc23db2e06c9098f8cfbd0181184054a',1,'QwtDial']]], + ['rotatescale',['RotateScale',['../class_qwt_dial.html#a7376f53193014b91643350e6e6bc85ada95a22f59ec832d22f011a9421f528c41',1,'QwtDial']]], + ['roundingalignment',['roundingAlignment',['../class_qwt_painter.html#ae9af230df7bb8d40b802d4f3205a8631',1,'QwtPainter::roundingAlignment()'],['../class_qwt_painter.html#ab11788d777ce54a1959bf8387dba6ad9',1,'QwtPainter::roundingAlignment(QPainter *)']]], + ['roundpoints',['RoundPoints',['../class_qwt_point_mapper.html#aafc07ceadb3f311057037ca8680e1c23a0e367a1519b0005cad8bb324854cc8e3',1,'QwtPointMapper']]], + ['rradius',['rRadius',['../class_qwt_point_polar.html#a69cf76a959e4417038b4e2684d307847',1,'QwtPointPolar']]], + ['rtriangle',['RTriangle',['../class_qwt_symbol.html#a62f457952470c2076962e83ef2c24d2faeb6111f6fc1813efb466687309c873bd',1,'QwtSymbol']]], + ['rtti',['rtti',['../class_qwt_plot_bar_chart.html#a88888d4deb246c45f3161cfc5a8940e6',1,'QwtPlotBarChart::rtti()'],['../class_qwt_plot_curve.html#a1cb75062e781f4e0839a6cd2081c3928',1,'QwtPlotCurve::rtti()'],['../class_qwt_plot_grid.html#aae0d0b5afbc670dd257302b13601ea99',1,'QwtPlotGrid::rtti()'],['../class_qwt_plot_histogram.html#a7a927d6ad8544cf5d46e629a03a5a8f1',1,'QwtPlotHistogram::rtti()'],['../class_qwt_plot_interval_curve.html#a59e7b26fc91dd3c7c2412b5fd8d4ca9f',1,'QwtPlotIntervalCurve::rtti()'],['../class_qwt_plot_item.html#af153b5a40a60ac626f1c58e69fc4ecad',1,'QwtPlotItem::rtti()'],['../class_qwt_plot_legend_item.html#ad5ae47214f5424e73e960cf16e282cf5',1,'QwtPlotLegendItem::rtti()'],['../class_qwt_plot_marker.html#a4e48032adf8bdda1aacba4977280123f',1,'QwtPlotMarker::rtti()'],['../class_qwt_plot_multi_bar_chart.html#a60d8065486dbf458019a283798f1e99c',1,'QwtPlotMultiBarChart::rtti()'],['../class_qwt_plot_scale_item.html#a72d7c46ade62f45f3dffa93931900d74',1,'QwtPlotScaleItem::rtti()'],['../class_qwt_plot_shape_item.html#a1f7cff8165dcd7f6cfa416b28f052847',1,'QwtPlotShapeItem::rtti()'],['../class_qwt_plot_spectro_curve.html#a5e866a7b7c024d26329814745ca2379c',1,'QwtPlotSpectroCurve::rtti()'],['../class_qwt_plot_spectrogram.html#a01197466f530633759337bbb7b8f7504',1,'QwtPlotSpectrogram::rtti()'],['../class_qwt_plot_svg_item.html#a4331deca8a2ecdd6a7ebe1be7de22969',1,'QwtPlotSvgItem::rtti()'],['../class_qwt_plot_text_label.html#a6478e871cb51ee383e82c437cf6dbf86',1,'QwtPlotTextLabel::rtti()'],['../class_qwt_plot_trading_curve.html#aa57d588027e9dbeb2cc9bc0cafff84b9',1,'QwtPlotTradingCurve::rtti()'],['../class_qwt_plot_zone_item.html#a7af34a4fdf5d9af4786049405de46ce1',1,'QwtPlotZoneItem::rtti()']]], + ['rtti_5fplotbarchart',['Rtti_PlotBarChart',['../class_qwt_plot_item.html#ab149ac85e233ce9cedf2f2f2af871bf3ab89eb3547903640b6cc9d0aac02ef6c3',1,'QwtPlotItem']]], + ['rtti_5fplotcurve',['Rtti_PlotCurve',['../class_qwt_plot_item.html#ab149ac85e233ce9cedf2f2f2af871bf3af51a35012ed097a762b8918cf20caa69',1,'QwtPlotItem']]], + ['rtti_5fplotgrid',['Rtti_PlotGrid',['../class_qwt_plot_item.html#ab149ac85e233ce9cedf2f2f2af871bf3af3125faa8333135a5724cc1d6c276683',1,'QwtPlotItem']]], + ['rtti_5fplothistogram',['Rtti_PlotHistogram',['../class_qwt_plot_item.html#ab149ac85e233ce9cedf2f2f2af871bf3a4538dd66ec78ffd7ce6763f9000edcee',1,'QwtPlotItem']]], + ['rtti_5fplotintervalcurve',['Rtti_PlotIntervalCurve',['../class_qwt_plot_item.html#ab149ac85e233ce9cedf2f2f2af871bf3a5698aa120baa6e3d3d2a6bda8a82b226',1,'QwtPlotItem']]], + ['rtti_5fplotitem',['Rtti_PlotItem',['../class_qwt_plot_item.html#ab149ac85e233ce9cedf2f2f2af871bf3af1fb53ddb320ecbf2bba00a323cf08ff',1,'QwtPlotItem']]], + ['rtti_5fplotlegend',['Rtti_PlotLegend',['../class_qwt_plot_item.html#ab149ac85e233ce9cedf2f2f2af871bf3a06cd77e370cf62597501e692965e1f9c',1,'QwtPlotItem']]], + ['rtti_5fplotmarker',['Rtti_PlotMarker',['../class_qwt_plot_item.html#ab149ac85e233ce9cedf2f2f2af871bf3a15b3819a193f24b76c78e39cb80c7789',1,'QwtPlotItem']]], + ['rtti_5fplotmultibarchart',['Rtti_PlotMultiBarChart',['../class_qwt_plot_item.html#ab149ac85e233ce9cedf2f2f2af871bf3a73007ac5158d0ac857af2c6dcecf2712',1,'QwtPlotItem']]], + ['rtti_5fplotscale',['Rtti_PlotScale',['../class_qwt_plot_item.html#ab149ac85e233ce9cedf2f2f2af871bf3a386936d7e0186eabeb833a51cc4fb1cc',1,'QwtPlotItem']]], + ['rtti_5fplotshape',['Rtti_PlotShape',['../class_qwt_plot_item.html#ab149ac85e233ce9cedf2f2f2af871bf3af18fa4c34b44eaf43e13608c6bd7c7b7',1,'QwtPlotItem']]], + ['rtti_5fplotspectrocurve',['Rtti_PlotSpectroCurve',['../class_qwt_plot_item.html#ab149ac85e233ce9cedf2f2f2af871bf3a27c1741ae71fad58da835b747246015d',1,'QwtPlotItem']]], + ['rtti_5fplotspectrogram',['Rtti_PlotSpectrogram',['../class_qwt_plot_item.html#ab149ac85e233ce9cedf2f2f2af871bf3ad67d72195856e6fd8112e1b310f3acb7',1,'QwtPlotItem']]], + ['rtti_5fplotsvg',['Rtti_PlotSVG',['../class_qwt_plot_item.html#ab149ac85e233ce9cedf2f2f2af871bf3a3aabc62d4c006ab40dd3e01db692ab4a',1,'QwtPlotItem']]], + ['rtti_5fplottextlabel',['Rtti_PlotTextLabel',['../class_qwt_plot_item.html#ab149ac85e233ce9cedf2f2f2af871bf3ae6f046fd43f578ad8a59243e6e665167',1,'QwtPlotItem']]], + ['rtti_5fplottradingcurve',['Rtti_PlotTradingCurve',['../class_qwt_plot_item.html#ab149ac85e233ce9cedf2f2f2af871bf3abcd9cebf717e528cb67458abfbf622dd',1,'QwtPlotItem']]], + ['rtti_5fplotuseritem',['Rtti_PlotUserItem',['../class_qwt_plot_item.html#ab149ac85e233ce9cedf2f2f2af871bf3aa60198228f57f46d4c64e4779107d0dc',1,'QwtPlotItem']]], + ['rtti_5fplotzone',['Rtti_PlotZone',['../class_qwt_plot_item.html#ab149ac85e233ce9cedf2f2f2af871bf3a52b2ec5c64c77a36a103b329a530b606',1,'QwtPlotItem']]], + ['rttivalues',['RttiValues',['../class_qwt_plot_item.html#ab149ac85e233ce9cedf2f2f2af871bf3',1,'QwtPlotItem']]], + ['rubberband',['RubberBand',['../class_qwt_picker.html#ab36c79d8ff20aba5b778d2823c1f7894',1,'QwtPicker::RubberBand()'],['../class_qwt_picker.html#a6a7af18636587af2c11a6c060929403a',1,'QwtPicker::rubberBand() const ']]], + ['rubberbandmask',['rubberBandMask',['../class_qwt_picker.html#a9894c9ca37f06ad79cff26a3c63f6c66',1,'QwtPicker']]], + ['rubberbandoverlay',['rubberBandOverlay',['../class_qwt_picker.html#aa4bdb9e280b226fe2743be0aef11eca8',1,'QwtPicker']]], + ['rubberbandpen',['rubberBandPen',['../class_qwt_picker.html#a074492301e00535def0fe2cb449fba37',1,'QwtPicker']]], + ['run',['run',['../class_qwt_sampling_thread.html#a247354fcc8e2597e105d87a2cfaa0a96',1,'QwtSamplingThread']]], + ['rx',['rx',['../class_qwt_point3_d.html#a99ae15c21e43fac2c4b8755111b03ad0',1,'QwtPoint3D']]], + ['ry',['ry',['../class_qwt_point3_d.html#ab0894c41fdb85dcc7affe38acf33f48d',1,'QwtPoint3D']]], + ['rz',['rz',['../class_qwt_point3_d.html#af76eb9c617ea48ab1050a79bac1d90eb',1,'QwtPoint3D']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/all_73.html b/ThirdParty/Qwt/doc/html/search/all_73.html new file mode 100644 index 0000000000..9abac91a94 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/all_73.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/all_73.js b/ThirdParty/Qwt/doc/html/search/all_73.js new file mode 100644 index 0000000000..b83a74138c --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/all_73.js @@ -0,0 +1,381 @@ +var searchData= +[ + ['s1',['s1',['../class_qwt_scale_map.html#a38b6a7040cd15a427f7631afa20cbad8',1,'QwtScaleMap']]], + ['s2',['s2',['../class_qwt_scale_map.html#a644fe199eecf30fcd1803be554cd21f7',1,'QwtScaleMap']]], + ['sample',['sample',['../class_qwt_point_array_data.html#ad2fa2b92a88d216fb4a74cb4b6ccbb9f',1,'QwtPointArrayData::sample()'],['../class_qwt_c_pointer_data.html#a5e01b287eca7d0c4b52bbf514c5244d2',1,'QwtCPointerData::sample()'],['../class_qwt_synthetic_point_data.html#a70d3ed6bfd764878f1709ab6b55e2f0e',1,'QwtSyntheticPointData::sample()'],['../class_qwt_sampling_thread.html#a67c4a524736808dc1ba3b81670c0cbd5',1,'QwtSamplingThread::sample()'],['../class_qwt_series_data.html#ae8650d16c07c58f01897ab48658a3266',1,'QwtSeriesData::sample()'],['../class_qwt_array_series_data.html#a900ba90abf9a0852026099bdcae2ba7f',1,'QwtArraySeriesData::sample()'],['../class_qwt_series_store.html#adbb86cd5cd59472f2f3137742ca74a48',1,'QwtSeriesStore::sample()']]], + ['samples',['samples',['../class_qwt_array_series_data.html#a2d3f931bd28f40bc6e13c4b507e5b502',1,'QwtArraySeriesData']]], + ['samplewidth',['sampleWidth',['../class_qwt_plot_abstract_bar_chart.html#aeb17b54d0ea782d72c94944b867e1946',1,'QwtPlotAbstractBarChart']]], + ['scalechange',['scaleChange',['../class_qwt_abstract_scale.html#a0dbb7bdc557c0a7b163643e41970ed6a',1,'QwtAbstractScale::scaleChange()'],['../class_qwt_abstract_slider.html#a491fe8bbe771fb51bf35d429d4b92e05',1,'QwtAbstractSlider::scaleChange()'],['../class_qwt_dial.html#a0cee4448e2753ed259917f1874a3e158',1,'QwtDial::scaleChange()'],['../class_qwt_scale_widget.html#af151a963ea3cb7f04815db93e8f4882d',1,'QwtScaleWidget::scaleChange()'],['../class_qwt_slider.html#a31ae4c53eb17d77ee0fd846ff6eea7e3',1,'QwtSlider::scaleChange()'],['../class_qwt_thermo.html#a3f2f5077580235a5a776805a9721c8ba',1,'QwtThermo::scaleChange()']]], + ['scalecomponent',['ScaleComponent',['../class_qwt_abstract_scale_draw.html#a26215d06a4d48adf401d0aa05d4193c5',1,'QwtAbstractScaleDraw']]], + ['scalecomponents',['ScaleComponents',['../class_qwt_abstract_scale_draw.html#a0dd3ccdfa074fb6b1781b84ed2a4729a',1,'QwtAbstractScaleDraw']]], + ['scaledboundingrect',['scaledBoundingRect',['../class_qwt_graphic.html#aa415b6f8be72408538c20c0cc60eb0bc',1,'QwtGraphic']]], + ['scaledcolors',['ScaledColors',['../class_qwt_linear_color_map.html#ac8c5f1991f533b1d25a9a0a0874b7d54a01770189cb40240f2fe7fe2e6c1523f1',1,'QwtLinearColorMap']]], + ['scalediv',['scaleDiv',['../class_qwt_abstract_scale.html#ae0ec7f1528981f15d8ede6a78530f065',1,'QwtAbstractScale::scaleDiv()'],['../class_qwt_abstract_scale_draw.html#a82510027cd5bee269628c9d6302a19a9',1,'QwtAbstractScaleDraw::scaleDiv()'],['../class_qwt_plot_scale_item.html#a06695f68519b2cc8660441d12d84ab13',1,'QwtPlotScaleItem::scaleDiv()']]], + ['scaledivchanged',['scaleDivChanged',['../class_qwt_scale_widget.html#a55c52717ede368069f5f44b9901e3400',1,'QwtScaleWidget']]], + ['scaledraw',['scaleDraw',['../class_qwt_dial.html#adaa9a23f4e19d3cd085db1c61665d1d6',1,'QwtDial::scaleDraw()'],['../class_qwt_dial.html#ae1b59c65bc9717bd83ffb8e8ce07988c',1,'QwtDial::scaleDraw() const '],['../class_qwt_knob.html#aa9c4c23e20fc59b3ca2bfed9fe1e3719',1,'QwtKnob::scaleDraw() const '],['../class_qwt_knob.html#a3154037eec8c76c24577b8bf1d92b871',1,'QwtKnob::scaleDraw()'],['../class_qwt_plot_scale_item.html#abdcced6eb4179319aeeeba370ec54a0f',1,'QwtPlotScaleItem::scaleDraw() const '],['../class_qwt_plot_scale_item.html#ab75d17fe11c146b49ffa47940f512850',1,'QwtPlotScaleItem::scaleDraw()'],['../class_qwt_scale_widget.html#ad8603e84f851e5d91feb21beebf19896',1,'QwtScaleWidget::scaleDraw() const '],['../class_qwt_scale_widget.html#a6ccb7e3a4537396f59fc30c7d76cc20d',1,'QwtScaleWidget::scaleDraw()'],['../class_qwt_slider.html#ab3394f8eb22b75cc6add3b8d3444ad30',1,'QwtSlider::scaleDraw()'],['../class_qwt_thermo.html#aaacb94a49eb05c91a3896d202f79ec46',1,'QwtThermo::scaleDraw() const '],['../class_qwt_thermo.html#a7d0f262032c034c5da703ec2f2d120b7',1,'QwtThermo::scaleDraw()']]], + ['scaledsymbolwidth',['scaledSymbolWidth',['../class_qwt_plot_trading_curve.html#a327d6afbc4bc12794e9bd586c0fcafbc',1,'QwtPlotTradingCurve']]], + ['scaleengine',['scaleEngine',['../class_qwt_abstract_scale.html#a5b8084cc735933ce9338fd2df1126f0e',1,'QwtAbstractScale::scaleEngine() const '],['../class_qwt_abstract_scale.html#aea3b9d4912f1c28671f232e4100936d7',1,'QwtAbstractScale::scaleEngine()']]], + ['scaleinnerrect',['scaleInnerRect',['../class_qwt_dial.html#ab793e4c15e9b32a7e8d13f0b28d1feb9',1,'QwtDial']]], + ['scaleinterest',['ScaleInterest',['../class_qwt_plot_item.html#affbc42460ace9ac725fa825a3f8bfb66a0d1c46890f22ef973d897ab0a9d38971',1,'QwtPlotItem']]], + ['scalemap',['scaleMap',['../class_qwt_abstract_scale.html#a68f120e12e373796b5d74199a9b8a4b0',1,'QwtAbstractScale::scaleMap()'],['../class_qwt_abstract_scale_draw.html#aac87f593525666a47a57d9e2b4f02c66',1,'QwtAbstractScaleDraw::scaleMap() const '],['../class_qwt_abstract_scale_draw.html#ae7488eb63ad73a2e69acb29ff069c904',1,'QwtAbstractScaleDraw::scaleMap()']]], + ['scalemaxmajor',['scaleMaxMajor',['../class_qwt_abstract_scale.html#a4cfbcd9880297b1ca28fa824e3f4c3e6',1,'QwtAbstractScale']]], + ['scalemaxminor',['scaleMaxMinor',['../class_qwt_abstract_scale.html#a5b23fafbb56bb43fd241c1839256357f',1,'QwtAbstractScale']]], + ['scaleposition',['scalePosition',['../class_qwt_slider.html#ac3f14f80cc92d1c267e2ae88df6f61c1',1,'QwtSlider::scalePosition()'],['../class_qwt_thermo.html#a1cbfd720c1f8c7bf38c984999726086f',1,'QwtThermo::scalePosition()'],['../class_qwt_slider.html#a120d984d7c519578eed88c4fe97cb1a7',1,'QwtSlider::ScalePosition()'],['../class_qwt_thermo.html#a4d7af32d29d1cc18e23b9143cf7ad498',1,'QwtThermo::ScalePosition()']]], + ['scalerect',['scaleRect',['../class_qwt_plot_item.html#a186036cbee194b87b9bc4afb693c27f4',1,'QwtPlotItem::scaleRect()'],['../class_qwt_plot_layout.html#a184c8134d58aff17f3a91ae1505917e2',1,'QwtPlotLayout::scaleRect()'],['../class_qwt_plot_picker.html#a6becfde9ef447128a55c0675bf1c1524',1,'QwtPlotPicker::scaleRect()']]], + ['scalesamplestoaxes',['ScaleSamplesToAxes',['../class_qwt_plot_abstract_bar_chart.html#ae1db0e1606747ef46c863c54c210e53aaa436f4537d15dbfac62c864389b12220',1,'QwtPlotAbstractBarChart']]], + ['scalesampletocanvas',['ScaleSampleToCanvas',['../class_qwt_plot_abstract_bar_chart.html#ae1db0e1606747ef46c863c54c210e53aaf63f5c75741674252ac3d788735873d5',1,'QwtPlotAbstractBarChart']]], + ['scalestepsize',['scaleStepSize',['../class_qwt_abstract_scale.html#ad94ddd24f5f9742a577b19f9c6e00117',1,'QwtAbstractScale']]], + ['scatter_20plot',['Scatter Plot',['../scatterscreenshots.html',1,'']]], + ['scrolledto',['scrolledTo',['../class_qwt_abstract_slider.html#af19ab98a4101c2eaa43de2df7ebe4d0d',1,'QwtAbstractSlider::scrolledTo()'],['../class_qwt_dial.html#afc13ba2a48fc4f99a74f08d87dabc016',1,'QwtDial::scrolledTo()'],['../class_qwt_knob.html#a800716b7da7d41da1472c561d6e0b332',1,'QwtKnob::scrolledTo()'],['../class_qwt_slider.html#aa895f8b5fb3968d4ce3008f27792d3b9',1,'QwtSlider::scrolledTo()']]], + ['scrollextent',['scrollExtent',['../class_qwt_abstract_legend.html#a51e8c45d2afc691e78b09c662d7a493e',1,'QwtAbstractLegend::scrollExtent()'],['../class_qwt_legend.html#ad75d747944921533aede5bfce518ec02',1,'QwtLegend::scrollExtent()']]], + ['sdist',['sDist',['../class_qwt_scale_map.html#adf621246cfa7313280a35a44063972f3',1,'QwtScaleMap']]], + ['second',['Second',['../class_qwt_date.html#ad037b999a51cae4d9ab36bf8e7859587aabaf7a7d45288a33590f61fe075b3590',1,'QwtDate']]], + ['secondhand',['SecondHand',['../class_qwt_analog_clock.html#acd8f7e963ae073120684de46821f2cfea2d9426a775588d3afb667ca8e9393c8d',1,'QwtAnalogClock']]], + ['selected',['selected',['../class_qwt_picker.html#a283ec139021c9b5e95d1472a9c902c7e',1,'QwtPicker::selected()'],['../class_qwt_plot_picker.html#a28f6c8af0efd0abb6dc144670efbb31b',1,'QwtPlotPicker::selected()'],['../class_qwt_plot_picker.html#ace55ce208052c631ce666b5af2b7342b',1,'QwtPlotPicker::selected()'],['../class_qwt_plot_picker.html#a7eb9fdda3166c452660130ceffd1d092',1,'QwtPlotPicker::selected()']]], + ['selection',['selection',['../class_qwt_picker.html#ac5bc0a5f7054c407195ce9ee1d0cf394',1,'QwtPicker']]], + ['selectiontype',['selectionType',['../class_qwt_picker_machine.html#a9ccd6ccb3fa0e2a73730e69a8658c316',1,'QwtPickerMachine::selectionType() const '],['../class_qwt_picker_machine.html#a24a9faf12cfa5746eee839a2c0bb937d',1,'QwtPickerMachine::SelectionType()']]], + ['set',['set',['../class_qwt_set_sample.html#af05cfa9fc52e7798f6594ba1bbbcd16b',1,'QwtSetSample']]], + ['setabortkey',['setAbortKey',['../class_qwt_panner.html#acbb1b9e30214354708e1d75db6b78289',1,'QwtPanner']]], + ['setabstractscaledraw',['setAbstractScaleDraw',['../class_qwt_abstract_scale.html#a950c5bf521dc704b78f76c7951346288',1,'QwtAbstractScale']]], + ['setalarmbrush',['setAlarmBrush',['../class_qwt_thermo.html#a1d6a0fae32e21fe6c5f54762073dbe8b',1,'QwtThermo']]], + ['setalarmenabled',['setAlarmEnabled',['../class_qwt_thermo.html#abed75ea5e839ee4afed2c96f6927721e',1,'QwtThermo']]], + ['setalarmlevel',['setAlarmLevel',['../class_qwt_thermo.html#ab42dff878632d210050be2be03535f6a',1,'QwtThermo']]], + ['setaligncanvastoscale',['setAlignCanvasToScale',['../class_qwt_plot_layout.html#ad243b9afc9b5ce9530b500dc35096d67',1,'QwtPlotLayout']]], + ['setaligncanvastoscales',['setAlignCanvasToScales',['../class_qwt_plot_layout.html#a147fcf4c59b34779b5a7dc7361a3b6c3',1,'QwtPlotLayout']]], + ['setalignment',['setAlignment',['../class_qwt_knob.html#ab84683292e11b7c3de4855d844b5471c',1,'QwtKnob::setAlignment()'],['../class_qwt_plot_legend_item.html#a7f0bc77d242fe1977d8dee501fa5240f',1,'QwtPlotLegendItem::setAlignment()'],['../class_qwt_plot_scale_item.html#af11343d14c4ee38e0527cedd52b3da85',1,'QwtPlotScaleItem::setAlignment()'],['../class_qwt_scale_draw.html#a7a4de0055dc1358e55c3357366a54091',1,'QwtScaleDraw::setAlignment()'],['../class_qwt_scale_widget.html#ab6421ace2bd56d5559689522336556e0',1,'QwtScaleWidget::setAlignment()']]], + ['setalpha',['setAlpha',['../class_qwt_plot_raster_item.html#a14f2ab8ec0994384e6269f869c352273',1,'QwtPlotRasterItem']]], + ['setanglerange',['setAngleRange',['../class_qwt_round_scale_draw.html#a5d85678fdb9fbb4d622425aab9ecc681',1,'QwtRoundScaleDraw']]], + ['setaspectratio',['setAspectRatio',['../class_qwt_plot_rescaler.html#a31f71937b4cff3e60f74db83beb6d2de',1,'QwtPlotRescaler::setAspectRatio(double ratio)'],['../class_qwt_plot_rescaler.html#aa747f1cf3ecc3a37f98d0972e1db600b',1,'QwtPlotRescaler::setAspectRatio(int axis, double ratio)']]], + ['setattribute',['setAttribute',['../class_qwt_plot_direct_painter.html#a498b9857a09e399010a3f8bc9c235a8d',1,'QwtPlotDirectPainter::setAttribute()'],['../class_qwt_scale_engine.html#acf02a88f6e778edbc9e005960f35b3b7',1,'QwtScaleEngine::setAttribute()']]], + ['setattributes',['setAttributes',['../class_qwt_scale_engine.html#acd73d5f27b5db0bc7ee673eb6fe9810d',1,'QwtScaleEngine']]], + ['setautodelete',['setAutoDelete',['../class_qwt_plot_dict.html#a3291431f0a9cca5b2affc5adf17bbdfb',1,'QwtPlotDict']]], + ['setautoreplot',['setAutoReplot',['../class_qwt_plot.html#ab1cbce6d43ff9772735a9df9104f882f',1,'QwtPlot']]], + ['setaxes',['setAxes',['../class_qwt_plot_item.html#a6f6c7b34fe86e8029914b3b780b55ea4',1,'QwtPlotItem']]], + ['setaxis',['setAxis',['../class_qwt_plot_picker.html#aa901c86543585c7056133a5cb6652e3d',1,'QwtPlotPicker::setAxis()'],['../class_qwt_plot_zoomer.html#a6cb755e06b83e50e8353dd706f7fb6f0',1,'QwtPlotZoomer::setAxis()']]], + ['setaxisautoscale',['setAxisAutoScale',['../class_qwt_plot.html#a6fb58f90366920f234440fceead50432',1,'QwtPlot']]], + ['setaxisenabled',['setAxisEnabled',['../class_qwt_plot_magnifier.html#ac8806df408b5ed9eac79cd38e5fc1508',1,'QwtPlotMagnifier::setAxisEnabled()'],['../class_qwt_plot_panner.html#acbd5d67684c5a20ea0115e66f69540e4',1,'QwtPlotPanner::setAxisEnabled()']]], + ['setaxisfont',['setAxisFont',['../class_qwt_plot.html#a9a14e57652c016f40388a68e556917e3',1,'QwtPlot']]], + ['setaxislabelalignment',['setAxisLabelAlignment',['../class_qwt_plot.html#a19f1b67fa79b80c712cf5f52b97ea0c5',1,'QwtPlot']]], + ['setaxislabelrotation',['setAxisLabelRotation',['../class_qwt_plot.html#ad5fa7aa01c88eab38ad64b131584f977',1,'QwtPlot']]], + ['setaxismaxmajor',['setAxisMaxMajor',['../class_qwt_plot.html#a34df698558c9bd9c38bdd8ff04cc6c41',1,'QwtPlot']]], + ['setaxismaxminor',['setAxisMaxMinor',['../class_qwt_plot.html#aa45b271684d6202061f1afcfa70e7cf6',1,'QwtPlot']]], + ['setaxisscale',['setAxisScale',['../class_qwt_plot.html#acef5ea818944b93b8695d0c16924eed6',1,'QwtPlot']]], + ['setaxisscalediv',['setAxisScaleDiv',['../class_qwt_plot.html#a2365da57b983eb39752fa4f6378c225a',1,'QwtPlot']]], + ['setaxisscaledraw',['setAxisScaleDraw',['../class_qwt_plot.html#a956a14b08e016eb83768ff4187d3849d',1,'QwtPlot']]], + ['setaxisscaleengine',['setAxisScaleEngine',['../class_qwt_plot.html#abf09452377b53e584a5086354a134d78',1,'QwtPlot']]], + ['setaxistitle',['setAxisTitle',['../class_qwt_plot.html#a5d60f1836e05e5cc5c7fe9570d6a608a',1,'QwtPlot::setAxisTitle(int axisId, const QString &)'],['../class_qwt_plot.html#ad134a193ab40ce33743365558d0303c4',1,'QwtPlot::setAxisTitle(int axisId, const QwtText &)']]], + ['setazimuth',['setAzimuth',['../class_qwt_point_polar.html#a32c6c64510fce3e087d332305b4aca9e',1,'QwtPointPolar']]], + ['setbackgroundbrush',['setBackgroundBrush',['../class_qwt_plot_legend_item.html#a82c391eecd2752c3a85a274973f34b6e',1,'QwtPlotLegendItem::setBackgroundBrush()'],['../class_qwt_text.html#af016a747b234aede9f0cbbeb06ed2802',1,'QwtText::setBackgroundBrush()']]], + ['setbackgroundmode',['setBackgroundMode',['../class_qwt_plot_legend_item.html#a4974efd3548c1335f0969275a95e7cba',1,'QwtPlotLegendItem']]], + ['setbartitles',['setBarTitles',['../class_qwt_plot_multi_bar_chart.html#ab519e583c3463e260c8f47be67aa9b8e',1,'QwtPlotMultiBarChart']]], + ['setbase',['setBase',['../class_qwt_scale_engine.html#afdabe4fd2a89b7cd5a21cdc9ac2269d6',1,'QwtScaleEngine']]], + ['setbaseline',['setBaseline',['../class_qwt_plot_abstract_bar_chart.html#adafbea42ddc3f7f639f2880a4bf683ad',1,'QwtPlotAbstractBarChart::setBaseline()'],['../class_qwt_plot_curve.html#adbb5da6798a60138315b18194cf1ca1e',1,'QwtPlotCurve::setBaseline()'],['../class_qwt_plot_histogram.html#a372314f4e2921673f74d46773d583cf2',1,'QwtPlotHistogram::setBaseline()']]], + ['setborderdist',['setBorderDist',['../class_qwt_scale_widget.html#a75477785c41114e4b2fc08bec64e5d26',1,'QwtScaleWidget']]], + ['setborderdistance',['setBorderDistance',['../class_qwt_plot_legend_item.html#a1238fb3d43f81bea8fa5d89fb6f24bfe',1,'QwtPlotLegendItem::setBorderDistance()'],['../class_qwt_plot_scale_item.html#a34bb235d0715d9c13669fe90669fc545',1,'QwtPlotScaleItem::setBorderDistance()']]], + ['setborderflags',['setBorderFlags',['../class_qwt_interval.html#ad1bce23251519f0d44937413f8547dc5',1,'QwtInterval']]], + ['setborderpen',['setBorderPen',['../class_qwt_plot_legend_item.html#a92d38a3db46df13cc325c3ec8ea63768',1,'QwtPlotLegendItem::setBorderPen()'],['../class_qwt_text.html#aca4dd700b7a182114a8c0eb864c4ec2f',1,'QwtText::setBorderPen()']]], + ['setborderradius',['setBorderRadius',['../class_qwt_plot_canvas.html#a1e5c325697c0e892bf0e4e514d50177c',1,'QwtPlotCanvas::setBorderRadius()'],['../class_qwt_plot_legend_item.html#afe9ab7925e12c81d7534343de29ae9cf',1,'QwtPlotLegendItem::setBorderRadius()'],['../class_qwt_text.html#a7c62dfe82aa94f113cd4f8702bd2242c',1,'QwtText::setBorderRadius()']]], + ['setborderwidth',['setBorderWidth',['../class_qwt_knob.html#a2e0a17648602bab3b1aaabfc3ba19441',1,'QwtKnob::setBorderWidth()'],['../class_qwt_slider.html#a0d40da533b9417974240e127b5d701e4',1,'QwtSlider::setBorderWidth()'],['../class_qwt_thermo.html#a25821f13d01848a1a37690d4796311bc',1,'QwtThermo::setBorderWidth()'],['../class_qwt_wheel.html#a50a2046f1151af7599aee3ad8f4e3ff0',1,'QwtWheel::setBorderWidth()']]], + ['setboundingrect',['setBoundingRect',['../class_qwt_point_mapper.html#a03910571df91575456e98134f6543650',1,'QwtPointMapper']]], + ['setbrush',['setBrush',['../class_qwt_interval_symbol.html#a2bf63ba6d8051ad890787b4762ae8b9a',1,'QwtIntervalSymbol::setBrush()'],['../class_qwt_plot_curve.html#adc52ea882ec1f994e2d2e23c7465b0c2',1,'QwtPlotCurve::setBrush()'],['../class_qwt_plot_histogram.html#a0bf40c3f9f9074cac5deecd4525583b3',1,'QwtPlotHistogram::setBrush()'],['../class_qwt_plot_interval_curve.html#a3102b513c27c54775fd371858aa31bba',1,'QwtPlotIntervalCurve::setBrush()'],['../class_qwt_plot_shape_item.html#ac73e7b2bc260f50dd997e078384a3d6b',1,'QwtPlotShapeItem::setBrush()'],['../class_qwt_plot_zone_item.html#a29d7add8c10cde3c5710354cd0d033a8',1,'QwtPlotZoneItem::setBrush()'],['../class_qwt_symbol.html#ae6aa7281d518bdd4adae8a37bbb5e09a',1,'QwtSymbol::setBrush()']]], + ['setcachepolicy',['setCachePolicy',['../class_qwt_plot_raster_item.html#a31f74199f7e333c2683b0f18289e4c7f',1,'QwtPlotRasterItem::setCachePolicy()'],['../class_qwt_symbol.html#a4c358a923bdcb122a59f21eb419f1bc6',1,'QwtSymbol::setCachePolicy()']]], + ['setcanvas',['setCanvas',['../class_qwt_plot.html#aea67c885034219789b360c0e624bfeaf',1,'QwtPlot']]], + ['setcanvasbackground',['setCanvasBackground',['../class_qwt_plot.html#adb0b2e68d86039f86e3240fb399fa0fe',1,'QwtPlot']]], + ['setcanvasmargin',['setCanvasMargin',['../class_qwt_plot_layout.html#a11667dad6675a7a58cc60ab1597b1203',1,'QwtPlotLayout']]], + ['setcanvasrect',['setCanvasRect',['../class_qwt_plot_layout.html#ab3d6614684b96a5879300476d2df8f8f',1,'QwtPlotLayout']]], + ['setchecked',['setChecked',['../class_qwt_legend_label.html#aec4affb8dbd281a7a8c5511c3ebf5ff8',1,'QwtLegendLabel']]], + ['setchunksize',['setChunkSize',['../class_qwt_weeding_curve_fitter.html#a9f17a819447cba0e733bd71d90ee2766',1,'QwtWeedingCurveFitter']]], + ['setclipping',['setClipping',['../class_qwt_plot_direct_painter.html#ac3d406aada74b7d9202c1017d8347708',1,'QwtPlotDirectPainter']]], + ['setclipregion',['setClipRegion',['../class_qwt_plot_direct_painter.html#a0c97174b06957f9b20ea295ff403a557',1,'QwtPlotDirectPainter']]], + ['setcolor',['setColor',['../class_qwt_alpha_color_map.html#a372ba8791102270991473897fb36a965',1,'QwtAlphaColorMap::setColor()'],['../class_qwt_symbol.html#a046443d76371c92add79e1f360bf3134',1,'QwtSymbol::setColor()'],['../class_qwt_text.html#ac7de5839a5c3b1ee367cfbd5691aa105',1,'QwtText::setColor()']]], + ['setcolorbarenabled',['setColorBarEnabled',['../class_qwt_scale_widget.html#aeb337b8e67fc00ca98bf39a6d70aea61',1,'QwtScaleWidget']]], + ['setcolorbarwidth',['setColorBarWidth',['../class_qwt_scale_widget.html#a76eb179267a572944d1ebdbf62c573f1',1,'QwtScaleWidget']]], + ['setcolorinterval',['setColorInterval',['../class_qwt_linear_color_map.html#abfae35c30755c0bbd1447342055e9a13',1,'QwtLinearColorMap']]], + ['setcolormap',['setColorMap',['../class_qwt_plot_spectro_curve.html#a67d046af16feeddc9bec08c698b46446',1,'QwtPlotSpectroCurve::setColorMap()'],['../class_qwt_plot_spectrogram.html#a55375b61c01962b06ad222c980ca2dcc',1,'QwtPlotSpectrogram::setColorMap()'],['../class_qwt_scale_widget.html#a3cfd919d042007accd3fdb3fcd75045c',1,'QwtScaleWidget::setColorMap()'],['../class_qwt_thermo.html#ad2ac0e2d496fd3d28f83f61728b83337',1,'QwtThermo::setColorMap()']]], + ['setcolorrange',['setColorRange',['../class_qwt_plot_spectro_curve.html#a133f4117e925a1faed456bd9524477e4',1,'QwtPlotSpectroCurve']]], + ['setcommands',['setCommands',['../class_qwt_graphic.html#a22cd36c524b08834bac74337aea9f7e8',1,'QwtGraphic']]], + ['setconrecflag',['setConrecFlag',['../class_qwt_plot_spectrogram.html#adcec06278d4ff4b8dd3a85e2ef188d7b',1,'QwtPlotSpectrogram']]], + ['setcontourlevels',['setContourLevels',['../class_qwt_plot_spectrogram.html#a5b7669a3c390e30f0c51e5c4689095d2',1,'QwtPlotSpectrogram']]], + ['setcurrenttime',['setCurrentTime',['../class_qwt_analog_clock.html#a1972a54ce59155ec7435103f11a775a7',1,'QwtAnalogClock']]], + ['setcursor',['setCursor',['../class_qwt_panner.html#ac8b0625fe155fff0132df85727f54a3e',1,'QwtPanner']]], + ['setcurveattribute',['setCurveAttribute',['../class_qwt_plot_curve.html#a6ac9243e280f96cd149102a91271a473',1,'QwtPlotCurve']]], + ['setcurvefitter',['setCurveFitter',['../class_qwt_plot_curve.html#ac15588c78d175906a30de501b4dd7957',1,'QwtPlotCurve']]], + ['setdata',['setData',['../class_qwt_legend_label.html#abd0140174ae2f0818cc926f68a9f27cc',1,'QwtLegendLabel::setData()'],['../class_qwt_plot_spectrogram.html#a5ee036cdf8dbaf5f8fd82a3fc47b023a',1,'QwtPlotSpectrogram::setData()'],['../class_qwt_series_store.html#add3ce83fe90e976b75a0ebaa79caee4c',1,'QwtSeriesStore::setData()']]], + ['setdateformat',['setDateFormat',['../class_qwt_date_scale_draw.html#ae8eb41024970bec16987d0c736ae890e',1,'QwtDateScaleDraw']]], + ['setdefaultcontourpen',['setDefaultContourPen',['../class_qwt_plot_spectrogram.html#af883cb50d74057994b3179ab0e262e64',1,'QwtPlotSpectrogram::setDefaultContourPen(const QColor &, qreal width=0.0, Qt::PenStyle=Qt::SolidLine)'],['../class_qwt_plot_spectrogram.html#afa3dea62acc8e5607e84bff8f50804b8',1,'QwtPlotSpectrogram::setDefaultContourPen(const QPen &)']]], + ['setdefaultitemmode',['setDefaultItemMode',['../class_qwt_legend.html#af977ff3e749f8281ee8ad4b926542b50',1,'QwtLegend']]], + ['setdefaultsize',['setDefaultSize',['../class_qwt_graphic.html#acba8d73bc62bd15c15491d4a6e739869',1,'QwtGraphic']]], + ['setdiscardflag',['setDiscardFlag',['../class_qwt_plot_renderer.html#a33439eb1407f3ba78fdd7b50461bbafc',1,'QwtPlotRenderer']]], + ['setdiscardflags',['setDiscardFlags',['../class_qwt_plot_renderer.html#ac618f4d6605c2484c03140323e1bd639',1,'QwtPlotRenderer']]], + ['setdisplaymode',['setDisplayMode',['../class_qwt_plot_spectrogram.html#a482a82bcf1b9f2a9a75f527063b394a2',1,'QwtPlotSpectrogram']]], + ['setdown',['setDown',['../class_qwt_legend_label.html#ad79fbc910254d1607deb331ade69db90',1,'QwtLegendLabel']]], + ['setenabled',['setEnabled',['../class_qwt_magnifier.html#a03d892c58039fc864a452b7c636a1df7',1,'QwtMagnifier::setEnabled()'],['../class_qwt_panner.html#a43e06c262c945fc7faeb729539bbde58',1,'QwtPanner::setEnabled()'],['../class_qwt_picker.html#aa590756369efae6ebf323302a0af5d36',1,'QwtPicker::setEnabled()'],['../class_qwt_plot_rescaler.html#a6f1c886d127ec4943552170dc63edf29',1,'QwtPlotRescaler::setEnabled()']]], + ['setexpandingdirection',['setExpandingDirection',['../class_qwt_plot_rescaler.html#aa2ecffbc14d951ab9f1809c14bc4e21b',1,'QwtPlotRescaler::setExpandingDirection(ExpandingDirection)'],['../class_qwt_plot_rescaler.html#a1681eb01b65b91e8b2583d87f890576f',1,'QwtPlotRescaler::setExpandingDirection(int axis, ExpandingDirection)']]], + ['setexpandingdirections',['setExpandingDirections',['../class_qwt_dyn_grid_layout.html#a56cd48dda979428402dd39d470674dee',1,'QwtDynGridLayout']]], + ['setfillbrush',['setFillBrush',['../class_qwt_thermo.html#af6ad0c2ca39afb30bb79a326484c9a21',1,'QwtThermo']]], + ['setfitmode',['setFitMode',['../class_qwt_spline_curve_fitter.html#a8381be57ee16b5a2bdacafbd5d71908b',1,'QwtSplineCurveFitter']]], + ['setflag',['setFlag',['../class_qwt_point_mapper.html#a6e03e14718d3d66a0f6a02fec7fcaeed',1,'QwtPointMapper']]], + ['setflags',['setFlags',['../class_qwt_point_mapper.html#ab556bd339cca487f25e2d894c51abe85',1,'QwtPointMapper']]], + ['setfocusindicator',['setFocusIndicator',['../class_qwt_plot_canvas.html#ae7330616dbb97128d01c5446ef0b006e',1,'QwtPlotCanvas']]], + ['setfont',['setFont',['../class_qwt_plot_legend_item.html#aa63eae9c2b05cb92186a40dde19fedec',1,'QwtPlotLegendItem::setFont()'],['../class_qwt_plot_scale_item.html#a8f2bc7a401bb3e1cf796ff024032e31d',1,'QwtPlotScaleItem::setFont()'],['../class_qwt_text.html#ad071f3c4fae4512a1cc71554d95eb69a',1,'QwtText::setFont()']]], + ['setfooter',['setFooter',['../class_qwt_plot.html#a30a098d942a1a9612b94e8fa5a3c9183',1,'QwtPlot::setFooter(const QString &)'],['../class_qwt_plot.html#ab5dd22281bfafd93b2855afa69b872f9',1,'QwtPlot::setFooter(const QwtText &t)']]], + ['setfooterrect',['setFooterRect',['../class_qwt_plot_layout.html#a60698767fe44c86ee4bcef27c1b48d26',1,'QwtPlotLayout']]], + ['setframeshadow',['setFrameShadow',['../class_qwt_dial.html#a272e17e53586a149df4dca437d5f9494',1,'QwtDial::setFrameShadow()'],['../class_qwt_plot_g_l_canvas.html#aee1da52928fa1fb765fa9c5794f40a4a',1,'QwtPlotGLCanvas::setFrameShadow()']]], + ['setframeshape',['setFrameShape',['../class_qwt_plot_g_l_canvas.html#a579e3f0891236317742cb58d9cacb6f5',1,'QwtPlotGLCanvas']]], + ['setframestyle',['setFrameStyle',['../class_qwt_column_symbol.html#a80826051d63efaf033868f05404ef565',1,'QwtColumnSymbol::setFrameStyle()'],['../class_qwt_plot_g_l_canvas.html#a9e1a08cbed3d6fb4ba89a31591265d0d',1,'QwtPlotGLCanvas::setFrameStyle()']]], + ['setgeometry',['setGeometry',['../class_qwt_dyn_grid_layout.html#afdf23bb94de5258f14fb077b39a64391',1,'QwtDynGridLayout']]], + ['setgraphic',['setGraphic',['../class_qwt_symbol.html#ab060930c548548b33441757dcc4b2f73',1,'QwtSymbol']]], + ['setgroove',['setGroove',['../class_qwt_slider.html#a4afc308735f59ffd51adb12d0a32bd81',1,'QwtSlider']]], + ['sethand',['setHand',['../class_qwt_analog_clock.html#a643101aafbe7a6fc91cb550203a7d3ee',1,'QwtAnalogClock']]], + ['sethandlesize',['setHandleSize',['../class_qwt_slider.html#a83ecd72c7ca593ebd361ad8912ac9d39',1,'QwtSlider']]], + ['seticon',['setIcon',['../class_qwt_legend_label.html#ae6113ca4894637f62f7e7df582672788',1,'QwtLegendLabel']]], + ['setincsteps',['setIncSteps',['../class_qwt_counter.html#a6aa68e7fc717fb0e2e48a978301c96eb',1,'QwtCounter']]], + ['setindent',['setIndent',['../class_qwt_text_label.html#aad25ab34c219f8d97ec7c39d064ed4a0',1,'QwtTextLabel']]], + ['setinterval',['setInterval',['../class_qwt_interval.html#a0373ca3cdb22ed507e4188fd06f68b17',1,'QwtInterval::setInterval()'],['../class_qwt_matrix_raster_data.html#a69db38d8f920edb9dc3f0953ca16db8f',1,'QwtMatrixRasterData::setInterval()'],['../class_qwt_plot_zone_item.html#acdf04297cd78f586e447318db60334e6',1,'QwtPlotZoneItem::setInterval(double min, double max)'],['../class_qwt_plot_zone_item.html#ad963f6a8301525c35add92c509fef44c',1,'QwtPlotZoneItem::setInterval(const QwtInterval &)'],['../class_qwt_synthetic_point_data.html#a1a0b2548b496affcf65272acd86c6700',1,'QwtSyntheticPointData::setInterval()'],['../class_qwt_raster_data.html#a14abf60573989e2a2c97e21a98aee558',1,'QwtRasterData::setInterval()'],['../class_qwt_sampling_thread.html#a36c56404ef0042cf52f1e592edf94f5d',1,'QwtSamplingThread::setInterval()'],['../class_qwt_scale_div.html#aa5c61a5fef5f83f2735e4e1b8e545f0b',1,'QwtScaleDiv::setInterval(double lowerBound, double upperBound)'],['../class_qwt_scale_div.html#ad335ddb86f5c635324cd0e8d00430ac4',1,'QwtScaleDiv::setInterval(const QwtInterval &)']]], + ['setintervalhint',['setIntervalHint',['../class_qwt_plot_rescaler.html#afefb0ec065ff855785d0198fc04a07d3',1,'QwtPlotRescaler']]], + ['setinverted',['setInverted',['../class_qwt_wheel.html#a66fec7ef7c7f889218f8ae0d0dcd90b5',1,'QwtWheel']]], + ['setinvertedcontrols',['setInvertedControls',['../class_qwt_abstract_slider.html#a8344b634faf639447c707ef665d2d324',1,'QwtAbstractSlider']]], + ['setitemattribute',['setItemAttribute',['../class_qwt_plot_item.html#a5a335be8ff488809a2cf7f4b734ad1b6',1,'QwtPlotItem']]], + ['setiteminterest',['setItemInterest',['../class_qwt_plot_item.html#ab65cbfe489ff73e32a919a0633298fb7',1,'QwtPlotItem']]], + ['setitemmargin',['setItemMargin',['../class_qwt_plot_legend_item.html#a85933f3f34ce2ed226217e35eb0341be',1,'QwtPlotLegendItem']]], + ['setitemmode',['setItemMode',['../class_qwt_legend_label.html#a2f469bcbc733332110d61d70f863df2e',1,'QwtLegendLabel']]], + ['setitemspacing',['setItemSpacing',['../class_qwt_plot_legend_item.html#a6f1f7d6e9161260ac703abc1118a63b9',1,'QwtPlotLegendItem']]], + ['setkeyfactor',['setKeyFactor',['../class_qwt_magnifier.html#ac079b44e124fdaba1d894ef519bc4e4f',1,'QwtMagnifier']]], + ['setkeypattern',['setKeyPattern',['../class_qwt_event_pattern.html#ae3543f014372987ed1aff4b2b880f631',1,'QwtEventPattern::setKeyPattern(KeyPatternCode, int keyCode, Qt::KeyboardModifiers modifierCodes=Qt::NoModifier)'],['../class_qwt_event_pattern.html#a73cf4257902b8a9d95aef60fabd3f747',1,'QwtEventPattern::setKeyPattern(const QVector< KeyPattern > &)']]], + ['setknobstyle',['setKnobStyle',['../class_qwt_knob.html#a3e69357a595407a73c23df7ad68bf117',1,'QwtKnob']]], + ['setknobwidth',['setKnobWidth',['../class_qwt_knob.html#a3c5fd9348d4fc0ffd39eb4d98daca831',1,'QwtKnob']]], + ['setlabel',['setLabel',['../class_qwt_plot_marker.html#ad90adc27ccd6a10a7d6d1bb4464bf7d1',1,'QwtPlotMarker']]], + ['setlabelalignment',['setLabelAlignment',['../class_qwt_plot_marker.html#ab0c88d103cc68093ac7469ad421105e0',1,'QwtPlotMarker::setLabelAlignment()'],['../class_qwt_scale_draw.html#a3df0a1fe4a498ef028a5348e54bfaa7f',1,'QwtScaleDraw::setLabelAlignment()'],['../class_qwt_scale_widget.html#a8d16473c34f8eaea7e6c457a4de25949',1,'QwtScaleWidget::setLabelAlignment()']]], + ['setlabelmap',['setLabelMap',['../class_qwt_compass_scale_draw.html#a55c807e3399832b53b4a9783780f9dd0',1,'QwtCompassScaleDraw']]], + ['setlabelorientation',['setLabelOrientation',['../class_qwt_plot_marker.html#a2bd6a30b0b04bd2c07505e1cfcdd2561',1,'QwtPlotMarker']]], + ['setlabelrotation',['setLabelRotation',['../class_qwt_scale_draw.html#abf5881339fddde65a00c1dd391023320',1,'QwtScaleDraw::setLabelRotation()'],['../class_qwt_scale_widget.html#aea277057b98a66ee8038f6a827e0f404',1,'QwtScaleWidget::setLabelRotation()']]], + ['setlayoutattribute',['setLayoutAttribute',['../class_qwt_text.html#a2b621d3104ead2185d2d939b1f5b9d68',1,'QwtText']]], + ['setlayoutflag',['setLayoutFlag',['../class_qwt_plot_renderer.html#ab06e26ebf2038b55e5f30bb14c90caec',1,'QwtPlotRenderer::setLayoutFlag()'],['../class_qwt_scale_widget.html#a6e3495e29ba5dfb4a75827ec1df03f6a',1,'QwtScaleWidget::setLayoutFlag()']]], + ['setlayoutflags',['setLayoutFlags',['../class_qwt_plot_renderer.html#a475ee59a0a3078380b6da31567bd0a14',1,'QwtPlotRenderer']]], + ['setlayouthint',['setLayoutHint',['../class_qwt_plot_abstract_bar_chart.html#aff6bb52dad207c8396b359a248a00359',1,'QwtPlotAbstractBarChart']]], + ['setlayoutpolicy',['setLayoutPolicy',['../class_qwt_plot_abstract_bar_chart.html#aabc7165ee75a38f444aa97e9b3dca16b',1,'QwtPlotAbstractBarChart']]], + ['setlegendattribute',['setLegendAttribute',['../class_qwt_plot_curve.html#a0b1b7816e822607eb16e6eb2fd7bfa5c',1,'QwtPlotCurve']]], + ['setlegendiconsize',['setLegendIconSize',['../class_qwt_plot_item.html#a0827dd69bf19ec0145b6cc6efad2c11b',1,'QwtPlotItem']]], + ['setlegendmode',['setLegendMode',['../class_qwt_plot_bar_chart.html#a1ba4d1347a2d493fe3859a1c0fac6a6d',1,'QwtPlotBarChart::setLegendMode()'],['../class_qwt_plot_shape_item.html#a2daf96fc886bb84e4a55913fc0c39906',1,'QwtPlotShapeItem::setLegendMode()']]], + ['setlegendposition',['setLegendPosition',['../class_qwt_plot_layout.html#a11c9695a68f95135841cb23212589f18',1,'QwtPlotLayout::setLegendPosition(QwtPlot::LegendPosition pos, double ratio)'],['../class_qwt_plot_layout.html#a001f1eca91803d0eaa9548efc50879eb',1,'QwtPlotLayout::setLegendPosition(QwtPlot::LegendPosition pos)']]], + ['setlegendratio',['setLegendRatio',['../class_qwt_plot_layout.html#aabe9f952046139667e055c661bee4dbb',1,'QwtPlotLayout']]], + ['setlegendrect',['setLegendRect',['../class_qwt_plot_layout.html#a5d5c1dacdfff8281acf0a909acaf866c',1,'QwtPlotLayout']]], + ['setlength',['setLength',['../class_qwt_scale_draw.html#a002528e391ce07246a5d6b05b4bac9d9',1,'QwtScaleDraw']]], + ['setlinepen',['setLinePen',['../class_qwt_plot_marker.html#a9414658a5980527326b87615d0fc1560',1,'QwtPlotMarker::setLinePen(const QColor &, qreal width=0.0, Qt::PenStyle=Qt::SolidLine)'],['../class_qwt_plot_marker.html#ac21d413827e42d8a9d5c35a373314195',1,'QwtPlotMarker::setLinePen(const QPen &p)']]], + ['setlinestyle',['setLineStyle',['../class_qwt_plot_marker.html#ae4533f9f9f5a7dfbc85729215d4b5932',1,'QwtPlotMarker']]], + ['setlinewidth',['setLineWidth',['../class_qwt_column_symbol.html#af9348444ae2c21d3bcaff3217fc694fc',1,'QwtColumnSymbol::setLineWidth()'],['../class_qwt_dial.html#a7946ca363a97fd28de4993a5caa54507',1,'QwtDial::setLineWidth()'],['../class_qwt_plot_g_l_canvas.html#a9b831253eef4f77a0f580468cb5e41d6',1,'QwtPlotGLCanvas::setLineWidth()']]], + ['setlowerbound',['setLowerBound',['../class_qwt_abstract_scale.html#aa1b73da4589370fc14fd2ef49b02d142',1,'QwtAbstractScale::setLowerBound()'],['../class_qwt_scale_div.html#a7d334df11402bf3a5146a8232144bdf8',1,'QwtScaleDiv::setLowerBound()']]], + ['setmajorpen',['setMajorPen',['../class_qwt_plot_grid.html#a08aa0669817c8a797e7c22731a02a66d',1,'QwtPlotGrid::setMajorPen(const QColor &, qreal width=0.0, Qt::PenStyle=Qt::SolidLine)'],['../class_qwt_plot_grid.html#a6fb1cc92165d29deebac5c68c4ab18dd',1,'QwtPlotGrid::setMajorPen(const QPen &)']]], + ['setmargin',['setMargin',['../class_qwt_plot_abstract_bar_chart.html#a97946d3da8e9fe2e49494a882651e4fd',1,'QwtPlotAbstractBarChart::setMargin()'],['../class_qwt_plot_legend_item.html#a503f19f2c8b2b7549a74ef887081bb8d',1,'QwtPlotLegendItem::setMargin()'],['../class_qwt_plot_text_label.html#a28bba339d2996ae2a8a426575820a816',1,'QwtPlotTextLabel::setMargin()'],['../class_qwt_scale_widget.html#a36d92ef63d996fe1fd58a46431924ab6',1,'QwtScaleWidget::setMargin()'],['../class_qwt_text_label.html#a833d27574b72bbc135f2972c72382eba',1,'QwtTextLabel::setMargin()']]], + ['setmargins',['setMargins',['../class_qwt_scale_engine.html#aed2ab1fc105a25fa97bbecf4b2f541a7',1,'QwtScaleEngine']]], + ['setmarkersize',['setMarkerSize',['../class_qwt_knob.html#a88e06ffddd31d3c0df04771793173353',1,'QwtKnob']]], + ['setmarkerstyle',['setMarkerStyle',['../class_qwt_knob.html#aaa80356a3e3d3703070a6f2b1802646c',1,'QwtKnob']]], + ['setmaskmode',['setMaskMode',['../class_qwt_widget_overlay.html#a56828c036263679fc95087bd87496df0',1,'QwtWidgetOverlay']]], + ['setmass',['setMass',['../class_qwt_wheel.html#a2af8b9b10ebff58b351027208c1e2b86',1,'QwtWheel']]], + ['setmaxcolumns',['setMaxColumns',['../class_qwt_dyn_grid_layout.html#a436bdce04ae004008acf2e1282941032',1,'QwtDynGridLayout::setMaxColumns()'],['../class_qwt_legend.html#adc427eb1a6ee6a3c17f7c1b8867b48b2',1,'QwtLegend::setMaxColumns()'],['../class_qwt_plot_legend_item.html#a8b6f1db48c05feb5d0f8525b41898be7',1,'QwtPlotLegendItem::setMaxColumns()']]], + ['setmaximum',['setMaximum',['../class_qwt_counter.html#a5ada3f5f233e93e79bfd84eb4dd99519',1,'QwtCounter::setMaximum()'],['../class_qwt_wheel.html#a9d3cb6dceb49c33935277603610b7934',1,'QwtWheel::setMaximum()']]], + ['setmaxscalearc',['setMaxScaleArc',['../class_qwt_dial.html#ad508f5c8bff6d0ae7023c834b7ed2ee6',1,'QwtDial']]], + ['setmaxstackdepth',['setMaxStackDepth',['../class_qwt_plot_zoomer.html#a3965591944793790407ba91d6de3a882',1,'QwtPlotZoomer']]], + ['setmaxsymbolwidth',['setMaxSymbolWidth',['../class_qwt_plot_trading_curve.html#af97b34d767ae5a89076ec79324739bc5',1,'QwtPlotTradingCurve']]], + ['setmaxvalue',['setMaxValue',['../class_qwt_interval.html#a3eeedaf35966d535670863cb0f97613a',1,'QwtInterval']]], + ['setmaxweeks',['setMaxWeeks',['../class_qwt_date_scale_engine.html#a0520441c198ee00c9d727340f639504b',1,'QwtDateScaleEngine']]], + ['setmidlinewidth',['setMidLineWidth',['../class_qwt_plot_g_l_canvas.html#a529cce50eea2c9a46fe9c41852f6cee3',1,'QwtPlotGLCanvas']]], + ['setminborderdist',['setMinBorderDist',['../class_qwt_scale_widget.html#a4299d99073231d977924c7e40ff9a6a9',1,'QwtScaleWidget']]], + ['setminimum',['setMinimum',['../class_qwt_counter.html#a511c9d97d31860d1720d8008fb8e2793',1,'QwtCounter::setMinimum()'],['../class_qwt_wheel.html#af9c58c5a8097f6e6f87bbaed48e34abb',1,'QwtWheel::setMinimum()']]], + ['setminimumextent',['setMinimumExtent',['../class_qwt_abstract_scale_draw.html#ac174255c334b995ca010a6964597d5f2',1,'QwtAbstractScaleDraw']]], + ['setminorpen',['setMinorPen',['../class_qwt_plot_grid.html#aeac99ccce0d170a9500f238cf0321669',1,'QwtPlotGrid::setMinorPen(const QColor &, qreal width=0.0, Qt::PenStyle=Qt::SolidLine)'],['../class_qwt_plot_grid.html#a6f184d76d56a470166cdc5141cd33014',1,'QwtPlotGrid::setMinorPen(const QPen &p)']]], + ['setminscalearc',['setMinScaleArc',['../class_qwt_dial.html#abed02cef48f26bafbf0a92c8c4e5abc9',1,'QwtDial']]], + ['setminsymbolwidth',['setMinSymbolWidth',['../class_qwt_plot_trading_curve.html#a8411a6cd96cf521e95a06792a0b99a52',1,'QwtPlotTradingCurve']]], + ['setminvalue',['setMinValue',['../class_qwt_interval.html#ab993dac41ca70402e0cb4f9f980d90f0',1,'QwtInterval']]], + ['setmode',['setMode',['../class_qwt_linear_color_map.html#afca7397fb6d07d05bab83e83e274a9c2',1,'QwtLinearColorMap::setMode()'],['../class_qwt_dial.html#a6b070ba6251fa40bbd876551413c5639',1,'QwtDial::setMode()'],['../class_qwt_null_paint_device.html#a8b159556695136a58eec6e78fd88957b',1,'QwtNullPaintDevice::setMode()']]], + ['setmousebutton',['setMouseButton',['../class_qwt_magnifier.html#ad814a5d9cb227d6fb56f8289dffe597c',1,'QwtMagnifier::setMouseButton()'],['../class_qwt_panner.html#a6f138454b2c1d7e814ae1975d6a7b8be',1,'QwtPanner::setMouseButton()']]], + ['setmousefactor',['setMouseFactor',['../class_qwt_magnifier.html#ada5dac479dc1e69c04760bb7dc197ac9',1,'QwtMagnifier']]], + ['setmousepattern',['setMousePattern',['../class_qwt_event_pattern.html#a0b786f31af2f8084ec361bc905beda3f',1,'QwtEventPattern::setMousePattern(MousePatternCode, Qt::MouseButton button, Qt::KeyboardModifiers=Qt::NoModifier)'],['../class_qwt_event_pattern.html#ad8e3b196c1026b038ccdf359f9a69d29',1,'QwtEventPattern::setMousePattern(const QVector< MousePattern > &)']]], + ['setneedle',['setNeedle',['../class_qwt_dial.html#ac91311f8777eabdbcf6384f308d34a0c',1,'QwtDial']]], + ['setnumbuttons',['setNumButtons',['../class_qwt_counter.html#ae9241fda2e375becdb484cc2cf7752f4',1,'QwtCounter']]], + ['setnumthornlevels',['setNumThornLevels',['../class_qwt_simple_compass_rose.html#ad91026da3b586a3193a264401221a275',1,'QwtSimpleCompassRose']]], + ['setnumthorns',['setNumThorns',['../class_qwt_simple_compass_rose.html#a3c86abb463eb4741d1776318d6fa557b',1,'QwtSimpleCompassRose']]], + ['setnumturns',['setNumTurns',['../class_qwt_knob.html#a8d69c0c3bc110eaa68cfda26d31a8e98',1,'QwtKnob']]], + ['setorientation',['setOrientation',['../class_qwt_plot_series_item.html#a9d131249079ec3bc503831349bd1a051',1,'QwtPlotSeriesItem::setOrientation()'],['../class_qwt_plot_zone_item.html#a0e957d092637846d8c7e7f6d1282e8ac',1,'QwtPlotZoneItem::setOrientation()'],['../class_qwt_slider.html#a3a5d51f56dee5e51dc37bb6f546b16b5',1,'QwtSlider::setOrientation()'],['../class_qwt_thermo.html#ae6c0926a7d4d163e08a0f940642b2ea9',1,'QwtThermo::setOrientation()'],['../class_qwt_wheel.html#acae74c8161fd1df728f26253dd1defa8',1,'QwtWheel::setOrientation()']]], + ['setorientations',['setOrientations',['../class_qwt_panner.html#aaa71a8b6f7f46ae8f5a8084094d7bd9a',1,'QwtPanner']]], + ['setorigin',['setOrigin',['../class_qwt_dial.html#a3f64c6fbac747f735e57c2073e93bc50',1,'QwtDial::setOrigin()'],['../class_qwt_thermo.html#a00f3853e0fabfe89cbf47d35c15b0aa4',1,'QwtThermo::setOrigin()']]], + ['setoriginmode',['setOriginMode',['../class_qwt_thermo.html#a95cca109a11bba24d8e8a422a3717ab0',1,'QwtThermo']]], + ['setpagestepcount',['setPageStepCount',['../class_qwt_wheel.html#adeecd6e684163c92143908240f89ce1e',1,'QwtWheel']]], + ['setpagesteps',['setPageSteps',['../class_qwt_abstract_slider.html#ae2af9e818c0e7fb39a3a07174e4dabf2',1,'QwtAbstractSlider']]], + ['setpaintattribute',['setPaintAttribute',['../class_qwt_plot_canvas.html#a7859beb87bcef4fd53f99e7c87104e27',1,'QwtPlotCanvas::setPaintAttribute()'],['../class_qwt_plot_curve.html#a7f9c70366415b5cb068af80be5bf3748',1,'QwtPlotCurve::setPaintAttribute()'],['../class_qwt_plot_interval_curve.html#ab962c4ad6896bc9d9450f6436f00bd81',1,'QwtPlotIntervalCurve::setPaintAttribute()'],['../class_qwt_plot_raster_item.html#a70d6b94821e5eafb29b1f045d1f3a2e6',1,'QwtPlotRasterItem::setPaintAttribute()'],['../class_qwt_plot_shape_item.html#acd66d009cd24cdfb418a5cc9486b5001',1,'QwtPlotShapeItem::setPaintAttribute()'],['../class_qwt_plot_spectro_curve.html#a3a2ddc8e46bc4414b5ce104e7c70f9b4',1,'QwtPlotSpectroCurve::setPaintAttribute()'],['../class_qwt_plot_trading_curve.html#ac0b8015b37a90a5ae995569158fae4e2',1,'QwtPlotTradingCurve::setPaintAttribute()'],['../class_qwt_text.html#aac80e3f05137173059b196206ceea9e8',1,'QwtText::setPaintAttribute()']]], + ['setpaintinterval',['setPaintInterval',['../class_qwt_scale_map.html#a994240e446986112f196a65657dc9755',1,'QwtScaleMap']]], + ['setpalette',['setPalette',['../class_qwt_column_symbol.html#a7d2b17a4b8aef7ae098fd42bc663527b',1,'QwtColumnSymbol::setPalette()'],['../class_qwt_compass_rose.html#ad69f887ed012d6bf6bf2ffeb133e26d5',1,'QwtCompassRose::setPalette()'],['../class_qwt_dial_needle.html#ae850883a64501136bca64d6ea2d084b9',1,'QwtDialNeedle::setPalette()'],['../class_qwt_plot_scale_item.html#aff7adf18c2a6f679227c0fdaa54f39f7',1,'QwtPlotScaleItem::setPalette()']]], + ['setpath',['setPath',['../class_qwt_symbol.html#a67a6005486f1ae864acfd4778e9282db',1,'QwtSymbol']]], + ['setpen',['setPen',['../class_qwt_interval_symbol.html#a9c3bbee5ea764f246e66bd7bc9382b79',1,'QwtIntervalSymbol::setPen(const QColor &, qreal width=0.0, Qt::PenStyle=Qt::SolidLine)'],['../class_qwt_interval_symbol.html#af40ddcffa51daf70c9f44f18b33a9ee2',1,'QwtIntervalSymbol::setPen(const QPen &)'],['../class_qwt_plot_curve.html#ae00bd073a2bcf7c3c810d70af1f86750',1,'QwtPlotCurve::setPen(const QColor &, qreal width=0.0, Qt::PenStyle=Qt::SolidLine)'],['../class_qwt_plot_curve.html#a08328abaf2c3b67e479d1e485d2d0c4d',1,'QwtPlotCurve::setPen(const QPen &)'],['../class_qwt_plot_grid.html#aa85de55eb3c28f15d4000a11d194b758',1,'QwtPlotGrid::setPen(const QColor &, qreal width=0.0, Qt::PenStyle=Qt::SolidLine)'],['../class_qwt_plot_grid.html#af80a13ae94179cf11967d0c39c85c3df',1,'QwtPlotGrid::setPen(const QPen &)'],['../class_qwt_plot_histogram.html#a57d55a701251e55d52a142d417f12d38',1,'QwtPlotHistogram::setPen(const QColor &, qreal width=0.0, Qt::PenStyle=Qt::SolidLine)'],['../class_qwt_plot_histogram.html#a230e53561dd2645ba34beaa89f4f4f61',1,'QwtPlotHistogram::setPen(const QPen &)'],['../class_qwt_plot_interval_curve.html#a41a5be16fecb66885f5dd08779fbee6b',1,'QwtPlotIntervalCurve::setPen(const QColor &, qreal width=0.0, Qt::PenStyle=Qt::SolidLine)'],['../class_qwt_plot_interval_curve.html#a706a3e88fbec2ab48a1a3e91c61cd223',1,'QwtPlotIntervalCurve::setPen(const QPen &)'],['../class_qwt_plot_shape_item.html#a7626d822bf3d7905a606a0e0c7079c11',1,'QwtPlotShapeItem::setPen(const QColor &, qreal width=0.0, Qt::PenStyle=Qt::SolidLine)'],['../class_qwt_plot_shape_item.html#a2ccab3059bb905fc2baee07cb69a262b',1,'QwtPlotShapeItem::setPen(const QPen &)'],['../class_qwt_plot_zone_item.html#a76a86eb41801930e5733bc509966ee4d',1,'QwtPlotZoneItem::setPen(const QColor &, qreal width=0.0, Qt::PenStyle=Qt::SolidLine)'],['../class_qwt_plot_zone_item.html#a29e88c47cdde211812df6d1073ab5c69',1,'QwtPlotZoneItem::setPen(const QPen &)'],['../class_qwt_symbol.html#a144ca0e312c4a1e64c2d9e161c01fb7c',1,'QwtSymbol::setPen(const QColor &, qreal width=0.0, Qt::PenStyle=Qt::SolidLine)'],['../class_qwt_symbol.html#ac4d75a6a9f9ae7f8f1002c465d5bbcb6',1,'QwtSymbol::setPen(const QPen &)']]], + ['setpenwidth',['setPenWidth',['../class_qwt_abstract_scale_draw.html#a098e1f813077c9bb0c5f83266035943a',1,'QwtAbstractScaleDraw::setPenWidth()'],['../class_qwt_plot_spectro_curve.html#ac3246da1a881538149addc2f22401578',1,'QwtPlotSpectroCurve::setPenWidth()']]], + ['setpinpoint',['setPinPoint',['../class_qwt_symbol.html#a78643c91d94690b91745f10f0601579e',1,'QwtSymbol']]], + ['setpinpointenabled',['setPinPointEnabled',['../class_qwt_symbol.html#a570e07b342701bf37794bf1191917005',1,'QwtSymbol']]], + ['setpipewidth',['setPipeWidth',['../class_qwt_thermo.html#a9d3a55a818ebf0dd508e20ca9eef224b',1,'QwtThermo']]], + ['setpixmap',['setPixmap',['../class_qwt_symbol.html#a69b548566bbd186992869b54777a0728',1,'QwtSymbol']]], + ['setplaintext',['setPlainText',['../class_qwt_text_label.html#a02113ab776a00ab8bbc83197ce49445e',1,'QwtTextLabel']]], + ['setplotlayout',['setPlotLayout',['../class_qwt_plot.html#a08e258f9ba498662a8be9a559c9c7e44',1,'QwtPlot']]], + ['setpoint',['setPoint',['../class_qwt_point_polar.html#a8cd4f93356a8a8c07400c3ad9ff1b560',1,'QwtPointPolar']]], + ['setpoints',['setPoints',['../class_qwt_spline.html#a6ed13410b1d5f6b33ba0e3c2b07932cf',1,'QwtSpline']]], + ['setpolygon',['setPolygon',['../class_qwt_plot_shape_item.html#a9810bd70cfdff88d14f88d9edf20c85b',1,'QwtPlotShapeItem']]], + ['setpolylinesplitting',['setPolylineSplitting',['../class_qwt_painter.html#a174bca411198c64dfff828a15d80ddfb',1,'QwtPainter']]], + ['setposition',['setPosition',['../class_qwt_plot_scale_item.html#a94536af312bb9d6de5bc7547c59e4faf',1,'QwtPlotScaleItem']]], + ['setradius',['setRadius',['../class_qwt_point_polar.html#a31ae2f4d6fad44f51ad5e7444a7f21fe',1,'QwtPointPolar::setRadius()'],['../class_qwt_round_scale_draw.html#a219e0db15594f297ae6ff769fd6c0485',1,'QwtRoundScaleDraw::setRadius()']]], + ['setrange',['setRange',['../class_qwt_counter.html#ad794d0d2589a38113933ae764e87ce22',1,'QwtCounter::setRange()'],['../class_qwt_wheel.html#a572f0bc2c5cd4c4f5e0b0f48c914a0e5',1,'QwtWheel::setRange()']]], + ['setrangeflags',['setRangeFlags',['../class_qwt_thermo.html#aa2ce6d6d20097fead0baca0ab31ef1b2',1,'QwtThermo']]], + ['setrawsamples',['setRawSamples',['../class_qwt_plot_curve.html#afd13c94e23520dacbc37b4d0fd036a8b',1,'QwtPlotCurve']]], + ['setreadonly',['setReadOnly',['../class_qwt_abstract_slider.html#a9cc63283a2d4f0bcbb67fd331629a318',1,'QwtAbstractSlider::setReadOnly()'],['../class_qwt_counter.html#ad34441cf06c68478b826e5b85fbb3ba7',1,'QwtCounter::setReadOnly()']]], + ['setrect',['setRect',['../class_qwt_pixel_matrix.html#ae8150f8d1f1922746172e9da1488e98b',1,'QwtPixelMatrix::setRect()'],['../class_qwt_plot_shape_item.html#a0a448e4354f67a3957b8123214cd75bb',1,'QwtPlotShapeItem::setRect()']]], + ['setrectofinterest',['setRectOfInterest',['../class_qwt_synthetic_point_data.html#a39cc8512e7d8beecde003f7781174b84',1,'QwtSyntheticPointData::setRectOfInterest()'],['../class_qwt_series_data.html#a391b4601a7454b2f9582fbc2662d108e',1,'QwtSeriesData::setRectOfInterest()'],['../class_qwt_abstract_series_store.html#a8a1cab11ce068f9c578a02d40e111b1a',1,'QwtAbstractSeriesStore::setRectOfInterest()'],['../class_qwt_series_store.html#a64971dd5eaed045b88ac06c9cd8fd6e9',1,'QwtSeriesStore::setRectOfInterest()']]], + ['setreference',['setReference',['../class_qwt_scale_engine.html#a89985ea69dbd858c8b9162ecd2be936e',1,'QwtScaleEngine']]], + ['setreferenceaxis',['setReferenceAxis',['../class_qwt_plot_rescaler.html#a6f13d60cc1e1071a6830ea30ccbcca37',1,'QwtPlotRescaler']]], + ['setrenderflags',['setRenderFlags',['../class_qwt_text.html#a2e71d427de766455323794f27d369a5d',1,'QwtText']]], + ['setrenderhint',['setRenderHint',['../class_qwt_graphic.html#a494b5de0452120653188828f6a1a6f55',1,'QwtGraphic::setRenderHint()'],['../class_qwt_plot_item.html#acd023c40f659c304ded324942865edc8',1,'QwtPlotItem::setRenderHint()']]], + ['setrendermode',['setRenderMode',['../class_qwt_widget_overlay.html#a80fd06e2111993848f45a21627ec09b4',1,'QwtWidgetOverlay']]], + ['setrenderthreadcount',['setRenderThreadCount',['../class_qwt_plot_item.html#a188ae18fbbce9adcf259ebe2f0de1f6b',1,'QwtPlotItem']]], + ['setrendertolerance',['setRenderTolerance',['../class_qwt_plot_shape_item.html#a76f617b8662ed118382d49c5201791e2',1,'QwtPlotShapeItem']]], + ['setresamplemode',['setResampleMode',['../class_qwt_matrix_raster_data.html#a038effe6e4be13725b7a8d35370595fd',1,'QwtMatrixRasterData']]], + ['setrescalepolicy',['setRescalePolicy',['../class_qwt_plot_rescaler.html#ae6b7df41b5387d0aed532559546e40b6',1,'QwtPlotRescaler']]], + ['setresizemode',['setResizeMode',['../class_qwt_picker.html#af85c8a3c709bd106d2b34b718a746e03',1,'QwtPicker']]], + ['setrose',['setRose',['../class_qwt_compass.html#a06456c0c52107bfa8b1d1267fba5b86f',1,'QwtCompass']]], + ['setroundingalignment',['setRoundingAlignment',['../class_qwt_painter.html#a49581f980f2c761852cda08502c96abb',1,'QwtPainter']]], + ['setrubberband',['setRubberBand',['../class_qwt_picker.html#a83096bad2662e02e4914a7b40241c351',1,'QwtPicker']]], + ['setrubberbandpen',['setRubberBandPen',['../class_qwt_picker.html#a13117b1929f1ca00a75002f7f4c612bc',1,'QwtPicker']]], + ['setsamples',['setSamples',['../class_qwt_plot_bar_chart.html#a669eb25dba458699465b317f2e96c1eb',1,'QwtPlotBarChart::setSamples(const QVector< QPointF > &)'],['../class_qwt_plot_bar_chart.html#a1b9e0f311a5570a93663994eb90b364f',1,'QwtPlotBarChart::setSamples(const QVector< double > &)'],['../class_qwt_plot_bar_chart.html#a257226bc375b036c7501d83e82360aef',1,'QwtPlotBarChart::setSamples(QwtSeriesData< QPointF > *series)'],['../class_qwt_plot_curve.html#aa51cd3fa00f2a046ca5a9889c5db2413',1,'QwtPlotCurve::setSamples(const double *xData, const double *yData, int size)'],['../class_qwt_plot_curve.html#a1e6e9a417479e372197b746538fae47c',1,'QwtPlotCurve::setSamples(const QVector< double > &xData, const QVector< double > &yData)'],['../class_qwt_plot_curve.html#a67b24f3663484ff5e973a288c6071b2a',1,'QwtPlotCurve::setSamples(const QVector< QPointF > &)'],['../class_qwt_plot_curve.html#afa11e2336827438b8f05dfae2d1668e6',1,'QwtPlotCurve::setSamples(QwtSeriesData< QPointF > *)'],['../class_qwt_plot_histogram.html#a6cc1fe6cd9f7dfc55a2bf5afd02ccce5',1,'QwtPlotHistogram::setSamples(const QVector< QwtIntervalSample > &)'],['../class_qwt_plot_histogram.html#a2207266b529e691a5d7a406643ff4fd5',1,'QwtPlotHistogram::setSamples(QwtSeriesData< QwtIntervalSample > *)'],['../class_qwt_plot_interval_curve.html#ac60fd04f3000b26ea82342065ba82afe',1,'QwtPlotIntervalCurve::setSamples(const QVector< QwtIntervalSample > &)'],['../class_qwt_plot_interval_curve.html#a7b7e1e4867c27f760c894b22e04d3ca8',1,'QwtPlotIntervalCurve::setSamples(QwtSeriesData< QwtIntervalSample > *)'],['../class_qwt_plot_multi_bar_chart.html#ad54633b91b7f602e376f3acb9e235e3c',1,'QwtPlotMultiBarChart::setSamples(const QVector< QwtSetSample > &)'],['../class_qwt_plot_multi_bar_chart.html#a95a17a8087bd87e5fea5ea4fbb910ecf',1,'QwtPlotMultiBarChart::setSamples(const QVector< QVector< double > > &)'],['../class_qwt_plot_multi_bar_chart.html#ab24b14666946b36e51bace7b5ecb0f81',1,'QwtPlotMultiBarChart::setSamples(QwtSeriesData< QwtSetSample > *)'],['../class_qwt_plot_spectro_curve.html#a668926af2266515a5d82911ac81262ca',1,'QwtPlotSpectroCurve::setSamples(const QVector< QwtPoint3D > &)'],['../class_qwt_plot_spectro_curve.html#a6374cf95ed6731d098328f2b8c317a8c',1,'QwtPlotSpectroCurve::setSamples(QwtSeriesData< QwtPoint3D > *)'],['../class_qwt_plot_trading_curve.html#a5675417b12acd80ff37ec66df2907c9f',1,'QwtPlotTradingCurve::setSamples(const QVector< QwtOHLCSample > &)'],['../class_qwt_plot_trading_curve.html#a715d423a080355522ab9a176be64b58e',1,'QwtPlotTradingCurve::setSamples(QwtSeriesData< QwtOHLCSample > *)'],['../class_qwt_array_series_data.html#a4afaaf2602be769f4bdcc8fda6b737cb',1,'QwtArraySeriesData::setSamples()']]], + ['setscale',['setScale',['../class_qwt_abstract_scale.html#ae9640e814b5029d7dd79cb3ba752102b',1,'QwtAbstractScale::setScale(double lowerBound, double upperBound)'],['../class_qwt_abstract_scale.html#ab54877c80f0b00fdb6e4745448aee128',1,'QwtAbstractScale::setScale(const QwtInterval &)'],['../class_qwt_abstract_scale.html#ad002e1a352ecf85c1a8595a138d42db7',1,'QwtAbstractScale::setScale(const QwtScaleDiv &)']]], + ['setscalearc',['setScaleArc',['../class_qwt_dial.html#a8abc41e15c62017d3c3ffb98acb9677f',1,'QwtDial']]], + ['setscalediv',['setScaleDiv',['../class_qwt_abstract_scale_draw.html#a4399aac94a294f5ed6c52114dde00d2f',1,'QwtAbstractScaleDraw::setScaleDiv()'],['../class_qwt_plot_scale_item.html#a99032adf91892f73d06a4810cd78d26b',1,'QwtPlotScaleItem::setScaleDiv()'],['../class_qwt_scale_widget.html#ac7959531c846b54d728b846635fc1406',1,'QwtScaleWidget::setScaleDiv()']]], + ['setscaledivfromaxis',['setScaleDivFromAxis',['../class_qwt_plot_scale_item.html#a0b4660ad3d3fcf1f1de711b075b073c6',1,'QwtPlotScaleItem']]], + ['setscaledraw',['setScaleDraw',['../class_qwt_dial.html#a2ed8a0642e1c612013ba812c7e037404',1,'QwtDial::setScaleDraw()'],['../class_qwt_knob.html#afea44f23da7f79a2b790178850c26edd',1,'QwtKnob::setScaleDraw()'],['../class_qwt_plot_scale_item.html#a0224f2720f3df4fc781d10560a4a1590',1,'QwtPlotScaleItem::setScaleDraw()'],['../class_qwt_scale_widget.html#af93459026340638898c11a799f4ae0c0',1,'QwtScaleWidget::setScaleDraw()'],['../class_qwt_slider.html#a9039a6d5d5bb7b21c312637cf40f8319',1,'QwtSlider::setScaleDraw()'],['../class_qwt_thermo.html#a8b5ab653b893e41116200570632ad1c3',1,'QwtThermo::setScaleDraw()']]], + ['setscaleengine',['setScaleEngine',['../class_qwt_abstract_scale.html#aa00f44140af3f2b7595cb6e23371198f',1,'QwtAbstractScale']]], + ['setscaleinterval',['setScaleInterval',['../class_qwt_scale_map.html#aaa33bc8e1aed7aa17d345053194e7094',1,'QwtScaleMap']]], + ['setscalemaxmajor',['setScaleMaxMajor',['../class_qwt_abstract_scale.html#a40fdb4572ad8fdec8b93766ff5f8eda8',1,'QwtAbstractScale']]], + ['setscalemaxminor',['setScaleMaxMinor',['../class_qwt_abstract_scale.html#a6520bb1e52571f865b21b3710786a4db',1,'QwtAbstractScale']]], + ['setscaleposition',['setScalePosition',['../class_qwt_slider.html#a530aa52c218ad27e8eebbecc7a27e25a',1,'QwtSlider::setScalePosition()'],['../class_qwt_thermo.html#a0306a248194d2f8c08ba90506122d6ca',1,'QwtThermo::setScalePosition()']]], + ['setscalerect',['setScaleRect',['../class_qwt_plot_layout.html#a842733777eb2b0bf2cacc4bb01c169c7',1,'QwtPlotLayout']]], + ['setscalestepsize',['setScaleStepSize',['../class_qwt_abstract_scale.html#aac745efd9414e529794e2189f7c535cb',1,'QwtAbstractScale']]], + ['setshape',['setShape',['../class_qwt_plot_shape_item.html#a0a8f3ed22324b23d04588cc749b74674',1,'QwtPlotShapeItem']]], + ['setshrinkfactor',['setShrinkFactor',['../class_qwt_simple_compass_rose.html#afaf84e19eb8eb2360306860b02d46cfc',1,'QwtSimpleCompassRose']]], + ['setsinglestep',['setSingleStep',['../class_qwt_counter.html#a7d1057b48f57d890bf5c60259b456350',1,'QwtCounter::setSingleStep()'],['../class_qwt_wheel.html#a63f5d4794cc1e624ab305083c7f4ed29',1,'QwtWheel::setSingleStep()']]], + ['setsinglesteps',['setSingleSteps',['../class_qwt_abstract_slider.html#ad470727c9fa3da9c50e26138cf03623e',1,'QwtAbstractSlider']]], + ['setsize',['setSize',['../class_qwt_synthetic_point_data.html#a321754c5acac77e0e5685968b1cdfdae',1,'QwtSyntheticPointData::setSize()'],['../class_qwt_symbol.html#a9fa391b34596f89256278254fa2ae3d8',1,'QwtSymbol::setSize(const QSize &)'],['../class_qwt_symbol.html#afd5587cd1752594954ca6146f643acfb',1,'QwtSymbol::setSize(int width, int height=-1)']]], + ['setspacing',['setSpacing',['../class_qwt_abstract_scale_draw.html#ae5bdaadb303510f7eb9dbec5c52f7a47',1,'QwtAbstractScaleDraw::setSpacing()'],['../class_qwt_legend_label.html#ad19d9ee759551f1fe785dc0ad806fd59',1,'QwtLegendLabel::setSpacing()'],['../class_qwt_plot_abstract_bar_chart.html#a0cb5bd5a653918b1513fa87ad75fa8b1',1,'QwtPlotAbstractBarChart::setSpacing()'],['../class_qwt_plot_layout.html#a6508553ec1d66bede49e7767526c3d03',1,'QwtPlotLayout::setSpacing()'],['../class_qwt_plot_legend_item.html#a9932f074e5861464a055fdce6394889c',1,'QwtPlotLegendItem::setSpacing()'],['../class_qwt_plot_marker.html#a856c9c5c6e22d86461ee6df101534831',1,'QwtPlotMarker::setSpacing()'],['../class_qwt_scale_widget.html#aaaad9f3d54fd329b16b738ca2df00ddf',1,'QwtScaleWidget::setSpacing()'],['../class_qwt_slider.html#a947f384faba10690bbff780bfe9e420f',1,'QwtSlider::setSpacing()'],['../class_qwt_thermo.html#a5d772862c760019a7797f45aa6b0690f',1,'QwtThermo::setSpacing()']]], + ['setspline',['setSpline',['../class_qwt_spline_curve_fitter.html#a7f819ad010b19d58179655e4ceb1c6f1',1,'QwtSplineCurveFitter']]], + ['setsplinesize',['setSplineSize',['../class_qwt_spline_curve_fitter.html#a8ecea80fb540b92cd22b6b0703636460',1,'QwtSplineCurveFitter']]], + ['setsplinetype',['setSplineType',['../class_qwt_spline.html#a222953661f01658a16042d587196aff8',1,'QwtSpline']]], + ['setstate',['setState',['../class_qwt_picker_machine.html#a569c426543e4a6aa15c221eb7c4910f0',1,'QwtPickerMachine']]], + ['setstatemachine',['setStateMachine',['../class_qwt_picker.html#a5ff72a5658631bcad3857ca5cfd3e6d9',1,'QwtPicker']]], + ['setstepalignment',['setStepAlignment',['../class_qwt_abstract_slider.html#a758fe135e2ee173c98dac70777e6dd4c',1,'QwtAbstractSlider::setStepAlignment()'],['../class_qwt_wheel.html#a5e5bf1d335538ff6971d48b914f26d51',1,'QwtWheel::setStepAlignment()']]], + ['setstepbutton1',['setStepButton1',['../class_qwt_counter.html#ae56a556a72955b6d10419f2c41779383',1,'QwtCounter']]], + ['setstepbutton2',['setStepButton2',['../class_qwt_counter.html#a0d764a96706593d8c8b51338e92abfcc',1,'QwtCounter']]], + ['setstepbutton3',['setStepButton3',['../class_qwt_counter.html#a8b55539578de083793b8310cb8909294',1,'QwtCounter']]], + ['setstyle',['setStyle',['../class_qwt_column_symbol.html#a3e2c72514fdc2e857ee2a34bc9f96e93',1,'QwtColumnSymbol::setStyle()'],['../class_qwt_interval_symbol.html#a24d64169355cc200a49af15c08fe93fc',1,'QwtIntervalSymbol::setStyle()'],['../class_qwt_plot_curve.html#a2de41014c2b87fd459d0c438a15dd33e',1,'QwtPlotCurve::setStyle()'],['../class_qwt_plot_histogram.html#a449af026888616f08b45e980d9da57fe',1,'QwtPlotHistogram::setStyle()'],['../class_qwt_plot_interval_curve.html#a74e6c2bf66e0436e827b5b017b943cad',1,'QwtPlotIntervalCurve::setStyle()'],['../class_qwt_plot_multi_bar_chart.html#a4daa7bdd0043eeafe5ab6e5db290181d',1,'QwtPlotMultiBarChart::setStyle()'],['../class_qwt_symbol.html#a4d3b9f3dd8c4ca034694b86372b74eb9',1,'QwtSymbol::setStyle()']]], + ['setsvgdocument',['setSvgDocument',['../class_qwt_symbol.html#a5e6a790b3133c878fde132a7fcf91475',1,'QwtSymbol']]], + ['setsymbol',['setSymbol',['../class_qwt_plot_bar_chart.html#a3e3c50c37484c3049dc9f433269e9a44',1,'QwtPlotBarChart::setSymbol()'],['../class_qwt_plot_curve.html#a413b1a18de12ece4dec5ae0738ecd03f',1,'QwtPlotCurve::setSymbol()'],['../class_qwt_plot_histogram.html#aa662f072a1758bfac9c0c86136ee27ad',1,'QwtPlotHistogram::setSymbol()'],['../class_qwt_plot_interval_curve.html#a4bc2408868638a41f5baa70b759283a2',1,'QwtPlotIntervalCurve::setSymbol()'],['../class_qwt_plot_marker.html#af44231c2b63bb277706e4f515297c7b1',1,'QwtPlotMarker::setSymbol()'],['../class_qwt_plot_multi_bar_chart.html#ad08e420c6c450672694e9bf253dc8b3b',1,'QwtPlotMultiBarChart::setSymbol()']]], + ['setsymbolbrush',['setSymbolBrush',['../class_qwt_plot_trading_curve.html#ac9ec84c2c75ff3a5597cd30aafbd76c2',1,'QwtPlotTradingCurve']]], + ['setsymbolextent',['setSymbolExtent',['../class_qwt_plot_trading_curve.html#af52822a65584bbd19255e6b99fe9e8b2',1,'QwtPlotTradingCurve']]], + ['setsymbolpen',['setSymbolPen',['../class_qwt_plot_trading_curve.html#aa15ee206779a9f3ff180113421bc4baa',1,'QwtPlotTradingCurve::setSymbolPen(const QColor &, qreal width=0.0, Qt::PenStyle=Qt::SolidLine)'],['../class_qwt_plot_trading_curve.html#aec9c455a3a877c36d408383e5b4700e0',1,'QwtPlotTradingCurve::setSymbolPen(const QPen &)']]], + ['setsymbolstyle',['setSymbolStyle',['../class_qwt_plot_trading_curve.html#a0c9928481272af1487baa4e0dcd47202',1,'QwtPlotTradingCurve']]], + ['settext',['setText',['../class_qwt_legend_label.html#a2498e1b2e1a17abf63fa4d94a08ebb95',1,'QwtLegendLabel::setText()'],['../class_qwt_plot_text_label.html#adce2e99ef7816ff544c5a5525bf05006',1,'QwtPlotTextLabel::setText()'],['../class_qwt_text.html#a9ba9caa82fcfbc4bfbf8ce20ccea981e',1,'QwtText::setText()'],['../class_qwt_text_label.html#ab300b9a0a6392e180f2caff41ba2b9b8',1,'QwtTextLabel::setText(const QString &, QwtText::TextFormat textFormat=QwtText::AutoText)'],['../class_qwt_text_label.html#ac43ba313b78dccf7aa7433f26059b2e2',1,'QwtTextLabel::setText(const QwtText &)']]], + ['settextengine',['setTextEngine',['../class_qwt_text.html#aef6a1e71b1feba3116ce69f6c9de70ad',1,'QwtText']]], + ['settextpen',['setTextPen',['../class_qwt_plot_legend_item.html#ae41a2af3f5353a01ed5d4dd786b84ef7',1,'QwtPlotLegendItem']]], + ['settickcount',['setTickCount',['../class_qwt_wheel.html#ae13600528c5b13a27b4220ac53b22153',1,'QwtWheel']]], + ['setticklength',['setTickLength',['../class_qwt_abstract_scale_draw.html#a7fed388e435aae791d61f48cc9ddf632',1,'QwtAbstractScaleDraw']]], + ['setticks',['setTicks',['../class_qwt_scale_div.html#af67401fd5d16138eddede3381c559964',1,'QwtScaleDiv']]], + ['settime',['setTime',['../class_qwt_analog_clock.html#aa99a628b290789583052bcec9163d95c',1,'QwtAnalogClock']]], + ['settimespec',['setTimeSpec',['../class_qwt_date_scale_draw.html#a278fdb655a98dda440ce5c0f8fc82c4e',1,'QwtDateScaleDraw::setTimeSpec()'],['../class_qwt_date_scale_engine.html#addbf8fdc00c2de0c6afe436ef25b3bef',1,'QwtDateScaleEngine::setTimeSpec()']]], + ['settitle',['setTitle',['../class_qwt_plot.html#a9a7f0b219b404e5bed5dfca26c5c06a7',1,'QwtPlot::setTitle(const QString &)'],['../class_qwt_plot.html#a032ced8ddfad7483a372214954203719',1,'QwtPlot::setTitle(const QwtText &t)'],['../class_qwt_plot_item.html#a1b74686181ab6dd5033917123c7db30f',1,'QwtPlotItem::setTitle(const QString &title)'],['../class_qwt_plot_item.html#a2db3214b23b78274fa6f8c0321a76839',1,'QwtPlotItem::setTitle(const QwtText &title)'],['../class_qwt_scale_widget.html#a28ad440a43978d2d50f19e17d0776403',1,'QwtScaleWidget::setTitle(const QString &title)'],['../class_qwt_scale_widget.html#a1451d5d2293358ba097a833a40015524',1,'QwtScaleWidget::setTitle(const QwtText &title)']]], + ['settitlerect',['setTitleRect',['../class_qwt_plot_layout.html#a82b49e88c7928224c4b0342b6302c086',1,'QwtPlotLayout']]], + ['settolerance',['setTolerance',['../class_qwt_weeding_curve_fitter.html#a62c303f6826fef2be7b7bbe82f530680',1,'QwtWeedingCurveFitter']]], + ['settotalangle',['setTotalAngle',['../class_qwt_knob.html#a82c6a859d63833894a6e66f0fdbf8f05',1,'QwtKnob::setTotalAngle()'],['../class_qwt_wheel.html#ae4e5dfd4c6683706716681cfd7e3d8bf',1,'QwtWheel::setTotalAngle()']]], + ['settotalsteps',['setTotalSteps',['../class_qwt_abstract_slider.html#a60eea9d9996c99abcb7d50f5ed2634f8',1,'QwtAbstractSlider']]], + ['settrackerfont',['setTrackerFont',['../class_qwt_picker.html#a9f54cce7d2e3f6e06351315bf655d5d9',1,'QwtPicker']]], + ['settrackermode',['setTrackerMode',['../class_qwt_picker.html#a94fc60c7223cdc470ae63156f6446d6f',1,'QwtPicker']]], + ['settrackerpen',['setTrackerPen',['../class_qwt_picker.html#af703bc51cda716e503cbd86731270e5b',1,'QwtPicker']]], + ['settracking',['setTracking',['../class_qwt_abstract_slider.html#a58d37e22b616787793a9e62ec7c5adc3',1,'QwtAbstractSlider::setTracking()'],['../class_qwt_wheel.html#a181ca4c891e763ebe30a0ed74a329c2b',1,'QwtWheel::setTracking()']]], + ['settransformation',['setTransformation',['../class_qwt_abstract_scale_draw.html#a732d0e49c9092c48893b4f71cc7357db',1,'QwtAbstractScaleDraw::setTransformation()'],['../class_qwt_scale_engine.html#ad063f4bb947996191be5c2a5fa0dbaf6',1,'QwtScaleEngine::setTransformation()'],['../class_qwt_scale_map.html#ad8e971dd4be07801f0adc99549153718',1,'QwtScaleMap::setTransformation()'],['../class_qwt_scale_widget.html#a749ea25d3e0ab0d7e6335982f3919055',1,'QwtScaleWidget::setTransformation()']]], + ['settrough',['setTrough',['../class_qwt_slider.html#ab4de4c649662416dc12c92c8e7cd0273',1,'QwtSlider']]], + ['setupdateinterval',['setUpdateInterval',['../class_qwt_slider.html#aeaab96d3554d509dbdd93a539617b9e9',1,'QwtSlider::setUpdateInterval()'],['../class_qwt_wheel.html#a5c234f68f0ff9906e2861e6fcd9dcc54',1,'QwtWheel::setUpdateInterval()']]], + ['setupperbound',['setUpperBound',['../class_qwt_abstract_scale.html#a1b2ea5c97eb19ccd55ec83713ab675fe',1,'QwtAbstractScale::setUpperBound()'],['../class_qwt_scale_div.html#a56545b9c67dcfb4bd0c7b5fc430ab70d',1,'QwtScaleDiv::setUpperBound()']]], + ['setutcoffset',['setUtcOffset',['../class_qwt_date_scale_draw.html#ab97b5fc37dc46dcf635a56e13d7b93a3',1,'QwtDateScaleDraw::setUtcOffset()'],['../class_qwt_date_scale_engine.html#a47dc382bbdf3e415b40543fc2736537f',1,'QwtDateScaleEngine::setUtcOffset()']]], + ['setvalid',['setValid',['../class_qwt_abstract_slider.html#a6b527ff0d2f96b85465fd73250d2e03f',1,'QwtAbstractSlider::setValid()'],['../class_qwt_counter.html#aa06625ab417f82fdc82790e3376af708',1,'QwtCounter::setValid()']]], + ['setvalue',['setValue',['../class_qwt_abstract_slider.html#ac3713f8989b647cb79f0a5894991e36a',1,'QwtAbstractSlider::setValue()'],['../class_qwt_counter.html#a429a2e986aa46c1231643df5d4c78970',1,'QwtCounter::setValue()'],['../class_qwt_legend_data.html#a1be4b4cf3c1df733744633ea6c02346a',1,'QwtLegendData::setValue()'],['../class_qwt_matrix_raster_data.html#a4601944bceabd921cdaa544180576274',1,'QwtMatrixRasterData::setValue()'],['../class_qwt_plot_marker.html#ad3a480c64192dabffd02bf5db31f917c',1,'QwtPlotMarker::setValue(double, double)'],['../class_qwt_plot_marker.html#a290374903ca168104dbce7e2058774c3',1,'QwtPlotMarker::setValue(const QPointF &)'],['../class_qwt_thermo.html#ad54ebf4761c12f948d09cd45a26d1fd4',1,'QwtThermo::setValue()'],['../class_qwt_wheel.html#a6f46526b283b7fde127bc595c96db7e8',1,'QwtWheel::setValue()']]], + ['setvaluematrix',['setValueMatrix',['../class_qwt_matrix_raster_data.html#a578ffc26f04a9099e2b31fc2d9360adb',1,'QwtMatrixRasterData']]], + ['setvalues',['setValues',['../class_qwt_legend_data.html#a68c3bc398c541f345a12fa9321ad52ed',1,'QwtLegendData']]], + ['setviewangle',['setViewAngle',['../class_qwt_wheel.html#a7f15b6aef98ad6b52bebc749381bc753',1,'QwtWheel']]], + ['setvisible',['setVisible',['../class_qwt_plot_item.html#a5f0eeb2b72207fd8d33a95b0565657a1',1,'QwtPlotItem']]], + ['setweek0type',['setWeek0Type',['../class_qwt_date_scale_draw.html#acd5e9ce4e1e98e849d6002d22b2f7198',1,'QwtDateScaleDraw::setWeek0Type()'],['../class_qwt_date_scale_engine.html#a5e11c5e7c4f58063ded8f6d35d2816f4',1,'QwtDateScaleEngine::setWeek0Type()']]], + ['setwheelborderwidth',['setWheelBorderWidth',['../class_qwt_wheel.html#a4aa70134746908cef687e3c1bb7aa60c',1,'QwtWheel']]], + ['setwheelfactor',['setWheelFactor',['../class_qwt_magnifier.html#ae3a33ab8776ed2122fecc821a32bb36a',1,'QwtMagnifier']]], + ['setwheelmodifiers',['setWheelModifiers',['../class_qwt_magnifier.html#aadfc853d8619b43b21564d8d5fe50093',1,'QwtMagnifier']]], + ['setwheelwidth',['setWheelWidth',['../class_qwt_wheel.html#ac434254039981344ccca22c76bce4f38',1,'QwtWheel']]], + ['setwidth',['setWidth',['../class_qwt_simple_compass_rose.html#ae4067a436f45d2f2ca23d8233539566b',1,'QwtSimpleCompassRose::setWidth()'],['../class_qwt_dial_simple_needle.html#ad7672543371e38c864e44d9240271c22',1,'QwtDialSimpleNeedle::setWidth()'],['../class_qwt_interval_symbol.html#adfacdeb67c9e6d194df4d3d627de23eb',1,'QwtIntervalSymbol::setWidth()']]], + ['setwrapping',['setWrapping',['../class_qwt_abstract_slider.html#ada27ca51ab146554b981fafed38e41e0',1,'QwtAbstractSlider::setWrapping()'],['../class_qwt_counter.html#a8fc7d115682f295dfcc64fa8312ccdeb',1,'QwtCounter::setWrapping()'],['../class_qwt_wheel.html#a4ee4c2bcd6536f7639b5e275ab3235c2',1,'QwtWheel::setWrapping()']]], + ['setx',['setX',['../class_qwt_point3_d.html#afe85919187fd62bc3db082d1e2b17bac',1,'QwtPoint3D']]], + ['setxaxis',['setXAxis',['../class_qwt_plot_item.html#a81d3dd7feaadda4b0dbb8c13642046cf',1,'QwtPlotItem']]], + ['setxdiv',['setXDiv',['../class_qwt_plot_grid.html#aeeb88397c2aaf5e763d57c898a2fcd13',1,'QwtPlotGrid']]], + ['setxvalue',['setXValue',['../class_qwt_plot_marker.html#a0d53b0e0ed8b48478c02a0ecaf5852b2',1,'QwtPlotMarker']]], + ['sety',['setY',['../class_qwt_point3_d.html#a986ba13d44e6960b4fb72795be4ff66a',1,'QwtPoint3D']]], + ['setyaxis',['setYAxis',['../class_qwt_plot_item.html#aa92dad876d76ce136925d5ae8f01db9a',1,'QwtPlotItem']]], + ['setydiv',['setYDiv',['../class_qwt_plot_grid.html#a9eb130275560bdaa65551e2f69232b72',1,'QwtPlotGrid']]], + ['setyvalue',['setYValue',['../class_qwt_plot_marker.html#a47d8e3c0708ad02a9c7cc6aaf985e278',1,'QwtPlotMarker']]], + ['setz',['setZ',['../class_qwt_plot_item.html#a57d90e4146133b59d589c71b3a643e82',1,'QwtPlotItem::setZ()'],['../class_qwt_point3_d.html#ae4bed4f5b955843dcf92302b16799e8b',1,'QwtPoint3D::setZ()']]], + ['setzoombase',['setZoomBase',['../class_qwt_plot_zoomer.html#a7ee4f2a0606df6e85258c52f0b5c7bc2',1,'QwtPlotZoomer::setZoomBase(bool doReplot=true)'],['../class_qwt_plot_zoomer.html#a4376cd882cf72e1794cbbe7264ee96fb',1,'QwtPlotZoomer::setZoomBase(const QRectF &)']]], + ['setzoominkey',['setZoomInKey',['../class_qwt_magnifier.html#a004d9e770ed745bbcb5dcdb7a7ecc0a9',1,'QwtMagnifier']]], + ['setzoomoutkey',['setZoomOutKey',['../class_qwt_magnifier.html#a095a8cc622175fafc5b3cc6eb274af07',1,'QwtMagnifier']]], + ['setzoomstack',['setZoomStack',['../class_qwt_plot_zoomer.html#afc12a6e757768a71d1c74b90931bfc70',1,'QwtPlotZoomer']]], + ['shadow',['Shadow',['../class_qwt_dial.html#a7472124cb120352e8538430ab48c2386',1,'QwtDial::Shadow()'],['../class_qwt_plot_g_l_canvas.html#a6ce3b3cb6888443dfadca2399a632830',1,'QwtPlotGLCanvas::Shadow()']]], + ['shape',['shape',['../class_qwt_plot_shape_item.html#ab14eeb97e17da5ee1f458ef9c74afb20',1,'QwtPlotShapeItem::shape()'],['../class_qwt_plot_g_l_canvas.html#abb14b54c316ea3b3d39dee1dc0e78849',1,'QwtPlotGLCanvas::Shape()']]], + ['show',['show',['../class_qwt_plot_item.html#a93a50fb9c86bc66617e28315e02281c3',1,'QwtPlotItem']]], + ['shrinkfactor',['shrinkFactor',['../class_qwt_simple_compass_rose.html#a49ac7941c4a09f5a33e660b130d7bc2e',1,'QwtSimpleCompassRose']]], + ['singlestep',['singleStep',['../class_qwt_counter.html#a0057de1b365b6f18309c29c7b210cdd1',1,'QwtCounter::singleStep()'],['../class_qwt_wheel.html#a153e7629785d63a52b089c528a008578',1,'QwtWheel::singleStep()']]], + ['singlesteps',['singleSteps',['../class_qwt_abstract_slider.html#a749174444d3e63c232492edba727adfe',1,'QwtAbstractSlider']]], + ['size',['size',['../class_qwt_point_array_data.html#a2222b2ad6346dc6357a412fc50ec8f56',1,'QwtPointArrayData::size()'],['../class_qwt_c_pointer_data.html#a780b9ae434856509cef9bbe954f03a3e',1,'QwtCPointerData::size()'],['../class_qwt_synthetic_point_data.html#a61b2cc26e1b5fa4a64e29273cf3e1599',1,'QwtSyntheticPointData::size()'],['../class_qwt_series_data.html#a3cfe5b26fc55a887ac85b0103ae80a3e',1,'QwtSeriesData::size()'],['../class_qwt_array_series_data.html#a52c123dcc321a03ccd18c2c138318025',1,'QwtArraySeriesData::size()'],['../class_qwt_symbol.html#a3aba8eed9fcd85f4a4799e63543a2398',1,'QwtSymbol::size()']]], + ['sizehint',['sizeHint',['../class_qwt_arrow_button.html#a180ca16baa83c02e8dca4ffbe3dba2e8',1,'QwtArrowButton::sizeHint()'],['../class_qwt_counter.html#a9ccdfd602ccd5ecd8595172cd22b2b27',1,'QwtCounter::sizeHint()'],['../class_qwt_dial.html#a7d79a5c1cbaadb1ded9306044fa2a4a1',1,'QwtDial::sizeHint()'],['../class_qwt_dyn_grid_layout.html#afed46e3a8e1b6e67dcf62eca0bc948d6',1,'QwtDynGridLayout::sizeHint()'],['../class_qwt_knob.html#ac5f92af50fdcbf0b501f18efd07294fd',1,'QwtKnob::sizeHint()'],['../class_qwt_legend.html#a2517a7d9d78ab7a3892125ecf755f33f',1,'QwtLegend::sizeHint()'],['../class_qwt_legend_label.html#a58cf61eb9e87fe7a36266e687fe721eb',1,'QwtLegendLabel::sizeHint()'],['../class_qwt_plot.html#a8e25bdd9b085344227a7f9e218ce557c',1,'QwtPlot::sizeHint()'],['../class_qwt_scale_widget.html#a5ed815b5ac0ed7d43ab923fcd1f5da3d',1,'QwtScaleWidget::sizeHint()'],['../class_qwt_slider.html#a31c4c636f8b762e390beaf501bedcffc',1,'QwtSlider::sizeHint()'],['../class_qwt_text_label.html#a0217bc022e6f3b2f22819c84d5867ae7',1,'QwtTextLabel::sizeHint()'],['../class_qwt_thermo.html#abdb43977b3628a0b42039bef071c81cd',1,'QwtThermo::sizeHint()'],['../class_qwt_wheel.html#a77404d4e604a196bd4e809ec7d9f2076',1,'QwtWheel::sizeHint()']]], + ['sizemetrics',['sizeMetrics',['../class_qwt_graphic.html#a8996e22267dc37c9bc18dd9392ec5916',1,'QwtGraphic::sizeMetrics()'],['../class_qwt_null_paint_device.html#ab95def8c9d76d4fa6142458fd5ea4970',1,'QwtNullPaintDevice::sizeMetrics()']]], + ['sliderchange',['sliderChange',['../class_qwt_abstract_slider.html#a36ac20a000d40b2fddf5c144d1133f77',1,'QwtAbstractSlider::sliderChange()'],['../class_qwt_dial.html#a9e9e5a3aac1bc3752de8ab0a7ef71be2',1,'QwtDial::sliderChange()']]], + ['slidermoved',['sliderMoved',['../class_qwt_abstract_slider.html#ae59671d27931b545073e599a10967452',1,'QwtAbstractSlider']]], + ['sliderpressed',['sliderPressed',['../class_qwt_abstract_slider.html#afd92a0c79c113b3c5e9952d12cff80f5',1,'QwtAbstractSlider']]], + ['sliderrect',['sliderRect',['../class_qwt_slider.html#af5355e9015fc49a3d978603cb8b9bbee',1,'QwtSlider']]], + ['sliderreleased',['sliderReleased',['../class_qwt_abstract_slider.html#ab94184da7a029a5f586671251ff380ea',1,'QwtAbstractSlider']]], + ['spacing',['spacing',['../class_qwt_abstract_scale_draw.html#a93561d85e879402086f2607e45e89cc2',1,'QwtAbstractScaleDraw::spacing()'],['../class_qwt_legend_label.html#aa976458d79004b7b29ebea3cf0a069de',1,'QwtLegendLabel::spacing()'],['../class_qwt_plot_abstract_bar_chart.html#a0a2e625021bba3b9224b410281fddcf9',1,'QwtPlotAbstractBarChart::spacing()'],['../class_qwt_plot_layout.html#ae93650a8f3208578f87348334b77a282',1,'QwtPlotLayout::spacing()'],['../class_qwt_plot_legend_item.html#a4906d4e498c3b537a6354e2a1293a9c9',1,'QwtPlotLegendItem::spacing()'],['../class_qwt_plot_marker.html#ad7655fdd7089b6c8058c238f1462f298',1,'QwtPlotMarker::spacing()'],['../class_qwt_scale_widget.html#a1bdb5b6fa77a4535087f1c672ee394ce',1,'QwtScaleWidget::spacing()'],['../class_qwt_slider.html#aafa34f60f76fb7786d992cc90116e6b6',1,'QwtSlider::spacing()'],['../class_qwt_thermo.html#a16ca09c525bb05c7316ae6accb7aad79',1,'QwtThermo::spacing()']]], + ['specialsymbol',['specialSymbol',['../class_qwt_plot_bar_chart.html#a4a1e222c476d5909b7479bad4197f62b',1,'QwtPlotBarChart::specialSymbol()'],['../class_qwt_plot_multi_bar_chart.html#af94cc6845797ada8a9be828401375e39',1,'QwtPlotMultiBarChart::specialSymbol()']]], + ['spectrogram_2c_20contour_20plot',['Spectrogram, Contour Plot',['../spectrogramscreenshots.html',1,'']]], + ['spline',['spline',['../class_qwt_spline_curve_fitter.html#a7e5211e9e84df705d8bbbc7a57fbfa6d',1,'QwtSplineCurveFitter::spline() const '],['../class_qwt_spline_curve_fitter.html#ac501260a25953e1ded6bbc84c3250fa8',1,'QwtSplineCurveFitter::spline()'],['../class_qwt_spline_curve_fitter.html#a8c5e6858f885b5691c30092a950879a8a97f3e821b70470f056b60a883229ec13',1,'QwtSplineCurveFitter::Spline()']]], + ['splinesize',['splineSize',['../class_qwt_spline_curve_fitter.html#a09e5cb291c90db0aa8e6e51377bc9308',1,'QwtSplineCurveFitter']]], + ['splinetype',['splineType',['../class_qwt_spline.html#a36442cbb781422e5b97ae242265dd4b4',1,'QwtSpline::splineType() const '],['../class_qwt_spline.html#a2bd2bda128f82acd596348eb8d64231c',1,'QwtSpline::SplineType()']]], + ['stacked',['Stacked',['../class_qwt_plot_multi_bar_chart.html#ac67e03008156171c2dd19de4a46eaceeaa66475ce53f2f8b7d77687cfdf28a810',1,'QwtPlotMultiBarChart']]], + ['star1',['Star1',['../class_qwt_symbol.html#a62f457952470c2076962e83ef2c24d2fa358acf734d29ba274e9f08fa555d8bf5',1,'QwtSymbol']]], + ['star2',['Star2',['../class_qwt_symbol.html#a62f457952470c2076962e83ef2c24d2faee962f0906b5571b20737d8aee796f80',1,'QwtSymbol']]], + ['start',['start',['../class_qwt_system_clock.html#a3408bd55b49582f7847865aacc7beb37',1,'QwtSystemClock']]], + ['startborderdist',['startBorderDist',['../class_qwt_scale_widget.html#ab82bb290d685dfaec3894f5892f04ef9',1,'QwtScaleWidget']]], + ['state',['State',['../class_qwt_painter_command.html#a6619a454c4332c02412611467935b7baaecdaa394f26072749a5f2e1a41639bac',1,'QwtPainterCommand::State()'],['../class_qwt_picker_machine.html#a9060b1036ef5125968fc7030681d73c0',1,'QwtPickerMachine::state()']]], + ['statedata',['stateData',['../class_qwt_painter_command.html#ae801f205610698ebc9f704cdcedafb68',1,'QwtPainterCommand::stateData()'],['../class_qwt_painter_command.html#a12f846b9964f499a568d0b61876173ec',1,'QwtPainterCommand::stateData() const ']]], + ['statemachine',['stateMachine',['../class_qwt_picker.html#afec1e9a7c913893f49df1dccf150e0ec',1,'QwtPicker::stateMachine() const '],['../class_qwt_picker.html#afeb497069fb64ef3948f5dae605268ae',1,'QwtPicker::stateMachine()']]], + ['stepalignment',['stepAlignment',['../class_qwt_abstract_slider.html#a3c30c64a3bfc03a12131476e034e5a2c',1,'QwtAbstractSlider::stepAlignment()'],['../class_qwt_wheel.html#a3738470b6ea312ee47ba53ddfbdf355c',1,'QwtWheel::stepAlignment()']]], + ['stepbutton1',['stepButton1',['../class_qwt_counter.html#a8e0b28f111c45b3a2241fd8889bc8bce',1,'QwtCounter']]], + ['stepbutton2',['stepButton2',['../class_qwt_counter.html#a7d99de95e1c05e4994413e6d8cd641fe',1,'QwtCounter']]], + ['stepbutton3',['stepButton3',['../class_qwt_counter.html#abc6eb2073cc7d7b5f1d7e4c6c7b205c9',1,'QwtCounter']]], + ['steps',['Steps',['../class_qwt_plot_curve.html#a15998aa80a11ba6ba80eebabaf773f70a18071408a0b9bfe58378c6d81e207b2c',1,'QwtPlotCurve']]], + ['sticks',['Sticks',['../class_qwt_plot_curve.html#a15998aa80a11ba6ba80eebabaf773f70a770b0908599507e5677b6e9ff9913f38',1,'QwtPlotCurve']]], + ['stop',['stop',['../class_qwt_sampling_thread.html#ac644ff417342617a39dbd86e50d09132',1,'QwtSamplingThread']]], + ['stopflying',['stopFlying',['../class_qwt_wheel.html#af46272363dc06755e2d4c7e448664ff8',1,'QwtWheel']]], + ['stretch',['Stretch',['../class_qwt_picker.html#ab3c894deed026f392496dd07809a6fd3a86899007b306839db254d6d9712af588',1,'QwtPicker']]], + ['stretchgrid',['stretchGrid',['../class_qwt_dyn_grid_layout.html#aba94fa07d16ec2d36589b777dc853605',1,'QwtDynGridLayout']]], + ['stretchselection',['stretchSelection',['../class_qwt_picker.html#a24b0e4bcf6a9b7f41c81ea19305105a8',1,'QwtPicker']]], + ['strip',['strip',['../class_qwt_scale_engine.html#ab2b5b3c6081e1d0007f904dbc3f9f7f1',1,'QwtScaleEngine']]], + ['style',['Style',['../class_qwt_column_symbol.html#aaace508375eef3ee23ed6c47b1d65ef2',1,'QwtColumnSymbol::Style()'],['../class_qwt_dial_simple_needle.html#ad28821489e04f1fd942e5bebc8a60584',1,'QwtDialSimpleNeedle::Style()'],['../class_qwt_compass_magnet_needle.html#aee1d882c6ec8b680b94b59b5710a92a5',1,'QwtCompassMagnetNeedle::Style()'],['../class_qwt_compass_wind_arrow.html#a55f11e28c9d87c0fb7c306ccd174f2a8',1,'QwtCompassWindArrow::Style()'],['../class_qwt_interval_symbol.html#a8fe960fd50b3ad08765ef8bb632ad77e',1,'QwtIntervalSymbol::Style()'],['../class_qwt_symbol.html#a62f457952470c2076962e83ef2c24d2f',1,'QwtSymbol::Style()'],['../class_qwt_column_symbol.html#a3cf6f4e696a6df0936160d6bdb8e6b25',1,'QwtColumnSymbol::style()'],['../class_qwt_interval_symbol.html#a301b219e05ee54fd49dafd969bc4ddd7',1,'QwtIntervalSymbol::style()'],['../class_qwt_plot_curve.html#a2df43bdea2a17118c9114d6fa774e598',1,'QwtPlotCurve::style()'],['../class_qwt_plot_histogram.html#a00915a951baa4fb251f5614cb0dd8aa9',1,'QwtPlotHistogram::style()'],['../class_qwt_plot_interval_curve.html#ada1fea7fe0359c1bc175b3a2baf10c87',1,'QwtPlotIntervalCurve::style()'],['../class_qwt_plot_multi_bar_chart.html#a8420d5b608303727564539e3b08ef7cc',1,'QwtPlotMultiBarChart::style()'],['../class_qwt_symbol.html#a5e5811e1a1621e617716a2a62578b507',1,'QwtSymbol::style()']]], + ['style1',['Style1',['../class_qwt_compass_wind_arrow.html#a55f11e28c9d87c0fb7c306ccd174f2a8a62b689f03b4e974660ce1241942b09fc',1,'QwtCompassWindArrow']]], + ['style2',['Style2',['../class_qwt_compass_wind_arrow.html#a55f11e28c9d87c0fb7c306ccd174f2a8a44a462b3f0fa85bf3fa8dc421484e529',1,'QwtCompassWindArrow']]], + ['styled',['Styled',['../class_qwt_knob.html#addd00357b45752377aec83a3ab7208beaff19cfc4c98c17198e25d519c45d65ea',1,'QwtKnob']]], + ['sunken',['Sunken',['../class_qwt_dial.html#a7472124cb120352e8538430ab48c2386ae1388e8ff1a378e22cd082fcb46aa685',1,'QwtDial::Sunken()'],['../class_qwt_knob.html#addd00357b45752377aec83a3ab7208bea599810d6e366e66eaa7f662f1424e7ed',1,'QwtKnob::Sunken()'],['../class_qwt_plot_g_l_canvas.html#a6ce3b3cb6888443dfadca2399a632830ae707e3b005592b559a8093b94b08d9c0',1,'QwtPlotGLCanvas::Sunken()']]], + ['svgdocument',['SvgDocument',['../class_qwt_symbol.html#a62f457952470c2076962e83ef2c24d2fa6e9400c5e295122c0fa825d40d13bb73',1,'QwtSymbol']]], + ['swapdata',['swapData',['../class_qwt_series_store.html#a5f47997d53d580e6a12a6ca61b7225b0',1,'QwtSeriesStore']]], + ['symbol',['symbol',['../class_qwt_plot_bar_chart.html#abf3aabedfb304ef4154dec6918cb9ff7',1,'QwtPlotBarChart::symbol()'],['../class_qwt_plot_curve.html#a38e6e66301d602e80bf751f43820c080',1,'QwtPlotCurve::symbol()'],['../class_qwt_plot_histogram.html#a5815e991c891210789fef0295047f790',1,'QwtPlotHistogram::symbol()'],['../class_qwt_plot_interval_curve.html#a178654ee5b40932b06bbfcf5cb96ca7e',1,'QwtPlotIntervalCurve::symbol()'],['../class_qwt_plot_marker.html#ac3f7385b517bb8d7f0f572bfdecbc222',1,'QwtPlotMarker::symbol()'],['../class_qwt_plot_multi_bar_chart.html#a331b06acee387cd152a6ce440e7aeaca',1,'QwtPlotMultiBarChart::symbol(int barIndex) const '],['../class_qwt_plot_multi_bar_chart.html#a3e245523004a91c7a9db4c2089c3f0f6',1,'QwtPlotMultiBarChart::symbol(int barIndex)']]], + ['symbolbrush',['symbolBrush',['../class_qwt_plot_trading_curve.html#a55377e71da70b9040bc0b7a410c6aa97',1,'QwtPlotTradingCurve']]], + ['symbolextent',['symbolExtent',['../class_qwt_plot_trading_curve.html#abe2c4f7a1fd7b6643e7a4065313b0ff4',1,'QwtPlotTradingCurve']]], + ['symbolpen',['symbolPen',['../class_qwt_plot_trading_curve.html#ae317bb564cbc142899d6832a34b6d225',1,'QwtPlotTradingCurve']]], + ['symbolstyle',['symbolStyle',['../class_qwt_plot_trading_curve.html#a0b4e200a5ff4f3c05bd0be6487f8ee27',1,'QwtPlotTradingCurve::symbolStyle() const '],['../class_qwt_plot_trading_curve.html#af1ca10dd8c3f1ef662d40fc8a113b44a',1,'QwtPlotTradingCurve::SymbolStyle()']]], + ['symmetric',['Symmetric',['../class_qwt_scale_engine.html#a7548418e0896d75eec164bfa2ba3ff5fab3931d404b68708d0c6eaf87ae744fc9',1,'QwtScaleEngine']]], + ['symmetrize',['symmetrize',['../class_qwt_interval.html#a86dae3b22782b8548fd4e2c625bf1830',1,'QwtInterval']]], + ['syncscale',['syncScale',['../class_qwt_plot_rescaler.html#a1a83473ef31ff45d1595eca80c2d3b1d',1,'QwtPlotRescaler']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/all_74.html b/ThirdParty/Qwt/doc/html/search/all_74.html new file mode 100644 index 0000000000..c646aeffcd --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/all_74.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/all_74.js b/ThirdParty/Qwt/doc/html/search/all_74.js new file mode 100644 index 0000000000..49f52c62b3 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/all_74.js @@ -0,0 +1,77 @@ +var searchData= +[ + ['takeat',['takeAt',['../class_qwt_dyn_grid_layout.html#ad16c097bc1563eb1587e12789498bac9',1,'QwtDynGridLayout']]], + ['testandsetpixel',['testAndSetPixel',['../class_qwt_pixel_matrix.html#a51c2ecd161c0c93dccb62fcf640ff280',1,'QwtPixelMatrix']]], + ['testattribute',['testAttribute',['../class_qwt_plot_direct_painter.html#ad48b7706cbba44f91fb9f770e10bcc93',1,'QwtPlotDirectPainter::testAttribute()'],['../class_qwt_scale_engine.html#ab43cac5ff8843531bbb02b4401e8fb62',1,'QwtScaleEngine::testAttribute()']]], + ['testconrecflag',['testConrecFlag',['../class_qwt_plot_spectrogram.html#a00e9f22015d793458ceb36c691b1b154',1,'QwtPlotSpectrogram']]], + ['testcurveattribute',['testCurveAttribute',['../class_qwt_plot_curve.html#a0dc5e6af9ec33a1b54e3c3041c00b939',1,'QwtPlotCurve']]], + ['testdiscardflag',['testDiscardFlag',['../class_qwt_plot_renderer.html#a04fe5d9c1d81b6bfc307f8a90b4ff5c3',1,'QwtPlotRenderer']]], + ['testdisplaymode',['testDisplayMode',['../class_qwt_plot_spectrogram.html#a292ec25eb59adaedf90eef45e98f4d38',1,'QwtPlotSpectrogram']]], + ['testflag',['testFlag',['../class_qwt_point_mapper.html#acadf83f0fdb3123813b5c1eac20c3ad5',1,'QwtPointMapper']]], + ['testitemattribute',['testItemAttribute',['../class_qwt_plot_item.html#aef70936d34ef661876692e6a06d4a464',1,'QwtPlotItem']]], + ['testiteminterest',['testItemInterest',['../class_qwt_plot_item.html#a788e1dcce2faadd0bf2fd6f453ec55d0',1,'QwtPlotItem']]], + ['testlayoutattribute',['testLayoutAttribute',['../class_qwt_text.html#a5b7bddee1d80139b93d60a0a3a044944',1,'QwtText']]], + ['testlayoutflag',['testLayoutFlag',['../class_qwt_plot_renderer.html#a4e58ce0389b485c0d1014a13c2bdd0f7',1,'QwtPlotRenderer::testLayoutFlag()'],['../class_qwt_scale_widget.html#a14109672bbee79337864ae4c6525994f',1,'QwtScaleWidget::testLayoutFlag()']]], + ['testlegendattribute',['testLegendAttribute',['../class_qwt_plot_curve.html#a7ca93712e476c18995e396425e451039',1,'QwtPlotCurve']]], + ['testpaintattribute',['testPaintAttribute',['../class_qwt_plot_canvas.html#a804f78518b0ba72b11ba996fd2457fb1',1,'QwtPlotCanvas::testPaintAttribute()'],['../class_qwt_plot_curve.html#ad262cf6b8448d3cb693cbceecc6d8481',1,'QwtPlotCurve::testPaintAttribute()'],['../class_qwt_plot_interval_curve.html#ac8a923fcf205493466e1e086eecec8b7',1,'QwtPlotIntervalCurve::testPaintAttribute()'],['../class_qwt_plot_raster_item.html#a17d8f350acf46d2ba7a68df977f80a52',1,'QwtPlotRasterItem::testPaintAttribute()'],['../class_qwt_plot_shape_item.html#a0bdf30d604bc22d5279e250daa2e1542',1,'QwtPlotShapeItem::testPaintAttribute()'],['../class_qwt_plot_spectro_curve.html#abd7f7eb2830b0dfb7f6211f0b252088e',1,'QwtPlotSpectroCurve::testPaintAttribute()'],['../class_qwt_plot_trading_curve.html#a50a0f77fb107b62ce7d1a53856a01a98',1,'QwtPlotTradingCurve::testPaintAttribute()'],['../class_qwt_text.html#a53c4bcae538e272660d33bed6f71f01b',1,'QwtText::testPaintAttribute()']]], + ['testpixel',['testPixel',['../class_qwt_pixel_matrix.html#a1089a8d1da928ed35766da496a9b234e',1,'QwtPixelMatrix']]], + ['testrenderhint',['testRenderHint',['../class_qwt_graphic.html#ab0447885a89e0dd014d8e12b5924b2f1',1,'QwtGraphic::testRenderHint()'],['../class_qwt_plot_item.html#ad4009381d6a26359125549e1cf874b69',1,'QwtPlotItem::testRenderHint()']]], + ['text',['text',['../class_qwt_plot_text_label.html#ae1e2796dce184885e871a7b8981e3bac',1,'QwtPlotTextLabel::text()'],['../class_qwt_text.html#a15a42a83153f82bab8cfc283d090d736',1,'QwtText::text()'],['../class_qwt_text_label.html#a6ff4f9a87e11594740f312c8522f933e',1,'QwtTextLabel::text()']]], + ['textengine',['textEngine',['../class_qwt_text.html#a053d8fdb4de77bd3b6f2eb0ecd3980ca',1,'QwtText::textEngine(const QString &text, QwtText::TextFormat=AutoText)'],['../class_qwt_text.html#a2828c4976bd30572d236811bc30037be',1,'QwtText::textEngine(QwtText::TextFormat)']]], + ['textext',['TeXText',['../class_qwt_text.html#a63e0d6a59a427a37ed0bfa71b782fd76af31a767faf2f7e322941866c6140ddc6',1,'QwtText']]], + ['textformat',['TextFormat',['../class_qwt_text.html#a63e0d6a59a427a37ed0bfa71b782fd76',1,'QwtText']]], + ['textmargins',['textMargins',['../class_qwt_text_engine.html#a83c8d3dc590b9914e9216c01e78e0838',1,'QwtTextEngine::textMargins()'],['../class_qwt_plain_text_engine.html#ac209b74082557d3086cb3b52f99c522d',1,'QwtPlainTextEngine::textMargins()'],['../class_qwt_rich_text_engine.html#a3d507f2cad8ce44d0ee5da3070b943ca',1,'QwtRichTextEngine::textMargins()'],['../class_qwt_math_m_l_text_engine.html#ae89278f8e3642851b6357e34763008fe',1,'QwtMathMLTextEngine::textMargins()']]], + ['textpen',['textPen',['../class_qwt_plot_legend_item.html#a402f612eb053d20bea8ee94b2e6e1893',1,'QwtPlotLegendItem']]], + ['textrect',['textRect',['../class_qwt_plot_text_label.html#ac5b13cbdd6334b05ff4961494755add4',1,'QwtPlotTextLabel::textRect()'],['../class_qwt_text_label.html#ab4f9a18c47618903927fb2b40cbb06e2',1,'QwtTextLabel::textRect()']]], + ['textsize',['textSize',['../class_qwt_text.html#a62537933249b2f967b54468360d41519',1,'QwtText::textSize()'],['../class_qwt_text_engine.html#ad9382cc8ff22c6b3e448fce566a76178',1,'QwtTextEngine::textSize()'],['../class_qwt_plain_text_engine.html#a220628c0e315021a3ae9d4447bf88018',1,'QwtPlainTextEngine::textSize()'],['../class_qwt_rich_text_engine.html#a0dc185454c60931a0c136fc61774abfb',1,'QwtRichTextEngine::textSize()'],['../class_qwt_math_m_l_text_engine.html#ae2b00277f488f755a3bf7fc19548d0ec',1,'QwtMathMLTextEngine::textSize()']]], + ['thinstyle',['ThinStyle',['../class_qwt_compass_magnet_needle.html#aee1d882c6ec8b680b94b59b5710a92a5ab63a2dd26ef14c2aaf9763bc24a8bdac',1,'QwtCompassMagnetNeedle']]], + ['tick',['Tick',['../class_qwt_knob.html#a7254d94e76a74228637931fb75939b95a5ccaa93ece2f928a1167b423339826d9',1,'QwtKnob']]], + ['tickcount',['tickCount',['../class_qwt_wheel.html#ae563d5e05052756af3ef9aeb0bb3a086',1,'QwtWheel']]], + ['ticklabel',['tickLabel',['../class_qwt_abstract_scale_draw.html#a5e703dcb115a51024f89f92e61c2c8d8',1,'QwtAbstractScaleDraw']]], + ['ticklength',['tickLength',['../class_qwt_abstract_scale_draw.html#aa43034f7ad87c33e9790c730ed48c55d',1,'QwtAbstractScaleDraw']]], + ['ticks',['Ticks',['../class_qwt_abstract_scale_draw.html#a26215d06a4d48adf401d0aa05d4193c5a1f23d080ce1229a0c4f70469e88acce0',1,'QwtAbstractScaleDraw::Ticks()'],['../class_qwt_scale_div.html#ac3463fd59946cc3f71875abaaa1adf32',1,'QwtScaleDiv::ticks()']]], + ['ticktype',['TickType',['../class_qwt_scale_div.html#af21aedaa886dd5e067cf63505838736c',1,'QwtScaleDiv']]], + ['time',['time',['../class_qwt_o_h_l_c_sample.html#a7d457c0a7d71f90539bf6233a19c1df4',1,'QwtOHLCSample']]], + ['timerevent',['timerEvent',['../class_qwt_slider.html#ab42a98053119570e1fd8d68f5e2d2166',1,'QwtSlider::timerEvent()'],['../class_qwt_wheel.html#a8ca7e27c6afacdc520342f7324ecd6eb',1,'QwtWheel::timerEvent()']]], + ['timespec',['timeSpec',['../class_qwt_date_scale_draw.html#a43eaebd8bb9af3bb6a541a09f1d79014',1,'QwtDateScaleDraw::timeSpec()'],['../class_qwt_date_scale_engine.html#a28c2d2c4d1c6ac5408c6efca0f700856',1,'QwtDateScaleEngine::timeSpec()']]], + ['title',['title',['../class_qwt_legend_data.html#a23d0faa63f590c1f0c3ee7c9479410cf',1,'QwtLegendData::title()'],['../class_qwt_plot.html#a1ae4b2e10f6691b7f1a14af70f743e2c',1,'QwtPlot::title()'],['../class_qwt_plot_item.html#a3859d011b670b5f89e45d1ccef9206f7',1,'QwtPlotItem::title()'],['../class_qwt_scale_widget.html#a75ab60ac06977a6cb1991aa2e7979c2e',1,'QwtScaleWidget::title()']]], + ['titleheightforwidth',['titleHeightForWidth',['../class_qwt_scale_widget.html#a1c488b9304a8e30af20e4da1d397a72f',1,'QwtScaleWidget']]], + ['titleinverted',['TitleInverted',['../class_qwt_scale_widget.html#a95903255246c9da84e7388b567354c8fac6160b1d9f11f92db884ff26da8e2637',1,'QwtScaleWidget']]], + ['titlelabel',['titleLabel',['../class_qwt_plot.html#ac39356b86ed70ebf256a8ae964910206',1,'QwtPlot::titleLabel()'],['../class_qwt_plot.html#abea1bb53b3f08fb085a1d954eb199078',1,'QwtPlot::titleLabel() const ']]], + ['titlerect',['titleRect',['../class_qwt_plot_layout.html#af11dfb5fa14f8998f53bb5a4f83e4e11',1,'QwtPlotLayout']]], + ['todatetime',['toDateTime',['../class_qwt_date.html#a8039dc115458981fc1c7fc2c0aa8d053',1,'QwtDate::toDateTime()'],['../class_qwt_date_scale_draw.html#a50502cedfca719b9531d448f24f6ea21',1,'QwtDateScaleDraw::toDateTime()'],['../class_qwt_date_scale_engine.html#af03153128e1d166d3f808ad716b23b21',1,'QwtDateScaleEngine::toDateTime()']]], + ['todouble',['toDouble',['../class_qwt_date.html#afce10fd70f7a1ecac3f97776fb2dc46a',1,'QwtDate']]], + ['toimage',['toImage',['../class_qwt_graphic.html#a48aab63a2c421c59cf1e8d6241b68a59',1,'QwtGraphic::toImage() const '],['../class_qwt_graphic.html#a0eb6c29ac8b9b1371ea73139be7b99c3',1,'QwtGraphic::toImage(const QSize &, Qt::AspectRatioMode=Qt::IgnoreAspectRatio) const '],['../class_qwt_point_mapper.html#a68b7b12f5e5cdad135d2d4aa408b1bdd',1,'QwtPointMapper::toImage()']]], + ['tolerance',['tolerance',['../class_qwt_weeding_curve_fitter.html#aa2e69ce083d02c4da0d669a082a15187',1,'QwtWeedingCurveFitter']]], + ['topixmap',['toPixmap',['../class_qwt_graphic.html#ace94ae880be955e6a9429d6ac9fdc560',1,'QwtGraphic::toPixmap() const '],['../class_qwt_graphic.html#afc9926defd739e5c942492c623e445ce',1,'QwtGraphic::toPixmap(const QSize &, Qt::AspectRatioMode=Qt::IgnoreAspectRatio) const ']]], + ['toplegend',['TopLegend',['../class_qwt_plot.html#a31aacb65b5c049dde8c34a0d8482661ba0ee6820a1e8b56737958b738ca23ae34',1,'QwtPlot']]], + ['topoint',['toPoint',['../class_qwt_point3_d.html#a611b2608fdbe8099ae987870a10b38a6',1,'QwtPoint3D::toPoint()'],['../class_qwt_point_polar.html#ab61dd4130840876c00d79c28ea534d06',1,'QwtPointPolar::toPoint()']]], + ['topoints',['toPoints',['../class_qwt_point_mapper.html#a136350d94f21f7b7c309d3f207d283b7',1,'QwtPointMapper']]], + ['topointsf',['toPointsF',['../class_qwt_point_mapper.html#ae096ea4844f89bfaebb4806572d935a8',1,'QwtPointMapper']]], + ['topolygon',['toPolygon',['../class_qwt_point_mapper.html#a6712085a3930dd5d5cebe3fa9eabb522',1,'QwtPointMapper']]], + ['topolygonf',['toPolygonF',['../class_qwt_point_mapper.html#a63b8ce75856b3be11532fdf4bd9602a2',1,'QwtPointMapper']]], + ['topscale',['TopScale',['../class_qwt_scale_draw.html#acd7ceeeac592ef08530788580b461c66a2386da707d8f736701b8ab98f778648c',1,'QwtScaleDraw']]], + ['toptobottom',['TopToBottom',['../class_qwt_column_rect.html#a70bb2c6f1f8dabe3bc00793740e0908ba82a13d6063cc299b78ebe1a90a1f39da',1,'QwtColumnRect']]], + ['torect',['toRect',['../class_qwt_column_rect.html#a0169ba0be3e683ce5c87aacfd172095e',1,'QwtColumnRect']]], + ['tostring',['toString',['../class_qwt_date.html#a2c19998281321ba078d717f7f9ec6855',1,'QwtDate']]], + ['totalangle',['totalAngle',['../class_qwt_knob.html#a804d957c14e08bd9b132985c892ab853',1,'QwtKnob::totalAngle()'],['../class_qwt_wheel.html#ac05734986ee427e6d820f54a267dde26',1,'QwtWheel::totalAngle()']]], + ['totalsteps',['totalSteps',['../class_qwt_abstract_slider.html#aa3f22dfcf2e897c7312a5ed04834eeed',1,'QwtAbstractSlider']]], + ['trackerfont',['trackerFont',['../class_qwt_picker.html#ae87b2ac560d8795a302ee00c0ff0ab3d',1,'QwtPicker']]], + ['trackermode',['trackerMode',['../class_qwt_picker.html#a0647370ed08612d2a55742dc00f6acb7',1,'QwtPicker']]], + ['trackeroverlay',['trackerOverlay',['../class_qwt_picker.html#afeba8fa29515e673efec3684f2e878d9',1,'QwtPicker']]], + ['trackerpen',['trackerPen',['../class_qwt_picker.html#aa45bf8a52ea95bdf63e2225ec7fa8063',1,'QwtPicker']]], + ['trackerposition',['trackerPosition',['../class_qwt_picker.html#a6f95df13af38b041e422fc6f5d002354',1,'QwtPicker']]], + ['trackerrect',['trackerRect',['../class_qwt_picker.html#a3091a5812652b9fef50507ecf957160b',1,'QwtPicker']]], + ['trackertext',['trackerText',['../class_qwt_picker.html#a48ab7695edfa22df80490bf930f16cc4',1,'QwtPicker::trackerText()'],['../class_qwt_plot_picker.html#a7a85e6d7a45e5e480db670bb5f9a9b72',1,'QwtPlotPicker::trackerText()']]], + ['trackertextf',['trackerTextF',['../class_qwt_plot_picker.html#aceebd0c9f95da689a3045c3ccd23aa38',1,'QwtPlotPicker']]], + ['trailingscale',['TrailingScale',['../class_qwt_slider.html#a120d984d7c519578eed88c4fe97cb1a7a2f836c58c76f5a8ed3c905d699b3f439',1,'QwtSlider::TrailingScale()'],['../class_qwt_thermo.html#a4d7af32d29d1cc18e23b9143cf7ad498aaf66e72accc5a41142773f586158c067',1,'QwtThermo::TrailingScale()']]], + ['transform',['transform',['../class_qwt_abstract_scale.html#a59e9927b2e43f1db82af9fd1c774e36d',1,'QwtAbstractScale::transform()'],['../class_qwt_plot.html#afbeb5482d0464fd17221a22cc6ba40b3',1,'QwtPlot::transform()'],['../class_qwt_plot_picker.html#a4da9fc86484af7fc12565ad1bb6df24b',1,'QwtPlotPicker::transform(const QRectF &) const '],['../class_qwt_plot_picker.html#a800f6eb68661f26caba0ea4688e73e94',1,'QwtPlotPicker::transform(const QPointF &) const '],['../class_qwt_scale_map.html#ab77cbd649a65b080c3ff21d7abce7f73',1,'QwtScaleMap::transform(double s) const '],['../class_qwt_scale_map.html#af99eeda829142128f97e0b6c4fbf9e1f',1,'QwtScaleMap::transform(const QwtScaleMap &, const QwtScaleMap &, const QRectF &)'],['../class_qwt_scale_map.html#a6be600afa5bd75f5ff52b1f102b123b0',1,'QwtScaleMap::transform(const QwtScaleMap &, const QwtScaleMap &, const QPointF &)'],['../class_qwt_transform.html#a1093b5856cbc6cf812460535442fb130',1,'QwtTransform::transform()'],['../class_qwt_null_transform.html#abf4fa9a536049e6da78e71d5f8485b4e',1,'QwtNullTransform::transform()'],['../class_qwt_log_transform.html#ae13d9e1c7a71fd50afe2e804d2a2fb15',1,'QwtLogTransform::transform()'],['../class_qwt_power_transform.html#aad3892cb63f5981521184960e240a4f3',1,'QwtPowerTransform::transform()']]], + ['transformation',['transformation',['../class_qwt_scale_engine.html#acbc5488cb3f3e2ec9566d4797468d0d7',1,'QwtScaleEngine::transformation()'],['../class_qwt_scale_map.html#adba2c419bba77e8e099febfaa0f543e4',1,'QwtScaleMap::transformation()']]], + ['transformationflag',['TransformationFlag',['../class_qwt_point_mapper.html#aafc07ceadb3f311057037ca8680e1c23',1,'QwtPointMapper']]], + ['transformationflags',['TransformationFlags',['../class_qwt_point_mapper.html#af7a8c38f6dd7faf8396a87a882e2f967',1,'QwtPointMapper']]], + ['transition',['transition',['../class_qwt_picker.html#a90f9f3485f054c36c1835931e9a387dd',1,'QwtPicker::transition()'],['../class_qwt_picker_machine.html#acf7b57003bec437ce1ecf83e6d544968',1,'QwtPickerMachine::transition()'],['../class_qwt_picker_tracker_machine.html#a77f580a0ebcb019028db9565ca6148b9',1,'QwtPickerTrackerMachine::transition()'],['../class_qwt_picker_click_point_machine.html#a07b6da1b620dcdb304176c3f40d603df',1,'QwtPickerClickPointMachine::transition()'],['../class_qwt_picker_drag_point_machine.html#aa9e5fc73a7e828ecb1feb1305bdedc36',1,'QwtPickerDragPointMachine::transition()'],['../class_qwt_picker_click_rect_machine.html#add912362fad567108cad0a8a506aaf25',1,'QwtPickerClickRectMachine::transition()'],['../class_qwt_picker_drag_rect_machine.html#a5ff67c2ab51575ddbffe225288ff5f33',1,'QwtPickerDragRectMachine::transition()'],['../class_qwt_picker_drag_line_machine.html#a3896893cd1950d5a00eb1ce01861a24a',1,'QwtPickerDragLineMachine::transition()'],['../class_qwt_picker_polygon_machine.html#a3a5466ca9faa33603a0b6ced6aa96791',1,'QwtPickerPolygonMachine::transition()']]], + ['triangle',['Triangle',['../class_qwt_knob.html#a7254d94e76a74228637931fb75939b95a69258df5bb213fe4f7da5362470d8f85',1,'QwtKnob::Triangle()'],['../class_qwt_symbol.html#a62f457952470c2076962e83ef2c24d2fa559fad30c36d3e3e2ecad4a21122be79',1,'QwtSymbol::Triangle()']]], + ['trianglestyle',['TriangleStyle',['../class_qwt_compass_magnet_needle.html#aee1d882c6ec8b680b94b59b5710a92a5ad2ba960c4dae88e36da39f6b62798f3b',1,'QwtCompassMagnetNeedle']]], + ['tube',['Tube',['../class_qwt_plot_interval_curve.html#aaef834575b923e1b317f4a86b2d97cd2a786c87eb6dcc86d0fea802043904a647',1,'QwtPlotIntervalCurve']]], + ['type',['type',['../class_qwt_painter_command.html#a0c64c4b170b574201daa1c41366d14b7',1,'QwtPainterCommand::type() const '],['../class_qwt_painter_command.html#a6619a454c4332c02412611467935b7ba',1,'QwtPainterCommand::Type()']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/all_75.html b/ThirdParty/Qwt/doc/html/search/all_75.html new file mode 100644 index 0000000000..550133a973 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/all_75.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/all_75.js b/ThirdParty/Qwt/doc/html/search/all_75.js new file mode 100644 index 0000000000..ec99ef81a4 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/all_75.js @@ -0,0 +1,26 @@ +var searchData= +[ + ['unite',['unite',['../class_qwt_interval.html#ade8626dc4c9521e05ce7fc51cb58d730',1,'QwtInterval']]], + ['updateaxes',['updateAxes',['../class_qwt_plot.html#a1fb2dbc3697a66024d48c08b1d18f8a5',1,'QwtPlot']]], + ['updatecanvasmargins',['updateCanvasMargins',['../class_qwt_plot.html#aef8e679c64cf3158466ab33e7774f264',1,'QwtPlot']]], + ['updatedisplay',['updateDisplay',['../class_qwt_picker.html#a03aa9bf28f991473d564a57d1bf3bdcc',1,'QwtPicker']]], + ['updateinterval',['updateInterval',['../class_qwt_slider.html#a38ed0ece831bc66425159793e6f0b84e',1,'QwtSlider::updateInterval()'],['../class_qwt_wheel.html#a8294b9e8340781da463a53719cae5d23',1,'QwtWheel::updateInterval()']]], + ['updatelayout',['updateLayout',['../class_qwt_plot.html#ad470068832406086d6823109d8d7f050',1,'QwtPlot']]], + ['updatelegend',['updateLegend',['../class_qwt_abstract_legend.html#aa9fc80c9e1dcbcfef51b96a3bff268ca',1,'QwtAbstractLegend::updateLegend()'],['../class_qwt_legend.html#a0a294317170adf5c271c1ce243f66a87',1,'QwtLegend::updateLegend()'],['../class_qwt_plot.html#a9c4242c89decd06f3d35b66568ad69c9',1,'QwtPlot::updateLegend()'],['../class_qwt_plot.html#a9bb681bc692ed8f35c32174ffe98dca9',1,'QwtPlot::updateLegend(const QwtPlotItem *)'],['../class_qwt_plot_item.html#af0c4272375b1ee95a1454c4c503ff324',1,'QwtPlotItem::updateLegend()'],['../class_qwt_plot_legend_item.html#a5bfda08242671a2d9d02b7bfc558926d',1,'QwtPlotLegendItem::updateLegend()']]], + ['updateoverlay',['updateOverlay',['../class_qwt_widget_overlay.html#a231231eebaf7655f8264d2ee2b03127c',1,'QwtWidgetOverlay']]], + ['updatescalediv',['updateScaleDiv',['../class_qwt_plot_grid.html#ad15166f257160adc90b60b9e29d69edf',1,'QwtPlotGrid::updateScaleDiv()'],['../class_qwt_plot_item.html#abf6a70847d3db952161ca4d4a952eea0',1,'QwtPlotItem::updateScaleDiv()'],['../class_qwt_plot_scale_item.html#a9c32bac1ff73c6527305698792a6edfe',1,'QwtPlotScaleItem::updateScaleDiv()'],['../class_qwt_plot_series_item.html#a890792d0f44e341812b5283c249608b2',1,'QwtPlotSeriesItem::updateScaleDiv()']]], + ['updatescales',['updateScales',['../class_qwt_plot_rescaler.html#a999de79352fda2a89e32d1a8831fa5fd',1,'QwtPlotRescaler']]], + ['updatestate',['updateState',['../class_qwt_graphic.html#aa63b1055a8c8a5f6989c926c71b9e5b4',1,'QwtGraphic::updateState()'],['../class_qwt_null_paint_device.html#a235bd4e1453a13f7c4c076a9595a8840',1,'QwtNullPaintDevice::updateState()']]], + ['updatestylesheetinfo',['updateStyleSheetInfo',['../class_qwt_plot_canvas.html#a00cf0a23416a719cb8b742fca074c681',1,'QwtPlotCanvas']]], + ['updatewidget',['updateWidget',['../class_qwt_legend.html#aded18ba97822645209775c27cf6730b3',1,'QwtLegend']]], + ['upperbound',['upperBound',['../class_qwt_abstract_scale.html#a3adb3785868bcadaf9046f82d10e7bda',1,'QwtAbstractScale::upperBound()'],['../class_qwt_scale_div.html#af314ab8ccdf18dec6642c1700687b48d',1,'QwtScaleDiv::upperBound()']]], + ['uppermargin',['upperMargin',['../class_qwt_scale_engine.html#aa3fca2f37156fa3bd8ef21be8d339938',1,'QwtScaleEngine']]], + ['usedcolor',['usedColor',['../class_qwt_text.html#a1496bcc9225230c4da25ea73ba0a345a',1,'QwtText']]], + ['usedfont',['usedFont',['../class_qwt_text.html#a9769ab68a4fe26025c4172a14092f792',1,'QwtText']]], + ['usercurve',['UserCurve',['../class_qwt_plot_curve.html#a15998aa80a11ba6ba80eebabaf773f70a7d8b49e6cead1de23860e1c68d17dee3',1,'QwtPlotCurve::UserCurve()'],['../class_qwt_plot_interval_curve.html#aaef834575b923e1b317f4a86b2d97cd2a0ba2b869afe22c1213d7e34590775b0e',1,'QwtPlotIntervalCurve::UserCurve()']]], + ['userrubberband',['UserRubberBand',['../class_qwt_picker.html#ab36c79d8ff20aba5b778d2823c1f7894a96f40f8cc50bd940f0338a68ba159b8e',1,'QwtPicker']]], + ['userstyle',['UserStyle',['../class_qwt_column_symbol.html#aaace508375eef3ee23ed6c47b1d65ef2aa9a5f984f62fb53ce3eeea35be3b0536',1,'QwtColumnSymbol::UserStyle()'],['../class_qwt_plot_histogram.html#a3ba21c3aef994daf7b848ccf71b0dbc5a586b4f119cfbfe62de143c836227c06e',1,'QwtPlotHistogram::UserStyle()'],['../class_qwt_symbol.html#a62f457952470c2076962e83ef2c24d2faed4c49ccbda1c85bdc6ea399e8d8cca8',1,'QwtSymbol::UserStyle()']]], + ['usersymbol',['UserSymbol',['../class_qwt_interval_symbol.html#a8fe960fd50b3ad08765ef8bb632ad77ea40c2cb30f61f7ad63ff20482efd0e7b0',1,'QwtIntervalSymbol::UserSymbol()'],['../class_qwt_plot_trading_curve.html#af1ca10dd8c3f1ef662d40fc8a113b44aadd5f8436afcc44afe7b6204a7e1329c1',1,'QwtPlotTradingCurve::UserSymbol()']]], + ['utcoffset',['utcOffset',['../class_qwt_date.html#aeadce3496f631eae3a7e54749078c7a4',1,'QwtDate::utcOffset()'],['../class_qwt_date_scale_draw.html#a0c676fcb0e77b660afdb2b39c617a2ab',1,'QwtDateScaleDraw::utcOffset()'],['../class_qwt_date_scale_engine.html#a9a77943b8f9d36be57fdf382bd62e48d',1,'QwtDateScaleEngine::utcOffset()']]], + ['utriangle',['UTriangle',['../class_qwt_symbol.html#a62f457952470c2076962e83ef2c24d2fabf99d9afabd98be69e2ee377bbfa85bf',1,'QwtSymbol']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/all_76.html b/ThirdParty/Qwt/doc/html/search/all_76.html new file mode 100644 index 0000000000..50b86daa03 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/all_76.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/all_76.js b/ThirdParty/Qwt/doc/html/search/all_76.js new file mode 100644 index 0000000000..4f5a2dfa87 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/all_76.js @@ -0,0 +1,14 @@ +var searchData= +[ + ['value',['value',['../class_qwt_interval_sample.html#ad1e098d87833c45636dc96f9c5c14245',1,'QwtIntervalSample::value()'],['../class_qwt_set_sample.html#a5bff5286dddfa1f2070da64fe619859f',1,'QwtSetSample::value()'],['../class_qwt_abstract_slider.html#a6804d4bc124378858d4b3bcfcae6ef66',1,'QwtAbstractSlider::value()'],['../class_qwt_counter.html#a121194fadd8cea929c1ac9509f27fe58',1,'QwtCounter::value()'],['../class_qwt_legend_data.html#a73016050ce489f85018025ec5a268387',1,'QwtLegendData::value()'],['../class_qwt_matrix_raster_data.html#a49952670063166bccdbfb9cdbd7b56e8',1,'QwtMatrixRasterData::value()'],['../class_qwt_plot_marker.html#a2dd71303454a3437b064216b9f729ac7',1,'QwtPlotMarker::value()'],['../class_qwt_raster_data.html#a6396fc013fcec893b1e8cea4cf03691e',1,'QwtRasterData::value()'],['../class_qwt_spline.html#a1f67187eefe2959f0c902532edf64d41',1,'QwtSpline::value()'],['../class_qwt_thermo.html#ae359eec1e467ad86706b9cccb4e04c97',1,'QwtThermo::value()'],['../class_qwt_wheel.html#acaf83399d06bfa769d7d22f59f524d67',1,'QwtWheel::value()']]], + ['valueat',['valueAt',['../class_qwt_wheel.html#a9ab710c0fd49ed5ebe3f816ef077eb96',1,'QwtWheel']]], + ['valuechanged',['valueChanged',['../class_qwt_abstract_slider.html#a6bc5c410cd56119c6ad50743c9a46af1',1,'QwtAbstractSlider::valueChanged()'],['../class_qwt_counter.html#add02928c348417fbfadd7095d058f331',1,'QwtCounter::valueChanged()'],['../class_qwt_wheel.html#ad6551abe91933fd2230d5fee805e637a',1,'QwtWheel::valueChanged()']]], + ['valuematrix',['valueMatrix',['../class_qwt_matrix_raster_data.html#a001d575e77cf90c29ec8c5a6f8656946',1,'QwtMatrixRasterData']]], + ['values',['values',['../class_qwt_legend_data.html#aeecadb69ee0e384b34f4b39a2131924e',1,'QwtLegendData']]], + ['verticalscrollbar',['verticalScrollBar',['../class_qwt_legend.html#a494758e3d7ab688c59989da52e7e97cf',1,'QwtLegend']]], + ['viewangle',['viewAngle',['../class_qwt_wheel.html#a49c04ea6e1ec21268f63d45239bc9333',1,'QwtWheel']]], + ['viewbox',['viewBox',['../class_qwt_plot_svg_item.html#aeb813520578062494f4e604a40713ccc',1,'QwtPlotSvgItem']]], + ['vinterval',['vInterval',['../class_qwt_column_rect.html#a0dcd7826655c73da74a8f9ad87f3d62a',1,'QwtColumnRect']]], + ['vline',['VLine',['../class_qwt_plot_marker.html#a297efa835423bfa5a870bbc8ff1c623ba55ab75371699cd7c0e55c494da6454dc',1,'QwtPlotMarker::VLine()'],['../class_qwt_symbol.html#a62f457952470c2076962e83ef2c24d2fa041fb14668884dd95527a34beab22fd8',1,'QwtSymbol::VLine()']]], + ['vlinerubberband',['VLineRubberBand',['../class_qwt_picker.html#ab36c79d8ff20aba5b778d2823c1f7894a0eb6ef7b155e41ea015afc7f68940a86',1,'QwtPicker']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/all_77.html b/ThirdParty/Qwt/doc/html/search/all_77.html new file mode 100644 index 0000000000..55d7142924 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/all_77.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/all_77.js b/ThirdParty/Qwt/doc/html/search/all_77.js new file mode 100644 index 0000000000..34aa470192 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/all_77.js @@ -0,0 +1,28 @@ +var searchData= +[ + ['what_27s_20new_20in_20qwt_206_2e1',['What's new in Qwt 6.1',['../qwtchangelog.html',1,'']]], + ['weedoutpoints',['WeedOutPoints',['../class_qwt_point_mapper.html#aafc07ceadb3f311057037ca8680e1c23a288f41a8e4d53c895f7bffaaa9b5d9e4',1,'QwtPointMapper']]], + ['week',['Week',['../class_qwt_date.html#ad037b999a51cae4d9ab36bf8e7859587ae204b4e8ce8679ba9ac378e41bd77b2b',1,'QwtDate']]], + ['week0type',['week0Type',['../class_qwt_date_scale_draw.html#a1c64d18c81ff3b77449df87c014b6721',1,'QwtDateScaleDraw::week0Type()'],['../class_qwt_date_scale_engine.html#add6b4e1668ce1c45fc5d05dd612283d2',1,'QwtDateScaleEngine::week0Type()'],['../class_qwt_date.html#ab915db512c556a4666ada4fbfccfce1e',1,'QwtDate::Week0Type()']]], + ['weeknumber',['weekNumber',['../class_qwt_date.html#a90dd1f9dc38565c003f8e1ef821965b7',1,'QwtDate']]], + ['wheelborderwidth',['wheelBorderWidth',['../class_qwt_wheel.html#a76117515ddfb6c0bbd680e070dd67670',1,'QwtWheel']]], + ['wheelevent',['wheelEvent',['../class_qwt_abstract_slider.html#a7050c9ce667176e6de4c6357b5acd493',1,'QwtAbstractSlider::wheelEvent()'],['../class_qwt_counter.html#acdada1ba1d5873b9c8b3f75d63b4685a',1,'QwtCounter::wheelEvent()'],['../class_qwt_dial.html#ad35fe293f6b53f6c4ab977d6259fbf19',1,'QwtDial::wheelEvent()'],['../class_qwt_wheel.html#a1ff8fa42a64643b7fa09ea2c17164075',1,'QwtWheel::wheelEvent()']]], + ['wheelfactor',['wheelFactor',['../class_qwt_magnifier.html#a83722e9f081603a45e118947d7f810a4',1,'QwtMagnifier']]], + ['wheelmodifiers',['wheelModifiers',['../class_qwt_magnifier.html#a6a05561142ecde0c3323e64e75c72691',1,'QwtMagnifier']]], + ['wheelmoved',['wheelMoved',['../class_qwt_wheel.html#a7d0f833add72c3aceb0773825626bddf',1,'QwtWheel']]], + ['wheelpressed',['wheelPressed',['../class_qwt_wheel.html#aa9cb862f6ed4a75b007f13bbc3804ad0',1,'QwtWheel']]], + ['wheelrect',['wheelRect',['../class_qwt_wheel.html#a72891a083911e03110e1f1f60f47f064',1,'QwtWheel']]], + ['wheelreleased',['wheelReleased',['../class_qwt_wheel.html#a9ddffcbd6752571e8b1d75f2640dc6d5',1,'QwtWheel']]], + ['wheelwidth',['wheelWidth',['../class_qwt_wheel.html#ad88a4923037b4c692a5f001fb55a9549',1,'QwtWheel']]], + ['widgetenterevent',['widgetEnterEvent',['../class_qwt_picker.html#a7d3d1b97aba53a7f917013e111a5a636',1,'QwtPicker']]], + ['widgetkeypressevent',['widgetKeyPressEvent',['../class_qwt_magnifier.html#a382cec084a2bfc0610ca500121205f04',1,'QwtMagnifier::widgetKeyPressEvent()'],['../class_qwt_panner.html#a7ed4e89f6c52b841e20ad497af4b4ebc',1,'QwtPanner::widgetKeyPressEvent()'],['../class_qwt_picker.html#af5bc441b2fc143363563922a3b3c70ae',1,'QwtPicker::widgetKeyPressEvent()'],['../class_qwt_plot_zoomer.html#aa44e42dcf37547a6b93d04a593f140c6',1,'QwtPlotZoomer::widgetKeyPressEvent()']]], + ['widgetkeyreleaseevent',['widgetKeyReleaseEvent',['../class_qwt_magnifier.html#af84037c68c9b88263d1c27bb648cf9ff',1,'QwtMagnifier::widgetKeyReleaseEvent()'],['../class_qwt_panner.html#a8bd447df4a30299bbc8e6b6d3e2e2f9f',1,'QwtPanner::widgetKeyReleaseEvent()'],['../class_qwt_picker.html#a9f2c739a619be794b22a10ede9674a1e',1,'QwtPicker::widgetKeyReleaseEvent()']]], + ['widgetleaveevent',['widgetLeaveEvent',['../class_qwt_picker.html#a8a2a18f2b98c8524b1d3684df44c24aa',1,'QwtPicker']]], + ['widgetmousedoubleclickevent',['widgetMouseDoubleClickEvent',['../class_qwt_picker.html#af1ffb07c24be57cd4a753b04412b3212',1,'QwtPicker']]], + ['widgetmousemoveevent',['widgetMouseMoveEvent',['../class_qwt_magnifier.html#a4eb68b98b063cc14b7839f02f8671dfc',1,'QwtMagnifier::widgetMouseMoveEvent()'],['../class_qwt_panner.html#a6545bc6e25018253c59fc27a48eb948f',1,'QwtPanner::widgetMouseMoveEvent()'],['../class_qwt_picker.html#a88b203109a4d3b26c2e0bee110c56c9d',1,'QwtPicker::widgetMouseMoveEvent()']]], + ['widgetmousepressevent',['widgetMousePressEvent',['../class_qwt_magnifier.html#a5930b3ec00ae99883f36cf8bf568cbf7',1,'QwtMagnifier::widgetMousePressEvent()'],['../class_qwt_panner.html#ae002958978dcc751f9edda24e5858dd9',1,'QwtPanner::widgetMousePressEvent()'],['../class_qwt_picker.html#a4bfae8da37c3936ae73d4798cca4a3d9',1,'QwtPicker::widgetMousePressEvent()']]], + ['widgetmousereleaseevent',['widgetMouseReleaseEvent',['../class_qwt_magnifier.html#aa7cc31995444ca8dd8412b8a6dab7b93',1,'QwtMagnifier::widgetMouseReleaseEvent()'],['../class_qwt_panner.html#ab2da1e24b1456b223eaa826d8e0a3a81',1,'QwtPanner::widgetMouseReleaseEvent()'],['../class_qwt_picker.html#ac009633e005b6290e07b902f2a58e45e',1,'QwtPicker::widgetMouseReleaseEvent()'],['../class_qwt_plot_zoomer.html#aabded662ecb3555b3a29cf3daacf79de',1,'QwtPlotZoomer::widgetMouseReleaseEvent()']]], + ['widgetwheelevent',['widgetWheelEvent',['../class_qwt_magnifier.html#a236762870830cc0621411c173472392b',1,'QwtMagnifier::widgetWheelEvent()'],['../class_qwt_picker.html#af92ffabe291a6254378dc932c5cce0a7',1,'QwtPicker::widgetWheelEvent()']]], + ['width',['width',['../class_qwt_simple_compass_rose.html#a28e7dcd6574c6239f5d15cdda93ac835',1,'QwtSimpleCompassRose::width()'],['../class_qwt_dial_simple_needle.html#af7c8d5ed409364e4e67b7e40f1c0cfe2',1,'QwtDialSimpleNeedle::width()'],['../class_qwt_interval.html#a7cded184fdbb9e30756f422ceca7522e',1,'QwtInterval::width()'],['../class_qwt_interval_symbol.html#a7f0bb9488778d9054932a5c072daecdc',1,'QwtIntervalSymbol::width()']]], + ['wrapping',['wrapping',['../class_qwt_abstract_slider.html#a829f90f6e4b7852da72d6e3f4137b041',1,'QwtAbstractSlider::wrapping()'],['../class_qwt_counter.html#a22d4cd0baab3b0b56340bb409b92b672',1,'QwtCounter::wrapping()'],['../class_qwt_wheel.html#a6da22b8a5457c1c228073edc24ffbf0e',1,'QwtWheel::wrapping()']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/all_78.html b/ThirdParty/Qwt/doc/html/search/all_78.html new file mode 100644 index 0000000000..39075d44eb --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/all_78.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/all_78.js b/ThirdParty/Qwt/doc/html/search/all_78.js new file mode 100644 index 0000000000..98654c51f5 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/all_78.js @@ -0,0 +1,13 @@ +var searchData= +[ + ['x',['x',['../class_qwt_point3_d.html#a055a9d12fbdc279452ee6c056bd3ba8f',1,'QwtPoint3D::x()'],['../class_qwt_synthetic_point_data.html#ab14ef450ef097f05dbb8b8d75202538b',1,'QwtSyntheticPointData::x()']]], + ['xaxis',['xAxis',['../class_qwt_plot_item.html#a7af360bf6d5a5b6257ce6b0dd99b7525',1,'QwtPlotItem::xAxis()'],['../class_qwt_plot_picker.html#a9cdd6d56e990173a00c6c81edbe8818d',1,'QwtPlotPicker::xAxis()']]], + ['xbottom',['xBottom',['../class_qwt_plot.html#a81df699dcf9dde0752c0726b5f31e271ad5566960e78f2473c1a1e853def4c4ac',1,'QwtPlot']]], + ['xcross',['XCross',['../class_qwt_symbol.html#a62f457952470c2076962e83ef2c24d2faa734e8b9433131230af5d8c319b5529e',1,'QwtSymbol']]], + ['xdata',['xData',['../class_qwt_point_array_data.html#a94db4f8c1d2a4495f22144d03255bc2d',1,'QwtPointArrayData::xData()'],['../class_qwt_c_pointer_data.html#a6409b0bcf77674d1970185c6c3245e26',1,'QwtCPointerData::xData()']]], + ['xenabled',['xEnabled',['../class_qwt_plot_grid.html#a46d19c58295d538518586374efadd34c',1,'QwtPlotGrid']]], + ['xminenabled',['xMinEnabled',['../class_qwt_plot_grid.html#a2eeb5b2118f35409cb1450c2a032e8ff',1,'QwtPlotGrid']]], + ['xscalediv',['xScaleDiv',['../class_qwt_plot_grid.html#a4de2f1d11d5b24c0790db1e3dd0b3436',1,'QwtPlotGrid']]], + ['xtop',['xTop',['../class_qwt_plot.html#a81df699dcf9dde0752c0726b5f31e271ae51eb7525eb3f9f806e659614018beb8',1,'QwtPlot']]], + ['xvalue',['xValue',['../class_qwt_plot_marker.html#aad43f527f3c0033865fea5a488ef3857',1,'QwtPlotMarker']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/all_79.html b/ThirdParty/Qwt/doc/html/search/all_79.html new file mode 100644 index 0000000000..033719a1b3 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/all_79.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/all_79.js b/ThirdParty/Qwt/doc/html/search/all_79.js new file mode 100644 index 0000000000..22e119c36f --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/all_79.js @@ -0,0 +1,13 @@ +var searchData= +[ + ['y',['y',['../class_qwt_point3_d.html#ac2c90240ee705f3422202aeb6d5e0654',1,'QwtPoint3D::y()'],['../class_qwt_synthetic_point_data.html#af65186bea0056b3f7f46814c61d68c99',1,'QwtSyntheticPointData::y()']]], + ['yaxis',['yAxis',['../class_qwt_plot_item.html#ac7714ffa278a10e0cf45972e487b63ff',1,'QwtPlotItem::yAxis()'],['../class_qwt_plot_picker.html#a3068fb734845abfdf5dff00ead18377f',1,'QwtPlotPicker::yAxis()']]], + ['ydata',['yData',['../class_qwt_point_array_data.html#ac7fcf7f7dfa58298bb165142d81d03f2',1,'QwtPointArrayData::yData()'],['../class_qwt_c_pointer_data.html#a7c538ed7b3e4cc5db6d4d97c09ed9d73',1,'QwtCPointerData::yData()']]], + ['year',['Year',['../class_qwt_date.html#ad037b999a51cae4d9ab36bf8e7859587ae306523ed94ccf930afb811ff7a735ab',1,'QwtDate']]], + ['yenabled',['yEnabled',['../class_qwt_plot_grid.html#ad0f38876f49c5197e929ab80e389dbb5',1,'QwtPlotGrid']]], + ['yleft',['yLeft',['../class_qwt_plot.html#a81df699dcf9dde0752c0726b5f31e271a1bb1fbc11e31ebfa8bf72356f6837b17',1,'QwtPlot']]], + ['yminenabled',['yMinEnabled',['../class_qwt_plot_grid.html#af677551f6121de684888af6e2b77333f',1,'QwtPlotGrid']]], + ['yright',['yRight',['../class_qwt_plot.html#a81df699dcf9dde0752c0726b5f31e271a1de23b30c6b0c08aefe06d6265b65155',1,'QwtPlot']]], + ['yscalediv',['yScaleDiv',['../class_qwt_plot_grid.html#a0da37b84786570c1ecff37ac18c6684c',1,'QwtPlotGrid']]], + ['yvalue',['yValue',['../class_qwt_plot_marker.html#a30ec999a3e4eba759d4c405fa92f9563',1,'QwtPlotMarker']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/all_7a.html b/ThirdParty/Qwt/doc/html/search/all_7a.html new file mode 100644 index 0000000000..5d99ff7618 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/all_7a.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/all_7a.js b/ThirdParty/Qwt/doc/html/search/all_7a.js new file mode 100644 index 0000000000..77f54afbd5 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/all_7a.js @@ -0,0 +1,10 @@ +var searchData= +[ + ['z',['z',['../class_qwt_plot_item.html#a4c58d814336643190b9f2918f80c30df',1,'QwtPlotItem::z()'],['../class_qwt_point3_d.html#afd56ba68ce1cfad4a4e477f45f0c85d4',1,'QwtPoint3D::z()']]], + ['zoom',['zoom',['../class_qwt_plot_zoomer.html#afe9f123f263536b620d1a9061d5705c6',1,'QwtPlotZoomer::zoom(const QRectF &)'],['../class_qwt_plot_zoomer.html#a0cee73f15c5791553cb52c4e7b3e881e',1,'QwtPlotZoomer::zoom(int up)']]], + ['zoombase',['zoomBase',['../class_qwt_plot_zoomer.html#ab0edba67626ca0c6c0632b38b1f67921',1,'QwtPlotZoomer']]], + ['zoomed',['zoomed',['../class_qwt_plot_zoomer.html#af5d312de34b493b59e48f03850478648',1,'QwtPlotZoomer']]], + ['zoomrect',['zoomRect',['../class_qwt_plot_zoomer.html#a91a2d1f0609666322dd955d3366cfbf0',1,'QwtPlotZoomer']]], + ['zoomrectindex',['zoomRectIndex',['../class_qwt_plot_zoomer.html#a63797aa3b9e540a2c5f539fa34a05fbc',1,'QwtPlotZoomer']]], + ['zoomstack',['zoomStack',['../class_qwt_plot_zoomer.html#a3fd87611a5b3b263f26800b1008985ec',1,'QwtPlotZoomer']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/all_7e.html b/ThirdParty/Qwt/doc/html/search/all_7e.html new file mode 100644 index 0000000000..71f33b19d6 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/all_7e.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/all_7e.js b/ThirdParty/Qwt/doc/html/search/all_7e.js new file mode 100644 index 0000000000..7cf6bc48ad --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/all_7e.js @@ -0,0 +1,100 @@ +var searchData= +[ + ['_7eqwtabstractlegend',['~QwtAbstractLegend',['../class_qwt_abstract_legend.html#a6d86d9c50679dea9fefafc457fc70814',1,'QwtAbstractLegend']]], + ['_7eqwtabstractscale',['~QwtAbstractScale',['../class_qwt_abstract_scale.html#a73890593efff11427ea7a42a3ebadefd',1,'QwtAbstractScale']]], + ['_7eqwtabstractscaledraw',['~QwtAbstractScaleDraw',['../class_qwt_abstract_scale_draw.html#adc4d3f491b28ee39d728a4a4a9cdd494',1,'QwtAbstractScaleDraw']]], + ['_7eqwtabstractseriesstore',['~QwtAbstractSeriesStore',['../class_qwt_abstract_series_store.html#a3990acd8aba251e46d8c64d2154e3f72',1,'QwtAbstractSeriesStore']]], + ['_7eqwtabstractslider',['~QwtAbstractSlider',['../class_qwt_abstract_slider.html#a31b9e0314988b7d547c9ded625014bbb',1,'QwtAbstractSlider']]], + ['_7eqwtalphacolormap',['~QwtAlphaColorMap',['../class_qwt_alpha_color_map.html#ac6445d25b9df0b565383b8189691bbad',1,'QwtAlphaColorMap']]], + ['_7eqwtanalogclock',['~QwtAnalogClock',['../class_qwt_analog_clock.html#a3abdcecf88e3d3510d94e96e7e9e74ee',1,'QwtAnalogClock']]], + ['_7eqwtarrowbutton',['~QwtArrowButton',['../class_qwt_arrow_button.html#a506ab071fa7ee92928ace7dcea774a73',1,'QwtArrowButton']]], + ['_7eqwtcolormap',['~QwtColorMap',['../class_qwt_color_map.html#af20e4ffdb3c5d34f5a6dc301bcbb9f7e',1,'QwtColorMap']]], + ['_7eqwtcolumnsymbol',['~QwtColumnSymbol',['../class_qwt_column_symbol.html#a4ca8a7cb15c23be659f3bdcdb50ae20c',1,'QwtColumnSymbol']]], + ['_7eqwtcompass',['~QwtCompass',['../class_qwt_compass.html#af6cc3b946f3761f7ce53d3a2ec000817',1,'QwtCompass']]], + ['_7eqwtcompassrose',['~QwtCompassRose',['../class_qwt_compass_rose.html#a9e3e5086d7225152cad3a276096753be',1,'QwtCompassRose']]], + ['_7eqwtcounter',['~QwtCounter',['../class_qwt_counter.html#a6469133eb210b470023a3dcc735aec4d',1,'QwtCounter']]], + ['_7eqwtcurvefitter',['~QwtCurveFitter',['../class_qwt_curve_fitter.html#a62919f309f0441d94adea94573d0f778',1,'QwtCurveFitter']]], + ['_7eqwtdatescaledraw',['~QwtDateScaleDraw',['../class_qwt_date_scale_draw.html#af32e43b35fbc805400f907a5e1466b83',1,'QwtDateScaleDraw']]], + ['_7eqwtdatescaleengine',['~QwtDateScaleEngine',['../class_qwt_date_scale_engine.html#a1e1d01f5ac297bcdb1458a35bcd8d554',1,'QwtDateScaleEngine']]], + ['_7eqwtdial',['~QwtDial',['../class_qwt_dial.html#a16cd1e45a78890c6c5f6e9c07b0180c7',1,'QwtDial']]], + ['_7eqwtdialneedle',['~QwtDialNeedle',['../class_qwt_dial_needle.html#ac23b2af4af50042967c8cea87b474247',1,'QwtDialNeedle']]], + ['_7eqwtdyngridlayout',['~QwtDynGridLayout',['../class_qwt_dyn_grid_layout.html#abb583f302fbf5d92b306841d414e52a4',1,'QwtDynGridLayout']]], + ['_7eqwteventpattern',['~QwtEventPattern',['../class_qwt_event_pattern.html#a3f8c2a2cca991000bafefd924b47895d',1,'QwtEventPattern']]], + ['_7eqwtgraphic',['~QwtGraphic',['../class_qwt_graphic.html#a1be9e3400a8d094cdf2deb1ff3eb9d65',1,'QwtGraphic']]], + ['_7eqwtintervalsymbol',['~QwtIntervalSymbol',['../class_qwt_interval_symbol.html#ac983feda2d6417a24e430aa0cd0548b9',1,'QwtIntervalSymbol']]], + ['_7eqwtknob',['~QwtKnob',['../class_qwt_knob.html#a13f3e622b333c9918bc61844029f8a70',1,'QwtKnob']]], + ['_7eqwtlegend',['~QwtLegend',['../class_qwt_legend.html#a2dd3bc628652909b74e7ddb5db021ea5',1,'QwtLegend']]], + ['_7eqwtlegenddata',['~QwtLegendData',['../class_qwt_legend_data.html#a56608cc97875e7b3dd9340decd5231cb',1,'QwtLegendData']]], + ['_7eqwtlegendlabel',['~QwtLegendLabel',['../class_qwt_legend_label.html#ad9f7483fa0625a28aba97cca8c3167b7',1,'QwtLegendLabel']]], + ['_7eqwtlinearcolormap',['~QwtLinearColorMap',['../class_qwt_linear_color_map.html#a82caa759e44d439aa9866bd03e2e3696',1,'QwtLinearColorMap']]], + ['_7eqwtlinearscaleengine',['~QwtLinearScaleEngine',['../class_qwt_linear_scale_engine.html#aa9e543118c60aa04f68123030821fedd',1,'QwtLinearScaleEngine']]], + ['_7eqwtlogscaleengine',['~QwtLogScaleEngine',['../class_qwt_log_scale_engine.html#ad749149c492c7105fb6e5518abd323c9',1,'QwtLogScaleEngine']]], + ['_7eqwtlogtransform',['~QwtLogTransform',['../class_qwt_log_transform.html#a39296a96bd30f5ea8f22cb79456c23f0',1,'QwtLogTransform']]], + ['_7eqwtmagnifier',['~QwtMagnifier',['../class_qwt_magnifier.html#ac18a7858407951a335399ee6969a50da',1,'QwtMagnifier']]], + ['_7eqwtmathmltextengine',['~QwtMathMLTextEngine',['../class_qwt_math_m_l_text_engine.html#a864d4265a7621e7389b21d419e6503ff',1,'QwtMathMLTextEngine']]], + ['_7eqwtmatrixrasterdata',['~QwtMatrixRasterData',['../class_qwt_matrix_raster_data.html#a15284284966f25383fe67f2e278f4869',1,'QwtMatrixRasterData']]], + ['_7eqwtnullpaintdevice',['~QwtNullPaintDevice',['../class_qwt_null_paint_device.html#a050e40b6efff32a616f3e8326f4fd632',1,'QwtNullPaintDevice']]], + ['_7eqwtnulltransform',['~QwtNullTransform',['../class_qwt_null_transform.html#aa2ee005d43d2532e3312eb50dd873f0a',1,'QwtNullTransform']]], + ['_7eqwtpaintercommand',['~QwtPainterCommand',['../class_qwt_painter_command.html#af2b2cc7b6d5ce371b3d2456c231f846e',1,'QwtPainterCommand']]], + ['_7eqwtpanner',['~QwtPanner',['../class_qwt_panner.html#a19c9b9a08da05649f6d2ef5bf6fb391c',1,'QwtPanner']]], + ['_7eqwtpicker',['~QwtPicker',['../class_qwt_picker.html#a5d0906a0d3b12e0e44499f855cb9dab1',1,'QwtPicker']]], + ['_7eqwtpickermachine',['~QwtPickerMachine',['../class_qwt_picker_machine.html#aa1164dfb8ae6ac62fb3b6cb19efcb3e5',1,'QwtPickerMachine']]], + ['_7eqwtpixelmatrix',['~QwtPixelMatrix',['../class_qwt_pixel_matrix.html#a6691629e198fb39e6f653038cfb74f6b',1,'QwtPixelMatrix']]], + ['_7eqwtplaintextengine',['~QwtPlainTextEngine',['../class_qwt_plain_text_engine.html#a0ada8796b2caaff7bb8d61e9fb1b5143',1,'QwtPlainTextEngine']]], + ['_7eqwtplot',['~QwtPlot',['../class_qwt_plot.html#a2b60620e3681810946dcc66002aad016',1,'QwtPlot']]], + ['_7eqwtplotabstractbarchart',['~QwtPlotAbstractBarChart',['../class_qwt_plot_abstract_bar_chart.html#a80176eb6c7f95c5f5b9b90e595e1fdcd',1,'QwtPlotAbstractBarChart']]], + ['_7eqwtplotbarchart',['~QwtPlotBarChart',['../class_qwt_plot_bar_chart.html#ad09883b49e09cee21bb9d21cd7425271',1,'QwtPlotBarChart']]], + ['_7eqwtplotcanvas',['~QwtPlotCanvas',['../class_qwt_plot_canvas.html#a320320bbb1b511c0c37fb2452a7f4404',1,'QwtPlotCanvas']]], + ['_7eqwtplotcurve',['~QwtPlotCurve',['../class_qwt_plot_curve.html#aa05ec6d3883821a8e62330fbeeb85dbd',1,'QwtPlotCurve']]], + ['_7eqwtplotdict',['~QwtPlotDict',['../class_qwt_plot_dict.html#a9199acfe3e8dcb095065bff3f90f518b',1,'QwtPlotDict']]], + ['_7eqwtplotdirectpainter',['~QwtPlotDirectPainter',['../class_qwt_plot_direct_painter.html#aab96bfd08e9041c2552210bbd3ee5ad0',1,'QwtPlotDirectPainter']]], + ['_7eqwtplotglcanvas',['~QwtPlotGLCanvas',['../class_qwt_plot_g_l_canvas.html#a330939a56e289c42bcfbee2d82ef8347',1,'QwtPlotGLCanvas']]], + ['_7eqwtplotgrid',['~QwtPlotGrid',['../class_qwt_plot_grid.html#af39443cd91b8a96a797af1d6b78bfab3',1,'QwtPlotGrid']]], + ['_7eqwtplothistogram',['~QwtPlotHistogram',['../class_qwt_plot_histogram.html#a64bf6dad5655ef1ef3a0a1507d2feafb',1,'QwtPlotHistogram']]], + ['_7eqwtplotintervalcurve',['~QwtPlotIntervalCurve',['../class_qwt_plot_interval_curve.html#a1b04a9a4e327b8e33de2c02cf89fa574',1,'QwtPlotIntervalCurve']]], + ['_7eqwtplotitem',['~QwtPlotItem',['../class_qwt_plot_item.html#a282a1d0424a06737f80e1fe83ccf7a0c',1,'QwtPlotItem']]], + ['_7eqwtplotlayout',['~QwtPlotLayout',['../class_qwt_plot_layout.html#a39653485c638535bc11f50d2e5ef936d',1,'QwtPlotLayout']]], + ['_7eqwtplotlegenditem',['~QwtPlotLegendItem',['../class_qwt_plot_legend_item.html#adae55c1a6f185acc37a70df9008d4624',1,'QwtPlotLegendItem']]], + ['_7eqwtplotmagnifier',['~QwtPlotMagnifier',['../class_qwt_plot_magnifier.html#a38c0508241885ea49542cc0f11c740df',1,'QwtPlotMagnifier']]], + ['_7eqwtplotmarker',['~QwtPlotMarker',['../class_qwt_plot_marker.html#a920d2ddeb2041c03790d7c173e3ad0cf',1,'QwtPlotMarker']]], + ['_7eqwtplotmultibarchart',['~QwtPlotMultiBarChart',['../class_qwt_plot_multi_bar_chart.html#a171ad297d47ba4d4b74755a55af6db94',1,'QwtPlotMultiBarChart']]], + ['_7eqwtplotpanner',['~QwtPlotPanner',['../class_qwt_plot_panner.html#aa72bb8323d5a8eb46900f978bf1e3623',1,'QwtPlotPanner']]], + ['_7eqwtplotpicker',['~QwtPlotPicker',['../class_qwt_plot_picker.html#a0a13f683558c0e3bdb796a3b508be159',1,'QwtPlotPicker']]], + ['_7eqwtplotrasteritem',['~QwtPlotRasterItem',['../class_qwt_plot_raster_item.html#a2715233827c346ab15504dc75d6e9714',1,'QwtPlotRasterItem']]], + ['_7eqwtplotrenderer',['~QwtPlotRenderer',['../class_qwt_plot_renderer.html#a572bea1c8400ba75c01d0bb8bdf391c3',1,'QwtPlotRenderer']]], + ['_7eqwtplotrescaler',['~QwtPlotRescaler',['../class_qwt_plot_rescaler.html#ae34a0dbae9074c211f36c765142d8ddd',1,'QwtPlotRescaler']]], + ['_7eqwtplotscaleitem',['~QwtPlotScaleItem',['../class_qwt_plot_scale_item.html#a8f246e1e73704c1c40ae1294269b65fa',1,'QwtPlotScaleItem']]], + ['_7eqwtplotseriesitem',['~QwtPlotSeriesItem',['../class_qwt_plot_series_item.html#aa4ef832ea5b6c65c9538943794702bc5',1,'QwtPlotSeriesItem']]], + ['_7eqwtplotshapeitem',['~QwtPlotShapeItem',['../class_qwt_plot_shape_item.html#accacacbcdbf558ad3dfcba462bf2b0c3',1,'QwtPlotShapeItem']]], + ['_7eqwtplotspectrocurve',['~QwtPlotSpectroCurve',['../class_qwt_plot_spectro_curve.html#a8246490aaa9d47e77f5596f56fb073d6',1,'QwtPlotSpectroCurve']]], + ['_7eqwtplotspectrogram',['~QwtPlotSpectrogram',['../class_qwt_plot_spectrogram.html#ae76415d290cf4a512d07a17260b7a84a',1,'QwtPlotSpectrogram']]], + ['_7eqwtplotsvgitem',['~QwtPlotSvgItem',['../class_qwt_plot_svg_item.html#a4509baf861772124c71abd1b6514b319',1,'QwtPlotSvgItem']]], + ['_7eqwtplottextlabel',['~QwtPlotTextLabel',['../class_qwt_plot_text_label.html#a20e024910ca49b8fd7326cbfca77df22',1,'QwtPlotTextLabel']]], + ['_7eqwtplottradingcurve',['~QwtPlotTradingCurve',['../class_qwt_plot_trading_curve.html#a93a040562cf897355196f127c7231194',1,'QwtPlotTradingCurve']]], + ['_7eqwtplotzoneitem',['~QwtPlotZoneItem',['../class_qwt_plot_zone_item.html#a696327e3e806dd2cada33b8e2d4f18f8',1,'QwtPlotZoneItem']]], + ['_7eqwtpointmapper',['~QwtPointMapper',['../class_qwt_point_mapper.html#aabe6a70dae5784e8b67f4527c51e0c09',1,'QwtPointMapper']]], + ['_7eqwtpowertransform',['~QwtPowerTransform',['../class_qwt_power_transform.html#a33a82c2e0a67e7463646e7dbb64ccff1',1,'QwtPowerTransform']]], + ['_7eqwtrasterdata',['~QwtRasterData',['../class_qwt_raster_data.html#a95b24c7cad42c5f7947e64e990def3e8',1,'QwtRasterData']]], + ['_7eqwtroundscaledraw',['~QwtRoundScaleDraw',['../class_qwt_round_scale_draw.html#a81583432e629cd8a14524b05fabb4731',1,'QwtRoundScaleDraw']]], + ['_7eqwtsamplingthread',['~QwtSamplingThread',['../class_qwt_sampling_thread.html#a7a0b4d5c172f2ded5f6b6483c6ab56e5',1,'QwtSamplingThread']]], + ['_7eqwtscaledraw',['~QwtScaleDraw',['../class_qwt_scale_draw.html#a9c907c8fa27ec7312e78145e3050c599',1,'QwtScaleDraw']]], + ['_7eqwtscaleengine',['~QwtScaleEngine',['../class_qwt_scale_engine.html#ab9c21b4550d44d9a82c1865864cb8943',1,'QwtScaleEngine']]], + ['_7eqwtscalemap',['~QwtScaleMap',['../class_qwt_scale_map.html#aecafd09423984a5e0ffa935d1b45110c',1,'QwtScaleMap']]], + ['_7eqwtscalewidget',['~QwtScaleWidget',['../class_qwt_scale_widget.html#a84213c50912000db319b2c7d704f9a33',1,'QwtScaleWidget']]], + ['_7eqwtseriesdata',['~QwtSeriesData',['../class_qwt_series_data.html#a841a56f909879d599a385b9c3d046745',1,'QwtSeriesData']]], + ['_7eqwtseriesstore',['~QwtSeriesStore',['../class_qwt_series_store.html#ae500a3787e77e16d096f4e6c1d292101',1,'QwtSeriesStore']]], + ['_7eqwtsimplecompassrose',['~QwtSimpleCompassRose',['../class_qwt_simple_compass_rose.html#a157304c9a535126d33a80df9a9dad292',1,'QwtSimpleCompassRose']]], + ['_7eqwtslider',['~QwtSlider',['../class_qwt_slider.html#a1d82f2f616f8cd3cc7c265948d1b7886',1,'QwtSlider']]], + ['_7eqwtspline',['~QwtSpline',['../class_qwt_spline.html#a90805882826469c94fdc871f18261bb6',1,'QwtSpline']]], + ['_7eqwtsplinecurvefitter',['~QwtSplineCurveFitter',['../class_qwt_spline_curve_fitter.html#a933ecbf859698978104d0dd4ec2a2f6a',1,'QwtSplineCurveFitter']]], + ['_7eqwtsymbol',['~QwtSymbol',['../class_qwt_symbol.html#a5a30269273545d5ed25f7116a421eda2',1,'QwtSymbol']]], + ['_7eqwtsystemclock',['~QwtSystemClock',['../class_qwt_system_clock.html#a79a46a34a317543a08a8424a333b9ee3',1,'QwtSystemClock']]], + ['_7eqwttext',['~QwtText',['../class_qwt_text.html#aba243ac11b91979ad3f2ee7d3c700195',1,'QwtText']]], + ['_7eqwttextengine',['~QwtTextEngine',['../class_qwt_text_engine.html#adda9e23494429c54b3cc3452940fb2bc',1,'QwtTextEngine']]], + ['_7eqwttextlabel',['~QwtTextLabel',['../class_qwt_text_label.html#adf8f363200c527a6af4259647304be5a',1,'QwtTextLabel']]], + ['_7eqwtthermo',['~QwtThermo',['../class_qwt_thermo.html#ad0e2bd43eae2402ade490a5e6c4ef4ae',1,'QwtThermo']]], + ['_7eqwttransform',['~QwtTransform',['../class_qwt_transform.html#aa2653db3104e672464dc569592fc14ab',1,'QwtTransform']]], + ['_7eqwtweedingcurvefitter',['~QwtWeedingCurveFitter',['../class_qwt_weeding_curve_fitter.html#abbd30a948fc6974f881678f80a29768c',1,'QwtWeedingCurveFitter']]], + ['_7eqwtwheel',['~QwtWheel',['../class_qwt_wheel.html#a57f465a31a9d2d88cb7a1d0e6391535e',1,'QwtWheel']]], + ['_7eqwtwidgetoverlay',['~QwtWidgetOverlay',['../class_qwt_widget_overlay.html#af234383cb42288746b970fb3fa18395d',1,'QwtWidgetOverlay']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/classes_6b.html b/ThirdParty/Qwt/doc/html/search/classes_6b.html new file mode 100644 index 0000000000..039fdc0ded --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/classes_6b.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/classes_6b.js b/ThirdParty/Qwt/doc/html/search/classes_6b.js new file mode 100644 index 0000000000..c3ca1aac71 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/classes_6b.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['keypattern',['KeyPattern',['../class_qwt_event_pattern_1_1_key_pattern.html',1,'QwtEventPattern']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/classes_6d.html b/ThirdParty/Qwt/doc/html/search/classes_6d.html new file mode 100644 index 0000000000..12b1c839ae --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/classes_6d.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/classes_6d.js b/ThirdParty/Qwt/doc/html/search/classes_6d.js new file mode 100644 index 0000000000..83e9f20f0a --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/classes_6d.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['mousepattern',['MousePattern',['../class_qwt_event_pattern_1_1_mouse_pattern.html',1,'QwtEventPattern']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/classes_71.html b/ThirdParty/Qwt/doc/html/search/classes_71.html new file mode 100644 index 0000000000..d03fedd226 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/classes_71.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/classes_71.js b/ThirdParty/Qwt/doc/html/search/classes_71.js new file mode 100644 index 0000000000..f82504246b --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/classes_71.js @@ -0,0 +1,149 @@ +var searchData= +[ + ['qwtabstractlegend',['QwtAbstractLegend',['../class_qwt_abstract_legend.html',1,'']]], + ['qwtabstractscale',['QwtAbstractScale',['../class_qwt_abstract_scale.html',1,'']]], + ['qwtabstractscaledraw',['QwtAbstractScaleDraw',['../class_qwt_abstract_scale_draw.html',1,'']]], + ['qwtabstractseriesstore',['QwtAbstractSeriesStore',['../class_qwt_abstract_series_store.html',1,'']]], + ['qwtabstractslider',['QwtAbstractSlider',['../class_qwt_abstract_slider.html',1,'']]], + ['qwtalphacolormap',['QwtAlphaColorMap',['../class_qwt_alpha_color_map.html',1,'']]], + ['qwtanalogclock',['QwtAnalogClock',['../class_qwt_analog_clock.html',1,'']]], + ['qwtarrayseriesdata',['QwtArraySeriesData',['../class_qwt_array_series_data.html',1,'']]], + ['qwtarrayseriesdata_3c_20qpointf_20_3e',['QwtArraySeriesData< QPointF >',['../class_qwt_array_series_data.html',1,'']]], + ['qwtarrayseriesdata_3c_20qwtintervalsample_20_3e',['QwtArraySeriesData< QwtIntervalSample >',['../class_qwt_array_series_data.html',1,'']]], + ['qwtarrayseriesdata_3c_20qwtohlcsample_20_3e',['QwtArraySeriesData< QwtOHLCSample >',['../class_qwt_array_series_data.html',1,'']]], + ['qwtarrayseriesdata_3c_20qwtpoint3d_20_3e',['QwtArraySeriesData< QwtPoint3D >',['../class_qwt_array_series_data.html',1,'']]], + ['qwtarrayseriesdata_3c_20qwtsetsample_20_3e',['QwtArraySeriesData< QwtSetSample >',['../class_qwt_array_series_data.html',1,'']]], + ['qwtarrowbutton',['QwtArrowButton',['../class_qwt_arrow_button.html',1,'']]], + ['qwtclipper',['QwtClipper',['../class_qwt_clipper.html',1,'']]], + ['qwtcolormap',['QwtColorMap',['../class_qwt_color_map.html',1,'']]], + ['qwtcolumnrect',['QwtColumnRect',['../class_qwt_column_rect.html',1,'']]], + ['qwtcolumnsymbol',['QwtColumnSymbol',['../class_qwt_column_symbol.html',1,'']]], + ['qwtcompass',['QwtCompass',['../class_qwt_compass.html',1,'']]], + ['qwtcompassmagnetneedle',['QwtCompassMagnetNeedle',['../class_qwt_compass_magnet_needle.html',1,'']]], + ['qwtcompassrose',['QwtCompassRose',['../class_qwt_compass_rose.html',1,'']]], + ['qwtcompassscaledraw',['QwtCompassScaleDraw',['../class_qwt_compass_scale_draw.html',1,'']]], + ['qwtcompasswindarrow',['QwtCompassWindArrow',['../class_qwt_compass_wind_arrow.html',1,'']]], + ['qwtcounter',['QwtCounter',['../class_qwt_counter.html',1,'']]], + ['qwtcpointerdata',['QwtCPointerData',['../class_qwt_c_pointer_data.html',1,'']]], + ['qwtcurvefitter',['QwtCurveFitter',['../class_qwt_curve_fitter.html',1,'']]], + ['qwtdate',['QwtDate',['../class_qwt_date.html',1,'']]], + ['qwtdatescaledraw',['QwtDateScaleDraw',['../class_qwt_date_scale_draw.html',1,'']]], + ['qwtdatescaleengine',['QwtDateScaleEngine',['../class_qwt_date_scale_engine.html',1,'']]], + ['qwtdial',['QwtDial',['../class_qwt_dial.html',1,'']]], + ['qwtdialneedle',['QwtDialNeedle',['../class_qwt_dial_needle.html',1,'']]], + ['qwtdialsimpleneedle',['QwtDialSimpleNeedle',['../class_qwt_dial_simple_needle.html',1,'']]], + ['qwtdyngridlayout',['QwtDynGridLayout',['../class_qwt_dyn_grid_layout.html',1,'']]], + ['qwteventpattern',['QwtEventPattern',['../class_qwt_event_pattern.html',1,'']]], + ['qwtgraphic',['QwtGraphic',['../class_qwt_graphic.html',1,'']]], + ['qwtinterval',['QwtInterval',['../class_qwt_interval.html',1,'']]], + ['qwtintervalsample',['QwtIntervalSample',['../class_qwt_interval_sample.html',1,'']]], + ['qwtintervalseriesdata',['QwtIntervalSeriesData',['../class_qwt_interval_series_data.html',1,'']]], + ['qwtintervalsymbol',['QwtIntervalSymbol',['../class_qwt_interval_symbol.html',1,'']]], + ['qwtknob',['QwtKnob',['../class_qwt_knob.html',1,'']]], + ['qwtlegend',['QwtLegend',['../class_qwt_legend.html',1,'']]], + ['qwtlegenddata',['QwtLegendData',['../class_qwt_legend_data.html',1,'']]], + ['qwtlegendlabel',['QwtLegendLabel',['../class_qwt_legend_label.html',1,'']]], + ['qwtlinearcolormap',['QwtLinearColorMap',['../class_qwt_linear_color_map.html',1,'']]], + ['qwtlinearscaleengine',['QwtLinearScaleEngine',['../class_qwt_linear_scale_engine.html',1,'']]], + ['qwtlogscaleengine',['QwtLogScaleEngine',['../class_qwt_log_scale_engine.html',1,'']]], + ['qwtlogtransform',['QwtLogTransform',['../class_qwt_log_transform.html',1,'']]], + ['qwtmagnifier',['QwtMagnifier',['../class_qwt_magnifier.html',1,'']]], + ['qwtmathmltextengine',['QwtMathMLTextEngine',['../class_qwt_math_m_l_text_engine.html',1,'']]], + ['qwtmatrixrasterdata',['QwtMatrixRasterData',['../class_qwt_matrix_raster_data.html',1,'']]], + ['qwtnullpaintdevice',['QwtNullPaintDevice',['../class_qwt_null_paint_device.html',1,'']]], + ['qwtnulltransform',['QwtNullTransform',['../class_qwt_null_transform.html',1,'']]], + ['qwtohlcsample',['QwtOHLCSample',['../class_qwt_o_h_l_c_sample.html',1,'']]], + ['qwtpainter',['QwtPainter',['../class_qwt_painter.html',1,'']]], + ['qwtpaintercommand',['QwtPainterCommand',['../class_qwt_painter_command.html',1,'']]], + ['qwtpanner',['QwtPanner',['../class_qwt_panner.html',1,'']]], + ['qwtpicker',['QwtPicker',['../class_qwt_picker.html',1,'']]], + ['qwtpickerclickpointmachine',['QwtPickerClickPointMachine',['../class_qwt_picker_click_point_machine.html',1,'']]], + ['qwtpickerclickrectmachine',['QwtPickerClickRectMachine',['../class_qwt_picker_click_rect_machine.html',1,'']]], + ['qwtpickerdraglinemachine',['QwtPickerDragLineMachine',['../class_qwt_picker_drag_line_machine.html',1,'']]], + ['qwtpickerdragpointmachine',['QwtPickerDragPointMachine',['../class_qwt_picker_drag_point_machine.html',1,'']]], + ['qwtpickerdragrectmachine',['QwtPickerDragRectMachine',['../class_qwt_picker_drag_rect_machine.html',1,'']]], + ['qwtpickermachine',['QwtPickerMachine',['../class_qwt_picker_machine.html',1,'']]], + ['qwtpickerpolygonmachine',['QwtPickerPolygonMachine',['../class_qwt_picker_polygon_machine.html',1,'']]], + ['qwtpickertrackermachine',['QwtPickerTrackerMachine',['../class_qwt_picker_tracker_machine.html',1,'']]], + ['qwtpixelmatrix',['QwtPixelMatrix',['../class_qwt_pixel_matrix.html',1,'']]], + ['qwtplaintextengine',['QwtPlainTextEngine',['../class_qwt_plain_text_engine.html',1,'']]], + ['qwtplot',['QwtPlot',['../class_qwt_plot.html',1,'']]], + ['qwtplotabstractbarchart',['QwtPlotAbstractBarChart',['../class_qwt_plot_abstract_bar_chart.html',1,'']]], + ['qwtplotbarchart',['QwtPlotBarChart',['../class_qwt_plot_bar_chart.html',1,'']]], + ['qwtplotcanvas',['QwtPlotCanvas',['../class_qwt_plot_canvas.html',1,'']]], + ['qwtplotcurve',['QwtPlotCurve',['../class_qwt_plot_curve.html',1,'']]], + ['qwtplotdict',['QwtPlotDict',['../class_qwt_plot_dict.html',1,'']]], + ['qwtplotdirectpainter',['QwtPlotDirectPainter',['../class_qwt_plot_direct_painter.html',1,'']]], + ['qwtplotglcanvas',['QwtPlotGLCanvas',['../class_qwt_plot_g_l_canvas.html',1,'']]], + ['qwtplotgrid',['QwtPlotGrid',['../class_qwt_plot_grid.html',1,'']]], + ['qwtplothistogram',['QwtPlotHistogram',['../class_qwt_plot_histogram.html',1,'']]], + ['qwtplotintervalcurve',['QwtPlotIntervalCurve',['../class_qwt_plot_interval_curve.html',1,'']]], + ['qwtplotitem',['QwtPlotItem',['../class_qwt_plot_item.html',1,'']]], + ['qwtplotlayout',['QwtPlotLayout',['../class_qwt_plot_layout.html',1,'']]], + ['qwtplotlegenditem',['QwtPlotLegendItem',['../class_qwt_plot_legend_item.html',1,'']]], + ['qwtplotmagnifier',['QwtPlotMagnifier',['../class_qwt_plot_magnifier.html',1,'']]], + ['qwtplotmarker',['QwtPlotMarker',['../class_qwt_plot_marker.html',1,'']]], + ['qwtplotmultibarchart',['QwtPlotMultiBarChart',['../class_qwt_plot_multi_bar_chart.html',1,'']]], + ['qwtplotpanner',['QwtPlotPanner',['../class_qwt_plot_panner.html',1,'']]], + ['qwtplotpicker',['QwtPlotPicker',['../class_qwt_plot_picker.html',1,'']]], + ['qwtplotrasteritem',['QwtPlotRasterItem',['../class_qwt_plot_raster_item.html',1,'']]], + ['qwtplotrenderer',['QwtPlotRenderer',['../class_qwt_plot_renderer.html',1,'']]], + ['qwtplotrescaler',['QwtPlotRescaler',['../class_qwt_plot_rescaler.html',1,'']]], + ['qwtplotscaleitem',['QwtPlotScaleItem',['../class_qwt_plot_scale_item.html',1,'']]], + ['qwtplotseriesitem',['QwtPlotSeriesItem',['../class_qwt_plot_series_item.html',1,'']]], + ['qwtplotshapeitem',['QwtPlotShapeItem',['../class_qwt_plot_shape_item.html',1,'']]], + ['qwtplotspectrocurve',['QwtPlotSpectroCurve',['../class_qwt_plot_spectro_curve.html',1,'']]], + ['qwtplotspectrogram',['QwtPlotSpectrogram',['../class_qwt_plot_spectrogram.html',1,'']]], + ['qwtplotsvgitem',['QwtPlotSvgItem',['../class_qwt_plot_svg_item.html',1,'']]], + ['qwtplottextlabel',['QwtPlotTextLabel',['../class_qwt_plot_text_label.html',1,'']]], + ['qwtplottradingcurve',['QwtPlotTradingCurve',['../class_qwt_plot_trading_curve.html',1,'']]], + ['qwtplotzoneitem',['QwtPlotZoneItem',['../class_qwt_plot_zone_item.html',1,'']]], + ['qwtplotzoomer',['QwtPlotZoomer',['../class_qwt_plot_zoomer.html',1,'']]], + ['qwtpoint3d',['QwtPoint3D',['../class_qwt_point3_d.html',1,'']]], + ['qwtpoint3dseriesdata',['QwtPoint3DSeriesData',['../class_qwt_point3_d_series_data.html',1,'']]], + ['qwtpointarraydata',['QwtPointArrayData',['../class_qwt_point_array_data.html',1,'']]], + ['qwtpointmapper',['QwtPointMapper',['../class_qwt_point_mapper.html',1,'']]], + ['qwtpointpolar',['QwtPointPolar',['../class_qwt_point_polar.html',1,'']]], + ['qwtpointseriesdata',['QwtPointSeriesData',['../class_qwt_point_series_data.html',1,'']]], + ['qwtpowertransform',['QwtPowerTransform',['../class_qwt_power_transform.html',1,'']]], + ['qwtrasterdata',['QwtRasterData',['../class_qwt_raster_data.html',1,'']]], + ['qwtrichtextengine',['QwtRichTextEngine',['../class_qwt_rich_text_engine.html',1,'']]], + ['qwtroundscaledraw',['QwtRoundScaleDraw',['../class_qwt_round_scale_draw.html',1,'']]], + ['qwtsamplingthread',['QwtSamplingThread',['../class_qwt_sampling_thread.html',1,'']]], + ['qwtscalearithmetic',['QwtScaleArithmetic',['../class_qwt_scale_arithmetic.html',1,'']]], + ['qwtscalediv',['QwtScaleDiv',['../class_qwt_scale_div.html',1,'']]], + ['qwtscaledraw',['QwtScaleDraw',['../class_qwt_scale_draw.html',1,'']]], + ['qwtscaleengine',['QwtScaleEngine',['../class_qwt_scale_engine.html',1,'']]], + ['qwtscalemap',['QwtScaleMap',['../class_qwt_scale_map.html',1,'']]], + ['qwtscalewidget',['QwtScaleWidget',['../class_qwt_scale_widget.html',1,'']]], + ['qwtseriesdata',['QwtSeriesData',['../class_qwt_series_data.html',1,'']]], + ['qwtseriesdata_3c_20qpointf_20_3e',['QwtSeriesData< QPointF >',['../class_qwt_series_data.html',1,'']]], + ['qwtseriesdata_3c_20qwtintervalsample_20_3e',['QwtSeriesData< QwtIntervalSample >',['../class_qwt_series_data.html',1,'']]], + ['qwtseriesdata_3c_20qwtohlcsample_20_3e',['QwtSeriesData< QwtOHLCSample >',['../class_qwt_series_data.html',1,'']]], + ['qwtseriesdata_3c_20qwtpoint3d_20_3e',['QwtSeriesData< QwtPoint3D >',['../class_qwt_series_data.html',1,'']]], + ['qwtseriesdata_3c_20qwtsetsample_20_3e',['QwtSeriesData< QwtSetSample >',['../class_qwt_series_data.html',1,'']]], + ['qwtseriesstore',['QwtSeriesStore',['../class_qwt_series_store.html',1,'']]], + ['qwtseriesstore_3c_20qpointf_20_3e',['QwtSeriesStore< QPointF >',['../class_qwt_series_store.html',1,'']]], + ['qwtseriesstore_3c_20qwtintervalsample_20_3e',['QwtSeriesStore< QwtIntervalSample >',['../class_qwt_series_store.html',1,'']]], + ['qwtseriesstore_3c_20qwtohlcsample_20_3e',['QwtSeriesStore< QwtOHLCSample >',['../class_qwt_series_store.html',1,'']]], + ['qwtseriesstore_3c_20qwtpoint3d_20_3e',['QwtSeriesStore< QwtPoint3D >',['../class_qwt_series_store.html',1,'']]], + ['qwtseriesstore_3c_20qwtsetsample_20_3e',['QwtSeriesStore< QwtSetSample >',['../class_qwt_series_store.html',1,'']]], + ['qwtsetsample',['QwtSetSample',['../class_qwt_set_sample.html',1,'']]], + ['qwtsetseriesdata',['QwtSetSeriesData',['../class_qwt_set_series_data.html',1,'']]], + ['qwtsimplecompassrose',['QwtSimpleCompassRose',['../class_qwt_simple_compass_rose.html',1,'']]], + ['qwtslider',['QwtSlider',['../class_qwt_slider.html',1,'']]], + ['qwtspline',['QwtSpline',['../class_qwt_spline.html',1,'']]], + ['qwtsplinecurvefitter',['QwtSplineCurveFitter',['../class_qwt_spline_curve_fitter.html',1,'']]], + ['qwtsymbol',['QwtSymbol',['../class_qwt_symbol.html',1,'']]], + ['qwtsyntheticpointdata',['QwtSyntheticPointData',['../class_qwt_synthetic_point_data.html',1,'']]], + ['qwtsystemclock',['QwtSystemClock',['../class_qwt_system_clock.html',1,'']]], + ['qwttext',['QwtText',['../class_qwt_text.html',1,'']]], + ['qwttextengine',['QwtTextEngine',['../class_qwt_text_engine.html',1,'']]], + ['qwttextlabel',['QwtTextLabel',['../class_qwt_text_label.html',1,'']]], + ['qwtthermo',['QwtThermo',['../class_qwt_thermo.html',1,'']]], + ['qwttradingchartdata',['QwtTradingChartData',['../class_qwt_trading_chart_data.html',1,'']]], + ['qwttransform',['QwtTransform',['../class_qwt_transform.html',1,'']]], + ['qwtweedingcurvefitter',['QwtWeedingCurveFitter',['../class_qwt_weeding_curve_fitter.html',1,'']]], + ['qwtwheel',['QwtWheel',['../class_qwt_wheel.html',1,'']]], + ['qwtwidgetoverlay',['QwtWidgetOverlay',['../class_qwt_widget_overlay.html',1,'']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/close.png b/ThirdParty/Qwt/doc/html/search/close.png new file mode 100644 index 0000000000..9342d3dfee Binary files /dev/null and b/ThirdParty/Qwt/doc/html/search/close.png differ diff --git a/ThirdParty/Qwt/doc/html/search/enums_61.html b/ThirdParty/Qwt/doc/html/search/enums_61.html new file mode 100644 index 0000000000..b5e91ecf95 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/enums_61.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/enums_61.js b/ThirdParty/Qwt/doc/html/search/enums_61.js new file mode 100644 index 0000000000..99e704b1a6 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/enums_61.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['alignment',['Alignment',['../class_qwt_scale_draw.html#acd7ceeeac592ef08530788580b461c66',1,'QwtScaleDraw']]], + ['attribute',['Attribute',['../class_qwt_plot_direct_painter.html#a38f72175526a1a748d311763707cf934',1,'QwtPlotDirectPainter::Attribute()'],['../class_qwt_scale_engine.html#a7548418e0896d75eec164bfa2ba3ff5f',1,'QwtScaleEngine::Attribute()']]], + ['axis',['Axis',['../class_qwt_plot.html#a81df699dcf9dde0752c0726b5f31e271',1,'QwtPlot']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/enums_62.html b/ThirdParty/Qwt/doc/html/search/enums_62.html new file mode 100644 index 0000000000..e8fef345b1 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/enums_62.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/enums_62.js b/ThirdParty/Qwt/doc/html/search/enums_62.js new file mode 100644 index 0000000000..6d06559cb4 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/enums_62.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['backgroundmode',['BackgroundMode',['../class_qwt_plot_legend_item.html#a26f5e39bb332d42f9dde96fa788960cc',1,'QwtPlotLegendItem']]], + ['borderflag',['BorderFlag',['../class_qwt_interval.html#a3a4b4e49495108c660fc07a62af7ac54',1,'QwtInterval']]], + ['button',['Button',['../class_qwt_counter.html#a027cfd91946ca9a19a1d606411e0f374',1,'QwtCounter']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/enums_63.html b/ThirdParty/Qwt/doc/html/search/enums_63.html new file mode 100644 index 0000000000..e8a1e6c81b --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/enums_63.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/enums_63.js b/ThirdParty/Qwt/doc/html/search/enums_63.js new file mode 100644 index 0000000000..5e0e0df6d7 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/enums_63.js @@ -0,0 +1,9 @@ +var searchData= +[ + ['cachepolicy',['CachePolicy',['../class_qwt_plot_raster_item.html#a94929fc4c31c3dab75ee5adcac2d57b0',1,'QwtPlotRasterItem::CachePolicy()'],['../class_qwt_symbol.html#adda2e2c0e5234692adbc530552efd549',1,'QwtSymbol::CachePolicy()']]], + ['chartstyle',['ChartStyle',['../class_qwt_plot_multi_bar_chart.html#ac67e03008156171c2dd19de4a46eacee',1,'QwtPlotMultiBarChart']]], + ['command',['Command',['../class_qwt_picker_machine.html#a3a8d3d4c107ce5f8351e4cbdd38c43f7',1,'QwtPickerMachine']]], + ['conrecflag',['ConrecFlag',['../class_qwt_raster_data.html#ac0053b66315fde6f0a9a69c40d7c5dcc',1,'QwtRasterData']]], + ['curveattribute',['CurveAttribute',['../class_qwt_plot_curve.html#a38064f7de6f026a49db782c365f872c3',1,'QwtPlotCurve']]], + ['curvestyle',['CurveStyle',['../class_qwt_plot_curve.html#a15998aa80a11ba6ba80eebabaf773f70',1,'QwtPlotCurve::CurveStyle()'],['../class_qwt_plot_interval_curve.html#aaef834575b923e1b317f4a86b2d97cd2',1,'QwtPlotIntervalCurve::CurveStyle()']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/enums_64.html b/ThirdParty/Qwt/doc/html/search/enums_64.html new file mode 100644 index 0000000000..ff2d7b6e55 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/enums_64.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/enums_64.js b/ThirdParty/Qwt/doc/html/search/enums_64.js new file mode 100644 index 0000000000..d0b62e1157 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/enums_64.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['direction',['Direction',['../class_qwt_column_rect.html#a70bb2c6f1f8dabe3bc00793740e0908b',1,'QwtColumnRect::Direction()'],['../class_qwt_plot_trading_curve.html#ab9136d2f1a4dc34dd09a0c03e809b4af',1,'QwtPlotTradingCurve::Direction()']]], + ['discardflag',['DiscardFlag',['../class_qwt_plot_renderer.html#a34d2aa9911e93cb7871e6ce4210e41cd',1,'QwtPlotRenderer']]], + ['displaymode',['DisplayMode',['../class_qwt_picker.html#a01be4d404ffc3a7b238b0d0aaeb66b93',1,'QwtPicker::DisplayMode()'],['../class_qwt_plot_spectrogram.html#a7f4904fe68b442d0f93040ea1fa1d062',1,'QwtPlotSpectrogram::DisplayMode()']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/enums_65.html b/ThirdParty/Qwt/doc/html/search/enums_65.html new file mode 100644 index 0000000000..d204a51963 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/enums_65.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/enums_65.js b/ThirdParty/Qwt/doc/html/search/enums_65.js new file mode 100644 index 0000000000..877b4e49d7 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/enums_65.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['expandingdirection',['ExpandingDirection',['../class_qwt_plot_rescaler.html#a1c314e9513cef076a79381111aa67585',1,'QwtPlotRescaler']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/enums_66.html b/ThirdParty/Qwt/doc/html/search/enums_66.html new file mode 100644 index 0000000000..196030cd62 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/enums_66.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/enums_66.js b/ThirdParty/Qwt/doc/html/search/enums_66.js new file mode 100644 index 0000000000..17e624a33d --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/enums_66.js @@ -0,0 +1,7 @@ +var searchData= +[ + ['fitmode',['FitMode',['../class_qwt_spline_curve_fitter.html#a8c5e6858f885b5691c30092a950879a8',1,'QwtSplineCurveFitter']]], + ['focusindicator',['FocusIndicator',['../class_qwt_plot_canvas.html#a89b44e4c28038a674ce211fe9ac2d7be',1,'QwtPlotCanvas']]], + ['format',['Format',['../class_qwt_color_map.html#a9e5570790910fa3894887bca7dc5a670',1,'QwtColorMap']]], + ['framestyle',['FrameStyle',['../class_qwt_column_symbol.html#a4b97f7748370447559a11a5adeb70e44',1,'QwtColumnSymbol']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/enums_68.html b/ThirdParty/Qwt/doc/html/search/enums_68.html new file mode 100644 index 0000000000..4d3503f988 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/enums_68.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/enums_68.js b/ThirdParty/Qwt/doc/html/search/enums_68.js new file mode 100644 index 0000000000..88e988e6c5 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/enums_68.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['hand',['Hand',['../class_qwt_analog_clock.html#acd8f7e963ae073120684de46821f2cfe',1,'QwtAnalogClock']]], + ['histogramstyle',['HistogramStyle',['../class_qwt_plot_histogram.html#a3ba21c3aef994daf7b848ccf71b0dbc5',1,'QwtPlotHistogram']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/enums_69.html b/ThirdParty/Qwt/doc/html/search/enums_69.html new file mode 100644 index 0000000000..8b2dd270c5 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/enums_69.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/enums_69.js b/ThirdParty/Qwt/doc/html/search/enums_69.js new file mode 100644 index 0000000000..67c0fb6d35 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/enums_69.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['intervaltype',['IntervalType',['../class_qwt_date.html#ad037b999a51cae4d9ab36bf8e7859587',1,'QwtDate']]], + ['itemattribute',['ItemAttribute',['../class_qwt_plot_item.html#ae0fabcdd35f4818ce5bbe019b0eed062',1,'QwtPlotItem']]], + ['iteminterest',['ItemInterest',['../class_qwt_plot_item.html#affbc42460ace9ac725fa825a3f8bfb66',1,'QwtPlotItem']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/enums_6b.html b/ThirdParty/Qwt/doc/html/search/enums_6b.html new file mode 100644 index 0000000000..f32d549652 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/enums_6b.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/enums_6b.js b/ThirdParty/Qwt/doc/html/search/enums_6b.js new file mode 100644 index 0000000000..9aeb9c2144 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/enums_6b.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['keypatterncode',['KeyPatternCode',['../class_qwt_event_pattern.html#a8fb57ceb9982d5583a1bf568e37d3007',1,'QwtEventPattern']]], + ['knobstyle',['KnobStyle',['../class_qwt_knob.html#addd00357b45752377aec83a3ab7208be',1,'QwtKnob']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/enums_6c.html b/ThirdParty/Qwt/doc/html/search/enums_6c.html new file mode 100644 index 0000000000..e271132b10 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/enums_6c.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/enums_6c.js b/ThirdParty/Qwt/doc/html/search/enums_6c.js new file mode 100644 index 0000000000..6bce04409d --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/enums_6c.js @@ -0,0 +1,10 @@ +var searchData= +[ + ['layoutattribute',['LayoutAttribute',['../class_qwt_text.html#a0953aabc098f410dba89bbada47f2e5a',1,'QwtText']]], + ['layoutflag',['LayoutFlag',['../class_qwt_plot_renderer.html#a111b4db55d3f620a33e75f6b398e4b4a',1,'QwtPlotRenderer::LayoutFlag()'],['../class_qwt_scale_widget.html#a95903255246c9da84e7388b567354c8f',1,'QwtScaleWidget::LayoutFlag()']]], + ['layoutpolicy',['LayoutPolicy',['../class_qwt_plot_abstract_bar_chart.html#ae1db0e1606747ef46c863c54c210e53a',1,'QwtPlotAbstractBarChart']]], + ['legendattribute',['LegendAttribute',['../class_qwt_plot_curve.html#a6c1ac1ca99c06598c4044dd2ceeb9fd7',1,'QwtPlotCurve']]], + ['legendmode',['LegendMode',['../class_qwt_plot_bar_chart.html#a5648ff170b563218111d022993b1d6a3',1,'QwtPlotBarChart::LegendMode()'],['../class_qwt_plot_shape_item.html#a2cf398a73f125044df9b83ba421c47cd',1,'QwtPlotShapeItem::LegendMode()']]], + ['legendposition',['LegendPosition',['../class_qwt_plot.html#a31aacb65b5c049dde8c34a0d8482661b',1,'QwtPlot']]], + ['linestyle',['LineStyle',['../class_qwt_plot_marker.html#a297efa835423bfa5a870bbc8ff1c623b',1,'QwtPlotMarker']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/enums_6d.html b/ThirdParty/Qwt/doc/html/search/enums_6d.html new file mode 100644 index 0000000000..2bf0c6dd66 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/enums_6d.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/enums_6d.js b/ThirdParty/Qwt/doc/html/search/enums_6d.js new file mode 100644 index 0000000000..a6ad39ace1 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/enums_6d.js @@ -0,0 +1,7 @@ +var searchData= +[ + ['markerstyle',['MarkerStyle',['../class_qwt_knob.html#a7254d94e76a74228637931fb75939b95',1,'QwtKnob']]], + ['maskmode',['MaskMode',['../class_qwt_widget_overlay.html#a413679fb15e072d5a404f237062b75fc',1,'QwtWidgetOverlay']]], + ['mode',['Mode',['../class_qwt_linear_color_map.html#ac8c5f1991f533b1d25a9a0a0874b7d54',1,'QwtLinearColorMap::Mode()'],['../class_qwt_dial.html#a7376f53193014b91643350e6e6bc85ad',1,'QwtDial::Mode()'],['../class_qwt_legend_data.html#aaa33cc8e6aec17440df5d4c38d7545b7',1,'QwtLegendData::Mode()'],['../class_qwt_null_paint_device.html#a1e605d04e468e2e7fc45c639251a053a',1,'QwtNullPaintDevice::Mode()']]], + ['mousepatterncode',['MousePatternCode',['../class_qwt_event_pattern.html#af48dc808ac5e125eeed41a4c0285d1ea',1,'QwtEventPattern']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/enums_6f.html b/ThirdParty/Qwt/doc/html/search/enums_6f.html new file mode 100644 index 0000000000..6a389c1b73 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/enums_6f.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/enums_6f.js b/ThirdParty/Qwt/doc/html/search/enums_6f.js new file mode 100644 index 0000000000..d5df523e6f --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/enums_6f.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['option',['Option',['../class_qwt_plot_layout.html#ad0d2d60e86a4c69ec105524041d5221d',1,'QwtPlotLayout']]], + ['originmode',['OriginMode',['../class_qwt_thermo.html#a932d866dd7782cc56cd7fc3e5abb3183',1,'QwtThermo']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/enums_70.html b/ThirdParty/Qwt/doc/html/search/enums_70.html new file mode 100644 index 0000000000..d737ab2180 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/enums_70.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/enums_70.js b/ThirdParty/Qwt/doc/html/search/enums_70.js new file mode 100644 index 0000000000..ffe46e7ce6 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/enums_70.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['paintattribute',['PaintAttribute',['../class_qwt_plot_canvas.html#a76066290edb594a71ee09be564563b0f',1,'QwtPlotCanvas::PaintAttribute()'],['../class_qwt_plot_curve.html#a96db1b854c63bfbc452c943251a11b66',1,'QwtPlotCurve::PaintAttribute()'],['../class_qwt_plot_interval_curve.html#a3deaf543802d69a38961f9e944bfad95',1,'QwtPlotIntervalCurve::PaintAttribute()'],['../class_qwt_plot_raster_item.html#a75ac68ea258b8612e8a1893e845394ee',1,'QwtPlotRasterItem::PaintAttribute()'],['../class_qwt_plot_shape_item.html#aaa78031ce7ab1b8e713bc05da05a4631',1,'QwtPlotShapeItem::PaintAttribute()'],['../class_qwt_plot_spectro_curve.html#af6d4c6ae392f3f521db710484a059625',1,'QwtPlotSpectroCurve::PaintAttribute()'],['../class_qwt_plot_trading_curve.html#afc40b9bee1371ebce4a7f3853fee7968',1,'QwtPlotTradingCurve::PaintAttribute()'],['../class_qwt_text.html#a9739e47ea489e690f121e4b1d27ae24e',1,'QwtText::PaintAttribute()']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/enums_72.html b/ThirdParty/Qwt/doc/html/search/enums_72.html new file mode 100644 index 0000000000..011dc7e35e --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/enums_72.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/enums_72.js b/ThirdParty/Qwt/doc/html/search/enums_72.js new file mode 100644 index 0000000000..76e84c6716 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/enums_72.js @@ -0,0 +1,11 @@ +var searchData= +[ + ['renderhint',['RenderHint',['../class_qwt_graphic.html#a3f87dcc606b131ed6c3cfeead1d6de03',1,'QwtGraphic::RenderHint()'],['../class_qwt_plot_item.html#abe0e8a39aceef9a600b73e02550a9704',1,'QwtPlotItem::RenderHint()']]], + ['rendermode',['RenderMode',['../class_qwt_widget_overlay.html#aaa8358f3b841b733d69e62aa645783d8',1,'QwtWidgetOverlay']]], + ['resamplemode',['ResampleMode',['../class_qwt_matrix_raster_data.html#a3c8def5d9ae452bd82e6c4b71b480209',1,'QwtMatrixRasterData']]], + ['rescalepolicy',['RescalePolicy',['../class_qwt_plot_rescaler.html#a6a614b832876a7641cb5410ba81d9d6a',1,'QwtPlotRescaler']]], + ['resizemode',['ResizeMode',['../class_qwt_picker.html#ab3c894deed026f392496dd07809a6fd3',1,'QwtPicker']]], + ['role',['Role',['../class_qwt_legend_data.html#a55bd21943c804101d956250ca43f93f9',1,'QwtLegendData']]], + ['rttivalues',['RttiValues',['../class_qwt_plot_item.html#ab149ac85e233ce9cedf2f2f2af871bf3',1,'QwtPlotItem']]], + ['rubberband',['RubberBand',['../class_qwt_picker.html#ab36c79d8ff20aba5b778d2823c1f7894',1,'QwtPicker']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/enums_73.html b/ThirdParty/Qwt/doc/html/search/enums_73.html new file mode 100644 index 0000000000..af19563ef4 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/enums_73.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/enums_73.js b/ThirdParty/Qwt/doc/html/search/enums_73.js new file mode 100644 index 0000000000..386a09510e --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/enums_73.js @@ -0,0 +1,11 @@ +var searchData= +[ + ['scalecomponent',['ScaleComponent',['../class_qwt_abstract_scale_draw.html#a26215d06a4d48adf401d0aa05d4193c5',1,'QwtAbstractScaleDraw']]], + ['scaleposition',['ScalePosition',['../class_qwt_slider.html#a120d984d7c519578eed88c4fe97cb1a7',1,'QwtSlider::ScalePosition()'],['../class_qwt_thermo.html#a4d7af32d29d1cc18e23b9143cf7ad498',1,'QwtThermo::ScalePosition()']]], + ['selectiontype',['SelectionType',['../class_qwt_picker_machine.html#a24a9faf12cfa5746eee839a2c0bb937d',1,'QwtPickerMachine']]], + ['shadow',['Shadow',['../class_qwt_dial.html#a7472124cb120352e8538430ab48c2386',1,'QwtDial::Shadow()'],['../class_qwt_plot_g_l_canvas.html#a6ce3b3cb6888443dfadca2399a632830',1,'QwtPlotGLCanvas::Shadow()']]], + ['shape',['Shape',['../class_qwt_plot_g_l_canvas.html#abb14b54c316ea3b3d39dee1dc0e78849',1,'QwtPlotGLCanvas']]], + ['splinetype',['SplineType',['../class_qwt_spline.html#a2bd2bda128f82acd596348eb8d64231c',1,'QwtSpline']]], + ['style',['Style',['../class_qwt_column_symbol.html#aaace508375eef3ee23ed6c47b1d65ef2',1,'QwtColumnSymbol::Style()'],['../class_qwt_dial_simple_needle.html#ad28821489e04f1fd942e5bebc8a60584',1,'QwtDialSimpleNeedle::Style()'],['../class_qwt_compass_magnet_needle.html#aee1d882c6ec8b680b94b59b5710a92a5',1,'QwtCompassMagnetNeedle::Style()'],['../class_qwt_compass_wind_arrow.html#a55f11e28c9d87c0fb7c306ccd174f2a8',1,'QwtCompassWindArrow::Style()'],['../class_qwt_interval_symbol.html#a8fe960fd50b3ad08765ef8bb632ad77e',1,'QwtIntervalSymbol::Style()'],['../class_qwt_symbol.html#a62f457952470c2076962e83ef2c24d2f',1,'QwtSymbol::Style()']]], + ['symbolstyle',['SymbolStyle',['../class_qwt_plot_trading_curve.html#af1ca10dd8c3f1ef662d40fc8a113b44a',1,'QwtPlotTradingCurve']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/enums_74.html b/ThirdParty/Qwt/doc/html/search/enums_74.html new file mode 100644 index 0000000000..9b754ee67f --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/enums_74.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/enums_74.js b/ThirdParty/Qwt/doc/html/search/enums_74.js new file mode 100644 index 0000000000..7174e5c3f1 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/enums_74.js @@ -0,0 +1,7 @@ +var searchData= +[ + ['textformat',['TextFormat',['../class_qwt_text.html#a63e0d6a59a427a37ed0bfa71b782fd76',1,'QwtText']]], + ['ticktype',['TickType',['../class_qwt_scale_div.html#af21aedaa886dd5e067cf63505838736c',1,'QwtScaleDiv']]], + ['transformationflag',['TransformationFlag',['../class_qwt_point_mapper.html#aafc07ceadb3f311057037ca8680e1c23',1,'QwtPointMapper']]], + ['type',['Type',['../class_qwt_painter_command.html#a6619a454c4332c02412611467935b7ba',1,'QwtPainterCommand']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/enums_77.html b/ThirdParty/Qwt/doc/html/search/enums_77.html new file mode 100644 index 0000000000..b3081599ad --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/enums_77.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/enums_77.js b/ThirdParty/Qwt/doc/html/search/enums_77.js new file mode 100644 index 0000000000..a0c5cc4710 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/enums_77.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['week0type',['Week0Type',['../class_qwt_date.html#ab915db512c556a4666ada4fbfccfce1e',1,'QwtDate']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/enumvalues_61.html b/ThirdParty/Qwt/doc/html/search/enumvalues_61.html new file mode 100644 index 0000000000..77dd02c463 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/enumvalues_61.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/enumvalues_61.js b/ThirdParty/Qwt/doc/html/search/enumvalues_61.js new file mode 100644 index 0000000000..a403323f4b --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/enumvalues_61.js @@ -0,0 +1,17 @@ +var searchData= +[ + ['activeonly',['ActiveOnly',['../class_qwt_picker.html#a01be4d404ffc3a7b238b0d0aaeb66b93a973f3446b39ea41b5dc3b31593ecb64a',1,'QwtPicker']]], + ['alignscales',['AlignScales',['../class_qwt_plot_layout.html#ad0d2d60e86a4c69ec105524041d5221daf92cc90a2b68a8788a813807d379b95a',1,'QwtPlotLayout']]], + ['alphamask',['AlphaMask',['../class_qwt_widget_overlay.html#a413679fb15e072d5a404f237062b75fca263c0fea842a8d4957ded6f5e47f734e',1,'QwtWidgetOverlay']]], + ['alwaysoff',['AlwaysOff',['../class_qwt_picker.html#a01be4d404ffc3a7b238b0d0aaeb66b93a94fcf579dddb78a1c88fd4136d3a673a',1,'QwtPicker']]], + ['alwayson',['AlwaysOn',['../class_qwt_picker.html#a01be4d404ffc3a7b238b0d0aaeb66b93a07a7513aa69633c1a3b04fdbfe4674e0',1,'QwtPicker']]], + ['arrow',['Arrow',['../class_qwt_dial_simple_needle.html#ad28821489e04f1fd942e5bebc8a60584a27ace220f0a5c6abd061c85bbdc9a663',1,'QwtDialSimpleNeedle']]], + ['atomicpainter',['AtomicPainter',['../class_qwt_plot_direct_painter.html#a38f72175526a1a748d311763707cf934a95bfb017daa98b23665c1de06e8bd8e5',1,'QwtPlotDirectPainter']]], + ['auto',['Auto',['../class_qwt_spline_curve_fitter.html#a8c5e6858f885b5691c30092a950879a8ae19b8325da178d410cf10b04ed5a5df6',1,'QwtSplineCurveFitter']]], + ['autoadjustsamples',['AutoAdjustSamples',['../class_qwt_plot_abstract_bar_chart.html#ae1db0e1606747ef46c863c54c210e53aa6d8801b5f08318c9be2441ca4bb15a96',1,'QwtPlotAbstractBarChart']]], + ['autocache',['AutoCache',['../class_qwt_symbol.html#adda2e2c0e5234692adbc530552efd549acaa219da83872a5ea6bec535667037b5',1,'QwtSymbol']]], + ['autorendermode',['AutoRenderMode',['../class_qwt_widget_overlay.html#aaa8358f3b841b733d69e62aa645783d8a831530722d8dc0e42aabfbcacbb6ecc6',1,'QwtWidgetOverlay']]], + ['autoscale',['AutoScale',['../class_qwt_plot_item.html#ae0fabcdd35f4818ce5bbe019b0eed062a9de83e2ad8a88796a36a11ef8b033a48',1,'QwtPlotItem']]], + ['autotext',['AutoText',['../class_qwt_text.html#a63e0d6a59a427a37ed0bfa71b782fd76a0645d333081ec9e3574c98f510c284a1',1,'QwtText']]], + ['axiscnt',['axisCnt',['../class_qwt_plot.html#a81df699dcf9dde0752c0726b5f31e271aea62036dfd48ee0f9450718592614892',1,'QwtPlot']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/enumvalues_62.html b/ThirdParty/Qwt/doc/html/search/enumvalues_62.html new file mode 100644 index 0000000000..ecbeb60860 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/enumvalues_62.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/enumvalues_62.js b/ThirdParty/Qwt/doc/html/search/enumvalues_62.js new file mode 100644 index 0000000000..4743ecde60 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/enumvalues_62.js @@ -0,0 +1,15 @@ +var searchData= +[ + ['backbone',['Backbone',['../class_qwt_abstract_scale_draw.html#a26215d06a4d48adf401d0aa05d4193c5a61a6c4f4dec2b089edfb655e2b21c3a2',1,'QwtAbstractScaleDraw']]], + ['backingstore',['BackingStore',['../class_qwt_plot_canvas.html#a76066290edb594a71ee09be564563b0fa7b88a46e1414f6d904aa494c89d064f3',1,'QwtPlotCanvas']]], + ['bar',['Bar',['../class_qwt_interval_symbol.html#a8fe960fd50b3ad08765ef8bb632ad77ea1e4120af73e888e2edf05798d906e934',1,'QwtIntervalSymbol::Bar()'],['../class_qwt_plot_trading_curve.html#af1ca10dd8c3f1ef662d40fc8a113b44aa151b8fa49a6da794fc18563b32f26e37',1,'QwtPlotTradingCurve::Bar()']]], + ['bilinearinterpolation',['BilinearInterpolation',['../class_qwt_matrix_raster_data.html#a3c8def5d9ae452bd82e6c4b71b480209a6f25a9f1f27cb94525ce39df487af13f',1,'QwtMatrixRasterData']]], + ['bottomlegend',['BottomLegend',['../class_qwt_plot.html#a31aacb65b5c049dde8c34a0d8482661ba8b863705308d89b388732f186be15fb5',1,'QwtPlot']]], + ['bottomscale',['BottomScale',['../class_qwt_scale_draw.html#acd7ceeeac592ef08530788580b461c66a0e16389e135da75f06117d1ee3ef765f',1,'QwtScaleDraw']]], + ['bottomtotop',['BottomToTop',['../class_qwt_column_rect.html#a70bb2c6f1f8dabe3bc00793740e0908baa5f0a56f1bd041136476d4ad40ae56f0',1,'QwtColumnRect']]], + ['box',['Box',['../class_qwt_column_symbol.html#aaace508375eef3ee23ed6c47b1d65ef2ad21d1b393a2474a1caa6a9d83daa8f21',1,'QwtColumnSymbol::Box()'],['../class_qwt_interval_symbol.html#a8fe960fd50b3ad08765ef8bb632ad77eaf4f31197926c38dcc0377bb75ed5e6e1',1,'QwtIntervalSymbol::Box()']]], + ['button1',['Button1',['../class_qwt_counter.html#a027cfd91946ca9a19a1d606411e0f374a1b29fe43c7d59986eb5854ddaf6f7179',1,'QwtCounter']]], + ['button2',['Button2',['../class_qwt_counter.html#a027cfd91946ca9a19a1d606411e0f374a6015e556fcb8c4d45126dee5435b478d',1,'QwtCounter']]], + ['button3',['Button3',['../class_qwt_counter.html#a027cfd91946ca9a19a1d606411e0f374a30b64d40b31283807f1a4f3d57af0e74',1,'QwtCounter']]], + ['buttoncnt',['ButtonCnt',['../class_qwt_counter.html#a027cfd91946ca9a19a1d606411e0f374aca8e93a2d129f7cc91f54f5f4da20c5f',1,'QwtCounter']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/enumvalues_63.html b/ThirdParty/Qwt/doc/html/search/enumvalues_63.html new file mode 100644 index 0000000000..ad1be30aa0 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/enumvalues_63.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/enumvalues_63.js b/ThirdParty/Qwt/doc/html/search/enumvalues_63.js new file mode 100644 index 0000000000..1ae398d601 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/enumvalues_63.js @@ -0,0 +1,18 @@ +var searchData= +[ + ['cache',['Cache',['../class_qwt_symbol.html#adda2e2c0e5234692adbc530552efd549af9c909c7a68dd83785c85a0083dcf796',1,'QwtSymbol']]], + ['candlestick',['CandleStick',['../class_qwt_plot_trading_curve.html#af1ca10dd8c3f1ef662d40fc8a113b44aa647559431e0ec4404de12dfd0c324482',1,'QwtPlotTradingCurve']]], + ['canvasfocusindicator',['CanvasFocusIndicator',['../class_qwt_plot_canvas.html#a89b44e4c28038a674ce211fe9ac2d7bea884899cc2fa5cb416e73fe3e7aba2271',1,'QwtPlotCanvas']]], + ['checkable',['Checkable',['../class_qwt_legend_data.html#aaa33cc8e6aec17440df5d4c38d7545b7a250e05444c9927d83d3815d9f5593917',1,'QwtLegendData']]], + ['clickable',['Clickable',['../class_qwt_legend_data.html#aaa33cc8e6aec17440df5d4c38d7545b7a39077c66db9fe2faf4d85a6f9266583f',1,'QwtLegendData']]], + ['clippoints',['ClipPoints',['../class_qwt_plot_spectro_curve.html#af6d4c6ae392f3f521db710484a059625ab8586d2301ec1e0888f852bca84c2501',1,'QwtPlotSpectroCurve']]], + ['clippolygons',['ClipPolygons',['../class_qwt_plot_curve.html#a96db1b854c63bfbc452c943251a11b66a26f9aa8ae434aa94b4049b9908995abf',1,'QwtPlotCurve::ClipPolygons()'],['../class_qwt_plot_interval_curve.html#a3deaf543802d69a38961f9e944bfad95aac1361651d57a0df1a079f30849e72a1',1,'QwtPlotIntervalCurve::ClipPolygons()'],['../class_qwt_plot_shape_item.html#aaa78031ce7ab1b8e713bc05da05a4631a21854077548e55943dc8f9f208960442',1,'QwtPlotShapeItem::ClipPolygons()']]], + ['clipsymbol',['ClipSymbol',['../class_qwt_plot_interval_curve.html#a3deaf543802d69a38961f9e944bfad95a9b164d29534731bbd3d34717baf399ca',1,'QwtPlotIntervalCurve']]], + ['clipsymbols',['ClipSymbols',['../class_qwt_plot_trading_curve.html#afc40b9bee1371ebce4a7f3853fee7968a8bcf035ef95b4c4f95fa78a3459a4c2c',1,'QwtPlotTradingCurve']]], + ['columns',['Columns',['../class_qwt_plot_histogram.html#a3ba21c3aef994daf7b848ccf71b0dbc5a9cd056b6b9881b07c625756488487362',1,'QwtPlotHistogram']]], + ['contourmode',['ContourMode',['../class_qwt_plot_spectrogram.html#a7f4904fe68b442d0f93040ea1fa1d062a64e86465a6d48ad80c4baadb144f9cf8',1,'QwtPlotSpectrogram']]], + ['copyalphamask',['CopyAlphaMask',['../class_qwt_widget_overlay.html#aaa8358f3b841b733d69e62aa645783d8a923e121c1d01bb72deb897a6f913aaf5',1,'QwtWidgetOverlay']]], + ['copybackingstore',['CopyBackingStore',['../class_qwt_plot_direct_painter.html#a38f72175526a1a748d311763707cf934a8b04f057d6223852a87bdd319dcf4711',1,'QwtPlotDirectPainter']]], + ['cross',['Cross',['../class_qwt_plot_marker.html#a297efa835423bfa5a870bbc8ff1c623ba5014eec17204ed4b0cec35e7322696d2',1,'QwtPlotMarker::Cross()'],['../class_qwt_symbol.html#a62f457952470c2076962e83ef2c24d2fab75eff873d34264d84a55cb94b603fef',1,'QwtSymbol::Cross()']]], + ['crossrubberband',['CrossRubberBand',['../class_qwt_picker.html#ab36c79d8ff20aba5b778d2823c1f7894a1b90615892fec7ff6bb3352ce887b097',1,'QwtPicker']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/enumvalues_64.html b/ThirdParty/Qwt/doc/html/search/enumvalues_64.html new file mode 100644 index 0000000000..7f516b4e80 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/enumvalues_64.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/enumvalues_64.js b/ThirdParty/Qwt/doc/html/search/enumvalues_64.js new file mode 100644 index 0000000000..edaeeca60e --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/enumvalues_64.js @@ -0,0 +1,18 @@ +var searchData= +[ + ['day',['Day',['../class_qwt_date.html#ad037b999a51cae4d9ab36bf8e7859587a1d503616cab082a9c741be881cc0a813',1,'QwtDate']]], + ['decreasing',['Decreasing',['../class_qwt_plot_trading_curve.html#ab9136d2f1a4dc34dd09a0c03e809b4afacd9a36ba360db4449bf40928d1652d83',1,'QwtPlotTradingCurve']]], + ['defaultlayout',['DefaultLayout',['../class_qwt_plot_renderer.html#a111b4db55d3f620a33e75f6b398e4b4aa7aeaacf4750595de6774ad45ba170c5d',1,'QwtPlotRenderer']]], + ['diamond',['Diamond',['../class_qwt_symbol.html#a62f457952470c2076962e83ef2c24d2fa952136b2f18abfe1b4712ce9de84dbf4',1,'QwtSymbol']]], + ['discardbackground',['DiscardBackground',['../class_qwt_plot_renderer.html#a34d2aa9911e93cb7871e6ce4210e41cda8520c4587d5b11708b5b314936a07288',1,'QwtPlotRenderer']]], + ['discardcanvasbackground',['DiscardCanvasBackground',['../class_qwt_plot_renderer.html#a34d2aa9911e93cb7871e6ce4210e41cdab9bb1a51c26e57f6c2b7e650c6edab03',1,'QwtPlotRenderer']]], + ['discardcanvasframe',['DiscardCanvasFrame',['../class_qwt_plot_renderer.html#a34d2aa9911e93cb7871e6ce4210e41cda081e5228ec807e75df243a8ad31f2871',1,'QwtPlotRenderer']]], + ['discardfooter',['DiscardFooter',['../class_qwt_plot_renderer.html#a34d2aa9911e93cb7871e6ce4210e41cda1c61c6c040ce707dcf1cd51f92040d1e',1,'QwtPlotRenderer']]], + ['discardlegend',['DiscardLegend',['../class_qwt_plot_renderer.html#a34d2aa9911e93cb7871e6ce4210e41cdac20500aed74824fbea6c3b0d057a482a',1,'QwtPlotRenderer']]], + ['discardnone',['DiscardNone',['../class_qwt_plot_renderer.html#a34d2aa9911e93cb7871e6ce4210e41cdaf2b5ab01146a2e3f85454741465f1f16',1,'QwtPlotRenderer']]], + ['discardtitle',['DiscardTitle',['../class_qwt_plot_renderer.html#a34d2aa9911e93cb7871e6ce4210e41cda2866f5a7d38cbfb34431b95c8dc952e1',1,'QwtPlotRenderer']]], + ['dot',['Dot',['../class_qwt_knob.html#a7254d94e76a74228637931fb75939b95a298324d95eafb4e99717a35b81b0b704',1,'QwtKnob']]], + ['dots',['Dots',['../class_qwt_plot_curve.html#a15998aa80a11ba6ba80eebabaf773f70ac30a3c76d19bc69fc69bed68fc154838',1,'QwtPlotCurve']]], + ['drawoverlay',['DrawOverlay',['../class_qwt_widget_overlay.html#aaa8358f3b841b733d69e62aa645783d8ab4b3bfef277a5231f8632a6800a256d8',1,'QwtWidgetOverlay']]], + ['dtriangle',['DTriangle',['../class_qwt_symbol.html#a62f457952470c2076962e83ef2c24d2fad8ea4408d80512825a2700b4968f1715',1,'QwtSymbol']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/enumvalues_65.html b/ThirdParty/Qwt/doc/html/search/enumvalues_65.html new file mode 100644 index 0000000000..745e9ac845 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/enumvalues_65.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/enumvalues_65.js b/ThirdParty/Qwt/doc/html/search/enumvalues_65.js new file mode 100644 index 0000000000..80508a886d --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/enumvalues_65.js @@ -0,0 +1,12 @@ +var searchData= +[ + ['ellipse',['Ellipse',['../class_qwt_symbol.html#a62f457952470c2076962e83ef2c24d2fa09e1d50ec759311a76c158f69149fa44',1,'QwtSymbol']]], + ['ellipserubberband',['EllipseRubberBand',['../class_qwt_picker.html#ab36c79d8ff20aba5b778d2823c1f7894a6a548d259f7f04ae868419431883e7ef',1,'QwtPicker']]], + ['excludeborders',['ExcludeBorders',['../class_qwt_interval.html#a3a4b4e49495108c660fc07a62af7ac54afc7d2a399b311a1cc8026681410fc22c',1,'QwtInterval']]], + ['excludemaximum',['ExcludeMaximum',['../class_qwt_interval.html#a3a4b4e49495108c660fc07a62af7ac54a70e70e65956ae319e507bc38b792c434',1,'QwtInterval']]], + ['excludeminimum',['ExcludeMinimum',['../class_qwt_interval.html#a3a4b4e49495108c660fc07a62af7ac54aa7fde04c41d882187bb13f0104da7240',1,'QwtInterval']]], + ['expandboth',['ExpandBoth',['../class_qwt_plot_rescaler.html#a1c314e9513cef076a79381111aa67585a3dfb8208dfb62200761e4221763db033',1,'QwtPlotRescaler']]], + ['expanddown',['ExpandDown',['../class_qwt_plot_rescaler.html#a1c314e9513cef076a79381111aa67585a856d9a1fe75ed6398a1b3c4b60f3fbfd',1,'QwtPlotRescaler']]], + ['expanding',['Expanding',['../class_qwt_plot_rescaler.html#a6a614b832876a7641cb5410ba81d9d6aac0b9db1ea3c5666792c2a9813ca5d7e1',1,'QwtPlotRescaler']]], + ['expandup',['ExpandUp',['../class_qwt_plot_rescaler.html#a1c314e9513cef076a79381111aa67585a10adc202ca84a06179b905db6802668c',1,'QwtPlotRescaler']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/enumvalues_66.html b/ThirdParty/Qwt/doc/html/search/enumvalues_66.html new file mode 100644 index 0000000000..e7d399af5c --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/enumvalues_66.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/enumvalues_66.js b/ThirdParty/Qwt/doc/html/search/enumvalues_66.js new file mode 100644 index 0000000000..01f1ed77ac --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/enumvalues_66.js @@ -0,0 +1,15 @@ +var searchData= +[ + ['filterpoints',['FilterPoints',['../class_qwt_plot_curve.html#a96db1b854c63bfbc452c943251a11b66af09c1c6ec8c8198124f0e41c391f8391',1,'QwtPlotCurve']]], + ['firstday',['FirstDay',['../class_qwt_date.html#ab915db512c556a4666ada4fbfccfce1eab5c50b8108f8c4535201c0c590a598d6',1,'QwtDate']]], + ['firstthursday',['FirstThursday',['../class_qwt_date.html#ab915db512c556a4666ada4fbfccfce1ea82971cd90d670fe3048ad8c377379c1d',1,'QwtDate']]], + ['fitted',['Fitted',['../class_qwt_plot_curve.html#a38064f7de6f026a49db782c365f872c3a583f7bc6ca4d5245fa82757f4bddea1b',1,'QwtPlotCurve']]], + ['fitting',['Fitting',['../class_qwt_plot_rescaler.html#a6a614b832876a7641cb5410ba81d9d6aa30a43b11d9df23f66110b65d1e249db1',1,'QwtPlotRescaler']]], + ['fixed',['Fixed',['../class_qwt_plot_rescaler.html#a6a614b832876a7641cb5410ba81d9d6aab8f9ce10c092bee12de74b05a46b6e9c',1,'QwtPlotRescaler']]], + ['fixedcolors',['FixedColors',['../class_qwt_linear_color_map.html#ac8c5f1991f533b1d25a9a0a0874b7d54a564b5243ab2c5e4c972a6b645234c651',1,'QwtLinearColorMap']]], + ['fixedsamplesize',['FixedSampleSize',['../class_qwt_plot_abstract_bar_chart.html#ae1db0e1606747ef46c863c54c210e53aa17d33062f0a9e6c38e43a0c51ba778e5',1,'QwtPlotAbstractBarChart']]], + ['flat',['Flat',['../class_qwt_knob.html#addd00357b45752377aec83a3ab7208bea1dea5fdd408692d0efacc3edf8ca9454',1,'QwtKnob']]], + ['floating',['Floating',['../class_qwt_scale_engine.html#a7548418e0896d75eec164bfa2ba3ff5fa2158d4b3596e7d4a00375821fc0d20c3',1,'QwtScaleEngine']]], + ['framewithscales',['FrameWithScales',['../class_qwt_plot_renderer.html#a111b4db55d3f620a33e75f6b398e4b4aac81f7d56880ac4c03aaeab489c863a63',1,'QwtPlotRenderer']]], + ['fullrepaint',['FullRepaint',['../class_qwt_plot_direct_painter.html#a38f72175526a1a748d311763707cf934a133cb5ae512ffa0f0633c9d7bd423ff4',1,'QwtPlotDirectPainter']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/enumvalues_67.html b/ThirdParty/Qwt/doc/html/search/enumvalues_67.html new file mode 100644 index 0000000000..2ce35a6330 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/enumvalues_67.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/enumvalues_67.js b/ThirdParty/Qwt/doc/html/search/enumvalues_67.js new file mode 100644 index 0000000000..6924b71b61 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/enumvalues_67.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['graphic',['Graphic',['../class_qwt_symbol.html#a62f457952470c2076962e83ef2c24d2faa24a49671ffa302f19f28a5c56c6ec0e',1,'QwtSymbol']]], + ['grouped',['Grouped',['../class_qwt_plot_multi_bar_chart.html#ac67e03008156171c2dd19de4a46eaceeac112d35b99385c204f4b4fc91c602e60',1,'QwtPlotMultiBarChart']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/enumvalues_68.html b/ThirdParty/Qwt/doc/html/search/enumvalues_68.html new file mode 100644 index 0000000000..56ef1fcf7f --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/enumvalues_68.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/enumvalues_68.js b/ThirdParty/Qwt/doc/html/search/enumvalues_68.js new file mode 100644 index 0000000000..808b7f1854 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/enumvalues_68.js @@ -0,0 +1,9 @@ +var searchData= +[ + ['hackstyledbackground',['HackStyledBackground',['../class_qwt_plot_canvas.html#a76066290edb594a71ee09be564563b0fa2a2fee2c1807f8306850e15977bacb70',1,'QwtPlotCanvas']]], + ['hexagon',['Hexagon',['../class_qwt_symbol.html#a62f457952470c2076962e83ef2c24d2fa8bf81a46e1ee93ea3d8d8c8990b72f36',1,'QwtSymbol']]], + ['hline',['HLine',['../class_qwt_plot_marker.html#a297efa835423bfa5a870bbc8ff1c623ba4439b2f358352a4cf6414b0ea4861609',1,'QwtPlotMarker::HLine()'],['../class_qwt_symbol.html#a62f457952470c2076962e83ef2c24d2fa3bc949e0e38ccaf908bb58c7c177f7f6',1,'QwtSymbol::HLine()']]], + ['hlinerubberband',['HLineRubberBand',['../class_qwt_picker.html#ab36c79d8ff20aba5b778d2823c1f7894a9f3ab0ea1294b4eb2cae7b919ce0ffb0',1,'QwtPicker']]], + ['hour',['Hour',['../class_qwt_date.html#ad037b999a51cae4d9ab36bf8e7859587a8e7a2f91f89423e446bfdaa1e01ebd2f',1,'QwtDate']]], + ['hourhand',['HourHand',['../class_qwt_analog_clock.html#acd8f7e963ae073120684de46821f2cfea1e8f73f647c5a95ca062a8d63376982a',1,'QwtAnalogClock']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/enumvalues_69.html b/ThirdParty/Qwt/doc/html/search/enumvalues_69.html new file mode 100644 index 0000000000..bcd6d2e46c --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/enumvalues_69.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/enumvalues_69.js b/ThirdParty/Qwt/doc/html/search/enumvalues_69.js new file mode 100644 index 0000000000..09ae3fc371 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/enumvalues_69.js @@ -0,0 +1,22 @@ +var searchData= +[ + ['ignoreallverticesonlevel',['IgnoreAllVerticesOnLevel',['../class_qwt_raster_data.html#ac0053b66315fde6f0a9a69c40d7c5dccafd2f6337e825201a247408f033713c92',1,'QwtRasterData']]], + ['ignorefooter',['IgnoreFooter',['../class_qwt_plot_layout.html#ad0d2d60e86a4c69ec105524041d5221da132d4fc728c0826a269a143f2d655215',1,'QwtPlotLayout']]], + ['ignoreframes',['IgnoreFrames',['../class_qwt_plot_layout.html#ad0d2d60e86a4c69ec105524041d5221da9036bf7de40018a2f12d456a04949c6b',1,'QwtPlotLayout']]], + ['ignorelegend',['IgnoreLegend',['../class_qwt_plot_layout.html#ad0d2d60e86a4c69ec105524041d5221daa7237e2be1e8fc41a8b3156b57b95ed3',1,'QwtPlotLayout']]], + ['ignoreoutofrange',['IgnoreOutOfRange',['../class_qwt_raster_data.html#ac0053b66315fde6f0a9a69c40d7c5dcca18e8d1de171dd43cc957c279eb03d32c',1,'QwtRasterData']]], + ['ignorescrollbars',['IgnoreScrollbars',['../class_qwt_plot_layout.html#ad0d2d60e86a4c69ec105524041d5221da813736a8e614f8f24db773081642b74c',1,'QwtPlotLayout']]], + ['ignoretitle',['IgnoreTitle',['../class_qwt_plot_layout.html#ad0d2d60e86a4c69ec105524041d5221da00feaacfa819204f09074fc9b128b22c',1,'QwtPlotLayout']]], + ['image',['Image',['../class_qwt_painter_command.html#a6619a454c4332c02412611467935b7baab7dfdaa4ca3c9e6d57bdb27f5dd27669',1,'QwtPainterCommand']]], + ['imagebuffer',['ImageBuffer',['../class_qwt_plot_curve.html#a96db1b854c63bfbc452c943251a11b66a5e80434a35db4325ef8cdcb4dcb52282',1,'QwtPlotCurve']]], + ['imagemode',['ImageMode',['../class_qwt_plot_spectrogram.html#a7f4904fe68b442d0f93040ea1fa1d062ac9696cad413e4a11a4721779728fb9e3',1,'QwtPlotSpectrogram']]], + ['immediatepaint',['ImmediatePaint',['../class_qwt_plot_canvas.html#a76066290edb594a71ee09be564563b0fa91fb95b7ec380cc5d517195c2ae6368f',1,'QwtPlotCanvas']]], + ['includeborders',['IncludeBorders',['../class_qwt_interval.html#a3a4b4e49495108c660fc07a62af7ac54ad8a550b5eb1062cd84bcba22c60e5e60',1,'QwtInterval']]], + ['includereference',['IncludeReference',['../class_qwt_scale_engine.html#a7548418e0896d75eec164bfa2ba3ff5fad29dea0ac58c4675ac009620b0857984',1,'QwtScaleEngine']]], + ['increasing',['Increasing',['../class_qwt_plot_trading_curve.html#ab9136d2f1a4dc34dd09a0c03e809b4afa0d39ddffe160060a5c99ff5324d227d8',1,'QwtPlotTradingCurve']]], + ['indexed',['Indexed',['../class_qwt_color_map.html#a9e5570790910fa3894887bca7dc5a670a304cb055c004223ca77f1a4cbbf27ea2',1,'QwtColorMap']]], + ['invalid',['Invalid',['../class_qwt_painter_command.html#a6619a454c4332c02412611467935b7baa501f44c9ca82165fd3c76fd3f50d07dd',1,'QwtPainterCommand']]], + ['inverted',['Inverted',['../class_qwt_plot_curve.html#a38064f7de6f026a49db782c365f872c3af7790b4716576fd0641ec393f476bc46',1,'QwtPlotCurve::Inverted()'],['../class_qwt_scale_engine.html#a7548418e0896d75eec164bfa2ba3ff5fa2f3985208684d394319320b8e67ea062',1,'QwtScaleEngine::Inverted()']]], + ['itembackground',['ItemBackground',['../class_qwt_plot_legend_item.html#a26f5e39bb332d42f9dde96fa788960ccad59a658b42182dab97057e923887e7c8',1,'QwtPlotLegendItem']]], + ['itemfocusindicator',['ItemFocusIndicator',['../class_qwt_plot_canvas.html#a89b44e4c28038a674ce211fe9ac2d7bea5a56f0e29a38350abdcef18c3e583115',1,'QwtPlotCanvas']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/enumvalues_6a.html b/ThirdParty/Qwt/doc/html/search/enumvalues_6a.html new file mode 100644 index 0000000000..9bca13c164 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/enumvalues_6a.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/enumvalues_6a.js b/ThirdParty/Qwt/doc/html/search/enumvalues_6a.js new file mode 100644 index 0000000000..2913a65112 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/enumvalues_6a.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['juliandayforepoch',['JulianDayForEpoch',['../class_qwt_date.html#af636fffdebea2e4463fc32461b1217e0aed8ee8f3dbc5b7a5e953b3ec51a79108',1,'QwtDate']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/enumvalues_6b.html b/ThirdParty/Qwt/doc/html/search/enumvalues_6b.html new file mode 100644 index 0000000000..ca124bf244 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/enumvalues_6b.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/enumvalues_6b.js b/ThirdParty/Qwt/doc/html/search/enumvalues_6b.js new file mode 100644 index 0000000000..b9c35941e1 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/enumvalues_6b.js @@ -0,0 +1,15 @@ +var searchData= +[ + ['keepsize',['KeepSize',['../class_qwt_picker.html#ab3c894deed026f392496dd07809a6fd3ae873df582534c398b2f753763b0eb780',1,'QwtPicker']]], + ['keyabort',['KeyAbort',['../class_qwt_event_pattern.html#a8fb57ceb9982d5583a1bf568e37d3007a5b73ad3186285f5aaf2030a50a3fb5a4',1,'QwtEventPattern']]], + ['keydown',['KeyDown',['../class_qwt_event_pattern.html#a8fb57ceb9982d5583a1bf568e37d3007a00c2d782ca962ee6bcda1c4a3649d1e7',1,'QwtEventPattern']]], + ['keyhome',['KeyHome',['../class_qwt_event_pattern.html#a8fb57ceb9982d5583a1bf568e37d3007a4cba7de2850f874988cbaa38a236ecb2',1,'QwtEventPattern']]], + ['keyleft',['KeyLeft',['../class_qwt_event_pattern.html#a8fb57ceb9982d5583a1bf568e37d3007abaf3cd86d773c8e47a2c670b65d6ec95',1,'QwtEventPattern']]], + ['keypatterncount',['KeyPatternCount',['../class_qwt_event_pattern.html#a8fb57ceb9982d5583a1bf568e37d3007aca9b018d7ae0f2342779e91df7ddcdd3',1,'QwtEventPattern']]], + ['keyredo',['KeyRedo',['../class_qwt_event_pattern.html#a8fb57ceb9982d5583a1bf568e37d3007a2c8d72876cd9435ee018e9cf8fa2ff26',1,'QwtEventPattern']]], + ['keyright',['KeyRight',['../class_qwt_event_pattern.html#a8fb57ceb9982d5583a1bf568e37d3007a607bbbf235ba79f6e36a25c6d7d27c53',1,'QwtEventPattern']]], + ['keyselect1',['KeySelect1',['../class_qwt_event_pattern.html#a8fb57ceb9982d5583a1bf568e37d3007a32afc68b8e31079c00666a251d0b9c25',1,'QwtEventPattern']]], + ['keyselect2',['KeySelect2',['../class_qwt_event_pattern.html#a8fb57ceb9982d5583a1bf568e37d3007acfd4f64d5b3b29214e51afcc56ea7eaf',1,'QwtEventPattern']]], + ['keyundo',['KeyUndo',['../class_qwt_event_pattern.html#a8fb57ceb9982d5583a1bf568e37d3007a76cf851373169fbc588109c1eccca33a',1,'QwtEventPattern']]], + ['keyup',['KeyUp',['../class_qwt_event_pattern.html#a8fb57ceb9982d5583a1bf568e37d3007a010af73c06629f6c53daf69fad5b6efe',1,'QwtEventPattern']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/enumvalues_6c.html b/ThirdParty/Qwt/doc/html/search/enumvalues_6c.html new file mode 100644 index 0000000000..89f775c99d --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/enumvalues_6c.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/enumvalues_6c.js b/ThirdParty/Qwt/doc/html/search/enumvalues_6c.js new file mode 100644 index 0000000000..b15ad486aa --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/enumvalues_6c.js @@ -0,0 +1,21 @@ +var searchData= +[ + ['labels',['Labels',['../class_qwt_abstract_scale_draw.html#a26215d06a4d48adf401d0aa05d4193c5ad2709d7efbb6f1618f0a8a3b6cafae96',1,'QwtAbstractScaleDraw']]], + ['leadingscale',['LeadingScale',['../class_qwt_slider.html#a120d984d7c519578eed88c4fe97cb1a7a0822eb6df854223a53d2ff95d6070c5d',1,'QwtSlider::LeadingScale()'],['../class_qwt_thermo.html#a4d7af32d29d1cc18e23b9143cf7ad498acda60ddfe6178199553941b75ad927a0',1,'QwtThermo::LeadingScale()']]], + ['leftlegend',['LeftLegend',['../class_qwt_plot.html#a31aacb65b5c049dde8c34a0d8482661ba38b51536a196582bd1f7658c0828eb18',1,'QwtPlot']]], + ['leftscale',['LeftScale',['../class_qwt_scale_draw.html#acd7ceeeac592ef08530788580b461c66af2a8239964381f18dbd08d4a93a7fa23',1,'QwtScaleDraw']]], + ['lefttoright',['LeftToRight',['../class_qwt_column_rect.html#a70bb2c6f1f8dabe3bc00793740e0908ba3cde7a99f22f5d897ed4b963731256a6',1,'QwtColumnRect']]], + ['legend',['Legend',['../class_qwt_plot_item.html#ae0fabcdd35f4818ce5bbe019b0eed062a4e377b54bd879c60a95162b6a9e9e176',1,'QwtPlotItem']]], + ['legendbackground',['LegendBackground',['../class_qwt_plot_legend_item.html#a26f5e39bb332d42f9dde96fa788960cca638235bb73b0f3b34d0aba92842ec8e1',1,'QwtPlotLegendItem']]], + ['legendbartitles',['LegendBarTitles',['../class_qwt_plot_bar_chart.html#a5648ff170b563218111d022993b1d6a3a1d24c89de2f25180a0814d80f8b54c8e',1,'QwtPlotBarChart']]], + ['legendcharttitle',['LegendChartTitle',['../class_qwt_plot_bar_chart.html#a5648ff170b563218111d022993b1d6a3afff608b4bdd6b57ab86204c13d58f504',1,'QwtPlotBarChart']]], + ['legendcolor',['LegendColor',['../class_qwt_plot_shape_item.html#a2cf398a73f125044df9b83ba421c47cda5798347f022bcd9f66c0bb2c8a9534c3',1,'QwtPlotShapeItem']]], + ['legendinterest',['LegendInterest',['../class_qwt_plot_item.html#affbc42460ace9ac725fa825a3f8bfb66afcc4ef45e6613104ccc2b9f7988e4d22',1,'QwtPlotItem']]], + ['legendnoattribute',['LegendNoAttribute',['../class_qwt_plot_curve.html#a6c1ac1ca99c06598c4044dd2ceeb9fd7a5ca8291c000cca41c082035610b08a67',1,'QwtPlotCurve']]], + ['legendshape',['LegendShape',['../class_qwt_plot_shape_item.html#a2cf398a73f125044df9b83ba421c47cdac1d32e3ca5a234638e8bc46d2dd86e38',1,'QwtPlotShapeItem']]], + ['legendshowbrush',['LegendShowBrush',['../class_qwt_plot_curve.html#a6c1ac1ca99c06598c4044dd2ceeb9fd7a20cd7f91d61c44b05c49bffd930646be',1,'QwtPlotCurve']]], + ['legendshowline',['LegendShowLine',['../class_qwt_plot_curve.html#a6c1ac1ca99c06598c4044dd2ceeb9fd7a7eb8387acab6a10a95219634c97c266f',1,'QwtPlotCurve']]], + ['legendshowsymbol',['LegendShowSymbol',['../class_qwt_plot_curve.html#a6c1ac1ca99c06598c4044dd2ceeb9fd7a5902a8ff0c4c7f1080dd4e2bd5eb29be',1,'QwtPlotCurve']]], + ['lines',['Lines',['../class_qwt_plot_curve.html#a15998aa80a11ba6ba80eebabaf773f70a8914d88bcd5f680e7091469fed67c9ba',1,'QwtPlotCurve::Lines()'],['../class_qwt_plot_histogram.html#a3ba21c3aef994daf7b848ccf71b0dbc5a62b3af66b59203102394dbe1711a7a58',1,'QwtPlotHistogram::Lines()']]], + ['ltriangle',['LTriangle',['../class_qwt_symbol.html#a62f457952470c2076962e83ef2c24d2fa228f6d48261e8b6bc9981370ae65f5e5',1,'QwtSymbol']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/enumvalues_6d.html b/ThirdParty/Qwt/doc/html/search/enumvalues_6d.html new file mode 100644 index 0000000000..f68d5268e0 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/enumvalues_6d.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/enumvalues_6d.js b/ThirdParty/Qwt/doc/html/search/enumvalues_6d.js new file mode 100644 index 0000000000..4b94eb453d --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/enumvalues_6d.js @@ -0,0 +1,22 @@ +var searchData= +[ + ['majortick',['MajorTick',['../class_qwt_scale_div.html#af21aedaa886dd5e067cf63505838736cadda390d4186a0ff20ece95d986c1ae60',1,'QwtScaleDiv']]], + ['margins',['Margins',['../class_qwt_plot_item.html#ae0fabcdd35f4818ce5bbe019b0eed062a56ea00cf43b862667dec2ac727307d4d',1,'QwtPlotItem']]], + ['maskhint',['MaskHint',['../class_qwt_widget_overlay.html#a413679fb15e072d5a404f237062b75fcaa3c2ba9dd41304c6a6524ee5f7c70540',1,'QwtWidgetOverlay']]], + ['mathmltext',['MathMLText',['../class_qwt_text.html#a63e0d6a59a427a37ed0bfa71b782fd76abf479897e4514198246a0b232a597caf',1,'QwtText']]], + ['mediumtick',['MediumTick',['../class_qwt_scale_div.html#af21aedaa886dd5e067cf63505838736ca42fbe3ad54900057e75225ff5e68cc4a',1,'QwtScaleDiv']]], + ['millisecond',['Millisecond',['../class_qwt_date.html#ad037b999a51cae4d9ab36bf8e7859587a4e1d45d6382c27689a30adc11186d4f1',1,'QwtDate']]], + ['minimizememory',['MinimizeMemory',['../class_qwt_plot_curve.html#a96db1b854c63bfbc452c943251a11b66a154c720d852e71b7909adf5e56a3500d',1,'QwtPlotCurve']]], + ['minimumlayout',['MinimumLayout',['../class_qwt_text.html#a0953aabc098f410dba89bbada47f2e5aa35990c4c74747580e9357d490ebce42f',1,'QwtText']]], + ['minortick',['MinorTick',['../class_qwt_scale_div.html#af21aedaa886dd5e067cf63505838736ca6af9f3b95636a6fdebb4824c6db0ab9e',1,'QwtScaleDiv']]], + ['minute',['Minute',['../class_qwt_date.html#ad037b999a51cae4d9ab36bf8e7859587a7c9073c66b2628adbe772ac4c1a678ef',1,'QwtDate']]], + ['minutehand',['MinuteHand',['../class_qwt_analog_clock.html#acd8f7e963ae073120684de46821f2cfea024c7bee0110b50aad1bfffe6f468744',1,'QwtAnalogClock']]], + ['month',['Month',['../class_qwt_date.html#ad037b999a51cae4d9ab36bf8e7859587a0ab43f35f1bdbae7536be2be0455700a',1,'QwtDate']]], + ['mousepatterncount',['MousePatternCount',['../class_qwt_event_pattern.html#af48dc808ac5e125eeed41a4c0285d1eaa01bd637c7b7c0fbb80c013f8a935e562',1,'QwtEventPattern']]], + ['mouseselect1',['MouseSelect1',['../class_qwt_event_pattern.html#af48dc808ac5e125eeed41a4c0285d1eaa5875976eba018ca30eb30ba92986d270',1,'QwtEventPattern']]], + ['mouseselect2',['MouseSelect2',['../class_qwt_event_pattern.html#af48dc808ac5e125eeed41a4c0285d1eaac4185682db6cfd9c59955eb4cf052fd1',1,'QwtEventPattern']]], + ['mouseselect3',['MouseSelect3',['../class_qwt_event_pattern.html#af48dc808ac5e125eeed41a4c0285d1eaaa52e3aa1f4f6e57e22ffe9208f0dd1e3',1,'QwtEventPattern']]], + ['mouseselect4',['MouseSelect4',['../class_qwt_event_pattern.html#af48dc808ac5e125eeed41a4c0285d1eaa7cf49ee566862c3778e3d47096138f3b',1,'QwtEventPattern']]], + ['mouseselect5',['MouseSelect5',['../class_qwt_event_pattern.html#af48dc808ac5e125eeed41a4c0285d1eaac735f981781895836d0d9475ac3cae87',1,'QwtEventPattern']]], + ['mouseselect6',['MouseSelect6',['../class_qwt_event_pattern.html#af48dc808ac5e125eeed41a4c0285d1eaaf8f83e3d9c9a5d639a4290c6b124ddd9',1,'QwtEventPattern']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/enumvalues_6e.html b/ThirdParty/Qwt/doc/html/search/enumvalues_6e.html new file mode 100644 index 0000000000..ce1fb47a45 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/enumvalues_6e.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/enumvalues_6e.js b/ThirdParty/Qwt/doc/html/search/enumvalues_6e.js new file mode 100644 index 0000000000..475750671d --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/enumvalues_6e.js @@ -0,0 +1,24 @@ +var searchData= +[ + ['natural',['Natural',['../class_qwt_spline.html#a2bd2bda128f82acd596348eb8d64231ca506b78ec81ab6d56a4bbce891490c857',1,'QwtSpline']]], + ['nearestneighbour',['NearestNeighbour',['../class_qwt_matrix_raster_data.html#a3c8def5d9ae452bd82e6c4b71b480209acaa0a9e3b8afd376472d6a587a3f9873',1,'QwtMatrixRasterData']]], + ['nhands',['NHands',['../class_qwt_analog_clock.html#acd8f7e963ae073120684de46821f2cfea004c9f49b4271e02f350bccd21235ecd',1,'QwtAnalogClock']]], + ['noattribute',['NoAttribute',['../class_qwt_scale_engine.html#a7548418e0896d75eec164bfa2ba3ff5fa617f0da0b90080be49b79dbaaab191f8',1,'QwtScaleEngine']]], + ['nocache',['NoCache',['../class_qwt_plot_raster_item.html#a94929fc4c31c3dab75ee5adcac2d57b0a758ccf247c4ae50d4ffd090ef3a6058e',1,'QwtPlotRasterItem::NoCache()'],['../class_qwt_symbol.html#adda2e2c0e5234692adbc530552efd549ac0f276939fbf44c89e93b3a3870abb18',1,'QwtSymbol::NoCache()']]], + ['nocurve',['NoCurve',['../class_qwt_plot_curve.html#a15998aa80a11ba6ba80eebabaf773f70a0b6dcf16619a08af39437d6b6a234c9c',1,'QwtPlotCurve::NoCurve()'],['../class_qwt_plot_interval_curve.html#aaef834575b923e1b317f4a86b2d97cd2a40f2eb25abeed9eb2af1b4c4c0f56c15',1,'QwtPlotIntervalCurve::NoCurve()']]], + ['nofocusindicator',['NoFocusIndicator',['../class_qwt_plot_canvas.html#a89b44e4c28038a674ce211fe9ac2d7bea8578c1bdcba0a05d5d0b89aeb35a040d',1,'QwtPlotCanvas']]], + ['noframe',['NoFrame',['../class_qwt_column_symbol.html#a4b97f7748370447559a11a5adeb70e44a11a035d598228e1498b98153e3e9e043',1,'QwtColumnSymbol']]], + ['noline',['NoLine',['../class_qwt_plot_marker.html#a297efa835423bfa5a870bbc8ff1c623ba5407403ea223539c7cac264a9fff5fe0',1,'QwtPlotMarker']]], + ['nomarker',['NoMarker',['../class_qwt_knob.html#a7254d94e76a74228637931fb75939b95af12a242c58b244547abb48ef284246f6',1,'QwtKnob']]], + ['nomask',['NoMask',['../class_qwt_widget_overlay.html#a413679fb15e072d5a404f237062b75fca58d7a0858b0aa58407bf598c907636fd',1,'QwtWidgetOverlay']]], + ['normalmode',['NormalMode',['../class_qwt_null_paint_device.html#a1e605d04e468e2e7fc45c639251a053aa2ad991b2edd425baa217eb90ed9930f7',1,'QwtNullPaintDevice']]], + ['norubberband',['NoRubberBand',['../class_qwt_picker.html#ab36c79d8ff20aba5b778d2823c1f7894abe995b2c285314bf9fc459581e100934',1,'QwtPicker']]], + ['noscale',['NoScale',['../class_qwt_slider.html#a120d984d7c519578eed88c4fe97cb1a7a49899c3cf9ad1d8f45046824ecbfc6a4',1,'QwtSlider::NoScale()'],['../class_qwt_thermo.html#a4d7af32d29d1cc18e23b9143cf7ad498a54c98c1e9500e24a5f92e71a7020acbd',1,'QwtThermo::NoScale()']]], + ['noselection',['NoSelection',['../class_qwt_picker_machine.html#a24a9faf12cfa5746eee839a2c0bb937da326bcc03f7a99aa5970d875f3db46888',1,'QwtPickerMachine']]], + ['nostyle',['NoStyle',['../class_qwt_column_symbol.html#aaace508375eef3ee23ed6c47b1d65ef2a3c16d900e0dcfc18f174f4120136cb5b',1,'QwtColumnSymbol']]], + ['nosymbol',['NoSymbol',['../class_qwt_interval_symbol.html#a8fe960fd50b3ad08765ef8bb632ad77ea48e0d047b9988e77067a11f784556019',1,'QwtIntervalSymbol::NoSymbol()'],['../class_qwt_plot_trading_curve.html#af1ca10dd8c3f1ef662d40fc8a113b44aaffbe8e09731b6296d7534149c63a39b3',1,'QwtPlotTradingCurve::NoSymbol()'],['../class_qwt_symbol.html#a62f457952470c2076962e83ef2c24d2fac3089b3993834683204a7bda52e763d3',1,'QwtSymbol::NoSymbol()']]], + ['notch',['Notch',['../class_qwt_knob.html#a7254d94e76a74228637931fb75939b95a9ea483f1087c1f6b1ac215b5f146c7c3',1,'QwtKnob']]], + ['notick',['NoTick',['../class_qwt_scale_div.html#af21aedaa886dd5e067cf63505838736ca9f64c3f9efef05e3020903a54331c4ac',1,'QwtScaleDiv']]], + ['nticktypes',['NTickTypes',['../class_qwt_scale_div.html#af21aedaa886dd5e067cf63505838736ca86796bbf72d5eb7162a924ba27ce6553',1,'QwtScaleDiv']]], + ['nub',['Nub',['../class_qwt_knob.html#a7254d94e76a74228637931fb75939b95a1bf9be6c73beec7768d62f101d81a851',1,'QwtKnob']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/enumvalues_6f.html b/ThirdParty/Qwt/doc/html/search/enumvalues_6f.html new file mode 100644 index 0000000000..8e7354c093 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/enumvalues_6f.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/enumvalues_6f.js b/ThirdParty/Qwt/doc/html/search/enumvalues_6f.js new file mode 100644 index 0000000000..9c73f9f99e --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/enumvalues_6f.js @@ -0,0 +1,9 @@ +var searchData= +[ + ['opaque',['Opaque',['../class_qwt_plot_canvas.html#a76066290edb594a71ee09be564563b0fa1d10fbb2b1fc3323e8597597684b1f9f',1,'QwtPlotCanvas']]], + ['origincustom',['OriginCustom',['../class_qwt_thermo.html#a932d866dd7782cc56cd7fc3e5abb3183ad086bebe6a48967d8d078f0c27ee993f',1,'QwtThermo']]], + ['originmaximum',['OriginMaximum',['../class_qwt_thermo.html#a932d866dd7782cc56cd7fc3e5abb3183aa67de5780557c0c2ca93c45059ae932a',1,'QwtThermo']]], + ['originminimum',['OriginMinimum',['../class_qwt_thermo.html#a932d866dd7782cc56cd7fc3e5abb3183ae45b6edabbd2a63aa1551b7ed9b10f76',1,'QwtThermo']]], + ['otherformat',['OtherFormat',['../class_qwt_text.html#a63e0d6a59a427a37ed0bfa71b782fd76ad69e3155611ef96eb14ed0cfeb69fd3d',1,'QwtText']]], + ['outline',['Outline',['../class_qwt_plot_histogram.html#a3ba21c3aef994daf7b848ccf71b0dbc5ab6ef3ed19f600d5d67d34eedf4cf33a9',1,'QwtPlotHistogram']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/enumvalues_70.html b/ThirdParty/Qwt/doc/html/search/enumvalues_70.html new file mode 100644 index 0000000000..0b609cb11b --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/enumvalues_70.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/enumvalues_70.js b/ThirdParty/Qwt/doc/html/search/enumvalues_70.js new file mode 100644 index 0000000000..a12b2d12d0 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/enumvalues_70.js @@ -0,0 +1,19 @@ +var searchData= +[ + ['paintbackground',['PaintBackground',['../class_qwt_text.html#a9739e47ea489e690f121e4b1d27ae24ea77dd66b2a65e9998d9803672791e1456',1,'QwtText']]], + ['paintcache',['PaintCache',['../class_qwt_plot_raster_item.html#a94929fc4c31c3dab75ee5adcac2d57b0a3bfb74bebbfe1ccabe1d6654fee7c56d',1,'QwtPlotRasterItem']]], + ['paintindeviceresolution',['PaintInDeviceResolution',['../class_qwt_plot_raster_item.html#a75ac68ea258b8612e8a1893e845394eea77b139d4d7327465408fe06ec98dbc0d',1,'QwtPlotRasterItem']]], + ['paintusingtextcolor',['PaintUsingTextColor',['../class_qwt_text.html#a9739e47ea489e690f121e4b1d27ae24ea1aa48cee0a54089820e77600cf93dc4b',1,'QwtText']]], + ['paintusingtextfont',['PaintUsingTextFont',['../class_qwt_text.html#a9739e47ea489e690f121e4b1d27ae24eac12e48f17fd02a6bc1840c61c4862a65',1,'QwtText']]], + ['parametricspline',['ParametricSpline',['../class_qwt_spline_curve_fitter.html#a8c5e6858f885b5691c30092a950879a8a877f71e694ae9a2e33533a3fb5065c66',1,'QwtSplineCurveFitter']]], + ['path',['Path',['../class_qwt_painter_command.html#a6619a454c4332c02412611467935b7baa8f98e03699c40458ed0c2007dca698ca',1,'QwtPainterCommand::Path()'],['../class_qwt_symbol.html#a62f457952470c2076962e83ef2c24d2faa3cc8fec7843b850f3cde81a6b04394c',1,'QwtSymbol::Path()']]], + ['pathmode',['PathMode',['../class_qwt_null_paint_device.html#a1e605d04e468e2e7fc45c639251a053aa6dd94a051e9b1bab414cc819f2878e65',1,'QwtNullPaintDevice']]], + ['periodic',['Periodic',['../class_qwt_spline.html#a2bd2bda128f82acd596348eb8d64231ca500c12cdbdef35c62e9fab86c5727acb',1,'QwtSpline']]], + ['pixmap',['Pixmap',['../class_qwt_painter_command.html#a6619a454c4332c02412611467935b7baa02455f25a984a7dde5992e748af34487',1,'QwtPainterCommand::Pixmap()'],['../class_qwt_symbol.html#a62f457952470c2076962e83ef2c24d2fa45c8273247748316e5dd359b2d00216c',1,'QwtSymbol::Pixmap()']]], + ['plain',['Plain',['../class_qwt_column_symbol.html#a4b97f7748370447559a11a5adeb70e44a2841bca1e2a5d94fbfc5a51787460be1',1,'QwtColumnSymbol::Plain()'],['../class_qwt_dial.html#a7472124cb120352e8538430ab48c2386a8d0cdae56d44bcd25574d7e432498d86',1,'QwtDial::Plain()'],['../class_qwt_plot_g_l_canvas.html#a6ce3b3cb6888443dfadca2399a632830a2d5a783769032359be64ff1d1a6c9143',1,'QwtPlotGLCanvas::Plain()']]], + ['plaintext',['PlainText',['../class_qwt_text.html#a63e0d6a59a427a37ed0bfa71b782fd76aa6810f6d3c785c202d2507c601b97787',1,'QwtText']]], + ['pointselection',['PointSelection',['../class_qwt_picker_machine.html#a24a9faf12cfa5746eee839a2c0bb937dae65a34cc1ca5d818eb65c05b2484d855',1,'QwtPickerMachine']]], + ['polygonpathmode',['PolygonPathMode',['../class_qwt_null_paint_device.html#a1e605d04e468e2e7fc45c639251a053aad26aa1be0859afe98851b8ee170ca0a7',1,'QwtNullPaintDevice']]], + ['polygonrubberband',['PolygonRubberBand',['../class_qwt_picker.html#ab36c79d8ff20aba5b778d2823c1f7894a8b78b6221f2808abe027569c790f0945',1,'QwtPicker']]], + ['polygonselection',['PolygonSelection',['../class_qwt_picker_machine.html#a24a9faf12cfa5746eee839a2c0bb937dac74671ee5ba5d6fd0410f71db1aa3b97',1,'QwtPickerMachine']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/enumvalues_72.html b/ThirdParty/Qwt/doc/html/search/enumvalues_72.html new file mode 100644 index 0000000000..534d56e2ab --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/enumvalues_72.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/enumvalues_72.js b/ThirdParty/Qwt/doc/html/search/enumvalues_72.js new file mode 100644 index 0000000000..ba6f24e3a5 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/enumvalues_72.js @@ -0,0 +1,38 @@ +var searchData= +[ + ['raised',['Raised',['../class_qwt_column_symbol.html#a4b97f7748370447559a11a5adeb70e44a078f2b7db1cee79e83878fcc869df62e',1,'QwtColumnSymbol::Raised()'],['../class_qwt_dial.html#a7472124cb120352e8538430ab48c2386a4054b8890d1f837387762b4a12157847',1,'QwtDial::Raised()'],['../class_qwt_knob.html#addd00357b45752377aec83a3ab7208bea998504d08713af8a9af0d2cbe0aaf8df',1,'QwtKnob::Raised()'],['../class_qwt_plot_g_l_canvas.html#a6ce3b3cb6888443dfadca2399a632830a51c9540f673ec613857453927dc084cf',1,'QwtPlotGLCanvas::Raised()']]], + ['ray',['Ray',['../class_qwt_dial_simple_needle.html#ad28821489e04f1fd942e5bebc8a60584a580980e68ef26fc7d35962cf6f12a4b2',1,'QwtDialSimpleNeedle']]], + ['readonly',['ReadOnly',['../class_qwt_legend_data.html#aaa33cc8e6aec17440df5d4c38d7545b7add4342fbe2d82828b9ef7031c1b41a0b',1,'QwtLegendData']]], + ['rect',['Rect',['../class_qwt_symbol.html#a62f457952470c2076962e83ef2c24d2fa3c5d3b8c39e11cc10c6f0c8176bbd235',1,'QwtSymbol']]], + ['rectrubberband',['RectRubberBand',['../class_qwt_picker.html#ab36c79d8ff20aba5b778d2823c1f7894ae4dc32fb99b4fe2058bb594ab5e8c70a',1,'QwtPicker']]], + ['rectselection',['RectSelection',['../class_qwt_picker_machine.html#a24a9faf12cfa5746eee839a2c0bb937da9f540e78958e8e238240584120e8af1d',1,'QwtPickerMachine']]], + ['renderantialiased',['RenderAntialiased',['../class_qwt_plot_item.html#abe0e8a39aceef9a600b73e02550a9704ae0c9811915d496eaacbd749724647f13',1,'QwtPlotItem']]], + ['renderpensunscaled',['RenderPensUnscaled',['../class_qwt_graphic.html#a3f87dcc606b131ed6c3cfeead1d6de03ab70056f66aa75fb24c834cb3da7b0133',1,'QwtGraphic']]], + ['rgb',['RGB',['../class_qwt_color_map.html#a9e5570790910fa3894887bca7dc5a670a663473fd836d9a84fe48ae1755de326a',1,'QwtColorMap']]], + ['richtext',['RichText',['../class_qwt_text.html#a63e0d6a59a427a37ed0bfa71b782fd76a88f7eee487ce6f7769b67494623d8b79',1,'QwtText']]], + ['rightlegend',['RightLegend',['../class_qwt_plot.html#a31aacb65b5c049dde8c34a0d8482661ba5273f8002504c24f9dae6ce09b08f03c',1,'QwtPlot']]], + ['rightscale',['RightScale',['../class_qwt_scale_draw.html#acd7ceeeac592ef08530788580b461c66a84d42042d94ae7726395ceb578225e1e',1,'QwtScaleDraw']]], + ['righttoleft',['RightToLeft',['../class_qwt_column_rect.html#a70bb2c6f1f8dabe3bc00793740e0908bac08f1153f84950e62d369cc7b7011b5e',1,'QwtColumnRect']]], + ['rotateneedle',['RotateNeedle',['../class_qwt_dial.html#a7376f53193014b91643350e6e6bc85adacc23db2e06c9098f8cfbd0181184054a',1,'QwtDial']]], + ['rotatescale',['RotateScale',['../class_qwt_dial.html#a7376f53193014b91643350e6e6bc85ada95a22f59ec832d22f011a9421f528c41',1,'QwtDial']]], + ['roundpoints',['RoundPoints',['../class_qwt_point_mapper.html#aafc07ceadb3f311057037ca8680e1c23a0e367a1519b0005cad8bb324854cc8e3',1,'QwtPointMapper']]], + ['rtriangle',['RTriangle',['../class_qwt_symbol.html#a62f457952470c2076962e83ef2c24d2faeb6111f6fc1813efb466687309c873bd',1,'QwtSymbol']]], + ['rtti_5fplotbarchart',['Rtti_PlotBarChart',['../class_qwt_plot_item.html#ab149ac85e233ce9cedf2f2f2af871bf3ab89eb3547903640b6cc9d0aac02ef6c3',1,'QwtPlotItem']]], + ['rtti_5fplotcurve',['Rtti_PlotCurve',['../class_qwt_plot_item.html#ab149ac85e233ce9cedf2f2f2af871bf3af51a35012ed097a762b8918cf20caa69',1,'QwtPlotItem']]], + ['rtti_5fplotgrid',['Rtti_PlotGrid',['../class_qwt_plot_item.html#ab149ac85e233ce9cedf2f2f2af871bf3af3125faa8333135a5724cc1d6c276683',1,'QwtPlotItem']]], + ['rtti_5fplothistogram',['Rtti_PlotHistogram',['../class_qwt_plot_item.html#ab149ac85e233ce9cedf2f2f2af871bf3a4538dd66ec78ffd7ce6763f9000edcee',1,'QwtPlotItem']]], + ['rtti_5fplotintervalcurve',['Rtti_PlotIntervalCurve',['../class_qwt_plot_item.html#ab149ac85e233ce9cedf2f2f2af871bf3a5698aa120baa6e3d3d2a6bda8a82b226',1,'QwtPlotItem']]], + ['rtti_5fplotitem',['Rtti_PlotItem',['../class_qwt_plot_item.html#ab149ac85e233ce9cedf2f2f2af871bf3af1fb53ddb320ecbf2bba00a323cf08ff',1,'QwtPlotItem']]], + ['rtti_5fplotlegend',['Rtti_PlotLegend',['../class_qwt_plot_item.html#ab149ac85e233ce9cedf2f2f2af871bf3a06cd77e370cf62597501e692965e1f9c',1,'QwtPlotItem']]], + ['rtti_5fplotmarker',['Rtti_PlotMarker',['../class_qwt_plot_item.html#ab149ac85e233ce9cedf2f2f2af871bf3a15b3819a193f24b76c78e39cb80c7789',1,'QwtPlotItem']]], + ['rtti_5fplotmultibarchart',['Rtti_PlotMultiBarChart',['../class_qwt_plot_item.html#ab149ac85e233ce9cedf2f2f2af871bf3a73007ac5158d0ac857af2c6dcecf2712',1,'QwtPlotItem']]], + ['rtti_5fplotscale',['Rtti_PlotScale',['../class_qwt_plot_item.html#ab149ac85e233ce9cedf2f2f2af871bf3a386936d7e0186eabeb833a51cc4fb1cc',1,'QwtPlotItem']]], + ['rtti_5fplotshape',['Rtti_PlotShape',['../class_qwt_plot_item.html#ab149ac85e233ce9cedf2f2f2af871bf3af18fa4c34b44eaf43e13608c6bd7c7b7',1,'QwtPlotItem']]], + ['rtti_5fplotspectrocurve',['Rtti_PlotSpectroCurve',['../class_qwt_plot_item.html#ab149ac85e233ce9cedf2f2f2af871bf3a27c1741ae71fad58da835b747246015d',1,'QwtPlotItem']]], + ['rtti_5fplotspectrogram',['Rtti_PlotSpectrogram',['../class_qwt_plot_item.html#ab149ac85e233ce9cedf2f2f2af871bf3ad67d72195856e6fd8112e1b310f3acb7',1,'QwtPlotItem']]], + ['rtti_5fplotsvg',['Rtti_PlotSVG',['../class_qwt_plot_item.html#ab149ac85e233ce9cedf2f2f2af871bf3a3aabc62d4c006ab40dd3e01db692ab4a',1,'QwtPlotItem']]], + ['rtti_5fplottextlabel',['Rtti_PlotTextLabel',['../class_qwt_plot_item.html#ab149ac85e233ce9cedf2f2f2af871bf3ae6f046fd43f578ad8a59243e6e665167',1,'QwtPlotItem']]], + ['rtti_5fplottradingcurve',['Rtti_PlotTradingCurve',['../class_qwt_plot_item.html#ab149ac85e233ce9cedf2f2f2af871bf3abcd9cebf717e528cb67458abfbf622dd',1,'QwtPlotItem']]], + ['rtti_5fplotuseritem',['Rtti_PlotUserItem',['../class_qwt_plot_item.html#ab149ac85e233ce9cedf2f2f2af871bf3aa60198228f57f46d4c64e4779107d0dc',1,'QwtPlotItem']]], + ['rtti_5fplotzone',['Rtti_PlotZone',['../class_qwt_plot_item.html#ab149ac85e233ce9cedf2f2f2af871bf3a52b2ec5c64c77a36a103b329a530b606',1,'QwtPlotItem']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/enumvalues_73.html b/ThirdParty/Qwt/doc/html/search/enumvalues_73.html new file mode 100644 index 0000000000..f9e7321204 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/enumvalues_73.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/enumvalues_73.js b/ThirdParty/Qwt/doc/html/search/enumvalues_73.js new file mode 100644 index 0000000000..7d0de8e7a2 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/enumvalues_73.js @@ -0,0 +1,23 @@ +var searchData= +[ + ['scaledcolors',['ScaledColors',['../class_qwt_linear_color_map.html#ac8c5f1991f533b1d25a9a0a0874b7d54a01770189cb40240f2fe7fe2e6c1523f1',1,'QwtLinearColorMap']]], + ['scaleinterest',['ScaleInterest',['../class_qwt_plot_item.html#affbc42460ace9ac725fa825a3f8bfb66a0d1c46890f22ef973d897ab0a9d38971',1,'QwtPlotItem']]], + ['scalesamplestoaxes',['ScaleSamplesToAxes',['../class_qwt_plot_abstract_bar_chart.html#ae1db0e1606747ef46c863c54c210e53aaa436f4537d15dbfac62c864389b12220',1,'QwtPlotAbstractBarChart']]], + ['scalesampletocanvas',['ScaleSampleToCanvas',['../class_qwt_plot_abstract_bar_chart.html#ae1db0e1606747ef46c863c54c210e53aaf63f5c75741674252ac3d788735873d5',1,'QwtPlotAbstractBarChart']]], + ['second',['Second',['../class_qwt_date.html#ad037b999a51cae4d9ab36bf8e7859587aabaf7a7d45288a33590f61fe075b3590',1,'QwtDate']]], + ['secondhand',['SecondHand',['../class_qwt_analog_clock.html#acd8f7e963ae073120684de46821f2cfea2d9426a775588d3afb667ca8e9393c8d',1,'QwtAnalogClock']]], + ['spline',['Spline',['../class_qwt_spline_curve_fitter.html#a8c5e6858f885b5691c30092a950879a8a97f3e821b70470f056b60a883229ec13',1,'QwtSplineCurveFitter']]], + ['stacked',['Stacked',['../class_qwt_plot_multi_bar_chart.html#ac67e03008156171c2dd19de4a46eaceeaa66475ce53f2f8b7d77687cfdf28a810',1,'QwtPlotMultiBarChart']]], + ['star1',['Star1',['../class_qwt_symbol.html#a62f457952470c2076962e83ef2c24d2fa358acf734d29ba274e9f08fa555d8bf5',1,'QwtSymbol']]], + ['star2',['Star2',['../class_qwt_symbol.html#a62f457952470c2076962e83ef2c24d2faee962f0906b5571b20737d8aee796f80',1,'QwtSymbol']]], + ['state',['State',['../class_qwt_painter_command.html#a6619a454c4332c02412611467935b7baaecdaa394f26072749a5f2e1a41639bac',1,'QwtPainterCommand']]], + ['steps',['Steps',['../class_qwt_plot_curve.html#a15998aa80a11ba6ba80eebabaf773f70a18071408a0b9bfe58378c6d81e207b2c',1,'QwtPlotCurve']]], + ['sticks',['Sticks',['../class_qwt_plot_curve.html#a15998aa80a11ba6ba80eebabaf773f70a770b0908599507e5677b6e9ff9913f38',1,'QwtPlotCurve']]], + ['stretch',['Stretch',['../class_qwt_picker.html#ab3c894deed026f392496dd07809a6fd3a86899007b306839db254d6d9712af588',1,'QwtPicker']]], + ['style1',['Style1',['../class_qwt_compass_wind_arrow.html#a55f11e28c9d87c0fb7c306ccd174f2a8a62b689f03b4e974660ce1241942b09fc',1,'QwtCompassWindArrow']]], + ['style2',['Style2',['../class_qwt_compass_wind_arrow.html#a55f11e28c9d87c0fb7c306ccd174f2a8a44a462b3f0fa85bf3fa8dc421484e529',1,'QwtCompassWindArrow']]], + ['styled',['Styled',['../class_qwt_knob.html#addd00357b45752377aec83a3ab7208beaff19cfc4c98c17198e25d519c45d65ea',1,'QwtKnob']]], + ['sunken',['Sunken',['../class_qwt_dial.html#a7472124cb120352e8538430ab48c2386ae1388e8ff1a378e22cd082fcb46aa685',1,'QwtDial::Sunken()'],['../class_qwt_knob.html#addd00357b45752377aec83a3ab7208bea599810d6e366e66eaa7f662f1424e7ed',1,'QwtKnob::Sunken()'],['../class_qwt_plot_g_l_canvas.html#a6ce3b3cb6888443dfadca2399a632830ae707e3b005592b559a8093b94b08d9c0',1,'QwtPlotGLCanvas::Sunken()']]], + ['svgdocument',['SvgDocument',['../class_qwt_symbol.html#a62f457952470c2076962e83ef2c24d2fa6e9400c5e295122c0fa825d40d13bb73',1,'QwtSymbol']]], + ['symmetric',['Symmetric',['../class_qwt_scale_engine.html#a7548418e0896d75eec164bfa2ba3ff5fab3931d404b68708d0c6eaf87ae744fc9',1,'QwtScaleEngine']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/enumvalues_74.html b/ThirdParty/Qwt/doc/html/search/enumvalues_74.html new file mode 100644 index 0000000000..0d69a0acb0 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/enumvalues_74.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/enumvalues_74.js b/ThirdParty/Qwt/doc/html/search/enumvalues_74.js new file mode 100644 index 0000000000..8502e51fda --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/enumvalues_74.js @@ -0,0 +1,15 @@ +var searchData= +[ + ['textext',['TeXText',['../class_qwt_text.html#a63e0d6a59a427a37ed0bfa71b782fd76af31a767faf2f7e322941866c6140ddc6',1,'QwtText']]], + ['thinstyle',['ThinStyle',['../class_qwt_compass_magnet_needle.html#aee1d882c6ec8b680b94b59b5710a92a5ab63a2dd26ef14c2aaf9763bc24a8bdac',1,'QwtCompassMagnetNeedle']]], + ['tick',['Tick',['../class_qwt_knob.html#a7254d94e76a74228637931fb75939b95a5ccaa93ece2f928a1167b423339826d9',1,'QwtKnob']]], + ['ticks',['Ticks',['../class_qwt_abstract_scale_draw.html#a26215d06a4d48adf401d0aa05d4193c5a1f23d080ce1229a0c4f70469e88acce0',1,'QwtAbstractScaleDraw']]], + ['titleinverted',['TitleInverted',['../class_qwt_scale_widget.html#a95903255246c9da84e7388b567354c8fac6160b1d9f11f92db884ff26da8e2637',1,'QwtScaleWidget']]], + ['toplegend',['TopLegend',['../class_qwt_plot.html#a31aacb65b5c049dde8c34a0d8482661ba0ee6820a1e8b56737958b738ca23ae34',1,'QwtPlot']]], + ['topscale',['TopScale',['../class_qwt_scale_draw.html#acd7ceeeac592ef08530788580b461c66a2386da707d8f736701b8ab98f778648c',1,'QwtScaleDraw']]], + ['toptobottom',['TopToBottom',['../class_qwt_column_rect.html#a70bb2c6f1f8dabe3bc00793740e0908ba82a13d6063cc299b78ebe1a90a1f39da',1,'QwtColumnRect']]], + ['trailingscale',['TrailingScale',['../class_qwt_slider.html#a120d984d7c519578eed88c4fe97cb1a7a2f836c58c76f5a8ed3c905d699b3f439',1,'QwtSlider::TrailingScale()'],['../class_qwt_thermo.html#a4d7af32d29d1cc18e23b9143cf7ad498aaf66e72accc5a41142773f586158c067',1,'QwtThermo::TrailingScale()']]], + ['triangle',['Triangle',['../class_qwt_knob.html#a7254d94e76a74228637931fb75939b95a69258df5bb213fe4f7da5362470d8f85',1,'QwtKnob::Triangle()'],['../class_qwt_symbol.html#a62f457952470c2076962e83ef2c24d2fa559fad30c36d3e3e2ecad4a21122be79',1,'QwtSymbol::Triangle()']]], + ['trianglestyle',['TriangleStyle',['../class_qwt_compass_magnet_needle.html#aee1d882c6ec8b680b94b59b5710a92a5ad2ba960c4dae88e36da39f6b62798f3b',1,'QwtCompassMagnetNeedle']]], + ['tube',['Tube',['../class_qwt_plot_interval_curve.html#aaef834575b923e1b317f4a86b2d97cd2a786c87eb6dcc86d0fea802043904a647',1,'QwtPlotIntervalCurve']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/enumvalues_75.html b/ThirdParty/Qwt/doc/html/search/enumvalues_75.html new file mode 100644 index 0000000000..9c14af2d22 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/enumvalues_75.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/enumvalues_75.js b/ThirdParty/Qwt/doc/html/search/enumvalues_75.js new file mode 100644 index 0000000000..eb7880743a --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/enumvalues_75.js @@ -0,0 +1,8 @@ +var searchData= +[ + ['usercurve',['UserCurve',['../class_qwt_plot_curve.html#a15998aa80a11ba6ba80eebabaf773f70a7d8b49e6cead1de23860e1c68d17dee3',1,'QwtPlotCurve::UserCurve()'],['../class_qwt_plot_interval_curve.html#aaef834575b923e1b317f4a86b2d97cd2a0ba2b869afe22c1213d7e34590775b0e',1,'QwtPlotIntervalCurve::UserCurve()']]], + ['userrubberband',['UserRubberBand',['../class_qwt_picker.html#ab36c79d8ff20aba5b778d2823c1f7894a96f40f8cc50bd940f0338a68ba159b8e',1,'QwtPicker']]], + ['userstyle',['UserStyle',['../class_qwt_column_symbol.html#aaace508375eef3ee23ed6c47b1d65ef2aa9a5f984f62fb53ce3eeea35be3b0536',1,'QwtColumnSymbol::UserStyle()'],['../class_qwt_plot_histogram.html#a3ba21c3aef994daf7b848ccf71b0dbc5a586b4f119cfbfe62de143c836227c06e',1,'QwtPlotHistogram::UserStyle()'],['../class_qwt_symbol.html#a62f457952470c2076962e83ef2c24d2faed4c49ccbda1c85bdc6ea399e8d8cca8',1,'QwtSymbol::UserStyle()']]], + ['usersymbol',['UserSymbol',['../class_qwt_interval_symbol.html#a8fe960fd50b3ad08765ef8bb632ad77ea40c2cb30f61f7ad63ff20482efd0e7b0',1,'QwtIntervalSymbol::UserSymbol()'],['../class_qwt_plot_trading_curve.html#af1ca10dd8c3f1ef662d40fc8a113b44aadd5f8436afcc44afe7b6204a7e1329c1',1,'QwtPlotTradingCurve::UserSymbol()']]], + ['utriangle',['UTriangle',['../class_qwt_symbol.html#a62f457952470c2076962e83ef2c24d2fabf99d9afabd98be69e2ee377bbfa85bf',1,'QwtSymbol']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/enumvalues_76.html b/ThirdParty/Qwt/doc/html/search/enumvalues_76.html new file mode 100644 index 0000000000..488a028197 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/enumvalues_76.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/enumvalues_76.js b/ThirdParty/Qwt/doc/html/search/enumvalues_76.js new file mode 100644 index 0000000000..16ddf1ed40 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/enumvalues_76.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['vline',['VLine',['../class_qwt_plot_marker.html#a297efa835423bfa5a870bbc8ff1c623ba55ab75371699cd7c0e55c494da6454dc',1,'QwtPlotMarker::VLine()'],['../class_qwt_symbol.html#a62f457952470c2076962e83ef2c24d2fa041fb14668884dd95527a34beab22fd8',1,'QwtSymbol::VLine()']]], + ['vlinerubberband',['VLineRubberBand',['../class_qwt_picker.html#ab36c79d8ff20aba5b778d2823c1f7894a0eb6ef7b155e41ea015afc7f68940a86',1,'QwtPicker']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/enumvalues_77.html b/ThirdParty/Qwt/doc/html/search/enumvalues_77.html new file mode 100644 index 0000000000..966c1413ef --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/enumvalues_77.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/enumvalues_77.js b/ThirdParty/Qwt/doc/html/search/enumvalues_77.js new file mode 100644 index 0000000000..8e854491b9 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/enumvalues_77.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['weedoutpoints',['WeedOutPoints',['../class_qwt_point_mapper.html#aafc07ceadb3f311057037ca8680e1c23a288f41a8e4d53c895f7bffaaa9b5d9e4',1,'QwtPointMapper']]], + ['week',['Week',['../class_qwt_date.html#ad037b999a51cae4d9ab36bf8e7859587ae204b4e8ce8679ba9ac378e41bd77b2b',1,'QwtDate']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/enumvalues_78.html b/ThirdParty/Qwt/doc/html/search/enumvalues_78.html new file mode 100644 index 0000000000..0ce33de94b --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/enumvalues_78.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/enumvalues_78.js b/ThirdParty/Qwt/doc/html/search/enumvalues_78.js new file mode 100644 index 0000000000..e94c59418a --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/enumvalues_78.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['xbottom',['xBottom',['../class_qwt_plot.html#a81df699dcf9dde0752c0726b5f31e271ad5566960e78f2473c1a1e853def4c4ac',1,'QwtPlot']]], + ['xcross',['XCross',['../class_qwt_symbol.html#a62f457952470c2076962e83ef2c24d2faa734e8b9433131230af5d8c319b5529e',1,'QwtSymbol']]], + ['xtop',['xTop',['../class_qwt_plot.html#a81df699dcf9dde0752c0726b5f31e271ae51eb7525eb3f9f806e659614018beb8',1,'QwtPlot']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/enumvalues_79.html b/ThirdParty/Qwt/doc/html/search/enumvalues_79.html new file mode 100644 index 0000000000..53cd69831a --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/enumvalues_79.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/enumvalues_79.js b/ThirdParty/Qwt/doc/html/search/enumvalues_79.js new file mode 100644 index 0000000000..d766d0b48b --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/enumvalues_79.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['year',['Year',['../class_qwt_date.html#ad037b999a51cae4d9ab36bf8e7859587ae306523ed94ccf930afb811ff7a735ab',1,'QwtDate']]], + ['yleft',['yLeft',['../class_qwt_plot.html#a81df699dcf9dde0752c0726b5f31e271a1bb1fbc11e31ebfa8bf72356f6837b17',1,'QwtPlot']]], + ['yright',['yRight',['../class_qwt_plot.html#a81df699dcf9dde0752c0726b5f31e271a1de23b30c6b0c08aefe06d6265b65155',1,'QwtPlot']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/functions_61.html b/ThirdParty/Qwt/doc/html/search/functions_61.html new file mode 100644 index 0000000000..d68c74892b --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/functions_61.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/functions_61.js b/ThirdParty/Qwt/doc/html/search/functions_61.js new file mode 100644 index 0000000000..b911d792ee --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/functions_61.js @@ -0,0 +1,48 @@ +var searchData= +[ + ['abstractscaledraw',['abstractScaleDraw',['../class_qwt_abstract_scale.html#ab3c5f30892792e5ca3d84f4409ef6216',1,'QwtAbstractScale::abstractScaleDraw() const '],['../class_qwt_abstract_scale.html#aa61afdff037ef745a6dad686537cdb96',1,'QwtAbstractScale::abstractScaleDraw()']]], + ['accept',['accept',['../class_qwt_picker.html#a2c93d65c27fadf2f2522e81f04358604',1,'QwtPicker::accept()'],['../class_qwt_plot_zoomer.html#afe2a439f5085602e97c403d451561dd5',1,'QwtPlotZoomer::accept()']]], + ['activate',['activate',['../class_qwt_plot_layout.html#af940812bf4a9d94dac534734168d4ac8',1,'QwtPlotLayout']]], + ['activated',['activated',['../class_qwt_picker.html#a89a2c67a355d6b9bc54348e2f25fe139',1,'QwtPicker']]], + ['addcolorstop',['addColorStop',['../class_qwt_linear_color_map.html#aa7162a034e882e752c15051439bb2c99',1,'QwtLinearColorMap']]], + ['added',['added',['../class_qwt_set_sample.html#ab9c619f327e1bf3feca7f96d0ba44c24',1,'QwtSetSample']]], + ['additem',['addItem',['../class_qwt_dyn_grid_layout.html#a3ac3ace65c84e16fba7fe83cd795eea1',1,'QwtDynGridLayout']]], + ['adjustedpoints',['adjustedPoints',['../class_qwt_picker.html#ad09e8d2241f23b05377155c2f86010f5',1,'QwtPicker']]], + ['alarmbrush',['alarmBrush',['../class_qwt_thermo.html#a103f3f7f66d71931e7af95605c03028b',1,'QwtThermo']]], + ['alarmenabled',['alarmEnabled',['../class_qwt_thermo.html#a98d686ce15953eecd774e6c1dbb75286',1,'QwtThermo']]], + ['alarmlevel',['alarmLevel',['../class_qwt_thermo.html#a5ed8270840b7e23c539fdd67c3b6b846',1,'QwtThermo']]], + ['alarmrect',['alarmRect',['../class_qwt_thermo.html#acec691cc665beed149c6559e666d55e6',1,'QwtThermo']]], + ['align',['align',['../class_qwt_linear_scale_engine.html#a433918756a04fb25f29ed53f5d20bfd4',1,'QwtLinearScaleEngine::align()'],['../class_qwt_log_scale_engine.html#a9f0b3b6855c6fd4eda0855078b480206',1,'QwtLogScaleEngine::align()']]], + ['aligncanvastoscale',['alignCanvasToScale',['../class_qwt_plot_layout.html#a12544e8300be44585bb2b4963e909e77',1,'QwtPlotLayout']]], + ['aligndate',['alignDate',['../class_qwt_date_scale_engine.html#aba0a765afc53e8be743a8c4fc5bcca21',1,'QwtDateScaleEngine']]], + ['alignlegend',['alignLegend',['../class_qwt_plot_layout.html#a38c8c706367c67e36664bf901fd14f36',1,'QwtPlotLayout']]], + ['alignment',['alignment',['../class_qwt_knob.html#a8434f82e42972a470b59ef9296880c28',1,'QwtKnob::alignment()'],['../class_qwt_plot_legend_item.html#a33fd4ca3a52bdc4cf046103c1fc797b3',1,'QwtPlotLegendItem::alignment()'],['../class_qwt_scale_draw.html#ad0425d29e919f60021322b178661b6e5',1,'QwtScaleDraw::alignment()'],['../class_qwt_scale_widget.html#a96c6c060e258e21e609a0f99e59c5e33',1,'QwtScaleWidget::alignment()']]], + ['alignscales',['alignScales',['../class_qwt_plot_layout.html#a7d1690e687b2bff56fdccdca39e7b326',1,'QwtPlotLayout']]], + ['alpha',['alpha',['../class_qwt_plot_raster_item.html#a96b2faa0bc0fe086bff1abe72bcb2016',1,'QwtPlotRasterItem']]], + ['append',['append',['../class_qwt_picker.html#a5dd2e0ce6b2a6cc50e345ec13aef9255',1,'QwtPicker::append()'],['../class_qwt_plot_picker.html#a86a68e8ea235b9514084b729c75803ea',1,'QwtPlotPicker::append()']]], + ['appended',['appended',['../class_qwt_picker.html#ad52219271a7c8efab35ded14ac89827a',1,'QwtPicker::appended()'],['../class_qwt_plot_picker.html#a558f8fdf8645e202bd5324b766b445f7',1,'QwtPlotPicker::appended()']]], + ['applyproperties',['applyProperties',['../class_qwt_plot.html#ae7e93c7112d16cbd299cf3cbc0bf9f9f',1,'QwtPlot']]], + ['arrowsize',['arrowSize',['../class_qwt_arrow_button.html#a544fc12a1756eb2b703ab9a2903240cb',1,'QwtArrowButton']]], + ['arrowtype',['arrowType',['../class_qwt_arrow_button.html#a0a2a1b7dfff38ef00a0495fcb61d21a4',1,'QwtArrowButton']]], + ['aspectratio',['aspectRatio',['../class_qwt_plot_rescaler.html#a896b940761b437516043695d2687dd1c',1,'QwtPlotRescaler']]], + ['attach',['attach',['../class_qwt_plot_item.html#aeb2f676533ccae3436bf578824e2165e',1,'QwtPlotItem']]], + ['attributes',['attributes',['../class_qwt_scale_engine.html#a044961cfa3be3ac86d49610c3881df08',1,'QwtScaleEngine']]], + ['autodelete',['autoDelete',['../class_qwt_plot_dict.html#a10dfae8b454fa4258b0372366013507a',1,'QwtPlotDict']]], + ['autorefresh',['autoRefresh',['../class_qwt_plot.html#aea78ab565d05b69b8730a4af2a11f07e',1,'QwtPlot']]], + ['autoreplot',['autoReplot',['../class_qwt_plot.html#af14053ca41be0f9c6f820ed3c4379831',1,'QwtPlot']]], + ['autoscale',['autoScale',['../class_qwt_date_scale_engine.html#a6c7e5c416ff4a1d3cd5f029793a31c34',1,'QwtDateScaleEngine::autoScale()'],['../class_qwt_scale_engine.html#aa27323d6d9d5348bd253a61b45e4785b',1,'QwtScaleEngine::autoScale()'],['../class_qwt_linear_scale_engine.html#ad0f1d825e70eb7a1deb15875a8093cff',1,'QwtLinearScaleEngine::autoScale()'],['../class_qwt_log_scale_engine.html#a5020a25dde6a7d4dbf16012445c4cc81',1,'QwtLogScaleEngine::autoScale()']]], + ['axisautoscale',['axisAutoScale',['../class_qwt_plot.html#a112a1bc0b4f7132b10bc5b4efae45686',1,'QwtPlot']]], + ['axisenabled',['axisEnabled',['../class_qwt_plot.html#aac5107a1ec8836b53f084a5b1bb8cc43',1,'QwtPlot']]], + ['axisfont',['axisFont',['../class_qwt_plot.html#a637e2261d7722f00b2ce2bacadca8ffa',1,'QwtPlot']]], + ['axisinterval',['axisInterval',['../class_qwt_plot.html#ab4c5ab07abc1252a325d8ba2627ab5d3',1,'QwtPlot']]], + ['axismaxmajor',['axisMaxMajor',['../class_qwt_plot.html#a250fdf9506a71857d183983823a491d4',1,'QwtPlot']]], + ['axismaxminor',['axisMaxMinor',['../class_qwt_plot.html#adbe9b0fcfaf8a5baa49a3cb4ed425b42',1,'QwtPlot']]], + ['axisscalediv',['axisScaleDiv',['../class_qwt_plot.html#a8b5b2d9bc11dd893fe6b09c94c228a81',1,'QwtPlot']]], + ['axisscaledraw',['axisScaleDraw',['../class_qwt_plot.html#a2ff0d0733c0ce8bb275cfde23bf9736c',1,'QwtPlot::axisScaleDraw(int axisId) const '],['../class_qwt_plot.html#abbb49f1730c3ea9f636c032f81e5a87e',1,'QwtPlot::axisScaleDraw(int axisId)']]], + ['axisscaleengine',['axisScaleEngine',['../class_qwt_plot.html#a619b65bb95090ab5a528e33a5014ae4f',1,'QwtPlot::axisScaleEngine(int axisId)'],['../class_qwt_plot.html#a3e29973bcd6c879056ad655de8f667d8',1,'QwtPlot::axisScaleEngine(int axisId) const ']]], + ['axisstepsize',['axisStepSize',['../class_qwt_plot.html#a6f5fa5348dec97f2531f7ec58e727bee',1,'QwtPlot']]], + ['axistitle',['axisTitle',['../class_qwt_plot.html#a7807148d386457345025571e2a8e0983',1,'QwtPlot']]], + ['axisvalid',['axisValid',['../class_qwt_plot.html#ac02c033b024a4ecbefcf1b0e93c91205',1,'QwtPlot']]], + ['axiswidget',['axisWidget',['../class_qwt_plot.html#a6b495d9b17962be6e098026441a1f7b8',1,'QwtPlot::axisWidget(int axisId) const '],['../class_qwt_plot.html#ae3386e1d38f70864c4c019c0eb6a3d9d',1,'QwtPlot::axisWidget(int axisId)']]], + ['azimuth',['azimuth',['../class_qwt_point_polar.html#afac65de2dca25b0b6a6c5fb917fff424',1,'QwtPointPolar']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/functions_62.html b/ThirdParty/Qwt/doc/html/search/functions_62.html new file mode 100644 index 0000000000..5134d2d296 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/functions_62.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/functions_62.js b/ThirdParty/Qwt/doc/html/search/functions_62.js new file mode 100644 index 0000000000..649eb22952 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/functions_62.js @@ -0,0 +1,29 @@ +var searchData= +[ + ['backgroundbrush',['backgroundBrush',['../class_qwt_plot_legend_item.html#a7c3ab70e6df9d2c3bad203f7c505ae0c',1,'QwtPlotLegendItem::backgroundBrush()'],['../class_qwt_text.html#a46bb4836482e4fe554f5079871343ba6',1,'QwtText::backgroundBrush()']]], + ['backgroundmode',['backgroundMode',['../class_qwt_plot_legend_item.html#a550f9c49a2905e90ab7c6459105b43b2',1,'QwtPlotLegendItem']]], + ['backingstore',['backingStore',['../class_qwt_painter.html#ad1acc33fc6d94791852d9c07d7e1e94e',1,'QwtPainter::backingStore()'],['../class_qwt_plot_canvas.html#aa46dfe9b0d4a3a1d81ef1fca66c2093c',1,'QwtPlotCanvas::backingStore()']]], + ['bartitle',['barTitle',['../class_qwt_plot_bar_chart.html#a346fd4fbd04c48f3e28dff985820aea2',1,'QwtPlotBarChart']]], + ['bartitles',['barTitles',['../class_qwt_plot_multi_bar_chart.html#ab07fa887580b77358b787e1ec52c9c3a',1,'QwtPlotMultiBarChart']]], + ['base',['base',['../class_qwt_scale_engine.html#a5bfe4467f5b311b3879253b0a4470a2c',1,'QwtScaleEngine']]], + ['baseline',['baseline',['../class_qwt_plot_abstract_bar_chart.html#a89a0209b5af6036b0d17ffdb8659121b',1,'QwtPlotAbstractBarChart::baseline()'],['../class_qwt_plot_curve.html#a93e390b172c5fa9ffd534aeb2d572c0e',1,'QwtPlotCurve::baseline()'],['../class_qwt_plot_histogram.html#a1e15762e54960e7b1de75b542e8024bd',1,'QwtPlotHistogram::baseline()']]], + ['begin',['begin',['../class_qwt_picker.html#a49cb19aea451e275c5d376235e5a1d83',1,'QwtPicker::begin()'],['../class_qwt_plot_zoomer.html#aa54bb05797c0468c0f8de4217dce24dd',1,'QwtPlotZoomer::begin()']]], + ['borderdistance',['borderDistance',['../class_qwt_plot_legend_item.html#abd3614864cb8a2870c5e94aaa2e09875',1,'QwtPlotLegendItem::borderDistance()'],['../class_qwt_plot_scale_item.html#a3200035a9dd88e07f154ef4289a952c2',1,'QwtPlotScaleItem::borderDistance()']]], + ['borderflags',['borderFlags',['../class_qwt_interval.html#a885306d2a8538fe37c1446853aa18018',1,'QwtInterval']]], + ['borderpath',['borderPath',['../class_qwt_plot_canvas.html#a924b8de928d2c1c6eea611306b3e7170',1,'QwtPlotCanvas::borderPath()'],['../class_qwt_plot_g_l_canvas.html#a09dbce4a8649eaa31910cb51147d2b41',1,'QwtPlotGLCanvas::borderPath()']]], + ['borderpen',['borderPen',['../class_qwt_plot_legend_item.html#aef9f3986e55bfd53513b7c45fad240f3',1,'QwtPlotLegendItem::borderPen()'],['../class_qwt_text.html#ae06c3ab1a6396962e4035e7ec1452db6',1,'QwtText::borderPen()']]], + ['borderradius',['borderRadius',['../class_qwt_plot_canvas.html#a76b086055480789c4410eb114789fe2e',1,'QwtPlotCanvas::borderRadius()'],['../class_qwt_plot_legend_item.html#a2dc0926a766161c962c396b63cbc2778',1,'QwtPlotLegendItem::borderRadius()'],['../class_qwt_text.html#a21b879281d4e07f5ffe6e4465c176dc1',1,'QwtText::borderRadius()']]], + ['borderwidth',['borderWidth',['../class_qwt_knob.html#a3e19de6a4762aeaf2b95266b20961574',1,'QwtKnob::borderWidth()'],['../class_qwt_slider.html#aacc125aac3a5d593a4834957de28469c',1,'QwtSlider::borderWidth()'],['../class_qwt_thermo.html#aa3e9ce551b041571bdc2688930cf553c',1,'QwtThermo::borderWidth()'],['../class_qwt_wheel.html#a2bb051e6a069283c574b7ea278bbb96f',1,'QwtWheel::borderWidth()']]], + ['bounded',['bounded',['../class_qwt_scale_div.html#a9b73d97caf5ee1020d4d5f60716d4274',1,'QwtScaleDiv::bounded()'],['../class_qwt_transform.html#a2703fc5855720201f46ed9404271a527',1,'QwtTransform::bounded()'],['../class_qwt_log_transform.html#ab98c0508df005438dea8baa6c512b799',1,'QwtLogTransform::bounded()']]], + ['boundinginterval',['boundingInterval',['../class_qwt_o_h_l_c_sample.html#ae706a8617d441a416278e95f0688122b',1,'QwtOHLCSample']]], + ['boundinglabelrect',['boundingLabelRect',['../class_qwt_scale_draw.html#a364846c2b4be817c9a645bd226cdd6e7',1,'QwtScaleDraw']]], + ['boundingrect',['boundingRect',['../class_qwt_dial.html#a0d52d45d3a693e66d5799e285efdd34d',1,'QwtDial::boundingRect()'],['../class_qwt_graphic.html#a9c164c590611ddea0973db2917f65690',1,'QwtGraphic::boundingRect()'],['../class_qwt_plot_bar_chart.html#a004aec33aa7412c0d8fc23a94cf2e1e0',1,'QwtPlotBarChart::boundingRect()'],['../class_qwt_plot_histogram.html#a683686684263a384cd609c484330bb1f',1,'QwtPlotHistogram::boundingRect()'],['../class_qwt_plot_interval_curve.html#ae4b1140a52682976bb5946a772b7da7c',1,'QwtPlotIntervalCurve::boundingRect()'],['../class_qwt_plot_item.html#aec3c408e14af30b82b52c1197310eb21',1,'QwtPlotItem::boundingRect()'],['../class_qwt_plot_marker.html#a270ada9e0a68dcfd5cf0f7629af898a2',1,'QwtPlotMarker::boundingRect()'],['../class_qwt_plot_multi_bar_chart.html#a598ffecdc85925d084ac4346a675bc4b',1,'QwtPlotMultiBarChart::boundingRect()'],['../class_qwt_plot_raster_item.html#ad96073173caf80301e108a6d8b0648e9',1,'QwtPlotRasterItem::boundingRect()'],['../class_qwt_plot_series_item.html#a7a0fffd64c5416a8f18df00ab8a90ea3',1,'QwtPlotSeriesItem::boundingRect()'],['../class_qwt_plot_shape_item.html#a79d76e0b482abd8124f0226a15c1d3c0',1,'QwtPlotShapeItem::boundingRect()'],['../class_qwt_plot_svg_item.html#af358905da83fb1c67631b7fba9539daa',1,'QwtPlotSvgItem::boundingRect()'],['../class_qwt_plot_trading_curve.html#a1d0d5becf5adfce57f2083e73e32b6fb',1,'QwtPlotTradingCurve::boundingRect()'],['../class_qwt_plot_zone_item.html#a293eb96989d4678ec82ede787d0b4583',1,'QwtPlotZoneItem::boundingRect()'],['../class_qwt_point_array_data.html#a2d8b421115ba860e9d12a2266eeaef3b',1,'QwtPointArrayData::boundingRect()'],['../class_qwt_c_pointer_data.html#aecc3e98a3b2c4350212fa7b9e97110aa',1,'QwtCPointerData::boundingRect()'],['../class_qwt_synthetic_point_data.html#a89296d373856825047f48e86d7731b0a',1,'QwtSyntheticPointData::boundingRect()'],['../class_qwt_point_mapper.html#a1dd7644e312d7d05ae238759470180d4',1,'QwtPointMapper::boundingRect()'],['../class_qwt_series_data.html#aedb969ba51a27d88d26ad7f7cb1c2c7f',1,'QwtSeriesData::boundingRect()'],['../class_qwt_point_series_data.html#ad5cf93cd9f518be6b0d910982cabd96d',1,'QwtPointSeriesData::boundingRect()'],['../class_qwt_point3_d_series_data.html#a94ea1834516a2a484712723b5c9625ca',1,'QwtPoint3DSeriesData::boundingRect()'],['../class_qwt_interval_series_data.html#afd9a41faed021eddcc1a9a36d15350d2',1,'QwtIntervalSeriesData::boundingRect()'],['../class_qwt_set_series_data.html#a63aef8f3405883ab886b06cd27aabe7c',1,'QwtSetSeriesData::boundingRect()'],['../class_qwt_trading_chart_data.html#ae39ddc18e1669fb0be87ff6be92c1a96',1,'QwtTradingChartData::boundingRect()'],['../class_qwt_symbol.html#af7904c7e672fb871dd4b2eb852a745c5',1,'QwtSymbol::boundingRect()']]], + ['brush',['brush',['../class_qwt_interval_symbol.html#a925cdf560cbeb857ad4c2176b552aacc',1,'QwtIntervalSymbol::brush()'],['../class_qwt_plot_curve.html#a72b678ebb8e4821c1f85351292ce5697',1,'QwtPlotCurve::brush()'],['../class_qwt_plot_histogram.html#ae72360d1812a8137a0c7ee6b6a5ebebd',1,'QwtPlotHistogram::brush()'],['../class_qwt_plot_interval_curve.html#ad4aaae77788ba7bafd87ca8ec1970901',1,'QwtPlotIntervalCurve::brush()'],['../class_qwt_plot_shape_item.html#a5ab8814c57a33fa4bf8250515e85a237',1,'QwtPlotShapeItem::brush()'],['../class_qwt_plot_zone_item.html#a1c8e23cf9d0558749126891cc0584675',1,'QwtPlotZoneItem::brush()'],['../class_qwt_symbol.html#a7260c1fa79009661cd0723e6c2b9ef87',1,'QwtSymbol::brush()']]], + ['buildinterval',['buildInterval',['../class_qwt_scale_engine.html#ac9d1a77655b633ee4f165eb5c43a4374',1,'QwtScaleEngine']]], + ['buildmajorticks',['buildMajorTicks',['../class_qwt_linear_scale_engine.html#a00844c641535d54074f235d1fe3430f5',1,'QwtLinearScaleEngine::buildMajorTicks()'],['../class_qwt_log_scale_engine.html#a7918a44fcf0e308f23a687610778bbeb',1,'QwtLogScaleEngine::buildMajorTicks()']]], + ['buildminorticks',['buildMinorTicks',['../class_qwt_linear_scale_engine.html#ae65f6964ee4bd4bfa19ebf1134eb9d69',1,'QwtLinearScaleEngine::buildMinorTicks()'],['../class_qwt_log_scale_engine.html#adf9985e35cbacb8ba48378c3781a2071',1,'QwtLogScaleEngine::buildMinorTicks()']]], + ['buildnaturalspline',['buildNaturalSpline',['../class_qwt_spline.html#a1cdf09e841dd6a721eb788914273c484',1,'QwtSpline']]], + ['buildperiodicspline',['buildPeriodicSpline',['../class_qwt_spline.html#a8184717f8c018e69fabd1e33ac68ef19',1,'QwtSpline']]], + ['buildticks',['buildTicks',['../class_qwt_linear_scale_engine.html#a7d6a7687ea03a3ce9cde3478f7f21146',1,'QwtLinearScaleEngine::buildTicks()'],['../class_qwt_log_scale_engine.html#a5ab57d233a5722d74426f4c7c5f1b9a9',1,'QwtLogScaleEngine::buildTicks()']]], + ['buttonreleased',['buttonReleased',['../class_qwt_counter.html#a694ed7277e137e44bccc5918b4c15ecc',1,'QwtCounter']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/functions_63.html b/ThirdParty/Qwt/doc/html/search/functions_63.html new file mode 100644 index 0000000000..9114d820c9 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/functions_63.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/functions_63.js b/ThirdParty/Qwt/doc/html/search/functions_63.js new file mode 100644 index 0000000000..a23eb43f39 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/functions_63.js @@ -0,0 +1,56 @@ +var searchData= +[ + ['cachepolicy',['cachePolicy',['../class_qwt_plot_raster_item.html#ac953db5d88084f416b4dbc3ca8a323f3',1,'QwtPlotRasterItem::cachePolicy()'],['../class_qwt_symbol.html#a7ee06a50e28aacecfb7df83f63c22a41',1,'QwtSymbol::cachePolicy()']]], + ['canvas',['canvas',['../class_qwt_plot.html#a53f836bb4ec09c766e3d871ea4be28f7',1,'QwtPlot::canvas()'],['../class_qwt_plot.html#ad8a2c2c9739c1bc8b61b7dc191809f67',1,'QwtPlot::canvas() const '],['../class_qwt_plot_magnifier.html#a833e0c42a9ffdc92a60a1d1b0828b8ec',1,'QwtPlotMagnifier::canvas()'],['../class_qwt_plot_magnifier.html#a435c1df676fcfcc27206e2746137aadf',1,'QwtPlotMagnifier::canvas() const '],['../class_qwt_plot_panner.html#a372898a83f51e2b85aadb92f893d6235',1,'QwtPlotPanner::canvas()'],['../class_qwt_plot_panner.html#abac1d0855829801a7afa02064f023950',1,'QwtPlotPanner::canvas() const '],['../class_qwt_plot_picker.html#ad2a03a80f35826ed6256f039da2b4bf2',1,'QwtPlotPicker::canvas()'],['../class_qwt_plot_picker.html#a8cded1988abdd15b190f73ab2bb42842',1,'QwtPlotPicker::canvas() const '],['../class_qwt_plot_rescaler.html#ad4aa9bf81032b822b848774ee21142ce',1,'QwtPlotRescaler::canvas()'],['../class_qwt_plot_rescaler.html#ae324f6b86350254e1623853bf9ad9f77',1,'QwtPlotRescaler::canvas() const ']]], + ['canvasbackground',['canvasBackground',['../class_qwt_plot.html#a8e2efd0e10ae3b72773b5ab78f67375c',1,'QwtPlot']]], + ['canvasmap',['canvasMap',['../class_qwt_plot.html#aff5efd21f11ec91fb8f791799cb4db2f',1,'QwtPlot']]], + ['canvasmargin',['canvasMargin',['../class_qwt_plot_layout.html#aacf659495ecc45367eacf5f4b2aeca7d',1,'QwtPlotLayout']]], + ['canvasrect',['canvasRect',['../class_qwt_plot_layout.html#ad117328fb4ce4041bb2bb16a0392d416',1,'QwtPlotLayout']]], + ['canvasresizeevent',['canvasResizeEvent',['../class_qwt_plot_rescaler.html#a5490a4a1b576b1118c095cc54810e2aa',1,'QwtPlotRescaler']]], + ['ceil',['ceil',['../class_qwt_date.html#ab4d7b043971e13a97a8b5f9edb5eee02',1,'QwtDate']]], + ['ceileps',['ceilEps',['../class_qwt_scale_arithmetic.html#a86da4fc0928457d03201d8b520d7d816',1,'QwtScaleArithmetic']]], + ['center',['center',['../class_qwt_round_scale_draw.html#ae3d163159f0771bc05958faf798a1500',1,'QwtRoundScaleDraw']]], + ['changed',['changed',['../class_qwt_picker.html#ae47a68e89fdd72be75d4d2b92672319e',1,'QwtPicker']]], + ['changeevent',['changeEvent',['../class_qwt_dial.html#a7ba6373fff91cbc545d29c480bf80359',1,'QwtDial::changeEvent()'],['../class_qwt_knob.html#abccdba2f96c353ecc004adfcb19d2db9',1,'QwtKnob::changeEvent()'],['../class_qwt_slider.html#a89e8ecbeb21511a88016e31aa5c12a58',1,'QwtSlider::changeEvent()'],['../class_qwt_thermo.html#abb6858178fa0361ce9c4775944b96352',1,'QwtThermo::changeEvent()']]], + ['checked',['checked',['../class_qwt_legend.html#ae54179a767337c154beaa826c57dda87',1,'QwtLegend::checked()'],['../class_qwt_legend_label.html#a248d0836578ccf15fe56f2fee603e981',1,'QwtLegendLabel::checked()']]], + ['chunksize',['chunkSize',['../class_qwt_weeding_curve_fitter.html#a280b4984a2b2c67f9863bb27e2bb3ed3',1,'QwtWeedingCurveFitter']]], + ['clear',['clear',['../class_qwt_text_label.html#a6674cebd85cf692d154f967887547e11',1,'QwtTextLabel']]], + ['clearlegend',['clearLegend',['../class_qwt_plot_legend_item.html#ad5bf74d642b8a0ccfcc1a278442f94e9',1,'QwtPlotLegendItem']]], + ['clicked',['clicked',['../class_qwt_legend.html#a26619e20d875f1e8c666b982a897244b',1,'QwtLegend::clicked()'],['../class_qwt_legend_label.html#ae37056322967eddf53dbbd94748faa63',1,'QwtLegendLabel::clicked()']]], + ['clipcircle',['clipCircle',['../class_qwt_clipper.html#ab36605186b4a1c411fccb3b68cf1724a',1,'QwtClipper']]], + ['clippolygon',['clipPolygon',['../class_qwt_clipper.html#ab42cda85c068194ae0c60f66ecd12022',1,'QwtClipper::clipPolygon(const QRect &, const QPolygon &, bool closePolygon=false)'],['../class_qwt_clipper.html#adc4aa63cfb8b7ed97311b117f2613f0d',1,'QwtClipper::clipPolygon(const QRectF &, const QPolygon &, bool closePolygon=false)']]], + ['clippolygonf',['clipPolygonF',['../class_qwt_clipper.html#ab7f737adc53ccd730934197359de3c95',1,'QwtClipper']]], + ['clipregion',['clipRegion',['../class_qwt_plot_direct_painter.html#a62f4330f5be1386ef69ed5754aa16678',1,'QwtPlotDirectPainter']]], + ['closepolyline',['closePolyline',['../class_qwt_plot_curve.html#abada791559395b278f9dc4478dffcc6f',1,'QwtPlotCurve']]], + ['closestpoint',['closestPoint',['../class_qwt_plot_curve.html#a47620cb8ca3940f7007f8fb990d614f6',1,'QwtPlotCurve']]], + ['coefficientsa',['coefficientsA',['../class_qwt_spline.html#abbc5c1cf6016fc57050f379250da031e',1,'QwtSpline']]], + ['coefficientsb',['coefficientsB',['../class_qwt_spline.html#a1de897d6cc2d0d8dac840d15d0bb603e',1,'QwtSpline']]], + ['coefficientsc',['coefficientsC',['../class_qwt_spline.html#a27d51429a7447b18a8f05a44b3418f89',1,'QwtSpline']]], + ['color',['color',['../class_qwt_color_map.html#a35f74175e963d18e451a9fd4421ede1f',1,'QwtColorMap::color()'],['../class_qwt_alpha_color_map.html#a4a706714abbd4d82a9a2201a9ecf7aaf',1,'QwtAlphaColorMap::color()'],['../class_qwt_text.html#a8904020d2a906c4c66d8515ba47820fe',1,'QwtText::color()']]], + ['color1',['color1',['../class_qwt_linear_color_map.html#a3ab5066b01409f58e4ad0425474b1530',1,'QwtLinearColorMap']]], + ['color2',['color2',['../class_qwt_linear_color_map.html#a9fa696fff9ec599f0c305f73345ecab3',1,'QwtLinearColorMap']]], + ['colorbarinterval',['colorBarInterval',['../class_qwt_scale_widget.html#a45d81f98abea564eca1ec72dd56edaae',1,'QwtScaleWidget']]], + ['colorbarrect',['colorBarRect',['../class_qwt_scale_widget.html#a5271d10cf0e6097a243aa62beb784c02',1,'QwtScaleWidget']]], + ['colorbarwidth',['colorBarWidth',['../class_qwt_scale_widget.html#aa5877851d15888977621bfe86b945984',1,'QwtScaleWidget']]], + ['colorindex',['colorIndex',['../class_qwt_color_map.html#a762baa2edca8773ec09e0c1c5df2cf04',1,'QwtColorMap::colorIndex()'],['../class_qwt_linear_color_map.html#aa69528213eb7d484466f095c8a9a6efe',1,'QwtLinearColorMap::colorIndex()']]], + ['colormap',['colorMap',['../class_qwt_plot_spectro_curve.html#a901a8ee5d6aa7b6e41eadf8f1bdc1e03',1,'QwtPlotSpectroCurve::colorMap()'],['../class_qwt_plot_spectrogram.html#ac1f691f612643bae921cbc108f8d2b5e',1,'QwtPlotSpectrogram::colorMap()'],['../class_qwt_scale_widget.html#aacbe3acb087a109d9df21062bf5f1726',1,'QwtScaleWidget::colorMap()'],['../class_qwt_thermo.html#a8d9285fdda3f6f26fc0d9aa35b5f021e',1,'QwtThermo::colorMap()'],['../class_qwt_thermo.html#a00e16d590b76602a85ef7bf32533e945',1,'QwtThermo::colorMap() const ']]], + ['colorrange',['colorRange',['../class_qwt_plot_spectro_curve.html#aa495f44361e659e5fd83882e21e56542',1,'QwtPlotSpectroCurve']]], + ['colorstops',['colorStops',['../class_qwt_linear_color_map.html#afaafe752db9de97ec6fba163515f51dd',1,'QwtLinearColorMap']]], + ['colortable',['colorTable',['../class_qwt_color_map.html#a4ccc23356e058783071b06dee437b6d7',1,'QwtColorMap']]], + ['columnrect',['columnRect',['../class_qwt_plot_histogram.html#abbda48a6dc315904e0adb94ee4caf569',1,'QwtPlotHistogram']]], + ['columnsforwidth',['columnsForWidth',['../class_qwt_dyn_grid_layout.html#adf7cc1acc36b41086fb4815633473901',1,'QwtDynGridLayout']]], + ['commands',['commands',['../class_qwt_graphic.html#a9f188c3bbe1cf8b3b24c82c0fd222029',1,'QwtGraphic']]], + ['contains',['contains',['../class_qwt_interval.html#a862ee5d96ed32b991a0bbeed0e836560',1,'QwtInterval::contains()'],['../class_qwt_scale_div.html#ae0c34d8ffac04ab14d1bfaf06cf2b43b',1,'QwtScaleDiv::contains()'],['../class_qwt_scale_engine.html#a36acba98650d011f784641fa4ac43f87',1,'QwtScaleEngine::contains()']]], + ['contentsmask',['contentsMask',['../class_qwt_panner.html#a665cd319422766cdf9cacb96498b0c22',1,'QwtPanner::contentsMask()'],['../class_qwt_plot_panner.html#a01af550a710be3ca051610eda7f979e3',1,'QwtPlotPanner::contentsMask()']]], + ['contentswidget',['contentsWidget',['../class_qwt_legend.html#aa52edeceb553ae703516c984f34d7ab7',1,'QwtLegend::contentsWidget()'],['../class_qwt_legend.html#acd680c0f17f4184e10a3d3136b9836f5',1,'QwtLegend::contentsWidget() const ']]], + ['contourlevels',['contourLevels',['../class_qwt_plot_spectrogram.html#a850b6b098d5859ee96e6f7cd9e05509f',1,'QwtPlotSpectrogram']]], + ['contourlines',['contourLines',['../class_qwt_raster_data.html#a1fa90434ddeeeeaacb80657e49af8fe1',1,'QwtRasterData']]], + ['contourpen',['contourPen',['../class_qwt_plot_spectrogram.html#a9c5c16fcda0422739c5393e42be5af37',1,'QwtPlotSpectrogram']]], + ['contourrastersize',['contourRasterSize',['../class_qwt_plot_spectrogram.html#aa8baf22cfbfe9a0470fd17a251f7a8da',1,'QwtPlotSpectrogram']]], + ['controlpointrect',['controlPointRect',['../class_qwt_graphic.html#a42a6f02cc28b842c5eda6eabe7847439',1,'QwtGraphic']]], + ['copy',['copy',['../class_qwt_transform.html#aae011ee4205fa4391459766d88971809',1,'QwtTransform::copy()'],['../class_qwt_null_transform.html#af1770baa6d9b7a4f86e872bc55d6f899',1,'QwtNullTransform::copy()'],['../class_qwt_log_transform.html#a16c5031b6e252462b0e611d4a54b55f5',1,'QwtLogTransform::copy()'],['../class_qwt_power_transform.html#a1c3833f1f275ac298b3986cddc67055e',1,'QwtPowerTransform::copy()']]], + ['count',['count',['../class_qwt_dyn_grid_layout.html#a9a74593721ef1eba3d70275c36500ff6',1,'QwtDynGridLayout']]], + ['createwidget',['createWidget',['../class_qwt_legend.html#ac978d104d5d844cce177fac40ec56329',1,'QwtLegend']]], + ['cursor',['cursor',['../class_qwt_panner.html#a05a9ded33442da7f18c30bd06d45b55b',1,'QwtPanner']]], + ['curvefitter',['curveFitter',['../class_qwt_plot_curve.html#aaf299522e4ad972996c781aacc940d31',1,'QwtPlotCurve']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/functions_64.html b/ThirdParty/Qwt/doc/html/search/functions_64.html new file mode 100644 index 0000000000..17149308ab --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/functions_64.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/functions_64.js b/ThirdParty/Qwt/doc/html/search/functions_64.js new file mode 100644 index 0000000000..5272bae78e --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/functions_64.js @@ -0,0 +1,93 @@ +var searchData= +[ + ['data',['data',['../class_qwt_legend_label.html#a98ce3be22571bece709a828b3d18c770',1,'QwtLegendLabel::data()'],['../class_qwt_plot_spectrogram.html#a52d6090388ad9ff1117f3c4075903814',1,'QwtPlotSpectrogram::data() const '],['../class_qwt_plot_spectrogram.html#a4082962ff60af18a5212ea160f7b55ba',1,'QwtPlotSpectrogram::data()'],['../class_qwt_series_store.html#aae258d330c8d1bd2057b1f0bc13700f9',1,'QwtSeriesStore::data()'],['../class_qwt_series_store.html#afa10ec8a1ed48eb1955481bef8af6995',1,'QwtSeriesStore::data() const ']]], + ['datachanged',['dataChanged',['../class_qwt_plot_series_item.html#a8eaf7453ca8b3e8f522433149ba4c80d',1,'QwtPlotSeriesItem::dataChanged()'],['../class_qwt_abstract_series_store.html#ad95aac5e145cec2871e873c16f5f83b9',1,'QwtAbstractSeriesStore::dataChanged()']]], + ['datarect',['dataRect',['../class_qwt_abstract_series_store.html#a23d498a9d5bb10cb573db55650551a2c',1,'QwtAbstractSeriesStore::dataRect()'],['../class_qwt_series_store.html#a2acffb18573253acfb30cbedacf8c711',1,'QwtSeriesStore::dataRect()']]], + ['datasize',['dataSize',['../class_qwt_abstract_series_store.html#aa68ed8e5ce3da6b18826d8f95be86ad6',1,'QwtAbstractSeriesStore::dataSize()'],['../class_qwt_series_store.html#a1a3b9719889a0d7b85baf24b3dbf964f',1,'QwtSeriesStore::dataSize()']]], + ['dateformat',['dateFormat',['../class_qwt_date_scale_draw.html#aeb431d5113c2342b073d9faa4e65b5fb',1,'QwtDateScaleDraw']]], + ['dateformatofdate',['dateFormatOfDate',['../class_qwt_date_scale_draw.html#a00852822746e3999949b313c8cfd8550',1,'QwtDateScaleDraw']]], + ['dateofweek0',['dateOfWeek0',['../class_qwt_date.html#abb91fb441a254337d5445ad4bab1a662',1,'QwtDate']]], + ['defaultcontourpen',['defaultContourPen',['../class_qwt_plot_spectrogram.html#a0b5964a44f4c0ed0139681c6873ada73',1,'QwtPlotSpectrogram']]], + ['defaulticon',['defaultIcon',['../class_qwt_plot_item.html#af5264c9dcd9d1ec503bc1d46c10adc83',1,'QwtPlotItem']]], + ['defaultitemmode',['defaultItemMode',['../class_qwt_legend.html#a7ac3f2399fcf55dc35c1aa83abef4ac8',1,'QwtLegend']]], + ['defaultsize',['defaultSize',['../class_qwt_graphic.html#a588a284d40d45baa31d27e7131076d92',1,'QwtGraphic']]], + ['detach',['detach',['../class_qwt_plot_item.html#ab2bbee6dbe36a5f1d0ce853ac66716a6',1,'QwtPlotItem']]], + ['detachitems',['detachItems',['../class_qwt_plot_dict.html#acb2e402e05c693433ed7e84696fbdfc0',1,'QwtPlotDict']]], + ['dimforlength',['dimForLength',['../class_qwt_scale_widget.html#aa3c1f2f5e60ebb8f6fb42297dfe8881b',1,'QwtScaleWidget']]], + ['discardflags',['discardFlags',['../class_qwt_plot_renderer.html#ac0965a5084598e011ef1eb5c0d12347f',1,'QwtPlotRenderer']]], + ['discardraster',['discardRaster',['../class_qwt_raster_data.html#a369a5f525814bf569e01f88fbd8ddb5b',1,'QwtRasterData']]], + ['divideeps',['divideEps',['../class_qwt_scale_arithmetic.html#ae5f0415105b2a97cccb93f3da9ddaead',1,'QwtScaleArithmetic']]], + ['divideinterval',['divideInterval',['../class_qwt_scale_arithmetic.html#a9d03952650f73dd7a797791ddcfa91d7',1,'QwtScaleArithmetic::divideInterval()'],['../class_qwt_scale_engine.html#aff30158c5ccfee78f4c3e01c0fb5f4de',1,'QwtScaleEngine::divideInterval()']]], + ['dividescale',['divideScale',['../class_qwt_date_scale_engine.html#a335b9e9e2875492ce59befe31247c017',1,'QwtDateScaleEngine::divideScale()'],['../class_qwt_scale_engine.html#ab85442ced7cf3a39e5ad25f8cb80dea4',1,'QwtScaleEngine::divideScale()'],['../class_qwt_linear_scale_engine.html#aafed94c688e67c95a6ecf18e8bb522ab',1,'QwtLinearScaleEngine::divideScale()'],['../class_qwt_log_scale_engine.html#a883cc249cfcc290675af84960e4eccaf',1,'QwtLogScaleEngine::divideScale()']]], + ['draw',['draw',['../class_qwt_abstract_scale_draw.html#aca3c3a7499112f52616d0ee8518fa5a6',1,'QwtAbstractScaleDraw::draw()'],['../class_qwt_column_symbol.html#a647960f89c1f2f8524789d7ad90482d8',1,'QwtColumnSymbol::draw()'],['../class_qwt_compass_rose.html#ad974a3035da51a9cfb36fa04eb1c40a6',1,'QwtCompassRose::draw()'],['../class_qwt_simple_compass_rose.html#aa7541cd32c88b222731da37588e67bf3',1,'QwtSimpleCompassRose::draw()'],['../class_qwt_dial_needle.html#a425085086c4a8c7baff10b161616ee42',1,'QwtDialNeedle::draw()'],['../class_qwt_interval_symbol.html#aa13043e1d35361d8d259717a6579dadc',1,'QwtIntervalSymbol::draw()'],['../class_qwt_plot_grid.html#a9534a18db4f70b798bbbee2e50e0458d',1,'QwtPlotGrid::draw()'],['../class_qwt_plot_item.html#a0b0d6589d5db81ce72e6b33c4fbb21f9',1,'QwtPlotItem::draw()'],['../class_qwt_plot_legend_item.html#a6ce9e0ea057705582e31d3f6ea44ff16',1,'QwtPlotLegendItem::draw()'],['../class_qwt_plot_marker.html#abfd653364d9feeac09cd7ba77a650e3b',1,'QwtPlotMarker::draw()'],['../class_qwt_plot_raster_item.html#a2bb321c1ddc67b96a54a266ba27e6fe0',1,'QwtPlotRasterItem::draw()'],['../class_qwt_plot_scale_item.html#a2eef74cfd6007faf8b6e146277c82661',1,'QwtPlotScaleItem::draw()'],['../class_qwt_plot_series_item.html#af64601a32413f6f4928ceccc4934737e',1,'QwtPlotSeriesItem::draw()'],['../class_qwt_plot_shape_item.html#ab548f8daef8a2ae4184486bb1c4a47cf',1,'QwtPlotShapeItem::draw()'],['../class_qwt_plot_spectrogram.html#a92bafff167caeef9e1e4a6e652c0c5d4',1,'QwtPlotSpectrogram::draw()'],['../class_qwt_plot_svg_item.html#a83a95b772cc79f9a1590e0c4fe73d39c',1,'QwtPlotSvgItem::draw()'],['../class_qwt_plot_text_label.html#adfb623425eb95dcfe6fb18c661d04ebe',1,'QwtPlotTextLabel::draw()'],['../class_qwt_plot_zone_item.html#a02dfffe85a5578c6bbac0889f4739317',1,'QwtPlotZoneItem::draw()'],['../class_qwt_scale_widget.html#aab7267f2a3137b94a508a655bfaf4fd4',1,'QwtScaleWidget::draw()'],['../class_qwt_text.html#a01efd3ff82db2018b742265e0b7e4ece',1,'QwtText::draw()'],['../class_qwt_text_engine.html#ad727f58f9eebfec86369e7f2e5bf6a59',1,'QwtTextEngine::draw()'],['../class_qwt_plain_text_engine.html#a5fc2780c10ac2fb41aec91223b60fac7',1,'QwtPlainTextEngine::draw()'],['../class_qwt_rich_text_engine.html#a8f345540be2a90db3ce5a252ec443ce7',1,'QwtRichTextEngine::draw()'],['../class_qwt_math_m_l_text_engine.html#a4a347e3f7ac8fa7f57c4fcf62e4f2b36',1,'QwtMathMLTextEngine::draw()']]], + ['drawarrow',['drawArrow',['../class_qwt_arrow_button.html#aba724cf7e2f7e640b2e4f5c08f37d125',1,'QwtArrowButton']]], + ['drawbackbone',['drawBackbone',['../class_qwt_abstract_scale_draw.html#a15994a6033e689c3acdb8d83ae4f2a1c',1,'QwtAbstractScaleDraw::drawBackbone()'],['../class_qwt_round_scale_draw.html#a83ed97e96011d331939a3031df29f115',1,'QwtRoundScaleDraw::drawBackbone()'],['../class_qwt_scale_draw.html#aa53015c17e2abb01b179473cc488f20c',1,'QwtScaleDraw::drawBackbone()']]], + ['drawbackgound',['drawBackgound',['../class_qwt_painter.html#a726b908df4fd65a15e0d7ec3862947bc',1,'QwtPainter']]], + ['drawbackground',['drawBackground',['../class_qwt_plot_g_l_canvas.html#a7d829159155bff3fe206101914feeb26',1,'QwtPlotGLCanvas::drawBackground()'],['../class_qwt_plot_legend_item.html#ac72275134c687efc56304e2e74917174',1,'QwtPlotLegendItem::drawBackground()']]], + ['drawbar',['drawBar',['../class_qwt_plot_bar_chart.html#ad13634e3e2957f6a006eab2b5f56e828',1,'QwtPlotBarChart::drawBar()'],['../class_qwt_plot_multi_bar_chart.html#aa9f7a6f48b0d85937fd8d943aa89d91e',1,'QwtPlotMultiBarChart::drawBar()'],['../class_qwt_plot_trading_curve.html#a6a1b0150bbd4550c60e43bb7f74c6b3f',1,'QwtPlotTradingCurve::drawBar()']]], + ['drawborder',['drawBorder',['../class_qwt_plot_canvas.html#a4d415010a4baa09fa3b3edfcc6e5e4e7',1,'QwtPlotCanvas::drawBorder()'],['../class_qwt_plot_g_l_canvas.html#a9dc8018e6144788fe75dfc62206c1fe4',1,'QwtPlotGLCanvas::drawBorder()']]], + ['drawbox',['drawBox',['../class_qwt_column_symbol.html#a7f7951e3c38927c25f21dd8c3d47372a',1,'QwtColumnSymbol']]], + ['drawbuttonlabel',['drawButtonLabel',['../class_qwt_arrow_button.html#afc342cb3eaa01afe5aa897b3fd6aa7c2',1,'QwtArrowButton']]], + ['drawcandlestick',['drawCandleStick',['../class_qwt_plot_trading_curve.html#a66d576ebb06b9775729716d43164ab1a',1,'QwtPlotTradingCurve']]], + ['drawcanvas',['drawCanvas',['../class_qwt_plot.html#add1b88d8312e2671652d23f8181f2433',1,'QwtPlot']]], + ['drawcolorbar',['drawColorBar',['../class_qwt_painter.html#ae1009209978e5bb3f390905b81fb699f',1,'QwtPainter::drawColorBar()'],['../class_qwt_scale_widget.html#a6fe4349dce606498a417021e99b65fbf',1,'QwtScaleWidget::drawColorBar()']]], + ['drawcolumn',['drawColumn',['../class_qwt_plot_histogram.html#a4fe5a32387898f50c95e57603f092d2b',1,'QwtPlotHistogram']]], + ['drawcolumns',['drawColumns',['../class_qwt_plot_histogram.html#a53ef2324fd2bc187eb76dfb76c61f426',1,'QwtPlotHistogram']]], + ['drawcontents',['drawContents',['../class_qwt_dial.html#a9c567a9ce20120f3094a3d21ad26874a',1,'QwtDial::drawContents()'],['../class_qwt_text_label.html#ab1d6c248f451517a32c626372670ab51',1,'QwtTextLabel::drawContents()']]], + ['drawcontourlines',['drawContourLines',['../class_qwt_plot_spectrogram.html#aebd2c5ee80b3131138d4a55096962912',1,'QwtPlotSpectrogram']]], + ['drawcurve',['drawCurve',['../class_qwt_plot_curve.html#a9a1188e6abab05ed66ee7aebfc3d3679',1,'QwtPlotCurve']]], + ['drawdots',['drawDots',['../class_qwt_plot_curve.html#a9d5c81d3340aebf2ab8cf0dfee7e9c81',1,'QwtPlotCurve::drawDots()'],['../class_qwt_plot_spectro_curve.html#af6f48a0334d5646e2def2b3bfd16754c',1,'QwtPlotSpectroCurve::drawDots()']]], + ['drawellipse',['drawEllipse',['../class_qwt_null_paint_device.html#a36dbf087d462f077808f7d0a4611e572',1,'QwtNullPaintDevice::drawEllipse(const QRectF &)'],['../class_qwt_null_paint_device.html#a3a58da653add416644b1ad4e6567871e',1,'QwtNullPaintDevice::drawEllipse(const QRect &)'],['../class_qwt_painter.html#a0cce52b66d249859ff71e41edb3637ad',1,'QwtPainter::drawEllipse()']]], + ['drawfocusindicator',['drawFocusIndicator',['../class_qwt_dial.html#a1fce41a19c2e368fe90551e29c4de076',1,'QwtDial::drawFocusIndicator()'],['../class_qwt_knob.html#a89fc69b6f0d5ad4a4e99220db07721fd',1,'QwtKnob::drawFocusIndicator()'],['../class_qwt_plot_canvas.html#a4dc526ac5186fe253a158a392bbb4f40',1,'QwtPlotCanvas::drawFocusIndicator()']]], + ['drawfocusrect',['drawFocusRect',['../class_qwt_painter.html#aad72e955692b37a06547a6c0d62817b0',1,'QwtPainter::drawFocusRect(QPainter *, const QWidget *)'],['../class_qwt_painter.html#a3f6b853fa4a54712ea2ca20a9aa2f106',1,'QwtPainter::drawFocusRect(QPainter *, const QWidget *, const QRect &)']]], + ['drawframe',['drawFrame',['../class_qwt_dial.html#ad4534ebd8e4a792edbad3e16c25be7ca',1,'QwtDial::drawFrame()'],['../class_qwt_painter.html#ac0a433548dcb808cb88a93e7e2379ff4',1,'QwtPainter::drawFrame()']]], + ['drawgroupedbars',['drawGroupedBars',['../class_qwt_plot_multi_bar_chart.html#a2a3e582ab5ac2a4f7110fdf9f51a1959',1,'QwtPlotMultiBarChart']]], + ['drawhand',['drawHand',['../class_qwt_analog_clock.html#a62cbacb57c60c7584ba30f340ed575a1',1,'QwtAnalogClock']]], + ['drawhandle',['drawHandle',['../class_qwt_slider.html#a924e3fc8a885f72837379fdc29da2d20',1,'QwtSlider']]], + ['drawimage',['drawImage',['../class_qwt_graphic.html#a7055541b0d141c475b507ce3ad861f87',1,'QwtGraphic::drawImage()'],['../class_qwt_null_paint_device.html#a6a18a677959e446b34419d398d4fc4c7',1,'QwtNullPaintDevice::drawImage()'],['../class_qwt_painter.html#a2825f068a54e21e885235235daac3ec7',1,'QwtPainter::drawImage()']]], + ['drawitems',['drawItems',['../class_qwt_plot.html#a97be5b6d98b88053883cc26e4cedec8e',1,'QwtPlot::drawItems()'],['../class_qwt_plot_g_l_canvas.html#a0b385f2230b2abddf85882dbdfd89a34',1,'QwtPlotGLCanvas::drawItems()']]], + ['drawknob',['drawKnob',['../class_qwt_dial_needle.html#aaca9572717a1db10b1b6609571024688',1,'QwtDialNeedle::drawKnob()'],['../class_qwt_knob.html#a5ebc1ef5761b8db6d67820fc14cb89d5',1,'QwtKnob::drawKnob()']]], + ['drawlabel',['drawLabel',['../class_qwt_abstract_scale_draw.html#aa78dc8bf05a0224450c947af54128d8d',1,'QwtAbstractScaleDraw::drawLabel()'],['../class_qwt_plot_marker.html#a528aa01fd96e43829afc817433da49d4',1,'QwtPlotMarker::drawLabel()'],['../class_qwt_round_scale_draw.html#ad45ba2c90ac205bb9405c028d6498c0f',1,'QwtRoundScaleDraw::drawLabel()'],['../class_qwt_scale_draw.html#afc02a11a03efde4ea239d77c4d7711f4',1,'QwtScaleDraw::drawLabel()']]], + ['drawlegenddata',['drawLegendData',['../class_qwt_plot_legend_item.html#a4c9c3d7babfbaf5a7d09050d766d3987',1,'QwtPlotLegendItem']]], + ['drawline',['drawLine',['../class_qwt_painter.html#ad90ed35a673adb9767046c05b605bcf5',1,'QwtPainter::drawLine(QPainter *, double x1, double y1, double x2, double y2)'],['../class_qwt_painter.html#a8f4ebba74be8858ca43e50fac363468c',1,'QwtPainter::drawLine(QPainter *, const QPointF &p1, const QPointF &p2)'],['../class_qwt_painter.html#af31427d37c1cfd4ddc84e013086a77e1',1,'QwtPainter::drawLine(QPainter *, const QLineF &)']]], + ['drawlines',['drawLines',['../class_qwt_null_paint_device.html#a3a8c7d120fb6d1aa8617037e34df1cf3',1,'QwtNullPaintDevice::drawLines(const QLine *, int)'],['../class_qwt_null_paint_device.html#aa69ee4a20a2d5ff7f11b24db212bc636',1,'QwtNullPaintDevice::drawLines(const QLineF *, int)'],['../class_qwt_plot_curve.html#a20948ab52983ee8c2058b2b2689e97a0',1,'QwtPlotCurve::drawLines()'],['../class_qwt_plot_histogram.html#aa42318d0547aca1fff650a0025168890',1,'QwtPlotHistogram::drawLines()'],['../class_qwt_plot_marker.html#a4f0ebfc835da7397ee823860cfac62ca',1,'QwtPlotMarker::drawLines()']]], + ['drawliquid',['drawLiquid',['../class_qwt_thermo.html#ab9cca3cab3a8950b66e14b995b86beb8',1,'QwtThermo']]], + ['drawmarker',['drawMarker',['../class_qwt_knob.html#a2b0523757918e335fe444df702972f3e',1,'QwtKnob']]], + ['drawneedle',['drawNeedle',['../class_qwt_analog_clock.html#ac243e3acb6ba8edd73c24918e170f529',1,'QwtAnalogClock::drawNeedle()'],['../class_qwt_dial.html#ad287b8e8d3f5453c9f7a317d40d35162',1,'QwtDial::drawNeedle()'],['../class_qwt_dial_needle.html#a1e4fee366fec1838edc18890d9957f2b',1,'QwtDialNeedle::drawNeedle()'],['../class_qwt_dial_simple_needle.html#a0eff8832707ff968d17eddf478d6a771',1,'QwtDialSimpleNeedle::drawNeedle()'],['../class_qwt_compass_magnet_needle.html#aa052d929a09bfc6d487a973b2221d44d',1,'QwtCompassMagnetNeedle::drawNeedle()'],['../class_qwt_compass_wind_arrow.html#a4e3b612f2de83ff416e34f62c1f0fd6c',1,'QwtCompassWindArrow::drawNeedle()']]], + ['drawoutline',['drawOutline',['../class_qwt_plot_histogram.html#a9984abfbec9121b8026e9c7103ebec4b',1,'QwtPlotHistogram']]], + ['drawoverlay',['drawOverlay',['../class_qwt_widget_overlay.html#abb69235d3eba71b6dde354c668dd2611',1,'QwtWidgetOverlay']]], + ['drawpath',['drawPath',['../class_qwt_graphic.html#ab505a5efa0f4ba0494460d4671a7bf21',1,'QwtGraphic::drawPath()'],['../class_qwt_null_paint_device.html#a1df889689ff1e29a0f864be5ac809ada',1,'QwtNullPaintDevice::drawPath()'],['../class_qwt_painter.html#a22cff4eba018aee6680c43347e92238d',1,'QwtPainter::drawPath()']]], + ['drawpie',['drawPie',['../class_qwt_painter.html#af3a38d38e0909523dbac12cd93ba3122',1,'QwtPainter']]], + ['drawpixmap',['drawPixmap',['../class_qwt_graphic.html#a888ea196dec4fab9eb4acd4d535ec730',1,'QwtGraphic::drawPixmap()'],['../class_qwt_null_paint_device.html#a1a0a2f22ea26bdf74becd5e5813f8f6f',1,'QwtNullPaintDevice::drawPixmap()'],['../class_qwt_painter.html#aec25b066b31a967de60d645c58ed7557',1,'QwtPainter::drawPixmap()']]], + ['drawpoint',['drawPoint',['../class_qwt_painter.html#ab2e88f78d51387c661a9e10352ab945c',1,'QwtPainter::drawPoint(QPainter *, const QPoint &)'],['../class_qwt_painter.html#a1e65c0e2436e253de937e164d365aa5f',1,'QwtPainter::drawPoint(QPainter *, double x, double y)'],['../class_qwt_painter.html#a9b0ef616fc27c84dc7ee3cab5449a313',1,'QwtPainter::drawPoint(QPainter *, const QPointF &)']]], + ['drawpoints',['drawPoints',['../class_qwt_null_paint_device.html#a5b0b40aed4fa6b4b193834cf89af2a3e',1,'QwtNullPaintDevice::drawPoints(const QPointF *, int)'],['../class_qwt_null_paint_device.html#a89f89b7398be0e9c3c24cdf7e37803e2',1,'QwtNullPaintDevice::drawPoints(const QPoint *, int)'],['../class_qwt_painter.html#a0e1bddfd725ea95f628c491149c2deba',1,'QwtPainter::drawPoints(QPainter *, const QPolygon &)'],['../class_qwt_painter.html#a1f268ec257dbd52a7aca59c5c2ea3f98',1,'QwtPainter::drawPoints(QPainter *, const QPoint *, int pointCount)'],['../class_qwt_painter.html#a1a854725b6ff657557e678575dc56357',1,'QwtPainter::drawPoints(QPainter *, const QPolygonF &)'],['../class_qwt_painter.html#af5fa718b25a9b4df10ddb7e1270a4289',1,'QwtPainter::drawPoints(QPainter *, const QPointF *, int pointCount)']]], + ['drawpolygon',['drawPolygon',['../class_qwt_null_paint_device.html#ad8ccc7d13b3ed6011c4f986210912d02',1,'QwtNullPaintDevice::drawPolygon(const QPointF *, int, QPaintEngine::PolygonDrawMode)'],['../class_qwt_null_paint_device.html#a9bd92d6203a0c7ad70a529d59d685eb1',1,'QwtNullPaintDevice::drawPolygon(const QPoint *, int, QPaintEngine::PolygonDrawMode)'],['../class_qwt_painter.html#a2fff1088059c230864ac1eff90d8e975',1,'QwtPainter::drawPolygon(QPainter *, const QPolygonF &)'],['../class_qwt_painter.html#a67bd336cc96329e2d0e717574892c84c',1,'QwtPainter::drawPolygon(QPainter *, const QPolygon &)']]], + ['drawpolyline',['drawPolyline',['../class_qwt_painter.html#a60ab9909e9eac196c022b1ec6200d198',1,'QwtPainter::drawPolyline(QPainter *, const QPolygonF &)'],['../class_qwt_painter.html#a2aac8306cd6863887db1f2987eb0eced',1,'QwtPainter::drawPolyline(QPainter *, const QPointF *, int pointCount)'],['../class_qwt_painter.html#a4846eb8406cc49435013e41e4debacdc',1,'QwtPainter::drawPolyline(QPainter *, const QPolygon &)'],['../class_qwt_painter.html#a479d20a9aed2dee2ccdd735c6e77bc58',1,'QwtPainter::drawPolyline(QPainter *, const QPoint *, int pointCount)']]], + ['drawrect',['drawRect',['../class_qwt_painter.html#a0779e2b85c7d04547933574fd2021193',1,'QwtPainter::drawRect(QPainter *, double x, double y, double w, double h)'],['../class_qwt_painter.html#a838b9cc65ae98ecb40d62ed4281a37b7',1,'QwtPainter::drawRect(QPainter *, const QRectF &rect)']]], + ['drawrects',['drawRects',['../class_qwt_null_paint_device.html#a1ea5ece663be08bacd9b1b46230b5cbc',1,'QwtNullPaintDevice::drawRects(const QRect *, int)'],['../class_qwt_null_paint_device.html#a78163254e4793afc26b1752178964336',1,'QwtNullPaintDevice::drawRects(const QRectF *, int)']]], + ['drawrose',['drawRose',['../class_qwt_compass.html#a3cc1a7d06b9d6be235024a19ff0c6a25',1,'QwtCompass::drawRose()'],['../class_qwt_simple_compass_rose.html#a914bb202a844f0b11a18a0296e170025',1,'QwtSimpleCompassRose::drawRose()']]], + ['drawroundedframe',['drawRoundedFrame',['../class_qwt_painter.html#a00b91696b5dc3264b54c99e436616804',1,'QwtPainter']]], + ['drawroundframe',['drawRoundFrame',['../class_qwt_painter.html#a388f68022ef77dbdae9d700e104f0976',1,'QwtPainter']]], + ['drawrubberband',['drawRubberBand',['../class_qwt_picker.html#a4848b0a4ca94d4160fdcf29c73982bef',1,'QwtPicker']]], + ['drawsample',['drawSample',['../class_qwt_plot_bar_chart.html#a0080d33e4a30cd941c09b22249836099',1,'QwtPlotBarChart::drawSample()'],['../class_qwt_plot_multi_bar_chart.html#a548e1f1b4319abf03f1995dc25ad40be',1,'QwtPlotMultiBarChart::drawSample()']]], + ['drawscale',['drawScale',['../class_qwt_dial.html#ad93f277c9cca98580be853a13abd7cd4',1,'QwtDial']]], + ['drawscalecontents',['drawScaleContents',['../class_qwt_compass.html#a562e9358a830106f9d219a4fa8af3540',1,'QwtCompass::drawScaleContents()'],['../class_qwt_dial.html#a06b36d64377e54dac8812b4c4c0bf263',1,'QwtDial::drawScaleContents()']]], + ['drawseries',['drawSeries',['../class_qwt_plot_bar_chart.html#aa5a140241884fbeee3d41bdb0964a71c',1,'QwtPlotBarChart::drawSeries()'],['../class_qwt_plot_curve.html#aea90af49da5296087499e06ae1e35c9e',1,'QwtPlotCurve::drawSeries()'],['../class_qwt_plot_direct_painter.html#aacc2e1d79dd410cb1a4404fbc00290bd',1,'QwtPlotDirectPainter::drawSeries()'],['../class_qwt_plot_histogram.html#a588eb9f56482fe8669c4d6eaa2db09e2',1,'QwtPlotHistogram::drawSeries()'],['../class_qwt_plot_interval_curve.html#add274e6e29ff2df9b6961f3ed5ebcd5e',1,'QwtPlotIntervalCurve::drawSeries()'],['../class_qwt_plot_multi_bar_chart.html#a8b8058db564f8d5cb674afe224c4a584',1,'QwtPlotMultiBarChart::drawSeries()'],['../class_qwt_plot_series_item.html#af6c8091544081ff72723270cc7c8f139',1,'QwtPlotSeriesItem::drawSeries()'],['../class_qwt_plot_spectro_curve.html#a04529b82d2acbcf9fc8f66da73bae8e9',1,'QwtPlotSpectroCurve::drawSeries()'],['../class_qwt_plot_trading_curve.html#a36a3770784f70ef0e52fee3ad7ea055e',1,'QwtPlotTradingCurve::drawSeries()']]], + ['drawsimplerichtext',['drawSimpleRichText',['../class_qwt_painter.html#a1a44fdbb66452b38d57369a485da3971',1,'QwtPainter']]], + ['drawslider',['drawSlider',['../class_qwt_slider.html#a5e45e9ca42fdf659d89011bddd8ff779',1,'QwtSlider']]], + ['drawstackedbars',['drawStackedBars',['../class_qwt_plot_multi_bar_chart.html#acee8ee9034c64559598c2e6fcace60a5',1,'QwtPlotMultiBarChart']]], + ['drawsteps',['drawSteps',['../class_qwt_plot_curve.html#aa55bd22c153a15b7cba082c499536602',1,'QwtPlotCurve']]], + ['drawsticks',['drawSticks',['../class_qwt_plot_curve.html#a732c4a8b905be4f635d8558b6d959b52',1,'QwtPlotCurve']]], + ['drawsymbol',['drawSymbol',['../class_qwt_symbol.html#a4ad34a14ca9650c53530fd540d921fe8',1,'QwtSymbol::drawSymbol(QPainter *, const QRectF &) const '],['../class_qwt_symbol.html#a3403db40a12f2f79f79616cf858ecb1f',1,'QwtSymbol::drawSymbol(QPainter *, const QPointF &) const ']]], + ['drawsymbols',['drawSymbols',['../class_qwt_plot_curve.html#ad734862538617112beb6a59cc06ed3b5',1,'QwtPlotCurve::drawSymbols()'],['../class_qwt_plot_interval_curve.html#a54682faaed2110816fe874cad37142b7',1,'QwtPlotIntervalCurve::drawSymbols()'],['../class_qwt_plot_trading_curve.html#a3b330a144768322218ac6b996d4ac802',1,'QwtPlotTradingCurve::drawSymbols()'],['../class_qwt_symbol.html#a249740d6f7e6315e3de0ce6f7ad7020d',1,'QwtSymbol::drawSymbols(QPainter *, const QPolygonF &) const '],['../class_qwt_symbol.html#a18c1e4716c4ebc92a28becc86de4d429',1,'QwtSymbol::drawSymbols(QPainter *, const QPointF *, int numPoints) const ']]], + ['drawtext',['drawText',['../class_qwt_painter.html#a7b32c7e2937f7beea38728b9ce445860',1,'QwtPainter::drawText(QPainter *, double x, double y, const QString &)'],['../class_qwt_painter.html#a60048491773b3eb7aac5b984a4bd9730',1,'QwtPainter::drawText(QPainter *, const QPointF &, const QString &)'],['../class_qwt_painter.html#a90fd62c3862e9f4543eda02279f75f10',1,'QwtPainter::drawText(QPainter *, double x, double y, double w, double h, int flags, const QString &)'],['../class_qwt_painter.html#a2866de24c2d7ddb88ee5919d09cad03f',1,'QwtPainter::drawText(QPainter *, const QRectF &, int flags, const QString &)'],['../class_qwt_text_label.html#af1e33db74ecf9c4e7aff158db65404c2',1,'QwtTextLabel::drawText()']]], + ['drawtextitem',['drawTextItem',['../class_qwt_null_paint_device.html#a9c0566fc34422c4bd61534cebfb95d63',1,'QwtNullPaintDevice']]], + ['drawtick',['drawTick',['../class_qwt_abstract_scale_draw.html#a31791e80bf07d23adbe500740aac5a58',1,'QwtAbstractScaleDraw::drawTick()'],['../class_qwt_round_scale_draw.html#aff2f18e7e7cac42805724ab5b0f2aad7',1,'QwtRoundScaleDraw::drawTick()'],['../class_qwt_scale_draw.html#a84badd947ddc95a462ec20fe64922b36',1,'QwtScaleDraw::drawTick()']]], + ['drawticks',['drawTicks',['../class_qwt_wheel.html#aba74d0e494f6e590ac1deac60a66a68e',1,'QwtWheel']]], + ['drawtiledpixmap',['drawTiledPixmap',['../class_qwt_null_paint_device.html#a256a8a39d0f32fb210c4561fe1b3f867',1,'QwtNullPaintDevice']]], + ['drawtitle',['drawTitle',['../class_qwt_scale_widget.html#a7daf1650daa5503342721dda62d72243',1,'QwtScaleWidget']]], + ['drawtracker',['drawTracker',['../class_qwt_picker.html#a74c471c27ced5e7a5d59455bcd7d8290',1,'QwtPicker']]], + ['drawtube',['drawTube',['../class_qwt_plot_interval_curve.html#ae5522b27d49da7a99f8b01b577fa153e',1,'QwtPlotIntervalCurve']]], + ['drawusersymbol',['drawUserSymbol',['../class_qwt_plot_trading_curve.html#a02a8e52cb0b6c4d103ae616f00546cf3',1,'QwtPlotTradingCurve']]], + ['drawwheelbackground',['drawWheelBackground',['../class_qwt_wheel.html#a2c4fc6e5e04cd5623a035fd9581d395f',1,'QwtWheel']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/functions_65.html b/ThirdParty/Qwt/doc/html/search/functions_65.html new file mode 100644 index 0000000000..13260cf253 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/functions_65.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/functions_65.js b/ThirdParty/Qwt/doc/html/search/functions_65.js new file mode 100644 index 0000000000..216c69e03e --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/functions_65.js @@ -0,0 +1,22 @@ +var searchData= +[ + ['elapsed',['elapsed',['../class_qwt_sampling_thread.html#a27ebf049b4fc423bdb172d9036eb6683',1,'QwtSamplingThread::elapsed()'],['../class_qwt_system_clock.html#a0baae39a5a9d4f4e8bf3a8bd308a6dad',1,'QwtSystemClock::elapsed()']]], + ['enableaxis',['enableAxis',['../class_qwt_plot.html#ab644f7a0a0566ff776c89cc225ce37d7',1,'QwtPlot']]], + ['enablecomponent',['enableComponent',['../class_qwt_abstract_scale_draw.html#af975410588db6103f281e49d0b43c6a6',1,'QwtAbstractScaleDraw']]], + ['enablex',['enableX',['../class_qwt_plot_grid.html#aba4de91f74f86e172e080fa62765bba8',1,'QwtPlotGrid']]], + ['enablexmin',['enableXMin',['../class_qwt_plot_grid.html#a4106c58c9d463bd4ccd94e215cc246bb',1,'QwtPlotGrid']]], + ['enabley',['enableY',['../class_qwt_plot_grid.html#a0172d8af861495a94aa856af26ad786d',1,'QwtPlotGrid']]], + ['enableymin',['enableYMin',['../class_qwt_plot_grid.html#a21b26d5b6b0745ecdec12d6bdeb8ecb4',1,'QwtPlotGrid']]], + ['end',['end',['../class_qwt_picker.html#ad258c518257cf2f52326905a36efb0c4',1,'QwtPicker::end()'],['../class_qwt_plot_picker.html#a9fceb663542b6f9b0a358e9419406423',1,'QwtPlotPicker::end()'],['../class_qwt_plot_zoomer.html#ac7d10eb27858ccfebebecab5d69ecbb3',1,'QwtPlotZoomer::end()']]], + ['endborderdist',['endBorderDist',['../class_qwt_scale_widget.html#a314a2aff4b7629db21b45c8f74b3ae0b',1,'QwtScaleWidget']]], + ['event',['event',['../class_qwt_counter.html#ad855f1cec9068fd73cce5e2e29fb5771',1,'QwtCounter::event()'],['../class_qwt_plot.html#af40d1bfdd9b6cd94e9981db8b254b961',1,'QwtPlot::event()'],['../class_qwt_plot_canvas.html#ab7f160c99d7d408a979ebe2acae951bc',1,'QwtPlotCanvas::event()'],['../class_qwt_plot_g_l_canvas.html#a9345f69cd3c96c5cb4bdcc3d056de8dd',1,'QwtPlotGLCanvas::event()']]], + ['eventfilter',['eventFilter',['../class_qwt_legend.html#ade86e158b8254fe76d42e85f9808c827',1,'QwtLegend::eventFilter()'],['../class_qwt_magnifier.html#ae7f4c0ad7631501cec17abe31695281f',1,'QwtMagnifier::eventFilter()'],['../class_qwt_panner.html#a06b8eea86d4dcbe361c4af41a263f2cb',1,'QwtPanner::eventFilter()'],['../class_qwt_picker.html#ac149f9cb8fb068f31871e1fe450c376e',1,'QwtPicker::eventFilter()'],['../class_qwt_plot.html#a8c40a5ccc1b0fc18f29796ddc05b27f6',1,'QwtPlot::eventFilter()'],['../class_qwt_plot_direct_painter.html#ab421bd757679b61f1dcfde2991500ab2',1,'QwtPlotDirectPainter::eventFilter()'],['../class_qwt_plot_rescaler.html#a2a6809f3940b9114a1faed30f6edc3d0',1,'QwtPlotRescaler::eventFilter()'],['../class_qwt_widget_overlay.html#a460de4766c71c6977478eddff3546066',1,'QwtWidgetOverlay::eventFilter()']]], + ['expandingdirection',['expandingDirection',['../class_qwt_plot_rescaler.html#aadeb316249fa679323252140ff241176',1,'QwtPlotRescaler']]], + ['expandingdirections',['expandingDirections',['../class_qwt_dyn_grid_layout.html#a1340bdbdaf09f79ac9e80f96f1b8b106',1,'QwtDynGridLayout']]], + ['expandinterval',['expandInterval',['../class_qwt_plot_rescaler.html#ad3da887bf71befccf1f3094da448a502',1,'QwtPlotRescaler']]], + ['expandlinebreaks',['expandLineBreaks',['../class_qwt_plot_layout.html#a36aa9335a907f8f20a59a63cc7e0d78c',1,'QwtPlotLayout']]], + ['expandscale',['expandScale',['../class_qwt_plot_rescaler.html#ae3eb4d18dcd9ace4b7eb0bd05216c957',1,'QwtPlotRescaler']]], + ['exportto',['exportTo',['../class_qwt_plot_renderer.html#ac1912ef59ba1a3085f87c0ab49cbcd8b',1,'QwtPlotRenderer']]], + ['extend',['extend',['../class_qwt_interval.html#a484665e4af4ea42583b3224c10d1d9c3',1,'QwtInterval']]], + ['extent',['extent',['../class_qwt_abstract_scale_draw.html#a87e21208e981457cde501054319c77e7',1,'QwtAbstractScaleDraw::extent()'],['../class_qwt_round_scale_draw.html#a786fd49ec94ab51bb75d7a2f495b2727',1,'QwtRoundScaleDraw::extent()'],['../class_qwt_scale_draw.html#a1fa0cebc2b8f69dce72b0514ad7653f0',1,'QwtScaleDraw::extent()']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/functions_66.html b/ThirdParty/Qwt/doc/html/search/functions_66.html new file mode 100644 index 0000000000..12565e3b2f --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/functions_66.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/functions_66.js b/ThirdParty/Qwt/doc/html/search/functions_66.js new file mode 100644 index 0000000000..1c8862287b --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/functions_66.js @@ -0,0 +1,23 @@ +var searchData= +[ + ['fillbrush',['fillBrush',['../class_qwt_thermo.html#a3b109fe9027813e4e1b5ffa080a90046',1,'QwtThermo']]], + ['fillcurve',['fillCurve',['../class_qwt_plot_curve.html#a599d88770d6fafa5ae4edb75fd5d445f',1,'QwtPlotCurve']]], + ['fillpixmap',['fillPixmap',['../class_qwt_painter.html#ab3207c4d8ee4ce7fd472f8faefb93657',1,'QwtPainter']]], + ['fillrect',['fillRect',['../class_qwt_painter.html#a8f5561421bf2d1c1093059f1b7bba7ba',1,'QwtPainter::fillRect()'],['../class_qwt_thermo.html#a3226e3ca8266e16d8c90bae5c9f5a3d2',1,'QwtThermo::fillRect()']]], + ['fitcurve',['fitCurve',['../class_qwt_curve_fitter.html#afa9bf5b328aa553229e204533a60fec0',1,'QwtCurveFitter::fitCurve()'],['../class_qwt_spline_curve_fitter.html#a14d64180d7777d0cd9c2adf81e120140',1,'QwtSplineCurveFitter::fitCurve()'],['../class_qwt_weeding_curve_fitter.html#aa316dc6c60ae0d0c74ef0bc0fc239f0b',1,'QwtWeedingCurveFitter::fitCurve()']]], + ['fitmode',['fitMode',['../class_qwt_spline_curve_fitter.html#a473468f2151839f3290975f6b18f1c4f',1,'QwtSplineCurveFitter']]], + ['flags',['flags',['../class_qwt_point_mapper.html#aeb3ce1915222fab8a6e2ab83acd90f93',1,'QwtPointMapper']]], + ['floor',['floor',['../class_qwt_date.html#a1b350f22a57b44b529bc4de740dbe213',1,'QwtDate']]], + ['flooreps',['floorEps',['../class_qwt_scale_arithmetic.html#a924d97f2e5db236f43f4d65e430e09c1',1,'QwtScaleArithmetic']]], + ['focusindicator',['focusIndicator',['../class_qwt_plot_canvas.html#a0e9653bdf8c62299dbc3551ac7e5ec51',1,'QwtPlotCanvas']]], + ['font',['font',['../class_qwt_plot_legend_item.html#a040a9645b326123adde3ae0fe0bd3250',1,'QwtPlotLegendItem::font()'],['../class_qwt_plot_scale_item.html#ada859305224f3eec06e23dc7c3ce8f9c',1,'QwtPlotScaleItem::font()'],['../class_qwt_text.html#a76db41eeae98fbfa0933a38328a240ac',1,'QwtText::font()']]], + ['footer',['footer',['../class_qwt_plot.html#ad6898e29b51becca48e62a83f7d45034',1,'QwtPlot']]], + ['footerlabel',['footerLabel',['../class_qwt_plot.html#a613b07505a881a7e85a868effa1f5a96',1,'QwtPlot::footerLabel()'],['../class_qwt_plot.html#a5e0d7d488fa3aafcb10f3ef53d037f35',1,'QwtPlot::footerLabel() const ']]], + ['footerrect',['footerRect',['../class_qwt_plot_layout.html#ae782fe2075ad7e8b902b2deae317e96f',1,'QwtPlotLayout']]], + ['format',['format',['../class_qwt_color_map.html#a436802833ae1d4694f376655bc3d75be',1,'QwtColorMap']]], + ['framerect',['frameRect',['../class_qwt_plot_g_l_canvas.html#a0288ef4d408f6f270fedb895436acc89',1,'QwtPlotGLCanvas']]], + ['frameshadow',['frameShadow',['../class_qwt_dial.html#a49e37bd4da2ed2b846bba75c79a04fbc',1,'QwtDial::frameShadow()'],['../class_qwt_plot_g_l_canvas.html#a331133679651f7d08cfad03b7d723691',1,'QwtPlotGLCanvas::frameShadow()']]], + ['frameshape',['frameShape',['../class_qwt_plot_g_l_canvas.html#a06d846c980148c1b258baea8ba0b2d68',1,'QwtPlotGLCanvas']]], + ['framestyle',['frameStyle',['../class_qwt_column_symbol.html#a9e13ae8a8b07556ee2de672c7067606a',1,'QwtColumnSymbol::frameStyle()'],['../class_qwt_plot_g_l_canvas.html#ae5e8b391cd2ec58d0483a4dd7db5f395',1,'QwtPlotGLCanvas::frameStyle()']]], + ['framewidth',['frameWidth',['../class_qwt_plot_g_l_canvas.html#a39bc67f5fd7c4adb8ac5f5a4e43d9d68',1,'QwtPlotGLCanvas']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/functions_67.html b/ThirdParty/Qwt/doc/html/search/functions_67.html new file mode 100644 index 0000000000..53d4a096f7 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/functions_67.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/functions_67.js b/ThirdParty/Qwt/doc/html/search/functions_67.js new file mode 100644 index 0000000000..bc2db43595 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/functions_67.js @@ -0,0 +1,15 @@ +var searchData= +[ + ['geometry',['geometry',['../class_qwt_plot_legend_item.html#a526803d997725b68ca96cc9b9f911d49',1,'QwtPlotLegendItem']]], + ['getabortkey',['getAbortKey',['../class_qwt_panner.html#ae50b8bc2a17a480a50f39ddb96128cad',1,'QwtPanner']]], + ['getborderdisthint',['getBorderDistHint',['../class_qwt_scale_draw.html#ab6c5d65a109b63b2dd62984d38a4df0e',1,'QwtScaleDraw::getBorderDistHint()'],['../class_qwt_scale_widget.html#a57ca1a6a87417a732e0b1e66ac2a3493',1,'QwtScaleWidget::getBorderDistHint()']]], + ['getcanvasmarginhint',['getCanvasMarginHint',['../class_qwt_plot_abstract_bar_chart.html#aade3c92c2fcbbfdef47b810cdb2d4d90',1,'QwtPlotAbstractBarChart::getCanvasMarginHint()'],['../class_qwt_plot_item.html#a46b0d88f7667e0e93dee5253c8be001f',1,'QwtPlotItem::getCanvasMarginHint()']]], + ['getcanvasmarginshint',['getCanvasMarginsHint',['../class_qwt_plot.html#aa1cd126530e6b9db28714476035487ac',1,'QwtPlot']]], + ['getminborderdist',['getMinBorderDist',['../class_qwt_scale_widget.html#a2927a7cb5157b86c580d7ebed4dc4e7c',1,'QwtScaleWidget']]], + ['getmousebutton',['getMouseButton',['../class_qwt_magnifier.html#afc4efee268edb053630283b067933998',1,'QwtMagnifier::getMouseButton()'],['../class_qwt_panner.html#af75b070c58163f106f50d311ad1af1d0',1,'QwtPanner::getMouseButton()']]], + ['getzoominkey',['getZoomInKey',['../class_qwt_magnifier.html#abf357e6493dba55f478fb89e4c312131',1,'QwtMagnifier']]], + ['getzoomoutkey',['getZoomOutKey',['../class_qwt_magnifier.html#a06ae0b904538c8d21e070212e007dbf3',1,'QwtMagnifier']]], + ['grab',['grab',['../class_qwt_panner.html#ad854755a61d2cb9c9666889bdbbe9859',1,'QwtPanner::grab()'],['../class_qwt_plot_panner.html#a03b494d36d5adbe1b05aa3acbbf37f8b',1,'QwtPlotPanner::grab()']]], + ['grabproperties',['grabProperties',['../class_qwt_plot.html#afd1c65720e19e50aa083dabd5bbf88e8',1,'QwtPlot']]], + ['graphic',['graphic',['../class_qwt_symbol.html#ad7f3af9937686813ffa9264d578a33f2',1,'QwtSymbol']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/functions_68.html b/ThirdParty/Qwt/doc/html/search/functions_68.html new file mode 100644 index 0000000000..77d37fe1a7 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/functions_68.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/functions_68.js b/ThirdParty/Qwt/doc/html/search/functions_68.js new file mode 100644 index 0000000000..160b6b5f3b --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/functions_68.js @@ -0,0 +1,15 @@ +var searchData= +[ + ['hand',['hand',['../class_qwt_analog_clock.html#ab390561b0856eef0d2bb80bdff0fb204',1,'QwtAnalogClock::hand(Hand) const '],['../class_qwt_analog_clock.html#abb93bf8255bc00ef160165385bb6adce',1,'QwtAnalogClock::hand(Hand)']]], + ['handlerect',['handleRect',['../class_qwt_slider.html#a69df4f26e88b911c0dcf28d41987550a',1,'QwtSlider']]], + ['handlesize',['handleSize',['../class_qwt_slider.html#a56cf54a5b406530e8d3a5986626ba000',1,'QwtSlider']]], + ['hasclipping',['hasClipping',['../class_qwt_plot_direct_painter.html#a8d6b8b273b4e74181cd7ed5fdaf0bb7e',1,'QwtPlotDirectPainter']]], + ['hascomponent',['hasComponent',['../class_qwt_abstract_scale_draw.html#a95d74d9eaa5520754295efb33a4db50f',1,'QwtAbstractScaleDraw']]], + ['hasgroove',['hasGroove',['../class_qwt_slider.html#aeb2f0f70d1fb6358022805e3f1a0ae9d',1,'QwtSlider']]], + ['hasheightforwidth',['hasHeightForWidth',['../class_qwt_dyn_grid_layout.html#ae8867d543d54d5da9657c55b3c329d8e',1,'QwtDynGridLayout']]], + ['hasrole',['hasRole',['../class_qwt_legend_data.html#ae615eb3d1a3d88cc25dc0ed6dea70a72',1,'QwtLegendData']]], + ['hastrough',['hasTrough',['../class_qwt_slider.html#a3ff426a41b4daa6406315cd302d59032',1,'QwtSlider']]], + ['heightforwidth',['heightForWidth',['../class_qwt_dyn_grid_layout.html#afa3fd53b485e9f1ed90796ff923466f1',1,'QwtDynGridLayout::heightForWidth()'],['../class_qwt_legend.html#a273ec258209c42f57b154ff4da61e1d0',1,'QwtLegend::heightForWidth()'],['../class_qwt_plot_legend_item.html#af4b16cf1966e4c2bc96ba173501ef66f',1,'QwtPlotLegendItem::heightForWidth()'],['../class_qwt_text.html#a29f7064fa8825d30e0b7b7b740d2df9f',1,'QwtText::heightForWidth()'],['../class_qwt_text_engine.html#aee891b14d90c817b8c73d551f623cc17',1,'QwtTextEngine::heightForWidth()'],['../class_qwt_plain_text_engine.html#a9190bdcb6ed447a5bc056ad8304ad58b',1,'QwtPlainTextEngine::heightForWidth()'],['../class_qwt_rich_text_engine.html#ab19cc5ad4ae33aaffc6aaf5d58b93b19',1,'QwtRichTextEngine::heightForWidth()'],['../class_qwt_text_label.html#ade1867a2c9308f2235cfacf675fa1d4c',1,'QwtTextLabel::heightForWidth()'],['../class_qwt_math_m_l_text_engine.html#a3d5b7c9be31d9282b4c86c8ec3f4c8df',1,'QwtMathMLTextEngine::heightForWidth()']]], + ['hide',['hide',['../class_qwt_plot_item.html#a1faea017baa2492416a13e6bc3c144aa',1,'QwtPlotItem']]], + ['horizontalscrollbar',['horizontalScrollBar',['../class_qwt_legend.html#a40dab44d47921da18a925e8fcc8d6870',1,'QwtLegend']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/functions_69.html b/ThirdParty/Qwt/doc/html/search/functions_69.html new file mode 100644 index 0000000000..9edd1a1c1b --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/functions_69.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/functions_69.js b/ThirdParty/Qwt/doc/html/search/functions_69.js new file mode 100644 index 0000000000..715cbdaedd --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/functions_69.js @@ -0,0 +1,64 @@ +var searchData= +[ + ['icon',['icon',['../class_qwt_legend_data.html#a3a4e20d33c2eb8bec1e8ef9b943de74c',1,'QwtLegendData::icon()'],['../class_qwt_legend_label.html#a6fc6cdbd1b4b9db2de354cbe533e1c2a',1,'QwtLegendLabel::icon()']]], + ['imagedata',['imageData',['../class_qwt_painter_command.html#acb12c36d4b9df791bd4f2089e6c147d9',1,'QwtPainterCommand::imageData()'],['../class_qwt_painter_command.html#a60eed873d4177b3ebf3180ddf3893b3e',1,'QwtPainterCommand::imageData() const ']]], + ['imagemap',['imageMap',['../class_qwt_plot_raster_item.html#a9feb834f9e40cdff11d8cd6ad74fda10',1,'QwtPlotRasterItem']]], + ['incrementedvalue',['incrementedValue',['../class_qwt_abstract_slider.html#af4ee11b0a966af2d9fbd9feb240cb857',1,'QwtAbstractSlider']]], + ['incrementvalue',['incrementValue',['../class_qwt_abstract_slider.html#aa31fe73942c4cae17bce9e5cae36bd55',1,'QwtAbstractSlider']]], + ['incsteps',['incSteps',['../class_qwt_counter.html#a9c81b37e547358cc588311d941649de1',1,'QwtCounter']]], + ['indent',['indent',['../class_qwt_text_label.html#a56d1c5c770efd4f829f33d0b42f00c9b',1,'QwtTextLabel']]], + ['index',['index',['../class_qwt_pixel_matrix.html#a786989b4ff383d7939edbba31c89178d',1,'QwtPixelMatrix']]], + ['infotoitem',['infoToItem',['../class_qwt_plot.html#a067fb3bbf8fb60921831bad7066605dc',1,'QwtPlot']]], + ['init',['init',['../class_qwt_plot_curve.html#a7afecd61327d56ddc76687d119e92b5d',1,'QwtPlotCurve::init()'],['../class_qwt_plot_interval_curve.html#a98d9de9cc61e59e24d72e4f459b4b321',1,'QwtPlotIntervalCurve::init()'],['../class_qwt_plot_trading_curve.html#a9fdb6082069ae913ed988137da1d57dd',1,'QwtPlotTradingCurve::init()']]], + ['initkeypattern',['initKeyPattern',['../class_qwt_event_pattern.html#a91c1acb96b5c3849b9518206290f7da8',1,'QwtEventPattern']]], + ['initmousepattern',['initMousePattern',['../class_qwt_event_pattern.html#ab885e0f266fd5b574ccbc6272225f486',1,'QwtEventPattern']]], + ['initraster',['initRaster',['../class_qwt_raster_data.html#a64f5bf40b6138cc66719a56555c03589',1,'QwtRasterData']]], + ['innerrect',['innerRect',['../class_qwt_dial.html#a258643394b1fb9b02ecd573d49a2abb6',1,'QwtDial']]], + ['insertitem',['insertItem',['../class_qwt_plot_dict.html#a36a00709420eb4f54b046e64561d5186',1,'QwtPlotDict']]], + ['insertlegend',['insertLegend',['../class_qwt_plot.html#a022a535ad11bebeaf9204a4fb8c4c430',1,'QwtPlot']]], + ['intersect',['intersect',['../class_qwt_interval.html#aa4df23450ffa012e1fedd13509402483',1,'QwtInterval']]], + ['intersects',['intersects',['../class_qwt_interval.html#a46a768a591a9a600f9885bd15a60da5b',1,'QwtInterval']]], + ['interval',['interval',['../class_qwt_plot_raster_item.html#a0ffa377f71d05a0d3d077e040b08c357',1,'QwtPlotRasterItem::interval()'],['../class_qwt_plot_rescaler.html#a52a1d762ba0add0a49c632a735d624c1',1,'QwtPlotRescaler::interval()'],['../class_qwt_plot_spectrogram.html#a958a45464b5946aff31b7d28b7cfb5f9',1,'QwtPlotSpectrogram::interval()'],['../class_qwt_plot_zone_item.html#ac35ff886b2313394fee77b2126d59d1a',1,'QwtPlotZoneItem::interval()'],['../class_qwt_synthetic_point_data.html#acd5ffffb670778cfd714bc915615851e',1,'QwtSyntheticPointData::interval()'],['../class_qwt_raster_data.html#a8423d051697f975150b3b555bfcac8b9',1,'QwtRasterData::interval()'],['../class_qwt_sampling_thread.html#a4a2f5038c02c8cad5ebc1fae01480e73',1,'QwtSamplingThread::interval()'],['../class_qwt_scale_div.html#a00fa69fed58c7a8ce6c855bb4df799f0',1,'QwtScaleDiv::interval()']]], + ['intervalhint',['intervalHint',['../class_qwt_plot_rescaler.html#a9bd02f1786d7503bd0d3e973799739ce',1,'QwtPlotRescaler']]], + ['intervaltype',['intervalType',['../class_qwt_date_scale_draw.html#a7afcabca6cedf6f764a3a853eb143e1a',1,'QwtDateScaleDraw::intervalType()'],['../class_qwt_date_scale_engine.html#ab813083a22cd7e001bd68c9e2a9685bc',1,'QwtDateScaleEngine::intervalType()']]], + ['invalidate',['invalidate',['../class_qwt_dyn_grid_layout.html#acb55e24d5bc569c9822110d538e3a82e',1,'QwtDynGridLayout::invalidate()'],['../class_qwt_interval.html#a66c1d4ed7836dfbf3c6e851479ff32cf',1,'QwtInterval::invalidate()'],['../class_qwt_plot_layout.html#a44ce72879951571ffe4daa95be0ec242',1,'QwtPlotLayout::invalidate()']]], + ['invalidatebackingstore',['invalidateBackingStore',['../class_qwt_plot_canvas.html#adafbfa908b2d3b6cf9c20aa6cf9abe27',1,'QwtPlotCanvas']]], + ['invalidatecache',['invalidateCache',['../class_qwt_abstract_scale_draw.html#a4ed95cd23c5d779c1b05aa5295409aa6',1,'QwtAbstractScaleDraw::invalidateCache()'],['../class_qwt_dial.html#a8308ea7345348c683cd957de2ef5ca91',1,'QwtDial::invalidateCache()'],['../class_qwt_plot_raster_item.html#a547ce4d8d031b230226cfbd509ef65b5',1,'QwtPlotRasterItem::invalidateCache()'],['../class_qwt_plot_text_label.html#ac498a144d548eddd4209da5979815c76',1,'QwtPlotTextLabel::invalidateCache()'],['../class_qwt_symbol.html#a781dee5e5db701df592378eb71d84088',1,'QwtSymbol::invalidateCache()']]], + ['invert',['invert',['../class_qwt_scale_div.html#a1ea38d52d5836fd4376f480180973786',1,'QwtScaleDiv']]], + ['inverted',['inverted',['../class_qwt_interval.html#ac55c2cc97b9f7973cb3fab4536f48486',1,'QwtInterval::inverted()'],['../class_qwt_scale_div.html#a3e35d44b9b41656fb3b241a9b11ddaa4',1,'QwtScaleDiv::inverted()']]], + ['invertedcontrols',['invertedControls',['../class_qwt_abstract_slider.html#a3bc58490cd1f5a8ed5e86dec2a60586a',1,'QwtAbstractSlider']]], + ['invtransform',['invTransform',['../class_qwt_abstract_scale.html#a7907d116b784dea443ba50c43113c053',1,'QwtAbstractScale::invTransform()'],['../class_qwt_plot.html#ab98066e62e3a9f574f8f1d482974ef5c',1,'QwtPlot::invTransform()'],['../class_qwt_plot_picker.html#a259fb95f14eef08b24ba454d9b51d084',1,'QwtPlotPicker::invTransform(const QRect &) const '],['../class_qwt_plot_picker.html#a0e02acfa2bed42ab691bc0a50d39727b',1,'QwtPlotPicker::invTransform(const QPoint &) const '],['../class_qwt_scale_map.html#a9f973f23b61ed18dd7598255078bd837',1,'QwtScaleMap::invTransform(double p) const '],['../class_qwt_scale_map.html#a8fe572f224a14672684fd929c55568f8',1,'QwtScaleMap::invTransform(const QwtScaleMap &, const QwtScaleMap &, const QRectF &)'],['../class_qwt_scale_map.html#a08dc05a17283c531e2c1d79fd52bc56a',1,'QwtScaleMap::invTransform(const QwtScaleMap &, const QwtScaleMap &, const QPointF &)'],['../class_qwt_transform.html#a5cfb0a329b8418028baf6974b188d76b',1,'QwtTransform::invTransform()'],['../class_qwt_null_transform.html#aa52cc18dcd1d0cd37a950fb71ef68a1c',1,'QwtNullTransform::invTransform()'],['../class_qwt_log_transform.html#a7c9e1e11e9708aecef2df4dac0c7d56b',1,'QwtLogTransform::invTransform()'],['../class_qwt_power_transform.html#aae19e2002b08ab09ed177d8ff6753f82',1,'QwtPowerTransform::invTransform()']]], + ['isactive',['isActive',['../class_qwt_picker.html#af825f383c74928d1541f139e102983f9',1,'QwtPicker']]], + ['isaligning',['isAligning',['../class_qwt_painter.html#a5d62fd1bd470fa0d42b7b2e06504a581',1,'QwtPainter']]], + ['isaxisenabled',['isAxisEnabled',['../class_qwt_plot_magnifier.html#acb4c33465bdd3c19c07ea3fa836c1f8d',1,'QwtPlotMagnifier::isAxisEnabled()'],['../class_qwt_plot_panner.html#a30fc7de4bede9f191a96df42f86e704b',1,'QwtPlotPanner::isAxisEnabled()']]], + ['ischecked',['isChecked',['../class_qwt_legend_label.html#a60e810de6309544227293b70a2f225ce',1,'QwtLegendLabel']]], + ['iscolorbarenabled',['isColorBarEnabled',['../class_qwt_scale_widget.html#a0572bc26f5b99654067b916001bce582',1,'QwtScaleWidget']]], + ['isdown',['isDown',['../class_qwt_legend_label.html#a1693d4581c50054acdcf8c810548e6b0',1,'QwtLegendLabel']]], + ['isempty',['isEmpty',['../class_qwt_abstract_legend.html#a9904720ba92daf03d0e5d8559cc5cdfe',1,'QwtAbstractLegend::isEmpty()'],['../class_qwt_dyn_grid_layout.html#a755f41277b43417d6b719704dc2c0d29',1,'QwtDynGridLayout::isEmpty()'],['../class_qwt_graphic.html#ab733c7e707f29adc80676059ade5de50',1,'QwtGraphic::isEmpty()'],['../class_qwt_legend.html#a6ff50cb1e388a7da2a59709eef83be20',1,'QwtLegend::isEmpty()'],['../class_qwt_scale_div.html#a76e4ef37b52fcf224de98a913635fdf6',1,'QwtScaleDiv::isEmpty()'],['../class_qwt_text.html#a25843b1120b648752ed5be2247ebe43f',1,'QwtText::isEmpty()']]], + ['isenabled',['isEnabled',['../class_qwt_magnifier.html#a65552cac613ceac77e51b8deca522509',1,'QwtMagnifier::isEnabled()'],['../class_qwt_panner.html#a7b0bae829d1ee12208ab8722d52d15a1',1,'QwtPanner::isEnabled()'],['../class_qwt_picker.html#a984299a27421d57291bb84c8c08df4e5',1,'QwtPicker::isEnabled()'],['../class_qwt_plot_rescaler.html#afdafabbb963aa5b13ce4a6bae33958da',1,'QwtPlotRescaler::isEnabled()']]], + ['isincreasing',['isIncreasing',['../class_qwt_scale_div.html#ab4623880c2c2f789fdc3a9f5e6058484',1,'QwtScaleDiv']]], + ['isinverted',['isInverted',['../class_qwt_abstract_scale.html#a3d46b81ff8b0ace8cc5b64a4984a63f6',1,'QwtAbstractScale::isInverted()'],['../class_qwt_wheel.html#ab48b28394d4bfedcc877cac45f2fd540',1,'QwtWheel::isInverted()']]], + ['isinverting',['isInverting',['../class_qwt_scale_map.html#aee1376468f91fa74715a0cad6cf1f6dc',1,'QwtScaleMap']]], + ['isnull',['isNull',['../class_qwt_graphic.html#a1b764ed0f9855aea3d7957e9bea54648',1,'QwtGraphic::isNull()'],['../class_qwt_interval.html#ac5e85b71e18fa43c92984e08c4549830',1,'QwtInterval::isNull()'],['../class_qwt_point3_d.html#a4542223c75e50afac7124cd44ca9c900',1,'QwtPoint3D::isNull()'],['../class_qwt_point_polar.html#a73d21f582ee5960011300598e17fab00',1,'QwtPointPolar::isNull()'],['../class_qwt_system_clock.html#a5432c09607488f9bb7e3d7592518efb1',1,'QwtSystemClock::isNull()'],['../class_qwt_text.html#afdf53f75d1b8ce6f2f0b00df59fa0177',1,'QwtText::isNull()']]], + ['isorientationenabled',['isOrientationEnabled',['../class_qwt_panner.html#ac1117576e69a4f32d24ef5ec81da7bbd',1,'QwtPanner']]], + ['ispinpointenabled',['isPinPointEnabled',['../class_qwt_symbol.html#aa0e0393dbd5df4f6a01c8a69ffc0203f',1,'QwtSymbol']]], + ['isreadonly',['isReadOnly',['../class_qwt_abstract_slider.html#a040fd1fd03592c524314bf4b5539608d',1,'QwtAbstractSlider::isReadOnly()'],['../class_qwt_counter.html#af6e5c64758c6b320a55e04fcb0188e67',1,'QwtCounter::isReadOnly()']]], + ['isscaledivfromaxis',['isScaleDivFromAxis',['../class_qwt_plot_scale_item.html#a05c89366c36fb0417e76b1a93d1ef93c',1,'QwtPlotScaleItem']]], + ['isscrollposition',['isScrollPosition',['../class_qwt_abstract_slider.html#ae674fc01201ec3ae4964838ef539c88e',1,'QwtAbstractSlider::isScrollPosition()'],['../class_qwt_dial.html#ab88967335d1269331b2e4b329a9a0ffe',1,'QwtDial::isScrollPosition()'],['../class_qwt_knob.html#ae82446b733a33dcbceee356683dff29c',1,'QwtKnob::isScrollPosition()'],['../class_qwt_slider.html#a01cce62d0609ebb6c95deb53d9f05785',1,'QwtSlider::isScrollPosition()']]], + ['istracking',['isTracking',['../class_qwt_abstract_slider.html#a476e7638818d5d22cb6f68d17d11ba97',1,'QwtAbstractSlider::isTracking()'],['../class_qwt_wheel.html#a2a8e72ae875c699d285698ae4fb79731',1,'QwtWheel::isTracking()']]], + ['isvalid',['isValid',['../class_qwt_abstract_slider.html#a87c750f098cb5f70306a7908339cb88e',1,'QwtAbstractSlider::isValid()'],['../class_qwt_counter.html#a0a6d0889d8d9e4fd956e4f3882fb319e',1,'QwtCounter::isValid()'],['../class_qwt_interval.html#af7ddb2347a4b5ed2205f84372e41c99e',1,'QwtInterval::isValid()'],['../class_qwt_legend_data.html#a4f77fc2e39d6187fb58aeb964049b4c6',1,'QwtLegendData::isValid()'],['../class_qwt_point_polar.html#ad1f8c93359d28322b6e3eeb9758a66f2',1,'QwtPointPolar::isValid()'],['../class_qwt_o_h_l_c_sample.html#a882c50b7c38caccb3486602a414dcd8e',1,'QwtOHLCSample::isValid()'],['../class_qwt_spline.html#a8eb42cf7f0f81bb7b7b885466f8ebbbf',1,'QwtSpline::isValid()']]], + ['isvisible',['isVisible',['../class_qwt_plot_item.html#aeaf8eeb5f080017e181a5d7be798d789',1,'QwtPlotItem']]], + ['isx11graphicssystem',['isX11GraphicsSystem',['../class_qwt_painter.html#af352ad92f1c1dc8cfee0f3d799e2e26e',1,'QwtPainter']]], + ['itemat',['itemAt',['../class_qwt_dyn_grid_layout.html#adbec8dc847c4159d0765c8f0dd80d148',1,'QwtDynGridLayout']]], + ['itemattached',['itemAttached',['../class_qwt_plot.html#a09e33984e3d5635475ef218ac0bd85eb',1,'QwtPlot']]], + ['itemchanged',['itemChanged',['../class_qwt_plot_item.html#ad956fdbce5b0721abccce6d09fe4d5ce',1,'QwtPlotItem']]], + ['itemchecked',['itemChecked',['../class_qwt_legend.html#a19429ac46c36ca12531779099476ac8a',1,'QwtLegend']]], + ['itemclicked',['itemClicked',['../class_qwt_legend.html#a9e0e1b18a6d18b113802935bb6135921',1,'QwtLegend']]], + ['itemcount',['itemCount',['../class_qwt_dyn_grid_layout.html#ad7df7a3f47055041d6dd5ab1c4c660e0',1,'QwtDynGridLayout']]], + ['iteminfo',['itemInfo',['../class_qwt_legend.html#abd89da0c3ad3d9587ad35b63b424a73b',1,'QwtLegend']]], + ['itemlist',['itemList',['../class_qwt_plot_dict.html#a9cbb1c5c22de93594b7e2524af108f55',1,'QwtPlotDict::itemList() const '],['../class_qwt_plot_dict.html#a0979adc53ad5ecf5e4a93aa9b5a4df38',1,'QwtPlotDict::itemList(int rtti) const ']]], + ['itemmargin',['itemMargin',['../class_qwt_plot_legend_item.html#a7024ac39e0a9ce5b003089191c78b93d',1,'QwtPlotLegendItem']]], + ['itemmode',['itemMode',['../class_qwt_legend_label.html#a2c9266255b3d1cf1fb95394e62bc6cc2',1,'QwtLegendLabel']]], + ['itemspacing',['itemSpacing',['../class_qwt_plot_legend_item.html#a2a57286be83056770ec7971ff885e393',1,'QwtPlotLegendItem']]], + ['itemtoinfo',['itemToInfo',['../class_qwt_plot.html#a8f12d09af448489f705faecdaee5d8c2',1,'QwtPlot']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/functions_6b.html b/ThirdParty/Qwt/doc/html/search/functions_6b.html new file mode 100644 index 0000000000..a0d07a92d0 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/functions_6b.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/functions_6b.js b/ThirdParty/Qwt/doc/html/search/functions_6b.js new file mode 100644 index 0000000000..9f9b7b6064 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/functions_6b.js @@ -0,0 +1,11 @@ +var searchData= +[ + ['keyfactor',['keyFactor',['../class_qwt_magnifier.html#a98706c848275b06d2830a8dbe053c9a3',1,'QwtMagnifier']]], + ['keymatch',['keyMatch',['../class_qwt_event_pattern.html#ab4be2d84b3d73ff05d6c19f6fd9f75bc',1,'QwtEventPattern::keyMatch(KeyPatternCode, const QKeyEvent *) const '],['../class_qwt_event_pattern.html#ac2748e712cbfa8ce9eb12a3364b862de',1,'QwtEventPattern::keyMatch(const KeyPattern &, const QKeyEvent *) const ']]], + ['keypattern',['KeyPattern',['../class_qwt_event_pattern_1_1_key_pattern.html#ac52d2d39d519c750194462c8da4c8ec2',1,'QwtEventPattern::KeyPattern::KeyPattern()'],['../class_qwt_event_pattern.html#a3c8dfef92d0808da60d0f7b094ba7f26',1,'QwtEventPattern::keyPattern() const '],['../class_qwt_event_pattern.html#a9d8ea5b5ffea570c1fed4c8ca8e5cfff',1,'QwtEventPattern::keyPattern()']]], + ['keypressevent',['keyPressEvent',['../class_qwt_abstract_slider.html#ab6d1105f82e8a44ea75661135ba88c85',1,'QwtAbstractSlider::keyPressEvent()'],['../class_qwt_arrow_button.html#a17612daa99344272c4de1313a5c67b02',1,'QwtArrowButton::keyPressEvent()'],['../class_qwt_compass.html#ad4f31e6837ea045834fe67d192a4209d',1,'QwtCompass::keyPressEvent()'],['../class_qwt_counter.html#aafdc19bff96fcafc4b8ed8e3bf7bf07b',1,'QwtCounter::keyPressEvent()'],['../class_qwt_legend_label.html#a801059fdc196563ca28fd22fb3675024',1,'QwtLegendLabel::keyPressEvent()'],['../class_qwt_wheel.html#a29c6b09213126e9e14c853e13108e262',1,'QwtWheel::keyPressEvent()']]], + ['keyreleaseevent',['keyReleaseEvent',['../class_qwt_legend_label.html#aed12dffa845db6538f15cb45077cfb76',1,'QwtLegendLabel']]], + ['knobrect',['knobRect',['../class_qwt_knob.html#ad4bf9ef0988ac377577b21319e498231',1,'QwtKnob']]], + ['knobstyle',['knobStyle',['../class_qwt_knob.html#a6f8ec8b610b500990dff31f370cab8ba',1,'QwtKnob']]], + ['knobwidth',['knobWidth',['../class_qwt_knob.html#aa9470eed740c7175c7ccfc4406eb5fc2',1,'QwtKnob']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/functions_6c.html b/ThirdParty/Qwt/doc/html/search/functions_6c.html new file mode 100644 index 0000000000..33c0d6dd14 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/functions_6c.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/functions_6c.js b/ThirdParty/Qwt/doc/html/search/functions_6c.js new file mode 100644 index 0000000000..67acbf9633 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/functions_6c.js @@ -0,0 +1,41 @@ +var searchData= +[ + ['label',['label',['../class_qwt_abstract_scale_draw.html#a4ff88bc827dd6c6ca9298de13483b61f',1,'QwtAbstractScaleDraw::label()'],['../class_qwt_compass_scale_draw.html#acb6bfc20d538242fec35b6902dcb8ab1',1,'QwtCompassScaleDraw::label()'],['../class_qwt_date_scale_draw.html#a16207bc20afaaf6959f11cf0343da82c',1,'QwtDateScaleDraw::label()'],['../class_qwt_plot_marker.html#acf81c4a657fd772cf7c5387a19ab6793',1,'QwtPlotMarker::label()']]], + ['labelalignment',['labelAlignment',['../class_qwt_plot_marker.html#a16415f05a235642e2b93df9e4685d68e',1,'QwtPlotMarker::labelAlignment()'],['../class_qwt_scale_draw.html#ad024fd550ecc3816ee8886417794aae2',1,'QwtScaleDraw::labelAlignment()']]], + ['labelmap',['labelMap',['../class_qwt_compass_scale_draw.html#a92c0f162873b8ccd7bcf814f82b39819',1,'QwtCompassScaleDraw']]], + ['labelorientation',['labelOrientation',['../class_qwt_plot_marker.html#ab3be191bccfa7e668cc2ae8303c43c18',1,'QwtPlotMarker']]], + ['labelposition',['labelPosition',['../class_qwt_scale_draw.html#af0993dc0226ca63a2994f48ef6198c48',1,'QwtScaleDraw']]], + ['labelrect',['labelRect',['../class_qwt_arrow_button.html#ae32f665bfa6ab478e4ba7fd068bb3088',1,'QwtArrowButton::labelRect()'],['../class_qwt_scale_draw.html#a61ed70aef675f8694b4888f02c8ae83c',1,'QwtScaleDraw::labelRect()']]], + ['labelrotation',['labelRotation',['../class_qwt_scale_draw.html#a614f18b99f53e6a6282c39f95388face',1,'QwtScaleDraw']]], + ['labelsize',['labelSize',['../class_qwt_scale_draw.html#a49352345ab223395b7ff95c82b92c819',1,'QwtScaleDraw']]], + ['labeltransformation',['labelTransformation',['../class_qwt_scale_draw.html#a0efa1e4675c85b3187aa69220d135dc4',1,'QwtScaleDraw']]], + ['layoutflags',['layoutFlags',['../class_qwt_plot_renderer.html#a0989c9a2b03069418d1f097d14dd1b0b',1,'QwtPlotRenderer']]], + ['layoutgrid',['layoutGrid',['../class_qwt_dyn_grid_layout.html#aab4aede7957a5a84403cb88da387d8dc',1,'QwtDynGridLayout']]], + ['layouthint',['layoutHint',['../class_qwt_plot_abstract_bar_chart.html#a0fad5758160f0a84467771c44cd88675',1,'QwtPlotAbstractBarChart']]], + ['layoutitems',['layoutItems',['../class_qwt_dyn_grid_layout.html#a0fe5c2a70d1086036fac2487cc982341',1,'QwtDynGridLayout']]], + ['layoutlegend',['layoutLegend',['../class_qwt_plot_layout.html#ae5eebbda9691833dfb5d2aa6a193f131',1,'QwtPlotLayout']]], + ['layoutpolicy',['layoutPolicy',['../class_qwt_plot_abstract_bar_chart.html#a940affbba9565ae4e5b2a6d61ef1cd8c',1,'QwtPlotAbstractBarChart']]], + ['layoutscale',['layoutScale',['../class_qwt_scale_widget.html#a5964a55d1572ea775eae3ca93a755358',1,'QwtScaleWidget']]], + ['legend',['legend',['../class_qwt_plot.html#ab45dd6bc980376d0ba648fefb87103f8',1,'QwtPlot::legend()'],['../class_qwt_plot.html#aa82dbb3bae37e660a7707640b99ca29e',1,'QwtPlot::legend() const ']]], + ['legendchanged',['legendChanged',['../class_qwt_plot_item.html#a3967414c7542e267d0c2793f02be7241',1,'QwtPlotItem']]], + ['legenddata',['legendData',['../class_qwt_plot_bar_chart.html#aab363d4fbe516f7e2db3796a93745e83',1,'QwtPlotBarChart::legendData()'],['../class_qwt_plot_item.html#a584b37b42cb2c63424cedade1f4d7221',1,'QwtPlotItem::legendData()'],['../class_qwt_plot_multi_bar_chart.html#aaa178e1310e20219976db52c8beea2e5',1,'QwtPlotMultiBarChart::legendData()']]], + ['legenddatachanged',['legendDataChanged',['../class_qwt_plot.html#acf7bcea83713f73e5914325c50a1c22b',1,'QwtPlot']]], + ['legendgeometries',['legendGeometries',['../class_qwt_plot_legend_item.html#aca33e96eaa79ad4e220a52c9c25fa224',1,'QwtPlotLegendItem']]], + ['legendicon',['legendIcon',['../class_qwt_plot_bar_chart.html#a9563e64873ecf0589adae350b0ba5240',1,'QwtPlotBarChart::legendIcon()'],['../class_qwt_plot_curve.html#a2ac863876e1e2a7f30f6d4fbc9ca677e',1,'QwtPlotCurve::legendIcon()'],['../class_qwt_plot_histogram.html#a541b2532b9437979b35f78a44ac5ff3e',1,'QwtPlotHistogram::legendIcon()'],['../class_qwt_plot_interval_curve.html#ac7ad3b7a2a70aef77c15a75101c36bf4',1,'QwtPlotIntervalCurve::legendIcon()'],['../class_qwt_plot_item.html#ab192921c0d3c94832c6f617716a6b275',1,'QwtPlotItem::legendIcon()'],['../class_qwt_plot_marker.html#afd4de898e8615b6cec8c6f090b585c1b',1,'QwtPlotMarker::legendIcon()'],['../class_qwt_plot_multi_bar_chart.html#a9200443a4ff8b88041136b2292d63965',1,'QwtPlotMultiBarChart::legendIcon()'],['../class_qwt_plot_shape_item.html#aacaaf2fb5cc5011d0c7164a26c1af2df',1,'QwtPlotShapeItem::legendIcon()'],['../class_qwt_plot_trading_curve.html#ad88db48643d8119e8077a0b2c9dad0f1',1,'QwtPlotTradingCurve::legendIcon()']]], + ['legendiconsize',['legendIconSize',['../class_qwt_plot_item.html#a3239ad2b425382e153e80cc393dd4fc2',1,'QwtPlotItem']]], + ['legendmode',['legendMode',['../class_qwt_plot_bar_chart.html#a9caca23828aea1b5fb4907bb42f4cffb',1,'QwtPlotBarChart::legendMode()'],['../class_qwt_plot_shape_item.html#ad7a855b061225ffd312415c3ace9a0a0',1,'QwtPlotShapeItem::legendMode()']]], + ['legendposition',['legendPosition',['../class_qwt_plot_layout.html#a6351a18b76e22d9e83d682d203599afc',1,'QwtPlotLayout']]], + ['legendratio',['legendRatio',['../class_qwt_plot_layout.html#a6d5d4e568ad74010742e1fdcfc1c7672',1,'QwtPlotLayout']]], + ['legendrect',['legendRect',['../class_qwt_plot_layout.html#a638c809e0612ab1ee67d0f3a25600289',1,'QwtPlotLayout']]], + ['legendwidget',['legendWidget',['../class_qwt_legend.html#a232dcbd75b79304983b92956b576a8a6',1,'QwtLegend']]], + ['legendwidgets',['legendWidgets',['../class_qwt_legend.html#a999f58842126639610f3131fdb750358',1,'QwtLegend']]], + ['length',['length',['../class_qwt_scale_draw.html#a82f2a2d25d4ecc2a781a252ef9515704',1,'QwtScaleDraw']]], + ['limited',['limited',['../class_qwt_interval.html#a7ba77698fdc61495ff4fbbaf3095184b',1,'QwtInterval']]], + ['linepen',['linePen',['../class_qwt_plot_marker.html#a744b2aa104fa41d2f09c6658749c2d72',1,'QwtPlotMarker']]], + ['linestyle',['lineStyle',['../class_qwt_plot_marker.html#a9afac9382c6e482ea0181048b155e287',1,'QwtPlotMarker']]], + ['linewidth',['lineWidth',['../class_qwt_column_symbol.html#afe6850ba90ade0fdf61edd203e49206d',1,'QwtColumnSymbol::lineWidth()'],['../class_qwt_dial.html#afb583edf70364eb562bf84686b60a9b7',1,'QwtDial::lineWidth()'],['../class_qwt_plot_g_l_canvas.html#af171f7b3727852df3062a975251eb976',1,'QwtPlotGLCanvas::lineWidth()']]], + ['loaddata',['loadData',['../class_qwt_plot_svg_item.html#a9e611f0c845289ddfb9758fa4479e719',1,'QwtPlotSvgItem']]], + ['loadfile',['loadFile',['../class_qwt_plot_svg_item.html#aca9592f3d3dca512b7970851b159cf57',1,'QwtPlotSvgItem']]], + ['lowerbound',['lowerBound',['../class_qwt_abstract_scale.html#a093b44d00c18164c2814c3b999066dc7',1,'QwtAbstractScale::lowerBound()'],['../class_qwt_scale_div.html#a7b9b339170625553fbb488c7877372d0',1,'QwtScaleDiv::lowerBound()']]], + ['lowermargin',['lowerMargin',['../class_qwt_scale_engine.html#a0cbcd5c35a8796baf8307bba19991bab',1,'QwtScaleEngine']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/functions_6d.html b/ThirdParty/Qwt/doc/html/search/functions_6d.html new file mode 100644 index 0000000000..73fecffde8 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/functions_6d.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/functions_6d.js b/ThirdParty/Qwt/doc/html/search/functions_6d.js new file mode 100644 index 0000000000..8c3d4ad2b4 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/functions_6d.js @@ -0,0 +1,54 @@ +var searchData= +[ + ['majorpen',['majorPen',['../class_qwt_plot_grid.html#a7a3ff3aed415e3f2315514ae798f433e',1,'QwtPlotGrid']]], + ['margin',['margin',['../class_qwt_plot_abstract_bar_chart.html#af82ec574a3c6031d35c423b54afcfde6',1,'QwtPlotAbstractBarChart::margin()'],['../class_qwt_plot_legend_item.html#ac146ccfb6e0f3c85bed5d2a898a5ffc8',1,'QwtPlotLegendItem::margin()'],['../class_qwt_plot_text_label.html#a259ab949f5434091f34fe71b12ec72ab',1,'QwtPlotTextLabel::margin()'],['../class_qwt_scale_widget.html#a4827906c3f11825d479c6e493c8e1b4c',1,'QwtScaleWidget::margin()'],['../class_qwt_text_label.html#ab754bebe50bc0e713cde9ba58bf6c3c8',1,'QwtTextLabel::margin()']]], + ['markersize',['markerSize',['../class_qwt_knob.html#a502582b7f31df549e07664e874607a1e',1,'QwtKnob']]], + ['markerstyle',['markerStyle',['../class_qwt_knob.html#af7d2aaab6614c8e49974823333215bf7',1,'QwtKnob']]], + ['maskhint',['maskHint',['../class_qwt_widget_overlay.html#ad5c0592969220c56494be3034e5a83de',1,'QwtWidgetOverlay']]], + ['maskmode',['maskMode',['../class_qwt_widget_overlay.html#a161e7b6614b8e4ab0377eba9ce8a3f5a',1,'QwtWidgetOverlay']]], + ['mass',['mass',['../class_qwt_wheel.html#a55de1496f0eef04da9bc293306a40df6',1,'QwtWheel']]], + ['maxcolumns',['maxColumns',['../class_qwt_dyn_grid_layout.html#a06b418089a233555dd3354d98b712c3e',1,'QwtDynGridLayout::maxColumns()'],['../class_qwt_legend.html#ade4944cabe8f165bb1c218155a2ef251',1,'QwtLegend::maxColumns()'],['../class_qwt_plot_legend_item.html#addf073d47a835cf50dce684667a377ba',1,'QwtPlotLegendItem::maxColumns()']]], + ['maxdate',['maxDate',['../class_qwt_date.html#af82ba26011550602f1adb61da53bd830',1,'QwtDate']]], + ['maximum',['maximum',['../class_qwt_abstract_scale.html#a92d1f793aa5dc3c18f96448d43bd255e',1,'QwtAbstractScale::maximum()'],['../class_qwt_counter.html#a82dead63dd6b56056251b84848ab1b75',1,'QwtCounter::maximum()'],['../class_qwt_wheel.html#a5f79673a9ba7e8cbf47f5f88e5367a32',1,'QwtWheel::maximum()']]], + ['maxitemwidth',['maxItemWidth',['../class_qwt_dyn_grid_layout.html#a74ebb14c4b4fae32354d3824bf29c93e',1,'QwtDynGridLayout']]], + ['maxlabelheight',['maxLabelHeight',['../class_qwt_scale_draw.html#ab5fcdcbb4c3fe419e48efd3068ecd3e4',1,'QwtScaleDraw']]], + ['maxlabelwidth',['maxLabelWidth',['../class_qwt_scale_draw.html#ab0c4ee29e81cee70e8a491e5ff80b8ff',1,'QwtScaleDraw']]], + ['maxscalearc',['maxScaleArc',['../class_qwt_dial.html#a9d7a976894700e616126d41a312f999d',1,'QwtDial']]], + ['maxstackdepth',['maxStackDepth',['../class_qwt_plot_zoomer.html#ac0d39d53af224cbeda37e0417d084dab',1,'QwtPlotZoomer']]], + ['maxsymbolwidth',['maxSymbolWidth',['../class_qwt_plot_trading_curve.html#a73fd6f5b6555ac4789930b5a908732ca',1,'QwtPlotTradingCurve']]], + ['maxticklength',['maxTickLength',['../class_qwt_abstract_scale_draw.html#afac6ad0e98fefd9d103366726542a055',1,'QwtAbstractScaleDraw']]], + ['maxvalue',['maxValue',['../class_qwt_interval.html#aac7cffc81147c07efc4a95c2e6222a1a',1,'QwtInterval']]], + ['maxweeks',['maxWeeks',['../class_qwt_date_scale_engine.html#a1e1168602421de588ec7c5615100e22f',1,'QwtDateScaleEngine']]], + ['maxxvalue',['maxXValue',['../class_qwt_plot_curve.html#a2428e72e84b23a9442ae48fe4540c17f',1,'QwtPlotCurve']]], + ['maxyvalue',['maxYValue',['../class_qwt_plot_curve.html#a135a412978bf646716b37b0ac8528665',1,'QwtPlotCurve']]], + ['metric',['metric',['../class_qwt_null_paint_device.html#a014f8bf4ba5f58df3d17747e09d8f539',1,'QwtNullPaintDevice']]], + ['midlinewidth',['midLineWidth',['../class_qwt_plot_g_l_canvas.html#af4d70838d3af7c8521fe313b813c347e',1,'QwtPlotGLCanvas']]], + ['mightrender',['mightRender',['../class_qwt_text_engine.html#a98316f2f6f4f50216ceffbe9babe2901',1,'QwtTextEngine::mightRender()'],['../class_qwt_plain_text_engine.html#ae7bd7417f0173e2d35fe1bf7a514ec9b',1,'QwtPlainTextEngine::mightRender()'],['../class_qwt_rich_text_engine.html#a42da46eee5fbda55e34b18c64b0b5e0b',1,'QwtRichTextEngine::mightRender()'],['../class_qwt_math_m_l_text_engine.html#a59ca5842c32fd12cfd2aeeef5c985600',1,'QwtMathMLTextEngine::mightRender()']]], + ['mindate',['minDate',['../class_qwt_date.html#a9ab1845543957472c2c6529ad03ef98d',1,'QwtDate']]], + ['minimum',['minimum',['../class_qwt_abstract_scale.html#ac71c042246a7bb684c1b41c0204b6f14',1,'QwtAbstractScale::minimum()'],['../class_qwt_counter.html#aa653ae82690f6ea0ba1b3fb9081ce67a',1,'QwtCounter::minimum()'],['../class_qwt_wheel.html#a88e7f5245b579d112a516cbd447e07f3',1,'QwtWheel::minimum()']]], + ['minimumextent',['minimumExtent',['../class_qwt_abstract_scale_draw.html#a563f102ef1370ecdfdc47133fb0c78ec',1,'QwtAbstractScaleDraw']]], + ['minimumsize',['minimumSize',['../class_qwt_plot_legend_item.html#ad80478871117dc788d13cbef58759b4e',1,'QwtPlotLegendItem']]], + ['minimumsizehint',['minimumSizeHint',['../class_qwt_arrow_button.html#a5bc3817732a253bb214a94d1c76508ce',1,'QwtArrowButton::minimumSizeHint()'],['../class_qwt_dial.html#a21e46fa17a55b938c027ec7b4b97d157',1,'QwtDial::minimumSizeHint()'],['../class_qwt_knob.html#a03d014cd8d025bfeab6e004c53ab6e5b',1,'QwtKnob::minimumSizeHint()'],['../class_qwt_plot.html#a5a17d0ea2e9a977d48045e742f5b8cfd',1,'QwtPlot::minimumSizeHint()'],['../class_qwt_plot_layout.html#a068a12c510998760c727a095f5b055fe',1,'QwtPlotLayout::minimumSizeHint()'],['../class_qwt_scale_widget.html#aee41cd1b3eff4cf06559e7a36baee5a5',1,'QwtScaleWidget::minimumSizeHint()'],['../class_qwt_slider.html#a1cc878ed8746de2ea7c33a88f1c4652c',1,'QwtSlider::minimumSizeHint()'],['../class_qwt_text_label.html#a75ed6482ddb21e4f67ad9272f2ce66bb',1,'QwtTextLabel::minimumSizeHint()'],['../class_qwt_thermo.html#a7bdc0a01f646b3cacda48bffc7c2057d',1,'QwtThermo::minimumSizeHint()'],['../class_qwt_wheel.html#a668397451f5ad7b2a78d01d9e7141bcf',1,'QwtWheel::minimumSizeHint()']]], + ['minlabeldist',['minLabelDist',['../class_qwt_scale_draw.html#a1e60d584f563933afba119d443ba5b32',1,'QwtScaleDraw']]], + ['minlength',['minLength',['../class_qwt_scale_draw.html#a2fbdde2e1263664069e2e5f9a1fc9266',1,'QwtScaleDraw']]], + ['minorpen',['minorPen',['../class_qwt_plot_grid.html#a69000abf9f7b8b8d7d6ba605b38d5f67',1,'QwtPlotGrid']]], + ['minscalearc',['minScaleArc',['../class_qwt_dial.html#a1725682984aff88ef891966225c06030',1,'QwtDial']]], + ['minsymbolwidth',['minSymbolWidth',['../class_qwt_plot_trading_curve.html#a1903b1b153f85394e26831ffa708c471',1,'QwtPlotTradingCurve']]], + ['minvalue',['minValue',['../class_qwt_interval.html#a173c9193bd16f99589db60326df04310',1,'QwtInterval']]], + ['minxvalue',['minXValue',['../class_qwt_plot_curve.html#a20c92bfce270e71893cdfa465781017b',1,'QwtPlotCurve']]], + ['minyvalue',['minYValue',['../class_qwt_plot_curve.html#a09f7aac646f0e534c2540d61a027b856',1,'QwtPlotCurve']]], + ['minzoomsize',['minZoomSize',['../class_qwt_plot_zoomer.html#aca5523ed1676ca733fdaf7484a8b4499',1,'QwtPlotZoomer']]], + ['mode',['mode',['../class_qwt_linear_color_map.html#a9ec309df6ec88472a63b14ac2c692c96',1,'QwtLinearColorMap::mode()'],['../class_qwt_dial.html#afd95a47735c0cfe963dfacd1a6a36a6f',1,'QwtDial::mode()'],['../class_qwt_legend_data.html#a7cd0c8df579edddf8abfe6c7a87af07f',1,'QwtLegendData::mode()'],['../class_qwt_null_paint_device.html#ab8dd2303c06d6cbfa5f4c0fa442eb493',1,'QwtNullPaintDevice::mode()']]], + ['mousefactor',['mouseFactor',['../class_qwt_magnifier.html#a49348534d3cd7fe37a4a7cb6c3bbff8d',1,'QwtMagnifier']]], + ['mousematch',['mouseMatch',['../class_qwt_event_pattern.html#a4cf45668d0706d6dcb1108d549e061c0',1,'QwtEventPattern::mouseMatch(MousePatternCode, const QMouseEvent *) const '],['../class_qwt_event_pattern.html#a091006f03b17d638a84ab0211e5c39de',1,'QwtEventPattern::mouseMatch(const MousePattern &, const QMouseEvent *) const ']]], + ['mousemoveevent',['mouseMoveEvent',['../class_qwt_abstract_slider.html#a05ffec4c6b43909ecec148121a618f40',1,'QwtAbstractSlider::mouseMoveEvent()'],['../class_qwt_wheel.html#a1c7445264de07cacf72ec942e189713b',1,'QwtWheel::mouseMoveEvent()']]], + ['mousepattern',['MousePattern',['../class_qwt_event_pattern_1_1_mouse_pattern.html#a4233e9620cdad92c498a5271cd32bcf6',1,'QwtEventPattern::MousePattern::MousePattern()'],['../class_qwt_event_pattern.html#a40f66b9b22867b5066d92e9c3f629a81',1,'QwtEventPattern::mousePattern() const '],['../class_qwt_event_pattern.html#a141107868ed1c9cf1b34046873234390',1,'QwtEventPattern::mousePattern()']]], + ['mousepressevent',['mousePressEvent',['../class_qwt_abstract_slider.html#a8a9ac5817d109ccbec208b65772cacf5',1,'QwtAbstractSlider::mousePressEvent()'],['../class_qwt_legend_label.html#a2890c885c9665c7cfe630f7471337cb2',1,'QwtLegendLabel::mousePressEvent()'],['../class_qwt_slider.html#aa326b252e90615537cd6633a5423f6c4',1,'QwtSlider::mousePressEvent()'],['../class_qwt_wheel.html#abf4ec8ed08f66034a9940dbb828703ac',1,'QwtWheel::mousePressEvent()']]], + ['mousereleaseevent',['mouseReleaseEvent',['../class_qwt_abstract_slider.html#aef54140a399f52c01cd9e82abf862783',1,'QwtAbstractSlider::mouseReleaseEvent()'],['../class_qwt_legend_label.html#a4b2c6badfcb25aea68fe3e72b134339e',1,'QwtLegendLabel::mouseReleaseEvent()'],['../class_qwt_slider.html#a801960c694bfd1dc6dcd8099553be7d7',1,'QwtSlider::mouseReleaseEvent()'],['../class_qwt_wheel.html#a0af92c432374d99d371ecd5570ea038e',1,'QwtWheel::mouseReleaseEvent()']]], + ['move',['move',['../class_qwt_picker.html#a59d92670978f200edb61e429afa06542',1,'QwtPicker::move()'],['../class_qwt_plot_picker.html#a7a979d23cd4d398e309409e76635bcf4',1,'QwtPlotPicker::move()'],['../class_qwt_scale_draw.html#a15f91bdd71ec87abe618e00cf18aa3f1',1,'QwtScaleDraw::move(double x, double y)'],['../class_qwt_scale_draw.html#a61f1b2112eb1fdd2bdeef429f7fc24d9',1,'QwtScaleDraw::move(const QPointF &)']]], + ['moveby',['moveBy',['../class_qwt_plot_zoomer.html#ac66b3eac03db212812198637f4e233ca',1,'QwtPlotZoomer']]], + ['movecanvas',['moveCanvas',['../class_qwt_plot_panner.html#aab045140de3e38d316593388da9231bd',1,'QwtPlotPanner']]], + ['movecenter',['moveCenter',['../class_qwt_round_scale_draw.html#af7e08b85826c5e1e5b1762fa07830107',1,'QwtRoundScaleDraw::moveCenter(double x, double y)'],['../class_qwt_round_scale_draw.html#a7be4951c2998474a79e4f1d621ea412a',1,'QwtRoundScaleDraw::moveCenter(const QPointF &)']]], + ['moved',['moved',['../class_qwt_panner.html#aa45ae2f4d6d20a83783898dd86d0b595',1,'QwtPanner::moved()'],['../class_qwt_picker.html#adddb4800c1dac0ba807e731f45d40742',1,'QwtPicker::moved()'],['../class_qwt_plot_picker.html#a4a35d30f1c4c4f80c49e3c6647b34e12',1,'QwtPlotPicker::moved()']]], + ['moveto',['moveTo',['../class_qwt_plot_zoomer.html#a40853271ba53bb66f9cf744ab69c1b13',1,'QwtPlotZoomer']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/functions_6e.html b/ThirdParty/Qwt/doc/html/search/functions_6e.html new file mode 100644 index 0000000000..5e54741d44 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/functions_6e.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/functions_6e.js b/ThirdParty/Qwt/doc/html/search/functions_6e.js new file mode 100644 index 0000000000..5504d988cd --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/functions_6e.js @@ -0,0 +1,12 @@ +var searchData= +[ + ['needle',['needle',['../class_qwt_dial.html#a58ed8cf5aae56c44427b25f691f69b5c',1,'QwtDial::needle() const '],['../class_qwt_dial.html#abbf494e72f6244e4ec88211354c739a4',1,'QwtDial::needle()']]], + ['normalized',['normalized',['../class_qwt_interval.html#a662aa6c6f7d575c72023eb32c0974508',1,'QwtInterval::normalized()'],['../class_qwt_point_polar.html#a2544921fb33e7601444223572243ed6a',1,'QwtPointPolar::normalized()']]], + ['num',['num',['../class_qwt_arrow_button.html#a09ae0f534912a14155233d7f431ffb2e',1,'QwtArrowButton']]], + ['numbuttons',['numButtons',['../class_qwt_counter.html#ac160c5e7a1c7f858b7f52ff0904ea142',1,'QwtCounter']]], + ['numcolumns',['numColumns',['../class_qwt_dyn_grid_layout.html#a968ad0c13f353d4fc62c7c097eb024fe',1,'QwtDynGridLayout::numColumns()'],['../class_qwt_matrix_raster_data.html#adbc9f8a45969a2673d2c0791ff7834b3',1,'QwtMatrixRasterData::numColumns()']]], + ['numrows',['numRows',['../class_qwt_dyn_grid_layout.html#ad3f387078e5e78b66b452c72e99923c2',1,'QwtDynGridLayout::numRows()'],['../class_qwt_matrix_raster_data.html#aaffe172692947226e0521798302dede7',1,'QwtMatrixRasterData::numRows()']]], + ['numthornlevels',['numThornLevels',['../class_qwt_simple_compass_rose.html#a8fa418ee344d934d556fa5719cd5ece5',1,'QwtSimpleCompassRose']]], + ['numthorns',['numThorns',['../class_qwt_simple_compass_rose.html#a7c3270789e94e94b8d515b04372bfe0b',1,'QwtSimpleCompassRose']]], + ['numturns',['numTurns',['../class_qwt_knob.html#aabeeacaf8f2c526f74eacbb043f4cfa3',1,'QwtKnob']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/functions_6f.html b/ThirdParty/Qwt/doc/html/search/functions_6f.html new file mode 100644 index 0000000000..9d6926417d --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/functions_6f.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/functions_6f.js b/ThirdParty/Qwt/doc/html/search/functions_6f.js new file mode 100644 index 0000000000..fae0151dd5 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/functions_6f.js @@ -0,0 +1,14 @@ +var searchData= +[ + ['operator_21_3d',['operator!=',['../class_qwt_interval.html#a4c1cb8360a05c1875f7957f00d3bdf16',1,'QwtInterval::operator!=()'],['../class_qwt_interval_symbol.html#a89737a98021a7ebf3eddd79469257411',1,'QwtIntervalSymbol::operator!=()'],['../class_qwt_point3_d.html#a38b3c81b7dfce567dfc2993db1aa6d74',1,'QwtPoint3D::operator!=()'],['../class_qwt_point_polar.html#af85df99741e28fbe6bdee96df42fb448',1,'QwtPointPolar::operator!=()'],['../class_qwt_interval_sample.html#a17e9ce13c70d8f5e369ee8ba6aec6e41',1,'QwtIntervalSample::operator!=()'],['../class_qwt_set_sample.html#a0b96a0b525bbf4aab51a406502c4734c',1,'QwtSetSample::operator!=()'],['../class_qwt_scale_div.html#a6bbd302e0628a5131f7d7c0c2e03f7d8',1,'QwtScaleDiv::operator!=()'],['../class_qwt_text.html#a092326f250d2b865ad93f16462d9fc9f',1,'QwtText::operator!=()']]], + ['operator_26',['operator&',['../class_qwt_interval.html#a87091a809fb14d2321240be47bb9cbe1',1,'QwtInterval']]], + ['operator_26_3d',['operator&=',['../class_qwt_interval.html#a31b75687b9d2e1931ec82f61cc644222',1,'QwtInterval']]], + ['operator_3d',['operator=',['../class_qwt_graphic.html#a56504c5384e140d199f73c6e729408ec',1,'QwtGraphic::operator=()'],['../class_qwt_interval_symbol.html#a49558f59372b7e69143f1ff49c5bfad8',1,'QwtIntervalSymbol::operator=()'],['../class_qwt_painter_command.html#a08dc6d9612be3a2e3abf2366935e7370',1,'QwtPainterCommand::operator=()'],['../class_qwt_scale_map.html#a3f55ef14f8874e626380fcf92b096791',1,'QwtScaleMap::operator=()'],['../class_qwt_spline.html#a8a597c34477dd4b5298db2d445b4e596',1,'QwtSpline::operator=()'],['../class_qwt_text.html#ad4a8678071c7e114c47a21f1f78cca37',1,'QwtText::operator=()']]], + ['operator_3d_3d',['operator==',['../class_qwt_interval.html#aec5aa21ab413fb5bfaa3360fae02e6b2',1,'QwtInterval::operator==()'],['../class_qwt_interval_symbol.html#a1fa66bf16cecbcc6a2a95d8484dbc0d3',1,'QwtIntervalSymbol::operator==()'],['../class_qwt_point3_d.html#aaafd119aea020d1e7e44360fd1172c22',1,'QwtPoint3D::operator==()'],['../class_qwt_point_polar.html#af59f940ff7d63de71044a8bba6d749db',1,'QwtPointPolar::operator==()'],['../class_qwt_interval_sample.html#a3ef77fe5326a1fdd4b0428b3093a0e25',1,'QwtIntervalSample::operator==()'],['../class_qwt_set_sample.html#a76859b776c7501b04c50197fe9e6c97e',1,'QwtSetSample::operator==()'],['../class_qwt_scale_div.html#a82c3bdbcb4263636a4e8f62a752553b4',1,'QwtScaleDiv::operator==()'],['../class_qwt_text.html#a0a7fba648ad898d751de60e9a6d7802f',1,'QwtText::operator==()']]], + ['operator_7c',['operator|',['../class_qwt_interval.html#ac6c5c7837821811f8b0748c529f137a6',1,'QwtInterval::operator|(const QwtInterval &) const '],['../class_qwt_interval.html#ae0671b0b9422d5da3a103cbd7c938484',1,'QwtInterval::operator|(double) const ']]], + ['operator_7c_3d',['operator|=',['../class_qwt_interval.html#a980e6449437b689893bd8ec7370e91e0',1,'QwtInterval::operator|=(const QwtInterval &)'],['../class_qwt_interval.html#a86a2785d0fc6860e15cfc277c14e7a09',1,'QwtInterval::operator|=(double)']]], + ['orientation',['orientation',['../class_qwt_column_rect.html#a8bb5221efc769ef7f474e1f1795de4b6',1,'QwtColumnRect::orientation()'],['../class_qwt_plot_rescaler.html#a5afb70d8dc928dedcb7daa3f95e7d506',1,'QwtPlotRescaler::orientation()'],['../class_qwt_plot_series_item.html#a2f97f0885d3f7adc7a9d484e741d2a76',1,'QwtPlotSeriesItem::orientation()'],['../class_qwt_plot_zone_item.html#a3543471c711b64a48f9f3eb672c24efc',1,'QwtPlotZoneItem::orientation()'],['../class_qwt_scale_draw.html#a06bf10d73aa03c16394a85fa70a7a3b1',1,'QwtScaleDraw::orientation()'],['../class_qwt_slider.html#a66ee353b1f2545db9bbbaea176c04251',1,'QwtSlider::orientation()'],['../class_qwt_thermo.html#aa15057791c2c884f0dc0fc77ff807d5f',1,'QwtThermo::orientation()'],['../class_qwt_wheel.html#acf5ccef9b918ef811698b5b619ec0d29',1,'QwtWheel::orientation()']]], + ['orientations',['orientations',['../class_qwt_panner.html#a4e7a195ed909f18d33a05b1b7c1f0930',1,'QwtPanner']]], + ['origin',['origin',['../class_qwt_dial.html#a5d7a8b9094bcc3fb82b31c3ac9ad706d',1,'QwtDial::origin()'],['../class_qwt_thermo.html#acb7ff196b2a792c40d07137fdff6d05f',1,'QwtThermo::origin()']]], + ['originmode',['originMode',['../class_qwt_thermo.html#abd2a6f3b600c3354d7321b6187296e38',1,'QwtThermo']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/functions_70.html b/ThirdParty/Qwt/doc/html/search/functions_70.html new file mode 100644 index 0000000000..8ef7fb962d --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/functions_70.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/functions_70.js b/ThirdParty/Qwt/doc/html/search/functions_70.js new file mode 100644 index 0000000000..f014dd544b --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/functions_70.js @@ -0,0 +1,34 @@ +var searchData= +[ + ['p1',['p1',['../class_qwt_scale_map.html#ac1ca2f9b4643d27fde693cc98bca0cd7',1,'QwtScaleMap']]], + ['p2',['p2',['../class_qwt_scale_map.html#acf404215292b10bd46b1089d2452b8e9',1,'QwtScaleMap']]], + ['pagestepcount',['pageStepCount',['../class_qwt_wheel.html#a2ffc984ae772de07b27ba73d35af7f74',1,'QwtWheel']]], + ['pagesteps',['pageSteps',['../class_qwt_abstract_slider.html#a29adb20551bf586cff0c2b074d5c1e50',1,'QwtAbstractSlider']]], + ['paintengine',['paintEngine',['../class_qwt_null_paint_device.html#a2058b09c918ed674ef1977d11d869b03',1,'QwtNullPaintDevice']]], + ['paintevent',['paintEvent',['../class_qwt_arrow_button.html#ad9bdd4ed2e655aa19929ab436ec8ab45',1,'QwtArrowButton::paintEvent()'],['../class_qwt_dial.html#a11e50d714b9decb0f5d34e5acdde970d',1,'QwtDial::paintEvent()'],['../class_qwt_knob.html#aac9eb31c18408aaa224f5ad040631384',1,'QwtKnob::paintEvent()'],['../class_qwt_legend_label.html#a03649851d343dbd2c4128e9e50def6b7',1,'QwtLegendLabel::paintEvent()'],['../class_qwt_panner.html#acd76ea518bd9267a45115d2c6ce19353',1,'QwtPanner::paintEvent()'],['../class_qwt_plot_canvas.html#aa8f1516817c578efd407d8dd574170ec',1,'QwtPlotCanvas::paintEvent()'],['../class_qwt_plot_g_l_canvas.html#aa0bf3be03e9545b78da74844e6f4eb91',1,'QwtPlotGLCanvas::paintEvent()'],['../class_qwt_scale_widget.html#ab3d4d32fb92fbef360841f74d469f2a9',1,'QwtScaleWidget::paintEvent()'],['../class_qwt_slider.html#a128624c8babc95f5a631dfe3112d2d2b',1,'QwtSlider::paintEvent()'],['../class_qwt_text_label.html#aff00274ee1c860530920b4feaca02393',1,'QwtTextLabel::paintEvent()'],['../class_qwt_thermo.html#a7ae9fe53b0b0925d88fd9e1e4eb026f7',1,'QwtThermo::paintEvent()'],['../class_qwt_wheel.html#a8856da1dadb2a7b73e8bd75a1e981ea3',1,'QwtWheel::paintEvent()'],['../class_qwt_widget_overlay.html#ac75689d1294c175540253bb72ea70496',1,'QwtWidgetOverlay::paintEvent()']]], + ['paintrect',['paintRect',['../class_qwt_plot_item.html#afa05b98fd7ea65ca1ffcb04bb6b4326d',1,'QwtPlotItem']]], + ['palette',['palette',['../class_qwt_column_symbol.html#afe13154e29f882e77fedf8bbc3280f7e',1,'QwtColumnSymbol::palette()'],['../class_qwt_compass_rose.html#ab2e5c2a4a27c40a175458b96d89394e8',1,'QwtCompassRose::palette()'],['../class_qwt_dial_needle.html#a8b3c915032389261e07cc983b433166c',1,'QwtDialNeedle::palette()'],['../class_qwt_plot_scale_item.html#a6e48f16a93b7e7dcb98c6bfda3b11c2e',1,'QwtPlotScaleItem::palette()']]], + ['panned',['panned',['../class_qwt_panner.html#ae9ce78e6f9ae73317af29b2dc5df7372',1,'QwtPanner']]], + ['parentwidget',['parentWidget',['../class_qwt_magnifier.html#a56b7ad2366a7f908c38bc2a994acde16',1,'QwtMagnifier::parentWidget()'],['../class_qwt_magnifier.html#a7ea89693ca6ebd6376838d4ab107bf5a',1,'QwtMagnifier::parentWidget() const '],['../class_qwt_picker.html#ada0c12257e006f0066d22c3eb83f667e',1,'QwtPicker::parentWidget()'],['../class_qwt_picker.html#a250dc5daf40a049f8db1f7ed730802d3',1,'QwtPicker::parentWidget() const ']]], + ['path',['path',['../class_qwt_painter_command.html#a19fa09138a8775e721817d4ca309f5ac',1,'QwtPainterCommand::path()'],['../class_qwt_painter_command.html#a09296ca1e32fb283149cb9edf5f38550',1,'QwtPainterCommand::path() const '],['../class_qwt_symbol.html#aa17d051c735f55441ce62c7043428b90',1,'QwtSymbol::path()']]], + ['pdist',['pDist',['../class_qwt_scale_map.html#af364d4fa10db6f5dbc93d6ce763e603f',1,'QwtScaleMap']]], + ['pen',['pen',['../class_qwt_interval_symbol.html#a5945eb2b656f12451d02721b9068441d',1,'QwtIntervalSymbol::pen()'],['../class_qwt_plot_curve.html#a778aafd1385ce833821751d0a8635cef',1,'QwtPlotCurve::pen()'],['../class_qwt_plot_histogram.html#a51727f20a46a48afbbc7f76a8ea6ec84',1,'QwtPlotHistogram::pen()'],['../class_qwt_plot_interval_curve.html#a942952ad07550f271a57db4cf5211ea8',1,'QwtPlotIntervalCurve::pen()'],['../class_qwt_plot_shape_item.html#a5c54cacd19217ca62583cc8890b7219a',1,'QwtPlotShapeItem::pen()'],['../class_qwt_plot_zone_item.html#aab5bb31db1e30d9c1fa3cc3fea71ec0f',1,'QwtPlotZoneItem::pen()'],['../class_qwt_symbol.html#a2fe55b71735bcaca3e931b65b9b1ed13',1,'QwtSymbol::pen()']]], + ['penwidth',['penWidth',['../class_qwt_abstract_scale_draw.html#a8933b8da6332a6d4badfa83e67b74865',1,'QwtAbstractScaleDraw::penWidth()'],['../class_qwt_plot_spectro_curve.html#a81a531d89ac21d25e86a958822720f38',1,'QwtPlotSpectroCurve::penWidth()']]], + ['pickarea',['pickArea',['../class_qwt_picker.html#accba1f639a7e0a0fa978bf638b5f7500',1,'QwtPicker']]], + ['pickedpoints',['pickedPoints',['../class_qwt_picker.html#a9e10695cd170fe335c6959de8d1298a1',1,'QwtPicker']]], + ['pinpoint',['pinPoint',['../class_qwt_symbol.html#ab107489def28441f21fd9166de795cb6',1,'QwtSymbol']]], + ['piperect',['pipeRect',['../class_qwt_thermo.html#a3359ca7488990dab26b182448b38395b',1,'QwtThermo']]], + ['pipewidth',['pipeWidth',['../class_qwt_thermo.html#aae17760ab12807624b63b6caeae5f3d0',1,'QwtThermo']]], + ['pixelhint',['pixelHint',['../class_qwt_matrix_raster_data.html#a7a9034de8037af500e4f737f54591358',1,'QwtMatrixRasterData::pixelHint()'],['../class_qwt_plot_raster_item.html#a03a69bfe7d3d125ba4f580d1ecd5e2f4',1,'QwtPlotRasterItem::pixelHint()'],['../class_qwt_plot_spectrogram.html#a9b06ef6a2526da8715615d07fdb31a95',1,'QwtPlotSpectrogram::pixelHint()'],['../class_qwt_raster_data.html#ad1ce58351804760d1ba1e7efe97d39d6',1,'QwtRasterData::pixelHint()']]], + ['pixmap',['pixmap',['../class_qwt_symbol.html#a60f679d9fdadfd0b96aacbd5ce8ebcc0',1,'QwtSymbol']]], + ['pixmapdata',['pixmapData',['../class_qwt_painter_command.html#aa85782270cf4ba4c9c20036e5e9780b3',1,'QwtPainterCommand::pixmapData()'],['../class_qwt_painter_command.html#a8dbf9778808df8c2b489c38382914260',1,'QwtPainterCommand::pixmapData() const ']]], + ['plaintext',['plainText',['../class_qwt_text_label.html#a6c50b70fa29335c07e5633a316e05e48',1,'QwtTextLabel']]], + ['plot',['plot',['../class_qwt_plot_canvas.html#a1b720b99dc1b686f58e789b13f339f63',1,'QwtPlotCanvas::plot()'],['../class_qwt_plot_canvas.html#a72550d1af1b5fb4caca5269c3d5891f9',1,'QwtPlotCanvas::plot() const '],['../class_qwt_plot_item.html#a4c99653a14a49ad94d466168d06e97b9',1,'QwtPlotItem::plot()'],['../class_qwt_plot_magnifier.html#ae0197fb4f393e149585ff62f8e29cea6',1,'QwtPlotMagnifier::plot()'],['../class_qwt_plot_magnifier.html#a2cc4ae00009f34f54880aea9e9837826',1,'QwtPlotMagnifier::plot() const '],['../class_qwt_plot_panner.html#ae52375921bfacc3e17d3db45858b1485',1,'QwtPlotPanner::plot()'],['../class_qwt_plot_panner.html#a2401ae1ff1e40b1ee4c7a997a895d2be',1,'QwtPlotPanner::plot() const '],['../class_qwt_plot_picker.html#ac5906d5fe7543f3db7808da44d8197a9',1,'QwtPlotPicker::plot()'],['../class_qwt_plot_picker.html#a88103b56426ff2a5fb8713ae8ab2d191',1,'QwtPlotPicker::plot() const '],['../class_qwt_plot_rescaler.html#aca7a946dd53744e4640be383cd161a7c',1,'QwtPlotRescaler::plot()'],['../class_qwt_plot_rescaler.html#ae49ce39ba8c7670bd8f70cf9078d96d5',1,'QwtPlotRescaler::plot() const ']]], + ['plotitems',['plotItems',['../class_qwt_plot_legend_item.html#ada1609304901c61024548ee37d824e7a',1,'QwtPlotLegendItem']]], + ['plotlayout',['plotLayout',['../class_qwt_plot.html#a9156b14a6f67f6279a16fea063ce1d14',1,'QwtPlot::plotLayout()'],['../class_qwt_plot.html#a6abb53bb19d8e931ba49bf439779f0ac',1,'QwtPlot::plotLayout() const ']]], + ['points',['points',['../class_qwt_spline.html#a14694e61052933921eda629062554d22',1,'QwtSpline']]], + ['polylinesplitting',['polylineSplitting',['../class_qwt_painter.html#a831cf0efa8a0869ab79307495d7e4590',1,'QwtPainter']]], + ['pos',['pos',['../class_qwt_scale_draw.html#a31b1a37c24d4a1f8f2e834b0b7c9a815',1,'QwtScaleDraw']]], + ['position',['position',['../class_qwt_plot_scale_item.html#a7228e5fc436e1cfb403c38974b781185',1,'QwtPlotScaleItem']]], + ['pressed',['pressed',['../class_qwt_legend_label.html#ae3c6cdfa7a6390c3f4152fc78c701cdd',1,'QwtLegendLabel']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/functions_71.html b/ThirdParty/Qwt/doc/html/search/functions_71.html new file mode 100644 index 0000000000..d8d7e7358b --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/functions_71.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/functions_71.js b/ThirdParty/Qwt/doc/html/search/functions_71.js new file mode 100644 index 0000000000..8f4e52027c --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/functions_71.js @@ -0,0 +1,128 @@ +var searchData= +[ + ['qwtabstractlegend',['QwtAbstractLegend',['../class_qwt_abstract_legend.html#a77092d06decd579fcde5c90875c3830b',1,'QwtAbstractLegend']]], + ['qwtabstractscale',['QwtAbstractScale',['../class_qwt_abstract_scale.html#a97fff64367cdbe7bc8dc56c41d5faf9e',1,'QwtAbstractScale']]], + ['qwtabstractscaledraw',['QwtAbstractScaleDraw',['../class_qwt_abstract_scale_draw.html#a19c944664a2e36f06ae71b745fbd442e',1,'QwtAbstractScaleDraw']]], + ['qwtabstractslider',['QwtAbstractSlider',['../class_qwt_abstract_slider.html#af539373e763744c295f90b919fc37870',1,'QwtAbstractSlider']]], + ['qwtalphacolormap',['QwtAlphaColorMap',['../class_qwt_alpha_color_map.html#af78213a5ff1ebef8a8d4447b0987bf32',1,'QwtAlphaColorMap']]], + ['qwtanalogclock',['QwtAnalogClock',['../class_qwt_analog_clock.html#af52a1110f1db89c162f49a23772745b9',1,'QwtAnalogClock']]], + ['qwtarrayseriesdata',['QwtArraySeriesData',['../class_qwt_array_series_data.html#a3cb14bbe2b27bf8d49994d80e8eab3ee',1,'QwtArraySeriesData::QwtArraySeriesData()'],['../class_qwt_array_series_data.html#a4bb811309027ac378a2dcc50ff9ef829',1,'QwtArraySeriesData::QwtArraySeriesData(const QVector< T > &samples)']]], + ['qwtarrowbutton',['QwtArrowButton',['../class_qwt_arrow_button.html#ab0ad5aefdd56db10976796be717671e9',1,'QwtArrowButton']]], + ['qwtcolormap',['QwtColorMap',['../class_qwt_color_map.html#a2ab0a6041ea6d37c0609ca2e3bd976ca',1,'QwtColorMap']]], + ['qwtcolumnrect',['QwtColumnRect',['../class_qwt_column_rect.html#ad3eeebc150334ee9393d7aff4f33c873',1,'QwtColumnRect']]], + ['qwtcolumnsymbol',['QwtColumnSymbol',['../class_qwt_column_symbol.html#a78d6b04908f7f814cdc07c3ae704b329',1,'QwtColumnSymbol']]], + ['qwtcompass',['QwtCompass',['../class_qwt_compass.html#a05357e2950a3dc534e68e3c21f6c6b94',1,'QwtCompass']]], + ['qwtcompassmagnetneedle',['QwtCompassMagnetNeedle',['../class_qwt_compass_magnet_needle.html#a3422e6490d44c527289bafdcceecd741',1,'QwtCompassMagnetNeedle']]], + ['qwtcompassscaledraw',['QwtCompassScaleDraw',['../class_qwt_compass_scale_draw.html#af5454a1e7d4d511e43c91f008fe65c06',1,'QwtCompassScaleDraw::QwtCompassScaleDraw()'],['../class_qwt_compass_scale_draw.html#ab8f8902087f6ba6428d637395451adfa',1,'QwtCompassScaleDraw::QwtCompassScaleDraw(const QMap< double, QString > &map)']]], + ['qwtcompasswindarrow',['QwtCompassWindArrow',['../class_qwt_compass_wind_arrow.html#a1b5931f43dd7e72fc5a3e2c9b509769d',1,'QwtCompassWindArrow']]], + ['qwtcounter',['QwtCounter',['../class_qwt_counter.html#aee94cdbaf1f3d22e110fd3535dbca34a',1,'QwtCounter']]], + ['qwtcpointerdata',['QwtCPointerData',['../class_qwt_c_pointer_data.html#a795b86d69226d1aabf9356848da6c083',1,'QwtCPointerData']]], + ['qwtcurvefitter',['QwtCurveFitter',['../class_qwt_curve_fitter.html#ad804660017ae0f3ede604470724b3df3',1,'QwtCurveFitter']]], + ['qwtdatescaledraw',['QwtDateScaleDraw',['../class_qwt_date_scale_draw.html#adbee23e84bc296b09f5a6d54252b75ba',1,'QwtDateScaleDraw']]], + ['qwtdatescaleengine',['QwtDateScaleEngine',['../class_qwt_date_scale_engine.html#a7eb99ee3e701d6f8467b1e9c8c248b9b',1,'QwtDateScaleEngine']]], + ['qwtdial',['QwtDial',['../class_qwt_dial.html#a910ad090ceb51587c965d9a2c9db8f60',1,'QwtDial']]], + ['qwtdialneedle',['QwtDialNeedle',['../class_qwt_dial_needle.html#aef3af79632ce784bc4d7332f6e269a1f',1,'QwtDialNeedle']]], + ['qwtdialsimpleneedle',['QwtDialSimpleNeedle',['../class_qwt_dial_simple_needle.html#a5f16b9298ecd293360a3ccf91d3dbfbb',1,'QwtDialSimpleNeedle']]], + ['qwtdyngridlayout',['QwtDynGridLayout',['../class_qwt_dyn_grid_layout.html#a2079ddcba8442ef9f386556dd9cb8cc6',1,'QwtDynGridLayout::QwtDynGridLayout(QWidget *, int margin=0, int space=-1)'],['../class_qwt_dyn_grid_layout.html#a05d45c0928702e37da3497626b0f7c93',1,'QwtDynGridLayout::QwtDynGridLayout(int space=-1)']]], + ['qwteventpattern',['QwtEventPattern',['../class_qwt_event_pattern.html#a1236c9239a3d8281d66b255ad18f7ee2',1,'QwtEventPattern']]], + ['qwtgraphic',['QwtGraphic',['../class_qwt_graphic.html#a45805a4faf2247ae42ccee21f37dabd2',1,'QwtGraphic::QwtGraphic()'],['../class_qwt_graphic.html#a12bf98d94b68b344e9e4f97c0a15f649',1,'QwtGraphic::QwtGraphic(const QwtGraphic &)']]], + ['qwtinterval',['QwtInterval',['../class_qwt_interval.html#acd8699b69f46bcea31fa225d1425add3',1,'QwtInterval::QwtInterval()'],['../class_qwt_interval.html#a6c48e99ff0a44784a4084dd8b1bc3fec',1,'QwtInterval::QwtInterval(double minValue, double maxValue, BorderFlags=IncludeBorders)']]], + ['qwtintervalsample',['QwtIntervalSample',['../class_qwt_interval_sample.html#a9f1259560f2628f8d32a648076c09d23',1,'QwtIntervalSample::QwtIntervalSample()'],['../class_qwt_interval_sample.html#a1e17c77625481f0987ed0bc7f461499c',1,'QwtIntervalSample::QwtIntervalSample(double, const QwtInterval &)'],['../class_qwt_interval_sample.html#a02e2490f2bbc671a1a771c53ab2889da',1,'QwtIntervalSample::QwtIntervalSample(double value, double min, double max)']]], + ['qwtintervalseriesdata',['QwtIntervalSeriesData',['../class_qwt_interval_series_data.html#ae85a2103d690c67f0e17aab94884bb79',1,'QwtIntervalSeriesData']]], + ['qwtintervalsymbol',['QwtIntervalSymbol',['../class_qwt_interval_symbol.html#a40c03c5b54dc3c4a69cf1dc88bf25893',1,'QwtIntervalSymbol::QwtIntervalSymbol(Style=NoSymbol)'],['../class_qwt_interval_symbol.html#a7a4ddf7e61445833f39105614ebd77c1',1,'QwtIntervalSymbol::QwtIntervalSymbol(const QwtIntervalSymbol &)']]], + ['qwtknob',['QwtKnob',['../class_qwt_knob.html#a767e89f3d4875da7d2074050572e0556',1,'QwtKnob']]], + ['qwtlegend',['QwtLegend',['../class_qwt_legend.html#adf5a64070a546eaac36fc9afac56b7fb',1,'QwtLegend']]], + ['qwtlegenddata',['QwtLegendData',['../class_qwt_legend_data.html#a519e4f01583d051e4b2458ab9dfcb196',1,'QwtLegendData']]], + ['qwtlegendlabel',['QwtLegendLabel',['../class_qwt_legend_label.html#a557315a25a130c2608a2f63613096ab9',1,'QwtLegendLabel']]], + ['qwtlinearcolormap',['QwtLinearColorMap',['../class_qwt_linear_color_map.html#a0ef6a29bb027017aad89a4c4a4b07019',1,'QwtLinearColorMap::QwtLinearColorMap(QwtColorMap::Format=QwtColorMap::RGB)'],['../class_qwt_linear_color_map.html#ae591cf441db15a021c25d0b58bfa7a5e',1,'QwtLinearColorMap::QwtLinearColorMap(const QColor &from, const QColor &to, QwtColorMap::Format=QwtColorMap::RGB)']]], + ['qwtlinearscaleengine',['QwtLinearScaleEngine',['../class_qwt_linear_scale_engine.html#a989e6f0fabe43934f1ed7c0ca290ab03',1,'QwtLinearScaleEngine']]], + ['qwtlogscaleengine',['QwtLogScaleEngine',['../class_qwt_log_scale_engine.html#a68f89f870f918c2ecc56d8d2b0074a3a',1,'QwtLogScaleEngine']]], + ['qwtlogtransform',['QwtLogTransform',['../class_qwt_log_transform.html#ae38156a50ab292af9638a78a374c30ff',1,'QwtLogTransform']]], + ['qwtmagnifier',['QwtMagnifier',['../class_qwt_magnifier.html#aa11b927c72e0421570a137f0fa1cfb7b',1,'QwtMagnifier']]], + ['qwtmathmltextengine',['QwtMathMLTextEngine',['../class_qwt_math_m_l_text_engine.html#af88b085974808e0497d120044672f721',1,'QwtMathMLTextEngine']]], + ['qwtmatrixrasterdata',['QwtMatrixRasterData',['../class_qwt_matrix_raster_data.html#a3e80514459cc6aab03cfd839da53e45e',1,'QwtMatrixRasterData']]], + ['qwtnullpaintdevice',['QwtNullPaintDevice',['../class_qwt_null_paint_device.html#a7fc0a16619aba83241eab7ecb83c80ca',1,'QwtNullPaintDevice']]], + ['qwtnulltransform',['QwtNullTransform',['../class_qwt_null_transform.html#a0e5ec82fc1aef04b684108ff8334dd1e',1,'QwtNullTransform']]], + ['qwtohlcsample',['QwtOHLCSample',['../class_qwt_o_h_l_c_sample.html#ad4056581f619e0a36d854fc5bb4341ef',1,'QwtOHLCSample']]], + ['qwtpaintercommand',['QwtPainterCommand',['../class_qwt_painter_command.html#a0a3ce67b97475d9ff41c26542d216e22',1,'QwtPainterCommand::QwtPainterCommand()'],['../class_qwt_painter_command.html#aa67dd2e6a432635c101295de585ffdcd',1,'QwtPainterCommand::QwtPainterCommand(const QwtPainterCommand &)'],['../class_qwt_painter_command.html#a8648ff991175d5f06bae6b04df06bd03',1,'QwtPainterCommand::QwtPainterCommand(const QPainterPath &)'],['../class_qwt_painter_command.html#a7dae6c078fdb8d173358e988f06e2163',1,'QwtPainterCommand::QwtPainterCommand(const QRectF &rect, const QPixmap &, const QRectF &subRect)'],['../class_qwt_painter_command.html#a3830b0c0f920588107a3acc1ab05853b',1,'QwtPainterCommand::QwtPainterCommand(const QRectF &rect, const QImage &, const QRectF &subRect, Qt::ImageConversionFlags)'],['../class_qwt_painter_command.html#adcd99c908be8b5e57dee2f7dbed73dc3',1,'QwtPainterCommand::QwtPainterCommand(const QPaintEngineState &)']]], + ['qwtpanner',['QwtPanner',['../class_qwt_panner.html#af5482be26d69a64c3880653265240736',1,'QwtPanner']]], + ['qwtpicker',['QwtPicker',['../class_qwt_picker.html#af9a5f4b0e4b37e2f323e801aa9dd6fe1',1,'QwtPicker::QwtPicker(QWidget *parent)'],['../class_qwt_picker.html#ac04e38a178229292cfff4f3110ffbe5e',1,'QwtPicker::QwtPicker(RubberBand rubberBand, DisplayMode trackerMode, QWidget *)']]], + ['qwtpickerclickpointmachine',['QwtPickerClickPointMachine',['../class_qwt_picker_click_point_machine.html#aa4bab7db982c16270176957451db1d8e',1,'QwtPickerClickPointMachine']]], + ['qwtpickerclickrectmachine',['QwtPickerClickRectMachine',['../class_qwt_picker_click_rect_machine.html#ac154f2cb83e86f8b5d9d410c53b4bdb4',1,'QwtPickerClickRectMachine']]], + ['qwtpickerdraglinemachine',['QwtPickerDragLineMachine',['../class_qwt_picker_drag_line_machine.html#acf3157352ff3d68fdd000e8a944467b3',1,'QwtPickerDragLineMachine']]], + ['qwtpickerdragpointmachine',['QwtPickerDragPointMachine',['../class_qwt_picker_drag_point_machine.html#af534289d12a39eeb9b52402b61967fac',1,'QwtPickerDragPointMachine']]], + ['qwtpickerdragrectmachine',['QwtPickerDragRectMachine',['../class_qwt_picker_drag_rect_machine.html#a49ce41d12442bc295578c0682cb38682',1,'QwtPickerDragRectMachine']]], + ['qwtpickermachine',['QwtPickerMachine',['../class_qwt_picker_machine.html#ab27bc3f70d48aa145db9ebbfdba34e15',1,'QwtPickerMachine']]], + ['qwtpickerpolygonmachine',['QwtPickerPolygonMachine',['../class_qwt_picker_polygon_machine.html#ab6da61726ca16c06a1d9c02f067492c6',1,'QwtPickerPolygonMachine']]], + ['qwtpickertrackermachine',['QwtPickerTrackerMachine',['../class_qwt_picker_tracker_machine.html#a730ee0927456e192f777c225277b3fe0',1,'QwtPickerTrackerMachine']]], + ['qwtpixelmatrix',['QwtPixelMatrix',['../class_qwt_pixel_matrix.html#aa197eddf30db429ab267db2a875e7d71',1,'QwtPixelMatrix']]], + ['qwtplaintextengine',['QwtPlainTextEngine',['../class_qwt_plain_text_engine.html#a0ad29b2229a879afe49b546704eb7079',1,'QwtPlainTextEngine']]], + ['qwtplot',['QwtPlot',['../class_qwt_plot.html#acde7121614da027e9a1dbc4591613ca7',1,'QwtPlot::QwtPlot(QWidget *=NULL)'],['../class_qwt_plot.html#a3c9b10d39c181991f24eab1828ad68a5',1,'QwtPlot::QwtPlot(const QwtText &title, QWidget *=NULL)']]], + ['qwtplotabstractbarchart',['QwtPlotAbstractBarChart',['../class_qwt_plot_abstract_bar_chart.html#a1eed4138383e5f0d118d518fd0255711',1,'QwtPlotAbstractBarChart']]], + ['qwtplotbarchart',['QwtPlotBarChart',['../class_qwt_plot_bar_chart.html#abc94e8caf46d58726de297d00a09575d',1,'QwtPlotBarChart::QwtPlotBarChart(const QString &title=QString::null)'],['../class_qwt_plot_bar_chart.html#a99bf404571a13a0f9a4e3a01cbe69d8a',1,'QwtPlotBarChart::QwtPlotBarChart(const QwtText &title)']]], + ['qwtplotcanvas',['QwtPlotCanvas',['../class_qwt_plot_canvas.html#a8b0cd76cd283f8f35331dfc7543cbf89',1,'QwtPlotCanvas']]], + ['qwtplotcurve',['QwtPlotCurve',['../class_qwt_plot_curve.html#ac7d2d9e21ee3e054b51fb954cf95c820',1,'QwtPlotCurve::QwtPlotCurve(const QString &title=QString::null)'],['../class_qwt_plot_curve.html#a3bcaa88363509f4bc1ad92bee498f203',1,'QwtPlotCurve::QwtPlotCurve(const QwtText &title)']]], + ['qwtplotdict',['QwtPlotDict',['../class_qwt_plot_dict.html#a0ee364450834ac63f4cbd5baab82d15f',1,'QwtPlotDict']]], + ['qwtplotdirectpainter',['QwtPlotDirectPainter',['../class_qwt_plot_direct_painter.html#af9e6e2056afd4db4c081e4b04d5c9a85',1,'QwtPlotDirectPainter']]], + ['qwtplotglcanvas',['QwtPlotGLCanvas',['../class_qwt_plot_g_l_canvas.html#adc7704723f078ff57243a2e2fc217832',1,'QwtPlotGLCanvas']]], + ['qwtplotgrid',['QwtPlotGrid',['../class_qwt_plot_grid.html#a43001238f3024c15baa8ae61b29ae170',1,'QwtPlotGrid']]], + ['qwtplothistogram',['QwtPlotHistogram',['../class_qwt_plot_histogram.html#ada0642611a7edc4ea3beac45428fd786',1,'QwtPlotHistogram::QwtPlotHistogram(const QString &title=QString::null)'],['../class_qwt_plot_histogram.html#a5c0973a9425655be4218298706d25f38',1,'QwtPlotHistogram::QwtPlotHistogram(const QwtText &title)']]], + ['qwtplotintervalcurve',['QwtPlotIntervalCurve',['../class_qwt_plot_interval_curve.html#af5bfe837aec8dc8884394ca7813a8d41',1,'QwtPlotIntervalCurve::QwtPlotIntervalCurve(const QString &title=QString::null)'],['../class_qwt_plot_interval_curve.html#ab7d0884ffb900fc453d621580f348c0e',1,'QwtPlotIntervalCurve::QwtPlotIntervalCurve(const QwtText &title)']]], + ['qwtplotitem',['QwtPlotItem',['../class_qwt_plot_item.html#a5d892ac856fb9176515c5f2d806161dc',1,'QwtPlotItem']]], + ['qwtplotlayout',['QwtPlotLayout',['../class_qwt_plot_layout.html#ac89596fb2a3d3a92901f124821045a47',1,'QwtPlotLayout']]], + ['qwtplotlegenditem',['QwtPlotLegendItem',['../class_qwt_plot_legend_item.html#a5e647b9936095cde8193214d6a89b07f',1,'QwtPlotLegendItem']]], + ['qwtplotmagnifier',['QwtPlotMagnifier',['../class_qwt_plot_magnifier.html#a6edabe11a02cae3ae8e8adaa9013d109',1,'QwtPlotMagnifier']]], + ['qwtplotmarker',['QwtPlotMarker',['../class_qwt_plot_marker.html#a0333be3f54ed6096e8efdeadf1809f7a',1,'QwtPlotMarker::QwtPlotMarker(const QString &title=QString::null)'],['../class_qwt_plot_marker.html#a230b1a284a58732e02fd65678a14c455',1,'QwtPlotMarker::QwtPlotMarker(const QwtText &title)']]], + ['qwtplotmultibarchart',['QwtPlotMultiBarChart',['../class_qwt_plot_multi_bar_chart.html#a8e5a1a75c21f52f53a588a80f95d0317',1,'QwtPlotMultiBarChart::QwtPlotMultiBarChart(const QString &title=QString::null)'],['../class_qwt_plot_multi_bar_chart.html#a5e663f9492a0aff79e171997d779ffb4',1,'QwtPlotMultiBarChart::QwtPlotMultiBarChart(const QwtText &title)']]], + ['qwtplotpanner',['QwtPlotPanner',['../class_qwt_plot_panner.html#a94d661c312edbf7ef094dd32dff57d44',1,'QwtPlotPanner']]], + ['qwtplotpicker',['QwtPlotPicker',['../class_qwt_plot_picker.html#ab63357cd493d0fa388193d515cb8bd38',1,'QwtPlotPicker::QwtPlotPicker(QWidget *canvas)'],['../class_qwt_plot_picker.html#ae8ae9704219d3874a4a20cb27cbe0665',1,'QwtPlotPicker::QwtPlotPicker(int xAxis, int yAxis, QWidget *)'],['../class_qwt_plot_picker.html#ad8d6d7be79511db92ad2ca0af70ea824',1,'QwtPlotPicker::QwtPlotPicker(int xAxis, int yAxis, RubberBand rubberBand, DisplayMode trackerMode, QWidget *)']]], + ['qwtplotrasteritem',['QwtPlotRasterItem',['../class_qwt_plot_raster_item.html#a2149c1d6b71c607027345a9a51ef3314',1,'QwtPlotRasterItem::QwtPlotRasterItem(const QString &title=QString::null)'],['../class_qwt_plot_raster_item.html#af487c6abc8e95200d4537d1373f96be5',1,'QwtPlotRasterItem::QwtPlotRasterItem(const QwtText &title)']]], + ['qwtplotrenderer',['QwtPlotRenderer',['../class_qwt_plot_renderer.html#aa265be7e2873a28dbb4f1788020cebe6',1,'QwtPlotRenderer']]], + ['qwtplotrescaler',['QwtPlotRescaler',['../class_qwt_plot_rescaler.html#a4bef342d0a571af31685c2ff88def5d5',1,'QwtPlotRescaler']]], + ['qwtplotscaleitem',['QwtPlotScaleItem',['../class_qwt_plot_scale_item.html#a9d093fc9de7d423435f455c110d4605d',1,'QwtPlotScaleItem']]], + ['qwtplotseriesitem',['QwtPlotSeriesItem',['../class_qwt_plot_series_item.html#a2c5f7667a8040b76454c1f70062dd010',1,'QwtPlotSeriesItem::QwtPlotSeriesItem(const QString &title=QString::null)'],['../class_qwt_plot_series_item.html#ada75c34290dbd2b12a199a70dbc0f2b9',1,'QwtPlotSeriesItem::QwtPlotSeriesItem(const QwtText &title)']]], + ['qwtplotshapeitem',['QwtPlotShapeItem',['../class_qwt_plot_shape_item.html#a0b2979ee8b1956ea4db4c0fc89b9c978',1,'QwtPlotShapeItem::QwtPlotShapeItem(const QString &title=QString::null)'],['../class_qwt_plot_shape_item.html#a33fb91a92c34c58c48d3de1ee278bbc7',1,'QwtPlotShapeItem::QwtPlotShapeItem(const QwtText &title)']]], + ['qwtplotspectrocurve',['QwtPlotSpectroCurve',['../class_qwt_plot_spectro_curve.html#aa02c00eb35a6f08ab11091ef66c737cd',1,'QwtPlotSpectroCurve::QwtPlotSpectroCurve(const QString &title=QString::null)'],['../class_qwt_plot_spectro_curve.html#a78170049ecb2b6681a107abf26783bd7',1,'QwtPlotSpectroCurve::QwtPlotSpectroCurve(const QwtText &title)']]], + ['qwtplotspectrogram',['QwtPlotSpectrogram',['../class_qwt_plot_spectrogram.html#ae90c0431be329ecbefc7ed9ac77f5ed6',1,'QwtPlotSpectrogram']]], + ['qwtplotsvgitem',['QwtPlotSvgItem',['../class_qwt_plot_svg_item.html#a3b6e505f0ef1d9e40030db2a8b60762e',1,'QwtPlotSvgItem::QwtPlotSvgItem(const QString &title=QString::null)'],['../class_qwt_plot_svg_item.html#ac750a4ff902302ab485971fcea6bee38',1,'QwtPlotSvgItem::QwtPlotSvgItem(const QwtText &title)']]], + ['qwtplottextlabel',['QwtPlotTextLabel',['../class_qwt_plot_text_label.html#a19466cb637c30cfce5abfe024cbc3e3a',1,'QwtPlotTextLabel']]], + ['qwtplottradingcurve',['QwtPlotTradingCurve',['../class_qwt_plot_trading_curve.html#a0a46b6269279e2c96b253d241025b13f',1,'QwtPlotTradingCurve::QwtPlotTradingCurve(const QString &title=QString::null)'],['../class_qwt_plot_trading_curve.html#aa8359acb3760cc9f8ccc8ab10d10262f',1,'QwtPlotTradingCurve::QwtPlotTradingCurve(const QwtText &title)']]], + ['qwtplotzoneitem',['QwtPlotZoneItem',['../class_qwt_plot_zone_item.html#aa63ced2cda200381e887a6a9e28a03b5',1,'QwtPlotZoneItem']]], + ['qwtplotzoomer',['QwtPlotZoomer',['../class_qwt_plot_zoomer.html#a1f77745e104b4a6300ebf1c6c3412b7e',1,'QwtPlotZoomer::QwtPlotZoomer(QWidget *, bool doReplot=true)'],['../class_qwt_plot_zoomer.html#a9fd8927796071ce7ab63341db5e0f1ed',1,'QwtPlotZoomer::QwtPlotZoomer(int xAxis, int yAxis, QWidget *, bool doReplot=true)']]], + ['qwtpoint3d',['QwtPoint3D',['../class_qwt_point3_d.html#acd7ec5a157397ce719225592b32cc510',1,'QwtPoint3D::QwtPoint3D()'],['../class_qwt_point3_d.html#a33b9fa088b750e1f4ded65c23fb62868',1,'QwtPoint3D::QwtPoint3D(double x, double y, double z)'],['../class_qwt_point3_d.html#a3847545c69e11d4c33891c5d9218afee',1,'QwtPoint3D::QwtPoint3D(const QwtPoint3D &)'],['../class_qwt_point3_d.html#a6747ac88e709543e57fc285e84181f49',1,'QwtPoint3D::QwtPoint3D(const QPointF &)']]], + ['qwtpoint3dseriesdata',['QwtPoint3DSeriesData',['../class_qwt_point3_d_series_data.html#a4410e3dea4acccfdde70eb1f99829c16',1,'QwtPoint3DSeriesData']]], + ['qwtpointarraydata',['QwtPointArrayData',['../class_qwt_point_array_data.html#a33044621333635f861b3945faf29cdc1',1,'QwtPointArrayData::QwtPointArrayData(const QVector< double > &x, const QVector< double > &y)'],['../class_qwt_point_array_data.html#ad83a51f37e5d626b60695baf3f0fd6fd',1,'QwtPointArrayData::QwtPointArrayData(const double *x, const double *y, size_t size)']]], + ['qwtpointmapper',['QwtPointMapper',['../class_qwt_point_mapper.html#a6e5eabb9c1af9b035023376fa2e1c472',1,'QwtPointMapper']]], + ['qwtpointpolar',['QwtPointPolar',['../class_qwt_point_polar.html#a365875acf86a9f052e12784b5f2f7d44',1,'QwtPointPolar::QwtPointPolar()'],['../class_qwt_point_polar.html#af1c77f9730d441937e52ff5beee04975',1,'QwtPointPolar::QwtPointPolar(double azimuth, double radius)'],['../class_qwt_point_polar.html#ae5cd7e8ab0505672748f779c9668fe29',1,'QwtPointPolar::QwtPointPolar(const QwtPointPolar &)'],['../class_qwt_point_polar.html#a269241ca9f94f641063fe896cdd77165',1,'QwtPointPolar::QwtPointPolar(const QPointF &)']]], + ['qwtpointseriesdata',['QwtPointSeriesData',['../class_qwt_point_series_data.html#aee91c50c88699839f7f5e720a23b9d3a',1,'QwtPointSeriesData']]], + ['qwtpowertransform',['QwtPowerTransform',['../class_qwt_power_transform.html#af29ae09162f70bdf81bc5a6fabcb84ba',1,'QwtPowerTransform']]], + ['qwtrasterdata',['QwtRasterData',['../class_qwt_raster_data.html#a0fc20e05a794c0dc85f6ae5719566588',1,'QwtRasterData']]], + ['qwtrichtextengine',['QwtRichTextEngine',['../class_qwt_rich_text_engine.html#aa4c1d5a1ee88d7406ba1d6453005b46a',1,'QwtRichTextEngine']]], + ['qwtroundscaledraw',['QwtRoundScaleDraw',['../class_qwt_round_scale_draw.html#a9c44d19488567825d826528b701587c8',1,'QwtRoundScaleDraw']]], + ['qwtsamplingthread',['QwtSamplingThread',['../class_qwt_sampling_thread.html#afb02e4696306d5211b4b6470410afbfc',1,'QwtSamplingThread']]], + ['qwtscalediv',['QwtScaleDiv',['../class_qwt_scale_div.html#a724dd19a63de442c0eb493308649ff19',1,'QwtScaleDiv::QwtScaleDiv(double lowerBound=0.0, double upperBound=0.0)'],['../class_qwt_scale_div.html#abdc25d9fe6b2efdd76a60f363a7c719c',1,'QwtScaleDiv::QwtScaleDiv(const QwtInterval &, QList< double >[NTickTypes])'],['../class_qwt_scale_div.html#a7326c0f401dee07c2a2661166daf24ae',1,'QwtScaleDiv::QwtScaleDiv(double lowerBound, double upperBound, QList< double >[NTickTypes])'],['../class_qwt_scale_div.html#a1c011f6d8ac4832b69b447d870a8f735',1,'QwtScaleDiv::QwtScaleDiv(double lowerBound, double upperBound, const QList< double > &minorTicks, const QList< double > &mediumTicks, const QList< double > &majorTicks)']]], + ['qwtscaledraw',['QwtScaleDraw',['../class_qwt_scale_draw.html#adbd01ba8d7f19fb3122f917b1c74145b',1,'QwtScaleDraw']]], + ['qwtscaleengine',['QwtScaleEngine',['../class_qwt_scale_engine.html#a4ad501667558e5095d36cc190d12790d',1,'QwtScaleEngine']]], + ['qwtscalemap',['QwtScaleMap',['../class_qwt_scale_map.html#a9576a2e19c0be1d036fee344ab68f542',1,'QwtScaleMap::QwtScaleMap()'],['../class_qwt_scale_map.html#a579bc766106d98edd7153e62ea77a19b',1,'QwtScaleMap::QwtScaleMap(const QwtScaleMap &)']]], + ['qwtscalewidget',['QwtScaleWidget',['../class_qwt_scale_widget.html#addfd5f0802f85f8abee1d3ff7a1617d6',1,'QwtScaleWidget::QwtScaleWidget(QWidget *parent=NULL)'],['../class_qwt_scale_widget.html#a13c0c28d56a9e44a81990c7c3fbb96e5',1,'QwtScaleWidget::QwtScaleWidget(QwtScaleDraw::Alignment, QWidget *parent=NULL)']]], + ['qwtseriesdata',['QwtSeriesData',['../class_qwt_series_data.html#a3f075340d18fb112a342d74716eb8d9c',1,'QwtSeriesData']]], + ['qwtseriesstore',['QwtSeriesStore',['../class_qwt_series_store.html#aa23545f522f87da936c0f095ee07c80e',1,'QwtSeriesStore']]], + ['qwtsetsample',['QwtSetSample',['../class_qwt_set_sample.html#af506c3484b65d5de2b6042755066ff81',1,'QwtSetSample::QwtSetSample()'],['../class_qwt_set_sample.html#af0bbb11cf7ed592107a4baf052290035',1,'QwtSetSample::QwtSetSample(double, const QVector< double > &=QVector< double >())']]], + ['qwtsetseriesdata',['QwtSetSeriesData',['../class_qwt_set_series_data.html#ae28991355a06876fcd14d760771e431b',1,'QwtSetSeriesData']]], + ['qwtsimplecompassrose',['QwtSimpleCompassRose',['../class_qwt_simple_compass_rose.html#a66cc98efe5717eaf11fb0e713cd1aa21',1,'QwtSimpleCompassRose']]], + ['qwtslider',['QwtSlider',['../class_qwt_slider.html#a6012d14e7a24752fca8828e1e1bedaa4',1,'QwtSlider::QwtSlider(QWidget *parent=NULL)'],['../class_qwt_slider.html#a5a4132613bc376adeabfedfe2f6bd02a',1,'QwtSlider::QwtSlider(Qt::Orientation, QWidget *parent=NULL)']]], + ['qwtspline',['QwtSpline',['../class_qwt_spline.html#a5d1e0ba35c637a88c66d9e4cbaf36e93',1,'QwtSpline::QwtSpline()'],['../class_qwt_spline.html#a2e42391f76d0b3091bf7754239f3ff0d',1,'QwtSpline::QwtSpline(const QwtSpline &)']]], + ['qwtsplinecurvefitter',['QwtSplineCurveFitter',['../class_qwt_spline_curve_fitter.html#a98ae80240b254df85dcc44e1f3e4e830',1,'QwtSplineCurveFitter']]], + ['qwtsymbol',['QwtSymbol',['../class_qwt_symbol.html#a710105d32ed915db46e4dbddc9cf6dc4',1,'QwtSymbol::QwtSymbol(Style=NoSymbol)'],['../class_qwt_symbol.html#a3fb872dc1cf5841df25ad6cba7fe9329',1,'QwtSymbol::QwtSymbol(Style, const QBrush &, const QPen &, const QSize &)'],['../class_qwt_symbol.html#aae936c253af0c441d19181d01b20b4a9',1,'QwtSymbol::QwtSymbol(const QPainterPath &, const QBrush &, const QPen &)']]], + ['qwtsyntheticpointdata',['QwtSyntheticPointData',['../class_qwt_synthetic_point_data.html#ad2980a20669d9703046e9ded9cacf496',1,'QwtSyntheticPointData']]], + ['qwtsystemclock',['QwtSystemClock',['../class_qwt_system_clock.html#a384e20d6049376575bf28306154854fd',1,'QwtSystemClock']]], + ['qwttext',['QwtText',['../class_qwt_text.html#a91439964ad1150c136dcaa113a648ecf',1,'QwtText::QwtText(const QString &=QString::null, TextFormat textFormat=AutoText)'],['../class_qwt_text.html#af88b42733c420574fa76b2d58b965313',1,'QwtText::QwtText(const QwtText &)']]], + ['qwttextengine',['QwtTextEngine',['../class_qwt_text_engine.html#a97c5ef76ee920ab0f19e178e85017d9d',1,'QwtTextEngine']]], + ['qwttextlabel',['QwtTextLabel',['../class_qwt_text_label.html#a95e022e766f4b9675f451482be7d654a',1,'QwtTextLabel::QwtTextLabel(QWidget *parent=NULL)'],['../class_qwt_text_label.html#a1a44e38b02bb398d315affe02bb4ea69',1,'QwtTextLabel::QwtTextLabel(const QwtText &, QWidget *parent=NULL)']]], + ['qwtthermo',['QwtThermo',['../class_qwt_thermo.html#a1d5bb3608c29cd8d104f22f0ffe31098',1,'QwtThermo']]], + ['qwttradingchartdata',['QwtTradingChartData',['../class_qwt_trading_chart_data.html#abfe5df45f8a6313b68e93715c7bbfb7b',1,'QwtTradingChartData']]], + ['qwttransform',['QwtTransform',['../class_qwt_transform.html#aa1fa1ab21d0fc01e06d3a6e462008d0b',1,'QwtTransform']]], + ['qwtweedingcurvefitter',['QwtWeedingCurveFitter',['../class_qwt_weeding_curve_fitter.html#a7deb4d070a329cbdee454023194898a7',1,'QwtWeedingCurveFitter']]], + ['qwtwheel',['QwtWheel',['../class_qwt_wheel.html#a98fc47123aac47168b5d98a73b87d0a7',1,'QwtWheel']]], + ['qwtwidgetoverlay',['QwtWidgetOverlay',['../class_qwt_widget_overlay.html#afeb3615cf79bee41bbae21f3b92b924d',1,'QwtWidgetOverlay']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/functions_72.html b/ThirdParty/Qwt/doc/html/search/functions_72.html new file mode 100644 index 0000000000..71f58bbd14 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/functions_72.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/functions_72.js b/ThirdParty/Qwt/doc/html/search/functions_72.js new file mode 100644 index 0000000000..2ee80fe66c --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/functions_72.js @@ -0,0 +1,55 @@ +var searchData= +[ + ['radius',['radius',['../class_qwt_point_polar.html#ab629fcfb36f0f29df45b256c6bddf194',1,'QwtPointPolar::radius()'],['../class_qwt_round_scale_draw.html#ac5fba54e87a8bdcf01f909b5fe60ac1e',1,'QwtRoundScaleDraw::radius()']]], + ['range',['range',['../class_qwt_scale_div.html#abe63aa19b346a4683ab19bf59a5bb37c',1,'QwtScaleDiv']]], + ['rangeflags',['rangeFlags',['../class_qwt_thermo.html#a3b05d842b667cf8724f8a900f0d05b34',1,'QwtThermo']]], + ['razimuth',['rAzimuth',['../class_qwt_point_polar.html#ae509330927d54dbc7cf65fae42083fce',1,'QwtPointPolar']]], + ['rect',['rect',['../class_qwt_pixel_matrix.html#a05162507dc01b9616ef4b6b079786599',1,'QwtPixelMatrix']]], + ['rectofinterest',['rectOfInterest',['../class_qwt_synthetic_point_data.html#a00ead6b5e6cbc06d87af6edaa518d05f',1,'QwtSyntheticPointData']]], + ['reference',['reference',['../class_qwt_scale_engine.html#a5962458870865df797e84e3bd6badf02',1,'QwtScaleEngine']]], + ['referenceaxis',['referenceAxis',['../class_qwt_plot_rescaler.html#ae495168aec756dd617a5ad0c24e0eede',1,'QwtPlotRescaler']]], + ['released',['released',['../class_qwt_legend_label.html#a6e5dc9325dfed28651c8b40f17ba73af',1,'QwtLegendLabel']]], + ['remove',['remove',['../class_qwt_picker.html#a217ae414d4967e66def863b019194661',1,'QwtPicker']]], + ['removed',['removed',['../class_qwt_picker.html#ae43005f819fc423da4bad205d99e4d1e',1,'QwtPicker']]], + ['removeitem',['removeItem',['../class_qwt_plot_dict.html#abd0227e8b888b40b4e62a23f6040c6cd',1,'QwtPlotDict']]], + ['render',['render',['../class_qwt_graphic.html#a0bad97fa44e9270ba8bc66a370025a9f',1,'QwtGraphic::render(QPainter *) const '],['../class_qwt_graphic.html#af4d9626a5bb93bc83273f202e273b764',1,'QwtGraphic::render(QPainter *, const QSizeF &, Qt::AspectRatioMode=Qt::IgnoreAspectRatio) const '],['../class_qwt_graphic.html#afb45aff5460002a670ad7fabeae8d1d4',1,'QwtGraphic::render(QPainter *, const QRectF &, Qt::AspectRatioMode=Qt::IgnoreAspectRatio) const '],['../class_qwt_graphic.html#aa44399acb7c639a0a84dc427b59a3169',1,'QwtGraphic::render(QPainter *, const QPointF &, Qt::Alignment=Qt::AlignTop|Qt::AlignLeft) const '],['../class_qwt_plot_renderer.html#a44ff336a2d3d955ac17b1daa5fca3c31',1,'QwtPlotRenderer::render()'],['../class_qwt_plot_svg_item.html#a333715a1c09bdb07f3eb57d2272f2b90',1,'QwtPlotSvgItem::render()']]], + ['rendercanvas',['renderCanvas',['../class_qwt_plot_renderer.html#adbf07b9b77766b507dbe16791556b02c',1,'QwtPlotRenderer']]], + ['rendercontourlines',['renderContourLines',['../class_qwt_plot_spectrogram.html#aad79c66b4ab2b64f368378691f562b56',1,'QwtPlotSpectrogram']]], + ['renderdocument',['renderDocument',['../class_qwt_plot_renderer.html#a9e6c72105a0a6533a1a43efea91f62d9',1,'QwtPlotRenderer::renderDocument(QwtPlot *, const QString &fileName, const QSizeF &sizeMM, int resolution=85)'],['../class_qwt_plot_renderer.html#a983cfb85dc7896deedcda562141e8225',1,'QwtPlotRenderer::renderDocument(QwtPlot *, const QString &fileName, const QString &format, const QSizeF &sizeMM, int resolution=85)']]], + ['renderer',['renderer',['../class_qwt_plot_svg_item.html#a64d8e932edaaa7ffd5820be216eecadb',1,'QwtPlotSvgItem::renderer() const '],['../class_qwt_plot_svg_item.html#a7263211f1f91f669d9abd8e6dd9529a3',1,'QwtPlotSvgItem::renderer()']]], + ['renderflags',['renderFlags',['../class_qwt_text.html#a59c6bf54af867ce5632a07117fe442e1',1,'QwtText']]], + ['renderfooter',['renderFooter',['../class_qwt_plot_renderer.html#a9eb95db72559d1820c38fd6f772c7b4b',1,'QwtPlotRenderer']]], + ['renderimage',['renderImage',['../class_qwt_plot_raster_item.html#a1738b36c0e6e4073f3ad6629e7923f74',1,'QwtPlotRasterItem::renderImage()'],['../class_qwt_plot_spectrogram.html#a99fa9694347e6f06240538af88385ca6',1,'QwtPlotSpectrogram::renderImage()']]], + ['renderitem',['renderItem',['../class_qwt_legend.html#ad2f7db6a681a11d2af7a960a8db931f5',1,'QwtLegend']]], + ['renderlegend',['renderLegend',['../class_qwt_abstract_legend.html#a2fe1ac5ac1448e4d86b7437505214d9c',1,'QwtAbstractLegend::renderLegend()'],['../class_qwt_legend.html#aacc94e890b12b745619c02749628b6ce',1,'QwtLegend::renderLegend()'],['../class_qwt_plot_renderer.html#adbf1706f778a88d7db5304adde93b02a',1,'QwtPlotRenderer::renderLegend()']]], + ['rendermode',['renderMode',['../class_qwt_widget_overlay.html#a33b227f98d26b0f1d4f2a0d5e9a6d99c',1,'QwtWidgetOverlay']]], + ['renderscale',['renderScale',['../class_qwt_plot_renderer.html#a3242670daa59fe5ba7b8b4d60339d3a1',1,'QwtPlotRenderer']]], + ['rendersymbols',['renderSymbols',['../class_qwt_symbol.html#ae72f15c4142dd2de7a361768c17e5560',1,'QwtSymbol']]], + ['renderthreadcount',['renderThreadCount',['../class_qwt_plot_item.html#acb8a2fce65770739fc263fd1fb19fcf3',1,'QwtPlotItem']]], + ['rendertile',['renderTile',['../class_qwt_plot_spectrogram.html#a122ad763c5195de93cac900bd3bcb112',1,'QwtPlotSpectrogram']]], + ['rendertitle',['renderTitle',['../class_qwt_plot_renderer.html#af793ca09c4f337fae62bfae962c8ade2',1,'QwtPlotRenderer']]], + ['renderto',['renderTo',['../class_qwt_plot_renderer.html#afa913f7f77dc04ab9fe0030df79c9806',1,'QwtPlotRenderer::renderTo(QwtPlot *, QPrinter &) const '],['../class_qwt_plot_renderer.html#a1501f42510d7f5c144d67baac5d129b5',1,'QwtPlotRenderer::renderTo(QwtPlot *, QPaintDevice &p) const ']]], + ['rendertolerance',['renderTolerance',['../class_qwt_plot_shape_item.html#aad8a52abd8293e8c01c07b5116db7970',1,'QwtPlotShapeItem']]], + ['replot',['replot',['../class_qwt_plot.html#a7b094e29b8e92b00e36517d0d7633c4b',1,'QwtPlot::replot()'],['../class_qwt_plot_canvas.html#a1548423348c29001ee2b6fd1c0f9f033',1,'QwtPlotCanvas::replot()'],['../class_qwt_plot_g_l_canvas.html#af2bf82a971fcea76dab92da15a859c67',1,'QwtPlotGLCanvas::replot()']]], + ['resamplemode',['resampleMode',['../class_qwt_matrix_raster_data.html#af4edef83d2862640893552b8f20ed725',1,'QwtMatrixRasterData']]], + ['rescale',['rescale',['../class_qwt_abstract_scale.html#a647e6458305a0967077f4b1f03811c14',1,'QwtAbstractScale::rescale()'],['../class_qwt_magnifier.html#a5c3d5bda10412a50bd403afe84e2ccee',1,'QwtMagnifier::rescale()'],['../class_qwt_plot_magnifier.html#a271ae5ad42c3dd12812246d2dee687ea',1,'QwtPlotMagnifier::rescale()'],['../class_qwt_plot_rescaler.html#afd6783b36fa0a2f61b481bffc5f33251',1,'QwtPlotRescaler::rescale() const '],['../class_qwt_plot_rescaler.html#a6c609a90c617ddddb5c0e282ceeeeeac',1,'QwtPlotRescaler::rescale(const QSize &oldSize, const QSize &newSize) const '],['../class_qwt_plot_zoomer.html#a0d0f90bbd5fe99d5231b3cee00fffabe',1,'QwtPlotZoomer::rescale()']]], + ['rescalepolicy',['rescalePolicy',['../class_qwt_plot_rescaler.html#adceb6d094c1db33c1ef23e18e1b49185',1,'QwtPlotRescaler']]], + ['reset',['reset',['../class_qwt_graphic.html#a441f351c6578deab715126586dd1ca21',1,'QwtGraphic::reset()'],['../class_qwt_picker.html#a0e50f7be7182e81607bf1625dcdff6eb',1,'QwtPicker::reset()'],['../class_qwt_picker_machine.html#ace6daa55324a8daab3839cf8ba677a93',1,'QwtPickerMachine::reset()'],['../class_qwt_plot_direct_painter.html#a895bf1ebfd772a2200dc09bed596cf4d',1,'QwtPlotDirectPainter::reset()'],['../class_qwt_spline.html#afc52fd49e7f00d57a0336059fae299c0',1,'QwtSpline::reset()']]], + ['resetsymbolmap',['resetSymbolMap',['../class_qwt_plot_multi_bar_chart.html#a2fac8a87796eb02ca1418ea806c0abb4',1,'QwtPlotMultiBarChart']]], + ['resizeevent',['resizeEvent',['../class_qwt_plot.html#aa4d5f73681880b9770bb6a604c415987',1,'QwtPlot::resizeEvent()'],['../class_qwt_plot_canvas.html#a1d4a1508bef7b417c3414c345bd60022',1,'QwtPlotCanvas::resizeEvent()'],['../class_qwt_scale_widget.html#a9072385d42de47fec634989134d1cd98',1,'QwtScaleWidget::resizeEvent()'],['../class_qwt_slider.html#a1f65d6ce5f8ed94e0a632edcd68a51f9',1,'QwtSlider::resizeEvent()'],['../class_qwt_thermo.html#a31ea86c3ab9c6925752dc8d6215fd9f0',1,'QwtThermo::resizeEvent()'],['../class_qwt_widget_overlay.html#a1ec8de0015c9b823fd304d9febb580ca',1,'QwtWidgetOverlay::resizeEvent()']]], + ['resizemode',['resizeMode',['../class_qwt_picker.html#a684032c8aea570b069da2f8193760df9',1,'QwtPicker']]], + ['restart',['restart',['../class_qwt_system_clock.html#a6be327dd133c1d7ecccfb95050eef7b9',1,'QwtSystemClock']]], + ['rgb',['rgb',['../class_qwt_color_map.html#aaed0bb47b6379696c588732348438136',1,'QwtColorMap::rgb()'],['../class_qwt_linear_color_map.html#ac031babccc90d8c857c707d0841ba1eb',1,'QwtLinearColorMap::rgb()'],['../class_qwt_alpha_color_map.html#a2f0ce2bdaecf7e74b635b8433ed733d5',1,'QwtAlphaColorMap::rgb()']]], + ['rose',['rose',['../class_qwt_compass.html#a7405a44d947e16f53b11dea4544d7683',1,'QwtCompass::rose() const '],['../class_qwt_compass.html#a99477d676bd866acd1a418615cba423b',1,'QwtCompass::rose()']]], + ['roundingalignment',['roundingAlignment',['../class_qwt_painter.html#ae9af230df7bb8d40b802d4f3205a8631',1,'QwtPainter::roundingAlignment()'],['../class_qwt_painter.html#ab11788d777ce54a1959bf8387dba6ad9',1,'QwtPainter::roundingAlignment(QPainter *)']]], + ['rradius',['rRadius',['../class_qwt_point_polar.html#a69cf76a959e4417038b4e2684d307847',1,'QwtPointPolar']]], + ['rtti',['rtti',['../class_qwt_plot_bar_chart.html#a88888d4deb246c45f3161cfc5a8940e6',1,'QwtPlotBarChart::rtti()'],['../class_qwt_plot_curve.html#a1cb75062e781f4e0839a6cd2081c3928',1,'QwtPlotCurve::rtti()'],['../class_qwt_plot_grid.html#aae0d0b5afbc670dd257302b13601ea99',1,'QwtPlotGrid::rtti()'],['../class_qwt_plot_histogram.html#a7a927d6ad8544cf5d46e629a03a5a8f1',1,'QwtPlotHistogram::rtti()'],['../class_qwt_plot_interval_curve.html#a59e7b26fc91dd3c7c2412b5fd8d4ca9f',1,'QwtPlotIntervalCurve::rtti()'],['../class_qwt_plot_item.html#af153b5a40a60ac626f1c58e69fc4ecad',1,'QwtPlotItem::rtti()'],['../class_qwt_plot_legend_item.html#ad5ae47214f5424e73e960cf16e282cf5',1,'QwtPlotLegendItem::rtti()'],['../class_qwt_plot_marker.html#a4e48032adf8bdda1aacba4977280123f',1,'QwtPlotMarker::rtti()'],['../class_qwt_plot_multi_bar_chart.html#a60d8065486dbf458019a283798f1e99c',1,'QwtPlotMultiBarChart::rtti()'],['../class_qwt_plot_scale_item.html#a72d7c46ade62f45f3dffa93931900d74',1,'QwtPlotScaleItem::rtti()'],['../class_qwt_plot_shape_item.html#a1f7cff8165dcd7f6cfa416b28f052847',1,'QwtPlotShapeItem::rtti()'],['../class_qwt_plot_spectro_curve.html#a5e866a7b7c024d26329814745ca2379c',1,'QwtPlotSpectroCurve::rtti()'],['../class_qwt_plot_spectrogram.html#a01197466f530633759337bbb7b8f7504',1,'QwtPlotSpectrogram::rtti()'],['../class_qwt_plot_svg_item.html#a4331deca8a2ecdd6a7ebe1be7de22969',1,'QwtPlotSvgItem::rtti()'],['../class_qwt_plot_text_label.html#a6478e871cb51ee383e82c437cf6dbf86',1,'QwtPlotTextLabel::rtti()'],['../class_qwt_plot_trading_curve.html#aa57d588027e9dbeb2cc9bc0cafff84b9',1,'QwtPlotTradingCurve::rtti()'],['../class_qwt_plot_zone_item.html#a7af34a4fdf5d9af4786049405de46ce1',1,'QwtPlotZoneItem::rtti()']]], + ['rubberband',['rubberBand',['../class_qwt_picker.html#a6a7af18636587af2c11a6c060929403a',1,'QwtPicker']]], + ['rubberbandmask',['rubberBandMask',['../class_qwt_picker.html#a9894c9ca37f06ad79cff26a3c63f6c66',1,'QwtPicker']]], + ['rubberbandoverlay',['rubberBandOverlay',['../class_qwt_picker.html#aa4bdb9e280b226fe2743be0aef11eca8',1,'QwtPicker']]], + ['rubberbandpen',['rubberBandPen',['../class_qwt_picker.html#a074492301e00535def0fe2cb449fba37',1,'QwtPicker']]], + ['run',['run',['../class_qwt_sampling_thread.html#a247354fcc8e2597e105d87a2cfaa0a96',1,'QwtSamplingThread']]], + ['rx',['rx',['../class_qwt_point3_d.html#a99ae15c21e43fac2c4b8755111b03ad0',1,'QwtPoint3D']]], + ['ry',['ry',['../class_qwt_point3_d.html#ab0894c41fdb85dcc7affe38acf33f48d',1,'QwtPoint3D']]], + ['rz',['rz',['../class_qwt_point3_d.html#af76eb9c617ea48ab1050a79bac1d90eb',1,'QwtPoint3D']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/functions_73.html b/ThirdParty/Qwt/doc/html/search/functions_73.html new file mode 100644 index 0000000000..c80660e8c3 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/functions_73.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/functions_73.js b/ThirdParty/Qwt/doc/html/search/functions_73.js new file mode 100644 index 0000000000..10088af7e6 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/functions_73.js @@ -0,0 +1,357 @@ +var searchData= +[ + ['s1',['s1',['../class_qwt_scale_map.html#a38b6a7040cd15a427f7631afa20cbad8',1,'QwtScaleMap']]], + ['s2',['s2',['../class_qwt_scale_map.html#a644fe199eecf30fcd1803be554cd21f7',1,'QwtScaleMap']]], + ['sample',['sample',['../class_qwt_point_array_data.html#ad2fa2b92a88d216fb4a74cb4b6ccbb9f',1,'QwtPointArrayData::sample()'],['../class_qwt_c_pointer_data.html#a5e01b287eca7d0c4b52bbf514c5244d2',1,'QwtCPointerData::sample()'],['../class_qwt_synthetic_point_data.html#a70d3ed6bfd764878f1709ab6b55e2f0e',1,'QwtSyntheticPointData::sample()'],['../class_qwt_sampling_thread.html#a67c4a524736808dc1ba3b81670c0cbd5',1,'QwtSamplingThread::sample()'],['../class_qwt_series_data.html#ae8650d16c07c58f01897ab48658a3266',1,'QwtSeriesData::sample()'],['../class_qwt_array_series_data.html#a900ba90abf9a0852026099bdcae2ba7f',1,'QwtArraySeriesData::sample()'],['../class_qwt_series_store.html#adbb86cd5cd59472f2f3137742ca74a48',1,'QwtSeriesStore::sample()']]], + ['samples',['samples',['../class_qwt_array_series_data.html#a2d3f931bd28f40bc6e13c4b507e5b502',1,'QwtArraySeriesData']]], + ['samplewidth',['sampleWidth',['../class_qwt_plot_abstract_bar_chart.html#aeb17b54d0ea782d72c94944b867e1946',1,'QwtPlotAbstractBarChart']]], + ['scalechange',['scaleChange',['../class_qwt_abstract_scale.html#a0dbb7bdc557c0a7b163643e41970ed6a',1,'QwtAbstractScale::scaleChange()'],['../class_qwt_abstract_slider.html#a491fe8bbe771fb51bf35d429d4b92e05',1,'QwtAbstractSlider::scaleChange()'],['../class_qwt_dial.html#a0cee4448e2753ed259917f1874a3e158',1,'QwtDial::scaleChange()'],['../class_qwt_scale_widget.html#af151a963ea3cb7f04815db93e8f4882d',1,'QwtScaleWidget::scaleChange()'],['../class_qwt_slider.html#a31ae4c53eb17d77ee0fd846ff6eea7e3',1,'QwtSlider::scaleChange()'],['../class_qwt_thermo.html#a3f2f5077580235a5a776805a9721c8ba',1,'QwtThermo::scaleChange()']]], + ['scaledboundingrect',['scaledBoundingRect',['../class_qwt_graphic.html#aa415b6f8be72408538c20c0cc60eb0bc',1,'QwtGraphic']]], + ['scalediv',['scaleDiv',['../class_qwt_abstract_scale.html#ae0ec7f1528981f15d8ede6a78530f065',1,'QwtAbstractScale::scaleDiv()'],['../class_qwt_abstract_scale_draw.html#a82510027cd5bee269628c9d6302a19a9',1,'QwtAbstractScaleDraw::scaleDiv()'],['../class_qwt_plot_scale_item.html#a06695f68519b2cc8660441d12d84ab13',1,'QwtPlotScaleItem::scaleDiv()']]], + ['scaledivchanged',['scaleDivChanged',['../class_qwt_scale_widget.html#a55c52717ede368069f5f44b9901e3400',1,'QwtScaleWidget']]], + ['scaledraw',['scaleDraw',['../class_qwt_dial.html#adaa9a23f4e19d3cd085db1c61665d1d6',1,'QwtDial::scaleDraw()'],['../class_qwt_dial.html#ae1b59c65bc9717bd83ffb8e8ce07988c',1,'QwtDial::scaleDraw() const '],['../class_qwt_knob.html#aa9c4c23e20fc59b3ca2bfed9fe1e3719',1,'QwtKnob::scaleDraw() const '],['../class_qwt_knob.html#a3154037eec8c76c24577b8bf1d92b871',1,'QwtKnob::scaleDraw()'],['../class_qwt_plot_scale_item.html#abdcced6eb4179319aeeeba370ec54a0f',1,'QwtPlotScaleItem::scaleDraw() const '],['../class_qwt_plot_scale_item.html#ab75d17fe11c146b49ffa47940f512850',1,'QwtPlotScaleItem::scaleDraw()'],['../class_qwt_scale_widget.html#ad8603e84f851e5d91feb21beebf19896',1,'QwtScaleWidget::scaleDraw() const '],['../class_qwt_scale_widget.html#a6ccb7e3a4537396f59fc30c7d76cc20d',1,'QwtScaleWidget::scaleDraw()'],['../class_qwt_slider.html#ab3394f8eb22b75cc6add3b8d3444ad30',1,'QwtSlider::scaleDraw()'],['../class_qwt_thermo.html#aaacb94a49eb05c91a3896d202f79ec46',1,'QwtThermo::scaleDraw() const '],['../class_qwt_thermo.html#a7d0f262032c034c5da703ec2f2d120b7',1,'QwtThermo::scaleDraw()']]], + ['scaledsymbolwidth',['scaledSymbolWidth',['../class_qwt_plot_trading_curve.html#a327d6afbc4bc12794e9bd586c0fcafbc',1,'QwtPlotTradingCurve']]], + ['scaleengine',['scaleEngine',['../class_qwt_abstract_scale.html#a5b8084cc735933ce9338fd2df1126f0e',1,'QwtAbstractScale::scaleEngine() const '],['../class_qwt_abstract_scale.html#aea3b9d4912f1c28671f232e4100936d7',1,'QwtAbstractScale::scaleEngine()']]], + ['scaleinnerrect',['scaleInnerRect',['../class_qwt_dial.html#ab793e4c15e9b32a7e8d13f0b28d1feb9',1,'QwtDial']]], + ['scalemap',['scaleMap',['../class_qwt_abstract_scale.html#a68f120e12e373796b5d74199a9b8a4b0',1,'QwtAbstractScale::scaleMap()'],['../class_qwt_abstract_scale_draw.html#aac87f593525666a47a57d9e2b4f02c66',1,'QwtAbstractScaleDraw::scaleMap() const '],['../class_qwt_abstract_scale_draw.html#ae7488eb63ad73a2e69acb29ff069c904',1,'QwtAbstractScaleDraw::scaleMap()']]], + ['scalemaxmajor',['scaleMaxMajor',['../class_qwt_abstract_scale.html#a4cfbcd9880297b1ca28fa824e3f4c3e6',1,'QwtAbstractScale']]], + ['scalemaxminor',['scaleMaxMinor',['../class_qwt_abstract_scale.html#a5b23fafbb56bb43fd241c1839256357f',1,'QwtAbstractScale']]], + ['scaleposition',['scalePosition',['../class_qwt_slider.html#ac3f14f80cc92d1c267e2ae88df6f61c1',1,'QwtSlider::scalePosition()'],['../class_qwt_thermo.html#a1cbfd720c1f8c7bf38c984999726086f',1,'QwtThermo::scalePosition()']]], + ['scalerect',['scaleRect',['../class_qwt_plot_item.html#a186036cbee194b87b9bc4afb693c27f4',1,'QwtPlotItem::scaleRect()'],['../class_qwt_plot_layout.html#a184c8134d58aff17f3a91ae1505917e2',1,'QwtPlotLayout::scaleRect()'],['../class_qwt_plot_picker.html#a6becfde9ef447128a55c0675bf1c1524',1,'QwtPlotPicker::scaleRect()']]], + ['scalestepsize',['scaleStepSize',['../class_qwt_abstract_scale.html#ad94ddd24f5f9742a577b19f9c6e00117',1,'QwtAbstractScale']]], + ['scrolledto',['scrolledTo',['../class_qwt_abstract_slider.html#af19ab98a4101c2eaa43de2df7ebe4d0d',1,'QwtAbstractSlider::scrolledTo()'],['../class_qwt_dial.html#afc13ba2a48fc4f99a74f08d87dabc016',1,'QwtDial::scrolledTo()'],['../class_qwt_knob.html#a800716b7da7d41da1472c561d6e0b332',1,'QwtKnob::scrolledTo()'],['../class_qwt_slider.html#aa895f8b5fb3968d4ce3008f27792d3b9',1,'QwtSlider::scrolledTo()']]], + ['scrollextent',['scrollExtent',['../class_qwt_abstract_legend.html#a51e8c45d2afc691e78b09c662d7a493e',1,'QwtAbstractLegend::scrollExtent()'],['../class_qwt_legend.html#ad75d747944921533aede5bfce518ec02',1,'QwtLegend::scrollExtent()']]], + ['sdist',['sDist',['../class_qwt_scale_map.html#adf621246cfa7313280a35a44063972f3',1,'QwtScaleMap']]], + ['selected',['selected',['../class_qwt_picker.html#a283ec139021c9b5e95d1472a9c902c7e',1,'QwtPicker::selected()'],['../class_qwt_plot_picker.html#a28f6c8af0efd0abb6dc144670efbb31b',1,'QwtPlotPicker::selected()'],['../class_qwt_plot_picker.html#ace55ce208052c631ce666b5af2b7342b',1,'QwtPlotPicker::selected()'],['../class_qwt_plot_picker.html#a7eb9fdda3166c452660130ceffd1d092',1,'QwtPlotPicker::selected()']]], + ['selection',['selection',['../class_qwt_picker.html#ac5bc0a5f7054c407195ce9ee1d0cf394',1,'QwtPicker']]], + ['selectiontype',['selectionType',['../class_qwt_picker_machine.html#a9ccd6ccb3fa0e2a73730e69a8658c316',1,'QwtPickerMachine']]], + ['setabortkey',['setAbortKey',['../class_qwt_panner.html#acbb1b9e30214354708e1d75db6b78289',1,'QwtPanner']]], + ['setabstractscaledraw',['setAbstractScaleDraw',['../class_qwt_abstract_scale.html#a950c5bf521dc704b78f76c7951346288',1,'QwtAbstractScale']]], + ['setalarmbrush',['setAlarmBrush',['../class_qwt_thermo.html#a1d6a0fae32e21fe6c5f54762073dbe8b',1,'QwtThermo']]], + ['setalarmenabled',['setAlarmEnabled',['../class_qwt_thermo.html#abed75ea5e839ee4afed2c96f6927721e',1,'QwtThermo']]], + ['setalarmlevel',['setAlarmLevel',['../class_qwt_thermo.html#ab42dff878632d210050be2be03535f6a',1,'QwtThermo']]], + ['setaligncanvastoscale',['setAlignCanvasToScale',['../class_qwt_plot_layout.html#ad243b9afc9b5ce9530b500dc35096d67',1,'QwtPlotLayout']]], + ['setaligncanvastoscales',['setAlignCanvasToScales',['../class_qwt_plot_layout.html#a147fcf4c59b34779b5a7dc7361a3b6c3',1,'QwtPlotLayout']]], + ['setalignment',['setAlignment',['../class_qwt_knob.html#ab84683292e11b7c3de4855d844b5471c',1,'QwtKnob::setAlignment()'],['../class_qwt_plot_legend_item.html#a7f0bc77d242fe1977d8dee501fa5240f',1,'QwtPlotLegendItem::setAlignment()'],['../class_qwt_plot_scale_item.html#af11343d14c4ee38e0527cedd52b3da85',1,'QwtPlotScaleItem::setAlignment()'],['../class_qwt_scale_draw.html#a7a4de0055dc1358e55c3357366a54091',1,'QwtScaleDraw::setAlignment()'],['../class_qwt_scale_widget.html#ab6421ace2bd56d5559689522336556e0',1,'QwtScaleWidget::setAlignment()']]], + ['setalpha',['setAlpha',['../class_qwt_plot_raster_item.html#a14f2ab8ec0994384e6269f869c352273',1,'QwtPlotRasterItem']]], + ['setanglerange',['setAngleRange',['../class_qwt_round_scale_draw.html#a5d85678fdb9fbb4d622425aab9ecc681',1,'QwtRoundScaleDraw']]], + ['setaspectratio',['setAspectRatio',['../class_qwt_plot_rescaler.html#a31f71937b4cff3e60f74db83beb6d2de',1,'QwtPlotRescaler::setAspectRatio(double ratio)'],['../class_qwt_plot_rescaler.html#aa747f1cf3ecc3a37f98d0972e1db600b',1,'QwtPlotRescaler::setAspectRatio(int axis, double ratio)']]], + ['setattribute',['setAttribute',['../class_qwt_plot_direct_painter.html#a498b9857a09e399010a3f8bc9c235a8d',1,'QwtPlotDirectPainter::setAttribute()'],['../class_qwt_scale_engine.html#acf02a88f6e778edbc9e005960f35b3b7',1,'QwtScaleEngine::setAttribute()']]], + ['setattributes',['setAttributes',['../class_qwt_scale_engine.html#acd73d5f27b5db0bc7ee673eb6fe9810d',1,'QwtScaleEngine']]], + ['setautodelete',['setAutoDelete',['../class_qwt_plot_dict.html#a3291431f0a9cca5b2affc5adf17bbdfb',1,'QwtPlotDict']]], + ['setautoreplot',['setAutoReplot',['../class_qwt_plot.html#ab1cbce6d43ff9772735a9df9104f882f',1,'QwtPlot']]], + ['setaxes',['setAxes',['../class_qwt_plot_item.html#a6f6c7b34fe86e8029914b3b780b55ea4',1,'QwtPlotItem']]], + ['setaxis',['setAxis',['../class_qwt_plot_picker.html#aa901c86543585c7056133a5cb6652e3d',1,'QwtPlotPicker::setAxis()'],['../class_qwt_plot_zoomer.html#a6cb755e06b83e50e8353dd706f7fb6f0',1,'QwtPlotZoomer::setAxis()']]], + ['setaxisautoscale',['setAxisAutoScale',['../class_qwt_plot.html#a6fb58f90366920f234440fceead50432',1,'QwtPlot']]], + ['setaxisenabled',['setAxisEnabled',['../class_qwt_plot_magnifier.html#ac8806df408b5ed9eac79cd38e5fc1508',1,'QwtPlotMagnifier::setAxisEnabled()'],['../class_qwt_plot_panner.html#acbd5d67684c5a20ea0115e66f69540e4',1,'QwtPlotPanner::setAxisEnabled()']]], + ['setaxisfont',['setAxisFont',['../class_qwt_plot.html#a9a14e57652c016f40388a68e556917e3',1,'QwtPlot']]], + ['setaxislabelalignment',['setAxisLabelAlignment',['../class_qwt_plot.html#a19f1b67fa79b80c712cf5f52b97ea0c5',1,'QwtPlot']]], + ['setaxislabelrotation',['setAxisLabelRotation',['../class_qwt_plot.html#ad5fa7aa01c88eab38ad64b131584f977',1,'QwtPlot']]], + ['setaxismaxmajor',['setAxisMaxMajor',['../class_qwt_plot.html#a34df698558c9bd9c38bdd8ff04cc6c41',1,'QwtPlot']]], + ['setaxismaxminor',['setAxisMaxMinor',['../class_qwt_plot.html#aa45b271684d6202061f1afcfa70e7cf6',1,'QwtPlot']]], + ['setaxisscale',['setAxisScale',['../class_qwt_plot.html#acef5ea818944b93b8695d0c16924eed6',1,'QwtPlot']]], + ['setaxisscalediv',['setAxisScaleDiv',['../class_qwt_plot.html#a2365da57b983eb39752fa4f6378c225a',1,'QwtPlot']]], + ['setaxisscaledraw',['setAxisScaleDraw',['../class_qwt_plot.html#a956a14b08e016eb83768ff4187d3849d',1,'QwtPlot']]], + ['setaxisscaleengine',['setAxisScaleEngine',['../class_qwt_plot.html#abf09452377b53e584a5086354a134d78',1,'QwtPlot']]], + ['setaxistitle',['setAxisTitle',['../class_qwt_plot.html#a5d60f1836e05e5cc5c7fe9570d6a608a',1,'QwtPlot::setAxisTitle(int axisId, const QString &)'],['../class_qwt_plot.html#ad134a193ab40ce33743365558d0303c4',1,'QwtPlot::setAxisTitle(int axisId, const QwtText &)']]], + ['setazimuth',['setAzimuth',['../class_qwt_point_polar.html#a32c6c64510fce3e087d332305b4aca9e',1,'QwtPointPolar']]], + ['setbackgroundbrush',['setBackgroundBrush',['../class_qwt_plot_legend_item.html#a82c391eecd2752c3a85a274973f34b6e',1,'QwtPlotLegendItem::setBackgroundBrush()'],['../class_qwt_text.html#af016a747b234aede9f0cbbeb06ed2802',1,'QwtText::setBackgroundBrush()']]], + ['setbackgroundmode',['setBackgroundMode',['../class_qwt_plot_legend_item.html#a4974efd3548c1335f0969275a95e7cba',1,'QwtPlotLegendItem']]], + ['setbartitles',['setBarTitles',['../class_qwt_plot_multi_bar_chart.html#ab519e583c3463e260c8f47be67aa9b8e',1,'QwtPlotMultiBarChart']]], + ['setbase',['setBase',['../class_qwt_scale_engine.html#afdabe4fd2a89b7cd5a21cdc9ac2269d6',1,'QwtScaleEngine']]], + ['setbaseline',['setBaseline',['../class_qwt_plot_abstract_bar_chart.html#adafbea42ddc3f7f639f2880a4bf683ad',1,'QwtPlotAbstractBarChart::setBaseline()'],['../class_qwt_plot_curve.html#adbb5da6798a60138315b18194cf1ca1e',1,'QwtPlotCurve::setBaseline()'],['../class_qwt_plot_histogram.html#a372314f4e2921673f74d46773d583cf2',1,'QwtPlotHistogram::setBaseline()']]], + ['setborderdist',['setBorderDist',['../class_qwt_scale_widget.html#a75477785c41114e4b2fc08bec64e5d26',1,'QwtScaleWidget']]], + ['setborderdistance',['setBorderDistance',['../class_qwt_plot_legend_item.html#a1238fb3d43f81bea8fa5d89fb6f24bfe',1,'QwtPlotLegendItem::setBorderDistance()'],['../class_qwt_plot_scale_item.html#a34bb235d0715d9c13669fe90669fc545',1,'QwtPlotScaleItem::setBorderDistance()']]], + ['setborderflags',['setBorderFlags',['../class_qwt_interval.html#ad1bce23251519f0d44937413f8547dc5',1,'QwtInterval']]], + ['setborderpen',['setBorderPen',['../class_qwt_plot_legend_item.html#a92d38a3db46df13cc325c3ec8ea63768',1,'QwtPlotLegendItem::setBorderPen()'],['../class_qwt_text.html#aca4dd700b7a182114a8c0eb864c4ec2f',1,'QwtText::setBorderPen()']]], + ['setborderradius',['setBorderRadius',['../class_qwt_plot_canvas.html#a1e5c325697c0e892bf0e4e514d50177c',1,'QwtPlotCanvas::setBorderRadius()'],['../class_qwt_plot_legend_item.html#afe9ab7925e12c81d7534343de29ae9cf',1,'QwtPlotLegendItem::setBorderRadius()'],['../class_qwt_text.html#a7c62dfe82aa94f113cd4f8702bd2242c',1,'QwtText::setBorderRadius()']]], + ['setborderwidth',['setBorderWidth',['../class_qwt_knob.html#a2e0a17648602bab3b1aaabfc3ba19441',1,'QwtKnob::setBorderWidth()'],['../class_qwt_slider.html#a0d40da533b9417974240e127b5d701e4',1,'QwtSlider::setBorderWidth()'],['../class_qwt_thermo.html#a25821f13d01848a1a37690d4796311bc',1,'QwtThermo::setBorderWidth()'],['../class_qwt_wheel.html#a50a2046f1151af7599aee3ad8f4e3ff0',1,'QwtWheel::setBorderWidth()']]], + ['setboundingrect',['setBoundingRect',['../class_qwt_point_mapper.html#a03910571df91575456e98134f6543650',1,'QwtPointMapper']]], + ['setbrush',['setBrush',['../class_qwt_interval_symbol.html#a2bf63ba6d8051ad890787b4762ae8b9a',1,'QwtIntervalSymbol::setBrush()'],['../class_qwt_plot_curve.html#adc52ea882ec1f994e2d2e23c7465b0c2',1,'QwtPlotCurve::setBrush()'],['../class_qwt_plot_histogram.html#a0bf40c3f9f9074cac5deecd4525583b3',1,'QwtPlotHistogram::setBrush()'],['../class_qwt_plot_interval_curve.html#a3102b513c27c54775fd371858aa31bba',1,'QwtPlotIntervalCurve::setBrush()'],['../class_qwt_plot_shape_item.html#ac73e7b2bc260f50dd997e078384a3d6b',1,'QwtPlotShapeItem::setBrush()'],['../class_qwt_plot_zone_item.html#a29d7add8c10cde3c5710354cd0d033a8',1,'QwtPlotZoneItem::setBrush()'],['../class_qwt_symbol.html#ae6aa7281d518bdd4adae8a37bbb5e09a',1,'QwtSymbol::setBrush()']]], + ['setcachepolicy',['setCachePolicy',['../class_qwt_plot_raster_item.html#a31f74199f7e333c2683b0f18289e4c7f',1,'QwtPlotRasterItem::setCachePolicy()'],['../class_qwt_symbol.html#a4c358a923bdcb122a59f21eb419f1bc6',1,'QwtSymbol::setCachePolicy()']]], + ['setcanvas',['setCanvas',['../class_qwt_plot.html#aea67c885034219789b360c0e624bfeaf',1,'QwtPlot']]], + ['setcanvasbackground',['setCanvasBackground',['../class_qwt_plot.html#adb0b2e68d86039f86e3240fb399fa0fe',1,'QwtPlot']]], + ['setcanvasmargin',['setCanvasMargin',['../class_qwt_plot_layout.html#a11667dad6675a7a58cc60ab1597b1203',1,'QwtPlotLayout']]], + ['setcanvasrect',['setCanvasRect',['../class_qwt_plot_layout.html#ab3d6614684b96a5879300476d2df8f8f',1,'QwtPlotLayout']]], + ['setchecked',['setChecked',['../class_qwt_legend_label.html#aec4affb8dbd281a7a8c5511c3ebf5ff8',1,'QwtLegendLabel']]], + ['setchunksize',['setChunkSize',['../class_qwt_weeding_curve_fitter.html#a9f17a819447cba0e733bd71d90ee2766',1,'QwtWeedingCurveFitter']]], + ['setclipping',['setClipping',['../class_qwt_plot_direct_painter.html#ac3d406aada74b7d9202c1017d8347708',1,'QwtPlotDirectPainter']]], + ['setclipregion',['setClipRegion',['../class_qwt_plot_direct_painter.html#a0c97174b06957f9b20ea295ff403a557',1,'QwtPlotDirectPainter']]], + ['setcolor',['setColor',['../class_qwt_alpha_color_map.html#a372ba8791102270991473897fb36a965',1,'QwtAlphaColorMap::setColor()'],['../class_qwt_symbol.html#a046443d76371c92add79e1f360bf3134',1,'QwtSymbol::setColor()'],['../class_qwt_text.html#ac7de5839a5c3b1ee367cfbd5691aa105',1,'QwtText::setColor()']]], + ['setcolorbarenabled',['setColorBarEnabled',['../class_qwt_scale_widget.html#aeb337b8e67fc00ca98bf39a6d70aea61',1,'QwtScaleWidget']]], + ['setcolorbarwidth',['setColorBarWidth',['../class_qwt_scale_widget.html#a76eb179267a572944d1ebdbf62c573f1',1,'QwtScaleWidget']]], + ['setcolorinterval',['setColorInterval',['../class_qwt_linear_color_map.html#abfae35c30755c0bbd1447342055e9a13',1,'QwtLinearColorMap']]], + ['setcolormap',['setColorMap',['../class_qwt_plot_spectro_curve.html#a67d046af16feeddc9bec08c698b46446',1,'QwtPlotSpectroCurve::setColorMap()'],['../class_qwt_plot_spectrogram.html#a55375b61c01962b06ad222c980ca2dcc',1,'QwtPlotSpectrogram::setColorMap()'],['../class_qwt_scale_widget.html#a3cfd919d042007accd3fdb3fcd75045c',1,'QwtScaleWidget::setColorMap()'],['../class_qwt_thermo.html#ad2ac0e2d496fd3d28f83f61728b83337',1,'QwtThermo::setColorMap()']]], + ['setcolorrange',['setColorRange',['../class_qwt_plot_spectro_curve.html#a133f4117e925a1faed456bd9524477e4',1,'QwtPlotSpectroCurve']]], + ['setcommands',['setCommands',['../class_qwt_graphic.html#a22cd36c524b08834bac74337aea9f7e8',1,'QwtGraphic']]], + ['setconrecflag',['setConrecFlag',['../class_qwt_plot_spectrogram.html#adcec06278d4ff4b8dd3a85e2ef188d7b',1,'QwtPlotSpectrogram']]], + ['setcontourlevels',['setContourLevels',['../class_qwt_plot_spectrogram.html#a5b7669a3c390e30f0c51e5c4689095d2',1,'QwtPlotSpectrogram']]], + ['setcurrenttime',['setCurrentTime',['../class_qwt_analog_clock.html#a1972a54ce59155ec7435103f11a775a7',1,'QwtAnalogClock']]], + ['setcursor',['setCursor',['../class_qwt_panner.html#ac8b0625fe155fff0132df85727f54a3e',1,'QwtPanner']]], + ['setcurveattribute',['setCurveAttribute',['../class_qwt_plot_curve.html#a6ac9243e280f96cd149102a91271a473',1,'QwtPlotCurve']]], + ['setcurvefitter',['setCurveFitter',['../class_qwt_plot_curve.html#ac15588c78d175906a30de501b4dd7957',1,'QwtPlotCurve']]], + ['setdata',['setData',['../class_qwt_legend_label.html#abd0140174ae2f0818cc926f68a9f27cc',1,'QwtLegendLabel::setData()'],['../class_qwt_plot_spectrogram.html#a5ee036cdf8dbaf5f8fd82a3fc47b023a',1,'QwtPlotSpectrogram::setData()'],['../class_qwt_series_store.html#add3ce83fe90e976b75a0ebaa79caee4c',1,'QwtSeriesStore::setData()']]], + ['setdateformat',['setDateFormat',['../class_qwt_date_scale_draw.html#ae8eb41024970bec16987d0c736ae890e',1,'QwtDateScaleDraw']]], + ['setdefaultcontourpen',['setDefaultContourPen',['../class_qwt_plot_spectrogram.html#af883cb50d74057994b3179ab0e262e64',1,'QwtPlotSpectrogram::setDefaultContourPen(const QColor &, qreal width=0.0, Qt::PenStyle=Qt::SolidLine)'],['../class_qwt_plot_spectrogram.html#afa3dea62acc8e5607e84bff8f50804b8',1,'QwtPlotSpectrogram::setDefaultContourPen(const QPen &)']]], + ['setdefaultitemmode',['setDefaultItemMode',['../class_qwt_legend.html#af977ff3e749f8281ee8ad4b926542b50',1,'QwtLegend']]], + ['setdefaultsize',['setDefaultSize',['../class_qwt_graphic.html#acba8d73bc62bd15c15491d4a6e739869',1,'QwtGraphic']]], + ['setdiscardflag',['setDiscardFlag',['../class_qwt_plot_renderer.html#a33439eb1407f3ba78fdd7b50461bbafc',1,'QwtPlotRenderer']]], + ['setdiscardflags',['setDiscardFlags',['../class_qwt_plot_renderer.html#ac618f4d6605c2484c03140323e1bd639',1,'QwtPlotRenderer']]], + ['setdisplaymode',['setDisplayMode',['../class_qwt_plot_spectrogram.html#a482a82bcf1b9f2a9a75f527063b394a2',1,'QwtPlotSpectrogram']]], + ['setdown',['setDown',['../class_qwt_legend_label.html#ad79fbc910254d1607deb331ade69db90',1,'QwtLegendLabel']]], + ['setenabled',['setEnabled',['../class_qwt_magnifier.html#a03d892c58039fc864a452b7c636a1df7',1,'QwtMagnifier::setEnabled()'],['../class_qwt_panner.html#a43e06c262c945fc7faeb729539bbde58',1,'QwtPanner::setEnabled()'],['../class_qwt_picker.html#aa590756369efae6ebf323302a0af5d36',1,'QwtPicker::setEnabled()'],['../class_qwt_plot_rescaler.html#a6f1c886d127ec4943552170dc63edf29',1,'QwtPlotRescaler::setEnabled()']]], + ['setexpandingdirection',['setExpandingDirection',['../class_qwt_plot_rescaler.html#aa2ecffbc14d951ab9f1809c14bc4e21b',1,'QwtPlotRescaler::setExpandingDirection(ExpandingDirection)'],['../class_qwt_plot_rescaler.html#a1681eb01b65b91e8b2583d87f890576f',1,'QwtPlotRescaler::setExpandingDirection(int axis, ExpandingDirection)']]], + ['setexpandingdirections',['setExpandingDirections',['../class_qwt_dyn_grid_layout.html#a56cd48dda979428402dd39d470674dee',1,'QwtDynGridLayout']]], + ['setfillbrush',['setFillBrush',['../class_qwt_thermo.html#af6ad0c2ca39afb30bb79a326484c9a21',1,'QwtThermo']]], + ['setfitmode',['setFitMode',['../class_qwt_spline_curve_fitter.html#a8381be57ee16b5a2bdacafbd5d71908b',1,'QwtSplineCurveFitter']]], + ['setflag',['setFlag',['../class_qwt_point_mapper.html#a6e03e14718d3d66a0f6a02fec7fcaeed',1,'QwtPointMapper']]], + ['setflags',['setFlags',['../class_qwt_point_mapper.html#ab556bd339cca487f25e2d894c51abe85',1,'QwtPointMapper']]], + ['setfocusindicator',['setFocusIndicator',['../class_qwt_plot_canvas.html#ae7330616dbb97128d01c5446ef0b006e',1,'QwtPlotCanvas']]], + ['setfont',['setFont',['../class_qwt_plot_legend_item.html#aa63eae9c2b05cb92186a40dde19fedec',1,'QwtPlotLegendItem::setFont()'],['../class_qwt_plot_scale_item.html#a8f2bc7a401bb3e1cf796ff024032e31d',1,'QwtPlotScaleItem::setFont()'],['../class_qwt_text.html#ad071f3c4fae4512a1cc71554d95eb69a',1,'QwtText::setFont()']]], + ['setfooter',['setFooter',['../class_qwt_plot.html#a30a098d942a1a9612b94e8fa5a3c9183',1,'QwtPlot::setFooter(const QString &)'],['../class_qwt_plot.html#ab5dd22281bfafd93b2855afa69b872f9',1,'QwtPlot::setFooter(const QwtText &t)']]], + ['setfooterrect',['setFooterRect',['../class_qwt_plot_layout.html#a60698767fe44c86ee4bcef27c1b48d26',1,'QwtPlotLayout']]], + ['setframeshadow',['setFrameShadow',['../class_qwt_dial.html#a272e17e53586a149df4dca437d5f9494',1,'QwtDial::setFrameShadow()'],['../class_qwt_plot_g_l_canvas.html#aee1da52928fa1fb765fa9c5794f40a4a',1,'QwtPlotGLCanvas::setFrameShadow()']]], + ['setframeshape',['setFrameShape',['../class_qwt_plot_g_l_canvas.html#a579e3f0891236317742cb58d9cacb6f5',1,'QwtPlotGLCanvas']]], + ['setframestyle',['setFrameStyle',['../class_qwt_column_symbol.html#a80826051d63efaf033868f05404ef565',1,'QwtColumnSymbol::setFrameStyle()'],['../class_qwt_plot_g_l_canvas.html#a9e1a08cbed3d6fb4ba89a31591265d0d',1,'QwtPlotGLCanvas::setFrameStyle()']]], + ['setgeometry',['setGeometry',['../class_qwt_dyn_grid_layout.html#afdf23bb94de5258f14fb077b39a64391',1,'QwtDynGridLayout']]], + ['setgraphic',['setGraphic',['../class_qwt_symbol.html#ab060930c548548b33441757dcc4b2f73',1,'QwtSymbol']]], + ['setgroove',['setGroove',['../class_qwt_slider.html#a4afc308735f59ffd51adb12d0a32bd81',1,'QwtSlider']]], + ['sethand',['setHand',['../class_qwt_analog_clock.html#a643101aafbe7a6fc91cb550203a7d3ee',1,'QwtAnalogClock']]], + ['sethandlesize',['setHandleSize',['../class_qwt_slider.html#a83ecd72c7ca593ebd361ad8912ac9d39',1,'QwtSlider']]], + ['seticon',['setIcon',['../class_qwt_legend_label.html#ae6113ca4894637f62f7e7df582672788',1,'QwtLegendLabel']]], + ['setincsteps',['setIncSteps',['../class_qwt_counter.html#a6aa68e7fc717fb0e2e48a978301c96eb',1,'QwtCounter']]], + ['setindent',['setIndent',['../class_qwt_text_label.html#aad25ab34c219f8d97ec7c39d064ed4a0',1,'QwtTextLabel']]], + ['setinterval',['setInterval',['../class_qwt_interval.html#a0373ca3cdb22ed507e4188fd06f68b17',1,'QwtInterval::setInterval()'],['../class_qwt_matrix_raster_data.html#a69db38d8f920edb9dc3f0953ca16db8f',1,'QwtMatrixRasterData::setInterval()'],['../class_qwt_plot_zone_item.html#acdf04297cd78f586e447318db60334e6',1,'QwtPlotZoneItem::setInterval(double min, double max)'],['../class_qwt_plot_zone_item.html#ad963f6a8301525c35add92c509fef44c',1,'QwtPlotZoneItem::setInterval(const QwtInterval &)'],['../class_qwt_synthetic_point_data.html#a1a0b2548b496affcf65272acd86c6700',1,'QwtSyntheticPointData::setInterval()'],['../class_qwt_raster_data.html#a14abf60573989e2a2c97e21a98aee558',1,'QwtRasterData::setInterval()'],['../class_qwt_sampling_thread.html#a36c56404ef0042cf52f1e592edf94f5d',1,'QwtSamplingThread::setInterval()'],['../class_qwt_scale_div.html#aa5c61a5fef5f83f2735e4e1b8e545f0b',1,'QwtScaleDiv::setInterval(double lowerBound, double upperBound)'],['../class_qwt_scale_div.html#ad335ddb86f5c635324cd0e8d00430ac4',1,'QwtScaleDiv::setInterval(const QwtInterval &)']]], + ['setintervalhint',['setIntervalHint',['../class_qwt_plot_rescaler.html#afefb0ec065ff855785d0198fc04a07d3',1,'QwtPlotRescaler']]], + ['setinverted',['setInverted',['../class_qwt_wheel.html#a66fec7ef7c7f889218f8ae0d0dcd90b5',1,'QwtWheel']]], + ['setinvertedcontrols',['setInvertedControls',['../class_qwt_abstract_slider.html#a8344b634faf639447c707ef665d2d324',1,'QwtAbstractSlider']]], + ['setitemattribute',['setItemAttribute',['../class_qwt_plot_item.html#a5a335be8ff488809a2cf7f4b734ad1b6',1,'QwtPlotItem']]], + ['setiteminterest',['setItemInterest',['../class_qwt_plot_item.html#ab65cbfe489ff73e32a919a0633298fb7',1,'QwtPlotItem']]], + ['setitemmargin',['setItemMargin',['../class_qwt_plot_legend_item.html#a85933f3f34ce2ed226217e35eb0341be',1,'QwtPlotLegendItem']]], + ['setitemmode',['setItemMode',['../class_qwt_legend_label.html#a2f469bcbc733332110d61d70f863df2e',1,'QwtLegendLabel']]], + ['setitemspacing',['setItemSpacing',['../class_qwt_plot_legend_item.html#a6f1f7d6e9161260ac703abc1118a63b9',1,'QwtPlotLegendItem']]], + ['setkeyfactor',['setKeyFactor',['../class_qwt_magnifier.html#ac079b44e124fdaba1d894ef519bc4e4f',1,'QwtMagnifier']]], + ['setkeypattern',['setKeyPattern',['../class_qwt_event_pattern.html#ae3543f014372987ed1aff4b2b880f631',1,'QwtEventPattern::setKeyPattern(KeyPatternCode, int keyCode, Qt::KeyboardModifiers modifierCodes=Qt::NoModifier)'],['../class_qwt_event_pattern.html#a73cf4257902b8a9d95aef60fabd3f747',1,'QwtEventPattern::setKeyPattern(const QVector< KeyPattern > &)']]], + ['setknobstyle',['setKnobStyle',['../class_qwt_knob.html#a3e69357a595407a73c23df7ad68bf117',1,'QwtKnob']]], + ['setknobwidth',['setKnobWidth',['../class_qwt_knob.html#a3c5fd9348d4fc0ffd39eb4d98daca831',1,'QwtKnob']]], + ['setlabel',['setLabel',['../class_qwt_plot_marker.html#ad90adc27ccd6a10a7d6d1bb4464bf7d1',1,'QwtPlotMarker']]], + ['setlabelalignment',['setLabelAlignment',['../class_qwt_plot_marker.html#ab0c88d103cc68093ac7469ad421105e0',1,'QwtPlotMarker::setLabelAlignment()'],['../class_qwt_scale_draw.html#a3df0a1fe4a498ef028a5348e54bfaa7f',1,'QwtScaleDraw::setLabelAlignment()'],['../class_qwt_scale_widget.html#a8d16473c34f8eaea7e6c457a4de25949',1,'QwtScaleWidget::setLabelAlignment()']]], + ['setlabelmap',['setLabelMap',['../class_qwt_compass_scale_draw.html#a55c807e3399832b53b4a9783780f9dd0',1,'QwtCompassScaleDraw']]], + ['setlabelorientation',['setLabelOrientation',['../class_qwt_plot_marker.html#a2bd6a30b0b04bd2c07505e1cfcdd2561',1,'QwtPlotMarker']]], + ['setlabelrotation',['setLabelRotation',['../class_qwt_scale_draw.html#abf5881339fddde65a00c1dd391023320',1,'QwtScaleDraw::setLabelRotation()'],['../class_qwt_scale_widget.html#aea277057b98a66ee8038f6a827e0f404',1,'QwtScaleWidget::setLabelRotation()']]], + ['setlayoutattribute',['setLayoutAttribute',['../class_qwt_text.html#a2b621d3104ead2185d2d939b1f5b9d68',1,'QwtText']]], + ['setlayoutflag',['setLayoutFlag',['../class_qwt_plot_renderer.html#ab06e26ebf2038b55e5f30bb14c90caec',1,'QwtPlotRenderer::setLayoutFlag()'],['../class_qwt_scale_widget.html#a6e3495e29ba5dfb4a75827ec1df03f6a',1,'QwtScaleWidget::setLayoutFlag()']]], + ['setlayoutflags',['setLayoutFlags',['../class_qwt_plot_renderer.html#a475ee59a0a3078380b6da31567bd0a14',1,'QwtPlotRenderer']]], + ['setlayouthint',['setLayoutHint',['../class_qwt_plot_abstract_bar_chart.html#aff6bb52dad207c8396b359a248a00359',1,'QwtPlotAbstractBarChart']]], + ['setlayoutpolicy',['setLayoutPolicy',['../class_qwt_plot_abstract_bar_chart.html#aabc7165ee75a38f444aa97e9b3dca16b',1,'QwtPlotAbstractBarChart']]], + ['setlegendattribute',['setLegendAttribute',['../class_qwt_plot_curve.html#a0b1b7816e822607eb16e6eb2fd7bfa5c',1,'QwtPlotCurve']]], + ['setlegendiconsize',['setLegendIconSize',['../class_qwt_plot_item.html#a0827dd69bf19ec0145b6cc6efad2c11b',1,'QwtPlotItem']]], + ['setlegendmode',['setLegendMode',['../class_qwt_plot_bar_chart.html#a1ba4d1347a2d493fe3859a1c0fac6a6d',1,'QwtPlotBarChart::setLegendMode()'],['../class_qwt_plot_shape_item.html#a2daf96fc886bb84e4a55913fc0c39906',1,'QwtPlotShapeItem::setLegendMode()']]], + ['setlegendposition',['setLegendPosition',['../class_qwt_plot_layout.html#a11c9695a68f95135841cb23212589f18',1,'QwtPlotLayout::setLegendPosition(QwtPlot::LegendPosition pos, double ratio)'],['../class_qwt_plot_layout.html#a001f1eca91803d0eaa9548efc50879eb',1,'QwtPlotLayout::setLegendPosition(QwtPlot::LegendPosition pos)']]], + ['setlegendratio',['setLegendRatio',['../class_qwt_plot_layout.html#aabe9f952046139667e055c661bee4dbb',1,'QwtPlotLayout']]], + ['setlegendrect',['setLegendRect',['../class_qwt_plot_layout.html#a5d5c1dacdfff8281acf0a909acaf866c',1,'QwtPlotLayout']]], + ['setlength',['setLength',['../class_qwt_scale_draw.html#a002528e391ce07246a5d6b05b4bac9d9',1,'QwtScaleDraw']]], + ['setlinepen',['setLinePen',['../class_qwt_plot_marker.html#a9414658a5980527326b87615d0fc1560',1,'QwtPlotMarker::setLinePen(const QColor &, qreal width=0.0, Qt::PenStyle=Qt::SolidLine)'],['../class_qwt_plot_marker.html#ac21d413827e42d8a9d5c35a373314195',1,'QwtPlotMarker::setLinePen(const QPen &p)']]], + ['setlinestyle',['setLineStyle',['../class_qwt_plot_marker.html#ae4533f9f9f5a7dfbc85729215d4b5932',1,'QwtPlotMarker']]], + ['setlinewidth',['setLineWidth',['../class_qwt_column_symbol.html#af9348444ae2c21d3bcaff3217fc694fc',1,'QwtColumnSymbol::setLineWidth()'],['../class_qwt_dial.html#a7946ca363a97fd28de4993a5caa54507',1,'QwtDial::setLineWidth()'],['../class_qwt_plot_g_l_canvas.html#a9b831253eef4f77a0f580468cb5e41d6',1,'QwtPlotGLCanvas::setLineWidth()']]], + ['setlowerbound',['setLowerBound',['../class_qwt_abstract_scale.html#aa1b73da4589370fc14fd2ef49b02d142',1,'QwtAbstractScale::setLowerBound()'],['../class_qwt_scale_div.html#a7d334df11402bf3a5146a8232144bdf8',1,'QwtScaleDiv::setLowerBound()']]], + ['setmajorpen',['setMajorPen',['../class_qwt_plot_grid.html#a08aa0669817c8a797e7c22731a02a66d',1,'QwtPlotGrid::setMajorPen(const QColor &, qreal width=0.0, Qt::PenStyle=Qt::SolidLine)'],['../class_qwt_plot_grid.html#a6fb1cc92165d29deebac5c68c4ab18dd',1,'QwtPlotGrid::setMajorPen(const QPen &)']]], + ['setmargin',['setMargin',['../class_qwt_plot_abstract_bar_chart.html#a97946d3da8e9fe2e49494a882651e4fd',1,'QwtPlotAbstractBarChart::setMargin()'],['../class_qwt_plot_legend_item.html#a503f19f2c8b2b7549a74ef887081bb8d',1,'QwtPlotLegendItem::setMargin()'],['../class_qwt_plot_text_label.html#a28bba339d2996ae2a8a426575820a816',1,'QwtPlotTextLabel::setMargin()'],['../class_qwt_scale_widget.html#a36d92ef63d996fe1fd58a46431924ab6',1,'QwtScaleWidget::setMargin()'],['../class_qwt_text_label.html#a833d27574b72bbc135f2972c72382eba',1,'QwtTextLabel::setMargin()']]], + ['setmargins',['setMargins',['../class_qwt_scale_engine.html#aed2ab1fc105a25fa97bbecf4b2f541a7',1,'QwtScaleEngine']]], + ['setmarkersize',['setMarkerSize',['../class_qwt_knob.html#a88e06ffddd31d3c0df04771793173353',1,'QwtKnob']]], + ['setmarkerstyle',['setMarkerStyle',['../class_qwt_knob.html#aaa80356a3e3d3703070a6f2b1802646c',1,'QwtKnob']]], + ['setmaskmode',['setMaskMode',['../class_qwt_widget_overlay.html#a56828c036263679fc95087bd87496df0',1,'QwtWidgetOverlay']]], + ['setmass',['setMass',['../class_qwt_wheel.html#a2af8b9b10ebff58b351027208c1e2b86',1,'QwtWheel']]], + ['setmaxcolumns',['setMaxColumns',['../class_qwt_dyn_grid_layout.html#a436bdce04ae004008acf2e1282941032',1,'QwtDynGridLayout::setMaxColumns()'],['../class_qwt_legend.html#adc427eb1a6ee6a3c17f7c1b8867b48b2',1,'QwtLegend::setMaxColumns()'],['../class_qwt_plot_legend_item.html#a8b6f1db48c05feb5d0f8525b41898be7',1,'QwtPlotLegendItem::setMaxColumns()']]], + ['setmaximum',['setMaximum',['../class_qwt_counter.html#a5ada3f5f233e93e79bfd84eb4dd99519',1,'QwtCounter::setMaximum()'],['../class_qwt_wheel.html#a9d3cb6dceb49c33935277603610b7934',1,'QwtWheel::setMaximum()']]], + ['setmaxscalearc',['setMaxScaleArc',['../class_qwt_dial.html#ad508f5c8bff6d0ae7023c834b7ed2ee6',1,'QwtDial']]], + ['setmaxstackdepth',['setMaxStackDepth',['../class_qwt_plot_zoomer.html#a3965591944793790407ba91d6de3a882',1,'QwtPlotZoomer']]], + ['setmaxsymbolwidth',['setMaxSymbolWidth',['../class_qwt_plot_trading_curve.html#af97b34d767ae5a89076ec79324739bc5',1,'QwtPlotTradingCurve']]], + ['setmaxvalue',['setMaxValue',['../class_qwt_interval.html#a3eeedaf35966d535670863cb0f97613a',1,'QwtInterval']]], + ['setmaxweeks',['setMaxWeeks',['../class_qwt_date_scale_engine.html#a0520441c198ee00c9d727340f639504b',1,'QwtDateScaleEngine']]], + ['setmidlinewidth',['setMidLineWidth',['../class_qwt_plot_g_l_canvas.html#a529cce50eea2c9a46fe9c41852f6cee3',1,'QwtPlotGLCanvas']]], + ['setminborderdist',['setMinBorderDist',['../class_qwt_scale_widget.html#a4299d99073231d977924c7e40ff9a6a9',1,'QwtScaleWidget']]], + ['setminimum',['setMinimum',['../class_qwt_counter.html#a511c9d97d31860d1720d8008fb8e2793',1,'QwtCounter::setMinimum()'],['../class_qwt_wheel.html#af9c58c5a8097f6e6f87bbaed48e34abb',1,'QwtWheel::setMinimum()']]], + ['setminimumextent',['setMinimumExtent',['../class_qwt_abstract_scale_draw.html#ac174255c334b995ca010a6964597d5f2',1,'QwtAbstractScaleDraw']]], + ['setminorpen',['setMinorPen',['../class_qwt_plot_grid.html#aeac99ccce0d170a9500f238cf0321669',1,'QwtPlotGrid::setMinorPen(const QColor &, qreal width=0.0, Qt::PenStyle=Qt::SolidLine)'],['../class_qwt_plot_grid.html#a6f184d76d56a470166cdc5141cd33014',1,'QwtPlotGrid::setMinorPen(const QPen &p)']]], + ['setminscalearc',['setMinScaleArc',['../class_qwt_dial.html#abed02cef48f26bafbf0a92c8c4e5abc9',1,'QwtDial']]], + ['setminsymbolwidth',['setMinSymbolWidth',['../class_qwt_plot_trading_curve.html#a8411a6cd96cf521e95a06792a0b99a52',1,'QwtPlotTradingCurve']]], + ['setminvalue',['setMinValue',['../class_qwt_interval.html#ab993dac41ca70402e0cb4f9f980d90f0',1,'QwtInterval']]], + ['setmode',['setMode',['../class_qwt_linear_color_map.html#afca7397fb6d07d05bab83e83e274a9c2',1,'QwtLinearColorMap::setMode()'],['../class_qwt_dial.html#a6b070ba6251fa40bbd876551413c5639',1,'QwtDial::setMode()'],['../class_qwt_null_paint_device.html#a8b159556695136a58eec6e78fd88957b',1,'QwtNullPaintDevice::setMode()']]], + ['setmousebutton',['setMouseButton',['../class_qwt_magnifier.html#ad814a5d9cb227d6fb56f8289dffe597c',1,'QwtMagnifier::setMouseButton()'],['../class_qwt_panner.html#a6f138454b2c1d7e814ae1975d6a7b8be',1,'QwtPanner::setMouseButton()']]], + ['setmousefactor',['setMouseFactor',['../class_qwt_magnifier.html#ada5dac479dc1e69c04760bb7dc197ac9',1,'QwtMagnifier']]], + ['setmousepattern',['setMousePattern',['../class_qwt_event_pattern.html#a0b786f31af2f8084ec361bc905beda3f',1,'QwtEventPattern::setMousePattern(MousePatternCode, Qt::MouseButton button, Qt::KeyboardModifiers=Qt::NoModifier)'],['../class_qwt_event_pattern.html#ad8e3b196c1026b038ccdf359f9a69d29',1,'QwtEventPattern::setMousePattern(const QVector< MousePattern > &)']]], + ['setneedle',['setNeedle',['../class_qwt_dial.html#ac91311f8777eabdbcf6384f308d34a0c',1,'QwtDial']]], + ['setnumbuttons',['setNumButtons',['../class_qwt_counter.html#ae9241fda2e375becdb484cc2cf7752f4',1,'QwtCounter']]], + ['setnumthornlevels',['setNumThornLevels',['../class_qwt_simple_compass_rose.html#ad91026da3b586a3193a264401221a275',1,'QwtSimpleCompassRose']]], + ['setnumthorns',['setNumThorns',['../class_qwt_simple_compass_rose.html#a3c86abb463eb4741d1776318d6fa557b',1,'QwtSimpleCompassRose']]], + ['setnumturns',['setNumTurns',['../class_qwt_knob.html#a8d69c0c3bc110eaa68cfda26d31a8e98',1,'QwtKnob']]], + ['setorientation',['setOrientation',['../class_qwt_plot_series_item.html#a9d131249079ec3bc503831349bd1a051',1,'QwtPlotSeriesItem::setOrientation()'],['../class_qwt_plot_zone_item.html#a0e957d092637846d8c7e7f6d1282e8ac',1,'QwtPlotZoneItem::setOrientation()'],['../class_qwt_slider.html#a3a5d51f56dee5e51dc37bb6f546b16b5',1,'QwtSlider::setOrientation()'],['../class_qwt_thermo.html#ae6c0926a7d4d163e08a0f940642b2ea9',1,'QwtThermo::setOrientation()'],['../class_qwt_wheel.html#acae74c8161fd1df728f26253dd1defa8',1,'QwtWheel::setOrientation()']]], + ['setorientations',['setOrientations',['../class_qwt_panner.html#aaa71a8b6f7f46ae8f5a8084094d7bd9a',1,'QwtPanner']]], + ['setorigin',['setOrigin',['../class_qwt_dial.html#a3f64c6fbac747f735e57c2073e93bc50',1,'QwtDial::setOrigin()'],['../class_qwt_thermo.html#a00f3853e0fabfe89cbf47d35c15b0aa4',1,'QwtThermo::setOrigin()']]], + ['setoriginmode',['setOriginMode',['../class_qwt_thermo.html#a95cca109a11bba24d8e8a422a3717ab0',1,'QwtThermo']]], + ['setpagestepcount',['setPageStepCount',['../class_qwt_wheel.html#adeecd6e684163c92143908240f89ce1e',1,'QwtWheel']]], + ['setpagesteps',['setPageSteps',['../class_qwt_abstract_slider.html#ae2af9e818c0e7fb39a3a07174e4dabf2',1,'QwtAbstractSlider']]], + ['setpaintattribute',['setPaintAttribute',['../class_qwt_plot_canvas.html#a7859beb87bcef4fd53f99e7c87104e27',1,'QwtPlotCanvas::setPaintAttribute()'],['../class_qwt_plot_curve.html#a7f9c70366415b5cb068af80be5bf3748',1,'QwtPlotCurve::setPaintAttribute()'],['../class_qwt_plot_interval_curve.html#ab962c4ad6896bc9d9450f6436f00bd81',1,'QwtPlotIntervalCurve::setPaintAttribute()'],['../class_qwt_plot_raster_item.html#a70d6b94821e5eafb29b1f045d1f3a2e6',1,'QwtPlotRasterItem::setPaintAttribute()'],['../class_qwt_plot_shape_item.html#acd66d009cd24cdfb418a5cc9486b5001',1,'QwtPlotShapeItem::setPaintAttribute()'],['../class_qwt_plot_spectro_curve.html#a3a2ddc8e46bc4414b5ce104e7c70f9b4',1,'QwtPlotSpectroCurve::setPaintAttribute()'],['../class_qwt_plot_trading_curve.html#ac0b8015b37a90a5ae995569158fae4e2',1,'QwtPlotTradingCurve::setPaintAttribute()'],['../class_qwt_text.html#aac80e3f05137173059b196206ceea9e8',1,'QwtText::setPaintAttribute()']]], + ['setpaintinterval',['setPaintInterval',['../class_qwt_scale_map.html#a994240e446986112f196a65657dc9755',1,'QwtScaleMap']]], + ['setpalette',['setPalette',['../class_qwt_column_symbol.html#a7d2b17a4b8aef7ae098fd42bc663527b',1,'QwtColumnSymbol::setPalette()'],['../class_qwt_compass_rose.html#ad69f887ed012d6bf6bf2ffeb133e26d5',1,'QwtCompassRose::setPalette()'],['../class_qwt_dial_needle.html#ae850883a64501136bca64d6ea2d084b9',1,'QwtDialNeedle::setPalette()'],['../class_qwt_plot_scale_item.html#aff7adf18c2a6f679227c0fdaa54f39f7',1,'QwtPlotScaleItem::setPalette()']]], + ['setpath',['setPath',['../class_qwt_symbol.html#a67a6005486f1ae864acfd4778e9282db',1,'QwtSymbol']]], + ['setpen',['setPen',['../class_qwt_interval_symbol.html#a9c3bbee5ea764f246e66bd7bc9382b79',1,'QwtIntervalSymbol::setPen(const QColor &, qreal width=0.0, Qt::PenStyle=Qt::SolidLine)'],['../class_qwt_interval_symbol.html#af40ddcffa51daf70c9f44f18b33a9ee2',1,'QwtIntervalSymbol::setPen(const QPen &)'],['../class_qwt_plot_curve.html#ae00bd073a2bcf7c3c810d70af1f86750',1,'QwtPlotCurve::setPen(const QColor &, qreal width=0.0, Qt::PenStyle=Qt::SolidLine)'],['../class_qwt_plot_curve.html#a08328abaf2c3b67e479d1e485d2d0c4d',1,'QwtPlotCurve::setPen(const QPen &)'],['../class_qwt_plot_grid.html#aa85de55eb3c28f15d4000a11d194b758',1,'QwtPlotGrid::setPen(const QColor &, qreal width=0.0, Qt::PenStyle=Qt::SolidLine)'],['../class_qwt_plot_grid.html#af80a13ae94179cf11967d0c39c85c3df',1,'QwtPlotGrid::setPen(const QPen &)'],['../class_qwt_plot_histogram.html#a57d55a701251e55d52a142d417f12d38',1,'QwtPlotHistogram::setPen(const QColor &, qreal width=0.0, Qt::PenStyle=Qt::SolidLine)'],['../class_qwt_plot_histogram.html#a230e53561dd2645ba34beaa89f4f4f61',1,'QwtPlotHistogram::setPen(const QPen &)'],['../class_qwt_plot_interval_curve.html#a41a5be16fecb66885f5dd08779fbee6b',1,'QwtPlotIntervalCurve::setPen(const QColor &, qreal width=0.0, Qt::PenStyle=Qt::SolidLine)'],['../class_qwt_plot_interval_curve.html#a706a3e88fbec2ab48a1a3e91c61cd223',1,'QwtPlotIntervalCurve::setPen(const QPen &)'],['../class_qwt_plot_shape_item.html#a7626d822bf3d7905a606a0e0c7079c11',1,'QwtPlotShapeItem::setPen(const QColor &, qreal width=0.0, Qt::PenStyle=Qt::SolidLine)'],['../class_qwt_plot_shape_item.html#a2ccab3059bb905fc2baee07cb69a262b',1,'QwtPlotShapeItem::setPen(const QPen &)'],['../class_qwt_plot_zone_item.html#a76a86eb41801930e5733bc509966ee4d',1,'QwtPlotZoneItem::setPen(const QColor &, qreal width=0.0, Qt::PenStyle=Qt::SolidLine)'],['../class_qwt_plot_zone_item.html#a29e88c47cdde211812df6d1073ab5c69',1,'QwtPlotZoneItem::setPen(const QPen &)'],['../class_qwt_symbol.html#a144ca0e312c4a1e64c2d9e161c01fb7c',1,'QwtSymbol::setPen(const QColor &, qreal width=0.0, Qt::PenStyle=Qt::SolidLine)'],['../class_qwt_symbol.html#ac4d75a6a9f9ae7f8f1002c465d5bbcb6',1,'QwtSymbol::setPen(const QPen &)']]], + ['setpenwidth',['setPenWidth',['../class_qwt_abstract_scale_draw.html#a098e1f813077c9bb0c5f83266035943a',1,'QwtAbstractScaleDraw::setPenWidth()'],['../class_qwt_plot_spectro_curve.html#ac3246da1a881538149addc2f22401578',1,'QwtPlotSpectroCurve::setPenWidth()']]], + ['setpinpoint',['setPinPoint',['../class_qwt_symbol.html#a78643c91d94690b91745f10f0601579e',1,'QwtSymbol']]], + ['setpinpointenabled',['setPinPointEnabled',['../class_qwt_symbol.html#a570e07b342701bf37794bf1191917005',1,'QwtSymbol']]], + ['setpipewidth',['setPipeWidth',['../class_qwt_thermo.html#a9d3a55a818ebf0dd508e20ca9eef224b',1,'QwtThermo']]], + ['setpixmap',['setPixmap',['../class_qwt_symbol.html#a69b548566bbd186992869b54777a0728',1,'QwtSymbol']]], + ['setplaintext',['setPlainText',['../class_qwt_text_label.html#a02113ab776a00ab8bbc83197ce49445e',1,'QwtTextLabel']]], + ['setplotlayout',['setPlotLayout',['../class_qwt_plot.html#a08e258f9ba498662a8be9a559c9c7e44',1,'QwtPlot']]], + ['setpoint',['setPoint',['../class_qwt_point_polar.html#a8cd4f93356a8a8c07400c3ad9ff1b560',1,'QwtPointPolar']]], + ['setpoints',['setPoints',['../class_qwt_spline.html#a6ed13410b1d5f6b33ba0e3c2b07932cf',1,'QwtSpline']]], + ['setpolygon',['setPolygon',['../class_qwt_plot_shape_item.html#a9810bd70cfdff88d14f88d9edf20c85b',1,'QwtPlotShapeItem']]], + ['setpolylinesplitting',['setPolylineSplitting',['../class_qwt_painter.html#a174bca411198c64dfff828a15d80ddfb',1,'QwtPainter']]], + ['setposition',['setPosition',['../class_qwt_plot_scale_item.html#a94536af312bb9d6de5bc7547c59e4faf',1,'QwtPlotScaleItem']]], + ['setradius',['setRadius',['../class_qwt_point_polar.html#a31ae2f4d6fad44f51ad5e7444a7f21fe',1,'QwtPointPolar::setRadius()'],['../class_qwt_round_scale_draw.html#a219e0db15594f297ae6ff769fd6c0485',1,'QwtRoundScaleDraw::setRadius()']]], + ['setrange',['setRange',['../class_qwt_counter.html#ad794d0d2589a38113933ae764e87ce22',1,'QwtCounter::setRange()'],['../class_qwt_wheel.html#a572f0bc2c5cd4c4f5e0b0f48c914a0e5',1,'QwtWheel::setRange()']]], + ['setrangeflags',['setRangeFlags',['../class_qwt_thermo.html#aa2ce6d6d20097fead0baca0ab31ef1b2',1,'QwtThermo']]], + ['setrawsamples',['setRawSamples',['../class_qwt_plot_curve.html#afd13c94e23520dacbc37b4d0fd036a8b',1,'QwtPlotCurve']]], + ['setreadonly',['setReadOnly',['../class_qwt_abstract_slider.html#a9cc63283a2d4f0bcbb67fd331629a318',1,'QwtAbstractSlider::setReadOnly()'],['../class_qwt_counter.html#ad34441cf06c68478b826e5b85fbb3ba7',1,'QwtCounter::setReadOnly()']]], + ['setrect',['setRect',['../class_qwt_pixel_matrix.html#ae8150f8d1f1922746172e9da1488e98b',1,'QwtPixelMatrix::setRect()'],['../class_qwt_plot_shape_item.html#a0a448e4354f67a3957b8123214cd75bb',1,'QwtPlotShapeItem::setRect()']]], + ['setrectofinterest',['setRectOfInterest',['../class_qwt_synthetic_point_data.html#a39cc8512e7d8beecde003f7781174b84',1,'QwtSyntheticPointData::setRectOfInterest()'],['../class_qwt_series_data.html#a391b4601a7454b2f9582fbc2662d108e',1,'QwtSeriesData::setRectOfInterest()'],['../class_qwt_abstract_series_store.html#a8a1cab11ce068f9c578a02d40e111b1a',1,'QwtAbstractSeriesStore::setRectOfInterest()'],['../class_qwt_series_store.html#a64971dd5eaed045b88ac06c9cd8fd6e9',1,'QwtSeriesStore::setRectOfInterest()']]], + ['setreference',['setReference',['../class_qwt_scale_engine.html#a89985ea69dbd858c8b9162ecd2be936e',1,'QwtScaleEngine']]], + ['setreferenceaxis',['setReferenceAxis',['../class_qwt_plot_rescaler.html#a6f13d60cc1e1071a6830ea30ccbcca37',1,'QwtPlotRescaler']]], + ['setrenderflags',['setRenderFlags',['../class_qwt_text.html#a2e71d427de766455323794f27d369a5d',1,'QwtText']]], + ['setrenderhint',['setRenderHint',['../class_qwt_graphic.html#a494b5de0452120653188828f6a1a6f55',1,'QwtGraphic::setRenderHint()'],['../class_qwt_plot_item.html#acd023c40f659c304ded324942865edc8',1,'QwtPlotItem::setRenderHint()']]], + ['setrendermode',['setRenderMode',['../class_qwt_widget_overlay.html#a80fd06e2111993848f45a21627ec09b4',1,'QwtWidgetOverlay']]], + ['setrenderthreadcount',['setRenderThreadCount',['../class_qwt_plot_item.html#a188ae18fbbce9adcf259ebe2f0de1f6b',1,'QwtPlotItem']]], + ['setrendertolerance',['setRenderTolerance',['../class_qwt_plot_shape_item.html#a76f617b8662ed118382d49c5201791e2',1,'QwtPlotShapeItem']]], + ['setresamplemode',['setResampleMode',['../class_qwt_matrix_raster_data.html#a038effe6e4be13725b7a8d35370595fd',1,'QwtMatrixRasterData']]], + ['setrescalepolicy',['setRescalePolicy',['../class_qwt_plot_rescaler.html#ae6b7df41b5387d0aed532559546e40b6',1,'QwtPlotRescaler']]], + ['setresizemode',['setResizeMode',['../class_qwt_picker.html#af85c8a3c709bd106d2b34b718a746e03',1,'QwtPicker']]], + ['setrose',['setRose',['../class_qwt_compass.html#a06456c0c52107bfa8b1d1267fba5b86f',1,'QwtCompass']]], + ['setroundingalignment',['setRoundingAlignment',['../class_qwt_painter.html#a49581f980f2c761852cda08502c96abb',1,'QwtPainter']]], + ['setrubberband',['setRubberBand',['../class_qwt_picker.html#a83096bad2662e02e4914a7b40241c351',1,'QwtPicker']]], + ['setrubberbandpen',['setRubberBandPen',['../class_qwt_picker.html#a13117b1929f1ca00a75002f7f4c612bc',1,'QwtPicker']]], + ['setsamples',['setSamples',['../class_qwt_plot_bar_chart.html#a669eb25dba458699465b317f2e96c1eb',1,'QwtPlotBarChart::setSamples(const QVector< QPointF > &)'],['../class_qwt_plot_bar_chart.html#a1b9e0f311a5570a93663994eb90b364f',1,'QwtPlotBarChart::setSamples(const QVector< double > &)'],['../class_qwt_plot_bar_chart.html#a257226bc375b036c7501d83e82360aef',1,'QwtPlotBarChart::setSamples(QwtSeriesData< QPointF > *series)'],['../class_qwt_plot_curve.html#aa51cd3fa00f2a046ca5a9889c5db2413',1,'QwtPlotCurve::setSamples(const double *xData, const double *yData, int size)'],['../class_qwt_plot_curve.html#a1e6e9a417479e372197b746538fae47c',1,'QwtPlotCurve::setSamples(const QVector< double > &xData, const QVector< double > &yData)'],['../class_qwt_plot_curve.html#a67b24f3663484ff5e973a288c6071b2a',1,'QwtPlotCurve::setSamples(const QVector< QPointF > &)'],['../class_qwt_plot_curve.html#afa11e2336827438b8f05dfae2d1668e6',1,'QwtPlotCurve::setSamples(QwtSeriesData< QPointF > *)'],['../class_qwt_plot_histogram.html#a6cc1fe6cd9f7dfc55a2bf5afd02ccce5',1,'QwtPlotHistogram::setSamples(const QVector< QwtIntervalSample > &)'],['../class_qwt_plot_histogram.html#a2207266b529e691a5d7a406643ff4fd5',1,'QwtPlotHistogram::setSamples(QwtSeriesData< QwtIntervalSample > *)'],['../class_qwt_plot_interval_curve.html#ac60fd04f3000b26ea82342065ba82afe',1,'QwtPlotIntervalCurve::setSamples(const QVector< QwtIntervalSample > &)'],['../class_qwt_plot_interval_curve.html#a7b7e1e4867c27f760c894b22e04d3ca8',1,'QwtPlotIntervalCurve::setSamples(QwtSeriesData< QwtIntervalSample > *)'],['../class_qwt_plot_multi_bar_chart.html#ad54633b91b7f602e376f3acb9e235e3c',1,'QwtPlotMultiBarChart::setSamples(const QVector< QwtSetSample > &)'],['../class_qwt_plot_multi_bar_chart.html#a95a17a8087bd87e5fea5ea4fbb910ecf',1,'QwtPlotMultiBarChart::setSamples(const QVector< QVector< double > > &)'],['../class_qwt_plot_multi_bar_chart.html#ab24b14666946b36e51bace7b5ecb0f81',1,'QwtPlotMultiBarChart::setSamples(QwtSeriesData< QwtSetSample > *)'],['../class_qwt_plot_spectro_curve.html#a668926af2266515a5d82911ac81262ca',1,'QwtPlotSpectroCurve::setSamples(const QVector< QwtPoint3D > &)'],['../class_qwt_plot_spectro_curve.html#a6374cf95ed6731d098328f2b8c317a8c',1,'QwtPlotSpectroCurve::setSamples(QwtSeriesData< QwtPoint3D > *)'],['../class_qwt_plot_trading_curve.html#a5675417b12acd80ff37ec66df2907c9f',1,'QwtPlotTradingCurve::setSamples(const QVector< QwtOHLCSample > &)'],['../class_qwt_plot_trading_curve.html#a715d423a080355522ab9a176be64b58e',1,'QwtPlotTradingCurve::setSamples(QwtSeriesData< QwtOHLCSample > *)'],['../class_qwt_array_series_data.html#a4afaaf2602be769f4bdcc8fda6b737cb',1,'QwtArraySeriesData::setSamples()']]], + ['setscale',['setScale',['../class_qwt_abstract_scale.html#ae9640e814b5029d7dd79cb3ba752102b',1,'QwtAbstractScale::setScale(double lowerBound, double upperBound)'],['../class_qwt_abstract_scale.html#ab54877c80f0b00fdb6e4745448aee128',1,'QwtAbstractScale::setScale(const QwtInterval &)'],['../class_qwt_abstract_scale.html#ad002e1a352ecf85c1a8595a138d42db7',1,'QwtAbstractScale::setScale(const QwtScaleDiv &)']]], + ['setscalearc',['setScaleArc',['../class_qwt_dial.html#a8abc41e15c62017d3c3ffb98acb9677f',1,'QwtDial']]], + ['setscalediv',['setScaleDiv',['../class_qwt_abstract_scale_draw.html#a4399aac94a294f5ed6c52114dde00d2f',1,'QwtAbstractScaleDraw::setScaleDiv()'],['../class_qwt_plot_scale_item.html#a99032adf91892f73d06a4810cd78d26b',1,'QwtPlotScaleItem::setScaleDiv()'],['../class_qwt_scale_widget.html#ac7959531c846b54d728b846635fc1406',1,'QwtScaleWidget::setScaleDiv()']]], + ['setscaledivfromaxis',['setScaleDivFromAxis',['../class_qwt_plot_scale_item.html#a0b4660ad3d3fcf1f1de711b075b073c6',1,'QwtPlotScaleItem']]], + ['setscaledraw',['setScaleDraw',['../class_qwt_dial.html#a2ed8a0642e1c612013ba812c7e037404',1,'QwtDial::setScaleDraw()'],['../class_qwt_knob.html#afea44f23da7f79a2b790178850c26edd',1,'QwtKnob::setScaleDraw()'],['../class_qwt_plot_scale_item.html#a0224f2720f3df4fc781d10560a4a1590',1,'QwtPlotScaleItem::setScaleDraw()'],['../class_qwt_scale_widget.html#af93459026340638898c11a799f4ae0c0',1,'QwtScaleWidget::setScaleDraw()'],['../class_qwt_slider.html#a9039a6d5d5bb7b21c312637cf40f8319',1,'QwtSlider::setScaleDraw()'],['../class_qwt_thermo.html#a8b5ab653b893e41116200570632ad1c3',1,'QwtThermo::setScaleDraw()']]], + ['setscaleengine',['setScaleEngine',['../class_qwt_abstract_scale.html#aa00f44140af3f2b7595cb6e23371198f',1,'QwtAbstractScale']]], + ['setscaleinterval',['setScaleInterval',['../class_qwt_scale_map.html#aaa33bc8e1aed7aa17d345053194e7094',1,'QwtScaleMap']]], + ['setscalemaxmajor',['setScaleMaxMajor',['../class_qwt_abstract_scale.html#a40fdb4572ad8fdec8b93766ff5f8eda8',1,'QwtAbstractScale']]], + ['setscalemaxminor',['setScaleMaxMinor',['../class_qwt_abstract_scale.html#a6520bb1e52571f865b21b3710786a4db',1,'QwtAbstractScale']]], + ['setscaleposition',['setScalePosition',['../class_qwt_slider.html#a530aa52c218ad27e8eebbecc7a27e25a',1,'QwtSlider::setScalePosition()'],['../class_qwt_thermo.html#a0306a248194d2f8c08ba90506122d6ca',1,'QwtThermo::setScalePosition()']]], + ['setscalerect',['setScaleRect',['../class_qwt_plot_layout.html#a842733777eb2b0bf2cacc4bb01c169c7',1,'QwtPlotLayout']]], + ['setscalestepsize',['setScaleStepSize',['../class_qwt_abstract_scale.html#aac745efd9414e529794e2189f7c535cb',1,'QwtAbstractScale']]], + ['setshape',['setShape',['../class_qwt_plot_shape_item.html#a0a8f3ed22324b23d04588cc749b74674',1,'QwtPlotShapeItem']]], + ['setshrinkfactor',['setShrinkFactor',['../class_qwt_simple_compass_rose.html#afaf84e19eb8eb2360306860b02d46cfc',1,'QwtSimpleCompassRose']]], + ['setsinglestep',['setSingleStep',['../class_qwt_counter.html#a7d1057b48f57d890bf5c60259b456350',1,'QwtCounter::setSingleStep()'],['../class_qwt_wheel.html#a63f5d4794cc1e624ab305083c7f4ed29',1,'QwtWheel::setSingleStep()']]], + ['setsinglesteps',['setSingleSteps',['../class_qwt_abstract_slider.html#ad470727c9fa3da9c50e26138cf03623e',1,'QwtAbstractSlider']]], + ['setsize',['setSize',['../class_qwt_synthetic_point_data.html#a321754c5acac77e0e5685968b1cdfdae',1,'QwtSyntheticPointData::setSize()'],['../class_qwt_symbol.html#a9fa391b34596f89256278254fa2ae3d8',1,'QwtSymbol::setSize(const QSize &)'],['../class_qwt_symbol.html#afd5587cd1752594954ca6146f643acfb',1,'QwtSymbol::setSize(int width, int height=-1)']]], + ['setspacing',['setSpacing',['../class_qwt_abstract_scale_draw.html#ae5bdaadb303510f7eb9dbec5c52f7a47',1,'QwtAbstractScaleDraw::setSpacing()'],['../class_qwt_legend_label.html#ad19d9ee759551f1fe785dc0ad806fd59',1,'QwtLegendLabel::setSpacing()'],['../class_qwt_plot_abstract_bar_chart.html#a0cb5bd5a653918b1513fa87ad75fa8b1',1,'QwtPlotAbstractBarChart::setSpacing()'],['../class_qwt_plot_layout.html#a6508553ec1d66bede49e7767526c3d03',1,'QwtPlotLayout::setSpacing()'],['../class_qwt_plot_legend_item.html#a9932f074e5861464a055fdce6394889c',1,'QwtPlotLegendItem::setSpacing()'],['../class_qwt_plot_marker.html#a856c9c5c6e22d86461ee6df101534831',1,'QwtPlotMarker::setSpacing()'],['../class_qwt_scale_widget.html#aaaad9f3d54fd329b16b738ca2df00ddf',1,'QwtScaleWidget::setSpacing()'],['../class_qwt_slider.html#a947f384faba10690bbff780bfe9e420f',1,'QwtSlider::setSpacing()'],['../class_qwt_thermo.html#a5d772862c760019a7797f45aa6b0690f',1,'QwtThermo::setSpacing()']]], + ['setspline',['setSpline',['../class_qwt_spline_curve_fitter.html#a7f819ad010b19d58179655e4ceb1c6f1',1,'QwtSplineCurveFitter']]], + ['setsplinesize',['setSplineSize',['../class_qwt_spline_curve_fitter.html#a8ecea80fb540b92cd22b6b0703636460',1,'QwtSplineCurveFitter']]], + ['setsplinetype',['setSplineType',['../class_qwt_spline.html#a222953661f01658a16042d587196aff8',1,'QwtSpline']]], + ['setstate',['setState',['../class_qwt_picker_machine.html#a569c426543e4a6aa15c221eb7c4910f0',1,'QwtPickerMachine']]], + ['setstatemachine',['setStateMachine',['../class_qwt_picker.html#a5ff72a5658631bcad3857ca5cfd3e6d9',1,'QwtPicker']]], + ['setstepalignment',['setStepAlignment',['../class_qwt_abstract_slider.html#a758fe135e2ee173c98dac70777e6dd4c',1,'QwtAbstractSlider::setStepAlignment()'],['../class_qwt_wheel.html#a5e5bf1d335538ff6971d48b914f26d51',1,'QwtWheel::setStepAlignment()']]], + ['setstepbutton1',['setStepButton1',['../class_qwt_counter.html#ae56a556a72955b6d10419f2c41779383',1,'QwtCounter']]], + ['setstepbutton2',['setStepButton2',['../class_qwt_counter.html#a0d764a96706593d8c8b51338e92abfcc',1,'QwtCounter']]], + ['setstepbutton3',['setStepButton3',['../class_qwt_counter.html#a8b55539578de083793b8310cb8909294',1,'QwtCounter']]], + ['setstyle',['setStyle',['../class_qwt_column_symbol.html#a3e2c72514fdc2e857ee2a34bc9f96e93',1,'QwtColumnSymbol::setStyle()'],['../class_qwt_interval_symbol.html#a24d64169355cc200a49af15c08fe93fc',1,'QwtIntervalSymbol::setStyle()'],['../class_qwt_plot_curve.html#a2de41014c2b87fd459d0c438a15dd33e',1,'QwtPlotCurve::setStyle()'],['../class_qwt_plot_histogram.html#a449af026888616f08b45e980d9da57fe',1,'QwtPlotHistogram::setStyle()'],['../class_qwt_plot_interval_curve.html#a74e6c2bf66e0436e827b5b017b943cad',1,'QwtPlotIntervalCurve::setStyle()'],['../class_qwt_plot_multi_bar_chart.html#a4daa7bdd0043eeafe5ab6e5db290181d',1,'QwtPlotMultiBarChart::setStyle()'],['../class_qwt_symbol.html#a4d3b9f3dd8c4ca034694b86372b74eb9',1,'QwtSymbol::setStyle()']]], + ['setsvgdocument',['setSvgDocument',['../class_qwt_symbol.html#a5e6a790b3133c878fde132a7fcf91475',1,'QwtSymbol']]], + ['setsymbol',['setSymbol',['../class_qwt_plot_bar_chart.html#a3e3c50c37484c3049dc9f433269e9a44',1,'QwtPlotBarChart::setSymbol()'],['../class_qwt_plot_curve.html#a413b1a18de12ece4dec5ae0738ecd03f',1,'QwtPlotCurve::setSymbol()'],['../class_qwt_plot_histogram.html#aa662f072a1758bfac9c0c86136ee27ad',1,'QwtPlotHistogram::setSymbol()'],['../class_qwt_plot_interval_curve.html#a4bc2408868638a41f5baa70b759283a2',1,'QwtPlotIntervalCurve::setSymbol()'],['../class_qwt_plot_marker.html#af44231c2b63bb277706e4f515297c7b1',1,'QwtPlotMarker::setSymbol()'],['../class_qwt_plot_multi_bar_chart.html#ad08e420c6c450672694e9bf253dc8b3b',1,'QwtPlotMultiBarChart::setSymbol()']]], + ['setsymbolbrush',['setSymbolBrush',['../class_qwt_plot_trading_curve.html#ac9ec84c2c75ff3a5597cd30aafbd76c2',1,'QwtPlotTradingCurve']]], + ['setsymbolextent',['setSymbolExtent',['../class_qwt_plot_trading_curve.html#af52822a65584bbd19255e6b99fe9e8b2',1,'QwtPlotTradingCurve']]], + ['setsymbolpen',['setSymbolPen',['../class_qwt_plot_trading_curve.html#aa15ee206779a9f3ff180113421bc4baa',1,'QwtPlotTradingCurve::setSymbolPen(const QColor &, qreal width=0.0, Qt::PenStyle=Qt::SolidLine)'],['../class_qwt_plot_trading_curve.html#aec9c455a3a877c36d408383e5b4700e0',1,'QwtPlotTradingCurve::setSymbolPen(const QPen &)']]], + ['setsymbolstyle',['setSymbolStyle',['../class_qwt_plot_trading_curve.html#a0c9928481272af1487baa4e0dcd47202',1,'QwtPlotTradingCurve']]], + ['settext',['setText',['../class_qwt_legend_label.html#a2498e1b2e1a17abf63fa4d94a08ebb95',1,'QwtLegendLabel::setText()'],['../class_qwt_plot_text_label.html#adce2e99ef7816ff544c5a5525bf05006',1,'QwtPlotTextLabel::setText()'],['../class_qwt_text.html#a9ba9caa82fcfbc4bfbf8ce20ccea981e',1,'QwtText::setText()'],['../class_qwt_text_label.html#ab300b9a0a6392e180f2caff41ba2b9b8',1,'QwtTextLabel::setText(const QString &, QwtText::TextFormat textFormat=QwtText::AutoText)'],['../class_qwt_text_label.html#ac43ba313b78dccf7aa7433f26059b2e2',1,'QwtTextLabel::setText(const QwtText &)']]], + ['settextengine',['setTextEngine',['../class_qwt_text.html#aef6a1e71b1feba3116ce69f6c9de70ad',1,'QwtText']]], + ['settextpen',['setTextPen',['../class_qwt_plot_legend_item.html#ae41a2af3f5353a01ed5d4dd786b84ef7',1,'QwtPlotLegendItem']]], + ['settickcount',['setTickCount',['../class_qwt_wheel.html#ae13600528c5b13a27b4220ac53b22153',1,'QwtWheel']]], + ['setticklength',['setTickLength',['../class_qwt_abstract_scale_draw.html#a7fed388e435aae791d61f48cc9ddf632',1,'QwtAbstractScaleDraw']]], + ['setticks',['setTicks',['../class_qwt_scale_div.html#af67401fd5d16138eddede3381c559964',1,'QwtScaleDiv']]], + ['settime',['setTime',['../class_qwt_analog_clock.html#aa99a628b290789583052bcec9163d95c',1,'QwtAnalogClock']]], + ['settimespec',['setTimeSpec',['../class_qwt_date_scale_draw.html#a278fdb655a98dda440ce5c0f8fc82c4e',1,'QwtDateScaleDraw::setTimeSpec()'],['../class_qwt_date_scale_engine.html#addbf8fdc00c2de0c6afe436ef25b3bef',1,'QwtDateScaleEngine::setTimeSpec()']]], + ['settitle',['setTitle',['../class_qwt_plot.html#a9a7f0b219b404e5bed5dfca26c5c06a7',1,'QwtPlot::setTitle(const QString &)'],['../class_qwt_plot.html#a032ced8ddfad7483a372214954203719',1,'QwtPlot::setTitle(const QwtText &t)'],['../class_qwt_plot_item.html#a1b74686181ab6dd5033917123c7db30f',1,'QwtPlotItem::setTitle(const QString &title)'],['../class_qwt_plot_item.html#a2db3214b23b78274fa6f8c0321a76839',1,'QwtPlotItem::setTitle(const QwtText &title)'],['../class_qwt_scale_widget.html#a28ad440a43978d2d50f19e17d0776403',1,'QwtScaleWidget::setTitle(const QString &title)'],['../class_qwt_scale_widget.html#a1451d5d2293358ba097a833a40015524',1,'QwtScaleWidget::setTitle(const QwtText &title)']]], + ['settitlerect',['setTitleRect',['../class_qwt_plot_layout.html#a82b49e88c7928224c4b0342b6302c086',1,'QwtPlotLayout']]], + ['settolerance',['setTolerance',['../class_qwt_weeding_curve_fitter.html#a62c303f6826fef2be7b7bbe82f530680',1,'QwtWeedingCurveFitter']]], + ['settotalangle',['setTotalAngle',['../class_qwt_knob.html#a82c6a859d63833894a6e66f0fdbf8f05',1,'QwtKnob::setTotalAngle()'],['../class_qwt_wheel.html#ae4e5dfd4c6683706716681cfd7e3d8bf',1,'QwtWheel::setTotalAngle()']]], + ['settotalsteps',['setTotalSteps',['../class_qwt_abstract_slider.html#a60eea9d9996c99abcb7d50f5ed2634f8',1,'QwtAbstractSlider']]], + ['settrackerfont',['setTrackerFont',['../class_qwt_picker.html#a9f54cce7d2e3f6e06351315bf655d5d9',1,'QwtPicker']]], + ['settrackermode',['setTrackerMode',['../class_qwt_picker.html#a94fc60c7223cdc470ae63156f6446d6f',1,'QwtPicker']]], + ['settrackerpen',['setTrackerPen',['../class_qwt_picker.html#af703bc51cda716e503cbd86731270e5b',1,'QwtPicker']]], + ['settracking',['setTracking',['../class_qwt_abstract_slider.html#a58d37e22b616787793a9e62ec7c5adc3',1,'QwtAbstractSlider::setTracking()'],['../class_qwt_wheel.html#a181ca4c891e763ebe30a0ed74a329c2b',1,'QwtWheel::setTracking()']]], + ['settransformation',['setTransformation',['../class_qwt_abstract_scale_draw.html#a732d0e49c9092c48893b4f71cc7357db',1,'QwtAbstractScaleDraw::setTransformation()'],['../class_qwt_scale_engine.html#ad063f4bb947996191be5c2a5fa0dbaf6',1,'QwtScaleEngine::setTransformation()'],['../class_qwt_scale_map.html#ad8e971dd4be07801f0adc99549153718',1,'QwtScaleMap::setTransformation()'],['../class_qwt_scale_widget.html#a749ea25d3e0ab0d7e6335982f3919055',1,'QwtScaleWidget::setTransformation()']]], + ['settrough',['setTrough',['../class_qwt_slider.html#ab4de4c649662416dc12c92c8e7cd0273',1,'QwtSlider']]], + ['setupdateinterval',['setUpdateInterval',['../class_qwt_slider.html#aeaab96d3554d509dbdd93a539617b9e9',1,'QwtSlider::setUpdateInterval()'],['../class_qwt_wheel.html#a5c234f68f0ff9906e2861e6fcd9dcc54',1,'QwtWheel::setUpdateInterval()']]], + ['setupperbound',['setUpperBound',['../class_qwt_abstract_scale.html#a1b2ea5c97eb19ccd55ec83713ab675fe',1,'QwtAbstractScale::setUpperBound()'],['../class_qwt_scale_div.html#a56545b9c67dcfb4bd0c7b5fc430ab70d',1,'QwtScaleDiv::setUpperBound()']]], + ['setutcoffset',['setUtcOffset',['../class_qwt_date_scale_draw.html#ab97b5fc37dc46dcf635a56e13d7b93a3',1,'QwtDateScaleDraw::setUtcOffset()'],['../class_qwt_date_scale_engine.html#a47dc382bbdf3e415b40543fc2736537f',1,'QwtDateScaleEngine::setUtcOffset()']]], + ['setvalid',['setValid',['../class_qwt_abstract_slider.html#a6b527ff0d2f96b85465fd73250d2e03f',1,'QwtAbstractSlider::setValid()'],['../class_qwt_counter.html#aa06625ab417f82fdc82790e3376af708',1,'QwtCounter::setValid()']]], + ['setvalue',['setValue',['../class_qwt_abstract_slider.html#ac3713f8989b647cb79f0a5894991e36a',1,'QwtAbstractSlider::setValue()'],['../class_qwt_counter.html#a429a2e986aa46c1231643df5d4c78970',1,'QwtCounter::setValue()'],['../class_qwt_legend_data.html#a1be4b4cf3c1df733744633ea6c02346a',1,'QwtLegendData::setValue()'],['../class_qwt_matrix_raster_data.html#a4601944bceabd921cdaa544180576274',1,'QwtMatrixRasterData::setValue()'],['../class_qwt_plot_marker.html#ad3a480c64192dabffd02bf5db31f917c',1,'QwtPlotMarker::setValue(double, double)'],['../class_qwt_plot_marker.html#a290374903ca168104dbce7e2058774c3',1,'QwtPlotMarker::setValue(const QPointF &)'],['../class_qwt_thermo.html#ad54ebf4761c12f948d09cd45a26d1fd4',1,'QwtThermo::setValue()'],['../class_qwt_wheel.html#a6f46526b283b7fde127bc595c96db7e8',1,'QwtWheel::setValue()']]], + ['setvaluematrix',['setValueMatrix',['../class_qwt_matrix_raster_data.html#a578ffc26f04a9099e2b31fc2d9360adb',1,'QwtMatrixRasterData']]], + ['setvalues',['setValues',['../class_qwt_legend_data.html#a68c3bc398c541f345a12fa9321ad52ed',1,'QwtLegendData']]], + ['setviewangle',['setViewAngle',['../class_qwt_wheel.html#a7f15b6aef98ad6b52bebc749381bc753',1,'QwtWheel']]], + ['setvisible',['setVisible',['../class_qwt_plot_item.html#a5f0eeb2b72207fd8d33a95b0565657a1',1,'QwtPlotItem']]], + ['setweek0type',['setWeek0Type',['../class_qwt_date_scale_draw.html#acd5e9ce4e1e98e849d6002d22b2f7198',1,'QwtDateScaleDraw::setWeek0Type()'],['../class_qwt_date_scale_engine.html#a5e11c5e7c4f58063ded8f6d35d2816f4',1,'QwtDateScaleEngine::setWeek0Type()']]], + ['setwheelborderwidth',['setWheelBorderWidth',['../class_qwt_wheel.html#a4aa70134746908cef687e3c1bb7aa60c',1,'QwtWheel']]], + ['setwheelfactor',['setWheelFactor',['../class_qwt_magnifier.html#ae3a33ab8776ed2122fecc821a32bb36a',1,'QwtMagnifier']]], + ['setwheelmodifiers',['setWheelModifiers',['../class_qwt_magnifier.html#aadfc853d8619b43b21564d8d5fe50093',1,'QwtMagnifier']]], + ['setwheelwidth',['setWheelWidth',['../class_qwt_wheel.html#ac434254039981344ccca22c76bce4f38',1,'QwtWheel']]], + ['setwidth',['setWidth',['../class_qwt_simple_compass_rose.html#ae4067a436f45d2f2ca23d8233539566b',1,'QwtSimpleCompassRose::setWidth()'],['../class_qwt_dial_simple_needle.html#ad7672543371e38c864e44d9240271c22',1,'QwtDialSimpleNeedle::setWidth()'],['../class_qwt_interval_symbol.html#adfacdeb67c9e6d194df4d3d627de23eb',1,'QwtIntervalSymbol::setWidth()']]], + ['setwrapping',['setWrapping',['../class_qwt_abstract_slider.html#ada27ca51ab146554b981fafed38e41e0',1,'QwtAbstractSlider::setWrapping()'],['../class_qwt_counter.html#a8fc7d115682f295dfcc64fa8312ccdeb',1,'QwtCounter::setWrapping()'],['../class_qwt_wheel.html#a4ee4c2bcd6536f7639b5e275ab3235c2',1,'QwtWheel::setWrapping()']]], + ['setx',['setX',['../class_qwt_point3_d.html#afe85919187fd62bc3db082d1e2b17bac',1,'QwtPoint3D']]], + ['setxaxis',['setXAxis',['../class_qwt_plot_item.html#a81d3dd7feaadda4b0dbb8c13642046cf',1,'QwtPlotItem']]], + ['setxdiv',['setXDiv',['../class_qwt_plot_grid.html#aeeb88397c2aaf5e763d57c898a2fcd13',1,'QwtPlotGrid']]], + ['setxvalue',['setXValue',['../class_qwt_plot_marker.html#a0d53b0e0ed8b48478c02a0ecaf5852b2',1,'QwtPlotMarker']]], + ['sety',['setY',['../class_qwt_point3_d.html#a986ba13d44e6960b4fb72795be4ff66a',1,'QwtPoint3D']]], + ['setyaxis',['setYAxis',['../class_qwt_plot_item.html#aa92dad876d76ce136925d5ae8f01db9a',1,'QwtPlotItem']]], + ['setydiv',['setYDiv',['../class_qwt_plot_grid.html#a9eb130275560bdaa65551e2f69232b72',1,'QwtPlotGrid']]], + ['setyvalue',['setYValue',['../class_qwt_plot_marker.html#a47d8e3c0708ad02a9c7cc6aaf985e278',1,'QwtPlotMarker']]], + ['setz',['setZ',['../class_qwt_plot_item.html#a57d90e4146133b59d589c71b3a643e82',1,'QwtPlotItem::setZ()'],['../class_qwt_point3_d.html#ae4bed4f5b955843dcf92302b16799e8b',1,'QwtPoint3D::setZ()']]], + ['setzoombase',['setZoomBase',['../class_qwt_plot_zoomer.html#a7ee4f2a0606df6e85258c52f0b5c7bc2',1,'QwtPlotZoomer::setZoomBase(bool doReplot=true)'],['../class_qwt_plot_zoomer.html#a4376cd882cf72e1794cbbe7264ee96fb',1,'QwtPlotZoomer::setZoomBase(const QRectF &)']]], + ['setzoominkey',['setZoomInKey',['../class_qwt_magnifier.html#a004d9e770ed745bbcb5dcdb7a7ecc0a9',1,'QwtMagnifier']]], + ['setzoomoutkey',['setZoomOutKey',['../class_qwt_magnifier.html#a095a8cc622175fafc5b3cc6eb274af07',1,'QwtMagnifier']]], + ['setzoomstack',['setZoomStack',['../class_qwt_plot_zoomer.html#afc12a6e757768a71d1c74b90931bfc70',1,'QwtPlotZoomer']]], + ['shape',['shape',['../class_qwt_plot_shape_item.html#ab14eeb97e17da5ee1f458ef9c74afb20',1,'QwtPlotShapeItem']]], + ['show',['show',['../class_qwt_plot_item.html#a93a50fb9c86bc66617e28315e02281c3',1,'QwtPlotItem']]], + ['shrinkfactor',['shrinkFactor',['../class_qwt_simple_compass_rose.html#a49ac7941c4a09f5a33e660b130d7bc2e',1,'QwtSimpleCompassRose']]], + ['singlestep',['singleStep',['../class_qwt_counter.html#a0057de1b365b6f18309c29c7b210cdd1',1,'QwtCounter::singleStep()'],['../class_qwt_wheel.html#a153e7629785d63a52b089c528a008578',1,'QwtWheel::singleStep()']]], + ['singlesteps',['singleSteps',['../class_qwt_abstract_slider.html#a749174444d3e63c232492edba727adfe',1,'QwtAbstractSlider']]], + ['size',['size',['../class_qwt_point_array_data.html#a2222b2ad6346dc6357a412fc50ec8f56',1,'QwtPointArrayData::size()'],['../class_qwt_c_pointer_data.html#a780b9ae434856509cef9bbe954f03a3e',1,'QwtCPointerData::size()'],['../class_qwt_synthetic_point_data.html#a61b2cc26e1b5fa4a64e29273cf3e1599',1,'QwtSyntheticPointData::size()'],['../class_qwt_series_data.html#a3cfe5b26fc55a887ac85b0103ae80a3e',1,'QwtSeriesData::size()'],['../class_qwt_array_series_data.html#a52c123dcc321a03ccd18c2c138318025',1,'QwtArraySeriesData::size()'],['../class_qwt_symbol.html#a3aba8eed9fcd85f4a4799e63543a2398',1,'QwtSymbol::size()']]], + ['sizehint',['sizeHint',['../class_qwt_arrow_button.html#a180ca16baa83c02e8dca4ffbe3dba2e8',1,'QwtArrowButton::sizeHint()'],['../class_qwt_counter.html#a9ccdfd602ccd5ecd8595172cd22b2b27',1,'QwtCounter::sizeHint()'],['../class_qwt_dial.html#a7d79a5c1cbaadb1ded9306044fa2a4a1',1,'QwtDial::sizeHint()'],['../class_qwt_dyn_grid_layout.html#afed46e3a8e1b6e67dcf62eca0bc948d6',1,'QwtDynGridLayout::sizeHint()'],['../class_qwt_knob.html#ac5f92af50fdcbf0b501f18efd07294fd',1,'QwtKnob::sizeHint()'],['../class_qwt_legend.html#a2517a7d9d78ab7a3892125ecf755f33f',1,'QwtLegend::sizeHint()'],['../class_qwt_legend_label.html#a58cf61eb9e87fe7a36266e687fe721eb',1,'QwtLegendLabel::sizeHint()'],['../class_qwt_plot.html#a8e25bdd9b085344227a7f9e218ce557c',1,'QwtPlot::sizeHint()'],['../class_qwt_scale_widget.html#a5ed815b5ac0ed7d43ab923fcd1f5da3d',1,'QwtScaleWidget::sizeHint()'],['../class_qwt_slider.html#a31c4c636f8b762e390beaf501bedcffc',1,'QwtSlider::sizeHint()'],['../class_qwt_text_label.html#a0217bc022e6f3b2f22819c84d5867ae7',1,'QwtTextLabel::sizeHint()'],['../class_qwt_thermo.html#abdb43977b3628a0b42039bef071c81cd',1,'QwtThermo::sizeHint()'],['../class_qwt_wheel.html#a77404d4e604a196bd4e809ec7d9f2076',1,'QwtWheel::sizeHint()']]], + ['sizemetrics',['sizeMetrics',['../class_qwt_graphic.html#a8996e22267dc37c9bc18dd9392ec5916',1,'QwtGraphic::sizeMetrics()'],['../class_qwt_null_paint_device.html#ab95def8c9d76d4fa6142458fd5ea4970',1,'QwtNullPaintDevice::sizeMetrics()']]], + ['sliderchange',['sliderChange',['../class_qwt_abstract_slider.html#a36ac20a000d40b2fddf5c144d1133f77',1,'QwtAbstractSlider::sliderChange()'],['../class_qwt_dial.html#a9e9e5a3aac1bc3752de8ab0a7ef71be2',1,'QwtDial::sliderChange()']]], + ['slidermoved',['sliderMoved',['../class_qwt_abstract_slider.html#ae59671d27931b545073e599a10967452',1,'QwtAbstractSlider']]], + ['sliderpressed',['sliderPressed',['../class_qwt_abstract_slider.html#afd92a0c79c113b3c5e9952d12cff80f5',1,'QwtAbstractSlider']]], + ['sliderrect',['sliderRect',['../class_qwt_slider.html#af5355e9015fc49a3d978603cb8b9bbee',1,'QwtSlider']]], + ['sliderreleased',['sliderReleased',['../class_qwt_abstract_slider.html#ab94184da7a029a5f586671251ff380ea',1,'QwtAbstractSlider']]], + ['spacing',['spacing',['../class_qwt_abstract_scale_draw.html#a93561d85e879402086f2607e45e89cc2',1,'QwtAbstractScaleDraw::spacing()'],['../class_qwt_legend_label.html#aa976458d79004b7b29ebea3cf0a069de',1,'QwtLegendLabel::spacing()'],['../class_qwt_plot_abstract_bar_chart.html#a0a2e625021bba3b9224b410281fddcf9',1,'QwtPlotAbstractBarChart::spacing()'],['../class_qwt_plot_layout.html#ae93650a8f3208578f87348334b77a282',1,'QwtPlotLayout::spacing()'],['../class_qwt_plot_legend_item.html#a4906d4e498c3b537a6354e2a1293a9c9',1,'QwtPlotLegendItem::spacing()'],['../class_qwt_plot_marker.html#ad7655fdd7089b6c8058c238f1462f298',1,'QwtPlotMarker::spacing()'],['../class_qwt_scale_widget.html#a1bdb5b6fa77a4535087f1c672ee394ce',1,'QwtScaleWidget::spacing()'],['../class_qwt_slider.html#aafa34f60f76fb7786d992cc90116e6b6',1,'QwtSlider::spacing()'],['../class_qwt_thermo.html#a16ca09c525bb05c7316ae6accb7aad79',1,'QwtThermo::spacing()']]], + ['specialsymbol',['specialSymbol',['../class_qwt_plot_bar_chart.html#a4a1e222c476d5909b7479bad4197f62b',1,'QwtPlotBarChart::specialSymbol()'],['../class_qwt_plot_multi_bar_chart.html#af94cc6845797ada8a9be828401375e39',1,'QwtPlotMultiBarChart::specialSymbol()']]], + ['spline',['spline',['../class_qwt_spline_curve_fitter.html#a7e5211e9e84df705d8bbbc7a57fbfa6d',1,'QwtSplineCurveFitter::spline() const '],['../class_qwt_spline_curve_fitter.html#ac501260a25953e1ded6bbc84c3250fa8',1,'QwtSplineCurveFitter::spline()']]], + ['splinesize',['splineSize',['../class_qwt_spline_curve_fitter.html#a09e5cb291c90db0aa8e6e51377bc9308',1,'QwtSplineCurveFitter']]], + ['splinetype',['splineType',['../class_qwt_spline.html#a36442cbb781422e5b97ae242265dd4b4',1,'QwtSpline']]], + ['start',['start',['../class_qwt_system_clock.html#a3408bd55b49582f7847865aacc7beb37',1,'QwtSystemClock']]], + ['startborderdist',['startBorderDist',['../class_qwt_scale_widget.html#ab82bb290d685dfaec3894f5892f04ef9',1,'QwtScaleWidget']]], + ['state',['state',['../class_qwt_picker_machine.html#a9060b1036ef5125968fc7030681d73c0',1,'QwtPickerMachine']]], + ['statedata',['stateData',['../class_qwt_painter_command.html#ae801f205610698ebc9f704cdcedafb68',1,'QwtPainterCommand::stateData()'],['../class_qwt_painter_command.html#a12f846b9964f499a568d0b61876173ec',1,'QwtPainterCommand::stateData() const ']]], + ['statemachine',['stateMachine',['../class_qwt_picker.html#afec1e9a7c913893f49df1dccf150e0ec',1,'QwtPicker::stateMachine() const '],['../class_qwt_picker.html#afeb497069fb64ef3948f5dae605268ae',1,'QwtPicker::stateMachine()']]], + ['stepalignment',['stepAlignment',['../class_qwt_abstract_slider.html#a3c30c64a3bfc03a12131476e034e5a2c',1,'QwtAbstractSlider::stepAlignment()'],['../class_qwt_wheel.html#a3738470b6ea312ee47ba53ddfbdf355c',1,'QwtWheel::stepAlignment()']]], + ['stepbutton1',['stepButton1',['../class_qwt_counter.html#a8e0b28f111c45b3a2241fd8889bc8bce',1,'QwtCounter']]], + ['stepbutton2',['stepButton2',['../class_qwt_counter.html#a7d99de95e1c05e4994413e6d8cd641fe',1,'QwtCounter']]], + ['stepbutton3',['stepButton3',['../class_qwt_counter.html#abc6eb2073cc7d7b5f1d7e4c6c7b205c9',1,'QwtCounter']]], + ['stop',['stop',['../class_qwt_sampling_thread.html#ac644ff417342617a39dbd86e50d09132',1,'QwtSamplingThread']]], + ['stopflying',['stopFlying',['../class_qwt_wheel.html#af46272363dc06755e2d4c7e448664ff8',1,'QwtWheel']]], + ['stretchgrid',['stretchGrid',['../class_qwt_dyn_grid_layout.html#aba94fa07d16ec2d36589b777dc853605',1,'QwtDynGridLayout']]], + ['stretchselection',['stretchSelection',['../class_qwt_picker.html#a24b0e4bcf6a9b7f41c81ea19305105a8',1,'QwtPicker']]], + ['strip',['strip',['../class_qwt_scale_engine.html#ab2b5b3c6081e1d0007f904dbc3f9f7f1',1,'QwtScaleEngine']]], + ['style',['style',['../class_qwt_column_symbol.html#a3cf6f4e696a6df0936160d6bdb8e6b25',1,'QwtColumnSymbol::style()'],['../class_qwt_interval_symbol.html#a301b219e05ee54fd49dafd969bc4ddd7',1,'QwtIntervalSymbol::style()'],['../class_qwt_plot_curve.html#a2df43bdea2a17118c9114d6fa774e598',1,'QwtPlotCurve::style()'],['../class_qwt_plot_histogram.html#a00915a951baa4fb251f5614cb0dd8aa9',1,'QwtPlotHistogram::style()'],['../class_qwt_plot_interval_curve.html#ada1fea7fe0359c1bc175b3a2baf10c87',1,'QwtPlotIntervalCurve::style()'],['../class_qwt_plot_multi_bar_chart.html#a8420d5b608303727564539e3b08ef7cc',1,'QwtPlotMultiBarChart::style()'],['../class_qwt_symbol.html#a5e5811e1a1621e617716a2a62578b507',1,'QwtSymbol::style()']]], + ['swapdata',['swapData',['../class_qwt_series_store.html#a5f47997d53d580e6a12a6ca61b7225b0',1,'QwtSeriesStore']]], + ['symbol',['symbol',['../class_qwt_plot_bar_chart.html#abf3aabedfb304ef4154dec6918cb9ff7',1,'QwtPlotBarChart::symbol()'],['../class_qwt_plot_curve.html#a38e6e66301d602e80bf751f43820c080',1,'QwtPlotCurve::symbol()'],['../class_qwt_plot_histogram.html#a5815e991c891210789fef0295047f790',1,'QwtPlotHistogram::symbol()'],['../class_qwt_plot_interval_curve.html#a178654ee5b40932b06bbfcf5cb96ca7e',1,'QwtPlotIntervalCurve::symbol()'],['../class_qwt_plot_marker.html#ac3f7385b517bb8d7f0f572bfdecbc222',1,'QwtPlotMarker::symbol()'],['../class_qwt_plot_multi_bar_chart.html#a331b06acee387cd152a6ce440e7aeaca',1,'QwtPlotMultiBarChart::symbol(int barIndex) const '],['../class_qwt_plot_multi_bar_chart.html#a3e245523004a91c7a9db4c2089c3f0f6',1,'QwtPlotMultiBarChart::symbol(int barIndex)']]], + ['symbolbrush',['symbolBrush',['../class_qwt_plot_trading_curve.html#a55377e71da70b9040bc0b7a410c6aa97',1,'QwtPlotTradingCurve']]], + ['symbolextent',['symbolExtent',['../class_qwt_plot_trading_curve.html#abe2c4f7a1fd7b6643e7a4065313b0ff4',1,'QwtPlotTradingCurve']]], + ['symbolpen',['symbolPen',['../class_qwt_plot_trading_curve.html#ae317bb564cbc142899d6832a34b6d225',1,'QwtPlotTradingCurve']]], + ['symbolstyle',['symbolStyle',['../class_qwt_plot_trading_curve.html#a0b4e200a5ff4f3c05bd0be6487f8ee27',1,'QwtPlotTradingCurve']]], + ['symmetrize',['symmetrize',['../class_qwt_interval.html#a86dae3b22782b8548fd4e2c625bf1830',1,'QwtInterval']]], + ['syncscale',['syncScale',['../class_qwt_plot_rescaler.html#a1a83473ef31ff45d1595eca80c2d3b1d',1,'QwtPlotRescaler']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/functions_74.html b/ThirdParty/Qwt/doc/html/search/functions_74.html new file mode 100644 index 0000000000..1605901ee1 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/functions_74.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/functions_74.js b/ThirdParty/Qwt/doc/html/search/functions_74.js new file mode 100644 index 0000000000..dd17d6137b --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/functions_74.js @@ -0,0 +1,61 @@ +var searchData= +[ + ['takeat',['takeAt',['../class_qwt_dyn_grid_layout.html#ad16c097bc1563eb1587e12789498bac9',1,'QwtDynGridLayout']]], + ['testandsetpixel',['testAndSetPixel',['../class_qwt_pixel_matrix.html#a51c2ecd161c0c93dccb62fcf640ff280',1,'QwtPixelMatrix']]], + ['testattribute',['testAttribute',['../class_qwt_plot_direct_painter.html#ad48b7706cbba44f91fb9f770e10bcc93',1,'QwtPlotDirectPainter::testAttribute()'],['../class_qwt_scale_engine.html#ab43cac5ff8843531bbb02b4401e8fb62',1,'QwtScaleEngine::testAttribute()']]], + ['testconrecflag',['testConrecFlag',['../class_qwt_plot_spectrogram.html#a00e9f22015d793458ceb36c691b1b154',1,'QwtPlotSpectrogram']]], + ['testcurveattribute',['testCurveAttribute',['../class_qwt_plot_curve.html#a0dc5e6af9ec33a1b54e3c3041c00b939',1,'QwtPlotCurve']]], + ['testdiscardflag',['testDiscardFlag',['../class_qwt_plot_renderer.html#a04fe5d9c1d81b6bfc307f8a90b4ff5c3',1,'QwtPlotRenderer']]], + ['testdisplaymode',['testDisplayMode',['../class_qwt_plot_spectrogram.html#a292ec25eb59adaedf90eef45e98f4d38',1,'QwtPlotSpectrogram']]], + ['testflag',['testFlag',['../class_qwt_point_mapper.html#acadf83f0fdb3123813b5c1eac20c3ad5',1,'QwtPointMapper']]], + ['testitemattribute',['testItemAttribute',['../class_qwt_plot_item.html#aef70936d34ef661876692e6a06d4a464',1,'QwtPlotItem']]], + ['testiteminterest',['testItemInterest',['../class_qwt_plot_item.html#a788e1dcce2faadd0bf2fd6f453ec55d0',1,'QwtPlotItem']]], + ['testlayoutattribute',['testLayoutAttribute',['../class_qwt_text.html#a5b7bddee1d80139b93d60a0a3a044944',1,'QwtText']]], + ['testlayoutflag',['testLayoutFlag',['../class_qwt_plot_renderer.html#a4e58ce0389b485c0d1014a13c2bdd0f7',1,'QwtPlotRenderer::testLayoutFlag()'],['../class_qwt_scale_widget.html#a14109672bbee79337864ae4c6525994f',1,'QwtScaleWidget::testLayoutFlag()']]], + ['testlegendattribute',['testLegendAttribute',['../class_qwt_plot_curve.html#a7ca93712e476c18995e396425e451039',1,'QwtPlotCurve']]], + ['testpaintattribute',['testPaintAttribute',['../class_qwt_plot_canvas.html#a804f78518b0ba72b11ba996fd2457fb1',1,'QwtPlotCanvas::testPaintAttribute()'],['../class_qwt_plot_curve.html#ad262cf6b8448d3cb693cbceecc6d8481',1,'QwtPlotCurve::testPaintAttribute()'],['../class_qwt_plot_interval_curve.html#ac8a923fcf205493466e1e086eecec8b7',1,'QwtPlotIntervalCurve::testPaintAttribute()'],['../class_qwt_plot_raster_item.html#a17d8f350acf46d2ba7a68df977f80a52',1,'QwtPlotRasterItem::testPaintAttribute()'],['../class_qwt_plot_shape_item.html#a0bdf30d604bc22d5279e250daa2e1542',1,'QwtPlotShapeItem::testPaintAttribute()'],['../class_qwt_plot_spectro_curve.html#abd7f7eb2830b0dfb7f6211f0b252088e',1,'QwtPlotSpectroCurve::testPaintAttribute()'],['../class_qwt_plot_trading_curve.html#a50a0f77fb107b62ce7d1a53856a01a98',1,'QwtPlotTradingCurve::testPaintAttribute()'],['../class_qwt_text.html#a53c4bcae538e272660d33bed6f71f01b',1,'QwtText::testPaintAttribute()']]], + ['testpixel',['testPixel',['../class_qwt_pixel_matrix.html#a1089a8d1da928ed35766da496a9b234e',1,'QwtPixelMatrix']]], + ['testrenderhint',['testRenderHint',['../class_qwt_graphic.html#ab0447885a89e0dd014d8e12b5924b2f1',1,'QwtGraphic::testRenderHint()'],['../class_qwt_plot_item.html#ad4009381d6a26359125549e1cf874b69',1,'QwtPlotItem::testRenderHint()']]], + ['text',['text',['../class_qwt_plot_text_label.html#ae1e2796dce184885e871a7b8981e3bac',1,'QwtPlotTextLabel::text()'],['../class_qwt_text.html#a15a42a83153f82bab8cfc283d090d736',1,'QwtText::text()'],['../class_qwt_text_label.html#a6ff4f9a87e11594740f312c8522f933e',1,'QwtTextLabel::text()']]], + ['textengine',['textEngine',['../class_qwt_text.html#a053d8fdb4de77bd3b6f2eb0ecd3980ca',1,'QwtText::textEngine(const QString &text, QwtText::TextFormat=AutoText)'],['../class_qwt_text.html#a2828c4976bd30572d236811bc30037be',1,'QwtText::textEngine(QwtText::TextFormat)']]], + ['textmargins',['textMargins',['../class_qwt_text_engine.html#a83c8d3dc590b9914e9216c01e78e0838',1,'QwtTextEngine::textMargins()'],['../class_qwt_plain_text_engine.html#ac209b74082557d3086cb3b52f99c522d',1,'QwtPlainTextEngine::textMargins()'],['../class_qwt_rich_text_engine.html#a3d507f2cad8ce44d0ee5da3070b943ca',1,'QwtRichTextEngine::textMargins()'],['../class_qwt_math_m_l_text_engine.html#ae89278f8e3642851b6357e34763008fe',1,'QwtMathMLTextEngine::textMargins()']]], + ['textpen',['textPen',['../class_qwt_plot_legend_item.html#a402f612eb053d20bea8ee94b2e6e1893',1,'QwtPlotLegendItem']]], + ['textrect',['textRect',['../class_qwt_plot_text_label.html#ac5b13cbdd6334b05ff4961494755add4',1,'QwtPlotTextLabel::textRect()'],['../class_qwt_text_label.html#ab4f9a18c47618903927fb2b40cbb06e2',1,'QwtTextLabel::textRect()']]], + ['textsize',['textSize',['../class_qwt_text.html#a62537933249b2f967b54468360d41519',1,'QwtText::textSize()'],['../class_qwt_text_engine.html#ad9382cc8ff22c6b3e448fce566a76178',1,'QwtTextEngine::textSize()'],['../class_qwt_plain_text_engine.html#a220628c0e315021a3ae9d4447bf88018',1,'QwtPlainTextEngine::textSize()'],['../class_qwt_rich_text_engine.html#a0dc185454c60931a0c136fc61774abfb',1,'QwtRichTextEngine::textSize()'],['../class_qwt_math_m_l_text_engine.html#ae2b00277f488f755a3bf7fc19548d0ec',1,'QwtMathMLTextEngine::textSize()']]], + ['tickcount',['tickCount',['../class_qwt_wheel.html#ae563d5e05052756af3ef9aeb0bb3a086',1,'QwtWheel']]], + ['ticklabel',['tickLabel',['../class_qwt_abstract_scale_draw.html#a5e703dcb115a51024f89f92e61c2c8d8',1,'QwtAbstractScaleDraw']]], + ['ticklength',['tickLength',['../class_qwt_abstract_scale_draw.html#aa43034f7ad87c33e9790c730ed48c55d',1,'QwtAbstractScaleDraw']]], + ['ticks',['ticks',['../class_qwt_scale_div.html#ac3463fd59946cc3f71875abaaa1adf32',1,'QwtScaleDiv']]], + ['timerevent',['timerEvent',['../class_qwt_slider.html#ab42a98053119570e1fd8d68f5e2d2166',1,'QwtSlider::timerEvent()'],['../class_qwt_wheel.html#a8ca7e27c6afacdc520342f7324ecd6eb',1,'QwtWheel::timerEvent()']]], + ['timespec',['timeSpec',['../class_qwt_date_scale_draw.html#a43eaebd8bb9af3bb6a541a09f1d79014',1,'QwtDateScaleDraw::timeSpec()'],['../class_qwt_date_scale_engine.html#a28c2d2c4d1c6ac5408c6efca0f700856',1,'QwtDateScaleEngine::timeSpec()']]], + ['title',['title',['../class_qwt_legend_data.html#a23d0faa63f590c1f0c3ee7c9479410cf',1,'QwtLegendData::title()'],['../class_qwt_plot.html#a1ae4b2e10f6691b7f1a14af70f743e2c',1,'QwtPlot::title()'],['../class_qwt_plot_item.html#a3859d011b670b5f89e45d1ccef9206f7',1,'QwtPlotItem::title()'],['../class_qwt_scale_widget.html#a75ab60ac06977a6cb1991aa2e7979c2e',1,'QwtScaleWidget::title()']]], + ['titleheightforwidth',['titleHeightForWidth',['../class_qwt_scale_widget.html#a1c488b9304a8e30af20e4da1d397a72f',1,'QwtScaleWidget']]], + ['titlelabel',['titleLabel',['../class_qwt_plot.html#ac39356b86ed70ebf256a8ae964910206',1,'QwtPlot::titleLabel()'],['../class_qwt_plot.html#abea1bb53b3f08fb085a1d954eb199078',1,'QwtPlot::titleLabel() const ']]], + ['titlerect',['titleRect',['../class_qwt_plot_layout.html#af11dfb5fa14f8998f53bb5a4f83e4e11',1,'QwtPlotLayout']]], + ['todatetime',['toDateTime',['../class_qwt_date.html#a8039dc115458981fc1c7fc2c0aa8d053',1,'QwtDate::toDateTime()'],['../class_qwt_date_scale_draw.html#a50502cedfca719b9531d448f24f6ea21',1,'QwtDateScaleDraw::toDateTime()'],['../class_qwt_date_scale_engine.html#af03153128e1d166d3f808ad716b23b21',1,'QwtDateScaleEngine::toDateTime()']]], + ['todouble',['toDouble',['../class_qwt_date.html#afce10fd70f7a1ecac3f97776fb2dc46a',1,'QwtDate']]], + ['toimage',['toImage',['../class_qwt_graphic.html#a48aab63a2c421c59cf1e8d6241b68a59',1,'QwtGraphic::toImage() const '],['../class_qwt_graphic.html#a0eb6c29ac8b9b1371ea73139be7b99c3',1,'QwtGraphic::toImage(const QSize &, Qt::AspectRatioMode=Qt::IgnoreAspectRatio) const '],['../class_qwt_point_mapper.html#a68b7b12f5e5cdad135d2d4aa408b1bdd',1,'QwtPointMapper::toImage()']]], + ['tolerance',['tolerance',['../class_qwt_weeding_curve_fitter.html#aa2e69ce083d02c4da0d669a082a15187',1,'QwtWeedingCurveFitter']]], + ['topixmap',['toPixmap',['../class_qwt_graphic.html#ace94ae880be955e6a9429d6ac9fdc560',1,'QwtGraphic::toPixmap() const '],['../class_qwt_graphic.html#afc9926defd739e5c942492c623e445ce',1,'QwtGraphic::toPixmap(const QSize &, Qt::AspectRatioMode=Qt::IgnoreAspectRatio) const ']]], + ['topoint',['toPoint',['../class_qwt_point3_d.html#a611b2608fdbe8099ae987870a10b38a6',1,'QwtPoint3D::toPoint()'],['../class_qwt_point_polar.html#ab61dd4130840876c00d79c28ea534d06',1,'QwtPointPolar::toPoint()']]], + ['topoints',['toPoints',['../class_qwt_point_mapper.html#a136350d94f21f7b7c309d3f207d283b7',1,'QwtPointMapper']]], + ['topointsf',['toPointsF',['../class_qwt_point_mapper.html#ae096ea4844f89bfaebb4806572d935a8',1,'QwtPointMapper']]], + ['topolygon',['toPolygon',['../class_qwt_point_mapper.html#a6712085a3930dd5d5cebe3fa9eabb522',1,'QwtPointMapper']]], + ['topolygonf',['toPolygonF',['../class_qwt_point_mapper.html#a63b8ce75856b3be11532fdf4bd9602a2',1,'QwtPointMapper']]], + ['torect',['toRect',['../class_qwt_column_rect.html#a0169ba0be3e683ce5c87aacfd172095e',1,'QwtColumnRect']]], + ['tostring',['toString',['../class_qwt_date.html#a2c19998281321ba078d717f7f9ec6855',1,'QwtDate']]], + ['totalangle',['totalAngle',['../class_qwt_knob.html#a804d957c14e08bd9b132985c892ab853',1,'QwtKnob::totalAngle()'],['../class_qwt_wheel.html#ac05734986ee427e6d820f54a267dde26',1,'QwtWheel::totalAngle()']]], + ['totalsteps',['totalSteps',['../class_qwt_abstract_slider.html#aa3f22dfcf2e897c7312a5ed04834eeed',1,'QwtAbstractSlider']]], + ['trackerfont',['trackerFont',['../class_qwt_picker.html#ae87b2ac560d8795a302ee00c0ff0ab3d',1,'QwtPicker']]], + ['trackermode',['trackerMode',['../class_qwt_picker.html#a0647370ed08612d2a55742dc00f6acb7',1,'QwtPicker']]], + ['trackeroverlay',['trackerOverlay',['../class_qwt_picker.html#afeba8fa29515e673efec3684f2e878d9',1,'QwtPicker']]], + ['trackerpen',['trackerPen',['../class_qwt_picker.html#aa45bf8a52ea95bdf63e2225ec7fa8063',1,'QwtPicker']]], + ['trackerposition',['trackerPosition',['../class_qwt_picker.html#a6f95df13af38b041e422fc6f5d002354',1,'QwtPicker']]], + ['trackerrect',['trackerRect',['../class_qwt_picker.html#a3091a5812652b9fef50507ecf957160b',1,'QwtPicker']]], + ['trackertext',['trackerText',['../class_qwt_picker.html#a48ab7695edfa22df80490bf930f16cc4',1,'QwtPicker::trackerText()'],['../class_qwt_plot_picker.html#a7a85e6d7a45e5e480db670bb5f9a9b72',1,'QwtPlotPicker::trackerText()']]], + ['trackertextf',['trackerTextF',['../class_qwt_plot_picker.html#aceebd0c9f95da689a3045c3ccd23aa38',1,'QwtPlotPicker']]], + ['transform',['transform',['../class_qwt_abstract_scale.html#a59e9927b2e43f1db82af9fd1c774e36d',1,'QwtAbstractScale::transform()'],['../class_qwt_plot.html#afbeb5482d0464fd17221a22cc6ba40b3',1,'QwtPlot::transform()'],['../class_qwt_plot_picker.html#a4da9fc86484af7fc12565ad1bb6df24b',1,'QwtPlotPicker::transform(const QRectF &) const '],['../class_qwt_plot_picker.html#a800f6eb68661f26caba0ea4688e73e94',1,'QwtPlotPicker::transform(const QPointF &) const '],['../class_qwt_scale_map.html#ab77cbd649a65b080c3ff21d7abce7f73',1,'QwtScaleMap::transform(double s) const '],['../class_qwt_scale_map.html#af99eeda829142128f97e0b6c4fbf9e1f',1,'QwtScaleMap::transform(const QwtScaleMap &, const QwtScaleMap &, const QRectF &)'],['../class_qwt_scale_map.html#a6be600afa5bd75f5ff52b1f102b123b0',1,'QwtScaleMap::transform(const QwtScaleMap &, const QwtScaleMap &, const QPointF &)'],['../class_qwt_transform.html#a1093b5856cbc6cf812460535442fb130',1,'QwtTransform::transform()'],['../class_qwt_null_transform.html#abf4fa9a536049e6da78e71d5f8485b4e',1,'QwtNullTransform::transform()'],['../class_qwt_log_transform.html#ae13d9e1c7a71fd50afe2e804d2a2fb15',1,'QwtLogTransform::transform()'],['../class_qwt_power_transform.html#aad3892cb63f5981521184960e240a4f3',1,'QwtPowerTransform::transform()']]], + ['transformation',['transformation',['../class_qwt_scale_engine.html#acbc5488cb3f3e2ec9566d4797468d0d7',1,'QwtScaleEngine::transformation()'],['../class_qwt_scale_map.html#adba2c419bba77e8e099febfaa0f543e4',1,'QwtScaleMap::transformation()']]], + ['transition',['transition',['../class_qwt_picker.html#a90f9f3485f054c36c1835931e9a387dd',1,'QwtPicker::transition()'],['../class_qwt_picker_machine.html#acf7b57003bec437ce1ecf83e6d544968',1,'QwtPickerMachine::transition()'],['../class_qwt_picker_tracker_machine.html#a77f580a0ebcb019028db9565ca6148b9',1,'QwtPickerTrackerMachine::transition()'],['../class_qwt_picker_click_point_machine.html#a07b6da1b620dcdb304176c3f40d603df',1,'QwtPickerClickPointMachine::transition()'],['../class_qwt_picker_drag_point_machine.html#aa9e5fc73a7e828ecb1feb1305bdedc36',1,'QwtPickerDragPointMachine::transition()'],['../class_qwt_picker_click_rect_machine.html#add912362fad567108cad0a8a506aaf25',1,'QwtPickerClickRectMachine::transition()'],['../class_qwt_picker_drag_rect_machine.html#a5ff67c2ab51575ddbffe225288ff5f33',1,'QwtPickerDragRectMachine::transition()'],['../class_qwt_picker_drag_line_machine.html#a3896893cd1950d5a00eb1ce01861a24a',1,'QwtPickerDragLineMachine::transition()'],['../class_qwt_picker_polygon_machine.html#a3a5466ca9faa33603a0b6ced6aa96791',1,'QwtPickerPolygonMachine::transition()']]], + ['type',['type',['../class_qwt_painter_command.html#a0c64c4b170b574201daa1c41366d14b7',1,'QwtPainterCommand']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/functions_75.html b/ThirdParty/Qwt/doc/html/search/functions_75.html new file mode 100644 index 0000000000..a6c28fa650 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/functions_75.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/functions_75.js b/ThirdParty/Qwt/doc/html/search/functions_75.js new file mode 100644 index 0000000000..11852269f7 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/functions_75.js @@ -0,0 +1,21 @@ +var searchData= +[ + ['unite',['unite',['../class_qwt_interval.html#ade8626dc4c9521e05ce7fc51cb58d730',1,'QwtInterval']]], + ['updateaxes',['updateAxes',['../class_qwt_plot.html#a1fb2dbc3697a66024d48c08b1d18f8a5',1,'QwtPlot']]], + ['updatecanvasmargins',['updateCanvasMargins',['../class_qwt_plot.html#aef8e679c64cf3158466ab33e7774f264',1,'QwtPlot']]], + ['updatedisplay',['updateDisplay',['../class_qwt_picker.html#a03aa9bf28f991473d564a57d1bf3bdcc',1,'QwtPicker']]], + ['updateinterval',['updateInterval',['../class_qwt_slider.html#a38ed0ece831bc66425159793e6f0b84e',1,'QwtSlider::updateInterval()'],['../class_qwt_wheel.html#a8294b9e8340781da463a53719cae5d23',1,'QwtWheel::updateInterval()']]], + ['updatelayout',['updateLayout',['../class_qwt_plot.html#ad470068832406086d6823109d8d7f050',1,'QwtPlot']]], + ['updatelegend',['updateLegend',['../class_qwt_abstract_legend.html#aa9fc80c9e1dcbcfef51b96a3bff268ca',1,'QwtAbstractLegend::updateLegend()'],['../class_qwt_legend.html#a0a294317170adf5c271c1ce243f66a87',1,'QwtLegend::updateLegend()'],['../class_qwt_plot.html#a9c4242c89decd06f3d35b66568ad69c9',1,'QwtPlot::updateLegend()'],['../class_qwt_plot.html#a9bb681bc692ed8f35c32174ffe98dca9',1,'QwtPlot::updateLegend(const QwtPlotItem *)'],['../class_qwt_plot_item.html#af0c4272375b1ee95a1454c4c503ff324',1,'QwtPlotItem::updateLegend()'],['../class_qwt_plot_legend_item.html#a5bfda08242671a2d9d02b7bfc558926d',1,'QwtPlotLegendItem::updateLegend()']]], + ['updateoverlay',['updateOverlay',['../class_qwt_widget_overlay.html#a231231eebaf7655f8264d2ee2b03127c',1,'QwtWidgetOverlay']]], + ['updatescalediv',['updateScaleDiv',['../class_qwt_plot_grid.html#ad15166f257160adc90b60b9e29d69edf',1,'QwtPlotGrid::updateScaleDiv()'],['../class_qwt_plot_item.html#abf6a70847d3db952161ca4d4a952eea0',1,'QwtPlotItem::updateScaleDiv()'],['../class_qwt_plot_scale_item.html#a9c32bac1ff73c6527305698792a6edfe',1,'QwtPlotScaleItem::updateScaleDiv()'],['../class_qwt_plot_series_item.html#a890792d0f44e341812b5283c249608b2',1,'QwtPlotSeriesItem::updateScaleDiv()']]], + ['updatescales',['updateScales',['../class_qwt_plot_rescaler.html#a999de79352fda2a89e32d1a8831fa5fd',1,'QwtPlotRescaler']]], + ['updatestate',['updateState',['../class_qwt_graphic.html#aa63b1055a8c8a5f6989c926c71b9e5b4',1,'QwtGraphic::updateState()'],['../class_qwt_null_paint_device.html#a235bd4e1453a13f7c4c076a9595a8840',1,'QwtNullPaintDevice::updateState()']]], + ['updatestylesheetinfo',['updateStyleSheetInfo',['../class_qwt_plot_canvas.html#a00cf0a23416a719cb8b742fca074c681',1,'QwtPlotCanvas']]], + ['updatewidget',['updateWidget',['../class_qwt_legend.html#aded18ba97822645209775c27cf6730b3',1,'QwtLegend']]], + ['upperbound',['upperBound',['../class_qwt_abstract_scale.html#a3adb3785868bcadaf9046f82d10e7bda',1,'QwtAbstractScale::upperBound()'],['../class_qwt_scale_div.html#af314ab8ccdf18dec6642c1700687b48d',1,'QwtScaleDiv::upperBound()']]], + ['uppermargin',['upperMargin',['../class_qwt_scale_engine.html#aa3fca2f37156fa3bd8ef21be8d339938',1,'QwtScaleEngine']]], + ['usedcolor',['usedColor',['../class_qwt_text.html#a1496bcc9225230c4da25ea73ba0a345a',1,'QwtText']]], + ['usedfont',['usedFont',['../class_qwt_text.html#a9769ab68a4fe26025c4172a14092f792',1,'QwtText']]], + ['utcoffset',['utcOffset',['../class_qwt_date.html#aeadce3496f631eae3a7e54749078c7a4',1,'QwtDate::utcOffset()'],['../class_qwt_date_scale_draw.html#a0c676fcb0e77b660afdb2b39c617a2ab',1,'QwtDateScaleDraw::utcOffset()'],['../class_qwt_date_scale_engine.html#a9a77943b8f9d36be57fdf382bd62e48d',1,'QwtDateScaleEngine::utcOffset()']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/functions_76.html b/ThirdParty/Qwt/doc/html/search/functions_76.html new file mode 100644 index 0000000000..e5263cc30f --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/functions_76.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/functions_76.js b/ThirdParty/Qwt/doc/html/search/functions_76.js new file mode 100644 index 0000000000..6fef4dfa92 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/functions_76.js @@ -0,0 +1,11 @@ +var searchData= +[ + ['value',['value',['../class_qwt_abstract_slider.html#a6804d4bc124378858d4b3bcfcae6ef66',1,'QwtAbstractSlider::value()'],['../class_qwt_counter.html#a121194fadd8cea929c1ac9509f27fe58',1,'QwtCounter::value()'],['../class_qwt_legend_data.html#a73016050ce489f85018025ec5a268387',1,'QwtLegendData::value()'],['../class_qwt_matrix_raster_data.html#a49952670063166bccdbfb9cdbd7b56e8',1,'QwtMatrixRasterData::value()'],['../class_qwt_plot_marker.html#a2dd71303454a3437b064216b9f729ac7',1,'QwtPlotMarker::value()'],['../class_qwt_raster_data.html#a6396fc013fcec893b1e8cea4cf03691e',1,'QwtRasterData::value()'],['../class_qwt_spline.html#a1f67187eefe2959f0c902532edf64d41',1,'QwtSpline::value()'],['../class_qwt_thermo.html#ae359eec1e467ad86706b9cccb4e04c97',1,'QwtThermo::value()'],['../class_qwt_wheel.html#acaf83399d06bfa769d7d22f59f524d67',1,'QwtWheel::value()']]], + ['valueat',['valueAt',['../class_qwt_wheel.html#a9ab710c0fd49ed5ebe3f816ef077eb96',1,'QwtWheel']]], + ['valuechanged',['valueChanged',['../class_qwt_abstract_slider.html#a6bc5c410cd56119c6ad50743c9a46af1',1,'QwtAbstractSlider::valueChanged()'],['../class_qwt_counter.html#add02928c348417fbfadd7095d058f331',1,'QwtCounter::valueChanged()'],['../class_qwt_wheel.html#ad6551abe91933fd2230d5fee805e637a',1,'QwtWheel::valueChanged()']]], + ['valuematrix',['valueMatrix',['../class_qwt_matrix_raster_data.html#a001d575e77cf90c29ec8c5a6f8656946',1,'QwtMatrixRasterData']]], + ['values',['values',['../class_qwt_legend_data.html#aeecadb69ee0e384b34f4b39a2131924e',1,'QwtLegendData']]], + ['verticalscrollbar',['verticalScrollBar',['../class_qwt_legend.html#a494758e3d7ab688c59989da52e7e97cf',1,'QwtLegend']]], + ['viewangle',['viewAngle',['../class_qwt_wheel.html#a49c04ea6e1ec21268f63d45239bc9333',1,'QwtWheel']]], + ['viewbox',['viewBox',['../class_qwt_plot_svg_item.html#aeb813520578062494f4e604a40713ccc',1,'QwtPlotSvgItem']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/functions_77.html b/ThirdParty/Qwt/doc/html/search/functions_77.html new file mode 100644 index 0000000000..add7295de6 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/functions_77.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/functions_77.js b/ThirdParty/Qwt/doc/html/search/functions_77.js new file mode 100644 index 0000000000..c1f05a0d37 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/functions_77.js @@ -0,0 +1,25 @@ +var searchData= +[ + ['week0type',['week0Type',['../class_qwt_date_scale_draw.html#a1c64d18c81ff3b77449df87c014b6721',1,'QwtDateScaleDraw::week0Type()'],['../class_qwt_date_scale_engine.html#add6b4e1668ce1c45fc5d05dd612283d2',1,'QwtDateScaleEngine::week0Type()']]], + ['weeknumber',['weekNumber',['../class_qwt_date.html#a90dd1f9dc38565c003f8e1ef821965b7',1,'QwtDate']]], + ['wheelborderwidth',['wheelBorderWidth',['../class_qwt_wheel.html#a76117515ddfb6c0bbd680e070dd67670',1,'QwtWheel']]], + ['wheelevent',['wheelEvent',['../class_qwt_abstract_slider.html#a7050c9ce667176e6de4c6357b5acd493',1,'QwtAbstractSlider::wheelEvent()'],['../class_qwt_counter.html#acdada1ba1d5873b9c8b3f75d63b4685a',1,'QwtCounter::wheelEvent()'],['../class_qwt_dial.html#ad35fe293f6b53f6c4ab977d6259fbf19',1,'QwtDial::wheelEvent()'],['../class_qwt_wheel.html#a1ff8fa42a64643b7fa09ea2c17164075',1,'QwtWheel::wheelEvent()']]], + ['wheelfactor',['wheelFactor',['../class_qwt_magnifier.html#a83722e9f081603a45e118947d7f810a4',1,'QwtMagnifier']]], + ['wheelmodifiers',['wheelModifiers',['../class_qwt_magnifier.html#a6a05561142ecde0c3323e64e75c72691',1,'QwtMagnifier']]], + ['wheelmoved',['wheelMoved',['../class_qwt_wheel.html#a7d0f833add72c3aceb0773825626bddf',1,'QwtWheel']]], + ['wheelpressed',['wheelPressed',['../class_qwt_wheel.html#aa9cb862f6ed4a75b007f13bbc3804ad0',1,'QwtWheel']]], + ['wheelrect',['wheelRect',['../class_qwt_wheel.html#a72891a083911e03110e1f1f60f47f064',1,'QwtWheel']]], + ['wheelreleased',['wheelReleased',['../class_qwt_wheel.html#a9ddffcbd6752571e8b1d75f2640dc6d5',1,'QwtWheel']]], + ['wheelwidth',['wheelWidth',['../class_qwt_wheel.html#ad88a4923037b4c692a5f001fb55a9549',1,'QwtWheel']]], + ['widgetenterevent',['widgetEnterEvent',['../class_qwt_picker.html#a7d3d1b97aba53a7f917013e111a5a636',1,'QwtPicker']]], + ['widgetkeypressevent',['widgetKeyPressEvent',['../class_qwt_magnifier.html#a382cec084a2bfc0610ca500121205f04',1,'QwtMagnifier::widgetKeyPressEvent()'],['../class_qwt_panner.html#a7ed4e89f6c52b841e20ad497af4b4ebc',1,'QwtPanner::widgetKeyPressEvent()'],['../class_qwt_picker.html#af5bc441b2fc143363563922a3b3c70ae',1,'QwtPicker::widgetKeyPressEvent()'],['../class_qwt_plot_zoomer.html#aa44e42dcf37547a6b93d04a593f140c6',1,'QwtPlotZoomer::widgetKeyPressEvent()']]], + ['widgetkeyreleaseevent',['widgetKeyReleaseEvent',['../class_qwt_magnifier.html#af84037c68c9b88263d1c27bb648cf9ff',1,'QwtMagnifier::widgetKeyReleaseEvent()'],['../class_qwt_panner.html#a8bd447df4a30299bbc8e6b6d3e2e2f9f',1,'QwtPanner::widgetKeyReleaseEvent()'],['../class_qwt_picker.html#a9f2c739a619be794b22a10ede9674a1e',1,'QwtPicker::widgetKeyReleaseEvent()']]], + ['widgetleaveevent',['widgetLeaveEvent',['../class_qwt_picker.html#a8a2a18f2b98c8524b1d3684df44c24aa',1,'QwtPicker']]], + ['widgetmousedoubleclickevent',['widgetMouseDoubleClickEvent',['../class_qwt_picker.html#af1ffb07c24be57cd4a753b04412b3212',1,'QwtPicker']]], + ['widgetmousemoveevent',['widgetMouseMoveEvent',['../class_qwt_magnifier.html#a4eb68b98b063cc14b7839f02f8671dfc',1,'QwtMagnifier::widgetMouseMoveEvent()'],['../class_qwt_panner.html#a6545bc6e25018253c59fc27a48eb948f',1,'QwtPanner::widgetMouseMoveEvent()'],['../class_qwt_picker.html#a88b203109a4d3b26c2e0bee110c56c9d',1,'QwtPicker::widgetMouseMoveEvent()']]], + ['widgetmousepressevent',['widgetMousePressEvent',['../class_qwt_magnifier.html#a5930b3ec00ae99883f36cf8bf568cbf7',1,'QwtMagnifier::widgetMousePressEvent()'],['../class_qwt_panner.html#ae002958978dcc751f9edda24e5858dd9',1,'QwtPanner::widgetMousePressEvent()'],['../class_qwt_picker.html#a4bfae8da37c3936ae73d4798cca4a3d9',1,'QwtPicker::widgetMousePressEvent()']]], + ['widgetmousereleaseevent',['widgetMouseReleaseEvent',['../class_qwt_magnifier.html#aa7cc31995444ca8dd8412b8a6dab7b93',1,'QwtMagnifier::widgetMouseReleaseEvent()'],['../class_qwt_panner.html#ab2da1e24b1456b223eaa826d8e0a3a81',1,'QwtPanner::widgetMouseReleaseEvent()'],['../class_qwt_picker.html#ac009633e005b6290e07b902f2a58e45e',1,'QwtPicker::widgetMouseReleaseEvent()'],['../class_qwt_plot_zoomer.html#aabded662ecb3555b3a29cf3daacf79de',1,'QwtPlotZoomer::widgetMouseReleaseEvent()']]], + ['widgetwheelevent',['widgetWheelEvent',['../class_qwt_magnifier.html#a236762870830cc0621411c173472392b',1,'QwtMagnifier::widgetWheelEvent()'],['../class_qwt_picker.html#af92ffabe291a6254378dc932c5cce0a7',1,'QwtPicker::widgetWheelEvent()']]], + ['width',['width',['../class_qwt_simple_compass_rose.html#a28e7dcd6574c6239f5d15cdda93ac835',1,'QwtSimpleCompassRose::width()'],['../class_qwt_dial_simple_needle.html#af7c8d5ed409364e4e67b7e40f1c0cfe2',1,'QwtDialSimpleNeedle::width()'],['../class_qwt_interval.html#a7cded184fdbb9e30756f422ceca7522e',1,'QwtInterval::width()'],['../class_qwt_interval_symbol.html#a7f0bb9488778d9054932a5c072daecdc',1,'QwtIntervalSymbol::width()']]], + ['wrapping',['wrapping',['../class_qwt_abstract_slider.html#a829f90f6e4b7852da72d6e3f4137b041',1,'QwtAbstractSlider::wrapping()'],['../class_qwt_counter.html#a22d4cd0baab3b0b56340bb409b92b672',1,'QwtCounter::wrapping()'],['../class_qwt_wheel.html#a6da22b8a5457c1c228073edc24ffbf0e',1,'QwtWheel::wrapping()']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/functions_78.html b/ThirdParty/Qwt/doc/html/search/functions_78.html new file mode 100644 index 0000000000..7f647970fe --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/functions_78.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/functions_78.js b/ThirdParty/Qwt/doc/html/search/functions_78.js new file mode 100644 index 0000000000..366346e15e --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/functions_78.js @@ -0,0 +1,10 @@ +var searchData= +[ + ['x',['x',['../class_qwt_point3_d.html#a055a9d12fbdc279452ee6c056bd3ba8f',1,'QwtPoint3D::x()'],['../class_qwt_synthetic_point_data.html#ab14ef450ef097f05dbb8b8d75202538b',1,'QwtSyntheticPointData::x()']]], + ['xaxis',['xAxis',['../class_qwt_plot_item.html#a7af360bf6d5a5b6257ce6b0dd99b7525',1,'QwtPlotItem::xAxis()'],['../class_qwt_plot_picker.html#a9cdd6d56e990173a00c6c81edbe8818d',1,'QwtPlotPicker::xAxis()']]], + ['xdata',['xData',['../class_qwt_point_array_data.html#a94db4f8c1d2a4495f22144d03255bc2d',1,'QwtPointArrayData::xData()'],['../class_qwt_c_pointer_data.html#a6409b0bcf77674d1970185c6c3245e26',1,'QwtCPointerData::xData()']]], + ['xenabled',['xEnabled',['../class_qwt_plot_grid.html#a46d19c58295d538518586374efadd34c',1,'QwtPlotGrid']]], + ['xminenabled',['xMinEnabled',['../class_qwt_plot_grid.html#a2eeb5b2118f35409cb1450c2a032e8ff',1,'QwtPlotGrid']]], + ['xscalediv',['xScaleDiv',['../class_qwt_plot_grid.html#a4de2f1d11d5b24c0790db1e3dd0b3436',1,'QwtPlotGrid']]], + ['xvalue',['xValue',['../class_qwt_plot_marker.html#aad43f527f3c0033865fea5a488ef3857',1,'QwtPlotMarker']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/functions_79.html b/ThirdParty/Qwt/doc/html/search/functions_79.html new file mode 100644 index 0000000000..32abd5ea68 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/functions_79.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/functions_79.js b/ThirdParty/Qwt/doc/html/search/functions_79.js new file mode 100644 index 0000000000..ca83a1d4d7 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/functions_79.js @@ -0,0 +1,10 @@ +var searchData= +[ + ['y',['y',['../class_qwt_point3_d.html#ac2c90240ee705f3422202aeb6d5e0654',1,'QwtPoint3D::y()'],['../class_qwt_synthetic_point_data.html#af65186bea0056b3f7f46814c61d68c99',1,'QwtSyntheticPointData::y()']]], + ['yaxis',['yAxis',['../class_qwt_plot_item.html#ac7714ffa278a10e0cf45972e487b63ff',1,'QwtPlotItem::yAxis()'],['../class_qwt_plot_picker.html#a3068fb734845abfdf5dff00ead18377f',1,'QwtPlotPicker::yAxis()']]], + ['ydata',['yData',['../class_qwt_point_array_data.html#ac7fcf7f7dfa58298bb165142d81d03f2',1,'QwtPointArrayData::yData()'],['../class_qwt_c_pointer_data.html#a7c538ed7b3e4cc5db6d4d97c09ed9d73',1,'QwtCPointerData::yData()']]], + ['yenabled',['yEnabled',['../class_qwt_plot_grid.html#ad0f38876f49c5197e929ab80e389dbb5',1,'QwtPlotGrid']]], + ['yminenabled',['yMinEnabled',['../class_qwt_plot_grid.html#af677551f6121de684888af6e2b77333f',1,'QwtPlotGrid']]], + ['yscalediv',['yScaleDiv',['../class_qwt_plot_grid.html#a0da37b84786570c1ecff37ac18c6684c',1,'QwtPlotGrid']]], + ['yvalue',['yValue',['../class_qwt_plot_marker.html#a30ec999a3e4eba759d4c405fa92f9563',1,'QwtPlotMarker']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/functions_7a.html b/ThirdParty/Qwt/doc/html/search/functions_7a.html new file mode 100644 index 0000000000..e23b42fb02 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/functions_7a.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/functions_7a.js b/ThirdParty/Qwt/doc/html/search/functions_7a.js new file mode 100644 index 0000000000..77f54afbd5 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/functions_7a.js @@ -0,0 +1,10 @@ +var searchData= +[ + ['z',['z',['../class_qwt_plot_item.html#a4c58d814336643190b9f2918f80c30df',1,'QwtPlotItem::z()'],['../class_qwt_point3_d.html#afd56ba68ce1cfad4a4e477f45f0c85d4',1,'QwtPoint3D::z()']]], + ['zoom',['zoom',['../class_qwt_plot_zoomer.html#afe9f123f263536b620d1a9061d5705c6',1,'QwtPlotZoomer::zoom(const QRectF &)'],['../class_qwt_plot_zoomer.html#a0cee73f15c5791553cb52c4e7b3e881e',1,'QwtPlotZoomer::zoom(int up)']]], + ['zoombase',['zoomBase',['../class_qwt_plot_zoomer.html#ab0edba67626ca0c6c0632b38b1f67921',1,'QwtPlotZoomer']]], + ['zoomed',['zoomed',['../class_qwt_plot_zoomer.html#af5d312de34b493b59e48f03850478648',1,'QwtPlotZoomer']]], + ['zoomrect',['zoomRect',['../class_qwt_plot_zoomer.html#a91a2d1f0609666322dd955d3366cfbf0',1,'QwtPlotZoomer']]], + ['zoomrectindex',['zoomRectIndex',['../class_qwt_plot_zoomer.html#a63797aa3b9e540a2c5f539fa34a05fbc',1,'QwtPlotZoomer']]], + ['zoomstack',['zoomStack',['../class_qwt_plot_zoomer.html#a3fd87611a5b3b263f26800b1008985ec',1,'QwtPlotZoomer']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/functions_7e.html b/ThirdParty/Qwt/doc/html/search/functions_7e.html new file mode 100644 index 0000000000..45c26c5047 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/functions_7e.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/functions_7e.js b/ThirdParty/Qwt/doc/html/search/functions_7e.js new file mode 100644 index 0000000000..7cf6bc48ad --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/functions_7e.js @@ -0,0 +1,100 @@ +var searchData= +[ + ['_7eqwtabstractlegend',['~QwtAbstractLegend',['../class_qwt_abstract_legend.html#a6d86d9c50679dea9fefafc457fc70814',1,'QwtAbstractLegend']]], + ['_7eqwtabstractscale',['~QwtAbstractScale',['../class_qwt_abstract_scale.html#a73890593efff11427ea7a42a3ebadefd',1,'QwtAbstractScale']]], + ['_7eqwtabstractscaledraw',['~QwtAbstractScaleDraw',['../class_qwt_abstract_scale_draw.html#adc4d3f491b28ee39d728a4a4a9cdd494',1,'QwtAbstractScaleDraw']]], + ['_7eqwtabstractseriesstore',['~QwtAbstractSeriesStore',['../class_qwt_abstract_series_store.html#a3990acd8aba251e46d8c64d2154e3f72',1,'QwtAbstractSeriesStore']]], + ['_7eqwtabstractslider',['~QwtAbstractSlider',['../class_qwt_abstract_slider.html#a31b9e0314988b7d547c9ded625014bbb',1,'QwtAbstractSlider']]], + ['_7eqwtalphacolormap',['~QwtAlphaColorMap',['../class_qwt_alpha_color_map.html#ac6445d25b9df0b565383b8189691bbad',1,'QwtAlphaColorMap']]], + ['_7eqwtanalogclock',['~QwtAnalogClock',['../class_qwt_analog_clock.html#a3abdcecf88e3d3510d94e96e7e9e74ee',1,'QwtAnalogClock']]], + ['_7eqwtarrowbutton',['~QwtArrowButton',['../class_qwt_arrow_button.html#a506ab071fa7ee92928ace7dcea774a73',1,'QwtArrowButton']]], + ['_7eqwtcolormap',['~QwtColorMap',['../class_qwt_color_map.html#af20e4ffdb3c5d34f5a6dc301bcbb9f7e',1,'QwtColorMap']]], + ['_7eqwtcolumnsymbol',['~QwtColumnSymbol',['../class_qwt_column_symbol.html#a4ca8a7cb15c23be659f3bdcdb50ae20c',1,'QwtColumnSymbol']]], + ['_7eqwtcompass',['~QwtCompass',['../class_qwt_compass.html#af6cc3b946f3761f7ce53d3a2ec000817',1,'QwtCompass']]], + ['_7eqwtcompassrose',['~QwtCompassRose',['../class_qwt_compass_rose.html#a9e3e5086d7225152cad3a276096753be',1,'QwtCompassRose']]], + ['_7eqwtcounter',['~QwtCounter',['../class_qwt_counter.html#a6469133eb210b470023a3dcc735aec4d',1,'QwtCounter']]], + ['_7eqwtcurvefitter',['~QwtCurveFitter',['../class_qwt_curve_fitter.html#a62919f309f0441d94adea94573d0f778',1,'QwtCurveFitter']]], + ['_7eqwtdatescaledraw',['~QwtDateScaleDraw',['../class_qwt_date_scale_draw.html#af32e43b35fbc805400f907a5e1466b83',1,'QwtDateScaleDraw']]], + ['_7eqwtdatescaleengine',['~QwtDateScaleEngine',['../class_qwt_date_scale_engine.html#a1e1d01f5ac297bcdb1458a35bcd8d554',1,'QwtDateScaleEngine']]], + ['_7eqwtdial',['~QwtDial',['../class_qwt_dial.html#a16cd1e45a78890c6c5f6e9c07b0180c7',1,'QwtDial']]], + ['_7eqwtdialneedle',['~QwtDialNeedle',['../class_qwt_dial_needle.html#ac23b2af4af50042967c8cea87b474247',1,'QwtDialNeedle']]], + ['_7eqwtdyngridlayout',['~QwtDynGridLayout',['../class_qwt_dyn_grid_layout.html#abb583f302fbf5d92b306841d414e52a4',1,'QwtDynGridLayout']]], + ['_7eqwteventpattern',['~QwtEventPattern',['../class_qwt_event_pattern.html#a3f8c2a2cca991000bafefd924b47895d',1,'QwtEventPattern']]], + ['_7eqwtgraphic',['~QwtGraphic',['../class_qwt_graphic.html#a1be9e3400a8d094cdf2deb1ff3eb9d65',1,'QwtGraphic']]], + ['_7eqwtintervalsymbol',['~QwtIntervalSymbol',['../class_qwt_interval_symbol.html#ac983feda2d6417a24e430aa0cd0548b9',1,'QwtIntervalSymbol']]], + ['_7eqwtknob',['~QwtKnob',['../class_qwt_knob.html#a13f3e622b333c9918bc61844029f8a70',1,'QwtKnob']]], + ['_7eqwtlegend',['~QwtLegend',['../class_qwt_legend.html#a2dd3bc628652909b74e7ddb5db021ea5',1,'QwtLegend']]], + ['_7eqwtlegenddata',['~QwtLegendData',['../class_qwt_legend_data.html#a56608cc97875e7b3dd9340decd5231cb',1,'QwtLegendData']]], + ['_7eqwtlegendlabel',['~QwtLegendLabel',['../class_qwt_legend_label.html#ad9f7483fa0625a28aba97cca8c3167b7',1,'QwtLegendLabel']]], + ['_7eqwtlinearcolormap',['~QwtLinearColorMap',['../class_qwt_linear_color_map.html#a82caa759e44d439aa9866bd03e2e3696',1,'QwtLinearColorMap']]], + ['_7eqwtlinearscaleengine',['~QwtLinearScaleEngine',['../class_qwt_linear_scale_engine.html#aa9e543118c60aa04f68123030821fedd',1,'QwtLinearScaleEngine']]], + ['_7eqwtlogscaleengine',['~QwtLogScaleEngine',['../class_qwt_log_scale_engine.html#ad749149c492c7105fb6e5518abd323c9',1,'QwtLogScaleEngine']]], + ['_7eqwtlogtransform',['~QwtLogTransform',['../class_qwt_log_transform.html#a39296a96bd30f5ea8f22cb79456c23f0',1,'QwtLogTransform']]], + ['_7eqwtmagnifier',['~QwtMagnifier',['../class_qwt_magnifier.html#ac18a7858407951a335399ee6969a50da',1,'QwtMagnifier']]], + ['_7eqwtmathmltextengine',['~QwtMathMLTextEngine',['../class_qwt_math_m_l_text_engine.html#a864d4265a7621e7389b21d419e6503ff',1,'QwtMathMLTextEngine']]], + ['_7eqwtmatrixrasterdata',['~QwtMatrixRasterData',['../class_qwt_matrix_raster_data.html#a15284284966f25383fe67f2e278f4869',1,'QwtMatrixRasterData']]], + ['_7eqwtnullpaintdevice',['~QwtNullPaintDevice',['../class_qwt_null_paint_device.html#a050e40b6efff32a616f3e8326f4fd632',1,'QwtNullPaintDevice']]], + ['_7eqwtnulltransform',['~QwtNullTransform',['../class_qwt_null_transform.html#aa2ee005d43d2532e3312eb50dd873f0a',1,'QwtNullTransform']]], + ['_7eqwtpaintercommand',['~QwtPainterCommand',['../class_qwt_painter_command.html#af2b2cc7b6d5ce371b3d2456c231f846e',1,'QwtPainterCommand']]], + ['_7eqwtpanner',['~QwtPanner',['../class_qwt_panner.html#a19c9b9a08da05649f6d2ef5bf6fb391c',1,'QwtPanner']]], + ['_7eqwtpicker',['~QwtPicker',['../class_qwt_picker.html#a5d0906a0d3b12e0e44499f855cb9dab1',1,'QwtPicker']]], + ['_7eqwtpickermachine',['~QwtPickerMachine',['../class_qwt_picker_machine.html#aa1164dfb8ae6ac62fb3b6cb19efcb3e5',1,'QwtPickerMachine']]], + ['_7eqwtpixelmatrix',['~QwtPixelMatrix',['../class_qwt_pixel_matrix.html#a6691629e198fb39e6f653038cfb74f6b',1,'QwtPixelMatrix']]], + ['_7eqwtplaintextengine',['~QwtPlainTextEngine',['../class_qwt_plain_text_engine.html#a0ada8796b2caaff7bb8d61e9fb1b5143',1,'QwtPlainTextEngine']]], + ['_7eqwtplot',['~QwtPlot',['../class_qwt_plot.html#a2b60620e3681810946dcc66002aad016',1,'QwtPlot']]], + ['_7eqwtplotabstractbarchart',['~QwtPlotAbstractBarChart',['../class_qwt_plot_abstract_bar_chart.html#a80176eb6c7f95c5f5b9b90e595e1fdcd',1,'QwtPlotAbstractBarChart']]], + ['_7eqwtplotbarchart',['~QwtPlotBarChart',['../class_qwt_plot_bar_chart.html#ad09883b49e09cee21bb9d21cd7425271',1,'QwtPlotBarChart']]], + ['_7eqwtplotcanvas',['~QwtPlotCanvas',['../class_qwt_plot_canvas.html#a320320bbb1b511c0c37fb2452a7f4404',1,'QwtPlotCanvas']]], + ['_7eqwtplotcurve',['~QwtPlotCurve',['../class_qwt_plot_curve.html#aa05ec6d3883821a8e62330fbeeb85dbd',1,'QwtPlotCurve']]], + ['_7eqwtplotdict',['~QwtPlotDict',['../class_qwt_plot_dict.html#a9199acfe3e8dcb095065bff3f90f518b',1,'QwtPlotDict']]], + ['_7eqwtplotdirectpainter',['~QwtPlotDirectPainter',['../class_qwt_plot_direct_painter.html#aab96bfd08e9041c2552210bbd3ee5ad0',1,'QwtPlotDirectPainter']]], + ['_7eqwtplotglcanvas',['~QwtPlotGLCanvas',['../class_qwt_plot_g_l_canvas.html#a330939a56e289c42bcfbee2d82ef8347',1,'QwtPlotGLCanvas']]], + ['_7eqwtplotgrid',['~QwtPlotGrid',['../class_qwt_plot_grid.html#af39443cd91b8a96a797af1d6b78bfab3',1,'QwtPlotGrid']]], + ['_7eqwtplothistogram',['~QwtPlotHistogram',['../class_qwt_plot_histogram.html#a64bf6dad5655ef1ef3a0a1507d2feafb',1,'QwtPlotHistogram']]], + ['_7eqwtplotintervalcurve',['~QwtPlotIntervalCurve',['../class_qwt_plot_interval_curve.html#a1b04a9a4e327b8e33de2c02cf89fa574',1,'QwtPlotIntervalCurve']]], + ['_7eqwtplotitem',['~QwtPlotItem',['../class_qwt_plot_item.html#a282a1d0424a06737f80e1fe83ccf7a0c',1,'QwtPlotItem']]], + ['_7eqwtplotlayout',['~QwtPlotLayout',['../class_qwt_plot_layout.html#a39653485c638535bc11f50d2e5ef936d',1,'QwtPlotLayout']]], + ['_7eqwtplotlegenditem',['~QwtPlotLegendItem',['../class_qwt_plot_legend_item.html#adae55c1a6f185acc37a70df9008d4624',1,'QwtPlotLegendItem']]], + ['_7eqwtplotmagnifier',['~QwtPlotMagnifier',['../class_qwt_plot_magnifier.html#a38c0508241885ea49542cc0f11c740df',1,'QwtPlotMagnifier']]], + ['_7eqwtplotmarker',['~QwtPlotMarker',['../class_qwt_plot_marker.html#a920d2ddeb2041c03790d7c173e3ad0cf',1,'QwtPlotMarker']]], + ['_7eqwtplotmultibarchart',['~QwtPlotMultiBarChart',['../class_qwt_plot_multi_bar_chart.html#a171ad297d47ba4d4b74755a55af6db94',1,'QwtPlotMultiBarChart']]], + ['_7eqwtplotpanner',['~QwtPlotPanner',['../class_qwt_plot_panner.html#aa72bb8323d5a8eb46900f978bf1e3623',1,'QwtPlotPanner']]], + ['_7eqwtplotpicker',['~QwtPlotPicker',['../class_qwt_plot_picker.html#a0a13f683558c0e3bdb796a3b508be159',1,'QwtPlotPicker']]], + ['_7eqwtplotrasteritem',['~QwtPlotRasterItem',['../class_qwt_plot_raster_item.html#a2715233827c346ab15504dc75d6e9714',1,'QwtPlotRasterItem']]], + ['_7eqwtplotrenderer',['~QwtPlotRenderer',['../class_qwt_plot_renderer.html#a572bea1c8400ba75c01d0bb8bdf391c3',1,'QwtPlotRenderer']]], + ['_7eqwtplotrescaler',['~QwtPlotRescaler',['../class_qwt_plot_rescaler.html#ae34a0dbae9074c211f36c765142d8ddd',1,'QwtPlotRescaler']]], + ['_7eqwtplotscaleitem',['~QwtPlotScaleItem',['../class_qwt_plot_scale_item.html#a8f246e1e73704c1c40ae1294269b65fa',1,'QwtPlotScaleItem']]], + ['_7eqwtplotseriesitem',['~QwtPlotSeriesItem',['../class_qwt_plot_series_item.html#aa4ef832ea5b6c65c9538943794702bc5',1,'QwtPlotSeriesItem']]], + ['_7eqwtplotshapeitem',['~QwtPlotShapeItem',['../class_qwt_plot_shape_item.html#accacacbcdbf558ad3dfcba462bf2b0c3',1,'QwtPlotShapeItem']]], + ['_7eqwtplotspectrocurve',['~QwtPlotSpectroCurve',['../class_qwt_plot_spectro_curve.html#a8246490aaa9d47e77f5596f56fb073d6',1,'QwtPlotSpectroCurve']]], + ['_7eqwtplotspectrogram',['~QwtPlotSpectrogram',['../class_qwt_plot_spectrogram.html#ae76415d290cf4a512d07a17260b7a84a',1,'QwtPlotSpectrogram']]], + ['_7eqwtplotsvgitem',['~QwtPlotSvgItem',['../class_qwt_plot_svg_item.html#a4509baf861772124c71abd1b6514b319',1,'QwtPlotSvgItem']]], + ['_7eqwtplottextlabel',['~QwtPlotTextLabel',['../class_qwt_plot_text_label.html#a20e024910ca49b8fd7326cbfca77df22',1,'QwtPlotTextLabel']]], + ['_7eqwtplottradingcurve',['~QwtPlotTradingCurve',['../class_qwt_plot_trading_curve.html#a93a040562cf897355196f127c7231194',1,'QwtPlotTradingCurve']]], + ['_7eqwtplotzoneitem',['~QwtPlotZoneItem',['../class_qwt_plot_zone_item.html#a696327e3e806dd2cada33b8e2d4f18f8',1,'QwtPlotZoneItem']]], + ['_7eqwtpointmapper',['~QwtPointMapper',['../class_qwt_point_mapper.html#aabe6a70dae5784e8b67f4527c51e0c09',1,'QwtPointMapper']]], + ['_7eqwtpowertransform',['~QwtPowerTransform',['../class_qwt_power_transform.html#a33a82c2e0a67e7463646e7dbb64ccff1',1,'QwtPowerTransform']]], + ['_7eqwtrasterdata',['~QwtRasterData',['../class_qwt_raster_data.html#a95b24c7cad42c5f7947e64e990def3e8',1,'QwtRasterData']]], + ['_7eqwtroundscaledraw',['~QwtRoundScaleDraw',['../class_qwt_round_scale_draw.html#a81583432e629cd8a14524b05fabb4731',1,'QwtRoundScaleDraw']]], + ['_7eqwtsamplingthread',['~QwtSamplingThread',['../class_qwt_sampling_thread.html#a7a0b4d5c172f2ded5f6b6483c6ab56e5',1,'QwtSamplingThread']]], + ['_7eqwtscaledraw',['~QwtScaleDraw',['../class_qwt_scale_draw.html#a9c907c8fa27ec7312e78145e3050c599',1,'QwtScaleDraw']]], + ['_7eqwtscaleengine',['~QwtScaleEngine',['../class_qwt_scale_engine.html#ab9c21b4550d44d9a82c1865864cb8943',1,'QwtScaleEngine']]], + ['_7eqwtscalemap',['~QwtScaleMap',['../class_qwt_scale_map.html#aecafd09423984a5e0ffa935d1b45110c',1,'QwtScaleMap']]], + ['_7eqwtscalewidget',['~QwtScaleWidget',['../class_qwt_scale_widget.html#a84213c50912000db319b2c7d704f9a33',1,'QwtScaleWidget']]], + ['_7eqwtseriesdata',['~QwtSeriesData',['../class_qwt_series_data.html#a841a56f909879d599a385b9c3d046745',1,'QwtSeriesData']]], + ['_7eqwtseriesstore',['~QwtSeriesStore',['../class_qwt_series_store.html#ae500a3787e77e16d096f4e6c1d292101',1,'QwtSeriesStore']]], + ['_7eqwtsimplecompassrose',['~QwtSimpleCompassRose',['../class_qwt_simple_compass_rose.html#a157304c9a535126d33a80df9a9dad292',1,'QwtSimpleCompassRose']]], + ['_7eqwtslider',['~QwtSlider',['../class_qwt_slider.html#a1d82f2f616f8cd3cc7c265948d1b7886',1,'QwtSlider']]], + ['_7eqwtspline',['~QwtSpline',['../class_qwt_spline.html#a90805882826469c94fdc871f18261bb6',1,'QwtSpline']]], + ['_7eqwtsplinecurvefitter',['~QwtSplineCurveFitter',['../class_qwt_spline_curve_fitter.html#a933ecbf859698978104d0dd4ec2a2f6a',1,'QwtSplineCurveFitter']]], + ['_7eqwtsymbol',['~QwtSymbol',['../class_qwt_symbol.html#a5a30269273545d5ed25f7116a421eda2',1,'QwtSymbol']]], + ['_7eqwtsystemclock',['~QwtSystemClock',['../class_qwt_system_clock.html#a79a46a34a317543a08a8424a333b9ee3',1,'QwtSystemClock']]], + ['_7eqwttext',['~QwtText',['../class_qwt_text.html#aba243ac11b91979ad3f2ee7d3c700195',1,'QwtText']]], + ['_7eqwttextengine',['~QwtTextEngine',['../class_qwt_text_engine.html#adda9e23494429c54b3cc3452940fb2bc',1,'QwtTextEngine']]], + ['_7eqwttextlabel',['~QwtTextLabel',['../class_qwt_text_label.html#adf8f363200c527a6af4259647304be5a',1,'QwtTextLabel']]], + ['_7eqwtthermo',['~QwtThermo',['../class_qwt_thermo.html#ad0e2bd43eae2402ade490a5e6c4ef4ae',1,'QwtThermo']]], + ['_7eqwttransform',['~QwtTransform',['../class_qwt_transform.html#aa2653db3104e672464dc569592fc14ab',1,'QwtTransform']]], + ['_7eqwtweedingcurvefitter',['~QwtWeedingCurveFitter',['../class_qwt_weeding_curve_fitter.html#abbd30a948fc6974f881678f80a29768c',1,'QwtWeedingCurveFitter']]], + ['_7eqwtwheel',['~QwtWheel',['../class_qwt_wheel.html#a57f465a31a9d2d88cb7a1d0e6391535e',1,'QwtWheel']]], + ['_7eqwtwidgetoverlay',['~QwtWidgetOverlay',['../class_qwt_widget_overlay.html#af234383cb42288746b970fb3fa18395d',1,'QwtWidgetOverlay']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/mag_sel.png b/ThirdParty/Qwt/doc/html/search/mag_sel.png new file mode 100644 index 0000000000..81f6040a20 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/search/mag_sel.png differ diff --git a/ThirdParty/Qwt/doc/html/search/nomatches.html b/ThirdParty/Qwt/doc/html/search/nomatches.html new file mode 100644 index 0000000000..b1ded27e9a --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/nomatches.html @@ -0,0 +1,12 @@ + + + + + + + +
+
No Matches
+
+ + diff --git a/ThirdParty/Qwt/doc/html/search/pages_63.html b/ThirdParty/Qwt/doc/html/search/pages_63.html new file mode 100644 index 0000000000..8a7aaf9e21 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/pages_63.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/pages_63.js b/ThirdParty/Qwt/doc/html/search/pages_63.js new file mode 100644 index 0000000000..3270061ee4 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/pages_63.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['curve_20plots',['Curve Plots',['../curvescreenshots.html',1,'']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/pages_64.html b/ThirdParty/Qwt/doc/html/search/pages_64.html new file mode 100644 index 0000000000..e404fbfc2b --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/pages_64.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/pages_64.js b/ThirdParty/Qwt/doc/html/search/pages_64.js new file mode 100644 index 0000000000..59e68d6e8d --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/pages_64.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['dials_2c_20compasses_2c_20knobs_2c_20wheels_2c_20sliders_2c_20thermos',['Dials, Compasses, Knobs, Wheels, Sliders, Thermos',['../controlscreenshots.html',1,'']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/pages_68.html b/ThirdParty/Qwt/doc/html/search/pages_68.html new file mode 100644 index 0000000000..92ef1a3841 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/pages_68.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/pages_68.js b/ThirdParty/Qwt/doc/html/search/pages_68.js new file mode 100644 index 0000000000..407858c44a --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/pages_68.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['histogram',['Histogram',['../histogramscreenshots.html',1,'']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/pages_69.html b/ThirdParty/Qwt/doc/html/search/pages_69.html new file mode 100644 index 0000000000..5feff99655 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/pages_69.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/pages_69.js b/ThirdParty/Qwt/doc/html/search/pages_69.js new file mode 100644 index 0000000000..3d9235e133 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/pages_69.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['installing_20qwt',['Installing Qwt',['../qwtinstall.html',1,'']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/pages_71.html b/ThirdParty/Qwt/doc/html/search/pages_71.html new file mode 100644 index 0000000000..88a23f5b3b --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/pages_71.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/pages_71.js b/ThirdParty/Qwt/doc/html/search/pages_71.js new file mode 100644 index 0000000000..d573f521d1 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/pages_71.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['qwt_20_2d_20qt_20widgets_20for_20technical_20applications',['Qwt - Qt Widgets for Technical Applications',['../index.html',1,'']]], + ['qwt_20license_2c_20version_201_2e0',['Qwt License, Version 1.0',['../qwtlicense.html',1,'']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/pages_73.html b/ThirdParty/Qwt/doc/html/search/pages_73.html new file mode 100644 index 0000000000..4f6f002977 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/pages_73.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/pages_73.js b/ThirdParty/Qwt/doc/html/search/pages_73.js new file mode 100644 index 0000000000..922b37d0de --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/pages_73.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['scatter_20plot',['Scatter Plot',['../scatterscreenshots.html',1,'']]], + ['spectrogram_2c_20contour_20plot',['Spectrogram, Contour Plot',['../spectrogramscreenshots.html',1,'']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/pages_77.html b/ThirdParty/Qwt/doc/html/search/pages_77.html new file mode 100644 index 0000000000..664abf558d --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/pages_77.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/pages_77.js b/ThirdParty/Qwt/doc/html/search/pages_77.js new file mode 100644 index 0000000000..b13dafe4d3 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/pages_77.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['what_27s_20new_20in_20qwt_206_2e1',['What's new in Qwt 6.1',['../qwtchangelog.html',1,'']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/search.css b/ThirdParty/Qwt/doc/html/search/search.css new file mode 100644 index 0000000000..5b208eddd8 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/search.css @@ -0,0 +1,271 @@ +/*---------------- Search Box */ + +#FSearchBox { + float: left; +} + +#MSearchBox { + white-space : nowrap; + position: absolute; + float: none; + display: inline; + margin-top: 8px; + right: 0px; + width: 170px; + z-index: 102; + background-color: white; +} + +#MSearchBox .left +{ + display:block; + position:absolute; + left:10px; + width:20px; + height:19px; + background:url('search_l.png') no-repeat; + background-position:right; +} + +#MSearchSelect { + display:block; + position:absolute; + width:20px; + height:19px; +} + +.left #MSearchSelect { + left:4px; +} + +.right #MSearchSelect { + right:5px; +} + +#MSearchField { + display:block; + position:absolute; + height:19px; + background:url('search_m.png') repeat-x; + border:none; + width:116px; + margin-left:20px; + padding-left:4px; + color: #909090; + outline: none; + font: 9pt Arial, Verdana, sans-serif; +} + +#FSearchBox #MSearchField { + margin-left:15px; +} + +#MSearchBox .right { + display:block; + position:absolute; + right:10px; + top:0px; + width:20px; + height:19px; + background:url('search_r.png') no-repeat; + background-position:left; +} + +#MSearchClose { + display: none; + position: absolute; + top: 4px; + background : none; + border: none; + margin: 0px 4px 0px 0px; + padding: 0px 0px; + outline: none; +} + +.left #MSearchClose { + left: 6px; +} + +.right #MSearchClose { + right: 2px; +} + +.MSearchBoxActive #MSearchField { + color: #000000; +} + +/*---------------- Search filter selection */ + +#MSearchSelectWindow { + display: none; + position: absolute; + left: 0; top: 0; + border: 1px solid #90A5CE; + background-color: #F9FAFC; + z-index: 1; + padding-top: 4px; + padding-bottom: 4px; + -moz-border-radius: 4px; + -webkit-border-top-left-radius: 4px; + -webkit-border-top-right-radius: 4px; + -webkit-border-bottom-left-radius: 4px; + -webkit-border-bottom-right-radius: 4px; + -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); +} + +.SelectItem { + font: 8pt Arial, Verdana, sans-serif; + padding-left: 2px; + padding-right: 12px; + border: 0px; +} + +span.SelectionMark { + margin-right: 4px; + font-family: monospace; + outline-style: none; + text-decoration: none; +} + +a.SelectItem { + display: block; + outline-style: none; + color: #000000; + text-decoration: none; + padding-left: 6px; + padding-right: 12px; +} + +a.SelectItem:focus, +a.SelectItem:active { + color: #000000; + outline-style: none; + text-decoration: none; +} + +a.SelectItem:hover { + color: #FFFFFF; + background-color: #3D578C; + outline-style: none; + text-decoration: none; + cursor: pointer; + display: block; +} + +/*---------------- Search results window */ + +iframe#MSearchResults { + width: 60ex; + height: 15em; +} + +#MSearchResultsWindow { + display: none; + position: absolute; + left: 0; top: 0; + border: 1px solid #000; + background-color: #EEF1F7; +} + +/* ----------------------------------- */ + + +#SRIndex { + clear:both; + padding-bottom: 15px; +} + +.SREntry { + font-size: 10pt; + padding-left: 1ex; +} + +.SRPage .SREntry { + font-size: 8pt; + padding: 1px 5px; +} + +body.SRPage { + margin: 5px 2px; +} + +.SRChildren { + padding-left: 3ex; padding-bottom: .5em +} + +.SRPage .SRChildren { + display: none; +} + +.SRSymbol { + font-weight: bold; + color: #425E97; + font-family: Arial, Verdana, sans-serif; + text-decoration: none; + outline: none; +} + +a.SRScope { + display: block; + color: #425E97; + font-family: Arial, Verdana, sans-serif; + text-decoration: none; + outline: none; +} + +a.SRSymbol:focus, a.SRSymbol:active, +a.SRScope:focus, a.SRScope:active { + text-decoration: underline; +} + +span.SRScope { + padding-left: 4px; +} + +.SRPage .SRStatus { + padding: 2px 5px; + font-size: 8pt; + font-style: italic; +} + +.SRResult { + display: none; +} + +DIV.searchresults { + margin-left: 10px; + margin-right: 10px; +} + +/*---------------- External search page results */ + +.searchresult { + background-color: #F0F3F8; +} + +.pages b { + color: white; + padding: 5px 5px 3px 5px; + background-image: url("../tab_a.png"); + background-repeat: repeat-x; + text-shadow: 0 1px 1px #000000; +} + +.pages { + line-height: 17px; + margin-left: 4px; + text-decoration: none; +} + +.hl { + font-weight: bold; +} + +#searchresults { + margin-bottom: 20px; +} + +.searchpages { + margin-top: 10px; +} + diff --git a/ThirdParty/Qwt/doc/html/search/search.js b/ThirdParty/Qwt/doc/html/search/search.js new file mode 100644 index 0000000000..106aa8e80d --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/search.js @@ -0,0 +1,809 @@ +// Search script generated by doxygen +// Copyright (C) 2009 by Dimitri van Heesch. + +// The code in this file is loosly based on main.js, part of Natural Docs, +// which is Copyright (C) 2003-2008 Greg Valure +// Natural Docs is licensed under the GPL. + +var indexSectionsWithContent = +{ + 0: "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000111111111111111111111111110001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + 1: "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010100010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + 2: "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000111111111011111111111111110001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + 3: "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011100011011101000110100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + 4: "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000111100001001001101110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + 5: "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000111111011011101101110010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + 6: "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000111111111111111101111111100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + 7: "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001100011000000010100010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" +}; + +var indexSectionNames = +{ + 0: "all", + 1: "classes", + 2: "functions", + 3: "variables", + 4: "typedefs", + 5: "enums", + 6: "enumvalues", + 7: "pages" +}; + +function convertToId(search) +{ + var result = ''; + for (i=0;i do a search + { + this.Search(); + } + } + + this.OnSearchSelectKey = function(evt) + { + var e = (evt) ? evt : window.event; // for IE + if (e.keyCode==40 && this.searchIndex0) // Up + { + this.searchIndex--; + this.OnSelectItem(this.searchIndex); + } + else if (e.keyCode==13 || e.keyCode==27) + { + this.OnSelectItem(this.searchIndex); + this.CloseSelectionWindow(); + this.DOMSearchField().focus(); + } + return false; + } + + // --------- Actions + + // Closes the results window. + this.CloseResultsWindow = function() + { + this.DOMPopupSearchResultsWindow().style.display = 'none'; + this.DOMSearchClose().style.display = 'none'; + this.Activate(false); + } + + this.CloseSelectionWindow = function() + { + this.DOMSearchSelectWindow().style.display = 'none'; + } + + // Performs a search. + this.Search = function() + { + this.keyTimeout = 0; + + // strip leading whitespace + var searchValue = this.DOMSearchField().value.replace(/^ +/, ""); + + var code = searchValue.toLowerCase().charCodeAt(0); + var hexCode; + if (code<16) + { + hexCode="0"+code.toString(16); + } + else + { + hexCode=code.toString(16); + } + + var resultsPage; + var resultsPageWithSearch; + var hasResultsPage; + + if (indexSectionsWithContent[this.searchIndex].charAt(code) == '1') + { + resultsPage = this.resultsPath + '/' + indexSectionNames[this.searchIndex] + '_' + hexCode + '.html'; + resultsPageWithSearch = resultsPage+'?'+escape(searchValue); + hasResultsPage = true; + } + else // nothing available for this search term + { + resultsPage = this.resultsPath + '/nomatches.html'; + resultsPageWithSearch = resultsPage; + hasResultsPage = false; + } + + window.frames.MSearchResults.location = resultsPageWithSearch; + var domPopupSearchResultsWindow = this.DOMPopupSearchResultsWindow(); + + if (domPopupSearchResultsWindow.style.display!='block') + { + var domSearchBox = this.DOMSearchBox(); + this.DOMSearchClose().style.display = 'inline'; + if (this.insideFrame) + { + var domPopupSearchResults = this.DOMPopupSearchResults(); + domPopupSearchResultsWindow.style.position = 'relative'; + domPopupSearchResultsWindow.style.display = 'block'; + var width = document.body.clientWidth - 8; // the -8 is for IE :-( + domPopupSearchResultsWindow.style.width = width + 'px'; + domPopupSearchResults.style.width = width + 'px'; + } + else + { + var domPopupSearchResults = this.DOMPopupSearchResults(); + var left = getXPos(domSearchBox) + 150; // domSearchBox.offsetWidth; + var top = getYPos(domSearchBox) + 20; // domSearchBox.offsetHeight + 1; + domPopupSearchResultsWindow.style.display = 'block'; + left -= domPopupSearchResults.offsetWidth; + domPopupSearchResultsWindow.style.top = top + 'px'; + domPopupSearchResultsWindow.style.left = left + 'px'; + } + } + + this.lastSearchValue = searchValue; + this.lastResultsPage = resultsPage; + } + + // -------- Activation Functions + + // Activates or deactivates the search panel, resetting things to + // their default values if necessary. + this.Activate = function(isActive) + { + if (isActive || // open it + this.DOMPopupSearchResultsWindow().style.display == 'block' + ) + { + this.DOMSearchBox().className = 'MSearchBoxActive'; + + var searchField = this.DOMSearchField(); + + if (searchField.value == this.searchLabel) // clear "Search" term upon entry + { + searchField.value = ''; + this.searchActive = true; + } + } + else if (!isActive) // directly remove the panel + { + this.DOMSearchBox().className = 'MSearchBoxInactive'; + this.DOMSearchField().value = this.searchLabel; + this.searchActive = false; + this.lastSearchValue = '' + this.lastResultsPage = ''; + } + } +} + +// ----------------------------------------------------------------------- + +// The class that handles everything on the search results page. +function SearchResults(name) +{ + // The number of matches from the last run of . + this.lastMatchCount = 0; + this.lastKey = 0; + this.repeatOn = false; + + // Toggles the visibility of the passed element ID. + this.FindChildElement = function(id) + { + var parentElement = document.getElementById(id); + var element = parentElement.firstChild; + + while (element && element!=parentElement) + { + if (element.nodeName == 'DIV' && element.className == 'SRChildren') + { + return element; + } + + if (element.nodeName == 'DIV' && element.hasChildNodes()) + { + element = element.firstChild; + } + else if (element.nextSibling) + { + element = element.nextSibling; + } + else + { + do + { + element = element.parentNode; + } + while (element && element!=parentElement && !element.nextSibling); + + if (element && element!=parentElement) + { + element = element.nextSibling; + } + } + } + } + + this.Toggle = function(id) + { + var element = this.FindChildElement(id); + if (element) + { + if (element.style.display == 'block') + { + element.style.display = 'none'; + } + else + { + element.style.display = 'block'; + } + } + } + + // Searches for the passed string. If there is no parameter, + // it takes it from the URL query. + // + // Always returns true, since other documents may try to call it + // and that may or may not be possible. + this.Search = function(search) + { + if (!search) // get search word from URL + { + search = window.location.search; + search = search.substring(1); // Remove the leading '?' + search = unescape(search); + } + + search = search.replace(/^ +/, ""); // strip leading spaces + search = search.replace(/ +$/, ""); // strip trailing spaces + search = search.toLowerCase(); + search = convertToId(search); + + var resultRows = document.getElementsByTagName("div"); + var matches = 0; + + var i = 0; + while (i < resultRows.length) + { + var row = resultRows.item(i); + if (row.className == "SRResult") + { + var rowMatchName = row.id.toLowerCase(); + rowMatchName = rowMatchName.replace(/^sr\d*_/, ''); // strip 'sr123_' + + if (search.length<=rowMatchName.length && + rowMatchName.substr(0, search.length)==search) + { + row.style.display = 'block'; + matches++; + } + else + { + row.style.display = 'none'; + } + } + i++; + } + document.getElementById("Searching").style.display='none'; + if (matches == 0) // no results + { + document.getElementById("NoMatches").style.display='block'; + } + else // at least one result + { + document.getElementById("NoMatches").style.display='none'; + } + this.lastMatchCount = matches; + return true; + } + + // return the first item with index index or higher that is visible + this.NavNext = function(index) + { + var focusItem; + while (1) + { + var focusName = 'Item'+index; + focusItem = document.getElementById(focusName); + if (focusItem && focusItem.parentNode.parentNode.style.display=='block') + { + break; + } + else if (!focusItem) // last element + { + break; + } + focusItem=null; + index++; + } + return focusItem; + } + + this.NavPrev = function(index) + { + var focusItem; + while (1) + { + var focusName = 'Item'+index; + focusItem = document.getElementById(focusName); + if (focusItem && focusItem.parentNode.parentNode.style.display=='block') + { + break; + } + else if (!focusItem) // last element + { + break; + } + focusItem=null; + index--; + } + return focusItem; + } + + this.ProcessKeys = function(e) + { + if (e.type == "keydown") + { + this.repeatOn = false; + this.lastKey = e.keyCode; + } + else if (e.type == "keypress") + { + if (!this.repeatOn) + { + if (this.lastKey) this.repeatOn = true; + return false; // ignore first keypress after keydown + } + } + else if (e.type == "keyup") + { + this.lastKey = 0; + this.repeatOn = false; + } + return this.lastKey!=0; + } + + this.Nav = function(evt,itemIndex) + { + var e = (evt) ? evt : window.event; // for IE + if (e.keyCode==13) return true; + if (!this.ProcessKeys(e)) return false; + + if (this.lastKey==38) // Up + { + var newIndex = itemIndex-1; + var focusItem = this.NavPrev(newIndex); + if (focusItem) + { + var child = this.FindChildElement(focusItem.parentNode.parentNode.id); + if (child && child.style.display == 'block') // children visible + { + var n=0; + var tmpElem; + while (1) // search for last child + { + tmpElem = document.getElementById('Item'+newIndex+'_c'+n); + if (tmpElem) + { + focusItem = tmpElem; + } + else // found it! + { + break; + } + n++; + } + } + } + if (focusItem) + { + focusItem.focus(); + } + else // return focus to search field + { + parent.document.getElementById("MSearchField").focus(); + } + } + else if (this.lastKey==40) // Down + { + var newIndex = itemIndex+1; + var focusItem; + var item = document.getElementById('Item'+itemIndex); + var elem = this.FindChildElement(item.parentNode.parentNode.id); + if (elem && elem.style.display == 'block') // children visible + { + focusItem = document.getElementById('Item'+itemIndex+'_c0'); + } + if (!focusItem) focusItem = this.NavNext(newIndex); + if (focusItem) focusItem.focus(); + } + else if (this.lastKey==39) // Right + { + var item = document.getElementById('Item'+itemIndex); + var elem = this.FindChildElement(item.parentNode.parentNode.id); + if (elem) elem.style.display = 'block'; + } + else if (this.lastKey==37) // Left + { + var item = document.getElementById('Item'+itemIndex); + var elem = this.FindChildElement(item.parentNode.parentNode.id); + if (elem) elem.style.display = 'none'; + } + else if (this.lastKey==27) // Escape + { + parent.searchBox.CloseResultsWindow(); + parent.document.getElementById("MSearchField").focus(); + } + else if (this.lastKey==13) // Enter + { + return true; + } + return false; + } + + this.NavChild = function(evt,itemIndex,childIndex) + { + var e = (evt) ? evt : window.event; // for IE + if (e.keyCode==13) return true; + if (!this.ProcessKeys(e)) return false; + + if (this.lastKey==38) // Up + { + if (childIndex>0) + { + var newIndex = childIndex-1; + document.getElementById('Item'+itemIndex+'_c'+newIndex).focus(); + } + else // already at first child, jump to parent + { + document.getElementById('Item'+itemIndex).focus(); + } + } + else if (this.lastKey==40) // Down + { + var newIndex = childIndex+1; + var elem = document.getElementById('Item'+itemIndex+'_c'+newIndex); + if (!elem) // last child, jump to parent next parent + { + elem = this.NavNext(itemIndex+1); + } + if (elem) + { + elem.focus(); + } + } + else if (this.lastKey==27) // Escape + { + parent.searchBox.CloseResultsWindow(); + parent.document.getElementById("MSearchField").focus(); + } + else if (this.lastKey==13) // Enter + { + return true; + } + return false; + } +} + +function setKeyActions(elem,action) +{ + elem.setAttribute('onkeydown',action); + elem.setAttribute('onkeypress',action); + elem.setAttribute('onkeyup',action); +} + +function setClassAttr(elem,attr) +{ + elem.setAttribute('class',attr); + elem.setAttribute('className',attr); +} + +function createResults() +{ + var results = document.getElementById("SRResults"); + for (var e=0; e + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/typedefs_61.js b/ThirdParty/Qwt/doc/html/search/typedefs_61.js new file mode 100644 index 0000000000..696a7d1cfa --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/typedefs_61.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['attributes',['Attributes',['../class_qwt_plot_direct_painter.html#a26a66587377067b3bc0539274370693f',1,'QwtPlotDirectPainter::Attributes()'],['../class_qwt_scale_engine.html#a798f5f1420019d33baa799d26bca0255',1,'QwtScaleEngine::Attributes()']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/typedefs_62.html b/ThirdParty/Qwt/doc/html/search/typedefs_62.html new file mode 100644 index 0000000000..208fc59427 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/typedefs_62.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/typedefs_62.js b/ThirdParty/Qwt/doc/html/search/typedefs_62.js new file mode 100644 index 0000000000..2d3f1d1c68 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/typedefs_62.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['borderflags',['BorderFlags',['../class_qwt_interval.html#a678a26fcaa91cca596d9aebcbf5776c9',1,'QwtInterval']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/typedefs_63.html b/ThirdParty/Qwt/doc/html/search/typedefs_63.html new file mode 100644 index 0000000000..4313190942 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/typedefs_63.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/typedefs_63.js b/ThirdParty/Qwt/doc/html/search/typedefs_63.js new file mode 100644 index 0000000000..5553e4c585 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/typedefs_63.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['conrecflags',['ConrecFlags',['../class_qwt_raster_data.html#a8101f4a0c71813d49fcdc73a457c4874',1,'QwtRasterData']]], + ['contourlines',['ContourLines',['../class_qwt_raster_data.html#adc6679160a229992f0870a2b784985f3',1,'QwtRasterData']]], + ['curveattributes',['CurveAttributes',['../class_qwt_plot_curve.html#a43f465d035a5125d582768944287c70c',1,'QwtPlotCurve']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/typedefs_64.html b/ThirdParty/Qwt/doc/html/search/typedefs_64.html new file mode 100644 index 0000000000..79948147e5 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/typedefs_64.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/typedefs_64.js b/ThirdParty/Qwt/doc/html/search/typedefs_64.js new file mode 100644 index 0000000000..787fe71d89 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/typedefs_64.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['discardflags',['DiscardFlags',['../class_qwt_plot_renderer.html#aa61638c08ef926c0148dd12c9f830b2d',1,'QwtPlotRenderer']]], + ['displaymodes',['DisplayModes',['../class_qwt_plot_spectrogram.html#a245a6d1281abe84d177d61be0698db55',1,'QwtPlotSpectrogram']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/typedefs_69.html b/ThirdParty/Qwt/doc/html/search/typedefs_69.html new file mode 100644 index 0000000000..77acf71ad7 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/typedefs_69.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/typedefs_69.js b/ThirdParty/Qwt/doc/html/search/typedefs_69.js new file mode 100644 index 0000000000..d8a3409501 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/typedefs_69.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['itemattributes',['ItemAttributes',['../class_qwt_plot_item.html#af356dc13c7838c7437334e199a356764',1,'QwtPlotItem']]], + ['iteminterests',['ItemInterests',['../class_qwt_plot_item.html#a6a0c870664f074f342422859638c1228',1,'QwtPlotItem']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/typedefs_6c.html b/ThirdParty/Qwt/doc/html/search/typedefs_6c.html new file mode 100644 index 0000000000..9e5f273a1f --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/typedefs_6c.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/typedefs_6c.js b/ThirdParty/Qwt/doc/html/search/typedefs_6c.js new file mode 100644 index 0000000000..5a67dfa399 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/typedefs_6c.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['layoutattributes',['LayoutAttributes',['../class_qwt_text.html#aadd451b81d506c5bbefdddb8a100b9a3',1,'QwtText']]], + ['layoutflags',['LayoutFlags',['../class_qwt_plot_renderer.html#a20cf36bbea6b03a023d34c25b8b4b295',1,'QwtPlotRenderer::LayoutFlags()'],['../class_qwt_scale_widget.html#a19dcd8adcfd10fe26e021fa47e22b843',1,'QwtScaleWidget::LayoutFlags()']]], + ['legendattributes',['LegendAttributes',['../class_qwt_plot_curve.html#aa9b27e27ddc27466eed70485e690daa6',1,'QwtPlotCurve']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/typedefs_6f.html b/ThirdParty/Qwt/doc/html/search/typedefs_6f.html new file mode 100644 index 0000000000..509da63e1f --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/typedefs_6f.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/typedefs_6f.js b/ThirdParty/Qwt/doc/html/search/typedefs_6f.js new file mode 100644 index 0000000000..1dcf4ca2b5 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/typedefs_6f.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['options',['Options',['../class_qwt_plot_layout.html#aa43457184903f3aaa58e6e073622ef52',1,'QwtPlotLayout']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/typedefs_70.html b/ThirdParty/Qwt/doc/html/search/typedefs_70.html new file mode 100644 index 0000000000..32b2dfcd7d --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/typedefs_70.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/typedefs_70.js b/ThirdParty/Qwt/doc/html/search/typedefs_70.js new file mode 100644 index 0000000000..16504884af --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/typedefs_70.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['paintattributes',['PaintAttributes',['../class_qwt_plot_canvas.html#ac007a0126efb62443e52905d3157102d',1,'QwtPlotCanvas::PaintAttributes()'],['../class_qwt_plot_curve.html#a39ba40485087294c775a367d859b6237',1,'QwtPlotCurve::PaintAttributes()'],['../class_qwt_plot_interval_curve.html#a1fa99e81e5c1b687aec620e9b8746d6c',1,'QwtPlotIntervalCurve::PaintAttributes()'],['../class_qwt_plot_raster_item.html#a6bde441d571c4943da01765dec2d4b4a',1,'QwtPlotRasterItem::PaintAttributes()'],['../class_qwt_plot_shape_item.html#af4ab987535185011cf4e5587094a5b40',1,'QwtPlotShapeItem::PaintAttributes()'],['../class_qwt_plot_spectro_curve.html#a78b3bf4c7d055f2f00bd371e9ddc4f2f',1,'QwtPlotSpectroCurve::PaintAttributes()'],['../class_qwt_plot_trading_curve.html#a284bcaa3994148bda302e5fec17467d8',1,'QwtPlotTradingCurve::PaintAttributes()'],['../class_qwt_text.html#a0d239ca5c8e0cd3c748325ad453bb13f',1,'QwtText::PaintAttributes()']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/typedefs_72.html b/ThirdParty/Qwt/doc/html/search/typedefs_72.html new file mode 100644 index 0000000000..22bf694e23 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/typedefs_72.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/typedefs_72.js b/ThirdParty/Qwt/doc/html/search/typedefs_72.js new file mode 100644 index 0000000000..ae2d7926b0 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/typedefs_72.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['renderhints',['RenderHints',['../class_qwt_graphic.html#ac239a34c1c3fe47a3a57b70331c0d2fa',1,'QwtGraphic::RenderHints()'],['../class_qwt_plot_item.html#a40cf900701d3a68948b00316689616d1',1,'QwtPlotItem::RenderHints()']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/typedefs_73.html b/ThirdParty/Qwt/doc/html/search/typedefs_73.html new file mode 100644 index 0000000000..0bed01ebe0 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/typedefs_73.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/typedefs_73.js b/ThirdParty/Qwt/doc/html/search/typedefs_73.js new file mode 100644 index 0000000000..f1d7e34da2 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/typedefs_73.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['scalecomponents',['ScaleComponents',['../class_qwt_abstract_scale_draw.html#a0dd3ccdfa074fb6b1781b84ed2a4729a',1,'QwtAbstractScaleDraw']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/typedefs_74.html b/ThirdParty/Qwt/doc/html/search/typedefs_74.html new file mode 100644 index 0000000000..b2f6d2a098 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/typedefs_74.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/typedefs_74.js b/ThirdParty/Qwt/doc/html/search/typedefs_74.js new file mode 100644 index 0000000000..d1a0ac0649 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/typedefs_74.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['transformationflags',['TransformationFlags',['../class_qwt_point_mapper.html#af7a8c38f6dd7faf8396a87a882e2f967',1,'QwtPointMapper']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/variables_62.html b/ThirdParty/Qwt/doc/html/search/variables_62.html new file mode 100644 index 0000000000..ff4152508c --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/variables_62.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/variables_62.js b/ThirdParty/Qwt/doc/html/search/variables_62.js new file mode 100644 index 0000000000..caa50ce6ab --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/variables_62.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['button',['button',['../class_qwt_event_pattern_1_1_mouse_pattern.html#ade5b5bdb3bf76814f003c02ea11c5924',1,'QwtEventPattern::MousePattern']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/variables_63.html b/ThirdParty/Qwt/doc/html/search/variables_63.html new file mode 100644 index 0000000000..422085c127 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/variables_63.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/variables_63.js b/ThirdParty/Qwt/doc/html/search/variables_63.js new file mode 100644 index 0000000000..7a336ad27b --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/variables_63.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['close',['close',['../class_qwt_o_h_l_c_sample.html#a7627b9a618065a82e96e651406f4fac4',1,'QwtOHLCSample']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/variables_64.html b/ThirdParty/Qwt/doc/html/search/variables_64.html new file mode 100644 index 0000000000..df4414b92e --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/variables_64.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/variables_64.js b/ThirdParty/Qwt/doc/html/search/variables_64.js new file mode 100644 index 0000000000..7326f39119 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/variables_64.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['d_5fboundingrect',['d_boundingRect',['../class_qwt_series_data.html#a24fbbcb0baa0c728117d2e6764d00414',1,'QwtSeriesData']]], + ['d_5fsamples',['d_samples',['../class_qwt_array_series_data.html#a86ccb32fa8c9b3bb9cb92b6040b0c490',1,'QwtArraySeriesData']]], + ['direction',['direction',['../class_qwt_column_rect.html#aa630854df28955f2ee91c94524b079d7',1,'QwtColumnRect']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/variables_68.html b/ThirdParty/Qwt/doc/html/search/variables_68.html new file mode 100644 index 0000000000..2f0a862b90 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/variables_68.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/variables_68.js b/ThirdParty/Qwt/doc/html/search/variables_68.js new file mode 100644 index 0000000000..818fe3393c --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/variables_68.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['high',['high',['../class_qwt_o_h_l_c_sample.html#a4b23c1c6250364d4c58b6fc23ac1cdff',1,'QwtOHLCSample']]], + ['hinterval',['hInterval',['../class_qwt_column_rect.html#a16a24ece2aa70fc763d08e220608d63a',1,'QwtColumnRect']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/variables_69.html b/ThirdParty/Qwt/doc/html/search/variables_69.html new file mode 100644 index 0000000000..44c2cd1eee --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/variables_69.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/variables_69.js b/ThirdParty/Qwt/doc/html/search/variables_69.js new file mode 100644 index 0000000000..916b90185b --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/variables_69.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['interval',['interval',['../class_qwt_interval_sample.html#a264492c8f0ad3cec0b9d4d58b9a97236',1,'QwtIntervalSample']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/variables_6b.html b/ThirdParty/Qwt/doc/html/search/variables_6b.html new file mode 100644 index 0000000000..d1001a9691 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/variables_6b.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/variables_6b.js b/ThirdParty/Qwt/doc/html/search/variables_6b.js new file mode 100644 index 0000000000..ab2cfd4426 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/variables_6b.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['key',['key',['../class_qwt_event_pattern_1_1_key_pattern.html#af13072b058c3abbb591450b82f049dd6',1,'QwtEventPattern::KeyPattern']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/variables_6c.html b/ThirdParty/Qwt/doc/html/search/variables_6c.html new file mode 100644 index 0000000000..8d08e812e0 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/variables_6c.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/variables_6c.js b/ThirdParty/Qwt/doc/html/search/variables_6c.js new file mode 100644 index 0000000000..5c282af6a0 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/variables_6c.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['logmax',['LogMax',['../class_qwt_log_transform.html#ae5b7d96e9a765986cf1fc4b4c1fc7915',1,'QwtLogTransform']]], + ['logmin',['LogMin',['../class_qwt_log_transform.html#ad16ce32a68b714955412dc8b1b8f6622',1,'QwtLogTransform']]], + ['low',['low',['../class_qwt_o_h_l_c_sample.html#aedac8489a18dfae092c010360c53ad7d',1,'QwtOHLCSample']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/variables_6d.html b/ThirdParty/Qwt/doc/html/search/variables_6d.html new file mode 100644 index 0000000000..1b8f1a83ad --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/variables_6d.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/variables_6d.js b/ThirdParty/Qwt/doc/html/search/variables_6d.js new file mode 100644 index 0000000000..98b8212756 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/variables_6d.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['modifiers',['modifiers',['../class_qwt_event_pattern_1_1_mouse_pattern.html#ad12c724aac7bba9f16540c604dc108f9',1,'QwtEventPattern::MousePattern::modifiers()'],['../class_qwt_event_pattern_1_1_key_pattern.html#a1db88ed291d4ba49fa84e32e86fa10d1',1,'QwtEventPattern::KeyPattern::modifiers()']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/variables_6f.html b/ThirdParty/Qwt/doc/html/search/variables_6f.html new file mode 100644 index 0000000000..f06e2e0f4e --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/variables_6f.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/variables_6f.js b/ThirdParty/Qwt/doc/html/search/variables_6f.js new file mode 100644 index 0000000000..4380fe95be --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/variables_6f.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['open',['open',['../class_qwt_o_h_l_c_sample.html#a71b133fe8f7676b2ff7b17e39d669f95',1,'QwtOHLCSample']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/variables_73.html b/ThirdParty/Qwt/doc/html/search/variables_73.html new file mode 100644 index 0000000000..388a6d74b9 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/variables_73.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/variables_73.js b/ThirdParty/Qwt/doc/html/search/variables_73.js new file mode 100644 index 0000000000..601763be24 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/variables_73.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['set',['set',['../class_qwt_set_sample.html#af05cfa9fc52e7798f6594ba1bbbcd16b',1,'QwtSetSample']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/variables_74.html b/ThirdParty/Qwt/doc/html/search/variables_74.html new file mode 100644 index 0000000000..1665fb806e --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/variables_74.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/variables_74.js b/ThirdParty/Qwt/doc/html/search/variables_74.js new file mode 100644 index 0000000000..32f6da3e4b --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/variables_74.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['time',['time',['../class_qwt_o_h_l_c_sample.html#a7d457c0a7d71f90539bf6233a19c1df4',1,'QwtOHLCSample']]] +]; diff --git a/ThirdParty/Qwt/doc/html/search/variables_76.html b/ThirdParty/Qwt/doc/html/search/variables_76.html new file mode 100644 index 0000000000..8af2374616 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/variables_76.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/ThirdParty/Qwt/doc/html/search/variables_76.js b/ThirdParty/Qwt/doc/html/search/variables_76.js new file mode 100644 index 0000000000..880542b10c --- /dev/null +++ b/ThirdParty/Qwt/doc/html/search/variables_76.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['value',['value',['../class_qwt_interval_sample.html#ad1e098d87833c45636dc96f9c5c14245',1,'QwtIntervalSample::value()'],['../class_qwt_set_sample.html#a5bff5286dddfa1f2070da64fe619859f',1,'QwtSetSample::value()']]], + ['vinterval',['vInterval',['../class_qwt_column_rect.html#a0dcd7826655c73da74a8f9ad87f3d62a',1,'QwtColumnRect']]] +]; diff --git a/ThirdParty/Qwt/doc/html/sinus.png b/ThirdParty/Qwt/doc/html/sinus.png new file mode 100644 index 0000000000..d8edc5dcb5 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/sinus.png differ diff --git a/ThirdParty/Qwt/doc/html/sliders.png b/ThirdParty/Qwt/doc/html/sliders.png new file mode 100644 index 0000000000..9b62a746c8 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/sliders.png differ diff --git a/ThirdParty/Qwt/doc/html/spectrogram1.png b/ThirdParty/Qwt/doc/html/spectrogram1.png new file mode 100644 index 0000000000..e2774e93bb Binary files /dev/null and b/ThirdParty/Qwt/doc/html/spectrogram1.png differ diff --git a/ThirdParty/Qwt/doc/html/spectrogram2.png b/ThirdParty/Qwt/doc/html/spectrogram2.png new file mode 100644 index 0000000000..dcc33857d7 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/spectrogram2.png differ diff --git a/ThirdParty/Qwt/doc/html/spectrogram3.png b/ThirdParty/Qwt/doc/html/spectrogram3.png new file mode 100644 index 0000000000..9c985a9e95 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/spectrogram3.png differ diff --git a/ThirdParty/Qwt/doc/html/spectrogramscreenshots.html b/ThirdParty/Qwt/doc/html/spectrogramscreenshots.html new file mode 100644 index 0000000000..26964b3d39 --- /dev/null +++ b/ThirdParty/Qwt/doc/html/spectrogramscreenshots.html @@ -0,0 +1,99 @@ + + + + + + +Qwt User's Guide: Spectrogram, Contour Plot + + + + + + + + + +
+
+ + + + + + +
+
Qwt User's Guide +  6.1.0 +
+
+
+ + + + + + + + +
+ +
+ +
+
+
+
Spectrogram, Contour Plot
+
+
+
+spectrogram1.png +
+
+spectrogram2.png +
+
+spectrogram3.png +
+

/*!

+
+ + + + diff --git a/ThirdParty/Qwt/doc/html/sync_off.png b/ThirdParty/Qwt/doc/html/sync_off.png new file mode 100644 index 0000000000..3b443fc628 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/sync_off.png differ diff --git a/ThirdParty/Qwt/doc/html/sync_on.png b/ThirdParty/Qwt/doc/html/sync_on.png new file mode 100644 index 0000000000..e08320fb64 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/sync_on.png differ diff --git a/ThirdParty/Qwt/doc/html/sysinfo.png b/ThirdParty/Qwt/doc/html/sysinfo.png new file mode 100644 index 0000000000..562aa5feb8 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/sysinfo.png differ diff --git a/ThirdParty/Qwt/doc/html/tab_a.png b/ThirdParty/Qwt/doc/html/tab_a.png new file mode 100644 index 0000000000..3b725c41c5 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/tab_a.png differ diff --git a/ThirdParty/Qwt/doc/html/tab_b.png b/ThirdParty/Qwt/doc/html/tab_b.png new file mode 100644 index 0000000000..e2b4a8638c Binary files /dev/null and b/ThirdParty/Qwt/doc/html/tab_b.png differ diff --git a/ThirdParty/Qwt/doc/html/tab_h.png b/ThirdParty/Qwt/doc/html/tab_h.png new file mode 100644 index 0000000000..fd5cb70548 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/tab_h.png differ diff --git a/ThirdParty/Qwt/doc/html/tab_s.png b/ThirdParty/Qwt/doc/html/tab_s.png new file mode 100644 index 0000000000..ab478c95b6 Binary files /dev/null and b/ThirdParty/Qwt/doc/html/tab_s.png differ diff --git a/ThirdParty/Qwt/doc/html/tabs.css b/ThirdParty/Qwt/doc/html/tabs.css new file mode 100644 index 0000000000..9cf578f23a --- /dev/null +++ b/ThirdParty/Qwt/doc/html/tabs.css @@ -0,0 +1,60 @@ +.tabs, .tabs2, .tabs3 { + background-image: url('tab_b.png'); + width: 100%; + z-index: 101; + font-size: 13px; + font-family: 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif; +} + +.tabs2 { + font-size: 10px; +} +.tabs3 { + font-size: 9px; +} + +.tablist { + margin: 0; + padding: 0; + display: table; +} + +.tablist li { + float: left; + display: table-cell; + background-image: url('tab_b.png'); + line-height: 36px; + list-style: none; +} + +.tablist a { + display: block; + padding: 0 20px; + font-weight: bold; + background-image:url('tab_s.png'); + background-repeat:no-repeat; + background-position:right; + color: #283A5D; + text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); + text-decoration: none; + outline: none; +} + +.tabs3 .tablist a { + padding: 0 10px; +} + +.tablist a:hover { + background-image: url('tab_h.png'); + background-repeat:repeat-x; + color: #fff; + text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0); + text-decoration: none; +} + +.tablist li.current a { + background-image: url('tab_a.png'); + background-repeat:repeat-x; + color: #fff; + text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0); +} diff --git a/ThirdParty/Qwt/doc/install.dox b/ThirdParty/Qwt/doc/install.dox new file mode 100644 index 0000000000..5435766395 --- /dev/null +++ b/ThirdParty/Qwt/doc/install.dox @@ -0,0 +1,305 @@ +/*! +\page qwtinstall Installing Qwt + +\tableofcontents + +\section DOWNLOAD Download + + Stable Qwt releases are available from the + Qwt project page. + + Qwt-6.1.0 consists of 4 files: + + - qwt-6.1.0.zip\n + Zip file with the Qwt sources and the html documentation for Windows + + - qwt-6.1.0.tar.bz2\n + Compressed tar file with the Qwt sources and the html documentation + for UNIX systems ( Linux, Mac, ... ) + + - qwt-6.1.0.pdf\n + Qwt documentation as PDF document. + + - qwt-6.1.0.qch\n + Qwt documentation as Qt Compressed Help document, that can be loaded into + the Qt Assistant or Creator. In the Qt Creator context sensitive help will be + available like for Qt classes. + + Precompiled Qwt Designer plugins, that are compatible with some binary packages + of the Qt Creator: + + - qwtdesigner-6.1.0-*.zip + + +\section INSTALL Installing Qwt + + Beside headers, libraries and the html version of the class documentation a proper + Qwt installation contains a Designer plugin and a Qwt features file for building + applications using Qwt. + + All files will be copied to an installation directory, that is configurable + by editing qwtconfig.pri. Its default settings is: + + - Windows\n + C:\\Qwt-6.1.0 + + - Unix like systems\n + /usr/local/qwt-6.1.0 + + For the rest of the document this install path will be written as ${QWT_ROOT} + and needs to be replaced by the real path in all commands below. + + It is not unlikely, to have more than one installation of Qwt + on the same system. F.e for using the Qwt Designer plugin in the Qt Creator + a version of Qwt is necessary with the same Qt and compiler combination, that had + been used for building the Qt Creator ( see "Help->About Qt Creator ..." ). + + Installing Qwt is done in 3 steps, that are quite common on UNIX systems. + + -# Configuration\n + In the configuration step all parameters are set to control how + to build and install Qwt + -# Build\n + In the build step binaries are built from the source files. + -# Installation\n + The installation copies and rearranges all files that are necessary to build + Qwt applications to a target directory. + + The installation doesn't modify the system beside copying files to a + directory in a proper way. After removing build and installation directories the + system is in the same state as it was before. + +\subsection CONFIGSUBSECTION Configuration + + Configuring Qwt has to be done by editing the Project files used for building: + + - qwtbuild.pri\n + qwtbuild.pri contains settings for how to build Qwt. All settings + of this file are only for building Qwt itself and doesn't have an impact + on how an application using Qwt is built. Usually its default settings + doesn't need to be modified. + + - qwtconfig.pri\n + qwtconfig.pri defines what modules of Qwt will be built and where to + install them. qwtconfig.pri gets installed together with the Qwt features + file qwt.prf and all its settings are known to project files for building + Qwt applications. + + In qwtconfig.pri the meaning of each option is explained in detail - it's worth + reading it before running into problems later. + +\subsection BUILDSUBSECTION Build and installation + + The Qt Creator is a graphical frontend for calling qmake/make and - technically - + it could be used for building and installing Qwt. But as this way requires a lot + more understanding of details the following step by step instructions are for + the easier way using the command line. + +\subsubsection qwtinstall-unix Unix-like systems + + The first step before creating the Makefile is to check that the correct version + of qmake is used. F.e. on older Linux distribution you often find a Qt3 qmake + and in the path. + + The default setting of qmake is to generate a makefile that builds Qwt for the + same environment where the version of qmake has been built for. + So creating a makefile usually means something like: + +\code + cd qwt-6.1.0 + /usr/local/Qt-5.0.1/bin/qmake qwt.pro +\endcode + + The generated Makefile includes all paths related to the chosen Qt version + and the next step is: + +\code + make +\endcode + ( On multicore systems you can speed up building the Qwt libraries with running several + jobs simultaneously: f.e. "make -j4" on a dual core. ) + + + Finally you have to install everything below the directories you have specified + in qwtconfig.pri. Usually this is one of the system directories ( /usr/local, /opt, ... ) + where you don't have write permission and then the installation + needs to be done as root: + +\code + sudo make install +\endcode + ( On systems where sudo is not supported you can do the same with: su -c "make install" ) + +\subsubsection qwtinstall-windows Windows + + Qt packages offer a command line interface, that can be found in the Qt application + menu: f.e "All Programs -> Qt -> Command Prompt". It is not mandatory to use it, but + probably the easiest way as it offers an environment, where everything is + initialized for a version of Qt ( f.e qmake is in the PATH ). + + Creating a makefile usually means something like: + +\code + cd qwt-6.1.0 + qmake qwt.pro +\endcode + + The generated makefile includes all paths related to the chosen Qt version. + +\paragraph qwtinstall-windows-mingw MinGW + + For MinGW builds the name of the make tool is "mingw32-make" + +\code + mingw32-make +\endcode + ( On multicore systems you can speed up building the Qwt libraries with running several + jobs simultaneously: "mingw32-make -j" ) + + Finally you have to install everything below the directories you have specified + in qwtconfig.pri. + +\code + mingw32-make install +\endcode + + +\paragraph qwtinstall-windows-msvc MSVC + + For MSVC builds the name of the make tool is "nmake". Alternatively + it is possible to use "jom" ( http://qt-project.org/wiki/jom ), + that is usually included in a Qt Creator package. + +\code + nmake +\endcode + + Finally you have to install everything below the directories you have specified + in qwtconfig.pri. + +\code + nmake install +\endcode + + +\section INTEGRATION Qwt and the Qt tool chain + +\subsection USEPLUGIN Designer plugin + + The Designer plugin and the corresponding Qwt library ( if the plugin has not + been built self containing ) have to be compatible with Qt version of the application + loading it ( usually the Qt Creator ) - what is often a different version of the + Qt libraries you want to build your application with. F.e on Windows the Qt Creator + is usually built with a MSVC compiler - even if included in a MinGW package ! + + To help Qt Designer/Creator with locating the Qwt Designer plugin + you have to set the environment variable QT_PLUGIN_PATH, modify qt.conf - + or install the plugin to one of the application default paths. + + The Qt documentation explains all options in detail: + + - http://qt-project.org/doc/qt-5.0/qtdoc/deployment-plugins.html + - http://qt-project.org/doc/qtcreator-2.7/adding-plugins.html. + + F.e. on a Linux system you could add the following lines to .bashrc: + +\code + QT_PLUGIN_PATH="${QWT_ROOT}/plugins:$QT_PLUGIN_PATH" + export QT_PLUGIN_PATH +\endcode + + When the plugin has not been built including the Qwt library + ( see QwtDesignerSelfContained in qwtconfig.pri ) + the Qt Designer/Creator also needs to locate the Qwt libraries. On Unix systems the + path to the installed library is compiled into the plugin ( see rpath, ldd ), but on + Windows the Qt Creator needs to be configured ( ( \ref RUNAPP ) in the same way as for + any application using Qwt. + + In case of problems the diagnostics of Qt Creator and Designer are very limited + ( usually none ), but setting the environment variable QT_DEBUG_PLUGINS might help. + In the Qt Creator it is possible to check which plugins were loaded + successfully and for certain problems it also lists those that were recognized + but failed ( Tools > Form Editor > About Qt Designer Plugins ). + +\subsection USEHELP Online Help + + The Qwt class documentation can be loaded into the Qt Creator: + + - open the settings dialog from the Tools->Options menu + - raise the tab "Help->Documentation". + - press the Add button and select qwt-6.1.0.qch. + + Now the context sensitive help ( F1 ) works for Qwt classes. + + For browsing the documentation in the Qt Assistant: + + - open the settings dialog from the Edit->Preferences menu + - raise the tab Documentation. + - press the Add button and select qwt-6.1.0.qch. + +\section COMPILEANDLINKAPP Building a Qwt application + +All flags and settings that are necessary to compile and link an application using Qwt +can be found in the file ${QWT_ROOT}/features/qwt.prf. + +When using qmake it can included from the application project file in 2 different ways: + + - Adding Qwt as qmake feature\n\n + When using the qmake feature mechanism you can bind a special version + of qmake to a special installation of Qwt without having to add + this dependency to the application project. + How to add Qwt as feature is documented in the + qmake docs. + + After adding Qwt as a feature f.e on Linux as a persistent property .... +@code + qmake -set QMAKEFEATURES ${QWT_ROOT}/features +@endcode + .. the following line can be added to the application project file: +\code + CONFIG += qwt +\endcode + + - Including qwt.prf in the application project file\n\n + Instead of using qwt.prf as qmake feature it can be included from + the application project file:\n\n +\code +include ( ${QWT_ROOT}/features/qwt.prf ) +\endcode \n + The advantage of using a direct include is, that all settings of qwt.prf + are known to the application project file ( qmake features are included after the + application project file has been parsed ) and it can be implemented depending on - + f.e. settings made in qwtconfig.pri. + +On Unix platforms it is possible to link a runtime path into the executable, so that the +location of the Qwt libraries can be found without having to configure a runtime environment: + - QMAKE_LFLAGS_RPATH + - QMAKE_RPATH + - QMAKE_RPATHDIR + +\section RUNAPP Running a Qwt application + + When using Qwt as shared library ( DLL ) the + dynamic linker has to find + it according to the rules of the operating system. + +\subsection RUNWINDOWS Windows + +The only reasonable way to configure the runtime environment - without having to copy the +Qwt libraries around - is to modify the PATH variable. F.e. this could be done by adding +the following line to some batch file: + +\code +set PATH=%PATH%;${QWT_ROOT}\lib +\endcode + +\subsection RUNLINUX GNU/Linux + + Read the documentation about: + + - ldconfig + - /etc/ld.so.conf + - LD_LIBRARY_PATH + + Using the ldd command a configuration can be tested. +*/ diff --git a/ThirdParty/Qwt/doc/qwt.dox b/ThirdParty/Qwt/doc/qwt.dox new file mode 100644 index 0000000000..0d6dbc23f6 --- /dev/null +++ b/ThirdParty/Qwt/doc/qwt.dox @@ -0,0 +1,153 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +/* + This file contains NO source code, just some documentation for doxygen to + parse. +*/ + +/*! + \mainpage Qwt - Qt Widgets for Technical Applications + +The Qwt library contains GUI Components and utility classes which are primarily +useful for programs with a technical background. Beside a framework for 2D plots +it provides scales, sliders, dials, compasses, thermometers, wheels and knobs +to control or display values, arrays, or ranges of type double. + + \image html plot.png + + \if homepage + \section homepage Project page + The official project page is hosted at + sourceforge + \endif + + \section license License + + Qwt is distributed under the terms of the \ref qwtlicense. + + \section platforms Platforms + + Qwt 6.1 might be usable in all environments where you find + Qt. + It is compatible with Qt4 ( >= 4.4 ) and Qt5. + + \section changelogonmainpage What's new + Read the \ref qwtchangelog "summary" of the most important changes. + + \section screenshotsonmainpage Screenshots + - \ref curvescreenshots\n + - \ref scatterscreenshots\n + - \ref spectrogramscreenshots\n + - \ref histogramscreenshots\n + - \ref controlscreenshots\n + + \latexonly Screenshots are only available in the HTML docs.\endlatexonly + + \section downloads Downloads + Stable releases or prereleases are available at the Qwt project page. + + For getting a snapshot with all bugfixes for the latest 5.2 release: + \code svn checkout svn://svn.code.sf.net/p/qwt/code/branches/qwt-5.2 \endcode + + For getting a snapshot with all bugfixes for the latest 6.1 release: + \code svn checkout svn://svn.code.sf.net/p/qwt/code/branches/qwt-6.1 \endcode + + For getting a development snapshot from the SVN repository: + \code svn checkout svn://svn.code.sf.net/p/qwt/code/trunk/qwt \endcode + + \section installonmainpage Installation + + Qwt doesn't distribute binary packages, but today all major Linux distributors + offer one. Note, that these packages often don't include the examples. + + When no binary packages are available ( f.e. on Windows ) Qwt needs to be + \ref qwtinstall "compiled and installed" on the target system. + + \section support Support + - Mailing list\n + For all kind of Qwt related questions use the Qwt mailing list.\n + If you prefer newsgroups use the mail to news gateway of Gmane. + + - Forum\n + Qt Centre is a great resource for Qt + related questions. It has a sub forum, that is dedicated to + Qwt related questions. + + - Individual support\n + If you are looking for individual support, or need someone who implements + your Qwt component/application contact support@qwt-project.org. Sending + requests to this address without a good reason for not using public + support channels might be silently ignored. + + \section relatedprojects Related Projects + + QwtPolar, a polar plot widget.\n + QwtPlot3D, an OpenGL 3D plot widget.\n + + \section donations Donations + + Sourceforge offers a Donation System via PayPal. + You can use it, if you like to support the development of Qwt. + + \section credits Credits: + \par Authors: + Uwe Rathmann, Josef Wilgen ( <= Qwt 0.2 ) + \par Project admin: + Uwe Rathmann \ +*/ + +/*! + \page qwtlicense Qwt License, Version 1.0 + \include "COPYING" +*/ + +/*! + \page curvescreenshots Curve Plots + \image html plot.png + + \image html sinus.png + + \image html cpuplot.png + + \image html graph.png + + \image html curves.png +*/ + +/*! + \page scatterscreenshots Scatter Plot + \image html scatterplot.png +*/ + +/*! + \page spectrogramscreenshots Spectrogram, Contour Plot + \image html spectrogram1.png + + \image html spectrogram2.png + + \image html spectrogram3.png + +/*! + \page histogramscreenshots Histogram + \image html histogram.png +*/ + +/*! + \page controlscreenshots Dials, Compasses, Knobs, Wheels, Sliders, Thermos + \image html radio.png + + \image html sliders.png + + \image html dials1.png + + \image html dials2.png + + \image html sysinfo.png +*/ diff --git a/ThirdParty/Qwt/examples/animation/animation.pro b/ThirdParty/Qwt/examples/animation/animation.pro new file mode 100644 index 0000000000..d8cebc69e6 --- /dev/null +++ b/ThirdParty/Qwt/examples/animation/animation.pro @@ -0,0 +1,19 @@ +################################################################ +# Qwt Widget Library +# Copyright (C) 1997 Josef Wilgen +# Copyright (C) 2002 Uwe Rathmann +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the Qwt License, Version 1.0 +################################################################ + +include( $${PWD}/../examples.pri ) + +TARGET = animation + +HEADERS = \ + plot.h + +SOURCES = \ + plot.cpp \ + main.cpp diff --git a/ThirdParty/Qwt/examples/animation/main.cpp b/ThirdParty/Qwt/examples/animation/main.cpp new file mode 100644 index 0000000000..f5a4a9b9a1 --- /dev/null +++ b/ThirdParty/Qwt/examples/animation/main.cpp @@ -0,0 +1,46 @@ +#include +#include "plot.h" + +#ifndef QWT_NO_OPENGL +#define USE_OPENGL 1 +#endif + +#if USE_OPENGL +#include +#include +#else +#include +#endif + +int main ( int argc, char **argv ) +{ +#if USE_OPENGL +#if QT_VERSION >= 0x040600 && QT_VERSION < 0x050000 + // on my box QPaintEngine::OpenGL2 has serious problems, f.e: + // the lines of a simple drawRect are wrong. + + QGL::setPreferredPaintEngine( QPaintEngine::OpenGL ); +#endif +#endif + + QApplication a( argc, argv ); + + Plot plot; + +#if USE_OPENGL + QwtPlotGLCanvas *canvas = new QwtPlotGLCanvas(); + canvas->setFrameStyle( QwtPlotGLCanvas::NoFrame ); +#else + QwtPlotCanvas *canvas = new QwtPlotCanvas(); + canvas->setFrameStyle( QFrame::NoFrame ); + canvas->setPaintAttribute( QwtPlotCanvas::BackingStore, false ); +#endif + + plot.setCanvas( canvas ); + plot.setCanvasBackground( QColor( 30, 30, 50 ) ); + + plot.resize( 400, 400 ); + plot.show(); + + return a.exec(); +} diff --git a/ThirdParty/Qwt/examples/animation/plot.cpp b/ThirdParty/Qwt/examples/animation/plot.cpp new file mode 100644 index 0000000000..fac7917dc7 --- /dev/null +++ b/ThirdParty/Qwt/examples/animation/plot.cpp @@ -0,0 +1,241 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include "plot.h" + +class Curve: public QwtPlotCurve +{ +public: + void setTransformation( const QTransform &transform ) + { + d_transform = transform; + } + + virtual void updateSamples( double phase ) + { + setSamples( d_transform.map( points( phase ) ) ); + } + +private: + virtual QPolygonF points( double phase ) const = 0; + +private: + QTransform d_transform; +}; + +class Curve1: public Curve +{ +public: + Curve1() + { + setPen( QColor( 150, 150, 200 ), 2 ); + setStyle( QwtPlotCurve::Lines ); + + QwtSplineCurveFitter *curveFitter = new QwtSplineCurveFitter(); + curveFitter->setSplineSize( 150 ); + setCurveFitter( curveFitter ); + + setCurveAttribute( QwtPlotCurve::Fitted, true ); + + QwtSymbol *symbol = new QwtSymbol( QwtSymbol::XCross ); + symbol->setPen( Qt::yellow ); + symbol->setSize( 7 ); + + setSymbol( symbol ); + + // somewhere to the left + QTransform transform; + transform.scale( 1.5, 1.0 ); + transform.translate( 1.5, 3.0 ); + + setTransformation( transform ); + } + + virtual QPolygonF points( double phase ) const + { + QPolygonF points; + + const int numSamples = 15; + for ( int i = 0; i < numSamples; i++ ) + { + const double v = 6.28 * double( i ) / double( numSamples - 1 ); + points += QPointF( qSin( v - phase ), v ); + } + + return points; + } +}; + +class Curve2: public Curve +{ +public: + Curve2() + { + setStyle( QwtPlotCurve::Sticks ); + setPen( QColor( 200, 150, 50 ) ); + + setSymbol( new QwtSymbol( QwtSymbol::Ellipse, + QColor( Qt::gray ), QColor( Qt::yellow ), QSize( 5, 5 ) ) ); + } + +private: + virtual QPolygonF points( double phase ) const + { + QPolygonF points; + + const int numSamples = 50; + for ( int i = 0; i < numSamples; i++ ) + { + const double v = 10.0 * i / double( numSamples - 1 ); + points += QPointF( v, qCos( 3.0 * ( v + phase ) ) ); + } + + return points; + } +}; + +class Curve3: public Curve +{ +public: + Curve3() + { + setStyle( QwtPlotCurve::Lines ); + setPen( QColor( 100, 200, 150 ), 2 ); + + QwtSplineCurveFitter* curveFitter = new QwtSplineCurveFitter(); + curveFitter->setFitMode( QwtSplineCurveFitter::ParametricSpline ); + curveFitter->setSplineSize( 200 ); + setCurveFitter( curveFitter ); + + setCurveAttribute( QwtPlotCurve::Fitted, true ); + + // somewhere in the top right corner + QTransform transform; + transform.translate( 7.0, 7.5 ); + transform.scale( 2.0, 2.0 ); + + setTransformation( transform ); + } + +private: + virtual QPolygonF points( double phase ) const + { + QPolygonF points; + + const int numSamples = 9; + for ( int i = 0; i < numSamples; i++ ) + { + const double v = i * 2.0 * M_PI / ( numSamples - 1 ); + points += QPointF( qSin( v - phase ), qCos( 3.0 * ( v + phase ) ) ); + } + + return points; + } +}; + +class Curve4: public Curve +{ +public: + Curve4() + { + setStyle( QwtPlotCurve::Lines ); + setPen( Qt::red, 2 ); + + initSamples(); + + // somewhere in the center + QTransform transform; + transform.translate( 7.0, 3.0 ); + transform.scale( 1.5, 1.5 ); + + setTransformation( transform ); + } + +private: + virtual QPolygonF points( double phase ) const + { + const double speed = 0.05; + + const double s = speed * qSin( phase ); + const double c = qSqrt( 1.0 - s * s ); + + for ( int i = 0; i < d_points.size(); i++ ) + { + const QPointF p = d_points[i]; + + const double u = p.x(); + const double v = p.y(); + + d_points[i].setX( u * c - v * s ); + d_points[i].setY( v * c + u * s ); + } + + return d_points; + } + + void initSamples() + { + const int numSamples = 15; + + for ( int i = 0; i < numSamples; i++ ) + { + const double angle = i * ( 2.0 * M_PI / ( numSamples - 1 ) ); + + QPointF p( qCos( angle ), qSin( angle ) ); + if ( i % 2 ) + p *= 0.4; + + d_points += p; + } + } + +private: + mutable QPolygonF d_points; +}; + +Plot::Plot( QWidget *parent ): + QwtPlot( parent) +{ + setAutoReplot( false ); + + setTitle( "Animated Curves" ); + + // hide all axes + for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ ) + enableAxis( axis, false ); + + plotLayout()->setCanvasMargin( 10 ); + + d_curves[0] = new Curve1(); + d_curves[1] = new Curve2(); + d_curves[2] = new Curve3(); + d_curves[3] = new Curve4(); + + updateCurves(); + + for ( int i = 0; i < CurveCount; i++ ) + d_curves[i]->attach( this ); + + d_time.start(); + ( void )startTimer( 40 ); +} + +void Plot::timerEvent( QTimerEvent * ) +{ + updateCurves(); + replot(); +} + +void Plot::updateCurves() +{ + const double speed = 2 * M_PI / 25000.0; // a cycle every 25 seconds + + const double phase = d_time.elapsed() * speed; + for ( int i = 0; i < CurveCount; i++ ) + d_curves[i]->updateSamples( phase ); +} diff --git a/ThirdParty/Qwt/examples/animation/plot.h b/ThirdParty/Qwt/examples/animation/plot.h new file mode 100644 index 0000000000..e2d51acaee --- /dev/null +++ b/ThirdParty/Qwt/examples/animation/plot.h @@ -0,0 +1,21 @@ +#include +#include + +class Curve; + +class Plot: public QwtPlot +{ +public: + Plot( QWidget * = NULL); + +protected: + virtual void timerEvent( QTimerEvent * ); + +private: + void updateCurves(); + + enum { CurveCount = 4 }; + Curve *d_curves[CurveCount]; + + QTime d_time; +}; diff --git a/ThirdParty/Qwt/examples/barchart/barchart.cpp b/ThirdParty/Qwt/examples/barchart/barchart.cpp new file mode 100644 index 0000000000..997403148b --- /dev/null +++ b/ThirdParty/Qwt/examples/barchart/barchart.cpp @@ -0,0 +1,132 @@ +#include "barchart.h" +#include +#include +#include +#include +#include +#include +#include + +BarChart::BarChart( QWidget *parent ): + QwtPlot( parent ) +{ + setAutoFillBackground( true ); + + setPalette( Qt::white ); + canvas()->setPalette( QColor( "LemonChiffon" ) ); + + setTitle( "Bar Chart" ); + + setAxisTitle( QwtPlot::yLeft, "Whatever" ); + setAxisTitle( QwtPlot::xBottom, "Whatever" ); + + d_barChartItem = new QwtPlotMultiBarChart( "Bar Chart " ); + d_barChartItem->setLayoutPolicy( QwtPlotMultiBarChart::AutoAdjustSamples ); + d_barChartItem->setSpacing( 20 ); + d_barChartItem->setMargin( 3 ); + + d_barChartItem->attach( this ); + + insertLegend( new QwtLegend() ); + + populate(); + setOrientation( 0 ); + + setAutoReplot( true ); +} + +void BarChart::populate() +{ + static const char *colors[] = { "DarkOrchid", "SteelBlue", "Gold" }; + + const int numSamples = 5; + const int numBars = sizeof( colors ) / sizeof( colors[0] ); + + QList titles; + for ( int i = 0; i < numBars; i++ ) + { + QString title("Bar %1"); + titles += title.arg( i ); + } + d_barChartItem->setBarTitles( titles ); + d_barChartItem->setLegendIconSize( QSize( 10, 14 ) ); + + for ( int i = 0; i < numBars; i++ ) + { + QwtColumnSymbol *symbol = new QwtColumnSymbol( QwtColumnSymbol::Box ); + symbol->setLineWidth( 2 ); + symbol->setFrameStyle( QwtColumnSymbol::Raised ); + symbol->setPalette( QPalette( colors[i] ) ); + + d_barChartItem->setSymbol( i, symbol ); + } + + QVector< QVector > series; + for ( int i = 0; i < numSamples; i++ ) + { + QVector values; + for ( int j = 0; j < numBars; j++ ) + values += ( 2 + qrand() % 8 ); + + series += values; + } + + d_barChartItem->setSamples( series ); +} + +void BarChart::setMode( int mode ) +{ + if ( mode == 0 ) + { + d_barChartItem->setStyle( QwtPlotMultiBarChart::Grouped ); + } + else + { + d_barChartItem->setStyle( QwtPlotMultiBarChart::Stacked ); + } +} + +void BarChart::setOrientation( int orientation ) +{ + QwtPlot::Axis axis1, axis2; + + if ( orientation == 0 ) + { + axis1 = QwtPlot::xBottom; + axis2 = QwtPlot::yLeft; + + d_barChartItem->setOrientation( Qt::Vertical ); + } + else + { + axis1 = QwtPlot::yLeft; + axis2 = QwtPlot::xBottom; + + d_barChartItem->setOrientation( Qt::Horizontal ); + } + + setAxisScale( axis1, 0, d_barChartItem->dataSize() - 1, 1.0 ); + setAxisAutoScale( axis2 ); + + QwtScaleDraw *scaleDraw1 = axisScaleDraw( axis1 ); + scaleDraw1->enableComponent( QwtScaleDraw::Backbone, false ); + scaleDraw1->enableComponent( QwtScaleDraw::Ticks, false ); + + QwtScaleDraw *scaleDraw2 = axisScaleDraw( axis2 ); + scaleDraw2->enableComponent( QwtScaleDraw::Backbone, true ); + scaleDraw2->enableComponent( QwtScaleDraw::Ticks, true ); + + plotLayout()->setAlignCanvasToScale( axis1, true ); + plotLayout()->setAlignCanvasToScale( axis2, false ); + + plotLayout()->setCanvasMargin( 0 ); + updateCanvasMargins(); + + replot(); +} + +void BarChart::exportChart() +{ + QwtPlotRenderer renderer; + renderer.exportTo( this, "barchart.pdf" ); +} diff --git a/ThirdParty/Qwt/examples/barchart/barchart.h b/ThirdParty/Qwt/examples/barchart/barchart.h new file mode 100644 index 0000000000..ff5afd9d89 --- /dev/null +++ b/ThirdParty/Qwt/examples/barchart/barchart.h @@ -0,0 +1,25 @@ +#ifndef _BAR_CHART_H_ + +#include + +class QwtPlotMultiBarChart; + +class BarChart: public QwtPlot +{ + Q_OBJECT + +public: + BarChart( QWidget * = NULL ); + +public Q_SLOTS: + void setMode( int ); + void setOrientation( int ); + void exportChart(); + +private: + void populate(); + + QwtPlotMultiBarChart *d_barChartItem; +}; + +#endif diff --git a/ThirdParty/Qwt/examples/barchart/barchart.pro b/ThirdParty/Qwt/examples/barchart/barchart.pro new file mode 100644 index 0000000000..ff069655b6 --- /dev/null +++ b/ThirdParty/Qwt/examples/barchart/barchart.pro @@ -0,0 +1,19 @@ +################################################################ +# Qwt Widget Library +# Copyright (C) 1997 Josef Wilgen +# Copyright (C) 2002 Uwe Rathmann +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the Qwt License, Version 1.0 +################################################################ + +include( $${PWD}/../examples.pri ) + +TARGET = barchart + +SOURCES = \ + barchart.cpp \ + main.cpp + +HEADERS = \ + barchart.h diff --git a/ThirdParty/Qwt/examples/barchart/main.cpp b/ThirdParty/Qwt/examples/barchart/main.cpp new file mode 100644 index 0000000000..a47da346a7 --- /dev/null +++ b/ThirdParty/Qwt/examples/barchart/main.cpp @@ -0,0 +1,64 @@ +#include +#include +#include +#include +#include +#include "barchart.h" + +class MainWindow: public QMainWindow +{ +public: + MainWindow( QWidget * = NULL ); + +private: + BarChart *d_chart; +}; + +MainWindow::MainWindow( QWidget *parent ): + QMainWindow( parent ) +{ + d_chart = new BarChart( this ); + setCentralWidget( d_chart ); + + QToolBar *toolBar = new QToolBar( this ); + + QComboBox *typeBox = new QComboBox( toolBar ); + typeBox->addItem( "Grouped" ); + typeBox->addItem( "Stacked" ); + typeBox->setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ); + + QComboBox *orientationBox = new QComboBox( toolBar ); + orientationBox->addItem( "Vertical" ); + orientationBox->addItem( "Horizontal" ); + orientationBox->setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ); + + QToolButton *btnExport = new QToolButton( toolBar ); + btnExport->setText( "Export" ); + btnExport->setToolButtonStyle( Qt::ToolButtonTextUnderIcon ); + connect( btnExport, SIGNAL( clicked() ), d_chart, SLOT( exportChart() ) ); + + toolBar->addWidget( typeBox ); + toolBar->addWidget( orientationBox ); + toolBar->addWidget( btnExport ); + addToolBar( toolBar ); + + d_chart->setMode( typeBox->currentIndex() ); + connect( typeBox, SIGNAL( currentIndexChanged( int ) ), + d_chart, SLOT( setMode( int ) ) ); + + d_chart->setOrientation( orientationBox->currentIndex() ); + connect( orientationBox, SIGNAL( currentIndexChanged( int ) ), + d_chart, SLOT( setOrientation( int ) ) ); +} + +int main( int argc, char **argv ) +{ + QApplication a( argc, argv ); + + MainWindow mainWindow; + + mainWindow.resize( 600, 400 ); + mainWindow.show(); + + return a.exec(); +} diff --git a/ThirdParty/Qwt/examples/bode/bode.pro b/ThirdParty/Qwt/examples/bode/bode.pro new file mode 100644 index 0000000000..ab42e28b17 --- /dev/null +++ b/ThirdParty/Qwt/examples/bode/bode.pro @@ -0,0 +1,23 @@ +################################################################ +# Qwt Widget Library +# Copyright (C) 1997 Josef Wilgen +# Copyright (C) 2002 Uwe Rathmann +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the Qwt License, Version 1.0 +################################################################ + +include( $${PWD}/../examples.pri ) + +TARGET = bode + +HEADERS = \ + mainwindow.h \ + plot.h \ + complexnumber.h \ + pixmaps.h + +SOURCES = \ + plot.cpp \ + mainwindow.cpp \ + main.cpp diff --git a/ThirdParty/Qwt/examples/bode/complexnumber.h b/ThirdParty/Qwt/examples/bode/complexnumber.h new file mode 100644 index 0000000000..62dfe1acd4 --- /dev/null +++ b/ThirdParty/Qwt/examples/bode/complexnumber.h @@ -0,0 +1,83 @@ +#ifndef _COMPLEX_NUMBER_H_ +#define _COMPLEX_NUMBER_H_ + +#include + +class ComplexNumber +{ +public: + ComplexNumber() ; + ComplexNumber( double r, double i = 0.0 ); + + double real() const; + double imag() const; + + friend ComplexNumber operator*( + const ComplexNumber &, const ComplexNumber & ); + + friend ComplexNumber operator+( + const ComplexNumber &, const ComplexNumber & ); + + friend ComplexNumber operator-( + const ComplexNumber &, const ComplexNumber & ); + friend ComplexNumber operator/( + const ComplexNumber &, const ComplexNumber & ); + +private: + double d_real; + double d_imag; +}; + +inline ComplexNumber::ComplexNumber(): + d_real( 0.0 ), + d_imag( -0.0 ) +{ +} + +inline ComplexNumber::ComplexNumber( double re, double im ): + d_real( re ), + d_imag( im ) +{ +} + +inline double ComplexNumber::real() const +{ + return d_real; +} + +inline double ComplexNumber::imag() const +{ + return d_imag; +} + +inline ComplexNumber operator+( + const ComplexNumber &x1, const ComplexNumber &x2 ) +{ + return ComplexNumber( x1.d_real + x2.d_real, x1.d_imag + x2.d_imag ); +} + +inline ComplexNumber operator-( + const ComplexNumber &x1, const ComplexNumber &x2 ) +{ + return ComplexNumber( x1.d_real - x2.d_real, x1.d_imag - x2.d_imag ); +} + +inline ComplexNumber operator*( + const ComplexNumber &x1, const ComplexNumber &x2 ) +{ + return ComplexNumber( x1.d_real * x2.d_real - x1.d_imag * x2.d_imag, + x1.d_real * x2.d_imag + x2.d_real * x1.d_imag ); +} + +inline ComplexNumber operator/( + const ComplexNumber &x1, const ComplexNumber &x2 ) +{ + double denom = x2.d_real * x2.d_real + x2.d_imag * x2.d_imag; + + return ComplexNumber( + ( x1.d_real * x2.d_real + x1.d_imag * x2.d_imag ) / denom, + ( x1.d_imag * x2.d_real - x2.d_imag * x1.d_real ) / denom + ); +} + +#endif diff --git a/ThirdParty/Qwt/examples/bode/main.cpp b/ThirdParty/Qwt/examples/bode/main.cpp new file mode 100644 index 0000000000..6058abf1f0 --- /dev/null +++ b/ThirdParty/Qwt/examples/bode/main.cpp @@ -0,0 +1,13 @@ +#include +#include "mainwindow.h" + +int main ( int argc, char **argv ) +{ + QApplication a( argc, argv ); + + MainWindow w; + w.resize( 540, 400 ); + w.show(); + + return a.exec(); +} diff --git a/ThirdParty/Qwt/examples/bode/mainwindow.cpp b/ThirdParty/Qwt/examples/bode/mainwindow.cpp new file mode 100644 index 0000000000..5cdd9b8d31 --- /dev/null +++ b/ThirdParty/Qwt/examples/bode/mainwindow.cpp @@ -0,0 +1,231 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "pixmaps.h" +#include "plot.h" +#include "mainwindow.h" + +class Zoomer: public QwtPlotZoomer +{ +public: + Zoomer( int xAxis, int yAxis, QWidget *canvas ): + QwtPlotZoomer( xAxis, yAxis, canvas ) + { + setTrackerMode( QwtPicker::AlwaysOff ); + setRubberBand( QwtPicker::NoRubberBand ); + + // RightButton: zoom out by 1 + // Ctrl+RightButton: zoom out to full size + + setMousePattern( QwtEventPattern::MouseSelect2, + Qt::RightButton, Qt::ControlModifier ); + setMousePattern( QwtEventPattern::MouseSelect3, + Qt::RightButton ); + } +}; + +//----------------------------------------------------------------- +// +// bode.cpp -- A demo program featuring QwtPlot and QwtCounter +// +// This example demonstrates the mapping of different curves +// to different axes in a QwtPlot widget. It also shows how to +// display the cursor position and how to implement zooming. +// +//----------------------------------------------------------------- + +MainWindow::MainWindow( QWidget *parent ): + QMainWindow( parent ) +{ + d_plot = new Plot( this ); + + const int margin = 5; + d_plot->setContentsMargins( margin, margin, margin, 0 ); + + setContextMenuPolicy( Qt::NoContextMenu ); + + d_zoomer[0] = new Zoomer( QwtPlot::xBottom, QwtPlot::yLeft, + d_plot->canvas() ); + d_zoomer[0]->setRubberBand( QwtPicker::RectRubberBand ); + d_zoomer[0]->setRubberBandPen( QColor( Qt::green ) ); + d_zoomer[0]->setTrackerMode( QwtPicker::ActiveOnly ); + d_zoomer[0]->setTrackerPen( QColor( Qt::white ) ); + + d_zoomer[1] = new Zoomer( QwtPlot::xTop, QwtPlot::yRight, + d_plot->canvas() ); + + d_panner = new QwtPlotPanner( d_plot->canvas() ); + d_panner->setMouseButton( Qt::MidButton ); + + d_picker = new QwtPlotPicker( QwtPlot::xBottom, QwtPlot::yLeft, + QwtPlotPicker::CrossRubberBand, QwtPicker::AlwaysOn, + d_plot->canvas() ); + d_picker->setStateMachine( new QwtPickerDragPointMachine() ); + d_picker->setRubberBandPen( QColor( Qt::green ) ); + d_picker->setRubberBand( QwtPicker::CrossRubberBand ); + d_picker->setTrackerPen( QColor( Qt::white ) ); + + setCentralWidget( d_plot ); + + QToolBar *toolBar = new QToolBar( this ); + + QToolButton *btnZoom = new QToolButton( toolBar ); + btnZoom->setText( "Zoom" ); + btnZoom->setIcon( QPixmap( zoom_xpm ) ); + btnZoom->setCheckable( true ); + btnZoom->setToolButtonStyle( Qt::ToolButtonTextUnderIcon ); + toolBar->addWidget( btnZoom ); + connect( btnZoom, SIGNAL( toggled( bool ) ), SLOT( enableZoomMode( bool ) ) ); + +#ifndef QT_NO_PRINTER + QToolButton *btnPrint = new QToolButton( toolBar ); + btnPrint->setText( "Print" ); + btnPrint->setIcon( QPixmap( print_xpm ) ); + btnPrint->setToolButtonStyle( Qt::ToolButtonTextUnderIcon ); + toolBar->addWidget( btnPrint ); + connect( btnPrint, SIGNAL( clicked() ), SLOT( print() ) ); +#endif + + QToolButton *btnExport = new QToolButton( toolBar ); + btnExport->setText( "Export" ); + btnExport->setIcon( QPixmap( print_xpm ) ); + btnExport->setToolButtonStyle( Qt::ToolButtonTextUnderIcon ); + toolBar->addWidget( btnExport ); + connect( btnExport, SIGNAL( clicked() ), SLOT( exportDocument() ) ); + + toolBar->addSeparator(); + + QWidget *hBox = new QWidget( toolBar ); + + QHBoxLayout *layout = new QHBoxLayout( hBox ); + layout->setSpacing( 0 ); + layout->addWidget( new QWidget( hBox ), 10 ); // spacer + layout->addWidget( new QLabel( "Damping Factor", hBox ), 0 ); + layout->addSpacing( 10 ); + + QwtCounter *cntDamp = new QwtCounter( hBox ); + cntDamp->setRange( 0.0, 5.0 ); + cntDamp->setSingleStep( 0.01 ); + cntDamp->setValue( 0.0 ); + + layout->addWidget( cntDamp, 0 ); + + ( void )toolBar->addWidget( hBox ); + + addToolBar( toolBar ); +#ifndef QT_NO_STATUSBAR + ( void )statusBar(); +#endif + + enableZoomMode( false ); + showInfo(); + + connect( cntDamp, SIGNAL( valueChanged( double ) ), + d_plot, SLOT( setDamp( double ) ) ); + + connect( d_picker, SIGNAL( moved( const QPoint & ) ), + SLOT( moved( const QPoint & ) ) ); + connect( d_picker, SIGNAL( selected( const QPolygon & ) ), + SLOT( selected( const QPolygon & ) ) ); +} + +#ifndef QT_NO_PRINTER + +void MainWindow::print() +{ + QPrinter printer( QPrinter::HighResolution ); + + QString docName = d_plot->title().text(); + if ( !docName.isEmpty() ) + { + docName.replace ( QRegExp ( QString::fromLatin1 ( "\n" ) ), tr ( " -- " ) ); + printer.setDocName ( docName ); + } + + printer.setCreator( "Bode example" ); + printer.setOrientation( QPrinter::Landscape ); + + QPrintDialog dialog( &printer ); + if ( dialog.exec() ) + { + QwtPlotRenderer renderer; + + if ( printer.colorMode() == QPrinter::GrayScale ) + { + renderer.setDiscardFlag( QwtPlotRenderer::DiscardBackground ); + renderer.setDiscardFlag( QwtPlotRenderer::DiscardCanvasBackground ); + renderer.setDiscardFlag( QwtPlotRenderer::DiscardCanvasFrame ); + renderer.setLayoutFlag( QwtPlotRenderer::FrameWithScales ); + } + + renderer.renderTo( d_plot, printer ); + } +} + +#endif + +void MainWindow::exportDocument() +{ + QwtPlotRenderer renderer; + renderer.exportTo( d_plot, "bode.pdf" ); +} + +void MainWindow::enableZoomMode( bool on ) +{ + d_panner->setEnabled( on ); + + d_zoomer[0]->setEnabled( on ); + d_zoomer[0]->zoom( 0 ); + + d_zoomer[1]->setEnabled( on ); + d_zoomer[1]->zoom( 0 ); + + d_picker->setEnabled( !on ); + + showInfo(); +} + +void MainWindow::showInfo( QString text ) +{ + if ( text == QString::null ) + { + if ( d_picker->rubberBand() ) + text = "Cursor Pos: Press left mouse button in plot region"; + else + text = "Zoom: Press mouse button and drag"; + } + +#ifndef QT_NO_STATUSBAR + statusBar()->showMessage( text ); +#endif +} + +void MainWindow::moved( const QPoint &pos ) +{ + QString info; + info.sprintf( "Freq=%g, Ampl=%g, Phase=%g", + d_plot->invTransform( QwtPlot::xBottom, pos.x() ), + d_plot->invTransform( QwtPlot::yLeft, pos.y() ), + d_plot->invTransform( QwtPlot::yRight, pos.y() ) + ); + showInfo( info ); +} + +void MainWindow::selected( const QPolygon & ) +{ + showInfo(); +} diff --git a/ThirdParty/Qwt/examples/bode/mainwindow.h b/ThirdParty/Qwt/examples/bode/mainwindow.h new file mode 100644 index 0000000000..1373b52cba --- /dev/null +++ b/ThirdParty/Qwt/examples/bode/mainwindow.h @@ -0,0 +1,35 @@ +#include + +class QwtPlotZoomer; +class QwtPlotPicker; +class QwtPlotPanner; +class Plot; +class QPolygon; + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + MainWindow( QWidget *parent = 0 ); + +private Q_SLOTS: + void moved( const QPoint & ); + void selected( const QPolygon & ); + +#ifndef QT_NO_PRINTER + void print(); +#endif + + void exportDocument(); + void enableZoomMode( bool ); + +private: + void showInfo( QString text = QString::null ); + + Plot *d_plot; + + QwtPlotZoomer *d_zoomer[2]; + QwtPlotPicker *d_picker; + QwtPlotPanner *d_panner; +}; diff --git a/ThirdParty/Qwt/examples/bode/pixmaps.h b/ThirdParty/Qwt/examples/bode/pixmaps.h new file mode 100644 index 0000000000..c3bc0b9bcd --- /dev/null +++ b/ThirdParty/Qwt/examples/bode/pixmaps.h @@ -0,0 +1,99 @@ +#ifndef PIXMAPS_H +#define PIXMAPS_H + +static const char *print_xpm[] = +{ + "32 32 12 1", + "a c #ffffff", + "h c #ffff00", + "c c #ffffff", + "f c #dcdcdc", + "b c #c0c0c0", + "j c #a0a0a4", + "e c #808080", + "g c #808000", + "d c #585858", + "i c #00ff00", + "# c #000000", + ". c None", + "................................", + "................................", + "...........###..................", + "..........#abb###...............", + ".........#aabbbbb###............", + ".........#ddaaabbbbb###.........", + "........#ddddddaaabbbbb###......", + ".......#deffddddddaaabbbbb###...", + "......#deaaabbbddddddaaabbbbb###", + ".....#deaaaaaaabbbddddddaaabbbb#", + "....#deaaabbbaaaa#ddedddfggaaad#", + "...#deaaaaaaaaaa#ddeeeeafgggfdd#", + "..#deaaabbbaaaa#ddeeeeabbbbgfdd#", + ".#deeefaaaaaaa#ddeeeeabbhhbbadd#", + "#aabbbeeefaaa#ddeeeeabbbbbbaddd#", + "#bbaaabbbeee#ddeeeeabbiibbadddd#", + "#bbbbbaaabbbeeeeeeabbbbbbaddddd#", + "#bjbbbbbbaaabbbbeabbbbbbadddddd#", + "#bjjjjbbbbbbaaaeabbbbbbaddddddd#", + "#bjaaajjjbbbbbbaaabbbbadddddddd#", + "#bbbbbaaajjjbbbbbbaaaaddddddddd#", + "#bjbbbbbbaaajjjbbbbbbddddddddd#.", + "#bjjjjbbbbbbaaajjjbbbdddddddd#..", + "#bjaaajjjbbbbbbjaajjbddddddd#...", + "#bbbbbaaajjjbbbjbbaabdddddd#....", + "###bbbbbbaaajjjjbbbbbddddd#.....", + "...###bbbbbbaaajbbbbbdddd#......", + "......###bbbbbbjbbbbbddd#.......", + ".........###bbbbbbbbbdd#........", + "............###bbbbbbd#.........", + "...............###bbb#..........", + "..................###..........." +}; + + +static const char *zoom_xpm[] = +{ + "32 32 8 1", + "# c #000000", + "b c #c0c0c0", + "a c #ffffff", + "e c #585858", + "d c #a0a0a4", + "c c #0000ff", + "f c #00ffff", + ". c None", + "..######################........", + ".#a#baaaaaaaaaaaaaaaaaa#........", + "#aa#baaaaaaaaaaaaaccaca#........", + "####baaaaaaaaaaaaaaaaca####.....", + "#bbbbaaaaaaaaaaaacccaaa#da#.....", + "#aaaaaaaaaaaaaaaacccaca#da#.....", + "#aaaaaaaaaaaaaaaaaccaca#da#.....", + "#aaaaaaaaaabe###ebaaaaa#da#.....", + "#aaaaaaaaa#########aaaa#da#.....", + "#aaaaaaaa###dbbbb###aaa#da#.....", + "#aaaaaaa###aaaaffb###aa#da#.....", + "#aaaaaab##aaccaaafb##ba#da#.....", + "#aaaaaae#daaccaccaad#ea#da#.....", + "#aaaaaa##aaaaaaccaab##a#da#.....", + "#aaaaaa##aacccaaaaab##a#da#.....", + "#aaaaaa##aaccccaccab##a#da#.....", + "#aaaaaae#daccccaccad#ea#da#.....", + "#aaaaaab##aacccaaaa##da#da#.....", + "#aaccacd###aaaaaaa###da#da#.....", + "#aaaaacad###daaad#####a#da#.....", + "#acccaaaad##########da##da#.....", + "#acccacaaadde###edd#eda#da#.....", + "#aaccacaaaabdddddbdd#eda#a#.....", + "#aaaaaaaaaaaaaaaaaadd#eda##.....", + "#aaaaaaaaaaaaaaaaaaadd#eda#.....", + "#aaaaaaaccacaaaaaaaaadd#eda#....", + "#aaaaaaaaaacaaaaaaaaaad##eda#...", + "#aaaaaacccaaaaaaaaaaaaa#d#eda#..", + "########################dd#eda#.", + "...#dddddddddddddddddddddd##eda#", + "...#aaaaaaaaaaaaaaaaaaaaaa#.####", + "...########################..##." +}; + +#endif diff --git a/ThirdParty/Qwt/examples/bode/plot.cpp b/ThirdParty/Qwt/examples/bode/plot.cpp new file mode 100644 index 0000000000..a7a443a0c2 --- /dev/null +++ b/ThirdParty/Qwt/examples/bode/plot.cpp @@ -0,0 +1,190 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "complexnumber.h" +#include "plot.h" + +#if QT_VERSION < 0x040601 +#define qExp(x) ::exp(x) +#define qAtan2(y, x) ::atan2(y, x) +#endif + +static void logSpace( double *array, int size, double xmin, double xmax ) +{ + if ( ( xmin <= 0.0 ) || ( xmax <= 0.0 ) || ( size <= 0 ) ) + return; + + const int imax = size - 1; + + array[0] = xmin; + array[imax] = xmax; + + const double lxmin = log( xmin ); + const double lxmax = log( xmax ); + const double lstep = ( lxmax - lxmin ) / double( imax ); + + for ( int i = 1; i < imax; i++ ) + array[i] = qExp( lxmin + double( i ) * lstep ); +} + +Plot::Plot( QWidget *parent ): + QwtPlot( parent ) +{ + setAutoReplot( false ); + + setTitle( "Frequency Response of a Second-Order System" ); + + QwtPlotCanvas *canvas = new QwtPlotCanvas(); + canvas->setBorderRadius( 10 ); + + setCanvas( canvas ); + setCanvasBackground( QColor( "MidnightBlue" ) ); + + // legend + QwtLegend *legend = new QwtLegend; + insertLegend( legend, QwtPlot::BottomLegend ); + + // grid + QwtPlotGrid *grid = new QwtPlotGrid; + grid->enableXMin( true ); + grid->setMajorPen( Qt::white, 0, Qt::DotLine ); + grid->setMinorPen( Qt::gray, 0 , Qt::DotLine ); + grid->attach( this ); + + // axes + enableAxis( QwtPlot::yRight ); + setAxisTitle( QwtPlot::xBottom, "Normalized Frequency" ); + setAxisTitle( QwtPlot::yLeft, "Amplitude [dB]" ); + setAxisTitle( QwtPlot::yRight, "Phase [deg]" ); + + setAxisMaxMajor( QwtPlot::xBottom, 6 ); + setAxisMaxMinor( QwtPlot::xBottom, 9 ); + setAxisScaleEngine( QwtPlot::xBottom, new QwtLogScaleEngine ); + + // curves + d_curve1 = new QwtPlotCurve( "Amplitude" ); + d_curve1->setRenderHint( QwtPlotItem::RenderAntialiased ); + d_curve1->setPen( Qt::yellow ); + d_curve1->setLegendAttribute( QwtPlotCurve::LegendShowLine ); + d_curve1->setYAxis( QwtPlot::yLeft ); + d_curve1->attach( this ); + + d_curve2 = new QwtPlotCurve( "Phase" ); + d_curve2->setRenderHint( QwtPlotItem::RenderAntialiased ); + d_curve2->setPen( Qt::cyan ); + d_curve2->setLegendAttribute( QwtPlotCurve::LegendShowLine ); + d_curve2->setYAxis( QwtPlot::yRight ); + d_curve2->attach( this ); + + // marker + d_marker1 = new QwtPlotMarker(); + d_marker1->setValue( 0.0, 0.0 ); + d_marker1->setLineStyle( QwtPlotMarker::VLine ); + d_marker1->setLabelAlignment( Qt::AlignRight | Qt::AlignBottom ); + d_marker1->setLinePen( Qt::green, 0, Qt::DashDotLine ); + d_marker1->attach( this ); + + d_marker2 = new QwtPlotMarker(); + d_marker2->setLineStyle( QwtPlotMarker::HLine ); + d_marker2->setLabelAlignment( Qt::AlignRight | Qt::AlignBottom ); + d_marker2->setLinePen( QColor( 200, 150, 0 ), 0, Qt::DashDotLine ); + d_marker2->setSymbol( new QwtSymbol( QwtSymbol::Diamond, + QColor( Qt::yellow ), QColor( Qt::green ), QSize( 8, 8 ) ) ); + d_marker2->attach( this ); + + setDamp( 0.0 ); + + setAutoReplot( true ); +} + +void Plot::showData( const double *frequency, const double *amplitude, + const double *phase, int count ) +{ + d_curve1->setSamples( frequency, amplitude, count ); + d_curve2->setSamples( frequency, phase, count ); +} + +void Plot::showPeak( double freq, double amplitude ) +{ + QString label; + label.sprintf( "Peak: %.3g dB", amplitude ); + + QwtText text( label ); + text.setFont( QFont( "Helvetica", 10, QFont::Bold ) ); + text.setColor( QColor( 200, 150, 0 ) ); + + d_marker2->setValue( freq, amplitude ); + d_marker2->setLabel( text ); +} + +void Plot::show3dB( double freq ) +{ + QString label; + label.sprintf( "-3 dB at f = %.3g", freq ); + + QwtText text( label ); + text.setFont( QFont( "Helvetica", 10, QFont::Bold ) ); + text.setColor( Qt::green ); + + d_marker1->setValue( freq, 0.0 ); + d_marker1->setLabel( text ); +} + +// +// re-calculate frequency response +// +void Plot::setDamp( double damping ) +{ + const bool doReplot = autoReplot(); + setAutoReplot( false ); + + const int ArraySize = 200; + + double frequency[ArraySize]; + double amplitude[ArraySize]; + double phase[ArraySize]; + + // build frequency vector with logarithmic division + logSpace( frequency, ArraySize, 0.01, 100 ); + + int i3 = 1; + double fmax = 1; + double amax = -1000.0; + + for ( int i = 0; i < ArraySize; i++ ) + { + double f = frequency[i]; + const ComplexNumber g = + ComplexNumber( 1.0 ) / ComplexNumber( 1.0 - f * f, 2.0 * damping * f ); + + amplitude[i] = 20.0 * log10( qSqrt( g.real() * g.real() + g.imag() * g.imag() ) ); + phase[i] = qAtan2( g.imag(), g.real() ) * ( 180.0 / M_PI ); + + if ( ( i3 <= 1 ) && ( amplitude[i] < -3.0 ) ) + i3 = i; + if ( amplitude[i] > amax ) + { + amax = amplitude[i]; + fmax = frequency[i]; + } + + } + + double f3 = frequency[i3] - ( frequency[i3] - frequency[i3 - 1] ) + / ( amplitude[i3] - amplitude[i3 -1] ) * ( amplitude[i3] + 3 ); + + showPeak( fmax, amax ); + show3dB( f3 ); + showData( frequency, amplitude, phase, ArraySize ); + + setAutoReplot( doReplot ); + + replot(); +} diff --git a/ThirdParty/Qwt/examples/bode/plot.h b/ThirdParty/Qwt/examples/bode/plot.h new file mode 100644 index 0000000000..4529468a6f --- /dev/null +++ b/ThirdParty/Qwt/examples/bode/plot.h @@ -0,0 +1,31 @@ +#ifndef _PLOT_H_ +#define _PLOT_H_ + +#include + +class QwtPlotCurve; +class QwtPlotMarker; + +class Plot: public QwtPlot +{ + Q_OBJECT + +public: + Plot( QWidget *parent ); + +public Q_SLOTS: + void setDamp( double damping ); + +private: + void showData( const double *frequency, const double *amplitude, + const double *phase, int count ); + void showPeak( double freq, double amplitude ); + void show3dB( double freq ); + + QwtPlotCurve *d_curve1; + QwtPlotCurve *d_curve2; + QwtPlotMarker *d_marker1; + QwtPlotMarker *d_marker2; +}; + +#endif diff --git a/ThirdParty/Qwt/examples/controls/controls.pro b/ThirdParty/Qwt/examples/controls/controls.pro new file mode 100644 index 0000000000..0c3e5f0e1a --- /dev/null +++ b/ThirdParty/Qwt/examples/controls/controls.pro @@ -0,0 +1,34 @@ +################################################################ +# Qwt Widget Library +# Copyright (C) 1997 Josef Wilgen +# Copyright (C) 2002 Uwe Rathmann +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the Qwt License, Version 1.0 +################################################################ + +include( $${PWD}/../examples.pri ) + +TARGET = controls + +HEADERS = \ + sliderbox.h \ + slidertab.h \ + wheelbox.h \ + wheeltab.h \ + knobbox.h \ + knobtab.h \ + dialbox.h \ + dialtab.h + +SOURCES = \ + sliderbox.cpp \ + slidertab.cpp \ + wheelbox.cpp \ + wheeltab.cpp \ + knobbox.cpp \ + knobtab.cpp \ + dialbox.cpp \ + dialtab.cpp \ + main.cpp + diff --git a/ThirdParty/Qwt/examples/controls/dialbox.cpp b/ThirdParty/Qwt/examples/controls/dialbox.cpp new file mode 100644 index 0000000000..4365c9ae9e --- /dev/null +++ b/ThirdParty/Qwt/examples/controls/dialbox.cpp @@ -0,0 +1,163 @@ +#include +#include +#include +#include +#include +#include +#include +#include "dialbox.h" + +DialBox::DialBox( QWidget *parent, int type ): + QWidget( parent ) +{ + d_dial = createDial( type ); + + d_label = new QLabel( this ); + d_label->setAlignment( Qt::AlignCenter ); + + QVBoxLayout *layout = new QVBoxLayout( this );; + layout->setSpacing( 0 ); + layout->addWidget( d_dial, 10 ); + layout->addWidget( d_label ); + + connect( d_dial, SIGNAL( valueChanged( double ) ), + this, SLOT( setNum( double ) ) ); + + setNum( d_dial->value() ); +} + +QwtDial *DialBox::createDial( int type ) const +{ + QwtDial *dial = new QwtDial(); + dial->setTracking( true ); + dial->setFocusPolicy( Qt::StrongFocus ); + dial->setObjectName( QString( "Dial %1" ).arg( type + 1 ) ); + + QColor needleColor( Qt::red ); + + switch( type ) + { + case 0: + { + dial->setOrigin( 135.0 ); + dial->setScaleArc( 0.0, 270.0 ); + dial->setScaleMaxMinor( 4 ); + dial->setScaleMaxMajor( 10 ); + dial->setScale( -100.0, 100.0 ); + + needleColor = QColor( "Goldenrod" ); + + break; + } + case 1: + { + dial->setOrigin( 135.0 ); + dial->setScaleArc( 0.0, 270.0 ); + dial->setScaleMaxMinor( 10 ); + dial->setScaleMaxMajor( 10 ); + dial->setScale( 10.0, 0.0 ); + + QwtRoundScaleDraw *scaleDraw = new QwtRoundScaleDraw(); + scaleDraw->setSpacing( 8 ); + scaleDraw->enableComponent( + QwtAbstractScaleDraw::Backbone, false ); + scaleDraw->setTickLength( QwtScaleDiv::MinorTick, 2 ); + scaleDraw->setTickLength( QwtScaleDiv::MediumTick, 4 ); + scaleDraw->setTickLength( QwtScaleDiv::MajorTick, 8 ); + dial->setScaleDraw( scaleDraw ); + + break; + } + case 2: + { + dial->setOrigin( 150.0 ); + dial->setScaleArc( 0.0, 240.0 ); + + QwtLinearScaleEngine *scaleEngine = new QwtLinearScaleEngine( 2 ); + scaleEngine->setTransformation( new QwtPowerTransform( 2 ) ); + dial->setScaleEngine( scaleEngine ); + + QList< double > ticks[ QwtScaleDiv::NTickTypes ]; + ticks[ QwtScaleDiv::MajorTick ] << 0 << 4 + << 16 << 32 << 64 << 96 << 128; + ticks[ QwtScaleDiv::MediumTick ] << 24 << 48 << 80 << 112; + ticks[ QwtScaleDiv::MinorTick ] + << 0.5 << 1 << 2 + << 7 << 10 << 13 + << 20 << 28 + << 40 << 56 + << 72 << 88 + << 104 << 120; + + dial->setScale( QwtScaleDiv( 0, 128, ticks ) ); + break; + } + case 3: + { + dial->setOrigin( 135.0 ); + dial->setScaleArc( 0.0, 270.0 ); + dial->setScaleMaxMinor( 9 ); + dial->setScaleEngine( new QwtLogScaleEngine ); + dial->setScale( 1.0e-2, 1.0e2 ); + + break; + } + case 4: + { + dial->setOrigin( 225.0 ); + dial->setScaleArc( 0.0, 360.0 ); + dial->setScaleMaxMinor( 5 ); + dial->setScaleStepSize( 20 ); + dial->setScale( 100.0, -100.0 ); + dial->setWrapping( true ); + dial->setTotalSteps( 40 ); + dial->setMode( QwtDial::RotateScale ); + dial->setValue( 70.0 ); + + needleColor = QColor( "DarkSlateBlue" ); + + break; + } + case 5: + { + dial->setOrigin( 45.0 ); + dial->setScaleArc( 0.0, 225.0 ); + dial->setScaleMaxMinor( 5 ); + dial->setScaleMaxMajor( 10 ); + dial->setScale( 0.0, 10.0 ); + + break; + } + } + + QwtDialSimpleNeedle *needle = new QwtDialSimpleNeedle( + QwtDialSimpleNeedle::Arrow, true, needleColor, + QColor( Qt::gray ).light( 130 ) ); + dial->setNeedle( needle ); + + //const QColor base( QColor( "DimGray" ) ); + const QColor base( QColor( Qt::darkGray ).dark( 150 ) ); + + QPalette palette; + palette.setColor( QPalette::Base, base ); + palette.setColor( QPalette::Window, base.dark( 150 ) ); + palette.setColor( QPalette::Mid, base.dark( 110 ) ); + palette.setColor( QPalette::Light, base.light( 170 ) ); + palette.setColor( QPalette::Dark, base.dark( 170 ) ); + palette.setColor( QPalette::Text, base.dark( 200 ).light( 800 ) ); + palette.setColor( QPalette::WindowText, base.dark( 200 ) ); + + dial->setPalette( palette ); + dial->setLineWidth( 4 ); + dial->setFrameShadow( QwtDial::Sunken ); + + return dial; +} + +void DialBox::setNum( double v ) +{ + QString text; + text.setNum( v, 'f', 2 ); + + d_label->setText( text ); +} diff --git a/ThirdParty/Qwt/examples/controls/dialbox.h b/ThirdParty/Qwt/examples/controls/dialbox.h new file mode 100644 index 0000000000..f0a8268bec --- /dev/null +++ b/ThirdParty/Qwt/examples/controls/dialbox.h @@ -0,0 +1,25 @@ +#ifndef _DIAL_BOX_H_ +#define _DIAL_BOX_H_ + +#include + +class QLabel; +class QwtDial; + +class DialBox: public QWidget +{ + Q_OBJECT +public: + DialBox( QWidget *parent, int type ); + +private Q_SLOTS: + void setNum( double v ); + +private: + QwtDial *createDial( int type ) const; + + QwtDial *d_dial; + QLabel *d_label; +}; + +#endif diff --git a/ThirdParty/Qwt/examples/controls/dialtab.cpp b/ThirdParty/Qwt/examples/controls/dialtab.cpp new file mode 100644 index 0000000000..a497252762 --- /dev/null +++ b/ThirdParty/Qwt/examples/controls/dialtab.cpp @@ -0,0 +1,17 @@ +#include "dialtab.h" +#include "dialbox.h" +#include + +DialTab::DialTab( QWidget *parent ): + QWidget( parent ) +{ + QGridLayout *layout = new QGridLayout( this ); + + const int numRows = 3; + for ( int i = 0; i < 2 * numRows; i++ ) + { + DialBox *dialBox = new DialBox( this, i ); + layout->addWidget( dialBox, i / numRows, i % numRows ); + } +} + diff --git a/ThirdParty/Qwt/examples/controls/dialtab.h b/ThirdParty/Qwt/examples/controls/dialtab.h new file mode 100644 index 0000000000..61812d24e9 --- /dev/null +++ b/ThirdParty/Qwt/examples/controls/dialtab.h @@ -0,0 +1,12 @@ +#ifndef _DIAL_TAB_H +#define _DIAL_TAB_H 1 + +#include + +class DialTab: public QWidget +{ +public: + DialTab( QWidget *parent = NULL ); +}; + +#endif diff --git a/ThirdParty/Qwt/examples/controls/knobbox.cpp b/ThirdParty/Qwt/examples/controls/knobbox.cpp new file mode 100644 index 0000000000..45d82eb794 --- /dev/null +++ b/ThirdParty/Qwt/examples/controls/knobbox.cpp @@ -0,0 +1,119 @@ +#include +#include +#include +#include +#include +#include "knobbox.h" + +KnobBox::KnobBox( QWidget *parent, int knobType ): + QWidget( parent ) +{ + d_knob = createKnob( knobType ); + d_knob->setKnobWidth( 100 ); + + d_label = new QLabel( this ); + d_label->setAlignment( Qt::AlignCenter ); + + QVBoxLayout *layout = new QVBoxLayout( this );; + layout->setSpacing( 0 ); + layout->addWidget( d_knob, 10 ); + layout->addWidget( d_label ); + layout->addStretch( 10 ); + + connect( d_knob, SIGNAL( valueChanged( double ) ), + this, SLOT( setNum( double ) ) ); + + setNum( d_knob->value() ); +} + +QwtKnob *KnobBox::createKnob( int knobType ) const +{ + QwtKnob *knob = new QwtKnob(); + knob->setTracking( true ); + + switch( knobType ) + { + case 0: + { + knob->setKnobStyle( QwtKnob::Sunken ); + knob->setMarkerStyle( QwtKnob::Nub ); + knob->setWrapping( true ); + knob->setNumTurns( 4 ); + knob->setScaleStepSize( 10.0 ); + knob->setScale( 0, 400 ); + knob->setTotalSteps( 400 ); + break; + } + case 1: + { + knob->setKnobStyle( QwtKnob::Sunken ); + knob->setMarkerStyle( QwtKnob::Dot ); + break; + } + case 2: + { + knob->setKnobStyle( QwtKnob::Sunken ); + knob->setMarkerStyle( QwtKnob::Tick ); + + QwtLinearScaleEngine *scaleEngine = new QwtLinearScaleEngine( 2 ); + scaleEngine->setTransformation( new QwtPowerTransform( 2 ) ); + knob->setScaleEngine( scaleEngine ); + + QList< double > ticks[ QwtScaleDiv::NTickTypes ]; + ticks[ QwtScaleDiv::MajorTick ] << 0 << 4 + << 16 << 32 << 64 << 96 << 128; + ticks[ QwtScaleDiv::MediumTick ] << 24 << 48 << 80 << 112; + ticks[ QwtScaleDiv::MinorTick ] + << 0.5 << 1 << 2 + << 7 << 10 << 13 + << 20 << 28 + << 40 << 56 + << 72 << 88 + << 104 << 120; + + knob->setScale( QwtScaleDiv( 0, 128, ticks ) ); + + knob->setTotalSteps( 100 ); + knob->setStepAlignment( false ); + knob->setSingleSteps( 1 ); + knob->setPageSteps( 5 ); + + break; + } + case 3: + { + knob->setKnobStyle( QwtKnob::Flat ); + knob->setMarkerStyle( QwtKnob::Notch ); + knob->setScaleEngine( new QwtLogScaleEngine() ); + knob->setScaleStepSize( 1.0 ); + knob->setScale( 0.1, 1000.0 ); + knob->setScaleMaxMinor( 10 ); + break; + } + case 4: + { + knob->setKnobStyle( QwtKnob::Raised ); + knob->setMarkerStyle( QwtKnob::Dot ); + knob->setWrapping( true ); + break; + } + case 5: + { + knob->setKnobStyle( QwtKnob::Styled ); + knob->setMarkerStyle( QwtKnob::Triangle ); + knob->setTotalAngle( 180.0 ); + knob->setScale( 100, -100 ); + break; + } + } + + return knob; +} + +void KnobBox::setNum( double v ) +{ + QString text; + text.setNum( v, 'f', 2 ); + + d_label->setText( text ); +} diff --git a/ThirdParty/Qwt/examples/controls/knobbox.h b/ThirdParty/Qwt/examples/controls/knobbox.h new file mode 100644 index 0000000000..5b5fcef371 --- /dev/null +++ b/ThirdParty/Qwt/examples/controls/knobbox.h @@ -0,0 +1,25 @@ +#ifndef _KNOB_BOX_H_ +#define _KNOB_BOX_H_ + +#include + +class QLabel; +class QwtKnob; + +class KnobBox: public QWidget +{ + Q_OBJECT +public: + KnobBox( QWidget *parent, int knobType ); + +private Q_SLOTS: + void setNum( double v ); + +private: + QwtKnob *createKnob( int knobType ) const; + + QwtKnob *d_knob; + QLabel *d_label; +}; + +#endif diff --git a/ThirdParty/Qwt/examples/controls/knobtab.cpp b/ThirdParty/Qwt/examples/controls/knobtab.cpp new file mode 100644 index 0000000000..dc3ad5d383 --- /dev/null +++ b/ThirdParty/Qwt/examples/controls/knobtab.cpp @@ -0,0 +1,17 @@ +#include "knobtab.h" +#include "knobbox.h" +#include + +KnobTab::KnobTab( QWidget *parent ): + QWidget( parent ) +{ + QGridLayout *layout = new QGridLayout( this ); + + const int numRows = 3; + for ( int i = 0; i < 2 * numRows; i++ ) + { + KnobBox *knobBox = new KnobBox( this, i ); + layout->addWidget( knobBox, i / numRows, i % numRows ); + } +} + diff --git a/ThirdParty/Qwt/examples/controls/knobtab.h b/ThirdParty/Qwt/examples/controls/knobtab.h new file mode 100644 index 0000000000..731668b12a --- /dev/null +++ b/ThirdParty/Qwt/examples/controls/knobtab.h @@ -0,0 +1,12 @@ +#ifndef _KNOB_TAB_H +#define _KNOB_TAB_H 1 + +#include + +class KnobTab: public QWidget +{ +public: + KnobTab( QWidget *parent = NULL ); +}; + +#endif diff --git a/ThirdParty/Qwt/examples/controls/main.cpp b/ThirdParty/Qwt/examples/controls/main.cpp new file mode 100644 index 0000000000..755633aa22 --- /dev/null +++ b/ThirdParty/Qwt/examples/controls/main.cpp @@ -0,0 +1,41 @@ +#include +#include +#include "slidertab.h" +#include "wheeltab.h" +#include "knobtab.h" +#include "dialtab.h" + + +int main ( int argc, char **argv ) +{ + QApplication a( argc, argv ); + + QTabWidget tabWidget; + + SliderTab *sliderTab = new SliderTab(); + sliderTab->setAutoFillBackground( true ); + sliderTab->setPalette( QColor( "DimGray" ) ); + + WheelTab *wheelTab = new WheelTab(); + wheelTab->setAutoFillBackground( true ); + wheelTab->setPalette( QColor( "Silver" ) ); + + KnobTab *knobTab = new KnobTab(); + knobTab->setAutoFillBackground( true ); + knobTab->setPalette( Qt::darkGray ); + + DialTab *dialTab = new DialTab(); + dialTab->setAutoFillBackground( true ); + dialTab->setPalette( Qt::darkGray ); + + tabWidget.addTab( new SliderTab, "Slider" ); + tabWidget.addTab( new WheelTab, "Wheel/Thermo" ); + tabWidget.addTab( knobTab, "Knob" ); + tabWidget.addTab( dialTab, "Dial" ); + + tabWidget.resize( 800, 600 ); + tabWidget.show(); + + return a.exec(); +} + diff --git a/ThirdParty/Qwt/examples/controls/sliderbox.cpp b/ThirdParty/Qwt/examples/controls/sliderbox.cpp new file mode 100644 index 0000000000..ac059e348a --- /dev/null +++ b/ThirdParty/Qwt/examples/controls/sliderbox.cpp @@ -0,0 +1,172 @@ +#include +#include +#include +#include +#include +#include "sliderbox.h" + +SliderBox::SliderBox( int sliderType, QWidget *parent ): + QWidget( parent ) +{ + d_slider = createSlider( sliderType ); + + QFlags alignment; + + if ( d_slider->orientation() == Qt::Horizontal ) + { + if ( d_slider->scalePosition() == QwtSlider::TrailingScale ) + alignment = Qt::AlignBottom; + else + alignment = Qt::AlignTop; + + alignment |= Qt::AlignHCenter; + } + else + { + if ( d_slider->scalePosition() == QwtSlider::TrailingScale ) + alignment = Qt::AlignRight; + else + alignment = Qt::AlignLeft; + + alignment |= Qt::AlignVCenter; + } + + d_label = new QLabel( this ); + d_label->setAlignment( alignment ); + d_label->setFixedWidth( d_label->fontMetrics().width( "10000.9" ) ); + + connect( d_slider, SIGNAL( valueChanged( double ) ), SLOT( setNum( double ) ) ); + + QBoxLayout *layout; + if ( d_slider->orientation() == Qt::Horizontal ) + layout = new QHBoxLayout( this ); + else + layout = new QVBoxLayout( this ); + + layout->addWidget( d_slider ); + layout->addWidget( d_label ); + + setNum( d_slider->value() ); +} + +QwtSlider *SliderBox::createSlider( int sliderType ) const +{ + QwtSlider *slider = new QwtSlider(); + + switch( sliderType ) + { + case 0: + { + slider->setOrientation( Qt::Horizontal ); + slider->setScalePosition( QwtSlider::TrailingScale ); + slider->setTrough( true ); + slider->setGroove( false ); + slider->setSpacing( 0 ); + slider->setHandleSize( QSize( 30, 16 ) ); + slider->setScale( 10.0, -10.0 ); + slider->setTotalSteps( 8 ); + slider->setSingleSteps( 1 ); + slider->setPageSteps( 1 ); + slider->setWrapping( true ); + break; + } + case 1: + { + slider->setOrientation( Qt::Horizontal ); + slider->setScalePosition( QwtSlider::NoScale ); + slider->setTrough( true ); + slider->setGroove( true ); + slider->setScale( 0.0, 1.0 ); + slider->setTotalSteps( 100 ); + slider->setSingleSteps( 1 ); + slider->setPageSteps( 5 ); + break; + } + case 2: + { + slider->setOrientation( Qt::Horizontal ); + slider->setScalePosition( QwtSlider::LeadingScale ); + slider->setTrough( false ); + slider->setGroove( true ); + slider->setHandleSize( QSize( 12, 25 ) ); + slider->setScale( 1000.0, 3000.0 ); + slider->setTotalSteps( 200.0 ); + slider->setSingleSteps( 2 ); + slider->setPageSteps( 10 ); + break; + } + case 3: + { + slider->setOrientation( Qt::Horizontal ); + slider->setScalePosition( QwtSlider::TrailingScale ); + slider->setTrough( true ); + slider->setGroove( true ); + + QwtLinearScaleEngine *scaleEngine = new QwtLinearScaleEngine( 2 ); + scaleEngine->setTransformation( new QwtPowerTransform( 2 ) ); + slider->setScaleEngine( scaleEngine ); + slider->setScale( 0.0, 128.0 ); + slider->setTotalSteps( 100 ); + slider->setStepAlignment( false ); + slider->setSingleSteps( 1 ); + slider->setPageSteps( 5 ); + break; + } + case 4: + { + slider->setOrientation( Qt::Vertical ); + slider->setScalePosition( QwtSlider::TrailingScale ); + slider->setTrough( false ); + slider->setGroove( true ); + slider->setScale( 100.0, 0.0 ); + slider->setInvertedControls( true ); + slider->setTotalSteps( 100 ); + slider->setPageSteps( 5 ); + slider->setScaleMaxMinor( 5 ); + break; + } + case 5: + { + slider->setOrientation( Qt::Vertical ); + slider->setScalePosition( QwtSlider::NoScale ); + slider->setTrough( true ); + slider->setGroove( false ); + slider->setScale( 0.0, 100.0 ); + slider->setTotalSteps( 100 ); + slider->setPageSteps( 10 ); + break; + } + case 6: + { + slider->setOrientation( Qt::Vertical ); + slider->setScalePosition( QwtSlider::LeadingScale ); + slider->setTrough( true ); + slider->setGroove( true ); + slider->setScaleEngine( new QwtLogScaleEngine ); + slider->setStepAlignment( false ); + slider->setHandleSize( QSize( 20, 32 ) ); + slider->setBorderWidth( 1 ); + slider->setScale( 1.0, 1.0e4 ); + slider->setTotalSteps( 100 ); + slider->setPageSteps( 10 ); + slider->setScaleMaxMinor( 9 ); + break; + } + } + + if ( slider ) + { + QString name( "Slider %1" ); + slider->setObjectName( name.arg( sliderType ) ); + } + + return slider; +} + +void SliderBox::setNum( double v ) +{ + QString text; + text.setNum( v, 'f', 2 ); + + d_label->setText( text ); +} diff --git a/ThirdParty/Qwt/examples/controls/sliderbox.h b/ThirdParty/Qwt/examples/controls/sliderbox.h new file mode 100644 index 0000000000..c79accdee0 --- /dev/null +++ b/ThirdParty/Qwt/examples/controls/sliderbox.h @@ -0,0 +1,25 @@ +#ifndef _SLIDER_BOX_H_ +#define _SLIDER_BOX_H_ 1 + +#include + +class QLabel; +class QwtSlider; + +class SliderBox: public QWidget +{ + Q_OBJECT +public: + SliderBox( int sliderType, QWidget *parent = NULL ); + +private Q_SLOTS: + void setNum( double v ); + +private: + QwtSlider *createSlider( int sliderType ) const; + + QwtSlider *d_slider; + QLabel *d_label; +}; + +#endif diff --git a/ThirdParty/Qwt/examples/controls/slidertab.cpp b/ThirdParty/Qwt/examples/controls/slidertab.cpp new file mode 100644 index 0000000000..311d6433c9 --- /dev/null +++ b/ThirdParty/Qwt/examples/controls/slidertab.cpp @@ -0,0 +1,37 @@ +#include "slidertab.h" +#include "sliderbox.h" +#include + +SliderTab::SliderTab( QWidget *parent ): + QWidget( parent ) +{ + int i; + + QBoxLayout *hLayout = createLayout( Qt::Vertical ); + for ( i = 0; i < 4; i++ ) + hLayout->addWidget( new SliderBox( i ) ); + hLayout->addStretch(); + + QBoxLayout *vLayout = createLayout( Qt::Horizontal ); + for ( ; i < 7; i++ ) + vLayout->addWidget( new SliderBox( i ) ); + + QBoxLayout *mainLayout = createLayout( Qt::Horizontal, this ); + mainLayout->addLayout( vLayout ); + mainLayout->addLayout( hLayout, 10 ); +} + +QBoxLayout *SliderTab::createLayout( + Qt::Orientation orientation, QWidget *widget ) +{ + QBoxLayout *layout = + new QBoxLayout( QBoxLayout::LeftToRight, widget ); + + if ( orientation == Qt::Vertical ) + layout->setDirection( QBoxLayout::TopToBottom ); + + layout->setSpacing( 20 ); + layout->setMargin( 0 ); + + return layout; +} diff --git a/ThirdParty/Qwt/examples/controls/slidertab.h b/ThirdParty/Qwt/examples/controls/slidertab.h new file mode 100644 index 0000000000..ffa243c07c --- /dev/null +++ b/ThirdParty/Qwt/examples/controls/slidertab.h @@ -0,0 +1,18 @@ +#ifndef _SLIDER_TAB_H +#define _SLIDER_TAB_H 1 + +#include + +class QBoxLayout; + +class SliderTab: public QWidget +{ +public: + SliderTab( QWidget *parent = NULL ); + +private: + QBoxLayout *createLayout( Qt::Orientation, + QWidget *widget = NULL ); +}; + +#endif diff --git a/ThirdParty/Qwt/examples/controls/wheelbox.cpp b/ThirdParty/Qwt/examples/controls/wheelbox.cpp new file mode 100644 index 0000000000..141b003416 --- /dev/null +++ b/ThirdParty/Qwt/examples/controls/wheelbox.cpp @@ -0,0 +1,188 @@ +#include +#include +#include +#include +#include +#include +#include +#include "wheelbox.h" + +WheelBox::WheelBox( Qt::Orientation orientation, + int type, QWidget *parent ): + QWidget( parent ) +{ + QWidget *box = createBox( orientation, type ); + d_label = new QLabel( this ); + d_label->setAlignment( Qt::AlignHCenter | Qt::AlignTop ); + + QBoxLayout *layout = new QVBoxLayout( this ); + layout->addWidget( box ); + layout->addWidget( d_label ); + + setNum( d_wheel->value() ); + + connect( d_wheel, SIGNAL( valueChanged( double ) ), + this, SLOT( setNum( double ) ) ); +} + +QWidget *WheelBox::createBox( + Qt::Orientation orientation, int type ) +{ + d_wheel = new QwtWheel(); + d_wheel->setValue( 80 ); + d_wheel->setWheelWidth( 20 ); + d_wheel->setMass( 1.0 ); + + d_thermo = new QwtThermo(); + d_thermo->setOrientation( orientation ); + + if ( orientation == Qt::Horizontal ) + { + d_thermo->setScalePosition( QwtThermo::LeadingScale ); + d_wheel->setOrientation( Qt::Vertical ); + } + else + { + d_thermo->setScalePosition( QwtThermo::TrailingScale ); + d_wheel->setOrientation( Qt::Horizontal ); + } + + switch( type ) + { + case 0: + { + QwtLinearColorMap *colorMap = new QwtLinearColorMap(); + colorMap->setColorInterval( Qt::blue, Qt::red ); + d_thermo->setColorMap( colorMap ); + + break; + } + case 1: + { + QwtLinearColorMap *colorMap = new QwtLinearColorMap(); + colorMap->setMode( QwtLinearColorMap::FixedColors ); + + int idx = 4; + + colorMap->setColorInterval( Qt::GlobalColor( idx ), + Qt::GlobalColor( idx + 10 ) ); + for ( int i = 1; i < 10; i++ ) + { + colorMap->addColorStop( i / 10.0, + Qt::GlobalColor( idx + i ) ); + } + + d_thermo->setColorMap( colorMap ); + break; + } + case 2: + { + d_wheel->setRange( 10, 1000 ); + d_wheel->setSingleStep( 1.0 ); + + d_thermo->setScaleEngine( new QwtLogScaleEngine ); + d_thermo->setScaleMaxMinor( 10 ); + + d_thermo->setFillBrush( Qt::darkCyan ); + d_thermo->setAlarmBrush( Qt::magenta ); + d_thermo->setAlarmLevel( 500.0 ); + + d_wheel->setValue( 800 ); + + break; + } + case 3: + { + d_wheel->setRange( -1000, 1000 ); + d_wheel->setSingleStep( 1.0 ); + d_wheel->setPalette( QColor( "Tan" ) ); + + QwtLinearScaleEngine *scaleEngine = new QwtLinearScaleEngine(); + scaleEngine->setTransformation( new QwtPowerTransform( 2 ) ); + + d_thermo->setScaleMaxMinor( 5 ); + d_thermo->setScaleEngine( scaleEngine ); + + QPalette pal = palette(); + pal.setColor( QPalette::Base, Qt::darkGray ); + pal.setColor( QPalette::ButtonText, QColor( "darkKhaki" ) ); + + d_thermo->setPalette( pal ); + break; + } + case 4: + { + d_wheel->setRange( -100, 300 ); + d_wheel->setInverted( true ); + + QwtLinearColorMap *colorMap = new QwtLinearColorMap(); + colorMap->setColorInterval( Qt::darkCyan, Qt::yellow ); + d_thermo->setColorMap( colorMap ); + + d_wheel->setValue( 243 ); + + break; + } + case 5: + { + d_thermo->setFillBrush( Qt::darkCyan ); + d_thermo->setAlarmBrush( Qt::magenta ); + d_thermo->setAlarmLevel( 60.0 ); + + break; + } + case 6: + { + d_thermo->setOriginMode( QwtThermo::OriginMinimum ); + d_thermo->setFillBrush( QBrush( "DarkSlateBlue" ) ); + d_thermo->setAlarmBrush( QBrush( "DarkOrange" ) ); + d_thermo->setAlarmLevel( 60.0 ); + + break; + } + case 7: + { + d_wheel->setRange( -100, 100 ); + + d_thermo->setOriginMode( QwtThermo::OriginCustom ); + d_thermo->setOrigin( 0.0 ); + d_thermo->setFillBrush( Qt::darkBlue ); + + break; + } + } + + double min = d_wheel->minimum(); + double max = d_wheel->maximum(); + + if ( d_wheel->isInverted() ) + qSwap( min, max ); + + d_thermo->setScale( min, max ); + d_thermo->setValue( d_wheel->value() ); + + connect( d_wheel, SIGNAL( valueChanged( double ) ), + d_thermo, SLOT( setValue( double ) ) ); + + QWidget *box = new QWidget(); + + QBoxLayout *layout; + + if ( orientation == Qt::Horizontal ) + layout = new QHBoxLayout( box ); + else + layout = new QVBoxLayout( box ); + + layout->addWidget( d_thermo, Qt::AlignCenter ); + layout->addWidget( d_wheel ); + + return box; +} + +void WheelBox::setNum( double v ) +{ + QString text; + text.setNum( v, 'f', 2 ); + + d_label->setText( text ); +} diff --git a/ThirdParty/Qwt/examples/controls/wheelbox.h b/ThirdParty/Qwt/examples/controls/wheelbox.h new file mode 100644 index 0000000000..4381fa2c87 --- /dev/null +++ b/ThirdParty/Qwt/examples/controls/wheelbox.h @@ -0,0 +1,29 @@ +#ifndef _WHEEL_BOX_H_ +#define _WHEEL_BOX_H_ 1 + +#include + +class QLabel; +class QwtThermo; +class QwtWheel; + +class WheelBox: public QWidget +{ + Q_OBJECT +public: + WheelBox( Qt::Orientation, + int type, QWidget *parent = NULL ); + +private Q_SLOTS: + void setNum( double v ); + +private: + QWidget *createBox( Qt::Orientation, int type ); + +private: + QwtWheel *d_wheel; + QwtThermo *d_thermo; + QLabel *d_label; +}; + +#endif diff --git a/ThirdParty/Qwt/examples/controls/wheeltab.cpp b/ThirdParty/Qwt/examples/controls/wheeltab.cpp new file mode 100644 index 0000000000..a309a6f5a0 --- /dev/null +++ b/ThirdParty/Qwt/examples/controls/wheeltab.cpp @@ -0,0 +1,28 @@ +#include "wheeltab.h" +#include "wheelbox.h" +#include + +WheelTab::WheelTab( QWidget *parent ): + QWidget( parent ) +{ + const int numBoxes = 4; + + QGridLayout *layout1 = new QGridLayout(); + for ( int i = 0; i < numBoxes; i++ ) + { + WheelBox *box = new WheelBox( Qt::Vertical, i ); + layout1->addWidget( box, i / 2, i % 2 ); + } + + QGridLayout *layout2 = new QGridLayout(); + for ( int i = 0; i < numBoxes; i++ ) + { + WheelBox *box = new WheelBox( Qt::Horizontal, i + numBoxes ); + layout2->addWidget( box, i / 2, i % 2 ); + } + + QHBoxLayout *layout = new QHBoxLayout( this ); + layout->addLayout( layout1, 2 ); + layout->addLayout( layout2, 5 ); +} + diff --git a/ThirdParty/Qwt/examples/controls/wheeltab.h b/ThirdParty/Qwt/examples/controls/wheeltab.h new file mode 100644 index 0000000000..4ea971789f --- /dev/null +++ b/ThirdParty/Qwt/examples/controls/wheeltab.h @@ -0,0 +1,12 @@ +#ifndef _WHEEL_TAB_H +#define _WHEEL_TAB_H 1 + +#include + +class WheelTab: public QWidget +{ +public: + WheelTab( QWidget *parent = NULL ); +}; + +#endif diff --git a/ThirdParty/Qwt/examples/cpuplot/cpupiemarker.cpp b/ThirdParty/Qwt/examples/cpuplot/cpupiemarker.cpp new file mode 100644 index 0000000000..5de5f7cd59 --- /dev/null +++ b/ThirdParty/Qwt/examples/cpuplot/cpupiemarker.cpp @@ -0,0 +1,55 @@ +#include +#include +#include +#include "cpuplot.h" +#include "cpupiemarker.h" + +CpuPieMarker::CpuPieMarker() +{ + setZ( 1000 ); + setRenderHint( QwtPlotItem::RenderAntialiased, true ); +} + +int CpuPieMarker::rtti() const +{ + return QwtPlotItem::Rtti_PlotUserItem; +} + +void CpuPieMarker::draw( QPainter *painter, + const QwtScaleMap &, const QwtScaleMap &, + const QRectF &rect ) const +{ + const CpuPlot *cpuPlot = static_cast ( plot() ); + + const QwtScaleMap yMap = cpuPlot->canvasMap( QwtPlot::yLeft ); + + const int margin = 5; + + QRectF pieRect; + pieRect.setX( rect.x() + margin ); + pieRect.setY( rect.y() + margin ); + pieRect.setHeight( yMap.transform( 80.0 ) ); + pieRect.setWidth( pieRect.height() ); + + const int dataType[] = { CpuPlot::User, CpuPlot::System, CpuPlot::Idle }; + + int angle = static_cast( 5760 * 0.75 ); + for ( unsigned int i = 0; + i < sizeof( dataType ) / sizeof( dataType[0] ); i++ ) + { + const QwtPlotCurve *curve = cpuPlot->cpuCurve( dataType[i] ); + if ( curve->dataSize() > 0 ) + { + const int value = static_cast( 5760 * curve->sample( 0 ).y() / 100.0 ); + + painter->save(); + painter->setBrush( QBrush( curve->pen().color(), Qt::SolidPattern ) ); + if ( value != 0 ) + painter->drawPie( pieRect, -angle, -value ); + painter->restore(); + + angle += value; + } + } +} + diff --git a/ThirdParty/Qwt/examples/cpuplot/cpupiemarker.h b/ThirdParty/Qwt/examples/cpuplot/cpupiemarker.h new file mode 100644 index 0000000000..366138a563 --- /dev/null +++ b/ThirdParty/Qwt/examples/cpuplot/cpupiemarker.h @@ -0,0 +1,17 @@ +//----------------------------------------------------------------- +// This class shows how to extend QwtPlotItems. It displays a +// pie chart of user/total/idle cpu usage in percent. +//----------------------------------------------------------------- + +#include + +class CpuPieMarker: public QwtPlotItem +{ +public: + CpuPieMarker(); + + virtual int rtti() const; + + virtual void draw( QPainter *, + const QwtScaleMap &, const QwtScaleMap &, const QRectF & ) const; +}; diff --git a/ThirdParty/Qwt/examples/cpuplot/cpuplot.cpp b/ThirdParty/Qwt/examples/cpuplot/cpuplot.cpp new file mode 100644 index 0000000000..2a3c24b168 --- /dev/null +++ b/ThirdParty/Qwt/examples/cpuplot/cpuplot.cpp @@ -0,0 +1,254 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "cpupiemarker.h" +#include "cpuplot.h" + +class TimeScaleDraw: public QwtScaleDraw +{ +public: + TimeScaleDraw( const QTime &base ): + baseTime( base ) + { + } + virtual QwtText label( double v ) const + { + QTime upTime = baseTime.addSecs( static_cast( v ) ); + return upTime.toString(); + } +private: + QTime baseTime; +}; + +class Background: public QwtPlotItem +{ +public: + Background() + { + setZ( 0.0 ); + } + + virtual int rtti() const + { + return QwtPlotItem::Rtti_PlotUserItem; + } + + virtual void draw( QPainter *painter, + const QwtScaleMap &, const QwtScaleMap &yMap, + const QRectF &canvasRect ) const + { + QColor c( Qt::white ); + QRectF r = canvasRect; + + for ( int i = 100; i > 0; i -= 10 ) + { + r.setBottom( yMap.transform( i - 10 ) ); + r.setTop( yMap.transform( i ) ); + painter->fillRect( r, c ); + + c = c.dark( 110 ); + } + } +}; + +class CpuCurve: public QwtPlotCurve +{ +public: + CpuCurve( const QString &title ): + QwtPlotCurve( title ) + { + setRenderHint( QwtPlotItem::RenderAntialiased ); + } + + void setColor( const QColor &color ) + { + QColor c = color; + c.setAlpha( 150 ); + + setPen( c ); + setBrush( c ); + } +}; + +CpuPlot::CpuPlot( QWidget *parent ): + QwtPlot( parent ), + dataCount( 0 ) +{ + setAutoReplot( false ); + + QwtPlotCanvas *canvas = new QwtPlotCanvas(); + canvas->setBorderRadius( 10 ); + + setCanvas( canvas ); + + plotLayout()->setAlignCanvasToScales( true ); + + QwtLegend *legend = new QwtLegend; + legend->setDefaultItemMode( QwtLegendData::Checkable ); + insertLegend( legend, QwtPlot::RightLegend ); + + setAxisTitle( QwtPlot::xBottom, " System Uptime [h:m:s]" ); + setAxisScaleDraw( QwtPlot::xBottom, + new TimeScaleDraw( cpuStat.upTime() ) ); + setAxisScale( QwtPlot::xBottom, 0, HISTORY ); + setAxisLabelRotation( QwtPlot::xBottom, -50.0 ); + setAxisLabelAlignment( QwtPlot::xBottom, Qt::AlignLeft | Qt::AlignBottom ); + + /* + In situations, when there is a label at the most right position of the + scale, additional space is needed to display the overlapping part + of the label would be taken by reducing the width of scale and canvas. + To avoid this "jumping canvas" effect, we add a permanent margin. + We don't need to do the same for the left border, because there + is enough space for the overlapping label below the left scale. + */ + + QwtScaleWidget *scaleWidget = axisWidget( QwtPlot::xBottom ); + const int fmh = QFontMetrics( scaleWidget->font() ).height(); + scaleWidget->setMinBorderDist( 0, fmh / 2 ); + + setAxisTitle( QwtPlot::yLeft, "Cpu Usage [%]" ); + setAxisScale( QwtPlot::yLeft, 0, 100 ); + + Background *bg = new Background(); + bg->attach( this ); + + CpuPieMarker *pie = new CpuPieMarker(); + pie->attach( this ); + + CpuCurve *curve; + + curve = new CpuCurve( "System" ); + curve->setColor( Qt::red ); + curve->attach( this ); + data[System].curve = curve; + + curve = new CpuCurve( "User" ); + curve->setColor( Qt::blue ); + curve->setZ( curve->z() - 1 ); + curve->attach( this ); + data[User].curve = curve; + + curve = new CpuCurve( "Total" ); + curve->setColor( Qt::black ); + curve->setZ( curve->z() - 2 ); + curve->attach( this ); + data[Total].curve = curve; + + curve = new CpuCurve( "Idle" ); + curve->setColor( Qt::darkCyan ); + curve->setZ( curve->z() - 3 ); + curve->attach( this ); + data[Idle].curve = curve; + + showCurve( data[System].curve, true ); + showCurve( data[User].curve, true ); + showCurve( data[Total].curve, false ); + showCurve( data[Idle].curve, false ); + + for ( int i = 0; i < HISTORY; i++ ) + timeData[HISTORY - 1 - i] = i; + + ( void )startTimer( 1000 ); // 1 second + + connect( legend, SIGNAL( checked( const QVariant &, bool, int ) ), + SLOT( legendChecked( const QVariant &, bool ) ) ); +} + +void CpuPlot::timerEvent( QTimerEvent * ) +{ + for ( int i = dataCount; i > 0; i-- ) + { + for ( int c = 0; c < NCpuData; c++ ) + { + if ( i < HISTORY ) + data[c].data[i] = data[c].data[i-1]; + } + } + + cpuStat.statistic( data[User].data[0], data[System].data[0] ); + + data[Total].data[0] = data[User].data[0] + data[System].data[0]; + data[Idle].data[0] = 100.0 - data[Total].data[0]; + + if ( dataCount < HISTORY ) + dataCount++; + + for ( int j = 0; j < HISTORY; j++ ) + timeData[j]++; + + setAxisScale( QwtPlot::xBottom, + timeData[HISTORY - 1], timeData[0] ); + + for ( int c = 0; c < NCpuData; c++ ) + { + data[c].curve->setRawSamples( + timeData, data[c].data, dataCount ); + } + + replot(); +} + +void CpuPlot::legendChecked( const QVariant &itemInfo, bool on ) +{ + QwtPlotItem *plotItem = infoToItem( itemInfo ); + if ( plotItem ) + showCurve( plotItem, on ); +} + +void CpuPlot::showCurve( QwtPlotItem *item, bool on ) +{ + item->setVisible( on ); + + QwtLegend *lgd = qobject_cast( legend() ); + + QList legendWidgets = + lgd->legendWidgets( itemToInfo( item ) ); + + if ( legendWidgets.size() == 1 ) + { + QwtLegendLabel *legendLabel = + qobject_cast( legendWidgets[0] ); + + if ( legendLabel ) + legendLabel->setChecked( on ); + } + + replot(); +} + +int main( int argc, char **argv ) +{ + QApplication a( argc, argv ); + + QWidget vBox; + vBox.setWindowTitle( "Cpu Plot" ); + + CpuPlot *plot = new CpuPlot( &vBox ); + plot->setTitle( "History" ); + + const int margin = 5; + plot->setContentsMargins( margin, margin, margin, margin ); + + QString info( "Press the legend to en/disable a curve" ); + + QLabel *label = new QLabel( info, &vBox ); + + QVBoxLayout *layout = new QVBoxLayout( &vBox ); + layout->addWidget( plot ); + layout->addWidget( label ); + + vBox.resize( 600, 400 ); + vBox.show(); + + return a.exec(); +} + diff --git a/ThirdParty/Qwt/examples/cpuplot/cpuplot.h b/ThirdParty/Qwt/examples/cpuplot/cpuplot.h new file mode 100644 index 0000000000..a0c39a3f87 --- /dev/null +++ b/ThirdParty/Qwt/examples/cpuplot/cpuplot.h @@ -0,0 +1,47 @@ +#include +#include "cpustat.h" + +#define HISTORY 60 // seconds + +class QwtPlotCurve; + +class CpuPlot : public QwtPlot +{ + Q_OBJECT +public: + enum CpuData + { + User, + System, + Total, + Idle, + + NCpuData + }; + + CpuPlot( QWidget * = 0 ); + const QwtPlotCurve *cpuCurve( int id ) const + { + return data[id].curve; + } + +protected: + void timerEvent( QTimerEvent *e ); + +private Q_SLOTS: + void legendChecked( const QVariant &, bool on ); + +private: + void showCurve( QwtPlotItem *, bool on ); + + struct + { + QwtPlotCurve *curve; + double data[HISTORY]; + } data[NCpuData]; + + double timeData[HISTORY]; + + int dataCount; + CpuStat cpuStat; +}; diff --git a/ThirdParty/Qwt/examples/cpuplot/cpuplot.pro b/ThirdParty/Qwt/examples/cpuplot/cpuplot.pro new file mode 100644 index 0000000000..1cc631299b --- /dev/null +++ b/ThirdParty/Qwt/examples/cpuplot/cpuplot.pro @@ -0,0 +1,22 @@ +################################################################ +# Qwt Widget Library +# Copyright (C) 1997 Josef Wilgen +# Copyright (C) 2002 Uwe Rathmann +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the Qwt License, Version 1.0 +################################################################ + +include( $${PWD}/../examples.pri ) + +TARGET = cpuplot + +HEADERS = \ + cpuplot.h \ + cpustat.h \ + cpupiemarker.h + +SOURCES = \ + cpuplot.cpp \ + cpustat.cpp \ + cpupiemarker.cpp diff --git a/ThirdParty/Qwt/examples/cpuplot/cpustat.cpp b/ThirdParty/Qwt/examples/cpuplot/cpustat.cpp new file mode 100644 index 0000000000..f9c7552ca7 --- /dev/null +++ b/ThirdParty/Qwt/examples/cpuplot/cpustat.cpp @@ -0,0 +1,220 @@ +#include +#include +#include +#include "cpustat.h" + +CpuStat::CpuStat() +{ + lookUp( procValues ); +} + +QTime CpuStat::upTime() const +{ + QTime t( 0, 0, 0 ); + for ( int i = 0; i < NValues; i++ ) + t = t.addSecs( int( procValues[i] / 100 ) ); + + return t; +} + +void CpuStat::statistic( double &user, double &system ) +{ + double values[NValues]; + + lookUp( values ); + + double userDelta = values[User] + values[Nice] + - procValues[User] - procValues[Nice]; + double systemDelta = values[System] - procValues[System]; + + double totalDelta = 0; + for ( int i = 0; i < NValues; i++ ) + totalDelta += values[i] - procValues[i]; + + user = userDelta / totalDelta * 100.0; + system = systemDelta / totalDelta * 100.0; + + for ( int j = 0; j < NValues; j++ ) + procValues[j] = values[j]; +} + +void CpuStat::lookUp( double values[NValues] ) const +{ + QFile file( "/proc/stat" ); + if ( !file.open( QIODevice::ReadOnly ) ) + { + static double dummyValues[][NValues] = + { + { 103726, 0, 23484, 819556 }, + { 103783, 0, 23489, 819604 }, + { 103798, 0, 23490, 819688 }, + { 103820, 0, 23490, 819766 }, + { 103840, 0, 23493, 819843 }, + { 103875, 0, 23499, 819902 }, + { 103917, 0, 23504, 819955 }, + { 103950, 0, 23508, 820018 }, + { 103987, 0, 23510, 820079 }, + { 104020, 0, 23513, 820143 }, + { 104058, 0, 23514, 820204 }, + { 104099, 0, 23520, 820257 }, + { 104121, 0, 23525, 820330 }, + { 104159, 0, 23530, 820387 }, + { 104176, 0, 23534, 820466 }, + { 104215, 0, 23538, 820523 }, + { 104245, 0, 23541, 820590 }, + { 104267, 0, 23545, 820664 }, + { 104311, 0, 23555, 820710 }, + { 104355, 0, 23565, 820756 }, + { 104367, 0, 23567, 820842 }, + { 104383, 0, 23572, 820921 }, + { 104396, 0, 23577, 821003 }, + { 104413, 0, 23579, 821084 }, + { 104446, 0, 23588, 821142 }, + { 104521, 0, 23594, 821161 }, + { 104611, 0, 23604, 821161 }, + { 104708, 0, 23607, 821161 }, + { 104804, 0, 23611, 821161 }, + { 104895, 0, 23620, 821161 }, + { 104993, 0, 23622, 821161 }, + { 105089, 0, 23626, 821161 }, + { 105185, 0, 23630, 821161 }, + { 105281, 0, 23634, 821161 }, + { 105379, 0, 23636, 821161 }, + { 105472, 0, 23643, 821161 }, + { 105569, 0, 23646, 821161 }, + { 105666, 0, 23649, 821161 }, + { 105763, 0, 23652, 821161 }, + { 105828, 0, 23661, 821187 }, + { 105904, 0, 23666, 821206 }, + { 105999, 0, 23671, 821206 }, + { 106094, 0, 23676, 821206 }, + { 106184, 0, 23686, 821206 }, + { 106273, 0, 23692, 821211 }, + { 106306, 0, 23700, 821270 }, + { 106341, 0, 23703, 821332 }, + { 106392, 0, 23709, 821375 }, + { 106423, 0, 23715, 821438 }, + { 106472, 0, 23721, 821483 }, + { 106531, 0, 23727, 821517 }, + { 106562, 0, 23732, 821582 }, + { 106597, 0, 23736, 821643 }, + { 106633, 0, 23737, 821706 }, + { 106666, 0, 23742, 821768 }, + { 106697, 0, 23744, 821835 }, + { 106730, 0, 23748, 821898 }, + { 106765, 0, 23751, 821960 }, + { 106799, 0, 23754, 822023 }, + { 106831, 0, 23758, 822087 }, + { 106862, 0, 23761, 822153 }, + { 106899, 0, 23763, 822214 }, + { 106932, 0, 23766, 822278 }, + { 106965, 0, 23768, 822343 }, + { 107009, 0, 23771, 822396 }, + { 107040, 0, 23775, 822461 }, + { 107092, 0, 23780, 822504 }, + { 107143, 0, 23787, 822546 }, + { 107200, 0, 23795, 822581 }, + { 107250, 0, 23803, 822623 }, + { 107277, 0, 23810, 822689 }, + { 107286, 0, 23810, 822780 }, + { 107313, 0, 23817, 822846 }, + { 107325, 0, 23818, 822933 }, + { 107332, 0, 23818, 823026 }, + { 107344, 0, 23821, 823111 }, + { 107357, 0, 23821, 823198 }, + { 107368, 0, 23823, 823284 }, + { 107375, 0, 23824, 823377 }, + { 107386, 0, 23825, 823465 }, + { 107396, 0, 23826, 823554 }, + { 107422, 0, 23830, 823624 }, + { 107434, 0, 23831, 823711 }, + { 107456, 0, 23835, 823785 }, + { 107468, 0, 23838, 823870 }, + { 107487, 0, 23840, 823949 }, + { 107515, 0, 23843, 824018 }, + { 107528, 0, 23846, 824102 }, + { 107535, 0, 23851, 824190 }, + { 107548, 0, 23853, 824275 }, + { 107562, 0, 23857, 824357 }, + { 107656, 0, 23863, 824357 }, + { 107751, 0, 23868, 824357 }, + { 107849, 0, 23870, 824357 }, + { 107944, 0, 23875, 824357 }, + { 108043, 0, 23876, 824357 }, + { 108137, 0, 23882, 824357 }, + { 108230, 0, 23889, 824357 }, + { 108317, 0, 23902, 824357 }, + { 108412, 0, 23907, 824357 }, + { 108511, 0, 23908, 824357 }, + { 108608, 0, 23911, 824357 }, + { 108704, 0, 23915, 824357 }, + { 108801, 0, 23918, 824357 }, + { 108891, 0, 23928, 824357 }, + { 108987, 0, 23932, 824357 }, + { 109072, 0, 23943, 824361 }, + { 109079, 0, 23943, 824454 }, + { 109086, 0, 23944, 824546 }, + { 109098, 0, 23950, 824628 }, + { 109108, 0, 23955, 824713 }, + { 109115, 0, 23957, 824804 }, + { 109122, 0, 23958, 824896 }, + { 109132, 0, 23959, 824985 }, + { 109142, 0, 23961, 825073 }, + { 109146, 0, 23962, 825168 }, + { 109153, 0, 23964, 825259 }, + { 109162, 0, 23966, 825348 }, + { 109168, 0, 23969, 825439 }, + { 109176, 0, 23971, 825529 }, + { 109185, 0, 23974, 825617 }, + { 109193, 0, 23977, 825706 }, + { 109198, 0, 23978, 825800 }, + { 109206, 0, 23978, 825892 }, + { 109212, 0, 23981, 825983 }, + { 109219, 0, 23981, 826076 }, + { 109225, 0, 23981, 826170 }, + { 109232, 0, 23984, 826260 }, + { 109242, 0, 23984, 826350 }, + { 109255, 0, 23986, 826435 }, + { 109268, 0, 23987, 826521 }, + { 109283, 0, 23990, 826603 }, + { 109288, 0, 23991, 826697 }, + { 109295, 0, 23993, 826788 }, + { 109308, 0, 23994, 826874 }, + { 109322, 0, 24009, 826945 }, + { 109328, 0, 24011, 827037 }, + { 109338, 0, 24012, 827126 }, + { 109347, 0, 24012, 827217 }, + { 109354, 0, 24017, 827305 }, + { 109367, 0, 24017, 827392 }, + { 109371, 0, 24019, 827486 }, + }; + static int counter = 0; + + for ( int i = 0; i < NValues; i++ ) + values[i] = dummyValues[counter][i]; + + counter = ( counter + 1 ) + % ( sizeof( dummyValues ) / sizeof( dummyValues[0] ) ); + } + else + { + QTextStream textStream( &file ); + do + { + QString line = textStream.readLine(); + line = line.trimmed(); + if ( line.startsWith( "cpu " ) ) + { + const QStringList valueList = + line.split( " ", QString::SkipEmptyParts ); + if ( valueList.count() >= 5 ) + { + for ( int i = 0; i < NValues; i++ ) + values[i] = valueList[i+1].toDouble(); + } + break; + } + } + while( !textStream.atEnd() ); + } +} diff --git a/ThirdParty/Qwt/examples/cpuplot/cpustat.h b/ThirdParty/Qwt/examples/cpuplot/cpustat.h new file mode 100644 index 0000000000..019bea8553 --- /dev/null +++ b/ThirdParty/Qwt/examples/cpuplot/cpustat.h @@ -0,0 +1,23 @@ +#include + +class CpuStat +{ +public: + CpuStat(); + void statistic( double &user, double &system ); + QTime upTime() const; + + enum Value + { + User, + Nice, + System, + Idle, + + NValues + }; + +private: + void lookUp( double[NValues] ) const; + double procValues[NValues]; +}; diff --git a/ThirdParty/Qwt/examples/curvdemo1/curvdemo1.cpp b/ThirdParty/Qwt/examples/curvdemo1/curvdemo1.cpp new file mode 100644 index 0000000000..e813dc1984 --- /dev/null +++ b/ThirdParty/Qwt/examples/curvdemo1/curvdemo1.cpp @@ -0,0 +1,202 @@ + +#include +#include +#include +#include +#include +#include +#include +#include + +//------------------------------------------------------------ +// curvdemo1 +// +// This example program features some of the different +// display styles of the QwtPlotCurve class +//------------------------------------------------------------ + + +// +// Array Sizes +// +const int Size = 27; +const int CurvCnt = 6; + +// +// Arrays holding the values +// +double xval[Size]; +double yval[Size]; +QwtScaleMap xMap; +QwtScaleMap yMap; + +class MainWin : public QFrame +{ +public: + MainWin(); + +protected: + virtual void paintEvent( QPaintEvent * ); + void drawContents( QPainter *p ); + +private: + void shiftDown( QRect &rect, int offset ) const; + + QwtPlotCurve d_curves[CurvCnt]; +}; + +MainWin::MainWin() +{ + int i; + + xMap.setScaleInterval( -0.5, 10.5 ); + yMap.setScaleInterval( -1.1, 1.1 ); + + // + // Frame style + // + setFrameStyle( QFrame::Box | QFrame::Raised ); + setLineWidth( 2 ); + setMidLineWidth( 3 ); + + // + // Calculate values + // + for( i = 0; i < Size; i++ ) + { + xval[i] = double( i ) * 10.0 / double( Size - 1 ); + yval[i] = qSin( xval[i] ) * qCos( 2.0 * xval[i] ); + } + + // + // define curve styles + // + i = 0; + + d_curves[i].setSymbol( new QwtSymbol( QwtSymbol::Cross, Qt::NoBrush, + QPen( Qt::black ), QSize( 5, 5 ) ) ); + d_curves[i].setPen( Qt::darkGreen ); + d_curves[i].setStyle( QwtPlotCurve::Lines ); + d_curves[i].setCurveAttribute( QwtPlotCurve::Fitted ); + i++; + + d_curves[i].setSymbol( new QwtSymbol( QwtSymbol::Ellipse, Qt::yellow, + QPen( Qt::blue ), QSize( 5, 5 ) ) ); + d_curves[i].setPen( Qt::red ); + d_curves[i].setStyle( QwtPlotCurve::Sticks ); + i++; + + d_curves[i].setPen( Qt::darkBlue ); + d_curves[i].setStyle( QwtPlotCurve::Lines ); + i++; + + d_curves[i].setPen( Qt::darkBlue ); + d_curves[i].setStyle( QwtPlotCurve::Lines ); + d_curves[i].setRenderHint( QwtPlotItem::RenderAntialiased ); + i++; + + d_curves[i].setPen( Qt::darkCyan ); + d_curves[i].setStyle( QwtPlotCurve::Steps ); + i++; + + d_curves[i].setSymbol( new QwtSymbol( QwtSymbol::XCross, Qt::NoBrush, + QPen( Qt::darkMagenta ), QSize( 5, 5 ) ) ); + d_curves[i].setStyle( QwtPlotCurve::NoCurve ); + i++; + + + // + // attach data + // + for( i = 0; i < CurvCnt; i++ ) + d_curves[i].setRawSamples( xval, yval, Size ); +} + +void MainWin::shiftDown( QRect &rect, int offset ) const +{ + rect.translate( 0, offset ); +} + +void MainWin::paintEvent( QPaintEvent *event ) +{ + QFrame::paintEvent( event ); + + QPainter painter( this ); + painter.setClipRect( contentsRect() ); + drawContents( &painter ); +} + + +// +// REDRAW CONTENTS +// +void MainWin::drawContents( QPainter *painter ) +{ + int deltay, i; + + QRect r = contentsRect(); + + deltay = r.height() / CurvCnt - 1; + + r.setHeight( deltay ); + + // + // draw curves + // + for ( i = 0; i < CurvCnt; i++ ) + { + xMap.setPaintInterval( r.left(), r.right() ); + yMap.setPaintInterval( r.top(), r.bottom() ); + + painter->setRenderHint( QPainter::Antialiasing, + d_curves[i].testRenderHint( QwtPlotItem::RenderAntialiased ) ); + d_curves[i].draw( painter, xMap, yMap, r ); + + shiftDown( r, deltay ); + } + + // + // draw titles + // + r = contentsRect(); // reset r + painter->setFont( QFont( "Helvetica", 8 ) ); + + const int alignment = Qt::AlignTop | Qt::AlignHCenter; + + painter->setPen( Qt::black ); + + painter->drawText( 0, r.top(), r.width(), painter->fontMetrics().height(), + alignment, "Style: Line/Fitted, Symbol: Cross" ); + shiftDown( r, deltay ); + + painter->drawText( 0, r.top(), r.width(), painter->fontMetrics().height(), + alignment, "Style: Sticks, Symbol: Ellipse" ); + shiftDown( r, deltay ); + + painter->drawText( 0 , r.top(), r.width(), painter->fontMetrics().height(), + alignment, "Style: Lines, Symbol: None" ); + shiftDown( r, deltay ); + + painter->drawText( 0 , r.top(), r.width(), painter->fontMetrics().height(), + alignment, "Style: Lines, Symbol: None, Antialiased" ); + shiftDown( r, deltay ); + + painter->drawText( 0, r.top(), r.width(), painter->fontMetrics().height(), + alignment, "Style: Steps, Symbol: None" ); + shiftDown( r, deltay ); + + painter->drawText( 0, r.top(), r.width(), painter->fontMetrics().height(), + alignment, "Style: NoCurve, Symbol: XCross" ); +} + +int main ( int argc, char **argv ) +{ + QApplication a( argc, argv ); + + MainWin w; + + w.resize( 300, 600 ); + w.show(); + + return a.exec(); +} diff --git a/ThirdParty/Qwt/examples/curvdemo1/curvdemo1.pro b/ThirdParty/Qwt/examples/curvdemo1/curvdemo1.pro new file mode 100644 index 0000000000..298c977449 --- /dev/null +++ b/ThirdParty/Qwt/examples/curvdemo1/curvdemo1.pro @@ -0,0 +1,15 @@ +################################################################ +# Qwt Widget Library +# Copyright (C) 1997 Josef Wilgen +# Copyright (C) 2002 Uwe Rathmann +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the Qwt License, Version 1.0 +################################################################ + +include( $${PWD}/../examples.pri ) + +TARGET = curvdemo1 + +SOURCES = \ + curvdemo1.cpp diff --git a/ThirdParty/Qwt/examples/dials/attitude_indicator.cpp b/ThirdParty/Qwt/examples/dials/attitude_indicator.cpp new file mode 100644 index 0000000000..a5810be673 --- /dev/null +++ b/ThirdParty/Qwt/examples/dials/attitude_indicator.cpp @@ -0,0 +1,127 @@ +#include "attitude_indicator.h" +#include +#include +#include +#include +#include + +AttitudeIndicatorNeedle::AttitudeIndicatorNeedle( const QColor &color ) +{ + QPalette palette; + palette.setColor( QPalette::Text, color ); + setPalette( palette ); +} + +void AttitudeIndicatorNeedle::drawNeedle( QPainter *painter, + double length, QPalette::ColorGroup colorGroup ) const +{ + double triangleSize = length * 0.1; + double pos = length - 2.0; + + QPainterPath path; + path.moveTo( pos, 0 ); + path.lineTo( pos - 2 * triangleSize, triangleSize ); + path.lineTo( pos - 2 * triangleSize, -triangleSize ); + path.closeSubpath(); + + painter->setBrush( palette().brush( colorGroup, QPalette::Text ) ); + painter->drawPath( path ); + + double l = length - 2; + painter->setPen( QPen( palette().color( colorGroup, QPalette::Text ), 3 ) ); + painter->drawLine( QPointF( 0.0, -l ), QPointF( 0.0, l ) ); +} + +AttitudeIndicator::AttitudeIndicator( + QWidget *parent ): + QwtDial( parent ), + d_gradient( 0.0 ) +{ + QwtRoundScaleDraw *scaleDraw = new QwtRoundScaleDraw(); + scaleDraw->enableComponent( QwtAbstractScaleDraw::Backbone, false ); + scaleDraw->enableComponent( QwtAbstractScaleDraw::Labels, false ); + setScaleDraw( scaleDraw ); + + setMode( RotateScale ); + setWrapping( true ); + + setOrigin( 270.0 ); + + setScaleMaxMinor( 0 ); + setScaleStepSize( 30.0 ); + setScale( 0.0, 360.0 ); + + const QColor color = palette().color( QPalette::Text ); + setNeedle( new AttitudeIndicatorNeedle( color ) ); +} + +void AttitudeIndicator::setGradient( double gradient ) +{ + if ( gradient < -1.0 ) + gradient = -1.0; + else if ( gradient > 1.0 ) + gradient = 1.0; + + if ( d_gradient != gradient ) + { + d_gradient = gradient; + update(); + } +} + +void AttitudeIndicator::drawScale( QPainter *painter, + const QPointF ¢er, double radius ) const +{ + const double offset = 4.0; + + const QPointF p0 = qwtPolar2Pos( center, offset, 1.5 * M_PI ); + + const double w = innerRect().width(); + + QPainterPath path; + path.moveTo( qwtPolar2Pos( p0, w, 0.0 ) ); + path.lineTo( qwtPolar2Pos( path.currentPosition(), 2 * w, M_PI ) ); + path.lineTo( qwtPolar2Pos( path.currentPosition(), w, 0.5 * M_PI ) ); + path.lineTo( qwtPolar2Pos( path.currentPosition(), w, 0.0 ) ); + + painter->save(); + painter->setClipPath( path ); // swallow 180 - 360 degrees + + QwtDial::drawScale( painter, center, radius ); + + painter->restore(); +} + +void AttitudeIndicator::drawScaleContents( QPainter *painter, + const QPointF &, double ) const +{ + int dir = 360 - qRound( origin() - value() ); // counter clockwise + int arc = 90 + qRound( gradient() * 90 ); + + const QColor skyColor( 38, 151, 221 ); + + painter->save(); + painter->setBrush( skyColor ); + painter->drawChord( scaleInnerRect(), + ( dir - arc ) * 16, 2 * arc * 16 ); + painter->restore(); +} + +void AttitudeIndicator::keyPressEvent( QKeyEvent *event ) +{ + switch( event->key() ) + { + case Qt::Key_Plus: + { + setGradient( gradient() + 0.05 ); + break; + } + case Qt::Key_Minus: + { + setGradient( gradient() - 0.05 ); + break; + } + default: + QwtDial::keyPressEvent( event ); + } +} diff --git a/ThirdParty/Qwt/examples/dials/attitude_indicator.h b/ThirdParty/Qwt/examples/dials/attitude_indicator.h new file mode 100644 index 0000000000..d4eb0c8330 --- /dev/null +++ b/ThirdParty/Qwt/examples/dials/attitude_indicator.h @@ -0,0 +1,39 @@ +#include +#include + +class AttitudeIndicatorNeedle: public QwtDialNeedle +{ +public: + AttitudeIndicatorNeedle( const QColor & ); + +protected: + virtual void drawNeedle( QPainter *, + double length, QPalette::ColorGroup ) const; +}; + +class AttitudeIndicator: public QwtDial +{ + Q_OBJECT + +public: + AttitudeIndicator( QWidget *parent = NULL ); + + double angle() const { return value(); } + double gradient() const { return d_gradient; } + +public Q_SLOTS: + void setGradient( double ); + void setAngle( double angle ) { setValue( angle ); } + +protected: + virtual void keyPressEvent( QKeyEvent * ); + + virtual void drawScale( QPainter *, + const QPointF ¢er, double radius ) const; + + virtual void drawScaleContents( QPainter *painter, + const QPointF ¢er, double radius ) const; + +private: + double d_gradient; +}; diff --git a/ThirdParty/Qwt/examples/dials/cockpit_grid.cpp b/ThirdParty/Qwt/examples/dials/cockpit_grid.cpp new file mode 100644 index 0000000000..f298fd4525 --- /dev/null +++ b/ThirdParty/Qwt/examples/dials/cockpit_grid.cpp @@ -0,0 +1,186 @@ +#include +#include +#include +#include +#include "attitude_indicator.h" +#include "speedo_meter.h" +#include "cockpit_grid.h" + +CockpitGrid::CockpitGrid( QWidget *parent ): + QFrame( parent ) +{ + setAutoFillBackground( true ); + + setPalette( colorTheme( QColor( Qt::darkGray ).dark( 150 ) ) ); + + QGridLayout *layout = new QGridLayout( this ); + layout->setSpacing( 5 ); + layout->setMargin( 0 ); + + int i; + for ( i = 0; i < 3; i++ ) + { + QwtDial *dial = createDial( i ); + layout->addWidget( dial, 0, i ); + } + + for ( i = 0; i < layout->columnCount(); i++ ) + layout->setColumnStretch( i, 1 ); +} + +QwtDial *CockpitGrid::createDial( int pos ) +{ + QwtDial *dial = NULL; + switch( pos ) + { + case 0: + { + d_clock = new QwtAnalogClock( this ); +#if 0 + // disable minor ticks + d_clock->scaleDraw()->setTickLength( QwtScaleDiv::MinorTick, 0 ); +#endif + + const QColor knobColor = QColor( Qt::gray ).light( 130 ); + + for ( int i = 0; i < QwtAnalogClock::NHands; i++ ) + { + QColor handColor = QColor( Qt::gray ).light( 150 ); + int width = 8; + + if ( i == QwtAnalogClock::SecondHand ) + { + handColor = Qt::gray; + width = 5; + } + + QwtDialSimpleNeedle *hand = new QwtDialSimpleNeedle( + QwtDialSimpleNeedle::Arrow, true, handColor, knobColor ); + hand->setWidth( width ); + + d_clock->setHand( static_cast( i ), hand ); + } + + QTimer *timer = new QTimer( d_clock ); + timer->connect( timer, SIGNAL( timeout() ), + d_clock, SLOT( setCurrentTime() ) ); + timer->start( 1000 ); + + dial = d_clock; + break; + } + case 1: + { + d_speedo = new SpeedoMeter( this ); + d_speedo->setScaleStepSize( 20.0 ); + d_speedo->setScale( 0.0, 240.0 ); + d_speedo->scaleDraw()->setPenWidth( 2 ); + + QTimer *timer = new QTimer( d_speedo ); + timer->connect( timer, SIGNAL( timeout() ), + this, SLOT( changeSpeed() ) ); + timer->start( 50 ); + + dial = d_speedo; + break; + } + case 2: + { + d_ai = new AttitudeIndicator( this ); + d_ai->scaleDraw()->setPenWidth( 3 ); + + QTimer *gradientTimer = new QTimer( d_ai ); + gradientTimer->connect( gradientTimer, SIGNAL( timeout() ), + this, SLOT( changeGradient() ) ); + gradientTimer->start( 100 ); + + QTimer *angleTimer = new QTimer( d_ai ); + angleTimer->connect( angleTimer, SIGNAL( timeout() ), + this, SLOT( changeAngle() ) ); + angleTimer->start( 100 ); + + dial = d_ai; + break; + } + + } + + if ( dial ) + { + dial->setReadOnly( true ); + dial->setLineWidth( 4 ); + dial->setFrameShadow( QwtDial::Sunken ); + } + return dial; +} + +QPalette CockpitGrid::colorTheme( const QColor &base ) const +{ + QPalette palette; + palette.setColor( QPalette::Base, base ); + palette.setColor( QPalette::Window, base.dark( 150 ) ); + palette.setColor( QPalette::Mid, base.dark( 110 ) ); + palette.setColor( QPalette::Light, base.light( 170 ) ); + palette.setColor( QPalette::Dark, base.dark( 170 ) ); + palette.setColor( QPalette::Text, base.dark( 200 ).light( 800 ) ); + palette.setColor( QPalette::WindowText, base.dark( 200 ) ); + + return palette; +} + +void CockpitGrid::changeSpeed() +{ + static double offset = 0.8; + + double speed = d_speedo->value(); + + if ( ( speed < 7.0 && offset < 0.0 ) || + ( speed > 203.0 && offset > 0.0 ) ) + { + offset = -offset; + } + + static int counter = 0; + switch( counter++ % 12 ) + { + case 0: + case 2: + case 7: + case 8: + break; + default: + d_speedo->setValue( speed + offset ); + } +} + +void CockpitGrid::changeAngle() +{ + static double offset = 0.05; + + double angle = d_ai->angle(); + if ( angle > 180.0 ) + angle -= 360.0; + + if ( ( angle < -5.0 && offset < 0.0 ) || + ( angle > 5.0 && offset > 0.0 ) ) + { + offset = -offset; + } + + d_ai->setAngle( angle + offset ); +} + +void CockpitGrid::changeGradient() +{ + static double offset = 0.005; + + double gradient = d_ai->gradient(); + + if ( ( gradient < -0.05 && offset < 0.0 ) || + ( gradient > 0.05 && offset > 0.0 ) ) + { + offset = -offset; + } + + d_ai->setGradient( gradient + offset ); +} diff --git a/ThirdParty/Qwt/examples/dials/cockpit_grid.h b/ThirdParty/Qwt/examples/dials/cockpit_grid.h new file mode 100644 index 0000000000..38139ee512 --- /dev/null +++ b/ThirdParty/Qwt/examples/dials/cockpit_grid.h @@ -0,0 +1,28 @@ +#include +#include + +class QwtDial; +class QwtAnalogClock; +class SpeedoMeter; +class AttitudeIndicator; + +class CockpitGrid: public QFrame +{ + Q_OBJECT + +public: + CockpitGrid( QWidget *parent = NULL ); + +private Q_SLOTS: + void changeSpeed(); + void changeGradient(); + void changeAngle(); + +private: + QPalette colorTheme( const QColor & ) const; + QwtDial *createDial( int pos ); + + QwtAnalogClock *d_clock; + SpeedoMeter *d_speedo; + AttitudeIndicator *d_ai; +}; diff --git a/ThirdParty/Qwt/examples/dials/compass_grid.cpp b/ThirdParty/Qwt/examples/dials/compass_grid.cpp new file mode 100644 index 0000000000..02f66ed844 --- /dev/null +++ b/ThirdParty/Qwt/examples/dials/compass_grid.cpp @@ -0,0 +1,226 @@ +#include +#include +#include +#include +#include "compass_grid.h" + +CompassGrid::CompassGrid( QWidget *parent ): + QFrame( parent ) +{ + QPalette p = palette(); + p.setColor( backgroundRole(), Qt::gray ); + setPalette( p ); + + setAutoFillBackground( true ); + + QGridLayout *layout = new QGridLayout( this ); + layout->setSpacing( 5 ); + layout->setMargin( 0 ); + + int i; + for ( i = 0; i < 6; i++ ) + { + QwtCompass *compass = createCompass( i ); + layout->addWidget( compass, i / 3, i % 3 ); + } + + for ( i = 0; i < layout->columnCount(); i++ ) + layout->setColumnStretch( i, 1 ); +} + +QwtCompass *CompassGrid::createCompass( int pos ) +{ + int c; + + QPalette palette0; + for ( c = 0; c < QPalette::NColorRoles; c++ ) + { + const QPalette::ColorRole colorRole = + static_cast( c ); + + palette0.setColor( colorRole, QColor() ); + } + + palette0.setColor( QPalette::Base, + palette().color( backgroundRole() ).light( 120 ) ); + palette0.setColor( QPalette::WindowText, + palette0.color( QPalette::Base ) ); + + QwtCompass *compass = new QwtCompass( this ); + compass->setLineWidth( 4 ); + compass->setFrameShadow( + pos <= 2 ? QwtCompass::Sunken : QwtCompass::Raised ); + + switch( pos ) + { + case 0: + { + /* + A compass with a rose and no needle. Scale and rose are + rotating. + */ + compass->setMode( QwtCompass::RotateScale ); + + QwtSimpleCompassRose *rose = new QwtSimpleCompassRose( 16, 2 ); + rose->setWidth( 0.15 ); + + compass->setRose( rose ); + break; + } + case 1: + { + /* + A windrose, with a scale indicating the main directions only + */ + QMap map; + map.insert( 0.0, "N" ); + map.insert( 90.0, "E" ); + map.insert( 180.0, "S" ); + map.insert( 270.0, "W" ); + + compass->setScaleDraw( new QwtCompassScaleDraw( map ) ); + + QwtSimpleCompassRose *rose = new QwtSimpleCompassRose( 4, 1 ); + compass->setRose( rose ); + + compass->setNeedle( + new QwtCompassWindArrow( QwtCompassWindArrow::Style2 ) ); + compass->setValue( 60.0 ); + break; + } + case 2: + { + /* + A compass with a rotating needle in darkBlue. Shows + a ticks for each degree. + */ + + palette0.setColor( QPalette::Base, Qt::darkBlue ); + palette0.setColor( QPalette::WindowText, + QColor( Qt::darkBlue ).dark( 120 ) ); + palette0.setColor( QPalette::Text, Qt::white ); + + QwtCompassScaleDraw *scaleDraw = new QwtCompassScaleDraw(); + scaleDraw->enableComponent( QwtAbstractScaleDraw::Ticks, true ); + scaleDraw->enableComponent( QwtAbstractScaleDraw::Labels, true ); + scaleDraw->enableComponent( QwtAbstractScaleDraw::Backbone, false ); + scaleDraw->setTickLength( QwtScaleDiv::MinorTick, 1 ); + scaleDraw->setTickLength( QwtScaleDiv::MediumTick, 1 ); + scaleDraw->setTickLength( QwtScaleDiv::MajorTick, 3 ); + + compass->setScaleDraw( scaleDraw ); + + compass->setScaleMaxMajor( 36 ); + compass->setScaleMaxMinor( 5 ); + + compass->setNeedle( + new QwtCompassMagnetNeedle( QwtCompassMagnetNeedle::ThinStyle ) ); + compass->setValue( 220.0 ); + + break; + } + case 3: + { + /* + A compass without a frame, showing numbers as tick labels. + The origin is at 220.0 + */ + palette0.setColor( QPalette::Base, + palette().color( backgroundRole() ) ); + palette0.setColor( QPalette::WindowText, Qt::blue ); + + compass->setLineWidth( 0 ); + + QMap map; + for ( double d = 0.0; d < 360.0; d += 60.0 ) + { + QString label; + label.sprintf( "%.0f", d ); + map.insert( d, label ); + } + + QwtCompassScaleDraw *scaleDraw = + new QwtCompassScaleDraw( map ); + scaleDraw->enableComponent( QwtAbstractScaleDraw::Ticks, true ); + scaleDraw->enableComponent( QwtAbstractScaleDraw::Labels, true ); + scaleDraw->enableComponent( QwtAbstractScaleDraw::Backbone, true ); + scaleDraw->setTickLength( QwtScaleDiv::MinorTick, 0 ); + scaleDraw->setTickLength( QwtScaleDiv::MediumTick, 0 ); + scaleDraw->setTickLength( QwtScaleDiv::MajorTick, 3 ); + + compass->setScaleDraw( scaleDraw ); + + compass->setScaleMaxMajor( 36 ); + compass->setScaleMaxMinor( 5 ); + + compass->setNeedle( new QwtDialSimpleNeedle( QwtDialSimpleNeedle::Ray, + true, Qt::white ) ); + compass->setOrigin( 220.0 ); + compass->setValue( 20.0 ); + break; + } + case 4: + { + /* + A compass showing another needle + */ + QwtCompassScaleDraw *scaleDraw = new QwtCompassScaleDraw(); + scaleDraw->enableComponent( QwtAbstractScaleDraw::Ticks, true ); + scaleDraw->enableComponent( QwtAbstractScaleDraw::Labels, true ); + scaleDraw->enableComponent( QwtAbstractScaleDraw::Backbone, false ); + scaleDraw->setTickLength( QwtScaleDiv::MinorTick, 0 ); + scaleDraw->setTickLength( QwtScaleDiv::MediumTick, 0 ); + scaleDraw->setTickLength( QwtScaleDiv::MajorTick, 3 ); + + compass->setScaleDraw( scaleDraw ); + + compass->setNeedle( new QwtCompassMagnetNeedle( + QwtCompassMagnetNeedle::TriangleStyle, Qt::white, Qt::red ) ); + compass->setValue( 220.0 ); + break; + } + case 5: + { + /* + A compass with a yellow on black ray + */ + palette0.setColor( QPalette::WindowText, Qt::black ); + + compass->setNeedle( new QwtDialSimpleNeedle( QwtDialSimpleNeedle::Ray, + false, Qt::yellow ) ); + compass->setValue( 315.0 ); + break; + } + } + + QPalette newPalette = compass->palette(); + for ( c = 0; c < QPalette::NColorRoles; c++ ) + { + const QPalette::ColorRole colorRole = + static_cast( c ); + + if ( palette0.color( colorRole ).isValid() ) + newPalette.setColor( colorRole, palette0.color( colorRole ) ); + } + + for ( int i = 0; i < QPalette::NColorGroups; i++ ) + { + const QPalette::ColorGroup colorGroup = + static_cast( i ); + + const QColor light = + newPalette.color( colorGroup, QPalette::Base ).light( 170 ); + const QColor dark = newPalette.color( colorGroup, QPalette::Base ).dark( 170 ); + const QColor mid = compass->frameShadow() == QwtDial::Raised + ? newPalette.color( colorGroup, QPalette::Base ).dark( 110 ) + : newPalette.color( colorGroup, QPalette::Base ).light( 110 ); + + newPalette.setColor( colorGroup, QPalette::Dark, dark ); + newPalette.setColor( colorGroup, QPalette::Mid, mid ); + newPalette.setColor( colorGroup, QPalette::Light, light ); + } + + compass->setPalette( newPalette ); + + return compass; +} diff --git a/ThirdParty/Qwt/examples/dials/compass_grid.h b/ThirdParty/Qwt/examples/dials/compass_grid.h new file mode 100644 index 0000000000..3869270096 --- /dev/null +++ b/ThirdParty/Qwt/examples/dials/compass_grid.h @@ -0,0 +1,11 @@ +#include +class QwtCompass; + +class CompassGrid: public QFrame +{ +public: + CompassGrid( QWidget *parent = NULL ); + +private: + QwtCompass *createCompass( int pos ); +}; diff --git a/ThirdParty/Qwt/examples/dials/dials.cpp b/ThirdParty/Qwt/examples/dials/dials.cpp new file mode 100644 index 0000000000..e34a5828d7 --- /dev/null +++ b/ThirdParty/Qwt/examples/dials/dials.cpp @@ -0,0 +1,24 @@ +#include +#include +#include "compass_grid.h" +#include "cockpit_grid.h" + +//----------------------------------------------------------------- +// +// dials.cpp -- A demo program featuring QwtDial and friends +// +//----------------------------------------------------------------- + +int main ( int argc, char **argv ) +{ + QApplication a( argc, argv ); + + QTabWidget tabWidget; + tabWidget.addTab( new CompassGrid, "Compass" ); + tabWidget.addTab( new CockpitGrid, "Cockpit" ); + + tabWidget.show(); + + return a.exec(); +} + diff --git a/ThirdParty/Qwt/examples/dials/dials.pro b/ThirdParty/Qwt/examples/dials/dials.pro new file mode 100644 index 0000000000..11db8664e9 --- /dev/null +++ b/ThirdParty/Qwt/examples/dials/dials.pro @@ -0,0 +1,26 @@ +################################################################ +# Qwt Widget Library +# Copyright (C) 1997 Josef Wilgen +# Copyright (C) 2002 Uwe Rathmann +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the Qwt License, Version 1.0 +################################################################ + +include( $${PWD}/../examples.pri ) + +TARGET = dials + +HEADERS = \ + attitude_indicator.h \ + speedo_meter.h \ + cockpit_grid.h \ + compass_grid.h + +SOURCES = \ + attitude_indicator.cpp \ + speedo_meter.cpp \ + cockpit_grid.cpp \ + compass_grid.cpp \ + dials.cpp + diff --git a/ThirdParty/Qwt/examples/dials/speedo_meter.cpp b/ThirdParty/Qwt/examples/dials/speedo_meter.cpp new file mode 100644 index 0000000000..3205d4cc8c --- /dev/null +++ b/ThirdParty/Qwt/examples/dials/speedo_meter.cpp @@ -0,0 +1,52 @@ +#include +#include +#include +#include "speedo_meter.h" + +SpeedoMeter::SpeedoMeter( QWidget *parent ): + QwtDial( parent ), + d_label( "km/h" ) +{ + QwtRoundScaleDraw *scaleDraw = new QwtRoundScaleDraw(); + scaleDraw->setSpacing( 8 ); + scaleDraw->enableComponent( QwtAbstractScaleDraw::Backbone, false ); + scaleDraw->setTickLength( QwtScaleDiv::MinorTick, 0 ); + scaleDraw->setTickLength( QwtScaleDiv::MediumTick, 4 ); + scaleDraw->setTickLength( QwtScaleDiv::MajorTick, 8 ); + setScaleDraw( scaleDraw ); + + setWrapping( false ); + setReadOnly( true ); + + setOrigin( 135.0 ); + setScaleArc( 0.0, 270.0 ); + + QwtDialSimpleNeedle *needle = new QwtDialSimpleNeedle( + QwtDialSimpleNeedle::Arrow, true, Qt::red, + QColor( Qt::gray ).light( 130 ) ); + setNeedle( needle ); +} + +void SpeedoMeter::setLabel( const QString &label ) +{ + d_label = label; + update(); +} + +QString SpeedoMeter::label() const +{ + return d_label; +} + +void SpeedoMeter::drawScaleContents( QPainter *painter, + const QPointF ¢er, double radius ) const +{ + QRectF rect( 0.0, 0.0, 2.0 * radius, 2.0 * radius - 10.0 ); + rect.moveCenter( center ); + + const QColor color = palette().color( QPalette::Text ); + painter->setPen( color ); + + const int flags = Qt::AlignBottom | Qt::AlignHCenter; + painter->drawText( rect, flags, d_label ); +} diff --git a/ThirdParty/Qwt/examples/dials/speedo_meter.h b/ThirdParty/Qwt/examples/dials/speedo_meter.h new file mode 100644 index 0000000000..3f49e28cb3 --- /dev/null +++ b/ThirdParty/Qwt/examples/dials/speedo_meter.h @@ -0,0 +1,18 @@ +#include +#include + +class SpeedoMeter: public QwtDial +{ +public: + SpeedoMeter( QWidget *parent = NULL ); + + void setLabel( const QString & ); + QString label() const; + +protected: + virtual void drawScaleContents( QPainter *painter, + const QPointF ¢er, double radius ) const; + +private: + QString d_label; +}; diff --git a/ThirdParty/Qwt/examples/distrowatch/barchart.cpp b/ThirdParty/Qwt/examples/distrowatch/barchart.cpp new file mode 100644 index 0000000000..0ffe4a1741 --- /dev/null +++ b/ThirdParty/Qwt/examples/distrowatch/barchart.cpp @@ -0,0 +1,192 @@ +#include "barchart.h" +#include +#include +#include +#include +#include +#include +#include + +class DistroScaleDraw: public QwtScaleDraw +{ +public: + DistroScaleDraw( Qt::Orientation orientation, const QStringList &labels ): + d_labels( labels ) + { + setTickLength( QwtScaleDiv::MinorTick, 0 ); + setTickLength( QwtScaleDiv::MediumTick, 0 ); + setTickLength( QwtScaleDiv::MajorTick, 2 ); + + enableComponent( QwtScaleDraw::Backbone, false ); + + if ( orientation == Qt::Vertical ) + { + setLabelRotation( -60.0 ); + } + else + { + setLabelRotation( -20.0 ); + } + + setLabelAlignment( Qt::AlignLeft | Qt::AlignVCenter ); + } + + virtual QwtText label( double value ) const + { + QwtText lbl; + + const int index = qRound( value ); + if ( index >= 0 && index <= d_labels.size() ) + { + lbl = d_labels[ index ]; + } + + return lbl; + } + +private: + const QStringList d_labels; +}; + +class DistroChartItem: public QwtPlotBarChart +{ +public: + DistroChartItem(): + QwtPlotBarChart( "Page Hits" ) + { + setLegendMode( QwtPlotBarChart::LegendBarTitles ); + setLegendIconSize( QSize( 10, 14 ) ); + } + + void addDistro( const QString &distro, const QColor &color ) + { + d_colors += color; + d_distros += distro; + itemChanged(); + } + + virtual QwtColumnSymbol *specialSymbol( + int index, const QPointF& ) const + { + // we want to have individual colors for each bar + + QwtColumnSymbol *symbol = new QwtColumnSymbol( QwtColumnSymbol::Box ); + symbol->setLineWidth( 2 ); + symbol->setFrameStyle( QwtColumnSymbol::Raised ); + + QColor c( Qt::white ); + if ( index >= 0 && index < d_colors.size() ) + c = d_colors[ index ]; + + symbol->setPalette( c ); + + return symbol; + } + + virtual QwtText barTitle( int sampleIndex ) const + { + QwtText title; + if ( sampleIndex >= 0 && sampleIndex < d_distros.size() ) + title = d_distros[ sampleIndex ]; + + return title; + } + +private: + QList d_colors; + QList d_distros; +}; + +BarChart::BarChart( QWidget *parent ): + QwtPlot( parent ) +{ + const struct + { + const char *distro; + const int hits; + QColor color; + + } pageHits[] = + { + { "Arch", 1114, QColor( "DodgerBlue" ) }, + { "Debian", 1373, QColor( "#d70751" ) }, + { "Fedora", 1638, QColor( "SteelBlue" ) }, + { "Mageia", 1395, QColor( "Indigo" ) }, + { "Mint", 3874, QColor( 183, 255, 183 ) }, + { "openSuSE", 1532, QColor( 115, 186, 37 ) }, + { "Puppy", 1059, QColor( "LightSkyBlue" ) }, + { "Ubuntu", 2391, QColor( "FireBrick" ) } + }; + + setAutoFillBackground( true ); + setPalette( QColor( "Linen" ) ); + + QwtPlotCanvas *canvas = new QwtPlotCanvas(); + canvas->setLineWidth( 2 ); + canvas->setFrameStyle( QFrame::Box | QFrame::Sunken ); + canvas->setBorderRadius( 10 ); + + QPalette canvasPalette( QColor( "Plum" ) ); + canvasPalette.setColor( QPalette::Foreground, QColor( "Indigo" ) ); + canvas->setPalette( canvasPalette ); + + setCanvas( canvas ); + + setTitle( "DistroWatch Page Hit Ranking, April 2012" ); + + d_barChartItem = new DistroChartItem(); + + QVector< double > samples; + + for ( uint i = 0; i < sizeof( pageHits ) / sizeof( pageHits[ 0 ] ); i++ ) + { + d_distros += pageHits[ i ].distro; + samples += pageHits[ i ].hits; + + d_barChartItem->addDistro( + pageHits[ i ].distro, pageHits[ i ].color ); + } + + d_barChartItem->setSamples( samples ); + + d_barChartItem->attach( this ); + + insertLegend( new QwtLegend() ); + + setOrientation( 0 ); + setAutoReplot( false ); +} + +void BarChart::setOrientation( int o ) +{ + const Qt::Orientation orientation = + ( o == 0 ) ? Qt::Vertical : Qt::Horizontal; + + int axis1 = QwtPlot::xBottom; + int axis2 = QwtPlot::yLeft; + + if ( orientation == Qt::Horizontal ) + qSwap( axis1, axis2 ); + + d_barChartItem->setOrientation( orientation ); + + setAxisTitle( axis1, "Distros" ); + setAxisMaxMinor( axis1, 3 ); + setAxisScaleDraw( axis1, new DistroScaleDraw( orientation, d_distros ) ); + + setAxisTitle( axis2, "Hits per day ( HPD )" ); + setAxisMaxMinor( axis2, 3 ); + + QwtScaleDraw *scaleDraw = new QwtScaleDraw(); + scaleDraw->setTickLength( QwtScaleDiv::MediumTick, 4 ); + setAxisScaleDraw( axis2, scaleDraw ); + + plotLayout()->setCanvasMargin( 0 ); + replot(); +} + +void BarChart::exportChart() +{ + QwtPlotRenderer renderer; + renderer.exportTo( this, "distrowatch.pdf" ); +} diff --git a/ThirdParty/Qwt/examples/distrowatch/barchart.h b/ThirdParty/Qwt/examples/distrowatch/barchart.h new file mode 100644 index 0000000000..33afa40282 --- /dev/null +++ b/ThirdParty/Qwt/examples/distrowatch/barchart.h @@ -0,0 +1,26 @@ +#ifndef _BAR_CHART_H_ + +#include +#include + +class DistroChartItem; + +class BarChart: public QwtPlot +{ + Q_OBJECT + +public: + BarChart( QWidget * = NULL ); + +public Q_SLOTS: + void setOrientation( int ); + void exportChart(); + +private: + void populate(); + + DistroChartItem *d_barChartItem; + QStringList d_distros; +}; + +#endif diff --git a/ThirdParty/Qwt/examples/distrowatch/distrowatch.pro b/ThirdParty/Qwt/examples/distrowatch/distrowatch.pro new file mode 100644 index 0000000000..f241023875 --- /dev/null +++ b/ThirdParty/Qwt/examples/distrowatch/distrowatch.pro @@ -0,0 +1,19 @@ +################################################################ +# Qwt Widget Library +# Copyright (C) 1997 Josef Wilgen +# Copyright (C) 2002 Uwe Rathmann +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the Qwt License, Version 1.0 +################################################################ + +include( $${PWD}/../examples.pri ) + +TARGET = distrowatch + +HEADERS = \ + barchart.h + +SOURCES = \ + barchart.cpp \ + main.cpp diff --git a/ThirdParty/Qwt/examples/distrowatch/main.cpp b/ThirdParty/Qwt/examples/distrowatch/main.cpp new file mode 100644 index 0000000000..88d4e4809e --- /dev/null +++ b/ThirdParty/Qwt/examples/distrowatch/main.cpp @@ -0,0 +1,54 @@ +#include +#include +#include +#include +#include +#include "barchart.h" + +class MainWindow: public QMainWindow +{ +public: + MainWindow( QWidget * = NULL ); + +private: + BarChart *d_chart; +}; + +MainWindow::MainWindow( QWidget *parent ): + QMainWindow( parent ) +{ + d_chart = new BarChart( this ); + setCentralWidget( d_chart ); + + QToolBar *toolBar = new QToolBar( this ); + + QComboBox *orientationBox = new QComboBox( toolBar ); + orientationBox->addItem( "Vertical" ); + orientationBox->addItem( "Horizontal" ); + orientationBox->setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ); + + QToolButton *btnExport = new QToolButton( toolBar ); + btnExport->setText( "Export" ); + btnExport->setToolButtonStyle( Qt::ToolButtonTextUnderIcon ); + connect( btnExport, SIGNAL( clicked() ), d_chart, SLOT( exportChart() ) ); + + toolBar->addWidget( orientationBox ); + toolBar->addWidget( btnExport ); + addToolBar( toolBar ); + + d_chart->setOrientation( orientationBox->currentIndex() ); + connect( orientationBox, SIGNAL( currentIndexChanged( int ) ), + d_chart, SLOT( setOrientation( int ) ) ); +} + +int main( int argc, char **argv ) +{ + QApplication a( argc, argv ); + + MainWindow mainWindow; + + mainWindow.resize( 600, 400 ); + mainWindow.show(); + + return a.exec(); +} diff --git a/ThirdParty/Qwt/examples/event_filter/README b/ThirdParty/Qwt/examples/event_filter/README new file mode 100644 index 0000000000..05fc242058 --- /dev/null +++ b/ThirdParty/Qwt/examples/event_filter/README @@ -0,0 +1,27 @@ +QwtPlot is a composite widget consisting of a title label, +the canvas, the scales and a legend. Although all components +should be exchangable some day, the current design isn´t ready for it. + +In this situation event filtering is the mechanism to extend the behaviour +of the plot components. event_filter shows 3 examples how to use it: + +1) CanvasPicker + +The CanvasPicker implements a solution, how to move points on the canvas +with mouse and keyboard. + +2) ScalePicker + +The ScalePicker translates the position of mouse clicks on the scales +and emits them as signals. + +3) Plot: ColorBar, QSlider + +The Plot class shows how to add widgets to the scales. In this example +there is no filter class. The derived plot widget filters its components. + + +Please note that CanvasPicker and ScalePicker are standalone classes +that could be connected with your QwtPlot as well. + +Uwe diff --git a/ThirdParty/Qwt/examples/event_filter/canvaspicker.cpp b/ThirdParty/Qwt/examples/event_filter/canvaspicker.cpp new file mode 100644 index 0000000000..f8bb9fcca2 --- /dev/null +++ b/ThirdParty/Qwt/examples/event_filter/canvaspicker.cpp @@ -0,0 +1,372 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "canvaspicker.h" + +CanvasPicker::CanvasPicker( QwtPlot *plot ): + QObject( plot ), + d_selectedCurve( NULL ), + d_selectedPoint( -1 ) +{ + QwtPlotCanvas *canvas = qobject_cast( plot->canvas() ); + canvas->installEventFilter( this ); + + // We want the focus, but no focus rect. The + // selected point will be highlighted instead. + + canvas->setFocusPolicy( Qt::StrongFocus ); +#ifndef QT_NO_CURSOR + canvas->setCursor( Qt::PointingHandCursor ); +#endif + canvas->setFocusIndicator( QwtPlotCanvas::ItemFocusIndicator ); + canvas->setFocus(); + + const char *text = + "All points can be moved using the left mouse button " + "or with these keys:\n\n" + "- Up:\t\tSelect next curve\n" + "- Down:\t\tSelect previous curve\n" + "- Left, ´-´:\tSelect next point\n" + "- Right, ´+´:\tSelect previous point\n" + "- 7, 8, 9, 4, 6, 1, 2, 3:\tMove selected point"; + canvas->setWhatsThis( text ); + + shiftCurveCursor( true ); +} + +QwtPlot *CanvasPicker::plot() +{ + return qobject_cast( parent() ); +} + +const QwtPlot *CanvasPicker::plot() const +{ + return qobject_cast( parent() ); +} + +bool CanvasPicker::event( QEvent *ev ) +{ + if ( ev->type() == QEvent::User ) + { + showCursor( true ); + return true; + } + return QObject::event( ev ); +} + +bool CanvasPicker::eventFilter( QObject *object, QEvent *event ) +{ + if ( plot() == NULL || object != plot()->canvas() ) + return false; + + switch( event->type() ) + { + case QEvent::FocusIn: + { + showCursor( true ); + break; + } + case QEvent::FocusOut: + { + showCursor( false ); + break; + } + case QEvent::Paint: + { + QApplication::postEvent( this, new QEvent( QEvent::User ) ); + break; + } + case QEvent::MouseButtonPress: + { + const QMouseEvent *mouseEvent = static_cast( event ); + select( mouseEvent->pos() ); + return true; + } + case QEvent::MouseMove: + { + const QMouseEvent *mouseEvent = static_cast( event ); + move( mouseEvent->pos() ); + return true; + } + case QEvent::KeyPress: + { + const QKeyEvent *keyEvent = static_cast( event ); + + const int delta = 5; + switch( keyEvent->key() ) + { + case Qt::Key_Up: + { + shiftCurveCursor( true ); + return true; + } + case Qt::Key_Down: + { + shiftCurveCursor( false ); + return true; + } + case Qt::Key_Right: + case Qt::Key_Plus: + { + if ( d_selectedCurve ) + shiftPointCursor( true ); + else + shiftCurveCursor( true ); + return true; + } + case Qt::Key_Left: + case Qt::Key_Minus: + { + if ( d_selectedCurve ) + shiftPointCursor( false ); + else + shiftCurveCursor( true ); + return true; + } + + // The following keys represent a direction, they are + // organized on the keyboard. + + case Qt::Key_1: + { + moveBy( -delta, delta ); + break; + } + case Qt::Key_2: + { + moveBy( 0, delta ); + break; + } + case Qt::Key_3: + { + moveBy( delta, delta ); + break; + } + case Qt::Key_4: + { + moveBy( -delta, 0 ); + break; + } + case Qt::Key_6: + { + moveBy( delta, 0 ); + break; + } + case Qt::Key_7: + { + moveBy( -delta, -delta ); + break; + } + case Qt::Key_8: + { + moveBy( 0, -delta ); + break; + } + case Qt::Key_9: + { + moveBy( delta, -delta ); + break; + } + default: + break; + } + } + default: + break; + } + + return QObject::eventFilter( object, event ); +} + +// Select the point at a position. If there is no point +// deselect the selected point + +void CanvasPicker::select( const QPoint &pos ) +{ + QwtPlotCurve *curve = NULL; + double dist = 10e10; + int index = -1; + + const QwtPlotItemList& itmList = plot()->itemList(); + for ( QwtPlotItemIterator it = itmList.begin(); + it != itmList.end(); ++it ) + { + if ( ( *it )->rtti() == QwtPlotItem::Rtti_PlotCurve ) + { + QwtPlotCurve *c = static_cast( *it ); + + double d; + int idx = c->closestPoint( pos, &d ); + if ( d < dist ) + { + curve = c; + index = idx; + dist = d; + } + } + } + + showCursor( false ); + d_selectedCurve = NULL; + d_selectedPoint = -1; + + if ( curve && dist < 10 ) // 10 pixels tolerance + { + d_selectedCurve = curve; + d_selectedPoint = index; + showCursor( true ); + } +} + +// Move the selected point +void CanvasPicker::moveBy( int dx, int dy ) +{ + if ( dx == 0 && dy == 0 ) + return; + + if ( !d_selectedCurve ) + return; + + const QPointF sample = + d_selectedCurve->sample( d_selectedPoint ); + + const double x = plot()->transform( + d_selectedCurve->xAxis(), sample.x() ); + const double y = plot()->transform( + d_selectedCurve->yAxis(), sample.y() ); + + move( QPoint( qRound( x + dx ), qRound( y + dy ) ) ); +} + +// Move the selected point +void CanvasPicker::move( const QPoint &pos ) +{ + if ( !d_selectedCurve ) + return; + + QVector xData( d_selectedCurve->dataSize() ); + QVector yData( d_selectedCurve->dataSize() ); + + for ( int i = 0; + i < static_cast( d_selectedCurve->dataSize() ); i++ ) + { + if ( i == d_selectedPoint ) + { + xData[i] = plot()->invTransform( + d_selectedCurve->xAxis(), pos.x() ); + yData[i] = plot()->invTransform( + d_selectedCurve->yAxis(), pos.y() ); + } + else + { + const QPointF sample = d_selectedCurve->sample( i ); + xData[i] = sample.x(); + yData[i] = sample.y(); + } + } + d_selectedCurve->setSamples( xData, yData ); + + /* + Enable QwtPlotCanvas::ImmediatePaint, so that the canvas has been + updated before we paint the cursor on it. + */ + QwtPlotCanvas *plotCanvas = + qobject_cast( plot()->canvas() ); + + plotCanvas->setPaintAttribute( QwtPlotCanvas::ImmediatePaint, true ); + plot()->replot(); + plotCanvas->setPaintAttribute( QwtPlotCanvas::ImmediatePaint, false ); + + showCursor( true ); +} + +// Hightlight the selected point +void CanvasPicker::showCursor( bool showIt ) +{ + if ( !d_selectedCurve ) + return; + + QwtSymbol *symbol = const_cast( d_selectedCurve->symbol() ); + + const QBrush brush = symbol->brush(); + if ( showIt ) + symbol->setBrush( symbol->brush().color().dark( 180 ) ); + + QwtPlotDirectPainter directPainter; + directPainter.drawSeries( d_selectedCurve, d_selectedPoint, d_selectedPoint ); + + if ( showIt ) + symbol->setBrush( brush ); // reset brush +} + +// Select the next/previous curve +void CanvasPicker::shiftCurveCursor( bool up ) +{ + QwtPlotItemIterator it; + + const QwtPlotItemList &itemList = plot()->itemList(); + + QwtPlotItemList curveList; + for ( it = itemList.begin(); it != itemList.end(); ++it ) + { + if ( ( *it )->rtti() == QwtPlotItem::Rtti_PlotCurve ) + curveList += *it; + } + if ( curveList.isEmpty() ) + return; + + it = curveList.begin(); + + if ( d_selectedCurve ) + { + for ( it = curveList.begin(); it != curveList.end(); ++it ) + { + if ( d_selectedCurve == *it ) + break; + } + if ( it == curveList.end() ) // not found + it = curveList.begin(); + + if ( up ) + { + ++it; + if ( it == curveList.end() ) + it = curveList.begin(); + } + else + { + if ( it == curveList.begin() ) + it = curveList.end(); + --it; + } + } + + showCursor( false ); + d_selectedPoint = 0; + d_selectedCurve = static_cast( *it ); + showCursor( true ); +} + +// Select the next/previous neighbour of the selected point +void CanvasPicker::shiftPointCursor( bool up ) +{ + if ( !d_selectedCurve ) + return; + + int index = d_selectedPoint + ( up ? 1 : -1 ); + index = ( index + d_selectedCurve->dataSize() ) % d_selectedCurve->dataSize(); + + if ( index != d_selectedPoint ) + { + showCursor( false ); + d_selectedPoint = index; + showCursor( true ); + } +} diff --git a/ThirdParty/Qwt/examples/event_filter/canvaspicker.h b/ThirdParty/Qwt/examples/event_filter/canvaspicker.h new file mode 100644 index 0000000000..c5b0f2f05b --- /dev/null +++ b/ThirdParty/Qwt/examples/event_filter/canvaspicker.h @@ -0,0 +1,33 @@ +#include + +class QPoint; +class QCustomEvent; +class QwtPlot; +class QwtPlotCurve; + +class CanvasPicker: public QObject +{ + Q_OBJECT +public: + CanvasPicker( QwtPlot *plot ); + virtual bool eventFilter( QObject *, QEvent * ); + + virtual bool event( QEvent * ); + +private: + void select( const QPoint & ); + void move( const QPoint & ); + void moveBy( int dx, int dy ); + + void release(); + + void showCursor( bool enable ); + void shiftPointCursor( bool up ); + void shiftCurveCursor( bool up ); + + QwtPlot *plot(); + const QwtPlot *plot() const; + + QwtPlotCurve *d_selectedCurve; + int d_selectedPoint; +}; diff --git a/ThirdParty/Qwt/examples/event_filter/colorbar.cpp b/ThirdParty/Qwt/examples/event_filter/colorbar.cpp new file mode 100644 index 0000000000..113377928f --- /dev/null +++ b/ThirdParty/Qwt/examples/event_filter/colorbar.cpp @@ -0,0 +1,112 @@ +#include +#include +#include +#include +#include "colorbar.h" + +ColorBar::ColorBar( Qt::Orientation o, QWidget *parent ): + QWidget( parent ), + d_orientation( o ), + d_light( Qt::white ), + d_dark( Qt::black ) +{ +#ifndef QT_NO_CURSOR + setCursor( Qt::PointingHandCursor ); +#endif +} + +void ColorBar::setOrientation( Qt::Orientation o ) +{ + d_orientation = o; + update(); +} + +void ColorBar::setLight( const QColor &light ) +{ + d_light = light; + update(); +} + +void ColorBar::setDark( const QColor &dark ) +{ + d_dark = dark; + update(); +} + +void ColorBar::setRange( const QColor &light, const QColor &dark ) +{ + d_light = light; + d_dark = dark; + update(); +} + +void ColorBar::mousePressEvent( QMouseEvent *e ) +{ + if( e->button() == Qt::LeftButton ) + { + // emit the color of the position where the mouse click + // happened + + const QPixmap pm = QPixmap::grabWidget( this ); + const QRgb rgb = pm.toImage().pixel( e->x(), e->y() ); + + Q_EMIT selected( QColor( rgb ) ); + e->accept(); + } +} + +void ColorBar::paintEvent( QPaintEvent * ) +{ + QPainter painter( this ); + drawColorBar( &painter, rect() ); +} + +void ColorBar::drawColorBar( QPainter *painter, const QRect &rect ) const +{ + int h1, s1, v1; + int h2, s2, v2; + + d_light.getHsv( &h1, &s1, &v1 ); + d_dark.getHsv( &h2, &s2, &v2 ); + + painter->save(); + painter->setClipRect( rect ); + painter->setClipping( true ); + + painter->fillRect( rect, d_dark ); + + const int sectionSize = 2; + + int numIntervals; + if ( d_orientation == Qt::Horizontal ) + numIntervals = rect.width() / sectionSize; + else + numIntervals = rect.height() / sectionSize; + + for ( int i = 0; i < numIntervals; i++ ) + { + QRect section; + if ( d_orientation == Qt::Horizontal ) + { + section.setRect( rect.x() + i * sectionSize, rect.y(), + sectionSize, rect.height() ); + } + else + { + section.setRect( rect.x(), rect.y() + i * sectionSize, + rect.width(), sectionSize ); + } + + const double ratio = i / static_cast( numIntervals ); + + QColor c; + c.setHsv( h1 + qRound( ratio * ( h2 - h1 ) ), + s1 + qRound( ratio * ( s2 - s1 ) ), + v1 + qRound( ratio * ( v2 - v1 ) ) ); + + painter->fillRect( section, c ); + } + + painter->restore(); +} + diff --git a/ThirdParty/Qwt/examples/event_filter/colorbar.h b/ThirdParty/Qwt/examples/event_filter/colorbar.h new file mode 100644 index 0000000000..757581323f --- /dev/null +++ b/ThirdParty/Qwt/examples/event_filter/colorbar.h @@ -0,0 +1,33 @@ +#include + +class ColorBar: public QWidget +{ + Q_OBJECT + +public: + ColorBar( Qt::Orientation = Qt::Horizontal, QWidget * = NULL ); + + virtual void setOrientation( Qt::Orientation ); + Qt::Orientation orientation() const { return d_orientation; } + + void setRange( const QColor &light, const QColor &dark ); + void setLight( const QColor &light ); + void setDark( const QColor &dark ); + + QColor light() const { return d_light; } + QColor dark() const { return d_dark; } + +Q_SIGNALS: + void selected( const QColor & ); + +protected: + virtual void mousePressEvent( QMouseEvent * ); + virtual void paintEvent( QPaintEvent * ); + + void drawColorBar( QPainter *, const QRect & ) const; + +private: + Qt::Orientation d_orientation; + QColor d_light; + QColor d_dark; +}; diff --git a/ThirdParty/Qwt/examples/event_filter/event_filter.cpp b/ThirdParty/Qwt/examples/event_filter/event_filter.cpp new file mode 100644 index 0000000000..efa8ba3cdc --- /dev/null +++ b/ThirdParty/Qwt/examples/event_filter/event_filter.cpp @@ -0,0 +1,51 @@ +//----------------------------------------------------------------- +// A demo program showing how to use event filtering +//----------------------------------------------------------------- + +#include +#include +#include +#include +#include +#include "plot.h" +#include "canvaspicker.h" +#include "scalepicker.h" + +int main ( int argc, char **argv ) +{ + QApplication a( argc, argv ); + + QMainWindow mainWindow; + QToolBar *toolBar = new QToolBar( &mainWindow ); + QAction *action = QWhatsThis::createAction( toolBar ); + toolBar->addAction( action ); + mainWindow.addToolBar( toolBar ); + + Plot *plot = new Plot( &mainWindow ); + + // The canvas picker handles all mouse and key + // events on the plot canvas + + ( void ) new CanvasPicker( plot ); + + // The scale picker translates mouse clicks + // int o clicked() signals + + ScalePicker *scalePicker = new ScalePicker( plot ); + a.connect( scalePicker, SIGNAL( clicked( int, double ) ), + plot, SLOT( insertCurve( int, double ) ) ); + + mainWindow.setCentralWidget( plot ); + + mainWindow.resize( 540, 400 ); + mainWindow.show(); + + const char *text = + "An useless plot to demonstrate how to use event filtering.\n\n" + "You can click on the color bar, the scales or move the wheel.\n" + "All points can be moved using the mouse or the keyboard."; + plot->setWhatsThis( text ); + + int rv = a.exec(); + return rv; +} diff --git a/ThirdParty/Qwt/examples/event_filter/event_filter.pro b/ThirdParty/Qwt/examples/event_filter/event_filter.pro new file mode 100644 index 0000000000..c50daa895f --- /dev/null +++ b/ThirdParty/Qwt/examples/event_filter/event_filter.pro @@ -0,0 +1,25 @@ +################################################################ +# Qwt Widget Library +# Copyright (C) 1997 Josef Wilgen +# Copyright (C) 2002 Uwe Rathmann +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the Qwt License, Version 1.0 +################################################################ + +include( $${PWD}/../examples.pri ) + +TARGET = event_filter + +HEADERS = \ + colorbar.h \ + scalepicker.h \ + canvaspicker.h \ + plot.h + +SOURCES = \ + colorbar.cpp \ + scalepicker.cpp \ + canvaspicker.cpp \ + plot.cpp \ + event_filter.cpp diff --git a/ThirdParty/Qwt/examples/event_filter/plot.cpp b/ThirdParty/Qwt/examples/event_filter/plot.cpp new file mode 100644 index 0000000000..f9aa31f407 --- /dev/null +++ b/ThirdParty/Qwt/examples/event_filter/plot.cpp @@ -0,0 +1,176 @@ +#include "plot.h" +#include "colorbar.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +Plot::Plot( QWidget *parent ): + QwtPlot( parent ) +{ + setTitle( "Interactive Plot" ); + + setCanvasColor( Qt::darkCyan ); + + QwtPlotGrid *grid = new QwtPlotGrid; + grid->setMajorPen( Qt::white, 0, Qt::DotLine ); + grid->attach( this ); + + // axes + + setAxisScale( QwtPlot::xBottom, 0.0, 100.0 ); + setAxisScale( QwtPlot::yLeft, 0.0, 100.0 ); + + // Avoid jumping when label with 3 digits + // appear/disappear when scrolling vertically + + QwtScaleDraw *sd = axisScaleDraw( QwtPlot::yLeft ); + sd->setMinimumExtent( sd->extent( axisWidget( QwtPlot::yLeft )->font() ) ); + + plotLayout()->setAlignCanvasToScales( true ); + + insertCurve( Qt::Vertical, Qt::blue, 30.0 ); + insertCurve( Qt::Vertical, Qt::magenta, 70.0 ); + insertCurve( Qt::Horizontal, Qt::yellow, 30.0 ); + insertCurve( Qt::Horizontal, Qt::white, 70.0 ); + + replot(); + + // ------------------------------------ + // We add a color bar to the left axis + // ------------------------------------ + + QwtScaleWidget *scaleWidget = axisWidget( yLeft ); + scaleWidget->setMargin( 10 ); // area for the color bar + d_colorBar = new ColorBar( Qt::Vertical, scaleWidget ); + d_colorBar->setRange( Qt::red, Qt::darkBlue ); + d_colorBar->setFocusPolicy( Qt::TabFocus ); + + connect( d_colorBar, SIGNAL( selected( const QColor & ) ), + SLOT( setCanvasColor( const QColor & ) ) ); + + // we need the resize events, to lay out the color bar + scaleWidget->installEventFilter( this ); + + // ------------------------------------ + // We add a wheel to the canvas + // ------------------------------------ + + d_wheel = new QwtWheel( canvas() ); + d_wheel->setOrientation( Qt::Vertical ); + d_wheel->setRange( -100, 100 ); + d_wheel->setValue( 0.0 ); + d_wheel->setMass( 0.2 ); + d_wheel->setTotalAngle( 4 * 360.0 ); + + connect( d_wheel, SIGNAL( valueChanged( double ) ), + SLOT( scrollLeftAxis( double ) ) ); + + // we need the resize events, to lay out the wheel + canvas()->installEventFilter( this ); + + d_colorBar->setWhatsThis( + "Selecting a color will change the background of the plot." ); + scaleWidget->setWhatsThis( + "Selecting a value at the scale will insert a new curve." ); + d_wheel->setWhatsThis( + "With the wheel you can move the visible area." ); + axisWidget( xBottom )->setWhatsThis( + "Selecting a value at the scale will insert a new curve." ); +} + +void Plot::setCanvasColor( const QColor &c ) +{ + setCanvasBackground( c ); + replot(); +} + +void Plot::scrollLeftAxis( double value ) +{ + setAxisScale( yLeft, value, value + 100.0 ); + replot(); +} + +bool Plot::eventFilter( QObject *object, QEvent *e ) +{ + if ( e->type() == QEvent::Resize ) + { + const QSize size = static_cast( e )->size(); + if ( object == axisWidget( yLeft ) ) + { + const QwtScaleWidget *scaleWidget = axisWidget( yLeft ); + + const int margin = 2; + + // adjust the color bar to the scale backbone + const int x = size.width() - scaleWidget->margin() + margin; + const int w = scaleWidget->margin() - 2 * margin; + const int y = scaleWidget->startBorderDist(); + const int h = size.height() - + scaleWidget->startBorderDist() - scaleWidget->endBorderDist(); + + d_colorBar->setGeometry( x, y, w, h ); + } + if ( object == canvas() ) + { + const int w = 16; + const int h = 50; + const int margin = 2; + + const QRect cr = canvas()->contentsRect(); + d_wheel->setGeometry( + cr.right() - margin - w, cr.center().y() - h / 2, w, h ); + } + } + + return QwtPlot::eventFilter( object, e ); +} + +void Plot::insertCurve( int axis, double base ) +{ + Qt::Orientation o; + if ( axis == yLeft || axis == yRight ) + o = Qt::Horizontal; + else + o = Qt::Vertical; + + QRgb rgb = static_cast( rand() ); + insertCurve( o, QColor( rgb ), base ); + replot(); +} + +void Plot::insertCurve( Qt::Orientation o, + const QColor &c, double base ) +{ + QwtPlotCurve *curve = new QwtPlotCurve(); + + curve->setPen( c ); + curve->setSymbol( new QwtSymbol( QwtSymbol::Ellipse, + Qt::gray, c, QSize( 8, 8 ) ) ); + + double x[10]; + double y[sizeof( x ) / sizeof( x[0] )]; + + for ( uint i = 0; i < sizeof( x ) / sizeof( x[0] ); i++ ) + { + double v = 5.0 + i * 10.0; + if ( o == Qt::Horizontal ) + { + x[i] = v; + y[i] = base; + } + else + { + x[i] = base; + y[i] = v; + } + } + + curve->setSamples( x, y, sizeof( x ) / sizeof( x[0] ) ); + curve->attach( this ); +} diff --git a/ThirdParty/Qwt/examples/event_filter/plot.h b/ThirdParty/Qwt/examples/event_filter/plot.h new file mode 100644 index 0000000000..8f0798c65e --- /dev/null +++ b/ThirdParty/Qwt/examples/event_filter/plot.h @@ -0,0 +1,25 @@ +#include + +class ColorBar; +class QwtWheel; + +class Plot: public QwtPlot +{ + Q_OBJECT +public: + Plot( QWidget *parent = NULL ); + virtual bool eventFilter( QObject *, QEvent * ); + +public Q_SLOTS: + void setCanvasColor( const QColor & ); + void insertCurve( int axis, double base ); + +private Q_SLOTS: + void scrollLeftAxis( double ); + +private: + void insertCurve( Qt::Orientation, const QColor &, double base ); + + ColorBar *d_colorBar; + QwtWheel *d_wheel; +}; diff --git a/ThirdParty/Qwt/examples/event_filter/scalepicker.cpp b/ThirdParty/Qwt/examples/event_filter/scalepicker.cpp new file mode 100644 index 0000000000..4cbf1b3bf1 --- /dev/null +++ b/ThirdParty/Qwt/examples/event_filter/scalepicker.cpp @@ -0,0 +1,119 @@ +#include "scalepicker.h" +#include +#include +#include +#include + +ScalePicker::ScalePicker( QwtPlot *plot ): + QObject( plot ) +{ + for ( uint i = 0; i < QwtPlot::axisCnt; i++ ) + { + QwtScaleWidget *scaleWidget = plot->axisWidget( i ); + if ( scaleWidget ) + scaleWidget->installEventFilter( this ); + } +} + +bool ScalePicker::eventFilter( QObject *object, QEvent *event ) +{ + if ( event->type() == QEvent::MouseButtonPress ) + { + QwtScaleWidget *scaleWidget = qobject_cast( object ); + if ( scaleWidget ) + { + QMouseEvent *mouseEvent = static_cast( event ); + mouseClicked( scaleWidget, mouseEvent->pos() ); + + return true; + } + } + + return QObject::eventFilter( object, event ); +} + +void ScalePicker::mouseClicked( const QwtScaleWidget *scale, const QPoint &pos ) +{ + QRect rect = scaleRect( scale ); + + int margin = 10; // 10 pixels tolerance + rect.setRect( rect.x() - margin, rect.y() - margin, + rect.width() + 2 * margin, rect.height() + 2 * margin ); + + if ( rect.contains( pos ) ) // No click on the title + { + // translate the position in a value on the scale + + double value = 0.0; + int axis = -1; + + const QwtScaleDraw *sd = scale->scaleDraw(); + switch( scale->alignment() ) + { + case QwtScaleDraw::LeftScale: + { + value = sd->scaleMap().invTransform( pos.y() ); + axis = QwtPlot::yLeft; + break; + } + case QwtScaleDraw::RightScale: + { + value = sd->scaleMap().invTransform( pos.y() ); + axis = QwtPlot::yRight; + break; + } + case QwtScaleDraw::BottomScale: + { + value = sd->scaleMap().invTransform( pos.x() ); + axis = QwtPlot::xBottom; + break; + } + case QwtScaleDraw::TopScale: + { + value = sd->scaleMap().invTransform( pos.x() ); + axis = QwtPlot::xTop; + break; + } + } + Q_EMIT clicked( axis, value ); + } +} + +// The rect of a scale without the title +QRect ScalePicker::scaleRect( const QwtScaleWidget *scale ) const +{ + const int bld = scale->margin(); + const int mjt = qCeil( scale->scaleDraw()->maxTickLength() ); + const int sbd = scale->startBorderDist(); + const int ebd = scale->endBorderDist(); + + QRect rect; + switch( scale->alignment() ) + { + case QwtScaleDraw::LeftScale: + { + rect.setRect( scale->width() - bld - mjt, sbd, + mjt, scale->height() - sbd - ebd ); + break; + } + case QwtScaleDraw::RightScale: + { + rect.setRect( bld, sbd, + mjt, scale->height() - sbd - ebd ); + break; + } + case QwtScaleDraw::BottomScale: + { + rect.setRect( sbd, bld, + scale->width() - sbd - ebd, mjt ); + break; + } + case QwtScaleDraw::TopScale: + { + rect.setRect( sbd, scale->height() - bld - mjt, + scale->width() - sbd - ebd, mjt ); + break; + } + } + return rect; +} diff --git a/ThirdParty/Qwt/examples/event_filter/scalepicker.h b/ThirdParty/Qwt/examples/event_filter/scalepicker.h new file mode 100644 index 0000000000..bcdc12d9e6 --- /dev/null +++ b/ThirdParty/Qwt/examples/event_filter/scalepicker.h @@ -0,0 +1,20 @@ +#include +#include + +class QwtPlot; +class QwtScaleWidget; + +class ScalePicker: public QObject +{ + Q_OBJECT +public: + ScalePicker( QwtPlot *plot ); + virtual bool eventFilter( QObject *, QEvent * ); + +Q_SIGNALS: + void clicked( int axis, double value ); + +private: + void mouseClicked( const QwtScaleWidget *, const QPoint & ); + QRect scaleRect( const QwtScaleWidget * ) const; +}; diff --git a/ThirdParty/Qwt/examples/examples.pri b/ThirdParty/Qwt/examples/examples.pri new file mode 100644 index 0000000000..33c7be821d --- /dev/null +++ b/ThirdParty/Qwt/examples/examples.pri @@ -0,0 +1,77 @@ +################################################################ +# Qwt Widget Library +# Copyright (C) 1997 Josef Wilgen +# Copyright (C) 2002 Uwe Rathmann +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the Qwt License, Version 1.0 +################################################################### + +QWT_ROOT = $${PWD}/.. +include( $${QWT_ROOT}/qwtconfig.pri ) +include( $${QWT_ROOT}/qwtbuild.pri ) +include( $${QWT_ROOT}/qwtfunctions.pri ) + +TEMPLATE = app + +INCLUDEPATH += $${QWT_ROOT}/src +DEPENDPATH += $${QWT_ROOT}/src + +!debug_and_release { + + DESTDIR = $${QWT_ROOT}/examples/bin +} +else { + CONFIG(debug, debug|release) { + + DESTDIR = $${QWT_ROOT}/examples/bin_debug + } + else { + + DESTDIR = $${QWT_ROOT}/examples/bin + } +} + +QMAKE_RPATHDIR *= $${QWT_ROOT}/lib + +contains(QWT_CONFIG, QwtFramework) { + + LIBS += -F$${QWT_ROOT}/lib +} +else { + + LIBS += -L$${QWT_ROOT}/lib +} + +qwtAddLibrary(qwt) + +greaterThan(QT_MAJOR_VERSION, 4) { + + QT += printsupport + QT += concurrent +} + +contains(QWT_CONFIG, QwtOpenGL ) { + + QT += opengl +} +else { + + DEFINES += QWT_NO_OPENGL +} + +contains(QWT_CONFIG, QwtSvg) { + + QT += svg +} +else { + + DEFINES += QWT_NO_SVG +} + + +win32 { + contains(QWT_CONFIG, QwtDll) { + DEFINES += QT_DLL QWT_DLL + } +} diff --git a/ThirdParty/Qwt/examples/examples.pro b/ThirdParty/Qwt/examples/examples.pro new file mode 100644 index 0000000000..1f0ea4d9d7 --- /dev/null +++ b/ThirdParty/Qwt/examples/examples.pro @@ -0,0 +1,51 @@ +################################################################ +# Qwt Widget Library +# Copyright (C) 1997 Josef Wilgen +# Copyright (C) 2002 Uwe Rathmann +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the Qwt License, Version 1.0 +################################################################ + +include( $${PWD}/../qwtconfig.pri ) + +TEMPLATE = subdirs + +contains(QWT_CONFIG, QwtPlot) { + + SUBDIRS += \ + animation \ + barchart \ + cpuplot \ + curvdemo1 \ + distrowatch \ + friedberg \ + itemeditor \ + legends \ + stockchart \ + simpleplot \ + sinusplot \ + realtime \ + refreshtest \ + scatterplot \ + spectrogram \ + rasterview \ + tvplot + + contains(QWT_CONFIG, QwtWidgets) { + + SUBDIRS += \ + bode \ + event_filter \ + oscilloscope + } +} + +contains(QWT_CONFIG, QwtWidgets) { + + SUBDIRS += \ + sysinfo \ + radio \ + dials \ + controls +} diff --git a/ThirdParty/Qwt/examples/friedberg/friedberg.pro b/ThirdParty/Qwt/examples/friedberg/friedberg.pro new file mode 100644 index 0000000000..3a15c5b6ba --- /dev/null +++ b/ThirdParty/Qwt/examples/friedberg/friedberg.pro @@ -0,0 +1,21 @@ +################################################################ +# Qwt Widget Library +# Copyright (C) 1997 Josef Wilgen +# Copyright (C) 2002 Uwe Rathmann +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the Qwt License, Version 1.0 +################################################################ + +include( $${PWD}/../examples.pri ) + +TARGET = friedberg + +HEADERS = \ + plot.h \ + friedberg2007.h + +SOURCES = \ + friedberg2007.cpp \ + plot.cpp \ + main.cpp diff --git a/ThirdParty/Qwt/examples/friedberg/friedberg2007.cpp b/ThirdParty/Qwt/examples/friedberg/friedberg2007.cpp new file mode 100644 index 0000000000..19f688e9e9 --- /dev/null +++ b/ThirdParty/Qwt/examples/friedberg/friedberg2007.cpp @@ -0,0 +1,384 @@ +#include "friedberg2007.h" + +// Temperature 2007 from Friedberg somewhere in Germany +// See: http://wetter61169.de + +Temperature friedberg2007[] = +{ + /* 01.01 */ Temperature( 2.6, 9.8, 7.07862 ), + /* 02.01 */ Temperature( 0.8, 5.8, 3.6993 ), + /* 03.01 */ Temperature( 2, 7, 5.02388 ), + /* 04.01 */ Temperature( 5.3, 7.8, 6.37778 ), + /* 05.01 */ Temperature( 5.6, 7.7, 6.83149 ), + /* 06.01 */ Temperature( 7.2, 8.9, 8.0816 ), + /* 07.01 */ Temperature( 4.2, 9.9, 7.54704 ), + /* 08.01 */ Temperature( 3.5, 8.9, 6.71951 ), + /* 09.01 */ Temperature( 8.2, 12.9, 10.8594 ), + /* 10.01 */ Temperature( 6.3, 11.9, 9.76424 ), + /* 11.01 */ Temperature( 3.9, 9.2, 6.18223 ), + /* 12.01 */ Temperature( 6.9, 9.7, 8.44236 ), + /* 13.01 */ Temperature( 9, 12.3, 10.6649 ), + /* 14.01 */ Temperature( 1.8, 10.8, 7.23438 ), + /* 15.01 */ Temperature( -2.8, 1.8, -0.518403 ), + /* 16.01 */ Temperature( -0.6, 4.5, 2.39479 ), + /* 17.01 */ Temperature( 4.3, 10.2, 7.23472 ), + /* 18.01 */ Temperature( 9.1, 13.6, 10.9316 ), + /* 19.01 */ Temperature( 6.9, 12.4, 9.4128 ), + /* 20.01 */ Temperature( 7.1, 13.3, 10.5083 ), + /* 21.01 */ Temperature( 3.5, 9.6, 6.10871 ), + /* 22.01 */ Temperature( -1.8, 6, 2.89028 ), + /* 23.01 */ Temperature( -5.4, 1.7, -2.46678 ), + /* 24.01 */ Temperature( -5.3, -1.3, -3.71483 ), + /* 25.01 */ Temperature( -7.5, 3.3, -3.36736 ), + /* 26.01 */ Temperature( -11.1, 0.3, -5.50662 ), + /* 27.01 */ Temperature( 0.2, 3.2, 1.95345 ), + /* 28.01 */ Temperature( 1.9, 5.2, 3.43633 ), + /* 29.01 */ Temperature( 4.4, 9.1, 6.24236 ), + /* 30.01 */ Temperature( 2.3, 11.5, 6.03114 ), + /* 31.01 */ Temperature( 4.6, 10.2, 6.04192 ), + + /* 01.02 */ Temperature( 4.8, 13.8, 7.87674 ), + /* 02.02 */ Temperature( 5.7, 10, 7.28646 ), + /* 03.02 */ Temperature( 2.9, 8.2, 5.71771 ), + /* 04.02 */ Temperature( -1.5, 7.2, 4.71319 ), + /* 05.02 */ Temperature( -2.6, 4.4, 1.23542 ), + /* 06.02 */ Temperature( 0.3, 9.2, 2.59965 ), + /* 07.02 */ Temperature( -0.4, 2.4, 0.641667 ), + /* 08.02 */ Temperature( -1.7, 3.8, 0.811458 ), + /* 09.02 */ Temperature( 0.7, 7, 3.58328 ), + /* 10.02 */ Temperature( 1, 6, 3.51181 ), + /* 11.02 */ Temperature( 4.7, 9.6, 6.14913 ), + /* 12.02 */ Temperature( 5.3, 8.7, 6.80552 ), + /* 13.02 */ Temperature( 4.4, 10.3, 6.84552 ), + /* 14.02 */ Temperature( 2.6, 6.5, 4.58681 ), + /* 15.02 */ Temperature( -0.8, 13.4, 6.38542 ), + /* 16.02 */ Temperature( -3, 14.4, 4.11336 ), + /* 17.02 */ Temperature( 0.5, 13, 5.87457 ), + /* 18.02 */ Temperature( -2.2, 14.1, 4.36528 ), + /* 19.02 */ Temperature( 3.9, 5.6, 4.63737 ), + /* 20.02 */ Temperature( -0.4, 9.2, 4.37014 ), + /* 21.02 */ Temperature( -1.9, 5.5, 1.85675 ), + /* 22.02 */ Temperature( 1, 13.1, 5.41176 ), + /* 23.02 */ Temperature( 1.9, 13.9, 7.74251 ), + /* 24.02 */ Temperature( 3.8, 9.6, 7.19306 ), + /* 25.02 */ Temperature( 5.8, 10.8, 7.80312 ), + /* 26.02 */ Temperature( 5.2, 10.4, 6.79481 ), + /* 27.02 */ Temperature( 3.2, 7.4, 5.22986 ), + /* 28.02 */ Temperature( 6.4, 13.4, 9.13356 ), + + /* 01.03 */ Temperature( 4.6, 11.4, 7.70554 ), + /* 02.03 */ Temperature( 3.4, 10.9, 5.98408 ), + /* 03.03 */ Temperature( 2.9, 10.5, 5.45675 ), + /* 04.03 */ Temperature( -0.7, 16.8, 7.29585 ), + /* 05.03 */ Temperature( 4.2, 13.4, 8.35862 ), + /* 06.03 */ Temperature( 3, 13, 7.76644 ), + /* 07.03 */ Temperature( 2, 13.3, 8.24618 ), + /* 08.03 */ Temperature( -0.8, 15, 6.11765 ), + /* 09.03 */ Temperature( -0.7, 11, 5.7568 ), + /* 10.03 */ Temperature( 1.2, 14.4, 6.61389 ), + /* 11.03 */ Temperature( -1.7, 18, 6.66146 ), + /* 12.03 */ Temperature( -0.6, 21.9, 8.9816 ), + /* 13.03 */ Temperature( -0.9, 19.6, 9.08299 ), + /* 14.03 */ Temperature( 5.3, 18.9, 10.5562 ), + /* 15.03 */ Temperature( 2, 20.5, 9.65156 ), + /* 16.03 */ Temperature( 0.2, 16.7, 7.8699 ), + /* 17.03 */ Temperature( 4.5, 10.6, 7.87535 ), + /* 18.03 */ Temperature( 2.7, 9.7, 6.71806 ), + /* 19.03 */ Temperature( 0.4, 10.9, 3.92404 ), + /* 20.03 */ Temperature( -2, 12.7, 4.01359 ), + /* 21.03 */ Temperature( 0.3, 6.8, 3.00382 ), + /* 22.03 */ Temperature( 0.9, 4.2, 2.2816 ), + /* 23.03 */ Temperature( 2, 5.7, 3.39233 ), + /* 24.03 */ Temperature( 3.9, 9.3, 6.41076 ), + /* 25.03 */ Temperature( 4.2, 19.1, 9.92182 ), + /* 26.03 */ Temperature( 2.3, 22, 12.5716 ), + /* 27.03 */ Temperature( 4.9, 20.6, 13.4568 ), + /* 28.03 */ Temperature( 0.3, 22.8, 10.755 ), + /* 29.03 */ Temperature( 1.8, 17.2, 9.43924 ), + /* 30.03 */ Temperature( 1.9, 19.8, 10.25 ), + /* 31.03 */ Temperature( 6.7, 17, 11.1324 ), + + /* 01.04 */ Temperature( 5.7, 22, 12.8457 ), + /* 02.04 */ Temperature( 6.4, 22.1, 13.3847 ), + /* 03.04 */ Temperature( 5.8, 17.5, 10.5614 ), + /* 04.04 */ Temperature( 2.8, 16.2, 8.06574 ), + /* 05.04 */ Temperature( -0.6, 20.8, 9.18062 ), + /* 06.04 */ Temperature( 2.1, 24, 13.0069 ), + /* 07.04 */ Temperature( 5.3, 16.2, 10.2771 ), + /* 08.04 */ Temperature( 0.1, 20.7, 9.79861 ), + /* 09.04 */ Temperature( 0.3, 18.9, 10.0087 ), + /* 10.04 */ Temperature( 4, 16.4, 11.4208 ), + /* 11.04 */ Temperature( 2.3, 23.4, 13.083 ), + /* 12.04 */ Temperature( 7, 29.4, 16.5826 ), + /* 13.04 */ Temperature( 10.6, 31.5, 19.2249 ), + /* 14.04 */ Temperature( 11.8, 34, 21.441 ), + /* 15.04 */ Temperature( 11.6, 33.8, 21.0201 ), + /* 16.04 */ Temperature( 8.7, 31.1, 18.7885 ), + /* 17.04 */ Temperature( 5.5, 27.2, 16.1432 ), + /* 18.04 */ Temperature( 6.1, 17.2, 10.6688 ), + /* 19.04 */ Temperature( -0.6, 21.3, 10.4806 ), + /* 20.04 */ Temperature( 5.9, 21.6, 12.6257 ), + /* 21.04 */ Temperature( 2.1, 21.6, 11.0858 ), + /* 22.04 */ Temperature( 3.9, 25.9, 14.2108 ), + /* 23.04 */ Temperature( 3.1, 27.8, 15.7111 ), + /* 24.04 */ Temperature( 13.7, 29, 19.6397 ), + /* 25.04 */ Temperature( 9.8, 31.6, 19.601 ), + /* 26.04 */ Temperature( 8.2, 32.4, 20.0389 ), + /* 27.04 */ Temperature( 11.8, 32.1, 21.0726 ), + /* 28.04 */ Temperature( 12.6, 33.3, 21.6993 ), + /* 29.04 */ Temperature( 10.5, 27.4, 19.1206 ), + /* 30.04 */ Temperature( 5.3, 26.4, 15.0972 ), + + /* 01.05 */ Temperature( 6.9, 25.3, 15.2802 ), + /* 02.05 */ Temperature( 4.3, 26.2, 14.8401 ), + /* 03.05 */ Temperature( 7.1, 28.5, 17.2145 ), + /* 04.05 */ Temperature( 11, 28.5, 18.537 ), + /* 05.05 */ Temperature( 12, 28, 18.1672 ), + /* 06.05 */ Temperature( 10.4, 29, 18.3844 ), + /* 07.05 */ Temperature( 13, 18.1, 15.0028 ), + /* 08.05 */ Temperature( 10.7, 18.3, 13.2014 ), + /* 09.05 */ Temperature( 10.8, 14.4, 12.5208 ), + /* 10.05 */ Temperature( 11.9, 23.5, 16.9632 ), + /* 11.05 */ Temperature( 9.8, 16.9, 15.0795 ), + /* 12.05 */ Temperature( 9.2, 19.6, 13.8521 ), + /* 13.05 */ Temperature( 8.9, 26.3, 16.2028 ), + /* 14.05 */ Temperature( 11.1, 17.5, 13.2934 ), + /* 15.05 */ Temperature( 6.5, 17, 11.7743 ), + /* 16.05 */ Temperature( 4.9, 13.6, 9.75625 ), + /* 17.05 */ Temperature( 6.8, 16.6, 9.96701 ), + /* 18.05 */ Temperature( 2.4, 21.2, 11.4311 ), + /* 19.05 */ Temperature( 8.2, 24.4, 15.4188 ), + /* 20.05 */ Temperature( 14.1, 31.7, 21.3303 ), + /* 21.05 */ Temperature( 11, 30.9, 21.5359 ), + /* 22.05 */ Temperature( 13.8, 31, 21.5177 ), + /* 23.05 */ Temperature( 16, 27.8, 21.0271 ), + /* 24.05 */ Temperature( 15, 34, 23.4142 ), + /* 25.05 */ Temperature( 14.3, 31.8, 22.8903 ), + /* 26.05 */ Temperature( 13.6, 33.1, 22.6156 ), + /* 27.05 */ Temperature( 11.2, 23.4, 16.6192 ), + /* 28.05 */ Temperature( 9.6, 13.1, 11.3222 ), + /* 29.05 */ Temperature( 8.3, 11.2, 10.3529 ), + /* 30.05 */ Temperature( 4.2, 20.8, 12.6218 ), + /* 31.05 */ Temperature( 9.2, 23.6, 15.1073 ), + + /* 01.06 */ Temperature( 10.8, 24.4, 16.3205 ), + /* 02.06 */ Temperature( 13, 26.5, 18.9649 ), + /* 03.06 */ Temperature( 14, 25.1, 18.5398 ), + /* 04.06 */ Temperature( 13, 28, 20.2139 ), + /* 05.06 */ Temperature( 14, 28.8, 20.438 ), + /* 06.06 */ Temperature( 14, 30.4, 21.7821 ), + /* 07.06 */ Temperature( 17, 34.8, 25.3087 ), + /* 08.06 */ Temperature( 17.9, 35.7, 25.7872 ), + /* 09.06 */ Temperature( 17.8, 31.6, 22.0788 ), + /* 10.06 */ Temperature( 15.5, 33.4, 22.4458 ), + /* 11.06 */ Temperature( 16.6, 28.3, 19.8797 ), + /* 12.06 */ Temperature( 14, 27.3, 20.2566 ), + /* 13.06 */ Temperature( 13.2, 28.2, 19.4233 ), + /* 14.06 */ Temperature( 12.7, 30, 20.1427 ), + /* 15.06 */ Temperature( 15.2, 22.6, 18.5917 ), + /* 16.06 */ Temperature( 13.2, 24, 17.7014 ), + /* 17.06 */ Temperature( 11.7, 27.9, 19.8229 ), + /* 18.06 */ Temperature( 15.9, 27.2, 20.3358 ), + /* 19.06 */ Temperature( 12.6, 33.7, 22.2427 ), + /* 20.06 */ Temperature( 15.7, 30.8, 23.7507 ), + /* 21.06 */ Temperature( 14.8, 22.6, 18.2538 ), + /* 22.06 */ Temperature( 12.4, 21.3, 15.9969 ), + /* 23.06 */ Temperature( 12.6, 21.6, 15.8149 ), + /* 24.06 */ Temperature( 13, 26, 18.4176 ), + /* 25.06 */ Temperature( 12.9, 24.4, 17.1299 ), + /* 26.06 */ Temperature( 10.8, 18.8, 13.2913 ), + /* 27.06 */ Temperature( 9.9, 18.8, 13.5465 ), + /* 28.06 */ Temperature( 12, 19.8, 14.8434 ), + /* 29.06 */ Temperature( 12, 19, 15.155 ), + /* 30.06 */ Temperature( 12.4, 22.4, 17.1354 ), + + /* 01.07 */ Temperature( 12.1, 24.9, 19.1639 ), + /* 02.07 */ Temperature( 15.7, 24.3, 18.4554 ), + /* 03.07 */ Temperature( 12.7, 17.2, 14.6564 ), + /* 04.07 */ Temperature( 11.2, 19, 13.9529 ), + /* 05.07 */ Temperature( 11.5, 19, 14.6422 ), + /* 06.07 */ Temperature( 12.4, 22, 16.6146 ), + /* 07.07 */ Temperature( 11.6, 24, 17.666 ), + /* 08.07 */ Temperature( 9, 28, 19.1351 ), + /* 09.07 */ Temperature( 11.3, 21.5, 16.5271 ), + /* 10.07 */ Temperature( 11.3, 20.2, 14.2326 ), + /* 11.07 */ Temperature( 10.2, 19.2, 14.0649 ), + /* 12.07 */ Temperature( 13.2, 23.1, 16.6346 ), + /* 13.07 */ Temperature( 15, 27, 19.6844 ), + /* 14.07 */ Temperature( 13.4, 32.4, 23.845 ), + /* 15.07 */ Temperature( 15, 38.2, 26.8559 ), + /* 16.07 */ Temperature( 16.1, 36.5, 26.4483 ), + /* 17.07 */ Temperature( 19.7, 30.5, 24.189 ), + /* 18.07 */ Temperature( 14.2, 29.3, 22.1363 ), + /* 19.07 */ Temperature( 16.4, 25.9, 19.0819 ), + /* 20.07 */ Temperature( 16.2, 30.8, 22.151 ), + /* 21.07 */ Temperature( 14, 24.3, 18.6573 ), + /* 22.07 */ Temperature( 13.2, 24.5, 18.3301 ), + /* 23.07 */ Temperature( 10.6, 23.4, 16.6903 ), + /* 24.07 */ Temperature( 13.2, 20.8, 16.2743 ), + /* 25.07 */ Temperature( 12.2, 25.8, 18.8267 ), + /* 26.07 */ Temperature( 11.9, 28.9, 20.5522 ), + /* 27.07 */ Temperature( 17.6, 25.8, 21.5691 ), + /* 28.07 */ Temperature( 16.6, 24.6, 19.2295 ), + /* 29.07 */ Temperature( 13, 19, 15.9021 ), + /* 30.07 */ Temperature( 9.6, 19.7, 13.875 ), + /* 31.07 */ Temperature( 8, 22, 14.5284 ), + + /* 01.08 */ Temperature( 7.6, 27.5, 17.5684 ), + /* 02.08 */ Temperature( 9.2, 22.2, 16.1035 ), + /* 03.08 */ Temperature( 12.7, 25.3, 18.2958 ), + /* 04.08 */ Temperature( 8.6, 31.3, 19.7941 ), + /* 05.08 */ Temperature( 10.3, 32.7, 21.492 ), + /* 06.08 */ Temperature( 10, 33.4, 22.4431 ), + /* 07.08 */ Temperature( 16.8, 22.6, 19.5583 ), + /* 08.08 */ Temperature( 13.5, 16.7, 15.0264 ), + /* 09.08 */ Temperature( 13.2, 18.8, 15.6003 ), + /* 10.08 */ Temperature( 14.6, 27.9, 18.8292 ), + /* 11.08 */ Temperature( 16.3, 26.4, 20.3837 ), + /* 12.08 */ Temperature( 12.1, 28.7, 19.9892 ), + /* 13.08 */ Temperature( 15, 27.4, 19.7542 ), + /* 14.08 */ Temperature( 11.3, 28.3, 20.5656 ), + /* 15.08 */ Temperature( 18.6, 28.4, 23.1215 ), + /* 16.08 */ Temperature( 16, 23.6, 19.491 ), + /* 17.08 */ Temperature( 12.6, 22, 17.0437 ), + /* 18.08 */ Temperature( 8.5, 25.7, 16.5589 ), + /* 19.08 */ Temperature( 13.4, 25.8, 18.0543 ), + /* 20.08 */ Temperature( 10.9, 21.5, 16.1306 ), + /* 21.08 */ Temperature( 10.6, 19.2, 14.6177 ), + /* 22.08 */ Temperature( 14, 24.6, 17.3841 ), + /* 23.08 */ Temperature( 13.8, 30.4, 20.6125 ), + /* 24.08 */ Temperature( 12.3, 30.3, 20.7622 ), + /* 25.08 */ Temperature( 12.8, 30.2, 21.6736 ), + /* 26.08 */ Temperature( 15, 29.3, 21.266 ), + /* 27.08 */ Temperature( 12.9, 25.9, 18.791 ), + /* 28.08 */ Temperature( 9.3, 24.6, 16.2833 ), + /* 29.08 */ Temperature( 10.8, 25, 16.8459 ), + /* 30.08 */ Temperature( 8.2, 24.4, 15.9267 ), + /* 31.08 */ Temperature( 14.1, 20.5, 16.6128 ), + + /* 01.09 */ Temperature( 13.4, 21.9, 16.2205 ), + /* 02.09 */ Temperature( 12, 20.7, 16.0882 ), + /* 03.09 */ Temperature( 10.8, 21.3, 14.7913 ), + /* 04.09 */ Temperature( 7.8, 18.2, 12.2747 ), + /* 05.09 */ Temperature( 8.1, 22.2, 12.9406 ), + /* 06.09 */ Temperature( 10, 23.8, 13.8785 ), + /* 07.09 */ Temperature( 10.7, 21.2, 15.4823 ), + /* 08.09 */ Temperature( 12.4, 21, 15.8194 ), + /* 09.09 */ Temperature( 12.7, 16.9, 14.7212 ), + /* 10.09 */ Temperature( 10.3, 17.7, 12.9271 ), + /* 11.09 */ Temperature( 10.6, 20.8, 14.4788 ), + /* 12.09 */ Temperature( 10.8, 21.9, 15.0184 ), + /* 13.09 */ Temperature( 6.9, 24.6, 14.5222 ), + /* 14.09 */ Temperature( 8.1, 24, 15.6583 ), + /* 15.09 */ Temperature( 8.8, 22.8, 15.941 ), + /* 16.09 */ Temperature( 3.1, 24.5, 14.1486 ), + /* 17.09 */ Temperature( 12.4, 21.2, 16.0497 ), + /* 18.09 */ Temperature( 7.8, 16.1, 12.024 ), + /* 19.09 */ Temperature( 5.3, 18.1, 10.3003 ), + /* 20.09 */ Temperature( 6.4, 20.3, 12.3177 ), + /* 21.09 */ Temperature( 6, 23.8, 13.6247 ), + /* 22.09 */ Temperature( 5.7, 27, 14.6847 ), + /* 23.09 */ Temperature( 7.8, 28, 16.6238 ), + /* 24.09 */ Temperature( 9.6, 24.9, 16.7191 ), + /* 25.09 */ Temperature( 8.4, 17.6, 12.636 ), + /* 26.09 */ Temperature( 4.3, 18.9, 10.0809 ), + /* 27.09 */ Temperature( 9.4, 11.2, 10.3344 ), + /* 28.09 */ Temperature( 7.7, 12.6, 10.5337 ), + /* 29.09 */ Temperature( 9.8, 15.3, 11.9306 ), + /* 30.09 */ Temperature( 9.6, 21.1, 13.6635 ), + + /* 01.10 */ Temperature( 8.9, 24.5, 14.8163 ), + /* 02.10 */ Temperature( 13.5, 20.2, 16.1628 ), + /* 03.10 */ Temperature( 12.5, 18, 15.4691 ), + /* 04.10 */ Temperature( 13.8, 25, 17.2073 ), + /* 05.10 */ Temperature( 9.1, 23.2, 14.6181 ), + /* 06.10 */ Temperature( 6.4, 23.4, 12.8625 ), + /* 07.10 */ Temperature( 4.6, 22.1, 11.0052 ), + /* 08.10 */ Temperature( 2, 22.2, 10.1677 ), + /* 09.10 */ Temperature( 7.8, 21.6, 12.2139 ), + /* 10.10 */ Temperature( 7.1, 22.7, 13.0115 ), + /* 11.10 */ Temperature( 6.1, 21.2, 11.4333 ), + /* 12.10 */ Temperature( 4.3, 15.2, 10.6104 ), + /* 13.10 */ Temperature( 5.8, 23, 12.8875 ), + /* 14.10 */ Temperature( 1, 23, 9.72986 ), + /* 15.10 */ Temperature( 1, 19.3, 9.33021 ), + /* 16.10 */ Temperature( 8.5, 20.4, 13.2639 ), + /* 17.10 */ Temperature( 6.8, 17.3, 11.8174 ), + /* 18.10 */ Temperature( 5.2, 15.6, 9.06076 ), + /* 19.10 */ Temperature( 2.7, 13.5, 7.1309 ), + /* 20.10 */ Temperature( -0.2, 15.8, 6.01667 ), + /* 21.10 */ Temperature( 2.6, 6.1, 4.9441 ), + /* 22.10 */ Temperature( -0.8, 13.2, 4.50694 ), + /* 23.10 */ Temperature( -0.4, 13.3, 4.71007 ), + /* 24.10 */ Temperature( 2.9, 8.1, 5.96979 ), + /* 25.10 */ Temperature( 6.3, 10.5, 8.01206 ), + /* 26.10 */ Temperature( 7, 10.8, 8.14965 ), + /* 27.10 */ Temperature( 6.6, 9.7, 7.7809 ), + /* 28.10 */ Temperature( 1.7, 10.8, 6.95728 ), + /* 29.10 */ Temperature( 2.2, 9.9, 6.62917 ), + /* 30.10 */ Temperature( 5.8, 15, 8.76181 ), + /* 31.10 */ Temperature( 0.7, 15, 6.01528 ), + + /* 01.11 */ Temperature( -0.2, 9.7, 3.75842 ), + /* 02.11 */ Temperature( 6.4, 9.6, 8.00138 ), + /* 03.11 */ Temperature( 8.7, 13.1, 10.5676 ), + /* 04.11 */ Temperature( 8, 11.8, 9.54306 ), + /* 05.11 */ Temperature( 5.8, 15.9, 8.52345 ), + /* 06.11 */ Temperature( 5.5, 10.8, 7.16493 ), + /* 07.11 */ Temperature( 5.5, 8.9, 7.30172 ), + /* 08.11 */ Temperature( 7, 11.7, 8.96701 ), + /* 09.11 */ Temperature( 2.5, 8.4, 4.86528 ), + /* 10.11 */ Temperature( 3.7, 9, 5.20828 ), + /* 11.11 */ Temperature( 2.8, 10.6, 6.80756 ), + /* 12.11 */ Temperature( 2.7, 9.5, 5.07647 ), + /* 13.11 */ Temperature( 0.1, 5.4, 3.3945 ), + /* 14.11 */ Temperature( -0.7, 7.9, 2.02234 ), + /* 15.11 */ Temperature( -1.8, 6.5, 1.07778 ), + /* 16.11 */ Temperature( -4.4, 5.1, -0.693772 ), + /* 17.11 */ Temperature( -0.3, 3.4, 1.33229 ), + /* 18.11 */ Temperature( -0.4, 4.3, 2.4622 ), + /* 19.11 */ Temperature( 1.8, 3.6, 2.78282 ), + /* 20.11 */ Temperature( 1.3, 5.6, 2.95979 ), + /* 21.11 */ Temperature( 1.6, 5.7, 3.62284 ), + /* 22.11 */ Temperature( 3.1, 7.3, 5.60277 ), + /* 23.11 */ Temperature( 4.2, 7.7, 6.28166 ), + /* 24.11 */ Temperature( -0.5, 11.5, 3.25931 ), + /* 25.11 */ Temperature( -1, 8.8, 2.86505 ), + /* 26.11 */ Temperature( 1.2, 6.8, 3.09414 ), + /* 27.11 */ Temperature( -0.8, 7.5, 3.17805 ), + /* 28.11 */ Temperature( -2.8, 3.1, -0.920139 ), + /* 29.11 */ Temperature( -2.6, 1.7, -0.491696 ), + /* 30.11 */ Temperature( 1.3, 6.5, 3.85 ), + + /* 01.12 */ Temperature( 4.1, 8.7, 5.88924 ), + /* 02.12 */ Temperature( 4.8, 9, 6.81667 ), + /* 03.12 */ Temperature( 3.5, 8.5, 6.23633 ), + /* 04.12 */ Temperature( 2.7, 6.6, 4.63045 ), + /* 05.12 */ Temperature( 4.3, 8.6, 6.85993 ), + /* 06.12 */ Temperature( 5.5, 9.3, 7.79201 ), + /* 07.12 */ Temperature( 3.1, 13.4, 8.79444 ), + /* 08.12 */ Temperature( 2.6, 6.3, 4.67093 ), + /* 09.12 */ Temperature( 3, 10.4, 5.75724 ), + /* 10.12 */ Temperature( 4.1, 6.8, 5.31834 ), + /* 11.12 */ Temperature( 4.1, 7.4, 5.28993 ), + /* 12.12 */ Temperature( 3.9, 6.4, 4.64479 ), + /* 13.12 */ Temperature( 1.7, 9.1, 4.15363 ), + /* 14.12 */ Temperature( 0.4, 1.8, 0.934602 ), + /* 15.12 */ Temperature( -4.5, 2.1, -1.17292 ), + /* 16.12 */ Temperature( -5, 4.8, -2.17431 ), + /* 17.12 */ Temperature( -5.6, 6.1, -1.35448 ), + /* 18.12 */ Temperature( -4.9, 6.4, -1.25502 ), + /* 19.12 */ Temperature( -4.4, 6.6, -1.02396 ), + /* 20.12 */ Temperature( -7.3, 5.2, -2.63854 ), + /* 21.12 */ Temperature( -8.5, 5.7, -3.58333 ), + /* 22.12 */ Temperature( -7.9, -5.3, -6.13438 ), + /* 23.12 */ Temperature( -6.1, -4.4, -5.23472 ), + /* 24.12 */ Temperature( -4.6, -3.3, -3.84291 ), + /* 25.12 */ Temperature( -4.9, -2.8, -3.9066 ), + /* 26.12 */ Temperature( -4.7, -1.9, -3.10379 ), + /* 27.12 */ Temperature( -1.9, -0.2, -0.679791 ), + /* 28.12 */ Temperature( -1.8, 0.5, -0.521875 ), + /* 29.12 */ Temperature( -2.2, 2.3, -0.430796 ), + /* 30.12 */ Temperature( 0.9, 5.2, 2.83437 ), + /* 31.12 */ Temperature( -1, 8.3, 2.27093 ) +}; diff --git a/ThirdParty/Qwt/examples/friedberg/friedberg2007.h b/ThirdParty/Qwt/examples/friedberg/friedberg2007.h new file mode 100644 index 0000000000..691f101418 --- /dev/null +++ b/ThirdParty/Qwt/examples/friedberg/friedberg2007.h @@ -0,0 +1,28 @@ +#ifndef _FRIEDBERG_2007_H_ +#define _FRIEDBERG_2007_H_ + +class Temperature +{ +public: + Temperature(): + minValue( 0.0 ), + maxValue( 0.0 ), + averageValue( 0.0 ) + { + } + + Temperature( double min, double max, double average ): + minValue( min ), + maxValue( max ), + averageValue( average ) + { + } + + double minValue; + double maxValue; + double averageValue; +}; + +extern Temperature friedberg2007[]; + +#endif diff --git a/ThirdParty/Qwt/examples/friedberg/main.cpp b/ThirdParty/Qwt/examples/friedberg/main.cpp new file mode 100644 index 0000000000..498c7144a8 --- /dev/null +++ b/ThirdParty/Qwt/examples/friedberg/main.cpp @@ -0,0 +1,55 @@ +#include +#include +#include +#include +#include +#include "plot.h" + +class MainWindow: public QMainWindow +{ +public: + MainWindow( QWidget * = NULL ); + +private: + Plot *d_plot; +}; + +MainWindow::MainWindow( QWidget *parent ): + QMainWindow( parent ) +{ + d_plot = new Plot( this ); + setCentralWidget( d_plot ); + + QToolBar *toolBar = new QToolBar( this ); + + QComboBox *typeBox = new QComboBox( toolBar ); + typeBox->addItem( "Bars" ); + typeBox->addItem( "Tube" ); + typeBox->setCurrentIndex( 1 ); + typeBox->setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ); + + QToolButton *btnExport = new QToolButton( toolBar ); + btnExport->setText( "Export" ); + btnExport->setToolButtonStyle( Qt::ToolButtonTextUnderIcon ); + connect( btnExport, SIGNAL( clicked() ), d_plot, SLOT( exportPlot() ) ); + + toolBar->addWidget( typeBox ); + toolBar->addWidget( btnExport ); + addToolBar( toolBar ); + + d_plot->setMode( typeBox->currentIndex() ); + connect( typeBox, SIGNAL( currentIndexChanged( int ) ), + d_plot, SLOT( setMode( int ) ) ); +} + +int main( int argc, char **argv ) +{ + QApplication a( argc, argv ); + + MainWindow w; + w.setObjectName( "MainWindow" ); + w.resize( 600, 400 ); + w.show(); + + return a.exec(); +} diff --git a/ThirdParty/Qwt/examples/friedberg/plot.cpp b/ThirdParty/Qwt/examples/friedberg/plot.cpp new file mode 100644 index 0000000000..09b13e0b57 --- /dev/null +++ b/ThirdParty/Qwt/examples/friedberg/plot.cpp @@ -0,0 +1,209 @@ +#include "plot.h" +#include "friedberg2007.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class Grid: public QwtPlotGrid +{ +public: + Grid() + { + enableXMin( true ); + setMajorPen( Qt::white, 0, Qt::DotLine ); + setMinorPen( Qt::gray, 0, Qt::DotLine ); + } + + virtual void updateScaleDiv( const QwtScaleDiv &xScaleDiv, + const QwtScaleDiv &yScaleDiv ) + { + QwtScaleDiv scaleDiv( xScaleDiv.lowerBound(), + xScaleDiv.upperBound() ); + + scaleDiv.setTicks( QwtScaleDiv::MinorTick, + xScaleDiv.ticks( QwtScaleDiv::MinorTick ) ); + scaleDiv.setTicks( QwtScaleDiv::MajorTick, + xScaleDiv.ticks( QwtScaleDiv::MediumTick ) ); + + QwtPlotGrid::updateScaleDiv( scaleDiv, yScaleDiv ); + } +}; + +class YearScaleDraw: public QwtScaleDraw +{ +public: + YearScaleDraw() + { + setTickLength( QwtScaleDiv::MajorTick, 0 ); + setTickLength( QwtScaleDiv::MinorTick, 0 ); + setTickLength( QwtScaleDiv::MediumTick, 6 ); + + setLabelRotation( -60.0 ); + setLabelAlignment( Qt::AlignLeft | Qt::AlignVCenter ); + + setSpacing( 15 ); + } + + virtual QwtText label( double value ) const + { + return QDate::longMonthName( int( value / 30 ) + 1 ); + } +}; + +Plot::Plot( QWidget *parent ): + QwtPlot( parent ) +{ + setObjectName( "FriedbergPlot" ); + setTitle( "Temperature of Friedberg/Germany" ); + + setAxisTitle( QwtPlot::xBottom, "2007" ); + setAxisScaleDiv( QwtPlot::xBottom, yearScaleDiv() ); + setAxisScaleDraw( QwtPlot::xBottom, new YearScaleDraw() ); + + setAxisTitle( QwtPlot::yLeft, + QString( "Temperature [%1C]" ).arg( QChar( 0x00B0 ) ) ); + + QwtPlotCanvas *canvas = new QwtPlotCanvas(); + canvas->setPalette( Qt::darkGray ); + canvas->setBorderRadius( 10 ); + + setCanvas( canvas ); + + // grid + QwtPlotGrid *grid = new Grid; + grid->attach( this ); + + insertLegend( new QwtLegend(), QwtPlot::RightLegend ); + + const int numDays = 365; + QVector averageData( numDays ); + QVector rangeData( numDays ); + + for ( int i = 0; i < numDays; i++ ) + { + const Temperature &t = friedberg2007[i]; + averageData[i] = QPointF( double( i ), t.averageValue ); + rangeData[i] = QwtIntervalSample( double( i ), + QwtInterval( t.minValue, t.maxValue ) ); + } + + insertCurve( "Average", averageData, Qt::black ); + insertErrorBars( "Range", rangeData, Qt::blue ); + + // LeftButton for the zooming + // MidButton for the panning + // RightButton: zoom out by 1 + // Ctrl+RighButton: zoom out to full size + + QwtPlotZoomer* zoomer = new QwtPlotZoomer( canvas ); + zoomer->setRubberBandPen( QColor( Qt::black ) ); + zoomer->setTrackerPen( QColor( Qt::black ) ); + zoomer->setMousePattern( QwtEventPattern::MouseSelect2, + Qt::RightButton, Qt::ControlModifier ); + zoomer->setMousePattern( QwtEventPattern::MouseSelect3, + Qt::RightButton ); + + QwtPlotPanner *panner = new QwtPlotPanner( canvas ); + panner->setMouseButton( Qt::MidButton ); +} + +QwtScaleDiv Plot::yearScaleDiv() const +{ + const int days[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; + + QList mediumTicks; + mediumTicks += 0.0; + for ( uint i = 0; i < sizeof( days ) / sizeof( days[0] ); i++ ) + mediumTicks += mediumTicks.last() + days[i]; + + QList minorTicks; + for ( int i = 1; i <= 365; i += 7 ) + minorTicks += i; + + QList majorTicks; + for ( int i = 0; i < 12; i++ ) + majorTicks += i * 30 + 15; + + QwtScaleDiv scaleDiv( mediumTicks.first(), mediumTicks.last() + 1, + minorTicks, mediumTicks, majorTicks ); + return scaleDiv; +} + +void Plot::insertCurve( const QString& title, + const QVector& samples, const QColor &color ) +{ + d_curve = new QwtPlotCurve( title ); + d_curve->setRenderHint( QwtPlotItem::RenderAntialiased ); + d_curve->setStyle( QwtPlotCurve::NoCurve ); + d_curve->setLegendAttribute( QwtPlotCurve::LegendShowSymbol ); + + QwtSymbol *symbol = new QwtSymbol( QwtSymbol::XCross ); + symbol->setSize( 4 ); + symbol->setPen( color ); + d_curve->setSymbol( symbol ); + + d_curve->setSamples( samples ); + d_curve->attach( this ); +} + +void Plot::insertErrorBars( + const QString &title, + const QVector& samples, + const QColor &color ) +{ + d_intervalCurve = new QwtPlotIntervalCurve( title ); + d_intervalCurve->setRenderHint( QwtPlotItem::RenderAntialiased ); + d_intervalCurve->setPen( Qt::white ); + + QColor bg( color ); + bg.setAlpha( 150 ); + d_intervalCurve->setBrush( QBrush( bg ) ); + d_intervalCurve->setStyle( QwtPlotIntervalCurve::Tube ); + + d_intervalCurve->setSamples( samples ); + d_intervalCurve->attach( this ); +} + +void Plot::setMode( int style ) +{ + if ( style == Tube ) + { + d_intervalCurve->setStyle( QwtPlotIntervalCurve::Tube ); + d_intervalCurve->setSymbol( NULL ); + d_intervalCurve->setRenderHint( QwtPlotItem::RenderAntialiased, true ); + } + else + { + d_intervalCurve->setStyle( QwtPlotIntervalCurve::NoCurve ); + + QColor c( d_intervalCurve->brush().color().rgb() ); // skip alpha + + QwtIntervalSymbol *errorBar = + new QwtIntervalSymbol( QwtIntervalSymbol::Bar ); + errorBar->setWidth( 8 ); // should be something even + errorBar->setPen( c ); + + d_intervalCurve->setSymbol( errorBar ); + d_intervalCurve->setRenderHint( QwtPlotItem::RenderAntialiased, false ); + } + + replot(); +} + +void Plot::exportPlot() +{ + QwtPlotRenderer renderer; + renderer.exportTo( this, "friedberg.pdf" ); +} diff --git a/ThirdParty/Qwt/examples/friedberg/plot.h b/ThirdParty/Qwt/examples/friedberg/plot.h new file mode 100644 index 0000000000..387655433a --- /dev/null +++ b/ThirdParty/Qwt/examples/friedberg/plot.h @@ -0,0 +1,43 @@ +#ifndef _PLOT_H_ +#define _PLOT_H_ + +#include +#include +#include + +class QwtPlotCurve; +class QwtPlotIntervalCurve; + +class Plot: public QwtPlot +{ + Q_OBJECT + +public: + enum Mode + { + Bars, + Tube + }; + + Plot( QWidget * = NULL ); + +public Q_SLOTS: + void setMode( int ); + void exportPlot(); + +private: + void insertCurve( const QString &title, + const QVector &, const QColor & ); + + void insertErrorBars( const QString &title, + const QVector &, + const QColor &color ); + + + QwtScaleDiv yearScaleDiv() const; + + QwtPlotIntervalCurve *d_intervalCurve; + QwtPlotCurve *d_curve; +}; + +#endif diff --git a/ThirdParty/Qwt/examples/itemeditor/editor.cpp b/ThirdParty/Qwt/examples/itemeditor/editor.cpp new file mode 100644 index 0000000000..fb45ad2b9c --- /dev/null +++ b/ThirdParty/Qwt/examples/itemeditor/editor.cpp @@ -0,0 +1,374 @@ +#include "editor.h" +#include +#include +#include +#include +#include + +class Overlay: public QwtWidgetOverlay +{ +public: + Overlay( QWidget *parent, Editor *editor ): + QwtWidgetOverlay( parent ), + d_editor( editor ) + { + switch( editor->mode() ) + { + case Editor::NoMask: + { + setMaskMode( QwtWidgetOverlay::NoMask ); + setRenderMode( QwtWidgetOverlay::AutoRenderMode ); + break; + } + case Editor::Mask: + { + setMaskMode( QwtWidgetOverlay::MaskHint ); + setRenderMode( QwtWidgetOverlay::AutoRenderMode ); + break; + } + case Editor::AlphaMask: + { + setMaskMode( QwtWidgetOverlay::AlphaMask ); + setRenderMode( QwtWidgetOverlay::AutoRenderMode ); + break; + } + case Editor::AlphaMaskRedraw: + { + setMaskMode( QwtWidgetOverlay::AlphaMask ); + setRenderMode( QwtWidgetOverlay::DrawOverlay ); + break; + } + case Editor::AlphaMaskCopyMask: + { + setMaskMode( QwtWidgetOverlay::AlphaMask ); + setRenderMode( QwtWidgetOverlay::CopyAlphaMask ); + break; + } + } + } + +protected: + virtual void drawOverlay( QPainter *painter ) const + { + d_editor->drawOverlay( painter ); + } + + virtual QRegion maskHint() const + { + return d_editor->maskHint(); + } + +private: + Editor *d_editor; +}; + +Editor::Editor( QwtPlot* plot ): + QObject( plot ), + d_isEnabled( false ), + d_overlay( NULL ), + d_mode( Mask ) +{ + setEnabled( true ); +} + + +Editor::~Editor() +{ + delete d_overlay; +} + +QwtPlot *Editor::plot() +{ + return qobject_cast( parent() ); +} + +const QwtPlot *Editor::plot() const +{ + return qobject_cast( parent() ); +} + +void Editor::setMode( Mode mode ) +{ + d_mode = mode; +} + +Editor::Mode Editor::mode() const +{ + return d_mode; +} + +void Editor::setEnabled( bool on ) +{ + if ( on == d_isEnabled ) + return; + + QwtPlot *plot = qobject_cast( parent() ); + if ( plot ) + { + d_isEnabled = on; + + if ( on ) + { + plot->canvas()->installEventFilter( this ); + } + else + { + plot->canvas()->removeEventFilter( this ); + + delete d_overlay; + d_overlay = NULL; + } + } +} + +bool Editor::isEnabled() const +{ + return d_isEnabled; +} + +bool Editor::eventFilter( QObject* object, QEvent* event ) +{ + QwtPlot *plot = qobject_cast( parent() ); + if ( plot && object == plot->canvas() ) + { + switch( event->type() ) + { + case QEvent::MouseButtonPress: + { + const QMouseEvent* mouseEvent = + dynamic_cast( event ); + + if ( d_overlay == NULL && + mouseEvent->button() == Qt::LeftButton ) + { + const bool accepted = pressed( mouseEvent->pos() ); + if ( accepted ) + { + d_overlay = new Overlay( plot->canvas(), this ); + + d_overlay->updateOverlay(); + d_overlay->show(); + } + } + + break; + } + case QEvent::MouseMove: + { + if ( d_overlay ) + { + const QMouseEvent* mouseEvent = + dynamic_cast< QMouseEvent* >( event ); + + const bool accepted = moved( mouseEvent->pos() ); + if ( accepted ) + d_overlay->updateOverlay(); + } + + break; + } + case QEvent::MouseButtonRelease: + { + const QMouseEvent* mouseEvent = + static_cast( event ); + + if ( d_overlay && mouseEvent->button() == Qt::LeftButton ) + { + released( mouseEvent->pos() ); + + delete d_overlay; + d_overlay = NULL; + } + + break; + } + default: + break; + } + + return false; + } + + return QObject::eventFilter( object, event ); +} + +bool Editor::pressed( const QPoint& pos ) +{ + d_editedItem = itemAt( pos ); + if ( d_editedItem ) + { + d_currentPos = pos; + setItemVisible( d_editedItem, false ); + + return true; + } + + return false; // don't accept the position +} + +bool Editor::moved( const QPoint& pos ) +{ + if ( plot() == NULL ) + return false; + + const QwtScaleMap xMap = plot()->canvasMap( d_editedItem->xAxis() ); + const QwtScaleMap yMap = plot()->canvasMap( d_editedItem->yAxis() ); + + const QPointF p1 = QwtScaleMap::invTransform( xMap, yMap, d_currentPos ); + const QPointF p2 = QwtScaleMap::invTransform( xMap, yMap, pos ); + +#if QT_VERSION >= 0x040600 + const QPainterPath shape = d_editedItem->shape().translated( p2 - p1 ); +#else + const double dx = p2.x() - p1.x(); + const double dy = p2.y() - p1.y(); + + QPainterPath shape = d_editedItem->shape(); + for ( int i = 0; i < shape.elementCount(); i++ ) + { + const QPainterPath::Element &el = shape.elementAt( i ); + shape.setElementPositionAt( i, el.x + dx, el.y + dy ); + } +#endif + + d_editedItem->setShape( shape ); + d_currentPos = pos; + + return true; +} + +void Editor::released( const QPoint& pos ) +{ + Q_UNUSED( pos ); + + if ( d_editedItem ) + { + raiseItem( d_editedItem ); + setItemVisible( d_editedItem, true ); + } +} + +QwtPlotShapeItem* Editor::itemAt( const QPoint& pos ) const +{ + const QwtPlot *plot = this->plot(); + if ( plot == NULL ) + return NULL; + + // translate pos into the plot coordinates + double coords[ QwtPlot::axisCnt ]; + coords[ QwtPlot::xBottom ] = + plot->canvasMap( QwtPlot::xBottom ).invTransform( pos.x() ); + coords[ QwtPlot::xTop ] = + plot->canvasMap( QwtPlot::xTop ).invTransform( pos.x() ); + coords[ QwtPlot::yLeft ] = + plot->canvasMap( QwtPlot::yLeft ).invTransform( pos.y() ); + coords[ QwtPlot::yRight ] = + plot->canvasMap( QwtPlot::yRight ).invTransform( pos.y() ); + + QwtPlotItemList items = plot->itemList(); + for ( int i = items.size() - 1; i >= 0; i-- ) + { + QwtPlotItem *item = items[ i ]; + if ( item->isVisible() && + item->rtti() == QwtPlotItem::Rtti_PlotShape ) + { + QwtPlotShapeItem *shapeItem = static_cast( item ); + const QPointF p( coords[ item->xAxis() ], coords[ item->yAxis() ] ); + + if ( shapeItem->boundingRect().contains( p ) + && shapeItem->shape().contains( p ) ) + { + return shapeItem; + } + } + } + + return NULL; +} + +QRegion Editor::maskHint() const +{ + return maskHint( d_editedItem ); +} + +QRegion Editor::maskHint( QwtPlotShapeItem *shapeItem ) const +{ + const QwtPlot *plot = this->plot(); + if ( plot == NULL || shapeItem == NULL ) + return QRegion(); + + const QwtScaleMap xMap = plot->canvasMap( shapeItem->xAxis() ); + const QwtScaleMap yMap = plot->canvasMap( shapeItem->yAxis() ); + + QRect rect = QwtScaleMap::transform( xMap, yMap, + shapeItem->shape().boundingRect() ).toRect(); + + const int m = 5; // some margin for the pen + return rect.adjusted( -m, -m, m, m ); +} + +void Editor::drawOverlay( QPainter* painter ) const +{ + const QwtPlot *plot = this->plot(); + if ( plot == NULL || d_editedItem == NULL ) + return; + + const QwtScaleMap xMap = plot->canvasMap( d_editedItem->xAxis() ); + const QwtScaleMap yMap = plot->canvasMap( d_editedItem->yAxis() ); + + painter->setRenderHint( QPainter::Antialiasing, + d_editedItem->testRenderHint( QwtPlotItem::RenderAntialiased ) ); + d_editedItem->draw( painter, xMap, yMap, + plot->canvas()->contentsRect() ); +} + +void Editor::raiseItem( QwtPlotShapeItem *shapeItem ) +{ + const QwtPlot *plot = this->plot(); + if ( plot == NULL || shapeItem == NULL ) + return; + + const QwtPlotItemList items = plot->itemList(); + for ( int i = items.size() - 1; i >= 0; i-- ) + { + QwtPlotItem *item = items[ i ]; + if ( shapeItem == item ) + return; + + if ( item->isVisible() && + item->rtti() == QwtPlotItem::Rtti_PlotShape ) + { + shapeItem->setZ( item->z() + 1 ); + return; + } + } +} + +void Editor::setItemVisible( QwtPlotShapeItem *item, bool on ) +{ + if ( plot() == NULL || item == NULL || item->isVisible() == on ) + return; + + const bool doAutoReplot = plot()->autoReplot(); + plot()->setAutoReplot( false ); + + item->setVisible( on ); + + plot()->setAutoReplot( doAutoReplot ); + + /* + Avoid replot with a full repaint of the canvas. + For special combinations - f.e. using the + raster paint engine on a remote display - + this makes a difference. + */ + + QwtPlotCanvas *canvas = + qobject_cast( plot()->canvas() ); + if ( canvas ) + canvas->invalidateBackingStore(); + + plot()->canvas()->update( maskHint( item ) ); + +} + diff --git a/ThirdParty/Qwt/examples/itemeditor/editor.h b/ThirdParty/Qwt/examples/itemeditor/editor.h new file mode 100644 index 0000000000..7f8c8965a7 --- /dev/null +++ b/ThirdParty/Qwt/examples/itemeditor/editor.h @@ -0,0 +1,66 @@ +#ifndef _EDITOR_H_ +#define _EDITOR_H_ + +#include +#include +#include +#include + +class QwtPlot; +class QwtPlotShapeItem; +class QPainter; +class QPoint; + +class Editor: public QObject +{ + Q_OBJECT + +public: + enum Mode + { + NoMask, + Mask, + AlphaMask, + AlphaMaskRedraw, + AlphaMaskCopyMask + }; + + Editor( QwtPlot * ); + virtual ~Editor(); + + const QwtPlot *plot() const; + QwtPlot *plot(); + + virtual void setEnabled( bool on ); + bool isEnabled() const; + + void drawOverlay( QPainter * ) const; + QRegion maskHint() const; + + virtual bool eventFilter( QObject *, QEvent *); + + void setMode( Mode mode ); + Mode mode() const; + +private: + bool pressed( const QPoint & ); + bool moved( const QPoint & ); + void released( const QPoint & ); + + QwtPlotShapeItem* itemAt( const QPoint& ) const; + void raiseItem( QwtPlotShapeItem * ); + + QRegion maskHint( QwtPlotShapeItem * ) const; + void setItemVisible( QwtPlotShapeItem *item, bool on ); + + bool d_isEnabled; + QPointer d_overlay; + + // Mouse positions + QPointF d_currentPos; + QwtPlotShapeItem* d_editedItem; + + Mode d_mode; +}; + +#endif diff --git a/ThirdParty/Qwt/examples/itemeditor/itemeditor.pro b/ThirdParty/Qwt/examples/itemeditor/itemeditor.pro new file mode 100644 index 0000000000..7342091159 --- /dev/null +++ b/ThirdParty/Qwt/examples/itemeditor/itemeditor.pro @@ -0,0 +1,24 @@ +################################################################ +# Qwt Widget Library +# Copyright (C) 1997 Josef Wilgen +# Copyright (C) 2002 Uwe Rathmann +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the Qwt License, Version 1.0 +################################################################ + +include( $${PWD}/../examples.pri ) + +TARGET = itemeditor + +HEADERS = \ + editor.h \ + shapefactory.h \ + plot.h + +SOURCES = \ + editor.cpp \ + shapefactory.cpp \ + plot.cpp \ + main.cpp + diff --git a/ThirdParty/Qwt/examples/itemeditor/main.cpp b/ThirdParty/Qwt/examples/itemeditor/main.cpp new file mode 100644 index 0000000000..d66fc6358d --- /dev/null +++ b/ThirdParty/Qwt/examples/itemeditor/main.cpp @@ -0,0 +1,54 @@ +#include "plot.h" +#include +#include +#include +#include +#include + +class MainWindow: public QMainWindow +{ +public: + MainWindow( QWidget * = NULL ); +}; + +MainWindow::MainWindow( QWidget *parent ): + QMainWindow( parent ) +{ + Plot *plot = new Plot( this ); + setCentralWidget( plot ); + + QToolBar *toolBar = new QToolBar( this ); + + QComboBox *modeBox = new QComboBox( toolBar ); + modeBox->addItem( "No Mask" ); + modeBox->addItem( "Mask" ); + modeBox->addItem( "Alpha Mask" ); + modeBox->addItem( "Alpha Mask/Redraw" ); + modeBox->addItem( "Alpha Mask/Copy Mask" ); + modeBox->setCurrentIndex( 1 ); + modeBox->setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ); + + connect( modeBox, SIGNAL( currentIndexChanged( int ) ), + plot, SLOT( setMode( int ) ) ); + + QToolButton *btnExport = new QToolButton( toolBar ); + btnExport->setText( "Export" ); + btnExport->setToolButtonStyle( Qt::ToolButtonTextUnderIcon ); + connect( btnExport, SIGNAL( clicked() ), plot, SLOT( exportPlot() ) ); + + toolBar->addWidget( modeBox ); + toolBar->addWidget( btnExport ); + addToolBar( toolBar ); + +} + +int main( int argc, char **argv ) +{ + QApplication app( argc, argv ); + + MainWindow window; + window.resize( 600, 400 ); + window.show(); + + return app.exec(); +} diff --git a/ThirdParty/Qwt/examples/itemeditor/plot.cpp b/ThirdParty/Qwt/examples/itemeditor/plot.cpp new file mode 100644 index 0000000000..53c18fa4d9 --- /dev/null +++ b/ThirdParty/Qwt/examples/itemeditor/plot.cpp @@ -0,0 +1,120 @@ +#include "plot.h" +#include "editor.h" +#include +#include +#include +#include +#include + +class Legend: public QwtLegend +{ +protected: + virtual QWidget *createWidget( const QwtLegendData &data ) const + { + QWidget *w = QwtLegend::createWidget( data ); + if ( w ) + { + w->setStyleSheet( + "border-radius: 5px;" + "padding: 2px;" + "background: LemonChiffon;" + ); + } + + return w; + } +}; + +Plot::Plot( QWidget *parent ): + QwtPlot( parent ) +{ + setAutoReplot( false ); + + setTitle( "Movable Items" ); + + const int margin = 5; + setContentsMargins( margin, margin, margin, margin ); + + setAutoFillBackground( true ); + setPalette( QColor( "DimGray" ).lighter( 110 ) ); + + QwtPlotCanvas *canvas = new QwtPlotCanvas(); +#if 0 + // a gradient making a replot slow on X11 + canvas->setStyleSheet( + "border: 2px solid Black;" + "border-radius: 15px;" + "background-color: qlineargradient( x1: 0, y1: 0, x2: 0, y2: 1," + "stop: 0 LemonChiffon, stop: 0.5 PaleGoldenrod, stop: 1 LemonChiffon );" + ); +#else + canvas->setStyleSheet( + "border: 2px inset DimGray;" + "border-radius: 15px;" + "background: LemonChiffon;" + ); +#endif + + setCanvas( canvas ); + insertLegend( new Legend(), QwtPlot::RightLegend ); + + populate(); + + updateAxes(); + for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ ) + setAxisAutoScale( axis, false ); + + d_editor = new Editor( this ); + ( void ) new QwtPlotMagnifier( canvas ); +} + +void Plot::populate() +{ + addShape( "Rectangle", ShapeFactory::Rect, "RoyalBlue", + QPointF( 30.0, 50.0 ), QSizeF( 40.0, 50.0 ) ); + addShape( "Ellipse", ShapeFactory::Ellipse, "IndianRed", + QPointF( 80.0, 130.0 ), QSizeF( 50.0, 40.0 ) ); + addShape( "Ring", ShapeFactory::Ring, "DarkOliveGreen", + QPointF( 30.0, 165.0 ), QSizeF( 40.0, 40.0 ) ); + addShape( "Triangle", ShapeFactory::Triangle, "SandyBrown", + QPointF( 165.0, 165.0 ), QSizeF( 60.0, 40.0 ) ); + addShape( "Star", ShapeFactory::Star, "DarkViolet", + QPointF( 165.0, 50.0 ), QSizeF( 40.0, 50.0 ) ); + addShape( "Hexagon", ShapeFactory::Hexagon, "DarkSlateGray", + QPointF( 120.0, 70.0 ), QSizeF( 50.0, 50.0 ) ); + +} + +void Plot::addShape( const QString &title, + ShapeFactory::Shape shape, const QColor &color, + const QPointF &pos, const QSizeF &size ) +{ + QwtPlotShapeItem *item = new QwtPlotShapeItem( title ); + item->setItemAttribute( QwtPlotItem::Legend, true ); + item->setLegendMode( QwtPlotShapeItem::LegendShape ); + item->setLegendIconSize( QSize( 20, 20 ) ); + item->setRenderHint( QwtPlotItem::RenderAntialiased, true ); + item->setShape( ShapeFactory::path( shape, pos, size ) ); + + QColor fillColor = color; + fillColor.setAlpha( 200 ); + + QPen pen( color, 3 ); + pen.setJoinStyle( Qt::MiterJoin ); + item->setPen( pen ); + item->setBrush( fillColor ); + + item->attach( this ); +} + +void Plot::exportPlot() +{ + QwtPlotRenderer renderer; + renderer.exportTo( this, "shapes.pdf" ); +} + +void Plot::setMode( int mode ) +{ + d_editor->setMode( static_cast( mode ) ); +} + diff --git a/ThirdParty/Qwt/examples/itemeditor/plot.h b/ThirdParty/Qwt/examples/itemeditor/plot.h new file mode 100644 index 0000000000..1652a6466a --- /dev/null +++ b/ThirdParty/Qwt/examples/itemeditor/plot.h @@ -0,0 +1,33 @@ +#ifndef _PLOT_H +#define _PLOT_H + +#include +#include "shapefactory.h" + +class QColor; +class QSizeF; +class QPointF; +class Editor; + +class Plot: public QwtPlot +{ + Q_OBJECT + +public: + Plot( QWidget *parent = NULL ); + +public Q_SLOTS: + void exportPlot(); + void setMode( int ); + +private: + void populate(); + + void addShape( const QString &title, + ShapeFactory::Shape, const QColor &, + const QPointF &, const QSizeF & ); + + Editor *d_editor; +}; + +#endif diff --git a/ThirdParty/Qwt/examples/itemeditor/shapefactory.cpp b/ThirdParty/Qwt/examples/itemeditor/shapefactory.cpp new file mode 100644 index 0000000000..2a9b01d468 --- /dev/null +++ b/ThirdParty/Qwt/examples/itemeditor/shapefactory.cpp @@ -0,0 +1,113 @@ +#include "shapefactory.h" + +QPainterPath ShapeFactory::path( Shape shape, + const QPointF &pos, const QSizeF &size ) +{ + QRectF rect; + rect.setSize( size ); + rect.moveCenter( pos ); + + QPainterPath path; + + switch( shape ) + { + case Rect: + { + path.addRect( rect ); + break; + } + case Triangle: + { + QPolygonF triangle; + triangle += rect.bottomLeft(); + triangle += QPointF( rect.center().x(), rect.top() ); + triangle += rect.bottomRight(); + + path.addPolygon( triangle ); + break; + } + case Ellipse: + { + path.addEllipse( rect ); + break; + } + case Ring: + { + path.addEllipse( rect ); + + const double w = 0.25 * rect.width(); + path.addEllipse( rect.adjusted( w, w, -w, -w ) ); + break; + } + case Star: + { + const double cos30 = 0.866025; + + const double dy = 0.25 * size.height(); + const double dx = 0.5 * size.width() * cos30 / 3.0; + + double x1 = pos.x() - 3 * dx; + double y1 = pos.y() - 2 * dy; + + const double x2 = x1 + 1 * dx; + const double x3 = x1 + 2 * dx; + const double x4 = x1 + 3 * dx; + const double x5 = x1 + 4 * dx; + const double x6 = x1 + 5 * dx; + const double x7 = x1 + 6 * dx; + + const double y2 = y1 + 1 * dy; + const double y3 = y1 + 2 * dy; + const double y4 = y1 + 3 * dy; + const double y5 = y1 + 4 * dy; + + QPolygonF star; + star += QPointF( x4, y1 ); + star += QPointF( x5, y2 ); + star += QPointF( x7, y2 ); + star += QPointF( x6, y3 ); + star += QPointF( x7, y4 ); + star += QPointF( x5, y4 ); + star += QPointF( x4, y5 ); + star += QPointF( x3, y4 ); + star += QPointF( x1, y4 ); + star += QPointF( x2, y3 ); + star += QPointF( x1, y2 ); + star += QPointF( x3, y2 ); + + path.addPolygon( star ); + break; + } + case Hexagon: + { + const double cos30 = 0.866025; + + const double dx = 0.5 * size.width() - cos30; + const double dy = 0.25 * size.height(); + + double x1 = pos.x() - dx; + double y1 = pos.y() - 2 * dy; + + const double x2 = x1 + 1 * dx; + const double x3 = x1 + 2 * dx; + + const double y2 = y1 + 1 * dy; + const double y3 = y1 + 3 * dy; + const double y4 = y1 + 4 * dy; + + QPolygonF hexagon; + hexagon += QPointF( x2, y1 ); + hexagon += QPointF( x3, y2 ); + hexagon += QPointF( x3, y3 ); + hexagon += QPointF( x2, y4 ); + hexagon += QPointF( x1, y3 ); + hexagon += QPointF( x1, y2 ); + + path.addPolygon( hexagon ); + break; + } + }; + + path.closeSubpath(); + return path; +} diff --git a/ThirdParty/Qwt/examples/itemeditor/shapefactory.h b/ThirdParty/Qwt/examples/itemeditor/shapefactory.h new file mode 100644 index 0000000000..3dcd725357 --- /dev/null +++ b/ThirdParty/Qwt/examples/itemeditor/shapefactory.h @@ -0,0 +1,21 @@ +#ifndef _SHAPE_FACTORY_H_ +#define _SHAPE_FACTORY_H_ + +#include + +namespace ShapeFactory +{ + enum Shape + { + Rect, + Triangle, + Ellipse, + Ring, + Star, + Hexagon + }; + + QPainterPath path( Shape, const QPointF &, const QSizeF & ); +}; + +#endif diff --git a/ThirdParty/Qwt/examples/legends/legends.pro b/ThirdParty/Qwt/examples/legends/legends.pro new file mode 100644 index 0000000000..a8e9e7821e --- /dev/null +++ b/ThirdParty/Qwt/examples/legends/legends.pro @@ -0,0 +1,24 @@ +################################################################ +# Qwt Widget Library +# Copyright (C) 1997 Josef Wilgen +# Copyright (C) 2002 Uwe Rathmann +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the Qwt License, Version 1.0 +################################################################ + +include( $${PWD}/../examples.pri ) + +TARGET = legends + +HEADERS = \ + mainwindow.h \ + panel.h \ + settings.h \ + plot.h + +SOURCES = \ + mainwindow.cpp \ + panel.cpp \ + plot.cpp \ + main.cpp diff --git a/ThirdParty/Qwt/examples/legends/main.cpp b/ThirdParty/Qwt/examples/legends/main.cpp new file mode 100644 index 0000000000..91b30b5a17 --- /dev/null +++ b/ThirdParty/Qwt/examples/legends/main.cpp @@ -0,0 +1,14 @@ +#include +#include "mainwindow.h" + +int main ( int argc, char **argv ) +{ + QApplication a( argc, argv ); + a.setStyle( "Windows" ); + + MainWindow w; + w.resize( 700, 500 ); + w.show(); + + return a.exec(); +} diff --git a/ThirdParty/Qwt/examples/legends/mainwindow.cpp b/ThirdParty/Qwt/examples/legends/mainwindow.cpp new file mode 100644 index 0000000000..200d8e4c76 --- /dev/null +++ b/ThirdParty/Qwt/examples/legends/mainwindow.cpp @@ -0,0 +1,61 @@ +#include +#include +#include +#include +#include +#include "plot.h" +#include "panel.h" +#include "mainwindow.h" + +MainWindow::MainWindow( QWidget *parent ): + QMainWindow( parent ) +{ + d_plot = new Plot(); + + Settings settings; + settings.legend.isEnabled = true; + settings.legend.position = QwtPlot::BottomLegend; + + settings.legendItem.isEnabled = false; + settings.legendItem.numColumns = 1; + settings.legendItem.alignment = Qt::AlignRight | Qt::AlignVCenter; + settings.legendItem.backgroundMode = 0; + settings.legendItem.size = d_plot->canvas()->font().pointSize(); + + settings.curve.numCurves = 4; + settings.curve.title = "Curve"; + + d_panel = new Panel(); + d_panel->setSettings( settings ); + + QWidget *box = new QWidget( this ); + QHBoxLayout *layout = new QHBoxLayout( box ); + layout->addWidget( d_plot, 10 ); + layout->addWidget( d_panel ); + + setCentralWidget( box ); + + QToolBar *toolBar = new QToolBar( this ); + + QToolButton *btnExport = new QToolButton( toolBar ); + btnExport->setText( "Export" ); + toolBar->addWidget( btnExport ); + + addToolBar( toolBar ); + + updatePlot(); + + connect( d_panel, SIGNAL( edited() ), SLOT( updatePlot() ) ); + connect( btnExport, SIGNAL( clicked() ), SLOT( exportPlot() ) ); +} + +void MainWindow::updatePlot() +{ + d_plot->applySettings( d_panel->settings() ); +} + +void MainWindow::exportPlot() +{ + QwtPlotRenderer renderer; + renderer.exportTo( d_plot, "legends.pdf" ); +} diff --git a/ThirdParty/Qwt/examples/legends/mainwindow.h b/ThirdParty/Qwt/examples/legends/mainwindow.h new file mode 100644 index 0000000000..26e36a00b6 --- /dev/null +++ b/ThirdParty/Qwt/examples/legends/mainwindow.h @@ -0,0 +1,20 @@ +#include + +class Plot; +class Panel; + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + MainWindow( QWidget *parent = 0 ); + +private Q_SLOTS: + void updatePlot(); + void exportPlot(); + +private: + Plot *d_plot; + Panel *d_panel; +}; diff --git a/ThirdParty/Qwt/examples/legends/panel.cpp b/ThirdParty/Qwt/examples/legends/panel.cpp new file mode 100644 index 0000000000..256fc5b8a8 --- /dev/null +++ b/ThirdParty/Qwt/examples/legends/panel.cpp @@ -0,0 +1,216 @@ +#include "panel.h" +#include "settings.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +Panel::Panel( QWidget *parent ): + QWidget( parent ) +{ + // create widgets + + d_legend.checkBox = new QCheckBox( "Enabled" ); + + d_legend.positionBox = new QComboBox(); + d_legend.positionBox->addItem( "Left", QwtPlot::LeftLegend ); + d_legend.positionBox->addItem( "Right", QwtPlot::RightLegend ); + d_legend.positionBox->addItem( "Bottom", QwtPlot::BottomLegend ); + d_legend.positionBox->addItem( "Top", QwtPlot::TopLegend ); + d_legend.positionBox->addItem( "External", QwtPlot::TopLegend + 1 ); + + d_legendItem.checkBox = new QCheckBox( "Enabled" ); + + d_legendItem.numColumnsBox = new QSpinBox(); + d_legendItem.numColumnsBox->setRange( 0, 10 ); + d_legendItem.numColumnsBox->setSpecialValueText( "Unlimited" ); + + d_legendItem.hAlignmentBox = new QComboBox(); + d_legendItem.hAlignmentBox->addItem( "Left", Qt::AlignLeft ); + d_legendItem.hAlignmentBox->addItem( "Centered", Qt::AlignHCenter ); + d_legendItem.hAlignmentBox->addItem( "Right", Qt::AlignRight ); + + d_legendItem.vAlignmentBox = new QComboBox(); + d_legendItem.vAlignmentBox->addItem( "Top", Qt::AlignTop ); + d_legendItem.vAlignmentBox->addItem( "Centered", Qt::AlignVCenter ); + d_legendItem.vAlignmentBox->addItem( "Bottom", Qt::AlignBottom ); + + d_legendItem.backgroundBox = new QComboBox(); + d_legendItem.backgroundBox->addItem( "Legend", + QwtPlotLegendItem::LegendBackground ); + d_legendItem.backgroundBox->addItem( "Items", + QwtPlotLegendItem::ItemBackground ); + + d_legendItem.sizeBox = new QSpinBox(); + d_legendItem.sizeBox->setRange( 8, 22 ); + + d_curve.numCurves = new QSpinBox(); + d_curve.numCurves->setRange( 0, 99 ); + + d_curve.title = new QLineEdit(); + + // layout + + QGroupBox *legendBox = new QGroupBox( "Legend" ); + QGridLayout *legendBoxLayout = new QGridLayout( legendBox ); + + int row = 0; + legendBoxLayout->addWidget( d_legend.checkBox, row, 0, 1, -1 ); + + row++; + legendBoxLayout->addWidget( new QLabel( "Position" ), row, 0 ); + legendBoxLayout->addWidget( d_legend.positionBox, row, 1 ); + + + QGroupBox *legendItemBox = new QGroupBox( "Legend Item" ); + QGridLayout *legendItemBoxLayout = new QGridLayout( legendItemBox ); + + row = 0; + legendItemBoxLayout->addWidget( d_legendItem.checkBox, row, 0, 1, -1 ); + + row++; + legendItemBoxLayout->addWidget( new QLabel( "Columns" ), row, 0 ); + legendItemBoxLayout->addWidget( d_legendItem.numColumnsBox, row, 1 ); + + row++; + legendItemBoxLayout->addWidget( new QLabel( "Horizontal" ), row, 0 ); + legendItemBoxLayout->addWidget( d_legendItem.hAlignmentBox, row, 1 ); + + row++; + legendItemBoxLayout->addWidget( new QLabel( "Vertical" ), row, 0 ); + legendItemBoxLayout->addWidget( d_legendItem.vAlignmentBox, row, 1 ); + + row++; + legendItemBoxLayout->addWidget( new QLabel( "Background" ), row, 0 ); + legendItemBoxLayout->addWidget( d_legendItem.backgroundBox, row, 1 ); + + row++; + legendItemBoxLayout->addWidget( new QLabel( "Size" ), row, 0 ); + legendItemBoxLayout->addWidget( d_legendItem.sizeBox, row, 1 ); + + QGroupBox *curveBox = new QGroupBox( "Curves" ); + QGridLayout *curveBoxLayout = new QGridLayout( curveBox ); + + row = 0; + curveBoxLayout->addWidget( new QLabel( "Number" ), row, 0 ); + curveBoxLayout->addWidget( d_curve.numCurves, row, 1 ); + + row++; + curveBoxLayout->addWidget( new QLabel( "Title" ), row, 0 ); + curveBoxLayout->addWidget( d_curve.title, row, 1 ); + + QVBoxLayout *layout = new QVBoxLayout( this ); + layout->addWidget( legendBox ); + layout->addWidget( legendItemBox ); + layout->addWidget( curveBox ); + layout->addStretch( 10 ); + + connect( d_legend.checkBox, + SIGNAL( stateChanged( int ) ), SIGNAL( edited() ) ); + connect( d_legend.positionBox, + SIGNAL( currentIndexChanged( int ) ), SIGNAL( edited() ) ); + + connect( d_legendItem.checkBox, + SIGNAL( stateChanged( int ) ), SIGNAL( edited() ) ); + connect( d_legendItem.numColumnsBox, + SIGNAL( valueChanged( int ) ), SIGNAL( edited() ) ); + connect( d_legendItem.hAlignmentBox, + SIGNAL( currentIndexChanged( int ) ), SIGNAL( edited() ) ); + connect( d_legendItem.vAlignmentBox, + SIGNAL( currentIndexChanged( int ) ), SIGNAL( edited() ) ); + connect( d_legendItem.backgroundBox, + SIGNAL( currentIndexChanged( int ) ), SIGNAL( edited() ) ); + connect( d_curve.numCurves, + SIGNAL( valueChanged( int ) ), SIGNAL( edited() ) ); + connect( d_legendItem.sizeBox, + SIGNAL( valueChanged( int ) ), SIGNAL( edited() ) ); + connect( d_curve.title, + SIGNAL( textEdited( const QString & ) ), SIGNAL( edited() ) ); +} + +void Panel::setSettings( const Settings &settings) +{ + blockSignals( true ); + + d_legend.checkBox->setCheckState( + settings.legend.isEnabled ? Qt::Checked : Qt::Unchecked ); + d_legend.positionBox->setCurrentIndex( settings.legend.position ); + + d_legendItem.checkBox->setCheckState( + settings.legendItem.isEnabled ? Qt::Checked : Qt::Unchecked ); + + d_legendItem.numColumnsBox->setValue( settings.legendItem.numColumns ); + + int align = settings.legendItem.alignment; + + if ( align & Qt::AlignLeft ) + d_legendItem.hAlignmentBox->setCurrentIndex( 0 ); + else if ( align & Qt::AlignRight ) + d_legendItem.hAlignmentBox->setCurrentIndex( 2 ); + else + d_legendItem.hAlignmentBox->setCurrentIndex( 1 ); + + if ( align & Qt::AlignTop ) + d_legendItem.vAlignmentBox->setCurrentIndex( 0 ); + else if ( align & Qt::AlignBottom ) + d_legendItem.vAlignmentBox->setCurrentIndex( 2 ); + else + d_legendItem.vAlignmentBox->setCurrentIndex( 1 ); + + d_legendItem.backgroundBox->setCurrentIndex( + settings.legendItem.backgroundMode ); + + d_legendItem.sizeBox->setValue( settings.legendItem.size ); + + d_curve.numCurves->setValue( settings.curve.numCurves ); + d_curve.title->setText( settings.curve.title ); + + blockSignals( false ); +} + +Settings Panel::settings() const +{ + Settings s; + + s.legend.isEnabled = + d_legend.checkBox->checkState() == Qt::Checked; + s.legend.position = d_legend.positionBox->currentIndex(); + + s.legendItem.isEnabled = + d_legendItem.checkBox->checkState() == Qt::Checked; + s.legendItem.numColumns = d_legendItem.numColumnsBox->value(); + + int align = 0; + + int hIndex = d_legendItem.hAlignmentBox->currentIndex(); + if ( hIndex == 0 ) + align |= Qt::AlignLeft; + else if ( hIndex == 2 ) + align |= Qt::AlignRight; + else + align |= Qt::AlignHCenter; + + int vIndex = d_legendItem.vAlignmentBox->currentIndex(); + if ( vIndex == 0 ) + align |= Qt::AlignTop; + else if ( vIndex == 2 ) + align |= Qt::AlignBottom; + else + align |= Qt::AlignVCenter; + + s.legendItem.alignment = align; + + s.legendItem.backgroundMode = + d_legendItem.backgroundBox->currentIndex(); + s.legendItem.size = d_legendItem.sizeBox->value(); + + s.curve.numCurves = d_curve.numCurves->value(); + s.curve.title = d_curve.title->text(); + + return s; +} diff --git a/ThirdParty/Qwt/examples/legends/panel.h b/ThirdParty/Qwt/examples/legends/panel.h new file mode 100644 index 0000000000..570f4943f1 --- /dev/null +++ b/ThirdParty/Qwt/examples/legends/panel.h @@ -0,0 +1,52 @@ +#ifndef _PANEL_ +#define _PANEL_ + +#include "settings.h" +#include + +class QCheckBox; +class QComboBox; +class QSpinBox; +class QLineEdit; + +class Panel: public QWidget +{ + Q_OBJECT + +public: + Panel( QWidget *parent = NULL ); + + void setSettings( const Settings &); + Settings settings() const; + +Q_SIGNALS: + void edited(); + +private: + struct + { + QCheckBox *checkBox; + QComboBox *positionBox; + + } d_legend; + + struct + { + QCheckBox *checkBox; + QSpinBox *numColumnsBox; + QComboBox *hAlignmentBox; + QComboBox *vAlignmentBox; + QComboBox *backgroundBox; + QSpinBox *sizeBox; + + } d_legendItem; + + struct + { + QSpinBox *numCurves; + QLineEdit *title; + + } d_curve; +}; + +#endif diff --git a/ThirdParty/Qwt/examples/legends/plot.cpp b/ThirdParty/Qwt/examples/legends/plot.cpp new file mode 100644 index 0000000000..1485f53398 --- /dev/null +++ b/ThirdParty/Qwt/examples/legends/plot.cpp @@ -0,0 +1,263 @@ +#include "plot.h" +#include "settings.h" +#include +#include +#include +#include +#include +#include + +class LegendItem: public QwtPlotLegendItem +{ +public: + LegendItem() + { + setRenderHint( QwtPlotItem::RenderAntialiased ); + + QColor color( Qt::white ); + + setTextPen( color ); +#if 1 + setBorderPen( color ); + + QColor c( Qt::gray ); + c.setAlpha( 200 ); + + setBackgroundBrush( c ); +#endif + } +}; + +class Curve: public QwtPlotCurve +{ +public: + Curve( int index ): + d_index( index ) + { + setRenderHint( QwtPlotItem::RenderAntialiased ); + initData(); + } + + void setCurveTitle( const QString &title ) + { + QString txt("%1 %2"); + setTitle( QString( "%1 %2" ).arg( title ).arg( d_index ) ); + } + + void initData() + { + QVector points; + + double y = qrand() % 1000; + + for ( double x = 0.0; x <= 1000.0; x += 100.0 ) + { + double off = qrand() % 200 - 100; + if ( y + off > 980.0 || y + off < 20.0 ) + off = -off; + + y += off; + + points += QPointF( x, y ); + } + + setSamples( points ); + } + +private: + const int d_index; +}; + +Plot::Plot( QWidget *parent ): + QwtPlot( parent ), + d_externalLegend( NULL ), + d_legendItem( NULL ), + d_isDirty( false ) +{ + QwtPlotCanvas *canvas = new QwtPlotCanvas(); + canvas->setFocusIndicator( QwtPlotCanvas::CanvasFocusIndicator ); + canvas->setFocusPolicy( Qt::StrongFocus ); + canvas->setPalette( Qt::black ); + setCanvas( canvas ); + + setAutoReplot( false ); + + setTitle( "Legend Test" ); + setFooter( "Footer" ); + + // grid + QwtPlotGrid *grid = new QwtPlotGrid; + grid->enableXMin( true ); + grid->setMajorPen( Qt::gray, 0, Qt::DotLine ); + grid->setMinorPen( Qt::darkGray, 0, Qt::DotLine ); + grid->attach( this ); + + // axis + setAxisScale( QwtPlot::yLeft, 0.0, 1000.0 ); + setAxisScale( QwtPlot::xBottom, 0.0, 1000.0 ); +} + +Plot::~Plot() +{ + delete d_externalLegend; +} + +void Plot::insertCurve() +{ + static int counter = 1; + + const char *colors[] = + { + "LightSalmon", + "SteelBlue", + "Yellow", + "Fuchsia", + "PaleGreen", + "PaleTurquoise", + "Cornsilk", + "HotPink", + "Peru", + "Maroon" + }; + const int numColors = sizeof( colors ) / sizeof( colors[0] ); + + QwtPlotCurve *curve = new Curve( counter++ ); + curve->setPen( QColor( colors[ counter % numColors ] ), 2 ); + curve->attach( this ); +} + +void Plot::applySettings( const Settings &settings ) +{ + d_isDirty = false; + setAutoReplot( true ); + + if ( settings.legend.isEnabled ) + { + if ( settings.legend.position > QwtPlot::TopLegend ) + { + if ( legend() ) + { + // remove legend controlled by the plot + insertLegend( NULL ); + } + + if ( d_externalLegend == NULL ) + { + d_externalLegend = new QwtLegend(); + d_externalLegend->setWindowTitle("Plot Legend"); + + connect( + this, + SIGNAL( legendDataChanged( const QVariant &, + const QList & ) ), + d_externalLegend, + SLOT( updateLegend( const QVariant &, + const QList & ) ) ); + + d_externalLegend->show(); + + // populate the new legend + updateLegend(); + } + } + else + { + delete d_externalLegend; + d_externalLegend = NULL; + + if ( legend() == NULL || + plotLayout()->legendPosition() != settings.legend.position ) + { + insertLegend( new QwtLegend(), + QwtPlot::LegendPosition( settings.legend.position ) ); + } + } + } + else + { + insertLegend( NULL ); + + delete d_externalLegend; + d_externalLegend = NULL; + } + + if ( settings.legendItem.isEnabled ) + { + if ( d_legendItem == NULL ) + { + d_legendItem = new LegendItem(); + d_legendItem->attach( this ); + } + + d_legendItem->setMaxColumns( settings.legendItem.numColumns ); + d_legendItem->setAlignment( Qt::Alignment( settings.legendItem.alignment ) ); + d_legendItem->setBackgroundMode( + QwtPlotLegendItem::BackgroundMode( settings.legendItem.backgroundMode ) ); + if ( settings.legendItem.backgroundMode == + QwtPlotLegendItem::ItemBackground ) + { + d_legendItem->setBorderRadius( 4 ); + d_legendItem->setMargin( 0 ); + d_legendItem->setSpacing( 4 ); + d_legendItem->setItemMargin( 2 ); + } + else + { + d_legendItem->setBorderRadius( 8 ); + d_legendItem->setMargin( 4 ); + d_legendItem->setSpacing( 2 ); + d_legendItem->setItemMargin( 0 ); + } + + QFont font = d_legendItem->font(); + font.setPointSize( settings.legendItem.size ); + d_legendItem->setFont( font ); + } + else + { + delete d_legendItem; + d_legendItem = NULL; + } + + QwtPlotItemList curveList = itemList( QwtPlotItem::Rtti_PlotCurve ); + if ( curveList.size() != settings.curve.numCurves ) + { + while ( curveList.size() > settings.curve.numCurves ) + { + QwtPlotItem* curve = curveList.takeFirst(); + delete curve; + } + + for ( int i = curveList.size(); i < settings.curve.numCurves; i++ ) + insertCurve(); + } + + curveList = itemList( QwtPlotItem::Rtti_PlotCurve ); + for ( int i = 0; i < curveList.count(); i++ ) + { + Curve* curve = static_cast( curveList[i] ); + curve->setCurveTitle( settings.curve.title ); + + int sz = 0.5 * settings.legendItem.size; + curve->setLegendIconSize( QSize( sz, sz ) ); + } + + setAutoReplot( false ); + if ( d_isDirty ) + { + d_isDirty = false; + replot(); + } +} + +void Plot::replot() +{ + if ( autoReplot() ) + { + d_isDirty = true; + return; + } + + QwtPlot::replot(); +} + diff --git a/ThirdParty/Qwt/examples/legends/plot.h b/ThirdParty/Qwt/examples/legends/plot.h new file mode 100644 index 0000000000..b29c9d3f1d --- /dev/null +++ b/ThirdParty/Qwt/examples/legends/plot.h @@ -0,0 +1,32 @@ +#ifndef _PLOT_H_ +#define _PLOT_H_ + +#include + +class Settings; +class LegendItem; +class QwtLegend; + +class Plot: public QwtPlot +{ + Q_OBJECT + +public: + Plot( QWidget *parent = NULL ); + virtual ~Plot(); + +public Q_SLOTS: + void applySettings( const Settings & ); + +public: + virtual void replot(); + +private: + void insertCurve(); + + QwtLegend *d_externalLegend; + LegendItem *d_legendItem; + bool d_isDirty; +}; + +#endif diff --git a/ThirdParty/Qwt/examples/legends/settings.h b/ThirdParty/Qwt/examples/legends/settings.h new file mode 100644 index 0000000000..2f9061b686 --- /dev/null +++ b/ThirdParty/Qwt/examples/legends/settings.h @@ -0,0 +1,47 @@ +#ifndef _SETTINGS_ +#define _SETTINGS_ + +#include + +class Settings +{ +public: + Settings() + { + legend.isEnabled = false; + legend.position = 0; + + legendItem.isEnabled = false; + legendItem.numColumns = 0; + legendItem.alignment = 0; + legendItem.backgroundMode = 0; + legendItem.size = 12; + + curve.numCurves = 0; + curve.title = "Curve"; + } + + struct + { + bool isEnabled; + int position; + } legend; + + struct + { + bool isEnabled; + int numColumns; + int alignment; + int backgroundMode; + int size; + + } legendItem; + + struct + { + int numCurves; + QString title; + } curve; +}; + +#endif diff --git a/ThirdParty/Qwt/examples/oscilloscope/curvedata.cpp b/ThirdParty/Qwt/examples/oscilloscope/curvedata.cpp new file mode 100644 index 0000000000..28e02eb727 --- /dev/null +++ b/ThirdParty/Qwt/examples/oscilloscope/curvedata.cpp @@ -0,0 +1,27 @@ +#include "curvedata.h" +#include "signaldata.h" + +const SignalData &CurveData::values() const +{ + return SignalData::instance(); +} + +SignalData &CurveData::values() +{ + return SignalData::instance(); +} + +QPointF CurveData::sample( size_t i ) const +{ + return SignalData::instance().value( i ); +} + +size_t CurveData::size() const +{ + return SignalData::instance().size(); +} + +QRectF CurveData::boundingRect() const +{ + return SignalData::instance().boundingRect(); +} diff --git a/ThirdParty/Qwt/examples/oscilloscope/curvedata.h b/ThirdParty/Qwt/examples/oscilloscope/curvedata.h new file mode 100644 index 0000000000..246eca583f --- /dev/null +++ b/ThirdParty/Qwt/examples/oscilloscope/curvedata.h @@ -0,0 +1,16 @@ +#include +#include + +class SignalData; + +class CurveData: public QwtSeriesData +{ +public: + const SignalData &values() const; + SignalData &values(); + + virtual QPointF sample( size_t i ) const; + virtual size_t size() const; + + virtual QRectF boundingRect() const; +}; diff --git a/ThirdParty/Qwt/examples/oscilloscope/knob.cpp b/ThirdParty/Qwt/examples/oscilloscope/knob.cpp new file mode 100644 index 0000000000..8bb61edc83 --- /dev/null +++ b/ThirdParty/Qwt/examples/oscilloscope/knob.cpp @@ -0,0 +1,95 @@ +#include "knob.h" +#include +#include +#include +#include +#include +#include +#include + +Knob::Knob( const QString &title, double min, double max, QWidget *parent ): + QWidget( parent ) +{ + QFont font( "Helvetica", 10 ); + + d_knob = new QwtKnob( this ); + d_knob->setFont( font ); + + QwtScaleDiv scaleDiv = + d_knob->scaleEngine()->divideScale( min, max, 5, 3 ); + + QList ticks = scaleDiv.ticks( QwtScaleDiv::MajorTick ); + if ( ticks.size() > 0 && ticks[0] > min ) + { + if ( ticks.first() > min ) + ticks.prepend( min ); + if ( ticks.last() < max ) + ticks.append( max ); + } + scaleDiv.setTicks( QwtScaleDiv::MajorTick, ticks ); + d_knob->setScale( scaleDiv ); + + d_knob->setKnobWidth( 50 ); + + font.setBold( true ); + d_label = new QLabel( title, this ); + d_label->setFont( font ); + d_label->setAlignment( Qt::AlignTop | Qt::AlignHCenter ); + + setSizePolicy( QSizePolicy::MinimumExpanding, + QSizePolicy::MinimumExpanding ); + + connect( d_knob, SIGNAL( valueChanged( double ) ), + this, SIGNAL( valueChanged( double ) ) ); +} + +QSize Knob::sizeHint() const +{ + QSize sz1 = d_knob->sizeHint(); + QSize sz2 = d_label->sizeHint(); + + const int w = qMax( sz1.width(), sz2.width() ); + const int h = sz1.height() + sz2.height(); + + int off = qCeil( d_knob->scaleDraw()->extent( d_knob->font() ) ); + off -= 15; // spacing + + return QSize( w, h - off ); +} + +void Knob::setValue( double value ) +{ + d_knob->setValue( value ); +} + +double Knob::value() const +{ + return d_knob->value(); +} + +void Knob::setTheme( const QColor &color ) +{ + d_knob->setPalette( color ); +} + +QColor Knob::theme() const +{ + return d_knob->palette().color( QPalette::Window ); +} + +void Knob::resizeEvent( QResizeEvent *event ) +{ + const QSize sz = event->size(); + const QSize hint = d_label->sizeHint(); + + d_label->setGeometry( 0, sz.height() - hint.height(), + sz.width(), hint.height() ); + + const int knobHeight = d_knob->sizeHint().height(); + + int off = qCeil( d_knob->scaleDraw()->extent( d_knob->font() ) ); + off -= 15; // spacing + + d_knob->setGeometry( 0, d_label->pos().y() - knobHeight + off, + sz.width(), knobHeight ); +} diff --git a/ThirdParty/Qwt/examples/oscilloscope/knob.h b/ThirdParty/Qwt/examples/oscilloscope/knob.h new file mode 100644 index 0000000000..bfc70d7159 --- /dev/null +++ b/ThirdParty/Qwt/examples/oscilloscope/knob.h @@ -0,0 +1,38 @@ +#ifndef _KNOB_H_ +#define _KNOB_H_ + +#include + +class QwtKnob; +class QLabel; + +class Knob: public QWidget +{ + Q_OBJECT + + Q_PROPERTY( QColor theme READ theme WRITE setTheme ) + +public: + Knob( const QString &title, + double min, double max, QWidget *parent = NULL ); + + virtual QSize sizeHint() const; + + void setValue( double value ); + double value() const; + + void setTheme( const QColor & ); + QColor theme() const; + +Q_SIGNALS: + double valueChanged( double ); + +protected: + virtual void resizeEvent( QResizeEvent * ); + +private: + QwtKnob *d_knob; + QLabel *d_label; +}; + +#endif diff --git a/ThirdParty/Qwt/examples/oscilloscope/main.cpp b/ThirdParty/Qwt/examples/oscilloscope/main.cpp new file mode 100644 index 0000000000..75ffbe4a74 --- /dev/null +++ b/ThirdParty/Qwt/examples/oscilloscope/main.cpp @@ -0,0 +1,36 @@ +#include +#include "mainwindow.h" +#include "samplingthread.h" + +int main( int argc, char **argv ) +{ + QApplication app( argc, argv ); + app.setPalette( Qt::darkGray ); + + MainWindow window; + window.resize( 800, 400 ); + + SamplingThread samplingThread; + samplingThread.setFrequency( window.frequency() ); + samplingThread.setAmplitude( window.amplitude() ); + samplingThread.setInterval( window.signalInterval() ); + + window.connect( &window, SIGNAL( frequencyChanged( double ) ), + &samplingThread, SLOT( setFrequency( double ) ) ); + window.connect( &window, SIGNAL( amplitudeChanged( double ) ), + &samplingThread, SLOT( setAmplitude( double ) ) ); + window.connect( &window, SIGNAL( signalIntervalChanged( double ) ), + &samplingThread, SLOT( setInterval( double ) ) ); + + window.show(); + + samplingThread.start(); + window.start(); + + bool ok = app.exec(); + + samplingThread.stop(); + samplingThread.wait( 1000 ); + + return ok; +} diff --git a/ThirdParty/Qwt/examples/oscilloscope/mainwindow.cpp b/ThirdParty/Qwt/examples/oscilloscope/mainwindow.cpp new file mode 100644 index 0000000000..8c46f447bc --- /dev/null +++ b/ThirdParty/Qwt/examples/oscilloscope/mainwindow.cpp @@ -0,0 +1,69 @@ +#include "mainwindow.h" +#include "plot.h" +#include "knob.h" +#include "wheelbox.h" +#include +#include +#include + +MainWindow::MainWindow( QWidget *parent ): + QWidget( parent ) +{ + const double intervalLength = 10.0; // seconds + + d_plot = new Plot( this ); + d_plot->setIntervalLength( intervalLength ); + + d_amplitudeKnob = new Knob( "Amplitude", 0.0, 200.0, this ); + d_amplitudeKnob->setValue( 160.0 ); + + d_frequencyKnob = new Knob( "Frequency [Hz]", 0.1, 20.0, this ); + d_frequencyKnob->setValue( 17.8 ); + + d_intervalWheel = new WheelBox( "Displayed [s]", 1.0, 100.0, 1.0, this ); + d_intervalWheel->setValue( intervalLength ); + + d_timerWheel = new WheelBox( "Sample Interval [ms]", 0.0, 20.0, 0.1, this ); + d_timerWheel->setValue( 10.0 ); + + QVBoxLayout* vLayout1 = new QVBoxLayout(); + vLayout1->addWidget( d_intervalWheel ); + vLayout1->addWidget( d_timerWheel ); + vLayout1->addStretch( 10 ); + vLayout1->addWidget( d_amplitudeKnob ); + vLayout1->addWidget( d_frequencyKnob ); + + QHBoxLayout *layout = new QHBoxLayout( this ); + layout->addWidget( d_plot, 10 ); + layout->addLayout( vLayout1 ); + + connect( d_amplitudeKnob, SIGNAL( valueChanged( double ) ), + SIGNAL( amplitudeChanged( double ) ) ); + connect( d_frequencyKnob, SIGNAL( valueChanged( double ) ), + SIGNAL( frequencyChanged( double ) ) ); + connect( d_timerWheel, SIGNAL( valueChanged( double ) ), + SIGNAL( signalIntervalChanged( double ) ) ); + + connect( d_intervalWheel, SIGNAL( valueChanged( double ) ), + d_plot, SLOT( setIntervalLength( double ) ) ); +} + +void MainWindow::start() +{ + d_plot->start(); +} + +double MainWindow::frequency() const +{ + return d_frequencyKnob->value(); +} + +double MainWindow::amplitude() const +{ + return d_amplitudeKnob->value(); +} + +double MainWindow::signalInterval() const +{ + return d_timerWheel->value(); +} diff --git a/ThirdParty/Qwt/examples/oscilloscope/mainwindow.h b/ThirdParty/Qwt/examples/oscilloscope/mainwindow.h new file mode 100644 index 0000000000..8994f04882 --- /dev/null +++ b/ThirdParty/Qwt/examples/oscilloscope/mainwindow.h @@ -0,0 +1,32 @@ +#include + +class Plot; +class Knob; +class WheelBox; + +class MainWindow : public QWidget +{ + Q_OBJECT + +public: + MainWindow( QWidget * = NULL ); + + void start(); + + double amplitude() const; + double frequency() const; + double signalInterval() const; + +Q_SIGNALS: + void amplitudeChanged( double ); + void frequencyChanged( double ); + void signalIntervalChanged( double ); + +private: + Knob *d_frequencyKnob; + Knob *d_amplitudeKnob; + WheelBox *d_timerWheel; + WheelBox *d_intervalWheel; + + Plot *d_plot; +}; diff --git a/ThirdParty/Qwt/examples/oscilloscope/osci.css b/ThirdParty/Qwt/examples/oscilloscope/osci.css new file mode 100644 index 0000000000..344a8c4261 --- /dev/null +++ b/ThirdParty/Qwt/examples/oscilloscope/osci.css @@ -0,0 +1,55 @@ +MainWindow +{ + border: 1px solid white; + border-radius: 20px; + padding: 10px; + background-color: qlineargradient( x1: 0, y1: 0, x2: 1, y2: 1, + stop: 0 #31312C, stop: 0.5 #808080 stop: 1 #31312C ); +} + +QwtPlotCanvas +{ + border: 1px solid White; + border-radius: 10px; + background-color: #101010; + color: yellow; /* used as curve color */ +} + +QwtScaleWidget +{ + color: white; +} + +WheelBox +{ + qproperty-theme: #878787; +} + +QwtWheel +{ + /* background-color: yellow; */ + qproperty-mass: 0.0; + qproperty-tickCount: 5; + qproperty-wheelWidth: 15; + qproperty-borderWidth: 2; + qproperty-wheelBorderWidth: 2; + qproperty-wrapping: true; +} + +Knob +{ + qproperty-theme: #606060; +} + +QwtKnob +{ + qproperty-knobStyle: Sunken; + qproperty-markerStyle: Nub; + qproperty-markerSize: 8; + qproperty-borderWidth: 2; +} + +QLCDNumber +{ + color: yellow; +} diff --git a/ThirdParty/Qwt/examples/oscilloscope/oscilloscope.pro b/ThirdParty/Qwt/examples/oscilloscope/oscilloscope.pro new file mode 100644 index 0000000000..2fa8e1ea33 --- /dev/null +++ b/ThirdParty/Qwt/examples/oscilloscope/oscilloscope.pro @@ -0,0 +1,31 @@ +################################################################ +# Qwt Widget Library +# Copyright (C) 1997 Josef Wilgen +# Copyright (C) 2002 Uwe Rathmann +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the Qwt License, Version 1.0 +################################################################ + +include( $${PWD}/../examples.pri ) + +TARGET = oscilloscope + +HEADERS = \ + signaldata.h \ + plot.h \ + knob.h \ + wheelbox.h \ + samplingthread.h \ + curvedata.h \ + mainwindow.h + +SOURCES = \ + signaldata.cpp \ + plot.cpp \ + knob.cpp \ + wheelbox.cpp \ + samplingthread.cpp \ + curvedata.cpp \ + mainwindow.cpp \ + main.cpp diff --git a/ThirdParty/Qwt/examples/oscilloscope/plot.cpp b/ThirdParty/Qwt/examples/oscilloscope/plot.cpp new file mode 100644 index 0000000000..42a4e19cc5 --- /dev/null +++ b/ThirdParty/Qwt/examples/oscilloscope/plot.cpp @@ -0,0 +1,254 @@ +#include "plot.h" +#include "curvedata.h" +#include "signaldata.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class Canvas: public QwtPlotCanvas +{ +public: + Canvas( QwtPlot *plot = NULL ): + QwtPlotCanvas( plot ) + { + // The backing store is important, when working with widget + // overlays ( f.e rubberbands for zooming ). + // Here we don't have them and the internal + // backing store of QWidget is good enough. + + setPaintAttribute( QwtPlotCanvas::BackingStore, false ); + setBorderRadius( 10 ); + + if ( QwtPainter::isX11GraphicsSystem() ) + { +#if QT_VERSION < 0x050000 + // Even if not liked by the Qt development, Qt::WA_PaintOutsidePaintEvent + // works on X11. This has a nice effect on the performance. + + setAttribute( Qt::WA_PaintOutsidePaintEvent, true ); +#endif + + // Disabling the backing store of Qt improves the performance + // for the direct painter even more, but the canvas becomes + // a native window of the window system, receiving paint events + // for resize and expose operations. Those might be expensive + // when there are many points and the backing store of + // the canvas is disabled. So in this application + // we better don't both backing stores. + + if ( testPaintAttribute( QwtPlotCanvas::BackingStore ) ) + { + setAttribute( Qt::WA_PaintOnScreen, true ); + setAttribute( Qt::WA_NoSystemBackground, true ); + } + } + + setupPalette(); + } + +private: + void setupPalette() + { + QPalette pal = palette(); + +#if QT_VERSION >= 0x040400 + QLinearGradient gradient; + gradient.setCoordinateMode( QGradient::StretchToDeviceMode ); + gradient.setColorAt( 0.0, QColor( 0, 49, 110 ) ); + gradient.setColorAt( 1.0, QColor( 0, 87, 174 ) ); + + pal.setBrush( QPalette::Window, QBrush( gradient ) ); +#else + pal.setBrush( QPalette::Window, QBrush( color ) ); +#endif + + // QPalette::WindowText is used for the curve color + pal.setColor( QPalette::WindowText, Qt::green ); + + setPalette( pal ); + } +}; + +Plot::Plot( QWidget *parent ): + QwtPlot( parent ), + d_paintedPoints( 0 ), + d_interval( 0.0, 10.0 ), + d_timerId( -1 ) +{ + d_directPainter = new QwtPlotDirectPainter(); + + setAutoReplot( false ); + setCanvas( new Canvas() ); + + plotLayout()->setAlignCanvasToScales( true ); + + setAxisTitle( QwtPlot::xBottom, "Time [s]" ); + setAxisScale( QwtPlot::xBottom, d_interval.minValue(), d_interval.maxValue() ); + setAxisScale( QwtPlot::yLeft, -200.0, 200.0 ); + + QwtPlotGrid *grid = new QwtPlotGrid(); + grid->setPen( Qt::gray, 0.0, Qt::DotLine ); + grid->enableX( true ); + grid->enableXMin( true ); + grid->enableY( true ); + grid->enableYMin( false ); + grid->attach( this ); + + d_origin = new QwtPlotMarker(); + d_origin->setLineStyle( QwtPlotMarker::Cross ); + d_origin->setValue( d_interval.minValue() + d_interval.width() / 2.0, 0.0 ); + d_origin->setLinePen( Qt::gray, 0.0, Qt::DashLine ); + d_origin->attach( this ); + + d_curve = new QwtPlotCurve(); + d_curve->setStyle( QwtPlotCurve::Lines ); + d_curve->setPen( canvas()->palette().color( QPalette::WindowText ) ); + d_curve->setRenderHint( QwtPlotItem::RenderAntialiased, true ); + d_curve->setPaintAttribute( QwtPlotCurve::ClipPolygons, false ); + d_curve->setData( new CurveData() ); + d_curve->attach( this ); +} + +Plot::~Plot() +{ + delete d_directPainter; +} + +void Plot::start() +{ + d_clock.start(); + d_timerId = startTimer( 10 ); +} + +void Plot::replot() +{ + CurveData *data = static_cast( d_curve->data() ); + data->values().lock(); + + QwtPlot::replot(); + d_paintedPoints = data->size(); + + data->values().unlock(); +} + +void Plot::setIntervalLength( double interval ) +{ + if ( interval > 0.0 && interval != d_interval.width() ) + { + d_interval.setMaxValue( d_interval.minValue() + interval ); + setAxisScale( QwtPlot::xBottom, + d_interval.minValue(), d_interval.maxValue() ); + + replot(); + } +} + +void Plot::updateCurve() +{ + CurveData *data = static_cast( d_curve->data() ); + data->values().lock(); + + const int numPoints = data->size(); + if ( numPoints > d_paintedPoints ) + { + const bool doClip = !canvas()->testAttribute( Qt::WA_PaintOnScreen ); + if ( doClip ) + { + /* + Depending on the platform setting a clip might be an important + performance issue. F.e. for Qt Embedded this reduces the + part of the backing store that has to be copied out - maybe + to an unaccelerated frame buffer device. + */ + + const QwtScaleMap xMap = canvasMap( d_curve->xAxis() ); + const QwtScaleMap yMap = canvasMap( d_curve->yAxis() ); + + QRectF br = qwtBoundingRect( *data, + d_paintedPoints - 1, numPoints - 1 ); + + const QRect clipRect = QwtScaleMap::transform( xMap, yMap, br ).toRect(); + d_directPainter->setClipRegion( clipRect ); + } + + d_directPainter->drawSeries( d_curve, + d_paintedPoints - 1, numPoints - 1 ); + d_paintedPoints = numPoints; + } + + data->values().unlock(); +} + +void Plot::incrementInterval() +{ + d_interval = QwtInterval( d_interval.maxValue(), + d_interval.maxValue() + d_interval.width() ); + + CurveData *data = static_cast( d_curve->data() ); + data->values().clearStaleValues( d_interval.minValue() ); + + // To avoid, that the grid is jumping, we disable + // the autocalculation of the ticks and shift them + // manually instead. + + QwtScaleDiv scaleDiv = axisScaleDiv( QwtPlot::xBottom ); + scaleDiv.setInterval( d_interval ); + + for ( int i = 0; i < QwtScaleDiv::NTickTypes; i++ ) + { + QList ticks = scaleDiv.ticks( i ); + for ( int j = 0; j < ticks.size(); j++ ) + ticks[j] += d_interval.width(); + scaleDiv.setTicks( i, ticks ); + } + setAxisScaleDiv( QwtPlot::xBottom, scaleDiv ); + + d_origin->setValue( d_interval.minValue() + d_interval.width() / 2.0, 0.0 ); + + d_paintedPoints = 0; + replot(); +} + +void Plot::timerEvent( QTimerEvent *event ) +{ + if ( event->timerId() == d_timerId ) + { + updateCurve(); + + const double elapsed = d_clock.elapsed() / 1000.0; + if ( elapsed > d_interval.maxValue() ) + incrementInterval(); + + return; + } + + QwtPlot::timerEvent( event ); +} + +void Plot::resizeEvent( QResizeEvent *event ) +{ + d_directPainter->reset(); + QwtPlot::resizeEvent( event ); +} + +void Plot::showEvent( QShowEvent * ) +{ + replot(); +} + +bool Plot::eventFilter( QObject *object, QEvent *event ) +{ + if ( object == canvas() && + event->type() == QEvent::PaletteChange ) + { + d_curve->setPen( canvas()->palette().color( QPalette::WindowText ) ); + } + + return QwtPlot::eventFilter( object, event ); +} diff --git a/ThirdParty/Qwt/examples/oscilloscope/plot.h b/ThirdParty/Qwt/examples/oscilloscope/plot.h new file mode 100644 index 0000000000..16a53b8d7f --- /dev/null +++ b/ThirdParty/Qwt/examples/oscilloscope/plot.h @@ -0,0 +1,44 @@ +#include +#include +#include + +class QwtPlotCurve; +class QwtPlotMarker; +class QwtPlotDirectPainter; + +class Plot: public QwtPlot +{ + Q_OBJECT + +public: + Plot( QWidget * = NULL ); + virtual ~Plot(); + + void start(); + virtual void replot(); + + virtual bool eventFilter( QObject *, QEvent * ); + +public Q_SLOTS: + void setIntervalLength( double ); + +protected: + virtual void showEvent( QShowEvent * ); + virtual void resizeEvent( QResizeEvent * ); + virtual void timerEvent( QTimerEvent * ); + +private: + void updateCurve(); + void incrementInterval(); + + QwtPlotMarker *d_origin; + QwtPlotCurve *d_curve; + int d_paintedPoints; + + QwtPlotDirectPainter *d_directPainter; + + QwtInterval d_interval; + int d_timerId; + + QwtSystemClock d_clock; +}; diff --git a/ThirdParty/Qwt/examples/oscilloscope/samplingthread.cpp b/ThirdParty/Qwt/examples/oscilloscope/samplingthread.cpp new file mode 100644 index 0000000000..7c0733ccb0 --- /dev/null +++ b/ThirdParty/Qwt/examples/oscilloscope/samplingthread.cpp @@ -0,0 +1,54 @@ +#include "samplingthread.h" +#include "signaldata.h" +#include +#include + +#if QT_VERSION < 0x040600 +#define qFastSin(x) ::sin(x) +#endif + +SamplingThread::SamplingThread( QObject *parent ): + QwtSamplingThread( parent ), + d_frequency( 5.0 ), + d_amplitude( 20.0 ) +{ +} + +void SamplingThread::setFrequency( double frequency ) +{ + d_frequency = frequency; +} + +double SamplingThread::frequency() const +{ + return d_frequency; +} + +void SamplingThread::setAmplitude( double amplitude ) +{ + d_amplitude = amplitude; +} + +double SamplingThread::amplitude() const +{ + return d_amplitude; +} + +void SamplingThread::sample( double elapsed ) +{ + if ( d_frequency > 0.0 ) + { + const QPointF s( elapsed, value( elapsed ) ); + SignalData::instance().append( s ); + } +} + +double SamplingThread::value( double timeStamp ) const +{ + const double period = 1.0 / d_frequency; + + const double x = ::fmod( timeStamp, period ); + const double v = d_amplitude * qFastSin( x / period * 2 * M_PI ); + + return v; +} diff --git a/ThirdParty/Qwt/examples/oscilloscope/samplingthread.h b/ThirdParty/Qwt/examples/oscilloscope/samplingthread.h new file mode 100644 index 0000000000..1416113226 --- /dev/null +++ b/ThirdParty/Qwt/examples/oscilloscope/samplingthread.h @@ -0,0 +1,25 @@ +#include + +class SamplingThread: public QwtSamplingThread +{ + Q_OBJECT + +public: + SamplingThread( QObject *parent = NULL ); + + double frequency() const; + double amplitude() const; + +public Q_SLOTS: + void setAmplitude( double ); + void setFrequency( double ); + +protected: + virtual void sample( double elapsed ); + +private: + virtual double value( double timeStamp ) const; + + double d_frequency; + double d_amplitude; +}; diff --git a/ThirdParty/Qwt/examples/oscilloscope/signaldata.cpp b/ThirdParty/Qwt/examples/oscilloscope/signaldata.cpp new file mode 100644 index 0000000000..b5ef07f98c --- /dev/null +++ b/ThirdParty/Qwt/examples/oscilloscope/signaldata.cpp @@ -0,0 +1,133 @@ +#include "signaldata.h" +#include +#include +#include + +class SignalData::PrivateData +{ +public: + PrivateData(): + boundingRect( 1.0, 1.0, -2.0, -2.0 ) // invalid + { + values.reserve( 1000 ); + } + + inline void append( const QPointF &sample ) + { + values.append( sample ); + + // adjust the bounding rectangle + + if ( boundingRect.width() < 0 || boundingRect.height() < 0 ) + { + boundingRect.setRect( sample.x(), sample.y(), 0.0, 0.0 ); + } + else + { + boundingRect.setRight( sample.x() ); + + if ( sample.y() > boundingRect.bottom() ) + boundingRect.setBottom( sample.y() ); + + if ( sample.y() < boundingRect.top() ) + boundingRect.setTop( sample.y() ); + } + } + + QReadWriteLock lock; + + QVector values; + QRectF boundingRect; + + QMutex mutex; // protecting pendingValues + QVector pendingValues; +}; + +SignalData::SignalData() +{ + d_data = new PrivateData(); +} + +SignalData::~SignalData() +{ + delete d_data; +} + +int SignalData::size() const +{ + return d_data->values.size(); +} + +QPointF SignalData::value( int index ) const +{ + return d_data->values[index]; +} + +QRectF SignalData::boundingRect() const +{ + return d_data->boundingRect; +} + +void SignalData::lock() +{ + d_data->lock.lockForRead(); +} + +void SignalData::unlock() +{ + d_data->lock.unlock(); +} + +void SignalData::append( const QPointF &sample ) +{ + d_data->mutex.lock(); + d_data->pendingValues += sample; + + const bool isLocked = d_data->lock.tryLockForWrite(); + if ( isLocked ) + { + const int numValues = d_data->pendingValues.size(); + const QPointF *pendingValues = d_data->pendingValues.data(); + + for ( int i = 0; i < numValues; i++ ) + d_data->append( pendingValues[i] ); + + d_data->pendingValues.clear(); + + d_data->lock.unlock(); + } + + d_data->mutex.unlock(); +} + +void SignalData::clearStaleValues( double limit ) +{ + d_data->lock.lockForWrite(); + + d_data->boundingRect = QRectF( 1.0, 1.0, -2.0, -2.0 ); // invalid + + const QVector values = d_data->values; + d_data->values.clear(); + d_data->values.reserve( values.size() ); + + int index; + for ( index = values.size() - 1; index >= 0; index-- ) + { + if ( values[index].x() < limit ) + break; + } + + if ( index > 0 ) + d_data->append( values[index++] ); + + while ( index < values.size() - 1 ) + d_data->append( values[index++] ); + + d_data->lock.unlock(); +} + +SignalData &SignalData::instance() +{ + static SignalData valueVector; + return valueVector; +} diff --git a/ThirdParty/Qwt/examples/oscilloscope/signaldata.h b/ThirdParty/Qwt/examples/oscilloscope/signaldata.h new file mode 100644 index 0000000000..61b05ade40 --- /dev/null +++ b/ThirdParty/Qwt/examples/oscilloscope/signaldata.h @@ -0,0 +1,33 @@ +#ifndef _SIGNAL_DATA_H_ +#define _SIGNAL_DATA_H_ 1 + +#include + +class SignalData +{ +public: + static SignalData &instance(); + + void append( const QPointF &pos ); + void clearStaleValues( double min ); + + int size() const; + QPointF value( int index ) const; + + QRectF boundingRect() const; + + void lock(); + void unlock(); + +private: + SignalData(); + SignalData( const SignalData & ); + SignalData &operator=( const SignalData & ); + + virtual ~SignalData(); + + class PrivateData; + PrivateData *d_data; +}; + +#endif diff --git a/ThirdParty/Qwt/examples/oscilloscope/wheelbox.cpp b/ThirdParty/Qwt/examples/oscilloscope/wheelbox.cpp new file mode 100644 index 0000000000..44ea3a0e7b --- /dev/null +++ b/ThirdParty/Qwt/examples/oscilloscope/wheelbox.cpp @@ -0,0 +1,102 @@ +#include "wheelbox.h" +#include +#include +#include +#include +#include +#include + +class Wheel: public QwtWheel +{ +public: + Wheel( WheelBox *parent ): + QwtWheel( parent ) + { + setFocusPolicy( Qt::WheelFocus ); + parent->installEventFilter( this ); + } + + virtual bool eventFilter( QObject *object, QEvent *event ) + { + if ( event->type() == QEvent::Wheel ) + { + const QWheelEvent *we = static_cast( event ); + + QWheelEvent wheelEvent( QPoint( 5, 5 ), we->delta(), + we->buttons(), we->modifiers(), + we->orientation() ); + + QApplication::sendEvent( this, &wheelEvent ); + return true; + } + return QwtWheel::eventFilter( object, event ); + } +}; + +WheelBox::WheelBox( const QString &title, + double min, double max, double stepSize, QWidget *parent ): + QWidget( parent ) +{ + + d_number = new QLCDNumber( this ); + d_number->setSegmentStyle( QLCDNumber::Filled ); + d_number->setAutoFillBackground( true ); + d_number->setFixedHeight( d_number->sizeHint().height() * 2 ); + d_number->setFocusPolicy( Qt::WheelFocus ); + + QPalette pal( Qt::black ); + pal.setColor( QPalette::WindowText, Qt::green ); + d_number->setPalette( pal ); + + d_wheel = new Wheel( this ); + d_wheel->setOrientation( Qt::Vertical ); + d_wheel->setInverted( true ); + d_wheel->setRange( min, max ); + d_wheel->setSingleStep( stepSize ); + d_wheel->setPageStepCount( 5 ); + d_wheel->setFixedHeight( d_number->height() ); + + d_number->setFocusProxy( d_wheel ); + + QFont font( "Helvetica", 10 ); + font.setBold( true ); + + d_label = new QLabel( title, this ); + d_label->setFont( font ); + + QHBoxLayout *hLayout = new QHBoxLayout; + hLayout->setContentsMargins( 0, 0, 0, 0 ); + hLayout->setSpacing( 2 ); + hLayout->addWidget( d_number, 10 ); + hLayout->addWidget( d_wheel ); + + QVBoxLayout *vLayout = new QVBoxLayout( this ); + vLayout->addLayout( hLayout, 10 ); + vLayout->addWidget( d_label, 0, Qt::AlignTop | Qt::AlignHCenter ); + + connect( d_wheel, SIGNAL( valueChanged( double ) ), + d_number, SLOT( display( double ) ) ); + connect( d_wheel, SIGNAL( valueChanged( double ) ), + this, SIGNAL( valueChanged( double ) ) ); +} + +void WheelBox::setTheme( const QColor &color ) +{ + d_wheel->setPalette( color ); +} + +QColor WheelBox::theme() const +{ + return d_wheel->palette().color( QPalette::Window ); +} + +void WheelBox::setValue( double value ) +{ + d_wheel->setValue( value ); + d_number->display( value ); +} + +double WheelBox::value() const +{ + return d_wheel->value(); +} diff --git a/ThirdParty/Qwt/examples/oscilloscope/wheelbox.h b/ThirdParty/Qwt/examples/oscilloscope/wheelbox.h new file mode 100644 index 0000000000..5331692a36 --- /dev/null +++ b/ThirdParty/Qwt/examples/oscilloscope/wheelbox.h @@ -0,0 +1,40 @@ +#ifndef _WHEELBOX_H_ +#define _WHEELBOX_H_ + +#include + +class QwtWheel; +class QLabel; +class QLCDNumber; + +class WheelBox: public QWidget +{ + Q_OBJECT + Q_PROPERTY( QColor theme READ theme WRITE setTheme ) + +public: + WheelBox( const QString &title, + double min, double max, double stepSize, + QWidget *parent = NULL ); + + void setTheme( const QColor & ); + QColor theme() const; + + void setUnit( const QString & ); + QString unit() const; + + void setValue( double value ); + double value() const; + +Q_SIGNALS: + double valueChanged( double ); + +private: + QLCDNumber *d_number; + QwtWheel *d_wheel; + QLabel *d_label; + + QString d_unit; +}; + +#endif diff --git a/ThirdParty/Qwt/examples/radio/ampfrm.cpp b/ThirdParty/Qwt/examples/radio/ampfrm.cpp new file mode 100644 index 0000000000..7dffc749a5 --- /dev/null +++ b/ThirdParty/Qwt/examples/radio/ampfrm.cpp @@ -0,0 +1,201 @@ +#include "ampfrm.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if QT_VERSION < 0x040600 +#define qFastSin(x) ::sin(x) +#define qFastCos(x) ::cos(x) +#endif + +class Knob: public QWidget +{ +public: + Knob( const QString &title, double min, double max, QWidget *parent ): + QWidget( parent ) + { + d_knob = new QwtKnob( this ); + d_knob->setScale( min, max ); + d_knob->setTotalSteps( 0 ); // disable + d_knob->setScaleMaxMajor( 10 ); + + d_knob->setKnobStyle( QwtKnob::Raised ); + d_knob->setKnobWidth( 50 ); + d_knob->setBorderWidth( 2 ); + d_knob->setMarkerStyle( QwtKnob::Notch ); + d_knob->setMarkerSize( 8 ); + + d_knob->scaleDraw()->setTickLength( QwtScaleDiv::MinorTick, 4 ); + d_knob->scaleDraw()->setTickLength( QwtScaleDiv::MediumTick, 4 ); + d_knob->scaleDraw()->setTickLength( QwtScaleDiv::MajorTick, 6 ); + + d_label = new QLabel( title, this ); + d_label->setAlignment( Qt::AlignTop | Qt::AlignHCenter ); + + setSizePolicy( QSizePolicy::MinimumExpanding, + QSizePolicy::MinimumExpanding ); + } + + virtual QSize sizeHint() const + { + QSize sz1 = d_knob->sizeHint(); + QSize sz2 = d_label->sizeHint(); + + const int w = qMax( sz1.width(), sz2.width() ); + const int h = sz1.height() + sz2.height(); + + int off = qCeil( d_knob->scaleDraw()->extent( d_knob->font() ) ); + off -= 10; // spacing + + return QSize( w, h - off ); + } + + void setValue( double value ) + { + d_knob->setValue( value ); + } + + double value() const + { + return d_knob->value(); + } + +protected: + virtual void resizeEvent( QResizeEvent *e ) + { + const QSize sz = e->size(); + + int h = d_label->sizeHint().height(); + + d_label->setGeometry( 0, sz.height() - h, sz.width(), h ); + + h = d_knob->sizeHint().height(); + int off = qCeil( d_knob->scaleDraw()->extent( d_knob->font() ) ); + off -= 10; // spacing + + d_knob->setGeometry( 0, d_label->pos().y() - h + off, + sz.width(), h ); + } + +private: + QwtKnob *d_knob; + QLabel *d_label; +}; + +class Thermo: public QWidget +{ +public: + Thermo( const QString &title, QWidget *parent ): + QWidget( parent ) + { + d_thermo = new QwtThermo( this ); + d_thermo->setPipeWidth( 6 ); + d_thermo->setScale( -40, 10 ); + d_thermo->setFillBrush( Qt::green ); + d_thermo->setAlarmBrush( Qt::red ); + d_thermo->setAlarmLevel( 0.0 ); + d_thermo->setAlarmEnabled( true ); + + QLabel *label = new QLabel( title, this ); + label->setAlignment( Qt::AlignTop | Qt::AlignLeft ); + + QVBoxLayout *layout = new QVBoxLayout( this ); + layout->setMargin( 0 ); + layout->setSpacing( 0 ); + layout->addWidget( d_thermo, 10 ); + layout->addWidget( label ); + } + + void setValue( double value ) + { + d_thermo->setValue( value ); + } + +private: + QwtThermo *d_thermo; +}; + +AmpFrame::AmpFrame( QWidget *p ): + QFrame( p ) +{ + d_knbVolume = new Knob( "Volume", 0.0, 10.0, this ); + d_knbBalance = new Knob( "Balance", -10.0, 10.0, this ); + d_knbTreble = new Knob( "Treble", -10.0, 10.0, this ); + d_knbBass = new Knob( "Bass", -10.0, 10.0, this ); + + d_thmLeft = new Thermo( "Left [dB]", this ); + d_thmRight = new Thermo( "Right [dB]", this ); + + QHBoxLayout *layout = new QHBoxLayout( this ); + layout->setSpacing( 0 ); + layout->setMargin( 10 ); + layout->addWidget( d_knbVolume ); + layout->addWidget( d_knbBalance); + layout->addWidget( d_knbTreble); + layout->addWidget( d_knbBass ); + layout->addSpacing( 20 ); + layout->addStretch( 10 ); + layout->addWidget( d_thmLeft ); + layout->addSpacing( 10 ); + layout->addWidget( d_thmRight ); + + d_knbVolume->setValue( 7.0 ); + ( void )startTimer( 50 ); +} + +void AmpFrame::timerEvent( QTimerEvent * ) +{ + static double phs = 0; + + // + // This amplifier generates its own input signal... + // + + const double sig_bass = ( 1.0 + 0.1 * d_knbBass->value() ) + * qFastSin( 13.0 * phs ); + const double sig_mid_l = qFastSin( 17.0 * phs ); + const double sig_mid_r = qFastCos( 17.5 * phs ); + const double sig_trbl_l = 0.5 * ( 1.0 + 0.1 * d_knbTreble->value() ) + * qFastSin( 35.0 * phs ); + const double sig_trbl_r = 0.5 * ( 1.0 + 0.1 * d_knbTreble->value() ) + * qFastSin( 34.0 * phs ); + + double sig_l = 0.05 * d_master * d_knbVolume->value() + * qwtSqr( sig_bass + sig_mid_l + sig_trbl_l ); + double sig_r = 0.05 * d_master * d_knbVolume->value() + * qwtSqr( sig_bass + sig_mid_r + sig_trbl_r ); + + double balance = 0.1 * d_knbBalance->value(); + if ( balance > 0 ) + sig_l *= ( 1.0 - balance ); + else + sig_r *= ( 1.0 + balance ); + + if ( sig_l > 0.01 ) + sig_l = 20.0 * log10( sig_l ); + else + sig_l = -40.0; + + if ( sig_r > 0.01 ) + sig_r = 20.0 * log10( sig_r ); + else + sig_r = - 40.0; + + d_thmLeft->setValue( sig_l ); + d_thmRight->setValue( sig_r ); + + phs += M_PI / 100; + if ( phs > M_PI ) + phs = 0; +} + +void AmpFrame::setMaster( double v ) +{ + d_master = v; +} diff --git a/ThirdParty/Qwt/examples/radio/ampfrm.h b/ThirdParty/Qwt/examples/radio/ampfrm.h new file mode 100644 index 0000000000..abec2a5d37 --- /dev/null +++ b/ThirdParty/Qwt/examples/radio/ampfrm.h @@ -0,0 +1,29 @@ +#include + +class Knob; +class Thermo; + +class AmpFrame : public QFrame +{ + Q_OBJECT +public: + AmpFrame( QWidget * ); + +public Q_SLOTS: + void setMaster( double v ); + +protected: + void timerEvent( QTimerEvent * ); + +private: + Knob *d_knbVolume; + Knob *d_knbBalance; + Knob *d_knbTreble; + Knob *d_knbBass; + Thermo *d_thmLeft; + Thermo *d_thmRight; + double d_master; +}; + + + diff --git a/ThirdParty/Qwt/examples/radio/mainwindow.cpp b/ThirdParty/Qwt/examples/radio/mainwindow.cpp new file mode 100644 index 0000000000..ecae457342 --- /dev/null +++ b/ThirdParty/Qwt/examples/radio/mainwindow.cpp @@ -0,0 +1,50 @@ +#include +#include "tunerfrm.h" +#include "ampfrm.h" +#include "mainwindow.h" + +MainWindow::MainWindow(): + QWidget() +{ + TunerFrame *frmTuner = new TunerFrame( this ); + frmTuner->setFrameStyle( QFrame::Panel | QFrame::Raised ); + + AmpFrame *frmAmp = new AmpFrame( this ); + frmAmp->setFrameStyle( QFrame::Panel | QFrame::Raised ); + + QVBoxLayout *layout = new QVBoxLayout( this ); + layout->setMargin( 0 ); + layout->setSpacing( 0 ); + layout->addWidget( frmTuner ); + layout->addWidget( frmAmp ); + + connect( frmTuner, SIGNAL( fieldChanged( double ) ), + frmAmp, SLOT( setMaster( double ) ) ); + + frmTuner->setFreq( 90.0 ); + + setPalette( QPalette( QColor( 192, 192, 192 ) ) ); + updateGradient(); +} + +void MainWindow::resizeEvent( QResizeEvent * ) +{ + // Qt 4.7.1: QGradient::StretchToDeviceMode is buggy on X11 + updateGradient(); +} + +void MainWindow::updateGradient() +{ + QPalette pal = palette(); + + const QColor buttonColor = pal.color( QPalette::Button ); + const QColor midLightColor = pal.color( QPalette::Midlight ); + + QLinearGradient gradient( rect().topLeft(), rect().topRight() ); + gradient.setColorAt( 0.0, midLightColor ); + gradient.setColorAt( 0.7, buttonColor ); + gradient.setColorAt( 1.0, buttonColor ); + + pal.setBrush( QPalette::Window, gradient ); + setPalette( pal ); +} diff --git a/ThirdParty/Qwt/examples/radio/mainwindow.h b/ThirdParty/Qwt/examples/radio/mainwindow.h new file mode 100644 index 0000000000..b3da235594 --- /dev/null +++ b/ThirdParty/Qwt/examples/radio/mainwindow.h @@ -0,0 +1,15 @@ +#include + +class MainWindow : public QWidget +{ +public: + MainWindow(); + +protected: + virtual void resizeEvent( QResizeEvent * ); + +private: + void updateGradient(); +}; + + diff --git a/ThirdParty/Qwt/examples/radio/radio.cpp b/ThirdParty/Qwt/examples/radio/radio.cpp new file mode 100644 index 0000000000..cfa60841f6 --- /dev/null +++ b/ThirdParty/Qwt/examples/radio/radio.cpp @@ -0,0 +1,12 @@ +#include +#include "mainwindow.h" + +int main ( int argc, char **argv ) +{ + QApplication a( argc, argv ); + + MainWindow w; + w.show(); + + return a.exec(); +} diff --git a/ThirdParty/Qwt/examples/radio/radio.pro b/ThirdParty/Qwt/examples/radio/radio.pro new file mode 100644 index 0000000000..5af596e6c7 --- /dev/null +++ b/ThirdParty/Qwt/examples/radio/radio.pro @@ -0,0 +1,23 @@ +################################################################ +# Qwt Widget Library +# Copyright (C) 1997 Josef Wilgen +# Copyright (C) 2002 Uwe Rathmann +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the Qwt License, Version 1.0 +################################################################ + +include( $${PWD}/../examples.pri ) + +TARGET = radio + +HEADERS = \ + mainwindow.h \ + ampfrm.h \ + tunerfrm.h + +SOURCES = \ + mainwindow.cpp \ + ampfrm.cpp \ + tunerfrm.cpp \ + radio.cpp diff --git a/ThirdParty/Qwt/examples/radio/tunerfrm.cpp b/ThirdParty/Qwt/examples/radio/tunerfrm.cpp new file mode 100644 index 0000000000..fced7df258 --- /dev/null +++ b/ThirdParty/Qwt/examples/radio/tunerfrm.cpp @@ -0,0 +1,113 @@ +#include +#include +#include +#include +#include +#include +#include "tunerfrm.h" + +#if QT_VERSION < 0x040600 +#define qFastSin(x) ::sin(x) +#define qFastCos(x) ::cos(x) +#endif + +class TuningThermo: public QWidget +{ +public: + TuningThermo( QWidget *parent ): + QWidget( parent ) + { + d_thermo = new QwtThermo( this ); + d_thermo->setOrientation( Qt::Horizontal ); + d_thermo->setScalePosition( QwtThermo::NoScale ); + d_thermo->setScale( 0.0, 1.0 ); + d_thermo->setFillBrush( Qt::green ); + + QLabel *label = new QLabel( "Tuning", this ); + label->setAlignment( Qt::AlignCenter ); + + QVBoxLayout *layout = new QVBoxLayout( this ); + layout->setMargin( 0 ); + layout->addWidget( d_thermo ); + layout->addWidget( label ); + + setFixedWidth( 3 * label->sizeHint().width() ); + } + + void setValue( double value ) + { + d_thermo->setValue( value ); + } + +private: + QwtThermo *d_thermo; +}; + +TunerFrame::TunerFrame( QWidget *parent ): + QFrame( parent ) +{ + const double freqMin = 87.5; + const double freqMax = 108; + + d_sliderFrequency = new QwtSlider( this ); + d_sliderFrequency->setOrientation( Qt::Horizontal ); + d_sliderFrequency->setScalePosition( QwtSlider::TrailingScale ); + d_sliderFrequency->setScale( freqMin, freqMax ); + d_sliderFrequency->setTotalSteps( + qRound( ( freqMax - freqMin ) / 0.01 ) ); + d_sliderFrequency->setSingleSteps( 1 ); + d_sliderFrequency->setPageSteps( 10 ); + d_sliderFrequency->setScaleMaxMinor( 5 ); + d_sliderFrequency->setScaleMaxMajor( 12 ); + d_sliderFrequency->setHandleSize( QSize( 80, 20 ) ); + d_sliderFrequency->setBorderWidth( 1 ); + + d_thermoTune = new TuningThermo( this ); + + d_wheelFrequency = new QwtWheel( this ); + d_wheelFrequency->setMass( 0.5 ); + d_wheelFrequency->setRange( 87.5, 108 ); + d_wheelFrequency->setSingleStep( 0.01 ); + d_wheelFrequency->setPageStepCount( 10 ); + d_wheelFrequency->setTotalAngle( 3600.0 ); + d_wheelFrequency->setFixedHeight( 30 ); + + + connect( d_wheelFrequency, SIGNAL( valueChanged( double ) ), SLOT( adjustFreq( double ) ) ); + connect( d_sliderFrequency, SIGNAL( valueChanged( double ) ), SLOT( adjustFreq( double ) ) ); + + QVBoxLayout *mainLayout = new QVBoxLayout( this ); + mainLayout->setMargin( 10 ); + mainLayout->setSpacing( 5 ); + mainLayout->addWidget( d_sliderFrequency ); + + QHBoxLayout *hLayout = new QHBoxLayout; + hLayout->setMargin( 0 ); + hLayout->addWidget( d_thermoTune, 0 ); + hLayout->addStretch( 5 ); + hLayout->addWidget( d_wheelFrequency, 2 ); + + mainLayout->addLayout( hLayout ); +} + +void TunerFrame::adjustFreq( double frq ) +{ + const double factor = 13.0 / ( 108 - 87.5 ); + + const double x = ( frq - 87.5 ) * factor; + const double field = qwtSqr( qFastSin( x ) * qFastCos( 4.0 * x ) ); + + d_thermoTune->setValue( field ); + + if ( d_sliderFrequency->value() != frq ) + d_sliderFrequency->setValue( frq ); + if ( d_wheelFrequency->value() != frq ) + d_wheelFrequency->setValue( frq ); + + Q_EMIT fieldChanged( field ); +} + +void TunerFrame::setFreq( double frq ) +{ + d_wheelFrequency->setValue( frq ); +} diff --git a/ThirdParty/Qwt/examples/radio/tunerfrm.h b/ThirdParty/Qwt/examples/radio/tunerfrm.h new file mode 100644 index 0000000000..48dd1bcd8a --- /dev/null +++ b/ThirdParty/Qwt/examples/radio/tunerfrm.h @@ -0,0 +1,30 @@ +#include + +class QwtWheel; +class QwtSlider; +class TuningThermo; + +class TunerFrame : public QFrame +{ + Q_OBJECT +public: + TunerFrame( QWidget *p ); + +Q_SIGNALS: + void fieldChanged( double f ); + +public Q_SLOTS: + void setFreq( double frq ); + +private Q_SLOTS: + void adjustFreq( double frq ); + +private: + QwtWheel *d_wheelFrequency; + TuningThermo *d_thermoTune; + QwtSlider *d_sliderFrequency; +}; + + + + diff --git a/ThirdParty/Qwt/examples/rasterview/main.cpp b/ThirdParty/Qwt/examples/rasterview/main.cpp new file mode 100644 index 0000000000..da9d09f1b6 --- /dev/null +++ b/ThirdParty/Qwt/examples/rasterview/main.cpp @@ -0,0 +1,59 @@ +#include +#include +#include +#include +#include +#include +#include "plot.h" + +class MainWindow: public QMainWindow +{ +public: + MainWindow( QWidget * = NULL ); +}; + +MainWindow::MainWindow( QWidget *parent ): + QMainWindow( parent ) +{ + Plot *plot = new Plot( this ); + setCentralWidget( plot ); + + QToolBar *toolBar = new QToolBar( this ); + + QComboBox *rasterBox = new QComboBox( toolBar ); + rasterBox->addItem( "Wikipedia" ); + + toolBar->addWidget( new QLabel( "Data ", toolBar ) ); + toolBar->addWidget( rasterBox ); + toolBar->addSeparator(); + + QComboBox *modeBox = new QComboBox( toolBar ); + modeBox->addItem( "Nearest Neighbour" ); + modeBox->addItem( "Bilinear Interpolation" ); + + toolBar->addWidget( new QLabel( "Resampling ", toolBar ) ); + toolBar->addWidget( modeBox ); + + toolBar->addSeparator(); + + QToolButton *btnExport = new QToolButton( toolBar ); + btnExport->setText( "Export" ); + btnExport->setToolButtonStyle( Qt::ToolButtonTextUnderIcon ); + toolBar->addWidget( btnExport ); + + addToolBar( toolBar ); + + connect( modeBox, SIGNAL( activated( int ) ), plot, SLOT( setResampleMode( int ) ) ); + connect( btnExport, SIGNAL( clicked() ), plot, SLOT( exportPlot() ) ); +} + +int main( int argc, char **argv ) +{ + QApplication a( argc, argv ); + + MainWindow mainWindow; + mainWindow.resize( 600, 400 ); + mainWindow.show(); + + return a.exec(); +} diff --git a/ThirdParty/Qwt/examples/rasterview/plot.cpp b/ThirdParty/Qwt/examples/rasterview/plot.cpp new file mode 100644 index 0000000000..414daffba7 --- /dev/null +++ b/ThirdParty/Qwt/examples/rasterview/plot.cpp @@ -0,0 +1,112 @@ +#include "plot.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class RasterData: public QwtMatrixRasterData +{ +public: + RasterData() + { + const double matrix[] = + { + 1, 2, 4, 1, + 6, 3, 5, 2, + 4, 2, 1, 5, + 5, 4, 2, 3 + }; + + QVector values; + for ( uint i = 0; i < sizeof( matrix ) / sizeof( double ); i++ ) + values += matrix[i]; + + const int numColumns = 4; + setValueMatrix( values, numColumns ); + + setInterval( Qt::XAxis, + QwtInterval( -0.5, 3.5, QwtInterval::ExcludeMaximum ) ); + setInterval( Qt::YAxis, + QwtInterval( -0.5, 3.5, QwtInterval::ExcludeMaximum ) ); + setInterval( Qt::ZAxis, QwtInterval( 1.0, 6.0 ) ); + } +}; + +class ColorMap: public QwtLinearColorMap +{ +public: + ColorMap(): + QwtLinearColorMap( Qt::darkBlue, Qt::darkRed ) + { + addColorStop( 0.2, Qt::blue ); + addColorStop( 0.4, Qt::cyan ); + addColorStop( 0.6, Qt::yellow ); + addColorStop( 0.8, Qt::red ); + } +}; + +Plot::Plot( QWidget *parent ): + QwtPlot( parent ) +{ + QwtPlotCanvas *canvas = new QwtPlotCanvas(); + canvas->setBorderRadius( 10 ); + setCanvas( canvas ); + +#if 0 + QwtPlotGrid *grid = new QwtPlotGrid(); + grid->setPen( Qt::DotLine ); + grid->attach( this ); +#endif + + d_spectrogram = new QwtPlotSpectrogram(); + d_spectrogram->setRenderThreadCount( 0 ); // use system specific thread count + + d_spectrogram->setColorMap( new ColorMap() ); + + d_spectrogram->setData( new RasterData() ); + d_spectrogram->attach( this ); + + const QwtInterval zInterval = d_spectrogram->data()->interval( Qt::ZAxis ); + // A color bar on the right axis + QwtScaleWidget *rightAxis = axisWidget( QwtPlot::yRight ); + rightAxis->setColorBarEnabled( true ); + rightAxis->setColorBarWidth( 40 ); + rightAxis->setColorMap( zInterval, new ColorMap() ); + + setAxisScale( QwtPlot::yRight, zInterval.minValue(), zInterval.maxValue() ); + enableAxis( QwtPlot::yRight ); + + plotLayout()->setAlignCanvasToScales( true ); + + setAxisScale( QwtPlot::xBottom, 0.0, 3.0 ); + setAxisMaxMinor( QwtPlot::xBottom, 0 ); + setAxisScale( QwtPlot::yLeft, 0.0, 3.0 ); + setAxisMaxMinor( QwtPlot::yLeft, 0 ); + + QwtPlotMagnifier *magnifier = new QwtPlotMagnifier( canvas ); + magnifier->setAxisEnabled( QwtPlot::yRight, false ); + + QwtPlotPanner *panner = new QwtPlotPanner( canvas ); + panner->setAxisEnabled( QwtPlot::yRight, false ); +} + +void Plot::exportPlot() +{ + QwtPlotRenderer renderer; + renderer.exportTo( this, "rasterview.pdf" ); +} + +void Plot::setResampleMode( int mode ) +{ + RasterData *data = static_cast( d_spectrogram->data() ); + data->setResampleMode( + static_cast( mode ) ); + + replot(); +} diff --git a/ThirdParty/Qwt/examples/rasterview/plot.h b/ThirdParty/Qwt/examples/rasterview/plot.h new file mode 100644 index 0000000000..140145f9fb --- /dev/null +++ b/ThirdParty/Qwt/examples/rasterview/plot.h @@ -0,0 +1,17 @@ +#include +#include + +class Plot: public QwtPlot +{ + Q_OBJECT + +public: + Plot( QWidget * = NULL ); + +public Q_SLOTS: + void exportPlot(); + void setResampleMode( int ); + +private: + QwtPlotSpectrogram *d_spectrogram; +}; diff --git a/ThirdParty/Qwt/examples/rasterview/rasterview.pro b/ThirdParty/Qwt/examples/rasterview/rasterview.pro new file mode 100644 index 0000000000..15fc8cc428 --- /dev/null +++ b/ThirdParty/Qwt/examples/rasterview/rasterview.pro @@ -0,0 +1,19 @@ +################################################################ +# Qwt Widget Library +# Copyright (C) 1997 Josef Wilgen +# Copyright (C) 2002 Uwe Rathmann +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the Qwt License, Version 1.0 +################################################################ + +include( $${PWD}/../examples.pri ) + +TARGET = rasterview + +HEADERS = \ + plot.h + +SOURCES = \ + plot.cpp \ + main.cpp diff --git a/ThirdParty/Qwt/examples/realtime/README b/ThirdParty/Qwt/examples/realtime/README new file mode 100644 index 0000000000..32c7f13934 --- /dev/null +++ b/ThirdParty/Qwt/examples/realtime/README @@ -0,0 +1,25 @@ +1) Incremental plots + +IncrementalPlot shows an example how to implement a plot that +displays growing data. + +The example produces random data when you push the start button. +With 'Timer' you can adjust the intervall between the +the generation of the points, with 'Points' you can set the number +of points to be generated. + +Unfortunately in Qt4 incremental painting is not possible with QPaintEngines +that doesn't support the QPaintEngine::PaintOutsidePaintEvent feature. +( These are all common paint engines beside the OpenGL engine, but this one +is not supported by Qwt yet. ) +That is the reason why you can see much faster repaints with Qt3. + +2) Stacked Zooming with scrollbars + +ScrollZoomer adds scrollbars for zooming. There are a couple of +reasons why the implementation is a hack and therefore the class +is not part of the Qwt lib, but it should be working with all +types of QwtPlots. Copy the code of scrollbar.[h|cpp] and +scrollzoomer.[h|cpp] to the application code. + +Uwe diff --git a/ThirdParty/Qwt/examples/realtime/clear.xpm b/ThirdParty/Qwt/examples/realtime/clear.xpm new file mode 100644 index 0000000000..86c72b8492 --- /dev/null +++ b/ThirdParty/Qwt/examples/realtime/clear.xpm @@ -0,0 +1,51 @@ +/* XPM */ +static const char *clear_xpm[] = { +/* width height num_colors chars_per_pixel */ +" 32 32 12 1", +/* colors */ +". c #000000", +"# c #004040", +"a c #303030", +"b c #400000", +"c c #404000", +"d c #585858", +"e c #808080", +"f c #a0a0a4", +"g c #bdbdbd", +"h c #c0c0c0", +"i c #dcdcdc", +"j c #ffffff", +/* pixels */ +"gggggggggggggggggggggggggggggggg", +"gggggggggggggg..gggggggggggggggg", +"gggggggggg....ficggggggggggggggg", +"ggggggg...fdad#ai......ggggggggg", +"gggg...fhjjidfbc#f.fffe...gggggg", +"ggg.fhjjjjihc#dhef.fhhhffe.ggggg", +"ggg.#jjjjjihhhhhe..ehhhfff.ggggg", +"ggg.#dffjjjjiihhcadehhfddd.ggggg", +"ggg.iiiffhfjjjjjhhhfdddddd.ggggg", +"ggg.#fjjiiffeeeeddddeeeddd.ggggg", +"gggg.#eeiiiiifffffffeee...gggggg", +"gggg.ffffffiifffffffddddd.gggggg", +"gggg.fffjfffeeeeddddeed.d.gggggg", +"gggg.fefiiiifhffeeeeded.d.gggggg", +"gggg.fefijhfhifefff.ded.d.gggggg", +"gggg.fefijeffifeefe.ded.d.gggggg", +"gggg.fefijeffifeefe.ded.d.gggggg", +"gggg.fefijeffifeefe.ded.d.gggggg", +"gggg.fefijeffifeefe.ded.d.gggggg", +"gggg.fefijeffifeefe.ded.d.gggggg", +"gggg.fefijeffifeefe.ded.d.gggggg", +"gggg.fefijeffifeefe.ded.d.gggggg", +"gggg.fefijeffifeefe.ded.d.gggggg", +"gggg.fefijeffifeefe.ded.d.gggggg", +"gggg.fefijeffifeefe.ded.d.gggggg", +"gggg.fefijeffifeefe.ded.d.gggggg", +"gggg.fffijeffifeefe.deddd.gggggg", +"gggg.ffiijeffifeefeddedd#.gggggg", +"gggg.eiijjjeiifdffedded#..gggggg", +"ggggg..fjjiiiiffffedddd..ggggggg", +"ggggggg...fhhfffffdd...ggggggggg", +"gggggggggg..........gggggggggggg" +}; diff --git a/ThirdParty/Qwt/examples/realtime/incrementalplot.cpp b/ThirdParty/Qwt/examples/realtime/incrementalplot.cpp new file mode 100644 index 0000000000..85a349afc1 --- /dev/null +++ b/ThirdParty/Qwt/examples/realtime/incrementalplot.cpp @@ -0,0 +1,124 @@ +#include +#include +#include +#include +#include +#include +#include "incrementalplot.h" +#include + +class CurveData: public QwtArraySeriesData +{ +public: + CurveData() + { + } + + virtual QRectF boundingRect() const + { + if ( d_boundingRect.width() < 0.0 ) + d_boundingRect = qwtBoundingRect( *this ); + + return d_boundingRect; + } + + inline void append( const QPointF &point ) + { + d_samples += point; + } + + void clear() + { + d_samples.clear(); + d_samples.squeeze(); + d_boundingRect = QRectF( 0.0, 0.0, -1.0, -1.0 ); + } +}; + +IncrementalPlot::IncrementalPlot( QWidget *parent ): + QwtPlot( parent ), + d_curve( NULL ) +{ + d_directPainter = new QwtPlotDirectPainter( this ); + + if ( QwtPainter::isX11GraphicsSystem() ) + { +#if QT_VERSION < 0x050000 + canvas()->setAttribute( Qt::WA_PaintOutsidePaintEvent, true ); +#endif + canvas()->setAttribute( Qt::WA_PaintOnScreen, true ); + } + + d_curve = new QwtPlotCurve( "Test Curve" ); + d_curve->setData( new CurveData() ); + showSymbols( true ); + + d_curve->attach( this ); + + setAutoReplot( false ); +} + +IncrementalPlot::~IncrementalPlot() +{ + delete d_curve; +} + +void IncrementalPlot::appendPoint( const QPointF &point ) +{ + CurveData *data = static_cast( d_curve->data() ); + data->append( point ); + + const bool doClip = !canvas()->testAttribute( Qt::WA_PaintOnScreen ); + if ( doClip ) + { + /* + Depending on the platform setting a clip might be an important + performance issue. F.e. for Qt Embedded this reduces the + part of the backing store that has to be copied out - maybe + to an unaccelerated frame buffer device. + */ + const QwtScaleMap xMap = canvasMap( d_curve->xAxis() ); + const QwtScaleMap yMap = canvasMap( d_curve->yAxis() ); + + QRegion clipRegion; + + const QSize symbolSize = d_curve->symbol()->size(); + QRect r( 0, 0, symbolSize.width() + 2, symbolSize.height() + 2 ); + + const QPointF center = + QwtScaleMap::transform( xMap, yMap, point ); + r.moveCenter( center.toPoint() ); + clipRegion += r; + + d_directPainter->setClipRegion( clipRegion ); + } + + d_directPainter->drawSeries( d_curve, + data->size() - 1, data->size() - 1 ); +} + +void IncrementalPlot::clearPoints() +{ + CurveData *data = static_cast( d_curve->data() ); + data->clear(); + + replot(); +} + +void IncrementalPlot::showSymbols( bool on ) +{ + if ( on ) + { + d_curve->setStyle( QwtPlotCurve::NoCurve ); + d_curve->setSymbol( new QwtSymbol( QwtSymbol::XCross, + Qt::NoBrush, QPen( Qt::white ), QSize( 4, 4 ) ) ); + } + else + { + d_curve->setPen( Qt::white ); + d_curve->setStyle( QwtPlotCurve::Dots ); + d_curve->setSymbol( NULL ); + } + + replot(); +} diff --git a/ThirdParty/Qwt/examples/realtime/incrementalplot.h b/ThirdParty/Qwt/examples/realtime/incrementalplot.h new file mode 100644 index 0000000000..33f19a1113 --- /dev/null +++ b/ThirdParty/Qwt/examples/realtime/incrementalplot.h @@ -0,0 +1,28 @@ +#ifndef _INCREMENTALPLOT_H_ +#define _INCREMENTALPLOT_H_ 1 + +#include + +class QwtPlotCurve; +class QwtPlotDirectPainter; + +class IncrementalPlot : public QwtPlot +{ + Q_OBJECT + +public: + IncrementalPlot( QWidget *parent = NULL ); + virtual ~IncrementalPlot(); + + void appendPoint( const QPointF & ); + void clearPoints(); + +public Q_SLOTS: + void showSymbols( bool ); + +private: + QwtPlotCurve *d_curve; + QwtPlotDirectPainter *d_directPainter; +}; + +#endif // _INCREMENTALPLOT_H_ diff --git a/ThirdParty/Qwt/examples/realtime/main.cpp b/ThirdParty/Qwt/examples/realtime/main.cpp new file mode 100644 index 0000000000..3e33f781e4 --- /dev/null +++ b/ThirdParty/Qwt/examples/realtime/main.cpp @@ -0,0 +1,12 @@ +#include +#include "mainwindow.h" + +int main( int argc, char **argv ) +{ + QApplication a( argc, argv ); + + MainWindow w; + w.show(); + + return a.exec(); +} diff --git a/ThirdParty/Qwt/examples/realtime/mainwindow.cpp b/ThirdParty/Qwt/examples/realtime/mainwindow.cpp new file mode 100644 index 0000000000..b06be4c0b9 --- /dev/null +++ b/ThirdParty/Qwt/examples/realtime/mainwindow.cpp @@ -0,0 +1,193 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "randomplot.h" +#include "mainwindow.h" +#include "start.xpm" +#include "clear.xpm" + +class MyToolBar: public QToolBar +{ +public: + MyToolBar( MainWindow *parent ): + QToolBar( parent ) + { + } + void addSpacing( int spacing ) + { + QLabel *label = new QLabel( this ); + addWidget( label ); + label->setFixedWidth( spacing ); + } +}; + +class Counter: public QWidget +{ +public: + Counter( QWidget *parent, + const QString &prefix, const QString &suffix, + int min, int max, int step ): + QWidget( parent ) + { + QHBoxLayout *layout = new QHBoxLayout( this ); + + if ( !prefix.isEmpty() ) + layout->addWidget( new QLabel( prefix + " ", this ) ); + + d_counter = new QSpinBox( this ); + d_counter->setRange( min, max ); + d_counter->setSingleStep( step ); + layout->addWidget( d_counter ); + + if ( !suffix.isEmpty() ) + layout->addWidget( new QLabel( QString( " " ) + suffix, this ) ); + } + + void setValue( int value ) { d_counter->setValue( value ); } + int value() const { return d_counter->value(); } + +private: + QSpinBox *d_counter; +}; + +MainWindow::MainWindow() +{ + addToolBar( toolBar() ); +#ifndef QT_NO_STATUSBAR + ( void )statusBar(); +#endif + + d_plot = new RandomPlot( this ); + const int margin = 4; + d_plot->setContentsMargins( margin, margin, margin, margin ); + + setCentralWidget( d_plot ); + + connect( d_startAction, SIGNAL( toggled( bool ) ), this, SLOT( appendPoints( bool ) ) ); + connect( d_clearAction, SIGNAL( triggered() ), d_plot, SLOT( clear() ) ); + connect( d_symbolType, SIGNAL( toggled( bool ) ), d_plot, SLOT( showSymbols( bool ) ) ); + connect( d_plot, SIGNAL( running( bool ) ), this, SLOT( showRunning( bool ) ) ); + connect( d_plot, SIGNAL( elapsed( int ) ), this, SLOT( showElapsed( int ) ) ); + + initWhatsThis(); + + setContextMenuPolicy( Qt::NoContextMenu ); +} + +QToolBar *MainWindow::toolBar() +{ + MyToolBar *toolBar = new MyToolBar( this ); + + toolBar->setAllowedAreas( Qt::TopToolBarArea | Qt::BottomToolBarArea ); + setToolButtonStyle( Qt::ToolButtonTextUnderIcon ); + + d_startAction = new QAction( QPixmap( start_xpm ), "Start", toolBar ); + d_startAction->setCheckable( true ); + d_clearAction = new QAction( QPixmap( clear_xpm ), "Clear", toolBar ); + QAction *whatsThisAction = QWhatsThis::createAction( toolBar ); + whatsThisAction->setText( "Help" ); + + toolBar->addAction( d_startAction ); + toolBar->addAction( d_clearAction ); + toolBar->addAction( whatsThisAction ); + + setIconSize( QSize( 22, 22 ) ); + + QWidget *hBox = new QWidget( toolBar ); + + d_symbolType = new QCheckBox( "Symbols", hBox ); + d_symbolType->setChecked( true ); + + d_randomCount = + new Counter( hBox, "Points", QString::null, 1, 100000, 100 ); + d_randomCount->setValue( 1000 ); + + d_timerCount = new Counter( hBox, "Delay", "ms", 0, 100000, 100 ); + d_timerCount->setValue( 0 ); + + QHBoxLayout *layout = new QHBoxLayout( hBox ); + layout->setMargin( 0 ); + layout->setSpacing( 0 ); + layout->addSpacing( 10 ); + layout->addWidget( new QWidget( hBox ), 10 ); // spacer + layout->addWidget( d_symbolType ); + layout->addSpacing( 5 ); + layout->addWidget( d_randomCount ); + layout->addSpacing( 5 ); + layout->addWidget( d_timerCount ); + + showRunning( false ); + + toolBar->addWidget( hBox ); + + return toolBar; +} + +void MainWindow::appendPoints( bool on ) +{ + if ( on ) + d_plot->append( d_timerCount->value(), + d_randomCount->value() ); + else + d_plot->stop(); +} + +void MainWindow::showRunning( bool running ) +{ + d_randomCount->setEnabled( !running ); + d_timerCount->setEnabled( !running ); + d_startAction->setChecked( running ); + d_startAction->setText( running ? "Stop" : "Start" ); +} + +void MainWindow::showElapsed( int ms ) +{ + QString text; + text.setNum( ms ); + text += " ms"; + + statusBar()->showMessage( text ); +} + +void MainWindow::initWhatsThis() +{ + const char *text1 = + "Zooming is enabled until the selected area gets " + "too small for the significance on the axes.\n\n" + "You can zoom in using the left mouse button.\n" + "The middle mouse button is used to go back to the " + "previous zoomed area.\n" + "The right mouse button is used to unzoom completely."; + + const char *text2 = + "Number of random points that will be generated."; + + const char *text3 = + "Delay between the generation of two random points."; + + const char *text4 = + "Start generation of random points.\n\n" + "The intention of this example is to show how to implement " + "growing curves. The points will be generated and displayed " + "one after the other.\n" + "To check the performance, a small delay and a large number " + "of points are useful. To watch the curve growing, a delay " + " > 300 ms and less points are better.\n" + "To inspect the curve, stacked zooming is implemented using the " + "mouse buttons on the plot."; + + const char *text5 = "Remove all points."; + + d_plot->setWhatsThis( text1 ); + d_randomCount->setWhatsThis( text2 ); + d_timerCount->setWhatsThis( text3 ); + d_startAction->setWhatsThis( text4 ); + d_clearAction->setWhatsThis( text5 ); +} + diff --git a/ThirdParty/Qwt/examples/realtime/mainwindow.h b/ThirdParty/Qwt/examples/realtime/mainwindow.h new file mode 100644 index 0000000000..bc69755157 --- /dev/null +++ b/ThirdParty/Qwt/examples/realtime/mainwindow.h @@ -0,0 +1,37 @@ +#ifndef _MAINWINDOW_H_ +#define _MAINWINDOW_H_ 1 + +#include +#include + +class QSpinBox; +class QPushButton; +class RandomPlot; +class Counter; +class QCheckBox; + +class MainWindow: public QMainWindow +{ + Q_OBJECT +public: + MainWindow(); + +private Q_SLOTS: + void showRunning( bool ); + void appendPoints( bool ); + void showElapsed( int ); + +private: + QToolBar *toolBar(); + void initWhatsThis(); + +private: + Counter *d_randomCount; + Counter *d_timerCount; + QCheckBox *d_symbolType; + QAction *d_startAction; + QAction *d_clearAction; + RandomPlot *d_plot; +}; + +#endif diff --git a/ThirdParty/Qwt/examples/realtime/randomplot.cpp b/ThirdParty/Qwt/examples/realtime/randomplot.cpp new file mode 100644 index 0000000000..f600378dd7 --- /dev/null +++ b/ThirdParty/Qwt/examples/realtime/randomplot.cpp @@ -0,0 +1,141 @@ +#include +#include +#include +#include +#include +#include +#include +#include "scrollzoomer.h" +#include "randomplot.h" + +const unsigned int c_rangeMax = 1000; + +class Zoomer: public ScrollZoomer +{ +public: + Zoomer( QWidget *canvas ): + ScrollZoomer( canvas ) + { +#if 0 + setRubberBandPen( QPen( Qt::red, 2, Qt::DotLine ) ); +#else + setRubberBandPen( QPen( Qt::red ) ); +#endif + } + + virtual QwtText trackerTextF( const QPointF &pos ) const + { + QColor bg( Qt::white ); + + QwtText text = QwtPlotZoomer::trackerTextF( pos ); + text.setBackgroundBrush( QBrush( bg ) ); + return text; + } + + virtual void rescale() + { + QwtScaleWidget *scaleWidget = plot()->axisWidget( yAxis() ); + QwtScaleDraw *sd = scaleWidget->scaleDraw(); + + double minExtent = 0.0; + if ( zoomRectIndex() > 0 ) + { + // When scrolling in vertical direction + // the plot is jumping in horizontal direction + // because of the different widths of the labels + // So we better use a fixed extent. + + minExtent = sd->spacing() + sd->maxTickLength() + 1; + minExtent += sd->labelSize( + scaleWidget->font(), c_rangeMax ).width(); + } + + sd->setMinimumExtent( minExtent ); + + ScrollZoomer::rescale(); + } +}; + +RandomPlot::RandomPlot( QWidget *parent ): + IncrementalPlot( parent ), + d_timer( 0 ), + d_timerCount( 0 ) +{ + setFrameStyle( QFrame::NoFrame ); + setLineWidth( 0 ); + + plotLayout()->setAlignCanvasToScales( true ); + + QwtPlotGrid *grid = new QwtPlotGrid; + grid->setMajorPen( Qt::gray, 0, Qt::DotLine ); + grid->attach( this ); + + setCanvasBackground( QColor( 29, 100, 141 ) ); // nice blue + + setAxisScale( xBottom, 0, c_rangeMax ); + setAxisScale( yLeft, 0, c_rangeMax ); + + replot(); + + // enable zooming + + ( void ) new Zoomer( canvas() ); +} + +QSize RandomPlot::sizeHint() const +{ + return QSize( 540, 400 ); +} + +void RandomPlot::appendPoint() +{ + double x = qrand() % c_rangeMax; + x += ( qrand() % 100 ) / 100; + + double y = qrand() % c_rangeMax; + y += ( qrand() % 100 ) / 100; + + IncrementalPlot::appendPoint( QPointF( x, y ) ); + + if ( --d_timerCount <= 0 ) + stop(); +} + +void RandomPlot::append( int timeout, int count ) +{ + if ( !d_timer ) + { + d_timer = new QTimer( this ); + connect( d_timer, SIGNAL( timeout() ), SLOT( appendPoint() ) ); + } + + d_timerCount = count; + + Q_EMIT running( true ); + d_timeStamp.start(); + + QwtPlotCanvas *plotCanvas = qobject_cast( canvas() ); + plotCanvas->setPaintAttribute( QwtPlotCanvas::BackingStore, false ); + + d_timer->start( timeout ); +} + +void RandomPlot::stop() +{ + Q_EMIT elapsed( d_timeStamp.elapsed() ); + + if ( d_timer ) + { + d_timer->stop(); + Q_EMIT running( false ); + } + + QwtPlotCanvas *plotCanvas = qobject_cast( canvas() ); + plotCanvas->setPaintAttribute( QwtPlotCanvas::BackingStore, true ); +} + +void RandomPlot::clear() +{ + clearPoints(); + replot(); +} diff --git a/ThirdParty/Qwt/examples/realtime/randomplot.h b/ThirdParty/Qwt/examples/realtime/randomplot.h new file mode 100644 index 0000000000..44d1ba4bc2 --- /dev/null +++ b/ThirdParty/Qwt/examples/realtime/randomplot.h @@ -0,0 +1,39 @@ +#ifndef _RANDOMPLOT_H_ +#define _RANDOMPLOT_H_ 1 + +#include "incrementalplot.h" +#include + +class QTimer; + +class RandomPlot: public IncrementalPlot +{ + Q_OBJECT + +public: + RandomPlot( QWidget *parent ); + + virtual QSize sizeHint() const; + +Q_SIGNALS: + void running( bool ); + void elapsed( int ms ); + +public Q_SLOTS: + void clear(); + void stop(); + void append( int timeout, int count ); + +private Q_SLOTS: + void appendPoint(); + +private: + void initCurve(); + + QTimer *d_timer; + int d_timerCount; + + QTime d_timeStamp; +}; + +#endif // _RANDOMPLOT_H_ diff --git a/ThirdParty/Qwt/examples/realtime/realtime.pro b/ThirdParty/Qwt/examples/realtime/realtime.pro new file mode 100644 index 0000000000..5f726d7b06 --- /dev/null +++ b/ThirdParty/Qwt/examples/realtime/realtime.pro @@ -0,0 +1,28 @@ +################################################################ +# Qwt Widget Library +# Copyright (C) 1997 Josef Wilgen +# Copyright (C) 2002 Uwe Rathmann +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the Qwt License, Version 1.0 +################################################################ + +include( $${PWD}/../examples.pri ) + +TARGET = realtime + +HEADERS = \ + mainwindow.h \ + scrollzoomer.h \ + scrollbar.h \ + incrementalplot.h \ + randomplot.h + +SOURCES = \ + main.cpp \ + mainwindow.cpp \ + scrollzoomer.cpp \ + scrollbar.cpp \ + incrementalplot.cpp \ + randomplot.cpp + diff --git a/ThirdParty/Qwt/examples/realtime/scrollbar.cpp b/ThirdParty/Qwt/examples/realtime/scrollbar.cpp new file mode 100644 index 0000000000..bd44c6c532 --- /dev/null +++ b/ThirdParty/Qwt/examples/realtime/scrollbar.cpp @@ -0,0 +1,170 @@ +#include +#include +#include "scrollbar.h" + +ScrollBar::ScrollBar( QWidget * parent ): + QScrollBar( parent ) +{ + init(); +} + +ScrollBar::ScrollBar( Qt::Orientation o, + QWidget *parent ): + QScrollBar( o, parent ) +{ + init(); +} + +ScrollBar::ScrollBar( double minBase, double maxBase, + Qt::Orientation o, QWidget *parent ): + QScrollBar( o, parent ) +{ + init(); + setBase( minBase, maxBase ); + moveSlider( minBase, maxBase ); +} + +void ScrollBar::init() +{ + d_inverted = orientation() == Qt::Vertical; + d_baseTicks = 1000000; + d_minBase = 0.0; + d_maxBase = 1.0; + moveSlider( d_minBase, d_maxBase ); + + connect( this, SIGNAL( sliderMoved( int ) ), SLOT( catchSliderMoved( int ) ) ); + connect( this, SIGNAL( valueChanged( int ) ), SLOT( catchValueChanged( int ) ) ); +} + +void ScrollBar::setInverted( bool inverted ) +{ + if ( d_inverted != inverted ) + { + d_inverted = inverted; + moveSlider( minSliderValue(), maxSliderValue() ); + } +} + +bool ScrollBar::isInverted() const +{ + return d_inverted; +} + +void ScrollBar::setBase( double min, double max ) +{ + if ( min != d_minBase || max != d_maxBase ) + { + d_minBase = min; + d_maxBase = max; + + moveSlider( minSliderValue(), maxSliderValue() ); + } +} + +void ScrollBar::moveSlider( double min, double max ) +{ + const int sliderTicks = qRound( ( max - min ) / + ( d_maxBase - d_minBase ) * d_baseTicks ); + + // setRange initiates a valueChanged of the scrollbars + // in some situations. So we block + // and unblock the signals. + + blockSignals( true ); + + setRange( sliderTicks / 2, d_baseTicks - sliderTicks / 2 ); + int steps = sliderTicks / 200; + if ( steps <= 0 ) + steps = 1; + + setSingleStep( steps ); + setPageStep( sliderTicks ); + + int tick = mapToTick( min + ( max - min ) / 2 ); + if ( isInverted() ) + tick = d_baseTicks - tick; + + setSliderPosition( tick ); + blockSignals( false ); +} + +double ScrollBar::minBaseValue() const +{ + return d_minBase; +} + +double ScrollBar::maxBaseValue() const +{ + return d_maxBase; +} + +void ScrollBar::sliderRange( int value, double &min, double &max ) const +{ + if ( isInverted() ) + value = d_baseTicks - value; + + const int visibleTicks = pageStep(); + + min = mapFromTick( value - visibleTicks / 2 ); + max = mapFromTick( value + visibleTicks / 2 ); +} + +double ScrollBar::minSliderValue() const +{ + double min, dummy; + sliderRange( value(), min, dummy ); + + return min; +} + +double ScrollBar::maxSliderValue() const +{ + double max, dummy; + sliderRange( value(), dummy, max ); + + return max; +} + +int ScrollBar::mapToTick( double v ) const +{ + const double pos = ( v - d_minBase ) / ( d_maxBase - d_minBase ) * d_baseTicks; + return static_cast( pos ); +} + +double ScrollBar::mapFromTick( int tick ) const +{ + return d_minBase + ( d_maxBase - d_minBase ) * tick / d_baseTicks; +} + +void ScrollBar::catchValueChanged( int value ) +{ + double min, max; + sliderRange( value, min, max ); + Q_EMIT valueChanged( orientation(), min, max ); +} + +void ScrollBar::catchSliderMoved( int value ) +{ + double min, max; + sliderRange( value, min, max ); + Q_EMIT sliderMoved( orientation(), min, max ); +} + +int ScrollBar::extent() const +{ + QStyleOptionSlider opt; + opt.init( this ); + opt.subControls = QStyle::SC_None; + opt.activeSubControls = QStyle::SC_None; + opt.orientation = orientation(); + opt.minimum = minimum(); + opt.maximum = maximum(); + opt.sliderPosition = sliderPosition(); + opt.sliderValue = value(); + opt.singleStep = singleStep(); + opt.pageStep = pageStep(); + opt.upsideDown = invertedAppearance(); + if ( orientation() == Qt::Horizontal ) + opt.state |= QStyle::State_Horizontal; + return style()->pixelMetric( QStyle::PM_ScrollBarExtent, &opt, this ); +} diff --git a/ThirdParty/Qwt/examples/realtime/scrollbar.h b/ThirdParty/Qwt/examples/realtime/scrollbar.h new file mode 100644 index 0000000000..821cc79ef7 --- /dev/null +++ b/ThirdParty/Qwt/examples/realtime/scrollbar.h @@ -0,0 +1,53 @@ +#ifndef _SCROLLBAR_H +#define _SCROLLBAR_H 1 + +#include + +class ScrollBar: public QScrollBar +{ + Q_OBJECT + +public: + ScrollBar( QWidget *parent = NULL ); + ScrollBar( Qt::Orientation, QWidget *parent = NULL ); + ScrollBar( double minBase, double maxBase, + Qt::Orientation o, QWidget *parent = NULL ); + + void setInverted( bool ); + bool isInverted() const; + + double minBaseValue() const; + double maxBaseValue() const; + + double minSliderValue() const; + double maxSliderValue() const; + + int extent() const; + +Q_SIGNALS: + void sliderMoved( Qt::Orientation, double, double ); + void valueChanged( Qt::Orientation, double, double ); + +public Q_SLOTS: + virtual void setBase( double min, double max ); + virtual void moveSlider( double min, double max ); + +protected: + void sliderRange( int value, double &min, double &max ) const; + int mapToTick( double ) const; + double mapFromTick( int ) const; + +private Q_SLOTS: + void catchValueChanged( int value ); + void catchSliderMoved( int value ); + +private: + void init(); + + bool d_inverted; + double d_minBase; + double d_maxBase; + int d_baseTicks; +}; + +#endif diff --git a/ThirdParty/Qwt/examples/realtime/scrollzoomer.cpp b/ThirdParty/Qwt/examples/realtime/scrollzoomer.cpp new file mode 100644 index 0000000000..d95b1df6cf --- /dev/null +++ b/ThirdParty/Qwt/examples/realtime/scrollzoomer.cpp @@ -0,0 +1,480 @@ +#include +#include +#include +#include +#include +#include "scrollbar.h" +#include "scrollzoomer.h" + +class ScrollData +{ +public: + ScrollData(): + scrollBar( NULL ), + position( ScrollZoomer::OppositeToScale ), + mode( Qt::ScrollBarAsNeeded ) + { + } + + ~ScrollData() + { + delete scrollBar; + } + + ScrollBar *scrollBar; + ScrollZoomer::ScrollBarPosition position; + Qt::ScrollBarPolicy mode; +}; + +ScrollZoomer::ScrollZoomer( QWidget *canvas ): + QwtPlotZoomer( canvas ), + d_cornerWidget( NULL ), + d_hScrollData( NULL ), + d_vScrollData( NULL ), + d_inZoom( false ) +{ + for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ ) + d_alignCanvasToScales[ axis ] = false; + + if ( !canvas ) + return; + + d_hScrollData = new ScrollData; + d_vScrollData = new ScrollData; +} + +ScrollZoomer::~ScrollZoomer() +{ + delete d_cornerWidget; + delete d_vScrollData; + delete d_hScrollData; +} + +void ScrollZoomer::rescale() +{ + QwtScaleWidget *xScale = plot()->axisWidget( xAxis() ); + QwtScaleWidget *yScale = plot()->axisWidget( yAxis() ); + + if ( zoomRectIndex() <= 0 ) + { + if ( d_inZoom ) + { + xScale->setMinBorderDist( 0, 0 ); + yScale->setMinBorderDist( 0, 0 ); + + QwtPlotLayout *layout = plot()->plotLayout(); + + for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ ) + layout->setAlignCanvasToScale( axis, d_alignCanvasToScales ); + + d_inZoom = false; + } + } + else + { + if ( !d_inZoom ) + { + /* + We set a minimum border distance. + Otherwise the canvas size changes when scrolling, + between situations where the major ticks are at + the canvas borders (requiring extra space for the label) + and situations where all labels can be painted below/top + or left/right of the canvas. + */ + int start, end; + + xScale->getBorderDistHint( start, end ); + xScale->setMinBorderDist( start, end ); + + yScale->getBorderDistHint( start, end ); + yScale->setMinBorderDist( start, end ); + + QwtPlotLayout *layout = plot()->plotLayout(); + for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ ) + { + d_alignCanvasToScales[axis] = + layout->alignCanvasToScale( axis ); + } + + layout->setAlignCanvasToScales( false ); + + d_inZoom = true; + } + } + + QwtPlotZoomer::rescale(); + updateScrollBars(); +} + +ScrollBar *ScrollZoomer::scrollBar( Qt::Orientation orientation ) +{ + ScrollBar *&sb = ( orientation == Qt::Vertical ) + ? d_vScrollData->scrollBar : d_hScrollData->scrollBar; + + if ( sb == NULL ) + { + sb = new ScrollBar( orientation, canvas() ); + sb->hide(); + connect( sb, + SIGNAL( valueChanged( Qt::Orientation, double, double ) ), + SLOT( scrollBarMoved( Qt::Orientation, double, double ) ) ); + } + return sb; +} + +ScrollBar *ScrollZoomer::horizontalScrollBar() const +{ + return d_hScrollData->scrollBar; +} + +ScrollBar *ScrollZoomer::verticalScrollBar() const +{ + return d_vScrollData->scrollBar; +} + +void ScrollZoomer::setHScrollBarMode( Qt::ScrollBarPolicy mode ) +{ + if ( hScrollBarMode() != mode ) + { + d_hScrollData->mode = mode; + updateScrollBars(); + } +} + +void ScrollZoomer::setVScrollBarMode( Qt::ScrollBarPolicy mode ) +{ + if ( vScrollBarMode() != mode ) + { + d_vScrollData->mode = mode; + updateScrollBars(); + } +} + +Qt::ScrollBarPolicy ScrollZoomer::hScrollBarMode() const +{ + return d_hScrollData->mode; +} + +Qt::ScrollBarPolicy ScrollZoomer::vScrollBarMode() const +{ + return d_vScrollData->mode; +} + +void ScrollZoomer::setHScrollBarPosition( ScrollBarPosition pos ) +{ + if ( d_hScrollData->position != pos ) + { + d_hScrollData->position = pos; + updateScrollBars(); + } +} + +void ScrollZoomer::setVScrollBarPosition( ScrollBarPosition pos ) +{ + if ( d_vScrollData->position != pos ) + { + d_vScrollData->position = pos; + updateScrollBars(); + } +} + +ScrollZoomer::ScrollBarPosition ScrollZoomer::hScrollBarPosition() const +{ + return d_hScrollData->position; +} + +ScrollZoomer::ScrollBarPosition ScrollZoomer::vScrollBarPosition() const +{ + return d_vScrollData->position; +} + +void ScrollZoomer::setCornerWidget( QWidget *w ) +{ + if ( w != d_cornerWidget ) + { + if ( canvas() ) + { + delete d_cornerWidget; + d_cornerWidget = w; + if ( d_cornerWidget->parent() != canvas() ) + d_cornerWidget->setParent( canvas() ); + + updateScrollBars(); + } + } +} + +QWidget *ScrollZoomer::cornerWidget() const +{ + return d_cornerWidget; +} + +bool ScrollZoomer::eventFilter( QObject *object, QEvent *event ) +{ + if ( object == canvas() ) + { + switch( event->type() ) + { + case QEvent::Resize: + { + int left, top, right, bottom; + canvas()->getContentsMargins( &left, &top, &right, &bottom ); + + QRect rect; + rect.setSize( static_cast( event )->size() ); + rect.adjust( left, top, -right, -bottom ); + + layoutScrollBars( rect ); + break; + } + case QEvent::ChildRemoved: + { + const QObject *child = + static_cast( event )->child(); + + if ( child == d_cornerWidget ) + d_cornerWidget = NULL; + else if ( child == d_hScrollData->scrollBar ) + d_hScrollData->scrollBar = NULL; + else if ( child == d_vScrollData->scrollBar ) + d_vScrollData->scrollBar = NULL; + break; + } + default: + break; + } + } + return QwtPlotZoomer::eventFilter( object, event ); +} + +bool ScrollZoomer::needScrollBar( Qt::Orientation orientation ) const +{ + Qt::ScrollBarPolicy mode; + double zoomMin, zoomMax, baseMin, baseMax; + + if ( orientation == Qt::Horizontal ) + { + mode = d_hScrollData->mode; + baseMin = zoomBase().left(); + baseMax = zoomBase().right(); + zoomMin = zoomRect().left(); + zoomMax = zoomRect().right(); + } + else + { + mode = d_vScrollData->mode; + baseMin = zoomBase().top(); + baseMax = zoomBase().bottom(); + zoomMin = zoomRect().top(); + zoomMax = zoomRect().bottom(); + } + + bool needed = false; + switch( mode ) + { + case Qt::ScrollBarAlwaysOn: + needed = true; + break; + case Qt::ScrollBarAlwaysOff: + needed = false; + break; + default: + { + if ( baseMin < zoomMin || baseMax > zoomMax ) + needed = true; + break; + } + } + return needed; +} + +void ScrollZoomer::updateScrollBars() +{ + if ( !canvas() ) + return; + + const int xAxis = QwtPlotZoomer::xAxis(); + const int yAxis = QwtPlotZoomer::yAxis(); + + int xScrollBarAxis = xAxis; + if ( hScrollBarPosition() == OppositeToScale ) + xScrollBarAxis = oppositeAxis( xScrollBarAxis ); + + int yScrollBarAxis = yAxis; + if ( vScrollBarPosition() == OppositeToScale ) + yScrollBarAxis = oppositeAxis( yScrollBarAxis ); + + + QwtPlotLayout *layout = plot()->plotLayout(); + + bool showHScrollBar = needScrollBar( Qt::Horizontal ); + if ( showHScrollBar ) + { + ScrollBar *sb = scrollBar( Qt::Horizontal ); + sb->setPalette( plot()->palette() ); + sb->setInverted( !plot()->axisScaleDiv( xAxis ).isIncreasing() ); + sb->setBase( zoomBase().left(), zoomBase().right() ); + sb->moveSlider( zoomRect().left(), zoomRect().right() ); + + if ( !sb->isVisibleTo( canvas() ) ) + { + sb->show(); + layout->setCanvasMargin( layout->canvasMargin( xScrollBarAxis ) + + sb->extent(), xScrollBarAxis ); + } + } + else + { + if ( horizontalScrollBar() ) + { + horizontalScrollBar()->hide(); + layout->setCanvasMargin( layout->canvasMargin( xScrollBarAxis ) + - horizontalScrollBar()->extent(), xScrollBarAxis ); + } + } + + bool showVScrollBar = needScrollBar( Qt::Vertical ); + if ( showVScrollBar ) + { + ScrollBar *sb = scrollBar( Qt::Vertical ); + sb->setPalette( plot()->palette() ); + sb->setInverted( !plot()->axisScaleDiv( yAxis ).isIncreasing() ); + sb->setBase( zoomBase().top(), zoomBase().bottom() ); + sb->moveSlider( zoomRect().top(), zoomRect().bottom() ); + + if ( !sb->isVisibleTo( canvas() ) ) + { + sb->show(); + layout->setCanvasMargin( layout->canvasMargin( yScrollBarAxis ) + + sb->extent(), yScrollBarAxis ); + } + } + else + { + if ( verticalScrollBar() ) + { + verticalScrollBar()->hide(); + layout->setCanvasMargin( layout->canvasMargin( yScrollBarAxis ) + - verticalScrollBar()->extent(), yScrollBarAxis ); + } + } + + if ( showHScrollBar && showVScrollBar ) + { + if ( d_cornerWidget == NULL ) + { + d_cornerWidget = new QWidget( canvas() ); + d_cornerWidget->setAutoFillBackground( true ); + d_cornerWidget->setPalette( plot()->palette() ); + } + d_cornerWidget->show(); + } + else + { + if ( d_cornerWidget ) + d_cornerWidget->hide(); + } + + layoutScrollBars( canvas()->contentsRect() ); + plot()->updateLayout(); +} + +void ScrollZoomer::layoutScrollBars( const QRect &rect ) +{ + int hPos = xAxis(); + if ( hScrollBarPosition() == OppositeToScale ) + hPos = oppositeAxis( hPos ); + + int vPos = yAxis(); + if ( vScrollBarPosition() == OppositeToScale ) + vPos = oppositeAxis( vPos ); + + ScrollBar *hScrollBar = horizontalScrollBar(); + ScrollBar *vScrollBar = verticalScrollBar(); + + const int hdim = hScrollBar ? hScrollBar->extent() : 0; + const int vdim = vScrollBar ? vScrollBar->extent() : 0; + + if ( hScrollBar && hScrollBar->isVisible() ) + { + int x = rect.x(); + int y = ( hPos == QwtPlot::xTop ) + ? rect.top() : rect.bottom() - hdim + 1; + int w = rect.width(); + + if ( vScrollBar && vScrollBar->isVisible() ) + { + if ( vPos == QwtPlot::yLeft ) + x += vdim; + w -= vdim; + } + + hScrollBar->setGeometry( x, y, w, hdim ); + } + if ( vScrollBar && vScrollBar->isVisible() ) + { + int pos = yAxis(); + if ( vScrollBarPosition() == OppositeToScale ) + pos = oppositeAxis( pos ); + + int x = ( vPos == QwtPlot::yLeft ) + ? rect.left() : rect.right() - vdim + 1; + int y = rect.y(); + + int h = rect.height(); + + if ( hScrollBar && hScrollBar->isVisible() ) + { + if ( hPos == QwtPlot::xTop ) + y += hdim; + + h -= hdim; + } + + vScrollBar->setGeometry( x, y, vdim, h ); + } + if ( hScrollBar && hScrollBar->isVisible() && + vScrollBar && vScrollBar->isVisible() ) + { + if ( d_cornerWidget ) + { + QRect cornerRect( + vScrollBar->pos().x(), hScrollBar->pos().y(), + vdim, hdim ); + d_cornerWidget->setGeometry( cornerRect ); + } + } +} + +void ScrollZoomer::scrollBarMoved( + Qt::Orientation o, double min, double max ) +{ + Q_UNUSED( max ); + + if ( o == Qt::Horizontal ) + moveTo( QPointF( min, zoomRect().top() ) ); + else + moveTo( QPointF( zoomRect().left(), min ) ); + + Q_EMIT zoomed( zoomRect() ); +} + +int ScrollZoomer::oppositeAxis( int axis ) const +{ + switch( axis ) + { + case QwtPlot::xBottom: + return QwtPlot::xTop; + case QwtPlot::xTop: + return QwtPlot::xBottom; + case QwtPlot::yLeft: + return QwtPlot::yRight; + case QwtPlot::yRight: + return QwtPlot::yLeft; + default: + break; + } + + return axis; +} diff --git a/ThirdParty/Qwt/examples/realtime/scrollzoomer.h b/ThirdParty/Qwt/examples/realtime/scrollzoomer.h new file mode 100644 index 0000000000..d46c10dce5 --- /dev/null +++ b/ThirdParty/Qwt/examples/realtime/scrollzoomer.h @@ -0,0 +1,67 @@ +#ifndef _SCROLLZOOMER_H +#define _SCROLLZOOMER_H + +#include +#include +#include + +class ScrollData; +class ScrollBar; + +class ScrollZoomer: public QwtPlotZoomer +{ + Q_OBJECT +public: + enum ScrollBarPosition + { + AttachedToScale, + OppositeToScale + }; + + ScrollZoomer( QWidget * ); + virtual ~ScrollZoomer(); + + ScrollBar *horizontalScrollBar() const; + ScrollBar *verticalScrollBar() const; + + void setHScrollBarMode( Qt::ScrollBarPolicy ); + void setVScrollBarMode( Qt::ScrollBarPolicy ); + + Qt::ScrollBarPolicy vScrollBarMode () const; + Qt::ScrollBarPolicy hScrollBarMode () const; + + void setHScrollBarPosition( ScrollBarPosition ); + void setVScrollBarPosition( ScrollBarPosition ); + + ScrollBarPosition hScrollBarPosition() const; + ScrollBarPosition vScrollBarPosition() const; + + QWidget* cornerWidget() const; + virtual void setCornerWidget( QWidget * ); + + virtual bool eventFilter( QObject *, QEvent * ); + + virtual void rescale(); + +protected: + virtual ScrollBar *scrollBar( Qt::Orientation ); + virtual void updateScrollBars(); + virtual void layoutScrollBars( const QRect & ); + +private Q_SLOTS: + void scrollBarMoved( Qt::Orientation o, double min, double max ); + +private: + bool needScrollBar( Qt::Orientation ) const; + int oppositeAxis( int ) const; + + QWidget *d_cornerWidget; + + ScrollData *d_hScrollData; + ScrollData *d_vScrollData; + + bool d_inZoom; + bool d_alignCanvasToScales[ QwtPlot::axisCnt ]; +}; + +#endif diff --git a/ThirdParty/Qwt/examples/realtime/start.xpm b/ThirdParty/Qwt/examples/realtime/start.xpm new file mode 100644 index 0000000000..62146842ad --- /dev/null +++ b/ThirdParty/Qwt/examples/realtime/start.xpm @@ -0,0 +1,266 @@ +/* XPM */ +static const char *start_xpm[] = { +/* width height num_colors chars_per_pixel */ +" 32 32 227 2", +/* colors */ +".. c #040204", +".# c #848684", +".a c #c4c2b4", +".b c #843a04", +".c c #444244", +".d c #ece2cc", +".e c #fca234", +".f c #c45e04", +".g c #bca27c", +".h c #646264", +".i c #e4c69c", +".j c #847254", +".k c #c4a684", +".l c #443e34", +".m c #a48e6c", +".n c #f4f2e4", +".o c #24261c", +".p c #a44a04", +".q c #c4825c", +".r c #644634", +".s c #b4b2ac", +".t c #747274", +".u c #844e2c", +".v c #ece6dc", +".w c #c4b6a4", +".x c #a49274", +".y c #343634", +".z c #fcd69c", +".A c #b4aa9c", +".B c #8c8e8c", +".C c #545254", +".D c #f4f2ec", +".E c #fcb67c", +".F c #e4965c", +".G c #e46634", +".H c #141614", +".I c #d4c2a4", +".J c #746a5c", +".K c #fcc2a4", +".L c #342a1c", +".M c #fc9204", +".N c #a45e2c", +".O c #94521c", +".P c #a4560c", +".Q c #645e54", +".R c #ec7a04", +".S c #f4deac", +".T c #5c462c", +".U c #bcaa8c", +".V c #d4be9c", +".W c #fcfaf4", +".X c #d4cab4", +".Y c #1c0a04", +".Z c #6c6a6c", +".0 c #e4caa4", +".1 c #2c2a1c", +".2 c #74462c", +".3 c #84562c", +".4 c #f4eee4", +".5 c #c4beb4", +".6 c #a49a84", +".7 c #f4ba7c", +".8 c #dc966c", +".9 c #948674", +"#. c #fc8a04", +"## c #f4eab4", +"#a c #fcb26c", +"#b c #c4ae94", +"#c c #f4e6d4", +"#d c #9c8e74", +"#e c #fc7e04", +"#f c #140604", +"#g c #b4a28c", +"#h c #6c625c", +"#i c #8c7e64", +"#j c #f4ae84", +"#k c #e4decc", +"#l c #ac5204", +"#m c #e48a4c", +"#n c #7c7a7c", +"#o c #ccba9c", +"#p c #fcd2b4", +"#q c #bcae9c", +"#r c #dcc6a4", +"#s c #ac723c", +"#t c #e4ceb4", +"#u c #ec9e74", +"#v c #8c8a8c", +"#w c #8c4204", +"#x c #4c4a34", +"#y c #7c3a04", +"#z c #fcfecc", +"#A c #2c221c", +"#B c #ac4e04", +"#C c #d48264", +"#D c #bcb2a4", +"#E c #a49684", +"#F c #b4aeac", +"#G c #5c5a5c", +"#H c #fcf2ec", +"#I c #fcb28c", +"#J c #7c6e5c", +"#K c #fcce9c", +"#L c #3c2e24", +"#M c #bc9e71", +"#N c #fc922c", +"#O c #bc622c", +"#P c #b45604", +"#Q c #f47a08", +"#R c #fcdeb8", +"#S c #544e44", +"#T c #fcfefc", +"#U c #e4ceaa", +"#V c #8c5a2c", +"#W c #e49e7c", +"#X c #f4eadb", +"#Y c #9c9284", +"#Z c #f4ae90", +"#0 c #c47e5c", +"#1 c #bc824c", +"#2 c #e47634", +"#3 c #e46e24", +"#4 c #b48e6c", +"#5 c #7c5a4c", +"#6 c #744e2c", +"#7 c #fcba9c", +"#8 c #cccacc", +"#9 c #f4722c", +"a. c #c46224", +"a# c #e47a54", +"aa c #ac663c", +"ab c #fce2cc", +"ac c #945634", +"ad c #fceacc", +"ae c #3c3e3c", +"af c #ec9e54", +"ag c #843e1c", +"ah c #fccab0", +"ai c #8c8274", +"aj c #4c4634", +"ak c #ecc2ac", +"al c #8c765c", +"am c #7c7264", +"an c #e49a7c", +"ao c #6c4e34", +"ap c #fc9a2c", +"aq c #4c4a4c", +"ar c #ccbea4", +"as c #fcf6dc", +"at c #3c3a3c", +"au c #949294", +"av c #fceebc", +"aw c #fcaa7c", +"ax c #ecdac8", +"ay c #0c0604", +"az c #fc8204", +"aA c #847664", +"aB c #e4d6c4", +"aC c #fcd2ac", +"aD c #1c1a14", +"aE c #342e2c", +"aF c #240e04", +"aG c #2c2e2c", +"aH c #fcbe7c", +"aI c #fc8e14", +"aJ c #fc7a14", +"aK c #944604", +"aL c #7c3e14", +"aM c #fcfadc", +"aN c #645244", +"aO c #bcb6b4", +"aP c #bc5604", +"aQ c #7c522c", +"aR c #cc8264", +"aS c #dccab0", +"aT c #ac9a84", +"aU c #f4e2cc", +"aV c #a45e3c", +"aW c #9c5634", +"aX c #fca634", +"aY c #c4aa89", +"aZ c #a44e07", +"a0 c #b4b6b4", +"a1 c #c4baa9", +"a2 c #a4967c", +"a3 c #b4aea4", +"a4 c #d4c6a8", +"a5 c #5c4a34", +"a6 c #bcae94", +"a7 c #845a2c", +"a8 c #948a7c", +"a9 c #c4b299", +"b. c #b4a690", +"b# c #6c6658", +"ba c #fcd6b4", +"bb c #2c261d", +"bc c #fcf6f0", +"bd c #fcb694", +"be c #fc9624", +"bf c #646664", +"bg c #747674", +"bh c #eceadc", +"bi c #545654", +"bj c #b49e7c", +"bk c #6c6e6c", +"bl c #fc8e04", +"bm c #fcb66c", +"bn c #7c7e7c", +"bo c #5c5e5c", +"bp c #8c8674", +"bq c #fc8604", +"br c #bc5a04", +"bs c #fca23c", +"bt c #443e3c", +"bu c #a4927c", +"bv c #b4aaa4", +"bw c #746a64", +"bx c #342a24", +"by c #fcfafc", +"bz c #2c2a24", +"bA c #a49a8c", +"bB c #bcbabc", +"bC c #9c8e7c", +"bD c #8c7e6c", +"bE c #ccbaa4", +"bF c #fcd2bc", +"bG c #fcb294", +/* pixels */ +"#Gbi#G.#bnbg.t.Zbfbf.hbo#G.Caqaq.c.C.C.C.C.C.C.C.C.C.C.Cbi#Gbi#G", +"#Gbi#Gbg#8#8.a#8#8#8#8#8#8#8#8.B#8#8#8#8#8#8#8#8#8#8#8.C#Gbi#Gbi", +"bi#Gbi#n#8#T#T#T#T#T#T#T#T#T#TbB#T#T#T#T#T#T#T#T#T#T#8aq#6afbm#z", +"#Gbi#Gbk#8#T#T#T#T#T#T#T#T#T#TbB#T#T#T#T#T#T#T#T#T#T#8#6af#aavaX", +"bi#Gbibk#8#T#T#T#T#T#T#T#T#T#TbB#T#T#T#T#T#T#T#T#T#T#6af#a##aX#.", +"#Gbi#Gbk#8#T#T#T#T#T#T#T#T#T#TbB#T#T#T#T#T#T#T#T#T.3af#a.S.e#.bq", +"#Gbi#G.Z#8#T#T#T#T#T#T#T#T#T#TbB#T#T#T#T#T#T#T#TaQaf#a#R.e#eazbq", +"bi#GbibkaubBbBbBbBbBbBbBbBbBbBbBbBbBbBbBbBbBbBa7af#aba.e#eazbq.M", +"#Gbi#G.Z#8#T#T#T#T#T#T#T#T#T#TbB#T#T#T#T#T#T#Vaf#ababs#ebqbq#.az", +"#Gbi#Gbf#8#T#T#T#T#T#T#T#T#T#TbB#T#T#Tby#T#saf#a#Kap#ebqbqbl#Q.f", +"bi#Gbi.Z#8#T#T#T#T#T#T#T#T#T#TbB#T#T#T#T.Naf#a.z#N#ebqbqbl.R.f#l", +"#Gbi#Gbf#8#T#T#T#T#T#T#T#T#T#TbB#T#T#T#1af.EaHbe#ebqbq#..Rbr#B#y", +"bi#Gbibf#8#T#T#T#T#T#T#T#T#T#TbB#T#T.F.7#jawaI#ebqbqbl.R#PaZ.b..", +"#Gbi#GbfaubBbBbBbBbBbBbBbBbBbBbBbBbG#RaMak#m#ebqbqbl#Q#P#B#w.Y.y", +"bi#Gbibf#8#T#T#T#T#T#T#T#T#T#TaObyaC.Wab#Z#2bqbq.M.RaP.p#way.y.y", +"#Gbi#G.h#8#T#T#T#T#T#T#T#T#Tbya0#I#Tad.K#j#2#QaJ.Rbr.p#yaF.y.yat", +"bi#Gbi.h#8#T#T#T#T#T#T#T#Tby.W.saCasba#Za#.G#9#3aPaZaK.Y.y.yat.c", +"#Gbi#Gbo#8#T#T#T#T#T#T#Tby.Wbc#I#T#p#7.8#0a.#O.P.paLay...yatbtaq", +"bi#Gbi.h#8#T#T#T#T#T#Tby.Wbc.DaCadah#W#0aa.O.2.ragaF#h..ataeaq.C", +"#Gbi#GboaubBbBbBbBbBaOa0.sa3bdasahanaRaV.u.Ta5ae#f.Q#S..aeaq.Cbi", +"bi#Gbibo#8#T#T#T#T.Wbcbc.D#HaCbF#uaRaWaQa5ajbt.HbDai#J..aq.Cbibi", +"#Gbi#Gbo#8#T#Tby.W.W.D#H.nbdab#u#Cac.uaN.o..bDaiaia8#i...Cbibi#G", +"bi#Gbibo#8#T#Tbybc.Dbc.n.4#4.8.q#5.r.l..#vbDaia8a2#g#d..bibi#Gbi", +"#Gbi#G#G#8#T.Wbc.D#H.D#X.j.Lao#5#L.H#vaibpbpbCaT.U#oa2..bi#Gbi#G", +"bi#Gbi#G#8.Wbc.D#H.n.4bjajaD#A...#bpai.9bC#E#ga9.V#r.gbb#Gbi#Gbi", +"#Gbi#Gbiaua0.s.s#Fa3bvaG....#vbwb#b#.JbwaA#i.9bC.m.xal.1bi#Gbi#G", +"bi#Gbi#G#8.D#H.4.4#X.v#x#v#qbAb##Y.6b.a6ar.I#r#r.0.i.g.Lbi#Gbi#G", +"bi#Gbibi#8.D.4.4#X#c.vax.X.AbAamb.#D#oa4aS#r.0.0.i.i#M#A#Gbi#Gbi", +"#Gbi#G.C#8.n.4#X#X.daUaBaS.wa6aiar#raS.0#U#U.0.i.0#r#Mbb#Gbi#Gbi", +"bi#Gbiaq#8.4#Xbh.v#c.d#kaB.Xa4buaS#U#t#U#U.0.0#r.i.i#Mbbbi#Gbi#G", +"#Gbi#Gae.a.a.5a1bE.w.w.w#ba6.U#iaYaYaY.k.g.g.g#M#M#M#M.Lbi#Gbi#G", +"bi#Gbi.HbxaEbxaEbz.LaEbzbzbbbzbbbbbxbb.Lbbbb.1.Lbb.1#Aay#Gbi#Gbi" +}; diff --git a/ThirdParty/Qwt/examples/refreshtest/circularbuffer.cpp b/ThirdParty/Qwt/examples/refreshtest/circularbuffer.cpp new file mode 100644 index 0000000000..1fec47243c --- /dev/null +++ b/ThirdParty/Qwt/examples/refreshtest/circularbuffer.cpp @@ -0,0 +1,73 @@ +#include "circularbuffer.h" +#include + +CircularBuffer::CircularBuffer( double interval, size_t numPoints ): + d_y( NULL ), + d_referenceTime( 0.0 ), + d_startIndex( 0 ), + d_offset( 0.0 ) +{ + fill( interval, numPoints ); +} + +void CircularBuffer::fill( double interval, size_t numPoints ) +{ + if ( interval <= 0.0 || numPoints < 2 ) + return; + + d_values.resize( numPoints ); + d_values.fill( 0.0 ); + + if ( d_y ) + { + d_step = interval / ( numPoints - 2 ); + for ( size_t i = 0; i < numPoints; i++ ) + d_values[i] = d_y( i * d_step ); + } + + d_interval = interval; +} + +void CircularBuffer::setFunction( double( *y )( double ) ) +{ + d_y = y; +} + +void CircularBuffer::setReferenceTime( double timeStamp ) +{ + d_referenceTime = timeStamp; + + const double startTime = ::fmod( d_referenceTime, d_values.size() * d_step ); + + d_startIndex = int( startTime / d_step ); // floor + d_offset = ::fmod( startTime, d_step ); +} + +double CircularBuffer::referenceTime() const +{ + return d_referenceTime; +} + +size_t CircularBuffer::size() const +{ + return d_values.size(); +} + +QPointF CircularBuffer::sample( size_t i ) const +{ + const int size = d_values.size(); + + int index = d_startIndex + i; + if ( index >= size ) + index -= size; + + const double x = i * d_step - d_offset - d_interval; + const double y = d_values.data()[index]; + + return QPointF( x, y ); +} + +QRectF CircularBuffer::boundingRect() const +{ + return QRectF( -1.0, -d_interval, 2.0, d_interval ); +} \ No newline at end of file diff --git a/ThirdParty/Qwt/examples/refreshtest/circularbuffer.h b/ThirdParty/Qwt/examples/refreshtest/circularbuffer.h new file mode 100644 index 0000000000..eae1a9f26a --- /dev/null +++ b/ThirdParty/Qwt/examples/refreshtest/circularbuffer.h @@ -0,0 +1,35 @@ +#ifndef _CIRCULAR_BUFFER_H_ +#define _CIRCULAR_BUFFER_H_ + +#include +#include + +class CircularBuffer: public QwtSeriesData +{ +public: + CircularBuffer( double interval = 10.0, size_t numPoints = 1000 ); + void fill( double interval, size_t numPoints ); + + void setReferenceTime( double ); + double referenceTime() const; + + virtual size_t size() const; + virtual QPointF sample( size_t i ) const; + + virtual QRectF boundingRect() const; + + void setFunction( double( *y )( double ) ); + +private: + double ( *d_y )( double ); + + double d_referenceTime; + double d_interval; + QVector d_values; + + double d_step; + int d_startIndex; + double d_offset; +}; + +#endif diff --git a/ThirdParty/Qwt/examples/refreshtest/main.cpp b/ThirdParty/Qwt/examples/refreshtest/main.cpp new file mode 100644 index 0000000000..0a306848ec --- /dev/null +++ b/ThirdParty/Qwt/examples/refreshtest/main.cpp @@ -0,0 +1,30 @@ +#include "mainwindow.h" +#include + +#ifndef QWT_NO_OPENGL +#if QT_VERSION >= 0x040600 && QT_VERSION < 0x050000 +#define USE_OPENGL 1 +#endif +#endif + +#if USE_OPENGL +#include +#endif + +int main( int argc, char **argv ) +{ +#if USE_OPENGL + // on my box QPaintEngine::OpenGL2 has serious problems, f.e: + // the lines of a simple drawRect are wrong. + + QGL::setPreferredPaintEngine( QPaintEngine::OpenGL ); +#endif + + QApplication a( argc, argv ); + + MainWindow mainWindow; + mainWindow.resize( 600, 400 ); + mainWindow.show(); + + return a.exec(); +} diff --git a/ThirdParty/Qwt/examples/refreshtest/mainwindow.cpp b/ThirdParty/Qwt/examples/refreshtest/mainwindow.cpp new file mode 100644 index 0000000000..c3df4cfd52 --- /dev/null +++ b/ThirdParty/Qwt/examples/refreshtest/mainwindow.cpp @@ -0,0 +1,76 @@ +#include +#include +#include +#include +#include +#include +#include "panel.h" +#include "plot.h" +#include "mainwindow.h" + +MainWindow::MainWindow( QWidget *parent ): + QMainWindow( parent ) +{ + QWidget *w = new QWidget( this ); + + d_panel = new Panel( w ); + + d_plot = new Plot( w ); + + QHBoxLayout *hLayout = new QHBoxLayout( w ); + hLayout->addWidget( d_panel ); + hLayout->addWidget( d_plot, 10 ); + + setCentralWidget( w ); + + d_frameCount = new QLabel( this ); + statusBar()->addWidget( d_frameCount, 10 ); + + applySettings( d_panel->settings() ); + + connect( d_panel, SIGNAL( settingsChanged( const Settings & ) ), + this, SLOT( applySettings( const Settings & ) ) ); +} + +bool MainWindow::eventFilter( QObject *object, QEvent *event ) +{ + if ( object == d_plot->canvas() && event->type() == QEvent::Paint ) + { + static int counter; + static QTime timeStamp; + + if ( !timeStamp.isValid() ) + { + timeStamp.start(); + counter = 0; + } + else + { + counter++; + + const double elapsed = timeStamp.elapsed() / 1000.0; + if ( elapsed >= 1 ) + { + QString fps; + fps.setNum( qRound( counter / elapsed ) ); + fps += " Fps"; + + d_frameCount->setText( fps ); + + counter = 0; + timeStamp.start(); + } + } + } + + return QMainWindow::eventFilter( object, event ); +} + +void MainWindow::applySettings( const Settings &settings ) +{ + d_plot->setSettings( settings ); + + // the canvas might have been recreated + d_plot->canvas()->removeEventFilter( this ); + d_plot->canvas()->installEventFilter( this ); +} diff --git a/ThirdParty/Qwt/examples/refreshtest/mainwindow.h b/ThirdParty/Qwt/examples/refreshtest/mainwindow.h new file mode 100644 index 0000000000..47d10bd795 --- /dev/null +++ b/ThirdParty/Qwt/examples/refreshtest/mainwindow.h @@ -0,0 +1,28 @@ +#ifndef _MAIN_WINDOW_H_ +#define _MAIN_WINDOW_H_ + +#include + +class Plot; +class Panel; +class QLabel; +class Settings; + +class MainWindow: public QMainWindow +{ + Q_OBJECT + +public: + MainWindow( QWidget *parent = NULL ); + virtual bool eventFilter( QObject *, QEvent * ); + +private Q_SLOTS: + void applySettings( const Settings & ); + +private: + Plot *d_plot; + Panel *d_panel; + QLabel *d_frameCount; +}; + +#endif diff --git a/ThirdParty/Qwt/examples/refreshtest/panel.cpp b/ThirdParty/Qwt/examples/refreshtest/panel.cpp new file mode 100644 index 0000000000..4189998c24 --- /dev/null +++ b/ThirdParty/Qwt/examples/refreshtest/panel.cpp @@ -0,0 +1,297 @@ +#include "panel.h" +#include +#include +#include +#include +#include +#include + +class SpinBox: public QSpinBox +{ +public: + SpinBox( int min, int max, int step, QWidget *parent ): + QSpinBox( parent ) + { + setRange( min, max ); + setSingleStep( step ); + } +}; + +class CheckBox: public QCheckBox +{ +public: + CheckBox( const QString &title, QWidget *parent ): + QCheckBox( title, parent ) + { + } + + void setChecked( bool checked ) + { + setCheckState( checked ? Qt::Checked : Qt::Unchecked ); + } + + bool isChecked() const + { + return checkState() == Qt::Checked; + } +}; + +Panel::Panel( QWidget *parent ): + QTabWidget( parent ) +{ + setTabPosition( QTabWidget::West ); + + addTab( createPlotTab( this ), "Plot" ); + addTab( createCanvasTab( this ), "Canvas" ); + addTab( createCurveTab( this ), "Curve" ); + + setSettings( Settings() ); + + connect( d_numPoints, SIGNAL( valueChanged( int ) ), SLOT( edited() ) ); + connect( d_updateInterval, SIGNAL( valueChanged( int ) ), SLOT( edited() ) ); + connect( d_curveWidth, SIGNAL( valueChanged( int ) ), SLOT( edited() ) ); + + connect( d_paintCache, SIGNAL( stateChanged( int ) ), SLOT( edited() ) ); + connect( d_paintOnScreen, SIGNAL( stateChanged( int ) ), SLOT( edited() ) ); + connect( d_immediatePaint, SIGNAL( stateChanged( int ) ), SLOT( edited() ) ); +#ifndef QWT_NO_OPENGL + connect( d_openGL, SIGNAL( stateChanged( int ) ), SLOT( edited() ) ); +#endif + + connect( d_curveAntialiasing, SIGNAL( stateChanged( int ) ), SLOT( edited() ) ); + connect( d_curveClipping, SIGNAL( stateChanged( int ) ), SLOT( edited() ) ); + connect( d_curveFiltering, SIGNAL( stateChanged( int ) ), SLOT( edited() ) ); + connect( d_lineSplitting, SIGNAL( stateChanged( int ) ), SLOT( edited() ) ); + connect( d_curveFilled, SIGNAL( stateChanged( int ) ), SLOT( edited() ) ); + + connect( d_updateType, SIGNAL( currentIndexChanged( int ) ), SLOT( edited() ) ); + connect( d_gridStyle, SIGNAL( currentIndexChanged( int ) ), SLOT( edited() ) ); + connect( d_curveType, SIGNAL( currentIndexChanged( int ) ), SLOT( edited() ) ); + connect( d_curvePen, SIGNAL( currentIndexChanged( int ) ), SLOT( edited() ) ); +} + +QWidget *Panel::createPlotTab( QWidget *parent ) +{ + QWidget *page = new QWidget( parent ); + + d_updateInterval = new SpinBox( 0, 1000, 10, page ); + d_numPoints = new SpinBox( 10, 1000000, 1000, page ); + + d_updateType = new QComboBox( page ); + d_updateType->addItem( "Repaint" ); + d_updateType->addItem( "Replot" ); + + int row = 0; + + QGridLayout *layout = new QGridLayout( page ); + + layout->addWidget( new QLabel( "Updates", page ), row, 0 ); + layout->addWidget( d_updateInterval, row, 1 ); + layout->addWidget( new QLabel( "ms", page ), row++, 2 ); + + layout->addWidget( new QLabel( "Points", page ), row, 0 ); + layout->addWidget( d_numPoints, row++, 1 ); + + layout->addWidget( new QLabel( "Update", page ), row, 0 ); + layout->addWidget( d_updateType, row++, 1 ); + + layout->addLayout( new QHBoxLayout(), row++, 0 ); + + layout->setColumnStretch( 1, 10 ); + layout->setRowStretch( row, 10 ); + + return page; +} + +QWidget *Panel::createCanvasTab( QWidget *parent ) +{ + QWidget *page = new QWidget( parent ); + + d_gridStyle = new QComboBox( page ); + d_gridStyle->addItem( "None" ); + d_gridStyle->addItem( "Solid" ); + d_gridStyle->addItem( "Dashes" ); + + d_paintCache = new CheckBox( "Paint Cache", page ); + d_paintOnScreen = new CheckBox( "Paint On Screen", page ); + d_immediatePaint = new CheckBox( "Immediate Paint", page ); +#ifndef QWT_NO_OPENGL + d_openGL = new CheckBox( "OpenGL", page ); +#endif + + int row = 0; + + QGridLayout *layout = new QGridLayout( page ); + layout->addWidget( new QLabel( "Grid", page ), row, 0 ); + layout->addWidget( d_gridStyle, row++, 1 ); + + layout->addWidget( d_paintCache, row++, 0, 1, -1 ); + layout->addWidget( d_paintOnScreen, row++, 0, 1, -1 ); + layout->addWidget( d_immediatePaint, row++, 0, 1, -1 ); +#ifndef QWT_NO_OPENGL + layout->addWidget( d_openGL, row++, 0, 1, -1 ); +#endif + + layout->addLayout( new QHBoxLayout(), row++, 0 ); + + layout->setColumnStretch( 1, 10 ); + layout->setRowStretch( row, 10 ); + + return page; +} + +QWidget *Panel::createCurveTab( QWidget *parent ) +{ + QWidget *page = new QWidget( parent ); + + d_curveType = new QComboBox( page ); + d_curveType->addItem( "Wave" ); + d_curveType->addItem( "Noise" ); + + d_curveAntialiasing = new CheckBox( "Antialiasing", page ); + d_curveClipping = new CheckBox( "Clipping", page ); + d_curveFiltering = new CheckBox( "Filtering", page ); + d_lineSplitting = new CheckBox( "Split Lines", page ); + + d_curveWidth = new SpinBox( 0, 10, 1, page ); + + d_curvePen = new QComboBox( page ); + d_curvePen->addItem( "Solid" ); + d_curvePen->addItem( "Dotted" ); + + d_curveFilled = new CheckBox( "Filled", page ); + + int row = 0; + + QGridLayout *layout = new QGridLayout( page ); + layout->addWidget( new QLabel( "Type", page ), row, 0 ); + layout->addWidget( d_curveType, row++, 1 ); + + layout->addWidget( d_curveAntialiasing, row++, 0, 1, -1 ); + layout->addWidget( d_curveClipping, row++, 0, 1, -1 ); + layout->addWidget( d_curveFiltering, row++, 0, 1, -1 ); + layout->addWidget( d_lineSplitting, row++, 0, 1, -1 ); + + layout->addWidget( new QLabel( "Width", page ), row, 0 ); + layout->addWidget( d_curveWidth, row++, 1 ); + + layout->addWidget( new QLabel( "Style", page ), row, 0 ); + layout->addWidget( d_curvePen, row++, 1 ); + + layout->addWidget( d_curveFilled, row++, 0, 1, -1 ); + + layout->addLayout( new QHBoxLayout(), row++, 0 ); + + layout->setColumnStretch( 1, 10 ); + layout->setRowStretch( row, 10 ); + + return page; +} + +void Panel::edited() +{ + const Settings s = settings(); + Q_EMIT settingsChanged( s ); +} + + +Settings Panel::settings() const +{ + Settings s; + + s.grid.pen = QPen( Qt::black, 0 ); + + switch( d_gridStyle->currentIndex() ) + { + case 0: + s.grid.pen.setStyle( Qt::NoPen ); + break; + case 2: + s.grid.pen.setStyle( Qt::DashLine ); + break; + } + + s.curve.pen.setStyle( d_curvePen->currentIndex() == 0 ? + Qt::SolidLine : Qt::DotLine ); + s.curve.pen.setWidth( d_curveWidth->value() ); + s.curve.brush.setStyle( ( d_curveFilled->isChecked() ) ? + Qt::SolidPattern : Qt::NoBrush ); + s.curve.numPoints = d_numPoints->value(); + s.curve.functionType = static_cast( + d_curveType->currentIndex() ); + if ( d_curveClipping->isChecked() ) + s.curve.paintAttributes |= QwtPlotCurve::ClipPolygons; + else + s.curve.paintAttributes &= ~QwtPlotCurve::ClipPolygons; + if ( d_curveFiltering->isChecked() ) + s.curve.paintAttributes |= QwtPlotCurve::FilterPoints; + else + s.curve.paintAttributes &= ~QwtPlotCurve::FilterPoints; + + if ( d_curveAntialiasing->isChecked() ) + s.curve.renderHint |= QwtPlotItem::RenderAntialiased; + else + s.curve.renderHint &= ~QwtPlotItem::RenderAntialiased; + + s.curve.lineSplitting = ( d_lineSplitting->isChecked() ); + + s.canvas.useBackingStore = ( d_paintCache->isChecked() ); + s.canvas.paintOnScreen = ( d_paintOnScreen->isChecked() ); + s.canvas.immediatePaint = ( d_immediatePaint->isChecked() ); +#ifndef QWT_NO_OPENGL + s.canvas.openGL = ( d_openGL->isChecked() ); +#endif + + s.updateInterval = d_updateInterval->value(); + s.updateType = static_cast( d_updateType->currentIndex() ); + + return s; +} + +void Panel::setSettings( const Settings &s ) +{ + d_numPoints->setValue( s.curve.numPoints ); + d_updateInterval->setValue( s.updateInterval ); + d_updateType->setCurrentIndex( s.updateType ); + + switch( s.grid.pen.style() ) + { + case Qt::NoPen: + { + d_gridStyle->setCurrentIndex( 0 ); + break; + } + case Qt::DashLine: + { + d_gridStyle->setCurrentIndex( 2 ); + break; + } + default: + { + d_gridStyle->setCurrentIndex( 1 ); // Solid + } + } + + d_paintCache->setChecked( s.canvas.useBackingStore ); + d_paintOnScreen->setChecked( s.canvas.paintOnScreen ); + d_immediatePaint->setChecked( s.canvas.immediatePaint ); +#ifndef QWT_NO_OPENGL + d_openGL->setChecked( s.canvas.openGL ); +#endif + + d_curveType->setCurrentIndex( s.curve.functionType ); + d_curveAntialiasing->setChecked( + s.curve.renderHint & QwtPlotCurve::RenderAntialiased ); + + d_curveClipping->setChecked( + s.curve.paintAttributes & QwtPlotCurve::ClipPolygons ); + d_curveFiltering->setChecked( + s.curve.paintAttributes & QwtPlotCurve::FilterPoints ); + + d_lineSplitting->setChecked( s.curve.lineSplitting ); + + d_curveWidth->setValue( s.curve.pen.width() ); + d_curvePen->setCurrentIndex( + s.curve.pen.style() == Qt::SolidLine ? 0 : 1 ); + d_curveFilled->setChecked( s.curve.brush.style() != Qt::NoBrush ); +} diff --git a/ThirdParty/Qwt/examples/refreshtest/panel.h b/ThirdParty/Qwt/examples/refreshtest/panel.h new file mode 100644 index 0000000000..9a0fcc5f3e --- /dev/null +++ b/ThirdParty/Qwt/examples/refreshtest/panel.h @@ -0,0 +1,54 @@ +#ifndef _PANEL_H_ +#define _PANEL_H_ 1 + +#include "settings.h" +#include + +class QComboBox; +class SpinBox; +class CheckBox; + +class Panel: public QTabWidget +{ + Q_OBJECT + +public: + Panel( QWidget * = NULL ); + + Settings settings() const; + void setSettings( const Settings & ); + +Q_SIGNALS: + void settingsChanged( const Settings & ); + +private Q_SLOTS: + void edited(); + +private: + QWidget *createPlotTab( QWidget * ); + QWidget *createCanvasTab( QWidget * ); + QWidget *createCurveTab( QWidget * ); + + SpinBox *d_numPoints; + SpinBox *d_updateInterval; + QComboBox *d_updateType; + + QComboBox *d_gridStyle; + CheckBox *d_paintCache; + CheckBox *d_paintOnScreen; + CheckBox *d_immediatePaint; +#ifndef QWT_NO_OPENGL + CheckBox *d_openGL; +#endif + + QComboBox *d_curveType; + CheckBox *d_curveAntialiasing; + CheckBox *d_curveClipping; + CheckBox *d_curveFiltering; + CheckBox *d_lineSplitting; + SpinBox *d_curveWidth; + QComboBox *d_curvePen; + CheckBox *d_curveFilled; +}; + +#endif diff --git a/ThirdParty/Qwt/examples/refreshtest/plot.cpp b/ThirdParty/Qwt/examples/refreshtest/plot.cpp new file mode 100644 index 0000000000..55a0be311b --- /dev/null +++ b/ThirdParty/Qwt/examples/refreshtest/plot.cpp @@ -0,0 +1,218 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#ifndef QWT_NO_OPENGL +#include +#include +#endif +#include "plot.h" +#include "circularbuffer.h" +#include "settings.h" + +static double wave( double x ) +{ + const double period = 1.0; + const double c = 5.0; + + double v = ::fmod( x, period ); + + const double amplitude = qAbs( x - qRound( x / c ) * c ) / ( 0.5 * c ); + v = amplitude * qSin( v / period * 2 * M_PI ); + + return v; +} + +static double noise( double ) +{ + return 2.0 * ( qrand() / ( static_cast( RAND_MAX ) + 1 ) ) - 1.0; +} + +#ifndef QWT_NO_OPENGL +class GLCanvas: public QwtPlotGLCanvas +{ +public: + GLCanvas( QwtPlot *parent = NULL ): + QwtPlotGLCanvas( parent ) + { + setContentsMargins( 1, 1, 1, 1 ); + } + +protected: + virtual void paintEvent( QPaintEvent *event ) + { + QPainter painter( this ); + painter.setClipRegion( event->region() ); + + QwtPlot *plot = qobject_cast< QwtPlot *>( parent() ); + if ( plot ) + plot->drawCanvas( &painter ); + + painter.setPen( palette().foreground().color() ); + painter.drawRect( rect().adjusted( 0, 0, -1, -1 ) ); + } +}; +#endif + +Plot::Plot( QWidget *parent ): + QwtPlot( parent ), + d_interval( 10.0 ), // seconds + d_timerId( -1 ) +{ + // Assign a title + setTitle( "Testing Refresh Rates" ); + + QwtPlotCanvas *canvas = new QwtPlotCanvas(); + canvas->setFrameStyle( QFrame::Box | QFrame::Plain ); + canvas->setLineWidth( 1 ); + canvas->setPalette( Qt::white ); + + setCanvas( canvas ); + + alignScales(); + + // Insert grid + d_grid = new QwtPlotGrid(); + d_grid->attach( this ); + + // Insert curve + d_curve = new QwtPlotCurve( "Data Moving Right" ); + d_curve->setPen( Qt::black ); + d_curve->setData( new CircularBuffer( d_interval, 10 ) ); + d_curve->attach( this ); + + // Axis + setAxisTitle( QwtPlot::xBottom, "Seconds" ); + setAxisScale( QwtPlot::xBottom, -d_interval, 0.0 ); + + setAxisTitle( QwtPlot::yLeft, "Values" ); + setAxisScale( QwtPlot::yLeft, -1.0, 1.0 ); + + d_clock.start(); + + setSettings( d_settings ); +} + +// +// Set a plain canvas frame and align the scales to it +// +void Plot::alignScales() +{ + // The code below shows how to align the scales to + // the canvas frame, but is also a good example demonstrating + // why the spreaded API needs polishing. + + for ( int i = 0; i < QwtPlot::axisCnt; i++ ) + { + QwtScaleWidget *scaleWidget = axisWidget( i ); + if ( scaleWidget ) + scaleWidget->setMargin( 0 ); + + QwtScaleDraw *scaleDraw = axisScaleDraw( i ); + if ( scaleDraw ) + scaleDraw->enableComponent( QwtAbstractScaleDraw::Backbone, false ); + } + + plotLayout()->setAlignCanvasToScales( true ); +} + +void Plot::setSettings( const Settings &s ) +{ + if ( d_timerId >= 0 ) + killTimer( d_timerId ); + + d_timerId = startTimer( s.updateInterval ); + + d_grid->setPen( s.grid.pen ); + d_grid->setVisible( s.grid.pen.style() != Qt::NoPen ); + + CircularBuffer *buffer = static_cast( d_curve->data() ); + if ( s.curve.numPoints != buffer->size() || + s.curve.functionType != d_settings.curve.functionType ) + { + switch( s.curve.functionType ) + { + case Settings::Wave: + buffer->setFunction( wave ); + break; + case Settings::Noise: + buffer->setFunction( noise ); + break; + default: + buffer->setFunction( NULL ); + } + + buffer->fill( d_interval, s.curve.numPoints ); + } + + d_curve->setPen( s.curve.pen ); + d_curve->setBrush( s.curve.brush ); + + d_curve->setPaintAttribute( QwtPlotCurve::ClipPolygons, + s.curve.paintAttributes & QwtPlotCurve::ClipPolygons ); + d_curve->setPaintAttribute( QwtPlotCurve::FilterPoints, + s.curve.paintAttributes & QwtPlotCurve::FilterPoints ); + + d_curve->setRenderHint( QwtPlotItem::RenderAntialiased, + s.curve.renderHint & QwtPlotItem::RenderAntialiased ); + +#ifndef QWT_NO_OPENGL + if ( s.canvas.openGL ) + { + QwtPlotGLCanvas *plotCanvas = qobject_cast( canvas() ); + if ( plotCanvas == NULL ) + { + plotCanvas = new GLCanvas(); + plotCanvas->setPalette( QColor( "khaki" ) ); + + setCanvas( plotCanvas ); + } + } + else +#endif + { + QwtPlotCanvas *plotCanvas = qobject_cast( canvas() ); + if ( plotCanvas == NULL ) + { + plotCanvas = new QwtPlotCanvas(); + plotCanvas->setFrameStyle( QFrame::Box | QFrame::Plain ); + plotCanvas->setLineWidth( 1 ); + plotCanvas->setPalette( Qt::white ); + + setCanvas( plotCanvas ); + } + + plotCanvas->setAttribute( Qt::WA_PaintOnScreen, s.canvas.paintOnScreen ); + + plotCanvas->setPaintAttribute( + QwtPlotCanvas::BackingStore, s.canvas.useBackingStore ); + plotCanvas->setPaintAttribute( + QwtPlotCanvas::ImmediatePaint, s.canvas.immediatePaint ); + } + + QwtPainter::setPolylineSplitting( s.curve.lineSplitting ); + + d_settings = s; +} + +void Plot::timerEvent( QTimerEvent * ) +{ + CircularBuffer *buffer = static_cast( d_curve->data() ); + buffer->setReferenceTime( d_clock.elapsed() / 1000.0 ); + + if ( d_settings.updateType == Settings::RepaintCanvas ) + { + // the axes in this example doesn't change. So all we need to do + // is to repaint the canvas. + + QMetaObject::invokeMethod( canvas(), "replot", Qt::DirectConnection ); + } + else + { + replot(); + } +} diff --git a/ThirdParty/Qwt/examples/refreshtest/plot.h b/ThirdParty/Qwt/examples/refreshtest/plot.h new file mode 100644 index 0000000000..8e63450772 --- /dev/null +++ b/ThirdParty/Qwt/examples/refreshtest/plot.h @@ -0,0 +1,38 @@ +#ifndef _PLOT_H_ +#define _PLOT_H_ 1 + +#include +#include +#include "settings.h" + +class QwtPlotGrid; +class QwtPlotCurve; + +class Plot: public QwtPlot +{ + Q_OBJECT + +public: + Plot( QWidget* = NULL ); + +public Q_SLOTS: + void setSettings( const Settings & ); + +protected: + virtual void timerEvent( QTimerEvent *e ); + +private: + void alignScales(); + + QwtPlotGrid *d_grid; + QwtPlotCurve *d_curve; + + QwtSystemClock d_clock; + double d_interval; + + int d_timerId; + + Settings d_settings; +}; + +#endif diff --git a/ThirdParty/Qwt/examples/refreshtest/refreshtest.pro b/ThirdParty/Qwt/examples/refreshtest/refreshtest.pro new file mode 100644 index 0000000000..3dca7a2510 --- /dev/null +++ b/ThirdParty/Qwt/examples/refreshtest/refreshtest.pro @@ -0,0 +1,27 @@ +################################################################ +# Qwt Widget Library +# Copyright (C) 1997 Josef Wilgen +# Copyright (C) 2002 Uwe Rathmann +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the Qwt License, Version 1.0 +################################################################ + +include( $${PWD}/../examples.pri ) + +TARGET = refreshtest + +HEADERS = \ + settings.h \ + circularbuffer.h \ + panel.h \ + plot.h \ + mainwindow.h + +SOURCES = \ + circularbuffer.cpp \ + panel.cpp \ + plot.cpp \ + mainwindow.cpp \ + main.cpp + diff --git a/ThirdParty/Qwt/examples/refreshtest/settings.h b/ThirdParty/Qwt/examples/refreshtest/settings.h new file mode 100644 index 0000000000..58ff2a7d5d --- /dev/null +++ b/ThirdParty/Qwt/examples/refreshtest/settings.h @@ -0,0 +1,78 @@ +#ifndef _SETTINGS_H_ +#define _SETTINGS_H_ + +#include +#include + +class Settings +{ +public: + enum FunctionType + { + NoFunction = -1, + + Wave, + Noise + }; + + enum UpdateType + { + RepaintCanvas, + Replot + }; + + Settings() + { + grid.pen = Qt::NoPen; + grid.pen.setCosmetic( true ); + + curve.brush = Qt::NoBrush; + curve.numPoints = 1000; + curve.functionType = Wave; + curve.paintAttributes = 0; + curve.renderHint = 0; + curve.lineSplitting = true; + + canvas.useBackingStore = false; + canvas.paintOnScreen = false; + canvas.immediatePaint = true; +#ifndef QWT_NO_OPENGL + canvas.openGL = false; +#endif + + updateType = RepaintCanvas; + updateInterval = 20; + } + + struct gridSettings + { + QPen pen; + } grid; + + struct curveSettings + { + QPen pen; + QBrush brush; + uint numPoints; + FunctionType functionType; + int paintAttributes; + int renderHint; + bool lineSplitting; + } curve; + + struct canvasSettings + { + bool useBackingStore; + bool paintOnScreen; + bool immediatePaint; + +#ifndef QWT_NO_OPENGL + bool openGL; +#endif + } canvas; + + UpdateType updateType; + int updateInterval; +}; + +#endif diff --git a/ThirdParty/Qwt/examples/scatterplot/main.cpp b/ThirdParty/Qwt/examples/scatterplot/main.cpp new file mode 100644 index 0000000000..4d874edeb6 --- /dev/null +++ b/ThirdParty/Qwt/examples/scatterplot/main.cpp @@ -0,0 +1,13 @@ +#include +#include "mainwindow.h" + +int main( int argc, char **argv ) +{ + QApplication a( argc, argv ); + + MainWindow w; + w.resize( 800, 600 ); + w.show(); + + return a.exec(); +} diff --git a/ThirdParty/Qwt/examples/scatterplot/mainwindow.cpp b/ThirdParty/Qwt/examples/scatterplot/mainwindow.cpp new file mode 100644 index 0000000000..358d73fefb --- /dev/null +++ b/ThirdParty/Qwt/examples/scatterplot/mainwindow.cpp @@ -0,0 +1,35 @@ +#include "mainwindow.h" +#include "plot.h" +#include + +static double randomValue() +{ + // a number between [ 0.0, 1.0 ] + return ( qrand() % 100000 ) / 100000.0; +} + +MainWindow::MainWindow() +{ + d_plot = new Plot( this ); + d_plot->setTitle( "Scatter Plot" ); + setCentralWidget( d_plot ); + + // a million points + setSamples( 100000 ); +} + +void MainWindow::setSamples( int numPoints ) +{ + QPolygonF samples; + + for ( int i = 0; i < numPoints; i++ ) + { + const double x = randomValue() * 24.0 + 1.0; + const double y = ::log( 10.0 * ( x - 1.0 ) + 1.0 ) + * ( randomValue() * 0.5 + 0.9 ); + + samples += QPointF( x, y ); + } + + d_plot->setSamples( samples ); +} diff --git a/ThirdParty/Qwt/examples/scatterplot/mainwindow.h b/ThirdParty/Qwt/examples/scatterplot/mainwindow.h new file mode 100644 index 0000000000..c616af6d4a --- /dev/null +++ b/ThirdParty/Qwt/examples/scatterplot/mainwindow.h @@ -0,0 +1,22 @@ +#ifndef _MAINWINDOW_H_ +#define _MAINWINDOW_H_ 1 + +#include + +class Plot; + +class MainWindow: public QMainWindow +{ + Q_OBJECT + +public: + MainWindow(); + +private: + void setSamples( int samples ); + +private: + Plot *d_plot; +}; + +#endif diff --git a/ThirdParty/Qwt/examples/scatterplot/plot.cpp b/ThirdParty/Qwt/examples/scatterplot/plot.cpp new file mode 100644 index 0000000000..1e65a399af --- /dev/null +++ b/ThirdParty/Qwt/examples/scatterplot/plot.cpp @@ -0,0 +1,91 @@ +#include "plot.h" +#include +#include +#include +#include +#include + +class DistancePicker: public QwtPlotPicker +{ +public: + DistancePicker( QWidget *canvas ): + QwtPlotPicker( canvas ) + { + setTrackerMode( QwtPicker::ActiveOnly ); + setStateMachine( new QwtPickerDragLineMachine() ); + setRubberBand( QwtPlotPicker::PolygonRubberBand ); + } + + virtual QwtText trackerTextF( const QPointF &pos ) const + { + QwtText text; + + const QPolygon points = selection(); + if ( !points.isEmpty() ) + { + QString num; + num.setNum( QLineF( pos, invTransform( points[0] ) ).length() ); + + QColor bg( Qt::white ); + bg.setAlpha( 200 ); + + text.setBackgroundBrush( QBrush( bg ) ); + text.setText( num ); + } + return text; + } +}; + +Plot::Plot( QWidget *parent ): + QwtPlot( parent ), + d_curve( NULL ) +{ + canvas()->setStyleSheet( + "border: 2px solid Black;" + "border-radius: 15px;" + "background-color: qlineargradient( x1: 0, y1: 0, x2: 0, y2: 1," + "stop: 0 LemonChiffon, stop: 1 PaleGoldenrod );" + ); + + // attach curve + d_curve = new QwtPlotCurve( "Scattered Points" ); + d_curve->setPen( QColor( "Purple" ) ); + + // when using QwtPlotCurve::ImageBuffer simple dots can be + // rendered in parallel on multicore systems. + d_curve->setRenderThreadCount( 0 ); // 0: use QThread::idealThreadCount() + + d_curve->attach( this ); + + setSymbol( NULL ); + + // panning with the left mouse button + (void )new QwtPlotPanner( canvas() ); + + // zoom in/out with the wheel + QwtPlotMagnifier *magnifier = new QwtPlotMagnifier( canvas() ); + magnifier->setMouseButton( Qt::NoButton ); + + // distanve measurement with the right mouse button + DistancePicker *picker = new DistancePicker( canvas() ); + picker->setMousePattern( QwtPlotPicker::MouseSelect1, Qt::RightButton ); + picker->setRubberBandPen( QPen( Qt::blue ) ); +} + +void Plot::setSymbol( QwtSymbol *symbol ) +{ + d_curve->setSymbol( symbol ); + + if ( symbol == NULL ) + { + d_curve->setStyle( QwtPlotCurve::Dots ); + } +} + +void Plot::setSamples( const QVector &samples ) +{ + d_curve->setPaintAttribute( + QwtPlotCurve::ImageBuffer, samples.size() > 1000 ); + + d_curve->setSamples( samples ); +} diff --git a/ThirdParty/Qwt/examples/scatterplot/plot.h b/ThirdParty/Qwt/examples/scatterplot/plot.h new file mode 100644 index 0000000000..8053f35552 --- /dev/null +++ b/ThirdParty/Qwt/examples/scatterplot/plot.h @@ -0,0 +1,23 @@ +#ifndef _PLOT_H_ +#define _PLOT_H_ 1 + +#include + +class QwtPlotCurve; +class QwtSymbol; + +class Plot : public QwtPlot +{ + Q_OBJECT + +public: + Plot( QWidget *parent = NULL ); + + void setSymbol( QwtSymbol * ); + void setSamples( const QVector &samples ); + +private: + QwtPlotCurve *d_curve; +}; + +#endif // _PLOT_H_ diff --git a/ThirdParty/Qwt/examples/scatterplot/scatterplot.pro b/ThirdParty/Qwt/examples/scatterplot/scatterplot.pro new file mode 100644 index 0000000000..67ad530ceb --- /dev/null +++ b/ThirdParty/Qwt/examples/scatterplot/scatterplot.pro @@ -0,0 +1,22 @@ +################################################################ +# Qwt Widget Library +# Copyright (C) 1997 Josef Wilgen +# Copyright (C) 2002 Uwe Rathmann +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the Qwt License, Version 1.0 +################################################################ + +include( $${PWD}/../examples.pri ) + +TARGET = scatterplot + +HEADERS = \ + mainwindow.h \ + plot.h + +SOURCES = \ + main.cpp \ + mainwindow.cpp \ + plot.cpp + diff --git a/ThirdParty/Qwt/examples/simpleplot/simpleplot.cpp b/ThirdParty/Qwt/examples/simpleplot/simpleplot.cpp new file mode 100644 index 0000000000..58a97de099 --- /dev/null +++ b/ThirdParty/Qwt/examples/simpleplot/simpleplot.cpp @@ -0,0 +1,42 @@ +#include +#include +#include +#include +#include +#include + +int main( int argc, char **argv ) +{ + QApplication a( argc, argv ); + + QwtPlot plot; + plot.setTitle( "Plot Demo" ); + plot.setCanvasBackground( Qt::white ); + plot.setAxisScale( QwtPlot::yLeft, 0.0, 10.0 ); + plot.insertLegend( new QwtLegend() ); + + QwtPlotGrid *grid = new QwtPlotGrid(); + grid->attach( &plot ); + + QwtPlotCurve *curve = new QwtPlotCurve(); + curve->setTitle( "Some Points" ); + curve->setPen( Qt::blue, 4 ), + curve->setRenderHint( QwtPlotItem::RenderAntialiased, true ); + + QwtSymbol *symbol = new QwtSymbol( QwtSymbol::Ellipse, + QBrush( Qt::yellow ), QPen( Qt::red, 2 ), QSize( 8, 8 ) ); + curve->setSymbol( symbol ); + + QPolygonF points; + points << QPointF( 0.0, 4.4 ) << QPointF( 1.0, 3.0 ) + << QPointF( 2.0, 4.5 ) << QPointF( 3.0, 6.8 ) + << QPointF( 4.0, 7.9 ) << QPointF( 5.0, 7.1 ); + curve->setSamples( points ); + + curve->attach( &plot ); + + plot.resize( 600, 400 ); + plot.show(); + + return a.exec(); +} diff --git a/ThirdParty/Qwt/examples/simpleplot/simpleplot.pro b/ThirdParty/Qwt/examples/simpleplot/simpleplot.pro new file mode 100644 index 0000000000..62dcad194b --- /dev/null +++ b/ThirdParty/Qwt/examples/simpleplot/simpleplot.pro @@ -0,0 +1,16 @@ +################################################################ +# Qwt Widget Library +# Copyright (C) 1997 Josef Wilgen +# Copyright (C) 2002 Uwe Rathmann +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the Qwt License, Version 1.0 +################################################################ + +include( $${PWD}/../examples.pri ) + +TARGET = simpleplot + +SOURCES = \ + simpleplot.cpp + diff --git a/ThirdParty/Qwt/examples/sinusplot/sinusplot.cpp b/ThirdParty/Qwt/examples/sinusplot/sinusplot.cpp new file mode 100644 index 0000000000..a9d40492ee --- /dev/null +++ b/ThirdParty/Qwt/examples/sinusplot/sinusplot.cpp @@ -0,0 +1,218 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//----------------------------------------------------------------- +// simple.cpp +// +// A simple example which shows how to use QwtPlot connected +// to a data class without any storage, calculating each values +// on the fly. +//----------------------------------------------------------------- + +class FunctionData: public QwtSyntheticPointData +{ +public: + FunctionData( double( *y )( double ) ): + QwtSyntheticPointData( 100 ), + d_y( y ) + { + } + + virtual double y( double x ) const + { + return d_y( x ); + } + +private: + double( *d_y )( double ); +}; + +class ArrowSymbol: public QwtSymbol +{ +public: + ArrowSymbol() + { + QPen pen( Qt::black, 0 ); + pen.setJoinStyle( Qt::MiterJoin ); + + setPen( pen ); + setBrush( Qt::red ); + + QPainterPath path; + path.moveTo( 0, 8 ); + path.lineTo( 0, 5 ); + path.lineTo( -3, 5 ); + path.lineTo( 0, 0 ); + path.lineTo( 3, 5 ); + path.lineTo( 0, 5 ); + + QTransform transform; + transform.rotate( -30.0 ); + path = transform.map( path ); + + setPath( path ); + setPinPoint( QPointF( 0, 0 ) ); + + setSize( 10, 14 ); + } +}; + +class Plot : public QwtPlot +{ +public: + Plot( QWidget *parent = NULL ); + +protected: + virtual void resizeEvent( QResizeEvent * ); + +private: + void populate(); + void updateGradient(); +}; + + +Plot::Plot( QWidget *parent ): + QwtPlot( parent ) +{ + setAutoFillBackground( true ); + setPalette( QPalette( QColor( 165, 193, 228 ) ) ); + updateGradient(); + + setTitle( "A Simple QwtPlot Demonstration" ); + insertLegend( new QwtLegend(), QwtPlot::RightLegend ); + + // axes + setAxisTitle( xBottom, "x -->" ); + setAxisScale( xBottom, 0.0, 10.0 ); + + setAxisTitle( yLeft, "y -->" ); + setAxisScale( yLeft, -1.0, 1.0 ); + + // canvas + QwtPlotCanvas *canvas = new QwtPlotCanvas(); + canvas->setLineWidth( 1 ); + canvas->setFrameStyle( QFrame::Box | QFrame::Plain ); + canvas->setBorderRadius( 15 ); + + QPalette canvasPalette( Qt::white ); + canvasPalette.setColor( QPalette::Foreground, QColor( 133, 190, 232 ) ); + canvas->setPalette( canvasPalette ); + + setCanvas( canvas ); + + // panning with the left mouse button + ( void ) new QwtPlotPanner( canvas ); + + // zoom in/out with the wheel + ( void ) new QwtPlotMagnifier( canvas ); + + populate(); +} + +void Plot::populate() +{ + // Insert new curves + QwtPlotCurve *cSin = new QwtPlotCurve( "y = sin(x)" ); + cSin->setRenderHint( QwtPlotItem::RenderAntialiased ); + cSin->setLegendAttribute( QwtPlotCurve::LegendShowLine, true ); + cSin->setPen( Qt::red ); + cSin->attach( this ); + + QwtPlotCurve *cCos = new QwtPlotCurve( "y = cos(x)" ); + cCos->setRenderHint( QwtPlotItem::RenderAntialiased ); + cCos->setLegendAttribute( QwtPlotCurve::LegendShowLine, true ); + cCos->setPen( Qt::blue ); + cCos->attach( this ); + + // Create sin and cos data + cSin->setData( new FunctionData( ::sin ) ); + cCos->setData( new FunctionData( ::cos ) ); + + // Insert markers + + // ...a horizontal line at y = 0... + QwtPlotMarker *mY = new QwtPlotMarker(); + mY->setLabel( QString::fromLatin1( "y = 0" ) ); + mY->setLabelAlignment( Qt::AlignRight | Qt::AlignTop ); + mY->setLineStyle( QwtPlotMarker::HLine ); + mY->setYValue( 0.0 ); + mY->attach( this ); + + // ...a vertical line at x = 2 * pi + QwtPlotMarker *mX = new QwtPlotMarker(); + mX->setLabel( QString::fromLatin1( "x = 2 pi" ) ); + mX->setLabelAlignment( Qt::AlignLeft | Qt::AlignBottom ); + mX->setLabelOrientation( Qt::Vertical ); + mX->setLineStyle( QwtPlotMarker::VLine ); + mX->setLinePen( Qt::black, 0, Qt::DashDotLine ); + mX->setXValue( 2.0 * M_PI ); + mX->attach( this ); + + const double x = 7.7; + + // an arrow at a specific position + QwtPlotMarker *mPos = new QwtPlotMarker( "Marker" ); + mPos->setRenderHint( QwtPlotItem::RenderAntialiased, true ); + mPos->setItemAttribute( QwtPlotItem::Legend, true ); + mPos->setSymbol( new ArrowSymbol() ); + mPos->setValue( QPointF( x, ::sin( x ) ) ); + mPos->setLabel( QString( "x = %1" ).arg( x ) ); + mPos->setLabelAlignment( Qt::AlignRight | Qt::AlignBottom ); + mPos->attach( this ); +} + +void Plot::updateGradient() +{ + QPalette pal = palette(); + + const QColor buttonColor = pal.color( QPalette::Button ); + + QLinearGradient gradient( rect().topLeft(), rect().bottomLeft() ); + gradient.setColorAt( 0.0, Qt::white ); + gradient.setColorAt( 0.7, buttonColor ); + gradient.setColorAt( 1.0, buttonColor ); + + pal.setBrush( QPalette::Window, gradient ); + setPalette( pal ); +} + +void Plot::resizeEvent( QResizeEvent *event ) +{ + QwtPlot::resizeEvent( event ); + + // Qt 4.7.1: QGradient::StretchToDeviceMode is buggy on X11 + updateGradient(); +} + +int main( int argc, char **argv ) +{ + QApplication a( argc, argv ); + + Plot *plot = new Plot(); + + // We put a dummy widget around to have + // so that Qt paints a widget background + // when resizing + + QWidget window; + QHBoxLayout *layout = new QHBoxLayout( &window ); + layout->setContentsMargins( 0, 0, 0, 0 ); + layout->addWidget( plot ); + + window.resize( 600, 400 ); + window.show(); + + return a.exec(); +} diff --git a/ThirdParty/Qwt/examples/sinusplot/sinusplot.pro b/ThirdParty/Qwt/examples/sinusplot/sinusplot.pro new file mode 100644 index 0000000000..fc43e58fb6 --- /dev/null +++ b/ThirdParty/Qwt/examples/sinusplot/sinusplot.pro @@ -0,0 +1,16 @@ +################################################################ +# Qwt Widget Library +# Copyright (C) 1997 Josef Wilgen +# Copyright (C) 2002 Uwe Rathmann +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the Qwt License, Version 1.0 +################################################################ + +include( $${PWD}/../examples.pri ) + +TARGET = sinusplot + +SOURCES = \ + sinusplot.cpp + diff --git a/ThirdParty/Qwt/examples/spectrogram/main.cpp b/ThirdParty/Qwt/examples/spectrogram/main.cpp new file mode 100644 index 0000000000..e4d0041982 --- /dev/null +++ b/ThirdParty/Qwt/examples/spectrogram/main.cpp @@ -0,0 +1,75 @@ +#include +#include +#include +#include +#include +#include "plot.h" + +class MainWindow: public QMainWindow +{ +public: + MainWindow( QWidget * = NULL ); + +private: + Plot *d_plot; +}; + +MainWindow::MainWindow( QWidget *parent ): + QMainWindow( parent ) +{ + d_plot = new Plot( this ); + + setCentralWidget( d_plot ); + + QToolBar *toolBar = new QToolBar( this ); + + QToolButton *btnSpectrogram = new QToolButton( toolBar ); + btnSpectrogram->setText( "Spectrogram" ); + btnSpectrogram->setCheckable( true ); + btnSpectrogram->setToolButtonStyle( Qt::ToolButtonTextUnderIcon ); + toolBar->addWidget( btnSpectrogram ); + connect( btnSpectrogram, SIGNAL( toggled( bool ) ), + d_plot, SLOT( showSpectrogram( bool ) ) ); + + QToolButton *btnContour = new QToolButton( toolBar ); + btnContour->setText( "Contour" ); + btnContour->setCheckable( true ); + btnContour->setToolButtonStyle( Qt::ToolButtonTextUnderIcon ); + toolBar->addWidget( btnContour ); + connect( btnContour, SIGNAL( toggled( bool ) ), + d_plot, SLOT( showContour( bool ) ) ); + +#ifndef QT_NO_PRINTER + QToolButton *btnPrint = new QToolButton( toolBar ); + btnPrint->setText( "Print" ); + btnPrint->setToolButtonStyle( Qt::ToolButtonTextUnderIcon ); + toolBar->addWidget( btnPrint ); + connect( btnPrint, SIGNAL( clicked() ), + d_plot, SLOT( printPlot() ) ); +#endif + + QSlider *slider = new QSlider( Qt::Horizontal ); + slider->setRange( 0, 255 ); + slider->setValue( 255 ); + connect( slider, SIGNAL( valueChanged( int ) ), + d_plot, SLOT( setAlpha( int ) ) ); + + toolBar->addWidget( slider ); + + addToolBar( toolBar ); + + btnSpectrogram->setChecked( true ); + btnContour->setChecked( false ); + +} + +int main( int argc, char **argv ) +{ + QApplication a( argc, argv ); + + MainWindow mainWindow; + mainWindow.resize( 600, 400 ); + mainWindow.show(); + + return a.exec(); +} diff --git a/ThirdParty/Qwt/examples/spectrogram/plot.cpp b/ThirdParty/Qwt/examples/spectrogram/plot.cpp new file mode 100644 index 0000000000..ccf452ea48 --- /dev/null +++ b/ThirdParty/Qwt/examples/spectrogram/plot.cpp @@ -0,0 +1,169 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "plot.h" + +class MyZoomer: public QwtPlotZoomer +{ +public: + MyZoomer( QWidget *canvas ): + QwtPlotZoomer( canvas ) + { + setTrackerMode( AlwaysOn ); + } + + virtual QwtText trackerTextF( const QPointF &pos ) const + { + QColor bg( Qt::white ); + bg.setAlpha( 200 ); + + QwtText text = QwtPlotZoomer::trackerTextF( pos ); + text.setBackgroundBrush( QBrush( bg ) ); + return text; + } +}; + +class SpectrogramData: public QwtRasterData +{ +public: + SpectrogramData() + { + setInterval( Qt::XAxis, QwtInterval( -1.5, 1.5 ) ); + setInterval( Qt::YAxis, QwtInterval( -1.5, 1.5 ) ); + setInterval( Qt::ZAxis, QwtInterval( 0.0, 10.0 ) ); + } + + virtual double value( double x, double y ) const + { + const double c = 0.842; + + const double v1 = x * x + ( y - c ) * ( y + c ); + const double v2 = x * ( y + c ) + x * ( y + c ); + + return 1.0 / ( v1 * v1 + v2 * v2 ); + } +}; + +class ColorMap: public QwtLinearColorMap +{ +public: + ColorMap(): + QwtLinearColorMap( Qt::darkCyan, Qt::red ) + { + addColorStop( 0.1, Qt::cyan ); + addColorStop( 0.6, Qt::green ); + addColorStop( 0.95, Qt::yellow ); + } +}; + +Plot::Plot( QWidget *parent ): + QwtPlot( parent ) +{ + d_spectrogram = new QwtPlotSpectrogram(); + d_spectrogram->setRenderThreadCount( 0 ); // use system specific thread count + + d_spectrogram->setColorMap( new ColorMap() ); + d_spectrogram->setCachePolicy( QwtPlotRasterItem::PaintCache ); + + d_spectrogram->setData( new SpectrogramData() ); + d_spectrogram->attach( this ); + + QList contourLevels; + for ( double level = 0.5; level < 10.0; level += 1.0 ) + contourLevels += level; + d_spectrogram->setContourLevels( contourLevels ); + + const QwtInterval zInterval = d_spectrogram->data()->interval( Qt::ZAxis ); + // A color bar on the right axis + QwtScaleWidget *rightAxis = axisWidget( QwtPlot::yRight ); + rightAxis->setTitle( "Intensity" ); + rightAxis->setColorBarEnabled( true ); + rightAxis->setColorMap( zInterval, new ColorMap() ); + + setAxisScale( QwtPlot::yRight, zInterval.minValue(), zInterval.maxValue() ); + enableAxis( QwtPlot::yRight ); + + plotLayout()->setAlignCanvasToScales( true ); + replot(); + + // LeftButton for the zooming + // MidButton for the panning + // RightButton: zoom out by 1 + // Ctrl+RighButton: zoom out to full size + + QwtPlotZoomer* zoomer = new MyZoomer( canvas() ); + zoomer->setMousePattern( QwtEventPattern::MouseSelect2, + Qt::RightButton, Qt::ControlModifier ); + zoomer->setMousePattern( QwtEventPattern::MouseSelect3, + Qt::RightButton ); + + QwtPlotPanner *panner = new QwtPlotPanner( canvas() ); + panner->setAxisEnabled( QwtPlot::yRight, false ); + panner->setMouseButton( Qt::MidButton ); + + // Avoid jumping when labels with more/less digits + // appear/disappear when scrolling vertically + + const QFontMetrics fm( axisWidget( QwtPlot::yLeft )->font() ); + QwtScaleDraw *sd = axisScaleDraw( QwtPlot::yLeft ); + sd->setMinimumExtent( fm.width( "100.00" ) ); + + const QColor c( Qt::darkBlue ); + zoomer->setRubberBandPen( c ); + zoomer->setTrackerPen( c ); +} + +void Plot::showContour( bool on ) +{ + d_spectrogram->setDisplayMode( QwtPlotSpectrogram::ContourMode, on ); + replot(); +} + +void Plot::showSpectrogram( bool on ) +{ + d_spectrogram->setDisplayMode( QwtPlotSpectrogram::ImageMode, on ); + d_spectrogram->setDefaultContourPen( + on ? QPen( Qt::black, 0 ) : QPen( Qt::NoPen ) ); + + replot(); +} + +void Plot::setAlpha( int alpha ) +{ + d_spectrogram->setAlpha( alpha ); + replot(); +} + +#ifndef QT_NO_PRINTER + +void Plot::printPlot() +{ + QPrinter printer( QPrinter::HighResolution ); + printer.setOrientation( QPrinter::Landscape ); + printer.setOutputFileName( "spectrogram.pdf" ); + + QPrintDialog dialog( &printer ); + if ( dialog.exec() ) + { + QwtPlotRenderer renderer; + + if ( printer.colorMode() == QPrinter::GrayScale ) + { + renderer.setDiscardFlag( QwtPlotRenderer::DiscardBackground ); + renderer.setDiscardFlag( QwtPlotRenderer::DiscardCanvasBackground ); + renderer.setDiscardFlag( QwtPlotRenderer::DiscardCanvasFrame ); + renderer.setLayoutFlag( QwtPlotRenderer::FrameWithScales ); + } + + renderer.renderTo( this, printer ); + } +} + +#endif diff --git a/ThirdParty/Qwt/examples/spectrogram/plot.h b/ThirdParty/Qwt/examples/spectrogram/plot.h new file mode 100644 index 0000000000..c741a1748b --- /dev/null +++ b/ThirdParty/Qwt/examples/spectrogram/plot.h @@ -0,0 +1,22 @@ +#include +#include + +class Plot: public QwtPlot +{ + Q_OBJECT + +public: + Plot( QWidget * = NULL ); + +public Q_SLOTS: + void showContour( bool on ); + void showSpectrogram( bool on ); + void setAlpha( int ); + +#ifndef QT_NO_PRINTER + void printPlot(); +#endif + +private: + QwtPlotSpectrogram *d_spectrogram; +}; diff --git a/ThirdParty/Qwt/examples/spectrogram/spectrogram.pro b/ThirdParty/Qwt/examples/spectrogram/spectrogram.pro new file mode 100644 index 0000000000..b35b101e86 --- /dev/null +++ b/ThirdParty/Qwt/examples/spectrogram/spectrogram.pro @@ -0,0 +1,19 @@ +################################################################ +# Qwt Widget Library +# Copyright (C) 1997 Josef Wilgen +# Copyright (C) 2002 Uwe Rathmann +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the Qwt License, Version 1.0 +################################################################ + +include( $${PWD}/../examples.pri ) + +TARGET = spectrogram + +HEADERS = \ + plot.h + +SOURCES = \ + plot.cpp \ + main.cpp diff --git a/ThirdParty/Qwt/examples/stockchart/griditem.cpp b/ThirdParty/Qwt/examples/stockchart/griditem.cpp new file mode 100644 index 0000000000..c73beffd4c --- /dev/null +++ b/ThirdParty/Qwt/examples/stockchart/griditem.cpp @@ -0,0 +1,278 @@ +#include "griditem.h" +#include +#include +#include + +GridItem::GridItem(): + QwtPlotItem( QwtText( "Grid" ) ), + m_orientations( Qt::Horizontal | Qt::Vertical ), + m_gridAttributes( AutoUpdate | FillCanvas ), + m_isXMinEnabled( false ), + m_isYMinEnabled( false ) +{ + setItemInterest( QwtPlotItem::ScaleInterest, true ); + setZ( 10.0 ); +} + +GridItem::~GridItem() +{ +} + +int GridItem::rtti() const +{ + return QwtPlotItem::Rtti_PlotUserItem + 99; // something +} + +void GridItem::setGridAttribute( GridAttribute attribute, bool on ) +{ + if ( bool( m_gridAttributes & attribute ) == on ) + return; + + if ( on ) + m_gridAttributes |= attribute; + else + m_gridAttributes &= ~attribute; + + itemChanged(); +} + +bool GridItem::testGridAttribute( GridAttribute attribute ) const +{ + return m_gridAttributes & attribute; +} + +void GridItem::setOrientations( Qt::Orientations orientations ) +{ + if ( m_orientations != orientations ) + { + m_orientations = orientations; + itemChanged(); + } +} + +Qt::Orientations GridItem::orientations() const +{ + return m_orientations; +} + +void GridItem::enableXMin( bool enabled ) +{ + if ( enabled != m_isXMinEnabled ) + { + m_isXMinEnabled = enabled; + itemChanged(); + } +} + +bool GridItem::isXMinEnabled() const +{ + return m_isXMinEnabled; +} + +void GridItem::enableYMin( bool enabled ) +{ + if ( enabled != m_isYMinEnabled ) + { + m_isYMinEnabled = enabled; + itemChanged(); + } +} + +bool GridItem::isYMinEnabled() const +{ + return m_isYMinEnabled; +} + +void GridItem::setXDiv( const QwtScaleDiv &scaleDiv ) +{ + if ( m_xScaleDiv != scaleDiv ) + { + m_xScaleDiv = scaleDiv; + itemChanged(); + } +} + +void GridItem::setYDiv( const QwtScaleDiv &scaleDiv ) +{ + if ( m_yScaleDiv != scaleDiv ) + { + m_yScaleDiv = scaleDiv; + itemChanged(); + } +} + +void GridItem::setPalette( const QPalette &palette ) +{ + if ( m_palette != palette ) + { + m_palette = palette; + itemChanged(); + } +} + +QPalette GridItem::palette() const +{ + return m_palette; +} + +void GridItem::draw( QPainter *painter, + const QwtScaleMap &xMap, const QwtScaleMap &yMap, + const QRectF &canvasRect ) const +{ + const bool doAlign = QwtPainter::roundingAlignment( painter ); + + const QRectF area = QwtScaleMap::invTransform( xMap, yMap, canvasRect ); + + QList xValues; + if ( m_orientations & Qt::Horizontal ) + { + xValues = m_xScaleDiv.ticks( QwtScaleDiv::MajorTick ); + + if ( m_isXMinEnabled ) + { + xValues += m_xScaleDiv.ticks( QwtScaleDiv::MediumTick ); + xValues += m_xScaleDiv.ticks( QwtScaleDiv::MinorTick ); + } + + if ( m_gridAttributes & FillCanvas ) + { + xValues += area.left(); + xValues += area.right(); + } + + qSort( xValues ); + } + + QList yValues; + if ( m_orientations & Qt::Vertical ) + { + yValues = m_yScaleDiv.ticks( QwtScaleDiv::MajorTick ); + + if ( m_isYMinEnabled ) + { + yValues += m_yScaleDiv.ticks( QwtScaleDiv::MediumTick ); + yValues += m_yScaleDiv.ticks( QwtScaleDiv::MinorTick ); + } + + if ( m_gridAttributes & FillCanvas ) + { + yValues += area.top(); + yValues += area.bottom(); + } + + qSort( yValues ); + } + + painter->setPen( Qt::NoPen ); + + if ( ( m_orientations & Qt::Horizontal ) && + ( m_orientations & Qt::Vertical ) ) + { + for ( int i = 1; i < xValues.size(); i++ ) + { + double x1 = xMap.transform( xValues[i - 1] ); + double x2 = xMap.transform( xValues[i] ); + + if ( doAlign ) + { + x1 = qRound( x1 ); + x2 = qRound( x2 ); + } + + for ( int j = 1; j < yValues.size(); j++ ) + { + const QRectF rect( xValues[i - 1], yValues[j - 1], + xValues[i] - xValues[i - 1], yValues[j] - yValues[j - 1] ); + + painter->setBrush( brush( i - 1, j - 1, rect ) ); + + double y1 = yMap.transform( yValues[j - 1] ); + double y2 = yMap.transform( yValues[j] ); + + if ( doAlign ) + { + y1 = qRound( y1 ); + y2 = qRound( y2 ); + } + + QwtPainter::drawRect( painter, x1, y1, x2 - x1, y2 - y1 ); + } + } + } + else if ( m_orientations & Qt::Horizontal ) + { + for ( int i = 1; i < xValues.size(); i++ ) + { + const QRectF rect( xValues[i - 1], area.top(), + xValues[i] - xValues[i - 1], area.bottom() ); + + painter->setBrush( brush( i - 1, 0, rect ) ); + + double x1 = xMap.transform( xValues[i - 1] ); + double x2 = xMap.transform( xValues[i] ); + + if ( doAlign ) + { + x1 = qRound( x1 ); + x2 = qRound( x2 ); + } + + QwtPainter::drawRect( painter, + x1, canvasRect.top(), x2 - x1, canvasRect.height() ); + } + } + else if ( m_orientations & Qt::Vertical ) + { + for ( int i = 1; i < yValues.size(); i++ ) + { + const QRectF rect( area.left(), yValues[i - 1], + area.width(), yValues[i] - yValues[i - 1] ); + + painter->setBrush( brush( 0, i - 1, rect ) ); + + double y1 = yMap.transform( yValues[i - 1] ); + double y2 = yMap.transform( yValues[i] ); + + if ( doAlign ) + { + y1 = qRound( y1 ); + y2 = qRound( y2 ); + } + + QwtPainter::drawRect( painter, canvasRect.left(), y1, + canvasRect.width(), y2 - y1 ); + } + } +} + +const QwtScaleDiv &GridItem::xScaleDiv() const +{ + return m_xScaleDiv; +} + +const QwtScaleDiv &GridItem::yScaleDiv() const +{ + return m_yScaleDiv; +} + +void GridItem::updateScaleDiv( + const QwtScaleDiv& xScaleDiv, const QwtScaleDiv& yScaleDiv ) +{ + if ( m_gridAttributes & AutoUpdate ) + { + setXDiv( xScaleDiv ); + setYDiv( yScaleDiv ); + } +} + +QBrush GridItem::brush( int row, int column, const QRectF & ) const +{ + /* + We need some sort of origin to avoid, that the brush + changes for the same rectangle when panning + */ + if ( ( row + column ) % 2 ) + return QBrush( m_palette.brush( QPalette::Base ) ); + else + return QBrush( m_palette.brush( QPalette::AlternateBase ) ); +} diff --git a/ThirdParty/Qwt/examples/stockchart/griditem.h b/ThirdParty/Qwt/examples/stockchart/griditem.h new file mode 100644 index 0000000000..f506a64fd6 --- /dev/null +++ b/ThirdParty/Qwt/examples/stockchart/griditem.h @@ -0,0 +1,70 @@ +#ifndef _GRID_ITEM_H_ +#define _GRID_ITEM_H_ + +#include +#include +#include + +class GridItem: public QwtPlotItem +{ +public: + enum GridAttribute + { + AutoUpdate = 0x01, + FillCanvas = 0x02 + }; + + typedef QFlags GridAttributes; + + explicit GridItem(); + virtual ~GridItem(); + + virtual int rtti() const; + + void setGridAttribute( GridAttribute, bool on = true ); + bool testGridAttribute( GridAttribute ) const; + + void setOrientations( Qt::Orientations ); + Qt::Orientations orientations() const; + + void enableXMin( bool ); + bool isXMinEnabled() const; + + void enableYMin( bool ); + bool isYMinEnabled() const; + + void setXDiv( const QwtScaleDiv &sx ); + const QwtScaleDiv &xScaleDiv() const; + + void setYDiv( const QwtScaleDiv &sy ); + const QwtScaleDiv &yScaleDiv() const; + + void setPalette( const QPalette & ); + QPalette palette() const; + + virtual void draw( QPainter *p, + const QwtScaleMap &xMap, const QwtScaleMap &yMap, + const QRectF &rect ) const; + + virtual void updateScaleDiv( + const QwtScaleDiv &xMap, const QwtScaleDiv &yMap ); + +protected: + virtual QBrush brush( int row, int column, const QRectF & ) const; + +private: + Qt::Orientations m_orientations; + GridAttributes m_gridAttributes; + + QwtScaleDiv m_xScaleDiv; + QwtScaleDiv m_yScaleDiv; + + bool m_isXMinEnabled; + bool m_isYMinEnabled; + + QPalette m_palette; +}; + +Q_DECLARE_OPERATORS_FOR_FLAGS( GridItem::GridAttributes ) + +#endif diff --git a/ThirdParty/Qwt/examples/stockchart/legend.cpp b/ThirdParty/Qwt/examples/stockchart/legend.cpp new file mode 100644 index 0000000000..2b065d628f --- /dev/null +++ b/ThirdParty/Qwt/examples/stockchart/legend.cpp @@ -0,0 +1,353 @@ +#include "legend.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static void qwtRenderBackground( QPainter *painter, + const QRectF &rect, const QWidget *widget ) +{ + if ( widget->testAttribute( Qt::WA_StyledBackground ) ) + { + QStyleOption opt; + opt.initFrom( widget ); + opt.rect = rect.toAlignedRect(); + + widget->style()->drawPrimitive( + QStyle::PE_Widget, &opt, painter, widget); + } + else + { + const QBrush brush = + widget->palette().brush( widget->backgroundRole() ); + + painter->fillRect( rect, brush ); + } +} + +class LegendTreeView: public QTreeView +{ +public: + LegendTreeView( Legend * ); + + QStandardItem *rootItem( int rtti ); + QStandardItem *insertRootItem( int rtti ); + + QList itemList( const QwtPlotItem * ); + + virtual QSize sizeHint() const; + virtual QSize minimumSizeHint() const; +}; + +LegendTreeView::LegendTreeView( Legend *legend ): + QTreeView( legend ) +{ + setFrameStyle( NoFrame ); + viewport()->setBackgroundRole(QPalette::Background); + viewport()->setAutoFillBackground( false ); + + setRootIsDecorated( true ); + setHeaderHidden( true ); + + QStandardItemModel *model = new QStandardItemModel(); + + setModel( model ); + + // we want unstyled items + setItemDelegate( new QItemDelegate( this ) ); +} + +QStandardItem *LegendTreeView::rootItem( int rtti ) +{ + QStandardItemModel *mdl = + qobject_cast( model() ); + + for ( int row = 0; row < mdl->rowCount(); row++ ) + { + QStandardItem *item = mdl->item( row ); + if ( item->data() == rtti ) + return item; + } + + return NULL; +} + +QList LegendTreeView::itemList( + const QwtPlotItem *plotItem ) +{ + QList itemList; + + const QStandardItem *rootItem = this->rootItem( plotItem->rtti() ); + if ( rootItem ) + { + for ( int i = 0; i < rootItem->rowCount(); i++ ) + { + QStandardItem *item = rootItem->child( i ); + + const QVariant key = item->data(); + + if ( key.canConvert() ) + { + const qlonglong ptr = key.value(); + if ( ptr == qlonglong( plotItem ) ) + itemList += item; + } + } + } + + return itemList; +} + +QStandardItem *LegendTreeView::insertRootItem( int rtti ) +{ + QStandardItem *item = new QStandardItem(); + item->setEditable( false ); + item->setData( rtti ); + + switch( rtti ) + { + case QwtPlotItem::Rtti_PlotTradingCurve: + { + item->setText( "Curves" ); + break; + } + case QwtPlotItem::Rtti_PlotZone: + { + item->setText( "Zones" ); + break; + } + case QwtPlotItem::Rtti_PlotMarker: + { + item->setText( "Events" ); + break; + } + default: + break; + } + + QStandardItemModel *mdl = + qobject_cast( model() ); + + mdl->appendRow( item ); + setExpanded( mdl->index( mdl->rowCount() - 1, 0 ), true ); + + return item; +} + +QSize LegendTreeView::minimumSizeHint() const +{ + return QSize( -1, -1 ); +} + +QSize LegendTreeView::sizeHint() const +{ + QStyleOptionViewItem styleOption; + styleOption.initFrom( this ); + + const QAbstractItemDelegate *delegate = itemDelegate(); + + const QStandardItemModel *mdl = + qobject_cast( model() ); + + int w = 0; + int h = 0; + + for ( int row = 0; row < mdl->rowCount(); row++ ) + { + const QStandardItem *rootItem = mdl->item( row ); + + int wRow = 0; + for ( int i = 0; i < rootItem->rowCount(); i++ ) + { + const QSize hint = delegate->sizeHint( styleOption, + rootItem->child( i )->index() ); + + wRow = qMax( wRow, hint.width() ); + h += hint.height(); + } + + const QSize rootHint = delegate->sizeHint( + styleOption, rootItem->index() ); + + wRow = qMax( wRow + indentation(), rootHint.width() ); + if ( wRow > w ) + w = wRow; + + if ( rootIsDecorated() ) + w += indentation(); + + h += rootHint.height(); + } + + int left, right, top, bottom; + getContentsMargins( &left, &top, &right, &bottom ); + + w += left + right; + h += top + bottom; + + return QSize( w, h ); +} + +Legend::Legend( QWidget *parent ): + QwtAbstractLegend( parent ) +{ + d_treeView = new LegendTreeView( this ); + + QVBoxLayout *layout = new QVBoxLayout( this ); + layout->setContentsMargins( 0, 0, 0, 0 ); + layout->addWidget( d_treeView ); + + connect( d_treeView, SIGNAL( clicked( const QModelIndex & ) ), + this, SLOT( handleClick( const QModelIndex & ) ) ); +} + +Legend::~Legend() +{ +} + +void Legend::renderLegend( QPainter *painter, + const QRectF &rect, bool fillBackground ) const +{ + if ( fillBackground ) + { + if ( autoFillBackground() || + testAttribute( Qt::WA_StyledBackground ) ) + { + qwtRenderBackground( painter, rect, d_treeView ); + } + } + + QStyleOptionViewItem styleOption; + styleOption.initFrom( this ); + styleOption.decorationAlignment = Qt::AlignCenter; + + const QAbstractItemDelegate *delegate = d_treeView->itemDelegate(); + + const QStandardItemModel *mdl = + qobject_cast( d_treeView->model() ); + + painter->save(); + painter->translate( rect.topLeft() ); + + for ( int row = 0; row < mdl->rowCount(); row++ ) + { + const QStandardItem *rootItem = mdl->item( row ); + + styleOption.rect = d_treeView->visualRect( rootItem->index() ); + if ( !styleOption.rect.isEmpty() ) + delegate->paint( painter, styleOption, rootItem->index() ); + + for ( int i = 0; i < rootItem->rowCount(); i++ ) + { + const QStandardItem *item = rootItem->child( i ); + + styleOption.rect = d_treeView->visualRect( item->index() ); + if ( !styleOption.rect.isEmpty() ) + { + delegate->paint( painter, styleOption, item->index() ); + } + } + } + painter->restore(); +} + +bool Legend::isEmpty() const +{ + return d_treeView->model()->rowCount() == 0; +} + +int Legend::scrollExtent( Qt::Orientation orientation ) const +{ + Q_UNUSED( orientation ); + + return style()->pixelMetric( QStyle::PM_ScrollBarExtent ); +} + +void Legend::updateLegend( const QVariant &itemInfo, + const QList &data ) +{ + QwtPlotItem *plotItem = qvariant_cast( itemInfo ); + + QStandardItem *rootItem = d_treeView->rootItem( plotItem->rtti() ); + QList itemList = d_treeView->itemList( plotItem ); + + while ( itemList.size() > data.size() ) + { + QStandardItem *item = itemList.takeLast(); + rootItem->removeRow( item->row() ); + } + + if ( !data.isEmpty() ) + { + if ( rootItem == NULL ) + rootItem = d_treeView->insertRootItem( plotItem->rtti() ); + + while ( itemList.size() < data.size() ) + { + QStandardItem *item = new QStandardItem(); + item->setEditable( false ); + item->setData( qlonglong( plotItem ) ); + item->setCheckable( true ); + item->setCheckState( plotItem->isVisible() ? + Qt::Checked : Qt::Unchecked ); + + itemList += item; + rootItem->appendRow( item ); + } + + for ( int i = 0; i < itemList.size(); i++ ) + updateItem( itemList[i], data[i] ); + } + else + { + if ( rootItem && rootItem->rowCount() == 0 ) + d_treeView->model()->removeRow( rootItem->row() ); + } + + d_treeView->updateGeometry(); +} + +void Legend::updateItem( QStandardItem *item, const QwtLegendData &data ) +{ + const QVariant titleValue = data.value( QwtLegendData::TitleRole ); + + QwtText title; + if ( titleValue.canConvert() ) + { + item->setText( title.text() ); + title = titleValue.value(); + } + else if ( titleValue.canConvert() ) + { + title.setText( titleValue.value() ); + } + item->setText( title.text() ); + + const QVariant iconValue = data.value( QwtLegendData::IconRole ); + + QPixmap pm; + if ( iconValue.canConvert() ) + pm = iconValue.value(); + + item->setData(pm, Qt::DecorationRole); +} + +void Legend::handleClick( const QModelIndex &index ) +{ + const QStandardItemModel *model = + qobject_cast( d_treeView->model() ); + + const QStandardItem *item = model->itemFromIndex( index ); + if ( item->isCheckable() ) + { + const qlonglong ptr = item->data().value(); + + Q_EMIT checked( (QwtPlotItem *)ptr, + item->checkState() == Qt::Checked, 0 ); + } +} diff --git a/ThirdParty/Qwt/examples/stockchart/legend.h b/ThirdParty/Qwt/examples/stockchart/legend.h new file mode 100644 index 0000000000..56cd7cdf2e --- /dev/null +++ b/ThirdParty/Qwt/examples/stockchart/legend.h @@ -0,0 +1,42 @@ +#ifndef _LEGEND_H_ +#define _LEGEND_H_ + +#include + +class LegendTreeView; +class QStandardItem; +class QModelIndex; +class QwtPlotItem; + +class Legend : public QwtAbstractLegend +{ + Q_OBJECT + +public: + explicit Legend( QWidget *parent = NULL ); + virtual ~Legend(); + + virtual void renderLegend( QPainter *, + const QRectF &, bool fillBackground ) const; + + virtual bool isEmpty() const; + + virtual int scrollExtent( Qt::Orientation ) const; + +Q_SIGNALS: + void checked( QwtPlotItem *plotItem, bool on, int index ); + +public Q_SLOTS: + virtual void updateLegend( const QVariant &, + const QList & ); + +private Q_SLOTS: + void handleClick( const QModelIndex & ); + +private: + void updateItem( QStandardItem *, const QwtLegendData & ); + + LegendTreeView *d_treeView; +}; + +#endif diff --git a/ThirdParty/Qwt/examples/stockchart/main.cpp b/ThirdParty/Qwt/examples/stockchart/main.cpp new file mode 100644 index 0000000000..14e116a42e --- /dev/null +++ b/ThirdParty/Qwt/examples/stockchart/main.cpp @@ -0,0 +1,54 @@ +#include +#include +#include +#include +#include +#include "plot.h" + +class MainWindow: public QMainWindow +{ +public: + MainWindow( QWidget * = NULL ); + +private: + Plot *d_plot; +}; + +MainWindow::MainWindow( QWidget *parent ): + QMainWindow( parent ) +{ + d_plot = new Plot( this ); + setCentralWidget( d_plot ); + + QToolBar *toolBar = new QToolBar( this ); + + QComboBox *typeBox = new QComboBox( toolBar ); + typeBox->addItem( "Bars" ); + typeBox->addItem( "CandleSticks" ); + typeBox->setCurrentIndex( 1 ); + typeBox->setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ); + + QToolButton *btnExport = new QToolButton( toolBar ); + btnExport->setText( "Export" ); + btnExport->setToolButtonStyle( Qt::ToolButtonTextUnderIcon ); + connect( btnExport, SIGNAL( clicked() ), d_plot, SLOT( exportPlot() ) ); + + toolBar->addWidget( typeBox ); + toolBar->addWidget( btnExport ); + addToolBar( toolBar ); + + d_plot->setMode( typeBox->currentIndex() ); + connect( typeBox, SIGNAL( currentIndexChanged( int ) ), + d_plot, SLOT( setMode( int ) ) ); +} + +int main( int argc, char **argv ) +{ + QApplication a( argc, argv ); + + MainWindow w; + w.resize( 600, 400 ); + w.show(); + + return a.exec(); +} diff --git a/ThirdParty/Qwt/examples/stockchart/plot.cpp b/ThirdParty/Qwt/examples/stockchart/plot.cpp new file mode 100644 index 0000000000..addf665c53 --- /dev/null +++ b/ThirdParty/Qwt/examples/stockchart/plot.cpp @@ -0,0 +1,253 @@ +#include "plot.h" +#include "legend.h" +#include "griditem.h" +#include "quotefactory.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class Zoomer: public QwtPlotZoomer +{ +public: + Zoomer( QWidget *canvas ): + QwtPlotZoomer( canvas ) + { + setRubberBandPen( QColor( Qt::darkGreen ) ); + setTrackerMode( QwtPlotPicker::AlwaysOn ); + } + +protected: + virtual QwtText trackerTextF( const QPointF &pos ) const + { + const QDateTime dt = QwtDate::toDateTime( pos.x() ); + + QString s; + s += QwtDate::toString( QwtDate::toDateTime( pos.x() ), + "MMM dd hh:mm ", QwtDate::FirstThursday ); + + QwtText text( s ); + text.setColor( Qt::white ); + + QColor c = rubberBandPen().color(); + text.setBorderPen( QPen( c ) ); + text.setBorderRadius( 6 ); + c.setAlpha( 170 ); + text.setBackgroundBrush( c ); + + return text; + } +}; + +class DateScaleDraw: public QwtDateScaleDraw +{ +public: + DateScaleDraw( Qt::TimeSpec timeSpec ): + QwtDateScaleDraw( timeSpec ) + { + // as we have dates from 2010 only we use + // format strings without the year + + setDateFormat( QwtDate::Millisecond, "hh:mm:ss:zzz\nddd dd MMM" ); + setDateFormat( QwtDate::Second, "hh:mm:ss\nddd dd MMM" ); + setDateFormat( QwtDate::Minute, "hh:mm\nddd dd MMM" ); + setDateFormat( QwtDate::Hour, "hh:mm\nddd dd MMM" ); + setDateFormat( QwtDate::Day, "ddd dd MMM" ); + setDateFormat( QwtDate::Week, "Www" ); + setDateFormat( QwtDate::Month, "MMM" ); + } +}; + +class ZoneItem: public QwtPlotZoneItem +{ +public: + ZoneItem( const QString &title ) + { + setTitle( title ); + setZ( 11 ); // on top the the grid + setOrientation( Qt::Vertical ); + setItemAttribute( QwtPlotItem::Legend, true ); + } + + void setColor( const QColor &color ) + { + QColor c = color; + + c.setAlpha( 100 ); + setPen( c ); + + c.setAlpha( 20 ); + setBrush( c ); + } + + void setInterval( const QDate &date1, const QDate &date2 ) + { + const QDateTime dt1( date1, QTime(), Qt::UTC ); + const QDateTime dt2( date2, QTime(), Qt::UTC ); + + QwtPlotZoneItem::setInterval( QwtDate::toDouble( dt1 ), + QwtDate::toDouble( dt2 ) ); + } +}; + +Plot::Plot( QWidget *parent ): + QwtPlot( parent ) +{ + setTitle( "Trading Chart" ); + + QwtDateScaleDraw *scaleDraw = new DateScaleDraw( Qt::UTC ); + QwtDateScaleEngine *scaleEngine = new QwtDateScaleEngine( Qt::UTC ); + + setAxisTitle( QwtPlot::xBottom, QString( "2010" ) ); + setAxisScaleDraw( QwtPlot::xBottom, scaleDraw ); + setAxisScaleEngine( QwtPlot::xBottom, scaleEngine ); + setAxisLabelRotation( QwtPlot::xBottom, -50.0 ); + setAxisLabelAlignment( QwtPlot::xBottom, Qt::AlignLeft | Qt::AlignBottom ); + + setAxisTitle( QwtPlot::yLeft, QString( "Price [EUR]" ) ); + +#if 0 + QwtLegend *legend = new QwtLegend; + legend->setDefaultItemMode( QwtLegendData::Checkable ); + insertLegend( legend, QwtPlot::RightLegend ); +#else + Legend *legend = new Legend; + insertLegend( legend, QwtPlot::RightLegend ); +#endif + + populate(); + + // LeftButton for the zooming + // MidButton for the panning + // RightButton: zoom out by 1 + // Ctrl+RighButton: zoom out to full size + + Zoomer* zoomer = new Zoomer( canvas() ); + zoomer->setMousePattern( QwtEventPattern::MouseSelect2, + Qt::RightButton, Qt::ControlModifier ); + zoomer->setMousePattern( QwtEventPattern::MouseSelect3, + Qt::RightButton ); + + QwtPlotPanner *panner = new QwtPlotPanner( canvas() ); + panner->setMouseButton( Qt::MidButton ); + + connect( legend, SIGNAL( checked( QwtPlotItem *, bool, int ) ), + SLOT( showItem( QwtPlotItem *, bool ) ) ); +} + +void Plot::populate() +{ + GridItem *gridItem = new GridItem(); +#if 0 + gridItem->setOrientations( Qt::Horizontal ); +#endif + gridItem->attach( this ); + + const Qt::GlobalColor colors[] = + { + Qt::red, + Qt::blue, + Qt::darkCyan, + Qt::darkMagenta, + Qt::darkYellow + }; + + const int numColors = sizeof( colors ) / sizeof( colors[0] ); + + for ( int i = 0; i < QuoteFactory::NumStocks; i++ ) + { + QuoteFactory::Stock stock = static_cast( i ); + + QwtPlotTradingCurve *curve = new QwtPlotTradingCurve(); + curve->setTitle( QuoteFactory::title( stock ) ); + curve->setOrientation( Qt::Vertical ); + curve->setSamples( QuoteFactory::samples2010( stock ) ); + + // as we have one sample per day a symbol width of + // 12h avoids overlapping symbols. We also bound + // the width, so that is is not scaled below 3 and + // above 15 pixels. + + curve->setSymbolExtent( 12 * 3600 * 1000.0 ); + curve->setMinSymbolWidth( 3 ); + curve->setMaxSymbolWidth( 15 ); + + const Qt::GlobalColor color = colors[ i % numColors ]; + + curve->setSymbolPen( color ); + curve->setSymbolBrush( QwtPlotTradingCurve::Decreasing, color ); + curve->setSymbolBrush( QwtPlotTradingCurve::Increasing, Qt::white ); + curve->attach( this ); + + showItem( curve, true ); + } + + for ( int i = 0; i < 2; i++ ) + { + QwtPlotMarker *marker = new QwtPlotMarker(); + + marker->setTitle( QString( "Event %1" ).arg( i + 1 ) ); + marker->setLineStyle( QwtPlotMarker::VLine ); + marker->setLinePen( colors[ i % numColors ], 0, Qt::DashLine ); + marker->setVisible( false ); + + QDateTime dt( QDate( 2010, 1, 1 ) ); + dt = dt.addDays( 77 * ( i + 1 ) ); + + marker->setValue( QwtDate::toDouble( dt ), 0.0 ); + + marker->setItemAttribute( QwtPlotItem::Legend, true ); + + marker->attach( this ); + } + + // to show how QwtPlotZoneItem works + + ZoneItem *zone1 = new ZoneItem( "Zone 1"); + zone1->setColor( Qt::darkBlue ); + zone1->setInterval( QDate( 2010, 3, 10 ), QDate( 2010, 3, 27 ) ); + zone1->setVisible( false ); + zone1->attach( this ); + + ZoneItem *zone2 = new ZoneItem( "Zone 2"); + zone2->setColor( Qt::darkMagenta ); + zone2->setInterval( QDate( 2010, 8, 1 ), QDate( 2010, 8, 24 ) ); + zone2->setVisible( false ); + zone2->attach( this ); + +} + +void Plot::setMode( int style ) +{ + QwtPlotTradingCurve::SymbolStyle symbolStyle = + static_cast( style ); + + QwtPlotItemList curves = itemList( QwtPlotItem::Rtti_PlotTradingCurve ); + for ( int i = 0; i < curves.size(); i++ ) + { + QwtPlotTradingCurve *curve = + static_cast( curves[i] ); + curve->setSymbolStyle( symbolStyle ); + } + + replot(); +} + +void Plot::showItem( QwtPlotItem *item, bool on ) +{ + item->setVisible( on ); + replot(); +} + +void Plot::exportPlot() +{ + QwtPlotRenderer renderer; + renderer.exportTo( this, "stockchart.pdf" ); +} diff --git a/ThirdParty/Qwt/examples/stockchart/plot.h b/ThirdParty/Qwt/examples/stockchart/plot.h new file mode 100644 index 0000000000..bc6f883c26 --- /dev/null +++ b/ThirdParty/Qwt/examples/stockchart/plot.h @@ -0,0 +1,24 @@ +#ifndef _PLOT_H_ +#define _PLOT_H_ + +#include + +class Plot: public QwtPlot +{ + Q_OBJECT + +public: + Plot( QWidget * = NULL ); + +public Q_SLOTS: + void setMode( int ); + void exportPlot(); + +private Q_SLOTS: + void showItem( QwtPlotItem *, bool on ); + +private: + void populate(); +}; + +#endif diff --git a/ThirdParty/Qwt/examples/stockchart/quotefactory.cpp b/ThirdParty/Qwt/examples/stockchart/quotefactory.cpp new file mode 100644 index 0000000000..4956601852 --- /dev/null +++ b/ThirdParty/Qwt/examples/stockchart/quotefactory.cpp @@ -0,0 +1,856 @@ +#include "quotefactory.h" +#include + +typedef struct +{ + int day; + + double open; + double high; + double low; + double close; + +} t_Data2010; + +static t_Data2010 bmwData[] = +{ + { 3, 31.82, 32.46, 31.82, 32.05 }, + { 4, 31.96, 32.41, 31.78, 32.31 }, + { 5, 32.45, 33.04, 32.36, 32.81 }, + { 6, 32.65, 33.20, 32.38, 33.10 }, + { 7, 33.33, 33.43, 32.51, 32.65 }, + { 10, 32.99, 33.05, 32.11, 32.17 }, + { 11, 32.26, 32.26, 31.10, 31.24 }, + { 12, 31.03, 31.52, 31.01, 31.42 }, + { 13, 31.61, 32.18, 31.50, 31.89 }, + { 14, 32.05, 32.13, 31.36, 31.63 }, + { 17, 31.82, 32.12, 31.43, 32.10 }, + { 18, 32.33, 32.45, 31.65, 32.43 }, + { 19, 32.30, 32.39, 31.67, 31.80 }, + { 20, 32.00, 32.19, 31.16, 31.16 }, + { 21, 31.14, 31.37, 30.32, 30.70 }, + { 24, 30.31, 30.79, 30.05, 30.14 }, + { 25, 30.00, 30.53, 29.40, 30.25 }, + { 26, 29.93, 30.14, 29.38, 29.59 }, + { 27, 29.95, 30.28, 29.49, 29.55 }, + { 28, 29.90, 31.30, 29.85, 30.96 }, + { 31, 30.69, 31.31, 30.56, 31.07 }, + { 32, 31.05, 31.28, 30.58, 31.17 }, + { 33, 31.28, 31.77, 31.01, 31.23 }, + { 34, 31.32, 31.53, 30.21, 30.33 }, + { 35, 30.25, 30.28, 29.43, 29.92 }, + { 38, 30.00, 30.45, 29.33, 29.61 }, + { 39, 29.75, 30.07, 29.35, 29.62 }, + { 40, 29.89, 30.12, 29.55, 29.67 }, + { 41, 29.81, 29.87, 29.02, 29.49 }, + { 42, 29.59, 29.84, 28.28, 29.00 }, + { 45, 29.00, 29.29, 28.46, 28.65 }, + { 46, 28.90, 29.45, 28.60, 29.41 }, + { 47, 29.68, 29.77, 29.35, 29.61 }, + { 48, 29.58, 29.76, 28.45, 29.42 }, + { 49, 29.22, 30.43, 29.01, 30.43 }, + { 52, 30.65, 30.67, 30.06, 30.26 }, + { 53, 30.35, 30.52, 29.53, 29.69 }, + { 54, 29.79, 29.87, 29.18, 29.49 }, + { 55, 29.25, 29.82, 29.06, 29.38 }, + { 56, 29.69, 30.00, 29.55, 29.78 }, + { 59, 30.20, 30.58, 29.95, 30.44 }, + { 60, 30.57, 31.47, 30.49, 31.34 }, + { 61, 31.40, 31.76, 31.08, 31.65 }, + { 62, 31.50, 31.80, 31.34, 31.56 }, + { 63, 31.63, 32.45, 31.63, 32.37 }, + { 66, 32.40, 32.54, 31.81, 31.99 }, + { 67, 31.83, 32.29, 31.58, 32.13 }, + { 68, 32.06, 32.33, 31.81, 32.26 }, + { 69, 32.17, 33.26, 32.16, 32.69 }, + { 70, 32.85, 32.94, 32.44, 32.54 }, + { 73, 32.62, 32.92, 32.54, 32.64 }, + { 74, 32.78, 32.97, 32.55, 32.76 }, + { 75, 32.83, 33.04, 32.45, 32.47 }, + { 76, 32.43, 32.56, 31.98, 32.10 }, + { 77, 32.42, 32.49, 32.02, 32.06 }, + { 80, 31.92, 32.65, 31.87, 32.50 }, + { 81, 32.69, 33.44, 32.61, 33.15 }, + { 82, 33.33, 33.51, 32.92, 33.38 }, + { 83, 33.50, 34.10, 33.49, 34.04 }, + { 84, 33.94, 34.35, 33.81, 34.20 }, + { 87, 34.40, 34.73, 34.01, 34.12 }, + { 88, 34.26, 34.43, 33.71, 33.78 }, + { 89, 33.88, 34.29, 33.78, 34.18 }, + { 90, 35.11, 35.49, 34.97, 35.15 }, + { 95, 35.40, 35.45, 35.15, 35.41 }, + { 96, 35.34, 35.41, 34.77, 34.80 }, + { 97, 34.80, 35.06, 34.44, 34.53 }, + { 98, 34.88, 35.05, 34.64, 34.86 }, + { 101, 35.25, 35.39, 34.99, 35.12 }, + { 102, 35.06, 35.38, 34.88, 35.35 }, + { 103, 35.06, 35.58, 34.88, 35.51 }, + { 104, 35.59, 35.61, 35.09, 35.33 }, + { 105, 35.15, 36.19, 35.15, 35.56 }, + { 108, 35.45, 35.78, 35.10, 35.31 }, + { 109, 36.56, 37.08, 36.41, 36.79 }, + { 110, 36.75, 36.99, 36.37, 36.58 }, + { 111, 36.63, 37.12, 35.93, 36.25 }, + { 112, 36.60, 37.40, 36.33, 37.28 }, + { 115, 37.60, 37.85, 37.26, 37.82 }, + { 116, 37.85, 37.96, 37.06, 37.06 }, + { 117, 36.80, 37.28, 36.14, 36.79 }, + { 118, 36.70, 36.90, 36.19, 36.78 }, + { 119, 36.83, 37.62, 36.70, 37.13 }, + { 122, 37.08, 37.50, 36.72, 37.38 }, + { 123, 37.51, 37.56, 35.38, 35.84 }, + { 124, 36.61, 36.62, 35.42, 35.98 }, + { 125, 35.45, 37.38, 35.45, 36.42 }, + { 126, 35.78, 36.90, 35.05, 35.48 }, + { 129, 36.23, 37.74, 36.20, 37.68 }, + { 130, 36.87, 38.19, 36.73, 38.18 }, + { 131, 37.97, 39.35, 37.74, 39.00 }, + { 132, 39.35, 40.06, 39.15, 39.52 }, + { 133, 39.42, 39.88, 38.46, 38.62 }, + { 136, 38.38, 39.59, 38.25, 38.72 }, + { 137, 39.10, 39.65, 38.90, 39.65 }, + { 138, 38.15, 38.70, 36.97, 37.00 }, + { 139, 37.44, 37.55, 35.43, 36.18 }, + { 140, 36.20, 36.57, 35.28, 36.03 }, + { 143, 36.30, 36.38, 35.41, 36.14 }, + { 144, 35.56, 35.67, 34.64, 35.29 }, + { 145, 35.80, 36.32, 35.50, 35.76 }, + { 146, 36.30, 37.33, 36.06, 37.21 }, + { 147, 37.42, 37.88, 37.02, 37.67 }, + { 150, 37.57, 38.09, 37.49, 37.97 }, + { 151, 37.96, 38.38, 36.98, 38.06 }, + { 152, 37.80, 38.46, 37.37, 38.46 }, + { 153, 39.24, 39.55, 38.94, 39.22 }, + { 154, 39.35, 39.40, 37.82, 38.10 }, + { 157, 37.40, 38.55, 37.40, 38.24 }, + { 158, 38.33, 38.54, 37.31, 37.68 }, + { 159, 37.85, 38.98, 37.76, 38.91 }, + { 160, 38.85, 40.92, 38.68, 40.65 }, + { 161, 40.95, 41.27, 39.72, 40.08 }, + { 164, 40.59, 40.85, 39.56, 39.76 }, + { 165, 39.35, 40.05, 39.34, 39.85 }, + { 166, 40.18, 40.41, 38.80, 39.03 }, + { 167, 38.91, 39.96, 38.74, 39.70 }, + { 168, 39.85, 40.87, 39.82, 40.71 }, + { 171, 41.70, 42.33, 41.43, 41.80 }, + { 172, 41.55, 41.88, 41.06, 41.51 }, + { 173, 41.11, 42.01, 41.07, 41.49 }, + { 174, 41.97, 42.19, 41.25, 41.36 }, + { 175, 41.36, 41.38, 40.22, 40.36 }, + { 178, 40.66, 41.64, 40.36, 41.26 }, + { 179, 40.84, 40.88, 39.87, 39.90 }, + { 180, 40.10, 40.61, 39.80, 40.06 }, + { 181, 39.56, 39.56, 38.08, 38.20 }, + { 182, 38.83, 39.20, 37.79, 37.88 }, + { 185, 38.10, 38.53, 37.91, 38.11 }, + { 186, 38.29, 39.27, 38.29, 39.00 }, + { 187, 38.70, 39.87, 38.62, 39.75 }, + { 188, 39.62, 39.97, 38.87, 38.91 }, + { 189, 39.30, 39.39, 38.60, 39.15 }, + { 192, 39.30, 39.30, 38.87, 38.90 }, + { 193, 39.00, 42.14, 39.00, 42.13 }, + { 194, 42.42, 42.71, 40.99, 41.54 }, + { 195, 41.75, 42.94, 41.36, 42.26 }, + { 196, 42.26, 43.29, 41.80, 42.15 }, + { 199, 41.85, 42.09, 41.17, 41.35 }, + { 200, 42.00, 42.12, 40.60, 41.07 }, + { 201, 41.30, 41.80, 40.61, 40.92 }, + { 202, 40.83, 42.35, 40.79, 41.97 }, + { 203, 41.95, 42.24, 41.58, 41.99 }, + { 206, 42.17, 42.29, 41.61, 42.11 }, + { 207, 42.24, 42.49, 41.21, 41.50 }, + { 208, 41.68, 41.88, 40.41, 40.72 }, + { 209, 40.77, 41.22, 40.40, 40.72 }, + { 210, 40.44, 41.40, 39.96, 41.31 }, + { 213, 41.46, 42.01, 41.02, 41.87 }, + { 214, 42.75, 44.04, 42.75, 43.16 }, + { 215, 43.14, 43.83, 42.49, 43.68 }, + { 216, 43.69, 44.99, 43.47, 44.51 }, + { 217, 44.90, 45.38, 43.72, 43.90 }, + { 220, 44.49, 44.60, 43.97, 44.31 }, + { 221, 44.35, 44.40, 43.15, 43.35 }, + { 222, 43.05, 43.08, 42.33, 42.40 }, + { 223, 42.30, 42.92, 40.78, 41.90 }, + { 224, 42.02, 42.22, 41.28, 41.88 }, + { 227, 42.08, 42.29, 41.40, 41.81 }, + { 228, 41.81, 43.10, 41.74, 43.10 }, + { 229, 43.02, 43.59, 42.76, 43.50 }, + { 230, 43.68, 44.07, 42.66, 42.84 }, + { 231, 42.84, 42.92, 41.74, 41.87 }, + { 234, 42.00, 42.31, 41.60, 41.86 }, + { 235, 41.56, 41.76, 41.10, 41.52 }, + { 236, 41.22, 41.97, 40.83, 41.44 }, + { 237, 41.56, 41.96, 41.35, 41.69 }, + { 238, 41.60, 41.81, 40.74, 41.76 }, + { 241, 41.76, 41.90, 40.94, 41.21 }, + { 242, 40.50, 41.67, 40.15, 41.67 }, + { 243, 42.00, 42.99, 41.38, 42.91 }, + { 244, 42.64, 43.89, 42.64, 43.60 }, + { 245, 43.60, 44.53, 43.26, 44.10 }, + { 248, 44.17, 44.20, 43.47, 44.03 }, + { 249, 43.97, 44.31, 43.51, 43.94 }, + { 250, 43.72, 44.99, 43.60, 44.99 }, + { 251, 44.70, 45.74, 44.51, 45.40 }, + { 252, 45.00, 46.87, 44.99, 46.21 }, + { 255, 46.65, 47.05, 45.91, 46.44 }, + { 256, 46.30, 47.12, 46.21, 47.12 }, + { 257, 46.98, 47.56, 46.88, 47.25 }, + { 258, 47.18, 47.45, 46.82, 47.35 }, + { 259, 47.81, 48.03, 47.10, 47.41 }, + { 262, 47.37, 49.12, 47.22, 49.12 }, + { 263, 48.85, 49.42, 48.45, 48.48 }, + { 264, 48.48, 48.70, 47.57, 48.08 }, + { 265, 48.49, 48.69, 47.49, 48.29 }, + { 266, 48.09, 50.53, 48.03, 50.35 }, + { 269, 50.15, 50.35, 49.60, 50.15 }, + { 270, 49.80, 50.69, 49.31, 50.67 }, + { 271, 51.00, 51.84, 50.64, 51.06 }, + { 272, 50.90, 52.15, 50.50, 51.44 }, + { 273, 51.44, 51.44, 49.12, 49.30 }, + { 276, 49.06, 49.19, 47.92, 48.22 }, + { 277, 48.37, 49.96, 47.82, 49.96 }, + { 278, 49.77, 50.05, 49.13, 49.49 }, + { 279, 49.31, 50.25, 48.81, 50.00 }, + { 280, 50.26, 50.29, 49.42, 50.07 }, + { 283, 50.20, 50.62, 49.82, 49.87 }, + { 284, 49.44, 50.49, 49.06, 50.20 }, + { 285, 50.40, 50.49, 49.88, 50.07 }, + { 286, 50.50, 50.50, 49.74, 50.00 }, + { 287, 50.08, 50.25, 49.19, 49.45 }, + { 290, 49.23, 49.42, 48.58, 49.00 }, + { 291, 48.99, 49.69, 48.84, 49.12 }, + { 292, 49.09, 49.60, 48.90, 49.60 }, + { 293, 49.54, 50.09, 49.31, 50.02 }, + { 294, 50.19, 50.44, 49.54, 50.03 }, + { 297, 50.31, 51.02, 50.20, 50.72 }, + { 298, 50.49, 50.94, 50.12, 50.44 }, + { 299, 50.04, 50.45, 49.10, 49.88 }, + { 300, 50.15, 50.48, 49.53, 49.85 }, + { 301, 49.49, 51.65, 49.44, 51.51 }, + { 304, 51.77, 52.99, 51.65, 52.96 }, + { 305, 52.70, 52.70, 52.10, 52.35 }, + { 306, 50.75, 52.38, 50.65, 51.64 }, + { 307, 52.05, 54.15, 52.00, 54.08 }, + { 308, 54.14, 54.99, 53.76, 54.06 }, + { 311, 53.69, 53.77, 52.86, 53.41 }, + { 312, 53.40, 54.98, 53.22, 54.91 }, + { 313, 54.60, 54.70, 53.33, 53.75 }, + { 314, 54.00, 54.49, 53.60, 54.42 }, + { 315, 53.33, 55.90, 52.85, 55.29 }, + { 318, 55.07, 56.52, 54.90, 56.06 }, + { 319, 55.68, 55.83, 54.62, 54.62 }, + { 320, 54.72, 54.73, 53.87, 54.30 }, + { 321, 54.96, 56.30, 54.94, 56.30 }, + { 322, 56.34, 56.73, 55.65, 56.67 }, + { 325, 57.33, 58.90, 57.30, 57.69 }, + { 326, 57.15, 58.62, 56.39, 56.47 }, + { 327, 57.01, 59.12, 56.48, 59.12 }, + { 328, 59.10, 60.00, 58.84, 59.90 }, + { 329, 59.31, 59.76, 58.13, 59.25 }, + { 332, 59.75, 59.91, 57.74, 57.74 }, + { 333, 57.70, 59.24, 57.22, 57.93 }, + { 334, 58.35, 60.90, 58.35, 60.90 }, + { 335, 61.69, 63.80, 61.55, 63.80 }, + { 336, 63.70, 65.49, 63.48, 63.69 }, + { 339, 64.00, 64.53, 62.75, 62.81 }, + { 340, 63.00, 64.49, 62.40, 63.98 }, + { 341, 63.50, 63.50, 61.90, 61.90 }, + { 342, 62.42, 62.66, 58.88, 60.20 }, + { 343, 60.50, 62.99, 60.39, 62.52 }, + { 346, 62.00, 63.44, 62.00, 63.44 }, + { 347, 63.40, 63.44, 62.14, 62.47 }, + { 348, 62.00, 62.83, 61.40, 62.49 }, + { 349, 62.40, 63.26, 61.79, 62.80 }, + { 350, 62.95, 63.15, 61.80, 61.95 }, + { 353, 61.90, 63.23, 61.64, 63.15 }, + { 354, 63.40, 64.80, 62.92, 64.80 }, + { 355, 64.98, 65.11, 64.30, 64.37 }, + { 356, 64.55, 64.69, 63.24, 63.26 }, + { 360, 62.70, 62.70, 59.12, 59.22 }, + { 361, 59.69, 59.98, 57.66, 58.25 }, + { 362, 58.10, 58.92, 58.08, 58.72 }, + { 363, 59.10, 59.47, 58.62, 58.85 } +}; + +static t_Data2010 porscheData[] = +{ + { 3, 43.00, 43.96, 42.80, 43.37 }, + { 4, 43.15, 45.00, 43.00, 44.77 }, + { 5, 45.75, 46.50, 45.41, 45.65 }, + { 6, 45.67, 48.56, 45.32, 48.28 }, + { 7, 48.78, 48.81, 47.39, 48.00 }, + { 10, 48.26, 49.18, 47.86, 48.35 }, + { 11, 48.35, 48.65, 46.73, 47.05 }, + { 12, 46.51, 47.65, 46.35, 47.37 }, + { 13, 48.10, 48.70, 47.00, 48.13 }, + { 14, 48.10, 48.20, 46.79, 47.85 }, + { 17, 47.85, 48.57, 47.58, 48.10 }, + { 18, 47.85, 48.00, 46.51, 47.65 }, + { 19, 47.24, 47.62, 45.86, 46.40 }, + { 20, 46.51, 46.61, 44.87, 45.00 }, + { 21, 45.00, 45.11, 42.92, 43.50 }, + { 24, 43.00, 43.83, 42.48, 42.97 }, + { 25, 42.47, 43.37, 41.90, 43.23 }, + { 26, 43.00, 43.00, 41.55, 42.28 }, + { 27, 42.80, 42.83, 41.65, 41.72 }, + { 28, 40.91, 41.50, 40.10, 41.11 }, + { 31, 40.85, 41.85, 40.81, 41.55 }, + { 32, 41.69, 43.16, 41.28, 42.87 }, + { 33, 43.47, 43.53, 42.30, 42.47 }, + { 34, 42.67, 42.85, 40.95, 41.15 }, + { 35, 40.81, 40.82, 39.56, 40.03 }, + { 38, 40.00, 40.94, 38.45, 38.95 }, + { 39, 38.65, 38.95, 37.83, 38.24 }, + { 40, 38.30, 38.65, 37.92, 38.30 }, + { 41, 38.40, 39.88, 37.91, 38.36 }, + { 42, 38.60, 38.84, 36.06, 36.99 }, + { 45, 37.31, 37.58, 35.85, 36.06 }, + { 46, 36.45, 36.78, 35.90, 36.78 }, + { 47, 37.01, 37.84, 36.14, 37.42 }, + { 48, 37.40, 37.73, 36.03, 37.16 }, + { 49, 36.90, 38.00, 36.72, 37.97 }, + { 52, 37.52, 38.12, 37.14, 37.14 }, + { 53, 37.22, 37.53, 36.34, 36.69 }, + { 54, 36.88, 36.93, 35.94, 36.55 }, + { 55, 36.35, 37.06, 35.75, 36.09 }, + { 56, 36.70, 37.05, 36.10, 36.90 }, + { 59, 37.10, 37.74, 36.78, 37.63 }, + { 60, 37.65, 38.58, 37.65, 38.56 }, + { 61, 38.35, 39.60, 38.35, 39.42 }, + { 62, 39.39, 40.15, 39.10, 39.70 }, + { 63, 39.75, 40.60, 39.10, 40.35 }, + { 66, 40.40, 40.40, 39.55, 39.97 }, + { 67, 40.05, 40.10, 39.13, 39.90 }, + { 68, 39.78, 40.55, 39.52, 40.37 }, + { 69, 39.86, 42.53, 39.62, 42.34 }, + { 70, 42.75, 44.73, 42.66, 43.03 }, + { 73, 43.27, 43.49, 42.60, 42.65 }, + { 74, 42.78, 43.78, 42.78, 43.78 }, + { 75, 43.73, 44.00, 42.57, 43.46 }, + { 76, 44.10, 44.51, 43.50, 44.51 }, + { 77, 44.40, 44.70, 44.04, 44.04 }, + { 80, 44.00, 44.05, 43.03, 43.69 }, + { 81, 43.13, 43.51, 42.08, 43.17 }, + { 82, 42.89, 44.71, 42.65, 44.20 }, + { 83, 44.31, 44.47, 43.59, 44.22 }, + { 84, 44.15, 45.15, 44.00, 45.13 }, + { 87, 45.45, 46.10, 45.20, 45.51 }, + { 88, 45.76, 46.10, 44.83, 45.17 }, + { 89, 45.60, 45.60, 44.90, 45.19 }, + { 90, 45.60, 46.46, 45.60, 46.37 }, + { 95, 46.00, 47.44, 46.00, 47.24 }, + { 96, 47.22, 47.48, 45.76, 46.04 }, + { 97, 45.05, 45.55, 44.04, 44.41 }, + { 98, 44.88, 45.44, 44.44, 44.99 }, + { 101, 45.20, 45.57, 44.88, 45.35 }, + { 102, 45.10, 46.03, 45.02, 45.71 }, + { 103, 46.02, 46.60, 45.54, 46.30 }, + { 104, 46.44, 46.60, 45.72, 46.04 }, + { 105, 45.80, 46.35, 44.67, 44.67 }, + { 108, 44.50, 45.17, 43.79, 43.83 }, + { 109, 45.39, 46.00, 44.66, 45.92 }, + { 110, 46.00, 46.46, 45.26, 46.26 }, + { 111, 46.29, 46.64, 44.94, 45.20 }, + { 112, 45.69, 46.22, 45.22, 45.97 }, + { 115, 46.30, 46.71, 45.85, 46.69 }, + { 116, 46.48, 46.48, 45.01, 45.01 }, + { 117, 44.60, 45.03, 42.97, 44.03 }, + { 118, 43.50, 44.38, 42.80, 43.76 }, + { 119, 43.40, 44.33, 42.85, 43.69 }, + { 122, 43.70, 43.70, 42.38, 42.71 }, + { 123, 42.95, 42.95, 40.39, 40.53 }, + { 124, 39.99, 40.15, 38.76, 39.95 }, + { 125, 39.05, 40.25, 37.17, 37.40 }, + { 126, 36.30, 37.25, 34.80, 35.58 }, + { 129, 37.54, 38.19, 37.12, 37.92 }, + { 130, 37.79, 38.08, 37.30, 38.08 }, + { 131, 37.94, 39.99, 37.78, 39.73 }, + { 132, 39.80, 40.20, 39.19, 39.73 }, + { 133, 39.35, 39.40, 36.61, 36.72 }, + { 136, 36.29, 38.48, 36.29, 37.58 }, + { 137, 38.33, 38.58, 37.64, 38.47 }, + { 138, 37.77, 38.42, 36.63, 36.67 }, + { 139, 36.40, 36.67, 33.83, 34.72 }, + { 140, 33.85, 34.69, 32.89, 34.07 }, + { 143, 34.49, 35.03, 33.15, 34.40 }, + { 144, 33.40, 33.42, 32.15, 32.54 }, + { 145, 33.28, 34.19, 32.76, 33.49 }, + { 146, 33.85, 35.77, 33.78, 35.49 }, + { 147, 35.99, 36.35, 35.08, 35.53 }, + { 150, 35.24, 35.81, 35.17, 35.34 }, + { 151, 35.21, 36.10, 34.42, 35.24 }, + { 152, 34.55, 35.20, 34.29, 34.85 }, + { 153, 35.63, 36.09, 35.29, 35.70 }, + { 154, 35.98, 35.98, 34.38, 34.50 }, + { 157, 34.45, 34.65, 32.94, 33.26 }, + { 158, 33.50, 33.65, 31.60, 31.91 }, + { 159, 32.42, 33.29, 32.00, 33.22 }, + { 160, 33.10, 33.97, 32.50, 33.58 }, + { 161, 33.97, 35.12, 33.83, 34.85 }, + { 164, 34.90, 35.70, 34.87, 34.97 }, + { 165, 34.40, 34.58, 32.86, 33.46 }, + { 166, 33.87, 33.87, 32.51, 32.87 }, + { 167, 33.17, 34.65, 32.62, 34.60 }, + { 168, 35.58, 35.64, 34.69, 35.06 }, + { 171, 36.52, 37.19, 36.00, 37.00 }, + { 172, 36.87, 37.48, 36.44, 36.85 }, + { 173, 36.38, 36.98, 36.05, 36.40 }, + { 174, 36.00, 36.50, 34.81, 35.08 }, + { 175, 35.21, 36.24, 34.53, 36.04 }, + { 178, 36.76, 37.24, 36.35, 37.16 }, + { 179, 36.49, 36.88, 35.75, 35.81 }, + { 180, 35.92, 36.28, 35.08, 35.29 }, + { 181, 35.00, 35.00, 33.49, 33.54 }, + { 182, 34.00, 34.40, 33.51, 33.51 }, + { 185, 33.80, 34.14, 33.60, 33.74 }, + { 186, 33.75, 35.79, 33.75, 34.96 }, + { 187, 34.85, 35.88, 34.48, 35.88 }, + { 188, 36.00, 36.64, 35.75, 35.96 }, + { 189, 36.41, 36.80, 35.85, 36.72 }, + { 192, 36.60, 37.22, 36.55, 37.08 }, + { 193, 37.10, 38.47, 37.10, 38.08 }, + { 194, 38.19, 38.35, 37.15, 37.49 }, + { 195, 37.35, 37.81, 36.60, 36.87 }, + { 196, 36.76, 37.22, 36.50, 36.74 }, + { 199, 36.51, 36.83, 35.95, 36.08 }, + { 200, 36.12, 36.35, 35.07, 35.42 }, + { 201, 35.40, 36.30, 34.87, 35.08 }, + { 202, 35.00, 37.66, 34.75, 37.47 }, + { 203, 37.70, 39.50, 37.55, 39.12 }, + { 206, 39.43, 39.46, 38.78, 39.18 }, + { 207, 39.30, 39.56, 38.69, 38.98 }, + { 208, 39.00, 39.19, 38.00, 38.23 }, + { 209, 38.10, 39.42, 37.13, 38.72 }, + { 210, 38.88, 39.38, 38.22, 38.82 }, + { 213, 39.26, 39.50, 38.72, 39.01 }, + { 214, 39.07, 40.04, 38.74, 39.10 }, + { 215, 38.85, 39.76, 38.71, 39.29 }, + { 216, 39.30, 39.99, 39.13, 39.53 }, + { 217, 39.50, 40.00, 38.06, 38.32 }, + { 220, 38.60, 39.55, 38.37, 39.38 }, + { 221, 39.48, 39.58, 38.18, 38.56 }, + { 222, 38.58, 38.58, 37.01, 37.31 }, + { 223, 37.32, 37.78, 36.42, 36.82 }, + { 224, 37.30, 37.30, 36.04, 36.53 }, + { 227, 37.00, 37.31, 36.30, 37.12 }, + { 228, 37.00, 38.17, 36.88, 38.00 }, + { 229, 38.10, 38.65, 37.60, 38.58 }, + { 230, 38.60, 39.25, 37.50, 37.88 }, + { 231, 37.85, 37.93, 36.92, 37.26 }, + { 234, 37.53, 38.09, 36.99, 37.64 }, + { 235, 37.59, 37.59, 36.35, 36.80 }, + { 236, 36.50, 36.88, 35.10, 35.93 }, + { 237, 36.40, 36.75, 36.00, 36.35 }, + { 238, 36.50, 36.96, 35.79, 36.78 }, + { 241, 36.91, 37.62, 36.80, 37.15 }, + { 242, 36.45, 36.78, 36.00, 36.74 }, + { 243, 36.82, 38.55, 36.34, 38.26 }, + { 244, 38.67, 39.39, 38.12, 39.26 }, + { 245, 39.28, 39.53, 38.83, 39.29 }, + { 248, 39.40, 39.49, 39.03, 39.28 }, + { 249, 39.30, 39.30, 38.56, 38.80 }, + { 250, 38.55, 39.04, 38.06, 38.89 }, + { 251, 39.00, 39.03, 38.50, 38.90 }, + { 252, 38.90, 39.43, 38.15, 38.30 }, + { 255, 38.76, 38.76, 37.88, 38.09 }, + { 256, 38.37, 38.60, 37.90, 38.42 }, + { 257, 38.69, 39.13, 38.11, 38.68 }, + { 258, 38.27, 38.46, 37.31, 37.41 }, + { 259, 37.88, 38.10, 37.31, 37.60 }, + { 262, 37.62, 37.75, 37.12, 37.52 }, + { 263, 37.50, 37.50, 36.82, 36.83 }, + { 264, 36.95, 37.33, 36.12, 36.12 }, + { 265, 36.07, 36.15, 34.55, 35.62 }, + { 266, 35.29, 36.61, 35.07, 36.53 }, + { 269, 36.60, 36.94, 36.12, 36.50 }, + { 270, 36.15, 36.15, 35.19, 35.51 }, + { 271, 35.51, 36.30, 35.13, 35.56 }, + { 272, 35.96, 36.85, 35.42, 36.33 }, + { 273, 36.50, 36.83, 36.04, 36.31 }, + { 276, 36.44, 36.51, 34.64, 34.74 }, + { 277, 34.75, 35.10, 34.45, 34.99 }, + { 278, 35.45, 35.45, 35.01, 35.20 }, + { 279, 35.50, 35.50, 34.72, 35.10 }, + { 280, 34.80, 35.33, 34.66, 35.25 }, + { 283, 35.12, 36.47, 35.12, 36.33 }, + { 284, 36.12, 37.65, 35.83, 37.16 }, + { 285, 37.40, 40.35, 37.18, 39.00 }, + { 286, 39.30, 40.75, 39.03, 40.34 }, + { 287, 40.80, 42.35, 40.30, 41.53 }, + { 290, 42.00, 42.80, 41.35, 42.70 }, + { 291, 42.70, 43.16, 38.75, 38.97 }, + { 292, 38.60, 40.00, 37.70, 39.79 }, + { 293, 39.61, 39.79, 38.00, 38.40 }, + { 294, 38.29, 38.29, 37.25, 37.60 }, + { 297, 37.73, 38.39, 37.49, 38.06 }, + { 298, 38.02, 38.19, 37.60, 37.99 }, + { 299, 37.90, 38.36, 37.31, 37.49 }, + { 300, 37.40, 37.81, 37.05, 37.19 }, + { 301, 37.00, 37.29, 35.92, 36.81 }, + { 304, 37.00, 37.21, 36.69, 36.90 }, + { 305, 37.00, 37.19, 36.83, 37.01 }, + { 306, 37.97, 38.08, 37.38, 37.65 }, + { 307, 38.39, 38.96, 38.01, 38.71 }, + { 308, 38.70, 40.38, 38.60, 40.02 }, + { 311, 40.02, 40.77, 40.01, 40.60 }, + { 312, 40.40, 43.71, 40.40, 43.54 }, + { 313, 43.00, 44.04, 41.28, 43.33 }, + { 314, 43.00, 44.54, 43.00, 43.94 }, + { 315, 43.30, 44.55, 42.54, 44.55 }, + { 318, 44.10, 47.18, 44.05, 46.60 }, + { 319, 46.45, 47.84, 45.97, 46.55 }, + { 320, 46.40, 47.57, 46.22, 47.38 }, + { 321, 47.85, 49.12, 47.62, 48.97 }, + { 322, 49.30, 50.00, 47.94, 50.00 }, + { 325, 50.20, 53.75, 50.10, 52.43 }, + { 326, 51.90, 54.94, 50.21, 53.07 }, + { 327, 53.20, 56.41, 53.20, 56.41 }, + { 328, 56.98, 59.63, 56.76, 59.27 }, + { 329, 59.00, 60.20, 53.65, 57.70 }, + { 332, 58.30, 59.40, 55.65, 55.88 }, + { 333, 55.85, 58.80, 54.50, 57.93 }, + { 334, 59.37, 61.72, 58.86, 61.43 }, + { 335, 62.93, 65.00, 62.20, 64.54 }, + { 336, 65.50, 66.50, 63.82, 64.80 }, + { 339, 66.00, 66.50, 65.05, 65.70 }, + { 340, 67.60, 69.88, 67.29, 68.57 }, + { 341, 67.90, 67.99, 63.65, 64.69 }, + { 342, 65.90, 66.18, 61.14, 62.02 }, + { 343, 61.42, 66.11, 61.29, 66.00 }, + { 346, 65.63, 67.60, 65.20, 67.19 }, + { 347, 66.99, 67.08, 65.07, 65.19 }, + { 348, 64.90, 65.66, 63.35, 65.50 }, + { 349, 65.07, 66.10, 63.21, 63.48 }, + { 350, 64.28, 64.72, 61.50, 62.06 }, + { 353, 62.00, 63.54, 61.88, 62.25 }, + { 354, 63.00, 63.80, 62.53, 63.75 }, + { 355, 63.79, 64.94, 63.00, 63.56 }, + { 356, 63.62, 64.25, 62.34, 62.48 }, + { 360, 62.21, 62.40, 57.51, 59.40 }, + { 361, 60.00, 60.81, 59.41, 60.07 }, + { 362, 60.10, 60.65, 60.00, 60.30 }, + { 363, 60.30, 60.51, 59.40, 59.66 } +}; + +static t_Data2010 daimlerData[] = +{ + { 3, 37.24, 37.60, 36.96, 37.55 }, + { 4, 37.50, 37.56, 36.87, 37.24 }, + { 5, 37.19, 37.33, 36.62, 37.25 }, + { 6, 36.85, 36.95, 36.35, 36.72 }, + { 7, 36.92, 37.15, 36.24, 36.94 }, + { 10, 37.19, 37.67, 37.04, 37.20 }, + { 11, 37.34, 37.40, 36.16, 36.28 }, + { 12, 36.00, 36.38, 35.60, 36.19 }, + { 13, 36.60, 37.19, 36.47, 37.10 }, + { 14, 37.00, 37.26, 36.31, 36.49 }, + { 17, 36.58, 37.25, 36.25, 37.12 }, + { 18, 36.65, 36.87, 35.73, 36.71 }, + { 19, 36.44, 36.52, 35.33, 35.60 }, + { 20, 35.90, 36.17, 34.69, 34.76 }, + { 21, 34.40, 34.66, 33.28, 34.18 }, + { 24, 33.56, 34.08, 33.22, 33.50 }, + { 25, 33.15, 33.95, 32.70, 33.86 }, + { 26, 33.46, 33.58, 32.60, 32.92 }, + { 27, 33.53, 33.80, 32.32, 32.32 }, + { 28, 32.85, 33.97, 32.69, 33.42 }, + { 31, 33.00, 33.74, 32.96, 33.57 }, + { 32, 33.51, 33.88, 32.92, 33.76 }, + { 33, 33.96, 34.95, 33.90, 34.34 }, + { 34, 34.49, 34.69, 33.01, 33.10 }, + { 35, 33.31, 33.31, 32.01, 32.32 }, + { 38, 32.79, 33.54, 32.60, 33.31 }, + { 39, 33.57, 33.85, 32.98, 33.33 }, + { 40, 33.42, 34.10, 33.34, 33.63 }, + { 41, 33.86, 33.90, 32.26, 32.77 }, + { 42, 32.93, 33.21, 31.74, 32.46 }, + { 45, 32.55, 33.11, 31.88, 32.01 }, + { 46, 32.25, 32.69, 31.82, 32.62 }, + { 47, 33.10, 33.47, 32.90, 33.04 }, + { 48, 33.04, 33.35, 29.92, 31.50 }, + { 49, 31.20, 32.32, 30.90, 32.30 }, + { 52, 32.60, 32.62, 31.36, 31.40 }, + { 53, 31.68, 31.90, 31.00, 31.25 }, + { 54, 31.45, 31.49, 30.43, 30.94 }, + { 55, 30.75, 31.23, 30.10, 30.35 }, + { 56, 30.56, 31.09, 30.26, 30.66 }, + { 59, 31.15, 31.55, 30.74, 31.34 }, + { 60, 31.40, 32.06, 31.24, 31.75 }, + { 61, 31.49, 32.25, 31.42, 31.95 }, + { 62, 31.75, 32.29, 31.57, 31.91 }, + { 63, 32.01, 33.10, 32.01, 32.99 }, + { 66, 32.97, 33.20, 32.73, 33.01 }, + { 67, 32.90, 32.99, 32.25, 32.76 }, + { 68, 32.83, 33.26, 32.58, 33.12 }, + { 69, 32.88, 33.56, 32.88, 33.19 }, + { 70, 33.20, 33.60, 33.03, 33.53 }, + { 73, 33.65, 33.83, 33.31, 33.33 }, + { 74, 33.60, 34.26, 33.51, 34.11 }, + { 75, 34.49, 34.60, 33.93, 34.35 }, + { 76, 34.35, 34.78, 34.17, 34.64 }, + { 77, 34.60, 34.89, 34.26, 34.38 }, + { 80, 34.19, 34.56, 33.92, 34.40 }, + { 81, 34.49, 34.74, 34.10, 34.45 }, + { 82, 34.55, 34.65, 33.78, 34.49 }, + { 83, 34.63, 35.19, 34.50, 35.01 }, + { 84, 34.85, 35.34, 34.78, 34.98 }, + { 87, 35.27, 35.53, 34.85, 34.95 }, + { 88, 35.28, 35.35, 34.34, 34.56 }, + { 89, 34.73, 34.99, 34.43, 34.85 }, + { 90, 35.08, 35.49, 35.06, 35.40 }, + { 95, 35.52, 35.84, 35.26, 35.51 }, + { 96, 35.60, 35.85, 35.28, 35.42 }, + { 97, 35.29, 35.36, 34.79, 35.18 }, + { 98, 35.50, 35.69, 35.10, 35.36 }, + { 101, 35.68, 35.74, 35.10, 35.41 }, + { 102, 35.43, 36.05, 34.98, 36.00 }, + { 103, 36.25, 36.74, 36.00, 36.67 }, + { 104, 36.80, 36.90, 36.19, 36.72 }, + { 105, 36.74, 37.38, 36.30, 36.54 }, + { 108, 36.49, 36.76, 36.12, 36.31 }, + { 109, 38.80, 39.24, 38.48, 39.00 }, + { 110, 39.06, 39.30, 38.38, 38.45 }, + { 111, 38.46, 38.96, 37.72, 37.85 }, + { 112, 38.21, 39.11, 37.81, 38.87 }, + { 115, 39.26, 39.52, 38.75, 39.47 }, + { 116, 39.26, 39.90, 37.93, 37.93 }, + { 117, 37.92, 38.18, 36.82, 37.76 }, + { 118, 37.85, 39.00, 37.68, 38.79 }, + { 119, 38.80, 39.30, 38.37, 38.81 }, + { 122, 38.31, 38.83, 38.08, 38.62 }, + { 123, 38.87, 38.88, 37.00, 37.37 }, + { 124, 37.72, 37.72, 36.60, 37.02 }, + { 125, 36.84, 37.74, 36.63, 36.93 }, + { 126, 36.25, 36.96, 35.30, 35.85 }, + { 129, 36.75, 38.01, 36.63, 38.01 }, + { 130, 37.33, 38.74, 37.17, 38.65 }, + { 131, 38.35, 40.17, 38.07, 39.79 }, + { 132, 40.20, 41.54, 40.02, 41.37 }, + { 133, 41.00, 41.38, 40.15, 40.58 }, + { 136, 40.21, 41.54, 40.01, 41.08 }, + { 137, 41.32, 41.92, 40.88, 41.92 }, + { 138, 41.40, 41.85, 39.85, 40.20 }, + { 139, 40.60, 40.64, 37.37, 38.40 }, + { 140, 38.15, 38.95, 37.11, 38.83 }, + { 143, 39.00, 39.13, 37.38, 38.49 }, + { 144, 37.26, 37.56, 36.67, 37.19 }, + { 145, 37.50, 38.87, 37.50, 38.24 }, + { 146, 38.60, 40.18, 38.60, 39.94 }, + { 147, 40.55, 40.67, 39.95, 40.30 }, + { 150, 40.35, 41.08, 40.31, 41.00 }, + { 151, 40.75, 41.43, 40.02, 40.99 }, + { 152, 40.50, 40.99, 39.97, 40.78 }, + { 153, 41.75, 41.99, 41.12, 41.26 }, + { 154, 41.55, 41.66, 39.87, 40.38 }, + { 157, 39.65, 40.61, 39.54, 40.08 }, + { 158, 40.15, 40.41, 39.47, 40.24 }, + { 159, 40.60, 42.05, 40.38, 41.94 }, + { 160, 41.72, 43.74, 41.64, 43.26 }, + { 161, 43.44, 43.88, 42.14, 42.74 }, + { 164, 43.20, 43.36, 42.38, 42.52 }, + { 165, 42.00, 42.79, 41.72, 42.33 }, + { 166, 42.46, 42.60, 40.78, 41.14 }, + { 167, 41.00, 42.44, 40.94, 42.31 }, + { 168, 42.47, 43.39, 42.35, 43.12 }, + { 171, 44.07, 44.79, 44.03, 44.50 }, + { 172, 44.15, 44.49, 43.74, 44.47 }, + { 173, 43.92, 44.65, 43.78, 43.95 }, + { 174, 44.49, 44.69, 43.25, 43.42 }, + { 175, 42.98, 42.98, 41.74, 42.01 }, + { 178, 42.14, 43.36, 41.86, 43.24 }, + { 179, 42.50, 42.72, 41.07, 41.28 }, + { 180, 41.62, 42.49, 41.32, 41.92 }, + { 181, 41.47, 41.82, 40.17, 40.42 }, + { 182, 40.90, 41.49, 40.17, 40.28 }, + { 185, 40.56, 40.85, 39.95, 39.95 }, + { 186, 40.15, 41.95, 40.15, 41.21 }, + { 187, 41.00, 41.99, 40.56, 41.94 }, + { 188, 42.01, 42.33, 41.15, 41.58 }, + { 189, 41.80, 41.97, 41.39, 41.63 }, + { 192, 41.80, 41.95, 41.38, 41.56 }, + { 193, 41.40, 43.81, 41.40, 43.81 }, + { 194, 44.03, 44.48, 43.06, 43.54 }, + { 195, 43.47, 44.35, 42.82, 43.28 }, + { 196, 43.39, 44.70, 42.94, 43.05 }, + { 199, 43.04, 43.22, 42.20, 42.63 }, + { 200, 42.65, 42.88, 41.30, 41.42 }, + { 201, 41.63, 42.05, 40.72, 40.96 }, + { 202, 40.79, 42.51, 40.76, 42.26 }, + { 203, 42.03, 42.83, 41.74, 42.49 }, + { 206, 42.74, 43.17, 42.36, 43.15 }, + { 207, 43.18, 43.38, 40.81, 41.34 }, + { 208, 41.90, 41.97, 41.27, 41.47 }, + { 209, 41.60, 42.11, 41.13, 41.44 }, + { 210, 41.31, 41.67, 40.79, 41.38 }, + { 213, 41.14, 41.58, 40.64, 41.40 }, + { 214, 41.33, 42.10, 41.33, 42.00 }, + { 215, 41.90, 42.10, 41.48, 41.68 }, + { 216, 41.63, 42.44, 41.56, 42.12 }, + { 217, 42.43, 42.75, 40.84, 40.97 }, + { 220, 41.53, 41.99, 41.10, 41.97 }, + { 221, 41.79, 41.79, 40.84, 41.22 }, + { 222, 40.85, 40.97, 39.92, 40.19 }, + { 223, 40.01, 40.40, 38.53, 39.07 }, + { 224, 39.48, 39.90, 38.89, 39.15 }, + { 227, 39.41, 40.14, 39.23, 39.96 }, + { 228, 40.26, 41.10, 40.13, 41.05 }, + { 229, 40.87, 41.10, 40.50, 40.62 }, + { 230, 40.97, 41.22, 39.65, 39.88 }, + { 231, 39.71, 39.95, 39.10, 39.23 }, + { 234, 39.18, 39.53, 38.90, 39.15 }, + { 235, 38.94, 39.05, 38.17, 38.66 }, + { 236, 38.46, 38.82, 37.64, 38.29 }, + { 237, 38.50, 38.63, 37.85, 38.08 }, + { 238, 37.99, 38.40, 37.60, 38.40 }, + { 241, 38.55, 38.83, 37.77, 38.12 }, + { 242, 37.50, 38.36, 37.03, 38.36 }, + { 243, 38.50, 40.49, 38.30, 40.46 }, + { 244, 40.29, 41.42, 40.22, 41.00 }, + { 245, 41.06, 42.24, 40.94, 41.65 }, + { 248, 41.72, 41.86, 41.08, 41.25 }, + { 249, 40.99, 41.36, 40.65, 41.35 }, + { 250, 41.25, 42.06, 41.12, 42.00 }, + { 251, 41.99, 43.15, 41.79, 43.08 }, + { 252, 43.00, 44.02, 42.86, 43.78 }, + { 255, 44.31, 44.65, 43.66, 43.67 }, + { 256, 43.57, 44.20, 43.54, 44.15 }, + { 257, 44.09, 44.49, 43.94, 44.12 }, + { 258, 43.70, 44.22, 43.62, 44.06 }, + { 259, 44.30, 44.74, 43.62, 44.47 }, + { 262, 44.47, 45.50, 44.35, 45.50 }, + { 263, 45.38, 45.90, 45.26, 45.63 }, + { 264, 45.01, 45.19, 44.23, 44.85 }, + { 265, 44.83, 45.13, 43.78, 44.35 }, + { 266, 44.08, 46.17, 44.00, 46.13 }, + { 269, 46.12, 46.69, 45.85, 46.41 }, + { 270, 46.25, 46.64, 45.55, 46.23 }, + { 271, 46.38, 46.85, 46.01, 46.28 }, + { 272, 45.98, 47.59, 45.88, 46.46 }, + { 273, 46.32, 46.86, 45.11, 45.51 }, + { 276, 45.19, 45.19, 43.66, 43.78 }, + { 277, 43.74, 44.88, 43.59, 44.69 }, + { 278, 45.05, 45.19, 44.03, 44.24 }, + { 279, 44.50, 45.49, 44.19, 45.37 }, + { 280, 45.20, 45.61, 44.62, 45.44 }, + { 283, 45.65, 46.30, 45.45, 45.92 }, + { 284, 46.02, 47.73, 45.66, 47.42 }, + { 285, 47.80, 48.21, 47.22, 47.94 }, + { 286, 48.00, 48.04, 47.17, 47.40 }, + { 287, 47.50, 48.13, 47.18, 47.72 }, + { 290, 47.64, 48.10, 47.24, 47.78 }, + { 291, 47.50, 47.80, 46.86, 47.04 }, + { 292, 46.80, 47.90, 46.75, 47.80 }, + { 293, 47.66, 49.12, 47.65, 49.03 }, + { 294, 48.97, 49.51, 48.63, 49.31 }, + { 297, 49.70, 50.05, 49.37, 49.70 }, + { 298, 49.22, 49.56, 48.30, 48.74 }, + { 299, 48.40, 49.10, 47.53, 47.62 }, + { 300, 48.10, 49.05, 46.74, 46.98 }, + { 301, 46.76, 47.73, 46.35, 47.43 }, + { 304, 48.10, 48.37, 47.33, 47.65 }, + { 305, 47.42, 48.62, 47.22, 48.41 }, + { 306, 48.50, 49.15, 48.10, 48.34 }, + { 307, 49.10, 50.14, 48.80, 50.00 }, + { 308, 50.08, 50.45, 48.85, 48.94 }, + { 311, 49.08, 49.10, 48.52, 48.94 }, + { 312, 48.72, 50.28, 48.65, 50.04 }, + { 313, 49.76, 49.91, 48.70, 49.17 }, + { 314, 49.56, 49.75, 48.98, 49.56 }, + { 315, 48.60, 50.23, 47.92, 49.88 }, + { 318, 49.26, 51.40, 49.26, 50.89 }, + { 319, 50.50, 50.93, 49.47, 49.47 }, + { 320, 49.46, 49.69, 48.98, 49.27 }, + { 321, 50.04, 50.96, 49.80, 50.81 }, + { 322, 50.88, 51.00, 50.18, 50.74 }, + { 325, 50.99, 51.59, 50.31, 50.56 }, + { 326, 50.16, 51.26, 49.51, 49.51 }, + { 327, 50.12, 52.04, 49.73, 52.04 }, + { 328, 52.00, 52.63, 51.52, 51.93 }, + { 329, 51.47, 51.93, 50.65, 51.54 }, + { 332, 51.93, 52.06, 49.79, 49.79 }, + { 333, 50.00, 50.93, 49.01, 49.87 }, + { 334, 50.51, 51.96, 50.09, 51.94 }, + { 335, 52.30, 53.64, 51.88, 53.49 }, + { 336, 53.00, 54.78, 52.68, 53.95 }, + { 339, 53.95, 54.18, 53.40, 53.62 }, + { 340, 53.68, 54.37, 52.61, 54.15 }, + { 341, 53.84, 54.05, 52.97, 53.26 }, + { 342, 53.85, 54.14, 52.15, 53.30 }, + { 343, 53.54, 54.93, 53.35, 54.87 }, + { 346, 55.00, 55.00, 54.42, 54.76 }, + { 347, 54.50, 54.87, 53.72, 54.11 }, + { 348, 53.81, 54.20, 53.17, 53.90 }, + { 349, 53.71, 54.58, 53.71, 54.41 }, + { 350, 54.07, 54.48, 53.57, 53.68 }, + { 353, 53.88, 54.50, 53.78, 53.88 }, + { 354, 54.02, 54.94, 53.95, 54.66 }, + { 355, 54.70, 55.05, 54.33, 54.33 }, + { 356, 54.30, 54.52, 54.04, 54.07 }, + { 360, 53.30, 53.45, 51.29, 51.57 }, + { 361, 51.67, 51.84, 51.02, 51.50 }, + { 362, 51.50, 51.62, 51.23, 51.32 }, + { 363, 51.50, 51.70, 50.61, 50.73 } +}; + +QVector QuoteFactory::samples2010( Stock stock ) +{ + const t_Data2010 *data = NULL; + int numSamples = 0; + + switch( stock ) + { + case BMW: + { + data = bmwData; + numSamples = sizeof( bmwData ) / sizeof( t_Data2010 ); + break; + } + case Daimler: + { + data = daimlerData; + numSamples = sizeof( daimlerData ) / sizeof( t_Data2010 ); + break; + } + case Porsche: + { + data = porscheData; + numSamples = sizeof( porscheData ) / sizeof( t_Data2010 ); + break; + } + default: + break; + } + + QVector samples; + samples.reserve( numSamples ); + + QDateTime year2010( QDate( 2010, 1, 1 ), QTime( 0, 0 ), Qt::UTC ); + + for ( int i = 0; i < numSamples; i++ ) + { + const t_Data2010 &ohlc = data[ i ]; + + samples += QwtOHLCSample( + QwtDate::toDouble( year2010.addDays( ohlc.day ) ), + ohlc.open, ohlc.high, ohlc.low, ohlc.close ); + } + + return samples; +} + +QString QuoteFactory::title( Stock stock ) +{ + switch( stock ) + { + case BMW: + return "BMW"; + case Daimler: + return "Daimler"; + case Porsche: + return "Porsche"; + default: + break; + } + + return "Unknown"; +} diff --git a/ThirdParty/Qwt/examples/stockchart/quotefactory.h b/ThirdParty/Qwt/examples/stockchart/quotefactory.h new file mode 100644 index 0000000000..ddaac2682f --- /dev/null +++ b/ThirdParty/Qwt/examples/stockchart/quotefactory.h @@ -0,0 +1,22 @@ +#ifndef _QUOTE_FACTORY_H_ +#define _QUOTE_FACTORY_H_ + +#include + +class QuoteFactory +{ +public: + enum Stock + { + BMW, + Daimler, + Porsche, + + NumStocks + }; + + static QVector samples2010( Stock ); + static QString title( Stock ); +}; + +#endif diff --git a/ThirdParty/Qwt/examples/stockchart/stockchart.pro b/ThirdParty/Qwt/examples/stockchart/stockchart.pro new file mode 100644 index 0000000000..36719d7278 --- /dev/null +++ b/ThirdParty/Qwt/examples/stockchart/stockchart.pro @@ -0,0 +1,25 @@ +################################################################ +# Qwt Widget Library +# Copyright (C) 1997 Josef Wilgen +# Copyright (C) 2002 Uwe Rathmann +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the Qwt License, Version 1.0 +################################################################ + +include( $${PWD}/../examples.pri ) + +TARGET = stockchart + +HEADERS = \ + legend.h \ + griditem.h \ + plot.h \ + quotefactory.h + +SOURCES = \ + legend.cpp \ + griditem.cpp \ + quotefactory.cpp \ + plot.cpp \ + main.cpp diff --git a/ThirdParty/Qwt/examples/stylesheets/blue.css b/ThirdParty/Qwt/examples/stylesheets/blue.css new file mode 100644 index 0000000000..6a7c773671 --- /dev/null +++ b/ThirdParty/Qwt/examples/stylesheets/blue.css @@ -0,0 +1,66 @@ +QwtPlot +{ + border: 1px solid white; + border-radius: 10px; + padding: 10px; + background-color: qlineargradient( x1: 0, y1: 0, x2: 0, y2: 1, + stop: 0 #657383, stop: 0.4 #8395AA, stop: 1 #657383 ); + background-color: qlineargradient( x1: 0, y1: 0, x2: 0, y2: 1, + stop: 0 #657383, stop: 1 #8395AA ); + background-color: qlineargradient( x1: 0, y1: 0, x2: 1, y2: 1, + stop: 0 #8395AA, stop: 1 #657383 ); + background-color: qlineargradient( x1: 0, y1: 0, x2: 1, y2: 1, + stop: 0 #8395AA, stop: 0.4 #657383 stop: 1 #8395AA ); + background-color: qlineargradient( x1: 0, y1: 0, x2: 1, y2: 1, + stop: 0 #7C8DA0, stop: 0.4 #657383 stop: 1 #7C8DA0 ); + background-color: qlineargradient( x1: 0, y1: 0, x2: 1, y2: 1, + stop: 0 #657383, stop: 0.25 #7C8DA0 stop: 0.55 #7C8DA0 stop: 1 #657383 ); + background-color: qlineargradient( x1: 0, y1: 0, x2: 1, y2: 1, + stop: 0 #8FA3B9, stop: 0.25 #7C8DA0 stop: 0.55 #7C8DA0 stop: 1 #8FA3B9 ); + background-color: qlineargradient( x1: 0, y1: 0, x2: 1, y2: 1, + stop: 0 #7C8DA0, stop: 0.4 #8FA3B9 stop: 0.55 #8FA3B9 stop: 1 #7C8DA0 ); + background-color: qlineargradient( x1: 0, y1: 0, x2: 1, y2: 1, + stop: 0 #7C8DA0, stop: 0.4 #8395AA stop: 0.55 #8395AA stop: 1 #7C8DA0 ); +} + +QwtPlotCanvas +{ + border: 1px solid white; + border-radius: 10px; + background-color: #616d7e; +} + +QwtPlotGLCanvas +{ + border: 1px solid white; + background-color: #616d7e; +} + +QwtScaleWidget +{ + color: white; +} + +QwtTextLabel#QwtPlotTitle +{ + color: white; +} + +QwtTextLabel#QwtPlotFooter +{ + color: white; +} + +QwtLegend +{ + border: 1px solid white; + border-radius: 10px; + padding: 2px; + background: #616d7e; +} + +QwtLegendLabel +{ + color: white; +} + diff --git a/ThirdParty/Qwt/examples/stylesheets/choco.css b/ThirdParty/Qwt/examples/stylesheets/choco.css new file mode 100644 index 0000000000..e819fecc90 --- /dev/null +++ b/ThirdParty/Qwt/examples/stylesheets/choco.css @@ -0,0 +1,50 @@ +QwtPlot +{ + border: 1px solid white; + border-radius: 10px; + padding: 10px; + background-color: qlineargradient( x1: 0, y1: 0, x2: 0, y2: 1, + stop: 0 Brown, stop: 0.5 Chocolate, stop: 1 Brown ); +} + +QwtPlotCanvas +{ + border: 1px solid White; + border-radius: 10px; + background-color: Tan; +} + +QwtPlotGLCanvas +{ + border: 1px solid White; + background-color: Tan; +} + +QwtScaleWidget +{ + color: white; +} + +QwtTextLabel#QwtPlotTitle +{ + color: white; +} + +QwtTextLabel#QwtPlotFooter +{ + color: white; +} + +QwtLegend +{ + border: 1px solid white; + border-radius: 10px; + padding: 2px; + background: brown; +} + +QwtLegendLabel +{ + color: white; +} + diff --git a/ThirdParty/Qwt/examples/stylesheets/oily.css b/ThirdParty/Qwt/examples/stylesheets/oily.css new file mode 100644 index 0000000000..5c561e82c0 --- /dev/null +++ b/ThirdParty/Qwt/examples/stylesheets/oily.css @@ -0,0 +1,51 @@ +QwtPlot +{ + border: 1px solid white; + border-radius: 10px; + padding: 10px; + background-color: qlineargradient( x1: 0, y1: 0, x2: 1, y2: 1, + stop: 0 #31312C, stop: 1 #808080 ); +} + +QwtPlotCanvas +{ + border: 1px solid White; + border-radius: 10px; + background-color: #101010; +} + +QwtPlotGLCanvas +{ + border: 1px solid White; + background-color: #101010; +} + +QwtScaleWidget +{ + color: white; +} + +QwtTextLabel#QwtPlotTitle +{ + color: white; +} + +QwtTextLabel#QwtPlotFooter +{ + color: white; +} + +QwtLegend +{ + border: 1px solid white; + border-radius: 10px; + padding: 2px; + background-color: qlineargradient( x1: 0, y1: 0, x2: 1, y2: 1, + stop: 0 #808080, stop: 1 #31312C ); +} + +QwtLegendLabel +{ + color: white; +} + diff --git a/ThirdParty/Qwt/examples/stylesheets/rosy.css b/ThirdParty/Qwt/examples/stylesheets/rosy.css new file mode 100644 index 0000000000..0bb9f05263 --- /dev/null +++ b/ThirdParty/Qwt/examples/stylesheets/rosy.css @@ -0,0 +1,50 @@ +QwtPlot +{ + border: 1px solid white; + border-radius: 10px; + padding: 10px; + background-color: qlineargradient( x1: 0, y1: 0, x2: 0, y2: 1, + stop: 0 #7e354d, stop: 0.5 #7f5a58, stop: 1 #7e354d ); +} + +QwtPlotCanvas +{ + border: 1px solid White; + border-radius: 10px; + background-color: #7f5a58; +} + +QwtPlotGLCanvas +{ + border: 1px solid White; + background-color: #7f5a58; +} + +QwtScaleWidget +{ + color: white; +} + +QwtTextLabel#QwtPlotTitle +{ + color: white; +} + +QwtTextLabel#QwtPlotFooter +{ + color: white; +} + +QwtLegend +{ + border: 1px solid white; + border-radius: 10px; + padding: 2px; + background: #7f5a58; +} + +QwtLegendLabel +{ + color: white; +} + diff --git a/ThirdParty/Qwt/examples/sysinfo/sysinfo.cpp b/ThirdParty/Qwt/examples/sysinfo/sysinfo.cpp new file mode 100644 index 0000000000..640202b8b1 --- /dev/null +++ b/ThirdParty/Qwt/examples/sysinfo/sysinfo.cpp @@ -0,0 +1,123 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +class ValueBar: public QWidget +{ +public: + ValueBar( Qt::Orientation orientation, + const QString &text, QWidget *parent, double value = 0.0 ): + QWidget( parent ) + { + d_label = new QLabel( text, this ); + d_label->setFont( QFont( "Helvetica", 10 ) ); + + d_thermo = new QwtThermo( this ); + d_thermo->setOrientation( orientation ); + d_thermo->setScale( 0.0, 100.0 ); + d_thermo->setValue( value ); + d_thermo->setFont( QFont( "Helvetica", 8 ) ); + d_thermo->setPipeWidth( 6 ); + d_thermo->setScaleMaxMajor( 6 ); + d_thermo->setScaleMaxMinor( 5 ); + d_thermo->setFillBrush( Qt::darkMagenta ); + +#if 0 + QwtLinearColorMap *colorMap = + new QwtLinearColorMap( Qt::blue, Qt::red ); + + colorMap->addColorStop( 0.2, Qt::yellow ); + colorMap->addColorStop( 0.3, Qt::cyan ); + colorMap->addColorStop( 0.4, Qt::green ); + colorMap->addColorStop( 0.5, Qt::magenta ); + colorMap->setMode( QwtLinearColorMap::FixedColors ); + d_thermo->setColorMap( colorMap ); +#endif + + QVBoxLayout *layout = new QVBoxLayout( this ); + layout->setMargin( 0 ); + layout->setSpacing( 0 ); + + if ( orientation == Qt::Horizontal ) + { + d_label->setAlignment( Qt::AlignCenter ); + d_thermo->setScalePosition( QwtThermo::LeadingScale ); + layout->addWidget( d_label ); + layout->addWidget( d_thermo ); + } + else + { + d_label->setAlignment( Qt::AlignRight ); + d_thermo->setScalePosition( QwtThermo::TrailingScale ); + layout->addWidget( d_thermo, 10, Qt::AlignHCenter ); + layout->addWidget( d_label, 0 ); + } + } + + void setValue( double value ) + { + d_thermo->setValue( value ); + } + +private: + QLabel *d_label; + QwtThermo *d_thermo; +}; + +class SysInfo : public QFrame +{ +public: + SysInfo( QWidget *parent = NULL ): + QFrame( parent ) + { + QGroupBox *memBox = new QGroupBox( "Memory Usage", this ); + memBox->setFont( QFont( "Helvetica", 10 ) ); + + QVBoxLayout *memLayout = new QVBoxLayout( memBox ); + memLayout->setMargin( 15 ); + memLayout->setSpacing( 5 ); + + Qt::Orientation o = Qt::Horizontal; + memLayout->addWidget( new ValueBar( o, "Used", memBox, 57 ) ); + memLayout->addWidget( new ValueBar( o, "Shared", memBox, 17 ) ); + memLayout->addWidget( new ValueBar( o, "Cache", memBox, 30 ) ); + memLayout->addWidget( new ValueBar( o, "Buffers", memBox, 22 ) ); + memLayout->addWidget( new ValueBar( o, "Swap Used", memBox, 57 ) ); + memLayout->addWidget( new QWidget( memBox ), 10 ); // spacer + + QGroupBox *cpuBox = new QGroupBox( "Cpu Usage", this ); + cpuBox->setFont( QFont( "Helvetica", 10 ) ); + + QHBoxLayout *cpuLayout = new QHBoxLayout( cpuBox ); + cpuLayout->setMargin( 15 ); + cpuLayout->setSpacing( 5 ); + + o = Qt::Vertical; + cpuLayout->addWidget( new ValueBar( o, "User", cpuBox, 57 ) ); + cpuLayout->addWidget( new ValueBar( o, "Total", cpuBox, 73 ) ); + cpuLayout->addWidget( new ValueBar( o, "System", cpuBox, 16 ) ); + cpuLayout->addWidget( new ValueBar( o, "Idle", cpuBox, 27 ) ); + + QHBoxLayout *layout = new QHBoxLayout( this ); + layout->setMargin( 10 ); + layout->addWidget( memBox, 10 ); + layout->addWidget( cpuBox, 0 ); + } +}; + +int main ( int argc, char **argv ) +{ + QApplication a( argc, argv ); + + SysInfo info; + info.resize( info.sizeHint().expandedTo( QSize( 600, 400 ) ) ); + info.show(); + + int rv = a.exec(); + return rv; +} diff --git a/ThirdParty/Qwt/examples/sysinfo/sysinfo.pro b/ThirdParty/Qwt/examples/sysinfo/sysinfo.pro new file mode 100644 index 0000000000..f93624b12d --- /dev/null +++ b/ThirdParty/Qwt/examples/sysinfo/sysinfo.pro @@ -0,0 +1,15 @@ +################################################################ +# Qwt Widget Library +# Copyright (C) 1997 Josef Wilgen +# Copyright (C) 2002 Uwe Rathmann +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the Qwt License, Version 1.0 +################################################################ + +include( $${PWD}/../examples.pri ) + +TARGET = sysinfo + +SOURCES = \ + sysinfo.cpp diff --git a/ThirdParty/Qwt/examples/tvplot/main.cpp b/ThirdParty/Qwt/examples/tvplot/main.cpp new file mode 100644 index 0000000000..2ce089613f --- /dev/null +++ b/ThirdParty/Qwt/examples/tvplot/main.cpp @@ -0,0 +1,57 @@ +#include +#include +#include +#include +#include +#include "tvplot.h" + +class MainWindow: public QMainWindow +{ +public: + MainWindow( QWidget * = NULL ); + +private: + TVPlot *d_plot; +}; + +MainWindow::MainWindow( QWidget *parent ): + QMainWindow( parent ) +{ + d_plot = new TVPlot( this ); + setCentralWidget( d_plot ); + + QToolBar *toolBar = new QToolBar( this ); + + QComboBox *typeBox = new QComboBox( toolBar ); + typeBox->addItem( "Outline" ); + typeBox->addItem( "Columns" ); + typeBox->addItem( "Lines" ); + typeBox->addItem( "Column Symbol" ); + typeBox->setCurrentIndex( typeBox->count() - 1 ); + typeBox->setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ); + + QToolButton *btnExport = new QToolButton( toolBar ); + btnExport->setText( "Export" ); + btnExport->setToolButtonStyle( Qt::ToolButtonTextUnderIcon ); + connect( btnExport, SIGNAL( clicked() ), d_plot, SLOT( exportPlot() ) ); + + toolBar->addWidget( typeBox ); + toolBar->addWidget( btnExport ); + addToolBar( toolBar ); + + d_plot->setMode( typeBox->currentIndex() ); + connect( typeBox, SIGNAL( currentIndexChanged( int ) ), + d_plot, SLOT( setMode( int ) ) ); +} + +int main( int argc, char **argv ) +{ + QApplication a( argc, argv ); + + MainWindow mainWindow; + + mainWindow.resize( 600, 400 ); + mainWindow.show(); + + return a.exec(); +} diff --git a/ThirdParty/Qwt/examples/tvplot/tvplot.cpp b/ThirdParty/Qwt/examples/tvplot/tvplot.cpp new file mode 100644 index 0000000000..4c0080b3b6 --- /dev/null +++ b/ThirdParty/Qwt/examples/tvplot/tvplot.cpp @@ -0,0 +1,169 @@ +#include "tvplot.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class Histogram: public QwtPlotHistogram +{ +public: + Histogram( const QString &, const QColor & ); + + void setColor( const QColor & ); + void setValues( uint numValues, const double * ); +}; + +Histogram::Histogram( const QString &title, const QColor &symbolColor ): + QwtPlotHistogram( title ) +{ + setStyle( QwtPlotHistogram::Columns ); + + setColor( symbolColor ); +} + +void Histogram::setColor( const QColor &color ) +{ + QColor c = color; + c.setAlpha( 180 ); + setBrush( QBrush( c ) ); +} + +void Histogram::setValues( uint numValues, const double *values ) +{ + QVector samples( numValues ); + for ( uint i = 0; i < numValues; i++ ) + { + QwtInterval interval( double( i ), i + 1.0 ); + interval.setBorderFlags( QwtInterval::ExcludeMaximum ); + + samples[i] = QwtIntervalSample( values[i], interval ); + } + + setData( new QwtIntervalSeriesData( samples ) ); +} + +TVPlot::TVPlot( QWidget *parent ): + QwtPlot( parent ) +{ + setTitle( "Watching TV during a weekend" ); + + QwtPlotCanvas *canvas = new QwtPlotCanvas(); + canvas->setPalette( Qt::gray ); + canvas->setBorderRadius( 10 ); + setCanvas( canvas ); + + plotLayout()->setAlignCanvasToScales( true ); + + setAxisTitle( QwtPlot::yLeft, "Number of People" ); + setAxisTitle( QwtPlot::xBottom, "Number of Hours" ); + + QwtLegend *legend = new QwtLegend; + legend->setDefaultItemMode( QwtLegendData::Checkable ); + insertLegend( legend, QwtPlot::RightLegend ); + + populate(); + + connect( legend, SIGNAL( checked( const QVariant &, bool, int ) ), + SLOT( showItem( const QVariant &, bool ) ) ); + + replot(); // creating the legend items + + QwtPlotItemList items = itemList( QwtPlotItem::Rtti_PlotHistogram ); + for ( int i = 0; i < items.size(); i++ ) + { + if ( i == 0 ) + { + const QVariant itemInfo = itemToInfo( items[i] ); + + QwtLegendLabel *legendLabel = + qobject_cast( legend->legendWidget( itemInfo ) ); + if ( legendLabel ) + legendLabel->setChecked( true ); + + items[i]->setVisible( true ); + } + else + { + items[i]->setVisible( false ); + } + } + + setAutoReplot( true ); +} + +void TVPlot::populate() +{ + QwtPlotGrid *grid = new QwtPlotGrid; + grid->enableX( false ); + grid->enableY( true ); + grid->enableXMin( false ); + grid->enableYMin( false ); + grid->setMajorPen( Qt::black, 0, Qt::DotLine ); + grid->attach( this ); + + const double juneValues[] = { 7, 19, 24, 32, 10, 5, 3 }; + const double novemberValues[] = { 4, 15, 22, 34, 13, 8, 4 }; + + Histogram *histogramJune = new Histogram( "Summer", Qt::red ); + histogramJune->setValues( + sizeof( juneValues ) / sizeof( double ), juneValues ); + histogramJune->attach( this ); + + Histogram *histogramNovember = new Histogram( "Winter", Qt::blue ); + histogramNovember->setValues( + sizeof( novemberValues ) / sizeof( double ), novemberValues ); + histogramNovember->attach( this ); +} + +void TVPlot::exportPlot() +{ + QwtPlotRenderer renderer; + renderer.exportTo( this, "tvplot.pdf" ); +} + +void TVPlot::setMode( int mode ) +{ + QwtPlotItemList items = itemList( QwtPlotItem::Rtti_PlotHistogram ); + + for ( int i = 0; i < items.size(); i++ ) + { + QwtPlotHistogram *histogram = static_cast( items[i] ); + if ( mode < 3 ) + { + histogram->setStyle( static_cast( mode ) ); + histogram->setSymbol( NULL ); + + QPen pen( Qt::black, 0 ); + if ( mode == QwtPlotHistogram::Lines ) + pen.setBrush( histogram->brush() ); + + histogram->setPen( pen ); + } + else + { + histogram->setStyle( QwtPlotHistogram::Columns ); + + QwtColumnSymbol *symbol = new QwtColumnSymbol( QwtColumnSymbol::Box ); + symbol->setFrameStyle( QwtColumnSymbol::Raised ); + symbol->setLineWidth( 2 ); + symbol->setPalette( QPalette( histogram->brush().color() ) ); + + histogram->setSymbol( symbol ); + } + } +} + +void TVPlot::showItem( const QVariant &itemInfo, bool on ) +{ + QwtPlotItem *plotItem = infoToItem( itemInfo ); + if ( plotItem ) + plotItem->setVisible( on ); +} + diff --git a/ThirdParty/Qwt/examples/tvplot/tvplot.h b/ThirdParty/Qwt/examples/tvplot/tvplot.h new file mode 100644 index 0000000000..ee09951323 --- /dev/null +++ b/ThirdParty/Qwt/examples/tvplot/tvplot.h @@ -0,0 +1,23 @@ +#ifndef _TV_PLOT_H_ + +#include + +class TVPlot: public QwtPlot +{ + Q_OBJECT + +public: + TVPlot( QWidget * = NULL ); + +public Q_SLOTS: + void setMode( int ); + void exportPlot(); + +private: + void populate(); + +private Q_SLOTS: + void showItem( const QVariant &, bool on ); +}; + +#endif diff --git a/ThirdParty/Qwt/examples/tvplot/tvplot.pro b/ThirdParty/Qwt/examples/tvplot/tvplot.pro new file mode 100644 index 0000000000..f91401551d --- /dev/null +++ b/ThirdParty/Qwt/examples/tvplot/tvplot.pro @@ -0,0 +1,19 @@ +################################################################ +# Qwt Widget Library +# Copyright (C) 1997 Josef Wilgen +# Copyright (C) 2002 Uwe Rathmann +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the Qwt License, Version 1.0 +################################################################ + +include( $${PWD}/../examples.pri ) + +TARGET = tvplot + +SOURCES = \ + tvplot.cpp \ + main.cpp + +HEADERS = \ + tvplot.h diff --git a/ThirdParty/Qwt/playground/curvetracker/curvetracker.cpp b/ThirdParty/Qwt/playground/curvetracker/curvetracker.cpp new file mode 100644 index 0000000000..ab540aac0e --- /dev/null +++ b/ThirdParty/Qwt/playground/curvetracker/curvetracker.cpp @@ -0,0 +1,129 @@ +#include "curvetracker.h" +#include +#include +#include +#include + +struct compareX +{ + inline bool operator()( const double x, const QPointF &pos ) const + { + return ( x < pos.x() ); + } +}; + +CurveTracker::CurveTracker( QWidget *canvas ): + QwtPlotPicker( canvas ) +{ + setTrackerMode( QwtPlotPicker::ActiveOnly ); + setRubberBand( VLineRubberBand ); + + setStateMachine( new QwtPickerDragPointMachine() ); +} + +QRect CurveTracker::trackerRect( const QFont &font ) const +{ + QRect r = QwtPlotPicker::trackerRect( font ); + + // align r to the first curve + + const QwtPlotItemList curves = plot()->itemList( QwtPlotItem::Rtti_PlotCurve ); + if ( curves.size() > 0 ) + { + QPointF pos = invTransform( trackerPosition() ); + + const QLineF line = curveLineAt( + static_cast( curves[0] ), pos.x() ); + if ( !line.isNull() ) + { + const double curveY = line.pointAt( + ( pos.x() - line.p1().x() ) / line.dx() ).y(); + + pos.setY( curveY ); + pos = transform( pos ); + + r.moveBottom( pos.y() ); + } + } + + return r; +} + +QwtText CurveTracker::trackerTextF( const QPointF &pos ) const +{ + QwtText trackerText; + + trackerText.setColor( Qt::black ); + + QColor c( "#333333" ); + trackerText.setBorderPen( QPen( c, 2 ) ); + c.setAlpha( 200 ); + trackerText.setBackgroundBrush( c ); + + QString info; + + const QwtPlotItemList curves = + plot()->itemList( QwtPlotItem::Rtti_PlotCurve ); + + for ( int i = 0; i < curves.size(); i++ ) + { + const QString curveInfo = curveInfoAt( + static_cast( curves[i] ), pos ); + + if ( !curveInfo.isEmpty() ) + { + if ( !info.isEmpty() ) + info += "
"; + + info += curveInfo; + } + } + + trackerText.setText( info ); + return trackerText; +} + +QString CurveTracker::curveInfoAt( + const QwtPlotCurve *curve, const QPointF &pos ) const +{ + const QLineF line = curveLineAt( curve, pos.x() ); + if ( line.isNull() ) + return QString::null; + + const double y = line.pointAt( + ( pos.x() - line.p1().x() ) / line.dx() ).y(); + + QString info( "%2" ); + return info.arg( curve->pen().color().name() ).arg( y ); +} + +QLineF CurveTracker::curveLineAt( + const QwtPlotCurve *curve, double x ) const +{ + QLineF line; + + if ( curve->dataSize() >= 2 ) + { + const QRectF br = curve->boundingRect(); + if ( br.isValid() && x >= br.left() && x <= br.right() ) + { + int index = qwtUpperSampleIndex( + *curve->data(), x, compareX() ); + + if ( index == -1 && + x == curve->sample( curve->dataSize() - 1 ).x() ) + { + // the last sample is excluded from qwtUpperSampleIndex + index = curve->dataSize() - 1; + } + + if ( index > 0 ) + { + line.setP1( curve->sample( index - 1 ) ); + line.setP2( curve->sample( index ) ); + } + } + } + + return line; +} diff --git a/ThirdParty/Qwt/playground/curvetracker/curvetracker.h b/ThirdParty/Qwt/playground/curvetracker/curvetracker.h new file mode 100644 index 0000000000..3fddd48142 --- /dev/null +++ b/ThirdParty/Qwt/playground/curvetracker/curvetracker.h @@ -0,0 +1,22 @@ +#ifndef _CURVE_TRACKER_ +#define _CURVE_TRACKER_H_ + +#include + +class QwtPlotCurve; + +class CurveTracker: public QwtPlotPicker +{ +public: + CurveTracker( QWidget * ); + +protected: + virtual QwtText trackerTextF( const QPointF & ) const; + virtual QRect trackerRect( const QFont & ) const; + +private: + QString curveInfoAt( const QwtPlotCurve *, const QPointF & ) const; + QLineF curveLineAt( const QwtPlotCurve *, double x ) const; +}; + +#endif diff --git a/ThirdParty/Qwt/playground/curvetracker/curvetracker.pro b/ThirdParty/Qwt/playground/curvetracker/curvetracker.pro new file mode 100644 index 0000000000..3f219d73ac --- /dev/null +++ b/ThirdParty/Qwt/playground/curvetracker/curvetracker.pro @@ -0,0 +1,22 @@ +################################################################ +# Qwt Widget Library +# Copyright (C) 1997 Josef Wilgen +# Copyright (C) 2002 Uwe Rathmann +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the Qwt License, Version 1.0 +################################################################ + +include( $${PWD}/../playground.pri ) + +TARGET = curvetracker + +HEADERS = \ + curvetracker.h \ + plot.h + +SOURCES = \ + curvetracker.cpp \ + plot.cpp \ + main.cpp + diff --git a/ThirdParty/Qwt/playground/curvetracker/main.cpp b/ThirdParty/Qwt/playground/curvetracker/main.cpp new file mode 100644 index 0000000000..cbf2848ed2 --- /dev/null +++ b/ThirdParty/Qwt/playground/curvetracker/main.cpp @@ -0,0 +1,13 @@ +#include +#include "plot.h" + +int main( int argc, char **argv ) +{ + QApplication a( argc, argv ); + + Plot plot; + plot.resize( 600, 400 ); + plot.show(); + + return a.exec(); +} diff --git a/ThirdParty/Qwt/playground/curvetracker/plot.cpp b/ThirdParty/Qwt/playground/curvetracker/plot.cpp new file mode 100644 index 0000000000..fb716533f9 --- /dev/null +++ b/ThirdParty/Qwt/playground/curvetracker/plot.cpp @@ -0,0 +1,107 @@ +#include "plot.h" +#include "curvetracker.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +Plot::Plot( QWidget *parent ): + QwtPlot( parent) +{ + setPalette( Qt::black ); + + // we want to have the axis scales like a frame around the + // canvas + plotLayout()->setAlignCanvasToScales( true ); + for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ ) + axisWidget( axis )->setMargin( 0 ); + + QwtPlotCanvas *canvas = new QwtPlotCanvas(); + canvas->setAutoFillBackground( false ); + canvas->setFrameStyle( QFrame::NoFrame ); + setCanvas( canvas ); + + setAxisScale( QwtPlot::yLeft, 0.0, 10.0 ); + + // a title + QwtText title( "Picker Demo" ); + title.setColor( Qt::white ); + title.setRenderFlags( Qt::AlignHCenter | Qt::AlignTop ); + + QFont font; + font.setBold( true ); + title.setFont( font ); + + QwtPlotTextLabel *titleItem = new QwtPlotTextLabel(); + titleItem->setText( title ); + titleItem->attach( this ); + +#if 1 + // section + + //QColor c( "PaleVioletRed" ); + + QwtPlotZoneItem* zone = new QwtPlotZoneItem(); + zone->setPen( Qt::darkGray ); + zone->setBrush( QColor( "#834358" ) ); + zone->setOrientation( Qt::Horizontal ); + zone->setInterval( 3.8, 5.7 ); + zone->attach( this ); + +#else + // grid + + QwtPlotGrid *grid = new QwtPlotGrid(); + grid->setMajorPen( Qt::white, 0, Qt::DotLine ); + grid->setMinorPen( Qt::gray, 0 , Qt::DotLine ); + grid->attach( this ); +#endif + + // curves + + QPolygonF points1; + points1 << QPointF( 0.2, 4.4 ) << QPointF( 1.2, 3.0 ) + << QPointF( 2.7, 4.5 ) << QPointF( 3.5, 6.8 ) + << QPointF( 4.7, 7.9 ) << QPointF( 5.8, 7.1 ); + + insertCurve( "Curve 1", "DarkOrange", points1 ); + + QPolygonF points2; + points2 << QPointF( 0.4, 8.7 ) << QPointF( 1.4, 7.8 ) + << QPointF( 2.3, 5.5 ) << QPointF( 3.3, 4.1 ) + << QPointF( 4.4, 5.2 ) << QPointF( 5.6, 5.7 ); + + insertCurve( "Curve 2", "DodgerBlue", points2 ); + + CurveTracker* tracker = new CurveTracker( this->canvas() ); + + // for the demo we want the tracker to be active without + // having to click on the canvas + tracker->setStateMachine( new QwtPickerTrackerMachine() ); + tracker->setRubberBandPen( QPen( "MediumOrchid" ) ); +} + +void Plot::insertCurve( const QString &title, + const QColor &color, const QPolygonF &points ) +{ + QwtPlotCurve *curve = new QwtPlotCurve(); + curve->setTitle( title ); + curve->setPen( color, 2 ), + curve->setRenderHint( QwtPlotItem::RenderAntialiased, true ); + + QwtSymbol *symbol = new QwtSymbol( QwtSymbol::Ellipse, + QBrush( Qt::white ), QPen( color, 2 ), QSize( 8, 8 ) ); + curve->setSymbol( symbol ); + + curve->setSamples( points ); + + curve->attach( this ); +} + + diff --git a/ThirdParty/Qwt/playground/curvetracker/plot.h b/ThirdParty/Qwt/playground/curvetracker/plot.h new file mode 100644 index 0000000000..c16d734ed3 --- /dev/null +++ b/ThirdParty/Qwt/playground/curvetracker/plot.h @@ -0,0 +1,21 @@ +#ifndef _PLOT_H_ +#define _PLOT_H_ + +#include + +class QPolygonF; + +class Plot: public QwtPlot +{ + Q_OBJECT + +public: + Plot( QWidget * = NULL ); + +private: + void insertCurve( const QString &title, + const QColor &, const QPolygonF & ); +}; + +#endif + diff --git a/ThirdParty/Qwt/playground/graphicscale/canvas.cpp b/ThirdParty/Qwt/playground/graphicscale/canvas.cpp new file mode 100644 index 0000000000..5cd44e6e3f --- /dev/null +++ b/ThirdParty/Qwt/playground/graphicscale/canvas.cpp @@ -0,0 +1,72 @@ +#include "canvas.h" +#include +#include + +Canvas::Canvas( Mode mode, QWidget *parent ): + QWidget( parent ), + d_mode( mode ) +{ + const int m = 10; + setContentsMargins( m, m, m, m ); + + if ( d_mode == Svg ) + d_renderer = new QSvgRenderer( this ); + else + d_graphic = new QwtGraphic(); +} + +Canvas::~Canvas() +{ + if ( d_mode == VectorGraphic ) + delete d_graphic; +} + +void Canvas::setSvg( const QByteArray &data ) +{ + if ( d_mode == VectorGraphic ) + { + d_graphic->reset(); + + QSvgRenderer renderer; + renderer.load( data ); + + QPainter p( d_graphic ); + renderer.render( &p, renderer.viewBoxF() ); + p.end(); + } + else + { + d_renderer->load( data ); + } + + update(); +} + +void Canvas::paintEvent( QPaintEvent * ) +{ + QPainter painter( this ); + + painter.save(); + + painter.setPen( Qt::black ); + painter.setBrush( Qt::white ); + painter.drawRect( contentsRect().adjusted( 0, 0, -1, -1 ) ); + + painter.restore(); + + painter.setPen( Qt::NoPen ); + painter.setBrush( Qt::NoBrush ); + render( &painter, contentsRect() ); +} + +void Canvas::render( QPainter *painter, const QRect &rect ) const +{ + if ( d_mode == Svg ) + { + d_renderer->render( painter, rect ); + } + else + { + d_graphic->render( painter, rect ); + } +} diff --git a/ThirdParty/Qwt/playground/graphicscale/canvas.h b/ThirdParty/Qwt/playground/graphicscale/canvas.h new file mode 100644 index 0000000000..1a62fa33e9 --- /dev/null +++ b/ThirdParty/Qwt/playground/graphicscale/canvas.h @@ -0,0 +1,33 @@ +#include + +class QByteArray; +class QSvgRenderer; +class QwtGraphic; + +class Canvas: public QWidget +{ +public: + enum Mode + { + Svg, + VectorGraphic + }; + + Canvas( Mode, QWidget *parent = NULL ); + virtual ~Canvas(); + + void setSvg( const QByteArray & ); + +protected: + virtual void paintEvent( QPaintEvent * ); + +private: + void render( QPainter *, const QRect & ) const; + + const Mode d_mode; + union + { + QSvgRenderer *d_renderer; + QwtGraphic *d_graphic; + }; +}; diff --git a/ThirdParty/Qwt/playground/graphicscale/graphicscale.pro b/ThirdParty/Qwt/playground/graphicscale/graphicscale.pro new file mode 100644 index 0000000000..64160c99cd --- /dev/null +++ b/ThirdParty/Qwt/playground/graphicscale/graphicscale.pro @@ -0,0 +1,23 @@ +################################################################ +# Qwt Widget Library +# Copyright (C) 1997 Josef Wilgen +# Copyright (C) 2002 Uwe Rathmann +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the Qwt License, Version 1.0 +################################################################ + +include( $${PWD}/../playground.pri ) + +TARGET = graphicscale +QT += svg + +HEADERS = \ + canvas.h \ + mainwindow.h + +SOURCES = \ + canvas.cpp \ + mainwindow.cpp \ + main.cpp + diff --git a/ThirdParty/Qwt/playground/graphicscale/main.cpp b/ThirdParty/Qwt/playground/graphicscale/main.cpp new file mode 100644 index 0000000000..03397ff6c1 --- /dev/null +++ b/ThirdParty/Qwt/playground/graphicscale/main.cpp @@ -0,0 +1,13 @@ +#include +#include "mainwindow.h" + +int main( int argc, char **argv ) +{ + QApplication a( argc, argv ); + + MainWindow w; + w.resize( 600, 400 ); + w.show(); + + return a.exec(); +} diff --git a/ThirdParty/Qwt/playground/graphicscale/mainwindow.cpp b/ThirdParty/Qwt/playground/graphicscale/mainwindow.cpp new file mode 100644 index 0000000000..cbcb398dea --- /dev/null +++ b/ThirdParty/Qwt/playground/graphicscale/mainwindow.cpp @@ -0,0 +1,109 @@ +#include "mainwindow.h" +#include "canvas.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +MainWindow::MainWindow() +{ + QWidget *w = new QWidget( this ); + + d_canvas[0] = new Canvas( Canvas::Svg, this ); + d_canvas[0]->setAutoFillBackground( true ); + d_canvas[0]->setPalette( Qt::gray ); + + d_canvas[1] = new Canvas( Canvas::VectorGraphic, this ); + d_canvas[1]->setAutoFillBackground( true ); + d_canvas[1]->setPalette( Qt::gray ); + + QVBoxLayout *vBox1 = new QVBoxLayout(); + vBox1->setContentsMargins( 0, 0, 0, 0 ); + vBox1->setSpacing( 5 ); + vBox1->addWidget( new QLabel( "SVG" ), 0, Qt::AlignCenter ); + vBox1->addWidget( d_canvas[0], 10 ); + + QVBoxLayout *vBox2 = new QVBoxLayout(); + vBox2->setContentsMargins( 0, 0, 0, 0 ); + vBox2->setSpacing( 5 ); + vBox2->addWidget( new QLabel( "Vector Graphic" ), 0, Qt::AlignCenter ); + vBox2->addWidget( d_canvas[1], 10 ); + + QHBoxLayout *layout = new QHBoxLayout( w ); + layout->addLayout( vBox1 ); + layout->addLayout( vBox2 ); + + setCentralWidget( w ); + + QToolBar *toolBar = new QToolBar( this ); + + QToolButton *btnLoad = new QToolButton( toolBar ); + + btnLoad->setText( "Load SVG" ); + btnLoad->setToolButtonStyle( Qt::ToolButtonTextUnderIcon ); + toolBar->addWidget( btnLoad ); + + addToolBar( toolBar ); + + connect( btnLoad, SIGNAL( clicked() ), this, SLOT( loadSVG() ) ); + +#if 0 + QPainterPath path; + path.addRect( QRectF( 1.0, 1.0, 2.0, 2.0 ) ); + loadPath( path ); +#endif +}; + +MainWindow::~MainWindow() +{ +} + +void MainWindow::loadSVG() +{ + QString dir = "/home1/uwe/qwt/qwt/tests/svg"; + const QString fileName = QFileDialog::getOpenFileName( NULL, + "Load a Scaleable Vector Graphic (SVG) Document", + dir, "SVG Files (*.svg)" ); + + if ( !fileName.isEmpty() ) + loadSVG( fileName ); + + statusBar()->showMessage( fileName ); +} + +void MainWindow::loadSVG( const QString &fileName ) +{ + QFile file( fileName ); + if ( !file.open(QIODevice::ReadOnly | QIODevice::Text) ) + return; + + const QByteArray document = file.readAll(); + file.close(); + + d_canvas[0]->setSvg( document ); + d_canvas[1]->setSvg( document ); +} + + +void MainWindow::loadPath( const QPainterPath &path ) +{ + QBuffer buf; + + QSvgGenerator generator; + generator.setOutputDevice( &buf ); + + QPainter painter( &generator ); + painter.setRenderHint( QPainter::Antialiasing, false ); + painter.setPen( QPen( Qt::blue, 0 ) ); + painter.setBrush( Qt::darkCyan ); + painter.drawPath( path ); + painter.end(); + + d_canvas[0]->setSvg( buf.data() ); + d_canvas[1]->setSvg( buf.data() ); +} diff --git a/ThirdParty/Qwt/playground/graphicscale/mainwindow.h b/ThirdParty/Qwt/playground/graphicscale/mainwindow.h new file mode 100644 index 0000000000..1c3084f7e8 --- /dev/null +++ b/ThirdParty/Qwt/playground/graphicscale/mainwindow.h @@ -0,0 +1,22 @@ +#include + +class Canvas; +class QPainterPath; + +class MainWindow: public QMainWindow +{ + Q_OBJECT + +public: + MainWindow(); + virtual ~MainWindow(); + +private Q_SLOTS: + void loadSVG(); + +private: + void loadSVG( const QString & ); + void loadPath( const QPainterPath & ); + + Canvas *d_canvas[2]; +}; diff --git a/ThirdParty/Qwt/playground/playground.pri b/ThirdParty/Qwt/playground/playground.pri new file mode 100644 index 0000000000..18c2c74de4 --- /dev/null +++ b/ThirdParty/Qwt/playground/playground.pri @@ -0,0 +1,78 @@ +################################################################ +# Qwt Widget Library +# Copyright (C) 1997 Josef Wilgen +# Copyright (C) 2002 Uwe Rathmann +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the Qwt License, Version 1.0 +################################################################### + +QWT_ROOT = $${PWD}/.. +include( $${QWT_ROOT}/qwtconfig.pri ) +include( $${QWT_ROOT}/qwtbuild.pri ) +include( $${QWT_ROOT}/qwtfunctions.pri ) + +TEMPLATE = app + +INCLUDEPATH += $${QWT_ROOT}/src +DEPENDPATH += $${QWT_ROOT}/src + +!debug_and_release { + + DESTDIR = $${QWT_ROOT}/playground/bin +} +else { + CONFIG(debug, debug|release) { + + DESTDIR = $${QWT_ROOT}/playground/bin_debug + } + else { + + DESTDIR = $${QWT_ROOT}/playground/bin + } +} + + +QMAKE_RPATHDIR *= $${QWT_ROOT}/lib + +contains(QWT_CONFIG, QwtFramework) { + + LIBS += -F$${QWT_ROOT}/lib +} +else { + + LIBS += -L$${QWT_ROOT}/lib +} + +qwtAddLibrary(qwt) + +greaterThan(QT_MAJOR_VERSION, 4) { + + QT += printsupport + QT += concurrent +} + +contains(QWT_CONFIG, QwtOpenGL ) { + + QT += opengl +} +else { + + DEFINES += QWT_NO_OPENGL +} + +contains(QWT_CONFIG, QwtSvg) { + + QT += svg +} +else { + + DEFINES += QWT_NO_SVG +} + + +win32 { + contains(QWT_CONFIG, QwtDll) { + DEFINES += QT_DLL QWT_DLL + } +} diff --git a/ThirdParty/Qwt/playground/playground.pro b/ThirdParty/Qwt/playground/playground.pro new file mode 100644 index 0000000000..ec6b5d21d5 --- /dev/null +++ b/ThirdParty/Qwt/playground/playground.pro @@ -0,0 +1,32 @@ +################################################################ +# Qwt Widget Library +# Copyright (C) 1997 Josef Wilgen +# Copyright (C) 2002 Uwe Rathmann +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the Qwt License, Version 1.0 +################################################################ + +include( $${PWD}/../qwtconfig.pri ) + +TEMPLATE = subdirs + +contains(QWT_CONFIG, QwtPlot) { + + SUBDIRS += \ + plotmatrix \ + timescale \ + scaleengine \ + graphicscale \ + rescaler \ + shapes \ + curvetracker \ + symbols + + contains(QWT_CONFIG, QwtSvg) { + + SUBDIRS += \ + svgmap + } + +} diff --git a/ThirdParty/Qwt/playground/plotmatrix/main.cpp b/ThirdParty/Qwt/playground/plotmatrix/main.cpp new file mode 100644 index 0000000000..96a4286104 --- /dev/null +++ b/ThirdParty/Qwt/playground/plotmatrix/main.cpp @@ -0,0 +1,60 @@ +#include "plotmatrix.h" +#include +#include +#include +#include + +class MainWindow: public PlotMatrix +{ +public: + MainWindow(); +}; + +MainWindow::MainWindow(): + PlotMatrix( 3, 4 ) +{ + enableAxis( QwtPlot::yLeft ); + enableAxis( QwtPlot::yRight ); + enableAxis( QwtPlot::xBottom ); + + for ( int row = 0; row < numRows(); row++ ) + { + const double v = qPow( 10.0, row ); + setAxisScale( QwtPlot::yLeft, row, -v, v ); + setAxisScale( QwtPlot::yRight, row, -v, v ); + } + + for ( int col = 0; col < numColumns(); col++ ) + { + const double v = qPow( 10.0, col ); + setAxisScale( QwtPlot::xBottom, col, -v, v ); + setAxisScale( QwtPlot::xTop, col, -v, v ); + } + + for ( int row = 0; row < numRows(); row++ ) + { + for ( int col = 0; col < numColumns(); col++ ) + { + QwtPlot *plt = plot( row, col ); + plt->setCanvasBackground( QColor( Qt::darkBlue ) ); + + QwtPlotGrid *grid = new QwtPlotGrid(); + grid->enableXMin( true ); + grid->setMajorPen( Qt::white, 0, Qt::DotLine ); + grid->setMinorPen( Qt::gray, 0 , Qt::DotLine ); + grid->attach( plt ); + } + } +} + +int main( int argc, char **argv ) +{ + QApplication a( argc, argv ); + + MainWindow mainWindow; + + mainWindow.resize( 800, 600 ); + mainWindow.show(); + + return a.exec(); +} diff --git a/ThirdParty/Qwt/playground/plotmatrix/plotmatrix.cpp b/ThirdParty/Qwt/playground/plotmatrix/plotmatrix.cpp new file mode 100644 index 0000000000..4a896fd20a --- /dev/null +++ b/ThirdParty/Qwt/playground/plotmatrix/plotmatrix.cpp @@ -0,0 +1,293 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +// vim: expandtab + +#include +#include +#include +#include +#include +#include "plotmatrix.h" + +class PlotMatrix::PrivateData +{ +public: + PrivateData(): + inScaleSync( false ) + { + isAxisEnabled[QwtPlot::xBottom] = true; + isAxisEnabled[QwtPlot::xTop] = false; + isAxisEnabled[QwtPlot::yLeft] = true; + isAxisEnabled[QwtPlot::yRight] = false; + } + + bool isAxisEnabled[QwtPlot::axisCnt]; + QVector plotWidgets; + mutable bool inScaleSync; +}; + +PlotMatrix::PlotMatrix( int numRows, int numColumns, QWidget *parent ): + QFrame( parent ) +{ + d_data = new PrivateData(); + d_data->plotWidgets.resize( numRows * numColumns ); + + QGridLayout *layout = new QGridLayout( this ); + for ( int row = 0; row < numRows; row++ ) + { + for ( int col = 0; col < numColumns; col++ ) + { + QwtPlot *plot = new QwtPlot( this ); + layout->addWidget( plot, row, col ); + + for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ ) + { + connect( plot->axisWidget( axis ), + SIGNAL( scaleDivChanged() ), SLOT( scaleDivChanged() ) ); + } + d_data->plotWidgets[row * numColumns + col] = plot; + } + } + + updateLayout(); +} + +PlotMatrix::~PlotMatrix() +{ + delete d_data; +} + +int PlotMatrix::numRows() const +{ + const QGridLayout *l = qobject_cast( layout() ); + if ( l ) + return l->rowCount(); + + return 0; +} + +int PlotMatrix::numColumns() const +{ + const QGridLayout *l = qobject_cast( layout() ); + if ( l ) + return l->columnCount(); + return 0; +} + +QwtPlot* PlotMatrix::plot( int row, int column ) +{ + const int index = row * numColumns() + column; + if ( index < d_data->plotWidgets.size() ) + return d_data->plotWidgets[index]; + + return NULL; +} + +const QwtPlot* PlotMatrix::plot( int row, int column ) const +{ + const int index = row * numColumns() + column; + if ( index < d_data->plotWidgets.size() ) + return d_data->plotWidgets[index]; + + return NULL; +} + +void PlotMatrix::enableAxis( int axis, bool tf ) +{ + if ( axis >= 0 && axis < QwtPlot::axisCnt ) + { + if ( tf != d_data->isAxisEnabled[axis] ) + { + d_data->isAxisEnabled[axis] = tf; + updateLayout(); + } + } +} + +bool PlotMatrix::axisEnabled( int axis ) const +{ + if ( axis >= 0 && axis < QwtPlot::axisCnt ) + return d_data->isAxisEnabled[axis]; + + return false; +} + +void PlotMatrix::setAxisScale( int axis, int rowOrColumn, + double min, double max, double step ) +{ + int row = 0; + int col = 0; + + if ( axis == QwtPlot::xBottom || axis == QwtPlot::xTop ) + col = rowOrColumn; + else + row = rowOrColumn; + + QwtPlot *plt = plot( row, col ); + if ( plt ) + { + plt->setAxisScale( axis, min, max, step ); + plt->updateAxes(); + } +} + +void PlotMatrix::scaleDivChanged() +{ + if ( d_data->inScaleSync ) + return; + + d_data->inScaleSync = true; + + QwtPlot *plt = NULL; + int axisId = -1; + int rowOrColumn = -1; + + // find the changed axis + for ( int row = 0; row < numRows(); row++ ) + { + for ( int col = 0; col < numColumns(); col++ ) + { + QwtPlot *p = plot( row, col ); + if ( p ) + { + for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ ) + { + if ( p->axisWidget( axis ) == sender() ) + { + plt = p; + axisId = axis; + if ( axisId == QwtPlot::xBottom || axisId == QwtPlot::xTop ) + rowOrColumn = col; + else + rowOrColumn = row; + + } + } + } + } + } + + if ( plt ) + { + + // synchronize the axes + if ( axisId == QwtPlot::xBottom || axisId == QwtPlot::xTop ) + { + for ( int row = 0; row < numRows(); row++ ) + { + QwtPlot *p = plot( row, rowOrColumn ); + if ( p != plt ) + p->setAxisScaleDiv( axisId, plt->axisScaleDiv( axisId ) ); + } + } + else + { + for ( int col = 0; col < numColumns(); col++ ) + { + QwtPlot *p = plot( rowOrColumn, col ); + if ( p != plt ) + p->setAxisScaleDiv( axisId, plt->axisScaleDiv( axisId ) ); + } + } + + updateLayout(); + } + + d_data->inScaleSync = false; +} + +void PlotMatrix::updateLayout() +{ + for ( int row = 0; row < numRows(); row++ ) + { + for ( int col = 0; col < numColumns(); col++ ) + { + QwtPlot *p = plot( row, col ); + if ( p ) + { + bool showAxis[QwtPlot::axisCnt]; + showAxis[QwtPlot::xBottom] = + axisEnabled( QwtPlot::xBottom ) && row == numRows() - 1; + showAxis[QwtPlot::xTop] = + axisEnabled( QwtPlot::xTop ) && row == 0; + showAxis[QwtPlot::yLeft] = + axisEnabled( QwtPlot::yLeft ) && col == 0; + showAxis[QwtPlot::yRight] = + axisEnabled( QwtPlot::yRight ) && col == numColumns() - 1; + + for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ ) + { + if ( axis == QwtPlot::xBottom || axis == QwtPlot::xTop ) + p->enableAxis( axis, showAxis[axis] ); + else + { + p->enableAxis( axis, true ); + + QwtScaleDraw *sd = p->axisScaleDraw( axis ); + sd->enableComponent( + QwtScaleDraw::Backbone, showAxis[axis] ); + sd->enableComponent( + QwtScaleDraw::Ticks, showAxis[axis] ); + sd->enableComponent( + QwtScaleDraw::Labels, showAxis[axis] ); + } + } + } + } + } + + for ( int col = 0; col < numColumns(); col++ ) + { + alignVAxes( col, QwtPlot::yLeft ); + alignVAxes( col, QwtPlot::yRight ); + } + + for ( int row = 0; row < numRows(); row++ ) + { + for ( int col = 0; col < numColumns(); col++ ) + { + QwtPlot *p = plot( row, col ); + if ( p ) + p->replot(); + } + } +} + +void PlotMatrix::alignVAxes( int col, int axis ) +{ + if ( axis != QwtPlot::yLeft && axis != QwtPlot::yRight ) + return; + + double maxExtent = 0; + for ( int row = 0; row < numRows(); row++ ) + { + QwtPlot *p = plot( row, col ); + if ( p ) + { + QwtScaleWidget *scaleWidget = p->axisWidget( axis ); + + QwtScaleDraw *sd = scaleWidget->scaleDraw(); + sd->setMinimumExtent( 0.0 ); + + const double extent = sd->extent( scaleWidget->font() ); + if ( extent > maxExtent ) + maxExtent = extent; + } + } + for ( int row = 0; row < numRows(); row++ ) + { + QwtPlot *p = plot( row, col ); + if ( p ) + { + QwtScaleWidget *scaleWidget = p->axisWidget( axis ); + scaleWidget->scaleDraw()->setMinimumExtent( maxExtent ); + } + } +} diff --git a/ThirdParty/Qwt/playground/plotmatrix/plotmatrix.h b/ThirdParty/Qwt/playground/plotmatrix/plotmatrix.h new file mode 100644 index 0000000000..5325819884 --- /dev/null +++ b/ThirdParty/Qwt/playground/plotmatrix/plotmatrix.h @@ -0,0 +1,38 @@ +#ifndef _PLOT_MATRIX_H_ +#define _PLOT_MATRIX_H_ + +#include +#include + +class PlotMatrix: public QFrame +{ + Q_OBJECT + +public: + PlotMatrix( int rows, int columns, QWidget * parent = NULL ); + virtual ~PlotMatrix(); + + int numRows() const; + int numColumns() const; + + QwtPlot* plot( int row, int column ); + const QwtPlot* plot( int row, int column ) const; + + void enableAxis( int axisId, bool tf = true ); + bool axisEnabled( int axisId ) const; + + void setAxisScale( int axisId, int rowOrColumn, + double min, double max, double step = 0 ); + +private Q_SLOTS: + void scaleDivChanged(); + +private: + void updateLayout(); + void alignVAxes( int col, int axis ); + + class PrivateData; + PrivateData *d_data; +}; + +#endif diff --git a/ThirdParty/Qwt/playground/plotmatrix/plotmatrix.pro b/ThirdParty/Qwt/playground/plotmatrix/plotmatrix.pro new file mode 100644 index 0000000000..027907e247 --- /dev/null +++ b/ThirdParty/Qwt/playground/plotmatrix/plotmatrix.pro @@ -0,0 +1,19 @@ +################################################################ +# Qwt Widget Library +# Copyright (C) 1997 Josef Wilgen +# Copyright (C) 2002 Uwe Rathmann +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the Qwt License, Version 1.0 +################################################################ + +include( $${PWD}/../playground.pri ) + +TARGET = plotmatrix + +HEADERS = \ + plotmatrix.h + +SOURCES = \ + plotmatrix.cpp \ + main.cpp diff --git a/ThirdParty/Qwt/playground/rescaler/main.cpp b/ThirdParty/Qwt/playground/rescaler/main.cpp new file mode 100644 index 0000000000..928aa1208c --- /dev/null +++ b/ThirdParty/Qwt/playground/rescaler/main.cpp @@ -0,0 +1,15 @@ +#include +#include "mainwindow.h" + +int main( int argc, char **argv ) +{ + QApplication a( argc, argv ); + + MainWindow mainWindow; + + mainWindow.resize( 800, 600 ); + mainWindow.show(); + + return a.exec(); +} + diff --git a/ThirdParty/Qwt/playground/rescaler/mainwindow.cpp b/ThirdParty/Qwt/playground/rescaler/mainwindow.cpp new file mode 100644 index 0000000000..21ebdcc83b --- /dev/null +++ b/ThirdParty/Qwt/playground/rescaler/mainwindow.cpp @@ -0,0 +1,146 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "plot.h" +#include "mainwindow.h" + +MainWindow::MainWindow() +{ + QFrame *w = new QFrame( this ); + + QWidget *panel = createPanel( w ); + panel->setFixedWidth( 2 * panel->sizeHint().width() ); + d_plot = createPlot( w ); + + QHBoxLayout *layout = new QHBoxLayout( w ); + layout->setMargin( 0 ); + layout->addWidget( panel, 0 ); + layout->addWidget( d_plot, 10 ); + + setCentralWidget( w ); + + setRescaleMode( 0 ); + + ( void )statusBar(); +} + +QWidget *MainWindow::createPanel( QWidget *parent ) +{ + QGroupBox *panel = new QGroupBox( "Navigation Panel", parent ); + + QComboBox *rescaleBox = new QComboBox( panel ); + rescaleBox->setEditable( false ); + rescaleBox->insertItem( KeepScales, "None" ); + rescaleBox->insertItem( Fixed, "Fixed" ); + rescaleBox->insertItem( Expanding, "Expanding" ); + rescaleBox->insertItem( Fitting, "Fitting" ); + + connect( rescaleBox, SIGNAL( activated( int ) ), SLOT( setRescaleMode( int ) ) ); + + d_rescaleInfo = new QLabel( panel ); + d_rescaleInfo->setSizePolicy( + QSizePolicy::Expanding, QSizePolicy::Expanding ); + d_rescaleInfo->setWordWrap( true ); + + QVBoxLayout *layout = new QVBoxLayout( panel ); + layout->addWidget( rescaleBox ); + layout->addWidget( d_rescaleInfo ); + layout->addStretch( 10 ); + + return panel; +} + +Plot *MainWindow::createPlot( QWidget *parent ) +{ + Plot *plot = new Plot( parent, QwtInterval( 0.0, 1000.0 ) ); + plot->replot(); + + d_rescaler = new QwtPlotRescaler( plot->canvas() ); + d_rescaler->setReferenceAxis( QwtPlot::xBottom ); + d_rescaler->setAspectRatio( QwtPlot::yLeft, 1.0 ); + d_rescaler->setAspectRatio( QwtPlot::yRight, 0.0 ); + d_rescaler->setAspectRatio( QwtPlot::xTop, 0.0 ); + + for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ ) + d_rescaler->setIntervalHint( axis, QwtInterval( 0.0, 1000.0 ) ); + + connect( plot, SIGNAL( resized( double, double ) ), + SLOT( showRatio( double, double ) ) ); + return plot; +} + +void MainWindow::setRescaleMode( int mode ) +{ + bool doEnable = true; + QString info; + QRectF rectOfInterest; + QwtPlotRescaler::ExpandingDirection direction = QwtPlotRescaler::ExpandUp; + + switch( mode ) + { + case KeepScales: + { + doEnable = false; + info = "All scales remain unchanged, when the plot is resized"; + break; + } + case Fixed: + { + d_rescaler->setRescalePolicy( QwtPlotRescaler::Fixed ); + info = "The scale of the bottom axis remains unchanged, " + "when the plot is resized. All other scales are changed, " + "so that a pixel on screen means the same distance for" + "all scales."; + break; + } + case Expanding: + { + d_rescaler->setRescalePolicy( QwtPlotRescaler::Expanding ); + info = "The scales of all axis are shrinked/expanded, when " + "resizing the plot, keeping the distance that is represented " + "by one pixel."; + d_rescaleInfo->setText( "Expanding" ); + break; + } + case Fitting: + { + d_rescaler->setRescalePolicy( QwtPlotRescaler::Fitting ); + const QwtInterval xIntv = + d_rescaler->intervalHint( QwtPlot::xBottom ); + const QwtInterval yIntv = + d_rescaler->intervalHint( QwtPlot::yLeft ); + + rectOfInterest = QRectF( xIntv.minValue(), yIntv.minValue(), + xIntv.width(), yIntv.width() ); + direction = QwtPlotRescaler::ExpandBoth; + + info = "Fitting"; + break; + } + } + + d_plot->setRectOfInterest( rectOfInterest ); + + d_rescaleInfo->setText( info ); + d_rescaler->setEnabled( doEnable ); + for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ ) + d_rescaler->setExpandingDirection( direction ); + + if ( doEnable ) + d_rescaler->rescale(); + else + d_plot->replot(); +} + +void MainWindow::showRatio( double xRatio, double yRatio ) +{ + const QString msg = QString( "%1, %2" ).arg( xRatio ).arg( yRatio ); + statusBar()->showMessage( msg ); +} + diff --git a/ThirdParty/Qwt/playground/rescaler/mainwindow.h b/ThirdParty/Qwt/playground/rescaler/mainwindow.h new file mode 100644 index 0000000000..6f52afba22 --- /dev/null +++ b/ThirdParty/Qwt/playground/rescaler/mainwindow.h @@ -0,0 +1,39 @@ +#ifndef _MAINWINDOW_H_ +#define _MAINWINDOW_H_ 1 + +#include + +class QwtPlotRescaler; +class QLabel; +class Plot; + +class MainWindow: public QMainWindow +{ + Q_OBJECT + +public: + enum RescaleMode + { + KeepScales, + Fixed, + Expanding, + Fitting + }; + + MainWindow(); + +private Q_SLOTS: + void setRescaleMode( int ); + void showRatio( double, double ); + +private: + QWidget *createPanel( QWidget * ); + Plot *createPlot( QWidget * ); + + QwtPlotRescaler *d_rescaler; + QLabel *d_rescaleInfo; + + Plot *d_plot; +}; + +#endif diff --git a/ThirdParty/Qwt/playground/rescaler/plot.cpp b/ThirdParty/Qwt/playground/rescaler/plot.cpp new file mode 100644 index 0000000000..d9a2b4cb71 --- /dev/null +++ b/ThirdParty/Qwt/playground/rescaler/plot.cpp @@ -0,0 +1,181 @@ +#include "plot.h" +#include +#include +#include +#include +#include +#include +#include +#include + +class TextItem: public QwtPlotItem +{ +public: + void setText( const QString &text ) + { + m_text = text; + } + + virtual void draw( QPainter *painter, + const QwtScaleMap &, const QwtScaleMap &, + const QRectF &canvasRect ) const + { + const int margin = 5; + const QRectF textRect = + canvasRect.adjusted( margin, margin, -margin, -margin ); + + painter->setPen( Qt::white ); + painter->drawText( textRect, + Qt::AlignBottom | Qt::AlignRight, m_text ); + } + +private: + QString m_text; +}; + + +// RectItem shows how to implement a simple plot item, +// what wouldn't be necessary as QwtPlotShapeItem +// would do the same +class RectItem: public QwtPlotItem +{ +public: + enum Type + { + Rect, + Ellipse + }; + + RectItem( Type type ): + d_type( type ) + { + } + + void setPen( const QPen &pen ) + { + if ( pen != d_pen ) + { + d_pen = pen; + itemChanged(); + } + } + + void setBrush( const QBrush &brush ) + { + if ( brush != d_brush ) + { + d_brush = brush; + itemChanged(); + } + } + void setRect( const QRectF &rect ) + { + if ( d_rect != rect ) + { + d_rect = rect; + itemChanged(); + } + } + + virtual QRectF boundingRect() const + { + return d_rect; + } + + virtual void draw( QPainter *painter, + const QwtScaleMap &xMap, const QwtScaleMap &yMap, + const QRectF & ) const + { + if ( d_rect.isValid() ) + { + const QRectF rect = QwtScaleMap::transform( + xMap, yMap, d_rect ); + + painter->setPen( d_pen ); + painter->setBrush( d_brush ); + + if ( d_type == Ellipse ) + QwtPainter::drawEllipse( painter, rect ); + else + QwtPainter::drawRect( painter, rect ); + } + } + +private: + QPen d_pen; + QBrush d_brush; + QRectF d_rect; + Type d_type; +}; + +Plot::Plot( QWidget *parent, const QwtInterval &interval ): + QwtPlot( parent ) +{ + for ( int axis = 0; axis < QwtPlot::axisCnt; axis ++ ) + setAxisScale( axis, interval.minValue(), interval.maxValue() ); + + setCanvasBackground( QColor( Qt::darkBlue ) ); + plotLayout()->setAlignCanvasToScales( true ); + + // grid + QwtPlotGrid *grid = new QwtPlotGrid; + //grid->enableXMin(true); + grid->setMajorPen( Qt::white, 0, Qt::DotLine ); + grid->setMinorPen( Qt::gray, 0 , Qt::DotLine ); + grid->attach( this ); + + const int numEllipses = 10; + + for ( int i = 0; i < numEllipses; i++ ) + { + const double x = interval.minValue() + + qrand() % qRound( interval.width() ); + const double y = interval.minValue() + + qrand() % qRound( interval.width() ); + const double r = interval.minValue() + + qrand() % qRound( interval.width() / 6 ); + + const QRectF area( x - r, y - r , 2 * r, 2 * r ); + + RectItem *item = new RectItem( RectItem::Ellipse ); + item->setRenderHint( QwtPlotItem::RenderAntialiased, true ); + item->setRect( area ); + item->setPen( QPen( Qt::yellow ) ); + item->attach( this ); + } + + TextItem *textItem = new TextItem(); + textItem->setText( "Navigation Example" ); + textItem->attach( this ); + + d_rectOfInterest = new RectItem( RectItem::Rect ); + d_rectOfInterest->setPen( Qt::NoPen ); + QColor c = Qt::gray; + c.setAlpha( 100 ); + d_rectOfInterest->setBrush( QBrush( c ) ); + d_rectOfInterest->attach( this ); +} + +void Plot::updateLayout() +{ + QwtPlot::updateLayout(); + + const QwtScaleMap xMap = canvasMap( QwtPlot::xBottom ); + const QwtScaleMap yMap = canvasMap( QwtPlot::yLeft ); + + const QRect cr = canvas()->contentsRect(); + const double x1 = xMap.invTransform( cr.left() ); + const double x2 = xMap.invTransform( cr.right() ); + const double y1 = yMap.invTransform( cr.bottom() ); + const double y2 = yMap.invTransform( cr.top() ); + + const double xRatio = ( x2 - x1 ) / cr.width(); + const double yRatio = ( y2 - y1 ) / cr.height(); + + Q_EMIT resized( xRatio, yRatio ); +} + +void Plot::setRectOfInterest( const QRectF &rect ) +{ + d_rectOfInterest->setRect( rect ); +} diff --git a/ThirdParty/Qwt/playground/rescaler/plot.h b/ThirdParty/Qwt/playground/rescaler/plot.h new file mode 100644 index 0000000000..0d9656ce4d --- /dev/null +++ b/ThirdParty/Qwt/playground/rescaler/plot.h @@ -0,0 +1,28 @@ +#ifndef _PLOT_H_ +#define _PLOT_H_ 1 + +#include + +class RectItem; +class QwtInterval; + +class Plot: public QwtPlot +{ + Q_OBJECT + +public: + Plot( QWidget *parent, const QwtInterval & ); + virtual void updateLayout(); + + void setRectOfInterest( const QRectF & ); + +Q_SIGNALS: + void resized( double xRatio, double yRatio ); + +private: + RectItem *d_rectOfInterest; +}; + +#endif + + diff --git a/ThirdParty/Qwt/playground/rescaler/rescaler.pro b/ThirdParty/Qwt/playground/rescaler/rescaler.pro new file mode 100644 index 0000000000..c29d9e98a4 --- /dev/null +++ b/ThirdParty/Qwt/playground/rescaler/rescaler.pro @@ -0,0 +1,22 @@ +################################################################ +# Qwt Widget Library +# Copyright (C) 1997 Josef Wilgen +# Copyright (C) 2002 Uwe Rathmann +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the Qwt License, Version 1.0 +################################################################ + +include( $${PWD}/../playground.pri ) + +TARGET = rescaler + +HEADERS = \ + mainwindow.h \ + plot.h + +SOURCES = \ + mainwindow.cpp \ + plot.cpp \ + main.cpp + diff --git a/ThirdParty/Qwt/playground/scaleengine/mainwindow.cpp b/ThirdParty/Qwt/playground/scaleengine/mainwindow.cpp new file mode 100644 index 0000000000..894d99149b --- /dev/null +++ b/ThirdParty/Qwt/playground/scaleengine/mainwindow.cpp @@ -0,0 +1,120 @@ +#include "mainwindow.h" +#include "plot.h" +#include "transformplot.h" +#include +#include +#include + +class TransformPos: public QwtTransform +{ +public: + TransformPos( double pos, double range, double factor ): + d_position( pos ), + d_range( range ), + d_factor( factor ), + d_powRange( qPow( d_range, d_factor ) ) + { + } + + virtual double transform( double value ) const + { + const double v1 = d_position - d_range; + const double v2 = v1 + 2 * d_range; + + if ( value <= v1 ) + { + return value; + } + + if ( value >= v2 ) + { + return v1 + 2 * d_powRange + value - v2; + } + + double v; + + if ( value <= d_position ) + { + v = v1 + qPow( value - v1, d_factor ); + } + else + { + v = v1 + 2 * d_powRange - qPow( v2 - value, d_factor ); + } + + return v; + } + + virtual double invTransform( double value ) const + { + const double v1 = d_position - d_range; + const double v2 = v1 + 2 * d_powRange; + + if ( value < v1 ) + { + return value; + } + + if ( value >= v2 ) + { + return value + 2 * ( d_range - d_powRange ); + } + + double v; + if ( value <= v1 + d_powRange ) + { + v = v1 + qPow( value - v1, 1.0 / d_factor ); + } + else + { + v = d_position + d_range - qPow( v2 - value, 1.0 / d_factor ); + } + + return v; + } + + virtual QwtTransform *copy() const + { + return new TransformPos( d_position, d_range, d_factor ); + } + +private: + const double d_position; + const double d_range; + const double d_factor; + const double d_powRange; +}; + +MainWindow::MainWindow( QWidget *parent ): + QMainWindow( parent ) +{ + QSplitter *splitter = new QSplitter( Qt::Vertical ); + + d_transformPlot = new TransformPlot( splitter ); + + d_transformPlot->insertTransformation( "Square Root", + QColor( "DarkSlateGray" ), new QwtPowerTransform( 0.5 ) ); + d_transformPlot->insertTransformation( "Linear", + QColor( "Peru" ), new QwtNullTransform() ); + d_transformPlot->insertTransformation( "Cubic", + QColor( "OliveDrab" ), new QwtPowerTransform( 3.0 ) ); + d_transformPlot->insertTransformation( "Power 10", + QColor( "Indigo" ), new QwtPowerTransform( 10.0 ) ); + d_transformPlot->insertTransformation( "Log", + QColor( "SteelBlue" ), new QwtLogTransform() ); + d_transformPlot->insertTransformation( "At 400", + QColor( "Crimson" ), new TransformPos( 400.0, 100.0, 1.4 ) ); + + const QwtPlotItemList curves = + d_transformPlot->itemList( QwtPlotItem::Rtti_PlotCurve ); + if ( !curves.isEmpty() ) + d_transformPlot->setLegendChecked( curves[ 2 ] ); + + d_plot = new Plot( splitter ); + d_plot->setTransformation( new QwtPowerTransform( 3.0 ) ); + + setCentralWidget( splitter ); + + connect( d_transformPlot, SIGNAL( selected( QwtTransform * ) ), + d_plot, SLOT( setTransformation( QwtTransform * ) ) ); +} diff --git a/ThirdParty/Qwt/playground/scaleengine/mainwindow.h b/ThirdParty/Qwt/playground/scaleengine/mainwindow.h new file mode 100644 index 0000000000..6eea4844dc --- /dev/null +++ b/ThirdParty/Qwt/playground/scaleengine/mainwindow.h @@ -0,0 +1,16 @@ +#include + +class Plot; +class TransformPlot; + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + MainWindow( QWidget *parent = 0 ); + +private: + Plot *d_plot; + TransformPlot *d_transformPlot; +}; diff --git a/ThirdParty/Qwt/playground/scaleengine/plot.cpp b/ThirdParty/Qwt/playground/scaleengine/plot.cpp new file mode 100644 index 0000000000..b5666bfd12 --- /dev/null +++ b/ThirdParty/Qwt/playground/scaleengine/plot.cpp @@ -0,0 +1,70 @@ +#include "plot.h" +#include +#include +#include +#include +#include + +Plot::Plot( QWidget *parent ): + QwtPlot( parent ) +{ + setCanvasBackground( Qt::white ); + + setAxisScale(QwtPlot::yLeft, 0.0, 10.0 ); + setTransformation( new QwtNullTransform() ); + + populate(); + + QwtPlotPicker *picker = new QwtPlotPicker( canvas() ); + picker->setTrackerMode( QwtPlotPicker::AlwaysOn ); +} + +void Plot::populate() +{ + QwtPlotGrid *grid = new QwtPlotGrid(); + grid->setMinorPen( Qt::black, 0, Qt::DashLine ); + grid->enableXMin( true ); + grid->attach( this ); + + QwtPlotCurve *curve = new QwtPlotCurve(); + curve->setTitle("Some Points"); + curve->setPen( Qt::blue, 4 ), + curve->setRenderHint( QwtPlotItem::RenderAntialiased, true ); + + QwtSymbol *symbol = new QwtSymbol( QwtSymbol::Ellipse, + QBrush( Qt::yellow ), QPen( Qt::red, 2 ), QSize( 8, 8 ) ); + curve->setSymbol( symbol ); + + QPolygonF points; + points << QPointF( 10.0, 4.4 ) + << QPointF( 100.0, 3.0 ) << QPointF( 200.0, 4.5 ) + << QPointF( 300.0, 6.8 ) << QPointF( 400.0, 7.9 ) + << QPointF( 500.0, 7.1 ) << QPointF( 600.0, 7.9 ) + << QPointF( 700.0, 7.1 ) << QPointF( 800.0, 5.4 ) + << QPointF( 900.0, 2.8 ) << QPointF( 1000.0, 3.6 ); + curve->setSamples( points ); + curve->attach( this ); +} + +void Plot::setTransformation( QwtTransform *transform ) +{ + QwtLinearScaleEngine *scaleEngine = new QwtLinearScaleEngine(); + scaleEngine->setTransformation( transform ); + + setAxisScaleEngine( QwtPlot::xBottom, scaleEngine ); + + // we have to reassign the axis settinge, because they are + // invalidated, when the scale engine has changed + + QwtScaleDiv scaleDiv = + axisScaleEngine( QwtPlot::xBottom )->divideScale( 10.0, 1000.0, 8, 10 ); + + QList ticks; + ticks += 10.0; + ticks += scaleDiv.ticks( QwtScaleDiv::MajorTick ); + scaleDiv.setTicks( QwtScaleDiv::MajorTick, ticks ); + + setAxisScaleDiv( QwtPlot::xBottom, scaleDiv ); + + replot(); +} diff --git a/ThirdParty/Qwt/playground/scaleengine/plot.h b/ThirdParty/Qwt/playground/scaleengine/plot.h new file mode 100644 index 0000000000..6548505b05 --- /dev/null +++ b/ThirdParty/Qwt/playground/scaleengine/plot.h @@ -0,0 +1,23 @@ +#ifndef _PLOT_H_ +#define _PLOT_H_ + +#include + +class QwtTransform; + +class Plot: public QwtPlot +{ + Q_OBJECT + +public: + Plot( QWidget *parent = NULL ); + +public Q_SLOTS: + void setTransformation( QwtTransform * ); + +private: + void populate(); +}; + +#endif + diff --git a/ThirdParty/Qwt/playground/scaleengine/scaleengine.cpp b/ThirdParty/Qwt/playground/scaleengine/scaleengine.cpp new file mode 100644 index 0000000000..6e02da2cb9 --- /dev/null +++ b/ThirdParty/Qwt/playground/scaleengine/scaleengine.cpp @@ -0,0 +1,13 @@ +#include +#include "mainwindow.h" + +int main(int argc, char **argv) +{ + QApplication a(argc, argv); + + MainWindow window; + window.resize(800,600); + window.show(); + + return a.exec(); +} diff --git a/ThirdParty/Qwt/playground/scaleengine/scaleengine.pro b/ThirdParty/Qwt/playground/scaleengine/scaleengine.pro new file mode 100644 index 0000000000..0b2d6f5c4b --- /dev/null +++ b/ThirdParty/Qwt/playground/scaleengine/scaleengine.pro @@ -0,0 +1,24 @@ +################################################################ +# Qwt Widget Library +# Copyright (C) 1997 Josef Wilgen +# Copyright (C) 2002 Uwe Rathmann +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the Qwt License, Version 1.0 +################################################################ + +include( $${PWD}/../playground.pri ) + +TARGET = scaleengine + +HEADERS = \ + transformplot.h \ + plot.h \ + mainwindow.h + +SOURCES = \ + transformplot.cpp \ + plot.cpp \ + mainwindow.cpp \ + scaleengine.cpp + diff --git a/ThirdParty/Qwt/playground/scaleengine/transformplot.cpp b/ThirdParty/Qwt/playground/scaleengine/transformplot.cpp new file mode 100644 index 0000000000..4f79e8a9cd --- /dev/null +++ b/ThirdParty/Qwt/playground/scaleengine/transformplot.cpp @@ -0,0 +1,108 @@ +#include "transformplot.h" +#include +#include +#include +#include +#include +#include + +class TransformData: public QwtSyntheticPointData +{ +public: + TransformData( QwtTransform *transform ): + QwtSyntheticPointData( 200 ), + d_transform( transform ) + { + } + + virtual ~TransformData() + { + delete d_transform; + } + + const QwtTransform *transform() const + { + return d_transform; + } + + virtual double y( double x ) const + { + const double min = 10.0; + const double max = 1000.0; + + const double value = min + x * ( max - min ); + + const double s1 = d_transform->transform( min ); + const double s2 = d_transform->transform( max ); + const double s = d_transform->transform( value ); + + return ( s - s1 ) / ( s2 - s1 ); + } + +private: + QwtTransform *d_transform; +}; + +TransformPlot::TransformPlot( QWidget *parent ): + QwtPlot( parent ) +{ + setTitle( "Transformations" ); + setCanvasBackground( Qt::white ); + + setAxisScale( QwtPlot::xBottom, 0.0, 1.0 ); + setAxisScale( QwtPlot::yLeft, 0.0, 1.0 ); + + QwtLegend *legend = new QwtLegend(); + legend->setDefaultItemMode( QwtLegendData::Checkable ); + insertLegend( legend, QwtPlot::RightLegend ); + + connect( legend, SIGNAL( checked( const QVariant &, bool, int ) ), + this, SLOT( legendChecked( const QVariant &, bool ) ) ); +} + +void TransformPlot::insertTransformation( + const QString &title, const QColor &color, QwtTransform *transform ) +{ + QwtPlotCurve *curve = new QwtPlotCurve( title ); + curve->setRenderHint( QwtPlotItem::RenderAntialiased, true ); + curve->setPen( color, 2 ); + curve->setData( new TransformData( transform ) ); + curve->attach( this ); +} + +void TransformPlot::legendChecked( const QVariant &itemInfo, bool on ) +{ + QwtPlotItem *plotItem = infoToItem( itemInfo ); + + setLegendChecked( plotItem ); + + if ( on && plotItem->rtti() == QwtPlotItem::Rtti_PlotCurve ) + { + QwtPlotCurve *curve = static_cast( plotItem ); + TransformData *data = static_cast( curve->data() ); + + Q_EMIT selected( data->transform()->copy() ); + } +} + +void TransformPlot::setLegendChecked( QwtPlotItem *plotItem ) +{ + const QwtPlotItemList items = itemList(); + for ( int i = 0; i < items.size(); i++ ) + { + QwtPlotItem *item = items[ i ]; + if ( item->testItemAttribute( QwtPlotItem::Legend ) ) + { + QwtLegend *lgd = qobject_cast( legend() ); + + QwtLegendLabel *label = qobject_cast< QwtLegendLabel *>( + lgd->legendWidget( itemToInfo( item ) ) ); + if ( label ) + { + lgd->blockSignals( true ); + label->setChecked( item == plotItem ); + lgd->blockSignals( false ); + } + } + } +} diff --git a/ThirdParty/Qwt/playground/scaleengine/transformplot.h b/ThirdParty/Qwt/playground/scaleengine/transformplot.h new file mode 100644 index 0000000000..8dd6c71219 --- /dev/null +++ b/ThirdParty/Qwt/playground/scaleengine/transformplot.h @@ -0,0 +1,27 @@ +#ifndef _TRANSFORM_PLOT_H_ +#define _TRANSFORM_PLOT_H_ + +#include + +class TransformPlot: public QwtPlot +{ + Q_OBJECT + +public: + TransformPlot( QWidget *parent = NULL ); + void insertTransformation( const QString &, + const QColor &, QwtTransform * ); + + void setLegendChecked( QwtPlotItem * ); + +Q_SIGNALS: + void selected( QwtTransform * ); + +private Q_SLOTS: + void legendChecked( const QVariant &, bool on ); + +private: +}; + +#endif + diff --git a/ThirdParty/Qwt/playground/shapes/shapes.cpp b/ThirdParty/Qwt/playground/shapes/shapes.cpp new file mode 100644 index 0000000000..c0e27c514f --- /dev/null +++ b/ThirdParty/Qwt/playground/shapes/shapes.cpp @@ -0,0 +1,100 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class Plot : public QwtPlot +{ +public: + Plot( QWidget *parent = NULL ); + +private: + void populate(); +}; + + +Plot::Plot( QWidget *parent ): + QwtPlot( parent ) +{ + setPalette( QColor( 60, 60, 60 ) ); + canvas()->setPalette( Qt::white ); + + // panning with the left mouse button + ( void ) new QwtPlotPanner( canvas() ); + + // zoom in/out with the wheel + ( void ) new QwtPlotMagnifier( canvas() ); + + setTitle( "Shapes" ); + insertLegend( new QwtLegend(), QwtPlot::RightLegend ); + + // axes + setAxisTitle( xBottom, "x -->" ); + setAxisTitle( yLeft, "y -->" ); +#if 0 + setAxisScaleEngine( xBottom, new QwtLog10ScaleEngine ); + setAxisScaleEngine( yLeft, new QwtLog10ScaleEngine ); +#endif + + populate(); +} + +void Plot::populate() +{ + const double d = 900.0; + const QRectF rect( 1.0, 1.0, d, d ); + + QPainterPath path; + //path.setFillRule( Qt::WindingFill ); + path.addEllipse( rect ); + + const QRectF rect2 = rect.adjusted( 0.2 * d, 0.3 * d, -0.22 * d, 1.5 * d ); + path.addEllipse( rect2 ); + +#if 0 + QFont font; + font.setPointSizeF( 200 ); + QPainterPath textPath; + textPath.addText( rect.center(), font, "Seppi" ); + + QTransform transform; + transform.translate( rect.center().x() - 600, rect.center().y() + 50 ); + transform.rotate( 180.0, Qt::XAxis ); + + textPath = transform.map( textPath ); + + path.addPath( textPath ); +#endif + + QwtPlotShapeItem *item = new QwtPlotShapeItem( "Shape" ); + item->setItemAttribute( QwtPlotItem::Legend, true ); + item->setRenderHint( QwtPlotItem::RenderAntialiased, true ); +#if 1 + item->setRenderTolerance( 1.0 ); +#endif + item->setShape( path ); + item->setPen( Qt::yellow ); + + QColor c = Qt::darkRed; + c.setAlpha( 100 ); + item->setBrush( c ); + + item->attach( this ); +} + +int main( int argc, char **argv ) +{ + QApplication a( argc, argv ); + + Plot plot; + plot.resize( 600, 400 ); + plot.show(); + + return a.exec(); +} diff --git a/ThirdParty/Qwt/playground/shapes/shapes.pro b/ThirdParty/Qwt/playground/shapes/shapes.pro new file mode 100644 index 0000000000..2aaf01645c --- /dev/null +++ b/ThirdParty/Qwt/playground/shapes/shapes.pro @@ -0,0 +1,16 @@ +################################################################ +# Qwt Widget Library +# Copyright (C) 1997 Josef Wilgen +# Copyright (C) 2002 Uwe Rathmann +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the Qwt License, Version 1.0 +################################################################ + +include( $${PWD}/../playground.pri ) + +TARGET = shapes + +SOURCES = \ + shapes.cpp + diff --git a/ThirdParty/Qwt/playground/svgmap/main.cpp b/ThirdParty/Qwt/playground/svgmap/main.cpp new file mode 100644 index 0000000000..74c334e74d --- /dev/null +++ b/ThirdParty/Qwt/playground/svgmap/main.cpp @@ -0,0 +1,49 @@ +#include +#include +#include +#include +#include "plot.h" + +class MainWindow: public QMainWindow +{ +public: + MainWindow( const QString &fileName ) + { + Plot *plot = new Plot( this ); + if ( !fileName.isEmpty() ) + plot->loadSVG( fileName ); + + setCentralWidget( plot ); + +#ifndef QT_NO_FILEDIALOG + + QToolBar *toolBar = new QToolBar( this ); + + QToolButton *btnLoad = new QToolButton( toolBar ); + + btnLoad->setText( "Load SVG" ); + btnLoad->setToolButtonStyle( Qt::ToolButtonTextUnderIcon ); + toolBar->addWidget( btnLoad ); + + addToolBar( toolBar ); + + connect( btnLoad, SIGNAL( clicked() ), plot, SLOT( loadSVG() ) ); +#endif + } +}; + +int main( int argc, char **argv ) +{ + QApplication a( argc, argv ); + + QString fileName; + if ( argc > 1 ) + fileName = argv[1]; + + MainWindow w( fileName ); + w.resize( 600, 400 ); + w.show(); + + int rv = a.exec(); + return rv; +} diff --git a/ThirdParty/Qwt/playground/svgmap/plot.cpp b/ThirdParty/Qwt/playground/svgmap/plot.cpp new file mode 100644 index 0000000000..6aa86804e6 --- /dev/null +++ b/ThirdParty/Qwt/playground/svgmap/plot.cpp @@ -0,0 +1,79 @@ +#include +#include +#include +#include +#include +#include +#include +#include "plot.h" + +Plot::Plot( QWidget *parent ): + QwtPlot( parent ), + d_mapItem( NULL ), + d_mapRect( 0.0, 0.0, 100.0, 100.0 ) // something +{ +#if 1 + /* + d_mapRect is only a reference for zooming, but + the ranges are nothing useful for the user. So we + hide the axes. + */ + plotLayout()->setCanvasMargin( 0 ); + for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ ) + enableAxis( axis, false ); +#else + QwtPlotGrid *grid = new QwtPlotGrid(); + grid->attach( this ); +#endif + + /* + Navigation: + + Left Mouse Button: Panning + Mouse Wheel: Zooming In/Out + Right Mouse Button: Reset to initial + */ + + ( void )new QwtPlotPanner( canvas() ); + ( void )new QwtPlotMagnifier( canvas() ); + + canvas()->setFocusPolicy( Qt::WheelFocus ); + rescale(); +} + +#ifndef QT_NO_FILEDIALOG + +void Plot::loadSVG() +{ + QString dir; + const QString fileName = QFileDialog::getOpenFileName( NULL, + "Load a Scaleable Vector Graphic (SVG) Map", + dir, "SVG Files (*.svg)" ); + + if ( !fileName.isEmpty() ) + loadSVG( fileName ); +} + +#endif + +void Plot::loadSVG( const QString &fileName ) +{ + if ( d_mapItem == NULL ) + { + d_mapItem = new QwtPlotSvgItem(); + d_mapItem->attach( this ); + } + + d_mapItem->loadFile( d_mapRect, fileName ); + rescale(); + + replot(); +} + +void Plot::rescale() +{ + setAxisScale( QwtPlot::xBottom, + d_mapRect.left(), d_mapRect.right() ); + setAxisScale( QwtPlot::yLeft, + d_mapRect.top(), d_mapRect.bottom() ); +} diff --git a/ThirdParty/Qwt/playground/svgmap/plot.h b/ThirdParty/Qwt/playground/svgmap/plot.h new file mode 100644 index 0000000000..b05c32b3e3 --- /dev/null +++ b/ThirdParty/Qwt/playground/svgmap/plot.h @@ -0,0 +1,26 @@ +#include +#include + +class QwtPlotSvgItem; + +class Plot: public QwtPlot +{ + Q_OBJECT + +public: + Plot( QWidget * = NULL ); + +public Q_SLOTS: + +#ifndef QT_NO_FILEDIALOG + void loadSVG(); +#endif + + void loadSVG( const QString & ); + +private: + void rescale(); + + QwtPlotSvgItem *d_mapItem; + const QRectF d_mapRect; +}; diff --git a/ThirdParty/Qwt/playground/svgmap/svgmap.pro b/ThirdParty/Qwt/playground/svgmap/svgmap.pro new file mode 100644 index 0000000000..9f3ad44d1a --- /dev/null +++ b/ThirdParty/Qwt/playground/svgmap/svgmap.pro @@ -0,0 +1,26 @@ +################################################################ +# Qwt Widget Library +# Copyright (C) 1997 Josef Wilgen +# Copyright (C) 2002 Uwe Rathmann +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the Qwt License, Version 1.0 +################################################################ + +include( $${PWD}/../playground.pri ) + +!contains(QWT_CONFIG, QwtSvg) { + + message(Are you trying to build Qwt with the Qt Creator as Shadow Build ?) + error(Qwt is configured without SVG support !) +} + +TARGET = svgmap +QT += svg + +HEADERS = \ + plot.h + +SOURCES = \ + plot.cpp \ + main.cpp diff --git a/ThirdParty/Qwt/playground/symbols/symbols.cpp b/ThirdParty/Qwt/playground/symbols/symbols.cpp new file mode 100644 index 0000000000..63f85f8d74 --- /dev/null +++ b/ThirdParty/Qwt/playground/symbols/symbols.cpp @@ -0,0 +1,212 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class MySymbol: public QwtSymbol +{ +public: + MySymbol( QwtSymbol::Style style, const QBrush &brush ) + { + QPen pen( Qt::black, 0 ); + pen.setJoinStyle( Qt::MiterJoin ); + pen.setCosmetic( true ); + + QPainterPath path = createArrow( QSize( 16, 24 ) ); + + const QSizeF pathSize = path.boundingRect().size(); + + setSize( 0.8 * pathSize.toSize() ); + + setPinPoint( QPointF( 0.0, 0.0 ) ); + + switch( style ) + { + case QwtSymbol::Pixmap: + { + const QSize sz = size(); + + const double ratio = qMin( sz.width() / pathSize.width(), + sz.height() / pathSize.height() ); + + QTransform transform; + transform.scale( ratio, ratio ); + + path = transform.map( path ); + + if ( isPinPointEnabled() ) + { + QPointF pos = transform.map( pinPoint() ); + setPinPoint( pos ); + } + + const QRectF br = path.boundingRect(); + + int m = 2 + qCeil( pen.widthF() ); + + QPixmap pm( sz + QSize( 2 * m, 2 * m ) ); + pm.fill( Qt::transparent ); + + QPainter painter( &pm ); + painter.setRenderHint( QPainter::Antialiasing, true ); + + painter.setPen( pen ); + painter.setBrush( brush ); + + painter.translate( m, m ); + painter.translate( -br.left(), br.top() ); + painter.drawPath( path ); + + setPixmap( pm ); + setSize( pm.size() ); + if ( isPinPointEnabled() ) + setPinPoint( pinPoint() + QPointF( m, m ) ); + + break; + } + case QwtSymbol::Graphic: + { + QwtGraphic graphic; + graphic.setRenderHint( QwtGraphic::RenderPensUnscaled ); + + QPainter painter( &graphic ); + painter.setRenderHint( QPainter::Antialiasing, true ); + painter.setPen( pen ); + painter.setBrush( brush ); + + painter.drawPath( path ); + painter.end(); + + setGraphic( graphic ); + break; + } + case QwtSymbol::SvgDocument: + { + QBuffer buf; + + QSvgGenerator generator; + generator.setOutputDevice( &buf ); + + QPainter painter( &generator ); + painter.setRenderHint( QPainter::Antialiasing, true ); + painter.setPen( pen ); + painter.setBrush( brush ); + + painter.drawPath( path ); + painter.end(); + + setSvgDocument( buf.data() ); + break; + } + case QwtSymbol::Path: + default: + { + setPen( pen ); + setBrush( brush ); + setPath( path ); + } + } + + } + +private: + QPainterPath createArrow( const QSizeF &size ) const + { + const double w = size.width(); + const double h = size.height(); + const double y0 = 0.6 * h; + + QPainterPath path; + path.moveTo( 0, h ); + path.lineTo( 0, y0 ); + path.lineTo( -0.5 * w, y0 ); + path.lineTo( 0, 0 ); + path.lineTo( 0.5 * w, y0 ); + path.lineTo( 0, y0 ); + + QTransform transform; + transform.rotate( -30.0 ); + path = transform.map( path ); + + return path; + } +}; + +int main( int argc, char **argv ) +{ + QApplication a( argc, argv ); + + QwtPlot plot; + plot.setTitle( "Plot Demo" ); + plot.setCanvasBackground( Qt::white ); + + plot.setAxisScale( QwtPlot::xBottom, -1.0, 6.0 ); + + QwtLegend *legend = new QwtLegend(); + legend->setDefaultItemMode( QwtLegendData::Checkable ); + plot.insertLegend( legend ); + + for ( int i = 0; i < 4; i++ ) + { + QwtPlotCurve *curve = new QwtPlotCurve(); + curve->setRenderHint( QwtPlotItem::RenderAntialiased, true ); + curve->setPen( Qt::blue ); + + QBrush brush; + QwtSymbol::Style style = QwtSymbol::NoSymbol; + QString title; + if ( i == 0 ) + { + brush = Qt::magenta; + style = QwtSymbol::Path; + title = "Path"; + } + else if ( i == 2 ) + { + brush = Qt::red; + style = QwtSymbol::Graphic; + title = "Graphic"; + } + else if ( i == 1 ) + { + brush = Qt::yellow; + style = QwtSymbol::SvgDocument; + title = "Svg"; + } + else if ( i == 3 ) + { + brush = Qt::cyan; + style = QwtSymbol::Pixmap; + title = "Pixmap"; + } + + MySymbol *symbol = new MySymbol( style, brush ); + + curve->setSymbol( symbol ); + curve->setTitle( title ); + curve->setLegendAttribute( QwtPlotCurve::LegendShowSymbol, true ); + curve->setLegendIconSize( QSize( 15, 18 ) ); + + QPolygonF points; + points << QPointF( 0.0, 4.4 ) << QPointF( 1.0, 3.0 ) + << QPointF( 2.0, 4.5 ) << QPointF( 3.0, 6.8 ) + << QPointF( 4.0, 7.9 ) << QPointF( 5.0, 7.1 ); + + points.translate( 0.0, i * 2.0 ); + + curve->setSamples( points ); + curve->attach( &plot ); + } + + plot.resize( 600, 400 ); + plot.show(); + + return a.exec(); +} diff --git a/ThirdParty/Qwt/playground/symbols/symbols.pro b/ThirdParty/Qwt/playground/symbols/symbols.pro new file mode 100644 index 0000000000..35f6d54501 --- /dev/null +++ b/ThirdParty/Qwt/playground/symbols/symbols.pro @@ -0,0 +1,16 @@ +################################################################ +# Qwt Widget Library +# Copyright (C) 1997 Josef Wilgen +# Copyright (C) 2002 Uwe Rathmann +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the Qwt License, Version 1.0 +################################################################ + +include( $${PWD}/../playground.pri ) + +TARGET = symbols + +SOURCES = \ + symbols.cpp + diff --git a/ThirdParty/Qwt/playground/timescale/main.cpp b/ThirdParty/Qwt/playground/timescale/main.cpp new file mode 100644 index 0000000000..14321f7561 --- /dev/null +++ b/ThirdParty/Qwt/playground/timescale/main.cpp @@ -0,0 +1,13 @@ +#include +#include "mainwindow.h" + +int main( int argc, char **argv ) +{ + QApplication a( argc, argv ); + + MainWindow window; + window.resize( 800, 600 ); + window.show(); + + return a.exec(); +} diff --git a/ThirdParty/Qwt/playground/timescale/mainwindow.cpp b/ThirdParty/Qwt/playground/timescale/mainwindow.cpp new file mode 100644 index 0000000000..7674728fc0 --- /dev/null +++ b/ThirdParty/Qwt/playground/timescale/mainwindow.cpp @@ -0,0 +1,58 @@ +#include "plot.h" +#include "panel.h" +#include "mainwindow.h" +#include +#include +#include + +MainWindow::MainWindow( QWidget *parent ): + QMainWindow( parent ) +{ + Settings settings; +#if 1 + settings.startDateTime = QDateTime( QDate( 2012, 10, 27 ), QTime( 18, 5, 0, 0 ) ); + settings.endDateTime = QDateTime( QDate( 2012, 10, 28 ), QTime( 12, 12, 0, 0 ) ); +#else + settings.startDateTime = QDateTime( QDate( 2011, 5, 3 ), QTime( 0, 6, 0, 0 ) ); + settings.endDateTime = QDateTime( QDate( 2012, 3, 10 ), QTime( 0, 5, 0, 0 ) ); +#endif + settings.maxMajorSteps = 10; + settings.maxMinorSteps = 8; + settings.maxWeeks = -1; + + d_plot = new Plot(); + d_panel = new Panel(); + d_panel->setSettings( settings ); + + QWidget *box = new QWidget( this ); + + QHBoxLayout *layout = new QHBoxLayout( box ); + layout->addWidget( d_plot, 10 ); + layout->addWidget( d_panel ); + + setCentralWidget( box ); + + updatePlot(); + + connect( d_panel, SIGNAL( edited() ), SLOT( updatePlot() ) ); + connect( d_plot->axisWidget( QwtPlot::yLeft ), + SIGNAL( scaleDivChanged() ), SLOT( updatePanel() ) ); +} + +void MainWindow::updatePlot() +{ + d_plot->blockSignals( true ); + d_plot->applySettings( d_panel->settings() ); + d_plot->blockSignals( false ); +} + +void MainWindow::updatePanel() +{ + const QwtScaleDiv scaleDiv = d_plot->axisScaleDiv( QwtPlot::yLeft ); + + Settings settings = d_panel->settings(); + settings.startDateTime = QwtDate::toDateTime( scaleDiv.lowerBound(), Qt::LocalTime ); + settings.endDateTime = QwtDate::toDateTime( scaleDiv.upperBound(), Qt::LocalTime ); + + d_panel->setSettings( settings ); +} diff --git a/ThirdParty/Qwt/playground/timescale/mainwindow.h b/ThirdParty/Qwt/playground/timescale/mainwindow.h new file mode 100644 index 0000000000..d8cef9671e --- /dev/null +++ b/ThirdParty/Qwt/playground/timescale/mainwindow.h @@ -0,0 +1,20 @@ +#include + +class Plot; +class Panel; + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + MainWindow( QWidget *parent = 0 ); + +private Q_SLOTS: + void updatePlot(); + void updatePanel(); + +private: + Plot *d_plot; + Panel *d_panel; +}; diff --git a/ThirdParty/Qwt/playground/timescale/panel.cpp b/ThirdParty/Qwt/playground/timescale/panel.cpp new file mode 100644 index 0000000000..65c97e3670 --- /dev/null +++ b/ThirdParty/Qwt/playground/timescale/panel.cpp @@ -0,0 +1,95 @@ +#include "panel.h" +#include "settings.h" +#include +#include +#include +#include +#include + +Panel::Panel( QWidget *parent ): + QWidget( parent ) +{ + // create widgets + + d_startDateTime = new QDateTimeEdit(); + d_startDateTime->setDisplayFormat( "M/d/yyyy h:mm AP :zzz" ); + d_startDateTime->setCalendarPopup( true ); + + d_endDateTime = new QDateTimeEdit(); + d_endDateTime->setDisplayFormat( "M/d/yyyy h:mm AP :zzz" ); + d_endDateTime->setCalendarPopup( true ); + + d_maxMajorSteps = new QSpinBox(); + d_maxMajorSteps->setRange( 0, 50 ); + + d_maxMinorSteps = new QSpinBox(); + d_maxMinorSteps->setRange( 0, 50 ); + + d_maxWeeks = new QSpinBox(); + d_maxWeeks->setRange( -1, 100 ); + d_maxWeeks->setSpecialValueText( "Disabled" ); + + // layout + + QGridLayout *layout = new QGridLayout( this ); + layout->setAlignment( Qt::AlignLeft | Qt::AlignTop ); + + int row = 0; + layout->addWidget( new QLabel( "From" ), row, 0 ); + layout->addWidget( d_startDateTime, row, 1 ); + + row++; + layout->addWidget( new QLabel( "To" ), row, 0 ); + layout->addWidget( d_endDateTime, row, 1 ); + + row++; + layout->addWidget( new QLabel( "Max. Major Steps" ), row, 0 ); + layout->addWidget( d_maxMajorSteps, row, 1 ); + + row++; + layout->addWidget( new QLabel( "Max. Minor Steps" ), row, 0 ); + layout->addWidget( d_maxMinorSteps, row, 1 ); + + row++; + layout->addWidget( new QLabel( "Max Weeks" ), row, 0 ); + layout->addWidget( d_maxWeeks, row, 1 ); + + connect( d_startDateTime, + SIGNAL( dateTimeChanged( const QDateTime & ) ), SIGNAL( edited() ) ); + connect( d_endDateTime, + SIGNAL( dateTimeChanged( const QDateTime & ) ), SIGNAL( edited() ) ); + connect( d_maxMajorSteps, + SIGNAL( valueChanged( int ) ), SIGNAL( edited() ) ); + connect( d_maxMinorSteps, + SIGNAL( valueChanged( int ) ), SIGNAL( edited() ) ); + connect( d_maxWeeks, + SIGNAL( valueChanged( int ) ), SIGNAL( edited() ) ); +} + +void Panel::setSettings( const Settings &settings ) +{ + blockSignals( true ); + + d_startDateTime->setDateTime( settings.startDateTime ); + d_endDateTime->setDateTime( settings.endDateTime ); + + d_maxMajorSteps->setValue( settings.maxMajorSteps ); + d_maxMinorSteps->setValue( settings.maxMinorSteps ); + d_maxWeeks->setValue( settings.maxWeeks ); + + blockSignals( false ); +} + +Settings Panel::settings() const +{ + Settings settings; + + settings.startDateTime = d_startDateTime->dateTime(); + settings.endDateTime = d_endDateTime->dateTime(); + + settings.maxMajorSteps = d_maxMajorSteps->value(); + settings.maxMinorSteps = d_maxMinorSteps->value(); + settings.maxWeeks = d_maxWeeks->value(); + + return settings; +} diff --git a/ThirdParty/Qwt/playground/timescale/panel.h b/ThirdParty/Qwt/playground/timescale/panel.h new file mode 100644 index 0000000000..458dfce9e3 --- /dev/null +++ b/ThirdParty/Qwt/playground/timescale/panel.h @@ -0,0 +1,32 @@ +#ifndef _PANEL_ +#define _PANEL_ + +#include "settings.h" +#include + +class QDateTimeEdit; +class QSpinBox; + +class Panel: public QWidget +{ + Q_OBJECT + +public: + Panel( QWidget *parent = NULL ); + + void setSettings( const Settings &); + Settings settings() const; + +Q_SIGNALS: + void edited(); + +private: + QDateTimeEdit* d_startDateTime; + QDateTimeEdit* d_endDateTime; + + QSpinBox *d_maxMajorSteps; + QSpinBox *d_maxMinorSteps; + QSpinBox *d_maxWeeks; +}; + +#endif diff --git a/ThirdParty/Qwt/playground/timescale/plot.cpp b/ThirdParty/Qwt/playground/timescale/plot.cpp new file mode 100644 index 0000000000..92c2d88764 --- /dev/null +++ b/ThirdParty/Qwt/playground/timescale/plot.cpp @@ -0,0 +1,90 @@ +#include "plot.h" +#include "settings.h" +#include +#include +#include +#include +#include +#include +#include + +Plot::Plot( QWidget *parent ): + QwtPlot( parent ) +{ + setAutoFillBackground( true ); + setPalette( Qt::darkGray ); + setCanvasBackground( Qt::white ); + + plotLayout()->setAlignCanvasToScales( true ); + + initAxis( QwtPlot::yLeft, "Local Time", Qt::LocalTime ); + initAxis( QwtPlot::yRight, + "Coordinated Universal Time ( UTC )", Qt::UTC ); + + QwtPlotPanner *panner = new QwtPlotPanner( canvas() ); + QwtPlotMagnifier *magnifier = new QwtPlotMagnifier( canvas() ); + + for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ ) + { + const bool on = axis == QwtPlot::yLeft || + axis == QwtPlot::yRight; + + enableAxis( axis, on ); + panner->setAxisEnabled( axis, on ); + magnifier->setAxisEnabled( axis, on ); + } + + QwtPlotGrid *grid = new QwtPlotGrid(); + grid->setMajorPen( Qt::black, 0, Qt::SolidLine ); + grid->setMinorPen( Qt::gray, 0 , Qt::SolidLine ); + grid->enableX( false ); + grid->enableXMin( false ); + grid->enableY( true ); + grid->enableYMin( true ); + + grid->attach( this ); +} + +void Plot::initAxis( int axis, + const QString& title, Qt::TimeSpec timeSpec ) +{ + setAxisTitle( axis, title ); + + QwtDateScaleDraw *scaleDraw = new QwtDateScaleDraw( timeSpec ); + QwtDateScaleEngine *scaleEngine = new QwtDateScaleEngine( timeSpec ); + +#if 0 + if ( timeSpec == Qt::LocalTime ) + { + scaleDraw->setTimeSpec( Qt::OffsetFromUTC ); + scaleDraw->setUtcOffset( 10 ); + + scaleEngine->setTimeSpec( Qt::OffsetFromUTC ); + scaleEngine->setUtcOffset( 10 ); + } +#endif + setAxisScaleDraw( axis, scaleDraw ); + setAxisScaleEngine( axis, scaleEngine ); +} + +void Plot::applySettings( const Settings &settings ) +{ + applyAxisSettings( QwtPlot::yLeft, settings ); + applyAxisSettings( QwtPlot::yRight, settings ); + + replot(); +} + +void Plot::applyAxisSettings( int axis, const Settings &settings ) +{ + QwtDateScaleEngine *scaleEngine = + static_cast( axisScaleEngine( axis ) ); + + scaleEngine->setMaxWeeks( settings.maxWeeks ); + setAxisMaxMinor( axis, settings.maxMinorSteps ); + setAxisMaxMajor( axis, settings.maxMajorSteps ); + + + setAxisScale( axis, QwtDate::toDouble( settings.startDateTime ), + QwtDate::toDouble( settings.endDateTime ) ); +} diff --git a/ThirdParty/Qwt/playground/timescale/plot.h b/ThirdParty/Qwt/playground/timescale/plot.h new file mode 100644 index 0000000000..d92b9a6763 --- /dev/null +++ b/ThirdParty/Qwt/playground/timescale/plot.h @@ -0,0 +1,23 @@ +#ifndef _PLOT_H_ +#define _PLOT_H_ + +#include + +class Settings; + +class Plot: public QwtPlot +{ + Q_OBJECT + +public: + Plot( QWidget *parent = NULL ); + +public Q_SLOTS: + void applySettings( const Settings & ); + +private: + void initAxis( int axis, const QString& title, Qt::TimeSpec ); + void applyAxisSettings( int axis, const Settings & ); +}; + +#endif diff --git a/ThirdParty/Qwt/playground/timescale/settings.h b/ThirdParty/Qwt/playground/timescale/settings.h new file mode 100644 index 0000000000..524190faff --- /dev/null +++ b/ThirdParty/Qwt/playground/timescale/settings.h @@ -0,0 +1,25 @@ +#ifndef _SETTINGS_H_ +#define _SETTINGS_H_ 1 + +#include + +class Settings +{ +public: + Settings(): + maxMajorSteps( 10 ), + maxMinorSteps( 5 ), + maxWeeks( -1 ) + { + }; + + QDateTime startDateTime; + QDateTime endDateTime; + + int maxMajorSteps; + int maxMinorSteps; + + int maxWeeks; +}; + +#endif diff --git a/ThirdParty/Qwt/playground/timescale/timescale.pro b/ThirdParty/Qwt/playground/timescale/timescale.pro new file mode 100644 index 0000000000..fae1e7f6f7 --- /dev/null +++ b/ThirdParty/Qwt/playground/timescale/timescale.pro @@ -0,0 +1,24 @@ +################################################################ +# Qwt Widget Library +# Copyright (C) 1997 Josef Wilgen +# Copyright (C) 2002 Uwe Rathmann +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the Qwt License, Version 1.0 +################################################################ + +include( $${PWD}/../playground.pri ) + +TARGET = timescale + +HEADERS = \ + panel.h \ + plot.h \ + mainwindow.h + +SOURCES = \ + panel.cpp \ + plot.cpp \ + mainwindow.cpp \ + main.cpp + diff --git a/ThirdParty/Qwt/qwt.prf b/ThirdParty/Qwt/qwt.prf new file mode 100644 index 0000000000..ea2737b6f6 --- /dev/null +++ b/ThirdParty/Qwt/qwt.prf @@ -0,0 +1,38 @@ +################################################################ +# Qwt Widget Library +# Copyright (C) 1997 Josef Wilgen +# Copyright (C) 2002 Uwe Rathmann +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the Qwt License, Version 1.0 +################################################################ + +include ( ./qwtconfig.pri ) +include ( ./qwtfunctions.pri ) + +contains(QWT_CONFIG, QwtDll) { + + DEFINES *= QWT_DLL +} + +contains(QWT_CONFIG, QwtSvg) { + + QT *= svg +} +else { + + DEFINES *= QWT_NO_SVG +} + +contains(QWT_CONFIG, QwtFramework) { + + INCLUDEPATH *= $${QWT_INSTALL_LIBS}/qwt.framework/Headers + LIBS *= -F$${QWT_INSTALL_LIBS} +} +else { + + INCLUDEPATH *= $${QWT_INSTALL_HEADERS} + LIBS *= -L$${QWT_INSTALL_LIBS} +} + +qwtAddLibrary(qwt) diff --git a/ThirdParty/Qwt/qwt.pro b/ThirdParty/Qwt/qwt.pro new file mode 100644 index 0000000000..04b7443a7e --- /dev/null +++ b/ThirdParty/Qwt/qwt.pro @@ -0,0 +1,36 @@ +################################################################ +# Qwt Widget Library +# Copyright (C) 1997 Josef Wilgen +# Copyright (C) 2002 Uwe Rathmann +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the Qwt License, Version 1.0 +################################################################ + +include( qwtconfig.pri ) + +TEMPLATE = subdirs +CONFIG += ordered + +SUBDIRS = \ + src \ + textengines \ + doc + +contains(QWT_CONFIG, QwtDesigner ) { + SUBDIRS += designer +} + +contains(QWT_CONFIG, QwtExamples ) { + SUBDIRS += examples +} + +contains(QWT_CONFIG, QwtPlayground ) { + SUBDIRS += playground +} + +qwtspec.files = qwtconfig.pri qwtfunctions.pri qwt.prf +qwtspec.path = $${QWT_INSTALL_FEATURES} + +INSTALLS += qwtspec + diff --git a/ThirdParty/Qwt/qwtbuild.pri b/ThirdParty/Qwt/qwtbuild.pri new file mode 100644 index 0000000000..8eba3b67d3 --- /dev/null +++ b/ThirdParty/Qwt/qwtbuild.pri @@ -0,0 +1,86 @@ +################################################################ +# Qwt Widget Library +# Copyright (C) 1997 Josef Wilgen +# Copyright (C) 2002 Uwe Rathmann +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the Qwt License, Version 1.0 +################################################################ + +###################################################################### +# qmake internal options +###################################################################### + +CONFIG += qt +CONFIG += warn_on +CONFIG += no_keywords +CONFIG += silent + +###################################################################### +# release/debug mode +###################################################################### + +win32 { + # On Windows you can't mix release and debug libraries. + # The designer is built in release mode. If you like to use it + # you need a release version. For your own application development you + # might need a debug version. + # Enable debug_and_release + build_all if you want to build both. + + CONFIG += debug_and_release + CONFIG += build_all +} +else { + + CONFIG += release + + VER_MAJ = $${QWT_VER_MAJ} + VER_MIN = $${QWT_VER_MIN} + VER_PAT = $${QWT_VER_PAT} + VERSION = $${QWT_VERSION} +} + +linux-g++ | linux-g++-64 { + #CONFIG += separate_debug_info + #QMAKE_CXXFLAGS *= -Wfloat-equal + #QMAKE_CXXFLAGS *= -Wshadow + #QMAKE_CXXFLAGS *= -Wpointer-arith + #QMAKE_CXXFLAGS *= -Wconversion + #QMAKE_CXXFLAGS *= -Wsign-compare + #QMAKE_CXXFLAGS *= -Wsign-conversion + #QMAKE_CXXFLAGS *= -Wlogical-op + #QMAKE_CXXFLAGS *= -Werror=format-security + #QMAKE_CXXFLAGS *= -std=c++11 + + # when using the gold linker ( Qt < 4.8 ) - might be + # necessary on non linux systems too + #QMAKE_LFLAGS += -lrt +} + +###################################################################### +# paths for building qwt +###################################################################### + +MOC_DIR = moc +RCC_DIR = resources + +!debug_and_release { + + # in case of debug_and_release object files + # are built in the release and debug subdirectories + OBJECTS_DIR = obj +} + +unix { + + exists( $${QMAKE_LIBDIR_QT}/libqwt.* ) { + + # On some Linux distributions the Qwt libraries are installed + # in the same directory as the Qt libraries. Unfortunately + # qmake always adds QMAKE_LIBDIR_QT at the beginning of the + # linker path, so that the installed libraries will be + # used instead of the local ones. + + error( "local build will conflict with $${QMAKE_LIBDIR_QT}/libqwt.*" ) + } +} diff --git a/ThirdParty/Qwt/qwtconfig.pri b/ThirdParty/Qwt/qwtconfig.pri new file mode 100644 index 0000000000..2c297a0f8f --- /dev/null +++ b/ThirdParty/Qwt/qwtconfig.pri @@ -0,0 +1,163 @@ +################################################################ +# Qwt Widget Library +# Copyright (C) 1997 Josef Wilgen +# Copyright (C) 2002 Uwe Rathmann +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the Qwt License, Version 1.0 +################################################################ + +QWT_VER_MAJ = 6 +QWT_VER_MIN = 1 +QWT_VER_PAT = 0 +QWT_VERSION = $${QWT_VER_MAJ}.$${QWT_VER_MIN}.$${QWT_VER_PAT} + +###################################################################### +# Install paths +###################################################################### + +QWT_INSTALL_PREFIX = $$[QT_INSTALL_PREFIX] + +unix { + QWT_INSTALL_PREFIX = /usr/local/qwt-$$QWT_VERSION +} + +win32 { + QWT_INSTALL_PREFIX = C:/Qwt-$$QWT_VERSION +} + +QWT_INSTALL_DOCS = $${QWT_INSTALL_PREFIX}/doc +QWT_INSTALL_HEADERS = $${QWT_INSTALL_PREFIX}/include +QWT_INSTALL_LIBS = $${QWT_INSTALL_PREFIX}/lib + +###################################################################### +# Designer plugin +# creator/designer load designer plugins from certain default +# directories ( f.e the path below QT_INSTALL_PREFIX ) and the +# directories listed in the QT_PLUGIN_PATH environment variable. +# When using the path below QWT_INSTALL_PREFIX you need to +# add $${QWT_INSTALL_PREFIX}/plugins to QT_PLUGIN_PATH in the +# runtime environment of designer/creator. +###################################################################### + +QWT_INSTALL_PLUGINS = $${QWT_INSTALL_PREFIX}/plugins/designer + +# linux distributors often organize the Qt installation +# their way and QT_INSTALL_PREFIX doesn't offer a good +# path. Also QT_INSTALL_PREFIX is only one of the default +# search paths of the designer - not the Qt creator + +#QWT_INSTALL_PLUGINS = $$[QT_INSTALL_PREFIX]/plugins/designer + +###################################################################### +# Features +# When building a Qwt application with qmake you might want to load +# the compiler/linker flags, that are required to build a Qwt application +# from qwt.prf. Therefore all you need to do is to add "CONFIG += qwt" +# to your project file and take care, that qwt.prf can be found by qmake. +# ( see http://doc.trolltech.com/4.7/qmake-advanced-usage.html#adding-new-configuration-features ) +# I recommend not to install the Qwt features together with the +# Qt features, because you will have to reinstall the Qwt features, +# with every Qt upgrade. +###################################################################### + +QWT_INSTALL_FEATURES = $${QWT_INSTALL_PREFIX}/features +# QWT_INSTALL_FEATURES = $$[QT_INSTALL_PREFIX]/features + +###################################################################### +# Build the static/shared libraries. +# If QwtDll is enabled, a shared library is built, otherwise +# it will be a static library. +###################################################################### + +QWT_CONFIG += QwtDll + +###################################################################### +# QwtPlot enables all classes, that are needed to use the QwtPlot +# widget. +###################################################################### + +QWT_CONFIG += QwtPlot + +###################################################################### +# QwtWidgets enables all classes, that are needed to use the all other +# widgets (sliders, dials, ...), beside QwtPlot. +###################################################################### + +QWT_CONFIG += QwtWidgets + +###################################################################### +# If you want to display svg images on the plot canvas, or +# export a plot to a SVG document +###################################################################### + +QWT_CONFIG += QwtSvg + +###################################################################### +# If you want to use a OpenGL plot canvas +###################################################################### + +QWT_CONFIG += QwtOpenGL + +###################################################################### +# You can use the MathML renderer of the Qt solutions package to +# enable MathML support in Qwt. Because of license implications +# the ( modified ) code of the MML Widget solution is included and +# linked together with the QwtMathMLTextEngine into an own library. +# To use it you will have to add "CONFIG += qwtmathml" +# to your qmake project file. +###################################################################### + +#QWT_CONFIG += QwtMathML + +###################################################################### +# If you want to build the Qwt designer plugin, +# enable the line below. +# Otherwise you have to build it from the designer directory. +###################################################################### + +QWT_CONFIG += QwtDesigner + +###################################################################### +# Compile all Qwt classes into the designer plugin instead +# of linking it against the shared Qwt library. Has no effect +# when QwtDesigner or QwtDll are not both enabled. +# +# On systems where rpath is supported ( all Unixoids ) the +# location of the installed Qwt library is compiled into the plugin, +# but on Windows it might be easier to have a self contained +# plugin to avoid any hassle with configuring the runtime +# environment of the designer/creator. +###################################################################### + +win32 { + QWT_CONFIG += QwtDesignerSelfContained +} + +###################################################################### +# If you want to auto build the examples, enable the line below +# Otherwise you have to build them from the examples directory. +###################################################################### + +#QWT_CONFIG += QwtExamples + +###################################################################### +# The playground is primarily intended for the Qwt development +# to explore and test new features. Nevertheless you might find +# ideas or code snippets that help for application development +# If you want to auto build the applications in playground, enable +# the line below. +# Otherwise you have to build them from the playground directory. +###################################################################### + +#QWT_CONFIG += QwtPlayground + +###################################################################### +# When Qt has been built as framework qmake wants +# to link frameworks instead of regular libs +###################################################################### + +macx:!static:CONFIG(qt_framework, qt_framework|qt_no_framework) { + + QWT_CONFIG += QwtFramework +} diff --git a/ThirdParty/Qwt/qwtfunctions.pri b/ThirdParty/Qwt/qwtfunctions.pri new file mode 100644 index 0000000000..000e7d4aea --- /dev/null +++ b/ThirdParty/Qwt/qwtfunctions.pri @@ -0,0 +1,71 @@ +################################################################ +# Qwt Widget Library +# Copyright (C) 1997 Josef Wilgen +# Copyright (C) 2002 Uwe Rathmann +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the Qwt License, Version 1.0 +################################################################ + +# Copied and modified from qt_functions.prf + +defineReplace(qwtLibraryTarget) { + + unset(LIBRARY_NAME) + LIBRARY_NAME = $$1 + + mac:contains(QWT_CONFIG, QwtFramework) { + + QMAKE_FRAMEWORK_BUNDLE_NAME = $$LIBRARY_NAME + export(QMAKE_FRAMEWORK_BUNDLE_NAME) + } + + contains(TEMPLATE, .*lib):CONFIG(debug, debug|release) { + + !debug_and_release|build_pass { + + mac:RET = $$member(LIBRARY_NAME, 0)_debug + win32:RET = $$member(LIBRARY_NAME, 0)d + } + } + + isEmpty(RET):RET = $$LIBRARY_NAME + return($$RET) +} + +defineTest(qwtAddLibrary) { + + LIB_NAME = $$1 + + unset(LINKAGE) + + mac:contains(QWT_CONFIG, QwtFramework) { + + LINKAGE = -framework $${LIB_NAME}$${QT_LIBINFIX} + } + + isEmpty(LINKAGE) { + + if(!debug_and_release|build_pass):CONFIG(debug, debug|release) { + + mac:LINKAGE = -l$${LIB_NAME}$${QT_LIBINFIX}_debug + win32:LINKAGE = -l$${LIB_NAME}$${QT_LIBINFIX}d + } + } + + isEmpty(LINKAGE) { + + LINKAGE = -l$${LIB_NAME}$${QT_LIBINFIX} + } + + !isEmpty(QMAKE_LSB) { + + QMAKE_LFLAGS *= --lsb-shared-libs=$${LIB_NAME}$${QT_LIBINFIX} + } + + LIBS += $$LINKAGE + export(LIBS) + export(QMAKE_LFLAGS) + + return(true) +} diff --git a/ThirdParty/Qwt/src/CMakeLists.txt b/ThirdParty/Qwt/src/CMakeLists.txt new file mode 100644 index 0000000000..8844512282 --- /dev/null +++ b/ThirdParty/Qwt/src/CMakeLists.txt @@ -0,0 +1,282 @@ +cmake_minimum_required(VERSION 2.8) + +project(Qwt) + +if (MSVC) + # Disable some annoying warnings (relative to warning level 3) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4267") +endif() + +find_package(Qt4 COMPONENTS QtCore QtGui QtOpenGL qtmain REQUIRED) +include(${QT_USE_FILE}) + + +# Adapted from src.pri file in Qwt's source catalog for Qwt 6.1.0 +# Compiles static library +# Some bits removed (at least SVG) + +add_definitions(-DQWT_NO_SVG) + +set(HEADER_FILES ${HEADER_FILES} +qwt.h +qwt_abstract_scale_draw.h +qwt_clipper.h +qwt_color_map.h +qwt_compat.h +qwt_column_symbol.h +qwt_date.h +qwt_date_scale_draw.h +qwt_date_scale_engine.h +qwt_dyngrid_layout.h +qwt_global.h +qwt_graphic.h +qwt_interval.h +qwt_interval_symbol.h +qwt_math.h +qwt_magnifier.h +qwt_null_paintdevice.h +qwt_painter.h +qwt_painter_command.h +qwt_panner.h +qwt_picker.h +qwt_picker_machine.h +qwt_pixel_matrix.h +qwt_point_3d.h +qwt_point_polar.h +qwt_round_scale_draw.h +qwt_scale_div.h +qwt_scale_draw.h +qwt_scale_engine.h +qwt_scale_map.h +qwt_spline.h +qwt_symbol.h +qwt_system_clock.h +qwt_text_engine.h +qwt_text_label.h +qwt_text.h +qwt_transform.h +qwt_widget_overlay.h +) + +set(SOURCE_FILES ${SOURCE_FILES} +qwt_abstract_scale_draw.cpp +qwt_clipper.cpp +qwt_color_map.cpp +qwt_column_symbol.cpp +qwt_date.cpp +qwt_date_scale_draw.cpp +qwt_date_scale_engine.cpp +qwt_dyngrid_layout.cpp +qwt_event_pattern.cpp +qwt_graphic.cpp +qwt_interval.cpp +qwt_interval_symbol.cpp +qwt_math.cpp +qwt_magnifier.cpp +qwt_null_paintdevice.cpp +qwt_painter.cpp +qwt_painter_command.cpp +qwt_panner.cpp +qwt_picker.cpp +qwt_picker_machine.cpp +qwt_pixel_matrix.cpp +qwt_point_3d.cpp +qwt_point_polar.cpp +qwt_round_scale_draw.cpp +qwt_scale_div.cpp +qwt_scale_draw.cpp +qwt_scale_map.cpp +qwt_spline.cpp +qwt_scale_engine.cpp +qwt_symbol.cpp +qwt_system_clock.cpp +qwt_text_engine.cpp +qwt_text_label.cpp +qwt_text.cpp +qwt_transform.cpp +qwt_widget_overlay.cpp +) + + +# QwtPlot +set(HEADER_FILES ${HEADER_FILES} +qwt_curve_fitter.h +qwt_event_pattern.h +qwt_abstract_legend.h +qwt_legend.h +qwt_legend_data.h +qwt_legend_label.h +qwt_plot.h +qwt_plot_renderer.h +qwt_plot_curve.h +qwt_plot_dict.h +qwt_plot_directpainter.h +qwt_plot_grid.h +qwt_plot_histogram.h +qwt_plot_item.h +qwt_plot_abstract_barchart.h +qwt_plot_barchart.h +qwt_plot_multi_barchart.h +qwt_plot_intervalcurve.h +qwt_plot_tradingcurve.h +qwt_plot_layout.h +qwt_plot_marker.h +qwt_plot_zoneitem.h +qwt_plot_textlabel.h +qwt_plot_rasteritem.h +qwt_plot_spectrogram.h +qwt_plot_spectrocurve.h +qwt_plot_scaleitem.h +qwt_plot_legenditem.h +qwt_plot_seriesitem.h +qwt_plot_shapeitem.h +qwt_plot_canvas.h +qwt_plot_panner.h +qwt_plot_picker.h +qwt_plot_zoomer.h +qwt_plot_magnifier.h +qwt_plot_rescaler.h +qwt_point_mapper.h +qwt_raster_data.h +qwt_matrix_raster_data.h +qwt_sampling_thread.h +qwt_samples.h +qwt_series_data.h +qwt_series_store.h +qwt_point_data.h +qwt_scale_widget.h +) + +set(SOURCE_FILES ${SOURCE_FILES} +qwt_curve_fitter.cpp +qwt_abstract_legend.cpp +qwt_legend.cpp +qwt_legend_data.cpp +qwt_legend_label.cpp +qwt_plot.cpp +qwt_plot_renderer.cpp +qwt_plot_xml.cpp +qwt_plot_axis.cpp +qwt_plot_curve.cpp +qwt_plot_dict.cpp +qwt_plot_directpainter.cpp +qwt_plot_grid.cpp +qwt_plot_histogram.cpp +qwt_plot_item.cpp +qwt_plot_abstract_barchart.cpp +qwt_plot_barchart.cpp +qwt_plot_multi_barchart.cpp +qwt_plot_intervalcurve.cpp +qwt_plot_zoneitem.cpp +qwt_plot_tradingcurve.cpp +qwt_plot_spectrogram.cpp +qwt_plot_spectrocurve.cpp +qwt_plot_scaleitem.cpp +qwt_plot_legenditem.cpp +qwt_plot_seriesitem.cpp +qwt_plot_shapeitem.cpp +qwt_plot_marker.cpp +qwt_plot_textlabel.cpp +qwt_plot_layout.cpp +qwt_plot_canvas.cpp +qwt_plot_panner.cpp +qwt_plot_rasteritem.cpp +qwt_plot_picker.cpp +qwt_plot_zoomer.cpp +qwt_plot_magnifier.cpp +qwt_plot_rescaler.cpp +qwt_point_mapper.cpp +qwt_raster_data.cpp +qwt_matrix_raster_data.cpp +qwt_sampling_thread.cpp +qwt_series_data.cpp +qwt_point_data.cpp +qwt_scale_widget.cpp +) + + +# QwtOpenGL +set(HEADER_FILES ${HEADER_FILES} +qwt_plot_glcanvas.h +) + +set(SOURCE_FILES ${SOURCE_FILES} +qwt_plot_glcanvas.cpp +) + + +#QwtWidgets +set(HEADER_FILES ${HEADER_FILES} +qwt_abstract_slider.h +qwt_abstract_scale.h +qwt_arrow_button.h +qwt_analog_clock.h +qwt_compass.h +qwt_compass_rose.h +qwt_counter.h +qwt_dial.h +qwt_dial_needle.h +qwt_knob.h +qwt_slider.h +qwt_thermo.h +qwt_wheel.h +) + +set(SOURCE_FILES ${SOURCE_FILES} +qwt_abstract_slider.cpp +qwt_abstract_scale.cpp +qwt_arrow_button.cpp +qwt_analog_clock.cpp +qwt_compass.cpp +qwt_compass_rose.cpp +qwt_counter.cpp +qwt_dial.cpp +qwt_dial_needle.cpp +qwt_knob.cpp +qwt_slider.cpp +qwt_thermo.cpp +qwt_wheel.cpp +) + + + +# Header files containing Q_OBJECT declarations +set(MOC_HEADER_FILES +qwt_abstract_legend.h +qwt_abstract_scale.h +qwt_abstract_slider.h +qwt_analog_clock.h +qwt_compass.h +qwt_counter.h +qwt_dial.h +qwt_dyngrid_layout.h +qwt_knob.h +qwt_legend.h +qwt_legend_label.h +qwt_magnifier.h +qwt_panner.h +qwt_picker.h +qwt_plot.h +qwt_plot_canvas.h +qwt_plot_glcanvas.h +qwt_plot_magnifier.h +qwt_plot_panner.h +qwt_plot_picker.h +qwt_plot_renderer.h +qwt_plot_zoomer.h +qwt_sampling_thread.h +qwt_scale_widget.h +qwt_slider.h +qwt_text_label.h +qwt_thermo.h +qwt_wheel.h +) + + + +set(MOC_SOURCE_FILES) +qt4_wrap_cpp(MOC_SOURCE_FILES ${MOC_HEADER_FILES} ) + + +add_library(${PROJECT_NAME} ${HEADER_FILES} ${SOURCE_FILES} ${MOC_SOURCE_FILES}) + diff --git a/ThirdParty/Qwt/src/qwt.h b/ThirdParty/Qwt/src/qwt.h new file mode 100644 index 0000000000..37494933ee --- /dev/null +++ b/ThirdParty/Qwt/src/qwt.h @@ -0,0 +1,22 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#ifndef QWT_H +#define QWT_H + +#include "qwt_global.h" + +/*! + Some constants for use within Qwt. +*/ +namespace Qwt +{ +}; + +#endif diff --git a/ThirdParty/Qwt/src/qwt_abstract_legend.cpp b/ThirdParty/Qwt/src/qwt_abstract_legend.cpp new file mode 100644 index 0000000000..4ecaac61d9 --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_abstract_legend.cpp @@ -0,0 +1,38 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#include "qwt_abstract_legend.h" + +/*! + Constructor + + \param parent Parent widget +*/ +QwtAbstractLegend::QwtAbstractLegend( QWidget *parent ): + QFrame( parent ) +{ +} + +//! Destructor +QwtAbstractLegend::~QwtAbstractLegend() +{ +} + +/*! + Return the extent, that is needed for elements to scroll + the legend ( usually scrollbars ), + + \param orientation Orientation + \return Extent of the corresponding scroll element +*/ +int QwtAbstractLegend::scrollExtent( Qt::Orientation orientation ) const +{ + Q_UNUSED( orientation ); + return 0; +} diff --git a/ThirdParty/Qwt/src/qwt_abstract_legend.h b/ThirdParty/Qwt/src/qwt_abstract_legend.h new file mode 100644 index 0000000000..18bd3f4b96 --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_abstract_legend.h @@ -0,0 +1,71 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#ifndef QWT_ABSTRACT_LEGEND_H +#define QWT_ABSTRACT_LEGEND_H + +#include "qwt_global.h" +#include "qwt_legend_data.h" +#include +#include + +class QVariant; + +/*! + \brief Abstract base class for legend widgets + + Legends, that need to be under control of the QwtPlot layout system + need to be derived from QwtAbstractLegend. + + \note Other type of legends can be implemented by connecting to + the QwtPlot::legendDataChanged() signal. But as these legends + are unknown to the plot layout system the layout code + ( on screen and for QwtPlotRenderer ) need to be organized + in application code. + + \sa QwtLegend + */ +class QWT_EXPORT QwtAbstractLegend : public QFrame +{ + Q_OBJECT + +public: + explicit QwtAbstractLegend( QWidget *parent = NULL ); + virtual ~QwtAbstractLegend(); + + /*! + Render the legend into a given rectangle. + + \param painter Painter + \param rect Bounding rectangle + \param fillBackground When true, fill rect with the widget background + + \sa renderLegend() is used by QwtPlotRenderer + */ + virtual void renderLegend( QPainter *painter, + const QRectF &rect, bool fillBackground ) const = 0; + + //! \return True, when no plot item is inserted + virtual bool isEmpty() const = 0; + + virtual int scrollExtent( Qt::Orientation ) const; + +public Q_SLOTS: + + /*! + \brief Update the entries for a plot item + + \param itemInfo Info about an item + \param data List of legend entry attributes for the item + */ + virtual void updateLegend( const QVariant &itemInfo, + const QList &data ) = 0; +}; + +#endif diff --git a/ThirdParty/Qwt/src/qwt_abstract_scale.cpp b/ThirdParty/Qwt/src/qwt_abstract_scale.cpp new file mode 100644 index 0000000000..3018b854ea --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_abstract_scale.cpp @@ -0,0 +1,449 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#include "qwt_abstract_scale.h" +#include "qwt_scale_engine.h" +#include "qwt_scale_draw.h" +#include "qwt_scale_div.h" +#include "qwt_scale_map.h" +#include "qwt_interval.h" + +class QwtAbstractScale::PrivateData +{ +public: + PrivateData(): + maxMajor( 5 ), + maxMinor( 3 ), + stepSize( 0.0 ) + { + scaleEngine = new QwtLinearScaleEngine(); + scaleDraw = new QwtScaleDraw(); + } + + ~PrivateData() + { + delete scaleEngine; + delete scaleDraw; + } + + QwtScaleEngine *scaleEngine; + QwtAbstractScaleDraw *scaleDraw; + + int maxMajor; + int maxMinor; + double stepSize; +}; + +/*! + Constructor + + \param parent Parent widget + + Creates a default QwtScaleDraw and a QwtLinearScaleEngine. + The initial scale boundaries are set to [ 0.0, 100.0 ] + + The scaleStepSize() is initialized to 0.0, scaleMaxMajor() to 5 + and scaleMaxMajor to 3. +*/ + +QwtAbstractScale::QwtAbstractScale( QWidget *parent ): + QWidget( parent ) +{ + d_data = new PrivateData; + rescale( 0.0, 100.0, d_data->stepSize ); +} + +//! Destructor +QwtAbstractScale::~QwtAbstractScale() +{ + delete d_data; +} + +/*! + Set the lower bound of the scale + + \param value Lower bound + + \sa lowerBound(), setScale(), setUpperBound() + \note For inverted scales the lower bound + is greater than the upper bound +*/ +void QwtAbstractScale::setLowerBound( double value ) +{ + setScale( value, upperBound() ); +} + +/*! + \return Lower bound of the scale + \sa setLowerBound(), setScale(), upperBound() +*/ +double QwtAbstractScale::lowerBound() const +{ + return d_data->scaleDraw->scaleDiv().lowerBound(); +} + +/*! + Set the upper bound of the scale + + \param value Upper bound + + \sa upperBound(), setScale(), setLowerBound() + \note For inverted scales the lower bound + is greater than the upper bound +*/ +void QwtAbstractScale::setUpperBound( double value ) +{ + setScale( lowerBound(), value ); +} + +/*! + \return Upper bound of the scale + \sa setUpperBound(), setScale(), lowerBound() +*/ +double QwtAbstractScale::upperBound() const +{ + return d_data->scaleDraw->scaleDiv().upperBound(); +} + +/*! + \brief Specify a scale. + + Define a scale by an interval + + The ticks are calculated using scaleMaxMinor(), + scaleMaxMajor() and scaleStepSize(). + + \param lowerBound lower limit of the scale interval + \param upperBound upper limit of the scale interval + + \note For inverted scales the lower bound + is greater than the upper bound +*/ +void QwtAbstractScale::setScale( double lowerBound, double upperBound ) +{ + rescale( lowerBound, upperBound, d_data->stepSize ); +} + +/*! + \brief Specify a scale. + + Define a scale by an interval + + The ticks are calculated using scaleMaxMinor(), + scaleMaxMajor() and scaleStepSize(). + + \param interval Interval +*/ +void QwtAbstractScale::setScale( const QwtInterval &interval ) +{ + setScale( interval.minValue(), interval.maxValue() ); +} + +/*! + \brief Specify a scale. + + scaleMaxMinor(), scaleMaxMajor() and scaleStepSize() and have no effect. + + \param scaleDiv Scale division + \sa setAutoScale() +*/ +void QwtAbstractScale::setScale( const QwtScaleDiv &scaleDiv ) +{ + if ( scaleDiv != d_data->scaleDraw->scaleDiv() ) + { +#if 1 + if ( d_data->scaleEngine ) + { + d_data->scaleDraw->setTransformation( + d_data->scaleEngine->transformation() ); + } +#endif + + d_data->scaleDraw->setScaleDiv( scaleDiv ); + + scaleChange(); + } +} + +/*! + \brief Set the maximum number of major tick intervals. + + The scale's major ticks are calculated automatically such that + the number of major intervals does not exceed ticks. + + The default value is 5. + + \param ticks Maximal number of major ticks. + + \sa scaleMaxMajor(), setScaleMaxMinor(), + setScaleStepSize(), QwtScaleEngine::divideInterval() +*/ +void QwtAbstractScale::setScaleMaxMajor( int ticks ) +{ + if ( ticks != d_data->maxMajor ) + { + d_data->maxMajor = ticks; + updateScaleDraw(); + } +} + +/*! + \return Maximal number of major tick intervals + \sa setScaleMaxMajor(), scaleMaxMinor() +*/ +int QwtAbstractScale::scaleMaxMajor() const +{ + return d_data->maxMajor; +} + +/*! + \brief Set the maximum number of minor tick intervals + + The scale's minor ticks are calculated automatically such that + the number of minor intervals does not exceed ticks. + The default value is 3. + + \param ticks Maximal number of minor ticks. + + \sa scaleMaxMajor(), setScaleMaxMinor(), + setScaleStepSize(), QwtScaleEngine::divideInterval() +*/ +void QwtAbstractScale::setScaleMaxMinor( int ticks ) +{ + if ( ticks != d_data->maxMinor ) + { + d_data->maxMinor = ticks; + updateScaleDraw(); + } +} + +/*! + \return Maximal number of minor tick intervals + \sa setScaleMaxMinor(), scaleMaxMajor() +*/ +int QwtAbstractScale::scaleMaxMinor() const +{ + return d_data->maxMinor; +} + +/*! + \brief Set the step size used for calculating a scale division + + The step size is hint for calculating the intervals for + the major ticks of the scale. A value of 0.0 is interpreted + as no hint. + + \param stepSize Hint for the step size of the scale + + \sa scaleStepSize(), QwtScaleEngine::divideScale() + + \note Position and distance between the major ticks also + depends on scaleMaxMajor(). +*/ +void QwtAbstractScale::setScaleStepSize( double stepSize ) +{ + if ( stepSize != d_data->stepSize ) + { + d_data->stepSize = stepSize; + updateScaleDraw(); + } +} + +/*! + \return Hint for the step size of the scale + \sa setScaleStepSize(), QwtScaleEngine::divideScale() +*/ +double QwtAbstractScale::scaleStepSize() const +{ + return d_data->stepSize; +} + +/*! + \brief Set a scale draw + + scaleDraw has to be created with new and will be deleted in + the destructor or the next call of setAbstractScaleDraw(). + + \sa abstractScaleDraw() +*/ +void QwtAbstractScale::setAbstractScaleDraw( QwtAbstractScaleDraw *scaleDraw ) +{ + if ( scaleDraw == NULL || scaleDraw == d_data->scaleDraw ) + return; + + if ( d_data->scaleDraw != NULL ) + scaleDraw->setScaleDiv( d_data->scaleDraw->scaleDiv() ); + + delete d_data->scaleDraw; + d_data->scaleDraw = scaleDraw; +} + +/*! + \return Scale draw + \sa setAbstractScaleDraw() +*/ +QwtAbstractScaleDraw *QwtAbstractScale::abstractScaleDraw() +{ + return d_data->scaleDraw; +} + +/*! + \return Scale draw + \sa setAbstractScaleDraw() +*/ +const QwtAbstractScaleDraw *QwtAbstractScale::abstractScaleDraw() const +{ + return d_data->scaleDraw; +} + +/*! + \brief Set a scale engine + + The scale engine is responsible for calculating the scale division + and provides a transformation between scale and widget coordinates. + + scaleEngine has to be created with new and will be deleted in + the destructor or the next call of setScaleEngine. +*/ +void QwtAbstractScale::setScaleEngine( QwtScaleEngine *scaleEngine ) +{ + if ( scaleEngine != NULL && scaleEngine != d_data->scaleEngine ) + { + delete d_data->scaleEngine; + d_data->scaleEngine = scaleEngine; + } +} + +/*! + \return Scale engine + \sa setScaleEngine() +*/ +const QwtScaleEngine *QwtAbstractScale::scaleEngine() const +{ + return d_data->scaleEngine; +} + +/*! + \return Scale engine + \sa setScaleEngine() +*/ +QwtScaleEngine *QwtAbstractScale::scaleEngine() +{ + return d_data->scaleEngine; +} + +/*! + \return Scale boundaries and positions of the ticks + + The scale division might have been assigned explicitly + or calculated implicitly by rescale(). + */ +const QwtScaleDiv &QwtAbstractScale::scaleDiv() const +{ + return d_data->scaleDraw->scaleDiv(); +} + +/*! + \return Map to translate between scale and widget coordinates + */ +const QwtScaleMap &QwtAbstractScale::scaleMap() const +{ + return d_data->scaleDraw->scaleMap(); +} + +/*! + Translate a scale value into a widget coordinate + + \param value Scale value + \return Corresponding widget coordinate for value + \sa scaleMap(), invTransform() + */ +int QwtAbstractScale::transform( double value ) const +{ + return qRound( d_data->scaleDraw->scaleMap().transform( value ) ); +} + +/*! + Translate a widget coordinate into a scale value + + \param value Widget coordinate + \return Corresponding scale coordinate for value + \sa scaleMap(), transform() + */ +double QwtAbstractScale::invTransform( int value ) const +{ + return d_data->scaleDraw->scaleMap().invTransform( value ); +} + +/*! + \return True, when the scale is increasing in opposite direction + to the widget coordinates + */ +bool QwtAbstractScale::isInverted() const +{ + return d_data->scaleDraw->scaleMap().isInverting(); +} + +/*! + \return The boundary with the smaller value + \sa maximum(), lowerBound(), upperBound() + */ +double QwtAbstractScale::minimum() const +{ + return qMin( d_data->scaleDraw->scaleDiv().lowerBound(), + d_data->scaleDraw->scaleDiv().upperBound() ); +} + +/*! + \return The boundary with the larger value + \sa minimum(), lowerBound(), upperBound() + */ +double QwtAbstractScale::maximum() const +{ + return qMax( d_data->scaleDraw->scaleDiv().lowerBound(), + d_data->scaleDraw->scaleDiv().upperBound() ); +} + +//! Notify changed scale +void QwtAbstractScale::scaleChange() +{ +} + +/*! + Recalculate the scale division and update the scale. + + \param lowerBound Lower limit of the scale interval + \param upperBound Upper limit of the scale interval + \param stepSize Major step size + + \sa scaleChange() +*/ +void QwtAbstractScale::rescale( + double lowerBound, double upperBound, double stepSize ) +{ + const QwtScaleDiv scaleDiv = d_data->scaleEngine->divideScale( + lowerBound, upperBound, d_data->maxMajor, d_data->maxMinor, stepSize ); + + if ( scaleDiv != d_data->scaleDraw->scaleDiv() ) + { +#if 1 + d_data->scaleDraw->setTransformation( + d_data->scaleEngine->transformation() ); +#endif + + d_data->scaleDraw->setScaleDiv( scaleDiv ); + scaleChange(); + } +} + +void QwtAbstractScale::updateScaleDraw() +{ + rescale( d_data->scaleDraw->scaleDiv().lowerBound(), + d_data->scaleDraw->scaleDiv().upperBound(), d_data->stepSize ); +} diff --git a/ThirdParty/Qwt/src/qwt_abstract_scale.h b/ThirdParty/Qwt/src/qwt_abstract_scale.h new file mode 100644 index 0000000000..4ed6616aa8 --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_abstract_scale.h @@ -0,0 +1,105 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#ifndef QWT_ABSTRACT_SCALE_H +#define QWT_ABSTRACT_SCALE_H + +#include "qwt_global.h" +#include + +class QwtScaleEngine; +class QwtAbstractScaleDraw; +class QwtScaleDiv; +class QwtScaleMap; +class QwtInterval; + +/*! + \brief An abstract base class for widgets having a scale + + The scale of an QwtAbstractScale is determined by a QwtScaleDiv + definition, that contains the boundaries and the ticks of the scale. + The scale is painted using a QwtScaleDraw object. + + The scale division might be assigned explicitly - but usually + it is calculated from the boundaries using a QwtScaleEngine. + + The scale engine also decides the type of transformation of the scale + ( linear, logarithmic ... ). +*/ + +class QWT_EXPORT QwtAbstractScale: public QWidget +{ + Q_OBJECT + + Q_PROPERTY( double lowerBound READ lowerBound WRITE setLowerBound ) + Q_PROPERTY( double upperBound READ upperBound WRITE setUpperBound ) + + Q_PROPERTY( int scaleMaxMajor READ scaleMaxMajor WRITE setScaleMaxMajor ) + Q_PROPERTY( int scaleMaxMinor READ scaleMaxMinor WRITE setScaleMaxMinor ) + + Q_PROPERTY( double scaleStepSize READ scaleStepSize WRITE setScaleStepSize ) + +public: + QwtAbstractScale( QWidget *parent = NULL ); + virtual ~QwtAbstractScale(); + + void setScale( double lowerBound, double upperBound ); + void setScale( const QwtInterval & ); + void setScale( const QwtScaleDiv & ); + + const QwtScaleDiv& scaleDiv() const; + + void setLowerBound( double value ); + double lowerBound() const; + + void setUpperBound( double value ); + double upperBound() const; + + void setScaleStepSize( double stepSize ); + double scaleStepSize() const; + + void setScaleMaxMajor( int ticks ); + int scaleMaxMinor() const; + + void setScaleMaxMinor( int ticks ); + int scaleMaxMajor() const; + + void setScaleEngine( QwtScaleEngine * ); + const QwtScaleEngine *scaleEngine() const; + QwtScaleEngine *scaleEngine(); + + int transform( double ) const; + double invTransform( int ) const; + + bool isInverted() const; + + double minimum() const; + double maximum() const; + + const QwtScaleMap &scaleMap() const; + +protected: + void rescale( double lowerBound, + double upperBound, double stepSize ); + + void setAbstractScaleDraw( QwtAbstractScaleDraw * ); + + const QwtAbstractScaleDraw *abstractScaleDraw() const; + QwtAbstractScaleDraw *abstractScaleDraw(); + + virtual void scaleChange(); + +private: + void updateScaleDraw(); + + class PrivateData; + PrivateData *d_data; +}; + +#endif diff --git a/ThirdParty/Qwt/src/qwt_abstract_scale_draw.cpp b/ThirdParty/Qwt/src/qwt_abstract_scale_draw.cpp new file mode 100644 index 0000000000..30b3ed9143 --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_abstract_scale_draw.cpp @@ -0,0 +1,419 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#include "qwt_abstract_scale_draw.h" +#include "qwt_math.h" +#include "qwt_text.h" +#include "qwt_painter.h" +#include "qwt_scale_map.h" +#include +#include +#include +#include + +class QwtAbstractScaleDraw::PrivateData +{ +public: + PrivateData(): + spacing( 4.0 ), + penWidth( 0 ), + minExtent( 0.0 ) + { + components = QwtAbstractScaleDraw::Backbone + | QwtAbstractScaleDraw::Ticks + | QwtAbstractScaleDraw::Labels; + + tickLength[QwtScaleDiv::MinorTick] = 4.0; + tickLength[QwtScaleDiv::MediumTick] = 6.0; + tickLength[QwtScaleDiv::MajorTick] = 8.0; + } + + ScaleComponents components; + + QwtScaleMap map; + QwtScaleDiv scaleDiv; + + double spacing; + double tickLength[QwtScaleDiv::NTickTypes]; + int penWidth; + + double minExtent; + + QMap labelCache; +}; + +/*! + \brief Constructor + + The range of the scale is initialized to [0, 100], + The spacing (distance between ticks and labels) is + set to 4, the tick lengths are set to 4,6 and 8 pixels +*/ +QwtAbstractScaleDraw::QwtAbstractScaleDraw() +{ + d_data = new QwtAbstractScaleDraw::PrivateData; +} + +//! Destructor +QwtAbstractScaleDraw::~QwtAbstractScaleDraw() +{ + delete d_data; +} + +/*! + En/Disable a component of the scale + + \param component Scale component + \param enable On/Off + + \sa hasComponent() +*/ +void QwtAbstractScaleDraw::enableComponent( + ScaleComponent component, bool enable ) +{ + if ( enable ) + d_data->components |= component; + else + d_data->components &= ~component; +} + +/*! + Check if a component is enabled + + \param component Component type + \return true, when component is enabled + \sa enableComponent() +*/ +bool QwtAbstractScaleDraw::hasComponent( ScaleComponent component ) const +{ + return ( d_data->components & component ); +} + +/*! + Change the scale division + \param scaleDiv New scale division +*/ +void QwtAbstractScaleDraw::setScaleDiv( const QwtScaleDiv &scaleDiv ) +{ + d_data->scaleDiv = scaleDiv; + d_data->map.setScaleInterval( scaleDiv.lowerBound(), scaleDiv.upperBound() ); + d_data->labelCache.clear(); +} + +/*! + Change the transformation of the scale + \param transformation New scale transformation +*/ +void QwtAbstractScaleDraw::setTransformation( + QwtTransform *transformation ) +{ + d_data->map.setTransformation( transformation ); +} + +//! \return Map how to translate between scale and pixel values +const QwtScaleMap &QwtAbstractScaleDraw::scaleMap() const +{ + return d_data->map; +} + +//! \return Map how to translate between scale and pixel values +QwtScaleMap &QwtAbstractScaleDraw::scaleMap() +{ + return d_data->map; +} + +//! \return scale division +const QwtScaleDiv& QwtAbstractScaleDraw::scaleDiv() const +{ + return d_data->scaleDiv; +} + +/*! + \brief Specify the width of the scale pen + \param width Pen width + \sa penWidth() +*/ +void QwtAbstractScaleDraw::setPenWidth( int width ) +{ + if ( width < 0 ) + width = 0; + + if ( width != d_data->penWidth ) + d_data->penWidth = width; +} + +/*! + \return Scale pen width + \sa setPenWidth() +*/ +int QwtAbstractScaleDraw::penWidth() const +{ + return d_data->penWidth; +} + +/*! + \brief Draw the scale + + \param painter The painter + + \param palette Palette, text color is used for the labels, + foreground color for ticks and backbone +*/ +void QwtAbstractScaleDraw::draw( QPainter *painter, + const QPalette& palette ) const +{ + painter->save(); + + QPen pen = painter->pen(); + pen.setWidth( d_data->penWidth ); + pen.setCosmetic( false ); + painter->setPen( pen ); + + if ( hasComponent( QwtAbstractScaleDraw::Labels ) ) + { + painter->save(); + painter->setPen( palette.color( QPalette::Text ) ); // ignore pen style + + const QList &majorTicks = + d_data->scaleDiv.ticks( QwtScaleDiv::MajorTick ); + + for ( int i = 0; i < majorTicks.count(); i++ ) + { + const double v = majorTicks[i]; + if ( d_data->scaleDiv.contains( v ) ) + drawLabel( painter, v ); + } + + painter->restore(); + } + + if ( hasComponent( QwtAbstractScaleDraw::Ticks ) ) + { + painter->save(); + + QPen pen = painter->pen(); + pen.setColor( palette.color( QPalette::WindowText ) ); + pen.setCapStyle( Qt::FlatCap ); + + painter->setPen( pen ); + + for ( int tickType = QwtScaleDiv::MinorTick; + tickType < QwtScaleDiv::NTickTypes; tickType++ ) + { + const QList &ticks = d_data->scaleDiv.ticks( tickType ); + for ( int i = 0; i < ticks.count(); i++ ) + { + const double v = ticks[i]; + if ( d_data->scaleDiv.contains( v ) ) + drawTick( painter, v, d_data->tickLength[tickType] ); + } + } + + painter->restore(); + } + + if ( hasComponent( QwtAbstractScaleDraw::Backbone ) ) + { + painter->save(); + + QPen pen = painter->pen(); + pen.setColor( palette.color( QPalette::WindowText ) ); + pen.setCapStyle( Qt::FlatCap ); + + painter->setPen( pen ); + + drawBackbone( painter ); + + painter->restore(); + } + + painter->restore(); +} + +/*! + \brief Set the spacing between tick and labels + + The spacing is the distance between ticks and labels. + The default spacing is 4 pixels. + + \param spacing Spacing + + \sa spacing() +*/ +void QwtAbstractScaleDraw::setSpacing( double spacing ) +{ + if ( spacing < 0 ) + spacing = 0; + + d_data->spacing = spacing; +} + +/*! + \brief Get the spacing + + The spacing is the distance between ticks and labels. + The default spacing is 4 pixels. + + \return Spacing + \sa setSpacing() +*/ +double QwtAbstractScaleDraw::spacing() const +{ + return d_data->spacing; +} + +/*! + \brief Set a minimum for the extent + + The extent is calculated from the components of the + scale draw. In situations, where the labels are + changing and the layout depends on the extent (f.e scrolling + a scale), setting an upper limit as minimum extent will + avoid jumps of the layout. + + \param minExtent Minimum extent + + \sa extent(), minimumExtent() +*/ +void QwtAbstractScaleDraw::setMinimumExtent( double minExtent ) +{ + if ( minExtent < 0.0 ) + minExtent = 0.0; + + d_data->minExtent = minExtent; +} + +/*! + Get the minimum extent + \return Minimum extent + \sa extent(), setMinimumExtent() +*/ +double QwtAbstractScaleDraw::minimumExtent() const +{ + return d_data->minExtent; +} + +/*! + Set the length of the ticks + + \param tickType Tick type + \param length New length + + \warning the length is limited to [0..1000] +*/ +void QwtAbstractScaleDraw::setTickLength( + QwtScaleDiv::TickType tickType, double length ) +{ + if ( tickType < QwtScaleDiv::MinorTick || + tickType > QwtScaleDiv::MajorTick ) + { + return; + } + + if ( length < 0.0 ) + length = 0.0; + + const double maxTickLen = 1000.0; + if ( length > maxTickLen ) + length = maxTickLen; + + d_data->tickLength[tickType] = length; +} + +/*! + \return Length of the ticks + \sa setTickLength(), maxTickLength() +*/ +double QwtAbstractScaleDraw::tickLength( QwtScaleDiv::TickType tickType ) const +{ + if ( tickType < QwtScaleDiv::MinorTick || + tickType > QwtScaleDiv::MajorTick ) + { + return 0; + } + + return d_data->tickLength[tickType]; +} + +/*! + \return Length of the longest tick + + Useful for layout calculations + \sa tickLength(), setTickLength() +*/ +double QwtAbstractScaleDraw::maxTickLength() const +{ + double length = 0.0; + for ( int i = 0; i < QwtScaleDiv::NTickTypes; i++ ) + length = qMax( length, d_data->tickLength[i] ); + + return length; +} + +/*! + \brief Convert a value into its representing label + + The value is converted to a plain text using + QLocale().toString(value). + This method is often overloaded by applications to have individual + labels. + + \param value Value + \return Label string. +*/ +QwtText QwtAbstractScaleDraw::label( double value ) const +{ + if ( qFuzzyCompare( value + 1.0, 1.0 ) ) + value = 0.0; + + return QLocale().toString( value ); +} + +/*! + \brief Convert a value into its representing label and cache it. + + The conversion between value and label is called very often + in the layout and painting code. Unfortunately the + calculation of the label sizes might be slow (really slow + for rich text in Qt4), so it's necessary to cache the labels. + + \param font Font + \param value Value + + \return Tick label +*/ +const QwtText &QwtAbstractScaleDraw::tickLabel( + const QFont &font, double value ) const +{ + QMap::const_iterator it = d_data->labelCache.find( value ); + if ( it == d_data->labelCache.end() ) + { + QwtText lbl = label( value ); + lbl.setRenderFlags( 0 ); + lbl.setLayoutAttribute( QwtText::MinimumLayout ); + + ( void )lbl.textSize( font ); // initialize the internal cache + + it = d_data->labelCache.insert( value, lbl ); + } + + return ( *it ); +} + +/*! + Invalidate the cache used by tickLabel() + + The cache is invalidated, when a new QwtScaleDiv is set. If + the labels need to be changed. while the same QwtScaleDiv is set, + invalidateCache() needs to be called manually. +*/ +void QwtAbstractScaleDraw::invalidateCache() +{ + d_data->labelCache.clear(); +} diff --git a/ThirdParty/Qwt/src/qwt_abstract_scale_draw.h b/ThirdParty/Qwt/src/qwt_abstract_scale_draw.h new file mode 100644 index 0000000000..d0f1ec3c3b --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_abstract_scale_draw.h @@ -0,0 +1,141 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#ifndef QWT_ABSTRACT_SCALE_DRAW_H +#define QWT_ABSTRACT_SCALE_DRAW_H + +#include "qwt_global.h" +#include "qwt_scale_div.h" +#include "qwt_text.h" + +class QPalette; +class QPainter; +class QFont; +class QwtTransform; +class QwtScaleMap; + +/*! + \brief A abstract base class for drawing scales + + QwtAbstractScaleDraw can be used to draw linear or logarithmic scales. + + After a scale division has been specified as a QwtScaleDiv object + using setScaleDiv(), the scale can be drawn with the draw() member. +*/ +class QWT_EXPORT QwtAbstractScaleDraw +{ +public: + + /*! + Components of a scale + \sa enableComponent(), hasComponent + */ + enum ScaleComponent + { + //! Backbone = the line where the ticks are located + Backbone = 0x01, + + //! Ticks + Ticks = 0x02, + + //! Labels + Labels = 0x04 + }; + + //! Scale components + typedef QFlags ScaleComponents; + + QwtAbstractScaleDraw(); + virtual ~QwtAbstractScaleDraw(); + + void setScaleDiv( const QwtScaleDiv &s ); + const QwtScaleDiv& scaleDiv() const; + + void setTransformation( QwtTransform * ); + const QwtScaleMap &scaleMap() const; + QwtScaleMap &scaleMap(); + + void enableComponent( ScaleComponent, bool enable = true ); + bool hasComponent( ScaleComponent ) const; + + void setTickLength( QwtScaleDiv::TickType, double length ); + double tickLength( QwtScaleDiv::TickType ) const; + double maxTickLength() const; + + void setSpacing( double margin ); + double spacing() const; + + void setPenWidth( int width ); + int penWidth() const; + + virtual void draw( QPainter *, const QPalette & ) const; + + virtual QwtText label( double ) const; + + /*! + Calculate the extent + + The extent is the distance from the baseline to the outermost + pixel of the scale draw in opposite to its orientation. + It is at least minimumExtent() pixels. + + \param font Font used for drawing the tick labels + \return Number of pixels + + \sa setMinimumExtent(), minimumExtent() + */ + virtual double extent( const QFont &font ) const = 0; + + void setMinimumExtent( double ); + double minimumExtent() const; + +protected: + /*! + Draw a tick + + \param painter Painter + \param value Value of the tick + \param len Length of the tick + + \sa drawBackbone(), drawLabel() + */ + virtual void drawTick( QPainter *painter, double value, double len ) const = 0; + + /*! + Draws the baseline of the scale + \param painter Painter + + \sa drawTick(), drawLabel() + */ + virtual void drawBackbone( QPainter *painter ) const = 0; + + /*! + Draws the label for a major scale tick + + \param painter Painter + \param value Value + + \sa drawTick(), drawBackbone() + */ + virtual void drawLabel( QPainter *painter, double value ) const = 0; + + void invalidateCache(); + const QwtText &tickLabel( const QFont &, double value ) const; + +private: + QwtAbstractScaleDraw( const QwtAbstractScaleDraw & ); + QwtAbstractScaleDraw &operator=( const QwtAbstractScaleDraw & ); + + class PrivateData; + PrivateData *d_data; +}; + +Q_DECLARE_OPERATORS_FOR_FLAGS( QwtAbstractScaleDraw::ScaleComponents ) + +#endif diff --git a/ThirdParty/Qwt/src/qwt_abstract_slider.cpp b/ThirdParty/Qwt/src/qwt_abstract_slider.cpp new file mode 100644 index 0000000000..ea613bdca3 --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_abstract_slider.cpp @@ -0,0 +1,820 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#include "qwt_abstract_slider.h" +#include "qwt_abstract_scale_draw.h" +#include "qwt_math.h" +#include "qwt_scale_map.h" +#include + +#if QT_VERSION < 0x040601 +#define qFabs(x) ::fabs(x) +#endif + +static double qwtAlignToScaleDiv( + const QwtAbstractSlider *slider, double value ) +{ + const QwtScaleDiv &sd = slider->scaleDiv(); + + const int tValue = slider->transform( value ); + + if ( tValue == slider->transform( sd.lowerBound() ) ) + return sd.lowerBound(); + + if ( tValue == slider->transform( sd.lowerBound() ) ) + return sd.upperBound(); + + for ( int i = 0; i < QwtScaleDiv::NTickTypes; i++ ) + { + const QList ticks = sd.ticks( i ); + for ( int j = 0; j < ticks.size(); j++ ) + { + if ( slider->transform( ticks[ j ] ) == tValue ) + return ticks[ j ]; + } + } + + return value; +} + +class QwtAbstractSlider::PrivateData +{ +public: + PrivateData(): + isScrolling( false ), + isTracking( true ), + pendingValueChanged( false ), + readOnly( false ), + totalSteps( 100 ), + singleSteps( 1 ), + pageSteps( 10 ), + stepAlignment( true ), + isValid( false ), + value( 0.0 ), + wrapping( false ), + invertedControls( false ) + { + } + + bool isScrolling; + bool isTracking; + bool pendingValueChanged; + + bool readOnly; + + uint totalSteps; + uint singleSteps; + uint pageSteps; + bool stepAlignment; + + bool isValid; + double value; + + bool wrapping; + bool invertedControls; +}; + +/*! + \brief Constructor + + The scale is initialized to [0.0, 100.0], the + number of steps is set to 100 with 1 and 10 and single + an page step sizes. Step alignment is enabled. + + The initial value is invalid. + + \param parent Parent widget +*/ +QwtAbstractSlider::QwtAbstractSlider( QWidget *parent ): + QwtAbstractScale( parent ) +{ + d_data = new QwtAbstractSlider::PrivateData; + + setScale( 0.0, 100.0 ); + setFocusPolicy( Qt::StrongFocus ); +} + +//! Destructor +QwtAbstractSlider::~QwtAbstractSlider() +{ + delete d_data; +} + +/*! + Set the value to be valid/invalid + + \param on When true, the value is invalidated + + \sa setValue() +*/ +void QwtAbstractSlider::setValid( bool on ) +{ + if ( on != d_data->isValid ) + { + d_data->isValid = on; + sliderChange(); + + Q_EMIT valueChanged( d_data->value ); + } +} + +//! \return True, when the value is invalid +bool QwtAbstractSlider::isValid() const +{ + return d_data->isValid; +} + +/*! + En/Disable read only mode + + In read only mode the slider can't be controlled by mouse + or keyboard. + + \param on Enables in case of true + \sa isReadOnly() + + \warning The focus policy is set to Qt::StrongFocus or Qt::NoFocus +*/ +void QwtAbstractSlider::setReadOnly( bool on ) +{ + if ( d_data->readOnly != on ) + { + d_data->readOnly = on; + setFocusPolicy( on ? Qt::StrongFocus : Qt::NoFocus ); + + update(); + } +} + +/*! + In read only mode the slider can't be controlled by mouse + or keyboard. + + \return true if read only + \sa setReadOnly() +*/ +bool QwtAbstractSlider::isReadOnly() const +{ + return d_data->readOnly; +} + +/*! + \brief Enables or disables tracking. + + If tracking is enabled, the slider emits the valueChanged() + signal while the movable part of the slider is being dragged. + If tracking is disabled, the slider emits the valueChanged() signal + only when the user releases the slider. + + Tracking is enabled by default. + \param on \c true (enable) or \c false (disable) tracking. + + \sa isTracking(), sliderMoved() +*/ +void QwtAbstractSlider::setTracking( bool on ) +{ + d_data->isTracking = on; +} + +/*! + \return True, when tracking has been enabled + \sa setTracking() +*/ +bool QwtAbstractSlider::isTracking() const +{ + return d_data->isTracking; +} + +/*! + Mouse press event handler + \param event Mouse event +*/ +void QwtAbstractSlider::mousePressEvent( QMouseEvent *event ) +{ + if ( isReadOnly() ) + { + event->ignore(); + return; + } + + if ( !d_data->isValid || lowerBound() == upperBound() ) + return; + + d_data->isScrolling = isScrollPosition( event->pos() ); + + if ( d_data->isScrolling ) + { + d_data->pendingValueChanged = false; + + Q_EMIT sliderPressed(); + } +} + +/*! + Mouse Move Event handler + \param event Mouse event +*/ +void QwtAbstractSlider::mouseMoveEvent( QMouseEvent *event ) +{ + if ( isReadOnly() ) + { + event->ignore(); + return; + } + + if ( d_data->isValid && d_data->isScrolling ) + { + double value = scrolledTo( event->pos() ); + if ( value != d_data->value ) + { + value = boundedValue( value ); + + if ( d_data->stepAlignment ) + { + value = alignedValue( value ); + } + else + { + value = qwtAlignToScaleDiv( this, value ); + } + + if ( value != d_data->value ) + { + d_data->value = value; + + sliderChange(); + + Q_EMIT sliderMoved( d_data->value ); + + if ( d_data->isTracking ) + Q_EMIT valueChanged( d_data->value ); + else + d_data->pendingValueChanged = true; + } + } + } +} + +/*! + Mouse Release Event handler + \param event Mouse event +*/ +void QwtAbstractSlider::mouseReleaseEvent( QMouseEvent *event ) +{ + if ( isReadOnly() ) + { + event->ignore(); + return; + } + + if ( d_data->isScrolling && d_data->isValid ) + { + d_data->isScrolling = false; + + if ( d_data->pendingValueChanged ) + Q_EMIT valueChanged( d_data->value ); + + Q_EMIT sliderReleased(); + } +} + +/*! + Wheel Event handler + + In/decreases the value by s number of steps. The direction + depends on the invertedControls() property. + + When the control or shift modifier is pressed the wheel delta + ( divided by 120 ) is mapped to an increment according to + pageSteps(). Otherwise it is mapped to singleSteps(). + + \param event Wheel event +*/ +void QwtAbstractSlider::wheelEvent( QWheelEvent *event ) +{ + if ( isReadOnly() ) + { + event->ignore(); + return; + } + + if ( !d_data->isValid || d_data->isScrolling ) + return; + + int numSteps = 0; + + if ( ( event->modifiers() & Qt::ControlModifier) || + ( event->modifiers() & Qt::ShiftModifier ) ) + { + // one page regardless of delta + numSteps = d_data->pageSteps; + if ( event->delta() < 0 ) + numSteps = -numSteps; + } + else + { + const int numTurns = ( event->delta() / 120 ); + numSteps = numTurns * d_data->singleSteps; + } + + if ( d_data->invertedControls ) + numSteps = -numSteps; + + const double value = incrementedValue( d_data->value, numSteps ); + if ( value != d_data->value ) + { + d_data->value = value; + sliderChange(); + + Q_EMIT sliderMoved( d_data->value ); + Q_EMIT valueChanged( d_data->value ); + } +} + +/*! + Handles key events + + QwtAbstractSlider handles the following keys: + + - Qt::Key_Left\n + Add/Subtract singleSteps() in direction to lowerBound(); + - Qt::Key_Right\n + Add/Subtract singleSteps() in direction to upperBound(); + - Qt::Key_Down\n + Subtract singleSteps(), when invertedControls() is false + - Qt::Key_Up\n + Add singleSteps(), when invertedControls() is false + - Qt::Key_PageDown\n + Subtract pageSteps(), when invertedControls() is false + - Qt::Key_PageUp\n + Add pageSteps(), when invertedControls() is false + - Qt::Key_Home\n + Set the value to the minimum() + - Qt::Key_End\n + Set the value to the maximum() + + \param event Key event + \sa isReadOnly() +*/ +void QwtAbstractSlider::keyPressEvent( QKeyEvent *event ) +{ + if ( isReadOnly() ) + { + event->ignore(); + return; + } + + if ( !d_data->isValid || d_data->isScrolling ) + return; + + int numSteps = 0; + double value = d_data->value; + + switch ( event->key() ) + { + case Qt::Key_Left: + { + numSteps = -static_cast( d_data->singleSteps ); + if ( isInverted() ) + numSteps = -numSteps; + + break; + } + case Qt::Key_Right: + { + numSteps = d_data->singleSteps; + if ( isInverted() ) + numSteps = -numSteps; + + break; + } + case Qt::Key_Down: + { + numSteps = -static_cast( d_data->singleSteps ); + if ( d_data->invertedControls ) + numSteps = -numSteps; + break; + } + case Qt::Key_Up: + { + numSteps = d_data->singleSteps; + if ( d_data->invertedControls ) + numSteps = -numSteps; + + break; + } + case Qt::Key_PageUp: + { + numSteps = d_data->pageSteps; + if ( d_data->invertedControls ) + numSteps = -numSteps; + break; + } + case Qt::Key_PageDown: + { + numSteps = -static_cast( d_data->pageSteps ); + if ( d_data->invertedControls ) + numSteps = -numSteps; + break; + } + case Qt::Key_Home: + { + value = minimum(); + break; + } + case Qt::Key_End: + { + value = maximum(); + break; + } + default:; + { + event->ignore(); + } + } + + if ( numSteps != 0 ) + { + value = incrementedValue( d_data->value, numSteps ); + } + + if ( value != d_data->value ) + { + d_data->value = value; + sliderChange(); + + Q_EMIT sliderMoved( d_data->value ); + Q_EMIT valueChanged( d_data->value ); + } +} + +/*! + \brief Set the number of steps + + The range of the slider is divided into a number of steps from + which the value increments according to user inputs depend. + + The default setting is 100. + + \param stepCount Number of steps + + \sa totalSteps(), setSingleSteps(), setPageSteps() + */ +void QwtAbstractSlider::setTotalSteps( uint stepCount ) +{ + d_data->totalSteps = stepCount; +} + +/*! + \return Number of steps + \sa setTotalSteps(), singleSteps(), pageSteps() + */ +uint QwtAbstractSlider::totalSteps() const +{ + return d_data->totalSteps; +} + +/*! + \brief Set the number of steps for a single increment + + The range of the slider is divided into a number of steps from + which the value increments according to user inputs depend. + + \param stepCount Number of steps + + \sa singleSteps(), setTotalSteps(), setPageSteps() + */ + +void QwtAbstractSlider::setSingleSteps( uint stepCount ) +{ + d_data->singleSteps = stepCount; +} + +/*! + \return Number of steps + \sa setSingleSteps(), totalSteps(), pageSteps() + */ +uint QwtAbstractSlider::singleSteps() const +{ + return d_data->singleSteps; +} + +/*! + \brief Set the number of steps for a page increment + + The range of the slider is divided into a number of steps from + which the value increments according to user inputs depend. + + \param stepCount Number of steps + + \sa pageSteps(), setTotalSteps(), setSingleSteps() + */ + +void QwtAbstractSlider::setPageSteps( uint stepCount ) +{ + d_data->pageSteps = stepCount; +} + +/*! + \return Number of steps + \sa setPageSteps(), totalSteps(), singleSteps() + */ +uint QwtAbstractSlider::pageSteps() const +{ + return d_data->pageSteps; +} + +/*! + \brief Enable step alignment + + When step alignment is enabled values resulting from slider + movements are aligned to the step size. + + \param on Enable step alignment when true + \sa stepAlignment() +*/ +void QwtAbstractSlider::setStepAlignment( bool on ) +{ + if ( on != d_data->stepAlignment ) + { + d_data->stepAlignment = on; + } +} + +/*! + \return True, when step alignment is enabled + \sa setStepAlignment() + */ +bool QwtAbstractSlider::stepAlignment() const +{ + return d_data->stepAlignment; +} + +/*! + Set the slider to the specified value + + \param value New value + \sa setValid(), sliderChange(), valueChanged() +*/ +void QwtAbstractSlider::setValue( double value ) +{ + value = qBound( minimum(), value, maximum() ); + + const bool changed = ( d_data->value != value ) || !d_data->isValid; + + d_data->value = value; + d_data->isValid = true; + + if ( changed ) + { + sliderChange(); + Q_EMIT valueChanged( d_data->value ); + } +} + +//! Returns the current value. +double QwtAbstractSlider::value() const +{ + return d_data->value; +} + +/*! + If wrapping is true stepping up from upperBound() value will + take you to the minimum() value and vice versa. + + \param on En/Disable wrapping + \sa wrapping() +*/ +void QwtAbstractSlider::setWrapping( bool on ) +{ + d_data->wrapping = on; +} + +/*! + \return True, when wrapping is set + \sa setWrapping() + */ +bool QwtAbstractSlider::wrapping() const +{ + return d_data->wrapping; +} + +/*! + Invert wheel and key events + + Usually scrolling the mouse wheel "up" and using keys like page + up will increase the slider's value towards its maximum. + When invertedControls() is enabled the value is scrolled + towards its minimum. + + Inverting the controls might be f.e. useful for a vertical slider + with an inverted scale ( decreasing from top to bottom ). + + \param on Invert controls, when true + + \sa invertedControls(), keyEvent(), wheelEvent() + */ +void QwtAbstractSlider::setInvertedControls( bool on ) +{ + d_data->invertedControls = on; +} + +/*! + \return True, when the controls are inverted + \sa setInvertedControls() + */ +bool QwtAbstractSlider::invertedControls() const +{ + return d_data->invertedControls; +} + +/*! + Increment the slider + + The step size depends on the number of totalSteps() + + \param stepCount Number of steps + \sa setTotalSteps(), incrementedValue() + */ +void QwtAbstractSlider::incrementValue( int stepCount ) +{ + const double value = incrementedValue( + d_data->value, stepCount ); + + if ( value != d_data->value ) + { + d_data->value = value; + sliderChange(); + } +} + +/*! + Increment a value + + \param value Value + \param stepCount Number of steps + + \return Incremented value + */ +double QwtAbstractSlider::incrementedValue( + double value, int stepCount ) const +{ + if ( d_data->totalSteps == 0 ) + return value; + + const QwtTransform *transformation = + scaleMap().transformation(); + + if ( transformation == NULL ) + { + const double range = maximum() - minimum(); + value += stepCount * range / d_data->totalSteps; + } + else + { + QwtScaleMap map = scaleMap(); + map.setPaintInterval( 0, d_data->totalSteps ); + + // we need equidant steps according to + // paint device coordinates + const double range = transformation->transform( maximum() ) + - transformation->transform( minimum() ); + + const double stepSize = range / d_data->totalSteps; + + double v = transformation->transform( value ); + + v = qRound( v / stepSize ) * stepSize; + v += stepCount * range / d_data->totalSteps; + + value = transformation->invTransform( v ); + } + + value = boundedValue( value ); + + if ( d_data->stepAlignment ) + value = alignedValue( value ); + + return value; +} + +double QwtAbstractSlider::boundedValue( double value ) const +{ + const double vmin = minimum(); + const double vmax = maximum(); + + if ( d_data->wrapping && vmin != vmax ) + { + const int fullCircle = 360 * 16; + + const double pd = scaleMap().pDist(); + if ( int( pd / fullCircle ) * fullCircle == pd ) + { + // full circle scales: min and max are the same + const double range = vmax - vmin; + + if ( value < vmin ) + { + value += ::ceil( ( vmin - value ) / range ) * range; + } + else if ( value > vmax ) + { + value -= ::ceil( ( value - vmax ) / range ) * range; + } + } + else + { + if ( value < vmin ) + value = vmax; + else if ( value > vmax ) + value = vmin; + } + } + else + { + value = qBound( vmin, value, vmax ); + } + + return value; +} + +double QwtAbstractSlider::alignedValue( double value ) const +{ + if ( d_data->totalSteps == 0 ) + return value; + + if ( scaleMap().transformation() == NULL ) + { + const double stepSize = + ( maximum() - minimum() ) / d_data->totalSteps; + + if ( stepSize > 0.0 ) + { + value = lowerBound() + + qRound( ( value - lowerBound() ) / stepSize ) * stepSize; + } + } + else + { + const double stepSize = + ( scaleMap().p2() - scaleMap().p1() ) / d_data->totalSteps; + + if ( stepSize > 0.0 ) + { + double v = scaleMap().transform( value ); + + v = scaleMap().p1() + + qRound( ( v - scaleMap().p1() ) / stepSize ) * stepSize; + + value = scaleMap().invTransform( v ); + } + } + + // correct rounding error if value = 0 + if ( qFuzzyCompare( value + 1.0, 1.0 ) ) + { + value = 0.0; + } + else + { + // correct rounding error at the border + if ( qFuzzyCompare( value, upperBound() ) ) + value = upperBound(); + else if ( qFuzzyCompare( value, lowerBound() ) ) + value = lowerBound(); + } + + return value; +} + +/*! + Update the slider according to modifications of the scale + */ +void QwtAbstractSlider::scaleChange() +{ + const double value = qBound( minimum(), d_data->value, maximum() ); + + const bool changed = ( value != d_data->value ); + if ( changed ) + { + d_data->value = value; + } + + if ( d_data->isValid || changed ) + Q_EMIT valueChanged( d_data->value ); + + updateGeometry(); + update(); +} + +//! Calling update() +void QwtAbstractSlider::sliderChange() +{ + update(); +} diff --git a/ThirdParty/Qwt/src/qwt_abstract_slider.h b/ThirdParty/Qwt/src/qwt_abstract_slider.h new file mode 100644 index 0000000000..c91dcb6048 --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_abstract_slider.h @@ -0,0 +1,167 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#ifndef QWT_ABSTRACT_SLIDER_H +#define QWT_ABSTRACT_SLIDER_H + +#include "qwt_global.h" +#include "qwt_abstract_scale.h" + +/*! + \brief An abstract base class for slider widgets with a scale + + A slider widget displays a value according to a scale. + The class is designed as a common super class for widgets like + QwtKnob, QwtDial and QwtSlider. + + When the slider is nor readOnly() its value can be modified + by keyboard, mouse and wheel inputs. + + The range of the slider is divided into a number of steps from + which the value increments according to user inputs depend. + Only for linear scales the number of steps correspond with + a fixed step size. +*/ + +class QWT_EXPORT QwtAbstractSlider: public QwtAbstractScale +{ + Q_OBJECT + + Q_PROPERTY( double value READ value WRITE setValue ) + + Q_PROPERTY( uint totalSteps READ totalSteps WRITE setTotalSteps ) + Q_PROPERTY( uint singleSteps READ singleSteps WRITE setSingleSteps ) + Q_PROPERTY( uint pageSteps READ pageSteps WRITE setPageSteps ) + Q_PROPERTY( bool stepAlignment READ stepAlignment WRITE setStepAlignment ) + + Q_PROPERTY( bool readOnly READ isReadOnly WRITE setReadOnly ) + Q_PROPERTY( bool tracking READ isTracking WRITE setTracking ) + Q_PROPERTY( bool wrapping READ wrapping WRITE setWrapping ) + + Q_PROPERTY( bool invertedControls READ invertedControls WRITE setInvertedControls ) + +public: + explicit QwtAbstractSlider( QWidget *parent = NULL ); + virtual ~QwtAbstractSlider(); + + void setValid( bool ); + bool isValid() const; + + double value() const; + + void setWrapping( bool ); + bool wrapping() const; + + void setTotalSteps( uint ); + uint totalSteps() const; + + void setSingleSteps( uint ); + uint singleSteps() const; + + void setPageSteps( uint ); + uint pageSteps() const; + + void setStepAlignment( bool ); + bool stepAlignment() const; + + void setTracking( bool ); + bool isTracking() const; + + void setReadOnly( bool ); + bool isReadOnly() const; + + void setInvertedControls( bool ); + bool invertedControls() const; + +public Q_SLOTS: + void setValue( double val ); + +Q_SIGNALS: + + /*! + \brief Notify a change of value. + + When tracking is enabled (default setting), + this signal will be emitted every time the value changes. + + \param value New value + + \sa setTracking(), sliderMoved() + */ + void valueChanged( double value ); + + /*! + This signal is emitted when the user presses the + movable part of the slider. + */ + void sliderPressed(); + + /*! + This signal is emitted when the user releases the + movable part of the slider. + */ + void sliderReleased(); + + /*! + This signal is emitted when the user moves the + slider with the mouse. + + \param value New value + + \sa valueChanged() + */ + void sliderMoved( double value ); + +protected: + virtual void mousePressEvent( QMouseEvent * ); + virtual void mouseReleaseEvent( QMouseEvent * ); + virtual void mouseMoveEvent( QMouseEvent * ); + virtual void keyPressEvent( QKeyEvent * ); + virtual void wheelEvent( QWheelEvent * ); + + /*! + \brief Determine what to do when the user presses a mouse button. + + \param pos Mouse position + + \retval True, when pos is a valid scroll position + \sa scrolledTo() + */ + virtual bool isScrollPosition( const QPoint &pos ) const = 0; + + /*! + \brief Determine the value for a new position of the + movable part of the slider + + \param pos Mouse position + + \return Value for the mouse position + \sa isScrollPosition() + */ + virtual double scrolledTo( const QPoint &pos ) const = 0; + + void incrementValue( int numSteps ); + + virtual void scaleChange(); + +protected: + virtual void sliderChange(); + + double incrementedValue( + double value, int stepCount ) const; + +private: + double alignedValue( double ) const; + double boundedValue( double ) const; + + class PrivateData; + PrivateData *d_data; +}; + +#endif diff --git a/ThirdParty/Qwt/src/qwt_analog_clock.cpp b/ThirdParty/Qwt/src/qwt_analog_clock.cpp new file mode 100644 index 0000000000..1d44a95cb2 --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_analog_clock.cpp @@ -0,0 +1,244 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#include "qwt_analog_clock.h" +#include "qwt_round_scale_draw.h" +#include +#include + +class QwtAnalogClockScaleDraw: public QwtRoundScaleDraw +{ +public: + QwtAnalogClockScaleDraw() + { + setSpacing( 8 ); + + enableComponent( QwtAbstractScaleDraw::Backbone, false ); + + setTickLength( QwtScaleDiv::MinorTick, 2 ); + setTickLength( QwtScaleDiv::MediumTick, 4 ); + setTickLength( QwtScaleDiv::MajorTick, 8 ); + + setPenWidth( 1 ); + } + + virtual QwtText label( double value ) const + { + if ( qFuzzyCompare( value + 1.0, 1.0 ) ) + value = 60.0 * 60.0 * 12.0; + + return QLocale().toString( qRound( value / ( 60.0 * 60.0 ) ) ); + } +}; + +/*! + Constructor + \param parent Parent widget +*/ +QwtAnalogClock::QwtAnalogClock( QWidget *parent ): + QwtDial( parent ) +{ + setWrapping( true ); + setReadOnly( true ); + + setOrigin( 270.0 ); + setScaleDraw( new QwtAnalogClockScaleDraw() ); + + setTotalSteps( 60 ); + + const int secondsPerHour = 60.0 * 60.0; + + QList majorTicks; + QList minorTicks; + + for ( int i = 0; i < 12; i++ ) + { + majorTicks += i * secondsPerHour; + + for ( int j = 1; j < 5; j++ ) + minorTicks += i * secondsPerHour + j * secondsPerHour / 5.0; + } + + QwtScaleDiv scaleDiv; + scaleDiv.setInterval( 0.0, 12.0 * secondsPerHour ); + scaleDiv.setTicks( QwtScaleDiv::MajorTick, majorTicks ); + scaleDiv.setTicks( QwtScaleDiv::MinorTick, minorTicks ); + setScale( scaleDiv ); + + QColor knobColor = palette().color( QPalette::Active, QPalette::Text ); + knobColor = knobColor.dark( 120 ); + + QColor handColor; + int width; + + for ( int i = 0; i < NHands; i++ ) + { + if ( i == SecondHand ) + { + width = 2; + handColor = knobColor.dark( 120 ); + } + else + { + width = 8; + handColor = knobColor; + } + + QwtDialSimpleNeedle *hand = new QwtDialSimpleNeedle( + QwtDialSimpleNeedle::Arrow, true, handColor, knobColor ); + hand->setWidth( width ); + + d_hand[i] = NULL; + setHand( static_cast( i ), hand ); + } +} + +//! Destructor +QwtAnalogClock::~QwtAnalogClock() +{ + for ( int i = 0; i < NHands; i++ ) + delete d_hand[i]; +} + +/*! + Nop method, use setHand() instead + \sa setHand() +*/ +void QwtAnalogClock::setNeedle( QwtDialNeedle * ) +{ + // no op + return; +} + +/*! + Set a clock hand + \param hand Specifies the type of hand + \param needle Hand + \sa hand() +*/ +void QwtAnalogClock::setHand( Hand hand, QwtDialNeedle *needle ) +{ + if ( hand >= 0 && hand < NHands ) + { + delete d_hand[hand]; + d_hand[hand] = needle; + } +} + +/*! + \return Clock hand + \param hd Specifies the type of hand + \sa setHand() +*/ +QwtDialNeedle *QwtAnalogClock::hand( Hand hd ) +{ + if ( hd < 0 || hd >= NHands ) + return NULL; + + return d_hand[hd]; +} + +/*! + \return Clock hand + \param hd Specifies the type of hand + \sa setHand() +*/ +const QwtDialNeedle *QwtAnalogClock::hand( Hand hd ) const +{ + return const_cast( this )->hand( hd ); +} + +/*! + \brief Set the current time +*/ +void QwtAnalogClock::setCurrentTime() +{ + setTime( QTime::currentTime() ); +} + +/*! + Set a time + \param time Time to display +*/ +void QwtAnalogClock::setTime( const QTime &time ) +{ + if ( time.isValid() ) + { + setValue( ( time.hour() % 12 ) * 60.0 * 60.0 + + time.minute() * 60.0 + time.second() ); + } + else + setValid( false ); +} + +/*! + \brief Draw the needle + + A clock has no single needle but three hands instead. drawNeedle() + translates value() into directions for the hands and calls + drawHand(). + + \param painter Painter + \param center Center of the clock + \param radius Maximum length for the hands + \param dir Dummy, not used. + \param colorGroup ColorGroup + + \sa drawHand() +*/ +void QwtAnalogClock::drawNeedle( QPainter *painter, const QPointF ¢er, + double radius, double dir, QPalette::ColorGroup colorGroup ) const +{ + Q_UNUSED( dir ); + + if ( isValid() ) + { + const double hours = value() / ( 60.0 * 60.0 ); + const double minutes = + ( value() - qFloor(hours) * 60.0 * 60.0 ) / 60.0; + const double seconds = value() - qFloor(hours) * 60.0 * 60.0 + - qFloor(minutes) * 60.0; + + double angle[NHands]; + angle[HourHand] = 360.0 * hours / 12.0; + angle[MinuteHand] = 360.0 * minutes / 60.0; + angle[SecondHand] = 360.0 * seconds / 60.0; + + for ( int hand = 0; hand < NHands; hand++ ) + { + const double d = 360.0 - angle[hand] - origin(); + drawHand( painter, static_cast( hand ), + center, radius, d, colorGroup ); + } + } +} + +/*! + Draw a clock hand + + \param painter Painter + \param hd Specify the type of hand + \param center Center of the clock + \param radius Maximum length for the hands + \param direction Direction of the hand in degrees, counter clockwise + \param cg ColorGroup +*/ +void QwtAnalogClock::drawHand( QPainter *painter, Hand hd, + const QPointF ¢er, double radius, double direction, + QPalette::ColorGroup cg ) const +{ + const QwtDialNeedle *needle = hand( hd ); + if ( needle ) + { + if ( hd == HourHand ) + radius = qRound( 0.8 * radius ); + + needle->draw( painter, center, radius, direction, cg ); + } +} diff --git a/ThirdParty/Qwt/src/qwt_analog_clock.h b/ThirdParty/Qwt/src/qwt_analog_clock.h new file mode 100644 index 0000000000..ffe27e2cdb --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_analog_clock.h @@ -0,0 +1,93 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#ifndef QWT_ANALOG_CLOCK_H +#define QWT_ANALOG_CLOCK_H + +#include "qwt_global.h" +#include "qwt_dial.h" +#include "qwt_dial_needle.h" +#include + +/*! + \brief An analog clock + + \image html analogclock.png + + \par Example + \code + #include + + QwtAnalogClock *clock = new QwtAnalogClock(...); + clock->scaleDraw()->setPenWidth(3); + clock->setLineWidth(6); + clock->setFrameShadow(QwtDial::Sunken); + clock->setTime(); + + // update the clock every second + QTimer *timer = new QTimer(clock); + timer->connect(timer, SIGNAL(timeout()), clock, SLOT(setCurrentTime())); + timer->start(1000); + + \endcode + + \note The examples/dials example shows how to use QwtAnalogClock. +*/ + +class QWT_EXPORT QwtAnalogClock: public QwtDial +{ + Q_OBJECT + +public: + /*! + Hand type + \sa setHand(), hand() + */ + enum Hand + { + //! Needle displaying the seconds + SecondHand, + + //! Needle displaying the minutes + MinuteHand, + + //! Needle displaying the hours + HourHand, + + //! Number of needles + NHands + }; + + explicit QwtAnalogClock( QWidget* parent = NULL ); + virtual ~QwtAnalogClock(); + + void setHand( Hand, QwtDialNeedle * ); + + const QwtDialNeedle *hand( Hand ) const; + QwtDialNeedle *hand( Hand ); + +public Q_SLOTS: + void setCurrentTime(); + void setTime( const QTime & ); + +protected: + virtual void drawNeedle( QPainter *, const QPointF &, + double radius, double direction, QPalette::ColorGroup ) const; + + virtual void drawHand( QPainter *, Hand, const QPointF &, + double radius, double direction, QPalette::ColorGroup ) const; + +private: + // use setHand instead + void setNeedle( QwtDialNeedle * ); + + QwtDialNeedle *d_hand[NHands]; +}; + +#endif diff --git a/ThirdParty/Qwt/src/qwt_arrow_button.cpp b/ThirdParty/Qwt/src/qwt_arrow_button.cpp new file mode 100644 index 0000000000..bd20f91e9c --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_arrow_button.cpp @@ -0,0 +1,333 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#include "qwt_arrow_button.h" +#include "qwt_math.h" +#include +#include +#include +#include +#include + +static const int MaxNum = 3; +static const int Margin = 2; +static const int Spacing = 1; + +class QwtArrowButton::PrivateData +{ +public: + int num; + Qt::ArrowType arrowType; +}; + +static QStyleOptionButton styleOpt( const QwtArrowButton* btn ) +{ + QStyleOptionButton option; + option.init( btn ); + option.features = QStyleOptionButton::None; + if ( btn->isFlat() ) + option.features |= QStyleOptionButton::Flat; + if ( btn->menu() ) + option.features |= QStyleOptionButton::HasMenu; + if ( btn->autoDefault() || btn->isDefault() ) + option.features |= QStyleOptionButton::AutoDefaultButton; + if ( btn->isDefault() ) + option.features |= QStyleOptionButton::DefaultButton; + if ( btn->isDown() ) + option.state |= QStyle::State_Sunken; + if ( !btn->isFlat() && !btn->isDown() ) + option.state |= QStyle::State_Raised; + + return option; +} + +/*! + \param num Number of arrows + \param arrowType see Qt::ArrowType in the Qt docs. + \param parent Parent widget +*/ +QwtArrowButton::QwtArrowButton( int num, + Qt::ArrowType arrowType, QWidget *parent ): + QPushButton( parent ) +{ + d_data = new PrivateData; + d_data->num = qBound( 1, num, MaxNum ); + d_data->arrowType = arrowType; + + setAutoRepeat( true ); + setAutoDefault( false ); + + switch ( d_data->arrowType ) + { + case Qt::LeftArrow: + case Qt::RightArrow: + setSizePolicy( QSizePolicy::Expanding, + QSizePolicy::Fixed ); + break; + default: + setSizePolicy( QSizePolicy::Fixed, + QSizePolicy::Expanding ); + } +} + +//! Destructor +QwtArrowButton::~QwtArrowButton() +{ + delete d_data; + d_data = NULL; +} + +/*! + \brief The direction of the arrows +*/ +Qt::ArrowType QwtArrowButton::arrowType() const +{ + return d_data->arrowType; +} + +/*! + \brief The number of arrows +*/ +int QwtArrowButton::num() const +{ + return d_data->num; +} + +/*! + \return the bounding rectangle for the label +*/ +QRect QwtArrowButton::labelRect() const +{ + const int m = Margin; + + QRect r = rect(); + r.setRect( r.x() + m, r.y() + m, + r.width() - 2 * m, r.height() - 2 * m ); + + if ( isDown() ) + { + QStyleOptionButton option = styleOpt( this ); + const int ph = style()->pixelMetric( + QStyle::PM_ButtonShiftHorizontal, &option, this ); + const int pv = style()->pixelMetric( + QStyle::PM_ButtonShiftVertical, &option, this ); + + r.translate( ph, pv ); + } + + return r; +} + +/*! + Paint event handler + \param event Paint event +*/ +void QwtArrowButton::paintEvent( QPaintEvent *event ) +{ + QPushButton::paintEvent( event ); + QPainter painter( this ); + drawButtonLabel( &painter ); +} + +/*! + \brief Draw the button label + + \param painter Painter + \sa The Qt Manual for QPushButton +*/ +void QwtArrowButton::drawButtonLabel( QPainter *painter ) +{ + const bool isVertical = d_data->arrowType == Qt::UpArrow || + d_data->arrowType == Qt::DownArrow; + + const QRect r = labelRect(); + QSize boundingSize = labelRect().size(); + if ( isVertical ) + boundingSize.transpose(); + + const int w = + ( boundingSize.width() - ( MaxNum - 1 ) * Spacing ) / MaxNum; + + QSize arrow = arrowSize( Qt::RightArrow, + QSize( w, boundingSize.height() ) ); + + if ( isVertical ) + arrow.transpose(); + + QRect contentsSize; // aligned rect where to paint all arrows + if ( d_data->arrowType == Qt::LeftArrow || d_data->arrowType == Qt::RightArrow ) + { + contentsSize.setWidth( d_data->num * arrow.width() + + ( d_data->num - 1 ) * Spacing ); + contentsSize.setHeight( arrow.height() ); + } + else + { + contentsSize.setWidth( arrow.width() ); + contentsSize.setHeight( d_data->num * arrow.height() + + ( d_data->num - 1 ) * Spacing ); + } + + QRect arrowRect( contentsSize ); + arrowRect.moveCenter( r.center() ); + arrowRect.setSize( arrow ); + + painter->save(); + for ( int i = 0; i < d_data->num; i++ ) + { + drawArrow( painter, arrowRect, d_data->arrowType ); + + int dx = 0; + int dy = 0; + + if ( isVertical ) + dy = arrow.height() + Spacing; + else + dx = arrow.width() + Spacing; + + arrowRect.translate( dx, dy ); + } + painter->restore(); + + if ( hasFocus() ) + { + QStyleOptionFocusRect option; + option.init( this ); + option.backgroundColor = palette().color( QPalette::Window ); + + style()->drawPrimitive( QStyle::PE_FrameFocusRect, + &option, painter, this ); + } +} + +/*! + Draw an arrow int a bounding rectangle + + \param painter Painter + \param r Rectangle where to paint the arrow + \param arrowType Arrow type +*/ +void QwtArrowButton::drawArrow( QPainter *painter, + const QRect &r, Qt::ArrowType arrowType ) const +{ + QPolygon pa( 3 ); + + switch ( arrowType ) + { + case Qt::UpArrow: + pa.setPoint( 0, r.bottomLeft() ); + pa.setPoint( 1, r.bottomRight() ); + pa.setPoint( 2, r.center().x(), r.top() ); + break; + case Qt::DownArrow: + pa.setPoint( 0, r.topLeft() ); + pa.setPoint( 1, r.topRight() ); + pa.setPoint( 2, r.center().x(), r.bottom() ); + break; + case Qt::RightArrow: + pa.setPoint( 0, r.topLeft() ); + pa.setPoint( 1, r.bottomLeft() ); + pa.setPoint( 2, r.right(), r.center().y() ); + break; + case Qt::LeftArrow: + pa.setPoint( 0, r.topRight() ); + pa.setPoint( 1, r.bottomRight() ); + pa.setPoint( 2, r.left(), r.center().y() ); + break; + default: + break; + } + + painter->save(); + + painter->setRenderHint( QPainter::Antialiasing, true ); + painter->setPen( Qt::NoPen ); + painter->setBrush( palette().brush( QPalette::ButtonText ) ); + painter->drawPolygon( pa ); + + painter->restore(); +} + +/*! + \return a size hint +*/ +QSize QwtArrowButton::sizeHint() const +{ + const QSize hint = minimumSizeHint(); + return hint.expandedTo( QApplication::globalStrut() ); +} + +/*! + \brief Return a minimum size hint +*/ +QSize QwtArrowButton::minimumSizeHint() const +{ + const QSize asz = arrowSize( Qt::RightArrow, QSize() ); + + QSize sz( + 2 * Margin + ( MaxNum - 1 ) * Spacing + MaxNum * asz.width(), + 2 * Margin + asz.height() + ); + + if ( d_data->arrowType == Qt::UpArrow || d_data->arrowType == Qt::DownArrow ) + sz.transpose(); + + QStyleOption styleOption; + styleOption.init( this ); + + sz = style()->sizeFromContents( QStyle::CT_PushButton, + &styleOption, sz, this ); + + return sz; +} + +/*! + Calculate the size for a arrow that fits into a rectangle of a given size + + \param arrowType Arrow type + \param boundingSize Bounding size + \return Size of the arrow +*/ +QSize QwtArrowButton::arrowSize( Qt::ArrowType arrowType, + const QSize &boundingSize ) const +{ + QSize bs = boundingSize; + if ( arrowType == Qt::UpArrow || arrowType == Qt::DownArrow ) + bs.transpose(); + + const int MinLen = 2; + const QSize sz = bs.expandedTo( + QSize( MinLen, 2 * MinLen - 1 ) ); // minimum + + int w = sz.width(); + int h = 2 * w - 1; + + if ( h > sz.height() ) + { + h = sz.height(); + w = ( h + 1 ) / 2; + } + + QSize arrSize( w, h ); + if ( arrowType == Qt::UpArrow || arrowType == Qt::DownArrow ) + arrSize.transpose(); + + return arrSize; +} + +/*! + \brief autoRepeat for the space keys +*/ +void QwtArrowButton::keyPressEvent( QKeyEvent *event ) +{ + if ( event->isAutoRepeat() && event->key() == Qt::Key_Space ) + Q_EMIT clicked(); + + QPushButton::keyPressEvent( event ); +} diff --git a/ThirdParty/Qwt/src/qwt_arrow_button.h b/ThirdParty/Qwt/src/qwt_arrow_button.h new file mode 100644 index 0000000000..ae436fec0f --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_arrow_button.h @@ -0,0 +1,52 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#ifndef QWT_ARROW_BUTTON_H +#define QWT_ARROW_BUTTON_H + +#include "qwt_global.h" +#include + +/*! + \brief Arrow Button + + A push button with one or more filled triangles on its front. + An Arrow button can have 1 to 3 arrows in a row, pointing + up, down, left or right. +*/ +class QWT_EXPORT QwtArrowButton : public QPushButton +{ +public: + explicit QwtArrowButton ( int num, Qt::ArrowType, QWidget *parent = NULL ); + virtual ~QwtArrowButton(); + + Qt::ArrowType arrowType() const; + int num() const; + + virtual QSize sizeHint() const; + virtual QSize minimumSizeHint() const; + +protected: + virtual void paintEvent( QPaintEvent *event ); + + virtual void drawButtonLabel( QPainter *p ); + virtual void drawArrow( QPainter *, + const QRect &, Qt::ArrowType ) const; + virtual QRect labelRect() const; + virtual QSize arrowSize( Qt::ArrowType, + const QSize &boundingSize ) const; + + virtual void keyPressEvent( QKeyEvent * ); + +private: + class PrivateData; + PrivateData *d_data; +}; + +#endif diff --git a/ThirdParty/Qwt/src/qwt_clipper.cpp b/ThirdParty/Qwt/src/qwt_clipper.cpp new file mode 100644 index 0000000000..51614aa37f --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_clipper.cpp @@ -0,0 +1,510 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#include "qwt_clipper.h" +#include "qwt_point_polar.h" +#include +#include +#include + +#if QT_VERSION < 0x040601 +#define qAtan(x) ::atan(x) +#endif + +namespace QwtClip +{ + // some templates used for inlining + template class LeftEdge; + template class RightEdge; + template class TopEdge; + template class BottomEdge; + + template class PointBuffer; +} + +template +class QwtClip::LeftEdge +{ +public: + inline LeftEdge( Value x1, Value, Value, Value ): + d_x1( x1 ) + { + } + + inline bool isInside( const Point &p ) const + { + return p.x() >= d_x1; + } + + inline Point intersection( const Point &p1, const Point &p2 ) const + { + double dy = ( p1.y() - p2.y() ) / double( p1.x() - p2.x() ); + return Point( d_x1, static_cast< Value >( p2.y() + ( d_x1 - p2.x() ) * dy ) ); + } +private: + const Value d_x1; +}; + +template +class QwtClip::RightEdge +{ +public: + inline RightEdge( Value, Value x2, Value, Value ): + d_x2( x2 ) + { + } + + inline bool isInside( const Point &p ) const + { + return p.x() <= d_x2; + } + + inline Point intersection( const Point &p1, const Point &p2 ) const + { + double dy = ( p1.y() - p2.y() ) / double( p1.x() - p2.x() ); + return Point( d_x2, static_cast( p2.y() + ( d_x2 - p2.x() ) * dy ) ); + } + +private: + const Value d_x2; +}; + +template +class QwtClip::TopEdge +{ +public: + inline TopEdge( Value, Value, Value y1, Value ): + d_y1( y1 ) + { + } + + inline bool isInside( const Point &p ) const + { + return p.y() >= d_y1; + } + + inline Point intersection( const Point &p1, const Point &p2 ) const + { + double dx = ( p1.x() - p2.x() ) / double( p1.y() - p2.y() ); + return Point( static_cast( p2.x() + ( d_y1 - p2.y() ) * dx ), d_y1 ); + } + +private: + const Value d_y1; +}; + +template +class QwtClip::BottomEdge +{ +public: + inline BottomEdge( Value, Value, Value, Value y2 ): + d_y2( y2 ) + { + } + + inline bool isInside( const Point &p ) const + { + return p.y() <= d_y2; + } + + inline Point intersection( const Point &p1, const Point &p2 ) const + { + double dx = ( p1.x() - p2.x() ) / double( p1.y() - p2.y() ); + return Point( static_cast( p2.x() + ( d_y2 - p2.y() ) * dx ), d_y2 ); + } + +private: + const Value d_y2; +}; + +template +class QwtClip::PointBuffer +{ +public: + PointBuffer( int capacity = 0 ): + m_capacity( 0 ), + m_size( 0 ), + m_buffer( NULL ) + { + if ( capacity > 0 ) + reserve( capacity ); + } + + ~PointBuffer() + { + if ( m_buffer ) + ::free( m_buffer ); + } + + inline void setPoints( int numPoints, const Point *points ) + { + reserve( numPoints ); + + m_size = numPoints; + ::memcpy( m_buffer, points, m_size * sizeof( Point ) ); + } + + inline void reset() + { + m_size = 0; + } + + inline int size() const + { + return m_size; + } + + inline Point *data() const + { + return m_buffer; + } + + inline Point &operator[]( int i ) + { + return m_buffer[i]; + } + + inline const Point &operator[]( int i ) const + { + return m_buffer[i]; + } + + inline void add( const Point &point ) + { + if ( m_capacity <= m_size ) + reserve( m_size + 1 ); + + m_buffer[m_size++] = point; + } + +private: + inline void reserve( int size ) + { + if ( m_capacity == 0 ) + m_capacity = 1; + + while ( m_capacity < size ) + m_capacity *= 2; + + m_buffer = static_cast( + ::realloc( m_buffer, m_capacity * sizeof( Point ) ) ); + } + + int m_capacity; + int m_size; + Point *m_buffer; +}; + +using namespace QwtClip; + +template +class QwtPolygonClipper +{ +public: + QwtPolygonClipper( const Rect &clipRect ): + d_clipRect( clipRect ) + { + } + + Polygon clipPolygon( const Polygon &polygon, bool closePolygon ) const + { +#if 0 + if ( d_clipRect.contains( polygon.boundingRect() ) ) + return polygon; +#endif + + PointBuffer points1; + PointBuffer points2( qMin( 256, polygon.size() ) ); + + points1.setPoints( polygon.size(), polygon.data() ); + + clipEdge< LeftEdge >( closePolygon, points1, points2 ); + clipEdge< RightEdge >( closePolygon, points2, points1 ); + clipEdge< TopEdge >( closePolygon, points1, points2 ); + clipEdge< BottomEdge >( closePolygon, points2, points1 ); + + Polygon p; + p.resize( points1.size() ); + ::memcpy( p.data(), points1.data(), points1.size() * sizeof( Point ) ); + + return p; + } + +private: + template + inline void clipEdge( bool closePolygon, + PointBuffer &points, PointBuffer &clippedPoints ) const + { + clippedPoints.reset(); + + if ( points.size() < 2 ) + { + if ( points.size() == 1 ) + clippedPoints.add( points[0] ); + return; + } + + const Edge edge( d_clipRect.x(), d_clipRect.x() + d_clipRect.width(), + d_clipRect.y(), d_clipRect.y() + d_clipRect.height() ); + + int lastPos, start; + if ( closePolygon ) + { + start = 0; + lastPos = points.size() - 1; + } + else + { + start = 1; + lastPos = 0; + + if ( edge.isInside( points[0] ) ) + clippedPoints.add( points[0] ); + } + + const uint nPoints = points.size(); + for ( uint i = start; i < nPoints; i++ ) + { + const Point &p1 = points[i]; + const Point &p2 = points[lastPos]; + + if ( edge.isInside( p1 ) ) + { + if ( edge.isInside( p2 ) ) + { + clippedPoints.add( p1 ); + } + else + { + clippedPoints.add( edge.intersection( p1, p2 ) ); + clippedPoints.add( p1 ); + } + } + else + { + if ( edge.isInside( p2 ) ) + { + clippedPoints.add( edge.intersection( p1, p2 ) ); + } + } + lastPos = i; + } + } + + const Rect d_clipRect; +}; + +class QwtCircleClipper +{ +public: + QwtCircleClipper( const QRectF &r ); + QVector clipCircle( const QPointF &, double radius ) const; + +private: + enum Edge + { + Left, + Top, + Right, + Bottom, + + NEdges + }; + + QList cuttingPoints( + Edge, const QPointF &pos, double radius ) const; + + double toAngle( const QPointF &, const QPointF & ) const; + + const QRectF d_rect; +}; + + +QwtCircleClipper::QwtCircleClipper( const QRectF &r ): + d_rect( r ) +{ +} + +QVector QwtCircleClipper::clipCircle( + const QPointF &pos, double radius ) const +{ + QList points; + for ( int edge = 0; edge < NEdges; edge++ ) + points += cuttingPoints( static_cast(edge), pos, radius ); + + QVector intv; + if ( points.size() <= 0 ) + { + QRectF cRect( 0, 0, 2 * radius, 2 * radius ); + cRect.moveCenter( pos ); + if ( d_rect.contains( cRect ) ) + intv += QwtInterval( 0.0, 2 * M_PI ); + } + else + { + QList angles; + for ( int i = 0; i < points.size(); i++ ) + angles += toAngle( pos, points[i] ); + qSort( angles ); + + const int in = d_rect.contains( qwtPolar2Pos( pos, radius, + angles[0] + ( angles[1] - angles[0] ) / 2 ) ); + + if ( in ) + { + for ( int i = 0; i < angles.size() - 1; i += 2 ) + intv += QwtInterval( angles[i], angles[i+1] ); + } + else + { + for ( int i = 1; i < angles.size() - 1; i += 2 ) + intv += QwtInterval( angles[i], angles[i+1] ); + intv += QwtInterval( angles.last(), angles.first() ); + } + } + + return intv; +} + +double QwtCircleClipper::toAngle( + const QPointF &from, const QPointF &to ) const +{ + if ( from.x() == to.x() ) + return from.y() <= to.y() ? M_PI / 2.0 : 3 * M_PI / 2.0; + + const double m = qAbs( ( to.y() - from.y() ) / ( to.x() - from.x() ) ); + + double angle = qAtan( m ); + if ( to.x() > from.x() ) + { + if ( to.y() > from.y() ) + angle = 2 * M_PI - angle; + } + else + { + if ( to.y() > from.y() ) + angle = M_PI + angle; + else + angle = M_PI - angle; + } + + return angle; +} + +QList QwtCircleClipper::cuttingPoints( + Edge edge, const QPointF &pos, double radius ) const +{ + QList points; + + if ( edge == Left || edge == Right ) + { + const double x = ( edge == Left ) ? d_rect.left() : d_rect.right(); + if ( qAbs( pos.x() - x ) < radius ) + { + const double off = qSqrt( qwtSqr( radius ) - qwtSqr( pos.x() - x ) ); + const double m_y1 = pos.y() + off; + if ( m_y1 >= d_rect.top() && m_y1 <= d_rect.bottom() ) + points += QPointF( x, m_y1 ); + + const double m_y2 = pos.y() - off; + if ( m_y2 >= d_rect.top() && m_y2 <= d_rect.bottom() ) + points += QPointF( x, m_y2 ); + } + } + else + { + const double y = ( edge == Top ) ? d_rect.top() : d_rect.bottom(); + if ( qAbs( pos.y() - y ) < radius ) + { + const double off = qSqrt( qwtSqr( radius ) - qwtSqr( pos.y() - y ) ); + const double x1 = pos.x() + off; + if ( x1 >= d_rect.left() && x1 <= d_rect.right() ) + points += QPointF( x1, y ); + + const double m_x2 = pos.x() - off; + if ( m_x2 >= d_rect.left() && m_x2 <= d_rect.right() ) + points += QPointF( m_x2, y ); + } + } + return points; +} + +/*! + Sutherland-Hodgman polygon clipping + + \param clipRect Clip rectangle + \param polygon Polygon + \param closePolygon True, when the polygon is closed + + \return Clipped polygon +*/ +QPolygon QwtClipper::clipPolygon( + const QRectF &clipRect, const QPolygon &polygon, bool closePolygon ) +{ + const int minX = qCeil( clipRect.left() ); + const int maxX = qFloor( clipRect.right() ); + const int minY = qCeil( clipRect.top() ); + const int maxY = qFloor( clipRect.bottom() ); + + const QRect r( minX, minY, maxX - minX, maxY - minY ); + + QwtPolygonClipper clipper( r ); + return clipper.clipPolygon( polygon, closePolygon ); +} +/*! + Sutherland-Hodgman polygon clipping + + \param clipRect Clip rectangle + \param polygon Polygon + \param closePolygon True, when the polygon is closed + + \return Clipped polygon +*/ +QPolygon QwtClipper::clipPolygon( + const QRect &clipRect, const QPolygon &polygon, bool closePolygon ) +{ + QwtPolygonClipper clipper( clipRect ); + return clipper.clipPolygon( polygon, closePolygon ); +} + +/*! + Sutherland-Hodgman polygon clipping + + \param clipRect Clip rectangle + \param polygon Polygon + \param closePolygon True, when the polygon is closed + + \return Clipped polygon +*/ +QPolygonF QwtClipper::clipPolygonF( + const QRectF &clipRect, const QPolygonF &polygon, bool closePolygon ) +{ + QwtPolygonClipper clipper( clipRect ); + return clipper.clipPolygon( polygon, closePolygon ); +} + +/*! + Circle clipping + + clipCircle() divides a circle into intervals of angles representing arcs + of the circle. When the circle is completely inside the clip rectangle + an interval [0.0, 2 * M_PI] is returned. + + \param clipRect Clip rectangle + \param center Center of the circle + \param radius Radius of the circle + + \return Arcs of the circle +*/ +QVector QwtClipper::clipCircle( const QRectF &clipRect, + const QPointF ¢er, double radius ) +{ + QwtCircleClipper clipper( clipRect ); + return clipper.clipCircle( center, radius ); +} diff --git a/ThirdParty/Qwt/src/qwt_clipper.h b/ThirdParty/Qwt/src/qwt_clipper.h new file mode 100644 index 0000000000..1b1820bb02 --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_clipper.h @@ -0,0 +1,40 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#ifndef QWT_CLIPPER_H +#define QWT_CLIPPER_H + +#include "qwt_global.h" +#include "qwt_interval.h" +#include +#include + +class QRect; +class QRectF; + +/*! + \brief Some clipping algorithms +*/ + +class QWT_EXPORT QwtClipper +{ +public: + static QPolygon clipPolygon( const QRect &, + const QPolygon &, bool closePolygon = false ); + static QPolygon clipPolygon( const QRectF &, + const QPolygon &, bool closePolygon = false ); + + static QPolygonF clipPolygonF( const QRectF &, + const QPolygonF &, bool closePolygon = false ); + + static QVector clipCircle( + const QRectF &, const QPointF &, double radius ); +}; + +#endif diff --git a/ThirdParty/Qwt/src/qwt_color_map.cpp b/ThirdParty/Qwt/src/qwt_color_map.cpp new file mode 100644 index 0000000000..571c1380dd --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_color_map.cpp @@ -0,0 +1,444 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#include "qwt_color_map.h" +#include "qwt_math.h" +#include "qwt_interval.h" +#include + +class QwtLinearColorMap::ColorStops +{ +public: + ColorStops() + { + _stops.reserve( 256 ); + } + + void insert( double pos, const QColor &color ); + QRgb rgb( QwtLinearColorMap::Mode, double pos ) const; + + QVector stops() const; + +private: + + class ColorStop + { + public: + ColorStop(): + pos( 0.0 ), + rgb( 0 ) + { + }; + + ColorStop( double p, const QColor &c ): + pos( p ), + rgb( c.rgb() ) + { + r = qRed( rgb ); + g = qGreen( rgb ); + b = qBlue( rgb ); + } + + double pos; + QRgb rgb; + int r, g, b; + }; + + inline int findUpper( double pos ) const; + QVector _stops; +}; + +void QwtLinearColorMap::ColorStops::insert( double pos, const QColor &color ) +{ + // Lookups need to be very fast, insertions are not so important. + // Anyway, a balanced tree is what we need here. TODO ... + + if ( pos < 0.0 || pos > 1.0 ) + return; + + int index; + if ( _stops.size() == 0 ) + { + index = 0; + _stops.resize( 1 ); + } + else + { + index = findUpper( pos ); + if ( index == _stops.size() || + qAbs( _stops[index].pos - pos ) >= 0.001 ) + { + _stops.resize( _stops.size() + 1 ); + for ( int i = _stops.size() - 1; i > index; i-- ) + _stops[i] = _stops[i-1]; + } + } + + _stops[index] = ColorStop( pos, color ); +} + +inline QVector QwtLinearColorMap::ColorStops::stops() const +{ + QVector positions( _stops.size() ); + for ( int i = 0; i < _stops.size(); i++ ) + positions[i] = _stops[i].pos; + return positions; +} + +inline int QwtLinearColorMap::ColorStops::findUpper( double pos ) const +{ + int index = 0; + int n = _stops.size(); + + const ColorStop *stops = _stops.data(); + + while ( n > 0 ) + { + const int half = n >> 1; + const int middle = index + half; + + if ( stops[middle].pos <= pos ) + { + index = middle + 1; + n -= half + 1; + } + else + n = half; + } + + return index; +} + +inline QRgb QwtLinearColorMap::ColorStops::rgb( + QwtLinearColorMap::Mode mode, double pos ) const +{ + if ( pos <= 0.0 ) + return _stops[0].rgb; + if ( pos >= 1.0 ) + return _stops[ _stops.size() - 1 ].rgb; + + const int index = findUpper( pos ); + if ( mode == FixedColors ) + { + return _stops[index-1].rgb; + } + else + { + const ColorStop &s1 = _stops[index-1]; + const ColorStop &s2 = _stops[index]; + + const double ratio = ( pos - s1.pos ) / ( s2.pos - s1.pos ); + + const int r = s1.r + qRound( ratio * ( s2.r - s1.r ) ); + const int g = s1.g + qRound( ratio * ( s2.g - s1.g ) ); + const int b = s1.b + qRound( ratio * ( s2.b - s1.b ) ); + + return qRgb( r, g, b ); + } +} + +//! Constructor +QwtColorMap::QwtColorMap( Format format ): + d_format( format ) +{ +} + +//! Destructor +QwtColorMap::~QwtColorMap() +{ +} + +/*! + Build and return a color map of 256 colors + + The color table is needed for rendering indexed images in combination + with using colorIndex(). + + \param interval Range for the values + \return A color table, that can be used for a QImage +*/ +QVector QwtColorMap::colorTable( const QwtInterval &interval ) const +{ + QVector table( 256 ); + + if ( interval.isValid() ) + { + const double step = interval.width() / ( table.size() - 1 ); + for ( int i = 0; i < table.size(); i++ ) + table[i] = rgb( interval, interval.minValue() + step * i ); + } + + return table; +} + +class QwtLinearColorMap::PrivateData +{ +public: + ColorStops colorStops; + QwtLinearColorMap::Mode mode; +}; + +/*! + Build a color map with two stops at 0.0 and 1.0. The color + at 0.0 is Qt::blue, at 1.0 it is Qt::yellow. + + \param format Preferred format of the color map +*/ +QwtLinearColorMap::QwtLinearColorMap( QwtColorMap::Format format ): + QwtColorMap( format ) +{ + d_data = new PrivateData; + d_data->mode = ScaledColors; + + setColorInterval( Qt::blue, Qt::yellow ); +} + +/*! + Build a color map with two stops at 0.0 and 1.0. + + \param color1 Color used for the minimum value of the value interval + \param color2 Color used for the maximum value of the value interval + \param format Preferred format for the color map +*/ +QwtLinearColorMap::QwtLinearColorMap( const QColor &color1, + const QColor &color2, QwtColorMap::Format format ): + QwtColorMap( format ) +{ + d_data = new PrivateData; + d_data->mode = ScaledColors; + setColorInterval( color1, color2 ); +} + +//! Destructor +QwtLinearColorMap::~QwtLinearColorMap() +{ + delete d_data; +} + +/*! + \brief Set the mode of the color map + + FixedColors means the color is calculated from the next lower + color stop. ScaledColors means the color is calculated + by interpolating the colors of the adjacent stops. + + \sa mode() +*/ +void QwtLinearColorMap::setMode( Mode mode ) +{ + d_data->mode = mode; +} + +/*! + \return Mode of the color map + \sa setMode() +*/ +QwtLinearColorMap::Mode QwtLinearColorMap::mode() const +{ + return d_data->mode; +} + +/*! + Set the color range + + Add stops at 0.0 and 1.0. + + \param color1 Color used for the minimum value of the value interval + \param color2 Color used for the maximum value of the value interval + + \sa color1(), color2() +*/ +void QwtLinearColorMap::setColorInterval( + const QColor &color1, const QColor &color2 ) +{ + d_data->colorStops = ColorStops(); + d_data->colorStops.insert( 0.0, color1 ); + d_data->colorStops.insert( 1.0, color2 ); +} + +/*! + Add a color stop + + The value has to be in the range [0.0, 1.0]. + F.e. a stop at position 17.0 for a range [10.0,20.0] must be + passed as: (17.0 - 10.0) / (20.0 - 10.0) + + \param value Value between [0.0, 1.0] + \param color Color stop +*/ +void QwtLinearColorMap::addColorStop( double value, const QColor& color ) +{ + if ( value >= 0.0 && value <= 1.0 ) + d_data->colorStops.insert( value, color ); +} + +/*! + \return Positions of color stops in increasing order +*/ +QVector QwtLinearColorMap::colorStops() const +{ + return d_data->colorStops.stops(); +} + +/*! + \return the first color of the color range + \sa setColorInterval() +*/ +QColor QwtLinearColorMap::color1() const +{ + return QColor( d_data->colorStops.rgb( d_data->mode, 0.0 ) ); +} + +/*! + \return the second color of the color range + \sa setColorInterval() +*/ +QColor QwtLinearColorMap::color2() const +{ + return QColor( d_data->colorStops.rgb( d_data->mode, 1.0 ) ); +} + +/*! + Map a value of a given interval into a RGB value + + \param interval Range for all values + \param value Value to map into a RGB value + + \return RGB value for value +*/ +QRgb QwtLinearColorMap::rgb( + const QwtInterval &interval, double value ) const +{ + if ( qIsNaN(value) ) + return qRgba(0, 0, 0, 0); + + const double width = interval.width(); + + double ratio = 0.0; + if ( width > 0.0 ) + ratio = ( value - interval.minValue() ) / width; + + return d_data->colorStops.rgb( d_data->mode, ratio ); +} + +/*! + \brief Map a value of a given interval into a color index + + \param interval Range for all values + \param value Value to map into a color index + + \return Index, between 0 and 255 +*/ +unsigned char QwtLinearColorMap::colorIndex( + const QwtInterval &interval, double value ) const +{ + const double width = interval.width(); + + if ( qIsNaN(value) || width <= 0.0 || value <= interval.minValue() ) + return 0; + + if ( value >= interval.maxValue() ) + return 255; + + const double ratio = ( value - interval.minValue() ) / width; + + unsigned char index; + if ( d_data->mode == FixedColors ) + index = static_cast( ratio * 255 ); // always floor + else + index = static_cast( qRound( ratio * 255 ) ); + + return index; +} + +class QwtAlphaColorMap::PrivateData +{ +public: + QColor color; + QRgb rgb; +}; + + +/*! + Constructor + \param color Color of the map +*/ +QwtAlphaColorMap::QwtAlphaColorMap( const QColor &color ): + QwtColorMap( QwtColorMap::RGB ) +{ + d_data = new PrivateData; + d_data->color = color; + d_data->rgb = color.rgb() & qRgba( 255, 255, 255, 0 ); +} + +//! Destructor +QwtAlphaColorMap::~QwtAlphaColorMap() +{ + delete d_data; +} + +/*! + Set the color + + \param color Color + \sa color() +*/ +void QwtAlphaColorMap::setColor( const QColor &color ) +{ + d_data->color = color; + d_data->rgb = color.rgb(); +} + +/*! + \return the color + \sa setColor() +*/ +QColor QwtAlphaColorMap::color() const +{ + return d_data->color; +} + +/*! + \brief Map a value of a given interval into a alpha value + + alpha := (value - interval.minValue()) / interval.width(); + + \param interval Range for all values + \param value Value to map into a RGB value + \return RGB value, with an alpha value +*/ +QRgb QwtAlphaColorMap::rgb( const QwtInterval &interval, double value ) const +{ + const double width = interval.width(); + if ( !qIsNaN(value) && width >= 0.0 ) + { + const double ratio = ( value - interval.minValue() ) / width; + int alpha = qRound( 255 * ratio ); + if ( alpha < 0 ) + alpha = 0; + if ( alpha > 255 ) + alpha = 255; + + return d_data->rgb | ( alpha << 24 ); + } + return d_data->rgb; +} + +/*! + Dummy function, needed to be implemented as it is pure virtual + in QwtColorMap. Color indices make no sense in combination with + an alpha channel. + + \return Always 0 +*/ +unsigned char QwtAlphaColorMap::colorIndex( + const QwtInterval &, double ) const +{ + return 0; +} diff --git a/ThirdParty/Qwt/src/qwt_color_map.h b/ThirdParty/Qwt/src/qwt_color_map.h new file mode 100644 index 0000000000..91a92bd0cc --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_color_map.h @@ -0,0 +1,200 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#ifndef QWT_COLOR_MAP_H +#define QWT_COLOR_MAP_H + +#include "qwt_global.h" +#include "qwt_interval.h" +#include +#include + +/*! + \brief QwtColorMap is used to map values into colors. + + For displaying 3D data on a 2D plane the 3rd dimension is often + displayed using colors, like f.e in a spectrogram. + + Each color map is optimized to return colors for only one of the + following image formats: + + - QImage::Format_Indexed8\n + - QImage::Format_ARGB32\n + + \sa QwtPlotSpectrogram, QwtScaleWidget +*/ + +class QWT_EXPORT QwtColorMap +{ +public: + /*! + Format for color mapping + \sa rgb(), colorIndex(), colorTable() + */ + + enum Format + { + //! The map is intended to map into RGB values. + RGB, + + /*! + The map is intended to map into 8 bit values, that + are indices into the color table. + */ + Indexed + }; + + QwtColorMap( Format = QwtColorMap::RGB ); + virtual ~QwtColorMap(); + + Format format() const; + + /*! + Map a value of a given interval into a RGB value. + + \param interval Range for the values + \param value Value + \return RGB value, corresponding to value + */ + virtual QRgb rgb( const QwtInterval &interval, + double value ) const = 0; + + /*! + Map a value of a given interval into a color index + + \param interval Range for the values + \param value Value + \return color index, corresponding to value + */ + virtual unsigned char colorIndex( + const QwtInterval &interval, double value ) const = 0; + + QColor color( const QwtInterval &, double value ) const; + virtual QVector colorTable( const QwtInterval & ) const; + +private: + Format d_format; +}; + +/*! + \brief QwtLinearColorMap builds a color map from color stops. + + A color stop is a color at a specific position. The valid + range for the positions is [0.0, 1.0]. When mapping a value + into a color it is translated into this interval according to mode(). +*/ +class QWT_EXPORT QwtLinearColorMap: public QwtColorMap +{ +public: + /*! + Mode of color map + \sa setMode(), mode() + */ + enum Mode + { + //! Return the color from the next lower color stop + FixedColors, + + //! Interpolating the colors of the adjacent stops. + ScaledColors + }; + + QwtLinearColorMap( QwtColorMap::Format = QwtColorMap::RGB ); + QwtLinearColorMap( const QColor &from, const QColor &to, + QwtColorMap::Format = QwtColorMap::RGB ); + + virtual ~QwtLinearColorMap(); + + void setMode( Mode ); + Mode mode() const; + + void setColorInterval( const QColor &color1, const QColor &color2 ); + void addColorStop( double value, const QColor& ); + QVector colorStops() const; + + QColor color1() const; + QColor color2() const; + + virtual QRgb rgb( const QwtInterval &, double value ) const; + virtual unsigned char colorIndex( + const QwtInterval &, double value ) const; + + class ColorStops; + +private: + // Disabled copy constructor and operator= + QwtLinearColorMap( const QwtLinearColorMap & ); + QwtLinearColorMap &operator=( const QwtLinearColorMap & ); + + class PrivateData; + PrivateData *d_data; +}; + +/*! + \brief QwtAlphaColorMap varies the alpha value of a color +*/ +class QWT_EXPORT QwtAlphaColorMap: public QwtColorMap +{ +public: + QwtAlphaColorMap( const QColor & = QColor( Qt::gray ) ); + virtual ~QwtAlphaColorMap(); + + void setColor( const QColor & ); + QColor color() const; + + virtual QRgb rgb( const QwtInterval &, double value ) const; + +private: + QwtAlphaColorMap( const QwtAlphaColorMap & ); + QwtAlphaColorMap &operator=( const QwtAlphaColorMap & ); + + virtual unsigned char colorIndex( + const QwtInterval &, double value ) const; + + class PrivateData; + PrivateData *d_data; +}; + + +/*! + Map a value into a color + + \param interval Valid interval for values + \param value Value + + \return Color corresponding to value + + \warning This method is slow for Indexed color maps. If it is + necessary to map many values, its better to get the + color table once and find the color using colorIndex(). +*/ +inline QColor QwtColorMap::color( + const QwtInterval &interval, double value ) const +{ + if ( d_format == RGB ) + { + return QColor( rgb( interval, value ) ); + } + else + { + const unsigned int index = colorIndex( interval, value ); + return colorTable( interval )[index]; // slow + } +} + +/*! + \return Intended format of the color map + \sa Format +*/ +inline QwtColorMap::Format QwtColorMap::format() const +{ + return d_format; +} + +#endif diff --git a/ThirdParty/Qwt/src/qwt_column_symbol.cpp b/ThirdParty/Qwt/src/qwt_column_symbol.cpp new file mode 100644 index 0000000000..d6f0f1a635 --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_column_symbol.cpp @@ -0,0 +1,293 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#include "qwt_column_symbol.h" +#include "qwt_math.h" +#include "qwt_painter.h" +#include +#include + +static void qwtDrawBox( QPainter *p, const QRectF &rect, + const QPalette &pal, double lw ) +{ + if ( lw > 0.0 ) + { + if ( rect.width() == 0.0 ) + { + p->setPen( pal.dark().color() ); + p->drawLine( rect.topLeft(), rect.bottomLeft() ); + return; + } + + if ( rect.height() == 0.0 ) + { + p->setPen( pal.dark().color() ); + p->drawLine( rect.topLeft(), rect.topRight() ); + return; + } + + lw = qMin( lw, rect.height() / 2.0 - 1.0 ); + lw = qMin( lw, rect.width() / 2.0 - 1.0 ); + + const QRectF outerRect = rect.adjusted( 0, 0, 1, 1 ); + QPolygonF polygon( outerRect ); + + if ( outerRect.width() > 2 * lw && + outerRect.height() > 2 * lw ) + { + const QRectF innerRect = outerRect.adjusted( lw, lw, -lw, -lw ); + polygon = polygon.subtracted( innerRect ); + } + + p->setPen( Qt::NoPen ); + + p->setBrush( pal.dark() ); + p->drawPolygon( polygon ); + } + + const QRectF windowRect = rect.adjusted( lw, lw, -lw + 1, -lw + 1 ); + if ( windowRect.isValid() ) + p->fillRect( windowRect, pal.window() ); +} + +static void qwtDrawPanel( QPainter *painter, const QRectF &rect, + const QPalette &pal, double lw ) +{ + if ( lw > 0.0 ) + { + if ( rect.width() == 0.0 ) + { + painter->setPen( pal.window().color() ); + painter->drawLine( rect.topLeft(), rect.bottomLeft() ); + return; + } + + if ( rect.height() == 0.0 ) + { + painter->setPen( pal.window().color() ); + painter->drawLine( rect.topLeft(), rect.topRight() ); + return; + } + + lw = qMin( lw, rect.height() / 2.0 - 1.0 ); + lw = qMin( lw, rect.width() / 2.0 - 1.0 ); + + const QRectF outerRect = rect.adjusted( 0, 0, 1, 1 ); + const QRectF innerRect = outerRect.adjusted( lw, lw, -lw, -lw ); + + QPolygonF lines[2]; + + lines[0] += outerRect.bottomLeft(); + lines[0] += outerRect.topLeft(); + lines[0] += outerRect.topRight(); + lines[0] += innerRect.topRight(); + lines[0] += innerRect.topLeft(); + lines[0] += innerRect.bottomLeft(); + + lines[1] += outerRect.topRight(); + lines[1] += outerRect.bottomRight(); + lines[1] += outerRect.bottomLeft(); + lines[1] += innerRect.bottomLeft(); + lines[1] += innerRect.bottomRight(); + lines[1] += innerRect.topRight(); + + painter->setPen( Qt::NoPen ); + + painter->setBrush( pal.light() ); + painter->drawPolygon( lines[0] ); + painter->setBrush( pal.dark() ); + painter->drawPolygon( lines[1] ); + } + + painter->fillRect( rect.adjusted( lw, lw, -lw + 1, -lw + 1 ), pal.window() ); +} + +class QwtColumnSymbol::PrivateData +{ +public: + PrivateData(): + style( QwtColumnSymbol::Box ), + frameStyle( QwtColumnSymbol::Raised ), + lineWidth( 2 ) + { + palette = QPalette( Qt::gray ); + } + + QwtColumnSymbol::Style style; + QwtColumnSymbol::FrameStyle frameStyle; + + QPalette palette; + int lineWidth; +}; + +/*! + Constructor + + \param style Style of the symbol + \sa setStyle(), style(), Style +*/ +QwtColumnSymbol::QwtColumnSymbol( Style style ) +{ + d_data = new PrivateData(); + d_data->style = style; +} + +//! Destructor +QwtColumnSymbol::~QwtColumnSymbol() +{ + delete d_data; +} + +/*! + Specify the symbol style + + \param style Style + \sa style(), setPalette() +*/ +void QwtColumnSymbol::setStyle( Style style ) +{ + d_data->style = style; +} + +/*! + \return Current symbol style + \sa setStyle() +*/ +QwtColumnSymbol::Style QwtColumnSymbol::style() const +{ + return d_data->style; +} + +/*! + Assign a palette for the symbol + + \param palette Palette + \sa palette(), setStyle() +*/ +void QwtColumnSymbol::setPalette( const QPalette &palette ) +{ + d_data->palette = palette; +} + +/*! + \return Current palette + \sa setPalette() +*/ +const QPalette& QwtColumnSymbol::palette() const +{ + return d_data->palette; +} + +/*! + Set the frame, that is used for the Box style. + + \param frameStyle Frame style + \sa frameStyle(), setLineWidth(), setStyle() +*/ +void QwtColumnSymbol::setFrameStyle( FrameStyle frameStyle ) +{ + d_data->frameStyle = frameStyle; +} + +/*! + \return Current frame style, that is used for the Box style. + \sa setFrameStyle(), lineWidth(), setStyle() +*/ +QwtColumnSymbol::FrameStyle QwtColumnSymbol::frameStyle() const +{ + return d_data->frameStyle; +} + +/*! + Set the line width of the frame, that is used for the Box style. + + \param width Width + \sa lineWidth(), setFrameStyle() +*/ +void QwtColumnSymbol::setLineWidth( int width ) +{ + if ( width < 0 ) + width = 0; + + d_data->lineWidth = width; +} + +/*! + \return Line width of the frame, that is used for the Box style. + \sa setLineWidth(), frameStyle(), setStyle() +*/ +int QwtColumnSymbol::lineWidth() const +{ + return d_data->lineWidth; +} + +/*! + Draw the symbol depending on its style. + + \param painter Painter + \param rect Directed rectangle + + \sa drawBox() +*/ +void QwtColumnSymbol::draw( QPainter *painter, + const QwtColumnRect &rect ) const +{ + painter->save(); + + switch ( d_data->style ) + { + case QwtColumnSymbol::Box: + { + drawBox( painter, rect ); + break; + } + default:; + } + + painter->restore(); +} + +/*! + Draw the symbol when it is in Box style. + + \param painter Painter + \param rect Directed rectangle + + \sa draw() +*/ +void QwtColumnSymbol::drawBox( QPainter *painter, + const QwtColumnRect &rect ) const +{ + QRectF r = rect.toRect(); + if ( QwtPainter::roundingAlignment( painter ) ) + { + r.setLeft( qRound( r.left() ) ); + r.setRight( qRound( r.right() ) ); + r.setTop( qRound( r.top() ) ); + r.setBottom( qRound( r.bottom() ) ); + } + + switch ( d_data->frameStyle ) + { + case QwtColumnSymbol::Raised: + { + qwtDrawPanel( painter, r, d_data->palette, d_data->lineWidth ); + break; + } + case QwtColumnSymbol::Plain: + { + qwtDrawBox( painter, r, d_data->palette, d_data->lineWidth ); + break; + } + default: + { + painter->fillRect( r, d_data->palette.window() ); + } + } +} diff --git a/ThirdParty/Qwt/src/qwt_column_symbol.h b/ThirdParty/Qwt/src/qwt_column_symbol.h new file mode 100644 index 0000000000..918fe4a3cc --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_column_symbol.h @@ -0,0 +1,161 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#ifndef QWT_COLUMN_SYMBOL_H +#define QWT_COLUMN_SYMBOL_H + +#include "qwt_global.h" +#include "qwt_interval.h" +#include +#include +#include + +class QPainter; +class QPalette; +class QRect; +class QwtText; + +/*! + \brief Directed rectangle representing bounding rectangle and orientation + of a column. +*/ +class QWT_EXPORT QwtColumnRect +{ +public: + //! Direction of the column + enum Direction + { + //! From left to right + LeftToRight, + + //! From right to left + RightToLeft, + + //! From bottom to top + BottomToTop, + + //! From top to bottom + TopToBottom + }; + + //! Build an rectangle with invalid intervals directed BottomToTop. + QwtColumnRect(): + direction( BottomToTop ) + { + } + + //! \return A normalized QRect built from the intervals + QRectF toRect() const + { + QRectF r( hInterval.minValue(), vInterval.minValue(), + hInterval.maxValue() - hInterval.minValue(), + vInterval.maxValue() - vInterval.minValue() ); + r = r.normalized(); + + if ( hInterval.borderFlags() & QwtInterval::ExcludeMinimum ) + r.adjust( 1, 0, 0, 0 ); + if ( hInterval.borderFlags() & QwtInterval::ExcludeMaximum ) + r.adjust( 0, 0, -1, 0 ); + if ( vInterval.borderFlags() & QwtInterval::ExcludeMinimum ) + r.adjust( 0, 1, 0, 0 ); + if ( vInterval.borderFlags() & QwtInterval::ExcludeMaximum ) + r.adjust( 0, 0, 0, -1 ); + + return r; + } + + //! \return Orientation + Qt::Orientation orientation() const + { + if ( direction == LeftToRight || direction == RightToLeft ) + return Qt::Horizontal; + + return Qt::Vertical; + } + + //! Interval for the horizontal coordinates + QwtInterval hInterval; + + //! Interval for the vertical coordinates + QwtInterval vInterval; + + //! Direction + Direction direction; +}; + +//! A drawing primitive for columns +class QWT_EXPORT QwtColumnSymbol +{ +public: + /*! + Style + \sa setStyle(), style() + */ + enum Style + { + //! No Style, the symbol draws nothing + NoStyle = -1, + + /*! + The column is painted with a frame depending on the frameStyle() + and lineWidth() using the palette(). + */ + Box, + + /*! + Styles >= QwtColumnSymbol::UserStyle are reserved for derived + classes of QwtColumnSymbol that overload draw() with + additional application specific symbol types. + */ + UserStyle = 1000 + }; + + /*! + Frame Style used in Box style(). + \sa Style, setFrameStyle(), frameStyle(), setStyle(), setPalette() + */ + enum FrameStyle + { + //! No frame + NoFrame, + + //! A plain frame style + Plain, + + //! A raised frame style + Raised + }; + +public: + QwtColumnSymbol( Style = NoStyle ); + virtual ~QwtColumnSymbol(); + + void setFrameStyle( FrameStyle style ); + FrameStyle frameStyle() const; + + void setLineWidth( int width ); + int lineWidth() const; + + void setPalette( const QPalette & ); + const QPalette &palette() const; + + void setStyle( Style ); + Style style() const; + + virtual void draw( QPainter *, const QwtColumnRect & ) const; + +protected: + void drawBox( QPainter *, const QwtColumnRect & ) const; + +private: + class PrivateData; + PrivateData* d_data; +}; + +#endif diff --git a/ThirdParty/Qwt/src/qwt_compass.cpp b/ThirdParty/Qwt/src/qwt_compass.cpp new file mode 100644 index 0000000000..4e2c9ffdf5 --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_compass.cpp @@ -0,0 +1,308 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#include "qwt_compass.h" +#include "qwt_compass_rose.h" +#include "qwt_math.h" +#include "qwt_scale_draw.h" +#include "qwt_painter.h" +#include "qwt_dial_needle.h" +#include +#include +#include + +/*! + \brief Constructor + + Initializes a label map for multiples of 45 degrees + */ +QwtCompassScaleDraw::QwtCompassScaleDraw() +{ + enableComponent( QwtAbstractScaleDraw::Backbone, false ); + enableComponent( QwtAbstractScaleDraw::Ticks, false ); + + d_labelMap.insert( 0.0, QString::fromLatin1( "N" ) ); + d_labelMap.insert( 45.0, QString::fromLatin1( "NE" ) ); + d_labelMap.insert( 90.0, QString::fromLatin1( "E" ) ); + d_labelMap.insert( 135.0, QString::fromLatin1( "SE" ) ); + d_labelMap.insert( 180.0, QString::fromLatin1( "S" ) ); + d_labelMap.insert( 225.0, QString::fromLatin1( "SW" ) ); + d_labelMap.insert( 270.0, QString::fromLatin1( "W" ) ); + d_labelMap.insert( 315.0, QString::fromLatin1( "NW" ) ); + +#if 0 + d_labelMap.insert( 22.5, QString::fromLatin1( "NNE" ) ); + d_labelMap.insert( 67.5, QString::fromLatin1( "NEE" ) ); + d_labelMap.insert( 112.5, QString::fromLatin1( "SEE" ) ); + d_labelMap.insert( 157.5, QString::fromLatin1( "SSE" ) ); + d_labelMap.insert( 202.5, QString::fromLatin1( "SSW" ) ); + d_labelMap.insert( 247.5, QString::fromLatin1( "SWW" ) ); + d_labelMap.insert( 292.5, QString::fromLatin1( "NWW" ) ); + d_labelMap.insert( 337.5, QString::fromLatin1( "NNW" ) ); +#endif +} + +/*! + \brief Constructor + + \param map Value to label map + */ +QwtCompassScaleDraw::QwtCompassScaleDraw( const QMap &map ): + d_labelMap( map ) +{ + enableComponent( QwtAbstractScaleDraw::Backbone, false ); + enableComponent( QwtAbstractScaleDraw::Ticks, false ); +} + +/*! + \brief Set a map, mapping values to labels + \param map Value to label map + + The values of the major ticks are found by looking into this + map. The default map consists of the labels N, NE, E, SE, S, SW, W, NW. + + \warning The map will have no effect for values that are no major + tick values. Major ticks can be changed by QwtScaleDraw::setScale + + \sa labelMap(), scaleDraw(), setScale() +*/ +void QwtCompassScaleDraw::setLabelMap( const QMap &map ) +{ + d_labelMap = map; +} + + +/*! + \return map, mapping values to labels + \sa setLabelMap() +*/ +QMap QwtCompassScaleDraw::labelMap() const +{ + return d_labelMap; +} + +/*! + Map a value to a corresponding label + + \param value Value that will be mapped + + label() looks in the labelMap() for a corresponding label for value + or returns an null text. + + \return Label, or QString::null + \sa labelMap(), setLabelMap() +*/ + +QwtText QwtCompassScaleDraw::label( double value ) const +{ + if ( qFuzzyCompare( value + 1.0, 1.0 ) ) + value = 0.0; + + if ( value < 0.0 ) + value += 360.0; + + if ( d_labelMap.contains( value ) ) + return d_labelMap[value]; + + return QwtText(); +} + +class QwtCompass::PrivateData +{ +public: + PrivateData(): + rose( NULL ) + { + } + + ~PrivateData() + { + delete rose; + } + + QwtCompassRose *rose; +}; + +/*! + \brief Constructor + \param parent Parent widget + + Create a compass widget with a scale, no needle and no rose. + The default origin is 270.0 with no valid value. It accepts + mouse and keyboard inputs and has no step size. The default mode + is QwtDial::RotateNeedle. +*/ +QwtCompass::QwtCompass( QWidget* parent ): + QwtDial( parent ) +{ + d_data = new PrivateData; + + setScaleDraw( new QwtCompassScaleDraw() ); + + setOrigin( 270.0 ); + setWrapping( true ); + + setScaleMaxMajor( 36 ); + setScaleMaxMinor( 10 ); + + setScale( 0.0, 360.0 ); // degrees as default + setTotalSteps( 360 ); +} + +//! Destructor +QwtCompass::~QwtCompass() +{ + delete d_data; +} + + +/*! + Draw the contents of the scale + + \param painter Painter + \param center Center of the content circle + \param radius Radius of the content circle +*/ +void QwtCompass::drawScaleContents( QPainter *painter, + const QPointF ¢er, double radius ) const +{ + QPalette::ColorGroup cg; + if ( isEnabled() ) + cg = hasFocus() ? QPalette::Active : QPalette::Inactive; + else + cg = QPalette::Disabled; + + double north = origin(); + if ( isValid() ) + { + if ( mode() == RotateScale ) + north -= value(); + } + + const int margin = 4; + drawRose( painter, center, radius - margin, 360.0 - north, cg ); +} + +/*! + Draw the compass rose + + \param painter Painter + \param center Center of the compass + \param radius of the circle, where to paint the rose + \param north Direction pointing north, in degrees counter clockwise + \param cg Color group +*/ +void QwtCompass::drawRose( QPainter *painter, const QPointF ¢er, + double radius, double north, QPalette::ColorGroup cg ) const +{ + if ( d_data->rose ) + d_data->rose->draw( painter, center, radius, north, cg ); +} + +/*! + Set a rose for the compass + \param rose Compass rose + \warning The rose will be deleted, when a different rose is + set or in ~QwtCompass + \sa rose() +*/ +void QwtCompass::setRose( QwtCompassRose *rose ) +{ + if ( rose != d_data->rose ) + { + if ( d_data->rose ) + delete d_data->rose; + + d_data->rose = rose; + update(); + } +} + +/*! + \return rose + \sa setRose() +*/ +const QwtCompassRose *QwtCompass::rose() const +{ + return d_data->rose; +} + +/*! + \return rose + \sa setRose() +*/ +QwtCompassRose *QwtCompass::rose() +{ + return d_data->rose; +} + +/*! + Handles key events + + Beside the keys described in QwtDial::keyPressEvent numbers + from 1-9 (without 5) set the direction according to their + position on the num pad. + + \sa isReadOnly() +*/ +void QwtCompass::keyPressEvent( QKeyEvent *kev ) +{ + if ( isReadOnly() ) + return; + +#if 0 + if ( kev->key() == Key_5 ) + { + invalidate(); // signal ??? + return; + } +#endif + + double newValue = value(); + + if ( kev->key() >= Qt::Key_1 && kev->key() <= Qt::Key_9 ) + { + if ( mode() != RotateNeedle || kev->key() == Qt::Key_5 ) + return; + + switch ( kev->key() ) + { + case Qt::Key_6: + newValue = 180.0 * 0.0; + break; + case Qt::Key_3: + newValue = 180.0 * 0.25; + break; + case Qt::Key_2: + newValue = 180.0 * 0.5; + break; + case Qt::Key_1: + newValue = 180.0 * 0.75; + break; + case Qt::Key_4: + newValue = 180.0 * 1.0; + break; + case Qt::Key_7: + newValue = 180.0 * 1.25; + break; + case Qt::Key_8: + newValue = 180.0 * 1.5; + break; + case Qt::Key_9: + newValue = 180.0 * 1.75; + break; + } + newValue -= origin(); + setValue( newValue ); + } + else + { + QwtDial::keyPressEvent( kev ); + } +} diff --git a/ThirdParty/Qwt/src/qwt_compass.h b/ThirdParty/Qwt/src/qwt_compass.h new file mode 100644 index 0000000000..b9a3c95bff --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_compass.h @@ -0,0 +1,83 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#ifndef QWT_COMPASS_H +#define QWT_COMPASS_H 1 + +#include "qwt_global.h" +#include "qwt_dial.h" +#include "qwt_round_scale_draw.h" +#include +#include + +class QwtCompassRose; + +/*! + \brief A special scale draw made for QwtCompass + + QwtCompassScaleDraw maps values to strings using + a special map, that can be modified by the application + + The default map consists of the labels N, NE, E, SE, S, SW, W, NW. + + \sa QwtCompass +*/ +class QWT_EXPORT QwtCompassScaleDraw: public QwtRoundScaleDraw +{ +public: + explicit QwtCompassScaleDraw(); + explicit QwtCompassScaleDraw( const QMap &map ); + + void setLabelMap( const QMap &map ); + QMap labelMap() const; + + virtual QwtText label( double value ) const; + +private: + QMap d_labelMap; +}; + +/*! + \brief A Compass Widget + + QwtCompass is a widget to display and enter directions. It consists + of a scale, an optional needle and rose. + + \image html dials1.png + + \note The examples/dials example shows how to use QwtCompass. +*/ + +class QWT_EXPORT QwtCompass: public QwtDial +{ + Q_OBJECT + +public: + explicit QwtCompass( QWidget* parent = NULL ); + virtual ~QwtCompass(); + + void setRose( QwtCompassRose *rose ); + const QwtCompassRose *rose() const; + QwtCompassRose *rose(); + +protected: + virtual void drawRose( QPainter *, const QPointF ¢er, + double radius, double north, QPalette::ColorGroup ) const; + + virtual void drawScaleContents( QPainter *, + const QPointF ¢er, double radius ) const; + + virtual void keyPressEvent( QKeyEvent * ); + +private: + class PrivateData; + PrivateData *d_data; +}; + +#endif diff --git a/ThirdParty/Qwt/src/qwt_compass_rose.cpp b/ThirdParty/Qwt/src/qwt_compass_rose.cpp new file mode 100644 index 0000000000..21a35f2444 --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_compass_rose.cpp @@ -0,0 +1,269 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#include "qwt_compass_rose.h" +#include "qwt_point_polar.h" +#include "qwt_painter.h" +#include + +static QPointF qwtIntersection( + QPointF p11, QPointF p12, QPointF p21, QPointF p22 ) +{ + const QLineF line1( p11, p12 ); + const QLineF line2( p21, p22 ); + + QPointF pos; + if ( line1.intersect( line2, &pos ) == QLineF::NoIntersection ) + return QPointF(); + + return pos; +} + +class QwtSimpleCompassRose::PrivateData +{ +public: + PrivateData(): + width( 0.2 ), + numThorns( 8 ), + numThornLevels( -1 ), + shrinkFactor( 0.9 ) + { + } + + double width; + int numThorns; + int numThornLevels; + double shrinkFactor; +}; + +/*! + Constructor + + \param numThorns Number of thorns + \param numThornLevels Number of thorn levels +*/ +QwtSimpleCompassRose::QwtSimpleCompassRose( + int numThorns, int numThornLevels ) +{ + d_data = new PrivateData(); + d_data->numThorns = numThorns; + d_data->numThornLevels = numThornLevels; + + const QColor dark( 128, 128, 255 ); + const QColor light( 192, 255, 255 ); + + QPalette palette; + palette.setColor( QPalette::Dark, dark ); + palette.setColor( QPalette::Light, light ); + + setPalette( palette ); +} + +//! Destructor +QwtSimpleCompassRose::~QwtSimpleCompassRose() +{ + delete d_data; +} + +/*! + Set the Factor how to shrink the thorns with each level + The default value is 0.9. + + \param factor Shrink factor + \sa shrinkFactor() +*/ +void QwtSimpleCompassRose::setShrinkFactor( double factor ) +{ + d_data->shrinkFactor = factor; +} + +/*! + \return Factor how to shrink the thorns with each level + \sa setShrinkFactor() +*/ +double QwtSimpleCompassRose::shrinkFactor() const +{ + return d_data->shrinkFactor; +} + +/*! + Draw the rose + + \param painter Painter + \param center Center point + \param radius Radius of the rose + \param north Position + \param cg Color group +*/ +void QwtSimpleCompassRose::draw( QPainter *painter, const QPointF ¢er, + double radius, double north, QPalette::ColorGroup cg ) const +{ + QPalette pal = palette(); + pal.setCurrentColorGroup( cg ); + + drawRose( painter, pal, center, radius, north, d_data->width, + d_data->numThorns, d_data->numThornLevels, d_data->shrinkFactor ); +} + +/*! + Draw the rose + + \param painter Painter + \param palette Palette + \param center Center of the rose + \param radius Radius of the rose + \param north Position pointing to north + \param width Width of the rose + \param numThorns Number of thorns + \param numThornLevels Number of thorn levels + \param shrinkFactor Factor to shrink the thorns with each level +*/ +void QwtSimpleCompassRose::drawRose( + QPainter *painter, + const QPalette &palette, + const QPointF ¢er, double radius, double north, double width, + int numThorns, int numThornLevels, double shrinkFactor ) +{ + if ( numThorns < 4 ) + numThorns = 4; + + if ( numThorns % 4 ) + numThorns += 4 - numThorns % 4; + + if ( numThornLevels <= 0 ) + numThornLevels = numThorns / 4; + + if ( shrinkFactor >= 1.0 ) + shrinkFactor = 1.0; + + if ( shrinkFactor <= 0.5 ) + shrinkFactor = 0.5; + + painter->save(); + + painter->setPen( Qt::NoPen ); + + for ( int j = 1; j <= numThornLevels; j++ ) + { + double step = qPow( 2.0, j ) * M_PI / numThorns; + if ( step > M_PI_2 ) + break; + + double r = radius; + for ( int k = 0; k < 3; k++ ) + { + if ( j + k < numThornLevels ) + r *= shrinkFactor; + } + + double leafWidth = r * width; + if ( 2.0 * M_PI / step > 32 ) + leafWidth = 16; + + const double origin = qwtRadians( north ); + for ( double angle = origin; + angle < 2.0 * M_PI + origin; angle += step ) + { + const QPointF p = qwtPolar2Pos( center, r, angle ); + const QPointF p1 = qwtPolar2Pos( center, leafWidth, angle + M_PI_2 ); + const QPointF p2 = qwtPolar2Pos( center, leafWidth, angle - M_PI_2 ); + const QPointF p3 = qwtPolar2Pos( center, r, angle + step / 2.0 ); + const QPointF p4 = qwtPolar2Pos( center, r, angle - step / 2.0 ); + + QPainterPath darkPath; + darkPath.moveTo( center ); + darkPath.lineTo( p ); + darkPath.lineTo( qwtIntersection( center, p3, p1, p ) ); + + painter->setBrush( palette.brush( QPalette::Dark ) ); + painter->drawPath( darkPath ); + + QPainterPath lightPath; + lightPath.moveTo( center ); + lightPath.lineTo( p ); + lightPath.lineTo( qwtIntersection( center, p4, p2, p ) ); + + painter->setBrush( palette.brush( QPalette::Light ) ); + painter->drawPath( lightPath ); + } + } + painter->restore(); +} + +/*! + Set the width of the rose heads. Lower value make thinner heads. + The range is limited from 0.03 to 0.4. + + \param width Width +*/ +void QwtSimpleCompassRose::setWidth( double width ) +{ + d_data->width = width; + if ( d_data->width < 0.03 ) + d_data->width = 0.03; + + if ( d_data->width > 0.4 ) + d_data->width = 0.4; +} + +/*! + \return Width of the rose + \sa setWidth() + */ +double QwtSimpleCompassRose::width() const +{ + return d_data->width; +} + +/*! + Set the number of thorns on one level + The number is aligned to a multiple of 4, with a minimum of 4 + + \param numThorns Number of thorns + \sa numThorns(), setNumThornLevels() +*/ +void QwtSimpleCompassRose::setNumThorns( int numThorns ) +{ + if ( numThorns < 4 ) + numThorns = 4; + + if ( numThorns % 4 ) + numThorns += 4 - numThorns % 4; + + d_data->numThorns = numThorns; +} + +/*! + \return Number of thorns + \sa setNumThorns(), setNumThornLevels() +*/ +int QwtSimpleCompassRose::numThorns() const +{ + return d_data->numThorns; +} + +/*! + Set the of thorns levels + + \param numThornLevels Number of thorns levels + \sa setNumThorns(), numThornLevels() +*/ +void QwtSimpleCompassRose::setNumThornLevels( int numThornLevels ) +{ + d_data->numThornLevels = numThornLevels; +} + +/*! + \return Number of thorn levels + \sa setNumThorns(), setNumThornLevels() +*/ +int QwtSimpleCompassRose::numThornLevels() const +{ + return d_data->numThornLevels; +} diff --git a/ThirdParty/Qwt/src/qwt_compass_rose.h b/ThirdParty/Qwt/src/qwt_compass_rose.h new file mode 100644 index 0000000000..9b715dfe02 --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_compass_rose.h @@ -0,0 +1,89 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#ifndef QWT_COMPASS_ROSE_H +#define QWT_COMPASS_ROSE_H 1 + +#include "qwt_global.h" +#include + +class QPainter; + +/*! + \brief Abstract base class for a compass rose +*/ +class QWT_EXPORT QwtCompassRose +{ +public: + //! Destructor + virtual ~QwtCompassRose() {}; + + //! Assign a palette + virtual void setPalette( const QPalette &p ) + { + d_palette = p; + } + + //! \return Current palette + const QPalette &palette() const + { + return d_palette; + } + + /*! + Draw the rose + + \param painter Painter + \param center Center point + \param radius Radius of the rose + \param north Position + \param colorGroup Color group + */ + virtual void draw( QPainter *painter, + const QPointF ¢er, double radius, double north, + QPalette::ColorGroup colorGroup = QPalette::Active ) const = 0; + +private: + QPalette d_palette; +}; + +/*! + \brief A simple rose for QwtCompass +*/ +class QWT_EXPORT QwtSimpleCompassRose: public QwtCompassRose +{ +public: + QwtSimpleCompassRose( int numThorns = 8, int numThornLevels = -1 ); + virtual ~QwtSimpleCompassRose(); + + void setWidth( double w ); + double width() const; + + void setNumThorns( int count ); + int numThorns() const; + + void setNumThornLevels( int count ); + int numThornLevels() const; + + void setShrinkFactor( double factor ); + double shrinkFactor() const; + + virtual void draw( QPainter *, const QPointF ¢er, double radius, + double north, QPalette::ColorGroup = QPalette::Active ) const; + + static void drawRose( QPainter *, const QPalette &, + const QPointF ¢er, double radius, double origin, double width, + int numThorns, int numThornLevels, double shrinkFactor ); + +private: + class PrivateData; + PrivateData *d_data; +}; + +#endif diff --git a/ThirdParty/Qwt/src/qwt_compat.h b/ThirdParty/Qwt/src/qwt_compat.h new file mode 100644 index 0000000000..c97cf6b9c8 --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_compat.h @@ -0,0 +1,42 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#ifndef _QWT_COMPAT_H_ +#define _QWT_COMPAT_H_ + +#include "qwt_global.h" +#include "qwt_interval.h" +#include "qwt_point_3d.h" +#include +#include +#include +#include +#include +#include + +// A couple of definition for Qwt5 compatibility + +#define qwtMax qMax +#define qwtMin qMin +#define qwtAbs qAbs +#define qwtRound qRound + +#define QwtArray QVector + +typedef QList QwtValueList; +typedef QPointF QwtDoublePoint; +typedef QSizeF QwtDoubleSize; +typedef QRectF QwtDoubleRect; + +typedef QPolygon QwtPolygon; +typedef QPolygonF QwtPolygonF; +typedef QwtInterval QwtDoubleInterval; +typedef QwtPoint3D QwtDoublePoint3D; + +#endif diff --git a/ThirdParty/Qwt/src/qwt_counter.cpp b/ThirdParty/Qwt/src/qwt_counter.cpp new file mode 100644 index 0000000000..192de117c7 --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_counter.cpp @@ -0,0 +1,776 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#include "qwt_arrow_button.h" +#include "qwt_math.h" +#include "qwt_counter.h" +#include +#include +#include +#include +#include + +class QwtCounter::PrivateData +{ +public: + PrivateData(): + minimum( 0.0 ), + maximum( 0.0 ), + singleStep( 1.0 ), + isValid( false ), + value( 0.0 ), + wrapping( false ) + { + increment[Button1] = 1; + increment[Button2] = 10; + increment[Button3] = 100; + } + + QwtArrowButton *buttonDown[ButtonCnt]; + QwtArrowButton *buttonUp[ButtonCnt]; + QLineEdit *valueEdit; + + int increment[ButtonCnt]; + int numButtons; + + double minimum; + double maximum; + double singleStep; + + bool isValid; + double value; + + bool wrapping; +}; + +/*! + The counter is initialized with a range is set to [0.0, 1.0] with + 0.01 as single step size. The value is invalid. + + The default number of buttons is set to 2. The default increments are: + \li Button 1: 1 step + \li Button 2: 10 steps + \li Button 3: 100 steps + + \param parent + */ +QwtCounter::QwtCounter( QWidget *parent ): + QWidget( parent ) +{ + initCounter(); +} + +void QwtCounter::initCounter() +{ + d_data = new PrivateData; + + QHBoxLayout *layout = new QHBoxLayout( this ); + layout->setSpacing( 0 ); + layout->setMargin( 0 ); + + for ( int i = ButtonCnt - 1; i >= 0; i-- ) + { + QwtArrowButton *btn = + new QwtArrowButton( i + 1, Qt::DownArrow, this ); + btn->setFocusPolicy( Qt::NoFocus ); + btn->installEventFilter( this ); + layout->addWidget( btn ); + + connect( btn, SIGNAL( released() ), SLOT( btnReleased() ) ); + connect( btn, SIGNAL( clicked() ), SLOT( btnClicked() ) ); + + d_data->buttonDown[i] = btn; + } + + d_data->valueEdit = new QLineEdit( this ); + d_data->valueEdit->setReadOnly( false ); + d_data->valueEdit->setValidator( new QDoubleValidator( d_data->valueEdit ) ); + layout->addWidget( d_data->valueEdit ); + + connect( d_data->valueEdit, SIGNAL( editingFinished() ), + SLOT( textChanged() ) ); + + layout->setStretchFactor( d_data->valueEdit, 10 ); + + for ( int i = 0; i < ButtonCnt; i++ ) + { + QwtArrowButton *btn = + new QwtArrowButton( i + 1, Qt::UpArrow, this ); + btn->setFocusPolicy( Qt::NoFocus ); + btn->installEventFilter( this ); + layout->addWidget( btn ); + + connect( btn, SIGNAL( released() ), SLOT( btnReleased() ) ); + connect( btn, SIGNAL( clicked() ), SLOT( btnClicked() ) ); + + d_data->buttonUp[i] = btn; + } + + setNumButtons( 2 ); + setRange( 0.0, 1.0 ); + setSingleStep( 0.001 ); + setValue( 0.0 ); + + setSizePolicy( + QSizePolicy( QSizePolicy::Preferred, QSizePolicy::Fixed ) ); + + setFocusProxy( d_data->valueEdit ); + setFocusPolicy( Qt::StrongFocus ); +} + +//! Destructor +QwtCounter::~QwtCounter() +{ + delete d_data; +} + +/*! + Set the counter to be in valid/invalid state + + When the counter is set to invalid, no numbers are displayed and + the buttons are disabled. + + \param on If true the counter will be set as valid + + \sa setValue(), isValid() +*/ +void QwtCounter::setValid( bool on ) +{ + if ( on != d_data->isValid ) + { + d_data->isValid = on; + + updateButtons(); + + if ( d_data->isValid ) + { + showNumber( value() ); + Q_EMIT valueChanged( value() ); + } + else + { + d_data->valueEdit->setText( QString::null ); + } + } +} + +/*! + \return True, if the value is valid + \sa setValid(), setValue() + */ +bool QwtCounter::isValid() const +{ + return d_data->isValid; +} + +/*! + \brief Allow/disallow the user to manually edit the value + + \param on True disable editing + \sa isReadOnly() +*/ +void QwtCounter::setReadOnly( bool on ) +{ + d_data->valueEdit->setReadOnly( on ); +} + +/*! + \return True, when the line line edit is read only. (default is no) + \sa setReadOnly() + */ +bool QwtCounter::isReadOnly() const +{ + return d_data->valueEdit->isReadOnly(); +} + +/*! + \brief Set a new value without adjusting to the step raster + + The state of the counter is set to be valid. + + \param value New value + + \sa isValid(), value(), valueChanged() + \warning The value is clipped when it lies outside the range. +*/ + +void QwtCounter::setValue( double value ) +{ + const double vmin = qMin( d_data->minimum, d_data->maximum ); + const double vmax = qMax( d_data->minimum, d_data->maximum ); + + value = qBound( vmin, value, vmax ); + + if ( !d_data->isValid || value != d_data->value ) + { + d_data->isValid = true; + d_data->value = value; + + showNumber( value ); + updateButtons(); + + Q_EMIT valueChanged( value ); + } +} + +/*! + \return Current value of the counter + \sa setValue(), valueChanged() + */ +double QwtCounter::value() const +{ + return d_data->value; +} + +/*! + \brief Set the minimum and maximum values + + The maximum is adjusted if necessary to ensure that the range remains valid. + The value might be modified to be inside of the range. + + \param min Minimum value + \param max Maximum value + + \sa minimum(), maximum() + */ +void QwtCounter::setRange( double min, double max ) +{ + max = qMax( min, max ); + + if ( d_data->maximum == max && d_data->minimum == min ) + return; + + d_data->minimum = min; + d_data->maximum = max; + + setSingleStep( singleStep() ); + + const double value = qBound( min, d_data->value, max ); + + if ( value != d_data->value ) + { + d_data->value = value; + + if ( d_data->isValid ) + { + showNumber( value ); + Q_EMIT valueChanged( value ); + } + } + + updateButtons(); +} + +/*! + Set the minimum value of the range + + \param value Minimum value + \sa setRange(), setMaximum(), minimum() + + \note The maximum is adjusted if necessary to ensure that the range remains valid. +*/ +void QwtCounter::setMinimum( double value ) +{ + setRange( value, maximum() ); +} + +/*! + \return The minimum of the range + \sa setRange(), setMinimum(), maximum() +*/ +double QwtCounter::minimum() const +{ + return d_data->minimum; +} + +/*! + Set the maximum value of the range + + \param value Maximum value + \sa setRange(), setMinimum(), maximum() +*/ +void QwtCounter::setMaximum( double value ) +{ + setRange( minimum(), value ); +} + +/*! + \return The maximum of the range + \sa setRange(), setMaximum(), minimum() +*/ +double QwtCounter::maximum() const +{ + return d_data->maximum; +} + +/*! + \brief Set the step size of the counter + + A value <= 0.0 disables stepping + + \param stepSize Single step size + \sa singleStep() +*/ +void QwtCounter::setSingleStep( double stepSize ) +{ + d_data->singleStep = qMax( stepSize, 0.0 ); +} + +/*! + \return Single step size + \sa setSingleStep() + */ +double QwtCounter::singleStep() const +{ + return d_data->singleStep; +} + +/*! + \brief En/Disable wrapping + + If wrapping is true stepping up from maximum() value will take + you to the minimum() value and vice versa. + + \param on En/Disable wrapping + \sa wrapping() + */ +void QwtCounter::setWrapping( bool on ) +{ + d_data->wrapping = on; +} + +/*! + \return True, when wrapping is set + \sa setWrapping() + */ +bool QwtCounter::wrapping() const +{ + return d_data->wrapping; +} + +/*! + Specify the number of buttons on each side of the label + + \param numButtons Number of buttons + \sa numButtons() +*/ +void QwtCounter::setNumButtons( int numButtons ) +{ + if ( numButtons < 0 || numButtons > QwtCounter::ButtonCnt ) + return; + + for ( int i = 0; i < QwtCounter::ButtonCnt; i++ ) + { + if ( i < numButtons ) + { + d_data->buttonDown[i]->show(); + d_data->buttonUp[i]->show(); + } + else + { + d_data->buttonDown[i]->hide(); + d_data->buttonUp[i]->hide(); + } + } + + d_data->numButtons = numButtons; +} + +/*! + \return The number of buttons on each side of the widget. + \sa setNumButtons() +*/ +int QwtCounter::numButtons() const +{ + return d_data->numButtons; +} + +/*! + Specify the number of steps by which the value + is incremented or decremented when a specified button + is pushed. + + \param button Button index + \param numSteps Number of steps + + \sa incSteps() +*/ +void QwtCounter::setIncSteps( QwtCounter::Button button, int numSteps ) +{ + if ( button >= 0 && button < QwtCounter::ButtonCnt ) + d_data->increment[ button ] = numSteps; +} + +/*! + \return The number of steps by which a specified button increments the value + or 0 if the button is invalid. + \param button Button index + + \sa setIncSteps() +*/ +int QwtCounter::incSteps( QwtCounter::Button button ) const +{ + if ( button >= 0 && button < QwtCounter::ButtonCnt ) + return d_data->increment[ button ]; + + return 0; +} + + +/*! + Set the number of increment steps for button 1 + \param nSteps Number of steps +*/ +void QwtCounter::setStepButton1( int nSteps ) +{ + setIncSteps( QwtCounter::Button1, nSteps ); +} + +//! returns the number of increment steps for button 1 +int QwtCounter::stepButton1() const +{ + return incSteps( QwtCounter::Button1 ); +} + +/*! + Set the number of increment steps for button 2 + \param nSteps Number of steps +*/ +void QwtCounter::setStepButton2( int nSteps ) +{ + setIncSteps( QwtCounter::Button2, nSteps ); +} + +//! returns the number of increment steps for button 2 +int QwtCounter::stepButton2() const +{ + return incSteps( QwtCounter::Button2 ); +} + +/*! + Set the number of increment steps for button 3 + \param nSteps Number of steps +*/ +void QwtCounter::setStepButton3( int nSteps ) +{ + setIncSteps( QwtCounter::Button3, nSteps ); +} + +//! returns the number of increment steps for button 3 +int QwtCounter::stepButton3() const +{ + return incSteps( QwtCounter::Button3 ); +} + +//! Set from lineedit +void QwtCounter::textChanged() +{ + bool converted = false; + + const double value = d_data->valueEdit->text().toDouble( &converted ); + if ( converted ) + setValue( value ); +} + +/*! + Handle QEvent::PolishRequest events + \param event Event + \return see QWidget::event() +*/ +bool QwtCounter::event( QEvent *event ) +{ + if ( event->type() == QEvent::PolishRequest ) + { + const int w = d_data->valueEdit->fontMetrics().width( "W" ) + 8; + for ( int i = 0; i < ButtonCnt; i++ ) + { + d_data->buttonDown[i]->setMinimumWidth( w ); + d_data->buttonUp[i]->setMinimumWidth( w ); + } + } + + return QWidget::event( event ); +} + +/*! + Handle key events + + - Ctrl + Qt::Key_Home\n + Step to minimum() + - Ctrl + Qt::Key_End\n + Step to maximum() + - Qt::Key_Up\n + Increment by incSteps(QwtCounter::Button1) + - Qt::Key_Down\n + Decrement by incSteps(QwtCounter::Button1) + - Qt::Key_PageUp\n + Increment by incSteps(QwtCounter::Button2) + - Qt::Key_PageDown\n + Decrement by incSteps(QwtCounter::Button2) + - Shift + Qt::Key_PageUp\n + Increment by incSteps(QwtCounter::Button3) + - Shift + Qt::Key_PageDown\n + Decrement by incSteps(QwtCounter::Button3) + + \param event Key event +*/ +void QwtCounter::keyPressEvent ( QKeyEvent *event ) +{ + bool accepted = true; + + switch ( event->key() ) + { + case Qt::Key_Home: + { + if ( event->modifiers() & Qt::ControlModifier ) + setValue( minimum() ); + else + accepted = false; + break; + } + case Qt::Key_End: + { + if ( event->modifiers() & Qt::ControlModifier ) + setValue( maximum() ); + else + accepted = false; + break; + } + case Qt::Key_Up: + { + incrementValue( d_data->increment[0] ); + break; + } + case Qt::Key_Down: + { + incrementValue( -d_data->increment[0] ); + break; + } + case Qt::Key_PageUp: + case Qt::Key_PageDown: + { + int increment = d_data->increment[0]; + if ( d_data->numButtons >= 2 ) + increment = d_data->increment[1]; + if ( d_data->numButtons >= 3 ) + { + if ( event->modifiers() & Qt::ShiftModifier ) + increment = d_data->increment[2]; + } + if ( event->key() == Qt::Key_PageDown ) + increment = -increment; + incrementValue( increment ); + break; + } + default: + { + accepted = false; + } + } + + if ( accepted ) + { + event->accept(); + return; + } + + QWidget::keyPressEvent ( event ); +} + +/*! + Handle wheel events + \param event Wheel event +*/ +void QwtCounter::wheelEvent( QWheelEvent *event ) +{ + event->accept(); + + if ( d_data->numButtons <= 0 ) + return; + + int increment = d_data->increment[0]; + if ( d_data->numButtons >= 2 ) + { + if ( event->modifiers() & Qt::ControlModifier ) + increment = d_data->increment[1]; + } + if ( d_data->numButtons >= 3 ) + { + if ( event->modifiers() & Qt::ShiftModifier ) + increment = d_data->increment[2]; + } + + for ( int i = 0; i < d_data->numButtons; i++ ) + { + if ( d_data->buttonDown[i]->geometry().contains( event->pos() ) || + d_data->buttonUp[i]->geometry().contains( event->pos() ) ) + { + increment = d_data->increment[i]; + } + } + + const int wheel_delta = 120; + +#if 1 + int delta = event->delta(); + if ( delta >= 2 * wheel_delta ) + delta /= 2; // Never saw an abs(delta) < 240 +#endif + + incrementValue( delta / wheel_delta * increment ); +} + +void QwtCounter::incrementValue( int numSteps ) +{ + const double min = d_data->minimum; + const double max = d_data->maximum; + double stepSize = d_data->singleStep; + + if ( !d_data->isValid || min >= max || stepSize <= 0.0 ) + return; + + +#if 1 + stepSize = qMax( stepSize, 1.0e-10 * ( max - min ) ); +#endif + + double value = d_data->value + numSteps * stepSize; + + if ( d_data->wrapping ) + { + const double range = max - min; + + if ( value < min ) + { + value += ::ceil( ( min - value ) / range ) * range; + } + else if ( value > max ) + { + value -= ::ceil( ( value - max ) / range ) * range; + } + } + else + { + value = qBound( min, value, max ); + } + + value = min + qRound( ( value - min ) / stepSize ) * stepSize; + if ( qFuzzyCompare( value, max ) ) + value = max; + + if ( qFuzzyCompare( value + 1.0, 1.0 ) ) + value = 0.0; + + if ( value != d_data->value ) + { + d_data->value = value; + showNumber( d_data->value ); + updateButtons(); + + Q_EMIT valueChanged( d_data->value ); + } +} + + +/*! + \brief Update buttons according to the current value + + When the QwtCounter under- or over-flows, the focus is set to the smallest + up- or down-button and counting is disabled. + + Counting is re-enabled on a button release event (mouse or space bar). +*/ +void QwtCounter::updateButtons() +{ + if ( d_data->isValid ) + { + // 1. save enabled state of the smallest down- and up-button + // 2. change enabled state on under- or over-flow + + for ( int i = 0; i < QwtCounter::ButtonCnt; i++ ) + { + d_data->buttonDown[i]->setEnabled( value() > minimum() ); + d_data->buttonUp[i]->setEnabled( value() < maximum() ); + } + } + else + { + for ( int i = 0; i < QwtCounter::ButtonCnt; i++ ) + { + d_data->buttonDown[i]->setEnabled( false ); + d_data->buttonUp[i]->setEnabled( false ); + } + } +} +/*! + Display number string + + \param number Number +*/ +void QwtCounter::showNumber( double number ) +{ + QString text; + text.setNum( number ); + + const int cursorPos = d_data->valueEdit->cursorPosition(); + d_data->valueEdit->setText( text ); + d_data->valueEdit->setCursorPosition( cursorPos ); +} + +//! Button clicked +void QwtCounter::btnClicked() +{ + for ( int i = 0; i < ButtonCnt; i++ ) + { + if ( d_data->buttonUp[i] == sender() ) + incrementValue( d_data->increment[i] ); + + if ( d_data->buttonDown[i] == sender() ) + incrementValue( -d_data->increment[i] ); + } +} + +//! Button released +void QwtCounter::btnReleased() +{ + Q_EMIT buttonReleased( value() ); +} + +//! A size hint +QSize QwtCounter::sizeHint() const +{ + QString tmp; + + int w = tmp.setNum( minimum() ).length(); + int w1 = tmp.setNum( maximum() ).length(); + if ( w1 > w ) + w = w1; + w1 = tmp.setNum( minimum() + singleStep() ).length(); + if ( w1 > w ) + w = w1; + w1 = tmp.setNum( maximum() - singleStep() ).length(); + if ( w1 > w ) + w = w1; + + tmp.fill( '9', w ); + + QFontMetrics fm( d_data->valueEdit->font() ); + w = fm.width( tmp ) + 2; + if ( d_data->valueEdit->hasFrame() ) + w += 2 * style()->pixelMetric( QStyle::PM_DefaultFrameWidth ); + + // Now we replace default sizeHint contribution of d_data->valueEdit by + // what we really need. + + w += QWidget::sizeHint().width() - d_data->valueEdit->sizeHint().width(); + + const int h = qMin( QWidget::sizeHint().height(), + d_data->valueEdit->minimumSizeHint().height() ); + return QSize( w, h ); +} diff --git a/ThirdParty/Qwt/src/qwt_counter.h b/ThirdParty/Qwt/src/qwt_counter.h new file mode 100644 index 0000000000..8799eddcac --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_counter.h @@ -0,0 +1,161 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#ifndef QWT_COUNTER_H +#define QWT_COUNTER_H + +#include "qwt_global.h" +#include + +/*! + \brief The Counter Widget + + A Counter consists of a label displaying a number and + one ore more (up to three) push buttons on each side + of the label which can be used to increment or decrement + the counter's value. + + A counter has a range from a minimum value to a maximum value + and a step size. When the wrapping property is set + the counter is circular. + + The number of steps by which a button increments or decrements the value + can be specified using setIncSteps(). The number of buttons can be + changed with setNumButtons(). + + Example: +\code +#include + +QwtCounter *counter = new QwtCounter(parent); + +counter->setRange(0.0, 100.0); // From 0.0 to 100 +counter->setSingleStep( 1.0 ); // Step size 1.0 +counter->setNumButtons(2); // Two buttons each side +counter->setIncSteps(QwtCounter::Button1, 1); // Button 1 increments 1 step +counter->setIncSteps(QwtCounter::Button2, 20); // Button 2 increments 20 steps + +connect(counter, SIGNAL(valueChanged(double)), myClass, SLOT(newValue(double))); +\endcode + */ + +class QWT_EXPORT QwtCounter : public QWidget +{ + Q_OBJECT + + Q_PROPERTY( double value READ value WRITE setValue ) + Q_PROPERTY( double minimum READ minimum WRITE setMinimum ) + Q_PROPERTY( double maximum READ maximum WRITE setMaximum ) + Q_PROPERTY( double singleStep READ singleStep WRITE setSingleStep ) + + Q_PROPERTY( int numButtons READ numButtons WRITE setNumButtons ) + Q_PROPERTY( int stepButton1 READ stepButton1 WRITE setStepButton1 ) + Q_PROPERTY( int stepButton2 READ stepButton2 WRITE setStepButton2 ) + Q_PROPERTY( int stepButton3 READ stepButton3 WRITE setStepButton3 ) + + Q_PROPERTY( bool readOnly READ isReadOnly WRITE setReadOnly ) + Q_PROPERTY( bool wrapping READ wrapping WRITE setWrapping ) + +public: + //! Button index + enum Button + { + //! Button intended for minor steps + Button1, + + //! Button intended for medium steps + Button2, + + //! Button intended for large steps + Button3, + + //! Number of buttons + ButtonCnt + }; + + explicit QwtCounter( QWidget *parent = NULL ); + virtual ~QwtCounter(); + + void setValid( bool ); + bool isValid() const; + + void setWrapping( bool ); + bool wrapping() const; + + bool isReadOnly() const; + void setReadOnly( bool ); + + void setNumButtons( int n ); + int numButtons() const; + + void setIncSteps( QwtCounter::Button btn, int nSteps ); + int incSteps( QwtCounter::Button btn ) const; + + virtual QSize sizeHint() const; + + double singleStep() const; + void setSingleStep( double s ); + + void setRange( double min, double max ); + + double minimum() const; + void setMinimum( double min ); + + double maximum() const; + void setMaximum( double max ); + + void setStepButton1( int nSteps ); + int stepButton1() const; + + void setStepButton2( int nSteps ); + int stepButton2() const; + + void setStepButton3( int nSteps ); + int stepButton3() const; + + double value() const; + +public Q_SLOTS: + void setValue( double ); + + +Q_SIGNALS: + /*! + This signal is emitted when a button has been released + \param value The new value + */ + void buttonReleased ( double value ); + + /*! + This signal is emitted when the counter's value has changed + \param value The new value + */ + void valueChanged ( double value ); + +protected: + virtual bool event( QEvent * ); + virtual void wheelEvent( QWheelEvent * ); + virtual void keyPressEvent( QKeyEvent * ); + +private Q_SLOTS: + void btnReleased(); + void btnClicked(); + void textChanged(); + +private: + void incrementValue( int numSteps ); + void initCounter(); + void updateButtons(); + void showNumber( double ); + + class PrivateData; + PrivateData *d_data; +}; + +#endif diff --git a/ThirdParty/Qwt/src/qwt_curve_fitter.cpp b/ThirdParty/Qwt/src/qwt_curve_fitter.cpp new file mode 100644 index 0000000000..5f09d5d8d0 --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_curve_fitter.cpp @@ -0,0 +1,453 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#include "qwt_curve_fitter.h" +#include "qwt_math.h" +#include "qwt_spline.h" +#include +#include + +#if QT_VERSION < 0x040601 +#define qFabs(x) ::fabs(x) +#endif + +//! Constructor +QwtCurveFitter::QwtCurveFitter() +{ +} + +//! Destructor +QwtCurveFitter::~QwtCurveFitter() +{ +} + +class QwtSplineCurveFitter::PrivateData +{ +public: + PrivateData(): + fitMode( QwtSplineCurveFitter::Auto ), + splineSize( 250 ) + { + } + + QwtSpline spline; + QwtSplineCurveFitter::FitMode fitMode; + int splineSize; +}; + +//! Constructor +QwtSplineCurveFitter::QwtSplineCurveFitter() +{ + d_data = new PrivateData; +} + +//! Destructor +QwtSplineCurveFitter::~QwtSplineCurveFitter() +{ + delete d_data; +} + +/*! + Select the algorithm used for building the spline + + \param mode Mode representing a spline algorithm + \sa fitMode() +*/ +void QwtSplineCurveFitter::setFitMode( FitMode mode ) +{ + d_data->fitMode = mode; +} + +/*! + \return Mode representing a spline algorithm + \sa setFitMode() +*/ +QwtSplineCurveFitter::FitMode QwtSplineCurveFitter::fitMode() const +{ + return d_data->fitMode; +} + +/*! + Assign a spline + + \param spline Spline + \sa spline() +*/ +void QwtSplineCurveFitter::setSpline( const QwtSpline &spline ) +{ + d_data->spline = spline; + d_data->spline.reset(); +} + +/*! + \return Spline + \sa setSpline() +*/ +const QwtSpline &QwtSplineCurveFitter::spline() const +{ + return d_data->spline; +} + +/*! + \return Spline + \sa setSpline() +*/ +QwtSpline &QwtSplineCurveFitter::spline() +{ + return d_data->spline; +} + +/*! + Assign a spline size ( has to be at least 10 points ) + + \param splineSize Spline size + \sa splineSize() +*/ +void QwtSplineCurveFitter::setSplineSize( int splineSize ) +{ + d_data->splineSize = qMax( splineSize, 10 ); +} + +/*! + \return Spline size + \sa setSplineSize() +*/ +int QwtSplineCurveFitter::splineSize() const +{ + return d_data->splineSize; +} + +/*! + Find a curve which has the best fit to a series of data points + + \param points Series of data points + \return Curve points +*/ +QPolygonF QwtSplineCurveFitter::fitCurve( const QPolygonF &points ) const +{ + const int size = points.size(); + if ( size <= 2 ) + return points; + + FitMode fitMode = d_data->fitMode; + if ( fitMode == Auto ) + { + fitMode = Spline; + + const QPointF *p = points.data(); + for ( int i = 1; i < size; i++ ) + { + if ( p[i].x() <= p[i-1].x() ) + { + fitMode = ParametricSpline; + break; + } + }; + } + + if ( fitMode == ParametricSpline ) + return fitParametric( points ); + else + return fitSpline( points ); +} + +QPolygonF QwtSplineCurveFitter::fitSpline( const QPolygonF &points ) const +{ + d_data->spline.setPoints( points ); + if ( !d_data->spline.isValid() ) + return points; + + QPolygonF fittedPoints( d_data->splineSize ); + + const double x1 = points[0].x(); + const double x2 = points[int( points.size() - 1 )].x(); + const double dx = x2 - x1; + const double delta = dx / ( d_data->splineSize - 1 ); + + for ( int i = 0; i < d_data->splineSize; i++ ) + { + QPointF &p = fittedPoints[i]; + + const double v = x1 + i * delta; + const double sv = d_data->spline.value( v ); + + p.setX( v ); + p.setY( sv ); + } + d_data->spline.reset(); + + return fittedPoints; +} + +QPolygonF QwtSplineCurveFitter::fitParametric( const QPolygonF &points ) const +{ + int i; + const int size = points.size(); + + QPolygonF fittedPoints( d_data->splineSize ); + QPolygonF splinePointsX( size ); + QPolygonF splinePointsY( size ); + + const QPointF *p = points.data(); + QPointF *spX = splinePointsX.data(); + QPointF *spY = splinePointsY.data(); + + double param = 0.0; + for ( i = 0; i < size; i++ ) + { + const double x = p[i].x(); + const double y = p[i].y(); + if ( i > 0 ) + { + const double delta = qSqrt( qwtSqr( x - spX[i-1].y() ) + + qwtSqr( y - spY[i-1].y() ) ); + param += qMax( delta, 1.0 ); + } + spX[i].setX( param ); + spX[i].setY( x ); + spY[i].setX( param ); + spY[i].setY( y ); + } + + d_data->spline.setPoints( splinePointsX ); + if ( !d_data->spline.isValid() ) + return points; + + const double deltaX = + splinePointsX[size - 1].x() / ( d_data->splineSize - 1 ); + for ( i = 0; i < d_data->splineSize; i++ ) + { + const double dtmp = i * deltaX; + fittedPoints[i].setX( d_data->spline.value( dtmp ) ); + } + + d_data->spline.setPoints( splinePointsY ); + if ( !d_data->spline.isValid() ) + return points; + + const double deltaY = + splinePointsY[size - 1].x() / ( d_data->splineSize - 1 ); + for ( i = 0; i < d_data->splineSize; i++ ) + { + const double dtmp = i * deltaY; + fittedPoints[i].setY( d_data->spline.value( dtmp ) ); + } + + return fittedPoints; +} + +class QwtWeedingCurveFitter::PrivateData +{ +public: + PrivateData(): + tolerance( 1.0 ), + chunkSize( 0 ) + { + } + + double tolerance; + uint chunkSize; +}; + +class QwtWeedingCurveFitter::Line +{ +public: + Line( int i1 = 0, int i2 = 0 ): + from( i1 ), + to( i2 ) + { + } + + int from; + int to; +}; + +/*! + Constructor + + \param tolerance Tolerance + \sa setTolerance(), tolerance() +*/ +QwtWeedingCurveFitter::QwtWeedingCurveFitter( double tolerance ) +{ + d_data = new PrivateData; + setTolerance( tolerance ); +} + +//! Destructor +QwtWeedingCurveFitter::~QwtWeedingCurveFitter() +{ + delete d_data; +} + +/*! + Assign the tolerance + + The tolerance is the maximum distance, that is acceptable + between the original curve and the smoothed curve. + + Increasing the tolerance will reduce the number of the + resulting points. + + \param tolerance Tolerance + + \sa tolerance() +*/ +void QwtWeedingCurveFitter::setTolerance( double tolerance ) +{ + d_data->tolerance = qMax( tolerance, 0.0 ); +} + +/*! + \return Tolerance + \sa setTolerance() +*/ +double QwtWeedingCurveFitter::tolerance() const +{ + return d_data->tolerance; +} + +/*! + Limit the number of points passed to a run of the algorithm + + The runtime of the Douglas Peucker algorithm increases non linear + with the number of points. For a chunk size > 0 the polygon + is split into pieces passed to the algorithm one by one. + + \param numPoints Maximum for the number of points passed to the algorithm + + \sa chunkSize() +*/ +void QwtWeedingCurveFitter::setChunkSize( uint numPoints ) +{ + if ( numPoints > 0 ) + numPoints = qMax( numPoints, 3U ); + + d_data->chunkSize = numPoints; +} + +/*! + + \return Maximum for the number of points passed to a run + of the algorithm - or 0, when unlimited + \sa setChunkSize() +*/ +uint QwtWeedingCurveFitter::chunkSize() const +{ + return d_data->chunkSize; +} + +/*! + \param points Series of data points + \return Curve points +*/ +QPolygonF QwtWeedingCurveFitter::fitCurve( const QPolygonF &points ) const +{ + QPolygonF fittedPoints; + + if ( d_data->chunkSize == 0 ) + { + fittedPoints = simplify( points ); + } + else + { + for ( int i = 0; i < points.size(); i += d_data->chunkSize ) + { + const QPolygonF p = points.mid( i, d_data->chunkSize ); + fittedPoints += simplify( p ); + } + } + + return fittedPoints; +} + +QPolygonF QwtWeedingCurveFitter::simplify( const QPolygonF &points ) const +{ + const double toleranceSqr = d_data->tolerance * d_data->tolerance; + + QStack stack; + stack.reserve( 500 ); + + const QPointF *p = points.data(); + const int nPoints = points.size(); + + QVector usePoint( nPoints, false ); + + stack.push( Line( 0, nPoints - 1 ) ); + + while ( !stack.isEmpty() ) + { + const Line r = stack.pop(); + + // initialize line segment + const double vecX = p[r.to].x() - p[r.from].x(); + const double vecY = p[r.to].y() - p[r.from].y(); + + const double vecLength = qSqrt( vecX * vecX + vecY * vecY ); + + const double unitVecX = ( vecLength != 0.0 ) ? vecX / vecLength : 0.0; + const double unitVecY = ( vecLength != 0.0 ) ? vecY / vecLength : 0.0; + + double maxDistSqr = 0.0; + int nVertexIndexMaxDistance = r.from + 1; + for ( int i = r.from + 1; i < r.to; i++ ) + { + //compare to anchor + const double fromVecX = p[i].x() - p[r.from].x(); + const double fromVecY = p[i].y() - p[r.from].y(); + + double distToSegmentSqr; + if ( fromVecX * unitVecX + fromVecY * unitVecY < 0.0 ) + { + distToSegmentSqr = fromVecX * fromVecX + fromVecY * fromVecY; + } + else + { + const double toVecX = p[i].x() - p[r.to].x(); + const double toVecY = p[i].y() - p[r.to].y(); + const double toVecLength = toVecX * toVecX + toVecY * toVecY; + + const double s = toVecX * ( -unitVecX ) + toVecY * ( -unitVecY ); + if ( s < 0.0 ) + { + distToSegmentSqr = toVecLength; + } + else + { + distToSegmentSqr = qFabs( toVecLength - s * s ); + } + } + + if ( maxDistSqr < distToSegmentSqr ) + { + maxDistSqr = distToSegmentSqr; + nVertexIndexMaxDistance = i; + } + } + if ( maxDistSqr <= toleranceSqr ) + { + usePoint[r.from] = true; + usePoint[r.to] = true; + } + else + { + stack.push( Line( r.from, nVertexIndexMaxDistance ) ); + stack.push( Line( nVertexIndexMaxDistance, r.to ) ); + } + } + + QPolygonF stripped; + for ( int i = 0; i < nPoints; i++ ) + { + if ( usePoint[i] ) + stripped += p[i]; + } + + return stripped; +} diff --git a/ThirdParty/Qwt/src/qwt_curve_fitter.h b/ThirdParty/Qwt/src/qwt_curve_fitter.h new file mode 100644 index 0000000000..eac376a34d --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_curve_fitter.h @@ -0,0 +1,139 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#ifndef QWT_CURVE_FITTER_H +#define QWT_CURVE_FITTER_H + +#include "qwt_global.h" +#include +#include + +class QwtSpline; + +/*! + \brief Abstract base class for a curve fitter +*/ +class QWT_EXPORT QwtCurveFitter +{ +public: + virtual ~QwtCurveFitter(); + + /*! + Find a curve which has the best fit to a series of data points + + \param polygon Series of data points + \return Curve points + */ + virtual QPolygonF fitCurve( const QPolygonF &polygon ) const = 0; + +protected: + QwtCurveFitter(); + +private: + QwtCurveFitter( const QwtCurveFitter & ); + QwtCurveFitter &operator=( const QwtCurveFitter & ); +}; + +/*! + \brief A curve fitter using cubic splines +*/ +class QWT_EXPORT QwtSplineCurveFitter: public QwtCurveFitter +{ +public: + /*! + Spline type + The default setting is Auto + \sa setFitMode(), FitMode() + */ + enum FitMode + { + /*! + Use the default spline algorithm for polygons with + increasing x values ( p[i-1] < p[i] ), otherwise use + a parametric spline algorithm. + */ + Auto, + + //! Use a default spline algorithm + Spline, + + //! Use a parametric spline algorithm + ParametricSpline + }; + + QwtSplineCurveFitter(); + virtual ~QwtSplineCurveFitter(); + + void setFitMode( FitMode ); + FitMode fitMode() const; + + void setSpline( const QwtSpline& ); + const QwtSpline &spline() const; + QwtSpline &spline(); + + void setSplineSize( int size ); + int splineSize() const; + + virtual QPolygonF fitCurve( const QPolygonF & ) const; + +private: + QPolygonF fitSpline( const QPolygonF & ) const; + QPolygonF fitParametric( const QPolygonF & ) const; + + class PrivateData; + PrivateData *d_data; +}; + +/*! + \brief A curve fitter implementing Douglas and Peucker algorithm + + The purpose of the Douglas and Peucker algorithm is that given a 'curve' + composed of line segments to find a curve not too dissimilar but that + has fewer points. The algorithm defines 'too dissimilar' based on the + maximum distance (tolerance) between the original curve and the + smoothed curve. + + The runtime of the algorithm increases non linear ( worst case O( n*n ) ) + and might be very slow for huge polygons. To avoid performance issues + it might be useful to split the polygon ( setChunkSize() ) and to run the algorithm + for these smaller parts. The disadvantage of having no interpolation + at the borders is for most use cases irrelevant. + + The smoothed curve consists of a subset of the points that defined the + original curve. + + In opposite to QwtSplineCurveFitter the Douglas and Peucker algorithm reduces + the number of points. By adjusting the tolerance parameter according to the + axis scales QwtSplineCurveFitter can be used to implement different + level of details to speed up painting of curves of many points. +*/ +class QWT_EXPORT QwtWeedingCurveFitter: public QwtCurveFitter +{ +public: + QwtWeedingCurveFitter( double tolerance = 1.0 ); + virtual ~QwtWeedingCurveFitter(); + + void setTolerance( double ); + double tolerance() const; + + void setChunkSize( uint ); + uint chunkSize() const; + + virtual QPolygonF fitCurve( const QPolygonF & ) const; + +private: + virtual QPolygonF simplify( const QPolygonF & ) const; + + class Line; + + class PrivateData; + PrivateData *d_data; +}; + +#endif diff --git a/ThirdParty/Qwt/src/qwt_date.cpp b/ThirdParty/Qwt/src/qwt_date.cpp new file mode 100644 index 0000000000..0cf5ca0d2a --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_date.cpp @@ -0,0 +1,654 @@ +#include "qwt_date.h" +#include +#include +#include +#include +#include + +#if QT_VERSION >= 0x050000 + +typedef qint64 QwtJulianDay; +static const QwtJulianDay minJulianDayD = Q_INT64_C( -784350574879 ); +static const QwtJulianDay maxJulianDayD = Q_INT64_C( 784354017364 ); + +#else + +// QDate stores the Julian day as unsigned int, but +// but it is QDate::fromJulianDay( int ). That's why +// we have the range [ 1, INT_MAX ] +typedef int QwtJulianDay; +static const QwtJulianDay minJulianDayD = 1; +static const QwtJulianDay maxJulianDayD = std::numeric_limits::max(); + +#endif + +static inline Qt::DayOfWeek qwtFirstDayOfWeek() +{ +#if QT_VERSION >= 0x040800 + return QLocale().firstDayOfWeek(); +#else + + switch( QLocale().country() ) + { + case QLocale::Maldives: + return Qt::Friday; + + case QLocale::Afghanistan: + case QLocale::Algeria: + case QLocale::Bahrain: + case QLocale::Djibouti: + case QLocale::Egypt: + case QLocale::Eritrea: + case QLocale::Ethiopia: + case QLocale::Iran: + case QLocale::Iraq: + case QLocale::Jordan: + case QLocale::Kenya: + case QLocale::Kuwait: + case QLocale::LibyanArabJamahiriya: + case QLocale::Morocco: + case QLocale::Oman: + case QLocale::Qatar: + case QLocale::SaudiArabia: + case QLocale::Somalia: + case QLocale::Sudan: + case QLocale::Tunisia: + case QLocale::Yemen: + return Qt::Saturday; + + case QLocale::AmericanSamoa: + case QLocale::Argentina: + case QLocale::Azerbaijan: + case QLocale::Botswana: + case QLocale::Canada: + case QLocale::China: + case QLocale::FaroeIslands: + case QLocale::Georgia: + case QLocale::Greenland: + case QLocale::Guam: + case QLocale::HongKong: + case QLocale::Iceland: + case QLocale::India: + case QLocale::Ireland: + case QLocale::Israel: + case QLocale::Jamaica: + case QLocale::Japan: + case QLocale::Kyrgyzstan: + case QLocale::Lao: + case QLocale::Malta: + case QLocale::MarshallIslands: + case QLocale::Macau: + case QLocale::Mongolia: + case QLocale::NewZealand: + case QLocale::NorthernMarianaIslands: + case QLocale::Pakistan: + case QLocale::Philippines: + case QLocale::RepublicOfKorea: + case QLocale::Singapore: + case QLocale::SyrianArabRepublic: + case QLocale::Taiwan: + case QLocale::Thailand: + case QLocale::TrinidadAndTobago: + case QLocale::UnitedStates: + case QLocale::UnitedStatesMinorOutlyingIslands: + case QLocale::USVirginIslands: + case QLocale::Uzbekistan: + case QLocale::Zimbabwe: + return Qt::Sunday; + + default: + return Qt::Monday; + } +#endif +} + +static inline void qwtFloorTime( + QwtDate::IntervalType intervalType, QDateTime &dt ) +{ + // when dt is inside the special hour where DST is ending + // an hour is no unique. Therefore we have to + // use UTC time. + + const Qt::TimeSpec timeSpec = dt.timeSpec(); + + if ( timeSpec == Qt::LocalTime ) + dt = dt.toTimeSpec( Qt::UTC ); + + const QTime t = dt.time(); + switch( intervalType ) + { + case QwtDate::Second: + { + dt.setTime( QTime( t.hour(), t.minute(), t.second() ) ); + break; + } + case QwtDate::Minute: + { + dt.setTime( QTime( t.hour(), t.minute(), 0 ) ); + break; + } + case QwtDate::Hour: + { + dt.setTime( QTime( t.hour(), 0, 0 ) ); + break; + } + default: + break; + } + + if ( timeSpec == Qt::LocalTime ) + dt = dt.toTimeSpec( Qt::LocalTime ); +} + +static inline QDateTime qwtToTimeSpec( + const QDateTime &dt, Qt::TimeSpec spec ) +{ + if ( dt.timeSpec() == spec ) + return dt; + + const qint64 jd = dt.date().toJulianDay(); + if ( jd < 0 || jd >= INT_MAX ) + { + // the conversion between local time and UTC + // is internally limited. To avoid + // overflows we simply ignore the difference + // for those dates + + QDateTime dt2 = dt; + dt2.setTimeSpec( spec ); + return dt2; + } + + return dt.toTimeSpec( spec ); +} + +static inline double qwtToJulianDay( int year, int month, int day ) +{ + // code from QDate but using doubles to avoid overflows + // for large values + + const int m1 = ( month - 14 ) / 12; + const int m2 = ( 367 * ( month - 2 - 12 * m1 ) ) / 12; + const double y1 = ::floor( ( 4900.0 + year + m1 ) / 100 ); + + return ::floor( ( 1461.0 * ( year + 4800 + m1 ) ) / 4 ) + m2 + - ::floor( ( 3 * y1 ) / 4 ) + day - 32075; +} + +static inline qint64 qwtFloorDiv64( qint64 a, int b ) +{ + if ( a < 0 ) + a -= b - 1; + + return a / b; +} + +static inline qint64 qwtFloorDiv( int a, int b ) +{ + if ( a < 0 ) + a -= b - 1; + + return a / b; +} + +static inline QDate qwtToDate( int year, int month = 1, int day = 1 ) +{ +#if QT_VERSION >= 0x050000 + return QDate( year, month, day ); +#else + if ( year > 100000 ) + { + // code from QDate but using doubles to avoid overflows + // for large values + + const int m1 = ( month - 14 ) / 12; + const int m2 = ( 367 * ( month - 2 - 12 * m1 ) ) / 12; + const double y1 = ::floor( ( 4900.0 + year + m1 ) / 100 ); + + const double jd = ::floor( ( 1461.0 * ( year + 4800 + m1 ) ) / 4 ) + m2 + - ::floor( ( 3 * y1 ) / 4 ) + day - 32075; + + if ( jd > maxJulianDayD ) + { + qWarning() << "qwtToDate: overflow"; + return QDate(); + } + + return QDate::fromJulianDay( static_cast( jd ) ); + } + else + { + return QDate( year, month, day ); + } +#endif +} + +/*! + Translate from double to QDateTime + + \param value Number of milliseconds since the epoch, + 1970-01-01T00:00:00 UTC + \param timeSpec Time specification + \return Datetime value + + \sa toDouble(), QDateTime::setMSecsSinceEpoch() + \note The return datetime for Qt::OffsetFromUTC will be Qt::UTC + */ +QDateTime QwtDate::toDateTime( double value, Qt::TimeSpec timeSpec ) +{ + const int msecsPerDay = 86400000; + + const double days = static_cast( ::floor( value / msecsPerDay ) ); + + const double jd = QwtDate::JulianDayForEpoch + days; + if ( ( jd > maxJulianDayD ) || ( jd < minJulianDayD ) ) + { + qWarning() << "QwtDate::toDateTime: overflow"; + return QDateTime(); + } + + const QDate d = QDate::fromJulianDay( static_cast( jd ) ); + + const int msecs = static_cast( value - days * msecsPerDay ); + + static const QTime timeNull( 0, 0, 0, 0 ); + + QDateTime dt( d, timeNull.addMSecs( msecs ), Qt::UTC ); + + if ( timeSpec == Qt::LocalTime ) + dt = qwtToTimeSpec( dt, timeSpec ); + + return dt; +} + +/*! + Translate from QDateTime to double + + \param dateTime Datetime value + \return Number of milliseconds since 1970-01-01T00:00:00 UTC has passed. + + \sa toDateTime(), QDateTime::toMSecsSinceEpoch() + \warning For values very far below or above 1970-01-01 UTC rounding errors + will happen due to the limited significance of a double. + */ +double QwtDate::toDouble( const QDateTime &dateTime ) +{ + const int msecsPerDay = 86400000; + + const QDateTime dt = qwtToTimeSpec( dateTime, Qt::UTC ); + + const double days = dt.date().toJulianDay() - QwtDate::JulianDayForEpoch; + + const QTime time = dt.time(); + const double secs = 3600.0 * time.hour() + + 60.0 * time.minute() + time.second(); + + return days * msecsPerDay + time.msec() + 1000.0 * secs; +} + +/*! + Ceil a datetime according the interval type + + \param dateTime Datetime value + \param intervalType Interval type, how to ceil. + F.e. when intervalType = QwtDate::Months, the result + will be ceiled to the next beginning of a month + \return Ceiled datetime + \sa floor() + */ +QDateTime QwtDate::ceil( const QDateTime &dateTime, IntervalType intervalType ) +{ + if ( dateTime.date() >= QwtDate::maxDate() ) + return dateTime; + + QDateTime dt = dateTime; + + switch ( intervalType ) + { + case QwtDate::Millisecond: + { + break; + } + case QwtDate::Second: + { + qwtFloorTime( QwtDate::Second, dt ); + if ( dt < dateTime ) + dt.addSecs( 1 ); + + break; + } + case QwtDate::Minute: + { + qwtFloorTime( QwtDate::Minute, dt ); + if ( dt < dateTime ) + dt.addSecs( 60 ); + + break; + } + case QwtDate::Hour: + { + qwtFloorTime( QwtDate::Hour, dt ); + if ( dt < dateTime ) + dt.addSecs( 3600 ); + + break; + } + case QwtDate::Day: + { + dt.setTime( QTime( 0, 0 ) ); + if ( dt < dateTime ) + dt = dt.addDays( 1 ); + + break; + } + case QwtDate::Week: + { + dt.setTime( QTime( 0, 0 ) ); + if ( dt < dateTime ) + dt = dt.addDays( 1 ); + + int days = qwtFirstDayOfWeek() - dt.date().dayOfWeek(); + if ( days < 0 ) + days += 7; + + dt = dt.addDays( days ); + + break; + } + case QwtDate::Month: + { + dt.setTime( QTime( 0, 0 ) ); + dt.setDate( qwtToDate( dateTime.date().year(), + dateTime.date().month() ) ); + + if ( dt < dateTime ) + dt.addMonths( 1 ); + + break; + } + case QwtDate::Year: + { + dt.setTime( QTime( 0, 0 ) ); + + const QDate d = dateTime.date(); + + int year = d.year(); + if ( d.month() > 1 || d.day() > 1 || !dateTime.time().isNull() ) + year++; + + if ( year == 0 ) + year++; // there is no year 0 + + dt.setDate( qwtToDate( year ) ); + break; + } + } + + return dt; +} + +/*! + Floor a datetime according the interval type + + \param dateTime Datetime value + \param intervalType Interval type, how to ceil. + F.e. when intervalType = QwtDate::Months, + the result will be ceiled to the next + beginning of a month + \return Floored datetime + \sa floor() + */ +QDateTime QwtDate::floor( const QDateTime &dateTime, + IntervalType intervalType ) +{ + if ( dateTime.date() <= QwtDate::minDate() ) + return dateTime; + + QDateTime dt = dateTime; + + switch ( intervalType ) + { + case QwtDate::Millisecond: + { + break; + } + case QwtDate::Second: + case QwtDate::Minute: + case QwtDate::Hour: + { + qwtFloorTime( intervalType, dt ); + break; + } + case QwtDate::Day: + { + dt.setTime( QTime( 0, 0 ) ); + break; + } + case QwtDate::Week: + { + dt.setTime( QTime( 0, 0 ) ); + + int days = dt.date().dayOfWeek() - qwtFirstDayOfWeek(); + if ( days < 0 ) + days += 7; + + dt = dt.addDays( -days ); + + break; + } + case QwtDate::Month: + { + dt.setTime( QTime( 0, 0 ) ); + + const QDate date = qwtToDate( dt.date().year(), + dt.date().month() ); + dt.setDate( date ); + + break; + } + case QwtDate::Year: + { + dt.setTime( QTime( 0, 0 ) ); + + const QDate date = qwtToDate( dt.date().year() ); + dt.setDate( date ); + + break; + } + } + + return dt; +} + +/*! + Minimum for the supported date range + + The range of valid dates depends on how QDate stores the + Julian day internally. + + - For Qt4 it is "Tue Jan 2 -4713" + - For Qt5 it is "Thu Jan 1 -2147483648" + + \return minimum of the date range + \sa maxDate() + */ +QDate QwtDate::minDate() +{ + static QDate date; + if ( !date.isValid() ) + date = QDate::fromJulianDay( minJulianDayD ); + + return date; +} + +/*! + Maximum for the supported date range + + The range of valid dates depends on how QDate stores the + Julian day internally. + + - For Qt4 it is "Tue Jun 3 5874898" + - For Qt5 it is "Tue Dec 31 2147483647" + + \return maximum of the date range + \sa minDate() + \note The maximum differs between Qt4 and Qt5 + */ +QDate QwtDate::maxDate() +{ + static QDate date; + if ( !date.isValid() ) + date = QDate::fromJulianDay( maxJulianDayD ); + + return date; +} + +/*! + \brief Date of the first day of the first week for a year + + The first day of a week depends on the current locale + ( QLocale::firstDayOfWeek() ). + + \param year Year + \param type Option how to identify the first week + \return First day of week 0 + + \sa QLocale::firstDayOfWeek(), weekNumber() + */ +QDate QwtDate::dateOfWeek0( int year, Week0Type type ) +{ + const Qt::DayOfWeek firstDayOfWeek = qwtFirstDayOfWeek(); + + QDate dt0( year, 1, 1 ); + + // floor to the first day of the week + int days = dt0.dayOfWeek() - firstDayOfWeek; + if ( days < 0 ) + days += 7; + + dt0 = dt0.addDays( -days ); + + if ( type == QwtDate::FirstThursday ) + { + // according to ISO 8601 the first week is defined + // by the first thursday. + + int d = Qt::Thursday - firstDayOfWeek; + if ( d < 0 ) + d += 7; + + if ( dt0.addDays( d ).year() < year ) + dt0 = dt0.addDays( 7 ); + } + + return dt0; +} + +/*! + Find the week number of a date + + - QwtDate::FirstThursday\n + Corresponding to ISO 8601 ( see QDate::weekNumber() ). + + - QwtDate::FirstDay\n + Number of weeks that have begun since dateOfWeek0(). + + \param date Date + \param type Option how to identify the first week + + \return Week number, starting with 1 + */ +int QwtDate::weekNumber( const QDate &date, Week0Type type ) +{ + int weekNo; + + if ( type == QwtDate::FirstDay ) + { + const QDate day0 = dateOfWeek0( date.year(), type ); + weekNo = day0.daysTo( date ) / 7 + 1; + } + else + { + weekNo = date.weekNumber(); + } + + return weekNo; +} + +/*! + Offset in seconds from Coordinated Universal Time + + The offset depends on the time specification of dateTime: + + - Qt::UTC + 0, dateTime has no offset + - Qt::OffsetFromUTC + returns dateTime.utcOffset() + - Qt::LocalTime: + number of seconds from the UTC + + For Qt::LocalTime the offset depends on the timezone and + daylight savings. + + \param dateTime Datetime value + \return Offset in seconds + */ +int QwtDate::utcOffset( const QDateTime &dateTime ) +{ + int seconds = 0; + + switch( dateTime.timeSpec() ) + { + case Qt::UTC: + { + break; + } + case Qt::OffsetFromUTC: + { + seconds = dateTime.utcOffset(); + } + default: + { + const QDateTime dt1( dateTime.date(), dateTime.time(), Qt::UTC ); + seconds = dateTime.secsTo( dt1 ); + } + } + + return seconds; +} + +/*! + Translate a datetime into a string + + Beside the format expressions documented in QDateTime::toString() + the following expressions are supported: + + - w\n + week number: ( 1 - 53 ) + - ww\n + week number with a leading zero ( 01 - 53 ) + + \param dateTime Datetime value + \param format Format string + \param week0Type Specification of week 0 + + \return Datetime string + \sa QDateTime::toString(), weekNumber(), QwtDateScaleDraw + */ +QString QwtDate::toString( const QDateTime &dateTime, + const QString & format, Week0Type week0Type ) +{ + QString weekNo; + weekNo.setNum( QwtDate::weekNumber( dateTime.date(), week0Type ) ); + + QString weekNoWW; + if ( weekNo.length() == 1 ) + weekNoWW += "0"; + weekNoWW += weekNo; + + QString fmt = format; + fmt.replace( "ww", weekNoWW ); + fmt.replace( "w", weekNo ); + + return dateTime.toString( fmt ); +} diff --git a/ThirdParty/Qwt/src/qwt_date.h b/ThirdParty/Qwt/src/qwt_date.h new file mode 100644 index 0000000000..30422a1c1c --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_date.h @@ -0,0 +1,128 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#ifndef _QWT_DATE_H_ +#define _QWT_DATE_H_ + +#include "qwt_global.h" +#include + +/*! + \brief A collection of methods around date/time values + + Qt offers convenient classes for dealing with date/time values, + but Qwt uses coordinate systems that are based on doubles. + QwtDate offers methods to translate from QDateTime to double and v.v. + + A double is interpreted as the number of milliseconds since + 1970-01-01T00:00:00 Universal Coordinated Time - also known + as "The Epoch". + + While the range of the Julian day in Qt4 is limited to [0, MAX_INT], + Qt5 stores it as qint64 offering a huge range of valid dates. + As the significance of a double is below this ( assuming a + fraction of 52 bits ) the translation is not + bijective with rounding errors for dates very far from Epoch. + For a resolution of 1 ms those start to happen for dates above the + year 144683. + + An axis for a date/time interval is expected to be aligned + and divided in time/date units like seconds, minutes, ... + QwtDate offers several algorithms that are needed to + calculate these axes. + + \sa QwtDateScaleEngine, QwtDateScaleDraw, QDate, QTime +*/ +class QWT_EXPORT QwtDate +{ +public: + /*! + How to identify the first week of year differs between + countries. + */ + enum Week0Type + { + /*! + According to ISO 8601 the first week of a year is defined + as "the week with the year's first Thursday in it". + + FirstThursday corresponds to the numbering that is + implemented in QDate::weekNumber(). + */ + FirstThursday, + + /*! + "The week with January 1.1 in it." + + In the U.S. this definition is more common than + FirstThursday. + */ + FirstDay + }; + + /*! + Classification of an time interval + + Time intervals needs to be classified to decide how to + align and divide it. + */ + enum IntervalType + { + //! The interval is related to milliseconds + Millisecond, + + //! The interval is related to seconds + Second, + + //! The interval is related to minutes + Minute, + + //! The interval is related to hours + Hour, + + //! The interval is related to days + Day, + + //! The interval is related to weeks + Week, + + //! The interval is related to months + Month, + + //! The interval is related to years + Year + }; + + enum + { + //! The Julian day of "The Epoch" + JulianDayForEpoch = 2440588 + }; + + static QDate minDate(); + static QDate maxDate(); + + static QDateTime toDateTime( double value, + Qt::TimeSpec = Qt::UTC ); + + static double toDouble( const QDateTime & ); + + static QDateTime ceil( const QDateTime &, IntervalType ); + static QDateTime floor( const QDateTime &, IntervalType ); + + static QDate dateOfWeek0( int year, Week0Type ); + static int weekNumber( const QDate &, Week0Type ); + + static int utcOffset( const QDateTime & ); + + static QString toString( const QDateTime &, + const QString & format, Week0Type ); +}; + +#endif diff --git a/ThirdParty/Qwt/src/qwt_date_scale_draw.cpp b/ThirdParty/Qwt/src/qwt_date_scale_draw.cpp new file mode 100644 index 0000000000..7cfc6dec0b --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_date_scale_draw.cpp @@ -0,0 +1,269 @@ +#include "qwt_date_scale_draw.h" + +class QwtDateScaleDraw::PrivateData +{ +public: + PrivateData( Qt::TimeSpec spec ): + timeSpec( spec ), + utcOffset( 0 ), + week0Type( QwtDate::FirstThursday ) + { + dateFormats[ QwtDate::Millisecond ] = "hh:mm:ss:zzz\nddd dd MMM yyyy"; + dateFormats[ QwtDate::Second ] = "hh:mm:ss\nddd dd MMM yyyy"; + dateFormats[ QwtDate::Minute ] = "hh:mm\nddd dd MMM yyyy"; + dateFormats[ QwtDate::Hour ] = "hh:mm\nddd dd MMM yyyy"; + dateFormats[ QwtDate::Day ] = "ddd dd MMM yyyy"; + dateFormats[ QwtDate::Week ] = "Www yyyy"; + dateFormats[ QwtDate::Month ] = "MMM yyyy"; + dateFormats[ QwtDate::Year ] = "yyyy"; + } + + Qt::TimeSpec timeSpec; + int utcOffset; + QwtDate::Week0Type week0Type; + QString dateFormats[ QwtDate::Year + 1 ]; +}; + +/*! + \brief Constructor + + The default setting is to display tick labels for the + given time specification. The first week of a year is defined like + for QwtDate::FirstThursday. + + \param timeSpec Time specification + + \sa setTimeSpec(), setWeek0Type() + */ +QwtDateScaleDraw::QwtDateScaleDraw( Qt::TimeSpec timeSpec ) +{ + d_data = new PrivateData( timeSpec ); +} + +//! Destructor +QwtDateScaleDraw::~QwtDateScaleDraw() +{ + delete d_data; +} + +/*! + Set the time specification used for the tick labels + + \param timeSpec Time specification + \sa timeSpec(), setUtcOffset(), toDateTime() + */ +void QwtDateScaleDraw::setTimeSpec( Qt::TimeSpec timeSpec ) +{ + d_data->timeSpec = timeSpec; +} + +/*! + \return Time specification used for the tick labels + \sa setTimeSpec(), utcOffset(), toDateTime() + */ +Qt::TimeSpec QwtDateScaleDraw::timeSpec() const +{ + return d_data->timeSpec; +} + +/*! + Set the offset in seconds from Coordinated Universal Time + + \param seconds Offset in seconds + + \note The offset has no effect beside for the time specification + Qt::OffsetFromUTC. + + \sa QDate::utcOffset(), setTimeSpec(), toDateTime() + */ +void QwtDateScaleDraw::setUtcOffset( int seconds ) +{ + d_data->utcOffset = seconds; +} + +/*! + \return Offset in seconds from Coordinated Universal Time + \note The offset has no effect beside for the time specification + Qt::OffsetFromUTC. + + \sa QDate::setUtcOffset(), setTimeSpec(), toDateTime() + */ +int QwtDateScaleDraw::utcOffset() const +{ + return d_data->utcOffset; +} + +/*! + Sets how to identify the first week of a year. + + \param week0Type Mode how to identify the first week of a year + + \sa week0Type(). + \note week0Type has no effect beside for intervals classified as + QwtDate::Week. + */ +void QwtDateScaleDraw::setWeek0Type( QwtDate::Week0Type week0Type ) +{ + d_data->week0Type = week0Type; +} + +/*! + \return Setting how to identify the first week of a year. + \sa setWeek0Type() + */ +QwtDate::Week0Type QwtDateScaleDraw::week0Type() const +{ + return d_data->week0Type; +} + +/*! + Set the default format string for an datetime interval type + + \param intervalType Interval type + \param format Default format string + + \sa dateFormat(), dateFormatOfDate(), QwtDate::toString() + */ +void QwtDateScaleDraw::setDateFormat( + QwtDate::IntervalType intervalType, const QString &format ) +{ + if ( intervalType >= QwtDate::Millisecond && + intervalType <= QwtDate::Year ) + { + d_data->dateFormats[ intervalType ] = format; + } +} + +/*! + \param intervalType Interval type + \return Default format string for an datetime interval type + \sa setDateFormat(), dateFormatOfDate() + */ +QString QwtDateScaleDraw::dateFormat( + QwtDate::IntervalType intervalType ) const +{ + if ( intervalType >= QwtDate::Millisecond && + intervalType <= QwtDate::Year ) + { + return d_data->dateFormats[ intervalType ]; + } + + return QString::null; +} + +/*! + Format string for the representation of a datetime + + dateFormatOfDate() is intended to be overloaded for + situations, where formats are individual for specific + datetime values. + + The default setting ignores dateTime and return + the default format for the interval type. + + \param dateTime Datetime value + \param intervalType Interval type + \return Format string + + \sa setDateFormat(), QwtDate::toString() + */ +QString QwtDateScaleDraw::dateFormatOfDate( const QDateTime &dateTime, + QwtDate::IntervalType intervalType ) const +{ + Q_UNUSED( dateTime ) + + if ( intervalType >= QwtDate::Millisecond && + intervalType <= QwtDate::Year ) + { + return d_data->dateFormats[ intervalType ]; + } + + return d_data->dateFormats[ QwtDate::Second ]; +} + +/*! + \brief Convert a value into its representing label + + The value is converted to a datetime value using toDateTime() + and converted to a plain text using QwtDate::toString(). + + \param value Value + \return Label string. + + \sa dateFormatOfDate() +*/ +QwtText QwtDateScaleDraw::label( double value ) const +{ + const QDateTime dt = toDateTime( value ); + const QString fmt = dateFormatOfDate( + dt, intervalType( scaleDiv() ) ); + + return QwtDate::toString( dt, fmt, d_data->week0Type ); +} + +/*! + Find the less detailed datetime unit, where no rounding + errors happen. + + \param scaleDiv Scale division + \return Interval type + + \sa dateFormatOfDate() + */ +QwtDate::IntervalType QwtDateScaleDraw::intervalType( + const QwtScaleDiv &scaleDiv ) const +{ + int intvType = QwtDate::Year; + + bool alignedToWeeks = true; + + const QList ticks = scaleDiv.ticks( QwtScaleDiv::MajorTick ); + for ( int i = 0; i < ticks.size(); i++ ) + { + const QDateTime dt = toDateTime( ticks[i] ); + for ( int j = QwtDate::Second; j <= intvType; j++ ) + { + const QDateTime dt0 = QwtDate::floor( dt, + static_cast( j ) ); + + if ( dt0 != dt ) + { + if ( j == QwtDate::Week ) + { + alignedToWeeks = false; + } + else + { + intvType = j - 1; + break; + } + } + } + + if ( intvType == QwtDate::Millisecond ) + break; + } + + if ( intvType == QwtDate::Week && !alignedToWeeks ) + intvType = QwtDate::Day; + + return static_cast( intvType ); +} + +/*! + Translate a double value into a QDateTime object. + + \return QDateTime object initialized with timeSpec() and utcOffset(). + \sa timeSpec(), utcOffset(), QwtDate::toDateTime() + */ +QDateTime QwtDateScaleDraw::toDateTime( double value ) const +{ + QDateTime dt = QwtDate::toDateTime( value, d_data->timeSpec ); + if ( d_data->timeSpec == Qt::OffsetFromUTC ) + { + dt = dt.addSecs( d_data->utcOffset ); + dt.setUtcOffset( d_data->utcOffset ); + } + + return dt; +} diff --git a/ThirdParty/Qwt/src/qwt_date_scale_draw.h b/ThirdParty/Qwt/src/qwt_date_scale_draw.h new file mode 100644 index 0000000000..92589e890f --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_date_scale_draw.h @@ -0,0 +1,77 @@ +#ifndef _QWT_DATE_SCALE_DRAW_H_ +#define _QWT_DATE_SCALE_DRAW_H_ 1 + +#include "qwt_global.h" +#include "qwt_scale_draw.h" +#include "qwt_date.h" + +/*! + \brief A class for drawing datetime scales + + QwtDateScaleDraw displays values as datetime labels. + The format of the labels depends on the alignment of + the major tick labels. + + The default format strings are: + + - Millisecond\n + "hh:mm:ss:zzz\nddd dd MMM yyyy" + - Second\n + "hh:mm:ss\nddd dd MMM yyyy" + - Minute\n + "hh:mm\nddd dd MMM yyyy" + - Hour\n + "hh:mm\nddd dd MMM yyyy" + - Day\n + "ddd dd MMM yyyy" + - Week\n + "Www yyyy" + - Month\n + "MMM yyyy" + - Year\n + "yyyy" + + The format strings can be modified using setDateFormat() + or individually for each tick label by overloading dateFormatOfDate(), + + Usually QwtDateScaleDraw is used in combination with + QwtDateScaleEngine, that calculates scales for datetime + intervals. + + \sa QwtDateScaleEngine, QwtPlot::setAxisScaleDraw() +*/ +class QWT_EXPORT QwtDateScaleDraw: public QwtScaleDraw +{ +public: + QwtDateScaleDraw( Qt::TimeSpec = Qt::LocalTime ); + virtual ~QwtDateScaleDraw(); + + void setDateFormat( QwtDate::IntervalType, const QString & ); + QString dateFormat( QwtDate::IntervalType ) const; + + void setTimeSpec( Qt::TimeSpec ); + Qt::TimeSpec timeSpec() const; + + void setUtcOffset( int seconds ); + int utcOffset() const; + + void setWeek0Type( QwtDate::Week0Type ); + QwtDate::Week0Type week0Type() const; + + virtual QwtText label( double ) const; + + QDateTime toDateTime( double ) const; + +protected: + virtual QwtDate::IntervalType + intervalType( const QwtScaleDiv & ) const; + + virtual QString dateFormatOfDate( const QDateTime &, + QwtDate::IntervalType ) const; + +private: + class PrivateData; + PrivateData *d_data; +}; + +#endif diff --git a/ThirdParty/Qwt/src/qwt_date_scale_engine.cpp b/ThirdParty/Qwt/src/qwt_date_scale_engine.cpp new file mode 100644 index 0000000000..bff2be45f9 --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_date_scale_engine.cpp @@ -0,0 +1,1247 @@ +#include "qwt_date_scale_engine.h" +#include "qwt_math.h" +#include "qwt_transform.h" +#include +#include + +static inline double qwtMsecsForType( QwtDate::IntervalType type ) +{ + static const double msecs[] = + { + 1.0, + 1000.0, + 60.0 * 1000.0, + 3600.0 * 1000.0, + 24.0 * 3600.0 * 1000.0, + 7.0 * 24.0 * 3600.0 * 1000.0, + 30.0 * 24.0 * 3600.0 * 1000.0, + 365.0 * 24.0 * 3600.0 * 1000.0, + }; + + if ( type < 0 || type >= static_cast( sizeof( msecs ) / sizeof( msecs[0] ) ) ) + return 1.0; + + return msecs[ type ]; +} + +static inline int qwtAlignValue( + double value, double stepSize, bool up ) +{ + double d = value / stepSize; + d = up ? ::ceil( d ) : ::floor( d ); + + return static_cast( d * stepSize ); +} + +static double qwtIntervalWidth( const QDateTime &minDate, + const QDateTime &maxDate, QwtDate::IntervalType intervalType ) +{ + switch( intervalType ) + { + case QwtDate::Millisecond: + { + const double secsTo = minDate.secsTo( maxDate ); + const double msecs = maxDate.time().msec() - + minDate.time().msec(); + + return secsTo * 1000 + msecs; + } + case QwtDate::Second: + { + return minDate.secsTo( maxDate ); + } + case QwtDate::Minute: + { + const double secsTo = minDate.secsTo( maxDate ); + return ::floor( secsTo / 60 ); + } + case QwtDate::Hour: + { + const double secsTo = minDate.secsTo( maxDate ); + return ::floor( secsTo / 3600 ); + } + case QwtDate::Day: + { + return minDate.daysTo( maxDate ); + } + case QwtDate::Week: + { + return ::floor( minDate.daysTo( maxDate ) / 7.0 ); + } + case QwtDate::Month: + { + const double years = + double( maxDate.date().year() ) - minDate.date().year(); + + int months = maxDate.date().month() - minDate.date().month(); + if ( maxDate.date().day() < minDate.date().day() ) + months--; + + return years * 12 + months; + } + case QwtDate::Year: + { + double years = + double( maxDate.date().year() ) - minDate.date().year(); + + if ( maxDate.date().month() < minDate.date().month() ) + years -= 1.0; + + return years; + } + } + + return 0.0; +} + +static double qwtRoundedIntervalWidth( + const QDateTime &minDate, const QDateTime &maxDate, + QwtDate::IntervalType intervalType ) +{ + const QDateTime minD = QwtDate::floor( minDate, intervalType ); + const QDateTime maxD = QwtDate::ceil( maxDate, intervalType ); + + return qwtIntervalWidth( minD, maxD, intervalType ); +} + +static inline int qwtStepCount( int intervalSize, int maxSteps, + const int limits[], size_t numLimits ) +{ + for ( uint i = 0; i < numLimits; i++ ) + { + const int numSteps = intervalSize / limits[ i ]; + + if ( numSteps > 1 && numSteps <= maxSteps && + numSteps * limits[ i ] == intervalSize ) + { + return numSteps; + } + } + + return 0; +} + +static int qwtStepSize( int intervalSize, int maxSteps, uint base ) +{ + if ( maxSteps <= 0 ) + return 0; + + if ( maxSteps > 2 ) + { + for ( int numSteps = maxSteps; numSteps > 1; numSteps-- ) + { + const double stepSize = double( intervalSize ) / numSteps; + + const double p = ::floor( ::log( stepSize ) / ::log( double( base ) ) ); + const double fraction = qPow( base, p ); + + for ( uint n = base; n >= 1; n /= 2 ) + { + if ( qFuzzyCompare( stepSize, n * fraction ) ) + return qRound( stepSize ); + + if ( n == 3 && ( base % 2 ) == 0 ) + { + if ( qFuzzyCompare( stepSize, 2 * fraction ) ) + return qRound( stepSize ); + } + } + } + } + + return 0; +} + +static int qwtDivideInterval( double intervalSize, int numSteps, + const int limits[], size_t numLimits ) +{ + const int v = qCeil( intervalSize / double( numSteps ) ); + + for ( uint i = 0; i < numLimits - 1; i++ ) + { + if ( v <= limits[i] ) + return limits[i]; + } + + return limits[ numLimits - 1 ]; +} + +static double qwtDivideScale( double intervalSize, int numSteps, + QwtDate::IntervalType intervalType ) +{ + if ( intervalType != QwtDate::Day ) + { + if ( ( intervalSize > numSteps ) && + ( intervalSize <= 2 * numSteps ) ) + { + return 2.0; + } + } + + double stepSize; + + switch( intervalType ) + { + case QwtDate::Second: + case QwtDate::Minute: + { + static int limits[] = { 1, 2, 5, 10, 15, 20, 30, 60 }; + + stepSize = qwtDivideInterval( intervalSize, numSteps, + limits, sizeof( limits ) / sizeof( int ) ); + + break; + } + case QwtDate::Hour: + { + static int limits[] = { 1, 2, 3, 4, 6, 12, 24 }; + + stepSize = qwtDivideInterval( intervalSize, numSteps, + limits, sizeof( limits ) / sizeof( int ) ); + + break; + } + case QwtDate::Day: + { + const double v = intervalSize / double( numSteps ); + if ( v <= 5.0 ) + stepSize = qCeil( v ); + else + stepSize = qCeil( v / 7 ) * 7; + + break; + } + case QwtDate::Week: + { + static int limits[] = { 1, 2, 4, 8, 12, 26, 52 }; + + stepSize = qwtDivideInterval( intervalSize, numSteps, + limits, sizeof( limits ) / sizeof( int ) ); + + break; + } + case QwtDate::Month: + { + static int limits[] = { 1, 2, 3, 4, 6, 12 }; + + stepSize = qwtDivideInterval( intervalSize, numSteps, + limits, sizeof( limits ) / sizeof( int ) ); + + break; + } + case QwtDate::Year: + case QwtDate::Millisecond: + default: + { + stepSize = QwtScaleArithmetic::divideInterval( + intervalSize, numSteps, 10 ); + } + } + + return stepSize; +} + +static double qwtDivideMajorStep( double stepSize, int maxMinSteps, + QwtDate::IntervalType intervalType ) +{ + double minStepSize = 0.0; + + switch( intervalType ) + { + case QwtDate::Second: + { + minStepSize = qwtStepSize( stepSize, maxMinSteps, 10 ); + if ( minStepSize == 0.0 ) + minStepSize = 0.5 * stepSize; + + break; + } + case QwtDate::Minute: + { + static int limits[] = { 1, 2, 5, 10, 15, 20, 30, 60 }; + + int numSteps; + + if ( stepSize > maxMinSteps ) + { + numSteps = qwtStepCount( stepSize, maxMinSteps, + limits, sizeof( limits ) / sizeof( int ) ); + + } + else + { + numSteps = qwtStepCount( stepSize * 60, maxMinSteps, + limits, sizeof( limits ) / sizeof( int ) ); + } + + if ( numSteps > 0 ) + minStepSize = double( stepSize ) / numSteps; + + break; + } + case QwtDate::Hour: + { + int numSteps = 0; + + if ( stepSize > maxMinSteps ) + { + static int limits[] = { 1, 2, 3, 4, 6, 12, 24, 48, 72 }; + + numSteps = qwtStepCount( stepSize, maxMinSteps, + limits, sizeof( limits ) / sizeof( int ) ); + } + else + { + static int limits[] = { 1, 2, 5, 10, 15, 20, 30, 60 }; + + numSteps = qwtStepCount( stepSize * 60, maxMinSteps, + limits, sizeof( limits ) / sizeof( int ) ); + } + + if ( numSteps > 0 ) + minStepSize = double( stepSize ) / numSteps; + + break; + } + case QwtDate::Day: + { + int numSteps = 0; + + if ( stepSize > maxMinSteps ) + { + static int limits[] = { 1, 2, 3, 7, 14, 28 }; + + numSteps = qwtStepCount( stepSize, maxMinSteps, + limits, sizeof( limits ) / sizeof( int ) ); + } + else + { + static int limits[] = { 1, 2, 3, 4, 6, 12, 24, 48, 72 }; + + numSteps = qwtStepCount( stepSize * 24, maxMinSteps, + limits, sizeof( limits ) / sizeof( int ) ); + } + + if ( numSteps > 0 ) + minStepSize = double( stepSize ) / numSteps; + + break; + } + case QwtDate::Week: + { + const int daysInStep = stepSize * 7; + + if ( maxMinSteps >= daysInStep ) + { + // we want to have one tick per day + minStepSize = 1.0 / 7.0; + } + else + { + // when the stepSize is more than a week we want to + // have a tick for each week + + const int stepSizeInWeeks = stepSize; + + if ( stepSizeInWeeks <= maxMinSteps ) + { + minStepSize = 1; + } + else + { + minStepSize = QwtScaleArithmetic::divideInterval( + stepSizeInWeeks, maxMinSteps, 10 ); + } + } + break; + } + case QwtDate::Month: + { + // fractions of months doesn't make any sense + + if ( stepSize < maxMinSteps ) + maxMinSteps = static_cast( stepSize ); + + static int limits[] = { 1, 2, 3, 4, 6, 12 }; + + int numSteps = qwtStepCount( stepSize, maxMinSteps, + limits, sizeof( limits ) / sizeof( int ) ); + + if ( numSteps > 0 ) + minStepSize = double( stepSize ) / numSteps; + + break; + } + case QwtDate::Year: + { + if ( stepSize >= maxMinSteps ) + { + minStepSize = QwtScaleArithmetic::divideInterval( + stepSize, maxMinSteps, 10 ); + } + else + { + // something in months + + static int limits[] = { 1, 2, 3, 4, 6, 12 }; + + int numSteps = qwtStepCount( 12 * stepSize, maxMinSteps, + limits, sizeof( limits ) / sizeof( int ) ); + + if ( numSteps > 0 ) + minStepSize = double( stepSize ) / numSteps; + } + + break; + } + default: + break; + } + + if ( intervalType != QwtDate::Month + && minStepSize == 0.0 ) + { + minStepSize = 0.5 * stepSize; + } + + return minStepSize; +} + +static QList qwtDstTicks( const QDateTime &dateTime, + int secondsMajor, int secondsMinor ) +{ + if ( secondsMinor <= 0 ) + QList(); + + QDateTime minDate = dateTime.addSecs( -secondsMajor ); + minDate = QwtDate::floor( minDate, QwtDate::Hour ); + + const double utcOffset = QwtDate::utcOffset( dateTime ); + + // find the hours where daylight saving time happens + + double dstMin = QwtDate::toDouble( minDate ); + while ( minDate < dateTime && + QwtDate::utcOffset( minDate ) != utcOffset ) + { + minDate = minDate.addSecs( 3600 ); + dstMin += 3600 * 1000.0; + } + + QList ticks; + for ( int i = 0; i < 3600; i += secondsMinor ) + ticks += dstMin + i * 1000.0; + + return ticks; +} + +static QwtScaleDiv qwtDivideToSeconds( + const QDateTime &minDate, const QDateTime &maxDate, + double stepSize, int maxMinSteps, + QwtDate::IntervalType intervalType ) +{ + // calculate the min step size + double minStepSize = 0; + + if ( maxMinSteps > 1 ) + { + minStepSize = qwtDivideMajorStep( stepSize, + maxMinSteps, intervalType ); + } + + bool daylightSaving = false; + if ( minDate.timeSpec() == Qt::LocalTime ) + { + daylightSaving = intervalType > QwtDate::Hour; + if ( intervalType == QwtDate::Hour ) + { + daylightSaving = stepSize > 1; + } + } + + const double s = qwtMsecsForType( intervalType ) / 1000; + const int secondsMajor = static_cast( stepSize * s ); + const double secondsMinor = minStepSize * s; + + // UTC excludes daylight savings. So from the difference + // of a date and its UTC counterpart we can find out + // the daylight saving hours + + const double utcOffset = QwtDate::utcOffset( minDate ); + double dstOff = 0; + + QList majorTicks; + QList mediumTicks; + QList minorTicks; + + for ( QDateTime dt = minDate; dt <= maxDate; + dt = dt.addSecs( secondsMajor ) ) + { + if ( !dt.isValid() ) + break; + + double majorValue = QwtDate::toDouble( dt ); + + if ( daylightSaving ) + { + const double offset = utcOffset - QwtDate::utcOffset( dt ); + majorValue += offset * 1000.0; + + if ( offset > dstOff ) + { + // we add some minor ticks for the DST hour, + // otherwise the ticks will be unaligned: 0, 2, 3, 5 ... + minorTicks += qwtDstTicks( + dt, secondsMajor, qRound( secondsMinor ) ); + } + + dstOff = offset; + } + + if ( majorTicks.isEmpty() || majorTicks.last() != majorValue ) + majorTicks += majorValue; + + if ( secondsMinor > 0.0 ) + { + const int numMinorSteps = qFloor( secondsMajor / secondsMinor ); + + for ( int i = 1; i < numMinorSteps; i++ ) + { + const QDateTime mt = dt.addMSecs( + qRound64( i * secondsMinor * 1000 ) ); + + double minorValue = QwtDate::toDouble( mt ); + if ( daylightSaving ) + { + const double offset = utcOffset - QwtDate::utcOffset( mt ); + minorValue += offset * 1000.0; + } + + if ( minorTicks.isEmpty() || minorTicks.last() != minorValue ) + { + const bool isMedium = ( numMinorSteps % 2 == 0 ) + && ( i != 1 ) && ( i == numMinorSteps / 2 ); + + if ( isMedium ) + mediumTicks += minorValue; + else + minorTicks += minorValue; + } + } + } + } + + QwtScaleDiv scaleDiv; + + scaleDiv.setInterval( QwtDate::toDouble( minDate ), + QwtDate::toDouble( maxDate ) ); + + scaleDiv.setTicks( QwtScaleDiv::MajorTick, majorTicks ); + scaleDiv.setTicks( QwtScaleDiv::MediumTick, mediumTicks ); + scaleDiv.setTicks( QwtScaleDiv::MinorTick, minorTicks ); + + return scaleDiv; +} + +static QwtScaleDiv qwtDivideToMonths( + QDateTime &minDate, const QDateTime &maxDate, + double stepSize, int maxMinSteps ) +{ + // months are intervals with non + // equidistant ( in ms ) steps: we have to build the + // scale division manually + + int minStepDays = 0; + int minStepSize = 0.0; + + if ( maxMinSteps > 1 ) + { + if ( stepSize == 1 ) + { + if ( maxMinSteps >= 30 ) + minStepDays = 1; + else if ( maxMinSteps >= 6 ) + minStepDays = 5; + else if ( maxMinSteps >= 3 ) + minStepDays = 10; + + minStepDays = 15; + } + else + { + minStepSize = qwtDivideMajorStep( + stepSize, maxMinSteps, QwtDate::Month ); + } + } + + QList majorTicks; + QList mediumTicks; + QList minorTicks; + + for ( QDateTime dt = minDate; + dt <= maxDate; dt = dt.addMonths( stepSize ) ) + { + if ( !dt.isValid() ) + break; + + majorTicks += QwtDate::toDouble( dt ); + + if ( minStepDays > 0 ) + { + for ( int days = minStepDays; + days < 30; days += minStepDays ) + { + const double tick = QwtDate::toDouble( dt.addDays( days ) ); + + if ( days == 15 && minStepDays != 15 ) + mediumTicks += tick; + else + minorTicks += tick; + } + } + else if ( minStepSize > 0.0 ) + { + const int numMinorSteps = qRound( stepSize / (double) minStepSize ); + + for ( int i = 1; i < numMinorSteps; i++ ) + { + const double minorValue = + QwtDate::toDouble( dt.addMonths( i * minStepSize ) ); + + if ( ( numMinorSteps % 2 == 0 ) && ( i == numMinorSteps / 2 ) ) + mediumTicks += minorValue; + else + minorTicks += minorValue; + } + } + } + + QwtScaleDiv scaleDiv; + scaleDiv.setInterval( QwtDate::toDouble( minDate ), + QwtDate::toDouble( maxDate ) ); + + scaleDiv.setTicks( QwtScaleDiv::MajorTick, majorTicks ); + scaleDiv.setTicks( QwtScaleDiv::MediumTick, mediumTicks ); + scaleDiv.setTicks( QwtScaleDiv::MinorTick, minorTicks ); + + return scaleDiv; +} + +static QwtScaleDiv qwtDivideToYears( + const QDateTime &minDate, const QDateTime &maxDate, + double stepSize, int maxMinSteps ) +{ + QList majorTicks; + QList mediumTicks; + QList minorTicks; + + double minStepSize = 0.0; + + if ( maxMinSteps > 1 ) + { + minStepSize = qwtDivideMajorStep( + stepSize, maxMinSteps, QwtDate::Year ); + } + + int numMinorSteps = 0; + if ( minStepSize > 0.0 ) + numMinorSteps = qFloor( stepSize / minStepSize ); + + bool dateBC = minDate.date().year() < -1; + + for ( QDateTime dt = minDate; dt <= maxDate; + dt = dt.addYears( stepSize ) ) + { + if ( dateBC && dt.date().year() > 1 ) + { + // there is no year 0 in the Julian calendar + dt = dt.addYears( -1 ); + dateBC = false; + } + + if ( !dt.isValid() ) + break; + + majorTicks += QwtDate::toDouble( dt ); + + for ( int i = 1; i < numMinorSteps; i++ ) + { + QDateTime tickDate; + + const double years = qRound( i * minStepSize ); + if ( years >= INT_MAX / 12 ) + { + tickDate = dt.addYears( years ); + } + else + { + tickDate = dt.addMonths( qRound( years * 12 ) ); + } + + const bool isMedium = ( numMinorSteps > 2 ) && + ( numMinorSteps % 2 == 0 ) && ( i == numMinorSteps / 2 ); + + const double minorValue = QwtDate::toDouble( tickDate ); + if ( isMedium ) + mediumTicks += minorValue; + else + minorTicks += minorValue; + } + + if ( QwtDate::maxDate().addYears( -stepSize ) < dt.date() ) + { + break; + } + } + + QwtScaleDiv scaleDiv; + scaleDiv.setInterval( QwtDate::toDouble( minDate ), + QwtDate::toDouble( maxDate ) ); + + scaleDiv.setTicks( QwtScaleDiv::MajorTick, majorTicks ); + scaleDiv.setTicks( QwtScaleDiv::MediumTick, mediumTicks ); + scaleDiv.setTicks( QwtScaleDiv::MinorTick, minorTicks ); + + return scaleDiv; +} + +class QwtDateScaleEngine::PrivateData +{ +public: + PrivateData( Qt::TimeSpec spec ): + timeSpec( spec ), + utcOffset( 0 ), + week0Type( QwtDate::FirstThursday ), + maxWeeks( 4 ) + { + } + + Qt::TimeSpec timeSpec; + int utcOffset; + QwtDate::Week0Type week0Type; + int maxWeeks; +}; + + +/*! + \brief Constructor + + The engine is initialized to build scales for the + given time specification. It classifies intervals > 4 weeks + as >= Qt::Month. The first week of a year is defined like + for QwtDate::FirstThursday. + + \param timeSpec Time specification + + \sa setTimeSpec(), setMaxWeeks(), setWeek0Type() + */ +QwtDateScaleEngine::QwtDateScaleEngine( Qt::TimeSpec timeSpec ): + QwtLinearScaleEngine( 10 ) +{ + d_data = new PrivateData( timeSpec ); +} + +//! Destructor +QwtDateScaleEngine::~QwtDateScaleEngine() +{ + delete d_data; +} + +/*! + Set the time specification used by the engine + + \param timeSpec Time specification + \sa timeSpec(), setUtcOffset(), toDateTime() + */ +void QwtDateScaleEngine::setTimeSpec( Qt::TimeSpec timeSpec ) +{ + d_data->timeSpec = timeSpec; +} + +/*! + \return Time specification used by the engine + \sa setTimeSpec(), utcOffset(), toDateTime() + */ +Qt::TimeSpec QwtDateScaleEngine::timeSpec() const +{ + return d_data->timeSpec; +} + +/*! + Set the offset in seconds from Coordinated Universal Time + + \param seconds Offset in seconds + + \note The offset has no effect beside for the time specification + Qt::OffsetFromUTC. + + \sa QDate::utcOffset(), setTimeSpec(), toDateTime() + */ +void QwtDateScaleEngine::setUtcOffset( int seconds ) +{ + d_data->utcOffset = seconds; +} + +/*! + \return Offset in seconds from Coordinated Universal Time + \note The offset has no effect beside for the time specification + Qt::OffsetFromUTC. + + \sa QDate::setUtcOffset(), setTimeSpec(), toDateTime() + */ +int QwtDateScaleEngine::utcOffset() const +{ + return d_data->utcOffset; +} + +/*! + Sets how to identify the first week of a year. + + \param week0Type Mode how to identify the first week of a year + + \sa week0Type(), setMaxWeeks() + \note week0Type has no effect beside for intervals classified as + QwtDate::Week. + */ +void QwtDateScaleEngine::setWeek0Type( QwtDate::Week0Type week0Type ) +{ + d_data->week0Type = week0Type; +} + +/*! + \return Setting how to identify the first week of a year. + \sa setWeek0Type(), maxWeeks() + */ +QwtDate::Week0Type QwtDateScaleEngine::week0Type() const +{ + return d_data->week0Type; +} + +/*! + Set a upper limit for the number of weeks, when an interval + can be classified as Qt::Week. + + The default setting is 4 weeks. + + \param weeks Upper limit for the number of weeks + + \note In business charts a year is often devided + into weeks [1-52] + \sa maxWeeks(), setWeek0Type() + */ +void QwtDateScaleEngine::setMaxWeeks( int weeks ) +{ + d_data->maxWeeks = qMax( weeks, 0 ); +} + +/*! + \return Upper limit for the number of weeks, when an interval + can be classified as Qt::Week. + \sa setMaxWeeks(), week0Type() + */ +int QwtDateScaleEngine::maxWeeks() const +{ + return d_data->maxWeeks; +} + +/*! + Classification of a date/time interval division + + \param minDate Minimum ( = earlier ) of the interval + \param maxDate Maximum ( = later ) of the interval + \param maxSteps Maximum for the number of steps + + \return Interval classification + */ +QwtDate::IntervalType QwtDateScaleEngine::intervalType( + const QDateTime &minDate, const QDateTime &maxDate, + int maxSteps ) const +{ + const double jdMin = minDate.date().toJulianDay(); + const double jdMax = maxDate.date().toJulianDay(); + + if ( ( jdMax - jdMin ) / 365 > maxSteps ) + return QwtDate::Year; + + const int months = qwtRoundedIntervalWidth( minDate, maxDate, QwtDate::Month ); + if ( months > maxSteps * 6 ) + return QwtDate::Year; + + const int days = qwtRoundedIntervalWidth( minDate, maxDate, QwtDate::Day ); + const int weeks = qwtRoundedIntervalWidth( minDate, maxDate, QwtDate::Week ); + + if ( weeks > d_data->maxWeeks ) + { + if ( days > 4 * maxSteps * 7 ) + return QwtDate::Month; + } + + if ( days > maxSteps * 7 ) + return QwtDate::Week; + + const int hours = qwtRoundedIntervalWidth( minDate, maxDate, QwtDate::Hour ); + if ( hours > maxSteps * 24 ) + return QwtDate::Day; + + const int seconds = qwtRoundedIntervalWidth( minDate, maxDate, QwtDate::Second ); + + if ( seconds >= maxSteps * 3600 ) + return QwtDate::Hour; + + if ( seconds >= maxSteps * 60 ) + return QwtDate::Minute; + + if ( seconds >= maxSteps ) + return QwtDate::Second; + + return QwtDate::Millisecond; +} + +/*! + Align and divide an interval + + The algorithm aligns and divides the interval into steps. + + Datetime interval divisions are usually not equidistant and the + calculated stepSize is can only be used as an approximation + for the steps calculated by divideScale(). + + \param maxNumSteps Max. number of steps + \param x1 First limit of the interval (In/Out) + \param x2 Second limit of the interval (In/Out) + \param stepSize Step size (Out) + + \sa QwtScaleEngine::setAttribute() +*/ +void QwtDateScaleEngine::autoScale( int maxNumSteps, + double &x1, double &x2, double &stepSize ) const +{ + stepSize = 0.0; + + QwtInterval interval( x1, x2 ); + interval = interval.normalized(); + + interval.setMinValue( interval.minValue() - lowerMargin() ); + interval.setMaxValue( interval.maxValue() + upperMargin() ); + + if ( testAttribute( QwtScaleEngine::Symmetric ) ) + interval = interval.symmetrize( reference() ); + + if ( testAttribute( QwtScaleEngine::IncludeReference ) ) + interval = interval.extend( reference() ); + + if ( interval.width() == 0.0 ) + interval = buildInterval( interval.minValue() ); + + const QDateTime from = toDateTime( interval.minValue() ); + const QDateTime to = toDateTime( interval.maxValue() ); + + if ( from.isValid() && to.isValid() ) + { + if ( maxNumSteps < 1 ) + maxNumSteps = 1; + + const QwtDate::IntervalType intvType = + intervalType( from, to, maxNumSteps ); + + double width = qwtIntervalWidth( from, to, intvType ); + width = QwtScaleArithmetic::divideInterval( width, maxNumSteps, 10 ); + + if ( width != 0.0 && !testAttribute( QwtScaleEngine::Floating ) ) + { + const QDateTime d1 = alignDate( from, width, intvType, false ); + const QDateTime d2 = alignDate( to, width, intvType, true ); + + interval.setMinValue( QwtDate::toDouble( d1 ) ); + interval.setMaxValue( QwtDate::toDouble( d2 ) ); + } + + stepSize = width * qwtMsecsForType( intvType ); + } + + x1 = interval.minValue(); + x2 = interval.maxValue(); + + if ( testAttribute( QwtScaleEngine::Inverted ) ) + { + qSwap( x1, x2 ); + stepSize = -stepSize; + } +} + +/*! + \brief Calculate a scale division for a date/time interval + + \param x1 First interval limit + \param x2 Second interval limit + \param maxMajorSteps Maximum for the number of major steps + \param maxMinorSteps Maximum number of minor steps + \param stepSize Step size. If stepSize == 0, the scaleEngine + calculates one. + \return Calculated scale division +*/ +QwtScaleDiv QwtDateScaleEngine::divideScale( double x1, double x2, + int maxMajorSteps, int maxMinorSteps, double stepSize ) const +{ + if ( maxMajorSteps < 1 ) + maxMajorSteps = 1; + + const double min = qMin( x1, x2 ); + const double max = qMax( x1, x2 ); + + const QDateTime from = toDateTime( min ); + const QDateTime to = toDateTime( max ); + + if ( from == to ) + return QwtScaleDiv(); + + stepSize = qAbs( stepSize ); + if ( stepSize > 0.0 ) + { + // as interval types above hours are not equidistant + // ( even days might have 23/25 hours because of daylight saving ) + // the stepSize is used as a hint only + + maxMajorSteps = qCeil( ( max - min ) / stepSize ); + } + + const QwtDate::IntervalType intvType = + intervalType( from, to, maxMajorSteps ); + + QwtScaleDiv scaleDiv; + + if ( intvType == QwtDate::Millisecond ) + { + // for milliseconds and below we can use the decimal system + scaleDiv = QwtLinearScaleEngine::divideScale( min, max, + maxMajorSteps, maxMinorSteps, stepSize ); + } + else + { + const QDateTime minDate = QwtDate::floor( from, intvType ); + const QDateTime maxDate = QwtDate::ceil( to, intvType ); + + scaleDiv = buildScaleDiv( minDate, maxDate, + maxMajorSteps, maxMinorSteps, intvType ); + + // scaleDiv has been calculated from an extended interval + // adjusted to the step size. We have to shrink it again. + + scaleDiv = scaleDiv.bounded( min, max ); + } + + if ( x1 > x2 ) + scaleDiv.invert(); + + return scaleDiv; +} + +QwtScaleDiv QwtDateScaleEngine::buildScaleDiv( + const QDateTime &minDate, const QDateTime &maxDate, + int maxMajorSteps, int maxMinorSteps, + QwtDate::IntervalType intervalType ) const +{ + // calculate the step size + const double stepSize = qwtDivideScale( + qwtIntervalWidth( minDate, maxDate, intervalType ), + maxMajorSteps, intervalType ); + + // align minDate to the step size + QDateTime dt0 = alignDate( minDate, stepSize, intervalType, false ); + if ( !dt0.isValid() ) + { + // the floored date is out of the range of a + // QDateTime - we ceil instead. + dt0 = alignDate( minDate, stepSize, intervalType, true ); + } + + QwtScaleDiv scaleDiv; + + if ( intervalType <= QwtDate::Week ) + { + scaleDiv = qwtDivideToSeconds( dt0, maxDate, + stepSize, maxMinorSteps, intervalType ); + } + else + { + if( intervalType == QwtDate::Month ) + { + scaleDiv = qwtDivideToMonths( dt0, maxDate, + stepSize, maxMinorSteps ); + } + else if ( intervalType == QwtDate::Year ) + { + scaleDiv = qwtDivideToYears( dt0, maxDate, + stepSize, maxMinorSteps ); + } + } + + + return scaleDiv; +} + +/*! + Align a date/time value for a step size + + For Qt::Day alignments there is no "natural day 0" - + instead the first day of the year is used to avoid jumping + major ticks positions when panning a scale. For other alignments + ( f.e according to the first day of the month ) alignDate() + has to be overloaded. + + \param dateTime Date/time value + \param stepSize Step size + \param intervalType Interval type + \param up When true dateTime is ceiled - otherwise it is floored + + \return Aligned date/time value + */ +QDateTime QwtDateScaleEngine::alignDate( + const QDateTime &dateTime, double stepSize, + QwtDate::IntervalType intervalType, bool up ) const +{ + // what about: (year == 1582 && month == 10 && day > 4 && day < 15) ?? + + QDateTime dt = dateTime; + + if ( dateTime.timeSpec() == Qt::OffsetFromUTC ) + { + dt.setUtcOffset( 0 ); + } + + switch( intervalType ) + { + case QwtDate::Millisecond: + { + const int ms = qwtAlignValue( + dt.time().msec(), stepSize, up ) ; + + dt = QwtDate::floor( dateTime, QwtDate::Second ); + dt = dt.addMSecs( ms ); + + break; + } + case QwtDate::Second: + { + const int s = qwtAlignValue( + dt.time().second(), stepSize, up ); + + dt = QwtDate::floor( dt, QwtDate::Minute ); + dt = dt.addSecs( s ); + + break; + } + case QwtDate::Minute: + { + const int m = qwtAlignValue( + dt.time().minute(), stepSize, up ); + + dt = QwtDate::floor( dt, QwtDate::Hour ); + dt = dt.addSecs( m * 60 ); + + break; + } + case QwtDate::Hour: + { + const int h = qwtAlignValue( + dt.time().hour(), stepSize, up ); + + dt = QwtDate::floor( dt, QwtDate::Day ); + dt = dt.addSecs( h * 3600 ); + + break; + } + case QwtDate::Day: + { + // What date do we expect f.e. from an alignment of 5 days ?? + // Aligning them to the beginning of the year avoids at least + // jumping major ticks when panning + + const int d = qwtAlignValue( + dt.date().dayOfYear(), stepSize, up ); + + dt = QwtDate::floor( dt, QwtDate::Year ); + dt = dt.addDays( d - 1 ); + + break; + } + case QwtDate::Week: + { + const QDate date = QwtDate::dateOfWeek0( + dt.date().year(), d_data->week0Type ); + + const int numWeeks = date.daysTo( dt.date() ) / 7; + const int d = qwtAlignValue( numWeeks, stepSize, up ) * 7; + + dt = QwtDate::floor( dt, QwtDate::Day ); + dt.setDate( date ); + dt = dt.addDays( d ); + + break; + } + case QwtDate::Month: + { + const int m = qwtAlignValue( + dt.date().month() - 1, stepSize, up ); + + dt = QwtDate::floor( dt, QwtDate::Year ); + dt = dt.addMonths( m ); + + break; + } + case QwtDate::Year: + { + const int y = qwtAlignValue( + dateTime.date().year(), stepSize, up ); + + dt = QwtDate::floor( dt, QwtDate::Day ); + if ( y == 0 ) + { + // there is no year 0 in the Julian calendar + dt.setDate( QDate( stepSize, 1, 1 ).addYears( -stepSize ) ); + } + else + { + dt.setDate( QDate( y, 1, 1 ) ); + } + + break; + } + } + + if ( dateTime.timeSpec() == Qt::OffsetFromUTC ) + { + dt.setUtcOffset( dateTime.utcOffset() ); + } + + return dt; +} + +/*! + Translate a double value into a QDateTime object. + + For QDateTime result is bounded by QwtDate::minDate() and QwtDate::maxDate() + + \return QDateTime object initialized with timeSpec() and utcOffset(). + \sa timeSpec(), utcOffset(), QwtDate::toDateTime() + */ +QDateTime QwtDateScaleEngine::toDateTime( double value ) const +{ + QDateTime dt = QwtDate::toDateTime( value, d_data->timeSpec ); + if ( !dt.isValid() ) + { + const QDate date = ( value <= 0.0 ) + ? QwtDate::minDate() : QwtDate::maxDate(); + + dt = QDateTime( date, QTime( 0, 0 ), d_data->timeSpec ); + } + + if ( d_data->timeSpec == Qt::OffsetFromUTC ) + { + dt = dt.addSecs( d_data->utcOffset ); + dt.setUtcOffset( d_data->utcOffset ); + } + + return dt; +} + diff --git a/ThirdParty/Qwt/src/qwt_date_scale_engine.h b/ThirdParty/Qwt/src/qwt_date_scale_engine.h new file mode 100644 index 0000000000..db1d0f1342 --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_date_scale_engine.h @@ -0,0 +1,77 @@ +#ifndef _QWT_DATE_SCALE_ENGINE_H_ +#define _QWT_DATE_SCALE_ENGINE_H_ 1 + +#include "qwt_date.h" +#include "qwt_scale_engine.h" + +/*! + \brief A scale engine for date/time values + + QwtDateScaleEngine builds scales from a time intervals. + Together with QwtDateScaleDraw it can be used for + axes according to date/time values. + + Years, months, weeks, days, hours and minutes are organized + in steps with non constant intervals. QwtDateScaleEngine + classifies intervals and aligns the boundaries and tick positions + according to this classification. + + QwtDateScaleEngine supports representations depending + on Qt::TimeSpec specifications. The valid range for scales + is limited by the range of QDateTime, that differs + between Qt4 and Qt5. + + Datetime values are expected as the number of milliseconds since + 1970-01-01T00:00:00 Universal Coordinated Time - also known + as "The Epoch", that can be converted to QDateTime using + QwtDate::toDateTime(). + + \sa QwtDate, QwtPlot::setAxisScaleEngine(), + QwtAbstractScale::setScaleEngine() +*/ +class QWT_EXPORT QwtDateScaleEngine: public QwtLinearScaleEngine +{ +public: + QwtDateScaleEngine( Qt::TimeSpec = Qt::LocalTime ); + virtual ~QwtDateScaleEngine(); + + void setTimeSpec( Qt::TimeSpec ); + Qt::TimeSpec timeSpec() const; + + void setUtcOffset( int seconds ); + int utcOffset() const; + + void setWeek0Type( QwtDate::Week0Type ); + QwtDate::Week0Type week0Type() const; + + void setMaxWeeks( int ); + int maxWeeks() const; + + virtual void autoScale( int maxNumSteps, + double &x1, double &x2, double &stepSize ) const; + + virtual QwtScaleDiv divideScale( + double x1, double x2, + int maxMajorSteps, int maxMinorSteps, + double stepSize = 0.0 ) const; + + virtual QwtDate::IntervalType intervalType( + const QDateTime &, const QDateTime &, int maxSteps ) const; + + QDateTime toDateTime( double ) const; + +protected: + virtual QDateTime alignDate( const QDateTime &, double stepSize, + QwtDate::IntervalType, bool up ) const; + +private: + QwtScaleDiv buildScaleDiv( const QDateTime &, const QDateTime &, + int maxMajorSteps, int maxMinorSteps, + QwtDate::IntervalType ) const; + +private: + class PrivateData; + PrivateData *d_data; +}; + +#endif diff --git a/ThirdParty/Qwt/src/qwt_dial.cpp b/ThirdParty/Qwt/src/qwt_dial.cpp new file mode 100644 index 0000000000..1440eb14a4 --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_dial.cpp @@ -0,0 +1,872 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#include "qwt_dial.h" +#include "qwt_dial_needle.h" +#include "qwt_math.h" +#include "qwt_scale_engine.h" +#include "qwt_scale_map.h" +#include "qwt_round_scale_draw.h" +#include "qwt_painter.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static inline double qwtAngleDist( double a1, double a2 ) +{ + double dist = qAbs( a2 - a1 ); + if ( dist > 360.0 ) + dist -= 360.0; + + return dist; +} + +static inline bool qwtIsOnArc( double angle, double min, double max ) +{ + if ( min < max ) + { + return ( angle >= min ) && ( angle <= max ); + } + else + { + return ( angle >= min ) || ( angle <= max ); + } +} + +static inline double qwtBoundedAngle( double min, double angle, double max ) +{ + double from = qwtNormalizeDegrees( min ); + double to = qwtNormalizeDegrees( max ); + + double a; + + if ( qwtIsOnArc( angle, from, to ) ) + { + a = angle; + if ( a < min ) + a += 360.0; + } + else + { + if ( qwtAngleDist( angle, from ) < + qwtAngleDist( angle, to ) ) + { + a = min; + } + else + { + a = max; + } + } + + return a; +} + +class QwtDial::PrivateData +{ +public: + PrivateData(): + frameShadow( Sunken ), + lineWidth( 0 ), + mode( RotateNeedle ), + origin( 90.0 ), + minScaleArc( 0.0 ), + maxScaleArc( 0.0 ), + needle( NULL ), + arcOffset( 0.0 ), + mouseOffset( 0.0 ) + { + } + + ~PrivateData() + { + delete needle; + } + Shadow frameShadow; + int lineWidth; + + QwtDial::Mode mode; + + double origin; + double minScaleArc; + double maxScaleArc; + + double scalePenWidth; + QwtDialNeedle *needle; + + double arcOffset; + double mouseOffset; + + QPixmap pixmapCache; +}; + +/*! + \brief Constructor + \param parent Parent widget + + Create a dial widget with no needle. The scale is initialized + to [ 0.0, 360.0 ] and 360 steps ( QwtAbstractSlider::setTotalSteps() ). + The origin of the scale is at 90°, + + The value is set to 0.0. + + The default mode is QwtDial::RotateNeedle. +*/ +QwtDial::QwtDial( QWidget* parent ): + QwtAbstractSlider( parent ) +{ + d_data = new PrivateData; + + setFocusPolicy( Qt::TabFocus ); + + QPalette p = palette(); + for ( int i = 0; i < QPalette::NColorGroups; i++ ) + { + const QPalette::ColorGroup colorGroup = + static_cast( i ); + + // Base: background color of the circle inside the frame. + // WindowText: background color of the circle inside the scale + + p.setColor( colorGroup, QPalette::WindowText, + p.color( colorGroup, QPalette::Base ) ); + } + setPalette( p ); + + QwtRoundScaleDraw* scaleDraw = new QwtRoundScaleDraw(); + scaleDraw->setRadius( 0 ); + + setScaleDraw( scaleDraw ); + + setScaleArc( 0.0, 360.0 ); // scale as a full circle + + setScaleMaxMajor( 10 ); + setScaleMaxMinor( 5 ); + + setValue( 0.0 ); +} + +//! Destructor +QwtDial::~QwtDial() +{ + delete d_data; +} + +/*! + Sets the frame shadow value from the frame style. + + \param shadow Frame shadow + \sa setLineWidth(), QFrame::setFrameShadow() +*/ +void QwtDial::setFrameShadow( Shadow shadow ) +{ + if ( shadow != d_data->frameShadow ) + { + invalidateCache(); + + d_data->frameShadow = shadow; + if ( lineWidth() > 0 ) + update(); + } +} + +/*! + \return Frame shadow + /sa setFrameShadow(), lineWidth(), QFrame::frameShadow() +*/ +QwtDial::Shadow QwtDial::frameShadow() const +{ + return d_data->frameShadow; +} + +/*! + Sets the line width of the frame + + \param lineWidth Line width + \sa setFrameShadow() +*/ +void QwtDial::setLineWidth( int lineWidth ) +{ + if ( lineWidth < 0 ) + lineWidth = 0; + + if ( d_data->lineWidth != lineWidth ) + { + invalidateCache(); + + d_data->lineWidth = lineWidth; + update(); + } +} + +/*! + \return Line width of the frame + \sa setLineWidth(), frameShadow(), lineWidth() +*/ +int QwtDial::lineWidth() const +{ + return d_data->lineWidth; +} + +/*! + \return bounding rectangle of the circle inside the frame + \sa setLineWidth(), scaleInnerRect(), boundingRect() +*/ +QRect QwtDial::innerRect() const +{ + const int lw = lineWidth(); + return boundingRect().adjusted( lw, lw, -lw, -lw ); +} + +/*! + \return bounding rectangle of the dial including the frame + \sa setLineWidth(), scaleInnerRect(), innerRect() +*/ +QRect QwtDial::boundingRect() const +{ + const QRect cr = contentsRect(); + + const double dim = qMin( cr.width(), cr.height() ); + + QRect inner( 0, 0, dim, dim ); + inner.moveCenter( cr.center() ); + + return inner; +} + +/*! + \return rectangle inside the scale + \sa setLineWidth(), boundingRect(), innerRect() +*/ +QRect QwtDial::scaleInnerRect() const +{ + QRect rect = innerRect(); + + const QwtAbstractScaleDraw *sd = scaleDraw(); + if ( sd ) + { + int scaleDist = qCeil( sd->extent( font() ) ); + scaleDist++; // margin + + rect.adjust( scaleDist, scaleDist, -scaleDist, -scaleDist ); + } + + return rect; +} + +/*! + \brief Change the mode of the dial. + \param mode New mode + + In case of QwtDial::RotateNeedle the needle is rotating, in case of + QwtDial::RotateScale, the needle points to origin() + and the scale is rotating. + + The default mode is QwtDial::RotateNeedle. + + \sa mode(), setValue(), setOrigin() +*/ +void QwtDial::setMode( Mode mode ) +{ + if ( mode != d_data->mode ) + { + invalidateCache(); + + d_data->mode = mode; + sliderChange(); + } +} + +/*! + \return Mode of the dial. + \sa setMode(), origin(), setScaleArc(), value() +*/ +QwtDial::Mode QwtDial::mode() const +{ + return d_data->mode; +} + +/*! + Invalidate the internal caches used to speed up repainting + */ +void QwtDial::invalidateCache() +{ + d_data->pixmapCache = QPixmap(); +} + +/*! + Paint the dial + \param event Paint event +*/ +void QwtDial::paintEvent( QPaintEvent *event ) +{ + QPainter painter( this ); + painter.setClipRegion( event->region() ); + + QStyleOption opt; + opt.init(this); + style()->drawPrimitive(QStyle::PE_Widget, &opt, &painter, this); + + if ( d_data->mode == QwtDial::RotateScale ) + { + painter.save(); + painter.setRenderHint( QPainter::Antialiasing, true ); + + drawContents( &painter ); + + painter.restore(); + } + + const QRect r = contentsRect(); + if ( r.size() != d_data->pixmapCache.size() ) + { + d_data->pixmapCache = QwtPainter::backingStore( this, r.size() ); + d_data->pixmapCache.fill( Qt::transparent ); + + QPainter p( &d_data->pixmapCache ); + p.setRenderHint( QPainter::Antialiasing, true ); + p.translate( -r.topLeft() ); + + if ( d_data->mode != QwtDial::RotateScale ) + drawContents( &p ); + + if ( lineWidth() > 0 ) + drawFrame( &p ); + + if ( d_data->mode != QwtDial::RotateNeedle ) + drawNeedle( &p ); + } + + painter.drawPixmap( r.topLeft(), d_data->pixmapCache ); + + if ( d_data->mode == QwtDial::RotateNeedle ) + drawNeedle( &painter ); + + if ( hasFocus() ) + drawFocusIndicator( &painter ); +} + +/*! + Draw the focus indicator + \param painter Painter +*/ +void QwtDial::drawFocusIndicator( QPainter *painter ) const +{ + QwtPainter::drawFocusRect( painter, this, boundingRect() ); +} + +/*! + Draw the frame around the dial + + \param painter Painter + \sa lineWidth(), frameShadow() +*/ +void QwtDial::drawFrame( QPainter *painter ) +{ + QwtPainter::drawRoundFrame( painter, boundingRect(), + palette(), lineWidth(), d_data->frameShadow ); +} + +/*! + \brief Draw the contents inside the frame + + QPalette::Window is the background color outside of the frame. + QPalette::Base is the background color inside the frame. + QPalette::WindowText is the background color inside the scale. + + \param painter Painter + + \sa boundingRect(), innerRect(), + scaleInnerRect(), QWidget::setPalette() +*/ +void QwtDial::drawContents( QPainter *painter ) const +{ + if ( testAttribute( Qt::WA_NoSystemBackground ) || + palette().brush( QPalette::Base ) != + palette().brush( QPalette::Window ) ) + { + const QRectF br = boundingRect(); + + painter->save(); + painter->setPen( Qt::NoPen ); + painter->setBrush( palette().brush( QPalette::Base ) ); + painter->drawEllipse( br ); + painter->restore(); + } + + const QRectF insideScaleRect = scaleInnerRect(); + if ( palette().brush( QPalette::WindowText ) != + palette().brush( QPalette::Base ) ) + { + painter->save(); + painter->setPen( Qt::NoPen ); + painter->setBrush( palette().brush( QPalette::WindowText ) ); + painter->drawEllipse( insideScaleRect ); + painter->restore(); + } + + const QPointF center = insideScaleRect.center(); + const double radius = 0.5 * insideScaleRect.width(); + + painter->save(); + drawScale( painter, center, radius ); + painter->restore(); + + painter->save(); + drawScaleContents( painter, center, radius ); + painter->restore(); +} + +/*! + Draw the needle + + \param painter Painter + \param center Center of the dial + \param radius Length for the needle + \param direction Direction of the needle in degrees, counter clockwise + \param colorGroup ColorGroup +*/ +void QwtDial::drawNeedle( QPainter *painter, const QPointF ¢er, + double radius, double direction, QPalette::ColorGroup colorGroup ) const +{ + if ( d_data->needle ) + { + direction = 360.0 - direction; // counter clockwise + d_data->needle->draw( painter, center, radius, direction, colorGroup ); + } +} + +void QwtDial::drawNeedle( QPainter *painter ) const +{ + if ( !isValid() ) + return; + + QPalette::ColorGroup colorGroup; + if ( isEnabled() ) + colorGroup = hasFocus() ? QPalette::Active : QPalette::Inactive; + else + colorGroup = QPalette::Disabled; + + const QRectF sr = scaleInnerRect(); + + painter->save(); + painter->setRenderHint( QPainter::Antialiasing, true ); + drawNeedle( painter, sr.center(), 0.5 * sr.width(), + transform( value() ) + 270.0, colorGroup ); + painter->restore(); +} + +/*! + Draw the scale + + \param painter Painter + \param center Center of the dial + \param radius Radius of the scale +*/ +void QwtDial::drawScale( QPainter *painter, + const QPointF ¢er, double radius ) const +{ + QwtRoundScaleDraw *sd = const_cast( scaleDraw() ); + if ( sd == NULL ) + return; + + sd->setRadius( radius ); + sd->moveCenter( center ); + + QPalette pal = palette(); + + const QColor textColor = pal.color( QPalette::Text ); + pal.setColor( QPalette::WindowText, textColor ); // ticks, backbone + + painter->setFont( font() ); + painter->setPen( QPen( textColor, sd->penWidth() ) ); + + painter->setBrush( Qt::red ); + sd->draw( painter, pal ); +} + +/*! + Draw the contents inside the scale + + Paints nothing. + + \param painter Painter + \param center Center of the contents circle + \param radius Radius of the contents circle +*/ +void QwtDial::drawScaleContents( QPainter *painter, + const QPointF ¢er, double radius ) const +{ + Q_UNUSED(painter); + Q_UNUSED(center); + Q_UNUSED(radius); +} + +/*! + Set a needle for the dial + + \param needle Needle + + \warning The needle will be deleted, when a different needle is + set or in ~QwtDial() +*/ +void QwtDial::setNeedle( QwtDialNeedle *needle ) +{ + if ( needle != d_data->needle ) + { + if ( d_data->needle ) + delete d_data->needle; + + d_data->needle = needle; + update(); + } +} + +/*! + \return needle + \sa setNeedle() +*/ +const QwtDialNeedle *QwtDial::needle() const +{ + return d_data->needle; +} + +/*! + \return needle + \sa setNeedle() +*/ +QwtDialNeedle *QwtDial::needle() +{ + return d_data->needle; +} + +//! \return the scale draw +QwtRoundScaleDraw *QwtDial::scaleDraw() +{ + return static_cast( abstractScaleDraw() ); +} + +//! \return the scale draw +const QwtRoundScaleDraw *QwtDial::scaleDraw() const +{ + return static_cast( abstractScaleDraw() ); +} + +/*! + Set an individual scale draw + + The motivation for setting a scale draw is often + to overload QwtRoundScaleDraw::label() to return + individual tick labels. + + \param scaleDraw Scale draw + \warning The previous scale draw is deleted +*/ +void QwtDial::setScaleDraw( QwtRoundScaleDraw *scaleDraw ) +{ + setAbstractScaleDraw( scaleDraw ); + sliderChange(); +} + +/*! + Change the arc of the scale + + \param minArc Lower limit + \param maxArc Upper limit + + \sa minScaleArc(), maxScaleArc() +*/ +void QwtDial::setScaleArc( double minArc, double maxArc ) +{ + if ( minArc != 360.0 && minArc != -360.0 ) + minArc = ::fmod( minArc, 360.0 ); + if ( maxArc != 360.0 && maxArc != -360.0 ) + maxArc = ::fmod( maxArc, 360.0 ); + + double minScaleArc = qMin( minArc, maxArc ); + double maxScaleArc = qMax( minArc, maxArc ); + + if ( maxScaleArc - minScaleArc > 360.0 ) + maxScaleArc = minScaleArc + 360.0; + + if ( ( minScaleArc != d_data->minScaleArc ) || + ( maxScaleArc != d_data->maxScaleArc ) ) + { + d_data->minScaleArc = minScaleArc; + d_data->maxScaleArc = maxScaleArc; + + invalidateCache(); + sliderChange(); + } +} + +/*! + Set the lower limit for the scale arc + + \param min Lower limit of the scale arc + \sa setScaleArc(), setMaxScaleArc() + */ +void QwtDial::setMinScaleArc( double min ) +{ + setScaleArc( min, d_data->maxScaleArc ); +} + +/*! + \return Lower limit of the scale arc + \sa setScaleArc() +*/ +double QwtDial::minScaleArc() const +{ + return d_data->minScaleArc; +} + +/*! + Set the upper limit for the scale arc + + \param max Upper limit of the scale arc + \sa setScaleArc(), setMinScaleArc() + */ +void QwtDial::setMaxScaleArc( double max ) +{ + setScaleArc( d_data->minScaleArc, max ); +} + +/*! + \return Upper limit of the scale arc + \sa setScaleArc() +*/ +double QwtDial::maxScaleArc() const +{ + return d_data->maxScaleArc; +} + +/*! + \brief Change the origin + + The origin is the angle where scale and needle is relative to. + + \param origin New origin + \sa origin() +*/ +void QwtDial::setOrigin( double origin ) +{ + invalidateCache(); + + d_data->origin = origin; + sliderChange(); +} + +/*! + The origin is the angle where scale and needle is relative to. + + \return Origin of the dial + \sa setOrigin() +*/ +double QwtDial::origin() const +{ + return d_data->origin; +} + +/*! + \return Size hint + \sa minimumSizeHint() +*/ +QSize QwtDial::sizeHint() const +{ + int sh = 0; + if ( scaleDraw() ) + sh = qCeil( scaleDraw()->extent( font() ) ); + + const int d = 6 * sh + 2 * lineWidth(); + + QSize hint( d, d ); + if ( !isReadOnly() ) + hint = hint.expandedTo( QApplication::globalStrut() ); + + return hint; +} + +/*! + \return Minimum size hint + \sa sizeHint() +*/ +QSize QwtDial::minimumSizeHint() const +{ + int sh = 0; + if ( scaleDraw() ) + sh = qCeil( scaleDraw()->extent( font() ) ); + + const int d = 3 * sh + 2 * lineWidth(); + + return QSize( d, d ); +} + +/*! + \brief Determine what to do when the user presses a mouse button. + + \param pos Mouse position + + \retval True, when the inner circle contains pos + \sa scrolledTo() +*/ +bool QwtDial::isScrollPosition( const QPoint &pos ) const +{ + const QRegion region( innerRect(), QRegion::Ellipse ); + if ( region.contains( pos ) && ( pos != innerRect().center() ) ) + { + double angle = QLineF( rect().center(), pos ).angle(); + if ( d_data->mode == QwtDial::RotateScale ) + angle = 360.0 - angle; + + double valueAngle = + qwtNormalizeDegrees( 90.0 - transform( value() ) ); + + d_data->mouseOffset = qwtNormalizeDegrees( angle - valueAngle ); + d_data->arcOffset = scaleMap().p1(); + + return true; + } + + return false; +} + +/*! + \brief Determine the value for a new position of the + slider handle. + + \param pos Mouse position + + \return Value for the mouse position + \sa isScrollPosition() +*/ +double QwtDial::scrolledTo( const QPoint &pos ) const +{ + double angle = QLineF( rect().center(), pos ).angle(); + if ( d_data->mode == QwtDial::RotateScale ) + { + angle += scaleMap().p1() - d_data->arcOffset; + angle = 360.0 - angle; + } + + angle = qwtNormalizeDegrees( angle - d_data->mouseOffset ); + angle = qwtNormalizeDegrees( 90.0 - angle ); + + if ( scaleMap().pDist() >= 360.0 ) + { + if ( angle < scaleMap().p1() ) + angle += 360.0; + + if ( !wrapping() ) + { + double boundedAngle = angle; + + const double arc = angle - transform( value() ); + if ( qAbs( arc ) > 180.0 ) + { + boundedAngle = ( arc > 0 ) + ? scaleMap().p1() : scaleMap().p2(); + } + + d_data->mouseOffset += ( boundedAngle - angle ); + + angle = boundedAngle; + } + } + else + { + const double boundedAngle = + qwtBoundedAngle( scaleMap().p1(), angle, scaleMap().p2() ); + + if ( !wrapping() ) + d_data->mouseOffset += ( boundedAngle - angle ); + + angle = boundedAngle; + } + + return invTransform( angle ); +} + +/*! + Change Event handler + \param event Change event + + Invalidates internal paint caches if necessary +*/ +void QwtDial::changeEvent( QEvent *event ) +{ + switch( event->type() ) + { + case QEvent::EnabledChange: + case QEvent::FontChange: + case QEvent::StyleChange: + case QEvent::PaletteChange: + case QEvent::LanguageChange: + case QEvent::LocaleChange: + { + invalidateCache(); + break; + } + default: + break; + } + + QwtAbstractSlider::changeEvent( event ); +} + +/*! + Wheel Event handler + \param event Wheel event +*/ +void QwtDial::wheelEvent( QWheelEvent *event ) +{ + const QRegion region( innerRect(), QRegion::Ellipse ); + if ( region.contains( event->pos() ) ) + QwtAbstractSlider::wheelEvent( event ); +} + +void QwtDial::setAngleRange( double angle, double span ) +{ + QwtRoundScaleDraw *sd = const_cast( scaleDraw() ); + if ( sd ) + { + angle = qwtNormalizeDegrees( angle - 270.0 ); + sd->setAngleRange( angle, angle + span ); + } +} + +/*! + Invalidate the internal caches and call + QwtAbstractSlider::scaleChange() + */ +void QwtDial::scaleChange() +{ + invalidateCache(); + QwtAbstractSlider::scaleChange(); +} + +void QwtDial::sliderChange() +{ + setAngleRange( d_data->origin + d_data->minScaleArc, + d_data->maxScaleArc - d_data->minScaleArc ); + + if ( mode() == RotateScale ) + { + const double arc = transform( value() ) - scaleMap().p1(); + setAngleRange( d_data->origin - arc, + d_data->maxScaleArc - d_data->minScaleArc ); + } + + QwtAbstractSlider::sliderChange(); +} diff --git a/ThirdParty/Qwt/src/qwt_dial.h b/ThirdParty/Qwt/src/qwt_dial.h new file mode 100644 index 0000000000..a409b4be60 --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_dial.h @@ -0,0 +1,168 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#ifndef QWT_DIAL_H +#define QWT_DIAL_H 1 + +#include "qwt_global.h" +#include "qwt_abstract_slider.h" +#include "qwt_abstract_scale_draw.h" +#include +#include + +class QwtDialNeedle; +class QwtRoundScaleDraw; + +/*! + \brief QwtDial class provides a rounded range control. + + QwtDial is intended as base class for dial widgets like + speedometers, compass widgets, clocks ... + + \image html dials2.png + + A dial contains a scale and a needle indicating the current value + of the dial. Depending on Mode one of them is fixed and the + other is rotating. If not isReadOnly() the + dial can be rotated by dragging the mouse or using keyboard inputs + (see QwtAbstractSlider::keyPressEvent()). A dial might be wrapping, what means + a rotation below/above one limit continues on the other limit (f.e compass). + The scale might cover any arc of the dial, its values are related to + the origin() of the dial. + + Often dials have to be updated very often according to values from external + devices. For these high refresh rates QwtDial caches as much as possible. + For derived classes it might be necessary to clear these caches manually + according to attribute changes using invalidateCache(). + + \sa QwtCompass, QwtAnalogClock, QwtDialNeedle + \note The controls and dials examples shows different types of dials. + \note QDial is more similar to QwtKnob than to QwtDial +*/ + +class QWT_EXPORT QwtDial: public QwtAbstractSlider +{ + Q_OBJECT + + Q_ENUMS( Shadow Mode Direction ) + + Q_PROPERTY( int lineWidth READ lineWidth WRITE setLineWidth ) + Q_PROPERTY( Shadow frameShadow READ frameShadow WRITE setFrameShadow ) + Q_PROPERTY( Mode mode READ mode WRITE setMode ) + Q_PROPERTY( double origin READ origin WRITE setOrigin ) + Q_PROPERTY( double minScaleArc READ minScaleArc WRITE setMinScaleArc ) + Q_PROPERTY( double maxScaleArc READ maxScaleArc WRITE setMaxScaleArc ) + +public: + + /*! + \brief Frame shadow + + Unfortunately it is not possible to use QFrame::Shadow + as a property of a widget that is not derived from QFrame. + The following enum is made for the designer only. It is safe + to use QFrame::Shadow instead. + */ + enum Shadow + { + //! QFrame::Plain + Plain = QFrame::Plain, + + //! QFrame::Raised + Raised = QFrame::Raised, + + //! QFrame::Sunken + Sunken = QFrame::Sunken + }; + + //! Mode controlling whether the needle or the scale is rotating + enum Mode + { + //! The needle is rotating + RotateNeedle, + + //! The needle is fixed, the scales are rotating + RotateScale + }; + + explicit QwtDial( QWidget *parent = NULL ); + virtual ~QwtDial(); + + void setFrameShadow( Shadow ); + Shadow frameShadow() const; + + void setLineWidth( int ); + int lineWidth() const; + + void setMode( Mode ); + Mode mode() const; + + void setScaleArc( double min, double max ); + + void setMinScaleArc( double min ); + double minScaleArc() const; + + void setMaxScaleArc( double min ); + double maxScaleArc() const; + + virtual void setOrigin( double ); + double origin() const; + + void setNeedle( QwtDialNeedle * ); + const QwtDialNeedle *needle() const; + QwtDialNeedle *needle(); + + QRect boundingRect() const; + QRect innerRect() const; + + virtual QRect scaleInnerRect() const; + + virtual QSize sizeHint() const; + virtual QSize minimumSizeHint() const; + + void setScaleDraw( QwtRoundScaleDraw * ); + + QwtRoundScaleDraw *scaleDraw(); + const QwtRoundScaleDraw *scaleDraw() const; + +protected: + virtual void wheelEvent( QWheelEvent * ); + virtual void paintEvent( QPaintEvent * ); + virtual void changeEvent( QEvent * ); + + virtual void drawFrame( QPainter *p ); + virtual void drawContents( QPainter * ) const; + virtual void drawFocusIndicator( QPainter * ) const; + + void invalidateCache(); + + virtual void drawScale( QPainter *, + const QPointF ¢er, double radius ) const; + + virtual void drawScaleContents( QPainter *painter, + const QPointF ¢er, double radius ) const; + + virtual void drawNeedle( QPainter *, const QPointF &, + double radius, double direction, QPalette::ColorGroup ) const; + + virtual double scrolledTo( const QPoint & ) const; + virtual bool isScrollPosition( const QPoint & ) const; + + virtual void sliderChange(); + virtual void scaleChange(); + +private: + void setAngleRange( double angle, double span ); + void drawNeedle( QPainter * ) const; + + class PrivateData; + PrivateData *d_data; +}; + +#endif diff --git a/ThirdParty/Qwt/src/qwt_dial_needle.cpp b/ThirdParty/Qwt/src/qwt_dial_needle.cpp new file mode 100644 index 0000000000..1b53a3d5b3 --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_dial_needle.cpp @@ -0,0 +1,440 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#include "qwt_dial_needle.h" +#include "qwt_global.h" +#include "qwt_math.h" +#include "qwt_painter.h" +#include +#include + +#if QT_VERSION < 0x040601 +#define qFastSin(x) qSin(x) +#define qFastCos(x) qCos(x) +#endif + +static void qwtDrawStyle1Needle( QPainter *painter, + const QPalette &palette, QPalette::ColorGroup colorGroup, + double length ) +{ + const double r[] = { 0.4, 0.3, 1, 0.8, 1, 0.3, 0.4 }; + const double a[] = { -45, -20, -15, 0, 15, 20, 45 }; + + QPainterPath path; + for ( int i = 0; i < 7; i++ ) + { + const double angle = a[i] / 180.0 * M_PI; + const double radius = r[i] * length; + + const double x = radius * qFastCos( angle ); + const double y = radius * qFastSin( angle ); + + path.lineTo( x, -y ); + } + + painter->setPen( Qt::NoPen ); + painter->setBrush( palette.brush( colorGroup, QPalette::Light ) ); + painter->drawPath( path ); +} + +static void qwtDrawStyle2Needle( QPainter *painter, + const QPalette &palette, QPalette::ColorGroup colorGroup, double length ) +{ + const double ratioX = 0.7; + const double ratioY = 0.3; + + QPainterPath path1; + path1.lineTo( ratioX * length, 0.0 ); + path1.lineTo( length, ratioY * length ); + + QPainterPath path2; + path2.lineTo( ratioX * length, 0.0 ); + path2.lineTo( length, -ratioY * length ); + + painter->setPen( Qt::NoPen ); + + painter->setBrush( palette.brush( colorGroup, QPalette::Light ) ); + painter->drawPath( path1 ); + + painter->setBrush( palette.brush( colorGroup, QPalette::Dark ) ); + painter->drawPath( path2 ); +} + +static void qwtDrawShadedPointer( QPainter *painter, + const QColor &lightColor, const QColor &darkColor, + double length, double width ) +{ + const double peak = qMax( length / 10.0, 5.0 ); + + const double knobWidth = width + 8; + QRectF knobRect( 0, 0, knobWidth, knobWidth ); + knobRect.moveCenter( QPointF(0, 0) ); + + QPainterPath path1; + path1.lineTo( 0.0, 0.5 * width ); + path1.lineTo( length - peak, 0.5 * width ); + path1.lineTo( length, 0.0 ); + path1.lineTo( 0.0, 0.0 ); + + QPainterPath arcPath1; + arcPath1.arcTo( knobRect, 0.0, -90.0 ); + + path1 = path1.united( arcPath1 ); + + QPainterPath path2; + path2.lineTo( 0.0, -0.5 * width ); + path2.lineTo( length - peak, -0.5 * width ); + path2.lineTo( length, 0.0 ); + path2.lineTo( 0.0, 0.0 ); + + QPainterPath arcPath2; + arcPath2.arcTo( knobRect, 0.0, 90.0 ); + + path2 = path2.united( arcPath2 ); + + painter->setPen( Qt::NoPen ); + + painter->setBrush( lightColor ); + painter->drawPath( path1 ); + + painter->setBrush( darkColor ); + painter->drawPath( path2 ); +} + +static void qwtDrawArrowNeedle( QPainter *painter, + const QPalette &palette, QPalette::ColorGroup colorGroup, + double length, double width ) +{ + if ( width <= 0 ) + width = qMax( length * 0.06, 9.0 ); + + const double peak = qMax( 2.0, 0.4 * width ); + + QPainterPath path; + path.moveTo( 0.0, 0.5 * width ); + path.lineTo( length - peak, 0.3 * width ); + path.lineTo( length, 0.0 ); + path.lineTo( length - peak, -0.3 * width ); + path.lineTo( 0.0, -0.5 * width ); + + QRectF br = path.boundingRect(); + + QPalette pal( palette.color( QPalette::Mid ) ); + QColor c1 = pal.color( QPalette::Light ); + QColor c2 = pal.color( QPalette::Dark ); + + QLinearGradient gradient( br.topLeft(), br.bottomLeft() ); + gradient.setColorAt( 0.0, c1 ); + gradient.setColorAt( 0.5, c1 ); + gradient.setColorAt( 0.5001, c2 ); + gradient.setColorAt( 1.0, c2 ); + + QPen pen( gradient, 1 ); + pen.setJoinStyle( Qt::MiterJoin ); + + painter->setPen( pen ); + painter->setBrush( palette.brush( colorGroup, QPalette::Mid ) ); + + painter->drawPath( path ); +} + +static void qwtDrawTriangleNeedle( QPainter *painter, + const QPalette &palette, QPalette::ColorGroup colorGroup, + double length ) +{ + const double width = qRound( length / 3.0 ); + + QPainterPath path[4]; + + path[0].lineTo( length, 0.0 ); + path[0].lineTo( 0.0, width / 2 ); + + path[1].lineTo( length, 0.0 ); + path[1].lineTo( 0.0, -width / 2 ); + + path[2].lineTo( -length, 0.0 ); + path[2].lineTo( 0.0, width / 2 ); + + path[3].lineTo( -length, 0.0 ); + path[3].lineTo( 0.0, -width / 2 ); + + + const int colorOffset = 10; + const QColor darkColor = palette.color( colorGroup, QPalette::Dark ); + const QColor lightColor = palette.color( colorGroup, QPalette::Light ); + + QColor color[4]; + color[0] = darkColor.light( 100 + colorOffset ); + color[1] = darkColor.dark( 100 + colorOffset ); + color[2] = lightColor.light( 100 + colorOffset ); + color[3] = lightColor.dark( 100 + colorOffset ); + + painter->setPen( Qt::NoPen ); + + for ( int i = 0; i < 4; i++ ) + { + painter->setBrush( color[i] ); + painter->drawPath( path[i] ); + } +} + +//! Constructor +QwtDialNeedle::QwtDialNeedle(): + d_palette( QApplication::palette() ) +{ +} + +//! Destructor +QwtDialNeedle::~QwtDialNeedle() +{ +} + +/*! + Sets the palette for the needle. + + \param palette New Palette +*/ +void QwtDialNeedle::setPalette( const QPalette &palette ) +{ + d_palette = palette; +} + +/*! + \return the palette of the needle. +*/ +const QPalette &QwtDialNeedle::palette() const +{ + return d_palette; +} + +/*! + Draw the needle + + \param painter Painter + \param center Center of the dial, start position for the needle + \param length Length of the needle + \param direction Direction of the needle, in degrees counter clockwise + \param colorGroup Color group, used for painting +*/ +void QwtDialNeedle::draw( QPainter *painter, + const QPointF ¢er, double length, double direction, + QPalette::ColorGroup colorGroup ) const +{ + painter->save(); + + painter->translate( center ); + painter->rotate( -direction ); + + drawNeedle( painter, length, colorGroup ); + + painter->restore(); +} + +//! Draw the knob +void QwtDialNeedle::drawKnob( QPainter *painter, + double width, const QBrush &brush, bool sunken ) const +{ + QPalette palette( brush.color() ); + + QColor c1 = palette.color( QPalette::Light ); + QColor c2 = palette.color( QPalette::Dark ); + + if ( sunken ) + qSwap( c1, c2 ); + + QRectF rect( 0.0, 0.0, width, width ); + rect.moveCenter( painter->combinedTransform().map( QPointF() ) ); + + QLinearGradient gradient( rect.topLeft(), rect.bottomRight() ); + gradient.setColorAt( 0.0, c1 ); + gradient.setColorAt( 0.3, c1 ); + gradient.setColorAt( 0.7, c2 ); + gradient.setColorAt( 1.0, c2 ); + + painter->save(); + + painter->resetTransform(); + + painter->setPen( QPen( gradient, 1 ) ); + painter->setBrush( brush ); + painter->drawEllipse( rect ); + + painter->restore(); +} + +/*! + Constructor + + \param style Style + \param hasKnob With/Without knob + \param mid Middle color + \param base Base color +*/ +QwtDialSimpleNeedle::QwtDialSimpleNeedle( Style style, bool hasKnob, + const QColor &mid, const QColor &base ): + d_style( style ), + d_hasKnob( hasKnob ), + d_width( -1 ) +{ + QPalette palette; + palette.setColor( QPalette::Mid, mid ); + palette.setColor( QPalette::Base, base ); + + setPalette( palette ); +} + +/*! + Set the width of the needle + \param width Width + \sa width() +*/ +void QwtDialSimpleNeedle::setWidth( double width ) +{ + d_width = width; +} + +/*! + \return the width of the needle + \sa setWidth() +*/ +double QwtDialSimpleNeedle::width() const +{ + return d_width; +} + +/*! + Draw the needle + + \param painter Painter + \param length Length of the needle + \param colorGroup Color group, used for painting +*/ +void QwtDialSimpleNeedle::drawNeedle( QPainter *painter, + double length, QPalette::ColorGroup colorGroup ) const +{ + double knobWidth = 0.0; + double width = d_width; + + if ( d_style == Arrow ) + { + if ( width <= 0.0 ) + width = qMax(length * 0.06, 6.0); + + qwtDrawArrowNeedle( painter, + palette(), colorGroup, length, width ); + + knobWidth = qMin( width * 2.0, 0.2 * length ); + } + else + { + if ( width <= 0.0 ) + width = 5.0; + + QPen pen ( palette().brush( colorGroup, QPalette::Mid ), width ); + pen.setCapStyle( Qt::FlatCap ); + + painter->setPen( pen ); + painter->drawLine( QPointF( 0.0, 0.0 ), QPointF( length, 0.0 ) ); + + knobWidth = qMax( width * 3.0, 5.0 ); + } + + if ( d_hasKnob && knobWidth > 0.0 ) + { + drawKnob( painter, knobWidth, + palette().brush( colorGroup, QPalette::Base ), false ); + } +} + +//! Constructor +QwtCompassMagnetNeedle::QwtCompassMagnetNeedle( Style style, + const QColor &light, const QColor &dark ): + d_style( style ) +{ + QPalette palette; + palette.setColor( QPalette::Light, light ); + palette.setColor( QPalette::Dark, dark ); + palette.setColor( QPalette::Base, Qt::gray ); + + setPalette( palette ); +} + +/*! + Draw the needle + + \param painter Painter + \param length Length of the needle + \param colorGroup Color group, used for painting +*/ +void QwtCompassMagnetNeedle::drawNeedle( QPainter *painter, + double length, QPalette::ColorGroup colorGroup ) const +{ + if ( d_style == ThinStyle ) + { + const double width = qMax( length / 6.0, 3.0 ); + + const int colorOffset = 10; + + const QColor light = palette().color( colorGroup, QPalette::Light ); + const QColor dark = palette().color( colorGroup, QPalette::Dark ); + + qwtDrawShadedPointer( painter, + dark.light( 100 + colorOffset ), + dark.dark( 100 + colorOffset ), + length, width ); + + painter->rotate( 180.0 ); + + qwtDrawShadedPointer( painter, + light.light( 100 + colorOffset ), + light.dark( 100 + colorOffset ), + length, width ); + + const QBrush baseBrush = palette().brush( colorGroup, QPalette::Base ); + drawKnob( painter, width, baseBrush, true ); + } + else + { + qwtDrawTriangleNeedle( painter, palette(), colorGroup, length ); + } +} + +/*! + Constructor + + \param style Arrow style + \param light Light color + \param dark Dark color +*/ +QwtCompassWindArrow::QwtCompassWindArrow( Style style, + const QColor &light, const QColor &dark ): + d_style( style ) +{ + QPalette palette; + palette.setColor( QPalette::Light, light ); + palette.setColor( QPalette::Dark, dark ); + + setPalette( palette ); +} + +/*! + Draw the needle + + \param painter Painter + \param length Length of the needle + \param colorGroup Color group, used for painting +*/ +void QwtCompassWindArrow::drawNeedle( QPainter *painter, + double length, QPalette::ColorGroup colorGroup ) const +{ + if ( d_style == Style1 ) + qwtDrawStyle1Needle( painter, palette(), colorGroup, length ); + else + qwtDrawStyle2Needle( painter, palette(), colorGroup, length ); +} diff --git a/ThirdParty/Qwt/src/qwt_dial_needle.h b/ThirdParty/Qwt/src/qwt_dial_needle.h new file mode 100644 index 0000000000..d84384a0fd --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_dial_needle.h @@ -0,0 +1,187 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#ifndef QWT_DIAL_NEEDLE_H +#define QWT_DIAL_NEEDLE_H 1 + +#include "qwt_global.h" +#include + +class QPainter; +class QPoint; + +/*! + \brief Base class for needles that can be used in a QwtDial. + + QwtDialNeedle is a pointer that indicates a value by pointing + to a specific direction. + + \sa QwtDial, QwtCompass +*/ + +class QWT_EXPORT QwtDialNeedle +{ +public: + QwtDialNeedle(); + virtual ~QwtDialNeedle(); + + virtual void setPalette( const QPalette & ); + const QPalette &palette() const; + + virtual void draw( QPainter *painter, const QPointF ¢er, + double length, double direction, + QPalette::ColorGroup = QPalette::Active ) const; + +protected: + /*! + \brief Draw the needle + + The origin of the needle is at position (0.0, 0.0 ) + pointing in direction 0.0 ( = east ). + + The painter is already initialized with translation and + rotation. + + \param painter Painter + \param length Length of the needle + \param colorGroup Color group, used for painting + + \sa setPalette(), palette() + */ + virtual void drawNeedle( QPainter *painter, + double length, QPalette::ColorGroup colorGroup ) const = 0; + + virtual void drawKnob( QPainter *, double width, + const QBrush &, bool sunken ) const; + +private: + QPalette d_palette; +}; + +/*! + \brief A needle for dial widgets + + The following colors are used: + + - QPalette::Mid\n + Pointer + - QPalette::Base\n + Knob + + \sa QwtDial, QwtCompass +*/ + +class QWT_EXPORT QwtDialSimpleNeedle: public QwtDialNeedle +{ +public: + //! Style of the needle + enum Style + { + //! Arrow + Arrow, + + //! A straight line from the center + Ray + }; + + QwtDialSimpleNeedle( Style, bool hasKnob = true, + const QColor &mid = Qt::gray, const QColor &base = Qt::darkGray ); + + void setWidth( double width ); + double width() const; + +protected: + virtual void drawNeedle( QPainter *, double length, + QPalette::ColorGroup ) const; + +private: + Style d_style; + bool d_hasKnob; + double d_width; +}; + +/*! + \brief A magnet needle for compass widgets + + A magnet needle points to two opposite directions indicating + north and south. + + The following colors are used: + - QPalette::Light\n + Used for pointing south + - QPalette::Dark\n + Used for pointing north + - QPalette::Base\n + Knob (ThinStyle only) + + \sa QwtDial, QwtCompass +*/ + +class QWT_EXPORT QwtCompassMagnetNeedle: public QwtDialNeedle +{ +public: + //! Style of the needle + enum Style + { + //! A needle with a triangular shape + TriangleStyle, + + //! A thin needle + ThinStyle + }; + + QwtCompassMagnetNeedle( Style = TriangleStyle, + const QColor &light = Qt::white, const QColor &dark = Qt::red ); + +protected: + virtual void drawNeedle( QPainter *, + double length, QPalette::ColorGroup ) const; + +private: + Style d_style; +}; + +/*! + \brief An indicator for the wind direction + + QwtCompassWindArrow shows the direction where the wind comes from. + + - QPalette::Light\n + Used for Style1, or the light half of Style2 + - QPalette::Dark\n + Used for the dark half of Style2 + + \sa QwtDial, QwtCompass +*/ + +class QWT_EXPORT QwtCompassWindArrow: public QwtDialNeedle +{ +public: + //! Style of the arrow + enum Style + { + //! A needle pointing to the center + Style1, + + //! A needle pointing to the center + Style2 + }; + + QwtCompassWindArrow( Style, const QColor &light = Qt::white, + const QColor &dark = Qt::gray ); + +protected: + virtual void drawNeedle( QPainter *, + double length, QPalette::ColorGroup ) const; + +private: + Style d_style; +}; + +#endif diff --git a/ThirdParty/Qwt/src/qwt_dyngrid_layout.cpp b/ThirdParty/Qwt/src/qwt_dyngrid_layout.cpp new file mode 100644 index 0000000000..9e0fa2851f --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_dyngrid_layout.cpp @@ -0,0 +1,591 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#include "qwt_dyngrid_layout.h" +#include "qwt_math.h" +#include +#include + +class QwtDynGridLayout::PrivateData +{ +public: + PrivateData(): + isDirty( true ) + { + } + + void updateLayoutCache(); + + mutable QList itemList; + + uint maxColumns; + uint numRows; + uint numColumns; + + Qt::Orientations expanding; + + bool isDirty; + QVector itemSizeHints; +}; + +void QwtDynGridLayout::PrivateData::updateLayoutCache() +{ + itemSizeHints.resize( itemList.count() ); + + int index = 0; + + for ( QList::iterator it = itemList.begin(); + it != itemList.end(); ++it, index++ ) + { + itemSizeHints[ index ] = ( *it )->sizeHint(); + } + + isDirty = false; +} + +/*! + \param parent Parent widget + \param margin Margin + \param spacing Spacing +*/ + +QwtDynGridLayout::QwtDynGridLayout( QWidget *parent, + int margin, int spacing ): + QLayout( parent ) +{ + init(); + + setSpacing( spacing ); + setMargin( margin ); +} + +/*! + \param spacing Spacing +*/ + +QwtDynGridLayout::QwtDynGridLayout( int spacing ) +{ + init(); + setSpacing( spacing ); +} + +/*! + Initialize the layout with default values. +*/ +void QwtDynGridLayout::init() +{ + d_data = new QwtDynGridLayout::PrivateData; + d_data->maxColumns = d_data->numRows = d_data->numColumns = 0; + d_data->expanding = 0; +} + +//! Destructor + +QwtDynGridLayout::~QwtDynGridLayout() +{ + for ( int i = 0; i < d_data->itemList.size(); i++ ) + delete d_data->itemList[i]; + + delete d_data; +} + +//! Invalidate all internal caches +void QwtDynGridLayout::invalidate() +{ + d_data->isDirty = true; + QLayout::invalidate(); +} + +/*! + Limit the number of columns. + \param maxColumns upper limit, 0 means unlimited + \sa maxColumns() +*/ +void QwtDynGridLayout::setMaxColumns( uint maxColumns ) +{ + d_data->maxColumns = maxColumns; +} + +/*! + \brief Return the upper limit for the number of columns. + + 0 means unlimited, what is the default. + + \return Upper limit for the number of columns + \sa setMaxColumns() +*/ +uint QwtDynGridLayout::maxColumns() const +{ + return d_data->maxColumns; +} + +/*! + \brief Add an item to the next free position. + \param item Layout item + */ +void QwtDynGridLayout::addItem( QLayoutItem *item ) +{ + d_data->itemList.append( item ); + invalidate(); +} + +/*! + \return true if this layout is empty. +*/ +bool QwtDynGridLayout::isEmpty() const +{ + return d_data->itemList.isEmpty(); +} + +/*! + \return number of layout items +*/ +uint QwtDynGridLayout::itemCount() const +{ + return d_data->itemList.count(); +} + +/*! + Find the item at a specific index + + \param index Index + \return Item at a specific index + \sa takeAt() +*/ +QLayoutItem *QwtDynGridLayout::itemAt( int index ) const +{ + if ( index < 0 || index >= d_data->itemList.count() ) + return NULL; + + return d_data->itemList.at( index ); +} + +/*! + Find the item at a specific index and remove it from the layout + + \param index Index + \return Layout item, removed from the layout + \sa itemAt() +*/ +QLayoutItem *QwtDynGridLayout::takeAt( int index ) +{ + if ( index < 0 || index >= d_data->itemList.count() ) + return NULL; + + d_data->isDirty = true; + return d_data->itemList.takeAt( index ); +} + +//! \return Number of items in the layout +int QwtDynGridLayout::count() const +{ + return d_data->itemList.count(); +} + +/*! + Set whether this layout can make use of more space than sizeHint(). + A value of Qt::Vertical or Qt::Horizontal means that it wants to grow in only + one dimension, while Qt::Vertical | Qt::Horizontal means that it wants + to grow in both dimensions. The default value is 0. + + \param expanding Or'd orientations + \sa expandingDirections() +*/ +void QwtDynGridLayout::setExpandingDirections( Qt::Orientations expanding ) +{ + d_data->expanding = expanding; +} + +/*! + \brief Returns whether this layout can make use of more space than sizeHint(). + + A value of Qt::Vertical or Qt::Horizontal means that it wants to grow in only + one dimension, while Qt::Vertical | Qt::Horizontal means that it wants + to grow in both dimensions. + + \return Orientations, where the layout expands + \sa setExpandingDirections() +*/ +Qt::Orientations QwtDynGridLayout::expandingDirections() const +{ + return d_data->expanding; +} + +/*! + Reorganizes columns and rows and resizes managed items within + a rectangle. + + \param rect Layout geometry +*/ +void QwtDynGridLayout::setGeometry( const QRect &rect ) +{ + QLayout::setGeometry( rect ); + + if ( isEmpty() ) + return; + + d_data->numColumns = columnsForWidth( rect.width() ); + d_data->numRows = itemCount() / d_data->numColumns; + if ( itemCount() % d_data->numColumns ) + d_data->numRows++; + + QList itemGeometries = layoutItems( rect, d_data->numColumns ); + + int index = 0; + for ( QList::iterator it = d_data->itemList.begin(); + it != d_data->itemList.end(); ++it ) + { + ( *it )->setGeometry( itemGeometries[index] ); + index++; + } +} + +/*! + \brief Calculate the number of columns for a given width. + + The calculation tries to use as many columns as possible + ( limited by maxColumns() ) + + \param width Available width for all columns + \return Number of columns for a given width + + \sa maxColumns(), setMaxColumns() +*/ +uint QwtDynGridLayout::columnsForWidth( int width ) const +{ + if ( isEmpty() ) + return 0; + + uint maxColumns = itemCount(); + if ( d_data->maxColumns > 0 ) + maxColumns = qMin( d_data->maxColumns, maxColumns ); + + if ( maxRowWidth( maxColumns ) <= width ) + return maxColumns; + + for ( uint numColumns = 2; numColumns <= maxColumns; numColumns++ ) + { + const int rowWidth = maxRowWidth( numColumns ); + if ( rowWidth > width ) + return numColumns - 1; + } + + return 1; // At least 1 column +} + +/*! + Calculate the width of a layout for a given number of + columns. + + \param numColumns Given number of columns + \param itemWidth Array of the width hints for all items +*/ +int QwtDynGridLayout::maxRowWidth( int numColumns ) const +{ + int col; + + QVector colWidth( numColumns ); + for ( col = 0; col < numColumns; col++ ) + colWidth[col] = 0; + + if ( d_data->isDirty ) + d_data->updateLayoutCache(); + + for ( int index = 0; + index < d_data->itemSizeHints.count(); index++ ) + { + col = index % numColumns; + colWidth[col] = qMax( colWidth[col], + d_data->itemSizeHints[int( index )].width() ); + } + + int rowWidth = 2 * margin() + ( numColumns - 1 ) * spacing(); + for ( col = 0; col < numColumns; col++ ) + rowWidth += colWidth[col]; + + return rowWidth; +} + +/*! + \return the maximum width of all layout items +*/ +int QwtDynGridLayout::maxItemWidth() const +{ + if ( isEmpty() ) + return 0; + + if ( d_data->isDirty ) + d_data->updateLayoutCache(); + + int w = 0; + for ( int i = 0; i < d_data->itemSizeHints.count(); i++ ) + { + const int itemW = d_data->itemSizeHints[i].width(); + if ( itemW > w ) + w = itemW; + } + + return w; +} + +/*! + Calculate the geometries of the layout items for a layout + with numColumns columns and a given rectangle. + + \param rect Rect where to place the items + \param numColumns Number of columns + \return item geometries +*/ + +QList QwtDynGridLayout::layoutItems( const QRect &rect, + uint numColumns ) const +{ + QList itemGeometries; + if ( numColumns == 0 || isEmpty() ) + return itemGeometries; + + uint numRows = itemCount() / numColumns; + if ( numColumns % itemCount() ) + numRows++; + + if ( numRows == 0 ) + return itemGeometries; + + QVector rowHeight( numRows ); + QVector colWidth( numColumns ); + + layoutGrid( numColumns, rowHeight, colWidth ); + + bool expandH, expandV; + expandH = expandingDirections() & Qt::Horizontal; + expandV = expandingDirections() & Qt::Vertical; + + if ( expandH || expandV ) + stretchGrid( rect, numColumns, rowHeight, colWidth ); + + const int maxColumns = d_data->maxColumns; + d_data->maxColumns = numColumns; + const QRect alignedRect = alignmentRect( rect ); + d_data->maxColumns = maxColumns; + + const int xOffset = expandH ? 0 : alignedRect.x(); + const int yOffset = expandV ? 0 : alignedRect.y(); + + QVector colX( numColumns ); + QVector rowY( numRows ); + + const int xySpace = spacing(); + + rowY[0] = yOffset + margin(); + for ( uint r = 1; r < numRows; r++ ) + rowY[r] = rowY[r-1] + rowHeight[r-1] + xySpace; + + colX[0] = xOffset + margin(); + for ( uint c = 1; c < numColumns; c++ ) + colX[c] = colX[c-1] + colWidth[c-1] + xySpace; + + const int itemCount = d_data->itemList.size(); + for ( int i = 0; i < itemCount; i++ ) + { + const int row = i / numColumns; + const int col = i % numColumns; + + QRect itemGeometry( colX[col], rowY[row], + colWidth[col], rowHeight[row] ); + itemGeometries.append( itemGeometry ); + } + + return itemGeometries; +} + + +/*! + Calculate the dimensions for the columns and rows for a grid + of numColumns columns. + + \param numColumns Number of columns. + \param rowHeight Array where to fill in the calculated row heights. + \param colWidth Array where to fill in the calculated column widths. +*/ + +void QwtDynGridLayout::layoutGrid( uint numColumns, + QVector& rowHeight, QVector& colWidth ) const +{ + if ( numColumns <= 0 ) + return; + + if ( d_data->isDirty ) + d_data->updateLayoutCache(); + + for ( int index = 0; index < d_data->itemSizeHints.count(); index++ ) + { + const int row = index / numColumns; + const int col = index % numColumns; + + const QSize &size = d_data->itemSizeHints[int( index )]; + + rowHeight[row] = ( col == 0 ) + ? size.height() : qMax( rowHeight[row], size.height() ); + colWidth[col] = ( row == 0 ) + ? size.width() : qMax( colWidth[col], size.width() ); + } +} + +/*! + \return true: QwtDynGridLayout implements heightForWidth(). + \sa heightForWidth() +*/ +bool QwtDynGridLayout::hasHeightForWidth() const +{ + return true; +} + +/*! + \return The preferred height for this layout, given a width. + \sa hasHeightForWidth() +*/ +int QwtDynGridLayout::heightForWidth( int width ) const +{ + if ( isEmpty() ) + return 0; + + const uint numColumns = columnsForWidth( width ); + uint numRows = itemCount() / numColumns; + if ( itemCount() % numColumns ) + numRows++; + + QVector rowHeight( numRows ); + QVector colWidth( numColumns ); + + layoutGrid( numColumns, rowHeight, colWidth ); + + int h = 2 * margin() + ( numRows - 1 ) * spacing(); + for ( uint row = 0; row < numRows; row++ ) + h += rowHeight[row]; + + return h; +} + +/*! + Stretch columns in case of expanding() & QSizePolicy::Horizontal and + rows in case of expanding() & QSizePolicy::Vertical to fill the entire + rect. Rows and columns are stretched with the same factor. + + \param rect Bounding rectangle + \param numColumns Number of columns + \param rowHeight Array to be filled with the calculated row heights + \param colWidth Array to be filled with the calculated column widths + + \sa setExpanding(), expanding() +*/ +void QwtDynGridLayout::stretchGrid( const QRect &rect, + uint numColumns, QVector& rowHeight, QVector& colWidth ) const +{ + if ( numColumns == 0 || isEmpty() ) + return; + + bool expandH, expandV; + expandH = expandingDirections() & Qt::Horizontal; + expandV = expandingDirections() & Qt::Vertical; + + if ( expandH ) + { + int xDelta = rect.width() - 2 * margin() - ( numColumns - 1 ) * spacing(); + for ( uint col = 0; col < numColumns; col++ ) + xDelta -= colWidth[col]; + + if ( xDelta > 0 ) + { + for ( uint col = 0; col < numColumns; col++ ) + { + const int space = xDelta / ( numColumns - col ); + colWidth[col] += space; + xDelta -= space; + } + } + } + + if ( expandV ) + { + uint numRows = itemCount() / numColumns; + if ( itemCount() % numColumns ) + numRows++; + + int yDelta = rect.height() - 2 * margin() - ( numRows - 1 ) * spacing(); + for ( uint row = 0; row < numRows; row++ ) + yDelta -= rowHeight[row]; + + if ( yDelta > 0 ) + { + for ( uint row = 0; row < numRows; row++ ) + { + const int space = yDelta / ( numRows - row ); + rowHeight[row] += space; + yDelta -= space; + } + } + } +} + +/*! + Return the size hint. If maxColumns() > 0 it is the size for + a grid with maxColumns() columns, otherwise it is the size for + a grid with only one row. + + \return Size hint + \sa maxColumns(), setMaxColumns() +*/ +QSize QwtDynGridLayout::sizeHint() const +{ + if ( isEmpty() ) + return QSize(); + + uint numColumns = itemCount(); + if ( d_data->maxColumns > 0 ) + numColumns = qMin( d_data->maxColumns, numColumns ); + + uint numRows = itemCount() / numColumns; + if ( itemCount() % numColumns ) + numRows++; + + QVector rowHeight( numRows ); + QVector colWidth( numColumns ); + + layoutGrid( numColumns, rowHeight, colWidth ); + + int h = 2 * margin() + ( numRows - 1 ) * spacing(); + for ( uint row = 0; row < numRows; row++ ) + h += rowHeight[row]; + + int w = 2 * margin() + ( numColumns - 1 ) * spacing(); + for ( uint col = 0; col < numColumns; col++ ) + w += colWidth[col]; + + return QSize( w, h ); +} + +/*! + \return Number of rows of the current layout. + \sa numColumns() + \warning The number of rows might change whenever the geometry changes +*/ +uint QwtDynGridLayout::numRows() const +{ + return d_data->numRows; +} + +/*! + \return Number of columns of the current layout. + \sa numRows() + \warning The number of columns might change whenever the geometry changes +*/ +uint QwtDynGridLayout::numColumns() const +{ + return d_data->numColumns; +} diff --git a/ThirdParty/Qwt/src/qwt_dyngrid_layout.h b/ThirdParty/Qwt/src/qwt_dyngrid_layout.h new file mode 100644 index 0000000000..dd20266124 --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_dyngrid_layout.h @@ -0,0 +1,83 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#ifndef QWT_DYNGRID_LAYOUT_H +#define QWT_DYNGRID_LAYOUT_H + +#include "qwt_global.h" +#include +#include +#include + +/*! + \brief The QwtDynGridLayout class lays out widgets in a grid, + adjusting the number of columns and rows to the current size. + + QwtDynGridLayout takes the space it gets, divides it up into rows and + columns, and puts each of the widgets it manages into the correct cell(s). + It lays out as many number of columns as possible (limited by maxColumns()). +*/ + +class QWT_EXPORT QwtDynGridLayout : public QLayout +{ + Q_OBJECT +public: + explicit QwtDynGridLayout( QWidget *, int margin = 0, int space = -1 ); + explicit QwtDynGridLayout( int space = -1 ); + + virtual ~QwtDynGridLayout(); + + virtual void invalidate(); + + void setMaxColumns( uint maxCols ); + uint maxColumns() const; + + uint numRows () const; + uint numColumns () const; + + virtual void addItem( QLayoutItem * ); + + virtual QLayoutItem *itemAt( int index ) const; + virtual QLayoutItem *takeAt( int index ); + virtual int count() const; + + void setExpandingDirections( Qt::Orientations ); + virtual Qt::Orientations expandingDirections() const; + QList layoutItems( const QRect &, uint numCols ) const; + + virtual int maxItemWidth() const; + + virtual void setGeometry( const QRect &rect ); + + virtual bool hasHeightForWidth() const; + virtual int heightForWidth( int ) const; + + virtual QSize sizeHint() const; + + virtual bool isEmpty() const; + uint itemCount() const; + + virtual uint columnsForWidth( int width ) const; + +protected: + + void layoutGrid( uint numCols, + QVector& rowHeight, QVector& colWidth ) const; + void stretchGrid( const QRect &rect, uint numCols, + QVector& rowHeight, QVector& colWidth ) const; + +private: + void init(); + int maxRowWidth( int numCols ) const; + + class PrivateData; + PrivateData *d_data; +}; + +#endif diff --git a/ThirdParty/Qwt/src/qwt_event_pattern.cpp b/ThirdParty/Qwt/src/qwt_event_pattern.cpp new file mode 100644 index 0000000000..463774362e --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_event_pattern.cpp @@ -0,0 +1,265 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#include "qwt_event_pattern.h" +#include + +/*! + Constructor + + \sa MousePatternCode, KeyPatternCode +*/ + +QwtEventPattern::QwtEventPattern(): + d_mousePattern( MousePatternCount ), + d_keyPattern( KeyPatternCount ) +{ + initKeyPattern(); + initMousePattern( 3 ); +} + +//! Destructor +QwtEventPattern::~QwtEventPattern() +{ +} + +/*! + Set default mouse patterns, depending on the number of mouse buttons + + \param numButtons Number of mouse buttons ( <= 3 ) + \sa MousePatternCode +*/ +void QwtEventPattern::initMousePattern( int numButtons ) +{ + d_mousePattern.resize( MousePatternCount ); + + switch ( numButtons ) + { + case 1: + { + setMousePattern( MouseSelect1, Qt::LeftButton ); + setMousePattern( MouseSelect2, Qt::LeftButton, Qt::ControlModifier ); + setMousePattern( MouseSelect3, Qt::LeftButton, Qt::AltModifier ); + break; + } + case 2: + { + setMousePattern( MouseSelect1, Qt::LeftButton ); + setMousePattern( MouseSelect2, Qt::RightButton ); + setMousePattern( MouseSelect3, Qt::LeftButton, Qt::AltModifier ); + break; + } + default: + { + setMousePattern( MouseSelect1, Qt::LeftButton ); + setMousePattern( MouseSelect2, Qt::RightButton ); + setMousePattern( MouseSelect3, Qt::MidButton ); + } + } + + setMousePattern( MouseSelect4, d_mousePattern[MouseSelect1].button, + d_mousePattern[MouseSelect1].modifiers | Qt::ShiftModifier ); + + setMousePattern( MouseSelect5, d_mousePattern[MouseSelect2].button, + d_mousePattern[MouseSelect2].modifiers | Qt::ShiftModifier ); + + setMousePattern( MouseSelect6, d_mousePattern[MouseSelect3].button, + d_mousePattern[MouseSelect3].modifiers | Qt::ShiftModifier ); +} + +/*! + Set default mouse patterns. + + \sa KeyPatternCode +*/ +void QwtEventPattern::initKeyPattern() +{ + d_keyPattern.resize( KeyPatternCount ); + + setKeyPattern( KeySelect1, Qt::Key_Return ); + setKeyPattern( KeySelect2, Qt::Key_Space ); + setKeyPattern( KeyAbort, Qt::Key_Escape ); + + setKeyPattern( KeyLeft, Qt::Key_Left ); + setKeyPattern( KeyRight, Qt::Key_Right ); + setKeyPattern( KeyUp, Qt::Key_Up ); + setKeyPattern( KeyDown, Qt::Key_Down ); + + setKeyPattern( KeyRedo, Qt::Key_Plus ); + setKeyPattern( KeyUndo, Qt::Key_Minus ); + setKeyPattern( KeyHome, Qt::Key_Escape ); +} + +/*! + Change one mouse pattern + + \param pattern Index of the pattern + \param button Button + \param modifiers Keyboard modifiers + + \sa QMouseEvent +*/ +void QwtEventPattern::setMousePattern( MousePatternCode pattern, + Qt::MouseButton button, Qt::KeyboardModifiers modifiers ) +{ + if ( pattern >= 0 && pattern < MousePatternCount ) + { + d_mousePattern[ pattern ].button = button; + d_mousePattern[ pattern ].modifiers = modifiers; + } +} + +/*! + Change one key pattern + + \param pattern Index of the pattern + \param key Key + \param modifiers Keyboard modifiers + + \sa QKeyEvent +*/ +void QwtEventPattern::setKeyPattern( KeyPatternCode pattern, + int key, Qt::KeyboardModifiers modifiers ) +{ + if ( pattern >= 0 && pattern < KeyPatternCount ) + { + d_keyPattern[ pattern ].key = key; + d_keyPattern[ pattern ].modifiers = modifiers; + } +} + +//! Change the mouse event patterns +void QwtEventPattern::setMousePattern( const QVector &pattern ) +{ + d_mousePattern = pattern; +} + +//! Change the key event patterns +void QwtEventPattern::setKeyPattern( const QVector &pattern ) +{ + d_keyPattern = pattern; +} + +//! \return Mouse pattern +const QVector & +QwtEventPattern::mousePattern() const +{ + return d_mousePattern; +} + +//! \return Key pattern +const QVector & +QwtEventPattern::keyPattern() const +{ + return d_keyPattern; +} + +//! \return Mouse pattern +QVector &QwtEventPattern::mousePattern() +{ + return d_mousePattern; +} + +//! \return Key pattern +QVector &QwtEventPattern::keyPattern() +{ + return d_keyPattern; +} + +/*! + \brief Compare a mouse event with an event pattern. + + A mouse event matches the pattern when both have the same button + value and in the state value the same key flags(Qt::KeyButtonMask) + are set. + + \param code Index of the event pattern + \param event Mouse event + \return true if matches + + \sa keyMatch() +*/ +bool QwtEventPattern::mouseMatch( MousePatternCode code, + const QMouseEvent *event ) const +{ + if ( code >= 0 && code < MousePatternCount ) + return mouseMatch( d_mousePattern[ code ], event ); + + return false; +} + +/*! + \brief Compare a mouse event with an event pattern. + + A mouse event matches the pattern when both have the same button + value and in the state value the same key flags(Qt::KeyButtonMask) + are set. + + \param pattern Mouse event pattern + \param event Mouse event + \return true if matches + + \sa keyMatch() +*/ + +bool QwtEventPattern::mouseMatch( const MousePattern &pattern, + const QMouseEvent *event ) const +{ + if ( event == NULL ) + return false; + + const MousePattern mousePattern( event->button(), event->modifiers() ); + return mousePattern == pattern; +} + +/*! + \brief Compare a key event with an event pattern. + + A key event matches the pattern when both have the same key + value and in the state value the same key flags (Qt::KeyButtonMask) + are set. + + \param code Index of the event pattern + \param event Key event + \return true if matches + + \sa mouseMatch() +*/ +bool QwtEventPattern::keyMatch( KeyPatternCode code, + const QKeyEvent *event ) const +{ + if ( code >= 0 && code < KeyPatternCount ) + return keyMatch( d_keyPattern[ code ], event ); + + return false; +} + +/*! + \brief Compare a key event with an event pattern. + + A key event matches the pattern when both have the same key + value and in the state value the same key flags (Qt::KeyButtonMask) + are set. + + \param pattern Key event pattern + \param event Key event + \return true if matches + + \sa mouseMatch() +*/ + +bool QwtEventPattern::keyMatch( + const KeyPattern &pattern, const QKeyEvent *event ) const +{ + if ( event == NULL ) + return false; + + const KeyPattern keyPattern( event->key(), event->modifiers() ); + return keyPattern == pattern; +} diff --git a/ThirdParty/Qwt/src/qwt_event_pattern.h b/ThirdParty/Qwt/src/qwt_event_pattern.h new file mode 100644 index 0000000000..7c5d1a37f6 --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_event_pattern.h @@ -0,0 +1,240 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#ifndef QWT_EVENT_PATTERN +#define QWT_EVENT_PATTERN 1 + +#include "qwt_global.h" +#include +#include + +class QMouseEvent; +class QKeyEvent; + +/*! + \brief A collection of event patterns + + QwtEventPattern introduces an level of indirection for mouse and + keyboard inputs. Those are represented by symbolic names, so + the application code can be configured by individual mappings. + + \sa QwtPicker, QwtPickerMachine, QwtPlotZoomer +*/ +class QWT_EXPORT QwtEventPattern +{ +public: + /*! + \brief Symbolic mouse input codes + + QwtEventPattern implements 3 different settings for + mice with 1, 2, or 3 buttons that can be activated + using initMousePattern(). The default setting is for + 3 button mice. + + Individual settings can be configured using setMousePattern(). + + \sa initMousePattern(), setMousePattern(), setKeyPattern() + */ + enum MousePatternCode + { + /*! + The default setting for 1, 2 and 3 button mice is: + + - Qt::LeftButton + - Qt::LeftButton + - Qt::LeftButton + */ + MouseSelect1, + + /*! + The default setting for 1, 2 and 3 button mice is: + + - Qt::LeftButton + Qt::ControlModifier + - Qt::RightButton + - Qt::RightButton + */ + MouseSelect2, + + /*! + The default setting for 1, 2 and 3 button mice is: + + - Qt::LeftButton + Qt::AltModifier + - Qt::LeftButton + Qt::AltModifier + - Qt::MidButton + */ + MouseSelect3, + + /*! + The default setting for 1, 2 and 3 button mice is: + + - Qt::LeftButton + Qt::ShiftModifier + - Qt::LeftButton + Qt::ShiftModifier + - Qt::LeftButton + Qt::ShiftModifier + */ + MouseSelect4, + + /*! + The default setting for 1, 2 and 3 button mice is: + + - Qt::LeftButton + Qt::ControlButton | Qt::ShiftModifier + - Qt::RightButton + Qt::ShiftModifier + - Qt::RightButton + Qt::ShiftModifier + */ + MouseSelect5, + + /*! + The default setting for 1, 2 and 3 button mice is: + + - Qt::LeftButton + Qt::AltModifier + Qt::ShiftModifier + - Qt::LeftButton + Qt::AltModifier | Qt::ShiftModifier + - Qt::MidButton + Qt::ShiftModifier + */ + MouseSelect6, + + //! Number of mouse patterns + MousePatternCount + }; + + /*! + \brief Symbolic keyboard input codes + + Individual settings can be configured using setKeyPattern() + + \sa setKeyPattern(), setMousePattern() + */ + enum KeyPatternCode + { + //! Qt::Key_Return + KeySelect1, + + //! Qt::Key_Space + KeySelect2, + + //! Qt::Key_Escape + KeyAbort, + + //! Qt::Key_Left + KeyLeft, + + //! Qt::Key_Right + KeyRight, + + //! Qt::Key_Up + KeyUp, + + //! Qt::Key_Down + KeyDown, + + //! Qt::Key_Plus + KeyRedo, + + //! Qt::Key_Minus + KeyUndo, + + //! Qt::Key_Escape + KeyHome, + + //! Number of key patterns + KeyPatternCount + }; + + //! A pattern for mouse events + class MousePattern + { + public: + //! Constructor + MousePattern( Qt::MouseButton btn = Qt::NoButton, + Qt::KeyboardModifiers modifierCodes = Qt::NoModifier ): + button( btn ), + modifiers( modifierCodes ) + { + } + + //! Button + Qt::MouseButton button; + + //! Keyboard modifier + Qt::KeyboardModifiers modifiers; + }; + + //! A pattern for key events + class KeyPattern + { + public: + //! Constructor + KeyPattern( int keyCode = Qt::Key_unknown, + Qt::KeyboardModifiers modifierCodes = Qt::NoModifier ): + key( keyCode ), + modifiers( modifierCodes ) + { + } + + //! Key code + int key; + + //! Modifiers + Qt::KeyboardModifiers modifiers; + }; + + QwtEventPattern(); + virtual ~QwtEventPattern(); + + void initMousePattern( int numButtons ); + void initKeyPattern(); + + void setMousePattern( MousePatternCode, Qt::MouseButton button, + Qt::KeyboardModifiers = Qt::NoModifier ); + + void setKeyPattern( KeyPatternCode, int keyCode, + Qt::KeyboardModifiers modifierCodes = Qt::NoModifier ); + + void setMousePattern( const QVector & ); + void setKeyPattern( const QVector & ); + + const QVector &mousePattern() const; + const QVector &keyPattern() const; + + QVector &mousePattern(); + QVector &keyPattern(); + + bool mouseMatch( MousePatternCode, const QMouseEvent * ) const; + bool keyMatch( KeyPatternCode, const QKeyEvent * ) const; + +protected: + virtual bool mouseMatch( const MousePattern &, const QMouseEvent * ) const; + virtual bool keyMatch( const KeyPattern &, const QKeyEvent * ) const; + +private: + +#if defined(_MSC_VER) +#pragma warning(push) +#pragma warning(disable: 4251) +#endif + QVector d_mousePattern; + QVector d_keyPattern; +#if defined(_MSC_VER) +#pragma warning(pop) +#endif +}; + +//! Compare operator +inline bool operator==( QwtEventPattern::MousePattern b1, + QwtEventPattern::MousePattern b2 ) +{ + return b1.button == b2.button && b1.modifiers == b2.modifiers; +} + +//! Compare operator +inline bool operator==( QwtEventPattern::KeyPattern b1, + QwtEventPattern::KeyPattern b2 ) +{ + return b1.key == b2.key && b1.modifiers == b2.modifiers; +} + +#endif diff --git a/ThirdParty/Qwt/src/qwt_global.h b/ThirdParty/Qwt/src/qwt_global.h new file mode 100644 index 0000000000..71ea702709 --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_global.h @@ -0,0 +1,41 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#ifndef QWT_GLOBAL_H +#define QWT_GLOBAL_H + +#include + +// QWT_VERSION is (major << 16) + (minor << 8) + patch. + +#define QWT_VERSION 0x060100 +#define QWT_VERSION_STR "6.1.0" + +#if defined(_MSC_VER) /* MSVC Compiler */ +/* template-class specialization 'identifier' is already instantiated */ +#pragma warning(disable: 4660) +/* inherits via dominance */ +#pragma warning(disable: 4250) +#endif // _MSC_VER + +#ifdef QWT_DLL + +#if defined(QWT_MAKEDLL) // create a Qwt DLL library +#define QWT_EXPORT Q_DECL_EXPORT +#else // use a Qwt DLL library +#define QWT_EXPORT Q_DECL_IMPORT +#endif + +#endif // QWT_DLL + +#ifndef QWT_EXPORT +#define QWT_EXPORT +#endif + +#endif diff --git a/ThirdParty/Qwt/src/qwt_graphic.cpp b/ThirdParty/Qwt/src/qwt_graphic.cpp new file mode 100644 index 0000000000..d67bcea0e0 --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_graphic.cpp @@ -0,0 +1,986 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#include "qwt_graphic.h" +#include "qwt_painter_command.h" +#include +#include +#include +#include +#include +#include +#include + +static bool qwtHasScalablePen( const QPainter *painter ) +{ + const QPen pen = painter->pen(); + + bool scalablePen = false; + + if ( pen.style() != Qt::NoPen && pen.brush().style() != Qt::NoBrush ) + { + scalablePen = !pen.isCosmetic(); + if ( !scalablePen && pen.widthF() == 0.0 ) + { + const QPainter::RenderHints hints = painter->renderHints(); + if ( hints.testFlag( QPainter::NonCosmeticDefaultPen ) ) + scalablePen = true; + } + } + + return scalablePen; +} + +static QRectF qwtStrokedPathRect( + const QPainter *painter, const QPainterPath &path ) +{ + QPainterPathStroker stroker; + stroker.setWidth( painter->pen().widthF() ); + stroker.setCapStyle( painter->pen().capStyle() ); + stroker.setJoinStyle( painter->pen().joinStyle() ); + stroker.setMiterLimit( painter->pen().miterLimit() ); + + QRectF rect; + if ( qwtHasScalablePen( painter ) ) + { + QPainterPath stroke = stroker.createStroke(path); + rect = painter->transform().map(stroke).boundingRect(); + } + else + { + QPainterPath mappedPath = painter->transform().map(path); + mappedPath = stroker.createStroke( mappedPath ); + + rect = mappedPath.boundingRect(); + } + + return rect; +} + +static inline void qwtExecCommand( + QPainter *painter, const QwtPainterCommand &cmd, + QwtGraphic::RenderHints renderHints, + const QTransform &transform ) +{ + switch( cmd.type() ) + { + case QwtPainterCommand::Path: + { + bool doMap = false; + + if ( renderHints.testFlag( QwtGraphic::RenderPensUnscaled ) + && painter->transform().isScaling() ) + { + bool isCosmetic = painter->pen().isCosmetic(); + if ( isCosmetic && painter->pen().widthF() == 0.0 ) + { + QPainter::RenderHints hints = painter->renderHints(); + if ( hints.testFlag( QPainter::NonCosmeticDefaultPen ) ) + isCosmetic = false; + } + + doMap = !isCosmetic; + } + + if ( doMap ) + { + const QTransform transform = painter->transform(); + + painter->resetTransform(); + painter->drawPath( transform.map( *cmd.path() ) ); + + painter->setTransform( transform ); + } + else + { + painter->drawPath( *cmd.path() ); + } + break; + } + case QwtPainterCommand::Pixmap: + { + const QwtPainterCommand::PixmapData *data = cmd.pixmapData(); + painter->drawPixmap( data->rect, data->pixmap, data->subRect ); + break; + } + case QwtPainterCommand::Image: + { + const QwtPainterCommand::ImageData *data = cmd.imageData(); + painter->drawImage( data->rect, data->image, + data->subRect, data->flags ); + break; + } + case QwtPainterCommand::State: + { + const QwtPainterCommand::StateData *data = cmd.stateData(); + + if ( data->flags & QPaintEngine::DirtyPen ) + painter->setPen( data->pen ); + + if ( data->flags & QPaintEngine::DirtyBrush ) + painter->setBrush( data->brush ); + + if ( data->flags & QPaintEngine::DirtyBrushOrigin ) + painter->setBrushOrigin( data->brushOrigin ); + + if ( data->flags & QPaintEngine::DirtyFont ) + painter->setFont( data->font ); + + if ( data->flags & QPaintEngine::DirtyBackground ) + { + painter->setBackgroundMode( data->backgroundMode ); + painter->setBackground( data->backgroundBrush ); + } + + if ( data->flags & QPaintEngine::DirtyTransform ) + { + painter->setTransform( data->transform * transform ); + } + + if ( data->flags & QPaintEngine::DirtyClipEnabled ) + painter->setClipping( data->isClipEnabled ); + + if ( data->flags & QPaintEngine::DirtyClipRegion) + { + painter->setClipRegion( data->clipRegion, + data->clipOperation ); + } + + if ( data->flags & QPaintEngine::DirtyClipPath ) + { + painter->setClipPath( data->clipPath, data->clipOperation ); + } + + if ( data->flags & QPaintEngine::DirtyHints) + { + const QPainter::RenderHints hints = data->renderHints; + + painter->setRenderHint( QPainter::Antialiasing, + hints.testFlag( QPainter::Antialiasing ) ); + + painter->setRenderHint( QPainter::TextAntialiasing, + hints.testFlag( QPainter::TextAntialiasing ) ); + + painter->setRenderHint( QPainter::SmoothPixmapTransform, + hints.testFlag( QPainter::SmoothPixmapTransform ) ); + + painter->setRenderHint( QPainter::HighQualityAntialiasing, + hints.testFlag( QPainter::HighQualityAntialiasing ) ); + + painter->setRenderHint( QPainter::NonCosmeticDefaultPen, + hints.testFlag( QPainter::NonCosmeticDefaultPen ) ); + } + + if ( data->flags & QPaintEngine::DirtyCompositionMode) + painter->setCompositionMode( data->compositionMode ); + + if ( data->flags & QPaintEngine::DirtyOpacity) + painter->setOpacity( data->opacity ); + + break; + } + default: + break; + } + +} + +class QwtGraphic::PathInfo +{ +public: + PathInfo(): + d_scalablePen( false ) + { + // QVector needs a default constructor + } + + PathInfo( const QRectF &pointRect, + const QRectF &boundingRect, bool scalablePen ): + d_pointRect( pointRect ), + d_boundingRect( boundingRect ), + d_scalablePen( scalablePen ) + { + } + + inline QRectF scaledBoundingRect( double sx, double sy, + bool scalePens ) const + { + if ( sx == 1.0 && sy == 1.0 ) + return d_boundingRect; + + QTransform transform; + transform.scale( sx, sy ); + + QRectF rect; + if ( scalePens && d_scalablePen ) + { + rect = transform.mapRect( d_boundingRect ); + } + else + { + rect = transform.mapRect( d_pointRect ); + + const double l = qAbs( d_pointRect.left() - d_boundingRect.left() ); + const double r = qAbs( d_pointRect.right() - d_boundingRect.right() ); + const double t = qAbs( d_pointRect.top() - d_boundingRect.top() ); + const double b = qAbs( d_pointRect.bottom() - d_boundingRect.bottom() ); + + rect.adjust( -l, -t, r, b ); + } + + return rect; + } + + inline double scaleFactorX( const QRectF& pathRect, + const QRectF &targetRect, bool scalePens ) const + { + if ( pathRect.width() <= 0.0 ) + return 0.0; + + const QPointF p0 = d_pointRect.center(); + + const double l = qAbs( pathRect.left() - p0.x() ); + const double r = qAbs( pathRect.right() - p0.x() ); + + const double w = 2.0 * qMin( l, r ) + * targetRect.width() / pathRect.width(); + + double sx; + if ( scalePens && d_scalablePen ) + { + sx = w / d_boundingRect.width(); + } + else + { + const double pw = qMax( + qAbs( d_boundingRect.left() - d_pointRect.left() ), + qAbs( d_boundingRect.right() - d_pointRect.right() ) ); + + sx = ( w - 2 * pw ) / d_pointRect.width(); + } + + return sx; + } + + inline double scaleFactorY( const QRectF& pathRect, + const QRectF &targetRect, bool scalePens ) const + { + if ( pathRect.height() <= 0.0 ) + return 0.0; + + const QPointF p0 = d_pointRect.center(); + + const double t = qAbs( pathRect.top() - p0.y() ); + const double b = qAbs( pathRect.bottom() - p0.y() ); + + const double h = 2.0 * qMin( t, b ) + * targetRect.height() / pathRect.height(); + + double sy; + if ( scalePens && d_scalablePen ) + { + sy = h / d_boundingRect.height(); + } + else + { + const double pw = + qMax( qAbs( d_boundingRect.top() - d_pointRect.top() ), + qAbs( d_boundingRect.bottom() - d_pointRect.bottom() ) ); + + sy = ( h - 2 * pw ) / d_pointRect.height(); + } + + return sy; + } + +private: + QRectF d_pointRect; + QRectF d_boundingRect; + bool d_scalablePen; +}; + +class QwtGraphic::PrivateData +{ +public: + PrivateData(): + boundingRect( 0.0, 0.0, -1.0, -1.0 ), + pointRect( 0.0, 0.0, -1.0, -1.0 ) + { + } + + QSizeF defaultSize; + QVector commands; + QVector pathInfos; + + QRectF boundingRect; + QRectF pointRect; + + QwtGraphic::RenderHints renderHints; +}; + +/*! + \brief Constructor + + Initializes a null graphic + \sa isNull() + */ +QwtGraphic::QwtGraphic(): + QwtNullPaintDevice() +{ + setMode( QwtNullPaintDevice::PathMode ); + d_data = new PrivateData; +} + +/*! + \brief Copy constructor + + \param other Source + \sa operator=() + */ +QwtGraphic::QwtGraphic( const QwtGraphic &other ): + QwtNullPaintDevice() +{ + setMode( other.mode() ); + d_data = new PrivateData( *other.d_data ); +} + +//! Destructor +QwtGraphic::~QwtGraphic() +{ + delete d_data; +} + +/*! + \brief Assignment operator + + \param other Source + \return A reference of this object + */ +QwtGraphic& QwtGraphic::operator=(const QwtGraphic &other) +{ + setMode( other.mode() ); + *d_data = *other.d_data; + + return *this; +} + +/*! + \brief Clear all stored commands + \sa isNull() + */ +void QwtGraphic::reset() +{ + d_data->commands.clear(); + d_data->pathInfos.clear(); + + d_data->boundingRect = QRectF( 0.0, 0.0, -1.0, -1.0 ); + d_data->pointRect = QRectF( 0.0, 0.0, -1.0, -1.0 ); + d_data->defaultSize = QSizeF(); + +} + +/*! + \return True, when no painter commands have been stored + \sa isEmpty(), commands() +*/ +bool QwtGraphic::isNull() const +{ + return d_data->commands.isEmpty(); +} + +/*! + \return True, when the bounding rectangle is empty + \sa boundingRect(), isNull() +*/ +bool QwtGraphic::isEmpty() const +{ + return d_data->boundingRect.isEmpty(); +} + +/*! + Toggle an render hint + + \param hint Render hint + \param on true/false + + \sa testRenderHint(), RenderHint +*/ +void QwtGraphic::setRenderHint( RenderHint hint, bool on ) +{ + if ( on ) + d_data->renderHints |= hint; + else + d_data->renderHints &= ~hint; +} + +/*! + Test a render hint + + \param hint Render hint + \return true/false + \sa setRenderHint(), RenderHint +*/ +bool QwtGraphic::testRenderHint( RenderHint hint ) const +{ + return d_data->renderHints.testFlag( hint ); +} + +/*! + The bounding rectangle is the controlPointRect() + extended by the areas needed for rendering the outlines + with unscaled pens. + + \return Bounding rectangle of the graphic + \sa controlPointRect(), scaledBoundingRect() + */ +QRectF QwtGraphic::boundingRect() const +{ + if ( d_data->boundingRect.width() < 0 ) + return QRectF(); + + return d_data->boundingRect; +} + +/*! + The control point rectangle is the bounding rectangle + of all control points of the paths and the target + rectangles of the images/pixmaps. + + \return Control point rectangle + \sa boundingRect(), scaledBoundingRect() + */ +QRectF QwtGraphic::controlPointRect() const +{ + if ( d_data->pointRect.width() < 0 ) + return QRectF(); + + return d_data->pointRect; +} + +/*! + \brief Calculate the target rectangle for scaling the graphic + + \param sx Horizontal scaling factor + \param sy Vertical scaling factor + + \note In case of paths that are painted with a cosmetic pen + ( see QPen::isCosmetic() ) the target rectangle is different to + multiplying the bounding rectangle. + + \return Scaled bounding rectangle + \sa boundingRect(), controlPointRect() + */ +QRectF QwtGraphic::scaledBoundingRect( double sx, double sy ) const +{ + if ( sx == 1.0 && sy == 1.0 ) + return d_data->boundingRect; + + QTransform transform; + transform.scale( sx, sy ); + + QRectF rect = transform.mapRect( d_data->pointRect ); + + for ( int i = 0; i < d_data->pathInfos.size(); i++ ) + { + rect |= d_data->pathInfos[i].scaledBoundingRect( sx, sy, + !d_data->renderHints.testFlag( RenderPensUnscaled ) ); + } + + return rect; +} + +//! \return Ceiled defaultSize() +QSize QwtGraphic::sizeMetrics() const +{ + const QSizeF sz = defaultSize(); + return QSize( qCeil( sz.width() ), qCeil( sz.height() ) ); +} + +/*! + \brief Set a default size + + The default size is used in all methods rendering the graphic, + where no size is explicitly specified. Assigning an empty size + means, that the default size will be calculated from the bounding + rectangle. + + The default setting is an empty size. + + \param size Default size + + \sa defaultSize(), boundingRect() + */ +void QwtGraphic::setDefaultSize( const QSizeF &size ) +{ + const double w = qMax( qreal( 0.0 ), size.width() ); + const double h = qMax( qreal( 0.0 ), size.height() ); + + d_data->defaultSize = QSizeF( w, h ); +} + +/*! + \brief Default size + + When a non empty size has been assigned by setDefaultSize() this + size will be returned. Otherwise the default size is the size + of the bounding rectangle. + + The default size is used in all methods rendering the graphic, + where no size is explicitly specified. + + \return Default size + \sa setDefaultSize(), boundingRect() + */ +QSizeF QwtGraphic::defaultSize() const +{ + if ( !d_data->defaultSize.isEmpty() ) + return d_data->defaultSize; + + return boundingRect().size(); +} + +/*! + \brief Replay all recorded painter commands + \param painter Qt painter + */ +void QwtGraphic::render( QPainter *painter ) const +{ + if ( isNull() ) + return; + + const int numCommands = d_data->commands.size(); + const QwtPainterCommand *commands = d_data->commands.constData(); + + const QTransform transform = painter->transform(); + + painter->save(); + + for ( int i = 0; i < numCommands; i++ ) + { + qwtExecCommand( painter, commands[i], + d_data->renderHints, transform ); + } + + painter->restore(); +} + +/*! + \brief Replay all recorded painter commands + + The graphic is scaled to fit into the rectangle + of the given size starting at ( 0, 0 ). + + \param painter Qt painter + \param size Size for the scaled graphic + \param aspectRatioMode Mode how to scale - See Qt::AspectRatioMode + */ +void QwtGraphic::render( QPainter *painter, const QSizeF &size, + Qt::AspectRatioMode aspectRatioMode ) const +{ + const QRectF r( 0.0, 0.0, size.width(), size.height() ); + render( painter, r, aspectRatioMode ); +} + +/*! + \brief Replay all recorded painter commands + + The graphic is scaled to fit into the given rectangle + + \param painter Qt painter + \param rect Rectangle for the scaled graphic + \param aspectRatioMode Mode how to scale - See Qt::AspectRatioMode + */ +void QwtGraphic::render( QPainter *painter, const QRectF &rect, + Qt::AspectRatioMode aspectRatioMode ) const +{ + if ( isEmpty() || rect.isEmpty() ) + return; + + double sx = 1.0; + double sy = 1.0; + + if ( d_data->pointRect.width() > 0.0 ) + sx = rect.width() / d_data->pointRect.width(); + + if ( d_data->pointRect.height() > 0.0 ) + sy = rect.height() / d_data->pointRect.height(); + + const bool scalePens = + !d_data->renderHints.testFlag( RenderPensUnscaled ); + + for ( int i = 0; i < d_data->pathInfos.size(); i++ ) + { + const PathInfo info = d_data->pathInfos[i]; + + const double ssx = info.scaleFactorX( + d_data->pointRect, rect, scalePens ); + + if ( ssx > 0.0 ) + sx = qMin( sx, ssx ); + + const double ssy = info.scaleFactorY( + d_data->pointRect, rect, scalePens ); + + if ( ssy > 0.0 ) + sy = qMin( sy, ssy ); + } + + if ( aspectRatioMode == Qt::KeepAspectRatio ) + { + const double s = qMin( sx, sy ); + sx = s; + sy = s; + } + else if ( aspectRatioMode == Qt::KeepAspectRatioByExpanding ) + { + const double s = qMax( sx, sy ); + sx = s; + sy = s; + } + + QTransform tr; + tr.translate( rect.center().x() - 0.5 * sx * d_data->pointRect.width(), + rect.center().y() - 0.5 * sy * d_data->pointRect.height() ); + tr.scale( sx, sy ); + tr.translate( -d_data->pointRect.x(), -d_data->pointRect.y() ); + + const QTransform transform = painter->transform(); + + painter->setTransform( tr, true ); + render( painter ); + + painter->setTransform( transform ); +} + +/*! + \brief Replay all recorded painter commands + + The graphic is scaled to the defaultSize() and aligned + to a position. + + \param painter Qt painter + \param pos Reference point, where to render + \param alignment Flags how to align the target rectangle + to pos. + */ +void QwtGraphic::render( QPainter *painter, + const QPointF &pos, Qt::Alignment alignment ) const +{ + QRectF r( pos, defaultSize() ); + + if ( alignment & Qt::AlignLeft ) + { + r.moveLeft( pos.x() ); + } + else if ( alignment & Qt::AlignHCenter ) + { + r.moveCenter( QPointF( pos.x(), r.center().y() ) ); + } + else if ( alignment & Qt::AlignRight ) + { + r.moveRight( pos.x() ); + } + + if ( alignment & Qt::AlignTop ) + { + r.moveTop( pos.y() ); + } + else if ( alignment & Qt::AlignVCenter ) + { + r.moveCenter( QPointF( r.center().x(), pos.y() ) ); + } + else if ( alignment & Qt::AlignBottom ) + { + r.moveBottom( pos.y() ); + } + + render( painter, r ); +} + +/*! + \brief Convert the graphic to a QPixmap + + All pixels of the pixmap get initialized by Qt::transparent + before the graphic is scaled and rendered on it. + + The size of the pixmap is the default size ( ceiled to integers ) + of the graphic. + + \return The graphic as pixmap in default size + \sa defaultSize(), toImage(), render() + */ +QPixmap QwtGraphic::toPixmap() const +{ + if ( isNull() ) + return QPixmap(); + + const QSizeF sz = defaultSize(); + + const int w = qCeil( sz.width() ); + const int h = qCeil( sz.height() ); + + QPixmap pixmap( w, h ); + pixmap.fill( Qt::transparent ); + + const QRectF r( 0.0, 0.0, sz.width(), sz.height() ); + + QPainter painter( &pixmap ); + render( &painter, r, Qt::KeepAspectRatio ); + painter.end(); + + return pixmap; +} + +/*! + \brief Convert the graphic to a QPixmap + + All pixels of the pixmap get initialized by Qt::transparent + before the graphic is scaled and rendered on it. + + \param size Size of the image + \param aspectRatioMode Aspect ratio how to scale the graphic + + \return The graphic as pixmap + \sa toImage(), render() + */ +QPixmap QwtGraphic::toPixmap( const QSize &size, + Qt::AspectRatioMode aspectRatioMode ) const +{ + QPixmap pixmap( size ); + pixmap.fill( Qt::transparent ); + + const QRect r( 0, 0, size.width(), size.height() ); + + QPainter painter( &pixmap ); + render( &painter, r, aspectRatioMode ); + painter.end(); + + return pixmap; +} + +/*! + \brief Convert the graphic to a QImage + + All pixels of the image get initialized by 0 ( transparent ) + before the graphic is scaled and rendered on it. + + The format of the image is QImage::Format_ARGB32_Premultiplied. + + \param size Size of the image + \param aspectRatioMode Aspect ratio how to scale the graphic + + \return The graphic as image + \sa toPixmap(), render() + */ +QImage QwtGraphic::toImage( const QSize &size, + Qt::AspectRatioMode aspectRatioMode ) const +{ + QImage image( size, QImage::Format_ARGB32_Premultiplied ); + image.fill( 0 ); + + const QRect r( 0, 0, size.width(), size.height() ); + + QPainter painter( &image ); + render( &painter, r, aspectRatioMode ); + painter.end(); + + return image; +} + +/*! + \brief Convert the graphic to a QImage + + All pixels of the image get initialized by 0 ( transparent ) + before the graphic is scaled and rendered on it. + + The format of the image is QImage::Format_ARGB32_Premultiplied. + + The size of the image is the default size ( ceiled to integers ) + of the graphic. + + \return The graphic as image in default size + \sa defaultSize(), toPixmap(), render() + */ +QImage QwtGraphic::toImage() const +{ + if ( isNull() ) + return QImage(); + + const QSizeF sz = defaultSize(); + + const int w = qCeil( sz.width() ); + const int h = qCeil( sz.height() ); + + QImage image( w, h, QImage::Format_ARGB32 ); + image.fill( 0 ); + + const QRect r( 0, 0, sz.width(), sz.height() ); + + QPainter painter( &image ); + render( &painter, r, Qt::KeepAspectRatio ); + painter.end(); + + return image; +} + +/*! + Store a path command in the command list + + \param path Painter path + \sa QPaintEngine::drawPath() +*/ +void QwtGraphic::drawPath( const QPainterPath &path ) +{ + const QPainter *painter = paintEngine()->painter(); + if ( painter == NULL ) + return; + + d_data->commands += QwtPainterCommand( path ); + + if ( !path.isEmpty() ) + { + const QPainterPath scaledPath = painter->transform().map( path ); + + QRectF pointRect = scaledPath.boundingRect(); + QRectF boundingRect = pointRect; + + if ( painter->pen().style() != Qt::NoPen + && painter->pen().brush().style() != Qt::NoBrush ) + { + boundingRect = qwtStrokedPathRect( painter, path ); + } + + updateControlPointRect( pointRect ); + updateBoundingRect( boundingRect ); + + d_data->pathInfos += PathInfo( pointRect, + boundingRect, qwtHasScalablePen( painter ) ); + } +} + +/*! + \brief Store a pixmap command in the command list + + \param rect target rectangle + \param pixmap Pixmap to be painted + \param subRect Reactangle of the pixmap to be painted + + \sa QPaintEngine::drawPixmap() +*/ +void QwtGraphic::drawPixmap( const QRectF &rect, + const QPixmap &pixmap, const QRectF &subRect ) +{ + const QPainter *painter = paintEngine()->painter(); + if ( painter == NULL ) + return; + + d_data->commands += QwtPainterCommand( rect, pixmap, subRect ); + + const QRectF r = painter->transform().mapRect( rect ); + updateControlPointRect( r ); + updateBoundingRect( r ); +} + +/*! + \brief Store a image command in the command list + + \param rect traget rectangle + \param image Image to be painted + \param subRect Reactangle of the pixmap to be painted + \param flags Image conversion flags + + \sa QPaintEngine::drawImage() + */ +void QwtGraphic::drawImage( const QRectF &rect, const QImage &image, + const QRectF &subRect, Qt::ImageConversionFlags flags) +{ + const QPainter *painter = paintEngine()->painter(); + if ( painter == NULL ) + return; + + d_data->commands += QwtPainterCommand( rect, image, subRect, flags ); + + const QRectF r = painter->transform().mapRect( rect ); + + updateControlPointRect( r ); + updateBoundingRect( r ); +} + +/*! + \brief Store a state command in the command list + + \param state State to be stored + \sa QPaintEngine::updateState() + */ +void QwtGraphic::updateState( const QPaintEngineState &state) +{ + d_data->commands += QwtPainterCommand( state ); +} + +void QwtGraphic::updateBoundingRect( const QRectF &rect ) +{ + QRectF br = rect; + + const QPainter *painter = paintEngine()->painter(); + if ( painter && painter->hasClipping() ) + { + QRectF cr = painter->clipRegion().boundingRect(); + cr = painter->transform().mapRect( br ); + + br &= cr; + } + + if ( d_data->boundingRect.width() < 0 ) + d_data->boundingRect = br; + else + d_data->boundingRect |= br; +} + +void QwtGraphic::updateControlPointRect( const QRectF &rect ) +{ + if ( d_data->pointRect.width() < 0.0 ) + d_data->pointRect = rect; + else + d_data->pointRect |= rect; +} + +/*! + \return List of recorded paint commands + \sa setCommands() + */ +const QVector< QwtPainterCommand > &QwtGraphic::commands() const +{ + return d_data->commands; +} + +/*! + \brief Append paint commands + + \param commands Paint commands + \sa commands() + */ +void QwtGraphic::setCommands( QVector< QwtPainterCommand > &commands ) +{ + reset(); + + const int numCommands = commands.size(); + if ( numCommands <= 0 ) + return; + + // to calculate a proper bounding rectangle we don't simply copy + // the commands. + + const QwtPainterCommand *cmds = commands.constData(); + + QPainter painter( this ); + for ( int i = 0; i < numCommands; i++ ) + qwtExecCommand( &painter, cmds[i], RenderHints(), QTransform() ); + + painter.end(); +} diff --git a/ThirdParty/Qwt/src/qwt_graphic.h b/ThirdParty/Qwt/src/qwt_graphic.h new file mode 100644 index 0000000000..ca625a8888 --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_graphic.h @@ -0,0 +1,174 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#ifndef QWT_GRAPHIC_H +#define QWT_GRAPHIC_H + +#include "qwt_global.h" +#include "qwt_null_paintdevice.h" +#include +#include +#include + +class QwtPainterCommand; + +/*! + \brief A paint device for scalable graphics + + QwtGraphic is the representation of a graphic that is tailored for + scalability. Like QPicture it will be initialized by QPainter + operations and replayed later to any target paint device. + + While the usual image representations QImage and QPixmap are not + scalable Qt offers two paint devices, that might be candidates + for representing a vector graphic: + + - QPicture\n + Unfortunately QPicture had been forgotten, when Qt4 + introduced floating point based render engines. Its API + is still on integers, what make it unusable for proper scaling. + + - QSvgRenderer/QSvgGenerator\n + Unfortunately QSvgRenderer hides to much information about + its nodes in internal APIs, that are necessary proper + layout calculations. Also it is derived from QObject and + can't be copied like QImage/QPixmap. + Also QSvgRenderer/QSvgGenerator are no complete SVG implementations + with a questionable future in Qt 5. + + QwtGraphic maps all scalable drawing primitives to a QPainterPath + and stores them together with the painter state changes + ( pen, brush, transformation ... ) in a list of QwtPaintCommands. + For being a complete QPaintDevice it also stores pixmaps or images, + what is somehow against the idea of the class, because these objects + can be scaled without a loss in quality. + + The main issue about scaling a QwtGraphic object are the pens used for + drawing the outlines of the painter paths. While non cosmetic pens + ( QPen::isCosmetic() ) are scaled with the same ratio as the path, + cosmetic pens have a fixed width. A graphic might have paths with + different pens - cosmetic and non-cosmetic. + + QwtGraphic caches 2 different rectangles: + + - control point rectangle\n + The control point rectangle is the bounding rectangle of all + control point rectangles of the painter paths, or the target + rectangle of the pixmaps/images. + + - bounding rectangle\n + The bounding rectangle extends the control point rectangle by + what is needed for rendering the outline with an unscaled pen. + + Because the offset for drawing the outline depends on the shape + of the painter path ( the peak of a triangle is different than the flat side ) + scaling with a fixed aspect ratio always needs to be calculated from the + control point rectangle. + + \sa QwtPainterCommand + */ +class QWT_EXPORT QwtGraphic: public QwtNullPaintDevice +{ +public: + /*! + Hint how to render a graphic + \sa setRenderHint(), testRenderHint() + */ + enum RenderHint + { + /*! + When RenderPensUnscaled is set non cosmetic pens are + painted unscaled - like cosmetic pens. The difference to + using cosmetic pens is, when the graphic is rendered + to a document in a scalable vector format ( PDF, SVG ): + the width of non cosmetic pens will be scaled by the + document viewer. + */ + RenderPensUnscaled = 0x1 + }; + + /*! + \brief Render hints + + The default setting is to disable all hints + */ + typedef QFlags RenderHints; + + QwtGraphic(); + QwtGraphic( const QwtGraphic & ); + + virtual ~QwtGraphic(); + + QwtGraphic& operator=( const QwtGraphic & ); + + void reset(); + + bool isNull() const; + bool isEmpty() const; + + void render( QPainter * ) const; + + void render( QPainter *, const QSizeF &, + Qt::AspectRatioMode = Qt::IgnoreAspectRatio ) const; + + void render( QPainter *, const QRectF &, + Qt::AspectRatioMode = Qt::IgnoreAspectRatio ) const; + + void render( QPainter *, const QPointF &, + Qt::Alignment = Qt::AlignTop | Qt::AlignLeft ) const; + + QPixmap toPixmap() const; + QPixmap toPixmap( const QSize &, + Qt::AspectRatioMode = Qt::IgnoreAspectRatio ) const; + + QImage toImage() const; + QImage toImage( const QSize &, + Qt::AspectRatioMode = Qt::IgnoreAspectRatio ) const; + + QRectF scaledBoundingRect( double sx, double sy ) const; + + QRectF boundingRect() const; + QRectF controlPointRect() const; + + const QVector< QwtPainterCommand > &commands() const; + void setCommands( QVector< QwtPainterCommand > & ); + + void setDefaultSize( const QSizeF & ); + QSizeF defaultSize() const; + + void setRenderHint( RenderHint, bool on = true ); + bool testRenderHint( RenderHint ) const; + +protected: + virtual QSize sizeMetrics() const; + + virtual void drawPath( const QPainterPath & ); + + virtual void drawPixmap( const QRectF &, + const QPixmap &, const QRectF & ); + + virtual void drawImage( const QRectF &, + const QImage &, const QRectF &, Qt::ImageConversionFlags ); + + virtual void updateState( const QPaintEngineState &state ); + +private: + void updateBoundingRect( const QRectF & ); + void updateControlPointRect( const QRectF & ); + + class PathInfo; + + class PrivateData; + PrivateData *d_data; +}; + +Q_DECLARE_OPERATORS_FOR_FLAGS( QwtGraphic::RenderHints ) +Q_DECLARE_METATYPE( QwtGraphic ) + +#endif diff --git a/ThirdParty/Qwt/src/qwt_interval.cpp b/ThirdParty/Qwt/src/qwt_interval.cpp new file mode 100644 index 0000000000..b7c6ee9920 --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_interval.cpp @@ -0,0 +1,354 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#include "qwt_interval.h" +#include "qwt_math.h" +#include + +/*! + \brief Normalize the limits of the interval + + If maxValue() < minValue() the limits will be inverted. + \return Normalized interval + + \sa isValid(), inverted() +*/ +QwtInterval QwtInterval::normalized() const +{ + if ( d_minValue > d_maxValue ) + { + return inverted(); + } + if ( d_minValue == d_maxValue && d_borderFlags == ExcludeMinimum ) + { + return inverted(); + } + + return *this; +} + +/*! + Invert the limits of the interval + \return Inverted interval + \sa normalized() +*/ +QwtInterval QwtInterval::inverted() const +{ + BorderFlags borderFlags = IncludeBorders; + if ( d_borderFlags & ExcludeMinimum ) + borderFlags |= ExcludeMaximum; + if ( d_borderFlags & ExcludeMaximum ) + borderFlags |= ExcludeMinimum; + + return QwtInterval( d_maxValue, d_minValue, borderFlags ); +} + +/*! + Test if a value is inside an interval + + \param value Value + \return true, if value >= minValue() && value <= maxValue() +*/ +bool QwtInterval::contains( double value ) const +{ + if ( !isValid() ) + return false; + + if ( value < d_minValue || value > d_maxValue ) + return false; + + if ( value == d_minValue && d_borderFlags & ExcludeMinimum ) + return false; + + if ( value == d_maxValue && d_borderFlags & ExcludeMaximum ) + return false; + + return true; +} + +//! Unite 2 intervals +QwtInterval QwtInterval::unite( const QwtInterval &other ) const +{ + /* + If one of the intervals is invalid return the other one. + If both are invalid return an invalid default interval + */ + if ( !isValid() ) + { + if ( !other.isValid() ) + return QwtInterval(); + else + return other; + } + if ( !other.isValid() ) + return *this; + + QwtInterval united; + BorderFlags flags = IncludeBorders; + + // minimum + if ( d_minValue < other.minValue() ) + { + united.setMinValue( d_minValue ); + flags &= d_borderFlags & ExcludeMinimum; + } + else if ( other.minValue() < d_minValue ) + { + united.setMinValue( other.minValue() ); + flags &= other.borderFlags() & ExcludeMinimum; + } + else // d_minValue == other.minValue() + { + united.setMinValue( d_minValue ); + flags &= ( d_borderFlags & other.borderFlags() ) & ExcludeMinimum; + } + + // maximum + if ( d_maxValue > other.maxValue() ) + { + united.setMaxValue( d_maxValue ); + flags &= d_borderFlags & ExcludeMaximum; + } + else if ( other.maxValue() > d_maxValue ) + { + united.setMaxValue( other.maxValue() ); + flags &= other.borderFlags() & ExcludeMaximum; + } + else // d_maxValue == other.maxValue() ) + { + united.setMaxValue( d_maxValue ); + flags &= d_borderFlags & other.borderFlags() & ExcludeMaximum; + } + + united.setBorderFlags( flags ); + return united; +} + +/*! + \brief Intersect 2 intervals + + \param other Interval to be intersect with + \return Intersection + */ +QwtInterval QwtInterval::intersect( const QwtInterval &other ) const +{ + if ( !other.isValid() || !isValid() ) + return QwtInterval(); + + QwtInterval i1 = *this; + QwtInterval i2 = other; + + // swap i1/i2, so that the minimum of i1 + // is smaller then the minimum of i2 + + if ( i1.minValue() > i2.minValue() ) + { + qSwap( i1, i2 ); + } + else if ( i1.minValue() == i2.minValue() ) + { + if ( i1.borderFlags() & ExcludeMinimum ) + qSwap( i1, i2 ); + } + + if ( i1.maxValue() < i2.minValue() ) + { + return QwtInterval(); + } + + if ( i1.maxValue() == i2.minValue() ) + { + if ( i1.borderFlags() & ExcludeMaximum || + i2.borderFlags() & ExcludeMinimum ) + { + return QwtInterval(); + } + } + + QwtInterval intersected; + BorderFlags flags = IncludeBorders; + + intersected.setMinValue( i2.minValue() ); + flags |= i2.borderFlags() & ExcludeMinimum; + + if ( i1.maxValue() < i2.maxValue() ) + { + intersected.setMaxValue( i1.maxValue() ); + flags |= i1.borderFlags() & ExcludeMaximum; + } + else if ( i2.maxValue() < i1.maxValue() ) + { + intersected.setMaxValue( i2.maxValue() ); + flags |= i2.borderFlags() & ExcludeMaximum; + } + else // i1.maxValue() == i2.maxValue() + { + intersected.setMaxValue( i1.maxValue() ); + flags |= i1.borderFlags() & i2.borderFlags() & ExcludeMaximum; + } + + intersected.setBorderFlags( flags ); + return intersected; +} + +/*! + \brief Unite this interval with the given interval. + + \param other Interval to be united with + \return This interval + */ +QwtInterval& QwtInterval::operator|=( const QwtInterval &other ) +{ + *this = *this | other; + return *this; +} + +/*! + \brief Intersect this interval with the given interval. + + \param other Interval to be intersected with + \return This interval + */ +QwtInterval& QwtInterval::operator&=( const QwtInterval &other ) +{ + *this = *this & other; + return *this; +} + +/*! + \brief Test if two intervals overlap + + \param other Interval + \return True, when the intervals are intersecting +*/ +bool QwtInterval::intersects( const QwtInterval &other ) const +{ + if ( !isValid() || !other.isValid() ) + return false; + + QwtInterval i1 = *this; + QwtInterval i2 = other; + + // swap i1/i2, so that the minimum of i1 + // is smaller then the minimum of i2 + + if ( i1.minValue() > i2.minValue() ) + { + qSwap( i1, i2 ); + } + else if ( i1.minValue() == i2.minValue() && + i1.borderFlags() & ExcludeMinimum ) + { + qSwap( i1, i2 ); + } + + if ( i1.maxValue() > i2.minValue() ) + { + return true; + } + if ( i1.maxValue() == i2.minValue() ) + { + return !( ( i1.borderFlags() & ExcludeMaximum ) || + ( i2.borderFlags() & ExcludeMinimum ) ); + } + return false; +} + +/*! + Adjust the limit that is closer to value, so that value becomes + the center of the interval. + + \param value Center + \return Interval with value as center +*/ +QwtInterval QwtInterval::symmetrize( double value ) const +{ + if ( !isValid() ) + return *this; + + const double delta = + qMax( qAbs( value - d_maxValue ), qAbs( value - d_minValue ) ); + + return QwtInterval( value - delta, value + delta ); +} + +/*! + Limit the interval, keeping the border modes + + \param lowerBound Lower limit + \param upperBound Upper limit + + \return Limited interval +*/ +QwtInterval QwtInterval::limited( double lowerBound, double upperBound ) const +{ + if ( !isValid() || lowerBound > upperBound ) + return QwtInterval(); + + double minValue = qMax( d_minValue, lowerBound ); + minValue = qMin( minValue, upperBound ); + + double maxValue = qMax( d_maxValue, lowerBound ); + maxValue = qMin( maxValue, upperBound ); + + return QwtInterval( minValue, maxValue, d_borderFlags ); +} + +/*! + \brief Extend the interval + + If value is below minValue(), value becomes the lower limit. + If value is above maxValue(), value becomes the upper limit. + + extend() has no effect for invalid intervals + + \param value Value + \return extended interval + + \sa isValid() +*/ +QwtInterval QwtInterval::extend( double value ) const +{ + if ( !isValid() ) + return *this; + + return QwtInterval( qMin( value, d_minValue ), + qMax( value, d_maxValue ), d_borderFlags ); +} + +/*! + Extend an interval + + \param value Value + \return Reference of the extended interval + + \sa extend() +*/ +QwtInterval& QwtInterval::operator|=( double value ) +{ + *this = *this | value; + return *this; +} + +#ifndef QT_NO_DEBUG_STREAM + +QDebug operator<<( QDebug debug, const QwtInterval &interval ) +{ + const int flags = interval.borderFlags(); + + debug.nospace() << "QwtInterval(" + << ( ( flags & QwtInterval::ExcludeMinimum ) ? "]" : "[" ) + << interval.minValue() << "," << interval.maxValue() + << ( ( flags & QwtInterval::ExcludeMaximum ) ? "[" : "]" ) + << ")"; + + return debug.space(); +} + +#endif diff --git a/ThirdParty/Qwt/src/qwt_interval.h b/ThirdParty/Qwt/src/qwt_interval.h new file mode 100644 index 0000000000..68841e00b3 --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_interval.h @@ -0,0 +1,320 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#ifndef QWT_INTERVAL_H +#define QWT_INTERVAL_H + +#include "qwt_global.h" +#include + +#ifndef QT_NO_DEBUG_STREAM +#include +#endif + +/*! + \brief A class representing an interval + + The interval is represented by 2 doubles, the lower and the upper limit. +*/ + +class QWT_EXPORT QwtInterval +{ +public: + /*! + Flag indicating if a border is included or excluded + \sa setBorderFlags(), borderFlags() + */ + enum BorderFlag + { + //! Min/Max values are inside the interval + IncludeBorders = 0x00, + + //! Min value is not included in the interval + ExcludeMinimum = 0x01, + + //! Max value is not included in the interval + ExcludeMaximum = 0x02, + + //! Min/Max values are not included in the interval + ExcludeBorders = ExcludeMinimum | ExcludeMaximum + }; + + //! Border flags + typedef QFlags BorderFlags; + + QwtInterval(); + QwtInterval( double minValue, double maxValue, + BorderFlags = IncludeBorders ); + + void setInterval( double minValue, double maxValue, + BorderFlags = IncludeBorders ); + + QwtInterval normalized() const; + QwtInterval inverted() const; + QwtInterval limited( double minValue, double maxValue ) const; + + bool operator==( const QwtInterval & ) const; + bool operator!=( const QwtInterval & ) const; + + void setBorderFlags( BorderFlags ); + BorderFlags borderFlags() const; + + double minValue() const; + double maxValue() const; + + double width() const; + + void setMinValue( double ); + void setMaxValue( double ); + + bool contains( double value ) const; + + bool intersects( const QwtInterval & ) const; + QwtInterval intersect( const QwtInterval & ) const; + QwtInterval unite( const QwtInterval & ) const; + + QwtInterval operator|( const QwtInterval & ) const; + QwtInterval operator&( const QwtInterval & ) const; + + QwtInterval &operator|=( const QwtInterval & ); + QwtInterval &operator&=( const QwtInterval & ); + + QwtInterval extend( double value ) const; + QwtInterval operator|( double ) const; + QwtInterval &operator|=( double ); + + bool isValid() const; + bool isNull() const; + void invalidate(); + + QwtInterval symmetrize( double value ) const; + +private: + double d_minValue; + double d_maxValue; + BorderFlags d_borderFlags; +}; + +Q_DECLARE_TYPEINFO(QwtInterval, Q_MOVABLE_TYPE); + +/*! + \brief Default Constructor + + Creates an invalid interval [0.0, -1.0] + \sa setInterval(), isValid() +*/ +inline QwtInterval::QwtInterval(): + d_minValue( 0.0 ), + d_maxValue( -1.0 ), + d_borderFlags( IncludeBorders ) +{ +} + +/*! + Constructor + + Build an interval with from min/max values + + \param minValue Minimum value + \param maxValue Maximum value + \param borderFlags Include/Exclude borders +*/ +inline QwtInterval::QwtInterval( + double minValue, double maxValue, BorderFlags borderFlags ): + d_minValue( minValue ), + d_maxValue( maxValue ), + d_borderFlags( borderFlags ) +{ +} + +/*! + Assign the limits of the interval + + \param minValue Minimum value + \param maxValue Maximum value + \param borderFlags Include/Exclude borders +*/ +inline void QwtInterval::setInterval( + double minValue, double maxValue, BorderFlags borderFlags ) +{ + d_minValue = minValue; + d_maxValue = maxValue; + d_borderFlags = borderFlags; +} + +/*! + Change the border flags + + \param borderFlags Or'd BorderMode flags + \sa borderFlags() +*/ +inline void QwtInterval::setBorderFlags( BorderFlags borderFlags ) +{ + d_borderFlags = borderFlags; +} + +/*! + \return Border flags + \sa setBorderFlags() +*/ +inline QwtInterval::BorderFlags QwtInterval::borderFlags() const +{ + return d_borderFlags; +} + +/*! + Assign the lower limit of the interval + + \param minValue Minimum value +*/ +inline void QwtInterval::setMinValue( double minValue ) +{ + d_minValue = minValue; +} + +/*! + Assign the upper limit of the interval + + \param maxValue Maximum value +*/ +inline void QwtInterval::setMaxValue( double maxValue ) +{ + d_maxValue = maxValue; +} + +//! \return Lower limit of the interval +inline double QwtInterval::minValue() const +{ + return d_minValue; +} + +//! \return Upper limit of the interval +inline double QwtInterval::maxValue() const +{ + return d_maxValue; +} + +/*! + A interval is valid when minValue() <= maxValue(). + In case of QwtInterval::ExcludeBorders it is true + when minValue() < maxValue() + + \return True, when the interval is valid +*/ +inline bool QwtInterval::isValid() const +{ + if ( ( d_borderFlags & ExcludeBorders ) == 0 ) + return d_minValue <= d_maxValue; + else + return d_minValue < d_maxValue; +} + +/*! + \brief Return the width of an interval + + The width of invalid intervals is 0.0, otherwise the result is + maxValue() - minValue(). + + \return Interval width + \sa isValid() +*/ +inline double QwtInterval::width() const +{ + return isValid() ? ( d_maxValue - d_minValue ) : 0.0; +} + +/*! + \brief Intersection of two intervals + + \param other Interval to intersect with + \return Intersection of this and other + + \sa intersect() +*/ +inline QwtInterval QwtInterval::operator&( + const QwtInterval &other ) const +{ + return intersect( other ); +} + +/*! + Union of two intervals + + \param other Interval to unite with + \return Union of this and other + + \sa unite() +*/ +inline QwtInterval QwtInterval::operator|( + const QwtInterval &other ) const +{ + return unite( other ); +} + +/*! + \brief Compare two intervals + + \param other Interval to compare with + \return True, when this and other are equal +*/ +inline bool QwtInterval::operator==( const QwtInterval &other ) const +{ + return ( d_minValue == other.d_minValue ) && + ( d_maxValue == other.d_maxValue ) && + ( d_borderFlags == other.d_borderFlags ); +} +/*! + \brief Compare two intervals + + \param other Interval to compare with + \return True, when this and other are not equal +*/ +inline bool QwtInterval::operator!=( const QwtInterval &other ) const +{ + return ( !( *this == other ) ); +} + +/*! + Extend an interval + + \param value Value + \return Extended interval + \sa extend() +*/ +inline QwtInterval QwtInterval::operator|( double value ) const +{ + return extend( value ); +} + +//! \return true, if isValid() && (minValue() >= maxValue()) +inline bool QwtInterval::isNull() const +{ + return isValid() && d_minValue >= d_maxValue; +} + +/*! + Invalidate the interval + + The limits are set to interval [0.0, -1.0] + \sa isValid() +*/ +inline void QwtInterval::invalidate() +{ + d_minValue = 0.0; + d_maxValue = -1.0; +} + +Q_DECLARE_OPERATORS_FOR_FLAGS( QwtInterval::BorderFlags ) +Q_DECLARE_METATYPE( QwtInterval ) + +#ifndef QT_NO_DEBUG_STREAM +QWT_EXPORT QDebug operator<<( QDebug, const QwtInterval & ); +#endif + +#endif diff --git a/ThirdParty/Qwt/src/qwt_interval_symbol.cpp b/ThirdParty/Qwt/src/qwt_interval_symbol.cpp new file mode 100644 index 0000000000..83c842d984 --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_interval_symbol.cpp @@ -0,0 +1,319 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#include "qwt_interval_symbol.h" +#include "qwt_painter.h" +#include "qwt_math.h" +#include + +#if QT_VERSION < 0x040601 +#define qAtan2(y, x) ::atan2(y, x) +#define qFastSin(x) qSin(x) +#define qFastCos(x) qCos(x) +#endif + +class QwtIntervalSymbol::PrivateData +{ +public: + PrivateData(): + style( QwtIntervalSymbol::NoSymbol ), + width( 6 ) + { + } + + bool operator==( const PrivateData &other ) const + { + return ( style == other.style ) + && ( width == other.width ) + && ( brush == other.brush ) + && ( pen == other.pen ); + } + + QwtIntervalSymbol::Style style; + int width; + + QPen pen; + QBrush brush; +}; + +/*! + Constructor + + \param style Style of the symbol + \sa setStyle(), style(), Style +*/ +QwtIntervalSymbol::QwtIntervalSymbol( Style style ) +{ + d_data = new PrivateData(); + d_data->style = style; +} + +//! Copy constructor +QwtIntervalSymbol::QwtIntervalSymbol( const QwtIntervalSymbol &other ) +{ + d_data = new PrivateData(); + *d_data = *other.d_data; +} + +//! Destructor +QwtIntervalSymbol::~QwtIntervalSymbol() +{ + delete d_data; +} + +//! \brief Assignment operator +QwtIntervalSymbol &QwtIntervalSymbol::operator=( + const QwtIntervalSymbol &other ) +{ + *d_data = *other.d_data; + return *this; +} + +//! \brief Compare two symbols +bool QwtIntervalSymbol::operator==( + const QwtIntervalSymbol &other ) const +{ + return *d_data == *other.d_data; +} + +//! \brief Compare two symbols +bool QwtIntervalSymbol::operator!=( + const QwtIntervalSymbol &other ) const +{ + return !( *d_data == *other.d_data ); +} + +/*! + Specify the symbol style + + \param style Style + \sa style(), Style +*/ +void QwtIntervalSymbol::setStyle( Style style ) +{ + d_data->style = style; +} + +/*! + \return Current symbol style + \sa setStyle() +*/ +QwtIntervalSymbol::Style QwtIntervalSymbol::style() const +{ + return d_data->style; +} + +/*! + Specify the width of the symbol + It is used depending on the style. + + \param width Width + \sa width(), setStyle() +*/ +void QwtIntervalSymbol::setWidth( int width ) +{ + d_data->width = width; +} + +/*! + \return Width of the symbol. + \sa setWidth(), setStyle() +*/ +int QwtIntervalSymbol::width() const +{ + return d_data->width; +} + +/*! + \brief Assign a brush + + The brush is used for the Box style. + + \param brush Brush + \sa brush() +*/ +void QwtIntervalSymbol::setBrush( const QBrush &brush ) +{ + d_data->brush = brush; +} + +/*! + \return Brush + \sa setBrush() +*/ +const QBrush& QwtIntervalSymbol::brush() const +{ + return d_data->brush; +} + +/*! + Build and assign a pen + + In Qt5 the default pen width is 1.0 ( 0.0 in Qt4 ) what makes it + non cosmetic ( see QPen::isCosmetic() ). This method has been introduced + to hide this incompatibility. + + \param color Pen color + \param width Pen width + \param style Pen style + + \sa pen(), brush() + */ +void QwtIntervalSymbol::setPen( const QColor &color, + qreal width, Qt::PenStyle style ) +{ + setPen( QPen( color, width, style ) ); +} + +/*! + Assign a pen + + \param pen Pen + \sa pen(), setBrush() +*/ +void QwtIntervalSymbol::setPen( const QPen &pen ) +{ + d_data->pen = pen; +} + +/*! + \return Pen + \sa setPen(), brush() +*/ +const QPen& QwtIntervalSymbol::pen() const +{ + return d_data->pen; +} + +/*! + Draw a symbol depending on its style + + \param painter Painter + \param orientation Orientation + \param from Start point of the interval in target device coordinates + \param to End point of the interval in target device coordinates + + \sa setStyle() +*/ +void QwtIntervalSymbol::draw( QPainter *painter, Qt::Orientation orientation, + const QPointF &from, const QPointF &to ) const +{ + const qreal pw = qMax( painter->pen().widthF(), qreal( 1.0 ) ); + + QPointF p1 = from; + QPointF p2 = to; + if ( QwtPainter::roundingAlignment( painter ) ) + { + p1 = p1.toPoint(); + p2 = p2.toPoint(); + } + + switch ( d_data->style ) + { + case QwtIntervalSymbol::Bar: + { + QwtPainter::drawLine( painter, p1, p2 ); + if ( d_data->width > pw ) + { + if ( ( orientation == Qt::Horizontal ) + && ( p1.y() == p2.y() ) ) + { + const double sw = d_data->width; + + const double y = p1.y() - sw / 2; + QwtPainter::drawLine( painter, + p1.x(), y, p1.x(), y + sw ); + QwtPainter::drawLine( painter, + p2.x(), y, p2.x(), y + sw ); + } + else if ( ( orientation == Qt::Vertical ) + && ( p1.x() == p2.x() ) ) + { + const double sw = d_data->width; + + const double x = p1.x() - sw / 2; + QwtPainter::drawLine( painter, + x, p1.y(), x + sw, p1.y() ); + QwtPainter::drawLine( painter, + x, p2.y(), x + sw, p2.y() ); + } + else + { + const double sw = d_data->width; + + const double dx = p2.x() - p1.x(); + const double dy = p2.y() - p1.y(); + const double angle = qAtan2( dy, dx ) + M_PI_2; + double dw2 = sw / 2.0; + + const double cx = qFastCos( angle ) * dw2; + const double sy = qFastSin( angle ) * dw2; + + QwtPainter::drawLine( painter, + p1.x() - cx, p1.y() - sy, + p1.x() + cx, p1.y() + sy ); + QwtPainter::drawLine( painter, + p2.x() - cx, p2.y() - sy, + p2.x() + cx, p2.y() + sy ); + } + } + break; + } + case QwtIntervalSymbol::Box: + { + if ( d_data->width <= pw ) + { + QwtPainter::drawLine( painter, p1, p2 ); + } + else + { + if ( ( orientation == Qt::Horizontal ) + && ( p1.y() == p2.y() ) ) + { + const double sw = d_data->width; + + const double y = p1.y() - d_data->width / 2; + QwtPainter::drawRect( painter, + p1.x(), y, p2.x() - p1.x(), sw ); + } + else if ( ( orientation == Qt::Vertical ) + && ( p1.x() == p2.x() ) ) + { + const double sw = d_data->width; + + const double x = p1.x() - d_data->width / 2; + QwtPainter::drawRect( painter, + x, p1.y(), sw, p2.y() - p1.y() ); + } + else + { + const double sw = d_data->width; + + const double dx = p2.x() - p1.x(); + const double dy = p2.y() - p1.y(); + const double angle = qAtan2( dy, dx ) + M_PI_2; + double dw2 = sw / 2.0; + + const double cx = qFastCos( angle ) * dw2; + const double sy = qFastSin( angle ) * dw2; + + QPolygonF polygon; + polygon += QPointF( p1.x() - cx, p1.y() - sy ); + polygon += QPointF( p1.x() + cx, p1.y() + sy ); + polygon += QPointF( p2.x() + cx, p2.y() + sy ); + polygon += QPointF( p2.x() - cx, p2.y() - sy ); + + QwtPainter::drawPolygon( painter, polygon ); + } + } + break; + } + default:; + } +} diff --git a/ThirdParty/Qwt/src/qwt_interval_symbol.h b/ThirdParty/Qwt/src/qwt_interval_symbol.h new file mode 100644 index 0000000000..f32e1c41dc --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_interval_symbol.h @@ -0,0 +1,87 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#ifndef QWT_INTERVAL_SYMBOL_H +#define QWT_INTERVAL_SYMBOL_H + +#include "qwt_global.h" +#include +#include + +class QPainter; +class QRect; +class QPointF; + +/*! + \brief A drawing primitive for displaying an interval like an error bar + + \sa QwtPlotIntervalCurve +*/ +class QWT_EXPORT QwtIntervalSymbol +{ +public: + //! Symbol style + enum Style + { + //! No Style. The symbol cannot be drawn. + NoSymbol = -1, + + /*! + The symbol displays a line with caps at the beginning/end. + The size of the caps depends on the symbol width(). + */ + Bar, + + /*! + The symbol displays a plain rectangle using pen() and brush(). + The size of the rectangle depends on the translated interval and + the width(), + */ + Box, + + /*! + Styles >= UserSymbol are reserved for derived + classes of QwtIntervalSymbol that overload draw() with + additional application specific symbol types. + */ + UserSymbol = 1000 + }; + +public: + QwtIntervalSymbol( Style = NoSymbol ); + QwtIntervalSymbol( const QwtIntervalSymbol & ); + virtual ~QwtIntervalSymbol(); + + QwtIntervalSymbol &operator=( const QwtIntervalSymbol & ); + bool operator==( const QwtIntervalSymbol & ) const; + bool operator!=( const QwtIntervalSymbol & ) const; + + void setWidth( int ); + int width() const; + + void setBrush( const QBrush& b ); + const QBrush& brush() const; + + void setPen( const QColor &, qreal width = 0.0, Qt::PenStyle = Qt::SolidLine ); + void setPen( const QPen & ); + const QPen& pen() const; + + void setStyle( Style ); + Style style() const; + + virtual void draw( QPainter *, Qt::Orientation, + const QPointF& from, const QPointF& to ) const; + +private: + + class PrivateData; + PrivateData* d_data; +}; + +#endif diff --git a/ThirdParty/Qwt/src/qwt_knob.cpp b/ThirdParty/Qwt/src/qwt_knob.cpp new file mode 100644 index 0000000000..5860e42c47 --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_knob.cpp @@ -0,0 +1,845 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#include "qwt_knob.h" +#include "qwt_round_scale_draw.h" +#include "qwt_math.h" +#include "qwt_painter.h" +#include "qwt_scale_map.h" +#include +#include +#include +#include +#include +#include +#include + +#if QT_VERSION < 0x040601 +#define qAtan2(y, x) ::atan2(y, x) +#define qFabs(x) ::fabs(x) +#define qFastCos(x) qCos(x) +#define qFastSin(x) qSin(x) +#endif + +static QSize qwtKnobSizeHint( const QwtKnob *knob, int min ) +{ + int knobWidth = knob->knobWidth(); + if ( knobWidth <= 0 ) + knobWidth = qMax( 3 * knob->markerSize(), min ); + + // Add the scale radial thickness to the knobWidth + const int extent = qCeil( knob->scaleDraw()->extent( knob->font() ) ); + const int d = 2 * ( extent + 4 ) + knobWidth; + + int left, right, top, bottom; + knob->getContentsMargins( &left, &top, &right, &bottom ); + + return QSize( d + left + right, d + top + bottom ); +} + +static inline double qwtToScaleAngle( double angle ) +{ + // the map is counter clockwise with the origin + // at 90° using angles from -180° -> 180° + + double a = 90.0 - angle; + if ( a <= -180.0 ) + a += 360.0; + else if ( a >= 180.0 ) + a -= 360.0; + + return a; +} + +static double qwtToDegrees( double value ) +{ + return qwtNormalizeDegrees( 90.0 - value ); +} + +class QwtKnob::PrivateData +{ +public: + PrivateData(): + knobStyle( QwtKnob::Raised ), + markerStyle( QwtKnob::Notch ), + borderWidth( 2 ), + borderDist( 4 ), + scaleDist( 4 ), + maxScaleTicks( 11 ), + knobWidth( 0 ), + alignment( Qt::AlignCenter ), + markerSize( 8 ), + totalAngle( 270.0 ), + mouseOffset( 0.0 ) + { + } + + QwtKnob::KnobStyle knobStyle; + QwtKnob::MarkerStyle markerStyle; + + int borderWidth; + int borderDist; + int scaleDist; + int maxScaleTicks; + int knobWidth; + Qt::Alignment alignment; + int markerSize; + + double totalAngle; + + double mouseOffset; +}; + +/*! + \brief Constructor + + Construct a knob with an angle of 270°. The style is + QwtKnob::Raised and the marker style is QwtKnob::Notch. + The width of the knob is set to 50 pixels. + + \param parent Parent widget + + \sa setTotalAngle() +*/ +QwtKnob::QwtKnob( QWidget* parent ): + QwtAbstractSlider( parent ) +{ + d_data = new PrivateData; + + setScaleDraw( new QwtRoundScaleDraw() ); + + setTotalAngle( 270.0 ); + + setScale( 0.0, 10.0 ); + setValue( 0.0 ); + + setSizePolicy( QSizePolicy::MinimumExpanding, + QSizePolicy::MinimumExpanding ); +} + +//! Destructor +QwtKnob::~QwtKnob() +{ + delete d_data; +} + +/*! + \brief Set the knob type + + \param knobStyle Knob type + \sa knobStyle(), setBorderWidth() +*/ +void QwtKnob::setKnobStyle( KnobStyle knobStyle ) +{ + if ( d_data->knobStyle != knobStyle ) + { + d_data->knobStyle = knobStyle; + update(); + } +} + +/*! + \return Marker type of the knob + \sa setKnobStyle(), setBorderWidth() +*/ +QwtKnob::KnobStyle QwtKnob::knobStyle() const +{ + return d_data->knobStyle; +} + +/*! + \brief Set the marker type of the knob + + \param markerStyle Marker type + \sa markerStyle(), setMarkerSize() +*/ +void QwtKnob::setMarkerStyle( MarkerStyle markerStyle ) +{ + if ( d_data->markerStyle != markerStyle ) + { + d_data->markerStyle = markerStyle; + update(); + } +} + +/*! + \return Marker type of the knob + \sa setMarkerStyle(), setMarkerSize() +*/ +QwtKnob::MarkerStyle QwtKnob::markerStyle() const +{ + return d_data->markerStyle; +} + +/*! + \brief Set the total angle by which the knob can be turned + \param angle Angle in degrees. + + The angle has to be between [10, 360] degrees. Angles above + 360 ( so that the knob can be turned several times around its axis ) + have to be set using setNumTurns(). + + The default angle is 270 degrees. + + \sa totalAngle(), setNumTurns() +*/ +void QwtKnob::setTotalAngle ( double angle ) +{ + angle = qBound( 10.0, angle, 360.0 ); + + if ( angle != d_data->totalAngle ) + { + d_data->totalAngle = angle; + + scaleDraw()->setAngleRange( -0.5 * d_data->totalAngle, + 0.5 * d_data->totalAngle ); + + updateGeometry(); + update(); + } +} + +/*! + \return the total angle + \sa setTotalAngle(), setNumTurns(), numTurns() + */ +double QwtKnob::totalAngle() const +{ + return d_data->totalAngle; +} + +/*! + \brief Set the number of turns + + When numTurns > 1 the knob can be turned several times around its axis + - otherwise the total angle is floored to 360°. + + \sa numTurns(), totalAngle(), setTotalAngle() +*/ + +void QwtKnob::setNumTurns( int numTurns ) +{ + numTurns = qMax( numTurns, 1 ); + + if ( numTurns == 1 && d_data->totalAngle <= 360.0 ) + return; + + const double angle = numTurns * 360.0; + if ( angle != d_data->totalAngle ) + { + d_data->totalAngle = angle; + + scaleDraw()->setAngleRange( -0.5 * d_data->totalAngle, + 0.5 * d_data->totalAngle ); + + updateGeometry(); + update(); + } +} + +/*! + \return Number of turns. + + When the total angle is below 360° numTurns() is ceiled to 1. + \sa setNumTurns(), setTotalAngle(), totalAngle() + */ +int QwtKnob::numTurns() const +{ + return qCeil( d_data->totalAngle / 360.0 ); +} + +/*! + Change the scale draw of the knob + + For changing the labels of the scales, it + is necessary to derive from QwtRoundScaleDraw and + overload QwtRoundScaleDraw::label(). + + \sa scaleDraw() +*/ +void QwtKnob::setScaleDraw( QwtRoundScaleDraw *scaleDraw ) +{ + setAbstractScaleDraw( scaleDraw ); + setTotalAngle( d_data->totalAngle ); +} + +/*! + \return the scale draw of the knob + \sa setScaleDraw() +*/ +const QwtRoundScaleDraw *QwtKnob::scaleDraw() const +{ + return static_cast( abstractScaleDraw() ); +} + +/*! + \return the scale draw of the knob + \sa setScaleDraw() +*/ +QwtRoundScaleDraw *QwtKnob::scaleDraw() +{ + return static_cast( abstractScaleDraw() ); +} + +/*! + Calculate the bounding rectangle of the knob without the scale + + \return Bounding rectangle of the knob + \sa knobWidth(), alignment(), QWidget::contentsRect() + */ +QRect QwtKnob::knobRect() const +{ + const QRect cr = contentsRect(); + + const int extent = qCeil( scaleDraw()->extent( font() ) ); + const int d = extent + d_data->scaleDist; + + int w = d_data->knobWidth; + if ( w <= 0 ) + { + const int dim = qMin( cr.width(), cr.height() ); + + w = dim - 2 * ( d ); + w = qMax( 0, w ); + } + + QRect r( 0, 0, w, w ); + + if ( d_data->alignment & Qt::AlignLeft ) + { + r.moveLeft( cr.left() + d ); + } + else if ( d_data->alignment & Qt::AlignRight ) + { + r.moveRight( cr.right() - d ); + } + else + { + r.moveCenter( QPoint( cr.center().x(), r.center().y() ) ); + } + + if ( d_data->alignment & Qt::AlignTop ) + { + r.moveTop( cr.top() + d ); + } + else if ( d_data->alignment & Qt::AlignBottom ) + { + r.moveBottom( cr.bottom() - d ); + } + else + { + r.moveCenter( QPoint( r.center().x(), cr.center().y() ) ); + } + + return r; +} + +/*! + \brief Determine what to do when the user presses a mouse button. + + \param pos Mouse position + + \retval True, when pos is inside the circle of the knob. + \sa scrolledTo() +*/ +bool QwtKnob::isScrollPosition( const QPoint &pos ) const +{ + const QRect kr = knobRect(); + + const QRegion region( kr, QRegion::Ellipse ); + if ( region.contains( pos ) && ( pos != kr.center() ) ) + { + const double angle = QLineF( kr.center(), pos ).angle(); + const double valueAngle = qwtToDegrees( transform( value() ) ); + + d_data->mouseOffset = qwtNormalizeDegrees( angle - valueAngle ); + + return true; + } + + return false; +} + +/*! + \brief Determine the value for a new position of the mouse + + \param pos Mouse position + + \return Value for the mouse position + \sa isScrollPosition() +*/ +double QwtKnob::scrolledTo( const QPoint &pos ) const +{ + double angle = QLineF( rect().center(), pos ).angle(); + angle = qwtNormalizeDegrees( angle - d_data->mouseOffset ); + + if ( scaleMap().pDist() > 360.0 ) + { + angle = qwtToDegrees( angle ); + + const double v = transform( value() ); + + int numTurns = qFloor( ( v - scaleMap().p1() ) / 360.0 ); + + double valueAngle = qwtNormalizeDegrees( v ); + if ( qAbs( valueAngle - angle ) > 180.0 ) + { + numTurns += ( angle > valueAngle ) ? -1 : 1; + } + + angle += scaleMap().p1() + numTurns * 360.0; + + if ( !wrapping() ) + { + const double boundedAngle = + qBound( scaleMap().p1(), angle, scaleMap().p2() ); + + d_data->mouseOffset += ( boundedAngle - angle ); + angle = boundedAngle; + } + } + else + { + angle = qwtToScaleAngle( angle ); + + const double boundedAngle = + qBound( scaleMap().p1(), angle, scaleMap().p2() ); + + if ( !wrapping() ) + d_data->mouseOffset += ( boundedAngle - angle ); + + angle = boundedAngle; + } + + return invTransform( angle ); +} + +/*! + Handle QEvent::StyleChange and QEvent::FontChange; + \param event Change event +*/ +void QwtKnob::changeEvent( QEvent *event ) +{ + switch( event->type() ) + { + case QEvent::StyleChange: + case QEvent::FontChange: + { + updateGeometry(); + update(); + break; + } + default: + break; + } +} + +/*! + Repaint the knob + \param event Paint event +*/ +void QwtKnob::paintEvent( QPaintEvent *event ) +{ + const QRectF knobRect = this->knobRect(); + + QPainter painter( this ); + painter.setClipRegion( event->region() ); + + QStyleOption opt; + opt.init(this); + style()->drawPrimitive(QStyle::PE_Widget, &opt, &painter, this); + + painter.setRenderHint( QPainter::Antialiasing, true ); + + if ( !knobRect.contains( event->region().boundingRect() ) ) + { + scaleDraw()->setRadius( 0.5 * knobRect.width() + d_data->scaleDist ); + scaleDraw()->moveCenter( knobRect.center() ); + + scaleDraw()->draw( &painter, palette() ); + } + + drawKnob( &painter, knobRect ); + + drawMarker( &painter, knobRect, + qwtNormalizeDegrees( transform( value() ) ) ); + + painter.setRenderHint( QPainter::Antialiasing, false ); + + if ( hasFocus() ) + drawFocusIndicator( &painter ); +} + +/*! + \brief Draw the knob + + \param painter painter + \param knobRect Bounding rectangle of the knob (without scale) +*/ +void QwtKnob::drawKnob( QPainter *painter, const QRectF &knobRect ) const +{ + double dim = qMin( knobRect.width(), knobRect.height() ); + dim -= d_data->borderWidth * 0.5; + + QRectF aRect( 0, 0, dim, dim ); + aRect.moveCenter( knobRect.center() ); + + QPen pen( Qt::NoPen ); + if ( d_data->borderWidth > 0 ) + { + QColor c1 = palette().color( QPalette::Light ); + QColor c2 = palette().color( QPalette::Dark ); + + QLinearGradient gradient( aRect.topLeft(), aRect.bottomRight() ); + gradient.setColorAt( 0.0, c1 ); + gradient.setColorAt( 0.3, c1 ); + gradient.setColorAt( 0.7, c2 ); + gradient.setColorAt( 1.0, c2 ); + + pen = QPen( gradient, d_data->borderWidth ); + } + + QBrush brush; + switch( d_data->knobStyle ) + { + case QwtKnob::Raised: + { + double off = 0.3 * knobRect.width(); + QRadialGradient gradient( knobRect.center(), + knobRect.width(), knobRect.topLeft() + QPointF( off, off ) ); + + gradient.setColorAt( 0.0, palette().color( QPalette::Midlight ) ); + gradient.setColorAt( 1.0, palette().color( QPalette::Button ) ); + + brush = QBrush( gradient ); + + break; + } + case QwtKnob::Styled: + { + QRadialGradient gradient(knobRect.center().x() - knobRect.width() / 3, + knobRect.center().y() - knobRect.height() / 2, + knobRect.width() * 1.3, + knobRect.center().x(), + knobRect.center().y() - knobRect.height() / 2); + + const QColor c = palette().color( QPalette::Button ); + gradient.setColorAt(0, c.lighter(110)); + gradient.setColorAt(qreal(0.5), c); + gradient.setColorAt(qreal(0.501), c.darker(102)); + gradient.setColorAt(1, c.darker(115)); + + brush = QBrush( gradient ); + + break; + } + case QwtKnob::Sunken: + { + QLinearGradient gradient( + knobRect.topLeft(), knobRect.bottomRight() ); + gradient.setColorAt( 0.0, palette().color( QPalette::Mid ) ); + gradient.setColorAt( 0.5, palette().color( QPalette::Button ) ); + gradient.setColorAt( 1.0, palette().color( QPalette::Midlight ) ); + brush = QBrush( gradient ); + + break; + } + case QwtKnob::Flat: + default: + brush = palette().brush( QPalette::Button ); + } + + painter->setPen( pen ); + painter->setBrush( brush ); + painter->drawEllipse( aRect ); +} + + +/*! + \brief Draw the marker at the knob's front + + \param painter Painter + \param rect Bounding rectangle of the knob without scale + \param angle Angle of the marker in degrees + ( clockwise, 0 at the 12 o'clock position ) +*/ +void QwtKnob::drawMarker( QPainter *painter, + const QRectF &rect, double angle ) const +{ + if ( d_data->markerStyle == NoMarker || !isValid() ) + return; + + const double radians = qwtRadians( angle ); + const double sinA = -qFastSin( radians ); + const double cosA = qFastCos( radians ); + + const double xm = rect.center().x(); + const double ym = rect.center().y(); + const double margin = 4.0; + + double radius = 0.5 * ( rect.width() - d_data->borderWidth ) - margin; + if ( radius < 1.0 ) + radius = 1.0; + + int markerSize = d_data->markerSize; + if ( markerSize <= 0 ) + markerSize = qRound( 0.4 * radius ); + + switch ( d_data->markerStyle ) + { + case Notch: + case Nub: + { + const double dotWidth = + qMin( double( markerSize ), radius); + + const double dotCenterDist = radius - 0.5 * dotWidth; + if ( dotCenterDist > 0.0 ) + { + const QPointF center( xm - sinA * dotCenterDist, + ym - cosA * dotCenterDist ); + + QRectF ellipse( 0.0, 0.0, dotWidth, dotWidth ); + ellipse.moveCenter( center ); + + QColor c1 = palette().color( QPalette::Light ); + QColor c2 = palette().color( QPalette::Mid ); + + if ( d_data->markerStyle == Notch ) + qSwap( c1, c2 ); + + QLinearGradient gradient( + ellipse.topLeft(), ellipse.bottomRight() ); + gradient.setColorAt( 0.0, c1 ); + gradient.setColorAt( 1.0, c2 ); + + painter->setPen( Qt::NoPen ); + painter->setBrush( gradient ); + + painter->drawEllipse( ellipse ); + } + break; + } + case Dot: + { + const double dotWidth = + qMin( double( markerSize ), radius); + + const double dotCenterDist = radius - 0.5 * dotWidth; + if ( dotCenterDist > 0.0 ) + { + const QPointF center( xm - sinA * dotCenterDist, + ym - cosA * dotCenterDist ); + + QRectF ellipse( 0.0, 0.0, dotWidth, dotWidth ); + ellipse.moveCenter( center ); + + painter->setPen( Qt::NoPen ); + painter->setBrush( palette().color( QPalette::ButtonText ) ); + painter->drawEllipse( ellipse ); + } + + break; + } + case Tick: + { + const double rb = qMax( radius - markerSize, 1.0 ); + const double re = radius; + + const QLineF line( xm - sinA * rb, ym - cosA * rb, + xm - sinA * re, ym - cosA * re ); + + QPen pen( palette().color( QPalette::ButtonText ), 0 ); + pen.setCapStyle( Qt::FlatCap ); + painter->setPen( pen ); + painter->drawLine ( line ); + + break; + } + case Triangle: + { + const double rb = qMax( radius - markerSize, 1.0 ); + const double re = radius; + + painter->translate( rect.center() ); + painter->rotate( angle - 90.0 ); + + QPolygonF polygon; + polygon += QPointF( re, 0.0 ); + polygon += QPointF( rb, 0.5 * ( re - rb ) ); + polygon += QPointF( rb, -0.5 * ( re - rb ) ); + + painter->setPen( Qt::NoPen ); + painter->setBrush( palette().color( QPalette::ButtonText ) ); + painter->drawPolygon( polygon ); + + painter->resetTransform(); + + break; + } + default: + break; + } +} + +/*! + Draw the focus indicator + \param painter Painter +*/ +void QwtKnob::drawFocusIndicator( QPainter *painter ) const +{ + const QRect cr = contentsRect(); + + int w = d_data->knobWidth; + if ( w <= 0 ) + { + w = qMin( cr.width(), cr.height() ); + } + else + { + const int extent = qCeil( scaleDraw()->extent( font() ) ); + w += 2 * ( extent + d_data->scaleDist ); + } + + QRect focusRect( 0, 0, w, w ); + focusRect.moveCenter( cr.center() ); + + QwtPainter::drawFocusRect( painter, this, focusRect ); +} + +/*! + \brief Set the alignment of the knob + + Similar to a QLabel::alignment() the flags decide how + to align the knob inside of contentsRect(). + + The default setting is Qt::AlignCenter + + \param alignment Or'd alignment flags + + \sa alignment(), setKnobWidth(), knobRect() + */ +void QwtKnob::setAlignment( Qt::Alignment alignment ) +{ + if ( d_data->alignment != alignment ) + { + d_data->alignment = alignment; + update(); + } +} + +/*! + \return Alignment of the knob inside of contentsRect() + \sa setAlignment(), knobWidth(), knobRect() + */ +Qt::Alignment QwtKnob::alignment() const +{ + return d_data->alignment; +} + +/*! + \brief Change the knob's width. + + Setting a fixed value for the diameter of the knob + is helpful for aligning several knobs in a row. + + \param width New width + + \sa knobWidth(), setAlignment() + \note Modifies the sizePolicy() +*/ +void QwtKnob::setKnobWidth( int width ) +{ + width = qMax( width, 0 ); + + if ( width != d_data->knobWidth ) + { + QSizePolicy::Policy policy; + if ( width > 0 ) + policy = QSizePolicy::Minimum; + else + policy = QSizePolicy::MinimumExpanding; + + setSizePolicy( policy, policy ); + + d_data->knobWidth = width; + + updateGeometry(); + update(); + } +} + +//! Return the width of the knob +int QwtKnob::knobWidth() const +{ + return d_data->knobWidth; +} + +/*! + \brief Set the knob's border width + \param borderWidth new border width +*/ +void QwtKnob::setBorderWidth( int borderWidth ) +{ + d_data->borderWidth = qMax( borderWidth, 0 ); + + updateGeometry(); + update(); + +} + +//! Return the border width +int QwtKnob::borderWidth() const +{ + return d_data->borderWidth; +} + +/*! + \brief Set the size of the marker + + When setting a size <= 0 the marker will + automatically scaled to 40% of the radius of the knob. + + \sa markerSize(), markerStyle() +*/ +void QwtKnob::setMarkerSize( int size ) +{ + if ( d_data->markerSize != size ) + { + d_data->markerSize = size; + update(); + } +} + +/*! + \return Marker size + \sa setMarkerSize() + */ +int QwtKnob::markerSize() const +{ + return d_data->markerSize; +} + +/*! + \return sizeHint() +*/ +QSize QwtKnob::sizeHint() const +{ + const QSize hint = qwtKnobSizeHint( this, 50 ); + return hint.expandedTo( QApplication::globalStrut() ); +} + +/*! + \return Minimum size hint + \sa sizeHint() +*/ +QSize QwtKnob::minimumSizeHint() const +{ + return qwtKnobSizeHint( this, 20 ); +} diff --git a/ThirdParty/Qwt/src/qwt_knob.h b/ThirdParty/Qwt/src/qwt_knob.h new file mode 100644 index 0000000000..852374c02b --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_knob.h @@ -0,0 +1,178 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#ifndef QWT_KNOB_H +#define QWT_KNOB_H + +#include "qwt_global.h" +#include "qwt_abstract_slider.h" + +class QwtRoundScaleDraw; + +/*! + \brief The Knob Widget + + The QwtKnob widget imitates look and behavior of a volume knob on a radio. + It looks similar to QDial - not to QwtDial. + + The value range of a knob might be divided into several turns. + + The layout of the knob depends on the knobWidth(). + + - width > 0 + The diameter of the knob is fixed and the knob is aligned + according to the alignment() flags inside of the contentsRect(). + + - width <= 0 + The knob is extended to the minimum of width/height of the contentsRect() + and aligned in the other direction according to alignment(). + + Setting a fixed knobWidth() is helpful to align several knobs with different + scale labels. + + \image html knob.png +*/ + +class QWT_EXPORT QwtKnob: public QwtAbstractSlider +{ + Q_OBJECT + + Q_ENUMS ( KnobStyle MarkerStyle ) + + Q_PROPERTY( KnobStyle knobStyle READ knobStyle WRITE setKnobStyle ) + Q_PROPERTY( int knobWidth READ knobWidth WRITE setKnobWidth ) + Q_PROPERTY( Qt::Alignment alignment READ alignment WRITE setAlignment ) + Q_PROPERTY( double totalAngle READ totalAngle WRITE setTotalAngle ) + Q_PROPERTY( int numTurns READ numTurns WRITE setNumTurns ) + Q_PROPERTY( MarkerStyle markerStyle READ markerStyle WRITE setMarkerStyle ) + Q_PROPERTY( int markerSize READ markerSize WRITE setMarkerSize ) + Q_PROPERTY( int borderWidth READ borderWidth WRITE setBorderWidth ) + +public: + /*! + \brief Style of the knob surface + + Depending on the KnobStyle the surface of the knob is + filled from the brushes of the widget palette(). + + \sa setKnobStyle(), knobStyle() + */ + enum KnobStyle + { + //! Fill the knob with a brush from QPalette::Button. + Flat, + + //! Build a gradient from QPalette::Midlight and QPalette::Button + Raised, + + /*! + Build a gradient from QPalette::Midlight, QPalette::Button + and QPalette::Midlight + */ + Sunken, + + /*! + Build a radial gradient from QPalette::Button + like it is used for QDial in various Qt styles. + */ + Styled + }; + + /*! + \brief Marker type + + The marker indicates the current value on the knob + The default setting is a Notch marker. + + \sa setMarkerStyle(), setMarkerSize() + */ + enum MarkerStyle + { + //! Don't paint any marker + NoMarker = -1, + + //! Paint a single tick in QPalette::ButtonText color + Tick, + + //! Paint a triangle in QPalette::ButtonText color + Triangle, + + //! Paint a circle in QPalette::ButtonText color + Dot, + + /*! + Draw a raised ellipse with a gradient build from + QPalette::Light and QPalette::Mid + */ + Nub, + + /*! + Draw a sunken ellipse with a gradient build from + QPalette::Light and QPalette::Mid + */ + Notch + }; + + explicit QwtKnob( QWidget* parent = NULL ); + virtual ~QwtKnob(); + + void setAlignment( Qt::Alignment ); + Qt::Alignment alignment() const; + + void setKnobWidth( int ); + int knobWidth() const; + + void setNumTurns( int ); + int numTurns() const; + + void setTotalAngle ( double angle ); + double totalAngle() const; + + void setKnobStyle( KnobStyle ); + KnobStyle knobStyle() const; + + void setBorderWidth( int bw ); + int borderWidth() const; + + void setMarkerStyle( MarkerStyle ); + MarkerStyle markerStyle() const; + + void setMarkerSize( int ); + int markerSize() const; + + virtual QSize sizeHint() const; + virtual QSize minimumSizeHint() const; + + void setScaleDraw( QwtRoundScaleDraw * ); + + const QwtRoundScaleDraw *scaleDraw() const; + QwtRoundScaleDraw *scaleDraw(); + + QRect knobRect() const; + +protected: + virtual void paintEvent( QPaintEvent * ); + virtual void changeEvent( QEvent * ); + + virtual void drawKnob( QPainter *, const QRectF & ) const; + + virtual void drawFocusIndicator( QPainter * ) const; + + virtual void drawMarker( QPainter *, + const QRectF &, double arc ) const; + + virtual double scrolledTo( const QPoint & ) const; + virtual bool isScrollPosition( const QPoint & ) const; + +private: + class PrivateData; + PrivateData *d_data; +}; + +#endif diff --git a/ThirdParty/Qwt/src/qwt_legend.cpp b/ThirdParty/Qwt/src/qwt_legend.cpp new file mode 100644 index 0000000000..01cef89f15 --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_legend.cpp @@ -0,0 +1,801 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#include "qwt_legend.h" +#include "qwt_legend_label.h" +#include "qwt_dyngrid_layout.h" +#include "qwt_math.h" +#include "qwt_plot_item.h" +#include "qwt_painter.h" +#include +#include +#include +#include +#include +#include + +class QwtLegendMap +{ +public: + inline bool isEmpty() const { return d_entries.isEmpty(); } + + void insert( const QVariant &, const QList & ); + void remove( const QVariant & ); + + void removeWidget( const QWidget * ); + + QList legendWidgets( const QVariant & ) const; + QVariant itemInfo( const QWidget * ) const; + +private: + // we don't know anything about itemInfo and therefore don't have + // any key that can be used for a map or hashtab. + // But a simple linear list is o.k. here, as we will never have + // more than a few entries. + + class Entry + { + public: + QVariant itemInfo; + QList widgets; + }; + + QList< Entry > d_entries; +}; + +void QwtLegendMap::insert( const QVariant &itemInfo, + const QList &widgets ) +{ + for ( int i = 0; i < d_entries.size(); i++ ) + { + Entry &entry = d_entries[i]; + if ( entry.itemInfo == itemInfo ) + { + entry.widgets = widgets; + return; + } + } + + Entry newEntry; + newEntry.itemInfo = itemInfo; + newEntry.widgets = widgets; + + d_entries += newEntry; +} + +void QwtLegendMap::remove( const QVariant &itemInfo ) +{ + for ( int i = 0; i < d_entries.size(); i++ ) + { + Entry &entry = d_entries[i]; + if ( entry.itemInfo == itemInfo ) + { + d_entries.removeAt( i ); + return; + } + } +} + +void QwtLegendMap::removeWidget( const QWidget *widget ) +{ + QWidget *w = const_cast( widget ); + + for ( int i = 0; i < d_entries.size(); i++ ) + d_entries[ i ].widgets.removeAll( w ); +} + +QVariant QwtLegendMap::itemInfo( const QWidget *widget ) const +{ + if ( widget != NULL ) + { + QWidget *w = const_cast( widget ); + + for ( int i = 0; i < d_entries.size(); i++ ) + { + const Entry &entry = d_entries[i]; + if ( entry.widgets.indexOf( w ) >= 0 ) + return entry.itemInfo; + } + } + + return QVariant(); +} + +QList QwtLegendMap::legendWidgets( const QVariant &itemInfo ) const +{ + if ( itemInfo.isValid() ) + { + for ( int i = 0; i < d_entries.size(); i++ ) + { + const Entry &entry = d_entries[i]; + if ( entry.itemInfo == itemInfo ) + return entry.widgets; + } + } + + return QList(); +} + +class QwtLegend::PrivateData +{ +public: + PrivateData(): + itemMode( QwtLegendData::ReadOnly ), + view( NULL ) + { + } + + QwtLegendData::Mode itemMode; + QwtLegendMap itemMap; + + class LegendView; + LegendView *view; +}; + +class QwtLegend::PrivateData::LegendView: public QScrollArea +{ +public: + LegendView( QWidget *parent ): + QScrollArea( parent ) + { + contentsWidget = new QWidget( this ); + contentsWidget->setObjectName( "QwtLegendViewContents" ); + + setWidget( contentsWidget ); + setWidgetResizable( false ); + + viewport()->setObjectName( "QwtLegendViewport" ); + + // QScrollArea::setWidget internally sets autoFillBackground to true + // But we don't want a background. + contentsWidget->setAutoFillBackground( false ); + viewport()->setAutoFillBackground( false ); + } + + virtual bool event( QEvent *event ) + { + if ( event->type() == QEvent::PolishRequest ) + { + setFocusPolicy( Qt::NoFocus ); + } + + if ( event->type() == QEvent::Resize ) + { + // adjust the size to en/disable the scrollbars + // before QScrollArea adjusts the viewport size + + const QRect cr = contentsRect(); + + int w = cr.width(); + int h = contentsWidget->heightForWidth( cr.width() ); + if ( h > w ) + { + w -= verticalScrollBar()->sizeHint().width(); + h = contentsWidget->heightForWidth( w ); + } + + contentsWidget->resize( w, h ); + } + + return QScrollArea::event( event ); + } + + virtual bool viewportEvent( QEvent *event ) + { + bool ok = QScrollArea::viewportEvent( event ); + + if ( event->type() == QEvent::Resize ) + { + layoutContents(); + } + return ok; + } + + QSize viewportSize( int w, int h ) const + { + const int sbHeight = horizontalScrollBar()->sizeHint().height(); + const int sbWidth = verticalScrollBar()->sizeHint().width(); + + const int cw = contentsRect().width(); + const int ch = contentsRect().height(); + + int vw = cw; + int vh = ch; + + if ( w > vw ) + vh -= sbHeight; + + if ( h > vh ) + { + vw -= sbWidth; + if ( w > vw && vh == ch ) + vh -= sbHeight; + } + return QSize( vw, vh ); + } + + void layoutContents() + { + const QwtDynGridLayout *tl = qobject_cast( + contentsWidget->layout() ); + if ( tl == NULL ) + return; + + const QSize visibleSize = viewport()->contentsRect().size(); + + const int minW = int( tl->maxItemWidth() ) + 2 * tl->margin(); + + int w = qMax( visibleSize.width(), minW ); + int h = qMax( tl->heightForWidth( w ), visibleSize.height() ); + + const int vpWidth = viewportSize( w, h ).width(); + if ( w > vpWidth ) + { + w = qMax( vpWidth, minW ); + h = qMax( tl->heightForWidth( w ), visibleSize.height() ); + } + + contentsWidget->resize( w, h ); + } + + QWidget *contentsWidget; +}; + +/*! + Constructor + \param parent Parent widget +*/ +QwtLegend::QwtLegend( QWidget *parent ): + QwtAbstractLegend( parent ) +{ + setFrameStyle( NoFrame ); + + d_data = new QwtLegend::PrivateData; + + d_data->view = new QwtLegend::PrivateData::LegendView( this ); + d_data->view->setObjectName( "QwtLegendView" ); + d_data->view->setFrameStyle( NoFrame ); + + QwtDynGridLayout *gridLayout = new QwtDynGridLayout( + d_data->view->contentsWidget ); + gridLayout->setAlignment( Qt::AlignHCenter | Qt::AlignTop ); + + d_data->view->contentsWidget->installEventFilter( this ); + + QVBoxLayout *layout = new QVBoxLayout( this ); + layout->setContentsMargins( 0, 0, 0, 0 ); + layout->addWidget( d_data->view ); +} + +//! Destructor +QwtLegend::~QwtLegend() +{ + delete d_data; +} + +/*! + \brief Set the maximum number of entries in a row + + F.e when the maximum is set to 1 all items are aligned + vertically. 0 means unlimited + + \param numColums Maximum number of entries in a row + + \sa maxColumns(), QwtDynGridLayout::setMaxColumns() + */ +void QwtLegend::setMaxColumns( uint numColums ) +{ + QwtDynGridLayout *tl = qobject_cast( + d_data->view->contentsWidget->layout() ); + if ( tl ) + tl->setMaxColumns( numColums ); +} + +/*! + \return Maximum number of entries in a row + \sa setMaxColumns(), QwtDynGridLayout::maxColumns() + */ +uint QwtLegend::maxColumns() const +{ + uint maxCols = 0; + + const QwtDynGridLayout *tl = qobject_cast( + d_data->view->contentsWidget->layout() ); + if ( tl ) + maxCols = tl->maxColumns(); + + return maxCols; +} + +/*! + \brief Set the default mode for legend labels + + Legend labels will be constructed according to the + attributes in a QwtLegendData object. When it doesn't + contain a value for the QwtLegendData::ModeRole the + label will be initialized with the default mode of the legend. + + \param mode Default item mode + + \sa itemMode(), QwtLegendData::value(), QwtPlotItem::legendData() + \note Changing the mode doesn't have any effect on existing labels. + */ +void QwtLegend::setDefaultItemMode( QwtLegendData::Mode mode ) +{ + d_data->itemMode = mode; +} + +/*! + \return Default item mode + \sa setDefaultItemMode() +*/ +QwtLegendData::Mode QwtLegend::defaultItemMode() const +{ + return d_data->itemMode; +} + +/*! + The contents widget is the only child of the viewport of + the internal QScrollArea and the parent widget of all legend items. + + \return Container widget of the legend items +*/ +QWidget *QwtLegend::contentsWidget() +{ + return d_data->view->contentsWidget; +} + +/*! + \return Horizontal scrollbar + \sa verticalScrollBar() +*/ +QScrollBar *QwtLegend::horizontalScrollBar() const +{ + return d_data->view->horizontalScrollBar(); +} + +/*! + \return Vertical scrollbar + \sa horizontalScrollBar() +*/ +QScrollBar *QwtLegend::verticalScrollBar() const +{ + return d_data->view->verticalScrollBar(); +} + +/*! + The contents widget is the only child of the viewport of + the internal QScrollArea and the parent widget of all legend items. + + \return Container widget of the legend items + +*/ +const QWidget *QwtLegend::contentsWidget() const +{ + return d_data->view->contentsWidget; +} + +/*! + \brief Update the entries for an item + + \param itemInfo Info for an item + \param data List of legend entry attributes for the item + */ +void QwtLegend::updateLegend( const QVariant &itemInfo, + const QList &data ) +{ + QList widgetList = legendWidgets( itemInfo ); + + if ( widgetList.size() != data.size() ) + { + QLayout *contentsLayout = d_data->view->contentsWidget->layout(); + + while ( widgetList.size() > data.size() ) + { + QWidget *w = widgetList.takeLast(); + + contentsLayout->removeWidget( w ); + + // updates might be triggered by signals from the legend widget + // itself. So we better don't delete it here. + + w->hide(); + w->deleteLater(); + } + + for ( int i = widgetList.size(); i < data.size(); i++ ) + { + QWidget *widget = createWidget( data[i] ); + + if ( contentsLayout ) + contentsLayout->addWidget( widget ); + + widgetList += widget; + } + + if ( widgetList.isEmpty() ) + { + d_data->itemMap.remove( itemInfo ); + } + else + { + d_data->itemMap.insert( itemInfo, widgetList ); + } + + updateTabOrder(); + } + + for ( int i = 0; i < data.size(); i++ ) + updateWidget( widgetList[i], data[i] ); +} + +/*! + \brief Create a widget to be inserted into the legend + + The default implementation returns a QwtLegendLabel. + + \param data Attributes of the legend entry + \return Widget representing data on the legend + + \note updateWidget() will called soon after createWidget() + with the same attributes. + */ +QWidget *QwtLegend::createWidget( const QwtLegendData &data ) const +{ + Q_UNUSED( data ); + + QwtLegendLabel *label = new QwtLegendLabel(); + label->setItemMode( defaultItemMode() ); + + connect( label, SIGNAL( clicked() ), SLOT( itemClicked() ) ); + connect( label, SIGNAL( checked( bool ) ), SLOT( itemChecked( bool ) ) ); + + return label; +} + +/*! + \brief Update the widget + + \param widget Usually a QwtLegendLabel + \param data Attributes to be displayed + + \sa createWidget() + \note When widget is no QwtLegendLabel updateWidget() does nothing. + */ +void QwtLegend::updateWidget( QWidget *widget, const QwtLegendData &data ) +{ + QwtLegendLabel *label = qobject_cast( widget ); + if ( label ) + { + label->setData( data ); + if ( !data.value( QwtLegendData::ModeRole ).isValid() ) + { + // use the default mode, when there is no specific + // hint from the legend data + + label->setItemMode( defaultItemMode() ); + } + } +} + +void QwtLegend::updateTabOrder() +{ + QLayout *contentsLayout = d_data->view->contentsWidget->layout(); + if ( contentsLayout ) + { + // set tab focus chain + + QWidget *w = NULL; + + for ( int i = 0; i < contentsLayout->count(); i++ ) + { + QLayoutItem *item = contentsLayout->itemAt( i ); + if ( w && item->widget() ) + QWidget::setTabOrder( w, item->widget() ); + + w = item->widget(); + } + } +} + +//! Return a size hint. +QSize QwtLegend::sizeHint() const +{ + QSize hint = d_data->view->contentsWidget->sizeHint(); + hint += QSize( 2 * frameWidth(), 2 * frameWidth() ); + + return hint; +} + +/*! + \return The preferred height, for a width. + \param width Width +*/ +int QwtLegend::heightForWidth( int width ) const +{ + width -= 2 * frameWidth(); + + int h = d_data->view->contentsWidget->heightForWidth( width ); + if ( h >= 0 ) + h += 2 * frameWidth(); + + return h; +} + + +/*! + Handle QEvent::ChildRemoved andQEvent::LayoutRequest events + for the contentsWidget(). + + \param object Object to be filtered + \param event Event + + \return Forwarded to QwtAbstractLegend::eventFilter() +*/ +bool QwtLegend::eventFilter( QObject *object, QEvent *event ) +{ + if ( object == d_data->view->contentsWidget ) + { + switch ( event->type() ) + { + case QEvent::ChildRemoved: + { + const QChildEvent *ce = + static_cast(event); + if ( ce->child()->isWidgetType() ) + { + QWidget *w = static_cast< QWidget * >( ce->child() ); + d_data->itemMap.removeWidget( w ); + } + break; + } + case QEvent::LayoutRequest: + { + d_data->view->layoutContents(); + + if ( parentWidget() && parentWidget()->layout() == NULL ) + { + /* + We want the parent widget ( usually QwtPlot ) to recalculate + its layout, when the contentsWidget has changed. But + because of the scroll view we have to forward the LayoutRequest + event manually. + + We don't use updateGeometry() because it doesn't post LayoutRequest + events when the legend is hidden. But we want the + parent widget notified, so it can show/hide the legend + depending on its items. + */ + QApplication::postEvent( parentWidget(), + new QEvent( QEvent::LayoutRequest ) ); + } + break; + } + default: + break; + } + } + + return QwtAbstractLegend::eventFilter( object, event ); +} + +/*! + Called internally when the legend has been clicked on. + Emits a clicked() signal. +*/ +void QwtLegend::itemClicked() +{ + QWidget *w = qobject_cast( sender() ); + if ( w ) + { + const QVariant itemInfo = d_data->itemMap.itemInfo( w ); + if ( itemInfo.isValid() ) + { + const QList widgetList = + d_data->itemMap.legendWidgets( itemInfo ); + + const int index = widgetList.indexOf( w ); + if ( index >= 0 ) + Q_EMIT clicked( itemInfo, index ); + } + } +} + +/*! + Called internally when the legend has been checked + Emits a checked() signal. +*/ +void QwtLegend::itemChecked( bool on ) +{ + QWidget *w = qobject_cast( sender() ); + if ( w ) + { + const QVariant itemInfo = d_data->itemMap.itemInfo( w ); + if ( itemInfo.isValid() ) + { + const QList widgetList = + d_data->itemMap.legendWidgets( itemInfo ); + + const int index = widgetList.indexOf( w ); + if ( index >= 0 ) + Q_EMIT checked( itemInfo, on, index ); + } + } +} + +/*! + Render the legend into a given rectangle. + + \param painter Painter + \param rect Bounding rectangle + \param fillBackground When true, fill rect with the widget background + + \sa renderLegend() is used by QwtPlotRenderer - not by QwtLegend itself +*/ +void QwtLegend::renderLegend( QPainter *painter, + const QRectF &rect, bool fillBackground ) const +{ + if ( d_data->itemMap.isEmpty() ) + return; + + if ( fillBackground ) + { + if ( autoFillBackground() || + testAttribute( Qt::WA_StyledBackground ) ) + { + QwtPainter::drawBackgound( painter, rect, this ); + } + } + + const QwtDynGridLayout *legendLayout = + qobject_cast( contentsWidget()->layout() ); + if ( legendLayout == NULL ) + return; + + int left, right, top, bottom; + getContentsMargins( &left, &top, &right, &bottom ); + + QRect layoutRect; + layoutRect.setLeft( qCeil( rect.left() ) + left ); + layoutRect.setTop( qCeil( rect.top() ) + top ); + layoutRect.setRight( qFloor( rect.right() ) - right ); + layoutRect.setBottom( qFloor( rect.bottom() ) - bottom ); + + uint numCols = legendLayout->columnsForWidth( layoutRect.width() ); + QList itemRects = + legendLayout->layoutItems( layoutRect, numCols ); + + int index = 0; + + for ( int i = 0; i < legendLayout->count(); i++ ) + { + QLayoutItem *item = legendLayout->itemAt( i ); + QWidget *w = item->widget(); + if ( w ) + { + painter->save(); + + painter->setClipRect( itemRects[index] ); + renderItem( painter, w, itemRects[index], fillBackground ); + + index++; + painter->restore(); + } + } +} + +/*! + Render a legend entry into a given rectangle. + + \param painter Painter + \param widget Widget representing a legend entry + \param rect Bounding rectangle + \param fillBackground When true, fill rect with the widget background + + \note When widget is not derived from QwtLegendLabel renderItem + does nothing beside the background +*/ +void QwtLegend::renderItem( QPainter *painter, + const QWidget *widget, const QRectF &rect, bool fillBackground ) const +{ + if ( fillBackground ) + { + if ( widget->autoFillBackground() || + widget->testAttribute( Qt::WA_StyledBackground ) ) + { + QwtPainter::drawBackgound( painter, rect, widget ); + } + } + + const QwtLegendLabel *label = qobject_cast( widget ); + if ( label ) + { + // icon + + const QwtGraphic &icon = label->data().icon(); + const QSizeF sz = icon.defaultSize(); + + const QRectF iconRect( rect.x() + label->margin(), + rect.center().y() - 0.5 * sz.height(), + sz.width(), sz.height() ); + + icon.render( painter, iconRect, Qt::KeepAspectRatio ); + + // title + + QRectF titleRect = rect; + titleRect.setX( iconRect.right() + 2 * label->spacing() ); + + painter->setFont( label->font() ); + painter->setPen( label->palette().color( QPalette::Text ) ); + const_cast< QwtLegendLabel *>( label )->drawText( painter, titleRect ); + } +} + +/*! + \return List of widgets associated to a item + \param itemInfo Info about an item + \sa legendWidget(), itemInfo(), QwtPlot::itemToInfo() + */ +QList QwtLegend::legendWidgets( const QVariant &itemInfo ) const +{ + return d_data->itemMap.legendWidgets( itemInfo ); +} + +/*! + \return First widget in the list of widgets associated to an item + \param itemInfo Info about an item + \sa itemInfo(), QwtPlot::itemToInfo() + \note Almost all types of items have only one widget +*/ +QWidget *QwtLegend::legendWidget( const QVariant &itemInfo ) const +{ + const QList list = d_data->itemMap.legendWidgets( itemInfo ); + if ( list.isEmpty() ) + return NULL; + + return list[0]; +} + +/*! + Find the item that is associated to a widget + + \param widget Widget on the legend + \return Associated item info + \sa legendWidget() + */ +QVariant QwtLegend::itemInfo( const QWidget *widget ) const +{ + return d_data->itemMap.itemInfo( widget ); +} + +//! \return True, when no item is inserted +bool QwtLegend::isEmpty() const +{ + return d_data->itemMap.isEmpty(); +} + +/*! + Return the extent, that is needed for the scrollbars + + \param orientation Orientation ( + \return The width of the vertical scrollbar for Qt::Horizontal and v.v. + */ +int QwtLegend::scrollExtent( Qt::Orientation orientation ) const +{ + int extent = 0; + + if ( orientation == Qt::Horizontal ) + extent = verticalScrollBar()->sizeHint().width(); + else + extent = horizontalScrollBar()->sizeHint().height(); + + return extent; +} + diff --git a/ThirdParty/Qwt/src/qwt_legend.h b/ThirdParty/Qwt/src/qwt_legend.h new file mode 100644 index 0000000000..3d8fca67a3 --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_legend.h @@ -0,0 +1,117 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#ifndef QWT_LEGEND_H +#define QWT_LEGEND_H + +#include "qwt_global.h" +#include "qwt_abstract_legend.h" +#include + +class QScrollBar; + +/*! + \brief The legend widget + + The QwtLegend widget is a tabular arrangement of legend items. Legend + items might be any type of widget, but in general they will be + a QwtLegendLabel. + + \sa QwtLegendLabel, QwtPlotItem, QwtPlot +*/ + +class QWT_EXPORT QwtLegend : public QwtAbstractLegend +{ + Q_OBJECT + +public: + explicit QwtLegend( QWidget *parent = NULL ); + virtual ~QwtLegend(); + + void setMaxColumns( uint numColums ); + uint maxColumns() const; + + void setDefaultItemMode( QwtLegendData::Mode ); + QwtLegendData::Mode defaultItemMode() const; + + QWidget *contentsWidget(); + const QWidget *contentsWidget() const; + + QWidget *legendWidget( const QVariant & ) const; + QList legendWidgets( const QVariant & ) const; + + QVariant itemInfo( const QWidget * ) const; + + virtual bool eventFilter( QObject *, QEvent * ); + + virtual QSize sizeHint() const; + virtual int heightForWidth( int w ) const; + + QScrollBar *horizontalScrollBar() const; + QScrollBar *verticalScrollBar() const; + + virtual void renderLegend( QPainter *, + const QRectF &, bool fillBackground ) const; + + virtual void renderItem( QPainter *, + const QWidget *, const QRectF &, bool fillBackground ) const; + + virtual bool isEmpty() const; + virtual int scrollExtent( Qt::Orientation ) const; + +Q_SIGNALS: + /*! + A signal which is emitted when the user has clicked on + a legend label, which is in QwtLegendData::Clickable mode. + + \param itemInfo Info for the item item of the + selected legend item + \param index Index of the legend label in the list of widgets + that are associated with the plot item + + \note clicks are disabled as default + \sa setDefaultItemMode(), defaultItemMode(), QwtPlot::itemToInfo() + */ + void clicked( const QVariant &itemInfo, int index ); + + /*! + A signal which is emitted when the user has clicked on + a legend label, which is in QwtLegendData::Checkable mode + + \param itemInfo Info for the item of the + selected legend label + \param index Index of the legend label in the list of widgets + that are associated with the plot item + \param on True when the legend label is checked + + \note clicks are disabled as default + \sa setDefaultItemMode(), defaultItemMode(), QwtPlot::itemToInfo() + */ + void checked( const QVariant &itemInfo, bool on, int index ); + +public Q_SLOTS: + virtual void updateLegend( const QVariant &, + const QList & ); + +protected Q_SLOTS: + void itemClicked(); + void itemChecked( bool ); + +protected: + virtual QWidget *createWidget( const QwtLegendData & ) const; + virtual void updateWidget( QWidget *widget, const QwtLegendData &data ); + +private: + void updateTabOrder(); + + class PrivateData; + PrivateData *d_data; +}; + +#endif diff --git a/ThirdParty/Qwt/src/qwt_legend_data.cpp b/ThirdParty/Qwt/src/qwt_legend_data.cpp new file mode 100644 index 0000000000..cf0cb2ce36 --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_legend_data.cpp @@ -0,0 +1,129 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#include "qwt_legend_data.h" + +//! Constructor +QwtLegendData::QwtLegendData() +{ +} + +//! Destructor +QwtLegendData::~QwtLegendData() +{ +} + +/*! + Set the legend attributes + + QwtLegendData actually is a QMap with some + convenience interfaces + + \param map Values + \sa values() + */ +void QwtLegendData::setValues( const QMap &map ) +{ + d_map = map; +} + +/*! + \return Legend attributes + \sa setValues() + */ +const QMap &QwtLegendData::values() const +{ + return d_map; +} + +/*! + \param role Attribute role + \return True, when the internal map has an entry for role + */ +bool QwtLegendData::hasRole( int role ) const +{ + return d_map.contains( role ); +} + +/*! + Set an attribute value + + \param role Attribute role + \param data Attribute value + + \sa value() + */ +void QwtLegendData::setValue( int role, const QVariant &data ) +{ + d_map[role] = data; +} + +/*! + \param role Attribute role + \return Attribute value for a specific role + */ +QVariant QwtLegendData::value( int role ) const +{ + if ( !d_map.contains( role ) ) + return QVariant(); + + return d_map[role]; +} + +//! \return True, when the internal map is empty +bool QwtLegendData::isValid() const +{ + return !d_map.isEmpty(); +} + +//! \return Value of the TitleRole attribute +QwtText QwtLegendData::title() const +{ + QwtText text; + + const QVariant titleValue = value( QwtLegendData::TitleRole ); + if ( titleValue.canConvert() ) + { + text = qvariant_cast( titleValue ); + } + else if ( titleValue.canConvert() ) + { + text.setText( qvariant_cast( titleValue ) ); + } + + return text; +} + +//! \return Value of the IconRole attribute +QwtGraphic QwtLegendData::icon() const +{ + const QVariant iconValue = value( QwtLegendData::IconRole ); + + QwtGraphic graphic; + if ( iconValue.canConvert() ) + { + graphic = qvariant_cast( iconValue ); + } + + return graphic; +} + +//! \return Value of the ModeRole attribute +QwtLegendData::Mode QwtLegendData::mode() const +{ + const QVariant modeValue = value( QwtLegendData::ModeRole ); + if ( modeValue.canConvert() ) + { + const int mode = qvariant_cast( modeValue ); + return static_cast( mode ); + } + + return QwtLegendData::ReadOnly; +} + diff --git a/ThirdParty/Qwt/src/qwt_legend_data.h b/ThirdParty/Qwt/src/qwt_legend_data.h new file mode 100644 index 0000000000..d83e13264f --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_legend_data.h @@ -0,0 +1,87 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#ifndef QWT_LEGEND_DATA_H +#define QWT_LEGEND_DATA_H + +#include "qwt_global.h" +#include "qwt_text.h" +#include "qwt_graphic.h" +#include +#include +#include + +/*! + \brief Attributes of an entry on a legend + + QwtLegendData is an abstract container ( like QAbstractModel ) + to exchange attributes, that are only known between to + the plot item and the legend. + + By overloading QwtPlotItem::legendData() any other set of attributes + could be used, that can be handled by a modified ( or completely + different ) implementation of a legend. + + \sa QwtLegend, QwtPlotLegendItem + \note The stockchart example implements a legend as a tree + with checkable items + */ +class QWT_EXPORT QwtLegendData +{ +public: + //! Mode defining how a legend entry interacts + enum Mode + { + //! The legend item is not interactive, like a label + ReadOnly, + + //! The legend item is clickable, like a push button + Clickable, + + //! The legend item is checkable, like a checkable button + Checkable + }; + + //! Identifier how to interprete a QVariant + enum Role + { + // The value is a Mode + ModeRole, + + // The value is a title + TitleRole, + + // The value is an icon + IconRole, + + // Values < UserRole are reserved for internal use + UserRole = 32 + }; + + QwtLegendData(); + ~QwtLegendData(); + + void setValues( const QMap & ); + const QMap &values() const; + + void setValue( int role, const QVariant & ); + QVariant value( int role ) const; + + bool hasRole( int role ) const; + bool isValid() const; + + QwtGraphic icon() const; + QwtText title() const; + Mode mode() const; + +private: + QMap d_map; +}; + +#endif diff --git a/ThirdParty/Qwt/src/qwt_legend_label.cpp b/ThirdParty/Qwt/src/qwt_legend_label.cpp new file mode 100644 index 0000000000..19a7eb9578 --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_legend_label.cpp @@ -0,0 +1,421 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#include "qwt_legend_label.h" +#include "qwt_legend_data.h" +#include "qwt_math.h" +#include "qwt_painter.h" +#include "qwt_symbol.h" +#include "qwt_graphic.h" +#include +#include +#include +#include +#include +#include +#include + +static const int ButtonFrame = 2; +static const int Margin = 2; + +static QSize buttonShift( const QwtLegendLabel *w ) +{ + QStyleOption option; + option.init( w ); + + const int ph = w->style()->pixelMetric( + QStyle::PM_ButtonShiftHorizontal, &option, w ); + const int pv = w->style()->pixelMetric( + QStyle::PM_ButtonShiftVertical, &option, w ); + return QSize( ph, pv ); +} + +class QwtLegendLabel::PrivateData +{ +public: + PrivateData(): + itemMode( QwtLegendData::ReadOnly ), + isDown( false ), + spacing( Margin ) + { + } + + QwtLegendData::Mode itemMode; + QwtLegendData legendData; + bool isDown; + + QPixmap icon; + + int spacing; +}; + +/*! + Set the attributes of the legend label + + \param legendData Attributes of the label + \sa data() + */ +void QwtLegendLabel::setData( const QwtLegendData &legendData ) +{ + d_data->legendData = legendData; + + const bool doUpdate = updatesEnabled(); + setUpdatesEnabled( false ); + + setText( legendData.title() ); + setIcon( legendData.icon().toPixmap() ); + + if ( legendData.hasRole( QwtLegendData::ModeRole ) ) + setItemMode( legendData.mode() ); + + if ( doUpdate ) + { + setUpdatesEnabled( true ); + update(); + } +} + +/*! + \return Attributes of the label + \sa setData(), QwtPlotItem::legendData() + */ +const QwtLegendData &QwtLegendLabel::data() const +{ + return d_data->legendData; +} + +/*! + \param parent Parent widget +*/ +QwtLegendLabel::QwtLegendLabel( QWidget *parent ): + QwtTextLabel( parent ) +{ + d_data = new PrivateData; + setMargin( Margin ); + setIndent( Margin ); +} + +//! Destructor +QwtLegendLabel::~QwtLegendLabel() +{ + delete d_data; + d_data = NULL; +} + +/*! + Set the text to the legend item + + \param text Text label + \sa QwtTextLabel::text() +*/ +void QwtLegendLabel::setText( const QwtText &text ) +{ + const int flags = Qt::AlignLeft | Qt::AlignVCenter + | Qt::TextExpandTabs | Qt::TextWordWrap; + + QwtText txt = text; + txt.setRenderFlags( flags ); + + QwtTextLabel::setText( txt ); +} + +/*! + Set the item mode + The default is QwtLegendData::ReadOnly + + \param mode Item mode + \sa itemMode() +*/ +void QwtLegendLabel::setItemMode( QwtLegendData::Mode mode ) +{ + if ( mode != d_data->itemMode ) + { + d_data->itemMode = mode; + d_data->isDown = false; + + setFocusPolicy( ( mode != QwtLegendData::ReadOnly ) + ? Qt::TabFocus : Qt::NoFocus ); + setMargin( ButtonFrame + Margin ); + + updateGeometry(); + } +} + +/*! + \return Item mode + \sa setItemMode() +*/ +QwtLegendData::Mode QwtLegendLabel::itemMode() const +{ + return d_data->itemMode; +} + +/*! + Assign the icon + + \param icon Pixmap representing a plot item + + \sa icon(), QwtPlotItem::legendIcon() +*/ +void QwtLegendLabel::setIcon( const QPixmap &icon ) +{ + d_data->icon = icon; + + int indent = margin() + d_data->spacing; + if ( icon.width() > 0 ) + indent += icon.width() + d_data->spacing; + + setIndent( indent ); +} + +/*! + \return Pixmap representing a plot item + \sa setIcon() +*/ +QPixmap QwtLegendLabel::icon() const +{ + return d_data->icon; +} + +/*! + \brief Change the spacing between icon and text + + \param spacing Spacing + \sa spacing(), QwtTextLabel::margin() +*/ +void QwtLegendLabel::setSpacing( int spacing ) +{ + spacing = qMax( spacing, 0 ); + if ( spacing != d_data->spacing ) + { + d_data->spacing = spacing; + + int indent = margin() + d_data->spacing; + if ( d_data->icon.width() > 0 ) + indent += d_data->icon.width() + d_data->spacing; + + setIndent( indent ); + } +} + +/*! + \return Spacing between icon and text + \sa setSpacing(), QwtTextLabel::margin() +*/ +int QwtLegendLabel::spacing() const +{ + return d_data->spacing; +} + +/*! + Check/Uncheck a the item + + \param on check/uncheck + \sa setItemMode() +*/ +void QwtLegendLabel::setChecked( bool on ) +{ + if ( d_data->itemMode == QwtLegendData::Checkable ) + { + const bool isBlocked = signalsBlocked(); + blockSignals( true ); + + setDown( on ); + + blockSignals( isBlocked ); + } +} + +//! Return true, if the item is checked +bool QwtLegendLabel::isChecked() const +{ + return d_data->itemMode == QwtLegendData::Checkable && isDown(); +} + +//! Set the item being down +void QwtLegendLabel::setDown( bool down ) +{ + if ( down == d_data->isDown ) + return; + + d_data->isDown = down; + update(); + + if ( d_data->itemMode == QwtLegendData::Clickable ) + { + if ( d_data->isDown ) + Q_EMIT pressed(); + else + { + Q_EMIT released(); + Q_EMIT clicked(); + } + } + + if ( d_data->itemMode == QwtLegendData::Checkable ) + Q_EMIT checked( d_data->isDown ); +} + +//! Return true, if the item is down +bool QwtLegendLabel::isDown() const +{ + return d_data->isDown; +} + +//! Return a size hint +QSize QwtLegendLabel::sizeHint() const +{ + QSize sz = QwtTextLabel::sizeHint(); + sz.setHeight( qMax( sz.height(), d_data->icon.height() + 4 ) ); + + if ( d_data->itemMode != QwtLegendData::ReadOnly ) + { + sz += buttonShift( this ); + sz = sz.expandedTo( QApplication::globalStrut() ); + } + + return sz; +} + +//! Paint event +void QwtLegendLabel::paintEvent( QPaintEvent *e ) +{ + const QRect cr = contentsRect(); + + QPainter painter( this ); + painter.setClipRegion( e->region() ); + + if ( d_data->isDown ) + { + qDrawWinButton( &painter, 0, 0, width(), height(), + palette(), true ); + } + + painter.save(); + + if ( d_data->isDown ) + { + const QSize shiftSize = buttonShift( this ); + painter.translate( shiftSize.width(), shiftSize.height() ); + } + + painter.setClipRect( cr ); + + drawContents( &painter ); + + if ( !d_data->icon.isNull() ) + { + QRect iconRect = cr; + iconRect.setX( iconRect.x() + margin() ); + if ( d_data->itemMode != QwtLegendData::ReadOnly ) + iconRect.setX( iconRect.x() + ButtonFrame ); + + iconRect.setSize( d_data->icon.size() ); + iconRect.moveCenter( QPoint( iconRect.center().x(), cr.center().y() ) ); + + painter.drawPixmap( iconRect, d_data->icon ); + } + + painter.restore(); +} + +//! Handle mouse press events +void QwtLegendLabel::mousePressEvent( QMouseEvent *e ) +{ + if ( e->button() == Qt::LeftButton ) + { + switch ( d_data->itemMode ) + { + case QwtLegendData::Clickable: + { + setDown( true ); + return; + } + case QwtLegendData::Checkable: + { + setDown( !isDown() ); + return; + } + default:; + } + } + QwtTextLabel::mousePressEvent( e ); +} + +//! Handle mouse release events +void QwtLegendLabel::mouseReleaseEvent( QMouseEvent *e ) +{ + if ( e->button() == Qt::LeftButton ) + { + switch ( d_data->itemMode ) + { + case QwtLegendData::Clickable: + { + setDown( false ); + return; + } + case QwtLegendData::Checkable: + { + return; // do nothing, but accept + } + default:; + } + } + QwtTextLabel::mouseReleaseEvent( e ); +} + +//! Handle key press events +void QwtLegendLabel::keyPressEvent( QKeyEvent *e ) +{ + if ( e->key() == Qt::Key_Space ) + { + switch ( d_data->itemMode ) + { + case QwtLegendData::Clickable: + { + if ( !e->isAutoRepeat() ) + setDown( true ); + return; + } + case QwtLegendData::Checkable: + { + if ( !e->isAutoRepeat() ) + setDown( !isDown() ); + return; + } + default:; + } + } + + QwtTextLabel::keyPressEvent( e ); +} + +//! Handle key release events +void QwtLegendLabel::keyReleaseEvent( QKeyEvent *e ) +{ + if ( e->key() == Qt::Key_Space ) + { + switch ( d_data->itemMode ) + { + case QwtLegendData::Clickable: + { + if ( !e->isAutoRepeat() ) + setDown( false ); + return; + } + case QwtLegendData::Checkable: + { + return; // do nothing, but accept + } + default:; + } + } + + QwtTextLabel::keyReleaseEvent( e ); +} diff --git a/ThirdParty/Qwt/src/qwt_legend_label.h b/ThirdParty/Qwt/src/qwt_legend_label.h new file mode 100644 index 0000000000..f0a1584af3 --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_legend_label.h @@ -0,0 +1,80 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#ifndef QWT_LEGEND_LABEL_H +#define QWT_LEGEND_LABEL_H + +#include "qwt_global.h" +#include "qwt_legend_data.h" +#include "qwt_text.h" +#include "qwt_text_label.h" +#include + +class QwtLegendData; + +/*! + \brief A widget representing something on a QwtLegend. +*/ +class QWT_EXPORT QwtLegendLabel: public QwtTextLabel +{ + Q_OBJECT +public: + explicit QwtLegendLabel( QWidget *parent = 0 ); + virtual ~QwtLegendLabel(); + + void setData( const QwtLegendData & ); + const QwtLegendData &data() const; + + void setItemMode( QwtLegendData::Mode ); + QwtLegendData::Mode itemMode() const; + + void setSpacing( int spacing ); + int spacing() const; + + virtual void setText( const QwtText & ); + + void setIcon( const QPixmap & ); + QPixmap icon() const; + + virtual QSize sizeHint() const; + + bool isChecked() const; + +public Q_SLOTS: + void setChecked( bool on ); + +Q_SIGNALS: + //! Signal, when the legend item has been clicked + void clicked(); + + //! Signal, when the legend item has been pressed + void pressed(); + + //! Signal, when the legend item has been released + void released(); + + //! Signal, when the legend item has been toggled + void checked( bool ); + +protected: + void setDown( bool ); + bool isDown() const; + + virtual void paintEvent( QPaintEvent * ); + virtual void mousePressEvent( QMouseEvent * ); + virtual void mouseReleaseEvent( QMouseEvent * ); + virtual void keyPressEvent( QKeyEvent * ); + virtual void keyReleaseEvent( QKeyEvent * ); + +private: + class PrivateData; + PrivateData *d_data; +}; + +#endif diff --git a/ThirdParty/Qwt/src/qwt_magnifier.cpp b/ThirdParty/Qwt/src/qwt_magnifier.cpp new file mode 100644 index 0000000000..55e7bb5eb7 --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_magnifier.cpp @@ -0,0 +1,492 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#include "qwt_magnifier.h" +#include "qwt_math.h" +#include +#include + +class QwtMagnifier::PrivateData +{ +public: + PrivateData(): + isEnabled( false ), + wheelFactor( 0.9 ), + wheelModifiers( Qt::NoModifier ), + mouseFactor( 0.95 ), + mouseButton( Qt::RightButton ), + mouseButtonModifiers( Qt::NoModifier ), + keyFactor( 0.9 ), + zoomInKey( Qt::Key_Plus ), + zoomInKeyModifiers( Qt::NoModifier ), + zoomOutKey( Qt::Key_Minus ), + zoomOutKeyModifiers( Qt::NoModifier ), + mousePressed( false ) + { + } + + bool isEnabled; + + double wheelFactor; + Qt::KeyboardModifiers wheelModifiers; + + double mouseFactor; + + Qt::MouseButton mouseButton; + Qt::KeyboardModifiers mouseButtonModifiers; + + double keyFactor; + + int zoomInKey; + Qt::KeyboardModifiers zoomInKeyModifiers; + + int zoomOutKey; + Qt::KeyboardModifiers zoomOutKeyModifiers; + + bool mousePressed; + bool hasMouseTracking; + QPoint mousePos; +}; + +/*! + Constructor + \param parent Widget to be magnified +*/ +QwtMagnifier::QwtMagnifier( QWidget *parent ): + QObject( parent ) +{ + d_data = new PrivateData(); + setEnabled( true ); +} + +//! Destructor +QwtMagnifier::~QwtMagnifier() +{ + delete d_data; +} + +/*! + \brief En/disable the magnifier + + When enabled is true an event filter is installed for + the observed widget, otherwise the event filter is removed. + + \param on true or false + \sa isEnabled(), eventFilter() +*/ +void QwtMagnifier::setEnabled( bool on ) +{ + if ( d_data->isEnabled != on ) + { + d_data->isEnabled = on; + + QObject *o = parent(); + if ( o ) + { + if ( d_data->isEnabled ) + o->installEventFilter( this ); + else + o->removeEventFilter( this ); + } + } +} + +/*! + \return true when enabled, false otherwise + \sa setEnabled(), eventFilter() +*/ +bool QwtMagnifier::isEnabled() const +{ + return d_data->isEnabled; +} + +/*! + \brief Change the wheel factor + + The wheel factor defines the ratio between the current range + on the parent widget and the zoomed range for each step of the wheel. + + Use values > 1 for magnification (i.e. 2.0) and values < 1 for + scaling down (i.e. 1/2.0 = 0.5). You can use this feature for + inverting the direction of the wheel. + + The default value is 0.9. + + \param factor Wheel factor + \sa wheelFactor(), setWheelButtonState(), + setMouseFactor(), setKeyFactor() +*/ +void QwtMagnifier::setWheelFactor( double factor ) +{ + d_data->wheelFactor = factor; +} + +/*! + \return Wheel factor + \sa setWheelFactor() +*/ +double QwtMagnifier::wheelFactor() const +{ + return d_data->wheelFactor; +} + +/*! + Assign keyboard modifiers for zooming in/out using the wheel. + The default modifiers are Qt::NoModifiers. + + \param modifiers Keyboard modifiers + \sa wheelModifiers() +*/ +void QwtMagnifier::setWheelModifiers( Qt::KeyboardModifiers modifiers ) +{ + d_data->wheelModifiers = modifiers; +} + +/*! + \return Wheel modifiers + \sa setWheelModifiers() +*/ +Qt::KeyboardModifiers QwtMagnifier::wheelModifiers() const +{ + return d_data->wheelModifiers; +} + +/*! + \brief Change the mouse factor + + The mouse factor defines the ratio between the current range + on the parent widget and the zoomed range for each vertical mouse movement. + The default value is 0.95. + + \param factor Wheel factor + \sa mouseFactor(), setMouseButton(), setWheelFactor(), setKeyFactor() +*/ +void QwtMagnifier::setMouseFactor( double factor ) +{ + d_data->mouseFactor = factor; +} + +/*! + \return Mouse factor + \sa setMouseFactor() +*/ +double QwtMagnifier::mouseFactor() const +{ + return d_data->mouseFactor; +} + +/*! + Assign the mouse button, that is used for zooming in/out. + The default value is Qt::RightButton. + + \param button Button + \param modifiers Keyboard modifiers + + \sa getMouseButton() +*/ +void QwtMagnifier::setMouseButton( + Qt::MouseButton button, Qt::KeyboardModifiers modifiers ) +{ + d_data->mouseButton = button; + d_data->mouseButtonModifiers = modifiers; +} + +//! \sa setMouseButton() +void QwtMagnifier::getMouseButton( + Qt::MouseButton &button, Qt::KeyboardModifiers &modifiers ) const +{ + button = d_data->mouseButton; + modifiers = d_data->mouseButtonModifiers; +} + +/*! + \brief Change the key factor + + The key factor defines the ratio between the current range + on the parent widget and the zoomed range for each key press of + the zoom in/out keys. The default value is 0.9. + + \param factor Key factor + \sa keyFactor(), setZoomInKey(), setZoomOutKey(), + setWheelFactor, setMouseFactor() +*/ +void QwtMagnifier::setKeyFactor( double factor ) +{ + d_data->keyFactor = factor; +} + +/*! + \return Key factor + \sa setKeyFactor() +*/ +double QwtMagnifier::keyFactor() const +{ + return d_data->keyFactor; +} + +/*! + Assign the key, that is used for zooming in. + The default combination is Qt::Key_Plus + Qt::NoModifier. + + \param key + \param modifiers + \sa getZoomInKey(), setZoomOutKey() +*/ +void QwtMagnifier::setZoomInKey( int key, + Qt::KeyboardModifiers modifiers ) +{ + d_data->zoomInKey = key; + d_data->zoomInKeyModifiers = modifiers; +} + +/*! + \brief Retrieve the settings of the zoom in key + + \param key Key code, see Qt::Key + \param modifiers Keyboard modifiers + + \sa setZoomInKey() +*/ +void QwtMagnifier::getZoomInKey( int &key, + Qt::KeyboardModifiers &modifiers ) const +{ + key = d_data->zoomInKey; + modifiers = d_data->zoomInKeyModifiers; +} + +/*! + Assign the key, that is used for zooming out. + The default combination is Qt::Key_Minus + Qt::NoModifier. + + \param key + \param modifiers + \sa getZoomOutKey(), setZoomOutKey() +*/ +void QwtMagnifier::setZoomOutKey( int key, + Qt::KeyboardModifiers modifiers ) +{ + d_data->zoomOutKey = key; + d_data->zoomOutKeyModifiers = modifiers; +} + +/*! + \brief Retrieve the settings of the zoom out key + + \param key Key code, see Qt::Key + \param modifiers Keyboard modifiers + + \sa setZoomOutKey() +*/ +void QwtMagnifier::getZoomOutKey( int &key, + Qt::KeyboardModifiers &modifiers ) const +{ + key = d_data->zoomOutKey; + modifiers = d_data->zoomOutKeyModifiers; +} + +/*! + \brief Event filter + + When isEnabled() is true, the mouse events of the + observed widget are filtered. + + \param object Object to be filtered + \param event Event + + \return Forwarded to QObject::eventFilter() + + \sa widgetMousePressEvent(), widgetMouseReleaseEvent(), + widgetMouseMoveEvent(), widgetWheelEvent(), widgetKeyPressEvent() + widgetKeyReleaseEvent() +*/ +bool QwtMagnifier::eventFilter( QObject *object, QEvent *event ) +{ + if ( object && object == parent() ) + { + switch ( event->type() ) + { + case QEvent::MouseButtonPress: + { + widgetMousePressEvent( static_cast( event ) ); + break; + } + case QEvent::MouseMove: + { + widgetMouseMoveEvent( static_cast( event ) ); + break; + } + case QEvent::MouseButtonRelease: + { + widgetMouseReleaseEvent( static_cast( event ) ); + break; + } + case QEvent::Wheel: + { + widgetWheelEvent( static_cast( event ) ); + break; + } + case QEvent::KeyPress: + { + widgetKeyPressEvent( static_cast( event ) ); + break; + } + case QEvent::KeyRelease: + { + widgetKeyReleaseEvent( static_cast( event ) ); + break; + } + default:; + } + } + return QObject::eventFilter( object, event ); +} + +/*! + Handle a mouse press event for the observed widget. + + \param mouseEvent Mouse event + \sa eventFilter(), widgetMouseReleaseEvent(), widgetMouseMoveEvent() +*/ +void QwtMagnifier::widgetMousePressEvent( QMouseEvent *mouseEvent ) +{ + if ( parentWidget() == NULL ) + return; + + if ( ( mouseEvent->button() != d_data->mouseButton ) || + ( mouseEvent->modifiers() != d_data->mouseButtonModifiers ) ) + { + return; + } + + d_data->hasMouseTracking = parentWidget()->hasMouseTracking(); + + parentWidget()->setMouseTracking( true ); + d_data->mousePos = mouseEvent->pos(); + d_data->mousePressed = true; +} + +/*! + Handle a mouse release event for the observed widget. + + \param mouseEvent Mouse event + + \sa eventFilter(), widgetMousePressEvent(), widgetMouseMoveEvent(), +*/ +void QwtMagnifier::widgetMouseReleaseEvent( QMouseEvent *mouseEvent ) +{ + Q_UNUSED( mouseEvent ); + + if ( d_data->mousePressed && parentWidget() ) + { + d_data->mousePressed = false; + parentWidget()->setMouseTracking( d_data->hasMouseTracking ); + } +} + +/*! + Handle a mouse move event for the observed widget. + + \param mouseEvent Mouse event + \sa eventFilter(), widgetMousePressEvent(), widgetMouseReleaseEvent(), +*/ +void QwtMagnifier::widgetMouseMoveEvent( QMouseEvent *mouseEvent ) +{ + if ( !d_data->mousePressed ) + return; + + const int dy = mouseEvent->pos().y() - d_data->mousePos.y(); + if ( dy != 0 ) + { + double f = d_data->mouseFactor; + if ( dy < 0 ) + f = 1 / f; + + rescale( f ); + } + + d_data->mousePos = mouseEvent->pos(); +} + +/*! + Handle a wheel event for the observed widget. + + \param wheelEvent Wheel event + \sa eventFilter() +*/ +void QwtMagnifier::widgetWheelEvent( QWheelEvent *wheelEvent ) +{ + if ( wheelEvent->modifiers() != d_data->wheelModifiers ) + { + return; + } + + if ( d_data->wheelFactor != 0.0 ) + { + /* + A positive delta indicates that the wheel was + rotated forwards away from the user; a negative + value indicates that the wheel was rotated + backwards toward the user. + Most mouse types work in steps of 15 degrees, + in which case the delta value is a multiple + of 120 (== 15 * 8). + */ + double f = qPow( d_data->wheelFactor, + qAbs( wheelEvent->delta() / 120.0 ) ); + + if ( wheelEvent->delta() > 0 ) + f = 1 / f; + + rescale( f ); + } +} + +/*! + Handle a key press event for the observed widget. + + \param keyEvent Key event + \sa eventFilter(), widgetKeyReleaseEvent() +*/ +void QwtMagnifier::widgetKeyPressEvent( QKeyEvent *keyEvent ) +{ + if ( keyEvent->key() == d_data->zoomInKey && + keyEvent->modifiers() == d_data->zoomInKeyModifiers ) + { + rescale( d_data->keyFactor ); + } + else if ( keyEvent->key() == d_data->zoomOutKey && + keyEvent->modifiers() == d_data->zoomOutKeyModifiers ) + { + rescale( 1.0 / d_data->keyFactor ); + } +} + +/*! + Handle a key release event for the observed widget. + + \param keyEvent Key event + \sa eventFilter(), widgetKeyReleaseEvent() +*/ +void QwtMagnifier::widgetKeyReleaseEvent( QKeyEvent *keyEvent ) +{ + Q_UNUSED( keyEvent ); +} + +//! \return Parent widget, where the rescaling happens +QWidget *QwtMagnifier::parentWidget() +{ + return qobject_cast( parent() ); +} + +//! \return Parent widget, where the rescaling happens +const QWidget *QwtMagnifier::parentWidget() const +{ + return qobject_cast( parent() ); +} + diff --git a/ThirdParty/Qwt/src/qwt_magnifier.h b/ThirdParty/Qwt/src/qwt_magnifier.h new file mode 100644 index 0000000000..48e8ed8c41 --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_magnifier.h @@ -0,0 +1,86 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#ifndef QWT_MAGNIFIER_H +#define QWT_MAGNIFIER_H 1 + +#include "qwt_global.h" +#include + +class QWidget; +class QMouseEvent; +class QWheelEvent; +class QKeyEvent; + +/*! + \brief QwtMagnifier provides zooming, by magnifying in steps. + + Using QwtMagnifier a plot can be zoomed in/out in steps using + keys, the mouse wheel or moving a mouse button in vertical direction. +*/ +class QWT_EXPORT QwtMagnifier: public QObject +{ + Q_OBJECT + +public: + explicit QwtMagnifier( QWidget * ); + virtual ~QwtMagnifier(); + + QWidget *parentWidget(); + const QWidget *parentWidget() const; + + void setEnabled( bool ); + bool isEnabled() const; + + // mouse + void setMouseFactor( double ); + double mouseFactor() const; + + void setMouseButton( Qt::MouseButton, Qt::KeyboardModifiers = Qt::NoModifier ); + void getMouseButton( Qt::MouseButton &, Qt::KeyboardModifiers & ) const; + + // mouse wheel + void setWheelFactor( double ); + double wheelFactor() const; + + void setWheelModifiers( Qt::KeyboardModifiers ); + Qt::KeyboardModifiers wheelModifiers() const; + + // keyboard + void setKeyFactor( double ); + double keyFactor() const; + + void setZoomInKey( int key, Qt::KeyboardModifiers = Qt::NoModifier ); + void getZoomInKey( int &key, Qt::KeyboardModifiers & ) const; + + void setZoomOutKey( int key, Qt::KeyboardModifiers = Qt::NoModifier ); + void getZoomOutKey( int &key, Qt::KeyboardModifiers & ) const; + + virtual bool eventFilter( QObject *, QEvent * ); + +protected: + /*! + Rescale the parent widget + \param factor Scale factor + */ + virtual void rescale( double factor ) = 0; + + virtual void widgetMousePressEvent( QMouseEvent * ); + virtual void widgetMouseReleaseEvent( QMouseEvent * ); + virtual void widgetMouseMoveEvent( QMouseEvent * ); + virtual void widgetWheelEvent( QWheelEvent * ); + virtual void widgetKeyPressEvent( QKeyEvent * ); + virtual void widgetKeyReleaseEvent( QKeyEvent * ); + +private: + class PrivateData; + PrivateData *d_data; +}; + +#endif diff --git a/ThirdParty/Qwt/src/qwt_math.cpp b/ThirdParty/Qwt/src/qwt_math.cpp new file mode 100644 index 0000000000..9e898c1051 --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_math.cpp @@ -0,0 +1,74 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#include "qwt_math.h" + +/*! + \brief Find the smallest value in an array + \param array Pointer to an array + \param size Array size +*/ +double qwtGetMin( const double *array, int size ) +{ + if ( size <= 0 ) + return 0.0; + + double rv = array[0]; + for ( int i = 1; i < size; i++ ) + rv = qMin( rv, array[i] ); + + return rv; +} + + +/*! + \brief Find the largest value in an array + \param array Pointer to an array + \param size Array size +*/ +double qwtGetMax( const double *array, int size ) +{ + if ( size <= 0 ) + return 0.0; + + double rv = array[0]; + for ( int i = 1; i < size; i++ ) + rv = qMax( rv, array[i] ); + + return rv; +} + +/*! + \brief Normalize an angle to be int the range [0.0, 2 * PI[ + \param radians Angle in radians + \return Normalized angle in radians +*/ +double qwtNormalizeRadians( double radians ) +{ + double a = ::fmod( radians, 2.0 * M_PI ); + if ( a < 0.0 ) + a += 2.0 * M_PI; + + return a; + +} + +/*! + \brief Normalize an angle to be int the range [0.0, 360.0[ + \param radians Angle in degrees + \return Normalized angle in degrees +*/ +double qwtNormalizeDegrees( double degrees ) +{ + double a = ::fmod( degrees, 360.0 ); + if ( a < 0.0 ) + a += 360.0; + + return a; +} diff --git a/ThirdParty/Qwt/src/qwt_math.h b/ThirdParty/Qwt/src/qwt_math.h new file mode 100644 index 0000000000..23ad205601 --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_math.h @@ -0,0 +1,149 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#ifndef QWT_MATH_H +#define QWT_MATH_H + +#include "qwt_global.h" + +#if defined(_MSC_VER) +/* + Microsoft says: + + Define _USE_MATH_DEFINES before including math.h to expose these macro + definitions for common math constants. These are placed under an #ifdef + since these commonly-defined names are not part of the C/C++ standards. +*/ +#define _USE_MATH_DEFINES 1 +#endif + +#include +#include "qwt_global.h" + +#ifndef M_PI_2 +// For Qt <= 4.8.4 M_PI_2 is not known by MinGW-w64 +// when compiling with -std=c++11 +#define M_PI_2 (1.57079632679489661923) +#endif + +#ifndef LOG_MIN +//! Minimum value for logarithmic scales +#define LOG_MIN 1.0e-100 +#endif + +#ifndef LOG_MAX +//! Maximum value for logarithmic scales +#define LOG_MAX 1.0e100 +#endif + +QWT_EXPORT double qwtGetMin( const double *array, int size ); +QWT_EXPORT double qwtGetMax( const double *array, int size ); + +QWT_EXPORT double qwtNormalizeRadians( double radians ); +QWT_EXPORT double qwtNormalizeDegrees( double degrees ); + +/*! + \brief Compare 2 values, relative to an interval + + Values are "equal", when : + \f$\cdot value2 - value1 <= abs(intervalSize * 10e^{-6})\f$ + + \param value1 First value to compare + \param value2 Second value to compare + \param intervalSize interval size + + \return 0: if equal, -1: if value2 > value1, 1: if value1 > value2 +*/ +inline int qwtFuzzyCompare( double value1, double value2, double intervalSize ) +{ + const double eps = qAbs( 1.0e-6 * intervalSize ); + + if ( value2 - value1 > eps ) + return -1; + + if ( value1 - value2 > eps ) + return 1; + + return 0; +} + + +inline bool qwtFuzzyGreaterOrEqual( double d1, double d2 ) +{ + return ( d1 >= d2 ) || qFuzzyCompare( d1, d2 ); +} + +inline bool qwtFuzzyLessOrEqual( double d1, double d2 ) +{ + return ( d1 <= d2 ) || qFuzzyCompare( d1, d2 ); +} + +//! Return the sign +inline int qwtSign( double x ) +{ + if ( x > 0.0 ) + return 1; + else if ( x < 0.0 ) + return ( -1 ); + else + return 0; +} + +//! Return the square of a number +inline double qwtSqr( double x ) +{ + return x * x; +} + +//! Approximation of arc tangent ( error below 0,005 radians ) +inline double qwtFastAtan( double x ) +{ + if ( x < -1.0 ) + return -M_PI_2 - x / ( x * x + 0.28 ); + + if ( x > 1.0 ) + return M_PI_2 - x / ( x * x + 0.28 ); + + return x / ( 1.0 + x * x * 0.28 ); +} + +//! Approximation of arc tangent ( error below 0,005 radians ) +inline double qwtFastAtan2( double y, double x ) +{ + if ( x > 0 ) + return qwtFastAtan( y / x ); + + if ( x < 0 ) + { + const double d = qwtFastAtan( y / x ); + return ( y >= 0 ) ? d + M_PI : d - M_PI; + } + + if ( y < 0.0 ) + return -M_PI_2; + + if ( y > 0.0 ) + return M_PI_2; + + return 0.0; +} + +// Translate degrees into radians +inline double qwtRadians( double degrees ) +{ + return degrees * M_PI / 180.0; +} + +// Translate radians into degrees +inline double qwtDegrees( double degrees ) +{ + return degrees * 180.0 / M_PI; +} + +#endif diff --git a/ThirdParty/Qwt/src/qwt_matrix_raster_data.cpp b/ThirdParty/Qwt/src/qwt_matrix_raster_data.cpp new file mode 100644 index 0000000000..69355adb34 --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_matrix_raster_data.cpp @@ -0,0 +1,298 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#include "qwt_matrix_raster_data.h" +#include +#include + +class QwtMatrixRasterData::PrivateData +{ +public: + PrivateData(): + resampleMode(QwtMatrixRasterData::NearestNeighbour), + numColumns(0) + { + } + + inline double value(int row, int col) const + { + return values.data()[ row * numColumns + col ]; + } + + QwtMatrixRasterData::ResampleMode resampleMode; + + QVector values; + int numColumns; + int numRows; + + double dx; + double dy; +}; + +//! Constructor +QwtMatrixRasterData::QwtMatrixRasterData() +{ + d_data = new PrivateData(); + update(); +} + +//! Destructor +QwtMatrixRasterData::~QwtMatrixRasterData() +{ + delete d_data; +} + +/*! + \brief Set the resampling algorithm + + \param mode Resampling mode + \sa resampleMode(), value() +*/ +void QwtMatrixRasterData::setResampleMode( ResampleMode mode ) +{ + d_data->resampleMode = mode; +} + +/*! + \return resampling algorithm + \sa setResampleMode(), value() +*/ +QwtMatrixRasterData::ResampleMode QwtMatrixRasterData::resampleMode() const +{ + return d_data->resampleMode; +} + +/*! + \brief Assign the bounding interval for an axis + + Setting the bounding intervals for the X/Y axis is mandatory + to define the positions for the values of the value matrix. + The interval in Z direction defines the possible range for + the values in the matrix, what is f.e used by QwtPlotSpectrogram + to map values to colors. The Z-interval might be the bounding + interval of the values in the matrix, but usually it isn't. + ( f.e a interval of 0.0-100.0 for values in percentage ) + + \param axis X, Y or Z axis + \param interval Interval + + \sa QwtRasterData::interval(), setValueMatrix() +*/ +void QwtMatrixRasterData::setInterval( + Qt::Axis axis, const QwtInterval &interval ) +{ + QwtRasterData::setInterval( axis, interval ); + update(); +} + +/*! + \brief Assign a value matrix + + The positions of the values are calculated by dividing + the bounding rectangle of the X/Y intervals into equidistant + rectangles ( pixels ). Each value corresponds to the center of + a pixel. + + \param values Vector of values + \param numColumns Number of columns + + \sa valueMatrix(), numColumns(), numRows(), setInterval()() +*/ +void QwtMatrixRasterData::setValueMatrix( + const QVector &values, int numColumns ) +{ + d_data->values = values; + d_data->numColumns = qMax( numColumns, 0 ); + update(); +} + +/*! + \return Value matrix + \sa setValueMatrix(), numColumns(), numRows(), setInterval() +*/ +const QVector QwtMatrixRasterData::valueMatrix() const +{ + return d_data->values; +} + +/*! + \brief Change a single value in the matrix + + \param row Row index + \param col Column index + \param value New value + + \sa value(), setValueMatrix() +*/ +void QwtMatrixRasterData::setValue( int row, int col, double value ) +{ + if ( row >= 0 && row < d_data->numRows && + col >= 0 && col < d_data->numColumns ) + { + const int index = row * d_data->numColumns + col; + d_data->values.data()[ index ] = value; + } +} + +/*! + \return Number of columns of the value matrix + \sa valueMatrix(), numRows(), setValueMatrix() +*/ +int QwtMatrixRasterData::numColumns() const +{ + return d_data->numColumns; +} + +/*! + \return Number of rows of the value matrix + \sa valueMatrix(), numColumns(), setValueMatrix() +*/ +int QwtMatrixRasterData::numRows() const +{ + return d_data->numRows; +} + +/*! + \brief Calculate the pixel hint + + pixelHint() returns the geometry of a pixel, that can be used + to calculate the resolution and alignment of the plot item, that is + representing the data. + + - NearestNeighbour\n + pixelHint() returns the surrounding pixel of the top left value + in the matrix. + + - BilinearInterpolation\n + Returns an empty rectangle recommending + to render in target device ( f.e. screen ) resolution. + + \param area Requested area, ignored + \return Calculated hint + + \sa ResampleMode, setMatrix(), setInterval() +*/ +QRectF QwtMatrixRasterData::pixelHint( const QRectF &area ) const +{ + Q_UNUSED( area ) + + QRectF rect; + if ( d_data->resampleMode == NearestNeighbour ) + { + const QwtInterval intervalX = interval( Qt::XAxis ); + const QwtInterval intervalY = interval( Qt::YAxis ); + if ( intervalX.isValid() && intervalY.isValid() ) + { + rect = QRectF( intervalX.minValue(), intervalY.minValue(), + d_data->dx, d_data->dy ); + } + } + + return rect; +} + +/*! + \return the value at a raster position + + \param x X value in plot coordinates + \param y Y value in plot coordinates + + \sa ResampleMode +*/ +double QwtMatrixRasterData::value( double x, double y ) const +{ + const QwtInterval xInterval = interval( Qt::XAxis ); + const QwtInterval yInterval = interval( Qt::YAxis ); + + if ( !( xInterval.contains(x) && yInterval.contains(y) ) ) + return qQNaN(); + + double value; + + switch( d_data->resampleMode ) + { + case BilinearInterpolation: + { + int col1 = qRound( (x - xInterval.minValue() ) / d_data->dx ) - 1; + int row1 = qRound( (y - yInterval.minValue() ) / d_data->dy ) - 1; + int col2 = col1 + 1; + int row2 = row1 + 1; + + if ( col1 < 0 ) + col1 = col2; + else if ( col2 >= static_cast( d_data->numColumns ) ) + col2 = col1; + + if ( row1 < 0 ) + row1 = row2; + else if ( row2 >= static_cast( d_data->numRows ) ) + row2 = row1; + + const double v11 = d_data->value( row1, col1 ); + const double v21 = d_data->value( row1, col2 ); + const double v12 = d_data->value( row2, col1 ); + const double v22 = d_data->value( row2, col2 ); + + const double x2 = xInterval.minValue() + + ( col2 + 0.5 ) * d_data->dx; + const double y2 = yInterval.minValue() + + ( row2 + 0.5 ) * d_data->dy; + + const double rx = ( x2 - x ) / d_data->dx; + const double ry = ( y2 - y ) / d_data->dy; + + const double vr1 = rx * v11 + ( 1.0 - rx ) * v21; + const double vr2 = rx * v12 + ( 1.0 - rx ) * v22; + + value = ry * vr1 + ( 1.0 - ry ) * vr2; + + break; + } + case NearestNeighbour: + default: + { + int row = int( (y - yInterval.minValue() ) / d_data->dy ); + int col = int( (x - xInterval.minValue() ) / d_data->dx ); + + // In case of intervals, where the maximum is included + // we get out of bound for row/col, when the value for the + // maximum is requested. Instead we return the value + // from the last row/col + + if ( row >= d_data->numRows ) + row = d_data->numRows - 1; + + if ( col >= d_data->numColumns ) + col = d_data->numColumns - 1; + + value = d_data->value( row, col ); + } + } + + return value; +} + +void QwtMatrixRasterData::update() +{ + d_data->numRows = 0; + d_data->dx = 0.0; + d_data->dy = 0.0; + + if ( d_data->numColumns > 0 ) + { + d_data->numRows = d_data->values.size() / d_data->numColumns; + + const QwtInterval xInterval = interval( Qt::XAxis ); + const QwtInterval yInterval = interval( Qt::YAxis ); + if ( xInterval.isValid() ) + d_data->dx = xInterval.width() / d_data->numColumns; + if ( yInterval.isValid() ) + d_data->dy = yInterval.width() / d_data->numRows; + } +} diff --git a/ThirdParty/Qwt/src/qwt_matrix_raster_data.h b/ThirdParty/Qwt/src/qwt_matrix_raster_data.h new file mode 100644 index 0000000000..0b107c9fd9 --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_matrix_raster_data.h @@ -0,0 +1,74 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#ifndef QWT_MATRIX_RASTER_DATA_H +#define QWT_MATRIX_RASTER_DATA_H 1 + +#include "qwt_global.h" +#include "qwt_raster_data.h" +#include + +/*! + \brief A class representing a matrix of values as raster data + + QwtMatrixRasterData implements an interface for a matrix of + equidistant values, that can be used by a QwtPlotRasterItem. + It implements a couple of resampling algorithms, to provide + values for positions, that or not on the value matrix. +*/ +class QWT_EXPORT QwtMatrixRasterData: public QwtRasterData +{ +public: + /*! + \brief Resampling algorithm + The default setting is NearestNeighbour; + */ + enum ResampleMode + { + /*! + Return the value from the matrix, that is nearest to the + the requested position. + */ + NearestNeighbour, + + /*! + Interpolate the value from the distances and values of the + 4 surrounding values in the matrix, + */ + BilinearInterpolation + }; + + QwtMatrixRasterData(); + virtual ~QwtMatrixRasterData(); + + void setResampleMode(ResampleMode mode); + ResampleMode resampleMode() const; + + virtual void setInterval( Qt::Axis, const QwtInterval & ); + + void setValueMatrix( const QVector &values, int numColumns ); + const QVector valueMatrix() const; + + void setValue( int row, int col, double value ); + + int numColumns() const; + int numRows() const; + + virtual QRectF pixelHint( const QRectF & ) const; + + virtual double value( double x, double y ) const; + +private: + void update(); + + class PrivateData; + PrivateData *d_data; +}; + +#endif diff --git a/ThirdParty/Qwt/src/qwt_null_paintdevice.cpp b/ThirdParty/Qwt/src/qwt_null_paintdevice.cpp new file mode 100644 index 0000000000..db1611da25 --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_null_paintdevice.cpp @@ -0,0 +1,593 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#include "qwt_null_paintdevice.h" +#include +#include + +class QwtNullPaintDevice::PrivateData +{ +public: + PrivateData(): + mode( QwtNullPaintDevice::NormalMode ) + { + } + + QwtNullPaintDevice::Mode mode; +}; + +class QwtNullPaintDevice::PaintEngine: public QPaintEngine +{ +public: + PaintEngine(); + + virtual bool begin( QPaintDevice * ); + virtual bool end(); + + virtual Type type () const; + virtual void updateState(const QPaintEngineState &); + + virtual void drawRects(const QRect *, int ); + virtual void drawRects(const QRectF *, int ); + + virtual void drawLines(const QLine *, int ); + virtual void drawLines(const QLineF *, int ); + + virtual void drawEllipse(const QRectF &); + virtual void drawEllipse(const QRect &); + + virtual void drawPath(const QPainterPath &); + + virtual void drawPoints(const QPointF *, int ); + virtual void drawPoints(const QPoint *, int ); + + virtual void drawPolygon(const QPointF *, int , PolygonDrawMode ); + virtual void drawPolygon(const QPoint *, int , PolygonDrawMode ); + + virtual void drawPixmap(const QRectF &, + const QPixmap &, const QRectF &); + + virtual void drawTextItem(const QPointF &, const QTextItem &); + + virtual void drawTiledPixmap(const QRectF &, + const QPixmap &, const QPointF &s); + + virtual void drawImage(const QRectF &, + const QImage &, const QRectF &, Qt::ImageConversionFlags ); + +private: + QwtNullPaintDevice *nullDevice(); +}; + +QwtNullPaintDevice::PaintEngine::PaintEngine(): + QPaintEngine( QPaintEngine::AllFeatures ) +{ +} + +bool QwtNullPaintDevice::PaintEngine::begin( QPaintDevice * ) +{ + setActive( true ); + return true; +} + +bool QwtNullPaintDevice::PaintEngine::end() +{ + setActive( false ); + return true; +} + +QPaintEngine::Type QwtNullPaintDevice::PaintEngine::type() const +{ + return QPaintEngine::User; +} + +void QwtNullPaintDevice::PaintEngine::drawRects( + const QRect *rects, int rectCount) +{ + QwtNullPaintDevice *device = nullDevice(); + if ( device == NULL ) + return; + + if ( device->mode() != QwtNullPaintDevice::NormalMode ) + { + QPaintEngine::drawRects( rects, rectCount ); + return; + } + + device->drawRects( rects, rectCount ); +} + +void QwtNullPaintDevice::PaintEngine::drawRects( + const QRectF *rects, int rectCount) +{ + QwtNullPaintDevice *device = nullDevice(); + if ( device == NULL ) + return; + + if ( device->mode() != QwtNullPaintDevice::NormalMode ) + { + QPaintEngine::drawRects( rects, rectCount ); + return; + } + + device->drawRects( rects, rectCount ); +} + +void QwtNullPaintDevice::PaintEngine::drawLines( + const QLine *lines, int lineCount) +{ + QwtNullPaintDevice *device = nullDevice(); + if ( device == NULL ) + return; + + if ( device->mode() != QwtNullPaintDevice::NormalMode ) + { + QPaintEngine::drawLines( lines, lineCount ); + return; + } + + device->drawLines( lines, lineCount ); +} + +void QwtNullPaintDevice::PaintEngine::drawLines( + const QLineF *lines, int lineCount) +{ + QwtNullPaintDevice *device = nullDevice(); + if ( device == NULL ) + return; + + if ( device->mode() != QwtNullPaintDevice::NormalMode ) + { + QPaintEngine::drawLines( lines, lineCount ); + return; + } + + device->drawLines( lines, lineCount ); +} + +void QwtNullPaintDevice::PaintEngine::drawEllipse( + const QRectF &rect) +{ + QwtNullPaintDevice *device = nullDevice(); + if ( device == NULL ) + return; + + if ( device->mode() != QwtNullPaintDevice::NormalMode ) + { + QPaintEngine::drawEllipse( rect ); + return; + } + + device->drawEllipse( rect ); +} + +void QwtNullPaintDevice::PaintEngine::drawEllipse( + const QRect &rect) +{ + QwtNullPaintDevice *device = nullDevice(); + if ( device == NULL ) + return; + + if ( device->mode() != QwtNullPaintDevice::NormalMode ) + { + QPaintEngine::drawEllipse( rect ); + return; + } + + device->drawEllipse( rect ); +} + + +void QwtNullPaintDevice::PaintEngine::drawPath( + const QPainterPath &path) +{ + QwtNullPaintDevice *device = nullDevice(); + if ( device == NULL ) + return; + + device->drawPath( path ); +} + +void QwtNullPaintDevice::PaintEngine::drawPoints( + const QPointF *points, int pointCount) +{ + QwtNullPaintDevice *device = nullDevice(); + if ( device == NULL ) + return; + + if ( device->mode() != QwtNullPaintDevice::NormalMode ) + { + QPaintEngine::drawPoints( points, pointCount ); + return; + } + + device->drawPoints( points, pointCount ); +} + +void QwtNullPaintDevice::PaintEngine::drawPoints( + const QPoint *points, int pointCount) +{ + QwtNullPaintDevice *device = nullDevice(); + if ( device == NULL ) + return; + + if ( device->mode() != QwtNullPaintDevice::NormalMode ) + { + QPaintEngine::drawPoints( points, pointCount ); + return; + } + + device->drawPoints( points, pointCount ); +} + +void QwtNullPaintDevice::PaintEngine::drawPolygon( + const QPointF *points, int pointCount, PolygonDrawMode mode) +{ + QwtNullPaintDevice *device = nullDevice(); + if ( device == NULL ) + return; + + if ( device->mode() == QwtNullPaintDevice::PathMode ) + { + QPainterPath path; + + if ( pointCount > 0 ) + { + path.moveTo( points[0] ); + for ( int i = 1; i < pointCount; i++ ) + path.lineTo( points[i] ); + + if ( mode != PolylineMode ) + path.closeSubpath(); + } + + device->drawPath( path ); + return; + } + + device->drawPolygon( points, pointCount, mode ); +} + +void QwtNullPaintDevice::PaintEngine::drawPolygon( + const QPoint *points, int pointCount, PolygonDrawMode mode) +{ + QwtNullPaintDevice *device = nullDevice(); + if ( device == NULL ) + return; + + if ( device->mode() == QwtNullPaintDevice::PathMode ) + { + QPainterPath path; + + if ( pointCount > 0 ) + { + path.moveTo( points[0] ); + for ( int i = 1; i < pointCount; i++ ) + path.lineTo( points[i] ); + + if ( mode != PolylineMode ) + path.closeSubpath(); + } + + device->drawPath( path ); + return; + } + + device->drawPolygon( points, pointCount, mode ); +} + +void QwtNullPaintDevice::PaintEngine::drawPixmap( + const QRectF &rect, const QPixmap &pm, const QRectF &subRect ) +{ + QwtNullPaintDevice *device = nullDevice(); + if ( device == NULL ) + return; + + device->drawPixmap( rect, pm, subRect ); +} + +void QwtNullPaintDevice::PaintEngine::drawTextItem( + const QPointF &pos, const QTextItem &textItem) +{ + QwtNullPaintDevice *device = nullDevice(); + if ( device == NULL ) + return; + + if ( device->mode() != QwtNullPaintDevice::NormalMode ) + { + QPaintEngine::drawTextItem( pos, textItem ); + return; + } + + device->drawTextItem( pos, textItem ); +} + +void QwtNullPaintDevice::PaintEngine::drawTiledPixmap( + const QRectF &rect, const QPixmap &pixmap, + const QPointF &subRect) +{ + QwtNullPaintDevice *device = nullDevice(); + if ( device == NULL ) + return; + + if ( device->mode() != QwtNullPaintDevice::NormalMode ) + { + QPaintEngine::drawTiledPixmap( rect, pixmap, subRect ); + return; + } + + device->drawTiledPixmap( rect, pixmap, subRect ); +} + +void QwtNullPaintDevice::PaintEngine::drawImage( + const QRectF &rect, const QImage &image, + const QRectF &subRect, Qt::ImageConversionFlags flags) +{ + QwtNullPaintDevice *device = nullDevice(); + if ( device == NULL ) + return; + + device->drawImage( rect, image, subRect, flags ); +} + +void QwtNullPaintDevice::PaintEngine::updateState( + const QPaintEngineState &state) +{ + QwtNullPaintDevice *device = nullDevice(); + if ( device == NULL ) + return; + + device->updateState( state ); +} + +inline QwtNullPaintDevice *QwtNullPaintDevice::PaintEngine::nullDevice() +{ + if ( !isActive() ) + return NULL; + + return static_cast( paintDevice() ); +} + +//! Constructor +QwtNullPaintDevice::QwtNullPaintDevice(): + d_engine( NULL ) +{ + d_data = new PrivateData; +} + +//! Destructor +QwtNullPaintDevice::~QwtNullPaintDevice() +{ + delete d_engine; + delete d_data; +} + +/*! + Set the render mode + + \param mode New mode + \sa mode() + */ +void QwtNullPaintDevice::setMode( Mode mode ) +{ + d_data->mode = mode; +} + +/*! + \return Render mode + \sa setMode() +*/ +QwtNullPaintDevice::Mode QwtNullPaintDevice::mode() const +{ + return d_data->mode; +} + +//! See QPaintDevice::paintEngine() +QPaintEngine *QwtNullPaintDevice::paintEngine() const +{ + if ( d_engine == NULL ) + { + QwtNullPaintDevice *that = + const_cast< QwtNullPaintDevice * >( this ); + + that->d_engine = new PaintEngine(); + } + + return d_engine; +} + +/*! + See QPaintDevice::metric() + + \param deviceMetric Type of metric + \return Metric information for the given paint device metric. + + \sa sizeMetrics() +*/ +int QwtNullPaintDevice::metric( PaintDeviceMetric deviceMetric ) const +{ + int value; + + switch ( deviceMetric ) + { + case PdmWidth: + { + value = sizeMetrics().width(); + break; + } + case PdmHeight: + { + value = sizeMetrics().height(); + break; + } + case PdmNumColors: + { + value = 0xffffffff; + break; + } + case PdmDepth: + { + value = 32; + break; + } + case PdmPhysicalDpiX: + case PdmPhysicalDpiY: + case PdmDpiY: + case PdmDpiX: + { + value = 72; + break; + } + case PdmWidthMM: + { + value = qRound( metric( PdmWidth ) * 25.4 / metric( PdmDpiX ) ); + break; + } + case PdmHeightMM: + { + value = qRound( metric( PdmHeight ) * 25.4 / metric( PdmDpiY ) ); + break; + } + default: + value = 0; + } + return value; + +} + +//! See QPaintEngine::drawRects() +void QwtNullPaintDevice::drawRects( + const QRect *rects, int rectCount) +{ + Q_UNUSED(rects); + Q_UNUSED(rectCount); +} + +//! See QPaintEngine::drawRects() +void QwtNullPaintDevice::drawRects( + const QRectF *rects, int rectCount) +{ + Q_UNUSED(rects); + Q_UNUSED(rectCount); +} + +//! See QPaintEngine::drawLines() +void QwtNullPaintDevice::drawLines( + const QLine *lines, int lineCount) +{ + Q_UNUSED(lines); + Q_UNUSED(lineCount); +} + +//! See QPaintEngine::drawLines() +void QwtNullPaintDevice::drawLines( + const QLineF *lines, int lineCount) +{ + Q_UNUSED(lines); + Q_UNUSED(lineCount); +} + +//! See QPaintEngine::drawEllipse() +void QwtNullPaintDevice::drawEllipse( const QRectF &rect ) +{ + Q_UNUSED(rect); +} + +//! See QPaintEngine::drawEllipse() +void QwtNullPaintDevice::drawEllipse( const QRect &rect ) +{ + Q_UNUSED(rect); +} + +//! See QPaintEngine::drawPath() +void QwtNullPaintDevice::drawPath( const QPainterPath &path ) +{ + Q_UNUSED(path); +} + +//! See QPaintEngine::drawPoints() +void QwtNullPaintDevice::drawPoints( + const QPointF *points, int pointCount) +{ + Q_UNUSED(points); + Q_UNUSED(pointCount); +} + +//! See QPaintEngine::drawPoints() +void QwtNullPaintDevice::drawPoints( + const QPoint *points, int pointCount) +{ + Q_UNUSED(points); + Q_UNUSED(pointCount); +} + +//! See QPaintEngine::drawPolygon() +void QwtNullPaintDevice::drawPolygon( + const QPointF *points, int pointCount, + QPaintEngine::PolygonDrawMode mode) +{ + Q_UNUSED(points); + Q_UNUSED(pointCount); + Q_UNUSED(mode); +} + +//! See QPaintEngine::drawPolygon() +void QwtNullPaintDevice::drawPolygon( + const QPoint *points, int pointCount, + QPaintEngine::PolygonDrawMode mode) +{ + Q_UNUSED(points); + Q_UNUSED(pointCount); + Q_UNUSED(mode); +} + +//! See QPaintEngine::drawPixmap() +void QwtNullPaintDevice::drawPixmap( const QRectF &rect, + const QPixmap &pm, const QRectF &subRect ) +{ + Q_UNUSED(rect); + Q_UNUSED(pm); + Q_UNUSED(subRect); +} + +//! See QPaintEngine::drawTextItem() +void QwtNullPaintDevice::drawTextItem( + const QPointF &pos, const QTextItem &textItem) +{ + Q_UNUSED(pos); + Q_UNUSED(textItem); +} + +//! See QPaintEngine::drawTiledPixmap() +void QwtNullPaintDevice::drawTiledPixmap( + const QRectF &rect, const QPixmap &pixmap, + const QPointF &subRect) +{ + Q_UNUSED(rect); + Q_UNUSED(pixmap); + Q_UNUSED(subRect); +} + +//! See QPaintEngine::drawImage() +void QwtNullPaintDevice::drawImage( + const QRectF &rect, const QImage &image, + const QRectF &subRect, Qt::ImageConversionFlags flags) +{ + Q_UNUSED(rect); + Q_UNUSED(image); + Q_UNUSED(subRect); + Q_UNUSED(flags); +} + +//! See QPaintEngine::updateState() +void QwtNullPaintDevice::updateState( + const QPaintEngineState &state ) +{ + Q_UNUSED(state); +} diff --git a/ThirdParty/Qwt/src/qwt_null_paintdevice.h b/ThirdParty/Qwt/src/qwt_null_paintdevice.h new file mode 100644 index 0000000000..d7f03beea9 --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_null_paintdevice.h @@ -0,0 +1,126 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#ifndef QWT_NULL_PAINT_DEVICE_H +#define QWT_NULL_PAINT_DEVICE_H 1 + +#include "qwt_global.h" +#include +#include + +/*! + \brief A null paint device doing nothing + + Sometimes important layout/rendering geometries are not + available or changeable from the public Qt class interface. + ( f.e hidden in the style implementation ). + + QwtNullPaintDevice can be used to manipulate or filter out + this information by analyzing the stream of paint primitives. + + F.e. QwtNullPaintDevice is used by QwtPlotCanvas to identify + styled backgrounds with rounded corners. +*/ + +class QWT_EXPORT QwtNullPaintDevice: public QPaintDevice +{ +public: + /*! + \brief Render mode + + \sa setMode(), mode() + */ + enum Mode + { + /*! + All vector graphic primitives are painted by + the corresponding draw methods + */ + NormalMode, + + /*! + Vector graphic primitives ( beside polygons ) are mapped to a QPainterPath + and are painted by drawPath. In PathMode mode + only a few draw methods are called: + + - drawPath() + - drawPixmap() + - drawImage() + - drawPolygon() + */ + PolygonPathMode, + + /*! + Vector graphic primitives are mapped to a QPainterPath + and are painted by drawPath. In PathMode mode + only a few draw methods are called: + + - drawPath() + - drawPixmap() + - drawImage() + */ + PathMode + }; + + QwtNullPaintDevice(); + virtual ~QwtNullPaintDevice(); + + void setMode( Mode ); + Mode mode() const; + + virtual QPaintEngine *paintEngine() const; + + virtual int metric( PaintDeviceMetric metric ) const; + + virtual void drawRects(const QRect *, int ); + virtual void drawRects(const QRectF *, int ); + + virtual void drawLines(const QLine *, int ); + virtual void drawLines(const QLineF *, int ); + + virtual void drawEllipse(const QRectF &); + virtual void drawEllipse(const QRect &); + + virtual void drawPath(const QPainterPath &); + + virtual void drawPoints(const QPointF *, int ); + virtual void drawPoints(const QPoint *, int ); + + virtual void drawPolygon( + const QPointF *, int , QPaintEngine::PolygonDrawMode ); + + virtual void drawPolygon( + const QPoint *, int , QPaintEngine::PolygonDrawMode ); + + virtual void drawPixmap(const QRectF &, + const QPixmap &, const QRectF &); + + virtual void drawTextItem(const QPointF &, const QTextItem &); + + virtual void drawTiledPixmap(const QRectF &, + const QPixmap &, const QPointF &s); + + virtual void drawImage(const QRectF &, + const QImage &, const QRectF &, Qt::ImageConversionFlags ); + + virtual void updateState( const QPaintEngineState &state ); + +protected: + //! \return Size needed to implement metric() + virtual QSize sizeMetrics() const = 0; + +private: + class PaintEngine; + PaintEngine *d_engine; + + class PrivateData; + PrivateData *d_data; +}; + +#endif diff --git a/ThirdParty/Qwt/src/qwt_painter.cpp b/ThirdParty/Qwt/src/qwt_painter.cpp new file mode 100644 index 0000000000..1509a7e2bf --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_painter.cpp @@ -0,0 +1,1266 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#include "qwt_painter.h" +#include "qwt_math.h" +#include "qwt_clipper.h" +#include "qwt_color_map.h" +#include "qwt_scale_map.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if QT_VERSION >= 0x050000 +#include +#endif + +#if QT_VERSION < 0x050000 + +#ifdef Q_WS_X11 +#include +#endif + +#endif + +bool QwtPainter::d_polylineSplitting = true; +bool QwtPainter::d_roundingAlignment = true; + +static inline bool qwtIsClippingNeeded( + const QPainter *painter, QRectF &clipRect ) +{ + bool doClipping = false; + const QPaintEngine *pe = painter->paintEngine(); + if ( pe && pe->type() == QPaintEngine::SVG ) + { + // The SVG paint engine ignores any clipping, + + if ( painter->hasClipping() ) + { + doClipping = true; + clipRect = painter->clipRegion().boundingRect(); + } + } + + return doClipping; +} + +template +static inline void qwtDrawPolyline( QPainter *painter, + const T *points, int pointCount, bool polylineSplitting ) +{ + bool doSplit = false; + if ( polylineSplitting ) + { + const QPaintEngine *pe = painter->paintEngine(); + if ( pe && pe->type() == QPaintEngine::Raster ) + { + /* + The raster paint engine seems to use some algo with O(n*n). + ( Qt 4.3 is better than Qt 4.2, but remains unacceptable) + To work around this problem, we have to split the polygon into + smaller pieces. + */ + doSplit = true; + } + } + + if ( doSplit ) + { + const int splitSize = 20; + for ( int i = 0; i < pointCount; i += splitSize ) + { + const int n = qMin( splitSize + 1, pointCount - i ); + painter->drawPolyline( points + i, n ); + } + } + else + painter->drawPolyline( points, pointCount ); +} + +static inline void qwtUnscaleFont( QPainter *painter ) +{ + if ( painter->font().pixelSize() >= 0 ) + return; + + static QSize screenResolution; + if ( !screenResolution.isValid() ) + { + QDesktopWidget *desktop = QApplication::desktop(); + if ( desktop ) + { + screenResolution.setWidth( desktop->logicalDpiX() ); + screenResolution.setHeight( desktop->logicalDpiY() ); + } + } + + const QPaintDevice *pd = painter->device(); + if ( pd->logicalDpiX() != screenResolution.width() || + pd->logicalDpiY() != screenResolution.height() ) + { + QFont pixelFont( painter->font(), QApplication::desktop() ); + pixelFont.setPixelSize( QFontInfo( pixelFont ).pixelSize() ); + + painter->setFont( pixelFont ); + } +} + +/*! + Check is the application is running with the X11 graphics system + that has some special capabilities that can be used for incremental + painting to a widget. + + \return True, when the graphics system is X11 +*/ +bool QwtPainter::isX11GraphicsSystem() +{ + static int onX11 = -1; + if ( onX11 < 0 ) + { + QPixmap pm( 1, 1 ); + QPainter painter( &pm ); + + onX11 = ( painter.paintEngine()->type() == QPaintEngine::X11 ) ? 1 : 0; + } + + return onX11 == 1; +} + +/*! + Check if the painter is using a paint engine, that aligns + coordinates to integers. Today these are all paint engines + beside QPaintEngine::Pdf and QPaintEngine::SVG. + + If we have an integer based paint engine it is also + checked if the painter has a transformation matrix, + that rotates or scales. + + \param painter Painter + \return true, when the painter is aligning + + \sa setRoundingAlignment() +*/ +bool QwtPainter::isAligning( QPainter *painter ) +{ + if ( painter && painter->isActive() ) + { + switch ( painter->paintEngine()->type() ) + { + case QPaintEngine::Pdf: + case QPaintEngine::SVG: + return false; + + default:; + } + + const QTransform tr = painter->transform(); + if ( tr.isRotating() || tr.isScaling() ) + { + // we might have to check translations too + return false; + } + } + + return true; +} + +/*! + Enable whether coordinates should be rounded, before they are painted + to a paint engine that floors to integer values. For other paint engines + this ( PDF, SVG ), this flag has no effect. + QwtPainter stores this flag only, the rounding itself is done in + the painting code ( f.e the plot items ). + + The default setting is true. + + \sa roundingAlignment(), isAligning() +*/ +void QwtPainter::setRoundingAlignment( bool enable ) +{ + d_roundingAlignment = enable; +} + +/*! + \brief En/Disable line splitting for the raster paint engine + + In some Qt versions the raster paint engine paints polylines of many points + much faster when they are split in smaller chunks: f.e all supported Qt versions + >= Qt 5.0 when drawing an antialiased polyline with a pen width >=2. + + The default setting is true. + + \sa polylineSplitting() +*/ +void QwtPainter::setPolylineSplitting( bool enable ) +{ + d_polylineSplitting = enable; +} + +//! Wrapper for QPainter::drawPath() +void QwtPainter::drawPath( QPainter *painter, const QPainterPath &path ) +{ + painter->drawPath( path ); +} + +//! Wrapper for QPainter::drawRect() +void QwtPainter::drawRect( QPainter *painter, double x, double y, double w, double h ) +{ + drawRect( painter, QRectF( x, y, w, h ) ); +} + +//! Wrapper for QPainter::drawRect() +void QwtPainter::drawRect( QPainter *painter, const QRectF &rect ) +{ + const QRectF r = rect; + + QRectF clipRect; + const bool deviceClipping = qwtIsClippingNeeded( painter, clipRect ); + + if ( deviceClipping ) + { + if ( !clipRect.intersects( r ) ) + return; + + if ( !clipRect.contains( r ) ) + { + fillRect( painter, r & clipRect, painter->brush() ); + + painter->save(); + painter->setBrush( Qt::NoBrush ); + drawPolyline( painter, QPolygonF( r ) ); + painter->restore(); + + return; + } + } + + painter->drawRect( r ); +} + +//! Wrapper for QPainter::fillRect() +void QwtPainter::fillRect( QPainter *painter, + const QRectF &rect, const QBrush &brush ) +{ + if ( !rect.isValid() ) + return; + + QRectF clipRect; + const bool deviceClipping = qwtIsClippingNeeded( painter, clipRect ); + + /* + Performance of Qt4 is horrible for a non trivial brush. Without + clipping expect minutes or hours for repainting large rectangles + (might result from zooming) + */ + + if ( deviceClipping ) + clipRect &= painter->window(); + else + clipRect = painter->window(); + + if ( painter->hasClipping() ) + clipRect &= painter->clipRegion().boundingRect(); + + QRectF r = rect; + if ( deviceClipping ) + r = r.intersected( clipRect ); + + if ( r.isValid() ) + painter->fillRect( r, brush ); +} + +//! Wrapper for QPainter::drawPie() +void QwtPainter::drawPie( QPainter *painter, const QRectF &rect, + int a, int alen ) +{ + QRectF clipRect; + const bool deviceClipping = qwtIsClippingNeeded( painter, clipRect ); + if ( deviceClipping && !clipRect.contains( rect ) ) + return; + + painter->drawPie( rect, a, alen ); +} + +//! Wrapper for QPainter::drawEllipse() +void QwtPainter::drawEllipse( QPainter *painter, const QRectF &rect ) +{ + QRectF clipRect; + const bool deviceClipping = qwtIsClippingNeeded( painter, clipRect ); + + if ( deviceClipping && !clipRect.contains( rect ) ) + return; + + painter->drawEllipse( rect ); +} + +//! Wrapper for QPainter::drawText() +void QwtPainter::drawText( QPainter *painter, double x, double y, + const QString &text ) +{ + drawText( painter, QPointF( x, y ), text ); +} + +//! Wrapper for QPainter::drawText() +void QwtPainter::drawText( QPainter *painter, const QPointF &pos, + const QString &text ) +{ + QRectF clipRect; + const bool deviceClipping = qwtIsClippingNeeded( painter, clipRect ); + + if ( deviceClipping && !clipRect.contains( pos ) ) + return; + + + painter->save(); + qwtUnscaleFont( painter ); + painter->drawText( pos, text ); + painter->restore(); +} + +//! Wrapper for QPainter::drawText() +void QwtPainter::drawText( QPainter *painter, + double x, double y, double w, double h, + int flags, const QString &text ) +{ + drawText( painter, QRectF( x, y, w, h ), flags, text ); +} + +//! Wrapper for QPainter::drawText() +void QwtPainter::drawText( QPainter *painter, const QRectF &rect, + int flags, const QString &text ) +{ + painter->save(); + qwtUnscaleFont( painter ); + painter->drawText( rect, flags, text ); + painter->restore(); +} + +#ifndef QT_NO_RICHTEXT + +/*! + Draw a text document into a rectangle + + \param painter Painter + \param rect Traget rectangle + \param flags Alignments/Text flags, see QPainter::drawText() + \param text Text document +*/ +void QwtPainter::drawSimpleRichText( QPainter *painter, const QRectF &rect, + int flags, const QTextDocument &text ) +{ + QTextDocument *txt = text.clone(); + + painter->save(); + + painter->setFont( txt->defaultFont() ); + qwtUnscaleFont( painter ); + + txt->setDefaultFont( painter->font() ); + txt->setPageSize( QSizeF( rect.width(), QWIDGETSIZE_MAX ) ); + + QAbstractTextDocumentLayout* layout = txt->documentLayout(); + + const double height = layout->documentSize().height(); + double y = rect.y(); + if ( flags & Qt::AlignBottom ) + y += ( rect.height() - height ); + else if ( flags & Qt::AlignVCenter ) + y += ( rect.height() - height ) / 2; + + QAbstractTextDocumentLayout::PaintContext context; + context.palette.setColor( QPalette::Text, painter->pen().color() ); + + painter->translate( rect.x(), y ); + layout->draw( painter, context ); + + painter->restore(); + delete txt; +} + +#endif // !QT_NO_RICHTEXT + + +//! Wrapper for QPainter::drawLine() +void QwtPainter::drawLine( QPainter *painter, + const QPointF &p1, const QPointF &p2 ) +{ + QRectF clipRect; + const bool deviceClipping = qwtIsClippingNeeded( painter, clipRect ); + + if ( deviceClipping && + !( clipRect.contains( p1 ) && clipRect.contains( p2 ) ) ) + { + QPolygonF polygon; + polygon += p1; + polygon += p2; + drawPolyline( painter, polygon ); + return; + } + + painter->drawLine( p1, p2 ); +} + +//! Wrapper for QPainter::drawPolygon() +void QwtPainter::drawPolygon( QPainter *painter, const QPolygonF &polygon ) +{ + QRectF clipRect; + const bool deviceClipping = qwtIsClippingNeeded( painter, clipRect ); + + QPolygonF cpa = polygon; + if ( deviceClipping ) + cpa = QwtClipper::clipPolygonF( clipRect, polygon ); + + painter->drawPolygon( cpa ); +} + +//! Wrapper for QPainter::drawPolyline() +void QwtPainter::drawPolyline( QPainter *painter, const QPolygonF &polygon ) +{ + QRectF clipRect; + const bool deviceClipping = qwtIsClippingNeeded( painter, clipRect ); + + QPolygonF cpa = polygon; + if ( deviceClipping ) + cpa = QwtClipper::clipPolygonF( clipRect, cpa ); + + qwtDrawPolyline( painter, + cpa.constData(), cpa.size(), d_polylineSplitting ); +} + +//! Wrapper for QPainter::drawPolyline() +void QwtPainter::drawPolyline( QPainter *painter, + const QPointF *points, int pointCount ) +{ + QRectF clipRect; + const bool deviceClipping = qwtIsClippingNeeded( painter, clipRect ); + + if ( deviceClipping ) + { + QPolygonF polygon( pointCount ); + ::memcpy( polygon.data(), points, pointCount * sizeof( QPointF ) ); + + polygon = QwtClipper::clipPolygonF( clipRect, polygon ); + qwtDrawPolyline( painter, + polygon.constData(), polygon.size(), d_polylineSplitting ); + } + else + { + qwtDrawPolyline( painter, points, pointCount, d_polylineSplitting ); + } +} + +//! Wrapper for QPainter::drawPolygon() +void QwtPainter::drawPolygon( QPainter *painter, const QPolygon &polygon ) +{ + QRectF clipRect; + const bool deviceClipping = qwtIsClippingNeeded( painter, clipRect ); + + QPolygon cpa = polygon; + if ( deviceClipping ) + cpa = QwtClipper::clipPolygon( clipRect, polygon ); + + painter->drawPolygon( cpa ); +} + +//! Wrapper for QPainter::drawPolyline() +void QwtPainter::drawPolyline( QPainter *painter, const QPolygon &polygon ) +{ + QRectF clipRect; + const bool deviceClipping = qwtIsClippingNeeded( painter, clipRect ); + + QPolygon cpa = polygon; + if ( deviceClipping ) + cpa = QwtClipper::clipPolygon( clipRect, cpa ); + + qwtDrawPolyline( painter, + cpa.constData(), cpa.size(), d_polylineSplitting ); +} + +//! Wrapper for QPainter::drawPolyline() +void QwtPainter::drawPolyline( QPainter *painter, + const QPoint *points, int pointCount ) +{ + QRectF clipRect; + const bool deviceClipping = qwtIsClippingNeeded( painter, clipRect ); + + if ( deviceClipping ) + { + QPolygon polygon( pointCount ); + ::memcpy( polygon.data(), points, pointCount * sizeof( QPoint ) ); + + polygon = QwtClipper::clipPolygon( clipRect, polygon ); + qwtDrawPolyline( painter, + polygon.constData(), polygon.size(), d_polylineSplitting ); + } + else + qwtDrawPolyline( painter, points, pointCount, d_polylineSplitting ); +} + +//! Wrapper for QPainter::drawPoint() +void QwtPainter::drawPoint( QPainter *painter, const QPointF &pos ) +{ + QRectF clipRect; + const bool deviceClipping = qwtIsClippingNeeded( painter, clipRect ); + + if ( deviceClipping && !clipRect.contains( pos ) ) + return; + + painter->drawPoint( pos ); +} + +//! Wrapper for QPainter::drawPoint() +void QwtPainter::drawPoint( QPainter *painter, const QPoint &pos ) +{ + QRectF clipRect; + const bool deviceClipping = qwtIsClippingNeeded( painter, clipRect ); + + if ( deviceClipping ) + { + const int minX = qCeil( clipRect.left() ); + const int maxX = qFloor( clipRect.right() ); + const int minY = qCeil( clipRect.top() ); + const int maxY = qFloor( clipRect.bottom() ); + + if ( pos.x() < minX || pos.x() > maxX + || pos.y() < minY || pos.y() > maxY ) + { + return; + } + } + + painter->drawPoint( pos ); +} + +//! Wrapper for QPainter::drawPoints() +void QwtPainter::drawPoints( QPainter *painter, + const QPoint *points, int pointCount ) +{ + QRectF clipRect; + const bool deviceClipping = qwtIsClippingNeeded( painter, clipRect ); + + if ( deviceClipping ) + { + const int minX = qCeil( clipRect.left() ); + const int maxX = qFloor( clipRect.right() ); + const int minY = qCeil( clipRect.top() ); + const int maxY = qFloor( clipRect.bottom() ); + + const QRect r( minX, minY, maxX - minX, maxY - minY ); + + QPolygon clippedPolygon( pointCount ); + QPoint *clippedData = clippedPolygon.data(); + + int numClippedPoints = 0; + for ( int i = 0; i < pointCount; i++ ) + { + if ( r.contains( points[i] ) ) + clippedData[ numClippedPoints++ ] = points[i]; + } + painter->drawPoints( clippedData, numClippedPoints ); + } + else + { + painter->drawPoints( points, pointCount ); + } +} + +//! Wrapper for QPainter::drawPoints() +void QwtPainter::drawPoints( QPainter *painter, + const QPointF *points, int pointCount ) +{ + QRectF clipRect; + const bool deviceClipping = qwtIsClippingNeeded( painter, clipRect ); + + if ( deviceClipping ) + { + QPolygonF clippedPolygon( pointCount ); + QPointF *clippedData = clippedPolygon.data(); + + int numClippedPoints = 0; + for ( int i = 0; i < pointCount; i++ ) + { + if ( clipRect.contains( points[i] ) ) + clippedData[ numClippedPoints++ ] = points[i]; + } + painter->drawPoints( clippedData, numClippedPoints ); + } + else + { + painter->drawPoints( points, pointCount ); + } +} + +//! Wrapper for QPainter::drawImage() +void QwtPainter::drawImage( QPainter *painter, + const QRectF &rect, const QImage &image ) +{ + const QRect alignedRect = rect.toAlignedRect(); + + if ( alignedRect != rect ) + { + const QRectF clipRect = rect.adjusted( 0.0, 0.0, -1.0, -1.0 ); + + painter->save(); + painter->setClipRect( clipRect, Qt::IntersectClip ); + painter->drawImage( alignedRect, image ); + painter->restore(); + } + else + { + painter->drawImage( alignedRect, image ); + } +} + +//! Wrapper for QPainter::drawPixmap() +void QwtPainter::drawPixmap( QPainter *painter, + const QRectF &rect, const QPixmap &pixmap ) +{ + const QRect alignedRect = rect.toAlignedRect(); + + if ( alignedRect != rect ) + { + const QRectF clipRect = rect.adjusted( 0.0, 0.0, -1.0, -1.0 ); + + painter->save(); + painter->setClipRect( clipRect, Qt::IntersectClip ); + painter->drawPixmap( alignedRect, pixmap ); + painter->restore(); + } + else + { + painter->drawPixmap( alignedRect, pixmap ); + } +} + +//! Draw a focus rectangle on a widget using its style. +void QwtPainter::drawFocusRect( QPainter *painter, const QWidget *widget ) +{ + drawFocusRect( painter, widget, widget->rect() ); +} + +//! Draw a focus rectangle on a widget using its style. +void QwtPainter::drawFocusRect( QPainter *painter, const QWidget *widget, + const QRect &rect ) +{ + QStyleOptionFocusRect opt; + opt.init( widget ); + opt.rect = rect; + opt.state |= QStyle::State_HasFocus; + + widget->style()->drawPrimitive( QStyle::PE_FrameFocusRect, + &opt, painter, widget ); +} + +/*! + Draw a round frame + + \param painter Painter + \param rect Frame rectangle + \param palette QPalette::WindowText is used for plain borders + QPalette::Dark and QPalette::Light for raised + or sunken borders + \param lineWidth Line width + \param frameStyle bitwise OR´ed value of QFrame::Shape and QFrame::Shadow +*/ +void QwtPainter::drawRoundFrame( QPainter *painter, + const QRectF &rect, const QPalette &palette, + int lineWidth, int frameStyle ) +{ + enum Style + { + Plain, + Sunken, + Raised + }; + + Style style = Plain; + if ( (frameStyle & QFrame::Sunken) == QFrame::Sunken ) + style = Sunken; + else if ( (frameStyle & QFrame::Raised) == QFrame::Raised ) + style = Raised; + + const double lw2 = 0.5 * lineWidth; + QRectF r = rect.adjusted( lw2, lw2, -lw2, -lw2 ); + + QBrush brush; + + if ( style != Plain ) + { + QColor c1 = palette.color( QPalette::Light ); + QColor c2 = palette.color( QPalette::Dark ); + + if ( style == Sunken ) + qSwap( c1, c2 ); + + QLinearGradient gradient( r.topLeft(), r.bottomRight() ); + gradient.setColorAt( 0.0, c1 ); +#if 0 + gradient.setColorAt( 0.3, c1 ); + gradient.setColorAt( 0.7, c2 ); +#endif + gradient.setColorAt( 1.0, c2 ); + + brush = QBrush( gradient ); + } + else // Plain + { + brush = palette.brush( QPalette::WindowText ); + } + + painter->save(); + + painter->setPen( QPen( brush, lineWidth ) ); + painter->setBrush( Qt::NoBrush ); + + painter->drawEllipse( r ); + + painter->restore(); +} + +/*! + Draw a rectangular frame + + \param painter Painter + \param rect Frame rectangle + \param palette Palette + \param foregroundRole Foreground role used for QFrame::Plain + \param frameWidth Frame width + \param midLineWidth Used for QFrame::Box + \param frameStyle bitwise OR´ed value of QFrame::Shape and QFrame::Shadow +*/ +void QwtPainter::drawFrame( QPainter *painter, const QRectF &rect, + const QPalette &palette, QPalette::ColorRole foregroundRole, + int frameWidth, int midLineWidth, int frameStyle ) +{ + if ( frameWidth <= 0 || rect.isEmpty() ) + return; + + const int shadow = frameStyle & QFrame::Shadow_Mask; + + painter->save(); + + if ( shadow == QFrame::Plain ) + { + const QRectF outerRect = rect.adjusted( 0.0, 0.0, -1.0, -1.0 ); + const QRectF innerRect = outerRect.adjusted( + frameWidth, frameWidth, -frameWidth, -frameWidth ); + + QPainterPath path; + path.addRect( outerRect ); + path.addRect( innerRect ); + + painter->setPen( Qt::NoPen ); + painter->setBrush( palette.color( foregroundRole ) ); + + painter->drawPath( path ); + } + else + { + const int shape = frameStyle & QFrame::Shape_Mask; + + if ( shape == QFrame::Box ) + { + const QRectF outerRect = rect.adjusted( 0.0, 0.0, -1.0, -1.0 ); + const QRectF midRect1 = outerRect.adjusted( + frameWidth, frameWidth, -frameWidth, -frameWidth ); + const QRectF midRect2 = midRect1.adjusted( + midLineWidth, midLineWidth, -midLineWidth, -midLineWidth ); + + const QRectF innerRect = midRect2.adjusted( + frameWidth, frameWidth, -frameWidth, -frameWidth ); + + QPainterPath path1; + path1.moveTo( outerRect.bottomLeft() ); + path1.lineTo( outerRect.topLeft() ); + path1.lineTo( outerRect.topRight() ); + path1.lineTo( midRect1.topRight() ); + path1.lineTo( midRect1.topLeft() ); + path1.lineTo( midRect1.bottomLeft() ); + + QPainterPath path2; + path2.moveTo( outerRect.bottomLeft() ); + path2.lineTo( outerRect.bottomRight() ); + path2.lineTo( outerRect.topRight() ); + path2.lineTo( midRect1.topRight() ); + path2.lineTo( midRect1.bottomRight() ); + path2.lineTo( midRect1.bottomLeft() ); + + QPainterPath path3; + path3.moveTo( midRect2.bottomLeft() ); + path3.lineTo( midRect2.topLeft() ); + path3.lineTo( midRect2.topRight() ); + path3.lineTo( innerRect.topRight() ); + path3.lineTo( innerRect.topLeft() ); + path3.lineTo( innerRect.bottomLeft() ); + + QPainterPath path4; + path4.moveTo( midRect2.bottomLeft() ); + path4.lineTo( midRect2.bottomRight() ); + path4.lineTo( midRect2.topRight() ); + path4.lineTo( innerRect.topRight() ); + path4.lineTo( innerRect.bottomRight() ); + path4.lineTo( innerRect.bottomLeft() ); + + QPainterPath path5; + path5.addRect( midRect1 ); + path5.addRect( midRect2 ); + + painter->setPen( Qt::NoPen ); + + QBrush brush1 = palette.dark().color(); + QBrush brush2 = palette.light().color(); + + if ( shadow == QFrame::Raised ) + qSwap( brush1, brush2 ); + + painter->setBrush( brush1 ); + painter->drawPath( path1 ); + painter->drawPath( path4 ); + + painter->setBrush( brush2 ); + painter->drawPath( path2 ); + painter->drawPath( path3 ); + + painter->setBrush( palette.mid() ); + painter->drawPath( path5 ); + } +#if 0 + // qDrawWinPanel doesn't result in something nice + // on a scalable document like PDF. Better draw a + // Panel. + + else if ( shape == QFrame::WinPanel ) + { + painter->setRenderHint( QPainter::NonCosmeticDefaultPen, true ); + qDrawWinPanel ( painter, rect.toRect(), palette, + frameStyle & QFrame::Sunken ); + } + else if ( shape == QFrame::StyledPanel ) + { + } +#endif + else + { + const QRectF outerRect = rect.adjusted( 0.0, 0.0, -1.0, -1.0 ); + const QRectF innerRect = outerRect.adjusted( + frameWidth - 1.0, frameWidth - 1.0, + -( frameWidth - 1.0 ), -( frameWidth - 1.0 ) ); + + QPainterPath path1; + path1.moveTo( outerRect.bottomLeft() ); + path1.lineTo( outerRect.topLeft() ); + path1.lineTo( outerRect.topRight() ); + path1.lineTo( innerRect.topRight() ); + path1.lineTo( innerRect.topLeft() ); + path1.lineTo( innerRect.bottomLeft() ); + + + QPainterPath path2; + path2.moveTo( outerRect.bottomLeft() ); + path2.lineTo( outerRect.bottomRight() ); + path2.lineTo( outerRect.topRight() ); + path2.lineTo( innerRect.topRight() ); + path2.lineTo( innerRect.bottomRight() ); + path2.lineTo( innerRect.bottomLeft() ); + + painter->setPen( Qt::NoPen ); + + QBrush brush1 = palette.dark().color(); + QBrush brush2 = palette.light().color(); + + if ( shadow == QFrame::Raised ) + qSwap( brush1, brush2 ); + + painter->setBrush( brush1 ); + painter->drawPath( path1 ); + + painter->setBrush( brush2 ); + painter->drawPath( path2 ); + } + + } + + painter->restore(); +} + +/*! + Draw a rectangular frame with rounded borders + + \param painter Painter + \param rect Frame rectangle + \param xRadius x-radius of the ellipses defining the corners + \param yRadius y-radius of the ellipses defining the corners + \param palette QPalette::WindowText is used for plain borders + QPalette::Dark and QPalette::Light for raised + or sunken borders + \param lineWidth Line width + \param frameStyle bitwise OR´ed value of QFrame::Shape and QFrame::Shadow +*/ + +void QwtPainter::drawRoundedFrame( QPainter *painter, + const QRectF &rect, double xRadius, double yRadius, + const QPalette &palette, int lineWidth, int frameStyle ) +{ + painter->save(); + painter->setRenderHint( QPainter::Antialiasing, true ); + painter->setBrush( Qt::NoBrush ); + + double lw2 = lineWidth * 0.5; + QRectF r = rect.adjusted( lw2, lw2, -lw2, -lw2 ); + + QPainterPath path; + path.addRoundedRect( r, xRadius, yRadius ); + + enum Style + { + Plain, + Sunken, + Raised + }; + + Style style = Plain; + if ( (frameStyle & QFrame::Sunken) == QFrame::Sunken ) + style = Sunken; + else if ( (frameStyle & QFrame::Raised) == QFrame::Raised ) + style = Raised; + + if ( style != Plain && path.elementCount() == 17 ) + { + // move + 4 * ( cubicTo + lineTo ) + QPainterPath pathList[8]; + + for ( int i = 0; i < 4; i++ ) + { + const int j = i * 4 + 1; + + pathList[ 2 * i ].moveTo( + path.elementAt(j - 1).x, path.elementAt( j - 1 ).y + ); + + pathList[ 2 * i ].cubicTo( + path.elementAt(j + 0).x, path.elementAt(j + 0).y, + path.elementAt(j + 1).x, path.elementAt(j + 1).y, + path.elementAt(j + 2).x, path.elementAt(j + 2).y ); + + pathList[ 2 * i + 1 ].moveTo( + path.elementAt(j + 2).x, path.elementAt(j + 2).y + ); + pathList[ 2 * i + 1 ].lineTo( + path.elementAt(j + 3).x, path.elementAt(j + 3).y + ); + } + + QColor c1( palette.color( QPalette::Dark ) ); + QColor c2( palette.color( QPalette::Light ) ); + + if ( style == Raised ) + qSwap( c1, c2 ); + + for ( int i = 0; i < 4; i++ ) + { + QRectF r = pathList[2 * i].controlPointRect(); + + QPen arcPen; + arcPen.setCapStyle( Qt::FlatCap ); + arcPen.setWidth( lineWidth ); + + QPen linePen; + linePen.setCapStyle( Qt::FlatCap ); + linePen.setWidth( lineWidth ); + + switch( i ) + { + case 0: + { + arcPen.setColor( c1 ); + linePen.setColor( c1 ); + break; + } + case 1: + { + QLinearGradient gradient; + gradient.setStart( r.topLeft() ); + gradient.setFinalStop( r.bottomRight() ); + gradient.setColorAt( 0.0, c1 ); + gradient.setColorAt( 1.0, c2 ); + + arcPen.setBrush( gradient ); + linePen.setColor( c2 ); + break; + } + case 2: + { + arcPen.setColor( c2 ); + linePen.setColor( c2 ); + break; + } + case 3: + { + QLinearGradient gradient; + + gradient.setStart( r.bottomRight() ); + gradient.setFinalStop( r.topLeft() ); + gradient.setColorAt( 0.0, c2 ); + gradient.setColorAt( 1.0, c1 ); + + arcPen.setBrush( gradient ); + linePen.setColor( c1 ); + break; + } + } + + + painter->setPen( arcPen ); + painter->drawPath( pathList[ 2 * i] ); + + painter->setPen( linePen ); + painter->drawPath( pathList[ 2 * i + 1] ); + } + } + else + { + QPen pen( palette.color( QPalette::WindowText ), lineWidth ); + painter->setPen( pen ); + painter->drawPath( path ); + } + + painter->restore(); +} + +/*! + Draw a color bar into a rectangle + + \param painter Painter + \param colorMap Color map + \param interval Value range + \param scaleMap Scale map + \param orientation Orientation + \param rect Traget rectangle +*/ +void QwtPainter::drawColorBar( QPainter *painter, + const QwtColorMap &colorMap, const QwtInterval &interval, + const QwtScaleMap &scaleMap, Qt::Orientation orientation, + const QRectF &rect ) +{ + QVector colorTable; + if ( colorMap.format() == QwtColorMap::Indexed ) + colorTable = colorMap.colorTable( interval ); + + QColor c; + + const QRect devRect = rect.toAlignedRect(); + + /* + We paint to a pixmap first to have something scalable for printing + ( f.e. in a Pdf document ) + */ + + QPixmap pixmap( devRect.size() ); + QPainter pmPainter( &pixmap ); + pmPainter.translate( -devRect.x(), -devRect.y() ); + + if ( orientation == Qt::Horizontal ) + { + QwtScaleMap sMap = scaleMap; + sMap.setPaintInterval( rect.left(), rect.right() ); + + for ( int x = devRect.left(); x <= devRect.right(); x++ ) + { + const double value = sMap.invTransform( x ); + + if ( colorMap.format() == QwtColorMap::RGB ) + c.setRgb( colorMap.rgb( interval, value ) ); + else + c = colorTable[colorMap.colorIndex( interval, value )]; + + pmPainter.setPen( c ); + pmPainter.drawLine( x, devRect.top(), x, devRect.bottom() ); + } + } + else // Vertical + { + QwtScaleMap sMap = scaleMap; + sMap.setPaintInterval( rect.bottom(), rect.top() ); + + for ( int y = devRect.top(); y <= devRect.bottom(); y++ ) + { + const double value = sMap.invTransform( y ); + + if ( colorMap.format() == QwtColorMap::RGB ) + c.setRgb( colorMap.rgb( interval, value ) ); + else + c = colorTable[colorMap.colorIndex( interval, value )]; + + pmPainter.setPen( c ); + pmPainter.drawLine( devRect.left(), y, devRect.right(), y ); + } + } + pmPainter.end(); + + drawPixmap( painter, rect, pixmap ); +} + +static inline void qwtFillRect( const QWidget *widget, QPainter *painter, + const QRect &rect, const QBrush &brush) +{ + if ( brush.style() == Qt::TexturePattern ) + { + painter->save(); + + painter->setClipRect( rect ); + painter->drawTiledPixmap(rect, brush.texture(), rect.topLeft()); + + painter->restore(); + } + else if ( brush.gradient() ) + { + painter->save(); + + painter->setClipRect( rect ); + painter->fillRect(0, 0, widget->width(), + widget->height(), brush); + + painter->restore(); + } + else + { + painter->fillRect(rect, brush); + } +} + +/*! + Fill a pixmap with the content of a widget + + In Qt >= 5.0 QPixmap::fill() is a nop, in Qt 4.x it is buggy + for backgrounds with gradients. Thus fillPixmap() offers + an alternative implementation. + + \param widget Widget + \param pixmap Pixmap to be filled + \param offset Offset + + \sa QPixmap::fill() + */ +void QwtPainter::fillPixmap( const QWidget *widget, + QPixmap &pixmap, const QPoint &offset ) +{ + const QRect rect( offset, pixmap.size() ); + + QPainter painter( &pixmap ); + painter.translate( -offset ); + + const QBrush autoFillBrush = + widget->palette().brush( widget->backgroundRole() ); + + if ( !( widget->autoFillBackground() && autoFillBrush.isOpaque() ) ) + { + const QBrush bg = widget->palette().brush( QPalette::Window ); + qwtFillRect( widget, &painter, rect, bg); + } + + if ( widget->autoFillBackground() ) + qwtFillRect( widget, &painter, rect, autoFillBrush); + + if ( widget->testAttribute(Qt::WA_StyledBackground) ) + { + painter.setClipRegion( rect ); + + QStyleOption opt; + opt.initFrom( widget ); + widget->style()->drawPrimitive( QStyle::PE_Widget, + &opt, &painter, widget ); + } +} + +/*! + Fill rect with the background of a widget + + \param painter Painter + \param rect Rectangle to be filled + \param widget Widget + + \sa QStyle::PE_Widget, QWidget::backgroundRole() + */ +void QwtPainter::drawBackgound( QPainter *painter, + const QRectF &rect, const QWidget *widget ) +{ + if ( widget->testAttribute( Qt::WA_StyledBackground ) ) + { + QStyleOption opt; + opt.initFrom( widget ); + opt.rect = rect.toAlignedRect(); + + widget->style()->drawPrimitive( + QStyle::PE_Widget, &opt, painter, widget); + } + else + { + const QBrush brush = + widget->palette().brush( widget->backgroundRole() ); + + painter->fillRect( rect, brush ); + } +} + +/*! + \return A pixmap that can be used as backing store + + \param widget Widget, for which the backinstore is intended + \param size Size of the pixmap + */ +QPixmap QwtPainter::backingStore( QWidget *widget, const QSize &size ) +{ + QPixmap pm; + +#define QWT_HIGH_DPI 1 + +#if QT_VERSION >= 0x050000 && QWT_HIGH_DPI + qreal pixelRatio = 1.0; + + if ( widget && widget->windowHandle() ) + { + pixelRatio = widget->windowHandle()->devicePixelRatio(); + } + else + { + if ( qApp ) + pixelRatio = qApp->devicePixelRatio(); + } + + pm = QPixmap( size * pixelRatio ); + pm.setDevicePixelRatio( pixelRatio ); +#else + Q_UNUSED( widget ) + pm = QPixmap( size ); +#endif + +#if QT_VERSION < 0x050000 +#ifdef Q_WS_X11 + if ( widget && isX11GraphicsSystem() ) + { + if ( pm.x11Info().screen() != widget->x11Info().screen() ) + pm.x11SetScreen( widget->x11Info().screen() ); + } +#endif +#endif + + return pm; +} + diff --git a/ThirdParty/Qwt/src/qwt_painter.h b/ThirdParty/Qwt/src/qwt_painter.h new file mode 100644 index 0000000000..9609b6935f --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_painter.h @@ -0,0 +1,188 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#ifndef QWT_PAINTER_H +#define QWT_PAINTER_H + +#include "qwt_global.h" + +#include +#include +#include +#include +#include + +class QPainter; +class QBrush; +class QColor; +class QWidget; +class QPolygonF; +class QRectF; +class QImage; +class QPixmap; +class QwtScaleMap; +class QwtColorMap; +class QwtInterval; + +class QTextDocument; +class QPainterPath; + +/*! + \brief A collection of QPainter workarounds +*/ +class QWT_EXPORT QwtPainter +{ +public: + static void setPolylineSplitting( bool ); + static bool polylineSplitting(); + + static void setRoundingAlignment( bool ); + static bool roundingAlignment(); + static bool roundingAlignment(QPainter *); + + static void drawText( QPainter *, double x, double y, const QString & ); + static void drawText( QPainter *, const QPointF &, const QString & ); + static void drawText( QPainter *, double x, double y, double w, double h, + int flags, const QString & ); + static void drawText( QPainter *, const QRectF &, + int flags, const QString & ); + +#ifndef QT_NO_RICHTEXT + static void drawSimpleRichText( QPainter *, const QRectF &, + int flags, const QTextDocument & ); +#endif + + static void drawRect( QPainter *, double x, double y, double w, double h ); + static void drawRect( QPainter *, const QRectF &rect ); + static void fillRect( QPainter *, const QRectF &, const QBrush & ); + + static void drawEllipse( QPainter *, const QRectF & ); + static void drawPie( QPainter *, const QRectF & r, int a, int alen ); + + static void drawLine( QPainter *, double x1, double y1, double x2, double y2 ); + static void drawLine( QPainter *, const QPointF &p1, const QPointF &p2 ); + static void drawLine( QPainter *, const QLineF & ); + + static void drawPolygon( QPainter *, const QPolygonF & ); + static void drawPolyline( QPainter *, const QPolygonF & ); + static void drawPolyline( QPainter *, const QPointF *, int pointCount ); + + static void drawPolygon( QPainter *, const QPolygon & ); + static void drawPolyline( QPainter *, const QPolygon & ); + static void drawPolyline( QPainter *, const QPoint *, int pointCount ); + + static void drawPoint( QPainter *, const QPoint & ); + static void drawPoints( QPainter *, const QPolygon & ); + static void drawPoints( QPainter *, const QPoint *, int pointCount ); + + static void drawPoint( QPainter *, double x, double y ); + static void drawPoint( QPainter *, const QPointF & ); + static void drawPoints( QPainter *, const QPolygonF & ); + static void drawPoints( QPainter *, const QPointF *, int pointCount ); + + static void drawPath( QPainter *, const QPainterPath & ); + static void drawImage( QPainter *, const QRectF &, const QImage & ); + static void drawPixmap( QPainter *, const QRectF &, const QPixmap & ); + + static void drawRoundFrame( QPainter *, + const QRectF &, const QPalette &, int lineWidth, int frameStyle ); + + static void drawRoundedFrame( QPainter *, + const QRectF &, double xRadius, double yRadius, + const QPalette &, int lineWidth, int frameStyle ); + + static void drawFrame( QPainter *, const QRectF &rect, + const QPalette &palette, QPalette::ColorRole foregroundRole, + int lineWidth, int midLineWidth, int frameStyle ); + + static void drawFocusRect( QPainter *, const QWidget * ); + static void drawFocusRect( QPainter *, const QWidget *, const QRect & ); + + static void drawColorBar( QPainter *painter, + const QwtColorMap &, const QwtInterval &, + const QwtScaleMap &, Qt::Orientation, const QRectF & ); + + static bool isAligning( QPainter *painter ); + static bool isX11GraphicsSystem(); + + static void fillPixmap( const QWidget *, + QPixmap &, const QPoint &offset = QPoint() ); + + static void drawBackgound( QPainter *painter, + const QRectF &rect, const QWidget *widget ); + + static QPixmap backingStore( QWidget *, const QSize & ); + +private: + static bool d_polylineSplitting; + static bool d_roundingAlignment; +}; + +//! Wrapper for QPainter::drawPoint() +inline void QwtPainter::drawPoint( QPainter *painter, double x, double y ) +{ + QwtPainter::drawPoint( painter, QPointF( x, y ) ); +} + +//! Wrapper for QPainter::drawPoints() +inline void QwtPainter::drawPoints( QPainter *painter, const QPolygon &polygon ) +{ + drawPoints( painter, polygon.data(), polygon.size() ); +} + +//! Wrapper for QPainter::drawPoints() +inline void QwtPainter::drawPoints( QPainter *painter, const QPolygonF &polygon ) +{ + drawPoints( painter, polygon.data(), polygon.size() ); +} + +//! Wrapper for QPainter::drawLine() +inline void QwtPainter::drawLine( QPainter *painter, + double x1, double y1, double x2, double y2 ) +{ + QwtPainter::drawLine( painter, QPointF( x1, y1 ), QPointF( x2, y2 ) ); +} + +//! Wrapper for QPainter::drawLine() +inline void QwtPainter::drawLine( QPainter *painter, const QLineF &line ) +{ + QwtPainter::drawLine( painter, line.p1(), line.p2() ); +} + +/*! + \return True, when line splitting for the raster paint engine is enabled. + \sa setPolylineSplitting() +*/ +inline bool QwtPainter::polylineSplitting() +{ + return d_polylineSplitting; +} + +/*! + Check whether coordinates should be rounded, before they are painted + to a paint engine that rounds to integer values. For other paint engines + ( PDF, SVG ), this flag has no effect. + + \return True, when rounding is enabled + \sa setRoundingAlignment(), isAligning() +*/ +inline bool QwtPainter::roundingAlignment() +{ + return d_roundingAlignment; +} + +/*! + \return roundingAlignment() && isAligning(painter); + \param painter Painter +*/ +inline bool QwtPainter::roundingAlignment(QPainter *painter) +{ + return d_roundingAlignment && isAligning(painter); +} +#endif diff --git a/ThirdParty/Qwt/src/qwt_painter_command.cpp b/ThirdParty/Qwt/src/qwt_painter_command.cpp new file mode 100644 index 0000000000..f6affae37e --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_painter_command.cpp @@ -0,0 +1,237 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#include "qwt_painter_command.h" + +//! Construct an invalid command +QwtPainterCommand::QwtPainterCommand(): + d_type( Invalid ) +{ +} + +//! Copy constructor +QwtPainterCommand::QwtPainterCommand( const QPainterPath &path ): + d_type( Path ) +{ + d_path = new QPainterPath( path ); +} + +/*! + Constructor for Pixmap paint operation + + \param rect Target rectangle + \param pixmap Pixmap + \param subRect Rectangle inside the pixmap + + \sa QPainter::drawPixmap() + */ +QwtPainterCommand::QwtPainterCommand( const QRectF &rect, + const QPixmap &pixmap, const QRectF& subRect ): + d_type( Pixmap ) +{ + d_pixmapData = new PixmapData(); + d_pixmapData->rect = rect; + d_pixmapData->pixmap = pixmap; + d_pixmapData->subRect = subRect; +} + +/*! + Constructor for Image paint operation + + \param rect Target rectangle + \param image Image + \param subRect Rectangle inside the image + \param flags Conversion flags + + \sa QPainter::drawImage() + */ +QwtPainterCommand::QwtPainterCommand( const QRectF &rect, + const QImage &image, const QRectF& subRect, + Qt::ImageConversionFlags flags ): + d_type( Image ) +{ + d_imageData = new ImageData(); + d_imageData->rect = rect; + d_imageData->image = image; + d_imageData->subRect = subRect; + d_imageData->flags = flags; +} + +/*! + Constructor for State paint operation + \param state Paint engine state + */ +QwtPainterCommand::QwtPainterCommand( const QPaintEngineState &state ): + d_type( State ) +{ + d_stateData = new StateData(); + + d_stateData->flags = state.state(); + + if ( d_stateData->flags & QPaintEngine::DirtyPen ) + d_stateData->pen = state.pen(); + + if ( d_stateData->flags & QPaintEngine::DirtyBrush ) + d_stateData->brush = state.brush(); + + if ( d_stateData->flags & QPaintEngine::DirtyBrushOrigin ) + d_stateData->brushOrigin = state.brushOrigin(); + + if ( d_stateData->flags & QPaintEngine::DirtyFont ) + d_stateData->font = state.font(); + + if ( d_stateData->flags & QPaintEngine::DirtyBackground ) + { + d_stateData->backgroundMode = state.backgroundMode(); + d_stateData->backgroundBrush = state.backgroundBrush(); + } + + if ( d_stateData->flags & QPaintEngine::DirtyTransform ) + d_stateData->transform = state.transform(); + + if ( d_stateData->flags & QPaintEngine::DirtyClipEnabled ) + d_stateData->isClipEnabled = state.isClipEnabled(); + + if ( d_stateData->flags & QPaintEngine::DirtyClipRegion ) + { + d_stateData->clipRegion = state.clipRegion(); + d_stateData->clipOperation = state.clipOperation(); + } + + if ( d_stateData->flags & QPaintEngine::DirtyClipPath ) + { + d_stateData->clipPath = state.clipPath(); + d_stateData->clipOperation = state.clipOperation(); + } + + if ( d_stateData->flags & QPaintEngine::DirtyHints ) + d_stateData->renderHints = state.renderHints(); + + if ( d_stateData->flags & QPaintEngine::DirtyCompositionMode ) + d_stateData->compositionMode = state.compositionMode(); + + if ( d_stateData->flags & QPaintEngine::DirtyOpacity ) + d_stateData->opacity = state.opacity(); +} + +/*! + Copy constructor + \param other Command to be copied + + */ +QwtPainterCommand::QwtPainterCommand(const QwtPainterCommand &other) +{ + copy( other ); +} + +//! Destructor +QwtPainterCommand::~QwtPainterCommand() +{ + reset(); +} + +/*! + Assignment operator + + \param other Command to be copied + \return Modified command + */ +QwtPainterCommand &QwtPainterCommand::operator=(const QwtPainterCommand &other) +{ + reset(); + copy( other ); + + return *this; +} + +void QwtPainterCommand::copy( const QwtPainterCommand &other ) +{ + d_type = other.d_type; + + switch( other.d_type ) + { + case Path: + { + d_path = new QPainterPath( *other.d_path ); + break; + } + case Pixmap: + { + d_pixmapData = new PixmapData( *other.d_pixmapData ); + break; + } + case Image: + { + d_imageData = new ImageData( *other.d_imageData ); + break; + } + case State: + { + d_stateData = new StateData( *other.d_stateData ); + break; + } + default: + break; + } +} + +void QwtPainterCommand::reset() +{ + switch( d_type ) + { + case Path: + { + delete d_path; + break; + } + case Pixmap: + { + delete d_pixmapData; + break; + } + case Image: + { + delete d_imageData; + break; + } + case State: + { + delete d_stateData; + break; + } + default: + break; + } + + d_type = Invalid; +} + +//! \return Painter path to be painted +QPainterPath *QwtPainterCommand::path() +{ + return d_path; +} + +//! \return Attributes how to paint a QPixmap +QwtPainterCommand::PixmapData* QwtPainterCommand::pixmapData() +{ + return d_pixmapData; +} + +//! \return Attributes how to paint a QImage +QwtPainterCommand::ImageData* QwtPainterCommand::imageData() +{ + return d_imageData; +} + +//! \return Attributes of a state change +QwtPainterCommand::StateData* QwtPainterCommand::stateData() +{ + return d_stateData; +} diff --git a/ThirdParty/Qwt/src/qwt_painter_command.h b/ThirdParty/Qwt/src/qwt_painter_command.h new file mode 100644 index 0000000000..2da597a7fa --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_painter_command.h @@ -0,0 +1,173 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#ifndef QWT_PAINTER_COMMAND_H +#define QWT_PAINTER_COMMAND_H + +#include "qwt_global.h" +#include +#include +#include +#include + +class QPainterPath; + +/*! + QwtPainterCommand represents the attributes of a paint operation + how it is used between QPainter and QPaintDevice + + It is used by QwtGraphic to record and replay paint operations + + \sa QwtGraphic::commands() + */ + +class QWT_EXPORT QwtPainterCommand +{ +public: + //! Type of the paint command + enum Type + { + //! Invalid command + Invalid = -1, + + //! Draw a QPainterPath + Path, + + //! Draw a QPixmap + Pixmap, + + //! Draw a QImage + Image, + + //! QPainter state change + State + }; + + //! Attributes how to paint a QPixmap + struct PixmapData + { + QRectF rect; + QPixmap pixmap; + QRectF subRect; + }; + + //! Attributes how to paint a QImage + struct ImageData + { + QRectF rect; + QImage image; + QRectF subRect; + Qt::ImageConversionFlags flags; + }; + + //! Attributes of a state change + struct StateData + { + QPaintEngine::DirtyFlags flags; + + QPen pen; + QBrush brush; + QPointF brushOrigin; + QBrush backgroundBrush; + Qt::BGMode backgroundMode; + QFont font; + QMatrix matrix; + QTransform transform; + + Qt::ClipOperation clipOperation; + QRegion clipRegion; + QPainterPath clipPath; + bool isClipEnabled; + + QPainter::RenderHints renderHints; + QPainter::CompositionMode compositionMode; + qreal opacity; + }; + + QwtPainterCommand(); + QwtPainterCommand(const QwtPainterCommand &); + + QwtPainterCommand( const QPainterPath & ); + + QwtPainterCommand( const QRectF &rect, + const QPixmap &, const QRectF& subRect ); + + QwtPainterCommand( const QRectF &rect, + const QImage &, const QRectF& subRect, + Qt::ImageConversionFlags ); + + QwtPainterCommand( const QPaintEngineState & ); + + ~QwtPainterCommand(); + + QwtPainterCommand &operator=(const QwtPainterCommand & ); + + Type type() const; + + QPainterPath *path(); + const QPainterPath *path() const; + + PixmapData* pixmapData(); + const PixmapData* pixmapData() const; + + ImageData* imageData(); + const ImageData* imageData() const; + + StateData* stateData(); + const StateData* stateData() const; + +private: + void copy( const QwtPainterCommand & ); + void reset(); + + Type d_type; + + union + { + QPainterPath *d_path; + PixmapData *d_pixmapData; + ImageData *d_imageData; + StateData *d_stateData; + }; +}; + +//! \return Type of the command +inline QwtPainterCommand::Type QwtPainterCommand::type() const +{ + return d_type; +} + +//! \return Painter path to be painted +inline const QPainterPath *QwtPainterCommand::path() const +{ + return d_path; +} + +//! \return Attributes how to paint a QPixmap +inline const QwtPainterCommand::PixmapData* +QwtPainterCommand::pixmapData() const +{ + return d_pixmapData; +} + +//! \return Attributes how to paint a QImage +inline const QwtPainterCommand::ImageData * +QwtPainterCommand::imageData() const +{ + return d_imageData; +} + +//! \return Attributes of a state change +inline const QwtPainterCommand::StateData * +QwtPainterCommand::stateData() const +{ + return d_stateData; +} + +#endif diff --git a/ThirdParty/Qwt/src/qwt_panner.cpp b/ThirdParty/Qwt/src/qwt_panner.cpp new file mode 100644 index 0000000000..18497a9163 --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_panner.cpp @@ -0,0 +1,538 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#include "qwt_panner.h" +#include "qwt_picker.h" +#include "qwt_painter.h" +#include +#include +#include +#include +#include + +static QVector qwtActivePickers( QWidget *w ) +{ + QVector pickers; + + QObjectList children = w->children(); + for ( int i = 0; i < children.size(); i++ ) + { + QwtPicker *picker = qobject_cast( children[i] ); + if ( picker && picker->isEnabled() ) + pickers += picker; + } + + return pickers; +} + +class QwtPanner::PrivateData +{ +public: + PrivateData(): + button( Qt::LeftButton ), + buttonModifiers( Qt::NoModifier ), + abortKey( Qt::Key_Escape ), + abortKeyModifiers( Qt::NoModifier ), +#ifndef QT_NO_CURSOR + cursor( NULL ), + restoreCursor( NULL ), + hasCursor( false ), +#endif + isEnabled( false ) + { + orientations = Qt::Vertical | Qt::Horizontal; + } + + ~PrivateData() + { +#ifndef QT_NO_CURSOR + delete cursor; + delete restoreCursor; +#endif + } + + Qt::MouseButton button; + Qt::KeyboardModifiers buttonModifiers; + + int abortKey; + Qt::KeyboardModifiers abortKeyModifiers; + + QPoint initialPos; + QPoint pos; + + QPixmap pixmap; + QBitmap contentsMask; + +#ifndef QT_NO_CURSOR + QCursor *cursor; + QCursor *restoreCursor; + bool hasCursor; +#endif + bool isEnabled; + Qt::Orientations orientations; +}; + +/*! + Creates an panner that is enabled for the left mouse button. + + \param parent Parent widget to be panned +*/ +QwtPanner::QwtPanner( QWidget *parent ): + QWidget( parent ) +{ + d_data = new PrivateData(); + + setAttribute( Qt::WA_TransparentForMouseEvents ); + setAttribute( Qt::WA_NoSystemBackground ); + setFocusPolicy( Qt::NoFocus ); + hide(); + + setEnabled( true ); +} + +//! Destructor +QwtPanner::~QwtPanner() +{ + delete d_data; +} + +/*! + Change the mouse button and modifiers used for panning + The defaults are Qt::LeftButton and Qt::NoModifier +*/ +void QwtPanner::setMouseButton( Qt::MouseButton button, + Qt::KeyboardModifiers modifiers ) +{ + d_data->button = button; + d_data->buttonModifiers = modifiers; +} + +//! Get mouse button and modifiers used for panning +void QwtPanner::getMouseButton( Qt::MouseButton &button, + Qt::KeyboardModifiers &modifiers ) const +{ + button = d_data->button; + modifiers = d_data->buttonModifiers; +} + +/*! + Change the abort key + The defaults are Qt::Key_Escape and Qt::NoModifiers + + \param key Key ( See Qt::Keycode ) + \param modifiers Keyboard modifiers +*/ +void QwtPanner::setAbortKey( int key, + Qt::KeyboardModifiers modifiers ) +{ + d_data->abortKey = key; + d_data->abortKeyModifiers = modifiers; +} + +//! Get the abort key and modifiers +void QwtPanner::getAbortKey( int &key, + Qt::KeyboardModifiers &modifiers ) const +{ + key = d_data->abortKey; + modifiers = d_data->abortKeyModifiers; +} + +/*! + Change the cursor, that is active while panning + The default is the cursor of the parent widget. + + \param cursor New cursor + + \sa setCursor() +*/ +#ifndef QT_NO_CURSOR +void QwtPanner::setCursor( const QCursor &cursor ) +{ + d_data->cursor = new QCursor( cursor ); +} +#endif + +/*! + \return Cursor that is active while panning + \sa setCursor() +*/ +#ifndef QT_NO_CURSOR +const QCursor QwtPanner::cursor() const +{ + if ( d_data->cursor ) + return *d_data->cursor; + + if ( parentWidget() ) + return parentWidget()->cursor(); + + return QCursor(); +} +#endif + +/*! + \brief En/disable the panner + + When enabled is true an event filter is installed for + the observed widget, otherwise the event filter is removed. + + \param on true or false + \sa isEnabled(), eventFilter() +*/ +void QwtPanner::setEnabled( bool on ) +{ + if ( d_data->isEnabled != on ) + { + d_data->isEnabled = on; + + QWidget *w = parentWidget(); + if ( w ) + { + if ( d_data->isEnabled ) + { + w->installEventFilter( this ); + } + else + { + w->removeEventFilter( this ); + hide(); + } + } + } +} + +/*! + Set the orientations, where panning is enabled + The default value is in both directions: Qt::Horizontal | Qt::Vertical + + /param o Orientation +*/ +void QwtPanner::setOrientations( Qt::Orientations o ) +{ + d_data->orientations = o; +} + +//! Return the orientation, where paning is enabled +Qt::Orientations QwtPanner::orientations() const +{ + return d_data->orientations; +} + +/*! + \return True if an orientation is enabled + \sa orientations(), setOrientations() +*/ +bool QwtPanner::isOrientationEnabled( Qt::Orientation o ) const +{ + return d_data->orientations & o; +} + +/*! + \return true when enabled, false otherwise + \sa setEnabled, eventFilter() +*/ +bool QwtPanner::isEnabled() const +{ + return d_data->isEnabled; +} + +/*! + \brief Paint event + + Repaint the grabbed pixmap on its current position and + fill the empty spaces by the background of the parent widget. + + \param pe Paint event +*/ +void QwtPanner::paintEvent( QPaintEvent *pe ) +{ + int dx = d_data->pos.x() - d_data->initialPos.x(); + int dy = d_data->pos.y() - d_data->initialPos.y(); + + QRect r( 0, 0, d_data->pixmap.width(), d_data->pixmap.height() ); + r.moveCenter( QPoint( r.center().x() + dx, r.center().y() + dy ) ); + + QPixmap pm( size() ); + QwtPainter::fillPixmap( parentWidget(), pm ); + + QPainter painter( &pm ); + + if ( !d_data->contentsMask.isNull() ) + { + QPixmap masked = d_data->pixmap; + masked.setMask( d_data->contentsMask ); + painter.drawPixmap( r, masked ); + } + else + { + painter.drawPixmap( r, d_data->pixmap ); + } + + painter.end(); + + if ( !d_data->contentsMask.isNull() ) + pm.setMask( d_data->contentsMask ); + + painter.begin( this ); + painter.setClipRegion( pe->region() ); + painter.drawPixmap( 0, 0, pm ); +} + +/*! + \brief Calculate a mask for the contents of the panned widget + + Sometimes only parts of the contents of a widget should be + panned. F.e. for a widget with a styled background with rounded borders + only the area inside of the border should be panned. + + \return An empty bitmap, indicating no mask +*/ +QBitmap QwtPanner::contentsMask() const +{ + return QBitmap(); +} + +/*! + Grab the widget into a pixmap. + \return Grabbed pixmap +*/ +QPixmap QwtPanner::grab() const +{ +#if QT_VERSION >= 0x050000 + return parentWidget()->grab( parentWidget()->rect() ); +#else + return QPixmap::grabWidget( parentWidget() ); +#endif +} + +/*! + \brief Event filter + + When isEnabled() is true mouse events of the + observed widget are filtered. + + \param object Object to be filtered + \param event Event + + \return Always false, beside for paint events for the + parent widget. + + \sa widgetMousePressEvent(), widgetMouseReleaseEvent(), + widgetMouseMoveEvent() +*/ +bool QwtPanner::eventFilter( QObject *object, QEvent *event ) +{ + if ( object == NULL || object != parentWidget() ) + return false; + + switch ( event->type() ) + { + case QEvent::MouseButtonPress: + { + widgetMousePressEvent( static_cast( event ) ); + break; + } + case QEvent::MouseMove: + { + widgetMouseMoveEvent( static_cast( event ) ); + break; + } + case QEvent::MouseButtonRelease: + { + widgetMouseReleaseEvent( static_cast( event ) ); + break; + } + case QEvent::KeyPress: + { + widgetKeyPressEvent( static_cast( event ) ); + break; + } + case QEvent::KeyRelease: + { + widgetKeyReleaseEvent( static_cast( event ) ); + break; + } + case QEvent::Paint: + { + if ( isVisible() ) + return true; + break; + } + default:; + } + + return false; +} + +/*! + Handle a mouse press event for the observed widget. + + \param mouseEvent Mouse event + \sa eventFilter(), widgetMouseReleaseEvent(), + widgetMouseMoveEvent(), +*/ +void QwtPanner::widgetMousePressEvent( QMouseEvent *mouseEvent ) +{ + if ( ( mouseEvent->button() != d_data->button ) + || ( mouseEvent->modifiers() != d_data->buttonModifiers ) ) + { + return; + } + + QWidget *w = parentWidget(); + if ( w == NULL ) + return; + +#ifndef QT_NO_CURSOR + showCursor( true ); +#endif + + d_data->initialPos = d_data->pos = mouseEvent->pos(); + + setGeometry( parentWidget()->rect() ); + + // We don't want to grab the picker ! + QVector pickers = qwtActivePickers( parentWidget() ); + for ( int i = 0; i < pickers.size(); i++ ) + pickers[i]->setEnabled( false ); + + d_data->pixmap = grab(); + d_data->contentsMask = contentsMask(); + + for ( int i = 0; i < pickers.size(); i++ ) + pickers[i]->setEnabled( true ); + + show(); +} + +/*! + Handle a mouse move event for the observed widget. + + \param mouseEvent Mouse event + \sa eventFilter(), widgetMousePressEvent(), widgetMouseReleaseEvent() +*/ +void QwtPanner::widgetMouseMoveEvent( QMouseEvent *mouseEvent ) +{ + if ( !isVisible() ) + return; + + QPoint pos = mouseEvent->pos(); + if ( !isOrientationEnabled( Qt::Horizontal ) ) + pos.setX( d_data->initialPos.x() ); + if ( !isOrientationEnabled( Qt::Vertical ) ) + pos.setY( d_data->initialPos.y() ); + + if ( pos != d_data->pos && rect().contains( pos ) ) + { + d_data->pos = pos; + update(); + + Q_EMIT moved( d_data->pos.x() - d_data->initialPos.x(), + d_data->pos.y() - d_data->initialPos.y() ); + } +} + +/*! + Handle a mouse release event for the observed widget. + + \param mouseEvent Mouse event + \sa eventFilter(), widgetMousePressEvent(), + widgetMouseMoveEvent(), +*/ +void QwtPanner::widgetMouseReleaseEvent( QMouseEvent *mouseEvent ) +{ + if ( isVisible() ) + { + hide(); +#ifndef QT_NO_CURSOR + showCursor( false ); +#endif + + QPoint pos = mouseEvent->pos(); + if ( !isOrientationEnabled( Qt::Horizontal ) ) + pos.setX( d_data->initialPos.x() ); + if ( !isOrientationEnabled( Qt::Vertical ) ) + pos.setY( d_data->initialPos.y() ); + + d_data->pixmap = QPixmap(); + d_data->contentsMask = QBitmap(); + d_data->pos = pos; + + if ( d_data->pos != d_data->initialPos ) + { + Q_EMIT panned( d_data->pos.x() - d_data->initialPos.x(), + d_data->pos.y() - d_data->initialPos.y() ); + } + } +} + +/*! + Handle a key press event for the observed widget. + + \param keyEvent Key event + \sa eventFilter(), widgetKeyReleaseEvent() +*/ +void QwtPanner::widgetKeyPressEvent( QKeyEvent *keyEvent ) +{ + if ( ( keyEvent->key() == d_data->abortKey ) + && ( keyEvent->modifiers() == d_data->abortKeyModifiers ) ) + { + hide(); + +#ifndef QT_NO_CURSOR + showCursor( false ); +#endif + d_data->pixmap = QPixmap(); + } +} + +/*! + Handle a key release event for the observed widget. + + \param keyEvent Key event + \sa eventFilter(), widgetKeyReleaseEvent() +*/ +void QwtPanner::widgetKeyReleaseEvent( QKeyEvent *keyEvent ) +{ + Q_UNUSED( keyEvent ); +} + +#ifndef QT_NO_CURSOR +void QwtPanner::showCursor( bool on ) +{ + if ( on == d_data->hasCursor ) + return; + + QWidget *w = parentWidget(); + if ( w == NULL || d_data->cursor == NULL ) + return; + + d_data->hasCursor = on; + + if ( on ) + { + if ( w->testAttribute( Qt::WA_SetCursor ) ) + { + delete d_data->restoreCursor; + d_data->restoreCursor = new QCursor( w->cursor() ); + } + w->setCursor( *d_data->cursor ); + } + else + { + if ( d_data->restoreCursor ) + { + w->setCursor( *d_data->restoreCursor ); + delete d_data->restoreCursor; + d_data->restoreCursor = NULL; + } + else + w->unsetCursor(); + } +} +#endif diff --git a/ThirdParty/Qwt/src/qwt_panner.h b/ThirdParty/Qwt/src/qwt_panner.h new file mode 100644 index 0000000000..a0c6873aba --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_panner.h @@ -0,0 +1,103 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#ifndef QWT_PANNER_H +#define QWT_PANNER_H 1 + +#include "qwt_global.h" +#include +#include + +class QCursor; + +/*! + \brief QwtPanner provides panning of a widget + + QwtPanner grabs the contents of a widget, that can be dragged + in all directions. The offset between the start and the end position + is emitted by the panned signal. + + QwtPanner grabs the content of the widget into a pixmap and moves + the pixmap around, without initiating any repaint events for the widget. + Areas, that are not part of content are not painted while panning. + This makes panning fast enough for widgets, where + repaints are too slow for mouse movements. + + For widgets, where repaints are very fast it might be better to + implement panning manually by mapping mouse events into paint events. +*/ +class QWT_EXPORT QwtPanner: public QWidget +{ + Q_OBJECT + +public: + QwtPanner( QWidget* parent ); + virtual ~QwtPanner(); + + void setEnabled( bool ); + bool isEnabled() const; + + void setMouseButton( Qt::MouseButton, + Qt::KeyboardModifiers = Qt::NoModifier ); + void getMouseButton( Qt::MouseButton &button, + Qt::KeyboardModifiers & ) const; + + void setAbortKey( int key, Qt::KeyboardModifiers = Qt::NoModifier ); + void getAbortKey( int &key, Qt::KeyboardModifiers & ) const; + + void setCursor( const QCursor & ); + const QCursor cursor() const; + + void setOrientations( Qt::Orientations ); + Qt::Orientations orientations() const; + + bool isOrientationEnabled( Qt::Orientation ) const; + + virtual bool eventFilter( QObject *, QEvent * ); + +Q_SIGNALS: + /*! + Signal emitted, when panning is done + + \param dx Offset in horizontal direction + \param dy Offset in vertical direction + */ + void panned( int dx, int dy ); + + /*! + Signal emitted, while the widget moved, but panning + is not finished. + + \param dx Offset in horizontal direction + \param dy Offset in vertical direction + */ + void moved( int dx, int dy ); + +protected: + virtual void widgetMousePressEvent( QMouseEvent * ); + virtual void widgetMouseReleaseEvent( QMouseEvent * ); + virtual void widgetMouseMoveEvent( QMouseEvent * ); + virtual void widgetKeyPressEvent( QKeyEvent * ); + virtual void widgetKeyReleaseEvent( QKeyEvent * ); + + virtual void paintEvent( QPaintEvent * ); + + virtual QBitmap contentsMask() const; + virtual QPixmap grab() const; + +private: +#ifndef QT_NO_CURSOR + void showCursor( bool ); +#endif + + class PrivateData; + PrivateData *d_data; +}; + +#endif diff --git a/ThirdParty/Qwt/src/qwt_picker.cpp b/ThirdParty/Qwt/src/qwt_picker.cpp new file mode 100644 index 0000000000..335ddf0cd0 --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_picker.cpp @@ -0,0 +1,1577 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#include "qwt_picker.h" +#include "qwt_picker_machine.h" +#include "qwt_painter.h" +#include "qwt_math.h" +#include "qwt_widget_overlay.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static inline QRegion qwtMaskRegion( const QRect &r, int penWidth ) +{ + const int pw = qMax( penWidth, 1 ); + const int pw2 = penWidth / 2; + + int x1 = r.left() - pw2; + int x2 = r.right() + 1 + pw2 + ( pw % 2 ); + + int y1 = r.top() - pw2; + int y2 = r.bottom() + 1 + pw2 + ( pw % 2 ); + + QRegion region; + + region += QRect( x1, y1, x2 - x1, pw ); + region += QRect( x1, y1, pw, y2 - y1 ); + region += QRect( x1, y2 - pw, x2 - x1, pw ); + region += QRect( x2 - pw, y1, pw, y2 - y1 ); + + return region; +} + +static inline QRegion qwtMaskRegion( const QLine &l, int penWidth ) +{ + const int pw = qMax( penWidth, 1 ); + const int pw2 = penWidth / 2; + + QRegion region; + + if ( l.x1() == l.x2() ) + { + region += QRect( l.x1() - pw2, l.y1(), + pw, l.y2() ).normalized(); + } + else if ( l.y1() == l.y2() ) + { + region += QRect( l.x1(), l.y1() - pw2, + l.x2(), pw ).normalized(); + } + + return region; +} + +class QwtPickerRubberband: public QwtWidgetOverlay +{ +public: + QwtPickerRubberband( QwtPicker *, QWidget * ); + +protected: + virtual void drawOverlay( QPainter * ) const; + virtual QRegion maskHint() const; + + QwtPicker *d_picker; +}; + +class QwtPickerTracker: public QwtWidgetOverlay +{ +public: + QwtPickerTracker( QwtPicker *, QWidget * ); + +protected: + virtual void drawOverlay( QPainter * ) const; + virtual QRegion maskHint() const; + + QwtPicker *d_picker; +}; + + +class QwtPicker::PrivateData +{ +public: + PrivateData(): + enabled( false ), + stateMachine( NULL ), + resizeMode( QwtPicker::Stretch ), + rubberBand( QwtPicker::NoRubberBand ), + trackerMode( QwtPicker::AlwaysOff ), + isActive( false ), + trackerPosition( -1, -1 ), + mouseTracking( false ), + openGL( false ) + { + } + + bool enabled; + + QwtPickerMachine *stateMachine; + + QwtPicker::ResizeMode resizeMode; + + QwtPicker::RubberBand rubberBand; + QPen rubberBandPen; + + QwtPicker::DisplayMode trackerMode; + QPen trackerPen; + QFont trackerFont; + + QPolygon pickedPoints; + bool isActive; + QPoint trackerPosition; + + bool mouseTracking; // used to save previous value + + QPointer< QwtPickerRubberband > rubberBandOverlay; + QPointer< QwtPickerTracker> trackerOverlay; + + bool openGL; +}; + +QwtPickerRubberband::QwtPickerRubberband( + QwtPicker *picker, QWidget *parent ): + QwtWidgetOverlay( parent ), + d_picker( picker ) +{ + setMaskMode( QwtWidgetOverlay::MaskHint ); +} + +QRegion QwtPickerRubberband::maskHint() const +{ + return d_picker->rubberBandMask(); +} + +void QwtPickerRubberband::drawOverlay( QPainter *painter ) const +{ + painter->setPen( d_picker->rubberBandPen() ); + d_picker->drawRubberBand( painter ); +} + +QwtPickerTracker::QwtPickerTracker( + QwtPicker *picker, QWidget *parent ): + QwtWidgetOverlay( parent ), + d_picker( picker ) +{ + setMaskMode( QwtWidgetOverlay::MaskHint ); +} + +QRegion QwtPickerTracker::maskHint() const +{ + return d_picker->trackerRect( font() ); +} + +void QwtPickerTracker::drawOverlay( QPainter *painter ) const +{ + painter->setPen( d_picker->trackerPen() ); + d_picker->drawTracker( painter ); +} + +/*! + Constructor + + Creates an picker that is enabled, but without a state machine. + rubber band and tracker are disabled. + + \param parent Parent widget, that will be observed + */ + +QwtPicker::QwtPicker( QWidget *parent ): + QObject( parent ) +{ + init( parent, NoRubberBand, AlwaysOff ); +} + +/*! + Constructor + + \param rubberBand Rubber band style + \param trackerMode Tracker mode + \param parent Parent widget, that will be observed + */ +QwtPicker::QwtPicker( RubberBand rubberBand, + DisplayMode trackerMode, QWidget *parent ): + QObject( parent ) +{ + init( parent, rubberBand, trackerMode ); +} + +//! Destructor +QwtPicker::~QwtPicker() +{ + setMouseTracking( false ); + + delete d_data->stateMachine; + delete d_data->rubberBandOverlay; + delete d_data->trackerOverlay; + + delete d_data; +} + +//! Initialize the picker - used by the constructors +void QwtPicker::init( QWidget *parent, + RubberBand rubberBand, DisplayMode trackerMode ) +{ + d_data = new PrivateData; + + d_data->rubberBand = rubberBand; + + if ( parent ) + { + if ( parent->focusPolicy() == Qt::NoFocus ) + parent->setFocusPolicy( Qt::WheelFocus ); + + d_data->openGL = parent->inherits( "QGLWidget" ); + d_data->trackerFont = parent->font(); + d_data->mouseTracking = parent->hasMouseTracking(); + + setEnabled( true ); + } + + setTrackerMode( trackerMode ); +} + +/*! + Set a state machine and delete the previous one + + \param stateMachine State machine + \sa stateMachine() +*/ +void QwtPicker::setStateMachine( QwtPickerMachine *stateMachine ) +{ + if ( d_data->stateMachine != stateMachine ) + { + reset(); + + delete d_data->stateMachine; + d_data->stateMachine = stateMachine; + + if ( d_data->stateMachine ) + d_data->stateMachine->reset(); + } +} + +/*! + \return Assigned state machine + \sa setStateMachine() +*/ +QwtPickerMachine *QwtPicker::stateMachine() +{ + return d_data->stateMachine; +} + +/*! + \return Assigned state machine + \sa setStateMachine() +*/ +const QwtPickerMachine *QwtPicker::stateMachine() const +{ + return d_data->stateMachine; +} + +//! Return the parent widget, where the selection happens +QWidget *QwtPicker::parentWidget() +{ + QObject *obj = parent(); + if ( obj && obj->isWidgetType() ) + return static_cast( obj ); + + return NULL; +} + +//! Return the parent widget, where the selection happens +const QWidget *QwtPicker::parentWidget() const +{ + QObject *obj = parent(); + if ( obj && obj->isWidgetType() ) + return static_cast< const QWidget *>( obj ); + + return NULL; +} + +/*! + Set the rubber band style + + \param rubberBand Rubber band style + The default value is NoRubberBand. + + \sa rubberBand(), RubberBand, setRubberBandPen() +*/ +void QwtPicker::setRubberBand( RubberBand rubberBand ) +{ + d_data->rubberBand = rubberBand; +} + +/*! + \return Rubber band style + \sa setRubberBand(), RubberBand, rubberBandPen() +*/ +QwtPicker::RubberBand QwtPicker::rubberBand() const +{ + return d_data->rubberBand; +} + +/*! + \brief Set the display mode of the tracker. + + A tracker displays information about current position of + the cursor as a string. The display mode controls + if the tracker has to be displayed whenever the observed + widget has focus and cursor (AlwaysOn), never (AlwaysOff), or + only when the selection is active (ActiveOnly). + + \param mode Tracker display mode + + \warning In case of AlwaysOn, mouseTracking will be enabled + for the observed widget. + \sa trackerMode(), DisplayMode +*/ + +void QwtPicker::setTrackerMode( DisplayMode mode ) +{ + if ( d_data->trackerMode != mode ) + { + d_data->trackerMode = mode; + setMouseTracking( d_data->trackerMode == AlwaysOn ); + } +} + +/*! + \return Tracker display mode + \sa setTrackerMode(), DisplayMode +*/ +QwtPicker::DisplayMode QwtPicker::trackerMode() const +{ + return d_data->trackerMode; +} + +/*! + \brief Set the resize mode. + + The resize mode controls what to do with the selected points of an active + selection when the observed widget is resized. + + Stretch means the points are scaled according to the new + size, KeepSize means the points remain unchanged. + + The default mode is Stretch. + + \param mode Resize mode + \sa resizeMode(), ResizeMode +*/ +void QwtPicker::setResizeMode( ResizeMode mode ) +{ + d_data->resizeMode = mode; +} + +/*! + \return Resize mode + \sa setResizeMode(), ResizeMode +*/ + +QwtPicker::ResizeMode QwtPicker::resizeMode() const +{ + return d_data->resizeMode; +} + +/*! + \brief En/disable the picker + + When enabled is true an event filter is installed for + the observed widget, otherwise the event filter is removed. + + \param enabled true or false + \sa isEnabled(), eventFilter() +*/ +void QwtPicker::setEnabled( bool enabled ) +{ + if ( d_data->enabled != enabled ) + { + d_data->enabled = enabled; + + QWidget *w = parentWidget(); + if ( w ) + { + if ( enabled ) + w->installEventFilter( this ); + else + w->removeEventFilter( this ); + } + + updateDisplay(); + } +} + +/*! + \return true when enabled, false otherwise + \sa setEnabled(), eventFilter() +*/ + +bool QwtPicker::isEnabled() const +{ + return d_data->enabled; +} + +/*! + Set the font for the tracker + + \param font Tracker font + \sa trackerFont(), setTrackerMode(), setTrackerPen() +*/ +void QwtPicker::setTrackerFont( const QFont &font ) +{ + if ( font != d_data->trackerFont ) + { + d_data->trackerFont = font; + updateDisplay(); + } +} + +/*! + \return Tracker font + \sa setTrackerFont(), trackerMode(), trackerPen() +*/ + +QFont QwtPicker::trackerFont() const +{ + return d_data->trackerFont; +} + +/*! + Set the pen for the tracker + + \param pen Tracker pen + \sa trackerPen(), setTrackerMode(), setTrackerFont() +*/ +void QwtPicker::setTrackerPen( const QPen &pen ) +{ + if ( pen != d_data->trackerPen ) + { + d_data->trackerPen = pen; + updateDisplay(); + } +} + +/*! + \return Tracker pen + \sa setTrackerPen(), trackerMode(), trackerFont() +*/ +QPen QwtPicker::trackerPen() const +{ + return d_data->trackerPen; +} + +/*! + Set the pen for the rubberband + + \param pen Rubber band pen + \sa rubberBandPen(), setRubberBand() +*/ +void QwtPicker::setRubberBandPen( const QPen &pen ) +{ + if ( pen != d_data->rubberBandPen ) + { + d_data->rubberBandPen = pen; + updateDisplay(); + } +} + +/*! + \return Rubber band pen + \sa setRubberBandPen(), rubberBand() +*/ +QPen QwtPicker::rubberBandPen() const +{ + return d_data->rubberBandPen; +} + +/*! + \brief Return the label for a position + + In case of HLineRubberBand the label is the value of the + y position, in case of VLineRubberBand the value of the x position. + Otherwise the label contains x and y position separated by a ',' . + + The format for the string conversion is "%d". + + \param pos Position + \return Converted position as string +*/ + +QwtText QwtPicker::trackerText( const QPoint &pos ) const +{ + QString label; + + switch ( rubberBand() ) + { + case HLineRubberBand: + label.sprintf( "%d", pos.y() ); + break; + case VLineRubberBand: + label.sprintf( "%d", pos.x() ); + break; + default: + label.sprintf( "%d, %d", pos.x(), pos.y() ); + } + return label; +} + +/*! + Calculate the mask for the rubber band overlay + + \return Region for the mask + \sa QWidget::setMask() + */ +QRegion QwtPicker::rubberBandMask() const +{ + QRegion mask; + + if ( !isActive() || rubberBand() == NoRubberBand || + rubberBandPen().style() == Qt::NoPen ) + { + return mask; + } + + const QPolygon pa = adjustedPoints( d_data->pickedPoints ); + + QwtPickerMachine::SelectionType selectionType = + QwtPickerMachine::NoSelection; + + if ( d_data->stateMachine ) + selectionType = d_data->stateMachine->selectionType(); + + switch ( selectionType ) + { + case QwtPickerMachine::NoSelection: + case QwtPickerMachine::PointSelection: + { + if ( pa.count() < 1 ) + return mask; + + const QPoint pos = pa[0]; + const int pw = rubberBandPen().width(); + + const QRect pRect = pickArea().boundingRect().toRect(); + switch ( rubberBand() ) + { + case VLineRubberBand: + { + mask += qwtMaskRegion( QLine( pos.x(), pRect.top(), + pos.x(), pRect.bottom() ), pw ); + break; + } + case HLineRubberBand: + { + mask += qwtMaskRegion( QLine( pRect.left(), pos.y(), + pRect.right(), pos.y() ), pw ); + break; + } + case CrossRubberBand: + { + mask += qwtMaskRegion( QLine( pos.x(), pRect.top(), + pos.x(), pRect.bottom() ), pw ); + mask += qwtMaskRegion( QLine( pRect.left(), pos.y(), + pRect.right(), pos.y() ), pw ); + break; + } + default: + break; + } + break; + } + case QwtPickerMachine::RectSelection: + { + if ( pa.count() < 2 ) + return mask; + + const int pw = rubberBandPen().width(); + + switch ( rubberBand() ) + { + case RectRubberBand: + { + const QRect r = QRect( pa.first(), pa.last() ); + mask = qwtMaskRegion( r.normalized(), pw ); + break; + } + case EllipseRubberBand: + { + const QRect r = QRect( pa.first(), pa.last() ); + mask += r.adjusted( -pw, -pw, pw, pw ); + break; + } + default: + break; + } + break; + } + case QwtPickerMachine::PolygonSelection: + { + const int pw = rubberBandPen().width(); + if ( pw <= 1 ) + { + // because of the join style we better + // return a mask for a pen width <= 1 only + + const int off = 2 * pw; + const QRect r = pa.boundingRect(); + mask += r.adjusted( -off, -off, off, off ); + } + break; + } + default: + break; + } + + return mask; +} + +/*! + Draw a rubber band, depending on rubberBand() + + \param painter Painter, initialized with a clip region + + \sa rubberBand(), RubberBand +*/ + +void QwtPicker::drawRubberBand( QPainter *painter ) const +{ + if ( !isActive() || rubberBand() == NoRubberBand || + rubberBandPen().style() == Qt::NoPen ) + { + return; + } + + const QPolygon pa = adjustedPoints( d_data->pickedPoints ); + + QwtPickerMachine::SelectionType selectionType = + QwtPickerMachine::NoSelection; + + if ( d_data->stateMachine ) + selectionType = d_data->stateMachine->selectionType(); + + switch ( selectionType ) + { + case QwtPickerMachine::NoSelection: + case QwtPickerMachine::PointSelection: + { + if ( pa.count() < 1 ) + return; + + const QPoint pos = pa[0]; + + const QRect pRect = pickArea().boundingRect().toRect(); + switch ( rubberBand() ) + { + case VLineRubberBand: + { + QwtPainter::drawLine( painter, pos.x(), + pRect.top(), pos.x(), pRect.bottom() ); + break; + } + case HLineRubberBand: + { + QwtPainter::drawLine( painter, pRect.left(), + pos.y(), pRect.right(), pos.y() ); + break; + } + case CrossRubberBand: + { + QwtPainter::drawLine( painter, pos.x(), + pRect.top(), pos.x(), pRect.bottom() ); + QwtPainter::drawLine( painter, pRect.left(), + pos.y(), pRect.right(), pos.y() ); + break; + } + default: + break; + } + break; + } + case QwtPickerMachine::RectSelection: + { + if ( pa.count() < 2 ) + return; + + const QRect rect = QRect( pa.first(), pa.last() ).normalized(); + switch ( rubberBand() ) + { + case EllipseRubberBand: + { + QwtPainter::drawEllipse( painter, rect ); + break; + } + case RectRubberBand: + { + QwtPainter::drawRect( painter, rect ); + break; + } + default: + break; + } + break; + } + case QwtPickerMachine::PolygonSelection: + { + if ( rubberBand() == PolygonRubberBand ) + painter->drawPolyline( pa ); + break; + } + default: + break; + } +} + +/*! + Draw the tracker + + \param painter Painter + \sa trackerRect(), trackerText() +*/ + +void QwtPicker::drawTracker( QPainter *painter ) const +{ + const QRect textRect = trackerRect( painter->font() ); + if ( !textRect.isEmpty() ) + { + const QwtText label = trackerText( d_data->trackerPosition ); + if ( !label.isEmpty() ) + label.draw( painter, textRect ); + } +} + +/*! + \brief Map the pickedPoints() into a selection() + + adjustedPoints() maps the points, that have been collected on + the parentWidget() into a selection(). The default implementation + simply returns the points unmodified. + + The reason, why a selection() differs from the picked points + depends on the application requirements. F.e. : + + - A rectangular selection might need to have a specific aspect ratio only.\n + - A selection could accept non intersecting polygons only.\n + - ...\n + + The example below is for a rectangular selection, where the first + point is the center of the selected rectangle. + \par Example + \verbatim QPolygon MyPicker::adjustedPoints(const QPolygon &points) const +{ + QPolygon adjusted; + if ( points.size() == 2 ) + { + const int width = qAbs(points[1].x() - points[0].x()); + const int height = qAbs(points[1].y() - points[0].y()); + + QRect rect(0, 0, 2 * width, 2 * height); + rect.moveCenter(points[0]); + + adjusted += rect.topLeft(); + adjusted += rect.bottomRight(); + } + return adjusted; +}\endverbatim\n + + \param points Selected points + \return Selected points unmodified +*/ +QPolygon QwtPicker::adjustedPoints( const QPolygon &points ) const +{ + return points; +} + +/*! + \return Selected points + \sa pickedPoints(), adjustedPoints() +*/ +QPolygon QwtPicker::selection() const +{ + return adjustedPoints( d_data->pickedPoints ); +} + +//! \return Current position of the tracker +QPoint QwtPicker::trackerPosition() const +{ + return d_data->trackerPosition; +} + +/*! + Calculate the bounding rectangle for the tracker text + from the current position of the tracker + + \param font Font of the tracker text + \return Bounding rectangle of the tracker text + + \sa trackerPosition() +*/ +QRect QwtPicker::trackerRect( const QFont &font ) const +{ + if ( trackerMode() == AlwaysOff || + ( trackerMode() == ActiveOnly && !isActive() ) ) + { + return QRect(); + } + + if ( d_data->trackerPosition.x() < 0 || d_data->trackerPosition.y() < 0 ) + return QRect(); + + QwtText text = trackerText( d_data->trackerPosition ); + if ( text.isEmpty() ) + return QRect(); + + const QSizeF textSize = text.textSize( font ); + QRect textRect( 0, 0, qCeil( textSize.width() ), qCeil( textSize.height() ) ); + + const QPoint &pos = d_data->trackerPosition; + + int alignment = 0; + if ( isActive() && d_data->pickedPoints.count() > 1 + && rubberBand() != NoRubberBand ) + { + const QPoint last = + d_data->pickedPoints[int( d_data->pickedPoints.count() ) - 2]; + + alignment |= ( pos.x() >= last.x() ) ? Qt::AlignRight : Qt::AlignLeft; + alignment |= ( pos.y() > last.y() ) ? Qt::AlignBottom : Qt::AlignTop; + } + else + alignment = Qt::AlignTop | Qt::AlignRight; + + const int margin = 5; + + int x = pos.x(); + if ( alignment & Qt::AlignLeft ) + x -= textRect.width() + margin; + else if ( alignment & Qt::AlignRight ) + x += margin; + + int y = pos.y(); + if ( alignment & Qt::AlignBottom ) + y += margin; + else if ( alignment & Qt::AlignTop ) + y -= textRect.height() + margin; + + textRect.moveTopLeft( QPoint( x, y ) ); + + const QRect pickRect = pickArea().boundingRect().toRect(); + + int right = qMin( textRect.right(), pickRect.right() - margin ); + int bottom = qMin( textRect.bottom(), pickRect.bottom() - margin ); + textRect.moveBottomRight( QPoint( right, bottom ) ); + + int left = qMax( textRect.left(), pickRect.left() + margin ); + int top = qMax( textRect.top(), pickRect.top() + margin ); + textRect.moveTopLeft( QPoint( left, top ) ); + + return textRect; +} + +/*! + \brief Event filter + + When isEnabled() is true all events of the observed widget are filtered. + Mouse and keyboard events are translated into widgetMouse- and widgetKey- + and widgetWheel-events. Paint and Resize events are handled to keep + rubber band and tracker up to date. + + \param object Object to be filtered + \param event Event + + \return Always false. + + \sa widgetEnterEvent(), widgetLeaveEvent(), + widgetMousePressEvent(), widgetMouseReleaseEvent(), + widgetMouseDoubleClickEvent(), widgetMouseMoveEvent(), + widgetWheelEvent(), widgetKeyPressEvent(), widgetKeyReleaseEvent(), + QObject::installEventFilter(), QObject::event() +*/ +bool QwtPicker::eventFilter( QObject *object, QEvent *event ) +{ + if ( object && object == parentWidget() ) + { + switch ( event->type() ) + { + case QEvent::Resize: + { + const QResizeEvent *re = static_cast( event ); + if ( d_data->resizeMode == Stretch ) + stretchSelection( re->oldSize(), re->size() ); + + break; + } + case QEvent::Enter: + { + widgetEnterEvent( event ); + break; + } + case QEvent::Leave: + { + widgetLeaveEvent( event ); + break; + } + case QEvent::MouseButtonPress: + { + widgetMousePressEvent( static_cast( event ) ); + break; + } + case QEvent::MouseButtonRelease: + { + widgetMouseReleaseEvent( static_cast( event ) ); + break; + } + case QEvent::MouseButtonDblClick: + { + widgetMouseDoubleClickEvent( static_cast( event ) ); + break; + } + case QEvent::MouseMove: + { + widgetMouseMoveEvent( static_cast( event ) ); + break; + } + case QEvent::KeyPress: + { + widgetKeyPressEvent( static_cast( event ) ); + break; + } + case QEvent::KeyRelease: + { + widgetKeyReleaseEvent( static_cast( event ) ); + break; + } + case QEvent::Wheel: + { + widgetWheelEvent( static_cast( event ) ); + break; + } + default: + break; + } + } + return false; +} + +/*! + Handle a mouse press event for the observed widget. + + \param mouseEvent Mouse event + + \sa eventFilter(), widgetMouseReleaseEvent(), + widgetMouseDoubleClickEvent(), widgetMouseMoveEvent(), + widgetWheelEvent(), widgetKeyPressEvent(), widgetKeyReleaseEvent() +*/ +void QwtPicker::widgetMousePressEvent( QMouseEvent *mouseEvent ) +{ + transition( mouseEvent ); +} + +/*! + Handle a mouse move event for the observed widget. + + \param mouseEvent Mouse event + + \sa eventFilter(), widgetMousePressEvent(), widgetMouseReleaseEvent(), + widgetMouseDoubleClickEvent(), + widgetWheelEvent(), widgetKeyPressEvent(), widgetKeyReleaseEvent() +*/ +void QwtPicker::widgetMouseMoveEvent( QMouseEvent *mouseEvent ) +{ + if ( pickArea().contains( mouseEvent->pos() ) ) + d_data->trackerPosition = mouseEvent->pos(); + else + d_data->trackerPosition = QPoint( -1, -1 ); + + if ( !isActive() ) + updateDisplay(); + + transition( mouseEvent ); +} + +/*! + Handle a enter event for the observed widget. + + \param event Qt event + + \sa eventFilter(), widgetMousePressEvent(), widgetMouseReleaseEvent(), + widgetMouseDoubleClickEvent(), + widgetWheelEvent(), widgetKeyPressEvent(), widgetKeyReleaseEvent() +*/ +void QwtPicker::widgetEnterEvent( QEvent *event ) +{ + transition( event ); +} + +/*! + Handle a leave event for the observed widget. + + \param event Qt event + + \sa eventFilter(), widgetMousePressEvent(), widgetMouseReleaseEvent(), + widgetMouseDoubleClickEvent(), + widgetWheelEvent(), widgetKeyPressEvent(), widgetKeyReleaseEvent() +*/ +void QwtPicker::widgetLeaveEvent( QEvent *event ) +{ + transition( event ); + + d_data->trackerPosition = QPoint( -1, -1 ); + if ( !isActive() ) + updateDisplay(); +} + +/*! + Handle a mouse release event for the observed widget. + + \param mouseEvent Mouse event + + \sa eventFilter(), widgetMousePressEvent(), + widgetMouseDoubleClickEvent(), widgetMouseMoveEvent(), + widgetWheelEvent(), widgetKeyPressEvent(), widgetKeyReleaseEvent() +*/ +void QwtPicker::widgetMouseReleaseEvent( QMouseEvent *mouseEvent ) +{ + transition( mouseEvent ); +} + +/*! + Handle mouse double click event for the observed widget. + + \param mouseEvent Mouse event + + \sa eventFilter(), widgetMousePressEvent(), widgetMouseReleaseEvent(), + widgetMouseMoveEvent(), + widgetWheelEvent(), widgetKeyPressEvent(), widgetKeyReleaseEvent() +*/ +void QwtPicker::widgetMouseDoubleClickEvent( QMouseEvent *mouseEvent ) +{ + transition( mouseEvent ); +} + + +/*! + Handle a wheel event for the observed widget. + + Move the last point of the selection in case of isActive() == true + + \param wheelEvent Wheel event + + \sa eventFilter(), widgetMousePressEvent(), widgetMouseReleaseEvent(), + widgetMouseDoubleClickEvent(), widgetMouseMoveEvent(), + widgetKeyPressEvent(), widgetKeyReleaseEvent() +*/ +void QwtPicker::widgetWheelEvent( QWheelEvent *wheelEvent ) +{ + if ( pickArea().contains( wheelEvent->pos() ) ) + d_data->trackerPosition = wheelEvent->pos(); + else + d_data->trackerPosition = QPoint( -1, -1 ); + + updateDisplay(); + + transition( wheelEvent ); +} + +/*! + Handle a key press event for the observed widget. + + Selections can be completely done by the keyboard. The arrow keys + move the cursor, the abort key aborts a selection. All other keys + are handled by the current state machine. + + \param keyEvent Key event + + \sa eventFilter(), widgetMousePressEvent(), widgetMouseReleaseEvent(), + widgetMouseDoubleClickEvent(), widgetMouseMoveEvent(), + widgetWheelEvent(), widgetKeyReleaseEvent(), stateMachine(), + QwtEventPattern::KeyPatternCode +*/ +void QwtPicker::widgetKeyPressEvent( QKeyEvent *keyEvent ) +{ + int dx = 0; + int dy = 0; + + int offset = 1; + if ( keyEvent->isAutoRepeat() ) + offset = 5; + + if ( keyMatch( KeyLeft, keyEvent ) ) + dx = -offset; + else if ( keyMatch( KeyRight, keyEvent ) ) + dx = offset; + else if ( keyMatch( KeyUp, keyEvent ) ) + dy = -offset; + else if ( keyMatch( KeyDown, keyEvent ) ) + dy = offset; + else if ( keyMatch( KeyAbort, keyEvent ) ) + { + reset(); + } + else + transition( keyEvent ); + + if ( dx != 0 || dy != 0 ) + { + const QRect rect = pickArea().boundingRect().toRect(); + const QPoint pos = parentWidget()->mapFromGlobal( QCursor::pos() ); + + int x = pos.x() + dx; + x = qMax( rect.left(), x ); + x = qMin( rect.right(), x ); + + int y = pos.y() + dy; + y = qMax( rect.top(), y ); + y = qMin( rect.bottom(), y ); + + QCursor::setPos( parentWidget()->mapToGlobal( QPoint( x, y ) ) ); + } +} + +/*! + Handle a key release event for the observed widget. + + Passes the event to the state machine. + + \param keyEvent Key event + + \sa eventFilter(), widgetMousePressEvent(), widgetMouseReleaseEvent(), + widgetMouseDoubleClickEvent(), widgetMouseMoveEvent(), + widgetWheelEvent(), widgetKeyPressEvent(), stateMachine() +*/ +void QwtPicker::widgetKeyReleaseEvent( QKeyEvent *keyEvent ) +{ + transition( keyEvent ); +} + +/*! + Passes an event to the state machine and executes the resulting + commands. Append and Move commands use the current position + of the cursor ( QCursor::pos() ). + + \param event Event +*/ +void QwtPicker::transition( const QEvent *event ) +{ + if ( !d_data->stateMachine ) + return; + + const QList commandList = + d_data->stateMachine->transition( *this, event ); + + QPoint pos; + switch ( event->type() ) + { + case QEvent::MouseButtonDblClick: + case QEvent::MouseButtonPress: + case QEvent::MouseButtonRelease: + case QEvent::MouseMove: + { + const QMouseEvent *me = + static_cast< const QMouseEvent * >( event ); + pos = me->pos(); + break; + } + default: + pos = parentWidget()->mapFromGlobal( QCursor::pos() ); + } + + for ( int i = 0; i < commandList.count(); i++ ) + { + switch ( commandList[i] ) + { + case QwtPickerMachine::Begin: + { + begin(); + break; + } + case QwtPickerMachine::Append: + { + append( pos ); + break; + } + case QwtPickerMachine::Move: + { + move( pos ); + break; + } + case QwtPickerMachine::Remove: + { + remove(); + break; + } + case QwtPickerMachine::End: + { + end(); + break; + } + } + } +} + +/*! + Open a selection setting the state to active + + \sa isActive(), end(), append(), move() +*/ +void QwtPicker::begin() +{ + if ( d_data->isActive ) + return; + + d_data->pickedPoints.resize( 0 ); + d_data->isActive = true; + Q_EMIT activated( true ); + + if ( trackerMode() != AlwaysOff ) + { + if ( d_data->trackerPosition.x() < 0 || d_data->trackerPosition.y() < 0 ) + { + QWidget *w = parentWidget(); + if ( w ) + d_data->trackerPosition = w->mapFromGlobal( QCursor::pos() ); + } + } + + updateDisplay(); + setMouseTracking( true ); +} + +/*! + \brief Close a selection setting the state to inactive. + + The selection is validated and maybe fixed by accept(). + + \param ok If true, complete the selection and emit a selected signal + otherwise discard the selection. + \return true if the selection is accepted, false otherwise + \sa isActive(), begin(), append(), move(), selected(), accept() +*/ +bool QwtPicker::end( bool ok ) +{ + if ( d_data->isActive ) + { + setMouseTracking( false ); + + d_data->isActive = false; + Q_EMIT activated( false ); + + if ( trackerMode() == ActiveOnly ) + d_data->trackerPosition = QPoint( -1, -1 ); + + if ( ok ) + ok = accept( d_data->pickedPoints ); + + if ( ok ) + Q_EMIT selected( d_data->pickedPoints ); + else + d_data->pickedPoints.resize( 0 ); + + updateDisplay(); + } + else + ok = false; + + return ok; +} + +/*! + Reset the state machine and terminate ( end(false) ) the selection +*/ +void QwtPicker::reset() +{ + if ( d_data->stateMachine ) + d_data->stateMachine->reset(); + + if ( isActive() ) + end( false ); +} + +/*! + Append a point to the selection and update rubber band and tracker. + The appended() signal is emitted. + + \param pos Additional point + + \sa isActive(), begin(), end(), move(), appended() +*/ +void QwtPicker::append( const QPoint &pos ) +{ + if ( d_data->isActive ) + { + const int idx = d_data->pickedPoints.count(); + d_data->pickedPoints.resize( idx + 1 ); + d_data->pickedPoints[idx] = pos; + + updateDisplay(); + Q_EMIT appended( pos ); + } +} + +/*! + Move the last point of the selection + The moved() signal is emitted. + + \param pos New position + \sa isActive(), begin(), end(), append() +*/ +void QwtPicker::move( const QPoint &pos ) +{ + if ( d_data->isActive ) + { + const int idx = d_data->pickedPoints.count() - 1; + if ( idx >= 0 ) + { + if ( d_data->pickedPoints[idx] != pos ) + { + d_data->pickedPoints[idx] = pos; + + updateDisplay(); + Q_EMIT moved( pos ); + } + } + } +} + +/*! + Remove the last point of the selection + The removed() signal is emitted. + + \sa isActive(), begin(), end(), append(), move() +*/ +void QwtPicker::remove() +{ + if ( d_data->isActive ) + { + const int idx = d_data->pickedPoints.count() - 1; + if ( idx > 0 ) + { + const int idx = d_data->pickedPoints.count(); + + const QPoint pos = d_data->pickedPoints[idx - 1]; + d_data->pickedPoints.resize( idx - 1 ); + + updateDisplay(); + Q_EMIT removed( pos ); + } + } +} + +/*! + \brief Validate and fix up the selection + + Accepts all selections unmodified + + \param selection Selection to validate and fix up + \return true, when accepted, false otherwise +*/ +bool QwtPicker::accept( QPolygon &selection ) const +{ + Q_UNUSED( selection ); + return true; +} + +/*! + A picker is active between begin() and end(). + \return true if the selection is active. +*/ +bool QwtPicker::isActive() const +{ + return d_data->isActive; +} + +/*! + Return the points, that have been collected so far. The selection() + is calculated from the pickedPoints() in adjustedPoints(). + \return Picked points +*/ +const QPolygon &QwtPicker::pickedPoints() const +{ + return d_data->pickedPoints; +} + +/*! + Scale the selection by the ratios of oldSize and newSize + The changed() signal is emitted. + + \param oldSize Previous size + \param newSize Current size + + \sa ResizeMode, setResizeMode(), resizeMode() +*/ +void QwtPicker::stretchSelection( const QSize &oldSize, const QSize &newSize ) +{ + if ( oldSize.isEmpty() ) + { + // avoid division by zero. But scaling for small sizes also + // doesn't make much sense, because of rounding losses. TODO ... + return; + } + + const double xRatio = + double( newSize.width() ) / double( oldSize.width() ); + const double yRatio = + double( newSize.height() ) / double( oldSize.height() ); + + for ( int i = 0; i < int( d_data->pickedPoints.count() ); i++ ) + { + QPoint &p = d_data->pickedPoints[i]; + p.setX( qRound( p.x() * xRatio ) ); + p.setY( qRound( p.y() * yRatio ) ); + + Q_EMIT changed( d_data->pickedPoints ); + } +} + +/*! + Set mouse tracking for the observed widget. + + In case of enable is true, the previous value + is saved, that is restored when enable is false. + + \warning Even when enable is false, mouse tracking might be restored + to true. When mouseTracking for the observed widget + has been changed directly by QWidget::setMouseTracking + while mouse tracking has been set to true, this value can't + be restored. +*/ + +void QwtPicker::setMouseTracking( bool enable ) +{ + QWidget *widget = parentWidget(); + if ( !widget ) + return; + + if ( enable ) + { + d_data->mouseTracking = widget->hasMouseTracking(); + widget->setMouseTracking( true ); + } + else + { + widget->setMouseTracking( d_data->mouseTracking ); + } +} + +/*! + Find the area of the observed widget, where selection might happen. + + \return parentWidget()->contentsRect() +*/ +QPainterPath QwtPicker::pickArea() const +{ + QPainterPath path; + + const QWidget *widget = parentWidget(); + if ( widget ) + path.addRect( widget->contentsRect() ); + + return path; +} + +//! Update the state of rubber band and tracker label +void QwtPicker::updateDisplay() +{ + QWidget *w = parentWidget(); + + bool showRubberband = false; + bool showTracker = false; + + if ( w && w->isVisible() && d_data->enabled ) + { + if ( rubberBand() != NoRubberBand && isActive() && + rubberBandPen().style() != Qt::NoPen ) + { + showRubberband = true; + } + + if ( trackerMode() == AlwaysOn || + ( trackerMode() == ActiveOnly && isActive() ) ) + { + if ( trackerPen() != Qt::NoPen + && !trackerRect( QFont() ).isEmpty() ) + { + showTracker = true; + } + } + } + + QPointer< QwtPickerRubberband > &rw = d_data->rubberBandOverlay; + if ( showRubberband ) + { + if ( rw.isNull() ) + { + rw = new QwtPickerRubberband( this, w ); + rw->setObjectName( "PickerRubberBand" ); + rw->resize( w->size() ); + } + + if ( d_data->rubberBand <= RectRubberBand ) + rw->setMaskMode( QwtWidgetOverlay::MaskHint ); + else + rw->setMaskMode( QwtWidgetOverlay::AlphaMask ); + + rw->updateOverlay(); + } + else + { + if ( d_data->openGL ) + { + // Qt 4.8 crashes for a delete + if ( !rw.isNull() ) + { + rw->hide(); + rw->deleteLater(); + rw = NULL; + } + } + else + { + delete rw; + } + } + + QPointer< QwtPickerTracker > &tw = d_data->trackerOverlay; + if ( showTracker ) + { + if ( tw.isNull() ) + { + tw = new QwtPickerTracker( this, w ); + tw->setObjectName( "PickerTracker" ); + tw->resize( w->size() ); + } + tw->setFont( d_data->trackerFont ); + tw->updateOverlay(); + } + else + { + if ( d_data->openGL ) + { + // Qt 4.8 crashes for a delete + if ( !tw.isNull() ) + { + tw->hide(); + tw->deleteLater(); + tw = NULL; + } + } + else + { + delete tw; + } + } +} + +//! \return Overlay displaying the rubber band +const QwtWidgetOverlay *QwtPicker::rubberBandOverlay() const +{ + return d_data->rubberBandOverlay; +} + +//! \return Overlay displaying the tracker text +const QwtWidgetOverlay *QwtPicker::trackerOverlay() const +{ + return d_data->trackerOverlay; +} + diff --git a/ThirdParty/Qwt/src/qwt_picker.h b/ThirdParty/Qwt/src/qwt_picker.h new file mode 100644 index 0000000000..87d6805e9e --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_picker.h @@ -0,0 +1,329 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#ifndef QWT_PICKER +#define QWT_PICKER 1 + +#include "qwt_global.h" +#include "qwt_text.h" +#include "qwt_event_pattern.h" +#include +#include +#include +#include +#include + +class QWidget; +class QMouseEvent; +class QWheelEvent; +class QKeyEvent; +class QwtPickerMachine; +class QwtWidgetOverlay; + +/*! + \brief QwtPicker provides selections on a widget + + QwtPicker filters all enter, leave, mouse and keyboard events of a widget + and translates them into an array of selected points. + + The way how the points are collected depends on type of state machine + that is connected to the picker. Qwt offers a couple of predefined + state machines for selecting: + + - Nothing\n + QwtPickerTrackerMachine + - Single points\n + QwtPickerClickPointMachine, QwtPickerDragPointMachine + - Rectangles\n + QwtPickerClickRectMachine, QwtPickerDragRectMachine + - Polygons\n + QwtPickerPolygonMachine + + While these state machines cover the most common ways to collect points + it is also possible to implement individual machines as well. + + QwtPicker translates the picked points into a selection using the + adjustedPoints() method. adjustedPoints() is intended to be reimplemented + to fix up the selection according to application specific requirements. + (F.e. when an application accepts rectangles of a fixed aspect ratio only.) + + Optionally QwtPicker support the process of collecting points by a + rubber band and tracker displaying a text for the current mouse + position. + + \par Example + \verbatim #include +#include + +QwtPicker *picker = new QwtPicker(widget); +picker->setStateMachine(new QwtPickerDragRectMachine); +picker->setTrackerMode(QwtPicker::ActiveOnly); +picker->setRubberBand(QwtPicker::RectRubberBand); \endverbatim\n + + The state machine triggers the following commands: + + - begin()\n + Activate/Initialize the selection. + - append()\n + Add a new point + - move() \n + Change the position of the last point. + - remove()\n + Remove the last point. + - end()\n + Terminate the selection and call accept to validate the picked points. + + The picker is active (isActive()), between begin() and end(). + In active state the rubber band is displayed, and the tracker is visible + in case of trackerMode is ActiveOnly or AlwaysOn. + + The cursor can be moved using the arrow keys. All selections can be aborted + using the abort key. (QwtEventPattern::KeyPatternCode) + + \warning In case of QWidget::NoFocus the focus policy of the observed + widget is set to QWidget::WheelFocus and mouse tracking + will be manipulated while the picker is active, + or if trackerMode() is AlwayOn. +*/ + +class QWT_EXPORT QwtPicker: public QObject, public QwtEventPattern +{ + Q_OBJECT + + Q_ENUMS( RubberBand DisplayMode ResizeMode ) + + Q_PROPERTY( bool isEnabled READ isEnabled WRITE setEnabled ) + Q_PROPERTY( ResizeMode resizeMode READ resizeMode WRITE setResizeMode ) + + Q_PROPERTY( DisplayMode trackerMode READ trackerMode WRITE setTrackerMode ) + Q_PROPERTY( QPen trackerPen READ trackerPen WRITE setTrackerPen ) + Q_PROPERTY( QFont trackerFont READ trackerFont WRITE setTrackerFont ) + + Q_PROPERTY( RubberBand rubberBand READ rubberBand WRITE setRubberBand ) + Q_PROPERTY( QPen rubberBandPen READ rubberBandPen WRITE setRubberBandPen ) + +public: + /*! + Rubber band style + + The default value is QwtPicker::NoRubberBand. + \sa setRubberBand(), rubberBand() + */ + + enum RubberBand + { + //! No rubberband. + NoRubberBand = 0, + + //! A horizontal line ( only for QwtPickerMachine::PointSelection ) + HLineRubberBand, + + //! A vertical line ( only for QwtPickerMachine::PointSelection ) + VLineRubberBand, + + //! A crosshair ( only for QwtPickerMachine::PointSelection ) + CrossRubberBand, + + //! A rectangle ( only for QwtPickerMachine::RectSelection ) + RectRubberBand, + + //! An ellipse ( only for QwtPickerMachine::RectSelection ) + EllipseRubberBand, + + //! A polygon ( only for QwtPickerMachine::PolygonSelection ) + PolygonRubberBand, + + /*! + Values >= UserRubberBand can be used to define additional + rubber bands. + */ + UserRubberBand = 100 + }; + + /*! + \brief Display mode + \sa setTrackerMode(), trackerMode(), isActive() + */ + enum DisplayMode + { + //! Display never + AlwaysOff, + + //! Display always + AlwaysOn, + + //! Display only when the selection is active + ActiveOnly + }; + + /*! + Controls what to do with the selected points of an active + selection when the observed widget is resized. + + The default value is QwtPicker::Stretch. + \sa setResizeMode() + */ + + enum ResizeMode + { + //! All points are scaled according to the new size, + Stretch, + + //! All points remain unchanged. + KeepSize + }; + + explicit QwtPicker( QWidget *parent ); + explicit QwtPicker( RubberBand rubberBand, + DisplayMode trackerMode, QWidget * ); + + virtual ~QwtPicker(); + + void setStateMachine( QwtPickerMachine * ); + const QwtPickerMachine *stateMachine() const; + QwtPickerMachine *stateMachine(); + + void setRubberBand( RubberBand ); + RubberBand rubberBand() const; + + void setTrackerMode( DisplayMode ); + DisplayMode trackerMode() const; + + void setResizeMode( ResizeMode ); + ResizeMode resizeMode() const; + + void setRubberBandPen( const QPen & ); + QPen rubberBandPen() const; + + void setTrackerPen( const QPen & ); + QPen trackerPen() const; + + void setTrackerFont( const QFont & ); + QFont trackerFont() const; + + bool isEnabled() const; + bool isActive() const; + + virtual bool eventFilter( QObject *, QEvent * ); + + QWidget *parentWidget(); + const QWidget *parentWidget() const; + + virtual QPainterPath pickArea() const; + + virtual void drawRubberBand( QPainter * ) const; + virtual void drawTracker( QPainter * ) const; + + virtual QRegion rubberBandMask() const; + + virtual QwtText trackerText( const QPoint &pos ) const; + QPoint trackerPosition() const; + virtual QRect trackerRect( const QFont & ) const; + + QPolygon selection() const; + +public Q_SLOTS: + void setEnabled( bool ); + +Q_SIGNALS: + /*! + A signal indicating, when the picker has been activated. + Together with setEnabled() it can be used to implement + selections with more than one picker. + + \param on True, when the picker has been activated + */ + void activated( bool on ); + + /*! + A signal emitting the selected points, + at the end of a selection. + + \param polygon Selected points + */ + void selected( const QPolygon &polygon ); + + /*! + A signal emitted when a point has been appended to the selection + + \param pos Position of the appended point. + \sa append(). moved() + */ + void appended( const QPoint &pos ); + + /*! + A signal emitted whenever the last appended point of the + selection has been moved. + + \param pos Position of the moved last point of the selection. + \sa move(), appended() + */ + void moved( const QPoint &pos ); + + /*! + A signal emitted whenever the last appended point of the + selection has been removed. + + \param pos Position of the point, that has been removed + \sa remove(), appended() + */ + void removed( const QPoint &pos ); + /*! + A signal emitted when the active selection has been changed. + This might happen when the observed widget is resized. + + \param selection Changed selection + \sa stretchSelection() + */ + void changed( const QPolygon &selection ); + +protected: + virtual QPolygon adjustedPoints( const QPolygon & ) const; + + virtual void transition( const QEvent * ); + + virtual void begin(); + virtual void append( const QPoint & ); + virtual void move( const QPoint & ); + virtual void remove(); + virtual bool end( bool ok = true ); + + virtual bool accept( QPolygon & ) const; + virtual void reset(); + + virtual void widgetMousePressEvent( QMouseEvent * ); + virtual void widgetMouseReleaseEvent( QMouseEvent * ); + virtual void widgetMouseDoubleClickEvent( QMouseEvent * ); + virtual void widgetMouseMoveEvent( QMouseEvent * ); + virtual void widgetWheelEvent( QWheelEvent * ); + virtual void widgetKeyPressEvent( QKeyEvent * ); + virtual void widgetKeyReleaseEvent( QKeyEvent * ); + virtual void widgetEnterEvent( QEvent * ); + virtual void widgetLeaveEvent( QEvent * ); + + virtual void stretchSelection( const QSize &oldSize, + const QSize &newSize ); + + virtual void updateDisplay(); + + const QwtWidgetOverlay *rubberBandOverlay() const; + const QwtWidgetOverlay *trackerOverlay() const; + + const QPolygon &pickedPoints() const; + +private: + void init( QWidget *, RubberBand rubberBand, DisplayMode trackerMode ); + + void setMouseTracking( bool ); + + class PrivateData; + PrivateData *d_data; +}; + +#endif diff --git a/ThirdParty/Qwt/src/qwt_picker_machine.cpp b/ThirdParty/Qwt/src/qwt_picker_machine.cpp new file mode 100644 index 0000000000..299624ed8d --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_picker_machine.cpp @@ -0,0 +1,526 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#include "qwt_picker_machine.h" +#include "qwt_event_pattern.h" +#include + +//! Constructor +QwtPickerMachine::QwtPickerMachine( SelectionType type ): + d_selectionType( type ), + d_state( 0 ) +{ +} + +//! Destructor +QwtPickerMachine::~QwtPickerMachine() +{ +} + +//! Return the selection type +QwtPickerMachine::SelectionType QwtPickerMachine::selectionType() const +{ + return d_selectionType; +} + +//! Return the current state +int QwtPickerMachine::state() const +{ + return d_state; +} + +//! Change the current state +void QwtPickerMachine::setState( int state ) +{ + d_state = state; +} + +//! Set the current state to 0. +void QwtPickerMachine::reset() +{ + setState( 0 ); +} + +//! Constructor +QwtPickerTrackerMachine::QwtPickerTrackerMachine(): + QwtPickerMachine( NoSelection ) +{ +} + +//! Transition +QList QwtPickerTrackerMachine::transition( + const QwtEventPattern &, const QEvent *e ) +{ + QList cmdList; + + switch ( e->type() ) + { + case QEvent::Enter: + case QEvent::MouseMove: + { + if ( state() == 0 ) + { + cmdList += Begin; + cmdList += Append; + setState( 1 ); + } + else + { + cmdList += Move; + } + break; + } + case QEvent::Leave: + { + cmdList += Remove; + cmdList += End; + setState( 0 ); + } + default: + break; + } + + return cmdList; +} + +//! Constructor +QwtPickerClickPointMachine::QwtPickerClickPointMachine(): + QwtPickerMachine( PointSelection ) +{ +} + +//! Transition +QList QwtPickerClickPointMachine::transition( + const QwtEventPattern &eventPattern, const QEvent *event ) +{ + QList cmdList; + + switch ( event->type() ) + { + case QEvent::MouseButtonPress: + { + if ( eventPattern.mouseMatch( QwtEventPattern::MouseSelect1, + static_cast( event ) ) ) + { + cmdList += Begin; + cmdList += Append; + cmdList += End; + } + break; + } + case QEvent::KeyPress: + { + if ( eventPattern.keyMatch( QwtEventPattern::KeySelect1, + static_cast ( event ) ) ) + { + cmdList += Begin; + cmdList += Append; + cmdList += End; + } + break; + } + default: + break; + } + + return cmdList; +} + +//! Constructor +QwtPickerDragPointMachine::QwtPickerDragPointMachine(): + QwtPickerMachine( PointSelection ) +{ +} + +//! Transition +QList QwtPickerDragPointMachine::transition( + const QwtEventPattern &eventPattern, const QEvent *event ) +{ + QList cmdList; + + switch ( event->type() ) + { + case QEvent::MouseButtonPress: + { + if ( eventPattern.mouseMatch( QwtEventPattern::MouseSelect1, + static_cast( event ) ) ) + { + if ( state() == 0 ) + { + cmdList += Begin; + cmdList += Append; + setState( 1 ); + } + } + break; + } + case QEvent::MouseMove: + case QEvent::Wheel: + { + if ( state() != 0 ) + cmdList += Move; + break; + } + case QEvent::MouseButtonRelease: + { + if ( state() != 0 ) + { + cmdList += End; + setState( 0 ); + } + break; + } + case QEvent::KeyPress: + { + if ( eventPattern.keyMatch( QwtEventPattern::KeySelect1, + static_cast( event ) ) ) + { + if ( state() == 0 ) + { + cmdList += Begin; + cmdList += Append; + setState( 1 ); + } + else + { + cmdList += End; + setState( 0 ); + } + } + break; + } + default: + break; + } + + return cmdList; +} + +//! Constructor +QwtPickerClickRectMachine::QwtPickerClickRectMachine(): + QwtPickerMachine( RectSelection ) +{ +} + +//! Transition +QList QwtPickerClickRectMachine::transition( + const QwtEventPattern &eventPattern, const QEvent *event ) +{ + QList cmdList; + + switch ( event->type() ) + { + case QEvent::MouseButtonPress: + { + if ( eventPattern.mouseMatch( QwtEventPattern::MouseSelect1, + static_cast( event ) ) ) + { + switch ( state() ) + { + case 0: + { + cmdList += Begin; + cmdList += Append; + setState( 1 ); + break; + } + case 1: + { + // Uh, strange we missed the MouseButtonRelease + break; + } + default: + { + cmdList += End; + setState( 0 ); + } + } + } + } + case QEvent::MouseMove: + case QEvent::Wheel: + { + if ( state() != 0 ) + cmdList += Move; + break; + } + case QEvent::MouseButtonRelease: + { + if ( eventPattern.mouseMatch( QwtEventPattern::MouseSelect1, + static_cast( event ) ) ) + { + if ( state() == 1 ) + { + cmdList += Append; + setState( 2 ); + } + } + break; + } + case QEvent::KeyPress: + { + if ( eventPattern.keyMatch( QwtEventPattern::KeySelect1, + static_cast ( event ) ) ) + { + if ( state() == 0 ) + { + cmdList += Begin; + cmdList += Append; + setState( 1 ); + } + else + { + if ( state() == 1 ) + { + cmdList += Append; + setState( 2 ); + } + else if ( state() == 2 ) + { + cmdList += End; + setState( 0 ); + } + } + } + break; + } + default: + break; + } + + return cmdList; +} + +//! Constructor +QwtPickerDragRectMachine::QwtPickerDragRectMachine(): + QwtPickerMachine( RectSelection ) +{ +} + +//! Transition +QList QwtPickerDragRectMachine::transition( + const QwtEventPattern &eventPattern, const QEvent *event ) +{ + QList cmdList; + + switch ( event->type() ) + { + case QEvent::MouseButtonPress: + { + if ( eventPattern.mouseMatch( QwtEventPattern::MouseSelect1, + static_cast( event ) ) ) + { + if ( state() == 0 ) + { + cmdList += Begin; + cmdList += Append; + cmdList += Append; + setState( 2 ); + } + } + break; + } + case QEvent::MouseMove: + case QEvent::Wheel: + { + if ( state() != 0 ) + cmdList += Move; + break; + } + case QEvent::MouseButtonRelease: + { + if ( state() == 2 ) + { + cmdList += End; + setState( 0 ); + } + break; + } + case QEvent::KeyPress: + { + if ( eventPattern.keyMatch( QwtEventPattern::KeySelect1, + static_cast ( event ) ) ) + { + if ( state() == 0 ) + { + cmdList += Begin; + cmdList += Append; + cmdList += Append; + setState( 2 ); + } + else + { + cmdList += End; + setState( 0 ); + } + } + break; + } + default: + break; + } + + return cmdList; +} + +//! Constructor +QwtPickerPolygonMachine::QwtPickerPolygonMachine(): + QwtPickerMachine( PolygonSelection ) +{ +} + +//! Transition +QList QwtPickerPolygonMachine::transition( + const QwtEventPattern &eventPattern, const QEvent *event ) +{ + QList cmdList; + + switch ( event->type() ) + { + case QEvent::MouseButtonPress: + { + if ( eventPattern.mouseMatch( QwtEventPattern::MouseSelect1, + static_cast( event ) ) ) + { + if ( state() == 0 ) + { + cmdList += Begin; + cmdList += Append; + cmdList += Append; + setState( 1 ); + } + else + { + cmdList += Append; + } + } + if ( eventPattern.mouseMatch( QwtEventPattern::MouseSelect2, + static_cast( event ) ) ) + { + if ( state() == 1 ) + { + cmdList += End; + setState( 0 ); + } + } + break; + } + case QEvent::MouseMove: + case QEvent::Wheel: + { + if ( state() != 0 ) + cmdList += Move; + break; + } + case QEvent::KeyPress: + { + if ( eventPattern.keyMatch( QwtEventPattern::KeySelect1, + static_cast ( event ) ) ) + { + if ( state() == 0 ) + { + cmdList += Begin; + cmdList += Append; + cmdList += Append; + setState( 1 ); + } + else + { + cmdList += Append; + } + } + else if ( eventPattern.keyMatch( QwtEventPattern::KeySelect2, + static_cast ( event ) ) ) + { + if ( state() == 1 ) + { + cmdList += End; + setState( 0 ); + } + } + break; + } + default: + break; + } + + return cmdList; +} + +//! Constructor +QwtPickerDragLineMachine::QwtPickerDragLineMachine(): + QwtPickerMachine( PolygonSelection ) +{ +} + +//! Transition +QList QwtPickerDragLineMachine::transition( + const QwtEventPattern &eventPattern, const QEvent *event ) +{ + QList cmdList; + + switch( event->type() ) + { + case QEvent::MouseButtonPress: + { + if ( eventPattern.mouseMatch( QwtEventPattern::MouseSelect1, + static_cast( event ) ) ) + { + if ( state() == 0 ) + { + cmdList += Begin; + cmdList += Append; + cmdList += Append; + setState( 1 ); + } + } + break; + } + case QEvent::KeyPress: + { + if ( eventPattern.keyMatch( QwtEventPattern::KeySelect1, + static_cast ( event ) ) ) + { + if ( state() == 0 ) + { + cmdList += Begin; + cmdList += Append; + cmdList += Append; + setState( 1 ); + } + else + { + cmdList += End; + setState( 0 ); + } + } + break; + } + case QEvent::MouseMove: + case QEvent::Wheel: + { + if ( state() != 0 ) + cmdList += Move; + + break; + } + case QEvent::MouseButtonRelease: + { + if ( state() != 0 ) + { + cmdList += End; + setState( 0 ); + } + } + default: + break; + } + + return cmdList; +} diff --git a/ThirdParty/Qwt/src/qwt_picker_machine.h b/ThirdParty/Qwt/src/qwt_picker_machine.h new file mode 100644 index 0000000000..6164b93b5b --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_picker_machine.h @@ -0,0 +1,214 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#ifndef QWT_PICKER_MACHINE +#define QWT_PICKER_MACHINE 1 + +#include "qwt_global.h" +#include + +class QEvent; +class QwtEventPattern; + +/*! + \brief A state machine for QwtPicker selections + + QwtPickerMachine accepts key and mouse events and translates them + into selection commands. + + \sa QwtEventPattern::MousePatternCode, QwtEventPattern::KeyPatternCode +*/ + +class QWT_EXPORT QwtPickerMachine +{ +public: + /*! + Type of a selection. + \sa selectionType() + */ + enum SelectionType + { + //! The state machine not usable for any type of selection. + NoSelection = -1, + + //! The state machine is for selecting a single point. + PointSelection, + + //! The state machine is for selecting a rectangle (2 points). + RectSelection, + + //! The state machine is for selecting a polygon (many points). + PolygonSelection + }; + + //! Commands - the output of a state machine + enum Command + { + Begin, + Append, + Move, + Remove, + End + }; + + QwtPickerMachine( SelectionType ); + virtual ~QwtPickerMachine(); + + //! Transition + virtual QList transition( + const QwtEventPattern &, const QEvent * ) = 0; + void reset(); + + int state() const; + void setState( int ); + + SelectionType selectionType() const; + +private: + const SelectionType d_selectionType; + int d_state; +}; + +/*! + \brief A state machine for indicating mouse movements + + QwtPickerTrackerMachine supports displaying information + corresponding to mouse movements, but is not intended for + selecting anything. Begin/End are related to Enter/Leave events. +*/ +class QWT_EXPORT QwtPickerTrackerMachine: public QwtPickerMachine +{ +public: + QwtPickerTrackerMachine(); + + virtual QList transition( + const QwtEventPattern &, const QEvent * ); +}; + +/*! + \brief A state machine for point selections + + Pressing QwtEventPattern::MouseSelect1 or + QwtEventPattern::KeySelect1 selects a point. + + \sa QwtEventPattern::MousePatternCode, QwtEventPattern::KeyPatternCode +*/ +class QWT_EXPORT QwtPickerClickPointMachine: public QwtPickerMachine +{ +public: + QwtPickerClickPointMachine(); + + virtual QList transition( + const QwtEventPattern &, const QEvent * ); +}; + +/*! + \brief A state machine for point selections + + Pressing QwtEventPattern::MouseSelect1 or QwtEventPattern::KeySelect1 + starts the selection, releasing QwtEventPattern::MouseSelect1 or + a second press of QwtEventPattern::KeySelect1 terminates it. +*/ +class QWT_EXPORT QwtPickerDragPointMachine: public QwtPickerMachine +{ +public: + QwtPickerDragPointMachine(); + + virtual QList transition( + const QwtEventPattern &, const QEvent * ); +}; + +/*! + \brief A state machine for rectangle selections + + Pressing QwtEventPattern::MouseSelect1 starts + the selection, releasing it selects the first point. Pressing it + again selects the second point and terminates the selection. + Pressing QwtEventPattern::KeySelect1 also starts the + selection, a second press selects the first point. A third one selects + the second point and terminates the selection. + + \sa QwtEventPattern::MousePatternCode, QwtEventPattern::KeyPatternCode +*/ + +class QWT_EXPORT QwtPickerClickRectMachine: public QwtPickerMachine +{ +public: + QwtPickerClickRectMachine(); + + virtual QList transition( + const QwtEventPattern &, const QEvent * ); +}; + +/*! + \brief A state machine for rectangle selections + + Pressing QwtEventPattern::MouseSelect1 selects + the first point, releasing it the second point. + Pressing QwtEventPattern::KeySelect1 also selects the + first point, a second press selects the second point and terminates + the selection. + + \sa QwtEventPattern::MousePatternCode, QwtEventPattern::KeyPatternCode +*/ + +class QWT_EXPORT QwtPickerDragRectMachine: public QwtPickerMachine +{ +public: + QwtPickerDragRectMachine(); + + virtual QList transition( + const QwtEventPattern &, const QEvent * ); +}; + +/*! + \brief A state machine for line selections + + Pressing QwtEventPattern::MouseSelect1 selects + the first point, releasing it the second point. + Pressing QwtEventPattern::KeySelect1 also selects the + first point, a second press selects the second point and terminates + the selection. + + A common use case of QwtPickerDragLineMachine are pickers for + distance measurements. + + \sa QwtEventPattern::MousePatternCode, QwtEventPattern::KeyPatternCode +*/ + +class QWT_EXPORT QwtPickerDragLineMachine: public QwtPickerMachine +{ +public: + QwtPickerDragLineMachine(); + + virtual QList transition( + const QwtEventPattern &, const QEvent * ); +}; + +/*! + \brief A state machine for polygon selections + + Pressing QwtEventPattern::MouseSelect1 or QwtEventPattern::KeySelect1 + starts the selection and selects the first point, or appends a point. + Pressing QwtEventPattern::MouseSelect2 or QwtEventPattern::KeySelect2 + appends the last point and terminates the selection. + + \sa QwtEventPattern::MousePatternCode, QwtEventPattern::KeyPatternCode +*/ + +class QWT_EXPORT QwtPickerPolygonMachine: public QwtPickerMachine +{ +public: + QwtPickerPolygonMachine(); + + virtual QList transition( + const QwtEventPattern &, const QEvent * ); +}; + +#endif diff --git a/ThirdParty/Qwt/src/qwt_pixel_matrix.cpp b/ThirdParty/Qwt/src/qwt_pixel_matrix.cpp new file mode 100644 index 0000000000..627992c7a1 --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_pixel_matrix.cpp @@ -0,0 +1,51 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2003 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#include "qwt_pixel_matrix.h" + +/*! + \brief Constructor + + \param rect Bounding rectangle for the matrix +*/ +QwtPixelMatrix::QwtPixelMatrix( const QRect& rect ): + QBitArray( qMax( rect.width() * rect.height(), 0 ) ), + d_rect( rect ) +{ +} + +//! Destructor +QwtPixelMatrix::~QwtPixelMatrix() +{ +} + +/*! + Set the bounding rectangle of the matrix + + \param rect Bounding rectangle + + \note All bits are cleared + */ +void QwtPixelMatrix::setRect( const QRect& rect ) +{ + if ( rect != d_rect ) + { + d_rect = rect; + const int sz = qMax( rect.width() * rect.height(), 0 ); + resize( sz ); + } + + fill( false ); +} + +//! \return Bounding rectangle +QRect QwtPixelMatrix::rect() const +{ + return d_rect; +} diff --git a/ThirdParty/Qwt/src/qwt_pixel_matrix.h b/ThirdParty/Qwt/src/qwt_pixel_matrix.h new file mode 100644 index 0000000000..0fe9daf1cb --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_pixel_matrix.h @@ -0,0 +1,98 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2003 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#ifndef QWT_PIXEL_MATRIX_H +#define QWT_PIXEL_MATRIX_H + +#include "qwt_global.h" +#include +#include + +/*! + \brief A bit field corresponding to the pixels of a rectangle + + QwtPixelMatrix is intended to filter out duplicates in an + unsorted array of points. +*/ +class QWT_EXPORT QwtPixelMatrix: public QBitArray +{ +public: + QwtPixelMatrix( const QRect& rect ); + ~QwtPixelMatrix(); + + void setRect( const QRect& rect ); + QRect rect() const; + + bool testPixel( int x, int y ) const; + bool testAndSetPixel( int x, int y, bool on ); + + int index( int x, int y ) const; + +private: + QRect d_rect; +}; + +/*! + \brief Test if a pixel has been set + + \param x X-coordinate + \param y Y-coordinate + + \return true, when pos is outside of rect(), or when the pixel + has already been set. + */ +inline bool QwtPixelMatrix::testPixel( int x, int y ) const +{ + const int idx = index( x, y ); + return ( idx >= 0 ) ? testBit( idx ) : true; +} + +/*! + \brief Set a pixel and test if a pixel has been set before + + \param x X-coordinate + \param y Y-coordinate + \param on Set/Clear the pixel + + \return true, when pos is outside of rect(), or when the pixel + was set before. + */ +inline bool QwtPixelMatrix::testAndSetPixel( int x, int y, bool on ) +{ + const int idx = index( x, y ); + if ( idx < 0 ) + return true; + + const bool onBefore = testBit( idx ); + setBit( idx, on ); + + return onBefore; +} + +/*! + \brief Calculate the index in the bit field corresponding to a position + + \param x X-coordinate + \param y Y-coordinate + \return Index, when rect() contains pos - otherwise -1. + */ +inline int QwtPixelMatrix::index( int x, int y ) const +{ + const int dx = x - d_rect.x(); + if ( dx < 0 || dx >= d_rect.width() ) + return -1; + + const int dy = y - d_rect.y(); + if ( dy < 0 || dy >= d_rect.height() ) + return -1; + + return dy * d_rect.width() + dx; +} + +#endif diff --git a/ThirdParty/Qwt/src/qwt_plot.cpp b/ThirdParty/Qwt/src/qwt_plot.cpp new file mode 100644 index 0000000000..dc63a3bd09 --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_plot.cpp @@ -0,0 +1,1163 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#include "qwt_plot.h" +#include "qwt_plot_dict.h" +#include "qwt_plot_layout.h" +#include "qwt_scale_widget.h" +#include "qwt_scale_engine.h" +#include "qwt_text_label.h" +#include "qwt_legend.h" +#include "qwt_legend_data.h" +#include "qwt_plot_canvas.h" +#include +#include +#include +#include +#include +#include + +static inline void qwtEnableLegendItems( QwtPlot *plot, bool on ) +{ + if ( on ) + { + QObject::connect( + plot, SIGNAL( legendDataChanged( + const QVariant &, const QList & ) ), + plot, SLOT( updateLegendItems( + const QVariant &, const QList & ) ) ); + } + else + { + QObject::disconnect( + plot, SIGNAL( legendDataChanged( + const QVariant &, const QList & ) ), + plot, SLOT( updateLegendItems( + const QVariant &, const QList & ) ) ); + } +} + +static void qwtSetTabOrder( + QWidget *first, QWidget *second, bool withChildren ) +{ + QList tabChain; + tabChain += first; + tabChain += second; + + if ( withChildren ) + { + QList children = second->findChildren(); + + QWidget *w = second->nextInFocusChain(); + while ( children.contains( w ) ) + { + children.removeAll( w ); + + tabChain += w; + w = w->nextInFocusChain(); + } + } + + for ( int i = 0; i < tabChain.size() - 1; i++ ) + { + QWidget *from = tabChain[i]; + QWidget *to = tabChain[i+1]; + + const Qt::FocusPolicy policy1 = from->focusPolicy(); + const Qt::FocusPolicy policy2 = to->focusPolicy(); + + QWidget *proxy1 = from->focusProxy(); + QWidget *proxy2 = to->focusProxy(); + + from->setFocusPolicy( Qt::TabFocus ); + from->setFocusProxy( NULL); + + to->setFocusPolicy( Qt::TabFocus ); + to->setFocusProxy( NULL); + + QWidget::setTabOrder( from, to ); + + from->setFocusPolicy( policy1 ); + from->setFocusProxy( proxy1); + + to->setFocusPolicy( policy2 ); + to->setFocusProxy( proxy2 ); + } +} + +class QwtPlot::PrivateData +{ +public: + QPointer titleLabel; + QPointer footerLabel; + QPointer canvas; + QPointer legend; + QwtPlotLayout *layout; + + bool autoReplot; +}; + +/*! + \brief Constructor + \param parent Parent widget + */ +QwtPlot::QwtPlot( QWidget *parent ): + QFrame( parent ) +{ + initPlot( QwtText() ); +} + +/*! + \brief Constructor + \param title Title text + \param parent Parent widget + */ +QwtPlot::QwtPlot( const QwtText &title, QWidget *parent ): + QFrame( parent ) +{ + initPlot( title ); +} + +//! Destructor +QwtPlot::~QwtPlot() +{ + detachItems( QwtPlotItem::Rtti_PlotItem, autoDelete() ); + + delete d_data->layout; + deleteAxesData(); + delete d_data; +} + +/*! + \brief Initializes a QwtPlot instance + \param title Title text + */ +void QwtPlot::initPlot( const QwtText &title ) +{ + d_data = new PrivateData; + + d_data->layout = new QwtPlotLayout; + d_data->autoReplot = false; + + // title + d_data->titleLabel = new QwtTextLabel( this ); + d_data->titleLabel->setObjectName( "QwtPlotTitle" ); + d_data->titleLabel->setFont( QFont( fontInfo().family(), 14, QFont::Bold ) ); + + QwtText text( title ); + text.setRenderFlags( Qt::AlignCenter | Qt::TextWordWrap ); + d_data->titleLabel->setText( text ); + + // footer + d_data->footerLabel = new QwtTextLabel( this ); + d_data->footerLabel->setObjectName( "QwtPlotFooter" ); + + QwtText footer; + footer.setRenderFlags( Qt::AlignCenter | Qt::TextWordWrap ); + d_data->footerLabel->setText( footer ); + + // legend + d_data->legend = NULL; + + // axis + initAxesData(); + + // canvas + d_data->canvas = new QwtPlotCanvas( this ); + d_data->canvas->setObjectName( "QwtPlotCanvas" ); + d_data->canvas->installEventFilter( this ); + + setSizePolicy( QSizePolicy::MinimumExpanding, + QSizePolicy::MinimumExpanding ); + + resize( 200, 200 ); + + QList focusChain; + focusChain << this << d_data->titleLabel << axisWidget( xTop ) + << axisWidget( yLeft ) << d_data->canvas << axisWidget( yRight ) + << axisWidget( xBottom ) << d_data->footerLabel; + + for ( int i = 0; i < focusChain.size() - 1; i++ ) + qwtSetTabOrder( focusChain[i], focusChain[i+1], false ); + + qwtEnableLegendItems( this, true ); +} + +/*! + \brief Set the drawing canvas of the plot widget + + QwtPlot invokes methods of the canvas as meta methods ( see QMetaObject ). + In opposite to using conventional C++ techniques like virtual methods + they allow to use canvas implementations that are derived from + QWidget or QGLWidget. + + The following meta methods could be implemented: + + - replot() + When the canvas doesn't offer a replot method, QwtPlot calls + update() instead. + + - borderPath() + The border path is necessary to clip the content of the canvas + When the canvas doesn't have any special border ( f.e rounded corners ) + it is o.k. not to implement this method. + + The default canvas is a QwtPlotCanvas + + \param canvas Canvas Widget + \sa canvas() + */ +void QwtPlot::setCanvas( QWidget *canvas ) +{ + if ( canvas == d_data->canvas ) + return; + + delete d_data->canvas; + d_data->canvas = canvas; + + if ( canvas ) + { + canvas->setParent( this ); + canvas->installEventFilter( this ); + + if ( isVisible() ) + canvas->show(); + } +} + +/*! + \brief Adds handling of layout requests + \param event Event + + \return See QFrame::event() +*/ +bool QwtPlot::event( QEvent *event ) +{ + bool ok = QFrame::event( event ); + switch ( event->type() ) + { + case QEvent::LayoutRequest: + updateLayout(); + break; + case QEvent::PolishRequest: + replot(); + break; + default:; + } + return ok; +} + +/*! + \brief Event filter + + The plot handles the following events for the canvas: + + - QEvent::Resize + The canvas margins might depend on its size + + - QEvent::ContentsRectChange + The layout needs to be recalculated + + \param object Object to be filtered + \param event Event + + \return See QFrame::eventFilter() + + \sa updateCanvasMargins(), updateLayout() +*/ +bool QwtPlot::eventFilter( QObject *object, QEvent *event ) +{ + if ( object == d_data->canvas ) + { + if ( event->type() == QEvent::Resize ) + { + updateCanvasMargins(); + } + else if ( event->type() == QEvent::ContentsRectChange ) + { + updateLayout(); + } + } + + return QFrame::eventFilter( object, event ); +} + +//! Replots the plot if autoReplot() is \c true. +void QwtPlot::autoRefresh() +{ + if ( d_data->autoReplot ) + replot(); +} + +/*! + \brief Set or reset the autoReplot option + + If the autoReplot option is set, the plot will be + updated implicitly by manipulating member functions. + Since this may be time-consuming, it is recommended + to leave this option switched off and call replot() + explicitly if necessary. + + The autoReplot option is set to false by default, which + means that the user has to call replot() in order to make + changes visible. + \param tf \c true or \c false. Defaults to \c true. + \sa replot() +*/ +void QwtPlot::setAutoReplot( bool tf ) +{ + d_data->autoReplot = tf; +} + +/*! + \return true if the autoReplot option is set. + \sa setAutoReplot() +*/ +bool QwtPlot::autoReplot() const +{ + return d_data->autoReplot; +} + +/*! + Change the plot's title + \param title New title +*/ +void QwtPlot::setTitle( const QString &title ) +{ + if ( title != d_data->titleLabel->text().text() ) + { + d_data->titleLabel->setText( title ); + updateLayout(); + } +} + +/*! + Change the plot's title + \param title New title +*/ +void QwtPlot::setTitle( const QwtText &title ) +{ + if ( title != d_data->titleLabel->text() ) + { + d_data->titleLabel->setText( title ); + updateLayout(); + } +} + +//! \return Title of the plot +QwtText QwtPlot::title() const +{ + return d_data->titleLabel->text(); +} + +//! \return Title label widget. +QwtTextLabel *QwtPlot::titleLabel() +{ + return d_data->titleLabel; +} + +//! \return Title label widget. +const QwtTextLabel *QwtPlot::titleLabel() const +{ + return d_data->titleLabel; +} + +/*! + Change the text the footer + \param text New text of the footer +*/ +void QwtPlot::setFooter( const QString &text ) +{ + if ( text != d_data->footerLabel->text().text() ) + { + d_data->footerLabel->setText( text ); + updateLayout(); + } +} + +/*! + Change the text the footer + \param text New text of the footer +*/ +void QwtPlot::setFooter( const QwtText &text ) +{ + if ( text != d_data->footerLabel->text() ) + { + d_data->footerLabel->setText( text ); + updateLayout(); + } +} + +//! \return Text of the footer +QwtText QwtPlot::footer() const +{ + return d_data->footerLabel->text(); +} + +//! \return Footer label widget. +QwtTextLabel *QwtPlot::footerLabel() +{ + return d_data->footerLabel; +} + +//! \return Footer label widget. +const QwtTextLabel *QwtPlot::footerLabel() const +{ + return d_data->footerLabel; +} + +/*! + \brief Assign a new plot layout + + \param layout Layout() + \sa plotLayout() + */ +void QwtPlot::setPlotLayout( QwtPlotLayout *layout ) +{ + if ( layout != d_data->layout ) + { + delete d_data->layout; + layout = d_data->layout; + + updateLayout(); + } +} + +//! \return the plot's layout +QwtPlotLayout *QwtPlot::plotLayout() +{ + return d_data->layout; +} + +//! \return the plot's layout +const QwtPlotLayout *QwtPlot::plotLayout() const +{ + return d_data->layout; +} + +/*! + \return the plot's legend + \sa insertLegend() +*/ +QwtAbstractLegend *QwtPlot::legend() +{ + return d_data->legend; +} + +/*! + \return the plot's legend + \sa insertLegend() +*/ +const QwtAbstractLegend *QwtPlot::legend() const +{ + return d_data->legend; +} + + +/*! + \return the plot's canvas +*/ +QWidget *QwtPlot::canvas() +{ + return d_data->canvas; +} + +/*! + \return the plot's canvas +*/ +const QWidget *QwtPlot::canvas() const +{ + return d_data->canvas; +} + +/*! + \return Size hint for the plot widget + \sa minimumSizeHint() +*/ +QSize QwtPlot::sizeHint() const +{ + int dw = 0; + int dh = 0; + for ( int axisId = 0; axisId < axisCnt; axisId++ ) + { + if ( axisEnabled( axisId ) ) + { + const int niceDist = 40; + const QwtScaleWidget *scaleWidget = axisWidget( axisId ); + const QwtScaleDiv &scaleDiv = scaleWidget->scaleDraw()->scaleDiv(); + const int majCnt = scaleDiv.ticks( QwtScaleDiv::MajorTick ).count(); + + if ( axisId == yLeft || axisId == yRight ) + { + int hDiff = ( majCnt - 1 ) * niceDist + - scaleWidget->minimumSizeHint().height(); + if ( hDiff > dh ) + dh = hDiff; + } + else + { + int wDiff = ( majCnt - 1 ) * niceDist + - scaleWidget->minimumSizeHint().width(); + if ( wDiff > dw ) + dw = wDiff; + } + } + } + return minimumSizeHint() + QSize( dw, dh ); +} + +/*! + \brief Return a minimum size hint +*/ +QSize QwtPlot::minimumSizeHint() const +{ + QSize hint = d_data->layout->minimumSizeHint( this ); + hint += QSize( 2 * frameWidth(), 2 * frameWidth() ); + + return hint; +} + +/*! + Resize and update internal layout + \param e Resize event +*/ +void QwtPlot::resizeEvent( QResizeEvent *e ) +{ + QFrame::resizeEvent( e ); + updateLayout(); +} + +/*! + \brief Redraw the plot + + If the autoReplot option is not set (which is the default) + or if any curves are attached to raw data, the plot has to + be refreshed explicitly in order to make changes visible. + + \sa updateAxes(), setAutoReplot() +*/ +void QwtPlot::replot() +{ + bool doAutoReplot = autoReplot(); + setAutoReplot( false ); + + updateAxes(); + + /* + Maybe the layout needs to be updated, because of changed + axes labels. We need to process them here before painting + to avoid that scales and canvas get out of sync. + */ + QApplication::sendPostedEvents( this, QEvent::LayoutRequest ); + + if ( d_data->canvas ) + { + const bool ok = QMetaObject::invokeMethod( + d_data->canvas, "replot", Qt::DirectConnection ); + if ( !ok ) + { + // fallback, when canvas has no a replot method + d_data->canvas->update( d_data->canvas->contentsRect() ); + } + } + + setAutoReplot( doAutoReplot ); +} + +/*! + \brief Adjust plot content to its current size. + \sa resizeEvent() +*/ +void QwtPlot::updateLayout() +{ + d_data->layout->activate( this, contentsRect() ); + + QRect titleRect = d_data->layout->titleRect().toRect(); + QRect footerRect = d_data->layout->footerRect().toRect(); + QRect scaleRect[QwtPlot::axisCnt]; + for ( int axisId = 0; axisId < axisCnt; axisId++ ) + scaleRect[axisId] = d_data->layout->scaleRect( axisId ).toRect(); + QRect legendRect = d_data->layout->legendRect().toRect(); + QRect canvasRect = d_data->layout->canvasRect().toRect(); + + // resize and show the visible widgets + + if ( !d_data->titleLabel->text().isEmpty() ) + { + d_data->titleLabel->setGeometry( titleRect ); + if ( !d_data->titleLabel->isVisibleTo( this ) ) + d_data->titleLabel->show(); + } + else + d_data->titleLabel->hide(); + + if ( !d_data->footerLabel->text().isEmpty() ) + { + d_data->footerLabel->setGeometry( footerRect ); + if ( !d_data->footerLabel->isVisibleTo( this ) ) + d_data->footerLabel->show(); + } + else + d_data->footerLabel->hide(); + + for ( int axisId = 0; axisId < axisCnt; axisId++ ) + { + if ( axisEnabled( axisId ) ) + { + axisWidget( axisId )->setGeometry( scaleRect[axisId] ); + +#if 1 + if ( axisId == xBottom || axisId == xTop ) + { + // do we need this code any longer ??? + + QRegion r( scaleRect[axisId] ); + if ( axisEnabled( yLeft ) ) + r = r.subtracted( QRegion( scaleRect[yLeft] ) ); + if ( axisEnabled( yRight ) ) + r = r.subtracted( QRegion( scaleRect[yRight] ) ); + r.translate( -scaleRect[ axisId ].x(), + -scaleRect[axisId].y() ); + + axisWidget( axisId )->setMask( r ); + } +#endif + if ( !axisWidget( axisId )->isVisibleTo( this ) ) + axisWidget( axisId )->show(); + } + else + axisWidget( axisId )->hide(); + } + + if ( d_data->legend ) + { + if ( d_data->legend->isEmpty() ) + { + d_data->legend->hide(); + } + else + { + d_data->legend->setGeometry( legendRect ); + d_data->legend->show(); + } + } + + d_data->canvas->setGeometry( canvasRect ); +} + +/*! + \brief Calculate the canvas margins + + \param maps QwtPlot::axisCnt maps, mapping between plot and paint device coordinates + \param canvasRect Bounding rectangle where to paint + \param left Return parameter for the left margin + \param top Return parameter for the top margin + \param right Return parameter for the right margin + \param bottom Return parameter for the bottom margin + + Plot items might indicate, that they need some extra space + at the borders of the canvas by the QwtPlotItem::Margins flag. + + updateCanvasMargins(), QwtPlotItem::getCanvasMarginHint() + */ +void QwtPlot::getCanvasMarginsHint( + const QwtScaleMap maps[], const QRectF &canvasRect, + double &left, double &top, double &right, double &bottom) const +{ + left = top = right = bottom = -1.0; + + const QwtPlotItemList& itmList = itemList(); + for ( QwtPlotItemIterator it = itmList.begin(); + it != itmList.end(); ++it ) + { + const QwtPlotItem *item = *it; + if ( item->testItemAttribute( QwtPlotItem::Margins ) ) + { + double m[ QwtPlot::axisCnt ]; + item->getCanvasMarginHint( + maps[ item->xAxis() ], maps[ item->yAxis() ], + canvasRect, m[yLeft], m[xTop], m[yRight], m[xBottom] ); + + left = qMax( left, m[yLeft] ); + top = qMax( top, m[xTop] ); + right = qMax( right, m[yRight] ); + bottom = qMax( bottom, m[xBottom] ); + } + } +} + +/*! + \brief Update the canvas margins + + Plot items might indicate, that they need some extra space + at the borders of the canvas by the QwtPlotItem::Margins flag. + + getCanvasMarginsHint(), QwtPlotItem::getCanvasMarginHint() + */ +void QwtPlot::updateCanvasMargins() +{ + QwtScaleMap maps[axisCnt]; + for ( int axisId = 0; axisId < axisCnt; axisId++ ) + maps[axisId] = canvasMap( axisId ); + + double margins[axisCnt]; + getCanvasMarginsHint( maps, canvas()->contentsRect(), + margins[yLeft], margins[xTop], margins[yRight], margins[xBottom] ); + + bool doUpdate = false; + for ( int axisId = 0; axisId < axisCnt; axisId++ ) + { + if ( margins[axisId] >= 0.0 ) + { + const int m = qCeil( margins[axisId] ); + plotLayout()->setCanvasMargin( m, axisId); + doUpdate = true; + } + } + + if ( doUpdate ) + updateLayout(); +} + +/*! + Redraw the canvas. + \param painter Painter used for drawing + + \warning drawCanvas calls drawItems what is also used + for printing. Applications that like to add individual + plot items better overload drawItems() + \sa drawItems() +*/ +void QwtPlot::drawCanvas( QPainter *painter ) +{ + QwtScaleMap maps[axisCnt]; + for ( int axisId = 0; axisId < axisCnt; axisId++ ) + maps[axisId] = canvasMap( axisId ); + + drawItems( painter, d_data->canvas->contentsRect(), maps ); +} + +/*! + Redraw the canvas items. + + \param painter Painter used for drawing + \param canvasRect Bounding rectangle where to paint + \param maps QwtPlot::axisCnt maps, mapping between plot and paint device coordinates + + \note Usually canvasRect is contentsRect() of the plot canvas. + Due to a bug in Qt this rectangle might be wrong for certain + frame styles ( f.e QFrame::Box ) and it might be necessary to + fix the margins manually using QWidget::setContentsMargins() +*/ + +void QwtPlot::drawItems( QPainter *painter, const QRectF &canvasRect, + const QwtScaleMap maps[axisCnt] ) const +{ + const QwtPlotItemList& itmList = itemList(); + for ( QwtPlotItemIterator it = itmList.begin(); + it != itmList.end(); ++it ) + { + QwtPlotItem *item = *it; + if ( item && item->isVisible() ) + { + painter->save(); + + painter->setRenderHint( QPainter::Antialiasing, + item->testRenderHint( QwtPlotItem::RenderAntialiased ) ); + painter->setRenderHint( QPainter::HighQualityAntialiasing, + item->testRenderHint( QwtPlotItem::RenderAntialiased ) ); + + item->draw( painter, + maps[item->xAxis()], maps[item->yAxis()], + canvasRect ); + + painter->restore(); + } + } +} + +/*! + \param axisId Axis + \return Map for the axis on the canvas. With this map pixel coordinates can + translated to plot coordinates and vice versa. + \sa QwtScaleMap, transform(), invTransform() + +*/ +QwtScaleMap QwtPlot::canvasMap( int axisId ) const +{ + QwtScaleMap map; + if ( !d_data->canvas ) + return map; + + map.setTransformation( axisScaleEngine( axisId )->transformation() ); + + const QwtScaleDiv &sd = axisScaleDiv( axisId ); + map.setScaleInterval( sd.lowerBound(), sd.upperBound() ); + + if ( axisEnabled( axisId ) ) + { + const QwtScaleWidget *s = axisWidget( axisId ); + if ( axisId == yLeft || axisId == yRight ) + { + double y = s->y() + s->startBorderDist() - d_data->canvas->y(); + double h = s->height() - s->startBorderDist() - s->endBorderDist(); + map.setPaintInterval( y + h, y ); + } + else + { + double x = s->x() + s->startBorderDist() - d_data->canvas->x(); + double w = s->width() - s->startBorderDist() - s->endBorderDist(); + map.setPaintInterval( x, x + w ); + } + } + else + { + int margin = 0; + if ( !plotLayout()->alignCanvasToScale( axisId ) ) + margin = plotLayout()->canvasMargin( axisId ); + + const QRect &canvasRect = d_data->canvas->contentsRect(); + if ( axisId == yLeft || axisId == yRight ) + { + map.setPaintInterval( canvasRect.bottom() - margin, + canvasRect.top() + margin ); + } + else + { + map.setPaintInterval( canvasRect.left() + margin, + canvasRect.right() - margin ); + } + } + return map; +} + +/*! + \brief Change the background of the plotting area + + Sets brush to QPalette::Window of all color groups of + the palette of the canvas. Using canvas()->setPalette() + is a more powerful way to set these colors. + + \param brush New background brush + \sa canvasBackground() +*/ +void QwtPlot::setCanvasBackground( const QBrush &brush ) +{ + QPalette pal = d_data->canvas->palette(); + pal.setBrush( QPalette::Window, brush ); + + canvas()->setPalette( pal ); +} + +/*! + Nothing else than: canvas()->palette().brush( + QPalette::Normal, QPalette::Window); + + \return Background brush of the plotting area. + \sa setCanvasBackground() +*/ +QBrush QwtPlot::canvasBackground() const +{ + return canvas()->palette().brush( + QPalette::Normal, QPalette::Window ); +} + +/*! + \return \c true if the specified axis exists, otherwise \c false + \param axisId axis index + */ +bool QwtPlot::axisValid( int axisId ) +{ + return ( ( axisId >= QwtPlot::yLeft ) && ( axisId < QwtPlot::axisCnt ) ); +} + +/*! + \brief Insert a legend + + If the position legend is \c QwtPlot::LeftLegend or \c QwtPlot::RightLegend + the legend will be organized in one column from top to down. + Otherwise the legend items will be placed in a table + with a best fit number of columns from left to right. + + insertLegend() will set the plot widget as parent for the legend. + The legend will be deleted in the destructor of the plot or when + another legend is inserted. + + Legends, that are not inserted into the layout of the plot widget + need to connect to the legendDataChanged() signal. Calling updateLegend() + initiates this signal for an initial update. When the application code + wants to implement its own layout this also needs to be done for + rendering plots to a document ( see QwtPlotRenderer ). + + \param legend Legend + \param pos The legend's position. For top/left position the number + of columns will be limited to 1, otherwise it will be set to + unlimited. + + \param ratio Ratio between legend and the bounding rectangle + of title, canvas and axes. The legend will be shrunk + if it would need more space than the given ratio. + The ratio is limited to ]0.0 .. 1.0]. In case of <= 0.0 + it will be reset to the default ratio. + The default vertical/horizontal ratio is 0.33/0.5. + + \sa legend(), QwtPlotLayout::legendPosition(), + QwtPlotLayout::setLegendPosition() +*/ +void QwtPlot::insertLegend( QwtAbstractLegend *legend, + QwtPlot::LegendPosition pos, double ratio ) +{ + d_data->layout->setLegendPosition( pos, ratio ); + + if ( legend != d_data->legend ) + { + if ( d_data->legend && d_data->legend->parent() == this ) + delete d_data->legend; + + d_data->legend = legend; + + if ( d_data->legend ) + { + connect( this, + SIGNAL( legendDataChanged( + const QVariant &, const QList & ) ), + d_data->legend, + SLOT( updateLegend( + const QVariant &, const QList & ) ) + ); + + if ( d_data->legend->parent() != this ) + d_data->legend->setParent( this ); + + qwtEnableLegendItems( this, false ); + updateLegend(); + qwtEnableLegendItems( this, true ); + + QwtLegend *lgd = qobject_cast( legend ); + if ( lgd ) + { + switch ( d_data->layout->legendPosition() ) + { + case LeftLegend: + case RightLegend: + { + if ( lgd->maxColumns() == 0 ) + lgd->setMaxColumns( 1 ); // 1 column: align vertical + break; + } + case TopLegend: + case BottomLegend: + { + lgd->setMaxColumns( 0 ); // unlimited + break; + } + default: + break; + } + } + + QWidget *previousInChain = NULL; + switch ( d_data->layout->legendPosition() ) + { + case LeftLegend: + { + previousInChain = axisWidget( QwtPlot::xTop ); + break; + } + case TopLegend: + { + previousInChain = this; + break; + } + case RightLegend: + { + previousInChain = axisWidget( QwtPlot::yRight ); + break; + } + case BottomLegend: + { + previousInChain = footerLabel(); + break; + } + } + + if ( previousInChain ) + qwtSetTabOrder( previousInChain, legend, true ); + } + } + + updateLayout(); +} + +/*! + Emit legendDataChanged() for all plot item + + \sa QwtPlotItem::legendData(), legendDataChanged() + */ +void QwtPlot::updateLegend() +{ + const QwtPlotItemList& itmList = itemList(); + for ( QwtPlotItemIterator it = itmList.begin(); + it != itmList.end(); ++it ) + { + updateLegend( *it ); + } +} + +/*! + Emit legendDataChanged() for a plot item + + \param plotItem Plot item + \sa QwtPlotItem::legendData(), legendDataChanged() + */ +void QwtPlot::updateLegend( const QwtPlotItem *plotItem ) +{ + if ( plotItem == NULL ) + return; + + QList legendData; + + if ( plotItem->testItemAttribute( QwtPlotItem::Legend ) ) + legendData = plotItem->legendData(); + + const QVariant itemInfo = itemToInfo( const_cast< QwtPlotItem *>( plotItem) ); + Q_EMIT legendDataChanged( itemInfo, legendData ); +} + +/*! + \brief Update all plot items interested in legend attributes + + Call QwtPlotItem::updateLegend(), when the QwtPlotItem::LegendInterest + flag is set. + + \param itemInfo Info about the plot item + \param legendData Entries to be displayed for the plot item ( usually 1 ) + + \sa QwtPlotItem::LegendInterest, + QwtPlotLegendItem, QwtPlotItem::updateLegend() + */ +void QwtPlot::updateLegendItems( const QVariant &itemInfo, + const QList &legendData ) +{ + QwtPlotItem *plotItem = infoToItem( itemInfo ); + if ( plotItem ) + { + const QwtPlotItemList& itmList = itemList(); + for ( QwtPlotItemIterator it = itmList.begin(); + it != itmList.end(); ++it ) + { + QwtPlotItem *item = *it; + if ( item->testItemInterest( QwtPlotItem::LegendInterest ) ) + item->updateLegend( plotItem, legendData ); + } + } +} + +/*! + \brief Attach/Detach a plot item + + \param plotItem Plot item + \param on When true attach the item, otherwise detach it + */ +void QwtPlot::attachItem( QwtPlotItem *plotItem, bool on ) +{ + if ( plotItem->testItemInterest( QwtPlotItem::LegendInterest ) ) + { + // plotItem is some sort of legend + + const QwtPlotItemList& itmList = itemList(); + for ( QwtPlotItemIterator it = itmList.begin(); + it != itmList.end(); ++it ) + { + QwtPlotItem *item = *it; + + QList legendData; + if ( on && item->testItemAttribute( QwtPlotItem::Legend ) ) + { + legendData = item->legendData(); + plotItem->updateLegend( item, legendData ); + } + } + } + + if ( on ) + insertItem( plotItem ); + else + removeItem( plotItem ); + + Q_EMIT itemAttached( plotItem, on ); + + if ( plotItem->testItemAttribute( QwtPlotItem::Legend ) ) + { + // the item wants to be represented on the legend + + if ( on ) + { + updateLegend( plotItem ); + } + else + { + const QVariant itemInfo = itemToInfo( plotItem ); + Q_EMIT legendDataChanged( itemInfo, QList() ); + } + } + + if ( autoReplot() ) + update(); +} + +/*! + \brief Build an information, that can be used to identify + a plot item on the legend. + + The default implementation simply wraps the plot item + into a QVariant object. When overloading itemToInfo() + usually infoToItem() needs to reimplemeted too. + +\code + QVariant itemInfo; + qVariantSetValue( itemInfo, plotItem ); +\endcode + + \param plotItem Plot item + \return Plot item embedded in a QVariant + \sa infoToItem() + */ +QVariant QwtPlot::itemToInfo( QwtPlotItem *plotItem ) const +{ + QVariant itemInfo; + qVariantSetValue( itemInfo, plotItem ); + + return itemInfo; +} + +/*! + \brief Identify the plot item according to an item info object, + that has bee generated from itemToInfo(). + + The default implementation simply tries to unwrap a QwtPlotItem + pointer: + +\code + if ( itemInfo.canConvert() ) + return qvariant_cast( itemInfo ); +\endcode + \param itemInfo Plot item + \return A plot item, when successful, otherwise a NULL pointer. + \sa itemToInfo() +*/ +QwtPlotItem *QwtPlot::infoToItem( const QVariant &itemInfo ) const +{ + if ( itemInfo.canConvert() ) + return qvariant_cast( itemInfo ); + + return NULL; +} + + diff --git a/ThirdParty/Qwt/src/qwt_plot.h b/ThirdParty/Qwt/src/qwt_plot.h new file mode 100644 index 0000000000..d6626136d8 --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_plot.h @@ -0,0 +1,312 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#ifndef QWT_PLOT_H +#define QWT_PLOT_H + +#include "qwt_global.h" +#include "qwt_text.h" +#include "qwt_plot_dict.h" +#include "qwt_scale_map.h" +#include "qwt_interval.h" +#include +#include +#include + +class QwtPlotLayout; +class QwtAbstractLegend; +class QwtScaleWidget; +class QwtScaleEngine; +class QwtScaleDiv; +class QwtScaleDraw; +class QwtTextLabel; + +/*! + \brief A 2-D plotting widget + + QwtPlot is a widget for plotting two-dimensional graphs. + An unlimited number of plot items can be displayed on + its canvas. Plot items might be curves (QwtPlotCurve), markers + (QwtPlotMarker), the grid (QwtPlotGrid), or anything else derived + from QwtPlotItem. + A plot can have up to four axes, with each plot item attached to an x- and + a y axis. The scales at the axes can be explicitly set (QwtScaleDiv), or + are calculated from the plot items, using algorithms (QwtScaleEngine) which + can be configured separately for each axis. + + The simpleplot example is a good starting point to see how to set up a + plot widget. + + \image html plot.png + + \par Example + The following example shows (schematically) the most simple + way to use QwtPlot. By default, only the left and bottom axes are + visible and their scales are computed automatically. + \verbatim +#include +#include + +QwtPlot *myPlot = new QwtPlot("Two Curves", parent); + +// add curves +QwtPlotCurve *curve1 = new QwtPlotCurve("Curve 1"); +QwtPlotCurve *curve2 = new QwtPlotCurve("Curve 2"); + +// connect or copy the data to the curves +curve1->setData(...); +curve2->setData(...); + +curve1->attach(myPlot); +curve2->attach(myPlot); + +// finally, refresh the plot +myPlot->replot(); +\endverbatim +*/ + +class QWT_EXPORT QwtPlot: public QFrame, public QwtPlotDict +{ + Q_OBJECT + + Q_PROPERTY( QBrush canvasBackground + READ canvasBackground WRITE setCanvasBackground ) + Q_PROPERTY( bool autoReplot READ autoReplot WRITE setAutoReplot ) + +#if 0 + // This property is intended to configure the plot + // widget from a special dialog in the deigner plugin. + // Disabled until such a dialog has been implemented. + + Q_PROPERTY( QString propertiesDocument + READ grabProperties WRITE applyProperties ) +#endif + +public: + //! \brief Axis index + enum Axis + { + //! Y axis left of the canvas + yLeft, + + //! Y axis right of the canvas + yRight, + + //! X axis below the canvas + xBottom, + + //! X axis above the canvas + xTop, + + //! Number of axes + axisCnt + }; + + /*! + Position of the legend, relative to the canvas. + + \sa insertLegend() + */ + enum LegendPosition + { + //! The legend will be left from the QwtPlot::yLeft axis. + LeftLegend, + + //! The legend will be right from the QwtPlot::yRight axis. + RightLegend, + + //! The legend will be below the footer + BottomLegend, + + //! The legend will be above the title + TopLegend + }; + + explicit QwtPlot( QWidget * = NULL ); + explicit QwtPlot( const QwtText &title, QWidget * = NULL ); + + virtual ~QwtPlot(); + + void applyProperties( const QString & ); + QString grabProperties() const; + + void setAutoReplot( bool = true ); + bool autoReplot() const; + + // Layout + + void setPlotLayout( QwtPlotLayout * ); + + QwtPlotLayout *plotLayout(); + const QwtPlotLayout *plotLayout() const; + + // Title + + void setTitle( const QString & ); + void setTitle( const QwtText &t ); + QwtText title() const; + + QwtTextLabel *titleLabel(); + const QwtTextLabel *titleLabel() const; + + // Footer + + void setFooter( const QString & ); + void setFooter( const QwtText &t ); + QwtText footer() const; + + QwtTextLabel *footerLabel(); + const QwtTextLabel *footerLabel() const; + + // Canvas + + void setCanvas( QWidget * ); + + QWidget *canvas(); + const QWidget *canvas() const; + + void setCanvasBackground( const QBrush & ); + QBrush canvasBackground() const; + + virtual QwtScaleMap canvasMap( int axisId ) const; + + double invTransform( int axisId, int pos ) const; + double transform( int axisId, double value ) const; + + // Axes + + QwtScaleEngine *axisScaleEngine( int axisId ); + const QwtScaleEngine *axisScaleEngine( int axisId ) const; + void setAxisScaleEngine( int axisId, QwtScaleEngine * ); + + void setAxisAutoScale( int axisId, bool on = true ); + bool axisAutoScale( int axisId ) const; + + void enableAxis( int axisId, bool tf = true ); + bool axisEnabled( int axisId ) const; + + void setAxisFont( int axisId, const QFont &f ); + QFont axisFont( int axisId ) const; + + void setAxisScale( int axisId, double min, double max, double step = 0 ); + void setAxisScaleDiv( int axisId, const QwtScaleDiv & ); + void setAxisScaleDraw( int axisId, QwtScaleDraw * ); + + double axisStepSize( int axisId ) const; + QwtInterval axisInterval( int axisId ) const; + + const QwtScaleDiv &axisScaleDiv( int axisId ) const; + + const QwtScaleDraw *axisScaleDraw( int axisId ) const; + QwtScaleDraw *axisScaleDraw( int axisId ); + + const QwtScaleWidget *axisWidget( int axisId ) const; + QwtScaleWidget *axisWidget( int axisId ); + + void setAxisLabelAlignment( int axisId, Qt::Alignment ); + void setAxisLabelRotation( int axisId, double rotation ); + + void setAxisTitle( int axisId, const QString & ); + void setAxisTitle( int axisId, const QwtText & ); + QwtText axisTitle( int axisId ) const; + + void setAxisMaxMinor( int axisId, int maxMinor ); + int axisMaxMinor( int axisId ) const; + + void setAxisMaxMajor( int axisId, int maxMajor ); + int axisMaxMajor( int axisId ) const; + + // Legend + + void insertLegend( QwtAbstractLegend *, + LegendPosition = QwtPlot::RightLegend, double ratio = -1.0 ); + + QwtAbstractLegend *legend(); + const QwtAbstractLegend *legend() const; + + void updateLegend(); + void updateLegend( const QwtPlotItem * ); + + // Misc + + virtual QSize sizeHint() const; + virtual QSize minimumSizeHint() const; + + virtual void updateLayout(); + virtual void drawCanvas( QPainter * ); + + void updateAxes(); + void updateCanvasMargins(); + + virtual void getCanvasMarginsHint( + const QwtScaleMap maps[], const QRectF &canvasRect, + double &left, double &top, double &right, double &bottom) const; + + virtual bool event( QEvent * ); + virtual bool eventFilter( QObject *, QEvent * ); + + virtual void drawItems( QPainter *, const QRectF &, + const QwtScaleMap maps[axisCnt] ) const; + + virtual QVariant itemToInfo( QwtPlotItem * ) const; + virtual QwtPlotItem *infoToItem( const QVariant & ) const; + +Q_SIGNALS: + /*! + A signal indicating, that an item has been attached/detached + + \param plotItem Plot item + \param on Attached/Detached + */ + void itemAttached( QwtPlotItem *plotItem, bool on ); + + /*! + A signal with the attributes how to update + the legend entries for a plot item. + + \param itemInfo Info about a plot item, build from itemToInfo() + \param data Attributes of the entries ( usually <= 1 ) for + the plot item. + + \sa itemToInfo(), infoToItem(), QwtAbstractLegend::updateLegend() + */ + void legendDataChanged( const QVariant &itemInfo, + const QList &data ); + +public Q_SLOTS: + virtual void replot(); + void autoRefresh(); + +protected: + static bool axisValid( int axisId ); + + virtual void resizeEvent( QResizeEvent *e ); + +private Q_SLOTS: + void updateLegendItems( const QVariant &itemInfo, + const QList &data ); + +private: + friend class QwtPlotItem; + void attachItem( QwtPlotItem *, bool ); + + void initAxesData(); + void deleteAxesData(); + void updateScaleDiv(); + + void initPlot( const QwtText &title ); + + class AxisData; + AxisData *d_axisData[axisCnt]; + + class PrivateData; + PrivateData *d_data; +}; + +#endif diff --git a/ThirdParty/Qwt/src/qwt_plot_abstract_barchart.cpp b/ThirdParty/Qwt/src/qwt_plot_abstract_barchart.cpp new file mode 100644 index 0000000000..9a72fdd5b3 --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_plot_abstract_barchart.cpp @@ -0,0 +1,367 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#include "qwt_plot_abstract_barchart.h" +#include "qwt_scale_map.h" + +static inline double qwtTransformWidth( + const QwtScaleMap &map, double value, double width ) +{ + const double w2 = 0.5 * width; + + const double v1 = map.transform( value - w2 ); + const double v2 = map.transform( value + w2 ); + + return qAbs( v2 - v1 ); +} + +class QwtPlotAbstractBarChart::PrivateData +{ +public: + PrivateData(): + layoutPolicy( QwtPlotAbstractBarChart::AutoAdjustSamples ), + layoutHint( 0.5 ), + spacing( 10 ), + margin( 5 ), + baseline( 0.0 ) + { + } + + QwtPlotAbstractBarChart::LayoutPolicy layoutPolicy; + double layoutHint; + int spacing; + int margin; + double baseline; +}; + +/*! + Constructor + \param title Title of the chart +*/ +QwtPlotAbstractBarChart::QwtPlotAbstractBarChart( const QwtText &title ): + QwtPlotSeriesItem( title ) +{ + d_data = new PrivateData; + + setItemAttribute( QwtPlotItem::Legend, true ); + setItemAttribute( QwtPlotItem::AutoScale, true ); + setItemAttribute( QwtPlotItem::Margins, true ); + setZ( 19.0 ); +} + +//! Destructor +QwtPlotAbstractBarChart::~QwtPlotAbstractBarChart() +{ + delete d_data; +} + +/*! + The combination of layoutPolicy() and layoutHint() define how the width + of the bars is calculated + + \param policy Layout policy + + \sa layoutPolicy(), layoutHint() + */ +void QwtPlotAbstractBarChart::setLayoutPolicy( LayoutPolicy policy ) +{ + if ( policy != d_data->layoutPolicy ) + { + d_data->layoutPolicy = policy; + itemChanged(); + } +} + +/*! + The combination of layoutPolicy() and layoutHint() define how the width + of the bars is calculated + + \return Layout policy of the chart item + \sa setLayoutPolicy(), layoutHint() + */ +QwtPlotAbstractBarChart::LayoutPolicy QwtPlotAbstractBarChart::layoutPolicy() const +{ + return d_data->layoutPolicy; +} + +/*! + The combination of layoutPolicy() and layoutHint() define how the width + of the bars is calculated + + \param hint Layout hint + + \sa LayoutPolicy, layoutPolicy(), layoutHint() + */ +void QwtPlotAbstractBarChart::setLayoutHint( double hint ) +{ + hint = qMax( 0.0, hint ); + if ( hint != d_data->layoutHint ) + { + d_data->layoutHint = hint; + itemChanged(); + } +} + +/*! + The combination of layoutPolicy() and layoutHint() define how the width + of the bars is calculated + + \return Layout policy of the chart item + \sa LayoutPolicy, setLayoutHint(), layoutPolicy() +*/ +double QwtPlotAbstractBarChart::layoutHint() const +{ + return d_data->layoutHint; +} + +/*! + \brief Set the spacing + + The spacing is the distance between 2 samples ( bars for QwtPlotBarChart or + a group of bars for QwtPlotMultiBarChart ) in paint device coordinates. + + \sa spacing() + */ +void QwtPlotAbstractBarChart::setSpacing( int spacing ) +{ + spacing = qMax( spacing, 0 ); + if ( spacing != d_data->spacing ) + { + d_data->spacing = spacing; + itemChanged(); + } +} + +/*! + \return Spacing between 2 samples ( bars or groups of bars ) + \sa setSpacing(), margin() + */ +int QwtPlotAbstractBarChart::spacing() const +{ + return d_data->spacing; +} +/*! + \brief Set the margin + + The margin is the distance between the outmost bars and the contentsRect() + of the canvas. The default setting is 5 pixels. + + \param margin Margin + + \sa spacing(), margin() + */ +void QwtPlotAbstractBarChart::setMargin( int margin ) +{ + margin = qMax( margin, 0 ); + if ( margin != d_data->margin ) + { + d_data->margin = margin; + itemChanged(); + } +} + +/*! + \return Margin between the outmost bars and the contentsRect() + of the canvas. + + \sa setMargin(), spacing() + */ +int QwtPlotAbstractBarChart::margin() const +{ + return d_data->margin; +} + +/*! + \brief Set the baseline + + The baseline is the origin for the chart. Each bar is + painted from the baseline in the direction of the sample + value. In case of a horizontal orientation() the baseline + is interpreted as x - otherwise as y - value. + + The default value for the baseline is 0. + + \param value Value for the baseline + + \sa baseline(), QwtPlotSeriesItem::orientation() +*/ +void QwtPlotAbstractBarChart::setBaseline( double value ) +{ + if ( value != d_data->baseline ) + { + d_data->baseline = value; + itemChanged(); + } +} + +/*! + \return Value for the origin of the bar chart + \sa setBaseline(), QwtPlotSeriesItem::orientation() + */ +double QwtPlotAbstractBarChart::baseline() const +{ + return d_data->baseline; +} + +/*! + Calculate the width for a sample in paint device coordinates + + \param map Scale map for the corresponding scale + \param canvasSize Size of the canvas in paint device coordinates + \param boundingSize Bounding size of the chart in plot coordinates + ( used in AutoAdjustSamples mode ) + \param value Value of the sample + + \return Sample width + \sa layoutPolicy(), layoutHint() +*/ +double QwtPlotAbstractBarChart::sampleWidth( const QwtScaleMap &map, + double canvasSize, double boundingSize, double value ) const +{ + double width; + + switch( d_data->layoutPolicy ) + { + case ScaleSamplesToAxes: + { + width = qwtTransformWidth( map, value, d_data->layoutHint ); + break; + } + case ScaleSampleToCanvas: + { + width = canvasSize * d_data->layoutHint; + break; + } + case FixedSampleSize: + { + width = d_data->layoutHint; + break; + } + case AutoAdjustSamples: + default: + { + const size_t numSamples = dataSize(); + + double w = 1.0; + if ( numSamples > 1 ) + { + w = qAbs( boundingSize / ( numSamples - 1 ) ); + } + + width = qwtTransformWidth( map, value, w ); + width -= d_data->spacing; + } + } + + return width; +} + +/*! + \brief Calculate a hint for the canvas margin + + Bar charts need to reserve some space for displaying the bars + for the first and the last sample. The hint is calculated + from the layoutHint() depending on the layoutPolicy(). + + The margins are in target device coordinates ( pixels on screen ) + + \param xMap Maps x-values into pixel coordinates. + \param yMap Maps y-values into pixel coordinates. + \param canvasRect Contents rectangle of the canvas in painter coordinates + \param left Returns the left margin + \param top Returns the top margin + \param right Returns the right margin + \param bottom Returns the bottom margin + + \return Margin + + \sa layoutPolicy(), layoutHint(), QwtPlotItem::Margins + QwtPlot::getCanvasMarginsHint(), QwtPlot::updateCanvasMargins() + */ +void QwtPlotAbstractBarChart::getCanvasMarginHint( const QwtScaleMap &xMap, + const QwtScaleMap &yMap, const QRectF &canvasRect, + double &left, double &top, double &right, double &bottom ) const +{ + double hint = -1.0; + + switch( layoutPolicy() ) + { + case ScaleSampleToCanvas: + { + if ( orientation() == Qt::Vertical ) + hint = 0.5 * canvasRect.width() * d_data->layoutHint; + else + hint = 0.5 * canvasRect.height() * d_data->layoutHint; + + break; + } + case FixedSampleSize: + { + hint = 0.5 * d_data->layoutHint; + break; + } + case AutoAdjustSamples: + case ScaleSamplesToAxes: + default: + { + const size_t numSamples = dataSize(); + if ( numSamples <= 0 ) + break; + + // doesn't work for nonlinear scales + + const QRectF br = dataRect(); + double spacing = 0.0; + double sampleWidthS = 1.0; + + if ( layoutPolicy() == ScaleSamplesToAxes ) + { + sampleWidthS = qMax( d_data->layoutHint, 0.0 ); + } + else + { + spacing = d_data->spacing; + + if ( numSamples > 1 ) + { + sampleWidthS = qAbs( br.width() / ( numSamples - 1 ) ); + } + } + + double ds, w; + if ( orientation() == Qt::Vertical ) + { + ds = qAbs( xMap.sDist() ); + w = canvasRect.width(); + } + else + { + ds = qAbs( yMap.sDist() ); + w = canvasRect.height(); + } + + const double sampleWidthP = ( w - spacing * ds ) + * sampleWidthS / ( ds + sampleWidthS ); + + hint = 0.5 * sampleWidthP; + hint += qMax( d_data->margin, 0 ); + } + } + + if ( orientation() == Qt::Vertical ) + { + left = right = hint; + top = bottom = -1.0; // no hint + } + else + { + left = right = -1.0; // no hint + top = bottom = hint; + } +} diff --git a/ThirdParty/Qwt/src/qwt_plot_abstract_barchart.h b/ThirdParty/Qwt/src/qwt_plot_abstract_barchart.h new file mode 100644 index 0000000000..78b98a5314 --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_plot_abstract_barchart.h @@ -0,0 +1,97 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#ifndef QWT_PLOT_ABSTRACT_BAR_CHART_H +#define QWT_PLOT_ABSTRACT_BAR_CHART_H + +#include "qwt_global.h" +#include "qwt_plot_seriesitem.h" +#include "qwt_series_data.h" + +/*! + \brief Abstract base class for bar chart items + + In opposite to almost all other plot items bar charts can't be + displayed inside of their bounding rectangle and need a special + API how to calculate the width of the bars and how they affect + the layout of the attached plot. + */ +class QWT_EXPORT QwtPlotAbstractBarChart: public QwtPlotSeriesItem +{ +public: + /*! + \brief Mode how to calculate the bar width + + setLayoutPolicy(), setLayoutHint(), barWidthHint() + */ + enum LayoutPolicy + { + /*! + The sample width is calculated by dividing the bounding rectangle + by the number of samples. + + \sa boundingRectangle() + \note The layoutHint() is ignored + */ + AutoAdjustSamples, + + /*! + layoutHint() defines an interval in axis coordinates + */ + ScaleSamplesToAxes, + + /*! + The bar width is calculated by multiplying layoutHint() + with the height or width of the canvas. + + \sa boundingRectangle() + */ + ScaleSampleToCanvas, + + /*! + layoutHint() defines a fixed width in paint device coordinates. + */ + FixedSampleSize + }; + + explicit QwtPlotAbstractBarChart( const QwtText &title ); + virtual ~QwtPlotAbstractBarChart(); + + void setLayoutPolicy( LayoutPolicy ); + LayoutPolicy layoutPolicy() const; + + void setLayoutHint( double ); + double layoutHint() const; + + void setSpacing( int ); + int spacing() const; + + void setMargin( int ); + int margin() const; + + void setBaseline( double ); + double baseline() const; + + virtual void getCanvasMarginHint( + const QwtScaleMap &xMap, const QwtScaleMap &yMap, + const QRectF &canvasRect, + double &left, double &top, double &right, double &bottom) const; + + +protected: + double sampleWidth( const QwtScaleMap &map, + double canvasSize, double dataSize, + double value ) const; + +private: + class PrivateData; + PrivateData *d_data; +}; + +#endif diff --git a/ThirdParty/Qwt/src/qwt_plot_axis.cpp b/ThirdParty/Qwt/src/qwt_plot_axis.cpp new file mode 100644 index 0000000000..e3802f68ec --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_plot_axis.cpp @@ -0,0 +1,719 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#include "qwt_plot.h" +#include "qwt_math.h" +#include "qwt_scale_widget.h" +#include "qwt_scale_div.h" +#include "qwt_scale_engine.h" + +class QwtPlot::AxisData +{ +public: + bool isEnabled; + bool doAutoScale; + + double minValue; + double maxValue; + double stepSize; + + int maxMajor; + int maxMinor; + + bool isValid; + + QwtScaleDiv scaleDiv; + QwtScaleEngine *scaleEngine; + QwtScaleWidget *scaleWidget; +}; + +//! Initialize axes +void QwtPlot::initAxesData() +{ + int axisId; + + for ( axisId = 0; axisId < axisCnt; axisId++ ) + d_axisData[axisId] = new AxisData; + + d_axisData[yLeft]->scaleWidget = + new QwtScaleWidget( QwtScaleDraw::LeftScale, this ); + d_axisData[yRight]->scaleWidget = + new QwtScaleWidget( QwtScaleDraw::RightScale, this ); + d_axisData[xTop]->scaleWidget = + new QwtScaleWidget( QwtScaleDraw::TopScale, this ); + d_axisData[xBottom]->scaleWidget = + new QwtScaleWidget( QwtScaleDraw::BottomScale, this ); + + d_axisData[yLeft]->scaleWidget->setObjectName( "QwtPlotAxisYLeft" ); + d_axisData[yRight]->scaleWidget->setObjectName( "QwtPlotAxisYRight" ); + d_axisData[xTop]->scaleWidget->setObjectName( "QwtPlotAxisXTop" ); + d_axisData[xBottom]->scaleWidget->setObjectName( "QwtPlotAxisXBottom" ); + +#if 1 + // better find the font sizes from the application font + QFont fscl( fontInfo().family(), 10 ); + QFont fttl( fontInfo().family(), 12, QFont::Bold ); +#endif + + for ( axisId = 0; axisId < axisCnt; axisId++ ) + { + AxisData &d = *d_axisData[axisId]; + + d.scaleEngine = new QwtLinearScaleEngine; + + d.scaleWidget->setTransformation( + d.scaleEngine->transformation() ); + + d.scaleWidget->setFont( fscl ); + d.scaleWidget->setMargin( 2 ); + + QwtText text = d.scaleWidget->title(); + text.setFont( fttl ); + d.scaleWidget->setTitle( text ); + + d.doAutoScale = true; + + d.minValue = 0.0; + d.maxValue = 1000.0; + d.stepSize = 0.0; + + d.maxMinor = 5; + d.maxMajor = 8; + + + d.isValid = false; + } + + d_axisData[yLeft]->isEnabled = true; + d_axisData[yRight]->isEnabled = false; + d_axisData[xBottom]->isEnabled = true; + d_axisData[xTop]->isEnabled = false; +} + +void QwtPlot::deleteAxesData() +{ + for ( int axisId = 0; axisId < axisCnt; axisId++ ) + { + delete d_axisData[axisId]->scaleEngine; + delete d_axisData[axisId]; + d_axisData[axisId] = NULL; + } +} + +/*! + \return Scale widget of the specified axis, or NULL if axisId is invalid. + \param axisId Axis index +*/ +const QwtScaleWidget *QwtPlot::axisWidget( int axisId ) const +{ + if ( axisValid( axisId ) ) + return d_axisData[axisId]->scaleWidget; + + return NULL; +} + +/*! + \return Scale widget of the specified axis, or NULL if axisId is invalid. + \param axisId Axis index +*/ +QwtScaleWidget *QwtPlot::axisWidget( int axisId ) +{ + if ( axisValid( axisId ) ) + return d_axisData[axisId]->scaleWidget; + + return NULL; +} + +/*! + Change the scale engine for an axis + + \param axisId Axis index + \param scaleEngine Scale engine + + \sa axisScaleEngine() +*/ +void QwtPlot::setAxisScaleEngine( int axisId, QwtScaleEngine *scaleEngine ) +{ + if ( axisValid( axisId ) && scaleEngine != NULL ) + { + AxisData &d = *d_axisData[axisId]; + + delete d.scaleEngine; + d.scaleEngine = scaleEngine; + + d_axisData[axisId]->scaleWidget->setTransformation( + scaleEngine->transformation() ); + + d.isValid = false; + + autoRefresh(); + } +} + +/*! + \param axisId Axis index + \return Scale engine for a specific axis +*/ +QwtScaleEngine *QwtPlot::axisScaleEngine( int axisId ) +{ + if ( axisValid( axisId ) ) + return d_axisData[axisId]->scaleEngine; + else + return NULL; +} + +/*! + \param axisId Axis index + \return Scale engine for a specific axis +*/ +const QwtScaleEngine *QwtPlot::axisScaleEngine( int axisId ) const +{ + if ( axisValid( axisId ) ) + return d_axisData[axisId]->scaleEngine; + else + return NULL; +} +/*! + \return \c True, if autoscaling is enabled + \param axisId Axis index +*/ +bool QwtPlot::axisAutoScale( int axisId ) const +{ + if ( axisValid( axisId ) ) + return d_axisData[axisId]->doAutoScale; + else + return false; + +} + +/*! + \return \c True, if a specified axis is enabled + \param axisId Axis index +*/ +bool QwtPlot::axisEnabled( int axisId ) const +{ + if ( axisValid( axisId ) ) + return d_axisData[axisId]->isEnabled; + else + return false; +} + +/*! + \return The font of the scale labels for a specified axis + \param axisId Axis index +*/ +QFont QwtPlot::axisFont( int axisId ) const +{ + if ( axisValid( axisId ) ) + return axisWidget( axisId )->font(); + else + return QFont(); + +} + +/*! + \return The maximum number of major ticks for a specified axis + \param axisId Axis index + \sa setAxisMaxMajor(), QwtScaleEngine::divideScale() +*/ +int QwtPlot::axisMaxMajor( int axisId ) const +{ + if ( axisValid( axisId ) ) + return d_axisData[axisId]->maxMajor; + else + return 0; +} + +/*! + \return the maximum number of minor ticks for a specified axis + \param axisId Axis index + \sa setAxisMaxMinor(), QwtScaleEngine::divideScale() +*/ +int QwtPlot::axisMaxMinor( int axisId ) const +{ + if ( axisValid( axisId ) ) + return d_axisData[axisId]->maxMinor; + else + return 0; +} + +/*! + \brief Return the scale division of a specified axis + + axisScaleDiv(axisId).lowerBound(), axisScaleDiv(axisId).upperBound() + are the current limits of the axis scale. + + \param axisId Axis index + \return Scale division + + \sa QwtScaleDiv, setAxisScaleDiv(), QwtScaleEngine::divideScale() +*/ +const QwtScaleDiv &QwtPlot::axisScaleDiv( int axisId ) const +{ + return d_axisData[axisId]->scaleDiv; +} + +/*! + \brief Return the scale draw of a specified axis + + \param axisId Axis index + \return Specified scaleDraw for axis, or NULL if axis is invalid. +*/ +const QwtScaleDraw *QwtPlot::axisScaleDraw( int axisId ) const +{ + if ( !axisValid( axisId ) ) + return NULL; + + return axisWidget( axisId )->scaleDraw(); +} + +/*! + \brief Return the scale draw of a specified axis + + \param axisId Axis index + \return Specified scaleDraw for axis, or NULL if axis is invalid. +*/ +QwtScaleDraw *QwtPlot::axisScaleDraw( int axisId ) +{ + if ( !axisValid( axisId ) ) + return NULL; + + return axisWidget( axisId )->scaleDraw(); +} + +/*! + \brief Return the step size parameter that has been set in setAxisScale. + + This doesn't need to be the step size of the current scale. + + \param axisId Axis index + \return step size parameter value + + \sa setAxisScale(), QwtScaleEngine::divideScale() +*/ +double QwtPlot::axisStepSize( int axisId ) const +{ + if ( !axisValid( axisId ) ) + return 0; + + return d_axisData[axisId]->stepSize; +} + +/*! + \brief Return the current interval of the specified axis + + This is only a convenience function for axisScaleDiv( axisId )->interval(); + + \param axisId Axis index + \return Scale interval + + \sa QwtScaleDiv, axisScaleDiv() +*/ +QwtInterval QwtPlot::axisInterval( int axisId ) const +{ + if ( !axisValid( axisId ) ) + return QwtInterval(); + + return d_axisData[axisId]->scaleDiv.interval(); +} + +/*! + \return Title of a specified axis + \param axisId Axis index +*/ +QwtText QwtPlot::axisTitle( int axisId ) const +{ + if ( axisValid( axisId ) ) + return axisWidget( axisId )->title(); + else + return QwtText(); +} + +/*! + \brief Enable or disable a specified axis + + When an axis is disabled, this only means that it is not + visible on the screen. Curves, markers and can be attached + to disabled axes, and transformation of screen coordinates + into values works as normal. + + Only xBottom and yLeft are enabled by default. + + \param axisId Axis index + \param tf \c true (enabled) or \c false (disabled) +*/ +void QwtPlot::enableAxis( int axisId, bool tf ) +{ + if ( axisValid( axisId ) && tf != d_axisData[axisId]->isEnabled ) + { + d_axisData[axisId]->isEnabled = tf; + updateLayout(); + } +} + +/*! + Transform the x or y coordinate of a position in the + drawing region into a value. + + \param axisId Axis index + \param pos position + + \return Position as axis coordinate + + \warning The position can be an x or a y coordinate, + depending on the specified axis. +*/ +double QwtPlot::invTransform( int axisId, int pos ) const +{ + if ( axisValid( axisId ) ) + return( canvasMap( axisId ).invTransform( pos ) ); + else + return 0.0; +} + + +/*! + \brief Transform a value into a coordinate in the plotting region + + \param axisId Axis index + \param value value + \return X or Y coordinate in the plotting region corresponding + to the value. +*/ +double QwtPlot::transform( int axisId, double value ) const +{ + if ( axisValid( axisId ) ) + return( canvasMap( axisId ).transform( value ) ); + else + return 0.0; +} + +/*! + \brief Change the font of an axis + + \param axisId Axis index + \param font Font + \warning This function changes the font of the tick labels, + not of the axis title. +*/ +void QwtPlot::setAxisFont( int axisId, const QFont &font ) +{ + if ( axisValid( axisId ) ) + axisWidget( axisId )->setFont( font ); +} + +/*! + \brief Enable autoscaling for a specified axis + + This member function is used to switch back to autoscaling mode + after a fixed scale has been set. Autoscaling is enabled by default. + + \param axisId Axis index + \param on On/Off + \sa setAxisScale(), setAxisScaleDiv(), updateAxes() + + \note The autoscaling flag has no effect until updateAxes() is executed + ( called by replot() ). +*/ +void QwtPlot::setAxisAutoScale( int axisId, bool on ) +{ + if ( axisValid( axisId ) && ( d_axisData[axisId]->doAutoScale != on ) ) + { + d_axisData[axisId]->doAutoScale = on; + autoRefresh(); + } +} + +/*! + \brief Disable autoscaling and specify a fixed scale for a selected axis. + + In updateAxes() the scale engine calculates a scale division from the + specified parameters, that will be assigned to the scale widget. So + updates of the scale widget usually happen delayed with the next replot. + + \param axisId Axis index + \param min Minimum of the scale + \param max Maximum of the scale + \param stepSize Major step size. If step == 0, the step size is + calculated automatically using the maxMajor setting. + + \sa setAxisMaxMajor(), setAxisAutoScale(), axisStepSize(), QwtScaleEngine::divideScale() +*/ +void QwtPlot::setAxisScale( int axisId, double min, double max, double stepSize ) +{ + if ( axisValid( axisId ) ) + { + AxisData &d = *d_axisData[axisId]; + + d.doAutoScale = false; + d.isValid = false; + + d.minValue = min; + d.maxValue = max; + d.stepSize = stepSize; + + autoRefresh(); + } +} + +/*! + \brief Disable autoscaling and specify a fixed scale for a selected axis. + + The scale division will be stored locally only until the next call + of updateAxes(). So updates of the scale widget usually happen delayed with + the next replot. + + \param axisId Axis index + \param scaleDiv Scale division + + \sa setAxisScale(), setAxisAutoScale() +*/ +void QwtPlot::setAxisScaleDiv( int axisId, const QwtScaleDiv &scaleDiv ) +{ + if ( axisValid( axisId ) ) + { + AxisData &d = *d_axisData[axisId]; + + d.doAutoScale = false; + d.scaleDiv = scaleDiv; + d.isValid = true; + + autoRefresh(); + } +} + +/*! + \brief Set a scale draw + + \param axisId Axis index + \param scaleDraw Object responsible for drawing scales. + + By passing scaleDraw it is possible to extend QwtScaleDraw + functionality and let it take place in QwtPlot. Please note + that scaleDraw has to be created with new and will be deleted + by the corresponding QwtScale member ( like a child object ). + + \sa QwtScaleDraw, QwtScaleWidget + \warning The attributes of scaleDraw will be overwritten by those of the + previous QwtScaleDraw. +*/ + +void QwtPlot::setAxisScaleDraw( int axisId, QwtScaleDraw *scaleDraw ) +{ + if ( axisValid( axisId ) ) + { + axisWidget( axisId )->setScaleDraw( scaleDraw ); + autoRefresh(); + } +} + +/*! + Change the alignment of the tick labels + + \param axisId Axis index + \param alignment Or'd Qt::AlignmentFlags see + + \sa QwtScaleDraw::setLabelAlignment() +*/ +void QwtPlot::setAxisLabelAlignment( int axisId, Qt::Alignment alignment ) +{ + if ( axisValid( axisId ) ) + axisWidget( axisId )->setLabelAlignment( alignment ); +} + +/*! + Rotate all tick labels + + \param axisId Axis index + \param rotation Angle in degrees. When changing the label rotation, + the label alignment might be adjusted too. + + \sa QwtScaleDraw::setLabelRotation(), setAxisLabelAlignment() +*/ +void QwtPlot::setAxisLabelRotation( int axisId, double rotation ) +{ + if ( axisValid( axisId ) ) + axisWidget( axisId )->setLabelRotation( rotation ); +} + +/*! + Set the maximum number of minor scale intervals for a specified axis + + \param axisId Axis index + \param maxMinor Maximum number of minor steps + + \sa axisMaxMinor() +*/ +void QwtPlot::setAxisMaxMinor( int axisId, int maxMinor ) +{ + if ( axisValid( axisId ) ) + { + maxMinor = qBound( 0, maxMinor, 100 ); + + AxisData &d = *d_axisData[axisId]; + if ( maxMinor != d.maxMinor ) + { + d.maxMinor = maxMinor; + d.isValid = false; + autoRefresh(); + } + } +} + +/*! + Set the maximum number of major scale intervals for a specified axis + + \param axisId Axis index + \param maxMajor Maximum number of major steps + + \sa axisMaxMajor() +*/ +void QwtPlot::setAxisMaxMajor( int axisId, int maxMajor ) +{ + if ( axisValid( axisId ) ) + { + maxMajor = qBound( 1, maxMajor, 10000 ); + + AxisData &d = *d_axisData[axisId]; + if ( maxMajor != d.maxMajor ) + { + d.maxMajor = maxMajor; + d.isValid = false; + autoRefresh(); + } + } +} + +/*! + \brief Change the title of a specified axis + + \param axisId Axis index + \param title axis title +*/ +void QwtPlot::setAxisTitle( int axisId, const QString &title ) +{ + if ( axisValid( axisId ) ) + axisWidget( axisId )->setTitle( title ); +} + +/*! + \brief Change the title of a specified axis + + \param axisId Axis index + \param title Axis title +*/ +void QwtPlot::setAxisTitle( int axisId, const QwtText &title ) +{ + if ( axisValid( axisId ) ) + axisWidget( axisId )->setTitle( title ); +} + +/*! + \brief Rebuild the axes scales + + In case of autoscaling the boundaries of a scale are calculated + from the bounding rectangles of all plot items, having the + QwtPlotItem::AutoScale flag enabled ( QwtScaleEngine::autoScale() ). + Then a scale division is calculated ( QwtScaleEngine::didvideScale() ) + and assigned to scale widget. + + When the scale boundaries have been assigned with setAxisScale() a + scale division is calculated ( QwtScaleEngine::didvideScale() ) + for this interval and assigned to the scale widget. + + When the scale has been set explicitly by setAxisScaleDiv() the + locally stored scale division gets assigned to the scale widget. + + The scale widget indicates modifications by emitting a + QwtScaleWidget::scaleDivChanged() signal. + + updateAxes() is usually called by replot(). + + \sa setAxisAutoScale(), setAxisScale(), setAxisScaleDiv(), replot() + QwtPlotItem::boundingRect() + */ +void QwtPlot::updateAxes() +{ + // Find bounding interval of the item data + // for all axes, where autoscaling is enabled + + QwtInterval intv[axisCnt]; + + const QwtPlotItemList& itmList = itemList(); + + QwtPlotItemIterator it; + for ( it = itmList.begin(); it != itmList.end(); ++it ) + { + const QwtPlotItem *item = *it; + + if ( !item->testItemAttribute( QwtPlotItem::AutoScale ) ) + continue; + + if ( !item->isVisible() ) + continue; + + if ( axisAutoScale( item->xAxis() ) || axisAutoScale( item->yAxis() ) ) + { + const QRectF rect = item->boundingRect(); + + if ( rect.width() >= 0.0 ) + intv[item->xAxis()] |= QwtInterval( rect.left(), rect.right() ); + + if ( rect.height() >= 0.0 ) + intv[item->yAxis()] |= QwtInterval( rect.top(), rect.bottom() ); + } + } + + // Adjust scales + + for ( int axisId = 0; axisId < axisCnt; axisId++ ) + { + AxisData &d = *d_axisData[axisId]; + + double minValue = d.minValue; + double maxValue = d.maxValue; + double stepSize = d.stepSize; + + if ( d.doAutoScale && intv[axisId].isValid() ) + { + d.isValid = false; + + minValue = intv[axisId].minValue(); + maxValue = intv[axisId].maxValue(); + + d.scaleEngine->autoScale( d.maxMajor, + minValue, maxValue, stepSize ); + } + if ( !d.isValid ) + { + d.scaleDiv = d.scaleEngine->divideScale( + minValue, maxValue, + d.maxMajor, d.maxMinor, stepSize ); + d.isValid = true; + } + + QwtScaleWidget *scaleWidget = axisWidget( axisId ); + scaleWidget->setScaleDiv( d.scaleDiv ); + + int startDist, endDist; + scaleWidget->getBorderDistHint( startDist, endDist ); + scaleWidget->setBorderDist( startDist, endDist ); + } + + for ( it = itmList.begin(); it != itmList.end(); ++it ) + { + QwtPlotItem *item = *it; + if ( item->testItemInterest( QwtPlotItem::ScaleInterest ) ) + { + item->updateScaleDiv( axisScaleDiv( item->xAxis() ), + axisScaleDiv( item->yAxis() ) ); + } + } +} + diff --git a/ThirdParty/Qwt/src/qwt_plot_barchart.cpp b/ThirdParty/Qwt/src/qwt_plot_barchart.cpp new file mode 100644 index 0000000000..b3455af5ec --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_plot_barchart.cpp @@ -0,0 +1,455 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#include "qwt_plot_barchart.h" +#include "qwt_scale_map.h" +#include "qwt_column_symbol.h" +#include "qwt_painter.h" +#include + +class QwtPlotBarChart::PrivateData +{ +public: + PrivateData(): + symbol( NULL ), + legendMode( QwtPlotBarChart::LegendChartTitle ) + { + } + + ~PrivateData() + { + delete symbol; + } + + QwtColumnSymbol *symbol; + QwtPlotBarChart::LegendMode legendMode; +}; + +/*! + Constructor + \param title Title of the curve +*/ +QwtPlotBarChart::QwtPlotBarChart( const QwtText &title ): + QwtPlotAbstractBarChart( title ) +{ + init(); +} + +/*! + Constructor + \param title Title of the curve +*/ +QwtPlotBarChart::QwtPlotBarChart( const QString &title ): + QwtPlotAbstractBarChart( QwtText( title ) ) +{ + init(); +} + +//! Destructor +QwtPlotBarChart::~QwtPlotBarChart() +{ + delete d_data; +} + +void QwtPlotBarChart::init() +{ + d_data = new PrivateData; + setData( new QwtPointSeriesData() ); +} + +//! \return QwtPlotItem::Rtti_PlotBarChart +int QwtPlotBarChart::rtti() const +{ + return QwtPlotItem::Rtti_PlotBarChart; +} + +/*! + Initialize data with an array of points + + \param samples Vector of points + \note QVector is implicitly shared + \note QPolygonF is derived from QVector +*/ +void QwtPlotBarChart::setSamples( + const QVector &samples ) +{ + setData( new QwtPointSeriesData( samples ) ); +} + +/*! + Initialize data with an array of doubles + + The indices in the array are taken as x coordinate, + while the doubles are interpreted as y values. + + \param samples Vector of y coordinates + \note QVector is implicitly shared +*/ +void QwtPlotBarChart::setSamples( + const QVector &samples ) +{ + QVector points; + for ( int i = 0; i < samples.size(); i++ ) + points += QPointF( i, samples[ i ] ); + + setData( new QwtPointSeriesData( points ) ); +} + +/*! + Assign a series of samples + + setSamples() is just a wrapper for setData() without any additional + value - beside that it is easier to find for the developer. + + \param data Data + \warning The item takes ownership of the data object, deleting + it when its not used anymore. +*/ +void QwtPlotBarChart::setSamples( QwtSeriesData *data ) +{ + setData( data ); +} + +/*! + \brief Assign a symbol + + The bar chart will take the ownership of the symbol, hence the previously + set symbol will be delete by setting a new one. If \p symbol is + \c NULL no symbol will be drawn. + + \param symbol Symbol + \sa symbol() +*/ +void QwtPlotBarChart::setSymbol( QwtColumnSymbol *symbol ) +{ + if ( symbol != d_data->symbol ) + { + delete d_data->symbol; + d_data->symbol = symbol; + + legendChanged(); + itemChanged(); + } +} + +/*! + \return Current symbol or NULL, when no symbol has been assigned + \sa setSymbol() +*/ +const QwtColumnSymbol *QwtPlotBarChart::symbol() const +{ + return d_data->symbol; +} + +/*! + Set the mode that decides what to display on the legend + + In case of LegendBarTitles barTitle() needs to be overloaded + to return individual titles for each bar. + + \param mode New mode + \sa legendMode(), legendData(), barTitle(), QwtPlotItem::ItemAttribute + */ +void QwtPlotBarChart::setLegendMode( LegendMode mode ) +{ + if ( mode != d_data->legendMode ) + { + d_data->legendMode = mode; + legendChanged(); + } +} + +/*! + \return Legend mode + \sa setLegendMode() + */ +QwtPlotBarChart::LegendMode QwtPlotBarChart::legendMode() const +{ + return d_data->legendMode; +} + +/*! + \return Bounding rectangle of all samples. + For an empty series the rectangle is invalid. +*/ +QRectF QwtPlotBarChart::boundingRect() const +{ + const size_t numSamples = dataSize(); + if ( numSamples == 0 ) + return QwtPlotSeriesItem::boundingRect(); + + const double baseLine = baseline(); + + QRectF rect = QwtPlotSeriesItem::boundingRect(); + if ( rect.bottom() < baseLine ) + rect.setBottom( baseLine ); + if ( rect.top() > baseLine ) + rect.setTop( baseLine ); + + if ( rect.isValid() && ( orientation() == Qt::Horizontal ) ) + rect.setRect( rect.y(), rect.x(), rect.height(), rect.width() ); + + return rect; +} + +/*! + Draw an interval of the bar chart + + \param painter Painter + \param xMap Maps x-values into pixel coordinates. + \param yMap Maps y-values into pixel coordinates. + \param canvasRect Contents rect of the canvas + \param from Index of the first point to be painted + \param to Index of the last point to be painted. If to < 0 the + curve will be painted to its last point. + + \sa drawSymbols() +*/ +void QwtPlotBarChart::drawSeries( QPainter *painter, + const QwtScaleMap &xMap, const QwtScaleMap &yMap, + const QRectF &canvasRect, int from, int to ) const +{ + if ( to < 0 ) + to = dataSize() - 1; + + if ( from < 0 ) + from = 0; + + if ( from > to ) + return; + + + const QRectF br = data()->boundingRect(); + const QwtInterval interval( br.left(), br.right() ); + + painter->save(); + + for ( int i = from; i <= to; i++ ) + { + drawSample( painter, xMap, yMap, + canvasRect, interval, i, sample( i ) ); + } + + painter->restore(); +} + +/*! + Draw a sample + + \param painter Painter + \param xMap x map + \param yMap y map + \param canvasRect Contents rect of the canvas + \param boundingInterval Bounding interval of sample values + \param index Index of the sample + \param sample Value of the sample + + \sa drawSeries() +*/ +void QwtPlotBarChart::drawSample( QPainter *painter, + const QwtScaleMap &xMap, const QwtScaleMap &yMap, + const QRectF &canvasRect, const QwtInterval &boundingInterval, + int index, const QPointF &sample ) const +{ + QwtColumnRect barRect; + + if ( orientation() == Qt::Horizontal ) + { + const double barHeight = sampleWidth( yMap, canvasRect.height(), + boundingInterval.width(), sample.y() ); + + const double x1 = xMap.transform( baseline() ); + const double x2 = xMap.transform( sample.y() ); + + const double y = yMap.transform( sample.x() ); + const double y1 = y - 0.5 * barHeight; + const double y2 = y + 0.5 * barHeight; + + barRect.direction = ( x1 < x2 ) ? + QwtColumnRect::LeftToRight : QwtColumnRect::RightToLeft; + + barRect.hInterval = QwtInterval( x1, x2 ).normalized(); + barRect.vInterval = QwtInterval( y1, y2 ); + } + else + { + const double barWidth = sampleWidth( xMap, canvasRect.width(), + boundingInterval.width(), sample.y() ); + + const double x = xMap.transform( sample.x() ); + const double x1 = x - 0.5 * barWidth; + const double x2 = x + 0.5 * barWidth; + + const double y1 = yMap.transform( baseline() ); + const double y2 = yMap.transform( sample.y() ); + + barRect.direction = ( y1 < y2 ) ? + QwtColumnRect::TopToBottom : QwtColumnRect::BottomToTop; + + barRect.hInterval = QwtInterval( x1, x2 ); + barRect.vInterval = QwtInterval( y1, y2 ).normalized(); + } + + drawBar( painter, index, sample, barRect ); +} + +/*! + Draw a bar + + \param painter Painter + \param sampleIndex Index of the sample represented by the bar + \param sample Value of the sample + \param rect Bounding rectangle of the bar + */ +void QwtPlotBarChart::drawBar( QPainter *painter, + int sampleIndex, const QPointF &sample, + const QwtColumnRect &rect ) const +{ + const QwtColumnSymbol *specialSym = + specialSymbol( sampleIndex, sample ); + + const QwtColumnSymbol *sym = specialSym; + if ( sym == NULL ) + sym = d_data->symbol; + + if ( sym ) + { + sym->draw( painter, rect ); + } + else + { + // we build a temporary default symbol + QwtColumnSymbol sym( QwtColumnSymbol::Box ); + sym.setLineWidth( 1 ); + sym.setFrameStyle( QwtColumnSymbol::Plain ); + sym.draw( painter, rect ); + } + + delete specialSym; +} + +/*! + Needs to be overloaded to return a + non default symbol for a specific sample + + \param sampleIndex Index of the sample represented by the bar + \param sample Value of the sample + + \return NULL, indicating to use the default symbol + */ +QwtColumnSymbol *QwtPlotBarChart::specialSymbol( + int sampleIndex, const QPointF &sample ) const +{ + Q_UNUSED( sampleIndex ); + Q_UNUSED( sample ); + + return NULL; +} + +/*! + \brief Return the title of a bar + + In LegendBarTitles mode the title is displayed on + the legend entry corresponding to a bar. + + The default implementation is a dummy, that is intended + to be overloaded. + + \param sampleIndex Index of the bar + \return An empty text + \sa LegendBarTitles + */ +QwtText QwtPlotBarChart::barTitle( int sampleIndex ) const +{ + Q_UNUSED( sampleIndex ); + return QwtText(); +} + +/*! + \brief Return all information, that is needed to represent + the item on the legend + + In case of LegendBarTitles an entry for each bar is returned, + otherwise the chart is represented like any other plot item + from its title() and the legendIcon(). + + \return Information, that is needed to represent the item on the legend + \sa title(), setLegendMode(), barTitle(), QwtLegend, QwtPlotLegendItem + */ +QList QwtPlotBarChart::legendData() const +{ + QList list; + + if ( d_data->legendMode == LegendBarTitles ) + { + const size_t numSamples = dataSize(); + for ( size_t i = 0; i < numSamples; i++ ) + { + QwtLegendData data; + + QVariant titleValue; + qVariantSetValue( titleValue, barTitle( i ) ); + data.setValue( QwtLegendData::TitleRole, titleValue ); + + if ( !legendIconSize().isEmpty() ) + { + QVariant iconValue; + qVariantSetValue( iconValue, + legendIcon( i, legendIconSize() ) ); + + data.setValue( QwtLegendData::IconRole, iconValue ); + } + + list += data; + } + } + else + { + return QwtPlotAbstractBarChart::legendData(); + } + + return list; +} + +/*! + \return Icon representing a bar or the chart on the legend + + When the legendMode() is LegendBarTitles the icon shows + the bar corresponding to index - otherwise the bar + displays the default symbol. + + \param index Index of the legend entry + \param size Icon size + + \sa setLegendMode(), drawBar(), + QwtPlotItem::setLegendIconSize(), QwtPlotItem::legendData() + */ +QwtGraphic QwtPlotBarChart::legendIcon( + int index, const QSizeF &size ) const +{ + QwtColumnRect column; + column.hInterval = QwtInterval( 0.0, size.width() - 1.0 ); + column.vInterval = QwtInterval( 0.0, size.height() - 1.0 ); + + QwtGraphic icon; + icon.setDefaultSize( size ); + icon.setRenderHint( QwtGraphic::RenderPensUnscaled, true ); + + QPainter painter( &icon ); + painter.setRenderHint( QPainter::Antialiasing, + testRenderHint( QwtPlotItem::RenderAntialiased ) ); + + int barIndex = -1; + if ( d_data->legendMode == QwtPlotBarChart::LegendBarTitles ) + barIndex = index; + + drawBar( &painter, barIndex, QPointF(), column ); + + return icon; +} diff --git a/ThirdParty/Qwt/src/qwt_plot_barchart.h b/ThirdParty/Qwt/src/qwt_plot_barchart.h new file mode 100644 index 0000000000..d47bfb9725 --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_plot_barchart.h @@ -0,0 +1,118 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#ifndef QWT_PLOT_BAR_CHART_H +#define QWT_PLOT_BAR_CHART_H + +#include "qwt_global.h" +#include "qwt_plot_abstract_barchart.h" +#include "qwt_series_data.h" + +class QwtColumnRect; +class QwtColumnSymbol; + +/*! + \brief QwtPlotBarChart displays a series of a values as bars. + + Each bar might be customized individually by implementing + a specialSymbol(). Otherwise it is rendered using a default symbol. + + Depending on its orientation() the bars are displayed horizontally + or vertically. The bars cover the interval between the baseline() + and the value. + + By activating the LegendBarTitles mode each sample will have + its own entry on the legend. + + The most common use case of a bar chart is to display a + list of y coordinates, where the x coordinate is simply the index + in the list. But for other situations ( f.e. when values are related + to dates ) it is also possible to set x coordinates explicitly. + + \sa QwtPlotMultiBarChart, QwtPlotHistogram, QwtPlotCurve::Sticks, + QwtPlotSeriesItem::orientation(), QwtPlotAbstractBarChart::baseline() + */ +class QWT_EXPORT QwtPlotBarChart: + public QwtPlotAbstractBarChart, public QwtSeriesStore +{ +public: + /*! + \brief Legend modes. + + The default setting is QwtPlotBarChart::LegendChartTitle. + \sa setLegendMode(), legendMode() + */ + enum LegendMode + { + /*! + One entry on the legend showing the default symbol + and the title() of the chart + + \sa QwtPlotItem::title() + */ + LegendChartTitle, + + /*! + One entry for each value showing the individual symbol + of the corresponding bar and the bar title. + + \sa specialSymbol(), barTitle() + */ + LegendBarTitles + }; + + explicit QwtPlotBarChart( const QString &title = QString::null ); + explicit QwtPlotBarChart( const QwtText &title ); + + virtual ~QwtPlotBarChart(); + + virtual int rtti() const; + + void setSamples( const QVector & ); + void setSamples( const QVector & ); + void setSamples( QwtSeriesData *series ); + + void setSymbol( QwtColumnSymbol * ); + const QwtColumnSymbol *symbol() const; + + void setLegendMode( LegendMode ); + LegendMode legendMode() const; + + virtual void drawSeries( QPainter *painter, + const QwtScaleMap &xMap, const QwtScaleMap &yMap, + const QRectF &canvasRect, int from, int to ) const; + + virtual QRectF boundingRect() const; + + virtual QwtColumnSymbol *specialSymbol( + int sampleIndex, const QPointF& ) const; + + virtual QwtText barTitle( int sampleIndex ) const; + +protected: + virtual void drawSample( QPainter *painter, + const QwtScaleMap &xMap, const QwtScaleMap &yMap, + const QRectF &canvasRect, const QwtInterval &boundingInterval, + int index, const QPointF& sample ) const; + + virtual void drawBar( QPainter *, + int sampleIndex, const QPointF& point, + const QwtColumnRect & ) const; + + QList legendData() const; + QwtGraphic legendIcon( int index, const QSizeF & ) const; + +private: + void init(); + + class PrivateData; + PrivateData *d_data; +}; + +#endif diff --git a/ThirdParty/Qwt/src/qwt_plot_canvas.cpp b/ThirdParty/Qwt/src/qwt_plot_canvas.cpp new file mode 100644 index 0000000000..0271713a8b --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_plot_canvas.cpp @@ -0,0 +1,1097 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#include "qwt_plot_canvas.h" +#include "qwt_painter.h" +#include "qwt_null_paintdevice.h" +#include "qwt_math.h" +#include "qwt_plot.h" +#include +#include +#include +#include +#include + +class QwtStyleSheetRecorder: public QwtNullPaintDevice +{ +public: + QwtStyleSheetRecorder( const QSize &size ): + d_size( size ) + { + } + + virtual void updateState( const QPaintEngineState &state ) + { + if ( state.state() & QPaintEngine::DirtyPen ) + { + d_pen = state.pen(); + } + if ( state.state() & QPaintEngine::DirtyBrush ) + { + d_brush = state.brush(); + } + if ( state.state() & QPaintEngine::DirtyBrushOrigin ) + { + d_origin = state.brushOrigin(); + } + } + + virtual void drawRects(const QRectF *rects, int count ) + { + for ( int i = 0; i < count; i++ ) + border.rectList += rects[i]; + } + + virtual void drawPath( const QPainterPath &path ) + { + const QRectF rect( QPointF( 0.0, 0.0 ), d_size ); + if ( path.controlPointRect().contains( rect.center() ) ) + { + setCornerRects( path ); + alignCornerRects( rect ); + + background.path = path; + background.brush = d_brush; + background.origin = d_origin; + } + else + { + border.pathList += path; + } + } + + void setCornerRects( const QPainterPath &path ) + { + QPointF pos( 0.0, 0.0 ); + + for ( int i = 0; i < path.elementCount(); i++ ) + { + QPainterPath::Element el = path.elementAt(i); + switch( el.type ) + { + case QPainterPath::MoveToElement: + case QPainterPath::LineToElement: + { + pos.setX( el.x ); + pos.setY( el.y ); + break; + } + case QPainterPath::CurveToElement: + { + QRectF r( pos, QPointF( el.x, el.y ) ); + clipRects += r.normalized(); + + pos.setX( el.x ); + pos.setY( el.y ); + + break; + } + case QPainterPath::CurveToDataElement: + { + if ( clipRects.size() > 0 ) + { + QRectF r = clipRects.last(); + r.setCoords( + qMin( r.left(), el.x ), + qMin( r.top(), el.y ), + qMax( r.right(), el.x ), + qMax( r.bottom(), el.y ) + ); + clipRects.last() = r.normalized(); + } + break; + } + } + } + } + +protected: + virtual QSize sizeMetrics() const + { + return d_size; + } + +private: + void alignCornerRects( const QRectF &rect ) + { + for ( int i = 0; i < clipRects.size(); i++ ) + { + QRectF &r = clipRects[i]; + if ( r.center().x() < rect.center().x() ) + r.setLeft( rect.left() ); + else + r.setRight( rect.right() ); + + if ( r.center().y() < rect.center().y() ) + r.setTop( rect.top() ); + else + r.setBottom( rect.bottom() ); + } + } + + +public: + QVector clipRects; + + struct Border + { + QList pathList; + QList rectList; + QRegion clipRegion; + } border; + + struct Background + { + QPainterPath path; + QBrush brush; + QPointF origin; + } background; + +private: + const QSize d_size; + + QPen d_pen; + QBrush d_brush; + QPointF d_origin; +}; + +static void qwtDrawBackground( QPainter *painter, QwtPlotCanvas *canvas ) +{ + painter->save(); + + const QPainterPath borderClip = canvas->borderPath( canvas->rect() ); + if ( !borderClip.isEmpty() ) + painter->setClipPath( borderClip, Qt::IntersectClip ); + + const QBrush &brush = + canvas->palette().brush( canvas->backgroundRole() ); + + if ( brush.style() == Qt::TexturePattern ) + { + QPixmap pm( canvas->size() ); + QwtPainter::fillPixmap( canvas, pm ); + painter->drawPixmap( 0, 0, pm ); + } + else if ( brush.gradient() ) + { + QVector rects; + + if ( brush.gradient()->coordinateMode() == QGradient::ObjectBoundingMode ) + { + rects += canvas->rect(); + } + else + { + rects = painter->clipRegion().rects(); + } + +#if 1 + bool useRaster = false; + + if ( painter->paintEngine()->type() == QPaintEngine::X11 ) + { + // Qt 4.7.1: gradients on X11 are broken ( subrects + + // QGradient::StretchToDeviceMode ) and horrible slow. + // As workaround we have to use the raster paintengine. + // Even if the QImage -> QPixmap translation is slow + // it is three times faster, than using X11 directly + + useRaster = true; + } +#endif + if ( useRaster ) + { + QImage::Format format = QImage::Format_RGB32; + + const QGradientStops stops = brush.gradient()->stops(); + for ( int i = 0; i < stops.size(); i++ ) + { + if ( stops[i].second.alpha() != 255 ) + { + // don't use Format_ARGB32_Premultiplied. It's + // recommended by the Qt docs, but QPainter::drawImage() + // is horrible slow on X11. + + format = QImage::Format_ARGB32; + break; + } + } + + QImage image( canvas->size(), format ); + + QPainter p( &image ); + p.setPen( Qt::NoPen ); + p.setBrush( brush ); + + p.drawRects( rects ); + + p.end(); + + painter->drawImage( 0, 0, image ); + } + else + { + painter->setPen( Qt::NoPen ); + painter->setBrush( brush ); + + painter->drawRects( rects ); + } + } + else + { + painter->setPen( Qt::NoPen ); + painter->setBrush( brush ); + + painter->drawRects( painter->clipRegion().rects() ); + + } + + painter->restore(); +} + +static inline void qwtRevertPath( QPainterPath &path ) +{ + if ( path.elementCount() == 4 ) + { + QPainterPath::Element el0 = path.elementAt(0); + QPainterPath::Element el3 = path.elementAt(3); + + path.setElementPositionAt( 0, el3.x, el3.y ); + path.setElementPositionAt( 3, el0.x, el0.y ); + } +} + +static QPainterPath qwtCombinePathList( const QRectF &rect, + const QList &pathList ) +{ + if ( pathList.isEmpty() ) + return QPainterPath(); + + QPainterPath ordered[8]; // starting top left + + for ( int i = 0; i < pathList.size(); i++ ) + { + int index = -1; + QPainterPath subPath = pathList[i]; + + const QRectF br = pathList[i].controlPointRect(); + if ( br.center().x() < rect.center().x() ) + { + if ( br.center().y() < rect.center().y() ) + { + if ( qAbs( br.top() - rect.top() ) < + qAbs( br.left() - rect.left() ) ) + { + index = 1; + } + else + { + index = 0; + } + } + else + { + if ( qAbs( br.bottom() - rect.bottom() ) < + qAbs( br.left() - rect.left() ) ) + { + index = 6; + } + else + { + index = 7; + } + } + + if ( subPath.currentPosition().y() > br.center().y() ) + qwtRevertPath( subPath ); + } + else + { + if ( br.center().y() < rect.center().y() ) + { + if ( qAbs( br.top() - rect.top() ) < + qAbs( br.right() - rect.right() ) ) + { + index = 2; + } + else + { + index = 3; + } + } + else + { + if ( qAbs( br.bottom() - rect.bottom() ) < + qAbs( br.right() - rect.right() ) ) + { + index = 5; + } + else + { + index = 4; + } + } + if ( subPath.currentPosition().y() < br.center().y() ) + qwtRevertPath( subPath ); + } + ordered[index] = subPath; + } + + for ( int i = 0; i < 4; i++ ) + { + if ( ordered[ 2 * i].isEmpty() != ordered[2 * i + 1].isEmpty() ) + { + // we don't accept incomplete rounded borders + return QPainterPath(); + } + } + + + const QPolygonF corners( rect ); + + QPainterPath path; + //path.moveTo( rect.topLeft() ); + + for ( int i = 0; i < 4; i++ ) + { + if ( ordered[2 * i].isEmpty() ) + { + path.lineTo( corners[i] ); + } + else + { + path.connectPath( ordered[2 * i] ); + path.connectPath( ordered[2 * i + 1] ); + } + } + + path.closeSubpath(); + +#if 0 + return path.simplified(); +#else + return path; +#endif +} + +static inline void qwtDrawStyledBackground( + QWidget *w, QPainter *painter ) +{ + QStyleOption opt; + opt.initFrom(w); + w->style()->drawPrimitive( QStyle::PE_Widget, &opt, painter, w); +} + +static QWidget *qwtBackgroundWidget( QWidget *w ) +{ + if ( w->parentWidget() == NULL ) + return w; + + if ( w->autoFillBackground() ) + { + const QBrush brush = w->palette().brush( w->backgroundRole() ); + if ( brush.color().alpha() > 0 ) + return w; + } + + if ( w->testAttribute( Qt::WA_StyledBackground ) ) + { + QImage image( 1, 1, QImage::Format_ARGB32 ); + image.fill( Qt::transparent ); + + QPainter painter( &image ); + painter.translate( -w->rect().center() ); + qwtDrawStyledBackground( w, &painter ); + painter.end(); + + if ( qAlpha( image.pixel( 0, 0 ) ) != 0 ) + return w; + } + + return qwtBackgroundWidget( w->parentWidget() ); +} + +static void qwtFillBackground( QPainter *painter, + QWidget *widget, const QVector &fillRects ) +{ + if ( fillRects.isEmpty() ) + return; + + QRegion clipRegion; + if ( painter->hasClipping() ) + clipRegion = painter->transform().map( painter->clipRegion() ); + else + clipRegion = widget->contentsRect(); + + // Try to find out which widget fills + // the unfilled areas of the styled background + + QWidget *bgWidget = qwtBackgroundWidget( widget->parentWidget() ); + + for ( int i = 0; i < fillRects.size(); i++ ) + { + const QRect rect = fillRects[i].toAlignedRect(); + if ( clipRegion.intersects( rect ) ) + { + QPixmap pm( rect.size() ); + QwtPainter::fillPixmap( bgWidget, pm, widget->mapTo( bgWidget, rect.topLeft() ) ); + painter->drawPixmap( rect, pm ); + } + } +} + +static void qwtFillBackground( QPainter *painter, QwtPlotCanvas *canvas ) +{ + QVector rects; + + if ( canvas->testAttribute( Qt::WA_StyledBackground ) ) + { + QwtStyleSheetRecorder recorder( canvas->size() ); + + QPainter p( &recorder ); + qwtDrawStyledBackground( canvas, &p ); + p.end(); + + if ( recorder.background.brush.isOpaque() ) + rects = recorder.clipRects; + else + rects += canvas->rect(); + } + else + { + const QRectF r = canvas->rect(); + const double radius = canvas->borderRadius(); + if ( radius > 0.0 ) + { + QSizeF sz( radius, radius ); + + rects += QRectF( r.topLeft(), sz ); + rects += QRectF( r.topRight() - QPointF( radius, 0 ), sz ); + rects += QRectF( r.bottomRight() - QPointF( radius, radius ), sz ); + rects += QRectF( r.bottomLeft() - QPointF( 0, radius ), sz ); + } + } + + qwtFillBackground( painter, canvas, rects); +} + + +class QwtPlotCanvas::PrivateData +{ +public: + PrivateData(): + focusIndicator( NoFocusIndicator ), + borderRadius( 0 ), + paintAttributes( 0 ), + backingStore( NULL ) + { + styleSheet.hasBorder = false; + } + + ~PrivateData() + { + delete backingStore; + } + + FocusIndicator focusIndicator; + double borderRadius; + QwtPlotCanvas::PaintAttributes paintAttributes; + QPixmap *backingStore; + + struct StyleSheet + { + bool hasBorder; + QPainterPath borderPath; + QVector cornerRects; + + struct StyleSheetBackground + { + QBrush brush; + QPointF origin; + } background; + + } styleSheet; + +}; + +/*! + \brief Constructor + + \param plot Parent plot widget + \sa QwtPlot::setCanvas() +*/ +QwtPlotCanvas::QwtPlotCanvas( QwtPlot *plot ): + QFrame( plot ) +{ + setFrameStyle( QFrame::Panel | QFrame::Sunken ); + setLineWidth( 2 ); + + d_data = new PrivateData; + +#ifndef QT_NO_CURSOR + setCursor( Qt::CrossCursor ); +#endif + + setAutoFillBackground( true ); + setPaintAttribute( QwtPlotCanvas::BackingStore, true ); + setPaintAttribute( QwtPlotCanvas::Opaque, true ); + setPaintAttribute( QwtPlotCanvas::HackStyledBackground, true ); +} + +//! Destructor +QwtPlotCanvas::~QwtPlotCanvas() +{ + delete d_data; +} + +//! Return parent plot widget +QwtPlot *QwtPlotCanvas::plot() +{ + return qobject_cast( parent() ); +} + +//! Return parent plot widget +const QwtPlot *QwtPlotCanvas::plot() const +{ + return qobject_cast( parent() ); +} + +/*! + \brief Changing the paint attributes + + \param attribute Paint attribute + \param on On/Off + + \sa testPaintAttribute(), backingStore() +*/ +void QwtPlotCanvas::setPaintAttribute( PaintAttribute attribute, bool on ) +{ + if ( bool( d_data->paintAttributes & attribute ) == on ) + return; + + if ( on ) + d_data->paintAttributes |= attribute; + else + d_data->paintAttributes &= ~attribute; + + switch ( attribute ) + { + case BackingStore: + { + if ( on ) + { + if ( d_data->backingStore == NULL ) + d_data->backingStore = new QPixmap(); + + if ( isVisible() ) + { +#if QT_VERSION >= 0x050000 + *d_data->backingStore = grab( rect() ); +#else + *d_data->backingStore = + QPixmap::grabWidget( this, rect() ); +#endif + } + } + else + { + delete d_data->backingStore; + d_data->backingStore = NULL; + } + break; + } + case Opaque: + { + if ( on ) + setAttribute( Qt::WA_OpaquePaintEvent, true ); + + break; + } + case HackStyledBackground: + case ImmediatePaint: + { + break; + } + } +} + +/*! + Test whether a paint attribute is enabled + + \param attribute Paint attribute + \return true, when attribute is enabled + \sa setPaintAttribute() +*/ +bool QwtPlotCanvas::testPaintAttribute( PaintAttribute attribute ) const +{ + return d_data->paintAttributes & attribute; +} + +//! \return Backing store, might be null +const QPixmap *QwtPlotCanvas::backingStore() const +{ + return d_data->backingStore; +} + +//! Invalidate the internal backing store +void QwtPlotCanvas::invalidateBackingStore() +{ + if ( d_data->backingStore ) + *d_data->backingStore = QPixmap(); +} + +/*! + Set the focus indicator + + \sa FocusIndicator, focusIndicator() +*/ +void QwtPlotCanvas::setFocusIndicator( FocusIndicator focusIndicator ) +{ + d_data->focusIndicator = focusIndicator; +} + +/*! + \return Focus indicator + + \sa FocusIndicator, setFocusIndicator() +*/ +QwtPlotCanvas::FocusIndicator QwtPlotCanvas::focusIndicator() const +{ + return d_data->focusIndicator; +} + +/*! + Set the radius for the corners of the border frame + + \param radius Radius of a rounded corner + \sa borderRadius() +*/ +void QwtPlotCanvas::setBorderRadius( double radius ) +{ + d_data->borderRadius = qMax( 0.0, radius ); +} + +/*! + \return Radius for the corners of the border frame + \sa setBorderRadius() +*/ +double QwtPlotCanvas::borderRadius() const +{ + return d_data->borderRadius; +} + +/*! + Qt event handler for QEvent::PolishRequest and QEvent::StyleChange + + \param event Qt Event + \return See QFrame::event() +*/ +bool QwtPlotCanvas::event( QEvent *event ) +{ + if ( event->type() == QEvent::PolishRequest ) + { + if ( testPaintAttribute( QwtPlotCanvas::Opaque ) ) + { + // Setting a style sheet changes the + // Qt::WA_OpaquePaintEvent attribute, but we insist + // on painting the background. + + setAttribute( Qt::WA_OpaquePaintEvent, true ); + } + } + + if ( event->type() == QEvent::PolishRequest || + event->type() == QEvent::StyleChange ) + { + updateStyleSheetInfo(); + } + + return QFrame::event( event ); +} + +/*! + Paint event + \param event Paint event +*/ +void QwtPlotCanvas::paintEvent( QPaintEvent *event ) +{ + QPainter painter( this ); + painter.setClipRegion( event->region() ); + + if ( testPaintAttribute( QwtPlotCanvas::BackingStore ) && + d_data->backingStore != NULL ) + { + QPixmap &bs = *d_data->backingStore; + if ( bs.size() != size() ) + { + bs = QwtPainter::backingStore( this, size() ); + + if ( testAttribute(Qt::WA_StyledBackground) ) + { + QPainter p( &bs ); + qwtFillBackground( &p, this ); + drawCanvas( &p, true ); + } + else + { + QPainter p; + if ( d_data->borderRadius <= 0.0 ) + { + QwtPainter::fillPixmap( this, bs ); + p.begin( &bs ); + drawCanvas( &p, false ); + } + else + { + p.begin( &bs ); + qwtFillBackground( &p, this ); + drawCanvas( &p, true ); + } + + if ( frameWidth() > 0 ) + drawBorder( &p ); + } + } + + painter.drawPixmap( 0, 0, *d_data->backingStore ); + } + else + { + if ( testAttribute(Qt::WA_StyledBackground ) ) + { + if ( testAttribute( Qt::WA_OpaquePaintEvent ) ) + { + qwtFillBackground( &painter, this ); + drawCanvas( &painter, true ); + } + else + { + drawCanvas( &painter, false ); + } + } + else + { + if ( testAttribute( Qt::WA_OpaquePaintEvent ) ) + { + if ( autoFillBackground() ) + { + qwtFillBackground( &painter, this ); + qwtDrawBackground( &painter, this ); + } + } + else + { + if ( borderRadius() > 0.0 ) + { + QPainterPath clipPath; + clipPath.addRect( rect() ); + clipPath = clipPath.subtracted( borderPath( rect() ) ); + + painter.save(); + + painter.setClipPath( clipPath, Qt::IntersectClip ); + qwtFillBackground( &painter, this ); + qwtDrawBackground( &painter, this ); + + painter.restore(); + } + } + + drawCanvas( &painter, false ); + + if ( frameWidth() > 0 ) + drawBorder( &painter ); + } + } + + if ( hasFocus() && focusIndicator() == CanvasFocusIndicator ) + drawFocusIndicator( &painter ); +} + +void QwtPlotCanvas::drawCanvas( QPainter *painter, bool withBackground ) +{ + bool hackStyledBackground = false; + + if ( withBackground && testAttribute( Qt::WA_StyledBackground ) + && testPaintAttribute( HackStyledBackground ) ) + { + // Antialiasing rounded borders is done by + // inserting pixels with colors between the + // border color and the color on the canvas, + // When the border is painted before the plot items + // these colors are interpolated for the canvas + // and the plot items need to be clipped excluding + // the anialiased pixels. In situations, where + // the plot items fill the area at the rounded + // borders this is noticeable. + // The only way to avoid these annoying "artefacts" + // is to paint the border on top of the plot items. + + if ( d_data->styleSheet.hasBorder && + !d_data->styleSheet.borderPath.isEmpty() ) + { + // We have a border with at least one rounded corner + hackStyledBackground = true; + } + } + + if ( withBackground ) + { + painter->save(); + + if ( testAttribute( Qt::WA_StyledBackground ) ) + { + if ( hackStyledBackground ) + { + // paint background without border + + painter->setPen( Qt::NoPen ); + painter->setBrush( d_data->styleSheet.background.brush ); + painter->setBrushOrigin( d_data->styleSheet.background.origin ); + painter->setClipPath( d_data->styleSheet.borderPath ); + painter->drawRect( contentsRect() ); + } + else + { + qwtDrawStyledBackground( this, painter ); + } + } + else if ( autoFillBackground() ) + { + painter->setPen( Qt::NoPen ); + painter->setBrush( palette().brush( backgroundRole() ) ); + + if ( d_data->borderRadius > 0.0 && ( rect() == frameRect() ) ) + { + if ( frameWidth() > 0 ) + { + painter->setClipPath( borderPath( rect() ) ); + painter->drawRect( rect() ); + } + else + { + painter->setRenderHint( QPainter::Antialiasing, true ); + painter->drawPath( borderPath( rect() ) ); + } + } + else + { + painter->drawRect( rect() ); + } + } + + painter->restore(); + } + + painter->save(); + + if ( !d_data->styleSheet.borderPath.isEmpty() ) + { + painter->setClipPath( + d_data->styleSheet.borderPath, Qt::IntersectClip ); + } + else + { + if ( d_data->borderRadius > 0.0 ) + painter->setClipPath( borderPath( frameRect() ), Qt::IntersectClip ); + else + painter->setClipRect( contentsRect(), Qt::IntersectClip ); + } + + plot()->drawCanvas( painter ); + + painter->restore(); + + if ( withBackground && hackStyledBackground ) + { + // Now paint the border on top + QStyleOptionFrame opt; + opt.initFrom(this); + style()->drawPrimitive( QStyle::PE_Frame, &opt, painter, this); + } +} + +/*! + Draw the border of the plot canvas + + \param painter Painter + \sa setBorderRadius() +*/ +void QwtPlotCanvas::drawBorder( QPainter *painter ) +{ + if ( d_data->borderRadius > 0 ) + { + if ( frameWidth() > 0 ) + { + QwtPainter::drawRoundedFrame( painter, QRectF( frameRect() ), + d_data->borderRadius, d_data->borderRadius, + palette(), frameWidth(), frameStyle() ); + } + } + else + { +#if QT_VERSION >= 0x040500 + QStyleOptionFrameV3 opt; + opt.init(this); + + int frameShape = frameStyle() & QFrame::Shape_Mask; + int frameShadow = frameStyle() & QFrame::Shadow_Mask; + + opt.frameShape = QFrame::Shape( int( opt.frameShape ) | frameShape ); +#if 0 + opt.rect = frameRect(); +#endif + + switch (frameShape) + { + case QFrame::Box: + case QFrame::HLine: + case QFrame::VLine: + case QFrame::StyledPanel: + case QFrame::Panel: + { + opt.lineWidth = lineWidth(); + opt.midLineWidth = midLineWidth(); + break; + } + default: + { + opt.lineWidth = frameWidth(); + break; + } + } + + if ( frameShadow == Sunken ) + opt.state |= QStyle::State_Sunken; + else if ( frameShadow == Raised ) + opt.state |= QStyle::State_Raised; + + style()->drawControl(QStyle::CE_ShapedFrame, &opt, painter, this); +#else + drawFrame( painter ); +#endif + } +} + +/*! + Resize event + \param event Resize event +*/ +void QwtPlotCanvas::resizeEvent( QResizeEvent *event ) +{ + QFrame::resizeEvent( event ); + updateStyleSheetInfo(); +} + +/*! + Draw the focus indication + \param painter Painter +*/ +void QwtPlotCanvas::drawFocusIndicator( QPainter *painter ) +{ + const int margin = 1; + + QRect focusRect = contentsRect(); + focusRect.setRect( focusRect.x() + margin, focusRect.y() + margin, + focusRect.width() - 2 * margin, focusRect.height() - 2 * margin ); + + QwtPainter::drawFocusRect( painter, this, focusRect ); +} + +/*! + Invalidate the paint cache and repaint the canvas + \sa invalidatePaintCache() +*/ +void QwtPlotCanvas::replot() +{ + invalidateBackingStore(); + + if ( testPaintAttribute( QwtPlotCanvas::ImmediatePaint ) ) + repaint( contentsRect() ); + else + update( contentsRect() ); +} + +//! Update the cached information about the current style sheet +void QwtPlotCanvas::updateStyleSheetInfo() +{ + if ( !testAttribute(Qt::WA_StyledBackground ) ) + return; + + QwtStyleSheetRecorder recorder( size() ); + + QPainter painter( &recorder ); + + QStyleOption opt; + opt.initFrom(this); + style()->drawPrimitive( QStyle::PE_Widget, &opt, &painter, this); + + painter.end(); + + d_data->styleSheet.hasBorder = !recorder.border.rectList.isEmpty(); + d_data->styleSheet.cornerRects = recorder.clipRects; + + if ( recorder.background.path.isEmpty() ) + { + if ( !recorder.border.rectList.isEmpty() ) + { + d_data->styleSheet.borderPath = + qwtCombinePathList( rect(), recorder.border.pathList ); + } + } + else + { + d_data->styleSheet.borderPath = recorder.background.path; + d_data->styleSheet.background.brush = recorder.background.brush; + d_data->styleSheet.background.origin = recorder.background.origin; + } +} + +/*! + Calculate the painter path for a styled or rounded border + + When the canvas has no styled background or rounded borders + the painter path is empty. + + \param rect Bounding rectangle of the canvas + \return Painter path, that can be used for clipping +*/ +QPainterPath QwtPlotCanvas::borderPath( const QRect &rect ) const +{ + if ( testAttribute(Qt::WA_StyledBackground ) ) + { + QwtStyleSheetRecorder recorder( rect.size() ); + + QPainter painter( &recorder ); + + QStyleOption opt; + opt.initFrom(this); + opt.rect = rect; + style()->drawPrimitive( QStyle::PE_Widget, &opt, &painter, this); + + painter.end(); + + if ( !recorder.background.path.isEmpty() ) + return recorder.background.path; + + if ( !recorder.border.rectList.isEmpty() ) + return qwtCombinePathList( rect, recorder.border.pathList ); + } + else if ( d_data->borderRadius > 0.0 ) + { + double fw2 = frameWidth() * 0.5; + QRectF r = QRectF(rect).adjusted( fw2, fw2, -fw2, -fw2 ); + + QPainterPath path; + path.addRoundedRect( r, d_data->borderRadius, d_data->borderRadius ); + return path; + } + + return QPainterPath(); +} diff --git a/ThirdParty/Qwt/src/qwt_plot_canvas.h b/ThirdParty/Qwt/src/qwt_plot_canvas.h new file mode 100644 index 0000000000..daea8a086f --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_plot_canvas.h @@ -0,0 +1,171 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#ifndef QWT_PLOT_CANVAS_H +#define QWT_PLOT_CANVAS_H + +#include "qwt_global.h" +#include +#include + +class QwtPlot; +class QPixmap; + +/*! + \brief Canvas of a QwtPlot. + + Canvas is the widget where all plot items are displayed + + \sa QwtPlot::setCanvas(), QwtPlotGLCanvas +*/ +class QWT_EXPORT QwtPlotCanvas : public QFrame +{ + Q_OBJECT + + Q_PROPERTY( double borderRadius READ borderRadius WRITE setBorderRadius ) + +public: + + /*! + \brief Paint attributes + + The default setting enables BackingStore and Opaque. + + \sa setPaintAttribute(), testPaintAttribute() + */ + enum PaintAttribute + { + /*! + \brief Paint double buffered reusing the content + of the pixmap buffer when possible. + + Using a backing store might improve the performance + significantly, when working with widget overlays ( like rubber bands ). + Disabling the cache might improve the performance for + incremental paints (using QwtPlotDirectPainter ). + + \sa backingStore(), invalidateBackingStore() + */ + BackingStore = 1, + + /*! + \brief Try to fill the complete contents rectangle + of the plot canvas + + When using styled backgrounds Qt assumes, that the + canvas doesn't fill its area completely + ( f.e because of rounded borders ) and fills the area + below the canvas. When this is done with gradients it might + result in a serious performance bottleneck - depending on the size. + + When the Opaque attribute is enabled the canvas tries to + identify the gaps with some heuristics and to fill those only. + + \warning Will not work for semitransparent backgrounds + */ + Opaque = 2, + + /*! + \brief Try to improve painting of styled backgrounds + + QwtPlotCanvas supports the box model attributes for + customizing the layout with style sheets. Unfortunately + the design of Qt style sheets has no concept how to + handle backgrounds with rounded corners - beside of padding. + + When HackStyledBackground is enabled the plot canvas tries + to separate the background from the background border + by reverse engineering to paint the background before and + the border after the plot items. In this order the border + gets perfectly antialiased and you can avoid some pixel + artifacts in the corners. + */ + HackStyledBackground = 4, + + /*! + When ImmediatePaint is set replot() calls repaint() + instead of update(). + + \sa replot(), QWidget::repaint(), QWidget::update() + */ + ImmediatePaint = 8 + }; + + //! Paint attributes + typedef QFlags PaintAttributes; + + /*! + \brief Focus indicator + The default setting is NoFocusIndicator + \sa setFocusIndicator(), focusIndicator(), paintFocus() + */ + + enum FocusIndicator + { + //! Don't paint a focus indicator + NoFocusIndicator, + + /*! + The focus is related to the complete canvas. + Paint the focus indicator using paintFocus() + */ + CanvasFocusIndicator, + + /*! + The focus is related to an item (curve, point, ...) on + the canvas. It is up to the application to display a + focus indication using f.e. highlighting. + */ + ItemFocusIndicator + }; + + explicit QwtPlotCanvas( QwtPlot * = NULL ); + virtual ~QwtPlotCanvas(); + + QwtPlot *plot(); + const QwtPlot *plot() const; + + void setFocusIndicator( FocusIndicator ); + FocusIndicator focusIndicator() const; + + void setBorderRadius( double ); + double borderRadius() const; + + void setPaintAttribute( PaintAttribute, bool on = true ); + bool testPaintAttribute( PaintAttribute ) const; + + const QPixmap *backingStore() const; + void invalidateBackingStore(); + + virtual bool event( QEvent * ); + + Q_INVOKABLE QPainterPath borderPath( const QRect & ) const; + +public Q_SLOTS: + void replot(); + +protected: + virtual void paintEvent( QPaintEvent * ); + virtual void resizeEvent( QResizeEvent * ); + + virtual void drawFocusIndicator( QPainter * ); + virtual void drawBorder( QPainter * ); + + void updateStyleSheetInfo(); + +private: + void drawCanvas( QPainter *, bool withBackground ); + + class PrivateData; + PrivateData *d_data; +}; + +Q_DECLARE_OPERATORS_FOR_FLAGS( QwtPlotCanvas::PaintAttributes ) + +#endif diff --git a/ThirdParty/Qwt/src/qwt_plot_curve.cpp b/ThirdParty/Qwt/src/qwt_plot_curve.cpp new file mode 100644 index 0000000000..140cc5996a --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_plot_curve.cpp @@ -0,0 +1,1191 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#include "qwt_plot_curve.h" +#include "qwt_point_data.h" +#include "qwt_math.h" +#include "qwt_clipper.h" +#include "qwt_painter.h" +#include "qwt_scale_map.h" +#include "qwt_plot.h" +#include "qwt_curve_fitter.h" +#include "qwt_symbol.h" +#include "qwt_point_mapper.h" +#include +#include +#include +#include + +static void qwtUpdateLegendIconSize( QwtPlotCurve *curve ) +{ + if ( curve->symbol() && + curve->testLegendAttribute( QwtPlotCurve::LegendShowSymbol ) ) + { + QSize sz = curve->symbol()->boundingRect().size(); + sz += QSize( 2, 2 ); // margin + + if ( curve->testLegendAttribute( QwtPlotCurve::LegendShowLine ) ) + { + // Avoid, that the line is completely covered by the symbol + + int w = qCeil( 1.5 * sz.width() ); + if ( w % 2 ) + w++; + + sz.setWidth( qMax( 8, w ) ); + } + + curve->setLegendIconSize( sz ); + } +} + +static int qwtVerifyRange( int size, int &i1, int &i2 ) +{ + if ( size < 1 ) + return 0; + + i1 = qBound( 0, i1, size - 1 ); + i2 = qBound( 0, i2, size - 1 ); + + if ( i1 > i2 ) + qSwap( i1, i2 ); + + return ( i2 - i1 + 1 ); +} + +class QwtPlotCurve::PrivateData +{ +public: + PrivateData(): + style( QwtPlotCurve::Lines ), + baseline( 0.0 ), + symbol( NULL ), + attributes( 0 ), + paintAttributes( + QwtPlotCurve::ClipPolygons | QwtPlotCurve::FilterPoints ), + legendAttributes( 0 ) + { + pen = QPen( Qt::black ); + curveFitter = new QwtSplineCurveFitter; + } + + ~PrivateData() + { + delete symbol; + delete curveFitter; + } + + QwtPlotCurve::CurveStyle style; + double baseline; + + const QwtSymbol *symbol; + QwtCurveFitter *curveFitter; + + QPen pen; + QBrush brush; + + QwtPlotCurve::CurveAttributes attributes; + QwtPlotCurve::PaintAttributes paintAttributes; + + QwtPlotCurve::LegendAttributes legendAttributes; +}; + +/*! + Constructor + \param title Title of the curve +*/ +QwtPlotCurve::QwtPlotCurve( const QwtText &title ): + QwtPlotSeriesItem( title ) +{ + init(); +} + +/*! + Constructor + \param title Title of the curve +*/ +QwtPlotCurve::QwtPlotCurve( const QString &title ): + QwtPlotSeriesItem( QwtText( title ) ) +{ + init(); +} + +//! Destructor +QwtPlotCurve::~QwtPlotCurve() +{ + delete d_data; +} + +//! Initialize internal members +void QwtPlotCurve::init() +{ + setItemAttribute( QwtPlotItem::Legend ); + setItemAttribute( QwtPlotItem::AutoScale ); + + d_data = new PrivateData; + setData( new QwtPointSeriesData() ); + + setZ( 20.0 ); +} + +//! \return QwtPlotItem::Rtti_PlotCurve +int QwtPlotCurve::rtti() const +{ + return QwtPlotItem::Rtti_PlotCurve; +} + +/*! + Specify an attribute how to draw the curve + + \param attribute Paint attribute + \param on On/Off + \sa testPaintAttribute() +*/ +void QwtPlotCurve::setPaintAttribute( PaintAttribute attribute, bool on ) +{ + if ( on ) + d_data->paintAttributes |= attribute; + else + d_data->paintAttributes &= ~attribute; +} + +/*! + \return True, when attribute is enabled + \sa setPaintAttribute() +*/ +bool QwtPlotCurve::testPaintAttribute( PaintAttribute attribute ) const +{ + return ( d_data->paintAttributes & attribute ); +} + +/*! + Specify an attribute how to draw the legend icon + + \param attribute Attribute + \param on On/Off + /sa testLegendAttribute(). legendIcon() +*/ +void QwtPlotCurve::setLegendAttribute( LegendAttribute attribute, bool on ) +{ + if ( on != testLegendAttribute( attribute ) ) + { + if ( on ) + d_data->legendAttributes |= attribute; + else + d_data->legendAttributes &= ~attribute; + + qwtUpdateLegendIconSize( this ); + legendChanged(); + } +} + +/*! + \return True, when attribute is enabled + \sa setLegendAttribute() +*/ +bool QwtPlotCurve::testLegendAttribute( LegendAttribute attribute ) const +{ + return ( d_data->legendAttributes & attribute ); +} + +/*! + Set the curve's drawing style + + \param style Curve style + \sa style() +*/ +void QwtPlotCurve::setStyle( CurveStyle style ) +{ + if ( style != d_data->style ) + { + d_data->style = style; + + legendChanged(); + itemChanged(); + } +} + +/*! + \return Style of the curve + \sa setStyle() +*/ +QwtPlotCurve::CurveStyle QwtPlotCurve::style() const +{ + return d_data->style; +} + +/*! + \brief Assign a symbol + + The curve will take the ownership of the symbol, hence the previously + set symbol will be delete by setting a new one. If \p symbol is + \c NULL no symbol will be drawn. + + \param symbol Symbol + \sa symbol() +*/ +void QwtPlotCurve::setSymbol( QwtSymbol *symbol ) +{ + if ( symbol != d_data->symbol ) + { + delete d_data->symbol; + d_data->symbol = symbol; + + qwtUpdateLegendIconSize( this ); + + legendChanged(); + itemChanged(); + } +} + +/*! + \return Current symbol or NULL, when no symbol has been assigned + \sa setSymbol() +*/ +const QwtSymbol *QwtPlotCurve::symbol() const +{ + return d_data->symbol; +} + +/*! + Build and assign a pen + + In Qt5 the default pen width is 1.0 ( 0.0 in Qt4 ) what makes it + non cosmetic ( see QPen::isCosmetic() ). This method has been introduced + to hide this incompatibility. + + \param color Pen color + \param width Pen width + \param style Pen style + + \sa pen(), brush() + */ +void QwtPlotCurve::setPen( const QColor &color, qreal width, Qt::PenStyle style ) +{ + setPen( QPen( color, width, style ) ); +} + +/*! + Assign a pen + + \param pen New pen + \sa pen(), brush() +*/ +void QwtPlotCurve::setPen( const QPen &pen ) +{ + if ( pen != d_data->pen ) + { + d_data->pen = pen; + + legendChanged(); + itemChanged(); + } +} + +/*! + \return Pen used to draw the lines + \sa setPen(), brush() +*/ +const QPen& QwtPlotCurve::pen() const +{ + return d_data->pen; +} + +/*! + \brief Assign a brush. + + In case of brush.style() != QBrush::NoBrush + and style() != QwtPlotCurve::Sticks + the area between the curve and the baseline will be filled. + + In case !brush.color().isValid() the area will be filled by + pen.color(). The fill algorithm simply connects the first and the + last curve point to the baseline. So the curve data has to be sorted + (ascending or descending). + + \param brush New brush + \sa brush(), setBaseline(), baseline() +*/ +void QwtPlotCurve::setBrush( const QBrush &brush ) +{ + if ( brush != d_data->brush ) + { + d_data->brush = brush; + + legendChanged(); + itemChanged(); + } +} + +/*! + \return Brush used to fill the area between lines and the baseline + \sa setBrush(), setBaseline(), baseline() +*/ +const QBrush& QwtPlotCurve::brush() const +{ + return d_data->brush; +} + +/*! + Draw an interval of the curve + + \param painter Painter + \param xMap Maps x-values into pixel coordinates. + \param yMap Maps y-values into pixel coordinates. + \param canvasRect Contents rectangle of the canvas + \param from Index of the first point to be painted + \param to Index of the last point to be painted. If to < 0 the + curve will be painted to its last point. + + \sa drawCurve(), drawSymbols(), +*/ +void QwtPlotCurve::drawSeries( QPainter *painter, + const QwtScaleMap &xMap, const QwtScaleMap &yMap, + const QRectF &canvasRect, int from, int to ) const +{ + const size_t numSamples = dataSize(); + + if ( !painter || numSamples <= 0 ) + return; + + if ( to < 0 ) + to = numSamples - 1; + + if ( qwtVerifyRange( numSamples, from, to ) > 0 ) + { + painter->save(); + painter->setPen( d_data->pen ); + + /* + Qt 4.0.0 is slow when drawing lines, but it's even + slower when the painter has a brush. So we don't + set the brush before we really need it. + */ + + drawCurve( painter, d_data->style, xMap, yMap, canvasRect, from, to ); + painter->restore(); + + if ( d_data->symbol && + ( d_data->symbol->style() != QwtSymbol::NoSymbol ) ) + { + painter->save(); + drawSymbols( painter, *d_data->symbol, + xMap, yMap, canvasRect, from, to ); + painter->restore(); + } + } +} + +/*! + \brief Draw the line part (without symbols) of a curve interval. + \param painter Painter + \param style curve style, see QwtPlotCurve::CurveStyle + \param xMap x map + \param yMap y map + \param canvasRect Contents rectangle of the canvas + \param from index of the first point to be painted + \param to index of the last point to be painted + \sa draw(), drawDots(), drawLines(), drawSteps(), drawSticks() +*/ +void QwtPlotCurve::drawCurve( QPainter *painter, int style, + const QwtScaleMap &xMap, const QwtScaleMap &yMap, + const QRectF &canvasRect, int from, int to ) const +{ + switch ( style ) + { + case Lines: + if ( testCurveAttribute( Fitted ) ) + { + // we always need the complete + // curve for fitting + from = 0; + to = dataSize() - 1; + } + drawLines( painter, xMap, yMap, canvasRect, from, to ); + break; + case Sticks: + drawSticks( painter, xMap, yMap, canvasRect, from, to ); + break; + case Steps: + drawSteps( painter, xMap, yMap, canvasRect, from, to ); + break; + case Dots: + drawDots( painter, xMap, yMap, canvasRect, from, to ); + break; + case NoCurve: + default: + break; + } +} + +/*! + \brief Draw lines + + If the CurveAttribute Fitted is enabled a QwtCurveFitter tries + to interpolate/smooth the curve, before it is painted. + + \param painter Painter + \param xMap x map + \param yMap y map + \param canvasRect Contents rectangle of the canvas + \param from index of the first point to be painted + \param to index of the last point to be painted + + \sa setCurveAttribute(), setCurveFitter(), draw(), + drawLines(), drawDots(), drawSteps(), drawSticks() +*/ +void QwtPlotCurve::drawLines( QPainter *painter, + const QwtScaleMap &xMap, const QwtScaleMap &yMap, + const QRectF &canvasRect, int from, int to ) const +{ + if ( from > to ) + return; + + const bool doAlign = QwtPainter::roundingAlignment( painter ); + const bool doFit = ( d_data->attributes & Fitted ) && d_data->curveFitter; + const bool doFill = ( d_data->brush.style() != Qt::NoBrush ) + && ( d_data->brush.color().alpha() > 0 ); + + QRectF clipRect; + if ( d_data->paintAttributes & ClipPolygons ) + { + qreal pw = qMax( qreal( 1.0 ), painter->pen().widthF()); + clipRect = canvasRect.adjusted(-pw, -pw, pw, pw); + } + + bool doIntegers = false; + +#if QT_VERSION < 0x040800 + + // For Qt <= 4.7 the raster paint engine is significantly faster + // for rendering QPolygon than for QPolygonF. So let's + // see if we can use it. + + if ( painter->paintEngine()->type() == QPaintEngine::Raster ) + { + // In case of filling or fitting performance doesn't count + // because both operations are much more expensive + // then drawing the polyline itself + + if ( !doFit && !doFill ) + doIntegers = true; + } +#endif + + const bool noDuplicates = d_data->paintAttributes & FilterPoints; + + QwtPointMapper mapper; + mapper.setFlag( QwtPointMapper::RoundPoints, doAlign ); + mapper.setFlag( QwtPointMapper::WeedOutPoints, noDuplicates ); + mapper.setBoundingRect( canvasRect ); + + if ( doIntegers ) + { + const QPolygon polyline = mapper.toPolygon( + xMap, yMap, data(), from, to ); + + if ( d_data->paintAttributes & ClipPolygons ) + { + const QPolygon clipped = QwtClipper::clipPolygon( + clipRect.toAlignedRect(), polyline, false ); + + QwtPainter::drawPolyline( painter, clipped ); + } + else + { + QwtPainter::drawPolyline( painter, polyline ); + } + } + else + { + QPolygonF polyline = mapper.toPolygonF( xMap, yMap, + data(), from, to ); + + if ( doFit ) + polyline = d_data->curveFitter->fitCurve( polyline ); + + if ( d_data->paintAttributes & ClipPolygons ) + { + const QPolygonF clipped = QwtClipper::clipPolygonF( + clipRect, polyline, false ); + + QwtPainter::drawPolyline( painter, clipped ); + } + else + { + QwtPainter::drawPolyline( painter, polyline ); + } + + if ( doFill ) + { + fillCurve( painter, xMap, yMap, canvasRect, polyline ); + } + } +} + +/*! + Draw sticks + + \param painter Painter + \param xMap x map + \param yMap y map + \param canvasRect Contents rectangle of the canvas + \param from index of the first point to be painted + \param to index of the last point to be painted + + \sa draw(), drawCurve(), drawDots(), drawLines(), drawSteps() +*/ +void QwtPlotCurve::drawSticks( QPainter *painter, + const QwtScaleMap &xMap, const QwtScaleMap &yMap, + const QRectF &, int from, int to ) const +{ + painter->save(); + painter->setRenderHint( QPainter::Antialiasing, false ); + + const bool doAlign = QwtPainter::roundingAlignment( painter ); + + double x0 = xMap.transform( d_data->baseline ); + double y0 = yMap.transform( d_data->baseline ); + if ( doAlign ) + { + x0 = qRound( x0 ); + y0 = qRound( y0 ); + } + + const Qt::Orientation o = orientation(); + + const QwtSeriesData *series = data(); + + for ( int i = from; i <= to; i++ ) + { + const QPointF sample = series->sample( i ); + double xi = xMap.transform( sample.x() ); + double yi = yMap.transform( sample.y() ); + if ( doAlign ) + { + xi = qRound( xi ); + yi = qRound( yi ); + } + + if ( o == Qt::Horizontal ) + QwtPainter::drawLine( painter, x0, yi, xi, yi ); + else + QwtPainter::drawLine( painter, xi, y0, xi, yi ); + } + + painter->restore(); +} + +/*! + Draw dots + + \param painter Painter + \param xMap x map + \param yMap y map + \param canvasRect Contents rectangle of the canvas + \param from index of the first point to be painted + \param to index of the last point to be painted + + \sa draw(), drawCurve(), drawSticks(), drawLines(), drawSteps() +*/ +void QwtPlotCurve::drawDots( QPainter *painter, + const QwtScaleMap &xMap, const QwtScaleMap &yMap, + const QRectF &canvasRect, int from, int to ) const +{ + const QColor color = painter->pen().color(); + + if ( painter->pen().style() == Qt::NoPen || color.alpha() == 0 ) + { + return; + } + + const bool doFill = ( d_data->brush.style() != Qt::NoBrush ) + && ( d_data->brush.color().alpha() > 0 ); + const bool doAlign = QwtPainter::roundingAlignment( painter ); + + QwtPointMapper mapper; + mapper.setBoundingRect( canvasRect ); + mapper.setFlag( QwtPointMapper::RoundPoints, doAlign ); + + if ( d_data->paintAttributes & FilterPoints ) + { + if ( ( color.alpha() == 255 ) + && !( painter->renderHints() & QPainter::Antialiasing ) ) + { + mapper.setFlag( QwtPointMapper::WeedOutPoints, true ); + } + } + + if ( doFill ) + { + mapper.setFlag( QwtPointMapper::WeedOutPoints, false ); + + QPolygonF points = mapper.toPointsF( + xMap, yMap, data(), from, to ); + + QwtPainter::drawPoints( painter, points ); + fillCurve( painter, xMap, yMap, canvasRect, points ); + } + else if ( d_data->paintAttributes & ImageBuffer ) + { + const QImage image = mapper.toImage( xMap, yMap, + data(), from, to, d_data->pen, + painter->testRenderHint( QPainter::Antialiasing ), + renderThreadCount() ); + + painter->drawImage( canvasRect.toAlignedRect(), image ); + } + else if ( d_data->paintAttributes & MinimizeMemory ) + { + const QwtSeriesData *series = data(); + + for ( int i = from; i <= to; i++ ) + { + const QPointF sample = series->sample( i ); + + double xi = xMap.transform( sample.x() ); + double yi = yMap.transform( sample.y() ); + + if ( doAlign ) + { + xi = qRound( xi ); + yi = qRound( yi ); + } + + QwtPainter::drawPoint( painter, QPointF( xi, yi ) ); + } + } + else + { + if ( doAlign ) + { + const QPolygon points = mapper.toPoints( + xMap, yMap, data(), from, to ); + + QwtPainter::drawPoints( painter, points ); + } + else + { + const QPolygonF points = mapper.toPointsF( + xMap, yMap, data(), from, to ); + + QwtPainter::drawPoints( painter, points ); + } + } +} + +/*! + Draw step function + + The direction of the steps depends on Inverted attribute. + + \param painter Painter + \param xMap x map + \param yMap y map + \param canvasRect Contents rectangle of the canvas + \param from index of the first point to be painted + \param to index of the last point to be painted + + \sa CurveAttribute, setCurveAttribute(), + draw(), drawCurve(), drawDots(), drawLines(), drawSticks() +*/ +void QwtPlotCurve::drawSteps( QPainter *painter, + const QwtScaleMap &xMap, const QwtScaleMap &yMap, + const QRectF &canvasRect, int from, int to ) const +{ + const bool doAlign = QwtPainter::roundingAlignment( painter ); + + QPolygonF polygon( 2 * ( to - from ) + 1 ); + QPointF *points = polygon.data(); + + bool inverted = orientation() == Qt::Vertical; + if ( d_data->attributes & Inverted ) + inverted = !inverted; + + const QwtSeriesData *series = data(); + + int i, ip; + for ( i = from, ip = 0; i <= to; i++, ip += 2 ) + { + const QPointF sample = series->sample( i ); + double xi = xMap.transform( sample.x() ); + double yi = yMap.transform( sample.y() ); + if ( doAlign ) + { + xi = qRound( xi ); + yi = qRound( yi ); + } + + if ( ip > 0 ) + { + const QPointF &p0 = points[ip - 2]; + QPointF &p = points[ip - 1]; + + if ( inverted ) + { + p.rx() = p0.x(); + p.ry() = yi; + } + else + { + p.rx() = xi; + p.ry() = p0.y(); + } + } + + points[ip].rx() = xi; + points[ip].ry() = yi; + } + + if ( d_data->paintAttributes & ClipPolygons ) + { + const QPolygonF clipped = QwtClipper::clipPolygonF( + canvasRect, polygon, false ); + + QwtPainter::drawPolyline( painter, clipped ); + } + else + { + QwtPainter::drawPolyline( painter, polygon ); + } + + if ( d_data->brush.style() != Qt::NoBrush ) + fillCurve( painter, xMap, yMap, canvasRect, polygon ); +} + + +/*! + Specify an attribute for drawing the curve + + \param attribute Curve attribute + \param on On/Off + + /sa testCurveAttribute(), setCurveFitter() +*/ +void QwtPlotCurve::setCurveAttribute( CurveAttribute attribute, bool on ) +{ + if ( bool( d_data->attributes & attribute ) == on ) + return; + + if ( on ) + d_data->attributes |= attribute; + else + d_data->attributes &= ~attribute; + + itemChanged(); +} + +/*! + \return true, if attribute is enabled + \sa setCurveAttribute() +*/ +bool QwtPlotCurve::testCurveAttribute( CurveAttribute attribute ) const +{ + return d_data->attributes & attribute; +} + +/*! + Assign a curve fitter + + The curve fitter "smooths" the curve points, when the Fitted + CurveAttribute is set. setCurveFitter(NULL) also disables curve fitting. + + The curve fitter operates on the translated points ( = widget coordinates) + to be functional for logarithmic scales. Obviously this is less performant + for fitting algorithms, that reduce the number of points. + + For situations, where curve fitting is used to improve the performance + of painting huge series of points it might be better to execute the fitter + on the curve points once and to cache the result in the QwtSeriesData object. + + \param curveFitter() Curve fitter + \sa Fitted +*/ +void QwtPlotCurve::setCurveFitter( QwtCurveFitter *curveFitter ) +{ + delete d_data->curveFitter; + d_data->curveFitter = curveFitter; + + itemChanged(); +} + +/*! + Get the curve fitter. If curve fitting is disabled NULL is returned. + + \return Curve fitter + \sa setCurveFitter(), Fitted +*/ +QwtCurveFitter *QwtPlotCurve::curveFitter() const +{ + return d_data->curveFitter; +} + +/*! + Fill the area between the curve and the baseline with + the curve brush + + \param painter Painter + \param xMap x map + \param yMap y map + \param canvasRect Contents rectangle of the canvas + \param polygon Polygon - will be modified ! + + \sa setBrush(), setBaseline(), setStyle() +*/ +void QwtPlotCurve::fillCurve( QPainter *painter, + const QwtScaleMap &xMap, const QwtScaleMap &yMap, + const QRectF &canvasRect, QPolygonF &polygon ) const +{ + if ( d_data->brush.style() == Qt::NoBrush ) + return; + + closePolyline( painter, xMap, yMap, polygon ); + if ( polygon.count() <= 2 ) // a line can't be filled + return; + + QBrush brush = d_data->brush; + if ( !brush.color().isValid() ) + brush.setColor( d_data->pen.color() ); + + if ( d_data->paintAttributes & ClipPolygons ) + polygon = QwtClipper::clipPolygonF( canvasRect, polygon, true ); + + painter->save(); + + painter->setPen( Qt::NoPen ); + painter->setBrush( brush ); + + QwtPainter::drawPolygon( painter, polygon ); + + painter->restore(); +} + +/*! + \brief Complete a polygon to be a closed polygon including the + area between the original polygon and the baseline. + + \param painter Painter + \param xMap X map + \param yMap Y map + \param polygon Polygon to be completed +*/ +void QwtPlotCurve::closePolyline( QPainter *painter, + const QwtScaleMap &xMap, const QwtScaleMap &yMap, + QPolygonF &polygon ) const +{ + if ( polygon.size() < 2 ) + return; + + const bool doAlign = QwtPainter::roundingAlignment( painter ); + + double baseline = d_data->baseline; + + if ( orientation() == Qt::Vertical ) + { + if ( yMap.transformation() ) + baseline = yMap.transformation()->bounded( baseline ); + + double refY = yMap.transform( baseline ); + if ( doAlign ) + refY = qRound( refY ); + + polygon += QPointF( polygon.last().x(), refY ); + polygon += QPointF( polygon.first().x(), refY ); + } + else + { + if ( xMap.transformation() ) + baseline = xMap.transformation()->bounded( baseline ); + + double refX = xMap.transform( baseline ); + if ( doAlign ) + refX = qRound( refX ); + + polygon += QPointF( refX, polygon.last().y() ); + polygon += QPointF( refX, polygon.first().y() ); + } +} + +/*! + Draw symbols + + \param painter Painter + \param symbol Curve symbol + \param xMap x map + \param yMap y map + \param canvasRect Contents rectangle of the canvas + \param from Index of the first point to be painted + \param to Index of the last point to be painted + + \sa setSymbol(), drawSeries(), drawCurve() +*/ +void QwtPlotCurve::drawSymbols( QPainter *painter, const QwtSymbol &symbol, + const QwtScaleMap &xMap, const QwtScaleMap &yMap, + const QRectF &canvasRect, int from, int to ) const +{ + QwtPointMapper mapper; + mapper.setFlag( QwtPointMapper::RoundPoints, + QwtPainter::roundingAlignment( painter ) ); + mapper.setFlag( QwtPointMapper::WeedOutPoints, + testPaintAttribute( QwtPlotCurve::FilterPoints ) ); + mapper.setBoundingRect( canvasRect ); + + const int chunkSize = 500; + + for ( int i = from; i <= to; i += chunkSize ) + { + const int n = qMin( chunkSize, to - i + 1 ); + + const QPolygonF points = mapper.toPointsF( xMap, yMap, + data(), i, i + n - 1 ); + + if ( points.size() > 0 ) + symbol.drawSymbols( painter, points ); + } +} + +/*! + \brief Set the value of the baseline + + The baseline is needed for filling the curve with a brush or + the Sticks drawing style. + + The interpretation of the baseline depends on the orientation(). + With Qt::Horizontal, the baseline is interpreted as a horizontal line + at y = baseline(), with Qt::Vertical, it is interpreted as a vertical + line at x = baseline(). + + The default value is 0.0. + + \param value Value of the baseline + \sa baseline(), setBrush(), setStyle(), QwtPlotAbstractSeriesItem::orientation() +*/ +void QwtPlotCurve::setBaseline( double value ) +{ + if ( d_data->baseline != value ) + { + d_data->baseline = value; + itemChanged(); + } +} + +/*! + \return Value of the baseline + \sa setBaseline() +*/ +double QwtPlotCurve::baseline() const +{ + return d_data->baseline; +} + +/*! + Find the closest curve point for a specific position + + \param pos Position, where to look for the closest curve point + \param dist If dist != NULL, closestPoint() returns the distance between + the position and the closest curve point + \return Index of the closest curve point, or -1 if none can be found + ( f.e when the curve has no points ) + \note closestPoint() implements a dumb algorithm, that iterates + over all points +*/ +int QwtPlotCurve::closestPoint( const QPoint &pos, double *dist ) const +{ + const size_t numSamples = dataSize(); + + if ( plot() == NULL || numSamples <= 0 ) + return -1; + + const QwtSeriesData *series = data(); + + const QwtScaleMap xMap = plot()->canvasMap( xAxis() ); + const QwtScaleMap yMap = plot()->canvasMap( yAxis() ); + + int index = -1; + double dmin = 1.0e10; + + for ( uint i = 0; i < numSamples; i++ ) + { + const QPointF sample = series->sample( i ); + + const double cx = xMap.transform( sample.x() ) - pos.x(); + const double cy = yMap.transform( sample.y() ) - pos.y(); + + const double f = qwtSqr( cx ) + qwtSqr( cy ); + if ( f < dmin ) + { + index = i; + dmin = f; + } + } + if ( dist ) + *dist = qSqrt( dmin ); + + return index; +} + +/*! + \return Icon representing the curve on the legend + + \param index Index of the legend entry + ( ignored as there is only one ) + \param size Icon size + + \sa QwtPlotItem::setLegendIconSize(), QwtPlotItem::legendData() + */ +QwtGraphic QwtPlotCurve::legendIcon( int index, + const QSizeF &size ) const +{ + Q_UNUSED( index ); + + if ( size.isEmpty() ) + return QwtGraphic(); + + QwtGraphic graphic; + graphic.setDefaultSize( size ); + graphic.setRenderHint( QwtGraphic::RenderPensUnscaled, true ); + + QPainter painter( &graphic ); + painter.setRenderHint( QPainter::Antialiasing, + testRenderHint( QwtPlotItem::RenderAntialiased ) ); + + if ( d_data->legendAttributes == 0 || + d_data->legendAttributes & QwtPlotCurve::LegendShowBrush ) + { + QBrush brush = d_data->brush; + + if ( brush.style() == Qt::NoBrush && + d_data->legendAttributes == 0 ) + { + if ( style() != QwtPlotCurve::NoCurve ) + { + brush = QBrush( pen().color() ); + } + else if ( d_data->symbol && + ( d_data->symbol->style() != QwtSymbol::NoSymbol ) ) + { + brush = QBrush( d_data->symbol->pen().color() ); + } + } + + if ( brush.style() != Qt::NoBrush ) + { + QRectF r( 0, 0, size.width(), size.height() ); + painter.fillRect( r, brush ); + } + } + + if ( d_data->legendAttributes & QwtPlotCurve::LegendShowLine ) + { + if ( pen() != Qt::NoPen ) + { + QPen pn = pen(); + pn.setCapStyle( Qt::FlatCap ); + + painter.setPen( pn ); + + const double y = 0.5 * size.height(); + QwtPainter::drawLine( &painter, 0.0, y, size.width(), y ); + } + } + + if ( d_data->legendAttributes & QwtPlotCurve::LegendShowSymbol ) + { + if ( d_data->symbol ) + { + QRectF r( 0, 0, size.width(), size.height() ); + d_data->symbol->drawSymbol( &painter, r ); + } + } + + return graphic; +} + +/*! + Initialize data with an array of points. + + \param samples Vector of points + \note QVector is implicitly shared + \note QPolygonF is derived from QVector +*/ +void QwtPlotCurve::setSamples( const QVector &samples ) +{ + setData( new QwtPointSeriesData( samples ) ); +} + +/*! + Assign a series of points + + setSamples() is just a wrapper for setData() without any additional + value - beside that it is easier to find for the developer. + + \param data Data + \warning The item takes ownership of the data object, deleting + it when its not used anymore. +*/ +void QwtPlotCurve::setSamples( QwtSeriesData *data ) +{ + setData( data ); +} + +#ifndef QWT_NO_COMPAT + +/*! + \brief Initialize the data by pointing to memory blocks which + are not managed by QwtPlotCurve. + + setRawSamples is provided for efficiency. + It is important to keep the pointers + during the lifetime of the underlying QwtCPointerData class. + + \param xData pointer to x data + \param yData pointer to y data + \param size size of x and y + + \sa QwtCPointerData +*/ +void QwtPlotCurve::setRawSamples( + const double *xData, const double *yData, int size ) +{ + setData( new QwtCPointerData( xData, yData, size ) ); +} + +/*! + Set data by copying x- and y-values from specified memory blocks. + Contrary to setRawSamples(), this function makes a 'deep copy' of + the data. + + \param xData pointer to x values + \param yData pointer to y values + \param size size of xData and yData + + \sa QwtPointArrayData +*/ +void QwtPlotCurve::setSamples( + const double *xData, const double *yData, int size ) +{ + setData( new QwtPointArrayData( xData, yData, size ) ); +} + +/*! + \brief Initialize data with x- and y-arrays (explicitly shared) + + \param xData x data + \param yData y data + + \sa QwtPointArrayData +*/ +void QwtPlotCurve::setSamples( const QVector &xData, + const QVector &yData ) +{ + setData( new QwtPointArrayData( xData, yData ) ); +} + +#endif // !QWT_NO_COMPAT + diff --git a/ThirdParty/Qwt/src/qwt_plot_curve.h b/ThirdParty/Qwt/src/qwt_plot_curve.h new file mode 100644 index 0000000000..3421abf816 --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_plot_curve.h @@ -0,0 +1,337 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#ifndef QWT_PLOT_CURVE_H +#define QWT_PLOT_CURVE_H + +#include "qwt_global.h" +#include "qwt_plot_seriesitem.h" +#include "qwt_series_data.h" +#include "qwt_text.h" +#include +#include + +class QPainter; +class QPolygonF; +class QwtScaleMap; +class QwtSymbol; +class QwtCurveFitter; + +/*! + \brief A plot item, that represents a series of points + + A curve is the representation of a series of points in the x-y plane. + It supports different display styles, interpolation ( f.e. spline ) + and symbols. + + \par Usage +
a) Assign curve properties
+
When a curve is created, it is configured to draw black solid lines + with in QwtPlotCurve::Lines style and no symbols. + You can change this by calling + setPen(), setStyle() and setSymbol().
+
b) Connect/Assign data.
+
QwtPlotCurve gets its points using a QwtSeriesData object offering + a bridge to the real storage of the points ( like QAbstractItemModel ). + There are several convenience classes derived from QwtSeriesData, that also store + the points inside ( like QStandardItemModel ). QwtPlotCurve also offers + a couple of variations of setSamples(), that build QwtSeriesData objects from + arrays internally.
+
c) Attach the curve to a plot
+
See QwtPlotItem::attach() +
+ + \par Example: + see examples/bode + + \sa QwtPointSeriesData, QwtSymbol, QwtScaleMap +*/ +class QWT_EXPORT QwtPlotCurve: + public QwtPlotSeriesItem, public QwtSeriesStore +{ +public: + /*! + Curve styles. + \sa setStyle(), style() + */ + enum CurveStyle + { + /*! + Don't draw a curve. Note: This doesn't affect the symbols. + */ + NoCurve = -1, + + /*! + Connect the points with straight lines. The lines might + be interpolated depending on the 'Fitted' attribute. Curve + fitting can be configured using setCurveFitter(). + */ + Lines, + + /*! + Draw vertical or horizontal sticks ( depending on the + orientation() ) from a baseline which is defined by setBaseline(). + */ + Sticks, + + /*! + Connect the points with a step function. The step function + is drawn from the left to the right or vice versa, + depending on the QwtPlotCurve::Inverted attribute. + */ + Steps, + + /*! + Draw dots at the locations of the data points. Note: + This is different from a dotted line (see setPen()), and faster + as a curve in QwtPlotCurve::NoStyle style and a symbol + painting a point. + */ + Dots, + + /*! + Styles >= QwtPlotCurve::UserCurve are reserved for derived + classes of QwtPlotCurve that overload drawCurve() with + additional application specific curve types. + */ + UserCurve = 100 + }; + + /*! + Attribute for drawing the curve + \sa setCurveAttribute(), testCurveAttribute(), curveFitter() + */ + enum CurveAttribute + { + /*! + For QwtPlotCurve::Steps only. + Draws a step function from the right to the left. + */ + Inverted = 0x01, + + /*! + Only in combination with QwtPlotCurve::Lines + A QwtCurveFitter tries to + interpolate/smooth the curve, before it is painted. + + \note Curve fitting requires temporary memory + for calculating coefficients and additional points. + If painting in QwtPlotCurve::Fitted mode is slow it might be better + to fit the points, before they are passed to QwtPlotCurve. + */ + Fitted = 0x02 + }; + + //! Curve attributes + typedef QFlags CurveAttributes; + + /*! + Attributes how to represent the curve on the legend + + \sa setLegendAttribute(), testLegendAttribute(), + QwtPlotItem::legendData(), legendIcon() + */ + + enum LegendAttribute + { + /*! + QwtPlotCurve tries to find a color representing the curve + and paints a rectangle with it. + */ + LegendNoAttribute = 0x00, + + /*! + If the style() is not QwtPlotCurve::NoCurve a line + is painted with the curve pen(). + */ + LegendShowLine = 0x01, + + /*! + If the curve has a valid symbol it is painted. + */ + LegendShowSymbol = 0x02, + + /*! + If the curve has a brush a rectangle filled with the + curve brush() is painted. + */ + LegendShowBrush = 0x04 + }; + + //! Legend attributes + typedef QFlags LegendAttributes; + + /*! + Attributes to modify the drawing algorithm. + The default setting enables ClipPolygons | FilterPoints + + \sa setPaintAttribute(), testPaintAttribute() + */ + enum PaintAttribute + { + /*! + Clip polygons before painting them. In situations, where points + are far outside the visible area (f.e when zooming deep) this + might be a substantial improvement for the painting performance + */ + ClipPolygons = 0x01, + + /*! + Tries to reduce the data that has to be painted, by sorting out + duplicates, or paintings outside the visible area. Might have a + notable impact on curves with many close points. + Only a couple of very basic filtering algorithms are implemented. + */ + FilterPoints = 0x02, + + /*! + Minimize memory usage that is temporarily needed for the + translated points, before they get painted. + This might slow down the performance of painting + */ + MinimizeMemory = 0x04, + + /*! + Render the points to a temporary image and paint the image. + This is a very special optimization for Dots style, when + having a huge amount of points. + With a reasonable number of points QPainter::drawPoints() + will be faster. + */ + ImageBuffer = 0x08 + }; + + //! Paint attributes + typedef QFlags PaintAttributes; + + explicit QwtPlotCurve( const QString &title = QString::null ); + explicit QwtPlotCurve( const QwtText &title ); + + virtual ~QwtPlotCurve(); + + virtual int rtti() const; + + void setPaintAttribute( PaintAttribute, bool on = true ); + bool testPaintAttribute( PaintAttribute ) const; + + void setLegendAttribute( LegendAttribute, bool on = true ); + bool testLegendAttribute( LegendAttribute ) const; + +#ifndef QWT_NO_COMPAT + void setRawSamples( const double *xData, const double *yData, int size ); + void setSamples( const double *xData, const double *yData, int size ); + void setSamples( const QVector &xData, const QVector &yData ); +#endif + void setSamples( const QVector & ); + void setSamples( QwtSeriesData * ); + + int closestPoint( const QPoint &pos, double *dist = NULL ) const; + + double minXValue() const; + double maxXValue() const; + double minYValue() const; + double maxYValue() const; + + void setCurveAttribute( CurveAttribute, bool on = true ); + bool testCurveAttribute( CurveAttribute ) const; + + void setPen( const QColor &, qreal width = 0.0, Qt::PenStyle = Qt::SolidLine ); + void setPen( const QPen & ); + const QPen &pen() const; + + void setBrush( const QBrush & ); + const QBrush &brush() const; + + void setBaseline( double ); + double baseline() const; + + void setStyle( CurveStyle style ); + CurveStyle style() const; + + void setSymbol( QwtSymbol * ); + const QwtSymbol *symbol() const; + + void setCurveFitter( QwtCurveFitter * ); + QwtCurveFitter *curveFitter() const; + + virtual void drawSeries( QPainter *, + const QwtScaleMap &xMap, const QwtScaleMap &yMap, + const QRectF &canvasRect, int from, int to ) const; + + virtual QwtGraphic legendIcon( int index, const QSizeF & ) const; + +protected: + + void init(); + + virtual void drawCurve( QPainter *p, int style, + const QwtScaleMap &xMap, const QwtScaleMap &yMap, + const QRectF &canvasRect, int from, int to ) const; + + virtual void drawSymbols( QPainter *p, const QwtSymbol &, + const QwtScaleMap &xMap, const QwtScaleMap &yMap, + const QRectF &canvasRect, int from, int to ) const; + + virtual void drawLines( QPainter *p, + const QwtScaleMap &xMap, const QwtScaleMap &yMap, + const QRectF &canvasRect, int from, int to ) const; + + virtual void drawSticks( QPainter *p, + const QwtScaleMap &xMap, const QwtScaleMap &yMap, + const QRectF &canvasRect, int from, int to ) const; + + virtual void drawDots( QPainter *p, + const QwtScaleMap &xMap, const QwtScaleMap &yMap, + const QRectF &canvasRect, int from, int to ) const; + + virtual void drawSteps( QPainter *p, + const QwtScaleMap &xMap, const QwtScaleMap &yMap, + const QRectF &canvasRect, int from, int to ) const; + + virtual void fillCurve( QPainter *, + const QwtScaleMap &, const QwtScaleMap &, + const QRectF &canvasRect, QPolygonF & ) const; + + void closePolyline( QPainter *, + const QwtScaleMap &, const QwtScaleMap &, QPolygonF & ) const; + +private: + class PrivateData; + PrivateData *d_data; +}; + +//! boundingRect().left() +inline double QwtPlotCurve::minXValue() const +{ + return boundingRect().left(); +} + +//! boundingRect().right() +inline double QwtPlotCurve::maxXValue() const +{ + return boundingRect().right(); +} + +//! boundingRect().top() +inline double QwtPlotCurve::minYValue() const +{ + return boundingRect().top(); +} + +//! boundingRect().bottom() +inline double QwtPlotCurve::maxYValue() const +{ + return boundingRect().bottom(); +} + +Q_DECLARE_OPERATORS_FOR_FLAGS( QwtPlotCurve::PaintAttributes ) +Q_DECLARE_OPERATORS_FOR_FLAGS( QwtPlotCurve::LegendAttributes ) +Q_DECLARE_OPERATORS_FOR_FLAGS( QwtPlotCurve::CurveAttributes ) + +#endif diff --git a/ThirdParty/Qwt/src/qwt_plot_dict.cpp b/ThirdParty/Qwt/src/qwt_plot_dict.cpp new file mode 100644 index 0000000000..17c61ed479 --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_plot_dict.cpp @@ -0,0 +1,191 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#include "qwt_plot_dict.h" + +class QwtPlotDict::PrivateData +{ +public: + + class ItemList: public QList + { + public: + void insertItem( QwtPlotItem *item ) + { + if ( item == NULL ) + return; + + QList::iterator it = + qUpperBound( begin(), end(), item, LessZThan() ); + insert( it, item ); + } + + void removeItem( QwtPlotItem *item ) + { + if ( item == NULL ) + return; + + QList::iterator it = + qLowerBound( begin(), end(), item, LessZThan() ); + + for ( ; it != end(); ++it ) + { + if ( item == *it ) + { + erase( it ); + break; + } + } + } + private: + class LessZThan + { + public: + inline bool operator()( const QwtPlotItem *item1, + const QwtPlotItem *item2 ) const + { + return item1->z() < item2->z(); + } + }; + }; + + ItemList itemList; + bool autoDelete; +}; + +/*! + Constructor + + Auto deletion is enabled. + \sa setAutoDelete(), QwtPlotItem::attach() +*/ +QwtPlotDict::QwtPlotDict() +{ + d_data = new QwtPlotDict::PrivateData; + d_data->autoDelete = true; +} + +/*! + Destructor + + If autoDelete() is on, all attached items will be deleted + \sa setAutoDelete(), autoDelete(), QwtPlotItem::attach() +*/ +QwtPlotDict::~QwtPlotDict() +{ + detachItems( QwtPlotItem::Rtti_PlotItem, d_data->autoDelete ); + delete d_data; +} + +/*! + En/Disable Auto deletion + + If Auto deletion is on all attached plot items will be deleted + in the destructor of QwtPlotDict. The default value is on. + + \sa autoDelete(), insertItem() +*/ +void QwtPlotDict::setAutoDelete( bool autoDelete ) +{ + d_data->autoDelete = autoDelete; +} + +/*! + \return true if auto deletion is enabled + \sa setAutoDelete(), insertItem() +*/ +bool QwtPlotDict::autoDelete() const +{ + return d_data->autoDelete; +} + +/*! + Insert a plot item + + \param item PlotItem + \sa removeItem() + */ +void QwtPlotDict::insertItem( QwtPlotItem *item ) +{ + d_data->itemList.insertItem( item ); +} + +/*! + Remove a plot item + + \param item PlotItem + \sa insertItem() + */ +void QwtPlotDict::removeItem( QwtPlotItem *item ) +{ + d_data->itemList.removeItem( item ); +} + +/*! + Detach items from the dictionary + + \param rtti In case of QwtPlotItem::Rtti_PlotItem detach all items + otherwise only those items of the type rtti. + \param autoDelete If true, delete all detached items +*/ +void QwtPlotDict::detachItems( int rtti, bool autoDelete ) +{ + PrivateData::ItemList list = d_data->itemList; + QwtPlotItemIterator it = list.begin(); + while ( it != list.end() ) + { + QwtPlotItem *item = *it; + + ++it; // increment before removing item from the list + + if ( rtti == QwtPlotItem::Rtti_PlotItem || item->rtti() == rtti ) + { + item->attach( NULL ); + if ( autoDelete ) + delete item; + } + } +} + +/*! + \brief A QwtPlotItemList of all attached plot items. + + Use caution when iterating these lists, as removing/detaching an item will + invalidate the iterator. Instead you can place pointers to objects to be + removed in a removal list, and traverse that list later. + + \return List of all attached plot items. +*/ +const QwtPlotItemList &QwtPlotDict::itemList() const +{ + return d_data->itemList; +} + +/*! + \return List of all attached plot items of a specific type. + \param rtti See QwtPlotItem::RttiValues + \sa QwtPlotItem::rtti() +*/ +QwtPlotItemList QwtPlotDict::itemList( int rtti ) const +{ + if ( rtti == QwtPlotItem::Rtti_PlotItem ) + return d_data->itemList; + + QwtPlotItemList items; + + PrivateData::ItemList list = d_data->itemList; + for ( QwtPlotItemIterator it = list.begin(); it != list.end(); ++it ) + { + QwtPlotItem *item = *it; + if ( item->rtti() == rtti ) + items += item; + } + + return items; +} diff --git a/ThirdParty/Qwt/src/qwt_plot_dict.h b/ThirdParty/Qwt/src/qwt_plot_dict.h new file mode 100644 index 0000000000..5d34f0c051 --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_plot_dict.h @@ -0,0 +1,58 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +/*! \file !*/ +#ifndef QWT_PLOT_DICT +#define QWT_PLOT_DICT + +#include "qwt_global.h" +#include "qwt_plot_item.h" +#include + +/// \var typedef QList< QwtPlotItem *> QwtPlotItemList +/// \brief See QT 4.x assistant documentation for QList +typedef QList QwtPlotItemList; +typedef QList::ConstIterator QwtPlotItemIterator; + +/*! + \brief A dictionary for plot items + + QwtPlotDict organizes plot items in increasing z-order. + If autoDelete() is enabled, all attached items will be deleted + in the destructor of the dictionary. + QwtPlotDict can be used to get access to all QwtPlotItem items - or all + items of a specific type - that are currently on the plot. + + \sa QwtPlotItem::attach(), QwtPlotItem::detach(), QwtPlotItem::z() +*/ +class QWT_EXPORT QwtPlotDict +{ +public: + explicit QwtPlotDict(); + virtual ~QwtPlotDict(); + + void setAutoDelete( bool ); + bool autoDelete() const; + + const QwtPlotItemList& itemList() const; + QwtPlotItemList itemList( int rtti ) const; + + void detachItems( int rtti = QwtPlotItem::Rtti_PlotItem, + bool autoDelete = true ); + +protected: + void insertItem( QwtPlotItem * ); + void removeItem( QwtPlotItem * ); + +private: + class PrivateData; + PrivateData *d_data; +}; + +#endif diff --git a/ThirdParty/Qwt/src/qwt_plot_directpainter.cpp b/ThirdParty/Qwt/src/qwt_plot_directpainter.cpp new file mode 100644 index 0000000000..d78352740c --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_plot_directpainter.cpp @@ -0,0 +1,317 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#include "qwt_plot_directpainter.h" +#include "qwt_scale_map.h" +#include "qwt_plot.h" +#include "qwt_plot_canvas.h" +#include "qwt_plot_seriesitem.h" +#include +#include +#include +#include + +static inline void qwtRenderItem( + QPainter *painter, const QRect &canvasRect, + QwtPlotSeriesItem *seriesItem, int from, int to ) +{ + // A minor performance improvement is possible + // with caching the maps. TODO ... + + QwtPlot *plot = seriesItem->plot(); + const QwtScaleMap xMap = plot->canvasMap( seriesItem->xAxis() ); + const QwtScaleMap yMap = plot->canvasMap( seriesItem->yAxis() ); + + painter->setRenderHint( QPainter::Antialiasing, + seriesItem->testRenderHint( QwtPlotItem::RenderAntialiased ) ); + seriesItem->drawSeries( painter, xMap, yMap, canvasRect, from, to ); +} + +static inline bool qwtHasBackingStore( const QwtPlotCanvas *canvas ) +{ + return canvas->testPaintAttribute( QwtPlotCanvas::BackingStore ) + && canvas->backingStore() && !canvas->backingStore()->isNull(); +} + +class QwtPlotDirectPainter::PrivateData +{ +public: + PrivateData(): + attributes( 0 ), + hasClipping(false), + seriesItem( NULL ) + { + } + + QwtPlotDirectPainter::Attributes attributes; + + bool hasClipping; + QRegion clipRegion; + + QPainter painter; + + QwtPlotSeriesItem *seriesItem; + int from; + int to; +}; + +//! Constructor +QwtPlotDirectPainter::QwtPlotDirectPainter( QObject *parent ): + QObject( parent ) +{ + d_data = new PrivateData; +} + +//! Destructor +QwtPlotDirectPainter::~QwtPlotDirectPainter() +{ + delete d_data; +} + +/*! + Change an attribute + + \param attribute Attribute to change + \param on On/Off + + \sa Attribute, testAttribute() +*/ +void QwtPlotDirectPainter::setAttribute( Attribute attribute, bool on ) +{ + if ( bool( d_data->attributes & attribute ) != on ) + { + if ( on ) + d_data->attributes |= attribute; + else + d_data->attributes &= ~attribute; + + if ( ( attribute == AtomicPainter ) && on ) + reset(); + } +} + +/*! + \return True, when attribute is enabled + \param attribute Attribute to be tested + \sa Attribute, setAttribute() +*/ +bool QwtPlotDirectPainter::testAttribute( Attribute attribute ) const +{ + return d_data->attributes & attribute; +} + +/*! + En/Disables clipping + + \param enable Enables clipping is true, disable it otherwise + \sa hasClipping(), clipRegion(), setClipRegion() +*/ +void QwtPlotDirectPainter::setClipping( bool enable ) +{ + d_data->hasClipping = enable; +} + +/*! + \return true, when clipping is enabled + \sa setClipping(), clipRegion(), setClipRegion() +*/ +bool QwtPlotDirectPainter::hasClipping() const +{ + return d_data->hasClipping; +} + +/*! + \brief Assign a clip region and enable clipping + + Depending on the environment setting a proper clip region might improve + the performance heavily. F.e. on Qt embedded only the clipped part of + the backing store will be copied to a ( maybe unaccelerated ) frame buffer + device. + + \param region Clip region + \sa clipRegion(), hasClipping(), setClipping() +*/ +void QwtPlotDirectPainter::setClipRegion( const QRegion ®ion ) +{ + d_data->clipRegion = region; + d_data->hasClipping = true; +} + +/*! + \return Currently set clip region. + \sa setClipRegion(), setClipping(), hasClipping() +*/ +QRegion QwtPlotDirectPainter::clipRegion() const +{ + return d_data->clipRegion; +} + +/*! + \brief Draw a set of points of a seriesItem. + + When observing an measurement while it is running, new points have to be + added to an existing seriesItem. drawSeries() can be used to display them avoiding + a complete redraw of the canvas. + + Setting plot()->canvas()->setAttribute(Qt::WA_PaintOutsidePaintEvent, true); + will result in faster painting, if the paint engine of the canvas widget + supports this feature. + + \param seriesItem Item to be painted + \param from Index of the first point to be painted + \param to Index of the last point to be painted. If to < 0 the + series will be painted to its last point. +*/ +void QwtPlotDirectPainter::drawSeries( + QwtPlotSeriesItem *seriesItem, int from, int to ) +{ + if ( seriesItem == NULL || seriesItem->plot() == NULL ) + return; + + QWidget *canvas = seriesItem->plot()->canvas(); + const QRect canvasRect = canvas->contentsRect(); + + QwtPlotCanvas *plotCanvas = qobject_cast( canvas ); + + if ( plotCanvas && qwtHasBackingStore( plotCanvas ) ) + { + QPainter painter( const_cast( plotCanvas->backingStore() ) ); + + if ( d_data->hasClipping ) + painter.setClipRegion( d_data->clipRegion ); + + qwtRenderItem( &painter, canvasRect, seriesItem, from, to ); + + if ( testAttribute( QwtPlotDirectPainter::FullRepaint ) ) + { + plotCanvas->repaint(); + return; + } + } + + bool immediatePaint = true; + if ( !canvas->testAttribute( Qt::WA_WState_InPaintEvent ) ) + { +#if QT_VERSION < 0x050000 + if ( !canvas->testAttribute( Qt::WA_PaintOutsidePaintEvent ) ) +#endif + immediatePaint = false; + } + + if ( immediatePaint ) + { + if ( !d_data->painter.isActive() ) + { + reset(); + + d_data->painter.begin( canvas ); + canvas->installEventFilter( this ); + } + + if ( d_data->hasClipping ) + { + d_data->painter.setClipRegion( + QRegion( canvasRect ) & d_data->clipRegion ); + } + else + { + if ( !d_data->painter.hasClipping() ) + d_data->painter.setClipRect( canvasRect ); + } + + qwtRenderItem( &d_data->painter, canvasRect, seriesItem, from, to ); + + if ( d_data->attributes & QwtPlotDirectPainter::AtomicPainter ) + { + reset(); + } + else + { + if ( d_data->hasClipping ) + d_data->painter.setClipping( false ); + } + } + else + { + reset(); + + d_data->seriesItem = seriesItem; + d_data->from = from; + d_data->to = to; + + QRegion clipRegion = canvasRect; + if ( d_data->hasClipping ) + clipRegion &= d_data->clipRegion; + + canvas->installEventFilter( this ); + canvas->repaint(clipRegion); + canvas->removeEventFilter( this ); + + d_data->seriesItem = NULL; + } +} + +//! Close the internal QPainter +void QwtPlotDirectPainter::reset() +{ + if ( d_data->painter.isActive() ) + { + QWidget *w = static_cast( d_data->painter.device() ); + if ( w ) + w->removeEventFilter( this ); + + d_data->painter.end(); + } +} + +//! Event filter +bool QwtPlotDirectPainter::eventFilter( QObject *, QEvent *event ) +{ + if ( event->type() == QEvent::Paint ) + { + reset(); + + if ( d_data->seriesItem ) + { + const QPaintEvent *pe = static_cast< QPaintEvent *>( event ); + + QWidget *canvas = d_data->seriesItem->plot()->canvas(); + + QPainter painter( canvas ); + painter.setClipRegion( pe->region() ); + + bool doCopyCache = testAttribute( CopyBackingStore ); + + if ( doCopyCache ) + { + QwtPlotCanvas *plotCanvas = + qobject_cast( canvas ); + if ( plotCanvas ) + { + doCopyCache = qwtHasBackingStore( plotCanvas ); + if ( doCopyCache ) + { + painter.drawPixmap( plotCanvas->contentsRect().topLeft(), + *plotCanvas->backingStore() ); + } + } + } + + if ( !doCopyCache ) + { + qwtRenderItem( &painter, canvas->contentsRect(), + d_data->seriesItem, d_data->from, d_data->to ); + } + + return true; // don't call QwtPlotCanvas::paintEvent() + } + } + + return false; +} diff --git a/ThirdParty/Qwt/src/qwt_plot_directpainter.h b/ThirdParty/Qwt/src/qwt_plot_directpainter.h new file mode 100644 index 0000000000..b555c87c32 --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_plot_directpainter.h @@ -0,0 +1,100 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#ifndef QWT_PLOT_DIRECT_PAINTER_H +#define QWT_PLOT_DIRECT_PAINTER_H + +#include "qwt_global.h" +#include + +class QRegion; +class QwtPlotSeriesItem; + +/*! + \brief Painter object trying to paint incrementally + + Often applications want to display samples while they are + collected. When there are too many samples complete replots + will be expensive to be processed in a collection cycle. + + QwtPlotDirectPainter offers an API to paint + subsets ( f.e all additions points ) without erasing/repainting + the plot canvas. + + On certain environments it might be important to calculate a proper + clip region before painting. F.e. for Qt Embedded only the clipped part + of the backing store will be copied to a ( maybe unaccelerated ) + frame buffer. + + \warning Incremental painting will only help when no replot is triggered + by another operation ( like changing scales ) and nothing needs + to be erased. +*/ +class QWT_EXPORT QwtPlotDirectPainter: public QObject +{ +public: + /*! + \brief Paint attributes + \sa setAttribute(), testAttribute(), drawSeries() + */ + enum Attribute + { + /*! + Initializing a QPainter is an expensive operation. + When AtomicPainter is set each call of drawSeries() opens/closes + a temporary QPainter. Otherwise QwtPlotDirectPainter tries to + use the same QPainter as long as possible. + */ + AtomicPainter = 0x01, + + /*! + When FullRepaint is set the plot canvas is explicitly repainted + after the samples have been rendered. + */ + FullRepaint = 0x02, + + /*! + When QwtPlotCanvas::BackingStore is enabled the painter + has to paint to the backing store and the widget. In certain + situations/environments it might be faster to paint to + the backing store only and then copy the backing store to the canvas. + This flag can also be useful for settings, where Qt fills the + the clip region with the widget background. + */ + CopyBackingStore = 0x04 + }; + + //! Paint attributes + typedef QFlags Attributes; + + QwtPlotDirectPainter( QObject *parent = NULL ); + virtual ~QwtPlotDirectPainter(); + + void setAttribute( Attribute, bool on ); + bool testAttribute( Attribute ) const; + + void setClipping( bool ); + bool hasClipping() const; + + void setClipRegion( const QRegion & ); + QRegion clipRegion() const; + + void drawSeries( QwtPlotSeriesItem *, int from, int to ); + void reset(); + + virtual bool eventFilter( QObject *, QEvent * ); + +private: + class PrivateData; + PrivateData *d_data; +}; + +Q_DECLARE_OPERATORS_FOR_FLAGS( QwtPlotDirectPainter::Attributes ) + +#endif diff --git a/ThirdParty/Qwt/src/qwt_plot_glcanvas.cpp b/ThirdParty/Qwt/src/qwt_plot_glcanvas.cpp new file mode 100644 index 0000000000..87a4cfde71 --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_plot_glcanvas.cpp @@ -0,0 +1,357 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#include "qwt_plot_glcanvas.h" +#include "qwt_plot.h" +#include +#include +#include +#include +#include +#include "qwt_painter.h" + +static QWidget *qwtBGWidget( QWidget *widget ) +{ + QWidget *w = widget; + + for ( ; w->parentWidget() != NULL; w = w->parentWidget() ) + { + if ( w->autoFillBackground() || + w->testAttribute( Qt::WA_StyledBackground ) ) + { + return w; + } + } + + return w; +} + +static void qwtUpdateContentsRect( QwtPlotGLCanvas *canvas ) +{ + const int fw = canvas->frameWidth(); + canvas->setContentsMargins( fw, fw, fw, fw ); +} + +class QwtPlotGLCanvas::PrivateData +{ +public: + PrivateData(): + frameStyle( QFrame::Panel | QFrame::Sunken), + lineWidth( 2 ), + midLineWidth( 0 ) + { + } + + int frameStyle; + int lineWidth; + int midLineWidth; +}; + +/*! + \brief Constructor + + \param plot Parent plot widget + \sa QwtPlot::setCanvas() +*/ +QwtPlotGLCanvas::QwtPlotGLCanvas( QwtPlot *plot ): + QGLWidget( plot ) +{ + d_data = new PrivateData; + +#ifndef QT_NO_CURSOR + setCursor( Qt::CrossCursor ); +#endif + + setAutoFillBackground( true ); + qwtUpdateContentsRect( this ); +} + +//! Destructor +QwtPlotGLCanvas::~QwtPlotGLCanvas() +{ + delete d_data; +} + +/*! + Set the frame style + + \param style The bitwise OR between a shape and a shadow. + + \sa frameStyle(), QFrame::setFrameStyle(), + setFrameShadow(), setFrameShape() + */ +void QwtPlotGLCanvas::setFrameStyle( int style ) +{ + if ( style != d_data->frameStyle ) + { + d_data->frameStyle = style; + qwtUpdateContentsRect( this ); + + update(); + } +} + +/*! + \return The bitwise OR between a frameShape() and a frameShadow() + \sa setFrameStyle(), QFrame::frameStyle() + */ +int QwtPlotGLCanvas::frameStyle() const +{ + return d_data->frameStyle; +} + +/*! + Set the frame shadow + + \param shadow Frame shadow + \sa frameShadow(), setFrameShape(), QFrame::setFrameShadow() + */ +void QwtPlotGLCanvas::setFrameShadow( Shadow shadow ) +{ + setFrameStyle(( d_data->frameStyle & QFrame::Shape_Mask ) | shadow ); +} + +/*! + \return Frame shadow + \sa setFrameShadow(), QFrame::setFrameShadow() + */ +QwtPlotGLCanvas::Shadow QwtPlotGLCanvas::frameShadow() const +{ + return (Shadow) ( d_data->frameStyle & QFrame::Shadow_Mask ); +} + +/*! + Set the frame shape + + \param shape Frame shape + \sa frameShape(), setFrameShadow(), QFrame::frameShape() + */ +void QwtPlotGLCanvas::setFrameShape( Shape shape ) +{ + setFrameStyle( ( d_data->frameStyle & QFrame::Shadow_Mask ) | shape ); +} + +/*! + \return Frame shape + \sa setFrameShape(), QFrame::frameShape() + */ +QwtPlotGLCanvas::Shape QwtPlotGLCanvas::frameShape() const +{ + return (Shape) ( d_data->frameStyle & QFrame::Shape_Mask ); +} + +/*! + Set the frame line width + + The default line width is 2 pixels. + + \param width Line width of the frame + \sa lineWidth(), setMidLineWidth() +*/ +void QwtPlotGLCanvas::setLineWidth( int width ) +{ + width = qMax( width, 0 ); + if ( width != d_data->lineWidth ) + { + d_data->lineWidth = qMax( width, 0 ); + qwtUpdateContentsRect( this ); + update(); + } +} + +/*! + \return Line width of the frame + \sa setLineWidth(), midLineWidth() + */ +int QwtPlotGLCanvas::lineWidth() const +{ + return d_data->lineWidth; +} + +/*! + Set the frame mid line width + + The default midline width is 0 pixels. + + \param width Midline width of the frame + \sa midLineWidth(), setLineWidth() +*/ +void QwtPlotGLCanvas::setMidLineWidth( int width ) +{ + width = qMax( width, 0 ); + if ( width != d_data->midLineWidth ) + { + d_data->midLineWidth = width; + qwtUpdateContentsRect( this ); + update(); + } +} + +/*! + \return Midline width of the frame + \sa setMidLineWidth(), lineWidth() + */ +int QwtPlotGLCanvas::midLineWidth() const +{ + return d_data->midLineWidth; +} + +/*! + \return Frame width depending on the style, line width and midline width. + */ +int QwtPlotGLCanvas::frameWidth() const +{ + return ( frameStyle() != NoFrame ) ? d_data->lineWidth : 0; +} + +/*! + Paint event + + \param event Paint event + \sa QwtPlot::drawCanvas() +*/ +void QwtPlotGLCanvas::paintEvent( QPaintEvent *event ) +{ + Q_UNUSED( event ); + + QPainter painter( this ); + + drawBackground( &painter ); + drawItems( &painter ); + + if ( !testAttribute( Qt::WA_StyledBackground ) ) + { + if ( frameWidth() > 0 ) + drawBorder( &painter ); + } +} +/*! + Qt event handler for QEvent::PolishRequest and QEvent::StyleChange + \param event Qt Event + \return See QGLWidget::event() +*/ +bool QwtPlotGLCanvas::event( QEvent *event ) +{ + const bool ok = QGLWidget::event( event ); + + if ( event->type() == QEvent::PolishRequest || + event->type() == QEvent::StyleChange ) + { + // assuming, that we always have a styled background + // when we have a style sheet + + setAttribute( Qt::WA_StyledBackground, + testAttribute( Qt::WA_StyleSheet ) ); + } + + return ok; +} + +/*! + Draw the plot items + \param painter Painter + + \sa QwtPlot::drawCanvas() +*/ +void QwtPlotGLCanvas::drawItems( QPainter *painter ) +{ + painter->save(); + + painter->setClipRect( contentsRect(), Qt::IntersectClip ); + + QwtPlot *plot = qobject_cast< QwtPlot *>( parent() ); + if ( plot ) + plot->drawCanvas( painter ); + + painter->restore(); +} + +/*! + Draw the background of the canvas + \param painter Painter +*/ +void QwtPlotGLCanvas::drawBackground( QPainter *painter ) +{ + painter->save(); + + QWidget *w = qwtBGWidget( this ); + + const QPoint off = mapTo( w, QPoint() ); + painter->translate( -off ); + + const QRect fillRect = rect().translated( off ); + + if ( w->testAttribute( Qt::WA_StyledBackground ) ) + { + painter->setClipRect( fillRect ); + + QStyleOption opt; + opt.initFrom( w ); + w->style()->drawPrimitive( QStyle::PE_Widget, &opt, painter, w); + } + else + { + painter->fillRect( fillRect, + w->palette().brush( w->backgroundRole() ) ); + } + + painter->restore(); +} + +/*! + Draw the border of the canvas + \param painter Painter +*/ +void QwtPlotGLCanvas::drawBorder( QPainter *painter ) +{ + const int fw = frameWidth(); + if ( fw <= 0 ) + return; + + if ( frameShadow() == QwtPlotGLCanvas::Plain ) + { + qDrawPlainRect( painter, frameRect(), + palette().shadow().color(), lineWidth() ); + } + else + { + if ( frameShape() == QwtPlotGLCanvas::Box ) + { + qDrawShadeRect( painter, frameRect(), palette(), + frameShadow() == Sunken, lineWidth(), midLineWidth() ); + } + else + { + qDrawShadePanel( painter, frameRect(), palette(), + frameShadow() == Sunken, lineWidth() ); + } + } +} + +//! Calls repaint() +void QwtPlotGLCanvas::replot() +{ + repaint(); +} + +/*! + \return Empty path +*/ +QPainterPath QwtPlotGLCanvas::borderPath( const QRect &rect ) const +{ + Q_UNUSED( rect ); + return QPainterPath(); +} + +//! \return The rectangle where the frame is drawn in. +QRect QwtPlotGLCanvas::frameRect() const +{ + const int fw = frameWidth(); + return contentsRect().adjusted( -fw, -fw, fw, fw ); +} diff --git a/ThirdParty/Qwt/src/qwt_plot_glcanvas.h b/ThirdParty/Qwt/src/qwt_plot_glcanvas.h new file mode 100644 index 0000000000..2ff1cf2e31 --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_plot_glcanvas.h @@ -0,0 +1,136 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#ifndef QWT_PLOT_GLCANVAS_H +#define QWT_PLOT_GLCANVAS_H + +#include "qwt_global.h" +#include +#include + +class QwtPlot; + +/*! + \brief An alternative canvas for a QwtPlot derived from QGLWidget + + QwtPlotGLCanvas implements the very basics to act as canvas + inside of a QwtPlot widget. It might be extended to a full + featured alternative to QwtPlotCanvas in a future version of Qwt. + + Even if QwtPlotGLCanvas is not derived from QFrame it imitates + its API. When using style sheets it supports the box model - beside + backgrounds with rounded borders. + + \sa QwtPlot::setCanvas(), QwtPlotCanvas + + \note You might want to use the QPaintEngine::OpenGL paint engine + ( see QGL::setPreferredPaintEngine() ). On a Linux test system + QPaintEngine::OpenGL2 shows very basic problems ( wrong + geometries of rectangles ) but also more advanced stuff + like antialiasing doesn't work. + + \note Another way to introduce OpenGL rendering to Qwt + is to use QGLPixelBuffer or QGLFramebufferObject. Both + type of buffers can be converted into a QImage and + used in combination with a regular QwtPlotCanvas. +*/ +class QWT_EXPORT QwtPlotGLCanvas: public QGLWidget +{ + Q_OBJECT + + Q_ENUMS( Shape Shadow ) + + Q_PROPERTY( Shadow frameShadow READ frameShadow WRITE setFrameShadow ) + Q_PROPERTY( Shape frameShape READ frameShape WRITE setFrameShape ) + Q_PROPERTY( int lineWidth READ lineWidth WRITE setLineWidth ) + Q_PROPERTY( int midLineWidth READ midLineWidth WRITE setMidLineWidth ) + Q_PROPERTY( int frameWidth READ frameWidth ) + Q_PROPERTY( QRect frameRect READ frameRect DESIGNABLE false ) + +public: + /*! + \brief Frame shadow + + Unfortunately it is not possible to use QFrame::Shadow + as a property of a widget that is not derived from QFrame. + The following enum is made for the designer only. It is safe + to use QFrame::Shadow instead. + */ + enum Shadow + { + //! QFrame::Plain + Plain = QFrame::Plain, + + //! QFrame::Raised + Raised = QFrame::Raised, + + //! QFrame::Sunken + Sunken = QFrame::Sunken + }; + + /*! + \brief Frame shape + + Unfortunately it is not possible to use QFrame::Shape + as a property of a widget that is not derived from QFrame. + The following enum is made for the designer only. It is safe + to use QFrame::Shadow instead. + + \note QFrame::StyledPanel and QFrame::WinPanel are unsuported + and will be displayed as QFrame::Panel. + */ + enum Shape + { + NoFrame = QFrame::NoFrame, + + Box = QFrame::Box, + Panel = QFrame::Panel + }; + + explicit QwtPlotGLCanvas( QwtPlot * = NULL ); + virtual ~QwtPlotGLCanvas(); + + void setFrameStyle( int style ); + int frameStyle() const; + + void setFrameShadow( Shadow ); + Shadow frameShadow() const; + + void setFrameShape( Shape ); + Shape frameShape() const; + + void setLineWidth( int ); + int lineWidth() const; + + void setMidLineWidth( int ); + int midLineWidth() const; + + int frameWidth() const; + QRect frameRect() const; + + Q_INVOKABLE QPainterPath borderPath( const QRect & ) const; + + virtual bool event( QEvent * ); + +public Q_SLOTS: + void replot(); + +protected: + virtual void paintEvent( QPaintEvent * ); + + virtual void drawBackground( QPainter * ); + virtual void drawBorder( QPainter * ); + virtual void drawItems( QPainter * ); + +private: + class PrivateData; + PrivateData *d_data; +}; + +#endif diff --git a/ThirdParty/Qwt/src/qwt_plot_grid.cpp b/ThirdParty/Qwt/src/qwt_plot_grid.cpp new file mode 100644 index 0000000000..4375e53d7d --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_plot_grid.cpp @@ -0,0 +1,438 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#include "qwt_plot_grid.h" +#include "qwt_painter.h" +#include "qwt_text.h" +#include "qwt_scale_map.h" +#include "qwt_scale_div.h" +#include "qwt_math.h" +#include +#include + +class QwtPlotGrid::PrivateData +{ +public: + PrivateData(): + xEnabled( true ), + yEnabled( true ), + xMinEnabled( false ), + yMinEnabled( false ) + { + } + + bool xEnabled; + bool yEnabled; + bool xMinEnabled; + bool yMinEnabled; + + QwtScaleDiv xScaleDiv; + QwtScaleDiv yScaleDiv; + + QPen majorPen; + QPen minorPen; +}; + +//! Enables major grid, disables minor grid +QwtPlotGrid::QwtPlotGrid(): + QwtPlotItem( QwtText( "Grid" ) ) +{ + d_data = new PrivateData; + + setItemInterest( QwtPlotItem::ScaleInterest, true ); + setZ( 10.0 ); +} + +//! Destructor +QwtPlotGrid::~QwtPlotGrid() +{ + delete d_data; +} + +//! \return QwtPlotItem::Rtti_PlotGrid +int QwtPlotGrid::rtti() const +{ + return QwtPlotItem::Rtti_PlotGrid; +} + +/*! + \brief Enable or disable vertical grid lines + \param on Enable (true) or disable + + \sa Minor grid lines can be enabled or disabled with + enableXMin() +*/ +void QwtPlotGrid::enableX( bool on ) +{ + if ( d_data->xEnabled != on ) + { + d_data->xEnabled = on; + + legendChanged(); + itemChanged(); + } +} + +/*! + \brief Enable or disable horizontal grid lines + \param on Enable (true) or disable + \sa Minor grid lines can be enabled or disabled with enableYMin() +*/ +void QwtPlotGrid::enableY( bool on ) +{ + if ( d_data->yEnabled != on ) + { + d_data->yEnabled = on; + + legendChanged(); + itemChanged(); + } +} + +/*! + \brief Enable or disable minor vertical grid lines. + \param on Enable (true) or disable + \sa enableX() +*/ +void QwtPlotGrid::enableXMin( bool on ) +{ + if ( d_data->xMinEnabled != on ) + { + d_data->xMinEnabled = on; + + legendChanged(); + itemChanged(); + } +} + +/*! + \brief Enable or disable minor horizontal grid lines + \param on Enable (true) or disable + \sa enableY() +*/ +void QwtPlotGrid::enableYMin( bool on ) +{ + if ( d_data->yMinEnabled != on ) + { + d_data->yMinEnabled = on; + + legendChanged(); + itemChanged(); + } +} + +/*! + Assign an x axis scale division + + \param scaleDiv Scale division +*/ +void QwtPlotGrid::setXDiv( const QwtScaleDiv &scaleDiv ) +{ + if ( d_data->xScaleDiv != scaleDiv ) + { + d_data->xScaleDiv = scaleDiv; + itemChanged(); + } +} + +/*! + Assign a y axis division + + \param scaleDiv Scale division +*/ +void QwtPlotGrid::setYDiv( const QwtScaleDiv &scaleDiv ) +{ + if ( d_data->yScaleDiv != scaleDiv ) + { + d_data->yScaleDiv = scaleDiv; + itemChanged(); + } +} + +/*! + Build and assign a pen for both major and minor grid lines + + In Qt5 the default pen width is 1.0 ( 0.0 in Qt4 ) what makes it + non cosmetic ( see QPen::isCosmetic() ). This method has been introduced + to hide this incompatibility. + + \param color Pen color + \param width Pen width + \param style Pen style + + \sa pen(), brush() + */ +void QwtPlotGrid::setPen( const QColor &color, qreal width, Qt::PenStyle style ) +{ + setPen( QPen( color, width, style ) ); +} + +/*! + Assign a pen for both major and minor grid lines + + \param pen Pen + \sa setMajorPen(), setMinorPen() +*/ +void QwtPlotGrid::setPen( const QPen &pen ) +{ + if ( d_data->majorPen != pen || d_data->minorPen != pen ) + { + d_data->majorPen = pen; + d_data->minorPen = pen; + + legendChanged(); + itemChanged(); + } +} + +/*! + Build and assign a pen for both major grid lines + + In Qt5 the default pen width is 1.0 ( 0.0 in Qt4 ) what makes it + non cosmetic ( see QPen::isCosmetic() ). This method has been introduced + to hide this incompatibility. + + \param color Pen color + \param width Pen width + \param style Pen style + + \sa pen(), brush() + */ +void QwtPlotGrid::setMajorPen( const QColor &color, qreal width, Qt::PenStyle style ) +{ + setMajorPen( QPen( color, width, style ) ); +} + +/*! + Assign a pen for the major grid lines + + \param pen Pen + \sa majorPen(), setMinorPen(), setPen() +*/ +void QwtPlotGrid::setMajorPen( const QPen &pen ) +{ + if ( d_data->majorPen != pen ) + { + d_data->majorPen = pen; + + legendChanged(); + itemChanged(); + } +} + +/*! + Build and assign a pen for the minor grid lines + + In Qt5 the default pen width is 1.0 ( 0.0 in Qt4 ) what makes it + non cosmetic ( see QPen::isCosmetic() ). This method has been introduced + to hide this incompatibility. + + \param color Pen color + \param width Pen width + \param style Pen style + + \sa pen(), brush() + */ +void QwtPlotGrid::setMinorPen( const QColor &color, qreal width, Qt::PenStyle style ) +{ + setMinorPen( QPen( color, width, style ) ); +} + +/*! + Assign a pen for the minor grid lines + + \param pen Pen + \sa minorPen(), setMajorPen(), setPen() +*/ +void QwtPlotGrid::setMinorPen( const QPen &pen ) +{ + if ( d_data->minorPen != pen ) + { + d_data->minorPen = pen; + + legendChanged(); + itemChanged(); + } +} + +/*! + \brief Draw the grid + + The grid is drawn into the bounding rectangle such that + grid lines begin and end at the rectangle's borders. The X and Y + maps are used to map the scale divisions into the drawing region + screen. + + \param painter Painter + \param xMap X axis map + \param yMap Y axis + \param canvasRect Contents rectangle of the plot canvas +*/ +void QwtPlotGrid::draw( QPainter *painter, + const QwtScaleMap &xMap, const QwtScaleMap &yMap, + const QRectF &canvasRect ) const +{ + // draw minor grid lines + QPen minorPen = d_data->minorPen; + minorPen.setCapStyle( Qt::FlatCap ); + + painter->setPen( minorPen ); + + if ( d_data->xEnabled && d_data->xMinEnabled ) + { + drawLines( painter, canvasRect, Qt::Vertical, xMap, + d_data->xScaleDiv.ticks( QwtScaleDiv::MinorTick ) ); + drawLines( painter, canvasRect, Qt::Vertical, xMap, + d_data->xScaleDiv.ticks( QwtScaleDiv::MediumTick ) ); + } + + if ( d_data->yEnabled && d_data->yMinEnabled ) + { + drawLines( painter, canvasRect, Qt::Horizontal, yMap, + d_data->yScaleDiv.ticks( QwtScaleDiv::MinorTick ) ); + drawLines( painter, canvasRect, Qt::Horizontal, yMap, + d_data->yScaleDiv.ticks( QwtScaleDiv::MediumTick ) ); + } + + // draw major grid lines + QPen majorPen = d_data->majorPen; + majorPen.setCapStyle( Qt::FlatCap ); + + painter->setPen( majorPen ); + + if ( d_data->xEnabled ) + { + drawLines( painter, canvasRect, Qt::Vertical, xMap, + d_data->xScaleDiv.ticks( QwtScaleDiv::MajorTick ) ); + } + + if ( d_data->yEnabled ) + { + drawLines( painter, canvasRect, Qt::Horizontal, yMap, + d_data->yScaleDiv.ticks( QwtScaleDiv::MajorTick ) ); + } +} + +void QwtPlotGrid::drawLines( QPainter *painter, const QRectF &canvasRect, + Qt::Orientation orientation, const QwtScaleMap &scaleMap, + const QList &values ) const +{ + const double x1 = canvasRect.left(); + const double x2 = canvasRect.right() - 1.0; + const double y1 = canvasRect.top(); + const double y2 = canvasRect.bottom() - 1.0; + + const bool doAlign = QwtPainter::roundingAlignment( painter ); + + for ( int i = 0; i < values.count(); i++ ) + { + double value = scaleMap.transform( values[i] ); + if ( doAlign ) + value = qRound( value ); + + if ( orientation == Qt::Horizontal ) + { + if ( qwtFuzzyGreaterOrEqual( value, y1 ) && + qwtFuzzyLessOrEqual( value, y2 ) ) + { + QwtPainter::drawLine( painter, x1, value, x2, value ); + } + } + else + { + if ( qwtFuzzyGreaterOrEqual( value, x1 ) && + qwtFuzzyLessOrEqual( value, x2 ) ) + { + QwtPainter::drawLine( painter, value, y1, value, y2 ); + } + } + } +} + +/*! + \return the pen for the major grid lines + \sa setMajorPen(), setMinorPen(), setPen() +*/ +const QPen &QwtPlotGrid::majorPen() const +{ + return d_data->majorPen; +} + +/*! + \return the pen for the minor grid lines + \sa setMinorPen(), setMajorPen(), setPen() +*/ +const QPen &QwtPlotGrid::minorPen() const +{ + return d_data->minorPen; +} + +/*! + \return true if vertical grid lines are enabled + \sa enableX() +*/ +bool QwtPlotGrid::xEnabled() const +{ + return d_data->xEnabled; +} + +/*! + \return true if minor vertical grid lines are enabled + \sa enableXMin() +*/ +bool QwtPlotGrid::xMinEnabled() const +{ + return d_data->xMinEnabled; +} + +/*! + \return true if horizontal grid lines are enabled + \sa enableY() +*/ +bool QwtPlotGrid::yEnabled() const +{ + return d_data->yEnabled; +} + +/*! + \return true if minor horizontal grid lines are enabled + \sa enableYMin() +*/ +bool QwtPlotGrid::yMinEnabled() const +{ + return d_data->yMinEnabled; +} + + +/*! \return the scale division of the x axis */ +const QwtScaleDiv &QwtPlotGrid::xScaleDiv() const +{ + return d_data->xScaleDiv; +} + +/*! \return the scale division of the y axis */ +const QwtScaleDiv &QwtPlotGrid::yScaleDiv() const +{ + return d_data->yScaleDiv; +} + +/*! + Update the grid to changes of the axes scale division + + \param xScaleDiv Scale division of the x-axis + \param yScaleDiv Scale division of the y-axis + + \sa QwtPlot::updateAxes() +*/ +void QwtPlotGrid::updateScaleDiv( const QwtScaleDiv& xScaleDiv, + const QwtScaleDiv& yScaleDiv ) +{ + setXDiv( xScaleDiv ); + setYDiv( yScaleDiv ); +} diff --git a/ThirdParty/Qwt/src/qwt_plot_grid.h b/ThirdParty/Qwt/src/qwt_plot_grid.h new file mode 100644 index 0000000000..16d984c721 --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_plot_grid.h @@ -0,0 +1,87 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#ifndef QWT_PLOT_GRID_H +#define QWT_PLOT_GRID_H + +#include "qwt_global.h" +#include "qwt_plot_item.h" +#include "qwt_scale_div.h" + +class QPainter; +class QPen; +class QwtScaleMap; +class QwtScaleDiv; + +/*! + \brief A class which draws a coordinate grid + + The QwtPlotGrid class can be used to draw a coordinate grid. + A coordinate grid consists of major and minor vertical + and horizontal grid lines. The locations of the grid lines + are determined by the X and Y scale divisions which can + be assigned with setXDiv() and setYDiv(). + The draw() member draws the grid within a bounding + rectangle. +*/ + +class QWT_EXPORT QwtPlotGrid: public QwtPlotItem +{ +public: + explicit QwtPlotGrid(); + virtual ~QwtPlotGrid(); + + virtual int rtti() const; + + void enableX( bool tf ); + bool xEnabled() const; + + void enableY( bool tf ); + bool yEnabled() const; + + void enableXMin( bool tf ); + bool xMinEnabled() const; + + void enableYMin( bool tf ); + bool yMinEnabled() const; + + void setXDiv( const QwtScaleDiv &sx ); + const QwtScaleDiv &xScaleDiv() const; + + void setYDiv( const QwtScaleDiv &sy ); + const QwtScaleDiv &yScaleDiv() const; + + void setPen( const QColor &, qreal width = 0.0, Qt::PenStyle = Qt::SolidLine ); + void setPen( const QPen & ); + + void setMajorPen( const QColor &, qreal width = 0.0, Qt::PenStyle = Qt::SolidLine ); + void setMajorPen( const QPen & ); + const QPen& majorPen() const; + + void setMinorPen( const QColor &, qreal width = 0.0, Qt::PenStyle = Qt::SolidLine ); + void setMinorPen( const QPen &p ); + const QPen& minorPen() const; + + virtual void draw( QPainter *p, + const QwtScaleMap &xMap, const QwtScaleMap &yMap, + const QRectF &rect ) const; + + virtual void updateScaleDiv( + const QwtScaleDiv &xMap, const QwtScaleDiv &yMap ); + +private: + void drawLines( QPainter *painter, const QRectF &, + Qt::Orientation orientation, const QwtScaleMap &, + const QList & ) const; + + class PrivateData; + PrivateData *d_data; +}; + +#endif diff --git a/ThirdParty/Qwt/src/qwt_plot_histogram.cpp b/ThirdParty/Qwt/src/qwt_plot_histogram.cpp new file mode 100644 index 0000000000..4464f03ff4 --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_plot_histogram.cpp @@ -0,0 +1,690 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#include "qwt_plot_histogram.h" +#include "qwt_plot.h" +#include "qwt_painter.h" +#include "qwt_column_symbol.h" +#include "qwt_scale_map.h" +#include +#include + +static inline bool qwtIsCombinable( const QwtInterval &d1, + const QwtInterval &d2 ) +{ + if ( d1.isValid() && d2.isValid() ) + { + if ( d1.maxValue() == d2.minValue() ) + { + if ( !( d1.borderFlags() & QwtInterval::ExcludeMaximum + && d2.borderFlags() & QwtInterval::ExcludeMinimum ) ) + { + return true; + } + } + } + + return false; +} + +class QwtPlotHistogram::PrivateData +{ +public: + PrivateData(): + baseline( 0.0 ), + style( Columns ), + symbol( NULL ) + { + } + + ~PrivateData() + { + delete symbol; + } + + double baseline; + + QPen pen; + QBrush brush; + QwtPlotHistogram::HistogramStyle style; + const QwtColumnSymbol *symbol; +}; + +/*! + Constructor + \param title Title of the histogram. +*/ +QwtPlotHistogram::QwtPlotHistogram( const QwtText &title ): + QwtPlotSeriesItem( title ) +{ + init(); +} + +/*! + Constructor + \param title Title of the histogram. +*/ +QwtPlotHistogram::QwtPlotHistogram( const QString &title ): + QwtPlotSeriesItem( title ) +{ + init(); +} + +//! Destructor +QwtPlotHistogram::~QwtPlotHistogram() +{ + delete d_data; +} + +//! Initialize data members +void QwtPlotHistogram::init() +{ + d_data = new PrivateData(); + setData( new QwtIntervalSeriesData() ); + + setItemAttribute( QwtPlotItem::AutoScale, true ); + setItemAttribute( QwtPlotItem::Legend, true ); + + setZ( 20.0 ); +} + +/*! + Set the histogram's drawing style + + \param style Histogram style + \sa HistogramStyle, style() +*/ +void QwtPlotHistogram::setStyle( HistogramStyle style ) +{ + if ( style != d_data->style ) + { + d_data->style = style; + + legendChanged(); + itemChanged(); + } +} + +/*! + \return Style of the histogram + \sa HistogramStyle, setStyle() +*/ +QwtPlotHistogram::HistogramStyle QwtPlotHistogram::style() const +{ + return d_data->style; +} + +/*! + Build and assign a pen + + In Qt5 the default pen width is 1.0 ( 0.0 in Qt4 ) what makes it + non cosmetic ( see QPen::isCosmetic() ). This method has been introduced + to hide this incompatibility. + + \param color Pen color + \param width Pen width + \param style Pen style + + \sa pen(), brush() + */ +void QwtPlotHistogram::setPen( const QColor &color, qreal width, Qt::PenStyle style ) +{ + setPen( QPen( color, width, style ) ); +} + +/*! + Assign a pen, that is used in a style() depending way. + + \param pen New pen + \sa pen(), brush() +*/ +void QwtPlotHistogram::setPen( const QPen &pen ) +{ + if ( pen != d_data->pen ) + { + d_data->pen = pen; + + legendChanged(); + itemChanged(); + } +} + +/*! + \return Pen used in a style() depending way. + \sa setPen(), brush() +*/ +const QPen &QwtPlotHistogram::pen() const +{ + return d_data->pen; +} + +/*! + Assign a brush, that is used in a style() depending way. + + \param brush New brush + \sa pen(), brush() +*/ +void QwtPlotHistogram::setBrush( const QBrush &brush ) +{ + if ( brush != d_data->brush ) + { + d_data->brush = brush; + + legendChanged(); + itemChanged(); + } +} + +/*! + \return Brush used in a style() depending way. + \sa setPen(), brush() +*/ +const QBrush &QwtPlotHistogram::brush() const +{ + return d_data->brush; +} + +/*! + \brief Assign a symbol + + In Column style an optional symbol can be assigned, that is responsible + for displaying the rectangle that is defined by the interval and + the distance between baseline() and value. When no symbol has been + defined the area is displayed as plain rectangle using pen() and brush(). + + \sa style(), symbol(), drawColumn(), pen(), brush() + + \note In applications, where different intervals need to be displayed + in a different way ( f.e different colors or even using different symbols) + it is recommended to overload drawColumn(). +*/ +void QwtPlotHistogram::setSymbol( const QwtColumnSymbol *symbol ) +{ + if ( symbol != d_data->symbol ) + { + delete d_data->symbol; + d_data->symbol = symbol; + + legendChanged(); + itemChanged(); + } +} + +/*! + \return Current symbol or NULL, when no symbol has been assigned + \sa setSymbol() +*/ +const QwtColumnSymbol *QwtPlotHistogram::symbol() const +{ + return d_data->symbol; +} + +/*! + \brief Set the value of the baseline + + Each column representing an QwtIntervalSample is defined by its + interval and the interval between baseline and the value of the sample. + + The default value of the baseline is 0.0. + + \param value Value of the baseline + \sa baseline() +*/ +void QwtPlotHistogram::setBaseline( double value ) +{ + if ( d_data->baseline != value ) + { + d_data->baseline = value; + itemChanged(); + } +} + +/*! + \return Value of the baseline + \sa setBaseline() +*/ +double QwtPlotHistogram::baseline() const +{ + return d_data->baseline; +} + +/*! + \return Bounding rectangle of all samples. + For an empty series the rectangle is invalid. +*/ +QRectF QwtPlotHistogram::boundingRect() const +{ + QRectF rect = data()->boundingRect(); + if ( !rect.isValid() ) + return rect; + + if ( orientation() == Qt::Horizontal ) + { + rect = QRectF( rect.y(), rect.x(), + rect.height(), rect.width() ); + + if ( rect.left() > d_data->baseline ) + rect.setLeft( d_data->baseline ); + else if ( rect.right() < d_data->baseline ) + rect.setRight( d_data->baseline ); + } + else + { + if ( rect.bottom() < d_data->baseline ) + rect.setBottom( d_data->baseline ); + else if ( rect.top() > d_data->baseline ) + rect.setTop( d_data->baseline ); + } + + return rect; +} + +//! \return QwtPlotItem::Rtti_PlotHistogram +int QwtPlotHistogram::rtti() const +{ + return QwtPlotItem::Rtti_PlotHistogram; +} + +/*! + Initialize data with an array of samples. + \param samples Vector of points +*/ +void QwtPlotHistogram::setSamples( + const QVector &samples ) +{ + setData( new QwtIntervalSeriesData( samples ) ); +} + +/*! + Assign a series of samples + + setSamples() is just a wrapper for setData() without any additional + value - beside that it is easier to find for the developer. + + \param data Data + \warning The item takes ownership of the data object, deleting + it when its not used anymore. +*/ +void QwtPlotHistogram::setSamples( + QwtSeriesData *data ) +{ + setData( data ); +} + +/*! + Draw a subset of the histogram samples + + \param painter Painter + \param xMap Maps x-values into pixel coordinates. + \param yMap Maps y-values into pixel coordinates. + \param canvasRect Contents rectangle of the canvas + \param from Index of the first sample to be painted + \param to Index of the last sample to be painted. If to < 0 the + series will be painted to its last sample. + + \sa drawOutline(), drawLines(), drawColumns +*/ +void QwtPlotHistogram::drawSeries( QPainter *painter, + const QwtScaleMap &xMap, const QwtScaleMap &yMap, + const QRectF &, int from, int to ) const +{ + if ( !painter || dataSize() <= 0 ) + return; + + if ( to < 0 ) + to = dataSize() - 1; + + switch ( d_data->style ) + { + case Outline: + drawOutline( painter, xMap, yMap, from, to ); + break; + case Lines: + drawLines( painter, xMap, yMap, from, to ); + break; + case Columns: + drawColumns( painter, xMap, yMap, from, to ); + break; + default: + break; + } +} + +/*! + Draw a histogram in Outline style() + + \param painter Painter + \param xMap Maps x-values into pixel coordinates. + \param yMap Maps y-values into pixel coordinates. + \param from Index of the first sample to be painted + \param to Index of the last sample to be painted. If to < 0 the + histogram will be painted to its last point. + + \sa setStyle(), style() + \warning The outline style requires, that the intervals are in increasing + order and not overlapping. +*/ +void QwtPlotHistogram::drawOutline( QPainter *painter, + const QwtScaleMap &xMap, const QwtScaleMap &yMap, + int from, int to ) const +{ + const bool doAlign = QwtPainter::roundingAlignment( painter ); + + double v0 = ( orientation() == Qt::Horizontal ) ? + xMap.transform( baseline() ) : yMap.transform( baseline() ); + if ( doAlign ) + v0 = qRound( v0 ); + + QwtIntervalSample previous; + + QPolygonF polygon; + for ( int i = from; i <= to; i++ ) + { + const QwtIntervalSample sample = this->sample( i ); + + if ( !sample.interval.isValid() ) + { + flushPolygon( painter, v0, polygon ); + previous = sample; + continue; + } + + if ( previous.interval.isValid() ) + { + if ( !qwtIsCombinable( previous.interval, sample.interval ) ) + flushPolygon( painter, v0, polygon ); + } + + if ( orientation() == Qt::Vertical ) + { + double x1 = xMap.transform( sample.interval.minValue() ); + double x2 = xMap.transform( sample.interval.maxValue() ); + double y = yMap.transform( sample.value ); + if ( doAlign ) + { + x1 = qRound( x1 ); + x2 = qRound( x2 ); + y = qRound( y ); + } + + if ( polygon.size() == 0 ) + polygon += QPointF( x1, v0 ); + + polygon += QPointF( x1, y ); + polygon += QPointF( x2, y ); + } + else + { + double y1 = yMap.transform( sample.interval.minValue() ); + double y2 = yMap.transform( sample.interval.maxValue() ); + double x = xMap.transform( sample.value ); + if ( doAlign ) + { + y1 = qRound( y1 ); + y2 = qRound( y2 ); + x = qRound( x ); + } + + if ( polygon.size() == 0 ) + polygon += QPointF( v0, y1 ); + + polygon += QPointF( x, y1 ); + polygon += QPointF( x, y2 ); + } + previous = sample; + } + + flushPolygon( painter, v0, polygon ); +} + +/*! + Draw a histogram in Columns style() + + \param painter Painter + \param xMap Maps x-values into pixel coordinates. + \param yMap Maps y-values into pixel coordinates. + \param from Index of the first sample to be painted + \param to Index of the last sample to be painted. If to < 0 the + histogram will be painted to its last point. + + \sa setStyle(), style(), setSymbol(), drawColumn() +*/ +void QwtPlotHistogram::drawColumns( QPainter *painter, + const QwtScaleMap &xMap, const QwtScaleMap &yMap, + int from, int to ) const +{ + painter->setPen( d_data->pen ); + painter->setBrush( d_data->brush ); + + const QwtSeriesData *series = data(); + + for ( int i = from; i <= to; i++ ) + { + const QwtIntervalSample sample = series->sample( i ); + if ( !sample.interval.isNull() ) + { + const QwtColumnRect rect = columnRect( sample, xMap, yMap ); + drawColumn( painter, rect, sample ); + } + } +} + +/*! + Draw a histogram in Lines style() + + \param painter Painter + \param xMap Maps x-values into pixel coordinates. + \param yMap Maps y-values into pixel coordinates. + \param from Index of the first sample to be painted + \param to Index of the last sample to be painted. If to < 0 the + histogram will be painted to its last point. + + \sa setStyle(), style(), setPen() +*/ +void QwtPlotHistogram::drawLines( QPainter *painter, + const QwtScaleMap &xMap, const QwtScaleMap &yMap, + int from, int to ) const +{ + const bool doAlign = QwtPainter::roundingAlignment( painter ); + + painter->setPen( d_data->pen ); + painter->setBrush( Qt::NoBrush ); + + const QwtSeriesData *series = data(); + + for ( int i = from; i <= to; i++ ) + { + const QwtIntervalSample sample = series->sample( i ); + if ( !sample.interval.isNull() ) + { + const QwtColumnRect rect = columnRect( sample, xMap, yMap ); + + QRectF r = rect.toRect(); + if ( doAlign ) + { + r.setLeft( qRound( r.left() ) ); + r.setRight( qRound( r.right() ) ); + r.setTop( qRound( r.top() ) ); + r.setBottom( qRound( r.bottom() ) ); + } + + switch ( rect.direction ) + { + case QwtColumnRect::LeftToRight: + { + QwtPainter::drawLine( painter, + r.topRight(), r.bottomRight() ); + break; + } + case QwtColumnRect::RightToLeft: + { + QwtPainter::drawLine( painter, + r.topLeft(), r.bottomLeft() ); + break; + } + case QwtColumnRect::TopToBottom: + { + QwtPainter::drawLine( painter, + r.bottomRight(), r.bottomLeft() ); + break; + } + case QwtColumnRect::BottomToTop: + { + QwtPainter::drawLine( painter, + r.topRight(), r.topLeft() ); + break; + } + } + } + } +} + +//! Internal, used by the Outline style. +void QwtPlotHistogram::flushPolygon( QPainter *painter, + double baseLine, QPolygonF &polygon ) const +{ + if ( polygon.size() == 0 ) + return; + + if ( orientation() == Qt::Horizontal ) + polygon += QPointF( baseLine, polygon.last().y() ); + else + polygon += QPointF( polygon.last().x(), baseLine ); + + if ( d_data->brush.style() != Qt::NoBrush ) + { + painter->setPen( Qt::NoPen ); + painter->setBrush( d_data->brush ); + + if ( orientation() == Qt::Horizontal ) + { + polygon += QPointF( polygon.last().x(), baseLine ); + polygon += QPointF( polygon.first().x(), baseLine ); + } + else + { + polygon += QPointF( baseLine, polygon.last().y() ); + polygon += QPointF( baseLine, polygon.first().y() ); + } + + QwtPainter::drawPolygon( painter, polygon ); + + polygon.pop_back(); + polygon.pop_back(); + } + if ( d_data->pen.style() != Qt::NoPen ) + { + painter->setBrush( Qt::NoBrush ); + painter->setPen( d_data->pen ); + QwtPainter::drawPolyline( painter, polygon ); + } + polygon.clear(); +} + +/*! + Calculate the area that is covered by a sample + + \param sample Sample + \param xMap Maps x-values into pixel coordinates. + \param yMap Maps y-values into pixel coordinates. + + \return Rectangle, that is covered by a sample +*/ +QwtColumnRect QwtPlotHistogram::columnRect( const QwtIntervalSample &sample, + const QwtScaleMap &xMap, const QwtScaleMap &yMap ) const +{ + QwtColumnRect rect; + + const QwtInterval &iv = sample.interval; + if ( !iv.isValid() ) + return rect; + + if ( orientation() == Qt::Horizontal ) + { + const double x0 = xMap.transform( baseline() ); + const double x = xMap.transform( sample.value ); + const double y1 = yMap.transform( iv.minValue() ); + const double y2 = yMap.transform( iv.maxValue() ); + + rect.hInterval.setInterval( x0, x ); + rect.vInterval.setInterval( y1, y2, iv.borderFlags() ); + rect.direction = ( x < x0 ) ? QwtColumnRect::RightToLeft : + QwtColumnRect::LeftToRight; + } + else + { + const double x1 = xMap.transform( iv.minValue() ); + const double x2 = xMap.transform( iv.maxValue() ); + const double y0 = yMap.transform( baseline() ); + const double y = yMap.transform( sample.value ); + + rect.hInterval.setInterval( x1, x2, iv.borderFlags() ); + rect.vInterval.setInterval( y0, y ); + rect.direction = ( y < y0 ) ? QwtColumnRect::BottomToTop : + QwtColumnRect::TopToBottom; + } + + return rect; +} + +/*! + Draw a column for a sample in Columns style(). + + When a symbol() has been set the symbol is used otherwise the + column is displayed as plain rectangle using pen() and brush(). + + \param painter Painter + \param rect Rectangle where to paint the column in paint device coordinates + \param sample Sample to be displayed + + \note In applications, where different intervals need to be displayed + in a different way ( f.e different colors or even using different symbols) + it is recommended to overload drawColumn(). +*/ +void QwtPlotHistogram::drawColumn( QPainter *painter, + const QwtColumnRect &rect, const QwtIntervalSample &sample ) const +{ + Q_UNUSED( sample ); + + if ( d_data->symbol && + ( d_data->symbol->style() != QwtColumnSymbol::NoStyle ) ) + { + d_data->symbol->draw( painter, rect ); + } + else + { + QRectF r = rect.toRect(); + if ( QwtPainter::roundingAlignment( painter ) ) + { + r.setLeft( qRound( r.left() ) ); + r.setRight( qRound( r.right() ) ); + r.setTop( qRound( r.top() ) ); + r.setBottom( qRound( r.bottom() ) ); + } + + QwtPainter::drawRect( painter, r ); + } +} + +/*! + A plain rectangle without pen using the brush() + + \param index Index of the legend entry + ( ignored as there is only one ) + \param size Icon size + \return A graphic displaying the icon + + \sa QwtPlotItem::setLegendIconSize(), QwtPlotItem::legendData() +*/ +QwtGraphic QwtPlotHistogram::legendIcon( int index, + const QSizeF &size ) const +{ + Q_UNUSED( index ); + return defaultIcon( d_data->brush, size ); +} diff --git a/ThirdParty/Qwt/src/qwt_plot_histogram.h b/ThirdParty/Qwt/src/qwt_plot_histogram.h new file mode 100644 index 0000000000..b96bdddc00 --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_plot_histogram.h @@ -0,0 +1,139 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#ifndef QWT_PLOT_HISTOGRAM_H +#define QWT_PLOT_HISTOGRAM_H + +#include "qwt_global.h" +#include "qwt_plot_seriesitem.h" +#include "qwt_column_symbol.h" +#include +#include + +class QwtIntervalData; +class QString; +class QPolygonF; + +/*! + \brief QwtPlotHistogram represents a series of samples, where an interval + is associated with a value ( \f$y = f([x1,x2])\f$ ). + + The representation depends on the style() and an optional symbol() + that is displayed for each interval. + + \note The term "histogram" is used in a different way in the areas of + digital image processing and statistics. Wikipedia introduces the + terms "image histogram" and "color histogram" to avoid confusions. + While "image histograms" can be displayed by a QwtPlotCurve there + is no applicable plot item for a "color histogram" yet. + + \sa QwtPlotBarChart, QwtPlotMultiBarChart +*/ + +class QWT_EXPORT QwtPlotHistogram: + public QwtPlotSeriesItem, public QwtSeriesStore +{ +public: + /*! + Histogram styles. + The default style is QwtPlotHistogram::Columns. + + \sa setStyle(), style(), setSymbol(), symbol(), setBaseline() + */ + enum HistogramStyle + { + /*! + Draw an outline around the area, that is build by all intervals + using the pen() and fill it with the brush(). The outline style + requires, that the intervals are in increasing order and + not overlapping. + */ + Outline, + + /*! + Draw a column for each interval. When a symbol() has been set + the symbol is used otherwise the column is displayed as + plain rectangle using pen() and brush(). + */ + Columns, + + /*! + Draw a simple line using the pen() for each interval. + */ + Lines, + + /*! + Styles >= UserStyle are reserved for derived + classes that overload drawSeries() with + additional application specific ways to display a histogram. + */ + UserStyle = 100 + }; + + explicit QwtPlotHistogram( const QString &title = QString::null ); + explicit QwtPlotHistogram( const QwtText &title ); + virtual ~QwtPlotHistogram(); + + virtual int rtti() const; + + void setPen( const QColor &, qreal width = 0.0, Qt::PenStyle = Qt::SolidLine ); + void setPen( const QPen & ); + const QPen &pen() const; + + void setBrush( const QBrush & ); + const QBrush &brush() const; + + void setSamples( const QVector & ); + void setSamples( QwtSeriesData * ); + + void setBaseline( double reference ); + double baseline() const; + + void setStyle( HistogramStyle style ); + HistogramStyle style() const; + + void setSymbol( const QwtColumnSymbol * ); + const QwtColumnSymbol *symbol() const; + + virtual void drawSeries( QPainter *p, + const QwtScaleMap &xMap, const QwtScaleMap &yMap, + const QRectF &canvasRect, int from, int to ) const; + + virtual QRectF boundingRect() const; + + virtual QwtGraphic legendIcon( int index, const QSizeF & ) const; + +protected: + virtual QwtColumnRect columnRect( const QwtIntervalSample &, + const QwtScaleMap &, const QwtScaleMap & ) const; + + virtual void drawColumn( QPainter *, const QwtColumnRect &, + const QwtIntervalSample & ) const; + + void drawColumns( QPainter *, + const QwtScaleMap &xMap, const QwtScaleMap &yMap, + int from, int to ) const; + + void drawOutline( QPainter *, + const QwtScaleMap &xMap, const QwtScaleMap &yMap, + int from, int to ) const; + + void drawLines( QPainter *, + const QwtScaleMap &xMap, const QwtScaleMap &yMap, + int from, int to ) const; + +private: + void init(); + void flushPolygon( QPainter *, double baseLine, QPolygonF & ) const; + + class PrivateData; + PrivateData *d_data; +}; + +#endif diff --git a/ThirdParty/Qwt/src/qwt_plot_intervalcurve.cpp b/ThirdParty/Qwt/src/qwt_plot_intervalcurve.cpp new file mode 100644 index 0000000000..200ea39b51 --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_plot_intervalcurve.cpp @@ -0,0 +1,603 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#include "qwt_plot_intervalcurve.h" +#include "qwt_interval_symbol.h" +#include "qwt_scale_map.h" +#include "qwt_clipper.h" +#include "qwt_painter.h" +#include + +#include + +static inline bool qwtIsHSampleInside( const QwtIntervalSample &sample, + double xMin, double xMax, double yMin, double yMax ) +{ + const double y = sample.value; + const double x1 = sample.interval.minValue(); + const double x2 = sample.interval.maxValue(); + + const bool isOffScreen = ( y < yMin ) || ( y > yMax ) + || ( x1 < xMin && x2 < xMin ) || ( x1 > xMax && x2 > xMax ); + + return !isOffScreen; +} + +static inline bool qwtIsVSampleInside( const QwtIntervalSample &sample, + double xMin, double xMax, double yMin, double yMax ) +{ + const double x = sample.value; + const double y1 = sample.interval.minValue(); + const double y2 = sample.interval.maxValue(); + + const bool isOffScreen = ( x < xMin ) || ( x > xMax ) + || ( y1 < yMin && y2 < yMin ) || ( y1 > yMax && y2 > yMax ); + + return !isOffScreen; +} + +class QwtPlotIntervalCurve::PrivateData +{ +public: + PrivateData(): + style( QwtPlotIntervalCurve::Tube ), + symbol( NULL ), + pen( Qt::black ), + brush( Qt::white ) + { + paintAttributes = QwtPlotIntervalCurve::ClipPolygons; + paintAttributes |= QwtPlotIntervalCurve::ClipSymbol; + + pen.setCapStyle( Qt::FlatCap ); + } + + ~PrivateData() + { + delete symbol; + } + + QwtPlotIntervalCurve::CurveStyle style; + const QwtIntervalSymbol *symbol; + + QPen pen; + QBrush brush; + + QwtPlotIntervalCurve::PaintAttributes paintAttributes; +}; + +/*! + Constructor + \param title Title of the curve +*/ +QwtPlotIntervalCurve::QwtPlotIntervalCurve( const QwtText &title ): + QwtPlotSeriesItem( title ) +{ + init(); +} + +/*! + Constructor + \param title Title of the curve +*/ +QwtPlotIntervalCurve::QwtPlotIntervalCurve( const QString &title ): + QwtPlotSeriesItem( QwtText( title ) ) +{ + init(); +} + +//! Destructor +QwtPlotIntervalCurve::~QwtPlotIntervalCurve() +{ + delete d_data; +} + +//! Initialize internal members +void QwtPlotIntervalCurve::init() +{ + setItemAttribute( QwtPlotItem::Legend, true ); + setItemAttribute( QwtPlotItem::AutoScale, true ); + + d_data = new PrivateData; + setData( new QwtIntervalSeriesData() ); + + setZ( 19.0 ); +} + +//! \return QwtPlotItem::Rtti_PlotIntervalCurve +int QwtPlotIntervalCurve::rtti() const +{ + return QwtPlotIntervalCurve::Rtti_PlotIntervalCurve; +} + +/*! + Specify an attribute how to draw the curve + + \param attribute Paint attribute + \param on On/Off + \sa testPaintAttribute() +*/ +void QwtPlotIntervalCurve::setPaintAttribute( + PaintAttribute attribute, bool on ) +{ + if ( on ) + d_data->paintAttributes |= attribute; + else + d_data->paintAttributes &= ~attribute; +} + +/*! + \return True, when attribute is enabled + \sa PaintAttribute, setPaintAttribute() +*/ +bool QwtPlotIntervalCurve::testPaintAttribute( + PaintAttribute attribute ) const +{ + return ( d_data->paintAttributes & attribute ); +} + +/*! + Initialize data with an array of samples. + \param samples Vector of samples +*/ +void QwtPlotIntervalCurve::setSamples( + const QVector &samples ) +{ + setData( new QwtIntervalSeriesData( samples ) ); +} + +/*! + Assign a series of samples + + setSamples() is just a wrapper for setData() without any additional + value - beside that it is easier to find for the developer. + + \param data Data + \warning The item takes ownership of the data object, deleting + it when its not used anymore. +*/ +void QwtPlotIntervalCurve::setSamples( + QwtSeriesData *data ) +{ + setData( data ); +} + +/*! + Set the curve's drawing style + + \param style Curve style + \sa CurveStyle, style() +*/ +void QwtPlotIntervalCurve::setStyle( CurveStyle style ) +{ + if ( style != d_data->style ) + { + d_data->style = style; + + legendChanged(); + itemChanged(); + } +} + +/*! + \return Style of the curve + \sa setStyle() +*/ +QwtPlotIntervalCurve::CurveStyle QwtPlotIntervalCurve::style() const +{ + return d_data->style; +} + +/*! + Assign a symbol. + + \param symbol Symbol + \sa symbol() +*/ +void QwtPlotIntervalCurve::setSymbol( const QwtIntervalSymbol *symbol ) +{ + if ( symbol != d_data->symbol ) + { + delete d_data->symbol; + d_data->symbol = symbol; + + legendChanged(); + itemChanged(); + } +} + +/*! + \return Current symbol or NULL, when no symbol has been assigned + \sa setSymbol() +*/ +const QwtIntervalSymbol *QwtPlotIntervalCurve::symbol() const +{ + return d_data->symbol; +} + +/*! + Build and assign a pen + + In Qt5 the default pen width is 1.0 ( 0.0 in Qt4 ) what makes it + non cosmetic ( see QPen::isCosmetic() ). This method has been introduced + to hide this incompatibility. + + \param color Pen color + \param width Pen width + \param style Pen style + + \sa pen(), brush() + */ +void QwtPlotIntervalCurve::setPen( const QColor &color, qreal width, Qt::PenStyle style ) +{ + setPen( QPen( color, width, style ) ); +} + +/*! + \brief Assign a pen + \param pen New pen + \sa pen(), brush() +*/ +void QwtPlotIntervalCurve::setPen( const QPen &pen ) +{ + if ( pen != d_data->pen ) + { + d_data->pen = pen; + + legendChanged(); + itemChanged(); + } +} + +/*! + \return Pen used to draw the lines + \sa setPen(), brush() +*/ +const QPen& QwtPlotIntervalCurve::pen() const +{ + return d_data->pen; +} + +/*! + Assign a brush. + + The brush is used to fill the area in Tube style(). + + \param brush Brush + \sa brush(), pen(), setStyle(), CurveStyle +*/ +void QwtPlotIntervalCurve::setBrush( const QBrush &brush ) +{ + if ( brush != d_data->brush ) + { + d_data->brush = brush; + + legendChanged(); + itemChanged(); + } +} + +/*! + \return Brush used to fill the area in Tube style() + \sa setBrush(), setStyle(), CurveStyle +*/ +const QBrush& QwtPlotIntervalCurve::brush() const +{ + return d_data->brush; +} + +/*! + \return Bounding rectangle of all samples. + For an empty series the rectangle is invalid. +*/ +QRectF QwtPlotIntervalCurve::boundingRect() const +{ + QRectF rect = QwtPlotSeriesItem::boundingRect(); + if ( rect.isValid() && orientation() == Qt::Vertical ) + rect.setRect( rect.y(), rect.x(), rect.height(), rect.width() ); + + return rect; +} + +/*! + Draw a subset of the samples + + \param painter Painter + \param xMap Maps x-values into pixel coordinates. + \param yMap Maps y-values into pixel coordinates. + \param canvasRect Contents rectangle of the canvas + \param from Index of the first sample to be painted + \param to Index of the last sample to be painted. If to < 0 the + series will be painted to its last sample. + + \sa drawTube(), drawSymbols() +*/ +void QwtPlotIntervalCurve::drawSeries( QPainter *painter, + const QwtScaleMap &xMap, const QwtScaleMap &yMap, + const QRectF &canvasRect, int from, int to ) const +{ + if ( to < 0 ) + to = dataSize() - 1; + + if ( from < 0 ) + from = 0; + + if ( from > to ) + return; + + switch ( d_data->style ) + { + case Tube: + drawTube( painter, xMap, yMap, canvasRect, from, to ); + break; + + case NoCurve: + default: + break; + } + + if ( d_data->symbol && + ( d_data->symbol->style() != QwtIntervalSymbol::NoSymbol ) ) + { + drawSymbols( painter, *d_data->symbol, + xMap, yMap, canvasRect, from, to ); + } +} + +/*! + Draw a tube + + Builds 2 curves from the upper and lower limits of the intervals + and draws them with the pen(). The area between the curves is + filled with the brush(). + + \param painter Painter + \param xMap Maps x-values into pixel coordinates. + \param yMap Maps y-values into pixel coordinates. + \param canvasRect Contents rectangle of the canvas + \param from Index of the first sample to be painted + \param to Index of the last sample to be painted. If to < 0 the + series will be painted to its last sample. + + \sa drawSeries(), drawSymbols() +*/ +void QwtPlotIntervalCurve::drawTube( QPainter *painter, + const QwtScaleMap &xMap, const QwtScaleMap &yMap, + const QRectF &canvasRect, int from, int to ) const +{ + const bool doAlign = QwtPainter::roundingAlignment( painter ); + + painter->save(); + + const size_t size = to - from + 1; + QPolygonF polygon( 2 * size ); + QPointF *points = polygon.data(); + + for ( uint i = 0; i < size; i++ ) + { + QPointF &minValue = points[i]; + QPointF &maxValue = points[2 * size - 1 - i]; + + const QwtIntervalSample intervalSample = sample( from + i ); + if ( orientation() == Qt::Vertical ) + { + double x = xMap.transform( intervalSample.value ); + double y1 = yMap.transform( intervalSample.interval.minValue() ); + double y2 = yMap.transform( intervalSample.interval.maxValue() ); + if ( doAlign ) + { + x = qRound( x ); + y1 = qRound( y1 ); + y2 = qRound( y2 ); + } + + minValue.rx() = x; + minValue.ry() = y1; + maxValue.rx() = x; + maxValue.ry() = y2; + } + else + { + double y = yMap.transform( intervalSample.value ); + double x1 = xMap.transform( intervalSample.interval.minValue() ); + double x2 = xMap.transform( intervalSample.interval.maxValue() ); + if ( doAlign ) + { + y = qRound( y ); + x1 = qRound( x1 ); + x2 = qRound( x2 ); + } + + minValue.rx() = x1; + minValue.ry() = y; + maxValue.rx() = x2; + maxValue.ry() = y; + } + } + + if ( d_data->brush.style() != Qt::NoBrush ) + { + painter->setPen( QPen( Qt::NoPen ) ); + painter->setBrush( d_data->brush ); + + if ( d_data->paintAttributes & ClipPolygons ) + { + const qreal m = 1.0; + const QPolygonF p = QwtClipper::clipPolygonF( + canvasRect.adjusted( -m, -m, m, m ), polygon, true ); + + QwtPainter::drawPolygon( painter, p ); + } + else + { + QwtPainter::drawPolygon( painter, polygon ); + } + } + + if ( d_data->pen.style() != Qt::NoPen ) + { + painter->setPen( d_data->pen ); + painter->setBrush( Qt::NoBrush ); + + if ( d_data->paintAttributes & ClipPolygons ) + { + qreal pw = qMax( qreal( 1.0 ), painter->pen().widthF() ); + const QRectF clipRect = canvasRect.adjusted( -pw, -pw, pw, pw ); + + QPolygonF p; + + p.resize( size ); + ::memcpy( p.data(), points, size * sizeof( QPointF ) ); + p = QwtClipper::clipPolygonF( clipRect, p ); + QwtPainter::drawPolyline( painter, p ); + + p.resize( size ); + ::memcpy( p.data(), points + size, size * sizeof( QPointF ) ); + p = QwtClipper::clipPolygonF( clipRect, p ); + QwtPainter::drawPolyline( painter, p ); + } + else + { + QwtPainter::drawPolyline( painter, points, size ); + QwtPainter::drawPolyline( painter, points + size, size ); + } + } + + painter->restore(); +} + +/*! + Draw symbols for a subset of the samples + + \param painter Painter + \param symbol Interval symbol + \param xMap x map + \param yMap y map + \param canvasRect Contents rectangle of the canvas + \param from Index of the first sample to be painted + \param to Index of the last sample to be painted + + \sa setSymbol(), drawSeries(), drawTube() +*/ +void QwtPlotIntervalCurve::drawSymbols( + QPainter *painter, const QwtIntervalSymbol &symbol, + const QwtScaleMap &xMap, const QwtScaleMap &yMap, + const QRectF &canvasRect, int from, int to ) const +{ + painter->save(); + + QPen pen = symbol.pen(); + pen.setCapStyle( Qt::FlatCap ); + + painter->setPen( pen ); + painter->setBrush( symbol.brush() ); + + const QRectF tr = QwtScaleMap::invTransform( xMap, yMap, canvasRect ); + + const double xMin = tr.left(); + const double xMax = tr.right(); + const double yMin = tr.top(); + const double yMax = tr.bottom(); + + const bool doClip = d_data->paintAttributes & ClipSymbol; + + for ( int i = from; i <= to; i++ ) + { + const QwtIntervalSample s = sample( i ); + + if ( orientation() == Qt::Vertical ) + { + if ( !doClip || qwtIsVSampleInside( s, xMin, xMax, yMin, yMax ) ) + { + const double x = xMap.transform( s.value ); + const double y1 = yMap.transform( s.interval.minValue() ); + const double y2 = yMap.transform( s.interval.maxValue() ); + + symbol.draw( painter, orientation(), + QPointF( x, y1 ), QPointF( x, y2 ) ); + } + } + else + { + if ( !doClip || qwtIsHSampleInside( s, xMin, xMax, yMin, yMax ) ) + { + const double y = yMap.transform( s.value ); + const double x1 = xMap.transform( s.interval.minValue() ); + const double x2 = xMap.transform( s.interval.maxValue() ); + + symbol.draw( painter, orientation(), + QPointF( x1, y ), QPointF( x2, y ) ); + } + } + } + + painter->restore(); +} + +/*! + \return Icon for the legend + + In case of Tube style() the icon is a plain rectangle filled with the brush(). + If a symbol is assigned it is scaled to size. + + \param index Index of the legend entry + ( ignored as there is only one ) + \param size Icon size + + \sa QwtPlotItem::setLegendIconSize(), QwtPlotItem::legendData() +*/ +QwtGraphic QwtPlotIntervalCurve::legendIcon( + int index, const QSizeF &size ) const +{ + Q_UNUSED( index ); + + if ( size.isEmpty() ) + return QwtGraphic(); + + QwtGraphic icon; + icon.setDefaultSize( size ); + icon.setRenderHint( QwtGraphic::RenderPensUnscaled, true ); + + QPainter painter( &icon ); + painter.setRenderHint( QPainter::Antialiasing, + testRenderHint( QwtPlotItem::RenderAntialiased ) ); + + if ( d_data->style == Tube ) + { + QRectF r( 0, 0, size.width(), size.height() ); + painter.fillRect( r, d_data->brush ); + } + + if ( d_data->symbol && + ( d_data->symbol->style() != QwtIntervalSymbol::NoSymbol ) ) + { + QPen pen = d_data->symbol->pen(); + pen.setWidthF( pen.widthF() ); + pen.setCapStyle( Qt::FlatCap ); + + painter.setPen( pen ); + painter.setBrush( d_data->symbol->brush() ); + + if ( orientation() == Qt::Vertical ) + { + const double x = 0.5 * size.width(); + + d_data->symbol->draw( &painter, orientation(), + QPointF( x, 0 ), QPointF( x, size.height() - 1.0 ) ); + } + else + { + const double y = 0.5 * size.height(); + + d_data->symbol->draw( &painter, orientation(), + QPointF( 0.0, y ), QPointF( size.width() - 1.0, y ) ); + } + } + + return icon; +} diff --git a/ThirdParty/Qwt/src/qwt_plot_intervalcurve.h b/ThirdParty/Qwt/src/qwt_plot_intervalcurve.h new file mode 100644 index 0000000000..624d82f1b0 --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_plot_intervalcurve.h @@ -0,0 +1,132 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#ifndef QWT_PLOT_INTERVAL_CURVE_H +#define QWT_PLOT_INTERVAL_CURVE_H + +#include "qwt_global.h" +#include "qwt_plot_seriesitem.h" +#include "qwt_series_data.h" + +class QwtIntervalSymbol; + +/*! + \brief QwtPlotIntervalCurve represents a series of samples, where each value + is associated with an interval ( \f$[y1,y2] = f(x)\f$ ). + + The representation depends on the style() and an optional symbol() + that is displayed for each interval. QwtPlotIntervalCurve might be used + to display error bars or the area between 2 curves. +*/ +class QWT_EXPORT QwtPlotIntervalCurve: + public QwtPlotSeriesItem, public QwtSeriesStore +{ +public: + /*! + \brief Curve styles. + The default setting is QwtPlotIntervalCurve::Tube. + + \sa setStyle(), style() + */ + enum CurveStyle + { + /*! + Don't draw a curve. Note: This doesn't affect the symbols. + */ + NoCurve, + + /*! + Build 2 curves from the upper and lower limits of the intervals + and draw them with the pen(). The area between the curves is + filled with the brush(). + */ + Tube, + + /*! + Styles >= QwtPlotIntervalCurve::UserCurve are reserved for derived + classes that overload drawSeries() with + additional application specific curve types. + */ + UserCurve = 100 + }; + + /*! + Attributes to modify the drawing algorithm. + \sa setPaintAttribute(), testPaintAttribute() + */ + enum PaintAttribute + { + /*! + Clip polygons before painting them. In situations, where points + are far outside the visible area (f.e when zooming deep) this + might be a substantial improvement for the painting performance. + */ + ClipPolygons = 0x01, + + //! Check if a symbol is on the plot canvas before painting it. + ClipSymbol = 0x02 + }; + + //! Paint attributes + typedef QFlags PaintAttributes; + + explicit QwtPlotIntervalCurve( const QString &title = QString::null ); + explicit QwtPlotIntervalCurve( const QwtText &title ); + + virtual ~QwtPlotIntervalCurve(); + + virtual int rtti() const; + + void setPaintAttribute( PaintAttribute, bool on = true ); + bool testPaintAttribute( PaintAttribute ) const; + + void setSamples( const QVector & ); + void setSamples( QwtSeriesData * ); + + void setPen( const QColor &, qreal width = 0.0, Qt::PenStyle = Qt::SolidLine ); + void setPen( const QPen & ); + const QPen &pen() const; + + void setBrush( const QBrush & ); + const QBrush &brush() const; + + void setStyle( CurveStyle style ); + CurveStyle style() const; + + void setSymbol( const QwtIntervalSymbol * ); + const QwtIntervalSymbol *symbol() const; + + virtual void drawSeries( QPainter *p, + const QwtScaleMap &xMap, const QwtScaleMap &yMap, + const QRectF &canvasRect, int from, int to ) const; + + virtual QRectF boundingRect() const; + + virtual QwtGraphic legendIcon( int index, const QSizeF & ) const; + +protected: + + void init(); + + virtual void drawTube( QPainter *, + const QwtScaleMap &xMap, const QwtScaleMap &yMap, + const QRectF &canvasRect, int from, int to ) const; + + virtual void drawSymbols( QPainter *, const QwtIntervalSymbol &, + const QwtScaleMap &xMap, const QwtScaleMap &yMap, + const QRectF &canvasRect, int from, int to ) const; + +private: + class PrivateData; + PrivateData *d_data; +}; + +Q_DECLARE_OPERATORS_FOR_FLAGS( QwtPlotIntervalCurve::PaintAttributes ) + +#endif diff --git a/ThirdParty/Qwt/src/qwt_plot_item.cpp b/ThirdParty/Qwt/src/qwt_plot_item.cpp new file mode 100644 index 0000000000..4cb03bbb2e --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_plot_item.cpp @@ -0,0 +1,698 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#include "qwt_plot_item.h" +#include "qwt_text.h" +#include "qwt_plot.h" +#include "qwt_legend_data.h" +#include "qwt_scale_div.h" +#include "qwt_graphic.h" +#include + +class QwtPlotItem::PrivateData +{ +public: + PrivateData(): + plot( NULL ), + isVisible( true ), + attributes( 0 ), + interests( 0 ), + renderHints( 0 ), + renderThreadCount( 1 ), + z( 0.0 ), + xAxis( QwtPlot::xBottom ), + yAxis( QwtPlot::yLeft ), + legendIconSize( 8, 8 ) + { + } + + mutable QwtPlot *plot; + + bool isVisible; + + QwtPlotItem::ItemAttributes attributes; + QwtPlotItem::ItemInterests interests; + + QwtPlotItem::RenderHints renderHints; + uint renderThreadCount; + + double z; + + int xAxis; + int yAxis; + + QwtText title; + QSize legendIconSize; +}; + +/*! + Constructor + \param title Title of the item +*/ +QwtPlotItem::QwtPlotItem( const QwtText &title ) +{ + d_data = new PrivateData; + d_data->title = title; +} + +//! Destroy the QwtPlotItem +QwtPlotItem::~QwtPlotItem() +{ + attach( NULL ); + delete d_data; +} + +/*! + \brief Attach the item to a plot. + + This method will attach a QwtPlotItem to the QwtPlot argument. It will first + detach the QwtPlotItem from any plot from a previous call to attach (if + necessary). If a NULL argument is passed, it will detach from any QwtPlot it + was attached to. + + \param plot Plot widget + \sa detach() +*/ +void QwtPlotItem::attach( QwtPlot *plot ) +{ + if ( plot == d_data->plot ) + return; + + if ( d_data->plot ) + d_data->plot->attachItem( this, false ); + + d_data->plot = plot; + + if ( d_data->plot ) + d_data->plot->attachItem( this, true ); +} + +/*! + \brief This method detaches a QwtPlotItem from any + QwtPlot it has been associated with. + + detach() is equivalent to calling attach( NULL ) + \sa attach() +*/ +void QwtPlotItem::detach() +{ + attach( NULL ); +} + +/*! + Return rtti for the specific class represented. QwtPlotItem is simply + a virtual interface class, and base classes will implement this method + with specific rtti values so a user can differentiate them. + + The rtti value is useful for environments, where the + runtime type information is disabled and it is not possible + to do a dynamic_cast<...>. + + \return rtti value + \sa RttiValues +*/ +int QwtPlotItem::rtti() const +{ + return Rtti_PlotItem; +} + +//! Return attached plot +QwtPlot *QwtPlotItem::plot() const +{ + return d_data->plot; +} + +/*! + Plot items are painted in increasing z-order. + + \return setZ(), QwtPlotDict::itemList() +*/ +double QwtPlotItem::z() const +{ + return d_data->z; +} + +/*! + \brief Set the z value + + Plot items are painted in increasing z-order. + + \param z Z-value + \sa z(), QwtPlotDict::itemList() +*/ +void QwtPlotItem::setZ( double z ) +{ + if ( d_data->z != z ) + { + if ( d_data->plot ) // update the z order + d_data->plot->attachItem( this, false ); + + d_data->z = z; + + if ( d_data->plot ) + d_data->plot->attachItem( this, true ); + + itemChanged(); + } +} + +/*! + Set a new title + + \param title Title + \sa title() +*/ +void QwtPlotItem::setTitle( const QString &title ) +{ + setTitle( QwtText( title ) ); +} + +/*! + Set a new title + + \param title Title + \sa title() +*/ +void QwtPlotItem::setTitle( const QwtText &title ) +{ + if ( d_data->title != title ) + { + d_data->title = title; + + legendChanged(); +#if 0 + itemChanged(); +#endif + } +} + +/*! + \return Title of the item + \sa setTitle() +*/ +const QwtText &QwtPlotItem::title() const +{ + return d_data->title; +} + +/*! + Toggle an item attribute + + \param attribute Attribute type + \param on true/false + + \sa testItemAttribute(), ItemInterest +*/ +void QwtPlotItem::setItemAttribute( ItemAttribute attribute, bool on ) +{ + if ( d_data->attributes.testFlag( attribute ) != on ) + { + if ( on ) + d_data->attributes |= attribute; + else + d_data->attributes &= ~attribute; + + if ( attribute == QwtPlotItem::Legend ) + legendChanged(); + + itemChanged(); + } +} + +/*! + Test an item attribute + + \param attribute Attribute type + \return true/false + \sa setItemAttribute(), ItemInterest +*/ +bool QwtPlotItem::testItemAttribute( ItemAttribute attribute ) const +{ + return d_data->attributes.testFlag( attribute ); +} + +/*! + Toggle an item interest + + \param interest Interest type + \param on true/false + + \sa testItemInterest(), ItemAttribute +*/ +void QwtPlotItem::setItemInterest( ItemInterest interest, bool on ) +{ + if ( d_data->interests.testFlag( interest ) != on ) + { + if ( on ) + d_data->interests |= interest; + else + d_data->interests &= ~interest; + + itemChanged(); + } +} + +/*! + Test an item interest + + \param interest Interest type + \return true/false + \sa setItemInterest(), ItemAttribute +*/ +bool QwtPlotItem::testItemInterest( ItemInterest interest ) const +{ + return d_data->interests.testFlag( interest ); +} + +/*! + Toggle an render hint + + \param hint Render hint + \param on true/false + + \sa testRenderHint(), RenderHint +*/ +void QwtPlotItem::setRenderHint( RenderHint hint, bool on ) +{ + if ( d_data->renderHints.testFlag( hint ) != on ) + { + if ( on ) + d_data->renderHints |= hint; + else + d_data->renderHints &= ~hint; + + itemChanged(); + } +} + +/*! + Test a render hint + + \param hint Render hint + \return true/false + \sa setRenderHint(), RenderHint +*/ +bool QwtPlotItem::testRenderHint( RenderHint hint ) const +{ + return d_data->renderHints.testFlag( hint ); +} + +/*! + On multi core systems rendering of certain plot item + ( f.e QwtPlotRasterItem ) can be done in parallel in + several threads. + + The default setting is set to 1. + + \param numThreads Number of threads to be used for rendering. + If numThreads is set to 0, the system specific + ideal thread count is used. + + The default thread count is 1 ( = no additional threads ) +*/ +void QwtPlotItem::setRenderThreadCount( uint numThreads ) +{ + d_data->renderThreadCount = numThreads; +} + +/*! + \return Number of threads to be used for rendering. + If numThreads() is set to 0, the system specific + ideal thread count is used. +*/ +uint QwtPlotItem::renderThreadCount() const +{ + return d_data->renderThreadCount; +} + +/*! + Set the size of the legend icon + + The default setting is 8x8 pixels + + \param size Size + \sa legendIconSize(), legendIcon() +*/ +void QwtPlotItem::setLegendIconSize( const QSize &size ) +{ + if ( d_data->legendIconSize != size ) + { + d_data->legendIconSize = size; + legendChanged(); + } +} + +/*! + \return Legend icon size + \sa setLegendIconSize(), legendIcon() +*/ +QSize QwtPlotItem::legendIconSize() const +{ + return d_data->legendIconSize; +} + +/*! + \return Icon representing the item on the legend + + The default implementation returns an invalid icon + + \param index Index of the legend entry + ( usually there is only one ) + \param size Icon size + + \sa setLegendIconSize(), legendData() + */ +QwtGraphic QwtPlotItem::legendIcon( + int index, const QSizeF &size ) const +{ + Q_UNUSED( index ) + Q_UNUSED( size ) + + return QwtGraphic(); +} + +/*! + \brief Return a default icon from a brush + + The default icon is a filled rectangle used + in several derived classes as legendIcon(). + + \param brush Fill brush + \param size Icon size + + \return A filled rectangle + */ +QwtGraphic QwtPlotItem::defaultIcon( + const QBrush &brush, const QSizeF &size ) const +{ + QwtGraphic icon; + if ( !size.isEmpty() ) + { + icon.setDefaultSize( size ); + + QRectF r( 0, 0, size.width(), size.height() ); + + QPainter painter( &icon ); + painter.fillRect( r, brush ); + } + + return icon; +} + +//! Show the item +void QwtPlotItem::show() +{ + setVisible( true ); +} + +//! Hide the item +void QwtPlotItem::hide() +{ + setVisible( false ); +} + +/*! + Show/Hide the item + + \param on Show if true, otherwise hide + \sa isVisible(), show(), hide() +*/ +void QwtPlotItem::setVisible( bool on ) +{ + if ( on != d_data->isVisible ) + { + d_data->isVisible = on; + itemChanged(); + } +} + +/*! + \return true if visible + \sa setVisible(), show(), hide() +*/ +bool QwtPlotItem::isVisible() const +{ + return d_data->isVisible; +} + +/*! + Update the legend and call QwtPlot::autoRefresh() for the + parent plot. + + \sa QwtPlot::legendChanged(), QwtPlot::autoRefresh() +*/ +void QwtPlotItem::itemChanged() +{ + if ( d_data->plot ) + d_data->plot->autoRefresh(); +} + +/*! + Update the legend of the parent plot. + \sa QwtPlot::updateLegend(), itemChanged() +*/ +void QwtPlotItem::legendChanged() +{ + if ( testItemAttribute( QwtPlotItem::Legend ) && d_data->plot ) + d_data->plot->updateLegend( this ); +} + +/*! + Set X and Y axis + + The item will painted according to the coordinates of its Axes. + + \param xAxis X Axis ( QwtPlot::xBottom or QwtPlot::xTop ) + \param yAxis Y Axis ( QwtPlot::yLeft or QwtPlot::yRight ) + + \sa setXAxis(), setYAxis(), xAxis(), yAxis(), QwtPlot::Axis +*/ +void QwtPlotItem::setAxes( int xAxis, int yAxis ) +{ + if ( xAxis == QwtPlot::xBottom || xAxis == QwtPlot::xTop ) + d_data->xAxis = xAxis; + + if ( yAxis == QwtPlot::yLeft || yAxis == QwtPlot::yRight ) + d_data->yAxis = yAxis; + + itemChanged(); +} + +/*! + Set the X axis + + The item will painted according to the coordinates its Axes. + + \param axis X Axis ( QwtPlot::xBottom or QwtPlot::xTop ) + \sa setAxes(), setYAxis(), xAxis(), QwtPlot::Axis +*/ +void QwtPlotItem::setXAxis( int axis ) +{ + if ( axis == QwtPlot::xBottom || axis == QwtPlot::xTop ) + { + d_data->xAxis = axis; + itemChanged(); + } +} + +/*! + Set the Y axis + + The item will painted according to the coordinates its Axes. + + \param axis Y Axis ( QwtPlot::yLeft or QwtPlot::yRight ) + \sa setAxes(), setXAxis(), yAxis(), QwtPlot::Axis +*/ +void QwtPlotItem::setYAxis( int axis ) +{ + if ( axis == QwtPlot::yLeft || axis == QwtPlot::yRight ) + { + d_data->yAxis = axis; + itemChanged(); + } +} + +//! Return xAxis +int QwtPlotItem::xAxis() const +{ + return d_data->xAxis; +} + +//! Return yAxis +int QwtPlotItem::yAxis() const +{ + return d_data->yAxis; +} + +/*! + \return An invalid bounding rect: QRectF(1.0, 1.0, -2.0, -2.0) + \note A width or height < 0.0 is ignored by the autoscaler +*/ +QRectF QwtPlotItem::boundingRect() const +{ + return QRectF( 1.0, 1.0, -2.0, -2.0 ); // invalid +} + +/*! + \brief Calculate a hint for the canvas margin + + When the QwtPlotItem::Margins flag is enabled the plot item + indicates, that it needs some margins at the borders of the canvas. + This is f.e. used by bar charts to reserve space for displaying + the bars. + + The margins are in target device coordinates ( pixels on screen ) + + \param xMap Maps x-values into pixel coordinates. + \param yMap Maps y-values into pixel coordinates. + \param canvasRect Contents rectangle of the canvas in painter coordinates + \param left Returns the left margin + \param top Returns the top margin + \param right Returns the right margin + \param bottom Returns the bottom margin + + \return The default implementation returns 0 for all margins + + \sa QwtPlot::getCanvasMarginsHint(), QwtPlot::updateCanvasMargins() + */ +void QwtPlotItem::getCanvasMarginHint( const QwtScaleMap &xMap, + const QwtScaleMap &yMap, const QRectF &canvasRect, + double &left, double &top, double &right, double &bottom ) const +{ + Q_UNUSED( xMap ); + Q_UNUSED( yMap ); + Q_UNUSED( canvasRect ); + + // use QMargins, when we don't need to support Qt < 4.6 anymore + left = top = right = bottom = 0.0; +} + +/*! + \brief Return all information, that is needed to represent + the item on the legend + + Most items are represented by one entry on the legend + showing an icon and a text, but f.e. QwtPlotMultiBarChart + displays one entry for each bar. + + QwtLegendData is basically a list of QVariants that makes it + possible to overload and reimplement legendData() to + return almost any type of information, that is understood + by the receiver that acts as the legend. + + The default implementation returns one entry with + the title() of the item and the legendIcon(). + + \return Data, that is needed to represent the item on the legend + \sa title(), legendIcon(), QwtLegend, QwtPlotLegendItem + */ +QList QwtPlotItem::legendData() const +{ + QwtLegendData data; + + QwtText label = title(); + label.setRenderFlags( label.renderFlags() & Qt::AlignLeft ); + + QVariant titleValue; + qVariantSetValue( titleValue, label ); + data.setValue( QwtLegendData::TitleRole, titleValue ); + + const QwtGraphic graphic = legendIcon( 0, legendIconSize() ); + if ( !graphic.isNull() ) + { + QVariant iconValue; + qVariantSetValue( iconValue, graphic ); + data.setValue( QwtLegendData::IconRole, iconValue ); + } + + QList list; + list += data; + + return list; +} + +/*! + \brief Update the item to changes of the axes scale division + + Update the item, when the axes of plot have changed. + The default implementation does nothing, but items that depend + on the scale division (like QwtPlotGrid()) have to reimplement + updateScaleDiv() + + updateScaleDiv() is only called when the ScaleInterest interest + is enabled. The default implementation does nothing. + + \param xScaleDiv Scale division of the x-axis + \param yScaleDiv Scale division of the y-axis + + \sa QwtPlot::updateAxes(), ScaleInterest +*/ +void QwtPlotItem::updateScaleDiv( const QwtScaleDiv &xScaleDiv, + const QwtScaleDiv &yScaleDiv ) +{ + Q_UNUSED( xScaleDiv ); + Q_UNUSED( yScaleDiv ); +} + +/*! + \brief Update the item to changes of the legend info + + Plot items that want to display a legend ( not those, that want to + be displayed on a legend ! ) will have to implement updateLegend(). + + updateLegend() is only called when the LegendInterest interest + is enabled. The default implementation does nothing. + + \param item Plot item to be displayed on a legend + \param data Attributes how to display item on the legend + + \sa QwtPlotLegendItem + + \note Plot items, that want to be displayed on a legend + need to enable the QwtPlotItem::Legend flag and to implement + legendData() and legendIcon() + */ +void QwtPlotItem::updateLegend( const QwtPlotItem *item, + const QList &data ) +{ + Q_UNUSED( item ); + Q_UNUSED( data ); +} + +/*! + \brief Calculate the bounding scale rectangle of 2 maps + + \param xMap Maps x-values into pixel coordinates. + \param yMap Maps y-values into pixel coordinates. + + \return Bounding scale rect of the scale maps, not normalized +*/ +QRectF QwtPlotItem::scaleRect( const QwtScaleMap &xMap, + const QwtScaleMap &yMap ) const +{ + return QRectF( xMap.s1(), yMap.s1(), + xMap.sDist(), yMap.sDist() ); +} + +/*! + \brief Calculate the bounding paint rectangle of 2 maps + + \param xMap Maps x-values into pixel coordinates. + \param yMap Maps y-values into pixel coordinates. + + \return Bounding paint rectangle of the scale maps, not normalized +*/ +QRectF QwtPlotItem::paintRect( const QwtScaleMap &xMap, + const QwtScaleMap &yMap ) const +{ + const QRectF rect( xMap.p1(), yMap.p1(), + xMap.pDist(), yMap.pDist() ); + + return rect; +} diff --git a/ThirdParty/Qwt/src/qwt_plot_item.h b/ThirdParty/Qwt/src/qwt_plot_item.h new file mode 100644 index 0000000000..c76634e748 --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_plot_item.h @@ -0,0 +1,307 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#ifndef QWT_PLOT_ITEM_H +#define QWT_PLOT_ITEM_H + +#include "qwt_global.h" +#include "qwt_text.h" +#include "qwt_legend_data.h" +#include "qwt_graphic.h" +#include +#include +#include + +class QPainter; +class QwtScaleMap; +class QwtScaleDiv; +class QwtPlot; + +/*! + \brief Base class for items on the plot canvas + + A plot item is "something", that can be painted on the plot canvas, + or only affects the scales of the plot widget. They can be categorized as: + + - Representator\n + A "Representator" is an item that represents some sort of data + on the plot canvas. The different representator classes are organized + according to the characteristics of the data: + - QwtPlotMarker + Represents a point or a horizontal/vertical coordinate + - QwtPlotCurve + Represents a series of points + - QwtPlotSpectrogram ( QwtPlotRasterItem ) + Represents raster data + - ... + + - Decorators\n + A "Decorator" is an item, that displays additional information, that + is not related to any data: + - QwtPlotGrid + - QwtPlotScaleItem + - QwtPlotSvgItem + - ... + + Depending on the QwtPlotItem::ItemAttribute flags, an item is included + into autoscaling or has an entry on the legend. + + Before misusing the existing item classes it might be better to + implement a new type of plot item + ( don't implement a watermark as spectrogram ). + Deriving a new type of QwtPlotItem primarily means to implement + the YourPlotItem::draw() method. + + \sa The cpuplot example shows the implementation of additional plot items. +*/ + +class QWT_EXPORT QwtPlotItem +{ +public: + /*! + \brief Runtime type information + + RttiValues is used to cast plot items, without + having to enable runtime type information of the compiler. + */ + enum RttiValues + { + //! Unspecific value, that can be used, when it doesn't matter + Rtti_PlotItem = 0, + + //! For QwtPlotGrid + Rtti_PlotGrid, + + //! For QwtPlotScaleItem + Rtti_PlotScale, + + //! For QwtPlotLegendItem + Rtti_PlotLegend, + + //! For QwtPlotMarker + Rtti_PlotMarker, + + //! For QwtPlotCurve + Rtti_PlotCurve, + + //! For QwtPlotSpectroCurve + Rtti_PlotSpectroCurve, + + //! For QwtPlotIntervalCurve + Rtti_PlotIntervalCurve, + + //! For QwtPlotHistogram + Rtti_PlotHistogram, + + //! For QwtPlotSpectrogram + Rtti_PlotSpectrogram, + + //! For QwtPlotSvgItem + Rtti_PlotSVG, + + //! For QwtPlotTradingCurve + Rtti_PlotTradingCurve, + + //! For QwtPlotBarChart + Rtti_PlotBarChart, + + //! For QwtPlotMultiBarChart + Rtti_PlotMultiBarChart, + + //! For QwtPlotShapeItem + Rtti_PlotShape, + + //! For QwtPlotTextLabel + Rtti_PlotTextLabel, + + //! For QwtPlotZoneItem + Rtti_PlotZone, + + /*! + Values >= Rtti_PlotUserItem are reserved for plot items + not implemented in the Qwt library. + */ + Rtti_PlotUserItem = 1000 + }; + + /*! + \brief Plot Item Attributes + + Various aspects of a plot widget depend on the attributes of + the attached plot items. If and how a single plot item + participates in these updates depends on its attributes. + + \sa setItemAttribute(), testItemAttribute(), ItemInterest + */ + enum ItemAttribute + { + //! The item is represented on the legend. + Legend = 0x01, + + /*! + The boundingRect() of the item is included in the + autoscaling calculation as long as its width or height + is >= 0.0. + */ + AutoScale = 0x02, + + /*! + The item needs extra space to display something outside + its bounding rectangle. + \sa getCanvasMarginHint() + */ + Margins = 0x04 + }; + + //! Plot Item Attributes + typedef QFlags ItemAttributes; + + /*! + \brief Plot Item Interests + + Plot items might depend on the situation of the corresponding + plot widget. By enabling an interest the plot item will be + notified, when the corresponding attribute of the plot widgets + has changed. + + \sa setItemAttribute(), testItemAttribute(), ItemInterest + */ + enum ItemInterest + { + /*! + The item is interested in updates of the scales + \sa updateScaleDiv() + */ + ScaleInterest = 0x01, + + /*! + The item is interested in updates of the legend ( of other items ) + This flag is intended for items, that want to implement a legend + for displaying entries of other plot item. + + \note If the plot item wants to be represented on a legend + enable QwtPlotItem::Legend instead. + + \sa updateLegend() + */ + LegendInterest = 0x02 + }; + + //! Plot Item Interests + typedef QFlags ItemInterests; + + //! Render hints + enum RenderHint + { + //! Enable antialiasing + RenderAntialiased = 0x1 + }; + + //! Render hints + typedef QFlags RenderHints; + + explicit QwtPlotItem( const QwtText &title = QwtText() ); + virtual ~QwtPlotItem(); + + void attach( QwtPlot *plot ); + void detach(); + + QwtPlot *plot() const; + + void setTitle( const QString &title ); + void setTitle( const QwtText &title ); + const QwtText &title() const; + + virtual int rtti() const; + + void setItemAttribute( ItemAttribute, bool on = true ); + bool testItemAttribute( ItemAttribute ) const; + + void setItemInterest( ItemInterest, bool on = true ); + bool testItemInterest( ItemInterest ) const; + + void setRenderHint( RenderHint, bool on = true ); + bool testRenderHint( RenderHint ) const; + + void setRenderThreadCount( uint numThreads ); + uint renderThreadCount() const; + + void setLegendIconSize( const QSize & ); + QSize legendIconSize() const; + + double z() const; + void setZ( double z ); + + void show(); + void hide(); + virtual void setVisible( bool ); + bool isVisible () const; + + void setAxes( int xAxis, int yAxis ); + + void setXAxis( int axis ); + int xAxis() const; + + void setYAxis( int axis ); + int yAxis() const; + + virtual void itemChanged(); + virtual void legendChanged(); + + /*! + \brief Draw the item + + \param painter Painter + \param xMap Maps x-values into pixel coordinates. + \param yMap Maps y-values into pixel coordinates. + \param canvasRect Contents rect of the canvas in painter coordinates + */ + virtual void draw( QPainter *painter, + const QwtScaleMap &xMap, const QwtScaleMap &yMap, + const QRectF &canvasRect ) const = 0; + + virtual QRectF boundingRect() const; + + virtual void getCanvasMarginHint( + const QwtScaleMap &xMap, const QwtScaleMap &yMap, + const QRectF &canvasSize, + double &left, double &top, double &right, double &bottom) const; + + virtual void updateScaleDiv( + const QwtScaleDiv&, const QwtScaleDiv& ); + + virtual void updateLegend( const QwtPlotItem *, + const QList & ); + + QRectF scaleRect( const QwtScaleMap &, const QwtScaleMap & ) const; + QRectF paintRect( const QwtScaleMap &, const QwtScaleMap & ) const; + + virtual QList legendData() const; + + virtual QwtGraphic legendIcon( int index, const QSizeF & ) const; + +protected: + QwtGraphic defaultIcon( const QBrush &, const QSizeF & ) const; + +private: + // Disabled copy constructor and operator= + QwtPlotItem( const QwtPlotItem & ); + QwtPlotItem &operator=( const QwtPlotItem & ); + + class PrivateData; + PrivateData *d_data; +}; + +Q_DECLARE_OPERATORS_FOR_FLAGS( QwtPlotItem::ItemAttributes ) +Q_DECLARE_OPERATORS_FOR_FLAGS( QwtPlotItem::ItemInterests ) +Q_DECLARE_OPERATORS_FOR_FLAGS( QwtPlotItem::RenderHints ) + +Q_DECLARE_METATYPE( QwtPlotItem * ) + +#endif diff --git a/ThirdParty/Qwt/src/qwt_plot_layout.cpp b/ThirdParty/Qwt/src/qwt_plot_layout.cpp new file mode 100644 index 0000000000..1c143e2376 --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_plot_layout.cpp @@ -0,0 +1,1444 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#include "qwt_plot_layout.h" +#include "qwt_text.h" +#include "qwt_text_label.h" +#include "qwt_scale_widget.h" +#include "qwt_abstract_legend.h" +#include +#include + +class QwtPlotLayout::LayoutData +{ +public: + void init( const QwtPlot *, const QRectF &rect ); + + struct t_legendData + { + int frameWidth; + int hScrollExtent; + int vScrollExtent; + QSize hint; + } legend; + + struct t_titleData + { + QwtText text; + int frameWidth; + } title; + + struct t_footerData + { + QwtText text; + int frameWidth; + } footer; + + struct t_scaleData + { + bool isEnabled; + const QwtScaleWidget *scaleWidget; + QFont scaleFont; + int start; + int end; + int baseLineOffset; + double tickOffset; + int dimWithoutTitle; + } scale[QwtPlot::axisCnt]; + + struct t_canvasData + { + int contentsMargins[ QwtPlot::axisCnt ]; + + } canvas; +}; + +/* + Extract all layout relevant data from the plot components +*/ +void QwtPlotLayout::LayoutData::init( const QwtPlot *plot, const QRectF &rect ) +{ + // legend + + if ( plot->legend() ) + { + legend.frameWidth = plot->legend()->frameWidth(); + legend.hScrollExtent = + plot->legend()->scrollExtent( Qt::Horizontal ); + legend.vScrollExtent = + plot->legend()->scrollExtent( Qt::Vertical ); + + const QSize hint = plot->legend()->sizeHint(); + + int w = qMin( hint.width(), qFloor( rect.width() ) ); + int h = plot->legend()->heightForWidth( w ); + if ( h <= 0 ) + h = hint.height(); + + if ( h > rect.height() ) + w += legend.hScrollExtent; + + legend.hint = QSize( w, h ); + } + + // title + + title.frameWidth = 0; + title.text = QwtText(); + + if ( plot->titleLabel() ) + { + const QwtTextLabel *label = plot->titleLabel(); + title.text = label->text(); + if ( !( title.text.testPaintAttribute( QwtText::PaintUsingTextFont ) ) ) + title.text.setFont( label->font() ); + + title.frameWidth = plot->titleLabel()->frameWidth(); + } + + // footer + + footer.frameWidth = 0; + footer.text = QwtText(); + + if ( plot->footerLabel() ) + { + const QwtTextLabel *label = plot->footerLabel(); + footer.text = label->text(); + if ( !( footer.text.testPaintAttribute( QwtText::PaintUsingTextFont ) ) ) + footer.text.setFont( label->font() ); + + footer.frameWidth = plot->footerLabel()->frameWidth(); + } + + // scales + + for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ ) + { + if ( plot->axisEnabled( axis ) ) + { + const QwtScaleWidget *scaleWidget = plot->axisWidget( axis ); + + scale[axis].isEnabled = true; + + scale[axis].scaleWidget = scaleWidget; + + scale[axis].scaleFont = scaleWidget->font(); + + scale[axis].start = scaleWidget->startBorderDist(); + scale[axis].end = scaleWidget->endBorderDist(); + + scale[axis].baseLineOffset = scaleWidget->margin(); + scale[axis].tickOffset = scaleWidget->margin(); + if ( scaleWidget->scaleDraw()->hasComponent( + QwtAbstractScaleDraw::Ticks ) ) + { + scale[axis].tickOffset += + scaleWidget->scaleDraw()->maxTickLength(); + } + + scale[axis].dimWithoutTitle = scaleWidget->dimForLength( + QWIDGETSIZE_MAX, scale[axis].scaleFont ); + + if ( !scaleWidget->title().isEmpty() ) + { + scale[axis].dimWithoutTitle -= + scaleWidget->titleHeightForWidth( QWIDGETSIZE_MAX ); + } + } + else + { + scale[axis].isEnabled = false; + scale[axis].start = 0; + scale[axis].end = 0; + scale[axis].baseLineOffset = 0; + scale[axis].tickOffset = 0.0; + scale[axis].dimWithoutTitle = 0; + } + } + + // canvas + + plot->canvas()->getContentsMargins( + &canvas.contentsMargins[ QwtPlot::yLeft ], + &canvas.contentsMargins[ QwtPlot::xTop ], + &canvas.contentsMargins[ QwtPlot::yRight ], + &canvas.contentsMargins[ QwtPlot::xBottom ] ); +} + +class QwtPlotLayout::PrivateData +{ +public: + PrivateData(): + spacing( 5 ) + { + } + + QRectF titleRect; + QRectF footerRect; + QRectF legendRect; + QRectF scaleRect[QwtPlot::axisCnt]; + QRectF canvasRect; + + QwtPlotLayout::LayoutData layoutData; + + QwtPlot::LegendPosition legendPos; + double legendRatio; + unsigned int spacing; + unsigned int canvasMargin[QwtPlot::axisCnt]; + bool alignCanvasToScales[QwtPlot::axisCnt]; +}; + +/*! + \brief Constructor + */ + +QwtPlotLayout::QwtPlotLayout() +{ + d_data = new PrivateData; + + setLegendPosition( QwtPlot::BottomLegend ); + setCanvasMargin( 4 ); + setAlignCanvasToScales( false ); + + invalidate(); +} + +//! Destructor +QwtPlotLayout::~QwtPlotLayout() +{ + delete d_data; +} + +/*! + Change a margin of the canvas. The margin is the space + above/below the scale ticks. A negative margin will + be set to -1, excluding the borders of the scales. + + \param margin New margin + \param axis One of QwtPlot::Axis. Specifies where the position of the margin. + -1 means margin at all borders. + \sa canvasMargin() + + \warning The margin will have no effect when alignCanvasToScale() is true +*/ + +void QwtPlotLayout::setCanvasMargin( int margin, int axis ) +{ + if ( margin < -1 ) + margin = -1; + + if ( axis == -1 ) + { + for ( axis = 0; axis < QwtPlot::axisCnt; axis++ ) + d_data->canvasMargin[axis] = margin; + } + else if ( axis >= 0 && axis < QwtPlot::axisCnt ) + d_data->canvasMargin[axis] = margin; +} + +/*! + \param axisId Axis index + \return Margin around the scale tick borders + \sa setCanvasMargin() +*/ +int QwtPlotLayout::canvasMargin( int axisId ) const +{ + if ( axisId < 0 || axisId >= QwtPlot::axisCnt ) + return 0; + + return d_data->canvasMargin[axisId]; +} + +/*! + \brief Set the align-canvas-to-axis-scales flag for all axes + + \param on True/False + \sa setAlignCanvasToScale(), alignCanvasToScale() +*/ +void QwtPlotLayout::setAlignCanvasToScales( bool on ) +{ + for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ ) + d_data->alignCanvasToScales[axis] = on; +} + +/*! + Change the align-canvas-to-axis-scales setting. The canvas may: + + - extend beyond the axis scale ends to maximize its size, + - align with the axis scale ends to control its size. + + The axisId parameter is somehow confusing as it identifies a border + of the plot and not the axes, that are aligned. F.e when QwtPlot::yLeft + is set, the left end of the the x-axes ( QwtPlot::xTop, QwtPlot::xBottom ) + is aligned. + + \param axisId Axis index + \param on New align-canvas-to-axis-scales setting + + \sa setCanvasMargin(), alignCanvasToScale(), setAlignCanvasToScales() + \warning In case of on == true canvasMargin() will have no effect +*/ +void QwtPlotLayout::setAlignCanvasToScale( int axisId, bool on ) +{ + if ( axisId >= 0 && axisId < QwtPlot::axisCnt ) + d_data->alignCanvasToScales[axisId] = on; +} + +/*! + Return the align-canvas-to-axis-scales setting. The canvas may: + - extend beyond the axis scale ends to maximize its size + - align with the axis scale ends to control its size. + + \param axisId Axis index + \return align-canvas-to-axis-scales setting + \sa setAlignCanvasToScale(), setAlignCanvasToScale(), setCanvasMargin() +*/ +bool QwtPlotLayout::alignCanvasToScale( int axisId ) const +{ + if ( axisId < 0 || axisId >= QwtPlot::axisCnt ) + return false; + + return d_data->alignCanvasToScales[ axisId ]; +} + +/*! + Change the spacing of the plot. The spacing is the distance + between the plot components. + + \param spacing New spacing + \sa setCanvasMargin(), spacing() +*/ +void QwtPlotLayout::setSpacing( int spacing ) +{ + d_data->spacing = qMax( 0, spacing ); +} + +/*! + \return Spacing + \sa margin(), setSpacing() +*/ +int QwtPlotLayout::spacing() const +{ + return d_data->spacing; +} + +/*! + \brief Specify the position of the legend + \param pos The legend's position. + \param ratio Ratio between legend and the bounding rectangle + of title, footer, canvas and axes. The legend will be shrunk + if it would need more space than the given ratio. + The ratio is limited to ]0.0 .. 1.0]. In case of <= 0.0 + it will be reset to the default ratio. + The default vertical/horizontal ratio is 0.33/0.5. + + \sa QwtPlot::setLegendPosition() +*/ + +void QwtPlotLayout::setLegendPosition( QwtPlot::LegendPosition pos, double ratio ) +{ + if ( ratio > 1.0 ) + ratio = 1.0; + + switch ( pos ) + { + case QwtPlot::TopLegend: + case QwtPlot::BottomLegend: + if ( ratio <= 0.0 ) + ratio = 0.33; + d_data->legendRatio = ratio; + d_data->legendPos = pos; + break; + case QwtPlot::LeftLegend: + case QwtPlot::RightLegend: + if ( ratio <= 0.0 ) + ratio = 0.5; + d_data->legendRatio = ratio; + d_data->legendPos = pos; + break; + default: + break; + } +} + +/*! + \brief Specify the position of the legend + \param pos The legend's position. Valid values are + \c QwtPlot::LeftLegend, \c QwtPlot::RightLegend, + \c QwtPlot::TopLegend, \c QwtPlot::BottomLegend. + + \sa QwtPlot::setLegendPosition() +*/ +void QwtPlotLayout::setLegendPosition( QwtPlot::LegendPosition pos ) +{ + setLegendPosition( pos, 0.0 ); +} + +/*! + \return Position of the legend + \sa setLegendPosition(), QwtPlot::setLegendPosition(), + QwtPlot::legendPosition() +*/ +QwtPlot::LegendPosition QwtPlotLayout::legendPosition() const +{ + return d_data->legendPos; +} + +/*! + Specify the relative size of the legend in the plot + \param ratio Ratio between legend and the bounding rectangle + of title, footer, canvas and axes. The legend will be shrunk + if it would need more space than the given ratio. + The ratio is limited to ]0.0 .. 1.0]. In case of <= 0.0 + it will be reset to the default ratio. + The default vertical/horizontal ratio is 0.33/0.5. +*/ +void QwtPlotLayout::setLegendRatio( double ratio ) +{ + setLegendPosition( legendPosition(), ratio ); +} + +/*! + \return The relative size of the legend in the plot. + \sa setLegendPosition() +*/ +double QwtPlotLayout::legendRatio() const +{ + return d_data->legendRatio; +} + +/*! + \brief Set the geometry for the title + + This method is intended to be used from derived layouts + overloading activate() + + \sa titleRect(), activate() + */ +void QwtPlotLayout::setTitleRect( const QRectF &rect ) +{ + d_data->titleRect = rect; +} + +/*! + \return Geometry for the title + \sa activate(), invalidate() +*/ +QRectF QwtPlotLayout::titleRect() const +{ + return d_data->titleRect; +} + +/*! + \brief Set the geometry for the footer + + This method is intended to be used from derived layouts + overloading activate() + + \sa footerRect(), activate() + */ +void QwtPlotLayout::setFooterRect( const QRectF &rect ) +{ + d_data->footerRect = rect; +} + +/*! + \return Geometry for the footer + \sa activate(), invalidate() +*/ +QRectF QwtPlotLayout::footerRect() const +{ + return d_data->footerRect; +} + +/*! + \brief Set the geometry for the legend + + This method is intended to be used from derived layouts + overloading activate() + + \param rect Rectangle for the legend + + \sa legendRect(), activate() + */ +void QwtPlotLayout::setLegendRect( const QRectF &rect ) +{ + d_data->legendRect = rect; +} + +/*! + \return Geometry for the legend + \sa activate(), invalidate() +*/ +QRectF QwtPlotLayout::legendRect() const +{ + return d_data->legendRect; +} + +/*! + \brief Set the geometry for an axis + + This method is intended to be used from derived layouts + overloading activate() + + \param axis Axis index + \param rect Rectangle for the scale + + \sa scaleRect(), activate() + */ +void QwtPlotLayout::setScaleRect( int axis, const QRectF &rect ) +{ + if ( axis >= 0 && axis < QwtPlot::axisCnt ) + d_data->scaleRect[axis] = rect; +} + +/*! + \param axis Axis index + \return Geometry for the scale + \sa activate(), invalidate() +*/ +QRectF QwtPlotLayout::scaleRect( int axis ) const +{ + if ( axis < 0 || axis >= QwtPlot::axisCnt ) + { + static QRectF dummyRect; + return dummyRect; + } + return d_data->scaleRect[axis]; +} + +/*! + \brief Set the geometry for the canvas + + This method is intended to be used from derived layouts + overloading activate() + + \sa canvasRect(), activate() + */ +void QwtPlotLayout::setCanvasRect( const QRectF &rect ) +{ + d_data->canvasRect = rect; +} + +/*! + \return Geometry for the canvas + \sa activate(), invalidate() +*/ +QRectF QwtPlotLayout::canvasRect() const +{ + return d_data->canvasRect; +} + +/*! + Invalidate the geometry of all components. + \sa activate() +*/ +void QwtPlotLayout::invalidate() +{ + d_data->titleRect = d_data->footerRect + = d_data->legendRect = d_data->canvasRect = QRect(); + + for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ ) + d_data->scaleRect[axis] = QRect(); +} + +/*! + \return Minimum size hint + \param plot Plot widget + + \sa QwtPlot::minimumSizeHint() +*/ + +QSize QwtPlotLayout::minimumSizeHint( const QwtPlot *plot ) const +{ + class ScaleData + { + public: + ScaleData() + { + w = h = minLeft = minRight = tickOffset = 0; + } + + int w; + int h; + int minLeft; + int minRight; + int tickOffset; + } scaleData[QwtPlot::axisCnt]; + + int canvasBorder[QwtPlot::axisCnt]; + + int fw; + plot->canvas()->getContentsMargins( &fw, NULL, NULL, NULL ); + + int axis; + for ( axis = 0; axis < QwtPlot::axisCnt; axis++ ) + { + if ( plot->axisEnabled( axis ) ) + { + const QwtScaleWidget *scl = plot->axisWidget( axis ); + ScaleData &sd = scaleData[axis]; + + const QSize hint = scl->minimumSizeHint(); + sd.w = hint.width(); + sd.h = hint.height(); + scl->getBorderDistHint( sd.minLeft, sd.minRight ); + sd.tickOffset = scl->margin(); + if ( scl->scaleDraw()->hasComponent( QwtAbstractScaleDraw::Ticks ) ) + sd.tickOffset += qCeil( scl->scaleDraw()->maxTickLength() ); + } + + canvasBorder[axis] = fw + d_data->canvasMargin[axis] + 1; + } + + + for ( axis = 0; axis < QwtPlot::axisCnt; axis++ ) + { + ScaleData &sd = scaleData[axis]; + if ( sd.w && ( axis == QwtPlot::xBottom || axis == QwtPlot::xTop ) ) + { + if ( ( sd.minLeft > canvasBorder[QwtPlot::yLeft] ) + && scaleData[QwtPlot::yLeft].w ) + { + int shiftLeft = sd.minLeft - canvasBorder[QwtPlot::yLeft]; + if ( shiftLeft > scaleData[QwtPlot::yLeft].w ) + shiftLeft = scaleData[QwtPlot::yLeft].w; + + sd.w -= shiftLeft; + } + if ( ( sd.minRight > canvasBorder[QwtPlot::yRight] ) + && scaleData[QwtPlot::yRight].w ) + { + int shiftRight = sd.minRight - canvasBorder[QwtPlot::yRight]; + if ( shiftRight > scaleData[QwtPlot::yRight].w ) + shiftRight = scaleData[QwtPlot::yRight].w; + + sd.w -= shiftRight; + } + } + + if ( sd.h && ( axis == QwtPlot::yLeft || axis == QwtPlot::yRight ) ) + { + if ( ( sd.minLeft > canvasBorder[QwtPlot::xBottom] ) && + scaleData[QwtPlot::xBottom].h ) + { + int shiftBottom = sd.minLeft - canvasBorder[QwtPlot::xBottom]; + if ( shiftBottom > scaleData[QwtPlot::xBottom].tickOffset ) + shiftBottom = scaleData[QwtPlot::xBottom].tickOffset; + + sd.h -= shiftBottom; + } + if ( ( sd.minLeft > canvasBorder[QwtPlot::xTop] ) && + scaleData[QwtPlot::xTop].h ) + { + int shiftTop = sd.minRight - canvasBorder[QwtPlot::xTop]; + if ( shiftTop > scaleData[QwtPlot::xTop].tickOffset ) + shiftTop = scaleData[QwtPlot::xTop].tickOffset; + + sd.h -= shiftTop; + } + } + } + + const QWidget *canvas = plot->canvas(); + + int left, top, right, bottom; + canvas->getContentsMargins( &left, &top, &right, &bottom ); + + const QSize minCanvasSize = canvas->minimumSize(); + + int w = scaleData[QwtPlot::yLeft].w + scaleData[QwtPlot::yRight].w; + int cw = qMax( scaleData[QwtPlot::xBottom].w, scaleData[QwtPlot::xTop].w ) + + left + 1 + right + 1; + w += qMax( cw, minCanvasSize.width() ); + + int h = scaleData[QwtPlot::xBottom].h + scaleData[QwtPlot::xTop].h; + int ch = qMax( scaleData[QwtPlot::yLeft].h, scaleData[QwtPlot::yRight].h ) + + top + 1 + bottom + 1; + h += qMax( ch, minCanvasSize.height() ); + + const QwtTextLabel *labels[2]; + labels[0] = plot->titleLabel(); + labels[1] = plot->footerLabel(); + + for ( int i = 0; i < 2; i++ ) + { + const QwtTextLabel *label = labels[i]; + if ( label && !label->text().isEmpty() ) + { + // If only QwtPlot::yLeft or QwtPlot::yRight is showing, + // we center on the plot canvas. + const bool centerOnCanvas = !( plot->axisEnabled( QwtPlot::yLeft ) + && plot->axisEnabled( QwtPlot::yRight ) ); + + int labelW = w; + if ( centerOnCanvas ) + { + labelW -= scaleData[QwtPlot::yLeft].w + + scaleData[QwtPlot::yRight].w; + } + + int labelH = label->heightForWidth( labelW ); + if ( labelH > labelW ) // Compensate for a long title + { + w = labelW = labelH; + if ( centerOnCanvas ) + { + w += scaleData[QwtPlot::yLeft].w + + scaleData[QwtPlot::yRight].w; + } + + labelH = label->heightForWidth( labelW ); + } + h += labelH + d_data->spacing; + } + } + + // Compute the legend contribution + + const QwtAbstractLegend *legend = plot->legend(); + if ( legend && !legend->isEmpty() ) + { + if ( d_data->legendPos == QwtPlot::LeftLegend + || d_data->legendPos == QwtPlot::RightLegend ) + { + int legendW = legend->sizeHint().width(); + int legendH = legend->heightForWidth( legendW ); + + if ( legend->frameWidth() > 0 ) + w += d_data->spacing; + + if ( legendH > h ) + legendW += legend->scrollExtent( Qt::Horizontal ); + + if ( d_data->legendRatio < 1.0 ) + legendW = qMin( legendW, int( w / ( 1.0 - d_data->legendRatio ) ) ); + + w += legendW + d_data->spacing; + } + else // QwtPlot::Top, QwtPlot::Bottom + { + int legendW = qMin( legend->sizeHint().width(), w ); + int legendH = legend->heightForWidth( legendW ); + + if ( legend->frameWidth() > 0 ) + h += d_data->spacing; + + if ( d_data->legendRatio < 1.0 ) + legendH = qMin( legendH, int( h / ( 1.0 - d_data->legendRatio ) ) ); + + h += legendH + d_data->spacing; + } + } + + return QSize( w, h ); +} + +/*! + Find the geometry for the legend + + \param options Options how to layout the legend + \param rect Rectangle where to place the legend + + \return Geometry for the legend + \sa Options +*/ + +QRectF QwtPlotLayout::layoutLegend( Options options, + const QRectF &rect ) const +{ + const QSize hint( d_data->layoutData.legend.hint ); + + int dim; + if ( d_data->legendPos == QwtPlot::LeftLegend + || d_data->legendPos == QwtPlot::RightLegend ) + { + // We don't allow vertical legends to take more than + // half of the available space. + + dim = qMin( hint.width(), int( rect.width() * d_data->legendRatio ) ); + + if ( !( options & IgnoreScrollbars ) ) + { + if ( hint.height() > rect.height() ) + { + // The legend will need additional + // space for the vertical scrollbar. + + dim += d_data->layoutData.legend.hScrollExtent; + } + } + } + else + { + dim = qMin( hint.height(), int( rect.height() * d_data->legendRatio ) ); + dim = qMax( dim, d_data->layoutData.legend.vScrollExtent ); + } + + QRectF legendRect = rect; + switch ( d_data->legendPos ) + { + case QwtPlot::LeftLegend: + legendRect.setWidth( dim ); + break; + case QwtPlot::RightLegend: + legendRect.setX( rect.right() - dim ); + legendRect.setWidth( dim ); + break; + case QwtPlot::TopLegend: + legendRect.setHeight( dim ); + break; + case QwtPlot::BottomLegend: + legendRect.setY( rect.bottom() - dim ); + legendRect.setHeight( dim ); + break; + } + + return legendRect; +} + +/*! + Align the legend to the canvas + + \param canvasRect Geometry of the canvas + \param legendRect Maximum geometry for the legend + + \return Geometry for the aligned legend +*/ +QRectF QwtPlotLayout::alignLegend( const QRectF &canvasRect, + const QRectF &legendRect ) const +{ + QRectF alignedRect = legendRect; + + if ( d_data->legendPos == QwtPlot::BottomLegend + || d_data->legendPos == QwtPlot::TopLegend ) + { + if ( d_data->layoutData.legend.hint.width() < canvasRect.width() ) + { + alignedRect.setX( canvasRect.x() ); + alignedRect.setWidth( canvasRect.width() ); + } + } + else + { + if ( d_data->layoutData.legend.hint.height() < canvasRect.height() ) + { + alignedRect.setY( canvasRect.y() ); + alignedRect.setHeight( canvasRect.height() ); + } + } + + return alignedRect; +} + +/*! + Expand all line breaks in text labels, and calculate the height + of their widgets in orientation of the text. + + \param options Options how to layout the legend + \param rect Bounding rectangle for title, footer, axes and canvas. + \param dimTitle Expanded height of the title widget + \param dimFooter Expanded height of the footer widget + \param dimAxis Expanded heights of the axis in axis orientation. + + \sa Options +*/ +void QwtPlotLayout::expandLineBreaks( Options options, const QRectF &rect, + int &dimTitle, int &dimFooter, int dimAxis[QwtPlot::axisCnt] ) const +{ + dimTitle = dimFooter = 0; + for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ ) + dimAxis[axis] = 0; + + int backboneOffset[QwtPlot::axisCnt]; + for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ ) + { + backboneOffset[axis] = 0; + if ( !( options & IgnoreFrames ) ) + backboneOffset[axis] += d_data->layoutData.canvas.contentsMargins[ axis ]; + + if ( !d_data->alignCanvasToScales[axis] ) + backboneOffset[axis] += d_data->canvasMargin[axis]; + } + + bool done = false; + while ( !done ) + { + done = true; + + // the size for the 4 axis depend on each other. Expanding + // the height of a horizontal axis will shrink the height + // for the vertical axis, shrinking the height of a vertical + // axis will result in a line break what will expand the + // width and results in shrinking the width of a horizontal + // axis what might result in a line break of a horizontal + // axis ... . So we loop as long until no size changes. + + if ( !( ( options & IgnoreTitle ) || + d_data->layoutData.title.text.isEmpty() ) ) + { + double w = rect.width(); + + if ( d_data->layoutData.scale[QwtPlot::yLeft].isEnabled + != d_data->layoutData.scale[QwtPlot::yRight].isEnabled ) + { + // center to the canvas + w -= dimAxis[QwtPlot::yLeft] + dimAxis[QwtPlot::yRight]; + } + + int d = qCeil( d_data->layoutData.title.text.heightForWidth( w ) ); + if ( !( options & IgnoreFrames ) ) + d += 2 * d_data->layoutData.title.frameWidth; + + if ( d > dimTitle ) + { + dimTitle = d; + done = false; + } + } + + if ( !( ( options & IgnoreFooter ) || + d_data->layoutData.footer.text.isEmpty() ) ) + { + double w = rect.width(); + + if ( d_data->layoutData.scale[QwtPlot::yLeft].isEnabled + != d_data->layoutData.scale[QwtPlot::yRight].isEnabled ) + { + // center to the canvas + w -= dimAxis[QwtPlot::yLeft] + dimAxis[QwtPlot::yRight]; + } + + int d = qCeil( d_data->layoutData.footer.text.heightForWidth( w ) ); + if ( !( options & IgnoreFrames ) ) + d += 2 * d_data->layoutData.footer.frameWidth; + + if ( d > dimFooter ) + { + dimFooter = d; + done = false; + } + } + + for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ ) + { + const struct LayoutData::t_scaleData &scaleData = + d_data->layoutData.scale[axis]; + + if ( scaleData.isEnabled ) + { + double length; + if ( axis == QwtPlot::xTop || axis == QwtPlot::xBottom ) + { + length = rect.width() - dimAxis[QwtPlot::yLeft] + - dimAxis[QwtPlot::yRight]; + length -= scaleData.start + scaleData.end; + + if ( dimAxis[QwtPlot::yRight] > 0 ) + length -= 1; + + length += qMin( dimAxis[QwtPlot::yLeft], + scaleData.start - backboneOffset[QwtPlot::yLeft] ); + length += qMin( dimAxis[QwtPlot::yRight], + scaleData.end - backboneOffset[QwtPlot::yRight] ); + } + else // QwtPlot::yLeft, QwtPlot::yRight + { + length = rect.height() - dimAxis[QwtPlot::xTop] + - dimAxis[QwtPlot::xBottom]; + length -= scaleData.start + scaleData.end; + length -= 1; + + if ( dimAxis[QwtPlot::xBottom] <= 0 ) + length -= 1; + if ( dimAxis[QwtPlot::xTop] <= 0 ) + length -= 1; + + if ( dimAxis[QwtPlot::xBottom] > 0 ) + { + length += qMin( + d_data->layoutData.scale[QwtPlot::xBottom].tickOffset, + double( scaleData.start - backboneOffset[QwtPlot::xBottom] ) ); + } + if ( dimAxis[QwtPlot::xTop] > 0 ) + { + length += qMin( + d_data->layoutData.scale[QwtPlot::xTop].tickOffset, + double( scaleData.end - backboneOffset[QwtPlot::xTop] ) ); + } + + if ( dimTitle > 0 ) + length -= dimTitle + d_data->spacing; + } + + int d = scaleData.dimWithoutTitle; + if ( !scaleData.scaleWidget->title().isEmpty() ) + { + d += scaleData.scaleWidget->titleHeightForWidth( qFloor( length ) ); + } + + + if ( d > dimAxis[axis] ) + { + dimAxis[axis] = d; + done = false; + } + } + } + } +} + +/*! + Align the ticks of the axis to the canvas borders using + the empty corners. + + \param options Layout options + \param canvasRect Geometry of the canvas ( IN/OUT ) + \param scaleRect Geometries of the scales ( IN/OUT ) + + \sa Options +*/ + +void QwtPlotLayout::alignScales( Options options, + QRectF &canvasRect, QRectF scaleRect[QwtPlot::axisCnt] ) const +{ + int backboneOffset[QwtPlot::axisCnt]; + for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ ) + { + backboneOffset[axis] = 0; + + if ( !d_data->alignCanvasToScales[axis] ) + { + backboneOffset[axis] += d_data->canvasMargin[axis]; + } + + if ( !( options & IgnoreFrames ) ) + { + backboneOffset[axis] += + d_data->layoutData.canvas.contentsMargins[axis]; + } + } + + for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ ) + { + if ( !scaleRect[axis].isValid() ) + continue; + + const int startDist = d_data->layoutData.scale[axis].start; + const int endDist = d_data->layoutData.scale[axis].end; + + QRectF &axisRect = scaleRect[axis]; + + if ( axis == QwtPlot::xTop || axis == QwtPlot::xBottom ) + { + const QRectF &leftScaleRect = scaleRect[QwtPlot::yLeft]; + const int leftOffset = + backboneOffset[QwtPlot::yLeft] - startDist; + + if ( leftScaleRect.isValid() ) + { + const double dx = leftOffset + leftScaleRect.width(); + if ( d_data->alignCanvasToScales[QwtPlot::yLeft] && dx < 0.0 ) + { + /* + The axis needs more space than the width + of the left scale. + */ + const double cLeft = canvasRect.left(); // qreal -> double + canvasRect.setLeft( qMax( cLeft, axisRect.left() - dx ) ); + } + else + { + const double minLeft = leftScaleRect.left(); + const double left = axisRect.left() + leftOffset; + axisRect.setLeft( qMax( left, minLeft ) ); + } + } + else + { + if ( d_data->alignCanvasToScales[QwtPlot::yLeft] && leftOffset < 0 ) + { + canvasRect.setLeft( qMax( canvasRect.left(), + axisRect.left() - leftOffset ) ); + } + else + { + if ( leftOffset > 0 ) + axisRect.setLeft( axisRect.left() + leftOffset ); + } + } + + const QRectF &rightScaleRect = scaleRect[QwtPlot::yRight]; + const int rightOffset = + backboneOffset[QwtPlot::yRight] - endDist + 1; + + if ( rightScaleRect.isValid() ) + { + const double dx = rightOffset + rightScaleRect.width(); + if ( d_data->alignCanvasToScales[QwtPlot::yRight] && dx < 0 ) + { + /* + The axis needs more space than the width + of the right scale. + */ + const double cRight = canvasRect.right(); // qreal -> double + canvasRect.setRight( qMin( cRight, axisRect.right() + dx ) ); + } + + const double maxRight = rightScaleRect.right(); + const double right = axisRect.right() - rightOffset; + axisRect.setRight( qMin( right, maxRight ) ); + } + else + { + if ( d_data->alignCanvasToScales[QwtPlot::yRight] && rightOffset < 0 ) + { + canvasRect.setRight( qMin( canvasRect.right(), + axisRect.right() + rightOffset ) ); + } + else + { + if ( rightOffset > 0 ) + axisRect.setRight( axisRect.right() - rightOffset ); + } + } + } + else // QwtPlot::yLeft, QwtPlot::yRight + { + const QRectF &bottomScaleRect = scaleRect[QwtPlot::xBottom]; + const int bottomOffset = + backboneOffset[QwtPlot::xBottom] - endDist + 1; + + if ( bottomScaleRect.isValid() ) + { + const double dy = bottomOffset + bottomScaleRect.height(); + if ( d_data->alignCanvasToScales[QwtPlot::xBottom] && dy < 0 ) + { + /* + The axis needs more space than the height + of the bottom scale. + */ + const double cBottom = canvasRect.bottom(); // qreal -> double + canvasRect.setBottom( qMin( cBottom, axisRect.bottom() + dy ) ); + } + else + { + const double maxBottom = bottomScaleRect.top() + + d_data->layoutData.scale[QwtPlot::xBottom].tickOffset; + const double bottom = axisRect.bottom() - bottomOffset; + axisRect.setBottom( qMin( bottom, maxBottom ) ); + } + } + else + { + if ( d_data->alignCanvasToScales[QwtPlot::xBottom] && bottomOffset < 0 ) + { + canvasRect.setBottom( qMin( canvasRect.bottom(), + axisRect.bottom() + bottomOffset ) ); + } + else + { + if ( bottomOffset > 0 ) + axisRect.setBottom( axisRect.bottom() - bottomOffset ); + } + } + + const QRectF &topScaleRect = scaleRect[QwtPlot::xTop]; + const int topOffset = backboneOffset[QwtPlot::xTop] - startDist; + + if ( topScaleRect.isValid() ) + { + const double dy = topOffset + topScaleRect.height(); + if ( d_data->alignCanvasToScales[QwtPlot::xTop] && dy < 0 ) + { + /* + The axis needs more space than the height + of the top scale. + */ + const double cTop = canvasRect.top(); // qreal -> double + canvasRect.setTop( qMax( cTop, axisRect.top() - dy ) ); + } + else + { + const double minTop = topScaleRect.bottom() - + d_data->layoutData.scale[QwtPlot::xTop].tickOffset; + const double top = axisRect.top() + topOffset; + axisRect.setTop( qMax( top, minTop ) ); + } + } + else + { + if ( d_data->alignCanvasToScales[QwtPlot::xTop] && topOffset < 0 ) + { + canvasRect.setTop( qMax( canvasRect.top(), + axisRect.top() - topOffset ) ); + } + else + { + if ( topOffset > 0 ) + axisRect.setTop( axisRect.top() + topOffset ); + } + } + } + } + + /* + The canvas has been aligned to the scale with largest + border distances. Now we have to realign the other scale. + */ + + + for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ ) + { + QRectF &sRect = scaleRect[axis]; + + if ( !sRect.isValid() ) + continue; + + if ( axis == QwtPlot::xBottom || axis == QwtPlot::xTop ) + { + if ( d_data->alignCanvasToScales[QwtPlot::yLeft] ) + { + double y = canvasRect.left() - d_data->layoutData.scale[axis].start; + if ( !( options & IgnoreFrames ) ) + y += d_data->layoutData.canvas.contentsMargins[ QwtPlot::yLeft ]; + + sRect.setLeft( y ); + } + if ( d_data->alignCanvasToScales[QwtPlot::yRight] ) + { + double y = canvasRect.right() - 1 + d_data->layoutData.scale[axis].end; + if ( !( options & IgnoreFrames ) ) + y -= d_data->layoutData.canvas.contentsMargins[ QwtPlot::yRight ]; + + sRect.setRight( y ); + } + + if ( d_data->alignCanvasToScales[ axis ] ) + { + if ( axis == QwtPlot::xTop ) + sRect.setBottom( canvasRect.top() ); + else + sRect.setTop( canvasRect.bottom() ); + } + } + else + { + if ( d_data->alignCanvasToScales[QwtPlot::xTop] ) + { + double x = canvasRect.top() - d_data->layoutData.scale[axis].start; + if ( !( options & IgnoreFrames ) ) + x += d_data->layoutData.canvas.contentsMargins[ QwtPlot::xTop ]; + + sRect.setTop( x ); + } + if ( d_data->alignCanvasToScales[QwtPlot::xBottom] ) + { + double x = canvasRect.bottom() - 1 + d_data->layoutData.scale[axis].end; + if ( !( options & IgnoreFrames ) ) + x -= d_data->layoutData.canvas.contentsMargins[ QwtPlot::xBottom ]; + + sRect.setBottom( x ); + } + + if ( d_data->alignCanvasToScales[ axis ] ) + { + if ( axis == QwtPlot::yLeft ) + sRect.setRight( canvasRect.left() ); + else + sRect.setLeft( canvasRect.right() ); + } + } + } +} + +/*! + \brief Recalculate the geometry of all components. + + \param plot Plot to be layout + \param plotRect Rectangle where to place the components + \param options Layout options + + \sa invalidate(), titleRect(), footerRect() + legendRect(), scaleRect(), canvasRect() +*/ +void QwtPlotLayout::activate( const QwtPlot *plot, + const QRectF &plotRect, Options options ) +{ + invalidate(); + + QRectF rect( plotRect ); // undistributed rest of the plot rect + + // We extract all layout relevant parameters from the widgets, + // and save them to d_data->layoutData. + + d_data->layoutData.init( plot, rect ); + + if ( !( options & IgnoreLegend ) + && plot->legend() && !plot->legend()->isEmpty() ) + { + d_data->legendRect = layoutLegend( options, rect ); + + // subtract d_data->legendRect from rect + + const QRegion region( rect.toRect() ); + rect = region.subtracted( d_data->legendRect.toRect() ).boundingRect(); + + switch ( d_data->legendPos ) + { + case QwtPlot::LeftLegend: + rect.setLeft( rect.left() + d_data->spacing ); + break; + case QwtPlot::RightLegend: + rect.setRight( rect.right() - d_data->spacing ); + break; + case QwtPlot::TopLegend: + rect.setTop( rect.top() + d_data->spacing ); + break; + case QwtPlot::BottomLegend: + rect.setBottom( rect.bottom() - d_data->spacing ); + break; + } + } + + /* + +---+-----------+---+ + | Title | + +---+-----------+---+ + | | Axis | | + +---+-----------+---+ + | A | | A | + | x | Canvas | x | + | i | | i | + | s | | s | + +---+-----------+---+ + | | Axis | | + +---+-----------+---+ + | Footer | + +---+-----------+---+ + */ + + // title, footer and axes include text labels. The height of each + // label depends on its line breaks, that depend on the width + // for the label. A line break in a horizontal text will reduce + // the available width for vertical texts and vice versa. + // expandLineBreaks finds the height/width for title, footer and axes + // including all line breaks. + + int dimTitle, dimFooter, dimAxes[QwtPlot::axisCnt]; + expandLineBreaks( options, rect, dimTitle, dimFooter, dimAxes ); + + if ( dimTitle > 0 ) + { + d_data->titleRect.setRect( + rect.left(), rect.top(), rect.width(), dimTitle ); + + rect.setTop( d_data->titleRect.bottom() + d_data->spacing ); + + if ( d_data->layoutData.scale[QwtPlot::yLeft].isEnabled != + d_data->layoutData.scale[QwtPlot::yRight].isEnabled ) + { + // if only one of the y axes is missing we align + // the title centered to the canvas + + d_data->titleRect.setX( rect.left() + dimAxes[QwtPlot::yLeft] ); + d_data->titleRect.setWidth( rect.width() + - dimAxes[QwtPlot::yLeft] - dimAxes[QwtPlot::yRight] ); + } + } + + if ( dimFooter > 0 ) + { + d_data->footerRect.setRect( + rect.left(), rect.bottom() - dimFooter, rect.width(), dimFooter ); + + rect.setBottom( d_data->footerRect.top() - d_data->spacing ); + + if ( d_data->layoutData.scale[QwtPlot::yLeft].isEnabled != + d_data->layoutData.scale[QwtPlot::yRight].isEnabled ) + { + // if only one of the y axes is missing we align + // the footer centered to the canvas + + d_data->footerRect.setX( rect.left() + dimAxes[QwtPlot::yLeft] ); + d_data->footerRect.setWidth( rect.width() + - dimAxes[QwtPlot::yLeft] - dimAxes[QwtPlot::yRight] ); + } + } + + d_data->canvasRect.setRect( + rect.x() + dimAxes[QwtPlot::yLeft], + rect.y() + dimAxes[QwtPlot::xTop], + rect.width() - dimAxes[QwtPlot::yRight] - dimAxes[QwtPlot::yLeft], + rect.height() - dimAxes[QwtPlot::xBottom] - dimAxes[QwtPlot::xTop] ); + + for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ ) + { + // set the rects for the axes + + if ( dimAxes[axis] ) + { + int dim = dimAxes[axis]; + QRectF &scaleRect = d_data->scaleRect[axis]; + + scaleRect = d_data->canvasRect; + switch ( axis ) + { + case QwtPlot::yLeft: + scaleRect.setX( d_data->canvasRect.left() - dim ); + scaleRect.setWidth( dim ); + break; + case QwtPlot::yRight: + scaleRect.setX( d_data->canvasRect.right() ); + scaleRect.setWidth( dim ); + break; + case QwtPlot::xBottom: + scaleRect.setY( d_data->canvasRect.bottom() ); + scaleRect.setHeight( dim ); + break; + case QwtPlot::xTop: + scaleRect.setY( d_data->canvasRect.top() - dim ); + scaleRect.setHeight( dim ); + break; + } + scaleRect = scaleRect.normalized(); + } + } + + // +---+-----------+---+ + // | <- Axis -> | + // +-^-+-----------+-^-+ + // | | | | | | + // | | | | + // | A | | A | + // | x | Canvas | x | + // | i | | i | + // | s | | s | + // | | | | + // | | | | | | + // +-V-+-----------+-V-+ + // | <- Axis -> | + // +---+-----------+---+ + + // The ticks of the axes - not the labels above - should + // be aligned to the canvas. So we try to use the empty + // corners to extend the axes, so that the label texts + // left/right of the min/max ticks are moved into them. + + alignScales( options, d_data->canvasRect, d_data->scaleRect ); + + if ( !d_data->legendRect.isEmpty() ) + { + // We prefer to align the legend to the canvas - not to + // the complete plot - if possible. + + d_data->legendRect = alignLegend( d_data->canvasRect, d_data->legendRect ); + } +} diff --git a/ThirdParty/Qwt/src/qwt_plot_layout.h b/ThirdParty/Qwt/src/qwt_plot_layout.h new file mode 100644 index 0000000000..c72c04fc3f --- /dev/null +++ b/ThirdParty/Qwt/src/qwt_plot_layout.h @@ -0,0 +1,122 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** + * Qwt Widget Library + * Copyright (C) 1997 Josef Wilgen + * Copyright (C) 2002 Uwe Rathmann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the Qwt License, Version 1.0 + *****************************************************************************/ + +#ifndef QWT_PLOT_LAYOUT_H +#define QWT_PLOT_LAYOUT_H + +#include "qwt_global.h" +#include "qwt_plot.h" + +/*! + \brief Layout engine for QwtPlot. + + It is used by the QwtPlot widget to organize its internal widgets + or by QwtPlot::print() to render its content to a QPaintDevice like + a QPrinter, QPixmap/QImage or QSvgRenderer. + + \sa QwtPlot::setPlotLayout() +*/ + +class QWT_EXPORT QwtPlotLayout +{ +public: + /*! + Options to configure the plot layout engine + \sa activate(), QwtPlotRenderer + */ + enum Option + { + //! Unused + AlignScales = 0x01, + + /*! + Ignore the dimension of the scrollbars. There are no + scrollbars, when the plot is not rendered to widgets. + */ + IgnoreScrollbars = 0x02, + + //! Ignore all frames. + IgnoreFrames = 0x04, + + //! Ignore the legend. + IgnoreLegend = 0x08, + + //! Ignore the title. + IgnoreTitle = 0x10, + + //! Ignore the footer. + IgnoreFooter = 0x20 + }; + + //! Layout options + typedef QFlags